[
  {
    "path": ".ctags.d/exclusion.ctags",
    "content": "# Exclude directories that don't contain real code\n--exclude=Units\n--exclude=tinst-root\n--exclude=Tmain\n"
  },
  {
    "path": ".dir-locals.el",
    "content": ";; Don't forget putting (add-hook 'hack-local-variables-hook (lambda () (editorconfig-apply))) to your .emacs.\n((c-mode . ((c-file-style . \"linux\"))))\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nend_of_line = lf\ninsert_final_newline = true\n\n[*.{c,h,sh}]\nindent_size = 4\nindent_style = tab\ntrim_trailing_whitespace = true\ntab_width = 4\n\n[misc/packcc/packcc.c]\nindent_size = 4\nindent_style = space\ntrim_trailing_whitespace = true\ntab_width = 4\n\n[*.{ctags,ps}]\nindent_size = 4\nindent_style = space\ntrim_trailing_whitespace = true\ntab_width = 4\n\n[{Makefile*,*.mak}]\nindent_size = 8\nindent_style = tab\ntrim_trailing_whitespace = true\ntab_width = 8\n\n[*.rst*]\nindent_size = 4\nindent_style = tab\ntrim_trailing_whitespace = true\ntab_width = 4\n\n[gnulib/*.{c,h}]\ntab_width = 8\n\n[misc/optlib2c]\ntrim_trailing_whitespace = true\n\n[win32/*.{bat,sln,vcxproj,vcxproj.filters}]\nend_of_line = crlf\n\n[win32/*.vcxproj*]\ninsert_final_newline = false\n"
  },
  {
    "path": ".gdbinit",
    "content": "define pst\n    call ps(st)\nend\n"
  },
  {
    "path": ".gitattributes",
    "content": "*\ttext=auto\n\n/win32/*.bat\ttext eol=crlf\n/win32/*.sln\ttext eol=crlf\n/win32/*.vcxproj\ttext eol=crlf\n/win32/*.vcxproj.filters\ttext eol=crlf\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "(\nThank you for contacting us.\n\nIf you are reporting an issue with the parsing output, please fill\nthe following template.  As your custom CTags configuration can\naffect results, please always use `--options=NONE` as the first\noption when running `ctags`.\n\nOtherwise, delete the template and write your issue from scratch.\nExamples may help developers understanding your issue better.\n\nUse GitHub web interface and markdown notation.\nUsing mail results broken text rendering that makes\nthe developers go crazy.\n)\n\n*****\n\nThe name of the parser:\n\n\nThe command line you used to run ctags:\n\n```\n$ ctags --options=NONE ...\n```\n\nThe content of input file:\n\n```C\n/* THIS IS AN EXAMPLE */\nint\nmain(void)\n{\n\t...\n```\n\nThe tags output you are not satisfied with:\n\n```\n!_THIS_IS_AN_EXAMPLE\nmainVoid\tfoo.c\t/^main(void)$/;\"\tkind:function\tline:2\tlanguage:C\ttyperef:typename:int\tsignature:(void)\troles:def\n...\n```\n\nThe tags output you expect:\n\n```\n!_THIS_IS_AN_EXAMPLE\nmain\tfoo.c\t/^main(void)$/;\"\tkind:function\tline:2\tlanguage:C\ttyperef:typename:int\tsignature:(void)\troles:def\n...\n```\n\nThe version of ctags:\n\n```\n$ ctags --version\nUniversal Ctags 0.0.0(EXAMPLE), Copyright (C) 2015 Universal Ctags Team\nUniversal Ctags is derived from Exuberant Ctags.\nExuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert\n  Compiled: May 11 1018, 23:16:36\n  URL: https://ctags.io/\n  Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath, +json, +interactive, +sandbox, +yaml\n```\n\nHow do you get ctags binary:\n\n(\nBuilding it locally, via GNU/Linux distribution, as BSD's package,\nwin32 binary taken from Universal-ctags/ctags-win32 project, macosx\nbinary taken from Universal-ctags/homebrew-universal-ctags project,\netc.\n)\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: \"github-actions\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/building-with-nmake.yml",
    "content": "name: build with Vistual Studio / NMake\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  test:\n\n    strategy:\n      fail-fast: false\n      matrix:\n        version: [2022]\n        arch: [x64, x86]\n\n    runs-on: windows-${{ matrix.version }}\n\n    defaults:\n      run:\n        shell: cmd /C {0}\n\n    steps:\n      - run: choco install -y file\n\n      - uses: actions/checkout@v6\n\n      - name: setup nmake\n        run: |\n          if \"${{ matrix.version }}\" == \"2019\" (\n            set \"XX= (x86)\"\n          ) else (\n            set \"XX=\"\n          )\n\n          @echo on\n\n          echo call \"C:\\Program Files%XX%\\Microsoft Visual Studio\\${{ matrix.version }}\\Enterprise\\VC\\Auxiliary\\Build\\vcvarsall.bat\" ${{ matrix.arch }} > nmake-setup.cmd\n          type nmake-setup.cmd\n\n      - name: build libiconv\n        run: |\n          @echo on\n\n          git clone --depth=1 https://github.com/koron/libiconv libiconv-source\n          cd libiconv-source\\msvc10\n\n          call \"${{ github.workspace }}\\nmake-setup.cmd\"\n          nmake NODEBUG=1 NOMSVCRT=1\n\n      - name: install libiconv\n        run: |\n          @echo on\n\n          mkdir libiconv-installed\\include\n          mkdir libiconv-installed\\lib\n\n          copy  libiconv-source\\msvc10\\iconv.h   libiconv-installed\\include\n          copy  libiconv-source\\msvc10\\iconv.lib libiconv-installed\\lib\n          copy  libiconv-source\\msvc10\\iconv.dll .\n\n      - name: build ctags with nmake\n        run: |\n          @echo on\n          call nmake-setup.cmd\n          nmake -f mk_mvc.mak WITH_ICONV=yes ICONV_DIR=libiconv-installed PDB=yes\n\n      - run: dir\n\n      - name: dumpbin ctags.exe\n        run: |\n          @echo on\n          call nmake-setup.cmd\n          dumpbin /dependents ctags.exe\n\n      - run: file ctags.exe\n      - run: ctags.exe --version\n"
  },
  {
    "path": ".github/workflows/building-with-pegof.yml",
    "content": "name: build ctags with pegof and run units target on Ubuntu\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n\n    strategy:\n      matrix:\n        os: [ubuntu-24.04]\n\n    runs-on: ${{ matrix.os }}\n\n    env:\n       DEBIAN_FRONTEND: noninteractive\n\n    steps:\n      - run: sudo apt -y update\n      - run: sudo apt -y install cmake g++ pkg-config automake libseccomp-dev libjansson-dev libyaml-dev libxml2-dev libpcre2-dev bash gdb python3-docutils\n      # cmake and g++ are used to build pegof\n\n      - uses: actions/checkout@v6\n\n      - uses: actions/checkout@v6\n        with:\n          repository: dolik-rce/pegof\n          submodules: recursive\n          fetch-tags: true\n          path: pegof\n\n      - run: cmake -S pegof -B pegof/build.d\n      - run: cmake --build     pegof/build.d\n\n      - run: pegof/build.d/pegof --version\n\n      - run: ./autogen.sh\n      - run: ./configure --enable-debugging --enable-iconv --with-pegof=$PWD/pegof/build.d/pegof\n\n      - run: make -j2\n\n      - run: ./ctags --list-features | grep pegof\n\n      - run: |\n          echo \"Targets: $(./ctags --list-languages=_packcc |  while read LANG REST; do echo \"$LANG\"; done | tr '\\n' ',')\"\n      - run: make units LANGUAGES=\"$(./ctags --list-languages=_packcc |  while read LANG REST; do echo \"$LANG\"; done | tr '\\n' ',')\"\n      - run: make dist\n        # See EXTRA_DIST in Makefile.am.\n        # Currently we add .pego files.\n"
  },
  {
    "path": ".github/workflows/code-coverage-on-ubuntu.yml",
    "content": "name: upload coverage report to codecov.io\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  coverage:\n\n    runs-on: ubuntu-22.04\n\n    env:\n      DEBIAN_FRONTEND: noninteractive\n\n      CC: gcc\n\n    steps:\n    - uses: actions/checkout@v6\n      with:\n        fetch-depth: 0\n\n    - run: sudo apt-get -y -o APT::Immediate-Configure=false update\n    - run: sudo apt-get -y -o APT::Immediate-Configure=false install bash pkg-config automake gcc gdb lcov libseccomp-dev libjansson-dev libyaml-dev libxml2-dev libpcre2-dev\n\n    - run: gcc --version\n    - run: make --version\n\n    - run: ./autogen.sh\n\n    - run: mkdir -p build.d\n\n    - run: cd build.d && ../configure --enable-debugging --enable-coverage-gcov\n    - run: cd build.d && make -j2\n\n    - run: cd build.d && ./ctags --list-features\n    - run: cd build.d && ./ctags --help\n    - run: cd build.d && ./ctags --version\n\n    - run: cd build.d && make check\n    - run: cd build.d && make roundtrip\n\n    - run: cd build.d && lcov -c -b . -d . -o coverage.info\n\n    - uses: codecov/codecov-action@v5\n      with:\n        files: build.d/coverage.info\n        name: travis-ubuntu-latest\n        token: ${{ secrets.CODECOV_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/cross-compile-for--netbsd-on-ubuntu.yml",
    "content": "name: cross compile for NetBSD on Ubuntu\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  build:\n    strategy:\n      fail-fast: false\n      matrix:\n        netbsd-release-version: ['10.1', '10.0', '9.4', '9.3']\n        # https://ftp.netbsd.org/pub/NetBSD/\n\n    runs-on: ubuntu-latest\n\n    env:\n      CC: clang --target=amd64-unknown-netbsd --sysroot=${{ github.workspace }}/amd64-unknown-netbsd-sysroot\n      CFLAGS:  -I${{ github.workspace }}/amd64-unknown-netbsd-3rdroot/include -fPIC\n      LDFLAGS: -L${{ github.workspace }}/amd64-unknown-netbsd-3rdroot/lib\n      PKG_CONFIG_PATH: ${{ github.workspace }}/amd64-unknown-netbsd-3rdroot/lib/pkgconfig\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - run: sudo apt-get -y update\n      - run: sudo apt-get -y install clang cmake make automake autoconf pkg-config curl file\n\n      - run: install -d amd64-unknown-netbsd-sysroot\n      - run: install -d amd64-unknown-netbsd-3rdroot\n\n      - name: install amd64-unknown-netbsd-sysroot\n        run: |\n          for item in base comp\n          do\n            FILENAME=\"$item.tar.xz\"\n            curl -LO \"https://ftp.netbsd.org/pub/NetBSD/NetBSD-${{ matrix.netbsd-release-version }}/amd64/binary/sets/$FILENAME\"\n            tar vxf \"$FILENAME\" -C amd64-unknown-netbsd-sysroot\n          done\n\n      - name: build zlib\n        run: |\n          install -d src/zlib\n          cd         src/zlib\n          curl -L -o src.tar.gz https://distfiles.macports.org/zlib/zlib-1.3.1.tar.xz\n          tar vxf    src.tar.gz --strip-components=1\n          sed -i 's|/share/pkgconfig|/lib/pkgconfig|' CMakeLists.txt\n          cmake -S . -B build.d -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/amd64-unknown-netbsd-3rdroot -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_TESTING=OFF\n          cmake --build build.d\n          cmake --install build.d\n\n      - name: build libiconv\n        run: |\n          install -d src/libiconv\n          cd         src/libiconv\n          curl -L -o src.tar.gz https://distfiles.macports.org/libiconv/libiconv-1.17.tar.gz\n          tar vxf    src.tar.gz --strip-components=1\n          ./configure --host=amd64-unknown-netbsd --prefix=${{ github.workspace }}/amd64-unknown-netbsd-3rdroot --enable-extra-encodings --enable-static --disable-shared\n          make V=1\n          make install\n\n      - name: build libxml2\n        run: |\n          install -d src/libxml2\n          cd         src/libxml2\n          curl -L -o src.tar.gz https://download.gnome.org/sources/libxml2/2.11/libxml2-2.11.6.tar.xz\n          tar vxf    src.tar.gz --strip-components=1\n          ./configure --host=amd64-unknown-netbsd --prefix=${{ github.workspace }}/amd64-unknown-netbsd-3rdroot --with-zlib --without-lzma --without-python --without-readline --without-coverage --enable-ipv6 --enable-static --disable-shared LIBS=-liconv\n          make V=1\n          make install\n\n      - name: build libyaml\n        run: |\n          install -d src/libyaml\n          cd         src/libyaml\n          curl -L -o src.tar.gz https://github.com/yaml/libyaml/releases/download/0.2.5/yaml-0.2.5.tar.gz\n          tar vxf    src.tar.gz --strip-components=1\n          ./configure --host=amd64-unknown-netbsd --prefix=${{ github.workspace }}/amd64-unknown-netbsd-3rdroot\n          make V=1\n          make install\n\n      - name: build jansson\n        run: |\n          install -d src/jansson\n          cd         src/jansson\n          curl -L -o src.tar.gz https://github.com/akheron/jansson/releases/download/v2.14/jansson-2.14.tar.gz\n          tar vxf    src.tar.gz --strip-components=1\n          cmake -S . -B build.d -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/amd64-unknown-netbsd-3rdroot -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_TESTING=OFF -DJANSSON_BUILD_SHARED_LIBS=OFF -DJANSSON_BUILD_DOCS=OFF -DJANSSON_COVERAGE=OFF -DJANSSON_EXAMPLES=OFF -DJANSSON_WITHOUT_TESTS=ON\n          cmake --build build.d\n          cmake --install build.d\n\n      - name: build libpcre2\n        run: |\n          install -d src/libpcre2\n          cd         src/libpcre2\n          curl -L -o src.tar.gz https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2\n          tar vxf    src.tar.gz --strip-components=1\n          cmake -S . -B build.d -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/amd64-unknown-netbsd-3rdroot -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_TESTING=OFF -DJANSSON_BUILD_SHARED_LIBS=OFF -DCMAKE_C_STANDARD=99 -DCMAKE_C_STANDARD_REQUIRED=ON -DPCRE2_BUILD_PCRE2_8=ON -DPCRE2_BUILD_PCRE2_16=ON -DPCRE2_BUILD_PCRE2_32=ON -DPCRE2_BUILD_PCRE2GREP=OFF -DPCRE2_BUILD_TESTS=OFF -DPCRE2_SUPPORT_VALGRIND=OFF -DPCRE2_SUPPORT_UNICODE=ON\n          cmake --build build.d\n          cmake --install build.d\n\n      - run: ./autogen.sh\n      - run: |\n          ./configure --host=amd64-unknown-netbsd --prefix=${{ github.workspace }}/uctags-netbsd-amd64 --enable-static || {\n            cat config.log\n            exit 1\n          }\n      - run: make V=1\n      - run: make install\n\n      - run: readelf -h ctags\n      - run: readelf -d ctags\n      - run: file ctags | grep NetBSD\n"
  },
  {
    "path": ".github/workflows/cross-compile-for-android-on-macos.yml",
    "content": "name: cross compile for Android on macOS\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  cross-compile:\n    strategy:\n      fail-fast: false\n      matrix:\n        build-machine-os: [macos-15, macos-14, macos-26]\n\n    runs-on: ${{ matrix.build-machine-os }}\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - run: brew install make automake autoconf file\n\n      - run: ./autogen.sh\n\n      - name: Run ./configure ...\n        run: |\n          TOOLCHAIN_BASE_DIR=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64\n          TOOLCHAIN_BIN_DIR=$TOOLCHAIN_BASE_DIR/bin\n          SYSROOT=$TOOLCHAIN_BASE_DIR/sysroot\n\n          export CC=$TOOLCHAIN_BIN_DIR/armv7a-linux-androideabi24-clang\n          export AR=$TOOLCHAIN_BIN_DIR/llvm-ar\n          export RANLIB=$TOOLCHAIN_BIN_DIR/llvm-ranlib\n\n          export CFLAGS=\"--sysroot $SYSROOT -Qunused-arguments -Os -fpic\"\n          export CPPFLAGS=\"--sysroot $SYSROOT -Qunused-arguments\"\n          export LDFLAGS=\"--sysroot $SYSROOT\"\n\n          ./configure \\\n              --host=armv7a-linux-androideabi \\\n              --disable-iconv \\\n              --disable-xml \\\n              --disable-json \\\n              --disable-yaml \\\n              --disable-pcre2\n\n      - run: make V=1\n\n      - run: file ctags | grep 'ELF 32-bit LSB pie executable, ARM, EABI5'\n"
  },
  {
    "path": ".github/workflows/cross-compile-for-android-on-ubuntu.yml",
    "content": "name: cross compile for Android on ubuntu\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  cross-compile:\n    strategy:\n      fail-fast: false\n      matrix:\n        build-machine-os: [ubuntu-24.04, ubuntu-22.04]\n\n    runs-on: ${{ matrix.build-machine-os }}\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - run: sudo apt-get -y -o APT::Immediate-Configure=false update\n      - run: sudo apt-get -y -o APT::Immediate-Configure=false install gcc make automake autoconf file\n\n      - run: ./autogen.sh\n\n      - name: Run ./configure ...\n        run: |\n          TOOLCHAIN_BASE_DIR=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64\n          TOOLCHAIN_BIN_DIR=$TOOLCHAIN_BASE_DIR/bin\n          SYSROOT=$TOOLCHAIN_BASE_DIR/sysroot\n\n          export CC=$TOOLCHAIN_BIN_DIR/armv7a-linux-androideabi24-clang\n          export AR=$TOOLCHAIN_BIN_DIR/llvm-ar\n          export RANLIB=$TOOLCHAIN_BIN_DIR/llvm-ranlib\n\n          export CFLAGS=\"--sysroot $SYSROOT -Qunused-arguments -Os -fpic\"\n          export CPPFLAGS=\"--sysroot $SYSROOT -Qunused-arguments\"\n          export LDFLAGS=\"--sysroot $SYSROOT\"\n\n          set -ex\n\n          ./configure \\\n              --host=armv7a-linux-androideabi \\\n              --disable-iconv \\\n              --disable-xml \\\n              --disable-json \\\n              --disable-yaml \\\n              --disable-pcre2\n\n      - run: make V=1\n\n      # pie executable or shared object\n      - run: file ctags | grep 'ELF 32-bit LSB .*, ARM, EABI5'\n"
  },
  {
    "path": ".github/workflows/cross-compile-for-freebsd-on-ubuntu.yml",
    "content": "name: cross compile for FreeBSD on Ubuntu\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  build:\n    strategy:\n      fail-fast: false\n      matrix:\n        freebsd-release-version: ['14.2', '14.1', '14.0', '13.4', '13.3', '13.2', '13.1', '13.0']\n        # https://archive.freebsd.org/old-releases/amd64/\n\n    runs-on: ubuntu-latest\n\n    env:\n      CC: clang --target=amd64-unknown-freebsd --sysroot=${{ github.workspace }}/amd64-unknown-freebsd-sysroot\n      CFLAGS:  -I${{ github.workspace }}/amd64-unknown-freebsd-3rdroot/include -fPIC\n      LDFLAGS: -L${{ github.workspace }}/amd64-unknown-freebsd-3rdroot/lib\n      PKG_CONFIG_PATH: ${{ github.workspace }}/amd64-unknown-freebsd-3rdroot/lib/pkgconfig\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - run: sudo apt-get -y update\n      - run: sudo apt-get -y install clang cmake make automake autoconf curl file\n\n      - run: install -d amd64-unknown-freebsd-sysroot\n      - run: install -d amd64-unknown-freebsd-3rdroot\n\n      - run: curl -L -o amd64-unknown-freebsd-sysroot.txz https://archive.freebsd.org/old-releases/amd64/${{ matrix.freebsd-release-version }}-RELEASE/base.txz\n      - run: tar vxf    amd64-unknown-freebsd-sysroot.txz -C amd64-unknown-freebsd-sysroot\n\n      - name: build zlib\n        run: |\n          install -d src/zlib\n          cd         src/zlib\n          curl -L -o src.tar.gz https://distfiles.macports.org/zlib/zlib-1.3.1.tar.xz\n          tar vxf    src.tar.gz --strip-components=1\n          sed -i 's|/share/pkgconfig|/lib/pkgconfig|' CMakeLists.txt\n          cmake -S . -B build.d -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/amd64-unknown-freebsd-3rdroot -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_TESTING=OFF\n          cmake --build build.d\n          cmake --install build.d\n\n      - name: build libiconv\n        run: |\n          install -d src/libiconv\n          cd         src/libiconv\n          curl -L -o src.tar.gz https://distfiles.macports.org/libiconv/libiconv-1.17.tar.gz\n          tar vxf    src.tar.gz --strip-components=1\n          ./configure --host=amd64-unknown-freebsd --prefix=${{ github.workspace }}/amd64-unknown-freebsd-3rdroot --enable-extra-encodings --enable-static --disable-shared\n          make V=1\n          make install\n\n      - name: build libxml2\n        run: |\n          install -d src/libxml2\n          cd         src/libxml2\n          curl -L -o src.tar.gz https://download.gnome.org/sources/libxml2/2.11/libxml2-2.11.6.tar.xz\n          tar vxf    src.tar.gz --strip-components=1\n          ./configure --host=amd64-unknown-freebsd --prefix=${{ github.workspace }}/amd64-unknown-freebsd-3rdroot --with-zlib --without-lzma --without-python --without-readline --without-coverage --enable-ipv6 --enable-static --disable-shared LIBS=-liconv\n          make V=1\n          make install\n\n      - name: build libyaml\n        run: |\n          install -d src/libyaml\n          cd         src/libyaml\n          curl -L -o src.tar.gz https://github.com/yaml/libyaml/releases/download/0.2.5/yaml-0.2.5.tar.gz\n          tar vxf    src.tar.gz --strip-components=1\n          ./configure --host=amd64-unknown-freebsd --prefix=${{ github.workspace }}/amd64-unknown-freebsd-3rdroot\n          make V=1\n          make install\n\n      - name: build jansson\n        run: |\n          install -d src/jansson\n          cd         src/jansson\n          curl -L -o src.tar.gz https://github.com/akheron/jansson/releases/download/v2.14/jansson-2.14.tar.gz\n          tar vxf    src.tar.gz --strip-components=1\n          cmake -S . -B build.d -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/amd64-unknown-freebsd-3rdroot -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_TESTING=OFF -DJANSSON_BUILD_SHARED_LIBS=OFF -DJANSSON_BUILD_DOCS=OFF -DJANSSON_COVERAGE=OFF -DJANSSON_EXAMPLES=OFF -DJANSSON_WITHOUT_TESTS=ON\n          cmake --build build.d\n          cmake --install build.d\n\n      - name: build libpcre2\n        run: |\n          install -d src/libpcre2\n          cd         src/libpcre2\n          curl -L -o src.tar.gz https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2\n          tar vxf    src.tar.gz --strip-components=1\n          cmake -S . -B build.d -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/amd64-unknown-freebsd-3rdroot -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_TESTING=OFF -DJANSSON_BUILD_SHARED_LIBS=OFF -DCMAKE_C_STANDARD=99 -DCMAKE_C_STANDARD_REQUIRED=ON -DPCRE2_BUILD_PCRE2_8=ON -DPCRE2_BUILD_PCRE2_16=ON -DPCRE2_BUILD_PCRE2_32=ON -DPCRE2_BUILD_PCRE2GREP=OFF -DPCRE2_BUILD_TESTS=OFF -DPCRE2_SUPPORT_VALGRIND=OFF -DPCRE2_SUPPORT_UNICODE=ON\n          cmake --build build.d\n          cmake --install build.d\n\n      - run: ./autogen.sh\n      - run: |\n          ./configure --host=amd64-unknown-freebsd --prefix=${{ github.workspace }}/uctags-freebsd-amd64 --enable-static || {\n            cat config.log\n            exit 1\n          }\n      - run: make V=1\n      - run: make install\n\n      - run: readelf -h ctags\n      - run: readelf -d ctags\n      - run: file ctags | grep FreeBSD\n"
  },
  {
    "path": ".github/workflows/cross-compile-for-openbsd-on-ubuntu.yml",
    "content": "name: cross compile for OpenBSD on Ubuntu\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  build:\n    strategy:\n      fail-fast: false\n      matrix:\n        openbsd-release-version: ['7.8', '7.7']\n        # https://cdn.openbsd.org/pub/OpenBSD/\n\n    runs-on: ubuntu-latest\n\n    env:\n      CC: clang --target=amd64-unknown-openbsd --sysroot=${{ github.workspace }}/amd64-unknown-openbsd-sysroot\n      CFLAGS:  -I${{ github.workspace }}/amd64-unknown-openbsd-3rdroot/include -fPIC\n      LDFLAGS: -L${{ github.workspace }}/amd64-unknown-openbsd-3rdroot/lib\n      PKG_CONFIG_PATH: ${{ github.workspace }}/amd64-unknown-openbsd-3rdroot/lib/pkgconfig\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - run: sudo apt-get -y update\n      - run: sudo apt-get -y install clang cmake make automake autoconf pkg-config curl file\n\n      - run: install -d amd64-unknown-openbsd-sysroot\n      - run: install -d amd64-unknown-openbsd-3rdroot\n\n      - name: install amd64-unknown-openbsd-sysroot\n        run: |\n          major=\"$(printf '%s\\n' ${{ matrix.openbsd-release-version }} | cut -d. -f1)\"\n          minor=\"$(printf '%s\\n' ${{ matrix.openbsd-release-version }} | cut -d. -f2)\"\n\n          for item in base comp\n          do\n            FILENAME=\"$item$major$minor.tgz\"\n            curl -LO \"https://cdn.openbsd.org/pub/OpenBSD/${{ matrix.openbsd-release-version }}/amd64/$FILENAME\"\n            tar vxf \"$FILENAME\" -C amd64-unknown-openbsd-sysroot\n          done\n\n      - name: build zlib\n        run: |\n          install -d src/zlib\n          cd         src/zlib\n          curl -L -o src.tar.gz https://distfiles.macports.org/zlib/zlib-1.3.1.tar.xz\n          tar vxf    src.tar.gz --strip-components=1\n          sed -i 's|/share/pkgconfig|/lib/pkgconfig|' CMakeLists.txt\n          cmake -S . -B build.d -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/amd64-unknown-openbsd-3rdroot -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_TESTING=OFF\n          cmake --build build.d\n          cmake --install build.d\n\n      - name: build libiconv\n        run: |\n          install -d src/libiconv\n          cd         src/libiconv\n          curl -L -o src.tar.gz https://distfiles.macports.org/libiconv/libiconv-1.17.tar.gz\n          tar vxf    src.tar.gz --strip-components=1\n          ./configure --host=amd64-unknown-openbsd --prefix=${{ github.workspace }}/amd64-unknown-openbsd-3rdroot --enable-extra-encodings --enable-static --disable-shared\n          make V=1\n          make install\n\n      - name: build libxml2\n        run: |\n          install -d src/libxml2\n          cd         src/libxml2\n          curl -L -o src.tar.gz https://download.gnome.org/sources/libxml2/2.11/libxml2-2.11.6.tar.xz\n          tar vxf    src.tar.gz --strip-components=1\n          ./configure --host=amd64-unknown-openbsd --prefix=${{ github.workspace }}/amd64-unknown-openbsd-3rdroot --with-zlib --without-lzma --without-python --without-readline --without-coverage --enable-ipv6 --enable-static --disable-shared LIBS=-liconv\n          make V=1\n          make install\n          cd ${{ github.workspace }}/amd64-unknown-openbsd-3rdroot/lib/pkgconfig\n          sed -i '/^Requires: /d'      libxml-2.0.pc\n          printf 'Requires: zlib\\n' >> libxml-2.0.pc\n\n      - name: build libyaml\n        run: |\n          install -d src/libyaml\n          cd         src/libyaml\n          curl -L -o src.tar.gz https://github.com/yaml/libyaml/releases/download/0.2.5/yaml-0.2.5.tar.gz\n          tar vxf    src.tar.gz --strip-components=1\n          ./configure --host=amd64-unknown-openbsd --prefix=${{ github.workspace }}/amd64-unknown-openbsd-3rdroot\n          make V=1\n          make install\n\n      - name: build jansson\n        run: |\n          install -d src/jansson\n          cd         src/jansson\n          curl -L -o src.tar.gz https://github.com/akheron/jansson/releases/download/v2.14/jansson-2.14.tar.gz\n          tar vxf    src.tar.gz --strip-components=1\n          cmake -S . -B build.d -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/amd64-unknown-openbsd-3rdroot -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_TESTING=OFF -DJANSSON_BUILD_SHARED_LIBS=OFF -DJANSSON_BUILD_DOCS=OFF -DJANSSON_COVERAGE=OFF -DJANSSON_EXAMPLES=OFF -DJANSSON_WITHOUT_TESTS=ON\n          cmake --build build.d\n          cmake --install build.d\n\n      - name: build libpcre2\n        run: |\n          install -d src/libpcre2\n          cd         src/libpcre2\n          curl -L -o src.tar.gz https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2\n          tar vxf    src.tar.gz --strip-components=1\n          cmake -S . -B build.d -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/amd64-unknown-openbsd-3rdroot -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_TESTING=OFF -DJANSSON_BUILD_SHARED_LIBS=OFF -DCMAKE_C_STANDARD=99 -DCMAKE_C_STANDARD_REQUIRED=ON -DPCRE2_BUILD_PCRE2_8=ON -DPCRE2_BUILD_PCRE2_16=ON -DPCRE2_BUILD_PCRE2_32=ON -DPCRE2_BUILD_PCRE2GREP=OFF -DPCRE2_BUILD_TESTS=OFF -DPCRE2_SUPPORT_VALGRIND=OFF -DPCRE2_SUPPORT_UNICODE=ON\n          cmake --build build.d\n          cmake --install build.d\n\n      - run: rm ${{ github.workspace }}/amd64-unknown-openbsd-3rdroot/lib/lib*.so\n\n      - run: ./autogen.sh\n      - run: |\n          ./configure --host=amd64-unknown-openbsd --prefix=${{ github.workspace }}/uctags-openbsd-amd64 || {\n            cat config.log\n            exit 1\n          }\n      - run: cat config.log\n      - run: make V=1\n      - run: make install\n\n      - run: readelf -h ctags\n      - run: readelf -d ctags\n      - run: file ctags | grep OpenBSD\n"
  },
  {
    "path": ".github/workflows/cross-compile-for-windows-on-macos.yml",
    "content": "name: cross compile for Windows on macOS\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  cross-compile:\n    strategy:\n      fail-fast: false\n      matrix:\n        build-machine-os: [macos-15, macos-14, macos-26]\n        target: [i686-w64-mingw32,x86_64-w64-mingw32]\n\n    runs-on: ${{ matrix.build-machine-os }}\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - run: brew install mingw-w64 make automake autoconf file\n\n      - run: ./autogen.sh\n\n      - name: Run ./configure ...\n        run: |\n          ./configure \\\n              --host=${{ matrix.target }} \\\n              --disable-iconv \\\n              --disable-xml \\\n              --disable-json \\\n              --disable-yaml \\\n              --disable-pcre2 \\\n              CC=${{ matrix.target }}-gcc \\\n              CFLAGS='-v' \\\n              AR=${{ matrix.target }}-ar \\\n              RANLIB=${{ matrix.target }}-ranlib \\\n              WINDRES=${{ matrix.target }}-windres\n\n      - run: make V=1\n\n      - run: file ctags.exe | grep PE32\n"
  },
  {
    "path": ".github/workflows/cross-compile-for-windows-on-ubuntu.yml",
    "content": "name: cross compile for Windows on Ubuntu\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  cross-compile:\n    strategy:\n      fail-fast: false\n      matrix:\n        build-machine-os: [ubuntu-22.04, ubuntu-24.04]\n        target: [i686-w64-mingw32,x86_64-w64-mingw32]\n\n    runs-on: ${{ matrix.build-machine-os }}\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - run: sudo apt-get -y -o APT::Immediate-Configure=false update\n      - run: sudo apt-get -y -o APT::Immediate-Configure=false install mingw-w64 gcc make automake autoconf file\n\n      - run: ./autogen.sh\n\n      - name: Run ./configure ...\n        run: |\n          ./configure \\\n              --host=${{ matrix.target }} \\\n              --disable-iconv \\\n              --disable-xml \\\n              --disable-json \\\n              --disable-yaml \\\n              --disable-pcre2 \\\n              CC=${{ matrix.target }}-gcc \\\n              CFLAGS='-v' \\\n              AR=${{ matrix.target }}-ar \\\n              RANLIB=${{ matrix.target }}-ranlib \\\n              WINDRES=${{ matrix.target }}-windres\n\n      - run: make V=1\n\n      - run: file ctags.exe | grep PE32\n"
  },
  {
    "path": ".github/workflows/run-citre-tests.yml",
    "content": "# Citre (https://github.com/universal-ctags/citre) is a readtags frontend for\n# Emacs. This workflow runs unit tests of Citre to make sure changes in\n# readtags doesn't break the behavior that Citre expects.\n\n# Ref: https://github.com/universal-ctags/citre/issues/58#issuecomment-846229409\n\nname: run Citre tests on GNU/Linux\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n    runs-on: ubuntu-latest\n\n    env:\n      CC: gcc\n      READTAGS: '${{ github.workspace }}/readtags'\n\n    steps:\n      - uses: actions/checkout@v6\n      - name: update package information\n        run: sudo apt-get -y -o APT::Immediate-Configure=false update\n      - name: install tools and libraries\n        run: sudo apt-get -y -o APT::Immediate-Configure=false install pkg-config automake libjansson-dev libyaml-dev libseccomp-dev libxml2-dev\n      - name: autogen.sh\n        run: ./autogen.sh\n      - name: report the version of cc\n        run: $CC --version\n      - name: report the version of make\n        run: make --version\n      - name: configure\n        run: ./configure\n      - name: make\n        run: make\n      - name: report features\n        run: ./ctags --list-features\n      - name: install Emacs\n        run: sudo apt-get -y -o APT::Immediate-Configure=false install emacs\n      - name: checkout Citre repo\n        uses: actions/checkout@v6\n        with:\n          repository: 'universal-ctags/citre'\n          path: 'citre'\n      - name: run Citre unit tests for tags backend\n        working-directory: 'citre'\n        run: make test-tags\n"
  },
  {
    "path": ".github/workflows/tagging.yml",
    "content": "name: Create a weekly tag\n\non:\n  schedule:\n    - cron:  '0 0 * * 0'\n\njobs:\n  tag:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n      - run: misc/git-tag-maybe.sh\n"
  },
  {
    "path": ".github/workflows/testing-bsds.yml.bak",
    "content": "name: run units target on FreeBSD OpenBSD NetBSD\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  freebsd:\n    runs-on: macos-12\n\n    strategy:\n      fail-fast: false\n      matrix:\n        freebsd-version: [12,13]\n\n    steps:\n    - uses: actions/checkout@v3\n\n    - uses: actions/cache@v2\n      with:\n        path: ~/.vagrant.d/boxes\n        key: vagrant-generic-freebsd-${{ matrix.freebsd-version }}\n        restore-keys: |\n          vagrant-generic-freebsd-${{ matrix.freebsd-version }}\n\n    # https://app.vagrantup.com/boxes/search?utf8=%E2%9C%93&sort=downloads&provider=&q=freebsd\n    # https://github.com/leleliu008/github-actions-vagrant\n    - uses: leleliu008/github-actions-vagrant@v2\n      with:\n        mem: 2048\n        box: generic/freebsd${{ matrix.freebsd-version }}\n        log: warn\n        run: |\n          run pkg install -y automake pkgconf gmake python3\n          run freebsd-version\n          run cc --version\n          run ./autogen.sh\n          run ./configure --prefix=/usr\n          run gmake\n          run gmake install\n          run file ctags\n          run ctags --version\n          run gmake check CI=gha+vagrant+freebsd\n          run gmake roundtrip CI=gha+vagrant+freebsd\n\n  openbsd:\n    needs: freebsd\n    runs-on: macos-12\n\n    steps:\n    - uses: actions/checkout@v3\n\n    - uses: actions/cache@v2\n      with:\n        path: ~/.vagrant.d/boxes\n        key: vagrant-generic-openbsd-7\n        restore-keys: |\n          vagrant-generic-openbsd-7\n\n    - uses: leleliu008/github-actions-vagrant@v2\n      with:\n        mem: 2048\n        box: generic/openbsd7\n        log: warn\n        run: |\n          export AUTOCONF_VERSION=2.69\n          export AUTOMAKE_VERSION=1.16\n              \n          export CFLAGS='-I/usr/local/include -L/usr/local/lib'\n              \n          if [ ! -f /usr/local/lib/libiconv.so ] ; then\n            sudo ln -s /usr/local/lib/libiconv.so.* /usr/local/lib/libiconv.so\n          fi\n              \n          run sudo pkg_add automake-1.16.3 gmake\n\n          run cc --version\n            \n          run ./autogen.sh\n          run ./configure --prefix=/usr\n          run gmake\n          run sudo gmake install\n          run file /usr/bin/ctags\n          run ctags --version\n          # bugs to fix\n          #run make check CI=gha+vagrant+openbsd\n          run gmake roundtrip CI=gha+vagrant+openbsd\n\n  netbsd:\n    needs: openbsd\n    runs-on: macos-12\n\n    steps:\n    - uses: actions/checkout@v3\n\n    - uses: actions/cache@v2\n      with:\n        path: ~/.vagrant.d/boxes\n        key: vagrant-generic-netbsd-9\n        restore-keys: |\n          vagrant-generic-netbsd-9\n\n    - uses: leleliu008/github-actions-vagrant@v2\n      with:\n        mem: 2048\n        box: generic/netbsd9\n        log: warn\n        run: |\n          run sudo pkgin -y install mozilla-rootcerts automake autoconf pkg-config gmake\n\n          run cc --version\n\n          run ./autogen.sh\n          run ./configure --prefix=/usr\n          run gmake\n          run sudo gmake install\n          run file /usr/bin/ctags\n          run ctags --version\n          # bugs to fix\n          #run make check CI=gha+vagrant+netbsd\n          run gmake roundtrip CI=gha+vagrant+netbsd\n"
  },
  {
    "path": ".github/workflows/testing-on-alpine.yml",
    "content": "name: run units target on AlpineLinux\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n    strategy:\n      fail-fast: false\n      matrix:\n        tag: ['3.23', '3.22', '3.21', '3.20', '3.19', '3.18', '3.17', '3.16']\n\n    runs-on: ubuntu-latest\n\n    container: alpine:${{ matrix.tag }}\n\n    steps:\n      - run: apk add libc-dev gcc make automake autoconf pkgconf python3 file diffutils git pcre2-dev jansson-dev yaml-dev libxml2-dev\n\n      # this is to fix https://github.com/actions/checkout/issues/760\n      - run: git config --global --add safe.directory /__w/ctags/ctags\n\n      - uses: actions/checkout@v6\n\n      - run: cc --version\n\n      - run: ./autogen.sh\n      - run: ./configure --prefix=/usr\n      - run: make\n      - run: make install\n      - run: file /usr/bin/ctags\n      - run: ctags --version\n      - run: make check V=1\n      - run: make roundtrip\n\n\n  chroot_qemu:\n\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        target-arch: [loongarch64, aarch64, ppc64le, riscv64, s390x]\n\n    timeout-minutes: 45\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - run: |\n          cat > run.sh <<EOF\n          set -ex\n\n          run() {\n            printf \"\\033[0;35m==>\\033[0m \\033[0;32m%b\\n\\033[0m\" \"\\$*\"\n            eval \"\\$@\"\n          }\n\n          run apk add libc-dev gcc make automake autoconf pkgconf python3 diffutils pcre2-dev jansson-dev yaml-dev libxml2-dev\n\n          run ./autogen.sh\n          run ./configure --enable-debugging\n          run make\n\n          run readelf -h ctags\n          run readelf -d ctags\n\n          run ./ctags --version\n\n          run make check V=1\n          run make roundtrip\n          run make tmain CI=1 CTAGS_DEP= READTAGS_DEP= OPTSCRIPT_DEP=\n          run make units CI=1 CTAGS_DEP=\n          EOF\n\n      - run: curl -LO https://raw.githubusercontent.com/alpinelinux/alpine-chroot-install/master/alpine-chroot-install\n      - run: chmod +x alpine-chroot-install\n      - run: sudo ./alpine-chroot-install -d /alpine -a ${{ matrix.target-arch }}\n      - run: /alpine/enter-chroot sh run.sh\n"
  },
  {
    "path": ".github/workflows/testing-on-cygwin.yml",
    "content": "name: run units target on Cygwin\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:  \n    runs-on: windows-latest\n\n    defaults:\n      run:\n        shell: C:\\tools\\cygwin\\bin\\bash.exe -l -i {0}\n\n    steps:\n    # https://www.cygwin.com/faq/faq.html#faq.setup.cli\n    - run: Invoke-WebRequest -OutFile setup-x86_64.exe \"http://cygwin.com/setup-x86_64.exe\"\n      shell: pwsh\n\n    - run: .\\setup-x86_64.exe --quiet-mode --no-desktop --no-shortcuts --no-startmenu --only-site --site http://mirrors.kernel.org/sourceware/cygwin/ --root C:\\tools\\cygwin --local-package-dir C:\\tools\\cygwin\\packages --packages gcc-g++,make,automake,autoconf,pkg-config,dos2unix,libiconv-devel,libjansson-devel,libxml2-devel,libyaml-devel | Out-Default\n      shell: pwsh\n\n    - run: git config --global core.autocrlf input\n      shell: bash\n\n    - uses: actions/checkout@v6\n    \n    - run: printf 'cd %s' \"$(cygpath '${{ github.workspace }}')\" >> ~/.bashrc\n\n    - run: ./autogen.sh\n    - run: ./configure --prefix=/usr\n    - run: make V=1\n    - run: make install\n    - run: file /usr/bin/ctags\n    - run: /usr/bin/ctags --version\n    - run: make check V=1\n    - run: make roundtrip\n"
  },
  {
    "path": ".github/workflows/testing-on-freebsd.yml",
    "content": "name: run units target on FreeBSD\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        freebsd-version: ['15.0', '14.3', '14.2', '14.1', '14.0', '13.5', '13.4', '13.3', '13.2']\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - uses: cross-platform-actions/action@master\n        with:\n          operating_system: freebsd\n          version: ${{ matrix.freebsd-version }}\n          shell: bash\n          run: |\n            run() {\n              printf \"\\033[0;35m==>\\033[0m \\033[0;32m%b\\n\\033[0m\" \"$*\"\n              eval \"$@\"\n            }\n\n            run sudo pkg install -y automake gmake pkgconf jansson libyaml libxml2 libiconv python3\n\n            run freebsd-version\n            run cc --version\n\n            run ./autogen.sh\n            run ./configure --prefix=/usr\n            run gmake\n            run sudo gmake install\n\n            run readelf -h ctags\n            run readelf -d ctags\n\n            run ctags --version\n\n            run gmake check CI=gha+vagrant+freebsd\n            run gmake roundtrip CI=gha+vagrant+freebsd\n"
  },
  {
    "path": ".github/workflows/testing-on-macos.yml",
    "content": "name: run units target on macOS\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n\n    strategy:\n      matrix:\n        os: [macos-15, macos-14, macos-26]\n\n    runs-on: ${{ matrix.os }}\n\n    steps:\n    - uses: actions/checkout@v6\n\n    # temporarily disabled, because it always fails these days.\n    #- run: brew update\n\n    # NOTE: DO NOT try to install libiconv and libxml2 package via brew, because macOS already provides them.\n    # NOTE: DO NOT try to install python3 package via brew, it has already been included in macos-xx runner images\n    # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md\n\n    - if: matrix.os == 'macos-26'\n      run: brew install --overwrite python@3.12\n\n    - run: brew install automake jansson libyaml pcre2\n\n    - run: pip3 install docutils --break-system-packages\n\n    - run: cc --version\n    - run: make --version\n\n    - run: ./autogen.sh\n    - run: ./configure --enable-debugging --enable-iconv\n    - run: make -j2\n\n    - run: ./ctags --version\n    - run: ./ctags --list-features\n\n    - run: make check\n    - run: make roundtrip\n    - run: make tmain\n    - run: make units\n"
  },
  {
    "path": ".github/workflows/testing-on-msys2.yml",
    "content": "name: run units target on MSYS2\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n    runs-on: windows-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        msystem: [MINGW32, MINGW64, CLANG64]\n\n    defaults:\n      run:\n        shell: msys2 {0}\n\n    steps:\n    - uses: msys2/setup-msys2@v2\n      with:\n        msystem: ${{ matrix.msystem }}\n        update: true\n        install: automake autoconf make dos2unix pkg-config\n        pacboy: toolchain:p python-sphinx:p jansson:p libxml2:p libyaml:p pcre2:p\n\n    - run: git config --global core.autocrlf input\n      shell: bash\n\n    - uses: actions/checkout@v6\n\n    - run: ./autogen.sh\n    - run: ./configure --prefix=/usr\n    - run: make V=1\n    - run: make install\n    - run: file /usr/bin/ctags\n    - run: ctags --version\n\n    - run: make check V=1\n\n    # FAILED: \"./readtags.exe\" -t \"/d/a/ctags2/ctags2/Units/parser-asciidoc.r/utf8-asciidoc.d/expected.tags\" - \"@Ѐ–𐀀\"\n    # The raw tag name was \"@Ѐ–𐀀\"\n    #- run: make roundtrip\n\n    - run: make tmain\n    - run: make units\n"
  },
  {
    "path": ".github/workflows/testing-on-netbsd.yml",
    "content": "name: run units target on NetBSD\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        netbsd-version: ['10.1', '10.0', '9.4', '9.3', '9.2']\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - uses: cross-platform-actions/action@v0.32.0\n        with:\n          operating_system: netbsd\n          version: ${{ matrix.netbsd-version }}\n          shell: bash\n          run: |\n            run() {\n              printf \"\\033[0;35m==>\\033[0m \\033[0;32m%b\\n\\033[0m\" \"$*\"\n              eval \"$@\"\n            }\n\n            # DO NOT try to install libxml2, because it has already been pre-installed\n            run sudo pkgin -y install automake autoconf gmake pkg-config jansson libyaml libiconv\n\n            run cc --version\n\n            run ./autogen.sh\n            run ./configure --prefix=/usr\n            run gmake\n            run sudo gmake install\n\n            run readelf -h /usr/bin/ctags\n            run readelf -d /usr/bin/ctags\n\n            run ctags --version\n\n            # bugs to fix\n            #run make check CI=gha+vagrant+netbsd\n            run gmake roundtrip CI=gha+vagrant+netbsd\n"
  },
  {
    "path": ".github/workflows/testing-on-openbsd.yml",
    "content": "name: run units target on OpenBSD\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        openbsd-version: ['7.8', '7.7', '7.6', '7.5', '7.4', '7.3', '7.2']\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - uses: cross-platform-actions/action@master\n        with:\n          operating_system: openbsd\n          version: ${{ matrix.openbsd-version }}\n          shell: bash\n          run: |\n            run() {\n              printf \"\\033[0;35m==>\\033[0m \\033[0;32m%b\\n\\033[0m\" \"$*\"\n              eval \"$@\"\n            }\n\n            export AUTOCONF_VERSION=2.69\n            export AUTOMAKE_VERSION=1.16\n\n            export  CFLAGS='-I/usr/local/include'\n            export LDFLAGS='-L/usr/local/lib'\n\n            run sudo pkg_add autoconf%2.69 automake%1.16 gmake pkgconf jansson libyaml libxml libiconv\n\n            run cc --version\n\n            run ./autogen.sh\n            run ./configure --prefix=/usr\n            run gmake\n            run sudo gmake install\n\n            run readelf -h /usr/bin/ctags\n            run readelf -d /usr/bin/ctags\n\n            run ctags --version\n\n            # bugs to fix\n            #run make check CI=gha+vagrant+openbsd\n            run gmake roundtrip CI=gha+vagrant+openbsd\n"
  },
  {
    "path": ".github/workflows/testing-on-ubi.yml",
    "content": "name: run units target on UBI\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n    strategy:\n      fail-fast: false\n      matrix:\n        tag: ['8' ]\n\n    runs-on: ubuntu-latest\n\n    container: registry.access.redhat.com/ubi${{ matrix.tag }}:latest\n\n    steps:\n      - run: dnf install -y --enablerepo=ubi-${{ matrix.tag }}-appstream-rpms --enablerepo=ubi-${{ matrix.tag }}-baseos-rpms --enablerepo=ubi-${{ matrix.tag }}-codeready-builder-rpms git python3 gcc automake autoconf pkgconfig make libxml2-devel libyaml-devel pcre2-devel findutils diffutils sudo file\n\n      # this is to fix https://github.com/actions/checkout/issues/760\n      - run: git config --global --add safe.directory /__w/ctags/ctags\n\n      - uses: actions/checkout@v6\n\n      - run: cc --version\n\n      - run: ./autogen.sh\n      - run: ./configure --prefix=/usr\n      - run: make\n      - run: make install\n      - run: file /usr/bin/ctags\n      - run: ctags --version\n      - run: make check V=1\n      - run: make roundtrip\n"
  },
  {
    "path": ".github/workflows/testing-on-ubuntu.yml",
    "content": "name: run units target on Ubuntu\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n\n    strategy:\n      matrix:\n        os: [ubuntu-24.04, ubuntu-22.04]\n        compiler: [gcc, clang]\n\n    runs-on: ${{ matrix.os }}\n\n    env:\n      DEBIAN_FRONTEND: noninteractive\n\n      CC: ${{ matrix.compiler }}\n\n    steps:\n    - uses: actions/checkout@v6\n      with:\n        fetch-depth: 0\n\n    - run: sudo apt-get -y -o APT::Immediate-Configure=false update\n    - run: sudo apt-get -y -o APT::Immediate-Configure=false install pkg-config automake ${{ matrix.compiler }} gdb bash python3-docutils libseccomp-dev libjansson-dev libyaml-dev libxml2-dev libpcre2-dev\n\n    # valgrind doesn't work well with an executable built with clang 14.\n    # https://forum.manjaro.org/t/valgrind-fails-possibly-corrupted-debuginfo-file/118156\n    - if: matrix.compiler == 'clang' && matrix.os == 'ubuntu-22.04'\n      run: |\n        type clang > /dev/null && clang --version | head -1 | grep -q 14 \\\n        || sudo apt-get -y -o APT::Immediate-Configure=false install valgrind\n\n    - run: ${{ matrix.compiler }} --version\n    - run: make --version\n\n    - run: ./autogen.sh\n\n    - run: mkdir -p build.d\n\n    - run: cd build.d && ../configure --enable-debugging --enable-iconv\n\n    - run: make -C build.d -j2\n\n    - run: cd build.d && ./ctags --list-features\n    - run: cd build.d && ./ctags --help\n    - run: cd build.d && ./ctags --version\n\n    - run: make -C build.d check\n    - run: make -C build.d roundtrip\n    - run: make -C build.d dist\n\n    #############################################################################\n\n    - run: mkdir -p dist-src\n\n    - run: tar xf build.d/universal-ctags*tar.gz -C dist-src --strip-components=1\n\n    - run: mkdir -p build2.d\n\n    - run: cd build2.d && ../dist-src/configure --enable-debugging\n\n    - run: cd build2.d && make -j2\n\n    - run: cd build2.d && ./ctags --list-features\n    - run: cd build2.d && ./ctags --help\n    - run: cd build2.d && ./ctags --version\n\n      # Our sandbox doesn't work with gcov.\n      # Following cases target ctags without gcov.\n    - run: cd build2.d && make tmain UNITS=sandbox,sandbox-crash,sandbox-default-req,sandbox-unknown-submode\n    - run: cd build2.d && make clean\n"
  },
  {
    "path": ".github/workflows/testing-with-valgrind.yml",
    "content": "name: run units target under VALGRIND\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v6\n\n    - run: sudo apt-get update\n    - run: sudo apt-get install valgrind pkg-config automake bash libjansson-dev libyaml-dev libseccomp-dev libxml2-dev libpcre2-dev gdb\n\n    - run: cc --version\n\n    - run: ./autogen.sh\n    - run: ./configure --enable-debugging\n    - run: make CFLAGS='-g -O0'\n    - run: make units VG=1\n"
  },
  {
    "path": ".gitignore",
    "content": "*-actual.txt\n*-diff.txt\n*.func-sort-c.html\n*.func.html\n*.gcda\n*.gcno\n*.gcov\n*.gcov.html\n*.o\n*.obj\n*.od\n*.pdf\n*.pyc\n*.swp\n*.c3workspace\n*.c3workspace.user\n*.tar.gz\n*.TMP\n*.tmp\n*~\n/Makefile\n/packcc\n/packcc.exe\n/packcc.dSYM\n.cache\n.deps\n.dirstamp\n.DS_Store\na.out\naclocal.m4\nautom4te.cache\nbadinput\ncommit-stamp\ncompile\ncompile_commands.json\nconfig.cache\nconfig.guess\nconfig.h\nconfig.h.in\nconfig.log\nconfig.status\nconfig.sub\nconfigure\ncore.*\nctags\nctags-universal*\nctags.exe\nctags.ref\nctags.ref.exe\ndctags\ndctags.exe\ndepcomp\ngdb-backtrace.txt\nGNUmakefile.in\ninstall-sh\nlast-aclocal.m4\nlibctags.a\nlibutil.a\nMakefile.in\nmini-geany\nmini-geany.exe\nmissing\nmkinstalldirs\noptscript\nperf.data*\nreadtags\nreadtags.exe\nrepoinfo.h\nrespmvc\nstamp-h1\nSTDERR.*\nsyntax.vim\ntags\ntags.ref\ntags.test\ntest.*.diff\ntg\ntinst-root\nutiltest\nwin32/*.aps\nwin32/*.opensdf\nwin32/*.sdf\nwin32/*.suo\nwin32/*.user\nwin32/[Dd]ebug/\nwin32/[Rr]elease/\n_build\nman/ctags.1\nman/ctags.1.html\nman/ctags.1.rst\nman/ctags-*.5\nman/ctags-*.5.rst\nman/ctags-*.5.html\nman/ctags-*.7\nman/ctags-*.7.rst\nman/ctags-*.7.html\nman/GNUmakefile\nman/readtags.1\nman/readtags.1.rst\nman/readtags.1.html\nman/tags.5\nman/tags.5.rst\nman/tags.5.html\nman/*.[157].in\nManTest\nmisc/mini-geany.actual\nTmain/**/Makefile\nTmain/**/Makefile.am\nTmain/**/Makefile.in\nUnits/**/Makefile\nUnits/**/Makefile.am\nUnits/**/Makefile.in\nTmain/dist.m4\nUnits/dist.m4\nVALGRIND.tmp.core.*\ngnulib/Makefile\ngnulib/alloca.h\ngnulib/ctype.h\ngnulib/inttypes.h\ngnulib/langinfo.h\ngnulib/libgnu.a\ngnulib/limits.h\ngnulib/locale.h\ngnulib/malloc/dynarray-skeleton.gl.h\ngnulib/malloc/dynarray.gl.h\ngnulib/stdlib.h\ngnulib/string.h\ngnulib/unistd.h\ngnulib/wchar.h\ngnulib/wctype.h\ngnulib/sys/types.h\n"
  },
  {
    "path": ".indent.pro",
    "content": "--blank-before-sizeof\n--blank-lines-after-procedures\n--brace-indent0\n--braces-after-if-line\n--braces-on-struct-decl-line\n--break-after-boolean-operator\n--case-brace-indentation0\n--case-indentation0\n--comment-indentation0\n--continuation-indentation4\n--cuddle-do-while\n--declaration-comment-column0\n--declaration-indentation0\n--dont-break-function-decl-args\n--dont-break-procedure-type\n--dont-line-up-parentheses\n--honour-newlines\n--indent-level4\n--line-length80\n--paren-indentation4\n--preprocessor-indentation1\n--no-blank-lines-after-commas\n--space-after-cast\n--space-after-for\n--space-after-if\n--space-after-procedure-calls\n--space-after-while\n--space-special-semicolon\n--start-left-side-of-comments\n--struct-brace-indentation4\n--tab-size4\n"
  },
  {
    "path": ".readthedocs.yaml",
    "content": "# .readthedocs.yaml\n# Read the Docs configuration file\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details\n\n# Required\nversion: 2\n\n# Set the version of Python and other tools you might need\nbuild:\n  os: ubuntu-22.04\n  tools:\n    python: \"3.11\"\n\n# Build documentation in the docs/ directory with Sphinx\nsphinx:\n  configuration: docs/conf.py\n\n# We recommend specifying your dependencies to enable reproducible builds:\n# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html\n# python:\n#   install:\n#   - requirements: docs/requirements.txt\n"
  },
  {
    "path": ".uncrustify.cfg",
    "content": "tok_split_gte=false\nutf8_byte=false\nutf8_force=false\nindent_cmt_with_tabs=false\nindent_align_string=false\nindent_braces=false\nindent_braces_no_func=false\nindent_braces_no_class=false\nindent_braces_no_struct=false\nindent_brace_parent=false\nindent_namespace=false\nindent_extern=false\nindent_class=false\nindent_class_colon=false\nindent_else_if=false\nindent_var_def_cont=false\nindent_func_call_param=false\nindent_func_def_param=false\nindent_func_proto_param=false\nindent_func_class_param=false\nindent_func_ctor_var_param=false\nindent_template_param=false\nindent_func_param_double=false\nindent_relative_single_line_comments=false\nindent_col1_comment=false\nindent_access_spec_body=false\nindent_paren_nl=false\nindent_comma_paren=false\nindent_bool_paren=false\nindent_first_bool_expr=false\nindent_square_nl=false\nindent_preserve_sql=false\nindent_align_assign=true\nsp_balance_nested_parens=false\nalign_keep_tabs=false\nalign_with_tabs=false\nalign_on_tabstop=false\nalign_number_left=false\nalign_func_params=false\nalign_same_func_call_params=false\nalign_var_def_colon=false\nalign_var_def_attribute=false\nalign_var_def_inline=false\nalign_right_cmt_mix=false\nalign_on_operator=false\nalign_mix_var_proto=false\nalign_single_line_func=false\nalign_single_line_brace=false\nalign_nl_cont=false\nalign_left_shift=true\nalign_oc_decl_colon=false\nnl_collapse_empty_body=false\nnl_assign_leave_one_liners=false\nnl_class_leave_one_liners=false\nnl_enum_leave_one_liners=false\nnl_getset_leave_one_liners=false\nnl_func_leave_one_liners=false\nnl_if_leave_one_liners=false\nnl_multi_line_cond=false\nnl_multi_line_define=false\nnl_before_case=false\nnl_after_case=false\nnl_after_return=false\nnl_after_semicolon=false\nnl_after_brace_open=false\nnl_after_brace_open_cmt=false\nnl_after_vbrace_open=false\nnl_after_vbrace_open_empty=false\nnl_after_brace_close=false\nnl_after_vbrace_close=false\nnl_define_macro=false\nnl_squeeze_ifdef=false\nnl_ds_struct_enum_cmt=false\nnl_ds_struct_enum_close_brace=false\nnl_create_if_one_liner=false\nnl_create_for_one_liner=false\nnl_create_while_one_liner=false\nls_for_split_full=false\nls_func_split_full=false\nnl_after_multiline_comment=false\neat_blanks_after_open_brace=false\neat_blanks_before_close_brace=false\nmod_full_brace_if_chain=false\nmod_pawn_semicolon=false\nmod_full_paren_if_bool=false\nmod_remove_extra_semicolon=false\nmod_sort_import=false\nmod_sort_using=false\nmod_sort_include=false\nmod_move_case_break=false\nmod_remove_empty_return=false\ncmt_indent_multi=true\ncmt_c_group=false\ncmt_c_nl_start=false\ncmt_c_nl_end=false\ncmt_cpp_group=false\ncmt_cpp_nl_start=false\ncmt_cpp_nl_end=false\ncmt_cpp_to_c=false\ncmt_star_cont=false\ncmt_multi_check_last=true\ncmt_insert_before_preproc=false\npp_indent_at_level=false\npp_region_indent_code=false\npp_if_indent_code=false\npp_define_at_level=false\ninput_tab_size=4\noutput_tab_size=4\nindent_columns=4\nindent_brace=0\nindent_switch_case=4\nnl_after_func_body=2\nnl_after_func_body_one_liner=2\nindent_with_tabs=1\nsp_arith=add\nsp_assign=add\nsp_assign_default=add\nsp_enum_assign=add\nsp_bool=add\nsp_compare=add\nsp_inside_paren=remove\nsp_paren_paren=remove\nsp_before_ptr_star=force\nsp_between_ptr_star=remove\nsp_after_ptr_star=remove\nsp_after_ptr_star_func=remove\nsp_before_sparen=force\nsp_before_semi_for_empty=force\nsp_before_square=add\nsp_before_squares=add\nsp_after_cast=force\nsp_sizeof_paren=force\nsp_func_call_paren=force\nsp_return_paren=force\nsp_not=force\nnl_start_of_file=remove\nnl_end_of_file=remove\nnl_enum_brace=remove\nnl_struct_brace=remove\nnl_union_brace=remove\nnl_if_brace=add\nnl_brace_else=add\nnl_elseif_brace=add\nnl_else_brace=add\nnl_else_if=remove\nnl_for_brace=add\nnl_while_brace=add\nnl_do_brace=add\nnl_brace_while=remove\nnl_switch_brace=add\nnl_fdef_brace=force\n"
  },
  {
    "path": "COPYING",
    "content": "\t\t    GNU GENERAL PUBLIC LICENSE\n\t\t       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\t\t\t    Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Library General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\f\n\t\t    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\f\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\f\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\f\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n\t\t\t    NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n\t\t     END OF TERMS AND CONDITIONS\n\f\n\t    How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) 19yy  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) 19yy name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General\nPublic License instead of this License.\n"
  },
  {
    "path": "Makefile.am",
    "content": "ACLOCAL_AMFLAGS = -I m4\n#AM_CPPFLAGS = -I$(top_builddir)/gnulib -I$(top_srcdir)/gnulib\nGNULIB_DIR = gnulib\nGNULIB_CPPFLAGS = -I$(top_builddir)/$(GNULIB_DIR) -I$(top_srcdir)/$(GNULIB_DIR)\nGNULIB_LIBS = $(GNULIB_DIR)/libgnu.a $(LIBPTHREAD)\n$(GNULIB_LIBS):\n\t$(MAKE) -C $(GNULIB_DIR) all\nSUBDIRS = $(GNULIB_DIR) . man\n\ninclude $(top_srcdir)/source.mak\n\nPACKCC_FILES = misc/packcc/.gitignore   \\\n\t       misc/packcc/README.md    \\\n\t       misc/packcc/LICENSE      \\\n\t       misc/packcc/src/packcc.c \\\n\t       \\\n\t       $(NULL)\n\nVALIDATOR_SH = \\\n\t     misc/validators/g++-common.sh\t\t\t\\\n\t     misc/validators/gfortran-common.sh\t\t\t\\\n\t     misc/validators/tsc-common.sh\t\t\t\\\n\t     misc/validators/validator-c\t\t\t\\\n\t     misc/validators/validator-cxx03\t\t\t\\\n\t     misc/validators/validator-cxx11\t\t\t\\\n\t     misc/validators/validator-cxx17\t\t\t\\\n\t     misc/validators/validator-cxx20+module\t\t\\\n\t     misc/validators/validator-fortran+dollar-ok\t\\\n\t     misc/validators/validator-gnat\t\t\t\\\n\t     misc/validators/validator-jq\t\t\t\\\n\t     misc/validators/validator-KNOWN-INVALIDATION\t\\\n\t     misc/validators/validator-node\t\t\t\\\n\t     misc/validators/validator-NONE\t\t\t\\\n\t     misc/validators/validator-puppet\t\t\t\\\n\t     misc/validators/validator-python\t\t\t\\\n\t     misc/validators/validator-ruby\t\t\t\\\n\t     misc/validators/validator-svlint\t\t\t\\\n\t     misc/validators/validator-swipl\t\t\t\\\n\t     misc/validators/validator-tsc\t\t\t\\\n\t     misc/validators/validator-tsc-es2015\t\t\\\n\t     \\\n\t     $(NULL)\n\nDEBUGGENS = \\\n\t    \\\n\t    misc/debuggen/README misc/debuggen/libdebuggen.sh \\\n\t    \\\n\t    misc/debuggen/rust.sh \\\n\t    misc/debuggen/typescript.sh \\\n\t    \\\n\t    $(NULL)\n\nEXTRA_DIST   = README.md NEWS.rst autogen.sh \\\n\t       misc/optlib2c \\\n\t       misc/enumstr.sh \\\n\t       misc/gencxxtypedumper.sh \\\n\t       $(DEBUGGENS) \\\n\t       .ctags.d/exclusion.ctags .dir-locals.el .editorconfig .gdbinit .gitignore \\\n\t       .indent.pro .uncrustify.cfg \\\n\t       misc/ctags-optlib-mode.el \\\n\t       misc/mk-interactive-request.sh misc/roundtrip misc/tinst \\\n\t       $(PACKCC_FILES) \\\n\t       $(VALIDATOR_SH) \\\n\t       $(WIN32_HEADS) $(WIN32_SRCS) mk_mingw.mak mk_mvc.mak \\\n\t       win32/mkstemp/COPYING.MinGW-w64-runtime.txt \\\n\t       win32/ctags.rc win32/ctags.exe.manifest win32/resource.h \\\n\t       win32/ctags_vs2013.sln \\\n\t       win32/ctags_vs2013.vcxproj win32/ctags_vs2013.vcxproj.filters \\\n\t       win32/ctags_vs2013.vcxproj.in win32/ctags_vs2013.vcxproj.filters.in \\\n\t       win32/GNUmakefile \\\n\t       win32/gen-repoinfo.bat \\\n\t       misc/txt2cstr \\\n\t       $(PEG_INPUT) $(OPTLIB2C_INPUT) $(OPTLIB2C_PCRE2_INPUT) $(TXT2CSTR_INPUT) \\\n\t       misc/universal-ctags.svg \\\n\t       misc/review \\\n\t       docs Tmain Units m4/gnulib-cache.m4\n\nif HAVE_PEGOF\n# Keeping intermediate files for debugging pegof and u-ctags buildsys.\nEXTRA_DIST   += $(PEGO_INTERMEDIATE)\nendif\n\nCLEANFILES =\nMOSTLYCLEANFILES =\nMAINTAINERCLEANFILES = autom4te.cache\n\n# for distcheck\nclean-local:\n\t@if test \"$(top_srcdir)\" != \"$(top_builddir)\"; then \\\n\t\trm -rf $(OPTLIB2C_SRCS) $(OPTLIB2C_PCRE2_SRCS); \\\n\t\trm -rf $(TXT2CSTR_SRCS); \\\n\telse \\\n\t\t$(MAKE) -C docs clean; \\\n\tfi\n\nmaintainer-clean-local:\n\trm -rf .deps misc/packcc/.dirstamp\n\nbin_PROGRAMS = ctags\nnoinst_LIBRARIES =\nnoinst_LIBRARIES += libctags.a\nnoinst_LIBRARIES += libutil.a\n\nnoinst_PROGRAMS = utiltest\n\nAM_LDFLAGS = $(EXTRA_LDFLAGS)\n\n# packcc always uses native compiler even when cross-compiling.\n# packcc cannot use the standard Automake rule.\nPACKCC_CPPFLAGS_FOR_BUILD  = -fsigned-char\nif HAVE_STRNLEN_FOR_BUILD\nPACKCC_CPPFLAGS_FOR_BUILD += -DPCC_USE_SYSTEM_STRNLEN\nendif\n\nPACKCC = $(top_builddir)/packcc$(BUILD_EXEEXT)\nCLEANFILES += $(PACKCC)\n\ncc4b_verbose = $(cc4b_verbose_@AM_V@)\ncc4b_verbose_ = $(cc4b_verbose_@AM_DEFAULT_V@)\ncc4b_verbose_0 = @echo CC4BUILD \"  $@\";\n$(PACKCC): $(srcdir)/$(PACKCC_SRC)\n\t$(cc4b_verbose)$(CC_FOR_BUILD) $(CFLAGS_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(PACKCC_CPPFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) -o $@ $(srcdir)/$(PACKCC_SRC)\n\nif USE_READCMD\nbin_PROGRAMS+= readtags\nreadtags_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/main -I$(srcdir)/libreadtags\nif ENABLE_DEBUGGING\nreadtags_CPPFLAGS+= $(DEBUG_CPPFLAGS)\nendif\nreadtags_CFLAGS = $(EXTRA_CFLAGS) $(WARNING_CFLAGS) $(COVERAGE_CFLAGS)\ndist_readtags_SOURCES = $(READTAGS_SRCS) $(READTAGS_HEADS)\nreadtags_CPPFLAGS += $(GNULIB_CPPFLAGS)\nreadtags_CPPFLAGS += -I$(srcdir)/dsl\nreadtags_CPPFLAGS += -DHAVE_CTAGS_INLINE_H\nreadtags_LDADD  =\nreadtags_LDADD += $(GNULIB_LIBS)\nreadtags_LDADD += libutil.a\ndist_readtags_SOURCES += $(READTAGS_DSL_SRCS) $(READTAGS_DSL_HEADS)\nendif\n\nif HAVE_PCRE2\nPARSER_SRCS += $(PCRE2_SRCS) $(OPTLIB2C_PCRE2_SRCS)\nPARSER_HEADS += $(PCRE2_HEADS)\nendif\n\nif HAVE_LIBXML\nPARSER_SRCS += $(XML_SRCS)\nPARSER_HEADS += $(XML_HEADS)\nendif\n\nif HAVE_JANSSON\nLIB_SRCS += $(JANSSON_SRCS)\nLIB_HEADS += $(JANSSON_HEADS)\nendif\n\nif HAVE_LIBYAML\nPARSER_SRCS += $(YAML_SRCS)\nPARSER_HEADS += $(YAML_HEADS)\nendif\n\nPARSER_HEADS += $(PEG_EXTRA_HEADS)\n\nlibutil_a_CPPFLAGS = -I$(srcdir) -I$(srcdir)/main\nlibutil_a_CFLAGS   =\nlibutil_a_CFLAGS  += $(EXTRA_CFLAGS)\nlibutil_a_CFLAGS  += $(WARNING_CFLAGS)\nlibutil_a_CFLAGS  += $(COVERAGE_CFLAGS)\nif ENABLE_DEBUGGING\nlibutil_a_CPPFLAGS+= $(DEBUG_CPPFLAGS)\nendif\ndist_libutil_a_SOURCES = $(UTIL_HEADS) $(UTIL_SRCS)\n\nutiltest_CPPFLAGS   = -I$(srcdir) -I$(srcdir)/main\nutiltest_CFLAGS     =\nutiltest_CFLAGS    += $(EXTRA_CFLAGS)\nutiltest_CFLAGS    += $(WARNING_CFLAGS)\nutiltest_CFLAGS    += $(COVERAGE_CFLAGS)\nif ENABLE_DEBUGGING\nutiltest_CPPFLAGS  += $(DEBUG_CPPFLAGS)\nendif\nutiltest_LDADD  =\nutiltest_LDADD += libutil.a\ndist_utiltest_SOURCES = $(UTILTEST_HEADS) $(UTILTEST_SRCS)\n\nlibctags_a_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/main -I$(srcdir)/dsl -I$(srcdir)/peg -DHAVE_PACKCC\nif ENABLE_DEBUGGING\nlibctags_a_CPPFLAGS+= $(DEBUG_CPPFLAGS)\nendif\nif HAVE_STRNLEN\nlibctags_a_CPPFLAGS += -DUSE_SYSTEM_STRNLEN\nendif\nif HAVE_PEGOF\nlibctags_a_CPPFLAGS += -DHAVE_PEGOF\nendif\nlibctags_a_CPPFLAGS+= $(GNULIB_CPPFLAGS)\nlibctags_a_CPPFLAGS+= -DHAVE_REPOINFO_H\n\nlibctags_a_CFLAGS   =\nlibctags_a_CFLAGS  += $(EXTRA_CFLAGS)\nlibctags_a_CFLAGS  += $(WARNING_CFLAGS)\nlibctags_a_CFLAGS  += $(COVERAGE_CFLAGS)\nlibctags_a_CFLAGS  += $(CGCC_CFLAGS)\nlibctags_a_CFLAGS  += $(LIBXML_CFLAGS)\nlibctags_a_CFLAGS  += $(JANSSON_CFLAGS)\nlibctags_a_CFLAGS  += $(LIBYAML_CFLAGS)\nlibctags_a_CFLAGS  += $(SECCOMP_CFLAGS)\nlibctags_a_CFLAGS  += $(PCRE2_CFLAGS)\n\nnodist_libctags_a_SOURCES = $(REPOINFO_HEADS) $(PEG_SRCS) $(PEG_HEADS)\nBUILT_SOURCES = $(REPOINFO_HEADS)\nCLEANFILES += $(REPOINFO_HEADS) $(PEG_SRCS) $(PEG_HEADS)\nEXTRA_libctags_a_DEPENDENCIES = $(GNULIB_LIBS)\n$(REPOINFO_SRCS): $(REPOINFO_HEADS)\nrepoinfo_verbose = $(repoinfo_verbose_@AM_V@)\nrepoinfo_verbose_ = $(repoinfo_verbose_@AM_DEFAULT_V@)\nrepoinfo_verbose_0 = @echo REPOINFO \"  $@\";\nif BUILD_IN_GIT_REPO\nGEN_REPOINFO = $(srcdir)/misc/gen-repoinfo\n$(REPOINFO_HEADS): FORCE\n\t$(repoinfo_verbose)$(GEN_REPOINFO) $@\nFORCE:\nelse\n$(REPOINFO_HEADS):\n\t$(repoinfo_verbose)echo > $@\nendif\n\nSUFFIXES=\n\nif RUN_OPTLIB2C\noptlib2c_verbose = $(optlib2c_verbose_@AM_V@)\noptlib2c_verbose_ = $(optlib2c_verbose_@AM_DEFAULT_V@)\noptlib2c_verbose_0 = @echo OPTLIB2C \"  $@\";\nOPTLIB2C = $(srcdir)/misc/optlib2c\nOPTLIB2C_DIR = optlib\nSUFFIXES += .ctags\n.ctags.c:\n\t$(optlib2c_verbose)$(OPTLIB2C) $< > $@\n$(OPTLIB2C_SRCS): $(OPTLIB2C) Makefile\nif HAVE_PCRE2\n$(OPTLIB2C_PCRE2_SRCS): $(OPTLIB2C) Makefile\nendif\nendif\n\nif RUN_TXT2CSTR\ntxt2cstr_verbose = $(txt2cstr_verbose_@AM_V@)\ntxt2cstr_verbose_ = $(txt2cstr_verbose_@AM_DEFAULT_V@)\ntxt2cstr_verbose_0 = @echo TXT2CSTR \"  $@\";\nTXT2CSTR = $(srcdir)/misc/txt2cstr\nTXT2CSTR_DIR = main\nSUFFIXES += .ps\n.ps.c:\n\t$(txt2cstr_verbose)$(TXT2CSTR) $< > $@\n$(TXT2CSTR_SRCS): $(TXT2CSTR) Makefile\nendif\n\npackcc_verbose = $(packcc_verbose_@AM_V@)\npackcc_verbose_ = $(packcc_verbose_@AM_DEFAULT_V@)\npackcc_verbose_0 = @echo PACKCC \"    $@\";\nSUFFIXES += .peg\n\nif HAVE_PEGOF\npegof_verbose = $(pegof_verbose_@AM_V@)\npegof_verbose_ = $(pegof_verbose_@AM_DEFAULT_V@)\npegof_verbose_0 = @echo PEGOF \"    $@\";\nSUFFIXES += .pego\n\nPEGOF_FLAGS = -O all\n.peg.pego:\n\t$(pegof_verbose)$(PEGOF) $(PEGOF_FLAGS) -o $(top_builddir)/peg/$(@F) -i \"$<\"\n.pego.c:\n\t$(packcc_verbose)$(PACKCC) -o $(top_builddir)/peg/$(*F) $(top_builddir)/peg/$(<F)\n.pego.h:\n\t$(packcc_verbose)$(PACKCC) -o $(top_builddir)/peg/$(*F) $(top_builddir)/peg/$(<F)\nelse\n.peg.c:\n\t$(packcc_verbose)$(PACKCC) -o $(top_builddir)/peg/$(*F) \"$<\"\n.peg.h:\n\t$(packcc_verbose)$(PACKCC) -o $(top_builddir)/peg/$(*F) \"$<\"\nendif\n\n# You cannot use $(PACKCC) as a target name here.\n$(PEG_SRCS) $(PEG_HEADS): $(PACKCC) Makefile\ndist_libctags_a_SOURCES = $(ALL_LIB_HEADS) $(ALL_LIB_SRCS)\n\nctags_CPPFLAGS = $(libctags_a_CPPFLAGS)\nctags_CFLAGS = $(libctags_a_CFLAGS)\nctags_LDADD  = libctags.a\nctags_LDADD += $(GNULIB_LIBS)\nctags_LDADD += $(LIBXML_LIBS)\nctags_LDADD += $(JANSSON_LIBS)\nctags_LDADD += $(LIBYAML_LIBS)\nctags_LDADD += $(SECCOMP_LIBS)\nctags_LDADD += $(ICONV_LIBS)\nctags_LDADD += $(PCRE2_LIBS)\ndist_ctags_SOURCES = $(CMDLINE_HEADS) $(CMDLINE_SRCS)\n\nif HOST_MINGW\nRES_OBJ = win32/ctags.res.o\nctags_LDADD += $(RES_OBJ)\nwindres_verbose = $(windres_verbose_@AM_V@)\nwindres_verbose_ = $(windres_verbose_@AM_DEFAULT_V@)\nwindres_verbose_0 = @echo WINDRES \"   $@\";\n$(RES_OBJ): win32/ctags.rc win32/ctags.exe.manifest win32/resource.h\n\t@mkdir -p $(builddir)/win32\n\t$(windres_verbose)$(WINDRES) -o $@ -O coff $<\nMOSTLYCLEANFILES += $(RES_OBJ)\nendif\n\nnoinst_PROGRAMS += mini-geany\nmini_geany_CPPFLAGS = $(libctags_a_CPPFLAGS)\nmini_geany_CFLAGS = $(libctags_a_CFLAGS)\nmini_geany_LDADD  = libctags.a\nmini_geany_LDADD += $(GNULIB_LIBS)\nmini_geany_LDADD += $(LIBXML_LIBS)\nmini_geany_LDADD += $(JANSSON_LIBS)\nmini_geany_LDADD += $(LIBYAML_LIBS)\nmini_geany_LDADD += $(SECCOMP_LIBS)\nmini_geany_LDADD += $(ICONV_LIBS)\nmini_geany_LDADD += $(PCRE2_LIBS)\nmini_geany_SOURCES = $(MINI_GEANY_HEADS) $(MINI_GEANY_SRCS)\n\nbin_PROGRAMS += optscript\noptscript_CPPFLAGS = $(libctags_a_CPPFLAGS)\noptscript_CFLAGS = $(libctags_a_CFLAGS)\noptscript_LDADD  = libctags.a\n# TODO: remove these dependencies from optscript command.\noptscript_LDADD += $(GNULIB_LIBS)\noptscript_LDADD += $(LIBXML_LIBS)\noptscript_LDADD += $(JANSSON_LIBS)\noptscript_LDADD += $(LIBYAML_LIBS)\noptscript_LDADD += $(SECCOMP_LIBS)\noptscript_LDADD += $(ICONV_LIBS)\noptscript_LDADD += $(PCRE2_LIBS)\noptscript_SOURCES = $(OPTSCRIPT_SRCS)\n\nif INSTALL_ETAGS\ninstall-exec-hook:\n\tcd $(DESTDIR)$(bindir) && \\\n\t\t$(LN_S) ctags$(EXEEXT) etags$(EXEEXT)\n\nuninstall-hook:\n\trm $(DESTDIR)$(bindir)/etags$(EXEEXT)\nendif\n\ndist-hook:\n\trm -rf $(distdir)/docs/_build\n\tfind $(distdir)/Tmain $(distdir)/Units \\( \\\n\t\t-name '*-actual.txt' -o -name '*-diff.txt' -o \\\n\t\t-name '*.TMP' -o -name '*.tmp' -o -name '*~' -o \\\n\t\t-name 'dist.m4' -o -name 'Makefile.am' -o \\\n\t\t-name 'Makefile.in' -o -name 'Makefile' -o \\\n\t\t-name 'BUNDLES' \\) -exec rm -f {} +\n\ninclude $(top_srcdir)/makefiles/testing.mak\n\ninclude $(top_srcdir)/makefiles/help.mak\n"
  },
  {
    "path": "README.md",
    "content": "# Universal Ctags\n\n[![Coverity Scan Build Status](https://scan.coverity.com/projects/4355/badge.svg)](https://scan.coverity.com/projects/4355)\n[![Coverage Status](https://coveralls.io/repos/universal-ctags/ctags/badge.svg?branch=master&service=github)](https://coveralls.io/github/universal-ctags/ctags?branch=master)\n[![Build status](https://ci.appveyor.com/api/projects/status/6hk2p5lv6jsrd9o7/branch/master?svg=true)](https://ci.appveyor.com/project/universalctags/ctags/branch/master)\n[![RTD build status](https://readthedocs.org/projects/ctags/badge)](https://docs.ctags.io)\n[![CircleCI Build Status](https://dl.circleci.com/status-badge/img/gh/universal-ctags/ctags/tree/master.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/universal-ctags/ctags/tree/master)\n![GitHub Actions/VALGRIND](https://github.com/universal-ctags/ctags/workflows/run%20units%20target%20under%20VALGRIND/badge.svg)\n[![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20Universal%20Ctags%20Guru-006BFF)](https://gurubase.io/g/universal-ctags)\n\n[Universal Ctags](https://ctags.io/) (abbreviated as u-ctags) is a *maintained*\nimplementation of `ctags`.\n`ctags` generates an index (or tag) file of language objects found in source\nfiles for programming languages.\nThis index makes it easy for text editors and other tools to locate the indexed\nitems.\n\n[Exuberant Ctags](http://ctags.sourceforge.net/) (e-ctags) maintained by Darren\nHiebert, the ancestor of Universal Ctags, improved traditional `ctags` with\nmulti-language support, the ability for the user to define new languages\nsearched by regular expressions (called optlib in Universal Ctags), and the\nability to generate emacs-style TAGS files.\nBut the activity of the project unfortunately stalled.\n\nUniversal Ctags has the objective of continuing the development of Exuberant\nCtags.\nReza Jelveh <reza.jelveh@gmail.com> initially created a personal fork of\nExuberant Ctags on GitHub.\nAs interest and participation grew, it was decided to move development to a\ndedicated project as Universal Ctags.\nThe goal of this project is to maintain a common/unified working space where\npeople interested in making ctags better can work together.\n\nSome of the major features of Universal Ctags are:\n\n* more numbers of improved language support\n    * new extended C/C++ language parser, etc.\n* fully extended optlib (a feature to define a new language parser from a\n  command line)\n* interactive mode (experimental)\n\n## The latest build and package ##\n\nIf you want to try the latest Universal Ctags without building it yourself...\n\n### Windows\nDaily builds are available at the [ctags-win32](https://github.com/universal-ctags/ctags-win32) project.\nGo to the [releases](https://github.com/universal-ctags/ctags-win32/releases) page to download zip packages.\n\n### Unix-like\nNightly builds are available at the [ctags-nightly-build](https://github.com/universal-ctags/ctags-nightly-build) project.\nGo to the [releases](https://github.com/universal-ctags/ctags-nightly-build/releases) page to download tarball archives.\n\n### Mac\nRecent builds are available via the [`universal-ctags` Homebrew formula](https://formulae.brew.sh/formula/universal-ctags).\n\n### Snap\nGo to [ctags-snap](https://github.com/universal-ctags/ctags-snap) and\nclone the `ctags-snap` repo. Then, follow instructions to build the\nsnap package of Universal Ctags. Snapcraft will automatically fetch the source\ncode from GitHub.\n\n## How to build and install ##\n\nTo build with Autotools (Autoconf and Automake) on GNU/Linux, OSX, or Windows 10 WSL,\n```\n    $ git clone https://github.com/universal-ctags/ctags.git\n    $ cd ctags\n    $ ./autogen.sh\n    $ ./configure  # use --prefix=/where/you/want to override installation directory, defaults to /usr/local\n    $ make\n    $ make install # may require extra privileges depending on where to install\n```\n\nGNU make is assumed as the `make` command.\n\nSee\n[`docs/autotools.rst`](https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst)\nfor more information.\n\nTo build on Windows, see\n[`docs/windows.rst`](https://github.com/universal-ctags/ctags/blob/master/docs/windows.rst)\nfor more information.\n\nTo build on OSX, see\n[`docs/osx.rst`](https://github.com/universal-ctags/ctags/blob/master/docs/osx.rst)\nfor more information.\n\n## Manual ##\nThe primary documents of Universal Ctags are man pages.\nUsers should first consult the\n[ctags(1)](https://docs.ctags.io/en/latest/man/ctags.1.html), and [other man\npages](https://docs.ctags.io/en/latest/man-pages.html) if necessary.\n\n[Universal Ctags Hacking Guide](https://docs.ctags.io), which also includes the\nman pages, is primarily for developers and provides additional information to\nthe man pages, including experimental features.\n\nSee also `*/README.md` on this repository.\n\n## Differences from exuberant-ctags ##\n\nYou may be interested in how Universal Ctags is different from Exuberant Ctags.\nSee\n[ctags-incompatibilities(7)](https://docs.ctags.io/en/latest/man/ctags-incompatibilities.7.html)\nand [Introduced changes](https://docs.ctags.io/en/latest/news.html) for details.\n\nThe most significant incompatible changes:\n\n* Universal Ctags doesn't load `~/.ctags` and `./.ctags` at starting up time.\n  Instead, it loads `~/.ctags.d/*.ctags` and `./.ctags.d/*.ctags`.\n\n* Universal Ctags is more strict about characters that can be\n  used in kind letters and kind names than Exuberant-ctags.\n\n  - The letter must be an alphabetical character (`[a-zA-EG-Z]`).\n    `F` is reserved for `file` kind.\n\n  - The first character of the name must be alphabetic, and\n    the rest characters must be alphanumeric (`[a-zA-Z][a-zA-Z0-9]*`).\n\n  The detailed background is explained in\n  [#1737](https://github.com/universal-ctags/ctags/pull/1737).\n\n  If you want to reuse your `.ctags` written for Exuberant-ctags,\n  you must review kind letters and names defined with `--regex-<LANG>=...`\n  options. When updating the definitions, using `--kinddef-<LANG>=...` option\n  is appreciated.\n\n## [CVE-2022-4515](https://access.redhat.com/security/cve/CVE-2022-4515) ##\nIt is not affected to Universal Ctags.\nIt was fixed in [e00c55d7a0204dc1d0ae316141323959e1e16162](https://github.com/universal-ctags/ctags/commit/e00c55d7a0204dc1d0ae316141323959e1e16162) in 2016. Thanks to the reporter.\n\nPull-requests are welcome!\n"
  },
  {
    "path": "Tmain/abnormal-output-file-names.d/input.c",
    "content": "int x;\n"
  },
  {
    "path": "Tmain/abnormal-output-file-names.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\n\n. ../utils.sh\n\nexit_if_win32 \"$CTAGS\"\n\nrm -f $BUILDDIR/\"'\"\nrm -f $BUILDDIR/'\"'\nrm -f $BUILDDIR/'$(ls)'\nrm -f $BUILDDIR/'a b'\n\n${CTAGS} --quiet --options=NONE -o $BUILDDIR/\"'\" --extras=-pF input.c\n${CTAGS} --quiet --options=NONE -o $BUILDDIR/'\"' --extras=-pF input.c\n${CTAGS} --quiet --options=NONE -o $BUILDDIR/'$(ls)' --extras=-pF input.c\n${CTAGS} --quiet --options=NONE -o $BUILDDIR/'a b' --extras=-pF input.c\n\necho '#' SINGLE QUOTE\nif [ -e $BUILDDIR/\"'\" ]; then\n\tcat $BUILDDIR/\"'\"\nfi\n\necho '#' DOUBLE QUOTES\nif [ -e $BUILDDIR/'\"' ]; then\n\tcat $BUILDDIR/'\"'\nfi\n\necho '#' PROCESS SUBSTITUTION\nif [ -e $BUILDDIR/'$(ls)' ]; then\n\tcat $BUILDDIR/'$(ls)'\nfi\n\necho '#' SPACE\nif [ -e $BUILDDIR/'a b' ]; then\n\tcat $BUILDDIR/'a b'\nfi\n\nrm -f $BUILDDIR/\"'\"\nrm -f $BUILDDIR/'\"'\nrm -f $BUILDDIR/'$(ls)'\nrm -f $BUILDDIR/'a b'\n"
  },
  {
    "path": "Tmain/abnormal-output-file-names.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/abnormal-output-file-names.d/stdout-expected.txt",
    "content": "# SINGLE QUOTE\nx\tinput.c\t/^int x;$/;\"\tv\ttyperef:typename:int\n# DOUBLE QUOTES\nx\tinput.c\t/^int x;$/;\"\tv\ttyperef:typename:int\n# PROCESS SUBSTITUTION\nx\tinput.c\t/^int x;$/;\"\tv\ttyperef:typename:int\n# SPACE\nx\tinput.c\t/^int x;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/alias-for-unknown-language.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/alias-for-unknown-language.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --alias-nosuchlang=Z\nexit $?\n"
  },
  {
    "path": "Tmain/alias-for-unknown-language.d/stderr-expected.txt",
    "content": "ctags: Unknown language \"nosuchlang\" in \"alias-nosuchlang\" option\n"
  },
  {
    "path": "Tmain/alias-for-unknown-language.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/allow-null-tag.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/allow-null-tag.d/input.json",
    "content": "[{\"\":1}]\n"
  },
  {
    "path": "Tmain/allow-null-tag.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --_fatal-warnings -o - input.json\nexit $?\n"
  },
  {
    "path": "Tmain/allow-null-tag.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/allow-null-tag.d/stdout-expected.txt",
    "content": "0\tinput.json\t/^[{\"\":1}]$/;\"\to\n"
  },
  {
    "path": "Tmain/avoid-null-tag-warning.d/input-0.sql",
    "content": "ALTER DATABASE :\"datname\" REFRESH COLLATION VERSION;\n"
  },
  {
    "path": "Tmain/avoid-null-tag-warning.d/input.asm",
    "content": "\t.proc\n"
  },
  {
    "path": "Tmain/avoid-null-tag-warning.d/input.sql",
    "content": "-- Taken from #2504 opened by @koenmeersman\nselect substr(sess_evnt.event, 1, 18) event\nfrom  v$session_event sess_evnt;\n"
  },
  {
    "path": "Tmain/avoid-null-tag-warning.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=$1\n\nV=\n# V=valgrind\n\necho '# no warning should be printed' 1>&2\n$CTAGS --quiet --options=NONE -o - input.sql\n$CTAGS --quiet --options=NONE -o - input-0.sql\n$CTAGS --quiet --options=NONE -o - input.asm\n"
  },
  {
    "path": "Tmain/avoid-null-tag-warning.d/stderr-expected.txt",
    "content": "# no warning should be printed\n"
  },
  {
    "path": "Tmain/avoid-null-tag-warning.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/broken-extradef.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE\"\n\ntitle()\n{\n\techo\n\techo \"$@\"\n\n\t{\n\t\techo\n\t\techo \"$@\"\n\t} 1>&2\n}\n\n{\ntitle '# echo unknown lang'\n${CTAGS} --_extradef-NOSUCHLANG\n${CTAGS} --_extradef-NOSUCHLANG=extra,desc\n\ntitle '# no option value'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=\n\ntitle '# wrong char in a field name'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=:\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=:abc\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=:abc,\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=:abc,description\n\ntitle '# empty extra name'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=,\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=,abc\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=,abc,\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=,abc,description\n\ntitle '# empty description'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=abc\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=abc,\n\ntitle '# no input file'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY=abc,desc\n\ntitle '# inject a flag separator'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY='extra,desc{foo}' --list-extras=IMAGINARY\n\ntitle '# inject a broken flag separator(1)'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY='extra,desc{foo' --list-extras=IMAGINARY\n\ntitle '# inject a broken flag separator(2)'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY='extra,desc{' --list-extras=IMAGINARY\n\ntitle '# use a { in description (1)'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY='extra,desc\\{' --list-extras=IMAGINARY\n\ntitle '# use a { in description (2)'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY='extra,desc\\{}' --list-extras=IMAGINARY\n\ntitle '# use a \\ in description'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY='extra,desc\\\\backslash' --list-extras=IMAGINARY\n\ntitle '# description started from {'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY='extra,{' --list-extras=IMAGINARY\n\ntitle '# description started from \\{'\n${CTAGS} --langdef=IMAGINARY --_extradef-IMAGINARY='extra,\\{' --list-extras=IMAGINARY\n\n} > /tmp/ctags-tmain-$$.stdout 2>/tmp/ctags-tmain-$$.stderr\n\nsed -e 's/\\.exe//g' < /tmp/ctags-tmain-$$.stdout\nrm /tmp/ctags-tmain-$$.stdout\n\nsed -e 's/\\.exe//g' < /tmp/ctags-tmain-$$.stderr 1>&2\nrm /tmp/ctags-tmain-$$.stderr\n"
  },
  {
    "path": "Tmain/broken-extradef.d/stderr-expected.txt",
    "content": "\n# echo unknown lang\nctags: Unknown language \"NOSUCHLANG\" in \"_extradef-NOSUCHLANG\" option\nctags: Unknown language \"NOSUCHLANG\" in \"_extradef-NOSUCHLANG\" option\n\n# no option value\nctags: no extra definition specified in \"--_extradef-IMAGINARY\" option\nctags: no extra definition specified in \"--_extradef-IMAGINARY\" option\n\n# wrong char in a field name\nctags: no extra description specified in \"--_extradef-IMAGINARY\" option\nctags: no extra description specified in \"--_extradef-IMAGINARY\" option\nctags: unacceptable char as part of extra name in \"--_extradef-IMAGINARY\" option: ':'\nctags: unacceptable char as part of extra name in \"--_extradef-IMAGINARY\" option: ':'\n\n# empty extra name\nctags: the extra name in \"--_extradef-IMAGINARY\" option is empty\nctags: the extra name in \"--_extradef-IMAGINARY\" option is empty\nctags: the extra name in \"--_extradef-IMAGINARY\" option is empty\nctags: the extra name in \"--_extradef-IMAGINARY\" option is empty\n\n# empty description\nctags: no extra description specified in \"--_extradef-IMAGINARY\" option\nctags: extra description in \"--_extradef-IMAGINARY\" option is empty\n\n# no input file\nctags: No files specified. Try \"ctags --help\".\n\n# inject a flag separator\n\n# inject a broken flag separator(1)\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{foo\"\n\n# inject a broken flag separator(2)\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{\"\n\n# use a { in description (1)\n\n# use a { in description (2)\n\n# use a \\ in description\n\n# description started from {\nctags: extra description in \"--_extradef-IMAGINARY\" option is empty\n\n# description started from \\{\n"
  },
  {
    "path": "Tmain/broken-extradef.d/stdout-expected.txt",
    "content": "\n# echo unknown lang\n\n# no option value\n\n# wrong char in a field name\n\n# empty extra name\n\n# empty description\n\n# no input file\n\n# inject a flag separator\n#LETTER NAME  ENABLED LANGUAGE  FIXED VER DESCRIPTION\n-       extra no      IMAGINARY no      0 desc\n\n# inject a broken flag separator(1)\n#LETTER NAME  ENABLED LANGUAGE  FIXED VER DESCRIPTION\n-       extra no      IMAGINARY no      0 desc\n\n# inject a broken flag separator(2)\n#LETTER NAME  ENABLED LANGUAGE  FIXED VER DESCRIPTION\n-       extra no      IMAGINARY no      0 desc\n\n# use a { in description (1)\n#LETTER NAME  ENABLED LANGUAGE  FIXED VER DESCRIPTION\n-       extra no      IMAGINARY no      0 desc{\n\n# use a { in description (2)\n#LETTER NAME  ENABLED LANGUAGE  FIXED VER DESCRIPTION\n-       extra no      IMAGINARY no      0 desc{}\n\n# use a \\ in description\n#LETTER NAME  ENABLED LANGUAGE  FIXED VER DESCRIPTION\n-       extra no      IMAGINARY no      0 desc\\backslash\n\n# description started from {\n\n# description started from \\{\n#LETTER NAME  ENABLED LANGUAGE  FIXED VER DESCRIPTION\n-       extra no      IMAGINARY no      0 {\n"
  },
  {
    "path": "Tmain/broken-fielddef.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE\"\n\ntitle()\n{\n\techo\n\techo \"$@\"\n\n\t{\n\t\techo\n\t\techo \"$@\"\n\t} 1>&2\n}\n\n{\ntitle '# echo unknown lang'\n${CTAGS} --_fielddef-NOSUCHLANG\n${CTAGS} --_fielddef-NOSUCHLANG=field,desc\n\ntitle '# no option value'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=\n\ntitle '# wrong char in a field name'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=:\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=:abc\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=:abc,\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=:abc,description\n\ntitle '# empty field name'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=,\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=,abc\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=,abc,\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=,abc,description\n\ntitle '# empty description'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=abc\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=abc,\n\ntitle '# no input file'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY=abc,desc\n\ntitle '# inject a flag separator'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY='field,desc{foo}' --list-fields=IMAGINARY\n\ntitle '# inject a broken flag separator(1)'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY='field,desc{foo' --list-fields=IMAGINARY\n\ntitle '# inject a broken flag separator(2)'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY='field,desc{' --list-fields=IMAGINARY\n\ntitle '# use a { in description (1)'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY='field,desc\\{' --list-fields=IMAGINARY\n\ntitle '# use a { in description (2)'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY='field,desc\\{}' --list-fields=IMAGINARY\n\ntitle '# use a \\ in description'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY='field,desc\\\\backslash' --list-fields=IMAGINARY\n\ntitle '# description started from {'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY='field,{' --list-fields=IMAGINARY\n\ntitle '# description started from \\{'\n${CTAGS} --langdef=IMAGINARY --_fielddef-IMAGINARY='field,\\{' --list-fields=IMAGINARY\n}  > /tmp/ctags-tmain-$$.stdout 2>/tmp/ctags-tmain-$$.stderr\n\nsed -e 's/\\.exe//g' < /tmp/ctags-tmain-$$.stdout\nrm /tmp/ctags-tmain-$$.stdout\n\nsed -e 's/\\.exe//g' < /tmp/ctags-tmain-$$.stderr 1>&2\nrm /tmp/ctags-tmain-$$.stderr\n"
  },
  {
    "path": "Tmain/broken-fielddef.d/stderr-expected.txt",
    "content": "\n# echo unknown lang\nctags: Unknown language \"NOSUCHLANG\" in \"_fielddef-NOSUCHLANG\" option\nctags: Unknown language \"NOSUCHLANG\" in \"_fielddef-NOSUCHLANG\" option\n\n# no option value\nctags: no field definition specified in \"--_fielddef-IMAGINARY\" option\nctags: no field definition specified in \"--_fielddef-IMAGINARY\" option\n\n# wrong char in a field name\nctags: no field description specified in \"--_fielddef-IMAGINARY\" option\nctags: no field description specified in \"--_fielddef-IMAGINARY\" option\nctags: unacceptable char as part of field name in \"--_fielddef-IMAGINARY\" option: ':'\nctags: unacceptable char as part of field name in \"--_fielddef-IMAGINARY\" option: ':'\n\n# empty field name\nctags: the field name in \"--_fielddef-IMAGINARY\" option is empty\nctags: the field name in \"--_fielddef-IMAGINARY\" option is empty\nctags: the field name in \"--_fielddef-IMAGINARY\" option is empty\nctags: the field name in \"--_fielddef-IMAGINARY\" option is empty\n\n# empty description\nctags: no field description specified in \"--_fielddef-IMAGINARY\" option\nctags: field description in \"--_fielddef-IMAGINARY\" option is empty\n\n# no input file\nctags: No files specified. Try \"ctags --help\".\n\n# inject a flag separator\n\n# inject a broken flag separator(1)\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{foo\"\n\n# inject a broken flag separator(2)\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{\"\n\n# use a { in description (1)\n\n# use a { in description (2)\n\n# use a \\ in description\n\n# description started from {\nctags: field description in \"--_fielddef-IMAGINARY\" option is empty\n\n# description started from \\{\n"
  },
  {
    "path": "Tmain/broken-fielddef.d/stdout-expected.txt",
    "content": "\n# echo unknown lang\n\n# no option value\n\n# wrong char in a field name\n\n# empty field name\n\n# empty description\n\n# no input file\n\n# inject a flag separator\n#LETTER NAME  ENABLED LANGUAGE  JSTYPE FIXED OP VER DESCRIPTION\n-       field no      IMAGINARY s--    no    --   0 desc\n\n# inject a broken flag separator(1)\n#LETTER NAME  ENABLED LANGUAGE  JSTYPE FIXED OP VER DESCRIPTION\n-       field no      IMAGINARY s--    no    --   0 desc\n\n# inject a broken flag separator(2)\n#LETTER NAME  ENABLED LANGUAGE  JSTYPE FIXED OP VER DESCRIPTION\n-       field no      IMAGINARY s--    no    --   0 desc\n\n# use a { in description (1)\n#LETTER NAME  ENABLED LANGUAGE  JSTYPE FIXED OP VER DESCRIPTION\n-       field no      IMAGINARY s--    no    --   0 desc{\n\n# use a { in description (2)\n#LETTER NAME  ENABLED LANGUAGE  JSTYPE FIXED OP VER DESCRIPTION\n-       field no      IMAGINARY s--    no    --   0 desc{}\n\n# use a \\ in description\n#LETTER NAME  ENABLED LANGUAGE  JSTYPE FIXED OP VER DESCRIPTION\n-       field no      IMAGINARY s--    no    --   0 desc\\backslash\n\n# description started from {\n\n# description started from \\{\n#LETTER NAME  ENABLED LANGUAGE  JSTYPE FIXED OP VER DESCRIPTION\n-       field no      IMAGINARY s--    no    --   0 {\n"
  },
  {
    "path": "Tmain/broken-json-output.d/exit-expected.tx",
    "content": "0\n"
  },
  {
    "path": "Tmain/broken-json-output.d/input.f",
    "content": "* \n      integer function F(x)\n      end function F\n      program main\n)\n"
  },
  {
    "path": "Tmain/broken-json-output.d/run.sh",
    "content": "# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=$1\n\nis_feature_available ${CTAGS} json\n\n${CTAGS} --quiet --options=NONE --sort=no --output-format=json input.f\n"
  },
  {
    "path": "Tmain/broken-json-output.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/broken-json-output.d/stdout-expected.txt",
    "content": "{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.f\", \"pattern\": \"/^      program main$/\", \"kind\": \"program\"}\n"
  },
  {
    "path": "Tmain/broken-langdef.d/input.c",
    "content": "int f(void) { return 0; }\n"
  },
  {
    "path": "Tmain/broken-langdef.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nrun_ctags()\n{\n\techo '#' \"$1\" 1>&2\n\t${CTAGS} --quiet --options=NONE --langdef=\"$1\" --kinddef-\"$1\"=f,func,functions --_force-quit=0 -o - input.c\n}\n\nrun_ctags \"\"\nrun_ctags all\nrun_ctags NONE\nfor c in '!' '\"' '$' '%' '&' \"'\" '(' ')' '*' ',' '-' '.' '/' ':' ';' '<' '=' '>' '?' '@' '[' '\\' ']' '^' '`' '|' '~'; do\n\trun_ctags \"C$c\"\ndone\n"
  },
  {
    "path": "Tmain/broken-langdef.d/stderr-expected.txt",
    "content": "# \nctags: No language specified for \"langdef\" option\n# all\nctags: \"all\" is reserved; don't use it as the name for defining a new language\n# NONE\nctags: \"NONE\" is reserved; don't use it as the name for defining a new language\n# C!\nctags: don't use `!' in a language name (C!)\n# C\"\nctags: don't use `\"' in a language name (C\")\n# C$\nctags: don't use `$' in a language name (C$)\n# C%\nctags: don't use `%' in a language name (C%)\n# C&\nctags: don't use `&' in a language name (C&)\n# C'\nctags: don't use \"'\" in a language name (C')\n# C(\nctags: don't use `(' in a language name (C()\n# C)\nctags: don't use `)' in a language name (C))\n# C*\nctags: don't use `*' in a language name (C*)\n# C,\nctags: don't use `,' in a language name (C,)\n# C-\nctags: don't use `-' in a language name (C-)\n# C.\nctags: don't use `.' in a language name (C.)\n# C/\nctags: don't use `/' in a language name (C/)\n# C:\nctags: don't use `:' in a language name (C:)\n# C;\nctags: don't use `;' in a language name (C;)\n# C<\nctags: don't use `<' in a language name (C<)\n# C=\nctags: don't use `=' in a language name (C=)\n# C>\nctags: don't use `>' in a language name (C>)\n# C?\nctags: don't use `?' in a language name (C?)\n# C@\nctags: don't use `@' in a language name (C@)\n# C[\nctags: don't use `[' in a language name (C[)\n# C\\\nctags: don't use `\\' in a language name (C\\)\n# C]\nctags: don't use `]' in a language name (C])\n# C^\nctags: don't use `^' in a language name (C^)\n# C`\nctags: don't use \"`\" in a language name (C`)\n# C|\nctags: don't use `|' in a language name (C|)\n# C~\nctags: don't use `~' in a language name (C~)\n"
  },
  {
    "path": "Tmain/broken-langdef.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/broken-paramdef.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE\"\n\ntitle()\n{\n\techo\n\techo \"$@\"\n\n\t{\n\t\techo\n\t\techo \"$@\"\n\t} 1>&2\n}\n\n{\ntitle '# echo unknown lang'\n${CTAGS} --_paramdef-NOSUCHLANG\n${CTAGS} --_paramdef-NOSUCHLANG=param,desc\n\ntitle '# no option value'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=\n\ntitle '# wrong char in a field name'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=:\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=:abc\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=:abc,\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=:abc,description\n\ntitle '# empty parameter name'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=,\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=,abc\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=,abc,\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=,abc,description\n\ntitle '# empty description'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=abc\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=abc,\n\ntitle '# no input file'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY=abc,desc\n\ntitle '# inject a flag separator'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY='param,desc{foo}' --list-params=IMAGINARY\n\ntitle '# inject a broken flag separator(1)'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY='param,desc{foo' --list-params=IMAGINARY\n\ntitle '# inject a broken flag separator(2)'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY='param,desc{' --list-params=IMAGINARY\n\ntitle '# use a { in description (1)'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY='param,desc\\{' --list-params=IMAGINARY\n\ntitle '# use a { in description (2)'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY='param,desc\\{}' --list-params=IMAGINARY\n\ntitle '# use a \\ in description'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY='param,desc\\\\backslash' --list-params=IMAGINARY\n\ntitle '# description started from {'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY='param,{' --list-params=IMAGINARY\n\ntitle '# description started from \\{'\n${CTAGS} --langdef=IMAGINARY --_paramdef-IMAGINARY='param,\\{' --list-params=IMAGINARY\n\n} > /tmp/ctags-tmain-$$.stdout 2>/tmp/ctags-tmain-$$.stderr\n\nsed -e 's/\\.exe//g' < /tmp/ctags-tmain-$$.stdout\nrm /tmp/ctags-tmain-$$.stdout\n\nsed -e 's/\\.exe//g' < /tmp/ctags-tmain-$$.stderr 1>&2\nrm /tmp/ctags-tmain-$$.stderr\n"
  },
  {
    "path": "Tmain/broken-paramdef.d/stderr-expected.txt",
    "content": "\n# echo unknown lang\nctags: Unknown language \"NOSUCHLANG\" in \"_paramdef-NOSUCHLANG\" option\nctags: Unknown language \"NOSUCHLANG\" in \"_paramdef-NOSUCHLANG\" option\n\n# no option value\nctags: no parameter definition specified in \"--_paramdef-IMAGINARY\" option\nctags: no parameter definition specified in \"--_paramdef-IMAGINARY\" option\n\n# wrong char in a field name\nctags: no parameter description specified in \"--_paramdef-IMAGINARY\" option\nctags: no parameter description specified in \"--_paramdef-IMAGINARY\" option\nctags: unacceptable char as part of parameter name in \"--_paramdef-IMAGINARY\" option: ':'\nctags: unacceptable char as part of parameter name in \"--_paramdef-IMAGINARY\" option: ':'\n\n# empty parameter name\nctags: the parameter name in \"--_paramdef-IMAGINARY\" option is empty\nctags: the parameter name in \"--_paramdef-IMAGINARY\" option is empty\nctags: the parameter name in \"--_paramdef-IMAGINARY\" option is empty\nctags: the parameter name in \"--_paramdef-IMAGINARY\" option is empty\n\n# empty description\nctags: no parameter description specified in \"--_paramdef-IMAGINARY\" option\nctags: parameter description in \"--_paramdef-IMAGINARY\" option is empty\n\n# no input file\nctags: No files specified. Try \"ctags --help\".\n\n# inject a flag separator\n\n# inject a broken flag separator(1)\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{foo\"\n\n# inject a broken flag separator(2)\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{\"\n\n# use a { in description (1)\n\n# use a { in description (2)\n\n# use a \\ in description\n\n# description started from {\nctags: parameter description in \"--_paramdef-IMAGINARY\" option is empty\n\n# description started from \\{\n"
  },
  {
    "path": "Tmain/broken-paramdef.d/stdout-expected.txt",
    "content": "\n# echo unknown lang\n\n# no option value\n\n# wrong char in a field name\n\n# empty parameter name\n\n# empty description\n\n# no input file\n\n# inject a flag separator\n#NAME  DESCRIPTION\nparam  desc\n\n# inject a broken flag separator(1)\n#NAME  DESCRIPTION\nparam  desc\n\n# inject a broken flag separator(2)\n#NAME  DESCRIPTION\nparam  desc\n\n# use a { in description (1)\n#NAME  DESCRIPTION\nparam  desc{\n\n# use a { in description (2)\n#NAME  DESCRIPTION\nparam  desc{}\n\n# use a \\ in description\n#NAME  DESCRIPTION\nparam  desc\\backslash\n\n# description started from {\n\n# description started from \\{\n#NAME  DESCRIPTION\nparam  {\n"
  },
  {
    "path": "Tmain/broken-regex-pattern.d/broken-pattern.ctags",
    "content": "# Though this pattern uses pcre2 extension, {pcre2} flag is not given.\n# This caused a crash.\n--mline-regex-Python=/[\\n]if\\s+__name__\\s*==\\s*(\"__main__\"|'__main__')\\s*:(?:\\s*#[^\\n]*)?\\n//f/{mgroup=1}{_anonymous=main}\n"
  },
  {
    "path": "Tmain/broken-regex-pattern.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/broken-regex-pattern.d/input.py",
    "content": "if import pydoc\nif __name__ == \"__main__\":\n    pydoc.cli()\n"
  },
  {
    "path": "Tmain/broken-regex-pattern.d/run.sh",
    "content": "# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE\"\n\n$CTAGS --options=./broken-pattern.ctags -o - input.py > /dev/null\n"
  },
  {
    "path": "Tmain/broken-regex-pattern.d/stderr-expected.txt",
    "content": "ctags: Warning: regcomp: Invalid preceding regular expression\nctags: Warning: pattern: [\n]if\\s+__name__\\s*==\\s*(\"__main__\"|'__main__')\\s*:(?:\\s*#[^\n]*)?\n\nctags: Warning: language: Python[0]\nctags: Warning: Failed in compiling the regex pattern with \"default\" regex engine\n"
  },
  {
    "path": "Tmain/broken-tagname-in-ectags-format.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/broken-tagname-in-ectags-format.d/input.cst",
    "content": "b\n\n"
  },
  {
    "path": "Tmain/broken-tagname-in-ectags-format.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILD_SUBDIR=$2\nstderr_tmp=${BUILD_SUBDIR}/stderr-actual.txt.tmp\n\n${CTAGS} --options=NONE -o - --language-force=CTagsSelfTest --verbose --output-format=e-ctags input.cst \\\n\t 2> ${stderr_tmp}\n\n# externalSortTags invokes sort command, and it is logged to stderr.\n# Delete the line for the comparison.\nsed -e '/^system (\"sort -u\")$/d' < ${stderr_tmp} 1>&2\nrm ${stderr_tmp}\n\nexit $?\n"
  },
  {
    "path": "Tmain/broken-tagname-in-ectags-format.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\n  Option: --output-format=e-ctags\nReading command line arguments\nCTagsSelfTest requires a memory stream for input\nOPENING input.cst as CTagsSelfTest language file [new,required]\nInitialize parser: CTagsSelfTest\n"
  },
  {
    "path": "Tmain/broken-tagname-in-ectags-format.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/broken-tagname-quiet.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/broken-tagname-quiet.d/input.cst",
    "content": "b\n"
  },
  {
    "path": "Tmain/broken-tagname-quiet.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE -o - --language-force=CTagsSelfTest input.cst\n\nexit $?\n"
  },
  {
    "path": "Tmain/broken-tagname-quiet.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/broken-tagname-quiet.d/stdout-expected.txt",
    "content": "newline-in-scope\tinput.cst\t/^b$/;\"\tb\tbroken tag:parent\\nscope\none\\nof\\rbroken\\tname\tinput.cst\t/^b$/;\"\tb\tbroken tag:\\\\Broken\\tContext\nonly\\nnewline\tinput.cst\t/^b$/;\"\tb\nonly\\ttab\tinput.cst\t/^b$/;\"\tb\ntab-in-scope\tinput.cst\t/^b$/;\"\tb\tbroken tag:parent\\tscope\n"
  },
  {
    "path": "Tmain/broken-tagname.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/broken-tagname.d/input.cst",
    "content": "b\n\n"
  },
  {
    "path": "Tmain/broken-tagname.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILD_SUBDIR=$2\nstderr_tmp=${BUILD_SUBDIR}/stderr-actual.txt.tmp\n\n${CTAGS} --options=NONE -o - --language-force=CTagsSelfTest --verbose input.cst \\\n\t 2> ${stderr_tmp}\n\n# externalSortTags invokes sort command, and it is logged to stderr.\n# Delete the line for the comparison.\nsed -e '/^system (\"sort -u\")$/d' < ${stderr_tmp} 1>&2\nrm ${stderr_tmp}\n\nexit $?\n"
  },
  {
    "path": "Tmain/broken-tagname.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nReading command line arguments\nCTagsSelfTest requires a memory stream for input\nOPENING input.cst as CTagsSelfTest language file [new,required]\nInitialize parser: CTagsSelfTest\nUnexpected character 0x0a included in a tagEntryInfo: one\nof\rbroken\tname\nFile: input.cst, Line: 1, Lang: CTagsSelfTest, Kind: b\nEscape the character\nUnexpected character 0x09 included in a tagEntryInfo: \\Broken\tContext\nFile: input.cst, Line: 1, Lang: CTagsSelfTest, Kind: b\nEscape the character\nUnexpected character 0x0a included in a tagEntryInfo: only\nnewline\nFile: input.cst, Line: 1, Lang: CTagsSelfTest, Kind: b\nEscape the character\nUnexpected character 0x09 included in a tagEntryInfo: only\ttab\nFile: input.cst, Line: 1, Lang: CTagsSelfTest, Kind: b\nEscape the character\nUnexpected character 0x0a included in a tagEntryInfo: parent\nscope\nFile: input.cst, Line: 1, Lang: CTagsSelfTest, Kind: b\nEscape the character\nUnexpected character 0x09 included in a tagEntryInfo: parent\tscope\nFile: input.cst, Line: 1, Lang: CTagsSelfTest, Kind: b\nEscape the character\nsorting tag file\n"
  },
  {
    "path": "Tmain/broken-tagname.d/stdout-expected.txt",
    "content": "newline-in-scope\tinput.cst\t/^b$/;\"\tb\tbroken tag:parent\\nscope\none\\nof\\rbroken\\tname\tinput.cst\t/^b$/;\"\tb\tbroken tag:\\\\Broken\\tContext\nonly\\nnewline\tinput.cst\t/^b$/;\"\tb\nonly\\ttab\tinput.cst\t/^b$/;\"\tb\ntab-in-scope\tinput.cst\t/^b$/;\"\tb\tbroken tag:parent\\tscope\n"
  },
  {
    "path": "Tmain/broken-version.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/broken-version.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nis_feature_available \"$CTAGS\" debug\n${CTAGS} --quiet --options=NONE --langdef=BROKEN'{version=0.1}' --_force-quit=1\nexit $?\n"
  },
  {
    "path": "Tmain/broken-version.d/stderr-expected.txt",
    "content": "ctags: Warning: versionCurrent (0) must be either equal to or greater than versionAge (1): BROKEN\n"
  },
  {
    "path": "Tmain/c-anon-counter.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/c-anon-counter.d/input1.c",
    "content": "enum {\n  A, B,\n} x;\n\nstruct {\n  int C, D;\n} y;\n\nunion {\n  int E, F;\n} z;\n"
  },
  {
    "path": "Tmain/c-anon-counter.d/input2.c",
    "content": "enum {\n  G, H,\n} a;\n\nstruct {\n  int I, J;\n} b;\n\nunion {\n  int K, L;\n} c;\n"
  },
  {
    "path": "Tmain/c-anon-counter.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\n\n${CTAGS} --quiet --options=NONE -o - input1.c input2.c > $BUILDDIR/12.tmp\n${CTAGS} --quiet --options=NONE -o - input2.c input1.c > $BUILDDIR/21.tmp\n\ndiff $BUILDDIR/12.tmp $BUILDDIR/21.tmp\ns=$?\n\nif [ \"$s\" = 0 ]; then\n    rm -f $BUILDDIR/12.tmp\n    rm -f $BUILDDIR/21.tmp\nfi\n\nexit $s\n"
  },
  {
    "path": "Tmain/c-anon-counter.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/c-anon-counter.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/c-large-enum.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/c-large-enum.d/run.sh",
    "content": "# Copyright: 2023 Masatake YAMATO\n# License: GPL-2\n\ninput=/tmp/c-large-enum.d-input.c\nCTAGS=\"$1 --quiet --options=NONE\"\n\ni=0\n{\n\techo \"enum E {\"\n\twhile [ $i -lt 32770 ]; do\n\t\tprintf \"X%x,\" $i\n\t\ti=$(($i + 1))\n\tdone\n\techo \"};\"\n} > $input\n\n${CTAGS} --sort=no -n --fields= --fields=+\"{nth}\" -x --_xformat='%{name} %{nth}' \"$input\" | tail -10\nr=$?\n\nrm -f \"$input\"\n\nexit $r\n"
  },
  {
    "path": "Tmain/c-large-enum.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/c-large-enum.d/stdout-expected.txt",
    "content": "X7ff8 32760\nX7ff9 32761\nX7ffa 32762\nX7ffb 32763\nX7ffc 32764\nX7ffd 32765\nX7ffe 32766\nX7fff 32767\nX8000 32767\nX8001 32767\n"
  },
  {
    "path": "Tmain/case-insensitive-pattern.d/INPUT.MK",
    "content": ""
  },
  {
    "path": "Tmain/case-insensitive-pattern.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nexit_if_no_case_insensitive_filenames \"${CTAGS}\"\n\n${CTAGS} --quiet --options=NONE --print-language INPUT.MK\n"
  },
  {
    "path": "Tmain/case-insensitive-pattern.d/stdout-expected.txt",
    "content": "INPUT.MK: Make\n"
  },
  {
    "path": "Tmain/clear-aliases.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/clear-aliases.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho '# clear' &&\n${CTAGS} --quiet --options=NONE --alias-C= --with-list-header=no --list-aliases=C &&\n\necho '# add' &&\n${CTAGS} --quiet --options=NONE --alias-Tcl=+abc --with-list-header=no --list-aliases=Tcl &&\n\necho '# reset' &&\n${CTAGS} --quiet --options=NONE --alias-Tcl=+abc --alias-Tcl=default --with-list-header=no --list-aliases=Tcl\n\necho '# all clear' &&\n${CTAGS} --quiet --options=NONE --alias-all= --with-list-header=no --list-aliases &&\n\necho '# all reset' &&\n${CTAGS} --quiet --options=NONE --alias-Tcl=+abc --alias-all=default --with-list-header=no --list-aliases=Tcl\n\nexit $?\n"
  },
  {
    "path": "Tmain/clear-aliases.d/stdout-expected.txt",
    "content": "# clear\n# add\nexpect\ntclsh\nabc\n# reset\nexpect\ntclsh\n# all clear\n# all reset\nexpect\ntclsh\n"
  },
  {
    "path": "Tmain/client-vista-vim-fields-expectation.d/README.md",
    "content": "If your change breaks this test case, notify the change\nto https://github.com/liuchengxu/vista.vim.\n"
  },
  {
    "path": "Tmain/client-vista-vim-fields-expectation.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/client-vista-vim-fields-expectation.d/run.sh",
    "content": "# Copyright: 2021 <https://github.com/liuchengxu>\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nis_feature_available \"${CTAGS}\" json\n\n$CTAGS --quiet --options=NONE --format=2 --excmd=pattern --fields=+nksSaf --extras=+F --sort=no --append=no --extras=  --language-force=vim --vim-kinds=acfvmn --output-format=json --fields=-PF -f- test.vim\n\nexit $?\n"
  },
  {
    "path": "Tmain/client-vista-vim-fields-expectation.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/client-vista-vim-fields-expectation.d/stdout-expected.txt",
    "content": "{\"_type\": \"tag\", \"name\": \"s:cur_dir\", \"line\": 1, \"kind\": \"variable\"}\n{\"_type\": \"tag\", \"name\": \"vista#FindItemsUnderDirectory\", \"line\": 3, \"kind\": \"function\", \"signature\": \"(dir)\"}\n"
  },
  {
    "path": "Tmain/client-vista-vim-fields-expectation.d/test.vim",
    "content": "let s:cur_dir = fnamemodify(resolve(expand('<sfile>:p')), ':h')\n\nfunction! vista#FindItemsUnderDirectory(dir) abort\n  return map(split(globpath(a:dir, '*'), '\\n'), 'fnamemodify(v:val, '':t:r'')')\nendfunction\n"
  },
  {
    "path": "Tmain/combination-of-fields-Zs.d/input.c",
    "content": "struct s {\n\tint i;\n};\n"
  },
  {
    "path": "Tmain/combination-of-fields-Zs.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho '# Z only'\n$CTAGS --quiet --options=NONE --fields=Z -o - input.c 2>&1 \\\n\t| sed -e 's/\\.exe//g' \\\n\t| sort\n\n# The last sort is needed because the order of lines from stdout and\n# that from stderr is not stable.\n"
  },
  {
    "path": "Tmain/combination-of-fields-Zs.d/stdout-expected.txt",
    "content": "# Z only\nctags: Warning: enable the s field to make the Z/scope field printable\nctags: Warning: though Z/scope field is enabled, s field is not enabled\ni\tinput.c\t/^\tint i;$/;\"\tscope:struct:s\ns\tinput.c\t/^struct s {$/\n"
  },
  {
    "path": "Tmain/combination-of-fields-zkK.d/input.c",
    "content": "struct s {\n\tint i;\n};\n"
  },
  {
    "path": "Tmain/combination-of-fields-zkK.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho '# z only'\n$CTAGS --quiet --options=NONE --fields=z -o - input.c 2>&1 \\\n\t| sed -e 's/\\.exe//g' \\\n\t| sort\n\n# The last sort is needed because the order of lines from stdout and\n# that from stderr is not stable.\n"
  },
  {
    "path": "Tmain/combination-of-fields-zkK.d/stdout-expected.txt",
    "content": "# z only\nctags: Warning: enable the K field to make the z/kind field printable\nctags: Warning: though z/kind field is enabled, neither k nor K field is not enabled\ni\tinput.c\t/^\tint i;$/;\"\tkind:member\ns\tinput.c\t/^struct s {$/;\"\tkind:struct\n"
  },
  {
    "path": "Tmain/common-prelude.d/aindex.expected",
    "content": "(0)\nfalse\n(1)\ntrue\n0\n(2)\ntrue\n1\n(3)\ntrue\n2\n(4)\nfalse\n(-)\nfalse\n(0a)\ntrue\n0\n(1a)\ntrue\n1\n"
  },
  {
    "path": "Tmain/common-prelude.d/aindex.ps",
    "content": "(0) ==\n[1 2 3] 0 _aindex pstack clear\n\n(1) ==\n[1 2 3] 1 _aindex pstack clear\n\n(2) ==\n[1 2 3] 2 _aindex pstack clear\n\n(3) ==\n[1 2 3] 3 _aindex pstack clear\n\n(4) ==\n[1 2 3] 4 _aindex pstack clear\n\n(-) ==\n[] /a _aindex pstack clear\n\n(0a) ==\n[/a] /a _aindex pstack clear\n\n(1a) ==\n[/b /a /b] /a _aindex pstack clear\n"
  },
  {
    "path": "Tmain/common-prelude.d/amember.expected",
    "content": "[/a /b /c]\ntrue\ntrue\ntrue\nfalse\n[1 true (abc)]\ntrue\nfalse\ntrue\nfalse\ntrue\nfalse\n"
  },
  {
    "path": "Tmain/common-prelude.d/amember.ps",
    "content": "[/a /b /c] ==\n[/a /b /c] /a _amember ==\n[/a /b /c] /b _amember ==\n[/a /b /c] /c _amember ==\n[/a /b /c] /d _amember ==\n[1 true (abc)] ==\n[1 true (abc)] 1 _amember ==\n[1 true (abc)] 2 _amember ==\n[1 true (abc)] true _amember ==\n[1 true (abc)] false _amember ==\n[1 true (abc)] (abc) _amember ==\n[1 true (abc)] (efg) _amember ==\n"
  },
  {
    "path": "Tmain/common-prelude.d/buildstring.expected",
    "content": "(abcdefghijklm)\n"
  },
  {
    "path": "Tmain/common-prelude.d/buildstring.ps",
    "content": "[\n    ?a\n    ?b\n    ?c (d) 0 get\n    (efg)\n    ?h\n    ?i\n    ?j\n    (klm)\n    _buildstring pstack clear\n"
  },
  {
    "path": "Tmain/common-prelude.d/chop.expected",
    "content": "(abcx)\n(abc)\n(abc )\n(abc)\n(abcx)\n(abcx)\n"
  },
  {
    "path": "Tmain/common-prelude.d/chop.ps",
    "content": "(abcx) ==\n(abcx) _chop pstack clear\n\n(abc ) ==\n(abc ) _chop_space pstack clear\n\n(abcx) ==\n(abcx) _chop_space pstack clear\n"
  },
  {
    "path": "Tmain/common-prelude.d/dedup.expected",
    "content": "(===)\n32\n(===)\n41\n32\n(===)\n32\n41\n(===)\n32\n(===)\n41\n(===)\n/a\n32\n(===)\n[]\n32\n"
  },
  {
    "path": "Tmain/common-prelude.d/dedup.ps",
    "content": "/result { (===) pstack clear } def\n\n32 32 _dedup_spaces result\n32 41 _dedup_spaces result\n41 32 _dedup_spaces result\n   32 _dedup_spaces result\n   41 _dedup_spaces result\n\n32 /a _dedup_spaces result\n32 [] _dedup_spaces result\n"
  },
  {
    "path": "Tmain/common-prelude.d/dedup_spaces.expected",
    "content": "32\n97\n32\n98\n32\n97\n"
  },
  {
    "path": "Tmain/common-prelude.d/dedup_spaces.ps",
    "content": "?a ?\\_ ( ) 0 get _dedup_spaces pstack clear\n?a ?\\_ ?b ( ) 0 get _dedup_spaces pstack clear\n"
  },
  {
    "path": "Tmain/common-prelude.d/ndup.expected",
    "content": "(abc)\n(efg)\n(efg)\n(xyz)\n(xyz)\n(xyz)\n(xyz)\n"
  },
  {
    "path": "Tmain/common-prelude.d/ndup.ps",
    "content": "(abc) 0 _ndup pstack clear\n(efg) 1 _ndup pstack clear\n(xyz) 3 _ndup pstack clear\n"
  },
  {
    "path": "Tmain/common-prelude.d/normalize_spaces.expected",
    "content": "(0abc, d, efg, hij)\n(1abc, d, efg, hij)\n"
  },
  {
    "path": "Tmain/common-prelude.d/normalize_spaces.ps",
    "content": "/x (0abc,\\t\\t\\n \\nd,\\f\\f\\v\\f\\v\\r\\r\\r\\n efg,  hij) def\nx _normalize_spaces! x pstack clear\n\n(1abc,\\t\\t\\n \\nd,\\f\\f\\v\\f\\v\\r\\r\\r\\n efg,  hij) dup\n_normalize_spaces! pstack clear\n"
  },
  {
    "path": "Tmain/common-prelude.d/putlast.expected",
    "content": "(abcdefgh)\n"
  },
  {
    "path": "Tmain/common-prelude.d/putlast.ps",
    "content": "/a (abc) def\n\na ?d _putlast!\na (efg) _putlast!\na ?h _putlast!\na ==\n"
  },
  {
    "path": "Tmain/common-prelude.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\nOPTSCRIPT=$4\n\n. ../utils.sh\n\nif ! [ -x \"${OPTSCRIPT}\" ]; then\n\tskip \"no optscript\"\nfi\n\nrm -f ${BUILDDIR}/*.{in,out}.tmp\n\nfor t in $(ls *.ps); do\n\ti=${BUILDDIR}/${t}.in.tmp\n\to=${BUILDDIR}/${t}.out.tmp\n\te=$(basename $t .ps).expected\n\n    printf \"%s\" \"${t}...\"\n\n\t{\n\t\t${CTAGS} --quiet --options=NONE --_dump-prelude\n\t\techo\n\t\tcat $t\n\t} > $i\n\n\t${OPTSCRIPT} $i > $o 2>&1\n\ts=$?\n\techo \"$s\"\n\n\tif [ $s != 0 ]; then\n\t\tcontinue\n\tfi\n\tif diff -ruN --strip-trailing-cr $e $o; then\n\t\trm $i\n\t\trm $o\n\tfi\ndone\n"
  },
  {
    "path": "Tmain/common-prelude.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/common-prelude.d/stdout-expected.txt",
    "content": "aindex.ps...0\namember.ps...0\nbuildstring.ps...0\nchop.ps...0\ndedup.ps...0\ndedup_spaces.ps...0\nndup.ps...0\nnormalize_spaces.ps...0\nputlast.ps...0\ntr.ps...0\n"
  },
  {
    "path": "Tmain/common-prelude.d/tr.expected",
    "content": "(a-b-c)\n(x-y-z)\n"
  },
  {
    "path": "Tmain/common-prelude.d/tr.ps",
    "content": "/x (a\\nb\\n\\c) def\nx (\\n-) _tr! x ==\n\n(x\\ny\\nz) dup (\\n-) _tr! ==\n"
  },
  {
    "path": "Tmain/cxx-how-kinds-defs-are-shared-or-copyed.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nprintf \"[C] enabling in C: \"\n${CTAGS} --quiet --options=NONE \\\n\t --kinds-C=+f --list-kinds=C | grep ^f\n\nprintf \"[C] disabling in C: \"\n${CTAGS} --quiet --options=NONE \\\n\t --kinds-C=-f --list-kinds=C | grep ^f\n\nprintf \"[C++] enabling in C: \"\n${CTAGS} --quiet --options=NONE \\\n\t --kinds-C=+f --list-kinds=C++ | grep ^f\n\nprintf \"[C++] disabling in C: \"\n${CTAGS} --quiet --options=NONE \\\n\t --kinds-C=-f --list-kinds=C++ | grep ^f\n\nprintf \"[C] enabling in C++: \"\n${CTAGS} --quiet --options=NONE \\\n\t --kinds-C++=+f --list-kinds=C | grep ^f\n\nprintf \"[C] disabling in C++: \"\n${CTAGS} --quiet --options=NONE \\\n\t --kinds-C++=-f --list-kinds=C | grep ^f\n\nprintf \"[C++] enabling in C++: \"\n${CTAGS} --quiet --options=NONE \\\n\t --kinds-C++=+f --list-kinds=C++ | grep ^f\n\nprintf \"[C++] disabling in C++: \"\n${CTAGS} --quiet --options=NONE \\\n\t --kinds-C++=-f --list-kinds=C++ | grep ^f\n"
  },
  {
    "path": "Tmain/cxx-how-kinds-defs-are-shared-or-copyed.d/stdout-expected.txt",
    "content": "[C] enabling in C: f  function definitions\n[C] disabling in C: f  function definitions [off]\n[C++] enabling in C: f  function definitions\n[C++] disabling in C: f  function definitions [off]\n[C] enabling in C++: f  function definitions\n[C] disabling in C++: f  function definitions [off]\n[C++] enabling in C++: f  function definitions\n[C++] disabling in C++: f  function definitions [off]\n"
  },
  {
    "path": "Tmain/disable-fixed-field.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/disable-fixed-field.d/input.c",
    "content": ""
  },
  {
    "path": "Tmain/disable-fixed-field.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --fields=-N -o - input.c\n${CTAGS} --quiet --options=NONE --fields=-F -o - input.c\n${CTAGS} --quiet --options=NONE --fields=-P -o - input.c\n${CTAGS} --quiet --options=NONE --fields=-'{name}' -o - input.c\n${CTAGS} --quiet --options=NONE --fields=-'{input}' -o - input.c\n${CTAGS} --quiet --options=NONE --fields=-'{pattern}' -o - input.c\n"
  },
  {
    "path": "Tmain/disable-fixed-field.d/stderr-expected.txt",
    "content": "ctags: Warning: Cannot disable fixed field: 'N'{name} in ctags output mode\nctags: Warning: Cannot disable fixed field: 'F'{input} in ctags output mode\nctags: Warning: Cannot disable fixed field: 'P'{pattern} in ctags output mode\nctags: Warning: Cannot disable fixed field: 'N'{name} in ctags output mode\nctags: Warning: Cannot disable fixed field: 'F'{input} in ctags output mode\nctags: Warning: Cannot disable fixed field: 'P'{pattern} in ctags output mode\n"
  },
  {
    "path": "Tmain/disable-fixed-field.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/disable-languages.d/input-matlab.m",
    "content": "# -*- matlab -*-\n"
  },
  {
    "path": "Tmain/disable-languages.d/input-objc.m",
    "content": "#error -*- objc -*-\n"
  },
  {
    "path": "Tmain/disable-languages.d/input.m",
    "content": ""
  },
  {
    "path": "Tmain/disable-languages.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\nCTAGS=$1\n\necho '# FILE NAME ONLY'\n# extension `m' matches both matlab and objc.\n# matlab wins by the alphabetical order of parser names\n${CTAGS} --quiet --options=NONE -G --print-language input.m\n\n# extension `m' matches only objc because matlab is disabled.\n${CTAGS} --quiet --options=NONE -G --languages=-MatLab --print-language input.m\n\n# extension `m' matches only matlab because objc is disabled.\n${CTAGS} --quiet --options=NONE -G --languages=-ObjectiveC --print-language input.m\n\n# extension `m' matches no parser because the both objc and matlab\n# are disabled.\n${CTAGS} --quiet --options=NONE -G --languages=-ObjectiveC,-MatLab --print-language input.m\n${CTAGS} --quiet --options=NONE -G --languages=-MatLab,-ObjectiveC --print-language input.m\n\necho '# EMACS MODE: MATLAB'\n# extension `m' matches both matlab and objc.\n# matlab wins by emacs modeline written in the input file.\n${CTAGS} --quiet --options=NONE -G --print-language input-matlab.m\n\n# extension `m' matches only objc. That's all.\n${CTAGS} --quiet --options=NONE -G --languages=-MatLab --print-language input-matlab.m\n\n# extension `m' matches only matlab. That's all.\n${CTAGS} --quiet --options=NONE -G --languages=-ObjectiveC --print-language input-matlab.m\n\n# extension `m' matches no parser because the both objc and matlab\n# are disabled. That's all. ctags has no chance to read the file contents.\n${CTAGS} --quiet --options=NONE -G --languages=-ObjectiveC,-MatLab --print-language input-matlab.m\n${CTAGS} --quiet --options=NONE -G --languages=-MatLab,-ObjectiveC --print-language input-matlab.m\n\necho '# EMACS MODE: OBJC'\n# extension `m' matches both matlab and objc.\n# objc wins by emacs modeline written in the input file.\n${CTAGS} --quiet --options=NONE -G --print-language input-objc.m\n\n# extension `m' matches only objc. That's all.\n${CTAGS} --quiet --options=NONE -G --languages=-MatLab --print-language input-objc.m\n\n# extension `m' matches only matlab. That's all.\n${CTAGS} --quiet --options=NONE -G --languages=-ObjectiveC --print-language input-objc.m\n\n# extension `m' matches no parser because the both objc and matlab\n# are disabled. That's all. ctags has no chance to read the file contents.\n${CTAGS} --quiet --options=NONE -G --languages=-ObjectiveC,-MatLab --print-language input-objc.m\n${CTAGS} --quiet --options=NONE -G --languages=-MatLab,-ObjectiveC --print-language input-objc.m\n"
  },
  {
    "path": "Tmain/disable-languages.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/disable-languages.d/stdout-expected.txt",
    "content": "# FILE NAME ONLY\ninput.m: MatLab\ninput.m: ObjectiveC\ninput.m: MatLab\ninput.m: NONE\ninput.m: NONE\n# EMACS MODE: MATLAB\ninput-matlab.m: MatLab\ninput-matlab.m: ObjectiveC\ninput-matlab.m: MatLab\ninput-matlab.m: NONE\ninput-matlab.m: NONE\n# EMACS MODE: OBJC\ninput-objc.m: ObjectiveC\ninput-objc.m: ObjectiveC\ninput-objc.m: MatLab\ninput-objc.m: NONE\ninput-objc.m: NONE\n"
  },
  {
    "path": "Tmain/dot-ctags-with-indentation.d/args.ctags",
    "content": "--_echo=A-begin\n\t--_echo=A-with-tab\n    --_echo=A-with-spaces\n--_echo=B-begin\n\n"
  },
  {
    "path": "Tmain/dot-ctags-with-indentation.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/dot-ctags-with-indentation.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --options=NONE --options=./args.ctags --_force-quit=0\nexit $?\n"
  },
  {
    "path": "Tmain/dot-ctags-with-indentation.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nctags: Notice: A-begin\nctags: Notice: A-with-tab\nctags: Notice: A-with-spaces\nctags: Notice: B-begin\n"
  },
  {
    "path": "Tmain/dot-ctags-with-indentation.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/dynamic-kinds.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/dynamic-kinds.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --quiet --options=NONE\t\t\t\t\t\t\\\n\t\t --langdef=X --kinddef-X='a,anchor,anchors'\t\\\n\t\t --kinddef-X='b,batch,batches'\t\t\t\t\\\n\t\t --list-kinds-full=X\nexit $?\n"
  },
  {
    "path": "Tmain/dynamic-kinds.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/dynamic-kinds.d/stdout-expected.txt",
    "content": "#LETTER NAME   ENABLED REFONLY NROLES MASTER VER DESCRIPTION\na       anchor yes     no      0      NONE     0 anchors\nb       batch  yes     no      0      NONE     0 batches\n"
  },
  {
    "path": "Tmain/e-ctags-output.d/input_file.cc",
    "content": "/* Could NOT be parsed well.\n   The signature should be  recorded well. */\nint32 test(int32 a)\n{\n    return 0;\n}\n/* Can be parsed */\nint32 test2(void)\n{\n    return 0;\n}\n\n/* A tab is included in signature.\n   However, it should be recorded well after converting\n   the tab to a whitespace. */\nint32 test3(int32\ta)\n{\n    return 0;\n}\n\n/* A newline is included in signature.\n   However, it should be recorded well after converting\n   the newline to a whitespace. */\nint32 test4(int32\na)\n{\n    return 0;\n}\n"
  },
  {
    "path": "Tmain/e-ctags-output.d/input_scope.rst",
    "content": "===========\ntitle\n===========\n\n\nX\ttab\tY\n===========\nThis one will not be recorded.\n\ntopic in tab\n----------------------\nThis one will not be recorded if --fileds=+s is given\nbecause a tab char is in the scope field.\n\nX space Y\n===========\nThis one will be recorded.\n\ntopic in space\n----------------------\nThis one will be recorded.\n"
  },
  {
    "path": "Tmain/e-ctags-output.d/input_space.rst",
    "content": "===================================\nA spaces B\n===================================\nThs should be recorded in e-ctags output.\n"
  },
  {
    "path": "Tmain/e-ctags-output.d/input_tab.rst",
    "content": "===================================\nA\ttabs\tB\n===================================\nThs should not be recorded in e-ctags output.\n"
  },
  {
    "path": "Tmain/e-ctags-output.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n# The original bug is reported by @elecalion in #2014.\n\nCTAGS=$1\nBUILDDIR=$2\n\n. ../utils.sh\n\ntmp=\"input file.cc\"\n\nrun()\n{\n\techo '#'\n\techo '#' with $1\n\techo '#'\n\n\tcp input_file.cc $BUILDDIR/\"${tmp}\"\n\tif ! direq_maybe $BUILDDIR .; then\n\t\tfor f in input_*.rst; do\n\t\t\tif ! [ -e $BUILDDIR/$f ]; then\n\t\t\t\tcp $f $BUILDDIR\n\t\t\t\tcopied=yes\n\t\t\tfi\n\t\tdone\n\tfi\n\t(\n\t\tcd $BUILDDIR\n\t\t\"${CTAGS}\" --quiet --options=NONE ${1} --output-format=e-ctags \\\n\t\t\t\t   --kinds-c++=+p --fields=+iaSs \\\n\t\t\t\t   -o - \\\n\t\t\t\t   \"${tmp}\" \\\n\t\t\t\t   input_tab.rst input_space.rst\n\t\trm -f \"${tmp}\"\n\n\t\techo \"# WITH SCOPE\"\n\t\t\"${CTAGS}\" --quiet --options=NONE ${1} --output-format=e-ctags \\\n\t\t\t\t   --fields=+s \\\n\t\t\t\t   -o - \\\n\t\t\t\t   input_scope.rst\n\n\t\techo \"# WITHOUT SCOPE\"\n\t\t\"${CTAGS}\" --quiet --options=NONE ${1} --output-format=e-ctags \\\n\t\t\t\t   --fields=-s \\\n\t\t\t\t   -o - \\\n\t\t\t\t   input_scope.rst\n\n\t\tif [ \"$copied\" = \"yes\" ]; then\n\t\t\trm -f input_*.rst\n\t\tfi\n\t)\n}\n\nrun \"--sort=yes\"\nrun \"--sort=no\"\n"
  },
  {
    "path": "Tmain/e-ctags-output.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/e-ctags-output.d/stdout-expected.txt",
    "content": "#\n# with --sort=yes\n#\nA spaces B\tinput_space.rst\t/^A spaces B$/;\"\tH\ntest\tinput file.cc\t/^int32 test(int32 a)$/;\"\tf\ttyperef:typename:int32\tsignature:(int32 a)\ntest2\tinput file.cc\t/^int32 test2(void)$/;\"\tf\ttyperef:typename:int32\tsignature:(void)\ntest3\tinput file.cc\t/^int32 test3(int32\ta)$/;\"\tf\ttyperef:typename:int32\tsignature:(int32 a)\ntest4\tinput file.cc\t/^int32 test4(int32$/;\"\tf\ttyperef:typename:int32\tsignature:(int32 a)\n# WITH SCOPE\nX space Y\tinput_scope.rst\t/^X space Y$/;\"\tc\ttitle:title\ntitle\tinput_scope.rst\t/^title$/;\"\tH\ntopic in space\tinput_scope.rst\t/^topic in space$/;\"\ts\tchapter:X space Y\n# WITHOUT SCOPE\nX space Y\tinput_scope.rst\t/^X space Y$/;\"\tc\ntitle\tinput_scope.rst\t/^title$/;\"\tH\ntopic in space\tinput_scope.rst\t/^topic in space$/;\"\ts\ntopic in tab\tinput_scope.rst\t/^topic in tab$/;\"\ts\n#\n# with --sort=no\n#\ntest\tinput file.cc\t/^int32 test(int32 a)$/;\"\tf\ttyperef:typename:int32\tsignature:(int32 a)\ntest2\tinput file.cc\t/^int32 test2(void)$/;\"\tf\ttyperef:typename:int32\tsignature:(void)\ntest3\tinput file.cc\t/^int32 test3(int32\ta)$/;\"\tf\ttyperef:typename:int32\tsignature:(int32 a)\ntest4\tinput file.cc\t/^int32 test4(int32$/;\"\tf\ttyperef:typename:int32\tsignature:(int32 a)\nA spaces B\tinput_space.rst\t/^A spaces B$/;\"\tH\n# WITH SCOPE\ntitle\tinput_scope.rst\t/^title$/;\"\tH\nX space Y\tinput_scope.rst\t/^X space Y$/;\"\tc\ttitle:title\ntopic in space\tinput_scope.rst\t/^topic in space$/;\"\ts\tchapter:X space Y\n# WITHOUT SCOPE\ntitle\tinput_scope.rst\t/^title$/;\"\tH\ntopic in tab\tinput_scope.rst\t/^topic in tab$/;\"\ts\nX space Y\tinput_scope.rst\t/^X space Y$/;\"\tc\ntopic in space\tinput_scope.rst\t/^topic in space$/;\"\ts\n"
  },
  {
    "path": "Tmain/early--version-opt-processing.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/early--version-opt-processing.d/run.sh",
    "content": "# Copyright: 2023 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\n\nremove_ctags_d=y\nif [ -d $BUILDDIR/.ctags.d ]; then\n   remove_ctags_d=n\nfi\n\ndefc_ctags=tmain_defc.ctags\nmkdir -p $BUILDDIR/.ctags.d\necho \"--langdef=C\" > $BUILDDIR/.ctags.d/\"$defc_ctags\"\n\n(cd $BUILDDIR; \"${CTAGS}\" --version;) > /dev/null\nstatus=$?\n\nrm $BUILDDIR/.ctags.d/\"$defc_ctags\"\nif [ \"$remove_ctags_d\" = y ]; then\n\trmdir $BUILDDIR/.ctags.d\nfi\n\nexit \"$status\"\n"
  },
  {
    "path": "Tmain/early--version-opt-processing.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/early--version-opt-processing.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/emacs-modeline-downcased-mode.d/exti-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/emacs-modeline-downcased-mode.d/functions",
    "content": "# -*-Shell-script-*-\n\n#\n# This is found in /etc/init.d/functions of Fedora23.\n#\n# This test case is special as as case for modeline\n# testing:\n#\n# 1. No whitespace between modename and -*-, and\n# 2. Capitalized\n#\n"
  },
  {
    "path": "Tmain/emacs-modeline-downcased-mode.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n$CTAGS --options=NONE --quiet -G --print-language ./functions\n\n"
  },
  {
    "path": "Tmain/emacs-modeline-downcased-mode.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\n"
  },
  {
    "path": "Tmain/emacs-modeline-downcased-mode.d/stdout-expected.txt",
    "content": "./functions: Sh\n"
  },
  {
    "path": "Tmain/emacs-modeline-non-alnum-in-head.d/input",
    "content": "/* -*- mode: C++; eval: (auto-fill-mode 1); -*- */\n"
  },
  {
    "path": "Tmain/emacs-modeline-non-alnum-in-head.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n$CTAGS --quiet --options=NONE -G --print-language input\n"
  },
  {
    "path": "Tmain/emacs-modeline-non-alnum-in-head.d/stdout-expected.txt",
    "content": "input: C++\n"
  },
  {
    "path": "Tmain/emacs-modeline-non-alnum-in-head2.d/input",
    "content": "/* -*- C++ -*- */\n"
  },
  {
    "path": "Tmain/emacs-modeline-non-alnum-in-head2.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n$CTAGS --quiet --options=NONE -G --print-language input\n"
  },
  {
    "path": "Tmain/emacs-modeline-non-alnum-in-head2.d/stdout-expected.txt",
    "content": "input: C++\n"
  },
  {
    "path": "Tmain/emacs-modeline-non-alnum-in-tail.d/input",
    "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* Local Variables:  */\n/* mode: c++         */\n/* comment-column: 0 */\n/* End:              */\n\n\n"
  },
  {
    "path": "Tmain/emacs-modeline-non-alnum-in-tail.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n$CTAGS --quiet --options=NONE -G --print-language input\n"
  },
  {
    "path": "Tmain/emacs-modeline-non-alnum-in-tail.d/stdout-expected.txt",
    "content": "input: C++\n"
  },
  {
    "path": "Tmain/emacs-modeline-uppercased-marker.d/exti-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/emacs-modeline-uppercased-marker.d/macros",
    "content": "#  -*- Mode: rpm-spec; indent-tabs-mode: nil -*- */\n#  SPDX-License-Identifier: LGPL-2.1+\n#\n#  This file is part of systemd.\n\n# RPM macros for packages installing systemd unit files\n"
  },
  {
    "path": "Tmain/emacs-modeline-uppercased-marker.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n$CTAGS --options=NONE --quiet -G --print-language ./macros\n"
  },
  {
    "path": "Tmain/emacs-modeline-uppercased-marker.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\n"
  },
  {
    "path": "Tmain/emacs-modeline-uppercased-marker.d/stdout-expected.txt",
    "content": "./macros: RpmSpec\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/input-firstline0.unknown",
    "content": "# -*- mode: sh; eval: (sh-set-shell \"zsh\") -*-\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/input-firstline1.unknown",
    "content": "# -*- mode: shell-script; sh-set-shell: zsh -*-\n# Emacs doesn't understand this notation but I found one in\n# https://github.com/neumachen/dotfiles/blob/3e2b04249f852dbdf7dee1e33e518de61031eb04/private_dot_config/exact_zsh/dot_zprofile\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/input-firstline2.unknown",
    "content": "# -*- mode: sh; eval: (sh-set-shell \"bash\") -*-\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/input-firstline3.unknown",
    "content": "# -*- mode: shell-script; sh-set-shell: bash -*-\n# Emacs doesn't understand this notation but I found one in\n# https://github.com/neumachen/dotfiles/blob/3e2b04249f852dbdf7dee1e33e518de61031eb04/private_dot_config/exact_zsh/dot_zprofile\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/input-firstline4.unknown",
    "content": "# -*- mode: sh -*-\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/input-firstline5.unknown",
    "content": "# -*- mode: shell-script -*-\n# Emacs doesn't understand this notation but I found one in\n# https://github.com/neumachen/dotfiles/blob/3e2b04249f852dbdf7dee1e33e518de61031eb04/private_dot_config/exact_zsh/dot_zprofile\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/input-lastlist0.unknown",
    "content": "# Local Variables:\n# mode: sh\n# eval: (sh-set-shell \"zsh\")\n# End:\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/input-lastlist1.unknown",
    "content": "# Local Variables:\n# mode: sh\n# eval: (sh-set-shell \"bash\")\n# End:\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/input-lastlist2.unknown",
    "content": "# Local Variables:\n# mode: sh\n# End:\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/run.sh",
    "content": "# Copyright: 2022 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nfor f in input-firstline0.unknown \\\n\t\t\t input-firstline1.unknown \\\n\t\t\t input-firstline2.unknown \\\n\t\t\t input-firstline3.unknown \\\n\t\t\t input-firstline4.unknown \\\n\t\t\t input-firstline5.unknown \\\n\t\t\t input-lastlist0.unknown  \\\n\t\t\t input-lastlist1.unknown  \\\n\t\t\t input-lastlist2.unknown  \\\n\t\t ; do\n\t$CTAGS --quiet --options=NONE -G --print-language $f\ndone\n"
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/emacs-modline-shell-script-zsh.d/stdout-expected.txt",
    "content": "input-firstline0.unknown: Zsh\ninput-firstline1.unknown: Zsh\ninput-firstline2.unknown: Sh\ninput-firstline3.unknown: Sh\ninput-firstline4.unknown: Sh\ninput-firstline5.unknown: Sh\ninput-lastlist0.unknown: Zsh\ninput-lastlist1.unknown: Sh\ninput-lastlist2.unknown: Sh\n"
  },
  {
    "path": "Tmain/enable-kind-postfix-with-wildcard.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --quiet --options=NONE '--kinds-all=*' --list-kinds | grep '\\[off\\]'\n\n"
  },
  {
    "path": "Tmain/enable-kind-postfix-with-wildcard.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/enable-kind-postfix-with-wildcard.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/enable-kind-postfix.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --quiet --options=NONE --kinds-c=+l-f --list-kinds=C | grep '^[fl]'\n\n\n\n"
  },
  {
    "path": "Tmain/enable-kind-postfix.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/enable-kind-postfix.d/stdout-expected.txt",
    "content": "f  function definitions [off]\nl  local variables\n"
  },
  {
    "path": "Tmain/enable-kind-prefix-with-wildcard.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --quiet --options=NONE --kinds-all='*' --list-kinds | grep '\\[off\\]'\n\n"
  },
  {
    "path": "Tmain/enable-kind-prefix-with-wildcard.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/enable-kind-prefix-with-wildcard.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/enable-kind-prefix.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --quiet --options=NONE --kinds-c=+l-f --list-kinds=C | grep '^[fl]'\n"
  },
  {
    "path": "Tmain/enable-kind-prefix.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/enable-kind-prefix.d/stdout-expected.txt",
    "content": "f  function definitions [off]\nl  local variables\n"
  },
  {
    "path": "Tmain/enable-non-existing-kind.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --quiet --options=NONE --kinds-C=+Z --_force-quit\n\n"
  },
  {
    "path": "Tmain/enable-non-existing-kind.d/stderr-expected.txt",
    "content": "ctags: Warning: Unsupported kind: 'Z' for --kinds-C option\n"
  },
  {
    "path": "Tmain/epoch-field.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nO0=/tmp/ctags-tstamp-$$.c\nO1=/tmp/ctags-tstamp-$$.h\nO2=/tmp/ctags-tstamp-$$.m\n\ncat > $O0 <<EOF\nint main (void)\n{\n\treturn 0;\n}\nEOF\n\ncat > $O1 <<EOF\nextern void foo (void);\nEOF\n\ncat > $O2 <<EOF\n#import <class.h>\nEOF\n\nis_json_avaiable()\n{\n\t$1 --quiet --options=NONE --with-list-header=no --list-features | grep -q \"json\"\n}\n\nrun()\n{\n\tlocal o=$1\n\tlocal t=$2\n\tshift 2\n\tlocal s\n\n\techo $t\n\tTZ=UTC+00:00 touch -t '200402291621.42' $o &&\n\t\t$CTAGS \"$@\" --kinds-C= --extras=f --fields=T -o - $o \\\n\t\t\t| sed -e 's/.*\\(epoch:.*\\)/tags:\\1/' &&\n\t\t$CTAGS \"$@\" --kinds-C= --extras=f --fields=T -o - -x --_xformat=\"xref:epoch:%T\" $o &&\n\t\t{\n\t\t\tif is_json_avaiable $CTAGS; then\n\t\t\t\t$CTAGS \"$@\" --kinds-C= --extras=f --fields=T -o - --output-format=json $o \\\n\t\t\t\t\t| sed -e 's/.*\"epoch\": \\([0-9]*\\).*/json:epoch:\\1/'\n\t\t\telse\n\t\t\t\techo \"json:epoch:1078071702\"\n\t\t\tfi\n\t\t}\n\ts=$?\n\trm $o\n\treturn $s\n}\n\nrun $O0 \".c file\" --quiet --options=NONE && run $O1 \".h file\" --quiet --options=NONE  && run $O2 \".m file\" --quiet --options=NONE -G\nexit $?\n"
  },
  {
    "path": "Tmain/epoch-field.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/epoch-field.d/stdout-expected.txt",
    "content": ".c file\ntags:epoch:1078071702\nxref:epoch:1078071702\njson:epoch:1078071702\n.h file\ntags:epoch:1078071702\nxref:epoch:1078071702\njson:epoch:1078071702\n.m file\ntags:epoch:1078071702\nxref:epoch:1078071702\njson:epoch:1078071702\n"
  },
  {
    "path": "Tmain/errors-about-parser-specific-extras.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\nO=\"--quiet --options=NONE --with-list-header=no\"\n\necho '#lang' 1>&2\n${CTAGS} ${O} --extras-NOSUCHLANG=-'{whitespaceSwapped}' --list-extras\n${CTAGS} ${O} --extras-NOSUCHLANG=-'{whitespaceSwapped}' --list-extras=\n${CTAGS} ${O} --extras-Robot=-'{whitespaceSwapped}' --list-extras=NOSUCHLANG\n\necho '#extras' 1>&2\n${CTAGS} ${O} --extras-Robot=-'{NOSUCHEXTRA}' --list-extras\n${CTAGS} ${O} --extras-Robot=-'{NOSUCHEXTRA}' --list-extras=\n${CTAGS} ${O} --extras-Robot=-'{NOSUCHEXTRA}' --list-extras=NOSUCHLANG\n\necho '#null' 1>&2\n${CTAGS} ${O} --extras-= --list-extras\n\n# not an error, just set all extras to false.\n${CTAGS} ${O} --extras-Robot= --list-extras\n\n${CTAGS} ${O} --extras-Robot=-'{whitespaceSwapped}' --list-extras=\n\necho '#null null' 1>&2\n\n# About --extras-Robot=, not an error, just set all extras to false.\n${CTAGS} ${O} --extras-Robot= --list-extras=\n${CTAGS} ${O} --extras-= --list-extras=\n"
  },
  {
    "path": "Tmain/errors-about-parser-specific-extras.d/stderr-expected.txt",
    "content": "#lang\nctags: Warning: Unknown language: NOSUCHLANG (ignoring \"--extras-NOSUCHLANG\")\nctags: Warning: Unknown language: NOSUCHLANG (ignoring \"--extras-NOSUCHLANG\")\nctags: Unknown language \"NOSUCHLANG\" in \"list-extras\" option\n#extras\nctags: no such extra: 'NOSUCHEXTRA'\nctags: no such extra: 'NOSUCHEXTRA'\nctags: no such extra: 'NOSUCHEXTRA'\n#null\nctags: No language given in \"extras-\" option\n#null null\nctags: No language given in \"extras-\" option\n"
  },
  {
    "path": "Tmain/errors-if-tags-exits-as-directory.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/errors-if-tags-exits-as-directory.d/run.sh",
    "content": "# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE $0\n"
  },
  {
    "path": "Tmain/errors-if-tags-exits-as-directory.d/stderr-expected.txt",
    "content": "ctags: \"tags\" already exists as a directory; I cannot write tag entries there.\nRemove the directory or specify a file name with -o <tagfile> option.\n"
  },
  {
    "path": "Tmain/errors-if-tags-exits-as-directory.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/errors-in-options-roles.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\nCTAGS=$1\n\nstatus ()\n{\n\techo \"status: $1\"\n} 1>&2\n\ntitle()\n{\n    echo\n    echo '#'\n\tfor x in \"$@\"; do\n\t\techo '#' $x\n\tdone\n    echo '#'\n} 1>&2\n\nrun()\n{\n\ttitle \"$@\"\n\t${CTAGS} --quiet --options=NONE \"$@\" --_force-quit=42\n\tstatus $?\n}\nrun '--roles-all=something'\n\nrun '--roles-all.*=something'\n\nrun '--roles-all.?='\n\nrun '--roles-NoSuchLang='\n\nrun '--roles-NoSuchLang.*='\nrun '--roles-NoSuchLang=+{role}'\nrun '--roles-NoSuchLang=-{role}'\n\nrun '--roles-C={role}'\nrun '--roles-C=+{role}'\nrun '--roles-C=-{role}'\n\nrun '--roles-C.*={role}'\nrun '--roles-C.*=+{role}'\nrun '--roles-C.*=-{role}'\n\nrun '--roles-C.{header='\nrun '--roles-C.{file}='\nrun '--roles-C.{noSuchKind}='\nrun '--roles-C.{header}x='\n\nrun '--roles-C.F='\n\n# run '--roles-C.X='\ntitle \"unknown kind letter x\"\n${CTAGS} --quiet --options=NONE --langdef=MyLang --roles-MyLang.X= --_force-quit=42\nstatus $?\n\nrun '--roles-C.fx='\nrun '--roles-C.?='\n\nrun '--roles-C.h={system'\nrun '--roles-C.h=+{system'\nrun '--roles-C.h=-{system'\nrun '--roles-C.h={system}{local'\nrun '--roles-C.h=+{system}{local'\nrun '--roles-C.h=-{system}{local'\nrun '--roles-C.h={system{local}'\nrun '--roles-C.h=+{system{local}'\nrun '--roles-C.h=-{system{local}'\n\nrun '--roles-C.{header}={system'\nrun '--roles-C.{header}=+{system'\nrun '--roles-C.{header}=-{system'\nrun '--roles-C.{header}={system}{local'\nrun '--roles-C.{header}=+{system}{local'\nrun '--roles-C.{header}=-{system}{local'\nrun '--roles-C.{header}={system{local}'\nrun '--roles-C.{header}=+{system{local}'\nrun '--roles-C.{header}=-{system{local}'\n\nrun '--roles-C.h={noSuchRole}'\nrun '--roles-C.h=+{noSuchRole}'\nrun '--roles-C.h=-{noSuchRole}'\nrun '--roles-C.h={system}{noSuchRole}'\nrun '--roles-C.h={noSuchRole}'\nrun '--roles-C.h=+{system}{noSuchRole}'\nrun '--roles-C.h=-{system}{noSuchRole}'\nrun '--roles-C.h=+{system}-{noSuchRole}'\nrun '--roles-C.h=-{system}+{noSuchRole}'\n\nrun '--roles-C.{header}={noSuchRole}'\nrun '--roles-C.{header}=+{noSuchRole}'\nrun '--roles-C.{header}=-{noSuchRole}'\nrun '--roles-C.{header}={system}{noSuchRole}'\nrun '--roles-C.{header}={noSuchRole}'\nrun '--roles-C.{header}=+{system}{noSuchRole}'\nrun '--roles-C.{header}=-{system}{noSuchRole}'\nrun '--roles-C.{header}=+{system}-{noSuchRole}'\nrun '--roles-C.{header}=-{system}+{noSuchRole}'\n\nrun '--roles-C.h=x{system}'\nrun '--roles-C.h=+x{system}'\nrun '--roles-C.h=-x{system}'\nrun '--roles-C.h=x+{system}'\nrun '--roles-C.h=+x+{system}'\nrun '--roles-C.h=-x+{system}'\nrun '--roles-C.h=x-{system}'\nrun '--roles-C.h=+x-{system}'\nrun '--roles-C.h=-x+-system}'\n\nrun '--roles-C.{header}=x{system}'\nrun '--roles-C.{header}=+x{system}'\nrun '--roles-C.{header}=-x{system}'\nrun '--roles-C.{header}=x+{system}'\nrun '--roles-C.{header}=+x+{system}'\nrun '--roles-C.{header}=-x+{system}'\nrun '--roles-C.{header}=x-{system}'\nrun '--roles-C.{header}=+x-{system}'\nrun '--roles-C.{header}=-x+-system}'\n"
  },
  {
    "path": "Tmain/errors-in-options-roles.d/stderr-expected.txt",
    "content": "\n#\n# --roles-all=something\n#\nctags: only '*' or '' (empty string) is acceptable as an argument for --roles-all: something\nstatus: 1\n\n#\n# --roles-all.*=something\n#\nctags: only '*' or '' (empty string) is acceptable as an argument for --roles-all.*: something\nstatus: 1\n\n#\n# --roles-all.?=\n#\nctags: only '*' or '' (empty string) is acceptable as a kind spec for --roles-all: --roles-all.?\nstatus: 1\n\n#\n# --roles-NoSuchLang=\n#\nctags: Warning: unknown language \"NoSuchLang\" in --roles-NoSuchLang option\nstatus: 42\n\n#\n# --roles-NoSuchLang.*=\n#\nctags: Warning: unknown language \"NoSuchLang\" in --roles-NoSuchLang.* option\nstatus: 42\n\n#\n# --roles-NoSuchLang=+{role}\n#\nctags: Warning: unknown language \"NoSuchLang\" in --roles-NoSuchLang option\nstatus: 42\n\n#\n# --roles-NoSuchLang=-{role}\n#\nctags: Warning: unknown language \"NoSuchLang\" in --roles-NoSuchLang option\nstatus: 42\n\n#\n# --roles-C={role}\n#\nctags: only '*' or '' (empty string) is acceptable as an argument for --roles-C: {role}\nstatus: 1\n\n#\n# --roles-C=+{role}\n#\nctags: only '*' or '' (empty string) is acceptable as an argument for --roles-C: +{role}\nstatus: 1\n\n#\n# --roles-C=-{role}\n#\nctags: only '*' or '' (empty string) is acceptable as an argument for --roles-C: -{role}\nstatus: 1\n\n#\n# --roles-C.*={role}\n#\nctags: only '*' or '' (empty string) is acceptable as an argument for --roles-C.*: {role}\nstatus: 1\n\n#\n# --roles-C.*=+{role}\n#\nctags: only '*' or '' (empty string) is acceptable as an argument for --roles-C.*: +{role}\nstatus: 1\n\n#\n# --roles-C.*=-{role}\n#\nctags: only '*' or '' (empty string) is acceptable as an argument for --roles-C.*: -{role}\nstatus: 1\n\n#\n# --roles-C.{header=\n#\nctags: no '}' representing the end of kind name in --roles-C.{header option: {header\nstatus: 1\n\n#\n# --roles-C.{file}=\n#\nctags: Warning: don't enable/disable a role in F/file kind; it has no role: --roles-C.{file}\nstatus: 42\n\n#\n# --roles-C.{noSuchKind}=\n#\nctags: Warning: no such kind name as specified in --roles-C.{noSuchKind} option\nstatus: 42\n\n#\n# --roles-C.{header}x=\n#\nctags: garbage after the kind specification {header} in --roles-C.{header}x option\nstatus: 1\n\n#\n# --roles-C.F=\n#\nctags: Warning: don't enable/disable a role in F/file kind; it has no role: --roles-C.F\nstatus: 42\n\n#\n# unknown kind letter x\n#\nctags: Warning: no such kind letter as specified in --roles-MyLang.X option\nstatus: 42\n\n#\n# --roles-C.fx=\n#\nctags: garbage after the kind specification 'f' in --roles-C.fx option\nstatus: 1\n\n#\n# --roles-C.?=\n#\nctags: '?', unexpected character in --roles-C.?\nstatus: 1\n\n#\n# --roles-C.h={system\n#\nctags: no '}' representing the end of role name in --roles-C.h option: system\nstatus: 1\n\n#\n# --roles-C.h=+{system\n#\nctags: no '}' representing the end of role name in --roles-C.h option: system\nstatus: 1\n\n#\n# --roles-C.h=-{system\n#\nctags: no '}' representing the end of role name in --roles-C.h option: system\nstatus: 1\n\n#\n# --roles-C.h={system}{local\n#\nctags: no '}' representing the end of role name in --roles-C.h option: local\nstatus: 1\n\n#\n# --roles-C.h=+{system}{local\n#\nctags: no '}' representing the end of role name in --roles-C.h option: local\nstatus: 1\n\n#\n# --roles-C.h=-{system}{local\n#\nctags: no '}' representing the end of role name in --roles-C.h option: local\nstatus: 1\n\n#\n# --roles-C.h={system{local}\n#\nctags: Warning: no such role: \"system{local\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h=+{system{local}\n#\nctags: Warning: no such role: \"system{local\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h=-{system{local}\n#\nctags: Warning: no such role: \"system{local\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}={system\n#\nctags: no '}' representing the end of role name in --roles-C.{header} option: system\nstatus: 1\n\n#\n# --roles-C.{header}=+{system\n#\nctags: no '}' representing the end of role name in --roles-C.{header} option: system\nstatus: 1\n\n#\n# --roles-C.{header}=-{system\n#\nctags: no '}' representing the end of role name in --roles-C.{header} option: system\nstatus: 1\n\n#\n# --roles-C.{header}={system}{local\n#\nctags: no '}' representing the end of role name in --roles-C.{header} option: local\nstatus: 1\n\n#\n# --roles-C.{header}=+{system}{local\n#\nctags: no '}' representing the end of role name in --roles-C.{header} option: local\nstatus: 1\n\n#\n# --roles-C.{header}=-{system}{local\n#\nctags: no '}' representing the end of role name in --roles-C.{header} option: local\nstatus: 1\n\n#\n# --roles-C.{header}={system{local}\n#\nctags: Warning: no such role: \"system{local\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}=+{system{local}\n#\nctags: Warning: no such role: \"system{local\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}=-{system{local}\n#\nctags: Warning: no such role: \"system{local\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h={noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h=+{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h=-{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h={system}{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h={noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h=+{system}{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h=-{system}{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h=+{system}-{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h=-{system}+{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}={noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}=+{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}=-{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}={system}{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}={noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}=+{system}{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}=-{system}{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}=+{system}-{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.{header}=-{system}+{noSuchRole}\n#\nctags: Warning: no such role: \"noSuchRole\" in kind 'h' in language \"C\"\nstatus: 42\n\n#\n# --roles-C.h=x{system}\n#\nctags: unexpected character x in --roles-C.h=x{system} option\nstatus: 1\n\n#\n# --roles-C.h=+x{system}\n#\nctags: unexpected character x in --roles-C.h=+x{system} option\nstatus: 1\n\n#\n# --roles-C.h=-x{system}\n#\nctags: unexpected character x in --roles-C.h=-x{system} option\nstatus: 1\n\n#\n# --roles-C.h=x+{system}\n#\nctags: unexpected character x in --roles-C.h=x+{system} option\nstatus: 1\n\n#\n# --roles-C.h=+x+{system}\n#\nctags: unexpected character x in --roles-C.h=+x+{system} option\nstatus: 1\n\n#\n# --roles-C.h=-x+{system}\n#\nctags: unexpected character x in --roles-C.h=-x+{system} option\nstatus: 1\n\n#\n# --roles-C.h=x-{system}\n#\nctags: unexpected character x in --roles-C.h=x-{system} option\nstatus: 1\n\n#\n# --roles-C.h=+x-{system}\n#\nctags: unexpected character x in --roles-C.h=+x-{system} option\nstatus: 1\n\n#\n# --roles-C.h=-x+-system}\n#\nctags: unexpected character x in --roles-C.h=-x+-system} option\nstatus: 1\n\n#\n# --roles-C.{header}=x{system}\n#\nctags: unexpected character x in --roles-C.{header}=x{system} option\nstatus: 1\n\n#\n# --roles-C.{header}=+x{system}\n#\nctags: unexpected character x in --roles-C.{header}=+x{system} option\nstatus: 1\n\n#\n# --roles-C.{header}=-x{system}\n#\nctags: unexpected character x in --roles-C.{header}=-x{system} option\nstatus: 1\n\n#\n# --roles-C.{header}=x+{system}\n#\nctags: unexpected character x in --roles-C.{header}=x+{system} option\nstatus: 1\n\n#\n# --roles-C.{header}=+x+{system}\n#\nctags: unexpected character x in --roles-C.{header}=+x+{system} option\nstatus: 1\n\n#\n# --roles-C.{header}=-x+{system}\n#\nctags: unexpected character x in --roles-C.{header}=-x+{system} option\nstatus: 1\n\n#\n# --roles-C.{header}=x-{system}\n#\nctags: unexpected character x in --roles-C.{header}=x-{system} option\nstatus: 1\n\n#\n# --roles-C.{header}=+x-{system}\n#\nctags: unexpected character x in --roles-C.{header}=+x-{system} option\nstatus: 1\n\n#\n# --roles-C.{header}=-x+-system}\n#\nctags: unexpected character x in --roles-C.{header}=-x+-system} option\nstatus: 1\n"
  },
  {
    "path": "Tmain/errors-in-options-roles.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/excmd-combine-backward.d/input.cpp",
    "content": "static int\nbar(void)\n{\n  const int foo = 0;\n\n  return foo;\n}\n\nint\nmain(void)\n{\n  int foo;\n  foo = bar();\n  return foo;\n}\n"
  },
  {
    "path": "Tmain/excmd-combine-backward.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n$CTAGS --quiet --options=NONE -o - -B --excmd=combine input.cpp\n"
  },
  {
    "path": "Tmain/excmd-combine-backward.d/stdout-expected.txt",
    "content": "bar\tinput.cpp\t2;?^bar(void)$?;\"\tf\ttyperef:typename:int\tfile:\nmain\tinput.cpp\t10;?^main(void)$?;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/excmd-combine.d/input.cpp",
    "content": "static int\nbar(void)\n{\n  const int foo = 0;\n\n  return foo;\n}\n\nint\nmain(void)\n{\n  int foo;\n  foo = bar();\n  return foo;\n}\n"
  },
  {
    "path": "Tmain/excmd-combine.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n$CTAGS --quiet --options=NONE -o - --excmd=combine input.cpp\n"
  },
  {
    "path": "Tmain/excmd-combine.d/stdout-expected.txt",
    "content": "bar\tinput.cpp\t2;/^bar(void)$/;\"\tf\ttyperef:typename:int\tfile:\nmain\tinput.cpp\t10;/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/extension-vs-pattern.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/extension-vs-pattern.d/input.xxx",
    "content": ""
  },
  {
    "path": "Tmain/extension-vs-pattern.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE\t\t\t\\\n\t --print-language\t\t\t\\\n\t --langdef=AAA --map-AAA='(input.xxx)'\t\\\n\t --langdef=BBB --map-BBB=.xxx      \t\\\n\t input.xxx &&\n${CTAGS} --quiet --options=NONE\t\t\t\\\n\t --print-language\t\t\t\\\n\t --langdef=AAA --map-AAA=.xxx      \t\\\n\t --langdef=BBB --map-BBB='(input.xxx)'\t\\\n\t input.xxx\n\nexit $?\n\n"
  },
  {
    "path": "Tmain/extension-vs-pattern.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/extension-vs-pattern.d/stdout-expected.txt",
    "content": "input.xxx: AAA\ninput.xxx: BBB\n"
  },
  {
    "path": "Tmain/extras-field-for-pseudo-tags.d/input.c",
    "content": "int main (void) { return 0; }\n"
  },
  {
    "path": "Tmain/extras-field-for-pseudo-tags.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nrun_ctags()\n{\n\techo '# option: ' \"$@\"\n\t${CTAGS} --quiet --options=NONE \\\n\t\t\t --fields=E --extras=p \\\n\t\t\t --pseudo-tags=-TAG_PROGRAM_VERSION \\\n\t\t\t --pseudo-tags=-TAG_PROC_CWD \\\n\t\t\t --pseudo-tags=-TAG_PARSER_VERSION \\\n\t\t\t --pseudo-tags=-TAG_OUTPUT_VERSION \\\n\t\t\t $@ \\\n\t\t\t -o - input.c\n}\n\nrun_ctags --format=1\nrun_ctags --format=2\n"
  },
  {
    "path": "Tmain/extras-field-for-pseudo-tags.d/stdout-expected.txt",
    "content": "# option:  --format=1\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_FIELD_DESCRIPTION\textras\t/Extra tag type information/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_FILE_FORMAT\t1\t/original ctags format/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_ROLE_DESCRIPTION!C!function\tforeigncall\t/called in foreign languages/\n!_TAG_ROLE_DESCRIPTION!C!function\tforeigndecl\t/declared in foreign languages/\n!_TAG_ROLE_DESCRIPTION!C!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C!header\tsystem\t/system header/\n!_TAG_ROLE_DESCRIPTION!C!macro\tundef\t/undefined/\n!_TAG_ROLE_DESCRIPTION!C!struct\tforeigndecl\t/declared in foreign languages/\nmain\tinput.c\t/^int main (void) { return 0; }$/\n# option:  --format=2\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/;\"\textras:pseudo\n!_TAG_FIELD_DESCRIPTION\textras\t/Extra tag type information/;\"\textras:pseudo\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/;\"\textras:pseudo\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/;\"\textras:pseudo\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/;\"\textras:pseudo\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/;\"\textras:pseudo\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/;\"\textras:pseudo\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/;\"\textras:pseudo\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/;\"\textras:pseudo\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/;\"\textras:pseudo\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/;\"\textras:pseudo\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/;\"\textras:pseudo\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/;\"\textras:pseudo\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/;\"\textras:pseudo\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/;\"\textras:pseudo\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/;\"\textras:pseudo\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/;\"\textras:pseudo\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/;\"\textras:pseudo\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/;\"\textras:pseudo\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/;\"\textras:pseudo\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/;\"\textras:pseudo\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//;\"\textras:pseudo\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/;\"\textras:pseudo\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/;\"\textras:pseudo\n!_TAG_ROLE_DESCRIPTION!C!function\tforeigncall\t/called in foreign languages/;\"\textras:pseudo\n!_TAG_ROLE_DESCRIPTION!C!function\tforeigndecl\t/declared in foreign languages/;\"\textras:pseudo\n!_TAG_ROLE_DESCRIPTION!C!header\tlocal\t/local header/;\"\textras:pseudo\n!_TAG_ROLE_DESCRIPTION!C!header\tsystem\t/system header/;\"\textras:pseudo\n!_TAG_ROLE_DESCRIPTION!C!macro\tundef\t/undefined/;\"\textras:pseudo\n!_TAG_ROLE_DESCRIPTION!C!struct\tforeigndecl\t/declared in foreign languages/;\"\textras:pseudo\nmain\tinput.c\t/^int main (void) { return 0; }$/\n"
  },
  {
    "path": "Tmain/extras-field.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/extras-field.d/input.cpp",
    "content": "#define Z\nnamespace X {\n  extern class Y {\n    int m;\n  } v;\n}\n#undef Z\n"
  },
  {
    "path": "Tmain/extras-field.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --kinds-C++=+x --fields=+Ere-T --extras=+qrf -o - input.cpp \\\n    | sed -e 's|[^\t]*\\(input.cpp\\)|\\1|'\n"
  },
  {
    "path": "Tmain/extras-field.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/extras-field.d/stdout-expected.txt",
    "content": "X\tinput.cpp\t/^namespace X {$/;\"\tn\tfile:\troles:def\textras:fileScope\tend:6\nX::Y\tinput.cpp\t/^  extern class Y {$/;\"\tc\tnamespace:X\tfile:\troles:def\textras:fileScope,qualified\tend:5\nX::Y::m\tinput.cpp\t/^    int m;$/;\"\tm\tclass:X::Y\ttyperef:typename:int\tfile:\troles:def\textras:fileScope,qualified\tend:4\nX::v\tinput.cpp\t/^  } v;$/;\"\tx\tnamespace:X\ttyperef:class:X::Y\troles:def\textras:qualified\tend:5\nY\tinput.cpp\t/^  extern class Y {$/;\"\tc\tnamespace:X\tfile:\troles:def\textras:fileScope\tend:5\nZ\tinput.cpp\t/^#define Z$/;\"\td\tfile:\troles:def\textras:fileScope\tend:1\nZ\tinput.cpp\t/^#undef Z$/;\"\td\tfile:\troles:undef\textras:fileScope,reference\ninput.cpp\tinput.cpp\t1;\"\tF\troles:def\textras:inputFile\tend:7\nm\tinput.cpp\t/^    int m;$/;\"\tm\tclass:X::Y\ttyperef:typename:int\tfile:\troles:def\textras:fileScope\tend:4\nv\tinput.cpp\t/^  } v;$/;\"\tx\tnamespace:X\ttyperef:class:X::Y\troles:def\tend:5\n"
  },
  {
    "path": "Tmain/extras-long.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nno_yaml()\n{\n\tgrep -v I18nRubyGem\n}\n\necho '# resetting'\n${CTAGS} --quiet --options=NONE --with-list-header=no \\\n\t --extras='{subparser}' --list-extras | no_yaml\n\necho '# enabling 1'\n${CTAGS} --quiet --options=NONE --with-list-header=no \\\n\t --extras=+'{pseudo}' --list-extras | no_yaml\n\necho '# disabling 1'\n${CTAGS} --quiet --options=NONE --with-list-header=no \\\n\t --extras=-'{fileScope}' --list-extras | no_yaml\n\necho '# combination'\n${CTAGS} --quiet --options=NONE --with-list-header=no \\\n\t --extras=-'{fileScope}+{inputFile}{reference}' --list-extras | no_yaml\n\necho '# combination with letters'\n${CTAGS} --quiet --options=NONE --with-list-header=no \\\n\t --extras=-'{fileScope}+p{inputFile}q{reference}-f' --list-extras | no_yaml\n"
  },
  {
    "path": "Tmain/extras-long.d/stdout-expected.txt",
    "content": "# resetting\n-       anonymous           no      NONE        no      0 Include tags for non-named objects like lambda\nF       fileScope           no      NONE        no      0 Include tags of file scope\nf       inputFile           no      NONE        no      0 Include an entry for the base file name of every input file\ng       guest               no      NONE        no      0 Include tags generated by guest parsers\np       pseudo              no      NONE        no      0 Include pseudo tags\nq       qualified           no      NONE        no      0 Include an extra class-qualified tag entry for each tag\nr       reference           no      NONE        no      0 Include reference tags\ns       subparser           yes     NONE        no      0 Include tags generated by subparsers\nz       nulltag             no      NONE        no      1 Include tags with empty strings as their names\n-       canonicalizedName   yes     Automake    no      1 Include canonicalized object name like libctags_a\n-       linkName            no      Fortran     no      1 Linking name used in foreign languages\n-       implicitClass       no      GDScript    no      0 Include tag for the implicitly defined unnamed class\n-       doubleSharps        no      IPythonCell no      0 Include cells starting from ##\n-       configPrefixed      yes     Kconfig     no      0 prepend CONFIG_ to config names\n-       CppDef              no      Make        no      1 Include FOO in -DFOO as as a name of CPreProcessor macro\n-       implicitImportName  yes     Odin        no      0 implicitly defined import name like \"filepath\" in \"core:path/filepath\"\n-       guessedFromFileName yes     PkgConfig   no      0 the guessed package name of the .pc file\n-       arityAppended       yes     Prolog      no      0 Include predicates with their arities\n-       funcmap             yes     QemuHX      no      0 Include mapping SQMP to C function name\n-       whitespaceSwapped   yes     Robot       no      0 Include tags swapping whitespace and underscore chars\n# enabling 1\n-       anonymous           yes     NONE        no      0 Include tags for non-named objects like lambda\nF       fileScope           yes     NONE        no      0 Include tags of file scope\nf       inputFile           no      NONE        no      0 Include an entry for the base file name of every input file\ng       guest               no      NONE        no      0 Include tags generated by guest parsers\np       pseudo              yes     NONE        no      0 Include pseudo tags\nq       qualified           no      NONE        no      0 Include an extra class-qualified tag entry for each tag\nr       reference           no      NONE        no      0 Include reference tags\ns       subparser           yes     NONE        no      0 Include tags generated by subparsers\nz       nulltag             no      NONE        no      1 Include tags with empty strings as their names\n-       canonicalizedName   yes     Automake    no      1 Include canonicalized object name like libctags_a\n-       linkName            no      Fortran     no      1 Linking name used in foreign languages\n-       implicitClass       no      GDScript    no      0 Include tag for the implicitly defined unnamed class\n-       doubleSharps        no      IPythonCell no      0 Include cells starting from ##\n-       configPrefixed      yes     Kconfig     no      0 prepend CONFIG_ to config names\n-       CppDef              no      Make        no      1 Include FOO in -DFOO as as a name of CPreProcessor macro\n-       implicitImportName  yes     Odin        no      0 implicitly defined import name like \"filepath\" in \"core:path/filepath\"\n-       guessedFromFileName yes     PkgConfig   no      0 the guessed package name of the .pc file\n-       arityAppended       yes     Prolog      no      0 Include predicates with their arities\n-       funcmap             yes     QemuHX      no      0 Include mapping SQMP to C function name\n-       whitespaceSwapped   yes     Robot       no      0 Include tags swapping whitespace and underscore chars\n# disabling 1\n-       anonymous           yes     NONE        no      0 Include tags for non-named objects like lambda\nF       fileScope           no      NONE        no      0 Include tags of file scope\nf       inputFile           no      NONE        no      0 Include an entry for the base file name of every input file\ng       guest               no      NONE        no      0 Include tags generated by guest parsers\np       pseudo              yes     NONE        no      0 Include pseudo tags\nq       qualified           no      NONE        no      0 Include an extra class-qualified tag entry for each tag\nr       reference           no      NONE        no      0 Include reference tags\ns       subparser           yes     NONE        no      0 Include tags generated by subparsers\nz       nulltag             no      NONE        no      1 Include tags with empty strings as their names\n-       canonicalizedName   yes     Automake    no      1 Include canonicalized object name like libctags_a\n-       linkName            no      Fortran     no      1 Linking name used in foreign languages\n-       implicitClass       no      GDScript    no      0 Include tag for the implicitly defined unnamed class\n-       doubleSharps        no      IPythonCell no      0 Include cells starting from ##\n-       configPrefixed      yes     Kconfig     no      0 prepend CONFIG_ to config names\n-       CppDef              no      Make        no      1 Include FOO in -DFOO as as a name of CPreProcessor macro\n-       implicitImportName  yes     Odin        no      0 implicitly defined import name like \"filepath\" in \"core:path/filepath\"\n-       guessedFromFileName yes     PkgConfig   no      0 the guessed package name of the .pc file\n-       arityAppended       yes     Prolog      no      0 Include predicates with their arities\n-       funcmap             yes     QemuHX      no      0 Include mapping SQMP to C function name\n-       whitespaceSwapped   yes     Robot       no      0 Include tags swapping whitespace and underscore chars\n# combination\n-       anonymous           yes     NONE        no      0 Include tags for non-named objects like lambda\nF       fileScope           no      NONE        no      0 Include tags of file scope\nf       inputFile           yes     NONE        no      0 Include an entry for the base file name of every input file\ng       guest               no      NONE        no      0 Include tags generated by guest parsers\np       pseudo              yes     NONE        no      0 Include pseudo tags\nq       qualified           no      NONE        no      0 Include an extra class-qualified tag entry for each tag\nr       reference           yes     NONE        no      0 Include reference tags\ns       subparser           yes     NONE        no      0 Include tags generated by subparsers\nz       nulltag             no      NONE        no      1 Include tags with empty strings as their names\n-       canonicalizedName   yes     Automake    no      1 Include canonicalized object name like libctags_a\n-       linkName            no      Fortran     no      1 Linking name used in foreign languages\n-       implicitClass       no      GDScript    no      0 Include tag for the implicitly defined unnamed class\n-       doubleSharps        no      IPythonCell no      0 Include cells starting from ##\n-       configPrefixed      yes     Kconfig     no      0 prepend CONFIG_ to config names\n-       CppDef              no      Make        no      1 Include FOO in -DFOO as as a name of CPreProcessor macro\n-       implicitImportName  yes     Odin        no      0 implicitly defined import name like \"filepath\" in \"core:path/filepath\"\n-       guessedFromFileName yes     PkgConfig   no      0 the guessed package name of the .pc file\n-       arityAppended       yes     Prolog      no      0 Include predicates with their arities\n-       funcmap             yes     QemuHX      no      0 Include mapping SQMP to C function name\n-       whitespaceSwapped   yes     Robot       no      0 Include tags swapping whitespace and underscore chars\n# combination with letters\n-       anonymous           yes     NONE        no      0 Include tags for non-named objects like lambda\nF       fileScope           no      NONE        no      0 Include tags of file scope\nf       inputFile           no      NONE        no      0 Include an entry for the base file name of every input file\ng       guest               no      NONE        no      0 Include tags generated by guest parsers\np       pseudo              yes     NONE        no      0 Include pseudo tags\nq       qualified           yes     NONE        no      0 Include an extra class-qualified tag entry for each tag\nr       reference           yes     NONE        no      0 Include reference tags\ns       subparser           yes     NONE        no      0 Include tags generated by subparsers\nz       nulltag             no      NONE        no      1 Include tags with empty strings as their names\n-       canonicalizedName   yes     Automake    no      1 Include canonicalized object name like libctags_a\n-       linkName            no      Fortran     no      1 Linking name used in foreign languages\n-       implicitClass       no      GDScript    no      0 Include tag for the implicitly defined unnamed class\n-       doubleSharps        no      IPythonCell no      0 Include cells starting from ##\n-       configPrefixed      yes     Kconfig     no      0 prepend CONFIG_ to config names\n-       CppDef              no      Make        no      1 Include FOO in -DFOO as as a name of CPreProcessor macro\n-       implicitImportName  yes     Odin        no      0 implicitly defined import name like \"filepath\" in \"core:path/filepath\"\n-       guessedFromFileName yes     PkgConfig   no      0 the guessed package name of the .pc file\n-       arityAppended       yes     Prolog      no      0 Include predicates with their arities\n-       funcmap             yes     QemuHX      no      0 Include mapping SQMP to C function name\n-       whitespaceSwapped   yes     Robot       no      0 Include tags swapping whitespace and underscore chars\n"
  },
  {
    "path": "Tmain/filter-option-write-to-file.d/input.c",
    "content": "int main(void) { return 0; }\n"
  },
  {
    "path": "Tmain/filter-option-write-to-file.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=/tmp/ctags-tmain-$$.txt\n\necho ./input.c | $CTAGS --quiet --options=NONE --filter -o $O\n\nrm -f ${O}\n"
  },
  {
    "path": "Tmain/filter-option-write-to-file.d/stderr-expected.txt",
    "content": "ctags: Warning: filter mode ignores output tag file name\n"
  },
  {
    "path": "Tmain/filter-option-write-to-file.d/stdout-expected.txt",
    "content": "main\t./input.c\t/^int main(void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/filter-option.d/input.c",
    "content": "int main(void) { return 0; }\n"
  },
  {
    "path": "Tmain/filter-option.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho ./input.c | $CTAGS --quiet --options=NONE --filter\necho ./input.c | $CTAGS --quiet --options=NONE --filter --output-format=xref\n"
  },
  {
    "path": "Tmain/filter-option.d/stdout-expected.txt",
    "content": "main\t./input.c\t/^int main(void) { return 0; }$/;\"\tf\ttyperef:typename:int\nmain             function      1 ./input.c        int main(void) { return 0; }\n"
  },
  {
    "path": "Tmain/fixed-field-handling-in-json-format.d/input.c",
    "content": "void main(void) {}\n"
  },
  {
    "path": "Tmain/fixed-field-handling-in-json-format.d/run.sh",
    "content": "# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=\"$1\"\n\nis_feature_available \"${CTAGS}\" json\n\nCTAGS=\"${CTAGS} --quiet --options=NONE\"\n\necho '# --output-format=json --fields=+n-P'\n${CTAGS} --output-format=json --fields=+n-P -o - input.c\n\necho '# --fields=+n-P --output-format=json'\n${CTAGS} --fields=+n-P --output-format=json -o - input.c\n"
  },
  {
    "path": "Tmain/fixed-field-handling-in-json-format.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/fixed-field-handling-in-json-format.d/stdout-expected.txt",
    "content": "# --output-format=json --fields=+n-P\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.c\", \"line\": 1, \"typeref\": \"typename:void\", \"kind\": \"function\"}\n# --fields=+n-P --output-format=json\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.c\", \"line\": 1, \"typeref\": \"typename:void\", \"kind\": \"function\"}\n"
  },
  {
    "path": "Tmain/fixed-field-handling.d/input.c",
    "content": "void main(void) {}\n"
  },
  {
    "path": "Tmain/fixed-field-handling.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=\"$1\"\n\nis_feature_available \"${CTAGS}\" json\n\nCTAGS=\"${CTAGS} --quiet --options=NONE\"\n\necho '# writer=default'\n${CTAGS} --machinable --list-fields | grep '^[NFP]'\n\nlist_fields()\n{\n\tlocal f=$1\n\tshift\n\n\techo \"# writer=$f $o\"\n\t${CTAGS} --output-format=$f --machinable $@ --list-fields | grep '^[NFP]'\n}\n\nfor f in u-ctags e-ctags etags xref json; do\n\tlist_fields $f\ndone\n\nfor f in xref json; do\n\tfor o in N F P; do\n\t\tlist_fields $f --fields=-$o\n\tdone\ndone\n\nfor o in N F P; do\n\tO=\"--fields=-$o\"\n\techo \"# writer=json $O\"\n\t${CTAGS} --output-format=json $O input.c\n\tO=\"--fields=$o\"\n\techo \"# writer=json $O\"\n\t${CTAGS} --output-format=json $O input.c\ndone\n\nO=\"--fields=\"\necho \"# writer=json $O\"\n${CTAGS} --output-format=json $O input.c\n"
  },
  {
    "path": "Tmain/fixed-field-handling.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/fixed-field-handling.d/stdout-expected.txt",
    "content": "# writer=default\nN\tname\tyes\tNONE\ts--\tyes\trw\t0\ttag name\nF\tinput\tyes\tNONE\ts--\tyes\tr-\t0\tinput file\nP\tpattern\tyes\tNONE\ts-b\tyes\t--\t0\tpattern\n# writer=u-ctags \nN\tname\tyes\tNONE\ts--\tyes\trw\t0\ttag name\nF\tinput\tyes\tNONE\ts--\tyes\tr-\t0\tinput file\nP\tpattern\tyes\tNONE\ts-b\tyes\t--\t0\tpattern\n# writer=e-ctags \nN\tname\tyes\tNONE\ts--\tyes\trw\t0\ttag name\nF\tinput\tyes\tNONE\ts--\tyes\tr-\t0\tinput file\nP\tpattern\tyes\tNONE\ts-b\tyes\t--\t0\tpattern\n# writer=etags \nF\tinput\tyes\tNONE\ts--\tno\tr-\t0\tinput file\nN\tname\tyes\tNONE\ts--\tno\trw\t0\ttag name\nP\tpattern\tyes\tNONE\ts-b\tno\t--\t0\tpattern\n# writer=xref \nF\tinput\tyes\tNONE\ts--\tno\tr-\t0\tinput file\nN\tname\tyes\tNONE\ts--\tno\trw\t0\ttag name\nP\tpattern\tyes\tNONE\ts-b\tno\t--\t0\tpattern\n# writer=json \nF\tinput\tyes\tNONE\ts--\tno\tr-\t0\tinput file\nN\tname\tyes\tNONE\ts--\tno\trw\t0\ttag name\nP\tpattern\tyes\tNONE\ts-b\tno\t--\t0\tpattern\n# writer=xref N\nF\tinput\tyes\tNONE\ts--\tno\tr-\t0\tinput file\nN\tname\tno\tNONE\ts--\tno\trw\t0\ttag name\nP\tpattern\tyes\tNONE\ts-b\tno\t--\t0\tpattern\n# writer=xref F\nF\tinput\tno\tNONE\ts--\tno\tr-\t0\tinput file\nN\tname\tyes\tNONE\ts--\tno\trw\t0\ttag name\nP\tpattern\tyes\tNONE\ts-b\tno\t--\t0\tpattern\n# writer=xref P\nF\tinput\tyes\tNONE\ts--\tno\tr-\t0\tinput file\nN\tname\tyes\tNONE\ts--\tno\trw\t0\ttag name\nP\tpattern\tno\tNONE\ts-b\tno\t--\t0\tpattern\n# writer=json N\nF\tinput\tyes\tNONE\ts--\tno\tr-\t0\tinput file\nN\tname\tno\tNONE\ts--\tno\trw\t0\ttag name\nP\tpattern\tyes\tNONE\ts-b\tno\t--\t0\tpattern\n# writer=json F\nF\tinput\tno\tNONE\ts--\tno\tr-\t0\tinput file\nN\tname\tyes\tNONE\ts--\tno\trw\t0\ttag name\nP\tpattern\tyes\tNONE\ts-b\tno\t--\t0\tpattern\n# writer=json P\nF\tinput\tyes\tNONE\ts--\tno\tr-\t0\tinput file\nN\tname\tyes\tNONE\ts--\tno\trw\t0\ttag name\nP\tpattern\tno\tNONE\ts-b\tno\t--\t0\tpattern\n# writer=json --fields=-N\n{\"_type\": \"tag\", \"path\": \"input.c\", \"pattern\": \"/^void main(void) {}$/\", \"typeref\": \"typename:void\", \"kind\": \"function\"}\n# writer=json --fields=N\n{\"_type\": \"tag\", \"name\": \"main\"}\n# writer=json --fields=-F\n{\"_type\": \"tag\", \"name\": \"main\", \"pattern\": \"/^void main(void) {}$/\", \"typeref\": \"typename:void\", \"kind\": \"function\"}\n# writer=json --fields=F\n{\"_type\": \"tag\", \"path\": \"input.c\"}\n# writer=json --fields=-P\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.c\", \"typeref\": \"typename:void\", \"kind\": \"function\"}\n# writer=json --fields=P\n{\"_type\": \"tag\", \"pattern\": \"/^void main(void) {}$/\"}\n# writer=json --fields=\n"
  },
  {
    "path": "Tmain/flags-fielddef-datatype.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/flags-fielddef-datatype.d/run.sh",
    "content": "# Copyright: 2023 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --langdef=FIELDTEST \\\n\t\t --_fielddef-FIELDTEST=strfield,\"a field having string value\"'{datatype=str}' \\\n\t\t --_fielddef-FIELDTEST=boolfield,\"a field having boolean value\"'{datatype=bool}' \\\n\t\t --_fielddef-FIELDTEST=intfield,\"a field having integer value\"'{datatype=int}' \\\n\t\t --_fielddef-FIELDTEST=strboolfield,\"a field having string value or false\"'{datatype=str+bool}' \\\n\t\t --_fielddef-FIELDTEST=deffield,\"a field that type is not specified\" \\\n\t\t --list-fields=FIELDTEST && \\\n! ${CTAGS} --quiet --options=NONE --langdef=FIELDTEST \\\n  --_fielddef-FIELDTEST=fooA,\"unexpected data type\"'{datatype=bar}' &&\n! ${CTAGS} --quiet --options=NONE --langdef=FIELDTEST \\\n  --_fielddef-FIELDTEST=fooB,\"unexpected data type\"'{datatype=int+baz}' &&\n! ${CTAGS} --quiet --options=NONE --langdef=FIELDTEST \\\n  --_fielddef-FIELDTEST=fooC,\"unexpected data type\"'{datatype=}' &&\n! ${CTAGS} --quiet --options=NONE --langdef=FIELDTEST \\\n  --_fielddef-FIELDTEST=fooD,\"unexpected data type\"'{datatype=+baz}' &&\n! ${CTAGS} --quiet --options=NONE --langdef=FIELDTEST \\\n  --_fielddef-FIELDTEST=fooE,\"unexpected data type\"'{datatype=bool+str}'\n"
  },
  {
    "path": "Tmain/flags-fielddef-datatype.d/stderr-expected.txt",
    "content": "ctags: unknown datatype for field \"fooA\": \"bar\"\nctags: unknown datatype for field \"fooB\": \"int+baz\"\nctags: no datatype given for field: \"fooC\"\nctags: unknown datatype for field \"fooD\": \"+baz\"\nctags: unknown datatype for field \"fooE\": \"bool+str\"\n"
  },
  {
    "path": "Tmain/flags-fielddef-datatype.d/stdout-expected.txt",
    "content": "#LETTER NAME         ENABLED LANGUAGE  JSTYPE FIXED OP VER DESCRIPTION\n-       boolfield    no      FIELDTEST --b    no    rw   0 a field having boolean value\n-       deffield     no      FIELDTEST s--    no    --   0 a field that type is not specified\n-       intfield     no      FIELDTEST -i-    no    rw   0 a field having integer value\n-       strboolfield no      FIELDTEST s-b    no    rw   0 a field having string value or false\n-       strfield     no      FIELDTEST s--    no    rw   0 a field having string value\n"
  },
  {
    "path": "Tmain/force-initializing-option.d/README",
    "content": "This test case expects the exit status will be 0 if an erorr doesn't\noccur during initializing a parser.\n"
  },
  {
    "path": "Tmain/force-initializing-option.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --_fatal-warnings --_force-initializing --_force-quit=0\n\nexit $?\n"
  },
  {
    "path": "Tmain/force-initializing-option.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/force-initializing-option.d/xit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/gcov-sandbox.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/gcov-sandbox.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\nis_feature_available $CTAGS sandbox\nis_feature_available ${CTAGS} interactive\nis_feature_available ${CTAGS} gcov\n\n{\n    echo '{\"command\":\"generate-tags\", \"filename\":\"input.c\", \"size\": 28}'\n    echo 'int main(void) { return 0; }'\n} | $CTAGS --quiet --options=NONE  --_interactive=sandbox\n\nexit $?\n"
  },
  {
    "path": "Tmain/gcov-sandbox.d/stderr-expected.txt",
    "content": "ctags: sandbox submode does not work if gcov is instrumented\n"
  },
  {
    "path": "Tmain/gcov-sandbox.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/generate-anon-ids.d/input0.c",
    "content": "struct {\n\tint x;\n} X;\n\nstruct {\n\tint y;\n} Y;\n"
  },
  {
    "path": "Tmain/generate-anon-ids.d/input1.c",
    "content": "struct {\n\tint a;\n} A;\n\nstruct {\n\tint b;\n} B;\n"
  },
  {
    "path": "Tmain/generate-anon-ids.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE -o - input0.c input1.c\n"
  },
  {
    "path": "Tmain/generate-anon-ids.d/stdout-expected.txt",
    "content": "A\tinput1.c\t/^} A;$/;\"\tv\ttyperef:struct:__anon840121570108\nB\tinput1.c\t/^} B;$/;\"\tv\ttyperef:struct:__anon840121570208\nX\tinput0.c\t/^} X;$/;\"\tv\ttyperef:struct:__anon84011d160108\nY\tinput0.c\t/^} Y;$/;\"\tv\ttyperef:struct:__anon84011d160208\n__anon84011d160108\tinput0.c\t/^struct {$/;\"\ts\tfile:\n__anon84011d160208\tinput0.c\t/^struct {$/;\"\ts\tfile:\n__anon840121570108\tinput1.c\t/^struct {$/;\"\ts\tfile:\n__anon840121570208\tinput1.c\t/^struct {$/;\"\ts\tfile:\na\tinput1.c\t/^\tint a;$/;\"\tm\tstruct:__anon840121570108\ttyperef:typename:int\tfile:\nb\tinput1.c\t/^\tint b;$/;\"\tm\tstruct:__anon840121570208\ttyperef:typename:int\tfile:\nx\tinput0.c\t/^\tint x;$/;\"\tm\tstruct:__anon84011d160108\ttyperef:typename:int\tfile:\ny\tinput0.c\t/^\tint y;$/;\"\tm\tstruct:__anon84011d160208\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Tmain/getter-extras-field.d/input.unknown",
    "content": "e\n"
  },
  {
    "path": "Tmain/getter-extras-field.d/run.sh",
    "content": "# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE -o - --options=x.ctags input.unknown\n"
  },
  {
    "path": "Tmain/getter-extras-field.d/stderr-expected.txt",
    "content": "true\n[/reference]\ntrue\n[/qualified /reference]\ntrue\n[/X.foo]\ntrue\n[/reference /X.foo]\n"
  },
  {
    "path": "Tmain/getter-extras-field.d/stdout-expected.txt",
    "content": "eCommon\tinput.unknown\t/^e$/;\"\td\textras:reference\na.b.eCommon2\tinput.unknown\t/^e$/;\"\td\textras:qualified,reference\neLangspec\tinput.unknown\t/^e$/;\"\td\textras:foo\neLangspec+Common\tinput.unknown\t/^e$/;\"\td\textras:reference,foo\n"
  },
  {
    "path": "Tmain/getter-extras-field.d/x.ctags",
    "content": "--sort=no\n--fields=+{extras}\n\n--langdef=X\n--map-X=.unknown\n--_tabledef-X=main\n\n--kinddef-X=d,def,definitions\n\n--_extradef-X=foo,...\n--extras-X=+{foo}\n--_extradef-X=bar,...\n--extras-X=-{bar}\n\n--_prelude-X={{\n\t/maketag0 {\n\t\t/def 1 /start _matchloc _tag _commit\n\t} def\n\t/maketag {\n\t\tmaketag0 pop\n\t} def\n\t/pc {pstack clear} def\n}}\n\n--_mtable-regex-X=main/(e)//{{\n\t(eCommon)   maketag0 dup /reference _markextra :extras pc\n\t(a.b.eCommon2)  maketag0 dup dup /reference _markextra /qualified _markextra :extras pc\n\t(eLangspec) maketag0 dup /X.foo _markextra :extras pc\n\t(eLangspec+Common) maketag0 dup dup /X.foo _markextra /reference _markextra :extras pc\n}}\n"
  },
  {
    "path": "Tmain/input-encoding-option.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/input-encoding-option.d/input.java",
    "content": "class Foo { // FooNX\n\tpublic Foo() { // RXgN^\n\t}\n}\n"
  },
  {
    "path": "Tmain/input-encoding-option.d/input.js",
    "content": "var a = 1; // ѿ\n"
  },
  {
    "path": "Tmain/input-encoding-option.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2015 Yasuhiro MATSUMOTO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\n\n. ../utils.sh\n\nif ${CTAGS} --quiet --options=NONE --list-features | grep -q iconv; then\n  check_encoding shift_jis\n  check_encoding euc-jp\n  check_encoding utf-8\n  if ${CTAGS} --quiet --options=NONE \\\n\t\t\t  --pseudo-tags=-TAG_PROC_CWD \\\n\t\t\t  --pseudo-tags=-TAG_PROGRAM_VERSION \\\n\t      --pseudo-tags=-TAG_KIND_DESCRIPTION \\\n\t      --pseudo-tags=-TAG_EXTRA_DESCRIPTION \\\n\t      --pseudo-tags=-TAG_FIELD_DESCRIPTION \\\n\t      --pseudo-tags=-TAG_ROLE_DESCRIPTION \\\n\t      --pseudo-tags=-TAG_PARSER_VERSION \\\n\t      --pseudo-tags=-TAG_OUTPUT_VERSION \\\n\t      --input-encoding=utf-8 --input-encoding-java=shift_jis --input-encoding-javascript=euc-jp \\\n\t      -o ${BUILDDIR}/tags \\\n\t      input.js input.java ; then\n      remove_commit_id ${BUILDDIR}/tags\n  fi\n  exit $?\nelse\n  skip \"iconv feature is not available\"\nfi\n"
  },
  {
    "path": "Tmain/input-encoding-option.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/input-encoding-option.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/input-encoding-option.d/tags-expected.txt",
    "content": "!_TAG_FILE_ENCODING\tUTF-8\t//\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\nFoo\tinput.java\t/^\tpublic Foo() { \\/\\/ コンストラクタ$/;\"\tm\tclass:Foo\nFoo\tinput.java\t/^class Foo { \\/\\/ Fooクラス$/;\"\tc\na\tinput.js\t/^var a = 1; \\/\\/ 変数初期化$/;\"\tv\n"
  },
  {
    "path": "Tmain/interactive-mode.d/run.sh",
    "content": "# Copyright: 2016 Aman Gupta\n# License: GPL-2\n\nCTAGS=$1\n. ../utils.sh\n\nis_feature_available ${CTAGS} interactive\n\n# It seems that the output format is slightly different between libjansson versions\ns()\n{\n\tsed -e s/':\"'/': \"'/g | jdropver\n}\n\ntrim_errno()\n{\n\t# The value errno depends on the platform.\n\tsed -e s/' \"errno\": [0-9]*,'//\n}\n\nCTAGS=\"$CTAGS --options=NONE\"\n\necho identification message on startup\necho =======================================\n${CTAGS} --_interactive < /dev/null |s\n\necho\necho error on invalid command\necho =======================================\necho '{\"command\":\"foobar\"}' | ${CTAGS} --_interactive |s\n\necho\necho error on missing arguments\necho =======================================\necho '{\"command\":\"generate-tags\"}' | ${CTAGS} --_interactive |s\n\necho\necho error on invalid file\necho =======================================\necho '{\"command\":\"generate-tags\", \"filename\":\"test.foo\"}' | ${CTAGS} --_interactive |s |trim_errno\n\necho\necho generate tags from file\necho =======================================\necho '{\"command\":\"generate-tags\", \"filename\":\"test.rb\"}' | ${CTAGS} --_interactive |s\n\necho\necho process multiple commands\necho =======================================\n(\n  echo '{\"command\":\"generate-tags\", \"filename\":\"test.rb\"}'\n  echo '{\"command\":\"generate-tags\", \"filename\":\"test.c\"}'\n) | ${CTAGS} --_interactive |s\n\necho\necho generate tags from data\necho =======================================\nsize=$(filesize test.rb)\n(\n  echo '{\"command\":\"generate-tags\", \"filename\":\"foobar.rb\", \"size\":'$size'}'\n  cat test.rb\n) | ${CTAGS} --_interactive |s\n"
  },
  {
    "path": "Tmain/interactive-mode.d/stdout-expected.txt",
    "content": "identification message on startup\n=======================================\n{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n\nerror on invalid command\n=======================================\n{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"error\", \"message\": \"unknown command name\", \"fatal\": true}\n\nerror on missing arguments\n=======================================\n{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"error\", \"message\": \"invalid generate-tags request\", \"fatal\": true}\n\nerror on invalid file\n=======================================\n{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"error\", \"message\": \"cannot open input file \\\"test.foo\\\"\", \"warning\": true, \"perror\": \"No such file or directory\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n\ngenerate tags from file\n=======================================\n{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"tag\", \"name\": \"Test\", \"path\": \"test.rb\", \"pattern\": \"/^class Test$/\", \"kind\": \"class\"}\n{\"_type\": \"tag\", \"name\": \"foobar\", \"path\": \"test.rb\", \"pattern\": \"/^  def foobar$/\", \"kind\": \"method\", \"scope\": \"Test\", \"scopeKind\": \"class\"}\n{\"_type\": \"tag\", \"name\": \"baz\", \"path\": \"test.rb\", \"pattern\": \"/^  def baz(a=1)$/\", \"kind\": \"method\", \"scope\": \"Test\", \"scopeKind\": \"class\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n\nprocess multiple commands\n=======================================\n{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"tag\", \"name\": \"Test\", \"path\": \"test.rb\", \"pattern\": \"/^class Test$/\", \"kind\": \"class\"}\n{\"_type\": \"tag\", \"name\": \"foobar\", \"path\": \"test.rb\", \"pattern\": \"/^  def foobar$/\", \"kind\": \"method\", \"scope\": \"Test\", \"scopeKind\": \"class\"}\n{\"_type\": \"tag\", \"name\": \"baz\", \"path\": \"test.rb\", \"pattern\": \"/^  def baz(a=1)$/\", \"kind\": \"method\", \"scope\": \"Test\", \"scopeKind\": \"class\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n{\"_type\": \"tag\", \"name\": \"say_hello\", \"path\": \"test.c\", \"pattern\": \"/^void say_hello() {$/\", \"typeref\": \"typename:void\", \"kind\": \"function\"}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"test.c\", \"pattern\": \"/^int main(int argc, char **argv) {$/\", \"typeref\": \"typename:int\", \"kind\": \"function\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n\ngenerate tags from data\n=======================================\n{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"tag\", \"name\": \"Test\", \"path\": \"foobar.rb\", \"pattern\": \"/^class Test$/\", \"kind\": \"class\"}\n{\"_type\": \"tag\", \"name\": \"foobar\", \"path\": \"foobar.rb\", \"pattern\": \"/^  def foobar$/\", \"kind\": \"method\", \"scope\": \"Test\", \"scopeKind\": \"class\"}\n{\"_type\": \"tag\", \"name\": \"baz\", \"path\": \"foobar.rb\", \"pattern\": \"/^  def baz(a=1)$/\", \"kind\": \"method\", \"scope\": \"Test\", \"scopeKind\": \"class\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n"
  },
  {
    "path": "Tmain/interactive-mode.d/test.c",
    "content": "#include <stdio.h>\n\nvoid say_hello() {\n  printf(\"hello world\\n\");\n}\n\nint main(int argc, char **argv) {\n  say_hello();\n}\n"
  },
  {
    "path": "Tmain/interactive-mode.d/test.rb",
    "content": "class Test\n  def foobar\n  end\n\n  def baz(a=1)\n  end\nend\n"
  },
  {
    "path": "Tmain/interactive-notice-output.d/input.cst",
    "content": "n\n"
  },
  {
    "path": "Tmain/interactive-notice-output.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\n# It seems that the output format is slightly different between libjansson versions\ns()\n{\n\tsed -e s/':\"'/': \"'/g | jdropver\n}\n\nif is_feature_available ${CTAGS} json; then\n\techo '{\"command\":\"generate-tags\", \"filename\":\"input.cst\"}' | $CTAGS --options=NONE --pseudo-tags=-TAG_PROGRAM_VERSION \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t--map-CTagsSelfTest=.cst --_interactive |s\n\techo '{\"command\":\"generate-tags\", \"filename\":\"input.cst\"}' | $CTAGS --quiet --options=NONE --pseudo-tags=-TAG_PROGRAM_VERSION \\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t--map-CTagsSelfTest=.cst --_interactive |s\nfi\n"
  },
  {
    "path": "Tmain/interactive-notice-output.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\n"
  },
  {
    "path": "Tmain/interactive-notice-output.d/stdout-expected.txt",
    "content": "{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"error\", \"message\": \"notice output for testing: triggerNotice\", \"notice\": true}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n"
  },
  {
    "path": "Tmain/interactive-option-write-to-file.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2017 Masatake YAMATO\n# Copyright: 2016 Aman Gupta\n# License: GPL-2\n\nCTAGS=$1\n. ../utils.sh\n\nis_feature_available ${CTAGS} interactive\n\n# It seems that the output format is slightly different between libjansson versions\ns()\n{\n\tsed -e s/':\"'/': \"'/g | jdropver\n}\n\nO=/tmp/ctags-tmain-$$.txt\n\necho '{\"command\":\"generate-tags\", \"filename\":\"test.rb\"}' | ${CTAGS} --quiet --options=NONE --_interactive -o ${O} |s\n\nrm -f ${O}\n"
  },
  {
    "path": "Tmain/interactive-option-write-to-file.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/interactive-option-write-to-file.d/stdout-expected.txt",
    "content": "{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"tag\", \"name\": \"Test\", \"path\": \"test.rb\", \"pattern\": \"/^class Test$/\", \"kind\": \"class\"}\n{\"_type\": \"tag\", \"name\": \"foobar\", \"path\": \"test.rb\", \"pattern\": \"/^  def foobar$/\", \"kind\": \"method\", \"scope\": \"Test\", \"scopeKind\": \"class\"}\n{\"_type\": \"tag\", \"name\": \"baz\", \"path\": \"test.rb\", \"pattern\": \"/^  def baz(a=1)$/\", \"kind\": \"method\", \"scope\": \"Test\", \"scopeKind\": \"class\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n"
  },
  {
    "path": "Tmain/interactive-option-write-to-file.d/test.rb",
    "content": "class Test\n  def foobar\n  end\n\n  def baz(a=1)\n  end\nend\n"
  },
  {
    "path": "Tmain/interactive-resource-management.d/input.c",
    "content": "int\nmain(void)\n{\n}\n"
  },
  {
    "path": "Tmain/interactive-resource-management.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\n\n. ../utils.sh\n\nif is_feature_available ${CTAGS} json; then\n\texit_status_for_input_c $CTAGS NONE                --output-format=json -o -                   --sort=no\n\texit_status_for_input_c $CTAGS $BUILDDIR/tags.json --output-format=json -o $BUILDDIR/tags.json --sort=no\n\texit_status_for_input_c $CTAGS $BUILDDIR/tags.json --output-format=json -o $BUILDDIR/tags.json\n\texit_status_for_input_c $CTAGS NONE                --output-format=json -o -\nfi\n"
  },
  {
    "path": "Tmain/interactive-resource-management.d/stdout-expected.txt",
    "content": "--output-format=json -o - --sort=no => ok\n--output-format=json -o tags.json --sort=no => ok\n--output-format=json -o tags.json => ok\n--output-format=json -o - => ok\n"
  },
  {
    "path": "Tmain/invalid-encoding-option.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/invalid-encoding-option.d/input.java",
    "content": "class Foo { // FooNX\n\tpublic Foo() { // RXgN^\n\t}\n}\n"
  },
  {
    "path": "Tmain/invalid-encoding-option.d/input.js",
    "content": "var a = 1; // ѿ\n"
  },
  {
    "path": "Tmain/invalid-encoding-option.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nif ${CTAGS} --quiet --options=NONE --list-features | grep -q iconv; then\n  check_encoding euc-jp\n  ${CTAGS} --quiet --options=NONE --input-encoding-java=invalid\t--input-encoding-javascript=euc-jp -o - input.js input.java\n  exit $?\nelse\n  skip \"iconv feature is not available\"\nfi\n"
  },
  {
    "path": "Tmain/invalid-encoding-option.d/stderr-expected.txt",
    "content": "ctags: failed opening encoding from 'invalid' to 'UTF-8'\n"
  },
  {
    "path": "Tmain/invalid-encoding-option.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/json-output-backslash-in-input-field.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/json-output-backslash-in-input-field.d/input.php",
    "content": "/* EMPTY */\n"
  },
  {
    "path": "Tmain/json-output-backslash-in-input-field.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nis_feature_available ${CTAGS} json\n\nO=\"--quiet --options=NONE \"\n\n${CTAGS} $O \\\n         --extras=+p --pseudo-tags=TAG_KIND_SEPARATOR \\\n         -o - \\\n\t\t --output-format=json input.php \\\n\t| grep '\"nn\"' | grep -v JSON_OUTPUT_VERSION\n"
  },
  {
    "path": "Tmain/json-output-backslash-in-input-field.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/json-output-backslash-in-input-field.d/stdout-expected.txt",
    "content": "{\"_type\": \"ptag\", \"name\": \"TAG_KIND_SEPARATOR\", \"parserName\": \"PHP\", \"path\": \"\\\\\", \"pattern\": \"nn\"}\n"
  },
  {
    "path": "Tmain/json-output-for-broken-input.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/json-output-for-broken-input.d/input.cs",
    "content": "aá:{0}\n"
  },
  {
    "path": "Tmain/json-output-for-broken-input.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nif is_feature_available \"${CTAGS}\" json; then\n\t${CTAGS} --quiet --options=NONE --output-format=json -o - ./input.cs\nfi\n"
  },
  {
    "path": "Tmain/json-output-for-broken-input.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/json-output-for-broken-input.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/json-output-format.d/input.1",
    "content": ".SH \"\tN\tA\tM\tE\t\"\n"
  },
  {
    "path": "Tmain/json-output-format.d/input.c",
    "content": "#include <stdio.h>\n\nstatic int foo (void)\n{\n  return 1;\n}\n\nint\nmain(void)\n{\n  return foo();\n}\n"
  },
  {
    "path": "Tmain/json-output-format.d/input.go",
    "content": "package main\n\nfunc main() {\n}\n"
  },
  {
    "path": "Tmain/json-output-format.d/input.py",
    "content": "class Foo:\n    def doIt():\n        pass\n"
  },
  {
    "path": "Tmain/json-output-format.d/run.sh",
    "content": "# Copyright: 2016 Aman Gupta\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nif is_feature_available \"${CTAGS}\" json; then\n    {\n\trun_with_format json --languages=+man --fields=-T\n\trun_with_format json --languages=+man --fields=\"*\"-T\n\trun_with_format json --languages=+man --fields=\"*\"-T --extras='*'\n    } | cat \\\n\t\t| grep -v TAG_PROGRAM_VERSION \\\n\t\t| grep -v TAG_OUTPUT_VERSION  \\\n\t\t| grep -v TAG_OUTPUT_FILESEP  \\\n\t\t| grep -v TAG_PROC_CWD\nfi\n"
  },
  {
    "path": "Tmain/json-output-format.d/stdout-expected.txt",
    "content": "# json --languages=+man --fields=-T\n{\"_type\": \"tag\", \"name\": \"Foo\", \"path\": \"input.py\", \"pattern\": \"/^class Foo:$/\", \"kind\": \"class\"}\n{\"_type\": \"tag\", \"name\": \"N\\tA\\tM\\tE\", \"path\": \"input.1\", \"pattern\": \"/^.SH \\\"\\tN\\tA\\tM\\tE\\t\\\"$/\", \"kind\": \"section\"}\n{\"_type\": \"tag\", \"name\": \"doIt\", \"path\": \"input.py\", \"pattern\": \"/^    def doIt():$/\", \"kind\": \"member\", \"scope\": \"Foo\", \"scopeKind\": \"class\"}\n{\"_type\": \"tag\", \"name\": \"foo\", \"path\": \"input.c\", \"pattern\": \"/^static int foo (void)$/\", \"file\": true, \"typeref\": \"typename:int\", \"kind\": \"function\"}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.c\", \"pattern\": \"/^main(void)$/\", \"typeref\": \"typename:int\", \"kind\": \"function\"}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.go\", \"pattern\": \"/^func main() {$/\", \"kind\": \"func\", \"scope\": \"main\", \"scopeKind\": \"package\"}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.go\", \"pattern\": \"/^package main$/\", \"kind\": \"package\"}\n# json --languages=+man --fields=*-T\n{\"_type\": \"tag\", \"name\": \"Foo\", \"path\": \"input.py\", \"pattern\": \"/^class Foo:$/\", \"language\": \"Python\", \"line\": 1, \"kind\": \"class\", \"inherits\": false, \"access\": \"public\", \"roles\": \"def\", \"end\": 3}\n{\"_type\": \"tag\", \"name\": \"N\\tA\\tM\\tE\", \"path\": \"input.1\", \"pattern\": \"/^.SH \\\"\\tN\\tA\\tM\\tE\\t\\\"$/\", \"language\": \"Man\", \"line\": 1, \"kind\": \"section\", \"roles\": \"def\", \"end\": 1}\n{\"_type\": \"tag\", \"name\": \"doIt\", \"path\": \"input.py\", \"pattern\": \"/^    def doIt():$/\", \"language\": \"Python\", \"line\": 2, \"kind\": \"member\", \"access\": \"public\", \"signature\": \"()\", \"scope\": \"Foo\", \"scopeKind\": \"class\", \"roles\": \"def\", \"end\": 3}\n{\"_type\": \"tag\", \"name\": \"foo\", \"path\": \"input.c\", \"pattern\": \"/^static int foo (void)$/\", \"file\": true, \"language\": \"C\", \"line\": 3, \"typeref\": \"typename:int\", \"kind\": \"function\", \"signature\": \"(void)\", \"roles\": \"def\", \"extras\": \"fileScope\", \"end\": 6}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.c\", \"pattern\": \"/^main(void)$/\", \"language\": \"C\", \"line\": 9, \"typeref\": \"typename:int\", \"kind\": \"function\", \"signature\": \"(void)\", \"roles\": \"def\", \"end\": 12}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.go\", \"pattern\": \"/^func main() {$/\", \"language\": \"Go\", \"line\": 3, \"kind\": \"func\", \"signature\": \"()\", \"scope\": \"main\", \"scopeKind\": \"package\", \"roles\": \"def\", \"end\": 4}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.go\", \"pattern\": \"/^package main$/\", \"language\": \"Go\", \"line\": 1, \"kind\": \"package\", \"roles\": \"def\"}\n# json --languages=+man --fields=*-T --extras=*\n{\"_type\": \"ptag\", \"name\": \"JSON_OUTPUT_VERSION\", \"path\": \"1.0\", \"pattern\": \"in development\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_EXTRA_DESCRIPTION\", \"path\": \"anonymous\", \"pattern\": \"Include tags for non-named objects like lambda\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_EXTRA_DESCRIPTION\", \"path\": \"fileScope\", \"pattern\": \"Include tags of file scope\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_EXTRA_DESCRIPTION\", \"path\": \"guest\", \"pattern\": \"Include tags generated by guest parsers\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_EXTRA_DESCRIPTION\", \"path\": \"inputFile\", \"pattern\": \"Include an entry for the base file name of every input file\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_EXTRA_DESCRIPTION\", \"path\": \"nulltag\", \"pattern\": \"Include tags with empty strings as their names\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_EXTRA_DESCRIPTION\", \"path\": \"pseudo\", \"pattern\": \"Include pseudo tags\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_EXTRA_DESCRIPTION\", \"path\": \"qualified\", \"pattern\": \"Include an extra class-qualified tag entry for each tag\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_EXTRA_DESCRIPTION\", \"path\": \"reference\", \"pattern\": \"Include reference tags\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_EXTRA_DESCRIPTION\", \"path\": \"subparser\", \"pattern\": \"Include tags generated by subparsers\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"package\", \"pattern\": \"the real package specified by the package name\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"packageName\", \"pattern\": \"the name for referring the package\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"parserName\": \"Python\", \"path\": \"nameref\", \"pattern\": \"the original name for the tag\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"access\", \"pattern\": \"Access (or export) of class members\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"compact\", \"pattern\": \"compact input line (used only in xref output)\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"end\", \"pattern\": \"end lines of various items\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"extras\", \"pattern\": \"Extra tag type information\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"file\", \"pattern\": \"File-restricted scoping\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"implementation\", \"pattern\": \"Implementation information\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"inherits\", \"pattern\": \"Inheritance information\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"input\", \"pattern\": \"input file\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"kind\", \"pattern\": \"[tags output] prepend \\\"kind:\\\" to k/ (or K/) field output, [xref and json output] kind in long-name form\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"language\", \"pattern\": \"Language of input file containing tag\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"line\", \"pattern\": \"Line number of tag definition\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"name\", \"pattern\": \"tag name\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"nth\", \"pattern\": \"the order in the parent scope\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"pattern\", \"pattern\": \"pattern\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"roles\", \"pattern\": \"Roles\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"scope\", \"pattern\": \"[tags output] prepend \\\"scope:\\\" key to s/scope field output, [xref and json output] the same as s/ field\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"scopeKind\", \"pattern\": \"[tags output] no effect, [xref and json output] kind of scope in long-name form\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"signature\", \"pattern\": \"Signature of routine (e.g. prototype or parameter list)\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"typeref\", \"pattern\": \"Type and name of a variable or typedef\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FIELD_DESCRIPTION\", \"path\": \"xpath\", \"pattern\": \"xpath for the tag\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_FILE_SORTED\", \"path\": \"1\", \"pattern\": \"0=unsorted, 1=sorted, 2=foldcase\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"C\", \"path\": \"d,macro\", \"pattern\": \"macro definitions\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"C\", \"path\": \"e,enumerator\", \"pattern\": \"enumerators (values inside an enumeration)\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"C\", \"path\": \"f,function\", \"pattern\": \"function definitions\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"C\", \"path\": \"g,enum\", \"pattern\": \"enumeration names\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"C\", \"path\": \"h,header\", \"pattern\": \"included header files\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"C\", \"path\": \"m,member\", \"pattern\": \"struct, and union members\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"C\", \"path\": \"s,struct\", \"pattern\": \"structure names\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"C\", \"path\": \"t,typedef\", \"pattern\": \"typedefs\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"C\", \"path\": \"u,union\", \"pattern\": \"union names\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"C\", \"path\": \"v,variable\", \"pattern\": \"variable definitions\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"M,anonMember\", \"pattern\": \"struct anonymous members\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"P,packageName\", \"pattern\": \"name for specifying imported package\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"Y,unknown\", \"pattern\": \"unknown\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"a,talias\", \"pattern\": \"type aliases\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"c,const\", \"pattern\": \"constants\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"f,func\", \"pattern\": \"functions\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"i,interface\", \"pattern\": \"interfaces\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"m,member\", \"pattern\": \"struct members\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"n,methodSpec\", \"pattern\": \"interface method specification\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"p,package\", \"pattern\": \"packages\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"s,struct\", \"pattern\": \"structs\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"t,type\", \"pattern\": \"types\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Go\", \"path\": \"v,var\", \"pattern\": \"variables\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Man\", \"path\": \"S,subsection\", \"pattern\": \"sub sections\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Man\", \"path\": \"s,section\", \"pattern\": \"sections\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Man\", \"path\": \"t,title\", \"pattern\": \"titles\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Python\", \"path\": \"I,namespace\", \"pattern\": \"name referring a module defined in other file\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Python\", \"path\": \"Y,unknown\", \"pattern\": \"name referring a class/variable/function/module defined in other module\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Python\", \"path\": \"c,class\", \"pattern\": \"classes\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Python\", \"path\": \"f,function\", \"pattern\": \"functions\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Python\", \"path\": \"i,module\", \"pattern\": \"modules\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Python\", \"path\": \"m,member\", \"pattern\": \"class members\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_KIND_DESCRIPTION\", \"parserName\": \"Python\", \"path\": \"v,variable\", \"pattern\": \"variables\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_OUTPUT_EXCMD\", \"path\": \"mixed\", \"pattern\": \"number, pattern, mixed, or combineV2\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_PARSER_VERSION\", \"parserName\": \"C\", \"path\": \"2.2\", \"pattern\": \"current.age\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_PARSER_VERSION\", \"parserName\": \"Go\", \"path\": \"1.1\", \"pattern\": \"current.age\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_PARSER_VERSION\", \"parserName\": \"Man\", \"path\": \"0.0\", \"pattern\": \"current.age\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_PARSER_VERSION\", \"parserName\": \"Python\", \"path\": \"1.1\", \"pattern\": \"current.age\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_PATTERN_LENGTH_LIMIT\", \"path\": \"96\", \"pattern\": \"0 for no limit\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_PROGRAM_AUTHOR\", \"path\": \"Universal Ctags Team\", \"pattern\": \"\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_PROGRAM_NAME\", \"path\": \"Universal Ctags\", \"pattern\": \"Derived from Exuberant Ctags\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_PROGRAM_URL\", \"path\": \"https://ctags.io/\", \"pattern\": \"official site\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"C\", \"kindName\": \"function\", \"path\": \"foreigncall\", \"pattern\": \"called in foreign languages\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"C\", \"kindName\": \"function\", \"path\": \"foreigndecl\", \"pattern\": \"declared in foreign languages\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"C\", \"kindName\": \"header\", \"path\": \"local\", \"pattern\": \"local header\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"C\", \"kindName\": \"header\", \"path\": \"system\", \"pattern\": \"system header\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"C\", \"kindName\": \"macro\", \"path\": \"undef\", \"pattern\": \"undefined\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"C\", \"kindName\": \"struct\", \"path\": \"foreigndecl\", \"pattern\": \"declared in foreign languages\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"Go\", \"kindName\": \"package\", \"path\": \"imported\", \"pattern\": \"imported package\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"Go\", \"kindName\": \"unknown\", \"path\": \"receiverType\", \"pattern\": \"receiver type\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"Python\", \"kindName\": \"function\", \"path\": \"entryPoint\", \"pattern\": \"specified as an entry point\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"Python\", \"kindName\": \"module\", \"path\": \"entryPoint\", \"pattern\": \"specified as a module of an entry point\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"Python\", \"kindName\": \"module\", \"path\": \"imported\", \"pattern\": \"imported modules\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"Python\", \"kindName\": \"module\", \"path\": \"indirectlyImported\", \"pattern\": \"module imported in alternative name\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"Python\", \"kindName\": \"module\", \"path\": \"namespace\", \"pattern\": \"namespace from where classes/variables/functions are imported\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"Python\", \"kindName\": \"unknown\", \"path\": \"imported\", \"pattern\": \"imported from the other module\"}\n{\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\", \"parserName\": \"Python\", \"kindName\": \"unknown\", \"path\": \"indirectlyImported\", \"pattern\": \"classes/variables/functions/modules imported in alternative name\"}\n{\"_type\": \"tag\", \"name\": \"Foo\", \"path\": \"input.py\", \"pattern\": \"/^class Foo:$/\", \"language\": \"Python\", \"line\": 1, \"kind\": \"class\", \"inherits\": false, \"access\": \"public\", \"roles\": \"def\", \"end\": 3}\n{\"_type\": \"tag\", \"name\": \"Foo.doIt\", \"path\": \"input.py\", \"pattern\": \"/^    def doIt():$/\", \"language\": \"Python\", \"line\": 2, \"kind\": \"member\", \"access\": \"public\", \"signature\": \"()\", \"scope\": \"Foo\", \"scopeKind\": \"class\", \"roles\": \"def\", \"extras\": \"qualified\", \"end\": 3}\n{\"_type\": \"tag\", \"name\": \"N\\tA\\tM\\tE\", \"path\": \"input.1\", \"pattern\": \"/^.SH \\\"\\tN\\tA\\tM\\tE\\t\\\"$/\", \"language\": \"Man\", \"line\": 1, \"kind\": \"section\", \"roles\": \"def\", \"end\": 1}\n{\"_type\": \"tag\", \"name\": \"doIt\", \"path\": \"input.py\", \"pattern\": \"/^    def doIt():$/\", \"language\": \"Python\", \"line\": 2, \"kind\": \"member\", \"access\": \"public\", \"signature\": \"()\", \"scope\": \"Foo\", \"scopeKind\": \"class\", \"roles\": \"def\", \"end\": 3}\n{\"_type\": \"tag\", \"name\": \"foo\", \"path\": \"input.c\", \"pattern\": \"/^static int foo (void)$/\", \"file\": true, \"language\": \"C\", \"line\": 3, \"typeref\": \"typename:int\", \"kind\": \"function\", \"signature\": \"(void)\", \"roles\": \"def\", \"extras\": \"fileScope\", \"end\": 6}\n{\"_type\": \"tag\", \"name\": \"input.1\", \"path\": \"input.1\", \"pattern\": false, \"language\": \"Man\", \"line\": 1, \"kind\": \"file\", \"roles\": \"def\", \"extras\": \"inputFile\", \"end\": 1}\n{\"_type\": \"tag\", \"name\": \"input.c\", \"path\": \"input.c\", \"pattern\": false, \"language\": \"C\", \"line\": 1, \"kind\": \"file\", \"roles\": \"def\", \"extras\": \"inputFile\", \"end\": 12}\n{\"_type\": \"tag\", \"name\": \"input.go\", \"path\": \"input.go\", \"pattern\": false, \"language\": \"Go\", \"line\": 1, \"kind\": \"file\", \"roles\": \"def\", \"extras\": \"inputFile\", \"end\": 4}\n{\"_type\": \"tag\", \"name\": \"input.py\", \"path\": \"input.py\", \"pattern\": false, \"language\": \"Python\", \"line\": 1, \"kind\": \"file\", \"roles\": \"def\", \"extras\": \"inputFile\", \"end\": 3}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.c\", \"pattern\": \"/^main(void)$/\", \"language\": \"C\", \"line\": 9, \"typeref\": \"typename:int\", \"kind\": \"function\", \"signature\": \"(void)\", \"roles\": \"def\", \"end\": 12}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.go\", \"pattern\": \"/^func main() {$/\", \"language\": \"Go\", \"line\": 3, \"kind\": \"func\", \"signature\": \"()\", \"scope\": \"main\", \"scopeKind\": \"package\", \"roles\": \"def\", \"end\": 4}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.go\", \"pattern\": \"/^package main$/\", \"language\": \"Go\", \"line\": 1, \"kind\": \"package\", \"roles\": \"def\"}\n{\"_type\": \"tag\", \"name\": \"main.main\", \"path\": \"input.go\", \"pattern\": \"/^func main() {$/\", \"language\": \"Go\", \"line\": 3, \"kind\": \"func\", \"signature\": \"()\", \"scope\": \"main\", \"scopeKind\": \"package\", \"roles\": \"def\", \"extras\": \"qualified\", \"end\": 4}\n{\"_type\": \"tag\", \"name\": \"stdio.h\", \"path\": \"input.c\", \"pattern\": \"/^#include <stdio.h>/\", \"language\": \"C\", \"line\": 1, \"kind\": \"header\", \"roles\": \"system\", \"extras\": \"reference\"}\n"
  },
  {
    "path": "Tmain/json-output-much-parser-fields.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/json-output-much-parser-fields.d/input.h",
    "content": "@protocol V\n(V(V(V(V(V(V\n/*  Takne from #2053 submitted by @chrismwendt */\n"
  },
  {
    "path": "Tmain/json-output-much-parser-fields.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\n#\n# This is crash test.\n# The input is broken so the we have no expectation for output.\n#\n\nCTAGS=$1\n. ../utils.sh\n\nis_feature_available ${CTAGS} json\n\n$CTAGS --options=NONE --output-format=json input.h\n"
  },
  {
    "path": "Tmain/json-output-ptag-in-list-extras.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n\n. ../utils.sh\n\nis_feature_available ${CTAGS} json\n\nO=/tmp/ctags-tmain-$$\n\necho '#' json regular file\n\"${CTAGS}\" --quiet --options=NONE --output-format=json -o $O --list-extras | grep pseudo\n\necho '#' json -\n\"${CTAGS}\" --quiet --options=NONE --output-format=json -o - --list-extras | grep pseudo\n\necho '#' json NOTHING\n\"${CTAGS}\" --quiet --options=NONE --output-format=json --list-extras | grep pseudo\n\nrm -f $O\n"
  },
  {
    "path": "Tmain/json-output-ptag-in-list-extras.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/json-output-ptag-in-list-extras.d/stdout-expected.txt",
    "content": "# json regular file\np       pseudo              yes     NONE        no      0 Include pseudo tags\n# json -\np       pseudo              no      NONE        no      0 Include pseudo tags\n# json NOTHING\np       pseudo              no      NONE        no      0 Include pseudo tags\n"
  },
  {
    "path": "Tmain/json-output-to-file.d/input.c",
    "content": "#include <stdio.h>\n\nstatic int foo (void)\n{\n  return 1;\n}\n\nint\nmain(void)\n{\n  return foo();\n}\n"
  },
  {
    "path": "Tmain/json-output-to-file.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nO=/tmp/ctags-tmain-$$.json\n\nis_feature_available \"${CTAGS}\" json\n\n$CTAGS --quiet --options=NONE --extras=-p --output-format=json  -f ${O} input.c > /dev/null && cat ${O}\ns=$?\n\nrm -f ${O}\n\nexit $s\n"
  },
  {
    "path": "Tmain/json-output-to-file.d/stdout-expected.txt",
    "content": "{\"_type\": \"tag\", \"name\": \"foo\", \"path\": \"input.c\", \"pattern\": \"/^static int foo (void)$/\", \"file\": true, \"typeref\": \"typename:int\", \"kind\": \"function\"}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.c\", \"pattern\": \"/^main(void)$/\", \"typeref\": \"typename:int\", \"kind\": \"function\"}\n"
  },
  {
    "path": "Tmain/json-output-typed-fields.d/input.c",
    "content": "static int local;\nint global;\n"
  },
  {
    "path": "Tmain/json-output-typed-fields.d/input.ctst",
    "content": "f\n"
  },
  {
    "path": "Tmain/json-output-typed-fields.d/input.rst",
    "content": "==============================================\nTITLE\n==============================================\n\nsection\n-------\n"
  },
  {
    "path": "Tmain/json-output-typed-fields.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\n\nif is_feature_available \"${CTAGS}\" json; then\n\t${CTAGS} --quiet --options=NONE -o - \\\n\t\t\t --output-format=json \\\n\t\t\t --language-force=CTagsSelfTest input.ctst\n\t${CTAGS} --quiet --options=NONE -o - \\\n\t\t\t --output-format=json \\\n\t\t\t --fields-RestructuredText=+'{overline}' input.rst\n\t${CTAGS} --quiet --options=NONE -o - \\\n\t\t\t --output-format=json \\\n\t\t\t input.c\nfi\n"
  },
  {
    "path": "Tmain/json-output-typed-fields.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/json-output-typed-fields.d/stdout-expected.txt",
    "content": "{\"_type\": \"tag\", \"name\": \"atag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\"}\n{\"_type\": \"tag\", \"name\": \"btag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\", \"bField\": true}\n{\"_type\": \"tag\", \"name\": \"ctag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\", \"bField\": true}\n{\"_type\": \"tag\", \"name\": \"dtag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\", \"sbField\": \"val\"}\n{\"_type\": \"tag\", \"name\": \"etag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\", \"sbField\": false}\n{\"_type\": \"tag\", \"name\": \"ftag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\", \"sField\": \"val\"}\n{\"_type\": \"tag\", \"name\": \"gtag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\", \"sField\": \"\"}\n{\"_type\": \"tag\", \"name\": \"htag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\", \"iField\": 23}\n{\"_type\": \"tag\", \"name\": \"itag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\", \"iField\": -3}\n{\"_type\": \"tag\", \"name\": \"jtag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\", \"iField\": 1}\n{\"_type\": \"tag\", \"name\": \"ktag\", \"path\": \"input.ctst\", \"pattern\": \"/^f$/\", \"kind\": \"fieldMaker\", \"iField\": 0}\n{\"_type\": \"tag\", \"name\": \"TITLE\", \"path\": \"input.rst\", \"pattern\": \"/^TITLE$/\", \"kind\": \"title\", \"overline\": true}\n{\"_type\": \"tag\", \"name\": \"section\", \"path\": \"input.rst\", \"pattern\": \"/^section$/\", \"kind\": \"subtitle\", \"scope\": \"TITLE\", \"scopeKind\": \"title\"}\n{\"_type\": \"tag\", \"name\": \"global\", \"path\": \"input.c\", \"pattern\": \"/^int global;$/\", \"typeref\": \"typename:int\", \"kind\": \"variable\"}\n{\"_type\": \"tag\", \"name\": \"local\", \"path\": \"input.c\", \"pattern\": \"/^static int local;$/\", \"file\": true, \"typeref\": \"typename:int\", \"kind\": \"variable\"}\n"
  },
  {
    "path": "Tmain/json-parser-limit-recursion.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/json-parser-limit-recursion.d/input512-one.json",
    "content": "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n{\"depth_pre\": 511},\n[\n{\"depth\": 512}\n],\n{\"depth_post\": 511}\n]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\n"
  },
  {
    "path": "Tmain/json-parser-limit-recursion.d/input512-two.json",
    "content": "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n{\"depth_pre\": 511},\n{\"two_pre\": 511},\n[\n{\"depth\": 512},\n{\"two\": 512}\n],\n{\"depth_post\": 511},\n{\"two_post\": 511},\n]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\n"
  },
  {
    "path": "Tmain/json-parser-limit-recursion.d/input513-one.json",
    "content": "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n[\n{\"depth_pre\": 512},\n[\n{\"depth\": 513}\n],\n{\"depth_post\": 512}\n]\n]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\n"
  },
  {
    "path": "Tmain/json-parser-limit-recursion.d/input513-two.json",
    "content": "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n[\n{\"depth_pre\": 512},\n{\"two_pre\": 512},\n[\n{\"depth\": 513},\n{\"two\": 513}\n],\n{\"depth_post\": 512},\n{\"two_post\": 512},\n]\n]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\n"
  },
  {
    "path": "Tmain/json-parser-limit-recursion.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=\"--options=NONE --sort=no -o - --kinds-JSON=-ao\"\n\necho '# depth: 512, items: 1' &&\necho '# depth: 512, items: 1' 1>&2 &&\n${CTAGS} --quiet $O input512-one.json &&\n\necho '# depth: 512, items: 2' &&\necho '# depth: 512, items: 2' 1>&2 &&\n${CTAGS} --quiet $O input512-two.json &&\n\necho '# depth: 513, items: 1' &&\necho '# depth: 513, items: 1' 1>&2 &&\n${CTAGS} --quiet $O input513-one.json &&\n\necho '# depth: 513, items: 2' &&\necho '# depth: 513, items: 2' 1>&2 &&\n${CTAGS} --quiet $O input513-two.json &&\n\necho '# depth: 513, items: 1, NO QUIET' &&\necho '# depth: 513, items: 1, NO QUIET' 1>&2 &&\n${CTAGS} $O input513-one.json &&\n\necho '# depth: 513, items: 2, NO QUIET' &&\necho '# depth: 513, items: 2, NO QUIET' 1>&2 &&\n${CTAGS} $O input513-two.json\n"
  },
  {
    "path": "Tmain/json-parser-limit-recursion.d/stderr-expected.txt",
    "content": "# depth: 512, items: 1\n# depth: 512, items: 2\n# depth: 513, items: 1\n# depth: 513, items: 2\n# depth: 513, items: 1, NO QUIET\nctags: Notice: No options will be read from files or environment\nctags: Notice: Terminate parsing: too deep brackets recursion in input513-one.json at 5\n# depth: 513, items: 2, NO QUIET\nctags: Notice: No options will be read from files or environment\nctags: Notice: Terminate parsing: too deep brackets recursion in input513-two.json at 6\n"
  },
  {
    "path": "Tmain/json-parser-limit-recursion.d/stdout-expected.txt",
    "content": "# depth: 512, items: 1\ndepth_pre\tinput512-one.json\t/^{\"depth_pre\": 511},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0\ndepth\tinput512-one.json\t/^{\"depth\": 512}$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0\ndepth_post\tinput512-one.json\t/^{\"depth_post\": 511}$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2\n# depth: 512, items: 2\ndepth_pre\tinput512-two.json\t/^{\"depth_pre\": 511},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0\ntwo_pre\tinput512-two.json\t/^{\"two_pre\": 511},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1\ndepth\tinput512-two.json\t/^{\"depth\": 512},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0\ntwo\tinput512-two.json\t/^{\"two\": 512}$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.1\ndepth_post\tinput512-two.json\t/^{\"depth_post\": 511},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3\ntwo_post\tinput512-two.json\t/^{\"two_post\": 511},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4\n# depth: 513, items: 1\ndepth_pre\tinput513-one.json\t/^{\"depth_pre\": 512},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0\n# depth: 513, items: 2\ndepth_pre\tinput513-two.json\t/^{\"depth_pre\": 512},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0\ntwo_pre\tinput513-two.json\t/^{\"two_pre\": 512},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1\n# depth: 513, items: 1, NO QUIET\ndepth_pre\tinput513-one.json\t/^{\"depth_pre\": 512},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0\n# depth: 513, items: 2, NO QUIET\ndepth_pre\tinput513-two.json\t/^{\"depth_pre\": 512},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0\ntwo_pre\tinput513-two.json\t/^{\"two_pre\": 512},$/;\"\tn\tobject:0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1\n"
  },
  {
    "path": "Tmain/kind-abnormal-spec.d/input.x",
    "content": "@\nL\n"
  },
  {
    "path": "Tmain/kind-abnormal-spec.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=\"--quiet --options=NONE\"\n\necho '# list kinds'\n${CTAGS} ${O} --languages=+CTagsSelfTest --list-kinds=CTagsSelfTest | tr '\\0' '_' | grep -v seccomp\necho\n\necho '# list kinds-full'\n${CTAGS} ${O} --languages=+CTagsSelfTest --list-kinds-full=CTagsSelfTest | tr '\\0' '_' | grep -v seccomp\necho\n\necho '# +K'\n${CTAGS} ${O} --languages=+CTagsSelfTest --language-force=CTagsSelfTest --fields=+K -o - input.x\necho\n\necho '# +k'\n${CTAGS} ${O} --languages=+CTagsSelfTest --language-force=CTagsSelfTest --fields=+k -o - input.x\necho\n\necho '# +zk'\n${CTAGS} ${O} --languages=+CTagsSelfTest --language-force=CTagsSelfTest --fields=+zk -o - input.x\necho\n\necho '# +Zk'\n${CTAGS} ${O} --languages=+CTagsSelfTest --language-force=CTagsSelfTest --fields=+Zk -o - input.x\necho\n"
  },
  {
    "path": "Tmain/kind-abnormal-spec.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/kind-abnormal-spec.d/stdout-expected.txt",
    "content": "# list kinds\nb  name with unwanted characters\n_  kind with no letter\nL  kind with no long name\nN  emit a normal tag\nB  beginning of an area for a guest\nE  end of an area for a guest\nQ  stop the parsing\nd  a kind disabled by default [off]\ne  a kind enabled by default\nr  emit a tag with multi roles\nR  emit a tag with multi roles(disabled by default) [off]\nf  tag for testing field:\nn  trigger notice output\nz  emit a tag having an empty string\nZ  don't emit a tag having an empty string\n\n# list kinds-full\n#LETTER NAME                                      ENABLED REFONLY NROLES MASTER VER DESCRIPTION\n        no letter                                 yes     no      0      NONE     0 kind with no letter\nB       ThisShouldNotBePrintedKindNameMustBeGiven yes     no      0      NONE     0 beginning of an area for a guest\nE       ThisShouldNotBePrintedKindNameMustBeGiven yes     no      0      NONE     0 end of an area for a guest\nL       ThisShouldNotBePrintedKindNameMustBeGiven yes     no      0      NONE     0 kind with no long name\nN       nothingSpecial                            yes     no      0      NONE     0 emit a normal tag\nQ       quit                                      yes     no      0      NONE     0 stop the parsing\nR       rolesDisabled                             no      yes     2      NONE     0 emit a tag with multi roles(disabled by default)\nZ       dontEmitNullTag                           yes     no      0      NONE     0 don't emit a tag having an empty string\nb       broken tag                                yes     no      1      NONE     0 name with unwanted characters\nd       disabled                                  no      no      2      NONE     0 a kind disabled by default\ne       enabled                                   yes     no      2      NONE     0 a kind enabled by default\nf       fieldMaker                                yes     no      0      NONE     0 tag for testing field:\nn       triggerNotice                             yes     no      0      NONE     0 trigger notice output\nr       roles                                     yes     yes     4      NONE     0 emit a tag with multi roles\nz       emitNullTag                               yes     no      0      NONE     0 emit a tag having an empty string\n\n# +K\nabnormal kindDefinition testing (no letter)\tinput.x\t/^@$/;\"\tno letter\nabnormal kindDefinition testing (no long name)\tinput.x\t/^L$/;\"\tL\n\n# +k\nabnormal kindDefinition testing (no letter)\tinput.x\t/^@$/;\"\tno letter\nabnormal kindDefinition testing (no long name)\tinput.x\t/^L$/;\"\tL\n\n# +zk\nabnormal kindDefinition testing (no letter)\tinput.x\t/^@$/;\"\tkind:no letter\nabnormal kindDefinition testing (no long name)\tinput.x\t/^L$/;\"\tkind:L\n\n# +Zk\nabnormal kindDefinition testing (no letter)\tinput.x\t/^@$/;\"\tno letter\nabnormal kindDefinition testing (no long name)\tinput.x\t/^L$/;\"\tL\n\n"
  },
  {
    "path": "Tmain/kind-and-role-defaults.d/input.cst",
    "content": "d\nd\nd\ne\ne\ne\n"
  },
  {
    "path": "Tmain/kind-and-role-defaults.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nB0=\"--quiet --options=NONE\"\nB1=\"-o - --fields=+E --language-force=CTagsSelfTest input.cst\"\nOPT=\n\nOPT=\necho \"# $OPT\"\n${CTAGS} $B0 $OPT $B1\necho\n\nOPT=\"--kinds-CTagsSelfTest=-e\"\necho \"# $OPT\"\n${CTAGS} $B0 $OPT $B1\necho\n\nOPT=\"--kinds-CTagsSelfTest=-e+d\"\necho \"# $OPT\"\n${CTAGS} $B0 $OPT $B1\necho\n\nOPT=\"--kinds-CTagsSelfTest=+d\"\necho \"# $OPT\"\n${CTAGS} $B0 $OPT $B1\necho\n\n\n\nOPT=\"--extras=+r --fields=+r\"\necho \"# $OPT\"\n${CTAGS} $B0 $OPT $B1\necho\n\nOPT=\"--extras=+r --fields=+r --kinds-CTagsSelfTest=-e\"\necho \"# $OPT\"\n${CTAGS} $B0 $OPT $B1\necho\n\nOPT=\"--extras=+r --fields=+r --kinds-CTagsSelfTest=-e+d\"\necho \"# $OPT\"\n${CTAGS} $B0 $OPT $B1\necho\n\nOPT=\"--extras=+r --fields=+r --kinds-CTagsSelfTest=+d\"\necho \"# $OPT\"\n${CTAGS} $B0 $OPT $B1\necho\n\nexit $?\n"
  },
  {
    "path": "Tmain/kind-and-role-defaults.d/stdout-expected.txt",
    "content": "# \nenabled-kind-no-role\tinput.cst\t/^e$/;\"\te\n\n# --kinds-CTagsSelfTest=-e\n\n# --kinds-CTagsSelfTest=-e+d\ndisable-kind-no-role\tinput.cst\t/^d$/;\"\td\n\n# --kinds-CTagsSelfTest=+d\ndisable-kind-no-role\tinput.cst\t/^d$/;\"\td\nenabled-kind-no-role\tinput.cst\t/^e$/;\"\te\n\n# --extras=+r --fields=+r\nenabled-kind-enabled-role\tinput.cst\t/^e$/;\"\te\troles:enabled\textras:reference\nenabled-kind-no-role\tinput.cst\t/^e$/;\"\te\troles:def\n\n# --extras=+r --fields=+r --kinds-CTagsSelfTest=-e\n\n# --extras=+r --fields=+r --kinds-CTagsSelfTest=-e+d\ndisable-kind-enabled-role\tinput.cst\t/^d$/;\"\td\troles:enabled\textras:reference\ndisable-kind-no-role\tinput.cst\t/^d$/;\"\td\troles:def\n\n# --extras=+r --fields=+r --kinds-CTagsSelfTest=+d\ndisable-kind-enabled-role\tinput.cst\t/^d$/;\"\td\troles:enabled\textras:reference\ndisable-kind-no-role\tinput.cst\t/^d$/;\"\td\troles:def\nenabled-kind-enabled-role\tinput.cst\t/^e$/;\"\te\troles:enabled\textras:reference\nenabled-kind-no-role\tinput.cst\t/^e$/;\"\te\troles:def\n\n"
  },
  {
    "path": "Tmain/kind-long-lregex.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho '# definition'\n${CTAGS} --quiet --options=NONE --with-list-header=no \\\n\t --langdef=IdealLang --regex-IdealLang='/def (.*)/\\1/d,definition,definitions/' \\\n\t --list-kinds-full=IdealLang\n\necho '# disabling'\n${CTAGS} --quiet --options=NONE --with-list-header=no \\\n\t --langdef=IdealLang --regex-IdealLang='/def (.*)/\\1/d,definition,definitions/' \\\n\t --kinds-IdealLang='-{definition}' \\\n\t --list-kinds-full=IdealLang\n\necho '# enabling again'\n${CTAGS} --quiet --options=NONE --with-list-header=no \\\n\t --langdef=IdealLang --regex-IdealLang='/def (.*)/\\1/d,definition,definitions/' \\\n\t --kinds-IdealLang='-{definition}' \\\n\t --kinds-IdealLang='+{definition}' \\\n\t --list-kinds-full=IdealLang\n"
  },
  {
    "path": "Tmain/kind-long-lregex.d/stdout-expected.txt",
    "content": "# definition\nd       definition yes     no      0      NONE     0 definitions\n# disabling\nd       definition no      no      0      NONE     0 definitions\n# enabling again\nd       definition yes     no      0      NONE     0 definitions\n"
  },
  {
    "path": "Tmain/kind-long.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --kinds-C=+'{label}' --list-kinds-full=C | grep label\n${CTAGS} --quiet --options=NONE --kinds-C=-'{macro}' --list-kinds-full=C | grep macro\n"
  },
  {
    "path": "Tmain/kind-long.d/stdout-expected.txt",
    "content": "L       label      yes     no      0      C        0 goto labels\nD       macroparam no      no      0      C        0 parameters inside macro definitions\nd       macro      no      no      2      C        0 macro definitions\n"
  },
  {
    "path": "Tmain/kinddef.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE\"\n\ntitle()\n{\n\techo\n\techo \"$@\"\n\n\t{\n\t\techo\n\t\techo \"$@\"\n\t} 1>&2\n}\n\n{\ntitle '# NOSUCHLANG'\n${CTAGS} --kinddef-NOSUCHLANG=l,name,description --list-kinds-full=NOSUCHLANG\n\nCTAGS=\"${CTAGS} --langdef=MYTEST\"\n\ntitle '# define \"a\"'\n${CTAGS} --kinddef-MYTEST=a,aa,aaa --list-kinds-full=MYTEST\n\ntitle '# no description 1'\n${CTAGS} --kinddef-MYTEST=a,aa, --list-kinds-full=MYTEST\n\ntitle '# no description 2'\n${CTAGS} --kinddef-MYTEST=a,aa --list-kinds-full=MYTEST\n\ntitle '# no name 1'\n${CTAGS} --kinddef-MYTEST=a, --list-kinds-full=MYTEST\n\ntitle '# no name 2'\n${CTAGS} --kinddef-MYTEST=a --list-kinds-full=MYTEST\n\ntitle '# an empty name 1'\n${CTAGS} --kinddef-MYTEST=a,,x --list-kinds-full=MYTEST\n\ntitle '# an empty name 2'\n${CTAGS} --kinddef-MYTEST=a,, --list-kinds-full=MYTEST\n\ntitle '# wrong letter in name 1'\n${CTAGS} --kinddef-MYTEST=\"a,a\tx,d\" --list-kinds-full=MYTEST\n\ntitle '# wrong letter in name 2'\n${CTAGS} --kinddef-MYTEST=\"a,a\tx,\" --list-kinds-full=MYTEST\n\ntitle '# wrong letter in name 3'\n${CTAGS} --kinddef-MYTEST=\"a,a\tx\" --list-kinds-full=MYTEST\n\ntitle '# no letter 1'\n${CTAGS} --kinddef-MYTEST=,n,d --list-kinds-full=MYTEST\n\ntitle '# no letter 2'\n${CTAGS} --kinddef-MYTEST=,n, --list-kinds-full=MYTEST\n\ntitle '# no letter 3'\n${CTAGS} --kinddef-MYTEST=,n --list-kinds-full=MYTEST\n\ntitle '# no letter 4'\n${CTAGS} --kinddef-MYTEST=, --list-kinds-full=MYTEST\n\ntitle '# no letter 5'\n${CTAGS} --kinddef-MYTEST= --list-kinds-full=MYTEST\n\ntitle '# wrong letter'\n${CTAGS} --kinddef-MYTEST=^ --list-kinds-full=MYTEST\n\ntitle '# wrong letter (using number)'\n${CTAGS} --kinddef-MYTEST=7 --list-kinds-full=MYTEST\n\ntitle '# reusing the letter for file kind'\n${CTAGS} --kinddef-MYTEST=F --list-kinds-full=MYTEST\n\ntitle '# reusing the name for file kind'\n${CTAGS} --kinddef-MYTEST=x,file,desc --list-kinds-full=MYTEST\n\ntitle '# inject a flag separator'\n${CTAGS} --kinddef-MYTEST='x,kind,desc{foo}' --list-kinds-full=MYTEST\n\ntitle '# inject a broken flag separator(1)'\n${CTAGS} --kinddef-MYTEST='x,kind,desc{foo' --list-kinds-full=MYTEST\n\ntitle '# inject a broken flag separator(2)'\n${CTAGS} --kinddef-MYTEST='x,kind,desc{' --list-kinds-full=MYTEST\n\ntitle '# use a { in description (1)'\n${CTAGS} --kinddef-MYTEST='x,kind,desc\\{' --list-kinds-full=MYTEST\n\ntitle '# use a { in description (2)'\n${CTAGS} --kinddef-MYTEST='x,kind,desc\\{}' --list-kinds-full=MYTEST\n\ntitle '# use a number char as the initial letter'\n${CTAGS} --kinddef-MYTEST='x,0kind,desc' --list-kinds-full=MYTEST\n\ntitle '# use a number char within the body'\n${CTAGS} --kinddef-MYTEST='x,k0ind,desc' --list-kinds-full=MYTEST\n\n# title '# use a { and \\t in description'\n# ${CTAGS} --kinddef-MYTEST='x,kind,desc\\{}\\t' --list-kinds-full=MYTEST\n\ntitle '# use a \\ in description'\n${CTAGS} --kinddef-MYTEST='x,kind,desc\\\\backslash' --list-kinds-full=MYTEST\n\ntitle '# description started from {'\n${CTAGS} --kinddef-MYTEST='x,kind,{' --list-kinds-full=MYTEST\n\ntitle '# description started from \\{'\n${CTAGS} --kinddef-MYTEST='x,kind,\\{' --list-kinds-full=MYTEST\n\ntitle '# _refonly flag'\n${CTAGS} --kinddef-MYTEST='x,kind,desc' --list-kinds-full=MYTEST\n${CTAGS} --kinddef-MYTEST='x,kind,desc' --_roledef-MYTEST.x=role,roleDesc --list-kinds-full=MYTEST\n${CTAGS} --kinddef-MYTEST='x,kind,desc{_refonly}' --_roledef-MYTEST.'{kind}'=role,roleDesc --list-kinds-full=MYTEST\n\n} > /tmp/ctags-tmain-$$.stdout 2>/tmp/ctags-tmain-$$.stderr\n\nsed -e 's/\\.exe//g' < /tmp/ctags-tmain-$$.stdout\nrm /tmp/ctags-tmain-$$.stdout\n\nsed -e 's/\\.exe//g' < /tmp/ctags-tmain-$$.stderr 1>&2\nrm /tmp/ctags-tmain-$$.stderr\n"
  },
  {
    "path": "Tmain/kinddef.d/stderr-expected.txt",
    "content": "\n# NOSUCHLANG\nctags: Unknown language \"NOSUCHLANG\" in \"kinddef-NOSUCHLANG\" option\n\n# define \"a\"\n\n# no description 1\nctags: found an empty kind description in \"--kinddef-MYTEST\" option\n\n# no description 2\nctags: no kind description specified in \"--kinddef-MYTEST\" option\n\n# no name 1\nctags: no kind name specified in \"--kinddef-MYTEST\" option\n\n# no name 2\nctags: wrong kind definition in \"--kinddef-MYTEST\" option: no comma after letter\n\n# an empty name 1\nctags: the kind name in \"--kinddef-MYTEST\" option is empty\n\n# an empty name 2\nctags: the kind name in \"--kinddef-MYTEST\" option is empty\n\n# wrong letter in name 1\nctags: non-alphanumeric char is used as part of kind name: 'a\tx' in \"--kinddef-MYTEST\" option\n\n# wrong letter in name 2\nctags: non-alphanumeric char is used as part of kind name: 'a\tx' in \"--kinddef-MYTEST\" option\n\n# wrong letter in name 3\nctags: no kind description specified in \"--kinddef-MYTEST\" option\n\n# no letter 1\nctags: no kind letter specified in \"--kinddef-MYTEST\" option\n\n# no letter 2\nctags: no kind letter specified in \"--kinddef-MYTEST\" option\n\n# no letter 3\nctags: no kind letter specified in \"--kinddef-MYTEST\" option\n\n# no letter 4\nctags: no kind letter specified in \"--kinddef-MYTEST\" option\n\n# no letter 5\nctags: no kind definition specified in \"--kinddef-MYTEST\" option\n\n# wrong letter\nctags: the kind letter given in \"--kinddef-MYTEST\" option is not an alphabet\n\n# wrong letter (using number)\nctags: the kind letter given in \"--kinddef-MYTEST\" option is not an alphabet\n\n# reusing the letter for file kind\nctags: the kind letter `F' in \"--kinddef-MYTEST\" option is reserved for \"file\" kind\n\n# reusing the name for file kind\nctags: the kind name file in \"--kinddef-MYTEST\" option is reserved\n\n# inject a flag separator\n\n# inject a broken flag separator(1)\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{foo\"\n\n# inject a broken flag separator(2)\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{\"\n\n# use a { in description (1)\n\n# use a { in description (2)\n\n# use a number char as the initial letter\nctags: a kind name doesn't start with an alphabetical character: '0kind' in \"--kinddef-MYTEST\" option\n\n# use a number char within the body\n\n# use a \\ in description\n\n# description started from {\nctags: found an empty kind description in \"--kinddef-MYTEST\" option\n\n# description started from \\{\n\n# _refonly flag\n"
  },
  {
    "path": "Tmain/kinddef.d/stdout-expected.txt",
    "content": "\n# NOSUCHLANG\n\n# define \"a\"\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\na       aa   yes     no      0      NONE     0 aaa\n\n# no description 1\n\n# no description 2\n\n# no name 1\n\n# no name 2\n\n# an empty name 1\n\n# an empty name 2\n\n# wrong letter in name 1\n\n# wrong letter in name 2\n\n# wrong letter in name 3\n\n# no letter 1\n\n# no letter 2\n\n# no letter 3\n\n# no letter 4\n\n# no letter 5\n\n# wrong letter\n\n# wrong letter (using number)\n\n# reusing the letter for file kind\n\n# reusing the name for file kind\n\n# inject a flag separator\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       kind yes     no      0      NONE     0 desc\n\n# inject a broken flag separator(1)\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       kind yes     no      0      NONE     0 desc\n\n# inject a broken flag separator(2)\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       kind yes     no      0      NONE     0 desc\n\n# use a { in description (1)\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       kind yes     no      0      NONE     0 desc{\n\n# use a { in description (2)\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       kind yes     no      0      NONE     0 desc{}\n\n# use a number char as the initial letter\n\n# use a number char within the body\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       k0ind yes     no      0      NONE     0 desc\n\n# use a \\ in description\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       kind yes     no      0      NONE     0 desc\\backslash\n\n# description started from {\n\n# description started from \\{\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       kind yes     no      0      NONE     0 {\n\n# _refonly flag\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       kind yes     no      0      NONE     0 desc\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       kind yes     no      1      NONE     0 desc\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       kind yes     yes     1      NONE     0 desc\n"
  },
  {
    "path": "Tmain/kinds-all-with-spec.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/kinds-all-with-spec.d/input.c",
    "content": "int main(void) {return 0;}\n"
  },
  {
    "path": "Tmain/kinds-all-with-spec.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nt ()\n{\n\techo '#' \"--all-kinds=$1\" 1>&2\n\t$CTAGS --quiet --options=NONE -o - --all-kinds=\"$1\" --fields=-T input.c\n\techo '#' \"--kinds-all=$1\" 1>&2\n\t$CTAGS --quiet --options=NONE -o - --kinds-all=\"$1\" --fields=-T input.c\n}\n\necho '#' 1>&2\necho '# unexpected flags after operators ([+-])' 1>&2\necho '#' 1>&2\nt '*-a'\nt '*-{abc}'\nt '*+a'\nt '*+{abc}'\n\nt 'F-a'\nt 'F-{abc}'\nt 'F+a'\nt 'F+{abc}'\n\nt '{file}-a'\nt '{file}-{abc}'\nt '{file}+a'\nt '{file}+{abc}'\n\nt '+F-a'\nt '+F-{abc}'\nt '+F+a'\nt '+F+{abc}'\n\nt '+{file}-a'\nt '+{file}-{abc}'\nt '+{file}+a'\nt '+{file}+{abc}'\n\necho '#' 1>&2\necho '# repeaed operators ([+-])' 1>&2\necho '#' 1>&2\nt '*--{file}'\nt '*--F'\nt '*++{file}'\nt '*++F'\nt '*+-{file}'\nt '*+-F'\nt '*-+{file}'\nt '*-+F'\n\nt '{file}--F'\nt '{file}++F'\nt '{file}-+F'\nt '{file}+-F'\n\nt '{file}--{file}'\nt '{file}++{file}'\nt '{file}-+{file}'\nt '{file}+-{file}'\n\nt 'F--{file}'\nt 'F++{file}'\nt 'F-+{file}'\nt 'F+-{file}'\n\nt 'F--F'\nt 'F++F'\nt 'F-+F'\nt 'F+-F'\n\necho '#' 1>&2\necho '# redundant * usage' 1>&2\necho '#' 1>&2\nt '-*'\nt '+*'\nt 'F-*'\nt 'F+*'\nt '{file}-*'\nt '{file}+*'\nt '+F-*'\nt '-F+*'\nt '+{file}-*'\nt '-{file}+*'\n\necho '#' 1>&2\necho '# Just print the parsed file name' 1>&2\necho '#' 1>&2\n\n$CTAGS --quiet --options=NONE -o- --all-kinds=F --extras=+f --fields=-T input.c\n$CTAGS --quiet --options=NONE -o- --all-kinds=FF --extras=+f --fields=-T input.c\n$CTAGS --quiet --options=NONE -o- --all-kinds=-F+F --extras=+f --fields=-T input.c\n$CTAGS --quiet --options=NONE -o- --all-kinds='*' --all-kinds=F --extras=+f --fields=-T input.c\n\n$CTAGS --quiet --options=NONE -o- --kinds-all=F --extras=+f --fields=-T input.c\n$CTAGS --quiet --options=NONE -o- --kinds-all=FF --extras=+f --fields=-T input.c\n$CTAGS --quiet --options=NONE -o- --kinds-all=-F+F --extras=+f --fields=-T input.c\n$CTAGS --quiet --options=NONE -o- --kinds-all='*' --kinds-all=F --extras=+f --fields=-T input.c\n\necho '#' 1>&2\necho '# The original test cases' 1>&2\necho '#' 1>&2\nif ! $CTAGS --quiet --options=NONE --kinds-all=xyz --_force-quit=0; then\n\t$CTAGS --quiet --options=NONE --all-kinds=abc --_force-quit=0\nelse\n\texit 0\nfi\n"
  },
  {
    "path": "Tmain/kinds-all-with-spec.d/stderr-expected.txt",
    "content": "#\n# unexpected flags after operators ([+-])\n#\n# --all-kinds=*-a\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=*-a\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=*-{abc}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=*-{abc}\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=*+a\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=*+a\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=*+{abc}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=*+{abc}\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=F-a\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=F-a\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=F-{abc}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=F-{abc}\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=F+a\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=F+a\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=F+{abc}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=F+{abc}\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds={file}-a\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all={file}-a\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds={file}-{abc}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all={file}-{abc}\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds={file}+a\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all={file}+a\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds={file}+{abc}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all={file}+{abc}\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=+F-a\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=+F-a\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=+F-{abc}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=+F-{abc}\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=+F+a\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=+F+a\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=+F+{abc}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=+F+{abc}\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=+{file}-a\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=+{file}-a\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=+{file}-{abc}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=+{file}-{abc}\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=+{file}+a\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=+{file}+a\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n# --all-kinds=+{file}+{abc}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n# --kinds-all=+{file}+{abc}\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\n#\n# repeaed operators ([+-])\n#\n# --all-kinds=*--{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=*--{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=*--F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=*--F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=*++{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=*++{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=*++F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=*++F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=*+-{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=*+-{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=*+-F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=*+-F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=*-+{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=*-+{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=*-+F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=*-+F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds={file}--F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all={file}--F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds={file}++F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all={file}++F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds={file}-+F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all={file}-+F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds={file}+-F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all={file}+-F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds={file}--{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all={file}--{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds={file}++{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all={file}++{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds={file}-+{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all={file}-+{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds={file}+-{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all={file}+-{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=F--{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=F--{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=F++{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=F++{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=F-+{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=F-+{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=F+-{file}\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=F+-{file}\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=F--F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=F--F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=F++F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=F++F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=F-+F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=F-+F\nctags: don't repeat + (nor -) in --kinds-all option\n# --all-kinds=F+-F\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't repeat + (nor -) in --all-kinds option\n# --kinds-all=F+-F\nctags: don't repeat + (nor -) in --kinds-all option\n#\n# redundant * usage\n#\n# --all-kinds=-*\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't use '*' after + (nor -) in --all-kinds option\n# --kinds-all=-*\nctags: don't use '*' after + (nor -) in --kinds-all option\n# --all-kinds=+*\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't use '*' after + (nor -) in --all-kinds option\n# --kinds-all=+*\nctags: don't use '*' after + (nor -) in --kinds-all option\n# --all-kinds=F-*\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't use '*' after + (nor -) in --all-kinds option\n# --kinds-all=F-*\nctags: don't use '*' after + (nor -) in --kinds-all option\n# --all-kinds=F+*\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't use '*' after + (nor -) in --all-kinds option\n# --kinds-all=F+*\nctags: don't use '*' after + (nor -) in --kinds-all option\n# --all-kinds={file}-*\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't use '*' after + (nor -) in --all-kinds option\n# --kinds-all={file}-*\nctags: don't use '*' after + (nor -) in --kinds-all option\n# --all-kinds={file}+*\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't use '*' after + (nor -) in --all-kinds option\n# --kinds-all={file}+*\nctags: don't use '*' after + (nor -) in --kinds-all option\n# --all-kinds=+F-*\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't use '*' after + (nor -) in --all-kinds option\n# --kinds-all=+F-*\nctags: don't use '*' after + (nor -) in --kinds-all option\n# --all-kinds=-F+*\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't use '*' after + (nor -) in --all-kinds option\n# --kinds-all=-F+*\nctags: don't use '*' after + (nor -) in --kinds-all option\n# --all-kinds=+{file}-*\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't use '*' after + (nor -) in --all-kinds option\n# --kinds-all=+{file}-*\nctags: don't use '*' after + (nor -) in --kinds-all option\n# --all-kinds=-{file}+*\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: don't use '*' after + (nor -) in --all-kinds option\n# --kinds-all=-{file}+*\nctags: don't use '*' after + (nor -) in --kinds-all option\n#\n# Just print the parsed file name\n#\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\n#\n# The original test cases\n#\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --kinds-all\nctags: Warning: \"--all-kinds\" option is obsolete; use \"--kinds-all\" instead\nctags: only '*', 'F', \"{file}\" or their combination is acceptable as kind letter for --all-kinds\n"
  },
  {
    "path": "Tmain/kinds-all-with-spec.d/stdout-expected.txt",
    "content": "input.c\tinput.c\t1;\"\tF\ninput.c\tinput.c\t1;\"\tF\ninput.c\tinput.c\t1;\"\tF\nmain\tinput.c\t/^int main(void) {return 0;}$/;\"\tf\ttyperef:typename:int\ninput.c\tinput.c\t1;\"\tF\ninput.c\tinput.c\t1;\"\tF\ninput.c\tinput.c\t1;\"\tF\ninput.c\tinput.c\t1;\"\tF\nmain\tinput.c\t/^int main(void) {return 0;}$/;\"\tf\ttyperef:typename:int\ninput.c\tinput.c\t1;\"\tF\n"
  },
  {
    "path": "Tmain/lang-sequel.d/args.ctags",
    "content": "--langdef=UnknownX\n--map-UnknownX=.unknown\n--_sequel-UnknownX={{\n    (bye) ==\n}}\n"
  },
  {
    "path": "Tmain/lang-sequel.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/lang-sequel.d/input.unknown",
    "content": "EMPTY\n"
  },
  {
    "path": "Tmain/lang-sequel.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\n${CTAGS} --quiet --options=NONE --options=./args.ctags -o - input.unknown\n"
  },
  {
    "path": "Tmain/lang-sequel.d/stderr-expected.txt",
    "content": "(bye)\n"
  },
  {
    "path": "Tmain/lang-sequel.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/lang-with-no-pattern.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/lang-with-no-pattern.d/input.foo",
    "content": ""
  },
  {
    "path": "Tmain/lang-with-no-pattern.d/run.sh",
    "content": "# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nis_feature_available ${CTAGS} debug\n\n${CTAGS} --quiet --options=NONE --langdef=foo --map-foo=+.foo -o - input.foo\n"
  },
  {
    "path": "Tmain/lang-with-no-pattern.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/lang-with-no-pattern.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/langmap-option-including-patterns.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/langmap-option-including-patterns.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n: &&\n    echo 1. &&\n    ${CTAGS} --quiet --options=NONE --langdef=foo --langmap=foo:'(akefile)' --langmap=foo:'([Mm]akefile)(GNUmakefile)' --list-maps | grep 'akefile' &&\n    echo 2. &&\n    ${CTAGS} --quiet --options=NONE --langmap=Ruby:+'([Mm]akefile)(GNUmakefile).html' --list-maps | grep '\\.rb' &&\n    echo 3. &&\n    ${CTAGS} --quiet --options=NONE --langmap=Ruby:+'([Mm]akefile)(GNUmakefile).html' --list-maps | grep 'akefile' &&\n    echo 4. &&\n    ${CTAGS} --quiet --options=NONE --langmap=Ruby:+'([Mm]akefile)(GNUmakefile).html' --list-maps | grep '\\.html' &&\n    echo 5. &&\n    ${CTAGS} --quiet --options=NONE --langmap=Ruby:+'([Mm]akefile)(GNUmakefile).html' --langmap=default --list-maps | grep '\\.html'\n\nexit $?\n"
  },
  {
    "path": "Tmain/langmap-option-including-patterns.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/langmap-option-including-patterns.d/stdout-expected.txt",
    "content": "1.\nAutomake Makefile.am GNUmakefile.am *.am\nRake     Rakefile *.rake\nfoo      [Mm]akefile GNUmakefile\n2.\nRuby     [Mm]akefile GNUmakefile *.rb *.ruby *.html\n3.\nAutomake Makefile.am GNUmakefile.am *.am\nRake     Rakefile *.rake\nRuby     [Mm]akefile GNUmakefile *.rb *.ruby *.html\n4.\nRuby     [Mm]akefile GNUmakefile *.rb *.ruby *.html\n5.\nHTML     *.htm *.html\n"
  },
  {
    "path": "Tmain/langmap-option.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/langmap-option.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n: &&\n    # Clear all mappings related to a language\n    echo 1. &&\n    ${CTAGS} --quiet --options=NONE --langmap=Ruby: --list-maps | grep '^Ruby' &&\n    # Take over a mapping from the other language (resetting)\n    echo 2. &&\n    ${CTAGS} --quiet --options=NONE --langdef=foo --langmap=foo:.rb --list-maps | grep '\\.rb' &&\n    # Overwrite a mapping\n    echo 3. &&\n    ${CTAGS} --quiet --options=NONE --langdef=foo --langmap=foo:.zzz --langmap=foo:.html --list-maps | grep '\\.html' &&\nexit $?\n"
  },
  {
    "path": "Tmain/langmap-option.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/langmap-option.d/stdout-expected.txt",
    "content": "1.\nRuby    \n2.\nfoo      *.rb\n3.\nfoo      *.html\n"
  },
  {
    "path": "Tmain/language-filed-optscript.d/foo.ctags",
    "content": "--langdef=foo\n--map-foo=+.foo\n\n--kinddef-foo=v,var,variables\n\n--regex-foo=/def ([a-z])/\\1/v/{{\n   . :language =\n}}\n"
  },
  {
    "path": "Tmain/language-filed-optscript.d/input.foo",
    "content": "def a\n"
  },
  {
    "path": "Tmain/language-filed-optscript.d/run.sh",
    "content": "# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --options=foo.ctags -o - input.foo\n"
  },
  {
    "path": "Tmain/language-filed-optscript.d/stderr-expected.txt",
    "content": "foo\n"
  },
  {
    "path": "Tmain/language-filed-optscript.d/stdout-expected.txt",
    "content": "a\tinput.foo\t/^def a$/;\"\tv\n"
  },
  {
    "path": "Tmain/language-names.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/language-names.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\ntest 0 = $( ${CTAGS} --options=NONE --list-languages | grep -v \"^[A-Z].*\" | wc -l )\n"
  },
  {
    "path": "Tmain/languages-and-language-force-options.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/languages-and-language-force-options.d/input.c",
    "content": ""
  },
  {
    "path": "Tmain/languages-and-language-force-options.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --language-force=C --languages=-C -o - input.c\n"
  },
  {
    "path": "Tmain/languages-and-language-force-options.d/stderr-expected.txt",
    "content": "ctags: C parser specified with --language-force is disabled\n"
  },
  {
    "path": "Tmain/line-regex-optscript.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/line-regex-optscript.d/hello.ctags",
    "content": "--langdef=hello\n--kinddef-hello=d,def,definitions\n--map-hello=+.hello\n\n--regex-hello=/^def +([-a-z]+):$/\\1/d/{{\n\t(world)\n\t/putlast { 1 index length exch put } def\n\t/tr {\n\t    % str [int<from> int<to>] str'\n\t    ()\n\t    2 index {\n\t\t% str [int<from> int<to>] str' int<chr>\n\t\tdup 3 index 0 get\n\t\t% str [int<from> int<to>] str' int<chr> int<chr> int<from>\n\t\teq {% str [int<from> int<to>] str' int<chr>\n\t\t    pop\n\t\t    dup 2 index 1 get putlast\n\t\t} {% str [int<from> int<to>] str' int<chr>\n\t\t    1 index exch putlast\n\t\t} ifelse\n\t    } forall\n\t    % str [int<from> int<to>] str'\n\t    exch pop\n\t    0 exch putinterval\n\t} def\n\t. :name dup (-_) tr . exch name:\n}}\n\n--regex-hello=/^end//{{\n\t(hello) pstack\n\tclear\n}}\n"
  },
  {
    "path": "Tmain/line-regex-optscript.d/input.hello",
    "content": "def x-y-z:\nend\n"
  },
  {
    "path": "Tmain/line-regex-optscript.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --quiet --options=NONE --options=hello.ctags -o - input.hello | sort\n"
  },
  {
    "path": "Tmain/line-regex-optscript.d/stderr-expected.txt",
    "content": "(hello)\n(world)\n"
  },
  {
    "path": "Tmain/line-regex-optscript.d/stdout-expected.txt",
    "content": "x_y_z\tinput.hello\t/^def x-y-z:$/;\"\td\n"
  },
  {
    "path": "Tmain/list-aliases.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\n\n${CTAGS} --quiet --options=NONE \\\n\t\t --list-aliases=sh\n"
  },
  {
    "path": "Tmain/list-aliases.d/stdout-expected.txt",
    "content": "#ALIAS\nsh\nbash\nksh\nash\ndash\nshell-script\n"
  },
  {
    "path": "Tmain/list-excludes.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --exclude='foo' --list-excludes\n"
  },
  {
    "path": "Tmain/list-excludes.d/stdout-expected.txt",
    "content": "#NAME\n*.a\n*.class\n*.dll\n*.exe\n*.gcda\n*.gcno\n*.lib\n*.o\n*.obj\n*.pyc\n*.pyo\n*.so\n*~\n.*.swp\n.DS_Store\n.arch-ids\n.arch-inventory\n.bzr\n.bzrignore\n.cvsignore\n.deps\n.dvi\n.git\n.gitattributes\n.gitignore\n.hg\n.hgignore\n.svn\nBitKeeper\nCVS\nEIFGEN\nPENDING\nRCS\nRESYNC\nSCCS\n_darcs\nautom4te.cache\nfoo\n{arch}\n"
  },
  {
    "path": "Tmain/list-extras.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/list-extras.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nno_yaml()\n{\n\tgrep -v I18nRubyGem\n}\n\n${CTAGS} --quiet --options=NONE --extras='*' --with-list-header --list-extras | no_yaml\n${CTAGS} --quiet --options=NONE --extras='*' --with-list-header --machinable --list-extras | no_yaml\n${CTAGS} --quiet --options=NONE --extras= --with-list-header --list-extras=NONE | no_yaml\n"
  },
  {
    "path": "Tmain/list-extras.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-extras.d/stdout-expected.txt",
    "content": "#LETTER NAME                ENABLED LANGUAGE    FIXED VER DESCRIPTION\n-       anonymous           yes     NONE        no      0 Include tags for non-named objects like lambda\nF       fileScope           yes     NONE        no      0 Include tags of file scope\nf       inputFile           yes     NONE        no      0 Include an entry for the base file name of every input file\ng       guest               yes     NONE        no      0 Include tags generated by guest parsers\np       pseudo              yes     NONE        no      0 Include pseudo tags\nq       qualified           yes     NONE        no      0 Include an extra class-qualified tag entry for each tag\nr       reference           yes     NONE        no      0 Include reference tags\ns       subparser           yes     NONE        no      0 Include tags generated by subparsers\nz       nulltag             yes     NONE        no      1 Include tags with empty strings as their names\n-       canonicalizedName   yes     Automake    no      1 Include canonicalized object name like libctags_a\n-       linkName            no      Fortran     no      1 Linking name used in foreign languages\n-       implicitClass       no      GDScript    no      0 Include tag for the implicitly defined unnamed class\n-       doubleSharps        no      IPythonCell no      0 Include cells starting from ##\n-       configPrefixed      yes     Kconfig     no      0 prepend CONFIG_ to config names\n-       CppDef              no      Make        no      1 Include FOO in -DFOO as as a name of CPreProcessor macro\n-       implicitImportName  yes     Odin        no      0 implicitly defined import name like \"filepath\" in \"core:path/filepath\"\n-       guessedFromFileName yes     PkgConfig   no      0 the guessed package name of the .pc file\n-       arityAppended       yes     Prolog      no      0 Include predicates with their arities\n-       funcmap             yes     QemuHX      no      0 Include mapping SQMP to C function name\n-       whitespaceSwapped   yes     Robot       no      0 Include tags swapping whitespace and underscore chars\n#LETTER\tNAME\tENABLED\tLANGUAGE\tFIXED\tVER\tDESCRIPTION\n-\tanonymous\tyes\tNONE\tno\t0\tInclude tags for non-named objects like lambda\nF\tfileScope\tyes\tNONE\tno\t0\tInclude tags of file scope\nf\tinputFile\tyes\tNONE\tno\t0\tInclude an entry for the base file name of every input file\ng\tguest\tyes\tNONE\tno\t0\tInclude tags generated by guest parsers\np\tpseudo\tyes\tNONE\tno\t0\tInclude pseudo tags\nq\tqualified\tyes\tNONE\tno\t0\tInclude an extra class-qualified tag entry for each tag\nr\treference\tyes\tNONE\tno\t0\tInclude reference tags\ns\tsubparser\tyes\tNONE\tno\t0\tInclude tags generated by subparsers\nz\tnulltag\tyes\tNONE\tno\t1\tInclude tags with empty strings as their names\n-\tcanonicalizedName\tyes\tAutomake\tno\t1\tInclude canonicalized object name like libctags_a\n-\tlinkName\tno\tFortran\tno\t1\tLinking name used in foreign languages\n-\timplicitClass\tno\tGDScript\tno\t0\tInclude tag for the implicitly defined unnamed class\n-\tdoubleSharps\tno\tIPythonCell\tno\t0\tInclude cells starting from ##\n-\tconfigPrefixed\tyes\tKconfig\tno\t0\tprepend CONFIG_ to config names\n-\tCppDef\tno\tMake\tno\t1\tInclude FOO in -DFOO as as a name of CPreProcessor macro\n-\timplicitImportName\tyes\tOdin\tno\t0\timplicitly defined import name like \"filepath\" in \"core:path/filepath\"\n-\tguessedFromFileName\tyes\tPkgConfig\tno\t0\tthe guessed package name of the .pc file\n-\tarityAppended\tyes\tProlog\tno\t0\tInclude predicates with their arities\n-\tfuncmap\tyes\tQemuHX\tno\t0\tInclude mapping SQMP to C function name\n-\twhitespaceSwapped\tyes\tRobot\tno\t0\tInclude tags swapping whitespace and underscore chars\n#LETTER NAME      ENABLED LANGUAGE FIXED VER DESCRIPTION\n-       anonymous no      NONE     no      0 Include tags for non-named objects like lambda\nF       fileScope no      NONE     no      0 Include tags of file scope\nf       inputFile no      NONE     no      0 Include an entry for the base file name of every input file\ng       guest     no      NONE     no      0 Include tags generated by guest parsers\np       pseudo    no      NONE     no      0 Include pseudo tags\nq       qualified no      NONE     no      0 Include an extra class-qualified tag entry for each tag\nr       reference no      NONE     no      0 Include reference tags\ns       subparser no      NONE     no      0 Include tags generated by subparsers\nz       nulltag   no      NONE     no      1 Include tags with empty strings as their names\n"
  },
  {
    "path": "Tmain/list-fields-fixed-field-handling.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=\"$1\"\n\nis_feature_available \"${CTAGS}\" json\n\nrun()\n{\n\techo '#' \"$@\"\n\t$CTAGS --quiet --options=NONE \"$@\" | grep -v -e ^-\n}\n\nrun --output-format=u-ctags  --fields=n --list-fields\nrun --fields=n --output-format=u-ctags  --list-fields\nrun --output-format=json  --fields=n --list-fields\nrun --fields=n --output-format=json  --list-fields\n"
  },
  {
    "path": "Tmain/list-fields-fixed-field-handling.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-fields-fixed-field-handling.d/stdout-expected.txt",
    "content": "# --output-format=u-ctags --fields=n --list-fields\n#LETTER NAME           ENABLED LANGUAGE         JSTYPE FIXED OP VER DESCRIPTION\nN       name           yes     NONE             s--    yes   rw   0 tag name\nF       input          yes     NONE             s--    yes   r-   0 input file\nP       pattern        yes     NONE             s-b    yes   --   0 pattern\nC       compact        no      NONE             s--    no    --   0 compact input line (used only in xref output)\nE       extras         no      NONE             s--    no    r-   0 Extra tag type information\nK       NONE           no      NONE             s--    no    --   0 Kind of tag in long-name form\nR       NONE           no      NONE             s--    no    --   0 Marker (R or D) representing whether tag is definition or reference\nS       signature      no      NONE             s--    no    rw   0 Signature of routine (e.g. prototype or parameter list)\nT       epoch          no      NONE             -i-    no    --   0 the last modified time of the input file (only for F/file kind tag)\nZ       scope          no      NONE             s--    no    rw   0 [tags output] prepend \"scope:\" key to s/scope field output, [xref and json output] the same as s/ field\na       access         no      NONE             s--    no    rw   0 Access (or export) of class members\ne       end            no      NONE             -i-    no    rw   0 end lines of various items\nf       file           no      NONE             --b    no    --   0 File-restricted scoping\ni       inherits       no      NONE             s-b    no    -w   0 Inheritance information\nk       NONE           no      NONE             s--    no    --   0 Kind of tag in one-letter form\nl       language       no      NONE             s--    no    r-   0 Language of input file containing tag\nm       implementation no      NONE             s--    no    --   0 Implementation information\nn       line           yes     NONE             -i-    no    rw   0 Line number of tag definition\no       nth            no      NONE             -i-    no    --   0 the order in the parent scope\np       scopeKind      no      NONE             s--    no    --   0 [tags output] no effect, [xref and json output] kind of scope in long-name form\nr       roles          no      NONE             s--    no    r-   0 Roles\ns       NONE           no      NONE             s--    no    --   0 [tags output] scope (kind:name) of tag definition, [xref and json output] name of scope\nt       typeref        no      NONE             s--    no    rw   0 Type and name of a variable or typedef\nx       xpath          no      NONE             s--    no    --   0 xpath for the tag\nz       kind           no      NONE             s--    no    r-   0 [tags output] prepend \"kind:\" to k/ (or K/) field output, [xref and json output] kind in long-name form\n# --fields=n --output-format=u-ctags --list-fields\n#LETTER NAME           ENABLED LANGUAGE         JSTYPE FIXED OP VER DESCRIPTION\nN       name           yes     NONE             s--    yes   rw   0 tag name\nF       input          yes     NONE             s--    yes   r-   0 input file\nP       pattern        yes     NONE             s-b    yes   --   0 pattern\nC       compact        no      NONE             s--    no    --   0 compact input line (used only in xref output)\nE       extras         no      NONE             s--    no    r-   0 Extra tag type information\nK       NONE           no      NONE             s--    no    --   0 Kind of tag in long-name form\nR       NONE           no      NONE             s--    no    --   0 Marker (R or D) representing whether tag is definition or reference\nS       signature      no      NONE             s--    no    rw   0 Signature of routine (e.g. prototype or parameter list)\nT       epoch          no      NONE             -i-    no    --   0 the last modified time of the input file (only for F/file kind tag)\nZ       scope          no      NONE             s--    no    rw   0 [tags output] prepend \"scope:\" key to s/scope field output, [xref and json output] the same as s/ field\na       access         no      NONE             s--    no    rw   0 Access (or export) of class members\ne       end            no      NONE             -i-    no    rw   0 end lines of various items\nf       file           no      NONE             --b    no    --   0 File-restricted scoping\ni       inherits       no      NONE             s-b    no    -w   0 Inheritance information\nk       NONE           no      NONE             s--    no    --   0 Kind of tag in one-letter form\nl       language       no      NONE             s--    no    r-   0 Language of input file containing tag\nm       implementation no      NONE             s--    no    --   0 Implementation information\nn       line           yes     NONE             -i-    no    rw   0 Line number of tag definition\no       nth            no      NONE             -i-    no    --   0 the order in the parent scope\np       scopeKind      no      NONE             s--    no    --   0 [tags output] no effect, [xref and json output] kind of scope in long-name form\nr       roles          no      NONE             s--    no    r-   0 Roles\ns       NONE           no      NONE             s--    no    --   0 [tags output] scope (kind:name) of tag definition, [xref and json output] name of scope\nt       typeref        no      NONE             s--    no    rw   0 Type and name of a variable or typedef\nx       xpath          no      NONE             s--    no    --   0 xpath for the tag\nz       kind           no      NONE             s--    no    r-   0 [tags output] prepend \"kind:\" to k/ (or K/) field output, [xref and json output] kind in long-name form\n# --output-format=json --fields=n --list-fields\n#LETTER NAME           ENABLED LANGUAGE         JSTYPE FIXED OP VER DESCRIPTION\nC       compact        no      NONE             s--    no    --   0 compact input line (used only in xref output)\nE       extras         no      NONE             s--    no    r-   0 Extra tag type information\nF       input          no      NONE             s--    no    r-   0 input file\nK       NONE           no      NONE             s--    no    --   0 Kind of tag in long-name form\nN       name           no      NONE             s--    no    rw   0 tag name\nP       pattern        no      NONE             s-b    no    --   0 pattern\nR       NONE           no      NONE             s--    no    --   0 Marker (R or D) representing whether tag is definition or reference\nS       signature      no      NONE             s--    no    rw   0 Signature of routine (e.g. prototype or parameter list)\nT       epoch          no      NONE             -i-    no    --   0 the last modified time of the input file (only for F/file kind tag)\nZ       scope          no      NONE             s--    no    rw   0 [tags output] prepend \"scope:\" key to s/scope field output, [xref and json output] the same as s/ field\na       access         no      NONE             s--    no    rw   0 Access (or export) of class members\ne       end            no      NONE             -i-    no    rw   0 end lines of various items\nf       file           no      NONE             --b    no    --   0 File-restricted scoping\ni       inherits       no      NONE             s-b    no    -w   0 Inheritance information\nk       NONE           no      NONE             s--    no    --   0 Kind of tag in one-letter form\nl       language       no      NONE             s--    no    r-   0 Language of input file containing tag\nm       implementation no      NONE             s--    no    --   0 Implementation information\nn       line           yes     NONE             -i-    no    rw   0 Line number of tag definition\no       nth            no      NONE             -i-    no    --   0 the order in the parent scope\np       scopeKind      no      NONE             s--    no    --   0 [tags output] no effect, [xref and json output] kind of scope in long-name form\nr       roles          no      NONE             s--    no    r-   0 Roles\ns       NONE           no      NONE             s--    no    --   0 [tags output] scope (kind:name) of tag definition, [xref and json output] name of scope\nt       typeref        no      NONE             s--    no    rw   0 Type and name of a variable or typedef\nx       xpath          no      NONE             s--    no    --   0 xpath for the tag\nz       kind           no      NONE             s--    no    r-   0 [tags output] prepend \"kind:\" to k/ (or K/) field output, [xref and json output] kind in long-name form\n# --fields=n --output-format=json --list-fields\n#LETTER NAME           ENABLED LANGUAGE         JSTYPE FIXED OP VER DESCRIPTION\nC       compact        no      NONE             s--    no    --   0 compact input line (used only in xref output)\nE       extras         no      NONE             s--    no    r-   0 Extra tag type information\nF       input          no      NONE             s--    no    r-   0 input file\nK       NONE           no      NONE             s--    no    --   0 Kind of tag in long-name form\nN       name           no      NONE             s--    no    rw   0 tag name\nP       pattern        no      NONE             s-b    no    --   0 pattern\nR       NONE           no      NONE             s--    no    --   0 Marker (R or D) representing whether tag is definition or reference\nS       signature      no      NONE             s--    no    rw   0 Signature of routine (e.g. prototype or parameter list)\nT       epoch          no      NONE             -i-    no    --   0 the last modified time of the input file (only for F/file kind tag)\nZ       scope          no      NONE             s--    no    rw   0 [tags output] prepend \"scope:\" key to s/scope field output, [xref and json output] the same as s/ field\na       access         no      NONE             s--    no    rw   0 Access (or export) of class members\ne       end            no      NONE             -i-    no    rw   0 end lines of various items\nf       file           no      NONE             --b    no    --   0 File-restricted scoping\ni       inherits       no      NONE             s-b    no    -w   0 Inheritance information\nk       NONE           no      NONE             s--    no    --   0 Kind of tag in one-letter form\nl       language       no      NONE             s--    no    r-   0 Language of input file containing tag\nm       implementation no      NONE             s--    no    --   0 Implementation information\nn       line           yes     NONE             -i-    no    rw   0 Line number of tag definition\no       nth            no      NONE             -i-    no    --   0 the order in the parent scope\np       scopeKind      no      NONE             s--    no    --   0 [tags output] no effect, [xref and json output] kind of scope in long-name form\nr       roles          no      NONE             s--    no    r-   0 Roles\ns       NONE           no      NONE             s--    no    --   0 [tags output] scope (kind:name) of tag definition, [xref and json output] name of scope\nt       typeref        no      NONE             s--    no    rw   0 Type and name of a variable or typedef\nx       xpath          no      NONE             s--    no    --   0 xpath for the tag\nz       kind           no      NONE             s--    no    r-   0 [tags output] prepend \"kind:\" to k/ (or K/) field output, [xref and json output] kind in long-name form\n"
  },
  {
    "path": "Tmain/list-fields-none.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/list-fields-none.d/run.sh",
    "content": "# Copyright: 2022 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n$CTAGS --quiet --options=NONE --list-fields=NONE | grep -v xpath\n"
  },
  {
    "path": "Tmain/list-fields-none.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-fields-none.d/stdout-expected.txt",
    "content": "#LETTER NAME           ENABLED LANGUAGE JSTYPE FIXED OP VER DESCRIPTION\nN       name           yes     NONE     s--    yes   rw   0 tag name\nF       input          yes     NONE     s--    yes   r-   0 input file\nP       pattern        yes     NONE     s-b    yes   --   0 pattern\nC       compact        no      NONE     s--    no    --   0 compact input line (used only in xref output)\nE       extras         no      NONE     s--    no    r-   0 Extra tag type information\nK       NONE           no      NONE     s--    no    --   0 Kind of tag in long-name form\nR       NONE           no      NONE     s--    no    --   0 Marker (R or D) representing whether tag is definition or reference\nS       signature      no      NONE     s--    no    rw   0 Signature of routine (e.g. prototype or parameter list)\nT       epoch          yes     NONE     -i-    no    --   0 the last modified time of the input file (only for F/file kind tag)\nZ       scope          no      NONE     s--    no    rw   0 [tags output] prepend \"scope:\" key to s/scope field output, [xref and json output] the same as s/ field\na       access         no      NONE     s--    no    rw   0 Access (or export) of class members\ne       end            no      NONE     -i-    no    rw   0 end lines of various items\nf       file           yes     NONE     --b    no    --   0 File-restricted scoping\ni       inherits       no      NONE     s-b    no    -w   0 Inheritance information\nk       NONE           yes     NONE     s--    no    --   0 Kind of tag in one-letter form\nl       language       no      NONE     s--    no    r-   0 Language of input file containing tag\nm       implementation no      NONE     s--    no    --   0 Implementation information\nn       line           no      NONE     -i-    no    rw   0 Line number of tag definition\no       nth            no      NONE     -i-    no    --   0 the order in the parent scope\np       scopeKind      no      NONE     s--    no    --   0 [tags output] no effect, [xref and json output] kind of scope in long-name form\nr       roles          no      NONE     s--    no    r-   0 Roles\ns       NONE           yes     NONE     s--    no    --   0 [tags output] scope (kind:name) of tag definition, [xref and json output] name of scope\nt       typeref        yes     NONE     s--    no    rw   0 Type and name of a variable or typedef\nz       kind           no      NONE     s--    no    r-   0 [tags output] prepend \"kind:\" to k/ (or K/) field output, [xref and json output] kind in long-name form\n"
  },
  {
    "path": "Tmain/list-fields-with-prefix.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\nCTAGS=$1\n\nignore_xpath ()\n{\n    grep -v Maven2 | grep -v XML\n}\n\n$CTAGS --quiet --options=NONE --put-field-prefix --list-fields \\\n    | grep UCTAGS \\\n    | ignore_xpath\n"
  },
  {
    "path": "Tmain/list-fields-with-prefix.d/stdout-expected.txt",
    "content": "E       UCTAGSextras         no      NONE             s--    no    r-   0 Extra tag type information\nT       UCTAGSepoch          yes     NONE             -i-    no    --   0 the last modified time of the input file (only for F/file kind tag)\nZ       UCTAGSscope          no      NONE             s--    no    rw   0 [tags output] prepend \"scope:\" key to s/scope field output, [xref and json output] the same as s/ field\ne       UCTAGSend            no      NONE             -i-    no    rw   0 end lines of various items\no       UCTAGSnth            no      NONE             -i-    no    --   0 the order in the parent scope\np       UCTAGSscopeKind      no      NONE             s--    no    --   0 [tags output] no effect, [xref and json output] kind of scope in long-name form\nr       UCTAGSroles          no      NONE             s--    no    r-   0 Roles\nx       UCTAGSxpath          no      NONE             s--    no    --   0 xpath for the tag\n-       UCTAGSproperties     yes     Asm              s--    no    --   0 properties (req, vararg for parameters)\n-       UCTAGSproperties     no      AutoIt           s--    no    --   0 properties (static, volatile, ...)\n-       UCTAGSalias          no      C                s--    no    --   1 the name of the alias target specified in __attribute__((alias(...)))\n-       UCTAGSmacrodef       no      C                s--    no    --   0 macro definition\n-       UCTAGSproperties     no      C                s--    no    --   0 properties (static, inline, mutable, export,...)\n-       UCTAGSsection        no      C                s--    no    --   1 the place where the object is placed\n-       UCTAGSalias          no      C++              s--    no    --   1 the name of the alias target specified in __attribute__((alias(...)))\n-       UCTAGScaptures       no      C++              s--    no    --   0 lambda capture list\n-       UCTAGSmacrodef       no      C++              s--    no    --   0 macro definition\n-       UCTAGSname           yes     C++              s--    no    --   0 aliased names\n-       UCTAGSproperties     no      C++              s--    no    --   0 properties (static, inline, mutable, export,...)\n-       UCTAGSsection        no      C++              s--    no    --   1 the place where the object is placed\n-       UCTAGSspecialization no      C++              s--    no    --   0 template specialization parameters\n-       UCTAGStemplate       no      C++              s--    no    --   0 template parameters\n-       UCTAGSmacrodef       no      CPreProcessor    s--    no    --   0 macro definition\n-       UCTAGSalias          no      CUDA             s--    no    --   1 the name of the alias target specified in __attribute__((alias(...)))\n-       UCTAGSmacrodef       no      CUDA             s--    no    --   0 macro definition\n-       UCTAGSproperties     no      CUDA             s--    no    --   0 properties (static, inline, mutable, export,...)\n-       UCTAGSsection        no      CUDA             s--    no    --   1 the place where the object is placed\n-       UCTAGSmoduleName     yes     Elm              s--    no    --   0 actual name of renamed module\n-       UCTAGSdefiner        yes     EmacsLisp        s--    no    --   1 the name of the function or macro that defines the unknown/Y-kind object\n-       UCTAGSannotations    yes     GDScript         s--    no    --   0 annotations on functions and variables\n-       UCTAGShowImported    no      Go               s--    no    --   0 how the package is imported (\"inline\" for `.' or \"init\" for `_')\n-       UCTAGSpackage        yes     Go               s--    no    --   0 the real package specified by the package name\n-       UCTAGSpackageName    yes     Go               s--    no    --   0 the name for referring the package\n-       UCTAGSreceiver       no      Go               s--    no    --   1 the name of the receiver\n-       UCTAGSimplements     yes     Inko             s--    no    rw   0 Trait being implemented\n-       UCTAGSproperties     no      JavaScript       s--    no    --   2 properties (static)\n-       UCTAGSassignment     yes     LdScript         s--    no    --   0 how a value is assigned to the symbol\n-       UCTAGSdefiner        yes     Lisp             s--    no    --   1 the name of the function or macro that defines the unknown/Y-kind object\n-       UCTAGSsectionMarker  no      Markdown         s--    no    --   0 character used for declaring section(#, ##, =, or -)\n-       UCTAGSwrapping       yes     Moose            s--    no    --   0 how a wrapper wrapping the method (around, after, or before)\n-       UCTAGSlangid         yes     NSIS             s--    no    --   0 language identifier specified in (License)LangString commands\n-       UCTAGScategory       yes     ObjectiveC       s--    no    --   0 category attached to the class\n-       UCTAGSprotocols      yes     ObjectiveC       s--    no    --   0 protocols that the class (or category) confirms to\n-       UCTAGSimportName     yes     Odin             s--    no    --   0 import name for the imported entity\n-       UCTAGShome           yes     Passwd           s--    no    rw   0 home directory\n-       UCTAGSshell          yes     Passwd           s--    no    rw   0 login shell\n-       UCTAGSarity          yes     Prolog           -i-    no    --   0 the number of parameters\n-       UCTAGSdecorators     no      Python           s--    no    --   0 decorators on functions and classes\n-       UCTAGSnameref        yes     Python           s--    no    --   0 the original name for the tag\n-       UCTAGSassignmentop   no      R                s--    no    --   0 operator for assignment\n-       UCTAGSconstructor    yes     R                s--    no    --   0 function used for making value assigned to the nameattr tag\n-       UCTAGSoverline       no      ReStructuredText --b    no    --   0 whether using overline & underline for declaring section\n-       UCTAGSsectionMarker  no      ReStructuredText s--    no    --   0 character used for declaring section\n-       UCTAGSmixin          yes     Ruby             s--    no    --   0 how the class or module is mixed in (mixin:HOW:MODULE)\n-       UCTAGSmacro          yes     Rust             s--    no    --   1 macro invocation containing the definition\n-       UCTAGSmodule         yes     SCSS             s--    no    rw   1 the name of module behind the namespace\n-       UCTAGSdefiner        yes     Scheme           s--    no    --   1 the name of the function or macro that defines the unknown/Y-kind object\n-       UCTAGSparameter      no      SystemVerilog    --b    no    --   0 parameter whose value can be overridden.\n-       UCTAGStarget         yes     Thrift           s--    no    --   0 the target language specified at \"namespace\"\n-       UCTAGSthrows         yes     Thrift           s--    no    --   0 throws list of function\n-       UCTAGSproperties     no      TypeScript       s--    no    --   1 properties (static)\n-       UCTAGSarchitecture   yes     VHDL             s--    no    --   0 architecture designing the entity\n-       UCTAGSparameter      no      Verilog          --b    no    --   0 parameter whose value can be overridden.\n"
  },
  {
    "path": "Tmain/list-fields.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/list-fields.d/input.c",
    "content": "#include <stdio.h>\nstruct X {\n  int i;\n};\n\nstruct Y {\n  int j;\n  struct X x;\n};\n\nint main(void)\n{\n  return 0;\n}\n\n"
  },
  {
    "path": "Tmain/list-fields.d/input.java",
    "content": "abstract public class Foo extends Bar\n{\n    public int x;\n};\n"
  },
  {
    "path": "Tmain/list-fields.d/input.sh",
    "content": "source x\nfunction y()\n{\n}\n\n"
  },
  {
    "path": "Tmain/list-fields.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nwith_field()\n{\n    local field=$1\n    local lang=$2\n    : &&\n\techo \"#$field\" &&\n\t$CTAGS --quiet --options=NONE $3 --machinable --fields=$field -o - input.$lang\n}\n\nignore_xpath ()\n{\n    grep -v Maven2 | grep -v XML\n}\n\n: &&\n    $CTAGS --quiet --options=NONE --machinable --with-list-header --list-fields  \\\n\t| ignore_xpath &&\n    with_field \"\" java &&\n    with_field a  java &&\n    with_field i  java &&\n    with_field kz java &&\n    with_field Kz java &&\n    with_field k  java &&\n    with_field K  java &&\n    with_field l  java &&\n    with_field m  java &&\n    with_field n  java &&\n    with_field s  java &&\n    with_field sZ java &&\n    with_field f  c &&\n    with_field S  c &&\n    with_field t  c &&\n    with_field r  sh --extras=+r &&\n    with_field r  sh \"--extras=+r -x --_xformat=%R/%r\"\n"
  },
  {
    "path": "Tmain/list-fields.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-fields.d/stdout-expected.txt",
    "content": "#LETTER\tNAME\tENABLED\tLANGUAGE\tJSTYPE\tFIXED\tOP\tVER\tDESCRIPTION\nN\tname\tyes\tNONE\ts--\tyes\trw\t0\ttag name\nF\tinput\tyes\tNONE\ts--\tyes\tr-\t0\tinput file\nP\tpattern\tyes\tNONE\ts-b\tyes\t--\t0\tpattern\nC\tcompact\tno\tNONE\ts--\tno\t--\t0\tcompact input line (used only in xref output)\nE\textras\tno\tNONE\ts--\tno\tr-\t0\tExtra tag type information\nK\tNONE\tno\tNONE\ts--\tno\t--\t0\tKind of tag in long-name form\nR\tNONE\tno\tNONE\ts--\tno\t--\t0\tMarker (R or D) representing whether tag is definition or reference\nS\tsignature\tno\tNONE\ts--\tno\trw\t0\tSignature of routine (e.g. prototype or parameter list)\nT\tepoch\tyes\tNONE\t-i-\tno\t--\t0\tthe last modified time of the input file (only for F/file kind tag)\nZ\tscope\tno\tNONE\ts--\tno\trw\t0\t[tags output] prepend \"scope:\" key to s/scope field output, [xref and json output] the same as s/ field\na\taccess\tno\tNONE\ts--\tno\trw\t0\tAccess (or export) of class members\ne\tend\tno\tNONE\t-i-\tno\trw\t0\tend lines of various items\nf\tfile\tyes\tNONE\t--b\tno\t--\t0\tFile-restricted scoping\ni\tinherits\tno\tNONE\ts-b\tno\t-w\t0\tInheritance information\nk\tNONE\tyes\tNONE\ts--\tno\t--\t0\tKind of tag in one-letter form\nl\tlanguage\tno\tNONE\ts--\tno\tr-\t0\tLanguage of input file containing tag\nm\timplementation\tno\tNONE\ts--\tno\t--\t0\tImplementation information\nn\tline\tno\tNONE\t-i-\tno\trw\t0\tLine number of tag definition\no\tnth\tno\tNONE\t-i-\tno\t--\t0\tthe order in the parent scope\np\tscopeKind\tno\tNONE\ts--\tno\t--\t0\t[tags output] no effect, [xref and json output] kind of scope in long-name form\nr\troles\tno\tNONE\ts--\tno\tr-\t0\tRoles\ns\tNONE\tyes\tNONE\ts--\tno\t--\t0\t[tags output] scope (kind:name) of tag definition, [xref and json output] name of scope\nt\ttyperef\tyes\tNONE\ts--\tno\trw\t0\tType and name of a variable or typedef\nx\txpath\tno\tNONE\ts--\tno\t--\t0\txpath for the tag\nz\tkind\tno\tNONE\ts--\tno\tr-\t0\t[tags output] prepend \"kind:\" to k/ (or K/) field output, [xref and json output] kind in long-name form\n-\tproperties\tyes\tAsm\ts--\tno\t--\t0\tproperties (req, vararg for parameters)\n-\tproperties\tno\tAutoIt\ts--\tno\t--\t0\tproperties (static, volatile, ...)\n-\talias\tno\tC\ts--\tno\t--\t1\tthe name of the alias target specified in __attribute__((alias(...)))\n-\tmacrodef\tno\tC\ts--\tno\t--\t0\tmacro definition\n-\tproperties\tno\tC\ts--\tno\t--\t0\tproperties (static, inline, mutable, export,...)\n-\tsection\tno\tC\ts--\tno\t--\t1\tthe place where the object is placed\n-\talias\tno\tC++\ts--\tno\t--\t1\tthe name of the alias target specified in __attribute__((alias(...)))\n-\tcaptures\tno\tC++\ts--\tno\t--\t0\tlambda capture list\n-\tmacrodef\tno\tC++\ts--\tno\t--\t0\tmacro definition\n-\tname\tyes\tC++\ts--\tno\t--\t0\taliased names\n-\tproperties\tno\tC++\ts--\tno\t--\t0\tproperties (static, inline, mutable, export,...)\n-\tsection\tno\tC++\ts--\tno\t--\t1\tthe place where the object is placed\n-\tspecialization\tno\tC++\ts--\tno\t--\t0\ttemplate specialization parameters\n-\ttemplate\tno\tC++\ts--\tno\t--\t0\ttemplate parameters\n-\tmacrodef\tno\tCPreProcessor\ts--\tno\t--\t0\tmacro definition\n-\talias\tno\tCUDA\ts--\tno\t--\t1\tthe name of the alias target specified in __attribute__((alias(...)))\n-\tmacrodef\tno\tCUDA\ts--\tno\t--\t0\tmacro definition\n-\tproperties\tno\tCUDA\ts--\tno\t--\t0\tproperties (static, inline, mutable, export,...)\n-\tsection\tno\tCUDA\ts--\tno\t--\t1\tthe place where the object is placed\n-\tmoduleName\tyes\tElm\ts--\tno\t--\t0\tactual name of renamed module\n-\tdefiner\tyes\tEmacsLisp\ts--\tno\t--\t1\tthe name of the function or macro that defines the unknown/Y-kind object\n-\tannotations\tyes\tGDScript\ts--\tno\t--\t0\tannotations on functions and variables\n-\thowImported\tno\tGo\ts--\tno\t--\t0\thow the package is imported (\"inline\" for `.' or \"init\" for `_')\n-\tpackage\tyes\tGo\ts--\tno\t--\t0\tthe real package specified by the package name\n-\tpackageName\tyes\tGo\ts--\tno\t--\t0\tthe name for referring the package\n-\treceiver\tno\tGo\ts--\tno\t--\t1\tthe name of the receiver\n-\timplements\tyes\tInko\ts--\tno\trw\t0\tTrait being implemented\n-\tproperties\tno\tJavaScript\ts--\tno\t--\t2\tproperties (static)\n-\tassignment\tyes\tLdScript\ts--\tno\t--\t0\thow a value is assigned to the symbol\n-\tdefiner\tyes\tLisp\ts--\tno\t--\t1\tthe name of the function or macro that defines the unknown/Y-kind object\n-\tsectionMarker\tno\tMarkdown\ts--\tno\t--\t0\tcharacter used for declaring section(#, ##, =, or -)\n-\twrapping\tyes\tMoose\ts--\tno\t--\t0\thow a wrapper wrapping the method (around, after, or before)\n-\tlangid\tyes\tNSIS\ts--\tno\t--\t0\tlanguage identifier specified in (License)LangString commands\n-\tcategory\tyes\tObjectiveC\ts--\tno\t--\t0\tcategory attached to the class\n-\tprotocols\tyes\tObjectiveC\ts--\tno\t--\t0\tprotocols that the class (or category) confirms to\n-\timportName\tyes\tOdin\ts--\tno\t--\t0\timport name for the imported entity\n-\thome\tyes\tPasswd\ts--\tno\trw\t0\thome directory\n-\tshell\tyes\tPasswd\ts--\tno\trw\t0\tlogin shell\n-\tarity\tyes\tProlog\t-i-\tno\t--\t0\tthe number of parameters\n-\tdecorators\tno\tPython\ts--\tno\t--\t0\tdecorators on functions and classes\n-\tnameref\tyes\tPython\ts--\tno\t--\t0\tthe original name for the tag\n-\tassignmentop\tno\tR\ts--\tno\t--\t0\toperator for assignment\n-\tconstructor\tyes\tR\ts--\tno\t--\t0\tfunction used for making value assigned to the nameattr tag\n-\toverline\tno\tReStructuredText\t--b\tno\t--\t0\twhether using overline & underline for declaring section\n-\tsectionMarker\tno\tReStructuredText\ts--\tno\t--\t0\tcharacter used for declaring section\n-\tmixin\tyes\tRuby\ts--\tno\t--\t0\thow the class or module is mixed in (mixin:HOW:MODULE)\n-\tmacro\tyes\tRust\ts--\tno\t--\t1\tmacro invocation containing the definition\n-\tmodule\tyes\tSCSS\ts--\tno\trw\t1\tthe name of module behind the namespace\n-\tdefiner\tyes\tScheme\ts--\tno\t--\t1\tthe name of the function or macro that defines the unknown/Y-kind object\n-\tparameter\tno\tSystemVerilog\t--b\tno\t--\t0\tparameter whose value can be overridden.\n-\ttarget\tyes\tThrift\ts--\tno\t--\t0\tthe target language specified at \"namespace\"\n-\tthrows\tyes\tThrift\ts--\tno\t--\t0\tthrows list of function\n-\tproperties\tno\tTypeScript\ts--\tno\t--\t1\tproperties (static)\n-\tarchitecture\tyes\tVHDL\ts--\tno\t--\t0\tarchitecture designing the entity\n-\tparameter\tno\tVerilog\t--b\tno\t--\t0\tparameter whose value can be overridden.\n#\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/\nx\tinput.java\t/^    public int x;$/\n#a\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/\nx\tinput.java\t/^    public int x;$/;\"\taccess:public\n#i\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/;\"\tinherits:Bar\nx\tinput.java\t/^    public int x;$/\n#kz\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/;\"\tkind:c\nx\tinput.java\t/^    public int x;$/;\"\tkind:f\n#Kz\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/;\"\tkind:class\nx\tinput.java\t/^    public int x;$/;\"\tkind:field\n#k\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/;\"\tc\nx\tinput.java\t/^    public int x;$/;\"\tf\n#K\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/;\"\tclass\nx\tinput.java\t/^    public int x;$/;\"\tfield\n#l\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/;\"\tlanguage:Java\nx\tinput.java\t/^    public int x;$/;\"\tlanguage:Java\n#m\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/;\"\timplementation:abstract\nx\tinput.java\t/^    public int x;$/\n#n\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/;\"\tline:1\nx\tinput.java\t/^    public int x;$/;\"\tline:3\n#s\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/\nx\tinput.java\t/^    public int x;$/;\"\tclass:Foo\n#sZ\nFoo\tinput.java\t/^abstract public class Foo extends Bar$/\nx\tinput.java\t/^    public int x;$/;\"\tscope:class:Foo\n#f\nX\tinput.c\t/^struct X {$/;\"\tfile:\nY\tinput.c\t/^struct Y {$/;\"\tfile:\ni\tinput.c\t/^  int i;$/;\"\tfile:\nj\tinput.c\t/^  int j;$/;\"\tfile:\nmain\tinput.c\t/^int main(void)$/\nx\tinput.c\t/^  struct X x;$/;\"\tfile:\n#S\nX\tinput.c\t/^struct X {$/\nY\tinput.c\t/^struct Y {$/\ni\tinput.c\t/^  int i;$/\nj\tinput.c\t/^  int j;$/\nmain\tinput.c\t/^int main(void)$/;\"\tsignature:(void)\nx\tinput.c\t/^  struct X x;$/\n#t\nX\tinput.c\t/^struct X {$/\nY\tinput.c\t/^struct Y {$/\ni\tinput.c\t/^  int i;$/;\"\ttyperef:typename:int\nj\tinput.c\t/^  int j;$/;\"\ttyperef:typename:int\nmain\tinput.c\t/^int main(void)$/;\"\ttyperef:typename:int\nx\tinput.c\t/^  struct X x;$/;\"\ttyperef:struct:X\n#r\nx\tinput.sh\t/^source x$/;\"\troles:loaded\ny\tinput.sh\t/^function y()$/;\"\troles:def\n#r\nD/def\nR/loaded\n"
  },
  {
    "path": "Tmain/list-kinds-full.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/list-kinds-full.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --machinable --with-list-header --list-kinds-full=C\n${CTAGS} --quiet --options=NONE --machinable --with-list-header --list-kinds-full=C++\n\n"
  },
  {
    "path": "Tmain/list-kinds-full.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-kinds-full.d/stdout-expected.txt",
    "content": "#LETTER\tNAME\tENABLED\tREFONLY\tNROLES\tMASTER\tVER\tDESCRIPTION\nD\tmacroparam\tno\tno\t0\tC\t0\tparameters inside macro definitions\nL\tlabel\tno\tno\t0\tC\t0\tgoto labels\nd\tmacro\tyes\tno\t2\tC\t0\tmacro definitions\ne\tenumerator\tyes\tno\t0\tC\t0\tenumerators (values inside an enumeration)\nf\tfunction\tyes\tno\t2\tC\t0\tfunction definitions\ng\tenum\tyes\tno\t0\tC\t0\tenumeration names\nh\theader\tyes\tyes\t2\tC\t0\tincluded header files\nl\tlocal\tno\tno\t0\tC\t0\tlocal variables\nm\tmember\tyes\tno\t0\tC\t0\tstruct, and union members\np\tprototype\tno\tno\t0\tC\t0\tfunction prototypes\ns\tstruct\tyes\tno\t1\tC\t0\tstructure names\nt\ttypedef\tyes\tno\t0\tC\t0\ttypedefs\nu\tunion\tyes\tno\t0\tC\t0\tunion names\nv\tvariable\tyes\tno\t0\tC\t0\tvariable definitions\nx\texternvar\tno\tno\t0\tC\t0\texternal and forward variable declarations\nz\tparameter\tno\tno\t0\tC\t0\tfunction parameters inside function or prototype definitions\n#LETTER\tNAME\tENABLED\tREFONLY\tNROLES\tMASTER\tVER\tDESCRIPTION\nA\talias\tno\tno\t0\tNONE\t0\tnamespace aliases\nD\tmacroparam\tno\tno\t0\tC\t0\tparameters inside macro definitions\nL\tlabel\tno\tno\t0\tC\t0\tgoto labels\nM\tmodule\tyes\tno\t2\tNONE\t2\tmodules\nN\tname\tno\tno\t0\tNONE\t0\tnames imported via using scope::symbol\nP\tpartition\tyes\tno\t1\tNONE\t2\tpartitions\nU\tusing\tno\tno\t0\tNONE\t0\tusing namespace statements\nZ\ttparam\tno\tno\t0\tNONE\t0\ttemplate parameters\nc\tclass\tyes\tno\t0\tNONE\t0\tclasses\nd\tmacro\tyes\tno\t2\tC\t0\tmacro definitions\ne\tenumerator\tyes\tno\t0\tC\t0\tenumerators (values inside an enumeration)\nf\tfunction\tyes\tno\t0\tC\t0\tfunction definitions\ng\tenum\tyes\tno\t0\tC\t0\tenumeration names\nh\theader\tyes\tyes\t4\tC\t0\tincluded header files\nl\tlocal\tno\tno\t0\tC\t0\tlocal variables\nm\tmember\tyes\tno\t0\tC\t0\tclass, struct, and union members\nn\tnamespace\tyes\tno\t0\tNONE\t0\tnamespaces\np\tprototype\tno\tno\t0\tC\t0\tfunction prototypes\ns\tstruct\tyes\tno\t0\tC\t0\tstructure names\nt\ttypedef\tyes\tno\t0\tC\t0\ttypedefs\nu\tunion\tyes\tno\t0\tC\t0\tunion names\nv\tvariable\tyes\tno\t0\tC\t0\tvariable definitions\nx\texternvar\tno\tno\t0\tC\t0\texternal and forward variable declarations\nz\tparameter\tno\tno\t0\tC\t0\tfunction parameters inside function or prototype definitions\n"
  },
  {
    "path": "Tmain/list-language-fields.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n$CTAGS --quiet --options=NONE --machinable --with-list-header \\\n       --list-fields=reStructuredText\n\n"
  },
  {
    "path": "Tmain/list-language-fields.d/stdout-expected.txt",
    "content": "#LETTER\tNAME\tENABLED\tLANGUAGE\tJSTYPE\tFIXED\tOP\tVER\tDESCRIPTION\n-\toverline\tno\tReStructuredText\t--b\tno\t--\t0\twhether using overline & underline for declaring section\n-\tsectionMarker\tno\tReStructuredText\ts--\tno\t--\t0\tcharacter used for declaring section\n"
  },
  {
    "path": "Tmain/list-language-flags.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/list-language-flags.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n: &&\n\techo langdef-flags: &&\n\t${CTAGS} --quiet --options=NONE --_list-langdef-flags &&\n\techo fielddef-flags: &&\n\t${CTAGS} --quiet --options=NONE --_list-fielddef-flags &&\n\techo kinddef-flags: &&\n\t${CTAGS} --quiet --options=NONE --_list-kinddef-flags &&\n\techo roledef-flags: &&\n\t${CTAGS} --quiet --options=NONE --_list-roledef-flags &&\n\techo extradef-flags: &&\n\t${CTAGS} --quiet --options=NONE --_list-extradef-flags &&\n\t:\n"
  },
  {
    "path": "Tmain/list-language-flags.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-language-flags.d/stdout-expected.txt",
    "content": "langdef-flags:\n#LETTER NAME                  DESCRIPTION\n-       base=BASEPARSER       utilize as a base parser\n-       bidirectional         utilize the base parser both 'dedicated' and 'shared' way\n-       dedicated             make the base parser dedicated to this subparser\n-       shared                share the base parser with the other subparsers\n-       version=CURRENT.AGE   set the version of the parser\n-       _autoFQTag            make full qualified tags automatically based on scope information\n-       _foreignLanguage=LANG initialize another parser\nfielddef-flags:\n#LETTER NAME            DESCRIPTION\n-       datatype=TYPE   acceptable datatype of the field (str|bool|int|str+bool)\n-       version=VERSION in which version of the parser this field is added\nkinddef-flags:\n#LETTER NAME            DESCRIPTION\n-       version=VERSION in which version of the parser this kind is added\n-       _refonly        use this kind reference tags only\nroledef-flags:\n#LETTER NAME            DESCRIPTION\n-       version=VERSION in which version of the parser this role is added\nextradef-flags:\n#LETTER NAME            DESCRIPTION\n-       version=VERSION in which version of the parser this extra is added\n"
  },
  {
    "path": "Tmain/list-map-extensions.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho '## all|grep LdScript'\n$CTAGS --quiet --options=NONE --list-map-extensions=all | grep '^#\\|LdScript'\n\necho '## LdScript'\n$CTAGS --quiet --options=NONE --list-map-extensions=LdScript\n"
  },
  {
    "path": "Tmain/list-map-extensions.d/stdout-expected.txt",
    "content": "## all|grep LdScript\n#LANGUAGE               EXTENSION\nLdScript                lds\nLdScript                scr\nLdScript                ld\nLdScript                ldi\n## LdScript\n#EXTENSION\nlds\nscr\nld\nldi\n"
  },
  {
    "path": "Tmain/list-map-patterns.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho '## all|grep LdScript'\n$CTAGS --quiet --options=NONE --list-map-patterns=all | grep '^#\\|LdScript'\n\necho '## LdScript'\n$CTAGS --quiet --options=NONE --list-map-patterns=LdScript\n"
  },
  {
    "path": "Tmain/list-map-patterns.d/stdout-expected.txt",
    "content": "## all|grep LdScript\n#LANGUAGE          PATTERN\nLdScript           *.lds.S\nLdScript           *.ld.S\nLdScript           ld.script\n## LdScript\n#PATTERN\n*.lds.S\n*.ld.S\nld.script\n"
  },
  {
    "path": "Tmain/list-map-rexprs.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/list-map-rexprs.d/run.sh",
    "content": "# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n$CTAGS --quiet --options=NONE \\\n\t   --langdef=Something \\\n\t   --map-Something='%\\%ESCAPING\\%%' \\\n\t   --map-Something=+'%ICASE%i' \\\n\t   --map-Something=+'%TEMP%' \\\n\t   --map-Something=-'%TEMP%' \\\n\t   --map-Something=+'%TEMPi%i' \\\n\t   --map-Something=-'%TEMPi%i' \\\n\t   --list-map-rexprs=Something\n\n$CTAGS --quiet --options=NONE \\\n\t   --langdef=Something \\\n\t   --map-Something='%aExpr%' \\\n\t   --map-Something=+'%\\%ESCAPING\\%%' \\\n\t   --map-Something=+'%ICASE%i' \\\n\t   --map-Something=+'%TEMP%' \\\n\t   --map-Something=-'%TEMP%' \\\n\t   --map-Something=+'%TEMPi%i' \\\n\t   --map-Something=-'%TEMPi%i' \\\n\t   --list-maps=Something\n\n$CTAGS --quiet --options=NONE \\\n\t   --langdef=Something \\\n\t   --kinddef-Something=t,type,types \\\n\t   --fields=+'{language}' \\\n\t   --regex-Something='/^([a-z]+)[ \\t]+tdef;$/\\1/t/' \\\n\t   \\\n\t   --map-Something='%something/.*\\.c%' \\\n\t   --map-Something=+'%something/.*\\.cpp%i' \\\n\t   --map-Something=+'%something/.*\\.h%{icase}' \\\n\t   \\\n\t   -x --_xformat='%10N %{language}' \\\n\t   -R something\n"
  },
  {
    "path": "Tmain/list-map-rexprs.d/something/input.CPP",
    "content": "float tdef;\n"
  },
  {
    "path": "Tmain/list-map-rexprs.d/something/input.c",
    "content": "int tdef;\n"
  },
  {
    "path": "Tmain/list-map-rexprs.d/something/input.h",
    "content": "double tdef;\n"
  },
  {
    "path": "Tmain/list-map-rexprs.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-map-rexprs.d/stdout-expected.txt",
    "content": "#EXPRESSION CASE\n%ESCAPING%  sensitive\nICASE       insensitive\nSomething %aExpr% %\\%ESCAPING\\%% %ICASE%i\n       int Something\n     float Something\n    double Something\n"
  },
  {
    "path": "Tmain/list-mline-regex-flags.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nis_feature_available ${CTAGS} pcre2\n\n${CTAGS} --quiet --options=NONE --list-mline-regex-flags\n"
  },
  {
    "path": "Tmain/list-mline-regex-flags.d/stdout-expected.txt",
    "content": "#LETTER NAME                                          DESCRIPTION\nb       basic                                         interpreted as a Posix basic regular expression.\ne       extend                                        interpreted as a Posix extended regular expression (default)\ni       icase                                         applied in a case-insensitive manner\np       pcre2                                         use pcre2 regex engine\n-       fatal=\"MESSAGE\"                               print the given MESSAGE and exit\n-       mgroup=N                                      a group in pattern determining the line number of tag\n-       scope=intervaltab                             set scope for the tag with the interval table\n-       warning=\"MESSAGE\"                             print the given MESSAGE at WARNING level\n-       _advanceTo=N[start|end]                       a group in pattern from where the next scan starts [0end]\n-       _anonymous=PREFIX                             make an anonymous tag with PREFIX\n-       _extra=EXTRA                                  record the tag only when the (foreign) extra is enabled\n-       _field=FIELD:VALUE                            record the matched string(VALUE) to the (foreign) language specific FIELD of the tag\n-       _guest=PARSERSPEC,N0[start|end],N1[start|end] run guest parser on the area\n-       _language=LANG                                make a foreign tag for LANG\n-       _role=ROLE                                    set the given ROLE to the roles field\n"
  },
  {
    "path": "Tmain/list-mtable-regex-flags.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nis_feature_available ${CTAGS} pcre2\n\n${CTAGS} --quiet --options=NONE --_list-mtable-regex-flags\n"
  },
  {
    "path": "Tmain/list-mtable-regex-flags.d/stdout-expected.txt",
    "content": "#LETTER NAME                                          DESCRIPTION\nb       basic                                         interpreted as a Posix basic regular expression.\ne       extend                                        interpreted as a Posix extended regular expression (default)\ni       icase                                         applied in a case-insensitive manner\np       pcre2                                         use pcre2 regex engine\n-       fatal=\"MESSAGE\"                               print the given MESSAGE and exit\n-       mgroup=N                                      a group in pattern determining the line number of tag\n-       placeholder                                   don't put this tag to tags file.\n-       scope=ACTION                                  use scope stack: ACTION = ref|push|pop|clear|set|replace|intervaltab\n-       tenter=TABLE[,CONT]                           enter to given regext table (with specifying continuation)\n-       tjump=TABLE                                   jump to another regext table(don't push the current table to state stack)\n-       tleave                                        leave from the current regext table\n-       tquit                                         stop the parsing with this parser\n-       treset=TABLE                                  clear the state stack and jump to given regex table\n-       warning=\"MESSAGE\"                             print the given MESSAGE at WARNING level\n-       _advanceTo=N[start|end]                       a group in pattern from where the next scan starts [0end]\n-       _anonymous=PREFIX                             make an anonymous tag with PREFIX\n-       _extra=EXTRA                                  record the tag only when the (foreign) extra is enabled\n-       _field=FIELD:VALUE                            record the matched string(VALUE) to the (foreign) language specific FIELD of the tag\n-       _guest=PARSERSPEC,N0[start|end],N1[start|end] run guest parser on the area\n-       _language=LANG                                make a foreign tag for LANG\n-       _role=ROLE                                    set the given ROLE to the roles field\n"
  },
  {
    "path": "Tmain/list-output-formats.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/list-output-formats.d/run.sh",
    "content": "# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n$CTAGS --quiet --options=NONE --machinable --with-list-header \\\n       --list-output-formats | grep -v '^json'\n"
  },
  {
    "path": "Tmain/list-output-formats.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-output-formats.d/stdout-expected.txt",
    "content": "#OFORMAT\tDEFAULT\tAVAILABLE\tNULLTAG\ne-ctags\tno\tyes\tno\netags\tno\tyes\tno\nu-ctags\tyes\tyes\tno\nxref\tno\tyes\tyes\n"
  },
  {
    "path": "Tmain/list-params.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nC=\"${CTAGS} --quiet --options=NONE\"\n\necho '# ALL'\n${C} --with-list-header=yes --list-params\necho\n\necho '# ALL MACHINABLE'\n${C} --with-list-header=yes --machinable --list-params\necho\n\necho '# ALL MACHINABLE NOHEADER'\n${C} --with-list-header=no  --machinable --list-params\necho\n\necho '# CPP'\n${C} --list-params=CPreProcessor\necho\n\necho '# CPP MACHINABLE'\n${C} --with-list-header=yes --machinable --list-params=CPreProcessor\necho\n\necho '# CPP MACHINABLE NOHEADER'\n${C} --with-list-header=no  --machinable --list-params=CPreProcessor\necho\n\necho '# CPP MACHINABLE NOHEADER + PARAM DEFINE WITH CMDLINE'\n${C} --_paramdef-CPreProcessor='pragma,handle program' --with-list-header=no  --machinable --list-params=CPreProcessor\necho\n"
  },
  {
    "path": "Tmain/list-params.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-params.d/stdout-expected.txt",
    "content": "# ALL\n#LANGUAGE      NAME                DESCRIPTION\nAsm            commentCharsAtBOL   line comment chraracters at the beginning of line ([;*@])\nAsm            commentCharsInMOL   line comment chraracters in the beginning of line ([])\nAsm            extraLinesepChars   extra characters used as a line separator ([])\nAsm            useCPreProcessor    run CPreProcessor parser for extracting macro definitions ([true] or false)\nCPreProcessor  _expand             expand macros if their definitions are in the current C/C++/CUDA input file (true or [false])\nCPreProcessor  define              define replacement for an identifier (name(params,...)=definition)\nCPreProcessor  if0                 examine code within \"#if 0\" branch (true or [false])\nCPreProcessor  ignore              a token to be specially handled\nFypp           guest               parser run after Fypp parser parses the original input (\"NONE\" or a parser name [Fortran])\nITcl           forceUse            enable the parser even when `itcl' namespace is not specified in the input (true or [false])\nProlog         allowNestedComments allow nested comments like \"/* /* */ */\" ([true] or false)\nTclOO          forceUse            enable the parser even when `oo' namespace is not specified in the input (true or [false])\n\n# ALL MACHINABLE\n#LANGUAGE\tNAME\tDESCRIPTION\nAsm\tcommentCharsAtBOL\tline comment chraracters at the beginning of line ([;*@])\nAsm\tcommentCharsInMOL\tline comment chraracters in the beginning of line ([])\nAsm\textraLinesepChars\textra characters used as a line separator ([])\nAsm\tuseCPreProcessor\trun CPreProcessor parser for extracting macro definitions ([true] or false)\nCPreProcessor\t_expand\texpand macros if their definitions are in the current C/C++/CUDA input file (true or [false])\nCPreProcessor\tdefine\tdefine replacement for an identifier (name(params,...)=definition)\nCPreProcessor\tif0\texamine code within \"#if 0\" branch (true or [false])\nCPreProcessor\tignore\ta token to be specially handled\nFypp\tguest\tparser run after Fypp parser parses the original input (\"NONE\" or a parser name [Fortran])\nITcl\tforceUse\tenable the parser even when `itcl' namespace is not specified in the input (true or [false])\nProlog\tallowNestedComments\tallow nested comments like \"/* /* */ */\" ([true] or false)\nTclOO\tforceUse\tenable the parser even when `oo' namespace is not specified in the input (true or [false])\n\n# ALL MACHINABLE NOHEADER\nAsm\tcommentCharsAtBOL\tline comment chraracters at the beginning of line ([;*@])\nAsm\tcommentCharsInMOL\tline comment chraracters in the beginning of line ([])\nAsm\textraLinesepChars\textra characters used as a line separator ([])\nAsm\tuseCPreProcessor\trun CPreProcessor parser for extracting macro definitions ([true] or false)\nCPreProcessor\t_expand\texpand macros if their definitions are in the current C/C++/CUDA input file (true or [false])\nCPreProcessor\tdefine\tdefine replacement for an identifier (name(params,...)=definition)\nCPreProcessor\tif0\texamine code within \"#if 0\" branch (true or [false])\nCPreProcessor\tignore\ta token to be specially handled\nFypp\tguest\tparser run after Fypp parser parses the original input (\"NONE\" or a parser name [Fortran])\nITcl\tforceUse\tenable the parser even when `itcl' namespace is not specified in the input (true or [false])\nProlog\tallowNestedComments\tallow nested comments like \"/* /* */ */\" ([true] or false)\nTclOO\tforceUse\tenable the parser even when `oo' namespace is not specified in the input (true or [false])\n\n# CPP\n#NAME    DESCRIPTION\n_expand  expand macros if their definitions are in the current C/C++/CUDA input file (true or [false])\ndefine   define replacement for an identifier (name(params,...)=definition)\nif0      examine code within \"#if 0\" branch (true or [false])\nignore   a token to be specially handled\n\n# CPP MACHINABLE\n#NAME\tDESCRIPTION\n_expand\texpand macros if their definitions are in the current C/C++/CUDA input file (true or [false])\ndefine\tdefine replacement for an identifier (name(params,...)=definition)\nif0\texamine code within \"#if 0\" branch (true or [false])\nignore\ta token to be specially handled\n\n# CPP MACHINABLE NOHEADER\n_expand\texpand macros if their definitions are in the current C/C++/CUDA input file (true or [false])\ndefine\tdefine replacement for an identifier (name(params,...)=definition)\nif0\texamine code within \"#if 0\" branch (true or [false])\nignore\ta token to be specially handled\n\n# CPP MACHINABLE NOHEADER + PARAM DEFINE WITH CMDLINE\n_expand\texpand macros if their definitions are in the current C/C++/CUDA input file (true or [false])\ndefine\tdefine replacement for an identifier (name(params,...)=definition)\nif0\texamine code within \"#if 0\" branch (true or [false])\nignore\ta token to be specially handled\npragma\thandle program\n\n"
  },
  {
    "path": "Tmain/list-pseudo-tags.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/list-pseudo-tags.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --list-pseudo-tags | grep -v ENCODING\n\n\n"
  },
  {
    "path": "Tmain/list-pseudo-tags.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-pseudo-tags.d/stdout-expected.txt",
    "content": "#NAME                     ENABLED VER DESCRIPTION\nJSON_OUTPUT_VERSION       off       0 the version of json output stream format\nTAG_EXTRA_DESCRIPTION     on        0 the names and descriptions of enabled extras\nTAG_FIELD_DESCRIPTION     on        0 the names and descriptions of enabled fields\nTAG_FILE_FORMAT           on        0 the version of tags file format\nTAG_FILE_SORTED           on        0 how tags are sorted\nTAG_KIND_DESCRIPTION      on        0 the letters, names and descriptions of enabled kinds in the language\nTAG_KIND_SEPARATOR        off       0 the separators used in kinds\nTAG_OUTPUT_EXCMD          on        0 the excmd: number, pattern, mixed, or combine\nTAG_OUTPUT_FILESEP        on        0 the separator used in file name (slash or backslash)\nTAG_OUTPUT_MODE           on        0 the output mode: u-ctags or e-ctags\nTAG_OUTPUT_VERSION        on        0 the version of the output interface (current.age)\nTAG_PARSER_VERSION        on        0 the version of the parser (current.age)\nTAG_PATTERN_LENGTH_LIMIT  on        0 the limit of pattern length\nTAG_PROC_CWD              on        0 the current working directory of the tags generator\nTAG_PROGRAM_AUTHOR        on        0 the author of this ctags implementation\nTAG_PROGRAM_NAME          on        0 the name of this ctags implementation\nTAG_PROGRAM_URL           on        0 the official site URL of this ctags implementation\nTAG_PROGRAM_VERSION       on        0 the version of this ctags implementation\nTAG_ROLE_DESCRIPTION      on        0 the names and descriptions of enabled roles\n"
  },
  {
    "path": "Tmain/list-regex-flags.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nis_feature_available ${CTAGS} pcre2\n\n${CTAGS} --quiet --options=NONE --list-regex-flags\n"
  },
  {
    "path": "Tmain/list-regex-flags.d/stdout-expected.txt",
    "content": "#LETTER NAME                                          DESCRIPTION\nb       basic                                         interpreted as a Posix basic regular expression.\ne       extend                                        interpreted as a Posix extended regular expression (default)\ni       icase                                         applied in a case-insensitive manner\np       pcre2                                         use pcre2 regex engine\nx       exclusive                                     skip testing the other patterns if a line is matched to this pattern\n-       fatal=\"MESSAGE\"                               print the given MESSAGE and exit\n-       placeholder                                   don't put this tag to tags file.\n-       postrun                                       run after parsing with built-in code, multline regex patterns, and multitable regex patterns\n-       scope=ACTION                                  use scope stack: ACTION = ref|push|pop|clear|set|replace|intervaltab\n-       warning=\"MESSAGE\"                             print the given MESSAGE at WARNING level\n-       _anonymous=PREFIX                             make an anonymous tag with PREFIX\n-       _extra=EXTRA                                  record the tag only when the (foreign) extra is enabled\n-       _field=FIELD:VALUE                            record the matched string(VALUE) to the (foreign) language specific FIELD of the tag\n-       _guest=PARSERSPEC,N0[start|end],N1[start|end] run guest parser on the area\n-       _language=LANG                                make a foreign tag for LANG\n-       _role=ROLE                                    set the given ROLE to the roles field\n"
  },
  {
    "path": "Tmain/list-roles-with-kind-names.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE\"\n\necho '{header}'\n${CTAGS} --list-roles=all.'{header}'\n\necho '{header}I'\n${CTAGS} --list-roles=all.'{header}I'\n\necho 'd{header}'\n${CTAGS} --list-roles=all.'d{header}'\n"
  },
  {
    "path": "Tmain/list-roles-with-kind-names.d/stdout-expected.txt",
    "content": "{header}\n#LANGUAGE      KIND(L/N) NAME     ENABLED VER DESCRIPTION\nC              h/header  local    on        0 local header\nC              h/header  system   on        0 system header\nC++            h/header  exported on        2 exported with \"exported imported ...\"\nC++            h/header  imported on        2 imported with \"imported ...\"\nC++            h/header  local    on        0 local header\nC++            h/header  system   on        0 system header\nCPreProcessor  h/header  local    on        0 local header\nCPreProcessor  h/header  system   on        0 system header\nCUDA           h/header  local    on        0 local header\nCUDA           h/header  system   on        0 system header\nVera           h/header  local    on        0 local header\nVera           h/header  system   on        0 system header\n{header}I\n#LANGUAGE      KIND(L/N)   NAME      ENABLED VER DESCRIPTION\nC              h/header    local     on        0 local header\nC              h/header    system    on        0 system header\nC++            h/header    exported  on        2 exported with \"exported imported ...\"\nC++            h/header    imported  on        2 imported with \"imported ...\"\nC++            h/header    local     on        0 local header\nC++            h/header    system    on        0 system header\nCPreProcessor  h/header    local     on        0 local header\nCPreProcessor  h/header    system    on        0 system header\nCUDA           h/header    local     on        0 local header\nCUDA           h/header    system    on        0 system header\nFlex           I/import    import    on        0 imports\nM4             I/macrofile included  on        0 included macro\nM4             I/macrofile sincluded on        0 silently included macro\nMake           I/makefile  included  on        0 included\nMake           I/makefile  optional  on        0 optionally included\nVera           h/header    local     on        0 local header\nVera           h/header    system    on        0 system header\nd{header}\n#LANGUAGE      KIND(L/N)   NAME      ENABLED VER DESCRIPTION\nAutomake       d/directory data      on        0 directory for DATA primary\nAutomake       d/directory library   on        0 directory for LIBRARIES primary\nAutomake       d/directory ltlibrary on        0 directory for LTLIBRARIES primary\nAutomake       d/directory man       on        0 directory for MANS primary\nAutomake       d/directory program   on        0 directory for PROGRAMS primary\nAutomake       d/directory script    on        0 directory for SCRIPTS primary\nC              d/macro     condition off       0 used in part of #if/#ifdef/#elif conditions\nC              d/macro     undef     on        0 undefined\nC              h/header    local     on        0 local header\nC              h/header    system    on        0 system header\nC++            d/macro     condition off       0 used in part of #if/#ifdef/#elif conditions\nC++            d/macro     undef     on        0 undefined\nC++            h/header    exported  on        2 exported with \"exported imported ...\"\nC++            h/header    imported  on        2 imported with \"imported ...\"\nC++            h/header    local     on        0 local header\nC++            h/header    system    on        0 system header\nCPreProcessor  d/macro     condition off       0 used in part of #if/#ifdef/#elif conditions\nCPreProcessor  d/macro     undef     on        0 undefined\nCPreProcessor  h/header    local     on        0 local header\nCPreProcessor  h/header    system    on        0 system header\nCUDA           d/macro     condition off       0 used in part of #if/#ifdef/#elif conditions\nCUDA           d/macro     undef     on        0 undefined\nCUDA           h/header    local     on        0 local header\nCUDA           h/header    system    on        0 system header\nM4             d/macro     undef     on        0 undefined\nVera           d/macro     condition off       0 used in part of #if/#ifdef/#elif conditions\nVera           d/macro     undef     on        0 undefined\nVera           h/header    local     on        0 local header\nVera           h/header    system    on        0 system header\n"
  },
  {
    "path": "Tmain/list-roles.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/list-roles.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\ntitle()\n{\n    echo\n    echo '#'\n    for x in \"$@\"; do\n        echo '#' $x\n    done\n    echo '#'\n}\n\nignore_xml()\n{\n    grep -v 'Glade\\|Ant\\|Maven2\\|XSLT'\n}\n\nignore_yaml()\n{\n    grep -v 'Yaml'\n}\n\n# When introducing newly rewritten parser, we would like to provide\n# the both new parser and old parser for debugging and providing\n# migration period to users. In such case the prefix \"Old\" will be\n# used to the name of old parser. The old parser should be ignored\n# in this test case.\nignore_old()\n{\n    grep -v '^Old'\n}\n\ntitle ''\n${CTAGS} --quiet --options=NONE --list-roles= | ignore_xml | ignore_old | ignore_yaml\n\ntitle 'all.*'\n${CTAGS} --quiet --options=NONE --list-roles='all.*' | ignore_xml | ignore_old | ignore_yaml\n\ntitle 'C.*'\n${CTAGS} --quiet --options=NONE --list-roles='C.*'\n\ntitle 'all.d'\n${CTAGS} --quiet --options=NONE --list-roles='all.d' | ignore_xml | ignore_old | ignore_yaml\n\ntitle 'Sh.s'\n${CTAGS} --quiet --options=NONE --list-roles='Sh.s'\n\n# --roles-all=\ntitle 'C.* with disabling  all roles of all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --list-roles='C.*'\n\n# --roles-all.*=\ntitle 'C.* with disabling all roles of all kinds of all languages'\n${CTAGS} --quiet --options=NONE --roles-all.'*'= --list-roles='C.*'\n\n# --roles-all.*='*'\ntitle 'C.* with enabling all roles of all kinds in all languages' \\\n\t  'after disabling system role of header kind of C language'\n${CTAGS} --quiet --options=NONE --roles-C.h=-'{system}' \\\n\t\t --roles-all.'*'='*' --list-roles='C.*'\n\n#--roles-all='*'\ntitle 'C.* with enabling all roles in all languages' \\\n\t  'after disabling system role of header kind of C language'\n${CTAGS} --quiet --options=NONE --roles-C.h=-'{system}' \\\n\t\t --roles-all='*' --list-roles='C.*'\n\n# --roles-<LANG>=\ntitle 'C.* with disabling all roles in C language'\n${CTAGS} --quiet --options=NONE --roles-C= --list-roles='C.*'\ntitle 'Sh.* with disabling all roles in C language'\n${CTAGS} --quiet --options=NONE --roles-C= --list-roles='Sh.*'\n\n# --roles-<LANG>.*=\ntitle 'C.* with disabling all roles of all kinds in C language'\n${CTAGS} --quiet --options=NONE --roles-C.'*'= --list-roles='C.*'\ntitle 'Sh.* with disabling all roles of all kinds in C language'\n${CTAGS} --quiet --options=NONE --roles-C.'*'= --list-roles='Sh.*'\n\n# --roles-<LANG>='*'\ntitle 'C.* with enabling all roles in C language' \\\n\t  'after disabling all roles in all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --roles-C='*' --list-roles='C.*'\ntitle 'Sh.* with enabling all roles in C language' \\\n\t  'after disabling all roles in all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --roles-C='*' --list-roles='Sh.*'\n\n# --roles-<LANG>.*='*'\ntitle 'C.* with enabling all roles of all kinds in C language' \\\n\t  'after disabling all roles in all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --roles-C.'*'='*' --list-roles='C.*'\ntitle 'Sh.* with enabling all roles of all kinds in C language' \\\n\t  'after disabling all roles in all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --roles-C.'*'='*' --list-roles='Sh.*'\n\n# --roles-<LANG>.{kind}=\ntitle 'C.* with disabling all roles of {header} kind in C language'\n${CTAGS} --quiet --options=NONE --roles-C.'{header}'= --list-roles='C.*'\ntitle 'Sh.* with disabling all roles of {header} kind in C language'\n${CTAGS} --quiet --options=NONE --roles-C.'{header}'= --list-roles='Sh.*'\n\n# --roles-<LANG>.k=\ntitle 'C.* with disabling all roles of h kind in C language'\n${CTAGS} --quiet --options=NONE --roles-C.h= --list-roles='C.*'\ntitle 'Sh.* with disabling all roles of h kind in C language'\n${CTAGS} --quiet --options=NONE --roles-C.h= --list-roles='Sh.*'\n\n# --roles-<LANG>.{kind}=*\ntitle 'C.* with enabling all roles of {header} kind in C language' \\\n\t  'after disabling all roles in all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --roles-C.'{header}'='*' --list-roles='C.*'\ntitle 'Sh.* with enabling all roles of {header} kind in C language' \\\n\t  'after disabling all roles in all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --roles-C.'{header}'='*' --list-roles='Sh.*'\n\n# --roles-<LANG>.k=*\ntitle 'C.* with enabling all roles of h kind in C language' \\\n\t  'after disabling all roles in all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --roles-C.'h'='*' --list-roles='C.*'\ntitle 'Sh.* with enabling all roles of h kind in C language' \\\n\t  'after disabling all roles in all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --roles-C.'h'='*' --list-roles='Sh.*'\n\n# --roles-<LANG>.{kind}=[+|-]{role}\n# --roles-<LANG>.k=[+|-]{role}\ntitle 'C.* with disabling system role of h kind'\n${CTAGS} --quiet --options=NONE --roles-C.h='-{system}' --list-roles='C.*'\ntitle 'C.* with disabling system role of {header} kind'\n${CTAGS} --quiet --options=NONE --roles-C.'{header}'='-{system}' --list-roles='C.*'\n\ntitle 'C.* with enabling system role of h kind after disabling the role'\n${CTAGS} --quiet --options=NONE --roles-C.h='-{system}+{system}' --list-roles='C.*'\ntitle 'C.* with enabling system role of {header} kind after disabling the role'\n${CTAGS} --quiet --options=NONE --roles-C.'{header}'='-{system}+{system}' --list-roles='C.*'\n\ntitle 'C.* with disabling system and local roles of h kind'\n${CTAGS} --quiet --options=NONE --roles-C.h='-{system}{local}' --list-roles='C.*'\ntitle 'C.* with disabling system and local roles of {header} kind'\n${CTAGS} --quiet --options=NONE --roles-C.'{header}'='-{system}{local}' --list-roles='C.*'\n\ntitle 'C.* with enabling system and local roles of h kind' \\\n\t  'after disabling all roles in all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --roles-C.h='+{system}{local}' --list-roles='C.*'\ntitle 'C.* with enabling system and local roles of {header} kind' \\\n\t  'after disabling all roles in all languages'\n${CTAGS} --quiet --options=NONE --roles-all= --roles-C.'{header}'='+{system}{local}' --list-roles='C.*'\n\ntitle 'C.* with disabling local role of h kind and undef role of d kind'\n${CTAGS} --quiet --options=NONE --roles-C.h='-{local}' --roles-C.d='-{undef}' --list-roles='C.*'\n\n# miscellaneous combinations\ntitle 'C.* with enabling all roles of header kinds after disabling all roles of the kind'\n${CTAGS} --quiet --options=NONE --roles-C.'{header}'= --roles-C.'{header}'='*' --list-roles='C.*'\n\ntitle 'C.* with enabling all roles of header kinds after disabling all roles of the kinds of C language'\n${CTAGS} --quiet --options=NONE --roles-C.'*'= --roles-C.'{header}'='*' --list-roles='C.*'\n\ntitle 'C.* with enabling all roles of header kinds after disabling all roles of the kinds of C language (short notation)'\n${CTAGS} --quiet --options=NONE --roles-C= --roles-C.'{header}'='*' --list-roles='C.*'\n"
  },
  {
    "path": "Tmain/list-roles.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/list-roles.d/stdout-expected.txt",
    "content": "\n#\n#\n#\n#LANGUAGE               KIND(L/N)         NAME               ENABLED VER DESCRIPTION\nAda                     p/package         subunit            on        0 package name referenced in separate()\nAutoIt                  S/script          local              on        0 local include\nAutoIt                  S/script          system             on        0 system include\nAutoconf                e/optenable       cmdline            on        0 specified in a configure command line\nAutoconf                w/optwith         cmdline            on        0 specified in a configure command line\nAutomake                c/condition       branched           on        0 used for branching\nAutomake                d/directory       data               on        0 directory for DATA primary\nAutomake                d/directory       library            on        0 directory for LIBRARIES primary\nAutomake                d/directory       ltlibrary          on        0 directory for LTLIBRARIES primary\nAutomake                d/directory       man                on        0 directory for MANS primary\nAutomake                d/directory       program            on        0 directory for PROGRAMS primary\nAutomake                d/directory       script             on        0 directory for SCRIPTS primary\nAutomake                p/pseudodir       data               on        0 directory for DATA primary\nAutomake                p/pseudodir       library            on        0 directory for LIBRARIES primary\nAutomake                p/pseudodir       ltlibrary          on        0 directory for LTLIBRARIES primary\nAutomake                p/pseudodir       man                on        0 directory for MANS primary\nAutomake                p/pseudodir       program            on        0 directory for PROGRAMS primary\nAutomake                p/pseudodir       script             on        0 directory for SCRIPTS primary\nBasic                   f/function        decl               on        0 declared\nBats                    S/script          loaded             on        0 script loaed with \"load\" command\nC                       d/macro           condition          off       0 used in part of #if/#ifdef/#elif conditions\nC                       d/macro           undef              on        0 undefined\nC                       f/function        foreigncall        on        2 called in foreign languages\nC                       f/function        foreigndecl        on        1 declared in foreign languages\nC                       h/header          local              on        0 local header\nC                       h/header          system             on        0 system header\nC                       s/struct          foreigndecl        on        1 declared in foreign languages\nC++                     M/module          imported           on        2 imported with \"imported ...\"\nC++                     M/module          partOwner          on        2 used for specifying a partition\nC++                     P/partition       imported           on        2 imported with \"imported ...\"\nC++                     d/macro           condition          off       0 used in part of #if/#ifdef/#elif conditions\nC++                     d/macro           undef              on        0 undefined\nC++                     h/header          exported           on        2 exported with \"exported imported ...\"\nC++                     h/header          imported           on        2 imported with \"imported ...\"\nC++                     h/header          local              on        0 local header\nC++                     h/header          system             on        0 system header\nCPreProcessor           d/macro           condition          off       0 used in part of #if/#ifdef/#elif conditions\nCPreProcessor           d/macro           undef              on        0 undefined\nCPreProcessor           h/header          local              on        0 local header\nCPreProcessor           h/header          system             on        0 system header\nCUDA                    d/macro           condition          off       0 used in part of #if/#ifdef/#elif conditions\nCUDA                    d/macro           undef              on        0 undefined\nCUDA                    h/header          local              on        0 local header\nCUDA                    h/header          system             on        0 system header\nCobol                   S/sourcefile      copied             on        0 copied in source file\nCobolFree               S/sourcefile      copied             on        0 copied in source file\nCobolVariable           S/sourcefile      copied             on        0 copied in source file\nDTD                     e/element         attOwner           on        0 attributes owner\nDTD                     p/parameterEntity condition          on        0 conditions\nDTD                     p/parameterEntity elementName        on        0 element names\nDTD                     p/parameterEntity partOfAttDef       on        0 part of attribute definition\nElm                     c/constructor     exposed            on        0 item exposed from a module\nElm                     f/function        exposed            on        0 item exposed from a module\nElm                     m/module          imported           on        0 module imported\nElm                     t/type            exposed            on        0 item exposed from a module\nFlex                    I/import          import             on        0 imports\nGDScript                c/class           extended           on        0 used as a base class for extending\nGemSpec                 g/gem             develDep           on        0 specifying development dependency\nGemSpec                 g/gem             runtimeDep         on        0 specifying runtime dependency\nGo                      Y/unknown         receiverType       on        0 receiver type\nGo                      p/package         imported           on        0 imported package\nHTML                    C/stylesheet      extFile            on        0 referenced as external files\nHTML                    J/script          extFile            on        0 referenced as external files\nHTML                    c/class           attribute          on        0 assigned as attributes\nJava                    p/package         imported           on        0 imported package\nJavaScript              c/class           chainElt           off       0 (EXPERIMENTAL)used as an element in a name chain like a.b.c\nJavaScript              f/function        foreigndecl        on        1 declared in foreign languages\nJavaScript              v/variable        chainElt           off       0 (EXPERIMENTAL)used as an element in a name chain like a.b.c\nJulia                   Y/unknown         imported           on        0 loaded by \"import\"\nJulia                   Y/unknown         used               on        0 loaded by \"using\"\nJulia                   n/module          imported           on        0 loaded by \"import\"\nJulia                   n/module          namespace          on        0 only some symbols in it are imported\nJulia                   n/module          used               on        0 loaded by \"using\"\nKconfig                 k/kconfig         source             on        0 kconfig file loaded with source directive\nLEX                     c/cond            grouping           on        1  conditions used for grouping of start or exclusive condition rules\nLdScript                i/inputSection    destination        on        1 specified as the destination of code and data\nLdScript                i/inputSection    discarded          on        0 discarded when linking\nLdScript                i/inputSection    mapped             on        0 mapped to output section\nLdScript                s/symbol          aliased            on        1 aliased with __attribute__((alias(...))) in C/C++ code\nLdScript                s/symbol          entrypoint         on        0 entry points\nLua                     Y/unknown         referenced         off       0 referenced somehow\nM4                      I/macrofile       included           on        0 included macro\nM4                      I/macrofile       sincluded          on        0 silently included macro\nM4                      d/macro           undef              on        0 undefined\nMake                    I/makefile        included           on        0 included\nMake                    I/makefile        optional           on        0 optionally included\nMeson                   m/module          imported           on        0 imported\nNSIS                    i/script          included           on        0 included with !include\nNftables                R/ruleset         included           on        0 included ruleset\nNftables                f/family          referenced         off       0 referenced somehow\nOdin                    A/asmfile         imported           on        0 imported assembly file via foreign\nOdin                    C/collection      referenced         on        0 referenced in import statement\nOdin                    L/ccode           imported           on        0 imported ccode via foreign\nOdin                    p/package         imported           on        0 imported package\nPerl                    M/module          unused             on        0 specified in `no' built-in function\nPerl                    M/module          used               on        0 specified in `use' built-in function\nPerl                    h/heredoc         endmarker          on        0 end marker\nPkgConfig               p/pkg             conflicted         on        0 conflicted\nPkgConfig               p/pkg             provided           on        0 provided\nPkgConfig               p/pkg             required           on        0 required\nProlog                  m/module          chainElt           off       0 (EXPERIMENTAL)used as an element in a module-qualified atom like module:predicate\nProtobuf                D/protodef        imported           on        0 imported\nProtobuf                m/message         extension          on        0 extending the message\nPython                  Y/unknown         imported           on        0 imported from the other module\nPython                  Y/unknown         indirectlyImported on        0 classes/variables/functions/modules imported in alternative name\nPython                  f/function        entryPoint         on        1 specified as an entry point\nPython                  i/module          entryPoint         on        1 specified as a module of an entry point\nPython                  i/module          imported           on        0 imported modules\nPython                  i/module          indirectlyImported on        0 module imported in alternative name\nPython                  i/module          namespace          on        0 namespace from where classes/variables/functions are imported\nR                       l/library         library            on        0 library attached by library function\nR                       l/library         require            on        0 library attached by require function\nR                       s/source          source             on        0 source loaded by source fucntion\nRpmSpec                 m/macro           undef              on        0 undefined\nRpmSpec                 p/patch           decl               on        0 declared for applying later\nRuby                    L/library         loaded             on        0 loaded by \"load\" method\nRuby                    L/library         required           on        0 loaded by \"require\" method\nRuby                    L/library         requiredRel        on        0 loaded by \"require_relative\" method\nSCSS                    M/module          used               on        1 used\nSELinuxTypeEnforcement  t/type            aliased            on        0 aliased\nSQL                     k/type            decl               off       1 declaration (shell in PostgreSQL)\nSh                      h/heredoc         endmarker          on        0 end marker\nSh                      s/script          loaded             on        0 loaded\nSystemTap               p/probe           attached           on        1 attached by code for probing\nSystemVerilog           m/module          decl               on        0 declaring instances\nSystemdUnit             u/unit            After              on        0 referred in After key\nSystemdUnit             u/unit            Before             on        0 referred in Before key\nSystemdUnit             u/unit            RequiredBy         on        0 referred in RequiredBy key\nSystemdUnit             u/unit            Requires           on        0 referred in Requires key\nSystemdUnit             u/unit            WantedBy           on        0 referred in WantedBy key\nSystemdUnit             u/unit            Wants              on        0 referred in Wants key\nSystemdUnit             u/unit            foreignlang        on        1 referenced in foreign languages\nTOML                    k/key             chainElt           off       0 (EXPERIMENTAL)used as an element in a key name chain like a.b.c\nTerraform               v/variable        assigned           on        0 assigned in Variable Definitions (.tfvars) files\nTex                     e/environment     used               off       0 environment usage introduced by \\begin{MyEnv}\nTex                     i/xinput          bibliography       on        0 bibliography (.bib) file\nTex                     i/xinput          included           on        0 external input file specified with \\include\nTex                     i/xinput          input              on        0 external input file specified with \\input\nThrift                  T/thriftFile      included           on        0 included file\nV                       Y/unknown         imported           on        0 imported symbol\nV                       p/module          foreignlang        on        0 representing a foreign language (i.e., C, JS...)\nV                       p/module          imported           on        0 imported module\nVHDL                    e/entity          desigend           on        0 designed by an architecture\nVera                    d/macro           condition          off       0 used in part of #if/#ifdef/#elif conditions\nVera                    d/macro           undef              on        0 undefined\nVera                    h/header          local              on        0 local header\nVera                    h/header          system             on        0 system header\nVerilog                 m/module          decl               on        0 declaring instances\nVim                     h/heredoc         endmarker          on        0 end marker\nZsh                     f/function        autoloaded         on        0 function name passed to autoload built-in command\nZsh                     h/heredoc         endmarker          on        0 end marker\nZsh                     s/script          autoloaded         on        0 autoloaded\nZsh                     s/script          loaded             on        0 loaded\n\n#\n# all.*\n#\n#LANGUAGE               KIND(L/N)         NAME               ENABLED VER DESCRIPTION\nAda                     p/package         subunit            on        0 package name referenced in separate()\nAutoIt                  S/script          local              on        0 local include\nAutoIt                  S/script          system             on        0 system include\nAutoconf                e/optenable       cmdline            on        0 specified in a configure command line\nAutoconf                w/optwith         cmdline            on        0 specified in a configure command line\nAutomake                c/condition       branched           on        0 used for branching\nAutomake                d/directory       data               on        0 directory for DATA primary\nAutomake                d/directory       library            on        0 directory for LIBRARIES primary\nAutomake                d/directory       ltlibrary          on        0 directory for LTLIBRARIES primary\nAutomake                d/directory       man                on        0 directory for MANS primary\nAutomake                d/directory       program            on        0 directory for PROGRAMS primary\nAutomake                d/directory       script             on        0 directory for SCRIPTS primary\nAutomake                p/pseudodir       data               on        0 directory for DATA primary\nAutomake                p/pseudodir       library            on        0 directory for LIBRARIES primary\nAutomake                p/pseudodir       ltlibrary          on        0 directory for LTLIBRARIES primary\nAutomake                p/pseudodir       man                on        0 directory for MANS primary\nAutomake                p/pseudodir       program            on        0 directory for PROGRAMS primary\nAutomake                p/pseudodir       script             on        0 directory for SCRIPTS primary\nBasic                   f/function        decl               on        0 declared\nBats                    S/script          loaded             on        0 script loaed with \"load\" command\nC                       d/macro           condition          off       0 used in part of #if/#ifdef/#elif conditions\nC                       d/macro           undef              on        0 undefined\nC                       f/function        foreigncall        on        2 called in foreign languages\nC                       f/function        foreigndecl        on        1 declared in foreign languages\nC                       h/header          local              on        0 local header\nC                       h/header          system             on        0 system header\nC                       s/struct          foreigndecl        on        1 declared in foreign languages\nC++                     M/module          imported           on        2 imported with \"imported ...\"\nC++                     M/module          partOwner          on        2 used for specifying a partition\nC++                     P/partition       imported           on        2 imported with \"imported ...\"\nC++                     d/macro           condition          off       0 used in part of #if/#ifdef/#elif conditions\nC++                     d/macro           undef              on        0 undefined\nC++                     h/header          exported           on        2 exported with \"exported imported ...\"\nC++                     h/header          imported           on        2 imported with \"imported ...\"\nC++                     h/header          local              on        0 local header\nC++                     h/header          system             on        0 system header\nCPreProcessor           d/macro           condition          off       0 used in part of #if/#ifdef/#elif conditions\nCPreProcessor           d/macro           undef              on        0 undefined\nCPreProcessor           h/header          local              on        0 local header\nCPreProcessor           h/header          system             on        0 system header\nCUDA                    d/macro           condition          off       0 used in part of #if/#ifdef/#elif conditions\nCUDA                    d/macro           undef              on        0 undefined\nCUDA                    h/header          local              on        0 local header\nCUDA                    h/header          system             on        0 system header\nCobol                   S/sourcefile      copied             on        0 copied in source file\nCobolFree               S/sourcefile      copied             on        0 copied in source file\nCobolVariable           S/sourcefile      copied             on        0 copied in source file\nDTD                     e/element         attOwner           on        0 attributes owner\nDTD                     p/parameterEntity condition          on        0 conditions\nDTD                     p/parameterEntity elementName        on        0 element names\nDTD                     p/parameterEntity partOfAttDef       on        0 part of attribute definition\nElm                     c/constructor     exposed            on        0 item exposed from a module\nElm                     f/function        exposed            on        0 item exposed from a module\nElm                     m/module          imported           on        0 module imported\nElm                     t/type            exposed            on        0 item exposed from a module\nFlex                    I/import          import             on        0 imports\nGDScript                c/class           extended           on        0 used as a base class for extending\nGemSpec                 g/gem             develDep           on        0 specifying development dependency\nGemSpec                 g/gem             runtimeDep         on        0 specifying runtime dependency\nGo                      Y/unknown         receiverType       on        0 receiver type\nGo                      p/package         imported           on        0 imported package\nHTML                    C/stylesheet      extFile            on        0 referenced as external files\nHTML                    J/script          extFile            on        0 referenced as external files\nHTML                    c/class           attribute          on        0 assigned as attributes\nJava                    p/package         imported           on        0 imported package\nJavaScript              c/class           chainElt           off       0 (EXPERIMENTAL)used as an element in a name chain like a.b.c\nJavaScript              f/function        foreigndecl        on        1 declared in foreign languages\nJavaScript              v/variable        chainElt           off       0 (EXPERIMENTAL)used as an element in a name chain like a.b.c\nJulia                   Y/unknown         imported           on        0 loaded by \"import\"\nJulia                   Y/unknown         used               on        0 loaded by \"using\"\nJulia                   n/module          imported           on        0 loaded by \"import\"\nJulia                   n/module          namespace          on        0 only some symbols in it are imported\nJulia                   n/module          used               on        0 loaded by \"using\"\nKconfig                 k/kconfig         source             on        0 kconfig file loaded with source directive\nLEX                     c/cond            grouping           on        1  conditions used for grouping of start or exclusive condition rules\nLdScript                i/inputSection    destination        on        1 specified as the destination of code and data\nLdScript                i/inputSection    discarded          on        0 discarded when linking\nLdScript                i/inputSection    mapped             on        0 mapped to output section\nLdScript                s/symbol          aliased            on        1 aliased with __attribute__((alias(...))) in C/C++ code\nLdScript                s/symbol          entrypoint         on        0 entry points\nLua                     Y/unknown         referenced         off       0 referenced somehow\nM4                      I/macrofile       included           on        0 included macro\nM4                      I/macrofile       sincluded          on        0 silently included macro\nM4                      d/macro           undef              on        0 undefined\nMake                    I/makefile        included           on        0 included\nMake                    I/makefile        optional           on        0 optionally included\nMeson                   m/module          imported           on        0 imported\nNSIS                    i/script          included           on        0 included with !include\nNftables                R/ruleset         included           on        0 included ruleset\nNftables                f/family          referenced         off       0 referenced somehow\nOdin                    A/asmfile         imported           on        0 imported assembly file via foreign\nOdin                    C/collection      referenced         on        0 referenced in import statement\nOdin                    L/ccode           imported           on        0 imported ccode via foreign\nOdin                    p/package         imported           on        0 imported package\nPerl                    M/module          unused             on        0 specified in `no' built-in function\nPerl                    M/module          used               on        0 specified in `use' built-in function\nPerl                    h/heredoc         endmarker          on        0 end marker\nPkgConfig               p/pkg             conflicted         on        0 conflicted\nPkgConfig               p/pkg             provided           on        0 provided\nPkgConfig               p/pkg             required           on        0 required\nProlog                  m/module          chainElt           off       0 (EXPERIMENTAL)used as an element in a module-qualified atom like module:predicate\nProtobuf                D/protodef        imported           on        0 imported\nProtobuf                m/message         extension          on        0 extending the message\nPython                  Y/unknown         imported           on        0 imported from the other module\nPython                  Y/unknown         indirectlyImported on        0 classes/variables/functions/modules imported in alternative name\nPython                  f/function        entryPoint         on        1 specified as an entry point\nPython                  i/module          entryPoint         on        1 specified as a module of an entry point\nPython                  i/module          imported           on        0 imported modules\nPython                  i/module          indirectlyImported on        0 module imported in alternative name\nPython                  i/module          namespace          on        0 namespace from where classes/variables/functions are imported\nR                       l/library         library            on        0 library attached by library function\nR                       l/library         require            on        0 library attached by require function\nR                       s/source          source             on        0 source loaded by source fucntion\nRpmSpec                 m/macro           undef              on        0 undefined\nRpmSpec                 p/patch           decl               on        0 declared for applying later\nRuby                    L/library         loaded             on        0 loaded by \"load\" method\nRuby                    L/library         required           on        0 loaded by \"require\" method\nRuby                    L/library         requiredRel        on        0 loaded by \"require_relative\" method\nSCSS                    M/module          used               on        1 used\nSELinuxTypeEnforcement  t/type            aliased            on        0 aliased\nSQL                     k/type            decl               off       1 declaration (shell in PostgreSQL)\nSh                      h/heredoc         endmarker          on        0 end marker\nSh                      s/script          loaded             on        0 loaded\nSystemTap               p/probe           attached           on        1 attached by code for probing\nSystemVerilog           m/module          decl               on        0 declaring instances\nSystemdUnit             u/unit            After              on        0 referred in After key\nSystemdUnit             u/unit            Before             on        0 referred in Before key\nSystemdUnit             u/unit            RequiredBy         on        0 referred in RequiredBy key\nSystemdUnit             u/unit            Requires           on        0 referred in Requires key\nSystemdUnit             u/unit            WantedBy           on        0 referred in WantedBy key\nSystemdUnit             u/unit            Wants              on        0 referred in Wants key\nSystemdUnit             u/unit            foreignlang        on        1 referenced in foreign languages\nTOML                    k/key             chainElt           off       0 (EXPERIMENTAL)used as an element in a key name chain like a.b.c\nTerraform               v/variable        assigned           on        0 assigned in Variable Definitions (.tfvars) files\nTex                     e/environment     used               off       0 environment usage introduced by \\begin{MyEnv}\nTex                     i/xinput          bibliography       on        0 bibliography (.bib) file\nTex                     i/xinput          included           on        0 external input file specified with \\include\nTex                     i/xinput          input              on        0 external input file specified with \\input\nThrift                  T/thriftFile      included           on        0 included file\nV                       Y/unknown         imported           on        0 imported symbol\nV                       p/module          foreignlang        on        0 representing a foreign language (i.e., C, JS...)\nV                       p/module          imported           on        0 imported module\nVHDL                    e/entity          desigend           on        0 designed by an architecture\nVera                    d/macro           condition          off       0 used in part of #if/#ifdef/#elif conditions\nVera                    d/macro           undef              on        0 undefined\nVera                    h/header          local              on        0 local header\nVera                    h/header          system             on        0 system header\nVerilog                 m/module          decl               on        0 declaring instances\nVim                     h/heredoc         endmarker          on        0 end marker\nZsh                     f/function        autoloaded         on        0 function name passed to autoload built-in command\nZsh                     h/heredoc         endmarker          on        0 end marker\nZsh                     s/script          autoloaded         on        0 autoloaded\nZsh                     s/script          loaded             on        0 loaded\n\n#\n# C.*\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# all.d\n#\n#LANGUAGE      KIND(L/N)   NAME      ENABLED VER DESCRIPTION\nAutomake       d/directory data      on        0 directory for DATA primary\nAutomake       d/directory library   on        0 directory for LIBRARIES primary\nAutomake       d/directory ltlibrary on        0 directory for LTLIBRARIES primary\nAutomake       d/directory man       on        0 directory for MANS primary\nAutomake       d/directory program   on        0 directory for PROGRAMS primary\nAutomake       d/directory script    on        0 directory for SCRIPTS primary\nC              d/macro     condition off       0 used in part of #if/#ifdef/#elif conditions\nC              d/macro     undef     on        0 undefined\nC++            d/macro     condition off       0 used in part of #if/#ifdef/#elif conditions\nC++            d/macro     undef     on        0 undefined\nCPreProcessor  d/macro     condition off       0 used in part of #if/#ifdef/#elif conditions\nCPreProcessor  d/macro     undef     on        0 undefined\nCUDA           d/macro     condition off       0 used in part of #if/#ifdef/#elif conditions\nCUDA           d/macro     undef     on        0 undefined\nM4             d/macro     undef     on        0 undefined\nVera           d/macro     condition off       0 used in part of #if/#ifdef/#elif conditions\nVera           d/macro     undef     on        0 undefined\n\n#\n# Sh.s\n#\n#KIND(L/N) NAME   ENABLED VER DESCRIPTION\ns/script   loaded on        0 loaded\n\n#\n# C.* with disabling all roles of all languages\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall off       2 called in foreign languages\nf/function  foreigndecl off       1 declared in foreign languages\nh/header    local       off       0 local header\nh/header    system      off       0 system header\ns/struct    foreigndecl off       1 declared in foreign languages\n\n#\n# C.* with disabling all roles of all kinds of all languages\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall off       2 called in foreign languages\nf/function  foreigndecl off       1 declared in foreign languages\nh/header    local       off       0 local header\nh/header    system      off       0 system header\ns/struct    foreigndecl off       1 declared in foreign languages\n\n#\n# C.* with enabling all roles of all kinds in all languages\n# after disabling system role of header kind of C language\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   on        0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# C.* with enabling all roles in all languages\n# after disabling system role of header kind of C language\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   on        0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# C.* with disabling all roles in C language\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall off       2 called in foreign languages\nf/function  foreigndecl off       1 declared in foreign languages\nh/header    local       off       0 local header\nh/header    system      off       0 system header\ns/struct    foreigndecl off       1 declared in foreign languages\n\n#\n# Sh.* with disabling all roles in C language\n#\n#KIND(L/N) NAME      ENABLED VER DESCRIPTION\nh/heredoc  endmarker on        0 end marker\ns/script   loaded    on        0 loaded\n\n#\n# C.* with disabling all roles of all kinds in C language\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall off       2 called in foreign languages\nf/function  foreigndecl off       1 declared in foreign languages\nh/header    local       off       0 local header\nh/header    system      off       0 system header\ns/struct    foreigndecl off       1 declared in foreign languages\n\n#\n# Sh.* with disabling all roles of all kinds in C language\n#\n#KIND(L/N) NAME      ENABLED VER DESCRIPTION\nh/heredoc  endmarker on        0 end marker\ns/script   loaded    on        0 loaded\n\n#\n# C.* with enabling all roles in C language\n# after disabling all roles in all languages\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   on        0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# Sh.* with enabling all roles in C language\n# after disabling all roles in all languages\n#\n#KIND(L/N) NAME      ENABLED VER DESCRIPTION\nh/heredoc  endmarker off       0 end marker\ns/script   loaded    off       0 loaded\n\n#\n# C.* with enabling all roles of all kinds in C language\n# after disabling all roles in all languages\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   on        0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# Sh.* with enabling all roles of all kinds in C language\n# after disabling all roles in all languages\n#\n#KIND(L/N) NAME      ENABLED VER DESCRIPTION\nh/heredoc  endmarker off       0 end marker\ns/script   loaded    off       0 loaded\n\n#\n# C.* with disabling all roles of {header} kind in C language\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       off       0 local header\nh/header    system      off       0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# Sh.* with disabling all roles of {header} kind in C language\n#\n#KIND(L/N) NAME      ENABLED VER DESCRIPTION\nh/heredoc  endmarker on        0 end marker\ns/script   loaded    on        0 loaded\n\n#\n# C.* with disabling all roles of h kind in C language\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       off       0 local header\nh/header    system      off       0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# Sh.* with disabling all roles of h kind in C language\n#\n#KIND(L/N) NAME      ENABLED VER DESCRIPTION\nh/heredoc  endmarker on        0 end marker\ns/script   loaded    on        0 loaded\n\n#\n# C.* with enabling all roles of {header} kind in C language\n# after disabling all roles in all languages\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall off       2 called in foreign languages\nf/function  foreigndecl off       1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl off       1 declared in foreign languages\n\n#\n# Sh.* with enabling all roles of {header} kind in C language\n# after disabling all roles in all languages\n#\n#KIND(L/N) NAME      ENABLED VER DESCRIPTION\nh/heredoc  endmarker off       0 end marker\ns/script   loaded    off       0 loaded\n\n#\n# C.* with enabling all roles of h kind in C language\n# after disabling all roles in all languages\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall off       2 called in foreign languages\nf/function  foreigndecl off       1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl off       1 declared in foreign languages\n\n#\n# Sh.* with enabling all roles of h kind in C language\n# after disabling all roles in all languages\n#\n#KIND(L/N) NAME      ENABLED VER DESCRIPTION\nh/heredoc  endmarker off       0 end marker\ns/script   loaded    off       0 loaded\n\n#\n# C.* with disabling system role of h kind\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      off       0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# C.* with disabling system role of {header} kind\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      off       0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# C.* with enabling system role of h kind after disabling the role\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# C.* with enabling system role of {header} kind after disabling the role\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# C.* with disabling system and local roles of h kind\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       off       0 local header\nh/header    system      off       0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# C.* with disabling system and local roles of {header} kind\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       off       0 local header\nh/header    system      off       0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# C.* with enabling system and local roles of h kind\n# after disabling all roles in all languages\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall off       2 called in foreign languages\nf/function  foreigndecl off       1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl off       1 declared in foreign languages\n\n#\n# C.* with enabling system and local roles of {header} kind\n# after disabling all roles in all languages\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall off       2 called in foreign languages\nf/function  foreigndecl off       1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl off       1 declared in foreign languages\n\n#\n# C.* with disabling local role of h kind and undef role of d kind\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       off       0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# C.* with enabling all roles of header kinds after disabling all roles of the kind\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       on        0 undefined\nf/function  foreigncall on        2 called in foreign languages\nf/function  foreigndecl on        1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl on        1 declared in foreign languages\n\n#\n# C.* with enabling all roles of header kinds after disabling all roles of the kinds of C language\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall off       2 called in foreign languages\nf/function  foreigndecl off       1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl off       1 declared in foreign languages\n\n#\n# C.* with enabling all roles of header kinds after disabling all roles of the kinds of C language (short notation)\n#\n#KIND(L/N)  NAME        ENABLED VER DESCRIPTION\nd/macro     condition   off       0 used in part of #if/#ifdef/#elif conditions\nd/macro     undef       off       0 undefined\nf/function  foreigncall off       2 called in foreign languages\nf/function  foreigndecl off       1 declared in foreign languages\nh/header    local       on        0 local header\nh/header    system      on        0 system header\ns/struct    foreigndecl off       1 declared in foreign languages\n"
  },
  {
    "path": "Tmain/list-subparsers-all.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\n\n. ../utils.sh\nis_feature_available $CTAGS xpath\nis_feature_available $CTAGS yaml\n\n${CTAGS} --quiet --options=NONE \\\n\t\t --list-subparsers=all\n"
  },
  {
    "path": "Tmain/list-subparsers-all.d/stdout-expected.txt",
    "content": "#NAME                BASEPARSER DIRECTIONS\nAnsiblePlaybook      Yaml       base <> sub {bidirectional}\nAnt                  XML        base <> sub {bidirectional}\nAutoconf             M4         base <> sub {bidirectional}\nAutomake             Make       base <= sub {dedicated}\nBats                 Sh         base <= sub {dedicated}\nBibLaTeX             BibTeX     base <> sub {bidirectional}\nCargo                TOML       base <= sub {dedicated}\nDBusIntrospect       XML        base <> sub {bidirectional}\nDBusService          Iniconf    base <= sub {dedicated}\nFunctionParameters   Perl       base <> sub {bidirectional}\nGemSpec              Ruby       base <= sub {dedicated}\nGlade                XML        base <> sub {bidirectional}\nI18nRubyGem          Yaml       base <> sub {bidirectional}\nIPythonCell          Python     base => sub {shared}\nITcl                 Tcl        base <> sub {bidirectional}\nJNI                  C          base <> sub {bidirectional}\nJNI                  C++        base <> sub {bidirectional}\nMaven2               XML        base <> sub {bidirectional}\nMoose                Perl       base <> sub {bidirectional}\nOpenAPI              Yaml       base <> sub {bidirectional}\nPlistXML             XML        base <> sub {bidirectional}\nPythonEntryPoints    Iniconf    base <= sub {dedicated}\nPythonLoggingConfig  Iniconf    base <> sub {bidirectional}\nQtMoc                C++        base <> sub {bidirectional}\nQuarto               Markdown   base <= sub {dedicated}\nR6Class              R          base <> sub {bidirectional}\nRMarkdown            Markdown   base <= sub {dedicated}\nRSpec                Ruby       base => sub {shared}\nRake                 Ruby       base <= sub {dedicated}\nRelaxNG              XML        base <> sub {bidirectional}\nS4Class              R          base <> sub {bidirectional}\nSELinuxInterface     M4         base <= sub {dedicated}\nSVG                  XML        base <> sub {bidirectional}\nSystemdUnit          Iniconf    base <= sub {dedicated}\nTclOO                Tcl        base <> sub {bidirectional}\nTeXBeamer            Tex        base <> sub {bidirectional}\nXRC                  XML        base <= sub {dedicated}\nXSLT                 XML        base <> sub {bidirectional}\nYumRepo              Iniconf    base <= sub {dedicated}\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd-no-dot.d/ctags.d/a.ctags",
    "content": "--_echo=hello\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd-no-dot.d/ctags.d/b.ctags",
    "content": "--_echo=world\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd-no-dot.d/ctags.d/c.ctags",
    "content": "--_force-quit=7\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd-no-dot.d/exit-expected.txt",
    "content": "7\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd-no-dot.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nskip_if_user_has_dot_ctags_d\n\n${CTAGS}\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd-no-dot.d/stderr-expected.txt",
    "content": "ctags: Notice: hello\nctags: Notice: world\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd-no-dot.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/load-conf-files-under-cwd.d/.ctags.d/a.ctags",
    "content": "--_echo=hello\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd.d/.ctags.d/b.ctags",
    "content": "--_echo=world\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd.d/.ctags.d/c.ctags",
    "content": "--_force-quit=7\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd.d/exit-expected.txt",
    "content": "7\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nexit_if_win32 \"$CTAGS\"\nskip_if_user_has_dot_ctags_d\n\n${CTAGS}\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd.d/stderr-expected.txt",
    "content": "ctags: Notice: hello\nctags: Notice: world\n"
  },
  {
    "path": "Tmain/load-conf-files-under-cwd.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/load-conf-files-under-default-xdg-config-home.d/exit-expected.txt",
    "content": "7\n"
  },
  {
    "path": "Tmain/load-conf-files-under-default-xdg-config-home.d/run.sh",
    "content": "# Copyright: 2019 itchyny\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\n# $HOME/.config/ctags/*.ctags are loaded\nexport HOME=./myhome\nexport XDG_CONFIG_HOME=\n${CTAGS}\n"
  },
  {
    "path": "Tmain/load-conf-files-under-default-xdg-config-home.d/stderr-expected.txt",
    "content": "ctags: Notice: hello\nctags: Notice: world\n"
  },
  {
    "path": "Tmain/load-conf-files-under-default-xdg-config-home.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/load-conf-files-under-home.d/exit-expected.txt",
    "content": "7\n"
  },
  {
    "path": "Tmain/load-conf-files-under-home.d/myhome/.ctags.d/a.ctags",
    "content": "--_echo=hello\n"
  },
  {
    "path": "Tmain/load-conf-files-under-home.d/myhome/.ctags.d/b.ctags",
    "content": "--_echo=world\n"
  },
  {
    "path": "Tmain/load-conf-files-under-home.d/myhome/.ctags.d/c.ctags",
    "content": "--_force-quit=7\n"
  },
  {
    "path": "Tmain/load-conf-files-under-home.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nexit_if_win32 \"$CTAGS\"\n\nexport HOME=./myhome\n${CTAGS}\n"
  },
  {
    "path": "Tmain/load-conf-files-under-home.d/stderr-expected.txt",
    "content": "ctags: Notice: hello\nctags: Notice: world\n"
  },
  {
    "path": "Tmain/load-conf-files-under-home.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/load-conf-files-under-xdg-config-home.d/exit-expected.txt",
    "content": "7\n"
  },
  {
    "path": "Tmain/load-conf-files-under-xdg-config-home.d/run.sh",
    "content": "# Copyright: 2019 itchyny\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\n# $XDG_CONFIG_HOME/ctags/*.ctags are loaded\nexport XDG_CONFIG_HOME=./.config\n${CTAGS}\n"
  },
  {
    "path": "Tmain/load-conf-files-under-xdg-config-home.d/stderr-expected.txt",
    "content": "ctags: Notice: hello\nctags: Notice: world\n"
  },
  {
    "path": "Tmain/load-conf-files-under-xdg-config-home.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/load-dot-ctags-twice.d/dot.ctags",
    "content": "--_echo=hello\n"
  },
  {
    "path": "Tmain/load-dot-ctags-twice.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/load-dot-ctags-twice.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n# TODO: --quiet\n${CTAGS} --options=NONE --options=./dot.ctags --options=./dot.ctags --_force-quit\n\n"
  },
  {
    "path": "Tmain/load-dot-ctags-twice.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nctags: Notice: hello\n"
  },
  {
    "path": "Tmain/load-dot-ctags-twice.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/lregex-clear-patterns.d/input.c",
    "content": "DEFINE(x, 1);\nregister(eax);\n"
  },
  {
    "path": "Tmain/lregex-clear-patterns.d/mylang.ctags",
    "content": "--langdef=MYLANG{base=C}\n--kinddef-MYLANG=d,def,definitions\n--kinddef-MYLANG=r,reg,registers\n--regex-MYLANG=/define\\(([a-zA-Z]+)[ \\t]*,/\\1/d/{icase}\n--regex-MYLANG=/REGISTER\\(([a-zA-Z]+)\\)/\\1/r/i\n"
  },
  {
    "path": "Tmain/lregex-clear-patterns.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho '#' Add a pattern\n${CTAGS} --quiet --options=NONE \\\n\t\t --options=./mylang.ctags \\\n\t\t -o - \\\n\t\t input.c\n\necho '#' Clear the pattern\n${CTAGS} --quiet --options=NONE \\\n\t\t --options=./mylang.ctags \\\n\t\t --regex-MYLANG= \\\n\t\t -o - \\\n\t\t input.c\n"
  },
  {
    "path": "Tmain/lregex-clear-patterns.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/lregex-clear-patterns.d/stdout-expected.txt",
    "content": "# Add a pattern\neax\tinput.c\t/^register(eax);$/;\"\tr\nx\tinput.c\t/^DEFINE(x, 1);$/;\"\td\n# Clear the pattern\n"
  },
  {
    "path": "Tmain/lregex-kind-letter.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE\"\n\n. ../utils.sh\n\necho2 param: '|(.)|\\1|^ => ignoring'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|^' --list-kinds-full=x\n# In this case, ctags ignores the substring after the last '|'.\n# It is evaluated as flags.\n\necho2 param: '|(.)|\\1|^| => warning'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|^|' --list-kinds-full=x\n# In this case, ctags warns specifying a wrong kind letter '^'.\n\necho2 param: '|(.)|\\1|, => ignoring'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|,' --list-kinds-full=x\n# In this case, ctags ignores the substring after the last '|'.\n# It is evaluated as flags.\n\necho2 param: '|(.)|\\1|,| => using the default letter and name'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|,|' --list-kinds-full=x\n# In this case, ctags recognizes a kind letter and name\n# are not given; 'r' and \"regex\" are used as default values.\n"
  },
  {
    "path": "Tmain/lregex-kind-letter.d/stderr-expected.txt",
    "content": "param: |(.)|\\1|^ => ignoring\nparam: |(.)|\\1|^| => warning\nctags: Kind letter must be an alphabetical character: \"^\"\nparam: |(.)|\\1|, => ignoring\nparam: |(.)|\\1|,| => using the default letter and name\n"
  },
  {
    "path": "Tmain/lregex-kind-letter.d/stdout-expected.txt",
    "content": "param: |(.)|\\1|^ => ignoring\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nr       regex yes     no      0      NONE     0 regex\nparam: |(.)|\\1|^| => warning\nparam: |(.)|\\1|, => ignoring\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nr       regex yes     no      0      NONE     0 regex\nparam: |(.)|\\1|,| => using the default letter and name\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nr       regex yes     no      0      NONE     0 regex\n"
  },
  {
    "path": "Tmain/lregex-kind-name.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE\"\n\n. ../utils.sh\n\necho2 param: '|(.)|\\1|x,name| => acceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,name|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,name,documents| => acceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,name,documents|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,name,0documents| => acceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,name,0documents|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,name,doc uments| => acceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,name,doc uments|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,name0| => acceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,name0|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,name0,documents| => acceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,name0,documents|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,name0,0documents| => acceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,name0,0documents|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,name0,doc uments| => acceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,name0,doc uments|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,0name| => unacceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,0name|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,0name,documents| => unacceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,0name,documents|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,0name,0documents| => unacceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,0name,0documents|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,0name,doc uments| => unacceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,0name,doc uments|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,na me| => unacceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,na me|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,na me,documents| => unacceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,na me,documents|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,na me,0documents| => unacceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,na me,0documents|' --list-kinds-full=x\n\necho2 param: '|(.)|\\1|x,na me,doc uments| => unacceptable'\n${CTAGS} --langdef=x --regex-x='|(.)|\\1|x,na me,doc uments|' --list-kinds-full=x\n"
  },
  {
    "path": "Tmain/lregex-kind-name.d/stderr-expected.txt",
    "content": "param: |(.)|\\1|x,name| => acceptable\nparam: |(.)|\\1|x,name,documents| => acceptable\nparam: |(.)|\\1|x,name,0documents| => acceptable\nparam: |(.)|\\1|x,name,doc uments| => acceptable\nparam: |(.)|\\1|x,name0| => acceptable\nparam: |(.)|\\1|x,name0,documents| => acceptable\nparam: |(.)|\\1|x,name0,0documents| => acceptable\nparam: |(.)|\\1|x,name0,doc uments| => acceptable\nparam: |(.)|\\1|x,0name| => unacceptable\nctags: A kind name doesn't start with an alphabetical character: '0name' in \"--regex-x\" option\nparam: |(.)|\\1|x,0name,documents| => unacceptable\nctags: A kind name doesn't start with an alphabetical character: '0name' in \"--regex-x\" option\nparam: |(.)|\\1|x,0name,0documents| => unacceptable\nctags: A kind name doesn't start with an alphabetical character: '0name' in \"--regex-x\" option\nparam: |(.)|\\1|x,0name,doc uments| => unacceptable\nctags: A kind name doesn't start with an alphabetical character: '0name' in \"--regex-x\" option\nparam: |(.)|\\1|x,na me| => unacceptable\nctags: Non-alphanumeric char is used in kind name: 'na me' in \"--regex-x\" option\nparam: |(.)|\\1|x,na me,documents| => unacceptable\nctags: Non-alphanumeric char is used in kind name: 'na me' in \"--regex-x\" option\nparam: |(.)|\\1|x,na me,0documents| => unacceptable\nctags: Non-alphanumeric char is used in kind name: 'na me' in \"--regex-x\" option\nparam: |(.)|\\1|x,na me,doc uments| => unacceptable\nctags: Non-alphanumeric char is used in kind name: 'na me' in \"--regex-x\" option\n"
  },
  {
    "path": "Tmain/lregex-kind-name.d/stdout-expected.txt",
    "content": "param: |(.)|\\1|x,name| => acceptable\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       name yes     no      0      NONE     0 name\nparam: |(.)|\\1|x,name,documents| => acceptable\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       name yes     no      0      NONE     0 documents\nparam: |(.)|\\1|x,name,0documents| => acceptable\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       name yes     no      0      NONE     0 0documents\nparam: |(.)|\\1|x,name,doc uments| => acceptable\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       name yes     no      0      NONE     0 doc uments\nparam: |(.)|\\1|x,name0| => acceptable\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       name0 yes     no      0      NONE     0 name0\nparam: |(.)|\\1|x,name0,documents| => acceptable\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       name0 yes     no      0      NONE     0 documents\nparam: |(.)|\\1|x,name0,0documents| => acceptable\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       name0 yes     no      0      NONE     0 0documents\nparam: |(.)|\\1|x,name0,doc uments| => acceptable\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nx       name0 yes     no      0      NONE     0 doc uments\nparam: |(.)|\\1|x,0name| => unacceptable\nparam: |(.)|\\1|x,0name,documents| => unacceptable\nparam: |(.)|\\1|x,0name,0documents| => unacceptable\nparam: |(.)|\\1|x,0name,doc uments| => unacceptable\nparam: |(.)|\\1|x,na me| => unacceptable\nparam: |(.)|\\1|x,na me,documents| => unacceptable\nparam: |(.)|\\1|x,na me,0documents| => unacceptable\nparam: |(.)|\\1|x,na me,doc uments| => unacceptable\n"
  },
  {
    "path": "Tmain/lregex-list-kinds-full.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/lregex-list-kinds-full.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t --langdef=foo \\\n\t --regex-foo='/a/\\0/a,xy,x y z/' --kinds-foo=-a --kinds-foo=+a \\\n\t --regex-foo=/b/\\0/b/ --kinds-foo=-b \\\n\t --regex-foo=/c/\\0/c/ \\\n\t --kinds-foo=-c \\\n\t --regex-foo=/d/\\0/d/ \\\n\t --machinable \\\n\t --with-list-header \\\n\t --list-kinds-full=foo | sort\n"
  },
  {
    "path": "Tmain/lregex-list-kinds-full.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/lregex-list-kinds-full.d/stdout-expected.txt",
    "content": "#LETTER\tNAME\tENABLED\tREFONLY\tNROLES\tMASTER\tVER\tDESCRIPTION\na\txy\tyes\tno\t0\tNONE\t0\tx y z\nb\tregex\tno\tno\t0\tNONE\t0\tregex\nc\tregex\tno\tno\t0\tNONE\t0\tregex\nd\tregex\tyes\tno\t0\tNONE\t0\tregex\n"
  },
  {
    "path": "Tmain/lregex-list-kinds-uniquely.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE \\\n\t\t --langdef=X \\\n\t\t --regex-X='/./\\0/l,label,labels/' \\\n\t\t --regex-X='/./\\0/l,label,labels/' \\\n\t\t --list-kinds=X\n"
  },
  {
    "path": "Tmain/lregex-list-kinds-uniquely.d/stdout-expected.txt",
    "content": "l  labels\n"
  },
  {
    "path": "Tmain/lregex-list-kinds.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/lregex-list-kinds.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t --langdef=foo \\\n\t --regex-foo=/a/\\0/a/ --kinds-foo=-a --kinds-foo=+a \\\n\t --regex-foo=/b/\\0/b/ --kinds-foo=-b \\\n\t --regex-foo=/c/\\0/c/ \\\n\t --kinds-foo=-c \\\n\t --regex-foo=/d/\\0/d/ \\\n\t --list-kinds=foo | sort\n"
  },
  {
    "path": "Tmain/lregex-list-kinds.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/lregex-list-kinds.d/stdout-expected.txt",
    "content": "a  regex\nb  regex [off]\nc  regex [off]\nd  regex\n"
  },
  {
    "path": "Tmain/lregex-reject-reserved-kind.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/lregex-reject-reserved-kind.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE -o - --langdef=foo --regex-foo=/a/\\0/F/ run.sh ||\n${CTAGS} --quiet --options=NONE -o - --langdef=foo --regex-foo=/a/\\0/x,file/ run.sh\n"
  },
  {
    "path": "Tmain/lregex-reject-reserved-kind.d/stderr-expected.txt",
    "content": "ctags: Kind letter 'F' used in regex definition \"a\" of foo language is reserved in ctags main\nctags: Kind name \"file\" used in regex definition \"a\" of foo language is reserved in ctags main\n"
  },
  {
    "path": "Tmain/lregex-reject-reserved-kind.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/lregex-scan-the-rest-of-input.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/lregex-scan-the-rest-of-input.d/input.cst",
    "content": "Q\na\nb\nc\nd\ne\nf\ng\nrestdef:x\nrestdef:y\nrestdef:z\n\n\n"
  },
  {
    "path": "Tmain/lregex-scan-the-rest-of-input.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2023 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t\t --kinddef-CTagsSelfTest=a,name,names \\\n\t\t --regex-CTagsSelfTest='/restdef:([a-z])/\\1/a/' \\\n\t\t --language-force=CTagsSelfTest input.cst\n\nexit $?\n"
  },
  {
    "path": "Tmain/lregex-scan-the-rest-of-input.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/lregex-scan-the-rest-of-input.d/stdout-expected.txt",
    "content": "x\tinput.cst\t/^restdef:x$/;\"\ta\ny\tinput.cst\t/^restdef:y$/;\"\ta\nz\tinput.cst\t/^restdef:z$/;\"\ta\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/X.ctags",
    "content": "--langdef=X\n--kinddef-X=f,foo,foobars\n--_tabledef-X=main\n--_tabledef-X=sharp\n--_mtable-regex-X=main/^#///{tjump=sharp}{_advanceTo=0start}\n--_mtable-regex-X=sharp/^[^\\n]+[\\n]//{tjump=main}\n--mline-regex-X=/^#.*//{_guest=C,0start,0end}\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/Y-r-regex-with-kinddef.ctags",
    "content": "--langdef=Y3\n--map-Y3=.yyy\n--kinddef-Y3=r,regex,captured by regex patterns\n--regex-Y3=/^block//r/{_anonymous=yyy}\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/Y-r-regex.ctags",
    "content": "--langdef=Y2\n--map-Y2=.yyy\n--regex-Y2=/^block//r,regex/{_anonymous=yyy}\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/Y-r.ctags",
    "content": "--langdef=Y1\n--map-Y1=.yyy\n--regex-Y1=/^block//r/{_anonymous=yyy}\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/Y-regex.ctags",
    "content": "--langdef=Y2\n--map-Y2=.yyy\n--regex-Y2=/^block//,regex/{_anonymous=yyy}\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/Yempty1.ctags",
    "content": "--langdef=Ye0\n--map-Ye0=.yyy\n--regex-Ye0=/^block//,/{_anonymous=yyy}\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/Yempty2.ctags",
    "content": "--langdef=Ye1\n--map-Ye1=.yyy\n--regex-Ye1=/^block//,,/{_anonymous=yyy}\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/Ynokind.ctags",
    "content": "--langdef=Y0\n--map-Y0=.yyy\n--regex-Y0=/^block///{_anonymous=yyy}\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/input.yyy",
    "content": "block\nend\n\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE\"\nBUILDDIR=$2\n\n$CTAGS --options=X.ctags --list-kinds=X\n\necho \"# no kind is specified\" 1>&2\n$CTAGS --options=Ynokind.ctags -o $BUILDDIR/tags input.yyy\n\necho \"# no kind (empty,) is specified\" 1>&2\n$CTAGS --options=Yempty1.ctags -o $BUILDDIR/tags input.yyy\n\necho \"# no kind (empty,,) is specified\" 1>&2\n$CTAGS --options=Yempty2.ctags -o $BUILDDIR/tags input.yyy\n\necho \"# (r/) kind is specified inline\" 1>&2\n$CTAGS --options=Y-r.ctags -o $BUILDDIR/tags input.yyy\n\necho \"# (/regex) kind is specified inline\" 1>&2\n$CTAGS --options=Y-regex.ctags -o $BUILDDIR/tags input.yyy\n\necho \"# (r/regex) kind is specified inline\" 1>&2\n$CTAGS --options=Y-r-regex.ctags -o $BUILDDIR/tags input.yyy\n\necho \"# (r/regex) kind defined with --kinddef-<LANG> option\" 1>&2\n$CTAGS --options=Y-r-regex-with-kinddef.ctags -o $BUILDDIR/tags input.yyy\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/stderr-expected.txt",
    "content": "# no kind is specified\nctags: Warning: use \"_anonymous\" regex flag only with an explicitly defined kind\nctags: Warning: ^block: regexp missing name pattern\nctags: Warning: input.yyy:1: null expansion of name pattern \"\"\n# no kind (empty,) is specified\nctags: Warning: use \"_anonymous\" regex flag only with an explicitly defined kind\nctags: Warning: ^block: regexp missing name pattern\nctags: Warning: input.yyy:1: null expansion of name pattern \"\"\n# no kind (empty,,) is specified\nctags: Warning: use \"_anonymous\" regex flag only with an explicitly defined kind\nctags: Warning: ^block: regexp missing name pattern\nctags: Warning: input.yyy:1: null expansion of name pattern \"\"\n# (r/) kind is specified inline\n# (/regex) kind is specified inline\n# (r/regex) kind is specified inline\n# (r/regex) kind defined with --kinddef-<LANG> option\n"
  },
  {
    "path": "Tmain/lregex-unexpected-regex-kind.d/stdout-expected.txt",
    "content": "f  foobars\n"
  },
  {
    "path": "Tmain/map-for-unknown-language.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/map-for-unknown-language.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --map-nosuchlang=.Z\nexit $?\n"
  },
  {
    "path": "Tmain/map-for-unknown-language.d/stderr-expected.txt",
    "content": "ctags: Unknown language \"nosuchlang\" in \"map-nosuchlang\" option\n"
  },
  {
    "path": "Tmain/map-for-unknown-language.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/map-lang-option.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/map-lang-option.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n: &&\n    ${CTAGS} --quiet --options=NONE \\\n\t     --langdef=foo \\\n\t     --map-foo=.qqq \\\n\t     --map-foo='.rb' \\\n\t     --map-foo=+'([Mm]akefile)' \\\n\t     --map-foo=+'(GNUmakefile)' \\\n\t     --map-foo=+.html \\\n\t     --map-foo=+.ppp \\\n\t     --map-foo=+'(RUN.TTT)' \\\n\t     --list-maps | grep '\\.qqq\\|\\.ppp\\|\\.rb\\|\\.html\\|akefile\\|RUN.TTT'\nexit $?\n"
  },
  {
    "path": "Tmain/map-lang-option.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/map-lang-option.d/stdout-expected.txt",
    "content": "Automake Makefile.am GNUmakefile.am *.am\nHTML     *.htm *.html\nMake     [Mm]akefile GNUmakefile *.mak *.mk\nRake     Rakefile *.rake\nRuby     *.rb *.ruby\nfoo      [Mm]akefile GNUmakefile RUN.TTT *.rb *.html *.ppp\n"
  },
  {
    "path": "Tmain/map-removing.d/ada.m",
    "content": "-*- Ada -*-\n\n"
  },
  {
    "path": "Tmain/map-removing.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/map-removing.d/matlab.m",
    "content": "-*- matlab -*-\n"
  },
  {
    "path": "Tmain/map-removing.d/objc.m",
    "content": "-*- objc -*-\n"
  },
  {
    "path": "Tmain/map-removing.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\nif ! ( echo 'MatLab   *.m' | grep -E '\\*\\.m\\>.*$' > /dev/null); then\n\tskip \"'grep -E' needed in this case doesn't work expectedly\"\nfi\n\n\necho default map including '*.m'\necho =======================================\n${CTAGS} --quiet --options=NONE \\\n\t --list-maps | grep -E '\\*\\.m\\>.*$'\necho\n\necho '[--map-<LANG>]' removing from '*.m' from 'ObjectiveC'\necho =======================================\n${CTAGS} --quiet --options=NONE \\\n\t --map-ObjectiveC=-.m --list-maps | grep -E '\\*\\.m\\>.*$'\necho\n\necho '[--map-<LANG>]' adding '*.m' to 'Ada'\necho =======================================\n${CTAGS} --quiet --options=NONE \\\n\t --map-Ada=+.m --list-maps | grep -E '\\*\\.m\\>.*$'\necho\n\necho '[--map-<LANG>]' removing from '*.m' from 'ObjectiveC', and adding '*.m' to 'Ada'\necho =======================================\n${CTAGS} --quiet --options=NONE \\\n\t --map-ObjectiveC=-.m --map-Ada=+.m --list-maps | grep -E '\\*\\.m\\>.*$'\necho\n\necho '[--map-<LANG>]' guessing parser with adding '*.m' to 'Ada'\necho =======================================\n${CTAGS} --quiet --options=NONE \\\n\t --print-language       \\\n\t --map-Ada=+.m          \\\n\t ada.m matlab.m objc.m\necho\n\necho '[--map-<LANG> --guess-language-eagerly]' guessing parser with adding '*.m' to 'Ada'\necho =======================================\n${CTAGS} --quiet --options=NONE   \\\n\t --print-language         \\\n\t --map-Ada=+.m            \\\n\t --guess-language-eagerly \\\n\t ada.m matlab.m objc.m\necho\n\nX=xxxyyyzzz\necho 'Removing multi extension entries'\n${CTAGS} --quiet --options=NONE   \\\n\t --map-Pascal=.$X \\\n\t --map-Fortran=.$X \\\n\t --langmap=C:.$X \\\n\t --list-maps | grep $X\n\necho 'Removing multi pattern entries'\n${CTAGS} --quiet --options=NONE   \\\n\t --map-Pascal='('$X')' \\\n\t --map-Fortran='('$X')' \\\n\t --langmap=C:'('$X')' \\\n\t --list-maps | grep $X\n"
  },
  {
    "path": "Tmain/map-removing.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/map-removing.d/stdout-expected.txt",
    "content": "default map including *.m\n=======================================\nMatLab   *.m\nObjectiveC *.mm *.m *.h\n\n[--map-<LANG>] removing from *.m from ObjectiveC\n=======================================\nMatLab   *.m\n\n[--map-<LANG>] adding *.m to Ada\n=======================================\nAda      *.adb *.ads *.Ada *.ada *.m\nMatLab   *.m\nObjectiveC *.mm *.m *.h\n\n[--map-<LANG>] removing from *.m from ObjectiveC, and adding *.m to Ada\n=======================================\nAda      *.adb *.ads *.Ada *.ada *.m\nMatLab   *.m\n\n[--map-<LANG>] guessing parser with adding *.m to Ada\n=======================================\nada.m: Ada\nmatlab.m: Ada\nobjc.m: Ada\n\n[--map-<LANG> --guess-language-eagerly] guessing parser with adding *.m to Ada\n=======================================\nada.m: Ada\nmatlab.m: MatLab\nobjc.m: ObjectiveC\n\nRemoving multi extension entries\nC        *.xxxyyyzzz\nRemoving multi pattern entries\nC        xxxyyyzzz\n"
  },
  {
    "path": "Tmain/map-rexpr.d/macros.d/macros.vim",
    "content": "%vimfiles_root %{_datadir}/vim/vimfiles\n"
  },
  {
    "path": "Tmain/map-rexpr.d/run.sh",
    "content": "# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\necho \"# < macros.d/macros.vm\"\n${CTAGS} --quiet --options=NONE --print-language macros.d/macros.vim\n${CTAGS} --quiet --options=NONE -o - macros.d/macros.vim\n\necho \"# cd macros.d; < macros.vim\"\n(\n\tcd macros.d;\n\t${CTAGS} --quiet --options=NONE --print-language macros.vim;\n\t${CTAGS} --quiet --options=NONE -o - macros.vim\n)\n"
  },
  {
    "path": "Tmain/map-rexpr.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/map-rexpr.d/stdout-expected.txt",
    "content": "# < macros.d/macros.vm\nmacros.d/macros.vim: RpmMacros\nvimfiles_root\tmacros.d/macros.vim\t/^%vimfiles_root %{_datadir}\\/vim\\/vimfiles$/;\"\tm\n# cd macros.d; < macros.vim\nmacros.vim: Vim\n"
  },
  {
    "path": "Tmain/maxdepth.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho '# DEPTH=1'\n${CTAGS} --quiet --options=NONE --maxdepth=1 -R -o - ./src\necho '# DEPTH=2'\n${CTAGS} --quiet --options=NONE --maxdepth=2 -R -o - ./src\nexit $?\n"
  },
  {
    "path": "Tmain/maxdepth.d/src/a.c",
    "content": "int a (void)\n{\n  return 0;\n}\n"
  },
  {
    "path": "Tmain/maxdepth.d/src/subdir/b.c",
    "content": "int b(void)\n{\n  return 0;\n}\n\n"
  },
  {
    "path": "Tmain/maxdepth.d/stdout-expected.txt",
    "content": "# DEPTH=1\na\t./src/a.c\t/^int a (void)$/;\"\tf\ttyperef:typename:int\n# DEPTH=2\na\t./src/a.c\t/^int a (void)$/;\"\tf\ttyperef:typename:int\nb\t./src/subdir/b.c\t/^int b(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/mline-no-advance.d/args.ctags",
    "content": "--mline-regex-FOO=/(.)/\\1/{_advanceTo=1start}\n"
  },
  {
    "path": "Tmain/mline-no-advance.d/input.foo",
    "content": "a\n"
  },
  {
    "path": "Tmain/mline-no-advance.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --options=NONE \\\n\t\t --langdef=FOO  \\\n\t\t --map-FOO=+.foo \\\n\t\t --options=./args.ctags \\\n\t\t -o - \\\n\t\t ./input.foo\n"
  },
  {
    "path": "Tmain/mline-no-advance.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nctags: Warning: FOO: no {mgroup=N} flag given in --mline-regex-<LANG>=/(.)/\\1/{_advanceTo=1start}... (addTagRegexOption)\nctags: Warning: a multi line regex pattern doesn't advance the input cursor: (.)\nctags: Warning: Language: FOO, input file: ./input.foo, pos: 0\n"
  },
  {
    "path": "Tmain/mtable-avoid-infinite-loop-at-the-eof.d/args.ctags",
    "content": "--langdef=FOO\n--map-FOO=+.foo\n--_tabledef-FOO=main\n--kinddef-FOO=e,eof,the end of file\n--_mtable-regex-FOO=main//eof/e/\n"
  },
  {
    "path": "Tmain/mtable-avoid-infinite-loop-at-the-eof.d/input.foo",
    "content": ""
  },
  {
    "path": "Tmain/mtable-avoid-infinite-loop-at-the-eof.d/input2.foo",
    "content": "a"
  },
  {
    "path": "Tmain/mtable-avoid-infinite-loop-at-the-eof.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --options=NONE --options=./args.ctags --sort=no -o - ./input.foo ./input2.foo\n"
  },
  {
    "path": "Tmain/mtable-avoid-infinite-loop-at-the-eof.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nctags: Warning: Forcefully advance the input pos because\nctags: Warning: following conditions for entering infinite loop are satisfied:\nctags: Warning: + matching the pattern succeeds,\nctags: Warning: + the next table is not given, and\nctags: Warning: + the input file pos doesn't advance.\nctags: Warning: Language: FOO, input file: ./input.foo, pos: 0\nctags: Warning: Forcefully advance the input pos because\nctags: Warning: following conditions for entering infinite loop are satisfied:\nctags: Warning: + matching the pattern succeeds,\nctags: Warning: + the next table is not given, and\nctags: Warning: + the input file pos doesn't advance.\nctags: Warning: Language: FOO, input file: ./input2.foo, pos: 0\nctags: Warning: Forcefully advance the input pos because\nctags: Warning: following conditions for entering infinite loop are satisfied:\nctags: Warning: + matching the pattern succeeds,\nctags: Warning: + the next table is not given, and\nctags: Warning: + the input file pos doesn't advance.\nctags: Warning: Language: FOO, input file: ./input2.foo, pos: 1\n"
  },
  {
    "path": "Tmain/mtable-avoid-infinite-loop-at-the-eof.d/stdout-expected.txt",
    "content": "eof\t./input.foo\t/^/;\"\te\neof\t./input2.foo\t/^a/;\"\te\neof\t./input2.foo\t/^a/;\"\te\n"
  },
  {
    "path": "Tmain/mtable-mutual-entering.d/args.ctags",
    "content": "--langdef=FOO\n--map-FOO=+.foo\n--_tabledef-FOO=A\n--_tabledef-FOO=B\n\n--_mtable-regex-FOO=A/define (.)/\\1/\n\n--_mtable-regex-FOO=A/([a-z]*)///{tenter=B}\n--_mtable-regex-FOO=B/([a-z]*)///{tenter=A}\n\n\n--langdef=BAR\n--map-BAR=+.bar\n--_tabledef-BAR=C\n--_tabledef-BAR=D\n--_mtable-regex-BAR=C/([a-z]*)///{tenter=D}\n--_mtable-regex-BAR=D/([a-z]*)///{tenter=C}\n\n--langdef=BAZ\n--map-BAZ=+.baz\n--_tabledef-BAZ=E\n--_tabledef-BAZ=F\n--_mtable-regex-BAZ=E/([0-9])///{tenter=F}\n--_mtable-regex-BAZ=F/([0-9])///{tenter=E}\n"
  },
  {
    "path": "Tmain/mtable-mutual-entering.d/input0.foo",
    "content": ""
  },
  {
    "path": "Tmain/mtable-mutual-entering.d/input1.foo",
    "content": "define x\n"
  },
  {
    "path": "Tmain/mtable-mutual-entering.d/input2.bar",
    "content": ""
  },
  {
    "path": "Tmain/mtable-mutual-entering.d/input3.baz",
    "content": "0123456789012345678901234567890123456789012345678901234567890123456789\n"
  },
  {
    "path": "Tmain/mtable-mutual-entering.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --options=NONE --options=./args.ctags -o - \\\n\t\t ./input0.foo ./input1.foo \\\n\t\t ./input2.bar \\\n\t\t ./input3.baz\n"
  },
  {
    "path": "Tmain/mtable-mutual-entering.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nctags: Warning: mtable<FOO/B>: the tenter/tleave stack overflows at 0 in ./input0.foo\nctags: Warning: DUMP FROM THE TOP:\nctags: Warning:  64 A\nctags: Warning:  63 B\nctags: Warning:  62 A\nctags: Warning:  61 B\nctags: Warning:  60 A\nctags: Warning:  59 B\nctags: Warning:  58 A\nctags: Warning:  57 B\nctags: Warning:  56 A\nctags: Warning:  55 B\nctags: Warning:  54 A\nctags: Warning:  53 B\nctags: Warning:  52 A\nctags: Warning:  51 B\nctags: Warning:  50 A\nctags: Warning:  49 B\nctags: Warning:  48 A\nctags: Warning:  47 B\nctags: Warning:  46 A\nctags: Warning:  45 B\nctags: Warning:  44 A\nctags: Warning:  43 B\nctags: Warning:  42 A\nctags: Warning:  41 B\nctags: Warning:  40 A\nctags: Warning:  39 B\nctags: Warning:  38 A\nctags: Warning:  37 B\nctags: Warning:  36 A\nctags: Warning:  35 B\nctags: Warning:  34 A\nctags: Warning:  33 B\nctags: Warning:  32 A\nctags: Warning:  31 B\nctags: Warning:  30 A\nctags: Warning:  29 B\nctags: Warning:  28 A\nctags: Warning:  27 B\nctags: Warning:  26 A\nctags: Warning:  25 B\nctags: Warning:  24 A\nctags: Warning:  23 B\nctags: Warning:  22 A\nctags: Warning:  21 B\nctags: Warning:  20 A\nctags: Warning:  19 B\nctags: Warning:  18 A\nctags: Warning:  17 B\nctags: Warning:  16 A\nctags: Warning:  15 B\nctags: Warning:  14 A\nctags: Warning:  13 B\nctags: Warning:  12 A\nctags: Warning:  11 B\nctags: Warning:  10 A\nctags: Warning:   9 B\nctags: Warning:   8 A\nctags: Warning:   7 B\nctags: Warning:   6 A\nctags: Warning:   5 B\nctags: Warning:   4 A\nctags: Warning:   3 B\nctags: Warning:   2 A\nctags: Warning:   1 B\nctags: Warning:   0 A\nctags: Warning: mtable<FOO/B>: the tenter/tleave stack overflows at 8 in ./input1.foo\nctags: Warning: DUMP FROM THE TOP:\nctags: Warning:  64 A\nctags: Warning:  63 B\nctags: Warning:  62 A\nctags: Warning:  61 B\nctags: Warning:  60 A\nctags: Warning:  59 B\nctags: Warning:  58 A\nctags: Warning:  57 B\nctags: Warning:  56 A\nctags: Warning:  55 B\nctags: Warning:  54 A\nctags: Warning:  53 B\nctags: Warning:  52 A\nctags: Warning:  51 B\nctags: Warning:  50 A\nctags: Warning:  49 B\nctags: Warning:  48 A\nctags: Warning:  47 B\nctags: Warning:  46 A\nctags: Warning:  45 B\nctags: Warning:  44 A\nctags: Warning:  43 B\nctags: Warning:  42 A\nctags: Warning:  41 B\nctags: Warning:  40 A\nctags: Warning:  39 B\nctags: Warning:  38 A\nctags: Warning:  37 B\nctags: Warning:  36 A\nctags: Warning:  35 B\nctags: Warning:  34 A\nctags: Warning:  33 B\nctags: Warning:  32 A\nctags: Warning:  31 B\nctags: Warning:  30 A\nctags: Warning:  29 B\nctags: Warning:  28 A\nctags: Warning:  27 B\nctags: Warning:  26 A\nctags: Warning:  25 B\nctags: Warning:  24 A\nctags: Warning:  23 B\nctags: Warning:  22 A\nctags: Warning:  21 B\nctags: Warning:  20 A\nctags: Warning:  19 B\nctags: Warning:  18 A\nctags: Warning:  17 B\nctags: Warning:  16 A\nctags: Warning:  15 B\nctags: Warning:  14 A\nctags: Warning:  13 B\nctags: Warning:  12 A\nctags: Warning:  11 B\nctags: Warning:  10 A\nctags: Warning:   9 B\nctags: Warning:   8 A\nctags: Warning:   7 B\nctags: Warning:   6 A\nctags: Warning:   5 B\nctags: Warning:   4 A\nctags: Warning:   3 B\nctags: Warning:   2 A\nctags: Warning:   1 B\nctags: Warning:   0 A\nctags: Warning: mtable<BAR/D>: the tenter/tleave stack overflows at 0 in ./input2.bar\nctags: Warning: DUMP FROM THE TOP:\nctags: Warning:  64 C\nctags: Warning:  63 D\nctags: Warning:  62 C\nctags: Warning:  61 D\nctags: Warning:  60 C\nctags: Warning:  59 D\nctags: Warning:  58 C\nctags: Warning:  57 D\nctags: Warning:  56 C\nctags: Warning:  55 D\nctags: Warning:  54 C\nctags: Warning:  53 D\nctags: Warning:  52 C\nctags: Warning:  51 D\nctags: Warning:  50 C\nctags: Warning:  49 D\nctags: Warning:  48 C\nctags: Warning:  47 D\nctags: Warning:  46 C\nctags: Warning:  45 D\nctags: Warning:  44 C\nctags: Warning:  43 D\nctags: Warning:  42 C\nctags: Warning:  41 D\nctags: Warning:  40 C\nctags: Warning:  39 D\nctags: Warning:  38 C\nctags: Warning:  37 D\nctags: Warning:  36 C\nctags: Warning:  35 D\nctags: Warning:  34 C\nctags: Warning:  33 D\nctags: Warning:  32 C\nctags: Warning:  31 D\nctags: Warning:  30 C\nctags: Warning:  29 D\nctags: Warning:  28 C\nctags: Warning:  27 D\nctags: Warning:  26 C\nctags: Warning:  25 D\nctags: Warning:  24 C\nctags: Warning:  23 D\nctags: Warning:  22 C\nctags: Warning:  21 D\nctags: Warning:  20 C\nctags: Warning:  19 D\nctags: Warning:  18 C\nctags: Warning:  17 D\nctags: Warning:  16 C\nctags: Warning:  15 D\nctags: Warning:  14 C\nctags: Warning:  13 D\nctags: Warning:  12 C\nctags: Warning:  11 D\nctags: Warning:  10 C\nctags: Warning:   9 D\nctags: Warning:   8 C\nctags: Warning:   7 D\nctags: Warning:   6 C\nctags: Warning:   5 D\nctags: Warning:   4 C\nctags: Warning:   3 D\nctags: Warning:   2 C\nctags: Warning:   1 D\nctags: Warning:   0 C\nctags: Warning: mtable<BAZ/F>: the tenter/tleave stack overflows at 65 in ./input3.baz\nctags: Warning: DUMP FROM THE TOP:\nctags: Warning:  64 E\nctags: Warning:  63 F\nctags: Warning:  62 E\nctags: Warning:  61 F\nctags: Warning:  60 E\nctags: Warning:  59 F\nctags: Warning:  58 E\nctags: Warning:  57 F\nctags: Warning:  56 E\nctags: Warning:  55 F\nctags: Warning:  54 E\nctags: Warning:  53 F\nctags: Warning:  52 E\nctags: Warning:  51 F\nctags: Warning:  50 E\nctags: Warning:  49 F\nctags: Warning:  48 E\nctags: Warning:  47 F\nctags: Warning:  46 E\nctags: Warning:  45 F\nctags: Warning:  44 E\nctags: Warning:  43 F\nctags: Warning:  42 E\nctags: Warning:  41 F\nctags: Warning:  40 E\nctags: Warning:  39 F\nctags: Warning:  38 E\nctags: Warning:  37 F\nctags: Warning:  36 E\nctags: Warning:  35 F\nctags: Warning:  34 E\nctags: Warning:  33 F\nctags: Warning:  32 E\nctags: Warning:  31 F\nctags: Warning:  30 E\nctags: Warning:  29 F\nctags: Warning:  28 E\nctags: Warning:  27 F\nctags: Warning:  26 E\nctags: Warning:  25 F\nctags: Warning:  24 E\nctags: Warning:  23 F\nctags: Warning:  22 E\nctags: Warning:  21 F\nctags: Warning:  20 E\nctags: Warning:  19 F\nctags: Warning:  18 E\nctags: Warning:  17 F\nctags: Warning:  16 E\nctags: Warning:  15 F\nctags: Warning:  14 E\nctags: Warning:  13 F\nctags: Warning:  12 E\nctags: Warning:  11 F\nctags: Warning:  10 E\nctags: Warning:   9 F\nctags: Warning:   8 E\nctags: Warning:   7 F\nctags: Warning:   6 E\nctags: Warning:   5 F\nctags: Warning:   4 E\nctags: Warning:   3 F\nctags: Warning:   2 E\nctags: Warning:   1 F\nctags: Warning:   0 E\n"
  },
  {
    "path": "Tmain/mtable-mutual-entering.d/stdout-expected.txt",
    "content": "x\t./input1.foo\t/^define x$/;\"\tr\n"
  },
  {
    "path": "Tmain/mtable-pinning.d/args.ctags",
    "content": "--langdef=FOO\n--map-FOO=+.foo\n--_tabledef-FOO=A\n--_tabledef-FOO=B\n\n--_mtable-regex-FOO=A/x//{tjump=B}{_advanceTo=0start}\n--_mtable-regex-FOO=B/x//{tjump=A}{_advanceTo=0start}\n\n--_mtable-regex-FOO=A/y//{tjump=A}{_advanceTo=0start}\n"
  },
  {
    "path": "Tmain/mtable-pinning.d/input0.foo",
    "content": "x\n"
  },
  {
    "path": "Tmain/mtable-pinning.d/input1.foo",
    "content": "y\n"
  },
  {
    "path": "Tmain/mtable-pinning.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --options=NONE --options=./args.ctags -o - \\\n\t\t ./input0.foo \\\n\t\t ./input1.foo\n"
  },
  {
    "path": "Tmain/mtable-pinning.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nctags: Warning: mtable<FOO/A>: the input cursor stays at 0 in ./input0.foo so long though the tables are switched\nctags: Warning: mtable<FOO/A>: the input cursor stays at 0 in ./input1.foo so long though the tables are switched\n"
  },
  {
    "path": "Tmain/mtable-stats.d/args.ctags",
    "content": "--langdef=FOO\n--map-FOO=+.foo\n\n--kinddef-FOO=n,namespace,namespaces\n--kinddef-FOO=c,class,classes\n--kinddef-FOO=v,variable,variables\n\n--_tabledef-FOO=main\n--_tabledef-FOO=block\n--_tabledef-FOO=blockEnd\n--_tabledef-FOO=skipWhitespace\n\n--_mtable-regex-FOO=skipWhitespace/[ \\t\\n]+//\n\n--_mtable-regex-FOO=main/namespace ([a-zA-Z]+) \\{/\\1/n/{tenter=block,blockEnd}{scope=push}\n--_mtable-extend-FOO=main+skipWhitespace\n--_mtable-regex-FOO=main///\n\n--_mtable-regex-FOO=blockEnd/\\};?//{scope=pop}\n--_mtable-extend-FOO=blockEnd+skipWhitespace\n\n--_mtable-regex-FOO=block/class ([a-zA-Z]+) \\{/\\1/c/{tenter=block,blockEnd}{scope=ref}{scope=push}\n--_mtable-regex-FOO=block/var ([a-zA-Z]+) ([a-zA-Z]+);/\\2/v/{scope=ref}\n--_mtable-extend-FOO=block+skipWhitespace\n"
  },
  {
    "path": "Tmain/mtable-stats.d/input.foo",
    "content": "namespace A {\n\tclass B {\n\t\tvar bool C;\n\t};\n}\n"
  },
  {
    "path": "Tmain/mtable-stats.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nstats=/tmp/ctags-Tmain-$$\n${CTAGS} --quiet --options=NONE --options=./args.ctags --totals=extra -o - ./input.foo 2> ${stats}\nsed -n -e '/^MTABLE REGEX.*/,$p' ${stats} 1>&2\nrm ${stats}\n"
  },
  {
    "path": "Tmain/mtable-stats.d/stderr-expected.txt",
    "content": "MTABLE REGEX STATISTICS of FOO\n==============================================\nmain\n-----------------------\n         1/1         ^namespace ([a-zA-Z]+) \\\\{               ref: 1\n         0/0         ^[ \\t\\n]+                                ref: 4\n         0/0         ^                                        ref: 1\n\nblock\n-----------------------\n         1/6         ^class ([a-zA-Z]+) \\\\{                   ref: 1\n         1/5         ^var ([a-zA-Z]+) ([a-zA-Z]+);            ref: 1\n         3/4         ^[ \\t\\n]+                                ref: 4\n\nblockEnd\n-----------------------\n         2/6         ^\\\\};?                                   ref: 1\n         2/4         ^[ \\t\\n]+                                ref: 4\n\nskipWhitespace\n-----------------------\n         0/0         ^[ \\t\\n]+                                ref: 4\n\n"
  },
  {
    "path": "Tmain/mtable-stats.d/stdout-expected.txt",
    "content": "A\t./input.foo\t/^namespace A {$/;\"\tn\nB\t./input.foo\t/^\tclass B {$/;\"\tc\tnamespace:A\nC\t./input.foo\t/^\t\tvar bool C;$/;\"\tv\tclass:A.B\n"
  },
  {
    "path": "Tmain/multi-roles.d/input.x",
    "content": "r\nR\n"
  },
  {
    "path": "Tmain/multi-roles.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\necho '# rolesDisabled is kept disabled'\n$CTAGS --quiet --options=NONE  --sort=no --language-force=CTagsSelfTest --extras=r --fields=Kr -o - input.x\necho '# rolesDisabled is enabled'\n$CTAGS --quiet --options=NONE  --sort=no --language-force=CTagsSelfTest --extras=r --fields=Kr --kinds-CTagsSelfTest=+R -o - input.x\n\nexit $?\n"
  },
  {
    "path": "Tmain/multi-roles.d/stdout-expected.txt",
    "content": "# rolesDisabled is kept disabled\nmultiRolesTarget\tinput.x\t/^r$/;\"\troles\troles:a,b,d\n# rolesDisabled is enabled\nmultiRolesTarget\tinput.x\t/^r$/;\"\troles\troles:a,b,d\nmultiRolesDisabledTarget\tinput.x\t/^R$/;\"\trolesDisabled\troles:A\nmultiRolesDisabledTarget\tinput.x\t/^R$/;\"\trolesDisabled\troles:B\n"
  },
  {
    "path": "Tmain/nameless-long-option.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/nameless-long-option.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --options=NONE --\nexit $?\n"
  },
  {
    "path": "Tmain/nameless-long-option.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nctags: Unknown option: --\n"
  },
  {
    "path": "Tmain/nameless-long-option.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/nested-mio.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/nested-mio.d/input.cst",
    "content": "B\nN\nE\n"
  },
  {
    "path": "Tmain/nested-mio.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --options=NONE -o - --extras=+g --language-force=CTagsSelfTest input.cst\nexit $?\n"
  },
  {
    "path": "Tmain/nested-mio.d/stdout-expected.txt",
    "content": "NOTHING_SPECIAL\tinput.cst\t/^N$/;\"\tN\n"
  },
  {
    "path": "Tmain/nested-subparsers-multilines.d/event.ctags",
    "content": "--langdef=Event{base=C}\n--kinddef-Event=e,event,events\n--mline-regex-Event=/DEFINE_EVENT\\(([^;]|[[:space:]])*[[:space:],]([a-zA-Z_][a-zA-Z0-9_]*)\\);/\\2/e/{mgroup=1}\n"
  },
  {
    "path": "Tmain/nested-subparsers-multilines.d/hook.ctags",
    "content": "--langdef=Hook{base=Event}\n--kinddef-Hook=h,hook,hooks\n--mline-regex-Hook=/DEFINE_HOOK\\(([^;]|[[:space:]])*[[:space:],]([a-zA-Z_][a-zA-Z0-9_]*)\\);/\\2/h/{mgroup=1}\n\n\n"
  },
  {
    "path": "Tmain/nested-subparsers-multilines.d/input.c",
    "content": "DEFINE_EVENT(a,\n\t\t\t b);\n\nDEFINE_HOOK(h,\n\t\t\ti);\n\nint\nmain(void)\n{\n}\n"
  },
  {
    "path": "Tmain/nested-subparsers-multilines.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\n\n${CTAGS} --quiet --options=NONE \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --fields=+lK \\\n\t\t -o - input.c\n"
  },
  {
    "path": "Tmain/nested-subparsers-multilines.d/stdout-expected.txt",
    "content": "b\tinput.c\t/^\t\t\t b);$/;\"\tevent\tlanguage:Event\ni\tinput.c\t/^\t\t\ti);$/;\"\thook\tlanguage:Hook\nmain\tinput.c\t/^main(void)$/;\"\tfunction\tlanguage:C\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/nested-subparsers.d/event.ctags",
    "content": "--langdef=Event{base=C}\n--kinddef-Event=e,event,events\n--regex-Event=/DEFINE_EVENT\\((.*)\\);/\\1/e/\n"
  },
  {
    "path": "Tmain/nested-subparsers.d/hook.ctags",
    "content": "--langdef=Hook{base=Event}\n--kinddef-Hook=h,hook,hooks\n--regex-Hook=/DEFINE_HOOK\\((.*)\\);/\\1/h/'\n\n"
  },
  {
    "path": "Tmain/nested-subparsers.d/input.c",
    "content": "DEFINE_EVENT(a);\nDEFINE_EVENT(b);\nDEFINE_HOOK(h);\nDEFINE_HOOK(i);\nint\nmain(void)\n{\n\tLOAD_PLUGIN(mylib.so, isearch);\n\tint u __attribute__((unused));\n}\n"
  },
  {
    "path": "Tmain/nested-subparsers.d/plugin.ctags",
    "content": "--langdef=Plugin{base=C}\n--kinddef-Plugin=f,File,files\n--kinddef-Plugin=n,name,name\n--regex-Plugin=/LOAD_PLUGIN\\((.*),[ \\t]*(.*)\\);/\\1/f/\n--regex-Plugin=/LOAD_PLUGIN\\((.*),[ \\t]*(.*)\\);/\\2/n/\n"
  },
  {
    "path": "Tmain/nested-subparsers.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE  --fields=+lK\"\n\nlist_kinds()\n{\n\techo '#'\n\techo '#' list kinds$2 $1\n\techo '#'\n\t${CTAGS}  -o - \\\n\t\t\t --options=./event.ctags \\\n\t\t\t --options=./hook.ctags \\\n\t\t\t --options=./plugin.ctags \\\n\t\t\t --list-kinds$2=$1\n}\n\nlist_kinds C\nlist_kinds Event\nlist_kinds Hook\nlist_kinds Plugin\n\nlist_kinds C -full\nlist_kinds Event -full\nlist_kinds Hook -full\nlist_kinds Plugin -full\n\necho C only\n${CTAGS} -o - input.c\n\necho\necho C + EVENT\n${CTAGS} -o - \\\n\t\t --options=./event.ctags \\\n\t\t input.c\n\n\necho\necho C + EVENT + HOOK\n${CTAGS}  -o - \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t input.c\n\necho\necho C + EVENT + HOOK + PLUGIN\n${CTAGS}  -o - \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --options=./plugin.ctags \\\n\t\t input.c\n\necho\necho C + EVENT + HOOK + PLUGIN + UA\n${CTAGS}  -o - \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --options=./plugin.ctags \\\n\t\t --options=./unused-attr.ctags \\\n\t\t input.c\n\necho\necho 'C(disabled)' + EVENT + HOOK + PLUGIN + UA\n${CTAGS}  -o - \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --options=./plugin.ctags \\\n\t\t --options=./unused-attr.ctags \\\n\t\t --languages=-C \\\n\t\t input.c\n\necho\necho C + 'EVENT(disabled)' + HOOK + PLUGIN + UA\n${CTAGS}  -o - \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --options=./plugin.ctags \\\n\t\t --options=./unused-attr.ctags \\\n\t\t --languages=-Event \\\n\t\t input.c\n\necho\necho C + 'EVENT' + 'HOOK(disabled)' + PLUGIN + UA\n${CTAGS}  -o - \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --options=./plugin.ctags \\\n\t\t --options=./unused-attr.ctags \\\n\t\t --languages=-Hook \\\n\t\t input.c\n\necho\necho C + 'EVENT' + 'HOOK' + PLUGIN + 'UA(-v)'\n${CTAGS}  -o - \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --options=./plugin.ctags \\\n\t\t --options=./unused-attr.ctags \\\n\t\t --kinds-UnusedAttr=-v \\\n\t\t input.c\n\necho List subparsers of C '(' 'EVENT' + 'HOOK' + PLUGIN + 'UA' ')'\n${CTAGS}  \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --options=./plugin.ctags \\\n\t\t --options=./unused-attr.ctags \\\n\t\t --list-subparsers=C\n\necho List subparsers of C '(' 'EVENT' + 'HOOK' + PLUGIN + 'UA' ')' without the header\n${CTAGS} --with-list-header=no \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --options=./plugin.ctags \\\n\t\t --options=./unused-attr.ctags \\\n\t\t --list-subparsers=C\n\necho List subparsers of C '(' 'EVENT' + 'HOOK' + PLUGIN + 'UA' ')' in machinable\n${CTAGS}  \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --options=./plugin.ctags \\\n\t\t --options=./unused-attr.ctags \\\n\t\t --machinable \\\n\t\t --list-subparsers=C\n\necho List subparsers of C '(' 'EVENT' + 'HOOK' + PLUGIN + 'UA' ')' in machinable without the header\n${CTAGS} --with-list-header=no \\\n\t\t --options=./event.ctags \\\n\t\t --options=./hook.ctags \\\n\t\t --options=./plugin.ctags \\\n\t\t --options=./unused-attr.ctags \\\n\t\t --machinable \\\n\t\t --list-subparsers=C\n"
  },
  {
    "path": "Tmain/nested-subparsers.d/stdout-expected.txt",
    "content": "#\n# list kinds C\n#\nd  macro definitions\ne  enumerators (values inside an enumeration)\nf  function definitions\ng  enumeration names\nh  included header files\nl  local variables [off]\nm  struct, and union members\np  function prototypes [off]\ns  structure names\nt  typedefs\nu  union names\nv  variable definitions\nx  external and forward variable declarations [off]\nz  function parameters inside function or prototype definitions [off]\nL  goto labels [off]\nD  parameters inside macro definitions [off]\n#\n# list kinds Event\n#\ne  events\n#\n# list kinds Hook\n#\nh  hooks\n#\n# list kinds Plugin\n#\nf  files\nn  name\n#\n# list kinds-full C\n#\n#LETTER NAME       ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nD       macroparam no      no      0      C        0 parameters inside macro definitions\nL       label      no      no      0      C        0 goto labels\nd       macro      yes     no      2      C        0 macro definitions\ne       enumerator yes     no      0      C        0 enumerators (values inside an enumeration)\nf       function   yes     no      2      C        0 function definitions\ng       enum       yes     no      0      C        0 enumeration names\nh       header     yes     yes     2      C        0 included header files\nl       local      no      no      0      C        0 local variables\nm       member     yes     no      0      C        0 struct, and union members\np       prototype  no      no      0      C        0 function prototypes\ns       struct     yes     no      1      C        0 structure names\nt       typedef    yes     no      0      C        0 typedefs\nu       union      yes     no      0      C        0 union names\nv       variable   yes     no      0      C        0 variable definitions\nx       externvar  no      no      0      C        0 external and forward variable declarations\nz       parameter  no      no      0      C        0 function parameters inside function or prototype definitions\n#\n# list kinds-full Event\n#\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\ne       event yes     no      0      NONE     0 events\n#\n# list kinds-full Hook\n#\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nh       hook yes     no      0      NONE     0 hooks\n#\n# list kinds-full Plugin\n#\n#LETTER NAME ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nf       File yes     no      0      NONE     0 files\nn       name yes     no      0      NONE     0 name\nC only\nmain\tinput.c\t/^main(void)$/;\"\tfunction\tlanguage:C\ttyperef:typename:int\n\nC + EVENT\na\tinput.c\t/^DEFINE_EVENT(a);$/;\"\tevent\tlanguage:Event\nb\tinput.c\t/^DEFINE_EVENT(b);$/;\"\tevent\tlanguage:Event\nmain\tinput.c\t/^main(void)$/;\"\tfunction\tlanguage:C\ttyperef:typename:int\n\nC + EVENT + HOOK\na\tinput.c\t/^DEFINE_EVENT(a);$/;\"\tevent\tlanguage:Event\nb\tinput.c\t/^DEFINE_EVENT(b);$/;\"\tevent\tlanguage:Event\nh\tinput.c\t/^DEFINE_HOOK(h);$/;\"\thook\tlanguage:Hook\ni\tinput.c\t/^DEFINE_HOOK(i);$/;\"\thook\tlanguage:Hook\nmain\tinput.c\t/^main(void)$/;\"\tfunction\tlanguage:C\ttyperef:typename:int\n\nC + EVENT + HOOK + PLUGIN\na\tinput.c\t/^DEFINE_EVENT(a);$/;\"\tevent\tlanguage:Event\nb\tinput.c\t/^DEFINE_EVENT(b);$/;\"\tevent\tlanguage:Event\nh\tinput.c\t/^DEFINE_HOOK(h);$/;\"\thook\tlanguage:Hook\ni\tinput.c\t/^DEFINE_HOOK(i);$/;\"\thook\tlanguage:Hook\nisearch\tinput.c\t/^\tLOAD_PLUGIN(mylib.so, isearch);$/;\"\tname\tlanguage:Plugin\nmain\tinput.c\t/^main(void)$/;\"\tfunction\tlanguage:C\ttyperef:typename:int\nmylib.so\tinput.c\t/^\tLOAD_PLUGIN(mylib.so, isearch);$/;\"\tFile\tlanguage:Plugin\n\nC + EVENT + HOOK + PLUGIN + UA\na\tinput.c\t/^DEFINE_EVENT(a);$/;\"\tevent\tlanguage:Event\nb\tinput.c\t/^DEFINE_EVENT(b);$/;\"\tevent\tlanguage:Event\nh\tinput.c\t/^DEFINE_HOOK(h);$/;\"\thook\tlanguage:Hook\ni\tinput.c\t/^DEFINE_HOOK(i);$/;\"\thook\tlanguage:Hook\nisearch\tinput.c\t/^\tLOAD_PLUGIN(mylib.so, isearch);$/;\"\tname\tlanguage:Plugin\nmain\tinput.c\t/^main(void)$/;\"\tfunction\tlanguage:C\ttyperef:typename:int\nmylib.so\tinput.c\t/^\tLOAD_PLUGIN(mylib.so, isearch);$/;\"\tFile\tlanguage:Plugin\nu\tinput.c\t/^\tint u __attribute__((unused));$/;\"\tvaraible\tlanguage:UnusedAttr\n\nC(disabled) + EVENT + HOOK + PLUGIN + UA\n\nC + EVENT(disabled) + HOOK + PLUGIN + UA\nisearch\tinput.c\t/^\tLOAD_PLUGIN(mylib.so, isearch);$/;\"\tname\tlanguage:Plugin\nmain\tinput.c\t/^main(void)$/;\"\tfunction\tlanguage:C\ttyperef:typename:int\nmylib.so\tinput.c\t/^\tLOAD_PLUGIN(mylib.so, isearch);$/;\"\tFile\tlanguage:Plugin\n\nC + EVENT + HOOK(disabled) + PLUGIN + UA\na\tinput.c\t/^DEFINE_EVENT(a);$/;\"\tevent\tlanguage:Event\nb\tinput.c\t/^DEFINE_EVENT(b);$/;\"\tevent\tlanguage:Event\nisearch\tinput.c\t/^\tLOAD_PLUGIN(mylib.so, isearch);$/;\"\tname\tlanguage:Plugin\nmain\tinput.c\t/^main(void)$/;\"\tfunction\tlanguage:C\ttyperef:typename:int\nmylib.so\tinput.c\t/^\tLOAD_PLUGIN(mylib.so, isearch);$/;\"\tFile\tlanguage:Plugin\nu\tinput.c\t/^\tint u __attribute__((unused));$/;\"\tvaraible\tlanguage:UnusedAttr\n\nC + EVENT + HOOK + PLUGIN + UA(-v)\na\tinput.c\t/^DEFINE_EVENT(a);$/;\"\tevent\tlanguage:Event\nb\tinput.c\t/^DEFINE_EVENT(b);$/;\"\tevent\tlanguage:Event\nh\tinput.c\t/^DEFINE_HOOK(h);$/;\"\thook\tlanguage:Hook\ni\tinput.c\t/^DEFINE_HOOK(i);$/;\"\thook\tlanguage:Hook\nisearch\tinput.c\t/^\tLOAD_PLUGIN(mylib.so, isearch);$/;\"\tname\tlanguage:Plugin\nmain\tinput.c\t/^main(void)$/;\"\tfunction\tlanguage:C\ttyperef:typename:int\nmylib.so\tinput.c\t/^\tLOAD_PLUGIN(mylib.so, isearch);$/;\"\tFile\tlanguage:Plugin\nList subparsers of C ( EVENT + HOOK + PLUGIN + UA )\n#NAME   BASEPARSER DIRECTIONS\nEvent   C          base => sub {shared}\nJNI     C          base <> sub {bidirectional}\nPlugin  C          base => sub {shared}\nList subparsers of C ( EVENT + HOOK + PLUGIN + UA ) without the header\nEvent   C          base => sub {shared}\nJNI     C          base <> sub {bidirectional}\nPlugin  C          base => sub {shared}\nList subparsers of C ( EVENT + HOOK + PLUGIN + UA ) in machinable\n#NAME\tBASEPARSER\tDIRECTIONS\nEvent\tC\tbase => sub {shared}\nJNI\tC\tbase <> sub {bidirectional}\nPlugin\tC\tbase => sub {shared}\nList subparsers of C ( EVENT + HOOK + PLUGIN + UA ) in machinable without the header\nEvent\tC\tbase => sub {shared}\nJNI\tC\tbase <> sub {bidirectional}\nPlugin\tC\tbase => sub {shared}\n"
  },
  {
    "path": "Tmain/nested-subparsers.d/unused-attr.ctags",
    "content": "--langdef=UnusedAttr{base=Event}\n--kinddef-UnusedAttr=v,varaible,unsed variable\n--regex-UnusedAttr=/([a-zA-Z][0-9a-zA-Z]*)[ \\t]+__attribute__\\(\\(unused\\)\\);/\\1/v/\n"
  },
  {
    "path": "Tmain/no-empty-tag.d/input-0.mak",
    "content": "-include *.d\n"
  },
  {
    "path": "Tmain/no-empty-tag.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n$CTAGS --options=NONE -o - input-0.mak > /dev/null\n"
  },
  {
    "path": "Tmain/no-empty-tag.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\n"
  },
  {
    "path": "Tmain/no-input-encoding-option.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/no-input-encoding-option.d/input.java",
    "content": "class Foo { // FooNX\n\tpublic Foo() { // RXgN^\n\t}\n}\n"
  },
  {
    "path": "Tmain/no-input-encoding-option.d/input.js",
    "content": "var a = 1; // ѿ\n"
  },
  {
    "path": "Tmain/no-input-encoding-option.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\n\n. ../utils.sh\n\nif ${CTAGS} --quiet --options=NONE --list-features | grep -q iconv; then\n  check_encoding utf-8\n  ${CTAGS} --quiet --options=NONE --output-encoding=utf-8 -o $BUILDDIR/tags input.js input.java\n  exit $?\nelse\n  skip \"iconv feature is not available\"\nfi\n"
  },
  {
    "path": "Tmain/no-input-encoding-option.d/stderr-expected.txt",
    "content": "ctags: Warning: --input-encoding is not specified\n"
  },
  {
    "path": "Tmain/no-input-encoding-option.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/notice-about-broken-symlink.d/.gitignore",
    "content": "broken-symlink.c\n"
  },
  {
    "path": "Tmain/notice-about-broken-symlink.d/run.sh",
    "content": "# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=$1\nSF=broken-symlink.c\n\n# See https://www.msys2.org/docs/symlinks/\nskip_if_running_on_msys\n\ncleanup()\n{\n\trm -f \"$SF\"\n}\n\ntrap cleanup EXIT\n\ncleanup\nif ! ln -s no-such-file.c \"$SF\"; then\n\tskip \"failed to create a symbolic link\"\nfi\n\necho '# broken-symlink.c + no option' 1>&2\n$CTAGS --options=NONE -o - broken-symlink.c\n\necho '# broken-symlink.c + --quiet option' 1>&2\n$CTAGS --quiet --options=NONE -o - broken-symlink.c\n\necho '# no-such-file.c + no option' 1>&2\n$CTAGS --options=NONE -o - no-such-file.c\n\necho '# no-such-file.c + --quiet option' 1>&2\n$CTAGS --quiet --options=NONE -o - no-such-file.c\n"
  },
  {
    "path": "Tmain/notice-about-broken-symlink.d/stderr-expected.txt",
    "content": "# broken-symlink.c + no option\nctags: Notice: No options will be read from files or environment\nctags: Notice: cannot open input file \"broken-symlink.c\" : No such file or directory\n# broken-symlink.c + --quiet option\n# no-such-file.c + no option\nctags: Notice: No options will be read from files or environment\nctags: Warning: cannot open input file \"no-such-file.c\" : No such file or directory\n# no-such-file.c + --quiet option\nctags: Warning: cannot open input file \"no-such-file.c\" : No such file or directory\n"
  },
  {
    "path": "Tmain/null-description-in-pseudo-tag.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/null-description-in-pseudo-tag.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n$CTAGS --quiet --options=NONE -o - \\\n\t   --langdef=XYZ --regex-XYZ='/aaaaaaaaaaaaaaaaaaaaa/\\0/x/' \\\n\t   --language-force=XYZ --pseudo-tags='TAG_KIND_DESCRIPTION' --extras=p \\\n\t   run.sh\n"
  },
  {
    "path": "Tmain/null-description-in-pseudo-tag.d/stdout-expected.txt",
    "content": "!_TAG_KIND_DESCRIPTION!XYZ\tx,regex\t/regex/\n"
  },
  {
    "path": "Tmain/nulltag-extra.d/input.cst",
    "content": "Z\nz\n\n"
  },
  {
    "path": "Tmain/nulltag-extra.d/run.sh",
    "content": "# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\n# The order of stdout and stderr lines is not stable.\nexit_if_win32 \"$CTAGS\"\n\n# is_feature_available $CTAGS json\n\nO=\"--options=NONE --language-force=CTagsSelfTest\"\n\nfor fmt in xref; do\n\techo \"# no extra ($fmt)\"\n\t${CTAGS} $O -o - --output-format=\"$fmt\" input.cst 2>&1\n\n\techo \"# drop '0' extra ($fmt)\"\n\t${CTAGS} $O -o - --output-format=\"$fmt\" --extras=-z input.cst 2>&1\n\n\techo \"# drop '{nulltag}' extra ($fmt)\"\n\t${CTAGS} $O -o - --output-format=\"$fmt\" --extras=-'{nulltag}' input.cst 2>&1\n\n\techo '# with --extras=+0 ($fmt)'\n\t${CTAGS} $O -o - --output-format=\"$fmt\" --extras=+z input.cst 2>&1\n\n\techo \"# with --extras=+{nulltag}' ($fmt)\"\n\t${CTAGS} $O -o - --output-format=\"$fmt\" --extras=+'{nulltag}' input.cst 2>&1\ndone | sed -e 's/\\.exe//'\n"
  },
  {
    "path": "Tmain/nulltag-extra.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/nulltag-extra.d/stdout-expected.txt",
    "content": "# no extra (xref)\nctags: Notice: No options will be read from files or environment\nctags: Notice: ignoring null tag in input.cst(line: 1, language: CTagsSelfTest)\n# drop '0' extra (xref)\nctags: Notice: No options will be read from files or environment\nctags: Notice: ignoring null tag in input.cst(line: 1, language: CTagsSelfTest)\n# drop '{nulltag}' extra (xref)\nctags: Notice: No options will be read from files or environment\nctags: Notice: ignoring null tag in input.cst(line: 1, language: CTagsSelfTest)\n# with --extras=+0 ($fmt)\nctags: Notice: No options will be read from files or environment\nctags: Notice: ignoring null tag in input.cst(line: 1, language: CTagsSelfTest)\n                 emitNullTag    2 input.cst        z\n# with --extras=+{nulltag}' (xref)\nctags: Notice: No options will be read from files or environment\nctags: Notice: ignoring null tag in input.cst(line: 1, language: CTagsSelfTest)\n                 emitNullTag    2 input.cst        z\n"
  },
  {
    "path": "Tmain/omit-long-patterns-etags.d/input.sh",
    "content": "                                                                                                func96()\n{\n\n}\n                                                                                               func95()\n{\n\n}\n                                                                                                 func97()\n{\n\n}\n\nfunc96\nfunc95\nfunc97\n"
  },
  {
    "path": "Tmain/omit-long-patterns-etags.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n# strlen (\"func95()\") => 8\n${CTAGS} --quiet --options=NONE --pattern-length-limit=`expr 96 + 8` -e -o - ./input.sh\n"
  },
  {
    "path": "Tmain/omit-long-patterns-etags.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/omit-long-patterns-etags.d/stdout-expected.txt",
    "content": "\f\ninput.sh,351\n                                                                                                func96()func96\u00011,0\n                                                                                               func95()func95\u00015,110\n                                                                                                 func97(func97\u00019,219\n"
  },
  {
    "path": "Tmain/omit-long-patterns.d/gen.sh",
    "content": "#!/bin/sh\nlimit=96\ncalls=\n\nl=$limit\nfor i in $(seq $l); do\n    echo -n ' '\ndone\necho \"func$l()\"\necho \"{\"\necho\necho \"}\"\ncalls=\"$calls func$l\"\n\nl=$(expr $limit - 1)\nfor i in $(seq $l); do\n    echo -n ' '\ndone\necho \"func$l()\"\necho \"{\"\necho\necho \"}\"\ncalls=\"$calls func$l\"\n\nl=$(expr $limit + 1)\nfor i in $(seq $l); do\n    echo -n ' '\ndone\necho \"func$l()\"\necho \"{\"\necho\necho \"}\"\ncalls=\"$calls func$l\"\n\necho\n\nfor c in $calls; do\n    echo $c\ndone\n"
  },
  {
    "path": "Tmain/omit-long-patterns.d/input.sh",
    "content": "                                                                                                func96()\n{\n\n}\n                                                                                               func95()\n{\n\n}\n                                                                                                 func97()\n{\n\n}\n\nfunc96\nfunc95\nfunc97\n"
  },
  {
    "path": "Tmain/omit-long-patterns.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n${CTAGS} --options=NONE -o - ./input.sh\n"
  },
  {
    "path": "Tmain/omit-long-patterns.d/stdout-expected.txt",
    "content": "func95\t./input.sh\t/^                                                                                               f/;\"\tf\nfunc96\t./input.sh\t/^                                                                                                /;\"\tf\nfunc97\t./input.sh\t/^                                                                                                /;\"\tf\n"
  },
  {
    "path": "Tmain/option-dump-keywords.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\nCTAGS=$1\n\n${CTAGS} \\\n\t--quiet --options=NONE \\\n\t--_force-initializing --_dump-keywords --_force-quit \\\n\t| grep -i ObjectiveC | sort\n"
  },
  {
    "path": "Tmain/option-dump-keywords.d/stdout-expected.txt",
    "content": "@class\tObjectiveC\n@defs\tObjectiveC\n@dynamic\tObjectiveC\n@encode\tObjectiveC\n@end\tObjectiveC\n@implementation\tObjectiveC\n@interface\tObjectiveC\n@optional\tObjectiveC\n@package\tObjectiveC\n@private\tObjectiveC\n@property\tObjectiveC\n@protected\tObjectiveC\n@protocol\tObjectiveC\n@public\tObjectiveC\n@required\tObjectiveC\n@selector\tObjectiveC\n@synchronized\tObjectiveC\n@synthesize\tObjectiveC\nenum\tObjectiveC\nextern\tObjectiveC\nstruct\tObjectiveC\ntypedef\tObjectiveC\n"
  },
  {
    "path": "Tmain/option-dump-options.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\nCTAGS=$1\n\n${CTAGS} \\\n\t--quiet --options=NONE \\\n\t--_dump-options --_force-quit | grep -e '_dump-options'\n"
  },
  {
    "path": "Tmain/option-dump-options.d/stdout-expected.txt",
    "content": "_dump-options\n"
  },
  {
    "path": "Tmain/option-echo-and-force-quit.d/exit-expected.txt",
    "content": "21\n"
  },
  {
    "path": "Tmain/option-echo-and-force-quit.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n# --quiet cannot be used in this test case.\n${CTAGS} --options=NONE --_echo=a --_echo=b --_force-quit=21 --_echo=b\n\n"
  },
  {
    "path": "Tmain/option-echo-and-force-quit.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nctags: Notice: a\nctags: Notice: b\n"
  },
  {
    "path": "Tmain/option-echo-and-force-quit.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/option-exclude-exception.d/input.d/bazel-x/x.c",
    "content": "int x = 1;\n"
  },
  {
    "path": "Tmain/option-exclude-exception.d/input.d/bazel-y/y.c",
    "content": "int y = 1;\n"
  },
  {
    "path": "Tmain/option-exclude-exception.d/input.d/bazel-z/z.c",
    "content": "int z = 1;\n"
  },
  {
    "path": "Tmain/option-exclude-exception.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\n\n${CTAGS} --quiet --options=NONE -o - -R --exclude='*/bazel-*' \\\n\t\t --exclude-exception='*/bazel-x/*' \\\n\t\t --exclude-exception='*/bazel-z/*' \\\n\t\t input.d\n"
  },
  {
    "path": "Tmain/option-exclude-exception.d/stdout-expected.txt",
    "content": "x\tinput.d/bazel-x/x.c\t/^int x = 1;$/;\"\tv\ttyperef:typename:int\nz\tinput.d/bazel-z/z.c\t/^int z = 1;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/option-exclude-including-fsep.d/input.d/bazel-x/x.c",
    "content": "int x = 1;\n"
  },
  {
    "path": "Tmain/option-exclude-including-fsep.d/input.d/bazel-y/y.c",
    "content": "int y = 1;\n"
  },
  {
    "path": "Tmain/option-exclude-including-fsep.d/input.d/bazel-z/z.c",
    "content": "int z = 1;\n"
  },
  {
    "path": "Tmain/option-exclude-including-fsep.d/input.d/labze-a/a.c",
    "content": "int a = 3;\n\n"
  },
  {
    "path": "Tmain/option-exclude-including-fsep.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\n\n${CTAGS} --quiet --options=NONE -o - -R --exclude='*/bazel-*' \\\n\t\t input.d\n"
  },
  {
    "path": "Tmain/option-exclude-including-fsep.d/stdout-expected.txt",
    "content": "a\tinput.d/labze-a/a.c\t/^int a = 3;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/option-exclude-simple.d/input.d/a.h",
    "content": "#ifndef A\n#define A\nstruct A {\n\tint a0, a1;\n};\n#endif\n"
  },
  {
    "path": "Tmain/option-exclude-simple.d/input.d/bazel-x/x.c",
    "content": "int x = 1;\n"
  },
  {
    "path": "Tmain/option-exclude-simple.d/input.d/bazel-y/y.c",
    "content": "int y = 1;\n"
  },
  {
    "path": "Tmain/option-exclude-simple.d/input.d/bazel-z/z.c",
    "content": "int z = 1;\n"
  },
  {
    "path": "Tmain/option-exclude-simple.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\n\n${CTAGS} --quiet --options=NONE -o - -R --exclude='*.c' \\\n\t\t input.d\n"
  },
  {
    "path": "Tmain/option-exclude-simple.d/stdout-expected.txt",
    "content": "A\tinput.d/a.h\t/^#define A$/;\"\td\nA\tinput.d/a.h\t/^struct A {$/;\"\ts\na0\tinput.d/a.h\t/^\tint a0, a1;$/;\"\tm\tstruct:A\ttyperef:typename:int\na1\tinput.d/a.h\t/^\tint a0, a1;$/;\"\tm\tstruct:A\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/option-extradef-in-mtable.d/input.mtextra",
    "content": "(def a)\n{def b}\n[def c]\n"
  },
  {
    "path": "Tmain/option-extradef-in-mtable.d/mtextra.ctags",
    "content": "--langdef=MTExtra\n--map-MTExtra=+.mtextra\n\n--kinddef-MTExtra=d,def,definitions\n\n# []\n--_extradef-MTExtra=acceptSquareBracket,accept square bracket\n# {}\n--_extradef-MTExtra=acceptCurlyBracket,accept curly bracket\n\n\n--_tabledef-MTExtra=main\n--_tabledef-MTExtra=body\n\n--_mtable-regex-MTExtra=main/\\(def +//{tenter=body}\n--_mtable-regex-MTExtra=main/\\[def +//{tenter=body}{_extra=acceptSquareBracket}\n--_mtable-regex-MTExtra=main/\\{def +//{tenter=body}{_extra=acceptCurlyBracket}\n--_mtable-regex-MTExtra=main/.//\n\n--_mtable-regex-MTExtra=body/([_a-z]+)\\)/\\1/d/{tleave}\n--_mtable-regex-MTExtra=body/([_a-z]+)\\]/\\1/d/{tleave}{_extra=acceptSquareBracket}\n--_mtable-regex-MTExtra=body/([_a-z]+)\\}/\\1/d/{tleave}{_extra=acceptCurlyBracket}\n--_mtable-regex-MTExtra=body/.//\n"
  },
  {
    "path": "Tmain/option-extradef-in-mtable.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\n\nmsgstr ()\n{\n\tif [ $1 = '+' ]; then\n\t\techo \"enabled\"\n\telse\n\t\techo \"disabled\"\n\tfi\n}\n\nrun_ctags ()\n{\n\tprintf '# []: %s, {}: %s\\n' $(msgstr $1) $(msgstr $2)\n\t${CTAGS} --quiet --options=NONE --options=mtextra.ctags \\\n\t\t\t --fields=+'{extras}' \\\n\t\t\t --extras-MTExtra=${1}'{acceptSquareBracket}' \\\n\t\t\t --extras-MTExtra=${2}'{acceptCurlyBracket}' \\\n\t\t\t -o - \\\n\t\t\t input.mtextra\n}\n\nrun_ctags + +\nrun_ctags - -\nrun_ctags + -\nrun_ctags - +\n"
  },
  {
    "path": "Tmain/option-extradef-in-mtable.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/option-extradef-in-mtable.d/stdout-expected.txt",
    "content": "# []: enabled, {}: enabled\na\tinput.mtextra\t/^(def a)$/;\"\td\nb\tinput.mtextra\t/^{def b}$/;\"\td\textras:acceptCurlyBracket\nc\tinput.mtextra\t/^[def c]$/;\"\td\textras:acceptSquareBracket\n# []: disabled, {}: disabled\na\tinput.mtextra\t/^(def a)$/;\"\td\n# []: enabled, {}: disabled\na\tinput.mtextra\t/^(def a)$/;\"\td\nc\tinput.mtextra\t/^[def c]$/;\"\td\textras:acceptSquareBracket\n# []: disabled, {}: enabled\na\tinput.mtextra\t/^(def a)$/;\"\td\nb\tinput.mtextra\t/^{def b}$/;\"\td\textras:acceptCurlyBracket\n"
  },
  {
    "path": "Tmain/option-extras-enabling-all.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/option-extras-enabling-all.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\ncolumn_for_enabled=\n\nif ! column_for_enabled=$(get_column_index $CTAGS --list-extras \"ENABLED\"); then\n\texit $?\nfi\n\n$CTAGS --quiet --options=NONE --extras-all= \\\n\t   --with-list-header=no --list-extras \\\n\t| filter_by_column_index $column_for_enabled | sort | uniq\n$CTAGS --quiet --options=NONE --extras-all='*' \\\n\t   --with-list-header=no --list-extras \\\n\t| filter_by_column_index $column_for_enabled | sort | uniq\n"
  },
  {
    "path": "Tmain/option-extras-enabling-all.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/option-extras-enabling-all.d/stdout-expected.txt",
    "content": "no\nyes\n"
  },
  {
    "path": "Tmain/option-no-such-foreign-extra.d/run.sh",
    "content": "# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=$1\n\nV=\n# V=valgrind\n\n${V} ${CTAGS} --quiet --options=NONE \\\n\t \\\n\t --langdef=NOSUCHLANG'{_foreignLanguage=Kconfig}' \\\n\t --_extradef-NOSUCHLANG='NOSUCHEXTRA,but this is not the part of Kconfig' \\\n     --regex-NOSUCHLANG='/^\\# (CONFIG_[^ ]+) is not set/\\1/c/{_language=Kconfig}{_extra=NOSUCHEXTRA}{exclusive}' \\\n\t \\\n\t --_force-quit=0\n"
  },
  {
    "path": "Tmain/option-no-such-foreign-extra.d/stderr-expected.txt",
    "content": "ctags: Warning: no such extra \"NOSUCHEXTRA\" in Kconfig\n"
  },
  {
    "path": "Tmain/option-no-such-foreign-field.d/run.sh",
    "content": "# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=$1\n\nV=\n# V=valgrind\n\n${V} ${CTAGS} --quiet --options=NONE \\\n\t \\\n\t --langdef=NOSUCHLANG'{_foreignLanguage=Kconfig}' \\\n\t --_fielddef-NOSUCHLANG='NOSUCHFIELD,but this is not the part of Kconfig' \\\n     --regex-NOSUCHLANG='/^\\# (CONFIG_[^ ]+) is (not set)/\\1/c/{_language=Kconfig}{_field=NOSUCHFIELD:\\1}{exclusive}' \\\n\t \\\n\t --_force-quit=0\n"
  },
  {
    "path": "Tmain/option-no-such-foreign-field.d/stderr-expected.txt",
    "content": "ctags: Warning: no such field \"NOSUCHFIELD\" in Kconfig\n"
  },
  {
    "path": "Tmain/option-options-directory.d/exit-expected.txt",
    "content": "7\n"
  },
  {
    "path": "Tmain/option-options-directory.d/optlib/a.ctags",
    "content": "--_echo=hello\n"
  },
  {
    "path": "Tmain/option-options-directory.d/optlib/b.ctags",
    "content": "--_echo=world\n"
  },
  {
    "path": "Tmain/option-options-directory.d/optlib/c.ctags",
    "content": "--_force-quit=7\n"
  },
  {
    "path": "Tmain/option-options-directory.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\n${CTAGS} --options=NONE --options=./optlib\n"
  },
  {
    "path": "Tmain/option-options-directory.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nctags: Notice: hello\nctags: Notice: world\n"
  },
  {
    "path": "Tmain/option-options-maybe.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/option-options-maybe.d/input-maybe.c",
    "content": "int foo (void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Tmain/option-options-maybe.d/input.c",
    "content": "int foo (void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Tmain/option-options-maybe.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nd=$(pwd)\n\n${CTAGS} --quiet --options=NONE --options=./NOSUCHFILE -o - input.c\n\n${CTAGS} --quiet --options=NONE --options-maybe=./NOSUCHFILE -o - input-maybe.c\n"
  },
  {
    "path": "Tmain/option-options-maybe.d/stderr-expected.txt",
    "content": "ctags: cannot stat \"./NOSUCHFILE\" : No such file or directory\n"
  },
  {
    "path": "Tmain/option-options-maybe.d/stdout-expected.txt",
    "content": "foo\tinput-maybe.c\t/^int foo (void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/option-pseudo-tags.d/input.c",
    "content": "/* EMPTY */\n"
  },
  {
    "path": "Tmain/option-pseudo-tags.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=\"--quiet --options=NONE \"\n\necho '# single with no curly bracket'\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags=TAG_PROGRAM_URL \\\n\t\t -o - \\\n\t\t input.c\n\necho '# single with curly bracket'\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags='{TAG_PROGRAM_URL}' \\\n\t\t -o - \\\n\t\t input.c\n\necho '# single with + no curly bracket'\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags= \\\n\t\t --pseudo-tags=+TAG_PROGRAM_URL \\\n\t\t -o - \\\n\t\t input.c\n\necho '# single with + curly bracket'\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags= \\\n\t\t --pseudo-tags=+'{TAG_PROGRAM_URL}' \\\n\t\t -o - \\\n\t\t input.c\n\necho '# single with +- no curly bracket'\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags= \\\n\t\t --pseudo-tags=+TAG_PROGRAM_VERSION \\\n\t\t --pseudo-tags=+TAG_PROGRAM_URL \\\n\t\t --pseudo-tags=-TAG_PROGRAM_VERSION \\\n\t\t -o - \\\n\t\t input.c\n\necho '# single with +- curly bracket'\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags= \\\n\t\t --pseudo-tags=+'{TAG_PROGRAM_VERSION}' \\\n\t\t --pseudo-tags=+'{TAG_PROGRAM_URL}' \\\n\t\t --pseudo-tags=-'{TAG_PROGRAM_VERSION}' \\\n\t\t -o - \\\n\t\t input.c\n\necho '# multiple specifications with +- curly bracket'\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags= \\\n\t\t --pseudo-tags='+{TAG_PROGRAM_VERSION}{TAG_FILE_SORTED}{TAG_PROGRAM_URL}-{TAG_PROGRAM_VERSION}' \\\n\t\t -o - \\\n\t\t input.c\n\necho '# multiple specifications with -+- curly bracket'\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags= \\\n\t\t --pseudo-tags='-{TAG_PROGRAM_VERSION}+{TAG_PROGRAM_VERSION}{TAG_FILE_FORMAT}{TAG_PROGRAM_URL}-{TAG_PROGRAM_VERSION}' \\\n\t\t -o - \\\n\t\t input.c\n"
  },
  {
    "path": "Tmain/option-pseudo-tags.d/stdout-expected.txt",
    "content": "# single with no curly bracket\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n# single with curly bracket\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n# single with + no curly bracket\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n# single with + curly bracket\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n# single with +- no curly bracket\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n# single with +- curly bracket\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n# multiple specifications with +- curly bracket\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n# multiple specifications with -+- curly bracket\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n"
  },
  {
    "path": "Tmain/option-totals-extra.d/input.unknown",
    "content": "N\nN\nN\nN\nN\nN\nN\nN\nN\nN\n"
  },
  {
    "path": "Tmain/option-totals-extra.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --totals=extra --language-force=CTagsSelfTest -o - input.unknown 2>&1 \\\n\t| grep -v ^N \\\n\t| sed -ne '/^STATISTICS.*/,$p'\n"
  },
  {
    "path": "Tmain/option-totals-extra.d/stdout-expected.txt",
    "content": "STATISTICS of CTagsSelfTest\n==============================================\nThe number of handled chars: 10\n"
  },
  {
    "path": "Tmain/option-use-slash-as-filename-separator.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nOPT=--use-slash-as-filename-separator\n\n. ../utils.sh\n\nexit_unless_win32 $CTAGS\n\necho '#u-ctags output'\n$CTAGS --quiet --options=NONE -o -      'src\\input.c'\n$CTAGS --quiet --options=NONE -o - $OPT 'src\\input.c'\n$CTAGS --quiet --options=NONE -o - ${OPT}=no 'src\\input.c'\n\necho '#u-ctags ptag output'\n{\n$CTAGS --quiet --options=NONE --extras=p -o -      'src\\input.c'\n$CTAGS --quiet --options=NONE --extras=p -o - $OPT 'src\\input.c'\n$CTAGS --quiet --options=NONE --extras=p -o - ${OPT}=no 'src\\input.c'\n} | grep TAG_OUTPUT_FILESEP\n\necho '#e-ctags output'\n$CTAGS --quiet --options=NONE --output-format=e-ctags -o -           'src\\input.c'\n$CTAGS --quiet --options=NONE --output-format=e-ctags -o - $OPT      'src\\input.c'\n$CTAGS --quiet --options=NONE --output-format=e-ctags -o - ${OPT}=no 'src\\input.c'\n\necho '#e-ctags ptag output'\n{\n$CTAGS --quiet --options=NONE --extras=p --output-format=e-ctags -o -           'src\\input.c'\n$CTAGS --quiet --options=NONE --extras=p --output-format=e-ctags -o - $OPT      'src\\input.c'\n$CTAGS --quiet --options=NONE --extras=p --output-format=e-ctags -o - ${OPT}=no 'src\\input.c'\n} | grep TAG_OUTPUT_FILESEP\n\necho '#xref output'\n$CTAGS --quiet --options=NONE --output-format=xref -o -           'src\\input.c'\n$CTAGS --quiet --options=NONE --output-format=xref -o - $OPT      'src\\input.c'\n$CTAGS --quiet --options=NONE --output-format=xref -o - ${OPT}=no 'src\\input.c'\n\n# TODO: json output\n"
  },
  {
    "path": "Tmain/option-use-slash-as-filename-separator.d/src/input.c",
    "content": "int n;\n"
  },
  {
    "path": "Tmain/option-use-slash-as-filename-separator.d/stdout-expected.txt",
    "content": "#u-ctags output\nn\tsrc/input.c\t/^int n;$/;\"\tv\ttyperef:typename:int\nn\tsrc/input.c\t/^int n;$/;\"\tv\ttyperef:typename:int\nn\tsrc\\\\input.c\t/^int n;$/;\"\tv\ttyperef:typename:int\n#u-ctags ptag output\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n#e-ctags output\nn\tsrc\\input.c\t/^int n;$/;\"\tv\ttyperef:typename:int\nn\tsrc/input.c\t/^int n;$/;\"\tv\ttyperef:typename:int\nn\tsrc\\input.c\t/^int n;$/;\"\tv\ttyperef:typename:int\n#e-ctags ptag output\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n#xref output\nn                variable      1 src\\\\input.c     int n;\nn                variable      1 src/input.c      int n;\nn                variable      1 src\\\\input.c     int n;\n"
  },
  {
    "path": "Tmain/optlib-dir-option.d/optlib/a.ctags",
    "content": "--_echo=hello\n"
  },
  {
    "path": "Tmain/optlib-dir-option.d/optlib/b.ctags",
    "content": "--_echo=world\n"
  },
  {
    "path": "Tmain/optlib-dir-option.d/optlib/c.ctags",
    "content": "--_force-quit=7\n"
  },
  {
    "path": "Tmain/optlib-dir-option.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nd=$(pwd)\n\necho '#' specifying files 1>&2\n(\n\tcd /\n\t${CTAGS} --options=NONE --optlib-dir=$d/optlib --options=a.ctags --options=b.ctags --options=c.ctags\n)\n\necho '#' specifying a dir 1>&2\n(\n\tcd /\n\t${CTAGS} --options=NONE --optlib-dir=$d --options=optlib\n)\n\necho '#' reset 1>&2\n(\n\tcd /\n\t${CTAGS} --options=NONE --optlib-dir= --options=optlib\n)\n"
  },
  {
    "path": "Tmain/optlib-dir-option.d/stderr-expected.txt",
    "content": "# specifying files\nctags: Notice: No options will be read from files or environment\nctags: Notice: hello\nctags: Notice: world\n# specifying a dir\nctags: Notice: No options will be read from files or environment\nctags: Notice: hello\nctags: Notice: world\n# reset\nctags: Notice: No options will be read from files or environment\nctags: cannot stat \"optlib\" : No such file or directory\n"
  },
  {
    "path": "Tmain/optlib-message-flag.d/args.ctags",
    "content": "--langdef=FOO\n--map-FOO=+.foo\n\n--kinddef-FOO=n,namespace,namespaces\n--kinddef-FOO=c,class,classes\n--kinddef-FOO=v,variable,variables\n\n--regex-FOO=/namespace ([a-zA-Z]+) /\\1/N,anotherNamespace/{warning=\"found namespace '\\1'\"}{exclusive}\n--regex-FOO=/namespace ([a-zA-Z]+) /\\1/x,bad/{fatal=\"should not get this\"}\n--regex-FOO=/bad regex ([a-zA-Z-]+)/\\1/x,bad/{fatal=\"bad='\\1'\"}\n\n\n--mline-regex-FOO=/namespace ([a-zA-Z]+) /\\1/m,mlineNamespace/{mgroup=1}{warning=\"got namespace\"}\n--mline-regex-FOO=/var ([a-zA-Z]+) ([a-zA-Z]+);/\\2/V,mlineVariable/{warning=\"got variable '\\2' of type \\1\"}{mgroup=2}\n--mline-regex-FOO=/bad multi-line ([a-zA-Z-]+)/\\1/x,bad/{fatal=\"bad='\\1'\"}{mgroup=1}\n\n\n--_tabledef-FOO=main\n--_tabledef-FOO=block\n--_tabledef-FOO=blockEnd\n--_tabledef-FOO=skipWhitespace\n\n--_mtable-regex-FOO=skipWhitespace/[ \\t\\n]+//\n\n--_mtable-regex-FOO=main/namespace ([a-zA-Z]+) \\{/\\1/n/{tenter=block,blockEnd}{warning=\"found namespace\"}{scope=push}\n--_mtable-extend-FOO=main+skipWhitespace\n--_mtable-regex-FOO=main///\n\n--_mtable-regex-FOO=blockEnd/\\};?//{scope=pop}{warning=\"end of block\"}\n--_mtable-extend-FOO=blockEnd+skipWhitespace\n--_mtable-regex-FOO=blockEnd/bad multi-table ([a-zA-Z-]+)//{fatal=\"bad='\\1'\"}\n--_mtable-regex-FOO=blockEnd/bad [^\\n]+\\n//\n\n--_mtable-regex-FOO=block/class ([a-zA-Z]+) \\{/\\1/c/{tenter=block,blockEnd}{warning=\"got class\"}{scope=ref}{scope=push}\n--_mtable-regex-FOO=block/var ([a-zA-Z]+) ([a-zA-Z]+);/\\2/v/{scope=ref}{warning=\"got variable '\\2' of type \\1\"}\n--_mtable-extend-FOO=block+skipWhitespace\n"
  },
  {
    "path": "Tmain/optlib-message-flag.d/input0.foo",
    "content": "namespace A {\n\tclass B {\n\t\tvar bool C;\n\t};\n}\n"
  },
  {
    "path": "Tmain/optlib-message-flag.d/input1.foo",
    "content": "namespace X {\n\tclass Y {\n\t\tvar bool Z;\n\t};\n}\n\nbad regex found-it\nbad multi-line found-mline\nbad multi-table found-mtable\n"
  },
  {
    "path": "Tmain/optlib-message-flag.d/input2.foo",
    "content": "namespace XX {\n\tclass YY {\n\t\tvar bool ZZ;\n\t};\n}\n\nbad multi-line found-mline\nbad multi-table found-mtable\n"
  },
  {
    "path": "Tmain/optlib-message-flag.d/input3.foo",
    "content": "namespace XXX {\n\tclass YYY {\n\t\tvar bool ZZZ;\n\t};\n}\n\nbad multi-table found-mtable\n"
  },
  {
    "path": "Tmain/optlib-message-flag.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\necho '#' warning messages 1>&2\n(\n\t${CTAGS} --options=NONE --options=./args.ctags -o - ./input0.foo\n)\n\necho '#' fatal regex message 1>&2\n(\n\t${CTAGS} --options=NONE --options=./args.ctags -o - ./input1.foo\n)\n\necho '#' fatal mline-regex message 1>&2\n(\n\t${CTAGS} --options=NONE --options=./args.ctags -o - ./input2.foo\n)\n\necho '#' fatal mtable-regex message 1>&2\n(\n\t${CTAGS} --options=NONE --options=./args.ctags -o - ./input3.foo\n)\n"
  },
  {
    "path": "Tmain/optlib-message-flag.d/stderr-expected.txt",
    "content": "# warning messages\nctags: Notice: No options will be read from files or environment\nctags: Warning: Message from regex<FOO>: found namespace 'A' (./input0.foo:1)\nctags: Warning: Message from regex<FOO>: got namespace (./input0.foo:1)\nctags: Warning: Message from regex<FOO>: got variable 'C' of type bool (./input0.foo:3)\nctags: Warning: Message from mtable<FOO/main[ 0]>: found namespace (./input0.foo:1)\nctags: Warning: Message from mtable<FOO/block[ 0]>: got class (./input0.foo:2)\nctags: Warning: Message from mtable<FOO/block[ 1]>: got variable 'C' of type bool (./input0.foo:3)\nctags: Warning: Message from mtable<FOO/blockEnd[ 0]>: end of block (./input0.foo:4)\nctags: Warning: Message from mtable<FOO/blockEnd[ 0]>: end of block (./input0.foo:5)\n# fatal regex message\nctags: Notice: No options will be read from files or environment\nctags: Warning: Message from regex<FOO>: found namespace 'X' (./input1.foo:1)\nctags: Fatal: Message from regex<FOO>: bad='found-it' (./input1.foo:7)\n# fatal mline-regex message\nctags: Notice: No options will be read from files or environment\nctags: Warning: Message from regex<FOO>: found namespace 'XX' (./input2.foo:1)\nctags: Warning: Message from regex<FOO>: got namespace (./input2.foo:1)\nctags: Warning: Message from regex<FOO>: got variable 'ZZ' of type bool (./input2.foo:3)\nctags: Fatal: Message from regex<FOO>: bad='found-mline' (./input2.foo:7)\n# fatal mtable-regex message\nctags: Notice: No options will be read from files or environment\nctags: Warning: Message from regex<FOO>: found namespace 'XXX' (./input3.foo:1)\nctags: Warning: Message from regex<FOO>: got namespace (./input3.foo:1)\nctags: Warning: Message from regex<FOO>: got variable 'ZZZ' of type bool (./input3.foo:3)\nctags: Warning: Message from mtable<FOO/main[ 0]>: found namespace (./input3.foo:1)\nctags: Warning: Message from mtable<FOO/block[ 0]>: got class (./input3.foo:2)\nctags: Warning: Message from mtable<FOO/block[ 1]>: got variable 'ZZZ' of type bool (./input3.foo:3)\nctags: Warning: Message from mtable<FOO/blockEnd[ 0]>: end of block (./input3.foo:4)\nctags: Warning: Message from mtable<FOO/blockEnd[ 0]>: end of block (./input3.foo:5)\nctags: Fatal: Message from mtable<FOO/blockEnd[ 2]>: bad='found-mtable' (./input3.foo:7)\n"
  },
  {
    "path": "Tmain/optlib-message-flag.d/stdout-expected.txt",
    "content": "A\t./input0.foo\t/^namespace A {$/;\"\tN\nA\t./input0.foo\t/^namespace A {$/;\"\tm\nA\t./input0.foo\t/^namespace A {$/;\"\tn\nB\t./input0.foo\t/^\tclass B {$/;\"\tc\tnamespace:A\nC\t./input0.foo\t/^\t\tvar bool C;$/;\"\tV\nC\t./input0.foo\t/^\t\tvar bool C;$/;\"\tv\tclass:A.B\n"
  },
  {
    "path": "Tmain/optscript-preludes-stack.d/args-c.ctags",
    "content": "--langdef=C10{base=C}\n--_prelude-C10={{\n    (prelude C10) ==\n}}\n--_sequel-C10={{\n    (sequel C10) ==\n}}\n\n\n--langdef=C11{base=C}\n--_prelude-C11={{\n    (prelude C11) ==\n}}\n--_sequel-C11={{\n    (sequel C11) ==\n}}\n\n--langdef=C20{base=C10}\n--_prelude-C20={{\n    (prelude C20) ==\n}}\n--_sequel-C20={{\n    (sequel C20) ==\n}}\n\n\n--langdef=C30{base=C20}\n--_prelude-C30={{\n    (prelude C30) ==\n}}\n--_sequel-C30={{\n    (sequel C30) ==\n}}\n"
  },
  {
    "path": "Tmain/optscript-preludes-stack.d/args-cpreprocessor.ctags",
    "content": "--langdef=CPreProcessor10{base=CPreProcessor}\n--_prelude-CPreProcessor10={{\n    (prelude CPreProcessor10) ==\n}}\n--_sequel-CPreProcessor10={{\n    (sequel CPreProcessor10) ==\n}}\n\n\n--langdef=CPreProcessor11{base=CPreProcessor}\n--_prelude-CPreProcessor11={{\n    (prelude CPreProcessor11) ==\n}}\n--_sequel-CPreProcessor11={{\n    (sequel CPreProcessor11) ==\n}}\n\n--langdef=CPreProcessor20{base=CPreProcessor10}\n--_prelude-CPreProcessor20={{\n    (prelude CPreProcessor20) ==\n}}\n--_sequel-CPreProcessor20={{\n    (sequel CPreProcessor20) ==\n}}\n\n\n--langdef=CPreProcessor30{base=CPreProcessor20}\n--_prelude-CPreProcessor30={{\n    (prelude CPreProcessor30) ==\n}}\n--_sequel-CPreProcessor30={{\n    (sequel CPreProcessor30) ==\n}}\n"
  },
  {
    "path": "Tmain/optscript-preludes-stack.d/args-dts.ctags",
    "content": "--langdef=DTS10{base=DTS}\n--_prelude-DTS10={{\n    (prelude DTS10) ==\n}}\n--_sequel-DTS10={{\n    (sequel DTS10) ==\n}}\n\n\n--langdef=DTS11{base=DTS}\n--_prelude-DTS11={{\n    (prelude DTS11) ==\n}}\n--_sequel-DTS11={{\n    (sequel DTS11) ==\n}}\n\n--langdef=DTS20{base=DTS10}\n--_prelude-DTS20={{\n    (prelude DTS20) ==\n}}\n--_sequel-DTS20={{\n    (sequel DTS20) ==\n}}\n\n\n--langdef=DTS30{base=DTS20}\n--_prelude-DTS30={{\n    (prelude DTS30) ==\n}}\n--_sequel-DTS30={{\n    (sequel DTS30) ==\n}}\n"
  },
  {
    "path": "Tmain/optscript-preludes-stack.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/optscript-preludes-stack.d/input.c",
    "content": "/* EMPTY */\n"
  },
  {
    "path": "Tmain/optscript-preludes-stack.d/input.dts",
    "content": ""
  },
  {
    "path": "Tmain/optscript-preludes-stack.d/input.i",
    "content": ""
  },
  {
    "path": "Tmain/optscript-preludes-stack.d/run.sh",
    "content": "# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n: &&\n\t${CTAGS} --quiet --options=NONE\\\n\t\t\t --_prelude-C='{{ (enter C) == }}' \\\n\t\t\t --_sequel-C='{{ (leave C) == }}' \\\n\t\t\t --options=./args-c.ctags -o - input.c &&\n\t${CTAGS} --quiet --options=NONE \\\n\t\t\t --_prelude-DTS='{{ (enter DTS) == }}' \\\n\t\t\t --_sequel-DTS='{{ (leave DTS) == }}' \\\n\t\t\t --options=./args-dts.ctags -o - input.dts &&\n\t${CTAGS} --quiet --options=NONE --map-CPreProcessor=+.i \\\n\t\t\t --_prelude-CPreProcessor='{{ (enter CPreProcessor) == }}' \\\n\t\t\t --_sequel-CPreProcessor='{{ (leave CPreProcessor) == }}' \\\n\t\t\t --options=./args-cpreprocessor.ctags -o - input.i\n\n#\n# BUGS: The following two don't work because in-use marker is not set to\n# the subparsers of the CPreprocessor parser. The CPreprocessor parser must\n# mark in-use on its sub parsers to call the inputStart and inputEnd methods\n# in the foreachSubparser loop.\n#\n#\t${CTAGS} --quiet --options=NONE --options=./args-cpreprocessor.ctags -o - input.c\n#\t${CTAGS} --quiet --options=NONE --options=./args-cpreprocessor.ctags -o - input.dts\n#\n"
  },
  {
    "path": "Tmain/optscript-preludes-stack.d/stderr-expected.txt",
    "content": "(enter C)\n(prelude C10)\n(prelude C20)\n(prelude C30)\n(prelude C11)\n(sequel C30)\n(sequel C20)\n(sequel C10)\n(sequel C11)\n(leave C)\n(enter DTS)\n(prelude DTS10)\n(prelude DTS20)\n(prelude DTS30)\n(prelude DTS11)\n(sequel DTS30)\n(sequel DTS20)\n(sequel DTS10)\n(sequel DTS11)\n(leave DTS)\nctags: Warning: Because of an internal limitation, Making a sub parser based on the CPreProcessor parser is not allowed: CPreProcessor\nctags: Warning: Because of an internal limitation, Making a sub parser based on the CPreProcessor parser is not allowed: CPreProcessor\n(enter CPreProcessor)\n(leave CPreProcessor)\n"
  },
  {
    "path": "Tmain/optscript-preludes-stack.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/optscript-scope.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/optscript-scope.d/input.unknown",
    "content": "* TITLE 0\n+ Subtitle 0.0\n+ Subtitle 0.1\n- subsubtitle 0.1.0\n- subsubtitle 0.1.1\n+ Subtitle 0.2\n- subsubtitle 0.2.0\n* TITLE 1\n+ Subtitle 1.0\n- subsubtitle 1.0.0\n- subsubtitle 1.0.1\n"
  },
  {
    "path": "Tmain/optscript-scope.d/run.sh",
    "content": "# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\n${CTAGS} --quiet --options=NONE \\\n\t\t --sort=no --fields=+n \\\n\t\t --options=./unknown.ctags \\\n\t\t --language-force=UnknownX \\\n\t\t -o - input.unknown\n"
  },
  {
    "path": "Tmain/optscript-scope.d/stderr-expected.txt",
    "content": "section-enter\n0\nscopetop: OK\nscopeNth0: OK\nsection-leave\n1\nsubsection-enter\n1\nscopeNth1: OK\nsubsection-leave\n2\nsubsection-enter\n2\nscopetop: OK\nscopeNth0: OK\nscopeNth1: OK\nsubsection-leave\n2\nsubsubsection-enter\n2\nsubsubsection-leave\n3\nsubsubsection-enter\n3\nsubsubsection-leave\n3\nsubsection-enter\n3\nscopetop: OK\nscopeNth0: OK\nscopeNth1: OK\nsubsection-leave\n2\nsubsubsection-enter\n2\nsubsubsection-leave\n3\nsection-enter\n3\nscopetop: OK\nscopeNth0: OK\nsection-leave\n1\nsubsection-enter\n1\nscopeNth1: OK\nsubsection-leave\n2\nsubsubsection-enter\n2\nsubsubsection-leave\n3\nsubsubsection-enter\n3\nsubsubsection-leave\n3\n"
  },
  {
    "path": "Tmain/optscript-scope.d/stdout-expected.txt",
    "content": "TITLE 0\tinput.unknown\t/^* TITLE 0$/;\"\ts\tline:1\nSubtitle 0.0\tinput.unknown\t/^+ Subtitle 0.0$/;\"\tt\tline:2\tsection:TITLE 0\nSubtitle 0.1\tinput.unknown\t/^+ Subtitle 0.1$/;\"\tt\tline:3\tsection:TITLE 0\nsubsubtitle 0.1.0\tinput.unknown\t/^- subsubtitle 0.1.0$/;\"\tu\tline:4\tsubsection:TITLE 0.Subtitle 0.1\nsubsubtitle 0.1.1\tinput.unknown\t/^- subsubtitle 0.1.1$/;\"\tu\tline:5\tsubsection:TITLE 0.Subtitle 0.1\nSubtitle 0.2\tinput.unknown\t/^+ Subtitle 0.2$/;\"\tt\tline:6\tsection:TITLE 0\nsubsubtitle 0.2.0\tinput.unknown\t/^- subsubtitle 0.2.0$/;\"\tu\tline:7\tsubsection:TITLE 0.Subtitle 0.2\nTITLE 1\tinput.unknown\t/^* TITLE 1$/;\"\ts\tline:8\nSubtitle 1.0\tinput.unknown\t/^+ Subtitle 1.0$/;\"\tt\tline:9\tsection:TITLE 1\nsubsubtitle 1.0.0\tinput.unknown\t/^- subsubtitle 1.0.0$/;\"\tu\tline:10\tsubsection:TITLE 1.Subtitle 1.0\nsubsubtitle 1.0.1\tinput.unknown\t/^- subsubtitle 1.0.1$/;\"\tu\tline:11\tsubsection:TITLE 1.Subtitle 1.0\n"
  },
  {
    "path": "Tmain/optscript-scope.d/unknown.ctags",
    "content": "--langdef=UnknownX\n--kinddef-UnknownX=s,section,sections\n--kinddef-UnknownX=t,subsection,subsections\n--kinddef-UnknownX=u,subsubsection,subsubsections\n\n--regex-UnknownX=/^\\* (.*)$/\\1/s/{{\n   /section-enter = _scopedepth =\n   . _scopeset\n   _scopetop {\n      (scopetop: OK) =\n      . eq {\n         (scopeNth0: OK) =\n      } {\n         (scopeNth0: FAILED) =\n      } ifelse\n   } {\n      (scopetop: FAILED) =\n   } ifelse\n   /section-leave = _scopedepth =\n}}\n\n--regex-UnknownX=/^\\+ (.*)$/\\1/t/{{\n   /subsection-enter = _scopedepth =\n   _scopedepth 3 eq {\n      _scopepop\n   } if\n   _scopedepth 2 eq {\n      0 _scopeNth _scopetop {\n        (scopetop: OK) =\n        eq {\n           (scopeNth0: OK) =\n        } {\n           (scopeNth0: FAILED) =\n        } ifelse\n      } {\n         (scopetop: FAILED) =\n      } ifelse\n      _scopepop\n   } if\n   . _scopepush\n   1 _scopeNth . :scope eq {\n      (scopeNth1: OK) =\n   } {\n      (scopeNth1: FAILED) =\n   } ifelse\n   /subsection-leave = _scopedepth =\n}}\n\n--regex-UnknownX=/^\\- (.*)$/\\1/u/{{\n   /subsubsection-enter = _scopedepth =\n   _scopedepth 3 eq {\n      _scopepop\n   } if\n   . _scopepush\n   /subsubsection-leave = _scopedepth =\n}}\n"
  },
  {
    "path": "Tmain/optscript.d/arithmetic.expected",
    "content": "8\n(3 5 add)\n33\n(99 3 idiv)\n4\n(99 5 mod)\n30\n(3 10 mul)\n-12\n(8 20 sub)\n3\n(-3 neg)\n-3\n(3 neg)\n3\n(-3 abs)\n3\n(3 abs)\n"
  },
  {
    "path": "Tmain/optscript.d/arithmetic.ps",
    "content": "(3 5 add) 3 5 add pstack clear\n(99 3 idiv) 99 3 idiv pstack clear\n(99 5 mod) 99 5 mod pstack clear\n(3 10 mul) 3 10 mul pstack clear\n(8 20 sub) 8 20 sub pstack clear\n(-3 neg)  -3 neg pstack clear\n(3 neg)    3 neg pstack clear\n(-3 abs)  -3 abs pstack clear\n(3 abs)    3 abs pstack clear\n"
  },
  {
    "path": "Tmain/optscript.d/array.expected",
    "content": "[null null null null null]\n[1 2 3]\n3\n2\n1\n/a\n[1 2 3]\n/a\n"
  },
  {
    "path": "Tmain/optscript.d/array.ps",
    "content": "5 array pstack clear\n/a [ 1 2 3 ] aload pstack\nastore pstack clear\n"
  },
  {
    "path": "Tmain/optscript.d/arrayx.expected",
    "content": "unmatchedmark\nnull\n"
  },
  {
    "path": "Tmain/optscript.d/arrayx.ps",
    "content": "clear\n{\n    { ] } stopped {\n        _errorname =\n        stop\n    } if\n} stopped pop\n_errorname =\n"
  },
  {
    "path": "Tmain/optscript.d/compound.expected",
    "content": "3\n(abc)\n2\n-dict:2-\n3\n[true false null]\n(abc)\ntrue\ntrue\nfalse\n[true false null]\n(---------------- get array ----------------)\n(a)\n(a ->)\n(b)\n(b ->)\n(c)\n(c ->)\ntrue\n3\n[(a) (b) (c)]\n(true ->)\n(---------------- get dict ----------------)\n(a)\n(a ->)\n(b)\n(b ->)\n(c)\n(c ->)\ntrue\nfalse\n-dict:3-\n(true ->)\n(---------------- get str ----------------)\n97\n(97 ->)\n98\n(98 ->)\n99\n(99 ->)\ntrue\n3\n(abc)\n(true ->)\n(---------------- forall array ----------------)\n6\n(6 -> )\n(---------------- forall dict values ----------------)\n6\n(6 -> )\n(---------------- forall dict keys ----------------)\nfalse\n(false ->)\n(---------------- forall string ----------------)\n294\n(294 ->)\n(---------------- put string ----------------)\n(abc)\n(\\(abc\\) ->)\n(abcd)\n(\\(abcd\\) ->)\n(abc e)\n(\\(abc e\\) ->)\n(---------------- put array ----------------)\n[/a /b /c]\n([/a /b /c] ->)\n[/a /b /c /d]\n([/a /b /c /d] ->)\n[/a /b /c null /e]\n([/a /b /c null /e] ->)\n(---------------- put dict ----------------)\n1\n(1 ->)\n(---------------- putinterval string ----------------)\n(xyzdef)\n(\\(xyzdef\\) ->)\n(xyz123)\n(\\(xyz123\\) ->)\n(xyz1234)\n(\\(xyz1234\\) ->)\n(abcdex)\n(\\(abcdex\\) ->)\n(abcdefx)\n(\\(abcdefx\\) ->)\n(abcdxf)\n(\\(abcdxf\\) ->)\n(abcdxyz)\n(\\(abcdxyz\\) ->)\n(---------------- putinterval array ----------------)\n[/x /b /c]\n([/x /b /c] ->)\n[/a /x /c]\n([/a /x /c] ->)\n[/a /b /x]\n([/a /b /x] ->)\n[/a /b /c /x]\n([/a /b /c /x] ->)\n[/a /b /c /x /y]\n([/a /b /c /x /y] ->)\n[/a /b /x /y]\n([/a /b /x /y] ->)\n[/a /x /y]\n([/a /x /y] ->)\n[/x /y /c]\n([/x /y /c] ->)\n[/x /y /z]\n([/x /y /z] ->)\n[/a /x /y /z]\n([/a /x /y /z] ->)\n[/a /b /x /y /z]\n([/a /b /x /y /z] ->)\n[/a /b /c /x /y /z]\n([/a /b /c /x /y /z] ->)\n[/a /b /c /x /y /z /1]\n([/a /b /c /x /y /z /1] ->)\n[/a /b /x /y /z /1]\n([/a /b /x /y /z /1] ->)\n[/a /x /y /z /1]\n([/a /x /y /z /1] ->)\n[/x /y /z /1]\n([/x /y /z /1] ->)\n(---------------- _copyinterval string ----------------)\n()\n(\\(\\) ->)\n(1)\n(\\(1\\) ->)\n(a)\n(\\(a\\) ->)\n(1a)\n(\\(1a\\) ->)\n(ab)\n(\\(ab\\) ->)\n(bc)\n(\\(bc\\) ->)\n(cde)\n(\\(cde\\) ->)\n(e)\n(\\(e\\) ->)\n()\n(\\(\\) ->)\n(---------------- _copyinterval array ----------------)\n[]\n([] ->)\n[1]\n([1] ->)\n[/a]\n([/a] ->)\n[1 /a]\n([1 /a] ->)\n[/a /b]\n([ /a /b ] ->)\n[/b /c]\n([/b /c] ->)\n[/c /d /e]\n([/c /d /e] ->)\n[/e]\n([/e] ->)\n[]\n([] ->)\n"
  },
  {
    "path": "Tmain/optscript.d/compound.ps",
    "content": "/pc { pstack clear } def\n(abc) dup length pc\n<< /a 1 /b 2 >> dup length pc\n[ true false null ] dup length pc\n\n(abc) () copy pc\n\n<< /a 1 /b 2 >> <<>> copy /a known pc\n<< /a 1 /b 2 >> <<>> copy /b known pc\n<< /a 1 /b 2 >> <<>> copy /c known pc\n\n[ true false null ] [] copy pc\n\n(---------------- get array ----------------) ==\n(a ->) [ (a) (b) (c) ] 0 get pc\n(b ->) [ (a) (b) (c) ] 1 get pc\n(c ->) [ (a) (b) (c) ] 2 get pc\n(true ->) { [ (a) (b) (c) ] 3 get } stopped pc\n\n(---------------- get dict ----------------) ==\n(a ->) << /a (a) true (b) 1 (c) >> /a get pc\n(b ->) << /a (a) true (b) 1 (c) >> true get pc\n(c ->) << /a (a) true (b) 1 (c) >> 1 get pc\n(true ->) { << /a (a) true (b) 1 (c) >> false get } stopped pc\n\n(---------------- get str ----------------) ==\n(97 ->) (abc) 0 get pc\n(98 ->) (abc) 1 get pc\n(99 ->) (abc) 2 get pc\n(true ->) { (abc) 3 get } stopped pc\n\n(---------------- forall array ----------------) ==\n(6 -> ) 0 [ 1 2 3 ] { add } forall pc\n\n(---------------- forall dict values ----------------) ==\n(6 -> ) 0 << /a 1 /b 2 /c 3 >> { exch pop add } forall pc\n\n(---------------- forall dict keys ----------------) ==\n(false ->)\n<< /a 1 /b 2 >> { pop } forall\n{\n    count 3 ne {\n\tstop\n    } if\n    dup /a eq {\n\tpop\n\t/b ne {\n\t    stop\n\t} if\n    } {\n\t/b eq {\n\t    /a ne {\n\t\tstop\n\t    } if\n\t} {\n\t    stop\n\t} ifelse\n    } ifelse\n} stopped pc\n\n(---------------- forall string ----------------) ==\n(294 ->)\n0 (abc) { add } forall pc\n\n(---------------- put string ----------------) ==\n((abc) ->)\n(xbc) dup 0 97 put pc\n\n((abcd) ->)\n(abc) dup 3 100 put pc\n\n((abc e) ->)\n(abc) dup 4 101 put pc\n\n(---------------- put array ----------------) ==\n([/a /b /c] ->)\n[ /a null /c ] dup 1 /b put pc\n\n([/a /b /c /d] ->)\n[ /a /b /c ] dup 3 /d put pc\n\n([/a /b /c null /e] ->)\n[ /a /b /c ] dup 4 /e put pc\n\n(---------------- put dict ----------------) ==\n(1 ->)\n<< /a 0 /b null /c 2 >> dup /b 1 put /b get pc\n\n(---------------- putinterval string ----------------) ==\n((xyzdef) ->)\n(abcdef) dup 0 (xyz) putinterval pc\n\n((xyz123) ->)\n(abcdef) dup 0 (xyz123) putinterval pc\n\n((xyz1234) ->)\n(abcdef) dup 0 (xyz1234) putinterval pc\n\n((abcdex) ->)\n(abcdef) dup 5 (x) putinterval pc\n\n((abcdefx) ->)\n(abcdef) dup 6 (x) putinterval pc\n\n((abcdxf) ->)\n(abcdef) dup 4 (x) putinterval pc\n\n((abcdxyz) ->)\n(abcdef) dup 4 (xyz) putinterval pc\n\n(---------------- putinterval array ----------------) ==\n([/x /b /c] ->)\n[ /a /b /c ] dup 0 [ /x ] putinterval pc\n\n([/a /x /c] ->)\n[ /a /b /c ] dup 1 [ /x ] putinterval pc\n\n([/a /b /x] ->)\n[ /a /b /c ] dup 2 [ /x ] putinterval pc\n\n([/a /b /c /x] ->)\n[ /a /b /c ] dup 3 [ /x ] putinterval pc\n\n([/a /b /c /x /y] ->)\n[ /a /b /c ] dup 3 [ /x /y ] putinterval pc\n\n([/a /b /x /y] ->)\n[ /a /b /c ] dup 2 [ /x /y ] putinterval pc\n\n([/a /x /y] ->)\n[ /a /b /c ] dup 1 [ /x /y ] putinterval pc\n\n([/x /y /c] ->)\n[ /a /b /c ] dup 0 [ /x /y ] putinterval pc\n\n([/x /y /z] ->)\n[ /a /b /c ] dup 0 [ /x /y /z ] putinterval pc\n\n([/a /x /y /z] ->)\n[ /a /b /c ] dup 1 [ /x /y /z ] putinterval pc\n\n([/a /b /x /y /z] ->)\n[ /a /b /c ] dup 2 [ /x /y /z ] putinterval pc\n\n([/a /b /c /x /y /z] ->)\n[ /a /b /c ] dup 3 [ /x /y /z ] putinterval pc\n\n([/a /b /c /x /y /z /1] ->)\n[ /a /b /c ] dup 3 [ /x /y /z /1 ] putinterval pc\n\n([/a /b /x /y /z /1] ->)\n[ /a /b /c ] dup 2 [ /x /y /z /1 ] putinterval pc\n\n([/a /x /y /z /1] ->)\n[ /a /b /c ] dup 1 [ /x /y /z /1 ] putinterval pc\n\n([/x /y /z /1] ->)\n[ /a /b /c ] dup 0 [ /x /y /z /1 ] putinterval pc\n\n(---------------- _copyinterval string ----------------) ==\n(() ->)\n(abcde) 0 0 () _copyinterval pc\n\n((1) ->)\n(abcde) 0 0 (1) _copyinterval pc\n\n((a) ->)\n(abcde) 0 1 () _copyinterval pc\n\n((1a) ->)\n(abcde) 0 1 (1) _copyinterval pc\n\n((ab) ->)\n(abcde) 0 2 () _copyinterval pc\n\n((bc) ->)\n(abcde) 1 2 () _copyinterval pc\n\n((cde) ->)\n(abcde) 2 3 () _copyinterval pc\n\n((e) ->)\n(abcde) 4 1 () _copyinterval pc\n\n(() ->)\n(abcde) 5 0 () _copyinterval pc\n\n(---------------- _copyinterval array ----------------) ==\n([] ->)\n[ /a /b /c /d /e ] 0 0 [] _copyinterval pc\n\n([1] ->)\n[ /a /b /c /d /e ] 0 0 [ 1 ] _copyinterval pc\n\n([/a] ->)\n[ /a /b /c /d /e ] 0 1 [] _copyinterval pc\n\n([1 /a] ->)\n[ /a /b /c /d /e ] 0 1 [ 1 ] _copyinterval pc\n\n([ /a /b ] ->)\n[ /a /b /c /d /e ] 0 2 [] _copyinterval pc\n\n([/b /c] ->)\n[ /a /b /c /d /e ] 1 2 [] _copyinterval pc\n\n([/c /d /e] ->)\n[ /a /b /c /d /e ] 2 3 [] _copyinterval pc\n\n([/e] ->)\n[ /a /b /c /d /e ] 4 1 [] _copyinterval pc\n\n([] ->)\n[ /a /b /c /d /e ] 5 0 [] _copyinterval pc\n\n\n\n"
  },
  {
    "path": "Tmain/optscript.d/control.expected",
    "content": "5\n12\n12\n(string)\n(executed if block)\n(executed if block)\n(executed else block)\n2\n1\n0\n4\n3\n2\n1\n0\n[(jump here as expected) true /undefined]\n[(jump here as expected) false null]\n5\n-1\n-2\n-3\n-4\n-5\n1\n3\n5\n7\n9\nexit in for:\n=> passed\nexit in forall string:\n=> passed\nexit in forall array:\n=> passed\nexit in forall dict:\n=> passed\n(---------------- countexecstack ----------------)\n3\n(---------------- execstack ----------------)\n[]\n(---------------- exception handling ----------------)\n(OK: this code just after loop should be executed)\n(OK: 'exit' should not be caught here.)\n(OK: 'stop' should be caught here.)\n"
  },
  {
    "path": "Tmain/optscript.d/control.ps",
    "content": "/pc { pstack clear } def\n\n{ 3 2 add } exec pc\n/exectest { 10 2 add } def\n/exectest load exec pc\n3 9 /add load exec pc\n(string) exec pc\n\ntrue  { (executed if block) } if pc\nfalse { (executed if block) } if pc\n\n/trueaction  { (executed if block) } def\n/falseaction { (executed else block) } def\n\ntrue  { trueaction } { falseaction } ifelse pc\nfalse { trueaction } { falseaction } ifelse pc\n\n/counter 0 def\n3 { counter counter 1 add /counter exch def } repeat pc\n\n/counter 0 def\n{ counter counter 1 add /counter exch def\n  counter 5 eq { exit } if } loop pc\n\n/underflow { 100 index } def\n{ undefflow } stopped { [(jump here as expected) _newerror _errorname] } { (jump here unexpectedly) } ifelse pc\n\n/break { stop } def\n{ break } stopped { [(jump here as expected) _newerror _errorname] } { (jump here unexpectedly) } ifelse pc\n\n{ 3 2 { //add } exec } exec pc\n\n-1 -1 -5 { == } for\n1 2 10   { == } for\n\n(exit in for:) =\n/counter 0 def\n0 2 10 { counter 1 add /counter exch def\n         6 eq { exit } if\n       } for\ncounter 4 eq {\n    (=> passed) =\n} {\n    (=> failed) =\n} ifelse\n\n(exit in forall string:) =\n(abc) { dup ?b eq { exit } { pop } ifelse } forall\n?b eq {\n    (=> passed) =\n} if\n\n(exit in forall array:) =\n[?a ?b ?c]  { dup ?b eq { exit } { pop } ifelse } forall\n?b eq {\n    (=> passed) =\n} if\n\n(exit in forall dict:) =\n<< ?a /a ?b /b ?c /c >> { pop dup ?b eq { exit } { pop } ifelse } forall\n?b eq {\n    (=> passed) =\n} if\n\n(---------------- countexecstack ----------------) ==\ntrue { countexecstack == } if\n\n(---------------- execstack ----------------) ==\ncountexecstack array execstack ==\n\n(---------------- exception handling ----------------) ==\n{\n    { exit } loop\n    (OK: this code just after loop should be executed) ==\n} stopped {\n    (FAIL: 'exit' should not be caught here.) ==\n} {\n    (OK: 'exit' should not be caught here.) ==\n} ifelse\n\n{\n    { stop } loop\n    (SOMETHING WRONG: this code just after loop should not be executed) ==\n} stopped {\n    (OK: 'stop' should be caught here.) ==\n} {\n    (FAIL: 'stop' should not be caught by loop.) ==\n} ifelse\n"
  },
  {
    "path": "Tmain/optscript.d/dict.expected",
    "content": "3\ntrue\nfalse\ntrue\n-dict:1-\nfalse\n3\n2\n1\n(a)\nfalse\n2\n3\n2\n(---- dictstack & cleardictstack ----)\n3\n4\n2\n(---- store ----)\n1\n-dict:1-\nnull\n(---- store integers ----)\n45\n(---- using types other than name as key objects ----)\n(3)\n(true)\n(false)\n(abc)\n(xyz)\n(3)\n(true)\n(false)\n(abc)\n(xyz)\n"
  },
  {
    "path": "Tmain/optscript.d/dict.ps",
    "content": "10 dict begin\n/three 3 def\n/three load ==\ncurrentdict /three known ==\ncurrentdict /four  known ==\n/three where pstack\nend\n/three where ==\n\nclear\n<< /a 1 /b 2 /c 3 >>\nbegin a b c end pstack\n<< /a (a) >> begin\n/a load ==\nend\n\n<< /a 1 >> dup /a undef /a known == clear\n\n(---- countdictstack ----)\ncountdictstack ==\n5 dict begin\ncountdictstack ==\nend\ncountdictstack ==\n\n(---- dictstack & cleardictstack ----) ==\nclear\n5 dict begin [] dictstack length == clear\n5 dict begin [] dictstack length == clear\ncleardictstack [] dictstack length == clear\n\n(---- store ----) ==\n<< /a 1 /b 2 /c 3 >> << /e 1 /f 2 /g 3 >> /a 0 store pop /a get ==\n\n<< /k null >> dup == /k get ==\n\n(---- store integers ----) ==\n0 << 1 true 2 true 3 true 4 true 5 true 6 true 7 true 8 true 9 true >> {pop add} forall =\n\n(---- using types other than name as key objects ----) ==\n\n/d 10 dict def\n\nd dup 3 (3) put 3 get == clear\nd dup true (true) put true get == clear\nd dup false (false) put false get == clear\nd dup (abc) (abc) put (abc) get == clear\nd dup /xyz (xyz) put (xyz) get == clear\n\n/d0 << 3 (3) true (true) false (false) (abc) (abc) /xyz (xyz) >> def\n\nd0 3     get == clear\nd0 true  get == clear\nd0 false get == clear\nd0 (abc) get == clear\nd0 (xyz) get == clear\n"
  },
  {
    "path": "Tmain/optscript.d/dictx.expected",
    "content": "-dict:0-\n-dict:1-\n-dict:0-\n-dict:1-\n-dict:0-\n-dict:1-\nrangecheck\nnull\n-dict:0-\n-dict:1-\n-dict:1-\n-dict:2-\n-dict:2-\n-dict:3-\nunmatchedmark\nrangecheck\nnull\n"
  },
  {
    "path": "Tmain/optscript.d/dictx.ps",
    "content": "0 dict == clear\n0 dict dup /x 1 put == clear\n1 dict ==\n1 dict dup /y 2 put == clear\n2 dict ==\n2 dict dup /z 2 put == clear\n\n{\n    { -1 dict } stopped {\n        _errorname =\n        stop\n    } if\n} stopped pop\n_errorname =\n\n<< >> == clear\n<<>> dup /x 0 put == clear\n\n<< /x 0 >> ==\n<</x 0>> dup /y 1 put == clear\n\n<< /x 0 /y 1 >> ==\n<< /x 0 /y 1 >> dup /z 2 put == clear\n\n{\n    { >> } stopped {\n               _errorname =\n               stop\n           } if\n}  stopped pop\n\n{\n    { << /a >> } stopped {\n        _errorname =\n        stop\n    } if\n} stopped pop\n_errorname =\n"
  },
  {
    "path": "Tmain/optscript.d/error-undefined-if-if.expected",
    "content": "Error: /undefined in a\nOperand stack:\ntop|   |bottom\nExecution stack:\ntop|   a   {a}   --if--   {true {a} if}   --if--   |bottom\nDictionary stack:\ntop|   -dict:1-   -dict:91-   |bottom\n"
  },
  {
    "path": "Tmain/optscript.d/error-undefined-if-if.ps",
    "content": "true { true { a } if } if\n"
  },
  {
    "path": "Tmain/optscript.d/error-undefined-if.expected",
    "content": "Error: /undefined in a\nOperand stack:\ntop|   |bottom\nExecution stack:\ntop|   a   {a}   --if--   |bottom\nDictionary stack:\ntop|   -dict:1-   -dict:91-   |bottom\n"
  },
  {
    "path": "Tmain/optscript.d/error-undefined-if.ps",
    "content": "true { a } if\n"
  },
  {
    "path": "Tmain/optscript.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/optscript.d/misc.expected",
    "content": "(--------------- bind ---------------)\n{--add-- {--add--}}\n({--add-- {--add--}} ->)\n1\n{--[-- 1 1 --add-- --]--}\n"
  },
  {
    "path": "Tmain/optscript.d/misc.ps",
    "content": "(--------------- bind ---------------) ==\n({--add-- {--add--}} ->)\n{ add { add } } bind pstack clear\n{ 1 } bind exec pstack clear\n{ [ 1 1 add ] } bind pstack\n"
  },
  {
    "path": "Tmain/optscript.d/pstack.expected",
    "content": "false\ntrue\nnull\n-dict:1-\n[{/add} {add}]\n{/add}\n{add}\n{/a /b /c}\n[/a /b /c]\n[1 2 3]\n-mark-\n(abc)\n/a\n1\n"
  },
  {
    "path": "Tmain/optscript.d/pstack.ps",
    "content": "1\n/a\n(abc)\nmark\n[ 1 2 3 ]\n[ /a /b /c ]\n{ /a /b /c }\n{ add }\n{ /add }\n[ { /add } { add } ]\n<< /a { /add } >>\nnull\ntrue\nfalse\n% This isn't printed well.\n% { [ abc ] [ /abc ] }\n\npstack\n"
  },
  {
    "path": "Tmain/optscript.d/read-and-print.expected",
    "content": "(array)\n[/a /b]\n[/abc /efg]\n[/1 /b]\n[/a /2]\n[/123 /123]\n(dict)\n/b\n/b\n/efg\n/efg\n/2\n/2\n/123\n/123\n(cvn)\n//a\n//a /x\n(immediate)\n1\n(a\\nb\\tc\\rd\\fe)\n(abcd\\n\\f\\r\\v\\t z)\n0\n[0]\n[-10]\n[0 -10]\nabc\nefg\n-dict:5-\n-dict:5-\n<<\n  98 /ab\n  99 (efg)\n  100 -dict:4-\n  10 /===\n  97 1\n>> \n<<\n  98 /ab\n  99 (efg)\n  100 <<\n    101 2\n    102 /ef\n    103 (xyz)\n    104 <<\n      105 3\n      106 /ij\n    >> \n  >> \n  10 /====\n  97 1\n>> \n[-dict:6-]\n[-dict:6-]\n[<<\n  98 /ab\n  99 (efg)\n  100 -dict:4-\n  10 /===\n  122 [-dict:2-]\n  97 1\n>> ]\n[<<\n  98 /ab\n  99 (efg)\n  100 <<\n    101 2\n    102 /ef\n    103 (xyz)\n    104 <<\n      105 3\n      106 /ij\n      107 [<<\n        88 1\n        89 [0 1 2]\n      >> ]\n    >> \n  >> \n  10 /====\n  122 [<<\n    66 [0 1 2]\n    65 1\n  >> ]\n  97 1\n>> ]\nchar after metachar\n[97]\n[10]\n"
  },
  {
    "path": "Tmain/optscript.d/read-and-print.ps",
    "content": "/pc { pstack clear } def\n/dpc { get pstack clear } def\n(array) pc\n[/a /b] pc\n[/abc /efg] pc\n[/1 /b] pc\n[/a /2] pc\n[/123 /123] pc\n(dict) pc\n<< /a /b >>     /a dpc\n<</a /b>>       /a dpc\n<< /abc /efg >> /abc dpc\n<</abc /efg>>   /abc dpc\n<< /1 /2 >>     /1 dpc\n<</1 /2>>       /1 dpc\n<< /123 /123 >> /123 dpc\n<</123 /123>>   /123 dpc\n(cvn) pc\n(/a)    cvn pc\n% gsnd prints \"//a /x\" for the next code.\n(/a /x) cvn pc\n(immediate) pc\n/a 1 def\n//a pc\n(a\\nb\\tc\\rd\\fe) pc\n\n/str () def\nstr 0 ?a put\nstr 1 ?b put\nstr 2 ?c put\nstr 3 ?d put\nstr 4 ?\\n put\nstr 5 ?\\f put\nstr 6 ?\\r put\nstr 7 ?\\v put\nstr 8 ?\\t put\nstr 9 ?\\  put\nstr 10 ?z put\nstr ==\n/-a { add } def\n-500 500 -a ==\n[0] ==\n[-10] ==\n[0 -10] ==\n\n/abc =\n(efg) =\n\n/inject {\n    % target key val\n    2 index type /dicttype eq {\n        2 index 3 1 roll put\n    } {\n        2 index 0 get\n        % array key val dict\n        3 1 roll put\n    } ifelse\n} def\n\n/debug= {\n    10 /=    inject dup =\n    10 /==   inject dup ==\n    10 /===  inject dup ===\n    10 /==== inject dup ====\n    pop\n} def\n\n% names cannot be used for keys because\n% the test output becomes unstable.\n%\n<< 10 null\n   97 1\n   98 /ab\n   99 (efg)\n   100 <<\n          101 2\n          102 /ef\n          103 (xyz)\n          104 <<\n                 105 3\n                 106 /ij\n             >>\n      >>\n>>\ndebug=\n\n[\n<< 10 null\n   97 1\n   98 /ab\n   99 (efg)\n   100 <<\n          101 2\n          102 /ef\n          103 (xyz)\n          104 <<\n                 105 3\n                 106 /ij\n                 107 [ << 88 1 89 [ 0 1 2 ] >> ]\n             >>\n      >>\n   122 [ << 65 1 66 [ 0 1 2 ] >> ]\n>>\n]\ndebug=\n\n(char after metachar) =\n[?a] ==\n[?\\n] ==\n"
  },
  {
    "path": "Tmain/optscript.d/relalogbits.expected",
    "content": "true\n(2 2 eq)\nfalse\n(2 0 eq)\nfalse\n(2 /a eq)\nfalse\n(2 true eq)\nfalse\n(2 false eq)\nfalse\n(2 << >> eq)\nfalse\n(2 [ ] eq)\nfalse\n(2 { } eq)\nfalse\n(2 \\( \\) eq)\nfalse\n(2 null eq)\ntrue\n(/a /a eq)\nfalse\n(/a /b eq)\nfalse\n(/a \\(a\\) eq)\n(----------------------- logical operators -----------------------)\ntrue\n(true  true  and => true )\nfalse\n(false true  and => false)\nfalse\n(true  false and => false)\nfalse\n(false false and => false)\ntrue\n(true  true  or  => true )\ntrue\n(false true  or  => true )\ntrue\n(true  false or  => true )\nfalse\n(false false or  => false)\nfalse\n(true  true  xor => false)\ntrue\n(false true  xor => true )\ntrue\n(true  false xor => true )\nfalse\n(false false xor => false)\nfalse\n(true  not => false)\ntrue\n(false not => true )\n(----------------------- comparison -----------------------)\nfalse\n(1 2 gt => false)\nfalse\n(1 1 gt => false)\ntrue\n(2 1 gt => true )\nfalse\n(1 2 ge => false)\ntrue\n(1 1 ge => true )\ntrue\n(2 1 ge => true )\ntrue\n(1 2 lt => true )\nfalse\n(1 1 lt => false)\nfalse\n(2 1 lt => false)\ntrue\n(1 2 le => true )\ntrue\n(1 1 le => true )\nfalse\n(2 1 le => false)\nfalse\n(\\(a\\) \\(b\\) gt => false)\nfalse\n(\\(a\\) \\(a\\) gt => false)\ntrue\n(\\(b\\) \\(a\\) gt => true )\nfalse\n(\\(a\\) \\(b\\) ge => false)\ntrue\n(\\(a\\) \\(a\\) ge => true )\ntrue\n(\\(b\\) \\(a\\) ge => true )\ntrue\n(\\(a\\) \\(b\\) lt => true )\nfalse\n(\\(a\\) \\(a\\) lt => false)\nfalse\n(\\(b\\) \\(a\\) lt => false)\ntrue\n(\\(a\\) \\(b\\) le => true )\ntrue\n(\\(a\\) \\(a\\) le => true )\nfalse\n(\\(b\\) \\(a\\) le => false)\n(----------------------- bit operators -----------------------)\n0\n(0 0 and => 0)\n0\n(0 1 and => 0)\n1\n(1 1 and => 1)\n1\n(3 1 and => 1)\n0\n(2 1 and => 0)\n0\n(0 0 or  => 0)\n1\n(0 1 or  => 1)\n1\n(1 1 or  => 1)\n3\n(3 1 or  => 3)\n3\n(2 1 or  => 3)\n0\n(0 0 xor => 0)\n1\n(0 1 xor => 1)\n0\n(1 1 xor => 0)\n2\n(3 1 xor => 2)\n3\n(2 1 xor => 3)\n-1\n(0 not => 0)\n-2\n(1 not => -2)\n1\n(1 not not => 1)\n56\n(7    3  bitshift => 56)\n17\n(142 -3  bitshift => 17)\n"
  },
  {
    "path": "Tmain/optscript.d/relalogbits.ps",
    "content": "/pc { pstack clear } def\n(2 2 eq) 2 2 eq pc\n(2 0 eq) 2 0 eq pc\n(2 /a eq) 2 /a eq pc\n(2 true eq) 2 true eq pc\n(2 false eq) 2 false eq pc\n(2 << >> eq) 2 << >> eq pc\n(2 [ ] eq) 2 [ ] eq pc\n(2 { } eq) 2 { } eq pc\n(2 \\( \\) eq) 2 ( ) eq pc\n(2 null eq) 2 null eq pc\n\n(/a /a eq) /a /a eq pc\n(/a /b eq) /a /b eq pc\n(/a \\(a\\) eq) /a (a) eq pc\n\n(----------------------- logical operators -----------------------) ==\n(true  true  and => true )  true  true  and pc\n(false true  and => false)  false true  and pc\n(true  false and => false)  true  false and pc\n(false false and => false)  false false and pc\n\n(true  true  or  => true )  true  true  or  pc\n(false true  or  => true )  false true  or  pc\n(true  false or  => true )  true  false or  pc\n(false false or  => false)  false false or  pc\n\n(true  true  xor => false)  true  true  xor pc\n(false true  xor => true )  false true  xor pc\n(true  false xor => true )  true  false xor pc\n(false false xor => false)  false false xor pc\n\n(true  not => false) true  not pc\n(false not => true ) false not pc\n\n(----------------------- comparison -----------------------) ==\n(1 2 gt => false) 1 2 gt pc\n(1 1 gt => false) 1 1 gt pc\n(2 1 gt => true ) 2 1 gt pc\n\n(1 2 ge => false) 1 2 ge pc\n(1 1 ge => true ) 1 1 ge pc\n(2 1 ge => true ) 2 1 ge pc\n\n(1 2 lt => true ) 1 2 lt pc\n(1 1 lt => false) 1 1 lt pc\n(2 1 lt => false) 2 1 lt pc\n\n(1 2 le => true ) 1 2 le pc\n(1 1 le => true ) 1 1 le pc\n(2 1 le => false) 2 1 le pc\n\n((a) (b) gt => false) (a) (b) gt pc\n((a) (a) gt => false) (a) (a) gt pc\n((b) (a) gt => true ) (b) (a) gt pc\n\n((a) (b) ge => false) (a) (b) ge pc\n((a) (a) ge => true ) (a) (a) ge pc\n((b) (a) ge => true ) (b) (a) ge pc\n\n((a) (b) lt => true ) (a) (b) lt pc\n((a) (a) lt => false) (a) (a) lt pc\n((b) (a) lt => false) (b) (a) lt pc\n\n((a) (b) le => true ) (a) (b) le pc\n((a) (a) le => true ) (a) (a) le pc\n((b) (a) le => false) (b) (a) le pc\n\n(----------------------- bit operators -----------------------) ==\n(0 0 and => 0) 0 0 and pc\n(0 1 and => 0) 0 1 and pc\n(1 1 and => 1) 1 1 and pc\n(3 1 and => 1) 3 1 and pc\n(2 1 and => 0) 2 1 and pc\n\n(0 0 or  => 0) 0 0 or pc\n(0 1 or  => 1) 0 1 or pc\n(1 1 or  => 1) 1 1 or pc\n(3 1 or  => 3) 3 1 or pc\n(2 1 or  => 3) 2 1 or pc\n\n(0 0 xor => 0) 0 0 xor pc\n(0 1 xor => 1) 0 1 xor pc\n(1 1 xor => 0) 1 1 xor pc\n(3 1 xor => 2) 3 1 xor pc\n(2 1 xor => 3) 2 1 xor pc\n\n(0 not => 0) 0 not pc\n(1 not => -2) 1 not pc\n(1 not not => 1) 1 not not pc\n\n(7    3  bitshift => 56) 7    3  bitshift pc\n(142 -3  bitshift => 17) 142 -3  bitshift pc\n"
  },
  {
    "path": "Tmain/optscript.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nBUILDDIR=$2\nOPTSCRIPT=$4\n\n. ../utils.sh\n\nif ! [ -x \"${OPTSCRIPT}\" ]; then\n\tskip \"no optscript\"\nfi\n\n\n_VALGRIND_EXIT=58\n\nif type valgrind > /dev/null 2>&1; then\n\tV()\n\t{\n\t\tvlog=$1\n\t\tshift\n\t\tvalgrind --leak-check=full --error-exitcode=${_VALGRIND_EXIT} --log-file=\"${vlog}\" \"$@\"\n\t}\nelse\n\tV()\n\t{\n\t\tvlog=$1\n\t\tshift\n\t\ttouch $vlog\n\t\t\"$@\"\n\t}\nfi\n\nrm -f ${BUILDDIR}/*.tmp\n\nfor i in $(ls *.ps); do\n    printf \"%s\" \"${i}...\"\n    o=${BUILDDIR}/$(basename $i .ps).out.tmp\n    e=$(basename $i .ps).expected\n\tv=${BUILDDIR}/$(basename $i .ps).valgrind.tmp\n\n\tcase $i in\n\t\terror-*.ps)\n\t\t\tV $v ${OPTSCRIPT} $i > $o 2>&1\n\t\t\t;;\n\t\t*)\n\t\t\tV $v ${OPTSCRIPT} $i > $o\n\t\t\t;;\n\tesac\n\ts=$?\n    printf \"%s\" \"$s\"\n\n\tif [ \"$s\" = \"$_VALGRIND_EXIT\" ]; then\n\t\techo\n\t\tcat $v;\n\t\texit $_VALGRIND_EXIT\n\tfi\n\n\tcase $s-$i in\n\t\t*-error-*.ps|0-*)\n\t\t\techo\n\t\t\tif diff -ruN --strip-trailing-cr $e $o; then\n\t\t\t   rm $o\n\t\t\t   rm $v\n\t\t\tfi\n\t\t\t;;\n\t\t*)\n\t\t\techo ERROR\n\t\t\t;;\n    esac\ndone\n"
  },
  {
    "path": "Tmain/optscript.d/stack.expected",
    "content": "/b\n/a\n/a\n/a\n-mark-\n/a\n/a\n-mark-\n/z\n/y\n/z\n/y\n/x\n/z\n/z\n/y\n/x\n/z\n/y\n/x\n/x\n/z\n/y\n/x\n/z\n/y\n/x\n/p\n/r\n/q\n/r\n/q\n/p\n3\n3\n/A\n/rangecheck\n"
  },
  {
    "path": "Tmain/optscript.d/stack.ps",
    "content": "/a /b pstack\npop   pstack\nmark  exch pstack\ndup   pstack\nclear\n/x /y /z 2 copy pstack\npop pop  1 copy pstack\npop      0 copy pstack\n2         index pstack\nclear\n/x /y /z  0 index ==\n/x /y /z  1 index ==\n/x /y /z  2 index ==\nclear\n/p /q /r  3 -1 roll pstack\n3  1 roll pstack\ncount ==\nmark 4 1 roll\ncounttomark ==\n/A 5 1 roll\ncleartomark\npstack\n{ (a) (b) (c) -1 3 roll } stopped {\n    _errorname ==\n} {\n    (RANGECHECK error is expected but got NONE) ==\n} ifelse\nclear\n"
  },
  {
    "path": "Tmain/optscript.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/optscript.d/stdout-expected.txt",
    "content": "arithmetic.ps...0\narray.ps...0\narrayx.ps...0\ncompound.ps...0\ncontrol.ps...0\ndict.ps...0\ndictx.ps...0\nerror-undefined-if-if.ps...1\nerror-undefined-if.ps...1\nmisc.ps...0\npstack.ps...0\nread-and-print.ps...0\nrelalogbits.ps...0\nstack.ps...0\nstring.ps...0\ntypeattrconv.ps...0\n"
  },
  {
    "path": "Tmain/optscript.d/string.expected",
    "content": "(--------------- string ---------------)\n32\n32\n32\n(32 32 32 ->)\n(--------------- _strstr ---------------)\ntrue\n0\n(abcdefgab)\n(\\(abcdefgab\\) 0 true->)\ntrue\n5\n(abcdefgab)\n(\\(abcdefgab\\) 5 true ->)\ntrue\n6\n(abcdefg)\n(\\(abcdefg\\) 6 true ->)\ntrue\n0\n(abcdefg)\n(\\(abcdefg\\) 0 true ->)\nfalse\n(abcdefg)\n(\\(abcdefg\\) false ->)\n(--------------- _strrstr ---------------)\ntrue\n7\n(abcdefgab)\n(\\(abcdefgab\\) 7 true->)\ntrue\n5\n(abcdefgab)\n(\\(abcdefgab\\) 5 true ->)\ntrue\n6\n(abcdefg)\n(\\(abcdefg\\) 6 true ->)\ntrue\n7\n(abcdefg)\n(\\(abcdefg\\) 7 true ->)\nfalse\n(abcdefg)\n(\\(abcdefg\\) false ->)\n(--------------- _strchr/_strrchr ---------------)\ntrue\n0\n(aba)\n(\\(aba\\) 0 true ->)\ntrue\n2\n(aba)\n(\\(aba\\) 2 true ->)\ntrue\n1\n(aba)\n(\\(aba\\) 1 true ->)\ntrue\n1\n(aba)\n(\\(aba\\) 1 true ->)\nfalse\n(aba)\n(\\(aba\\) false ->)\nfalse\n(aba)\n(\\(aba\\) false ->)\n(--------------- _strpbrk ---------------)\ntrue\n1\n(a.b;c)\n(\\(a.b;c\\) 1 true ->)\nfalse\n(a.b;c)\n(\\(a.b;c\\) false ->)\n"
  },
  {
    "path": "Tmain/optscript.d/string.ps",
    "content": "(--------------- string ---------------) ==\n(32 32 32 ->)\n3 string { } forall pstack clear\n(--------------- _strstr ---------------) ==\n((abcdefgab) 0 true->)\n(abcdefgab) (ab) _strstr pstack clear\n\n((abcdefgab) 5 true ->)\n(abcdefgab) (fg) _strstr pstack clear\n\n((abcdefg) 6 true ->)\n(abcdefg) (g) _strstr pstack clear\n\n((abcdefg) 0 true ->)\n(abcdefg) () _strstr pstack clear\n\n((abcdefg) false ->)\n(abcdefg) (z) _strstr pstack clear\n\n(--------------- _strrstr ---------------) ==\n((abcdefgab) 7 true->)\n(abcdefgab) (ab) _strrstr pstack clear\n\n((abcdefgab) 5 true ->)\n(abcdefgab) (fg) _strrstr pstack clear\n\n((abcdefg) 6 true ->)\n(abcdefg) (g) _strrstr pstack clear\n\n((abcdefg) 7 true ->)\n(abcdefg) () _strrstr pstack clear\n\n((abcdefg) false ->)\n(abcdefg) (z) _strrstr pstack clear\n\n(--------------- _strchr/_strrchr ---------------) ==\n\n/char { 0 get } def\n\n((aba) 0 true ->)\n(aba) (a) char _strchr pstack clear\n\n((aba) 2 true ->)\n(aba) (a) char _strrchr pstack clear\n\n((aba) 1 true ->)\n(aba) (b) char _strchr pstack clear\n\n((aba) 1 true ->)\n(aba) (b) char _strrchr pstack clear\n\n((aba) false ->)\n(aba) (c) char _strchr pstack clear\n\n((aba) false ->)\n(aba) (c) char _strrchr pstack clear\n\n(--------------- _strpbrk ---------------) ==\n\n((a.b;c) 1 true ->)\n(a.b;c) (;.) _strpbrk pstack clear\n\n((a.b;c) false ->)\n(a.b;c) (,-) _strpbrk pstack clear\n"
  },
  {
    "path": "Tmain/optscript.d/typeattrconv.expected",
    "content": "true\nbooleantype\nfalse\nbooleantype\nnull\nnulltype\n2\nintegertype\n(abc)\nstringtype\n/name\nnametype\n--add--\noperatortype\n-mark-\nmarktype\n[1 2 3]\narraytype\n-dict:1-\ndicttype\n{add}\narraytype\n/xyz\n(abc)\n(efg)\n(true)\n(false)\n(99)\n(-309)\n(--nulltype--)\n(--arraytype--)\n(--dicttype--)\n(--arraytype--)\n3\nabc\n/abc\ntrue\n{}\n[]\ntrue\n"
  },
  {
    "path": "Tmain/optscript.d/typeattrconv.ps",
    "content": "/type1 { dup == type == clear } def\n\ntrue type1\nfalse type1\nnull type1\n2 type1\n(abc) type1\n/name type1\n/add load type1\nmark type1\n[ 1 2 3 ] type1\n<< /a 1 >> type1\n{ add } type1\n\n(xyz) cvn ==\n\n(abc) 0 string cvs ==\n/efg 0 string cvs ==\ntrue 0 string cvs ==\nfalse 0 string cvs ==\n99 0 string cvs ==\n-309 0 string cvs ==\nnull 0 string cvs ==\n[ ] 0 string cvs ==\n<< >> 0 string cvs ==\n{ } 0 string cvs ==\n\n1 cvx 2 cvx [ /add cvx ] cvx exec ==\n\n{ /abc dup cvx pstack eq == } exec\n{ [  ] dup cvx pstack eq == } exec\n"
  },
  {
    "path": "Tmain/output-encoding-option.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/output-encoding-option.d/input.java",
    "content": "class Foo { // Fooクラス\n\tpublic Foo() { // コンストラクタ\n\t}\n}\n"
  },
  {
    "path": "Tmain/output-encoding-option.d/input.js",
    "content": "var a = 1; // ѿ\n"
  },
  {
    "path": "Tmain/output-encoding-option.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2015 Yasuhiro MATSUMOTO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\n\n. ../utils.sh\n\nif ${CTAGS} --quiet --options=NONE --list-features | grep -q iconv; then\n  check_encoding shift_jis\n  check_encoding utf-8\n  check_encoding euc-jp\n  if ${CTAGS}  --quiet --options=NONE \\\n\t       --pseudo-tags=-TAG_PROC_CWD \\\n\t       --pseudo-tags=-TAG_PROGRAM_VERSION \\\n\t       --pseudo-tags=-TAG_KIND_DESCRIPTION \\\n\t       --pseudo-tags=-TAG_FIELD_DESCRIPTION \\\n\t       --pseudo-tags=-TAG_EXTRA_DESCRIPTION \\\n\t       --pseudo-tags=-TAG_ROLE_DESCRIPTION \\\n\t       --pseudo-tags=-TAG_PARSER_VERSION \\\n\t       --pseudo-tags=-TAG_OUTPUT_VERSION \\\n\t       --output-encoding=shift_jis --input-encoding=utf-8 --input-encoding-javascript=euc-jp \\\n\t       -o ${BUILDDIR}/tags \\\n\t       input.js input.java ; then\n      remove_commit_id ${BUILDDIR}/tags\n  fi\n  exit $?\nelse\n\tskip \"iconv feature is not available\"\nfi\n"
  },
  {
    "path": "Tmain/output-encoding-option.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/output-encoding-option.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/output-encoding-option.d/tags-expected.txt",
    "content": "!_TAG_FILE_ENCODING\tshift_jis\t//\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\nFoo\tinput.java\t/^\tpublic Foo() { \\/\\/ RXgN^$/;\"\tm\tclass:Foo\nFoo\tinput.java\t/^class Foo { \\/\\/ FooNX$/;\"\tc\na\tinput.js\t/^var a = 1; \\/\\/ ϐ$/;\"\tv\n"
  },
  {
    "path": "Tmain/output-file-resource-management.d/input.c",
    "content": "int\nmain(void)\n{\n}\n"
  },
  {
    "path": "Tmain/output-file-resource-management.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\n\n. ../utils.sh\n\nexit_status_for_input_c $CTAGS NONE           -o -              --sort=no\nexit_status_for_input_c $CTAGS $BUILDDIR/tags -o $BUILDDIR/tags --sort=no\nexit_status_for_input_c $CTAGS $BUILDDIR/tags -o $BUILDDIR/tags\nexit_status_for_input_c $CTAGS NONE           -o -\n\nexit_status_for_input_c $CTAGS NONE           -e -o -              --sort=no\nexit_status_for_input_c $CTAGS $BUILDDIR/TAGS -e -o $BUILDDIR/TAGS --sort=no\nexit_status_for_input_c $CTAGS $BUILDDIR/TAGS -e -o $BUILDDIR/TAGS\nexit_status_for_input_c $CTAGS NONE           -e -o -\n\nexit_status_for_input_c $CTAGS NONE             -x -o -                --sort=no\nexit_status_for_input_c $CTAGS $BUILDDIR/tags-x -x -o $BUILDDIR/tags-x --sort=no\nexit_status_for_input_c $CTAGS $BUILDDIR/tags-x -x -o $BUILDDIR/tags-x\nexit_status_for_input_c $CTAGS NONE             -x -o -\n"
  },
  {
    "path": "Tmain/output-file-resource-management.d/stdout-expected.txt",
    "content": "-o - --sort=no => ok\n-o tags --sort=no => ok\n-o tags => ok\n-o - => ok\n-e -o - --sort=no => ok\n-e -o TAGS --sort=no => ok\n-e -o TAGS => ok\n-e -o - => ok\n-x -o - --sort=no => ok\n-x -o tags-x --sort=no => ok\n-x -o tags-x => ok\n-x -o - => ok\n"
  },
  {
    "path": "Tmain/output-format-option.d/input.c",
    "content": "int\nmain(void)\n{\n  return 0;\n}\n"
  },
  {
    "path": "Tmain/output-format-option.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nrun_with_format u-ctags\nrun_with_format etags\nrun_with_format xref\n"
  },
  {
    "path": "Tmain/output-format-option.d/stdout-expected.txt",
    "content": "# u-ctags\nmain\tinput.c\t/^main(void)$/;\"\tf\ttyperef:typename:int\n# etags\n\f\ninput.c,20\nmain(void)main\u00012,4\n# xref\nmain             function      2 input.c          main(void)\n"
  },
  {
    "path": "Tmain/output-input-field-with-no-escape.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=$1\n\n\n\nif ! ( echo '#define foo' > 'a\\b.c' ) 2> /dev/null; then\n\t   skip \"unsuitable platform to run this test\"\nfi\n\necho '# u-ctags'\n${CTAGS} --options=NONE --pseudo-tags=TAG_OUTPUT_MODE --extras=+p --output-format=u-ctags -o - 'a\\b.c'\n\necho '# e-ctags'\n${CTAGS} --options=NONE --pseudo-tags=TAG_OUTPUT_MODE --extras=+p --output-format=e-ctags -o - 'a\\b.c'\n\nrm 'a\\b.c'\n"
  },
  {
    "path": "Tmain/output-input-field-with-no-escape.d/stdout-expected.txt",
    "content": "# u-ctags\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\nfoo\ta\\\\b.c\t/^#define foo$/;\"\td\tfile:\n# e-ctags\n!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\nfoo\ta\\b.c\t/^#define foo$/;\"\td\tfile:\n"
  },
  {
    "path": "Tmain/parser-init-useCork.d/input.x",
    "content": "func A\n     var B\nend\n"
  },
  {
    "path": "Tmain/parser-init-useCork.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --options=x.ctags -x --_xformat=\"%N %s %{end}\" input.x\nexit $?\n"
  },
  {
    "path": "Tmain/parser-init-useCork.d/stdout-expected.txt",
    "content": "A  3\nB A \n"
  },
  {
    "path": "Tmain/parser-init-useCork.d/x.ctags",
    "content": "--langdef=X\n--map-X=+.x\n--kinddef-X=f,func,functions\n--kinddef-X=v,var,variables\n\n# This triggers the parser initialization.\n--kinds-X=+{var}\n\n--regex-X=/^func +([A-Z])$/\\1/f/{scope=push}\n--regex-X=/^end$///{scope=pop}{placeholder}\n--regex-X=/^[ \\t]*var ([A-Z])$/\\1/v/{scope=ref}\n"
  },
  {
    "path": "Tmain/parser-specific-extras-for-foreign-lang.d/input-0.x1",
    "content": "D:def00\nd:def01\nv:var0\n"
  },
  {
    "path": "Tmain/parser-specific-extras-for-foreign-lang.d/input-1.x1",
    "content": "D:def10\nd:def11\nv:var1\n"
  },
  {
    "path": "Tmain/parser-specific-extras-for-foreign-lang.d/run.sh",
    "content": "# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=$1\n\nV=\n# V=valgrind\n\nprintf \"# %s\\n\" --extras-X0=+'{iname}'\n${V} ${CTAGS} --quiet --options=NONE --options=./x0.ctags --options=./x1.ctags \\\n\t --extras-X0=+'{iname}' --fields=+'{extras}{language}' -o - input-0.x1\n\nprintf \"# %s\\n\" --extras-X0=-'{iname}'\n${V} ${CTAGS} --quiet --options=NONE --options=./x0.ctags --options=./x1.ctags \\\n\t --extras-X0=-'{iname}' --fields=+'{extras}{language}' -o - input-1.x1\n"
  },
  {
    "path": "Tmain/parser-specific-extras-for-foreign-lang.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/parser-specific-extras-for-foreign-lang.d/stdout-expected.txt",
    "content": "# --extras-X0=+{iname}\n__def01__\tinput-0.x1\t/^d:def01$/;\"\td\tlanguage:X0\textras:iname\ndef00\tinput-0.x1\t/^D:def00$/;\"\td\tlanguage:X0\nvar0\tinput-0.x1\t/^v:var0$/;\"\tv\tlanguage:X1\n# --extras-X0=-{iname}\ndef10\tinput-1.x1\t/^D:def10$/;\"\td\tlanguage:X0\nvar1\tinput-1.x1\t/^v:var1$/;\"\tv\tlanguage:X1\n"
  },
  {
    "path": "Tmain/parser-specific-extras-for-foreign-lang.d/x0.ctags",
    "content": "--langdef=X0\n--kinddef-X0=d,def,definitions\n--_extradef-X0=iname,internal name like __x__\n"
  },
  {
    "path": "Tmain/parser-specific-extras-for-foreign-lang.d/x1.ctags",
    "content": "--langdef=X1{_foreignLanguage=X0}\n--map-X1=+.x1\n--kinddef-X1=v,var,variables\n--regex-X1=/D:([a-z0-9]+)$/\\1/d/{_language=X0}\n--regex-X1=/d:([a-z0-9]+)$/__\\1__/d/{_language=X0}{_extra=iname}\n--regex-X1=/v:([a-z0-9]+)$/\\1/v/\n"
  },
  {
    "path": "Tmain/parser-specific-extras.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=\"--quiet --options=NONE --with-list-header=no\"\n\n${CTAGS} --quiet --options=NONE --extras='*' --list-extras=Robot\n${CTAGS} ${O} --extras-Robot=-'{whitespaceSwapped}' --list-extras=Robot\n${CTAGS} ${O} --extras-Robot=-'{whitespaceSwapped}' --extras-Robot=+'{whitespaceSwapped}' --list-extras=Robot\n${CTAGS} ${O} --extras-all=-'{whitespaceSwapped}' --list-extras=Robot\n${CTAGS} ${O} --extras-all=-'{whitespaceSwapped}' --extras-all=+'{whitespaceSwapped}' --list-extras=Robot\n${CTAGS} ${O} --extras-all=-'{whitespaceSwapped}' --extras-Robot=+'{whitespaceSwapped}' --list-extras=Robot\n${CTAGS} ${O} --extras-Robot=-'{whitespaceSwapped}' --extras-all=+'{whitespaceSwapped}' --list-extras=Robot\n"
  },
  {
    "path": "Tmain/parser-specific-extras.d/stdout-expected.txt",
    "content": "#LETTER NAME              ENABLED LANGUAGE FIXED VER DESCRIPTION\n-       whitespaceSwapped yes     Robot    no      0 Include tags swapping whitespace and underscore chars\n-       whitespaceSwapped no      Robot    no      0 Include tags swapping whitespace and underscore chars\n-       whitespaceSwapped yes     Robot    no      0 Include tags swapping whitespace and underscore chars\n-       whitespaceSwapped no      Robot    no      0 Include tags swapping whitespace and underscore chars\n-       whitespaceSwapped yes     Robot    no      0 Include tags swapping whitespace and underscore chars\n-       whitespaceSwapped yes     Robot    no      0 Include tags swapping whitespace and underscore chars\n-       whitespaceSwapped yes     Robot    no      0 Include tags swapping whitespace and underscore chars\n"
  },
  {
    "path": "Tmain/parser-specific-fields-clearing-all.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\n\necho \"# default\"\n${CTAGS} --quiet --options=NONE --with-list-header=no\\\n\t\t --list-fields=LdScript\n\necho \"# clear all\"\n${CTAGS} --quiet --options=NONE --with-list-header=no\\\n\t\t --fields-LdScript= --list-fields=LdScript\n"
  },
  {
    "path": "Tmain/parser-specific-fields-clearing-all.d/stdout-expected.txt",
    "content": "# default\n-       assignment yes     LdScript s--    no    --   0 how a value is assigned to the symbol\n# clear all\n-       assignment no      LdScript s--    no    --   0 how a value is assigned to the symbol\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang-in-json.d/input.unknownx",
    "content": "public func foo(n, m);\nprotected func bar(n);\nprivate func baz(n,...);\nSTR:strset@iamowner\nSTR:setsetempty@\nSTR:notset\nY:iamowner2=tagme2\nZ:tagme-z@iamowner-z\neset:a\nenoset:b\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang-in-json.d/knownz.ctags",
    "content": "--langdef=knownz\n--kinddef-knownz=m,mark,makers\n\n--_fielddef-knownz=owner,the owner of the markers{datatype=str}\n\n--_fielddef-knownz=len,the length of owner string{datatype=int}\n--fields-knownz=+{len}\n--_fielddef-knownz=lenplus,the length of owner string + 1{datatype=int}\n--fields-knownz=+{lenplus}\n\n--_fielddef-knownz=exported,whether the marker is exported or not{datatype=bool}\n--fields-knownz=+{exported}\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang-in-json.d/run.sh",
    "content": "# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=$1\n\nV=\n# V=valgrind\n\nis_feature_available \"${CTAGS}\" json\n\necho \"# output: json\"\n${V} ${CTAGS} --options=NONE --options=./knownz.ctags --sort=no --options=./unknownx.ctags \\\n\t --fields=+l \\\n\t --fields-unknownx=+'{protection}{signature}' \\\n\t --fields-knownz=+'{owner}' \\\n\t --output-format=json \\\n\t -o - input.unknownx\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang-in-json.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang-in-json.d/stdout-expected.txt",
    "content": "# output: json\n{\"_type\": \"tag\", \"name\": \"foo\", \"path\": \"input.unknownx\", \"pattern\": \"/^public func foo(n, m);$/\", \"language\": \"unknownx\", \"kind\": \"func\", \"protection\": \"public \", \"signature\": \"(n, m)\"}\n{\"_type\": \"tag\", \"name\": \"bar\", \"path\": \"input.unknownx\", \"pattern\": \"/^protected func bar(n);$/\", \"language\": \"unknownx\", \"kind\": \"func\", \"protection\": \"protected \", \"signature\": \"(n)\"}\n{\"_type\": \"tag\", \"name\": \"baz\", \"path\": \"input.unknownx\", \"pattern\": \"/^private func baz(n,...);$/\", \"language\": \"unknownx\", \"kind\": \"func\", \"protection\": \"private \", \"signature\": \"(n,...)\"}\n{\"_type\": \"tag\", \"name\": \"strset\", \"path\": \"input.unknownx\", \"pattern\": \"/^STR:strset@iamowner$/\", \"language\": \"knownz\", \"kind\": \"mark\", \"owner\": \"iamowner\"}\n{\"_type\": \"tag\", \"name\": \"setsetempty\", \"path\": \"input.unknownx\", \"pattern\": \"/^STR:setsetempty@$/\", \"language\": \"knownz\", \"kind\": \"mark\", \"owner\": \"\"}\n{\"_type\": \"tag\", \"name\": \"notset\", \"path\": \"input.unknownx\", \"pattern\": \"/^STR:notset$/\", \"language\": \"knownz\", \"kind\": \"mark\"}\n{\"_type\": \"tag\", \"name\": \"tagme2\", \"path\": \"input.unknownx\", \"pattern\": \"/^Y:iamowner2=tagme2$/\", \"language\": \"knownz\", \"kind\": \"mark\", \"owner\": \"iamowner2\"}\n{\"_type\": \"tag\", \"name\": \"tagme-z\", \"path\": \"input.unknownx\", \"pattern\": \"/^Z:tagme-z@iamowner-z$/\", \"language\": \"knownz\", \"kind\": \"mark\", \"owner\": \"iamowner-z\", \"len\": 10, \"lenplus\": 11}\n{\"_type\": \"tag\", \"name\": \"a\", \"path\": \"input.unknownx\", \"pattern\": \"/^eset:a$/\", \"language\": \"knownz\", \"kind\": \"mark\", \"exported\": true}\n{\"_type\": \"tag\", \"name\": \"b\", \"path\": \"input.unknownx\", \"pattern\": \"/^enoset:b$/\", \"language\": \"knownz\", \"kind\": \"mark\"}\n{\"_type\": \"tag\", \"name\": \"9_exported\", \"path\": \"input.unknownx\", \"pattern\": \"/^enoset:b$/\", \"language\": \"knownz\", \"kind\": \"mark\"}\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang-in-json.d/unknownx.ctags",
    "content": "--langdef=unknownx{_foreignLanguage=knownz}\n--kinddef-unknownx=f,func,functions\n--map-unknownx=+.unknownx\n\n--_fielddef-unknownx=protection,protections\n--_fielddef-unknownx=signature,signatures\n\n--_prelude-unknownx={{\n   /exported false def\n}}\n\n--regex-unknownx=/^((public|protected|private) +)?func ([^\\(]+)\\((.*)\\)/\\3/f/{_field=protection:\\1}{_field=signature:(\\4)}\n--regex-unknownx=/^STR:([a-z]+)@([a-z]+)/\\1/m/{_language=knownz}{_field=owner:\\2}\n--regex-unknownx=/^STR:([a-z]+)@$/\\1/m/{_language=knownz}{_field=owner:}\n--regex-unknownx=/^STR:([a-z]+)$/\\1/m/{_language=knownz}\n--regex-unknownx=/^Y:([a-z0-9]+)=([a-z0-9]+)/\\2/m/{_field=owner:\\1}{_language=knownz}\n--regex-unknownx=/^Z:([-a-z]+)@([-a-z]+)/\\1/m/{_language=knownz}{{\n    . \\2 knownz.owner:\n    . :knownz.owner {\n        . exch length knownz.len:\n    } if\n    . :knownz.len {\n        1 add\n        . exch knownz.lenplus:\n    } if\n}}\n\n--regex-unknownx=/^eset:([-a-z]+)/\\1/m/{_language=knownz}{{\n    /exported . def\n    . true knownz.exported:\n}}\n\n--regex-unknownx=/^enoset:([-a-z]+)/\\1/m/{_language=knownz}{{\n    . false knownz.exported:\n    exported :knownz.exported and {\n       mark exported 0 string cvs (_exported) _buildstring\n       /knownz\n       /mark\n       1@ _foreigntag _commit pop\n    } if\n}}\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang.d/input.unknownx",
    "content": "public func foo(n, m);\nprotected func bar(n);\nprivate func baz(n,...);\nSTR:strset@iamowner\nSTR:setsetempty@\nSTR:notset\nY:iamowner2=tagme2\nZ:tagme-z@iamowner-z\neset:a\nenoset:b\n\nstb:o\nstb:p-\nstb:q.something string\nx0:O\nx1:P\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang.d/knownz.ctags",
    "content": "--langdef=knownz\n--kinddef-knownz=m,mark,makers\n\n--_fielddef-knownz=owner,the owner of the markers{datatype=str}\n\n--_fielddef-knownz=len,the length of owner string{datatype=int}\n--fields-knownz=+{len}\n--_fielddef-knownz=lenplus,the length of owner string + 1{datatype=int}\n--fields-knownz=+{lenplus}\n\n--_fielddef-knownz=exported,whether the marker is exported or not{datatype=bool}\n--fields-knownz=+{exported}\n\n--_fielddef-knownz=stb,string or false{datatype=str+bool}\n--fields-knownz=+{stb}\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang.d/run.sh",
    "content": "# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=$1\n\nV=\n# V=valgrind\n\necho \"# output: tags\"\n${V} ${CTAGS} --options=NONE --options=./knownz.ctags --sort=no --options=./unknownx.ctags \\\n\t --fields=+l \\\n\t --fields-unknownx=+'{protection}{signature}' \\\n\t --fields-knownz=+'{owner}' \\\n\t -o - input.unknownx\n\necho \"# output: xref\"\n${V} ${CTAGS} --options=NONE --options=./knownz.ctags --sort=no --options=./unknownx.ctags \\\n\t --fields=+l \\\n\t --fields-unknownx=+'{protection}{signature}' \\\n\t --fields-knownz=+'{owner}' \\\n\t -x --_xformat=\"%N %l / owner:%{knownz.owner},len:%{knownz.len},lenplus:%{knownz.lenplus},exported:%{knownz.exported},stb:%{knownz.stb} / %{unknownx.protection}%{unknownx.signature}\" \\\n\t -o - input.unknownx\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\n/not-set\nfalse\n(something string)\n# Setting a string to a bool field\ntrue\ntrue\n# Setting a string to a int field\ntrue\n1\nctags: Notice: No options will be read from files or environment\n/not-set\nfalse\n(something string)\n# Setting a string to a bool field\ntrue\ntrue\n# Setting a string to a int field\ntrue\n1\n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang.d/stdout-expected.txt",
    "content": "# output: tags\nfoo\tinput.unknownx\t/^public func foo(n, m);$/;\"\tf\tlanguage:unknownx\tprotection:public \tsignature:(n, m)\nbar\tinput.unknownx\t/^protected func bar(n);$/;\"\tf\tlanguage:unknownx\tprotection:protected \tsignature:(n)\nbaz\tinput.unknownx\t/^private func baz(n,...);$/;\"\tf\tlanguage:unknownx\tprotection:private \tsignature:(n,...)\nstrset\tinput.unknownx\t/^STR:strset@iamowner$/;\"\tm\tlanguage:knownz\towner:iamowner\nsetsetempty\tinput.unknownx\t/^STR:setsetempty@$/;\"\tm\tlanguage:knownz\towner:\nnotset\tinput.unknownx\t/^STR:notset$/;\"\tm\tlanguage:knownz\ntagme2\tinput.unknownx\t/^Y:iamowner2=tagme2$/;\"\tm\tlanguage:knownz\towner:iamowner2\ntagme-z\tinput.unknownx\t/^Z:tagme-z@iamowner-z$/;\"\tm\tlanguage:knownz\towner:iamowner-z\tlen:10\tlenplus:11\na\tinput.unknownx\t/^eset:a$/;\"\tm\tlanguage:knownz\texported:\nb\tinput.unknownx\t/^enoset:b$/;\"\tm\tlanguage:knownz\n9_exported\tinput.unknownx\t/^enoset:b$/;\"\tm\tlanguage:knownz\no\tinput.unknownx\t/^stb:o$/;\"\tm\tlanguage:knownz\np\tinput.unknownx\t/^stb:p-$/;\"\tm\tlanguage:knownz\tstb:\nq\tinput.unknownx\t/^stb:q.something string$/;\"\tm\tlanguage:knownz\tstb:something string\nO\tinput.unknownx\t/^x0:O$/;\"\tm\tlanguage:knownz\texported:\nP\tinput.unknownx\t/^x1:P$/;\"\tm\tlanguage:knownz\tlen:1\n# output: xref\nfoo unknownx / owner:,len:,lenplus:,exported:-,stb: / public (n, m)\nbar unknownx / owner:,len:,lenplus:,exported:-,stb: / protected (n)\nbaz unknownx / owner:,len:,lenplus:,exported:-,stb: / private (n,...)\nstrset knownz / owner:iamowner,len:,lenplus:,exported:-,stb: / \nsetsetempty knownz / owner:,len:,lenplus:,exported:-,stb: / \nnotset knownz / owner:,len:,lenplus:,exported:-,stb: / \ntagme2 knownz / owner:iamowner2,len:,lenplus:,exported:-,stb: / \ntagme-z knownz / owner:iamowner-z,len:10,lenplus:11,exported:-,stb: / \na knownz / owner:,len:,lenplus:,exported:exported,stb: / \nb knownz / owner:,len:,lenplus:,exported:-,stb: / \n9_exported knownz / owner:,len:,lenplus:,exported:-,stb: / \no knownz / owner:,len:,lenplus:,exported:-,stb: / \np knownz / owner:,len:,lenplus:,exported:-,stb:- / \nq knownz / owner:,len:,lenplus:,exported:-,stb:something string / \nO knownz / owner:,len:,lenplus:,exported:exported,stb: / \nP knownz / owner:,len:1,lenplus:,exported:-,stb: / \n"
  },
  {
    "path": "Tmain/parser-specific-fields-for-foreign-lang.d/unknownx.ctags",
    "content": "--langdef=unknownx{_foreignLanguage=knownz}\n--kinddef-unknownx=f,func,functions\n--map-unknownx=+.unknownx\n\n--_fielddef-unknownx=protection,protections\n--_fielddef-unknownx=signature,signatures\n\n--_prelude-unknownx={{\n   /exported false def\n}}\n\n--regex-unknownx=/^((public|protected|private) +)?func ([^\\(]+)\\((.*)\\)/\\3/f/{_field=protection:\\1}{_field=signature:(\\4)}\n--regex-unknownx=/^STR:([a-z]+)@([a-z]+)/\\1/m/{_language=knownz}{_field=owner:\\2}\n--regex-unknownx=/^STR:([a-z]+)@$/\\1/m/{_language=knownz}{_field=owner:}\n--regex-unknownx=/^STR:([a-z]+)$/\\1/m/{_language=knownz}\n--regex-unknownx=/^Y:([a-z0-9]+)=([a-z0-9]+)/\\2/m/{_field=owner:\\1}{_language=knownz}\n--regex-unknownx=/^Z:([-a-z]+)@([-a-z]+)/\\1/m/{_language=knownz}{{\n    . \\2 knownz.owner:\n    . :knownz.owner {\n        . exch length knownz.len:\n    } if\n    . :knownz.len {\n        1 add\n        . exch knownz.lenplus:\n    } if\n}}\n\n--regex-unknownx=/^eset:([-a-z]+)/\\1/m/{_language=knownz}{{\n    /exported . def\n    . true knownz.exported:\n}}\n\n--regex-unknownx=/^enoset:([-a-z]+)/\\1/m/{_language=knownz}{{\n    . false knownz.exported:\n    exported :knownz.exported and {\n       mark exported 0 string cvs (_exported) _buildstring\n       /knownz\n       /mark\n       1@ _foreigntag _commit pop\n    } if\n}}\n\n--regex-unknownx=/^stb:([a-z])$/\\1/m/{_language=knownz}{{\n    . :knownz.stb {\n       ==\n    } {\n       /not-set ==\n    } ifelse\n}}\n--regex-unknownx=/^stb:([a-z])-$/\\1/m/{_language=knownz}{_field=stb:}{{\n    . :knownz.stb {\n       ==\n    } {\n       /not-set ==\n    } ifelse\n}}\n--regex-unknownx=/^stb:([a-z])\\.(.*)$/\\1/m/{_language=knownz}{_field=stb:\\2}{{\n    . :knownz.stb {\n       ==\n    } {\n       /not-set ==\n    } ifelse\n}}\n\n--regex-unknownx=/^x0:([a-zA-Z])$/\\1/m/{_language=knownz}{_field=exported:alpha}{{\n    (# Setting a string to a bool field) =\n    . :knownz.exported pstack clear\n}}\n\n# Setting string to a int field\n--regex-unknownx=/^x1:([a-zA-Z])$/\\1/m/{_language=knownz}{_field=len:alpha}{{\n    (# Setting a string to a int field) =\n    . :knownz.len pstack clear\n}}\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-datatype.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-datatype.d/input.testlang",
    "content": "str:s0\nstr:s1\nstr:s2\n\nint:i0\nint:i1\nint:i2\nint:i3\nint:i4\n\nbool:b0\nbool:b1\nbool:b2\n\nstrbool:sb0\nstrbool:sb1\nstrbool:sb2\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-datatype.d/run.sh",
    "content": "# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --options=testlang.ctags -o - \\\n\t\t --output-format=u-ctags \\\n\t\t input.testlang\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-datatype.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/parser-specific-fields-with-datatype.d/stdout-expected.txt",
    "content": "s0\tinput.testlang\t/^str:s0$/;\"\to\tstr:string\ns1\tinput.testlang\t/^str:s1$/;\"\to\tstr:\ns2\tinput.testlang\t/^str:s2$/;\"\to\ni0\tinput.testlang\t/^int:i0$/;\"\to\tint:10\ni1\tinput.testlang\t/^int:i1$/;\"\to\tint:-1\ni2\tinput.testlang\t/^int:i2$/;\"\to\tint:1\ni3\tinput.testlang\t/^int:i3$/;\"\to\tint:0\ni4\tinput.testlang\t/^int:i4$/;\"\to\nb0\tinput.testlang\t/^bool:b0$/;\"\to\tbool:\nb1\tinput.testlang\t/^bool:b1$/;\"\to\tbool:\nb2\tinput.testlang\t/^bool:b2$/;\"\to\nsb0\tinput.testlang\t/^strbool:sb0$/;\"\to\tstrbool:abc\nsb1\tinput.testlang\t/^strbool:sb1$/;\"\to\tstrbool:\nsb2\tinput.testlang\t/^strbool:sb2$/;\"\to\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-datatype.d/testlang.ctags",
    "content": "--sort=no\n\n--langdef=Testlang\n--map-Testlang=+.testlang\n\n--kinddef-Testlang=o,object,objects\n\n--_fielddef-Testlang=str,String{datatype=str}\n--fields-Testlang=+{str}\n--_fielddef-Testlang=int,Integer{datatype=int}\n--fields-Testlang=+{int}\n--_fielddef-Testlang=bool,Boolean{datatype=bool}\n--fields-Testlang=+{bool}\n--_fielddef-Testlang=strbool,String or Boolean{datatype=str+bool}\n--fields-Testlang=+{strbool}\n\n--regex-Testlang=/^str:(s0)/\\1/o/{_field=str:string}\n--regex-Testlang=/^str:(s1)/\\1/o/{_field=str:}\n--regex-Testlang=/^str:(s2)/\\1/o/\n\n--regex-Testlang=/^int:(i0)/\\1/o/{_field=int:10}\n--regex-Testlang=/^int:(i1)/\\1/o/{_field=int:-1}\n--regex-Testlang=/^int:(i2)/\\1/o/{_field=int:abc}\n--regex-Testlang=/^int:(i3)/\\1/o/{_field=int:}\n--regex-Testlang=/^int:(i4)/\\1/o/\n\n--regex-Testlang=/^bool:(b0)/\\1/o/{_field=bool:abc}\n--regex-Testlang=/^bool:(b1)/\\1/o/{_field=bool:}\n--regex-Testlang=/^bool:(b2)/\\1/o/\n\n--regex-Testlang=/^strbool:(sb0)/\\1/o/{_field=strbool:abc}\n--regex-Testlang=/^strbool:(sb1)/\\1/o/{_field=strbool:}\n--regex-Testlang=/^strbool:(sb2)/\\1/o/\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-scripts.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-scripts.d/input.testlang",
    "content": "string => string\nstring => integer\nstring => bool\nstring => strbool\nint => string\nint => integer\nint => bool\nint => strbool\ntrue => string\ntrue => integer\ntrue => bool\ntrue => strbool\nfalse => string\nfalse => integer\nfalse => bool\nfalse => strbool\narray => string\narray => integer\narray => bool\narray => strbool\n\nempty string => string\nempty string => integer\nempty string => bool\nempty string => strbool\n\nint =>\nbool =>\nstrbool =>\n\ntrue => bool, false => true\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-scripts.d/run.sh",
    "content": "# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\nCMDLINE=\"$CTAGS --quiet --options=NONE --options=./testlang.ctags\"\n\n. ../utils.sh\n\nis_feature_available \"$1\" json\n\necho '### ctags' &&\n${CMDLINE} \\\n\t\t --param-Testlang.dp=true \\\n\t\t -o - input.testlang &&\n\necho '### xref' &&\n${CMDLINE} \\\n\t\t --_xformat=\"%-16N :: str:%{Testlang.str} int:%{Testlang.int} bool:%{Testlang.bool} strbool:%{Testlang.strbool}\" \\\n\t\t -x input.testlang &&\n\necho '### json' &&\n${CMDLINE} \\\n\t\t --output-format=json -o - input.testlang &&\n\necho '### etags' &&\n${CMDLINE} \\\n\t\t --output-format=etags -o - input.testlang &&\n:\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-scripts.d/stderr-expected.txt",
    "content": "string => string...OK stringtype/(str)\nstring => integer...XERR typecheck\nstring => bool...XERR typecheck\nstring => strbool...OK stringtype/(str)\nint => string...XERR typecheck\nint => integer...OK integertype/17\nint => bool...XERR typecheck\nint => strbool...XERR typecheck\ntrue => string...XERR typecheck\ntrue => integer...XERR typecheck\ntrue => bool...OK booleantype/true\ntrue => strbool...XERR typecheck\nfalse => string...XERR typecheck\nfalse => integer...XERR typecheck\nfalse => bool...OK /noval\nfalse => strbool...OK booleantype/false\narray => string...XERR typecheck\narray => integer...XERR typecheck\narray => bool...XERR typecheck\narray => strbool...XERR typecheck\nempty string => string...OK stringtype/()\nempty string => integer...XERR typecheck\nempty string => bool...XERR typecheck\nempty string => strbool...OK booleantype/false\nint =>...OK /noval\nbool =>...OK /noval\nstrbool =>...OK /noval\ntrue => bool, false => true...XERR fieldreset\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-scripts.d/stdout-expected.txt",
    "content": "### ctags\nstring => string\tinput.testlang\t/^string => string$/;\"\to\tstr:str\nstring => integer\tinput.testlang\t/^string => integer$/;\"\to\nstring => bool\tinput.testlang\t/^string => bool$/;\"\to\nstring => strbool\tinput.testlang\t/^string => strbool$/;\"\to\tstrbool:str\nint => string\tinput.testlang\t/^int => string$/;\"\to\nint => integer\tinput.testlang\t/^int => integer$/;\"\to\tint:17\nint => bool\tinput.testlang\t/^int => bool$/;\"\to\nint => strbool\tinput.testlang\t/^int => strbool$/;\"\to\ntrue => string\tinput.testlang\t/^true => string$/;\"\to\ntrue => integer\tinput.testlang\t/^true => integer$/;\"\to\ntrue => bool\tinput.testlang\t/^true => bool$/;\"\to\tbool:\ntrue => strbool\tinput.testlang\t/^true => strbool$/;\"\to\nfalse => string\tinput.testlang\t/^false => string$/;\"\to\nfalse => integer\tinput.testlang\t/^false => integer$/;\"\to\nfalse => bool\tinput.testlang\t/^false => bool$/;\"\to\nfalse => strbool\tinput.testlang\t/^false => strbool$/;\"\to\tstrbool:\narray => string\tinput.testlang\t/^array => string$/;\"\to\narray => integer\tinput.testlang\t/^array => integer$/;\"\to\narray => bool\tinput.testlang\t/^array => bool$/;\"\to\narray => strbool\tinput.testlang\t/^array => strbool$/;\"\to\nempty string => string\tinput.testlang\t/^empty string => string$/;\"\to\tstr:\nempty string => integer\tinput.testlang\t/^empty string => integer$/;\"\to\nempty string => bool\tinput.testlang\t/^empty string => bool$/;\"\to\nempty string => strbool\tinput.testlang\t/^empty string => strbool$/;\"\to\tstrbool:\nint =>\tinput.testlang\t/^int =>$/;\"\to\nbool =>\tinput.testlang\t/^bool =>$/;\"\to\nstrbool =>\tinput.testlang\t/^strbool =>$/;\"\to\ntrue => bool, false => true\tinput.testlang\t/^true => bool, false => true$/;\"\to\tbool:\n### xref\nstring => string :: str:str int: bool:- strbool:\nstring => integer :: str: int: bool:- strbool:\nstring => bool   :: str: int: bool:- strbool:\nstring => strbool :: str: int: bool:- strbool:str\nint => string    :: str: int: bool:- strbool:\nint => integer   :: str: int:17 bool:- strbool:\nint => bool      :: str: int: bool:- strbool:\nint => strbool   :: str: int: bool:- strbool:\ntrue => string   :: str: int: bool:- strbool:\ntrue => integer  :: str: int: bool:- strbool:\ntrue => bool     :: str: int: bool:bool strbool:\ntrue => strbool  :: str: int: bool:- strbool:\nfalse => string  :: str: int: bool:- strbool:\nfalse => integer :: str: int: bool:- strbool:\nfalse => bool    :: str: int: bool:- strbool:\nfalse => strbool :: str: int: bool:- strbool:-\narray => string  :: str: int: bool:- strbool:\narray => integer :: str: int: bool:- strbool:\narray => bool    :: str: int: bool:- strbool:\narray => strbool :: str: int: bool:- strbool:\nempty string => string :: str: int: bool:- strbool:\nempty string => integer :: str: int: bool:- strbool:\nempty string => bool :: str: int: bool:- strbool:\nempty string => strbool :: str: int: bool:- strbool:-\nint =>           :: str: int: bool:- strbool:\nbool =>          :: str: int: bool:- strbool:\nstrbool =>       :: str: int: bool:- strbool:\ntrue => bool, false => true :: str: int: bool:bool strbool:\n### json\n{\"_type\": \"tag\", \"name\": \"string => string\", \"path\": \"input.testlang\", \"pattern\": \"/^string => string$/\", \"kind\": \"object\", \"str\": \"str\"}\n{\"_type\": \"tag\", \"name\": \"string => integer\", \"path\": \"input.testlang\", \"pattern\": \"/^string => integer$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"string => bool\", \"path\": \"input.testlang\", \"pattern\": \"/^string => bool$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"string => strbool\", \"path\": \"input.testlang\", \"pattern\": \"/^string => strbool$/\", \"kind\": \"object\", \"strbool\": \"str\"}\n{\"_type\": \"tag\", \"name\": \"int => string\", \"path\": \"input.testlang\", \"pattern\": \"/^int => string$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"int => integer\", \"path\": \"input.testlang\", \"pattern\": \"/^int => integer$/\", \"kind\": \"object\", \"int\": 17}\n{\"_type\": \"tag\", \"name\": \"int => bool\", \"path\": \"input.testlang\", \"pattern\": \"/^int => bool$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"int => strbool\", \"path\": \"input.testlang\", \"pattern\": \"/^int => strbool$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"true => string\", \"path\": \"input.testlang\", \"pattern\": \"/^true => string$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"true => integer\", \"path\": \"input.testlang\", \"pattern\": \"/^true => integer$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"true => bool\", \"path\": \"input.testlang\", \"pattern\": \"/^true => bool$/\", \"kind\": \"object\", \"bool\": true}\n{\"_type\": \"tag\", \"name\": \"true => strbool\", \"path\": \"input.testlang\", \"pattern\": \"/^true => strbool$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"false => string\", \"path\": \"input.testlang\", \"pattern\": \"/^false => string$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"false => integer\", \"path\": \"input.testlang\", \"pattern\": \"/^false => integer$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"false => bool\", \"path\": \"input.testlang\", \"pattern\": \"/^false => bool$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"false => strbool\", \"path\": \"input.testlang\", \"pattern\": \"/^false => strbool$/\", \"kind\": \"object\", \"strbool\": false}\n{\"_type\": \"tag\", \"name\": \"array => string\", \"path\": \"input.testlang\", \"pattern\": \"/^array => string$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"array => integer\", \"path\": \"input.testlang\", \"pattern\": \"/^array => integer$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"array => bool\", \"path\": \"input.testlang\", \"pattern\": \"/^array => bool$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"array => strbool\", \"path\": \"input.testlang\", \"pattern\": \"/^array => strbool$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"empty string => string\", \"path\": \"input.testlang\", \"pattern\": \"/^empty string => string$/\", \"kind\": \"object\", \"str\": \"\"}\n{\"_type\": \"tag\", \"name\": \"empty string => integer\", \"path\": \"input.testlang\", \"pattern\": \"/^empty string => integer$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"empty string => bool\", \"path\": \"input.testlang\", \"pattern\": \"/^empty string => bool$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"empty string => strbool\", \"path\": \"input.testlang\", \"pattern\": \"/^empty string => strbool$/\", \"kind\": \"object\", \"strbool\": false}\n{\"_type\": \"tag\", \"name\": \"int =>\", \"path\": \"input.testlang\", \"pattern\": \"/^int =>$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"bool =>\", \"path\": \"input.testlang\", \"pattern\": \"/^bool =>$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"strbool =>\", \"path\": \"input.testlang\", \"pattern\": \"/^strbool =>$/\", \"kind\": \"object\"}\n{\"_type\": \"tag\", \"name\": \"true => bool, false => true\", \"path\": \"input.testlang\", \"pattern\": \"/^true => bool, false => true$/\", \"kind\": \"object\", \"bool\": true}\n### etags\n\f\ninput.testlang,1095\nstring => stringstring => string\u00011,0\nstring => integerstring => integer\u00012,17\nstring => boolstring => bool\u00013,35\nstring => strboolstring => strbool\u00014,50\nint => stringint => string\u00015,68\nint => integerint => integer\u00016,82\nint => boolint => bool\u00017,97\nint => strboolint => strbool\u00018,109\ntrue => stringtrue => string\u00019,124\ntrue => integertrue => integer\u000110,139\ntrue => booltrue => bool\u000111,155\ntrue => strbooltrue => strbool\u000112,168\nfalse => stringfalse => string\u000113,184\nfalse => integerfalse => integer\u000114,200\nfalse => boolfalse => bool\u000115,217\nfalse => strboolfalse => strbool\u000116,231\narray => stringarray => string\u000117,248\narray => integerarray => integer\u000118,264\narray => boolarray => bool\u000119,281\narray => strboolarray => strbool\u000120,295\nempty string => stringempty string => string\u000122,313\nempty string => integerempty string => integer\u000123,336\nempty string => boolempty string => bool\u000124,360\nempty string => strboolempty string => strbool\u000125,381\nint =>int =>\u000127,406\nbool =>bool =>\u000128,413\nstrbool =>strbool =>\u000129,421\ntrue => bool, false => truetrue => bool, false => true\u000131,433\n"
  },
  {
    "path": "Tmain/parser-specific-fields-with-scripts.d/testlang.ctags",
    "content": "--sort=no\n\n--langdef=Testlang\n--map-Testlang=+.testlang\n\n--_paramdef-Testlang=dp,enable debug printing\n\n--kinddef-Testlang=o,object,objects\n\n--_fielddef-Testlang=str,String{datatype=str}\n--fields-Testlang=+{str}\n--_fielddef-Testlang=int,Integer{datatype=int}\n--fields-Testlang=+{int}\n--_fielddef-Testlang=bool,Boolean{datatype=bool}\n--fields-Testlang=+{bool}\n--_fielddef-Testlang=strbool,String or Boolean{datatype=str+bool}\n--fields-Testlang=+{strbool}\n\n--_prelude-Testlang={{\n   /dp _param {\n      pop\n      /q {=} def\n      /qq {==} def\n      /qa {=+} def\n      /qqa {==+} def\n   } {\n      /q {pop} def\n      /qq {pop} def\n      /qa {pop} def\n      /qqa {pop} def\n   } ifelse\n\n   /T { mark \\1 (...) _buildstring qa } def\n   /pval {\n      dup type qqa (/) qa qq\n   } def\n   /Tstr { T . exch { Testlang.str: }\n      stopped { clear (XERR ) qa _errorname q }\n              { (OK ) qa . :Testlang.str {pval}  {/noval qq} ifelse} ifelse\n   } def\n   /Tint { T . exch { Testlang.int: }\n      stopped { clear (XERR ) qa _errorname q }\n              { (OK ) qa . :Testlang.int {pval}  {/noval qq} ifelse } ifelse\n   } def\n   /Tbool { T . exch { Testlang.bool: }\n      stopped { clear (XERR ) qa _errorname q }\n              { (OK ) qa . :Testlang.bool {pval} {/noval qq} ifelse } ifelse\n   } def\n   /Tstrbool { T . exch { Testlang.strbool: }\n      stopped { clear (XERR ) qa _errorname q }\n              { (OK ) qa . :Testlang.strbool {pval} {/noval qq} ifelse } ifelse\n   } def\n   /verifygetter {\n      stopped { clear (XERR ) qa _errorname q }\n              { (OK ) qa {pval} {/noval qq} ifelse } ifelse\n   } def\n}}\n\n--regex-Testlang=/^(string => string)$/\\1/o/{{\n   (str) Tstr\n}}\n\n--regex-Testlang=/^(string => integer)$/\\1/o/{{\n   (str) Tint\n}}\n\n--regex-Testlang=/^(string => bool)$/\\1/o/{{\n   (str) Tbool\n}}\n\n--regex-Testlang=/^(string => strbool)$/\\1/o/{{\n   (str) Tstrbool\n}}\n\n--regex-Testlang=/^(int => string)$/\\1/o/{{\n   17 Tstr\n}}\n\n--regex-Testlang=/^(int => integer)$/\\1/o/{{\n   17 Tint\n}}\n\n--regex-Testlang=/^(int => bool)$/\\1/o/{{\n   17 Tbool\n}}\n\n--regex-Testlang=/^(int => strbool)$/\\1/o/{{\n   17 Tstrbool\n}}\n\n--regex-Testlang=/^(true => string)$/\\1/o/{{\n   true Tstr\n}}\n\n--regex-Testlang=/^(true => integer)$/\\1/o/{{\n   true Tint\n}}\n\n--regex-Testlang=/^(true => bool)$/\\1/o/{{\n   true Tbool\n}}\n\n--regex-Testlang=/^(true => strbool)$/\\1/o/{{\n   true Tstrbool\n}}\n\n--regex-Testlang=/^(false => string)$/\\1/o/{{\n   false Tstr\n}}\n\n--regex-Testlang=/^(false => integer)$/\\1/o/{{\n   false Tint\n}}\n\n--regex-Testlang=/^(false => bool)$/\\1/o/{{\n   false Tbool\n}}\n\n--regex-Testlang=/^(false => strbool)$/\\1/o/{{\n   false Tstrbool\n}}\n\n--regex-Testlang=/^(array => string)$/\\1/o/{{\n   [ 1 2 3 ] Tstr\n}}\n\n--regex-Testlang=/^(array => integer)$/\\1/o/{{\n   [ 1 2 3 ] Tint\n}}\n\n--regex-Testlang=/^(array => bool)$/\\1/o/{{\n   [ 1 2 3 ] Tbool\n}}\n\n--regex-Testlang=/^(array => strbool)$/\\1/o/{{\n   [ 1 2 3 ] Tstrbool\n}}\n\n--regex-Testlang=/^(empty string => string)$/\\1/o/{{\n   () Tstr\n}}\n\n--regex-Testlang=/^(empty string => integer)$/\\1/o/{{\n   () Tint\n}}\n\n--regex-Testlang=/^(empty string => bool)$/\\1/o/{{\n   () Tbool\n}}\n\n--regex-Testlang=/^(empty string => strbool)$/\\1/o/{{\n   () Tstrbool\n}}\n\n--regex-Testlang=/^(string =>)$/\\1/o/{{\n   { T . :Testlang.str } verifygetter\n}}\n\n--regex-Testlang=/^(int =>)$/\\1/o/{{\n   { T . :Testlang.int } verifygetter\n}}\n\n--regex-Testlang=/^(bool =>)$/\\1/o/{{\n   { T . :Testlang.bool } verifygetter\n}}\n\n--regex-Testlang=/^(strbool =>)$/\\1/o/{{\n   { T . :Testlang.strbool } verifygetter\n}}\n\n--regex-Testlang=/^(true => bool, false => true)$/\\1/o/{{\n   T\n   . true Testlang.bool:\n   { . false Testlang.bool: } stopped { clear (XERR ) qa _errorname q } if\n}}"
  },
  {
    "path": "Tmain/parser-specific-fields.d/input.unknownx",
    "content": "public func foo(n, m);\nprotected func bar(n);\nprivate func baz(n,...);\n"
  },
  {
    "path": "Tmain/parser-specific-fields.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nCTAGS=$1\n\nV=\n# V=valgrind\n\necho '#' disabling fields\n${V} ${CTAGS} --options=NONE --options=./unknownx.ctags -o - input.unknownx\n\necho '#' enabling signature only\n${V} ${CTAGS} --options=NONE --options=./unknownx.ctags --fields-unknownx=+'{signature}' -o - input.unknownx\n\necho '#' enabling protection only\n${V} ${CTAGS} --options=NONE --options=./unknownx.ctags --fields-unknownx=+'{protection}' -o - input.unknownx\n\necho '#' enabling both signature and protection\n${V} ${CTAGS} --options=NONE --options=./unknownx.ctags --fields-unknownx=+'{protection}{signature}' -o - input.unknownx\n"
  },
  {
    "path": "Tmain/parser-specific-fields.d/stderr-expected.txt",
    "content": "ctags: Notice: No options will be read from files or environment\nctags: Notice: No options will be read from files or environment\nctags: Notice: No options will be read from files or environment\nctags: Notice: No options will be read from files or environment\n"
  },
  {
    "path": "Tmain/parser-specific-fields.d/stdout-expected.txt",
    "content": "# disabling fields\nbar\tinput.unknownx\t/^protected func bar(n);$/;\"\tf\nbaz\tinput.unknownx\t/^private func baz(n,...);$/;\"\tf\nfoo\tinput.unknownx\t/^public func foo(n, m);$/;\"\tf\n# enabling signature only\nbar\tinput.unknownx\t/^protected func bar(n);$/;\"\tf\tsignature:(n)\nbaz\tinput.unknownx\t/^private func baz(n,...);$/;\"\tf\tsignature:(n,...)\nfoo\tinput.unknownx\t/^public func foo(n, m);$/;\"\tf\tsignature:(n, m)\n# enabling protection only\nbar\tinput.unknownx\t/^protected func bar(n);$/;\"\tf\tprotection:protected \nbaz\tinput.unknownx\t/^private func baz(n,...);$/;\"\tf\tprotection:private \nfoo\tinput.unknownx\t/^public func foo(n, m);$/;\"\tf\tprotection:public \n# enabling both signature and protection\nbar\tinput.unknownx\t/^protected func bar(n);$/;\"\tf\tprotection:protected \tsignature:(n)\nbaz\tinput.unknownx\t/^private func baz(n,...);$/;\"\tf\tprotection:private \tsignature:(n,...)\nfoo\tinput.unknownx\t/^public func foo(n, m);$/;\"\tf\tprotection:public \tsignature:(n, m)\n"
  },
  {
    "path": "Tmain/parser-specific-fields.d/unknownx.ctags",
    "content": "--langdef=unknownx\n--kinddef-unknownx=f,func,functions\n--map-unknownx=+.unknownx\n\n--_fielddef-unknownx=protection,protections\n--_fielddef-unknownx=signature,signatures\n\n--regex-unknownx=/^((public|protected|private) +)?func ([^\\(]+)\\((.*)\\)/\\3/f/{_field=protection:\\1}{_field=signature:(\\4)}\n\n"
  },
  {
    "path": "Tmain/pattern-length-limit.d/input-iso-8859-1.py",
    "content": "# this is made to pass the `(c & 0xC0) == 0x80` UTF-8 sub-byte check to make\n# sure we have a working hard limit in case of malicious input.\na=''\n"
  },
  {
    "path": "Tmain/pattern-length-limit.d/input-utf8.py",
    "content": "a='éàçè'\n"
  },
  {
    "path": "Tmain/pattern-length-limit.d/input.java",
    "content": "import com.example.Bar;\nimport java.util.logging.Logger;\npublic class Foo extends Bar {static Logger a = Logger.getLogger(Foo.class.getName()); static Logger b = Logger.getLogger(Foo.class.getName());}\n"
  },
  {
    "path": "Tmain/pattern-length-limit.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t --kinds-java=f  ./input.java\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t --pattern-length-limit=10 \\\n\t --kinds-java=f  ./input.java\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t --pattern-length-limit=0 \\\n\t --kinds-java=f  ./input.java\n\nfor etags in '' '-e'; do\n\techo \"--- multi-byte handling\" $(test -n \"$etags\" && echo \"(etags)\")\n\n\t# as the 7th byte is an inner byte, cutting at 6 and 7 should yield the same result\n\t${CTAGS} --quiet --options=NONE $etags -o - \\\n\t\t --pattern-length-limit=6 \\\n\t\t --kinds-python=v  ./input-utf8.py\n\t${CTAGS} --quiet --options=NONE $etags -o - \\\n\t\t --pattern-length-limit=7 \\\n\t\t --kinds-python=v  ./input-utf8.py\n\n\t${CTAGS} --quiet --options=NONE $etags -o - \\\n\t\t --pattern-length-limit=4 \\\n\t\t --kinds-python=v  ./input-iso-8859-1.py\ndone\n\nexit $?\n"
  },
  {
    "path": "Tmain/pattern-length-limit.d/stdout-expected.txt",
    "content": "a\t./input.java\t/^public class Foo extends Bar {static Logger a = Logger.getLogger(Foo.class.getName()); static Lo/;\"\tf\nb\t./input.java\t/^public class Foo extends Bar {static Logger a = Logger.getLogger(Foo.class.getName()); static Lo/;\"\tf\na\t./input.java\t/^public cla/;\"\tf\nb\t./input.java\t/^public cla/;\"\tf\na\t./input.java\t/^public class Foo extends Bar {static Logger a = Logger.getLogger(Foo.class.getName()); static Logger b = Logger.getLogger(Foo.class.getName());}$/;\"\tf\nb\t./input.java\t/^public class Foo extends Bar {static Logger a = Logger.getLogger(Foo.class.getName()); static Logger b = Logger.getLogger(Foo.class.getName());}$/;\"\tf\n--- multi-byte handling\na\t./input-utf8.py\t/^a='éà/;\"\tv\na\t./input-utf8.py\t/^a='éà/;\"\tv\na\t./input-iso-8859-1.py\t/^a='/;\"\tv\n--- multi-byte handling (etags)\n\f\ninput-utf8.py,14\na='éàa\u00011,0\n\f\ninput-utf8.py,14\na='éàa\u00011,0\n\f\ninput-iso-8859-1.py,16\na='a\u00013,141\n"
  },
  {
    "path": "Tmain/pretend-option.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n\"${CTAGS}\" --quiet --options=NONE --with-list-header=no --_pretend-Lisp=C --list-kinds=C\n"
  },
  {
    "path": "Tmain/pretend-option.d/stdout-expected.txt",
    "content": "Y  unknown type of definitions\nf  functions\nv  variables\nm  macros\nc  constants\nt  types\nC  classes\ns  structs\nM  methods\nG  generics\np  parameters\n"
  },
  {
    "path": "Tmain/ptag-dont-emit-to-stdout-by-default.d/input.c",
    "content": "int x;\n"
  },
  {
    "path": "Tmain/ptag-dont-emit-to-stdout-by-default.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --pseudo-tags='*' -o - input.c\n"
  },
  {
    "path": "Tmain/ptag-dont-emit-to-stdout-by-default.d/stdout-expected.txt",
    "content": "x\tinput.c\t/^int x;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/ptag-emits-even-when-rewinding.d/README",
    "content": "The original bug (#3932) was reproduced only when\n--disable-external-sort is set when building ctags.\n"
  },
  {
    "path": "Tmain/ptag-emits-even-when-rewinding.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/ptag-emits-even-when-rewinding.d/input.cpp",
    "content": "private\n"
  },
  {
    "path": "Tmain/ptag-emits-even-when-rewinding.d/run.sh",
    "content": "# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n# exit_if_win32 $CTAGS\n\nO=\"--quiet --options=NONE --extras=+p\"\n\ncount_ptags=$(${CTAGS} $O -o - input.cpp | grep -F '!_TAG_KIND_DESCRIPTION!C++' | wc -l)\ncount_list=$(${CTAGS} $O --with-list-header=no --list-kinds-full=C++ | grep '.[ \\t]*[^ \\t]*yes' | wc -l)\n\nif ! test \"$count_ptags\" -eq \"$count_list\"; then\n\techo count_ptags: $count_ptags\n\techo count_list: $count_list\n\t${CTAGS} $O -o - input.cpp\n\texit 1\nfi\nexit 0\n"
  },
  {
    "path": "Tmain/ptag-emits-even-when-rewinding.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/ptag-emits-even-when-rewinding.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/ptag-extra-desc.d/input.robot",
    "content": "# EMPTY\n"
  },
  {
    "path": "Tmain/ptag-extra-desc.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=\"--quiet --options=NONE \"\n\n${CTAGS} $O \\\n\t\t --extras=p --pseudo-tags=TAG_EXTRA_DESCRIPTION \\\n\t\t --extras=+g \\\n\t\t --extras-Robot='{whitespaceSwapped}' \\\n\t\t -o - \\\n\t\t input.robot\n\n${CTAGS} $O \\\n\t\t --extras=p --pseudo-tags=TAG_EXTRA_DESCRIPTION \\\n\t\t --extras-Robot=-'{whitespaceSwapped}' \\\n\t\t -o - \\\n\t\t input.robot\n"
  },
  {
    "path": "Tmain/ptag-extra-desc.d/stdout-expected.txt",
    "content": "!_TAG_EXTRA_DESCRIPTION\tguest\t/Include tags generated by guest parsers/\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_EXTRA_DESCRIPTION!Robot\twhitespaceSwapped\t/Include tags swapping whitespace and underscore chars/\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n"
  },
  {
    "path": "Tmain/ptag-field-sec.d/input.c",
    "content": "/* EMPTY */\n"
  },
  {
    "path": "Tmain/ptag-field-sec.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=\"--quiet --options=NONE \"\n\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags=TAG_FIELD_DESCRIPTION \\\n\t\t --fields=le \\\n\t\t --fields-C='{macrodef}' \\\n\t\t -o - \\\n\t\t input.c\n"
  },
  {
    "path": "Tmain/ptag-field-sec.d/stdout-expected.txt",
    "content": "!_TAG_FIELD_DESCRIPTION\tend\t/end lines of various items/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_FIELD_DESCRIPTION\tlanguage\t/Language of input file containing tag/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_FIELD_DESCRIPTION!C\tmacrodef\t/macro definition/\n"
  },
  {
    "path": "Tmain/ptag-in-optlib-parser.d/input.foo",
    "content": "# EMPTY\n"
  },
  {
    "path": "Tmain/ptag-in-optlib-parser.d/input.sh",
    "content": ""
  },
  {
    "path": "Tmain/ptag-in-optlib-parser.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\n{\n    echo '# BUILTIN'\n    ${CTAGS} --quiet --options=NONE -o - --extras=p --pseudo-tags='*' \\\n\t\t --pseudo-tags=-TAG_PROC_CWD \\\n\t\t --fields='-{typeref}{file}' \\\n\t     input.sh\n\n    echo '# REGEX'\n    ${CTAGS} --quiet --options=NONE -o - --extras=p --pseudo-tags='*' \\\n\t\t --pseudo-tags=-TAG_PROC_CWD \\\n\t     --langdef=foo --langmap=foo:+.foo \\\n\t\t --_fielddef-foo='field,field example' \\\n\t\t --fields='-{typeref}{file}' \\\n\t\t --fields-foo='{field}' \\\n\t\t --_extradef-foo='extra,extra example' \\\n\t\t --extras-foo='{extra}' \\\n\t     --regex-foo='/abc/\\1/k,kind,kinds/' input.foo\n} | grep -v VERSION\n"
  },
  {
    "path": "Tmain/ptag-in-optlib-parser.d/stdout-expected.txt",
    "content": "# BUILTIN\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_FIELD_DESCRIPTION\tepoch\t/the last modified time of the input file (only for F\\/file kind tag)/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!Sh\ta,alias\t/aliases/\n!_TAG_KIND_DESCRIPTION!Sh\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Sh\th,heredoc\t/label for here document/\n!_TAG_KIND_DESCRIPTION!Sh\ts,script\t/script files/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_ROLE_DESCRIPTION!Sh!heredoc\tendmarker\t/end marker/\n!_TAG_ROLE_DESCRIPTION!Sh!script\tloaded\t/loaded/\n# REGEX\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_EXTRA_DESCRIPTION!foo\textra\t/extra example/\n!_TAG_FIELD_DESCRIPTION\tepoch\t/the last modified time of the input file (only for F\\/file kind tag)/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_FIELD_DESCRIPTION!foo\tfield\t/field example/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!foo\tk,kind\t/kinds/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n"
  },
  {
    "path": "Tmain/ptag-kind-desc.d/input.c",
    "content": "/* EMPTY */\n"
  },
  {
    "path": "Tmain/ptag-kind-desc.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=\"--quiet --options=NONE \"\n\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags=TAG_KIND_DESCRIPTION \\\n\t\t --kinds-C=df \\\n\t\t -o - \\\n\t\t input.c\n"
  },
  {
    "path": "Tmain/ptag-kind-desc.d/stdout-expected.txt",
    "content": "!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n"
  },
  {
    "path": "Tmain/ptag-kind-sep.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/ptag-kind-sep.d/input.php",
    "content": "NOTHING HERE\n"
  },
  {
    "path": "Tmain/ptag-kind-sep.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t --extras=p --kinds-all= \\\n\t --pseudo-tags=TAG_PROGRAM_NAME \\\n\t input.php\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t --extras=+p --kinds-all= \\\n\t --pseudo-tags=+TAG_KIND_SEPARATOR \\\n\t --pseudo-tags=-TAG_PROGRAM_VERSION \\\n\t --pseudo-tags=-TAG_PROC_CWD \\\n\t --pseudo-tags=-TAG_KIND_DESCRIPTION \\\n\t --pseudo-tags=-TAG_FIELD_DESCRIPTION \\\n\t --pseudo-tags=-TAG_EXTRA_DESCRIPTION \\\n\t --pseudo-tags=-TAG_ROLE_DESCRIPTION \\\n\t --pseudo-tags=-TAG_PARSER_VERSION \\\n\t --pseudo-tags=-TAG_OUTPUT_VERSION \\\n\t input.php\n"
  },
  {
    "path": "Tmain/ptag-kind-sep.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/ptag-kind-sep.d/stdout-expected.txt",
    "content": "!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_SEPARATOR!PHP\t::\t/*a/\n!_TAG_KIND_SEPARATOR!PHP\t::\t/*c/\n!_TAG_KIND_SEPARATOR!PHP\t::\t/*d/\n!_TAG_KIND_SEPARATOR!PHP\t::\t/*f/\n!_TAG_KIND_SEPARATOR!PHP\t::\t/*i/\n!_TAG_KIND_SEPARATOR!PHP\t::\t/*l/\n!_TAG_KIND_SEPARATOR!PHP\t::\t/*n/\n!_TAG_KIND_SEPARATOR!PHP\t::\t/*t/\n!_TAG_KIND_SEPARATOR!PHP\t::\t/*v/\n!_TAG_KIND_SEPARATOR!PHP\t\\\\\t/na/\n!_TAG_KIND_SEPARATOR!PHP\t\\\\\t/nc/\n!_TAG_KIND_SEPARATOR!PHP\t\\\\\t/nd/\n!_TAG_KIND_SEPARATOR!PHP\t\\\\\t/nf/\n!_TAG_KIND_SEPARATOR!PHP\t\\\\\t/ni/\n!_TAG_KIND_SEPARATOR!PHP\t\\\\\t/nl/\n!_TAG_KIND_SEPARATOR!PHP\t\\\\\t/nn/\n!_TAG_KIND_SEPARATOR!PHP\t\\\\\t/nt/\n!_TAG_KIND_SEPARATOR!PHP\t\\\\\t/nv/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n"
  },
  {
    "path": "Tmain/ptag-output-excmd.d/input.c",
    "content": "/* EMPTY */\n"
  },
  {
    "path": "Tmain/ptag-output-excmd.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nO=\"--quiet --options=NONE \"\n\nfor c in number pattern mixed combine; do\n\t${CTAGS} $O \\\n\t\t\t --excmd=$c \\\n\t\t\t --extras=+p --pseudo-tags=TAG_OUTPUT_EXCMD \\\n\t\t\t -o - \\\n\t\t\t input.c\ndone\n"
  },
  {
    "path": "Tmain/ptag-output-excmd.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/ptag-output-excmd.d/stdout-expected.txt",
    "content": "!_TAG_OUTPUT_EXCMD\tnumber\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_EXCMD\tpattern\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_EXCMD\tcombineV2\t/number, pattern, mixed, or combineV2/\n"
  },
  {
    "path": "Tmain/ptag-proc-cwd-including-tab.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\n#\n# This test case doesn't work well on Windows on CI/CD envornments we use.\n# We can make a directory having \\t in their name.\n# cd built-in command with the name works well.\n# pwd prints the directory including \\t as expected.\n# However, the input fields of TAG_PROC_CWD doesn't includ \\t\n# character; it is replaced with a strange byte sequence \"f0 09\".\n# How to test:\n#\n#   $ cd ctags\n#   $ make\n#   $ mkdir \"$(printf 'a\\tb')\"\n#   $ cd \"$(printf 'a\\tb')\"\n#   $ echo 'int x;' > input.c\n#   $ ../ctags --extras=+p -o - input.c | grep _TAG_PROC_CWD\n#\n# Temporary we disable this test case.\n#\nexit_if_win32 $CTAGS\n\nO=\"--quiet --options=NONE \"\n\n(\n\tpid=$$\n\tdir=\"$(printf 'ctags-%s\\t%s-tmain' $pid $pid)\"\n\tcd /\n\tif pwd=$(readlink /tmp); then\n\t\tcd \"${pwd}\"\n\telse\n\t\tcd /tmp\n\tfi\n\tpwd=$(pwd)\n\tmkdir \"$dir\"\n\tcd \"$dir\"\n\ttouch input2.c\n\tls\n\t${CTAGS} $O \\\n\t\t\t --extras=+p --pseudo-tags=TAG_PROC_CWD \\\n\t\t\t -o - \\\n\t\t\t input2.c | sed -e \"s/$pid//g\" | sed -e \"s|$pwd|/tmp|\" | sed -e \"s|[A-Z]:/.*/tmp|/tmp|\"\n\trm input2.c\n\tcd ..\n\trmdir \"$dir\"\n)\n"
  },
  {
    "path": "Tmain/ptag-proc-cwd-including-tab.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/ptag-proc-cwd-including-tab.d/stdout-expected.txt",
    "content": "input2.c\n!_TAG_PROC_CWD\t/tmp/ctags-\\t-tmain/\t//\n"
  },
  {
    "path": "Tmain/ptag-proc-cwd.d/input.c",
    "content": "/* EMPTY */\n"
  },
  {
    "path": "Tmain/ptag-proc-cwd.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n# exit_if_win32 $CTAGS\n\nO=\"--quiet --options=NONE \"\n\n(\n\tcd /usr\n\t${CTAGS} $O \\\n\t\t\t --extras=+p --pseudo-tags=TAG_PROC_CWD \\\n\t\t\t -o - \\\n\t\t\t /input.c 2>/dev/null | sed -e \"s|[A-Z]:/.*/usr|/usr|\"\n)\n"
  },
  {
    "path": "Tmain/ptag-proc-cwd.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/ptag-proc-cwd.d/stdout-expected.txt",
    "content": "!_TAG_PROC_CWD\t/usr/\t//\n"
  },
  {
    "path": "Tmain/ptag-role-desc.d/input.c",
    "content": "/* EMPTY */\n"
  },
  {
    "path": "Tmain/ptag-role-desc.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=\"--quiet --options=NONE \"\n\n${CTAGS} $O \\\n\t\t --extras=+p --pseudo-tags=TAG_ROLE_DESCRIPTION \\\n\t\t --kinds-C=h \\\n\t\t -o - \\\n\t\t input.c\n"
  },
  {
    "path": "Tmain/ptag-role-desc.d/stdout-expected.txt",
    "content": "!_TAG_ROLE_DESCRIPTION!C!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C!header\tsystem\t/system header/\n"
  },
  {
    "path": "Tmain/readtags-alias.d/input.c",
    "content": "/* ctags -o output.tags input.c */\nstruct point3d {\n\tint x, y ,z;\n};\n"
  },
  {
    "path": "Tmain/readtags-alias.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/6d353f7f/\npoint3d\tinput.c\t/^struct point3d {$/;\"\ts\tfile:\nx\tinput.c\t/^\tint x, y ,z;$/;\"\tm\tstruct:point3d\ttyperef:typename:int\tfile:\ny\tinput.c\t/^\tint x, y ,z;$/;\"\tm\tstruct:point3d\ttyperef:typename:int\tfile:\nz\tinput.c\t/^\tint x, y ,z;$/;\"\tm\tstruct:point3d\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Tmain/readtags-alias.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '!_ -Q #t point3d'\n${V} ${READTAGS} -t output.tags -Q '#t' point3d\n\necho '!_ -Q true point3d'\n${V} ${READTAGS} -t output.tags -Q 'true' point3d\n\necho '!_ -Q #f point3d'\n${V} ${READTAGS} -t output.tags -Q '#f' point3d\n\necho '!_ -Q false point3d'\n${V} ${READTAGS} -t output.tags -Q 'false' point3d\n\necho '!_ -Q #t -l'\n${V} ${READTAGS} -t output.tags -Q '#t' -l\n\necho '!_ -Q true -l'\n${V} ${READTAGS} -t output.tags -Q 'true' -l\n\necho '!_ -Q #f -l'\n${V} ${READTAGS} -t output.tags -Q '#f' -l\n\necho '!_ -Q false -l'\n${V} ${READTAGS} -t output.tags -Q 'false' -l\n\necho '!_ -Q (null? nil) -l'\n${V} ${READTAGS} -t output.tags -Q '(null? nil)' -l\n\necho '!_ -Q (null? ()) -l'\n${V} ${READTAGS} -t output.tags -Q '(null? ())' -l\n\necho '!_ -Q (null? false) -l'\n${V} ${READTAGS} -t output.tags -Q '(null? false)' -l\n"
  },
  {
    "path": "Tmain/readtags-alias.d/stdout-expected.txt",
    "content": "!_ -Q #t point3d\npoint3d\tinput.c\t/^struct point3d {$/\n!_ -Q true point3d\npoint3d\tinput.c\t/^struct point3d {$/\n!_ -Q #f point3d\n!_ -Q false point3d\n!_ -Q #t -l\npoint3d\tinput.c\t/^struct point3d {$/\nx\tinput.c\t/^\tint x, y ,z;$/\ny\tinput.c\t/^\tint x, y ,z;$/\nz\tinput.c\t/^\tint x, y ,z;$/\n!_ -Q true -l\npoint3d\tinput.c\t/^struct point3d {$/\nx\tinput.c\t/^\tint x, y ,z;$/\ny\tinput.c\t/^\tint x, y ,z;$/\nz\tinput.c\t/^\tint x, y ,z;$/\n!_ -Q #f -l\n!_ -Q false -l\n!_ -Q (null? nil) -l\npoint3d\tinput.c\t/^struct point3d {$/\nx\tinput.c\t/^\tint x, y ,z;$/\ny\tinput.c\t/^\tint x, y ,z;$/\nz\tinput.c\t/^\tint x, y ,z;$/\n!_ -Q (null? ()) -l\npoint3d\tinput.c\t/^struct point3d {$/\nx\tinput.c\t/^\tint x, y ,z;$/\ny\tinput.c\t/^\tint x, y ,z;$/\nz\tinput.c\t/^\tint x, y ,z;$/\n!_ -Q (null? false) -l\n"
  },
  {
    "path": "Tmain/readtags-broken-input.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-broken-input.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\nfor i in 1 2 3 4 5 6; do\n\t${V} ${READTAGS} -t ./target.tags - greet${i} > /dev/null || exit 1\ndone\n\n${READTAGS} -t ./target.tags - greetA\n${READTAGS} -t ./target.tags - greetB\n"
  },
  {
    "path": "Tmain/readtags-broken-input.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-broken-input.d/stdout-expected.txt",
    "content": "greetA\tinput.java\t/^\t\tpublic void greet (String word) {$/\ngreetB\tinput.java\t?^\t\tpublic void greet (String word) {$?\n"
  },
  {
    "path": "Tmain/readtags-broken-input.d/target.tags",
    "content": "greet1\tinput.java\t/^\t\tpublic void greet (String word) {$;\"\tm\tline:9\tmethod:input.hello.anonXXX\ngreetA\tinput.java\t/^\t\tpublic void greet (String word) {$/;\"\tm\tline:9\tmethod:input.hello.anonXXX\ngreet2\tinput.java\tk:v\ngreet3\tinput.java\t\ngreet4\tinput.java\ngreet5\ngreetB\tinput.java\t?^\t\tpublic void greet (String word) {$?;\"\tm\tline:9\tmethod:input.hello.anonXXX\ngreet6\tinput.java\t?^\t\tpublic void greet (String word) {$;\"\tm\tline:9\tmethod:input.hello.anonXXX\n"
  },
  {
    "path": "Tmain/readtags-canonicalize-input-names.d/drive-letter0.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\tC:\\tmp\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t5.9.0\t/e08db39a3/\na_fn\txyz/a.c\t/^static void a_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\n"
  },
  {
    "path": "Tmain/readtags-canonicalize-input-names.d/drive-letter1.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\tD:/tmp\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t5.9.0\t/e08db39a3/\na_fn\txyz/a.c\t/^static void a_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\n"
  },
  {
    "path": "Tmain/readtags-canonicalize-input-names.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-canonicalize-input-names.d/good-ptags.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/../../tmp\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t5.9.0\t/e08db39a3/\n!_TAG_PROC_DUMMY\t/../../tmp\t//\n"
  },
  {
    "path": "Tmain/readtags-canonicalize-input-names.d/good0.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/tmp/abc/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t5.9.0\t/e08db39a3/\na_fn\txyz/a.c\t/^static void a_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nb_fn\tb.c\t/^static void b_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nc_fn\t./c.c\t/^static void c_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nd_fn\t./../d.c\t/^static void d_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ne_fn\t../e.c\t/^static void e_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nf_fn\t../../f.c\t/^static void f_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ng_fn\t../../../g.c\t/^static void g_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nh_fn\t../../../../h.c\t/^static void h_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ni_fn\t.././../../../i.c\t/^static void i_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nj_fn\t.././../j.c\t/^static void j_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nk_fn\t.././.././././k.c\t/^static void k_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nl_fn\t././././././l.c\t/^static void l_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nm_fn\t./././../abc/./m.c\t/^static void m_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nn_fn\t./././../abc/X/.././n.c\t/^static void n_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\no_fn\t.////.///////./////..//abc//X//..///.///o.c\t/^static void o_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\np_fn\t./../xyz/p.c\t/^static void p_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nq_fn\t./../xyz/../././xyz/q.c\t/^static void q_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nr_fn\t/r.c\t/^static void r_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ns_fn\t/../s.c\t/^static void s_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nt_fn\t/../././t.c\t/^static void t_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nu_fn\t/../././tmp/./u.c\t/^static void u_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nv_fn\t/../././tmp/./../tmp/abc/./v.c\t/^static void v_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nw_fn\t/../././tmp/./../tmp/../abc/./w.c\t/^static void w_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\n"
  },
  {
    "path": "Tmain/readtags-canonicalize-input-names.d/good1.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/tmp/abc/../././abc/../abc\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t5.9.0\t/e08db39a3/\na_fn\txyz/a.c\t/^static void a_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nb_fn\tb.c\t/^static void b_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nc_fn\t./c.c\t/^static void c_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nd_fn\t./../d.c\t/^static void d_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ne_fn\t../e.c\t/^static void e_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nf_fn\t../../f.c\t/^static void f_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ng_fn\t../../../g.c\t/^static void g_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nh_fn\t../../../../h.c\t/^static void h_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ni_fn\t.././../../../i.c\t/^static void i_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nj_fn\t.././../j.c\t/^static void j_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nk_fn\t.././.././././k.c\t/^static void k_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nl_fn\t././././././l.c\t/^static void l_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nm_fn\t./././../abc/./m.c\t/^static void m_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nn_fn\t./././../abc/X/.././n.c\t/^static void n_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\no_fn\t.////.///////./////..//abc//X//..///.///o.c\t/^static void o_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\np_fn\t./../xyz/p.c\t/^static void p_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nq_fn\t./../xyz/../././xyz/q.c\t/^static void q_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nr_fn\t/r.c\t/^static void r_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ns_fn\t/../s.c\t/^static void s_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nt_fn\t/../././t.c\t/^static void t_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nu_fn\t/../././tmp/./u.c\t/^static void u_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nv_fn\t/../././tmp/./../tmp/abc/./v.c\t/^static void v_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nw_fn\t/../././tmp/./../tmp/../abc/./w.c\t/^static void w_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\n"
  },
  {
    "path": "Tmain/readtags-canonicalize-input-names.d/good2.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/tmp/abc/../././abc/../abc/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t5.9.0\t/e08db39a3/\na_fn\txyz/a.c\t/^static void a_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nb_fn\tb.c\t/^static void b_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nc_fn\t./c.c\t/^static void c_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nd_fn\t./../d.c\t/^static void d_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ne_fn\t../e.c\t/^static void e_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nf_fn\t../../f.c\t/^static void f_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ng_fn\t../../../g.c\t/^static void g_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nh_fn\t../../../../h.c\t/^static void h_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ni_fn\t.././../../../i.c\t/^static void i_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nj_fn\t.././../j.c\t/^static void j_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nk_fn\t.././.././././k.c\t/^static void k_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nl_fn\t././././././l.c\t/^static void l_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nm_fn\t./././../abc/./m.c\t/^static void m_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nn_fn\t./././../abc/X/.././n.c\t/^static void n_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\no_fn\t.////.///////./////..//abc//X//..///.///o.c\t/^static void o_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\np_fn\t./../xyz/p.c\t/^static void p_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nq_fn\t./../xyz/../././xyz/q.c\t/^static void q_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nr_fn\t/r.c\t/^static void r_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\ns_fn\t/../s.c\t/^static void s_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nt_fn\t/../././t.c\t/^static void t_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nu_fn\t/../././tmp/./u.c\t/^static void u_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nv_fn\t/../././tmp/./../tmp/abc/./v.c\t/^static void v_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\nw_fn\t/../././tmp/./../tmp/../abc/./w.c\t/^static void w_fn(void) {}$/;\"\tf\ttyperef:typename:void\tfile:\n"
  },
  {
    "path": "Tmain/readtags-canonicalize-input-names.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\necho2()\n{\n\techo \"$@\"\n\techo \"$@\" 1>&2\n}\n\nrun_test()\n{\n\techo2 \"# $@\"\n\t\"${READTAGS}\" -F '(list $name \"\\t\" $input \"\\n\")' $2 -t $1 $3\n}\n\nrun_test good0.tags -C -l &&\nrun_test good1.tags --canonicalize-input -l &&\nrun_test good2.tags -C -l &&\n! run_test drive-letter0.tags --canonicalize-input -l &&\n! run_test drive-letter1.tags -C -l &&\nrun_test good-ptags.tags -C -D &&\nrun_test good-ptags.tags -C --list-pseudo-tags &&\nrun_test good0.tags -A -l &&\nrun_test good1.tags --absolute-input -l &&\nrun_test good2.tags -A -l &&\n! run_test drive-letter0.tags --absolute-input -l &&\n! run_test drive-letter1.tags -A -l &&\nrun_test good-ptags.tags -A -D &&\nrun_test good-ptags.tags -A --list-pseudo-tags\n"
  },
  {
    "path": "Tmain/readtags-canonicalize-input-names.d/stderr-expected.txt",
    "content": "# good0.tags -C -l\n# good1.tags --canonicalize-input -l\n# good2.tags -C -l\n# drive-letter0.tags --canonicalize-input -l\n!_TAG_PROC_CWD must start with '/': C:\\tmp\n# drive-letter1.tags -C -l\n!_TAG_PROC_CWD must start with '/': D:/tmp\n# good-ptags.tags -C -D\n# good-ptags.tags -C --list-pseudo-tags\n# good0.tags -A -l\n# good1.tags --absolute-input -l\n# good2.tags -A -l\n# drive-letter0.tags --absolute-input -l\n!_TAG_PROC_CWD must start with '/': C:\\tmp\n# drive-letter1.tags -A -l\n!_TAG_PROC_CWD must start with '/': D:/tmp\n# good-ptags.tags -A -D\n# good-ptags.tags -A --list-pseudo-tags\n"
  },
  {
    "path": "Tmain/readtags-canonicalize-input-names.d/stdout-expected.txt",
    "content": "# good0.tags -C -l\na_fn\txyz/a.c\nb_fn\tb.c\nc_fn\tc.c\nd_fn\t/tmp/d.c\ne_fn\t/tmp/e.c\nf_fn\t/f.c\ng_fn\t/g.c\nh_fn\t/h.c\ni_fn\t/i.c\nj_fn\t/j.c\nk_fn\t/k.c\nl_fn\tl.c\nm_fn\tm.c\nn_fn\tn.c\no_fn\to.c\np_fn\t/tmp/xyz/p.c\nq_fn\t/tmp/xyz/q.c\nr_fn\t/r.c\ns_fn\t/s.c\nt_fn\t/t.c\nu_fn\t/tmp/u.c\nv_fn\t/tmp/abc/v.c\nw_fn\t/abc/w.c\n# good1.tags --canonicalize-input -l\na_fn\txyz/a.c\nb_fn\tb.c\nc_fn\tc.c\nd_fn\t/tmp/d.c\ne_fn\t/tmp/e.c\nf_fn\t/f.c\ng_fn\t/g.c\nh_fn\t/h.c\ni_fn\t/i.c\nj_fn\t/j.c\nk_fn\t/k.c\nl_fn\tl.c\nm_fn\tm.c\nn_fn\tn.c\no_fn\to.c\np_fn\t/tmp/xyz/p.c\nq_fn\t/tmp/xyz/q.c\nr_fn\t/r.c\ns_fn\t/s.c\nt_fn\t/t.c\nu_fn\t/tmp/u.c\nv_fn\t/tmp/abc/v.c\nw_fn\t/abc/w.c\n# good2.tags -C -l\na_fn\txyz/a.c\nb_fn\tb.c\nc_fn\tc.c\nd_fn\t/tmp/d.c\ne_fn\t/tmp/e.c\nf_fn\t/f.c\ng_fn\t/g.c\nh_fn\t/h.c\ni_fn\t/i.c\nj_fn\t/j.c\nk_fn\t/k.c\nl_fn\tl.c\nm_fn\tm.c\nn_fn\tn.c\no_fn\to.c\np_fn\t/tmp/xyz/p.c\nq_fn\t/tmp/xyz/q.c\nr_fn\t/r.c\ns_fn\t/s.c\nt_fn\t/t.c\nu_fn\t/tmp/u.c\nv_fn\t/tmp/abc/v.c\nw_fn\t/abc/w.c\n# drive-letter0.tags --canonicalize-input -l\n# drive-letter1.tags -C -l\n# good-ptags.tags -C -D\n!_TAG_FILE_FORMAT\t2\n!_TAG_FILE_SORTED\t1\n!_TAG_OUTPUT_EXCMD\tmixed\n!_TAG_OUTPUT_FILESEP\tslash\n!_TAG_OUTPUT_MODE\tu-ctags\n!_TAG_PATTERN_LENGTH_LIMIT\t96\n!_TAG_PROC_CWD\t/tmp\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\n!_TAG_PROGRAM_NAME\tUniversal Ctags\n!_TAG_PROGRAM_URL\thttps://ctags.io/\n!_TAG_PROGRAM_VERSION\t5.9.0\n!_TAG_PROC_DUMMY\t/../../tmp\n# good-ptags.tags -C --list-pseudo-tags\n!_TAG_FILE_FORMAT\t2\n!_TAG_FILE_SORTED\t1\n!_TAG_OUTPUT_EXCMD\tmixed\n!_TAG_OUTPUT_FILESEP\tslash\n!_TAG_OUTPUT_MODE\tu-ctags\n!_TAG_PATTERN_LENGTH_LIMIT\t96\n!_TAG_PROC_CWD\t/tmp\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\n!_TAG_PROGRAM_NAME\tUniversal Ctags\n!_TAG_PROGRAM_URL\thttps://ctags.io/\n!_TAG_PROGRAM_VERSION\t5.9.0\n!_TAG_PROC_DUMMY\t/../../tmp\n# good0.tags -A -l\na_fn\t/tmp/abc/xyz/a.c\nb_fn\t/tmp/abc/b.c\nc_fn\t/tmp/abc/c.c\nd_fn\t/tmp/d.c\ne_fn\t/tmp/e.c\nf_fn\t/f.c\ng_fn\t/g.c\nh_fn\t/h.c\ni_fn\t/i.c\nj_fn\t/j.c\nk_fn\t/k.c\nl_fn\t/tmp/abc/l.c\nm_fn\t/tmp/abc/m.c\nn_fn\t/tmp/abc/n.c\no_fn\t/tmp/abc/o.c\np_fn\t/tmp/xyz/p.c\nq_fn\t/tmp/xyz/q.c\nr_fn\t/r.c\ns_fn\t/s.c\nt_fn\t/t.c\nu_fn\t/tmp/u.c\nv_fn\t/tmp/abc/v.c\nw_fn\t/abc/w.c\n# good1.tags --absolute-input -l\na_fn\t/tmp/abc/xyz/a.c\nb_fn\t/tmp/abc/b.c\nc_fn\t/tmp/abc/c.c\nd_fn\t/tmp/d.c\ne_fn\t/tmp/e.c\nf_fn\t/f.c\ng_fn\t/g.c\nh_fn\t/h.c\ni_fn\t/i.c\nj_fn\t/j.c\nk_fn\t/k.c\nl_fn\t/tmp/abc/l.c\nm_fn\t/tmp/abc/m.c\nn_fn\t/tmp/abc/n.c\no_fn\t/tmp/abc/o.c\np_fn\t/tmp/xyz/p.c\nq_fn\t/tmp/xyz/q.c\nr_fn\t/r.c\ns_fn\t/s.c\nt_fn\t/t.c\nu_fn\t/tmp/u.c\nv_fn\t/tmp/abc/v.c\nw_fn\t/abc/w.c\n# good2.tags -A -l\na_fn\t/tmp/abc/xyz/a.c\nb_fn\t/tmp/abc/b.c\nc_fn\t/tmp/abc/c.c\nd_fn\t/tmp/d.c\ne_fn\t/tmp/e.c\nf_fn\t/f.c\ng_fn\t/g.c\nh_fn\t/h.c\ni_fn\t/i.c\nj_fn\t/j.c\nk_fn\t/k.c\nl_fn\t/tmp/abc/l.c\nm_fn\t/tmp/abc/m.c\nn_fn\t/tmp/abc/n.c\no_fn\t/tmp/abc/o.c\np_fn\t/tmp/xyz/p.c\nq_fn\t/tmp/xyz/q.c\nr_fn\t/r.c\ns_fn\t/s.c\nt_fn\t/t.c\nu_fn\t/tmp/u.c\nv_fn\t/tmp/abc/v.c\nw_fn\t/abc/w.c\n# drive-letter0.tags --absolute-input -l\n# drive-letter1.tags -A -l\n# good-ptags.tags -A -D\n!_TAG_FILE_FORMAT\t2\n!_TAG_FILE_SORTED\t1\n!_TAG_OUTPUT_EXCMD\tmixed\n!_TAG_OUTPUT_FILESEP\tslash\n!_TAG_OUTPUT_MODE\tu-ctags\n!_TAG_PATTERN_LENGTH_LIMIT\t96\n!_TAG_PROC_CWD\t/tmp\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\n!_TAG_PROGRAM_NAME\tUniversal Ctags\n!_TAG_PROGRAM_URL\thttps://ctags.io/\n!_TAG_PROGRAM_VERSION\t5.9.0\n!_TAG_PROC_DUMMY\t/../../tmp\n# good-ptags.tags -A --list-pseudo-tags\n!_TAG_FILE_FORMAT\t2\n!_TAG_FILE_SORTED\t1\n!_TAG_OUTPUT_EXCMD\tmixed\n!_TAG_OUTPUT_FILESEP\tslash\n!_TAG_OUTPUT_MODE\tu-ctags\n!_TAG_PATTERN_LENGTH_LIMIT\t96\n!_TAG_PROC_CWD\t/tmp\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\n!_TAG_PROGRAM_NAME\tUniversal Ctags\n!_TAG_PROGRAM_URL\thttps://ctags.io/\n!_TAG_PROGRAM_VERSION\t5.9.0\n!_TAG_PROC_DUMMY\t/../../tmp\n"
  },
  {
    "path": "Tmain/readtags-combine.d/backward.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/6e3f1aa1/\nfoo\tinput.c\t2;?^int foo (void)$?;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-combine.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-combine.d/forward.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/6e3f1aa1/\nfoo\tinput.c\t0;/^int foo (void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-combine.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2019 CCI Europe. Author: Claus Moltke-Leth\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n${V} ${READTAGS} -e -t forward.tags -l &&\n${V} ${READTAGS} -e -t backward.tags -l\n"
  },
  {
    "path": "Tmain/readtags-combine.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-combine.d/stdout-expected.txt",
    "content": "foo\tinput.c\t0;/^int foo (void)$/;\"\tkind:f\ttyperef:typename:int\nfoo\tinput.c\t2;?^int foo (void)$?;\"\tkind:f\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-default-field-val.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-default-field-val.d/input.c",
    "content": "/* ctags -o output.tags --fields-C=+'{properties}' input.c */\nstatic int a(void)\n{\n\treturn 0;\n}\n\ninline int b(void)\n{\n\treturn 0;\n}\n\nint c(void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Tmain/readtags-default-field-val.d/output.tags",
    "content": "!_TAG_EXTRA_DESCRIPTION\tanonymous\t/Include tags for non-named objects like lambda/\n!_TAG_EXTRA_DESCRIPTION\tfileScope\t/Include tags of file scope/\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_EXTRA_DESCRIPTION\tsubparser\t/Include tags generated by subparsers/\n!_TAG_FIELD_DESCRIPTION\tepoch\t/the last modified time of the input file (only for F\\/file kind tag)/\n!_TAG_FIELD_DESCRIPTION\tfile\t/File-restricted scoping/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_FIELD_DESCRIPTION\ttyperef\t/Type and name of a variable or typedef/\n!_TAG_FIELD_DESCRIPTION!C\tproperties\t/properties (static, inline, mutable,...)/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_VERSION\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!C\t0.0\t/current.age/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/yamato/var/ctags-github/Tmain/readtags-default-field-val.d/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t6.0.0\t//\n!_TAG_ROLE_DESCRIPTION!C!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C!header\tsystem\t/system header/\n!_TAG_ROLE_DESCRIPTION!C!macro\tundef\t/undefined/\na\tinput.c\t/^static int a(void)$/;\"\tf\ttyperef:typename:int\tfile:\tproperties:static\nb\tinput.c\t/^inline int b(void)$/;\"\tf\ttyperef:typename:int\tproperties:inline\nc\tinput.c\t/^int c(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-default-field-val.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n# ?a\n# 97\n# (format \"%c\" 96)\n# => `\n\"${READTAGS}\" -t output.tags -S '(<> ($ \"properties\" \"`\") (& \"properties\" \"`\"))' -F '(list $name \" \" ($ \"properties\" \"noprop\") #t)' -l\n"
  },
  {
    "path": "Tmain/readtags-default-field-val.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-default-field-val.d/stdout-expected.txt",
    "content": "c noprop\nb inline\na static\n"
  },
  {
    "path": "Tmain/readtags-error-conflicting-actions.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/readtags-error-conflicting-actions.d/input.tags",
    "content": ""
  },
  {
    "path": "Tmain/readtags-error-conflicting-actions.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nBUILDDIR=$2\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\nf=${BUILDDIR}/tmp-readtags-error-conflicting-actions-$$\nrm -f \"$f\"\n\n{\n\t${READTAGS} --tag-file input.tags -l - main\n} 2> \"$f\"\n\ns=$?\n\nsed 's|.*\\(readtags[^:]*\\):|readtags:|' < \"$f\" 1>&2\nrm \"$f\"\n\nexit $s\n"
  },
  {
    "path": "Tmain/readtags-error-conflicting-actions.d/stderr-expected.txt",
    "content": "readtags: choose either an action: finding a tag or listing all\n"
  },
  {
    "path": "Tmain/readtags-error-conflicting-actions.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-error-in-sorter.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/readtags-error-in-sorter.d/input.c",
    "content": "/* ctags -o output.tags input.c */\nvoid foo (void)\n{\n}\n\nvoid bar (void)\n{\n}\n\nvoid baz (void)\n{\n}\n"
  },
  {
    "path": "Tmain/readtags-error-in-sorter.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/02cf1a61/\nbar\tinput.c\t/^void bar (void)$/;\"\tf\tlanguage:C\ttyperef:typename:void\nbaz\tinput.c\t/^void baz (void)$/;\"\tf\tlanguage:C\ttyperef:typename:void\nfoo\tinput.c\t/^void foo (void)$/;\"\tf\tlanguage:C\ttyperef:typename:void\n"
  },
  {
    "path": "Tmain/readtags-error-in-sorter.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n${READTAGS} -t output.tags -S '(<> \"a\" 1)' -l\n"
  },
  {
    "path": "Tmain/readtags-error-no-action.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/readtags-error-no-action.d/input.tags",
    "content": ""
  },
  {
    "path": "Tmain/readtags-error-no-action.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nBUILDDIR=$2\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\nf=${BUILDDIR}/tmp-readtags-error-no-action-$$\nrm -f \"$f\"\n\n{\n\t${READTAGS} -t input.tags\n} 2> \"$f\"\n\ns=$?\n\nsed 's|.*\\(readtags[^:]*\\):|readtags:|' < \"$f\" 1>&2\nrm \"$f\"\n\nexit $s\n"
  },
  {
    "path": "Tmain/readtags-error-no-action.d/stderr-expected.txt",
    "content": "readtags: no action specified: specify one of NAME, -l or -D\n"
  },
  {
    "path": "Tmain/readtags-error-no-action.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-error-no-input.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/readtags-error-no-input.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nBUILDDIR=$2\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\nf=${BUILDDIR}/tmp-readtags-error-no-input-$$\nrm -f \"$f\"\n{\n\t: &&\n\t\t${READTAGS} -t ./no-such-input.tags -l ||\n\t\t${READTAGS} -t ./no-such-input.tags -D ||\n\t\t${READTAGS} -t ./no-such-input.tags - main ||\n\t\t${READTAGS} -t ./no-such-input.tags main\n} 2> \"$f\"\n\ns=$?\n\nsed 's|.*\\(readtags[^:]*\\):|readtags:|' < \"$f\" 1>&2\nrm \"$f\"\n\nexit $s\n"
  },
  {
    "path": "Tmain/readtags-error-no-input.d/stderr-expected.txt",
    "content": "readtags: cannot open tag file: No such file or directory: ./no-such-input.tags\nreadtags: cannot open tag file: No such file or directory: ./no-such-input.tags\nreadtags: cannot open tag file: No such file or directory: ./no-such-input.tags\nreadtags: cannot open tag file: No such file or directory: ./no-such-input.tags\n"
  },
  {
    "path": "Tmain/readtags-error-no-input.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-escaping.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-escaping.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\naa\tmain/Makefile\t/^%:$/;\"\tt\n\\taa\tparsers/Makefile\t/^%:$/;\"\tt\n!b!b\tmain/Makefile\t/^%:$/;\"\tt\n\\x20c!c\tmain/Makefile\t/^%:$/;\"\tt\n\\x21d!d\tmain/Makefile\t/^%:$/;\"\tt\n\\\\\\aa\tparsers/cxx/Makefile\t/^%:$/;\"\tt\n"
  },
  {
    "path": "Tmain/readtags-escaping.d/output2.tags",
    "content": "\\x01level1\tinput.rst\t/^\u0001level1$/;\"\tc\nlevel2\tinput.rst\t/^level2$/;\"\ts\tscope:chapter:\\x01level1\n\\x21level3\\x03\tinput.rst\t/^!level3\u0003$/;\"\tS\tscope:section:level2\n\\x21level1+\tinput.rst\t/^!level1+$/;\"\tc\nlevel2+\tinput.rst\t/^level2+$/;\"\ts\tscope:chapter:!level1+\n\\x02level3+\\x04\tinput.rst\t/^\u0002level3+\u0004$/;\"\tS\tscope:section:level2+\n"
  },
  {
    "path": "Tmain/readtags-escaping.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\n: &&\necho '# -en -l' &&\n${V} ${READTAGS} -en -t ./output.tags -l &&\n\necho '# -enE -l' &&\n${V} ${READTAGS} -enE -t ./output.tags -l &&\n\necho '# -en --escape-output -l' &&\n${V} ${READTAGS} -en --escape-output -t ./output.tags -l &&\n\necho '# -en -D' &&\n${V} ${READTAGS} -en -t ./output.tags -D &&\n\necho '# -en -E -D' &&\n${V} ${READTAGS} -en -E -t ./output.tags -D &&\n\necho '# -en --escape-output -D' &&\n${V} ${READTAGS} -en --escape-output -t ./output.tags -D &&\n\necho '# -en -l (output2)' &&\n${V} ${READTAGS} -en -t ./output2.tags -l &&\n\necho '# -en --escape-output -l (output2)' &&\n${V} ${READTAGS} -en --escape-output -t ./output2.tags -l &&\n:\n"
  },
  {
    "path": "Tmain/readtags-escaping.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-escaping.d/stdout-expected.txt",
    "content": "# -en -l\naa\tmain/Makefile\t/^%:$/;\"\tkind:t\n\taa\tparsers/Makefile\t/^%:$/;\"\tkind:t\n!b!b\tmain/Makefile\t/^%:$/;\"\tkind:t\n c!c\tmain/Makefile\t/^%:$/;\"\tkind:t\n!d!d\tmain/Makefile\t/^%:$/;\"\tkind:t\n\\\u0007a\tparsers/cxx/Makefile\t/^%:$/;\"\tkind:t\n# -enE -l\naa\tmain/Makefile\t/^%:$/;\"\tkind:t\n\\taa\tparsers/Makefile\t/^%:$/;\"\tkind:t\n\\x21b!b\tmain/Makefile\t/^%:$/;\"\tkind:t\n\\x20c!c\tmain/Makefile\t/^%:$/;\"\tkind:t\n\\x21d!d\tmain/Makefile\t/^%:$/;\"\tkind:t\n\\\\\\aa\tparsers/cxx/Makefile\t/^%:$/;\"\tkind:t\n# -en --escape-output -l\naa\tmain/Makefile\t/^%:$/;\"\tkind:t\n\\taa\tparsers/Makefile\t/^%:$/;\"\tkind:t\n\\x21b!b\tmain/Makefile\t/^%:$/;\"\tkind:t\n\\x20c!c\tmain/Makefile\t/^%:$/;\"\tkind:t\n\\x21d!d\tmain/Makefile\t/^%:$/;\"\tkind:t\n\\\\\\aa\tparsers/cxx/Makefile\t/^%:$/;\"\tkind:t\n# -en -D\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\n# -en -E -D\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\n# -en --escape-output -D\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\n# -en -l (output2)\n\u0001level1\tinput.rst\t/^\u0001level1$/;\"\tkind:c\nlevel2\tinput.rst\t/^level2$/;\"\tkind:s\tscope:chapter:\u0001level1\n!level3\u0003\tinput.rst\t/^!level3\u0003$/;\"\tkind:S\tscope:section:level2\n!level1+\tinput.rst\t/^!level1+$/;\"\tkind:c\nlevel2+\tinput.rst\t/^level2+$/;\"\tkind:s\tscope:chapter:!level1+\n\u0002level3+\u0004\tinput.rst\t/^\u0002level3+\u0004$/;\"\tkind:S\tscope:section:level2+\n# -en --escape-output -l (output2)\n\\x01level1\tinput.rst\t/^\u0001level1$/;\"\tkind:c\nlevel2\tinput.rst\t/^level2$/;\"\tkind:s\tscope:chapter:\\x01level1\n\\x21level3\\x03\tinput.rst\t/^!level3\u0003$/;\"\tkind:S\tscope:section:level2\n\\x21level1+\tinput.rst\t/^!level1+$/;\"\tkind:c\nlevel2+\tinput.rst\t/^level2+$/;\"\tkind:s\tscope:chapter:!level1+\n\\x02level3+\\x04\tinput.rst\t/^\u0002level3+\u0004$/;\"\tkind:S\tscope:section:level2+\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-regex-extraction.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-regex-extraction.d/input.c",
    "content": "/* ../../ctags -o output.tags --fields=+Z'{nth}' --pseudo-tags= --pseudo-tags=+TAG_FILE_FORMAT --pseudo-tags=+TAG_FILE_SORTED input.c */\n\n/* Taken from linux/include/uapi/linux/bpf.h */\nenum bpf_prog_type {\n\tBPF_PROG_TYPE_UNSPEC,\n\tBPF_PROG_TYPE_SOCKET_FILTER,\n\tBPF_PROG_TYPE_KPROBE,\n\tBPF_PROG_TYPE_SCHED_CLS,\n\tBPF_PROG_TYPE_SCHED_ACT,\n\tBPF_PROG_TYPE_TRACEPOINT,\n\tBPF_PROG_TYPE_XDP,\n\tBPF_PROG_TYPE_PERF_EVENT,\n\tBPF_PROG_TYPE_CGROUP_SKB,\n\tBPF_PROG_TYPE_CGROUP_SOCK,\n\tBPF_PROG_TYPE_LWT_IN,\n\tBPF_PROG_TYPE_LWT_OUT,\n\tBPF_PROG_TYPE_LWT_XMIT,\n\tBPF_PROG_TYPE_SOCK_OPS,\n\tBPF_PROG_TYPE_SK_SKB,\n\tBPF_PROG_TYPE_CGROUP_DEVICE,\n\tBPF_PROG_TYPE_SK_MSG,\n\tBPF_PROG_TYPE_RAW_TRACEPOINT,\n\tBPF_PROG_TYPE_CGROUP_SOCK_ADDR,\n\tBPF_PROG_TYPE_LWT_SEG6LOCAL,\n\tBPF_PROG_TYPE_LIRC_MODE2,\n\tBPF_PROG_TYPE_SK_REUSEPORT,\n\tBPF_PROG_TYPE_FLOW_DISSECTOR,\n\tBPF_PROG_TYPE_CGROUP_SYSCTL,\n\tBPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE,\n\tBPF_PROG_TYPE_CGROUP_SOCKOPT,\n\tBPF_PROG_TYPE_TRACING,\n\tBPF_PROG_TYPE_STRUCT_OPS,\n\tBPF_PROG_TYPE_EXT,\n\tBPF_PROG_TYPE_LSM,\n\tBPF_PROG_TYPE_SK_LOOKUP,\n\tBPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */\n};\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-regex-extraction.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\nBPF_PROG_TYPE_CGROUP_DEVICE\tinput.c\t/^\tBPF_PROG_TYPE_CGROUP_DEVICE,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:15\nBPF_PROG_TYPE_CGROUP_SKB\tinput.c\t/^\tBPF_PROG_TYPE_CGROUP_SKB,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:8\nBPF_PROG_TYPE_CGROUP_SOCK\tinput.c\t/^\tBPF_PROG_TYPE_CGROUP_SOCK,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:9\nBPF_PROG_TYPE_CGROUP_SOCKOPT\tinput.c\t/^\tBPF_PROG_TYPE_CGROUP_SOCKOPT,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:25\nBPF_PROG_TYPE_CGROUP_SOCK_ADDR\tinput.c\t/^\tBPF_PROG_TYPE_CGROUP_SOCK_ADDR,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:18\nBPF_PROG_TYPE_CGROUP_SYSCTL\tinput.c\t/^\tBPF_PROG_TYPE_CGROUP_SYSCTL,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:23\nBPF_PROG_TYPE_EXT\tinput.c\t/^\tBPF_PROG_TYPE_EXT,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:28\nBPF_PROG_TYPE_FLOW_DISSECTOR\tinput.c\t/^\tBPF_PROG_TYPE_FLOW_DISSECTOR,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:22\nBPF_PROG_TYPE_KPROBE\tinput.c\t/^\tBPF_PROG_TYPE_KPROBE,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:2\nBPF_PROG_TYPE_LIRC_MODE2\tinput.c\t/^\tBPF_PROG_TYPE_LIRC_MODE2,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:20\nBPF_PROG_TYPE_LSM\tinput.c\t/^\tBPF_PROG_TYPE_LSM,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:29\nBPF_PROG_TYPE_LWT_IN\tinput.c\t/^\tBPF_PROG_TYPE_LWT_IN,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:10\nBPF_PROG_TYPE_LWT_OUT\tinput.c\t/^\tBPF_PROG_TYPE_LWT_OUT,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:11\nBPF_PROG_TYPE_LWT_SEG6LOCAL\tinput.c\t/^\tBPF_PROG_TYPE_LWT_SEG6LOCAL,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:19\nBPF_PROG_TYPE_LWT_XMIT\tinput.c\t/^\tBPF_PROG_TYPE_LWT_XMIT,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:12\nBPF_PROG_TYPE_PERF_EVENT\tinput.c\t/^\tBPF_PROG_TYPE_PERF_EVENT,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:7\nBPF_PROG_TYPE_RAW_TRACEPOINT\tinput.c\t/^\tBPF_PROG_TYPE_RAW_TRACEPOINT,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:17\nBPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE\tinput.c\t/^\tBPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:24\nBPF_PROG_TYPE_SCHED_ACT\tinput.c\t/^\tBPF_PROG_TYPE_SCHED_ACT,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:4\nBPF_PROG_TYPE_SCHED_CLS\tinput.c\t/^\tBPF_PROG_TYPE_SCHED_CLS,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:3\nBPF_PROG_TYPE_SK_LOOKUP\tinput.c\t/^\tBPF_PROG_TYPE_SK_LOOKUP,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:30\nBPF_PROG_TYPE_SK_MSG\tinput.c\t/^\tBPF_PROG_TYPE_SK_MSG,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:16\nBPF_PROG_TYPE_SK_REUSEPORT\tinput.c\t/^\tBPF_PROG_TYPE_SK_REUSEPORT,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:21\nBPF_PROG_TYPE_SK_SKB\tinput.c\t/^\tBPF_PROG_TYPE_SK_SKB,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:14\nBPF_PROG_TYPE_SOCKET_FILTER\tinput.c\t/^\tBPF_PROG_TYPE_SOCKET_FILTER,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:1\nBPF_PROG_TYPE_SOCK_OPS\tinput.c\t/^\tBPF_PROG_TYPE_SOCK_OPS,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:13\nBPF_PROG_TYPE_STRUCT_OPS\tinput.c\t/^\tBPF_PROG_TYPE_STRUCT_OPS,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:27\nBPF_PROG_TYPE_SYSCALL\tinput.c\t/^\tBPF_PROG_TYPE_SYSCALL, \\/* a program that can execute syscalls *\\/$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:31\nBPF_PROG_TYPE_TRACEPOINT\tinput.c\t/^\tBPF_PROG_TYPE_TRACEPOINT,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:5\nBPF_PROG_TYPE_TRACING\tinput.c\t/^\tBPF_PROG_TYPE_TRACING,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:26\nBPF_PROG_TYPE_UNSPEC\tinput.c\t/^\tBPF_PROG_TYPE_UNSPEC,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:0\nBPF_PROG_TYPE_XDP\tinput.c\t/^\tBPF_PROG_TYPE_XDP,$/;\"\te\tscope:enum:bpf_prog_type\tfile:\tnth:6\nbpf_prog_type\tinput.c\t/^enum bpf_prog_type {$/;\"\tg\tfile:\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-regex-extraction.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2023 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '#' /GROUP/\n${V} ${READTAGS} -t output.tags \\\n\t -Q '(eq? $scope \"enum:bpf_prog_type\")' \\\n\t -S '(<> $nth &nth)' \\\n\t -F '(list \"[\" $nth \"] = \\\"\" (downcase (#/BPF_PROG_TYPE_(.*)/ $name 1)) \"\\\",\\n\")' \\\n\t -l\n\necho '#' /group/i\n${V} ${READTAGS} -t output.tags \\\n\t -Q '(eq? $scope \"enum:bpf_prog_type\")' \\\n\t -S '(<> $nth &nth)' \\\n\t -F '(list \"[\" $nth \"] = \\\"\" (#/bpf_prog_type_(.*)/i $name 1) \"\\\",\\n\")' \\\n\t -l\n\necho '#' /GROUP/ with a fallback value\n${V} ${READTAGS} -t output.tags \\\n\t -Q '(eq? $scope \"enum:bpf_prog_type\")' \\\n\t -S '(<> $nth &nth)' \\\n\t -F '(list \"[\" $nth \"] = \\\"S\" (#/BPF_PROG_TYPE_S(.*)/ $name 1 \"???\") \"\\\",\\n\")' \\\n\t -l\n\necho '#' /GROUP/i with a fallback value\n${V} ${READTAGS} -t output.tags \\\n\t -Q '(eq? $scope \"enum:bpf_prog_type\")' \\\n\t -S '(<> $nth &nth)' \\\n\t -F '(list \"[\" $nth \"] = \\\"s\" (downcase (#/bpf_prog_type_s(.*)/i $name 1 \"???\")) \"\\\",\\n\")' \\\n\t -l\n\necho '#' /GROUP = 0/\n${V} ${READTAGS} -t output.tags \\\n\t -Q '(eq? $scope \"enum:bpf_prog_type\")' \\\n\t -S '(<> $nth &nth)' \\\n\t -F '(list \"[\" $nth \"] = \\\"\" (downcase (#/BPF_PROG_TYPE_(.*)/ $name 0)) \"\\\",\\n\")' \\\n\t -l\n\necho '#' /GROUP = empty/\n${V} ${READTAGS} -t output.tags \\\n\t -Q '(eq? $scope \"enum:bpf_prog_type\")' \\\n\t -S '(<> $nth &nth)' \\\n\t -F '(list \"[\" $nth \"] = \\\"\" (downcase (#/BPF_PROG_TYPE_UNSPE(.*)()/ $name 2)) \"\\\",\\n\")' \\\n\t -l\n\necho '#' /GROUP = 100/\n${V} ${READTAGS} -t output.tags \\\n\t -Q '(eq? $scope \"enum:bpf_prog_type\")' \\\n\t -S '(<> $nth &nth)' \\\n\t -F '(list \"[\" $nth \"] = \\\"\" (downcase (#/BPF_PROG_TYPE_UNSPE(.*)/ $name 100)) \"\\\",\\n\")' \\\n\t -l\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-regex-extraction.d/stderr-expected.txt",
    "content": "GOT ERROR in FORMATTING: wrong-regex-group: (#/BPF_PROG_TYPE_(.*)/ $name 0)\nGOT ERROR in FORMATTING: wrong-regex-group: (#/BPF_PROG_TYPE_UNSPE(.*)/ $name 100)\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-regex-extraction.d/stdout-expected.txt",
    "content": "# /GROUP/\n[0] = \"unspec\",\n[1] = \"socket_filter\",\n[2] = \"kprobe\",\n[3] = \"sched_cls\",\n[4] = \"sched_act\",\n[5] = \"tracepoint\",\n[6] = \"xdp\",\n[7] = \"perf_event\",\n[8] = \"cgroup_skb\",\n[9] = \"cgroup_sock\",\n[10] = \"lwt_in\",\n[11] = \"lwt_out\",\n[12] = \"lwt_xmit\",\n[13] = \"sock_ops\",\n[14] = \"sk_skb\",\n[15] = \"cgroup_device\",\n[16] = \"sk_msg\",\n[17] = \"raw_tracepoint\",\n[18] = \"cgroup_sock_addr\",\n[19] = \"lwt_seg6local\",\n[20] = \"lirc_mode2\",\n[21] = \"sk_reuseport\",\n[22] = \"flow_dissector\",\n[23] = \"cgroup_sysctl\",\n[24] = \"raw_tracepoint_writable\",\n[25] = \"cgroup_sockopt\",\n[26] = \"tracing\",\n[27] = \"struct_ops\",\n[28] = \"ext\",\n[29] = \"lsm\",\n[30] = \"sk_lookup\",\n[31] = \"syscall\",\n# /group/i\n[0] = \"UNSPEC\",\n[1] = \"SOCKET_FILTER\",\n[2] = \"KPROBE\",\n[3] = \"SCHED_CLS\",\n[4] = \"SCHED_ACT\",\n[5] = \"TRACEPOINT\",\n[6] = \"XDP\",\n[7] = \"PERF_EVENT\",\n[8] = \"CGROUP_SKB\",\n[9] = \"CGROUP_SOCK\",\n[10] = \"LWT_IN\",\n[11] = \"LWT_OUT\",\n[12] = \"LWT_XMIT\",\n[13] = \"SOCK_OPS\",\n[14] = \"SK_SKB\",\n[15] = \"CGROUP_DEVICE\",\n[16] = \"SK_MSG\",\n[17] = \"RAW_TRACEPOINT\",\n[18] = \"CGROUP_SOCK_ADDR\",\n[19] = \"LWT_SEG6LOCAL\",\n[20] = \"LIRC_MODE2\",\n[21] = \"SK_REUSEPORT\",\n[22] = \"FLOW_DISSECTOR\",\n[23] = \"CGROUP_SYSCTL\",\n[24] = \"RAW_TRACEPOINT_WRITABLE\",\n[25] = \"CGROUP_SOCKOPT\",\n[26] = \"TRACING\",\n[27] = \"STRUCT_OPS\",\n[28] = \"EXT\",\n[29] = \"LSM\",\n[30] = \"SK_LOOKUP\",\n[31] = \"SYSCALL\",\n# /GROUP/ with a fallback value\n[0] = \"S???\",\n[1] = \"SOCKET_FILTER\",\n[2] = \"S???\",\n[3] = \"SCHED_CLS\",\n[4] = \"SCHED_ACT\",\n[5] = \"S???\",\n[6] = \"S???\",\n[7] = \"S???\",\n[8] = \"S???\",\n[9] = \"S???\",\n[10] = \"S???\",\n[11] = \"S???\",\n[12] = \"S???\",\n[13] = \"SOCK_OPS\",\n[14] = \"SK_SKB\",\n[15] = \"S???\",\n[16] = \"SK_MSG\",\n[17] = \"S???\",\n[18] = \"S???\",\n[19] = \"S???\",\n[20] = \"S???\",\n[21] = \"SK_REUSEPORT\",\n[22] = \"S???\",\n[23] = \"S???\",\n[24] = \"S???\",\n[25] = \"S???\",\n[26] = \"S???\",\n[27] = \"STRUCT_OPS\",\n[28] = \"S???\",\n[29] = \"S???\",\n[30] = \"SK_LOOKUP\",\n[31] = \"SYSCALL\",\n# /GROUP/i with a fallback value\n[0] = \"s???\",\n[1] = \"socket_filter\",\n[2] = \"s???\",\n[3] = \"sched_cls\",\n[4] = \"sched_act\",\n[5] = \"s???\",\n[6] = \"s???\",\n[7] = \"s???\",\n[8] = \"s???\",\n[9] = \"s???\",\n[10] = \"s???\",\n[11] = \"s???\",\n[12] = \"s???\",\n[13] = \"sock_ops\",\n[14] = \"sk_skb\",\n[15] = \"s???\",\n[16] = \"sk_msg\",\n[17] = \"s???\",\n[18] = \"s???\",\n[19] = \"s???\",\n[20] = \"s???\",\n[21] = \"sk_reuseport\",\n[22] = \"s???\",\n[23] = \"s???\",\n[24] = \"s???\",\n[25] = \"s???\",\n[26] = \"s???\",\n[27] = \"struct_ops\",\n[28] = \"s???\",\n[29] = \"s???\",\n[30] = \"sk_lookup\",\n[31] = \"syscall\",\n# /GROUP = 0/\n# /GROUP = empty/\n[0] = \"\",\n[1] = \"\",\n[2] = \"\",\n[3] = \"\",\n[4] = \"\",\n[5] = \"\",\n[6] = \"\",\n[7] = \"\",\n[8] = \"\",\n[9] = \"\",\n[10] = \"\",\n[11] = \"\",\n[12] = \"\",\n[13] = \"\",\n[14] = \"\",\n[15] = \"\",\n[16] = \"\",\n[17] = \"\",\n[18] = \"\",\n[19] = \"\",\n[20] = \"\",\n[21] = \"\",\n[22] = \"\",\n[23] = \"\",\n[24] = \"\",\n[25] = \"\",\n[26] = \"\",\n[27] = \"\",\n[28] = \"\",\n[29] = \"\",\n[30] = \"\",\n[31] = \"\",\n# /GROUP = 100/\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-tr.d/input.cpp",
    "content": "// ctags -o output.tags input.cpp\nint __foo(void) { return 0; }\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-tr.d/output.tags",
    "content": "!_TAG_EXTRA_DESCRIPTION\tanonymous\t/Include tags for non-named objects like lambda/\n!_TAG_EXTRA_DESCRIPTION\tfileScope\t/Include tags of file scope/\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_EXTRA_DESCRIPTION\tsubparser\t/Include tags generated by subparsers/\n!_TAG_FIELD_DESCRIPTION\tepoch\t/the last modified time of the input file (only for F\\/file kind tag)/\n!_TAG_FIELD_DESCRIPTION\tfile\t/File-restricted scoping/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_FIELD_DESCRIPTION\ttyperef\t/Type and name of a variable or typedef/\n!_TAG_FIELD_DESCRIPTION!C++\tname\t/aliased names/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C++\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!C++\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C++\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C++\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C++\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C++\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C++\tm,member\t/class, struct, and union members/\n!_TAG_KIND_DESCRIPTION!C++\tn,namespace\t/namespaces/\n!_TAG_KIND_DESCRIPTION!C++\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C++\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C++\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C++\tv,variable\t/variable definitions/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_VERSION\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!C++\t0.0\t/current.age/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/yamato/var/ctags-github/Tmain/readtags-qualifier-op-tr.d/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t6.0.0\t//\n!_TAG_ROLE_DESCRIPTION!C++!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C++!header\tsystem\t/system header/\n!_TAG_ROLE_DESCRIPTION!C++!macro\tundef\t/undefined/\n__foo\tinput.cpp\t/^int __foo(void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-tr.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n${V} ${READTAGS} -t output.tags -F '(list (tr $name \"_$\") #t)' -l\n\n${V} ${READTAGS} -t output.tags -F '(list (tr $name \"_$x\") #t)' -l\n${V} ${READTAGS} -t output.tags -F '(list (tr $name \"_\") #t)' -l\n${V} ${READTAGS} -t output.tags -F '(list (tr $name \"\") #t)' -l\n${V} ${READTAGS} -t output.tags -F '(list (tr $name 2) #t)' -l\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-tr.d/stderr-expected.txt",
    "content": "GOT ERROR in FORMATTING: unexpected-string-length: tr\nGOT ERROR in FORMATTING: unexpected-string-length: tr\nGOT ERROR in FORMATTING: unexpected-string-length: tr\nGOT ERROR in FORMATTING: string-required: tr\n"
  },
  {
    "path": "Tmain/readtags-formatter-op-tr.d/stdout-expected.txt",
    "content": "$$foo\n"
  },
  {
    "path": "Tmain/readtags-formatter.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-formatter.d/input.c",
    "content": "/* ctags -o output.tags --fields=+St -n --pseudo-tags=-TAG_PROGRAM_VERSION input.c */\n\n#define N 1\n#define M 3\n\nstatic int foo (int v)\n{\n\treturn v + N;\n}\n\nstatic void bar(char **argv, int *r)\n{\n\t*r = M;\n}\n\nint main(int argc, char **argv)\n{\n\tint i;\n\n\tbar(argv, &i);\n\treturn foo (argc) + i;\n}\n"
  },
  {
    "path": "Tmain/readtags-formatter.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tnumber\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/jet/var/ctags-github/Tmain/readtags-formatter.d/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\nM\tinput.c\t4;\"\tmacro\tfile:\nN\tinput.c\t3;\"\tmacro\tfile:\nbar\tinput.c\t11;\"\tfunction\ttyperef:typename:void\tfile:\tsignature:(char ** argv,int * r)\nfoo\tinput.c\t6;\"\tfunction\ttyperef:typename:int\tfile:\tsignature:(int v)\nmain\tinput.c\t16;\"\tfunction\ttyperef:typename:int\tsignature:(int argc,char ** argv)\n"
  },
  {
    "path": "Tmain/readtags-formatter.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '# FQ' &&\n\t${V} ${READTAGS} -t output.tags -Q '(eq? $kind \"function\")' --formatter '(list $name #t)' -l &&\necho '# F' &&\n${V} ${READTAGS} -t output.tags -F '(if (eq? $kind \"function\") (list $name #t) #f)' -l &&\necho '# F declarations' &&\n${V} ${READTAGS} -t output.tags -F \\\n     '(if (eq? $kind \"function\")\n         (list (if $file \"static \" #f) $typeref-name \" \" $name $signature \";\" #t)\n        #f)' -l\n"
  },
  {
    "path": "Tmain/readtags-formatter.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-formatter.d/stdout-expected.txt",
    "content": "# FQ\nbar\nfoo\nmain\n# F\nbar\nfoo\nmain\n# F declarations\nstatic void bar(char ** argv,int * r);\nstatic int foo(int v);\nint main(int argc,char ** argv);\n"
  },
  {
    "path": "Tmain/readtags-list-pseudo-tags.d/ptag-sort-no.tags",
    "content": "!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\n"
  },
  {
    "path": "Tmain/readtags-list-pseudo-tags.d/ptag-sort-yes.tags",
    "content": "!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-list-pseudo-tags.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '# SORT=NO (-D)'\n${V} ${READTAGS} -t ./ptag-sort-no.tags -D\n\necho '# SORT=NO (-P)'\n${V} ${READTAGS} -t ./ptag-sort-no.tags -P no-such-tags\n\necho '# SORT=YES (-D)'\n${V} ${READTAGS} -t ./ptag-sort-yes.tags -D\n\necho '# SORT=YES (-P)'\n${V} ${READTAGS} -t ./ptag-sort-yes.tags -P no-such-tags\n\n# Without the following environment variable,\n# Msys2 convert #/MA/i to #C:/msys64/MA/i.\n# See https://www.msys2.org/docs/filesystem-paths/\nexport MSYS2_ARG_CONV_EXCL='*'\n\necho '# -D + FILTER (-D)'\n${V} ${READTAGS} -t ./ptag-sort-yes.tags -Q '(#/MA/i $name)' -D\n\necho '# -P -l + FILTER (-D)'\n${V} ${READTAGS} -t ./ptag-sort-yes.tags -Q '(#/MA/i $name)' -P -l\n"
  },
  {
    "path": "Tmain/readtags-list-pseudo-tags.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-list-pseudo-tags.d/stdout-expected.txt",
    "content": "# SORT=NO (-D)\n!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\n# SORT=NO (-P)\n!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\n# SORT=YES (-D)\n!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\n# SORT=YES (-P)\n!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\n# -D + FILTER (-D)\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n# -P -l + FILTER (-D)\n!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nmain\tinput.c\t/^int main (void) { return 0; }$/\n"
  },
  {
    "path": "Tmain/readtags-ptags-dls.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-ptags-dls.d/input.tags",
    "content": "!_TAG_EXTRA_DESCRIPTION\tanonymous\t/Include tags for non-named objects like lambda/\n!_TAG_EXTRA_DESCRIPTION\tfileScope\t/Include tags of file scope/\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_EXTRA_DESCRIPTION\tsubparser\t/Include tags generated by subparsers/\n!_TAG_FIELD_DESCRIPTION\tepoch\t/the last modified time of the input file (only for F\\/file kind tag)/\n!_TAG_FIELD_DESCRIPTION\tfile\t/File-restricted scoping/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_FIELD_DESCRIPTION\ttyperef\t/Type and name of a variable or typedef/\n!_TAG_FIELD_DESCRIPTION!Asm\tproperties\t/properties (req, vararg for parameters)/\n!_TAG_FIELD_DESCRIPTION!C++\tname\t/aliased names/\n!_TAG_FIELD_DESCRIPTION!Go\tpackage\t/the real package specified by the package name/\n!_TAG_FIELD_DESCRIPTION!Go\tpackageName\t/the name for referring the package/\n!_TAG_FIELD_DESCRIPTION!Python\tnameref\t/the original name for the tag/\n!_TAG_FIELD_DESCRIPTION!R\tconstructor\t/function used for making value assigned to the nameattr tag/\n!_TAG_FIELD_DESCRIPTION!Ruby\tmixin\t/how the class or module is mixed in (mixin:HOW:MODULE)/\n!_TAG_FIELD_DESCRIPTION!XML\turi\t/uri associated with name prefix/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tS,subsection\t/level 2 sections/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tT,l4subsection\t/level 4 sections/\n!_TAG_KIND_DESCRIPTION!Asciidoc\ta,anchor\t/anchors/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!Asciidoc\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tt,subsubsection\t/level 3 sections/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tu,l5subsection\t/level 5 sections/\n!_TAG_KIND_DESCRIPTION!Asm\td,define\t/defines/\n!_TAG_KIND_DESCRIPTION!Asm\tl,label\t/labels/\n!_TAG_KIND_DESCRIPTION!Asm\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!Asm\tt,type\t/types (structs and records)/\n!_TAG_KIND_DESCRIPTION!Awk\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Bats\tS,script\t/scripts/\n!_TAG_KIND_DESCRIPTION!Bats\tt,test\t/test cases/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C++\tM,module\t/modules/\n!_TAG_KIND_DESCRIPTION!C++\tP,partition\t/partitions/\n!_TAG_KIND_DESCRIPTION!C++\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!C++\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C++\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C++\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C++\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C++\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C++\tm,member\t/class, struct, and union members/\n!_TAG_KIND_DESCRIPTION!C++\tn,namespace\t/namespaces/\n!_TAG_KIND_DESCRIPTION!C++\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C++\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C++\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C++\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!CSS\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!CSS\ti,id\t/identities/\n!_TAG_KIND_DESCRIPTION!CSS\ts,selector\t/selectors/\n!_TAG_KIND_DESCRIPTION!DTD\tE,entity\t/entities/\n!_TAG_KIND_DESCRIPTION!DTD\ta,attribute\t/attributes/\n!_TAG_KIND_DESCRIPTION!DTD\te,element\t/elements/\n!_TAG_KIND_DESCRIPTION!DTD\tn,notation\t/notations/\n!_TAG_KIND_DESCRIPTION!DTD\tp,parameterEntity\t/parameter entities/\n!_TAG_KIND_DESCRIPTION!Diff\td,deletedFile\t/deleted files/\n!_TAG_KIND_DESCRIPTION!Diff\th,hunk\t/hunks/\n!_TAG_KIND_DESCRIPTION!Diff\tm,modifiedFile\t/modified files/\n!_TAG_KIND_DESCRIPTION!Diff\tn,newFile\t/newly created files/\n!_TAG_KIND_DESCRIPTION!DosBatch\tl,label\t/labels/\n!_TAG_KIND_DESCRIPTION!DosBatch\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!Go\tM,anonMember\t/struct anonymous members/\n!_TAG_KIND_DESCRIPTION!Go\tP,packageName\t/name for specifying imported package/\n!_TAG_KIND_DESCRIPTION!Go\tY,unknown\t/unknown/\n!_TAG_KIND_DESCRIPTION!Go\ta,talias\t/type aliases/\n!_TAG_KIND_DESCRIPTION!Go\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!Go\tf,func\t/functions/\n!_TAG_KIND_DESCRIPTION!Go\ti,interface\t/interfaces/\n!_TAG_KIND_DESCRIPTION!Go\tm,member\t/struct members/\n!_TAG_KIND_DESCRIPTION!Go\tn,methodSpec\t/interface method specification/\n!_TAG_KIND_DESCRIPTION!Go\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!Go\ts,struct\t/structs/\n!_TAG_KIND_DESCRIPTION!Go\tt,type\t/types/\n!_TAG_KIND_DESCRIPTION!Go\tv,var\t/variables/\n!_TAG_KIND_DESCRIPTION!HTML\tC,stylesheet\t/stylesheets/\n!_TAG_KIND_DESCRIPTION!HTML\tI,id\t/identifiers/\n!_TAG_KIND_DESCRIPTION!HTML\tJ,script\t/scripts/\n!_TAG_KIND_DESCRIPTION!HTML\ta,anchor\t/named anchors/\n!_TAG_KIND_DESCRIPTION!HTML\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!HTML\th,heading1\t/H1 headings/\n!_TAG_KIND_DESCRIPTION!HTML\ti,heading2\t/H2 headings/\n!_TAG_KIND_DESCRIPTION!HTML\tj,heading3\t/H3 headings/\n!_TAG_KIND_DESCRIPTION!HTML\tt,title\t/titles/\n!_TAG_KIND_DESCRIPTION!Iniconf\tk,key\t/keys/\n!_TAG_KIND_DESCRIPTION!Iniconf\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!JSON\ta,array\t/arrays/\n!_TAG_KIND_DESCRIPTION!JSON\tb,boolean\t/booleans/\n!_TAG_KIND_DESCRIPTION!JSON\tn,number\t/numbers/\n!_TAG_KIND_DESCRIPTION!JSON\to,object\t/objects/\n!_TAG_KIND_DESCRIPTION!JSON\ts,string\t/strings/\n!_TAG_KIND_DESCRIPTION!JSON\tz,null\t/nulls/\n!_TAG_KIND_DESCRIPTION!Lua\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Make\tI,makefile\t/makefiles/\n!_TAG_KIND_DESCRIPTION!Make\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!Make\tt,target\t/targets/\n!_TAG_KIND_DESCRIPTION!Man\tS,subsection\t/sub sections/\n!_TAG_KIND_DESCRIPTION!Man\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Man\tt,title\t/titles/\n!_TAG_KIND_DESCRIPTION!Markdown\tS,subsection\t/level 2 sections/\n!_TAG_KIND_DESCRIPTION!Markdown\tT,l4subsection\t/level 4 sections/\n!_TAG_KIND_DESCRIPTION!Markdown\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!Markdown\th,hashtag\t/hashtags/\n!_TAG_KIND_DESCRIPTION!Markdown\tn,footnote\t/footnotes/\n!_TAG_KIND_DESCRIPTION!Markdown\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Markdown\tt,subsubsection\t/level 3 sections/\n!_TAG_KIND_DESCRIPTION!Markdown\tu,l5subsection\t/level 5 sections/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tP,parameter\t/parameters/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tR,response\t/responses/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tT,tag\t/tags/\n!_TAG_KIND_DESCRIPTION!OpenAPI\td,schema\t/schemas/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tp,path\t/paths/\n!_TAG_KIND_DESCRIPTION!OpenAPI\ts,server\t/servers (or hosts in swagger)/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tt,title\t/titles/\n!_TAG_KIND_DESCRIPTION!Perl\tc,constant\t/constants/\n!_TAG_KIND_DESCRIPTION!Perl\tf,format\t/formats/\n!_TAG_KIND_DESCRIPTION!Perl\tl,label\t/labels/\n!_TAG_KIND_DESCRIPTION!Perl\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!Perl\ts,subroutine\t/subroutines/\n!_TAG_KIND_DESCRIPTION!Pod\tS,subsection\t/subsections/\n!_TAG_KIND_DESCRIPTION!Pod\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!Pod\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Pod\tt,subsubsection\t/subsubsections/\n!_TAG_KIND_DESCRIPTION!PowerShell\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!PowerShell\te,enumlabel\t/enum labels/\n!_TAG_KIND_DESCRIPTION!PowerShell\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!PowerShell\tg,enum\t/enum names/\n!_TAG_KIND_DESCRIPTION!PowerShell\ti,filter\t/filter/\n!_TAG_KIND_DESCRIPTION!PowerShell\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!Protobuf\tD,protodef\t/.proto definition/\n!_TAG_KIND_DESCRIPTION!Protobuf\tG,group\t/groups/\n!_TAG_KIND_DESCRIPTION!Protobuf\te,enumerator\t/enum constants/\n!_TAG_KIND_DESCRIPTION!Protobuf\tf,field\t/fields/\n!_TAG_KIND_DESCRIPTION!Protobuf\tg,enum\t/enum types/\n!_TAG_KIND_DESCRIPTION!Protobuf\tm,message\t/messages/\n!_TAG_KIND_DESCRIPTION!Protobuf\to,oneof\t/oneof names/\n!_TAG_KIND_DESCRIPTION!Protobuf\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!Protobuf\tr,rpc\t/RPC methods/\n!_TAG_KIND_DESCRIPTION!Protobuf\ts,service\t/services/\n!_TAG_KIND_DESCRIPTION!Python\tI,namespace\t/name referring a module defined in other file/\n!_TAG_KIND_DESCRIPTION!Python\tY,unknown\t/name referring a class\\/variable\\/function\\/module defined in other module/\n!_TAG_KIND_DESCRIPTION!Python\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!Python\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Python\ti,module\t/modules/\n!_TAG_KIND_DESCRIPTION!Python\tm,member\t/class members/\n!_TAG_KIND_DESCRIPTION!Python\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!R\tL,list\t/lists explicitly created with `list()'/\n!_TAG_KIND_DESCRIPTION!R\tc,vector\t/vectors explicitly created with `c()'/\n!_TAG_KIND_DESCRIPTION!R\td,dataframe\t/data frame explicitly created with `data.frame()'/\n!_TAG_KIND_DESCRIPTION!R\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!R\tg,globalVar\t/global variables having values other than function()/\n!_TAG_KIND_DESCRIPTION!R\tl,library\t/libraries/\n!_TAG_KIND_DESCRIPTION!R\tn,nameattr\t/names attribtes in vectors, lists, or dataframes/\n!_TAG_KIND_DESCRIPTION!R\ts,source\t/sources/\n!_TAG_KIND_DESCRIPTION!R\tv,functionVar\t/function variables having values other than function()/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tC,citation\t/citations/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tH,title\t/titles/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tS,subsection\t/subsections/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tT,target\t/targets/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\td,substdef\t/substitute definitions/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\th,subtitle\t/sub titles/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tt,subsubsection\t/subsubsections/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tg,global\t/global macros/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tp,patch\t/patch files/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tt,tag\t/tags/\n!_TAG_KIND_DESCRIPTION!Ruby\tA,accessor\t/accessors/\n!_TAG_KIND_DESCRIPTION!Ruby\tC,constant\t/constants/\n!_TAG_KIND_DESCRIPTION!Ruby\tL,library\t/libraries/\n!_TAG_KIND_DESCRIPTION!Ruby\tS,singletonMethod\t/singleton methods/\n!_TAG_KIND_DESCRIPTION!Ruby\ta,alias\t/aliases/\n!_TAG_KIND_DESCRIPTION!Ruby\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!Ruby\tf,method\t/methods/\n!_TAG_KIND_DESCRIPTION!Ruby\tm,module\t/modules/\n!_TAG_KIND_DESCRIPTION!SVG\td,def\t/ids in defs tags/\n!_TAG_KIND_DESCRIPTION!Sh\ta,alias\t/aliases/\n!_TAG_KIND_DESCRIPTION!Sh\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Sh\th,heredoc\t/label for here document/\n!_TAG_KIND_DESCRIPTION!Sh\ts,script\t/script files/\n!_TAG_KIND_DESCRIPTION!SystemdUnit\tu,unit\t/units/\n!_TAG_KIND_DESCRIPTION!TOML\tK,qkey\t/qualified keys/\n!_TAG_KIND_DESCRIPTION!TOML\ta,arraytable\t/array tables/\n!_TAG_KIND_DESCRIPTION!TOML\tt,table\t/tables/\n!_TAG_KIND_DESCRIPTION!XML\ti,id\t/id attributes/\n!_TAG_KIND_DESCRIPTION!XML\tn,nsprefix\t/namespace prefixes/\n!_TAG_KIND_DESCRIPTION!XML\tr,root\t/root elements/\n!_TAG_KIND_DESCRIPTION!Yaml\ta,anchor\t/anchors/\n!_TAG_KIND_DESCRIPTION!Zsh\ta,alias\t/aliases/\n!_TAG_KIND_DESCRIPTION!Zsh\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Zsh\th,heredoc\t/label for here document/\n!_TAG_KIND_DESCRIPTION!Zsh\ts,script\t/script files/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_VERSION\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Asciidoc\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Asm\t1.0\t/current.age/\n!_TAG_PARSER_VERSION!Awk\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Bats\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!C\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!C++\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!CSS\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!DTD\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Diff\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!DosBatch\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Go\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!HTML\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Iniconf\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!JSON\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Lua\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Make\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!Man\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Markdown\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!OpenAPI\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Perl\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Pod\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!PowerShell\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!Protobuf\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Python\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!R\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!ReStructuredText\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!RpmSpec\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Ruby\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!SVG\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Sh\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!SystemdUnit\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!TOML\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!XML\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Yaml\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Zsh\t0.0\t/current.age/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/yamato/var/ctags-github/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t6.1.0\t/d1ecc51b9/\n!_TAG_ROLE_DESCRIPTION!Bats!script\tloaded\t/script loaed with \"load\" command/\n!_TAG_ROLE_DESCRIPTION!C!function\tforeigndecl\t/declared in foreign languages/\n!_TAG_ROLE_DESCRIPTION!C!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C!header\tsystem\t/system header/\n!_TAG_ROLE_DESCRIPTION!C!macro\tundef\t/undefined/\n!_TAG_ROLE_DESCRIPTION!C!struct\tforeigndecl\t/declared in foreign languages/\n!_TAG_ROLE_DESCRIPTION!C++!header\texported\t/exported with \"exported imported ...\"/\n!_TAG_ROLE_DESCRIPTION!C++!header\timported\t/imported with \"imported ...\"/\n!_TAG_ROLE_DESCRIPTION!C++!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C++!header\tsystem\t/system header/\n!_TAG_ROLE_DESCRIPTION!C++!macro\tundef\t/undefined/\n!_TAG_ROLE_DESCRIPTION!C++!module\timported\t/imported with \"imported ...\"/\n!_TAG_ROLE_DESCRIPTION!C++!module\tpartOwner\t/used for specifying a partition/\n!_TAG_ROLE_DESCRIPTION!C++!partition\timported\t/imported with \"imported ...\"/\n!_TAG_ROLE_DESCRIPTION!DTD!element\tattOwner\t/attributes owner/\n!_TAG_ROLE_DESCRIPTION!DTD!parameterEntity\tcondition\t/conditions/\n!_TAG_ROLE_DESCRIPTION!DTD!parameterEntity\telementName\t/element names/\n!_TAG_ROLE_DESCRIPTION!DTD!parameterEntity\tpartOfAttDef\t/part of attribute definition/\n!_TAG_ROLE_DESCRIPTION!Go!package\timported\t/imported package/\n!_TAG_ROLE_DESCRIPTION!Go!unknown\treceiverType\t/receiver type/\n!_TAG_ROLE_DESCRIPTION!HTML!class\tattribute\t/assigned as attributes/\n!_TAG_ROLE_DESCRIPTION!HTML!script\textFile\t/referenced as external files/\n!_TAG_ROLE_DESCRIPTION!HTML!stylesheet\textFile\t/referenced as external files/\n!_TAG_ROLE_DESCRIPTION!Make!makefile\tincluded\t/included/\n!_TAG_ROLE_DESCRIPTION!Make!makefile\toptional\t/optionally included/\n!_TAG_ROLE_DESCRIPTION!Protobuf!message\textension\t/extending the message/\n!_TAG_ROLE_DESCRIPTION!Protobuf!protodef\timported\t/imported/\n!_TAG_ROLE_DESCRIPTION!Python!module\timported\t/imported modules/\n!_TAG_ROLE_DESCRIPTION!Python!module\tindirectlyImported\t/module imported in alternative name/\n!_TAG_ROLE_DESCRIPTION!Python!module\tnamespace\t/namespace from where classes\\/variables\\/functions are imported/\n!_TAG_ROLE_DESCRIPTION!Python!unknown\timported\t/imported from the other module/\n!_TAG_ROLE_DESCRIPTION!Python!unknown\tindirectlyImported\t/classes\\/variables\\/functions\\/modules imported in alternative name/\n!_TAG_ROLE_DESCRIPTION!R!library\tlibrary\t/library attached by library function/\n!_TAG_ROLE_DESCRIPTION!R!library\trequire\t/library attached by require function/\n!_TAG_ROLE_DESCRIPTION!R!source\tsource\t/source loaded by source fucntion/\n!_TAG_ROLE_DESCRIPTION!RpmSpec!macro\tundef\t/undefined/\n!_TAG_ROLE_DESCRIPTION!RpmSpec!patch\tdecl\t/declared for applying later/\n!_TAG_ROLE_DESCRIPTION!Ruby!library\tloaded\t/loaded by \"load\" method/\n!_TAG_ROLE_DESCRIPTION!Ruby!library\trequired\t/loaded by \"require\" method/\n!_TAG_ROLE_DESCRIPTION!Ruby!library\trequiredRel\t/loaded by \"require_relative\" method/\n!_TAG_ROLE_DESCRIPTION!Sh!heredoc\tendmarker\t/end marker/\n!_TAG_ROLE_DESCRIPTION!Sh!script\tloaded\t/loaded/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tAfter\t/referred in After key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tBefore\t/referred in Before key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tRequiredBy\t/referred in RequiredBy key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tRequires\t/referred in Requires key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tWantedBy\t/referred in WantedBy key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tWants\t/referred in Wants key/\n!_TAG_ROLE_DESCRIPTION!Yaml!anchor\talias\t/alias/\n!_TAG_ROLE_DESCRIPTION!Zsh!function\tautoloaded\t/function name passed to autoload built-in command/\n!_TAG_ROLE_DESCRIPTION!Zsh!heredoc\tendmarker\t/end marker/\n!_TAG_ROLE_DESCRIPTION!Zsh!script\tautoloaded\t/autoloaded/\n!_TAG_ROLE_DESCRIPTION!Zsh!script\tloaded\t/loaded/\nzr\t/home/yamato/var/podman/vendor/golang.org/x/net/http2/transport.go\t/^\tzr   *gzip.Reader  \\/\\/ lazily-initialized gzip reader$/;\"\tm\tstruct:http2.gzipReader\ttyperef:typename:*gzip.Reader\n"
  },
  {
    "path": "Tmain/readtags-ptags-dls.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '# FILTER' &&\n${V} ${READTAGS} -t input.tags -Q '(#/.*CWD.*/ $name)' -D &&\n\necho '# FORMATTER' &&\n${V} ${READTAGS} -t input.tags -Q '(#/.*CWD.*/ $name)' -F '(list $input #t)' -D &&\n\necho '# SORTING INPUT' &&\n${V} ${READTAGS} -t input.tags -S '(<or> (<> $input &input) (<> $name &name))' -D &&\n\necho '# SORTING ! INPUT' &&\n${V} ${READTAGS} -t input.tags -S '(*- (<or> (<> $input &input) (<> $name &name)))' -D\n"
  },
  {
    "path": "Tmain/readtags-ptags-dls.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-ptags-dls.d/stdout-expected.txt",
    "content": "# FILTER\n!_TAG_PROC_CWD\t/home/yamato/var/ctags-github/\t//\n# FORMATTER\n/home/yamato/var/ctags-github/\n# SORTING INPUT\n!_TAG_PROC_CWD\t/home/yamato/var/ctags-github/\t//\n!_TAG_OUTPUT_VERSION\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Asciidoc\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Awk\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Bats\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!CSS\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!DTD\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Diff\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!DosBatch\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Go\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!HTML\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Iniconf\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!JSON\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Lua\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Man\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!OpenAPI\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Perl\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Pod\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Protobuf\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Python\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!R\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!ReStructuredText\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!RpmSpec\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Ruby\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!SVG\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Sh\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!SystemdUnit\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!TOML\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!XML\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Yaml\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Zsh\t0.0\t/current.age/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PARSER_VERSION!Asm\t1.0\t/current.age/\n!_TAG_PARSER_VERSION!C\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!C++\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!Make\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!Markdown\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!PowerShell\t1.1\t/current.age/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_PROGRAM_VERSION\t6.1.0\t/d1ecc51b9/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_KIND_DESCRIPTION!Ruby\tA,accessor\t/accessors/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tAfter\t/referred in After key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tBefore\t/referred in Before key/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tC,citation\t/citations/\n!_TAG_KIND_DESCRIPTION!Ruby\tC,constant\t/constants/\n!_TAG_KIND_DESCRIPTION!HTML\tC,stylesheet\t/stylesheets/\n!_TAG_KIND_DESCRIPTION!Protobuf\tD,protodef\t/.proto definition/\n!_TAG_KIND_DESCRIPTION!DTD\tE,entity\t/entities/\n!_TAG_KIND_DESCRIPTION!Protobuf\tG,group\t/groups/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tH,title\t/titles/\n!_TAG_KIND_DESCRIPTION!HTML\tI,id\t/identifiers/\n!_TAG_KIND_DESCRIPTION!Make\tI,makefile\t/makefiles/\n!_TAG_KIND_DESCRIPTION!Python\tI,namespace\t/name referring a module defined in other file/\n!_TAG_KIND_DESCRIPTION!HTML\tJ,script\t/scripts/\n!_TAG_KIND_DESCRIPTION!TOML\tK,qkey\t/qualified keys/\n!_TAG_KIND_DESCRIPTION!Ruby\tL,library\t/libraries/\n!_TAG_KIND_DESCRIPTION!R\tL,list\t/lists explicitly created with `list()'/\n!_TAG_KIND_DESCRIPTION!Go\tM,anonMember\t/struct anonymous members/\n!_TAG_KIND_DESCRIPTION!C++\tM,module\t/modules/\n!_TAG_KIND_DESCRIPTION!Go\tP,packageName\t/name for specifying imported package/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tP,parameter\t/parameters/\n!_TAG_KIND_DESCRIPTION!C++\tP,partition\t/partitions/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tR,response\t/responses/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tRequiredBy\t/referred in RequiredBy key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tRequires\t/referred in Requires key/\n!_TAG_KIND_DESCRIPTION!Bats\tS,script\t/scripts/\n!_TAG_KIND_DESCRIPTION!Ruby\tS,singletonMethod\t/singleton methods/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tS,subsection\t/level 2 sections/\n!_TAG_KIND_DESCRIPTION!Man\tS,subsection\t/sub sections/\n!_TAG_KIND_DESCRIPTION!Markdown\tS,subsection\t/level 2 sections/\n!_TAG_KIND_DESCRIPTION!Pod\tS,subsection\t/subsections/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tS,subsection\t/subsections/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tT,l4subsection\t/level 4 sections/\n!_TAG_KIND_DESCRIPTION!Markdown\tT,l4subsection\t/level 4 sections/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tT,tag\t/tags/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tT,target\t/targets/\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tWantedBy\t/referred in WantedBy key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tWants\t/referred in Wants key/\n!_TAG_KIND_DESCRIPTION!Go\tY,unknown\t/unknown/\n!_TAG_KIND_DESCRIPTION!Python\tY,unknown\t/name referring a class\\/variable\\/function\\/module defined in other module/\n!_TAG_KIND_DESCRIPTION!Ruby\ta,alias\t/aliases/\n!_TAG_KIND_DESCRIPTION!Sh\ta,alias\t/aliases/\n!_TAG_KIND_DESCRIPTION!Zsh\ta,alias\t/aliases/\n!_TAG_KIND_DESCRIPTION!Asciidoc\ta,anchor\t/anchors/\n!_TAG_KIND_DESCRIPTION!HTML\ta,anchor\t/named anchors/\n!_TAG_KIND_DESCRIPTION!Yaml\ta,anchor\t/anchors/\n!_TAG_KIND_DESCRIPTION!JSON\ta,array\t/arrays/\n!_TAG_KIND_DESCRIPTION!TOML\ta,arraytable\t/array tables/\n!_TAG_KIND_DESCRIPTION!DTD\ta,attribute\t/attributes/\n!_TAG_KIND_DESCRIPTION!Go\ta,talias\t/type aliases/\n!_TAG_ROLE_DESCRIPTION!Yaml!anchor\talias\t/alias/\n!_TAG_EXTRA_DESCRIPTION\tanonymous\t/Include tags for non-named objects like lambda/\n!_TAG_ROLE_DESCRIPTION!DTD!element\tattOwner\t/attributes owner/\n!_TAG_ROLE_DESCRIPTION!HTML!class\tattribute\t/assigned as attributes/\n!_TAG_ROLE_DESCRIPTION!Zsh!function\tautoloaded\t/function name passed to autoload built-in command/\n!_TAG_ROLE_DESCRIPTION!Zsh!script\tautoloaded\t/autoloaded/\n!_TAG_KIND_DESCRIPTION!JSON\tb,boolean\t/booleans/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!Markdown\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!Pod\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!C++\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!CSS\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!HTML\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!PowerShell\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!Python\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!Ruby\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!Go\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!Perl\tc,constant\t/constants/\n!_TAG_KIND_DESCRIPTION!R\tc,vector\t/vectors explicitly created with `c()'/\n!_TAG_ROLE_DESCRIPTION!DTD!parameterEntity\tcondition\t/conditions/\n!_TAG_FIELD_DESCRIPTION!R\tconstructor\t/function used for making value assigned to the nameattr tag/\n!_TAG_KIND_DESCRIPTION!R\td,dataframe\t/data frame explicitly created with `data.frame()'/\n!_TAG_KIND_DESCRIPTION!SVG\td,def\t/ids in defs tags/\n!_TAG_KIND_DESCRIPTION!Asm\td,define\t/defines/\n!_TAG_KIND_DESCRIPTION!Diff\td,deletedFile\t/deleted files/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C++\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!OpenAPI\td,schema\t/schemas/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\td,substdef\t/substitute definitions/\n!_TAG_ROLE_DESCRIPTION!RpmSpec!patch\tdecl\t/declared for applying later/\n!_TAG_KIND_DESCRIPTION!DTD\te,element\t/elements/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C++\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!Protobuf\te,enumerator\t/enum constants/\n!_TAG_KIND_DESCRIPTION!PowerShell\te,enumlabel\t/enum labels/\n!_TAG_ROLE_DESCRIPTION!DTD!parameterEntity\telementName\t/element names/\n!_TAG_ROLE_DESCRIPTION!Sh!heredoc\tendmarker\t/end marker/\n!_TAG_ROLE_DESCRIPTION!Zsh!heredoc\tendmarker\t/end marker/\n!_TAG_FIELD_DESCRIPTION\tepoch\t/the last modified time of the input file (only for F\\/file kind tag)/\n!_TAG_ROLE_DESCRIPTION!C++!header\texported\t/exported with \"exported imported ...\"/\n!_TAG_ROLE_DESCRIPTION!HTML!script\textFile\t/referenced as external files/\n!_TAG_ROLE_DESCRIPTION!HTML!stylesheet\textFile\t/referenced as external files/\n!_TAG_ROLE_DESCRIPTION!Protobuf!message\textension\t/extending the message/\n!_TAG_KIND_DESCRIPTION!Protobuf\tf,field\t/fields/\n!_TAG_KIND_DESCRIPTION!Perl\tf,format\t/formats/\n!_TAG_KIND_DESCRIPTION!Go\tf,func\t/functions/\n!_TAG_KIND_DESCRIPTION!Awk\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C++\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!Lua\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!PowerShell\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Python\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!R\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Sh\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Zsh\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Ruby\tf,method\t/methods/\n!_TAG_FIELD_DESCRIPTION\tfile\t/File-restricted scoping/\n!_TAG_EXTRA_DESCRIPTION\tfileScope\t/Include tags of file scope/\n!_TAG_ROLE_DESCRIPTION!C!function\tforeigndecl\t/declared in foreign languages/\n!_TAG_ROLE_DESCRIPTION!C!struct\tforeigndecl\t/declared in foreign languages/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C++\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!PowerShell\tg,enum\t/enum names/\n!_TAG_KIND_DESCRIPTION!Protobuf\tg,enum\t/enum types/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tg,global\t/global macros/\n!_TAG_KIND_DESCRIPTION!R\tg,globalVar\t/global variables having values other than function()/\n!_TAG_KIND_DESCRIPTION!Markdown\th,hashtag\t/hashtags/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C++\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!HTML\th,heading1\t/H1 headings/\n!_TAG_KIND_DESCRIPTION!Sh\th,heredoc\t/label for here document/\n!_TAG_KIND_DESCRIPTION!Zsh\th,heredoc\t/label for here document/\n!_TAG_KIND_DESCRIPTION!Diff\th,hunk\t/hunks/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\th,subtitle\t/sub titles/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_KIND_DESCRIPTION!PowerShell\ti,filter\t/filter/\n!_TAG_KIND_DESCRIPTION!HTML\ti,heading2\t/H2 headings/\n!_TAG_KIND_DESCRIPTION!CSS\ti,id\t/identities/\n!_TAG_KIND_DESCRIPTION!XML\ti,id\t/id attributes/\n!_TAG_KIND_DESCRIPTION!Go\ti,interface\t/interfaces/\n!_TAG_KIND_DESCRIPTION!Python\ti,module\t/modules/\n!_TAG_ROLE_DESCRIPTION!C++!header\timported\t/imported with \"imported ...\"/\n!_TAG_ROLE_DESCRIPTION!C++!module\timported\t/imported with \"imported ...\"/\n!_TAG_ROLE_DESCRIPTION!C++!partition\timported\t/imported with \"imported ...\"/\n!_TAG_ROLE_DESCRIPTION!Go!package\timported\t/imported package/\n!_TAG_ROLE_DESCRIPTION!Protobuf!protodef\timported\t/imported/\n!_TAG_ROLE_DESCRIPTION!Python!module\timported\t/imported modules/\n!_TAG_ROLE_DESCRIPTION!Python!unknown\timported\t/imported from the other module/\n!_TAG_ROLE_DESCRIPTION!Make!makefile\tincluded\t/included/\n!_TAG_ROLE_DESCRIPTION!Python!module\tindirectlyImported\t/module imported in alternative name/\n!_TAG_ROLE_DESCRIPTION!Python!unknown\tindirectlyImported\t/classes\\/variables\\/functions\\/modules imported in alternative name/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_KIND_DESCRIPTION!HTML\tj,heading3\t/H3 headings/\n!_TAG_KIND_DESCRIPTION!Iniconf\tk,key\t/keys/\n!_TAG_KIND_DESCRIPTION!Asm\tl,label\t/labels/\n!_TAG_KIND_DESCRIPTION!DosBatch\tl,label\t/labels/\n!_TAG_KIND_DESCRIPTION!Perl\tl,label\t/labels/\n!_TAG_KIND_DESCRIPTION!R\tl,library\t/libraries/\n!_TAG_ROLE_DESCRIPTION!R!library\tlibrary\t/library attached by library function/\n!_TAG_ROLE_DESCRIPTION!Bats!script\tloaded\t/script loaed with \"load\" command/\n!_TAG_ROLE_DESCRIPTION!Ruby!library\tloaded\t/loaded by \"load\" method/\n!_TAG_ROLE_DESCRIPTION!Sh!script\tloaded\t/loaded/\n!_TAG_ROLE_DESCRIPTION!Zsh!script\tloaded\t/loaded/\n!_TAG_ROLE_DESCRIPTION!C!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C++!header\tlocal\t/local header/\n!_TAG_KIND_DESCRIPTION!Asm\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!Make\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C++\tm,member\t/class, struct, and union members/\n!_TAG_KIND_DESCRIPTION!Go\tm,member\t/struct members/\n!_TAG_KIND_DESCRIPTION!Python\tm,member\t/class members/\n!_TAG_KIND_DESCRIPTION!Protobuf\tm,message\t/messages/\n!_TAG_KIND_DESCRIPTION!Diff\tm,modifiedFile\t/modified files/\n!_TAG_KIND_DESCRIPTION!Ruby\tm,module\t/modules/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_FIELD_DESCRIPTION!Ruby\tmixin\t/how the class or module is mixed in (mixin:HOW:MODULE)/\n!_TAG_KIND_DESCRIPTION!Markdown\tn,footnote\t/footnotes/\n!_TAG_KIND_DESCRIPTION!Go\tn,methodSpec\t/interface method specification/\n!_TAG_KIND_DESCRIPTION!R\tn,nameattr\t/names attribtes in vectors, lists, or dataframes/\n!_TAG_KIND_DESCRIPTION!C++\tn,namespace\t/namespaces/\n!_TAG_KIND_DESCRIPTION!Diff\tn,newFile\t/newly created files/\n!_TAG_KIND_DESCRIPTION!DTD\tn,notation\t/notations/\n!_TAG_KIND_DESCRIPTION!XML\tn,nsprefix\t/namespace prefixes/\n!_TAG_KIND_DESCRIPTION!JSON\tn,number\t/numbers/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_FIELD_DESCRIPTION!C++\tname\t/aliased names/\n!_TAG_FIELD_DESCRIPTION!Python\tnameref\t/the original name for the tag/\n!_TAG_ROLE_DESCRIPTION!Python!module\tnamespace\t/namespace from where classes\\/variables\\/functions are imported/\n!_TAG_KIND_DESCRIPTION!JSON\to,object\t/objects/\n!_TAG_KIND_DESCRIPTION!Protobuf\to,oneof\t/oneof names/\n!_TAG_ROLE_DESCRIPTION!Make!makefile\toptional\t/optionally included/\n!_TAG_KIND_DESCRIPTION!Go\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!Perl\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!Protobuf\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!DTD\tp,parameterEntity\t/parameter entities/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tp,patch\t/patch files/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tp,path\t/paths/\n!_TAG_FIELD_DESCRIPTION!Go\tpackage\t/the real package specified by the package name/\n!_TAG_FIELD_DESCRIPTION!Go\tpackageName\t/the name for referring the package/\n!_TAG_ROLE_DESCRIPTION!DTD!parameterEntity\tpartOfAttDef\t/part of attribute definition/\n!_TAG_ROLE_DESCRIPTION!C++!module\tpartOwner\t/used for specifying a partition/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_FIELD_DESCRIPTION!Asm\tproperties\t/properties (req, vararg for parameters)/\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_KIND_DESCRIPTION!XML\tr,root\t/root elements/\n!_TAG_KIND_DESCRIPTION!Protobuf\tr,rpc\t/RPC methods/\n!_TAG_ROLE_DESCRIPTION!Go!unknown\treceiverType\t/receiver type/\n!_TAG_ROLE_DESCRIPTION!R!library\trequire\t/library attached by require function/\n!_TAG_ROLE_DESCRIPTION!Ruby!library\trequired\t/loaded by \"require\" method/\n!_TAG_ROLE_DESCRIPTION!Ruby!library\trequiredRel\t/loaded by \"require_relative\" method/\n!_TAG_KIND_DESCRIPTION!Sh\ts,script\t/script files/\n!_TAG_KIND_DESCRIPTION!Zsh\ts,script\t/script files/\n!_TAG_KIND_DESCRIPTION!Asciidoc\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Iniconf\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Man\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Markdown\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Pod\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!CSS\ts,selector\t/selectors/\n!_TAG_KIND_DESCRIPTION!OpenAPI\ts,server\t/servers (or hosts in swagger)/\n!_TAG_KIND_DESCRIPTION!Protobuf\ts,service\t/services/\n!_TAG_KIND_DESCRIPTION!R\ts,source\t/sources/\n!_TAG_KIND_DESCRIPTION!JSON\ts,string\t/strings/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C++\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!Go\ts,struct\t/structs/\n!_TAG_KIND_DESCRIPTION!Perl\ts,subroutine\t/subroutines/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_ROLE_DESCRIPTION!R!source\tsource\t/source loaded by source fucntion/\n!_TAG_EXTRA_DESCRIPTION\tsubparser\t/Include tags generated by subparsers/\n!_TAG_ROLE_DESCRIPTION!C!header\tsystem\t/system header/\n!_TAG_ROLE_DESCRIPTION!C++!header\tsystem\t/system header/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tt,subsubsection\t/level 3 sections/\n!_TAG_KIND_DESCRIPTION!Markdown\tt,subsubsection\t/level 3 sections/\n!_TAG_KIND_DESCRIPTION!Pod\tt,subsubsection\t/subsubsections/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tt,subsubsection\t/subsubsections/\n!_TAG_KIND_DESCRIPTION!TOML\tt,table\t/tables/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tt,tag\t/tags/\n!_TAG_KIND_DESCRIPTION!Make\tt,target\t/targets/\n!_TAG_KIND_DESCRIPTION!Bats\tt,test\t/test cases/\n!_TAG_KIND_DESCRIPTION!HTML\tt,title\t/titles/\n!_TAG_KIND_DESCRIPTION!Man\tt,title\t/titles/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tt,title\t/titles/\n!_TAG_KIND_DESCRIPTION!Asm\tt,type\t/types (structs and records)/\n!_TAG_KIND_DESCRIPTION!Go\tt,type\t/types/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C++\tt,typedef\t/typedefs/\n!_TAG_FIELD_DESCRIPTION\ttyperef\t/Type and name of a variable or typedef/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tu,l5subsection\t/level 5 sections/\n!_TAG_KIND_DESCRIPTION!Markdown\tu,l5subsection\t/level 5 sections/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C++\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!SystemdUnit\tu,unit\t/units/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_ROLE_DESCRIPTION!C!macro\tundef\t/undefined/\n!_TAG_ROLE_DESCRIPTION!C++!macro\tundef\t/undefined/\n!_TAG_ROLE_DESCRIPTION!RpmSpec!macro\tundef\t/undefined/\n!_TAG_FIELD_DESCRIPTION!XML\turi\t/uri associated with name prefix/\n!_TAG_KIND_DESCRIPTION!R\tv,functionVar\t/function variables having values other than function()/\n!_TAG_KIND_DESCRIPTION!Go\tv,var\t/variables/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C++\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!DosBatch\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!PowerShell\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!Python\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!JSON\tz,null\t/nulls/\n# SORTING ! INPUT\n!_TAG_KIND_DESCRIPTION!JSON\tz,null\t/nulls/\n!_TAG_KIND_DESCRIPTION!Python\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!PowerShell\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!DosBatch\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!C++\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!Go\tv,var\t/variables/\n!_TAG_KIND_DESCRIPTION!R\tv,functionVar\t/function variables having values other than function()/\n!_TAG_FIELD_DESCRIPTION!XML\turi\t/uri associated with name prefix/\n!_TAG_ROLE_DESCRIPTION!RpmSpec!macro\tundef\t/undefined/\n!_TAG_ROLE_DESCRIPTION!C++!macro\tundef\t/undefined/\n!_TAG_ROLE_DESCRIPTION!C!macro\tundef\t/undefined/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_KIND_DESCRIPTION!SystemdUnit\tu,unit\t/units/\n!_TAG_KIND_DESCRIPTION!C++\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!Markdown\tu,l5subsection\t/level 5 sections/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tu,l5subsection\t/level 5 sections/\n!_TAG_FIELD_DESCRIPTION\ttyperef\t/Type and name of a variable or typedef/\n!_TAG_KIND_DESCRIPTION!C++\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!Go\tt,type\t/types/\n!_TAG_KIND_DESCRIPTION!Asm\tt,type\t/types (structs and records)/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tt,title\t/titles/\n!_TAG_KIND_DESCRIPTION!Man\tt,title\t/titles/\n!_TAG_KIND_DESCRIPTION!HTML\tt,title\t/titles/\n!_TAG_KIND_DESCRIPTION!Bats\tt,test\t/test cases/\n!_TAG_KIND_DESCRIPTION!Make\tt,target\t/targets/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tt,tag\t/tags/\n!_TAG_KIND_DESCRIPTION!TOML\tt,table\t/tables/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tt,subsubsection\t/subsubsections/\n!_TAG_KIND_DESCRIPTION!Pod\tt,subsubsection\t/subsubsections/\n!_TAG_KIND_DESCRIPTION!Markdown\tt,subsubsection\t/level 3 sections/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tt,subsubsection\t/level 3 sections/\n!_TAG_ROLE_DESCRIPTION!C++!header\tsystem\t/system header/\n!_TAG_ROLE_DESCRIPTION!C!header\tsystem\t/system header/\n!_TAG_EXTRA_DESCRIPTION\tsubparser\t/Include tags generated by subparsers/\n!_TAG_ROLE_DESCRIPTION!R!source\tsource\t/source loaded by source fucntion/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_KIND_DESCRIPTION!Perl\ts,subroutine\t/subroutines/\n!_TAG_KIND_DESCRIPTION!Go\ts,struct\t/structs/\n!_TAG_KIND_DESCRIPTION!C++\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!JSON\ts,string\t/strings/\n!_TAG_KIND_DESCRIPTION!R\ts,source\t/sources/\n!_TAG_KIND_DESCRIPTION!Protobuf\ts,service\t/services/\n!_TAG_KIND_DESCRIPTION!OpenAPI\ts,server\t/servers (or hosts in swagger)/\n!_TAG_KIND_DESCRIPTION!CSS\ts,selector\t/selectors/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Pod\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Markdown\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Man\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Iniconf\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Asciidoc\ts,section\t/sections/\n!_TAG_KIND_DESCRIPTION!Zsh\ts,script\t/script files/\n!_TAG_KIND_DESCRIPTION!Sh\ts,script\t/script files/\n!_TAG_ROLE_DESCRIPTION!Ruby!library\trequiredRel\t/loaded by \"require_relative\" method/\n!_TAG_ROLE_DESCRIPTION!Ruby!library\trequired\t/loaded by \"require\" method/\n!_TAG_ROLE_DESCRIPTION!R!library\trequire\t/library attached by require function/\n!_TAG_ROLE_DESCRIPTION!Go!unknown\treceiverType\t/receiver type/\n!_TAG_KIND_DESCRIPTION!Protobuf\tr,rpc\t/RPC methods/\n!_TAG_KIND_DESCRIPTION!XML\tr,root\t/root elements/\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_FIELD_DESCRIPTION!Asm\tproperties\t/properties (req, vararg for parameters)/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_ROLE_DESCRIPTION!C++!module\tpartOwner\t/used for specifying a partition/\n!_TAG_ROLE_DESCRIPTION!DTD!parameterEntity\tpartOfAttDef\t/part of attribute definition/\n!_TAG_FIELD_DESCRIPTION!Go\tpackageName\t/the name for referring the package/\n!_TAG_FIELD_DESCRIPTION!Go\tpackage\t/the real package specified by the package name/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tp,path\t/paths/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tp,patch\t/patch files/\n!_TAG_KIND_DESCRIPTION!DTD\tp,parameterEntity\t/parameter entities/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!Protobuf\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!Perl\tp,package\t/packages/\n!_TAG_KIND_DESCRIPTION!Go\tp,package\t/packages/\n!_TAG_ROLE_DESCRIPTION!Make!makefile\toptional\t/optionally included/\n!_TAG_KIND_DESCRIPTION!Protobuf\to,oneof\t/oneof names/\n!_TAG_KIND_DESCRIPTION!JSON\to,object\t/objects/\n!_TAG_ROLE_DESCRIPTION!Python!module\tnamespace\t/namespace from where classes\\/variables\\/functions are imported/\n!_TAG_FIELD_DESCRIPTION!Python\tnameref\t/the original name for the tag/\n!_TAG_FIELD_DESCRIPTION!C++\tname\t/aliased names/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_KIND_DESCRIPTION!JSON\tn,number\t/numbers/\n!_TAG_KIND_DESCRIPTION!XML\tn,nsprefix\t/namespace prefixes/\n!_TAG_KIND_DESCRIPTION!DTD\tn,notation\t/notations/\n!_TAG_KIND_DESCRIPTION!Diff\tn,newFile\t/newly created files/\n!_TAG_KIND_DESCRIPTION!C++\tn,namespace\t/namespaces/\n!_TAG_KIND_DESCRIPTION!R\tn,nameattr\t/names attribtes in vectors, lists, or dataframes/\n!_TAG_KIND_DESCRIPTION!Go\tn,methodSpec\t/interface method specification/\n!_TAG_KIND_DESCRIPTION!Markdown\tn,footnote\t/footnotes/\n!_TAG_FIELD_DESCRIPTION!Ruby\tmixin\t/how the class or module is mixed in (mixin:HOW:MODULE)/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_KIND_DESCRIPTION!Ruby\tm,module\t/modules/\n!_TAG_KIND_DESCRIPTION!Diff\tm,modifiedFile\t/modified files/\n!_TAG_KIND_DESCRIPTION!Protobuf\tm,message\t/messages/\n!_TAG_KIND_DESCRIPTION!Python\tm,member\t/class members/\n!_TAG_KIND_DESCRIPTION!Go\tm,member\t/struct members/\n!_TAG_KIND_DESCRIPTION!C++\tm,member\t/class, struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!Make\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!Asm\tm,macro\t/macros/\n!_TAG_ROLE_DESCRIPTION!C++!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!Zsh!script\tloaded\t/loaded/\n!_TAG_ROLE_DESCRIPTION!Sh!script\tloaded\t/loaded/\n!_TAG_ROLE_DESCRIPTION!Ruby!library\tloaded\t/loaded by \"load\" method/\n!_TAG_ROLE_DESCRIPTION!Bats!script\tloaded\t/script loaed with \"load\" command/\n!_TAG_ROLE_DESCRIPTION!R!library\tlibrary\t/library attached by library function/\n!_TAG_KIND_DESCRIPTION!R\tl,library\t/libraries/\n!_TAG_KIND_DESCRIPTION!Perl\tl,label\t/labels/\n!_TAG_KIND_DESCRIPTION!DosBatch\tl,label\t/labels/\n!_TAG_KIND_DESCRIPTION!Asm\tl,label\t/labels/\n!_TAG_KIND_DESCRIPTION!Iniconf\tk,key\t/keys/\n!_TAG_KIND_DESCRIPTION!HTML\tj,heading3\t/H3 headings/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_ROLE_DESCRIPTION!Python!unknown\tindirectlyImported\t/classes\\/variables\\/functions\\/modules imported in alternative name/\n!_TAG_ROLE_DESCRIPTION!Python!module\tindirectlyImported\t/module imported in alternative name/\n!_TAG_ROLE_DESCRIPTION!Make!makefile\tincluded\t/included/\n!_TAG_ROLE_DESCRIPTION!Python!unknown\timported\t/imported from the other module/\n!_TAG_ROLE_DESCRIPTION!Python!module\timported\t/imported modules/\n!_TAG_ROLE_DESCRIPTION!Protobuf!protodef\timported\t/imported/\n!_TAG_ROLE_DESCRIPTION!Go!package\timported\t/imported package/\n!_TAG_ROLE_DESCRIPTION!C++!partition\timported\t/imported with \"imported ...\"/\n!_TAG_ROLE_DESCRIPTION!C++!module\timported\t/imported with \"imported ...\"/\n!_TAG_ROLE_DESCRIPTION!C++!header\timported\t/imported with \"imported ...\"/\n!_TAG_KIND_DESCRIPTION!Python\ti,module\t/modules/\n!_TAG_KIND_DESCRIPTION!Go\ti,interface\t/interfaces/\n!_TAG_KIND_DESCRIPTION!XML\ti,id\t/id attributes/\n!_TAG_KIND_DESCRIPTION!CSS\ti,id\t/identities/\n!_TAG_KIND_DESCRIPTION!HTML\ti,heading2\t/H2 headings/\n!_TAG_KIND_DESCRIPTION!PowerShell\ti,filter\t/filter/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\th,subtitle\t/sub titles/\n!_TAG_KIND_DESCRIPTION!Diff\th,hunk\t/hunks/\n!_TAG_KIND_DESCRIPTION!Zsh\th,heredoc\t/label for here document/\n!_TAG_KIND_DESCRIPTION!Sh\th,heredoc\t/label for here document/\n!_TAG_KIND_DESCRIPTION!HTML\th,heading1\t/H1 headings/\n!_TAG_KIND_DESCRIPTION!C++\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!Markdown\th,hashtag\t/hashtags/\n!_TAG_KIND_DESCRIPTION!R\tg,globalVar\t/global variables having values other than function()/\n!_TAG_KIND_DESCRIPTION!RpmSpec\tg,global\t/global macros/\n!_TAG_KIND_DESCRIPTION!Protobuf\tg,enum\t/enum types/\n!_TAG_KIND_DESCRIPTION!PowerShell\tg,enum\t/enum names/\n!_TAG_KIND_DESCRIPTION!C++\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_ROLE_DESCRIPTION!C!struct\tforeigndecl\t/declared in foreign languages/\n!_TAG_ROLE_DESCRIPTION!C!function\tforeigndecl\t/declared in foreign languages/\n!_TAG_EXTRA_DESCRIPTION\tfileScope\t/Include tags of file scope/\n!_TAG_FIELD_DESCRIPTION\tfile\t/File-restricted scoping/\n!_TAG_KIND_DESCRIPTION!Ruby\tf,method\t/methods/\n!_TAG_KIND_DESCRIPTION!Zsh\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Sh\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!R\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Python\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!PowerShell\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Lua\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!C++\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!Awk\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!Go\tf,func\t/functions/\n!_TAG_KIND_DESCRIPTION!Perl\tf,format\t/formats/\n!_TAG_KIND_DESCRIPTION!Protobuf\tf,field\t/fields/\n!_TAG_ROLE_DESCRIPTION!Protobuf!message\textension\t/extending the message/\n!_TAG_ROLE_DESCRIPTION!HTML!stylesheet\textFile\t/referenced as external files/\n!_TAG_ROLE_DESCRIPTION!HTML!script\textFile\t/referenced as external files/\n!_TAG_ROLE_DESCRIPTION!C++!header\texported\t/exported with \"exported imported ...\"/\n!_TAG_FIELD_DESCRIPTION\tepoch\t/the last modified time of the input file (only for F\\/file kind tag)/\n!_TAG_ROLE_DESCRIPTION!Zsh!heredoc\tendmarker\t/end marker/\n!_TAG_ROLE_DESCRIPTION!Sh!heredoc\tendmarker\t/end marker/\n!_TAG_ROLE_DESCRIPTION!DTD!parameterEntity\telementName\t/element names/\n!_TAG_KIND_DESCRIPTION!PowerShell\te,enumlabel\t/enum labels/\n!_TAG_KIND_DESCRIPTION!Protobuf\te,enumerator\t/enum constants/\n!_TAG_KIND_DESCRIPTION!C++\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!DTD\te,element\t/elements/\n!_TAG_ROLE_DESCRIPTION!RpmSpec!patch\tdecl\t/declared for applying later/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\td,substdef\t/substitute definitions/\n!_TAG_KIND_DESCRIPTION!OpenAPI\td,schema\t/schemas/\n!_TAG_KIND_DESCRIPTION!C++\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!Diff\td,deletedFile\t/deleted files/\n!_TAG_KIND_DESCRIPTION!Asm\td,define\t/defines/\n!_TAG_KIND_DESCRIPTION!SVG\td,def\t/ids in defs tags/\n!_TAG_KIND_DESCRIPTION!R\td,dataframe\t/data frame explicitly created with `data.frame()'/\n!_TAG_FIELD_DESCRIPTION!R\tconstructor\t/function used for making value assigned to the nameattr tag/\n!_TAG_ROLE_DESCRIPTION!DTD!parameterEntity\tcondition\t/conditions/\n!_TAG_KIND_DESCRIPTION!R\tc,vector\t/vectors explicitly created with `c()'/\n!_TAG_KIND_DESCRIPTION!Perl\tc,constant\t/constants/\n!_TAG_KIND_DESCRIPTION!Go\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!Ruby\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!Python\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!PowerShell\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!HTML\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!CSS\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!C++\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!Pod\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!Markdown\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tc,chapter\t/chapters/\n!_TAG_KIND_DESCRIPTION!JSON\tb,boolean\t/booleans/\n!_TAG_ROLE_DESCRIPTION!Zsh!script\tautoloaded\t/autoloaded/\n!_TAG_ROLE_DESCRIPTION!Zsh!function\tautoloaded\t/function name passed to autoload built-in command/\n!_TAG_ROLE_DESCRIPTION!HTML!class\tattribute\t/assigned as attributes/\n!_TAG_ROLE_DESCRIPTION!DTD!element\tattOwner\t/attributes owner/\n!_TAG_EXTRA_DESCRIPTION\tanonymous\t/Include tags for non-named objects like lambda/\n!_TAG_ROLE_DESCRIPTION!Yaml!anchor\talias\t/alias/\n!_TAG_KIND_DESCRIPTION!Go\ta,talias\t/type aliases/\n!_TAG_KIND_DESCRIPTION!DTD\ta,attribute\t/attributes/\n!_TAG_KIND_DESCRIPTION!TOML\ta,arraytable\t/array tables/\n!_TAG_KIND_DESCRIPTION!JSON\ta,array\t/arrays/\n!_TAG_KIND_DESCRIPTION!Yaml\ta,anchor\t/anchors/\n!_TAG_KIND_DESCRIPTION!HTML\ta,anchor\t/named anchors/\n!_TAG_KIND_DESCRIPTION!Asciidoc\ta,anchor\t/anchors/\n!_TAG_KIND_DESCRIPTION!Zsh\ta,alias\t/aliases/\n!_TAG_KIND_DESCRIPTION!Sh\ta,alias\t/aliases/\n!_TAG_KIND_DESCRIPTION!Ruby\ta,alias\t/aliases/\n!_TAG_KIND_DESCRIPTION!Python\tY,unknown\t/name referring a class\\/variable\\/function\\/module defined in other module/\n!_TAG_KIND_DESCRIPTION!Go\tY,unknown\t/unknown/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tWants\t/referred in Wants key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tWantedBy\t/referred in WantedBy key/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tT,target\t/targets/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tT,tag\t/tags/\n!_TAG_KIND_DESCRIPTION!Markdown\tT,l4subsection\t/level 4 sections/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tT,l4subsection\t/level 4 sections/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tS,subsection\t/subsections/\n!_TAG_KIND_DESCRIPTION!Pod\tS,subsection\t/subsections/\n!_TAG_KIND_DESCRIPTION!Markdown\tS,subsection\t/level 2 sections/\n!_TAG_KIND_DESCRIPTION!Man\tS,subsection\t/sub sections/\n!_TAG_KIND_DESCRIPTION!Asciidoc\tS,subsection\t/level 2 sections/\n!_TAG_KIND_DESCRIPTION!Ruby\tS,singletonMethod\t/singleton methods/\n!_TAG_KIND_DESCRIPTION!Bats\tS,script\t/scripts/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tRequires\t/referred in Requires key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tRequiredBy\t/referred in RequiredBy key/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tR,response\t/responses/\n!_TAG_KIND_DESCRIPTION!C++\tP,partition\t/partitions/\n!_TAG_KIND_DESCRIPTION!OpenAPI\tP,parameter\t/parameters/\n!_TAG_KIND_DESCRIPTION!Go\tP,packageName\t/name for specifying imported package/\n!_TAG_KIND_DESCRIPTION!C++\tM,module\t/modules/\n!_TAG_KIND_DESCRIPTION!Go\tM,anonMember\t/struct anonymous members/\n!_TAG_KIND_DESCRIPTION!R\tL,list\t/lists explicitly created with `list()'/\n!_TAG_KIND_DESCRIPTION!Ruby\tL,library\t/libraries/\n!_TAG_KIND_DESCRIPTION!TOML\tK,qkey\t/qualified keys/\n!_TAG_KIND_DESCRIPTION!HTML\tJ,script\t/scripts/\n!_TAG_KIND_DESCRIPTION!Python\tI,namespace\t/name referring a module defined in other file/\n!_TAG_KIND_DESCRIPTION!Make\tI,makefile\t/makefiles/\n!_TAG_KIND_DESCRIPTION!HTML\tI,id\t/identifiers/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tH,title\t/titles/\n!_TAG_KIND_DESCRIPTION!Protobuf\tG,group\t/groups/\n!_TAG_KIND_DESCRIPTION!DTD\tE,entity\t/entities/\n!_TAG_KIND_DESCRIPTION!Protobuf\tD,protodef\t/.proto definition/\n!_TAG_KIND_DESCRIPTION!HTML\tC,stylesheet\t/stylesheets/\n!_TAG_KIND_DESCRIPTION!Ruby\tC,constant\t/constants/\n!_TAG_KIND_DESCRIPTION!ReStructuredText\tC,citation\t/citations/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tBefore\t/referred in Before key/\n!_TAG_ROLE_DESCRIPTION!SystemdUnit!unit\tAfter\t/referred in After key/\n!_TAG_KIND_DESCRIPTION!Ruby\tA,accessor\t/accessors/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_VERSION\t6.1.0\t/d1ecc51b9/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_PARSER_VERSION!PowerShell\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!Markdown\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!Make\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!C++\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!C\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!Asm\t1.0\t/current.age/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PARSER_VERSION!Zsh\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Yaml\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!XML\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!TOML\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!SystemdUnit\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Sh\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!SVG\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Ruby\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!RpmSpec\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!ReStructuredText\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!R\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Python\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Protobuf\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Pod\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Perl\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!OpenAPI\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Man\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Lua\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!JSON\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Iniconf\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!HTML\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Go\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!DosBatch\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Diff\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!DTD\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!CSS\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Bats\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Awk\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!Asciidoc\t0.0\t/current.age/\n!_TAG_OUTPUT_VERSION\t0.0\t/current.age/\n!_TAG_PROC_CWD\t/home/yamato/var/ctags-github/\t//\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/pseudo-input-b_.tags",
    "content": "!_PTAG\tvalue\\\t/comment/;\"\nregular_tag\t/path/to/file\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/pseudo-input-bb.tags",
    "content": "!_PTAG\tvalue\\\\\t/comment/;\"\nregular_tag\t/path/to/file\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/pseudo-input-bt.tags",
    "content": "!_PTAG\tvalue\\t\t/comment/;\"\nregular_tag\t/path/to/file\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/pseudo-name-b_.tags",
    "content": "!_PTAG\\\tvalue\t/comment/;\"\nregular_tag\t/path/to/file\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/pseudo-name-bb.tags",
    "content": "!_PTAG\\\\\tvalue\t/comment/;\"\nregular_tag\t/path/to/file\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/pseudo-name-bt.tags",
    "content": "!_PTAG\\t\tvalue\t/comment/;\"\nregular_tag\t/path/to/file\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/regular-input-b_.tags",
    "content": "!_PTAG\tvalue\t/comment/;\"\nregular_tag\t/path/to/file\\\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/regular-input-bb.tags",
    "content": "!_PTAG\tvalue\t/comment/;\"\nregular_tag\t/path/to/file\\\\\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/regular-input-bt.tags",
    "content": "!_PTAG\tvalue\t/comment/;\"\nregular_tag\t/path/to/file\\t\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/regular-kind-b_.tags",
    "content": "!_PTAG\tvalue\t/comment/;\"\nregular_tag\t/path/to/file\t/^pattern$/;\"\tkind:\\\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/regular-kind-bb.tags",
    "content": "!_PTAG\tvalue\t/comment/;\"\nregular_tag\t/path/to/file\t/^pattern$/;\"\tkind:\\\\\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/regular-name-b_.tags",
    "content": "!_PTAG\tvalue\t/comment/;\"\nregular_tag\\\t/path/to/file\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/regular-name-bb.tags",
    "content": "!_PTAG\tvalue\t/comment/;\"\nregular_tag\\\\\t/path/to/file\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/regular-name-bt.tags",
    "content": "!_PTAG\tvalue\t/comment/;\"\nregular_tag\\t\t/path/to/file\t/^pattern$/;\"\tkind:\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2022 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\n# {regular|pseudo}-{field}-{char0{char1}*}.tags\nfor t in INIT\t\t\t\t\t\t\t\t\t\\\n\t\t\t regular-name-b_.tags\t\t\t\t\\\n\t\t\t regular-name-bb.tags\t\t\t\t\\\n\t\t\t regular-name-bt.tags\t\t\t\t\\\n\t\t\t regular-input-b_.tags\t\t\t\t\\\n\t\t\t regular-input-bb.tags\t\t\t\t\\\n\t\t\t regular-input-bt.tags\t\t\t\t\\\n\t\t\t regular-kind-b_.tags\t\t\t\t\\\n\t\t\t regular-kind-bb.tags\t\t\t\t\\\n\t\t\t pseudo-name-b_.tags\t\t\t\t\\\n\t\t\t pseudo-name-bb.tags\t\t\t\t\\\n\t\t\t pseudo-name-bt.tags\t\t\t\t\\\n\t\t\t pseudo-input-b_.tags\t\t\t\t\\\n\t\t\t pseudo-input-bb.tags\t\t\t\t\\\n\t\t\t pseudo-input-bt.tags\t\t\t\t\\\n\t\t ; do\n\tcase $t in\n\t\tINIT)\n\t\t\t;;\n\t\tregular-*)\n\t\t\techo \"# $t\"\n\t\t\t${V} ${READTAGS} -Ee -t $t -l || exit 1\n\t\t\techo\n\t\t\t;;\n\t\tpseudo-*)\n\t\t\techo \"# $t\"\n\t\t\t${V} ${READTAGS} -Ee -t $t -D || exit 1\n\t\t\techo\n\t\t\t;;\n\t\t*)\n\t\t\techo \"INTERNAL BUG\"\n\t\t\texit 1\n\t\t\t;;\n\tesac\ndone\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-ptags-escaping.d/stdout-expected.txt",
    "content": "# regular-name-b_.tags\nregular_tag\\\\\t/path/to/file\t/^pattern$/\n\n# regular-name-bb.tags\nregular_tag\\\\\t/path/to/file\t/^pattern$/\n\n# regular-name-bt.tags\nregular_tag\\t\t/path/to/file\t/^pattern$/\n\n# regular-input-b_.tags\nregular_tag\t/path/to/file\\\t/^pattern$/\n\n# regular-input-bb.tags\nregular_tag\t/path/to/file\\\\\t/^pattern$/\n\n# regular-input-bt.tags\nregular_tag\t/path/to/file\\t\t/^pattern$/\n\n# regular-kind-b_.tags\nregular_tag\t/path/to/file\t/^pattern$/;\"\tkind:\\\\\n\n# regular-kind-bb.tags\nregular_tag\t/path/to/file\t/^pattern$/;\"\tkind:\\\\\n\n# pseudo-name-b_.tags\n!_PTAG\\\\\tvalue\t/comment/\n\n# pseudo-name-bb.tags\n!_PTAG\\\\\tvalue\t/comment/\n\n# pseudo-name-bt.tags\n!_PTAG\\t\tvalue\t/comment/\n\n# pseudo-input-b_.tags\n!_PTAG\tvalue\\\t/comment/\n\n# pseudo-input-bb.tags\n!_PTAG\tvalue\\\\\t/comment/\n\n# pseudo-input-bt.tags\n!_PTAG\tvalue\\t\t/comment/\n\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/example-_-_.tags",
    "content": "!_TAG_PROC_CWD\t/home/a\\tb\t//"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/example-_-b.tags",
    "content": "!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/example-_-s.tags",
    "content": "!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/example-e-_.tags",
    "content": "!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n!_TAG_PROC_CWD\t/home/a\\tb\t//"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/example-e-b.tags",
    "content": "!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/example-e-s.tags",
    "content": "!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/example-u-_.tags",
    "content": "!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PROC_CWD\t/home/a\\tb\t//"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/example-u-b.tags",
    "content": "!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/example-u-s.tags",
    "content": "!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2022 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\nfor m in e u _; do\n    for s in s b _; do\n\techo readtags -e -t example-$m-$s.tags -E -D:\n\t${V} ${READTAGS} -e -t example-$m-$s.tags -E -D\n\techo readtags -e -t example-$m-$s.tags -D:\n\t${V} ${READTAGS} -e -t example-$m-$s.tags -D\n\techo\n    done\ndone\n"
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-ptags-escaping2.d/stdout-expected.txt",
    "content": "readtags -e -t example-e-s.tags -E -D:\n!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\nreadtags -e -t example-e-s.tags -D:\n!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\n\nreadtags -e -t example-e-b.tags -E -D:\n!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\nreadtags -e -t example-e-b.tags -D:\n!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\n\nreadtags -e -t example-e-_.tags -E -D:\n!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\nreadtags -e -t example-e-_.tags -D:\n!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\n\nreadtags -e -t example-u-s.tags -E -D:\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\nreadtags -e -t example-u-s.tags -D:\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\tb\t//\n\nreadtags -e -t example-u-b.tags -E -D:\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\nreadtags -e -t example-u-b.tags -D:\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\n\nreadtags -e -t example-u-_.tags -E -D:\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\nreadtags -e -t example-u-_.tags -D:\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\n\nreadtags -e -t example-_-s.tags -E -D:\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\nreadtags -e -t example-_-s.tags -D:\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\n\nreadtags -e -t example-_-b.tags -E -D:\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\nreadtags -e -t example-_-b.tags -D:\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_PROC_CWD\t/home/a\\tb\t//\n\nreadtags -e -t example-_-_.tags -E -D:\n!_TAG_PROC_CWD\t/home/a\\tb\t//\nreadtags -e -t example-_-_.tags -D:\n!_TAG_PROC_CWD\t/home/a\\tb\t//\n\n"
  },
  {
    "path": "Tmain/readtags-qualifier-begin.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-qualifier-begin.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/;\"\textras:pseudo\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/;\"\textras:pseudo\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/;\"\textras:pseudo\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/;\"\textras:pseudo\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/;\"\textras:pseudo\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//;\"\textras:pseudo\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/;\"\textras:pseudo\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/;\"\textras:pseudo\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8957c2ce/;\"\textras:pseudo\nabc\tsample.c\t/^int abc;$/;\"\tkind:variable\tline:2\tlanguage:C\ttyperef:typename:int\troles:def\tend:2\nefg\tsample.c\t/^int efg;$/;\"\tkind:variable\tline:3\tlanguage:C\ttyperef:typename:int\troles:def\tend:3\n"
  },
  {
    "path": "Tmain/readtags-qualifier-begin.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\nrun_readtags()\n{\n\tlocal fexpr=$1\n\tlocal action=$2\n\techo ';;' \"$fexpr\" &&\n\t\techo ';;' \"$fexpr\" 1>&2 &&\n\t\t${V} ${READTAGS} -e -t output.tags -Q \"$fexpr\" \"$action\"\n}\n\nrun_readtags '(begin #f (print $name) (print $line) #t)' -l &&\nrun_readtags '(begin #t (print $name) (print $line) #f)' -l &&\nrun_readtags '(begin #t (print $name) (print $line) (eq? $name \"efg\"))' -l &&\nrun_readtags '(begin #t (and (eq? $name \"abc\") (print $name) (print $line)) (eq? $name \"efg\"))' -l &&\nrun_readtags '(begin0 #t                (print $name) (print $line) #f)' -l &&\nrun_readtags '(begin0 #f                (print $name) (print $line) #t)' -l &&\nrun_readtags '(begin0 (eq? $name \"abc\") (print $name) (print $line) #t)' -l\nrun_readtags '(begin0 (eq? $name \"abc\") (and (eq? $name \"efg\") (print $name) (print $line)) #t)' -l\n"
  },
  {
    "path": "Tmain/readtags-qualifier-begin.d/sample.c",
    "content": "/* ./ctags --fields='*' -o output.tags sample.c */\nint abc;\nint efg;\n"
  },
  {
    "path": "Tmain/readtags-qualifier-begin.d/stderr-expected.txt",
    "content": ";; (begin #f (print $name) (print $line) #t)\n\"abc\"\n2\n\"efg\"\n3\n;; (begin #t (print $name) (print $line) #f)\n\"abc\"\n2\n\"efg\"\n3\n;; (begin #t (print $name) (print $line) (eq? $name \"efg\"))\n\"abc\"\n2\n\"efg\"\n3\n;; (begin #t (and (eq? $name \"abc\") (print $name) (print $line)) (eq? $name \"efg\"))\n\"abc\"\n2\n;; (begin0 #t                (print $name) (print $line) #f)\n\"abc\"\n2\n\"efg\"\n3\n;; (begin0 #f                (print $name) (print $line) #t)\n\"abc\"\n2\n\"efg\"\n3\n;; (begin0 (eq? $name \"abc\") (print $name) (print $line) #t)\n\"abc\"\n2\n\"efg\"\n3\n;; (begin0 (eq? $name \"abc\") (and (eq? $name \"efg\") (print $name) (print $line)) #t)\n\"efg\"\n3\n"
  },
  {
    "path": "Tmain/readtags-qualifier-begin.d/stdout-expected.txt",
    "content": ";; (begin #f (print $name) (print $line) #t)\nabc\tsample.c\t/^int abc;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:2\nefg\tsample.c\t/^int efg;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:3\n;; (begin #t (print $name) (print $line) #f)\n;; (begin #t (print $name) (print $line) (eq? $name \"efg\"))\nefg\tsample.c\t/^int efg;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:3\n;; (begin #t (and (eq? $name \"abc\") (print $name) (print $line)) (eq? $name \"efg\"))\nefg\tsample.c\t/^int efg;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:3\n;; (begin0 #t                (print $name) (print $line) #f)\nabc\tsample.c\t/^int abc;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:2\nefg\tsample.c\t/^int efg;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:3\n;; (begin0 #f                (print $name) (print $line) #t)\n;; (begin0 (eq? $name \"abc\") (print $name) (print $line) #t)\nabc\tsample.c\t/^int abc;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:2\n;; (begin0 (eq? $name \"abc\") (and (eq? $name \"efg\") (print $name) (print $line)) #t)\nabc\tsample.c\t/^int abc;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:2\n"
  },
  {
    "path": "Tmain/readtags-qualifier-broken-exp.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/readtags-qualifier-broken-exp.d/input.c",
    "content": "/* u-ctags input.c */\nint\nmain(void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Tmain/readtags-qualifier-broken-exp.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tDarren Hiebert\t/dhiebert@users.sourceforge.net/\n!_TAG_PROGRAM_NAME\tExuberant Ctags\t//\n!_TAG_PROGRAM_URL\thttp://ctags.sourceforge.net\t/official site/\n!_TAG_PROGRAM_VERSION\t5.8\t//\nmain\tinput.c\t/^main(void)$/;\"\tf\n"
  },
  {
    "path": "Tmain/readtags-qualifier-broken-exp.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n${V} ${READTAGS} -e -t output.tags -Q '(' -l\n"
  },
  {
    "path": "Tmain/readtags-qualifier-broken-exp.d/stderr-expected.txt",
    "content": "Failed to read the expression for filter: (\nReason: READ-ERROR\n"
  },
  {
    "path": "Tmain/readtags-qualifier-end-field.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-qualifier-end-field.d/output.tags",
    "content": "A\tinput.py\t/^class A(object):$/;\"\tc\tline:1\tend:18\nf\tinput.py\t/^    def f(self):$/;\"\tm\tline:3\tclass:A\tend:9\nA.f\tinput.py\t/^    def f(self):$/;\"\tm\tline:3\tclass:A\tend:9\ng\tinput.py\t/^        def g(x):$/;\"\tf\tline:4\tfunction:A.f\tfile:\tend:6\ny\tinput.py\t/^    y = 1$/;\"\tv\tline:10\tclass:A\nh\tinput.py\t/^    def h(self):$/;\"\tm\tline:12\tclass:A\tend:15\nA.h\tinput.py\t/^    def h(self):$/;\"\tm\tline:12\tclass:A\tend:15\ni\tinput.py\t/^    def i(self):$/;\"\tm\tline:16\tclass:A\tend:18\nA.i\tinput.py\t/^    def i(self):$/;\"\tm\tline:16\tclass:A\tend:18\ninput.py\tinput.py\t18;\"\tF\tline:18\n"
  },
  {
    "path": "Tmain/readtags-qualifier-end-field.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\necho ';; (and $end (> $end 14) (< $end 18))' &&\n    ${V} ${READTAGS} -e -t output.tags -Q '(and $end (> $end 14) (< $end 18))' -l &&\n    :\n"
  },
  {
    "path": "Tmain/readtags-qualifier-end-field.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-qualifier-end-field.d/stdout-expected.txt",
    "content": ";; (and $end (> $end 14) (< $end 18))\nh\tinput.py\t/^    def h(self):$/;\"\tkind:m\tclass:A\tend:15\nA.h\tinput.py\t/^    def h(self):$/;\"\tkind:m\tclass:A\tend:15\n"
  },
  {
    "path": "Tmain/readtags-qualifier-exp-with-garbage.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/readtags-qualifier-exp-with-garbage.d/input.c",
    "content": "/* ctags -o output.tags input.c */\nvoid foo (void)\n{\n}\n\nvoid bar (void)\n{\n}\n\nvoid baz (void)\n{\n}\n"
  },
  {
    "path": "Tmain/readtags-qualifier-exp-with-garbage.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/02cf1a61/\nbar\tinput.c\t/^void bar (void)$/;\"\tf\tlanguage:C\ttyperef:typename:void\nbaz\tinput.c\t/^void baz (void)$/;\"\tf\tlanguage:C\ttyperef:typename:void\nfoo\tinput.c\t/^void foo (void)$/;\"\tf\tlanguage:C\ttyperef:typename:void\n"
  },
  {
    "path": "Tmain/readtags-qualifier-exp-with-garbage.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2026 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\ns=0\n${READTAGS} -t output.tags -S '(<> 2 1)x' -l > /dev/null\ns=`expr $s + $?`\n\n${READTAGS} -t output.tags -S '(<> 2 1)        ' -l > /dev/null\ns=`expr $s + $?`\n\n${READTAGS} -t output.tags -S '(<> 2 1)        ; comment' -l > /dev/null\ns=`expr $s + $?`\n\nexit $s\n"
  },
  {
    "path": "Tmain/readtags-qualifier-exp-with-garbage.d/stderr-expected.txt",
    "content": "Garbage at the end of the sorter expression: x\n"
  },
  {
    "path": "Tmain/readtags-qualifier-nth-field.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-qualifier-nth-field.d/input.c",
    "content": "/* ctags --options=NONE --sort=yes--kinds-C=+z --fields=+o --pseudo-tags=-TAG_PROGRAM_VERSION output.tags */\nint z(int y, int x)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Tmain/readtags-qualifier-nth-field.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/jet/var/ctags-github/Tmain/readtags-qualifier-nth-field.d/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\nx\tinput.c\t/^int z(int y, int x)$/;\"\tz\tfunction:z\ttyperef:typename:int\tfile:\tnth:1\ny\tinput.c\t/^int z(int y, int x)$/;\"\tz\tfunction:z\ttyperef:typename:int\tfile:\tnth:0\nz\tinput.c\t/^int z(int y, int x)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-qualifier-nth-field.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n${V} ${READTAGS} -e -t output.tags \\\n\t -Q '(eq? $kind \"z\")' \\\n\t -S '(<> $nth &nth)' \\\n\t -F '(list $name \":\" $nth #t)' \\\n\t -l\n"
  },
  {
    "path": "Tmain/readtags-qualifier-nth-field.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-qualifier-nth-field.d/stdout-expected.txt",
    "content": "y:0\nx:1\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-downcase-upcase.d/input.cpp",
    "content": "// ctags -o output.tags --fields=+i input.cpp\nclass A {\nprotected:\n  int f (void) {\n    return 1;\n  }\n};\n\nclass B {\nprotected:\n  int g (void) {\n    return 1;\n  }\n};\n\nclass C: A, B {\npublic:\n  int h (void) {\n    return f () + g ();\n  }\n};\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-downcase-upcase.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/e87283aa/\nA\tinput.cpp\t/^class A {$/;\"\tc\tfile:\nB\tinput.cpp\t/^class B {$/;\"\tc\tfile:\nC\tinput.cpp\t/^class C: A, B {$/;\"\tc\tfile:\tinherits:A,B\nf\tinput.cpp\t/^  int f (void) {$/;\"\tf\tclass:A\ttyperef:typename:int\tfile:\ng\tinput.cpp\t/^  int g (void) {$/;\"\tf\tclass:B\ttyperef:typename:int\tfile:\nh\tinput.cpp\t/^  int h (void) {$/;\"\tf\tclass:C\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-downcase-upcase.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '# (eq? \"c\" (downcase $name))'\n${V} ${READTAGS} -t output.tags -Q '(eq? \"c\" (downcase $name))' -l\n\necho '# (and $inherits (#/(^|,)a(,|$)/ (downcase $inherits)))'\n${V} ${READTAGS} -t output.tags -Q '(and $inherits (#/(^|,)a(,|$)/ (downcase $inherits)))' -l\n\necho '# (and $inherits (#/(^|,)b(,|$)/ (downcase $inherits)))'\n${V} ${READTAGS} -t output.tags -Q '(and $inherits (#/(^|,)b(,|$)/ (downcase $inherits)))' -l\n\necho '# (and $inherits (#/(^|,)d(,|$)/ (downcase $inherits)))'\n${V} ${READTAGS} -t output.tags -Q '(and $inherits (#/(^|,)d(,|$)/ (downcase $inherits)))' -l\n\necho '# (eq? \"F\" (upcase $name))'\n${V} ${READTAGS} -t output.tags -Q '(eq? \"F\" (upcase $name))' -l\n\necho '# (eq? \"G\" (upcase $name))'\n${V} ${READTAGS} -t output.tags -Q '(eq? \"G\" (upcase $name))' -l\n\necho '# (eq? \"J\" (upcase $name))'\n${V} ${READTAGS} -t output.tags -Q '(eq? \"J\" (upcase $name))' -l\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-downcase-upcase.d/stdout-expected.txt",
    "content": "# (eq? \"c\" (downcase $name))\nC\tinput.cpp\t/^class C: A, B {$/\n# (and $inherits (#/(^|,)a(,|$)/ (downcase $inherits)))\nC\tinput.cpp\t/^class C: A, B {$/\n# (and $inherits (#/(^|,)b(,|$)/ (downcase $inherits)))\nC\tinput.cpp\t/^class C: A, B {$/\n# (and $inherits (#/(^|,)d(,|$)/ (downcase $inherits)))\n# (eq? \"F\" (upcase $name))\nf\tinput.cpp\t/^  int f (void) {$/\n# (eq? \"G\" (upcase $name))\ng\tinput.cpp\t/^  int g (void) {$/\n# (eq? \"J\" (upcase $name))\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-length.d/input.el",
    "content": ";; ctags -o output.tags input.el\n(defun hi-zzz ())\n(defun hi-aaa-some-long-thing ())\n(defun hi-bbb-1 ())\n(defun hi-y ())\n(defun bye ())\n(defun bye-long-long-long-long-lone ())\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-length.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/58efa7d1/\nbye\tinput.el\t/^(defun bye ())$/;\"\tf\nbye-long-long-long-long-lone\tinput.el\t/^(defun bye-long-long-long-long-lone ())$/;\"\tf\nhi-aaa-some-long-thing\tinput.el\t/^(defun hi-aaa-some-long-thing ())$/;\"\tf\nhi-bbb-1\tinput.el\t/^(defun hi-bbb-1 ())$/;\"\tf\nhi-y\tinput.el\t/^(defun hi-y ())$/;\"\tf\nhi-zzz\tinput.el\t/^(defun hi-zzz ())$/;\"\tf\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-length.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '# (<> $name &name)'\n${V} ${READTAGS} -t output.tags -S '(<> $name &name)' -p hi\n\necho '# (<or> (<> (length $name) (length &name)) (<> $name &name))'\n${V} ${READTAGS} -t output.tags -S '(<or> (<> (length $name) (length &name)) (<> $name &name))' -p hi\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-length.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-qualifier-op-length.d/stdout-expected.txt",
    "content": "# (<> $name &name)\nhi-aaa-some-long-thing\tinput.el\t/^(defun hi-aaa-some-long-thing ())$/\nhi-bbb-1\tinput.el\t/^(defun hi-bbb-1 ())$/\nhi-y\tinput.el\t/^(defun hi-y ())$/\nhi-zzz\tinput.el\t/^(defun hi-zzz ())$/\n# (<or> (<> (length $name) (length &name)) (<> $name &name))\nhi-y\tinput.el\t/^(defun hi-y ())$/\nhi-zzz\tinput.el\t/^(defun hi-zzz ())$/\nhi-bbb-1\tinput.el\t/^(defun hi-bbb-1 ())$/\nhi-aaa-some-long-thing\tinput.el\t/^(defun hi-aaa-some-long-thing ())$/\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-list.d/input.c",
    "content": "/* ctags --options=NONE --kinds-c='*' -o output.tags input.c */\nextern int f (void);\nint g (int c)\n{\n\treturn c;\n}\n\nint x;\n\nstruct s {\n\tint i, j, k;\n};\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-list.d/output.tags",
    "content": "!_TAG_EXTRA_DESCRIPTION\tanonymous\t/Include tags for non-named objects like lambda/\n!_TAG_EXTRA_DESCRIPTION\tfileScope\t/Include tags of file scope/\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_EXTRA_DESCRIPTION\tsubparser\t/Include tags generated by subparsers/\n!_TAG_FIELD_DESCRIPTION\tepoch\t/the last modified time of the input file (only for F\\/file kind tag)/\n!_TAG_FIELD_DESCRIPTION\tfile\t/File-restricted scoping/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_FIELD_DESCRIPTION\ttyperef\t/Type and name of a variable or typedef/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function or prototype definitions/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_VERSION\t1.1\t/current.age/\n!_TAG_PARSER_VERSION!C\t1.1\t/current.age/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/yamato/var/ctags-github/Tmain/readtags-qualifier-op-list.d/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t6.2.1\t//\n!_TAG_ROLE_DESCRIPTION!C!function\tforeigndecl\t/declared in foreign languages/\n!_TAG_ROLE_DESCRIPTION!C!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C!header\tsystem\t/system header/\n!_TAG_ROLE_DESCRIPTION!C!macro\tundef\t/undefined/\n!_TAG_ROLE_DESCRIPTION!C!struct\tforeigndecl\t/declared in foreign languages/\nc\tinput.c\t/^int g (int c)$/;\"\tz\tfunction:g\ttyperef:typename:int\tfile:\nf\tinput.c\t/^extern int f (void);$/;\"\tp\ttyperef:typename:int\tfile:\ng\tinput.c\t/^int g (int c)$/;\"\tf\ttyperef:typename:int\ni\tinput.c\t/^\tint i, j, k;$/;\"\tm\tstruct:s\ttyperef:typename:int\tfile:\nj\tinput.c\t/^\tint i, j, k;$/;\"\tm\tstruct:s\ttyperef:typename:int\tfile:\nk\tinput.c\t/^\tint i, j, k;$/;\"\tm\tstruct:s\ttyperef:typename:int\tfile:\ns\tinput.c\t/^struct s {$/;\"\ts\tfile:\nx\tinput.c\t/^int x;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-list.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2026 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\nqexpr='(not (member $kind (list \"m\" \"z\" \"p\" \"f\" \"s\")))'\necho \"-Q '${qexpr}'\"\n${V} ${READTAGS} -et output.tags \\\n\t -Q \"$qexpr\" \\\n\t -l\necho $?\n\nqexpr='(member $kind (list \"z\" \"p\"))'\necho \"-Q '${qexpr}'\"\n${V} ${READTAGS} -et output.tags \\\n\t -Q \"$qexpr\" \\\n\t -l\necho $?\n\nsexpr='(<or> (if (and (member $kind (list \"s\" \"v\")) (member &kind (list \"s\" \"v\"))) (<> $name &name) 0) (<> &name $name))'\necho \"-S $sexpr\"\n${V} ${READTAGS} -et output.tags \\\n\t -S \"$sexpr\" \\\n\t -l\necho $?\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-list.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-qualifier-op-list.d/stdout-expected.txt",
    "content": "-Q '(not (member $kind (list \"m\" \"z\" \"p\" \"f\" \"s\")))'\nx\tinput.c\t/^int x;$/;\"\tkind:v\ttyperef:typename:int\n0\n-Q '(member $kind (list \"z\" \"p\"))'\nc\tinput.c\t/^int g (int c)$/;\"\tkind:z\tfile:\tfunction:g\ttyperef:typename:int\nf\tinput.c\t/^extern int f (void);$/;\"\tkind:p\tfile:\ttyperef:typename:int\n0\n-S (<or> (if (and (member $kind (list \"s\" \"v\")) (member &kind (list \"s\" \"v\"))) (<> $name &name) 0) (<> &name $name))\ns\tinput.c\t/^struct s {$/;\"\tkind:s\tfile:\nx\tinput.c\t/^int x;$/;\"\tkind:v\ttyperef:typename:int\nk\tinput.c\t/^\tint i, j, k;$/;\"\tkind:m\tfile:\tstruct:s\ttyperef:typename:int\nj\tinput.c\t/^\tint i, j, k;$/;\"\tkind:m\tfile:\tstruct:s\ttyperef:typename:int\ni\tinput.c\t/^\tint i, j, k;$/;\"\tkind:m\tfile:\tstruct:s\ttyperef:typename:int\ng\tinput.c\t/^int g (int c)$/;\"\tkind:f\ttyperef:typename:int\nf\tinput.c\t/^extern int f (void);$/;\"\tkind:p\tfile:\ttyperef:typename:int\nc\tinput.c\t/^int g (int c)$/;\"\tkind:z\tfile:\tfunction:g\ttyperef:typename:int\n0\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-regexp-quote.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-regexp-quote.d/input.x",
    "content": "[{.*+]}^$()|?\\\nabc\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-regexp-quote.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/jet/var/ctags-new/Tmain/readtags-qualifier-op-regexp-quote.d/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n[{.*+]}^$()|?\\\\\tinput.x\t/^[{.*+]}^$()|?\\\\$/;\"\ta\nabc\tinput.x\t/^abc$/;\"\ta\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-regexp-quote.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n${V} ${READTAGS} -e -t output.tags \\\n\t -Q '(if (prefix? $name \"a\") #f ((string->regexp (string-append (regexp-quote $name) \".?\")) $name))' \\\n\t -l\n\n${V} ${READTAGS} -e -t output.tags \\\n\t -Q '(if (prefix? $name \"a\") #f ((string->regexp (string-append (regexp-quote \"[{.*+]}^$()|?\\\\\") \".?\")) $name))' \\\n\t -l\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-regexp-quote.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-qualifier-op-regexp-quote.d/stdout-expected.txt",
    "content": "[{.*+]}^$()|?\\\tinput.x\t/^[{.*+]}^$()|?\\\\$/;\"\tkind:a\n[{.*+]}^$()|?\\\tinput.x\t/^[{.*+]}^$()|?\\\\$/;\"\tkind:a\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-regexp-quote.d/x.ctags",
    "content": "# u-ctags --options=x.ctags -o output.tags input.x\n--langdef=X\n--map-X=.x\n--languages=X\n--kinddef-X=a,anything,something anythings\n--regex-X=/^(.*)$/\\1/a/\n--pseudo-tags=-TAG_PROGRAM_VERSION\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-string-append.d/input.c",
    "content": "struct abpcx {\n\tint p;\n};\n\nstruct abpcy {\n\tint p;\n};\n\nstruct abpcz {\n\tint p;\n};\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-string-append.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/jet/var/ctags-new/Tmain/readtags-qualifier-op-string-append.d/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\naapcz\tinput.c\t/^struct aapcz {$/;\"\tstruct\tline:9\tfile:\nabpcx\tinput.c\t/^struct abpcx {$/;\"\tstruct\tline:1\tfile:\nabpcy\tinput.c\t/^struct abpcy {$/;\"\tstruct\tline:5\tfile:\np\tinput.c\t/^\tint p;$/;\"\tmember\tline:10\tscope:struct:aapcz\ttyperef:typename:int\tfile:\np\tinput.c\t/^\tint p;$/;\"\tmember\tline:2\tscope:struct:abpcx\ttyperef:typename:int\tfile:\np\tinput.c\t/^\tint p;$/;\"\tmember\tline:6\tscope:struct:abpcy\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-string-append.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\nr()\n{\n\techo ';; ' \"$1\"\n\t${V} ${READTAGS} -e -t output.tags -Q \"$1\" -l\n}\n\nr '(eq? $scope-name (string-append \"ab\" $name \"cy\"))'\nr '(eq? $scope-name (concat \"ab\" \"p\" \"cy\"))'\nr '(eq? $scope-name (concat (concat \"a\" \"b\") $name (concat \"c\" \"y\")))'\nr '(eq? $scope-name (concat (concat \"a\" \"b\" $name) (concat \"c\" \"y\")))'\nr '(eq? $scope-name (concat (concat (concat \"a\" \"b\" $name) (concat \"c\" \"y\"))))'\nr '((string->regexp (concat (concat (concat \"a\" \"b\" $name) (concat \"c\" \"y\")))) (or $scope-name \"\"))'\nr '((string->regexp (concat (concat (concat \"a\" \"b\" \"p\") (concat \"c\" \"y\")))) (or $scope-name \"\"))'\nr '((printX (string->regexp (concat (concat (concat \"a\" \"b\" \"p\") (concat \"c\" \"y\"))))) (or $scope-name \"\"))'\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-string-append.d/stderr-expected.txt",
    "content": "#/abpcy/\n"
  },
  {
    "path": "Tmain/readtags-qualifier-op-string-append.d/stdout-expected.txt",
    "content": ";;  (eq? $scope-name (string-append \"ab\" $name \"cy\"))\np\tinput.c\t/^\tint p;$/;\"\tkind:member\tfile:\tscope:struct:abpcy\ttyperef:typename:int\n;;  (eq? $scope-name (concat \"ab\" \"p\" \"cy\"))\np\tinput.c\t/^\tint p;$/;\"\tkind:member\tfile:\tscope:struct:abpcy\ttyperef:typename:int\n;;  (eq? $scope-name (concat (concat \"a\" \"b\") $name (concat \"c\" \"y\")))\np\tinput.c\t/^\tint p;$/;\"\tkind:member\tfile:\tscope:struct:abpcy\ttyperef:typename:int\n;;  (eq? $scope-name (concat (concat \"a\" \"b\" $name) (concat \"c\" \"y\")))\np\tinput.c\t/^\tint p;$/;\"\tkind:member\tfile:\tscope:struct:abpcy\ttyperef:typename:int\n;;  (eq? $scope-name (concat (concat (concat \"a\" \"b\" $name) (concat \"c\" \"y\"))))\np\tinput.c\t/^\tint p;$/;\"\tkind:member\tfile:\tscope:struct:abpcy\ttyperef:typename:int\n;;  ((string->regexp (concat (concat (concat \"a\" \"b\" $name) (concat \"c\" \"y\")))) (or $scope-name \"\"))\np\tinput.c\t/^\tint p;$/;\"\tkind:member\tfile:\tscope:struct:abpcy\ttyperef:typename:int\n;;  ((string->regexp (concat (concat (concat \"a\" \"b\" \"p\") (concat \"c\" \"y\")))) (or $scope-name \"\"))\np\tinput.c\t/^\tint p;$/;\"\tkind:member\tfile:\tscope:struct:abpcy\ttyperef:typename:int\n;;  ((printX (string->regexp (concat (concat (concat \"a\" \"b\" \"p\") (concat \"c\" \"y\"))))) (or $scope-name \"\"))\np\tinput.c\t/^\tint p;$/;\"\tkind:member\tfile:\tscope:struct:abpcy\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-qualifier-regex.d/input.hxx",
    "content": "/*\n *  u-ctags --fields=S --kinds-C++=+p -o output.tags input.hxx\n */\nint f ( int,  int,  int);\nint f (char,  int,  int);\nint f (char, char,  int);\nint f (char,  int, char);\nint f (char, char, char);\nint f ( int, char,  int);\nint f ( int, char, char);\nint f ( int,  int, char);\n\ntypedef char CHAR;\ntypedef int  INT;\n\nint g ( INT,  INT,  INT);\nint g (CHAR,  INT,  INT);\nint g (CHAR, CHAR,  INT);\nint g (CHAR,  INT, CHAR);\nint g (CHAR, CHAR, CHAR);\nint g ( INT, CHAR,  INT);\nint g ( INT, CHAR, CHAR);\nint g ( INT,  INT, CHAR);\n"
  },
  {
    "path": "Tmain/readtags-qualifier-regex.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/e9d9780d/\nCHAR\tinput.hxx\t/^typedef char CHAR;$/\nINT\tinput.hxx\t/^typedef int  INT;$/\nf\tinput.hxx\t/^int f ( int,  int,  int);$/;\"\tsignature:(int,int,int)\nf\tinput.hxx\t/^int f ( int,  int, char);$/;\"\tsignature:(int,int,char)\nf\tinput.hxx\t/^int f ( int, char,  int);$/;\"\tsignature:(int,char,int)\nf\tinput.hxx\t/^int f ( int, char, char);$/;\"\tsignature:(int,char,char)\nf\tinput.hxx\t/^int f (char,  int,  int);$/;\"\tsignature:(char,int,int)\nf\tinput.hxx\t/^int f (char,  int, char);$/;\"\tsignature:(char,int,char)\nf\tinput.hxx\t/^int f (char, char,  int);$/;\"\tsignature:(char,char,int)\nf\tinput.hxx\t/^int f (char, char, char);$/;\"\tsignature:(char,char,char)\ng\tinput.hxx\t/^int g ( INT,  INT,  INT);$/;\"\tsignature:(INT,INT,INT)\ng\tinput.hxx\t/^int g ( INT,  INT, CHAR);$/;\"\tsignature:(INT,INT,CHAR)\ng\tinput.hxx\t/^int g ( INT, CHAR,  INT);$/;\"\tsignature:(INT,CHAR,INT)\ng\tinput.hxx\t/^int g ( INT, CHAR, CHAR);$/;\"\tsignature:(INT,CHAR,CHAR)\ng\tinput.hxx\t/^int g (CHAR,  INT,  INT);$/;\"\tsignature:(CHAR,INT,INT)\ng\tinput.hxx\t/^int g (CHAR,  INT, CHAR);$/;\"\tsignature:(CHAR,INT,CHAR)\ng\tinput.hxx\t/^int g (CHAR, CHAR,  INT);$/;\"\tsignature:(CHAR,CHAR,INT)\ng\tinput.hxx\t/^int g (CHAR, CHAR, CHAR);$/;\"\tsignature:(CHAR,CHAR,CHAR)\n"
  },
  {
    "path": "Tmain/readtags-qualifier-regex.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '# case sensitive'\n${V} ${READTAGS} -t output.tags -Q '(and $signature (#/char,.*,char|int,.*,int/ $signature))' -en -l\n\necho '# case insensitive: the pattern is lower case'\n${V} ${READTAGS} -t output.tags -Q '(and $signature (#/char,.*,char|int,.*,int/i $signature))' -en -l\n\necho '# case insensitive: the pattern is upper case'\n${V} ${READTAGS} -t output.tags -Q '(and $signature (#/CHAR,.*,CHAR|INT,.*,INT/i $signature))' -en -l\n\necho '# case sensitive (string->regexp)'\n${V} ${READTAGS} -t output.tags -Q '(or #f #f (or #f (and $signature ((string->regexp \"char,.*,char|int,.*,int\") $signature)) #f) #f)' -en -l\n\necho '# case sensitive (string->regexp :case-fold #f)'\n${V} ${READTAGS} -t output.tags -Q '(or #f #f (or #f (and $signature ((string->regexp \"char,.*,char|int,.*,int\" :case-fold #f) $signature)) #f) #f)' -en -l\n\necho '# case sensitive (string->regexp :case-fold false)'\n${V} ${READTAGS} -t output.tags -Q '(or #f #f (or #f (and $signature ((string->regexp \"char,.*,char|int,.*,int\" :case-fold false) $signature)) #f) #f)' -en -l\n\necho '# case insensitive: the pattern is lower case (string->regexp :case-fold #t)'\n${V} ${READTAGS} -t output.tags -Q '(or #f #f (or #f (and $signature ((string->regexp \"char,.*,char|int,.*,int\" :case-fold #t) $signature)) #f) #f)' -en -l\n\necho '# case insensitive: the pattern is upper case (string->regexp :case-fold true)'\n${V} ${READTAGS} -t output.tags -Q '(or #f #f (or #f (and $signature ((string->regexp \"CHAR,.*,CHAR|INT,.*,INT\" :case-fold true) $signature)) #f) #f)' -en -l\n\necho '# RAISING AN ERROR' 1>&2\n${V} ${READTAGS} -t output.tags -Q '(or #f #f (or #f (and $signature (#/[/ $signature)) #f) #f)' -en -l\n\necho '# RAISING AN ERROR (string->regexp)' 1>&2\n${V} ${READTAGS} -t output.tags -Q '(or #f #f (or #f (and $signature ((string->regexp \"[\") $signature)) #f) #f)' -en -l\n"
  },
  {
    "path": "Tmain/readtags-qualifier-regex.d/stderr-expected.txt",
    "content": "# RAISING AN ERROR\nFailed to read the expression for filter: (or #f #f (or #f (and $signature (#/[/ $signature)) #f) #f)\nReason: WRONG-REGEX-SYNTAX\n# RAISING AN ERROR (string->regexp)\nCOMPILE ERROR: WRONG-REGEX-SYNTAX: ()\nMEMORY EXHAUSTED or SYNTAX ERROR\nFailed to compile the expression of filter: (or #f #f (or #f (and $signature ((string->regexp \"[\") $signature)) #f) #f)\n"
  },
  {
    "path": "Tmain/readtags-qualifier-regex.d/stdout-expected.txt",
    "content": "# case sensitive\nf\tinput.hxx\t/^int f ( int,  int,  int);$/;\"\tsignature:(int,int,int)\nf\tinput.hxx\t/^int f ( int, char,  int);$/;\"\tsignature:(int,char,int)\nf\tinput.hxx\t/^int f (char,  int, char);$/;\"\tsignature:(char,int,char)\nf\tinput.hxx\t/^int f (char, char, char);$/;\"\tsignature:(char,char,char)\n# case insensitive: the pattern is lower case\nf\tinput.hxx\t/^int f ( int,  int,  int);$/;\"\tsignature:(int,int,int)\nf\tinput.hxx\t/^int f ( int, char,  int);$/;\"\tsignature:(int,char,int)\nf\tinput.hxx\t/^int f (char,  int, char);$/;\"\tsignature:(char,int,char)\nf\tinput.hxx\t/^int f (char, char, char);$/;\"\tsignature:(char,char,char)\ng\tinput.hxx\t/^int g ( INT,  INT,  INT);$/;\"\tsignature:(INT,INT,INT)\ng\tinput.hxx\t/^int g ( INT, CHAR,  INT);$/;\"\tsignature:(INT,CHAR,INT)\ng\tinput.hxx\t/^int g (CHAR,  INT, CHAR);$/;\"\tsignature:(CHAR,INT,CHAR)\ng\tinput.hxx\t/^int g (CHAR, CHAR, CHAR);$/;\"\tsignature:(CHAR,CHAR,CHAR)\n# case insensitive: the pattern is upper case\nf\tinput.hxx\t/^int f ( int,  int,  int);$/;\"\tsignature:(int,int,int)\nf\tinput.hxx\t/^int f ( int, char,  int);$/;\"\tsignature:(int,char,int)\nf\tinput.hxx\t/^int f (char,  int, char);$/;\"\tsignature:(char,int,char)\nf\tinput.hxx\t/^int f (char, char, char);$/;\"\tsignature:(char,char,char)\ng\tinput.hxx\t/^int g ( INT,  INT,  INT);$/;\"\tsignature:(INT,INT,INT)\ng\tinput.hxx\t/^int g ( INT, CHAR,  INT);$/;\"\tsignature:(INT,CHAR,INT)\ng\tinput.hxx\t/^int g (CHAR,  INT, CHAR);$/;\"\tsignature:(CHAR,INT,CHAR)\ng\tinput.hxx\t/^int g (CHAR, CHAR, CHAR);$/;\"\tsignature:(CHAR,CHAR,CHAR)\n# case sensitive (string->regexp)\nf\tinput.hxx\t/^int f ( int,  int,  int);$/;\"\tsignature:(int,int,int)\nf\tinput.hxx\t/^int f ( int, char,  int);$/;\"\tsignature:(int,char,int)\nf\tinput.hxx\t/^int f (char,  int, char);$/;\"\tsignature:(char,int,char)\nf\tinput.hxx\t/^int f (char, char, char);$/;\"\tsignature:(char,char,char)\n# case sensitive (string->regexp :case-fold #f)\nf\tinput.hxx\t/^int f ( int,  int,  int);$/;\"\tsignature:(int,int,int)\nf\tinput.hxx\t/^int f ( int, char,  int);$/;\"\tsignature:(int,char,int)\nf\tinput.hxx\t/^int f (char,  int, char);$/;\"\tsignature:(char,int,char)\nf\tinput.hxx\t/^int f (char, char, char);$/;\"\tsignature:(char,char,char)\n# case sensitive (string->regexp :case-fold false)\nf\tinput.hxx\t/^int f ( int,  int,  int);$/;\"\tsignature:(int,int,int)\nf\tinput.hxx\t/^int f ( int, char,  int);$/;\"\tsignature:(int,char,int)\nf\tinput.hxx\t/^int f (char,  int, char);$/;\"\tsignature:(char,int,char)\nf\tinput.hxx\t/^int f (char, char, char);$/;\"\tsignature:(char,char,char)\n# case insensitive: the pattern is lower case (string->regexp :case-fold #t)\nf\tinput.hxx\t/^int f ( int,  int,  int);$/;\"\tsignature:(int,int,int)\nf\tinput.hxx\t/^int f ( int, char,  int);$/;\"\tsignature:(int,char,int)\nf\tinput.hxx\t/^int f (char,  int, char);$/;\"\tsignature:(char,int,char)\nf\tinput.hxx\t/^int f (char, char, char);$/;\"\tsignature:(char,char,char)\ng\tinput.hxx\t/^int g ( INT,  INT,  INT);$/;\"\tsignature:(INT,INT,INT)\ng\tinput.hxx\t/^int g ( INT, CHAR,  INT);$/;\"\tsignature:(INT,CHAR,INT)\ng\tinput.hxx\t/^int g (CHAR,  INT, CHAR);$/;\"\tsignature:(CHAR,INT,CHAR)\ng\tinput.hxx\t/^int g (CHAR, CHAR, CHAR);$/;\"\tsignature:(CHAR,CHAR,CHAR)\n# case insensitive: the pattern is upper case (string->regexp :case-fold true)\nf\tinput.hxx\t/^int f ( int,  int,  int);$/;\"\tsignature:(int,int,int)\nf\tinput.hxx\t/^int f ( int, char,  int);$/;\"\tsignature:(int,char,int)\nf\tinput.hxx\t/^int f (char,  int, char);$/;\"\tsignature:(char,int,char)\nf\tinput.hxx\t/^int f (char, char, char);$/;\"\tsignature:(char,char,char)\ng\tinput.hxx\t/^int g ( INT,  INT,  INT);$/;\"\tsignature:(INT,INT,INT)\ng\tinput.hxx\t/^int g ( INT, CHAR,  INT);$/;\"\tsignature:(INT,CHAR,INT)\ng\tinput.hxx\t/^int g (CHAR,  INT, CHAR);$/;\"\tsignature:(CHAR,INT,CHAR)\ng\tinput.hxx\t/^int g (CHAR, CHAR, CHAR);$/;\"\tsignature:(CHAR,CHAR,CHAR)\n"
  },
  {
    "path": "Tmain/readtags-qualifier-sf-cond.d/input.c",
    "content": "typedef struct abc {\n\tint def;\n\tint ghi;\n} jkl;\n\njkl mno;\n\njkl pqr(void)\n{\n\treturn (jkl){.def = 1, .ghi = 2};\n}\n"
  },
  {
    "path": "Tmain/readtags-qualifier-sf-cond.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/jet/var/ctags-github/Tmain/readtags-qualifier-sf-cond.d/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\nabc\tinput.c\t/^typedef struct abc {$/;\"\ts\tfile:\ndef\tinput.c\t/^\tint def;$/;\"\tm\tstruct:abc\ttyperef:typename:int\tfile:\nghi\tinput.c\t/^\tint ghi;$/;\"\tm\tstruct:abc\ttyperef:typename:int\tfile:\njkl\tinput.c\t/^} jkl;$/;\"\tt\ttyperef:struct:abc\tfile:\nmno\tinput.c\t/^jkl mno;$/;\"\tv\ttyperef:typename:jkl\npqr\tinput.c\t/^jkl pqr(void)$/;\"\tf\ttyperef:typename:jkl\n"
  },
  {
    "path": "Tmain/readtags-qualifier-sf-cond.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n${V} ${READTAGS} -e -t output.tags \\\n\t -Q '(cond ((eq? $kind \"m\") (#/.h./ $name)) ((eq? $kind \"t\")) ((#/.n./ $name) #f) (#t))' \\\n\t -l\n"
  },
  {
    "path": "Tmain/readtags-qualifier-sf-cond.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-qualifier-sf-cond.d/stdout-expected.txt",
    "content": "abc\tinput.c\t/^typedef struct abc {$/;\"\tkind:s\tfile:\nghi\tinput.c\t/^\tint ghi;$/;\"\tkind:m\tfile:\tstruct:abc\ttyperef:typename:int\njkl\tinput.c\t/^} jkl;$/;\"\tkind:t\tfile:\ttyperef:struct:abc\npqr\tinput.c\t/^jkl pqr(void)$/;\"\tkind:f\ttyperef:typename:jkl\n"
  },
  {
    "path": "Tmain/readtags-qualifier.d/base.c",
    "content": "/*\n * ctags --fields='*' --kinds-C='*' -o c.tags base.c\n */\nint\nmain(int argc, char ** argv)\n{\n\tint r = argc + 1;\n\treturn r;\n}\n"
  },
  {
    "path": "Tmain/readtags-qualifier.d/base.py",
    "content": "#\n# ./ctags --fields='*' --extras='*' -o output.tags base.py\n#\nclass Foo:\n    def aq ():\n        pass\n    def aw ():\n        pass\n    def ae ():\n        pass\n    class A:\n        pass\nclass Bar (Foo):\n    def bq ():\n        pass\n    def bw ():\n        pass\n    class B:\n        pass\n\nclass Baz (Foo): \n    def bq ():\n        pass\n    def bw ():\n        pass\n    class C:\n        pass\n            \n"
  },
  {
    "path": "Tmain/readtags-qualifier.d/c.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/;\"\textras:pseudo\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/;\"\textras:pseudo\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/;\"\textras:pseudo\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/;\"\textras:pseudo\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/;\"\textras:pseudo\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//;\"\textras:pseudo\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/;\"\textras:pseudo\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/;\"\textras:pseudo\n!_TAG_PROGRAM_VERSION\t0.0.0\t/158beae9/;\"\textras:pseudo\nargc\tbase.c\t/^main(int argc, char ** argv)$/;\"\tkind:parameter\tline:5\tlanguage:C\tscope:function:main\ttyperef:typename:int\tfile:\troles:def\textras:fileScope\nargv\tbase.c\t/^main(int argc, char ** argv)$/;\"\tkind:parameter\tline:5\tlanguage:C\tscope:function:main\ttyperef:typename:char **\tfile:\troles:def\textras:fileScope\nmain\tbase.c\t/^main(int argc, char ** argv)$/;\"\tkind:function\tline:5\tlanguage:C\ttyperef:typename:int\tsignature:(int argc,char ** argv)\troles:def\tend:9\nr\tbase.c\t/^\tint r = argc + 1;$/;\"\tkind:local\tline:7\tlanguage:C\tscope:function:main\ttyperef:typename:int\tfile:\troles:def\textras:fileScope\tend:7\n"
  },
  {
    "path": "Tmain/readtags-qualifier.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-qualifier.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/bbd8fc2/\nA\tbase.py\t/^    class A:$/;\"\tkind:class\tline:11\tlanguage:Python\tscope:class:Foo\tinherits:\taccess:public\nB\tbase.py\t/^    class B:$/;\"\tkind:class\tline:18\tlanguage:Python\tscope:class:Bar\tinherits:\taccess:public\nBar\tbase.py\t/^class Bar (Foo):$/;\"\tkind:class\tline:13\tlanguage:Python\tinherits:Foo\taccess:public\nBar.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tline:14\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nBar.bw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tline:16\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nBaz\tbase.py\t/^class Baz (Foo): $/;\"\tkind:class\tline:21\tlanguage:Python\tinherits:Foo\taccess:public\nBaz.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tline:22\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nBaz.bw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tline:24\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nC\tbase.py\t/^    class C:$/;\"\tkind:class\tline:26\tlanguage:Python\tscope:class:Baz\tinherits:\taccess:public\nFoo\tbase.py\t/^class Foo:$/;\"\tkind:class\tline:4\tlanguage:Python\tinherits:\taccess:public\nFoo.ae\tbase.py\t/^    def ae ():$/;\"\tkind:member\tline:9\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nFoo.aq\tbase.py\t/^    def aq ():$/;\"\tkind:member\tline:5\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nFoo.aw\tbase.py\t/^    def aw ():$/;\"\tkind:member\tline:7\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nae\tbase.py\t/^    def ae ():$/;\"\tkind:member\tline:9\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\naq\tbase.py\t/^    def aq ():$/;\"\tkind:member\tline:5\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\naw\tbase.py\t/^    def aw ():$/;\"\tkind:member\tline:7\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nbase.py\tbase.py\t28;\"\tkind:file\tline:28\tlanguage:Python\nbq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tline:14\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nbq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tline:22\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nbw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tline:16\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nbw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tline:24\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\n"
  },
  {
    "path": "Tmain/readtags-qualifier.d/roles.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/bbd8fc2/\nBar\tbase.py\t/^class Bar (Foo):$/;\"\tkind:class\tline:13\tlanguage:Python\tinherits:Foo\taccess:public\nBaz\tbase.py\t/^class Baz (Foo): $/;\"\tkind:class\tline:21\tlanguage:Python\tinherits:Foo\taccess:public\nFoo\tbase.py\t/^class Bar (Foo):$/;\"\tkind:class\tline:13\tlanguage:Python\troles:superClass\nFoo\tbase.py\t/^class Baz (Foo): $/;\"\tkind:class\tline:21\tlanguage:Python\troles:superClass\n\n"
  },
  {
    "path": "Tmain/readtags-qualifier.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\necho ';; (suffix? $name \"q\")' &&\n${V} ${READTAGS} -e -t output.tags -Q '(suffix? $name \"q\")' -l &&\necho ';; (and (eq? $kind \"member\") (eq? \"Baz\" $scope-name))' &&\n${V} ${READTAGS} -e -t output.tags -Q '(and (eq? $kind \"member\") (eq? \"Baz\" $scope-name))' -l &&\necho ';; (and (eq? $kind \"member\") (substr? $name \".\"))' &&\n${V} ${READTAGS} -e -t output.tags -Q '(and (eq? $kind \"member\") (substr? $name \".\"))' -l &&\necho ';; (and $inherits (#/(^|,)Foo(,|$)/ $inherits) (eq? $kind \"class\"))' &&\n${V} ${READTAGS}  -e -t output.tags -Q '(and $inherits (#/(^|,)Foo(,|$)/ $inherits) (eq? $kind \"class\"))' -l &&\necho ';; (not ($ \"signature\"))' &&\n${V} ${READTAGS}  -e -t output.tags -Q '(not ($ \"signature\"))' -l &&\necho ';; (< 1 2)' &&\n${V} ${READTAGS}  -e -t output.tags -Q '(< 1 2)' -l &&\necho ';; (and $roles (#/(^|,)superClass(,|$)/ $roles))' &&\n${V} ${READTAGS}  -e -n -t roles.tags -Q '(and $roles (#/(^|,)superClass(,|$)/ $roles))' -l &&\necho ';; (substr? (or ($ \"roles\") \"\") \"super\")' &&\n${V} ${READTAGS}  -e -t roles.tags -Q '(substr? (or ($ \"roles\") \"\") \"super\")' -l &&\necho ';; (and (eq? $scope-kind \"function\") (eq? $kind \"local\"))' &&\n${V} ${READTAGS}  -e -t c.tags -Q '(and (eq? $scope-kind \"function\") (eq? $kind \"local\"))' -l &&\n:\n"
  },
  {
    "path": "Tmain/readtags-qualifier.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-qualifier.d/stdout-expected.txt",
    "content": ";; (suffix? $name \"q\")\nBar.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nBaz.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nFoo.aq\tbase.py\t/^    def aq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\naq\tbase.py\t/^    def aq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nbq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nbq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\n;; (and (eq? $kind \"member\") (eq? \"Baz\" $scope-name))\nBaz.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nBaz.bw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nbq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nbw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\n;; (and (eq? $kind \"member\") (substr? $name \".\"))\nBar.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nBar.bw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nBaz.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nBaz.bw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nFoo.ae\tbase.py\t/^    def ae ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nFoo.aq\tbase.py\t/^    def aq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nFoo.aw\tbase.py\t/^    def aw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\n;; (and $inherits (#/(^|,)Foo(,|$)/ $inherits) (eq? $kind \"class\"))\nBar\tbase.py\t/^class Bar (Foo):$/;\"\tkind:class\tlanguage:Python\tinherits:Foo\taccess:public\nBaz\tbase.py\t/^class Baz (Foo): $/;\"\tkind:class\tlanguage:Python\tinherits:Foo\taccess:public\n;; (not ($ \"signature\"))\nA\tbase.py\t/^    class A:$/;\"\tkind:class\tlanguage:Python\tscope:class:Foo\tinherits:\taccess:public\nB\tbase.py\t/^    class B:$/;\"\tkind:class\tlanguage:Python\tscope:class:Bar\tinherits:\taccess:public\nBar\tbase.py\t/^class Bar (Foo):$/;\"\tkind:class\tlanguage:Python\tinherits:Foo\taccess:public\nBaz\tbase.py\t/^class Baz (Foo): $/;\"\tkind:class\tlanguage:Python\tinherits:Foo\taccess:public\nC\tbase.py\t/^    class C:$/;\"\tkind:class\tlanguage:Python\tscope:class:Baz\tinherits:\taccess:public\nFoo\tbase.py\t/^class Foo:$/;\"\tkind:class\tlanguage:Python\tinherits:\taccess:public\nbase.py\tbase.py\t28;\"\tkind:file\tlanguage:Python\n;; (< 1 2)\nA\tbase.py\t/^    class A:$/;\"\tkind:class\tlanguage:Python\tscope:class:Foo\tinherits:\taccess:public\nB\tbase.py\t/^    class B:$/;\"\tkind:class\tlanguage:Python\tscope:class:Bar\tinherits:\taccess:public\nBar\tbase.py\t/^class Bar (Foo):$/;\"\tkind:class\tlanguage:Python\tinherits:Foo\taccess:public\nBar.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nBar.bw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nBaz\tbase.py\t/^class Baz (Foo): $/;\"\tkind:class\tlanguage:Python\tinherits:Foo\taccess:public\nBaz.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nBaz.bw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nC\tbase.py\t/^    class C:$/;\"\tkind:class\tlanguage:Python\tscope:class:Baz\tinherits:\taccess:public\nFoo\tbase.py\t/^class Foo:$/;\"\tkind:class\tlanguage:Python\tinherits:\taccess:public\nFoo.ae\tbase.py\t/^    def ae ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nFoo.aq\tbase.py\t/^    def aq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nFoo.aw\tbase.py\t/^    def aw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nae\tbase.py\t/^    def ae ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\naq\tbase.py\t/^    def aq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\naw\tbase.py\t/^    def aw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nbase.py\tbase.py\t28;\"\tkind:file\tlanguage:Python\nbq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nbq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nbw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nbw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\n;; (and $roles (#/(^|,)superClass(,|$)/ $roles))\nFoo\tbase.py\t/^class Bar (Foo):$/;\"\tkind:class\tline:13\tlanguage:Python\troles:superClass\nFoo\tbase.py\t/^class Baz (Foo): $/;\"\tkind:class\tline:21\tlanguage:Python\troles:superClass\n;; (substr? (or ($ \"roles\") \"\") \"super\")\nFoo\tbase.py\t/^class Bar (Foo):$/;\"\tkind:class\tlanguage:Python\troles:superClass\nFoo\tbase.py\t/^class Baz (Foo): $/;\"\tkind:class\tlanguage:Python\troles:superClass\n;; (and (eq? $scope-kind \"function\") (eq? $kind \"local\"))\nr\tbase.c\t/^\tint r = argc + 1;$/;\"\tkind:local\tfile:\tlanguage:C\tscope:function:main\ttyperef:typename:int\troles:def\textras:fileScope\tend:7\n"
  },
  {
    "path": "Tmain/readtags-simple-listing.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-simple-listing.d/input.c",
    "content": "/* u-ctags --sort=yes --fields=* -o output.tags input.c */\nint var;\nstrcut st {\n\tint m0;\n\tint m2;\n};\nchar c;\ntypedef strcut st tst;\n"
  },
  {
    "path": "Tmain/readtags-simple-listing.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '# no -e option' &&\n${V} ${READTAGS} -t ./sorted.tags -l &&\n\necho '# with -e option' &&\n${V} ${READTAGS} -e -t ./sorted.tags -l &&\n\necho '# with -e -n option' &&\n${V} ${READTAGS} -e -n -t ./sorted.tags -l\n"
  },
  {
    "path": "Tmain/readtags-simple-listing.d/sorted.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/;\"\textras:pseudo\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/;\"\textras:pseudo\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/;\"\textras:pseudo\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/;\"\textras:pseudo\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/;\"\textras:pseudo\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//;\"\textras:pseudo\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/;\"\textras:pseudo\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/;\"\textras:pseudo\n!_TAG_PROGRAM_VERSION\t0.0.0\t/5cbc78e4/;\"\textras:pseudo\nc\tinput.c\t/^char c;$/;\"\tkind:variable\tline:7\tlanguage:C\ttyperef:typename:char\troles:def\tend:7\nm0\tinput.c\t/^\tint m0;$/;\"\tkind:variable\tline:4\tlanguage:C\ttyperef:typename:int\troles:def\tend:4\nm2\tinput.c\t/^\tint m2;$/;\"\tkind:variable\tline:5\tlanguage:C\ttyperef:typename:int\troles:def\tend:5\ntst\tinput.c\t/^typedef strcut st tst;$/;\"\tkind:typedef\tline:8\tlanguage:C\ttyperef:typename:strcut st\tfile:\troles:def\textras:fileScope\nvar\tinput.c\t/^int var;$/;\"\tkind:variable\tline:65535\tlanguage:C\ttyperef:typename:int\troles:def\tend:4294967295\n"
  },
  {
    "path": "Tmain/readtags-simple-listing.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-simple-listing.d/stdout-expected.txt",
    "content": "# no -e option\nc\tinput.c\t/^char c;$/\nm0\tinput.c\t/^\tint m0;$/\nm2\tinput.c\t/^\tint m2;$/\ntst\tinput.c\t/^typedef strcut st tst;$/\nvar\tinput.c\t/^int var;$/\n# with -e option\nc\tinput.c\t/^char c;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:char\troles:def\tend:7\nm0\tinput.c\t/^\tint m0;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:4\nm2\tinput.c\t/^\tint m2;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:5\ntst\tinput.c\t/^typedef strcut st tst;$/;\"\tkind:typedef\tfile:\tlanguage:C\ttyperef:typename:strcut st\troles:def\textras:fileScope\nvar\tinput.c\t/^int var;$/;\"\tkind:variable\tlanguage:C\ttyperef:typename:int\troles:def\tend:4294967295\n# with -e -n option\nc\tinput.c\t/^char c;$/;\"\tkind:variable\tline:7\tlanguage:C\ttyperef:typename:char\troles:def\tend:7\nm0\tinput.c\t/^\tint m0;$/;\"\tkind:variable\tline:4\tlanguage:C\ttyperef:typename:int\troles:def\tend:4\nm2\tinput.c\t/^\tint m2;$/;\"\tkind:variable\tline:5\tlanguage:C\ttyperef:typename:int\troles:def\tend:5\ntst\tinput.c\t/^typedef strcut st tst;$/;\"\tkind:typedef\tfile:\tline:8\tlanguage:C\ttyperef:typename:strcut st\troles:def\textras:fileScope\nvar\tinput.c\t/^int var;$/;\"\tkind:variable\tline:65535\tlanguage:C\ttyperef:typename:int\troles:def\tend:4294967295\n"
  },
  {
    "path": "Tmain/readtags-sorter-cmp_or-sform.d/README.md",
    "content": "How to generate output.tags::\n\n    ctags  --kinds-C=+p -o output.tags input.d/foo.c input.d/bar.c input.d/decl.h \n\nThis is taken from https://github.com/universal-ctags/ctags/issues/4015#issuecomment-2157023359\n"
  },
  {
    "path": "Tmain/readtags-sorter-cmp_or-sform.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-sorter-cmp_or-sform.d/input.d/bar.c",
    "content": "void bar(void);\nvoid bar(void) {}\n"
  },
  {
    "path": "Tmain/readtags-sorter-cmp_or-sform.d/input.d/decl.h",
    "content": "void foo(void);\n"
  },
  {
    "path": "Tmain/readtags-sorter-cmp_or-sform.d/input.d/foo.c",
    "content": "void foo(void) {}\n"
  },
  {
    "path": "Tmain/readtags-sorter-cmp_or-sform.d/output.tags",
    "content": "!_TAG_EXTRA_DESCRIPTION\tanonymous\t/Include tags for non-named objects like lambda/\n!_TAG_EXTRA_DESCRIPTION\tfileScope\t/Include tags of file scope/\n!_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n!_TAG_EXTRA_DESCRIPTION\tsubparser\t/Include tags generated by subparsers/\n!_TAG_FIELD_DESCRIPTION\tepoch\t/the last modified time of the input file (only for F\\/file kind tag)/\n!_TAG_FIELD_DESCRIPTION\tfile\t/File-restricted scoping/\n!_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n!_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n!_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n!_TAG_FIELD_DESCRIPTION\ttyperef\t/Type and name of a variable or typedef/\n!_TAG_FIELD_DESCRIPTION!C++\tname\t/aliased names/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C++\tc,class\t/classes/\n!_TAG_KIND_DESCRIPTION!C++\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C++\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C++\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C++\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C++\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C++\tm,member\t/class, struct, and union members/\n!_TAG_KIND_DESCRIPTION!C++\tn,namespace\t/namespaces/\n!_TAG_KIND_DESCRIPTION!C++\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C++\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C++\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C++\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C++\tv,variable\t/variable definitions/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_VERSION\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!C\t0.0\t/current.age/\n!_TAG_PARSER_VERSION!C++\t0.0\t/current.age/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/yamato/var/ctags-github/Tmain/readtags-sorter-if3-sform.d/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t6.0.0\t//\n!_TAG_ROLE_DESCRIPTION!C!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C!header\tsystem\t/system header/\n!_TAG_ROLE_DESCRIPTION!C!macro\tundef\t/undefined/\n!_TAG_ROLE_DESCRIPTION!C++!header\tlocal\t/local header/\n!_TAG_ROLE_DESCRIPTION!C++!header\tsystem\t/system header/\n!_TAG_ROLE_DESCRIPTION!C++!macro\tundef\t/undefined/\nbar\tinput.d/bar.c\t/^void bar(void) {}$/;\"\tf\ttyperef:typename:void\nbar\tinput.d/bar.c\t/^void bar(void);$/;\"\tp\ttyperef:typename:void\tfile:\nfoo\tinput.d/decl.h\t/^void foo(void);$/;\"\tp\ttyperef:typename:void\nfoo\tinput.d/foo.c\t/^void foo(void) {}$/;\"\tf\ttyperef:typename:void\n"
  },
  {
    "path": "Tmain/readtags-sorter-cmp_or-sform.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2024 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\nERRLOG=/tmp/ctags-Tmain-$$\n${READTAGS} -et output.tags -S '\n(<or> (<> $name &name)\n      (and (eq? $kind \"p\") (eq? &kind \"f\")  1)\n      (and (eq? $kind \"f\") (eq? &kind \"p\") -1))' -l\n"
  },
  {
    "path": "Tmain/readtags-sorter-cmp_or-sform.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-sorter-cmp_or-sform.d/stdout-expected.txt",
    "content": "bar\tinput.d/bar.c\t/^void bar(void) {}$/;\"\tkind:f\ttyperef:typename:void\nbar\tinput.d/bar.c\t/^void bar(void);$/;\"\tkind:p\tfile:\ttyperef:typename:void\nfoo\tinput.d/foo.c\t/^void foo(void) {}$/;\"\tkind:f\ttyperef:typename:void\nfoo\tinput.d/decl.h\t/^void foo(void);$/;\"\tkind:p\ttyperef:typename:void\n"
  },
  {
    "path": "Tmain/readtags-sorter-if-sform-order.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-sorter-if-sform-order.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/717028d4/\nmutex\tinput.c\t/^\tint mutex;$/;\"\tm\tlanguage:C\tstruct:MUTEX_S\ttyperef:typename:int\tfile:\n\n"
  },
  {
    "path": "Tmain/readtags-sorter-if-sform-order.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n${READTAGS} -t output.tags -ne -Q '(if $extras (print $extras) #f)' -l\n"
  },
  {
    "path": "Tmain/readtags-sorter-if-sform-order.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-sorter-if-sform-order.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-sorter-if-sform.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-sorter-if-sform.d/input.c",
    "content": "enum  MUTEX_E { mutex_a, mutex_b, mutex };\n\n#define mutex mutex\n\nint mutex;\n\nstruct MUTEX_S {\n\tint mutex;\n};\n\ntypedef mutex int;\n"
  },
  {
    "path": "Tmain/readtags-sorter-if-sform.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/717028d4/\nMUTEX_E\tinput.c\t/^enum  MUTEX_E { mutex_a, mutex_b, mutex };$/;\"\tg\tlanguage:C\tfile:\nMUTEX_S\tinput.c\t/^struct MUTEX_S {$/;\"\ts\tlanguage:C\tfile:\nmutex\tinput.c\t/^\tint mutex;$/;\"\tm\tlanguage:C\tstruct:MUTEX_S\ttyperef:typename:int\tfile:\nmutex\tinput.c\t/^#define mutex /;\"\td\tlanguage:C\tfile:\nmutex\tinput.c\t/^enum  MUTEX_E { mutex_a, mutex_b, mutex };$/;\"\te\tlanguage:C\tenum:MUTEX_E\tfile:\nmutex\tinput.c\t/^int mutex;$/;\"\tv\tlanguage:C\ttyperef:typename:int\nmutex\tinput.c\t/^typedef mutex int;$/;\"\tt\tlanguage:C\ttyperef:typename:int\tfile:\nmutex_a\tinput.c\t/^enum  MUTEX_E { mutex_a, mutex_b, mutex };$/;\"\te\tlanguage:C\tenum:MUTEX_E\tfile:\nmutex_b\tinput.c\t/^enum  MUTEX_E { mutex_a, mutex_b, mutex };$/;\"\te\tlanguage:C\tenum:MUTEX_E\tfile:\n"
  },
  {
    "path": "Tmain/readtags-sorter-if-sform.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n${READTAGS} -t output.tags -ne -S '(if (eq? $kind &kind)\n    0\n  (+\n   (if (or (eq? $kind \"t\"))\n       -4\n     (if (eq? $kind \"v\")\n\t -3\n       (if (eq? $kind \"d\")\n\t   -2\n\t (if (eq? $kind \"e\")\n\t     -1\n\t   0))))\n   (if (or (eq? &kind \"t\"))\n       4\n     (if (eq? &kind \"v\")\n\t 3\n       (if (eq? &kind \"d\")\n\t   2\n\t (if (eq? &kind \"e\")\n\t     1\n\t   0))))))' mutex\n"
  },
  {
    "path": "Tmain/readtags-sorter-if-sform.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-sorter-if-sform.d/stdout-expected.txt",
    "content": "mutex\tinput.c\t/^typedef mutex int;$/;\"\tkind:t\tfile:\tlanguage:C\ttyperef:typename:int\nmutex\tinput.c\t/^int mutex;$/;\"\tkind:v\tlanguage:C\ttyperef:typename:int\nmutex\tinput.c\t/^#define mutex /;\"\tkind:d\tfile:\tlanguage:C\nmutex\tinput.c\t/^enum  MUTEX_E { mutex_a, mutex_b, mutex };$/;\"\tkind:e\tfile:\tlanguage:C\tenum:MUTEX_E\nmutex\tinput.c\t/^\tint mutex;$/;\"\tkind:m\tfile:\tlanguage:C\tstruct:MUTEX_S\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-sorter.d/.ctags.d/0.ctags",
    "content": "--fields=*\n-L .ctags.d/src.list\n-o output.tags\n"
  },
  {
    "path": "Tmain/readtags-sorter.d/.ctags.d/src.list",
    "content": "src/input-area.cpp\nsrc/input-volume.cpp\nsrc/input.h\n"
  },
  {
    "path": "Tmain/readtags-sorter.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-sorter.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/;\"\textras:pseudo\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/;\"\textras:pseudo\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/;\"\textras:pseudo\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/;\"\textras:pseudo\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/;\"\textras:pseudo\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//;\"\textras:pseudo\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/;\"\textras:pseudo\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/;\"\textras:pseudo\n!_TAG_PROGRAM_VERSION\t0.0.0\t/77f9ac3f/;\"\textras:pseudo\nINPUT_DATA_H\tsrc/input.h\t/^#define INPUT_DATA_H$/;\"\tkind:macro\tline:2\tlanguage:C++\troles:def\tend:2\narea\tsrc/input-area.cpp\t/^float area   (fpoint2d &p)$/;\"\tkind:function\tline:8\tlanguage:C++\ttyperef:typename:float\tsignature:(fpoint2d & p)\troles:def\tend:11\narea\tsrc/input-area.cpp\t/^float area   (ipoint2d &p)$/;\"\tkind:function\tline:3\tlanguage:C++\ttyperef:typename:float\tsignature:(ipoint2d & p)\troles:def\tend:6\nfpoint2d\tsrc/input.h\t/^struct fpoint2d {$/;\"\tkind:struct\tline:12\tlanguage:C++\troles:def\tend:14\nfpoint3d\tsrc/input.h\t/^struct fpoint3d {$/;\"\tkind:struct\tline:16\tlanguage:C++\troles:def\tend:19\nipoint2d\tsrc/input.h\t/^struct ipoint2d {$/;\"\tkind:struct\tline:4\tlanguage:C++\troles:def\tend:6\nipoint3d\tsrc/input.h\t/^struct ipoint3d {$/;\"\tkind:struct\tline:8\tlanguage:C++\troles:def\tend:10\nparent\tsrc/input.h\t/^  fpoint2d parent;$/;\"\tkind:member\tline:17\tlanguage:C++\tscope:struct:fpoint3d\ttyperef:typename:fpoint2d\taccess:public\troles:def\tend:17\nvolume\tsrc/input-volume.cpp\t/^float volume (fpoint3d *p)$/;\"\tkind:function\tline:8\tlanguage:C++\ttyperef:typename:float\tsignature:(fpoint3d * p)\troles:def\tend:11\nvolume\tsrc/input-volume.cpp\t/^float volume (ipoint3d *p)$/;\"\tkind:function\tline:3\tlanguage:C++\ttyperef:typename:float\tsignature:(ipoint3d * p)\troles:def\tend:6\nx\tsrc/input.h\t/^  float x, y;$/;\"\tkind:member\tline:13\tlanguage:C++\tscope:struct:fpoint2d\ttyperef:typename:float\taccess:public\troles:def\tend:13\nx\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\nx\tsrc/input.h\t/^  int x, y;$/;\"\tkind:member\tline:5\tlanguage:C++\tscope:struct:ipoint2d\ttyperef:typename:int\taccess:public\troles:def\tend:5\ny\tsrc/input.h\t/^  float x, y;$/;\"\tkind:member\tline:13\tlanguage:C++\tscope:struct:fpoint2d\ttyperef:typename:float\taccess:public\troles:def\tend:13\ny\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\ny\tsrc/input.h\t/^  int x, y;$/;\"\tkind:member\tline:5\tlanguage:C++\tscope:struct:ipoint2d\ttyperef:typename:int\taccess:public\troles:def\tend:5\nz\tsrc/input.h\t/^  float z;$/;\"\tkind:member\tline:18\tlanguage:C++\tscope:struct:fpoint3d\ttyperef:typename:float\taccess:public\troles:def\tend:18\nz\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\n"
  },
  {
    "path": "Tmain/readtags-sorter.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '!_INPUT_ORDER' &&\n${READTAGS} -t output.tags -ne -S '(<or> (<> $input &input) (<> $line &line) (<> $name &name))' -l &&\n\necho '!_INPUT_ORDER with flipping' &&\n${READTAGS} -t output.tags -ne -S '(*- (<or> (<> $input &input) (<> $line &line) (<> $name &name)))' -l &&\n\necho '!_COMPARING_CODE_SIZE' &&\n${READTAGS} -t output.tags -ne -S '(<or> (*- (<> (- (or $end $line) $line) (- (or &end &line) &line))) (<> $input &input) (<> $line &line) (<> $name &name))' -l\n\necho '!_INPUT_ORDER of structure members (linear search)' &&\n${READTAGS} -t output.tags -ne -Q '(eq? $kind \"member\")' -S '(<or> (<> $input &input) (<> $line &line) (<> $name &name))' -l\n"
  },
  {
    "path": "Tmain/readtags-sorter.d/src/input-area.cpp",
    "content": "#include \"input.h\"\n\nfloat area   (ipoint2d &p)\n{\n  return (float)(p.x * p.y);\n}\n\nfloat area   (fpoint2d &p)\n{\n  return p.x * p.y;\n}\n"
  },
  {
    "path": "Tmain/readtags-sorter.d/src/input-volume.cpp",
    "content": "#include \"input.h\"\n\nfloat volume (ipoint3d *p)\n{\n  return (float)(p->x * p->y * p->z);\n}\n\nfloat volume (fpoint3d *p)\n{\n  return area (p->parent) * p->z;\n}\n"
  },
  {
    "path": "Tmain/readtags-sorter.d/src/input.h",
    "content": "#ifndef INPUT_DATA_H\n#define INPUT_DATA_H\n\nstruct ipoint2d {\n  int x, y;\n};\n\nstruct ipoint3d {\n  int x, y, z;\n};\n\nstruct fpoint2d {\n  float x, y;\n};\n\nstruct fpoint3d {\n  fpoint2d parent;\n  float z;\n};\n\nfloat area   (ipoint2d &p);\nfloat area   (fpoint2d &p);\nfloat volume (ipoint3d *p);\nfloat volume (fpoint3d *p);\n\n#endif\n"
  },
  {
    "path": "Tmain/readtags-sorter.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-sorter.d/stdout-expected.txt",
    "content": "!_INPUT_ORDER\narea\tsrc/input-area.cpp\t/^float area   (ipoint2d &p)$/;\"\tkind:function\tline:3\tlanguage:C++\ttyperef:typename:float\tsignature:(ipoint2d & p)\troles:def\tend:6\narea\tsrc/input-area.cpp\t/^float area   (fpoint2d &p)$/;\"\tkind:function\tline:8\tlanguage:C++\ttyperef:typename:float\tsignature:(fpoint2d & p)\troles:def\tend:11\nvolume\tsrc/input-volume.cpp\t/^float volume (ipoint3d *p)$/;\"\tkind:function\tline:3\tlanguage:C++\ttyperef:typename:float\tsignature:(ipoint3d * p)\troles:def\tend:6\nvolume\tsrc/input-volume.cpp\t/^float volume (fpoint3d *p)$/;\"\tkind:function\tline:8\tlanguage:C++\ttyperef:typename:float\tsignature:(fpoint3d * p)\troles:def\tend:11\nINPUT_DATA_H\tsrc/input.h\t/^#define INPUT_DATA_H$/;\"\tkind:macro\tline:2\tlanguage:C++\troles:def\tend:2\nipoint2d\tsrc/input.h\t/^struct ipoint2d {$/;\"\tkind:struct\tline:4\tlanguage:C++\troles:def\tend:6\nx\tsrc/input.h\t/^  int x, y;$/;\"\tkind:member\tline:5\tlanguage:C++\tscope:struct:ipoint2d\ttyperef:typename:int\taccess:public\troles:def\tend:5\ny\tsrc/input.h\t/^  int x, y;$/;\"\tkind:member\tline:5\tlanguage:C++\tscope:struct:ipoint2d\ttyperef:typename:int\taccess:public\troles:def\tend:5\nipoint3d\tsrc/input.h\t/^struct ipoint3d {$/;\"\tkind:struct\tline:8\tlanguage:C++\troles:def\tend:10\nx\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\ny\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\nz\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\nfpoint2d\tsrc/input.h\t/^struct fpoint2d {$/;\"\tkind:struct\tline:12\tlanguage:C++\troles:def\tend:14\nx\tsrc/input.h\t/^  float x, y;$/;\"\tkind:member\tline:13\tlanguage:C++\tscope:struct:fpoint2d\ttyperef:typename:float\taccess:public\troles:def\tend:13\ny\tsrc/input.h\t/^  float x, y;$/;\"\tkind:member\tline:13\tlanguage:C++\tscope:struct:fpoint2d\ttyperef:typename:float\taccess:public\troles:def\tend:13\nfpoint3d\tsrc/input.h\t/^struct fpoint3d {$/;\"\tkind:struct\tline:16\tlanguage:C++\troles:def\tend:19\nparent\tsrc/input.h\t/^  fpoint2d parent;$/;\"\tkind:member\tline:17\tlanguage:C++\tscope:struct:fpoint3d\ttyperef:typename:fpoint2d\taccess:public\troles:def\tend:17\nz\tsrc/input.h\t/^  float z;$/;\"\tkind:member\tline:18\tlanguage:C++\tscope:struct:fpoint3d\ttyperef:typename:float\taccess:public\troles:def\tend:18\n!_INPUT_ORDER with flipping\nz\tsrc/input.h\t/^  float z;$/;\"\tkind:member\tline:18\tlanguage:C++\tscope:struct:fpoint3d\ttyperef:typename:float\taccess:public\troles:def\tend:18\nparent\tsrc/input.h\t/^  fpoint2d parent;$/;\"\tkind:member\tline:17\tlanguage:C++\tscope:struct:fpoint3d\ttyperef:typename:fpoint2d\taccess:public\troles:def\tend:17\nfpoint3d\tsrc/input.h\t/^struct fpoint3d {$/;\"\tkind:struct\tline:16\tlanguage:C++\troles:def\tend:19\ny\tsrc/input.h\t/^  float x, y;$/;\"\tkind:member\tline:13\tlanguage:C++\tscope:struct:fpoint2d\ttyperef:typename:float\taccess:public\troles:def\tend:13\nx\tsrc/input.h\t/^  float x, y;$/;\"\tkind:member\tline:13\tlanguage:C++\tscope:struct:fpoint2d\ttyperef:typename:float\taccess:public\troles:def\tend:13\nfpoint2d\tsrc/input.h\t/^struct fpoint2d {$/;\"\tkind:struct\tline:12\tlanguage:C++\troles:def\tend:14\nz\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\ny\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\nx\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\nipoint3d\tsrc/input.h\t/^struct ipoint3d {$/;\"\tkind:struct\tline:8\tlanguage:C++\troles:def\tend:10\ny\tsrc/input.h\t/^  int x, y;$/;\"\tkind:member\tline:5\tlanguage:C++\tscope:struct:ipoint2d\ttyperef:typename:int\taccess:public\troles:def\tend:5\nx\tsrc/input.h\t/^  int x, y;$/;\"\tkind:member\tline:5\tlanguage:C++\tscope:struct:ipoint2d\ttyperef:typename:int\taccess:public\troles:def\tend:5\nipoint2d\tsrc/input.h\t/^struct ipoint2d {$/;\"\tkind:struct\tline:4\tlanguage:C++\troles:def\tend:6\nINPUT_DATA_H\tsrc/input.h\t/^#define INPUT_DATA_H$/;\"\tkind:macro\tline:2\tlanguage:C++\troles:def\tend:2\nvolume\tsrc/input-volume.cpp\t/^float volume (fpoint3d *p)$/;\"\tkind:function\tline:8\tlanguage:C++\ttyperef:typename:float\tsignature:(fpoint3d * p)\troles:def\tend:11\nvolume\tsrc/input-volume.cpp\t/^float volume (ipoint3d *p)$/;\"\tkind:function\tline:3\tlanguage:C++\ttyperef:typename:float\tsignature:(ipoint3d * p)\troles:def\tend:6\narea\tsrc/input-area.cpp\t/^float area   (fpoint2d &p)$/;\"\tkind:function\tline:8\tlanguage:C++\ttyperef:typename:float\tsignature:(fpoint2d & p)\troles:def\tend:11\narea\tsrc/input-area.cpp\t/^float area   (ipoint2d &p)$/;\"\tkind:function\tline:3\tlanguage:C++\ttyperef:typename:float\tsignature:(ipoint2d & p)\troles:def\tend:6\n!_COMPARING_CODE_SIZE\narea\tsrc/input-area.cpp\t/^float area   (ipoint2d &p)$/;\"\tkind:function\tline:3\tlanguage:C++\ttyperef:typename:float\tsignature:(ipoint2d & p)\troles:def\tend:6\narea\tsrc/input-area.cpp\t/^float area   (fpoint2d &p)$/;\"\tkind:function\tline:8\tlanguage:C++\ttyperef:typename:float\tsignature:(fpoint2d & p)\troles:def\tend:11\nvolume\tsrc/input-volume.cpp\t/^float volume (ipoint3d *p)$/;\"\tkind:function\tline:3\tlanguage:C++\ttyperef:typename:float\tsignature:(ipoint3d * p)\troles:def\tend:6\nvolume\tsrc/input-volume.cpp\t/^float volume (fpoint3d *p)$/;\"\tkind:function\tline:8\tlanguage:C++\ttyperef:typename:float\tsignature:(fpoint3d * p)\troles:def\tend:11\nfpoint3d\tsrc/input.h\t/^struct fpoint3d {$/;\"\tkind:struct\tline:16\tlanguage:C++\troles:def\tend:19\nipoint2d\tsrc/input.h\t/^struct ipoint2d {$/;\"\tkind:struct\tline:4\tlanguage:C++\troles:def\tend:6\nipoint3d\tsrc/input.h\t/^struct ipoint3d {$/;\"\tkind:struct\tline:8\tlanguage:C++\troles:def\tend:10\nfpoint2d\tsrc/input.h\t/^struct fpoint2d {$/;\"\tkind:struct\tline:12\tlanguage:C++\troles:def\tend:14\nINPUT_DATA_H\tsrc/input.h\t/^#define INPUT_DATA_H$/;\"\tkind:macro\tline:2\tlanguage:C++\troles:def\tend:2\nx\tsrc/input.h\t/^  int x, y;$/;\"\tkind:member\tline:5\tlanguage:C++\tscope:struct:ipoint2d\ttyperef:typename:int\taccess:public\troles:def\tend:5\ny\tsrc/input.h\t/^  int x, y;$/;\"\tkind:member\tline:5\tlanguage:C++\tscope:struct:ipoint2d\ttyperef:typename:int\taccess:public\troles:def\tend:5\nx\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\ny\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\nz\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\nx\tsrc/input.h\t/^  float x, y;$/;\"\tkind:member\tline:13\tlanguage:C++\tscope:struct:fpoint2d\ttyperef:typename:float\taccess:public\troles:def\tend:13\ny\tsrc/input.h\t/^  float x, y;$/;\"\tkind:member\tline:13\tlanguage:C++\tscope:struct:fpoint2d\ttyperef:typename:float\taccess:public\troles:def\tend:13\nparent\tsrc/input.h\t/^  fpoint2d parent;$/;\"\tkind:member\tline:17\tlanguage:C++\tscope:struct:fpoint3d\ttyperef:typename:fpoint2d\taccess:public\troles:def\tend:17\nz\tsrc/input.h\t/^  float z;$/;\"\tkind:member\tline:18\tlanguage:C++\tscope:struct:fpoint3d\ttyperef:typename:float\taccess:public\troles:def\tend:18\n!_INPUT_ORDER of structure members (linear search)\nx\tsrc/input.h\t/^  int x, y;$/;\"\tkind:member\tline:5\tlanguage:C++\tscope:struct:ipoint2d\ttyperef:typename:int\taccess:public\troles:def\tend:5\ny\tsrc/input.h\t/^  int x, y;$/;\"\tkind:member\tline:5\tlanguage:C++\tscope:struct:ipoint2d\ttyperef:typename:int\taccess:public\troles:def\tend:5\nx\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\ny\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\nz\tsrc/input.h\t/^  int x, y, z;$/;\"\tkind:member\tline:9\tlanguage:C++\tscope:struct:ipoint3d\ttyperef:typename:int\taccess:public\troles:def\tend:9\nx\tsrc/input.h\t/^  float x, y;$/;\"\tkind:member\tline:13\tlanguage:C++\tscope:struct:fpoint2d\ttyperef:typename:float\taccess:public\troles:def\tend:13\ny\tsrc/input.h\t/^  float x, y;$/;\"\tkind:member\tline:13\tlanguage:C++\tscope:struct:fpoint2d\ttyperef:typename:float\taccess:public\troles:def\tend:13\nparent\tsrc/input.h\t/^  fpoint2d parent;$/;\"\tkind:member\tline:17\tlanguage:C++\tscope:struct:fpoint3d\ttyperef:typename:fpoint2d\taccess:public\troles:def\tend:17\nz\tsrc/input.h\t/^  float z;$/;\"\tkind:member\tline:18\tlanguage:C++\tscope:struct:fpoint3d\ttyperef:typename:float\taccess:public\troles:def\tend:18\n"
  },
  {
    "path": "Tmain/readtags-stdin.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/readtags-stdin.d/output.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/bbd8fc2/\nA\tbase.py\t/^    class A:$/;\"\tkind:class\tline:11\tlanguage:Python\tscope:class:Foo\tinherits:\taccess:public\nB\tbase.py\t/^    class B:$/;\"\tkind:class\tline:18\tlanguage:Python\tscope:class:Bar\tinherits:\taccess:public\nBar\tbase.py\t/^class Bar (Foo):$/;\"\tkind:class\tline:13\tlanguage:Python\tinherits:Foo\taccess:public\nBar.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tline:14\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nBar.bw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tline:16\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nBaz\tbase.py\t/^class Baz (Foo): $/;\"\tkind:class\tline:21\tlanguage:Python\tinherits:Foo\taccess:public\nBaz.bq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tline:22\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nBaz.bw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tline:24\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nC\tbase.py\t/^    class C:$/;\"\tkind:class\tline:26\tlanguage:Python\tscope:class:Baz\tinherits:\taccess:public\nFoo\tbase.py\t/^class Foo:$/;\"\tkind:class\tline:4\tlanguage:Python\tinherits:\taccess:public\nFoo.ae\tbase.py\t/^    def ae ():$/;\"\tkind:member\tline:9\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nFoo.aq\tbase.py\t/^    def aq ():$/;\"\tkind:member\tline:5\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nFoo.aw\tbase.py\t/^    def aw ():$/;\"\tkind:member\tline:7\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nae\tbase.py\t/^    def ae ():$/;\"\tkind:member\tline:9\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\naq\tbase.py\t/^    def aq ():$/;\"\tkind:member\tline:5\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\naw\tbase.py\t/^    def aw ():$/;\"\tkind:member\tline:7\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nbase.py\tbase.py\t28;\"\tkind:file\tline:28\tlanguage:Python\nbq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tline:14\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nbq\tbase.py\t/^    def bq ():$/;\"\tkind:member\tline:22\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\nbw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tline:16\tlanguage:Python\tscope:class:Bar\taccess:public\tsignature:()\nbw\tbase.py\t/^    def bw ():$/;\"\tkind:member\tline:24\tlanguage:Python\tscope:class:Baz\taccess:public\tsignature:()\n"
  },
  {
    "path": "Tmain/readtags-stdin.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n\n. ../utils.sh\n\n#V=\"valgrind --leak-check=full -v\"\nV=\n\nskip_if_no_readtags \"$READTAGS\"\n\n\"${READTAGS}\" -t output.tags -en -D -l \\\n\t| \"${READTAGS}\" -t - -en -Q '(eq? $signature \"()\")' -D -l \\\n\t| \"${READTAGS}\" -t - -en -Q '(and $line (< $line 10))' -D -l \\\n\t| \"${READTAGS}\" -t - -en -Q '(substr? $name \".a\")' -D -l \\\n\t| \"${READTAGS}\" -t - -en -S '(<> $line &line)' -D -l\n"
  },
  {
    "path": "Tmain/readtags-stdin.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-stdin.d/stdout-expected.txt",
    "content": "Foo.aq\tbase.py\t/^    def aq ():$/;\"\tkind:member\tline:5\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nFoo.aw\tbase.py\t/^    def aw ():$/;\"\tkind:member\tline:7\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\nFoo.ae\tbase.py\t/^    def ae ():$/;\"\tkind:member\tline:9\tlanguage:Python\tscope:class:Foo\taccess:public\tsignature:()\n"
  },
  {
    "path": "Tmain/readtags-with-list-pseudo-tags.d/ptag-sort-no.tags",
    "content": "!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\n"
  },
  {
    "path": "Tmain/readtags-with-list-pseudo-tags.d/ptag-sort-yes.tags",
    "content": "!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/readtags-with-list-pseudo-tags.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2023 Masatake YAMATO\n# License: GPL-2\n\nREADTAGS=$3\n#V=\"valgrind --leak-check=full --track-origins=yes -v\"\nV=\n\n. ../utils.sh\n\nskip_if_no_readtags \"$READTAGS\"\n\necho '# ACTION=LIST'\n${V} ${READTAGS} -t ./ptag-sort-no.tags -P -l\n\necho '# ACTION=NAME'\n${V} ${READTAGS} -t ./ptag-sort-yes.tags --with-pseudo-tags - main\n"
  },
  {
    "path": "Tmain/readtags-with-list-pseudo-tags.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/readtags-with-list-pseudo-tags.d/stdout-expected.txt",
    "content": "# ACTION=LIST\n!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\nmain\tinput.c\t/^int main (void) { return 0; }$/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\nafunc\tinput.el\t/^(defun afunc () nil)$/\n# ACTION=NAME\n!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nmain\tinput.c\t/^int main (void) { return 0; }$/\n"
  },
  {
    "path": "Tmain/regex-for-unknown-language.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/regex-for-unknown-language.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --regex-nosuchlang=/a/\nexit $?\n"
  },
  {
    "path": "Tmain/regex-for-unknown-language.d/stderr-expected.txt",
    "content": "ctags: Unknown language \"nosuchlang\" in \"regex-nosuchlang\" option\n"
  },
  {
    "path": "Tmain/regex-for-unknown-language.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/regex-patterns-from-file.d/input.c",
    "content": "DEFINE(x,1);\nREGISTER(y);\n"
  },
  {
    "path": "Tmain/regex-patterns-from-file.d/list.regex",
    "content": "/DEFINE\\(([a-z]),.*/\\1/t/\n/REGISTER\\(([a-z])\\)/\\1/t/\n\n"
  },
  {
    "path": "Tmain/regex-patterns-from-file.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE \\\n\t\t --langdef=TEST'{base=C}' \\\n\t\t --kinddef-TEST=t,test,tests \\\n\t\t --regex-TEST=@./list.regex \\\n\t\t -o - \\\n\t\t input.c\n"
  },
  {
    "path": "Tmain/regex-patterns-from-file.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/regex-patterns-from-file.d/stdout-expected.txt",
    "content": "x\tinput.c\t/^DEFINE(x,1);$/;\"\tt\ny\tinput.c\t/^REGISTER(y);$/;\"\tt\n"
  },
  {
    "path": "Tmain/reset-fields.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/reset-fields.d/input.h",
    "content": "struct point { double x, y };\n"
  },
  {
    "path": "Tmain/reset-fields.d/run.sh",
    "content": "# Copyright: 2022 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nrun_ctags()\n{\n\tprintf \"# 1:%s 2:%s\\n\" \"$1\" \"$2\"\n\t${CTAGS} --quiet --options=NONE \\\n\t\t\t $1 \\\n\t\t\t -n \\\n\t\t\t --fields=zKZStse --fields=+a \\\n\t\t\t -o - \\\n\t\t\t $2 \\\n\t\t\t input.h\n}\n\nrun_ctags &&\nrun_ctags --output-format=u-ctags \"\" &&\nrun_ctags --output-format=etags   \"\" &&\nrun_ctags --output-format=xref    \"\" &&\nrun_ctags \"\" --output-format=u-ctags &&\nrun_ctags \"\" --output-format=etags   &&\nrun_ctags \"\" --output-format=xref    &&\n:\n"
  },
  {
    "path": "Tmain/reset-fields.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/reset-fields.d/stdout-expected.txt",
    "content": "# 1: 2:\npoint\tinput.h\t1;\"\tkind:struct\tend:1\n# 1:--output-format=u-ctags 2:\npoint\tinput.h\t1;\"\tkind:struct\tend:1\n# 1:--output-format=etags 2:\n\f\ninput.h,40\nstruct point { double x, y };point\u00011,0\n# 1:--output-format=xref 2:\npoint            struct        1 input.h          struct point { double x, y };\n# 1: 2:--output-format=u-ctags\npoint\tinput.h\t1;\"\tkind:struct\tend:1\n# 1: 2:--output-format=etags\n\f\ninput.h,40\nstruct point { double x, y };point\u00011,0\n# 1: 2:--output-format=xref\npoint            struct        1 input.h          struct point { double x, y };\n"
  },
  {
    "path": "Tmain/roledef.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1 --quiet --options=NONE --langdef=IMAGINARY --kinddef-IMAGINARY=v,variable,variables\"\n\nexport MSYS2_ARG_CONV_EXCL=--_roledef-IMAGINARY\n\ntitle()\n{\n\techo\n\techo \"$@\"\n\n\t{\n\t\techo\n\t\techo \"$@\"\n\t} 1>&2\n}\n\n{\ntitle '# echo unknown lang'\n${CTAGS} --_roledef-NOSUCHLANG\n${CTAGS} --_roledef-NOSUCHLANG.k=role,roles\n${CTAGS} --_roledef-NOSUCHLANG.'{kind}'=role,roles\n\ntitle '# no kind spec'\n${CTAGS} --_roledef-IMAGINARY\n${CTAGS} --_roledef-IMAGINARY=\n${CTAGS} --_roledef-IMAGINARY=role\n${CTAGS} --_roledef-IMAGINARY=role,roles\n\ntitle '# echo unknown kind letter'\n${CTAGS} --_roledef-IMAGINARY.x=           --_force-quit\n${CTAGS} --_roledef-IMAGINARY.x=role       --_force-quit\n${CTAGS} --_roledef-IMAGINARY.x=role,      --_force-quit\n${CTAGS} --_roledef-IMAGINARY.x=role,roles --_force-quit\n\ntitle '# echo unknown kind name'\n${CTAGS} --_roledef-IMAGINARY.'{abc}'=           --_force-quit\n${CTAGS} --_roledef-IMAGINARY.'{abc}'=role       --_force-quit\n${CTAGS} --_roledef-IMAGINARY.'{abc}'=role,      --_force-quit\n${CTAGS} --_roledef-IMAGINARY.'{abc}'=role,roles --_force-quit\n\ntitle '# wrong char in a kind letter'\n${CTAGS} --_roledef-IMAGINARY.'/'=\n${CTAGS} --_roledef-IMAGINARY.'%'=\n${CTAGS} --_roledef-IMAGINARY.'^'=role\n${CTAGS} --_roledef-IMAGINARY.'#'=role,roles\n${CTAGS} --_roledef-IMAGINARY.'F'=role,roles\n${CTAGS} --_roledef-IMAGINARY.'{'=role,roles\n${CTAGS} --_roledef-IMAGINARY.'{v'=role,roles\n\ntitle '# wrong kind name'\n${CTAGS} --_roledef-IMAGINARY.'{file}'=role,roles\n${CTAGS} --_roledef-IMAGINARY.'{}'=role,roles\n${CTAGS} --_roledef-IMAGINARY.'{#}'=role,roles\n\ntitle '# empty role name'\n${CTAGS} --_roledef-IMAGINARY.v=\n${CTAGS} --_roledef-IMAGINARY.v=,\n${CTAGS} --_roledef-IMAGINARY.v=,desc\n${CTAGS} --_roledef-IMAGINARY.'{variable}'=\n${CTAGS} --_roledef-IMAGINARY.'{variable}'=,\n${CTAGS} --_roledef-IMAGINARY.'{variable}'=,desc\n\ntitle '# wrong char in role name'\n${CTAGS} --_roledef-IMAGINARY.v=+role+,\n${CTAGS} --_roledef-IMAGINARY.'{variable}'=+role+,\n\ntitle '# empty description'\n${CTAGS} --_roledef-IMAGINARY.v=role\n${CTAGS} --_roledef-IMAGINARY.v=role,\n${CTAGS} --_roledef-IMAGINARY.'{variable}'=role\n${CTAGS} --_roledef-IMAGINARY.'{variable}'=role,\n\ntitle '# role is acceptable but no input file'\n${CTAGS} --_roledef-IMAGINARY.v=role,roles\n${CTAGS} --_roledef-IMAGINARY.'{variable}'=role,roles\n\ntitle '# listing with --list-roles'\n${CTAGS} --_roledef-IMAGINARY.v=role,roles --list-roles=IMAGINARY\n${CTAGS} --_roledef-IMAGINARY.'{variable}'=role,roles \\\n\t\t --_roledef-IMAGINARY.v=foos,foods \\\n\t\t --list-roles=IMAGINARY\n\ntitle '# listing with --list-kinds-full'\n${CTAGS} --_roledef-IMAGINARY.v=role,roles --list-kinds-full=IMAGINARY\n${CTAGS} --_roledef-IMAGINARY.'{variable}'=role,roles \\\n\t\t --_roledef-IMAGINARY.v=foos,foods \\\n\t\t --list-kinds-full=IMAGINARY\n\ntitle '# inject a flag separator'\n${CTAGS} --_roledef-IMAGINARY.v='role,roles{foo}' --list-roles=IMAGINARY\n${CTAGS} --_roledef-IMAGINARY.'{variable}'='role,roles{foo}' --list-roles=IMAGINARY\n\ntitle '# inject a broken flag separator(1)'\n${CTAGS} --_roledef-IMAGINARY.v='role,roles{foo' --list-roles=IMAGINARY\n${CTAGS} --_roledef-IMAGINARY.'{variable}'='role,roles{foo' --list-roles=IMAGINARY\n\ntitle '# inject a broken flag separator(2)'\n${CTAGS} --_roledef-IMAGINARY.v='role,roles{' --list-roles=IMAGINARY\n${CTAGS} --_roledef-IMAGINARY.'{variable}'='role,roles{' --list-roles=IMAGINARY\n\ntitle '# use a { in description (1)'\n${CTAGS} --_roledef-IMAGINARY.v='role,roles\\{' --list-roles=IMAGINARY\n${CTAGS} --_roledef-IMAGINARY.'{variable}'='role,roles\\{' --list-roles=IMAGINARY\n\ntitle '# use a { in description (2)'\n${CTAGS} --_roledef-IMAGINARY.v='role,roles\\{}' --list-roles=IMAGINARY\n${CTAGS} --_roledef-IMAGINARY.'{variable}'='role,roles\\{}' --list-roles=IMAGINARY\n\ntitle '# use a \\ in description'\n${CTAGS} --_roledef-IMAGINARY.v='role,roles\\\\backslash' --list-roles=IMAGINARY\n${CTAGS} --_roledef-IMAGINARY.'{variable}'='role,roles\\\\backslash' --list-roles=IMAGINARY\n\ntitle '# description started from {'\n${CTAGS} --_roledef-IMAGINARY.v='role,{' --list-roles=IMAGINARY\n${CTAGS} --_roledef-IMAGINARY.'{variable}'='role,{' --list-roles=IMAGINARY\n\ntitle '# description started from \\{'\n${CTAGS} --_roledef-IMAGINARY.v='role,\\{' --list-roles=IMAGINARY\n${CTAGS} --_roledef-IMAGINARY.'{variable}'='role,\\{' --list-roles=IMAGINARY\n\ntitle '# too many roles'\nopts=\nfor i in $(seq 0 64); do\n\topts=\"$opts --_roledef-IMAGINARY.v=r$i,desc$i \"\ndone\n${CTAGS} $opts\n\n} > /tmp/ctags-tmain-$$.stdout 2>/tmp/ctags-tmain-$$.stderr\n\nsed -e 's/\\.exe//g' < /tmp/ctags-tmain-$$.stdout\nrm /tmp/ctags-tmain-$$.stdout\n\nsed -e 's/\\.exe//g' < /tmp/ctags-tmain-$$.stderr 1>&2\nrm /tmp/ctags-tmain-$$.stderr\n"
  },
  {
    "path": "Tmain/roledef.d/stderr-expected.txt",
    "content": "\n# echo unknown lang\nctags: Unknown language \"NOSUCHLANG\" in \"_roledef-NOSUCHLANG\" option\nctags: Unknown language \"NOSUCHLANG\" in \"_roledef-NOSUCHLANG.k\" option\nctags: Unknown language \"NOSUCHLANG\" in \"_roledef-NOSUCHLANG.{kind}\" option\n\n# no kind spec\nctags: no kind is specifined in \"--_roledef-IMAGINARY=\"\nctags: no kind is specifined in \"--_roledef-IMAGINARY=\"\nctags: no kind is specifined in \"--_roledef-IMAGINARY=role\"\nctags: no kind is specifined in \"--_roledef-IMAGINARY=role,roles\"\n\n# echo unknown kind letter\nctags: the kind for letter `x' specified in \"--_roledef-IMAGINARY.x\" option is not defined.\nctags: the kind for letter `x' specified in \"--_roledef-IMAGINARY.x\" option is not defined.\nctags: the kind for letter `x' specified in \"--_roledef-IMAGINARY.x\" option is not defined.\nctags: the kind for letter `x' specified in \"--_roledef-IMAGINARY.x\" option is not defined.\n\n# echo unknown kind name\nctags: the kind for name `abc' specified in \"--_roledef-IMAGINARY.{abc}\" option is not defined.\nctags: the kind for name `abc' specified in \"--_roledef-IMAGINARY.{abc}\" option is not defined.\nctags: the kind for name `abc' specified in \"--_roledef-IMAGINARY.{abc}\" option is not defined.\nctags: the kind for name `abc' specified in \"--_roledef-IMAGINARY.{abc}\" option is not defined.\n\n# wrong char in a kind letter\nctags: the kind letter given in \"--_roledef-IMAGINARY./\" option is not an alphabet or a number\nctags: the kind letter given in \"--_roledef-IMAGINARY.%\" option is not an alphabet or a number\nctags: the kind letter given in \"--_roledef-IMAGINARY.^\" option is not an alphabet or a number\nctags: the kind letter given in \"--_roledef-IMAGINARY.#\" option is not an alphabet or a number\nctags: the kind letter `F' in \"--_roledef-IMAGINARY.F\" option is reserved for \"file\" kind, and no role can be attached to it\nctags: no '}' representing the end of kind name in --_roledef-IMAGINARY.{ option: {\nctags: no '}' representing the end of kind name in --_roledef-IMAGINARY.{v option: {v\n\n# wrong kind name\nctags: don't define a role for F/file kind; it has no role: --_roledef-IMAGINARY.{file}\nctags: the kind for name `' specified in \"--_roledef-IMAGINARY.{}\" option is not defined.\nctags: the kind for name `#' specified in \"--_roledef-IMAGINARY.{#}\" option is not defined.\n\n# empty role name\nctags: no role description specified in \"--_roledef-IMAGINARY.v\" option\nctags: the role name in \"--_roledef-IMAGINARY.v\" option is empty\nctags: the role name in \"--_roledef-IMAGINARY.v\" option is empty\nctags: no role description specified in \"--_roledef-IMAGINARY.{variable}\" option\nctags: the role name in \"--_roledef-IMAGINARY.{variable}\" option is empty\nctags: the role name in \"--_roledef-IMAGINARY.{variable}\" option is empty\n\n# wrong char in role name\nctags: unacceptable char as part of role name in \"--_roledef-IMAGINARY.v\" option: '+'\nctags: unacceptable char as part of role name in \"--_roledef-IMAGINARY.{variable}\" option: '+'\n\n# empty description\nctags: no role description specified in \"--_roledef-IMAGINARY.v\" option\nctags: found an empty role description in \"--_roledef-IMAGINARY.v\" option\nctags: no role description specified in \"--_roledef-IMAGINARY.{variable}\" option\nctags: found an empty role description in \"--_roledef-IMAGINARY.{variable}\" option\n\n# role is acceptable but no input file\nctags: No files specified. Try \"ctags --help\".\nctags: No files specified. Try \"ctags --help\".\n\n# listing with --list-roles\n\n# listing with --list-kinds-full\n\n# inject a flag separator\n\n# inject a broken flag separator(1)\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{foo\"\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{foo\"\n\n# inject a broken flag separator(2)\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{\"\nctags: Warning: long flags specifier opened with `{' is not closed `}': \"{\"\n\n# use a { in description (1)\n\n# use a { in description (2)\n\n# use a \\ in description\n\n# description started from {\nctags: found an empty role description in \"--_roledef-IMAGINARY.v\" option\nctags: found an empty role description in \"--_roledef-IMAGINARY.{variable}\" option\n\n# description started from \\{\n\n# too many roles\nctags: Too many role definition for kind \"variable\" of language \"IMAGINARY\" (> 63)\n"
  },
  {
    "path": "Tmain/roledef.d/stdout-expected.txt",
    "content": "\n# echo unknown lang\n\n# no kind spec\n\n# echo unknown kind letter\n\n# echo unknown kind name\n\n# wrong char in a kind letter\n\n# wrong kind name\n\n# empty role name\n\n# wrong char in role name\n\n# empty description\n\n# role is acceptable but no input file\n\n# listing with --list-roles\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  foos on        0 foods\nv/variable  role on        0 roles\n\n# listing with --list-kinds-full\n#LETTER NAME     ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nv       variable yes     no      1      NONE     0 variables\n#LETTER NAME     ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nv       variable yes     no      2      NONE     0 variables\n\n# inject a flag separator\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles\n\n# inject a broken flag separator(1)\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles\n\n# inject a broken flag separator(2)\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles\n\n# use a { in description (1)\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles{\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles{\n\n# use a { in description (2)\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles{}\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles{}\n\n# use a \\ in description\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles\\backslash\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 roles\\backslash\n\n# description started from {\n\n# description started from \\{\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 {\n#KIND(L/N)  NAME ENABLED VER DESCRIPTION\nv/variable  role on        0 {\n\n# too many roles\n"
  },
  {
    "path": "Tmain/roles-field-optscript.d/foo.ctags",
    "content": "--extras=+r\n--fields=+r\n\n--langdef=foo\n--map-foo=+.foo\n\n--kinddef-foo=v,var,variables\n\n--_roledef-foo.v=lval,left side value\n--_roledef-foo.v=inc,incremeted\n--_roledef-foo.v=dec,decremented\n\n--regex-foo=/([a-z]) *=/\\1/v/{_role=lval}{{\n    \\1 . :roles pstack clear\n}}\n\n--regex-foo=/([a-z])\\+\\+/\\1/v/{_role=inc}{{\n    \\1 . :roles pstack clear\n}}\n\n--regex-foo=/([a-z])\\-\\-/\\1/v/{_role=dec}{{\n    \\1 . :roles pstack clear\n}}\n\n--regex-foo=/def +([a-z])/\\1/v/{{\n    \\1 . :roles pstack clear\n}}\n"
  },
  {
    "path": "Tmain/roles-field-optscript.d/input.foo",
    "content": "def a\n\na++\na--\na=3\n"
  },
  {
    "path": "Tmain/roles-field-optscript.d/run.sh",
    "content": "# Copyright: 2021 Masatake YAMATO\n# License: GPL-2\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --options=foo.ctags -o - input.foo | grep -v '^a'\n"
  },
  {
    "path": "Tmain/roles-field-optscript.d/stderr-expected.txt",
    "content": "[/def]\n(a)\n[/inc]\n(a)\n[/dec]\n(a)\n[/lval]\n(a)\n"
  },
  {
    "path": "Tmain/roles-field-optscript.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/ruby-scope-loop-oom.d/README",
    "content": "This is initially a crash test.\nThe crash (OOM killer) was reported in #3306 by @ivanbrennan.\na.rb and b.rb were taken from the issue.\n"
  },
  {
    "path": "Tmain/ruby-scope-loop-oom.d/a.rb",
    "content": "RSpec.describe \"A\" do\n  describe \"a\" do\n    it \"hangs\" do\n      {\n        for: nil\n      }\n      {\n        for: nil\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "Tmain/ruby-scope-loop-oom.d/b.rb",
    "content": "RSpec.describe \"B\" do\nend\n"
  },
  {
    "path": "Tmain/ruby-scope-loop-oom.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/ruby-scope-loop-oom.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2022 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nif ! type timeout > /dev/null 2>&1; then\n\tskip \"timeout command is not available\"\nfi\n\ntimeout 5s ${CTAGS} --quiet --options=NONE --fields=+e -o - a.rb b.rb\nexit $?\n"
  },
  {
    "path": "Tmain/ruby-scope-loop-oom.d/stdout-expected.txt",
    "content": "A\ta.rb\t/^RSpec.describe \"A\" do$/;\"\td\tend:12\nB\tb.rb\t/^RSpec.describe \"B\" do$/;\"\td\tend:2\na\ta.rb\t/^  describe \"a\" do$/;\"\td\tdescribe:A\tend:11\nhangs\ta.rb\t/^    it \"hangs\" do$/;\"\ti\tdescribe:A.a\tend:10\n"
  },
  {
    "path": "Tmain/run-as-etags.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/run-as-etags.d/run.sh",
    "content": "# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\n\n. ../utils.sh\n\n# on \"Environment: compiler=msvc, ARCH=x64\", we got following error:\n#\n# C:/projects/ctags/Tmain/run-as-etags.d/etags.exe:\n# error while loading shared libraries:\n# iconv.dll: cannot open shared object file: No such file or directory\nexit_if_win32 \"$CTAGS\"\n\netags=$BUILDDIR/etags\ncp $1 $etags\n\n$etags --quiet --options=NONE --_force-quit\nr=$?\n\nrm $etags\n\nexit $r\n"
  },
  {
    "path": "Tmain/run-as-etags.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/sandbox-crash.d/exit-expected.txt",
    "content": "159\n"
  },
  {
    "path": "Tmain/sandbox-crash.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\nis_feature_available $CTAGS debug\nis_feature_available $CTAGS sandbox\nis_feature_available ${CTAGS} interactive\nis_feature_available ${CTAGS} '!' gcov\n\n{\n    echo '{\"command\":\"generate-tags\", \"filename\":\"input.ctst\", \"size\": 1}'\n    echo 'P'\n} | $CTAGS --quiet --options=NONE  --language-force=CTagsSelfTest --_interactive=sandbox > /tmp/ctags-Tmain-$$\nr=$?\njdropver < /tmp/ctags-Tmain-$$\nrm /tmp/ctags-Tmain-$$\nexit $r\n"
  },
  {
    "path": "Tmain/sandbox-crash.d/stdout-expected.txt",
    "content": "{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n"
  },
  {
    "path": "Tmain/sandbox-default-req.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/sandbox-default-req.d/input.c",
    "content": "int main(void) { return 0; }\n"
  },
  {
    "path": "Tmain/sandbox-default-req.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\nis_feature_available $CTAGS sandbox\nis_feature_available ${CTAGS} interactive\nis_feature_available ${CTAGS} '!' gcov\n\n{\n    echo '{\"command\":\"generate-tags\", \"filename\":\"input.c\", \"size\": -1}'\n    echo '{\"command\":\"generate-tags\", \"filename\":\"input.el\", \"size\": 16}'\n    echo '(defun foo () 0)'\n} | $CTAGS --quiet --options=NONE  --_interactive=sandbox > /tmp/ctags-Tmain-$$\nr=$?\njdropver < /tmp/ctags-Tmain-$$\nrm /tmp/ctags-Tmain-$$\nexit $r\n"
  },
  {
    "path": "Tmain/sandbox-default-req.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/sandbox-default-req.d/stdout-expected.txt",
    "content": "{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"error\", \"message\": \"invalid request in sandbox submode: reading file contents from a file is limited\", \"fatal\": true}\n{\"_type\": \"tag\", \"name\": \"foo\", \"path\": \"input.el\", \"pattern\": \"/^(defun foo () 0)/\", \"kind\": \"function\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n"
  },
  {
    "path": "Tmain/sandbox-no-eager-guessing.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/sandbox-no-eager-guessing.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\nis_feature_available $CTAGS sandbox\nis_feature_available ${CTAGS} interactive\nis_feature_available ${CTAGS} '!' gcov\n\n{\n    echo '{\"command\":\"generate-tags\", \"filename\":\"input.unknown\", \"size\": 44}'\n    echo '/* -*- c -*- */ int main(void) { return 0; }'\n} | $CTAGS --quiet --options=NONE --_interactive=sandbox > /tmp/ctags-Tmain-$$\nr=$?\njdropver < /tmp/ctags-Tmain-$$\nrm /tmp/ctags-Tmain-$$\nexit $r\n"
  },
  {
    "path": "Tmain/sandbox-no-eager-guessing.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/sandbox-no-eager-guessing.d/stdout-expected.txt",
    "content": "{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n"
  },
  {
    "path": "Tmain/sandbox-unknown-submode.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/sandbox-unknown-submode.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\nis_feature_available $CTAGS sandbox\nis_feature_available ${CTAGS} interactive\nis_feature_available ${CTAGS} '!' gcov\n\n{\n    echo '{\"command\":\"generate-tags\", \"filename\":\"input.c\", \"size\": 28}'\n    echo 'int main(void) { return 0; }'\n} | $CTAGS --quiet --options=NONE  --_interactive=unknown\n\nexit $?\n"
  },
  {
    "path": "Tmain/sandbox-unknown-submode.d/stderr-expected.txt",
    "content": "ctags: Unknown option argument \"unknown\" for --_interactive option\n"
  },
  {
    "path": "Tmain/sandbox-unknown-submode.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/sandbox-with-eager-guessing.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/sandbox-with-eager-guessing.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\nis_feature_available $CTAGS sandbox\nis_feature_available ${CTAGS} interactive\nis_feature_available ${CTAGS} '!' gcov\n\n{\n    echo '{\"command\":\"generate-tags\", \"filename\":\"input.unknown\", \"size\": 44}'\n    echo '/* -*- c -*- */ int main(void) { return 0; }'\n} | $CTAGS --quiet --options=NONE  -G --_interactive=sandbox > /tmp/ctags-Tmain-$$\nr=$?\njdropver < /tmp/ctags-Tmain-$$\nrm /tmp/ctags-Tmain-$$\nexit $r\n"
  },
  {
    "path": "Tmain/sandbox-with-eager-guessing.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/sandbox-with-eager-guessing.d/stdout-expected.txt",
    "content": "{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.unknown\", \"pattern\": \"/^\\\\/* -*- c -*- *\\\\/ int main(void) { return 0; }/\", \"typeref\": \"typename:int\", \"kind\": \"function\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n"
  },
  {
    "path": "Tmain/sandbox.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/sandbox.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\nis_feature_available $CTAGS sandbox\nis_feature_available ${CTAGS} interactive\nis_feature_available ${CTAGS} '!' gcov\n\n{\n    echo '{\"command\":\"generate-tags\", \"filename\":\"input.c\", \"size\": 28}'\n    echo 'int main(void) { return 0; }'\n} | $CTAGS --quiet --options=NONE  --_interactive=sandbox > /tmp/ctags-Tmain-$$\nr=$?\njdropver < /tmp/ctags-Tmain-$$\nrm /tmp/ctags-Tmain-$$\nexit $r\n"
  },
  {
    "path": "Tmain/sandbox.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/sandbox.d/stdout-expected.txt",
    "content": "{\"_type\": \"program\", \"name\": \"Universal Ctags\"}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.c\", \"pattern\": \"/^int main(void) { return 0; }/\", \"typeref\": \"typename:int\", \"kind\": \"function\"}\n{\"_type\": \"completed\", \"command\": \"generate-tags\"}\n"
  },
  {
    "path": "Tmain/scopesep.d/input.tcl",
    "content": "namespace eval M {\n    namespace eval N {\n\tproc p0 {s} {\n\t}\n    }\n}\n\nproc p1 {s} {\n}\n"
  },
  {
    "path": "Tmain/scopesep.d/run.sh",
    "content": "# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho \"# root sep and wildcard\"\n${CTAGS} --quiet --options=NONE\t\t\t\t\t\\\n\t\t -o -\t\t\t\t\t\t\t\t\t\\\n\t\t --sort=no\t\t\t\t\t\t\t\t\\\n\t\t --extras=+q\t\t\t\t\t\t\t\\\n\t\t --_scopesep-Tcl='/*:/'\t\t\t\t\t\\\n\t\t --_scopesep-Tcl='*/*:+'\t\t\t\t\\\n\t\t input.tcl\n\necho \"# override wildcard\"\n${CTAGS} --quiet --options=NONE\t\t\t\t\t\\\n\t\t -o -\t\t\t\t\t\t\t\t\t\\\n\t\t --sort=no\t\t\t\t\t\t\t\t\\\n\t\t --extras=+q\t\t\t\t\t\t\t\\\n\t\t --_scopesep-Tcl='/*:/'\t\t\t\t\t\\\n\t\t --_scopesep-Tcl='*/*:+'\t\t\t\t\\\n\t\t --_scopesep-Tcl='n/n:->'\t\t\t\t\\\n\t\t --_scopesep-Tcl='n/p:^'\t\t\t\t\\\n\t\t input.tcl\n\necho \"# override rootsep\"\n${CTAGS} --quiet --options=NONE\t\t\t\t\t\\\n\t\t -o -\t\t\t\t\t\t\t\t\t\\\n\t\t --sort=no\t\t\t\t\t\t\t\t\\\n\t\t --extras=+q\t\t\t\t\t\t\t\\\n\t\t --_scopesep-Tcl='/*:/'\t\t\t\t\t\\\n\t\t --_scopesep-Tcl='*/*:+'\t\t\t\t\\\n\t\t --_scopesep-Tcl='/n:@'\t\t\t\t\t\\\n\t\t --_scopesep-Tcl='/p:%'\t\t\t\t\t\\\n\t\t input.tcl\n\necho \"# no default\"\n${CTAGS} --quiet --options=NONE\t\t\t\t\t\\\n\t\t -o -\t\t\t\t\t\t\t\t\t\\\n\t\t --sort=no\t\t\t\t\t\t\t\t\\\n\t\t --extras=+q\t\t\t\t\t\t\t\\\n\t\t --_scopesep-Tcl='n/n:->'\t\t\t\t\\\n\t\t --_scopesep-Tcl='n/p:^'\t\t\t\t\\\n\t\t --_scopesep-Tcl='/n:@'\t\t\t\t\t\\\n\t\t --_scopesep-Tcl='/p:%'\t\t\t\t\t\\\n\t\t input.tcl\n"
  },
  {
    "path": "Tmain/scopesep.d/stdout-expected.txt",
    "content": "# root sep and wildcard\nM\tinput.tcl\t/^namespace eval M {$/;\"\tn\n/M\tinput.tcl\t/^namespace eval M {$/;\"\tn\nN\tinput.tcl\t/^    namespace eval N {$/;\"\tn\tnamespace:/M\n/M+N\tinput.tcl\t/^    namespace eval N {$/;\"\tn\tnamespace:/M\np0\tinput.tcl\t/^\tproc p0 {s} {$/;\"\tp\tnamespace:/M+N\n/M+N+p0\tinput.tcl\t/^\tproc p0 {s} {$/;\"\tp\tnamespace:/M+N\np1\tinput.tcl\t/^proc p1 {s} {$/;\"\tp\n/p1\tinput.tcl\t/^proc p1 {s} {$/;\"\tp\n# override wildcard\nM\tinput.tcl\t/^namespace eval M {$/;\"\tn\n/M\tinput.tcl\t/^namespace eval M {$/;\"\tn\nN\tinput.tcl\t/^    namespace eval N {$/;\"\tn\tnamespace:/M\n/M->N\tinput.tcl\t/^    namespace eval N {$/;\"\tn\tnamespace:/M\np0\tinput.tcl\t/^\tproc p0 {s} {$/;\"\tp\tnamespace:/M->N\n/M->N^p0\tinput.tcl\t/^\tproc p0 {s} {$/;\"\tp\tnamespace:/M->N\np1\tinput.tcl\t/^proc p1 {s} {$/;\"\tp\n/p1\tinput.tcl\t/^proc p1 {s} {$/;\"\tp\n# override rootsep\nM\tinput.tcl\t/^namespace eval M {$/;\"\tn\n@M\tinput.tcl\t/^namespace eval M {$/;\"\tn\nN\tinput.tcl\t/^    namespace eval N {$/;\"\tn\tnamespace:@M\n@M+N\tinput.tcl\t/^    namespace eval N {$/;\"\tn\tnamespace:@M\np0\tinput.tcl\t/^\tproc p0 {s} {$/;\"\tp\tnamespace:@M+N\n@M+N+p0\tinput.tcl\t/^\tproc p0 {s} {$/;\"\tp\tnamespace:@M+N\np1\tinput.tcl\t/^proc p1 {s} {$/;\"\tp\n%p1\tinput.tcl\t/^proc p1 {s} {$/;\"\tp\n# no default\nM\tinput.tcl\t/^namespace eval M {$/;\"\tn\n@M\tinput.tcl\t/^namespace eval M {$/;\"\tn\nN\tinput.tcl\t/^    namespace eval N {$/;\"\tn\tnamespace:@M\n@M->N\tinput.tcl\t/^    namespace eval N {$/;\"\tn\tnamespace:@M\np0\tinput.tcl\t/^\tproc p0 {s} {$/;\"\tp\tnamespace:@M->N\n@M->N^p0\tinput.tcl\t/^\tproc p0 {s} {$/;\"\tp\tnamespace:@M->N\np1\tinput.tcl\t/^proc p1 {s} {$/;\"\tp\n%p1\tinput.tcl\t/^proc p1 {s} {$/;\"\tp\n"
  },
  {
    "path": "Tmain/selector-dont-select-disabled-lang.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/selector-dont-select-disabled-lang.d/input.h",
    "content": "@interface Ctags\n@end\n\nstruct s {\n  int i;\n};\n"
  },
  {
    "path": "Tmain/selector-dont-select-disabled-lang.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --languages=-ObjectiveC --print-language input.h\n\n"
  },
  {
    "path": "Tmain/selector-dont-select-disabled-lang.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/selector-dont-select-disabled-lang.d/stdout-expected.txt",
    "content": "input.h: C++\n"
  },
  {
    "path": "Tmain/selector-select-C-for-dot-h.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/selector-select-C-for-dot-h.d/input.h",
    "content": "#define a(x) (1+(x)))\n"
  },
  {
    "path": "Tmain/selector-select-C-for-dot-h.d/run.sh",
    "content": "# Copyright: 2023 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\necho --map-C++=-.h  --map-C=+.h && \\\n${CTAGS} --quiet --options=NONE \\\n\t\t --map-C++=-.h  --map-C=+.h  \\\n\t\t --fields=+'{language}{signature}' \\\n\t\t --fields-C=+'{macrodef}' \\\n\t\t --kinds-C=d -o - input.h &&\necho --map-C=+.h && \\\n${CTAGS} --quiet --options=NONE \\\n\t\t --map-C=+.h  \\\n\t\t --fields=+'{language}{signature}' \\\n\t\t --fields-C=+'{macrodef}' \\\n\t\t --kinds-C=d -o - input.h &&\necho --map-C=-.h && \\\n${CTAGS} --quiet --options=NONE \\\n\t\t --map-C++=-.h \\\n\t\t --fields=+'{language}{signature}' \\\n\t\t --fields-C=+'{macrodef}' \\\n\t\t --kinds-C=d -o - input.h &&\necho --map-ObjectiveC=-.h && \\\n${CTAGS} --quiet --options=NONE \\\n\t\t --map-ObjectiveC=-.h \\\n\t\t --fields=+'{language}{signature}' \\\n\t\t --fields-C=+'{macrodef}' \\\n\t\t --kinds-C=d -o - input.h &&\necho --map-ObjectiveC=-.h --map-C=-.h && \\\n${CTAGS} --quiet --options=NONE \\\n\t\t --map-ObjectiveC=-.h --map-C=-.h  \\\n\t\t --fields=+'{language}{signature}' \\\n\t\t --fields-C=+'{macrodef}' \\\n\t\t --kinds-C=d -o - input.h && \\\necho --map-ObjectiveC=-.h --map-C++=-.h && \\\n${CTAGS} --quiet --options=NONE \\\n\t\t --map-ObjectiveC=-.h --map-C++=-.h  \\\n\t\t --fields=+'{language}{signature}' \\\n\t\t --fields-C=+'{macrodef}' \\\n\t\t --kinds-C=d -o - input.h &&\necho --map-C++=-.h  --map-C=+.h --languages=-ObjectiveC && \\\n${CTAGS} --quiet --options=NONE \\\n\t\t --map-C++=-.h  --map-C=+.h --languages=-ObjectiveC \\\n\t\t --fields=+'{language}{signature}' \\\n\t\t --fields-C=+'{macrodef}' \\\n\t\t --kinds-C=d -o - input.h &&\necho --map-C++=-.h  --map-C=+.h --languages=-C++ && \\\n${CTAGS} --quiet --options=NONE \\\n\t\t --map-C++=-.h  --map-C=+.h --languages=-C++ \\\n\t\t --fields=+'{language}{signature}' \\\n\t\t --fields-C=+'{macrodef}' \\\n\t\t --kinds-C=d -o - input.h &&\necho --map-C++=-.h  --map-C=+.h --languages=-C && \\\n${CTAGS} --quiet --options=NONE \\\n\t\t --map-C++=-.h  --map-C=+.h --languages=-C \\\n\t\t --fields=+'{language}{signature}' \\\n\t\t --fields-C=+'{macrodef}' \\\n\t\t --kinds-C=d -o - input.h &&\n:\n"
  },
  {
    "path": "Tmain/selector-select-C-for-dot-h.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/selector-select-C-for-dot-h.d/stdout-expected.txt",
    "content": "--map-C++=-.h --map-C=+.h\na\tinput.h\t/^#define a(/;\"\td\tlanguage:C\tsignature:(x)\tmacrodef:(1+(x)))\n--map-C=+.h\na\tinput.h\t/^#define a(/;\"\td\tlanguage:C\tsignature:(x)\tmacrodef:(1+(x)))\n--map-C=-.h\na\tinput.h\t/^#define a(x) (1+(x)))$/;\"\tM\tlanguage:ObjectiveC\n--map-ObjectiveC=-.h\na\tinput.h\t/^#define a(/;\"\td\tlanguage:C++\tsignature:(x)\n--map-ObjectiveC=-.h --map-C=-.h\na\tinput.h\t/^#define a(/;\"\td\tlanguage:C++\tsignature:(x)\n--map-ObjectiveC=-.h --map-C++=-.h\n--map-C++=-.h --map-C=+.h --languages=-ObjectiveC\na\tinput.h\t/^#define a(/;\"\td\tlanguage:C\tsignature:(x)\tmacrodef:(1+(x)))\n--map-C++=-.h --map-C=+.h --languages=-C++\na\tinput.h\t/^#define a(/;\"\td\tlanguage:C\tsignature:(x)\tmacrodef:(1+(x)))\n--map-C++=-.h --map-C=+.h --languages=-C\na\tinput.h\t/^#define a(x) (1+(x)))$/;\"\tM\tlanguage:ObjectiveC\n"
  },
  {
    "path": "Tmain/selector-select-perl6-for-dot-pm.d/input0.pm",
    "content": "# Taken from Units/parara-raku.r/raku-bunch1.d/input.pm\nmy class JSONPrettyActions {\n    method TOP($/) {\n        make $/.values.[0].ast;\n    };\n    method object($/) {\n        make $<pairlist>.ast.hash.item;\n    }\n\n    method pairlist($/) {\n        make $<pair>>>.ast.flat;\n    }\n\n    method pair($/) {\n        make $<string>.ast => $<value>.ast;\n    }\n\n    method array($/) {\n        make $<arraylist>.ast.item;\n    }\n\n    method arraylist($/) {\n        make [$<value>>>.ast];\n    }\n\n    method string($/) {\n        make $0.elems == 1\n            ?? ($0[0].<str> || $0[0].<str_escape>).ast\n            !! join '', $0.list.map({ (.<str> || .<str_escape>).ast });\n    }\n    method value:sym<number>($/) { make +$/.Str }\n    method value:sym<string>($/) { make $<string>.ast }\n    method value:sym<true>($/)   { make Bool::True  }\n    method value:sym<false>($/)  { make Bool::False }\n    method value:sym<null>($/)   { make Any }\n    method value:sym<object>($/) { make $<object>.ast }\n    method value:sym<array>($/)  { make $<array>.ast }\n\n    method str($/)               { make ~$/ }\n\n    my %esc = '\\\\' => \"\\\\\",\n              '/'  => \"/\",\n              'b'  => \"\\b\",\n              'n'  => \"\\n\",\n              't'  => \"\\t\",\n              'f'  => \"\\f\",\n              'r'  => \"\\r\",\n              '\"'  => \"\\\"\";\n    method str_escape($/) {\n        make $<xdigit> ?? chr(:16($<xdigit>.join)) !! %esc.AT-KEY(~$/);\n    }\n}\n\nmy grammar JSONPrettyGrammar {\n    token TOP       { ^ \\s* [ <object> | <array> ] \\s* $ }\n    rule object     { '{' ~ '}' <pairlist>     }\n    rule pairlist   { <pair> * % \\,            }\n    rule pair       { <string> ':' <value>     }\n    rule array      { '[' ~ ']' <arraylist>    }\n    rule arraylist  {  <value> * % [ \\, ]        }\n\n    proto token value {*};\n    token value:sym<number> {\n        '-'?\n        [ 0 | <[1..9]> <[0..9]>* ]\n        [ \\. <[0..9]>+ ]?\n        [ <[eE]> [\\+|\\-]? <[0..9]>+ ]?\n    }\n    token value:sym<true>    { <sym>    };\n    token value:sym<false>   { <sym>    };\n    token value:sym<null>    { <sym>    };\n    token value:sym<object>  { <object> };\n    token value:sym<array>   { <array>  };\n    token value:sym<string>  { <string> }\n\n    token string {\n        \\\" ~ \\\" ( <str> | \\\\ <str_escape> )*\n    }\n\n    token str {\n        <-[\"\\\\\\t\\n]>+\n    }\n\n    token str_escape {\n        <[\"\\\\/bfnrt]> | u <xdigit>**4\n    }\n}\n\nproto sub to-json($, :$indent = 0, :$first = 0) {*}\n\nmulti sub to-json(Version:D $v, :$indent = 0, :$first = 0) { to-json(~$v, :$indent, :$first) }\nmulti sub to-json(Real:D $d, :$indent = 0, :$first = 0) { (' ' x $first) ~ ~$d }\nmulti sub to-json(Bool:D $d, :$indent = 0, :$first = 0) { (' ' x $first) ~ ($d ?? 'true' !! 'false') }\nmulti sub to-json(Str:D $d, :$indent = 0, :$first = 0) {\n    (' ' x $first) ~ '\"'\n    ~ $d.trans(['\"', '\\\\', \"\\b\", \"\\f\", \"\\n\", \"\\r\", \"\\t\"]\n            => ['\\\"', '\\\\\\\\', '\\b', '\\f', '\\n', '\\r', '\\t'])\\\n            .subst(/<-[\\c32..\\c126]>/, { ord(~$_).fmt('\\u%04x') }, :g)\n    ~ '\"'\n}\nmulti sub to-json(Positional:D $d, :$indent = 0, :$first = 0) {\n    (' ' x $first) ~ \"\\[\"\n            ~ ($d ?? $d.map({ \"\\n\" ~ to-json($_, :indent($indent + 2), :first($indent + 2)) }).join(\",\") ~ \"\\n\" ~ (' ' x $indent) !! ' ')\n            ~ ']';\n}\nmulti sub to-json(Associative:D $d, :$indent = 0, :$first = 0) {\n    (' ' x $first) ~ \"\\{\"\n            ~ ($d ?? $d.map({ \"\\n\" ~ to-json(.key, :first($indent + 2)) ~ ' : ' ~ to-json(.value, :indent($indent + 2)) }).join(\",\") ~ \"\\n\" ~ (' ' x $indent) !! ' ')\n            ~ '}';\n}\n\nmulti sub to-json(Mu:U $, :$indent = 0, :$first = 0) { 'null' }\nmulti sub to-json(Mu:D $s, :$indent = 0, :$first = 0) {\n    die \"Can't serialize an object of type \" ~ $s.WHAT.perl\n}\n\nsub from-json($text) {\n    my $a = JSONPrettyActions.new();\n    my $o = JSONPrettyGrammar.parse($text, :actions($a));\n    $o.ast;\n}\n"
  },
  {
    "path": "Tmain/selector-select-perl6-for-dot-pm.d/input1.pm",
    "content": "# Taken from Units/parser-raku/raku-bunch2.d/input.rakumod\n\n# Anything that can be subscribed to does this role. It provides the basic\n# supply management infrastructure, as well as various coercions that\n# turn Supply-like things into something else and convenience forms of calls\n# to SupplyOperations.\n\nmy class SupplyOperations is repr('Uninstantiable') { ... }\nmy class X::Supply::Combinator is Exception {\n    has $.combinator;\n    method message() { \"Can only use $!combinator to combine defined Supply objects\" }\n}\n\nmy class Tap {\n    has &.emit;\n    has &.done;\n    has &.quit;\n    has &.closing;\n    has $.supply;\n\n    method close (Tap:D:) { $!supply.close(self) }\n}\n\nmy role Supply {\n    has $!tappers_lock = Lock.new;\n    has @!tappers;\n    has $!been_tapped;\n    has @!paused;\n\n    method tap(Supply:D: &emit = -> $ { }, :&done,:&quit={die $_},:&closing) {\n        my $tap = Tap.new(:&emit, :&done, :&quit, :&closing, :supply(self));\n        $!tappers_lock.protect({\n            @!tappers.push($tap);\n            if @!paused -> \\todo {\n                $tap.emit().($_) for todo;\n                @!paused = ();\n            }\n            $!been_tapped = True;\n        });\n        $tap\n    }\n\n    proto method close(|) { * }\n    multi method close(Supply:D:) { self.close($_) for self.tappers }\n    multi method close(Supply:D: Tap $t) {\n        my $found;\n        $!tappers_lock.protect({\n            @!tappers .= grep( { $_ === $t ?? !($found = True) !! True } );\n        });\n        if $t.closing -> &closing {\n            closing();\n        }\n        $found // False;\n    }\n\n    method tappers(Supply:D:) {\n        # Shallow clone to provide safe snapshot.\n        my @tappers;\n        $!tappers_lock.protect({ @tappers = @!tappers });\n        @tappers\n    }\n\n    method emit(Supply:D: \\msg) {\n        if self.tappers -> \\tappers {\n            .emit().(msg) for tappers;\n        }\n        elsif !$!been_tapped {\n            $!tappers_lock.protect({ @!paused.push: msg });\n        }\n        Nil;\n    }\n\n    method more(Supply:D: \\msg) {\n        DEPRECATED('emit', |<2014.10 2015.09>);\n        self.emit(msg);\n    }\n\n    method done(Supply:D:) {\n        for self.tappers -> $t {\n            my $l = $t.done();\n            $l() if $l;\n        }\n        Nil;\n    }\n\n    method quit(Supply:D: $ex) {\n        for self.tappers -> $t {\n            my $f = $t.quit();\n            $f($ex) if $f;\n        }\n        Nil;\n    }\n\n    method taps(Supply:D:) { +@!tappers }\n    method live(Supply:D:) { True };\n\n    method Supply(Supply:) { self }\n    method Channel(Supply:D:) {\n        my $c = Channel.new();\n        self.tap( -> \\val { $c.send(val) },\n          done => { $c.close },\n          quit => -> $ex { $c.quit($ex) });\n        $c\n    }\n\n    method Promise(Supply:D:) {\n        my $l = Lock.new;\n        my $p = Promise.new;\n        my $v = $p.vow;\n        my $t = self.tap(\n          -> \\val {\n              $l.protect( {\n                  if $p.status == Planned {\n                      $v.keep(val);\n                      $t.close()\n                  }\n              } );\n          },\n          done => { $v.break(\"No value received\") },\n          quit => -> \\ex {\n              $l.protect( {\n                  if $p.status == Planned {\n                      $v.break(ex);\n                      $t.close()\n                  }\n              } );\n          },\n        );\n        $p\n    }\n\n    method wait(Supply:D:) {\n        my $l = Lock.new;\n        my $p = Promise.new;\n        my $t = self.tap( -> \\val {},\n          done => {\n              $l.protect( {\n                  if $p.status == Planned {\n                      $p.keep(True);\n                      $t.close()\n                  }\n              } );\n          },\n          quit => -> \\ex {\n              $l.protect( {\n                  if $p.status == Planned {\n                      $p.break(ex);\n                      $t.close()\n                  }\n              } );\n          },\n        );\n        $p.result\n    }\n\n    method list(Supply:D:) {\n        # Use a Channel to handle any asynchrony.\n        self.Channel.list;\n    }\n\n    method on-demand(Supply:U: |c)       { SupplyOperations.on-demand(|c) }\n    method from-list(Supply:U: |c)       { SupplyOperations.from-list(|c) }\n    method interval(Supply:U: |c)        { SupplyOperations.interval(|c) }\n    method flat(Supply:D: )              { SupplyOperations.flat(self) }\n    method grep(Supply:D: Mu $test)      { SupplyOperations.grep(self, $test) }\n    method map(Supply:D: &mapper)        { SupplyOperations.map(self, &mapper) }\n    method schedule-on(Supply:D: Scheduler $scheduler) {\n        SupplyOperations.schedule-on(self, $scheduler);\n    }\n    method start(Supply:D: &startee)     { SupplyOperations.start(self, &startee) }\n    method stable(Supply:D: $time, :$scheduler = $*SCHEDULER) {\n        SupplyOperations.stable(self, $time, :$scheduler);\n    }\n    method delay(Supply:D: $time, :$scheduler = $*SCHEDULER) {\n        DEPRECATED('delayed', '2015.02', '2015.09');\n        SupplyOperations.delayed(self, $time, :$scheduler);\n    }\n    method delayed(Supply:D: $time, :$scheduler = $*SCHEDULER) {\n        SupplyOperations.delayed(self, $time, :$scheduler)\n    }\n    method migrate(Supply:D: )           { SupplyOperations.migrate(self) }\n\n    multi method classify(Supply:D: &mapper )  {\n        SupplyOperations.classify(self, &mapper);\n    }\n    multi method classify(Supply:D: %mapper )  {\n        SupplyOperations.classify(self, { %mapper{$^a} });\n    }\n    multi method classify(Supply:D: @mapper )  {\n        SupplyOperations.classify(self, { @mapper[$^a] });\n    }\n\n    proto method categorize (|) { * }\n    multi method categorize(Supply:D: &mapper )  {\n        SupplyOperations.classify(self, &mapper, :multi);\n    }\n    multi method categorize(Supply:D: %mapper )  {\n        SupplyOperations.classify(self, { %mapper{$^a} }, :multi);\n    }\n    multi method categorize(Supply:D: @mapper )  {\n        SupplyOperations.classify(self, { @mapper[$^a] }, :multi);\n    }\n\n    method act(Supply:D: &actor) {\n        self.do(&actor).tap(|%_) # need \"do\" for serializing callbacks\n    }\n\n    method do(Supply:D $self: &side_effect) {\n        on -> $res {\n            $self => -> \\val { side_effect(val); $res.emit(val) }\n        }\n    }\n\n    method unique(Supply:D $self: :&as, :&with, :$expires) {\n        on -> $res {\n            $self => do {\n                if $expires {\n                    if &with and &with !=== &[===] {\n                        my @seen;  # really Mu, but doesn't work in settings\n                        my Mu $target;\n                        &as\n                          ?? -> \\val {\n                              my $now := now;\n                              $target = &as(val);\n                              my $index =\n                                @seen.first-index({&with($target,$_[0])});\n                              if $index.defined {\n                                  if $now > @seen[$index][1] {  # expired\n                                      @seen[$index][1] = $now+$expires;\n                                      $res.emit(val);\n                                  }\n                              }\n                              else {\n                                  @seen.push: [$target, $now+$expires];\n                                  $res.emit(val);\n                              }\n                          }\n                          !! -> \\val {\n                              my $now := now;\n                              my $index =\n                                @seen.first-index({&with(val,$_[0])});\n                              if $index.defined {\n                                  if $now > @seen[$index][1] {  # expired\n                                      @seen[$index][1] = $now+$expires;\n                                      $res.emit(val);\n                                  }\n                              }\n                              else {\n                                  @seen.push: [val, $now+$expires];\n                                  $res.emit(val);\n                              }\n                          };\n                    }\n                    else {\n                        my $seen := nqp::hash();\n                        my str $target;\n                        &as\n                          ?? -> \\val {\n                              my $now := now;\n                              $target = nqp::unbox_s(&as(val).WHICH);\n                              if !nqp::existskey($seen,$target) ||\n                                $now > nqp::atkey($seen,$target) { #expired\n                                  $res.emit(val);\n                                  nqp::bindkey($seen,$target,$now+$expires);\n                              }\n                          }\n                          !! -> \\val {\n                              my $now := now;\n                              $target = nqp::unbox_s(val.WHICH);\n                              if !nqp::existskey($seen,$target) ||\n                                $now > nqp::atkey($seen,$target) { #expired\n                                  $res.emit(val);\n                                  nqp::bindkey($seen,$target,$now+$expires);\n                              }\n                          };\n                    }\n                }\n                else { # !$!expires\n                    if &with and &with !=== &[===] {\n                        my @seen;  # really Mu, but doesn't work in settings\n                        my Mu $target;\n                        &as\n                          ?? -> \\val {\n                              $target = &as(val);\n                              if @seen.first({ &with($target,$_) } ) =:= Nil {\n                                  @seen.push($target);\n                                  $res.emit(val);\n                              }\n                          }\n                          !! -> \\val {\n                              if @seen.first({ &with(val,$_) } ) =:= Nil {\n                                  @seen.push(val);\n                                  $res.emit(val);\n                              }\n                          };\n                    }\n                    else {\n                        my $seen := nqp::hash();\n                        my str $target;\n                        &as\n                          ?? -> \\val {\n                              $target = nqp::unbox_s(&as(val).WHICH);\n                              unless nqp::existskey($seen, $target) {\n                                  nqp::bindkey($seen, $target, 1);\n                                  $res.emit(val);\n                              }\n                          }\n                          !! -> \\val {\n                              $target = nqp::unbox_s(val.WHICH);\n                              unless nqp::existskey($seen, $target) {\n                                  nqp::bindkey($seen, $target, 1);\n                                  $res.emit(val);\n                              }\n                          };\n                    }\n                }\n            }\n        }\n    }\n\n    method squish(Supply:D $self: :&as, :&with is copy) {\n        &with //= &[===];\n        on -> $res {\n            my @secret;\n            $self => do {\n                my Mu $last = @secret;\n                my Mu $target;\n                &as\n                  ?? -> \\val {\n                      $target = &as(val);\n                      unless &with($target,$last) {\n                          $last = $target;\n                          $res.emit(val);\n                      }\n                  }\n                  !! -> \\val {\n                      unless &with(val,$last) {\n                          $last = val;\n                          $res.emit(val);\n                      }\n                  };\n            }\n        }\n    }\n\n    proto method rotor(|) {*}\n    multi method rotor(Supply:D:) {\n        DEPRECATED('.rotor( $elems => -$gap )',|<2015.04 2015.09>);\n        self.rotor( (2 => -1) );\n    }\n    multi method rotor(Supply:D $self: *@cycle, :$partial) {\n        my @c := @cycle.infinite ?? @cycle !! @cycle xx *;\n\n        on -> $res {\n            $self => do {\n                my Int $elems;\n                my Int $gap;\n                my int $to-skip;\n                my int $skip;\n                sub next-batch() {\n                    given @c.shift {\n                        when Pair {\n                            $elems   = +.key;\n                            $gap     = +.value;\n                            $to-skip = $gap > 0 ?? $gap !! 0;\n                        }\n                        default {\n                            $elems   = +$_;\n                            $gap     = 0;\n                            $to-skip = 0;\n                        }\n                    }\n                }\n                next-batch;\n\n                my @batched;\n                sub flush() {\n                    $res.emit( [@batched] );\n                    @batched.splice( 0, +@batched + $gap );\n                    $skip = $to-skip;\n                }\n\n                {\n                    emit => -> \\val {\n                        @batched.push: val unless $skip && $skip--;\n                        if @batched.elems == $elems {\n                            flush;\n                            next-batch;\n                        }\n                    },\n                    done => {\n                        flush if @batched and $partial;\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method batch(Supply:D $self: :$elems, :$seconds ) {\n\n        return $self if (!$elems or $elems == 1) and !$seconds;  # nothing to do\n\n        on -> $res {\n            $self => do {\n                my @batched;\n                my $last_time;\n                sub flush {\n                    $res.emit([@batched]);\n                    @batched = ();\n                }\n\n                {\n                    emit => do {\n                        if $seconds {\n                            $last_time = time div $seconds;\n\n                            $elems # and $seconds\n                              ??  -> \\val {\n                                  my $this_time = time div $seconds;\n                                  if $this_time != $last_time {\n                                      flush if @batched;\n                                      $last_time = $this_time;\n                                      @batched.push: val;\n                                  }\n                                  else {\n                                      @batched.push: val;\n                                      flush if @batched.elems == $elems;\n                                  }\n                              }\n                              !! -> \\val {\n                                  my $this_time = time div $seconds;\n                                  if $this_time != $last_time {\n                                      flush if @batched;\n                                      $last_time = $this_time;\n                                  }\n                                  @batched.push: val;\n                              }\n                        }\n                        else { # just $elems\n                            -> \\val {\n                                @batched.push: val;\n                                flush if @batched.elems == $elems;\n                            }\n                        }\n                    },\n                    done => {\n                        flush if @batched;\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method lines(Supply:D $self: :$chomp = True ) {\n\n        on -> $res {\n            $self => do {\n                my str $str;\n                my int $chars;\n                my int $left;\n                my int $pos;\n                my int $nextpos;\n                my int $found;\n                my int $cr;\n                my int $crlf;\n\n                {\n                    emit => -> \\val {\n                        $str   = $str ~ nqp::unbox_s(val);\n                        $chars = nqp::chars($str);\n                        $pos   = 0;\n\n                        while ($left = $chars - $pos) > 0 {\n                            $nextpos = nqp::findcclass(\n                              nqp::const::CCLASS_NEWLINE, $str, $pos, $left\n                            );\n\n                            # no trailing line delimiter, so go buffer\n                            last unless nqp::iscclass(\n                              nqp::const::CCLASS_NEWLINE, $str, $nextpos\n                            );\n\n                            # potentially broken CRLF, so go buffer\n                            $cr = nqp::ordat($str, $nextpos) == 13;    # CR\n                            last if $cr == 1 and $nextpos + 1 == $chars;\n\n                            $crlf = $cr\n                              && nqp::ordat($str, $nextpos + 1) == 10; # LF\n\n                            if $chomp {\n                                $res.emit( ($found = $nextpos - $pos)\n                                  ?? nqp::box_s(\n                                       nqp::substr($str, $pos, $found), Str)\n                                  !! ''\n                                );\n                                $pos = $nextpos + 1 + $crlf;\n                            }\n                            else {\n                                $found = $nextpos - $pos + 1 + $crlf;\n                                $res.emit( nqp::box_s(\n                                  nqp::substr($str, $pos, $found), Str)\n                                );\n                                $pos = $pos + $found;\n                            }\n                        }\n                        $str = $pos < $chars\n                          ?? nqp::substr($str,$pos)\n                          !! '';\n                    },\n                    done => {\n                        if $str {\n                            $chars = nqp::chars($str);\n                            $res.emit( $chomp\n                              && nqp::ordat($str, $chars - 1) == 13    # CR\n                              ?? nqp::box_s(nqp::substr($str,0,$chars - 1),Str)\n                              !! nqp::box_s($str, Str)\n                            );\n                        }\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method words(Supply:D $self:) {\n\n        on -> $res {\n            $self => do {\n                my str $str;\n                my int $chars;\n                my int $left;\n                my int $pos;\n                my int $nextpos;\n                my int $found;\n                my int $cr;\n                my int $crlf;\n\n                {\n                    emit => -> \\val {\n                        $str   = $str ~ nqp::unbox_s(val);\n                        $chars = nqp::chars($str);\n                        $pos   = nqp::findnotcclass(\n                          nqp::const::CCLASS_WHITESPACE, $str, 0, $chars);\n\n                        while ($left = $chars - $pos) > 0 {\n                            $nextpos = nqp::findcclass(\n                              nqp::const::CCLASS_WHITESPACE, $str, $pos, $left\n                            );\n\n                            last unless $left = $chars - $nextpos; # broken word\n\n                            $res.emit( nqp::box_s(\n                              nqp::substr( $str, $pos, $nextpos - $pos ), Str)\n                            );\n\n                            $pos = nqp::findnotcclass(\n                              nqp::const::CCLASS_WHITESPACE,$str,$nextpos,$left);\n                        }\n                        $str = $pos < $chars\n                          ?? nqp::substr($str,$pos)\n                          !! '';\n                    },\n                    done => {\n                        $res.emit( nqp::box_s($str, Str) ) if $str;\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method elems(Supply:D $self: $seconds? ) {\n\n        on -> $res {\n            $self => do {\n                my $elems = 0;\n                my $last_time;\n                my $last_elems;\n\n                {\n                    emit => do {\n                        if $seconds {\n                            $last_time  = time div $seconds;\n                            $last_elems = $elems;\n                            -> \\val {\n                                  $last_elems = ++$elems;\n                                  my $this_time = time div $seconds;\n                                  if $this_time != $last_time {\n                                      $res.emit($elems);\n                                      $last_time = $this_time;\n                                  }\n                            }\n                        }\n                        else {\n                            -> \\val { $res.emit(++$elems) }\n                        }\n                    },\n                    done => {\n                        $res.emit($elems) if $seconds and $elems != $last_elems;\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method last(Supply:D $self: Int $number = 1) {  # should be Natural\n        on -> $res {\n            $self => do {\n                my @seen;\n                {\n                    emit => $number == 1\n                      ?? -> \\val { @seen[0] = val }\n                      !! -> \\val {\n                          @seen.shift if +@seen == $number;\n                          @seen.push: val;\n                      },\n                    done => {\n                        $res.emit($_) for @seen;\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method min(Supply:D $self: &by = &infix:<cmp>) {\n        my &cmp = &by.arity == 2 ?? &by !! { by($^a) cmp by($^b) }\n        on -> $res {\n            $self => do {\n                my $min;\n                {\n                    emit => -> \\val {\n                        if val.defined and !$min.defined || cmp(val,$min) < 0 {\n                            $res.emit( $min = val );\n                        }\n                    },\n                    done => { $res.done }\n                }\n            }\n        }\n    }\n\n    method max(Supply:D $self: &by = &infix:<cmp>) {\n        my &cmp = &by.arity == 2 ?? &by !! { by($^a) cmp by($^b) }\n        on -> $res {\n            $self => do {\n                my $max;\n                {\n                    emit => -> \\val {\n                        if val.defined and !$max.defined || cmp(val,$max) > 0 {\n                            $res.emit( $max = val );\n                        }\n                    },\n                    done => { $res.done }\n                }\n            }\n        }\n    }\n\n    method minmax(Supply:D $self: &by = &infix:<cmp>) {\n        my &cmp = &by.arity == 2 ?? &by !! { by($^a) cmp by($^b) }\n        on -> $res {\n            $self => do {\n                my $min;\n                my $max;\n                {\n                    emit => -> \\val {\n                        if val.defined {\n                            if !$min.defined {\n                                $res.emit( Range.new($min = val, $max = val) );\n                            }\n                            elsif cmp(val,$min) < 0 {\n                                $res.emit( Range.new( $min = val, $max ) );\n                            }\n                            elsif cmp(val,$max) > 0 {\n                                $res.emit( Range.new( $min, $max = val ) );\n                            }\n                        }\n                    },\n                    done => { $res.done }\n                }\n            }\n        }\n    }\n\n    method reduce(Supply:D $self: &with) {\n        on -> $res {\n            $self => do {\n                my $notfirst;\n                my $reduced;\n                {\n                    emit => -> \\val {\n                        $reduced = $notfirst ?? with($reduced,val) !! val;\n                        $res.emit($reduced);\n                        once $notfirst = True;\n                    },\n                    done => { $res.done }\n                }\n            }\n        }\n    }\n\n    method grab(Supply:D $self: &when_done) {\n        on -> $res {\n            $self => do {\n                my @seen;\n                {\n                    emit => -> \\val { @seen.push: val },\n                    done => {\n                        $res.emit($_) for when_done(@seen);\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method reverse(Supply:D:)                 { self.grab( {.reverse} ) }\n    method sort(Supply:D: &by = &infix:<cmp>) { self.grab( {.sort(&by)} ) }\n\n    method merge(*@s) {\n        @s.unshift(self) if self.DEFINITE;  # add if instance method\n        return Supply unless +@s;           # nothing to be done\n\n        X::Supply::Combinator.new(\n           combinator => 'merge'\n        ).throw if NOT_ALL_DEFINED_TYPE(@s,Supply);\n\n        return @s[0]  if +@s == 1;          # nothing to be done\n\n        my $dones = 0;\n        on -> $res {\n            @s => {\n                emit => -> \\val { $res.emit(val) },\n                done => { $res.done() if ++$dones == +@s }\n            },\n        }\n    }\n\n    method zip(*@s, :&with is copy = &[,]) {\n        @s.unshift(self) if self.DEFINITE;  # add if instance method\n        return Supply unless +@s;           # nothing to be done\n\n        X::Supply::Combinator.new(\n           combinator => 'zip'\n        ).throw if NOT_ALL_DEFINED_TYPE(@s,Supply);\n\n        return @s[0]  if +@s == 1;          # nothing to be done\n\n        my @values = ( [] xx +@s );\n        on -> $res {\n            @s => -> $val, $index {\n                @values[$index].push($val);\n                if all(@values) {\n                    $res.emit( [[&with]] @values>>.shift );\n                }\n            }\n        }\n    }\n\n    method zip-latest(*@s, :&with is copy = &[,], :$initial ) {\n        @s.unshift(self) if self.DEFINITE;  # add if instance method\n        return Supply unless +@s;           # nothing to do.\n\n        X::Supply::Combinator.new(\n           combinator => 'zip-latest'\n        ).throw if NOT_ALL_DEFINED_TYPE(@s,Supply);\n\n        return @s[0] if +@s == 1;           # nothing to do.\n\n        my @values;\n\n        my $uninitialised = +@s; # how many supplies have yet to emit until we\n                                 # can start emitting, too?\n\n        if $initial {\n            @values = @$initial;\n            $uninitialised = 0 max $uninitialised - @$initial;\n        }\n\n        my $dones = 0;\n\n        on -> $res {\n            @s => do {\n                {\n                emit => -> $val, $index {\n                    if $uninitialised > 0 && not @values.EXISTS-POS($index) {\n                        --$uninitialised;\n                    }\n                    @values[$index] = $val;\n                    unless $uninitialised {\n                        $res.emit( [[&with]] @values );\n                    }\n                },\n                done => { $res.done() if ++$dones == +@s }\n                }\n            }\n        }\n    }\n\n    method for(Supply:U: |c) {\n        DEPRECATED('from-list',|<2015.01 2015.09>);\n        SupplyOperations.from-list(|c);\n    }\n    method on_demand(Supply:U: |c)       {\n        DEPRECATED('on-demand',|<2015.03 2015.09>);\n        SupplyOperations.on-demand(|c);\n    }\n    method schedule_on(Supply:D: Scheduler $scheduler) {\n        DEPRECATED('schedule-on',|<2015.03 2015.09>);\n        SupplyOperations.schedule-on(self, $scheduler);\n    }\n    method uniq(Supply:D: |c) {\n        DEPRECATED('unique', |<2014.11 2015.09>);\n        self.unique(|c);\n    }\n}\n\n# The on meta-combinator provides a mechanism for implementing thread-safe\n# combinators on Supplies. It subscribes to a bunch of sources, but will\n# only let one of the specified callbacks to handle their emit/done/quit run\n# at a time. A little bit actor-like.\nmy class X::Supply::On::BadSetup is Exception {\n    method message() {\n        \"on requires a callable that returns a list of pairs with Supply keys\"\n    }\n}\nmy class X::Supply::On::NoEmit is Exception {\n    method message() {\n        \"on requires that emit be specified for each supply\"\n    }\n}\nsub on(&setup) {\n    my class OnSupply does Supply {\n        has &!setup;\n        has Bool $!live = False;\n\n        submethod BUILD(:&!setup) { }\n\n        method !add_source(\n          $source, $lock, $index, :&done is copy, :&quit is copy,\n          :&emit is copy, :&more   # more deprecated, emit must be changeable\n        ) {\n            DEPRECATED('emit => {...}', |<2014.10 2015.09>) if &more;\n            $!live ||= True if $source.live;\n            &emit //= &more // X::Supply::On::NoEmit.new.throw;\n            &done //= { self.done };\n            &quit //= -> $ex { self.quit($ex) };\n\n            my &tap_emit = &emit.arity == 2\n              ?? -> \\val {\n                  $lock.protect({ emit(val,$index) });\n                  CATCH { default { self.quit($_) } }\n              }\n              !!  -> \\val {\n                  $lock.protect({ emit(val) });\n                  CATCH { default { self.quit($_) } }\n              };\n\n            my &tap_done = &done.arity == 1\n              ?? {\n                  $lock.protect({ done($index) });\n                  CATCH { default { self.quit($_) } }\n              }\n              !! {\n                  $lock.protect({ done() });\n                  CATCH { default { self.quit($_) } }\n              };\n\n            my &tap_quit = &quit.arity == 2\n              ?? -> $ex {\n                  $lock.protect({ quit($ex,$index) });\n                  CATCH { default { self.quit($_) } }\n              }\n              !! -> $ex {\n                  $lock.protect({ quit($ex) });\n                  CATCH { default { self.quit($_) } }\n              };\n\n            $source.tap( &tap_emit, done => &tap_done, quit => &tap_quit );\n        }\n\n        method live { $!live }\n        method tap(|c) {\n            my @to_close;\n            my $sub = self.Supply::tap( |c, closing => {.close for @to_close});\n            my @tappers = &!setup(self);\n            my $lock    = Lock.new;\n\n            sub add ($source, $what, $index?) {\n                unless nqp::istype($source,Supply) {\n                    X::Supply::On::BadSetup.new.throw;\n                }\n                given $what {\n                    when EnumMap {\n                        @to_close.push(self!add_source($source, $lock, $index, |$what));\n                    }\n                    when Callable {\n                        @to_close.push(self!add_source($source, $lock, $index, emit => $what));\n                    }\n                    default {\n                        X::Supply::On::BadSetup.new.throw;\n                    }\n                }\n            }\n\n            for @tappers -> $tap {\n                unless nqp::istype($tap,Pair) {\n                    X::Supply::On::BadSetup.new.throw;\n                }\n                given $tap.key {\n                    when Positional {\n                        my $todo := $tap.value;\n                        for .list.kv -> $index, $supply {\n                            add( $supply, $todo, $index );\n                        }\n                    }\n                    when Supply {\n                        add( $_, $tap.value );\n                    }\n                    default {\n                        X::Supply::On::BadSetup.new.throw;\n                    }\n                }\n            }\n            $sub\n        }\n\n        method emit(\\msg) {\n            for self.tappers {\n                .emit().(msg)\n            }\n            Nil;\n        }\n\n        method done() {\n            for self.tappers {\n                if .done -> $l { $l() }\n            }\n            Nil;\n        }\n\n        method quit($ex) {\n            for self.tappers {\n                if .quit -> $t { $t($ex) }\n            }\n            Nil;\n        }\n    }\n\n    OnSupply.new(:&setup)\n}\n\n"
  },
  {
    "path": "Tmain/selector-select-perl6-for-dot-pm.d/input2.pm",
    "content": "# Taken from Units/parser-raku/raku-package.d/input.rakumod\nuse v6;\npackage Foo {\n    sub hello-world is export {\n        say \"hey there\";\n    }\n}\n"
  },
  {
    "path": "Tmain/selector-select-perl6-for-dot-pm.d/input3.pm",
    "content": "# Taken from perl5/subs.pm\npackage subs;\n\nuse strict;\nuse warnings;\n\nour $VERSION = '1.04';\n\n=head1 NAME\n\nsubs - Perl pragma to predeclare subroutine names\n\n=head1 SYNOPSIS\n\n    use subs qw(frob);\n    frob 3..10;\n\n=head1 DESCRIPTION\n\nThis will predeclare all the subroutines whose names are\nin the list, allowing you to use them without parentheses (as list operators)\neven before they're declared.\n\nUnlike pragmas that affect the C<$^H> hints variable, the C<use vars> and\nC<use subs> declarations are not lexically scoped to the block they appear\nin: they affect\nthe entire package in which they appear.  It is not possible to rescind these\ndeclarations with C<no vars> or C<no subs>.\n\nSee L<perlmodlib/Pragmatic Modules> and L<strict/strict subs>.\n\n=cut\n\nsub import {\n    my $callpack = caller;\n    my $pack = shift;\n    my @imports = @_;\n    foreach my $sym (@imports) {\n        no strict 'refs';\n        *{\"${callpack}::$sym\"} = \\&{\"${callpack}::$sym\"};\n    }\n};\n\n1;\n"
  },
  {
    "path": "Tmain/selector-select-perl6-for-dot-pm.d/run.sh",
    "content": "# Copyright: 2023 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\necho \"# --print-language\"\nfor i in input0.pm input1.pm input2.pm input3.pm; do\n\t${CTAGS} --quiet --options=NONE --print-language $i\ndone\n"
  },
  {
    "path": "Tmain/selector-select-perl6-for-dot-pm.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/selector-select-perl6-for-dot-pm.d/stdout-expected.txt",
    "content": "# --print-language\ninput0.pm: Perl6\ninput1.pm: Perl6\ninput2.pm: Perl6\ninput3.pm: Perl\n"
  },
  {
    "path": "Tmain/selector-xml-root-elelement.d/input.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<node name=\"/\">\n</node>\n"
  },
  {
    "path": "Tmain/selector-xml-root-elelement.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nis_feature_available ${CTAGS} xpath\n\n${CTAGS} --quiet --options=NONE --print-language input.xml\n"
  },
  {
    "path": "Tmain/selector-xml-root-elelement.d/stdout-expected.txt",
    "content": "input.xml: DBusIntrospect\n"
  },
  {
    "path": "Tmain/sorted-list-languages.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/sorted-list-languages.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\nCTAGS=$1\nBUILDDIR=$2\n\n. ../utils.sh\n\nif ! sort --help | grep --quiet GNU; then\n    skip \"GNU sort is needed to run this test case\"\nfi\n\nlist_languages()\n{\n    ${CTAGS} --quiet --options=NONE --list-languages\n}\n\nlist_languages > $BUILDDIR/ll.tmp\nlist_languages | sort --ignore-case > $BUILDDIR/sorted-ll.tmp\ndiff -uN $BUILDDIR/ll.tmp $BUILDDIR/sorted-ll.tmp\nr=$?\nrm $BUILDDIR/ll.tmp $BUILDDIR/sorted-ll.tmp\nexit $r\n"
  },
  {
    "path": "Tmain/sorted-list-languages.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/sorted-list-languages.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/subparser-direction.d/input.cc",
    "content": " ABC();\nint main(void)\n{\n}\n"
  },
  {
    "path": "Tmain/subparser-direction.d/input.mojom",
    "content": " ABC();\nint main(void)\n{\n}\n"
  },
  {
    "path": "Tmain/subparser-direction.d/mojom-bidirectional.ctags",
    "content": "--langdef=mojom{base=C++}{bidirectional}\n--map-mojom=+.mojom\n--kinddef-mojom=f,function,functions\n--regex-mojom=/^[ ]+([a-zA-Z]+)\\(/\\1/f/\n"
  },
  {
    "path": "Tmain/subparser-direction.d/mojom-dedicated.ctags",
    "content": "--langdef=mojom{base=C++}{dedicated}\n--kinddef-mojom=f,function,functions\n--map-mojom=+.mojom\n--regex-mojom=/^[ ]+([a-zA-Z]+)\\(/\\1/f/\n"
  },
  {
    "path": "Tmain/subparser-direction.d/mojom-default.ctags",
    "content": "--langdef=mojom{base=C++}\n--map-mojom=+.mojom\n--kinddef-mojom=f,function,functions\n--regex-mojom=/^[ ]+([a-zA-Z]+)\\(/\\1/f/\n"
  },
  {
    "path": "Tmain/subparser-direction.d/mojom-shared.ctags",
    "content": "--langdef=mojom{base=C++}{shared}\n--map-mojom=+.mojom\n--kinddef-mojom=f,function,functions\n--regex-mojom=/^[ ]+([a-zA-Z]+)\\(/\\1/f/\n"
  },
  {
    "path": "Tmain/subparser-direction.d/run.sh",
    "content": "# Taken from #1409 submitted by @sgraham\n\nCTAGS=\"$1 --quiet --options=NONE --fields=+l\"\n\necho '#' \"input: input.cc, optlib: shared\"\n${CTAGS} --options=./mojom-shared.ctags -o - input.cc\necho '#' \"input: input.mojom, optlib: shared\"\n${CTAGS} --options=./mojom-shared.ctags -o - input.mojom\n\necho\necho '#' \"input: input.cc, optlib: dedicated\"\n${CTAGS} --options=./mojom-dedicated.ctags -o - input.cc\necho '#' \"input: input.mojom, optlib: dedicated\"\n${CTAGS} --options=./mojom-dedicated.ctags -o - input.mojom\n\necho\necho '#' \"input: input.cc, optlib: bidirectional\"\n${CTAGS} --options=./mojom-bidirectional.ctags -o - input.cc\necho '#' \"input: input.mojom, optlib: bidirectional\"\n${CTAGS} --options=./mojom-bidirectional.ctags -o - input.mojom\n\necho\necho '#' \"input: input.cc, optlib: <default>\"\n${CTAGS} --options=./mojom-default.ctags -o - input.cc\necho '#' \"input: input.mojom, optlib: <default>\"\n${CTAGS} --options=./mojom-default.ctags -o - input.mojom\n"
  },
  {
    "path": "Tmain/subparser-direction.d/stdout-expected.txt",
    "content": "# input: input.cc, optlib: shared\nABC\tinput.cc\t/^ ABC();$/;\"\tf\tlanguage:mojom\nmain\tinput.cc\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n# input: input.mojom, optlib: shared\nABC\tinput.mojom\t/^ ABC();$/;\"\tf\tlanguage:mojom\n\n# input: input.cc, optlib: dedicated\nmain\tinput.cc\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n# input: input.mojom, optlib: dedicated\nABC\tinput.mojom\t/^ ABC();$/;\"\tf\tlanguage:mojom\nmain\tinput.mojom\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n\n# input: input.cc, optlib: bidirectional\nABC\tinput.cc\t/^ ABC();$/;\"\tf\tlanguage:mojom\nmain\tinput.cc\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n# input: input.mojom, optlib: bidirectional\nABC\tinput.mojom\t/^ ABC();$/;\"\tf\tlanguage:mojom\nmain\tinput.mojom\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n\n# input: input.cc, optlib: <default>\nABC\tinput.cc\t/^ ABC();$/;\"\tf\tlanguage:mojom\nmain\tinput.cc\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n# input: input.mojom, optlib: <default>\nABC\tinput.mojom\t/^ ABC();$/;\"\tf\tlanguage:mojom\n"
  },
  {
    "path": "Tmain/tab-in-parser-specific-field.d/foo.ctags",
    "content": "--langdef=foo\n--map-foo=.foo\n--_fielddef-foo=fprop,property attached to a function\n--kinddef-foo=f,func,functions\n--fields-foo=+{fprop}\n--regex-foo=/^def +([^@]+)@prop(\\([^\\)]*\\)):/\\1/f/{_field=fprop:\\2}\n"
  },
  {
    "path": "Tmain/tab-in-parser-specific-field.d/input.foo",
    "content": "def b@prop(arg0, arg1):\n    pass\n\n# TAB char betwen arg0 and arg1\ndef a@prop(arg0,\targ1):\n    pass\n"
  },
  {
    "path": "Tmain/tab-in-parser-specific-field.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nrun()\n{\n\techo '#'\n\techo '#' with $1\n\techo '#'\n\n\techo \"# Universal-ctags output format\"\n\t$CTAGS --options=NONE --options=./foo.ctags \"$1\" --output-format=u-ctags  -o - input.foo\n\n\techo \"# Exuberant-ctags output format\"\n\techo \"# 'a' has a tab char in fprop fields. So ctags drops it silent.\"\n\t$CTAGS --options=NONE --options=./foo.ctags \"$1\" --output-format=e-ctags  -o - input.foo\n}\n\nrun \"--sort=yes\"\nrun \"--sort=no\"\n"
  },
  {
    "path": "Tmain/tab-in-parser-specific-field.d/stdout-expected.txt",
    "content": "#\n# with --sort=yes\n#\n# Universal-ctags output format\na\tinput.foo\t/^def a@prop(arg0,\targ1):$/;\"\tf\tfprop:(arg0,\\targ1)\nb\tinput.foo\t/^def b@prop(arg0, arg1):$/;\"\tf\tfprop:(arg0, arg1)\n# Exuberant-ctags output format\n# 'a' has a tab char in fprop fields. So ctags drops it silent.\nb\tinput.foo\t/^def b@prop(arg0, arg1):$/;\"\tf\tfprop:(arg0, arg1)\n#\n# with --sort=no\n#\n# Universal-ctags output format\nb\tinput.foo\t/^def b@prop(arg0, arg1):$/;\"\tf\tfprop:(arg0, arg1)\na\tinput.foo\t/^def a@prop(arg0,\targ1):$/;\"\tf\tfprop:(arg0,\\targ1)\n# Exuberant-ctags output format\n# 'a' has a tab char in fprop fields. So ctags drops it silent.\nb\tinput.foo\t/^def b@prop(arg0, arg1):$/;\"\tf\tfprop:(arg0, arg1)\n"
  },
  {
    "path": "Tmain/tag-relative-option-in-etags.d/indirect/src/input.c",
    "content": "int main (void) {return 0;}\n"
  },
  {
    "path": "Tmain/tag-relative-option-in-etags.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\nARGS=\"--quiet --options=NONE\"\nO=TAGS.TMP\n\n. ../utils.sh\n\nfor x in no yes default; do\n    touch $BUILDDIR/${x}-$O\ndone\n\nif ! direq_maybe $BUILDDIR .; then\n\tcp -r indirect $BUILDDIR\n\tcopied=yes\nfi\n(\n    cd $BUILDDIR/indirect\n\n    ${CTAGS} ${ARGS} -e  -o ../no-${O}      --tag-relative=no  src/input.c\n    ${CTAGS} ${ARGS} -e  -o ../yes-${O}     --tag-relative=yes src/input.c\n    ${CTAGS} ${ARGS} -e  -o ../default-${O}                    src/input.c\n)\n\nfor x in no yes default; do\n    echo '#' ${x}\n    # convert path separators in the output\n    sed -e 's|\\\\|/|g' $BUILDDIR/${x}-$O\n    rm $BUILDDIR/${x}-$O\ndone\n\nif [ \"$copied\" = \"yes\" ]; then\n\tchmod -R u+w $BUILDDIR/indirect\n\trm -rf $BUILDDIR/indirect\nfi\n\nexit $?\n"
  },
  {
    "path": "Tmain/tag-relative-option-in-etags.d/stdout-expected.txt",
    "content": "# no\n\f\nsrc/input.c,37\nint main (void) {return 0;}main\u00011,0\n# yes\n\f\nindirect/src/input.c,37\nint main (void) {return 0;}main\u00011,0\n# default\n\f\nindirect/src/input.c,37\nint main (void) {return 0;}main\u00011,0\n"
  },
  {
    "path": "Tmain/tag-relative-option-no-optarg.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/tag-relative-option-no-optarg.d/run.sh",
    "content": "# Copyright: 2019 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=\"--quiet --options=NONE \"\n\n${CTAGS} $O --tag-relative --_force-quit=0\n"
  },
  {
    "path": "Tmain/tag-relative-option.d/input.c",
    "content": "#define X 1\n"
  },
  {
    "path": "Tmain/tag-relative-option.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nO=\"--quiet --options=NONE -o - -x \"\nP=$(pwd)\n\nif type realpath > /dev/null 2>&1; then\n   P=$(realpath \"$P\")\n   cd \"$P\"\nfi\n\n. ../utils.sh\n\nif ! ${CTAGS} $O --help | grep -e --tag-relative | grep --quiet -e always; then\n\techo \"--tag-relative=always|never is not available on this platform\"\n\texit ${__SKIP__}\nfi\n\n{\n    F=./input.c\n    ${CTAGS} $O --_xformat=\"default: $F -> %F\"                        $F\n    ${CTAGS} $O --_xformat=\"never:   $F -> %F\"  --tag-relative=never  $F\n    ${CTAGS} $O --_xformat=\"no:      $F -> %F\"  --tag-relative=no     $F\n    ${CTAGS} $O --_xformat=\"yes:     $F -> %F\"  --tag-relative=yes    $F\n    ${CTAGS} $O --_xformat=\"always:  $F -> %F\"  --tag-relative=always $F\n\n    F=input.c\n    ${CTAGS} $O --_xformat=\"default: $F -> %F\"                        $F\n    ${CTAGS} $O --_xformat=\"never:   $F -> %F\"  --tag-relative=never  $F\n    ${CTAGS} $O --_xformat=\"no:      $F -> %F\"  --tag-relative=no     $F\n    ${CTAGS} $O --_xformat=\"yes:     $F -> %F\"  --tag-relative=yes    $F\n    ${CTAGS} $O --_xformat=\"always:  $F -> %F\"  --tag-relative=always $F\n\n    F=${P}/input.c\n    ${CTAGS} $O --_xformat=\"default: $F -> %F\"                        $F\n    ${CTAGS} $O --_xformat=\"never:   $F -> %F\"  --tag-relative=never  $F\n    ${CTAGS} $O --_xformat=\"no:      $F -> %F\"  --tag-relative=no     $F\n    ${CTAGS} $O --_xformat=\"yes:     $F -> %F\"  --tag-relative=yes    $F\n    ${CTAGS} $O --_xformat=\"always:  $F -> %F\"  --tag-relative=always $F\n} | {\n    # Normalize Windows driver letter\n    #\n    # comment time:   Sat Feb  6 13:11:44 UTC 2021\n    # comment author: leleliu008@gmail.com\n    #\n    # as far as I know, the most widely used unix-like POSIX-compatible environments on Windows are Cygwin and MSYS2. Actually, MSYS2 is a modified fork of Cygwin. They both provide a command-line tool called cygpath which can be used to convert Windows PATH to UNIX path. There exists other unix-like POSIX-compatible environments on Windows, git-for-windows as an example, but they all based on Cygwin or MSYS2.\n    if command -v cygpath > /dev/null && command -v awk > /dev/null ; then\n        awk '{if ($NF ~ /^[A-Z]:/) { \"cygpath \"$NF | getline newpath; sub($NF,newpath) } print}'\n    else\n        # \\l is a GNU extension. But only Windows's path match [A-Z]: pattern, Cygwin and MSYS2 use GNU sed.\n        sed 's|\\([A-Z]\\):|/\\l\\1|'\n    fi\n} | {\n\t# Unescape\n\tsed -e 's|\\\\\\\\|\\\\|g'\n} | {\n\t# Convert to /\n    sed -e 's|\\\\|/|g'\n} | {\n\t# Convert pwd test environment neutral\n    sed -e \"s|${P}|/abs|g\"\n}\n"
  },
  {
    "path": "Tmain/tag-relative-option.d/stdout-expected.txt",
    "content": "default: ./input.c -> ./input.c\nnever:   ./input.c -> /abs/input.c\nno:      ./input.c -> ./input.c\nyes:     ./input.c -> input.c\nalways:  ./input.c -> input.c\ndefault: input.c -> input.c\nnever:   input.c -> /abs/input.c\nno:      input.c -> input.c\nyes:     input.c -> input.c\nalways:  input.c -> input.c\ndefault: /abs/input.c -> /abs/input.c\nnever:   /abs/input.c -> /abs/input.c\nno:      /abs/input.c -> /abs/input.c\nyes:     /abs/input.c -> /abs/input.c\nalways:  /abs/input.c -> input.c\n"
  },
  {
    "path": "Tmain/tags-output-typed-fields.d/input.c",
    "content": "static int local;\nint global;\n"
  },
  {
    "path": "Tmain/tags-output-typed-fields.d/input.ctst",
    "content": "f\n"
  },
  {
    "path": "Tmain/tags-output-typed-fields.d/input.rst",
    "content": "==============================================\nTITLE\n==============================================\n\nsection\n-------\n"
  },
  {
    "path": "Tmain/tags-output-typed-fields.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t\t --output-format=u-ctags \\\n\t\t --language-force=CTagsSelfTest input.ctst\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t\t --output-format=u-ctags \\\n\t\t --fields-RestructuredText=+'{overline}' \\\n\t\t input.rst\n\n${CTAGS} --quiet --options=NONE -o - \\\n\t\t --output-format=u-ctags \\\n\t\t input.c\n"
  },
  {
    "path": "Tmain/tags-output-typed-fields.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/tags-output-typed-fields.d/stdout-expected.txt",
    "content": "atag\tinput.ctst\t/^f$/;\"\tf\nbtag\tinput.ctst\t/^f$/;\"\tf\tbField:\nctag\tinput.ctst\t/^f$/;\"\tf\tbField:\ndtag\tinput.ctst\t/^f$/;\"\tf\tsbField:val\netag\tinput.ctst\t/^f$/;\"\tf\tsbField:\nftag\tinput.ctst\t/^f$/;\"\tf\tsField:val\ngtag\tinput.ctst\t/^f$/;\"\tf\tsField:\nhtag\tinput.ctst\t/^f$/;\"\tf\tiField:23\nitag\tinput.ctst\t/^f$/;\"\tf\tiField:-3\njtag\tinput.ctst\t/^f$/;\"\tf\tiField:1\nktag\tinput.ctst\t/^f$/;\"\tf\tiField:0\nTITLE\tinput.rst\t/^TITLE$/;\"\tH\toverline:\nsection\tinput.rst\t/^section$/;\"\th\ttitle:TITLE\nglobal\tinput.c\t/^int global;$/;\"\tv\ttyperef:typename:int\nlocal\tinput.c\t/^static int local;$/;\"\tv\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Tmain/tmain-example.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/tmain-example.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nBUILDDIR=$2\n\n${CTAGS} --quiet --options=NONE --list-kinds=Ruby && echo X > ${BUILDDIR}/tags\n"
  },
  {
    "path": "Tmain/tmain-example.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/tmain-example.d/stdout-expected.txt",
    "content": "c  classes\nf  methods\nm  modules\nS  singleton methods\nC  constants\nA  accessors\na  aliases\nL  libraries\n"
  },
  {
    "path": "Tmain/tmain-example.d/tags-expected.txt",
    "content": "X\n"
  },
  {
    "path": "Tmain/tmain-skip-example.d/run.sh",
    "content": "# Copyright: 2015 Masatake YAMATO\n# License: GPL-2\n\n. ../utils.sh\n\nif ${CTAGS} --quiet --options=NONE --list-features | grep -q afasdfasfasfsa; then\n    echo\nelse\n    skip \"example: no such feature\"\nfi\n"
  },
  {
    "path": "Tmain/tmain-skip-example.d/stdout-expected.txt",
    "content": "THIS FILE WILL NOT BE USE.\n"
  },
  {
    "path": "Tmain/trace-option.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/trace-option.d/input.unknown",
    "content": ""
  },
  {
    "path": "Tmain/trace-option.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\nis_feature_available $CTAGS debug\n\n# For comparison the output and the expectation, sed removes signature parts from the output.\n$CTAGS --quiet --options=NONE --_trace=CTagsSelfTest --language-force=CTagsSelfTest ./input.unknown\nexit $?\n"
  },
  {
    "path": "Tmain/trace-option.d/stderr-expected.txt",
    "content": "[>> parseFile][at 0] Parsing file ./input.unknown\n    [>> createCTSTTags][at 0] Parsing starts\n    [<< createCTSTTags][at 0] \n[<< parseFile][at 0] \n"
  },
  {
    "path": "Tmain/two-inputs-requiring-scope-stack.d/a.dts",
    "content": "/ {\n\taa: c@0 { };\n\tab: c@1 { };\n\tac: c@2 { };\n\tad: c@3 { };\n\tae: c@4 { };\n\taf: c@5 { };\n\tag: c@6 { };\n\tah: c@7 { };\n\tai: c@8 { };\n\taj: c@9 { };\n\tak: c@10 { };\n\tal: c@11 { };\n\tam: c@12 { };\n\tan: c@13 { };\n\tao: c@14 { };\n\tap: c@15 { };\n\taq: c@16 { };\n\tar: c@17 { };\n\tas: c@18 { };\n\tat: c@19 { };\n\tau: c@20 { };\n\tav: c@21 { };\n\taw: c@22 { };\n\tax: c@23 { };\n\tay: c@24 { };\n\tba: c@25 { };\n\tbb: c@26 { };\n\tbc: c@27 { };\n\tbd: c@28 { };\n\tbe: c@29 { };\n\tbf: c@30 { };\n\tbg: c@31 { };\n\tbh: c@32 { };\n\tbi: c@33 { };\n\tbj: c@34 { };\n\tbk: c@35 { };\n\tbl: c@36 { };\n\tbm: c@37 { };\n\tbn: c@38 { };\n\tbo: c@39 { };\n\tbp: c@40 { };\n\tbq: c@41 { };\n\tbr: c@42 { };\n\tbs: c@43 { };\n\tbt: c@44 { };\n\tbu: c@45 { };\n\tbv: c@46 { };\n\tbw: c@47 { };\n\tbx: c@48 { };\n\tby: c@49 { };\n\tca: c@50 { };\n\tcb: c@51 { };\n\tcc: c@52 { };\n\tcd: c@53 { };\n\tce: c@54 { };\n\tcf: c@55 { };\n\tcg: c@56 { };\n\tch: c@57 { };\n\tci: c@58 { };\n\tcj: c@59 { };\n\tck: c@60 { };\n\tcl: c@61 { };\n\tcm: c@62 { };\n\tcn: c@63 { };\n\tco: c@64 { };\n\tcp: c@65 { };\n\tcq: c@66 { };\n\tcr: c@67 { };\n\tcs: c@68 { };\n\tct: c@69 { };\n\tcu: c@70 { };\n\tcv: c@71 { };\n\tcw: c@72 { };\n\tcx: c@73 { };\n\tcy: c@74 { };\n\tda: c@75 { };\n\tdb: c@76 { };\n\tdc: c@77 { };\n\tdd: c@78 { };\n\tde: c@79 { };\n\tdf: c@80 { };\n\tdg: c@81 { };\n\tdh: c@82 { };\n\tdi: c@83 { };\n\tdj: c@84 { };\n\tdk: c@85 { };\n\tdl: c@86 { };\n\tdm: c@87 { };\n\tdn: c@88 { };\n\tdo: c@89 { };\n\tdp: c@90 { };\n\tdq: c@91 { };\n\tdr: c@92 { };\n\tds: c@93 { };\n\tdt: c@94 { };\n\tdu: c@95 { };\n\tdv: c@96 { };\n\tdw: c@97 { };\n\tdx: c@98 { };\n\tdy: c@99 { };\n\tea: c@100 { };\n\teb: c@101 { };\n\tec: c@102 { };\n\ted: c@103 { };\n\tee: c@104 { };\n\tef: c@105 { };\n\teg: c@106 { };\n\teh: c@107 { };\n\tei: c@108 { };\n\tej: c@109 { };\n\tek: c@110 { };\n\tel: c@111 { };\n\tem: c@112 { };\n\ten: c@113 { };\n\teo: c@114 { };\n\tep: c@115 { };\n\teq: c@116 { };\n\ter: c@117 { };\n\tes: c@118 { };\n\tet: c@119 { };\n\teu: c@120 { };\n\tev: c@121 { };\n\tew: c@122 { };\n\tex: c@123 { };\n\tey: c@124 { };\n\tfa: c@125 { };\n\tfb: c@126 { };\n\tfc: c@127 { };\n\tfd: c@128 { };\n\tfe: c@129 { };\n\tff: c@130 { };\n\tfg: c@131 { };\n\tfh: c@132 { };\n\tfi: c@133 { };\n\tfj: c@134 { };\n\tfk: c@135 { };\n\tfl: c@136 { };\n\tfm: c@137 { };\n\tfn: c@138 { };\n\tfo: c@139 { };\n\tfp: c@140 { };\n\tfq: c@141 { };\n\tfr: c@142 { };\n\tfs: c@143 { };\n\tft: c@144 { };\n\tfu: c@145 { };\n\tfv: c@146 { };\n\tfw: c@147 { };\n\tfx: c@148 { };\n\tfy: c@149 { };\n\tga: c@150 { };\n\tgb: c@151 { };\n\tgc: c@152 { };\n\tgd: c@153 { };\n\tge: c@154 { };\n\tgf: c@155 { };\n\tgg: c@156 { };\n\tgh: c@157 { };\n\tgi: c@158 { };\n\tgj: c@159 { };\n\tgk: c@160 { };\n\tgl: c@161 { };\n\tgm: c@162 { };\n\tgn: c@163 { };\n\tgo: c@164 { };\n\tgp: c@165 { };\n\tgq: c@166 { };\n\tgr: c@167 { };\n\tgs: c@168 { };\n\tgt: c@169 { };\n\tgu: c@170 { };\n\tgv: c@171 { };\n\tgw: c@172 { };\n\tgx: c@173 { };\n\tgy: c@174 { };\n\tha: c@175 { };\n\thb: c@176 { };\n\thc: c@177 { };\n\thd: c@178 { };\n\the: c@179 { };\n\thf: c@180 { };\n\thg: c@181 { };\n\thh: c@182 { };\n\thi: c@183 { };\n\thj: c@184 { };\n\thk: c@185 { };\n\thl: c@186 { };\n\thm: c@187 { };\n\thn: c@188 { };\n\tho: c@189 { };\n\thp: c@190 { };\n\thq: c@191 { };\n\thr: c@192 { };\n\ths: c@193 { };\n\tht: c@194 { };\n\thu: c@195 { };\n\thv: c@196 { };\n\thw: c@197 { };\n\thx: c@198 { };\n\thy: c@199 { };\n\tia: c@200 { };\n\tib: c@201 { };\n\tic: c@202 { };\n\tid: c@203 { };\n\tie: c@204 { };\n\tif: c@205 { };\n\tig: c@206 { };\n\tih: c@207 { };\n\tii: c@208 { };\n\tij: c@209 { };\n\tik: c@210 { };\n\til: c@211 { };\n\tim: c@212 { };\n\tin: c@213 { };\n\tio: c@214 { };\n\tip: c@215 { };\n\tiq: c@216 { };\n\tir: c@217 { };\n\tis: c@218 { };\n\tit: c@219 { };\n\tiu: c@220 { };\n\tiv: c@221 { };\n\tiw: c@222 { };\n\tix: c@223 { };\n\tiy: c@224 { };\n\tja: c@225 { };\n\tjb: c@226 { };\n\tjc: c@227 { };\n\tjd: c@228 { };\n\tje: c@229 { };\n\tjf: c@230 { };\n\tjg: c@231 { };\n\tjh: c@232 { };\n\tji: c@233 { };\n\tjj: c@234 { };\n\tjk: c@235 { };\n\tjl: c@236 { };\n\tjm: c@237 { };\n\tjn: c@238 { };\n\tjo: c@239 { };\n\tjp: c@240 { };\n\tjq: c@241 { };\n\tjr: c@242 { };\n\tjs: c@243 { };\n\tjt: c@244 { };\n\tju: c@245 { };\n\tjv: c@246 { };\n\tjw: c@247 { };\n\tjx: c@248 { };\n\tjy: c@249 { };\n\tka: c@250 { };\n\tkb: c@251 { };\n\tkc: c@252 { };\n\tkd: c@253 { };\n\tke: c@254 { };\n\tkf: c@255 { };\n\tkg: c@256 { };\n\tkh: c@257 { };\n\tki: c@258 { };\n\tkj: c@259 { };\n\tkk: c@260 { };\n\tkl: c@261 { };\n\tkm: c@262 { };\n\tkn: c@263 { };\n\tko: c@264 { };\n\tkp: c@265 { };\n\tkq: c@266 { };\n\tkr: c@267 { };\n\tks: c@268 { };\n\tkt: c@269 { };\n\tku: c@270 { };\n\tkv: c@271 { };\n\tkw: c@272 { };\n\tkx: c@273 { };\n\tky: c@274 { };\n\tla: c@275 { };\n\tlb: c@276 { };\n\tlc: c@277 { };\n\tld: c@278 { };\n\tle: c@279 { };\n\tlf: c@280 { };\n\tlg: c@281 { };\n\tlh: c@282 { };\n\tli: c@283 { };\n\tlj: c@284 { };\n\tlk: c@285 { };\n\tll: c@286 { };\n\tlm: c@287 { };\n\tln: c@288 { };\n\tlo: c@289 { };\n\tlp: c@290 { };\n\tlq: c@291 { };\n\tlr: c@292 { };\n\tls: c@293 { };\n\tlt: c@294 { };\n\tlu: c@295 { };\n\tlv: c@296 { };\n\tlw: c@297 { };\n\tlx: c@298 { };\n\tly: c@299 { };\n\tma: c@300 { };\n\tmb: c@301 { };\n\tmc: c@302 { };\n\tmd: c@303 { };\n\tme: c@304 { };\n\tmf: c@305 { };\n\tmg: c@306 { };\n\tmh: c@307 { };\n\tmi: c@308 { };\n\tmj: c@309 { };\n\tmk: c@310 { };\n\tml: c@311 { };\n\tmm: c@312 { };\n\tmn: c@313 { };\n\tmo: c@314 { };\n\tmp: c@315 { };\n\tmq: c@316 { };\n\tmr: c@317 { };\n\tms: c@318 { };\n\tmt: c@319 { };\n\tmu: c@320 { };\n\tmv: c@321 { };\n\tmw: c@322 { };\n\tmx: c@323 { };\n\tmy: c@324 { };\n\tna: c@325 { };\n\tnb: c@326 { };\n\tnc: c@327 { };\n\tnd: c@328 { };\n\tne: c@329 { };\n\tnf: c@330 { };\n\tng: c@331 { };\n\tnh: c@332 { };\n\tni: c@333 { };\n\tnj: c@334 { };\n\tnk: c@335 { };\n\tnl: c@336 { };\n\tnm: c@337 { };\n\tnn: c@338 { };\n\tno: c@339 { };\n\tnp: c@340 { };\n\tnq: c@341 { };\n\tnr: c@342 { };\n\tns: c@343 { };\n\tnt: c@344 { };\n\tnu: c@345 { };\n\tnv: c@346 { };\n\tnw: c@347 { };\n\tnx: c@348 { };\n\tny: c@349 { };\n\toa: c@350 { };\n\tob: c@351 { };\n\toc: c@352 { };\n\tod: c@353 { };\n\toe: c@354 { };\n\tof: c@355 { };\n\tog: c@356 { };\n\toh: c@357 { };\n\toi: c@358 { };\n\toj: c@359 { };\n\tok: c@360 { };\n\tol: c@361 { };\n\tom: c@362 { };\n\ton: c@363 { };\n\too: c@364 { };\n\top: c@365 { };\n\toq: c@366 { };\n\tor: c@367 { };\n\tos: c@368 { };\n\tot: c@369 { };\n\tou: c@370 { };\n\tov: c@371 { };\n\tow: c@372 { };\n\tox: c@373 { };\n\toy: c@374 { };\n\tpa: c@375 { };\n\tpb: c@376 { };\n\tpc: c@377 { };\n\tpd: c@378 { };\n\tpe: c@379 { };\n\tpf: c@380 { };\n\tpg: c@381 { };\n\tph: c@382 { };\n\tpi: c@383 { };\n\tpj: c@384 { };\n\tpk: c@385 { };\n\tpl: c@386 { };\n\tpm: c@387 { };\n\tpn: c@388 { };\n\tpo: c@389 { };\n\tpp: c@390 { };\n\tpq: c@391 { };\n\tpr: c@392 { };\n\tps: c@393 { };\n\tpt: c@394 { };\n\tpu: c@395 { };\n\tpv: c@396 { };\n\tpw: c@397 { };\n\tpx: c@398 { };\n\tpy: c@399 { };\n\tqa: c@400 { };\n\tqb: c@401 { };\n\tqc: c@402 { };\n\tqd: c@403 { };\n\tqe: c@404 { };\n\tqf: c@405 { };\n\tqg: c@406 { };\n\tqh: c@407 { };\n\tqi: c@408 { };\n\tqj: c@409 { };\n\tqk: c@410 { };\n\tql: c@411 { };\n\tqm: c@412 { };\n\tqn: c@413 { };\n\tqo: c@414 { };\n\tqp: c@415 { };\n\tqq: c@416 { };\n\tqr: c@417 { };\n\tqs: c@418 { };\n\tqt: c@419 { };\n\tqu: c@420 { };\n\tqv: c@421 { };\n\tqw: c@422 { };\n\tqx: c@423 { };\n\tqy: c@424 { };\n\tra: c@425 { };\n\trb: c@426 { };\n\trc: c@427 { };\n\trd: c@428 { };\n\tre: c@429 { };\n\trf: c@430 { };\n\trg: c@431 { };\n\trh: c@432 { };\n\tri: c@433 { };\n\trj: c@434 { };\n\trk: c@435 { };\n\trl: c@436 { };\n\trm: c@437 { };\n\trn: c@438 { };\n\tro: c@439 { };\n\trp: c@440 { };\n\trq: c@441 { };\n\trr: c@442 { };\n\trs: c@443 { };\n\trt: c@444 { };\n\tru: c@445 { };\n\trv: c@446 { };\n\trw: c@447 { };\n\trx: c@448 { };\n\try: c@449 { };\n\tsa: c@450 { };\n\tsb: c@451 { };\n\tsc: c@452 { };\n\tsd: c@453 { };\n\tse: c@454 { };\n\tsf: c@455 { };\n\tsg: c@456 { };\n\tsh: c@457 { };\n\tsi: c@458 { };\n\tsj: c@459 { };\n\tsk: c@460 { };\n\tsl: c@461 { };\n\tsm: c@462 { };\n\tsn: c@463 { };\n\tso: c@464 { };\n\tsp: c@465 { };\n\tsq: c@466 { };\n\tsr: c@467 { };\n\tss: c@468 { };\n\tst: c@469 { };\n\tsu: c@470 { };\n\tsv: c@471 { };\n\tsw: c@472 { };\n\tsx: c@473 { };\n\tsy: c@474 { };\n\tta: c@475 { };\n\ttb: c@476 { };\n\ttc: c@477 { };\n\ttd: c@478 { };\n\tte: c@479 { };\n\ttf: c@480 { };\n\ttg: c@481 { };\n\tth: c@482 { };\n\tti: c@483 { };\n\ttj: c@484 { };\n\ttk: c@485 { };\n\ttl: c@486 { };\n\ttm: c@487 { };\n\ttn: c@488 { };\n\tto: c@489 { };\n\ttp: c@490 { };\n\ttq: c@491 { };\n\ttr: c@492 { };\n\tts: c@493 { };\n\ttt: c@494 { };\n\ttu: c@495 { };\n\ttv: c@496 { };\n\ttw: c@497 { };\n\ttx: c@498 { };\n\tty: c@499 { };\n\tua: c@500 { };\n\tub: c@501 { };\n\tuc: c@502 { };\n\tud: c@503 { };\n\tue: c@504 { };\n\tuf: c@505 { };\n\tug: c@506 { };\n\tuh: c@507 { };\n\tui: c@508 { };\n\tuj: c@509 { };\n\tuk: c@510 { };\n\tul: c@511 { };\n\tum: c@512 { };\n\tun: c@513 { };\n\tuo: c@514 { };\n\tup: c@515 { };\n\tuq: c@516 { };\n\tur: c@517 { };\n\tus: c@518 { };\n\tut: c@519 { };\n\tuu: c@520 { };\n\tuv: c@521 { };\n\tuw: c@522 { };\n\tux: c@523 { };\n\tuy: c@524 { };\n\tva: c@525 { };\n\tvb: c@526 { };\n\tvc: c@527 { };\n\tvd: c@528 { };\n\tve: c@529 { };\n\tvf: c@530 { };\n\tvg: c@531 { };\n\tvh: c@532 { };\n\tvi: c@533 { };\n\tvj: c@534 { };\n\tvk: c@535 { };\n\tvl: c@536 { };\n\tvm: c@537 { };\n\tvn: c@538 { };\n\tvo: c@539 { };\n\tvp: c@540 { };\n\tvq: c@541 { };\n\tvr: c@542 { };\n\tvs: c@543 { };\n\tvt: c@544 { };\n\tvu: c@545 { };\n\tvv: c@546 { };\n\tvw: c@547 { };\n\tvx: c@548 { };\n\tvy: c@549 { };\n\twa: c@550 { };\n\twb: c@551 { };\n\twc: c@552 { };\n\twd: c@553 { };\n\twe: c@554 { };\n\twf: c@555 { };\n\twg: c@556 { };\n\twh: c@557 { };\n\twi: c@558 { };\n\twj: c@559 { };\n\twk: c@560 { };\n\twl: c@561 { };\n\twm: c@562 { };\n\twn: c@563 { };\n\two: c@564 { };\n\twp: c@565 { };\n\twq: c@566 { };\n\twr: c@567 { };\n\tws: c@568 { };\n\twt: c@569 { };\n\twu: c@570 { };\n\twv: c@571 { };\n\tww: c@572 { };\n\twx: c@573 { };\n\twy: c@574 { };\n\txa: c@575 { };\n\txb: c@576 { };\n\txc: c@577 { };\n\txd: c@578 { };\n\txe: c@579 { };\n\txf: c@580 { };\n\txg: c@581 { };\n\txh: c@582 { };\n\txi: c@583 { };\n\txj: c@584 { };\n\txk: c@585 { };\n\txl: c@586 { };\n\txm: c@587 { };\n\txn: c@588 { };\n\txo: c@589 { };\n\txp: c@590 { };\n\txq: c@591 { };\n\txr: c@592 { };\n\txs: c@593 { };\n\txt: c@594 { };\n\txu: c@595 { };\n\txv: c@596 { };\n\txw: c@597 { };\n\txx: c@598 { };\n\txy: c@599 { };\n\tya: c@600 { };\n\tyb: c@601 { };\n\tyc: c@602 { };\n\tyd: c@603 { };\n\tye: c@604 { };\n\tyf: c@605 { };\n\tyg: c@606 { };\n\tyh: c@607 { };\n\tyi: c@608 { };\n\tyj: c@609 { };\n\tyk: c@610 { };\n\tyl: c@611 { };\n\tym: c@612 { };\n\tyn: c@613 { };\n\tyo: c@614 { };\n\typ: c@615 { };\n\tyq: c@616 { };\n\tyr: c@617 { };\n\tys: c@618 { };\n\tyt: c@619 { };\n\tyu: c@620 { };\n\tyv: c@621 { };\n\tyw: c@622 { };\n\tyx: c@623 { };\n\tyy: c@624 { };\n};\n"
  },
  {
    "path": "Tmain/two-inputs-requiring-scope-stack.d/b.dts",
    "content": "/ {\n  b: b@0 { };\n};\n"
  },
  {
    "path": "Tmain/unreadable-input.d/input-1.c",
    "content": "int v1;\n"
  },
  {
    "path": "Tmain/unreadable-input.d/run.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2020 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\nINPUT0=/tmp/u-ctags/input-0.c\n\n. ../utils.sh\n\nif ! type pidof > /dev/null 2>&1; then\n\t# pidof is needed to find auditd.\n\tskip \"pidof command is not available\"\nfi\n\nif ! pidof auditd > /dev/null 2>&1; then\n\t# sudo expects auditd is running.\n\tskip \"auditd is not running\"\nfi\n\nif [ $(id -u) = 0 ] && ! sudo -u '#1' $CTAGS --version > /dev/null; then\n\tskip \"sudo needed in this test case doesn't work expectedly on this platform (execution)\"\nfi\n\nmkdir -p ${INPUT0%/*}\necho \"int v0;\" > ${INPUT0}\nchmod a-r ${INPUT0}\n\nif [ $(id -u) = 0 ] && sudo -u '#1' cat ${INPUT0} > /dev/null 2>&1; then\n\trm ${INPUT0}\n\tskip \"sudo needed in this test case doesn't work expectedly on this platform (file reading)\"\nelif [ $(id -u) != 0 ] && cat ${INPUT0} > /dev/null 2>&1; then\n\trm ${INPUT0}\n\tskip \"chmod a-r doesn't work expectedly on this platform\"\nfi\n\n\n{\n\techo ${INPUT0}\n\techo input-1.c\n} | {\n\tif [ $(id -u) = 0 ]; then\n\t\t# The root can read a file even we did \"chmod a-r\".\n\t\tsudo -u '#1' $CTAGS --quiet --options=NONE -L - -o -\n\telse\n\t\t$CTAGS --quiet --options=NONE -L - -o -\n\tfi\n}\nrm ${INPUT0}\n"
  },
  {
    "path": "Tmain/unreadable-input.d/stderr-expected.txt",
    "content": "ctags: Warning: cannot open \"/tmp/u-ctags/input-0.c\" : Permission denied\n"
  },
  {
    "path": "Tmain/unreadable-input.d/stdout-expected.txt",
    "content": "v1\tinput-1.c\t/^int v1;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/utils.sh",
    "content": "__SKIP__=77\n__INTERNAL_ERROR__=76\n\ninternal_error()\n{\n\techo \"$@\"\n\texit ${__INTERNAL_ERROR__}\n}\n\nskip()\n{\n\techo \"$@\"\n\texit ${__SKIP__}\n}\n\nremove_commit_id()\n{\n    # Remove a commit id embedded in tags file\n    sed -i -e '/!_TAG_PROGRAM_VERSION.*/s#/[^/]*/#//#' $1\n}\n\nfilesize()\n{\n    wc -c < \"$1\"\n}\n\nis_feature_available()\n{\n    local ctags=$1\n\tlocal tmp=$2\n\tlocal o=\"--quiet --options=NONE\"\n\tlocal neg\n\tlocal feat\n\n\tif [ \"${tmp}\" = '!' ]; then\n\t\tneg=1\n\t\tfeat=$3\n\telse\n\t\tfeat=$2\n\tfi\n\n\tif [ \"${neg}\" = 1 ]; then\n\t\tif ${ctags} $o --with-list-header=no --list-features | grep -q \"$feat\"; then\n\t\t\tskip \"feature \\\"$feat\\\" is available in $ctags\"\n\t\tfi\n\telse\n\t\tif ! ${ctags} $o --with-list-header=no --list-features | grep -q \"$feat\"; then\n\t\t\tskip \"feature \\\"$feat\\\" is not available in $ctags\"\n\t\tfi\n\tfi\n}\n\nskip_if_user_has_dot_ctags_d()\n{\n\tif [ -d ~/.ctags.d ]; then\n\t\tskip \"this test case doesn't work well if you have ~/.ctags.d\"\n\tfi\n}\n\nskip_if_no_readtags()\n{\n\tif [ -z \"${1}\" ]; then\n\t\tinternal_error 'skip_if_no_readtags(): missing \"$1\"'\n\tfi\n\n\tif ! [ -x \"${1}\" ]; then\n\t\tskip \"no readtags\"\n\tfi\n}\n\nskip_if_running_on_msys()\n{\n\tif [ -n \"$MSYSTEM\" ]; then\n\t\tskip \"this test case doesn't work well on MSYS2\"\n\tfi\n}\n\nexit_if_win32()\n{\n\tis_feature_available $1 '!' win32\n}\n\nexit_unless_win32()\n{\n\tis_feature_available $1 win32\n}\n\nexit_if_no_case_insensitive_filenames()\n{\n\tis_feature_available $1 case-insensitive-filenames\n}\n\nrun_with_format()\n{\n    echo '#' $*\n    local format=$1\n    shift\n    ${CTAGS} --quiet --options=NONE --output-format=$format \"$@\" -o - input.*\n}\n\nexit_status_for_input_c()\n{\n\tlocal ctags=$1\n\tshift\n\n\tlocal remove_file=$1\n\tshift\n\n\tprintf \"%s => \" \"$(echo \"$*\" | sed -e 's#[^ ][^ ]*/\\([^ ]*\\)#\\1#g')\"\n\t${ctags} --quiet --options=NONE \"$@\" input.c > /dev/null\n\tlocal result_local=$?\n\n\tif [ \"$remove_file\" != \"none\" ]; then\n\t\trm -f \"$remove_file\"\n\tfi\n\n\tif [ \"$result_local\" = 0 ]; then\n\t\techo \"ok\"\n\telse\n\t\techo \"failed\"\n\tfi\n}\n\nget_column_index()\n{\n\tlocal index=0\n\tlocal ctags=$1\n\tlocal option=$2\n\tlocal column=$3\n\n\tfor x in $($ctags  --quiet --options=NONE --with-list-header \"$option\" | sed -ne 's/^#\\(.*\\)$/\\1/p'); do\n\t\tif [ \"$x\" = \"$column\" ]; then\n\t\t\techo $index\n\t\t\treturn 0\n\t\tfi\n\t\tindex=$(expr $index + 1)\n\tdone\n\n\techo -1\n\treturn 1\n}\n\nfilter_by_column_index()\n{\n\tlocal index=$1\n\n\tawk '{print $'$(expr $index + 1)'}'\n}\n\necho2()\n{\n\t# use a external echo command here.\n\t# built-in echo suppresses \\1.\n\t/bin/echo \"$@\"\n\t/bin/echo \"$@\" 1>&2\n}\n\ndireq_maybe ()\n{\n    [ \"$(cd ${1} && pwd)\" = \"$(cd ${2} && pwd)\" ]\n    return $?\n}\n\ncheck_encoding()\n{\n    if iconv -l 2> /dev/null | grep -qi \"$1\"; then\n\t\treturn 0\n\tfi\n\tskip \"iconv doesn't know about the encoding: $1\"\n}\n\njdropver()\n{\n\tsed -e 's/, \"version\": \"[0-9.]*\"//'\n}\n"
  },
  {
    "path": "Tmain/version-option.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/version-option.d/run.sh",
    "content": "# Copyright: 2022 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=\"$1\"\n\n$CTAGS --quiet --options=NONE --version=C\n"
  },
  {
    "path": "Tmain/version-option.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/version-option.d/stdout-expected.txt",
    "content": "parser/C: 2.2\n"
  },
  {
    "path": "Tmain/versioning.d/broken-extra.ctags",
    "content": "--langdef=TEST{version=10.9}\n--_extradef-TEST=fullname,extended full name{version=-4}\n"
  },
  {
    "path": "Tmain/versioning.d/broken-field.ctags",
    "content": "--langdef=TEST{version=10.9}\n--_fielddef-TEST=param,parameters{version=-3}\n"
  },
  {
    "path": "Tmain/versioning.d/broken-kind.ctags",
    "content": "--langdef=TEST{version=10.9}\n--kinddef-TEST=d,def,definitions{version=-1}\n"
  },
  {
    "path": "Tmain/versioning.d/broken-role.ctags",
    "content": "--langdef=TEST{version=10.9}\n--kinddef-TEST=m,macro,macros{version=3}\n--_roledef-TEST.{macro}=expanded,expanded macros{version=-2}\n"
  },
  {
    "path": "Tmain/versioning.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/versioning.d/run.sh",
    "content": "#!/bin/sh\n# Copyright: 2022 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --langdef=TEST'{version=a.9}' --version=TEST\n${CTAGS} --quiet --options=NONE --langdef=TEST'{version=10.b}' --version=TEST\n${CTAGS} --quiet --options=NONE --langdef=TEST'{version=-1.9}' --version=TEST\n${CTAGS} --quiet --options=NONE --langdef=TEST'{version=10.-3}' --version=TEST\n\n${CTAGS} --quiet --options=NONE --options=./test.ctags --version=TEST\n${CTAGS} --quiet --options=NONE --options=./test.ctags --list-kinds-full=TEST\n${CTAGS} --quiet --options=NONE --options=./test.ctags --list-roles=TEST\n${CTAGS} --quiet --options=NONE --options=./test.ctags --list-fields=TEST\n${CTAGS} --quiet --options=NONE --options=./test.ctags --list-extras=TEST\n${CTAGS} --quiet --options=NONE --options=./test.ctags --describe-language=TEST\n\n${CTAGS} --quiet --options=NONE --options=./broken-kind.ctags --_force-quit=0\necho broken kind: $? 1>&2\n${CTAGS} --quiet --options=NONE --options=./broken-role.ctags --_force-quit=0\necho broken role: $? 1>&2\n${CTAGS} --quiet --options=NONE --options=./broken-field.ctags --_force-quit=0\necho broken field: $? 1>&2\n${CTAGS} --quiet --options=NONE --options=./broken-extra.ctags --_force-quit=0\necho broken extra: $? 1>&2\n\n${CTAGS} --quiet --options=NONE --options=./warning-kind.ctags --_force-quit=0\necho warning kind: $? 1>&2\n${CTAGS} --quiet --options=NONE --options=./warning-role.ctags --_force-quit=0\necho warning role: $? 1>&2\n${CTAGS} --quiet --options=NONE --options=./warning-field.ctags --_force-quit=0\necho warning field: $? 1>&2\n${CTAGS} --quiet --options=NONE --options=./warning-extra.ctags --_force-quit=0\necho warning extra: $? 1>&2\n"
  },
  {
    "path": "Tmain/versioning.d/stderr-expected.txt",
    "content": "ctags: Failed to parse the version number (the current part) for language \"TEST\": a.9\nctags: Failed to parse the version number (the age part) for language \"TEST\": 10.b\nctags: Failed to parse the version number (the current part) for language \"TEST\": -1.9\nctags: Failed to parse the version number (the age part) for language \"TEST\": 10.-3\nctags: Failed to parse the version number for kind \"def\": -1\nbroken kind: 1\nctags: Failed to parse the version number for role \"expanded\": -2\nbroken role: 1\nctags: Failed to parse the version number for field \"param\": -3\nbroken field: 1\nctags: Failed to parse the version number for extra \"fullname\": -4\nbroken extra: 1\nctags: Warning: the version number (11) of kind \"d,def\" of language \"TEST\" should be less than or equal to the current number (10) of the language\nwarning kind: 0\nctags: Warning: the version number (11) of role \"expanded\" of language \"TEST\" should be less than or equal to the current number (10) of the language\nwarning role: 0\nctags: Warning: the version number (11) of field \"param\" of language \"TEST\" should be less than or equal to the current number (10) of the language\nwarning field: 0\nctags: Warning: the version number (11) of extra \"fullname\" of language \"TEST\" should be less than or equal to the current number (10) of the language\nwarning extra: 0\n"
  },
  {
    "path": "Tmain/versioning.d/stdout-expected.txt",
    "content": "parser/TEST: 10.9\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nd       def   yes     no      0      NONE     6 definitions\nm       macro yes     no      2      NONE     3 macros\n#KIND(L/N) NAME     ENABLED VER DESCRIPTION\nm/macro    expanded on        4 expanded macros\nm/macro    redef    on        5 redefinied macros\n#LETTER NAME  ENABLED LANGUAGE JSTYPE FIXED OP VER DESCRIPTION\n-       local no      TEST     s--    no    --   6 used in narrow scopes\n-       param no      TEST     s--    no    --   4 parameters\n#LETTER NAME      ENABLED LANGUAGE FIXED VER DESCRIPTION\n-       fullname  no      TEST     no      9 extended full name\n-       shortname no      TEST     no     10 the named only narow scopes\nAbout TEST language\n=======================================================\nenabled: yes\nversion: 10.9\n\nMappings/rexprs\n-------------------------------------------------------\n\n\nMappings/patterns\n-------------------------------------------------------\n MYTEST\n\nMappings/extensions\n-------------------------------------------------------\n *.mytest\n\nAliases\n-------------------------------------------------------\n#ALIAS\nmy-test\n\nKinds\n-------------------------------------------------------\n#LETTER NAME  ENABLED REFONLY NROLES MASTER VER DESCRIPTION\nd       def   yes     no      0      NONE     6 definitions\nm       macro yes     no      2      NONE     3 macros\n\nRoles\n-------------------------------------------------------\n#KIND(L/N) NAME     ENABLED VER DESCRIPTION\nm/macro    expanded on        4 expanded macros\nm/macro    redef    on        5 redefinied macros\n\nFields\n-------------------------------------------------------\n#LETTER NAME  ENABLED LANGUAGE JSTYPE FIXED OP VER DESCRIPTION\n-       local no      TEST     s--    no    --   6 used in narrow scopes\n-       param no      TEST     s--    no    --   4 parameters\n\nExtras\n-------------------------------------------------------\n#LETTER NAME      ENABLED LANGUAGE FIXED VER DESCRIPTION\n-       fullname  no      TEST     no      9 extended full name\n-       shortname no      TEST     no     10 the named only narow scopes\n\nParameters\n-------------------------------------------------------\n#NAME  DESCRIPTION\ndebug  enable the debug features\n\nSub parsers stacked on this parser\n-------------------------------------------------------\n#NAME    BASEPARSER DIRECTIONS\nEXAMINE  TEST       base => sub {shared}\n\nImplementation specific status\n-------------------------------------------------------\nallow null tags: no\n"
  },
  {
    "path": "Tmain/versioning.d/test.ctags",
    "content": "--langdef=TEST{version=10.9}\n--map-TEST=+.mytest\n--map-TEST=+(MYTEST)\n--alias-TEST=+my-test\n\n--kinddef-TEST=d,def,definitions{version=6}\n--kinddef-TEST=m,macro,macros{version=3}\n--_roledef-TEST.{macro}=expanded,expanded macros{version=4}\n--_roledef-TEST.{macro}=redef,redefinied macros{version=5}\n\n--_fielddef-TEST=param,parameters{version=4}\n--_fielddef-TEST=local,used in narrow scopes{version=6}\n\n--_extradef-TEST=fullname,extended full name{version=9}\n--_extradef-TEST=shortname,the named only narow scopes{version=10}\n\n\n--_paramdef-TEST=debug,enable the debug features\n\n--langdef=EXAMINE{base=TEST}{shared}\n"
  },
  {
    "path": "Tmain/versioning.d/warning-extra.ctags",
    "content": "--langdef=TEST{version=10.9}\n--_extradef-TEST=fullname,extended full name{version=11}\n"
  },
  {
    "path": "Tmain/versioning.d/warning-field.ctags",
    "content": "--langdef=TEST{version=10.9}\n--_fielddef-TEST=param,parameters{version=11}\n"
  },
  {
    "path": "Tmain/versioning.d/warning-kind.ctags",
    "content": "--langdef=TEST{version=10.9}\n--kinddef-TEST=d,def,definitions{version=11}\n"
  },
  {
    "path": "Tmain/versioning.d/warning-role.ctags",
    "content": "--langdef=TEST{version=10.9}\n--kinddef-TEST=m,macro,macros{version=3}\n--_roledef-TEST.{macro}=expanded,expanded macros{version=11}\n"
  },
  {
    "path": "Tmain/w32-slash-in-exclude-option.d/input.d/capture_me/input.c",
    "content": "int capture_me_1(void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Tmain/w32-slash-in-exclude-option.d/input.d/dont_capture_me/input.c",
    "content": "int dont_capture_me(void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Tmain/w32-slash-in-exclude-option.d/input.d/input.c",
    "content": "int capture_me_0(void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Tmain/w32-slash-in-exclude-option.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nexit_unless_win32 \"$CTAGS\"\n\nMSYS2_ARG_CONV_EXCL=dont_capture_me/input.c ${CTAGS} --quiet --options=NONE -R -o - \\\n\t\t --exclude='input.d/dont_capture_me/input.c' input.d\n"
  },
  {
    "path": "Tmain/w32-slash-in-exclude-option.d/stdout-expected.txt",
    "content": "capture_me_0\tinput.d/input.c\t/^int capture_me_0(void)$/;\"\tf\ttyperef:typename:int\ncapture_me_1\tinput.d/capture_me/input.c\t/^int capture_me_1(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Tmain/warn-garbage-on-ostack.d/exit-expected.txt",
    "content": "0\n"
  },
  {
    "path": "Tmain/warn-garbage-on-ostack.d/garbage.ctags",
    "content": "--langdef=Garbage\n--map-Garbage=.garbage\n\n--regex-Garbage=/a//{{\n  /garbage0\n  (garbage1)\n}}\n"
  },
  {
    "path": "Tmain/warn-garbage-on-ostack.d/input.garbage",
    "content": "a\n"
  },
  {
    "path": "Tmain/warn-garbage-on-ostack.d/input.kconfig",
    "content": "config BCH_CONST_M\n"
  },
  {
    "path": "Tmain/warn-garbage-on-ostack.d/run.sh",
    "content": "# Copyright: 2025 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n$CTAGS --quiet --options=NONE --options=./garbage.ctags -o - input.garbage\n\n$CTAGS --quiet --options=NONE --map-Kconfig=+.kconfig -o - input.kconfig > /dev/null\n"
  },
  {
    "path": "Tmain/warn-garbage-on-ostack.d/stderr-expected.txt",
    "content": "ctags: Warning: [Garbage] 2 objects are left on the operand stack: input.garbage\n"
  },
  {
    "path": "Tmain/warn-garbage-on-ostack.d/stdout-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/warn-reusing-kind-letter.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE \\\n\t --langdef=X \\\n\t --regex-X='/./\\0/a,anyobject/' \\\n\t --regex-X='/./\\0/a,anyitem/' \\\n\t --langdef=Y \\\n\t --regex-Y='/./\\0/b,any' \\\n\t --regex-Y='/./\\0/b,any' \\\n\t --_force-quit=0 2>&1 | sed -e 's/.*ctags\\(.exe\\)\\{0,1\\}: //'\n"
  },
  {
    "path": "Tmain/warn-reusing-kind-letter.d/stdout-expected.txt",
    "content": "Warning: Don't reuse the kind letter `a' in a language X (old: \"anyobject\", new: \"anyitem\")\n"
  },
  {
    "path": "Tmain/wildcard-in-lang-of-fields-option.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE \\\n\t\t -o - --fields-all=+{signature}-{typeref} --list-fields | grep 'signature\\|typeref'\n"
  },
  {
    "path": "Tmain/wildcard-in-lang-of-fields-option.d/stdout-expected.txt",
    "content": "S       signature      yes     NONE             s--    no    rw   0 Signature of routine (e.g. prototype or parameter list)\nt       typeref        no      NONE             s--    no    rw   0 Type and name of a variable or typedef\n"
  },
  {
    "path": "Tmain/wrong-parser-name-in-field.d/exit-expected.txt",
    "content": "1\n"
  },
  {
    "path": "Tmain/wrong-parser-name-in-field.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --fields-Cxx=+{end} --list-fields=Cxx\nexit $?\n"
  },
  {
    "path": "Tmain/wrong-parser-name-in-field.d/stderr-expected.txt",
    "content": "ctags: Warning: Unknown language: Cxx (ignoring \"--fields-Cxx\")\nctags: Unknown language \"Cxx\" in \"list-fields\" option\n"
  },
  {
    "path": "Tmain/xref-output-common-fields.d/input.py",
    "content": "class Foo:\n    def doIt():\n        pass\n"
  },
  {
    "path": "Tmain/xref-output-common-fields.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n${CTAGS} --quiet --options=NONE --list-fields | while read K REST; do\n    if ! [ \"$K\" = '-' ]; then\n\techo \"field: $K\"\n\t${CTAGS} --quiet --options=NONE -x --_xformat=\"output: %N %${K}\" -o - input.py\n\techo \"status: $?\"\n\techo\n    fi\ndone\n"
  },
  {
    "path": "Tmain/xref-output-common-fields.d/stdout-expected.txt",
    "content": "field: #LETTER\nstatus: 1\n\nfield: N\noutput: Foo Foo\noutput: doIt doIt\nstatus: 0\n\nfield: F\noutput: Foo input.py\noutput: doIt input.py\nstatus: 0\n\nfield: P\noutput: Foo /^class Foo:$/\noutput: doIt /^    def doIt():$/\nstatus: 0\n\nfield: C\noutput: Foo class Foo:\noutput: doIt def doIt():\nstatus: 0\n\nfield: E\noutput: Foo \noutput: doIt \nstatus: 0\n\nfield: K\noutput: Foo class\noutput: doIt member\nstatus: 0\n\nfield: R\noutput: Foo D\noutput: doIt D\nstatus: 0\n\nfield: S\noutput: Foo -\noutput: doIt ()\nstatus: 0\n\nfield: T\noutput: Foo 0\noutput: doIt 0\nstatus: 0\n\nfield: Z\noutput: Foo \noutput: doIt Foo\nstatus: 0\n\nfield: a\noutput: Foo public\noutput: doIt public\nstatus: 0\n\nfield: e\noutput: Foo 3\noutput: doIt 3\nstatus: 0\n\nfield: f\noutput: Foo -\noutput: doIt -\nstatus: 0\n\nfield: i\noutput: Foo \noutput: doIt -\nstatus: 0\n\nfield: k\noutput: Foo c\noutput: doIt m\nstatus: 0\n\nfield: l\noutput: Foo Python\noutput: doIt Python\nstatus: 0\n\nfield: m\noutput: Foo -\noutput: doIt -\nstatus: 0\n\nfield: n\noutput: Foo 1\noutput: doIt 2\nstatus: 0\n\nfield: o\noutput: Foo \noutput: doIt \nstatus: 0\n\nfield: p\noutput: Foo \noutput: doIt class\nstatus: 0\n\nfield: r\noutput: Foo def\noutput: doIt def\nstatus: 0\n\nfield: s\noutput: Foo \noutput: doIt Foo\nstatus: 0\n\nfield: t\noutput: Foo -\noutput: doIt -\nstatus: 0\n\nfield: x\noutput: Foo \noutput: doIt \nstatus: 0\n\nfield: z\noutput: Foo class\noutput: doIt member\nstatus: 0\n\n"
  },
  {
    "path": "Tmain/xref-output-formatting-parser-specific-field.d/input.rst",
    "content": "Top level\n==============\n\nsubsection\n--------------\n"
  },
  {
    "path": "Tmain/xref-output-formatting-parser-specific-field.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho \"#\"\necho \"# JUST LONG NAME\"\necho \"#\"\n${CTAGS} --quiet --options=NONE \\\n\t -x \\\n\t --_xformat=\"%10N %10{sectionMarker}\" \\\n\t input.rst\n\necho \"#\"\necho \"# LANG, LONG NAME\"\necho \"#\"\n${CTAGS} --quiet --options=NONE \\\n\t -x \\\n\t --_xformat=\"%10N %10{reStructuredText.sectionMarker}\" \\\n\t input.rst\n\necho \"#\"\necho \"# WILDCARD, LONG NAME\"\necho \"#\"\n${CTAGS} --quiet --options=NONE \\\n\t -x \\\n\t --_xformat=\"%10N %10{*.sectionMarker}\" \\\n\t input.rst\n\necho \"#\"\necho \"# WRONG LANGUAGE\"\necho \"#\"\n${CTAGS} --quiet --options=NONE \\\n\t -x \\\n\t --_xformat=\"%10N %10{NOSUCHLANG.sectionMarker}\" \\\n\t input.rst\n\necho \"#\"\necho \"# WRONG FIELD\"\necho \"#\"\n${CTAGS} --quiet --options=NONE \\\n\t -x \\\n\t --_xformat=\"%10N %10{NOSUCHFIELD}\" \\\n\t input.rst\n\necho \"#\"\necho \"# ENABLING COMMON FIELD BY SPECIFYING WILDCARD\"\necho \"#\"\n${CTAGS} --quiet --options=NONE \\\n\t -x \\\n\t --_xformat=\"%10N %10{*.language}\" \\\n\t input.rst\n\necho \"#\"\necho \"# LIST: ENABLING COMMON FIELD BY SPECIFYING WILDCARD\"\necho \"#\"\n${CTAGS} --quiet --options=NONE \\\n\t -x \\\n\t --_xformat=\"%10N %10{*.language}\" \\\n\t --list-fields | grep -v NSIS | grep language\n\n\nexit $?\n"
  },
  {
    "path": "Tmain/xref-output-formatting-parser-specific-field.d/stderr-expected.txt",
    "content": "ctags: No such field name: sectionMarker\nctags: No suitable parser for field name: NOSUCHLANG.sectionMarker\nctags: No such field name: NOSUCHFIELD\n"
  },
  {
    "path": "Tmain/xref-output-formatting-parser-specific-field.d/stdout-expected.txt",
    "content": "#\n# JUST LONG NAME\n#\n#\n# LANG, LONG NAME\n#\n Top level          =\nsubsection          -\n#\n# WILDCARD, LONG NAME\n#\n Top level          =\nsubsection          -\n#\n# WRONG LANGUAGE\n#\n#\n# WRONG FIELD\n#\n#\n# ENABLING COMMON FIELD BY SPECIFYING WILDCARD\n#\n Top level ReStructuredText\nsubsection ReStructuredText\n#\n# LIST: ENABLING COMMON FIELD BY SPECIFYING WILDCARD\n#\nl       language       yes     NONE             s--    no    r-   0 Language of input file containing tag\n-       target         yes     Thrift           s--    no    --   0 the target language specified at \"namespace\"\n"
  },
  {
    "path": "Tmain/xref-output-ptag-in-list-extras.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\nO=/tmp/ctags-tmain-$$\n\necho '#' tags regular file\n\"${CTAGS}\" --options=NONE --output-format=u-ctags -o $O --list-extras | grep pseudo\n\necho '#' tags -\n\"${CTAGS}\" --options=NONE --output-format=u-ctags -o - --list-extras | grep pseudo\n\necho '#' tags NOTHING\n\"${CTAGS}\" --options=NONE --output-format=u-ctags --list-extras | grep pseudo\n\necho '#' xref regular file\n\"${CTAGS}\" --options=NONE --output-format=xref -o $O --list-extras | grep pseudo\n\necho '#' xref -\n\"${CTAGS}\" --options=NONE --output-format=xref -o - --list-extras | grep pseudo\n\necho '#' xref NOTHING\n\"${CTAGS}\" --options=NONE --output-format=xref --list-extras | grep pseudo\n\nrm -f $O\n"
  },
  {
    "path": "Tmain/xref-output-ptag-in-list-extras.d/stdout-expected.txt",
    "content": "# tags regular file\np       pseudo              yes     NONE        no      0 Include pseudo tags\n# tags -\np       pseudo              no      NONE        no      0 Include pseudo tags\n# tags NOTHING\np       pseudo              yes     NONE        no      0 Include pseudo tags\n# xref regular file\np       pseudo              no      NONE        no      0 Include pseudo tags\n# xref -\np       pseudo              no      NONE        no      0 Include pseudo tags\n# xref NOTHING\np       pseudo              no      NONE        no      0 Include pseudo tags\n"
  },
  {
    "path": "Tmain/xref-output-to-file.d/input.c",
    "content": "#include <stdio.h>\n\nstatic int foo (void)\n{\n  return 1;\n}\n\nint\nmain(void)\n{\n  return foo();\n}\n"
  },
  {
    "path": "Tmain/xref-output-to-file.d/run.sh",
    "content": "# Copyright: 2017 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\n. ../utils.sh\n\nO=/tmp/ctags-tmain-$$.xref\n$CTAGS --quiet --options=NONE --output-format=xref -f ${O} input.c > /dev/null && cat ${O}\ns=$?\n\nrm -f ${O}\n\nexit $s\n"
  },
  {
    "path": "Tmain/xref-output-to-file.d/stdout-expected.txt",
    "content": "foo              function      3 input.c          static int foo (void)\nmain             function      9 input.c          main(void)\n"
  },
  {
    "path": "Tmain/xref-output-typed-fields.d/input.c",
    "content": "static int local;\nint global;\n"
  },
  {
    "path": "Tmain/xref-output-typed-fields.d/input.ctst",
    "content": "f\n"
  },
  {
    "path": "Tmain/xref-output-typed-fields.d/input.rst",
    "content": "==============================================\nTITLE\n==============================================\n\nsection\n.......\n"
  },
  {
    "path": "Tmain/xref-output-typed-fields.d/run.sh",
    "content": "# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\nCTAGS=$1\n\necho '# input.ctst'\n${CTAGS} --quiet --options=NONE -o - \\\n\t\t --output-format=xref --_xformat='%{name} -> b=%{CTagsSelfTest.bField},sb=%{CTagsSelfTest.sbField},s=%{CTagsSelfTest.sField},i=%{CTagsSelfTest.iField}' \\\n\t\t --language-force=CTagsSelfTest input.ctst\n\necho '# input.rst'\n${CTAGS} --quiet --options=NONE -o - \\\n\t\t --output-format=xref --_xformat='%{name} -> %{RestructuredText.overline}' \\\n\t\t input.rst\n\necho '# input.c'\n${CTAGS} --quiet --options=NONE -o - \\\n\t\t --output-format=xref --_xformat='%{name} -> %{file}' \\\n\t\t input.c\n"
  },
  {
    "path": "Tmain/xref-output-typed-fields.d/stderr-expected.txt",
    "content": ""
  },
  {
    "path": "Tmain/xref-output-typed-fields.d/stdout-expected.txt",
    "content": "# input.ctst\natag -> b=-,sb=,s=,i=\nbtag -> b=bField,sb=,s=,i=\nctag -> b=bField,sb=,s=,i=\ndtag -> b=-,sb=val,s=,i=\netag -> b=-,sb=-,s=,i=\nftag -> b=-,sb=,s=val,i=\ngtag -> b=-,sb=,s=,i=\nhtag -> b=-,sb=,s=,i=23\nitag -> b=-,sb=,s=,i=-3\njtag -> b=-,sb=,s=,i=1\nktag -> b=-,sb=,s=,i=0\n# input.rst\nTITLE -> overline\nsection -> -\n# input.c\nglobal -> -\nlocal -> file\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-528-sml.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-528-sml.d/input.sml",
    "content": "and"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-529-bas.d/input.bas",
    "content": ":\t:\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-530-css.d/input.css",
    "content": "0[\"\t\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-531-make.d/input.mk",
    "content": "define\t0\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-532-vim.d/input.vim",
    "content": "vn\t0\t\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-536-flex.d/input.as",
    "content": "0'\t'={0:0\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-537-beta.d/input.bet",
    "content": "--0\t0:--\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-538-sql.d/input.sql",
    "content": "cursor '\t\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-539-js.d/input.js",
    "content": "let`\t\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-540-fortran.d/input.f",
    "content": "type;generic\"\t\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-541-json.d/input.json",
    "content": "{\"\\\t\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-542-vhdl.d/input.vhdl",
    "content": "constant\"\t\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-543-eiffel.d/input.e",
    "content": "class feature d alias\"\t\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-625-r.d/input.r",
    "content": "0<-\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-627-perl.d/input.pl",
    "content": "use constant{,=>\n\n"
  },
  {
    "path": "Units/afl-fuzz.r/github-issue-628-vera.d/input.vr",
    "content": "typedef interface c e;\n"
  },
  {
    "path": "Units/csharp-review-needed.r/array_ref_and_out.cs.t/expected.tags",
    "content": "FillArray\tinput.cs\t/^   static public void FillArray(out int[] myArray) $/;\"\tm\tclass:TestOut\nMain\tinput.cs\t/^   static public void Main() $/;\"\tm\tclass:TestOut\nMyMethod\tinput.cs\t/^public static void MyMethod(out int[] arr) $/;\"\tm\nMyMethod\tinput.cs\t/^public static void MyMethod(ref int[] arr) $/;\"\tm\nTestOut\tinput.cs\t/^class TestOut $/;\"\tc\n"
  },
  {
    "path": "Units/csharp-review-needed.r/array_ref_and_out.cs.t/input.cs",
    "content": "// Programmer's Reference: Passing Array Using ref and out\npublic static void MyMethod(out int[] arr) \n{\n   arr = new int[10];   // definite assignment of arr\n}\n\npublic static void MyMethod(ref int[] arr) \n{\n   arr = new int[10];   // arr initialized to a different array\n}\n\nusing System; \nclass TestOut \n{\n   static public void FillArray(out int[] myArray) \n   {\n      // Initialize the array:\n      myArray = new int[5] {1, 2, 3, 4, 5};\n   }\n\n   static public void Main() \n   {\n      int[] myArray; // Initialization is not required\n\n      // Pass the array to the callee using out:\n      FillArray(out myArray);\n\n      // Display the array elements:\n      Console.WriteLine(\"Array elements are:\");\n      for (int i=0; i < myArray.Length; i++)\n         Console.WriteLine(myArray[i]);\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/attributes.cs.t/expected.tags",
    "content": "Author\tinput.cs\t/^   public Author(string name) { this.name = name; version = 1.0; }$/;\"\tm\tclass:Author\nAuthor\tinput.cs\t/^public class Author : Attribute$/;\"\tc\nMyDllimportClass\tinput.cs\t/^[DllImport] public class MyDllimportClass {}$/;\"\tc\nTraceMethod\tinput.cs\t/^[Conditional(\"DEBUG\"), Conditional(\"TEST1\")] void TraceMethod() {}$/;\"\tm\nname\tinput.cs\t/^   string name;$/;\"\tf\tclass:Author\tfile:\nversion\tinput.cs\t/^   public double version;$/;\"\tf\tclass:Author\n"
  },
  {
    "path": "Units/csharp-review-needed.r/attributes.cs.t/input.cs",
    "content": "[DllImport] public class MyDllimportClass {}\n\n[DllImport(\"user32.dll\", SetLastError=false, ExactSpelling=false)]\n[DllImport(\"user32.dll\", ExactSpelling=false, SetLastError=false)]\n[DllImport(\"user32.dll\")]\n\n[Conditional(\"DEBUG\"), Conditional(\"TEST1\")] void TraceMethod() {}\n\nusing System;\n[AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct)]\npublic class Author : Attribute\n{\n   public Author(string name) { this.name = name; version = 1.0; }\n   public double version;\n   string name;\n}\n\n[AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct,\n   AllowMultiple=true)] // multiuse attribute\npublic class Author : Attribute\n{\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug1515910.cs.t/expected.tags",
    "content": "C\tinput.cs\t/^public class C {$/;\"\tc\nEnum1\tinput.cs\t/^enum Enum1 : byte {$/;\"\tg\nMyGenericClass1\tinput.cs\t/^public class MyGenericClass1<T> { }$/;\"\tc\nValue1\tinput.cs\t/^\tValue1, Values$/;\"\te\tenum:Enum1\tfile:\nValues\tinput.cs\t/^\tValue1, Values$/;\"\te\tenum:Enum1\tfile:\nint1\tinput.cs\t/^    private int int1 = 123;$/;\"\tf\tclass:C\tfile:\nstr1\tinput.cs\t/^    private string str1 = @\"abc\\\\\";$/;\"\tf\tclass:C\tfile:\nstr2\tinput.cs\t/^    private string str2 = @\"abc\\\\\";$/;\"\tf\tclass:C\tfile:\nstr3\tinput.cs\t/^    private string str3 = \"abc\";$/;\"\tf\tclass:C\tfile:\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug1515910.cs.t/input.cs",
    "content": "// Simple generic classes.\npublic class MyGenericClass1<T> { }\n\n// Derived enums.\nenum Enum1 : byte {\n\tValue1, Values\n}\n\n// Verbatim strings.\npublic class C {\n    private string str1 = @\"abc\\\";\n    private int int1 = 123;\n    private string str2 = @\"abc\\\";\n    private string str3 = \"abc\";\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug1611054.cs.t/expected.tags",
    "content": "C\tinput.cs\t/^class C {$/;\"\tc\na\tinput.cs\t/^\tpublic String a() {$/;\"\tm\tclass:C\nb\tinput.cs\t/^\tpublic void b() {$/;\"\tm\tclass:C\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug1611054.cs.t/input.cs",
    "content": "class C {\n\tpublic String a() {\n\t\treturn @\"c:\\\";\n\t}\n\t// this tag is missing in ctags 5.6\n\tpublic void b() {\n\t}\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug1800065.cs.t/expected.tags",
    "content": "C\tinput.cs\t/^public class C {$/;\"\tc\ntitle\tinput.cs\t/^ private string title;$/;\"\tf\tclass:C\tfile:\nwindow\tinput.cs\t/^ private Gtk.Window window;$/;\"\tf\tclass:C\tfile:\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug1800065.cs.t/input.cs",
    "content": "using Gtk;\npublic class C {\n private Gtk.Window window;\n private string title;\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug1830343.cs.t/expected.tags",
    "content": "ForEachTest\tinput.cs\t/^class ForEachTest {$/;\"\tc\nMain\tinput.cs\t/^\tstatic void Main(string[] args) {$/;\"\tm\tclass:ForEachTest\tfile:\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug1830343.cs.t/input.cs",
    "content": "class ForEachTest {\n\tstatic void Main(string[] args) {\n\t\tint[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };\n\t\tforeach (int i in fibarray) {\n\t\t\tSystem.Console.WriteLine(i);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug1830344.cs.t/expected.tags",
    "content": "C\tinput.cs\t/^public class C {$/;\"\tc\nm\tinput.cs\t/^\tpublic void m() {$/;\"\tm\tclass:C\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug1830344.cs.t/input.cs",
    "content": "public class C {\n\tpublic void m() {\n\t\tbool flagCheck = true;\n\t\tif (flagCheck == true) {\n\t\t\tConsole.WriteLine(\"true\");\n\t\t} else {\n\t\t\tConsole.WriteLine(\"false\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug2411878.cs.t/expected.tags",
    "content": "C\tinput.cs\t/^public class C {$/;\"\tc\nm_name\tinput.cs\t/^  private System.String m_name;$/;\"\tf\tclass:C\tfile:\n"
  },
  {
    "path": "Units/csharp-review-needed.r/bug2411878.cs.t/input.cs",
    "content": "public class C {\n  private System.String m_name;\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/events.cs.t/expected.tags",
    "content": "Add\tinput.cs\t/^      public override int Add(object value) $/;\"\tm\tclass:MyCollections.ListWithChangedEvent\nChanged\tinput.cs\t/^      public event ChangedEventHandler Changed;$/;\"\tE\tclass:MyCollections.ListWithChangedEvent\nChanged\tinput.cs\t/^      public event EventHandler Changed;$/;\"\tE\tclass:MyCollections.ListWithChangedEvent\nChangedEventHandler\tinput.cs\t/^   public delegate void ChangedEventHandler(object sender, EventArgs e);$/;\"\tm\tnamespace:MyCollections\nClear\tinput.cs\t/^      public override void Clear() $/;\"\tm\tclass:MyCollections.ListWithChangedEvent\nDetach\tinput.cs\t/^      public void Detach() $/;\"\tm\tclass:TestEvents.EventListener\nEventListener\tinput.cs\t/^      public EventListener(ListWithChangedEvent list) $/;\"\tm\tclass:TestEvents.EventListener\nEventListener\tinput.cs\t/^   class EventListener $/;\"\tc\tnamespace:TestEvents\nList\tinput.cs\t/^      private ListWithChangedEvent List;$/;\"\tf\tclass:TestEvents.EventListener\tfile:\nListChanged\tinput.cs\t/^      private void ListChanged(object sender, EventArgs e) $/;\"\tm\tclass:TestEvents.EventListener\tfile:\nListWithChangedEvent\tinput.cs\t/^   public class ListWithChangedEvent: ArrayList $/;\"\tc\tnamespace:MyCollections\nMain\tinput.cs\t/^      public static void Main() $/;\"\tm\tclass:TestEvents.Test\nMyCollections\tinput.cs\t/^namespace MyCollections $/;\"\tn\nOnChanged\tinput.cs\t/^      protected virtual void OnChanged(EventArgs e) $/;\"\tm\tclass:MyCollections.ListWithChangedEvent\nTest\tinput.cs\t/^   class Test $/;\"\tc\tnamespace:TestEvents\nTestEvents\tinput.cs\t/^namespace TestEvents $/;\"\tn\n"
  },
  {
    "path": "Units/csharp-review-needed.r/events.cs.t/input.cs",
    "content": "// events1.cs\nusing System;\nnamespace MyCollections \n{\n   using System.Collections;\n\n   // A delegate type for hooking up change notifications.\n   public delegate void ChangedEventHandler(object sender, EventArgs e);\n\n   // A class that works just like ArrayList, but sends event\n   // notifications whenever the list changes.\n   public class ListWithChangedEvent: ArrayList \n   {\n      // An event that clients can use to be notified whenever the\n      // elements of the list change.\n      public event ChangedEventHandler Changed;\n\n      // Invoke the Changed event; called whenever list changes\n      protected virtual void OnChanged(EventArgs e) \n      {\n         if (Changed != null)\n            Changed(this, e);\n      }\n\n      // Override some of the methods that can change the list;\n      // invoke event after each\n      public override int Add(object value) \n      {\n         int i = base.Add(value);\n         OnChanged(EventArgs.Empty);\n         return i;\n      }\n\n      public override void Clear() \n      {\n         base.Clear();\n         OnChanged(EventArgs.Empty);\n      }\n\n      public override object this[int index] \n      {\n         set \n         {\n            base[index] = value;\n            OnChanged(EventArgs.Empty);\n         }\n      }\n   }\n}\n\nnamespace TestEvents \n{\n   using MyCollections;\n\n   class EventListener \n   {\n      private ListWithChangedEvent List;\n\n      public EventListener(ListWithChangedEvent list) \n      {\n         List = list;\n         // Add \"ListChanged\" to the Changed event on \"List\".\n         List.Changed += new ChangedEventHandler(ListChanged);\n      }\n\n      // This will be called whenever the list changes.\n      private void ListChanged(object sender, EventArgs e) \n      {\n         Console.WriteLine(\"This is called when the event fires.\");\n      }\n\n      public void Detach() \n      {\n         // Detach the event and delete the list\n         List.Changed -= new ChangedEventHandler(ListChanged);\n         List = null;\n      }\n   }\n\n   class Test \n   {\n      // Test the ListWithChangedEvent class.\n      public static void Main() \n      {\n      // Create a new list.\n      ListWithChangedEvent list = new ListWithChangedEvent();\n\n      // Create a class that listens to the list's change event.\n      EventListener listener = new EventListener(list);\n\n      // Add and remove items from the list.\n      list.Add(\"item 1\");\n      list.Clear();\n      listener.Detach();\n      }\n   }\n}\n\n// events2.cs\nusing System;\nnamespace MyCollections \n{\n   using System.Collections;\n\n   // A class that works just like ArrayList, but sends event\n   // notifications whenever the list changes:\n   public class ListWithChangedEvent: ArrayList \n   {\n      // An event that clients can use to be notified whenever the\n      // elements of the list change:\n      public event EventHandler Changed;\n\n      // Invoke the Changed event; called whenever list changes:\n      protected virtual void OnChanged(EventArgs e) \n      {\n         if (Changed != null)\n            Changed(this,e);\n      }\n\n      // Override some of the methods that can change the list;\n      // invoke event after each:\n      public override int Add(object value) \n      {\n         int i = base.Add(value);\n         OnChanged(EventArgs.Empty);\n         return i;\n      }\n\n      public override void Clear() \n      {\n         base.Clear();\n         OnChanged(EventArgs.Empty);\n      }\n\n      public override object this[int index] \n      {\n         set \n         {\n            base[index] = value;\n            OnChanged(EventArgs.Empty);\n         }\n      }\n   }\n}\n\nnamespace TestEvents \n{\n   using MyCollections;\n\n   class EventListener \n   {\n      private ListWithChangedEvent List;\n\n      public EventListener(ListWithChangedEvent list) \n      {\n         List = list;\n         // Add \"ListChanged\" to the Changed event on \"List\":\n         List.Changed += new EventHandler(ListChanged);\n      }\n\n      // This will be called whenever the list changes:\n      private void ListChanged(object sender, EventArgs e) \n      {\n         Console.WriteLine(\"This is called when the event fires.\");\n      }\n\n      public void Detach() \n      {\n         // Detach the event and delete the list:\n         List.Changed -= new EventHandler(ListChanged);\n         List = null;\n      }\n   }\n\n   class Test \n   {\n      // Test the ListWithChangedEvent class:\n      public static void Main() \n      {\n      // Create a new list:\n      ListWithChangedEvent list = new ListWithChangedEvent();\n\n      // Create a class that listens to the list's change event:\n      EventListener listener = new EventListener(list);\n\n      // Add and remove items from the list:\n      list.Add(\"item 1\");\n      list.Clear();\n      listener.Detach();\n      }\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/general.cs.t/expected.tags",
    "content": "C1\tinput.cs\t/^   class C1      \\/\\/ N1.C1$/;\"\tc\tnamespace:N1\nC2\tinput.cs\t/^      class C2   \\/\\/ N1.C1.C2$/;\"\tc\tclass:N1.C1\nC2\tinput.cs\t/^      class C2   \\/\\/ N1.N2.C2$/;\"\tc\tnamespace:N1.N2\nIMyInterface\tinput.cs\t/^   interface IMyInterface $/;\"\ti\tnamespace:MyNamespace1\nMain\tinput.cs\t/^      public static void Main(string[] args) $/;\"\tm\tclass:MyNamespace1.MyClass2\nMyClass1\tinput.cs\t/^   class MyClass1 $/;\"\tc\tnamespace:MyNamespace1\nMyClass2\tinput.cs\t/^   class MyClass2 $/;\"\tc\tnamespace:MyNamespace1\nMyDelegate\tinput.cs\t/^   delegate int MyDelegate();$/;\"\tm\tnamespace:MyNamespace1\nMyEnum\tinput.cs\t/^   enum MyEnum $/;\"\tg\tnamespace:MyNamespace1\nMyNamespace1\tinput.cs\t/^namespace MyNamespace1 $/;\"\tn\nMyNamespace2\tinput.cs\t/^   namespace MyNamespace2 $/;\"\tn\tnamespace:MyNamespace1\nMyStruct\tinput.cs\t/^   struct MyStruct $/;\"\ts\tnamespace:MyNamespace1\nN1\tinput.cs\t/^namespace N1     \\/\\/ N1$/;\"\tn\nN2\tinput.cs\t/^   namespace N2  \\/\\/ N1.N2$/;\"\tn\tnamespace:N1\n"
  },
  {
    "path": "Units/csharp-review-needed.r/general.cs.t/input.cs",
    "content": "// General Structure of a C# Program\n// A skeleton of a C# program \nusing System;\nnamespace MyNamespace1 \n{\n   class MyClass1 \n   {\n   }\n   struct MyStruct \n   {\n   }\n   interface IMyInterface \n   {\n   }\n   delegate int MyDelegate();\n   enum MyEnum \n   {\n   } \n   namespace MyNamespace2 \n   {\n   }\n   class MyClass2 \n   {\n      public static void Main(string[] args) \n      {\n      }\n   }\n}\n\n\n// Using Fully Qualified Names\nnamespace N1     // N1\n{\n   class C1      // N1.C1\n   {\n      class C2   // N1.C1.C2\n      {\n      }\n   }\n   namespace N2  // N1.N2\n   {\n      class C2   // N1.N2.C2\n      {\n      }\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/indexer.cs.t/expected.tags",
    "content": "IndexerClass\tinput.cs\t/^class IndexerClass $/;\"\tc\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^public class MainClass $/;\"\tc\nmyArray\tinput.cs\t/^   private int [] myArray = new int[100]; $/;\"\tf\tclass:IndexerClass\tfile:\n"
  },
  {
    "path": "Units/csharp-review-needed.r/indexer.cs.t/input.cs",
    "content": "// cs_keyword_indexers.cs\nusing System;\nclass IndexerClass \n{\n   private int [] myArray = new int[100]; \n   public int this [int index]   // indexer declaration\n   {\n      get \n      {\n         // Check the index limits\n         if (index < 0 || index >= 100)\n            return 0;\n         else\n            return myArray[index];\n      }\n      set \n      {\n         if (!(index < 0 || index >= 100))\n            myArray[index] = value;\n      }\n   }\n}\n\npublic class MainClass \n{\n   public static void Main() \n   {\n      IndexerClass b = new IndexerClass();\n      // call the indexer to initialize the elements #3 and #5:\n      b[3] = 256;\n      b[5] = 1024;\n      for (int i=0; i<=10; i++) \n      {\n         Console.WriteLine(\"Element #{0} = {1}\", i, b[i]);\n      }\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/interface_indexers.cs.t/expected.tags",
    "content": "IMyInterface\tinput.cs\t/^public interface IMyInterface $/;\"\ti\nIndexerClass\tinput.cs\t/^class IndexerClass : IMyInterface$/;\"\tc\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^public class MainClass $/;\"\tc\nmyArray\tinput.cs\t/^   private int [] myArray = new int[100]; $/;\"\tf\tclass:IndexerClass\tfile:\n"
  },
  {
    "path": "Units/csharp-review-needed.r/interface_indexers.cs.t/input.cs",
    "content": "// cs_interface_indexers.cs\nusing System;\n// Indexer on an interface:\npublic interface IMyInterface \n{\n   // indexer declaration:\n   int this[int index] \n   {\n      get; \n      set; \n   }\n}\n\n// Implementing the interface:\nclass IndexerClass : IMyInterface\n{\n   private int [] myArray = new int[100]; \n   public int this [int index]   // indexer declaration\n   {\n      get \n      {\n         // Check the index limits\n         if (index < 0 || index >= 100)\n            return 0;\n         else\n            return myArray[index];\n      }\n      set \n      {\n         if (!(index < 0 || index >= 100))\n            myArray[index] = value;\n      }\n   }\n}\n\npublic class MainClass \n{\n   public static void Main() \n   {\n      IndexerClass b = new IndexerClass();\n      // call the indexer to initialize the elements #3 and #5:\n      b[2] = 4;\n      b[5] = 32;\n      for (int i=0; i<=10; i++) \n      {\n         Console.WriteLine(\"Element #{0} = {1}\", i, b[i]);\n      }\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/interface_properties.cs.t/expected.tags",
    "content": "Counter\tinput.cs\t/^   int Counter $/;\"\tp\tinterface:IEmployee\nCounter\tinput.cs\t/^   public int Counter $/;\"\tp\tclass:Employee\nEmployee\tinput.cs\t/^   public Employee() $/;\"\tm\tclass:Employee\nEmployee\tinput.cs\t/^public class Employee: IEmployee $/;\"\tc\nIEmployee\tinput.cs\t/^interface IEmployee $/;\"\ti\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^public class MainClass $/;\"\tc\nName\tinput.cs\t/^   public string Name $/;\"\tp\tclass:Employee\nName\tinput.cs\t/^   string Name $/;\"\tp\tinterface:IEmployee\ncounter\tinput.cs\t/^   private int counter;$/;\"\tf\tclass:Employee\tfile:\nname\tinput.cs\t/^   private string name;$/;\"\tf\tclass:Employee\tfile:\nnumberOfEmployees\tinput.cs\t/^   public static int numberOfEmployees;$/;\"\tf\tclass:Employee\n"
  },
  {
    "path": "Units/csharp-review-needed.r/interface_properties.cs.t/input.cs",
    "content": "// cs_interface_properties.cs\n// Interface Properties\nusing System;\ninterface IEmployee \n{\n   string Name \n   {\n      get;\n      set;\n   }\n\n   int Counter \n   {\n      get;\n   }\n}\n\npublic class Employee: IEmployee \n{\n   public static int numberOfEmployees;\n   private int counter;\n   private string name;\n   // Read-write instance property:\n   public string Name \n   {\n      get \n      {\n         return name; \n      }\n      set \n      {\n         name = value; \n      }\n   }\n   // Read-only instance property:\n   public int Counter \n   {\n      get \n      {\n         return counter; \n      }\n   }\n   // Constructor:\n   public Employee() \n   {\n      counter = ++counter + numberOfEmployees;\n   }\n}\n\npublic class MainClass \n{\n   public static void Main() \n   {\n      Console.Write(\"Enter number of employees: \");\n      string s = Console.ReadLine();\n      Employee.numberOfEmployees = int.Parse(s);\n      Employee e1 = new Employee();\n      Console.Write(\"Enter the name of the new employee: \");\n      e1.Name = Console.ReadLine();  \n      Console.WriteLine(\"The employee information:\");\n      Console.WriteLine(\"Employee number: {0}\", e1.Counter);\n      Console.WriteLine(\"Employee name: {0}\", e1.Name);\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/internal.cs.t/expected.tags",
    "content": "BaseClass\tinput.cs\t/^internal class BaseClass $/;\"\tc\nIntM\tinput.cs\t/^   public static int IntM = 0;$/;\"\tf\tclass:BaseClass\n"
  },
  {
    "path": "Units/csharp-review-needed.r/internal.cs.t/input.cs",
    "content": "// Assembly1.cs\n// compile with: /target:library\ninternal class BaseClass \n{\n   public static int IntM = 0;\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_abstract.cs.t/expected.tags",
    "content": "GetX\tinput.cs\t/^   public abstract int GetX   \\/\\/ Abstract property$/;\"\tp\tclass:MyBaseC\nGetX\tinput.cs\t/^   public override int GetX   \\/\\/ overriding property$/;\"\tp\tclass:MyDerivedC\nGetY\tinput.cs\t/^   public abstract int GetY   \\/\\/ Abstract property$/;\"\tp\tclass:MyBaseC\nGetY\tinput.cs\t/^   public override int GetY   \\/\\/ overriding property$/;\"\tp\tclass:MyDerivedC\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MyDerivedC\nMyBaseC\tinput.cs\t/^abstract class MyBaseC   \\/\\/ Abstract class$/;\"\tc\nMyDerivedC\tinput.cs\t/^class MyDerivedC: MyBaseC$/;\"\tc\nMyMethod\tinput.cs\t/^   public abstract void MyMethod();   \\/\\/ Abstract method$/;\"\tm\tclass:MyBaseC\nMyMethod\tinput.cs\t/^   public override void MyMethod() $/;\"\tm\tclass:MyDerivedC\nx\tinput.cs\t/^   protected int x = 100; $/;\"\tf\tclass:MyBaseC\ny\tinput.cs\t/^   protected int y = 150;$/;\"\tf\tclass:MyBaseC\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_abstract.cs.t/input.cs",
    "content": "// abstract_keyword.cs\n// Abstract Classes\nusing System;\nabstract class MyBaseC   // Abstract class\n{\n   protected int x = 100; \n   protected int y = 150;\n   public abstract void MyMethod();   // Abstract method\n\n   public abstract int GetX   // Abstract property\n   {\n      get;\n   }\n\n   public abstract int GetY   // Abstract property\n   {\n      get;\n   }\n}\n\nclass MyDerivedC: MyBaseC\n{\n   public override void MyMethod() \n   {\n      x++;\n      y++;   \n   }   \n\n   public override int GetX   // overriding property\n   {\n      get \n      {\n         return x+10;\n      }\n   }\n\n   public override int GetY   // overriding property\n   {\n      get\n      {\n         return y+10;\n      }\n   }\n\n   public static void Main() \n   {\n      MyDerivedC mC = new MyDerivedC();\n      mC.MyMethod();\n      Console.WriteLine(\"x = {0}, y = {1}\", mC.GetX, mC.GetY);    \n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_catch_try.cs.t/expected.tags",
    "content": "Main\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MyClass\nMyClass\tinput.cs\t/^class MyClass $/;\"\tc\nMyFn\tinput.cs\t/^   public void MyFn(string s) $/;\"\tm\tclass:MyClass\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_catch_try.cs.t/input.cs",
    "content": "// Ordering catch clauses\nusing System;\nclass MyClass \n{\n   public static void Main() \n   {\n      MyClass x = new MyClass();\n      try \n      {\n         string s = null;\n         x.MyFn(s);\n      }\n\n      // Most specific:\n      catch (ArgumentNullException e) \n      {\n         Console.WriteLine(\"{0} First exception caught.\", e);\n      }\n\n      // Least specific:\n      catch (Exception e) \n      {\n         Console.WriteLine(\"{0} Second exception caught.\", e);\n      }\n\n   }\n\n   public void MyFn(string s) \n   {\n      if (s == null) \n         throw new ArgumentNullException();\n   }   \n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_class.cs.t/expected.tags",
    "content": "Kid\tinput.cs\t/^   public Kid() $/;\"\tm\tclass:Kid\nKid\tinput.cs\t/^   public Kid(string name, int age) $/;\"\tm\tclass:Kid\nKid\tinput.cs\t/^public class Kid $/;\"\tc\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^public class MainClass $/;\"\tc\nPrintKid\tinput.cs\t/^   public void PrintKid() $/;\"\tm\tclass:Kid\nage\tinput.cs\t/^   private int age;$/;\"\tf\tclass:Kid\tfile:\nname\tinput.cs\t/^   private string name;$/;\"\tf\tclass:Kid\tfile:\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_class.cs.t/input.cs",
    "content": "// keyword_class.cs\n// class example\nusing System;\npublic class Kid \n{\n   private int age;\n   private string name;\n\n   // Default constructor:\n   public Kid() \n   {\n      name = \"N/A\";\n   }\n\n   // Constructor:\n   public Kid(string name, int age) \n   {\n      this.name = name;\n      this.age = age;\n   }\n\n   // Printing method:\n   public void PrintKid() \n   {\n      Console.WriteLine(\"{0}, {1} years old.\", name, age);\n   }\n}\n\npublic class MainClass \n{\n   public static void Main() \n   {\n      // Create objects\n      // Objects must be created using the new operator:\n      Kid kid1 = new Kid(\"Craig\", 11);\n      Kid kid2 = new Kid(\"Sally\", 10);\n\n      // Create an object using the default constructor:\n      Kid kid3 = new Kid(); \n\n      // Display results:\n      Console.Write(\"Kid #1: \");\n      kid1.PrintKid();\n      Console.Write(\"Kid #2: \");\n      kid2.PrintKid();\n      Console.Write(\"Kid #3: \");\n      kid3.PrintKid();\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_const.cs.t/expected.tags",
    "content": "ConstTest\tinput.cs\t/^public class ConstTest $/;\"\tc\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:ConstTest\nMyClass\tinput.cs\t/^      public MyClass(int p1, int p2) $/;\"\tm\tclass:ConstTest.MyClass\nMyClass\tinput.cs\t/^   class MyClass $/;\"\tc\tclass:ConstTest\nc1\tinput.cs\t/^      public const int c1 = 5;$/;\"\tf\tclass:ConstTest.MyClass\nc2\tinput.cs\t/^      public const int c2 = c1 + 5;$/;\"\tf\tclass:ConstTest.MyClass\nx\tinput.cs\t/^      public int x;$/;\"\tf\tclass:ConstTest.MyClass\ny\tinput.cs\t/^      public int y;$/;\"\tf\tclass:ConstTest.MyClass\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_const.cs.t/input.cs",
    "content": "// const_keyword.cs\n// Constants\nusing System;\npublic class ConstTest \n{\n   class MyClass \n   {\n      public int x;\n      public int y;\n      public const int c1 = 5;\n      public const int c2 = c1 + 5;\n\n      public MyClass(int p1, int p2) \n      {\n         x = p1; \n         y = p2;\n      }\n   }\n\n   public static void Main() \n   {\n      MyClass mC = new MyClass(11, 22);   \n      Console.WriteLine(\"x = {0}, y = {1}\", mC.x, mC.y);\n      Console.WriteLine(\"c1 = {0}, c2 = {1}\", MyClass.c1, MyClass.c2 );\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_delegate.cs.t/expected.tags",
    "content": "DelegateFunction\tinput.cs\t/^   public static void DelegateFunction(int i)$/;\"\tm\tclass:Program\nInstanceMethod\tinput.cs\t/^   public void InstanceMethod() $/;\"\tm\tclass:MyClass\nMain\tinput.cs\t/^   public static void Main()$/;\"\tm\tclass:Program\nMain\tinput.cs\t/^   static public void Main() $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^public class MainClass $/;\"\tc\nMyClass\tinput.cs\t/^public class MyClass $/;\"\tc\nMyDelegate\tinput.cs\t/^delegate void MyDelegate();$/;\"\tm\nMyDelegate\tinput.cs\t/^delegate void MyDelegate(int i);$/;\"\tm\nProgram\tinput.cs\t/^class Program$/;\"\tc\nStaticMethod\tinput.cs\t/^   static public void StaticMethod() $/;\"\tm\tclass:MyClass\nTakesADelegate\tinput.cs\t/^   public static void TakesADelegate(MyDelegate SomeFunction)$/;\"\tm\tclass:Program\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_delegate.cs.t/input.cs",
    "content": "// keyword_delegate.cs\n// delegate declaration\ndelegate void MyDelegate(int i);\n\nclass Program\n{\n   public static void Main()\n   {\n      TakesADelegate(new MyDelegate(DelegateFunction));\n   }\n\n   public static void TakesADelegate(MyDelegate SomeFunction)\n   {\n      SomeFunction(21);\n   }\n   \n   public static void DelegateFunction(int i)\n   {\n      System.Console.WriteLine(\"Called by delegate with number: {0}.\", i);\n   }\n}\n//\n// keyword_delegate2.cs\n// Calling both static and instance methods from delegates\nusing System;\n\n// delegate declaration\ndelegate void MyDelegate();\n\npublic class MyClass \n{\n   public void InstanceMethod() \n   {\n      Console.WriteLine(\"A message from the instance method.\"); \n   }\n\n   static public void StaticMethod() \n   {\n      Console.WriteLine(\"A message from the static method.\");\n   }\n}\n\npublic class MainClass \n{\n   static public void Main() \n   {\n      MyClass p = new MyClass();\n\n      // Map the delegate to the instance method:\n      MyDelegate d = new MyDelegate(p.InstanceMethod);\n      d();\n\n      // Map to the static method:\n      d = new MyDelegate(MyClass.StaticMethod);\n      d();\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_enum.cs.t/expected.tags",
    "content": "Days\tinput.cs\t/^   enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};$/;\"\tg\tclass:EnumTest\nEnumTest\tinput.cs\t/^public class EnumTest $/;\"\tc\nFri\tinput.cs\t/^   enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};$/;\"\te\tenum:EnumTest.Days\tfile:\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:EnumTest\nMax\tinput.cs\t/^   enum Range :long {Max = 2147483648L, Min = 255L};$/;\"\te\tenum:EnumTest.Range\tfile:\nMin\tinput.cs\t/^   enum Range :long {Max = 2147483648L, Min = 255L};$/;\"\te\tenum:EnumTest.Range\tfile:\nMon\tinput.cs\t/^   enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};$/;\"\te\tenum:EnumTest.Days\tfile:\nRange\tinput.cs\t/^   enum Range :long {Max = 2147483648L, Min = 255L};$/;\"\tg\tclass:EnumTest\nSat\tinput.cs\t/^   enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};$/;\"\te\tenum:EnumTest.Days\tfile:\nSun\tinput.cs\t/^   enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};$/;\"\te\tenum:EnumTest.Days\tfile:\nThu\tinput.cs\t/^   enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};$/;\"\te\tenum:EnumTest.Days\tfile:\nTue\tinput.cs\t/^   enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};$/;\"\te\tenum:EnumTest.Days\tfile:\nWed\tinput.cs\t/^   enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};$/;\"\te\tenum:EnumTest.Days\tfile:\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_enum.cs.t/input.cs",
    "content": "// C# Programmer's Reference: enum\n// keyword_enum.cs\n// enum initialization:\nusing System;\npublic class EnumTest \n{\n   enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};\n\n   public static void Main() \n   {\n      int x = (int) Days.Sun;\n      int y = (int) Days.Fri;\n      Console.WriteLine(\"Sun = {0}\", x);\n      Console.WriteLine(\"Fri = {0}\", y);\n   }\n}\n\n// keyword_enum2.cs\n// Using long enumerators\nusing System;\npublic class EnumTest \n{\n   enum Range :long {Max = 2147483648L, Min = 255L};\n   public static void Main() \n   {\n      long x = (long) Range.Max;\n      long y = (long) Range.Min;\n      Console.WriteLine(\"Max = {0}\", x);\n      Console.WriteLine(\"Min = {0}\", y);\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_event.cs.t/expected.tags",
    "content": "Event1\tinput.cs\t/^   public event MyDelegate1 Event1 $/;\"\tp\tclass:PropertyEventsSample\nEvent2\tinput.cs\t/^   public event MyDelegate1 Event2 $/;\"\tp\tclass:PropertyEventsSample\nEvent3\tinput.cs\t/^   public event MyDelegate2 Event3 $/;\"\tp\tclass:PropertyEventsSample\nEvent4\tinput.cs\t/^   public event MyDelegate3 Event4 $/;\"\tp\tclass:PropertyEventsSample\nEvent5\tinput.cs\t/^   public event MyDelegate3 Event5 $/;\"\tp\tclass:PropertyEventsSample\nEvent6\tinput.cs\t/^   public event MyDelegate4 Event6 $/;\"\tp\tclass:PropertyEventsSample\nExplicitEventsSample\tinput.cs\t/^public class ExplicitEventsSample: I1, I2 $/;\"\tc\nFireAway\tinput.cs\t/^   public void FireAway() $/;\"\tm\tclass:MyClass\nFireAway\tinput.cs\t/^   void FireAway();$/;\"\tm\tinterface:I\nFireEvents\tinput.cs\t/^   private void FireEvents() $/;\"\tm\tclass:ExplicitEventsSample\tfile:\nI\tinput.cs\t/^public interface I $/;\"\ti\nI1\tinput.cs\t/^public interface I1 $/;\"\ti\nI2\tinput.cs\t/^public interface I2 $/;\"\ti\nI2.MyEvent\tinput.cs\t/^   event MyDelegate2 I2.MyEvent   \\/\\/ explicit implementation of I2.MyEvent$/;\"\tp\tclass:ExplicitEventsSample\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MyClass\nMain\tinput.cs\t/^   static public void Main () $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^public class MainClass $/;\"\tc\nMyClass\tinput.cs\t/^public class MyClass $/;\"\tc\nMyClass\tinput.cs\t/^public class MyClass: I $/;\"\tc\nMyDelegate\tinput.cs\t/^public delegate void MyDelegate();   \\/\\/ delegate declaration$/;\"\tm\nMyDelegate1\tinput.cs\t/^public delegate void MyDelegate1();$/;\"\tm\nMyDelegate1\tinput.cs\t/^public delegate void MyDelegate1(int i);$/;\"\tm\nMyDelegate2\tinput.cs\t/^public delegate int MyDelegate2(string s);$/;\"\tm\nMyDelegate2\tinput.cs\t/^public delegate void MyDelegate2(string s);$/;\"\tm\nMyDelegate3\tinput.cs\t/^public delegate void MyDelegate3(int i, object o);$/;\"\tm\nMyDelegate4\tinput.cs\t/^public delegate void MyDelegate4();$/;\"\tm\nMyEvent\tinput.cs\t/^   event MyDelegate MyEvent;$/;\"\tE\tinterface:I\nMyEvent\tinput.cs\t/^   event MyDelegate1 MyEvent;$/;\"\tE\tinterface:I1\nMyEvent\tinput.cs\t/^   event MyDelegate2 MyEvent;$/;\"\tE\tinterface:I2\nMyEvent\tinput.cs\t/^   public event MyDelegate MyEvent;$/;\"\tE\tclass:MyClass\nMyEvent\tinput.cs\t/^   public event MyDelegate1 MyEvent;  \\/\\/ normal implementation of I1.MyEvent.$/;\"\tE\tclass:ExplicitEventsSample\nMyEvent2Storage\tinput.cs\t/^   private MyDelegate2 MyEvent2Storage;  \\/\\/ underlying storage for I2.MyEvent.$/;\"\tf\tclass:ExplicitEventsSample\tfile:\nPropertyEventsSample\tinput.cs\t/^public class PropertyEventsSample $/;\"\tc\neventTable\tinput.cs\t/^   private Hashtable eventTable = new Hashtable();$/;\"\tf\tclass:PropertyEventsSample\tfile:\nf\tinput.cs\t/^   static private void f() $/;\"\tm\tclass:MainClass\tfile:\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_event.cs.t/input.cs",
    "content": "// event_keyword.cs\nusing System;\npublic delegate void MyDelegate();   // delegate declaration\n\npublic interface I \n{\n   event MyDelegate MyEvent;\n   void FireAway();\n}\n\npublic class MyClass: I \n{\n   public event MyDelegate MyEvent;\n\n   public void FireAway() \n   {\n      if (MyEvent != null)\n         MyEvent();\n   }\n}\n\npublic class MainClass \n{\n   static private void f() \n   {\n      Console.WriteLine(\"This is called when the event fires.\");\n   }\n\n   static public void Main () \n   {\n      I i = new MyClass();\n\n      i.MyEvent += new MyDelegate(f);\n      i.FireAway();\n   }\n}\n\n// event_keyword2.cs\nusing System;\nusing System.Collections;\n\npublic delegate void MyDelegate1(int i);\npublic delegate void MyDelegate2(string s);\npublic delegate void MyDelegate3(int i, object o);\npublic delegate void MyDelegate4();\n\npublic class PropertyEventsSample \n{\n   private Hashtable eventTable = new Hashtable();\n\n   public event MyDelegate1 Event1 \n   {\n      add \n      {\n         eventTable[\"Event1\"] = (MyDelegate1)eventTable[\"Event1\"] + value;\n      }\n      remove\n      {\n         eventTable[\"Event1\"] = (MyDelegate1)eventTable[\"Event1\"] - value; \n      }\n   }\n\n   public event MyDelegate1 Event2 \n   {\n      add \n      {\n         eventTable[\"Event2\"] = (MyDelegate1)eventTable[\"Event2\"] + value;\n      }\n      remove\n      {\n         eventTable[\"Event2\"] = (MyDelegate1)eventTable[\"Event2\"] - value; \n      }\n   }\n\n   public event MyDelegate2 Event3 \n   {\n      add \n      {\n         eventTable[\"Event3\"] = (MyDelegate2)eventTable[\"Event3\"] + value;\n      }\n      remove\n      {\n         eventTable[\"Event3\"] = (MyDelegate2)eventTable[\"Event3\"] - value; \n      }\n   }\n\n   public event MyDelegate3 Event4 \n   {\n      add \n      {\n         eventTable[\"Event4\"] = (MyDelegate3)eventTable[\"Event4\"] + value;\n      }\n      remove\n      {\n         eventTable[\"Event4\"] = (MyDelegate3)eventTable[\"Event4\"] - value; \n      }\n   }\n\n   public event MyDelegate3 Event5 \n   {\n      add \n      {\n         eventTable[\"Event5\"] = (MyDelegate3)eventTable[\"Event5\"] + value;\n      }\n      remove\n      {\n         eventTable[\"Event5\"] = (MyDelegate3)eventTable[\"Event5\"] - value; \n      }\n   }\n\n   public event MyDelegate4 Event6 \n   {\n      add \n      {\n         eventTable[\"Event6\"] = (MyDelegate4)eventTable[\"Event6\"] + value;\n      }\n      remove\n      {\n         eventTable[\"Event6\"] = (MyDelegate4)eventTable[\"Event6\"] - value; \n      }\n   }\n}\n\npublic class MyClass \n{\n   public static void Main() \n   {\n   }\n}\n\n// event_keyword3.cs\nusing System;\n\npublic delegate void MyDelegate1();\n\npublic interface I1 \n{\n   event MyDelegate1 MyEvent;\n}\n\npublic delegate int MyDelegate2(string s);\n\npublic interface I2 \n{\n   event MyDelegate2 MyEvent;\n}\n\npublic class ExplicitEventsSample: I1, I2 \n{\n   public event MyDelegate1 MyEvent;  // normal implementation of I1.MyEvent.\n\n   event MyDelegate2 I2.MyEvent   // explicit implementation of I2.MyEvent\n   {\n      add\n      {\n         MyEvent2Storage += value;\n      }\n      remove\n      {\n         MyEvent2Storage -= value;\n      }\n   }\n\n   private MyDelegate2 MyEvent2Storage;  // underlying storage for I2.MyEvent.\n\n   private void FireEvents() \n   {\n      if (MyEvent != null)\n         MyEvent();\n      if (MyEvent2Storage != null)\n         MyEvent2Storage(\"hello\");\n   }\n}\n\npublic class MyClass \n{\n   public static void Main() \n   {\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_explicit.cs.t/expected.tags",
    "content": "Digit\tinput.cs\t/^   public Digit(byte value) $/;\"\tm\tstruct:Digit\nDigit\tinput.cs\t/^struct Digit$/;\"\ts\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:Test\nTest\tinput.cs\t/^class Test $/;\"\tc\noperator Digit\tinput.cs\t/^   public static explicit operator Digit(byte b) $/;\"\tm\tstruct:Digit\nvalue\tinput.cs\t/^   byte value;$/;\"\tf\tstruct:Digit\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_explicit.cs.t/input.cs",
    "content": "// cs_keyword_explicit.cs\nusing System;\nstruct Digit\n{\n   byte value;\n   public Digit(byte value) \n   {\n      if (value<0 || value>9) throw new ArgumentException();\n      this.value = value;\n   }\n\n   // define explicit byte-to-Digit conversion operator:\n   public static explicit operator Digit(byte b) \n   {\n      Console.WriteLine(\"conversion occurred\");\n      return new Digit(b);\n   }\n}\n\nclass Test \n{\n   public static void Main() \n   {\n      byte b = 3;\n      Digit d = (Digit)b; // explicit conversion\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_extern.cs.t/expected.tags",
    "content": "Main\tinput.cs\t/^   public static int Main() $/;\"\tm\tclass:MyClass\nMessageBox\tinput.cs\t/^   public static extern int MessageBox(int h, string m, string c, int type);$/;\"\tm\tclass:MyClass\tfile:\nMyClass\tinput.cs\t/^class MyClass $/;\"\tc\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_extern.cs.t/input.cs",
    "content": "using System;\nusing System.Runtime.InteropServices;\nclass MyClass \n{\n   [DllImport(\"User32.dll\")]\n   public static extern int MessageBox(int h, string m, string c, int type);\n\n   public static int Main() \n   {\n      string myString; \n      Console.Write(\"Enter your message: \");\n      myString = Console.ReadLine();\n      return MessageBox(0, myString, \"My Message Box\", 0);\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_implicit.cs.t/expected.tags",
    "content": "Digit\tinput.cs\t/^   public Digit(byte value) $/;\"\tm\tstruct:Digit\nDigit\tinput.cs\t/^struct Digit$/;\"\ts\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:Test\nTest\tinput.cs\t/^class Test $/;\"\tc\noperator byte\tinput.cs\t/^   public static implicit operator byte(Digit d) $/;\"\tm\tstruct:Digit\nvalue\tinput.cs\t/^   byte value;$/;\"\tf\tstruct:Digit\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_implicit.cs.t/input.cs",
    "content": "// cs_keyword_implicit.cs\nusing System;\nstruct Digit\n{\n   byte value;\n\n   public Digit(byte value) \n   {\n      if (value < 0 || value > 9) throw new ArgumentException();\n      this.value = value;\n   }\n\n   // define implicit Digit-to-byte conversion operator:\n   public static implicit operator byte(Digit d) \n   {\n      Console.WriteLine( \"conversion occurred\" );\n      return d.value;\n   }\n}\n\nclass Test \n{\n   public static void Main() \n   {\n      Digit d = new Digit(3);\n\n      // implicit (no cast) conversion from Digit to byte\n      byte b = d;   \n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_interface.cs.t/expected.tags",
    "content": "IPoint\tinput.cs\t/^interface IPoint $/;\"\ti\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^class MainClass $/;\"\tc\nMyPoint\tinput.cs\t/^   public MyPoint(int x, int y) $/;\"\tm\tclass:MyPoint\nMyPoint\tinput.cs\t/^class MyPoint : IPoint $/;\"\tc\nPrintPoint\tinput.cs\t/^   private static void PrintPoint(IPoint p) $/;\"\tm\tclass:MainClass\tfile:\nmyX\tinput.cs\t/^   private int myX;$/;\"\tf\tclass:MyPoint\tfile:\nmyY\tinput.cs\t/^   private int myY;$/;\"\tf\tclass:MyPoint\tfile:\nx\tinput.cs\t/^   int x $/;\"\tp\tinterface:IPoint\nx\tinput.cs\t/^   public int x $/;\"\tp\tclass:MyPoint\ny\tinput.cs\t/^   int y $/;\"\tp\tinterface:IPoint\ny\tinput.cs\t/^   public int y $/;\"\tp\tclass:MyPoint\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_interface.cs.t/input.cs",
    "content": "// keyword_interface.cs\n// Interface implementation\nusing System;\ninterface IPoint \n{\n   // Property signatures:\n   int x \n   {\n      get; \n      set; \n   }\n\n   int y \n   {\n      get; \n      set; \n   }\n}\n\nclass MyPoint : IPoint \n{\n   // Fields:\n   private int myX;\n   private int myY;\n\n   // Constructor:\n   public MyPoint(int x, int y) \n   {\n      myX = x;\n      myY = y;\n   }\n\n   // Property implementation:\n   public int x \n   {\n      get \n      {\n         return myX;\n      }\n\n      set \n      {\n         myX = value; \n      }\n   }\n\n   public int y \n   {\n      get \n      {\n         return myY; \n      }\n      set \n      {\n         myY = value; \n      }\n   }\n}\n\nclass MainClass \n{\n   private static void PrintPoint(IPoint p) \n   {\n      Console.WriteLine(\"x={0}, y={1}\", p.x, p.y);\n   }\n\n   public static void Main() \n   {\n      MyPoint p = new MyPoint(2,3);\n      Console.Write(\"My Point: \");\n      PrintPoint(p);\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_namespace.cs.t/expected.tags",
    "content": "AlternativeNestedNameSpaceClass\tinput.cs\t/^\tpublic class AlternativeNestedNameSpaceClass$/;\"\tc\tnamespace:SomeNameSpace.Nested\nMain\tinput.cs\t/^      public static void Main() $/;\"\tm\tclass:SomeNameSpace.MyClass\nMyClass\tinput.cs\t/^   public class MyClass $/;\"\tc\tnamespace:SomeNameSpace\nNested\tinput.cs\t/^   namespace Nested   \\/\\/ a nested namespace$/;\"\tn\tnamespace:SomeNameSpace\nNestedNameSpaceClass\tinput.cs\t/^      public class NestedNameSpaceClass $/;\"\tc\tnamespace:SomeNameSpace.Nested\nSayHello\tinput.cs\t/^         public static void SayHello() $/;\"\tm\tclass:SomeNameSpace.Nested.NestedNameSpaceClass\nSomeNameSpace\tinput.cs\t/^namespace SomeNameSpace$/;\"\tn\nSomeNameSpace.Nested\tinput.cs\t/^namespace SomeNameSpace.Nested$/;\"\tn\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_namespace.cs.t/input.cs",
    "content": "// cs_namespace_keyword.cs\nusing System;\nnamespace SomeNameSpace\n{\n   public class MyClass \n   {\n      public static void Main() \n      {\n         Nested.NestedNameSpaceClass.SayHello();\n      }\n   }\n\n   namespace Nested   // a nested namespace\n   {\n      public class NestedNameSpaceClass \n      {\n         public static void SayHello() \n         {\n            Console.WriteLine(\"Hello\");\n         }\n      }\n   }\n}\n\n// namespace can nest multiple levels at once.\nnamespace SomeNameSpace.Nested\n{\n\tpublic class AlternativeNestedNameSpaceClass\n\t{\n\t}\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_out.cs.t/expected.tags",
    "content": "Main\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MyClass\nMyClass\tinput.cs\t/^public class MyClass $/;\"\tc\nTestOut\tinput.cs\t/^   public static int TestOut(out char i) $/;\"\tm\tclass:MyClass\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_out.cs.t/input.cs",
    "content": "// cs_out.cs \nusing System;\npublic class MyClass \n{\n   public static int TestOut(out char i) \n   {\n      i = 'b';\n      return -1;\n   }\n\n   public static void Main() \n   {\n      char i;   // variable need not be initialized\n      Console.WriteLine(TestOut(out i));\n      Console.WriteLine(i);\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_override.cs.t/expected.tags",
    "content": "Area\tinput.cs\t/^      public override double Area() $/;\"\tm\tclass:TestClass.Cube\nArea\tinput.cs\t/^      public virtual double Area() $/;\"\tm\tclass:TestClass.Square\nCube\tinput.cs\t/^      public Cube(double x): base(x) $/;\"\tm\tclass:TestClass.Cube\nCube\tinput.cs\t/^   class Cube: Square $/;\"\tc\tclass:TestClass\nMain\tinput.cs\t/^   public static void Main()$/;\"\tm\tclass:TestClass\nSquare\tinput.cs\t/^      public Square(double x) $/;\"\tm\tclass:TestClass.Square\nSquare\tinput.cs\t/^   public class Square $/;\"\tc\tclass:TestClass\nTestClass\tinput.cs\t/^class TestClass $/;\"\tc\nx\tinput.cs\t/^      public double x;$/;\"\tf\tclass:TestClass.Square\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_override.cs.t/input.cs",
    "content": "// cs_override_keyword.cs\n// Calling overriden methods from the base class\nusing System;\nclass TestClass \n{\n   public class Square \n   {\n      public double x;\n\n      // Constructor:\n      public Square(double x) \n      {\n         this.x = x;\n      }\n\n      public virtual double Area() \n      {\n         return x*x; \n      }\n   }\n\n   class Cube: Square \n   {\n      // Constructor:\n      public Cube(double x): base(x) \n      {\n      }\n\n      // Calling the Area base method:\n      public override double Area() \n      {\n         return (6*(base.Area())); \n      }\n   }\n\n   public static void Main()\n   {\n      double x = 5.2;\n      Square s = new Square(x);\n      Square c = new Cube(x);\n      Console.WriteLine(\"Area of Square = {0:F2}\", s.Area());\n      Console.WriteLine(\"Area of Cube = {0:F2}\", c.Area());\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_params.cs.t/expected.tags",
    "content": "Main\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MyClass\nMyClass\tinput.cs\t/^public class MyClass $/;\"\tc\nUseParams\tinput.cs\t/^   public static void UseParams(params int[] list) $/;\"\tm\tclass:MyClass\nUseParams2\tinput.cs\t/^   public static void UseParams2(params object[] list) $/;\"\tm\tclass:MyClass\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_params.cs.t/input.cs",
    "content": "// cs_params.cs\nusing System;\npublic class MyClass \n{\n\n   public static void UseParams(params int[] list) \n   {\n      for ( int i = 0 ; i < list.Length ; i++ )\n         Console.WriteLine(list[i]);\n      Console.WriteLine();\n   }\n\n   public static void UseParams2(params object[] list) \n   {\n      for ( int i = 0 ; i < list.Length ; i++ )\n         Console.WriteLine((object)list[i]);\n      Console.WriteLine();\n   }\n\n   public static void Main() \n   {\n      UseParams(1, 2, 3);\n      UseParams2(1, 'a', \"test\"); \n\n      int[] myarray = new int[3] {10,11,12};\n      UseParams(myarray);\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_private.cs.t/expected.tags",
    "content": "AccessSalary\tinput.cs\t/^   public double AccessSalary() {$/;\"\tm\tclass:Employee\nEmployee\tinput.cs\t/^class Employee $/;\"\tc\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^class MainClass $/;\"\tc\nname\tinput.cs\t/^   public string name = \"xx\";$/;\"\tf\tclass:Employee\nnot_visible\tinput.cs\t/^   private int not_visible = 3;  \\/\\/ strangely, not in original example$/;\"\tf\tclass:Employee\tfile:\nsalary\tinput.cs\t/^   double salary = 100.00;   \\/\\/ private access by default$/;\"\tf\tclass:Employee\tfile:\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_private.cs.t/input.cs",
    "content": "// private_keyword.cs\nusing System;\nclass Employee \n{\n   public string name = \"xx\";\n   double salary = 100.00;   // private access by default\n   private int not_visible = 3;  // strangely, not in original example\n   public double AccessSalary() {\n      return salary;\n   }\n}\n\nclass MainClass \n{\n   public static void Main() \n   {\n      Employee e = new Employee();\n\n      // Accessing the public field:\n      string n = e.name; \n      \n      // Accessing the private field:\n      double s = e.AccessSalary();    \n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_protected.cs.t/expected.tags",
    "content": "Main\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MyDerivedC\nMyClass\tinput.cs\t/^class MyClass $/;\"\tc\nMyDerivedC\tinput.cs\t/^class MyDerivedC: MyClass $/;\"\tc\nx\tinput.cs\t/^   protected int x; $/;\"\tf\tclass:MyClass\ny\tinput.cs\t/^   protected int y;$/;\"\tf\tclass:MyClass\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_protected.cs.t/input.cs",
    "content": "// protected_keyword.cs\nusing System;\nclass MyClass \n{\n   protected int x; \n   protected int y;\n}\n\nclass MyDerivedC: MyClass \n{\n   public static void Main() \n   {\n      MyDerivedC mC = new MyDerivedC();\n\n      // Direct access to protected members:\n      mC.x = 10;\n      mC.y = 15;\n      Console.WriteLine(\"x = {0}, y = {1}\", mC.x, mC.y); \n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_public.cs.t/expected.tags",
    "content": "Main\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MyClass2\nMyClass1\tinput.cs\t/^class MyClass1 $/;\"\tc\nMyClass2\tinput.cs\t/^class MyClass2 $/;\"\tc\nx\tinput.cs\t/^   public int x; $/;\"\tf\tclass:MyClass1\ny\tinput.cs\t/^   public int y;$/;\"\tf\tclass:MyClass1\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_public.cs.t/input.cs",
    "content": "// protected_public.cs\n// Public access\nusing System;\nclass MyClass1 \n{\n   public int x; \n   public int y;\n}\n\nclass MyClass2 \n{\n   public static void Main() \n   {\n      MyClass1 mC = new MyClass1();\n\n      // Direct access to public members:\n      mC.x = 10;\n      mC.y = 15;\n      Console.WriteLine(\"x = {0}, y = {1}\", mC.x, mC.y); \n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_sealed.cs.t/expected.tags",
    "content": "Main\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^class MainClass $/;\"\tc\nMyClass\tinput.cs\t/^sealed class MyClass $/;\"\tc\nx\tinput.cs\t/^   public int x; $/;\"\tf\tclass:MyClass\ny\tinput.cs\t/^   public int y;$/;\"\tf\tclass:MyClass\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_sealed.cs.t/input.cs",
    "content": "// cs_sealed_keyword.cs\n// Sealed classes\nusing System;\nsealed class MyClass \n{\n   public int x; \n   public int y;\n}\n\nclass MainClass \n{\n   public static void Main() \n   {\n      MyClass mC = new MyClass(); \n      mC.x = 110;\n      mC.y = 150;\n      Console.WriteLine(\"x = {0}, y = {1}\", mC.x, mC.y); \n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_static.cs.t/expected.tags",
    "content": "AddEmployee\tinput.cs\t/^   public static int AddEmployee() $/;\"\tm\tclass:Employee\nEmployee\tinput.cs\t/^   public Employee () $/;\"\tm\tclass:Employee\nEmployee\tinput.cs\t/^   public Employee (string name, string id) $/;\"\tm\tclass:Employee\nEmployee\tinput.cs\t/^public class Employee $/;\"\tc\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^class MainClass: Employee $/;\"\tc\nemployeeCounter\tinput.cs\t/^   public static int employeeCounter;$/;\"\tf\tclass:Employee\nid\tinput.cs\t/^   public string id;$/;\"\tf\tclass:Employee\nname\tinput.cs\t/^   public string name;$/;\"\tf\tclass:Employee\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_static.cs.t/input.cs",
    "content": "// cs_static_keyword.cs\n// Static members\nusing System;\npublic class Employee \n{\n   public string id;\n   public string name;\n\n   public Employee () \n   {\n   }\n\n   public Employee (string name, string id) \n   {\n      this.name = name;\n      this.id = id;\n   } \n\n   public static int employeeCounter;\n\n   public static int AddEmployee() \n   {\n      return ++employeeCounter;\n   }\n}\n\nclass MainClass: Employee \n{\n   public static void Main() \n   {\n      Console.Write(\"Enter the employee's name: \");\n      string name = Console.ReadLine();\n      Console.Write(\"Enter the employee's ID: \");      \n      string id = Console.ReadLine();\n      // Create the employee object:\n      Employee e = new Employee (name, id);\n      Console.Write(\"Enter the current number of employees: \");\n      string n = Console.ReadLine();\n      Employee.employeeCounter = Int32.Parse(n);\n      Employee.AddEmployee();\n      // Display the new information:\n      Console.WriteLine(\"Name: {0}\", e.name);\n      Console.WriteLine(\"ID:   {0}\", e.id);\n      Console.WriteLine(\"New Number of Employees: {0}\",\n                         Employee.employeeCounter);\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_struct.cs.t/expected.tags",
    "content": "Main\tinput.cs\t/^   public static void Main()  $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^class MainClass $/;\"\tc\nPoint\tinput.cs\t/^   public Point(int p1, int p2) $/;\"\tm\tstruct:Point\nPoint\tinput.cs\t/^public struct Point $/;\"\ts\nx\tinput.cs\t/^   public int x, y;$/;\"\tf\tstruct:Point\ny\tinput.cs\t/^   public int x, y;$/;\"\tf\tstruct:Point\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_struct.cs.t/input.cs",
    "content": "// keyword_struct.cs\n// struct declaration and initialization\nusing System;\npublic struct Point \n{\n   public int x, y;\n\n   public Point(int p1, int p2) \n   {\n      x = p1;\n      y = p2;    \n   }\n}\n\nclass MainClass \n{\n   public static void Main()  \n   {\n      // Initialize:   \n      Point myPoint = new Point();\n      Point yourPoint = new Point(10,10);\n\n      // Display results:\n      Console.Write(\"My Point:   \");\n      Console.WriteLine(\"x = {0}, y = {1}\", myPoint.x, myPoint.y);\n      Console.Write(\"Your Point: \");\n      Console.WriteLine(\"x = {0}, y = {1}\", yourPoint.x, yourPoint.y);\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_virtual.cs.t/expected.tags",
    "content": "Area\tinput.cs\t/^         public override double Area()$/;\"\tm\tclass:TestClass.Sphere\nArea\tinput.cs\t/^      public override double Area() $/;\"\tm\tclass:TestClass.Circle\nArea\tinput.cs\t/^      public override double Area() $/;\"\tm\tclass:TestClass.Cylinder\nArea\tinput.cs\t/^      public virtual double Area() $/;\"\tm\tclass:TestClass.Dimensions\nCircle\tinput.cs\t/^      public Circle(double r): base(r, 0) $/;\"\tm\tclass:TestClass.Circle\nCircle\tinput.cs\t/^   public class Circle: Dimensions $/;\"\tc\tclass:TestClass\nCylinder\tinput.cs\t/^      public Cylinder(double r, double h): base(r, h) $/;\"\tm\tclass:TestClass.Cylinder\nCylinder\tinput.cs\t/^   class Cylinder: Dimensions $/;\"\tc\tclass:TestClass\nDimensions\tinput.cs\t/^      public Dimensions (double x, double y) $/;\"\tm\tclass:TestClass.Dimensions\nDimensions\tinput.cs\t/^      public Dimensions() $/;\"\tm\tclass:TestClass.Dimensions\nDimensions\tinput.cs\t/^   public class Dimensions $/;\"\tc\tclass:TestClass\nMain\tinput.cs\t/^   public static void Main()  $/;\"\tm\tclass:TestClass\nSphere\tinput.cs\t/^      public Sphere(double r): base(r, 0) $/;\"\tm\tclass:TestClass.Sphere\nSphere\tinput.cs\t/^   class Sphere: Dimensions $/;\"\tc\tclass:TestClass\nTestClass\tinput.cs\t/^class TestClass $/;\"\tc\npi\tinput.cs\t/^      public const double pi = Math.PI;$/;\"\tf\tclass:TestClass.Dimensions\nx\tinput.cs\t/^      protected double x, y;$/;\"\tf\tclass:TestClass.Dimensions\ny\tinput.cs\t/^      protected double x, y;$/;\"\tf\tclass:TestClass.Dimensions\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_virtual.cs.t/input.cs",
    "content": "// cs_virtual_keyword.cs\n// Virtual and override\nusing System;\nclass TestClass \n{\n   public class Dimensions \n   {\n      public const double pi = Math.PI;\n      protected double x, y;\n      public Dimensions() \n      {\n      }\n      public Dimensions (double x, double y) \n      {\n         this.x = x;\n         this.y = y;\n      }\n\n      public virtual double Area() \n      {\n         return x*y;\n      }\n   }\n\n   public class Circle: Dimensions \n   {\n      public Circle(double r): base(r, 0) \n      {\n      }\n\n      public override double Area() \n      { \n         return pi * x * x; \n      }\n   }\n\n   class Sphere: Dimensions \n   {\n      public Sphere(double r): base(r, 0) \n      {\n      }\n\n         public override double Area()\n      {\n         return 4 * pi * x * x; \n      }\n   }\n\n   class Cylinder: Dimensions \n   {\n      public Cylinder(double r, double h): base(r, h) \n      {\n      }\n\n      public override double Area() \n      {\n         return 2*pi*x*x + 2*pi*x*y; \n      }\n   }\n\n   public static void Main()  \n   {\n      double r = 3.0, h = 5.0;\n      Dimensions c = new Circle(r);\n      Dimensions s = new Sphere(r);\n      Dimensions l = new Cylinder(r, h);\n      // Display results:\n      Console.WriteLine(\"Area of Circle   = {0:F2}\", c.Area());\n      Console.WriteLine(\"Area of Sphere   = {0:F2}\", s.Area());\n      Console.WriteLine(\"Area of Cylinder = {0:F2}\", l.Area());\n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_volatile.cs.t/expected.tags",
    "content": "Main\tinput.cs\t/^   public static void Main()$/;\"\tm\tclass:Test\nTest\tinput.cs\t/^   Test(int _i)$/;\"\tm\tclass:Test\tfile:\nTest\tinput.cs\t/^class Test$/;\"\tc\ni\tinput.cs\t/^   public volatile int i;$/;\"\tf\tclass:Test\n"
  },
  {
    "path": "Units/csharp-review-needed.r/keyword_volatile.cs.t/input.cs",
    "content": "// csharp_volatile.cs\nclass Test\n{\n   public volatile int i;\n   \n   Test(int _i)\n   {\n      i = _i;\n   }\n   public static void Main()\n   {\n      \n   }\n}\n"
  },
  {
    "path": "Units/csharp-review-needed.r/property.cs.t/expected.tags",
    "content": "Counter\tinput.cs\t/^   public static int Counter $/;\"\tp\tclass:Employee\nEmployee\tinput.cs\t/^   public Employee() $/;\"\tm\tclass:Employee\nEmployee\tinput.cs\t/^public class Employee $/;\"\tc\nMain\tinput.cs\t/^   public static void Main() $/;\"\tm\tclass:MainClass\nMainClass\tinput.cs\t/^public class MainClass$/;\"\tc\nName\tinput.cs\t/^   public string Name $/;\"\tp\tclass:Employee\ncounter\tinput.cs\t/^   private static int counter;$/;\"\tf\tclass:Employee\tfile:\nname\tinput.cs\t/^   private string name;$/;\"\tf\tclass:Employee\tfile:\nnumberOfEmployees\tinput.cs\t/^   public static int numberOfEmployees;$/;\"\tf\tclass:Employee\n"
  },
  {
    "path": "Units/csharp-review-needed.r/property.cs.t/input.cs",
    "content": "// property.cs\n// Properties\nusing System;\npublic class Employee \n{\n   public static int numberOfEmployees;\n   private static int counter;\n   private string name;\n\n   // A read-write instance property:\n   public string Name \n   {\n      get \n      {\n         return name; \n      }\n      set \n      {\n         name = value; \n      }\n   }\n\n   // A read-only static property:\n   public static int Counter \n   {\n      get \n      {\n         return counter; \n      }\n   }\n\n   // Constructor:\n   public Employee() \n   {\n      // Calculate the employee's number:\n      counter = ++counter + numberOfEmployees;\n   }\n}\n\npublic class MainClass\n{\n   public static void Main() \n   {\n      Employee.numberOfEmployees = 100;\n      Employee e1 = new Employee();\n      e1.Name = \"Claude Vige\";  \n      Console.WriteLine(\"Employee number: {0}\", Employee.Counter);\n      Console.WriteLine(\"Employee name: {0}\", e1.Name);\n   }\n}\n"
  },
  {
    "path": "Units/extension-with-template-suffix.d/expected.tags",
    "content": "main\tinput.c.in\t/^main (void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/extension-with-template-suffix.d/input.c.in",
    "content": "int\nmain (void)\n{\n  return 0;\n}\n"
  },
  {
    "path": "Units/extra-anonymous.d/args.ctags",
    "content": "--sort=no\n--extras=+{anonymous}\n--fields=+{extras}\n"
  },
  {
    "path": "Units/extra-anonymous.d/expected.tags",
    "content": "__anonf6b77c200108\tinput.c\t/^struct {$/;\"\ts\tfile:\textras:fileScope,anonymous\nx\tinput.c\t/^  int x;$/;\"\tm\tstruct:__anonf6b77c200108\ttyperef:typename:int\tfile:\textras:fileScope\n__anonf6b77c20020a\tinput.c\t/^union {$/;\"\tu\tfile:\textras:fileScope,anonymous\nx\tinput.c\t/^  int x;$/;\"\tm\tunion:__anonf6b77c20020a\ttyperef:typename:int\tfile:\textras:fileScope\n__anonf6b77c200303\tinput.c\t/^enum {$/;\"\tg\tfile:\textras:fileScope,anonymous\nX\tinput.c\t/^  X;$/;\"\te\tenum:__anonf6b77c200303\tfile:\textras:fileScope\nClass2\tinput-0.js\t/^var Class2 = function() {$/;\"\tc\nc2m1\tinput-0.js\t/^  this.c2m1 = function() {$/;\"\tm\tclass:Class2\nanonymousFunctiond33a4a170300\tinput-0.js\t/^    c2m3(function() {$/;\"\tf\tmethod:Class2.c2m1\textras:anonymous\nClass3\tinput-0.js\t/^var Class3 = function() {$/;\"\tc\nc3m1\tinput-0.js\t/^  this.c3m1 = function() {$/;\"\tm\tclass:Class3\nanonymousFunctiond33a4a170600\tinput-0.js\t/^    return function(n) {$/;\"\tf\tmethod:Class3.c3m1\textras:anonymous\nf1\tinput-0.js\t/^function f1(y) {$/;\"\tf\nanonymousFunctiond33a4a170700\tinput-0.js\t/^  return function(x) {$/;\"\tf\tfunction:f1\textras:anonymous\nMixin\tinput-0.js\t/^function Mixin(superclass) {$/;\"\tc\nAnonymousClassd33a4a170801\tinput-0.js\t/^  return class extends superclass {$/;\"\tc\tclass:Mixin\textras:anonymous\nhello\tinput-0.js\t/^    hello() {$/;\"\tm\tclass:Mixin.AnonymousClassd33a4a170801\nAnonymousClassd33a4a170901\tinput-0.js\t/^class {$/;\"\tc\textras:anonymous\nmethod8\tinput-0.js\t/^\tmethod8(n) { return n * n; }$/;\"\tm\tclass:AnonymousClassd33a4a170901\n"
  },
  {
    "path": "Units/extra-anonymous.d/input-0.js",
    "content": "var Class2 = function() {\n  this.c2m1 = function() {\n    c2m3(function() {\n      return { 'test': {} };\n    });\n  };\n};\n\nvar Class3 = function() {\n  this.c3m1 = function() {\n    return function(n) {\n      if (n == 42) {\n        return 0;\n      } else {\n        return (n + 1) % 42;\n      }\n    };\n  };\n}\n\nfunction f1(y) {\n  return function(x) {\n    return x*y;\n  }\n}\n\nfunction Mixin(superclass) {\n  return class extends superclass {\n    hello() {\n      return \"hello from mixin\";\n    }\n  }\n}\n\nclass {\n\tmethod8(n) { return n * n; }\n}\n\n"
  },
  {
    "path": "Units/extra-anonymous.d/input.c",
    "content": "struct {\n  int x;\n};\n\nunion {\n  int x;\n};\n\nenum {\n  X;\n};\n"
  },
  {
    "path": "Units/extra-disabling-anonymous.d/args.ctags",
    "content": "--sort=no\n--extras=-{anonymous}\n--fields=+{extras}\n"
  },
  {
    "path": "Units/extra-disabling-anonymous.d/expected.tags",
    "content": "x\tinput.c\t/^  int x;$/;\"\tm\tstruct:__anon335cadda0108\ttyperef:typename:int\tfile:\textras:fileScope\nx\tinput.c\t/^  int x;$/;\"\tm\tunion:__anon335cadda020a\ttyperef:typename:int\tfile:\textras:fileScope\nX\tinput.c\t/^  X;$/;\"\te\tenum:__anon335cadda0303\tfile:\textras:fileScope\nClass2\tinput-0.js\t/^var Class2 = function() {$/;\"\tc\nc2m1\tinput-0.js\t/^  this.c2m1 = function() {$/;\"\tm\tclass:Class2\nClass3\tinput-0.js\t/^var Class3 = function() {$/;\"\tc\nc3m1\tinput-0.js\t/^  this.c3m1 = function() {$/;\"\tm\tclass:Class3\nf1\tinput-0.js\t/^function f1(y) {$/;\"\tf\nMixin\tinput-0.js\t/^function Mixin(superclass) {$/;\"\tc\nhello\tinput-0.js\t/^    hello() {$/;\"\tm\tclass:Mixin.AnonymousClass2503d9910801\nmethod8\tinput-0.js\t/^\tmethod8(n) { return n * n; }$/;\"\tm\tclass:AnonymousClass2503d9910901\n"
  },
  {
    "path": "Units/extra-disabling-anonymous.d/input-0.js",
    "content": "var Class2 = function() {\n  this.c2m1 = function() {\n    c2m3(function() {\n      return { 'test': {} };\n    });\n  };\n};\n\nvar Class3 = function() {\n  this.c3m1 = function() {\n    return function(n) {\n      if (n == 42) {\n        return 0;\n      } else {\n        return (n + 1) % 42;\n      }\n    };\n  };\n}\n\nfunction f1(y) {\n  return function(x) {\n    return x*y;\n  }\n}\n\nfunction Mixin(superclass) {\n  return class extends superclass {\n    hello() {\n      return \"hello from mixin\";\n    }\n  }\n}\n\nclass {\n\tmethod8(n) { return n * n; }\n}\n\n"
  },
  {
    "path": "Units/extra-disabling-anonymous.d/input.c",
    "content": "struct {\n  int x;\n};\n\nunion {\n  int x;\n};\n\nenum {\n  X;\n};\n"
  },
  {
    "path": "Units/extra-file-scope-option.d/args.ctags",
    "content": "--extras=-F\n"
  },
  {
    "path": "Units/extra-file-scope-option.d/expected.tags",
    "content": "y\tinput.c\t/^       void y(void) {}$/;\"\tf\ttyperef:typename:void\n"
  },
  {
    "path": "Units/extra-file-scope-option.d/input.c",
    "content": "static void x(void) {}\n       void y(void) {}\n"
  },
  {
    "path": "Units/extra-total-lines.d/args.ctags",
    "content": "# `f' is optional\n# There was a bug that `.' was disabled when `f' was specified together.\n\n## This test case lost the original aim when\n## `.` extra field is replaced with `end:` field.\n\n--extras=+f\n--fields=+e\n--excmd=number\n"
  },
  {
    "path": "Units/extra-total-lines.d/expected.tags",
    "content": "input.c\tinput.c\t1;\"\tF\tend:6\nmain\tinput.c\t2;\"\tf\ttyperef:typename:int\tend:5\n"
  },
  {
    "path": "Units/extra-total-lines.d/foo.h",
    "content": "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz\n"
  },
  {
    "path": "Units/extra-total-lines.d/input.c",
    "content": "# 1 \"./foo.h\"\nint main(void)\n{\n  return 0;\n}\n/* comment */\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/bidirectional.d/args.ctags",
    "content": "--sort=no\n--fields=+{language}\n\n--langdef=Base\n--map-Base=.base\n--kinddef-Base=b,basefunc,functions in Base language\n--regex-Base=/(^[a-z0-9]+)\\(/\\1/b/\n\n--langdef=Sub{base=Base}{bidirectional}\n--map-Sub=.sub\n--kinddef-Sub=s,subdef,definitions in Sub language\n--regex-Sub=/[ \\t]*@def[ \\t]+([a-z0-9]+).*;$/\\1/d/\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/bidirectional.d/expected.tags",
    "content": "f\tinput.base\t/^f() [$/;\"\tb\tlanguage:Base\nv\tinput.base\t/^\t@def v 1;$/;\"\td\tlanguage:Sub\nf0\tinput-0.sub\t/^f0() [$/;\"\tb\tlanguage:Base\nv0\tinput-0.sub\t/^\t@def v0 1;$/;\"\td\tlanguage:Sub\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/bidirectional.d/input-0.sub",
    "content": "f0() [\n\t@def v0 1;\n]\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/bidirectional.d/input.base",
    "content": "f() [\n\t@def v 1;\n]\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/dedicated.d/args.ctags",
    "content": "--sort=no\n--fields=+{language}\n\n--langdef=Base\n--map-Base=.base\n--kinddef-Base=b,basefunc,functions in Base language\n--regex-Base=/(^[a-z0-9]+)\\(/\\1/b/\n\n--langdef=Sub{base=Base}{dedicated}\n--map-Sub=.sub\n--kinddef-Sub=s,subdef,definitions in Sub language\n--regex-Sub=/[ \\t]*@def[ \\t]+([a-z0-9]+).*;$/\\1/d/\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/dedicated.d/expected.tags",
    "content": "f\tinput.base\t/^f() [$/;\"\tb\tlanguage:Base\nf0\tinput-0.sub\t/^f0() [$/;\"\tb\tlanguage:Base\nv0\tinput-0.sub\t/^\t@def v0 1;$/;\"\td\tlanguage:Sub\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/dedicated.d/input-0.sub",
    "content": "f0() [\n\t@def v0 1;\n]\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/dedicated.d/input.base",
    "content": "f() [\n\t@def v 1;\n]\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/default.d/args.ctags",
    "content": "--sort=no\n--fields=+{language}\n\n--langdef=Base\n--map-Base=.base\n--kinddef-Base=b,basefunc,functions in Base language\n--regex-Base=/(^[a-z0-9]+)\\(/\\1/b/\n\n--langdef=Sub{base=Base}\n--map-Sub=.sub\n--kinddef-Sub=s,subdef,definitions in Sub language\n--regex-Sub=/[ \\t]*@def[ \\t]+([a-z0-9]+).*;$/\\1/d/\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/default.d/expected.tags",
    "content": "f\tinput.base\t/^f() [$/;\"\tb\tlanguage:Base\nv\tinput.base\t/^\t@def v 1;$/;\"\td\tlanguage:Sub\nv0\tinput-0.sub\t/^\t@def v0 1;$/;\"\td\tlanguage:Sub\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/default.d/input-0.sub",
    "content": "f0() [\n\t@def v0 1;\n]\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/default.d/input.base",
    "content": "f() [\n\t@def v 1;\n]\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/shared.d/args.ctags",
    "content": "--sort=no\n--fields=+{language}\n\n--langdef=Base\n--map-Base=.base\n--kinddef-Base=b,basefunc,functions in Base language\n--regex-Base=/(^[a-z0-9]+)\\(/\\1/b/\n\n--langdef=Sub{base=Base}{shared}\n--map-Sub=.sub\n--kinddef-Sub=s,subdef,definitions in Sub language\n--regex-Sub=/[ \\t]*@def[ \\t]+([a-z0-9]+).*;$/\\1/d/\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/shared.d/expected.tags",
    "content": "f\tinput.base\t/^f() [$/;\"\tb\tlanguage:Base\nv\tinput.base\t/^\t@def v 1;$/;\"\td\tlanguage:Sub\nv0\tinput-0.sub\t/^\t@def v0 1;$/;\"\td\tlanguage:Sub\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/shared.d/input-0.sub",
    "content": "f0() [\n\t@def v0 1;\n]\n"
  },
  {
    "path": "Units/flags-langdef-directions.r/shared.d/input.base",
    "content": "f() [\n\t@def v 1;\n]\n"
  },
  {
    "path": "Units/foreign-tags.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+rlK\n\n--_roledef-C.f=documented,documented in a API document\n\n--langdef=DocC{_foreignLanguage=C}\n--map-DocC=.docc\n--regex-DocC=/^- +function: *([a-zA-Z_][a-zA-Z_0-9]+)\\(/\\1/f/{_language=C}{_role=documented}\n"
  },
  {
    "path": "Units/foreign-tags.d/expected.tags",
    "content": "compress\tinput.docc\t/^- function: compress(const char *plain_text, enum algorithm alg) => char *$/;\"\tfunction\tlanguage:C\troles:documented\ndecompress\tinput.docc\t/^- function: decompress(const char *compressed_byteseq) => char *$/;\"\tfunction\tlanguage:C\troles:documented\n"
  },
  {
    "path": "Units/foreign-tags.d/input.docc",
    "content": "- function: compress(const char *plain_text, enum algorithm alg) => char *\n  Compress a C string PLAING_TEXT with the algorithm specified with ALG.\n\n- function: decompress(const char *compressed_byteseq) => char *\n  Decompress a byte sequence compressed by compress().\n"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/README",
    "content": "With compiling ctags with -DDEBUG option, Assert macros are\nenabled. Current -DDEBUG is given by default.\n\nThe fuzz target could make some assertions false for -DDEBUG\nctags. This directory contains such unwanted inputs found by the\ntarget. They are minimized by SHRINK=1.\n\nLet's fix them!\nDon't forget rename .b directory to .d.\n"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/csharp-fha-0.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/csharp-fha-0.d/input.cs",
    "content": "r PARAM = 1;"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/d-fha-0.d/README",
    "content": "Because the input is invalid as D lagnauge source code.\nFor this input parser cannot build proper scope information.\n\nexpected.tags in this directory is just placeholder. Nothing is\nexpected for invalid input.\n"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/d-fha-0.d/expected.tags",
    "content": "T\tinput.d\t/^template(){T;$/;\"\tm\tfile:\n"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/d-fha-0.d/input.d",
    "content": "template(){T;\n"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/eiffel-fha-0.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/eiffel-fha-0.d/input.e",
    "content": "_"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/java-fha-0.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/java-fha-0.d/input.java",
    "content": "r PARAM = 1;"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/systemverilog-fha-0.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/systemverilog-fha-0.d/input.sv",
    "content": "int\n"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/vera-fha-0.d/expected.tags",
    "content": "iA\tinput.vr\t/^interface iA {/;\"\ti\n"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/vera-fha-0.d/input.vr",
    "content": "interface iA {"
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/verilog-fha-0.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/fuzz-hitting-assertions.r/verilog-fha-0.d/input.v",
    "content": "input\n"
  },
  {
    "path": "Units/guest-in-optlib-single-line.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+ln\n\n--langdef=single\n--map-single=.single\n\n--kinddef-single=d,def,definitions\n\n--regex-single=/^DEF:([a-zA-Z0-9]+)/\\1/d\n\n--regex-single=/^BEGIN:([a-zA-Z0-9]+)$//{_guest=\\1,0end,}\n--regex-single=/^BEGIN$//{_guest=,0end,}\n--regex-single=/^END:([a-zA-Z0-9]+)$//{_guest=\\1,,0start}\n--regex-single=/^END$//{_guest=,,0start}\n\n--regex-single=/^BEGIN_FILE:([a-zA-Z0-9.]+)$//{_guest=*1,0end,}\n--regex-single=/^BEGIN_FILE$//{_guest=,0end,}\n--regex-single=/^END_FILE:([a-zA-Z0-9.]+)$//{_guest=*1,,0start}\n--regex-single=/^END_FILE$//{_guest=,,0start}\n\n--regex-single=/^BEGIN_C$//{_guest=C,0end,}\n--regex-single=/^END_C$//{_guest=C,,0start}\n\n--regex-single=/^(BEGIN:([a-zA-Z0-9]+)<).*(>END)$//{_guest=\\2,1end,3start}\n--regex-single=/^BEGIN_FILE:([a-zA-Z0-9.]+)<(.*)>END_FILE$//{_guest=*1,2start,2end}\n--regex-single=/^(BEGIN_C<).*(>END_C)$//{_guest=C,1end,2start}\n"
  },
  {
    "path": "Units/guest-in-optlib-single-line.d/expected.tags",
    "content": "S0\tinput.single\t/^DEF:S0$/;\"\tr\tline:1\tlanguage:single\nE0\tinput.single\t/^DEF:E0$/;\"\tr\tline:7\tlanguage:single\nS1\tinput.single\t/^DEF:S1$/;\"\tr\tline:10\tlanguage:single\nE1\tinput.single\t/^DEF:E1$/;\"\tr\tline:16\tlanguage:single\nS2\tinput.single\t/^DEF:S2$/;\"\tr\tline:18\tlanguage:single\nE2\tinput.single\t/^DEF:E2$/;\"\tr\tline:24\tlanguage:single\nS3\tinput.single\t/^DEF:S3$/;\"\tr\tline:26\tlanguage:single\nE3\tinput.single\t/^DEF:E3$/;\"\tr\tline:32\tlanguage:single\nS4\tinput.single\t/^DEF:S4$/;\"\tr\tline:34\tlanguage:single\nE4\tinput.single\t/^DEF:E4$/;\"\tr\tline:43\tlanguage:single\nS5\tinput.single\t/^DEF:S5$/;\"\tr\tline:45\tlanguage:single\nE5\tinput.single\t/^DEF:E5$/;\"\tr\tline:47\tlanguage:single\nS6\tinput.single\t/^DEF:S6$/;\"\tr\tline:49\tlanguage:single\nE6\tinput.single\t/^DEF:E6$/;\"\tr\tline:51\tlanguage:single\nS7\tinput.single\t/^DEF:S7$/;\"\tr\tline:53\tlanguage:single\nE7\tinput.single\t/^DEF:E7$/;\"\tr\tline:55\tlanguage:single\nf0\tinput.single\t/^(defun f0 () (list))$/;\"\tf\tline:4\tlanguage:Lisp\nf1\tinput.single\t/^(defun f1 () (list))$/;\"\tf\tline:13\tlanguage:Lisp\nf2\tinput.single\t/^(defun f2 () (list))$/;\"\tf\tline:21\tlanguage:Lisp\nf3\tinput.single\t/^(defun f3 () (list))$/;\"\tf\tline:29\tlanguage:Lisp\nf4\tinput.single\t/^int f4 (void)$/;\"\tf\tline:37\tlanguage:C\ttyperef:typename:int\nf5\tinput.single\t/(defun f5 () (list))/;\"\tf\tline:46\tlanguage:Lisp\nf6\tinput.single\t/(defun f6 () (list))/;\"\tf\tline:50\tlanguage:Lisp\nf7\tinput.single\t/int f7 (void) { return 0; }/;\"\tf\tline:54\tlanguage:C\ttyperef:typename:int\nv0\tinput-0.single\t/(defvar v0 0/;\"\tv\tline:1\tlanguage:Lisp\ng0\tinput-1.single\t/^(defun g0 () (list))$/;\"\tf\tline:2\tlanguage:Lisp\ng1\tinput-1.single\t/^int g1 (void) { return 0; }$/;\"\tf\tline:6\tlanguage:C\ttyperef:typename:int\ng2\tinput-1.single\t/^function g2$/;\"\tf\tline:10\tlanguage:Sh\nEOF\tinput-1.single\t/^\tcat > foo.rst <<EOF$/;\"\th\tline:12\tlanguage:Sh\nG2 on g2\tinput-1.single\t/^G2 on g2$/;\"\tH\tline:14\tlanguage:ReStructuredText\nf\tinput-2.single\t/^f()$/;\"\tf\tline:4\tlanguage:Sh\n"
  },
  {
    "path": "Units/guest-in-optlib-single-line.d/input-0.single",
    "content": "BEGIN:lisp<(defvar v0 0>END\n"
  },
  {
    "path": "Units/guest-in-optlib-single-line.d/input-1.single",
    "content": "BEGIN:lisp\n(defun g0 () (list))\nEND\n\nBEGIN:C\nint g1 (void) { return 0; }\nEND\n\nBEGIN:Sh\nfunction g2\n{\n\tcat > foo.rst <<EOF\n==================\nG2 on g2\n==================\nEOF\n}\nEND\n"
  },
  {
    "path": "Units/guest-in-optlib-single-line.d/input-2.single",
    "content": "ksh is an alias for Sh parser.\n\nBEGIN:ksh\nf()\n{\n\techo x\n}\nEND\n"
  },
  {
    "path": "Units/guest-in-optlib-single-line.d/input.single",
    "content": "DEF:S0\n\nBEGIN:lisp\n(defun f0 () (list))\nEND\n\nDEF:E0\n\n\nDEF:S1\n\nBEGIN\n(defun f1 () (list))\nEND:lisp\n\nDEF:E1\n\nDEF:S2\n\nBEGIN_FILE:foo.cl\n(defun f2 () (list))\nEND_FILE\n\nDEF:E2\n\nDEF:S3\n\nBEGIN_FILE\n(defun f3 () (list))\nEND_FILE:foo.cl\n\nDEF:E3\n\nDEF:S4\n\nBEGIN_C\nint f4 (void)\n{\n\treturn 0;\n}\nEND_C\n\nDEF:E4\n\nDEF:S5\nBEGIN:lisp<(defun f5 () (list))>END\nDEF:E5\n\nDEF:S6\nBEGIN_FILE:bar.cl<(defun f6 () (list))>END_FILE\nDEF:E6\n\nDEF:S7\nBEGIN_C<int f7 (void) { return 0; }>END_C\nDEF:E7\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-after-shbang.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-after-shbang.d/expected.tags",
    "content": "main\tinput.nolang\t/^(define (main args) 1)$/;\"\tf\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-after-shbang.d/input.nolang",
    "content": "#!/bin/sh\n#| -*- scheme -*- |#\n:; exec gosh -- $0 \"$@\"\n(define (main args) 1)\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-eof.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-eof.d/expected.tags",
    "content": "hello-world\tinput.nolang\t/^(defun hello-world () (message \"hello, world\"))$/;\"\tf\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-eof.d/input.nolang",
    "content": "(defun hello-world () (message \"hello, world\"))\n;; Local Variables:\n;; mode: lisp\n;; compile-command: \"cc foo.c -Dfoo=bar -Dhack=whatever \\\n;;   -Dmumble=blaah\"\n;; End:\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n;; aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-firstline0.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-firstline0.d/expected.tags",
    "content": "hello-world\tinput.nolang\t/^(defun hello-world () (message \"hello, world\"))$/;\"\tf\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-firstline0.d/input.nolang",
    "content": ";; -*- mode: Lisp; fill-column: 75; comment-column: 50; -*-\n(defun hello-world () (message \"hello, world\"))\n\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-firstline1.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-firstline1.d/expected.tags",
    "content": "hello\tinput.nolang\t/^hello (void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-emacs-firstline1.d/input.nolang",
    "content": "/* -*- C -*- */\nint\nhello (void)\n{\n  return printf(\"hello, world\\n\");\n}\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim0-head.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim0-head.d/expected.tags",
    "content": "main\tinput.nolang\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim0-head.d/input.nolang",
    "content": "/* ex:set filetype=c.qt: */\nint\nmain(void)\n{\n\treturn 0;\n}\n\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim0-tail.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim0-tail.d/expected.tags",
    "content": "main\tinput.nolang\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim0-tail.d/input.nolang",
    "content": "int\nmain(void)\n{\n\treturn 0;\n}\n\n/* ex:set filetype=c.qt: */\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim1-head.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim1-head.d/expected.tags",
    "content": "main\tinput.nolang\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim1-head.d/input.nolang",
    "content": "/* vim: se noet ft=c.qt: */\n\nint\nmain(void)\n{\n\treturn 0;\n}\n\n\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim1-tail.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim1-tail.d/expected.tags",
    "content": "main\tinput.nolang\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim1-tail.d/input.nolang",
    "content": "int\nmain(void)\n{\n\treturn 0;\n}\n\n/* vim: se noet ft=c.qt: */\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim2-head.d/args.ctags",
    "content": "--fields=+l\n--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim2-head.d/expected.tags",
    "content": "main\tinput.nolang\t/^main(void)$/;\"\tf\tlanguage:C\ttyperef:typename:int\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim2-head.d/input.nolang",
    "content": "\n\n\n// vim: noet ft=first ft=c.qt\nint\nmain(void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim2-tail.d/args.ctags",
    "content": "--fields=+l\n--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim2-tail.d/expected.tags",
    "content": "main\tinput.nolang\t/^main(void)$/;\"\tf\tlanguage:C\ttyperef:typename:int\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-vim2-tail.d/input.nolang",
    "content": "int\nmain(void)\n{\n\treturn 0;\n}\n\n// vim: noet ft=first ft=c.qt\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-zsh-autoload.d/args.ctags",
    "content": "-G\n--fields=+l\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-zsh-autoload.d/expected.tags",
    "content": "_ctags\tinput.nolang\t/^_ctags() {$/;\"\tf\tlanguage:Zsh\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-zsh-autoload.d/input.nolang",
    "content": "#autoload\n_ctags() {\n\t return 0\n}\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-zsh-compdef.d/args.ctags",
    "content": "-G\n--fields=+l\n\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-zsh-compdef.d/expected.tags",
    "content": "_ctags\tinput.nolang\t/^_ctags() {$/;\"\tf\tlanguage:Zsh\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-modeline-zsh-compdef.d/input.nolang",
    "content": "#compdef ctags\n_ctags() {\n\t return 0\n}\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-shebang-python3.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-shebang-python3.d/expected.tags",
    "content": "foo\tinput.nolang\t/^def foo():$/;\"\tf\n"
  },
  {
    "path": "Units/main-guessing.r/nolang-shebang-python3.d/input.nolang",
    "content": "#!/usr/bin/python3\n\ndef foo():\n    pass\n\n"
  },
  {
    "path": "Units/matlab-tg-corpus.d/expected.tags",
    "content": "backtrack\tinput.m\t/^function [xn,fn,fcall] = backtrack(xc,d,fc,fnc,DDfnc,c,gamma,eps)$/;\"\tf\ncDDfnc\tinput.m\t/^        cDDfnc  =  gamma*cDDfnc;$/;\"\tv\ncDDfnc\tinput.m\t/^cDDfnc  =   c*DDfnc;$/;\"\tv\nd\tinput.m\t/^        d       =  gamma*d;$/;\"\tv\nfcall\tinput.m\t/^        fcall   =  fcall+1;$/;\"\tv\nfcall\tinput.m\t/^fcall   =   1 ;$/;\"\tv\nfn\tinput.m\t/^        fn      =  feval(fnc,xn);$/;\"\tv\nfn\tinput.m\t/^fn      =   feval(fnc,xn);$/;\"\tv\nfunc1\tinput.m\t/^function [x,y,z] = func1 $/;\"\tf\nfunc2\tinput.m\t/^function x = func2 $/;\"\tf\nfunc3\tinput.m\t/^function func3 $/;\"\tf\nxn\tinput.m\t/^                        xn  =  xc;$/;\"\tv\nxn\tinput.m\t/^        xn      =  xc+d;$/;\"\tv\nxn\tinput.m\t/^xn      =   xc+d;$/;\"\tv\n"
  },
  {
    "path": "Units/matlab-tg-corpus.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/matlab-tg-corpus.d/input.m",
    "content": "% http://www.math.washington.edu/~burke/crs/516/HTML/backtrack.html\n% Backtracking Linesearch\n\nfunction [xn,fn,fcall] = backtrack(xc,d,fc,fnc,DDfnc,c,gamma,eps)\n%\n%GENERAL DESCRIPTION\n%\n%This function performs the basic backtracking subroutine.\n%The subroutine requires the following input:\n%       xc    = the current point,\n%       d     = the direction of search,\n%       fc    = the current function value,\n%       fnc   = a string variable for the function name,\n%       DDfnc = the directional derivative of fnc at xc in the\n%               direction d, must have  DDfnc < 0,\n%       c     = the slope modification parameter in (0,1),\n%       gamma = the backstepping parameter in (0,1),\n%       eps   = the stopping criteria for norm(xn - xc),\n%               that is, the main algorithm stops when\n%               norm(xn - xc) <= eps.\n%\n%The routine returns\n%       xn  = the new point,\n%       fn  = the function value at the new point,\n%       fnc = the number of calls to fnc.\n%\n%TERMINATION CRITERIA\n%\n%The backtracking is terminated if the step to the new point\n%xn is so small that it triggers termination in the main algorithm,\n%i.e. norm(xc - xn) <= eps. In this case we return xn = xc if\n%fn >= fc (we have not reduced the function value); otherwise,\n%we return xn.\n%\n%THE MATH\n%\n%The backtracking routing attempts to find a step size for\n%reducing the value of the function fnc given the current point xc\n%and a direction d. It does this by successively trying step sizes\n%of the form gamma^s for s = 0,1,2... to find the smallest\n%value of s for which the inequality\n%\n%       fnc(xc+gamma^s*d)\\le fnc(xc)+c*gamma^s*DD\n%\n% is satisfied. The new point to be returned is then given\n% by xn = xc+gamma^s*d.\n%\n%CHECK INPUT SPECIFICATIONS\n%\nif DDfnc >= 0,\n        error('The backtracking subroutine has been sent a direction of nondesce\nnt. Program has been terminated.')\nend\nif c<= 0 | c>= 1,\n        error('The slope modification parameter c in the backtracking subroutine\n is not in (0,1).')\nend\nif gamma<=0 | gamma >=1,\n        error('The backtracking parameter gamma is not in (0,1).')\nend\nif eps <= 0,\n        error('The termination criteria eps sent to the backtracking line search\n is not positive.')\nend\n\n%\n%CHECK DIMENSIONS\n%\nif size(xc)~=size(d)\n        error('The vectors sent to backtrack are not of the same dimension.')\nend\n\n%\n%\n%EXECUTE THE LINE SEARCH\n%\n%\n\nxn      =   xc+d;\ncDDfnc  =   c*DDfnc;\nfn      =   feval(fnc,xn);\nfcall   =   1 ;\n\nwhile fn > fc+cDDfnc,\n        d       =  gamma*d;\n        cDDfnc  =  gamma*cDDfnc;\n        xn      =  xc+d;\n        fn      =  feval(fnc,xn);\n        fcall   =  fcall+1;\n\n%Check if the step to xn is too small.\n        if norm(d) <= eps,\n        disp('linesearch step too small')\n                if fn >= fc,\n                        xn  =  xc;\n                end\n                break\n        end\nend\n\n\nfunction [x,y,z] = func1 \nfunction x = func2 \nfunction func3 \n\n"
  },
  {
    "path": "Units/mtable-simple-with-continuation.d/args.ctags",
    "content": "--fields=+nKZe\n\n--langdef=X\n--langmap=X:.mtable\n--kinddef-X=c,class,classes\n--kinddef-X=n,namespace,namespaces\n\n--_tabledef-X=toplevel\n--_tabledef-X=class\n--_tabledef-X=classEnd\n--_tabledef-X=namespace\n--_tabledef-X=blockHead\n--_tabledef-X=block\n--_tabledef-X=blockEnd\n--_tabledef-X=separator\n\n--_mtable-regex-X=toplevel/class[ \\t\\n]//{tenter=class}\n--_mtable-regex-X=toplevel/namespace[ \\t\\n]//{tenter=namespace}\n--_mtable-regex-X=toplevel/[ \\n\\t]//\n--_mtable-regex-X=toplevel/.//{tenter=separator}\n\n--_mtable-regex-X=separator/[ \\n\\t]//{tleave}\n--_mtable-regex-X=separator/.//\n\n--_mtable-regex-X=class/([a-zA-Z0-9]+)/\\1/c/{tenter=blockHead,classEnd}{scope=push}\n--_mtable-regex-X=class/.//\n\n--_mtable-regex-X=namespace/([a-zA-Z0-9]+)/\\1/n/{tenter=blockHead,classEnd}{scope=push}\n--_mtable-regex-X=namespace/.//\n\n--_mtable-regex-X=blockHead/\\{//{tenter=block,blockEnd}\n--_mtable-regex-X=blockHead/.//\n\n--_mtable-regex-X=block/\\}//{tleave}\n--_mtable-extend-X=block+toplevel\n# --_mtable-regex-X=block/.//\n\n--_mtable-regex-X=classEnd///{tleave}{scope=pop}\n--_mtable-regex-X=blockEnd///{tleave}\n\n--kinds-X=-n\n"
  },
  {
    "path": "Units/mtable-simple-with-continuation.d/expected.tags",
    "content": "a\tinput.mtable\t/^class a$/;\"\tclass\tline:1\tend:4\nc\tinput.mtable\t/^class c$/;\"\tclass\tline:13\tscope:namespace:e\tend:21\nd\tinput.mtable\t/^\tclass d {$/;\"\tclass\tline:17\tscope:class:e.c\tend:19\n"
  },
  {
    "path": "Units/mtable-simple-with-continuation.d/input.mtable",
    "content": "class a\n{\n\t.\n}\n\n\ndummyclass b {\n.\n}\n\nnamespace e {\n\nclass c\n\n\t{ ..\n\n\tclass d {\n\n}\n\n}\n}\n"
  },
  {
    "path": "Units/mtable-simple-with-table-extending.d/args.ctags",
    "content": "--fields=+nKZe\n--sort=no\n\n--langdef=X\n--langmap=X:.mtable\n--kinddef-X=v,var,variables\n--kinddef-X=f,fun,functions\n\n--_tabledef-X=main\n--_tabledef-X=comment_sharp_sa\n--_tabledef-X=comment_sharp_sharp\n--_tabledef-X=char\n--_tabledef-X=string\n--_tabledef-X=varlist\n--_tabledef-X=func\n--_tabledef-X=fbody\n--_tabledef-X=generic\n\n--_mtable-regex-X=generic/\\/\\*//{tenter=comment_sharp_sa}\n--_mtable-regex-X=generic/\\/\\///{tenter=comment_sharp_sharp}\n--_mtable-regex-X=generic/'//{tenter=char}\n--_mtable-regex-X=generic/\"//{tenter=string}\n\n--_mtable-extend-X=main+generic\n--_mtable-regex-X=main/var//{tenter=varlist}\n--_mtable-regex-X=main/function//{tenter=func}\n--_mtable-regex-X=main/.//\n\n--_mtable-regex-X=comment_sharp_sa/\\*\\///{tleave}\n--_mtable-regex-X=comment_sharp_sa/.//\n\n--_mtable-regex-X=comment_sharp_sharp/\\n//{tleave}\n--_mtable-regex-X=comment_sharp_sharp/.//\n\n--_mtable-regex-X=char/'//{tleave}\n--_mtable-regex-X=char/.//\n\n--_mtable-regex-X=string/\"//{tleave}\n--_mtable-regex-X=string/.//\n\n--_mtable-extend-X=varlist+generic\n--_mtable-regex-X=varlist/([a-zA-Z]+)/\\1/v/{scope=ref}\n--_mtable-regex-X=varlist/;//{tleave}\n--_mtable-regex-X=varlist/.//\n\n--_mtable-extend-X=func+generic\n--_mtable-regex-X=func/([a-zA-Z]+)/\\1/f/{scope=push}\n--_mtable-regex-X=func/\\{//{tjump=fbody}\n--_mtable-regex-X=func/.//\n\n--_mtable-extend-X=fbody+generic\n--_mtable-regex-X=fbody/\\}//{tleave}{scope=pop}\n--_mtable-regex-X=fbody/var//{tenter=varlist}\n--_mtable-regex-X=fbody/function//{tenter=func}\n--_mtable-regex-X=fbody/.//\n"
  },
  {
    "path": "Units/mtable-simple-with-table-extending.d/expected.tags",
    "content": "foo\tinput.mtable\t/^function foo$/;\"\tfun\tline:1\tend:17\na\tinput.mtable\t/^\tvar a, b,$/;\"\tvar\tline:3\tscope:fun:foo\nb\tinput.mtable\t/^\tvar a, b,$/;\"\tvar\tline:3\tscope:fun:foo\nc\tinput.mtable\t/^c, e = \"x\";$/;\"\tvar\tline:16\tscope:fun:foo\ne\tinput.mtable\t/^c, e = \"x\";$/;\"\tvar\tline:16\tscope:fun:foo\nbar\tinput.mtable\t/^function bar$/;\"\tfun\tline:19\tend:27\ny\tinput.mtable\t/^\tvar y;$/;\"\tvar\tline:21\tscope:fun:bar\nbaz\tinput.mtable\t/^\tfunction baz$/;\"\tfun\tline:22\tscope:fun:bar\tend:25\nz\tinput.mtable\t/^\t\tvar z;$/;\"\tvar\tline:24\tscope:fun:bar.baz\n"
  },
  {
    "path": "Units/mtable-simple-with-table-extending.d/input.mtable",
    "content": "function foo\n{\n\tvar a, b,\n\n\n/* \n\n, \n\n\n*/\n\n\n// D,\n\nc, e = \"x\";\n}\n\nfunction bar\n{\n\tvar y;\n\tfunction baz\n\t{\n\t\tvar z;\n\t}\n\n}\n\n"
  },
  {
    "path": "Units/mtable-simple.d/args.ctags",
    "content": "--fields=+nKZe\n--sort=no\n\n--langdef=X\n--langmap=X:.mtable\n--kinddef-X=v,var,variables\n--kinddef-X=f,fun,functions\n\n--_tabledef-X=main\n--_tabledef-X=comment_sharp_sa\n--_tabledef-X=comment_sharp_sharp\n--_tabledef-X=char\n--_tabledef-X=string\n--_tabledef-X=varlist\n--_tabledef-X=func\n--_tabledef-X=fbody\n\n--_mtable-regex-X=main/\\/\\*//{tenter=comment_sharp_sa}\n--_mtable-regex-X=main/\\/\\///{tenter=comment_sharp_sharp}\n--_mtable-regex-X=main/'//{tenter=char}\n--_mtable-regex-X=main/\"//{tenter=string}\n--_mtable-regex-X=main/var//{tenter=varlist}\n--_mtable-regex-X=main/function//{tenter=func}\n--_mtable-regex-X=main/.//\n\n--_mtable-regex-X=comment_sharp_sa/\\*\\///{tleave}\n--_mtable-regex-X=comment_sharp_sa/.//\n\n--_mtable-regex-X=comment_sharp_sharp/\\n//{tleave}\n--_mtable-regex-X=comment_sharp_sharp/.//\n\n--_mtable-regex-X=char/'//{tleave}\n--_mtable-regex-X=char/.//\n\n--_mtable-regex-X=string/\"//{tleave}\n--_mtable-regex-X=string/.//\n\n--_mtable-regex-X=varlist/\\/\\*//{tenter=comment_sharp_sa}\n--_mtable-regex-X=varlist/\\/\\///{tenter=comment_sharp_sharp}\n--_mtable-regex-X=varlist/'//{tenter=char}\n--_mtable-regex-X=varlist/\"//{tenter=string}\n--_mtable-regex-X=varlist/([a-zA-Z]+)/\\1/v/{scope=ref}\n--_mtable-regex-X=varlist/;//{tleave}\n--_mtable-regex-X=varlist/.//\n\n--_mtable-regex-X=func/\\/\\*//{tenter=comment_sharp_sa}\n--_mtable-regex-X=func/\\/\\///{tenter=comment_sharp_sharp}\n--_mtable-regex-X=func/'//{tenter=char}\n--_mtable-regex-X=func/\"//{tenter=string}\n--_mtable-regex-X=func/([a-zA-Z]+)/\\1/f/{scope=push}\n--_mtable-regex-X=func/\\{//{tjump=fbody}\n--_mtable-regex-X=func/.//\n\n--_mtable-regex-X=fbody/\\/\\*//{tenter=comment_sharp_sa}\n--_mtable-regex-X=fbody/\\/\\///{tenter=comment_sharp_sharp}\n--_mtable-regex-X=fbody/'//{tenter=char}\n--_mtable-regex-X=fbody/\"//{tenter=string}\n--_mtable-regex-X=fbody/\\}//{tleave}{scope=pop}\n--_mtable-regex-X=fbody/var//{tenter=varlist}\n--_mtable-regex-X=fbody/function//{tenter=func}\n--_mtable-regex-X=fbody/.//\n"
  },
  {
    "path": "Units/mtable-simple.d/expected.tags",
    "content": "foo\tinput.mtable\t/^function foo$/;\"\tfun\tline:1\tend:17\na\tinput.mtable\t/^\tvar a, b,$/;\"\tvar\tline:3\tscope:fun:foo\nb\tinput.mtable\t/^\tvar a, b,$/;\"\tvar\tline:3\tscope:fun:foo\nc\tinput.mtable\t/^c, e = \"x\";$/;\"\tvar\tline:16\tscope:fun:foo\ne\tinput.mtable\t/^c, e = \"x\";$/;\"\tvar\tline:16\tscope:fun:foo\nbar\tinput.mtable\t/^function bar$/;\"\tfun\tline:19\tend:27\ny\tinput.mtable\t/^\tvar y;$/;\"\tvar\tline:21\tscope:fun:bar\nbaz\tinput.mtable\t/^\tfunction baz$/;\"\tfun\tline:22\tscope:fun:bar\tend:25\nz\tinput.mtable\t/^\t\tvar z;$/;\"\tvar\tline:24\tscope:fun:bar.baz\n"
  },
  {
    "path": "Units/mtable-simple.d/input.mtable",
    "content": "function foo\n{\n\tvar a, b,\n\n\n/* \n\n, \n\n\n*/\n\n\n// D,\n\nc, e = \"x\";\n}\n\nfunction bar\n{\n\tvar y;\n\tfunction baz\n\t{\n\t\tvar z;\n\t}\n\n}\n\n"
  },
  {
    "path": "Units/noext-tg-matlab.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/noext-tg-matlab.d/expected.tags",
    "content": "backtrack\tinput.nolang\t/^function [xn,fn,fcall] = backtrack(xc,d,fc,fnc,DDfnc,c,gamma,eps)$/;\"\tf\ncDDfnc\tinput.nolang\t/^        cDDfnc  =  gamma*cDDfnc;$/;\"\tv\ncDDfnc\tinput.nolang\t/^cDDfnc  =   c*DDfnc;$/;\"\tv\nd\tinput.nolang\t/^        d       =  gamma*d;$/;\"\tv\nfcall\tinput.nolang\t/^        fcall   =  fcall+1;$/;\"\tv\nfcall\tinput.nolang\t/^fcall   =   1 ;$/;\"\tv\nfn\tinput.nolang\t/^        fn      =  feval(fnc,xn);$/;\"\tv\nfn\tinput.nolang\t/^fn      =   feval(fnc,xn);$/;\"\tv\nfunc1\tinput.nolang\t/^function [x,y,z] = func1 $/;\"\tf\nfunc2\tinput.nolang\t/^function x = func2 $/;\"\tf\nfunc3\tinput.nolang\t/^function func3 $/;\"\tf\nxn\tinput.nolang\t/^                        xn  =  xc;$/;\"\tv\nxn\tinput.nolang\t/^        xn      =  xc+d;$/;\"\tv\nxn\tinput.nolang\t/^xn      =   xc+d;$/;\"\tv\n"
  },
  {
    "path": "Units/noext-tg-matlab.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/noext-tg-matlab.d/input.nolang",
    "content": "% -*- matlab -*-\n% http://www.math.washington.edu/~burke/crs/516/HTML/backtrack.html\n% Backtracking Linesearch\n\nfunction [xn,fn,fcall] = backtrack(xc,d,fc,fnc,DDfnc,c,gamma,eps)\n%\n%GENERAL DESCRIPTION\n%\n%This function performs the basic backtracking subroutine.\n%The subroutine requires the following input:\n%       xc    = the current point,\n%       d     = the direction of search,\n%       fc    = the current function value,\n%       fnc   = a string variable for the function name,\n%       DDfnc = the directional derivative of fnc at xc in the\n%               direction d, must have  DDfnc < 0,\n%       c     = the slope modification parameter in (0,1),\n%       gamma = the backstepping parameter in (0,1),\n%       eps   = the stopping criteria for norm(xn - xc),\n%               that is, the main algorithm stops when\n%               norm(xn - xc) <= eps.\n%\n%The routine returns\n%       xn  = the new point,\n%       fn  = the function value at the new point,\n%       fnc = the number of calls to fnc.\n%\n%TERMINATION CRITERIA\n%\n%The backtracking is terminated if the step to the new point\n%xn is so small that it triggers termination in the main algorithm,\n%i.e. norm(xc - xn) <= eps. In this case we return xn = xc if\n%fn >= fc (we have not reduced the function value); otherwise,\n%we return xn.\n%\n%THE MATH\n%\n%The backtracking routing attempts to find a step size for\n%reducing the value of the function fnc given the current point xc\n%and a direction d. It does this by successively trying step sizes\n%of the form gamma^s for s = 0,1,2... to find the smallest\n%value of s for which the inequality\n%\n%       fnc(xc+gamma^s*d)\\le fnc(xc)+c*gamma^s*DD\n%\n% is satisfied. The new point to be returned is then given\n% by xn = xc+gamma^s*d.\n%\n%CHECK INPUT SPECIFICATIONS\n%\nif DDfnc >= 0,\n        error('The backtracking subroutine has been sent a direction of nondesce\nnt. Program has been terminated.')\nend\nif c<= 0 | c>= 1,\n        error('The slope modification parameter c in the backtracking subroutine\n is not in (0,1).')\nend\nif gamma<=0 | gamma >=1,\n        error('The backtracking parameter gamma is not in (0,1).')\nend\nif eps <= 0,\n        error('The termination criteria eps sent to the backtracking line search\n is not positive.')\nend\n\n%\n%CHECK DIMENSIONS\n%\nif size(xc)~=size(d)\n        error('The vectors sent to backtrack are not of the same dimension.')\nend\n\n%\n%\n%EXECUTE THE LINE SEARCH\n%\n%\n\nxn      =   xc+d;\ncDDfnc  =   c*DDfnc;\nfn      =   feval(fnc,xn);\nfcall   =   1 ;\n\nwhile fn > fc+cDDfnc,\n        d       =  gamma*d;\n        cDDfnc  =  gamma*cDDfnc;\n        xn      =  xc+d;\n        fn      =  feval(fnc,xn);\n        fcall   =  fcall+1;\n\n%Check if the step to xn is too small.\n        if norm(d) <= eps,\n        disp('linesearch step too small')\n                if fn >= fc,\n                        xn  =  xc;\n                end\n                break\n        end\nend\n\n\nfunction [x,y,z] = func1 \nfunction x = func2 \nfunction func3 \n\n"
  },
  {
    "path": "Units/noext-tg-objc.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/noext-tg-objc.d/expected.tags",
    "content": "FileTree\tinput.nolang\t/^@implementation FileTree$/;\"\tI\nFolderTree\tinput.nolang\t/^@implementation FolderTree$/;\"\tI\nMyClass\tinput.nolang\t/^@implementation MyClass$/;\"\tI\naddChild:\tinput.nolang\t/^- (FolderTree*)addChild:(FileTree*)subTree$/;\"\tm\timplementation:FolderTree\ncreateFileList:atPlace:\tinput.nolang\t/^+ (void) createFileList: (NSString*)root atPlace:(FolderTree*)parentFolder$/;\"\tc\timplementation:FolderTree\ncreateLayoutTree\tinput.nolang\t/^- (LayoutTree*)createLayoutTree$/;\"\tm\timplementation:FileTree\ncreateLayoutTree\tinput.nolang\t/^- (LayoutTree*)createLayoutTree$/;\"\tm\timplementation:FolderTree\ndealloc\tinput.nolang\t/^- (void)dealloc$/;\"\tm\timplementation:FileTree\ndealloc\tinput.nolang\t/^- (void)dealloc$/;\"\tm\timplementation:FolderTree\ngetDiskSize\tinput.nolang\t/^- (FileSize)getDiskSize$/;\"\tm\timplementation:FileTree\ninitWithName:andSize:atPlace:\tinput.nolang\t/^- (id)initWithName:(NSString*)treeName$/;\"\tm\timplementation:FileTree\ninitWithName:atPlace:\tinput.nolang\t/^- (id)initWithName:(NSString*)treeName$/;\"\tm\timplementation:FileTree\ninitWithName:atPlace:\tinput.nolang\t/^- (id)initWithName:(NSString*)treeName$/;\"\tm\timplementation:FolderTree\nmain\tinput.nolang\t/^int main(int argc, char** argv)$/;\"\tf\nmyClassMethod:with:\tinput.nolang\t/^+ (void)myClassMethod:(int)arg1 with:(id)arg2;$/;\"\tc\timplementation:MyClass\nmyInstanceMethod:with:\tinput.nolang\t/^- (void)myInstanceMethod:(int)arg1 with:(id)arg2;$/;\"\tm\timplementation:MyClass\npopulateChildList:\tinput.nolang\t/^- (void) populateChildList:(NSString*)root$/;\"\tm\timplementation:FolderTree\n"
  },
  {
    "path": "Units/noext-tg-objc.d/input.nolang",
    "content": "/* -*- objc -*- */\n#if 0\n// This is ABOUT of Units facility.\n// ABC\n/* ABC */\n/* ABC\n */\n/* ABC\n *\n */\n#include <stdio.h>\n#include \"stdio.h\"\n#include <a/stdio.h>\n#include \"a/stdio.h\"\n#include \"a_stdio.h\"\n#endif\n\nint main(int argc, char** argv)\n{\n  return __pid;\n}\n#endif\n@implementation MyClass\n\n+ (void)myClassMethod:(int)arg1 with:(id)arg2;\n- (void)myInstanceMethod:(int)arg1 with:(id)arg2;\n\n@end\n\n@implementation FileTree\n- (FileSize)getDiskSize\n{\n    return diskSize;\n}\n\n- (id)initWithName:(NSString*)treeName\n           atPlace:(FolderTree*)parentFolder\n{\n    self = [super init];\n\n    diskSize = 0;\n    name = treeName;\n    parent = parentFolder;\n    [name retain];\n    representation = nil;\n\n    return self;\n}\n\n- (id)initWithName:(NSString*)treeName\n           andSize:(FileSize)size\n           atPlace:(FolderTree*)parentFolder\n{\n    self = [super init];\n\n    diskSize = size;\n    name = treeName;\n    parent = parentFolder;\n    [name retain];\n    representation = nil;\n\n    return self;\n}\n\n- (void)dealloc\n{\n    [name release];\n    [representation release];\n    [super dealloc];\n}\n\n- (LayoutTree*)createLayoutTree\n{\n    return nil;\n}\n@end\n\n@implementation FolderTree\n- (id)initWithName:(NSString*)treeName\n           atPlace:(FolderTree*)parentFolder\n{\n    self = [super initWithName:treeName\n                       atPlace:parentFolder];\n\n    children = [[NSMutableArray alloc] init];\n    return self;\n}\n\n- (void)dealloc\n{\n    [children release];\n    [super dealloc];\n}\n\n+ (void) createFileList: (NSString*)root atPlace:(FolderTree*)parentFolder\n{\n\tNSFileManager *localFileManager = [[NSFileManager alloc] init];\n\tNSURL\t\t  *rootUrl = [NSURL fileURLWithPath:root];\n\tNSDirectoryEnumerator *dirEnumerator = [localFileManager enumeratorAtURL:rootUrl\n\t\t\t\t\t\t\t\t\t\t\t\n                                                  includingPropertiesForKeys:[NSArray arrayWithObjects:\n                                                                              NSURLNameKey,\n                                                                              NSURLIsDirectoryKey,\n                                                                              nil]\n\t\t\t\t\t\t\t\t\t\t\t\n                                                                     options:NSDirectoryEnumerationSkipsHiddenFiles\n\t\t\t\t\t\t\t\t\t\t\t\n                                                                errorHandler:nil];\n    \n\tfor (NSURL *theURL in dirEnumerator)\n\t{\n        [theURL getResourceValue:&fileName\n\t\t\t\t\t\t  forKey:NSURLNameKey\n\t\t\t\t\t\t   error:NULL];\n        \n        // Ignore files under the _extras directory\n        if ([isDirectory boolValue]==YES)\n        {\n            [folder populateChildList:root];\n        }\n        else if ([isDirectory boolValue]==NO)\n        {\n            [parentFolder addChild:f];\n        }\t\t\n    }\n}\n\n- (void) populateChildList:(NSString*)root\n{\n    NSString *thisRoot = [[root stringByAppendingString:@\"/\"]\n                                stringByAppendingString:name];\n    \n    [FolderTree createFileList:thisRoot\n                       atPlace:self];\n    \n    for ( FileTree *f in children )\n        diskSize += [f getDiskSize];\n}\n\n- (FolderTree*)addChild:(FileTree*)subTree\n{\n    [children addObject:subTree];\n    return self;\n}\n\n- (LayoutTree*)createLayoutTree\n{\n    return\n        [[LayoutTree alloc] initWithFileList:children\n                                andTotalSize:diskSize];\n}\n@end\n"
  },
  {
    "path": "Units/objc-tg-corpus.d/expected.tags",
    "content": "FileTree\tinput.m\t/^@implementation FileTree$/;\"\tI\nFolderTree\tinput.m\t/^@implementation FolderTree$/;\"\tI\nMyClass\tinput.m\t/^@implementation MyClass$/;\"\tI\naddChild:\tinput.m\t/^- (FolderTree*)addChild:(FileTree*)subTree$/;\"\tm\timplementation:FolderTree\ncreateFileList:atPlace:\tinput.m\t/^+ (void) createFileList: (NSString*)root atPlace:(FolderTree*)parentFolder$/;\"\tc\timplementation:FolderTree\ncreateLayoutTree\tinput.m\t/^- (LayoutTree*)createLayoutTree$/;\"\tm\timplementation:FileTree\ncreateLayoutTree\tinput.m\t/^- (LayoutTree*)createLayoutTree$/;\"\tm\timplementation:FolderTree\ndealloc\tinput.m\t/^- (void)dealloc$/;\"\tm\timplementation:FileTree\ndealloc\tinput.m\t/^- (void)dealloc$/;\"\tm\timplementation:FolderTree\ngetDiskSize\tinput.m\t/^- (FileSize)getDiskSize$/;\"\tm\timplementation:FileTree\ninitWithName:andSize:atPlace:\tinput.m\t/^- (id)initWithName:(NSString*)treeName$/;\"\tm\timplementation:FileTree\ninitWithName:atPlace:\tinput.m\t/^- (id)initWithName:(NSString*)treeName$/;\"\tm\timplementation:FileTree\ninitWithName:atPlace:\tinput.m\t/^- (id)initWithName:(NSString*)treeName$/;\"\tm\timplementation:FolderTree\nmain\tinput.m\t/^int main(int argc, char** argv)$/;\"\tf\nmyClassMethod:with:\tinput.m\t/^+ (void)myClassMethod:(int)arg1 with:(id)arg2;$/;\"\tc\timplementation:MyClass\nmyInstanceMethod:with:\tinput.m\t/^- (void)myInstanceMethod:(int)arg1 with:(id)arg2;$/;\"\tm\timplementation:MyClass\npopulateChildList:\tinput.m\t/^- (void) populateChildList:(NSString*)root$/;\"\tm\timplementation:FolderTree\n"
  },
  {
    "path": "Units/objc-tg-corpus.d/input.m",
    "content": "#if 0\n// This is ABOUT of Units facility.\n// ABC\n/* ABC */\n/* ABC\n */\n/* ABC\n *\n */\n#include <stdio.h>\n#include \"stdio.h\"\n#include <a/stdio.h>\n#include \"a/stdio.h\"\n#include \"a_stdio.h\"\n#endif\n\nint main(int argc, char** argv)\n{\n  return __pid;\n}\n#endif\n@implementation MyClass\n\n+ (void)myClassMethod:(int)arg1 with:(id)arg2;\n- (void)myInstanceMethod:(int)arg1 with:(id)arg2;\n\n@end\n\n@implementation FileTree\n- (FileSize)getDiskSize\n{\n    return diskSize;\n}\n\n- (id)initWithName:(NSString*)treeName\n           atPlace:(FolderTree*)parentFolder\n{\n    self = [super init];\n\n    diskSize = 0;\n    name = treeName;\n    parent = parentFolder;\n    [name retain];\n    representation = nil;\n\n    return self;\n}\n\n- (id)initWithName:(NSString*)treeName\n           andSize:(FileSize)size\n           atPlace:(FolderTree*)parentFolder\n{\n    self = [super init];\n\n    diskSize = size;\n    name = treeName;\n    parent = parentFolder;\n    [name retain];\n    representation = nil;\n\n    return self;\n}\n\n- (void)dealloc\n{\n    [name release];\n    [representation release];\n    [super dealloc];\n}\n\n- (LayoutTree*)createLayoutTree\n{\n    return nil;\n}\n@end\n\n@implementation FolderTree\n- (id)initWithName:(NSString*)treeName\n           atPlace:(FolderTree*)parentFolder\n{\n    self = [super initWithName:treeName\n                       atPlace:parentFolder];\n\n    children = [[NSMutableArray alloc] init];\n    return self;\n}\n\n- (void)dealloc\n{\n    [children release];\n    [super dealloc];\n}\n\n+ (void) createFileList: (NSString*)root atPlace:(FolderTree*)parentFolder\n{\n\tNSFileManager *localFileManager = [[NSFileManager alloc] init];\n\tNSURL\t\t  *rootUrl = [NSURL fileURLWithPath:root];\n\tNSDirectoryEnumerator *dirEnumerator = [localFileManager enumeratorAtURL:rootUrl\n\t\t\t\t\t\t\t\t\t\t\t\n                                                  includingPropertiesForKeys:[NSArray arrayWithObjects:\n                                                                              NSURLNameKey,\n                                                                              NSURLIsDirectoryKey,\n                                                                              nil]\n\t\t\t\t\t\t\t\t\t\t\t\n                                                                     options:NSDirectoryEnumerationSkipsHiddenFiles\n\t\t\t\t\t\t\t\t\t\t\t\n                                                                errorHandler:nil];\n    \n\tfor (NSURL *theURL in dirEnumerator)\n\t{\n        [theURL getResourceValue:&fileName\n\t\t\t\t\t\t  forKey:NSURLNameKey\n\t\t\t\t\t\t   error:NULL];\n        \n        // Ignore files under the _extras directory\n        if ([isDirectory boolValue]==YES)\n        {\n            [folder populateChildList:root];\n        }\n        else if ([isDirectory boolValue]==NO)\n        {\n            [parentFolder addChild:f];\n        }\t\t\n    }\n}\n\n- (void) populateChildList:(NSString*)root\n{\n    NSString *thisRoot = [[root stringByAppendingString:@\"/\"]\n                                stringByAppendingString:name];\n    \n    [FolderTree createFileList:thisRoot\n                       atPlace:self];\n    \n    for ( FileTree *f in children )\n        diskSize += [f getDiskSize];\n}\n\n- (FolderTree*)addChild:(FileTree*)subTree\n{\n    [children addObject:subTree];\n    return self;\n}\n\n- (LayoutTree*)createLayoutTree\n{\n    return\n        [[LayoutTree alloc] initWithFileList:children\n                                andTotalSize:diskSize];\n}\n@end\n"
  },
  {
    "path": "Units/option-add-alias.d/args.ctags",
    "content": "--alias-python=+serpent\n--guess-language-eagerly\n"
  },
  {
    "path": "Units/option-add-alias.d/expected.tags",
    "content": "main\tinput.nolang\t/^def main (args):$/;\"\tf\n"
  },
  {
    "path": "Units/option-add-alias.d/input.nolang",
    "content": "#!/bin/serpent\ndef main (args):\n    print args\n"
  },
  {
    "path": "Units/option-disable-kind-in-both.d/args.ctags",
    "content": "--regex-c=/define (.*);/\\1/f,function/\n--kinds-c=-f\n"
  },
  {
    "path": "Units/option-disable-kind-in-both.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/option-disable-kind-in-both.d/input.c",
    "content": "int\nmain(void)\n{\n  define a;\n  return a;\n}\n"
  },
  {
    "path": "Units/option-disable-kind-in-builtin.d/args.ctags",
    "content": "--regex-c=/define (.*);/\\1/X,XDEFINE/\n--kinds-c=-f\n"
  },
  {
    "path": "Units/option-disable-kind-in-builtin.d/expected.tags",
    "content": "a\tinput.c\t/^  define a;$/;\"\tX\n"
  },
  {
    "path": "Units/option-disable-kind-in-builtin.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/option-disable-kind-in-builtin.d/input.c",
    "content": "int\nmain(void)\n{\n  define a;\n  return a;\n}\n"
  },
  {
    "path": "Units/option-disable-kind-in-regex.d/args.ctags",
    "content": "--regex-c=/define (.*);/\\1/X,XDEFINE/\n--kinds-c=-X\n"
  },
  {
    "path": "Units/option-disable-kind-in-regex.d/expected.tags",
    "content": "main\tinput.c\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/option-disable-kind-in-regex.d/input.c",
    "content": "int\nmain(void)\n{\n  define a;\n  return a;\n}\n"
  },
  {
    "path": "Units/option-extradef.d/args.ctags",
    "content": "--_extradef-Python=main,__main__ entry points\n--extras-Python=+{main}\n--regex-Python=/^if __name__ == '__main__':/__main__/f/{_extra=main}\n--fields=+E\n"
  },
  {
    "path": "Units/option-extradef.d/expected.tags",
    "content": "__main__\tinput.py\t/^if __name__ == '__main__':$/;\"\tf\textras:main\n"
  },
  {
    "path": "Units/option-extradef.d/input.py",
    "content": "#\n#\n#\n\nif __name__ == '__main__':\n    do_something()\n    \n"
  },
  {
    "path": "Units/option-file-tags-no.d/args.ctags",
    "content": "--file-tags=no\n--fields=+K\n"
  },
  {
    "path": "Units/option-file-tags-no.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/option-file-tags-no.d/input.mk",
    "content": ""
  },
  {
    "path": "Units/option-file-tags.d/args.ctags",
    "content": "--file-tags\n--fields=+K\n"
  },
  {
    "path": "Units/option-file-tags.d/expected.tags",
    "content": "input.mk\tinput.mk\t1;\"\tfile\n"
  },
  {
    "path": "Units/option-file-tags.d/input.mk",
    "content": ""
  },
  {
    "path": "Units/option-input-file.d/README",
    "content": "This test case is intended to be run under valgrind for capaturing memory leaks.\n"
  },
  {
    "path": "Units/option-input-file.d/args.ctags",
    "content": "SOMETHING STRING\n"
  },
  {
    "path": "Units/option-input-file.d/expected.tags",
    "content": "main\tinput.c\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/option-input-file.d/input.c",
    "content": "int\nmain(void)\n{\n}\n"
  },
  {
    "path": "Units/option-lang-compatibility.d/args.ctags",
    "content": "--langdef=foo\n--langmap=foo:+.foo\n--regex-foo=/^\\/([a-z]) def$/\\1/d,definition/\n"
  },
  {
    "path": "Units/option-lang-compatibility.d/expected.tags",
    "content": "x\tinput.foo\t/^\\/x def$/;\"\td\ny\tinput.foo\t/^\\/y def$/;\"\td\nz\tinput.foo\t/^\\/z def$/;\"\td\n"
  },
  {
    "path": "Units/option-lang-compatibility.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/option-lang-compatibility.d/input.foo",
    "content": "/x def\n/y def\n/z def\n"
  },
  {
    "path": "Units/option-langmap-ext--ext.d/args.ctags",
    "content": "--langmap=c:.c.x\n"
  },
  {
    "path": "Units/option-langmap-ext--ext.d/expected.tags",
    "content": "main\tinput.x\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/option-langmap-ext--ext.d/input.x",
    "content": "int\nmain(void)\n{\n\treturn 0;\n}"
  },
  {
    "path": "Units/option-langmap-ext--pat-ext.d/args.ctags",
    "content": "--langmap=c:.c(input.zzz).x\n"
  },
  {
    "path": "Units/option-langmap-ext--pat-ext.d/expected.tags",
    "content": "main\tinput.zzz\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/option-langmap-ext--pat-ext.d/input.zzz",
    "content": "int\nmain(void)\n{\n\treturn 0;\n}"
  },
  {
    "path": "Units/option-langmap-ext-pat--ext.d/args.ctags",
    "content": "--langmap=c:.c(input.ZZZ).x\n"
  },
  {
    "path": "Units/option-langmap-ext-pat--ext.d/expected.tags",
    "content": "main\tinput.x\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/option-langmap-ext-pat--ext.d/input.x",
    "content": "int\nmain(void)\n{\n\treturn 0;\n}"
  },
  {
    "path": "Units/option-langmap-pat--ext.d/args.ctags",
    "content": "--langmap=c:(input.YYY).x\n"
  },
  {
    "path": "Units/option-langmap-pat--ext.d/expected.tags",
    "content": "main\tinput.x\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/option-langmap-pat--ext.d/input.x",
    "content": "int\nmain(void)\n{\n\treturn 0;\n}"
  },
  {
    "path": "Units/option-langmap-pat--pat-ext.d/args.ctags",
    "content": "--langmap=c:(input.yyy)(input.zzz).x\n"
  },
  {
    "path": "Units/option-langmap-pat--pat-ext.d/expected.tags",
    "content": "main\tinput.zzz\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/option-langmap-pat--pat-ext.d/input.zzz",
    "content": "int\nmain(void)\n{\n\treturn 0;\n}"
  },
  {
    "path": "Units/option-regex-attaching-role.r/extending-existing-parser.d/args.ctags",
    "content": "#\n# This is an example of capturing reference tags by extending\n# already existing parser.\n# \n# Gauche is an implementation Scheme language.\n# It has a module system.\n#\n# Copyright: 2018 Masatake YAMATO\n# License: GPL-2\n#\n--langdef=myGauche{base=Scheme}\n\n--kinddef-myGauche=m,module,modules\n--_roledef-myGauche.m=used,specified as argument for use\n--_roledef-myGauche.{module}=exported,specified as argument for export\n--_roledef-myGauche.{module}=selected,specified as argument for select\n\n--_tabledef-myGauche=main\n--_tabledef-myGauche=export\n\n\n#\n# MAIN TABLE\n#\n\n# Cut the corners.\n# In serious parser, You should define tables for select-module, define-module and use.\n--_mtable-regex-myGauche=main/\\(define-module[ \\t\\n]+([-a-zA-Z0-9]+)/\\1/m/{tenter=main}{scope=push}\n\n--_mtable-regex-myGauche=main/\\(//{tenter=main}{scope=push}{placeholder}\n--_mtable-regex-myGauche=main/\\)//{tleave}{scope=pop}\n--_mtable-regex-myGauche=main/[ \\t\\n]+//\n\n# Cut the corners.\n--_mtable-regex-myGauche=main/select-module[ \\t\\n]+([-a-zA-Z0-9]+)/\\1/m/{_role=selected}{scope=set}\n--_mtable-regex-myGauche=main/use[ \\t\\n]+([-a-zA-Z0-9]+)/\\1/m/{_role=used}{scope=ref}\n\n--_mtable-regex-myGauche=main/export[ \\t\\n]+//{tenter=export}\n\n# TODO: This fall-back pattern should be implementated in ctags main side as default behaviour.\n--_mtable-regex-myGauche=main/.//\n\n#\n# EXPORT TABLE\n#\n\n--_mtable-regex-myGauche=export/[ \\t\\n]+//\n\n# TODO: Why \\0 is not allowed?\n--_mtable-regex-myGauche=export/([-a-zA-Z0-9]+)/\\1/m/{_role=exported}{scope=ref}\n\n# Return to parent table with ungetc\n--_mtable-regex-myGauche=export/\\)//{_advanceTo=0start}{tleave}\n--_mtable-regex-myGauche=export/.//\n\n\n--extras=+r\n--fields=+r\n\n--fields=+K{scope}{language}\n\n--sort=no\n"
  },
  {
    "path": "Units/option-regex-attaching-role.r/extending-existing-parser.d/expected.tags",
    "content": "foo\tinput.scm\t/^(define-module foo$/;\"\tunknown\tlanguage:Scheme\troles:def\tdefiner:DEFINE-MODULE\nfoobar\tinput.scm\t/^(define (foobar)$/;\"\tfunction\tlanguage:Scheme\troles:def\nfoo\tinput.scm\t/^(define-module foo$/;\"\tmodule\tlanguage:myGauche\troles:def\nbar\tinput.scm\t/^  (use bar)$/;\"\tmodule\tlanguage:myGauche\tscope:module:foo\troles:used\nbaz0\tinput.scm\t/^  (export baz0 baz1))$/;\"\tmodule\tlanguage:myGauche\tscope:module:foo\troles:exported\nbaz1\tinput.scm\t/^  (export baz0 baz1))$/;\"\tmodule\tlanguage:myGauche\tscope:module:foo\troles:exported\nfoo\tinput.scm\t/^(select-module foo)$/;\"\tmodule\tlanguage:myGauche\troles:selected\n"
  },
  {
    "path": "Units/option-regex-attaching-role.r/extending-existing-parser.d/input.scm",
    "content": "(define-module foo\n  (use bar)\n  (export baz0 baz1))\n(select-module foo)\n(define (foobar)\n  1)\n"
  },
  {
    "path": "Units/option-regex-attaching-role.r/standing-alone-line-parser.d/args.ctags",
    "content": "--langdef=FOO\n--map-FOO=.foo\n\n--kinddef-FOO=m,module,modules\n--kinddef-FOO=f,foofile,files written in FOO{_refonly}\n--kinddef-FOO=n,namespace,namespace\n\n--_fielddef-FOO=assocMod,module associated with the namespace\n\n--_roledef-FOO.m=used,refereed as an external module\n--_roledef-FOO.{module}=loaded,loaded into the current name space\n--_roledef-FOO.f=loaded,loaded into the current name space\n\n--regex-FOO=/^defmod +([A-Z]+)/\\1/m/\n--regex-FOO=/^use +([A-Z]+)/\\1/m/{_role=used}\n--regex-FOO=/^load +([A-Z]+)/\\1/m/{_role=loaded}\n--regex-FOO=/^load +\"([^\"]+)\"/\\1/f/{_role=loaded}\n--regex-FOO=/^load-and-use +([A-Z]+)/\\1/m/{_role=loaded}{_role=used}\n\n--regex-FOO=/^use +([A-Z]+) +as +([a-z]+)/\\2/n/{_field=assocMod:\\1}\n--regex-FOO=/^load-and-use +([A-Z]+) +as +([a-z]+)/\\2/n/{_field=assocMod:\\1}\n\n--fields=+r\n--fields-FOO=+{assocMod}\n--extras=+r\n--sort=no\n"
  },
  {
    "path": "Units/option-regex-attaching-role.r/standing-alone-line-parser.d/expected.tags",
    "content": "A\tinput.foo\t/^use A$/;\"\tm\troles:used\nB\tinput.foo\t/^load B$/;\"\tm\troles:loaded\nC.foo\tinput.foo\t/^load \"C.foo\"$/;\"\tf\troles:loaded\nD\tinput.foo\t/^load-and-use D$/;\"\tm\troles:used,loaded\nE\tinput.foo\t/^use E as e$/;\"\tm\troles:used\ne\tinput.foo\t/^use E as e$/;\"\tn\troles:def\tassocMod:E\nF\tinput.foo\t/^load-and-use F as f$/;\"\tm\troles:used,loaded\nf\tinput.foo\t/^load-and-use F as f$/;\"\tn\troles:def\tassocMod:F\nMYMODULE\tinput.foo\t/^defmod MYMODULE$/;\"\tm\troles:def\n"
  },
  {
    "path": "Units/option-regex-attaching-role.r/standing-alone-line-parser.d/input.foo",
    "content": "use A\nload B\nload \"C.foo\"\nload-and-use D\n\nuse E as e\nload-and-use F as f\n\ndefmod MYMODULE\n"
  },
  {
    "path": "Units/option-same-kind-in-regex-and-builtin.d/args.ctags",
    "content": "--regex-c=/define (.*);/\\1/f,function/\n--kinds-c=f\n"
  },
  {
    "path": "Units/option-same-kind-in-regex-and-builtin.d/expected.tags",
    "content": "a\tinput.c\t/^  define a;$/;\"\tf\nmain\tinput.c\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/option-same-kind-in-regex-and-builtin.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/option-same-kind-in-regex-and-builtin.d/input.c",
    "content": "unsigned int level = 42;\nint\nmain(void)\n{\n  define a;\n  return a;\n}\n"
  },
  {
    "path": "Units/optlib-recursive.d/args.ctags",
    "content": "--options=lang\n"
  },
  {
    "path": "Units/optlib-recursive.d/expected.tags",
    "content": "Animal\tinput.cof\t/^class Animal$/;\"\tc\nHorse\tinput.cof\t/^class Horse extends Animal$/;\"\tc\nSnake\tinput.cof\t/^class Snake extends Animal$/;\"\tc\nconstructor\tinput.cof\t/^  constructor: (@name) ->$/;\"\tf\nmove\tinput.cof\t/^  move: (meters) ->$/;\"\tf\nmove\tinput.cof\t/^  move: ->$/;\"\tf\n"
  },
  {
    "path": "Units/optlib-recursive.d/features",
    "content": "option-directory\nregex\n"
  },
  {
    "path": "Units/optlib-recursive.d/input.cof",
    "content": "# Taken from http://coffeescript.org/\n\nclass Animal\n  constructor: (@name) ->\n\n  move: (meters) ->\n    alert @name + \" moved #{meters}m.\"\n\nclass Snake extends Animal\n  move: ->\n    alert \"Slithering...\"\n    super 5\n\nclass Horse extends Animal\n  move: ->\n    alert \"Galloping...\"\n    super 45\n"
  },
  {
    "path": "Units/optlib-recursive.d/optlib/lang/a.ctags",
    "content": "#\n# Taken from https://github.com/fishman/dot_files/blob/master/ctags/.ctags\n#\n--langdef=Cof\n"
  },
  {
    "path": "Units/optlib-recursive.d/optlib/lang/b.ctags",
    "content": "#\n# Taken from https://github.com/fishman/dot_files/blob/master/ctags/.ctags\n#\n--langmap=Cof:.cof\n"
  },
  {
    "path": "Units/optlib-recursive.d/optlib/lang/c.ctags",
    "content": "#\n# Taken from https://github.com/fishman/dot_files/blob/master/ctags/.ctags\n#\n--regex-Cof=/^[ \\t]*class ([a-zA-Z_$][0-9a-zA-Z_.$]*).*$/\\1/c,class/\n"
  },
  {
    "path": "Units/optlib-recursive.d/optlib/lang/d.ctags",
    "content": "#\n# Taken from https://github.com/fishman/dot_files/blob/master/ctags/.ctags\n#\n--regex-Cof=/^[ \\t]*([a-zA-Z_$@][0-9a-zA-Z_$\\.]*)[ \\t]*[:=].*[=-]>.*$/\\1/f,function/\n"
  },
  {
    "path": "Units/optlib-recursive.d/optlib/lang/e.ctags",
    "content": "#\n# Taken from https://github.com/fishman/dot_files/blob/master/ctags/.ctags\n#\n--regex-Cof=/^[ \\t]*([a-zA-Z_$@][0-9a-zA-Z_$\\.]*)[ \\t]*=[^->\\n]*$/\\1/v,variable/\n"
  },
  {
    "path": "Units/optlib-simple.d/args.ctags",
    "content": "--options=coffee.ctags\n"
  },
  {
    "path": "Units/optlib-simple.d/expected.tags",
    "content": "Animal\tinput.coffee\t/^class Animal$/;\"\tc\nHorse\tinput.coffee\t/^class Horse extends Animal$/;\"\tc\nSnake\tinput.coffee\t/^class Snake extends Animal$/;\"\tc\nconstructor\tinput.coffee\t/^  constructor: (@name) ->$/;\"\tf\nmove\tinput.coffee\t/^  move: (meters) ->$/;\"\tf\nmove\tinput.coffee\t/^  move: ->$/;\"\tf\n"
  },
  {
    "path": "Units/optlib-simple.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/optlib-simple.d/input.coffee",
    "content": "# Taken from http://coffeescript.org/\n\nclass Animal\n  constructor: (@name) ->\n\n  move: (meters) ->\n    alert @name + \" moved #{meters}m.\"\n\nclass Snake extends Animal\n  move: ->\n    alert \"Slithering...\"\n    super 5\n\nclass Horse extends Animal\n  move: ->\n    alert \"Galloping...\"\n    super 45\n"
  },
  {
    "path": "Units/optlib-simple.d/optlib/coffee.ctags",
    "content": "#\n# Taken from https://github.com/fishman/dot_files/blob/master/ctags/.ctags\n#\n--langdef=coffee\n--langmap=coffee:.coffee\n--regex-coffee=/^[ \\t]*class ([a-zA-Z_$][0-9a-zA-Z_.$]*).*$/\\1/c,class/\n--regex-coffee=/^[ \\t]*([a-zA-Z_$@][0-9a-zA-Z_$\\.]*)[ \\t]*[:=].*[=-]>.*$/\\1/f,function/\n--regex-coffee=/^[ \\t]*([a-zA-Z_$@][0-9a-zA-Z_$\\.]*)[ \\t]*=[^->\\n]*$/\\1/v,variable/\n"
  },
  {
    "path": "Units/optscript.r/op-access.d/args.ctags",
    "content": "--sort=no\n--langdef=X\n--map-X=.unknown\n--kinddef-X=v,var,variables\n--fields=+{access}\n--regex-X=/^(pub|priv) +var +([a-z]+)$/\\2/v/{{\n    . \\1 (pub) eq {(public)}{(private)} ifelse access:\n    mark . :access {\n      0 string cvs\n      (-) \\2 _buildstring\n      /var _tag _commit pop\n    } {\n      cleartomark\n    } ifelse\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-access.d/expected.tags",
    "content": "x\tinput.unknown\t/^pub var x$/;\"\tv\taccess:public\npublic-x\tinput.unknown\t/^pub var x$/;\"\tv\ny\tinput.unknown\t/^priv var y$/;\"\tv\taccess:private\nprivate-y\tinput.unknown\t/^priv var y$/;\"\tv\n"
  },
  {
    "path": "Units/optscript.r/op-access.d/input.unknown",
    "content": "pub var x\npriv var y\n"
  },
  {
    "path": "Units/optscript.r/op-anongen.d/args.ctags",
    "content": "--sort=no\n--fields=+{extras}{language}\n\n--langdef=Foo{_foreignLanguage=C}\n--map-Foo=.foo\n--kinddef-Foo=a,app,applications\n\n--regex-Foo=/^c:(.)$//{{\n    \\1 /C /struct _anongen /C /struct _foreigntag _commit /anonymous _markextra\n}}\n\n--regex-Foo=/^f:(.)$//{{\n    \\1 /app _anongen /app _tag _commit /anonymous _markextra\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-anongen.d/expected.tags",
    "content": "15263c7700108\tinput.foo\t/^c:1$/;\"\ts\tlanguage:C\textras:anonymous\n25263c7700100\tinput.foo\t/^f:2$/;\"\ta\tlanguage:Foo\textras:anonymous\n"
  },
  {
    "path": "Units/optscript.r/op-anongen.d/input.foo",
    "content": "c:1\nf:2\n"
  },
  {
    "path": "Units/optscript.r/op-end.d/args.ctags",
    "content": "--fields=+en\n\n--langdef=X\n--map-X=.unknown\n--kinddef-X=d,def,definitions\n\n--regex-X=/[ \\t]*def ([a-z])/\\1/d/{exclusive}{{\n\t. _scopetop { scope: } if\n    . _scopeset\n}}\n\n--regex-X=/[ \\t]*(end)//{{\n\t_scopetop {\n        1 _matchloc end:\n        _scopepop\n    } if\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-end.d/expected.tags",
    "content": "a\tinput.unknown\t/^def a$/;\"\td\tline:1\tend:9\nb\tinput.unknown\t/^    def b$/;\"\td\tline:2\tdef:a\tend:4\nc\tinput.unknown\t/^    def c$/;\"\td\tline:5\tdef:a\tend:8\nd\tinput.unknown\t/^     \tdef d$/;\"\td\tline:6\tdef:a.c\tend:7\n"
  },
  {
    "path": "Units/optscript.r/op-end.d/input.unknown",
    "content": "def a\n    def b\n    \t...\n    end\n    def c\n     \tdef d\n\tend\n    end\nend\n\nend\n"
  },
  {
    "path": "Units/optscript.r/op-extras.d/args.ctags",
    "content": "--sort=no\n--fields=+{extras}\n\n--langdef=X\n--map-X=.unknown\n--_tabledef-X=main\n\n--kinddef-X=d,def,definitions\n\n--_extradef-X=foo,...\n--extras-X=+{foo}\n--_extradef-X=bar,...\n--extras-X=-{bar}\n\n--extras=+{subparser}\n--extras=-{reference}\n\n--_prelude-X={{\n\t/maketag0 {\n\t\t/def 1 /start _matchloc _tag _commit\n\t} def\n\t/maketag {\n\t\tmaketag0 pop\n\t} def\n}}\n\n--_mtable-regex-X=main/(a)//{{\n\t/X.foo _extraenabled {\\1} {(A)} ifelse\n\tmaketag\n}}\n\n--_mtable-regex-X=main/(b)//{{\n\t/X.bar _extraenabled {\\1} {(B)} ifelse\n\tmaketag\n}}\n\n--_mtable-regex-X=main/(c)//{{\n\t/subparser _extraenabled {\\1} {(C)} ifelse\n\tmaketag\n}}\n\n--_mtable-regex-X=main/(d)//{{\n\t/reference\t_extraenabled {\\1} {(D)} ifelse\n\tmaketag\n}}\n\n--_mtable-regex-X=main/(e)//{{\n\t(eCommon)   maketag0 /reference _markextra\n\t(a.b.eCommon2)  maketag0 dup /reference _markextra /qualified _markextra\n\t(eLangspec) maketag0 /X.foo _markextra\n\t(eLangspec+Common) maketag0 dup /X.foo _markextra /reference _markextra\n}}\n\n--_mtable-regex-X=main/(x)//{{\n\t{\n\t\t/nosuchextra  _extraenabled\n\t} stopped {\n\t\t(OK:no such extra)\n\t} {\n\t\tpop (thiShouldNotBeTagged)\n\t} ifelse maketag\n}}\n\n--_mtable-regex-X=main/(y)//{{\n\t{\n\t\t/X.nosuchextra\t_extraenabled\n\t} stopped {\n\t\t(OK:no such language extra)\n\t} {\n\t\tpop (thiShouldNotBeTagged)\n\t} ifelse maketag\n}}\n\n--_mtable-regex-X=main/(z)//{{\n\t% this one is for testing _tquit.\n\t_tquit\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-extras.d/expected.tags",
    "content": "a\tinput.unknown\t/^abcdaxyezb$/;\"\td\nB\tinput.unknown\t/^abcdaxyezb$/;\"\td\nc\tinput.unknown\t/^abcdaxyezb$/;\"\td\nD\tinput.unknown\t/^abcdaxyezb$/;\"\td\na\tinput.unknown\t/^abcdaxyezb$/;\"\td\nOK:no such extra\tinput.unknown\t/^abcdaxyezb$/;\"\td\nOK:no such language extra\tinput.unknown\t/^abcdaxyezb$/;\"\td\neCommon\tinput.unknown\t/^abcdaxyezb$/;\"\td\textras:reference\na.b.eCommon2\tinput.unknown\t/^abcdaxyezb$/;\"\td\textras:qualified,reference\neLangspec\tinput.unknown\t/^abcdaxyezb$/;\"\td\textras:foo\neLangspec+Common\tinput.unknown\t/^abcdaxyezb$/;\"\td\textras:reference,foo\n"
  },
  {
    "path": "Units/optscript.r/op-extras.d/input.unknown",
    "content": "abcdaxyezb\n\n"
  },
  {
    "path": "Units/optscript.r/op-inherits.d/args.ctags",
    "content": "--fields=+{inherits}\n--sort=no\n--fields=+{extras}\n\n--langdef=X\n--map-X=.unknown\n\n--kinddef-X=c,class,classes\n\n--regex-X=/^class[ \\t]+([A-Z]+)(<([A-Z]+))?/\\1/c/{scope=push}{{\n   \\3 _isstring {\n      . \\3 inherits:\n   } if\n}}\n\n--regex-X=/[ \\t]*set_paring[ \\t]+([A-Z]+)//{{\n   _scopetop {\n   \\1 inherits:\n   } if\n}}\n\n--regex-X=/[ \\t]*clear_paring//{{\n   _scopetop {\n      false inherits:\n   } if\n}}\n\n--regex-X=/^end//{scope=pop}{placeholder}\n"
  },
  {
    "path": "Units/optscript.r/op-inherits.d/expected.tags",
    "content": "A\tinput.unknown\t/^class A<O$/;\"\tc\tinherits:O\nB\tinput.unknown\t/^class B$/;\"\tc\nC\tinput.unknown\t/^class C<P$/;\"\tc\nD\tinput.unknown\t/^class D$/;\"\tc\tinherits:Q\nE\tinput.unknown\t/^class E<R$/;\"\tc\tinherits:S\n"
  },
  {
    "path": "Units/optscript.r/op-inherits.d/input.unknown",
    "content": "class A<O\nend\n\nclass B\nend\n\nclass C<P\n      clear_paring\nend\n\nclass D\n      set_paring Q\nend\n\nclass E<R\n      set_paring S\nend\n"
  },
  {
    "path": "Units/optscript.r/op-intervaltab.d/args.ctags",
    "content": "--sort=no\n\n--langdef=Foo{base=C}{shared}\n--fields=+lr\n--extras=+r\n\n--kinddef-Foo=r,readhandler,read handlers\n--kinddef-Foo=m,method,methods\n--_roledef-Foo.m=set,set a handler\n--kinddef-Foo=w,writehandler,write handlers\n--kinddef-Foo=s,seekhandler,seek handlers\n--kinddef-Foo=o,openhandler,open handlers\n--kinddef-Foo=R,releasehandler,release handlers\n\n# tag:int\n--regex-Foo=/= ([a-z_]*_read),//{postrun}{{\n   \\1 /readhandler _tag _commit dup\n   _intervaltab {\n      scope:\n   } {\n      pop\n   } ifelse\n}}\n\n# tag:tag\n--regex-Foo=/\\.([a-z_]+)[ \\t]*=//{postrun}{{\n   \\1 /method /set _reftag dup\n   _intervaltab {\n      exch _commit exch scope:\n   } {\n      _commit\n   } ifelse\n}}\n\n# matchloc\n--regex-Foo=/= ([a-z_]*_write),//{postrun}{{\n   \\1 /writehandler _tag _commit\n   @1 _intervaltab {\n      scope:\n   } {\n      pop\n   } ifelse\n}}\n\n--regex-Foo=/= ([a-z_]*_l?lseek),//{postrun}{{\n   \\1 /seekhandler _tag _commit\n   1@ _intervaltab {\n      scope:\n   } {\n      pop\n   } ifelse\n}}\n\n# [line:int]\n--regex-Foo=/= ([a-z_]*_release),//{postrun}{{\n   \\1 /releasehandler _tag _commit\n   [ 1@ _matchloc2line  ] _intervaltab {\n      scope:\n   } {\n      pop\n   } ifelse\n}}\n\n# [startline:int endline:int]\n--regex-Foo=/= ([a-z_]*_open)(,)//{postrun}{{\n   \\1 /openhandler _tag _commit\n   [ 1@ _matchloc2line @2 _matchloc2line ] _intervaltab {\n      scope:\n   } {\n      pop\n   } ifelse\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-intervaltab.d/expected.tags",
    "content": "proc_pid_cmdline_ops\tinput.c\t/^static const struct file_operations proc_pid_cmdline_ops = {$/;\"\tv\tlanguage:C\ttyperef:typename:const struct file_operations\tfile:\troles:def\nproc_lstats_operations\tinput.c\t/^static const struct file_operations proc_lstats_operations = {$/;\"\tv\tlanguage:C\ttyperef:typename:const struct file_operations\tfile:\troles:def\nproc_single_file_operations\tinput.c\t/^static const struct file_operations proc_single_file_operations = {$/;\"\tv\tlanguage:C\ttyperef:typename:const struct file_operations\tfile:\troles:def\nproc_pid_cmdline_read\tinput.c\t/^\t.read\t= proc_pid_cmdline_read,$/;\"\tr\tlanguage:Foo\tvariable:proc_pid_cmdline_ops\troles:def\nread\tinput.c\t/^\t.read\t= proc_pid_cmdline_read,$/;\"\tm\tlanguage:Foo\tvariable:proc_pid_cmdline_ops\troles:set\nllseek\tinput.c\t/^\t.llseek\t= generic_file_llseek,$/;\"\tm\tlanguage:Foo\tvariable:proc_pid_cmdline_ops\troles:set\ngeneric_file_llseek\tinput.c\t/^\t.llseek\t= generic_file_llseek,$/;\"\ts\tlanguage:Foo\tvariable:proc_pid_cmdline_ops\troles:def\nopen\tinput.c\t/^\t.open\t\t= lstats_open,$/;\"\tm\tlanguage:Foo\tvariable:proc_lstats_operations\troles:set\nlstats_open\tinput.c\t/^\t.open\t\t= lstats_open,$/;\"\to\tlanguage:Foo\tvariable:proc_lstats_operations\troles:def\nseq_read\tinput.c\t/^\t.read\t\t= seq_read,$/;\"\tr\tlanguage:Foo\tvariable:proc_lstats_operations\troles:def\nread\tinput.c\t/^\t.read\t\t= seq_read,$/;\"\tm\tlanguage:Foo\tvariable:proc_lstats_operations\troles:set\nwrite\tinput.c\t/^\t.write\t\t= lstats_write,$/;\"\tm\tlanguage:Foo\tvariable:proc_lstats_operations\troles:set\nlstats_write\tinput.c\t/^\t.write\t\t= lstats_write,$/;\"\tw\tlanguage:Foo\tvariable:proc_lstats_operations\troles:def\nllseek\tinput.c\t/^\t.llseek\t\t= seq_lseek,$/;\"\tm\tlanguage:Foo\tvariable:proc_lstats_operations\troles:set\nseq_lseek\tinput.c\t/^\t.llseek\t\t= seq_lseek,$/;\"\ts\tlanguage:Foo\tvariable:proc_lstats_operations\troles:def\nrelease\tinput.c\t/^\t.release\t= single_release,$/;\"\tm\tlanguage:Foo\tvariable:proc_lstats_operations\troles:set\nsingle_release\tinput.c\t/^\t.release\t= single_release,$/;\"\tR\tlanguage:Foo\tvariable:proc_lstats_operations\troles:def\nopen\tinput.c\t/^\t.open\t\t= proc_single_open,$/;\"\tm\tlanguage:Foo\tvariable:proc_single_file_operations\troles:set\nproc_single_open\tinput.c\t/^\t.open\t\t= proc_single_open,$/;\"\to\tlanguage:Foo\tvariable:proc_single_file_operations\troles:def\nseq_read\tinput.c\t/^\t.read\t\t= seq_read,$/;\"\tr\tlanguage:Foo\tvariable:proc_single_file_operations\troles:def\nread\tinput.c\t/^\t.read\t\t= seq_read,$/;\"\tm\tlanguage:Foo\tvariable:proc_single_file_operations\troles:set\nllseek\tinput.c\t/^\t.llseek\t\t= seq_lseek,$/;\"\tm\tlanguage:Foo\tvariable:proc_single_file_operations\troles:set\nseq_lseek\tinput.c\t/^\t.llseek\t\t= seq_lseek,$/;\"\ts\tlanguage:Foo\tvariable:proc_single_file_operations\troles:def\nrelease\tinput.c\t/^\t.release\t= single_release,$/;\"\tm\tlanguage:Foo\tvariable:proc_single_file_operations\troles:set\nsingle_release\tinput.c\t/^\t.release\t= single_release,$/;\"\tR\tlanguage:Foo\tvariable:proc_single_file_operations\troles:def\n"
  },
  {
    "path": "Units/optscript.r/op-intervaltab.d/input.c",
    "content": "/* Taken from Linux (fs/proc/base.c) */\n\nstatic const struct file_operations proc_pid_cmdline_ops = {\n\t.read\t= proc_pid_cmdline_read,\n\t.llseek\t= generic_file_llseek,\n};\n\nstatic const struct file_operations proc_lstats_operations = {\n\t.open\t\t= lstats_open,\n\t.read\t\t= seq_read,\n\t.write\t\t= lstats_write,\n\t.llseek\t\t= seq_lseek,\n\t.release\t= single_release,\n};\n\nstatic const struct file_operations proc_single_file_operations = {\n\t.open\t\t= proc_single_open,\n\t.read\t\t= seq_read,\n\t.llseek\t\t= seq_lseek,\n\t.release\t= single_release,\n};\n"
  },
  {
    "path": "Units/optscript.r/op-line.d/args.ctags",
    "content": "--fields=+n\n\n--langdef=X\n--map-X=.unknown\n--kinddef-X=d,def,definitions\n\n--regex-X=/[ \\t]*def ([a-z])/\\1/d/{exclusive}{{\n\t. dup :line 2 idiv line:\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-line.d/expected.tags",
    "content": "a\tinput.unknown\t/^#$/;\"\td\tline:1\nb\tinput.unknown\t/^def a$/;\"\td\tline:2\nc\tinput.unknown\t/^#$/;\"\td\tline:3\n"
  },
  {
    "path": "Units/optscript.r/op-line.d/input.unknown",
    "content": "#\ndef a\n#\ndef b\n#\ndef c\n\n"
  },
  {
    "path": "Units/optscript.r/op-markplaceholder.d/args.ctags",
    "content": "--sort=no\n--langdef=UnknownX\n--map-UnknownX=.unknown\n\n--kinddef-UnknownX=d,def,definitions\n\n--regex-UnknownX=/([ \\t]*)def +([a-zA-Z]):/\\2/d/{{\n    \\1 length 5 gt {\n        . _markplaceholder\n    } if\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-markplaceholder.d/expected.tags",
    "content": "a\tinput.unknown\t/^def a:$/;\"\td\nb\tinput.unknown\t/^    def b:$/;\"\td\nA\tinput.unknown\t/^def A:$/;\"\td\nB\tinput.unknown\t/^    def B:$/;\"\td\n"
  },
  {
    "path": "Units/optscript.r/op-markplaceholder.d/input.unknown",
    "content": "def a:\n    def b:\n        def c:\ndef A:\n    def B:\n        def C:\n"
  },
  {
    "path": "Units/optscript.r/op-matchloc2line.d/args.ctags",
    "content": "--fields=+n\n\n--langdef=X\n--map-X=.unknown\n--kinddef-X=l,line,lines\n\n--regex-X=/^DEF ([A-Z])//{{\n  0 string dup 1 _matchloc _matchloc2line exch cvs\n  /line\n  1 _matchloc\n  _tag _commit pop\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-matchloc2line.d/expected.tags",
    "content": "3\tinput.unknown\t/^DEF C$/;\"\tl\tline:3\n"
  },
  {
    "path": "Units/optscript.r/op-matchloc2line.d/input.unknown",
    "content": "REF A\nREF B\nDEF C\nREF D\n\n"
  },
  {
    "path": "Units/optscript.r/op-not-traced.d/args.ctags",
    "content": "--langdef=X\n--map-X=.unknown\n--kinddef-X=d,def,definitions\n\n--regex-X=/[ \\t]*def ([a-z])/\\1/d/{exclusive}{{\n    _traced {\n\t    mark . :name (-debug) _buildstring /def _tag _commit pop\n    } if\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-not-traced.d/expected.tags",
    "content": "a\tinput.unknown\t/^def a$/;\"\td\n"
  },
  {
    "path": "Units/optscript.r/op-not-traced.d/input.unknown",
    "content": "def a\n"
  },
  {
    "path": "Units/optscript.r/op-reftag.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n\n--langdef=foo\n--map-foo=+.foo\n\n--kinddef-foo=v,var,variables\n--_roledef-foo.v=lval,left side value\n\n--regex-foo=/^([a-z]) *=.*$//{{\n    \\1 /var /lval 1 _matchloc _reftag _commit pop\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-reftag.d/expected.tags",
    "content": "a\tinput.foo\t/^a=1$/;\"\tv\troles:lval\nb\tinput.foo\t/^b=1$/;\"\tv\troles:lval\n"
  },
  {
    "path": "Units/optscript.r/op-reftag.d/input.foo",
    "content": "a=1\nb=1\n"
  },
  {
    "path": "Units/optscript.r/op-scope.d/args.ctags",
    "content": "--langdef=X\n--map-X=.unknown\n--kinddef-X=p,package,packages\n--kinddef-X=d,def,definitions\n\n--regex-X=/def[ ]+([a-z]+)[ ]*:[ ]*([a-z]+)/\\1/d/{{\n\t. [ (typename) \\2 ] typeref:\n    . _scoperef\n}}\n\n--regex-X=/^package[ ]+([A-Z]+)[ ]*/\\1/p/{{\n\t. _scopeset\n}}\n\n--regex-X=/^subpackage[ ]+([A-Z]+)[ ]*/\\1/p/{{\n\t. _scopepush\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-scope.d/expected.tags",
    "content": "A\tinput.unknown\t/^subpackage A$/;\"\tp\tpackage:Z\nX\tinput.unknown\t/^package X$/;\"\tp\nY\tinput.unknown\t/^package Y$/;\"\tp\nZ\tinput.unknown\t/^package Z$/;\"\tp\na\tinput.unknown\t/^def a:int = 1$/;\"\td\tpackage:X\ttyperef:typename:int\nb\tinput.unknown\t/^def b:str = \"abc\"$/;\"\td\tpackage:X\ttyperef:typename:str\nc\tinput.unknown\t/^def c:name = name$/;\"\td\tpackage:Y\ttyperef:typename:name\nf\tinput.unknown\t/^def f:floag = 1.9$/;\"\td\tpackage:Z.A\ttyperef:typename:floag\n"
  },
  {
    "path": "Units/optscript.r/op-scope.d/input.unknown",
    "content": "package X\n\ndef a:int = 1\ndef b:str = \"abc\"\n\npackage Y\n\ndef c:name = name\n\npackage Z\n\nsubpackage A\n\ndef f:floag = 1.9\n"
  },
  {
    "path": "Units/optscript.r/op-signature.d/args.ctags",
    "content": "--langdef=X\n--map-X=.unknown\n--kinddef-X=d,def,definitions\n--fields=+{signature}\n--_tabledef-X=main\n--_tabledef-X=signature\n\n--_mtable-regex-X=main/def[ ]+([a-z0-9]+)(\\(?)/\\1/d/{{\n\t\\2 (\\() eq {\n       . /signature _tenter\n    } if\n}}\n--_mtable-regex-X=main/.//\n\n--_mtable-regex-X=signature/([^)]+)\\)//{{\n    mark (\\() \\1 dup _normalize_spaces! (\\)) _buildstring signature: _tleave\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-signature.d/expected.tags",
    "content": "func0\tinput.unknown\t/^def func0(a, b)$/;\"\td\tsignature:(a, b)\nfunc1\tinput.unknown\t/^def func1(x,$/;\"\td\tsignature:(x, y)\n"
  },
  {
    "path": "Units/optscript.r/op-signature.d/input.unknown",
    "content": "def func0(a, b)\n    ...\n\ndef func1(x,\n    y)\n    ...\n"
  },
  {
    "path": "Units/optscript.r/op-taction.d/args.ctags",
    "content": "--langdef=X\n--map-X=.unknown\n--kinddef-X=d,def,definitions\n--kinddef-X=l,localvar,local variables\n--kinddef-X=g,globalvar,global variables\n\n--_tabledef-X=main\n--_tabledef-X=eqtbl\n--_tabledef-X=deftbl\n\n--_mtable-regex-X=eqtbl/([a-zA-Z_]+)/\\1/l/{{\n    _tleave\n}}\n\n--_mtable-regex-X=eqtbl/.//{{\n    _tquit\n}}\n\n--_mtable-regex-X=deftbl/([a-zA-Z_]+)//{{\n    \\1 /globalvar 1 /start _matchloc _tag _commit\n    _tleave\n}}\n\n--_mtable-regex-X=deftbl/.//{{\n    _tquit\n}}\n\n--_mtable-regex-X=main/(def +|=)//{{\n    \\1 (=) eq {\n      /eqtbl  _tenter\n    } {\n      /deftbl _tenter\n    } ifelse\n}}\n--_mtable-regex-X=main/.//\n"
  },
  {
    "path": "Units/optscript.r/op-taction.d/expected.tags",
    "content": "a\tinput.unknown\t/^=a$/;\"\tl\nx\tinput.unknown\t/^def x$/;\"\tg\n"
  },
  {
    "path": "Units/optscript.r/op-taction.d/input.unknown",
    "content": "=a\ndef x\n"
  },
  {
    "path": "Units/optscript.r/op-tagloc.d/args.ctags",
    "content": "--langdef=FOO\n--map-FOO=.foo\n--kinddef-FOO=d,def,definitions\n--_extradef-FOO=withprefix,name with prefix\n--extras-FOO=+{withprefix}\n--fields=+{extras}\n--regex-FOO=/def +([a-zA-Z]+)/\\1/d/{{\n    mark (<prefix>) . :name _buildstring\n    . :kind\n    . _tagloc _tag _commit\n    /FOO.withprefix _markextra\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-tagloc.d/expected.tags",
    "content": "<prefix>x\tinput.foo\t/^def x$/;\"\td\textras:withprefix\n<prefix>y\tinput.foo\t/^def y$/;\"\td\textras:withprefix\nx\tinput.foo\t/^def x$/;\"\td\ny\tinput.foo\t/^def y$/;\"\td\n"
  },
  {
    "path": "Units/optscript.r/op-tagloc.d/input.foo",
    "content": "def x\ndef y\n"
  },
  {
    "path": "Units/optscript.r/op-traced.d/args.ctags",
    "content": "--langdef=X\n--map-X=.unknown\n--kinddef-X=d,def,definitions\n\n--regex-X=/[ \\t]*def ([a-z])/\\1/d/{exclusive}{{\n    _traced {\n\t    mark . :name (-debug) _buildstring /def _tag _commit pop\n    } if\n}}\n\n--_trace=X\n"
  },
  {
    "path": "Units/optscript.r/op-traced.d/expected.tags",
    "content": "a\tinput.unknown\t/^def a$/;\"\td\na-debug\tinput.unknown\t/^def a$/;\"\td\n"
  },
  {
    "path": "Units/optscript.r/op-traced.d/features",
    "content": "debug\n"
  },
  {
    "path": "Units/optscript.r/op-traced.d/input.unknown",
    "content": "def a\n"
  },
  {
    "path": "Units/optscript.r/op-typeref.d/args.ctags",
    "content": "--langdef=X\n--map-X=.unknown\n--kinddef-X=d,def,definitions\n--kinddef-X=t,type,type definitions\n\n--_prelude-X={{\n    /typedict 5 dict def\n}}\n\n--regex-X=/^type[ ]+([A-Z]+)$/\\1/t/{{\n    typedict \\1 cvn . put\n}}\n\n# [string string]\n--regex-X=/def[ ]+([a-z]+)[ ]*:[ ]*([a-z]+)/\\1/d/{{\n\t. [ (postfix) \\2 ] typeref:\n}}\n\n# string\n--regex-X=/def[ ]+<([a-z]+)>[ ]*([a-z]+)/\\2/d/{{\n\t.  \\1 typeref:\n}}\n\n# index\n--regex-X=/def[ ]+([A-Z]+)\\^([a-z]+)/\\2/d/{{\n    typedict \\1 cvn known {\n        . typedict \\1 cvn get typeref:\n    } if\n}}\n\n# false\n--regex-X=/def[ ]+([a-z]+)\\^!([a-z]+)/\\2/d/{{\n\t. \\1 typeref:\n    . false typeref:\n}}\n"
  },
  {
    "path": "Units/optscript.r/op-typeref.d/expected.tags",
    "content": "T\tinput.unknown\t/^type T$/;\"\tt\na\tinput.unknown\t/^def a:int = 1$/;\"\td\ttyperef:postfix:int\nb\tinput.unknown\t/^def b:str = \"abc\"$/;\"\td\ttyperef:postfix:str\nc\tinput.unknown\t/^def <boolean>c = true$/;\"\td\ttyperef:typename:boolean\nd\tinput.unknown\t/^def T^d = 1.0$/;\"\td\ttyperef:type:T\ne\tinput.unknown\t/^def float^!e = 1.0$/;\"\td\n"
  },
  {
    "path": "Units/optscript.r/op-typeref.d/input.unknown",
    "content": "def a:int = 1\ndef b:str = \"abc\"\n\ndef <boolean>c = true\n\ntype T\n\ndef T^d = 1.0\n\ndef float^!e = 1.0\n"
  },
  {
    "path": "Units/optscript.r/with-foreignLanguage-flag.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+rl\n\n--langdef=XXX{_foreignLanguage=C}\n--map-XXX=.xxx\n--fields=+n\n\n--kinddef-XXX=a,abc,abcx\n--_roledef-XXX.a=assigned,assigned\n\n--regex-XXX=/^(a)$/\\1/a/\n\n--regex-XXX=/^(b)$//{{\n    \\1 /abc _tag _commit pop\n}}\n--regex-XXX=/^(c)$/\\1/a/{_role=assigned}\n--regex-XXX=/^(d)$//{{\n    \\1 /abc /assigned _reftag _commit pop\n}}\n\n--_roledef-C.f=arolefortesting,a role for testing\n--regex-XXX=/\\/\\*(A)\\(\\)\\*\\//\\1/f/{_language=C}\n--regex-XXX=/\\/\\*(B)\\(\\)\\*\\///{{\n    \\1 /C /function _foreigntag _commit pop\n}}\n\n--regex-XXX=/\\/\\*(C)\\(\\)\\*\\//\\1/f/{_language=C}{_role=arolefortesting}\n--regex-XXX=/\\/\\*(D)\\(\\)\\*\\//\\1/f/{_role=arolefortesting}{_language=C}\n--regex-XXX=/\\/\\*(E)\\(\\)\\*\\///{{\n    \\1 /C /function /arolefortesting _foreignreftag _commit pop\n    1 _matchloc\n}}\n\n--regex-XXX=/\\/\\*(F)\\(\\)\\*\\///{{\n    dup\n    \\1 /C /function 4 -1 roll _foreigntag _commit pop\n}}\n\n--regex-XXX=/\\/\\*(G)\\(\\)\\*\\///{{\n    dup\n    \\1 /C /function /arolefortesting 5 -1 roll _foreignreftag _commit pop\n}}\n\n--regex-XXX=/\\/\\*(H)\\(\\)\\*\\///{{\n    \\1 /C /function null 5 -1 roll _foreignreftag _commit pop\n}}\n\n--regex-C=/FUNC\\(([a-z]*)\\);/\\1/f/\n"
  },
  {
    "path": "Units/optscript.r/with-foreignLanguage-flag.d/expected.tags",
    "content": "a\tinput.xxx\t/^a$/;\"\ta\tline:1\tlanguage:XXX\troles:def\nb\tinput.xxx\t/^b$/;\"\ta\tline:2\tlanguage:XXX\troles:def\nc\tinput.xxx\t/^c$/;\"\ta\tline:3\tlanguage:XXX\troles:assigned\nd\tinput.xxx\t/^d$/;\"\ta\tline:4\tlanguage:XXX\troles:assigned\nA\tinput.xxx\t/^\\/*A()*\\/$/;\"\tf\tline:5\tlanguage:C\troles:def\nB\tinput.xxx\t/^\\/*B()*\\/$/;\"\tf\tline:6\tlanguage:C\troles:def\nC\tinput.xxx\t/^\\/*C()*\\/$/;\"\tf\tline:7\tlanguage:C\troles:arolefortesting\nD\tinput.xxx\t/^\\/*D()*\\/$/;\"\tf\tline:8\tlanguage:C\troles:arolefortesting\nE\tinput.xxx\t/^\\/*E()*\\/$/;\"\tf\tline:9\tlanguage:C\troles:arolefortesting\nF\tinput.xxx\t/^\\/*E()*\\/$/;\"\tf\tline:9\tlanguage:C\troles:def\nG\tinput.xxx\t/^\\/*E()*\\/$/;\"\tf\tline:9\tlanguage:C\troles:arolefortesting\nH\tinput.xxx\t/^\\/*E()*\\/$/;\"\tf\tline:9\tlanguage:C\troles:def\nmyfunc\tinput-0.c\t/^FUNC(myfunc);$/;\"\tf\tline:1\tlanguage:C\troles:def\n"
  },
  {
    "path": "Units/optscript.r/with-foreignLanguage-flag.d/input-0.c",
    "content": "FUNC(myfunc);\n"
  },
  {
    "path": "Units/optscript.r/with-foreignLanguage-flag.d/input.xxx",
    "content": "a\nb\nc\nd\n/*A()*/\n/*B()*/\n/*C()*/\n/*D()*/\n/*E()*/\n/*F()*/\n/*G()*/\n/*H()*/\n"
  },
  {
    "path": "Units/paramdef.r/no-set.d/args.ctags",
    "content": "--langdef=Foo\n--map-Foo=.foo\n--kinddef-Foo=v,xval,externally defined values\n--_paramdef-Foo=VAR,desc\n--regex-Foo=/(x)//{{\n    /VAR _param {\n        /xval _tag _commit pop\n    } {\n        \\1 /xval _tag _commit pop\n    } ifelse\n}}\n"
  },
  {
    "path": "Units/paramdef.r/no-set.d/expected.tags",
    "content": "x\tinput.foo\t/^x$/;\"\tv\n"
  },
  {
    "path": "Units/paramdef.r/no-set.d/input.foo",
    "content": "x\n"
  },
  {
    "path": "Units/paramdef.r/simple.d/args.ctags",
    "content": "--langdef=Foo\n--map-Foo=.foo\n--kinddef-Foo=v,xval,externally defined values\n--_paramdef-Foo=VAR,desc\n--regex-Foo=/(x)//{{\n    /VAR _param {\n        /xval _tag _commit pop\n    } if\n}}\n--param-Foo.VAR=y\n"
  },
  {
    "path": "Units/paramdef.r/simple.d/expected.tags",
    "content": "y\tinput.foo\t/^x$/;\"\tv\n"
  },
  {
    "path": "Units/paramdef.r/simple.d/input.foo",
    "content": "x\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/language-force.d/args.ctags",
    "content": "--sort=no\n--language-force=I18nRubyGem\n--fields=+E\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/language-force.d/expected.tags",
    "content": "test\tinput.i18n\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser\nother\tinput.i18n\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser\ndog\tinput.i18n\t/^    dog: dog$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser\ncat\tinput.i18n\t/^    cat: cat$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser\ntracer\tinput.i18n\t/^    tracer: tracer$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser\nreporter\tinput.i18n\t/^    reporter: reporter$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser\ntest\tinput.i18n\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.test\tinput.i18n\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser,localeful\nother\tinput.i18n\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.other\tinput.i18n\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser,localeful\nanimals.dog\tinput.i18n\t/^    dog: dog$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.animals.dog\tinput.i18n\t/^    dog: dog$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser,localeful\nanimals.cat\tinput.i18n\t/^    cat: cat$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.animals.cat\tinput.i18n\t/^    cat: cat$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser,localeful\ntools.tracer\tinput.i18n\t/^    tracer: tracer$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.tools.tracer\tinput.i18n\t/^    tracer: tracer$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser,localeful\ntools.reporter\tinput.i18n\t/^    reporter: reporter$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.tools.reporter\tinput.i18n\t/^    reporter: reporter$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser,localeful\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/language-force.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/language-force.d/input.i18n",
    "content": "---\nen:\n  test: 2\n  other: 10\n  animals:\n    dog: dog\n    cat: cat\n  tools:\n    tracer: tracer\n    reporter: reporter\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/locale-kind.d/args.ctags",
    "content": "--sort=no\n--language-force=I18nRubyGem\n--fields=+E\n--extras-I18nRubyGem=\n--kinds-I18nRubyGem={locale}\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/locale-kind.d/expected.tags",
    "content": "en\tinput.yml\t/^en:$/;\"\tl\textras:subparser\nen\tinput-0.yml\t/^en:$/;\"\tl\textras:subparser\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/locale-kind.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/locale-kind.d/input-0.yml",
    "content": "---\nen:\n  hello: hello\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/locale-kind.d/input.yml",
    "content": "---\nen:\n  test: 2\n  other: 10\n  animals:\n    dog: dog\n    cat: cat\n  tools:\n    tracer: tracer\n    reporter: reporter\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/no-language-force.d/args.ctags",
    "content": "--sort=no\n--fields=+E\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/no-language-force.d/expected.tags",
    "content": "test\tinput.yml\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser\nother\tinput.yml\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser\ndog\tinput.yml\t/^    dog: dog$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser\ncat\tinput.yml\t/^    cat: cat$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser\ntracer\tinput.yml\t/^    tracer: tracer$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser\nreporter\tinput.yml\t/^    reporter: reporter$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser\ntest\tinput.yml\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.test\tinput.yml\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser,localeful\nother\tinput.yml\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.other\tinput.yml\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser,localeful\nanimals.dog\tinput.yml\t/^    dog: dog$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.animals.dog\tinput.yml\t/^    dog: dog$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser,localeful\nanimals.cat\tinput.yml\t/^    cat: cat$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.animals.cat\tinput.yml\t/^    cat: cat$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser,localeful\ntools.tracer\tinput.yml\t/^    tracer: tracer$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.tools.tracer\tinput.yml\t/^    tracer: tracer$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser,localeful\ntools.reporter\tinput.yml\t/^    reporter: reporter$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.tools.reporter\tinput.yml\t/^    reporter: reporter$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser,localeful\nhello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser\nhello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.hello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser,localeful\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/no-language-force.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/no-language-force.d/input-0.yml",
    "content": "---\nen:\n  hello: hello\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/no-language-force.d/input.yml",
    "content": "---\nen:\n  test: 2\n  other: 10\n  animals:\n    dog: dog\n    cat: cat\n  tools:\n    tracer: tracer\n    reporter: reporter\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/no-locale.d/args.ctags",
    "content": "--sort=no\n--fields=+E\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/no-locale.d/expected.tags",
    "content": "hello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser\nhello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.hello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser,localeful\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/no-locale.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/no-locale.d/input-0.yml",
    "content": "---\nen:\n  hello: hello\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/no-locale.d/input.yml",
    "content": "---\nnosuchlocale:\n  test: 2\n  other: 10\n  animals:\n    dog: dog\n    cat: cat\n  tools:\n    tracer: tracer\n    reporter: reporter\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/qualified.d/args.ctags",
    "content": "--sort=no\n--language-force=I18nRubyGem\n--fields=+E\n--extras=+q\n--extras-I18nRubyGem=-{localeful}\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/qualified.d/expected.tags",
    "content": "test\tinput.yml\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser\nen.test\tinput.yml\t/^  test: 2$/;\"\tk\tlocale:en\textras:qualified,subparser\nother\tinput.yml\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser\nen.other\tinput.yml\t/^  other: 10$/;\"\tk\tlocale:en\textras:qualified,subparser\ndog\tinput.yml\t/^    dog: dog$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser\nen.animals.dog\tinput.yml\t/^    dog: dog$/;\"\tk\tkeyInMiddle:en.animals\textras:qualified,subparser\ncat\tinput.yml\t/^    cat: cat$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser\nen.animals.cat\tinput.yml\t/^    cat: cat$/;\"\tk\tkeyInMiddle:en.animals\textras:qualified,subparser\ntracer\tinput.yml\t/^    tracer: tracer$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser\nen.tools.tracer\tinput.yml\t/^    tracer: tracer$/;\"\tk\tkeyInMiddle:en.tools\textras:qualified,subparser\nreporter\tinput.yml\t/^    reporter: reporter$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser\nen.tools.reporter\tinput.yml\t/^    reporter: reporter$/;\"\tk\tkeyInMiddle:en.tools\textras:qualified,subparser\ntest\tinput.yml\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser,localeless\nother\tinput.yml\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser,localeless\nanimals.dog\tinput.yml\t/^    dog: dog$/;\"\tk\tlocale:en\textras:subparser,localeless\nanimals.cat\tinput.yml\t/^    cat: cat$/;\"\tk\tlocale:en\textras:subparser,localeless\ntools.tracer\tinput.yml\t/^    tracer: tracer$/;\"\tk\tlocale:en\textras:subparser,localeless\ntools.reporter\tinput.yml\t/^    reporter: reporter$/;\"\tk\tlocale:en\textras:subparser,localeless\nhello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser\nen.hello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:qualified,subparser\nhello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser,localeless\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/qualified.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/qualified.d/input-0.yml",
    "content": "---\nen:\n  hello: hello\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/qualified.d/input.yml",
    "content": "---\nen:\n  test: 2\n  other: 10\n  animals:\n    dog: dog\n    cat: cat\n  tools:\n    tracer: tracer\n    reporter: reporter\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/simple-I18nRubyGem.d/args.ctags",
    "content": "--sort=no\n--language-force=I18nRubyGem\n--fields=+E\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/simple-I18nRubyGem.d/expected.tags",
    "content": "test\tinput.yml\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser\nother\tinput.yml\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser\ndog\tinput.yml\t/^    dog: dog$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser\ncat\tinput.yml\t/^    cat: cat$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser\ntracer\tinput.yml\t/^    tracer: tracer$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser\nreporter\tinput.yml\t/^    reporter: reporter$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser\ntest\tinput.yml\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.test\tinput.yml\t/^  test: 2$/;\"\tk\tlocale:en\textras:subparser,localeful\nother\tinput.yml\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.other\tinput.yml\t/^  other: 10$/;\"\tk\tlocale:en\textras:subparser,localeful\nanimals.dog\tinput.yml\t/^    dog: dog$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.animals.dog\tinput.yml\t/^    dog: dog$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser,localeful\nanimals.cat\tinput.yml\t/^    cat: cat$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.animals.cat\tinput.yml\t/^    cat: cat$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser,localeful\ntools.tracer\tinput.yml\t/^    tracer: tracer$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.tools.tracer\tinput.yml\t/^    tracer: tracer$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser,localeful\ntools.reporter\tinput.yml\t/^    reporter: reporter$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.tools.reporter\tinput.yml\t/^    reporter: reporter$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser,localeful\nhello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser\nhello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.hello\tinput-0.yml\t/^  hello: hello$/;\"\tk\tlocale:en\textras:subparser,localeful\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/simple-I18nRubyGem.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/simple-I18nRubyGem.d/input-0.yml",
    "content": "---\nen:\n  hello: hello\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/simple-I18nRubyGem.d/input.yml",
    "content": "---\nen:\n  test: 2\n  other: 10\n  animals:\n    dog: dog\n    cat: cat\n  tools:\n    tracer: tracer\n    reporter: reporter\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/symbols.d/args.ctags",
    "content": "--sort=no\n--language-force=I18nRubyGem\n--fields=+E\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/symbols.d/expected.tags",
    "content": "test\tinput.yml\t/^  :test: 2$/;\"\tk\tlocale:en\textras:subparser\nother\tinput.yml\t/^  :other: 10$/;\"\tk\tlocale:en\textras:subparser\ndog\tinput.yml\t/^    :dog: dog$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser\ncat\tinput.yml\t/^    :cat: cat$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser\ntracer\tinput.yml\t/^    :tracer: tracer$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser\nreporter\tinput.yml\t/^    :reporter: reporter$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser\ntest\tinput.yml\t/^  :test: 2$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.test\tinput.yml\t/^  :test: 2$/;\"\tk\tlocale:en\textras:subparser,localeful\nother\tinput.yml\t/^  :other: 10$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.other\tinput.yml\t/^  :other: 10$/;\"\tk\tlocale:en\textras:subparser,localeful\nanimals.dog\tinput.yml\t/^    :dog: dog$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.animals.dog\tinput.yml\t/^    :dog: dog$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser,localeful\nanimals.cat\tinput.yml\t/^    :cat: cat$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.animals.cat\tinput.yml\t/^    :cat: cat$/;\"\tk\tkeyInMiddle:en.animals\textras:subparser,localeful\ntools.tracer\tinput.yml\t/^    :tracer: tracer$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.tools.tracer\tinput.yml\t/^    :tracer: tracer$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser,localeful\ntools.reporter\tinput.yml\t/^    :reporter: reporter$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.tools.reporter\tinput.yml\t/^    :reporter: reporter$/;\"\tk\tkeyInMiddle:en.tools\textras:subparser,localeful\nhello\tinput-0.yml\t/^  :hello: hello$/;\"\tk\tlocale:en\textras:subparser\nhello\tinput-0.yml\t/^  :hello: hello$/;\"\tk\tlocale:en\textras:subparser,localeless\nen.hello\tinput-0.yml\t/^  :hello: hello$/;\"\tk\tlocale:en\textras:subparser,localeful\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/symbols.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/symbols.d/input-0.yml",
    "content": "---\n:en:\n  :hello: hello\n"
  },
  {
    "path": "Units/parser-I18nRubyGem.r/symbols.d/input.yml",
    "content": "---\n:en:\n  :test: 2\n  :other: 10\n  :animals:\n    :dog: dog\n    :cat: cat\n  :tools:\n    :tracer: tracer\n    :reporter: reporter\n"
  },
  {
    "path": "Units/parser-ada.r/ada-adb.d/expected.tags",
    "content": "Altivec\tinput.adb\t/^procedure Altivec is$/;\"\tr\nVector_A\tinput.adb\t/^   Vector_A : constant vector_unsigned_int := To_Vector (View_A);$/;\"\tn\tsubprogram:Altivec\tfile:\nVector_B\tinput.adb\t/^   Vector_B : constant vector_unsigned_int := To_Vector (View_B);$/;\"\tn\tsubprogram:Altivec\tfile:\nVector_C\tinput.adb\t/^   Vector_C : vector_unsigned_int;$/;\"\tv\tsubprogram:Altivec\tfile:\nView_A\tinput.adb\t/^   View_A   : constant VUI_View := (Values => (1, 2, 3, 4));$/;\"\tn\tsubprogram:Altivec\tfile:\nView_B\tinput.adb\t/^   View_B   : constant VUI_View := (Values => (1, 1, 1, 1));$/;\"\tn\tsubprogram:Altivec\tfile:\nView_C\tinput.adb\t/^   View_C   : VUI_View;$/;\"\tv\tsubprogram:Altivec\tfile:\n"
  },
  {
    "path": "Units/parser-ada.r/ada-adb.d/input.adb",
    "content": "--  Taken from altivec of GNAT examples (http://www.adacore.com/developers/code-samples/gnat-examples/)\n--  ====================================================================================================\n--  This example shows how to create and manipulate vectors by the mean of high\n--  level views.\n\nwith GNAT.Altivec;                   use GNAT.Altivec;\nwith GNAT.Altivec.Conversions;       use GNAT.Altivec.Conversions;\nwith GNAT.Altivec.Vector_Operations; use GNAT.Altivec.Vector_Operations;\nwith GNAT.Altivec.Vector_Types;      use GNAT.Altivec.Vector_Types;\nwith GNAT.Altivec.Vector_Views;      use GNAT.Altivec.Vector_Views;\n\nwith GNAT.IO;                        use GNAT.IO;\n\nprocedure Altivec is\n\n   View_A   : constant VUI_View := (Values => (1, 2, 3, 4));\n   Vector_A : constant vector_unsigned_int := To_Vector (View_A);\n\n   View_B   : constant VUI_View := (Values => (1, 1, 1, 1));\n   Vector_B : constant vector_unsigned_int := To_Vector (View_B);\n\n   Vector_C : vector_unsigned_int;\n   View_C   : VUI_View;\n\nbegin\n   Vector_C := vec_add (Vector_A, Vector_B);\n   --  C = A + B\n\n   View_C   := To_View (Vector_C);\n\n   for I in View_C.Values'Range loop\n      Put_Line (unsigned_int'Image (View_C.Values (I)));\n   end loop;\n\nend Altivec;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-ads.d/expected.tags",
    "content": "Adjust\tinput.ads\t/^    procedure Adjust(S: in out Stack);$/;\"\tR\tpackspec:GenStack\nData\tinput.ads\t/^        Data: Data_Ptr;$/;\"\tc\ttype:Node\tfile:\nData_Ptr\tinput.ads\t/^    type Data_Ptr is access StackData'Class;$/;\"\tt\tpackspec:GenStack\tfile:\nEmpty\tinput.ads\t/^    function Empty(S: Stack) return Boolean;$/;\"\tR\tpackspec:GenStack\nFinalize\tinput.ads\t/^    procedure Finalize(S: in out Stack);$/;\"\tR\tpackspec:GenStack\nGenStack\tinput.ads\t/^package GenStack is$/;\"\tP\nHead\tinput.ads\t/^        Head: Node_Ptr;$/;\"\tc\ttype:Stack\tfile:\nInitialize\tinput.ads\t/^    procedure Initialize(S: in out Stack);$/;\"\tR\tpackspec:GenStack\nNext\tinput.ads\t/^        Next: Node_Ptr;$/;\"\tc\ttype:Node\tfile:\nNode\tinput.ads\t/^    type Node is record$/;\"\tt\tpackspec:GenStack\tfile:\nNode_Ptr\tinput.ads\t/^    type Node_Ptr is access Node;$/;\"\tt\tpackspec:GenStack\tfile:\nPop\tinput.ads\t/^    procedure Pop(S: in out Stack; D: in out StackData'class);$/;\"\tR\tpackspec:GenStack\nPush\tinput.ads\t/^    procedure Push(S: in out Stack; D: StackData'class);$/;\"\tR\tpackspec:GenStack\nStack\tinput.ads\t/^    type Stack is new Controlled with private;$/;\"\tt\tpackspec:GenStack\nStack\tinput.ads\t/^    type Stack is new Controlled with record$/;\"\tt\tpackspec:GenStack\tfile:\nStackData\tinput.ads\t/^    type StackData is new Controlled with null record;$/;\"\tt\tpackspec:GenStack\nTop\tinput.ads\t/^    procedure Top(S: Stack; Data: in out StackData'class);$/;\"\tR\tpackspec:GenStack\n"
  },
  {
    "path": "Units/parser-ada.r/ada-ads.d/input.ads",
    "content": "-- Object-oriented generalized stack.  This illustrates the use of a\n-- controlled type, which is one that has construction and destructions.\n-- It also shows how to create two related types in the same package so\n-- that they can share private declarations.  This sort of thing is\n-- accomplished in Java or C++ using nested classes, or using friend\n-- declarations in C++.\n--\nwith Ada.Finalization; use Ada.Finalization;\n\npackage GenStack is\n    -- This is the stack type.\n    type Stack is new Controlled with private;\n\n    -- This is the base type for nodes.  Client packages must derive their\n    -- nodes from StackData.  Since it comes from Controlled, the user can\n    -- override the Initialize, Adjust, and Finalize methods as needed.\n    type StackData is new Controlled with null record;\n\n    -- Initialization operations.\n    procedure Initialize(S: in out Stack);\n    procedure Adjust(S: in out Stack);\n    procedure Finalize(S: in out Stack);\n\n    -- Stack operations.\n    procedure Push(S: in out Stack; D: StackData'class);\n    procedure Pop(S: in out Stack; D: in out StackData'class);\n    procedure Top(S: Stack; Data: in out StackData'class);\n    function Empty(S: Stack) return Boolean;\n\n    private\n    -- Pointer to the node type.\n    type Node;\n    type Node_Ptr is access Node;\n\n    -- Here is the generalized stack itself.  We would just make it the\n    -- pointer itself, but it needs to be a record so it can be in a with.\n    type Stack is new Controlled with record\n        Head: Node_Ptr;\n    end record;\n\n    -- Now, we need a pointer to the data part.\n    type Data_Ptr is access StackData'Class;\n\n    -- This is the node type.\n    type Node is record\n        Data: Data_Ptr;\n        Next: Node_Ptr;\n    end record;\n\nend GenStack;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-block-tracking.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ada.r/ada-block-tracking.d/expected.tags",
    "content": "Input\tinput.adb\t/^package body Input is$/;\"\tp\nF\tinput.adb\t/^  function F (S : Integer) return Integer is$/;\"\tr\tpackage:Input\tfile:\nR\tinput.adb\t/^  R : Integer;$/;\"\tv\tsubprogram:F\tfile:\nT\tinput.adb\t/^\tT : Integer := 2;$/;\"\tv\tanon:declare\tfile:\nP\tinput.adb\t/^\tP : Integer := 4;$/;\"\tv\tanon:declare\tfile:\nG\tinput.adb\t/^  function G (A : Integer) return Integer is$/;\"\tr\tpackage:Input\tfile:\nB\tinput.adb\t/^  B : Integer;$/;\"\tv\tsubprogram:G\tfile:\nC\tinput.adb\t/^\tC : Integer := 2;$/;\"\tv\tanon:declare\tfile:\nD\tinput.adb\t/^\tD : Integer := 4;$/;\"\tv\tanon:declare\tfile:\n"
  },
  {
    "path": "Units/parser-ada.r/ada-block-tracking.d/input.adb",
    "content": "package body Input is\n  function F (S : Integer) return Integer is\n  R : Integer;\n  begin\n    if S < 1 then\n      declare\n\tT : Integer := 2;\n      begin\n\tif  S > T then\n\t  T :=  3;\n\tend if;\n\tR := S;\n      end;\n    else\n      declare\n\tP : Integer := 4;\n      begin\n\treturn P;\n      end;\n    end if;\n    return R;\n  end F;\n  function G (A : Integer) return Integer is\n  B : Integer;\n  begin\n    if A < 1 then\n      declare\n\tC : Integer := 2;\n      begin\n\tcase A is\n\t when 1 => null;\n\t when others => null;\n\tend case;\n\tB := A;\n      end;\n    else\n      declare\n\tD : Integer := 4;\n      begin\n\treturn D;\n      end;\n    end if;\n    return B;\n  end G;\nend Input;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-block-tracking.d/validator",
    "content": "gnat\n"
  },
  {
    "path": "Units/parser-ada.r/ada-char-literal.d/expected.tags-e",
    "content": "\f\ninput.adb,158\npackage body System.Val_Util isSystem.Val_Util/b\u00014,69\n  procedure Bad_Value (S : String) isBad_Value/p\u00016,102\n  procedure Not_Tagged  isNot_Tagged/p\u000111,236\n"
  },
  {
    "path": "Units/parser-ada.r/ada-char-literal.d/input.adb",
    "content": "--- file: s-valuti.adb\nwith System.Case_Util; use System.Case_Util;\n\npackage body System.Val_Util is\n\n  procedure Bad_Value (S : String) is\n  begin\n    raise Constraint_Error with \"bad input for 'Value: \"\"\" & S & '\"';\n  end Bad_Value;\n\n  procedure Not_Tagged  is\n  begin\n    null;\n  end Not_Tagged;\nend System.Val_Util;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-end-without-designator.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ada.r/ada-end-without-designator.d/expected.tags",
    "content": "Truc\tinput.adb\t/^procedure Truc is$/;\"\tr\nSome_Function\tinput.adb\t/^  function Some_Function return Boolean is$/;\"\tr\tsubprogram:Truc\tfile:\nInner_Function_Without_End_Label\tinput.adb\t/^    function Inner_Function_Without_End_Label return Boolean is$/;\"\tr\tsubprogram:Some_Function\tfile:\nResult\tinput.adb\t/^    Result : constant Boolean := Inner_Function_Without_End_Label;$/;\"\tn\tsubprogram:Some_Function\tfile:\nSmurf\tinput.adb\t/^  function Smurf return Integer is$/;\"\tr\tsubprogram:Truc\tfile:\n"
  },
  {
    "path": "Units/parser-ada.r/ada-end-without-designator.d/input.adb",
    "content": "-- Taken from #4205 submitted by @koenmeersman\nprocedure Truc is\n  function Some_Function return Boolean is\n    function Inner_Function_Without_End_Label return Boolean is\n    begin\n      return True;\n    end;\n    Result : constant Boolean := Inner_Function_Without_End_Label;\n  begin\n    return Result;\n  end Some_Function;\n \n  function Smurf return Integer is\n  begin\n    if Some_Function then\n      return 1;\n    else\n      return 2;\n    end if;\n  end Smurf;\nbegin\n  if Smurf > 2 then\n    raise Program_Error;\n  end if;\nend Truc;\n\n"
  },
  {
    "path": "Units/parser-ada.r/ada-end-without-designator.d/validator",
    "content": "gnat\n"
  },
  {
    "path": "Units/parser-ada.r/ada-entry.d/args.ctags",
    "content": "--sort=no\n--kinds-Ada=+E\n\n--langdef=GnatProject\n--map-GnatProject=.gpr\n\n--kinddef-GnatProject=P,project,projects\n--regex-GnatProject=/^project[ \\t]+([a-zA-Z0-9_]+)/\\1/P/\n\n"
  },
  {
    "path": "Units/parser-ada.r/ada-entry.d/expected.tags",
    "content": "Input\tinput.adb\t/^procedure Input is$/;\"\tr\nInput_0\tinput_0.gpr\t/^project Input_0 is$/;\"\tP\nInput_1\tinput_1.adb\t/^package body Input_1 is$/;\"\tp\nMa_Tasche\tinput_1.adb\t/^   task body Ma_Tasche is$/;\"\tk\tpackage:Input_1\tfile:\nVar_Continuer\tinput_1.adb\t/^      Var_Continuer : Boolean := False;$/;\"\tv\ttask:Ma_Tasche\tfile:\nBoucle_Principale\tinput_1.adb\t/^      Boucle_Principale :$/;\"\ti\ttask:Ma_Tasche\tfile:\nAccepter\tinput_1.adb\t/^         accept Accepter$/;\"\te\tidentifier:Boucle_Principale\tfile:\nMon_Autre_Tasche\tinput_1.adb\t/^   task body Mon_Autre_Tasche is$/;\"\tk\tpackage:Input_1\tfile:\nUne_Autre_Tasche_1\tinput_1.adb\t/^   Une_Autre_Tasche_1 : Tasche_Type_1_T;$/;\"\tv\tpackage:Input_1\tfile:\nTasche_Type_1_T\tinput_1.adb\t/^   task body Tasche_Type_1_T is$/;\"\tk\tpackage:Input_1\tfile:\nTasche_Type_2_T\tinput_1.adb\t/^   task body Tasche_Type_2_T is$/;\"\tk\tpackage:Input_1\tfile:\nTasche_Type_3_T\tinput_1.adb\t/^   task body Tasche_Type_3_T is$/;\"\tk\tpackage:Input_1\tfile:\nUne_Autre_Tasche_2\tinput_1.adb\t/^   Une_Autre_Tasche_2 : Tasche_Type_2_T;$/;\"\tv\tpackage:Input_1\tfile:\nUne_Autre_Tasche_3\tinput_1.adb\t/^   Une_Autre_Tasche_3 : Tasche_Type_3_T (Taille => 5);$/;\"\tv\tpackage:Input_1\tfile:\nObjet_Protege\tinput_1.adb\t/^   protected body Objet_Protege is$/;\"\to\tpackage:Input_1\tfile:\nDemarrer\tinput_1.adb\t/^      entry Demarrer$/;\"\te\tprotected:Objet_Protege\tfile:\nFaire\tinput_1.adb\t/^      procedure Faire is$/;\"\tr\tprotected:Objet_Protege\tfile:\nTester\tinput_1.adb\t/^      function Tester$/;\"\tr\tprotected:Objet_Protege\tfile:\nType_Protege\tinput_1.adb\t/^   protected body Type_Protege is$/;\"\to\tpackage:Input_1\tfile:\nDemarrer\tinput_1.adb\t/^      entry Demarrer$/;\"\te\tprotected:Type_Protege\tfile:\nFaire\tinput_1.adb\t/^      procedure Faire is$/;\"\tr\tprotected:Type_Protege\tfile:\nTester\tinput_1.adb\t/^      function Tester$/;\"\tr\tprotected:Type_Protege\tfile:\nDiscriminant_Protege\tinput_1.adb\t/^   protected body Discriminant_Protege is$/;\"\to\tpackage:Input_1\tfile:\nDemarrer\tinput_1.adb\t/^      entry Demarrer$/;\"\te\tprotected:Discriminant_Protege\tfile:\nFaire\tinput_1.adb\t/^      procedure Faire is$/;\"\tr\tprotected:Discriminant_Protege\tfile:\nTester\tinput_1.adb\t/^      function Tester$/;\"\tr\tprotected:Discriminant_Protege\tfile:\nInput_1\tinput_1.ads\t/^package Input_1 is$/;\"\tP\nMa_Tasche\tinput_1.ads\t/^   task Ma_Tasche is$/;\"\tK\tpackspec:Input_1\nAccepter\tinput_1.ads\t/^      entry Accepter$/;\"\tE\ttaskspec:Ma_Tasche\nMon_Autre_Tasche\tinput_1.ads\t/^   task Mon_Autre_Tasche;$/;\"\tK\tpackspec:Input_1\nTasche_Type_1_T\tinput_1.ads\t/^   task type Tasche_Type_1_T;$/;\"\tK\tpackspec:Input_1\nUne_Tasche\tinput_1.ads\t/^   Une_Tasche : Tasche_Type_1_T;$/;\"\tv\tpackspec:Input_1\nTasche_Type_2_T\tinput_1.ads\t/^   task type Tasche_Type_2_T is$/;\"\tK\tpackspec:Input_1\nStart\tinput_1.ads\t/^      entry Start;$/;\"\tE\ttaskspec:Tasche_Type_2_T\nLire\tinput_1.ads\t/^      entry Lire$/;\"\tE\ttaskspec:Tasche_Type_2_T\nTasche_Type_3_T\tinput_1.ads\t/^   task type Tasche_Type_3_T$/;\"\tK\tpackspec:Input_1\nStart\tinput_1.ads\t/^      entry Start;$/;\"\tE\ttaskspec:Tasche_Type_3_T\nObjet_Protege\tinput_1.ads\t/^   protected Objet_Protege is$/;\"\tO\tpackspec:Input_1\nDemarrer\tinput_1.ads\t/^      entry Demarrer;$/;\"\tE\tprotectspec:Objet_Protege\nFaire\tinput_1.ads\t/^      procedure Faire;$/;\"\tR\tprotectspec:Objet_Protege\nTester\tinput_1.ads\t/^      function Tester return Boolean;$/;\"\tR\tprotectspec:Objet_Protege\nVariable\tinput_1.ads\t/^      Variable : Boolean := True;$/;\"\tv\tprotectspec:Objet_Protege\tfile:\nType_Protege\tinput_1.ads\t/^   protected type Type_Protege is$/;\"\tO\tpackspec:Input_1\nDemarrer\tinput_1.ads\t/^      entry Demarrer;$/;\"\tE\tprotectspec:Type_Protege\nFaire\tinput_1.ads\t/^      procedure Faire;$/;\"\tR\tprotectspec:Type_Protege\nTester\tinput_1.ads\t/^      function Tester return Boolean;$/;\"\tR\tprotectspec:Type_Protege\nVariable\tinput_1.ads\t/^      Variable : Boolean := True;$/;\"\tv\tprotectspec:Type_Protege\tfile:\nDiscriminant_Protege\tinput_1.ads\t/^   protected type Discriminant_Protege$/;\"\tO\tpackspec:Input_1\nDemarrer\tinput_1.ads\t/^      entry Demarrer;$/;\"\tE\tprotectspec:Discriminant_Protege\nFaire\tinput_1.ads\t/^      procedure Faire;$/;\"\tR\tprotectspec:Discriminant_Protege\nTester\tinput_1.ads\t/^      function Tester return Boolean;$/;\"\tR\tprotectspec:Discriminant_Protege\nVariable\tinput_1.ads\t/^      Variable : Boolean := True;$/;\"\tv\tprotectspec:Discriminant_Protege\tfile:\n"
  },
  {
    "path": "Units/parser-ada.r/ada-entry.d/input.adb",
    "content": "with Ada.Text_IO;\n-- with Mes_Tasches_P;\nwith Input_1;\n\n-- procedure Client is\nprocedure Input is\n\nbegin\n\n   Ada.Text_IO.Put_Line (\"Tasks won't stop, kill it with CTRL-C\");\n   -- Mes_Tasches_P.Ma_Tasche.Accepter (Continuer => True);\n   Input_1.Ma_Tasche.Accepter (Continuer => True);\n\nend Input;\n-- end Client;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-entry.d/input_0.gpr",
    "content": "-- project Client is\nproject Input_0 is\n\n   for Main use (\"input.adb\");\n\n   for Source_Dirs use (\"./**\");\n   for Object_Dir  use \"obj/\";\n   for Exec_Dir    use \"bin/\";\n\n   for Create_Missing_Dirs use \"True\";\n\n   package Compiler is\n      for Default_Switches (\"Ada\")  use (\"-O0\", \"-Wall\");\n   end Compiler;\n\nend Input_0;\n-- end Client;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-entry.d/input_1.adb",
    "content": "-- package body Mes_Tasches_P is\npackage body Input_1 is\n   ---------------------------------------------------------------------------\n   task body Ma_Tasche is\n      Var_Continuer : Boolean := False;\n   begin\n      Boucle_Principale :\n      loop\n         accept Accepter\n            (Continuer : Boolean)\n         do\n            Var_Continuer := Continuer;\n         end Accepter;\n      end loop Boucle_Principale;\n   end Ma_Tasche;\n   ---------------------------------------------------------------------------\n\n   ---------------------------------------------------------------------------\n   task body Mon_Autre_Tasche is\n   begin\n      null;\n   end Mon_Autre_Tasche;\n   ---------------------------------------------------------------------------\n\n   Une_Autre_Tasche_1 : Tasche_Type_1_T;\n\n   ---------------------------------------------------------------------------\n   task body Tasche_Type_1_T is\n   begin\n      null;\n   end Tasche_Type_1_T;\n   ---------------------------------------------------------------------------\n\n   ---------------------------------------------------------------------------\n   task body Tasche_Type_2_T is\n   begin\n      null;\n   end Tasche_Type_2_T;\n   ---------------------------------------------------------------------------\n\n   ---------------------------------------------------------------------------\n   task body Tasche_Type_3_T is\n   begin\n      null;\n   end Tasche_Type_3_T;\n   ---------------------------------------------------------------------------\n\n   Une_Autre_Tasche_2 : Tasche_Type_2_T;\n   Une_Autre_Tasche_3 : Tasche_Type_3_T (Taille => 5);\n\n   ---------------------------------------------------------------------------\n   protected body Objet_Protege is\n      entry Demarrer\n         when Variable\n      is\n      begin\n         null;\n      end Demarrer;\n\n      procedure Faire is\n      begin\n         null;\n      end Faire;\n\n      function Tester\n         return Boolean\n      is\n      begin\n         return Variable;\n      end Tester;\n   end Objet_Protege;\n   ---------------------------------------------------------------------------\n\n   ---------------------------------------------------------------------------\n   protected body Type_Protege is\n      entry Demarrer\n         when Variable\n      is\n      begin\n         null;\n      end Demarrer;\n\n      procedure Faire is\n      begin\n         null;\n      end Faire;\n\n      function Tester\n         return Boolean\n      is\n      begin\n         return Variable;\n      end Tester;\n   end Type_Protege;\n   ---------------------------------------------------------------------------\n\n   ---------------------------------------------------------------------------\n   protected body Discriminant_Protege is\n      entry Demarrer\n         when Variable\n      is\n      begin\n         null;\n      end Demarrer;\n\n      procedure Faire is\n      begin\n         null;\n      end Faire;\n\n      function Tester\n         return Boolean\n      is\n      begin\n         return Variable;\n      end Tester;\n   end Discriminant_Protege;\n   ---------------------------------------------------------------------------\n\nend Input_1;\n-- end Mes_Tasches_P;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-entry.d/input_1.ads",
    "content": "-- package Mes_Tasches_P is\npackage Input_1 is\n\n   task Ma_Tasche is\n      entry Accepter\n         (Continuer : Boolean);\n   end Ma_Tasche;\n\n   task Mon_Autre_Tasche;\n\n   task type Tasche_Type_1_T;\n\n   Une_Tasche : Tasche_Type_1_T;\n\n   task type Tasche_Type_2_T is\n      entry Start;\n      entry Lire\n         (Donnee : out Integer);\n   end Tasche_Type_2_T;\n\n   --  Task type with discriminant.\n   task type Tasche_Type_3_T\n      --  We could have any number of arguments in discriminant\n      --  Work exactly like argument in procedure/function/entry/accept\n      (Taille : Integer)\n   is\n      entry Start;\n   end Tasche_Type_3_T;\n\n   --  protected objects.\n\n   protected Objet_Protege is\n      entry Demarrer;\n      procedure Faire;\n      function Tester return Boolean;\n   private\n      Variable : Boolean := True;\n   end Objet_Protege;\n\n   protected type Type_Protege is\n      entry Demarrer;\n      procedure Faire;\n      function Tester return Boolean;\n   private\n      Variable : Boolean := True;\n   end Type_Protege;\n\n   protected type Discriminant_Protege\n      (Priorite : Natural)\n   is\n      entry Demarrer;\n      procedure Faire;\n      function Tester return Boolean;\n   private\n      Variable : Boolean := True;\n   end Discriminant_Protege;\n\nend Input_1;\n-- end Mes_Tasches_P;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-etags-suffix.d/args.ctags",
    "content": "--sort=no\n--kinds-Ada=-l\n"
  },
  {
    "path": "Units/parser-ada.r/ada-etags-suffix.d/expected.tags-e",
    "content": "\f\ninput.ads,0\n\f\ninput_0.adb,234\npackage body Input_0 isInput_0/b\u00011,0\n   function My_Function return Boolean isMy_Function/f\u00012,24\n   procedure My_Procedure isMy_Procedure/p\u00017,115\n   task body My_Task isMy_Task/b\u000112,187\n      accept GET (X: in My_T) doGET\u000114,220\n\f\ninput_0.ads,217\npackage Input_0 isInput_0/s\u00011,0\n   function My_Function return Boolean;My_Function/f\u00015,192\n   procedure My_Procedure;My_Procedure/p\u00019,411\n   type My_T is (A, B, C);My_T/t\u000116,792\n  task My_Task isMy_Task/k\u000120,973\n"
  },
  {
    "path": "Units/parser-ada.r/ada-etags-suffix.d/input.ads",
    "content": "-- DUMMY\n"
  },
  {
    "path": "Units/parser-ada.r/ada-etags-suffix.d/input_0.adb",
    "content": "package body Input_0 is\n   function My_Function return Boolean is\n   begin\n      return True;\n   end My_Function;\n\n   procedure My_Procedure is\n   begin\n      null;\n   end My_Procedure;\n\n   task body My_Task is\n   begin\n      accept GET (X: in My_T) do\n\t null;\n      end GET;\n   end My_Task;\n\n   end Input_0;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-etags-suffix.d/input_0.ads",
    "content": "package Input_0 is\n   -- Expecting above to create tag 'Input_0/s' as this is 'package spec'-definition with name 'Input_0'.\n   -- Emacs tag-search on Input_0/s should navigate to the above.\n\n   function My_Function return Boolean;\n   -- Expecting above to create tag 'My_Function/f' as this is 'function'-definition with name My_Function.\n   -- Emacs tag-search on My_Function/f should navigate to the above.\n\n   procedure My_Procedure;\n   -- Expecting above to create tag 'My_Procedure/p' as this is 'procedure'-definition with name My_Procedure.\n   -- Emacs tag-search on My_Procedure/p should navigate to the above.\n\n  -- Expecting above to create tag 'Input_0/s' as this is 'package spec'-definition with name 'Input_0'.\n  -- Emacs tag-search on Input_0/s should navigate to the above.\n\n   type My_T is (A, B, C);\n  -- Expecting above to create tag 'My_T/t' as this is 'type'-definition with name 'My_T'.\n  -- Emacs tag-search on My_T/t should navigate to the above.\n\n  task My_Task is\n    -- Expecting above to create tag 'My_Task/k' as this is 'task'-definition with name 'My_Task'.\n    -- Emacs tag-search on My_Task/k should navigate to the above.\n     entry GET (X : in My_T);\n  end My_Task;\n\nend Input_0;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-expression-function-with-generic.d/expected.tags-e",
    "content": "\f\ninput.adb,486\nprocedure My_Package isMy_Package/p\u00011,0\n  package Generic_Integer_Images isGeneric_Integer_Images/s\u00015,71\n    function Digit_To_Character (X : Unsigned_Type) return Character;Digit_To_Character/f\u00016,107\n    type Unsigned_Type is range <>;Unsigned_Type\u00014,35\n  package body Generic_Integer_Images isGeneric_Integer_Images/b\u00019,208\n    function Digit_To_Character (X : Unsigned_Type) return Character isDigit_To_Character/f\u000110,249\n  type Signed_Address is rangeSigned_Address/t\u000114,379\n"
  },
  {
    "path": "Units/parser-ada.r/ada-expression-function-with-generic.d/input.adb",
    "content": "procedure My_Package is\n\n  generic\n    type Unsigned_Type is range <>;\n  package Generic_Integer_Images is\n    function Digit_To_Character (X : Unsigned_Type) return Character;\n  end Generic_Integer_Images;\n\n  package body Generic_Integer_Images is\n    function Digit_To_Character (X : Unsigned_Type) return Character is\n      (Character'Val (0));\n  end Generic_Integer_Images;\n\n  type Signed_Address is range\n    -2**(Standard'Address_Size - 1) .. 2**(Standard'Address_Size - 1) - 1; \nbegin\n  null;\nend My_Package;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-expression-function.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ada.r/ada-expression-function.d/expected.tags",
    "content": "Test\tinput.adb\t/^procedure Test is$/;\"\tr\nMy_Type\tinput.adb\t/^  My_Type : Boolean := True;$/;\"\tv\tsubprogram:Test\tfile:\nTagged_Procedure\tinput.adb\t/^  procedure Tagged_Procedure is$/;\"\tr\tsubprogram:Test\tfile:\nBoolean_As_String\tinput.adb\t/^    function Boolean_As_String return String is$/;\"\tr\tsubprogram:Tagged_Procedure\tfile:\nAnother_Boolean_As_String\tinput.adb\t/^    function Another_Boolean_As_String return String is$/;\"\tr\tsubprogram:Tagged_Procedure\tfile:\np0\tinput.adb\t/^    procedure p0 is\t$/;\"\tr\tsubprogram:Tagged_Procedure\tfile:\nYet_Boolean_As_String\tinput.adb\t/^    function Yet_Boolean_As_String return String is$/;\"\tr\tsubprogram:Tagged_Procedure\tfile:\np1\tinput.adb\t/^    procedure p1 is\t$/;\"\tr\tsubprogram:Tagged_Procedure\tfile:\nNot_Tagged_Procedure\tinput.adb\t/^  procedure Not_Tagged_Procedure is$/;\"\tr\tsubprogram:Test\tfile:\n"
  },
  {
    "path": "Units/parser-ada.r/ada-expression-function.d/input.adb",
    "content": "with Ada.Text_IO;\t\n\nprocedure Test is\n\n  My_Type : Boolean := True;\n\n  procedure Tagged_Procedure is\n    function Boolean_As_String return String is\n      (case My_Type is\n         when True  => \"True Value\",\n         when False => \"False Value\");\n\t \n    function Another_Boolean_As_String return String is\n      (case My_Type is when True  => \"; function dummy0 return String is (\",\n         when False => \"; function dummy1 return String is (\");\t      \n    procedure p0 is\t\n    begin\n        Ada.Text_IO.put (\"-0\");\n    end p0;\t \t \n    function Yet_Boolean_As_String return String is\n      (case My_Type is\n         when True  => \"1\",\n         when False => \"0\");\n    procedure p1 is\t\n    begin\n        Ada.Text_IO.put (\"-1\");\n    end p1;\t \n  begin\n    null;\n  end Tagged_Procedure;\n\n  procedure Not_Tagged_Procedure is\n  begin\n    null;\n  end Not_Tagged_Procedure;\nbegin\n  null;\nend Test;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-function.d/args.ctags",
    "content": "--language-force=Ada\n"
  },
  {
    "path": "Units/parser-ada.r/ada-function.d/input.broken",
    "content": "function a(){}}function b("
  },
  {
    "path": "Units/parser-ada.r/ada-generic-in-package.d/args.ctags",
    "content": "--sort=no\n--kinds-Ada=+{formal}\n"
  },
  {
    "path": "Units/parser-ada.r/ada-generic-in-package.d/expected.tags-e",
    "content": "\f\ninput.ads,278\npackage My_Package isMy_Package/s\u00012,48\n  package Conversions isConversions/s\u00016,108\n    function From_Big_Real (Arg : Integer) return Num;From_Big_Real/f\u00017,133\n    type Num is digits <>;Num\u00015,81\n  type Missing_Tag is recordMissing_Tag/t\u000110,208\n    Num : Integer;Num\u000111,237\n\f\ninput_1.adb,1666\nprocedure Input_1 isInput_1/p\u00011,0\n  procedure Generic_Reverse_Array (X : in out Array_T);Generic_Reverse_Array/p\u00019,200\n    type T is private;T\u00014,32\n    type Index is range <>;Index\u00015,55\n    type Array_T is array (Index range <>) of T;Array_T\u00016,83\n    with function Img (A, B: T) return boolean;Img\u00018,152\n  procedure Generic_Reverse_Array (X : in out Array_T) isGeneric_Reverse_Array/p\u000111,257\n\tTmp     : T;Tmp\u000115,389\n\tX_Left  : T renames X (I);X_Left\u000116,403\n\tX_Right : T renames X (X'Last + X'First - I);X_Right\u000117,431\n  type Color is (None, Black, Red, Green, Blue, White);Color/t\u000126,603\n  type Color is (None, Black, Red, Green, Blue, White);None\u000126,603\n  type Color is (None, Black, Red, Green, Blue, White);Black\u000126,603\n  type Color is (None, Black, Red, Green, Blue, White);Red\u000126,603\n  type Color is (None, Black, Red, Green, Blue, White);Green\u000126,603\n  type Color is (None, Black, Red, Green, Blue, White);Blue\u000126,603\n  type Color is (None, Black, Red, Green, Blue, White);White\u000126,603\n  type Color_Array is array (Integer range <>) of Color;Color_Array/t\u000127,659\n  procedure Reverse_Color_Array is new Generic_Reverse_ArrayReverse_Color_Array/p\u000128,716\n  type Shape is (None, Circle, Triangle, Square);Shape/t\u000131,859\n  type Shape is (None, Circle, Triangle, Square);None\u000131,859\n  type Shape is (None, Circle, Triangle, Square);Circle\u000131,859\n  type Shape is (None, Circle, Triangle, Square);Triangle\u000131,859\n  type Shape is (None, Circle, Triangle, Square);Square\u000131,859\n  type Shape_Array is array (Integer range <>) of Shape;Shape_Array/t\u000132,909\n  procedure Reverse_Shape_Array is new Generic_Reverse_ArrayReverse_Shape_Array/p\u000133,966\n\f\ninput_2.ads,301\npackage input_2 isinput_2/s\u00011,0\n  type Generator is null record;Generator/t\u00013,20\n    type Unsigned is mod <>;Unsigned\u00015,63\n    type Real is digits <>;Real\u00016,92\n    with function Random (G: Generator) return Unsigned is <>;Random\u00017,120\n  function Random (G: Generator) return Real;Random/f\u00018,183\n"
  },
  {
    "path": "Units/parser-ada.r/ada-generic-in-package.d/input.ads",
    "content": "--  Taken from #2925 submitted by @koenmeersman\npackage My_Package is\n\n  generic\n    type Num is digits <>;\n  package Conversions is\n    function From_Big_Real (Arg : Integer) return Num;\n  end Conversions;\n\n  type Missing_Tag is record\n    Num : Integer;\n  end record;\n\nend My_Package;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-generic-in-package.d/input_1.adb",
    "content": "procedure Input_1 is\n\n  generic\n    type T is private;\n    type Index is range <>;\n    type Array_T is array (Index range <>) of T;\n    Null_Value : T;\n    with function Img (A, B: T) return boolean;\n  procedure Generic_Reverse_Array (X : in out Array_T);\n\n  procedure Generic_Reverse_Array (X : in out Array_T) is\n  begin\n    for I in X'First .. (X'Last + X'First) / 2 loop\n      declare\n\tTmp     : T;\n\tX_Left  : T renames X (I);\n\tX_Right : T renames X (X'Last + X'First - I);\n      begin\n\tTmp     := X_Left;\n\tX_Left  := X_Right;\n\tX_Right := Tmp;\n      end;\n    end loop;\n  end Generic_Reverse_Array;\n\n  type Color is (None, Black, Red, Green, Blue, White);\n  type Color_Array is array (Integer range <>) of Color;\n  procedure Reverse_Color_Array is new Generic_Reverse_Array\n     (T => Color, Index => Integer, Array_T => Color_Array, Null_Value => None);\n\n  type Shape is (None, Circle, Triangle, Square);\n  type Shape_Array is array (Integer range <>) of Shape;\n  procedure Reverse_Shape_Array is new Generic_Reverse_Array\n     (T => Shape, Index => Integer, Array_T => Shape_Array, Null_Value => None);\n\nbegin\n  null;\nend Input_1;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-generic-in-package.d/input_2.ads",
    "content": "package input_2 is\n\n  type Generator is null record;\n  generic\n    type Unsigned is mod <>;\n    type Real is digits <>;\n    with function Random (G: Generator) return Unsigned is <>;\n  function Random (G: Generator) return Real;\n\nend input_2;"
  },
  {
    "path": "Units/parser-ada.r/ada-is-end.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ada.r/ada-is-end.d/expected.tags",
    "content": "Seg_Fault_Example\tinput.ada\t/^procedure Seg_Fault_Example is$/;\"\tr\n"
  },
  {
    "path": "Units/parser-ada.r/ada-is-end.d/input.ada",
    "content": "with Ada.Text_IO;\n\nprocedure Seg_Fault_Example is\n\n"
  },
  {
    "path": "Units/parser-ada.r/ada-label.d/args.ctags",
    "content": "--sort=no\n--kinds-Ada=\"\"\n--kinds-Ada=+{label}"
  },
  {
    "path": "Units/parser-ada.r/ada-label.d/expected.tags",
    "content": "Null_Before_Label\tinput.adb\t/^  <<Null_Before_Label>> null;  <<Null_After_Label>>$/;\"\tb\tsubprogram:Input\tfile:\nNull_After_Label\tinput.adb\t/^  <<Null_Before_Label>> null;  <<Null_After_Label>>$/;\"\tb\tsubprogram:Input\tfile:\nAssignment_Before_Label\tinput.adb\t/^  <<Assignment_Before_Label>> X := 1; <<Assignment_After_Label>>$/;\"\tb\tsubprogram:Input\tfile:\nAssignment_After_Label\tinput.adb\t/^  <<Assignment_Before_Label>> X := 1; <<Assignment_After_Label>>$/;\"\tb\tsubprogram:Input\tfile:\nExit_Before_Label\tinput.adb\t/^      <<Exit_Before_Label>> exit; <<Exit_After_Label>>$/;\"\tb\tanon:loop\tfile:\nExit_After_Label\tinput.adb\t/^      <<Exit_Before_Label>> exit; <<Exit_After_Label>>$/;\"\tb\tanon:loop\tfile:\nGoto_Before_Label\tinput.adb\t/^      <<Goto_Before_Label>> goto Assignment_Before_Label;  <<Goto_After_Label>>$/;\"\tb\tanon:loop\tfile:\nGoto_After_Label\tinput.adb\t/^      <<Goto_Before_Label>> goto Assignment_Before_Label;  <<Goto_After_Label>>$/;\"\tb\tanon:loop\tfile:\nProcedure_Call_Before_Label\tinput.adb\t/^  <<Procedure_Call_Before_Label>> Ada.Text_IO.Put_Line (\"Hello World\"); <<Procedure_Call_After_L/;\"\tb\tsubprogram:Input\tfile:\nProcedure_Call_After_Label\tinput.adb\t/^  <<Procedure_Call_Before_Label>> Ada.Text_IO.Put_Line (\"Hello World\"); <<Procedure_Call_After_L/;\"\tb\tsubprogram:Input\tfile:\nReturn_Before_Label\tinput.adb\t/^    <<Return_Before_Label>> return; <<Return_After_Label>>$/;\"\tb\tsubprogram:Input\tfile:\nReturn_After_Label\tinput.adb\t/^    <<Return_Before_Label>> return; <<Return_After_Label>>$/;\"\tb\tsubprogram:Input\tfile:\nAccept_Before_Label\tinput.adb\t/^      <<Accept_Before_Label>> accept Start(Nr : in Natural) do$/;\"\tb\ttask:Server\tfile:\nRequeue_Before_Label\tinput.adb\t/^\t<<Requeue_Before_Label>> requeue Start; <<Requeue_After_Label>>$/;\"\tb\tentry:Start\tfile:\nRequeue_After_Label\tinput.adb\t/^\t<<Requeue_Before_Label>> requeue Start; <<Requeue_After_Label>>$/;\"\tb\tentry:Start\tfile:\nAccept_After_Label\tinput.adb\t/^      end Start; <<Accept_After_Label>>$/;\"\tb\ttask:Server\tfile:\nEntry_Before_Label\tinput.adb\t/^    <<Entry_Before_Label>> My_Task.Start (1); <<Entry_After_Label>>$/;\"\tb\tanon:declare\tfile:\nEntry_After_Label\tinput.adb\t/^    <<Entry_Before_Label>> My_Task.Start (1); <<Entry_After_Label>>$/;\"\tb\tanon:declare\tfile:\nDelay_Before_Label\tinput.adb\t/^    <<Delay_Before_Label>> delay 100.0; <<Delay_After_Label>>$/;\"\tb\tanon:declare\tfile:\nDelay_After_Label\tinput.adb\t/^    <<Delay_Before_Label>> delay 100.0; <<Delay_After_Label>>$/;\"\tb\tanon:declare\tfile:\nAbort_Before_Label\tinput.adb\t/^    <<Abort_Before_Label>> abort My_Task; <<Abort_After_Label>>$/;\"\tb\tanon:declare\tfile:\nAbort_After_Label\tinput.adb\t/^    <<Abort_Before_Label>> abort My_Task; <<Abort_After_Label>>$/;\"\tb\tanon:declare\tfile:\nSelect_Before_Statement\tinput.adb\t/^      <<Select_Before_Statement>> select$/;\"\tb\tanon:declare\tfile:\nSelect_After_Statement\tinput.adb\t/^      end select; <<Select_After_Statement>>$/;\"\tb\ttask:Server\tfile:\nCode_Before_Label\tinput.adb\t/^  <<Code_Before_Label>>$/;\"\tb\ttask:Server\tfile:\nCode_After_Label\tinput.adb\t/^  <<Code_After_Label>>$/;\"\tb\ttask:Server\tfile:\nMultiple_1_Before_Label\tinput.adb\t/^  <<Multiple_1_Before_Label>> <<Multiple_2_Before_Label>> <<Multiple_3_Before_Label>> null; <<Mu/;\"\tb\ttask:Server\tfile:\nMultiple_2_Before_Label\tinput.adb\t/^  <<Multiple_1_Before_Label>> <<Multiple_2_Before_Label>> <<Multiple_3_Before_Label>> null; <<Mu/;\"\tb\ttask:Server\tfile:\nMultiple_3_Before_Label\tinput.adb\t/^  <<Multiple_1_Before_Label>> <<Multiple_2_Before_Label>> <<Multiple_3_Before_Label>> null; <<Mu/;\"\tb\ttask:Server\tfile:\nMultiple_1_After_Label\tinput.adb\t/^  <<Multiple_1_Before_Label>> <<Multiple_2_Before_Label>> <<Multiple_3_Before_Label>> null; <<Mu/;\"\tb\ttask:Server\tfile:\nMultiple_2_After_Label\tinput.adb\t/^  <<Multiple_1_Before_Label>> <<Multiple_2_Before_Label>> <<Multiple_3_Before_Label>> null; <<Mu/;\"\tb\ttask:Server\tfile:\nMultiple_3_After_Label\tinput.adb\t/^  <<Multiple_1_Before_Label>> <<Multiple_2_Before_Label>> <<Multiple_3_Before_Label>> null; <<Mu/;\"\tb\ttask:Server\tfile:\nRaise_Before_Label\tinput.adb\t/^  <<Raise_Before_Label>> raise constraint_error; <<Raise_After_Label>>$/;\"\tb\ttask:Server\tfile:\nRaise_After_Label\tinput.adb\t/^  <<Raise_Before_Label>> raise constraint_error; <<Raise_After_Label>>$/;\"\tb\ttask:Server\tfile:\nIf_Before_Label\tinput.adb\t/^  <<If_Before_Label>> if X>1 then$/;\"\tb\ttask:Server\tfile:\nIf_After_Label\tinput.adb\t/^  end if; <<If_After_Label>> $/;\"\tb\ttask:Server\tfile:\nCase_Before_Label\tinput.adb\t/^  <<Case_Before_Label>> case X is$/;\"\tb\ttask:Server\tfile:\nCase_Code_Before_Label\tinput.adb\t/^    when 1 => <<Case_Code_Before_Label>> Ada.Text_IO.Put_Line (\"1\"); <<Case_Code_After_Label>> $/;\"\tb\ttask:Server\tfile:\nCase_Code_After_Label\tinput.adb\t/^    when 1 => <<Case_Code_Before_Label>> Ada.Text_IO.Put_Line (\"1\"); <<Case_Code_After_Label>> $/;\"\tb\ttask:Server\tfile:\nCase_After_Label\tinput.adb\t/^  end case; <<Case_After_Label>>$/;\"\tb\ttask:Server\tfile:\nLoop_Before_Label\tinput.adb\t/^  <<Loop_Before_Label>> loop\t$/;\"\tb\ttask:Server\tfile:\nLoop_Code_Before_Label\tinput.adb\t/^    <<Loop_Code_Before_Label>> Ada.Text_IO.Put_Line (\"1\"); <<Loop_Code_After_Label>>$/;\"\tb\tanon:loop\tfile:\nLoop_Code_After_Label\tinput.adb\t/^    <<Loop_Code_Before_Label>> Ada.Text_IO.Put_Line (\"1\"); <<Loop_Code_After_Label>>$/;\"\tb\tanon:loop\tfile:\nLoop_After_Label\tinput.adb\t/^  end loop; <<Loop_After_Label>>$/;\"\tb\ttask:Server\tfile:\nWhile_Before_Label\tinput.adb\t/^  <<While_Before_Label>> while X > 1 loop$/;\"\tb\ttask:Server\tfile:\nWhile_Code_Before_Label\tinput.adb\t/^    <<While_Code_Before_Label>> X := X + 1; <<While_Code_After_Label>>$/;\"\tb\tanon:loop\tfile:\nWhile_Code_After_Label\tinput.adb\t/^    <<While_Code_Before_Label>> X := X + 1; <<While_Code_After_Label>>$/;\"\tb\tanon:loop\tfile:\nWhile_After_Label\tinput.adb\t/^  end loop; <<While_After_Label>>$/;\"\tb\ttask:Server\tfile:\nFor_Before_Label\tinput.adb\t/^  <<For_Before_Label>> for I in 1 .. X loop$/;\"\tb\ttask:Server\tfile:\nFor_Code_Before_Label\tinput.adb\t/^    <<For_Code_Before_Label>> Ada.Text_IO.Put_Line (X'Image); <<For_Code_After_Label>>  $/;\"\tb\tanon:loop\tfile:\nFor_Code_After_Label\tinput.adb\t/^    <<For_Code_Before_Label>> Ada.Text_IO.Put_Line (X'Image); <<For_Code_After_Label>>  $/;\"\tb\tanon:loop\tfile:\nFor_After_Label\tinput.adb\t/^  end loop; <<For_After_Label>>$/;\"\tb\ttask:Server\tfile:\nDeclare_Before_Label\tinput.adb\t/^  <<Declare_Before_Label>> declare$/;\"\tb\ttask:Server\tfile:\nDeclare_After_Label\tinput.adb\t/^  end; <<Declare_After_Label>>$/;\"\tb\ttask:Server\tfile:\nBegin_Before_Label\tinput.adb\t/^  <<Begin_Before_Label>> begin$/;\"\tb\ttask:Server\tfile:\nBegin_After_Label\tinput.adb\t/^  end; <<Begin_After_Label>>$/;\"\tb\ttask:Server\tfile:\nReturn_Before_Label\tinput.adb\t/^      <<Return_Before_Label>> return Coord : Coordinate do$/;\"\tb\tsubprogram:Extended_Return\tfile:\nReturn_After_Label\tinput.adb\t/^      end return; <<Return_After_Label>>$/;\"\tb\tsubprogram:Extended_Return\tfile:\n"
  },
  {
    "path": "Units/parser-ada.r/ada-label.d/input.adb",
    "content": "-- Test labels\n-- See: ARM 5.1 :  Simple and Compound Statements - Sequences of Statements\n--\n-- A label should come before a simple statement or a compound statment.\n--\n-- Check if file compiles: gnatmake -gnatc Units/parser-ada.r/ada-label.d/input.adb\n--\nwith Ada.Text_IO;\n\nprocedure Input is\n  X : Integer;\nbegin\n  -- ARM 5.1(4/2) : Simple statements\n  --   null statement\n  <<Null_Before_Label>> null;  <<Null_After_Label>>\n\n  --   assignment\n  <<Assignment_Before_Label>> X := 1; <<Assignment_After_Label>>\n\n  for I in 1 .. X loop\n    if I > 1 then\n      --   exit statement\n      <<Exit_Before_Label>> exit; <<Exit_After_Label>>\n    elsif I > 2 then\n      --   goto statement\n      <<Goto_Before_Label>> goto Assignment_Before_Label;  <<Goto_After_Label>>\n    end if;\n  end loop;\n  \n  --   procedure call statement\n  <<Procedure_Call_Before_Label>> Ada.Text_IO.Put_Line (\"Hello World\"); <<Procedure_Call_After_Label>>\n  if X > 1 then\n    --   simple return statement\n    <<Return_Before_Label>> return; <<Return_After_Label>>\n  end if;\n\n  declare\n    task type Server is\n      entry Start(Nr : in Natural);\n    end Server;\n\n    task body Server is\n      Iden : Natural;\n    begin\n      <<Accept_Before_Label>> accept Start(Nr : in Natural) do\n        Iden := Nr;\n\t<<Requeue_Before_Label>> requeue Start; <<Requeue_After_Label>>\n      end Start; <<Accept_After_Label>>\n      Ada.Text_IO.Put_Line (\"Working...\");\n    end;\n\n    My_Task : Server;\n  begin\n    <<Entry_Before_Label>> My_Task.Start (1); <<Entry_After_Label>>\n    <<Delay_Before_Label>> delay 100.0; <<Delay_After_Label>>\n    <<Abort_Before_Label>> abort My_Task; <<Abort_After_Label>>\n    if X > 1 then\n      <<Select_Before_Statement>> select\n        My_Task.Start (1);\n      or\n        delay 10.0;\n      end select; <<Select_After_Statement>>\n    end if;\n  end;\n  <<Code_Before_Label>>\n  Ada.Text_IO.Put_Line (\"Code 1\");\n  Ada.Text_IO.Put_Line (\"Code 2\"); \n  <<Code_After_Label>>\n  <<Multiple_1_Before_Label>> <<Multiple_2_Before_Label>> <<Multiple_3_Before_Label>> null; <<Multiple_1_After_Label>> <<Multiple_2_After_Label>> <<Multiple_3_After_Label>>\n  <<Raise_Before_Label>> raise constraint_error; <<Raise_After_Label>>\n\n  -- ARM 5.1(5/2) Compound statements\n  --   if statement\n  <<If_Before_Label>> if X>1 then\n    Ada.Text_IO.Put_Line (\"X>1\");\n  elsif X > 2 then\n    Ada.Text_IO.Put_Line (\"X > 2\");\n  end if; <<If_After_Label>> \n\n  --   case statement\n  <<Case_Before_Label>> case X is\n    when 1 => <<Case_Code_Before_Label>> Ada.Text_IO.Put_Line (\"1\"); <<Case_Code_After_Label>> \n    when 2 => Ada.Text_IO.Put_Line (\"2\");\n    when others => Ada.Text_IO.Put_Line (\"2\");\n  end case; <<Case_After_Label>>\n\n  --   loop statement\n  <<Loop_Before_Label>> loop\t\n    <<Loop_Code_Before_Label>> Ada.Text_IO.Put_Line (\"1\"); <<Loop_Code_After_Label>>\n    exit;\n  end loop; <<Loop_After_Label>>\n\n  <<While_Before_Label>> while X > 1 loop\n    <<While_Code_Before_Label>> X := X + 1; <<While_Code_After_Label>>\n  end loop; <<While_After_Label>>\n  \n  <<For_Before_Label>> for I in 1 .. X loop\n    <<For_Code_Before_Label>> Ada.Text_IO.Put_Line (X'Image); <<For_Code_After_Label>>  \n  end loop; <<For_After_Label>>\n  \n  --   block statement\n  <<Declare_Before_Label>> declare\n    Y : Integer;\n  begin\n    Y := X + 1;\n    Ada.Text_IO.Put_Line (Y'Image);\n  end; <<Declare_After_Label>>\n\n  <<Begin_Before_Label>> begin\n    null;\n  end; <<Begin_After_Label>>\n\n  --   extended return statement\n  declare\n    type Coordinate is record\n      X : Integer;\n      Y : Integer; \n    end record;\n    \n    function Extended_Return return Coordinate is\n    begin\n      <<Return_Before_Label>> return Coord : Coordinate do\n        Coord.X := 10;\n\tCoord.Y := 20;\n      end return; <<Return_After_Label>>\n    end Extended_Return;\n  begin\n    null;\n  end;\n\n  --   accept statement  See above <<Accept_Before_Label>> and <<Accept_After_Label>>\n  --   select statement  See above <<Select_Before_Statement>> and <<Select_After_Statement>> \nend Input;"
  },
  {
    "path": "Units/parser-ada.r/ada-overriding.d/args.ctags",
    "content": "--kinds-Ada=+E\n--sort=no\n"
  },
  {
    "path": "Units/parser-ada.r/ada-overriding.d/expected.tags",
    "content": "Input\tinput.ads\t/^package Input$/;\"\tP\nTasche_T\tinput.ads\t/^   task type Tasche_T is new Carte_T with$/;\"\tK\tpackspec:Input\nCoucou\tinput.ads\t/^      entry Coucou;$/;\"\tE\ttaskspec:Tasche_T\nInutile\tinput.ads\t/^   procedure Inutile$/;\"\tR\tpackspec:Input\ninput_2\tinput_2.adb\t/^package body input_2$/;\"\tp\nTasche_T\tinput_2.adb\t/^   task body Tasche_T is$/;\"\tk\tpackage:input_2\tfile:\nCoucou\tinput_2.adb\t/^      accept Coucou do$/;\"\te\ttask:Tasche_T\tfile:\nInutile\tinput_2.adb\t/^   procedure Inutile$/;\"\tr\tpackage:input_2\tfile:\nInput_3\tinput_3.ads\t/^package Input_3 is$/;\"\tP\nObject\tinput_3.ads\t/^    type Object is tagged null record;$/;\"\tt\tpackspec:Input_3\nPrimitive\tinput_3.ads\t/^   function  Primitive return access Object; -- new in Ada 2005$/;\"\tR\tpackspec:Input_3\nDerived_Object\tinput_3.ads\t/^   type Derived_Object is new Object with null record;$/;\"\tt\tpackspec:Input_3\nPrimitive\tinput_3.ads\t/^   procedure Primitive (This : in Derived_Object); -- new primitive operation$/;\"\tR\tpackspec:Input_3\nPrimitive\tinput_3.ads\t/^   function  Primitive return access Derived_Object;$/;\"\tR\tpackspec:Input_3\n"
  },
  {
    "path": "Units/parser-ada.r/ada-overriding.d/input.ads",
    "content": "--  Taken from #2382 submitted by @JulienPivard\n--  @summary\n--  Implémentation par une tâche.\n--  @description\n--  Implémentation par une tache de la classe synchronisé.\n--  @group Version tâche\n--\n--  package Carte_P.Tasche_P\npackage Input\n   with\n      Pure           => False,\n      Preelaborate   => False,\n      Elaborate_Body => True,\n      Spark_Mode     => Off\nis\n\n   ---------------------------------------------------------------------------\n   task type Tasche_T is new Carte_T with\n   --  Implémentation par une tâche de l'interface Carte_T.\n\n      -----------------------------------\n      overriding\n      entry Coucou;\n      --  Implémentation par un accept.\n\n      -----------------------------------\n      --  overriding\n      --  entry Inutile;\n      --  Implémentation par un accept.\n      --  @param This\n      --  La carte.\n   end Tasche_T;\n   ---------------------------------------------------------------------------\n\n   overriding\n   procedure Inutile\n      (This : in out Tasche_T);\n   --  Implémentation par une procédure.\n   --  @param This\n   --  La carte.\n\nend Carte_P.Tasche_P;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-overriding.d/input_2.adb",
    "content": "--  Taken from #2382 submitted by @JulienPivard\nwith Ada.Text_IO;\n\npackage body input_2\n   with Spark_Mode => Off\nis\n\n   ---------------------------------------------------------------------------\n   task body Tasche_T is\n      --  Les déclarations qui vont bien.\n   begin\n      accept Coucou do\n         null;\n      end Coucou;\n\n      Ada.Text_IO.Put_Line (Item => \"Wesh gros je suis une tâche\");\n\n      --  accept Inutile do\n      --     null;\n      --  end Inutile;\n      abort Tasche_T;\n   end Tasche_T;\n   ---------------------------------------------------------------------------\n\n   ---------------------------------------------------------------------------\n   overriding\n   procedure Inutile\n      (This : in out Tasche_T)\n   is\n   begin\n      null;\n   end Inutile;\n   ---------------------------------------------------------------------------\n\nend input_2;\n\n"
  },
  {
    "path": "Units/parser-ada.r/ada-overriding.d/input_3.ads",
    "content": "--  Taken from https://en.wikibooks.org/wiki/Ada_Programming/Object_Orientation#Overriding_indicators\npackage Input_3 is\n    type Object is tagged null record;\n\n   function  Primitive return access Object; -- new in Ada 2005\n\n   type Derived_Object is new Object with null record;\n\n   not overriding -- new optional keywords in Ada 2005\n   procedure Primitive (This : in Derived_Object); -- new primitive operation\n\n   overriding\n   function  Primitive return access Derived_Object;\nend X;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-partial-bug.d/expected.tags",
    "content": "Altivec\tinput.adb\t/^procedure Altivec is$/;\"\tr\n"
  },
  {
    "path": "Units/parser-ada.r/ada-partial-bug.d/input.adb",
    "content": "procedure Altivec is\n\n   V"
  },
  {
    "path": "Units/parser-ada.r/ada-partial-bug2.d/input.adb",
    "content": "procedure Altivec is:\n\n   V"
  },
  {
    "path": "Units/parser-ada.r/ada-partial-type.d/expected.tags",
    "content": "One\tinput.ads\t/^        One: access T;$/;\"\tc\ttype:T\tfile:\nP\tinput.ads\t/^package P is$/;\"\tP\nT\tinput.ads\t/^    type T is record$/;\"\tt\tpackspec:P\nTwo\tinput.ads\t/^        Two: access T$/;\"\tc\ttype:T\tfile:\n"
  },
  {
    "path": "Units/parser-ada.r/ada-partial-type.d/input.ads",
    "content": "package P is\n    type T;\n    type T is record\n        One: access T;\n        -- Missing semicolon used to choke the Ada parser\n        Two: access T\n    end record;\nend P;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-protected.d/input.adb",
    "content": "protected\n"
  },
  {
    "path": "Units/parser-ada.r/ada-separate.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-ada.r/ada-separate.d/expected.tags",
    "content": "Buffer\tinput.adb\t/^separate (Buffer);$/;\"\tp\troles:subunit\nTest\tinput.adb\t/^package body Test is$/;\"\tp\tpackage:Buffer\troles:def\nParent\tinput-1.adb\t/^package body Parent is$/;\"\tp\troles:def\nVariable\tinput-1.adb\t/^    Variable : String := \"Hello, there.\";$/;\"\tv\tpackage:Parent\tfile:\troles:def\nParent\tinput-1.adb\t/^separate(Parent)$/;\"\tp\troles:subunit\nInner\tinput-1.adb\t/^procedure Inner is$/;\"\tr\tpackage:Parent\troles:def\n"
  },
  {
    "path": "Units/parser-ada.r/ada-separate.d/input-1.adb",
    "content": "--  Taken from https://www.adaic.org/resources/add_content/standards/05rm/html/RM-10-1-3.html\npackage body Parent is\n    Variable : String := \"Hello, there.\";\n    procedure Inner is separate;\nend Parent;\n\nwith Ada.Text_IO;\nseparate(Parent)\nprocedure Inner is\nbegin\n    Ada.Text_IO.Put_Line(Variable);\nend Inner;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-separate.d/input.adb",
    "content": "--  Taken from #2943 submitted by @koenmeersman\nwith Ada.Text_IO;\n\nseparate (Buffer);\n\npackage body Test is\n  procedure Inner is separate;\nbegin\n  null;\nend Test;\n\n"
  },
  {
    "path": "Units/parser-ada.r/ada-string-literal.d/expected.tags-e",
    "content": "\f\ninput.adb,660\nprocedure Reproduce isReproduce/p\u00012,18\n  type String_T is new String;String_T/t\u00014,42\n  function \"+\" (Left : String) return String_T is (String_T(Left));\"+\"/f\u00015,73\n  function \"+\" (Left : String_T; Right : String) return String_T is (String_T(String (Left) & Ri\"+\"/f\u00016,141\n  package Generic_G isGeneric_G/s\u000110,283\n    procedure Go;Go/p\u000111,306\n  package body Generic_G isGeneric_G/b\u000114,342\n    procedure Go isGo/p\u000115,370\n  package Impl isImpl/s\u000121,481\n    procedure Go;Go/p\u000122,499\n  package body Impl isImpl/b\u000125,530\n    package Generic1 is new Generic_G (Description => +\"; \" +\":\");Generic1/s\u000126,553\n    procedure Go renames Generic1.Go;Go/p\u000127,620\n"
  },
  {
    "path": "Units/parser-ada.r/ada-string-literal.d/input.adb",
    "content": "with Ada.Text_IO;\nprocedure Reproduce is\n\n  type String_T is new String;\n  function \"+\" (Left : String) return String_T is (String_T(Left));\n  function \"+\" (Left : String_T; Right : String) return String_T is (String_T(String (Left) & Right));\n\n  generic\n    Description : String_T;\n  package Generic_G is\n    procedure Go;\n  end Generic_G;\n\n  package body Generic_G is\n    procedure Go is\n    begin\n      Ada.Text_IO.Put_Line (String (Description));\n    end Go;\n  end Generic_G;\n\n  package Impl is\n    procedure Go;\n  end Impl;\n\n  package body Impl is\n    package Generic1 is new Generic_G (Description => +\"; \" +\":\");\n    procedure Go renames Generic1.Go;\n  end Impl;\n\nbegin\n  Impl.Go;\nend Reproduce;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-type-new-without-with.d/args.ctags",
    "content": "--sort=no\n--kinds-Ada=*\n"
  },
  {
    "path": "Units/parser-ada.r/ada-type-new-without-with.d/expected.tags",
    "content": "Input\tinput.adb\t/^procedure Input  is$/;\"\tr\nPak\tinput.adb\t/^   package Pak  is$/;\"\tP\tsubprogram:Input\tfile:\nInteger_1\tinput.adb\t/^      type Integer_1  is  range 1 .. 10;$/;\"\tt\tpackspec:Pak\nP\tinput.adb\t/^      procedure P (I:  in Integer_1); -- primitive operation, assumes 1 .. 10$/;\"\tR\tpackspec:Pak\nI\tinput.adb\t/^      procedure P (I:  in Integer_1); -- primitive operation, assumes 1 .. 10$/;\"\ta\tsubprogspec:P\tfile:\nInteger_2\tinput.adb\t/^      type Integer_2  is  new Integer_1  range 8 .. 10; -- must not break P's assumption$/;\"\tt\tpackspec:Pak\nPak\tinput.adb\t/^   package  body Pak  is$/;\"\tp\tsubprogram:Input\tfile:\nA\tinput.adb\t/^   A: Integer_1 := 4;$/;\"\tv\tsubprogram:Input\tfile:\nB\tinput.adb\t/^   B: Integer_2 := 9;$/;\"\tv\tsubprogram:Input\tfile:\n"
  },
  {
    "path": "Units/parser-ada.r/ada-type-new-without-with.d/input.adb",
    "content": "-- Taken from https://en.wikibooks.org/wiki/Ada_Programming/Type_System\n--\n-- This code has a from of \"type foo is new ...\"\n-- Though \"new\" is used in the form, \"with\" doesn't\n-- follow \"new\" like \"type foo is new bar with ...\".\n--\nprocedure Input  is\n\n   package Pak  is\n      type Integer_1  is  range 1 .. 10;\n      procedure P (I:  in Integer_1); -- primitive operation, assumes 1 .. 10\n      type Integer_2  is  new Integer_1  range 8 .. 10; -- must not break P's assumption\n\t\t\t\t\t\t\t-- procedure P (I: in Integer_2);  inherited P implicitly defined here\n   end Pak;\n\n   package  body Pak  is\n      -- omitted\n   end Pak;\n\n   use Pak;\n   A: Integer_1 := 4;\n   B: Integer_2 := 9;\n\nbegin\n\n   P (B); -- OK, call the inherited operation\n\nend Derived_Types;\n"
  },
  {
    "path": "Units/parser-ada.r/ada-whitespaces-between-id-and-colon.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ada.r/ada-whitespaces-between-id-and-colon.d/expected.tags",
    "content": "Go\tinput.adb\t/^procedure Go is$/;\"\tr\nLoop_Label\tinput.adb\t/^  Loop_Label :$/;\"\ti\tsubprogram:Go\tfile:\nNot_Tagged\tinput.adb\t/^      procedure Not_Tagged is$/;\"\tr\tanon:declare\tfile:\n"
  },
  {
    "path": "Units/parser-ada.r/ada-whitespaces-between-id-and-colon.d/input.adb",
    "content": "--  Taken from #2933 submitted by @koenmeersman\nprocedure Go is\nbegin\n  Loop_Label :\n  while True loop\n    declare\n      procedure Not_Tagged is\n      begin\n        null;\n      end Step_T;\n    begin\n      null;\n    end;\n  end loop Loop_Label;\nend Go;\n"
  },
  {
    "path": "Units/parser-ansibleplaybook.r/broken-input.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-ansibleplaybook.r/broken-input.d/args.ctags",
    "content": "--language-force=AnsiblePlaybook\n"
  },
  {
    "path": "Units/parser-ansibleplaybook.r/broken-input.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-ansibleplaybook.r/broken-input.d/input.yml",
    "content": "f: x\n    y:\n"
  },
  {
    "path": "Units/parser-ansibleplaybook.r/play-name.d/args.ctags",
    "content": "--fields=+e\n"
  },
  {
    "path": "Units/parser-ansibleplaybook.r/play-name.d/expected.tags",
    "content": "Update ctags\tinput.yml\t/^- name: Update ctags$/;\"\tp\tend:3\nUpdate etags\tinput.yml\t/^- name: Update etags$/;\"\tp\tend:5\n"
  },
  {
    "path": "Units/parser-ansibleplaybook.r/play-name.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-ansibleplaybook.r/play-name.d/input.yml",
    "content": "- name: Update ctags\n  yum: pkg=ctags latest\n- name: Update etags\n  yum: pkg=etags latest\n"
  },
  {
    "path": "Units/parser-ant.r/regex-based.d/args.ctags",
    "content": "--language-force=ant\n"
  },
  {
    "path": "Units/parser-ant.r/regex-based.d/expected.tags",
    "content": "MyProject\tinput.xml\t/^<project name=\"MyProject\" default=\"deploy\" basedir=\".\">$/;\"\tp\nclean\tinput.xml\t/^  <target name=\"clean\" depends=\"init\">$/;\"\tt\ncompile_something\tinput.xml\t/^  <target name=\"compile_something\" depends=\"init\">$/;\"\tt\ndeploy\tinput.xml\t/^    <target name=\"deploy\" depends=\"compile_something, generate_h_from_java\">$/;\"\tt\ngenerate_h_from_java\tinput.xml\t/^  <target name=\"generate_h_from_java\" depends=\"compile_something\">$/;\"\tt\ninit\tinput.xml\t/^  <target name=\"init\">$/;\"\tt\njavadoc\tinput.xml\t/^  <target name=\"javadoc\">$/;\"\tt\nrootDir\tinput.xml\t/^    <property name=\"rootDir\" value=\".\" \\/>$/;\"\tP\nsrcDir\tinput.xml\t/^    <property name=\"srcDir\" value=\"${rootDir}\\/src\" \\/>$/;\"\tP\n"
  },
  {
    "path": "Units/parser-ant.r/regex-based.d/features",
    "content": "!xpath\n"
  },
  {
    "path": "Units/parser-ant.r/regex-based.d/input.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n\r\n<project name=\"MyProject\" default=\"deploy\" basedir=\".\">\r\n  <import file=\"another.ant\"/>\r\n  <target name=\"init\">\r\n    <property environment=\"envvars\" />\r\n    <property name=\"rootDir\" value=\".\" />\r\n    <property name=\"srcDir\" value=\"${rootDir}/src\" />\r\n  \r\n    <path id=\"base.classpath\">\r\n      <pathelement location=\"${buildDir}\" />\r\n    </path>\r\n  </target>\r\n\r\n  <target name=\"clean\" depends=\"init\">\r\n    <delete dir=\"${buildDir}\"\r\n      verbose=\"false\"\r\n      quiet=\"false\"\r\n      />\r\n  </target>\r\n\r\n  <target name=\"compile_something\" depends=\"init\">\r\n    <mkdir dir=\"${buildDir}\" />\r\n    <mkdir dir=\"${buildDir}/images\" />\r\n    <javac srcdir=\"${javaDir}\"\r\n      destdir=\"${buildDir}\"\r\n      debug=\"on\"\r\n      optimize=\"off\"\r\n      verbose=\"no\"\r\n      listfiles=\"yes\"\r\n      deprecation=\"no\"\r\n      classpathref=\"base.classpath\"\r\n      />\r\n\r\n    <copy toDir=\"${buildDir}/images\">\r\n      <fileset dir=\"${javaImagesDir}\" includes=\"*.*\" />\r\n    </copy>\r\n\r\n  </target>\r\n\r\n  <!--target name=\"generate_h_from_java\" depends=\"compile_something\">\r\n    <exec executable=\"javah\" dir=\"${buildDir}\">\r\n    </exec>\r\n  </target-->\r\n\r\n  <target name=\"generate_h_from_java\" depends=\"compile_something\">\r\n    <javah destdir=\"${ulgateDir}\" classpath=\"${buildDir}\">\r\n    </javah>\r\n  </target>\r\n\r\n  <target name=\"javadoc\">\r\n    <delete dir=\"${javaDocDir}\"\r\n      verbose=\"false\"\r\n      quiet=\"false\"\r\n      />\r\n    <mkdir dir=\"${javaDocDir}\" />\r\n    <javadoc destdir=\"${javaDocDir}\"\r\n      classpathref=\"base.classpath\"\r\n      link=\"http://java.sun.com/j2se/1.4.1/docs/api/\"\r\n      verbose=\"no\"\r\n      additionalparam=\"-breakiterator\"\r\n      >\r\n      <fileset dir=\"${javaDir}\" />\r\n    </javadoc>\r\n  </target>\r\n\r\n    <target name=\"deploy\" depends=\"compile_something, generate_h_from_java\">\r\n\r\n      <delete dir=\"${deployDir}\"\r\n        verbose=\"false\"\r\n        quiet=\"false\"\r\n        />\r\n      <mkdir dir=\"${deployDir}\" />\r\n      <mkdir dir=\"${deployDir}/client\" />\r\n      <mkdir dir=\"${deployDir}/server\" />\r\n      \r\n      <jar jarfile=\"${deployDir}/server/something.jar\">\r\n        <fileset dir=\"${buildDir}\"\r\n           includes=\"images/**\"\r\n          />\r\n      </jar>\r\n      \r\n      <copy toDir=\"${deployDir}/client\" verbose=\"Yes\" >\r\n          <fileset dir=\"${binDir}\" includes=\"startClient.cmd\" />\r\n\t\t  <fileset dir=\"${binDir}\" includes=\"killProcess.vbs\" />\r\n      </copy>\r\n\r\n      <copy toDir=\"${deployDir}/server/sql\" verbose=\"Yes\" >\r\n  \t      <fileset dir=\"${sqlDir}\" includes=\"*.sql\" />\r\n      </copy>\r\n\r\n      <copy toDir=\"${deployDir}/server/samples\">\r\n        <fileset dir=\"${samplesDir}\" includes=\"**/*.*\" />\r\n      </copy>\r\n\r\n      <copy toDir=\"${deployDir}/doc\">\r\n        <fileset dir=\"${docDir}\" includes=\"**/*.*\" />\r\n      </copy>\r\n\r\n    </target>\r\n  \r\n</project>\r\n"
  },
  {
    "path": "Units/parser-ant.r/xpath-based-unix.d/args.ctags",
    "content": "--language-force=ant\n--extras=+r\n--fields=+rln\n"
  },
  {
    "path": "Units/parser-ant.r/xpath-based-unix.d/expected.tags",
    "content": "MyProject\tinput.xml\t/^<project name=\"MyProject\" default=\"deploy\" basedir=\".\">$/;\"\tp\tline:3\tlanguage:Ant\troles:def\nanother.ant\tinput.xml\t/^  <import file=\"another.ant\"\\/>$/;\"\ti\tline:4\tlanguage:Ant\tproject:MyProject\troles:imported\nbase.classpath\tinput.xml\t/^    <path id=\"base.classpath\">$/;\"\ti\tline:11\tlanguage:XML\troles:def\nclean\tinput.xml\t/^  <target name=\"clean\" depends=\"init\">$/;\"\tt\tline:16\tlanguage:Ant\tproject:MyProject\troles:def\ncompile_something\tinput.xml\t/^  <target name=\"compile_something\" depends=\"init\">$/;\"\tt\tline:23\tlanguage:Ant\tproject:MyProject\troles:def\ndeploy\tinput.xml\t/^    <target name=\"deploy\" depends=\"compile_something, generate_h_from_java\">$/;\"\tt\tline:68\tlanguage:Ant\tproject:MyProject\troles:def\ngenerate_h_from_java\tinput.xml\t/^  <target name=\"generate_h_from_java\" depends=\"compile_something\">$/;\"\tt\tline:47\tlanguage:Ant\tproject:MyProject\troles:def\ninit\tinput.xml\t/^  <target name=\"init\">$/;\"\tt\tline:6\tlanguage:Ant\tproject:MyProject\troles:def\njavadoc\tinput.xml\t/^  <target name=\"javadoc\">$/;\"\tt\tline:52\tlanguage:Ant\tproject:MyProject\troles:def\nx\tinput.xml\t/^  <property name=\"x\" value=\"y\" \\/>$/;\"\tP\tline:5\tlanguage:Ant\tproject:MyProject\troles:def\n"
  },
  {
    "path": "Units/parser-ant.r/xpath-based-unix.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-ant.r/xpath-based-unix.d/input.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<project name=\"MyProject\" default=\"deploy\" basedir=\".\">\n  <import file=\"another.ant\"/>\n  <property name=\"x\" value=\"y\" />\n  <target name=\"init\">\n    <property environment=\"envvars\" />\n    <property name=\"rootDir\" value=\".\" />\n    <property name=\"srcDir\" value=\"${rootDir}/src\" />\n  \n    <path id=\"base.classpath\">\n      <pathelement location=\"${buildDir}\" />\n    </path>\n  </target>\n\n  <target name=\"clean\" depends=\"init\">\n    <delete dir=\"${buildDir}\"\n      verbose=\"false\"\n      quiet=\"false\"\n      />\n  </target>\n\n  <target name=\"compile_something\" depends=\"init\">\n    <mkdir dir=\"${buildDir}\" />\n    <mkdir dir=\"${buildDir}/images\" />\n    <javac srcdir=\"${javaDir}\"\n      destdir=\"${buildDir}\"\n      debug=\"on\"\n      optimize=\"off\"\n      verbose=\"no\"\n      listfiles=\"yes\"\n      deprecation=\"no\"\n      classpathref=\"base.classpath\"\n      />\n\n    <copy toDir=\"${buildDir}/images\">\n      <fileset dir=\"${javaImagesDir}\" includes=\"*.*\" />\n    </copy>\n\n  </target>\n\n  <!--target name=\"generate_h_from_java\" depends=\"compile_something\">\n    <exec executable=\"javah\" dir=\"${buildDir}\">\n    </exec>\n  </target-->\n\n  <target name=\"generate_h_from_java\" depends=\"compile_something\">\n    <javah destdir=\"${ulgateDir}\" classpath=\"${buildDir}\">\n    </javah>\n  </target>\n\n  <target name=\"javadoc\">\n    <delete dir=\"${javaDocDir}\"\n      verbose=\"false\"\n      quiet=\"false\"\n      />\n    <mkdir dir=\"${javaDocDir}\" />\n    <javadoc destdir=\"${javaDocDir}\"\n      classpathref=\"base.classpath\"\n      link=\"http://java.sun.com/j2se/1.4.1/docs/api/\"\n      verbose=\"no\"\n      additionalparam=\"-breakiterator\"\n      >\n      <fileset dir=\"${javaDir}\" />\n    </javadoc>\n  </target>\n\n    <target name=\"deploy\" depends=\"compile_something, generate_h_from_java\">\n\n      <delete dir=\"${deployDir}\"\n        verbose=\"false\"\n        quiet=\"false\"\n        />\n      <mkdir dir=\"${deployDir}\" />\n      <mkdir dir=\"${deployDir}/client\" />\n      <mkdir dir=\"${deployDir}/server\" />\n      \n      <jar jarfile=\"${deployDir}/server/something.jar\">\n        <fileset dir=\"${buildDir}\"\n           includes=\"images/**\"\n          />\n      </jar>\n      \n      <copy toDir=\"${deployDir}/client\" verbose=\"Yes\" >\n          <fileset dir=\"${binDir}\" includes=\"startClient.cmd\" />\n\t\t  <fileset dir=\"${binDir}\" includes=\"killProcess.vbs\" />\n      </copy>\n\n      <copy toDir=\"${deployDir}/server/sql\" verbose=\"Yes\" >\n  \t      <fileset dir=\"${sqlDir}\" includes=\"*.sql\" />\n      </copy>\n\n      <copy toDir=\"${deployDir}/server/samples\">\n        <fileset dir=\"${samplesDir}\" includes=\"**/*.*\" />\n      </copy>\n\n      <copy toDir=\"${deployDir}/doc\">\n        <fileset dir=\"${docDir}\" includes=\"**/*.*\" />\n      </copy>\n\n    </target>\n  \n</project>\n"
  },
  {
    "path": "Units/parser-ant.r/xpath-based.d/args.ctags",
    "content": "--language-force=ant\n--extras=+r\n--fields=+rln\n"
  },
  {
    "path": "Units/parser-ant.r/xpath-based.d/expected.tags",
    "content": "MyProject\tinput.xml\t/^<project name=\"MyProject\" default=\"deploy\" basedir=\".\">$/;\"\tp\tline:3\tlanguage:Ant\troles:def\nanother.ant\tinput.xml\t/^  <import file=\"another.ant\"\\/>$/;\"\ti\tline:4\tlanguage:Ant\tproject:MyProject\troles:imported\nbase.classpath\tinput.xml\t/^    <path id=\"base.classpath\">$/;\"\ti\tline:11\tlanguage:XML\troles:def\nclean\tinput.xml\t/^  <target name=\"clean\" depends=\"init\">$/;\"\tt\tline:16\tlanguage:Ant\tproject:MyProject\troles:def\ncompile_something\tinput.xml\t/^  <target name=\"compile_something\" depends=\"init\">$/;\"\tt\tline:23\tlanguage:Ant\tproject:MyProject\troles:def\ndeploy\tinput.xml\t/^    <target name=\"deploy\" depends=\"compile_something, generate_h_from_java\">$/;\"\tt\tline:68\tlanguage:Ant\tproject:MyProject\troles:def\ngenerate_h_from_java\tinput.xml\t/^  <target name=\"generate_h_from_java\" depends=\"compile_something\">$/;\"\tt\tline:47\tlanguage:Ant\tproject:MyProject\troles:def\ninit\tinput.xml\t/^  <target name=\"init\">$/;\"\tt\tline:6\tlanguage:Ant\tproject:MyProject\troles:def\njavadoc\tinput.xml\t/^  <target name=\"javadoc\">$/;\"\tt\tline:52\tlanguage:Ant\tproject:MyProject\troles:def\nx\tinput.xml\t/^  <property name=\"x\" value=\"y\" \\/>$/;\"\tP\tline:5\tlanguage:Ant\tproject:MyProject\troles:def\n"
  },
  {
    "path": "Units/parser-ant.r/xpath-based.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-ant.r/xpath-based.d/input.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n\r\n<project name=\"MyProject\" default=\"deploy\" basedir=\".\">\r\n  <import file=\"another.ant\"/>\r\n  <property name=\"x\" value=\"y\" />\r\n  <target name=\"init\">\r\n    <property environment=\"envvars\" />\r\n    <property name=\"rootDir\" value=\".\" />\r\n    <property name=\"srcDir\" value=\"${rootDir}/src\" />\r\n  \r\n    <path id=\"base.classpath\">\r\n      <pathelement location=\"${buildDir}\" />\r\n    </path>\r\n  </target>\r\n\r\n  <target name=\"clean\" depends=\"init\">\r\n    <delete dir=\"${buildDir}\"\r\n      verbose=\"false\"\r\n      quiet=\"false\"\r\n      />\r\n  </target>\r\n\r\n  <target name=\"compile_something\" depends=\"init\">\r\n    <mkdir dir=\"${buildDir}\" />\r\n    <mkdir dir=\"${buildDir}/images\" />\r\n    <javac srcdir=\"${javaDir}\"\r\n      destdir=\"${buildDir}\"\r\n      debug=\"on\"\r\n      optimize=\"off\"\r\n      verbose=\"no\"\r\n      listfiles=\"yes\"\r\n      deprecation=\"no\"\r\n      classpathref=\"base.classpath\"\r\n      />\r\n\r\n    <copy toDir=\"${buildDir}/images\">\r\n      <fileset dir=\"${javaImagesDir}\" includes=\"*.*\" />\r\n    </copy>\r\n\r\n  </target>\r\n\r\n  <!--target name=\"generate_h_from_java\" depends=\"compile_something\">\r\n    <exec executable=\"javah\" dir=\"${buildDir}\">\r\n    </exec>\r\n  </target-->\r\n\r\n  <target name=\"generate_h_from_java\" depends=\"compile_something\">\r\n    <javah destdir=\"${ulgateDir}\" classpath=\"${buildDir}\">\r\n    </javah>\r\n  </target>\r\n\r\n  <target name=\"javadoc\">\r\n    <delete dir=\"${javaDocDir}\"\r\n      verbose=\"false\"\r\n      quiet=\"false\"\r\n      />\r\n    <mkdir dir=\"${javaDocDir}\" />\r\n    <javadoc destdir=\"${javaDocDir}\"\r\n      classpathref=\"base.classpath\"\r\n      link=\"http://java.sun.com/j2se/1.4.1/docs/api/\"\r\n      verbose=\"no\"\r\n      additionalparam=\"-breakiterator\"\r\n      >\r\n      <fileset dir=\"${javaDir}\" />\r\n    </javadoc>\r\n  </target>\r\n\r\n    <target name=\"deploy\" depends=\"compile_something, generate_h_from_java\">\r\n\r\n      <delete dir=\"${deployDir}\"\r\n        verbose=\"false\"\r\n        quiet=\"false\"\r\n        />\r\n      <mkdir dir=\"${deployDir}\" />\r\n      <mkdir dir=\"${deployDir}/client\" />\r\n      <mkdir dir=\"${deployDir}/server\" />\r\n      \r\n      <jar jarfile=\"${deployDir}/server/something.jar\">\r\n        <fileset dir=\"${buildDir}\"\r\n           includes=\"images/**\"\r\n          />\r\n      </jar>\r\n      \r\n      <copy toDir=\"${deployDir}/client\" verbose=\"Yes\" >\r\n          <fileset dir=\"${binDir}\" includes=\"startClient.cmd\" />\r\n\t\t  <fileset dir=\"${binDir}\" includes=\"killProcess.vbs\" />\r\n      </copy>\r\n\r\n      <copy toDir=\"${deployDir}/server/sql\" verbose=\"Yes\" >\r\n  \t      <fileset dir=\"${sqlDir}\" includes=\"*.sql\" />\r\n      </copy>\r\n\r\n      <copy toDir=\"${deployDir}/server/samples\">\r\n        <fileset dir=\"${samplesDir}\" includes=\"**/*.*\" />\r\n      </copy>\r\n\r\n      <copy toDir=\"${deployDir}/doc\">\r\n        <fileset dir=\"${docDir}\" includes=\"**/*.*\" />\r\n      </copy>\r\n\r\n    </target>\r\n  \r\n</project>\r\n"
  },
  {
    "path": "Units/parser-asciidoc.r/anchor-asciidoc.d/expected.tags",
    "content": "Chapter 1 (Level 0)\tinput.asciidoc\t/^= Chapter 1 (Level 0)$/;\"\tc\nChapter 2\tinput.asciidoc\t/^Chapter 2$/;\"\tc\nLevel 3 Section 1.1.1.1 Title\tinput.asciidoc\t/^==== Level 3 Section 1.1.1.1 Title$/;\"\tt\tsubsection:Subsection 1.1.1\nLevel 4 Section 1.1.1.1.1 Title\tinput.asciidoc\t/^===== Level 4 Section 1.1.1.1.1 Title [#inline-anchor-1]$/;\"\tT\tsubsubsection:Level 3 Section 1.1.1.1 Title\nSection 1.1\tinput.asciidoc\t/^== Section 1.1$/;\"\ts\tchapter:Chapter 1 (Level 0)\nSection 1.2\tinput.asciidoc\t/^== Section 1.2$/;\"\ts\tchapter:Chapter 1 (Level 0)\nSection 2.1\tinput.asciidoc\t/^Section 2.1$/;\"\ts\tchapter:Chapter 2\nSubsection 1.1.1\tinput.asciidoc\t/^=== Subsection 1.1.1$/;\"\tS\tsection:Section 1.1\nSubsection 1.2.1 Title\tinput.asciidoc\t/^=== [#inline-anchor-2a]Subsection 1.2.1 Title [[inline-anchor-2b, Subsection 1.2.1]]$/;\"\tS\tsection:Section 1.2\nSubsection 1.2.2 Title\tinput.asciidoc\t/^=== [[inline-anchor-3a]][#inline-anchor-3b]Subsection 1.2.2 Title [#inline-anchor-3c] ===$/;\"\tS\tsection:Section 1.2\nSubsection 2.1.1\tinput.asciidoc\t/^Subsection 2.1.1$/;\"\tS\tsection:Section 2.1\nchapter_2_anchor\tinput.asciidoc\t/^[[chapter_2_anchor]]$/;\"\ta\tsubsection:Subsection 1.2.2 Title\ninline-anchor-1\tinput.asciidoc\t/^===== Level 4 Section 1.1.1.1.1 Title [#inline-anchor-1]$/;\"\ta\tsubsubsection:Level 3 Section 1.1.1.1 Title\ninline-anchor-2a\tinput.asciidoc\t/^=== [#inline-anchor-2a]Subsection 1.2.1 Title [[inline-anchor-2b, Subsection 1.2.1]]$/;\"\ta\tsection:Section 1.2\ninline-anchor-2b\tinput.asciidoc\t/^=== [#inline-anchor-2a]Subsection 1.2.1 Title [[inline-anchor-2b, Subsection 1.2.1]]$/;\"\ta\tsection:Section 1.2\ninline-anchor-3a\tinput.asciidoc\t/^=== [[inline-anchor-3a]][#inline-anchor-3b]Subsection 1.2.2 Title [#inline-anchor-3c] ===$/;\"\ta\tsection:Section 1.2\ninline-anchor-3b\tinput.asciidoc\t/^=== [[inline-anchor-3a]][#inline-anchor-3b]Subsection 1.2.2 Title [#inline-anchor-3c] ===$/;\"\ta\tsection:Section 1.2\ninline-anchor-3c\tinput.asciidoc\t/^=== [[inline-anchor-3a]][#inline-anchor-3b]Subsection 1.2.2 Title [#inline-anchor-3c] ===$/;\"\ta\tsection:Section 1.2\nsection_1_1_1_1_anchor\tinput.asciidoc\t/^[#section_1_1_1_1_anchor]$/;\"\ta\tsubsection:Subsection 1.1.1\nsection_1_1_1_anchor\tinput.asciidoc\t/^[[section_1_1_1_anchor, The section 1.1.1 anchor]]$/;\"\ta\tsection:Section 1.1\nsection_1_1_anchor\tinput.asciidoc\t/^[[section_1_1_anchor]]$/;\"\ta\tchapter:Chapter 1 (Level 0)\nsection_1_2_anchor\tinput.asciidoc\t/^[#section_1_2_anchor, The section 1.2 anchor]$/;\"\ta\tl4subsection:Level 4 Section 1.1.1.1.1 Title\nsection_2_1_1_anchor\tinput.asciidoc\t/^[#section_2_1_1_anchor]$/;\"\ta\tsection:Section 2.1\nsection_2_1_anchor\tinput.asciidoc\t/^[[section_2_1_anchor]]$/;\"\ta\tchapter:Chapter 2\n"
  },
  {
    "path": "Units/parser-asciidoc.r/anchor-asciidoc.d/input.asciidoc",
    "content": "= Chapter 1 (Level 0)\n\nIntro text of chapter 1\n\n[[section_1_1_anchor]]\n== Section 1.1\n\nText of section 1.1\n\n[[section_1_1_1_anchor, The section 1.1.1 anchor]]\n=== Subsection 1.1.1\n\nText of subsection 1.1.1\n\n[#section_1_1_1_1_anchor]\n==== Level 3 Section 1.1.1.1 Title\n\nText of subsection 1.1.1.1\n\n===== Level 4 Section 1.1.1.1.1 Title [#inline-anchor-1]\n\nText of subsection 1.1.1.1\n\n[#section_1_2_anchor, The section 1.2 anchor]\n== Section 1.2\n\n[#invalid anchor for Text of section 1.2\n\n=== [#inline-anchor-2a]Subsection 1.2.1 Title [[inline-anchor-2b, Subsection 1.2.1]]\n\nText of subsection 1.2.1\n\n=== [[inline-anchor-3a]][#inline-anchor-3b]Subsection 1.2.2 Title [#inline-anchor-3c] ===\n\nText of subsection 1.2.2\n\n// and now two-line titles:\n\n[[chapter_2_anchor]]\nChapter 2\n=========\n\nIntro text of chapter 2\n\n[[section_2_1_anchor]]\nSection 2.1\n------------\n\nText of section 2.1\n\n[#section_2_1_1_anchor]\nSubsection 2.1.1\n~~~~~~~~~~~~~~~\n\nother invalid anchors:\n[[]]\n[#]\n[#,]\n[[]\n[#\n"
  },
  {
    "path": "Units/parser-asciidoc.r/anchor-invalid-asciidoc.d/expected.tags",
    "content": "L1\tinput.adoc\t/^== L1$/;\"\ts\tchapter:[A B]\nL1_b\tinput.adoc\t/^== L1_b$/;\"\ts\tchapter:[A B]\nL2\tinput.adoc\t/^=== L2$/;\"\tS\tsection:L1\nL3 Title\tinput.adoc\t/^==== L3 Title$/;\"\tt\tsubsection:L2\nL4 Title [ ]\tinput.adoc\t/^===== L4 Title [ ]$/;\"\tT\tsubsubsection:L3 Title\n[ #bad] L2_b Title [,]\tinput.adoc\t/^=== [ #bad] L2_b Title [,]$/;\"\tS\tsection:L1_b\n[A B]\tinput.adoc\t/^= [A B]$/;\"\tc\n[foo][bar] L2_c Title [[]\tinput.adoc\t/^=== [foo][bar] L2_c Title [[] ===$/;\"\tS\tsection:L1_b\ngood_anchor\tinput.adoc\t/^[[good_anchor, ]]$/;\"\ta\tsection:L1\n"
  },
  {
    "path": "Units/parser-asciidoc.r/anchor-invalid-asciidoc.d/input.adoc",
    "content": "= [A B]\n\nIntro text of chapter 1\n\n[c]\n== L1\n\nText of section 1.1\n\n[[good_anchor, ]]\n=== L2\n\nText of subsection 1.1.1\n\n[#]\n==== L3 Title\n\nText of subsection 1.1.1.1\n\n===== L4 Title [ ]\n\nText of subsection 1.1.1.1\n\n[, bad]\n== L1_b\n\n[#invalid anchor for Text of section 1.2\n\n=== [ #bad] L2_b Title [,]\n\nText of subsection 1.2.1\n\n=== [foo][bar] L2_c Title [[] ===\n\nText of subsection 1.2.2\n"
  },
  {
    "path": "Units/parser-asciidoc.r/one-character-title.d/expected.tags",
    "content": "a\tinput.adoc\t/^= a$/;\"\tc\nb\tinput.adoc\t/^== b$/;\"\ts\tchapter:a\nc\tinput.adoc\t/^=== c$/;\"\tS\tsection:b\n"
  },
  {
    "path": "Units/parser-asciidoc.r/one-character-title.d/input.adoc",
    "content": "= a\n\nLorem Ipsum.\n\n== b\n\nLorem Ipsum.\n\n=== c\n\nLorem Ipsum.\n"
  },
  {
    "path": "Units/parser-asciidoc.r/simple-asciidoc.d/expected.tags",
    "content": "Chapter 1 (Level 0)\tinput.asciidoc\t/^= Chapter 1 (Level 0)$/;\"\tc\nChapter 2\tinput.asciidoc\t/^Chapter 2$/;\"\tc\nLevel 3 Section 1.1.1.1 Title\tinput.asciidoc\t/^==== Level 3 Section 1.1.1.1 Title$/;\"\tt\tsubsection:Subsection 1.1.1\nLevel 3 Section 2.1.1.1 Title\tinput.asciidoc\t/^Level 3 Section 2.1.1.1 Title$/;\"\tt\tsubsection:Subsection 2.1.1\nLevel 4 Section 1.1.1.1.1 Title\tinput.asciidoc\t/^===== Level 4 Section 1.1.1.1.1 Title$/;\"\tT\tsubsubsection:Level 3 Section 1.1.1.1 Title\nLevel 4 Section 2.1.1.1.1 Title\tinput.asciidoc\t/^Level 4 Section 2.1.1.1.1 Title$/;\"\tT\tsubsubsection:Level 3 Section 2.1.1.1 Title\nLevel 5 Section 1.1.1.1.1.1 Title\tinput.asciidoc\t/^====== Level 5 Section 1.1.1.1.1.1 Title$/;\"\tu\tl4subsection:Level 4 Section 1.1.1.1.1 Title\nSection 1.1\tinput.asciidoc\t/^== Section 1.1$/;\"\ts\tchapter:Chapter 1 (Level 0)\nSection 1.2\tinput.asciidoc\t/^== Section 1.2$/;\"\ts\tchapter:Chapter 1 (Level 0)\nSection 2.1\tinput.asciidoc\t/^Section 2.1$/;\"\ts\tchapter:Chapter 2\nSection 2.2\tinput.asciidoc\t/^Section 2.2$/;\"\ts\tchapter:Chapter 2\nSubsection 1.1.1\tinput.asciidoc\t/^=== Subsection 1.1.1$/;\"\tS\tsection:Section 1.1\nSubsection 2.1.1\tinput.asciidoc\t/^Subsection 2.1.1$/;\"\tS\tsection:Section 2.1\n"
  },
  {
    "path": "Units/parser-asciidoc.r/simple-asciidoc.d/input.asciidoc",
    "content": "= Chapter 1 (Level 0)\n\nIntro text of chapter 1\n\n== Section 1.1\n\nText of section 1.1\n\n=== Subsection 1.1.1\n\nText of subsection 1.1.1\n\n==== Level 3 Section 1.1.1.1 Title\n\nText of subsection 1.1.1.1\n\n===== Level 4 Section 1.1.1.1.1 Title\n\nText of subsection 1.1.1.1.1\n\n====== Level 5 Section 1.1.1.1.1.1 Title\n\nText of subsection 1.1.1.1.1.1\n\n== Section 1.2\n\nText of section 1.2\n\n// and now two-line titles:\n\nChapter 2\n=========\n\nIntro text of chapter 2\n\nSection 2.1\n------------\n\nText of section 2.1\n\nSubsection 2.1.1\n~~~~~~~~~~~~~~~\n\nLevel 3 Section 2.1.1.1 Title\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nText of subsection 2.1.1.1\n\nLevel 4 Section 2.1.1.1.1 Title\n+++++++++++++++++++++++++++++++\n\nText of subsection 2.1.1.1.1\n\n\nSection 2.2\n-----------\n\nText of section 2.2\n\n"
  },
  {
    "path": "Units/parser-asciidoc.r/utf8-asciidoc.d/expected.tags",
    "content": "@Ѐ–𐀀\tinput.asc\t/^=== @Ѐ–𐀀$/;\"\tS\tsection:Šéçtiön 1.1\nChàptěr 1\tinput.asc\t/^Chàptěr 1$/;\"\tc\nSubsubsection 1.1.1.1\tinput.asc\t/^==== Subsubsection 1.1.1.1$/;\"\tt\tsubsection:@Ѐ–𐀀\nŠéçtiön 1.1\tinput.asc\t/^Šéçtiön 1.1$/;\"\ts\tchapter:Chàptěr 1\n"
  },
  {
    "path": "Units/parser-asciidoc.r/utf8-asciidoc.d/input.asc",
    "content": "Chàptěr 1\n=========\n\nIntro text of chapter 1\n\nŠéçtiön 1.1\n-----------\n\nText of section 1.1\n\n=== @Ѐ–𐀀\n\nText of subsection 1.1.1\n\n==== Subsubsection 1.1.1.1\n\n"
  },
  {
    "path": "Units/parser-asm.r/68hc11.asm.d/expected.tags",
    "content": "COLD\tinput.asm\t/^COLD        LDS  #STACK$/;\"\tl\nINTERRUPTS\tinput.asm\t/^INTERRUPTS:$/;\"\tl\nPORTD\tinput.asm\t/^PORTD       EQU  $1008$/;\"\td\nPROMPT\tinput.asm\t/^PROMPT      FCB CR,LF$/;\"\tl\nSP\tinput.asm\t/^SP          EQU  $20$/;\"\td\nTRAPP\tinput.asm\t/^TRAPP       FCB CR,LF$/;\"\tl\nsym1\tinput.asm\t/^sym1 EQU 1$/;\"\td\nsym2\tinput.asm\t/^sym2: EQU 2$/;\"\td\nsym3\tinput.asm\t/^sym3:$/;\"\tl\nsym4\tinput.asm\t/^sym4: bne sym3$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/68hc11.asm.d/input.asm",
    "content": "INTERRUPTS:\n;\nPORTD       EQU  $1008\n;\nSP          EQU  $20\n;\nTRAPP       FCB CR,LF\n            FCB CR,LF\n            FCC  '    ******** ILLEGAL OPCODE TRAP !!! ********'\n            FCB CR,LF\n            FCB 0\nPROMPT      FCB CR,LF\n            FCC  '               68Mon V1.2 (C) 1992 Keith Vasilakes'\n            FCB CR,LF\n            FCB 0\nCOLD        LDS  #STACK\n            LDAA #$20\n\n; http://www.mekatronix.com/downloads/docs/as11_man.pdf\nsym1 EQU 1\nsym2: EQU 2\nsym3:\nsym4: bne sym3\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-cmdline.d/args.ctags",
    "content": "--sort=no\n--param-Asm.useCPreProcessor=1\n--param-CPreProcessor._expand=1\n--fields=+{signature}\n--fields-CPreProcessor=+{macrodef}\n--param-Asm.extraLinesepChars=;\n-DGENTRY(LABEL)=.global LABEL; LABEL:\n-DLENTRY(LABEL)=LABEL; LABEL:\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-cmdline.d/expected.tags",
    "content": "gfunc0\tinput.S\t/^GENTRY(gfunc0)$/;\"\ts\ngfunc0\tinput.S\t/^GENTRY(gfunc0)$/;\"\tl\nlfunc\tinput.S\t/^LENTRY(lfunc)$/;\"\tl\nlfunc\tinput.S\t/^LENTRY(lfunc)$/;\"\tl\ngfunc1\tinput.S\t/^GENTRY(gfunc1)$/;\"\ts\ngfunc1\tinput.S\t/^GENTRY(gfunc1)$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-cmdline.d/input.S",
    "content": "GENTRY(gfunc0)\n\tnop\n\nLENTRY(lfunc)\n\tnop\n\nGENTRY(gfunc1)\n\tnop\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-with-limitation.d/args.ctags",
    "content": "--param-CPreProcessor._expand=1\n--fields-CPreProcessor=+{macrodef}\n--fields=+{language}{signature}\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-with-limitation.d/expected.tags",
    "content": "X\tinput.S\t/^#define X /;\"\td\tlanguage:CPreProcessor\tfile:\tmacrodef:Y\nY\tinput.S\t/^#define Y Y$/;\"\td\tlanguage:CPreProcessor\tfile:\tmacrodef:Y\nY\tinput.S\t/^X:$/;\"\tl\tlanguage:Asm\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-with-limitation.d/input.S",
    "content": "#define X Y\n#define Y Y\nX:\n\tnop\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-with-multi-line-args-last-items.b/args.ctags",
    "content": "--sort=no\n--param-Asm.useCPreProcessor=1\n--param-CPreProcessor._expand=1\n--fields=+{signature}{line}\n--fields-CPreProcessor=+{macrodef}\n--param-Asm.commentCharsAtBOL=#\n--param-Asm.extraLinesepChars=;\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-with-multi-line-args-last-items.b/expected.tags",
    "content": "ENTRY\tinput.S\t/^#define ENTRY(/;\"\td\tline:1\tfile:\tsignature:(SYMBOL,LABEL)\tmacrodef:.global SYMBOL ;LABEL: nop\nE\tinput.S\t/^ENTRY($/;\"\ts\tline:6\nF\tinput.S\t/^\tF)$/;\"\tl\tline:7\nG\tinput.S\t/^ENTRY($/;\"\ts\tline:10\nH\tinput.S\t/^\t)$/;\"\tl\tline:11\nI\tinput.S\t/^ENTRY($/;\"\ts\tline:15\nJ\tinput.S\t/^\t)$/;\"\tl\tline:16\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-with-multi-line-args-last-items.b/input.S",
    "content": "#define ENTRY(SYMBOL,LABEL) .global SYMBOL\t;\\\nLABEL: \\\n\tnop\n\nENTRY(\n\tE,\n\tF)\n\nENTRY(\n\tG,\n\tH\n\t)\n\nENTRY(\n\tI,\n\tJ,K,\n\tL\n\t)\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-with-multi-line-args.d/args.ctags",
    "content": "--sort=no\n--param-Asm.useCPreProcessor=1\n--param-CPreProcessor._expand=1\n--fields=+{signature}{line}\n--fields-CPreProcessor=+{macrodef}\n--param-Asm.commentCharsAtBOL=#\n--param-Asm.extraLinesepChars=;\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-with-multi-line-args.d/expected.tags",
    "content": "ENTRY\tinput.S\t/^#define ENTRY(/;\"\td\tline:1\tfile:\tsignature:(SYMBOL,LABEL)\tmacrodef:.global SYMBOL ;LABEL: nop\nA\tinput.S\t/^ENTRY(A, B)$/;\"\ts\tline:5\nB\tinput.S\t/^ENTRY(A, B)$/;\"\tl\tline:5\nC\tinput.S\t/^ENTRY(C,$/;\"\ts\tline:6\nD\tinput.S\t/^\tD)$/;\"\tl\tline:7\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion-with-multi-line-args.d/input.S",
    "content": "#define ENTRY(SYMBOL,LABEL) .global SYMBOL\t;\\\nLABEL: \\\n\tnop\n\nENTRY(A, B)\nENTRY(C,\n\tD)\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/args.ctags",
    "content": "--sort=no\n--param-Asm.useCPreProcessor=1\n--param-CPreProcessor._expand=1\n--fields=+{signature}\n--fields-CPreProcessor=+{macrodef}\n--param-Asm.commentCharsAtBOL=#\n--param-Asm.extraLinesepChars=;\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/expected.tags",
    "content": "ENTRY\tinput.S\t/^#define ENTRY(/;\"\td\tfile:\tsignature:(LABEL)\tmacrodef:.global LABEL ;LABEL\nmain\tinput.S\t/^ENTRY(main):$/;\"\ts\nmain\tinput.S\t/^ENTRY(main):$/;\"\tl\nENTRY2\tinput.S\t/^#define ENTRY2(/;\"\td\tfile:\tsignature:(LABEL,UNUSED)\tmacrodef:.global LABEL ;LABEL\nloop0\tinput.S\t/^ENTRY2(loop0, \"STRING\"):$/;\"\ts\nloop0\tinput.S\t/^ENTRY2(loop0, \"STRING\"):$/;\"\tl\nloop1\tinput.S\t/^ENTRY2(loop1, 'c'):$/;\"\ts\nloop1\tinput.S\t/^ENTRY2(loop1, 'c'):$/;\"\tl\nloop2\tinput.S\t/^ENTRY2(loop2, ('c')):$/;\"\ts\nloop2\tinput.S\t/^ENTRY2(loop2, ('c')):$/;\"\tl\nASM_NL\tinput.S\t/^#define ASM_NL\t/;\"\td\tfile:\tmacrodef:;\nSYM_ENTRY\tinput.S\t/^#define SYM_ENTRY(/;\"\td\tfile:\tsignature:(name,linkage,align...)\tmacrodef:linkage(name) ASM_NL align ASM_NL name:\nSYM_START\tinput.S\t/^#define SYM_START(/;\"\td\tfile:\tsignature:(name,linkage,align...)\tmacrodef:SYM_ENTRY(name, linkage, align)\nSYM_CODE_START\tinput.S\t/^#define SYM_CODE_START(/;\"\td\tfile:\tsignature:(name)\tmacrodef:SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)\nasm_exc_nmi\tinput.S\t/^SYM_CODE_START(asm_exc_nmi)$/;\"\tl\nENTRY0\tinput-0.S\t/^#define ENTRY0(/;\"\td\tfile:\tsignature:(LABEL)\tmacrodef:.global LABEL ;LABEL\nENTRY1\tinput-1.S\t/^#define ENTRY1(/;\"\td\tfile:\tsignature:(LABEL)\tmacrodef:.global LABEL ;LABEL\nENTRY2\tinput-2.S\t/^#define ENTRY2(/;\"\td\tfile:\tsignature:(LABEL)\tmacrodef:.global LABEL ;LABEL\nexit2\tinput-2.S\t/^ENTRY2(exit2):$/;\"\ts\nexit2\tinput-2.S\t/^ENTRY2(exit2):$/;\"\tl\nENTRY3\tinput-3.S\t/^#define ENTRY3 /;\"\td\tfile:\tmacrodef:label3:; nop;.section .entry.text, \nlabel3\tinput-3.S\t/^\tENTRY3\"a\"$/;\"\tl\nENTRY4\tinput-4.S\t/^#define ENTRY4 /;\"\td\tfile:\tmacrodef:label4:\nENTRY5\tinput-4.S\t/^#define ENTRY5 /;\"\td\tfile:\tmacrodef:label5:\nlabel4\tinput-4.S\t/^ENTRY4;\tnop$/;\"\tl\nlabel5\tinput-4.S\t/^ENTRY5$/;\"\tl\nMAC5\tinput-5.S\t/^#define MAC5 /;\"\td\tfile:\tmacrodef:maclabel5:; nop;maclabel50:; nop\nmaclabel5\tinput-5.S\t/^MAC5/;\"\tl\nmaclabel50\tinput-5.S\t/^MAC5/;\"\tl\nENTRYZ\tinput-6.S\t/^#define ENTRYZ /;\"\td\tfile:\tmacrodef:label6:; nop;.section .entry.text, \nlabel6\tinput-6.S\t/^\tENTRYZ'z'$/;\"\tl\nX\tinput-7.S\t/^#define X(/;\"\td\tfile:\tsignature:()\tmacrodef:mylabel:; nop;\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/input-0.S",
    "content": "#define ENTRY0(LABEL) .global LABEL\t;\\\nLABEL\n\n#comment\nENTRY0(dummy0:\n\tnop\n\nexit0:\n\tnop\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/input-1.S",
    "content": "#define ENTRY1(LABEL) .global LABEL\t;\\\nLABEL\n\n#comment\nENTRY1(dummy1:\n\tnop\n\nENTRY1(exit1):\n\tnop\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/input-2.S",
    "content": "#define ENTRY2(LABEL) .global LABEL\t;\\\nLABEL\n\n#comment\nENTRY2()\n\nENTRY2(exit2):\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/input-3.S",
    "content": "#define ENTRY3 label3:;\tnop;.section .entry.text, \n\tENTRY3\"a\"\n/* gcc -c input-3.S (x86_64) */\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/input-4.S",
    "content": "#define ENTRY4 label4:\n#define ENTRY5 label5:\nENTRY4;\tnop\nENTRY5\n\tnop\n/* gcc -c input-3.S (x86_64) */\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/input-5.S",
    "content": "/* Don't put NEWLINE at the eof this file.\n   No NEWLINE is part of testing. */\n#define MAC5 maclabel5:;\tnop;maclabel50:;\tnop\n\nMAC5"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/input-6.S",
    "content": "/* This is abroken input (at lesat for GAS) */\n#define ENTRYZ label6:;\tnop;.section .entry.text, \n\tENTRYZ'z'\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/input-7.S",
    "content": "#define X() mylabel:;\tnop;\n\nX:\n\tnop\n"
  },
  {
    "path": "Units/parser-asm.r/asm-cpp-macro-expansion.d/input.S",
    "content": "#define ENTRY(LABEL) .global LABEL\t;\\\nLABEL\n\n#comment\nENTRY(main):\n\tnop\n\n#define ENTRY2(LABEL,UNUSED) .global LABEL\t;\\\nLABEL\nENTRY2(loop0, \"STRING\"):\n\tnop\n\nENTRY2(loop1, 'c'):\n\tnop\n\nENTRY2(loop2, ('c')):\n\tnop\n\n/* Taken from linux kernel */\n#define ASM_NL\t\t ;\n#define SYM_ENTRY(name, linkage, align...)\t\t\\\n\tlinkage(name) ASM_NL\t\t\t\t\\\n\talign ASM_NL\t\t\t\t\t\\\n\tname:\n\n#define SYM_START(name, linkage, align...)\t\t\\\n\tSYM_ENTRY(name, linkage, align)\n\n#define SYM_CODE_START(name)\t\t\t\t\\\n\tSYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)\n\nSYM_CODE_START(asm_exc_nmi)\n\tUNWIND_HINT_IRET_REGS\n\tENDBR\n"
  },
  {
    "path": "Units/parser-asm.r/bd32.s.d/expected.tags",
    "content": "CRLF\tinput.s\t/^CRLF            dc.b    13,10,0         <cr>, <lf>, null$/;\"\td\nTEST\tinput.s\t/^TEST            move.l  a0,a1           get argv in a1$/;\"\tl\nsignon\tinput.s\t/^signon  dc.b    'TEST PROGRAM for BD32 programming drivers'$/;\"\td\ntest_1\tinput.s\t/^test_1          moveq.l #BD_PUTS,d0     puts () system call$/;\"\tl\ntest_error\tinput.s\t/^test_error      moveq.l #BD_QUIT,d0     all done - quit$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/bd32.s.d/input.s",
    "content": "* From: http://www.programmersheaven.com/zone5/cat462/3642.htm\n* For 68000 assembler manual, see http://www.ece.iit.edu/ftp/242/Asm.doc\n*\n* test driver for BD32 programming command\n* Scott Howard February 1992\n* Format: TEST <parameter 1> [<parameter 2> ...]\n* simply echoes the command line parameters back to the user\n\n                opt     nol\n                include ipd.inc\n                opt     l\n                dc.l    TEST            execution address\nsignon  dc.b    'TEST PROGRAM for BD32 programming drivers'\nCRLF            dc.b    13,10,0         <cr>, <lf>, null\n                even\n\n* following is the mainline routine for the driver\n\nTEST            move.l  a0,a1           get argv in a1\n                move.l  d0,d2           get argc\n                lea.l   signon(PC),a0   print signon string\n                moveq.l #BD_PUTS,d0     use 'putstring' function in BD32\n\t\tbgnd\n                cmpi.l  #2,d2           arg count < 2?\n                bcc     test_1\n                moveq.l #1,d1           bail out - error code 1\n                bra     test_error\ntest_1          moveq.l #BD_PUTS,d0     puts () system call\n                movea.l (a1)+,a0        point to next string\n\t\tbgnd\n                moveq.l #' ',d1         print space between each one\n                moveq.l #BD_PUTCHAR,d0\n\t\tbgnd\n                subq    #1,d2\n                bne     test_1          loop till done\n\t\tlea.l\tCRLF(PC),a0\tpoint to <cr> <lf> string\n                moveq.l #BD_PUTS,d0     display it on user screen\n\t\tbgnd\n                clr.l   d1              indicate 'no error' to BD32\ntest_error      moveq.l #BD_QUIT,d0     all done - quit\n\t\tbgnd\n\n                END     TEST\n"
  },
  {
    "path": "Units/parser-asm.r/bug538629.asm.d/expected.tags",
    "content": "MYMACRO\tinput.asm\t/^\tMYMACRO EQU 01234h$/;\"\td\n"
  },
  {
    "path": "Units/parser-asm.r/bug538629.asm.d/input.asm",
    "content": "\tMYMACRO EQU 01234h\n"
  },
  {
    "path": "Units/parser-asm.r/cpp-parameter-false.d/args.ctags",
    "content": "--sort=no\n--param-Asm.useCPreProcessor=0\n"
  },
  {
    "path": "Units/parser-asm.r/cpp-parameter-false.d/expected.tags",
    "content": "labelM\tinput.s\t/^\t.global labelM$/;\"\ts\nlabelM\tinput.s\t/^labelM:$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/cpp-parameter-false.d/input.s",
    "content": "#define labelM main\n\n\t.global labelM\nlabelM:\n\tnop\n"
  },
  {
    "path": "Units/parser-asm.r/cpp-parameter-true.d/args.ctags",
    "content": "--sort=no\n--param-Asm.useCPreProcessor=1\n"
  },
  {
    "path": "Units/parser-asm.r/cpp-parameter-true.d/expected.tags",
    "content": "labelM\tinput.S\t/^#define labelM /;\"\td\tfile:\nlabelM\tinput.S\t/^\t.global labelM$/;\"\ts\nlabelM\tinput.S\t/^labelM:$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/cpp-parameter-true.d/input.S",
    "content": "#define labelM main\n\n\t.global labelM\nlabelM:\n\tnop\n"
  },
  {
    "path": "Units/parser-asm.r/crash-when-deleting-token.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-asm.r/crash-when-deleting-token.d/args.ctags",
    "content": "-Iconst\n"
  },
  {
    "path": "Units/parser-asm.r/crash-when-deleting-token.d/input.S",
    "content": "\tconst\n\n"
  },
  {
    "path": "Units/parser-asm.r/directive-before-label.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-asm.r/directive-before-label.d/input.s",
    "content": "\t.aDirective label\n\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-comment-no-cpp.d/args.ctags",
    "content": "--sort=no\n--param-Asm.commentCharsAtBOL=L\n--param-Asm.useCPreProcessor=false\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-comment-no-cpp.d/expected.tags",
    "content": "retry\tinput.s\t/^retry:$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-comment-no-cpp.d/input.s",
    "content": "#define X 1\nLoop:\nretry:\n\tjmp retry\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-comment.d/args.ctags",
    "content": "--sort=no\n--param-Asm.commentCharsAtBOL=L\n--param-Asm.useCPreProcessor=true\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-comment.d/expected.tags",
    "content": "X\tinput.s\t/^#define X /;\"\td\tfile:\nretry\tinput.s\t/^retry:$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-comment.d/input.s",
    "content": "#define X 1\nLoop:\nretry:\n\tjmp retry\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-linesep-no-cpp.d/args.ctags",
    "content": "--sort=no\n--param-Asm.extraLinesepChars=,\n# To increse the test coverage, overwrite the parameter\n# that set from the command line once.\n--param-Asm.extraLinesepChars=;\n--param-Asm.useCPreProcessor=false\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-linesep-no-cpp.d/expected.tags",
    "content": "retry\tinput.s\t/^retry:;loop:$/;\"\tl\nloop\tinput.s\t/^retry:;loop:$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-linesep-no-cpp.d/input.s",
    "content": "#define X 1\nretry:;loop:\n\tjmp retry\n\tjmp loop\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-linesep.d/args.ctags",
    "content": "--sort=no\n--param-Asm.extraLinesepChars=,\n# To increse the test coverage, overwrite the parameter\n# that set from the command line once.\n--param-Asm.extraLinesepChars=;\n--param-Asm.useCPreProcessor=true\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-linesep.d/expected.tags",
    "content": "X\tinput.s\t/^#define X /;\"\td\tfile:\nretry\tinput.s\t/^retry:;loop:$/;\"\tl\nloop\tinput.s\t/^retry:;loop:$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/gas-parameterized-linesep.d/input.s",
    "content": "#define X 1\nretry:;loop:\n\tjmp retry\n\tjmp loop\n"
  },
  {
    "path": "Units/parser-asm.r/gas-section.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+rlK\n"
  },
  {
    "path": "Units/parser-asm.r/gas-section.d/expected.tags",
    "content": "machine/asm.h\tinput.s\t/^#include <machine\\/asm.h>/;\"\theader\tlanguage:CPreProcessor\troles:system\n.rodata.cst8\tinput.s\t/^\t.section .rodata.cst8,\"aM\",@progbits,8$/;\"\tinputSection\tlanguage:LdScript\troles:destination\none\tinput.s\t/^one:\t.double 1.0$/;\"\tlabel\tlanguage:Asm\troles:def\nlimit\tinput.s\t/^limit:\t.double 0.29$/;\"\tlabel\tlanguage:Asm\troles:def\n.inittext\tinput-0.s\t/^\t.section \".inittext\",\"ax\"$/;\"\tinputSection\tlanguage:LdScript\troles:destination\nintcall\tinput-0.s\t/^\t.globl\tintcall$/;\"\tsymbol\tlanguage:LdScript\tinputSection:.inittext\troles:def\nintcall\tinput-0.s\t/^intcall:$/;\"\tlabel\tlanguage:Asm\troles:def\ndefine_ftsec\tinput-1.s\t/^.macro define_ftsec name$/;\"\tmacro\tlanguage:Asm\troles:def\n.head.text.\\\\name\\\\()\tinput-1.s\t/^\t.section \".head.text.\\\\name\\\\()\",\"ax\",@progbits$/;\"\tinputSection\tlanguage:LdScript\troles:destination\n"
  },
  {
    "path": "Units/parser-asm.r/gas-section.d/input-0.s",
    "content": "/* Taken from linux/arch/x86/boot/bioscall.S */\n\n/*\n * \"Glove box\" for BIOS calls.  Avoids the constant problems with BIOSes\n * touching registers they shouldn't be.\n */\n\n\t.code16\n\t.section \".inittext\",\"ax\"\n\t.globl\tintcall\n\t.type\tintcall, @function\nintcall:\n\t/* Self-modify the INT instruction.  Ugly, but works. */\n\tcmpb\t%al, 3f\n"
  },
  {
    "path": "Units/parser-asm.r/gas-section.d/input-1.s",
    "content": "/* Taken from linux/arch/powerpc/include/asm/head-64.h */\n#ifdef __ASSEMBLY__\n.macro define_ftsec name\n\t.section \".head.text.\\name\\()\",\"ax\",@progbits\n.endm\n#endif\n"
  },
  {
    "path": "Units/parser-asm.r/gas-section.d/input.s",
    "content": "/* Taken from glibc/sysdeps/x86_64/fpu/e_logl.S */\n\n/*\n * Written by J.T. Conklin <jtc@netbsd.org>.\n * Public domain.\n *\n * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.\n * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>.\n */\n\n#include <machine/asm.h>\n\n\n\t.section .rodata.cst8,\"aM\",@progbits,8\n\n\t.p2align 3\n\t.type one,@object\none:\t.double 1.0\n\tASM_SIZE_DIRECTIVE(one)\n\t/* It is not important that this constant is precise.  It is only\n\t   a value which is known to be on the safe side for using the\n\t   fyl2xp1 instruction.  */\n\t.type limit,@object\nlimit:\t.double 0.29\n\tASM_SIZE_DIRECTIVE(limit)\n"
  },
  {
    "path": "Units/parser-asm.r/gas.s.d/args.ctags",
    "content": "--fields=+en\n"
  },
  {
    "path": "Units/parser-asm.r/gas.s.d/expected.tags",
    "content": "X\tinput.s\t/^#define X /;\"\td\tline:7\tfile:\tend:7\n_EQU\tinput.s\t/^.equ _EQU equ1$/;\"\td\tline:14\n_EQUIV\tinput.s\t/^.equiv _EQUIV equiv2$/;\"\td\tline:15\n_EQV\tinput.s\t/^.eqv _EQV eqv3$/;\"\td\tline:16\naltsum\tinput.s\t/^.macro  altsum from=0, to=6$/;\"\tm\tline:8\tend:13\nsum\tinput.s\t/^.macro  sum from=0, to=5$/;\"\tm\tline:1\tend:6\n"
  },
  {
    "path": "Units/parser-asm.r/gas.s.d/input.s",
    "content": ".macro  sum from=0, to=5\n\t.long   \\from\n\t.if     \\to-\\from\n\tsum     \"(\\from+1)\",\\to\n\t.endif\n\t.endm\n#define X 1\n.macro  altsum from=0, to=6\n\t.long   \\from\n\t.if     \\to-\\from\n\tsum     \"(\\from+1)\",\\to\n\t.endif\n\t.endm\n.equ _EQU equ1\n.equiv _EQUIV equiv2\n.eqv _EQV eqv3\n"
  },
  {
    "path": "Units/parser-asm.r/label-capturing.d/expected.tags",
    "content": "idtentry\tinput.S\t/^.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ist_offset=0 create_gap=0 /;\"\tm\n"
  },
  {
    "path": "Units/parser-asm.r/label-capturing.d/input.S",
    "content": "/* Taken from linux/arch/x86/entry/entry_64.S\n   idtentry is a macro. It should not be captured as a label. */\n\n/* SPDX-License-Identifier: GPL-2.0 */\n/*\n *  linux/arch/x86_64/entry.S\n *\n *  Copyright (C) 1991, 1992  Linus Torvalds\n *  Copyright (C) 2000, 2001, 2002  Andi Kleen SuSE Labs\n *  Copyright (C) 2000  Pavel Machek <pavel@suse.cz>\n *\n * entry.S contains the system-call and fault low-level handling routines.\n *\n * Some of this is documented in Documentation/x86/entry_64.rst\n *\n * A note on terminology:\n * - iret frame:\tArchitecture defined interrupt frame from SS to RIP\n *\t\t\tat the top of the kernel process stack.\n *\n * Some macro usage:\n * - SYM_FUNC_START/END:Define functions in the symbol table.\n * - TRACE_IRQ_*:\tTrace hardirq state for lock debugging.\n * - idtentry:\t\tDefine exception entry points.\n */\n\t\n.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ist_offset=0 create_gap=0 read_cr2=0\nSYM_CODE_START(\\sym)\n\tUNWIND_HINT_IRET_REGS offset=\\has_error_code*8\n\n\t/* Sanity check */\n\t.if \\shift_ist != -1 && \\paranoid != 1\n\t.error \"using shift_ist requires paranoid=1\"\n\t.endif\n\n\t.if \\create_gap && \\paranoid\n\t.error \"using create_gap requires paranoid=0\"\n\t.endif\n\n\tASM_CLAC\n\n\t.if \\has_error_code == 0\n\tpushq\t$-1\t\t\t\t/* ORIG_RAX: no syscall to restart */\n\t.endif\n\n\t.if \\paranoid == 1\n\ttestb\t$3, CS-ORIG_RAX(%rsp)\t\t/* If coming from userspace, switch stacks */\n\tjnz\t.Lfrom_usermode_switch_stack_\\@\n\t.endif\n\n\t.if \\create_gap == 1\n\t/*\n\t * If coming from kernel space, create a 6-word gap to allow the\n\t * int3 handler to emulate a call instruction.\n\t */\n\ttestb\t$3, CS-ORIG_RAX(%rsp)\n\tjnz\t.Lfrom_usermode_no_gap_\\@\n\t.rept\t6\n\tpushq\t5*8(%rsp)\n\t.endr\n\tUNWIND_HINT_IRET_REGS offset=8\n.Lfrom_usermode_no_gap_\\@:\n\t.endif\n\n\tidtentry_part \\do_sym, \\has_error_code, \\read_cr2, \\paranoid, \\shift_ist, \\ist_offset\n\n\t.if \\paranoid == 1\n\t/*\n\t * Entry from userspace.  Switch stacks and treat it\n\t * as a normal entry.  This means that paranoid handlers\n\t * run in real process context if user_mode(regs).\n\t */\n.Lfrom_usermode_switch_stack_\\@:\n\tidtentry_part \\do_sym, \\has_error_code, \\read_cr2, paranoid=0\n\t.endif\n\n_ASM_NOKPROBE(\\sym)\nSYM_CODE_END(\\sym)\n.endm\n\nidtentry divide_error\t\t\tdo_divide_error\t\t\thas_error_code=0\nidtentry overflow\t\t\tdo_overflow\t\t\thas_error_code=0\nidtentry bounds\t\t\t\tdo_bounds\t\t\thas_error_code=0\nidtentry invalid_op\t\t\tdo_invalid_op\t\t\thas_error_code=0\nidtentry device_not_available\t\tdo_device_not_available\t\thas_error_code=0\nidtentry double_fault\t\t\tdo_double_fault\t\t\thas_error_code=1 paranoid=2 read_cr2=1\nidtentry coprocessor_segment_overrun\tdo_coprocessor_segment_overrun\thas_error_code=0\nidtentry invalid_TSS\t\t\tdo_invalid_TSS\t\t\thas_error_code=1\nidtentry segment_not_present\t\tdo_segment_not_present\t\thas_error_code=1\nidtentry spurious_interrupt_bug\t\tdo_spurious_interrupt_bug\thas_error_code=0\nidtentry coprocessor_error\t\tdo_coprocessor_error\t\thas_error_code=0\nidtentry alignment_check\t\tdo_alignment_check\t\thas_error_code=1\nidtentry simd_coprocessor_error\t\tdo_simd_coprocessor_error\thas_error_code=0\n\n\t\n\n\t\n"
  },
  {
    "path": "Units/parser-asm.r/label-just-before-comment-no-cpp.d/args.ctags",
    "content": "--sort=no\n--param-Asm.commentCharsInMOL=;\n--param-Asm.useCPreProcessor=false\n"
  },
  {
    "path": "Units/parser-asm.r/label-just-before-comment-no-cpp.d/expected.tags",
    "content": "retry\tinput.s\t/^retry:;loop:$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/label-just-before-comment-no-cpp.d/input.s",
    "content": "#define X 1\nretry:;loop:\n\tjmp retry\n\tjmp retry\n"
  },
  {
    "path": "Units/parser-asm.r/label-just-before-comment.d/args.ctags",
    "content": "--sort=no\n--param-Asm.commentCharsInMOL=;\n--param-Asm.useCPreProcessor=true\n"
  },
  {
    "path": "Units/parser-asm.r/label-just-before-comment.d/expected.tags",
    "content": "X\tinput.s\t/^#define X /;\"\td\tfile:\nretry\tinput.s\t/^retry:;loop:$/;\"\tl\n"
  },
  {
    "path": "Units/parser-asm.r/label-just-before-comment.d/input.s",
    "content": "#define X 1\nretry:;loop:\n\tjmp retry\n\tjmp retry\n"
  },
  {
    "path": "Units/parser-asm.r/macro-params.d/args.ctags",
    "content": "--sort=no\n--kinds-Asm=+z\n--fields=+eSo\n--fields-Asm=+{properties}\n"
  },
  {
    "path": "Units/parser-asm.r/macro-params.d/expected.tags",
    "content": "comm\tinput.asm\t/^\t.macro comm$/;\"\tm\tend:4\nplus1\tinput.asm\t/^\t.macro plus1 p, p1$/;\"\tm\tsignature:p p1\tend:7\np\tinput.asm\t/^\t.macro plus1 p, p1$/;\"\tz\tmacro:plus1\tnth:0\np1\tinput.asm\t/^\t.macro plus1 p, p1$/;\"\tz\tmacro:plus1\tnth:1\nplus2\tinput.asm\t/^\t.macro plus2 p p1$/;\"\tm\tsignature:p p1\tend:10\np\tinput.asm\t/^\t.macro plus2 p p1$/;\"\tz\tmacro:plus2\tnth:0\np1\tinput.asm\t/^\t.macro plus2 p p1$/;\"\tz\tmacro:plus2\tnth:1\nreserve_str\tinput.asm\t/^\t.macro reserve_str p1=0 p2$/;\"\tm\tsignature:p1=0 p2\tend:13\np1\tinput.asm\t/^\t.macro reserve_str p1=0 p2$/;\"\tz\tmacro:reserve_str\tnth:0\np2\tinput.asm\t/^\t.macro reserve_str p1=0 p2$/;\"\tz\tmacro:reserve_str\tnth:1\nm\tinput.asm\t/^\t.macro m p1:req, p2=0, p3:vararg$/;\"\tm\tsignature:p1:req p2=0 p3:vararg\tend:16\np1\tinput.asm\t/^\t.macro m p1:req, p2=0, p3:vararg$/;\"\tz\tmacro:m\tnth:0\tproperties:req\np2\tinput.asm\t/^\t.macro m p1:req, p2=0, p3:vararg$/;\"\tz\tmacro:m\tnth:1\np3\tinput.asm\t/^\t.macro m p1:req, p2=0, p3:vararg$/;\"\tz\tmacro:m\tnth:2\tproperties:vararg\nfunc_define\tinput.asm\t/^\t.macro\tfunc_define\tname,nr=0$/;\"\tm\tsignature:name nr=0\tend:27\nname\tinput.asm\t/^\t.macro\tfunc_define\tname,nr=0$/;\"\tz\tmacro:func_define\tnth:0\nnr\tinput.asm\t/^\t.macro\tfunc_define\tname,nr=0$/;\"\tz\tmacro:func_define\tnth:1\n\\\\name\tinput.asm\t/^\t.macro\t\\\\name\targ1,arg2,arg3,arg4$/;\"\tm\tmacro:func_define\tsignature:arg1 arg2 arg3 arg4\tend:26\narg1\tinput.asm\t/^\t.macro\t\\\\name\targ1,arg2,arg3,arg4$/;\"\tz\tmacro:func_define.\\\\name\tnth:0\narg2\tinput.asm\t/^\t.macro\t\\\\name\targ1,arg2,arg3,arg4$/;\"\tz\tmacro:func_define.\\\\name\tnth:1\narg3\tinput.asm\t/^\t.macro\t\\\\name\targ1,arg2,arg3,arg4$/;\"\tz\tmacro:func_define.\\\\name\tnth:2\narg4\tinput.asm\t/^\t.macro\t\\\\name\targ1,arg2,arg3,arg4$/;\"\tz\tmacro:func_define.\\\\name\tnth:3\n"
  },
  {
    "path": "Units/parser-asm.r/macro-params.d/input.asm",
    "content": "\t;; Taken from \"7.63 '.macro'\", the section of the info document for Gas\n\n\t.macro comm\n\t.endm\n\n\t.macro plus1 p, p1\n\t.endm\n\n\t.macro plus2 p p1\n\t.endm\n\n\t.macro reserve_str p1=0 p2\n\t.endm\n\n\t.macro m p1:req, p2=0, p3:vararg\n\t.endm\n\n\t;; Taken From linux/arch/m68k/kernel/head.S\n\t.macro\tfunc_define\tname,nr=0\n\t.macro\t\\name\targ1,arg2,arg3,arg4\n\t\tmove_stack\t\\nr,\\arg1,\\arg2,\\arg3,\\arg4\n\t\tfunc_call\t\\name\n\t.if\t\\nr\n\t\tlea\t%sp@(\\nr*4),%sp\n\t.endif\n\t.endm\n\t.endm\n"
  },
  {
    "path": "Units/parser-asm.r/masm.asm.d/expected.tags",
    "content": "BYTE_BUFFER\tinput.asm\t/^BYTE_BUFFER    LABEL     BYTE$/;\"\tl\nLabelMaker1\tinput.asm\t/^LabelMaker1:$/;\"\tl\nLabelMaker2\tinput.asm\t/^LabelMaker2:$/;\"\tl\nMsg\tinput.asm\t/^Msg\tDB \"Text string\"$/;\"\td\nQUACK\tinput.asm\t/^QUACK  PROC PUBLIC$/;\"\tl\nWORD_BUFFER\tinput.asm\t/^WORD_BUFFER    DW        512 dup (?)$/;\"\td\nhllequal\tinput.asm\t/^hllequal := 4$/;\"\td\nmyequ\tinput.asm\t/^myequ\tEQU    3$/;\"\td\nmyequal\tinput.asm\t/^myequal = 4$/;\"\td\nmymacro\tinput.asm\t/^mymacro macro args$/;\"\tm\nmystruct\tinput.asm\t/^mystruct struct$/;\"\tt\n"
  },
  {
    "path": "Units/parser-asm.r/masm.asm.d/input.asm",
    "content": ".MODEL medium\n.DATA\nMsg\tDB \"Text string\"\n.CODE \nQUACK  PROC PUBLIC\n        enter   0, 0             ; May be an instruction or a macro\n        mov     bx, OFFSET DGROUP:Msg\n        mov     bx, [bp+6]\n        mov     WORD PTR [bx], ax\n        leave\n        ret    2\nQUACK  ENDP\nEND\n\nmyequ\tEQU    3\nmyequal = 4\n\n; http://www.xploiter.com/mirrors/asm/asm_1.htm\nhllequal := 4\n\nBYTE_BUFFER    LABEL     BYTE\nWORD_BUFFER    DW        512 dup (?)\n\n mov     bx, ax\nLabelMaker1:\n        xor     ax, ax\nLabelMaker2:\n\nmymacro macro args\nendm\n\nmystruct struct\nends\n"
  },
  {
    "path": "Units/parser-asm.r/moniker.x68.d/expected.tags",
    "content": "CHECK2\tinput.x68\t/^CHECK2  \tCMPI.B  #'A',(A0)               Is Char > A ?$/;\"\tl\nDUMMY\tinput.x68\t/^DUMMY\t  DS.B    1$/;\"\td\nF_NAME\tinput.x68\t/^F_NAME  DS.B    80$/;\"\td\nINITIAL\tinput.x68\t/^INITIAL \tMOVEA.L #F_NAME,A1              Move the first char to A1$/;\"\tl\nPRNSURNAME\tinput.x68\t/^PRNSURNAME\tMOVEA.L #S_NAME,A1              Pointer to start of prompt text$/;\"\tl\nPROMPT1\tinput.x68\t/^PROMPT1 DC.B    'Please enter your firstname (Max 80): '$/;\"\td\nPROMPT2\tinput.x68\t/^PROMPT2 DC.B    'Please enter your surname   (Max 80): '$/;\"\td\nPRTSTR\tinput.x68\t/^PRTSTR  \tEQU     1                       Print string Function$/;\"\td\nQUIT\tinput.x68\t/^QUIT    \tSTOP    #$2700                  Stop the prorgam$/;\"\tl\nREADSTR\tinput.x68\t/^READSTR \tEQU     2                       Read string function$/;\"\td\nRETURNFALSE\tinput.x68\t/^RETURNFALSE MOVE.B  #0,D5\t\t\t  Moves a zero to D5 to make CAPS false$/;\"\tl\nRETURNTRUE\tinput.x68\t/^RETURNTRUE  MOVE.B  #1,D5\t\t\t  Moves a one to D5 to make CAPS ture$/;\"\tl\nSTART\tinput.x68\t/^START   \tMOVEA.L #PROMPT1,A1             Pointer to start of prompt text$/;\"\tl\nSURNAME\tinput.x68\t/^SURNAME \tMOVEA.L #PROMPT2,A1             Pointer to start of prompt text$/;\"\tl\nS_NAME\tinput.x68\t/^S_NAME  DS.B    80$/;\"\td\n"
  },
  {
    "path": "Units/parser-asm.r/moniker.x68.d/input.x68",
    "content": "* http://www.xrmx.com/solutions/software/68k-fe/samples/moniker.x68\n*       MONIKER.X68\n*       Author : Greg Colley\n*       Date   : 29/01/99\n \n*       Program Description.\n*       This will prompt for surname and firstname, and check if its uppercase\n*       If it is it prints Initial + surname else it repromts.\n*\t  This program will only exit when nothing is entered in the surname or \n*\t  firstname.\n \nPRTSTR  \tEQU     1                       Print string Function\nREADSTR \tEQU     2                       Read string function\n\n        \tORG     $1000                   Start of code location\n\n*       \tPrint user prompt for enter the firstname\n*\t\t=========================================\nSTART   \tMOVEA.L #PROMPT1,A1             Pointer to start of prompt text\n        \tMOVE.B  #PRTSTR,D0              Set up print string function\n        \tMOVE.W  #(PROMPT2-PROMPT1),D1   The prompt string length\n        \tTRAP    #15                     Print Prompt\n        \n*       \tGet firstname\n*\t\t=============\n        \tMOVEA.L #F_NAME,A1              Pointer to store the sentence\n        \tMOVE.B  #READSTR,D0             Set up readstring function\n        \tTRAP    #15                     Get string from KB\n        \tMOVE.W  D1,D4                   Save length of input string to d4\n            \n\n*       \tCheck if Return is pressed\n        \tCMPI.W  #0,D4                   Is the length = 0\n        \tBEQ     QUIT                    If length = 0 then Quit\n\n*\t\tSet up the stuff to check it the entered word is in CAPS\n*\t\t========================================================\n      \tMOVEA.L #F_NAME,A0              Move the first char to A0\n       \tJSR     CHECK2                  Check if uppercase\n        \n        \tCMPI.B  #1,D5                   See if all the sentence is CAPS\n        \tBCS     START                   if it is'nt then re-enter                          \n\n\n*       \tPrint user prompt for enter the surname\n*\t\t=======================================\nSURNAME \tMOVEA.L #PROMPT2,A1             Pointer to start of prompt text\n        \tMOVE.B  #PRTSTR,D0              Set up print string function\n        \tMOVE.W  #(F_NAME-PROMPT2),D1    The prompt string length\n        \tTRAP    #15                     Print Prompt\n        \n*       \tGet surname\n*\t\t===========\n        \tMOVEA.L #S_NAME,A1              Pointer to store the sentence\n        \tMOVE.B  #READSTR,D0             Set up readstring function\n        \tTRAP    #15                     Get string from KB\n        \tMOVE.W  D1,D4                   Save length on input string\n            MOVE.W  D1,D3                   Save length of input string to d3\n\n*       \tCheck is Return is pressed\n        \tCMPI.W  #0,D4                   Is the length = 0\n        \tBEQ     QUIT                    If length = 0 then Quit\n\n*\t\tSet up the stuff to check it the entered word is in CAPS\n*\t\t========================================================\n        \tMOVEA.L #S_NAME,A0              Move the first char to A0  \n        \tJSR     CHECK2                  Check if uppercase        \n        \n        \tCMPI.B  #1,D5                   See if all the sentence is CAPS\n        \tBCS     SURNAME                 if it is'nt then re-enter     \n\n*       \tMove the first char for fname and prints it (Initial Bit)\n*\t\t=========================================================\nINITIAL \tMOVEA.L #F_NAME,A1              Move the first char to A1\n        \tMOVE.B  (A1),D1                 Move the first char of F_NAME to D1\n        \tMOVE.B  #6,D0                   Set up trap number\n        \tTRAP    #15                     Print the Initial\n\nPRNSURNAME\tMOVEA.L #S_NAME,A1              Pointer to start of prompt text\n        \tMOVE.B  #0,D0                   Set up print string function\n        \tMOVE.W  D3,D1                   The prompt string length\n        \tTRAP    #15                     Print Prompt\n\nQUIT    \tSTOP    #$2700                  Stop the prorgam\n\n\n*       \tCheck if uppercase\n*\t\t==================\n*\t\tThis subroutine will return a 1 in, d5 if it's OK or \n*        \treturn a 0 in d5 if its not ok.\n\nCHECK2  \tCMPI.B  #'A',(A0)               Is Char > A ?\n        \tBCS     RETURNFALSE             If no then re-enter\n        \tCMP.B   #('Z'+1),(A0)+          Check if char is < Z\n        \tBCC     RETURNFALSE             If it is then it must be a cap\n        \tSUBI.B  #1,D4                   Decrease s_name / f_name Length\n        \tBNE     CHECK2                  jump if the sentence is not = 0\n\nRETURNTRUE  MOVE.B  #1,D5\t\t\t  Moves a one to D5 to make CAPS ture\n            RTS\t\t\t\t\t  Jump back to the main program\n\nRETURNFALSE MOVE.B  #0,D5\t\t\t  Moves a zero to D5 to make CAPS false\n            RTS                             Jump back to the main program\n\n\n\n*       \tVar's & Const's\n*\t\t===============\n\nPROMPT1 DC.B    'Please enter your firstname (Max 80): '\nPROMPT2 DC.B    'Please enter your surname   (Max 80): '\nF_NAME  DS.B    80\nS_NAME  DS.B    80\nDUMMY\t  DS.B    1\n\n\t\tEND\t$1000\t\t\t\tEnd of assembley\n"
  },
  {
    "path": "Units/parser-asm.r/unbalanced-end-macro.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-asm.r/unbalanced-end-macro.d/input.S",
    "content": "\tNOP\n\t.endm\n"
  },
  {
    "path": "Units/parser-autoconf.r/disabling-m4.d/args.ctags",
    "content": "--sort=no\n--fields=+elnr\n--extras=+fr\n--languages=-M4\n"
  },
  {
    "path": "Units/parser-autoconf.r/disabling-m4.d/expected.tags",
    "content": "PKG_PREREQ\tinput.ac\t/^AC_DEFUN([PKG_PREREQ],$/;\"\tm\tline:4\tlanguage:Autoconf\troles:def\tend:8\ninput.ac\tinput.ac\t1;\"\tF\tline:1\tlanguage:Autoconf\troles:def\tend:12\n"
  },
  {
    "path": "Units/parser-autoconf.r/disabling-m4.d/input.ac",
    "content": "changequote([`],['])\ndefine(`x', 1)\nchangequote(`[',`]')\nAC_DEFUN([PKG_PREREQ],\n[m4_define([PKG_MACROS_VERSION], [0.29])\nm4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,\n    [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])\n])dnl PKG_PREREQ\nm4_define([y], 2)\nm4_changequote([`],['])\ndefine(`z', 3)\n\n"
  },
  {
    "path": "Units/parser-autoconf.r/forcing-autoconf-and-disabling-m4.d/args.ctags",
    "content": "--sort=no\n--fields=+elnr\n--extras=+fr\n--languages=-M4\n--language-force=Autoconf\n"
  },
  {
    "path": "Units/parser-autoconf.r/forcing-autoconf-and-disabling-m4.d/expected.tags",
    "content": "PKG_PREREQ\tinput.m4\t/^AC_DEFUN([PKG_PREREQ],$/;\"\tm\tline:4\tlanguage:Autoconf\troles:def\tend:8\ninput.m4\tinput.m4\t1;\"\tF\tline:1\tlanguage:Autoconf\troles:def\tend:12\n"
  },
  {
    "path": "Units/parser-autoconf.r/forcing-autoconf-and-disabling-m4.d/input.m4",
    "content": "changequote([`],['])\ndefine(`x', 1)\nchangequote(`[',`]')\nAC_DEFUN([PKG_PREREQ],\n[m4_define([PKG_MACROS_VERSION], [0.29])\nm4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,\n    [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])\n])dnl PKG_PREREQ\nm4_define([y], 2)\nm4_changequote([`],['])\ndefine(`z', 3)\n\n"
  },
  {
    "path": "Units/parser-autoconf.r/nested-block.ac.d/args.ctags",
    "content": "--sort=no\n--fields=+lneKz\n"
  },
  {
    "path": "Units/parser-autoconf.r/nested-block.ac.d/expected.tags",
    "content": "USE_STDBOOL_H\tinput.ac\t/^\tAH_TEMPLATE([USE_STDBOOL_H], [whether or not to use <stdbool.h>.])$/;\"\tkind:template\tline:3\tlanguage:Autoconf\tend:3\nUSE_STDBOOL_H\tinput.ac\t/^\tAC_DEFINE([USE_STDBOOL_H])$/;\"\tkind:definition\tline:4\tlanguage:Autoconf\tend:4\nbool\tinput.ac\t/^\tAH_TEMPLATE([bool],  [type for 'bool' if <stdbool.h> is missing or broken.])$/;\"\tkind:template\tline:7\tlanguage:Autoconf\tend:7\ntrue\tinput.ac\t/^\tAH_TEMPLATE([true],  [value of 'true' if <stdbool.h> is missing or broken.])$/;\"\tkind:template\tline:8\tlanguage:Autoconf\tend:8\nfalse\tinput.ac\t/^\tAH_TEMPLATE([false], [value of 'false' if <stdbool.h> is missing or broken.])$/;\"\tkind:template\tline:9\tlanguage:Autoconf\tend:9\ntrue\tinput.ac\t/^\tAC_DEFINE([true],  [1])$/;\"\tkind:definition\tline:10\tlanguage:Autoconf\tend:10\nfalse\tinput.ac\t/^\tAC_DEFINE([false], [0])$/;\"\tkind:definition\tline:11\tlanguage:Autoconf\tend:11\n"
  },
  {
    "path": "Units/parser-autoconf.r/nested-block.ac.d/input.ac",
    "content": "AC_CHECK_HEADERS([stdbool.h],\n[\n\tAH_TEMPLATE([USE_STDBOOL_H], [whether or not to use <stdbool.h>.])\n\tAC_DEFINE([USE_STDBOOL_H])\n],\n[\n\tAH_TEMPLATE([bool],  [type for 'bool' if <stdbool.h> is missing or broken.])\n\tAH_TEMPLATE([true],  [value of 'true' if <stdbool.h> is missing or broken.])\n\tAH_TEMPLATE([false], [value of 'false' if <stdbool.h> is missing or broken.])\n\tAC_DEFINE([true],  [1])\n\tAC_DEFINE([false], [0])\n])\n"
  },
  {
    "path": "Units/parser-autoconf.r/no-string-literal.d/expected.tags",
    "content": "HAVE_CONFDB\tinput.ac\t/^AC_DEFINE_UNQUOTED(HAVE_CONFDB, $HAVE_confdb, Have the old herarchial Corosync config API)$/;\"\td\nUUID_FILE\tinput.ac\t/^AC_DEFINE_UNQUOTED(UUID_FILE,\"$localstatedir\\/lib\\/heartbeat\\/hb_uuid\", I'm a bad boy.)$/;\"\td\n"
  },
  {
    "path": "Units/parser-autoconf.r/no-string-literal.d/input.ac",
    "content": "dnl Taken from configure.ac of pacemaker\nAC_DEFINE_UNQUOTED(UUID_FILE,\"$localstatedir/lib/heartbeat/hb_uuid\", I'm a bad boy.)\nAC_DEFINE_UNQUOTED(HAVE_CONFDB, $HAVE_confdb, Have the old herarchial Corosync config API)\n"
  },
  {
    "path": "Units/parser-autoconf.r/simple.ac.d/args.ctags",
    "content": "--sort=no\n--fields=+KeE\n"
  },
  {
    "path": "Units/parser-autoconf.r/simple.ac.d/expected.tags",
    "content": "universal-ctags\tinput.ac\t/^AC_INIT([universal-ctags],[0.0.0])$/;\"\tpackage\textras:subparser\tend:1\nTMPDIR\tinput.ac\t/^AH_TEMPLATE([TMPDIR],$/;\"\ttemplate\textras:subparser\tend:4\nCHECK_HEADER_DEFINE\tinput.ac\t/^AC_DEFUN([CHECK_HEADER_DEFINE], [$/;\"\tmacro\textras:subparser\tend:19\nctags-libexecdir\tinput.ac\t/^AC_ARG_WITH([ctags-libexecdir],$/;\"\toptwith\textras:subparser\tend:22\ntmpdir\tinput.ac\t/^AC_ARG_ENABLE(tmpdir,$/;\"\toptenable\textras:subparser\tend:26\npkgsysconfdir\tinput.ac\t/^AC_SUBST([pkgsysconfdir])$/;\"\tsubst\textras:subparser\tend:27\npkglibexecdir\tinput.ac\t/^AC_SUBST([pkglibexecdir])$/;\"\tsubst\textras:subparser\tend:28\nINSTALL_LIB\tinput.ac\t/^AM_CONDITIONAL(INSTALL_LIB, [test \"x$enable_readlib\" = \"xyes\"])$/;\"\tcondition\textras:subparser\tend:29\nINSTALL_ETAGS\tinput.ac\t/^AM_CONDITIONAL(INSTALL_ETAGS, [test \"x$enable_etags\" = \"xyes\"])$/;\"\tcondition\textras:subparser\tend:30\nUSE_READCMD\tinput.ac\t/^AM_CONDITIONAL(USE_READCMD, [test \"x$enable_readcmd\" = \"xyes\"])$/;\"\tcondition\textras:subparser\tend:31\nctags_name_executable\tinput.ac\t/^AC_SUBST(ctags_name_executable)$/;\"\tsubst\textras:subparser\tend:35\netags_name_executable\tinput.ac\t/^AC_SUBST(etags_name_executable)$/;\"\tsubst\textras:subparser\tend:37\nETAGS\tinput.ac\t/^AC_DEFINE_UNQUOTED(ETAGS, \"$etags_name_executable\")$/;\"\tdefinition\textras:subparser\tend:39\nMSDOS_STYLE_PATH\tinput.ac\t/^\tAC_DEFINE(MSDOS_STYLE_PATH)$/;\"\tdefinition\textras:subparser\tend:45\n"
  },
  {
    "path": "Units/parser-autoconf.r/simple.ac.d/input.ac",
    "content": "AC_INIT([universal-ctags],[0.0.0])\nAH_TEMPLATE([TMPDIR],\n\t[If you wish to change the directory in which temporary files are stored,\n\tdefine this label to the directory desired.])\nAC_DEFUN([CHECK_HEADER_DEFINE], [\n\tAC_MSG_CHECKING([if $1 is defined in $2])\n\tAC_EGREP_CPP([$2:$1],\n[\n#include <$2>\n#ifdef $1\nconst char *result_yes = \"$2:$1\";\n#endif\n], [\n\tAC_MSG_RESULT(yes)\n\t[$3]\n], [\n\tAC_MSG_RESULT(no)\n\t[$4]\n]) ])\nAC_ARG_WITH([ctags-libexecdir],\n\t[AS_HELP_STRING([--with-ctags-libexecdir=DIR],\n\t\t['universal-ctags'-specific program executables [LIBEXECDIR/ctags]])])\nAC_ARG_ENABLE(tmpdir,\n\t[AS_HELP_STRING([--enable-tmpdir=DIR],\n\t\t[default directory for temporary files [ARG=/tmp]])],\n\ttmpdir_specified=yes)\nAC_SUBST([pkgsysconfdir])\nAC_SUBST([pkglibexecdir])\nAM_CONDITIONAL(INSTALL_LIB, [test \"x$enable_readlib\" = \"xyes\"])\nAM_CONDITIONAL(INSTALL_ETAGS, [test \"x$enable_etags\" = \"xyes\"])\nAM_CONDITIONAL(USE_READCMD, [test \"x$enable_readcmd\" = \"xyes\"])\n\ndnl AC_MSG_NOTICE(Change with $program_transform_name)\nctags_name_executable=`echo ctags | sed \"$program_transform_name\"`\nAC_SUBST(ctags_name_executable)\netags_name_executable=`echo etags | sed \"$program_transform_name\"`\nAC_SUBST(etags_name_executable)\n\nAC_DEFINE_UNQUOTED(ETAGS, \"$etags_name_executable\")\n\n# Check for host type\ncase \"$host\" in\n  i?86-*-mingw* | x86_64-*-mingw*)\n\thost_mingw=yes\n\tAC_DEFINE(MSDOS_STYLE_PATH)\n\t;;\nesac\n"
  },
  {
    "path": "Units/parser-autoconf.r/simple2.ac.d/args.ctags",
    "content": "--sort=no\n--fields=+elnr\n--extras=+fr\n"
  },
  {
    "path": "Units/parser-autoconf.r/simple2.ac.d/expected.tags",
    "content": "x\tinput.ac\t/^define(`x', 1)$/;\"\td\tline:2\tlanguage:M4\troles:def\tend:2\nPKG_PREREQ\tinput.ac\t/^AC_DEFUN([PKG_PREREQ],$/;\"\tm\tline:4\tlanguage:Autoconf\troles:def\tend:8\nPKG_MACROS_VERSION\tinput.ac\t/^[m4_define([PKG_MACROS_VERSION], [0.29])$/;\"\td\tline:5\tlanguage:M4\troles:def\tend:5\ny\tinput.ac\t/^m4_define([y], 2)$/;\"\td\tline:9\tlanguage:M4\troles:def\tend:9\nz\tinput.ac\t/^define(`z', 3)$/;\"\td\tline:11\tlanguage:M4\troles:def\tend:11\ninput.ac\tinput.ac\t1;\"\tF\tline:1\tlanguage:Autoconf\troles:def\tend:12\n"
  },
  {
    "path": "Units/parser-autoconf.r/simple2.ac.d/input.ac",
    "content": "changequote([`],['])\ndefine(`x', 1)\nchangequote(`[',`]')\nAC_DEFUN([PKG_PREREQ],\n[m4_define([PKG_MACROS_VERSION], [0.29])\nm4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,\n    [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])\n])dnl PKG_PREREQ\nm4_define([y], 2)\nm4_changequote([`],['])\ndefine(`z', 3)\n\n"
  },
  {
    "path": "Units/parser-autoit.r/simple-au3.d/args.ctags",
    "content": "--fields=+erS\n--fields-AutoIt=+{properties}\n--extras=+r\n"
  },
  {
    "path": "Units/parser-autoit.r/simple-au3.d/expected.tags",
    "content": "All functions\tinput.au3\t/^#Region All functions$/;\"\tr\troles:def\tend:54\nConstants.au3\tinput.au3\t/^#include <Constants.au3>$/;\"\tS\troles:system\nGUIConstantsEx.au3\tinput.au3\t/^#include<GUIConstantsEx.au3>$/;\"\tS\troles:system\nMyDouble\tinput.au3\t/^Func MyDouble($iValue)$/;\"\tf\tregion:All functions\tsignature:($iValue)\troles:def\tend:32\nMyDouble0\tinput.au3\t/^func MyDouble0($iValue)$/;\"\tf\tregion:All functions\tsignature:($iValue)\troles:def\tend:38\nMyDouble1\tinput.au3\t/^    \tFUNC MyDouble1($iValue)$/;\"\tf\tregion:All functions\tsignature:($iValue)\troles:def\tend:43\nMyDummy\tinput.au3\t/^FUNC MyDummy($iValue)$/;\"\tf\tregion:All functions\tsignature:($iValue)\troles:def\tend:53\nMyVolatileDouble\tinput.au3\t/^Volatile Func MyVolatileDouble ($iValue)$/;\"\tf\tregion:All functions\tsignature:($iValue)\troles:def\tend:47\tproperties:volatile\nWindowsConstants.au3\tinput.au3\t/^#include \"WindowsConstants.au3\"$/;\"\tS\troles:local\niDoubled\tinput.au3\t/^Local $iDoubled = 0$/;\"\tl\troles:def\niFirst\tinput.au3\t/^    LOCAL STATIC $iFirst = 0$/;\"\tl\tfunc:All functions.MyDummy\troles:def\tproperties:static\niNumber\tinput.au3\t/^Local $iNumber = 10$/;\"\tl\troles:def\niSecond\tinput.au3\t/^    STATIC LOCAL $iSecond = 1$/;\"\tl\tfunc:All functions.MyDummy\troles:def\tproperties:static\niSomething\tinput.au3\t/^    Local $iSomething = 42$/;\"\tl\tfunc:All functions.MyDouble0\troles:def\n"
  },
  {
    "path": "Units/parser-autoit.r/simple-au3.d/input.au3",
    "content": "; Taken from https://www.autoitscript.com/autoit3/docs/intro/lang_functions.htm\n\n#include <Constants.au3>\n#include<GUIConstantsEx.au3>\n#include \"WindowsConstants.au3\"\n\nLocal $iNumber = 10\nLocal $iDoubled = 0\n\nFor $i = 1 To 10\n    $iDoubled = MyDouble($iNumber)\n    MsgBox($MB_OK, \"\", $iNumber & \" doubled is \" & $iDoubled)\n    $iNumber = $iDoubled\nNext\nExit\n\n#cs\nFunc Ignored()\nEndFunc\n#comments-start\nFunc Ignored0()\nEndFunc\n#comments-end\nFunc Ignored1()\nEndFunc\n#ce\n\n#Region All functions\nFunc MyDouble($iValue)\n    $iValue = $iValue * 2\n    Return $iValue\nEndFunc   ;==>MyDouble\n\nfunc MyDouble0($iValue)\n    Local $iSomething = 42\n    $iValue = $iValue * 2\n    Return $iValue\nEndFunc   ;==>MyDouble\n\n    \tFUNC MyDouble1($iValue)\n    $iValue = $iValue * 2\n    Return $iValue\nEndFunc\n\nVolatile Func MyVolatileDouble ($iValue)\n    Return $iValue * 2;\nEndFunc\n\nFUNC MyDummy($iValue)\n    LOCAL STATIC $iFirst = 0\n    STATIC LOCAL $iSecond = 1\n    RETURN $iValue * $iSecond + $iFirst\nENDFUNC\n#EndRegion All functions\n"
  },
  {
    "path": "Units/parser-automake.r/disable-make-parser.d/args.ctags",
    "content": "--language-force=Automake\n--languages=-Make\n--fields=+r\n--extras=+r\n"
  },
  {
    "path": "Units/parser-automake.r/disable-make-parser.d/expected.tags",
    "content": "bin\tinput.am\t/^bin_PROGRAMS = x$/;\"\td\troles:program\nx\tinput.am\t/^bin_PROGRAMS = x$/;\"\tP\tdirectory:bin\troles:def\n"
  },
  {
    "path": "Units/parser-automake.r/disable-make-parser.d/input.am",
    "content": "bin_PROGRAMS = x\n"
  },
  {
    "path": "Units/parser-automake.r/eof-value.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-automake.r/eof-value.d/args.ctags",
    "content": "--kinds-all'\n--fields=*\n--fields-all=*\n--extras=*\n--extras-all=*\n--roles-all.*=*\n"
  },
  {
    "path": "Units/parser-automake.r/eof-value.d/input.am",
    "content": "l:\n\t"
  },
  {
    "path": "Units/parser-automake.r/langstack.am.d/args.ctags",
    "content": "--sort=no\n--language-force=Automake\n--fields=+rlK\n--extras=+r\n"
  },
  {
    "path": "Units/parser-automake.r/langstack.am.d/expected.tags",
    "content": "prefix\tinput.am\t/^prefix=c$/;\"\tmacro\tlanguage:Make\troles:def\n$(top_srcdir)/source.mak\tinput.am\t/^include $(top_srcdir)\\/source.mak$/;\"\tmakefile\tlanguage:Make\troles:included\ncbin\tinput.am\t/^cbin=$(bindir)\\/ctags$/;\"\tmacro\tlanguage:Make\troles:def\ncbin_PROGRAMS\tinput.am\t/^cbin_PROGRAMS = $(prefix)ctags$/;\"\tmacro\tlanguage:Make\troles:def\ncbin\tinput.am\t/^cbin_PROGRAMS = $(prefix)ctags$/;\"\tdirectory\tlanguage:Automake\troles:program\n$(prefix)ctags\tinput.am\t/^cbin_PROGRAMS = $(prefix)ctags$/;\"\tprogram\tlanguage:Automake\tdirectory:cbin\troles:def\n__prefix_ctags\tinput.am\t/^cbin_PROGRAMS = $(prefix)ctags$/;\"\tprogram\tlanguage:Automake\tdirectory:cbin\troles:def\nINSTALL_ETAGS\tinput.am\t/^if INSTALL_ETAGS$/;\"\tcondition\tlanguage:Automake\troles:branched\ninstall-exec-hook\tinput.am\t/^install-exec-hook:$/;\"\ttarget\tlanguage:Make\troles:def\nuninstall-hook\tinput.am\t/^uninstall-hook:$/;\"\ttarget\tlanguage:Make\troles:def\n"
  },
  {
    "path": "Units/parser-automake.r/langstack.am.d/input.am",
    "content": "prefix=c\n\ninclude $(top_srcdir)/source.mak\n\ncbin=$(bindir)/ctags\ncbin_PROGRAMS = $(prefix)ctags\n\nif INSTALL_ETAGS\ninstall-exec-hook:\n\tcd $(DESTDIR)$(bindir) && \\\n\t\t$(LN_S) ctags$(EXEEXT) etags$(EXEEXT)\n\nuninstall-hook:\n\trm $(DESTDIR)$(bindir)/etags$(EXEEXT)\nendif\n"
  },
  {
    "path": "Units/parser-automake.r/noinst.d/args.ctags",
    "content": "--sort=no\n--extras=sr\n--fields=lZKrz\n"
  },
  {
    "path": "Units/parser-automake.r/noinst.d/expected.tags",
    "content": "check_LIBRARIES\tinput.am\t/^check_LIBRARIES = libt0.a libt1.a$/;\"\tkind:macro\tlanguage:Make\troles:def\nlibt0.a\tinput.am\t/^check_LIBRARIES = libt0.a libt1.a$/;\"\tkind:library\tlanguage:Automake\tscope:pseudodir:check\troles:def\nlibt0_a\tinput.am\t/^check_LIBRARIES = libt0.a libt1.a$/;\"\tkind:library\tlanguage:Automake\tscope:pseudodir:check\troles:def\nlibt1.a\tinput.am\t/^check_LIBRARIES = libt0.a libt1.a$/;\"\tkind:library\tlanguage:Automake\tscope:pseudodir:check\troles:def\nlibt1_a\tinput.am\t/^check_LIBRARIES = libt0.a libt1.a$/;\"\tkind:library\tlanguage:Automake\tscope:pseudodir:check\troles:def\ncheck_PROGRAMS\tinput.am\t/^check_PROGRAMS = testprog0  testprog1$/;\"\tkind:macro\tlanguage:Make\troles:def\ntestprog0\tinput.am\t/^check_PROGRAMS = testprog0  testprog1$/;\"\tkind:program\tlanguage:Automake\tscope:pseudodir:check\troles:def\ntestprog1\tinput.am\t/^check_PROGRAMS = testprog0  testprog1$/;\"\tkind:program\tlanguage:Automake\tscope:pseudodir:check\troles:def\nEXTRA_PROGRAMS\tinput.am\t/^EXTRA_PROGRAMS = xprog0 xprog1$/;\"\tkind:macro\tlanguage:Make\troles:def\nxprog0\tinput.am\t/^EXTRA_PROGRAMS = xprog0 xprog1$/;\"\tkind:program\tlanguage:Automake\tscope:pseudodir:EXTRA\troles:def\nxprog1\tinput.am\t/^EXTRA_PROGRAMS = xprog0 xprog1$/;\"\tkind:program\tlanguage:Automake\tscope:pseudodir:EXTRA\troles:def\n"
  },
  {
    "path": "Units/parser-automake.r/noinst.d/input.am",
    "content": "check_LIBRARIES = libt0.a libt1.a\ncheck_PROGRAMS = testprog0  testprog1\nEXTRA_PROGRAMS = xprog0 xprog1\n"
  },
  {
    "path": "Units/parser-automake.r/objprefix.d/args.ctags",
    "content": "--sort=no\n--extras=sr\n--fields=lZKrzE\n"
  },
  {
    "path": "Units/parser-automake.r/objprefix.d/expected.tags",
    "content": "dist_data_DATA\tinput.am\t/^dist_data_DATA = distribute-this$/;\"\tkind:macro\tlanguage:Make\troles:def\ndata\tinput.am\t/^dist_data_DATA = distribute-this$/;\"\tkind:directory\tlanguage:Automake\troles:data\textras:reference,subparser\ndistribute-this\tinput.am\t/^dist_data_DATA = distribute-this$/;\"\tkind:data\tlanguage:Automake\tscope:directory:data\troles:def\textras:subparser\nbin_PROGRAMS\tinput.am\t/^bin_PROGRAMS = foo$/;\"\tkind:macro\tlanguage:Make\troles:def\nbin\tinput.am\t/^bin_PROGRAMS = foo$/;\"\tkind:directory\tlanguage:Automake\troles:program\textras:reference,subparser\nfoo\tinput.am\t/^bin_PROGRAMS = foo$/;\"\tkind:program\tlanguage:Automake\tscope:directory:bin\troles:def\textras:subparser\nnodist_foo_SOURCES\tinput.am\t/^nodist_foo_SOURCES = do-not-distribute.c$/;\"\tkind:macro\tlanguage:Make\troles:def\nnobase_include_HEADERS\tinput.am\t/^nobase_include_HEADERS = sys\\/types.h$/;\"\tkind:macro\tlanguage:Make\troles:def\nman_MANS\tinput.am\t/^man_MANS = foo.1$/;\"\tkind:macro\tlanguage:Make\troles:def\nman\tinput.am\t/^man_MANS = foo.1$/;\"\tkind:directory\tlanguage:Automake\troles:man\textras:reference,subparser\nfoo.1\tinput.am\t/^man_MANS = foo.1$/;\"\tkind:man\tlanguage:Automake\tscope:directory:man\troles:def\textras:subparser\nnotrans_man_MANS\tinput.am\t/^notrans_man_MANS = foo.3$/;\"\tkind:macro\tlanguage:Make\troles:def\nman\tinput.am\t/^notrans_man_MANS = foo.3$/;\"\tkind:directory\tlanguage:Automake\troles:man\textras:reference,subparser\nfoo.3\tinput.am\t/^notrans_man_MANS = foo.3$/;\"\tkind:man\tlanguage:Automake\tscope:directory:man\troles:def\textras:subparser\nnotrans_dist_man3_MANS\tinput.am\t/^notrans_dist_man3_MANS = bar.3$/;\"\tkind:macro\tlanguage:Make\troles:def\nman3\tinput.am\t/^notrans_dist_man3_MANS = bar.3$/;\"\tkind:directory\tlanguage:Automake\troles:man\textras:reference,subparser\nbar.3\tinput.am\t/^notrans_dist_man3_MANS = bar.3$/;\"\tkind:man\tlanguage:Automake\tscope:directory:man3\troles:def\textras:subparser\n"
  },
  {
    "path": "Units/parser-automake.r/objprefix.d/input.am",
    "content": "dist_data_DATA = distribute-this\nbin_PROGRAMS = foo\nnodist_foo_SOURCES = do-not-distribute.c\nnobase_include_HEADERS = sys/types.h\nman_MANS = foo.1\nnotrans_man_MANS = foo.3\nnotrans_dist_man3_MANS = bar.3\n"
  },
  {
    "path": "Units/parser-automake.r/simple.am.d/args.ctags",
    "content": "--sort=no\n--language-force=Automake\n--fields=+r\n--extras=+r\n"
  },
  {
    "path": "Units/parser-automake.r/simple.am.d/expected.tags",
    "content": "$(top_srcdir)/source.mak\tinput.am\t/^include $(top_srcdir)\\/source.mak$/;\"\tI\troles:included\nEXTRA_DIST\tinput.am\t/^EXTRA_DIST   = $(NULL)$/;\"\tm\troles:def\nbin_PROGRAMS\tinput.am\t/^bin_PROGRAMS = ctags$/;\"\tm\troles:def\nbin\tinput.am\t/^bin_PROGRAMS = ctags$/;\"\td\troles:program\nctags\tinput.am\t/^bin_PROGRAMS = ctags$/;\"\tP\tdirectory:bin\troles:def\nUSE_READCMD\tinput.am\t/^if USE_READCMD$/;\"\tc\troles:branched\nbin\tinput.am\t/^bin_PROGRAMS+= readtags$/;\"\td\troles:program\nreadtags\tinput.am\t/^bin_PROGRAMS+= readtags$/;\"\tP\tdirectory:bin\troles:def\nreadtags_CPPFLAGS\tinput.am\t/^readtags_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)\\/main -I$(srcdir)\\/read$/;\"\tm\troles:def\ndist_readtags_SOURCES\tinput.am\t/^dist_readtags_SOURCES = $(READTAGS_SRCS) $(READTAGS_HEADS)$/;\"\tm\troles:def\nHAVE_FNMATCH\tinput.am\t/^if !HAVE_FNMATCH$/;\"\tc\troles:branched\nHAVE_REGCOMP\tinput.am\t/^if !HAVE_REGCOMP$/;\"\tc\troles:branched\nHAVE_LIBXML\tinput.am\t/^if HAVE_LIBXML$/;\"\tc\troles:branched\nctags_CPPFLAGS\tinput.am\t/^ctags_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)\\/main$/;\"\tm\troles:def\nENABLE_DEBUGGING\tinput.am\t/^if ENABLE_DEBUGGING$/;\"\tc\troles:branched\nctags_CFLAGS\tinput.am\t/^ctags_CFLAGS   =$/;\"\tm\troles:def\nctags_LDADD\tinput.am\t/^ctags_LDADD  =$/;\"\tm\troles:def\nnodist_ctags_SOURCES\tinput.am\t/^nodist_ctags_SOURCES = $(REPOINFO_HEADS)$/;\"\tm\troles:def\nBUILT_SOURCES\tinput.am\t/^BUILT_SOURCES = $(REPOINFO_HEADS)$/;\"\tm\troles:def\nCLEANFILES\tinput.am\t/^CLEANFILES = $(REPOINFO_HEADS)$/;\"\tm\troles:def\n$(REPOINFO_OBJS)\tinput.am\t/^$(REPOINFO_OBJS): $(REPOINFO_SRCS) $(REPOINFO_HEADS)$/;\"\tt\troles:def\nBUILD_IN_GIT_REPO\tinput.am\t/^if BUILD_IN_GIT_REPO$/;\"\tc\troles:branched\nGEN_REPOINFO\tinput.am\t/^GEN_REPOINFO = $(srcdir)\\/misc\\/gen-repoinfo$/;\"\tm\troles:def\n$(REPOINFO_HEADS)\tinput.am\t/^$(REPOINFO_HEADS): $(GEN_REPOINFO) $(srcdir)\\/.git\\/*$/;\"\tt\troles:def\n$(REPOINFO_HEADS)\tinput.am\t/^$(REPOINFO_HEADS):$/;\"\tt\troles:def\nRUN_OPTLIB2C\tinput.am\t/^if RUN_OPTLIB2C$/;\"\tc\troles:branched\noptlib2c_verbose\tinput.am\t/^optlib2c_verbose = $(optlib2c_verbose_@AM_V@)$/;\"\tm\troles:def\noptlib2c_verbose_\tinput.am\t/^optlib2c_verbose_ = $(optlib2c_verbose_@AM_DEFAULT_V@)$/;\"\tm\troles:def\noptlib2c_verbose_0\tinput.am\t/^optlib2c_verbose_0 = @echo OPTLIB2C \"  $@\";$/;\"\tm\troles:def\nOPTLIB2C\tinput.am\t/^OPTLIB2C = $(srcdir)\\/misc\\/optlib2c$/;\"\tm\troles:def\n%.c\tinput.am\t/^%.c: %.ctags $(OPTLIB2C) Makefile$/;\"\tt\troles:def\ndist_ctags_SOURCES\tinput.am\t/^dist_ctags_SOURCES = $(ALL_HEADS) $(ALL_SRCS)$/;\"\tm\troles:def\nman_MANS\tinput.am\t/^man_MANS = ctags.1$/;\"\tm\troles:def\nman\tinput.am\t/^man_MANS = ctags.1$/;\"\td\troles:man\nctags.1\tinput.am\t/^man_MANS = ctags.1$/;\"\tM\tdirectory:man\troles:def\nENABLE_XCMD\tinput.am\t/^if ENABLE_XCMD$/;\"\tc\troles:branched\ndriversdir\tinput.am\t/^driversdir = $(pkglibexecdir)\\/drivers$/;\"\tm\troles:def\ndrivers\tinput.am\t/^driversdir = $(pkglibexecdir)\\/drivers$/;\"\td\troles:def\ndist_drivers_SCRIPTS\tinput.am\t/^dist_drivers_SCRIPTS = libexec\\/drivers\\/coffeetags$/;\"\tm\troles:def\ndrivers\tinput.am\t/^dist_drivers_SCRIPTS = libexec\\/drivers\\/coffeetags$/;\"\td\troles:script\nlibexec/drivers/coffeetags\tinput.am\t/^dist_drivers_SCRIPTS = libexec\\/drivers\\/coffeetags$/;\"\tS\tdirectory:drivers\troles:def\nINSTALL_ETAGS\tinput.am\t/^if INSTALL_ETAGS$/;\"\tc\troles:branched\ninstall-exec-hook\tinput.am\t/^install-exec-hook:$/;\"\tt\troles:def\nuninstall-hook\tinput.am\t/^uninstall-hook:$/;\"\tt\troles:def\n$(top_srcdir)/makefiles/testing.mak\tinput.am\t/^include $(top_srcdir)\\/makefiles\\/testing.mak$/;\"\tI\troles:included\n$(top_srcdir)/makefiles/test-cases.mak\tinput.am\t/^include $(top_srcdir)\\/makefiles\\/test-cases.mak$/;\"\tI\troles:included\n$(top_srcdir)/makefiles/help.mak\tinput.am\t/^include $(top_srcdir)\\/makefiles\\/help.mak$/;\"\tI\troles:included\n"
  },
  {
    "path": "Units/parser-automake.r/simple.am.d/input.am",
    "content": "include $(top_srcdir)/source.mak\n\n# Test cases are added to EXTRA_DIST in makefiles/test-cases.mak\nEXTRA_DIST   = $(NULL)\n\nbin_PROGRAMS = ctags\n\nif USE_READCMD\nbin_PROGRAMS+= readtags\nreadtags_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/main -I$(srcdir)/read\ndist_readtags_SOURCES = $(READTAGS_SRCS) $(READTAGS_HEADS)\nreadtags_CPPFLAGS += -DQUALIFIER -I$(srcdir)/dsl\ndist_readtags_SOURCES += $(QUALIFIER_SRCS) $(QUALIFIER_HEADS)\nendif\n\nif !HAVE_FNMATCH\nMAIN_SRCS += $(FNMATCH_SRCS)\nMAIN_HEADS += $(FNMATCH_HEADS)\nendif\n\nif !HAVE_REGCOMP\nMAIN_SRCS += $(REGEX_SRCS)\nMAIN_HEADS += $(REGEX_HEADS)\nendif\n\nif HAVE_LIBXML\nPARSER_SRCS += $(XML_SRCS)\nPARSER_HEADS += $(XML_HEADS)\nendif\n\nctags_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/main\nif ENABLE_DEBUGGING\nctags_CPPFLAGS+= $(DEBUG_CPPFLAGS)\nendif\nctags_CPPFLAGS+= $(FNMATCH_CPPFLAGS)\nctags_CPPFLAGS+= $(REGCOMP_CPPFLAGS)\nctags_CPPFLAGS+= -DHAVE_REPOINFO_H\n\nctags_CFLAGS   =\nctags_CFLAGS  += $(EXTRA_CFLAGS)\nctags_CFLAGS  += $(WARNING_CFLAGS)\nctags_CFLAGS  += $(COVERAGE_CFLAGS)\nctags_CFLAGS  += $(CGCC_CFLAGS)\nctags_CFLAGS  += $(LIBXML_CFLAGS)\n\nctags_LDADD  =\nctags_LDADD += $(LIBXML_LIBS)\n\nnodist_ctags_SOURCES = $(REPOINFO_HEADS)\nBUILT_SOURCES = $(REPOINFO_HEADS)\nCLEANFILES = $(REPOINFO_HEADS)\n$(REPOINFO_OBJS): $(REPOINFO_SRCS) $(REPOINFO_HEADS)\nif BUILD_IN_GIT_REPO\nGEN_REPOINFO = $(srcdir)/misc/gen-repoinfo\n$(REPOINFO_HEADS): $(GEN_REPOINFO) $(srcdir)/.git/*\n\t$(GEN_REPOINFO) > $@\nelse\n$(REPOINFO_HEADS):\n\techo > $@\nendif\n\nif RUN_OPTLIB2C\noptlib2c_verbose = $(optlib2c_verbose_@AM_V@)\noptlib2c_verbose_ = $(optlib2c_verbose_@AM_DEFAULT_V@)\noptlib2c_verbose_0 = @echo OPTLIB2C \"  $@\";\nOPTLIB2C = $(srcdir)/misc/optlib2c\n%.c: %.ctags $(OPTLIB2C) Makefile\n\t$(optlib2c_verbose)$(OPTLIB2C) --transform-cmd=\"$(program_transform_name)\" $< > $@\nendif\ndist_ctags_SOURCES = $(ALL_HEADS) $(ALL_SRCS)\n\nman_MANS = ctags.1\n\nif ENABLE_XCMD\ndriversdir = $(pkglibexecdir)/drivers\ndist_drivers_SCRIPTS = libexec/drivers/coffeetags\nendif\n\nif INSTALL_ETAGS\ninstall-exec-hook:\n\tcd $(DESTDIR)$(bindir) && \\\n\t\t$(LN_S) ctags$(EXEEXT) etags$(EXEEXT)\n\nuninstall-hook:\n\trm $(DESTDIR)$(bindir)/etags$(EXEEXT)\nendif\n\ninclude $(top_srcdir)/makefiles/testing.mak\ninclude $(top_srcdir)/makefiles/test-cases.mak\n\ninclude $(top_srcdir)/makefiles/help.mak\n\n"
  },
  {
    "path": "Units/parser-automake.r/subdirs.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-automake.r/subdirs.d/expected.tags",
    "content": "SUBDIRS\tinput.am\t/^SUBDIRS  = lib src . test$/;\"\tm\nlib\tinput.am\t/^SUBDIRS  = lib src . test$/;\"\ts\nsrc\tinput.am\t/^SUBDIRS  = lib src . test$/;\"\ts\n.\tinput.am\t/^SUBDIRS  = lib src . test$/;\"\ts\ntest\tinput.am\t/^SUBDIRS  = lib src . test$/;\"\ts\ndocs\tinput.am\t/^SUBDIRS += docs$/;\"\ts\n"
  },
  {
    "path": "Units/parser-automake.r/subdirs.d/input.am",
    "content": "SUBDIRS  = lib src . test\nSUBDIRS += docs\n"
  },
  {
    "path": "Units/parser-awk.r/functions.d/expected.tags",
    "content": "leadingWhitespace\tinput.awk\t/^\tfunction leadingWhitespace() {}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-awk.r/functions.d/input.awk",
    "content": "# match function definitions preceded by whitespace\n\tfunction leadingWhitespace() {}\n"
  },
  {
    "path": "Units/parser-awk.r/gawk-alias.d/args.ctags",
    "content": "-G\n"
  },
  {
    "path": "Units/parser-awk.r/gawk-alias.d/expected.tags",
    "content": "mysub\tinput.unknown\t/^function mysub(pat, repl, str, global)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-awk.r/gawk-alias.d/input.unknown",
    "content": "#!/usr/bin/env gawk\n# Taken from info manual of gawk.\nfunction mysub(pat, repl, str, global)\n{\n    if (global)\n        gsub(pat, repl, str)\n    else\n        sub(pat, repl, str)\n    return str\n}\n"
  },
  {
    "path": "Units/parser-awk.r/simple-awk.d/expected.tags",
    "content": "mysub\tinput.awk\t/^function mysub(pat, repl, str, global)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-awk.r/simple-awk.d/input.awk",
    "content": "# Taken from info manual of gawk.\nfunction mysub(pat, repl, str, global)\n{\n    if (global)\n        gsub(pat, repl, str)\n    else\n        sub(pat, repl, str)\n    return str\n}\n"
  },
  {
    "path": "Units/parser-awk.r/simple2-awk.d/expected.tags",
    "content": "max\tinput.awk\t/^function max(x, y) { return (x > y) ? x : y }$/;\"\tf\nnumjust\tinput.awk\t/^function numjust(n, s) {   # position s in field n$/;\"\tf\n"
  },
  {
    "path": "Units/parser-awk.r/simple2-awk.d/input.awk",
    "content": "# Aho, Alfred V., Brian W. Kernighan, and Peter J. Weinberger. The AWK\n# Programming Language. Reading, MA: Addison-Wesley Pub., 1988, p. 98.\n\n\n# table - simple table formatter\n\nBEGIN {\n    FS = \"\\t\"; blanks = sprintf(\"%100s\", \" \")\n    number = \"^[+-]?([0-9]+[.]?[0-9]*|[.][0-9]+)$\"\n}\n\n{   row[NR] = $0\n    for (i = 1; i <= NF; i++) {\n        if ($i ~ number)\n            nwid[i] = max(nwid[i], length($i))\n        wid[i] = max(wid[i], length($i))\n    }\n}\n\nEND {\n    for (r = 1; r <= NR; r++) {\n        n = split(row[r], d)\n        for (i = 1; i <= n; i++) {\n            sep = (i < n) ? \"   \" : \"\\n\"\n            if (d[i] ~ number)\n                printf(\"%\" wid[i] \"s%s\", numjust(i,d[i]), sep)\n            else\n                printf(\"%-\" wid[i] \"s%s\", d[i], sep)\n        }\n    }\n}\n\nfunction max(x, y) { return (x > y) ? x : y }\n\nfunction numjust(n, s) {   # position s in field n\n    return s substr(blanks, 1, int((wid[n]-nwid[n])/2))\n}\n"
  },
  {
    "path": "Units/parser-basic.r/basic-labels.d/expected.tags",
    "content": "repeat\tinput.bas\t/^repeat:$/;\"\tl\n"
  },
  {
    "path": "Units/parser-basic.r/basic-labels.d/input.bas",
    "content": "' This is not a label:\nREM This is not a label:\n\nrepeat:\nPRINT \"Going 'round again\"\nGOTO repeat\nEND\n"
  },
  {
    "path": "Units/parser-basic.r/freebasic-access.d/args.ctags",
    "content": "--sort=no\n--fields=+{access}\n"
  },
  {
    "path": "Units/parser-basic.r/freebasic-access.d/expected.tags",
    "content": "i_am_private\tinput.bas\t/^Private Sub i_am_private$/;\"\tf\taccess:private\ni_am_public\tinput.bas\t/^Public Sub i_am_public$/;\"\tf\taccess:public\n"
  },
  {
    "path": "Units/parser-basic.r/freebasic-access.d/input.bas",
    "content": "# Taken from https://documentation.help/FreeBASIC/KeyPgPublic.html\nPrivate Sub i_am_private\nEnd Sub\n\nPublic Sub i_am_public\nEnd Sub\n"
  },
  {
    "path": "Units/parser-basic.r/freebasic-decls.d/args.ctags",
    "content": "--sort=no\n--fields=+rE\n--extras=+r\n"
  },
  {
    "path": "Units/parser-basic.r/freebasic-decls.d/expected.tags",
    "content": "curses\tinput.bas\t/^namespace curses 'public use this$/;\"\tn\troles:def\nwin\tinput.bas\t/^\t\ttype win as curses.curses_priv._win_st$/;\"\tt\tnamespace:curses\troles:def\n_Init\tinput.bas\t/^\t\tdeclare\tfunction\t_Init\talias \"initscr\" () as win ptr$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nGetMaxX\tinput.bas\t/^\t\tdeclare\tfunction\tGetMaxX alias\t\"getmaxx\" (byval as win ptr) as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nGetMaxY\tinput.bas\t/^\t\tdeclare\tfunction\tGetMaxY alias \"getmaxy\"\t(byval as win ptr) as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nCreateWindow\tinput.bas\t/^\t\tdeclare\tfunction\tCreateWindow alias \"newwin\" (byval as integer, byval as integer, byval as int/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nCreateSubWindow\tinput.bas\t/^\t\tdeclare\tfunction\tCreateSubWindow alias \"subwin\" (byval as win ptr, byval as integer, byval as /;\"\tf\tnamespace:curses\troles:decl\textras:reference\nGetChar\tinput.bas\t/^\t\tdeclare function\tGetChar alias \"getch\" () as UByte$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nCBreak\tinput.bas\t/^\t\tdeclare function\tCBreak alias \"cbreak\" () as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nEreaseTerm\tinput.bas\t/^\t\tdeclare function\tEreaseTerm alias \"erase\" () as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nClearTerm\tinput.bas\t/^\t\tdeclare function\tClearTerm alias \"clear\" () as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nEreaseWindow\tinput.bas\t/^\t\tdeclare function EreaseWindow alias \"werase\" (byval as win ptr) as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nClearWindow\tinput.bas\t/^\t\tdeclare function ClearWindow alias \"wclear\" (byval as win ptr) as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nDeleteWindow\tinput.bas\t/^\t\tdeclare function DeleteWindow alias \"delwin\" (byval as win ptr) as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\n_Exit\tinput.bas\t/^\t\tdeclare function _Exit alias \"endwin\" () as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nRefresTerm\tinput.bas\t/^\t\tdeclare function RefresTerm alias \"refresh\" () as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nRefreshWindow\tinput.bas\t/^\t\tdeclare function RefreshWindow alias \"wrefresh\" (byval as win ptr) as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nPrintTerm\tinput.bas\t/^\t\tdeclare function PrintTerm  alias \"printw\" (byval as zstring ptr, ... ) as integer$/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nPrintWindow\tinput.bas\t/^\t\tdeclare function PrintWindow alias \"wprintw\" (byval as win ptr, byval as zstring ptr, ... ) as/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nSetCursorPositionTerm\tinput.bas\t/^\t\tdeclare function SetCursorPositionTerm alias \"move\" (byval as integer,byval as integer) as int/;\"\tf\tnamespace:curses\troles:decl\textras:reference\nSetCursorPositionWindow\tinput.bas\t/^\t\tdeclare function SetCursorPositionWindow alias \"wmove\" (byval as win ptr, byval as integer, by/;\"\tf\tnamespace:curses\troles:decl\textras:reference\n"
  },
  {
    "path": "Units/parser-basic.r/freebasic-decls.d/input.bas",
    "content": "' Taken from https://termbin.com/x9wo submitted by @Glog78\nnamespace curses 'public use this\n\t#include \"curses_priv.bi\"\n\t#inclib \"curses\"\n\n\textern \"c\"\n\n\t\ttype win as curses.curses_priv._win_st\n\n\t\tdeclare\tfunction\t_Init\talias \"initscr\" () as win ptr\n\t\tdeclare\tfunction\tGetMaxX alias\t\"getmaxx\" (byval as win ptr) as integer\n\t\tdeclare\tfunction\tGetMaxY alias \"getmaxy\"\t(byval as win ptr) as integer\n\t\tdeclare\tfunction\tCreateWindow alias \"newwin\" (byval as integer, byval as integer, byval as integer, byval as integer) as win\n\t\tdeclare\tfunction\tCreateSubWindow alias \"subwin\" (byval as win ptr, byval as integer, byval as integer, byval as integer, byval as integer) as win ptr\n\t\tdeclare function\tGetChar alias \"getch\" () as UByte\n\t\tdeclare function\tCBreak alias \"cbreak\" () as integer\n\t\tdeclare function\tEreaseTerm alias \"erase\" () as integer\n\t\tdeclare function\tClearTerm alias \"clear\" () as integer\n\t\tdeclare function EreaseWindow alias \"werase\" (byval as win ptr) as integer\n\t\tdeclare function ClearWindow alias \"wclear\" (byval as win ptr) as integer\n\t\tdeclare function DeleteWindow alias \"delwin\" (byval as win ptr) as integer\n\t\tdeclare function _Exit alias \"endwin\" () as integer\n\t\tdeclare function RefresTerm alias \"refresh\" () as integer\n\t\tdeclare function RefreshWindow alias \"wrefresh\" (byval as win ptr) as integer\n\t\tdeclare function PrintTerm  alias \"printw\" (byval as zstring ptr, ... ) as integer\n\t\tdeclare function PrintWindow alias \"wprintw\" (byval as win ptr, byval as zstring ptr, ... ) as integer\n\t\tdeclare function SetCursorPositionTerm alias \"move\" (byval as integer,byval as integer) as integer\n\t\tdeclare function SetCursorPositionWindow alias \"wmove\" (byval as win ptr, byval as integer, byval as integer) as integer\n\n\tend extern\n\nend namespace 'curses\n\n' vim: bs=2 sw=2 ss=2 ts=2 nu noet ft=basic\n"
  },
  {
    "path": "Units/parser-basic.r/freebasic-namespace.d/args.ctags",
    "content": "--sort=no\n--fields=+e\n"
  },
  {
    "path": "Units/parser-basic.r/freebasic-namespace.d/expected.tags",
    "content": "first\tinput.bas\t/^namespace first 'first defines something'$/;\"\tn\tend:12\nfirst_func\tinput.bas\t/^  sub first_func$/;\"\tf\tnamespace:first\nsecond\tinput.bas\t/^  namespace second 'second defines something'$/;\"\tn\tnamespace:first\tend:11\nfirst_func\tinput.bas\t/^    sub first_func  'oh a second first_func$/;\"\tf\tnamespace:first.second\nsecond_func\tinput.bas\t/^    sub second_func$/;\"\tf\tnamespace:first.second\nfirst_func\tinput.bas\t/^sub first_func 'oh another first_func$/;\"\tf\n"
  },
  {
    "path": "Units/parser-basic.r/freebasic-namespace.d/input.bas",
    "content": "namespace first 'first defines something'\n  sub first_func\n  end sub\n\n  namespace second 'second defines something'\n    sub first_func  'oh a second first_func\n    end sub\n\n    sub second_func\n    end sub\n  end namespace 'ignored'\nend namespace\n\nsub first_func 'oh another first_func\nend sub\n\n' vim: bs=2 sw=2 ss=2 ts=2 nu et ft=basic\n"
  },
  {
    "path": "Units/parser-basic.r/simple.bas.d/expected.tags",
    "content": "a\tinput.bas\t/^Common a As Integer$/;\"\tv\nb\tinput.bas\t/^Dim b As Integer$/;\"\tv\nc\tinput.bas\t/^dim as string c(20), d=\"a\", e$/;\"\tv\nd\tinput.bas\t/^dim as string c(20), d=\"a\", e$/;\"\tv\ne\tinput.bas\t/^dim as string c(20), d=\"a\", e$/;\"\tv\nf\tinput.bas\t/^Function f()$/;\"\tf\ng\tinput.bas\t/^dim shared as string g$/;\"\tv\nh\tinput.bas\t/^dim as string ptr h$/;\"\tv\ni\tinput.bas\t/^dim as string * 4096 i$/;\"\tv\nj\tinput.bas\t/^dim j as string=\"Export_GIR_FULL_\"+mid(date,7)+\",\"+mid(date,1,2)+\"\"+mid(date,4,2)+\".csv\"$/;\"\tv\nk\tinput.bas\t/^dim as string k=\"Export_GIR_FULL_\"+mid(date(),\"(\")+\",\"+mid(date,1,2)+\"\"+mid(date,4,2)+\".csv\", l$/;\"\tv\nl\tinput.bas\t/^dim as string k=\"Export_GIR_FULL_\"+mid(date(),\"(\")+\",\"+mid(date,1,2)+\"\"+mid(date,4,2)+\".csv\", l$/;\"\tv\none\tinput.bas\t/^Const one = 1$/;\"\tc\nstart\tinput.bas\t/^start:$/;\"\tl\nstr\tinput.bas\t/^DIM AS STRING str$/;\"\tv\ntest\tinput.bas\t/^Type test$/;\"\tt\n"
  },
  {
    "path": "Units/parser-basic.r/simple.bas.d/input.bas",
    "content": "Gosub start\n\nConst one = 1\n\nCommon a As Integer\nDim b As Integer\nDIM AS STRING str\ndim as string c(20), d=\"a\", e\ndim shared as string g\ndim as string ptr h\ndim as string * 4096 i\ndim j as string=\"Export_GIR_FULL_\"+mid(date,7)+\",\"+mid(date,1,2)+\"\"+mid(date,4,2)+\".csv\"\ndim as string k=\"Export_GIR_FULL_\"+mid(date(),\"(\")+\",\"+mid(date,1,2)+\"\"+mid(date,4,2)+\".csv\", l\n\nType test\n    a As Integer\n    b As Integer\nEnd Type\n\nFunction f()\n    a = 3\nEnd Function\n\nstart:\n    f()\nReturn\n\n\n"
  },
  {
    "path": "Units/parser-basic.r/simple.bb.d/expected.tags",
    "content": "a\tinput.bb\t/^Global a$/;\"\tv\nb\tinput.bb\t/^Dim b(100)$/;\"\tv\nf\tinput.bb\t/^Function f()$/;\"\tf\none#\tinput.bb\t/^Const one# = 1.0$/;\"\tc\nstart\tinput.bb\t/^.start$/;\"\tl\ntest\tinput.bb\t/^Type test$/;\"\tt\n"
  },
  {
    "path": "Units/parser-basic.r/simple.bb.d/input.bb",
    "content": "Gosub start\n\nConst one# = 1.0\n\nGlobal a\nDim b(100)\n\nType test\n    Field a\n    Field b\nEnd Type\n\nFunction f()\n    a = 3\nEnd Function\n\n.start\n    f()\nReturn\n\n"
  },
  {
    "path": "Units/parser-bats.r/bats-simple.d/args.ctags",
    "content": "--sort=no\n--extras=+sr\n--fields=+lr\n"
  },
  {
    "path": "Units/parser-bats.r/bats-simple.d/expected.tags",
    "content": "Zeroth test\tinput.bats\t/^@test \"Zeroth test\" {$/;\"\tt\tlanguage:Bats\troles:def\nFirst test\tinput.bats\t/^@test \"First test\" {$/;\"\tt\tlanguage:Bats\troles:def\nSecond test\tinput.bats\t/^@test \"Second test\" {$/;\"\tt\tlanguage:Bats\troles:def\nLoading\tinput.bats\t/^@test \"Loading\" {$/;\"\tt\tlanguage:Bats\troles:def\nABC\tinput.bats\t/^      load \"ABC\"$/;\"\tS\tlanguage:Bats\troles:loaded\na\"b\tinput.bats\t/^      load \"a\\\\\"b\"$/;\"\tS\tlanguage:Bats\troles:loaded\nc\\\\d\tinput.bats\t/^      load \"c\\\\\\\\d\"$/;\"\tS\tlanguage:Bats\troles:loaded\nEFG\tinput.bats\t/^      load EFG$/;\"\tS\tlanguage:Bats\troles:loaded\nHIJ\tinput.bats\t/^      load 'HIJ'$/;\"\tS\tlanguage:Bats\troles:loaded\nh\\\\ij\tinput.bats\t/^      load 'h\\\\ij'$/;\"\tS\tlanguage:Bats\troles:loaded\nK L;M\tinput.bats\t/^      load K\\\\ L\\\\;M$/;\"\tS\tlanguage:Bats\troles:loaded\n"
  },
  {
    "path": "Units/parser-bats.r/bats-simple.d/input.bats",
    "content": "#!/usr/bin/env bats\n\n@test \"Zeroth test\" {\n  # will have no tags\n}\n\n# bats file_tags=a:b\n# bats test_tags=c:d\n\n@test \"First test\" {\n  # will be tagged a:b, c:d\n}\n\n# bats file_tags=\n\n@test \"Second test\" {\n  # will have no tags\n}\n\n@test \"Loading\" {\n      load \"ABC\"\n      load \"a\\\"b\"\n      load \"c\\\\d\"\n      load EFG\n      load 'HIJ'\n      load 'h\\ij'\n      load K\\ L\\;M\n}\n\n# Taken from https://bats-core.readthedocs.io/en/stable/writing-tests.html\n"
  },
  {
    "path": "Units/parser-bibtex.r/bib-simple.d/args.ctags",
    "content": "--sort=no\n--fields=+l\n"
  },
  {
    "path": "Units/parser-bibtex.r/bib-simple.d/expected.tags",
    "content": "1957-doe_loc_ident\tinput.bib\t/^@article{1957-doe_loc_ident,$/;\"\ta\tlanguage:BibTeX\ndoe+rocket\tinput.bib\t/^@Book{doe+rocket,$/;\"\tb\tlanguage:BibTeX\ntiny_collect\tinput.bib\t/^@booklet{tiny_collect,$/;\"\tB\tlanguage:BibTeX\n1960-rocket_deep-exploration\tinput.bib\t/^@conference{1960-rocket_deep-exploration,$/;\"\tc\tlanguage:BibTeX\n1961-doe-diverse_splits\tinput.bib\t/^@inbook{1961-doe-diverse_splits,$/;\"\ti\tlanguage:BibTeX\n1960-doe-location_splits\tinput.bib\t/^@incollection{1960-doe-location_splits,$/;\"\tI\tlanguage:BibTeX\n1959-rocket_exploration\tinput.bib\t/^@INPROCEEDINGS{1959-rocket_exploration,$/;\"\tj\tlanguage:BibTeX\nman_loc_splits\tinput.bib\t/^@manual{man_loc_splits,$/;\"\tm\tlanguage:BibTeX\ndoe_mastersth\tinput.bib\t/^@mastersthesis{doe_mastersth,$/;\"\tM\tlanguage:BibTeX\ndoe_mastersth_data\tinput.bib\t/^@misc{doe_mastersth_data,$/;\"\tn\tlanguage:BibTeX\ndoe_phd\tinput.bib\t/^@phdthesis{doe_phd,$/;\"\tp\tlanguage:BibTeX\n1960_conf_splits\tinput.bib\t/^@proceedings{1960_conf_splits,$/;\"\tP\tlanguage:BibTeX\njohn_doe\tinput.bib\t/^@string{john_doe = \"Prof. Dr. John Doe\"}$/;\"\ts\tlanguage:BibTeX\n1961_splits\tinput.bib\t/^@techreport{1961_splits$/;\"\tt\tlanguage:BibTeX\nxx_thoughts\tinput.bib\t/^@unpublished{xx_thoughts,$/;\"\tu\tlanguage:BibTeX\nhicks:2001\tinput.bib\t/^@Book{hicks:2001,$/;\"\tb\tlanguage:BibTeX\nknuthwebsite\tinput.bib\t/^@online{knuthwebsite,$/;\"\tV\tlanguage:BibLaTeX\n10.1145/605432.605407\tinput.bib\t/^@Article{10.1145\\/605432.605407,$/;\"\ta\tlanguage:BibTeX\n"
  },
  {
    "path": "Units/parser-bibtex.r/bib-simple.d/input.bib",
    "content": "% this is a comment that will be ignored\n\n@article{1957-doe_loc_ident,\n author    = \"John Doe\",\n title     = \"Exploration of the \n              Location-Identity Split\",\n journal   = \"Journal of Splits\",\n year      =  1957,\n volume    =  3\n}\n\n@Book{doe+rocket,\n author    = \"John Doe and Rocket Scientist\",\n title     = \"Theory of Splits\",\n publisher = \"Dover\",\n year      =  1964,\n address   = \"New York City\",\n edition   = \"ninth Dover printing, tenth GPO printing\"\n}\n\n@booklet{tiny_collect,\n  title    = \"A tiny collection of stuff\"\n}\n\n@conference{1960-rocket_deep-exploration,\n author    = \"Rocket Scientist\",\n title     = \"Deep Exploration of the Singleton Split\",\n booktitle = \"34th international conference of important stuff (ICIS)\",\n year      =  1960\n}\n\n@inbook{1961-doe-diverse_splits,\n  author    = \"John Doe\",\n  title     = \"A comprehensive list of splits\",\n  pages     = {13-39},\n  publisher = \"Penguin Books\",\n  year      = 1961\n}\n\n@incollection{1960-doe-location_splits,\n  author    = \"John Doe\",\n  title     = \"Survey of location splits\",\n  booktitle = \"Current state of the art in computational methods\",\n  publisher = \"Penguin Books\",\n  year      = 1960\n}\n\n@INPROCEEDINGS{1959-rocket_exploration,\n author    = \"Rocket Scientist\",\n title     = \"Exploration of the \n              Location-Singleton Split\",\n booktitle = \"33th international conference of important stuff (ICIS)\",\n year      =  1959\n}\n\n@manual{man_loc_splits,\n  title  = \"Introduction to Location Splits\"\n}\n\n@mastersthesis{doe_mastersth,\n  author = \"John Doe\"\n  title  = \"Evaluating location splits under identity constraints\",\n  school = \"School of Computer Science\",\n  year   = 1955\n}\n\n@misc{doe_mastersth_data,\n  author       = \"John Doe\"\n  title        = \"Dataset of location splits under identity constraints\",\n  howpublished = \"http://johndoe.edu/masterthesis/data\",\n  year         = 1955\n}\n\n@phdthesis{doe_phd,\n  author = \"John Doe\"\n  title  = \"Evaluating location splits under diverse constraints\",\n  school = \"School of Computer Science\",\n  year   = 1958\n}\n\n@proceedings{1960_conf_splits,\n  title = \"First international conference of splits\",\n  year  = 1960\n}\n\n@string{john_doe = \"Prof. Dr. John Doe\"}\n\n@techreport{1961_splits\n, author      = \"Rocket Scientist\"\n, title       = \"An introduction to advanced splits\"\n, institution = \"School of Engineering\"\n, year        = 1961\n}\n\n@unpublished{xx_thoughts,\n  author = \"John Doe and Rocket Scientist\",\n  title  = \"Thoughts on the future of splits\",\n  note   = \"Heavily thought about\"\n}\n\n@Comment Taken from https://ja.wikipedia.org/wiki/BibTeX\n@Book{hicks:2001,\n author = \"von Hicks, III, Michael\",\n title = \"Design of a Carbon Fiber Composite Grid Structure for the GLAST\n Spacecraft Using a Novel Manufacturing Technique\",\n publisher = \"Stanford Press\",\n year = 2001,\n address = \"Palo Alto\",\n edition = \"1st,\",\n isbn = \"0-69-697269-4\"\n }\n\n@Comment Taken fron https://ja.overleaf.com/learn/latex/Bibliography_management_with_biblatex\n@online{knuthwebsite,\n    author    = \"Donald Knuth\",\n    title     = \"Knuth: Computers and Typesetting\",\n    url       = \"http://www-cs-faculty.stanford.edu/~uno/abcde.html\",\n    keywords  = \"latex,knuth\"\n}\n\n@Comment Taken from https://github.com/universal-ctags/ctags/issues/3802#issuecomment-1723511773\n@Comment submitted by @andregpss (André Silva)\n@Article{10.1145/605432.605407,\nauthor = {Levis, Philip and Culler, David},\ntitle = {Mat'{e}: A Tiny Virtual Machine for Sensor Networks},\nyear = {2002} }\n"
  },
  {
    "path": "Units/parser-c.r/anonymous-param-in-broken-paramlist.d/README",
    "content": "This is a test case for detecting memory leaking.\n"
  },
  {
    "path": "Units/parser-c.r/anonymous-param-in-broken-paramlist.d/args.ctags",
    "content": "--kinds-C=+z\n--extras=+{anonymous}\n"
  },
  {
    "path": "Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input-0.c",
    "content": "/* https://gitlab.gnome.org/GNOME/glib/-/blob/main/gio/gdummyproxyresolver.c */\nG_DEFINE_TYPE_WITH_CODE (GDummyProxyResolver, g_dummy_proxy_resolver, G_TYPE_OBJECT,\n\t\t\t G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,\n\t\t\t\t\t\tg_dummy_proxy_resolver_iface_init)\n\t\t\t _g_io_modules_ensure_extension_points_registered ();\n\t\t\t g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME,\n\t\t\t\t\t\t\t g_define_type_id,\n\t\t\t\t\t\t\t \"dummy\",\n\t\t\t\t\t\t\t -100))\n\nstatic void\ng_dummy_proxy_resolver_finalize (GObject *object)\n{\n  /* must chain up */\n  G_OBJECT_CLASS (g_dummy_proxy_resolver_parent_class)->finalize (object);\n}\n"
  },
  {
    "path": "Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input-1.c",
    "content": "G (f () g ()) h (void) {\n"
  },
  {
    "path": "Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input.c",
    "content": "f(a,){\n"
  },
  {
    "path": "Units/parser-c.r/attr-attached-to-array-failed.b/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-c.r/attr-attached-to-array-failed.b/expected.tags",
    "content": "registered_fb3\tinput.c\t/^struct fb_info *registered_fb3[FB_MAX] __read_mostly X Y();$/;\"\tv\ttyperef:struct:fb_info * [FB_MAX]__read_mostly X Y()\nregistered_fb7\tinput.c\t/^struct fb_info *registered_fb7[FB_MAX] __read_mostly X(\"a\");$/;\"\tv\ttyperef:struct:fb_info * [FB_MAX]__read_mostly X (\"a\")\nregistered_fb8\tinput.c\t/^struct fb_info *registered_fb8[FB_MAX] __read_mostly X(\"a\") C;$/;\"\tv\ttyperef:struct:fb_info * [FB_MAX]__read_mostly X (\"a\") C\n"
  },
  {
    "path": "Units/parser-c.r/attr-attached-to-array-failed.b/input.c",
    "content": "struct fb_info *registered_fb3[FB_MAX] __read_mostly X Y();\nstruct fb_info *registered_fb7[FB_MAX] __read_mostly X(\"a\");\nstruct fb_info *registered_fb8[FB_MAX] __read_mostly X(\"a\") C;\n"
  },
  {
    "path": "Units/parser-c.r/attr-attached-to-array.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-c.r/attr-attached-to-array.d/expected.tags",
    "content": "registered_fb1\tinput.c\t/^struct fb_info *registered_fb1[FB_MAX] __read_mostly;$/;\"\tv\ttyperef:struct:fb_info * [FB_MAX]__read_mostly\nregistered_fb2\tinput.c\t/^struct fb_info *registered_fb2[FB_MAX] __read_mostly X;$/;\"\tv\ttyperef:struct:fb_info * [FB_MAX]__read_mostly X\nregistered_fb4\tinput.c\t/^struct fb_info *registered_fb4[FB_MAX] __read_mostly X Y(1, 2);$/;\"\tv\ttyperef:struct:fb_info * [FB_MAX]__read_mostly X Y (1,2)\nregistered_fb5\tinput.c\t/^struct fb_info *registered_fb5[FB_MAX] __read_mostly X Y(1, 2), fb6[3] _Z_;$/;\"\tv\ttyperef:struct:fb_info * [FB_MAX]__read_mostly X Y (1,2)\nfb6\tinput.c\t/^struct fb_info *registered_fb5[FB_MAX] __read_mostly X Y(1, 2), fb6[3] _Z_;$/;\"\tv\ttyperef:struct:fb_info[3]_Z_\n"
  },
  {
    "path": "Units/parser-c.r/attr-attached-to-array.d/input.c",
    "content": "struct fb_info *registered_fb1[FB_MAX] __read_mostly;\nstruct fb_info *registered_fb2[FB_MAX] __read_mostly X;\nstruct fb_info *registered_fb4[FB_MAX] __read_mostly X Y(1, 2);\nstruct fb_info *registered_fb5[FB_MAX] __read_mostly X Y(1, 2), fb6[3] _Z_;\n"
  },
  {
    "path": "Units/parser-c.r/backslash-in-input.c.d/expected.tags",
    "content": "main\tinput.c\t/^int main \\\\$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-c.r/backslash-in-input.c.d/input.c",
    "content": "\nint main \\\n  ()\n{\n}\n"
  },
  {
    "path": "Units/parser-c.r/bit_field.c.d/args.ctags",
    "content": "--sort=no\n--fields-all=+{end}\n"
  },
  {
    "path": "Units/parser-c.r/bit_field.c.d/expected.tags",
    "content": "bit_fields\tinput.c\t/^struct bit_fields {$/;\"\ts\tfile:\tend:5\na\tinput.c\t/^    unsigned int a: 1;$/;\"\tm\tstruct:bit_fields\ttyperef:typename:unsigned int:1\tfile:\tend:2\nb\tinput.c\t/^    unsigned int b: 1;$/;\"\tm\tstruct:bit_fields\ttyperef:typename:unsigned int:1\tfile:\tend:3\nc\tinput.c\t/^    unsigned int c: 2;$/;\"\tm\tstruct:bit_fields\ttyperef:typename:unsigned int:2\tfile:\tend:4\n__anon1719c4a50108\tinput.c\t/^struct {$/;\"\ts\tfile:\tend:12\nsign\tinput.c\t/^    unsigned sign  : 1;$/;\"\tm\tstruct:__anon1719c4a50108\ttyperef:typename:unsigned:1\tfile:\tend:8\nexp\tinput.c\t/^    unsigned exp   : _FP_EXPBITS_D;$/;\"\tm\tstruct:__anon1719c4a50108\ttyperef:typename:unsigned\tfile:\tend:9\nfrac1\tinput.c\t/^    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;$/;\"\tm\tstruct:__anon1719c4a50108\ttyperef:typename:unsigned\tfile:\tend:10\nfrac0\tinput.c\t/^    unsigned frac0 : _FP_W_TYPE_SIZE;$/;\"\tm\tstruct:__anon1719c4a50108\ttyperef:typename:unsigned\tfile:\tend:11\nshortname_info\tinput.c\t/^struct shortname_info {$/;\"\ts\tfile:\tend:18\nlower\tinput.c\t/^\tunsigned char lower:1,$/;\"\tm\tstruct:shortname_info\ttyperef:typename:unsigned char:1\tfile:\tend:15\nupper\tinput.c\t/^\t\t      upper:1,$/;\"\tm\tstruct:shortname_info\ttyperef:typename:unsigned char:1\tfile:\tend:16\nvalid\tinput.c\t/^\t\t      valid:1;$/;\"\tm\tstruct:shortname_info\ttyperef:typename:unsigned char:1\tfile:\tend:17\n__anon1719c4a50208\tinput.c\t/^{$/;\"\ts\tfile:\tend:27\npublic\tinput.c\t/^    BYTE \tpublic: 1;$/;\"\tm\tstruct:__anon1719c4a50208\ttyperef:typename:BYTE:1\tfile:\tend:23\nbad2\tinput.c\t/^    BYTE \tbad2: 1;$/;\"\tm\tstruct:__anon1719c4a50208\ttyperef:typename:BYTE:1\tfile:\tend:24\ngroup\tinput.c\t/^    BYTE \tgroup: 1;$/;\"\tm\tstruct:__anon1719c4a50208\ttyperef:typename:BYTE:1\tfile:\tend:25\npersonal\tinput.c\t/^    BYTE \tpersonal: 1;$/;\"\tm\tstruct:__anon1719c4a50208\ttyperef:typename:BYTE:1\tfile:\tend:26\nbitfield_flags\tinput.c\t/^} bitfield_flags;$/;\"\tt\ttyperef:struct:__anon1719c4a50208\tfile:\n__anon1719c4a50308\tinput.c\t/^{$/;\"\ts\tfile:\tend:35\nthis\tinput.c\t/^    BYTE\tthis;$/;\"\tm\tstruct:__anon1719c4a50308\ttyperef:typename:BYTE\tfile:\tend:31\npublic\tinput.c\t/^    BYTE\tpublic;$/;\"\tm\tstruct:__anon1719c4a50308\ttyperef:typename:BYTE\tfile:\tend:32\nprivate\tinput.c\t/^    BYTE\tprivate;$/;\"\tm\tstruct:__anon1719c4a50308\ttyperef:typename:BYTE\tfile:\tend:33\nthat\tinput.c\t/^    BYTE\tthat;$/;\"\tm\tstruct:__anon1719c4a50308\ttyperef:typename:BYTE\tfile:\tend:34\nmystruct\tinput.c\t/^} mystruct;$/;\"\tt\ttyperef:struct:__anon1719c4a50308\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/bit_field.c.d/input.c",
    "content": "struct bit_fields {\n    unsigned int a: 1;\n    unsigned int b: 1;\n    unsigned int c: 2;\n};\n\nstruct {\n    unsigned sign  : 1;\n    unsigned exp   : _FP_EXPBITS_D;\n    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;\n    unsigned frac0 : _FP_W_TYPE_SIZE;\n};\n\nstruct shortname_info {\n\tunsigned char lower:1,\n\t\t      upper:1,\n\t\t      valid:1;\n};\n\n// Problem reported by Michael Brown on 23 October 2001.\ntypedef struct\n{\n    BYTE \tpublic: 1;\n    BYTE \tbad2: 1;\n    BYTE \tgroup: 1;\n    BYTE \tpersonal: 1;\n} bitfield_flags;\n\ntypedef struct\n{\n    BYTE\tthis;\n    BYTE\tpublic;\n    BYTE\tprivate;\n    BYTE\tthat;\n} mystruct;\n"
  },
  {
    "path": "Units/parser-c.r/broken-input-cxx-operator.d/input.c",
    "content": "struct a::b{\n"
  },
  {
    "path": "Units/parser-c.r/bug1020715.c.d/args.ctags",
    "content": "--fields=+S\n--excmd=number\n--kinds-C=+l\n"
  },
  {
    "path": "Units/parser-c.r/bug1020715.c.d/expected.tags",
    "content": "f\tinput.c\t43;\"\tf\ttyperef:typename:void\tsignature:()\n"
  },
  {
    "path": "Units/parser-c.r/bug1020715.c.d/input.c",
    "content": "/*\nBugs item #1020715, was opened at 2004-09-01 22:42\nMessage generated for change (Tracker Item Submitted) made by Item Submitter\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=1020715&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Arne Georg Gleditsch (argggh)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: Strange parsing of C code\n\nInitial Comment:\nRunning ctags 5.5.4 like this\n\n/usr/local/bin/ctags --fields=+S --excmd=number -f - --c-types=+l /usr/src/source/2.6.6/drivers/scsi/aha152x.c | grep ^done\n\nreturns a bogus entry for the function \"done\" on line\n1745 with a wacky signature.  The file aha152x.c is\nfrom Linux 2.6.6, but is appended for convenience.\n*/\n/*\nDate: 2007-08-14 01:00\nSender: elliotth\nHide\n\ni don't really understand why the other lines in the test case were\nnecessary to exercise the bug, but changing parseParens to call\nprocessAngleBracket instead of just skipToMatch(\"<>\") fixes this bug. i've\ncommitted that since it causes no regressions.\n\n\nDate: 2007-08-14 00:34\nSender: elliotth\nHide\n\ni've come up with a minimal test case, and committed it. it's pretty\nweird:\n*/\nvoid f() {\n\tdone(a<<1);\n\ta->a;\n\tif (a->a) {\n\t}\n}\n/*\nchange just about anything and the bizarre \"done\" tag goes away. you can't\neven switch from '->' to '.', which seems odd.\n*/\n"
  },
  {
    "path": "Units/parser-c.r/bug1085585.c.d/args.ctags",
    "content": "--kinds-c=+p\n"
  },
  {
    "path": "Units/parser-c.r/bug1085585.c.d/expected.tags",
    "content": "check_parity\tinput.c\t/^static int check_parity(des_cblock (*key));$/;\"\tp\ttyperef:typename:int\tfile:\ndes_check_key\tinput.c\t/^int des_check_key=0;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-c.r/bug1085585.c.d/input.c",
    "content": "/*\nBugs item #1085585, was opened at 2004-12-14 20:55\nMessage generated for change (Tracker Item Submitted) made by Item Submitter\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=1085585&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: boisterous (yadavnav)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: ctags 5.5.4 doesn't work correctly on some files\n\nInitial Comment:\nHi,\n\nI ran exuberant ctags on the following file\n\nFreeBSD kernel : src/sys/crypto/des/des_setkey.c\n\nIf I run the 5.5.4 ctags on version 1.3 of the above\nfile then it doesn't produce all the tags\n\nThe version 1.3 is at:\n\nhttp://www.freebsd.org/cgi/cvsweb.cgi/src/sys/crypto/des/des_setkey.c?rev=1.3&content-type=text/x-cvsweb-markup\n\n[...]\n\nWhy does ctags fail on the 1.3 version of the file ?\n*/\n\n/* relevant portion from file */\nstatic int check_parity(des_cblock (*key));\nint des_check_key=0;\n"
  },
  {
    "path": "Units/parser-c.r/bug1086609.c.d/expected.tags",
    "content": "func2\tinput.c\t/^int func2(int a)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-c.r/bug1086609.c.d/input.c",
    "content": "/*\nBugs item #1086609, was opened at 2004-12-16 13:07\nMessage generated for change (Tracker Item Submitted) made by Item Submitter\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=1086609&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Mikhail Kruk (meshko)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: ctags getting confused by #if 0\n\nInitial Comment:\nHere is a sample C program which confuses ctags.  I\nthink every line in it is significant. Dropping any of\nthe #ifdefs or the #define makes the problem go away:\n*/\n#if 0\n#define __PROC__\nint func1(\n#if 0\n#endif\n)\n{\n}\n#endif\n\nint func2(int a)\n{\n}\n/*\nSomehow the opening brace from line 3 doesn't get\nignored and the closing brace does get ignored and\nctags drops out on \"int func2(int a)\" line with \"failed\nto find match for '(' at line 11\" error.\nGranted, having #if 0 in the middle of args list is\nweird, but perfeclty legal.\n*/\n"
  },
  {
    "path": "Units/parser-c.r/bug1198.c.d/args.ctags",
    "content": "--kinds-c=fpvx\n--fields=+tS\n"
  },
  {
    "path": "Units/parser-c.r/bug1198.c.d/expected.tags",
    "content": "XESetCopyEventCookie\tinput.c\t/^extern Bool (*XESetCopyEventCookie($/;\"\tp\ttyperef:typename:Bool (*)(Display *,XGenericEventCookie *,XGenericEventCookie *)\tfile:\tsignature:(Display *,int,Bool (*)(Display *,XGenericEventCookie *,XGenericEventCookie *))\nf\tinput.c\t/^int (* f (char c)) (void * a)$/;\"\tf\ttyperef:typename:int (*)(void * a)\tsignature:(char c)\nf\tinput.c\t/^int (* f (char c)) (void * a);$/;\"\tp\ttyperef:typename:int (*)(void * a)\tfile:\tsignature:(char c)\ng\tinput.c\t/^static int g (void *a)$/;\"\tf\ttyperef:typename:int\tfile:\tsignature:(void * a)\n"
  },
  {
    "path": "Units/parser-c.r/bug1198.c.d/input.c",
    "content": "/*\n Bug 1198@github reported by lvc on 26/11/2016.\n \n The latest universal ctags 015eae7 doesn't detect function XESetCopyEventCookie\n from libX11-1.3 library (include/X11/Xlibint.h):\n*/\n\nextern Bool (*XESetCopyEventCookie(\n    Display*            /* display */,\n    int                 /* extension */,\n    Bool (*) (\n               Display*                 /* display */,\n               XGenericEventCookie*     /* in */,\n               XGenericEventCookie*     /* out */\n             )          /* proc */\n))(\n    Display*, XGenericEventCookie*, XGenericEventCookie*\n);\n\n/* also adding simplified output found by masatake */\n\nint (* f (char c)) (void * a);\n\nstatic int g (void *a)\n{\n\treturn 1;\n}\n\nint (* f (char c)) (void * a)\n{\n\treturn g;\n}"
  },
  {
    "path": "Units/parser-c.r/bug1201689.c.d/expected.tags",
    "content": "test\tinput.c\t/^void test(a, ...)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-c.r/bug1201689.c.d/input.c",
    "content": "/*\nBugs item #1201689, was opened at 2005-05-13 18:18\nMessage generated for change (Tracker Item Submitted) made by Item Submitter\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=1201689&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Scott Ferguson (shf301)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: Variable Length Argument Lists in K&R Style not Parsed\n\nInitial Comment:\nA function with a K&R style parameter list that has a \nvariable length argument list will not be added to the tags file.\n\nFor example create a file, say test.c with the following code\n*/\nvoid test(a, ...)\nchar a;\n{\n    return;\n}\n/*\nRun ctags test.c.  the tags file with only contain the line:\n   a\ttest.c\t/^char a;$/;\"\tv\n\nThis occurs with ctags 5.3 and 5.5.4. \n\nVariable length argument lists work fine if the function is in \nANSI style, void test(char a, ...) will work fine.\n*/\n"
  },
  {
    "path": "Units/parser-c.r/bug1458930.c.d/args.ctags",
    "content": "--kinds-c=+p\n"
  },
  {
    "path": "Units/parser-c.r/bug1458930.c.d/expected.tags",
    "content": "x\tinput.c\t/^char x();$/;\"\tp\ttyperef:typename:char\tfile:\ny\tinput.c\t/^wchar_t y();$/;\"\tp\ttyperef:typename:wchar_t\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/bug1458930.c.d/input.c",
    "content": "// test with --kinds-c=+p\nchar x();\nwchar_t y();\n"
  },
  {
    "path": "Units/parser-c.r/bug1466117.c.d/expected.tags",
    "content": "__anonadd2b98b0108\tinput.c\t/^typedef struct {$/;\"\ts\tfile:\na\tinput.c\t/^\tint a;$/;\"\tm\tstruct:__anonadd2b98b0108\ttyperef:typename:int\tfile:\na\tinput.c\t/^\tint a;$/;\"\tm\tstruct:mystruct\ttyperef:typename:int\tfile:\nb\tinput.c\t/^\tint b;$/;\"\tm\tstruct:__anonadd2b98b0108\ttyperef:typename:int\tfile:\nb\tinput.c\t/^\tint b;$/;\"\tm\tstruct:mystruct\ttyperef:typename:int\tfile:\nmystruct\tinput.c\t/^typedef struct mystruct {$/;\"\ts\tfile:\nmystruct\tinput.c\t/^} mystruct;$/;\"\tt\ttyperef:struct:__anonadd2b98b0108\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/bug1466117.c.d/input.c",
    "content": "typedef struct mystruct {\n\tint a;\n\tint b;\n};\n\ntypedef struct {\n\tint a;\n\tint b;\n} mystruct;\n\n"
  },
  {
    "path": "Units/parser-c.r/bug1491666.c.d/args.ctags",
    "content": "--kinds-c=+l\n"
  },
  {
    "path": "Units/parser-c.r/bug1491666.c.d/expected.tags",
    "content": "__anon329ddd920108\tinput.c\t/^typedef struct {$/;\"\ts\tfile:\nmain\tinput.c\t/^void main (void) {$/;\"\tf\ttyperef:typename:void\nmy_struct\tinput.c\t/^} my_struct;$/;\"\tt\ttyperef:struct:__anon329ddd920108\tfile:\nvar1\tinput.c\t/^\tmy_struct var1;$/;\"\tl\tfunction:main\ttyperef:typename:my_struct\tfile:\nvar2\tinput.c\t/^\t\tvar2;$/;\"\tl\tfunction:main\ttyperef:typename:my_struct\tfile:\nx\tinput.c\t/^\t\tx;$/;\"\tm\tstruct:__anon329ddd920108\ttyperef:typename:int\tfile:\ny\tinput.c\t/^\t\ty;$/;\"\tm\tstruct:__anon329ddd920108\ttyperef:typename:float\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/bug1491666.c.d/input.c",
    "content": "typedef struct {\n\tint\n\t\tx;\n\n\tfloat\n\t\ty;\n} my_struct;\n\nvoid main (void) {\n\tmy_struct var1;\n\tmy_struct\n\t\tvar2;\n}\n"
  },
  {
    "path": "Units/parser-c.r/bug1764143.h.d/expected.tags",
    "content": "arch_reset\tinput.h\t/^static inline void arch_reset(char mode)$/;\"\tf\ttyperef:typename:void\nomap1_arch_reset\tinput.h\t/^static inline void omap1_arch_reset(char mode)$/;\"\tf\ttyperef:typename:void\n"
  },
  {
    "path": "Units/parser-c.r/bug1764143.h.d/input.h",
    "content": "static inline void omap1_arch_reset(char mode)\n{\n\t/*\n\t * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28\n\t * \"Global Software Reset Affects Traffic Controller Frequency\".\n\t */\n\tif (cpu_is_omap5912()) {\n\t\tomap_writew(omap_readw(DPLL_CTL) & ~(1 << 4),\n\t\t\t\t DPLL_CTL);\n\t\tomap_writew(0x8, ARM_RSTCT1);\n\t}\n\n\tif (machine_is_voiceblue())\n\t\tvoiceblue_reset();\n\telse\n\t\tomap_writew(1, ARM_RSTCT1);\n}\n\nstatic inline void arch_reset(char mode)\n{\n\tif (!cpu_is_omap24xx())\n\t\tomap1_arch_reset(mode);\n\telse\n\t\tomap_prcm_arch_reset(mode);\n}\n\n#endif\n"
  },
  {
    "path": "Units/parser-c.r/bug2554.c.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-c.r/bug2554.c.d/expected.tags",
    "content": "__anonbbb2b4710108\tinput.c\t/^{$/;\"\ts\tfile:\nn\tinput.c\t/^  int*n;$/;\"\tm\tstruct:__anonbbb2b4710108\ttyperef:typename:int *\tfile:\nS\tinput.c\t/^} S;$/;\"\tt\ttyperef:struct:__anonbbb2b4710108\tfile:\nfoo\tinput.c\t/^struct foo {$/;\"\ts\tfile:\nbar\tinput.c\t/^\tint bar;$/;\"\tm\tstruct:foo\ttyperef:typename:int\tfile:\nv\tinput.c\t/^} v = {$/;\"\tv\ttyperef:struct:foo\nw\tinput.c\t/^struct foo w = {$/;\"\tv\ttyperef:struct:foo\n"
  },
  {
    "path": "Units/parser-c.r/bug2554.c.d/input.c",
    "content": "/* valgrind reported an error when ctags built with\n * --enable-debugging configure option.\n *\n * To reproduce:\n *\n *  $ make units LANGUAGES=C VG=1\n *\n */\ntypedef struct\n{\n  int*n;\n} S;\n\nstruct foo {\n\tint bar;\n} v = {\n\t.bar = 1,\n};\n\nstruct foo w = {\n\t.bar = 2,\n};\n"
  },
  {
    "path": "Units/parser-c.r/bug507864.c.d/README",
    "content": "This one is prepared as part of a bug report,\nsf-bugs:22, http://sourceforge.net/p/ctags/bugs/22/.\n\nDarren Hiebert closed the bug with \"closed-wont-fix\"\nstatus with following comment:\n\n    The use of a macro call in an argument list, as shown in\n    bad_code.c is too problematic to derive a good solution for.\n    Such bizarre used of macros are rare and not worth the risk\n    of breaking more common situations.\n\nSo I(Masatake YAMATO), don't touch this case and put it\nhere.\n"
  },
  {
    "path": "Units/parser-c.r/bug507864.c.d/expected.tags",
    "content": "func1\tinput.c\t/^FUNCSTS func1(ENTSEQNO(seq)) {}$/;\"\tf\ttyperef:typename:FUNCSTS\nfunc2\tinput.c\t/^FUNCSTS func2 (MEMTXT(form_msg), MEMTXT (text), MEMTXT (mail)) {}$/;\"\tf\ttyperef:typename:FUNCSTS\n"
  },
  {
    "path": "Units/parser-c.r/bug507864.c.d/input.c",
    "content": "FUNCSTS func1(ENTSEQNO(seq)) {}\nFUNCSTS func2 (MEMTXT(form_msg), MEMTXT (text), MEMTXT (mail)) {}\n"
  },
  {
    "path": "Units/parser-c.r/bug556645.c.d/README",
    "content": "This one is prepared as part of a bug report,\nsf-bugs:33, http://sourceforge.net/p/ctags/bugs/33/.\n\nDarren Hiebert closed the bug with \"closed-wont-fix\"\nstatus with following comment:\n\n    This cannot be handled without preprocessing. Ctags does not\n    do preprocessing for a number of reasons, and so will never\n    handle such a situation. You can do the preprocessing\n    yourself and run ctags on the output with the\n    --line-directives option.\n\nSo I(Masatake YAMATO), don't touch this case and put it\nhere.\n\n--------------------------------------------------------------------\n\nSurprisingly, new C/Cxx parser can capture Qtype well.\n\n"
  },
  {
    "path": "Units/parser-c.r/bug556645.c.d/expected.tags",
    "content": "A1\tinput.c\t/^#define A1(/;\"\td\tfile:\nQtype\tinput.c\t/^typedef A1(ilm_struct, 1) Qtype;$/;\"\tt\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/bug556645.c.d/input.c",
    "content": "/*\nFrom noreply@sourceforge.net Wed May 29 23:11:25 2002\nDate: Wed, 15 May 2002 23:25:52 -0700\nFrom: noreply@sourceforge.net\nTo: noreply@sourceforge.net\nSubject: [ ctags-Bugs-556645 ] Some typedef can not be tagged in C code\n\nBugs item #556645, was opened at 2002-05-16 14:25\nYou can respond by visiting: \nhttp://sourceforge.net/tracker/?func=detail&atid=106556&aid=556645&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Howard Wu (howardhbwu)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: Some typedef can not be tagged in C code\n\nInitial Comment:\nMy Ctags version:5.2.3\n\nThe typedef of \"Qtype\" as the following,\n\n*/\n#define A1(_type, _length)                  \\\nstruct  {                                   \\\n    \t    unsigned int    head;           \\\n    \t    unsigned int    tail;           \\\n    \t    bool            is_full;        \\\n    \t    _type           queue[_length]; \\\n\t}\n\ntypedef A1(ilm_struct, 1) Qtype;\n\n/*\nAs using ctags, the \"Qtype\" can not be tagged by it.\n*/\n"
  },
  {
    "path": "Units/parser-c.r/bug556646.c.d/expected.tags",
    "content": "A\tinput.c\t/^  A = INDX_T2$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_C1\tinput.c\t/^  INDX_C1,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_C2\tinput.c\t/^  INDX_C2,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_IM1\tinput.c\t/^  INDX_IM1,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_IM2\tinput.c\t/^  INDX_IM2,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_L\tinput.c\t/^  INDX_L,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_L2\tinput.c\t/^  INDX_L2,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_M\tinput.c\t/^  INDX_M,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_NIL\tinput.c\t/^  INDX_NIL =   0x00,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_P\tinput.c\t/^  INDX_P,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_R\tinput.c\t/^  INDX_R,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_R2\tinput.c\t/^  INDX_R2,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_S\tinput.c\t/^  INDX_S,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_S1\tinput.c\t/^  INDX_S1,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_S2\tinput.c\t/^  INDX_S2,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_S3\tinput.c\t/^  INDX_S3,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_S4\tinput.c\t/^  INDX_S4,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_T\tinput.c\t/^  INDX_T,$/;\"\te\tenum:__anone0aee1a10103\tfile:\nINDX_T2\tinput.c\t/^  INDX_T2,$/;\"\te\tenum:__anone0aee1a10103\tfile:\n__anone0aee1a10103\tinput.c\t/^typedef enum{$/;\"\tg\tfile:\ntask_indx_type\tinput.c\t/^} task_indx_type;$/;\"\tt\ttyperef:enum:__anone0aee1a10103\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/bug556646.c.d/input.c",
    "content": "/*\nBugs item #556646, was opened at 2002-05-16 14:36\nYou can respond by visiting: \nhttp://sourceforge.net/tracker/?func=detail&atid=106556&aid=556646&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Howard Wu (howardhbwu)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: Some typedef can not be tagged in C code\n\nInitial Comment:\nMy Ctags version: 5.2.3\n*/\ntypedef enum{\n  INDX_NIL =   0x00,\n  INDX_P,\n  INDX_S,\n  INDX_M,\n  INDX_S1,\n  INDX_S2,\n  INDX_S3,\n  INDX_C1,\n  INDX_C2,\n  INDX_S4,\n  INDX_T,\n  INDX_L,\n  INDX_R,\n  INDX_R2,\n  INDX_IM1,\n  INDX_IM2,\n  INDX_L2,\n  INDX_T2,\n  A = INDX_T2\n} task_indx_type;\n\n/*\n\"task_indx_type\" can not be tagged with Ctags\n*/\n"
  },
  {
    "path": "Units/parser-c.r/bug945.c.d/args.ctags",
    "content": "-I __read_mostly\n\n"
  },
  {
    "path": "Units/parser-c.r/bug945.c.d/expected.tags",
    "content": "edsa_packet_type\tinput.c\t/^struct packet_type edsa_packet_type __read_mostly = {$/;\"\tv\ttyperef:struct:packet_type\n"
  },
  {
    "path": "Units/parser-c.r/bug945.c.d/input.c",
    "content": "/*\n  Bug 945@github reported by masatake on 21/05/2016.\n  The code below was treated as a struct declaration instead\n  of variable declaration.\n*/\n\n/* Taken from linux-3.10.0-229.fc21.x86_64/net/dsa/tag_edsa.c */\nstruct packet_type edsa_packet_type __read_mostly = {\n\t.type\t= cpu_to_be16(ETH_P_EDSA),\n\t.func\t= edsa_rcv,\n};\n"
  },
  {
    "path": "Units/parser-c.r/bug950.c.d/args.ctags",
    "content": "--kinds-c=p\n--fields=+tS\n"
  },
  {
    "path": "Units/parser-c.r/bug950.c.d/expected.tags",
    "content": "IdentifyImageMonochrome\tinput.c\t/^  IdentifyImageMonochrome(const Image *,ExceptionInfo *),$/;\"\tp\ttyperef:typename:MagickExport MagickBooleanType\tfile:\tsignature:(const Image *,ExceptionInfo *)\nIsGrayImage\tinput.c\t/^  IsGrayImage(const Image *,ExceptionInfo *),$/;\"\tp\ttyperef:typename:MagickExport MagickBooleanType\tfile:\tsignature:(const Image *,ExceptionInfo *)\nIsMonochromeImage\tinput.c\t/^  IsMonochromeImage(const Image *,ExceptionInfo *),$/;\"\tp\ttyperef:typename:MagickExport MagickBooleanType\tfile:\tsignature:(const Image *,ExceptionInfo *)\nIsOpaqueImage\tinput.c\t/^  IsOpaqueImage(const Image *,ExceptionInfo *),$/;\"\tp\ttyperef:typename:MagickExport MagickBooleanType\tfile:\tsignature:(const Image *,ExceptionInfo *)\nSetImageChannelDepth\tinput.c\t/^  SetImageChannelDepth(Image *,const ChannelType,const size_t),$/;\"\tp\ttyperef:typename:MagickExport MagickBooleanType\tfile:\tsignature:(Image *,const ChannelType,const size_t)\nSetImageDepth\tinput.c\t/^  SetImageDepth(Image *,const size_t),$/;\"\tp\ttyperef:typename:MagickExport MagickBooleanType\tfile:\tsignature:(Image *,const size_t)\nSetImageType\tinput.c\t/^  SetImageType(Image *,const ImageType);$/;\"\tp\ttyperef:typename:MagickExport MagickBooleanType\tfile:\tsignature:(Image *,const ImageType)\n"
  },
  {
    "path": "Units/parser-c.r/bug950.c.d/input.c",
    "content": "/*\n Bug 931@github reported by lvc on 24/05/2016.\n \n The latest version (9320ecf) of the universal ctags failed to recognize\n SetImageChannelDepth symbol in the ImageMagick library header file\n (include/ImageMagick-6/magick/attribute.h, v6.9.4-4):\n \n In fact only the last function prototype was extracted and everything\n else was treated as a giant return type.\n*/\n\nextern MagickExport MagickBooleanType\n  IdentifyImageMonochrome(const Image *,ExceptionInfo *),\n  IsGrayImage(const Image *,ExceptionInfo *),\n  IsMonochromeImage(const Image *,ExceptionInfo *),\n  IsOpaqueImage(const Image *,ExceptionInfo *),\n  SetImageChannelDepth(Image *,const ChannelType,const size_t),\n  SetImageDepth(Image *,const size_t),\n  SetImageType(Image *,const ImageType);\n  "
  },
  {
    "path": "Units/parser-c.r/c-define-mixed.d/args.ctags",
    "content": "--excmd=mixed\n--fields=+n\n"
  },
  {
    "path": "Units/parser-c.r/c-define-mixed.d/expected.tags",
    "content": "X\tinput.c\t/^#define X /;\"\td\tline:1\tfile:\nY\tinput.c\t/^#define Y(/;\"\td\tline:6\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/c-define-mixed.d/input.c",
    "content": "#define X 1\n/* 2 */\n/* 3 */\n/* 4 */\n/* 5 */\n#define Y(v) (6 + v)\n/* 7 */\n"
  },
  {
    "path": "Units/parser-c.r/c-digraphs.d/expected.tags",
    "content": "A\tinput.c\t/^%:define A /;\"\td\tfile:\nB\tinput.c\t/^%:define B /;\"\td\tfile:\nM3_INIT\tinput.c\t/^%:define M3_INIT(/;\"\td\tfile:\nSTRINGIFY\tinput.c\t/^%:define STRINGIFY(x) STRINGIFY_/;\"\td\tfile:\nSTRINGIFY_INTERN\tinput.c\t/^%:define STRINGIFY_INTERN(/;\"\td\tfile:\nbuf\tinput.c\t/^  char *buf;$/;\"\tm\tstruct:str\ttyperef:typename:char *\tfile:\nlen\tinput.c\t/^  unsigned int len, size;$/;\"\tm\tstruct:str\ttyperef:typename:unsigned int\tfile:\nmain\tinput.c\t/^int main(void)$/;\"\tf\ttyperef:typename:int\nmatrix3\tinput.c\t/^typedef int matrix3<:3:>;$/;\"\tt\ttyperef:typename:int[3]\tfile:\nsize\tinput.c\t/^  unsigned int len, size;$/;\"\tm\tstruct:str\ttyperef:typename:unsigned int\tfile:\nstr\tinput.c\t/^struct str <%$/;\"\ts\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/c-digraphs.d/input.c",
    "content": "\n/* simple trigraphs */\n%:define A 1\n%:define B 2\n%:define STRINGIFY_INTERN(x) %:x\n%:define STRINGIFY(x) STRINGIFY_INTERN(x)\n\n%:define M3_INIT(a, b, c) <% a, b, c %>\ntypedef int matrix3<:3:>;\n\nstruct str <%\n  char *buf;\n  unsigned int len, size;\n%>;\n\nint main(void)\n<%\n  const char *hello = STRINGIFY(hello);\n  matrix3 m = M3_INIT(1, 2, 3);\n\n  return m<:2:>;\n%>\n\n%:if 0\n#define bug4\n%:endif\n\n\n/* test the same with untaken preprocessor paths (as they are then not read by\n * the C parser but get.c) */\n#if 0\n%:define if0d_A 1\n%:define if0d_B 2\n#endif\n\n"
  },
  {
    "path": "Units/parser-c.r/c-include.d/args.ctags",
    "content": "--kinds-c=+h\n--fields=+r\n--extras=+r\n"
  },
  {
    "path": "Units/parser-c.r/c-include.d/expected.tags",
    "content": "../e.h\tinput.c\t/^#include <..\\/e.h>/;\"\th\troles:system\n../f.h\tinput.c\t/^#include \"..\\/f.h\"/;\"\th\troles:local\nD\tinput.c\t/^#define D /;\"\td\tfile:\troles:def\na.h\tinput.c\t/^#include <a.h>/;\"\th\troles:system\nb.h\tinput.c\t/^#include \"b.h\"/;\"\th\troles:local\ng.h\tinput.c\t/^#include<g.h>/;\"\th\troles:system\nh.h\tinput.c\t/^#include\"h.h\"/;\"\th\troles:local\ni.h\tinput.c\t/^#include       <i.h>/;\"\th\troles:system\nj.h\tinput.c\t/^#include       \"j.h\"/;\"\th\troles:local\nstdio.h\tinput.c\t/^   #    \tinclude <stdio.h>/;\"\th\troles:system\nsys/c.h\tinput.c\t/^#include <sys\\/c.h>/;\"\th\troles:system\nsys/d.h\tinput.c\t/^#include \"sys\\/d.h\"/;\"\th\troles:local\n"
  },
  {
    "path": "Units/parser-c.r/c-include.d/input.c",
    "content": "#include <a.h>\n#include \"b.h\"\n\n#include <sys/c.h>\n#include \"sys/d.h\"\n\n/* this is actually a syntax error */\n\"\n#include       <K.h>\n#include       \\\"L.h\\\"\n\"\n\n#include <../e.h>\n#include \"../f.h\"\n\nint\nM(void)\n{\n  return 0;\n}\n\n#define D 1\n\n#include<g.h>\n#include\"h.h\"\n\n#include       <i.h>\n#include       \"j.h\"\n\n   #    \tinclude <stdio.h>\n/* objc constant String */\n@\"#include<y.h>\"\n"
  },
  {
    "path": "Units/parser-c.r/c-keyword-alignas.d/args.ctags",
    "content": "--sort=no\n--kinds-C=+l\n"
  },
  {
    "path": "Units/parser-c.r/c-keyword-alignas.d/expected.tags",
    "content": "sse_t\tinput.c\t/^struct sse_t$/;\"\ts\tfile:\nsse_data\tinput.c\t/^    alignas(16) float sse_data[4];$/;\"\tm\tstruct:sse_t\ttyperef:typename:float[4]\tfile:\nsse_data_\tinput.c\t/^    _Alignas(16) float sse_data_[4];$/;\"\tm\tstruct:sse_t\ttyperef:typename:float[4]\tfile:\ndata\tinput.c\t/^struct data$/;\"\ts\tfile:\nx\tinput.c\t/^    char x;$/;\"\tm\tstruct:data\ttyperef:typename:char\tfile:\ncacheline\tinput.c\t/^    alignas(128) char cacheline[128]; \\/\\/ over-aligned array of char,$/;\"\tm\tstruct:data\ttyperef:typename:char[128]\tfile:\ncacheline_\tinput.c\t/^    _Alignas(128) char cacheline_[128];$/;\"\tm\tstruct:data\ttyperef:typename:char[128]\tfile:\nmain\tinput.c\t/^int main(void)$/;\"\tf\ttyperef:typename:int\nd\tinput.c\t/^    alignas(2048) struct data d; \\/\\/ this instance of data is aligned even stricter$/;\"\tl\tfunction:main\ttyperef:struct:data\tfile:\nd_\tinput.c\t/^    _Alignas(2048) struct data d_;$/;\"\tl\tfunction:main\ttyperef:struct:data\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/c-keyword-alignas.d/input.c",
    "content": "/* Taken from https://en.cppreference.com/w/c/language/_Alignas */\n#include <stdalign.h>\n#include <stdio.h>\n\n// every object of type struct sse_t will be aligned to 16-byte boundary\n// (note: needs support for DR 444)\nstruct sse_t\n{\n    alignas(16) float sse_data[4];\n    _Alignas(16) float sse_data_[4];\n};\n\n// every object of type struct data will be aligned to 128-byte boundary\nstruct data\n{\n    char x;\n    alignas(128) char cacheline[128]; // over-aligned array of char,\n                                      // not array of over-aligned chars\n    _Alignas(128) char cacheline_[128];\n\n};\n\nint main(void)\n{\n    printf(\"sizeof(data) = %zu (1 byte + 127 bytes padding + 128-byte array)\\n\",\n           sizeof(struct data));\n\n    printf(\"alignment of sse_t is %zu\\n\", alignof(struct sse_t));\n\n    alignas(2048) struct data d; // this instance of data is aligned even stricter\n    _Alignas(2048) struct data d_;\n    (void)d; // suppresses \"maybe unused\" warning\n}\n"
  },
  {
    "path": "Units/parser-c.r/c-knr.d/args.ctags",
    "content": "--kinds-c=fz\n\n"
  },
  {
    "path": "Units/parser-c.r/c-knr.d/expected.tags",
    "content": "f01\tinput.c\t/^int f01()$/;\"\tf\ttyperef:typename:int\nf02\tinput.c\t/^int f02(f02a01,f02a02)$/;\"\tf\nf02a01\tinput.c\t/^  int f02a01;$/;\"\tz\tfunction:f02\ttyperef:typename:int\tfile:\nf02a02\tinput.c\t/^  int f02a02;$/;\"\tz\tfunction:f02\ttyperef:typename:int\tfile:\nf03\tinput.c\t/^int f03(void)$/;\"\tf\ttyperef:typename:int\nf04\tinput.c\t/^int f04(...)$/;\"\tf\ttyperef:typename:int\nf05\tinput.c\t/^int f05($/;\"\tf\nf05a01\tinput.c\t/^\tunsigned short f05a01;$/;\"\tz\tfunction:f05\ttyperef:typename:unsigned short\tfile:\nf05a02\tinput.c\t/^\tint * f05a02;$/;\"\tz\tfunction:f05\ttyperef:typename:int *\tfile:\nf06\tinput.c\t/^int f06(f06a01,f06a02)$/;\"\tf\nf06a01\tinput.c\t/^\tunsigned short int f06a01, ** f06a02;$/;\"\tz\tfunction:f06\ttyperef:typename:unsigned short int\tfile:\nf06a02\tinput.c\t/^\tunsigned short int f06a01, ** f06a02;$/;\"\tz\tfunction:f06\ttyperef:typename:unsigned short int **\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/c-knr.d/input.c",
    "content": "int f01()\n{\n\treturn 0;\n}\n\nint f02(f02a01,f02a02)\n  int f02a01;\n  int f02a02;\n{\n\treturn f02a01 + f02a02;\n}\n\nint f03(void)\n{\n\treturn 0;\n}\n\nint f04(...)\n{\n\treturn 0;\n}\n\nint f05(\n\t\tf05a01,\n\t\tf05a02,\n\t\t...\n\t)\n\tunsigned short f05a01;\n\tint * f05a02;\n{\n\treturn 0;\n}\n\nint f06(f06a01,f06a02)\n\tunsigned short int f06a01, ** f06a02;\n{\n\treturn 0;\n}\n\n"
  },
  {
    "path": "Units/parser-c.r/c-label.d/args.ctags",
    "content": "--kinds-c=+L\n"
  },
  {
    "path": "Units/parser-c.r/c-label.d/expected.tags",
    "content": "main\tinput.c\t/^main(int argc)$/;\"\tf\ttyperef:typename:int\nout\tinput.c\t/^   out:$/;\"\tL\tfunction:main\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/c-label.d/input.c",
    "content": "int\nmain(int argc)\n{\n  goto out;\n  switch (argc)\n    {\n    case 1:\n      break;\n    case A|B:\n      break;\n    default:\n      break;\n    }\n   out:\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-c.r/c-multichars-between-single-quotes.d/expected.tags",
    "content": "c\tinput.c\t/^char c[]={'o.'};$/;\"\tv\ttyperef:typename:char[]\n"
  },
  {
    "path": "Units/parser-c.r/c-multichars-between-single-quotes.d/input.c",
    "content": "char c[]={'o.'};\n"
  },
  {
    "path": "Units/parser-c.r/c-sample.d/expected.tags",
    "content": "main\tinput.c\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-c.r/c-sample.d/input.c",
    "content": "int\nmain(void)\n{\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-c.r/c-size_t-wchar_t-typedef.d/expected.tags",
    "content": "size_t\tinput.c\t/^typedef int size_t;$/;\"\tt\ttyperef:typename:int\tfile:\nwchar_t\tinput.c\t/^typedef int wchar_t;$/;\"\tt\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/c-size_t-wchar_t-typedef.d/input.c",
    "content": "\ntypedef int size_t;\ntypedef int wchar_t;\n"
  },
  {
    "path": "Units/parser-c.r/c-struct-var-with-initializer.d/args.ctags",
    "content": "--sort=no\n--kinds-c=+lz\n--fields=+K\n"
  },
  {
    "path": "Units/parser-c.r/c-struct-var-with-initializer.d/expected.tags",
    "content": "__anon61565e570108\tinput.c\t/^struct {$/;\"\tstruct\tfile:\na\tinput.c\t/^  int a;$/;\"\tmember\tstruct:__anon61565e570108\ttyperef:typename:int\tfile:\nb\tinput.c\t/^} b = { 1 };$/;\"\tvariable\ttyperef:struct:__anon61565e570108\nc\tinput.c\t/^int c;$/;\"\tvariable\ttyperef:typename:int\nd\tinput.c\t/^int d(int e) {$/;\"\tfunction\ttyperef:typename:int\ne\tinput.c\t/^int d(int e) {$/;\"\tparameter\tfunction:d\ttyperef:typename:int\tfile:\n__anon61565e570208\tinput.c\t/^  struct {$/;\"\tstruct\tfunction:d\tfile:\nf\tinput.c\t/^    int f;$/;\"\tmember\tstruct:d::__anon61565e570208\ttyperef:typename:int\tfile:\ng\tinput.c\t/^  } g = { 1 };$/;\"\tlocal\tfunction:d\ttyperef:struct:d::__anon61565e570208\tfile:\nh\tinput.c\t/^  int h;$/;\"\tlocal\tfunction:d\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/c-struct-var-with-initializer.d/input.c",
    "content": "/* Derived from an issue (#1311) opened by BodoStroesser */\n\nstruct {\n  int a;\n} b = { 1 };\n\nint c;\n\nint d(int e) {\n  struct {\n    int f;\n  } g = { 1 };\n  int h;\n  g = (typeof(g)){ 2 };\n}\n"
  },
  {
    "path": "Units/parser-c.r/c-trigraphs.d/expected.tags",
    "content": "A\tinput.c\t/^??=define A /;\"\td\tfile:\nB\tinput.c\t/^??=define B /;\"\td\tfile:\nD\tinput.c\t/^??=define D /;\"\td\tfile:\nE\tinput.c\t/^??=define E /;\"\td\tfile:\nF\tinput.c\t/^??=define F /;\"\td\tfile:\nM3_INIT\tinput.c\t/^??=define M3_INIT(/;\"\td\tfile:\nSTRINGIFY\tinput.c\t/^??=define STRINGIFY(x) STRINGIFY_/;\"\td\tfile:\nSTRINGIFY_INTERN\tinput.c\t/^??=define STRINGIFY_INTERN(/;\"\td\tfile:\nbuf\tinput.c\t/^  char *buf;$/;\"\tm\tstruct:str\ttyperef:typename:char *\tfile:\nlen\tinput.c\t/^  unsigned int len, size;$/;\"\tm\tstruct:str\ttyperef:typename:unsigned int\tfile:\nmain\tinput.c\t/^int main(void)$/;\"\tf\ttyperef:typename:int\nmatrix3\tinput.c\t/^typedef int matrix3??(3??);$/;\"\tt\ttyperef:typename:int[3]\tfile:\nsize\tinput.c\t/^  unsigned int len, size;$/;\"\tm\tstruct:str\ttyperef:typename:unsigned int\tfile:\nstr\tinput.c\t/^struct str ??<$/;\"\ts\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/c-trigraphs.d/input.c",
    "content": "\n/* simple trigraphs */\n??=define A 1\n??=define B 2\n??=define STRINGIFY_INTERN(x) ??=x\n??=define STRINGIFY(x) STRINGIFY_INTERN(x)\n\n/* doesn't expand to anything that makes sense, but as \"???\" is not a valid\n * trigraph it should not prevent \"??/\" to match */\n??=define D 4 ???/\n#define bug1\n??=define E ?????/\n#define bug2\n\n/* \\ isn't interpreted for trigraphs */\n??=define F ???\\??/\nextern int bug3 = ??-0;\n\n??=define M3_INIT(a, b, c) ??< a, b, c ??>\ntypedef int matrix3??(3??);\n\nstruct str ??<\n  char *buf;\n  unsigned int len, size;\n??>;\n\nint main(void)\n??<\n  const char *hello = STRINGIFY(hello);\n  matrix3 m = M3_INIT(1, 2, 3);\n\n  return m??(2??);\n??>\n\n/* FIXME: how to test \"??'\" (\"^\"), \"??!\" (\"|\") and \"??-\" (\"~\")?\n *        I can't think of a construct CTags cares about using those */\n\n??=if 0\n#define bug4\n??=endif\n\n\n/* test the same with untaken preprocessor paths (as they are then not read by\n * the C parser but get.c) */\n#if 0\n\n??=define if0d_A 1\n??=define if0d_B 2\n??=define if0d_C 4 ???/\n#define bug5\n??=define I ?????/\n#define bug6\n??=define I ??????????/\n#define bug7\n\n#endif\n"
  },
  {
    "path": "Units/parser-c.r/c-var-initialized-using-macro.d/args.ctags",
    "content": "--sort=no\n--kinds-C=+lp\n"
  },
  {
    "path": "Units/parser-c.r/c-var-initialized-using-macro.d/expected.tags",
    "content": "INIT\tinput.c\t/^#define INIT(/;\"\td\tfile:\ni\tinput.c\t/^static const int i = INIT(2);$/;\"\tv\ttyperef:typename:const int\tfile:\nj\tinput.c\t/^int j;$/;\"\tv\ttyperef:typename:int\nk\tinput.c\t/^int k = 1;$/;\"\tv\ttyperef:typename:int\nf\tinput.c\t/^int f(void)$/;\"\tf\ttyperef:typename:int\nl\tinput.c\t/^\tint l = INIT(3);$/;\"\tl\tfunction:f\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/c-var-initialized-using-macro.d/input.c",
    "content": "#define INIT(x) x\n\nstatic const int i = INIT(2);\nint j;\nint k = 1;\n\nint f(void)\n{\n\tint l = INIT(3);\n\treturn l + k + j + i;\n}\n"
  },
  {
    "path": "Units/parser-c.r/complex_decl.c.d/expected.tags",
    "content": "ScanAction\tinput.c\t/^static void (* const(ScanAction[5][5]))(void *)= {};$/;\"\tv\ttyperef:typename:void (* const ([5][5]))(void *)\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/complex_decl.c.d/input.c",
    "content": "/* Complex declarations */\nstatic void (* const(ScanAction[5][5]))(void *)= {};\n"
  },
  {
    "path": "Units/parser-c.r/cxx-keywords-simple.d/args.ctags",
    "content": "--sort=no\n--kinds-C=+p\n--fields=+K\n"
  },
  {
    "path": "Units/parser-c.r/cxx-keywords-simple.d/expected.tags",
    "content": "private\tinput.h\t/^struct private {int x;} v24;$/;\"\tstruct\nx\tinput.h\t/^struct private {int x;} v24;$/;\"\tmember\tstruct:private\ttyperef:typename:int\nv24\tinput.h\t/^struct private {int x;} v24;$/;\"\tvariable\ttyperef:struct:private\nprotected\tinput.h\t/^struct protected {int x;} v25;$/;\"\tstruct\nx\tinput.h\t/^struct protected {int x;} v25;$/;\"\tmember\tstruct:protected\ttyperef:typename:int\nv25\tinput.h\t/^struct protected {int x;} v25;$/;\"\tvariable\ttyperef:struct:protected\npublic\tinput.h\t/^struct public {int x;} v26;$/;\"\tstruct\nx\tinput.h\t/^struct public {int x;} v26;$/;\"\tmember\tstruct:public\ttyperef:typename:int\nv26\tinput.h\t/^struct public {int x;} v26;$/;\"\tvariable\ttyperef:struct:public\ns24\tinput.h\t/^struct s24 {int private;} ;$/;\"\tstruct\nprivate\tinput.h\t/^struct s24 {int private;} ;$/;\"\tmember\tstruct:s24\ttyperef:typename:int\ns25\tinput.h\t/^struct s25 {int protected;} ;$/;\"\tstruct\nprotected\tinput.h\t/^struct s25 {int protected;} ;$/;\"\tmember\tstruct:s25\ttyperef:typename:int\ns26\tinput.h\t/^struct s26 {int public;} ;$/;\"\tstruct\npublic\tinput.h\t/^struct s26 {int public;} ;$/;\"\tmember\tstruct:s26\ttyperef:typename:int\nprivate\tinput.h\t/^typedef int private; \\/* 24 *\\/$/;\"\ttypedef\ttyperef:typename:int\nprotected\tinput.h\t/^typedef int protected; \\/* 25 *\\/$/;\"\ttypedef\ttyperef:typename:int\npublic\tinput.h\t/^typedef int public; \\/* 26 *\\/$/;\"\ttypedef\ttyperef:typename:int\nv24\tinput.h\t/^int v24, private;$/;\"\tvariable\ttyperef:typename:int\nprivate\tinput.h\t/^int v24, private;$/;\"\tvariable\ttyperef:typename:int\nv25\tinput.h\t/^int v25, protected;$/;\"\tvariable\ttyperef:typename:int\nprotected\tinput.h\t/^int v25, protected;$/;\"\tvariable\ttyperef:typename:int\nv26\tinput.h\t/^int v26, public;$/;\"\tvariable\ttyperef:typename:int\npublic\tinput.h\t/^int v26, public;$/;\"\tvariable\ttyperef:typename:int\nprivate\tinput.h\t/^int private (int a24);$/;\"\tprototype\ttyperef:typename:int\nprotected\tinput.h\t/^int protected (int a25);$/;\"\tprototype\ttyperef:typename:int\npublic\tinput.h\t/^int public (int a26);$/;\"\tprototype\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-c.r/cxx-keywords-simple.d/input.h",
    "content": "struct private {int x;} v24;\nstruct protected {int x;} v25;\nstruct public {int x;} v26;\nstruct s24 {int private;} ;\nstruct s25 {int protected;} ;\nstruct s26 {int public;} ;\ntypedef int private; /* 24 */\ntypedef int protected; /* 25 */\ntypedef int public; /* 26 */\nint v24, private;\nint v25, protected;\nint v26, public;\nint private (int a24);\nint protected (int a25);\nint public (int a26);\n"
  },
  {
    "path": "Units/parser-c.r/cxx-scope-keywords.d/args.ctags",
    "content": "--sort=no\n--kinds-C=+L\n--fields=+K\n"
  },
  {
    "path": "Units/parser-c.r/cxx-scope-keywords.d/expected.tags",
    "content": "data0\tinput.h\t/^struct data0 {$/;\"\tstruct\nprivate\tinput.h\t/^\tvoid *private;$/;\"\tmember\tstruct:data0\ttyperef:typename:void *\npublic\tinput.h\t/^\tvoid *public;$/;\"\tmember\tstruct:data0\ttyperef:typename:void *\nprotected\tinput.h\t/^\tvoid *protected;$/;\"\tmember\tstruct:data0\ttyperef:typename:void *\ndata1\tinput.h\t/^struct data1 {$/;\"\tstruct\nprivate\tinput.h\t/^\tvoid *private\\/* comment *\\/;$/;\"\tmember\tstruct:data1\ttyperef:typename:void *\npublic\tinput.h\t/^\tvoid *public\\/* comment$/;\"\tmember\tstruct:data1\ttyperef:typename:void *\nprotected\tinput.h\t/^\tvoid *protected \\/* comment$/;\"\tmember\tstruct:data1\ttyperef:typename:void *\ndata2\tinput.h\t/^struct data2 {$/;\"\tstruct\nprivate\tinput.h\t/^\tvoid *private ;$/;\"\tmember\tstruct:data2\ttyperef:typename:void *\npublic\tinput.h\t/^\tint   public:1 ;$/;\"\tmember\tstruct:data2\ttyperef:typename:int:1\nprotected\tinput.h\t/^\tvoid *protected __attribute__ ((aligned (8)))  ;$/;\"\tmember\tstruct:data2\ttyperef:typename:void *\nfoo\tinput.h\t/^void foo(void) {$/;\"\tfunction\ttyperef:typename:void\nprivate\tinput.h\t/^private:$/;\"\tlabel\tfunction:foo\tfile:\nbar\tinput.h\t/^void bar(void) {$/;\"\tfunction\ttyperef:typename:void\nprivate\tinput.h\t/^private :$/;\"\tlabel\tfunction:bar\tfile:\nbaz\tinput.h\t/^void baz(void) {$/;\"\tfunction\ttyperef:typename:void\nprivate\tinput.h\t/^ private\\/* coment *\\/:$/;\"\tlabel\tfunction:baz\tfile:\nprivate\tinput.h\t/^int private;$/;\"\tvariable\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-c.r/cxx-scope-keywords.d/input.h",
    "content": "struct data0 {\n\tvoid *private;\n\tvoid *public;\n\tvoid *protected;\n};\n\nstruct data1 {\n\tvoid *private/* comment */;\n\tvoid *public/* comment\n\t\t\t\t */ ;\n\tvoid *protected /* comment\n\t\t\t\t\t */;\n};\n\nstruct data2 {\n\tvoid *private ;\n\tint   public:1 ;\n\tvoid *protected __attribute__ ((aligned (8)))  ;\n};\n\nvoid foo(void) {\n  goto private;\nprivate:\n  return;\n}\n\nvoid bar(void) {\n  goto private ;\nprivate :\n  return;\n}\n\nvoid baz(void) {\n\tgoto private/* comment */;\n private/* coment */:\n  return;\n}\n\nint private;\n"
  },
  {
    "path": "Units/parser-c.r/directives-2.c.d/args.ctags",
    "content": "--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-c.r/directives-2.c.d/expected.tags",
    "content": "func\tinput.c\t/^int func()$/;\"\tf\ttyperef:typename:int\troles:def\nmain\tinput.c\t/^int main()$/;\"\tf\ttyperef:typename:int\troles:def\n"
  },
  {
    "path": "Units/parser-c.r/directives-2.c.d/input.c",
    "content": "int main()\n{\n        if (something) {\n                printf(\"hello\");\n#ifdef world\n        } else\n                printf(\" world\\n\");\n#else\n        }\n#endif\n}\n\nint func()\n{\n}\n"
  },
  {
    "path": "Units/parser-c.r/directives.c.d/README",
    "content": "About the expected output, see #379.\n"
  },
  {
    "path": "Units/parser-c.r/directives.c.d/args.ctags",
    "content": "--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-c.r/directives.c.d/expected.tags",
    "content": "FUNCTION_LIKE\tinput.c\t/^#define FUNCTION_LIKE(/;\"\td\tfile:\troles:def\nMACRO_TO_SEE1\tinput.c\t/^# define MACRO_TO_SEE1 /;\"\td\tfile:\troles:def\nMACRO_TO_SEE1\tinput.c\t/^#undef MACRO_TO_SEE1$/;\"\td\tfile:\troles:undef\nMACRO_TO_SEE2\tinput.c\t/^# define MACRO_TO_SEE2 /;\"\td\tfile:\troles:def\nMACRO_TO_SEE3\tinput.c\t/^# define MACRO_TO_SEE3 /;\"\td\tfile:\troles:def\nMACRO_TO_SEE4\tinput.c\t/^# define MACRO_TO_SEE4 /;\"\td\tfile:\troles:def\nPATH1\tinput.c\t/^#define PATH1$/;\"\td\tfile:\troles:def\nPATH1b\tinput.c\t/^#define PATH1b$/;\"\td\tfile:\troles:def\nSEE_THIS_MACRO\tinput.c\t/^# define SEE_THIS_MACRO /;\"\td\tfile:\troles:def\nVARIABLE_LIKE\tinput.c\t/^#define VARIABLE_LIKE\t/;\"\td\tfile:\troles:def\nWeakSymbol\tinput.c\t/^#pragma weak WeakSymbol /;\"\td\tfile:\troles:def\na\tinput.c\t/^int a;$/;\"\tv\ttyperef:typename:int\troles:def\nb\tinput.c\t/^int b;$/;\"\tv\ttyperef:typename:int\troles:def\nbar1\tinput.c\t/^int bar1 (void)$/;\"\tf\ttyperef:typename:int\troles:def\nc\tinput.c\t/^int c;$/;\"\tv\ttyperef:typename:int\troles:def\nd\tinput.c\t/^int d;$/;\"\tv\ttyperef:typename:int\troles:def\nfoo1\tinput.c\t/^int foo1 (void)$/;\"\tf\ttyperef:typename:int\troles:def\ng\tinput.c\t/^int g;$/;\"\tv\ttyperef:typename:int\troles:def\np1\tinput.c\t/^int p1;$/;\"\tv\ttyperef:typename:int\troles:def\nwith_long_comment\tinput.c\t/^#define with_long_comment /;\"\td\tfile:\troles:def\nz_this_branch_is_chosen\tinput.c\t/^#define  z_this_branch_is_chosen /;\"\td\tfile:\troles:def\n"
  },
  {
    "path": "Units/parser-c.r/directives.c.d/input.c",
    "content": "/* Test simple cases */\n#define VARIABLE_LIKE\tsome_value\n#define FUNCTION_LIKE(a,b)  (a + b)\n#pragma weak WeakSymbol = StrongSymbol\n\n#define with_long_comment  /* line 1\n\t\t\t      line 2 */\n\n/* Test usual case */\n#ifdef MY_MACRO\n# define MACRO_TO_SEE1 1\nint a;\n#elif YOUR_MACRO\n# define MACRO_TO_SEE2 2\nint b;\n#elif defined (THEIR_MACRO)\n# define MACRO_TO_SEE3 3\nint c;\n#else\n# define MACRO_TO_SEE4 4\nint d;\n#endif\n\n/* Test commented-out case */\n#if 0\n#define IGNORE_MACRO\nint e;\n# if 0\n#  define ANOTHER_IGNORE_MACRO\nint f;\n# else\n#  define YAIM\n# endif\n#else\n# define SEE_THIS_MACRO 1\nint g;\n#endif\n\n/* Test path selection algorithm */\n#ifdef OK\n#define PATH1\nint foo1 (void)\n{\n#define  z_this_branch_is_chosen 0\n#elif defined (OK)\n#define PATH2\nint foo2 (void)\n{\n#else\n#define PATH3\nint foo3 (void)\n{\n#endif\n}\n\nint bar1 (void)\n{\n#ifdef OK\n#define PATH1b\n}\nint p1;\n#elif defined (OK)\n#define PATH2b\n}\nint p2;\n#else\n#define PATH3b\n}\nint p3;\n#endif\n#undef MACRO_TO_SEE1\n\n"
  },
  {
    "path": "Units/parser-c.r/end-field-of-macro.d/args.ctags",
    "content": "--fields-all=+{end}\n--fields=+{line}\n"
  },
  {
    "path": "Units/parser-c.r/end-field-of-macro.d/expected.tags",
    "content": "F\tinput.c\t/^#define F(/;\"\td\tline:1\tfile:\tend:1\nG\tinput.c\t/^#define G$/;\"\td\tline:2\tfile:\tend:2\nZ\tinput.c\t/^#define Z(/;\"\td\tline:4\tfile:\tend:8\n"
  },
  {
    "path": "Units/parser-c.r/end-field-of-macro.d/input.c",
    "content": "#define F(X) X\n#define G\n#include <S.h>\n#define Z(Y)\t\t\t\t\t\\\nint main (void)\t\t\t\t\t\\\n{\t\t\t\t\t\t\\\n  return 0;\t\t\t\t\t\\\n}\n"
  },
  {
    "path": "Units/parser-c.r/end-field-of-var.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-c.r/end-field-of-var.d/expected.tags",
    "content": "n\tinput.c\t/^int n [2] = {$/;\"\tv\tline:1\ttyperef:typename:int[2]\tend:4\nm0\tinput.c\t/^int m0 [2] = {$/;\"\tv\tline:7\ttyperef:typename:int[2]\tend:10\nm1\tinput.c\t/^}, m1 [3] = {$/;\"\tv\tline:10\ttyperef:typename:int[3]\tend:14\npoint\tinput.c\t/^struct point {$/;\"\ts\tline:16\tfile:\tend:18\nx\tinput.c\t/^\tint x, y;$/;\"\tm\tline:17\tstruct:point\ttyperef:typename:int\tfile:\tend:17\ny\tinput.c\t/^\tint x, y;$/;\"\tm\tline:17\tstruct:point\ttyperef:typename:int\tfile:\tend:17\nP\tinput.c\t/^struct point P = {$/;\"\tv\tline:20\ttyperef:struct:point\tend:23\n"
  },
  {
    "path": "Units/parser-c.r/end-field-of-var.d/input.c",
    "content": "int n [2] = {\n\t1,\n\t2,\n};\n\n\nint m0 [2] = {\n\t3,\n\t4,\n}, m1 [3] = {\n\t5,\n\t6,\n\t8,\n};\n\nstruct point {\n\tint x, y;\n};\n\nstruct point P = {\n\t.x = 1,\n\t.y = 2,\n};\n"
  },
  {
    "path": "Units/parser-c.r/enum-bit-fields.d/args.ctags",
    "content": "--sort=no\n--fields-C=+{macrodef}\n--param-CPreProcessor._expand=1\n--fields=+{signature}\n"
  },
  {
    "path": "Units/parser-c.r/enum-bit-fields.d/expected.tags",
    "content": "s0\tinput.c\t/^struct s0 {$/;\"\ts\tfile:\n__anon4724ae570103\tinput.c\t/^\tenum {ID0} e0:1;$/;\"\tg\tstruct:s0\tfile:\nID0\tinput.c\t/^\tenum {ID0} e0:1;$/;\"\te\tenum:s0::__anon4724ae570103\tfile:\ne0\tinput.c\t/^\tenum {ID0} e0:1;$/;\"\tm\tstruct:s0\ttyperef:enum:s0::__anon4724ae570103:1\tfile:\nx0\tinput.c\t/^\tint x0;$/;\"\tm\tstruct:s0\ttyperef:typename:int\tfile:\nE1\tinput.c\t/^enum E1 {ID1};$/;\"\tg\tfile:\nID1\tinput.c\t/^enum E1 {ID1};$/;\"\te\tenum:E1\tfile:\ns1\tinput.c\t/^struct s1 {$/;\"\ts\tfile:\ne1\tinput.c\t/^\tenum E1 e1:1;$/;\"\tm\tstruct:s1\ttyperef:enum:E1:1\tfile:\nx1\tinput.c\t/^\tint x1;$/;\"\tm\tstruct:s1\ttyperef:typename:int\tfile:\ns2\tinput.c\t/^struct s2 {$/;\"\ts\tfile:\nE2\tinput.c\t/^\tenum E2 {ID2} e2:1;$/;\"\tg\tstruct:s2\tfile:\nID2\tinput.c\t/^\tenum E2 {ID2} e2:1;$/;\"\te\tenum:s2::E2\tfile:\ne2\tinput.c\t/^\tenum E2 {ID2} e2:1;$/;\"\tm\tstruct:s2\ttyperef:enum:s2::E2:1\tfile:\nx2\tinput.c\t/^\tint x2;$/;\"\tm\tstruct:s2\ttyperef:typename:int\tfile:\nE3\tinput.c\t/^enum E3 {ID3};$/;\"\tg\tfile:\nID3\tinput.c\t/^enum E3 {ID3};$/;\"\te\tenum:E3\tfile:\ns3\tinput.c\t/^struct s3 {$/;\"\ts\tfile:\ne3\tinput.c\t/^\tenum E3 e3:1;$/;\"\tm\tstruct:s3\ttyperef:enum:E3:1\tfile:\nx3\tinput.c\t/^\tint x3;$/;\"\tm\tstruct:s3\ttyperef:typename:int\tfile:\nE4\tinput.c\t/^enum E4 {ID4};$/;\"\tg\tfile:\nID4\tinput.c\t/^enum E4 {ID4};$/;\"\te\tenum:E4\tfile:\nbits\tinput.c\t/^#define bits /;\"\td\tfile:\tmacrodef:7\ns4\tinput.c\t/^struct s4 {$/;\"\ts\tfile:\ne4_1\tinput.c\t/^\tenum E4 e4_1:1, e4_2:2, e4_3:bits;$/;\"\tm\tstruct:s4\ttyperef:enum:E4:1\tfile:\ne4_2\tinput.c\t/^\tenum E4 e4_1:1, e4_2:2, e4_3:bits;$/;\"\tm\tstruct:s4\ttyperef:enum:E4:2\tfile:\ne4_3\tinput.c\t/^\tenum E4 e4_1:1, e4_2:2, e4_3:bits;$/;\"\tm\tstruct:s4\ttyperef:enum:E4:7\tfile:\nx4\tinput.c\t/^\tint x4;$/;\"\tm\tstruct:s4\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/enum-bit-fields.d/input.c",
    "content": "struct s0 {\n\tenum {ID0} e0:1;\n\tint x0;\n};\n\nenum E1 {ID1};\nstruct s1 {\n\tenum E1 e1:1;\n\tint x1;\n};\n\nstruct s2 {\n\tenum E2 {ID2} e2:1;\n\tint x2;\n};\n\nenum E3 {ID3};\nstruct s3 {\n\tenum E3 e3:1;\n\tint x3;\n};\n\nenum E4 {ID4};\n#define bits 7\nstruct s4 {\n\tenum E4 e4_1:1, e4_2:2, e4_3:bits;\n\tint x4;\n};\n"
  },
  {
    "path": "Units/parser-c.r/enum.c.d/args.ctags",
    "content": "--sort=no"
  },
  {
    "path": "Units/parser-c.r/enum.c.d/expected.tags",
    "content": "E1\tinput.c\t/^enum E1 {$/;\"\tg\tfile:\nE1_member1\tinput.c\t/^    E1_member1 = 1,$/;\"\te\tenum:E1\tfile:\nE1_member2\tinput.c\t/^    E1_member2,$/;\"\te\tenum:E1\tfile:\nE1_member3\tinput.c\t/^    E1_member3$/;\"\te\tenum:E1\tfile:\n__anonbdb313d80103\tinput.c\t/^enum {$/;\"\tg\tfile:\nAnon1_member1\tinput.c\t/^\tAnon1_member1$/;\"\te\tenum:__anonbdb313d80103\tfile:\nvar1\tinput.c\t/^enum E1 var1;$/;\"\tv\ttyperef:enum:E1\n__anonbdb313d80203\tinput.c\t/^enum { Anon2_member1 } var2;$/;\"\tg\tfile:\nAnon2_member1\tinput.c\t/^enum { Anon2_member1 } var2;$/;\"\te\tenum:__anonbdb313d80203\tfile:\nvar2\tinput.c\t/^enum { Anon2_member1 } var2;$/;\"\tv\ttyperef:enum:__anonbdb313d80203\n__anonbdb313d80303\tinput.c\t/^enum { Anon3_member1 } function(){ return Anon3_member1; };$/;\"\tg\tfile:\nAnon3_member1\tinput.c\t/^enum { Anon3_member1 } function(){ return Anon3_member1; };$/;\"\te\tenum:__anonbdb313d80303\tfile:\nfunction\tinput.c\t/^enum { Anon3_member1 } function(){ return Anon3_member1; };$/;\"\tf\ttyperef:enum:__anonbdb313d80303\nE2\tinput.c\t/^enum E2 { E2_member1 } var3[10];$/;\"\tg\tfile:\nE2_member1\tinput.c\t/^enum E2 { E2_member1 } var3[10];$/;\"\te\tenum:E2\tfile:\nvar3\tinput.c\t/^enum E2 { E2_member1 } var3[10];$/;\"\tv\ttyperef:enum:E2[10]\n"
  },
  {
    "path": "Units/parser-c.r/enum.c.d/input.c",
    "content": "enum E1 {\n    E1_member1 = 1,\n    E1_member2,\n    E1_member3\n};\n\nenum {\n\tAnon1_member1\n};\n\nenum E1 var1;\nenum { Anon2_member1 } var2;\n\n// The following is valid only in C\nenum { Anon3_member1 } function(){ return Anon3_member1; };\n\n// The following is accepted by gcc but it is also semantically flawed since the\n// function definition cannot be present in the same compilation unit.\n// \n// enum { Anon4_member1 } function2();\n//\n// It's true that the definition for function2 *could* be in some other compilation\n// unit and since the enum is technically an int, it might even work at linker level.\n//\n// However, it's ugly and complicates ctags parsing quite a lot.\n// So for now I deliberately choose to not support it. If you find a piece of code\n// that needs it, drop me a mail at <s dot stefanek at gmail dot com> :P\n\nenum E2 { E2_member1 } var3[10];\n\n\n\n\n"
  },
  {
    "path": "Units/parser-c.r/extern_variable.h.b/README",
    "content": "Exuberant ctags generates following tags file\n\n\t$ ctags -o - --C-kinds='x'  input.h\n\tC\t/home/jet/var/ctags/Units/review-needed.r/extern_variable.h.t/input.h\t/^class C;$/;\"\tx\n\tS\t/home/jet/var/ctags/Units/review-needed.r/extern_variable.h.t/input.h\t/^struct S;$/;\"\tx\n\ta\t/home/jet/var/ctags/Units/review-needed.r/extern_variable.h.t/input.h\t/^extern int a;$/;\"\tx\n\tb\t/home/jet/var/ctags/Units/review-needed.r/extern_variable.h.t/input.h\t/^extern struct B b;$/;\"\tx\n\nUniversal ctags generates following tags file\n\n\t$ ./ctags -o - --kinds-C='x'  input.h\n\ta\t/home/jet/var/ctags/Units/review-needed.r/extern_variable.h.t/input.h\t/^extern int a;$/;\"\tx\ttyperef:typename:int\n\tb\t/home/jet/var/ctags/Units/review-needed.r/extern_variable.h.t/input.h\t/^extern struct B b;$/;\"\tx\ttyperef:struct:B\n\nI marked this .b. We have to consider which behavior is better.\n"
  },
  {
    "path": "Units/parser-c.r/extern_variable.h.b/args.ctags",
    "content": "--kinds-C=x\n"
  },
  {
    "path": "Units/parser-c.r/extern_variable.h.b/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-c.r/extern_variable.h.b/input.h",
    "content": "extern int a;\nextern struct B b;\nstruct S;\nclass C;\n"
  },
  {
    "path": "Units/parser-c.r/func-after-typedef-for-fptr-returning-enum.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-c.r/func-after-typedef-for-fptr-returning-enum.d/expected.tags",
    "content": "s\tinput.c\t/^enum s { E };$/;\"\tg\tfile:\nE\tinput.c\t/^enum s { E };$/;\"\te\tenum:s\tfile:\ng\tinput.c\t/^typedef enum s (*g)(void);$/;\"\tt\ttyperef:enum:s (*)(void)\tfile:\nf\tinput.c\t/^void f(void){}$/;\"\tf\ttyperef:typename:void\tsignature:(void)\n"
  },
  {
    "path": "Units/parser-c.r/func-after-typedef-for-fptr-returning-enum.d/input.c",
    "content": "enum s { E };\ntypedef enum s (*g)(void);\nvoid f(void){}\n"
  },
  {
    "path": "Units/parser-c.r/func-after-typedef-for-fptr-returning-struct.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-c.r/func-after-typedef-for-fptr-returning-struct.d/expected.tags",
    "content": "s\tinput.c\t/^struct s {};$/;\"\ts\tfile:\ng\tinput.c\t/^typedef struct s (*g)(void);$/;\"\tt\ttyperef:struct:s (*)(void)\tfile:\nf\tinput.c\t/^void f(void){}$/;\"\tf\ttyperef:typename:void\tsignature:(void)\n"
  },
  {
    "path": "Units/parser-c.r/func-after-typedef-for-fptr-returning-struct.d/input.c",
    "content": "struct s {};\ntypedef struct s (*g)(void);\nvoid f(void){}\n"
  },
  {
    "path": "Units/parser-c.r/func_typedef.h.d/expected.tags",
    "content": "symlist_t\tinput.h\t/^typedef SLIST_HEAD(symlist, symbol_node) symlist_t;$/;\"\tt\n"
  },
  {
    "path": "Units/parser-c.r/func_typedef.h.d/input.h",
    "content": "typedef SLIST_HEAD(symlist, symbol_node) symlist_t;\n"
  },
  {
    "path": "Units/parser-c.r/if0.c.d/args.ctags",
    "content": "--if0\n"
  },
  {
    "path": "Units/parser-c.r/if0.c.d/expected.tags",
    "content": "x\tinput.c\t/^int x;$/;\"\tv\ttyperef:typename:int\ny\tinput.c\t/^int y;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-c.r/if0.c.d/input.c",
    "content": "#if 0\nint x;\n#else\nint y;\n#endif\n"
  },
  {
    "path": "Units/parser-c.r/line_directives.c.d/README",
    "content": "Universal ctags also reports NEWLANG as the language for input.c.\n\n================== THE ORIGINAL DOCUMENT ==================\n\nCurrently this test case made an assertion failure.\nSee also #402.\n\n\"OK.zzz \", a line of input.c changes the language, the value stored to\na global variable, File.source.language.\n\nInitially ctags sets C to File.source.language.  However, ctags sets\nNEWLANG to it as specified in args.ctags when ctags reads the line.\n\nReset the language is not so bad. However, when the preprocessor part(get.c)\nof C parser reads \"#define x 1\" from input stream, get.c makes a\n'v, variable definitions' kind tag. Such kind doesn't exist in the kind table of\nNEWLANG. This makes the assertion failure.\n\nWe can remove the code which reset File.source.language to avoid the\nassertion failure::\n\n```\n    diff --git a/main/read.c b/main/read.c\n    index 91c661c..79af808 100644\n    --- a/main/read.c\n    +++ b/main/read.c\n    @@ -118,7 +118,7 @@ static boolean setSourceFileName (vString *const fileName)\n\t\t\t\t    vStringValue (File.path), vStringValue (fileName));\n\t\t\t    pathName = vStringNewOwn (tmp);\n\t\t    }\n    -\t\tsetSourceFileParameters (pathName, language);\n    +\t\tsetSourceFileParameters (pathName, getSourceLanguage());\n\t\t    result = TRUE;\n\t    }\n\t    return result;\n```\n\nThis looks good to me. However the output (tags file) becomes incompatible\nto exuberant ctags when --fields=+l option is given to ctags.\n\n```\n[exuberant]$ ctags -o - --fields='+l' \\\n             --langdef=NEWLANG --langmap=NEWLANG:+.zzz --line-directives --excmd=number \\\n             Units/review-needed.r/line_directives.c.d/input.c\nctags: Warning: Ignoring non-option in ./.ctags\n\na\tUnits/review-needed.r/line_directives.c.d/a.c\t10;\"\tv\tlanguage:C\nb\tUnits/review-needed.r/line_directives.c.d/b.c\t20;\"\tv\tlanguage:C\nc\tUnits/review-needed.r/line_directives.c.d/c.c\t30;\"\tv\tlanguage:C\nd\tUnits/review-needed.r/line_directives.c.d/OK.zzz\t2;\"\tv\tlanguage:NEWLANG\n\n[universal]$ ./ctags -o - --fields='+l' \\\n             --langdef=NEWLANG --langmap=NEWLANG:+.zzz --line-directives --excmd=number \\\n             Units/review-needed.r/line_directives.c.d/input.c\n\na\tUnits/review-needed.r/line_directives.c.d/a.c\t10;\"\tv\tlanguage:C\nb\tUnits/review-needed.r/line_directives.c.d/b.c\t20;\"\tv\tlanguage:C\nc\tUnits/review-needed.r/line_directives.c.d/c.c\t30;\"\tv\tlanguage:C\nd\tUnits/review-needed.r/line_directives.c.d/OK.zzz\t2;\"\tv\tlanguage:C\n```\n\nExuberant ctags reports NEWLANG as the language of OK.zzz.\nUniversal ctags reports C as the language of OK.zzz.\n\n'v' is a kind of C language. So even we ignore the assertion\nissue, C should be reported. This is my position.\n\nAs suffix shows OK.zzz is obviously not a C language source\ncode. Reporting C as its language is wrong. This may be\nthe position of exuberant ctags.\n\nI replaced expected.tags with the output of universal ctags\nwith the above patch.\n"
  },
  {
    "path": "Units/parser-c.r/line_directives.c.d/args.ctags",
    "content": "--line-directives\n--excmd=number\n--fields=+l\n--langdef=NEWLANG\n--map-NEWLANG=+.zzz\n"
  },
  {
    "path": "Units/parser-c.r/line_directives.c.d/expected.tags",
    "content": "a\ta.c\t10;\"\tv\tlanguage:C\ttyperef:typename:int\nb\tb.c\t20;\"\tv\tlanguage:C\ttyperef:typename:int\nc\tc.c\t30;\"\tv\tlanguage:C\ttyperef:typename:int\nd\tOK.zzz\t2;\"\tv\tlanguage:NEWLANG\ttyperef:typename:int\ne\tOK.y\t100;\"\tv\tlanguage:YACC\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-c.r/line_directives.c.d/input.c",
    "content": "/* ANSI format */\n# line 10 \"a.c\"\nint a;\n/* GNU C format */\n# 20 \"b.c\"\nint b;\n/* obsolete format */\n# 30 c.c\nint c;\n/* invalid formats */\n# 1 OK.zzz\n# 0 Not OK\nint d;\n\n# 100 OK.y\nint e;\n"
  },
  {
    "path": "Units/parser-c.r/local.c.d/args.ctags",
    "content": "--kinds-c=+lL\n"
  },
  {
    "path": "Units/parser-c.r/local.c.d/expected.tags",
    "content": "a\tinput.c\t/^    int a;$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nb\tinput.c\t/^    int b = 3;$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nisContextualKeyword\tinput.c\t/^static boolean isContextualKeyword (const tokenInfo *const token)$/;\"\tf\ttyperef:typename:boolean\tfile:\nlabel\tinput.c\t/^label:$/;\"\tL\tfunction:isContextualKeyword\tfile:\nmain\tinput.c\t/^main ()$/;\"\tf\nresult\tinput.c\t/^    boolean result;$/;\"\tl\tfunction:isContextualKeyword\ttyperef:typename:boolean\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/local.c.d/input.c",
    "content": "main ()\n{\n    int a;\n    int b = 3;\n    a = 2;\n}\n\nstatic boolean isContextualKeyword (const tokenInfo *const token)\n{\n    boolean result;\nlabel:\n    goto label;\n    switch (token->keyword)\n    {\n\tcase KEYWORD_UNION:\n\t    result = TRUE;\n\t    break;\n\n\tdefault: result = FALSE; break;\n    }\n    return result;\n}\n"
  },
  {
    "path": "Units/parser-c.r/macrodef.d/args.ctags",
    "content": "--sort=no\n--fields-C=+{macrodef}\n--fields=+Sl\n"
  },
  {
    "path": "Units/parser-c.r/macrodef.d/expected.tags",
    "content": "INT\tinput.c\t/^#define INT /;\"\td\tlanguage:C\tfile:\tmacrodef:1\nSTR\tinput.c\t/^#define STR /;\"\td\tlanguage:C\tfile:\tmacrodef:\"bar\"\nCHR\tinput.c\t/^#define CHR /;\"\td\tlanguage:C\tfile:\tmacrodef:'b'\nHEX\tinput.c\t/^#define HEX /;\"\td\tlanguage:C\tfile:\tmacrodef:0xff01\nOCT\tinput.c\t/^#define OCT /;\"\td\tlanguage:C\tfile:\tmacrodef:0644\nSYSCALL_METADATA\tinput.c\t/^#define SYSCALL_METADATA(/;\"\td\tlanguage:C\tfile:\tsignature:(sname,nb,...)\tmacrodef:\nSYSCALL_DEFINE2\tinput.c\t/^#define SYSCALL_DEFINE2(/;\"\td\tlanguage:C\tfile:\tsignature:(name,...)\tmacrodef:SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)\nSYSCALL_DEFINEx\tinput.c\t/^#define SYSCALL_DEFINEx(/;\"\td\tlanguage:C\tfile:\tsignature:(x,sname,...)\tmacrodef:SYSCALL_METADATA(sname, x, __VA_ARGS__) __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)\n__SYSCALL_DEFINEx\tinput.c\t/^#define __SYSCALL_DEFINEx(/;\"\td\tlanguage:C\tfile:\tsignature:(x,name,...)\tmacrodef:__diag_push(); __diag_ignore(GCC, 8, \"-Wattribute-alias\", \"Type aliasing is used to sanitize syscall arguments\"); asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) __attribute__((alias(__stringify(__se_sys##name)))); ALLOW_ERROR_INJECTION(sys##name, ERRNO); static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) { long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__)); __MAP(x,__SC_TEST,__VA_ARGS__); __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); return ret; } __diag_pop(); static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\n__MAP1\tinput.c\t/^#define __MAP1(/;\"\td\tlanguage:C\tfile:\tsignature:(m,t,a,...)\tmacrodef:m(t,a)\n__MAP2\tinput.c\t/^#define __MAP2(/;\"\td\tlanguage:C\tfile:\tsignature:(m,t,a,...)\tmacrodef:m(t,a), __MAP1(m,__VA_ARGS__)\n__MAP\tinput.c\t/^#define __MAP(n,...) __MAP#/;\"\td\tlanguage:C\tfile:\tsignature:(n,...)\tmacrodef:__MAP##n(__VA_ARGS__)\n__SC_DECL\tinput.c\t/^#define __SC_DECL(/;\"\td\tlanguage:C\tfile:\tsignature:(t,a)\tmacrodef:t a\n"
  },
  {
    "path": "Units/parser-c.r/macrodef.d/input.c",
    "content": "#define INT 1\n#define STR \"bar\"\n#define CHR 'b'\n#define HEX 0xff01\n#define OCT 0644\n\n/*\n * Taken from linux kernel\n */\n#define SYSCALL_METADATA(sname, nb, ...)\n#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)\n#define SYSCALL_DEFINEx(x, sname, ...)\t\t\t\t\\\n\tSYSCALL_METADATA(sname, x, __VA_ARGS__)\t\t\t\\\n\t__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)\n\n/*\n * The asmlinkage stub is aliased to a function named __se_sys_*() which\n * sign-extends 32-bit ints to longs whenever needed. The actual work is\n * done within __do_sys_*().\n */\n#define __SYSCALL_DEFINEx(x, name, ...)\t\t\t\t\t\\\n\t__diag_push();\t\t\t\t\t\t\t\\\n\t__diag_ignore(GCC, 8, \"-Wattribute-alias\",\t\t\t\\\n\t\t      \"Type aliasing is used to sanitize syscall arguments\");\\\n\tasmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\t\\\n\t\t__attribute__((alias(__stringify(__se_sys##name))));\t\\\n\tALLOW_ERROR_INJECTION(sys##name, ERRNO);\t\t\t\\\n\tstatic inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\\\n\tasmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));\t\\\n\tasmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tlong ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\\\n\t\t__MAP(x,__SC_TEST,__VA_ARGS__);\t\t\t\t\\\n\t\t__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__));\t\\\n\t\treturn ret;\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\t__diag_pop();\t\t\t\t\t\t\t\\\n\tstatic inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\n\n#define __MAP1(m,t,a,...) m(t,a)\n#define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__)\n#define __MAP(n,...) __MAP##n(__VA_ARGS__)\n\n#define __SC_DECL(t, a)\tt a\n#if 0\nSYSCALL_DEFINE2(setregid16, old_gid_t, rgid, old_gid_t, egid)\n{\n\treturn __sys_setregid(low2highgid(rgid), low2highgid(egid));\n}\n#endif\n"
  },
  {
    "path": "Units/parser-c.r/macroexpand-empty-arg.d/args.ctags",
    "content": "--sort=no\n--fields=+n{signature}\n--param-CPreProcessor._expand=1\n--fields-C={macrodef}\n"
  },
  {
    "path": "Units/parser-c.r/macroexpand-empty-arg.d/expected.tags",
    "content": "X\tinput.c\t/^#define X$/;\"\td\tline:1\tfile:\tmacrodef:\nm0\tinput.c\t/^#define m0(/;\"\td\tline:2\tfile:\tsignature:(Q,W,E,R)\tmacrodef:int Q\nm1\tinput.c\t/^#define m1(/;\"\td\tline:3\tfile:\tsignature:(Q,W,E,R)\tmacrodef:int W\nm2\tinput.c\t/^#define m2(/;\"\td\tline:4\tfile:\tsignature:(Q,W,E,R)\tmacrodef:int E\nm3\tinput.c\t/^#define m3(/;\"\td\tline:5\tfile:\tsignature:(Q,W,E,R)\tmacrodef:int R\na\tinput.c\t/^m0(a,b,c,d);$/;\"\tv\tline:7\ttyperef:typename:int\na\tinput.c\t/^m0(a,X,c,d);$/;\"\tv\tline:8\ttyperef:typename:int\na\tinput.c\t/^m0(a,b,X,d);$/;\"\tv\tline:9\ttyperef:typename:int\na\tinput.c\t/^m0(a,b,c,X);$/;\"\tv\tline:10\ttyperef:typename:int\na\tinput.c\t/^m0(a,X,X,d);$/;\"\tv\tline:11\ttyperef:typename:int\na\tinput.c\t/^m0(a,b,X,X);$/;\"\tv\tline:12\ttyperef:typename:int\na\tinput.c\t/^m0(a,X,c,X);$/;\"\tv\tline:13\ttyperef:typename:int\na\tinput.c\t/^m0(a,X,X,X);$/;\"\tv\tline:14\ttyperef:typename:int\nb\tinput.c\t/^m1(a,b,c,d);$/;\"\tv\tline:16\ttyperef:typename:int\nb\tinput.c\t/^m1(X,b,c,d);$/;\"\tv\tline:17\ttyperef:typename:int\nb\tinput.c\t/^m1(a,b,X,d);$/;\"\tv\tline:18\ttyperef:typename:int\nb\tinput.c\t/^m1(a,b,c,X);$/;\"\tv\tline:19\ttyperef:typename:int\nb\tinput.c\t/^m1(X,b,X,d);$/;\"\tv\tline:20\ttyperef:typename:int\nb\tinput.c\t/^m1(a,b,X,X);$/;\"\tv\tline:21\ttyperef:typename:int\nb\tinput.c\t/^m1(X,b,c,X);$/;\"\tv\tline:22\ttyperef:typename:int\nb\tinput.c\t/^m1(X,b,X,X);$/;\"\tv\tline:23\ttyperef:typename:int\nc\tinput.c\t/^m2(a,b,c,d);$/;\"\tv\tline:25\ttyperef:typename:int\nc\tinput.c\t/^m2(X,b,c,d);$/;\"\tv\tline:26\ttyperef:typename:int\nc\tinput.c\t/^m2(a,X,c,d);$/;\"\tv\tline:27\ttyperef:typename:int\nc\tinput.c\t/^m2(a,b,c,X);$/;\"\tv\tline:28\ttyperef:typename:int\nc\tinput.c\t/^m2(X,X,c,d);$/;\"\tv\tline:29\ttyperef:typename:int\nc\tinput.c\t/^m2(a,X,c,X);$/;\"\tv\tline:30\ttyperef:typename:int\nc\tinput.c\t/^m2(X,b,c,X);$/;\"\tv\tline:31\ttyperef:typename:int\nc\tinput.c\t/^m2(X,X,c,X);$/;\"\tv\tline:32\ttyperef:typename:int\nd\tinput.c\t/^m3(a,b,c,d);$/;\"\tv\tline:34\ttyperef:typename:int\nd\tinput.c\t/^m3(X,b,c,d);$/;\"\tv\tline:35\ttyperef:typename:int\nd\tinput.c\t/^m3(a,X,c,d);$/;\"\tv\tline:36\ttyperef:typename:int\nd\tinput.c\t/^m3(a,b,X,d);$/;\"\tv\tline:37\ttyperef:typename:int\nd\tinput.c\t/^m3(X,X,c,d);$/;\"\tv\tline:38\ttyperef:typename:int\nd\tinput.c\t/^m3(a,X,X,d);$/;\"\tv\tline:39\ttyperef:typename:int\nd\tinput.c\t/^m3(X,b,X,d);$/;\"\tv\tline:40\ttyperef:typename:int\nd\tinput.c\t/^m3(X,X,X,d);$/;\"\tv\tline:41\ttyperef:typename:int\na\tinput.c\t/^m0(a,b,c,d);$/;\"\tv\tline:43\ttyperef:typename:int\na\tinput.c\t/^m0(a,,c,d);$/;\"\tv\tline:44\ttyperef:typename:int\na\tinput.c\t/^m0(a,b,,d);$/;\"\tv\tline:45\ttyperef:typename:int\na\tinput.c\t/^m0(a,b,c,);$/;\"\tv\tline:46\ttyperef:typename:int\na\tinput.c\t/^m0(a,,,d);$/;\"\tv\tline:47\ttyperef:typename:int\na\tinput.c\t/^m0(a,b,,);$/;\"\tv\tline:48\ttyperef:typename:int\na\tinput.c\t/^m0(a,,c,);$/;\"\tv\tline:49\ttyperef:typename:int\na\tinput.c\t/^m0(a,,,);$/;\"\tv\tline:50\ttyperef:typename:int\nb\tinput.c\t/^m1(a,b,c,d);$/;\"\tv\tline:52\ttyperef:typename:int\nb\tinput.c\t/^m1(,b,c,d);$/;\"\tv\tline:53\ttyperef:typename:int\nb\tinput.c\t/^m1(a,b,,d);$/;\"\tv\tline:54\ttyperef:typename:int\nb\tinput.c\t/^m1(a,b,c,);$/;\"\tv\tline:55\ttyperef:typename:int\nb\tinput.c\t/^m1(,b,,d);$/;\"\tv\tline:56\ttyperef:typename:int\nb\tinput.c\t/^m1(a,b,,);$/;\"\tv\tline:57\ttyperef:typename:int\nb\tinput.c\t/^m1(,b,c,);$/;\"\tv\tline:58\ttyperef:typename:int\nb\tinput.c\t/^m1(,b,,);$/;\"\tv\tline:59\ttyperef:typename:int\nc\tinput.c\t/^m2(a,b,c,d);$/;\"\tv\tline:61\ttyperef:typename:int\nc\tinput.c\t/^m2(,b,c,d);$/;\"\tv\tline:62\ttyperef:typename:int\nc\tinput.c\t/^m2(a,,c,d);$/;\"\tv\tline:63\ttyperef:typename:int\nc\tinput.c\t/^m2(a,b,c,);$/;\"\tv\tline:64\ttyperef:typename:int\nc\tinput.c\t/^m2(,,c,d);$/;\"\tv\tline:65\ttyperef:typename:int\nc\tinput.c\t/^m2(a,,c,);$/;\"\tv\tline:66\ttyperef:typename:int\nc\tinput.c\t/^m2(,b,c,);$/;\"\tv\tline:67\ttyperef:typename:int\nc\tinput.c\t/^m2(,,c,);$/;\"\tv\tline:68\ttyperef:typename:int\nd\tinput.c\t/^m3(a,b,c,d);$/;\"\tv\tline:70\ttyperef:typename:int\nd\tinput.c\t/^m3(,b,c,d);$/;\"\tv\tline:71\ttyperef:typename:int\nd\tinput.c\t/^m3(a,,c,d);$/;\"\tv\tline:72\ttyperef:typename:int\nd\tinput.c\t/^m3(a,b,,d);$/;\"\tv\tline:73\ttyperef:typename:int\nd\tinput.c\t/^m3(,,c,d);$/;\"\tv\tline:74\ttyperef:typename:int\nd\tinput.c\t/^m3(a,,,d);$/;\"\tv\tline:75\ttyperef:typename:int\nd\tinput.c\t/^m3(,b,,d);$/;\"\tv\tline:76\ttyperef:typename:int\nd\tinput.c\t/^m3(,,,d);$/;\"\tv\tline:77\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-c.r/macroexpand-empty-arg.d/input.c",
    "content": "#define X\n#define m0(Q,W,E,R) int Q\n#define m1(Q,W,E,R) int W\n#define m2(Q,W,E,R) int E\n#define m3(Q,W,E,R) int R\n\nm0(a,b,c,d);\nm0(a,X,c,d);\nm0(a,b,X,d);\nm0(a,b,c,X);\nm0(a,X,X,d);\nm0(a,b,X,X);\nm0(a,X,c,X);\nm0(a,X,X,X);\n\nm1(a,b,c,d);\nm1(X,b,c,d);\nm1(a,b,X,d);\nm1(a,b,c,X);\nm1(X,b,X,d);\nm1(a,b,X,X);\nm1(X,b,c,X);\nm1(X,b,X,X);\n\nm2(a,b,c,d);\nm2(X,b,c,d);\nm2(a,X,c,d);\nm2(a,b,c,X);\nm2(X,X,c,d);\nm2(a,X,c,X);\nm2(X,b,c,X);\nm2(X,X,c,X);\n\nm3(a,b,c,d);\nm3(X,b,c,d);\nm3(a,X,c,d);\nm3(a,b,X,d);\nm3(X,X,c,d);\nm3(a,X,X,d);\nm3(X,b,X,d);\nm3(X,X,X,d);\n\nm0(a,b,c,d);\nm0(a,,c,d);\nm0(a,b,,d);\nm0(a,b,c,);\nm0(a,,,d);\nm0(a,b,,);\nm0(a,,c,);\nm0(a,,,);\n\nm1(a,b,c,d);\nm1(,b,c,d);\nm1(a,b,,d);\nm1(a,b,c,);\nm1(,b,,d);\nm1(a,b,,);\nm1(,b,c,);\nm1(,b,,);\n\nm2(a,b,c,d);\nm2(,b,c,d);\nm2(a,,c,d);\nm2(a,b,c,);\nm2(,,c,d);\nm2(a,,c,);\nm2(,b,c,);\nm2(,,c,);\n\nm3(a,b,c,d);\nm3(,b,c,d);\nm3(a,,c,d);\nm3(a,b,,d);\nm3(,,c,d);\nm3(a,,,d);\nm3(,b,,d);\nm3(,,,d);\n"
  },
  {
    "path": "Units/parser-c.r/macroexpand-typeof.d/args.ctags",
    "content": "--sort=no\n--param-CPreProcessor._expand=true\n--fields-C=+{macrodef}\n--fields=+{signature}\n--kinds-C=+x\n"
  },
  {
    "path": "Units/parser-c.r/macroexpand-typeof.d/expected.tags",
    "content": "__attribute_copy__\tinput.c\t/^# define __attribute_copy__(/;\"\td\tfile:\tsignature:(arg)\tmacrodef:__attribute__ ((__copy__ (arg)))\nweak_alias\tinput.c\t/^# define weak_alias(name, aliasname) _weak_alias /;\"\td\tfile:\tsignature:(name,aliasname)\tmacrodef:_weak_alias (name, aliasname)\n_weak_alias\tinput.c\t/^# define _weak_alias(/;\"\td\tfile:\tsignature:(name,aliasname)\tmacrodef:extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))) __attribute_copy__ (name);\n__brk\tinput.c\t/^__brk (void *addr)$/;\"\tf\ttyperef:typename:int\tsignature:(void * addr)\nbrk\tinput.c\t/^weak_alias (__brk, brk)$/;\"\tx\ttyperef:typename:__typeof(__brk)\n"
  },
  {
    "path": "Units/parser-c.r/macroexpand-typeof.d/input.c",
    "content": "// Derrived from glibc\n# define __attribute_copy__(arg) __attribute__ ((__copy__ (arg)))\n# define weak_alias(name, aliasname) _weak_alias (name, aliasname)\n# define _weak_alias(name, aliasname) \\\n  extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))) \\\n    __attribute_copy__ (name);\n\nint\n__brk (void *addr)\n{\n\t/* ... */\n\treturn 0;\n}\nweak_alias (__brk, brk)\n"
  },
  {
    "path": "Units/parser-c.r/macroexpand-with-linenum-adjustment.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n-D SYSCALL_DEFINE3(name,...)=long name(__VA_ARGS__)\n--param-CPreProcessor._expand=1\n--fields=+{signature}\n--fields-C=+{macrodef}\n"
  },
  {
    "path": "Units/parser-c.r/macroexpand-with-linenum-adjustment.d/expected.tags",
    "content": "faccessat\tinput.c\t/^SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)$/;\"\tf\tline:1\ttyperef:typename:long\tsignature:(int,dfd,const char __user *,filename,int,mode)\tend:4\nfchmodat\tinput.c\t/^SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename,$/;\"\tf\tline:6\ttyperef:typename:long\tsignature:(int,dfd,const char __user *,filename,umode_t,mode)\tend:10\nmysyscall\tinput.c\t/^\tmysyscall, int, dfd,$/;\"\tf\tline:16\ttyperef:typename:long\tsignature:(int,dfd,const char __user *,filename,umode_t,mode)\tend:21\nINJECT_MEMBERS\tinput.c\t/^#define INJECT_MEMBERS(/;\"\td\tline:23\tfile:\tsignature:(m0,m1)\tend:26\tmacrodef:int m0; int padding; int m1\nP\tinput.c\t/^struct P {$/;\"\ts\tline:28\tfile:\tend:33\nx\tinput.c\t/^\t\tx$/;\"\tm\tline:30\tstruct:P\ttyperef:typename:int\tfile:\npadding\tinput.c\t/^\tINJECT_MEMBERS($/;\"\tm\tline:29\tstruct:P\ttyperef:typename:int\tfile:\tend:29\ny\tinput.c\t/^\t\ty);$/;\"\tm\tline:32\tstruct:P\ttyperef:typename:int\tfile:\tend:32\n"
  },
  {
    "path": "Units/parser-c.r/macroexpand-with-linenum-adjustment.d/input.c",
    "content": "SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)\n{\n        return do_faccessat(dfd, filename, mode, 0);\n}\n\nSYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename,\n                umode_t, mode)\n{\n        return do_fchmodat(dfd, filename, mode, 0);\n}\n\nSYSCALL_DEFINE3(\n\t/*\n\t * noise\n\t */\n\tmysyscall, int, dfd,\n\tconst char __user *, filename,\n                umode_t, mode)\n{\n        return 0;\n}\n\n#define INJECT_MEMBERS(m0, m1) \\\n\tint m0; \\\n\tint padding; \\\n\tint m1\n\nstruct P {\n\tINJECT_MEMBERS(\n\t\tx\n\t\t,\n\t\ty);\n};\n"
  },
  {
    "path": "Units/parser-c.r/macros.c.d/README",
    "content": "This case tests multiple behavior of C parser.\n\n1. #pragma weak\n\n2. Top level function call like macro expansions\n\n   (MACRO1, MACRO2, MACRO3)\n\n   If a macro takes one parameter, according to my observation ctags\n   records the parameter as a variable by default.  It looks sensible\n   behavior.\n\n   Look at following code:\n\n   #define DEF_LANG(X) struct Lang X\n   ...\n   DEF_LANG(alpha);\n\n   In this case ctags records alpha by default.  MACRO1 tests this\n   default behavior.\n\n   With -I option you can make this behavior for a specified macro be\n   disabled.  MACRO2 tests the -I option.\n\n   If a macro takes more than one parameters, according to my\n   observation ctags records nothing. In the future we can change\n   this behavior interesting way but in this case tests the current\n   implementation(MACRO3).\n\n3. name before double parenthesis\n\n   (__ARGS)\n\n   ctags.1 says:\n\n       Ctags will also try to specially handle arguments lists\n       enclosed in double sets of parentheses in order to accept the\n       following conditional construct:\n\n            extern void foo __ARGS((int one, char two));\n\n       Any name immediately preceding the \"((\" will be automatically\n       ignored and the previous name will be used.\n\n4. #undef\n"
  },
  {
    "path": "Units/parser-c.r/macros.c.d/args.ctags",
    "content": "--kinds-c=+p\n--fields=+S\n-I MACRO2\n--fields=+r\n--extras=+r\n"
  },
  {
    "path": "Units/parser-c.r/macros.c.d/expected.tags",
    "content": "DECL1\tinput.c\t/^DECL1(foo); \\/* gcc will accept this as function prototype (with some warnings) *\\/$/;\"\tp\tfile:\tsignature:(foo)\troles:def\nDECL3\tinput.c\t/^DECL3(x, y); \\/* gcc will accept this as function prototype (with some warnings) *\\/$/;\"\tp\tfile:\tsignature:(x,y)\troles:def\nFUNCTION_LIKE\tinput.c\t/^#define FUNCTION_LIKE(/;\"\td\tfile:\tsignature:(a,b)\troles:def\nFUNCTION_LIKE\tinput.c\t/^#undef FUNCTION_LIKE$/;\"\td\tfile:\troles:undef\nVARIABLE_LIKE\tinput.c\t/^#define VARIABLE_LIKE\t/;\"\td\tfile:\troles:def\nVARIABLE_LIKE\tinput.c\t/^#undef VARIABLE_LIKE$/;\"\td\tfile:\troles:undef\nWeakSymbol\tinput.c\t/^#pragma weak WeakSymbol /;\"\td\tfile:\troles:def\nprototype1\tinput.c\t/^void prototype1 __ARGS((int arg1, void *arg2));$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(int arg1,void * arg2)\troles:def\nprototype2\tinput.c\t/^void prototype2 __ARGS((int arg1, void *arg2))$/;\"\tf\ttyperef:typename:void\tsignature:(int arg1,void * arg2)\troles:def\n"
  },
  {
    "path": "Units/parser-c.r/macros.c.d/input.c",
    "content": "#define VARIABLE_LIKE\tsome_value\n#define FUNCTION_LIKE(a,b)  (a + b)\n#pragma weak WeakSymbol = StrongSymbol\n\n/* handling of spoofing macros */\nDECL1(foo); /* gcc will accept this as function prototype (with some warnings) */\nMACRO2(bar);\nDECL3(x, y); /* gcc will accept this as function prototype (with some warnings) */\n\nvoid prototype1 __ARGS((int arg1, void *arg2));\nvoid prototype2 __ARGS((int arg1, void *arg2))\n{\n}\n#undef FUNCTION_LIKE\n#undef VARIABLE_LIKE\n"
  },
  {
    "path": "Units/parser-c.r/option-disable-undef.c.d/args.ctags",
    "content": "#--undef=no\n"
  },
  {
    "path": "Units/parser-c.r/option-disable-undef.c.d/expected.tags",
    "content": "MACRO_TO_SEE\tinput.c\t/^#define MACRO_TO_SEE$/;\"\td\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/option-disable-undef.c.d/input.c",
    "content": "#define MACRO_TO_SEE\n#undef MACRO_NOT_TO_SEE\n"
  },
  {
    "path": "Units/parser-c.r/properties-thread.d/args.ctags",
    "content": "--sort=no\n--kinds-c=*-{parameter}\n--fields=+x\n--fields-c=+{properties}\n"
  },
  {
    "path": "Units/parser-c.r/properties-thread.d/expected.tags",
    "content": "i\tinput.c\t/^__thread int i;$/;\"\tv\ttyperef:typename:int\tproperties:thread_local\ns\tinput.c\t/^extern __thread struct state s;$/;\"\tx\ttyperef:struct:state\tproperties:extern,thread_local\np\tinput.c\t/^static __thread char *p;$/;\"\tv\ttyperef:typename:char *\tfile:\tproperties:static,thread_local\nq\tinput.c\t/^static _Thread_local char *q;$/;\"\tv\ttyperef:typename:char *\tfile:\tproperties:static,thread_local\n"
  },
  {
    "path": "Units/parser-c.r/properties-thread.d/input.c",
    "content": "/* Taken from https://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html#Thread-Local */\n__thread int i;\nextern __thread struct state s;\nstatic __thread char *p;\n\nstatic _Thread_local char *q;\n"
  },
  {
    "path": "Units/parser-c.r/properties.c.d/args.ctags",
    "content": "--sort=no\n--kinds-c=*\n--fields=+x\n--fields-c=+{properties}\n"
  },
  {
    "path": "Units/parser-c.r/properties.c.d/expected.tags",
    "content": "T\tinput.c\t/^static struct T {int t;} f1(int i)$/;\"\ts\tfile:\nt\tinput.c\t/^static struct T {int t;} f1(int i)$/;\"\tm\tstruct:T\ttyperef:typename:int\tfile:\nf1\tinput.c\t/^static struct T {int t;} f1(int i)$/;\"\tf\ttyperef:struct:T\tfile:\tproperties:static\ni\tinput.c\t/^static struct T {int t;} f1(int i)$/;\"\tz\tfunction:f1\ttyperef:typename:int\tfile:\nr\tinput.c\t/^  struct T r = {.t = i};$/;\"\tl\tfunction:f1\ttyperef:struct:T\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/properties.c.d/input.c",
    "content": "// See #3943.\n// static struct S {int s;} fS1(int i);\n\n/* This is invalid input as C++ code. */\nstatic struct T {int t;} f1(int i)\n{\n  struct T r = {.t = i};\n  return r;\n}\n"
  },
  {
    "path": "Units/parser-c.r/prototype.h.d/args.ctags",
    "content": "--kinds-C=+p\n\n"
  },
  {
    "path": "Units/parser-c.r/prototype.h.d/expected.tags",
    "content": "prototype_a\tinput.h\t/^int prototype_a (int a, char *b);$/;\"\tp\ttyperef:typename:int\nprototype_b\tinput.h\t/^extern void prototype_b (void);$/;\"\tp\ttyperef:typename:void\n"
  },
  {
    "path": "Units/parser-c.r/prototype.h.d/input.h",
    "content": "int prototype_a (int a, char *b);\nextern void prototype_b (void);\n"
  },
  {
    "path": "Units/parser-c.r/recursive-macros-2.d/README",
    "content": "typeref field for `p' in expected.tags may be changed when\nthe definition for CXX_PARSER_MAXIMUM_MACRO_USE_COUNT is changed.\n"
  },
  {
    "path": "Units/parser-c.r/recursive-macros-2.d/args.ctags",
    "content": "--kinds-C=*\n-D p=a\n-D a=(p+p)\n"
  },
  {
    "path": "Units/parser-c.r/recursive-macros-2.d/expected.tags",
    "content": "dummy\tinput.c\t/^int dummy;$/;\"\tv\ttyperef:typename:int\np\tinput.c\t/^int p;$/;\"\tv\ttyperef:typename:int ((((((((+p)+p)+p)+p)+p)+p)+p)+p)\n"
  },
  {
    "path": "Units/parser-c.r/recursive-macros-2.d/input.c",
    "content": "int p;\nint dummy;\n"
  },
  {
    "path": "Units/parser-c.r/recursive-macros.d/args.ctags",
    "content": "--kinds-C=*\n-D p=a\n-D a=p+p\n"
  },
  {
    "path": "Units/parser-c.r/recursive-macros.d/expected.tags",
    "content": "dummy\tinput.c\t/^int dummy;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-c.r/recursive-macros.d/input.c",
    "content": "int p;\nint dummy;\n"
  },
  {
    "path": "Units/parser-c.r/spurious_label_tags.c.d/args.ctags",
    "content": "--kinds-c=+lp\n"
  },
  {
    "path": "Units/parser-c.r/spurious_label_tags.c.d/expected.tags",
    "content": "label_forced_tags\tinput.c\t/^static void label_forced_tags(void)$/;\"\tf\ttyperef:typename:void\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/spurious_label_tags.c.d/input.c",
    "content": "/* When run with --kinds-c=+lp option demonstrates spurious tags for statement\n * following a label\n */\nstatic void label_forced_tags(void)\n{\nlabel1:\n\tproto1(arg);\nlabel2:\n\tif (arg)\n\t\tproto2(arg);\nlabel3:\n\tvariable = 3;\n\twhile (condition) {\n\tlabel4:\n\t\tproto3(arg);\n\t}\n}\n"
  },
  {
    "path": "Units/parser-c.r/static_array.c.d/expected.tags",
    "content": "charset2uni\tinput.c\t/^static wchar_t charset2uni[256] = {$/;\"\tv\ttyperef:typename:wchar_t[256]\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/static_array.c.d/input.c",
    "content": "/* Demonstrates temporary bug caused by statement reinitialization */\nstatic wchar_t charset2uni[256] = {\n};\n"
  },
  {
    "path": "Units/parser-c.r/using-cxx-keyword-in-c-code.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-c.r/using-cxx-keyword-in-c-code.d/expected.tags",
    "content": "mutable\tinput.c\t/^static int mutable;$/;\"\tv\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-c.r/using-cxx-keyword-in-c-code.d/input.c",
    "content": "static int mutable;\n"
  },
  {
    "path": "Units/parser-c.r/vardef-surrounded-by-parentheses.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-c.r/vardef-surrounded-by-parentheses.d/expected.tags",
    "content": "A\tinput.c\t/^int (A);$/;\"\tv\ttyperef:typename:int ()\nB\tinput.c\t/^int *(B);$/;\"\tv\ttyperef:typename:int * ()\nC\tinput.c\t/^struct s *(C);$/;\"\tv\ttyperef:struct:s * ()\na\tinput.c\t/^int (a[1]);$/;\"\tv\ttyperef:typename:int ([1])\nb\tinput.c\t/^int *(b[2]);$/;\"\tv\ttyperef:typename:int * ([2])\nc\tinput.c\t/^int (c[1][2]);$/;\"\tv\ttyperef:typename:int ([1][2])\nd\tinput.c\t/^int *(d[2][3]);$/;\"\tv\ttyperef:typename:int * ([2][3])\ne\tinput.c\t/^int *(* const volatile * e[3]);$/;\"\tv\ttyperef:typename:int * (* const volatile * [3])\ns\tinput.c\t/^struct s {$/;\"\ts\tfile:\nf\tinput.c\t/^\tint *(* const volatile * f[3][3]);$/;\"\tm\tstruct:s\ttyperef:typename:int * (* const volatile * [3][3])\tfile:\ng\tinput.c\t/^\tint (g[3]);$/;\"\tm\tstruct:s\ttyperef:typename:int ([3])\tfile:\nt\tinput.c\t/^} t;$/;\"\tv\ttyperef:struct:s\nh\tinput.c\t/^int (* volatile * (*h[1]));$/;\"\tv\ttyperef:typename:int (* volatile * (* [1]))\n"
  },
  {
    "path": "Units/parser-c.r/vardef-surrounded-by-parentheses.d/input.c",
    "content": "// The next one will be reconigzed as a macro.\n// struct s (a);\nint (A);\nMACRO(ARGS);\nint *(B);\nstruct s *(C);\n\nint (a[1]);\nint *(b[2]);\nint (c[1][2]);\nint *(d[2][3]);\nint *(* const volatile * e[3]);\n\nstruct s {\n\tint *(* const volatile * f[3][3]);\n\tint (g[3]);\n} t;\n\nint (* volatile * (*h[1]));\n"
  },
  {
    "path": "Units/parser-cargo.r/simple.d/args.ctags",
    "content": "--languages=-TOML\n--languages=+Cargo\n\n--map-Cargo=.cargo\n--sort=no\n--fields=+lK\n"
  },
  {
    "path": "Units/parser-cargo.r/simple.d/expected.tags",
    "content": "myapp\tinput.cargo\t/^name = \"myapp\"$/;\"\tpackage\tlanguage:Cargo\n"
  },
  {
    "path": "Units/parser-cargo.r/simple.d/features",
    "content": "packcc\n"
  },
  {
    "path": "Units/parser-cargo.r/simple.d/input.cargo",
    "content": "[package]\nname = \"myapp\"\n"
  },
  {
    "path": "Units/parser-clojure.r/broken-ns.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-clojure.r/broken-ns.d/input-0.clj",
    "content": "(ns ^abc\n"
  },
  {
    "path": "Units/parser-clojure.r/broken-ns.d/input-1.clj",
    "content": "(ns ^abc\n"
  },
  {
    "path": "Units/parser-clojure.r/broken-ns.d/input.clj",
    "content": "(ns ^{:doc \"Document\"}\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-def-in-unknown-scope.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-def-in-unknown-scope.d/expected.tags",
    "content": "N\tinput.clj\t/^(ns N)$/;\"\tn\ndefn\tinput.clj\t/^(defn defn [n]$/;\"\tf\tnamespace:N\nS\tinput.clj\t/^(ns S$/;\"\tn\ng\tinput.clj\t/^(N\\/defn 'g)$/;\"\tY\tnamespace:S\tname:g\nh\tinput.clj\t/^(clojure.core\\/defn h [] 1)$/;\"\tf\tnamespace:S\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-def-in-unknown-scope.d/input.clj",
    "content": "(ns N)\n\n(defn defn [n]\n  1)\n\n(ns S\n  (:require [N]))\n\n(N/defn 'g)\n(clojure.core/defn h [] 1)\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-metadata-in-fn.d/expected.tags",
    "content": "my-fn\tinput.clj\t/^(defn my-fn [])$/;\"\tf\nmy-hinted-fn\tinput.clj\t/^(defn my-hinted-fn ^MyReturnType [])$/;\"\tf\nmy-private-fn\tinput.clj\t/^(defn ^:private my-private-fn [])$/;\"\tf\nmy-private-hinted-fn\tinput.clj\t/^(defn ^:private my-private-hinted-fn ^MyReturnType [])$/;\"\tf\nmy-public-fn\tinput.clj\t/^(defn ^{:foo :bar} my-public-fn [])$/;\"\tf\nso-many-hints\tinput.clj\t/^(defn ^:private so-many-hints ^MyReturnType$/;\"\tf\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-metadata-in-fn.d/input.clj",
    "content": "(defn my-fn [])\n\n(defn ^:private my-private-fn [])\n\n(defn ^{:foo :bar} my-public-fn [])\n\n(defn my-hinted-fn ^MyReturnType [])\n\n(defn ^:private my-private-hinted-fn ^MyReturnType [])\n\n(defn ^:private so-many-hints ^MyReturnType\n  [^MyArgType x])\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-metadata-in-ns.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-metadata-in-ns.d/expected.tags",
    "content": "ns0\tinput.clj\t/^(ns ^{:doc \"Utility functions.\"} ns0)$/;\"\tn\ndebug0?\tinput.clj\t/^(defn debug0? ^boolean$/;\"\tf\tnamespace:ns0\nns1\tinput-0.clj\t/^(ns ^:dynamic ns1)$/;\"\tn\ndebug1?\tinput-0.clj\t/^(defn debug1? ^boolean$/;\"\tf\tnamespace:ns1\nns2\tinput-0.clj\t/^(ns ^String ns2)$/;\"\tn\ndebug2?\tinput-0.clj\t/^(defn debug2? ^boolean$/;\"\tf\tnamespace:ns2\nns00\tinput-0.clj\t/^(ns ^{:doc \"Utility functions.\"} ^{:doc1 \"something\"} ns00)$/;\"\tn\ndebug00?\tinput-0.clj\t/^(defn debug00? ^boolean$/;\"\tf\tnamespace:ns00\nns01\tinput-0.clj\t/^(ns ^{:doc \"Utility functions.\"} ^:dynamic ns01)$/;\"\tn\ndebug01?\tinput-0.clj\t/^(defn debug01? ^boolean$/;\"\tf\tnamespace:ns01\nns02\tinput-0.clj\t/^(ns ^{:doc \"Utility functions.\"} ^String ns02)$/;\"\tn\ndebug02?\tinput-0.clj\t/^(defn debug02? ^boolean$/;\"\tf\tnamespace:ns02\nns10\tinput-0.clj\t/^(ns ^:dynamic ^{:doc \"Utility functions.\"} ns10)$/;\"\tn\ndebug10?\tinput-0.clj\t/^(defn debug10? ^boolean$/;\"\tf\tnamespace:ns10\nns11\tinput-0.clj\t/^(ns ^:dynamic ^:dynamic-something ns11)$/;\"\tn\ndebug11?\tinput-0.clj\t/^(defn debug11? ^boolean$/;\"\tf\tnamespace:ns11\nns12\tinput-0.clj\t/^(ns ^:dynamic ^String ns12)$/;\"\tn\ndebug12?\tinput-0.clj\t/^(defn debug12? ^boolean$/;\"\tf\tnamespace:ns12\nns20\tinput-0.clj\t/^(ns ^String ^{:doc \"Utility functions.\"} ns20)$/;\"\tn\ndebug20?\tinput-0.clj\t/^(defn debug20? ^boolean$/;\"\tf\tnamespace:ns20\nns21\tinput-0.clj\t/^(ns ^String ^:dynamic ns21)$/;\"\tn\ndebug21?\tinput-0.clj\t/^(defn debug21? ^boolean$/;\"\tf\tnamespace:ns21\nns22\tinput-0.clj\t/^(ns ^String ^String-something ns22)$/;\"\tn\ndebug22?\tinput-0.clj\t/^(defn debug22? ^boolean$/;\"\tf\tnamespace:ns22\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-metadata-in-ns.d/input-0.clj",
    "content": "(ns ^:dynamic ns1)\n(defn debug1? ^boolean\n  []\n  goog.DEBUG)\n\n(ns ^String ns2)\n(defn debug2? ^boolean\n  []\n  goog.DEBUG)\n\n(ns ^{:doc \"Utility functions.\"} ^{:doc1 \"something\"} ns00)\n(defn debug00? ^boolean\n  []\n  goog.DEBUG)\n\n(ns ^{:doc \"Utility functions.\"} ^:dynamic ns01)\n(defn debug01? ^boolean\n  []\n  goog.DEBUG)\n\n(ns ^{:doc \"Utility functions.\"} ^String ns02)\n(defn debug02? ^boolean\n  []\n  goog.DEBUG)\n\n\n(ns ^:dynamic ^{:doc \"Utility functions.\"} ns10)\n(defn debug10? ^boolean\n  []\n  goog.DEBUG)\n\n(ns ^:dynamic ^:dynamic-something ns11)\n(defn debug11? ^boolean\n  []\n  goog.DEBUG)\n\n(ns ^:dynamic ^String ns12)\n(defn debug12? ^boolean\n  []\n  goog.DEBUG)\n\n(ns ^String ^{:doc \"Utility functions.\"} ns20)\n(defn debug20? ^boolean\n  []\n  goog.DEBUG)\n\n(ns ^String ^:dynamic ns21)\n(defn debug21? ^boolean\n  []\n  goog.DEBUG)\n\n(ns ^String ^String-something ns22)\n(defn debug22? ^boolean\n  []\n  goog.DEBUG)\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-metadata-in-ns.d/input.clj",
    "content": ";; Taken from #1657 opened by @arichiardi\n(ns ^{:doc \"Utility functions.\"} ns0)\n(defn debug0? ^boolean\n  []\n  goog.DEBUG)\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-methods.b/README",
    "content": "About methodId kind, see #4126.\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-methods.b/args.ctags",
    "content": "--sort=no\n--fields=+KzZ\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-methods.b/expected.tags",
    "content": "multimethod.test\tinput.clj\t/^(ns multimethod.test)$/;\"\tkind:namespace\ntest\tinput.clj\t/^(defmulti test$/;\"\tkind:multi\tscope:namespace:multimethod.test\ndocumented-multimethod\tinput.clj\t/^(defmulti documented-multimethod \"Documentation\"$/;\"\tkind:multi\tscope:namespace:multimethod.test\ntest\tinput.clj\t/^(defmethod test nil$/;\"\tkind:method\tscope:namespace:multimethod.test\ntest\tinput.clj\t/^(defmethod test :test$/;\"\tkind:method\tscope:namespace:multimethod.test\ntest\tinput.clj\t/^(defmethod test :test2 named-method$/;\"\tkind:method\tscope:namespace:multimethod.test\nnamed-method\tinput.clj\t/^(defmethod test :test2 named-method$/;\"\tkind:methodId\tmethod:test\tscope:namespace:multimethod.test\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-methods.b/input.clj",
    "content": "(ns multimethod.test)\n\n(defmulti test\n  (fn [type] type))\n\n(defmulti documented-multimethod \"Documentation\"\n  (fn [type] type))\n\n(defmethod test nil\n  [& _]\n  nil)\n\n(defmethod test :test\n  [& _]\n  nil)\n\n(defmethod test :test2 named-method\n  [& _]\n  nil)\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-vars.b/args.ctags",
    "content": "--sort=no\n--fields=+KzZ\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-vars.b/expected.tags",
    "content": "vars.test\tinput.clj\t/^(ns vars.test)$/;\"\tkind:namespace\nvar\tinput.clj\t/^(def var 'var)$/;\"\tkind:variable\tnamespace:vars.test\ndoc-var\tinput.clj\t/^(def doc-var \"Documentation\" 'var)$/;\"\tkind:variable\tscope:namespace:vars.test\ndynamic-var\tinput.clj\t/^(def dynamic-var ^:dynamic 'var)$/;\"\tkind:variable\tscope:namespace:vars.test\nconst-var\tinput.clj\t/^(def const-var ^:const 'var)$/;\"\tkind:variable\tscope:namespace:vars.test\nonce-var\tinput.clj\t/^(defonce once-var 'evaluated-once)$/;\"\tkind:variable\tscope:namespace:vars.test\nfn-var\tinput.clj\t/^(def fn-var (fn [] true))$/;\"\tkind:function\tscope:namespace:vars.test\n"
  },
  {
    "path": "Units/parser-clojure.r/clojure-vars.b/input.clj",
    "content": "(ns vars.test)\n\n(def var 'var)\n\n(def doc-var \"Documentation\" 'var)\n\n(def dynamic-var ^:dynamic 'var)\n\n(def const-var ^:const 'var)\n\n(defonce once-var 'evaluated-once)\n\n(def fn-var (fn [] true))\n"
  },
  {
    "path": "Units/parser-clojure.r/macros.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-clojure.r/macros.d/expected.tags",
    "content": "with-tree\tinput.clj\t/^(defmacro with-tree$/;\"\tm\nunless\tinput.clj\t/^(defmacro unless [pred a b]$/;\"\tm\n"
  },
  {
    "path": "Units/parser-clojure.r/macros.d/input.clj",
    "content": ";; Taken from https://clojuredocs.org/clojure.core/defmacro\n\n(defmacro with-tree\n  \"works on a JTree and restores its expanded paths after executing body\"\n  [tree & body]\n  `(let [tree# ~tree\n         root# (.getRoot (.getModel tree#))\n         expanded# (if-let [x# (.getExpandedDescendants\n                                tree# (TreePath. root#))]\n                     (enumeration-seq x#)\n                     ())\n         selectionpaths# (. selectionmodel# getSelectionPaths)]\n     ~@body\n     (doseq [path# expanded#]\n       (.expandPath tree# path#))))\n\n(defmacro unless [pred a b]\n  `(if (not ~pred) ~a ~b))\n"
  },
  {
    "path": "Units/parser-clojure.r/simple-clojure.d/expected.tags",
    "content": "another.name\tinput.clj\t/^(clojure.core\\/ns another.name)$/;\"\tn\napp.controller\tinput.clj\t/^(ns app.controller)$/;\"\tn\ncore-function-with-body\tinput.clj\t/^(clojure.core\\/defn core-function-with-body []$/;\"\tf\tnamespace:app.controller\nempty-fn\tinput.clj\t/^ (defn empty-fn [])$/;\"\tf\tnamespace:app.controller\nfunction-with-body\tinput.clj\t/^(defn function-with-body []$/;\"\tf\tnamespace:app.controller\nx\tinput.clj\t/^(defn x [])$/;\"\tf\tnamespace:another.name\n"
  },
  {
    "path": "Units/parser-clojure.r/simple-clojure.d/input.clj",
    "content": "(ns app.controller)\n\n (defn empty-fn [])\n\n(defn function-with-body []\n    (println \"body\"))\n\n(clojure.core/defn core-function-with-body []\n    (println \"core\"))\n\n'(defn quoted-function [])\n(quote quoted-function2 [])\n\n(clojure.core/ns another.name)\n(defn x [])\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-comments.d/expected.tags",
    "content": "another_good_target\tinput.cmake\t/^add_library(another_good_target# <-- target$/;\"\tt\ngood_target\tinput.cmake\t/^    good_target# this is legal comment placement set(NO_TAG foo)$/;\"\tt\ntag_this\tinput.cmake\t/^]]set(tag_this)$/;\"\tv\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-comments.d/input.cmake",
    "content": "# this is a test of comments set(DO_NOT_TAG \"foo\")\n\n#[[\nmulti-linecomments\noption(DO_NOT_TAG \"foo\" OFF)\n] not the end\n]]set(tag_this)\n\nadd_custom_target(# comment set(NO_TAG \"foo\")\n    # anothe rline comment\n    good_target# this is legal comment placement set(NO_TAG foo)\n    ALL)\n\nadd_library(another_good_target# <-- target\n    SHARED # set(NO_TAG bar)\n    gmock-all.cc\n    )\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-function.d/args.ctags",
    "content": "--fields=+ne\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-function.d/expected.tags",
    "content": "Bfunctiontag_this_2\tinput.cmake\t/^\tfunction(\tBfunctiontag_this_2 ${BAR})$/;\"\tf\tline:3\tend:4\na\tinput.cmake\t/^function(a)$/;\"\tf\tline:20\tend:28\nb\tinput.cmake\t/^  function(b)$/;\"\tf\tline:22\tfunction:a\tend:27\nc\tinput.cmake\t/^    function(c)$/;\"\tf\tline:24\tfunction:a.b\tend:26\ncxx_shared_library\tinput.cmake\t/^function(cxx_shared_library#$/;\"\tf\tline:6\tend:9\nd_ALSO_Tag_this\tinput.cmake\t/^        d_ALSO_Tag_this#[[ set(foo) ]]$/;\"\tf\tline:12\tend:14\neLastlyTagThis_\tinput.cmake\t/^eLastlyTagThis_ \"hello\")$/;\"\tf\tline:17\tend:18\ntag_this1\tinput.cmake\t/^function(tag_this1)$/;\"\tf\tline:1\tend:2\nvar1_in_func_a\tinput.cmake\t/^  set(var1_in_func_a TRUE)$/;\"\tv\tline:21\tfunction:a\nvar2_in_func_a_b\tinput.cmake\t/^\tset(var2_in_func_a_b TRUE)$/;\"\tv\tline:23\tfunction:a.b\nvar3_in_func_a_b_c\tinput.cmake\t/^    \tset(var3_in_func_a_b_c TRUE)$/;\"\tv\tline:25\tfunction:a.b.c\nvar4_in_no_func\tinput.cmake\t/^set(var4_in_no_func TRUE)$/;\"\tv\tline:30\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-function.d/input.cmake",
    "content": "function(tag_this1)\nendfunction(tag_this1)\n\tfunction(\tBfunctiontag_this_2 ${BAR})\n\tendfunction()\n\nfunction(cxx_shared_library#\n         name cxx_flags)\n  cxx_library_with_type(${name} SHARED \"${cxx_flags}\" ${ARGN})\nendfunction()\n\n    FUNCTION\t\t(\n        d_ALSO_Tag_this#[[ set(foo) ]]\n    true)\n    ENDFUNCTION()\n\nFunction(\neLastlyTagThis_ \"hello\")\nEndfunction()\n\nfunction(a)\n  set(var1_in_func_a TRUE)\n  function(b)\n\tset(var2_in_func_a_b TRUE)\n    function(c)\n    \tset(var3_in_func_a_b_c TRUE)\n    endfunction(c)\n  endfunction(b)\nendfunction(a)\n\nset(var4_in_no_func TRUE)\n\nfunction(${not_this} foo)\nfunction(not-this foo)\nfunction(not.this foo)\nfunction(1notthis foo)\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-macro.d/args.ctags",
    "content": "--fields=+ne\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-macro.d/expected.tags",
    "content": "Bmacrotag_this_2\tinput.cmake\t/^\tmacro(\tBmacrotag_this_2 ${BAR})$/;\"\tm\tline:3\na\tinput.cmake\t/^macro(a)$/;\"\tm\tline:20\ncxx_shared_library\tinput.cmake\t/^macro(cxx_shared_library#$/;\"\tm\tline:6\nd_ALSO_Tag_this\tinput.cmake\t/^        d_ALSO_Tag_this#[[ set(foo) ]]$/;\"\tm\tline:12\neLastlyTagThis_\tinput.cmake\t/^eLastlyTagThis_ \"hello\")$/;\"\tm\tline:17\ntag_this1\tinput.cmake\t/^macro(tag_this1)$/;\"\tm\tline:1\nvar1_unscoped\tinput.cmake\t/^  set(var1_unscoped TRUE)$/;\"\tv\tline:21\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-macro.d/input.cmake",
    "content": "macro(tag_this1)\nendmacro(tag_this1)\n\tmacro(\tBmacrotag_this_2 ${BAR})\n\tendmacro()\n\nmacro(cxx_shared_library#\n      name cxx_flags)\n  cxx_library_with_type(${name} SHARED \"${cxx_flags}\" ${ARGN})\nendmacro()\n\n    MACRO\t\t(\n        d_ALSO_Tag_this#[[ set(foo) ]]\n    true)\n    ENDMACRO()\n\nMacro(\neLastlyTagThis_ \"hello\")\nEndmacro()\n\nmacro(a)\n  set(var1_unscoped TRUE)\nendmacro(a)\n\nmacro(${not_this} foo)\nmacro(not-this foo)\nmacro(not.this foo)\nmacro(1not_this foo)\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-option.d/expected.tags",
    "content": "1_tag_this\tinput.cmake\t/^option(1_tag_this foo)$/;\"\tD\nB-option-tag_this_2\tinput.cmake\t/^option(B-option-tag_this_2 ${BAR})$/;\"\tD\nc_TAG_THIS\tinput.cmake\t/^    option ( c_TAG_THIS but_not_this)$/;\"\tD\nd-ALSO-Tag.this\tinput.cmake\t/^        d-ALSO-Tag.this$/;\"\tD\ne.LastlyTagThis\tinput.cmake\t/^e.LastlyTagThis \"hello\")$/;\"\tD\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-option.d/input.cmake",
    "content": "option(1_tag_this foo)\noption(B-option-tag_this_2 ${BAR})\n\n    option ( c_TAG_THIS but_not_this)\n\n    OPTION\t\t(\n        d-ALSO-Tag.this\n    true)\n\nOption(\ne.LastlyTagThis \"hello\")\n\noption(${not_this} foo)\noption(${ not_this } foo)\noption(not~this foo)\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-project.d/expected.tags",
    "content": "1_tag_this\tinput.cmake\t/^project(1_tag_this)$/;\"\tp\nB-project-tag_this_2\tinput.cmake\t/^project(B-project-tag_this_2 ${BAR})$/;\"\tp\nc_TAG_THIS\tinput.cmake\t/^    project ( c_TAG_THIS but_not_this)$/;\"\tp\nd-ALSO-Tag.this\tinput.cmake\t/^        d-ALSO-Tag.this$/;\"\tp\ne.LastlyTagThis\tinput.cmake\t/^e.LastlyTagThis \"hello\")$/;\"\tp\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-project.d/input.cmake",
    "content": "project(1_tag_this)\nproject(B-project-tag_this_2 ${BAR})\n\n    project ( c_TAG_THIS but_not_this)\n\n    PROJECT\t\t(\n        d-ALSO-Tag.this\n\t)\n\nProject(\ne.LastlyTagThis \"hello\")\n\nproject(${not_this})\nproject(${ not_this })\nproject(not/this)\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-scoped-variable.d/args.ctags",
    "content": "--fields=+ne\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-scoped-variable.d/expected.tags",
    "content": "_var10\tinput.cmake\t/^  set (_var10 \"\\/FI\\\\\"${_prefixFileNative}\\\\\"\" \"\\/FI\\\\\"${_prefixFileNative}\\\\\"\")$/;\"\tv\tline:24\tfunction:cxx_shared_library\n_var11_unscoped\tinput.cmake\t/^  set (_var11_unscoped \"\\/FI\\\\\"${_prefixFileNative}\\\\\"\" \"\\/FI\\\\\"${_prefixFileNative}\\\\\"\" PARENT_/;\"\tv\tline:25\n_var6\tinput.cmake\t/^  set (_var6 \"-x ${_xLanguage_${_language}} -c \\\\\"${_prefixFile}\\\\\" -o \\\\\"${_pchFile}\\\\\"\")$/;\"\tv\tline:16\tfunction:cxx_shared_library\n_var7_unscoped\tinput.cmake\t/^  set (_var7_unscoped \"-x ${_xLanguage_${_language}} -c \\\\\"${_prefixFile}\\\\\" -o \\\\\"${_pchFile}\\\\/;\"\tv\tline:17\n_var8_unscoped\tinput.cmake\t/^  \t_var8_unscoped$/;\"\tv\tline:19\tfunction:cxx_shared_library\n_var9\tinput.cmake\t/^  set (_var9 \"\\/FI\\\\\"${_prefixFileNative}\\\\\"\")$/;\"\tv\tline:23\tfunction:cxx_shared_library\na\tinput.cmake\t/^function(a)$/;\"\tf\tline:39\tend:50\nb\tinput.cmake\t/^\tfunction(b)$/;\"\tf\tline:40\tfunction:a\tend:49\nc\tinput.cmake\t/^\t\tfunction(c ...)$/;\"\tf\tline:45\tfunction:a.b\tend:48\ncxx_shared_library\tinput.cmake\t/^function(cxx_shared_library name cxx_flags)$/;\"\tf\tline:12\tend:26\nfunc1\tinput.cmake\t/^function(func1)$/;\"\tf\tline:1\tend:4\nfunc2\tinput.cmake\t/^\tfunction(\tfunc2 ${BAR})$/;\"\tf\tline:6\tend:10\nfunc4\tinput.cmake\t/^        func4$/;\"\tf\tline:29\tend:33\nmacro1\tinput.cmake\t/^macro(macro1)$/;\"\tm\tline:35\nmacro2\tinput.cmake\t/^\t\tmacro(macro2)$/;\"\tm\tline:41\nvar1\tinput.cmake\t/^\tset(var1 TRUE)$/;\"\tv\tline:2\tfunction:func1\nvar13_unscoped\tinput.cmake\t/^\tset(var13_unscoped TRUE)$/;\"\tv\tline:36\nvar14_a_b\tinput.cmake\t/^\t\t\tset(var14_a_b TRUE)$/;\"\tv\tline:42\tfunction:a.b\nvar15_a_b_c\tinput.cmake\t/^\t\t\tset(var15_a_b_c TRUE)$/;\"\tv\tline:46\tfunction:a.b.c\nvar2\tinput.cmake\t/^\tset(var2 \"hello\")$/;\"\tv\tline:3\tfunction:func1\nvar_12\tinput.cmake\t/^\t\tSET ( var_12 \"hello\" foo ${bar})$/;\"\tv\tline:31\tfunction:func4\nvar_16_unscoped\tinput.cmake\t/^\t\t\tset(var_16_unscoped \"hello \\\\\"\" ${ARGN} \"\\\\\" world\" PARENT_SCOPE)$/;\"\tv\tline:47\nvar_3_unscoped\tinput.cmake\t/^\t\tset ( var_3_unscoped \"hello\" PARENT_SCOPE)$/;\"\tv\tline:7\nvar_4_unscoped\tinput.cmake\t/^\t\tset ( var_4_unscoped \"hello\" \"world\" PARENT_SCOPE)$/;\"\tv\tline:8\nvar_5_unscoped\tinput.cmake\t/^\t\tset ( var_5_unscoped \"hello \\\\\"\" ${ARGN} \"\\\\\" world\" PARENT_SCOPE)$/;\"\tv\tline:9\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-scoped-variable.d/input.cmake",
    "content": "function(func1)\n\tset(var1 TRUE)\n\tset(var2 \"hello\")\nendfunction()\n\n\tfunction(\tfunc2 ${BAR})\n\t\tset ( var_3_unscoped \"hello\" PARENT_SCOPE)\n\t\tset ( var_4_unscoped \"hello\" \"world\" PARENT_SCOPE)\n\t\tset ( var_5_unscoped \"hello \\\"\" ${ARGN} \"\\\" world\" PARENT_SCOPE)\n\tendfunction()\n\nfunction(cxx_shared_library name cxx_flags)\n  cxx_library_with_type(${name} SHARED \"${cxx_flags}\" ${ARGN})\n\n  # yes cmake files reall have these types of things:\n  set (_var6 \"-x ${_xLanguage_${_language}} -c \\\"${_prefixFile}\\\" -o \\\"${_pchFile}\\\"\")\n  set (_var7_unscoped \"-x ${_xLanguage_${_language}} -c \\\"${_prefixFile}\\\" -o \\\"${_pchFile}\\\"\" PARENT_SCOPE)\n  set (\n  \t_var8_unscoped\n  \t\"-x ${_xLanguage_${_language}} -c \\\"${_prefixFile}\\\" -o \\\"${_pchFile}\\\"\"\n  \tPARENT_SCOPE)\n\n  set (_var9 \"/FI\\\"${_prefixFileNative}\\\"\")\n  set (_var10 \"/FI\\\"${_prefixFileNative}\\\"\" \"/FI\\\"${_prefixFileNative}\\\"\")\n  set (_var11_unscoped \"/FI\\\"${_prefixFileNative}\\\"\" \"/FI\\\"${_prefixFileNative}\\\"\" PARENT_SCOPE)\nendfunction()\n\n    FUNCTION\t\t(\n        func4\n    true)\n\t\tSET ( var_12 \"hello\" foo ${bar})\n\n\tENDFUNCTION()\n\nmacro(macro1)\n\tset(var13_unscoped TRUE)\nendmacro()\n\nfunction(a)\n\tfunction(b)\n\t\tmacro(macro2)\n\t\t\tset(var14_a_b TRUE)\n\t\tendmacro()\n\n\t\tfunction(c ...)\n\t\t\tset(var15_a_b_c TRUE)\n\t\t\tset(var_16_unscoped \"hello \\\"\" ${ARGN} \"\\\" world\" PARENT_SCOPE)\n\t\tendfunction()\n\tendfunction()\nendfunction()\n\n\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-simple.d/expected.tags",
    "content": "BUILD_GMOCK\tinput.cmake\t/^option(BUILD_GMOCK \"Builds the googlemock subproject\" ON)$/;\"\tD\nBUILD_GTEST\tinput.cmake\t/^option(BUILD_GTEST \"Builds the googletest subproject\" OFF)$/;\"\tD\nCMAKE_INSTALL_BINDIR\tinput.cmake\t/^  set(CMAKE_INSTALL_BINDIR \"bin\" CACHE STRING \"User executables (bin)\")$/;\"\tv\nCMAKE_INSTALL_INCLUDEDIR\tinput.cmake\t/^  set(CMAKE_INSTALL_INCLUDEDIR \"include\" CACHE STRING \"C header files (include)\")$/;\"\tv\nCMAKE_INSTALL_LIBDIR\tinput.cmake\t/^  set(CMAKE_INSTALL_LIBDIR \"lib${LIB_SUFFIX}\" CACHE STRING \"Object code libraries (lib)\")$/;\"\tv\ngoogletest-distribution\tinput.cmake\t/^project( googletest-distribution )$/;\"\tp\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-simple.d/input.cmake",
    "content": "# taken from https://github.com/google/googletest/blob/master/CMakeLists.txt\ncmake_minimum_required(VERSION 2.6.4)\n\nif (POLICY CMP0048)\n  cmake_policy(SET CMP0048 NEW)\nendif (POLICY CMP0048)\n\nproject( googletest-distribution )\n\nenable_testing()\n\ninclude(CMakeDependentOption)\nif (CMAKE_VERSION VERSION_LESS 2.8.5)\n  set(CMAKE_INSTALL_BINDIR \"bin\" CACHE STRING \"User executables (bin)\")\n  set(CMAKE_INSTALL_LIBDIR \"lib${LIB_SUFFIX}\" CACHE STRING \"Object code libraries (lib)\")\n  set(CMAKE_INSTALL_INCLUDEDIR \"include\" CACHE STRING \"C header files (include)\")\n  mark_as_advanced(CMAKE_INSTALL_BINDIR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_INCLUDEDIR)\nelse()\n  include(GNUInstallDirs)\nendif()\n\noption(BUILD_GTEST \"Builds the googletest subproject\" OFF)\n\n#Note that googlemock target already builds googletest\noption(BUILD_GMOCK \"Builds the googlemock subproject\" ON)\n\ncmake_dependent_option(INSTALL_GTEST \"Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)\" ON \"BUILD_GTEST OR BUILD_GMOCK\" OFF)\ncmake_dependent_option(INSTALL_GMOCK \"Enable installation of googlemock. (Projects embedding googlemock may want to turn this OFF.)\" ON \"BUILD_GMOCK\" OFF)\n\nif(BUILD_GMOCK)\n  add_subdirectory( googlemock )\nelseif(BUILD_GTEST)\n  add_subdirectory( googletest )\nendif()\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-target.d/expected.tags",
    "content": "1_tag_this\tinput.cmake\t/^add_custom_target(1_tag_this)$/;\"\tt\n1_tag_this\tinput.cmake\t/^add_executable(1_tag_this)$/;\"\tt\n1_tag_this\tinput.cmake\t/^add_library(1_tag_this)$/;\"\tt\nB-add_custom_target-tag_this_2\tinput.cmake\t/^add_custom_target(B-add_custom_target-tag_this_2 ${BAR})$/;\"\tt\nB-add_executable-tag_this_2\tinput.cmake\t/^add_executable(B-add_executable-tag_this_2#[[ set(foo) ]]${BAR})$/;\"\tt\nB-add_library-tag_this_2\tinput.cmake\t/^add_library(B-add_library-tag_this_2#$/;\"\tt\nc_TAG_THIS\tinput.cmake\t/^    add_custom_target ( c_TAG_THIS#$/;\"\tt\nc_TAG_THIS\tinput.cmake\t/^    add_executable ( c_TAG_THIS but_not_this)$/;\"\tt\nc_TAG_THIS\tinput.cmake\t/^    add_library ( c_TAG_THIS but_not_this)$/;\"\tt\nd-ALSO-Tag.this\tinput.cmake\t/^\t\td-ALSO-Tag.this$/;\"\tt\nd-ALSO-Tag.this\tinput.cmake\t/^        d-ALSO-Tag.this\t$/;\"\tt\nd-ALSO-Tag.this\tinput.cmake\t/^        d-ALSO-Tag.this$/;\"\tt\ne.LastlyTagThis\tinput.cmake\t/^e.LastlyTagThis \"CustomTarget\")$/;\"\tt\ne.LastlyTagThis\tinput.cmake\t/^e.LastlyTagThis \"Executable\")$/;\"\tt\ne.LastlyTagThis\tinput.cmake\t/^e.LastlyTagThis \"Library\")$/;\"\tt\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-target.d/input.cmake",
    "content": "add_custom_target(1_tag_this)\nadd_custom_target(B-add_custom_target-tag_this_2 ${BAR})\n\n    add_custom_target ( c_TAG_THIS#\n                        but_not_this)\n\n    ADD_CUSTOM_TARGET\t\t(\n        d-ALSO-Tag.this\n\t)\n\nAdd_Custom_target(\ne.LastlyTagThis \"CustomTarget\")\n\nadd_custom_target(${not_this})\nadd_custom_target(${ not_this })\nadd_custom_target(not/this)\n\n\nadd_executable(1_tag_this)\nadd_executable(B-add_executable-tag_this_2#[[ set(foo) ]]${BAR})\n\n    add_executable ( c_TAG_THIS but_not_this)\n\n    ADD_EXECUTABLE \t   (\n        d-ALSO-Tag.this\t\n    )\n\nAdd_Executable(\ne.LastlyTagThis \"Executable\")\n\nadd_executable(${not_this})\nadd_executable(${ not_this })\nadd_executable(not/this)\n\n\nadd_library(1_tag_this)\nadd_library(B-add_library-tag_this_2#\n            ${BAR})\n\n    add_library ( c_TAG_THIS but_not_this)\n\n    ADD_LIBRARY       (\n\t\td-ALSO-Tag.this\n    )\n\nAdd_Library(\ne.LastlyTagThis \"Library\")\n\nadd_library(${not_this})\nadd_library(${ not_this })\nadd_library(not/this)\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-variable.d/expected.tags",
    "content": "1_tag_this\tinput.cmake\t/^set(1_tag_this foo)$/;\"\tv\nB-set-tag_this_2\tinput.cmake\t/^set(B-set-tag_this_2 ${BAR})$/;\"\tv\nc_TAG_THIS\tinput.cmake\t/^    set ( c_TAG_THIS but_not_this)$/;\"\tv\nd-ALSO-Tag.this\tinput.cmake\t/^        d-ALSO-Tag.this$/;\"\tv\ne.LastlyTagThis\tinput.cmake\t/^e.LastlyTagThis \"hello\")$/;\"\tv\n"
  },
  {
    "path": "Units/parser-cmake.r/cmake-variable.d/input.cmake",
    "content": "set(1_tag_this foo)\nset(B-set-tag_this_2 ${BAR})\n\n    set ( c_TAG_THIS but_not_this)\n\n    SET\t\t(\n        d-ALSO-Tag.this\n    true)\n\nSet(\ne.LastlyTagThis \"hello\")\n\nset(${not_this} foo)\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/HelloWorld.d/expected.tags",
    "content": "CONFIGURATION\tinput.cbl\t/^       CONFIGURATION SECTION.$/;\"\ts\nDATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nENVIRONMENT\tinput.cbl\t/^       ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^       FILE SECTION.$/;\"\ts\nHelloWorld\tinput.cbl\t/^       PROGRAM-ID. HelloWorld.$/;\"\tP\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUTPUT\tinput.cbl\t/^       INPUT-OUTPUT SECTION.$/;\"\ts\nMAIN-PROCEDURE\tinput.cbl\t/^       MAIN-PROCEDURE.$/;\"\tp\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/HelloWorld.d/input.cbl",
    "content": "      ******************************************************************\n      * Author: Colin Duquesnoy\n      * Date: 23/02/2014\n      * Purpose: Hello world world example mean to test parser with a\n      * non free syntax.\n      * Tectonics: cobc\n      ******************************************************************\n       IDENTIFICATION DIVISION.\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n       PROGRAM-ID. HelloWorld.\n       ENVIRONMENT DIVISION.\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n       CONFIGURATION SECTION.\n      *-----------------------\n       INPUT-OUTPUT SECTION.\n      *-----------------------\n       DATA DIVISION.\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n       FILE SECTION.\n      *-----------------------\n       WORKING-STORAGE SECTION.\n      *-----------------------\n       PROCEDURE DIVISION.\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n       MAIN-PROCEDURE.\n      **\n      * The main procedure of the program\n      **\n            DISPLAY \"Hello world\"\n            STOP RUN.\n      ** add other procedures here\n       END PROGRAM HelloWorld.\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/HelloWorldFree.d/args.ctags",
    "content": "--language-force=CobolFree\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/HelloWorldFree.d/expected.tags",
    "content": "CONFIGURATION\tinput.cbl\t/^CONFIGURATION SECTION.$/;\"\ts\nDATA\tinput.cbl\t/^DATA DIVISION.$/;\"\tD\nENVIRONMENT\tinput.cbl\t/^ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^FILE SECTION.$/;\"\ts\nIDENTIFICATION\tinput.cbl\t/^IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUTPUT\tinput.cbl\t/^INPUT-OUTPUT SECTION.$/;\"\ts\nMAIN-PROCEDURE\tinput.cbl\t/^MAIN-PROCEDURE.$/;\"\tp\nPROCEDURE\tinput.cbl\t/^PROCEDURE DIVISION.$/;\"\tD\nWORKING-STORAGE\tinput.cbl\t/^WORKING-STORAGE SECTION.$/;\"\ts\nYOUR-PROGRAM-NAME\tinput.cbl\t/^PROGRAM-ID. YOUR-PROGRAM-NAME.$/;\"\tP\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/HelloWorldFree.d/input.cbl",
    "content": "IDENTIFICATION DIVISION.\nPROGRAM-ID. YOUR-PROGRAM-NAME.\nENVIRONMENT DIVISION.\nCONFIGURATION SECTION.\nINPUT-OUTPUT SECTION.\nDATA DIVISION.\nFILE SECTION.\nWORKING-STORAGE SECTION.\nPROCEDURE DIVISION.\nMAIN-PROCEDURE.\n    DISPLAY \"Hello world\"\n    DISPLAY 'HAHA'\nSTOP RUN.\nEND PROGRAM YOUR-PROGRAM-NAME.\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/HelloWorldLatin1.d/expected.tags",
    "content": "CONFIGURATION\tinput.cbl\t/^       CONFIGURATION SECTION.$/;\"\ts\nDATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nENVIRONMENT\tinput.cbl\t/^       ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^       FILE SECTION.$/;\"\ts\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUTPUT\tinput.cbl\t/^       INPUT-OUTPUT SECTION.$/;\"\ts\nMAIN-PROCEDURE\tinput.cbl\t/^       MAIN-PROCEDURE.$/;\"\tp\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\nYOUR-PROGRAM-NAME\tinput.cbl\t/^       PROGRAM-ID. YOUR-PROGRAM-NAME.$/;\"\tP\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/HelloWorldLatin1.d/input.cbl",
    "content": "      ******************************************************************\n      * Author: Colin Duquesnoy\n      * Date: 23/02/2014\n      * Purpose: Test d'un fichier encod en latin-1.\n      * non free syntax.\n      * Tectonics: cobc\n      ******************************************************************\n       IDENTIFICATION DIVISION.\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n       PROGRAM-ID. YOUR-PROGRAM-NAME.\n       ENVIRONMENT DIVISION.\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n       CONFIGURATION SECTION.\n      *-----------------------\n       INPUT-OUTPUT SECTION.\n      *-----------------------\n       DATA DIVISION.\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n       FILE SECTION.\n      *-----------------------\n       WORKING-STORAGE SECTION.\n      *-----------------------\n       PROCEDURE DIVISION.\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n       MAIN-PROCEDURE.\n      **\n      * The main procedure of the program\n      **\n            DISPLAY \"Hello world\"\n            STOP RUN.\n      ** add other procedures here\n       END PROGRAM YOUR-PROGRAM-NAME.\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/MALFORMED.d/expected.tags",
    "content": "CONFIGURATION\tinput.cbl\t/^       CONFIGURATION SECTION.$/;\"\ts\nDATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nENVIRONMENT\tinput.cbl\t/^               ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^       FILE SECTION.$/;\"\ts\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUTPUT\tinput.cbl\t/^       INPUT-OUTPUT SECTION.$/;\"\ts\nMAIN-PROCEDURE\tinput.cbl\t/^           MAIN-PROCEDURE.$/;\"\tp\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\nWORKING-STORAGE\tinput.cbl\t/^           WORKING-STORAGE SECTION.$/;\"\ts\nYOUR-PROGRAM-NAME\tinput.cbl\t/^       PROGRAM-ID. YOUR-PROGRAM-NAME.$/;\"\tP\nvar\tinput.cbl\t/^       01 var PIC 99.$/;\"\td\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/MALFORMED.d/input.cbl",
    "content": "      ******************************************************************\n      * Author:\n      * Date:\n      * Purpose:\n      * Tectonics: cobc\n      ******************************************************************\n       PROGRAM-ID. YOUR-PROGRAM-NAME.\n       IDENTIFICATION DIVISION.\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n       CONFIGURATION SECTION.\n      *-----------------------\n       INPUT-OUTPUT SECTION.\n      *-----------------------\n       DATA DIVISION.\n       01 var PIC 99.\n           02 generate-a-p\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n       FILE SECTION.\n      *-----------------------\n           WORKING-STORAGE SECTION.\n               ENVIRONMENT DIVISION.\n      *-----------------------\n       PROCEDURE DIVISION.\n      *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n           MAIN-PROCEDURE.\n      **\n      * The main procedure of the program\n      **\n                DISPLAY \"Hello world\"\n\n            STOP RUN.\n      ** add other procedures here\n       END PROGRAM YOUR-PROGRAM-NAME.\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/README",
    "content": "Imported from https://github.com/OpenCobolIDE/OpenCobolIDE/tree/master/test/testfiles.\n\nhttps://github.com/OpenCobolIDE/OpenCobolIDE/ is GPLv3\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/TEST-PRINTER.d/expected.tags",
    "content": "BUF-NB-LIGNES-PAR-PAGE\tinput.cbl\t/^       01 BUF-NB-LIGNES-PAR-PAGE PIC 99 VALUE 10.$/;\"\td\nDATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nENVIRONMENT\tinput.cbl\t/^       ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^       FILE SECTION.$/;\"\ts\nHELLO-WORLD\tinput.cbl\t/^       HELLO-WORLD.$/;\"\tp\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUTPUT\tinput.cbl\t/^       INPUT-OUTPUT SECTION.$/;\"\ts\nMAIN-PROCEDURE\tinput.cbl\t/^       MAIN-PROCEDURE.$/;\"\tp\nPA-BUFFER\tinput.cbl\t/^           02 PA-BUFFER        PIC X(80)   VALUE SPACES    .$/;\"\td\tgroup:PRINTER-PARAM\nPA-HOWMANY\tinput.cbl\t/^           02 PA-HOWMANY       PIC 99      VALUE 1         .$/;\"\td\tgroup:PRINTER-PARAM\nPA-RESET\tinput.cbl\t/^           02 PA-RESET         PIC X       VALUE \"N\"       .$/;\"\td\tgroup:PRINTER-PARAM\nPA-WHAT\tinput.cbl\t/^           02 PA-WHAT          PIC X(5)    VALUE \"LINES\"   .$/;\"\td\tgroup:PRINTER-PARAM\nPA-WHEN\tinput.cbl\t/^           02 PA-WHEN          PIC X(6)    VALUE \"AFTER\"   .$/;\"\td\tgroup:PRINTER-PARAM\nPRINTER-PARAM\tinput.cbl\t/^       01 PRINTER-PARAM.$/;\"\tg\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\nTEST-PRINTER\tinput.cbl\t/^       PROGRAM-ID. TEST-PRINTER.$/;\"\tP\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/TEST-PRINTER.d/input.cbl",
    "content": "      *******************************************************************\n      **=================================================================\n      ** Ce programme teste le module VIRTUAL-PRINTER\n      **\n      ** Auteurs: Colin Duquesnoy, Thomas Bertels\n      ** Date: Mai 2013\n      *******************************************************************\n       IDENTIFICATION DIVISION.\n      **************************************\n       PROGRAM-ID. TEST-PRINTER.\n      **\n       ENVIRONMENT DIVISION.\n      **************************************\n      **\n       INPUT-OUTPUT SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n      **\n       DATA DIVISION.\n      **************************************\n       FILE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n      **\n       WORKING-STORAGE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       01 PRINTER-PARAM.\n           02 PA-RESET         PIC X       VALUE \"N\"       .\n           02 PA-BUFFER        PIC X(80)   VALUE SPACES    .\n           02 PA-WHEN          PIC X(6)    VALUE \"AFTER\"   .\n           02 PA-WHAT          PIC X(5)    VALUE \"LINES\"   .\n           02 PA-HOWMANY       PIC 99      VALUE 1         .\n       01 BUF-NB-LIGNES-PAR-PAGE PIC 99 VALUE 10.\n      **\n       PROCEDURE DIVISION.\n      **************************************\n       MAIN-PROCEDURE.\n           DISPLAY \"Proj UF31: Test virtual printer\"\n\n           DISPLAY \"Combien de lignes par pages desirez-vous ?\"\n           ACCEPT BUF-NB-LIGNES-PAR-PAGE\n\n           MOVE \"O\"        TO PA-RESET\n01234A     call\n           \"VIRTUAL-PRINTER\" using PRINTER-PARAM\n\n           MOVE \"Bonjour\"  TO PA-BUFFER\n01234A     call\n           \"VIRTUAL-PRINTER\" using PRINTER-PARAM\n\n           MOVE \"La vie est dure et pleine de confiture\" to PA-BUFFER\n           MOVE \"LINES\"    TO PA-WHAT\n           MOVE \"BEFORE\"   TO PA-WHEN\n           MOVE 5          TO PA-HOWMANY\n01234A     call\n           \"VIRTUAL-PRINTER\"\n           using\n           PRINTER-PARAM\n\n           MOVE \"Bonjour\"  TO PA-BUFFER\n           MOVE \"PAGE\"    TO PA-WHAT\n           MOVE \"BEFORE\"   TO PA-WHEN\n01234A     call\n           \"VIRTUAL-PRINTER\" using PRINTER-PARAM\n\n           MOVE \"Bye bye\"  TO PA-BUFFER\n01234A     call\n           \"VIRTUAL-PRINTER\" using PRINTER-PARAM\n\n           DISPLAY \"End\"\n           STOP RUN.\n       HELLO-WORLD.\n           DISPLAY \"Hello World!!\".\n       END PROGRAM TEST-PRINTER.\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/TEST-PRINTER2.d/expected.tags",
    "content": "BUF-NB-LIGNES-PAR-PAGE\tinput.cbl\t/^       01 BUF-NB-LIGNES-PAR-PAGE PIC 99 VALUE 10.$/;\"\td\nDATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nENVIRONMENT\tinput.cbl\t/^       ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^       FILE SECTION.$/;\"\ts\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUTPUT\tinput.cbl\t/^       INPUT-OUTPUT SECTION.$/;\"\ts\nMAIN-PROCEDURE\tinput.cbl\t/^       MAIN-PROCEDURE.$/;\"\tp\nPA-BUFFER\tinput.cbl\t/^           02 PA-BUFFER        PIC X(80)   VALUE SPACES    .$/;\"\td\tgroup:PRINTER-PARAM\nPA-HOWMANY\tinput.cbl\t/^           02 PA-HOWMANY       PIC 99      VALUE 1         .$/;\"\td\tgroup:PRINTER-PARAM\nPA-RESET\tinput.cbl\t/^           02 PA-RESET         PIC X       VALUE \"N\"       .$/;\"\td\tgroup:PRINTER-PARAM\nPA-WHAT\tinput.cbl\t/^           02 PA-WHAT          PIC X(5)    VALUE \"LINES\"   .$/;\"\td\tgroup:PRINTER-PARAM\nPA-WHEN\tinput.cbl\t/^           02 PA-WHEN          PIC X(6)    VALUE \"AFTER\"   .$/;\"\td\tgroup:PRINTER-PARAM\nPRINTER-PARAM\tinput.cbl\t/^       01 PRINTER-PARAM.$/;\"\tg\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\nTEST-PRINTER\tinput.cbl\t/^       PROGRAM-ID. TEST-PRINTER.$/;\"\tP\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/TEST-PRINTER2.d/input.cbl",
    "content": "      *******************************************************************\n      **=================================================================\n      ** Ce programme teste le module VIRTUAL-PRINTER\n      **\n      ** Auteurs: Colin Duquesnoy, Thomas Bertels\n      ** Date: Mai 2013\n      *******************************************************************\n       IDENTIFICATION DIVISION.\n      **************************************\n       PROGRAM-ID. TEST-PRINTER.\n      **\n       ENVIRONMENT DIVISION.\n      **************************************\n      **\n       INPUT-OUTPUT SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n      **\n       DATA DIVISION.\n      **************************************\n       FILE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n      **\n       WORKING-STORAGE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       01 PRINTER-PARAM.\n           02 PA-RESET         PIC X       VALUE \"N\"       .\n           02 PA-BUFFER        PIC X(80)   VALUE SPACES    .\n           02 PA-WHEN          PIC X(6)    VALUE \"AFTER\"   .\n           02 PA-WHAT          PIC X(5)    VALUE \"LINES\"   .\n           02 PA-HOWMANY       PIC 99      VALUE 1         .\n       01 BUF-NB-LIGNES-PAR-PAGE PIC 99 VALUE 10.\n      **\n       PROCEDURE DIVISION.\n      **************************************\n       MAIN-PROCEDURE.\n           DISPLAY \"Proj UF31: Test virtual printer\"\n\n           DISPLAY \"Combien de lignes par pages desirez-vous ?\"\n           ACCEPT BUF-NB-LIGNES-PAR-PAGE\n\n           MOVE \"O\"        TO PA-RESET\n           CALL \"VIRTUAL-PRINTER\"\n                USING PRINTER-PARAM\n\n           CALL \"VIRTUAL-PRINTER2\"\n                USING PRINTER-PARAM\n       END PROGRAM TEST-PRINTER.\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/TEST-PRINTER3.d/expected.tags",
    "content": "BUF-NB-LIGNES-PAR-PAGE\tinput.cbl\t/^       01 BUF-NB-LIGNES-PAR-PAGE PIC 99 VALUE 10.$/;\"\td\nDATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nENVIRONMENT\tinput.cbl\t/^       ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^       FILE SECTION.$/;\"\ts\nHELLO-WORLD\tinput.cbl\t/^       HELLO-WORLD.$/;\"\tp\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUTPUT\tinput.cbl\t/^       INPUT-OUTPUT SECTION.$/;\"\ts\nMAIN-PROCEDURE\tinput.cbl\t/^       MAIN-PROCEDURE.$/;\"\tp\nPA-BUFFER\tinput.cbl\t/^           02 PA-BUFFER        PIC X(80)   VALUE SPACES    .$/;\"\td\tgroup:PRINTER-PARAM\nPA-HOWMANY\tinput.cbl\t/^           02 PA-HOWMANY       PIC 99      VALUE 1         .$/;\"\td\tgroup:PRINTER-PARAM\nPA-RESET\tinput.cbl\t/^           02 PA-RESET         PIC X       VALUE \"N\"       .$/;\"\td\tgroup:PRINTER-PARAM\nPA-WHAT\tinput.cbl\t/^           02 PA-WHAT          PIC X(5)    VALUE \"LINES\"   .$/;\"\td\tgroup:PRINTER-PARAM\nPA-WHEN\tinput.cbl\t/^           02 PA-WHEN          PIC X(6)    VALUE \"AFTER\"   .$/;\"\td\tgroup:PRINTER-PARAM\nPRINTER-PARAM\tinput.cbl\t/^       01 PRINTER-PARAM.$/;\"\tg\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\nTEST-PRINTER\tinput.cbl\t/^       PROGRAM-ID. TEST-PRINTER.$/;\"\tP\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/TEST-PRINTER3.d/input.cbl",
    "content": "      *******************************************************************\n      **=================================================================\n      ** Ce programme teste le module VIRTUAL-PRINTER\n      **\n      ** Auteurs: Colin Duquesnoy, Thomas Bertels\n      ** Date: Mai 2013\n      *******************************************************************\n       IDENTIFICATION DIVISION.\n      **************************************\n       PROGRAM-ID. TEST-PRINTER.\n      **\n       ENVIRONMENT DIVISION.\n      **************************************\n      **\n       INPUT-OUTPUT SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n      **\n       DATA DIVISION.\n      **************************************\n       FILE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n      **\n       WORKING-STORAGE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       01 PRINTER-PARAM.\n           02 PA-RESET         PIC X       VALUE \"N\"       .\n           02 PA-BUFFER        PIC X(80)   VALUE SPACES    .\n           02 PA-WHEN          PIC X(6)    VALUE \"AFTER\"   .\n           02 PA-WHAT          PIC X(5)    VALUE \"LINES\"   .\n           02 PA-HOWMANY       PIC 99      VALUE 1         .\n       01 BUF-NB-LIGNES-PAR-PAGE PIC 99 VALUE 10.\n      **\n       PROCEDURE DIVISION.\n      **************************************\n       MAIN-PROCEDURE.\n           DISPLAY \"Proj UF31: Test virtual printer\"\n\n           DISPLAY \"Combien de lignes par pages desirez-vous ?\"\n           ACCEPT BUF-NB-LIGNES-PAR-PAGE\n\n           MOVE \"O\"        TO PA-RESET\n           CALL \"VIRTUAL-PRINTER\" USING PRINTER-PARAM\n\n           MOVE \"Bonjour\"  TO PA-BUFFER\n           CALL \"VIRTUAL-PRINTER\" USING PRINTER-PARAM\n\n           MOVE \"La vie est dure et pleine de confiture\" to PA-BUFFER\n           MOVE \"LINES\"    TO PA-WHAT\n           MOVE \"BEFORE\"   TO PA-WHEN\n           MOVE 5          TO PA-HOWMANY\n           CALL \"VIRTUAL-PRINTER\" USING PRINTER-PARAM\n\n           MOVE \"Bonjour\"  TO PA-BUFFER\n           MOVE \"PAGE\"    TO PA-WHAT\n           MOVE \"BEFORE\"   TO PA-WHEN\n           CALL \"VIRTUAL-PRINTER\" USING PRINTER-PARAM\n\n           MOVE \"Bye bye\"  TO PA-BUFFER\n           CALL \"VIRTUAL-PRINTER\" USING PRINTER-PARAM\n\n           DISPLAY \"End\"\n           STOP RUN.\n       HELLO-WORLD.\n           DISPLAY \"Hello World!!\".\n       END PROGRAM TEST-PRINTER.\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/TEST-SINGLE-QUOTES.d/expected.tags",
    "content": "DATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nENVIRONMENT\tinput.cbl\t/^       ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^       FILE SECTION.$/;\"\ts\nHELLO-WORLD\tinput.cbl\t/^       HELLO-WORLD.$/;\"\tp\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUTPUT\tinput.cbl\t/^       INPUT-OUTPUT SECTION.$/;\"\ts\nMAIN-PROCEDURE\tinput.cbl\t/^       MAIN-PROCEDURE.$/;\"\tp\nPA-BUFFER\tinput.cbl\t/^           02 PA-BUFFER        PIC X(80)   VALUE SPACES    .$/;\"\td\tgroup:PRINTER-PARAM\nPA-HOWMANY\tinput.cbl\t/^           02 PA-HOWMANY       PIC 99      VALUE 1         .$/;\"\td\tgroup:PRINTER-PARAM\nPA-RESET\tinput.cbl\t/^           02 PA-RESET         PIC X       VALUE \"N\"       .$/;\"\td\tgroup:PRINTER-PARAM\nPA-WHAT\tinput.cbl\t/^           02 PA-WHAT          PIC X(5)    VALUE \"LINES\"   .$/;\"\td\tgroup:PRINTER-PARAM\nPA-WHEN\tinput.cbl\t/^           02 PA-WHEN          PIC X(6)    VALUE \"AFTER\"   .$/;\"\td\tgroup:PRINTER-PARAM\nPRINTER-PARAM\tinput.cbl\t/^       01 PRINTER-PARAM.$/;\"\tg\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\nTEST-PRINTER\tinput.cbl\t/^       PROGRAM-ID. TEST-PRINTER.$/;\"\tP\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/TEST-SINGLE-QUOTES.d/input.cbl",
    "content": "      *******************************************************************\n      **=================================================================\n      ** Ce programme teste le module VIRTUAL-PRINTER\n      **\n      ** Auteurs: Colin Duquesnoy, Thomas Bertels\n      ** Date: Mai 2013\n      *******************************************************************\n       IDENTIFICATION DIVISION.\n      **************************************\n       PROGRAM-ID. TEST-PRINTER.\n      **\n       ENVIRONMENT DIVISION.\n      **************************************\n      **\n       INPUT-OUTPUT SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n      **\n       DATA DIVISION.\n      **************************************\n       FILE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n      **\n       WORKING-STORAGE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       01 PRINTER-PARAM.\n           02 PA-RESET         PIC X       VALUE \"N\"       .\n           02 PA-BUFFER        PIC X(80)   VALUE SPACES    .\n           02 PA-WHEN          PIC X(6)    VALUE \"AFTER\"   .\n           02 PA-WHAT          PIC X(5)    VALUE \"LINES\"   .\n           02 PA-HOWMANY       PIC 99      VALUE 1         .\n      **\n       PROCEDURE DIVISION.\n      **************************************\n       MAIN-PROCEDURE.\n           DISPLAY \"Proj UF31: Test virtual printer\"\n\n           MOVE \"O\"        TO PA-RESET\n           CALL 'VIRTUAL-PRINTER' USING PRINTER-PARAM\n\n           MOVE \"Bonjour\"  TO PA-BUFFER\n           CALL 'VIRTUAL-PRINTER' USING PRINTER-PARAM\n\n           MOVE \"La vie est dure et pleine de confiture\" to PA-BUFFER\n           MOVE \"LINES\"    TO PA-WHAT\n           MOVE \"BEFORE\"   TO PA-WHEN\n           MOVE 5          TO PA-HOWMANY\n           CALL 'VIRTUAL-PRINTER' USING PRINTER-PARAM\n\n           MOVE \"Bonjour\"  TO PA-BUFFER\n           MOVE \"PAGE\"    TO PA-WHAT\n           MOVE \"BEFORE\"   TO PA-WHEN\n           CALL 'VIRTUAL-PRINTER' USING PRINTER-PARAM\n\n           MOVE \"Bye bye\"  TO PA-BUFFER\n           CALL 'VIRTUAL-PRINTER' USING PRINTER-PARAM\n\n           DISPLAY \"End\"\n           STOP RUN.\n       HELLO-WORLD.\n           DISPLAY \"Hello World!!\".\n       END PROGRAM TEST-PRINTER.\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/VIRTUAL-PRINTER.d/expected.tags",
    "content": "DATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nENREG-PRINTER\tinput.cbl\t/^       01 ENREG-PRINTER PIC X(80).$/;\"\td\nENVIRONMENT\tinput.cbl\t/^       ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^       FILE SECTION.$/;\"\ts\nFILE-CONTROL\tinput.cbl\t/^       FILE-CONTROL.$/;\"\tp\nFPRINTER\tinput.cbl\t/^       FD FPRINTER.$/;\"\tf\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUTPUT\tinput.cbl\t/^       INPUT-OUTPUT SECTION.$/;\"\ts\nLINKAGE\tinput.cbl\t/^       LINKAGE SECTION.$/;\"\ts\nMAIN-PRINTER\tinput.cbl\t/^       MAIN-PRINTER.$/;\"\tp\nPA-BUFFER\tinput.cbl\t/^           02 PA-BUFFER        PIC X(80)   .$/;\"\td\tgroup:RECEIVED-PARAM\nPA-HOWMANY\tinput.cbl\t/^           02 PA-HOWMANY       PIC 99      .$/;\"\td\tgroup:RECEIVED-PARAM\nPA-RESET\tinput.cbl\t/^           02 PA-RESET         PIC X       .$/;\"\td\tgroup:RECEIVED-PARAM\nPA-WHAT\tinput.cbl\t/^           02 PA-WHAT          PIC X(5)    .$/;\"\td\tgroup:RECEIVED-PARAM\nPA-WHEN\tinput.cbl\t/^           02 PA-WHEN          PIC X(6)    .$/;\"\td\tgroup:RECEIVED-PARAM\nRECEIVED-PARAM\tinput.cbl\t/^       01 RECEIVED-PARAM.$/;\"\tg\nVIRTUAL-PRINTER\tinput.cbl\t/^       PROGRAM-ID. VIRTUAL-PRINTER.$/;\"\tP\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/VIRTUAL-PRINTER.d/input.cbl",
    "content": "      *******************************************************************\n      ** Virtual printer subprogram\n      *******************************************************************\n       IDENTIFICATION DIVISION.\n      **************************************\n       PROGRAM-ID. VIRTUAL-PRINTER.\n      **\n       ENVIRONMENT DIVISION.\n      ***************************************\n      **\n       INPUT-OUTPUT SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       FILE-CONTROL.\n           SELECT FPRINTER ASSIGN to \"./printer.dat\"\n           ORGANIZATION LINE SEQUENTIAL\n       ACCESS SEQUENTIAL.\n      **\n       DATA DIVISION.\n      **************************************\n       FILE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       FD FPRINTER.\n       01 ENREG-PRINTER PIC X(80).\n      **\n       WORKING-STORAGE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       LINKAGE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       01 RECEIVED-PARAM.\n           02 PA-RESET         PIC X       .\n           02 PA-BUFFER        PIC X(80)   .\n           02 PA-WHEN          PIC X(6)    .\n           02 PA-WHAT          PIC X(5)    .\n           02 PA-HOWMANY       PIC 99      .\n       PROCEDURE DIVISION USING RECEIVED-PARAM.\n      **************************************\n       MAIN-PRINTER.\n           IF(PA-RESET = \"O\")\n               OPEN OUTPUT FPRINTER\n               if(PA-WHEN = \"AFTER\")\n                   if(PA-WHEN = \"AFTER\")\n                       WRITE ENREG-PRINTER\n                   END-IF\n               END-IF\n           ELSE\n                OPEN EXTEND FPRINTER\n                IF(PA-WHEN = \"AFTER\")\n                   IF(PA-WHAT = \"PAGE\")\n                       MOVE '>------------------------------------------'\n      -'------------------------------------<' TO ENREG-PRINTER\n                       WRITE ENREG-PRINTER\n                   ELSE\n                       SUBTRACT 1 FROM PA-HOWMANY\n                       PERFORM PA-HOWMANY TIMES\n                           MOVE SPACES TO ENREG-PRINTER\n                           WRITE ENREG-PRINTER\n                       END-PERFORM\n                   END-IF\n                END-IF\n                WRITE ENREG-PRINTER FROM PA-BUFFER\n                IF(PA-WHEN = \"BEFORE\")\n                   IF(PA-WHAT = \"PAGE\")\n                       MOVE '>------------------------------------------'\n      -'------------------------------------<' TO ENREG-PRINTER\n                       WRITE ENREG-PRINTER\n                   ELSE\n                       SUBTRACT 1 FROM PA-HOWMANY\n                       PERFORM PA-HOWMANY TIMES\n                           MOVE SPACES TO ENREG-PRINTER\n                           WRITE ENREG-PRINTER\n                       END-PERFORM\n                   END-IF\n                END-IF\n           END-IF\n           CLOSE FPRINTER\n           MOVE \"N\"        TO PA-RESET\n           MOVE SPACES     TO PA-BUFFER\n           MOVE \"AFTER\"    TO PA-WHEN\n           MOVE \"LINES\"    TO PA-WHAT\n           MOVE 1          TO PA-HOWMANY\n           EXIT PROGRAM.\n       END PROGRAM VIRTUAL-PRINTER.\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/VIRTUAL-PRINTER2.d/args.ctags",
    "content": "--language-force=CobolVariable\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/VIRTUAL-PRINTER2.d/expected.tags",
    "content": "DATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nENREG-PRINTER\tinput.cbl\t/^       01 ENREG-PRINTER PIC X(80).$/;\"\td\nENVIRONMENT\tinput.cbl\t/^       ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^       FILE SECTION.$/;\"\ts\nFILE-CONTROL\tinput.cbl\t/^       FILE-CONTROL.$/;\"\tp\nFPRINTER\tinput.cbl\t/^       FD FPRINTER.$/;\"\tf\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUTPUT\tinput.cbl\t/^       INPUT-OUTPUT SECTION.$/;\"\ts\nLINKAGE\tinput.cbl\t/^       LINKAGE SECTION.$/;\"\ts\nMAIN-PRINTER\tinput.cbl\t/^       MAIN-PRINTER.$/;\"\tp\nPA-BUFFER\tinput.cbl\t/^           02 PA-BUFFER        PIC X(80)   .$/;\"\td\tgroup:RECEIVED-PARAM\nPA-HOWMANY\tinput.cbl\t/^           02 PA-HOWMANY       PIC 99      .$/;\"\td\tgroup:RECEIVED-PARAM\nPA-RESET\tinput.cbl\t/^           02 PA-RESET         PIC X       .$/;\"\td\tgroup:RECEIVED-PARAM\nPA-WHAT\tinput.cbl\t/^           02 PA-WHAT          PIC X(5)    .$/;\"\td\tgroup:RECEIVED-PARAM\nPA-WHEN\tinput.cbl\t/^           02 PA-WHEN          PIC X(6)    .$/;\"\td\tgroup:RECEIVED-PARAM\nRECEIVED-PARAM\tinput.cbl\t/^                RECEIVED-PARAM.$/;\"\tp\nRECEIVED-PARAM\tinput.cbl\t/^       01 RECEIVED-PARAM.$/;\"\tg\nVIRTUAL-PRINTER\tinput.cbl\t/^       PROGRAM-ID. VIRTUAL-PRINTER.$/;\"\tP\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol-to-review.r/VIRTUAL-PRINTER2.d/input.cbl",
    "content": "      *******************************************************************\n      ** Virtual printer subprogram\n      *******************************************************************\n       IDENTIFICATION DIVISION.\n      **************************************\n       PROGRAM-ID. VIRTUAL-PRINTER.\n      **\n       ENVIRONMENT DIVISION.\n      ***************************************\n      **\n       INPUT-OUTPUT SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       FILE-CONTROL.\n           SELECT FPRINTER ASSIGN to \"./printer.dat\"\n           ORGANIZATION LINE SEQUENTIAL\n       ACCESS SEQUENTIAL.\n      **\n       DATA DIVISION.\n      **************************************\n       FILE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       FD FPRINTER.\n       01 ENREG-PRINTER PIC X(80).\n      **\n       WORKING-STORAGE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       LINKAGE SECTION.\n      **-*-*-*-*-*-*-*-*-*-*-*-*-*\n       01 RECEIVED-PARAM.\n           02 PA-RESET         PIC X       .\n           02 PA-BUFFER        PIC X(80)   .\n           02 PA-WHEN          PIC X(6)    .\n           02 PA-WHAT          PIC X(5)    .\n           02 PA-HOWMANY       PIC 99      .\n       PROCEDURE DIVISION\n            USING\n                RECEIVED-PARAM.\n      **************************************\n       MAIN-PRINTER.\n           IF(PA-RESET = \"O\")\n               OPEN OUTPUT FPRINTER\n           ELSE\n               OPEN EXTEND FPRINTER\n               IF(PA-WHEN = \"AFTER\")\n                   IF(PA-WHAT = \"PAGE\")\n                       MOVE '>------------------------------------------'\n      -'------------------------------------<' TO ENREG-PRINTER\n                       WRITE ENREG-PRINTER\n                   ELSE\n                       SUBTRACT 1 FROM PA-HOWMANY\n                       PERFORM PA-HOWMANY TIMES\n                           MOVE SPACES TO ENREG-PRINTER\n                           WRITE ENREG-PRINTER\n                       END-PERFORM\n                    END-IF\n                END-IF\n                WRITE ENREG-PRINTER FROM PA-BUFFER\n                IF(PA-WHEN = \"BEFORE\")\n                   IF(PA-WHAT = \"PAGE\")\n                       MOVE '>------------------------------------------'\n      -'------------------------------------<' TO ENREG-PRINTER\n                       WRITE ENREG-PRINTER\n                   ELSE\n                       SUBTRACT 1 FROM PA-HOWMANY\n                       PERFORM PA-HOWMANY TIMES\n                           MOVE SPACES TO ENREG-PRINTER\n                           WRITE ENREG-PRINTER\n                       END-PERFORM\n                   END-IF\n               END-IF\n           END-IF\n           CLOSE FPRINTER\n           MOVE \"N\"        TO PA-RESET\n           MOVE SPACES     TO PA-BUFFER\n           MOVE \"AFTER\"    TO PA-WHEN\n           MOVE \"LINES\"    TO PA-WHAT\n           MOVE 1          TO PA-HOWMANY\n           EXIT PROGRAM.\n       END PROGRAM VIRTUAL-PRINTER.\n"
  },
  {
    "path": "Units/parser-cobol-to-review2.r/FETCHTBL.d/expected.tags",
    "content": "AUTHOR\tinput.cbl\t/^       AUTHOR.                     TSH.$/;\"\tp\nD-EMP-NAME\tinput.cbl\t/^           05  D-EMP-NAME          PIC  X(20).$/;\"\td\tgroup:D-EMP-REC\nD-EMP-NO\tinput.cbl\t/^           05  D-EMP-NO            PIC  9(04).$/;\"\td\tgroup:D-EMP-REC\nD-EMP-REC\tinput.cbl\t/^       01  D-EMP-REC.$/;\"\tg\nD-EMP-SALARY\tinput.cbl\t/^           05  D-EMP-SALARY        PIC  --,--9.$/;\"\td\tgroup:D-EMP-REC\nDATA\tinput.cbl\t/^       DATA                        DIVISION.$/;\"\tD\nDATE-WRITTEN\tinput.cbl\t/^       DATE-WRITTEN.               2013-06-28.$/;\"\tp\nDBNAME\tinput.cbl\t/^       01  DBNAME                  PIC  X(30) VALUE SPACE.$/;\"\td\nEMP-CNT\tinput.cbl\t/^       01  EMP-CNT                 PIC  9(04).$/;\"\td\nEMP-NAME\tinput.cbl\t/^           05  EMP-NAME            PIC  X(20) .$/;\"\td\tgroup:EMP-REC-VARS\nEMP-NO\tinput.cbl\t/^           05  EMP-NO              PIC S9(04).$/;\"\td\tgroup:EMP-REC-VARS\nEMP-REC-VARS\tinput.cbl\t/^       01  EMP-REC-VARS.$/;\"\tg\nEMP-SALARY\tinput.cbl\t/^           05  EMP-SALARY          PIC S9(04).$/;\"\td\tgroup:EMP-REC-VARS\nEND-EVALUATE\tinput.cbl\t/^           END-EVALUATE.$/;\"\tp\nEND-PERFORM\tinput.cbl\t/^           END-PERFORM.$/;\"\tp\nERROR-RTN\tinput.cbl\t/^       ERROR-RTN.$/;\"\tp\nFETCHTBL\tinput.cbl\t/^       PROGRAM-ID.                 FETCHTBL.$/;\"\tP\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION              DIVISION.$/;\"\tD\nMAIN-RTN\tinput.cbl\t/^       MAIN-RTN.$/;\"\tp\nPASSWD\tinput.cbl\t/^       01  PASSWD                  PIC  X(10) VALUE SPACE.$/;\"\td\nPROCEDURE\tinput.cbl\t/^       PROCEDURE                   DIVISION.$/;\"\tD\nUSERNAME\tinput.cbl\t/^       01  USERNAME                PIC  X(30) VALUE SPACE.$/;\"\td\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE             SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol-to-review2.r/FETCHTBL.d/input.cbl",
    "content": "      ******************************************************************\n      *  Open Cobol ESQL (Ocesql) Sample Program\n      *\n      *  FETCHTBL --- demonstrates CONNECT, SELECT COUNT(*), \n      *               DECLARE cursor, FETCH cursor, COMMIT, \n      *               ROLLBACK, DISCONNECT\n      *\n      *  Copyright 2013 Tokyo System House Co., Ltd.\n      ******************************************************************\n       IDENTIFICATION              DIVISION.\n      ******************************************************************\n       PROGRAM-ID.                 FETCHTBL.\n       AUTHOR.                     TSH.\n       DATE-WRITTEN.               2013-06-28.\n\n      ******************************************************************\n       DATA                        DIVISION.\n      ******************************************************************\n       WORKING-STORAGE             SECTION.\n       01  D-EMP-REC.\n           05  D-EMP-NO            PIC  9(04).\n           05  FILLER              PIC  X.\n           05  D-EMP-NAME          PIC  X(20).\n           05  FILLER              PIC  X.\n           05  D-EMP-SALARY        PIC  --,--9.\n\n       EXEC SQL BEGIN DECLARE SECTION END-EXEC.\n       01  DBNAME                  PIC  X(30) VALUE SPACE.\n       01  USERNAME                PIC  X(30) VALUE SPACE.\n       01  PASSWD                  PIC  X(10) VALUE SPACE.\n       01  EMP-REC-VARS.\n           05  EMP-NO              PIC S9(04).\n           05  EMP-NAME            PIC  X(20) .\n           05  EMP-SALARY          PIC S9(04).\n       01  EMP-CNT                 PIC  9(04).\n       EXEC SQL END DECLARE SECTION END-EXEC.\n\n       EXEC SQL INCLUDE SQLCA END-EXEC.\n      ******************************************************************\n       PROCEDURE                   DIVISION.\n      ******************************************************************\n       MAIN-RTN.\n           DISPLAY \"*** FETCHTBL STARTED ***\".\n           \n      *    WHENEVER IS NOT YET SUPPORTED :(\n      *      EXEC SQL WHENEVER SQLERROR PERFORM ERROR-RTN END-EXEC.\n           \n      *    CONNECT\n           MOVE  \"testdb\"          TO   DBNAME.\n           MOVE  \"postgres\"        TO   USERNAME.\n           MOVE  SPACE             TO   PASSWD.\n           EXEC SQL\n               CONNECT :USERNAME IDENTIFIED BY :PASSWD USING :DBNAME \n           END-EXEC.\n           IF  SQLCODE NOT = ZERO PERFORM ERROR-RTN STOP RUN.\n           \n      *    SELECT COUNT(*) INTO HOST-VARIABLE\n           EXEC SQL \n               SELECT COUNT(*) INTO :EMP-CNT FROM EMP\n           END-EXEC.\n           DISPLAY \"TOTAL RECORD: \" EMP-CNT.\n           \n      *    DECLARE CURSOR\n           EXEC SQL \n               DECLARE C1 CURSOR FOR\n               SELECT EMP_NO, EMP_NAME, EMP_SALARY \n                      FROM EMP\n                      ORDER BY EMP_NO\n           END-EXEC.\n           EXEC SQL\n               OPEN C1\n           END-EXEC.\n           \n      *    FETCH\n           DISPLAY \"---- -------------------- ------\".\n           DISPLAY \"NO   NAME                 SALARY\".\n           DISPLAY \"---- -------------------- ------\".\n           EXEC SQL \n               FETCH C1 INTO :EMP-NO, :EMP-NAME, :EMP-SALARY\n           END-EXEC.\n           PERFORM UNTIL SQLCODE NOT = ZERO\n              MOVE  EMP-NO        TO    D-EMP-NO\n              MOVE  EMP-NAME      TO    D-EMP-NAME\n              MOVE  EMP-SALARY    TO    D-EMP-SALARY\n              DISPLAY D-EMP-REC\n              EXEC SQL \n                  FETCH C1 INTO :EMP-NO, :EMP-NAME, :EMP-SALARY\n              END-EXEC\n           END-PERFORM.\n           \n      *    CLOSE CURSOR\n           EXEC SQL \n               CLOSE C1 \n           END-EXEC. \n           \n      *    COMMIT\n           EXEC SQL \n               COMMIT WORK\n           END-EXEC.\n           \n      *    DISCONNECT\n           EXEC SQL\n               DISCONNECT ALL\n           END-EXEC.\n           \n      *    END\n           DISPLAY \"*** FETCHTBL FINISHED ***\".\n           STOP RUN.\n\n      ******************************************************************\n       ERROR-RTN.\n      ******************************************************************\n           DISPLAY \"*** SQL ERROR ***\".\n           DISPLAY \"SQLCODE: \" SQLCODE \" \" NO ADVANCING.\n           EVALUATE SQLCODE\n              WHEN  +10\n                 DISPLAY \"Record not found\"\n              WHEN  -01\n                 DISPLAY \"Connection falied\"\n              WHEN  -20\n                 DISPLAY \"Internal error\"\n              WHEN  -30\n                 DISPLAY \"PostgreSQL error\"\n                 DISPLAY \"ERRCODE: \"  SQLSTATE\n                 DISPLAY SQLERRMC\n              *> TO RESTART TRANSACTION, DO ROLLBACK.\n                 EXEC SQL\n                     ROLLBACK\n                 END-EXEC\n              WHEN  OTHER\n                 DISPLAY \"Undefined error\"\n                 DISPLAY \"ERRCODE: \"  SQLSTATE\n                 DISPLAY SQLERRMC\n           END-EVALUATE.\n      ******************************************************************\n\n"
  },
  {
    "path": "Units/parser-cobol-to-review2.r/INSERTTBL.d/expected.tags",
    "content": "AUTHOR\tinput.cbl\t/^       AUTHOR.                     TSH.$/;\"\tp\nDATA\tinput.cbl\t/^       DATA                        DIVISION.$/;\"\tD\nDATE-WRITTEN\tinput.cbl\t/^       DATE-WRITTEN.               2013-06-28.$/;\"\tp\nDBNAME\tinput.cbl\t/^       01  DBNAME                  PIC  X(30) VALUE SPACE.$/;\"\td\nEMP-NAME\tinput.cbl\t/^         03  EMP-NAME              PIC  X(20) .$/;\"\td\tgroup:EMP-REC-VARS\nEMP-NO\tinput.cbl\t/^         03  EMP-NO                PIC S9(04) VALUE ZERO.$/;\"\td\tgroup:EMP-REC-VARS\nEMP-REC-VARS\tinput.cbl\t/^       01  EMP-REC-VARS.$/;\"\tg\nEMP-SALARY\tinput.cbl\t/^         03  EMP-SALARY            PIC S9(04) VALUE ZERO.$/;\"\td\tgroup:EMP-REC-VARS\nEND-EVALUATE\tinput.cbl\t/^           END-EVALUATE.$/;\"\tp\nEND-PERFORM\tinput.cbl\t/^           END-PERFORM.$/;\"\tp\nERROR-RTN\tinput.cbl\t/^       ERROR-RTN.$/;\"\tp\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION              DIVISION.$/;\"\tD\nIDX\tinput.cbl\t/^       01  IDX                     PIC  9(02).$/;\"\td\nINSERTTBL\tinput.cbl\t/^       PROGRAM-ID.                 INSERTTBL.$/;\"\tP\nMAIN-RTN\tinput.cbl\t/^       MAIN-RTN.$/;\"\tp\nPASSWD\tinput.cbl\t/^       01  PASSWD                  PIC  X(10) VALUE SPACE.$/;\"\td\nPROCEDURE\tinput.cbl\t/^       PROCEDURE                   DIVISION.$/;\"\tD\nSYS-TIME\tinput.cbl\t/^       01  SYS-TIME                PIC  9(08).$/;\"\td\nTEST-DATA\tinput.cbl\t/^       01  TEST-DATA.$/;\"\tg\nTEST-DATA-R\tinput.cbl\t/^       01  TEST-DATA-R   REDEFINES TEST-DATA.$/;\"\td\nTEST-NAME\tinput.cbl\t/^           05  TEST-NAME           PIC  X(20) .$/;\"\td\tdata:TEST-DATA-R.TEST-TBL\nTEST-NO\tinput.cbl\t/^           05  TEST-NO             PIC S9(04).$/;\"\td\tdata:TEST-DATA-R.TEST-TBL\nTEST-SALARY\tinput.cbl\t/^           05  TEST-SALARY         PIC S9(04).$/;\"\td\tdata:TEST-DATA-R.TEST-TBL\nTEST-TBL\tinput.cbl\t/^         03  TEST-TBL    OCCURS  10.$/;\"\td\tdata:TEST-DATA-R\nUSERNAME\tinput.cbl\t/^       01  USERNAME                PIC  X(30) VALUE SPACE.$/;\"\td\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE             SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol-to-review2.r/INSERTTBL.d/input.cbl",
    "content": "      ******************************************************************\n      *  Open Cobol ESQL (Ocesql) Sample Program\n      *\n      *  INSERTTBL -- demonstrates CONNECT, DROP TABLE, CREATE TABLE, \n      *               INSERT rows, COMMIT, ROLLBACK, DISCONNECT\n      *\n      *  Copyright 2013 Tokyo System House Co., Ltd.\n      ******************************************************************\n       IDENTIFICATION              DIVISION.\n      ******************************************************************\n       PROGRAM-ID.                 INSERTTBL.\n       AUTHOR.                     TSH.\n       DATE-WRITTEN.               2013-06-28.\n\n      ******************************************************************\n       DATA                        DIVISION.\n      ******************************************************************\n       WORKING-STORAGE             SECTION.\n       01  TEST-DATA.\n                                       *>\"---+++++++++++++++++++++----\"\n      *   03 FILLER       PIC X(28) VALUE \"0001HOKKAI TARO         0400\".\n      *   03 FILLER       PIC X(28) VALUE \"0002AOMORI JIRO         0350\".\n      *   03 FILLER       PIC X(28) VALUE \"0003AKITA SABURO        0300\".\n      *   03 FILLER       PIC X(28) VALUE \"0004IWATE SHIRO         025p\".\n      *   03 FILLER       PIC X(28) VALUE \"0005MIYAGI GORO         020p\".\n      *   03 FILLER       PIC X(28) VALUE \"0006FUKUSHIMA RIKURO    0150\".\n      *   03 FILLER       PIC X(28) VALUE \"0007TOCHIGI SHICHIRO    010p\".\n      *   03 FILLER       PIC X(28) VALUE \"0008IBARAKI HACHIRO     0050\".\n      *   03 FILLER       PIC X(28) VALUE \"0009GUMMA KURO          020p\".\n      *   03 FILLER       PIC X(28) VALUE \"0010SAITAMA JURO        0350\".\n         03 FILLER       PIC X(28) VALUE \"0001kC@Y          0400\".\n         03 FILLER       PIC X(28) VALUE \"0002X@Y          0350\".\n         03 FILLER       PIC X(28) VALUE \"0003Hc@OY          0300\".\n         03 FILLER       PIC X(28) VALUE \"0004@lY          025p\".\n         03 FILLER       PIC X(28) VALUE \"0005{@ܘY          020p\".\n         03 FILLER       PIC X(28) VALUE \"0006@ZY          0150\".\n         03 FILLER       PIC X(28) VALUE \"0007Ȗ؁@Y          010p\".\n         03 FILLER       PIC X(28) VALUE \"0008@Y          0050\".\n         03 FILLER       PIC X(28) VALUE \"0009Qn@Y          020p\".\n         03 FILLER       PIC X(28) VALUE \"0010ʁ@\\Y          0350\".\n       01  TEST-DATA-R   REDEFINES TEST-DATA.\n         03  TEST-TBL    OCCURS  10.\n           05  TEST-NO             PIC S9(04).\n           05  TEST-NAME           PIC  X(20) .\n           05  TEST-SALARY         PIC S9(04).\n       01  IDX                     PIC  9(02).\n       01  SYS-TIME                PIC  9(08).\n \n       EXEC SQL BEGIN DECLARE SECTION END-EXEC.\n       01  DBNAME                  PIC  X(30) VALUE SPACE.\n       01  USERNAME                PIC  X(30) VALUE SPACE.\n       01  PASSWD                  PIC  X(10) VALUE SPACE.\n       01  EMP-REC-VARS.\n         03  EMP-NO                PIC S9(04) VALUE ZERO.\n         03  EMP-NAME              PIC  X(20) .\n         03  EMP-SALARY            PIC S9(04) VALUE ZERO.\n       EXEC SQL END DECLARE SECTION END-EXEC.\n\n       EXEC SQL INCLUDE SQLCA END-EXEC.\n      ******************************************************************\n       PROCEDURE                   DIVISION.\n      ******************************************************************\n       MAIN-RTN.\n           DISPLAY \"*** INSERTTBL STARTED ***\".\n\n      *    WHENEVER IS NOT YET SUPPORTED :(\n      *      EXEC SQL WHENEVER SQLERROR PERFORM ERROR-RTN END-EXEC.\n           \n      *    CONNECT\n           MOVE  \"testdb\"          TO   DBNAME.\n           MOVE  \"postgres\"        TO   USERNAME.\n           MOVE  SPACE             TO   PASSWD.\n           EXEC SQL\n               CONNECT :USERNAME IDENTIFIED BY :PASSWD USING :DBNAME \n           END-EXEC.\n           IF  SQLCODE NOT = ZERO PERFORM ERROR-RTN STOP RUN.\n           \n      *    DROP TABLE\n           EXEC SQL\n               DROP TABLE IF EXISTS EMP\n           END-EXEC.\n           IF  SQLCODE NOT = ZERO PERFORM ERROR-RTN.\n           \n      *    CREATE TABLE \n           EXEC SQL\n                CREATE TABLE EMP\n                (\n                    EMP_NO     NUMERIC(4,0) NOT NULL,\n                    EMP_NAME   CHAR(20),\n                    EMP_SALARY NUMERIC(4,0),\n                    CONSTRAINT IEMP_0 PRIMARY KEY (EMP_NO)\n                )\n           END-EXEC.\n           IF  SQLCODE NOT = ZERO PERFORM ERROR-RTN STOP RUN.\n           \n      *    INSERT ROWS USING LITERAL\n           EXEC SQL\n      *         INSERT INTO EMP VALUES (46, 'KAGOSHIMA ROKURO', -320)\n               INSERT INTO EMP VALUES (46, '@ZY', -320)\n           END-EXEC.\n           IF  SQLCODE NOT = ZERO PERFORM ERROR-RTN.\n\n           EXEC SQL\n      *         INSERT INTO EMP VALUES (47, 'OKINAWA SHICHIRO', 480)\n               INSERT INTO EMP VALUES (47, '@Y', 480)\n           END-EXEC.\n           IF  SQLCODE NOT = ZERO PERFORM ERROR-RTN.\n\n      *    INSERT ROWS USING HOST VARIABLE\n           PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > 10\n              MOVE TEST-NO(IDX)     TO  EMP-NO\n              MOVE TEST-NAME(IDX)   TO  EMP-NAME\n              MOVE TEST-SALARY(IDX) TO  EMP-SALARY\n              EXEC SQL\n                 INSERT INTO EMP VALUES\n                        (:EMP-NO,:EMP-NAME,:EMP-SALARY)\n              END-EXEC\n              IF  SQLCODE NOT = ZERO \n                  PERFORM ERROR-RTN\n                  EXIT PERFORM\n              END-IF\n           END-PERFORM.\n\n      *    COMMIT\n           EXEC SQL COMMIT WORK END-EXEC.\n           \n      *    DISCONNECT\n           EXEC SQL\n               DISCONNECT ALL\n           END-EXEC.\n           \n      *    END\n           DISPLAY \"*** INSERTTBL FINISHED ***\".\n           STOP RUN.\n\n      ******************************************************************\n       ERROR-RTN.\n      ******************************************************************\n           DISPLAY \"*** SQL ERROR ***\".\n           DISPLAY \"SQLCODE: \" SQLCODE \" \" NO ADVANCING.\n           EVALUATE SQLCODE\n              WHEN  +10\n                 DISPLAY \"Record not found\"\n              WHEN  -01\n                 DISPLAY \"Connection falied\"\n              WHEN  -20\n                 DISPLAY \"Internal error\"\n              WHEN  -30\n                 DISPLAY \"PostgreSQL error\"\n                 DISPLAY \"ERRCODE: \"  SQLSTATE\n                 DISPLAY SQLERRMC\n              *> TO RESTART TRANSACTION, DO ROLLBACK.\n                 EXEC SQL\n                     ROLLBACK\n                 END-EXEC\n              WHEN  OTHER\n                 DISPLAY \"Undefined error\"\n                 DISPLAY \"ERRCODE: \"  SQLSTATE\n                 DISPLAY SQLERRMC\n           END-EVALUATE.\n      ******************************************************************  \n"
  },
  {
    "path": "Units/parser-cobol-to-review2.r/README",
    "content": "License: GPLv2+\n\nTaken from https://github.com/opensourcecobol/Open-COBOL-ESQL/tree/develop/sample\nand https://github.com/opensourcecobol/Open-COBOL-ESQL/blob/develop/copy/sqlca.cbl\n"
  },
  {
    "path": "Units/parser-cobol-to-review2.r/sqlca.d/expected.tags",
    "content": "SQLCABC\tinput.cbl\t/^           05  SQLCABC               PIC S9(9) COMP-5.$/;\"\td\nSQLCAID\tinput.cbl\t/^           05  SQLCAID               PIC X(8).$/;\"\td\nSQLCODE\tinput.cbl\t/^           05  SQLCODE               PIC S9(9) COMP-5.$/;\"\td\nSQLERRD\tinput.cbl\t/^           05  SQLERRD OCCURS 6 TIMES                                   *> used only ERRD(3)$/;\"\td\nSQLERRM\tinput.cbl\t/^           05  SQLERRM.$/;\"\tg\nSQLERRMC\tinput.cbl\t/^           49  SQLERRMC              PIC X(70).$/;\"\td\tgroup:SQLERRM\nSQLERRML\tinput.cbl\t/^           49  SQLERRML              PIC S9(4) COMP-5.$/;\"\td\tgroup:SQLERRM\nSQLERRP\tinput.cbl\t/^           05  SQLERRP               PIC X(8).                          *> not used$/;\"\td\nSQLSTATE\tinput.cbl\t/^           05  SQLSTATE              PIC X(5).$/;\"\td\nSQLWARN\tinput.cbl\t/^           05  SQLWARN.                                                 *> not used$/;\"\tg\nSQLWARN0\tinput.cbl\t/^               10 SQLWARN0           PIC X(1).$/;\"\td\tgroup:SQLWARN\nSQLWARN1\tinput.cbl\t/^               10 SQLWARN1           PIC X(1).$/;\"\td\tgroup:SQLWARN\nSQLWARN2\tinput.cbl\t/^               10 SQLWARN2           PIC X(1).$/;\"\td\tgroup:SQLWARN\nSQLWARN3\tinput.cbl\t/^               10 SQLWARN3           PIC X(1).$/;\"\td\tgroup:SQLWARN\nSQLWARN4\tinput.cbl\t/^               10 SQLWARN4           PIC X(1).$/;\"\td\tgroup:SQLWARN\nSQLWARN5\tinput.cbl\t/^               10 SQLWARN5           PIC X(1).$/;\"\td\tgroup:SQLWARN\nSQLWARN6\tinput.cbl\t/^               10 SQLWARN6           PIC X(1).$/;\"\td\tgroup:SQLWARN\nSQLWARN7\tinput.cbl\t/^               10 SQLWARN7           PIC X(1).$/;\"\td\tgroup:SQLWARN\n"
  },
  {
    "path": "Units/parser-cobol-to-review2.r/sqlca.d/input.cbl",
    "content": "      ******************************************************************\n      *       SQLCA: SQL Communications Area for Ocesql                *\n      ******************************************************************\n       01  SQLCA GLOBAL.\n           05  SQLCAID               PIC X(8).\n           05  SQLCABC               PIC S9(9) COMP-5.\n           05  SQLCODE               PIC S9(9) COMP-5.\n           05  SQLERRM.\n           49  SQLERRML              PIC S9(4) COMP-5.\n           49  SQLERRMC              PIC X(70).\n           05  SQLERRP               PIC X(8).                          *> not used\n           05  SQLERRD OCCURS 6 TIMES                                   *> used only ERRD(3)\n                                     PIC S9(9) COMP-5.\n           05  SQLWARN.                                                 *> not used\n               10 SQLWARN0           PIC X(1).\n               10 SQLWARN1           PIC X(1).\n               10 SQLWARN2           PIC X(1).\n               10 SQLWARN3           PIC X(1).\n               10 SQLWARN4           PIC X(1).\n               10 SQLWARN5           PIC X(1).\n               10 SQLWARN6           PIC X(1).\n               10 SQLWARN7           PIC X(1).\n           05  SQLSTATE              PIC X(5).\n      ******************************************************************\n"
  },
  {
    "path": "Units/parser-cobol.r/comments.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-cobol.r/comments.d/input.cbl",
    "content": "      * DONTTAGME SECTION.\n"
  },
  {
    "path": "Units/parser-cobol.r/helloworld.d/expected.tags",
    "content": "00-MAIN\tinput.cbl\t/^ 04100 00-MAIN.                                                         00160000$/;\"\tp\nCONFIGURATION\tinput.cbl\t/^ 02100 CONFIGURATION SECTION.                                           00090000$/;\"\ts\nDATA\tinput.cbl\t/^ 03000 DATA DIVISION.                                                   00140000$/;\"\tD\nENVIRONMENT\tinput.cbl\t/^ 02000 ENVIRONMENT DIVISION.                                            00080000$/;\"\tD\nHELLO\tinput.cbl\t/^ 01100 PROGRAM-ID. 'HELLO'.                                             00070000$/;\"\tP\nIDENTIFICATION\tinput.cbl\t/^ 01000 IDENTIFICATION DIVISION.                                         00060000$/;\"\tD\nOBJECT-COMPUTER\tinput.cbl\t/^ 02120 OBJECT-COMPUTER.  HERCULES.                                      00110000$/;\"\tp\nPROCEDURE\tinput.cbl\t/^ 04000 PROCEDURE DIVISION.                                              00150000$/;\"\tD\nSOURCE-COMPUTER\tinput.cbl\t/^ 02110 SOURCE-COMPUTER.  GNULINUX.                                      00100000$/;\"\tp\nSPECIAL-NAMES\tinput.cbl\t/^ 02200 SPECIAL-NAMES.                                                   00120000$/;\"\tp\n"
  },
  {
    "path": "Units/parser-cobol.r/helloworld.d/input.cbl",
    "content": " 00000* VALIDATION OF BASE COBOL INSTALL                                00050000\n 01000 IDENTIFICATION DIVISION.                                         00060000\n 01100 PROGRAM-ID. 'HELLO'.                                             00070000\n 02000 ENVIRONMENT DIVISION.                                            00080000\n 02100 CONFIGURATION SECTION.                                           00090000\n 02110 SOURCE-COMPUTER.  GNULINUX.                                      00100000\n 02120 OBJECT-COMPUTER.  HERCULES.                                      00110000\n 02200 SPECIAL-NAMES.                                                   00120000\n 02210     CONSOLE IS CONSL.                                            00130000\n 03000 DATA DIVISION.                                                   00140000\n 04000 PROCEDURE DIVISION.                                              00150000\n 04100 00-MAIN.                                                         00160000\n 04110     DISPLAY 'HELLO, WORLD' UPON CONSL.                           00170000\n 04900     STOP RUN.                                                    00180000\n"
  },
  {
    "path": "Units/parser-cobol.r/helloworld2.d/expected.tags",
    "content": "00-MAIN\tinput.cbl\t/^ 04100 00-MAIN.$/;\"\tp\nCONFIGURATION\tinput.cbl\t/^ 02100 CONFIGURATION SECTION.$/;\"\ts\nDATA\tinput.cbl\t/^ 03000 DATA DIVISION.$/;\"\tD\nENVIRONMENT\tinput.cbl\t/^ 02000 ENVIRONMENT DIV$/;\"\tD\nHELLO WORLD\tinput.cbl\t/^ 01100 PROGRAM-ID. 'HELLO WORLD'.$/;\"\tP\nIDENTIFICATION\tinput.cbl\t/^\tIDENTIFICATION DIVISION.$/;\"\tD\nOBJECT-COMPUTER\tinput.cbl\t/^ 02120 OBJECT-COMPUTER.  HERCULES.$/;\"\tp\nPROCEDURE\tinput.cbl\t/^ 04000          PROCEDUR$/;\"\tD\nSOURCE-COMPUTER\tinput.cbl\t/^ 02110 SOURCE-COMPUTER.  GNULINUX.$/;\"\tp\nSPECIAL-NAMES\tinput.cbl\t/^ 02200 SPECIAL$/;\"\tp\n"
  },
  {
    "path": "Units/parser-cobol.r/helloworld2.d/input.cbl",
    "content": " 00000* VALIDATION OF BASE COBOL INSTALL\n\tIDENTIFICATION DIVISION.\n 01100 PROGRAM-ID. 'HELLO WORLD'.\n 02000 ENVIRONMENT DIV\n      -ISION.\n 02100 CONFIGURATION SECTION.\n 02110 SOURCE-COMPUTER.  GNULINUX.\n 02120 OBJECT-COMPUTER.  HERCULES.\n 02200 SPECIAL\n      --NAMES.\n 02210     CONSOLE IS CONSL.\n 03000 DATA DIVISION.\n 04000          PROCEDUR\n      -   E DIVISION.\n 04100 00-MAIN.\n 04110     DISPLAY\n           'HELLO, WORLD'\n           UPON CONSL.\n 04900     STOP RUN.\n"
  },
  {
    "path": "Units/parser-cobol.r/issue-1324.d/README",
    "content": "input.cbl is taken from a post by @FrankCal in #1324.\n"
  },
  {
    "path": "Units/parser-cobol.r/issue-1324.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-cobol.r/issue-1324.d/expected.tags",
    "content": "IDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\troles:def\nENVIRONMENT\tinput.cbl\t/^       ENVIRONMENT DIVISION.$/;\"\tD\troles:def\nCONFIGURATION\tinput.cbl\t/^       CONFIGURATION SECTION.$/;\"\ts\troles:def\nSPECIAL-NAMES\tinput.cbl\t/^       SPECIAL-NAMES.$/;\"\tp\troles:def\nDATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\troles:def\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\troles:def\nWS-ABBRUCH-TYP\tinput.cbl\t/^       01  WS-ABBRUCH-TYP          PIC 99.$/;\"\td\troles:def\nWS-ABBRUCH-EVENT\tinput.cbl\t/^           88  WS-ABBRUCH-EVENT    VALUE 91.$/;\"\td\tdata:WS-ABBRUCH-TYP\troles:def\nWS-ABBRUCH-OBJMGR\tinput.cbl\t/^.          88  WS-ABBRUCH-OBJMGR   VALUE 92.$/;\"\td\tdata:WS-ABBRUCH-TYP\troles:def\nWS-ABBRUCH-DB\tinput.cbl\t/^.          88  WS-ABBRUCH-DB       VALUE 93.$/;\"\td\tdata:WS-ABBRUCH-TYP\troles:def\nWS-ABBRUCH-PGM\tinput.cbl\t/^.          88  WS-ABBRUCH-PGM      VALUE 94.$/;\"\td\tdata:WS-ABBRUCH-TYP\troles:def\nF-TEXT\tinput.cbl\t/^       01  F-TEXT.$/;\"\tg\troles:def\nF-TEXT-DB\tinput.cbl\t/^           05 F-TEXT-DB            PIC X(5).$/;\"\td\tgroup:F-TEXT\troles:def\nF-TEXT-KEY1\tinput.cbl\t/^           05 F-TEXT-KEY1          PIC 9(8).$/;\"\td\tgroup:F-TEXT\troles:def\nF-TEXT-KEY2\tinput.cbl\t/^           05 F-TEXT-KEY2          PIC 9(8).$/;\"\td\tgroup:F-TEXT\troles:def\nF-TEXT-KEY3\tinput.cbl\t/^           05 F-TEXT-KEY3          PIC 99.$/;\"\td\tgroup:F-TEXT\troles:def\nF-TEXT-EVENT\tinput.cbl\t/^           05 F-TEXT-EVENT         PIC X(10).$/;\"\td\tgroup:F-TEXT\troles:def\nTCTOENV\tinput.cbl\t/^       COPY TCTOENV.$/;\"\tS\troles:copied\nTCWFLENG\tinput.cbl\t/^       COPY TCWFLENG.$/;\"\tS\troles:copied\nTCPR\tinput.cbl\t/^       COPY TCPR.$/;\"\tS\troles:copied\nLINKAGE\tinput.cbl\t/^       LINKAGE SECTION.$/;\"\ts\troles:def\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\troles:def\nMAIN\tinput.cbl\t/^       MAIN SECTION.$/;\"\ts\troles:def\nMAIN-EX\tinput.cbl\t/^       MAIN-EX. EXIT.$/;\"\tp\troles:def\nE01-PRUEFEN\tinput.cbl\t/^       E01-PRUEFEN SECTION.$/;\"\ts\troles:def\nM01-VORLAUF\tinput.cbl\t/^       M01-VORLAUF SECTION.$/;\"\ts\troles:def\nM01-VORLAUF-EX\tinput.cbl\t/^       M01-VORLAUF-EX.$/;\"\tp\troles:def\nM02-NACHLAUF\tinput.cbl\t/^       M02-NACHLAUF SECTION.$/;\"\ts\troles:def\nM02-NACHLAUF-EX\tinput.cbl\t/^       M02-NACHLAUF-EX.$/;\"\tp\troles:def\nM99-ABBRUCH\tinput.cbl\t/^       M99-ABBRUCH SECTION.$/;\"\ts\troles:def\nM99-ABBRUCH-EX\tinput.cbl\t/^       M99-ABBRUCH-EX. EXIT.$/;\"\tp\troles:def\n"
  },
  {
    "path": "Units/parser-cobol.r/issue-1324.d/input.cbl",
    "content": "       IDENTIFICATION DIVISION.\n           EXEC TAA IDENTIFY EFUN SERVICE\n                FAWEFUN-11 IN FAW\n           END-EXEC.\n      *\n       ENVIRONMENT DIVISION.\n       CONFIGURATION SECTION.\n       SPECIAL-NAMES.\n           DECIMAL-POINT IS COMMA.\n      *\n       DATA DIVISION.\n      *\n       WORKING-STORAGE SECTION.\n      *\n       01  WS-ABBRUCH-TYP          PIC 99.\n           88  WS-ABBRUCH-EVENT    VALUE 91.\n.          88  WS-ABBRUCH-OBJMGR   VALUE 92.\n.          88  WS-ABBRUCH-DB       VALUE 93.\n.          88  WS-ABBRUCH-PGM      VALUE 94.\n       01  F-TEXT.\n           05 F-TEXT-DB            PIC X(5).\n           05 FILLER               PIC X VALUE SPACE.\n           05 F-TEXT-KEY1          PIC 9(8).\n           05 FILLER               PIC X VALUE '/'.\n           05 F-TEXT-KEY2          PIC 9(8).\n           05 FILLER               PIC X VALUE '/'.\n           05 F-TEXT-KEY3          PIC 99.\n           05 FILLER               PIC X(7) VALUE ' EVENT:'.\n           05 F-TEXT-EVENT         PIC X(10).\n      *\n       COPY TCTOENV.\n       COPY TCWFLENG.\n       COPY TCPR.\n\n       LINKAGE SECTION.\n      *\n       PROCEDURE DIVISION.\n      *\n       MAIN SECTION.\n           EXEC TAA REGISTER END-EXEC\n\n\n           EXEC TAA ON SEVERE EXIT ARBG END-EXEC\n\n\n           PERFORM M01-VORLAUF\n\n\n           EVALUATE TRUE\n               WHEN TC-EVENT-PRUEFEN OF ME\n                    PERFORM E01-PRUEFEN\n                    SET TC-STATE-OK OF ME TO TRUE\n               WHEN OTHER\n                    SET WS-ABBRUCH-EVENT TO TRUE\n                    PERFORM M99-ABBRUCH\n           END-EVALUATE\n\n\n           PERFORM M02-NACHLAUF\n\n\n           EXEC TAA UNREGISTER END-EXEC\n      *\n           CONTINUE.\n       MAIN-EX. EXIT.\n      *\n       E01-PRUEFEN SECTION.\n           EXIT.\n      *\n       M01-VORLAUF SECTION.\n           CONTINUE.\n       M01-VORLAUF-EX.\n           EXIT.\n      *\n       M02-NACHLAUF SECTION.\n           CONTINUE.\n       M02-NACHLAUF-EX.\n           EXIT.\n      *\n       M99-ABBRUCH SECTION.\n           EVALUATE TRUE\n               WHEN WS-ABBRUCH-OBJMGR\n                   EXEC TAA\n                       SET AND RAISE SEVERE\n                       GROUP OMERR\n                       CODE 0\n                   END-EXEC\n               WHEN WS-ABBRUCH-EVENT\n                   EXEC TAA\n                       SET SEVERE\n                       GROUP AAEZUG01\n                       CODE 2\n                       ARGUMENTS = (TC-EVENT)\n                   END-EXEC\n                   EXEC TAA\n                       SET AND RAISE SEVERE\n                       GROUP USERERR\n                       CODE 1\n                   END-EXEC\n               WHEN WS-ABBRUCH-PGM\n                   EXEC TAA\n                       SET SEVERE\n                       GROUP AAEZUG01\n                       CODE 3\n                       ARGUMENTS = (TX-IM-SHORTNAME)\n                   END-EXEC\n                   EXEC TAA\n                       SET AND RAISE SEVERE\n                       GROUP USERERR\n                       CODE 1\n                   END-EXEC\n               WHEN OTHER\n                   EXEC TAA\n                       SET AND RAISE SEVERE\n                       GROUP USERERR\n                       CODE 0\n                   END-EXEC\n           END-EVALUATE\n           CONTINUE.\n       M99-ABBRUCH-EX. EXIT.\n"
  },
  {
    "path": "Units/parser-cobol.r/levels.d/expected.tags",
    "content": "DATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nEVEN\tinput.cbl\t/^                     88 EVEN VALUES 2, 4, 6, 8.$/;\"\td\tdata:RECORD1.ITEM2\nG1\tinput.cbl\t/^              02 G1.$/;\"\tg\tgroup:REC2\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nITEM1\tinput.cbl\t/^                     05 ITEM1 PICTURE X(10).$/;\"\td\tgroup:REC2.G1\nITEM1\tinput.cbl\t/^              05 ITEM1 PIC X(1).$/;\"\td\tgroup:RECORD1\nITEM2\tinput.cbl\t/^                     05 ITEM2 PIC X(10).$/;\"\td\tgroup:REC2.G1\nITEM2\tinput.cbl\t/^              05 ITEM2 PIC A(1).$/;\"\td\tgroup:RECORD1\nITEM3\tinput.cbl\t/^              05 ITEM3 PIC X(6).$/;\"\td\tgroup:RECORD1\nMAIN-PROCEDURE\tinput.cbl\t/^       MAIN-PROCEDURE.$/;\"\tp\nODD\tinput.cbl\t/^                     88 ODD VALUES 1, 3, 5, 7, 9.$/;\"\td\tdata:RECORD1.ITEM2\nOTHERNAME1\tinput.cbl\t/^              66 OTHERNAME1 RENAMES ITEM1 IN REC2.$/;\"\td\tgroup:REC2\nOTHERNAME2\tinput.cbl\t/^              66 OTHERNAME2 RENAMES G1.$/;\"\td\tgroup:REC2\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\nRDITEM4\tinput.cbl\t/^              66 RDITEM4 RENAMES ITEM1 THRU ITEM2.$/;\"\td\tgroup:RECORD1\nRDITEM5\tinput.cbl\t/^              66 RDITEM5 RENAMES ITEM1 THROUGH ITEM3.$/;\"\td\tgroup:RECORD1\nREC2\tinput.cbl\t/^       01 REC2.$/;\"\tg\nRECORD1\tinput.cbl\t/^       01 RECORD1.$/;\"\tg\nSTDLN1\tinput.cbl\t/^       77 STDLN1 PIC A(4).$/;\"\td\nTest-Items\tinput.cbl\t/^       PROGRAM-ID. Test-Items.$/;\"\tP\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol.r/levels.d/input.cbl",
    "content": "       IDENTIFICATION DIVISION.\n       PROGRAM-ID. Test-Items.\n\n       DATA DIVISION.\n       WORKING-STORAGE SECTION.\n       01 RECORD1.\n              05 ITEM1 PIC X(1).\n              05 ITEM2 PIC A(1).\n                     88 ODD VALUES 1, 3, 5, 7, 9.\n                     88 EVEN VALUES 2, 4, 6, 8.\n              05 ITEM3 PIC X(6).\n              66 RDITEM4 RENAMES ITEM1 THRU ITEM2.\n              66 RDITEM5 RENAMES ITEM1 THROUGH ITEM3.\n       77 STDLN1 PIC A(4).\n       01 REC2.\n              02 G1.\n                     05 ITEM1 PICTURE X(10).\n                     05 ITEM2 PIC X(10).\n              66 OTHERNAME1 RENAMES ITEM1 IN REC2.\n              66 OTHERNAME2 RENAMES G1.\n\n       PROCEDURE DIVISION.\n       MAIN-PROCEDURE.\n            DISPLAY \"Hello world\".\n            DISPLAY OTHERNAME2.\n            STOP RUN.\n       END PROGRAM Test-Items.\n"
  },
  {
    "path": "Units/parser-cobol.r/quoted-program-id.cbl.d/expected.tags",
    "content": "IDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nMAIN\tinput.cbl\t/^       MAIN.$/;\"\tp\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\nTest program name\tinput.cbl\t/^       PROGRAM-ID. 'Test program name'.$/;\"\tP\n"
  },
  {
    "path": "Units/parser-cobol.r/quoted-program-id.cbl.d/input.cbl",
    "content": "       IDENTIFICATION DIVISION.\n       PROGRAM-ID. 'Test program name'.\n       PROCEDURE DIVISION.\n       MAIN.\n           DISPLAY 'This is a test program'.\n       STOP RUN.\n       END PROGRAM 'Test program name'.\n"
  },
  {
    "path": "Units/parser-cobol.r/simple.cbl.d/expected.tags",
    "content": "AUTHOR\tinput.cbl\t/^       AUTHOR. Darren Hiebert.$/;\"\tp\nBegin\tinput.cbl\t/^       Begin.$/;\"\tp\nDATA\tinput.cbl\t/^       DATA DIVISION.$/;\"\tD\nDW-DAYS-IN-MONTH\tinput.cbl\t/^             05  DW-DAYS-IN-MONTH   OCCURS 12 TIMES$/;\"\td\tdata:Group-Name.Data-Item1.DW-DAYS-IN-MONTHS\nDW-DAYS-IN-MONTHS\tinput.cbl\t/^           03  DW-DAYS-IN-MONTHS    VALUE \"312831303130313130313031\".$/;\"\td\tdata:Group-Name.Data-Item1\nData-Item1\tinput.cbl\t/^         02 Data-Item1              PIC 9 VALUE ZEROS.$/;\"\td\tgroup:Group-Name\nENVIRONMENT\tinput.cbl\t/^       ENVIRONMENT DIVISION.$/;\"\tD\nFILE\tinput.cbl\t/^       FILE SECTION.$/;\"\ts\nFILE-CONTROL\tinput.cbl\t/^       FILE-CONTROL.$/;\"\tp\nFile-Data-Item\tinput.cbl\t/^         02 File-Data-Item          PIC 9(7).$/;\"\td\tgroup:File-Group-Name\nFile-Group-Name\tinput.cbl\t/^       01 File-Group-Name.$/;\"\tg\nFile-Name\tinput.cbl\t/^       FD File-Name.$/;\"\tf\nGroup-Name\tinput.cbl\t/^       01 Group-Name.$/;\"\tg\nIDENTIFICATION\tinput.cbl\t/^       IDENTIFICATION DIVISION.$/;\"\tD\nINPUT-OUPUT\tinput.cbl\t/^       INPUT-OUPUT SECTION.$/;\"\ts\nPROCEDURE\tinput.cbl\t/^       PROCEDURE DIVISION.$/;\"\tD\nProgram-Name\tinput.cbl\t/^       PROGRAM-ID. Program-Name.$/;\"\tP\nSH-WORK-MMDDYYYY\tinput.cbl\t/^           03 SH-WORK-MMDDYYYY      PIC  9(08)  VALUE 0.$/;\"\td\tdata:Group-Name.Data-Item1\nSH-WORK-MMDDYYYY-2\tinput.cbl\t/^           03 SH-WORK-MMDDYYYY-2    REDEFINES SH-WORK-MMDDYYYY.$/;\"\td\tdata:Group-Name.Data-Item1\nSubprogram-Name\tinput.cbl\t/^       Subprogram-Name.$/;\"\tp\nWORKING-STORAGE\tinput.cbl\t/^       WORKING-STORAGE SECTION.$/;\"\ts\n"
  },
  {
    "path": "Units/parser-cobol.r/simple.cbl.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/parser-cobol.r/simple.cbl.d/input.cbl",
    "content": "       IDENTIFICATION DIVISION.\n       PROGRAM-ID. Program-Name.\n       AUTHOR. Darren Hiebert.\n\n       ENVIRONMENT DIVISION.\n       INPUT-OUPUT SECTION.\n       FILE-CONTROL.\n           SELECT File-Name ASSIGN TO \"SAMPLE.DAT\"\n                ORGANIZATION IS LINE SEQUENTIAL.\n\n       DATA DIVISION.\n       FILE SECTION.\n       FD File-Name.\n       01 File-Group-Name.\n         02 File-Data-Item          PIC 9(7).\n\n       WORKING-STORAGE SECTION.\n       01 Group-Name.\n         02 Data-Item1              PIC 9 VALUE ZEROS.\n           03 SH-WORK-MMDDYYYY      PIC  9(08)  VALUE 0.\n           03 SH-WORK-MMDDYYYY-2    REDEFINES SH-WORK-MMDDYYYY.\n           03  DW-DAYS-IN-MONTHS    VALUE \"312831303130313130313031\".\n             05  DW-DAYS-IN-MONTH   OCCURS 12 TIMES\n                                        PIC  9(02).\n\n       PROCEDURE DIVISION.\n       Begin.\n           STOP RUN.\n\n       Subprogram-Name.\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/args.ctags",
    "content": "--sort=no\n--fields=+lE\n--extras=+g\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/expected.tags",
    "content": "DO_NOTHING_\tinput.c\t/^\t.macro\tDO_NOTHING_$/;\"\tm\tlanguage:Asm\textras:guest\nDO_NOTHING_0\tinput-0.c\t/^\t.macro\tDO_NOTHING_0$/;\"\tm\tlanguage:Asm\textras:guest\ndo_nothing_1\tinput-1.c\t/^inline void do_nothing_1(void) {}$/;\"\tf\tlanguage:C\ttyperef:typename:void\ndo_nothing_2\tinput-2.c\t/^\tinline void do_nothing_2 (void) {}$/;\"\tf\tlanguage:C\ttyperef:typename:void\nDO_NOTHING_2\tinput-2.c\t/^\t.macro\tDO_NOTHING_2$/;\"\tm\tlanguage:Asm\textras:guest\ndo_nothing_3a\tinput-3.c\t/^\tinline void do_nothing_3a (void) {}$/;\"\tf\tlanguage:C\ttyperef:typename:void\ndo_nothing_3b\tinput-3.c\t/^\tinline void do_nothing_3b (void) {}$/;\"\tf\tlanguage:C\ttyperef:typename:void\nDO_NOTHING_3\tinput-3.c\t/^\t.macro\tDO_NOTHING_3$/;\"\tm\tlanguage:Asm\textras:guest\ndo_nothing_4a\tinput-4.c\t/^\tinline void do_nothing_4a (void) {}$/;\"\tf\tlanguage:C\ttyperef:typename:void\ndo_nothing_4b\tinput-4.c\t/^\tinline void do_nothing_4b (void) {}$/;\"\tf\tlanguage:C\ttyperef:typename:void\nDO_NOTHING_4\tinput-4.c\t/^\t.macro\tDO_NOTHING_4$/;\"\tm\tlanguage:Asm\textras:guest\ndo_nothing_5\tinput-5.c\t/^inline void do_nothing_5(void) {}$/;\"\tf\tlanguage:C\ttyperef:typename:void\nDO_NOTHING_5\tinput-5.c\t/^\t.macro\tDO_NOTHING_5$/;\"\tm\tlanguage:Asm\textras:guest\ndo_nothing_6\tinput-6.c\t/^inline void do_nothing_6(void) {}$/;\"\tf\tlanguage:C\ttyperef:typename:void\nDO_NOTHING_7_NO_GUEST\tinput-7.asm\t/^.macro\tDO_NOTHING_7_NO_GUEST$/;\"\tm\tlanguage:Asm\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/input-0.c",
    "content": "#ifdef __ASSEMBLER__\n\n\t.macro\tDO_NOTHING_0\n\t nop\n\t.endm\n\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/input-1.c",
    "content": "#ifndef __ASSEMBLER__\n\ninline void do_nothing_1(void) {}\n\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/input-2.c",
    "content": "#if __ASSEMBLER__\n\n\t.macro\tDO_NOTHING_2\n\t nop\n\t.endm\n\n#else\n\n\tinline void do_nothing_2 (void) {}\n\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/input-3.c",
    "content": "#if __ASSEMBLER__\n\n\t.macro\tDO_NOTHING_3\n\t nop\n\t.endm\n\n#elif CONDITION3\n\n\tinline void do_nothing_3a (void) {}\n\n#else\n\n\tinline void do_nothing_3b (void) {}\n\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/input-4.c",
    "content": "#ifdef __ASSEMBLER__\n\n\t.macro\tDO_NOTHING_4\n\t nop\n\t.endm\n\n#elif CONDITION4\n\n\tinline void do_nothing_4a (void) {}\n\n#else\n\n\tinline void do_nothing_4b (void) {}\n\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/input-5.c",
    "content": "#ifndef __ASSEMBLER__\n\ninline void do_nothing_5(void) {}\n\n#else\n\n\t.macro\tDO_NOTHING_5\n\t nop\n\t.endm\n\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/input-6.c",
    "content": "#ifndef __ASSEMBLER__\n\ninline void do_nothing_6(void) {}\n\n#elif CONDITION5\n\n\t.macro\tDO_NOTHING_6a_this_cannot_be_tagged\n\t nop\n\t.endm\n\n#else\n\n\t.macro\tDO_NOTHING_6b_this_cannot_be_tagged\n\t nop\n\t.endm\n\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/input-7.asm",
    "content": "#ifdef __ASSEMBLER__\n\n.macro\tDO_NOTHING_7_NO_GUEST\n nop\n.endm\n\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/asm-area.d/input.c",
    "content": "#if __ASSEMBLER__\n\n\t.macro\tDO_NOTHING_\n\t nop\n\t.endm\n\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/backslash-in-parameters.d/args.ctags",
    "content": "--sort=no\n--fields=+Sn\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/backslash-in-parameters.d/expected.tags",
    "content": "IX_GET_BIT_FIELD16\tinput.h\t/^#define IX_GET_BIT_FIELD16(/;\"\td\tline:2\tsignature:(arg_PackedData16,arg_FieldLSBBit,arg_FieldMSBBit)\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/backslash-in-parameters.d/input.h",
    "content": "/* Taken from u-boot */\n#define IX_GET_BIT_FIELD16(\t\t\t\t\t  \\\n                            arg_PackedData16, \\\n                            arg_FieldLSBBit, \\\n                            arg_FieldMSBBit \\\n                          ) \\\n                          (((ix_uint16)(arg_PackedData16) & IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) >> \\\n                             arg_FieldLSBBit)\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/capture-params-in-macro-defs.d/args.ctags",
    "content": "--sort=no\n--language-force=CPreProcessor\n--kinds-CPreProcessor=+D\n--fields=+Sn\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/capture-params-in-macro-defs.d/expected.tags",
    "content": "arg_PackedData16\tinput.h\t/^                            arg_PackedData16, \\\\$/;\"\tD\tline:3\tmacro:IX_GET_BIT_FIELD16\narg_FieldLSBBit\tinput.h\t/^                            arg_FieldLSBBit, \\\\$/;\"\tD\tline:4\tmacro:IX_GET_BIT_FIELD16\narg_FieldMSBBit\tinput.h\t/^                            arg_FieldMSBBit \\\\$/;\"\tD\tline:5\tmacro:IX_GET_BIT_FIELD16\nIX_GET_BIT_FIELD16\tinput.h\t/^#define IX_GET_BIT_FIELD16(/;\"\td\tline:2\tsignature:(arg_PackedData16,arg_FieldLSBBit,arg_FieldMSBBit)\nM0\tinput.h\t/^#define M0(/;\"\td\tline:10\tsignature:()\nX\tinput.h\t/^#define M1(X) 1 + X$/;\"\tD\tline:11\tmacro:M1\nM1\tinput.h\t/^#define M1(/;\"\td\tline:11\tsignature:(X)\nX\tinput.h\t/^#define M2(X,Y) 1 + X + Y$/;\"\tD\tline:12\tmacro:M2\nY\tinput.h\t/^#define M2(X,Y) 1 + X + Y$/;\"\tD\tline:12\tmacro:M2\nM2\tinput.h\t/^#define M2(/;\"\td\tline:12\tsignature:(X,Y)\nX\tinput.h\t/^#define M3(X,Y,Z) 1 + X + Y + Z$/;\"\tD\tline:13\tmacro:M3\nY\tinput.h\t/^#define M3(X,Y,Z) 1 + X + Y + Z$/;\"\tD\tline:13\tmacro:M3\nZ\tinput.h\t/^#define M3(X,Y,Z) 1 + X + Y + Z$/;\"\tD\tline:13\tmacro:M3\nM3\tinput.h\t/^#define M3(/;\"\td\tline:13\tsignature:(X,Y,Z)\nX\tinput.h\t/^#define Mn(X,Y,Z,...) 1 + X + Y + Z$/;\"\tD\tline:14\tmacro:Mn\nY\tinput.h\t/^#define Mn(X,Y,Z,...) 1 + X + Y + Z$/;\"\tD\tline:14\tmacro:Mn\nZ\tinput.h\t/^#define Mn(X,Y,Z,...) 1 + X + Y + Z$/;\"\tD\tline:14\tmacro:Mn\nMn\tinput.h\t/^#define Mn(/;\"\td\tline:14\tsignature:(X,Y,Z,...)\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/capture-params-in-macro-defs.d/input.h",
    "content": "/* Taken from u-boot */\n#define IX_GET_BIT_FIELD16(\t\t\t\t\t  \\\n                            arg_PackedData16, \\\n                            arg_FieldLSBBit, \\\n                            arg_FieldMSBBit \\\n                          ) \\\n                          (((ix_uint16)(arg_PackedData16) & IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) >> \\\n                             arg_FieldLSBBit)\n\n#define M0() 1\n#define M1(X) 1 + X\n#define M2(X,Y) 1 + X + Y\n#define M3(X,Y,Z) 1 + X + Y + Z\n#define Mn(X,Y,Z,...) 1 + X + Y + Z\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client--clinet-kind.d/README",
    "content": "See #1514.\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client--clinet-kind.d/args.ctags",
    "content": "--languages=-CPreProcessor\n--kinds-C=-d\n\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client--clinet-kind.d/expected.tags",
    "content": "main\tinput.c\t/^main(int argc)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client--clinet-kind.d/input.c",
    "content": "#define X 1\n\nint\nmain(int argc)\n{\n       return X;\n}\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client--cpp-kind.d/README",
    "content": "See #1514.\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client--cpp-kind.d/args.ctags",
    "content": "--languages=-CPreProcessor\n--kinds-CPreProcessor=-d\n\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client--cpp-kind.d/expected.tags",
    "content": "X\tinput.c\t/^#define X /;\"\td\tfile:\nmain\tinput.c\t/^main(int argc)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client--cpp-kind.d/input.c",
    "content": "#define X 1\n\nint\nmain(int argc)\n{\n       return X;\n}\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client.d/README",
    "content": "See #1514.\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client.d/args.ctags",
    "content": "--languages=-CPreProcessor\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client.d/expected.tags",
    "content": "X\tinput.c\t/^#define X /;\"\td\tfile:\nmain\tinput.c\t/^main(int argc)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-client.d/input.c",
    "content": "#define X 1\n\nint\nmain(int argc)\n{\n       return X;\n}\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-cpp.d/args.ctags",
    "content": "--languages=-CPreProcessor\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-cpp.d/expected.tags",
    "content": "0x00\tinput.dts\t/^\t     phandle = <0x00>;$/;\"\tp\tlabel:label\nlabel\tinput.dts\t/^label: test {$/;\"\tl\nlabel2\tinput.dts\t/^\t     label2: chosen { } ;$/;\"\tl\tlabel:label\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/disable-cpp-cpp.d/input.dts",
    "content": "/dts-v1/;\n\n#include \"foo.dtsi\"\n#define bar 98\n\nlabel: test {\n       dummy {\n\t     label2: chosen { } ;\n\t     phandle = <0x00>;\n       };\n};\n#undef bar\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/if0-false-with-param.c.d/args.ctags",
    "content": "--param-CPreProcessor.if0=false\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/if0-false-with-param.c.d/expected.tags",
    "content": "y\tinput.c\t/^int y;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/if0-false-with-param.c.d/input.c",
    "content": "#if 0\nint x;\n#else\nint y;\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/if0-true-with-param.c.d/args.ctags",
    "content": "--param-CPreProcessor.if0=true\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/if0-true-with-param.c.d/expected.tags",
    "content": "x\tinput.c\t/^int x;$/;\"\tv\ttyperef:typename:int\ny\tinput.c\t/^int y;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/if0-true-with-param.c.d/input.c",
    "content": "#if 0\nint x;\n#else\nint y;\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macro-condition-role.d/args.ctags",
    "content": "--sort=no\n--roles-C++.{macro}=+{condition}\n--extras=+r\n--fields=+rn\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macro-condition-role.d/expected.tags",
    "content": "X0\tinput.h\t/^#ifdef X0$/;\"\td\tline:1\troles:condition\nHAVE_FEAT\tinput.h\t/^#if defined HAVE_FEAT && (Y_2k1 && _0Z \\\\$/;\"\td\tline:2\troles:condition\nY_2k1\tinput.h\t/^#if defined HAVE_FEAT && (Y_2k1 && _0Z \\\\$/;\"\td\tline:2\troles:condition\n_0Z\tinput.h\t/^#if defined HAVE_FEAT && (Y_2k1 && _0Z \\\\$/;\"\td\tline:2\troles:condition\n_A_0_\tinput.h\t/^\t\t\t\t\t\t  || \\/* C *\\/ _A_0_)$/;\"\td\tline:3\troles:condition\nX1\tinput.h\t/^#ifndef X1$/;\"\td\tline:5\troles:condition\nY1\tinput.h\t/^#elif Y1$/;\"\td\tline:7\troles:condition\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macro-condition-role.d/input.h",
    "content": "#ifdef X0\n#if defined HAVE_FEAT && (Y_2k1 && _0Z \\\n\t\t\t\t\t\t  || /* C */ _A_0_)\nextern\n#ifndef X1\nint\n#elif Y1\nlong\n#else\nshort\n#endif\nx;\n#endif\n#endif\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macrodef.d/args.ctags",
    "content": "--language-force=CPreProcessor\n--sort=no\n--fields-CPreProcessor=+{macrodef}\n--fields=+Sl\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macrodef.d/expected.tags",
    "content": "INT\tinput.h\t/^#define INT /;\"\td\tlanguage:CPreProcessor\tmacrodef:1\nSTR\tinput.h\t/^#define STR /;\"\td\tlanguage:CPreProcessor\tmacrodef:\"bar\"\nCHR\tinput.h\t/^#define CHR /;\"\td\tlanguage:CPreProcessor\tmacrodef:'b'\nHEX\tinput.h\t/^#define HEX /;\"\td\tlanguage:CPreProcessor\tmacrodef:0xff01\nOCT\tinput.h\t/^#define OCT /;\"\td\tlanguage:CPreProcessor\tmacrodef:0644\nSYSCALL_METADATA\tinput.h\t/^#define SYSCALL_METADATA(/;\"\td\tlanguage:CPreProcessor\tsignature:(sname,nb,...)\tmacrodef:\nSYSCALL_DEFINE2\tinput.h\t/^#define SYSCALL_DEFINE2(/;\"\td\tlanguage:CPreProcessor\tsignature:(name,...)\tmacrodef:SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)\nSYSCALL_DEFINEx\tinput.h\t/^#define SYSCALL_DEFINEx(/;\"\td\tlanguage:CPreProcessor\tsignature:(x,sname,...)\tmacrodef:SYSCALL_METADATA(sname, x, __VA_ARGS__) __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)\n__SYSCALL_DEFINEx\tinput.h\t/^#define __SYSCALL_DEFINEx(/;\"\td\tlanguage:CPreProcessor\tsignature:(x,name,...)\tmacrodef:__diag_push(); __diag_ignore(GCC, 8, \"-Wattribute-alias\", \"Type aliasing is used to sanitize syscall arguments\"); asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) __attribute__((alias(__stringify(__se_sys##name)))); ALLOW_ERROR_INJECTION(sys##name, ERRNO); static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) { long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__)); __MAP(x,__SC_TEST,__VA_ARGS__); __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); return ret; } __diag_pop(); static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\n__MAP1\tinput.h\t/^#define __MAP1(/;\"\td\tlanguage:CPreProcessor\tsignature:(m,t,a,...)\tmacrodef:m(t,a)\n__MAP2\tinput.h\t/^#define __MAP2(/;\"\td\tlanguage:CPreProcessor\tsignature:(m,t,a,...)\tmacrodef:m(t,a), __MAP1(m,__VA_ARGS__)\n__MAP\tinput.h\t/^#define __MAP(n,...) __MAP#/;\"\td\tlanguage:CPreProcessor\tsignature:(n,...)\tmacrodef:__MAP##n(__VA_ARGS__)\n__SC_DECL\tinput.h\t/^#define __SC_DECL(/;\"\td\tlanguage:CPreProcessor\tsignature:(t,a)\tmacrodef:t a\nslash_fn\tinput.h\t/^#define slash_fn(/;\"\td\tlanguage:CPreProcessor\tsignature:(t)\tmacrodef:t fn (t i, t j) { return i / j; }\nquestion_fn\tinput.h\t/^#define question_fn(/;\"\td\tlanguage:CPreProcessor\tsignature:(t)\tmacrodef:t fn (t i, t j) { return (i < j)? i: j; }\nfinally\tinput.h\t/^#define finally(/;\"\td\tlanguage:CPreProcessor\tsignature:(X)\tmacrodef:int fin_##X(void) { return 0; } \n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macrodef.d/input.h",
    "content": "#define INT 1\n#define STR \"bar\"\n#define CHR 'b'\n#define HEX 0xff01\n#define OCT 0644\n\n/*\n * Taken from linux kernel\n */\n#define SYSCALL_METADATA(sname, nb, ...)\n#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)\n#define SYSCALL_DEFINEx(x, sname, ...)\t\t\t\t\\\n\tSYSCALL_METADATA(sname, x, __VA_ARGS__)\t\t\t\\\n\t__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)\n\n/*\n * The asmlinkage stub is aliased to a function named __se_sys_*() which\n * sign-extends 32-bit ints to longs whenever needed. The actual work is\n * done within __do_sys_*().\n */\n#define __SYSCALL_DEFINEx(x, name, ...)\t\t\t\t\t\\\n\t__diag_push();\t\t\t\t\t\t\t\\\n\t__diag_ignore(GCC, 8, \"-Wattribute-alias\",\t\t\t\\\n\t\t      \"Type aliasing is used to sanitize syscall arguments\");\\\n\tasmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\t\\\n\t\t__attribute__((alias(__stringify(__se_sys##name))));\t\\\n\tALLOW_ERROR_INJECTION(sys##name, ERRNO);\t\t\t\\\n\tstatic inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\\\n\tasmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));\t\\\n\tasmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tlong ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\\\n\t\t__MAP(x,__SC_TEST,__VA_ARGS__);\t\t\t\t\\\n\t\t__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__));\t\\\n\t\treturn ret;\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\t__diag_pop();\t\t\t\t\t\t\t\\\n\tstatic inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\n\n#define __MAP1(m,t,a,...) m(t,a)\n#define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__)\n#define __MAP(n,...) __MAP##n(__VA_ARGS__)\n\n#define __SC_DECL(t, a)\tt a\n\nSYSCALL_DEFINE2(setregid16, old_gid_t, rgid, old_gid_t, egid)\n{\n\treturn __sys_setregid(low2highgid(rgid), low2highgid(egid));\n}\n\n#define slash_fn(t) t fn (t i, t j) {\t\t\t\\\n\treturn i / j;\t\t\t\t\t\t\t\t\\\n}\n\n#define question_fn(t) t fn (t i, t j) {\t\t\\\n\treturn (i < j)? i: j;\t\t\t\t\t\t\\\n}\n\n#define finally(X) \\\n\tint fin_##X(void) { return 0; } \\\n\\\n\t\\\n\\\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macroexpand.d/args.ctags",
    "content": "--param-CPreProcessor._expand=1\n--fields-C=+{macrodef}\n--fields=+Ss\n--sort=no\n# Override the defintion in the input file.\n-DS=float\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macroexpand.d/expected.tags",
    "content": "defStruct\tinput.c\t/^#define defStruct(/;\"\td\tfile:\tsignature:(PREFIX,X)\tmacrodef:struct PREFIX##X\nbegin\tinput.c\t/^#define begin /;\"\td\tfile:\tmacrodef:{\ndefField\tinput.c\t/^#define defField(/;\"\td\tfile:\tsignature:(PREFIX,T,F)\tmacrodef:T PREFIX##F;\nendf\tinput.c\t/^#define endf /;\"\td\tfile:\tmacrodef:;\nends\tinput.c\t/^#define ends /;\"\td\tfile:\tmacrodef:};\nmydefs\tinput.c\t/^#define mydefs(/;\"\td\tfile:\tsignature:(X)\tmacrodef:defStruct(my_,X)\nmydeff\tinput.c\t/^#define mydeff(/;\"\td\tfile:\tsignature:(T,Y)\tmacrodef:defField(my_,T,Y)\nyour_point\tinput.c\t/^defStruct(your_,point) begin$/;\"\ts\tfile:\nyour_x\tinput.c\t/^  defField(your_,int, x) endf$/;\"\tm\tstruct:your_point\ttyperef:typename:int\tfile:\nyour_y\tinput.c\t/^  defField(your_,int, y) endf$/;\"\tm\tstruct:your_point\ttyperef:typename:int\tfile:\nmy_point3d\tinput.c\t/^mydefs(point3d) begin$/;\"\ts\tfile:\nmy_x\tinput.c\t/^  mydeff(int, x) endf$/;\"\tm\tstruct:my_point3d\ttyperef:typename:int\tfile:\nmy_y\tinput.c\t/^  mydeff(int, y) endf$/;\"\tm\tstruct:my_point3d\ttyperef:typename:int\tfile:\nmy_z\tinput.c\t/^  mydeff(int, z) endf$/;\"\tm\tstruct:my_point3d\ttyperef:typename:int\tfile:\nT\tinput-0.c\t/^#define T /;\"\td\tfile:\tmacrodef:int\nmytype0\tinput-0.c\t/^typedef T mytype0;$/;\"\tt\ttyperef:typename:int\tfile:\nS\tinput-0.c\t/^#define S /;\"\td\tfile:\tmacrodef:int\nmytype1\tinput-0.c\t/^typedef S mytype1;$/;\"\tt\ttyperef:typename:float\tfile:\nIO7__POX_ERRSUM__UPE_ERROR\tinput-1.c\t/^#define IO7__POX_ERRSUM__UPE_ERROR        GEN_MASK(IO7__POX_ERRSUM__UPE_ERROR)/;\"\td\tfile:\tmacrodef:GEN_MASK(IO7__POX_ERRSUM__UPE_ERROR)\nf\tinput-1.c\t/^f(int err_sum)$/;\"\tf\ttyperef:typename:int\tsignature:(int err_sum)\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macroexpand.d/input-0.c",
    "content": "#define T int\ntypedef T mytype0;\n\n#define S int\ntypedef S mytype1;\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macroexpand.d/input-1.c",
    "content": "/* This code could trigger an infinite loop. */\n#define IO7__POX_ERRSUM__UPE_ERROR        GEN_MASK(IO7__POX_ERRSUM__UPE_ERROR)\nint\nf(int err_sum)\n{\n  if (err_sum & IO7__POX_ERRSUM__UPE_ERROR) {\n    return 0;\n  }\n}\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macroexpand.d/input.c",
    "content": "#define defStruct(PREFIX,X) struct PREFIX##X\n#define begin {\n#define defField(PREFIX,T, F) T PREFIX##F;\n#define endf ;\n#define ends };\n\n#define mydefs(X) defStruct(my_,X)\n#define mydeff(T,Y) defField(my_,T,Y)\n\ndefStruct(your_,point) begin\n  defField(your_,int, x) endf\n  defField(your_,int, y) endf\nends\n\nmydefs(point3d) begin\n  mydeff(int, x) endf\n  mydeff(int, y) endf\n  mydeff(int, z) endf\nends\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macros-specified-with-param.c.d/README",
    "content": "This case test is derrived from parser-c.r/macros.c.d.\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macros-specified-with-param.c.d/args.ctags",
    "content": "--kinds-c=+p\n--fields=+S\n--param-CPreProcessor.ignore=MACRO2\n--fields=+r\n--extras=+r\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macros-specified-with-param.c.d/expected.tags",
    "content": "DECL1\tinput.c\t/^DECL1(foo); \\/* gcc will accept this as function prototype (with some warnings) *\\/$/;\"\tp\tfile:\tsignature:(foo)\troles:def\nDECL3\tinput.c\t/^DECL3(x, y); \\/* gcc will accept this as function prototype (with some warnings) *\\/$/;\"\tp\tfile:\tsignature:(x,y)\troles:def\nFUNCTION_LIKE\tinput.c\t/^#define FUNCTION_LIKE(/;\"\td\tfile:\tsignature:(a,b)\troles:def\nFUNCTION_LIKE\tinput.c\t/^#undef FUNCTION_LIKE$/;\"\td\tfile:\troles:undef\nVARIABLE_LIKE\tinput.c\t/^#define VARIABLE_LIKE\t/;\"\td\tfile:\troles:def\nVARIABLE_LIKE\tinput.c\t/^#undef VARIABLE_LIKE$/;\"\td\tfile:\troles:undef\nWeakSymbol\tinput.c\t/^#pragma weak WeakSymbol /;\"\td\tfile:\troles:def\nprototype1\tinput.c\t/^void prototype1 __ARGS((int arg1, void *arg2));$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(int arg1,void * arg2)\troles:def\nprototype2\tinput.c\t/^void prototype2 __ARGS((int arg1, void *arg2))$/;\"\tf\ttyperef:typename:void\tsignature:(int arg1,void * arg2)\troles:def\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/macros-specified-with-param.c.d/input.c",
    "content": "#define VARIABLE_LIKE\tsome_value\n#define FUNCTION_LIKE(a,b)  (a + b)\n#pragma weak WeakSymbol = StrongSymbol\n\n/* handling of spoofing macros */\nDECL1(foo); /* gcc will accept this as function prototype (with some warnings) */\nMACRO2(bar);\nDECL3(x, y); /* gcc will accept this as function prototype (with some warnings) */\n\nvoid prototype1 __ARGS((int arg1, void *arg2));\nvoid prototype2 __ARGS((int arg1, void *arg2))\n{\n}\n#undef FUNCTION_LIKE\n#undef VARIABLE_LIKE\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/simple-cpreprocessor.d/args.ctags",
    "content": "--language-force=CPreProcessor\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/simple-cpreprocessor.d/expected.tags",
    "content": "X\tinput.c\t/^#define X /;\"\td\tfile:\troles:def\nstdio.h\tinput.c\t/^#include <stdio.h>/;\"\th\troles:system\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/simple-cpreprocessor.d/input.c",
    "content": "#define X 1\n#include <stdio.h>\n/*\n#define Y 2\n*/\n\n// #define Z 3\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/skip-newlines-in-literals.d/args.ctags",
    "content": "--sort=no\n--fields-C={macrodef}\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/skip-newlines-in-literals.d/expected.tags",
    "content": "X\tinput.c\t/^#define X /;\"\td\tfile:\tmacrodef:\"abc \\\\n\\\\t\\tefg\"\nY\tinput.c\t/^#define Y /;\"\td\tfile:\tmacrodef:\"abc\"\nA\tinput.c\t/^#define A /;\"\td\tfile:\tmacrodef:'a'\nB\tinput.c\t/^#define B /;\"\td\tfile:\tmacrodef:'b'\nC\tinput.c\t/^#define C /;\"\td\tfile:\tmacrodef:'\\\\n'\nD\tinput-0.c\t/^#define D \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;\"\td\tfile:\tmacrodef:\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalast\"\nE\tinput-0.c\t/^#define E \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;\"\td\tfile:\tmacrodef:\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaala\\\\n\"\nF\tinput-0.c\t/^#define F /;\"\td\tfile:\tmacrodef:\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalasS\"\nG\tinput-0.c\t/^#define G /;\"\td\tfile:\tmacrodef:\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalaSH\"\nH\tinput-0.c\t/^#define H /;\"\td\tfile:\tmacrodef:\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalasS\"\nJ\tinput-1.c\t/^#define J /;\"\td\tfile:\tmacrodef:'aaaaaalast'\nK\tinput-1.c\t/^#define K /;\"\td\tfile:\tmacrodef:'aaaaaalast'\nL\tinput-1.c\t/^#define L /;\"\td\tfile:\tmacrodef:'aaaaaalast'\nM\tinput-1.c\t/^#define M /;\"\td\tfile:\tmacrodef:'aaaaaala\\\\n'\nN\tinput-1.c\t/^#define N /;\"\td\tfile:\tmacrodef:'aaaaaalast'\nO\tinput-1.c\t/^#define O /;\"\td\tfile:\tmacrodef:'aaaaaalaxx'\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/skip-newlines-in-literals.d/input-0.c",
    "content": "#define D \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalastSHOULDBEINCLUDE\"\n#define E \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaala\\nSHOULDBEINCLUDE\"\n#define F \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalas\\nSHOULDBEINCLUDE\"\n\n#define G \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaala\\\nSHOULDBEINCLUDE\"\n#define H \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalas\\\nSHOULDBEINCLUDE\"\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/skip-newlines-in-literals.d/input-1.c",
    "content": "#define J 'aaaaaalastSHOULDNOTBETAGGED'\n#define K 'aaaaaalast\\n'\n#define L 'aaaaaalas\\nt'\n#define M 'aaaaaala\\nxx'\n#define N 'aaaaaalas\\\nt'\n#define O 'aaaaaala\\\nxx'\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/skip-newlines-in-literals.d/input.c",
    "content": "#define X \"abc \\n\\t\\\n\tefg\"\n#define Y \"abc\"\n\n#define A '\\\na'\n\n#define B 'b'\n#define C '\\n'\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-mbyte-string.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-mbyte-string.d/input-0.lds",
    "content": "i\"犬\"\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-mbyte-string.d/input-1.java",
    "content": "a(i'犬'\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-mbyte-string.d/input-2.lds",
    "content": "i'犬'\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-mbyte-string.d/input-3.java",
    "content": "a(i\"犬猫鼠羊兎鶏牛熊\"\n  /* Push back a logger string */\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-mbyte-string.d/input.java",
    "content": "a(i\"犬\"\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-multi-bytes-string.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-multi-bytes-string.d/input-0.lds",
    "content": "i\"犬\"\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-multi-bytes-string.d/input-1.java",
    "content": "a(i'犬'\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-multi-bytes-string.d/input-2.lds",
    "content": "i'犬'\n"
  },
  {
    "path": "Units/parser-cpreprocessor.r/unget-multi-bytes-string.d/input.java",
    "content": "a(i\"犬\"\n"
  },
  {
    "path": "Units/parser-csharp.r/nullable-parameters.d/args.ctags",
    "content": "--sort=no\n--fields=+{signature}\n"
  },
  {
    "path": "Units/parser-csharp.r/nullable-parameters.d/expected.tags",
    "content": "Foo\tinput.cs\t/^public class Foo$/;\"\tc\nBar\tinput.cs\t/^    public void Bar(decimal? p)$/;\"\tm\tclass:Foo\tsignature:(decimal? p)\n"
  },
  {
    "path": "Units/parser-csharp.r/nullable-parameters.d/input.cs",
    "content": "public class Foo\n{\n    public void Bar(decimal? p)\n    {\n    }\n}\n"
  },
  {
    "path": "Units/parser-css.r/css-at-rules.d/expected.tags",
    "content": "body\tinput.css\t/^  body { font-size: 10pt; }$/;\"\ts\nbody\tinput.css\t/^  body { font-size: 12px; }$/;\"\ts\nbody\tinput.css\t/^  body { line-height: 1.2 }$/;\"\ts\nhtml\tinput.css\t/^html { color: blue; }$/;\"\ts\n"
  },
  {
    "path": "Units/parser-css.r/css-at-rules.d/input.css",
    "content": "\n@import \"foo.css\";\n\n@namespace url(http://www.w3.org/1999/xhtml);\n@namespace svg url(http://www.w3.org/2000/svg);\n\n@media screen {\n  body { font-size: 10pt; }\n}\n@media print {\n  body { font-size: 12px; }\n}\n@media screen, print {\n  body { line-height: 1.2 }\n}\n\n@page :first {\n  margin: 2in;\n}\n\n@font-face {\n  font-family: Sample;\n  src: local(\"Sample\"),\n       url(Sample.ttf);\n}\n\nhtml { color: blue; }\n"
  },
  {
    "path": "Units/parser-css.r/css-at-supports.d/expected.tags",
    "content": "html\tinput.css\t/^  html { test-property: 42; }$/;\"\ts\nhtml\tinput.css\t/^html { color: blue; }$/;\"\ts\n"
  },
  {
    "path": "Units/parser-css.r/css-at-supports.d/input.css",
    "content": "\n@supports ((test-property: 42) or (test-property2: 42)) {\n  html { test-property: 42; }\n}\n\nhtml { color: blue; }\n"
  },
  {
    "path": "Units/parser-css.r/css-attribute-selectors.d/expected.tags",
    "content": "a[href^=\"http://\"]\tinput.css\t/^a[href^=\"http:\\/\\/\"] { color: red; }$/;\"\ts\na[href^=\"https://\"]\tinput.css\t/^a[href^=\"https:\\/\\/\"] { color: green; }$/;\"\ts\na[lang~=en]\tinput.css\t/^a[lang~=en] { background-color: light-green; }$/;\"\ts\nbody\tinput.css\t/^body { color: black; }$/;\"\ts\np\tinput.css\t/^p { color: gray }$/;\"\ts\n"
  },
  {
    "path": "Units/parser-css.r/css-attribute-selectors.d/input.css",
    "content": "\nbody { color: black; }\na[href^=\"http://\"] { color: red; }\na[href^=\"https://\"] { color: green; }\na[lang~=en] { background-color: light-green; }\np { color: gray }\n"
  },
  {
    "path": "Units/parser-css.r/css-comma-no-space.d/expected.tags",
    "content": "input\tinput.css\t/^input,textarea{border: 1px solid red;}$/;\"\ts\ntextarea\tinput.css\t/^input,textarea{border: 1px solid red;}$/;\"\ts\n"
  },
  {
    "path": "Units/parser-css.r/css-comma-no-space.d/input.css",
    "content": "input,textarea{border: 1px solid red;}\n"
  },
  {
    "path": "Units/parser-css.r/css-namespace-selectors.d/expected.tags",
    "content": "*|div\tinput.css\t/^*|div { color: blue; }$/;\"\ts\nsvg|a\tinput.css\t/^svg|a { color: green; }$/;\"\ts\n|a\tinput.css\t/^|a { color: red; }$/;\"\ts\n"
  },
  {
    "path": "Units/parser-css.r/css-namespace-selectors.d/input.css",
    "content": "\n|a { color: red; }\nsvg|a { color: green; }\n*|div { color: blue; }\n"
  },
  {
    "path": "Units/parser-css.r/css-pseudo-classes.d/expected.tags",
    "content": "a:lang(en):after\tinput.css\t/^a:lang(en):after { content: \"[en]\" }$/;\"\ts\nbody :not(span)\tinput.css\t/^body :not(span) { color: green; }$/;\"\ts\nspan:not(:first-child)\tinput.css\t/^span:not(:first-child) { color: red; }$/;\"\ts\nspan:nth-child(-n+3)\tinput.css\t/^span:nth-child(-n+3) { color: lime; }$/;\"\ts\nspan:nth-child(0n+1)\tinput.css\t/^span:nth-child(0n+1) { color: lime; }$/;\"\ts\nspan:nth-child(1)\tinput.css\t/^span:nth-child(1) { color: lime; }$/;\"\ts\ntr:nth-child(10n+0)\tinput.css\t/^tr:nth-child(10n+0) { background-color: gray }$/;\"\ts\ntr:nth-child(2n)\tinput.css\t/^tr:nth-child(2n) { background-color: light-gray }$/;\"\ts\ntr:nth-child(2n+1)\tinput.css\t/^tr:nth-child(2n+1) { background-color: light-gray }$/;\"\ts\ntr:nth-child(even)\tinput.css\t/^tr:nth-child(even) { background-color: light-gray }$/;\"\ts\ntr:nth-child(odd)\tinput.css\t/^tr:nth-child(odd) { background-color: light-gray }$/;\"\ts\n"
  },
  {
    "path": "Units/parser-css.r/css-pseudo-classes.d/input.css",
    "content": "\ntr:nth-child(2n+1) { background-color: light-gray }\ntr:nth-child(odd) { background-color: light-gray }\ntr:nth-child(2n) { background-color: light-gray }\ntr:nth-child(even) { background-color: light-gray }\ntr:nth-child(10n+0) { background-color: gray }\n\nspan:nth-child(0n+1) { color: lime; }\nspan:nth-child(1) { color: lime; }\nspan:nth-child(-n+3) { color: lime; }\n\nspan:not(:first-child) { color: red; }\nbody :not(span) { color: green; }\n\na:lang(en):after { content: \"[en]\" }\n"
  },
  {
    "path": "Units/parser-css.r/css-simple.d/expected.tags",
    "content": "#footer\tinput.css\t/^#footer { font-size: 80%; }$/;\"\ti\n*\tinput.css\t/^* { padding:0; }$/;\"\ts\n.foo a\tinput.css\t/^.foo a, .foo b { color: blue; }$/;\"\ts\n.foo b\tinput.css\t/^.foo a, .foo b { color: blue; }$/;\"\ts\n.header\tinput.css\t/^.header { font-size: 200%; }$/;\"\tc\n.red\tinput.css\t/^.red { color: red }$/;\"\tc\ndiv.magic\tinput.css\t/^div.magic $/;\"\tc\nhtml\tinput.css\t/^html$/;\"\ts\nimg ~ p\tinput.css\t/^img ~ p {$/;\"\ts\nul > li > a\tinput.css\t/^ul > li > a {$/;\"\ts\nul li\tinput.css\t/^ul li { padding-left: 1em; }$/;\"\ts\n"
  },
  {
    "path": "Units/parser-css.r/css-simple.d/input.css",
    "content": "\n* { padding:0; }\n\nhtml\n{\n  margin: 0\n}\n\n.header { font-size: 200%; }\n\n#footer { font-size: 80%; }\n\ndiv.magic \n\n{\n/* haha */\ntext-decoration: blink;\n}\n\n.red { color: red }\n\nul li { padding-left: 1em; }\n.foo a, .foo b { color: blue; }\n\nul > li > a {\n  font: monospace;\n}\n\n/* The general sibling combinator (~)\n * See https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_combinator */\nimg ~ p {\n  color: red;\n}\n"
  },
  {
    "path": "Units/parser-css.r/css-singlequote-in-comment-issue2.d/expected.tags",
    "content": "a\tinput.css\t/^a{x:0;\\/*'*\\/}$/;\"\ts\nb\tinput.css\t/^b{y:0;}$/;\"\ts\n"
  },
  {
    "path": "Units/parser-css.r/css-singlequote-in-comment-issue2.d/input.css",
    "content": "a{x:0;/*'*/}\nb{y:0;}\n"
  },
  {
    "path": "Units/parser-css.r/css-tag-types.d/expected.tags",
    "content": "#a #foo\tinput.css\t/^#a #foo{ color: red }$/;\"\ti\n#a #foo #bar\tinput.css\t/^#a #foo #bar{ color: red }$/;\"\ti\n#a #foo .bar\tinput.css\t/^#a #foo .bar{ color: red }$/;\"\tc\n#a #foo bar\tinput.css\t/^#a #foo bar{ color: red }$/;\"\ts\n#a .foo\tinput.css\t/^#a .foo{ color: red }$/;\"\tc\n#a .foo #bar\tinput.css\t/^#a .foo #bar{ color: red }$/;\"\ti\n#a .foo .bar\tinput.css\t/^#a .foo .bar{ color: red }$/;\"\tc\n#a .foo bar\tinput.css\t/^#a .foo bar{ color: red }$/;\"\ts\n#a foo\tinput.css\t/^#a foo{ color: red }$/;\"\ts\n#a foo #bar\tinput.css\t/^#a foo #bar{ color: red }$/;\"\ti\n#a foo .bar\tinput.css\t/^#a foo .bar{ color: red }$/;\"\tc\n#a foo bar\tinput.css\t/^#a foo bar{ color: red }$/;\"\ts\n.a #foo\tinput.css\t/^.a #foo{ color: red }$/;\"\ti\n.a #foo #bar\tinput.css\t/^.a #foo #bar{ color: red }$/;\"\ti\n.a #foo .bar\tinput.css\t/^.a #foo .bar{ color: red }$/;\"\tc\n.a #foo bar\tinput.css\t/^.a #foo bar{ color: red }$/;\"\ts\n.a .foo\tinput.css\t/^.a .foo{ color: red }$/;\"\tc\n.a .foo #bar\tinput.css\t/^.a .foo #bar{ color: red }$/;\"\ti\n.a .foo .bar\tinput.css\t/^.a .foo .bar{ color: red }$/;\"\tc\n.a .foo bar\tinput.css\t/^.a .foo bar{ color: red }$/;\"\ts\n.a foo\tinput.css\t/^.a foo{ color: red }$/;\"\ts\n.a foo #bar\tinput.css\t/^.a foo #bar{ color: red }$/;\"\ti\n.a foo .bar\tinput.css\t/^.a foo .bar{ color: red }$/;\"\tc\n.a foo bar\tinput.css\t/^.a foo bar{ color: red }$/;\"\ts\na #foo\tinput.css\t/^a #foo{ color: red }$/;\"\ti\na #foo #bar\tinput.css\t/^a #foo #bar{ color: red }$/;\"\ti\na #foo .bar\tinput.css\t/^a #foo .bar{ color: red }$/;\"\tc\na #foo bar\tinput.css\t/^a #foo bar{ color: red }$/;\"\ts\na .foo\tinput.css\t/^a .foo{ color: red }$/;\"\tc\na .foo #bar\tinput.css\t/^a .foo #bar{ color: red }$/;\"\ti\na .foo .bar\tinput.css\t/^a .foo .bar{ color: red }$/;\"\tc\na .foo bar\tinput.css\t/^a .foo bar{ color: red }$/;\"\ts\na foo\tinput.css\t/^a foo{ color: red }$/;\"\ts\na foo #bar\tinput.css\t/^a foo #bar{ color: red }$/;\"\ti\na foo .bar\tinput.css\t/^a foo .bar{ color: red }$/;\"\tc\na foo bar\tinput.css\t/^a foo bar{ color: red }$/;\"\ts\n"
  },
  {
    "path": "Units/parser-css.r/css-tag-types.d/input.css",
    "content": "a foo{ color: red }\na #foo{ color: red }\na .foo{ color: red }\na foo bar{ color: red }\na foo #bar{ color: red }\na foo .bar{ color: red }\na #foo bar{ color: red }\na #foo #bar{ color: red }\na #foo .bar{ color: red }\na .foo bar{ color: red }\na .foo #bar{ color: red }\na .foo .bar{ color: red }\n\n#a foo{ color: red }\n#a #foo{ color: red }\n#a .foo{ color: red }\n#a foo bar{ color: red }\n#a foo #bar{ color: red }\n#a foo .bar{ color: red }\n#a #foo bar{ color: red }\n#a #foo #bar{ color: red }\n#a #foo .bar{ color: red }\n#a .foo bar{ color: red }\n#a .foo #bar{ color: red }\n#a .foo .bar{ color: red }\n\n.a foo{ color: red }\n.a #foo{ color: red }\n.a .foo{ color: red }\n.a foo bar{ color: red }\n.a foo #bar{ color: red }\n.a foo .bar{ color: red }\n.a #foo bar{ color: red }\n.a #foo #bar{ color: red }\n.a #foo .bar{ color: red }\n.a .foo bar{ color: red }\n.a .foo #bar{ color: red }\n.a .foo .bar{ color: red }\n"
  },
  {
    "path": "Units/parser-css.r/css-trivial.d/expected.tags",
    "content": "a\tinput.css\t/^a{ color: red; }$/;\"\ts\nhtml\tinput.css\t/^html{ font: sans-serif; }$/;\"\ts\ninput\tinput.css\t/^input, textarea{ border: 1px solid green; }$/;\"\ts\np\tinput.css\t/^p{ text-align: justify; }$/;\"\ts\ntextarea\tinput.css\t/^input, textarea{ border: 1px solid green; }$/;\"\ts\n"
  },
  {
    "path": "Units/parser-css.r/css-trivial.d/input.css",
    "content": "\nhtml{ font: sans-serif; }\na{ color: red; }\np{ text-align: justify; }\ninput, textarea{ border: 1px solid green; }\n"
  },
  {
    "path": "Units/parser-cuda.r/cuda-sample.d/args.ctags",
    "content": "--sort=no\n--kinds-cuda=*"
  },
  {
    "path": "Units/parser-cuda.r/cuda-sample.d/expected.tags",
    "content": "array1\tinput.cu\t/^__shared__ float2 array1[];$/;\"\tv\ttyperef:typename:float2[]\narray2\tinput.cu\t/^__shared__ __device__ dim3 array2[];$/;\"\tv\ttyperef:typename:dim3[]\ni1\tinput.cu\t/^__device__ volatile int i1 = 1;$/;\"\tv\ttyperef:typename:volatile int\ni2\tinput.cu\t/^__constant__ int i2 = 2;$/;\"\tv\ttyperef:typename:int\ndev1\tinput.cu\t/^__device__ void dev1(float * a,const float * __restrict__ b)$/;\"\tf\ttyperef:typename:void\na\tinput.cu\t/^__device__ void dev1(float * a,const float * __restrict__ b)$/;\"\tz\tfunction:dev1\ttyperef:typename:float *\tfile:\nb\tinput.cu\t/^__device__ void dev1(float * a,const float * __restrict__ b)$/;\"\tz\tfunction:dev1\ttyperef:typename:const float * \tfile:\nkernel1\tinput.cu\t/^__global__ void kernel1(float * a,float * __restrict__ b)$/;\"\tf\ttyperef:typename:void\na\tinput.cu\t/^__global__ void kernel1(float * a,float * __restrict__ b)$/;\"\tz\tfunction:kernel1\ttyperef:typename:float *\tfile:\nb\tinput.cu\t/^__global__ void kernel1(float * a,float * __restrict__ b)$/;\"\tz\tfunction:kernel1\ttyperef:typename:float * \tfile:\nmain\tinput.cu\t/^int main()$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cuda.r/cuda-sample.d/input.cu",
    "content": "// C with some CUDA extensions.\n\n__shared__ float2 array1[];\n__shared__ __device__ dim3 array2[];\n__device__ volatile int i1 = 1;\n__constant__ int i2 = 2;\n\n__device__ void dev1(float * a,const float * __restrict__ b)\n{\n}\n\n__global__ void kernel1(float * a,float * __restrict__ b)\n{\n\t\n}\n\nint main()\n{\n\tkernel1<<<1024 * 1024 / 256,256>>>(NULL,NULL);\n}\n\n"
  },
  {
    "path": "Units/parser-cuda.r/param-with-default-value.d/args.ctags",
    "content": "--sort=no\n--fields=+{signature}\n"
  },
  {
    "path": "Units/parser-cuda.r/param-with-default-value.d/expected.tags",
    "content": "foo1\tinput.cuh\t/^float foo1(int a)$/;\"\tf\ttyperef:typename:float\tsignature:(int a)\nfoo2\tinput.cuh\t/^bool foo2(float* pointer = NULL)$/;\"\tf\ttyperef:typename:bool\tsignature:(float * pointer=NULL)\nfoo2_alt\tinput.cuh\t/^bool foo2_alt(float* pointer)$/;\"\tf\ttyperef:typename:bool\tsignature:(float * pointer)\nfoo3\tinput.cuh\t/^bool foo3(const int a, float b, double c)$/;\"\tf\ttyperef:typename:bool\tsignature:(const int a,float b,double c)\n"
  },
  {
    "path": "Units/parser-cuda.r/param-with-default-value.d/input.cuh",
    "content": "/* Taken from #4187 submitted by @emilioj, Emilio J. Padrón González */\nfloat foo1(int a)\n{\n  for (int useless1=0; i<1000; ++i) {\n    nonsense()\n  }\n}\n\nbool foo2(float* pointer = NULL)\n{\n  for (int useless2=0; i<1000; ++i) {\n    nonsense()\n  }\n}\n\nbool foo2_alt(float* pointer)\n{\n  for (int useless2_alt=0; i<1000; ++i) {\n    nonsense()\n  }\n}\n\nbool foo3(const int a, float b, double c)\n{\n  for (int useless3=0; i<1000; ++i) {\n    nonsense()\n  }\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/1117-using-in-c.d/input.c",
    "content": "using std::terminate_handler;\n"
  },
  {
    "path": "Units/parser-cxx.r/README",
    "content": "See https://github.com/universal-ctags/ctags/pull/742\nlocal variable handling verified in variables-prototypes-2.cpp.d and\nvariables-prototypes.cpp.b.\n"
  },
  {
    "path": "Units/parser-cxx.r/alignas-in-struct.d/expected.tags",
    "content": "AlignasTestStruct\tinput.cpp\t/^struct alignas( 64 ) AlignasTestStruct$/;\"\ts\tfile:\nAlignasTestStruct2\tinput.cpp\t/^class alignas( 64 ) AlignasTestStruct2$/;\"\tc\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/alignas-in-struct.d/input.cpp",
    "content": "// Taken from #1374 submitted by @oison-dan\nstruct alignas( 64 ) AlignasTestStruct\n{\n};\n\nclass alignas( 64 ) AlignasTestStruct2\n{\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/angle_bracket.cpp.d/expected.tags",
    "content": "bar\tinput.cpp\t/^static void bar (int value)$/;\"\tf\ttyperef:typename:void\tfile:\nbar2\tinput.cpp\t/^static bar2 (void)$/;\"\tf\tfile:\nfoo\tinput.cpp\t/^static void foo (int nelem)$/;\"\tf\ttyperef:typename:void\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/angle_bracket.cpp.d/input.cpp",
    "content": "static void foo (int nelem)\n{\n    int rsize = 2;\n    while (nelem < 0) {\n\trsize <<= 1;\n    }\n}\n\nstatic void bar (int value)\n{\n    return value < 0 ? value : 3;\n}\n\nstatic bar2 (void)\n{\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-alias.cpp.d/args.ctags",
    "content": "--sort=no\n--fields-C=+{alias}\n--extras=+r\n--fields=+{roles}{language}\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-alias.cpp.d/expected.tags",
    "content": "y\tinput.c\t/^int x __attribute__((alias(\"y\")));$/;\"\ts\tlanguage:LdScript\troles:aliased\nx\tinput.c\t/^int x __attribute__((alias(\"y\")));$/;\"\tv\tlanguage:C\ttyperef:typename:int\troles:def\talias:y\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-alias.cpp.d/input.c",
    "content": "int x __attribute__((alias(\"y\")));\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-sections.cpp-no-ldscript.d/args.ctags",
    "content": "--sort=no\n--kinds-C=+p\n--param-CPreProcessor._expand=1\n--fields-C=+{section}{macrodef}\n--fields=+S\n--fields=+rl\n--extras=+r\n--languages=-LdScript\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-sections.cpp-no-ldscript.d/expected.tags",
    "content": "f\tinput.c\t/^char f [] __attribute__((section(\"__ksymtab_strings\"), used, aligned(1)));$/;\"\tv\tlanguage:C\ttyperef:typename:char[]\troles:def\tsection:__ksymtab_strings\na\tinput.c\t/^struct duart a __attribute__ ((section (\"DUART_A\"))) = { 0 };$/;\"\tv\tlanguage:C\ttyperef:struct:duart\troles:def\tsection:DUART_A\nb\tinput.c\t/^struct duart b __attribute__ ((section (\"DUART_B\"))) = { 0 };$/;\"\tv\tlanguage:C\ttyperef:struct:duart\troles:def\tsection:DUART_B\nstack\tinput.c\t/^char stack[10000] __attribute__ ((section (\"STACK\"))) = { 0 };$/;\"\tv\tlanguage:C\ttyperef:typename:char[10000]\troles:def\tsection:STACK\ninit_data\tinput.c\t/^int init_data __attribute__ ((section (\"INITDATA\")));$/;\"\tv\tlanguage:C\ttyperef:typename:int\troles:def\tsection:INITDATA\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-sections.cpp-no-ldscript.d/input.c",
    "content": "/* Variables */\nchar f [] __attribute__((section(\"__ksymtab_strings\"), used, aligned(1)));\n\n/* Taken form gcc's info document. */\nstruct duart a __attribute__ ((section (\"DUART_A\"))) = { 0 };\nstruct duart b __attribute__ ((section (\"DUART_B\"))) = { 0 };\nchar stack[10000] __attribute__ ((section (\"STACK\"))) = { 0 };\nint init_data __attribute__ ((section (\"INITDATA\")));\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-sections.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-C=+p\n--param-CPreProcessor._expand=1\n--fields-C=+{section}{macrodef}\n--fields=+S\n--fields=+rl\n--extras=+r\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-sections.cpp.d/expected.tags",
    "content": "__ksymtab_strings\tinput.c\t/^char f [] __attribute__((section(\"__ksymtab_strings\"), used, aligned(1)));$/;\"\ti\tlanguage:LdScript\troles:destination\nf\tinput.c\t/^char f [] __attribute__((section(\"__ksymtab_strings\"), used, aligned(1)));$/;\"\tv\tlanguage:C\ttyperef:typename:char[]\troles:def\tsection:__ksymtab_strings\nDUART_A\tinput.c\t/^struct duart a __attribute__ ((section (\"DUART_A\"))) = { 0 };$/;\"\ti\tlanguage:LdScript\troles:destination\na\tinput.c\t/^struct duart a __attribute__ ((section (\"DUART_A\"))) = { 0 };$/;\"\tv\tlanguage:C\ttyperef:struct:duart\troles:def\tsection:DUART_A\nDUART_B\tinput.c\t/^struct duart b __attribute__ ((section (\"DUART_B\"))) = { 0 };$/;\"\ti\tlanguage:LdScript\troles:destination\nb\tinput.c\t/^struct duart b __attribute__ ((section (\"DUART_B\"))) = { 0 };$/;\"\tv\tlanguage:C\ttyperef:struct:duart\troles:def\tsection:DUART_B\nSTACK\tinput.c\t/^char stack[10000] __attribute__ ((section (\"STACK\"))) = { 0 };$/;\"\ti\tlanguage:LdScript\troles:destination\nstack\tinput.c\t/^char stack[10000] __attribute__ ((section (\"STACK\"))) = { 0 };$/;\"\tv\tlanguage:C\ttyperef:typename:char[10000]\troles:def\tsection:STACK\nINITDATA\tinput.c\t/^int init_data __attribute__ ((section (\"INITDATA\")));$/;\"\ti\tlanguage:LdScript\troles:destination\ninit_data\tinput.c\t/^int init_data __attribute__ ((section (\"INITDATA\")));$/;\"\tv\tlanguage:C\ttyperef:typename:int\troles:def\tsection:INITDATA\nCOMMAND_LINE_SIZE\tinput-0.c\t/^#define COMMAND_LINE_SIZE /;\"\td\tlanguage:C\tfile:\troles:def\tmacrodef:127\n__section\tinput-0.c\t/^#define __section(section)              __attribute__((__section_/;\"\td\tlanguage:C\tfile:\tsignature:(section)\troles:def\tmacrodef:__attribute__((__section__(section)))\n__initdata\tinput-0.c\t/^#define __initdata\t/;\"\td\tlanguage:C\tfile:\troles:def\tmacrodef:__section(\".init.data\")\n.init.data\tinput-0.c\t/^char __initdata b0[COMMAND_LINE_SIZE];$/;\"\ti\tlanguage:LdScript\troles:destination\nb0\tinput-0.c\t/^char __initdata b0[COMMAND_LINE_SIZE];$/;\"\tv\tlanguage:C\ttyperef:typename:char[127]\troles:def\tsection:.init.data\n.init.data\tinput-0.c\t/^char b1[COMMAND_LINE_SIZE] __initdata;$/;\"\ti\tlanguage:LdScript\troles:destination\nb1\tinput-0.c\t/^char b1[COMMAND_LINE_SIZE] __initdata;$/;\"\tv\tlanguage:C\ttyperef:typename:char[127]\troles:def\tsection:.init.data\nbar0p\tinput-1.c\t/^extern void f0 (void) __attribute__ ((section (\"bar0p\")));$/;\"\ti\tlanguage:LdScript\troles:destination\nf0\tinput-1.c\t/^extern void f0 (void) __attribute__ ((section (\"bar0p\")));$/;\"\tp\tlanguage:C\ttyperef:typename:void\tfile:\tsignature:(void)\troles:def\tsection:bar0p\nbar0\tinput-1.c\t/^{$/;\"\ti\tlanguage:LdScript\troles:destination\nf0\tinput-1.c\t/^void f0 (void) __attribute__ ((section (\"bar0\")))$/;\"\tf\tlanguage:C\ttyperef:typename:void\tsignature:(void)\troles:def\tsection:bar0\nbar1p\tinput-1.c\t/^extern void __attribute__ ((section (\"bar1p\")))  f1 (void);$/;\"\ti\tlanguage:LdScript\troles:destination\nf1\tinput-1.c\t/^extern void __attribute__ ((section (\"bar1p\")))  f1 (void);$/;\"\tp\tlanguage:C\ttyperef:typename:void\tfile:\tsignature:(void)\troles:def\tsection:bar1p\nbar1\tinput-1.c\t/^{$/;\"\ti\tlanguage:LdScript\troles:destination\nf1\tinput-1.c\t/^void __attribute__ ((section (\"bar1\"))) f1 (void)$/;\"\tf\tlanguage:C\ttyperef:typename:void\tsignature:(void)\troles:def\tsection:bar1\nbar2p\tinput-1.c\t/^extern __attribute__ ((section (\"bar2p\"))) void f2 (void);$/;\"\ti\tlanguage:LdScript\troles:destination\nf2\tinput-1.c\t/^extern __attribute__ ((section (\"bar2p\"))) void f2 (void);$/;\"\tp\tlanguage:C\ttyperef:typename:void\tfile:\tsignature:(void)\troles:def\tsection:bar2p\nbar2\tinput-1.c\t/^{$/;\"\ti\tlanguage:LdScript\troles:destination\nf2\tinput-1.c\t/^__attribute__ ((section (\"bar2\"))) void f2 (void)$/;\"\tf\tlanguage:C\ttyperef:typename:void\tsignature:(void)\troles:def\tsection:bar2\nbar3p\tinput-1.c\t/^__attribute__ ((section (\"bar3p\"))) extern void f3 (void);$/;\"\ti\tlanguage:LdScript\troles:destination\nf3\tinput-1.c\t/^__attribute__ ((section (\"bar3p\"))) extern void f3 (void);$/;\"\tp\tlanguage:C\ttyperef:typename:void\tfile:\tsignature:(void)\troles:def\tsection:bar3p\nbar3\tinput-1.c\t/^{$/;\"\ti\tlanguage:LdScript\troles:destination\nf3\tinput-1.c\t/^__attribute__ ((section (\"bar3\"))) extern void f3 (void)$/;\"\tf\tlanguage:C\ttyperef:typename:void\tsignature:(void)\troles:def\tsection:bar3\nbar4p\tinput-1.c\t/^__attribute__ ((section (\"bar4p\"))) static void f4 (void);$/;\"\ti\tlanguage:LdScript\troles:destination\nf4\tinput-1.c\t/^__attribute__ ((section (\"bar4p\"))) static void f4 (void);$/;\"\tp\tlanguage:C\ttyperef:typename:void\tfile:\tsignature:(void)\troles:def\tsection:bar4p\nbar4\tinput-1.c\t/^{$/;\"\ti\tlanguage:LdScript\troles:destination\nf4\tinput-1.c\t/^__attribute__ ((section (\"bar4\"))) static void f4 (void)$/;\"\tf\tlanguage:C\ttyperef:typename:void\tfile:\tsignature:(void)\troles:def\tsection:bar4\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-sections.cpp.d/input-0.c",
    "content": "/* --param-CPreProcessor._expand=1 */\n#define COMMAND_LINE_SIZE 127\n#define __section(section)              __attribute__((__section__(section)))\n#define __initdata\t__section(\".init.data\")\nchar __initdata b0[COMMAND_LINE_SIZE];\nchar b1[COMMAND_LINE_SIZE] __initdata;\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-sections.cpp.d/input-1.c",
    "content": "extern void f0 (void) __attribute__ ((section (\"bar0p\")));\nvoid f0 (void) __attribute__ ((section (\"bar0\")))\n{\n}\n\nextern void __attribute__ ((section (\"bar1p\")))  f1 (void);\nvoid __attribute__ ((section (\"bar1\"))) f1 (void)\n{\n}\n\nextern __attribute__ ((section (\"bar2p\"))) void f2 (void);\n__attribute__ ((section (\"bar2\"))) void f2 (void)\n{\n}\n\n__attribute__ ((section (\"bar3p\"))) extern void f3 (void);\n__attribute__ ((section (\"bar3\"))) extern void f3 (void)\n{\n}\n\n__attribute__ ((section (\"bar4p\"))) static void f4 (void);\n__attribute__ ((section (\"bar4\"))) static void f4 (void)\n{\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute-sections.cpp.d/input.c",
    "content": "/* Variables */\nchar f [] __attribute__((section(\"__ksymtab_strings\"), used, aligned(1)));\n\n/* Taken form gcc's info document. */\nstruct duart a __attribute__ ((section (\"DUART_A\"))) = { 0 };\nstruct duart b __attribute__ ((section (\"DUART_B\"))) = { 0 };\nchar stack[10000] __attribute__ ((section (\"STACK\"))) = { 0 };\nint init_data __attribute__ ((section (\"INITDATA\")));\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute.cpp.d/args.ctags",
    "content": "--kinds-c++=*\n--fields-C++=+{properties}\n--fields=+tS\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute.cpp.d/expected.tags",
    "content": "v1\tinput.cpp\t/^int v1 __attribute__((aligned(16)));$/;\"\tv\ttyperef:typename:int\nv2\tinput.cpp\t/^unsigned int v2 __attribute__((aligned(8),weak,visibility(\"hidden\")));$/;\"\tv\ttyperef:typename:unsigned int\nv3\tinput.cpp\t/^char v3[10000] __attribute__((section(\"STACK\"))) = { 0 };$/;\"\tv\ttyperef:typename:char[10000]\nv4\tinput.cpp\t/^char *__attribute__((aligned(8))) *v4;$/;\"\tv\ttyperef:typename:char **\ns1\tinput.cpp\t/^struct s1$/;\"\ts\tfile:\ns1v1\tinput.cpp\t/^\tchar s1v1;$/;\"\tm\tstruct:s1\ttyperef:typename:char\tfile:\ns1v2\tinput.cpp\t/^\tint s1v2[2] __attribute__((packed));$/;\"\tm\tstruct:s1\ttyperef:typename:int[2]\tfile:\nv5\tinput.cpp\t/^struct s1 __attribute__((vector_size(16))) v5;$/;\"\tv\ttyperef:struct:s1\ns2\tinput.cpp\t/^struct s2$/;\"\ts\tfile:\ns2v1\tinput.cpp\t/^\tshort s2v1[3];$/;\"\tm\tstruct:s2\ttyperef:typename:short[3]\tfile:\ns3\tinput.cpp\t/^struct __attribute__((__packed__)) s3$/;\"\ts\tfile:\ns3v1\tinput.cpp\t/^\tchar s3v1 __attribute__((deprecated));$/;\"\tm\tstruct:s3\ttyperef:typename:char\tfile:\tproperties:deprecated\ns3v2\tinput.cpp\t/^\tchar s3v2;$/;\"\tm\tstruct:s3\ttyperef:typename:char\tfile:\nt1\tinput.cpp\t/^typedef int t1 __attribute__ ((aligned (8)));$/;\"\tt\ttyperef:typename:int\tfile:\nt2\tinput.cpp\t/^typedef int t2 __attribute__ ((deprecated));$/;\"\tt\ttyperef:typename:int\tfile:\ne1\tinput.cpp\t/^enum e1 {$/;\"\tg\tfile:\ne1e1\tinput.cpp\t/^\te1e1 __attribute__((deprecated)),$/;\"\te\tenum:e1\tfile:\ne1e2\tinput.cpp\t/^\te1e2$/;\"\te\tenum:e1\tfile:\np1\tinput.cpp\t/^__attribute__((noreturn)) void p1(void),$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(void)\np2\tinput.cpp\t/^\t__attribute__((format(printf, 1, 2))) p2 (const char *, ...),$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(const char *,...)\n__anon6f96ad27010d\tinput.cpp\t/^\t__attribute__((format(printf, 1, 2))) p2 (const char *, ...),$/;\"\tz\tprototype:p2\ttyperef:typename:const char *\tfile:\np3\tinput.cpp\t/^\tp3 (void);$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(void)\np4\tinput.cpp\t/^void (__attribute__((noreturn)) ****p4) (void) __attribute__((deprecated));$/;\"\tv\ttyperef:typename:void (****)(void)\tproperties:deprecated\np5\tinput.cpp\t/^void p5() __attribute__ ((weak, alias (\"p4\")));$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:()\nf1\tinput.cpp\t/^\tf1(int f1p1,int f1p2 __attribute__((unused)),int f1p3)$/;\"\tf\ttyperef:typename:int\tsignature:(int f1p1,int f1p2,int f1p3)\tproperties:inline,deprecated\nf1p1\tinput.cpp\t/^\tf1(int f1p1,int f1p2 __attribute__((unused)),int f1p3)$/;\"\tz\tfunction:f1\ttyperef:typename:int\tfile:\nf1p2\tinput.cpp\t/^\tf1(int f1p1,int f1p2 __attribute__((unused)),int f1p3)$/;\"\tz\tfunction:f1\ttyperef:typename:int\tfile:\nf1p3\tinput.cpp\t/^\tf1(int f1p1,int f1p2 __attribute__((unused)),int f1p3)$/;\"\tz\tfunction:f1\ttyperef:typename:int\tfile:\nl1\tinput.cpp\t/^l1:$/;\"\tL\tfunction:f1\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/attribute.cpp.d/input.cpp",
    "content": "\n\nint v1 __attribute__((aligned(16)));\nunsigned int v2 __attribute__((aligned(8),weak,visibility(\"hidden\")));\nchar v3[10000] __attribute__((section(\"STACK\"))) = { 0 };\nchar *__attribute__((aligned(8))) *v4;\n\nstruct s1\n{\n\tchar s1v1;\n\tint s1v2[2] __attribute__((packed));\n};\n\nstruct s1 __attribute__((vector_size(16))) v5;\n\nstruct s2\n{\n\tshort s2v1[3];\n} __attribute__ ((aligned (8)));\n\nstruct __attribute__((__packed__)) s3\n{\n\tchar s3v1 __attribute__((deprecated));\n\tchar s3v2;\n};\n\ntypedef int t1 __attribute__ ((aligned (8)));\ntypedef int t2 __attribute__ ((deprecated));\n\nenum e1 {\n\te1e1 __attribute__((deprecated)),\n\te1e2\n};\n\n__attribute__((noreturn)) void p1(void),\n\t__attribute__((format(printf, 1, 2))) p2 (const char *, ...),\n\tp3 (void);\n\nvoid (__attribute__((noreturn)) ****p4) (void) __attribute__((deprecated));\nvoid p5() __attribute__ ((weak, alias (\"p4\")));\n\nint __attribute__((visibility(\"protected\")))\n\tf1(int f1p1,int f1p2 __attribute__((unused)),int f1p3)\n\t\t__attribute__ ((warn_unused_result,always_inline,deprecated))\n{\nl1:\n\t__attribute__((cold, unused)); /* Semi-colon is required here */\n\treturn -1;\n}"
  },
  {
    "path": "Units/parser-cxx.r/blocks-nesting-too-deep.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-cxx.r/blocks-nesting-too-deep.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/blocks-nesting-too-deep.d/expected.tags",
    "content": "foo\tinput.cxx\t/^void foo(void) {$/;\"\tf\ttyperef:typename:void\nbar\tinput-0.cxx\t/^void bar(void) {}$/;\"\tf\ttyperef:typename:void\nv1\tinput-0.cxx\t/^  int v1[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[/;\"\tv\ttyperef:typename:int\nbaz\tinput-1.cxx\t/^void baz(void) {}$/;\"\tf\ttyperef:typename:void\n"
  },
  {
    "path": "Units/parser-cxx.r/blocks-nesting-too-deep.d/input-0.cxx",
    "content": "//\n// Derived from https://raw.githubusercontent.com/llvm/llvm-project/25d1285eecbab731eaf418c8aab44e4eb5f9e538/clang/test/Parser/parser_overflow.c\n//\n\nvoid bar(void) {}\n\n#ifdef HUGE\n  // 16384 [, 16384 ]\n  int v0[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]];\n#else\n// 299 [, 299 ]\n  int v1[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]];\n#endif\n"
  },
  {
    "path": "Units/parser-cxx.r/blocks-nesting-too-deep.d/input-1.cxx",
    "content": "//\n// Derived from https://raw.githubusercontent.com/llvm/llvm-project/25d1285eecbab731eaf418c8aab44e4eb5f9e538/clang/test/Parser/parser_overflow.c\n//\n\nvoid baz(void) {}\n\n#ifdef HUGE\n  // 16384 (, 16384 )\n  int a0 = (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));\n#else\n// 299 (, 299 )\n  int a1 = ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));\n#endif\n"
  },
  {
    "path": "Units/parser-cxx.r/blocks-nesting-too-deep.d/input.cxx",
    "content": "//\n// Taken from https://raw.githubusercontent.com/llvm/llvm-project/25d1285eecbab731eaf418c8aab44e4eb5f9e538/clang/test/Parser/parser_overflow.c\n//\n\n// RUN: not %clang_cc1 %s -fsyntax-only -DHUGE 2>&1 | FileCheck %s\n// RUN: %clang_cc1 %s -fsyntax-only\n// RUN: not %clang_cc1 %s -fsyntax-only -fbracket-depth 299 2>&1 | FileCheck %s\n// RUN: %clang_cc1 %s -fsyntax-only -fbracket-depth 300\n// RUN: not %clang %s -fsyntax-only -fbracket-depth=299 2>&1 | FileCheck %s\n// RUN: %clang %s -fsyntax-only -fbracket-depth=300\n\nvoid foo(void) {\n#ifdef HUGE\n  // 16384 {, 16384 }\n    {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}\n#else\n// 299 {, 299 }\n{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}\n#endif\n}\n\n// CHECK: fatal error: bracket nesting level exceeded maximum of {{2048|299}}\n// CHECK: note: use -fbracket-depth=N to increase maximum nesting level\n"
  },
  {
    "path": "Units/parser-cxx.r/brackets.cpp.d/args.ctags",
    "content": "--kinds-c++=*\n--fields=+SK\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/brackets.cpp.d/expected.tags",
    "content": "EMPTY_MACRO\tinput.cpp\t/^#define EMPTY_MACRO$/;\"\tmacro\tfile:\nn01\tinput.cpp\t/^namespace n01 {$/;\"\tnamespace\tfile:\ng01\tinput.cpp\t/^\tstd::string g01 { \"\" };$/;\"\tvariable\tnamespace:n01\ttyperef:typename:std::string\nf01\tinput.cpp\t/^\tauto f01(std::string p01) -> std::string {$/;\"\tfunction\tnamespace:n01\ttyperef:typename:std::string\tsignature:(std::string p01)\np01\tinput.cpp\t/^\tauto f01(std::string p01) -> std::string {$/;\"\tparameter\tfunction:n01::f01\ttyperef:typename:std::string\tfile:\nl01\tinput.cpp\t/^\t\tstd::string l01 { \"\" };$/;\"\tlocal\tfunction:n01::f01\ttyperef:typename:std::string\tfile:\nl02\tinput.cpp\t/^\t\tstd::string l02 = { \"\" };$/;\"\tlocal\tfunction:n01::f01\ttyperef:typename:std::string\tfile:\nC01\tinput.cpp\t/^\tclass C01$/;\"\tclass\tnamespace:n01\tfile:\nm01\tinput.cpp\t/^\t\tstd::string m01 { \"\" };$/;\"\tmember\tclass:n01::C01\ttyperef:typename:std::string\tfile:\nm02\tinput.cpp\t/^\t\tstd::string m02;$/;\"\tmember\tclass:n01::C01\ttyperef:typename:std::string\tfile:\nm03\tinput.cpp\t/^\t\tstd::string m03;$/;\"\tmember\tclass:n01::C01\ttyperef:typename:std::string\tfile:\nC01\tinput.cpp\t/^\t\tC01(std::string p02)$/;\"\tfunction\tclass:n01::C01\tfile:\tsignature:(std::string p02)\np02\tinput.cpp\t/^\t\tC01(std::string p02)$/;\"\tparameter\tfunction:n01::C01::C01\ttyperef:typename:std::string\tfile:\nC01\tinput.cpp\t/^\t\tC01()$/;\"\tfunction\tclass:n01::C01\tfile:\tsignature:()\nl03\tinput.cpp\t/^\t\t\tstd::string l03 { \"\" };$/;\"\tlocal\tfunction:n01::C01::C01\ttyperef:typename:std::string\tfile:\nl04\tinput.cpp\t/^\t\t\tstd::string l04 { \"\" };$/;\"\tlocal\tfunction:n01::C01::C01\ttyperef:typename:std::string\tfile:\nl05\tinput.cpp\t/^\t\t\tC01 l05{ \"\" };$/;\"\tlocal\tfunction:n01::C01::C01\ttyperef:typename:C01\tfile:\nf02\tinput.cpp\t/^\t\tstd::string f02() const EMPTY_MACRO { }$/;\"\tfunction\tclass:n01::C01\ttyperef:typename:std::string\tfile:\tsignature:() const\nm04\tinput.cpp\t/^\t\tint m04 { 0 };$/;\"\tmember\tclass:n01::C01\ttyperef:typename:int\tfile:\nf03\tinput.cpp\t/^\t\tstd::string f03() const EMPTY_MACRO { }$/;\"\tfunction\tclass:n01::C01\ttyperef:typename:std::string\tfile:\tsignature:() const\nf04\tinput.cpp\t/^\t\tstd::string f04() const EMPTY_MACRO { }$/;\"\tfunction\tclass:n01::C01\ttyperef:typename:std::string\tfile:\tsignature:() const\nm05\tinput.cpp\t/^\t\tint m05 { 0 };$/;\"\tmember\tclass:n01::C01\ttyperef:typename:int\tfile:\nf05\tinput.cpp\t/^\t\tstd::string f05() const EMPTY_MACRO { }$/;\"\tfunction\tclass:n01::C01\ttyperef:typename:std::string\tfile:\tsignature:() const\nf06\tinput.cpp\t/^\t\tstd::string f06() const { }$/;\"\tfunction\tclass:n01::C01\ttyperef:typename:std::string\tfile:\tsignature:() const\nf07\tinput.cpp\t/^\t\tstd::string f07() { }$/;\"\tfunction\tclass:n01::C01\ttyperef:typename:std::string\tfile:\tsignature:()\n"
  },
  {
    "path": "Units/parser-cxx.r/brackets.cpp.d/input.cpp",
    "content": "// Compile with gcc -std=c++11 input.cpp\n\n#include <string>\n#include <memory>\n\n#define EMPTY_MACRO\n\nnamespace n01 {\n\n\tstd::string g01 { \"\" };\n\t\n\tauto f01(std::string p01) -> std::string {\n\t\t// initialization of unnamed temporary (makes no sense to report it, just don't think it's a function)\n\t\tstd::string { \"\" };\n\t\n\t\t// list initialisation for local\n\t\tstd::string l01 { \"\" };\n\t\t\n\t\t// constructor call for list initialisation\n\t\tnew std::string { \"\" };\n\n\t\t// copy list initialisation for local\n\t\tstd::string l02 = { \"\" };\n\n\t\t// return list initalizer\n\t\treturn { \"\" };\n\t}\n\t\n\tclass C01\n\t{\n\tpublic:\n\t\tstd::string m01 { \"\" };\n\t\tstd::string m02;\n\t\tstd::string m03;\n\t\n\t\tC01(std::string p02)\n\t\t\t: m02 { \"\" }\n\t\t{\n\t\t}\n\t\n\t\tC01()\n\t\t\t: m02 { \"\" },\n\t\t\tm03 { \"\" }\n\t\t{\n\t\t\tstd::string l03 { \"\" };\n\t\t\tf01({ \"\" });\n\t\t\tstd::string l04 { \"\" };\n\t\t\tC01 l05{ \"\" };\n\t\t}\n\t\t\n\t\tstd::string f02() const EMPTY_MACRO { }\n\t\tint m04 { 0 };\n\t\t\n\t\tstd::string f03() const EMPTY_MACRO { }\n\t\tstd::string f04() const EMPTY_MACRO { }\n\t\tint m05 { 0 };\n\t\t\n\t\tstd::string f05() const EMPTY_MACRO { }\n\t\tstd::string f06() const { }\n\t\tstd::string f07() { }\n\t};\n}\n\n\n"
  },
  {
    "path": "Units/parser-cxx.r/broken-input.d/input.cc",
    "content": "__attribute__((visibility(\"protected\")))\n        f1(int f1p1,int f1p2 __attribute__([(unused)),int f1p3)\n                __attribute__ ((warn_unused_result,always_inline,deprecated))\n{\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-1111.cpp.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-cxx.r/bug-github-1111.cpp.d/input.cpp",
    "content": "test"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-1671.cpp.d/expected.tags",
    "content": "my_function\tinput.cpp\t/^void my_function()$/;\"\tf\ttyperef:typename:void\ntabs\tinput.cpp\t/^struct tabs { const static long value = x; };$/;\"\ts\tfile:\ntabs\tinput.cpp\t/^struct tabs<x,typename enable_if_c<(x<0)>::type> { const static long value = -x; };$/;\"\ts\tfile:\nvalue\tinput.cpp\t/^struct tabs { const static long value = x; };$/;\"\tm\tstruct:tabs\ttyperef:typename:const long\tfile:\nvalue\tinput.cpp\t/^struct tabs<x,typename enable_if_c<(x<0)>::type> { const static long value = -x; };$/;\"\tm\tstruct:tabs\ttyperef:typename:const long\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-1671.cpp.d/input.cpp",
    "content": "/* Bug #1671 reported by davisking on 2018.01.28 */\n\ntemplate <long x, typename enabled=void>\nstruct tabs { const static long value = x; };\n\n// specialize tabs\ntemplate <long x>\nstruct tabs<x,typename enable_if_c<(x<0)>::type> { const static long value = -x; };\n\nvoid my_function()\n{\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-1675.cpp.d/expected.tags",
    "content": "longlong3\tinput.cpp\t/^struct __device_builtin__ longlong3$/;\"\ts\tfile:\nlonglong4\tinput.cpp\t/^struct __device_builtin__ __builtin_align__(16) longlong4$/;\"\ts\tfile:\nw\tinput.cpp\t/^    long long int x, y, z, w;$/;\"\tm\tstruct:longlong4\ttyperef:typename:long long int\tfile:\nx\tinput.cpp\t/^    long long int x, y, z, w;$/;\"\tm\tstruct:longlong4\ttyperef:typename:long long int\tfile:\nx\tinput.cpp\t/^    long long int x, y, z;$/;\"\tm\tstruct:longlong3\ttyperef:typename:long long int\tfile:\ny\tinput.cpp\t/^    long long int x, y, z, w;$/;\"\tm\tstruct:longlong4\ttyperef:typename:long long int\tfile:\ny\tinput.cpp\t/^    long long int x, y, z;$/;\"\tm\tstruct:longlong3\ttyperef:typename:long long int\tfile:\nz\tinput.cpp\t/^    long long int x, y, z, w;$/;\"\tm\tstruct:longlong4\ttyperef:typename:long long int\tfile:\nz\tinput.cpp\t/^    long long int x, y, z;$/;\"\tm\tstruct:longlong3\ttyperef:typename:long long int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-1675.cpp.d/input.cpp",
    "content": "// issue #1675 opened by bfrg on 01/02/2018\n//\n// Structure declarations that contain macro functions are not parsed correctly.\n\n// structure longlong4 is completely ignored\nstruct __device_builtin__ __builtin_align__(16) longlong4\n{\n    // x,y,z,w will be parsed as (global) variables and not members\n    long long int x, y, z, w;\n};\n\n// this one is parsed correctly\nstruct __device_builtin__ longlong3\n{\n    long long int x, y, z;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-1781.cpp.d/args.ctags",
    "content": "--fields-c++=+{properties}\n--fields=+n+a+Z+S+e\n--kinds-c++=pfzlv\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-1781.cpp.d/expected.tags",
    "content": "copyMatrix\tinput.cpp\t/^void copyMatrix(const ::cv::Mat source_p, LaGenMatDouble *destination_p_p)$/;\"\tf\tline:3\ttyperef:typename:void\tsignature:(const::cv::Mat source_p,LaGenMatDouble * destination_p_p)\tend:17\ncopyMatrix\tinput.cpp\t/^void copyMatrix(const LaGenMatDouble source_p, ::cv::Mat *destination_p_p)$/;\"\tf\tline:19\ttyperef:typename:void\tsignature:(const LaGenMatDouble source_p,::cv::Mat * destination_p_p)\tend:33\ndestination_p_p\tinput.cpp\t/^void copyMatrix(const ::cv::Mat source_p, LaGenMatDouble *destination_p_p)$/;\"\tz\tline:3\tscope:function:copyMatrix\ttyperef:typename:LaGenMatDouble *\tfile:\ndestination_p_p\tinput.cpp\t/^void copyMatrix(const LaGenMatDouble source_p, ::cv::Mat *destination_p_p)$/;\"\tz\tline:19\tscope:function:copyMatrix\ttyperef:typename:::cv::Mat *\tfile:\ni_l\tinput.cpp\t/^    for (int i_l = 0; i_l < source_p.rows(); ++i_l)$/;\"\tl\tline:23\tscope:function:copyMatrix\ttyperef:typename:int\tfile:\tend:23\ni_l\tinput.cpp\t/^    for (int i_l = 0; i_l < source_p.rows; ++i_l)$/;\"\tl\tline:7\tscope:function:copyMatrix\ttyperef:typename:int\tfile:\tend:7\nj_l\tinput.cpp\t/^        for (int j_l = 0; j_l < source_p.cols(); ++j_l)$/;\"\tl\tline:25\tscope:function:copyMatrix\ttyperef:typename:int\tfile:\tend:25\nj_l\tinput.cpp\t/^        for (int j_l = 0; j_l < source_p.cols; ++j_l)$/;\"\tl\tline:9\tscope:function:copyMatrix\ttyperef:typename:int\tfile:\tend:9\nsource_p\tinput.cpp\t/^void copyMatrix(const ::cv::Mat source_p, LaGenMatDouble *destination_p_p)$/;\"\tz\tline:3\tscope:function:copyMatrix\ttyperef:typename:const::cv::Mat\tfile:\nsource_p\tinput.cpp\t/^void copyMatrix(const LaGenMatDouble source_p, ::cv::Mat *destination_p_p)$/;\"\tz\tline:19\tscope:function:copyMatrix\ttyperef:typename:const LaGenMatDouble\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-1781.cpp.d/input.cpp",
    "content": "// Bug reported by reidakdumont on 2018/07/05\n\nvoid copyMatrix(const ::cv::Mat source_p, LaGenMatDouble *destination_p_p)\n{\n    if (destination_p_p->rows() != source_p.rows || destination_p_p->cols() != source_p.cols)\n        *destination_p_p = LaGenMatDouble(source_p.rows, source_p.cols);\n    for (int i_l = 0; i_l < source_p.rows; ++i_l)\n    {\n        for (int j_l = 0; j_l < source_p.cols; ++j_l)\n        {\n            if (source_p.type() == CV_32F)\n                (*destination_p_p)(i_l,j_l) = source_p.at<float>(i_l,j_l);\n            else if (source_p.type() == CV_64F)\n                (*destination_p_p)(i_l,j_l) = source_p.at<double>(i_l,j_l);\n        }\n    }\n}\n\nvoid copyMatrix(const LaGenMatDouble source_p, ::cv::Mat *destination_p_p)\n{\n    if (destination_p_p->rows != source_p.rows() || destination_p_p->cols != source_p.cols())\n        *destination_p_p = ::cv::Mat(source_p.rows(), source_p.cols(), CV_64F);\n    for (int i_l = 0; i_l < source_p.rows(); ++i_l)\n    {\n        for (int j_l = 0; j_l < source_p.cols(); ++j_l)\n        {\n            if (destination_p_p->type() == CV_32F)\n                destination_p_p->at<float>(i_l,j_l) = (source_p)(i_l,j_l);\n            else if (destination_p_p->type() == CV_64F)\n                destination_p_p->at<double>(i_l,j_l) = (source_p)(i_l,j_l);\n        }\n    }\n}"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-2263.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*-l\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-2263.cpp.d/expected.tags",
    "content": "C0\tinput.cc\t/^template <class T> class C0 {$/;\"\tc\tfile:\nT\tinput.cc\t/^template <class T> class C0 {$/;\"\tZ\tclass:C0\ttyperef:meta:class\nt\tinput.cc\t/^  T t;$/;\"\tm\tclass:C0\ttyperef:typename:T\tfile:\nC1\tinput.cc\t/^template <class T, typename T0 = C0<const T>> class C1 {$/;\"\tc\tfile:\nT\tinput.cc\t/^template <class T, typename T0 = C0<const T>> class C1 {$/;\"\tZ\tclass:C1\ttyperef:meta:class\nT0\tinput.cc\t/^template <class T, typename T0 = C0<const T>> class C1 {$/;\"\tZ\tclass:C1\ttyperef:meta:typename\nt0\tinput.cc\t/^  T0 t0;$/;\"\tm\tclass:C1\ttyperef:typename:T0\tfile:\nc1rehash\tinput.cc\t/^  void c1rehash() {}$/;\"\tf\tclass:C1\ttyperef:typename:void\tfile:\nC2\tinput.cc\t/^template <class T, typename T1 = C0<C0<const T>>> class C2 {$/;\"\tc\tfile:\nT\tinput.cc\t/^template <class T, typename T1 = C0<C0<const T>>> class C2 {$/;\"\tZ\tclass:C2\ttyperef:meta:class\nT1\tinput.cc\t/^template <class T, typename T1 = C0<C0<const T>>> class C2 {$/;\"\tZ\tclass:C2\ttyperef:meta:typename\nt1\tinput.cc\t/^  T1 t1;$/;\"\tm\tclass:C2\ttyperef:typename:T1\tfile:\nc2rehash\tinput.cc\t/^  void c2rehash() {}$/;\"\tf\tclass:C2\ttyperef:typename:void\tfile:\nC3\tinput.cc\t/^template <class T, typename T2 = C0<C0<C0<const T>>>> class C3 {$/;\"\tc\tfile:\nT\tinput.cc\t/^template <class T, typename T2 = C0<C0<C0<const T>>>> class C3 {$/;\"\tZ\tclass:C3\ttyperef:meta:class\nT2\tinput.cc\t/^template <class T, typename T2 = C0<C0<C0<const T>>>> class C3 {$/;\"\tZ\tclass:C3\ttyperef:meta:typename\nt2\tinput.cc\t/^  T2 t2;$/;\"\tm\tclass:C3\ttyperef:typename:T2\tfile:\nc3rehash\tinput.cc\t/^  void c3rehash() {}$/;\"\tf\tclass:C3\ttyperef:typename:void\tfile:\nC4\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>> class C4 {$/;\"\tc\tfile:\nT\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>> class C4 {$/;\"\tZ\tclass:C4\ttyperef:meta:class\nT3\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>> class C4 {$/;\"\tZ\tclass:C4\ttyperef:meta:typename\nt3\tinput.cc\t/^  T3 t3;$/;\"\tm\tclass:C4\ttyperef:typename:T3\tfile:\nc4rehash\tinput.cc\t/^  void c4rehash() {}$/;\"\tf\tclass:C4\ttyperef:typename:void\tfile:\nC5\tinput.cc\t/^template <class T, typename T4 = C0<C0<C0<C0<C0<const T>>>>>> class C5 {$/;\"\tc\tfile:\nT\tinput.cc\t/^template <class T, typename T4 = C0<C0<C0<C0<C0<const T>>>>>> class C5 {$/;\"\tZ\tclass:C5\ttyperef:meta:class\nT4\tinput.cc\t/^template <class T, typename T4 = C0<C0<C0<C0<C0<const T>>>>>> class C5 {$/;\"\tZ\tclass:C5\ttyperef:meta:typename\nt4\tinput.cc\t/^  T4 t4;$/;\"\tm\tclass:C5\ttyperef:typename:T4\tfile:\nc5rehash\tinput.cc\t/^  void c5rehash() {}$/;\"\tf\tclass:C5\ttyperef:typename:void\tfile:\nC4x1\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>, class S = int> class C4x1 {$/;\"\tc\tfile:\nT\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>, class S = int> class C4x1 {$/;\"\tZ\tclass:C4x1\ttyperef:meta:class\nT3\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>, class S = int> class C4x1 {$/;\"\tZ\tclass:C4x1\ttyperef:meta:typename\nS\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>, class S = int> class C4x1 {$/;\"\tZ\tclass:C4x1\ttyperef:meta:class\nt3\tinput.cc\t/^  T3 t3;$/;\"\tm\tclass:C4x1\ttyperef:typename:T3\tfile:\ns\tinput.cc\t/^  S  s;$/;\"\tm\tclass:C4x1\ttyperef:typename:S\tfile:\nc4x1rehash\tinput.cc\t/^  void c4x1rehash() {}$/;\"\tf\tclass:C4x1\ttyperef:typename:void\tfile:\nC4x2\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>, class S = C0<const T>> class C4x2 {$/;\"\tc\tfile:\nT\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>, class S = C0<const T>> class C4x2 {$/;\"\tZ\tclass:C4x2\ttyperef:meta:class\nT3\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>, class S = C0<const T>> class C4x2 {$/;\"\tZ\tclass:C4x2\ttyperef:meta:typename\nS\tinput.cc\t/^template <class T, typename T3 = C0<C0<C0<C0<const T>>>>, class S = C0<const T>> class C4x2 {$/;\"\tZ\tclass:C4x2\ttyperef:meta:class\nt3\tinput.cc\t/^  T3 t3;$/;\"\tm\tclass:C4x2\ttyperef:typename:T3\tfile:\ns\tinput.cc\t/^  S  s;$/;\"\tm\tclass:C4x2\ttyperef:typename:S\tfile:\nc4x2rehash\tinput.cc\t/^  void c4x2rehash() {}$/;\"\tf\tclass:C4x2\ttyperef:typename:void\tfile:\nmain\tinput.cc\t/^main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-2263.cpp.d/input.cc",
    "content": "template <class T> class C0 {\n  T t;\n};\n\ntemplate <class T, typename T0 = C0<const T>> class C1 {\n  T0 t0;\npublic:\n  void c1rehash() {}\n};\n\ntemplate <class T, typename T1 = C0<C0<const T>>> class C2 {\n  T1 t1;\npublic:\n  void c2rehash() {}\n};\n\ntemplate <class T, typename T2 = C0<C0<C0<const T>>>> class C3 {\n  T2 t2;\npublic:\n  void c3rehash() {}\n};\n\ntemplate <class T, typename T3 = C0<C0<C0<C0<const T>>>>> class C4 {\n  T3 t3;\npublic:\n  void c4rehash() {}\n};\n\ntemplate <class T, typename T4 = C0<C0<C0<C0<C0<const T>>>>>> class C5 {\n  T4 t4;\npublic:\n  void c5rehash() {}\n};\n\ntemplate <class T, typename T3 = C0<C0<C0<C0<const T>>>>, class S = int> class C4x1 {\n  T3 t3;\n  S  s;\npublic:\n  void c4x1rehash() {}\n};\n\ntemplate <class T, typename T3 = C0<C0<C0<C0<const T>>>>, class S = C0<const T>> class C4x2 {\n  T3 t3;\n  S  s;\npublic:\n  void c4x2rehash() {}\n};\n\n\nint\nmain(void)\n{\n  C0 <int> c0;\n  C1 <int> c1();\n  C2 <int> c2();\n  C3 <int> c3();\n  C4 <int> c4();\n  C4x1 <int, int, int> cx41();\n  C4x2 <int, int, int> cx42();\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-2538.cpp.d/args.ctags",
    "content": "-D'M=T(M)'\n-D'x=y.x'"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-2538.cpp.d/expected.tags",
    "content": "f\tinput.cpp\t/^int f(int v)$/;\"\tf\ttyperef:typename:int\ntest\tinput.cpp\t/^struct test$/;\"\ts\tfile:\nx\tinput.cpp\t/^\tint x;$/;\"\tm\tstruct:test\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-2538.cpp.d/input.cpp",
    "content": "// Recursive macro expansion causes a segmentation fault\n// or infinite loop\n\nstruct test\n{\n\tint x;\n};\n\nint f(int v)\n{\n\tstruct test y;\n\ty.x = 10;\n\treturn v & M;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-3019.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-3019.d/expected.tags",
    "content": "X\tinput.cpp\t/^struct X {$/;\"\ts\tfile:\noperator int\tinput.cpp\t/^    operator int() const { return 7; }$/;\"\tf\tstruct:X\tfile:\noperator int*\tinput.cpp\t/^    explicit operator int*() const { return nullptr; }$/;\"\tf\tstruct:X\tfile:\narr_t\tinput.cpp\t/^    using arr_t = int[3];$/;\"\tt\tstruct:X\ttyperef:typename:int[3]\tfile:\noperator arr_t*\tinput.cpp\t/^    operator arr_t*() const { return nullptr; } \\/\\/ OK if done through typedef$/;\"\tf\tstruct:X\tfile:\nmain\tinput.cpp\t/^int main()$/;\"\tf\ttyperef:typename:int\nmyint\tinput-1.cpp\t/^typedef int myint;$/;\"\tt\ttyperef:typename:int\tfile:\nPoint\tinput-1.cpp\t/^struct Point {$/;\"\ts\tfile:\nPoint\tinput-1.cpp\t/^  Point (int i): x(i), y(i) {}$/;\"\tf\tstruct:Point\tfile:\nx\tinput-1.cpp\t/^  int x,y;$/;\"\tm\tstruct:Point\ttyperef:typename:int\tfile:\ny\tinput-1.cpp\t/^  int x,y;$/;\"\tm\tstruct:Point\ttyperef:typename:int\tfile:\nInt\tinput-1.cpp\t/^class Int {$/;\"\tc\tfile:\nInt\tinput-1.cpp\t/^  Int (int i = 0): val(i), p(i) {}$/;\"\tf\tclass:Int\tfile:\noperator myint\tinput-1.cpp\t/^  operator myint() const { return val; }$/;\"\tf\tclass:Int\tfile:\noperator const myint\tinput-1.cpp\t/^  operator const myint() const { return val; }$/;\"\tf\tclass:Int\tfile:\noperator myint*\tinput-1.cpp\t/^  operator myint*() const { return NULL; }$/;\"\tf\tclass:Int\tfile:\noperator const myint*\tinput-1.cpp\t/^  operator const myint*() const { return NULL; }$/;\"\tf\tclass:Int\tfile:\noperator myint*const\tinput-1.cpp\t/^  operator myint*const() const { return NULL; }$/;\"\tf\tclass:Int\tfile:\noperator const myint*const\tinput-1.cpp\t/^  operator const myint*const() const { return NULL; }$/;\"\tf\tclass:Int\tfile:\noperator int\tinput-1.cpp\t/^  operator int() const { return val; }$/;\"\tf\tclass:Int\tfile:\noperator int*\tinput-1.cpp\t/^  operator int *() const { return 0; }$/;\"\tf\tclass:Int\tfile:\noperator const int*\tinput-1.cpp\t/^  operator const int *() const { return 0; }$/;\"\tf\tclass:Int\tfile:\noperator const int*const\tinput-1.cpp\t/^  operator const int *const() const { return 0; }$/;\"\tf\tclass:Int\tfile:\noperator int*const\tinput-1.cpp\t/^  operator int *const() const { return 0; }$/;\"\tf\tclass:Int\tfile:\noperator struct Point*\tinput-1.cpp\t/^  operator struct Point *() const { return (Point *)&p; }$/;\"\tf\tclass:Int\tfile:\noperator const struct Point*\tinput-1.cpp\t/^  operator const struct Point *() const { return 0; }$/;\"\tf\tclass:Int\tfile:\noperator const struct Point*const\tinput-1.cpp\t/^  operator const struct Point *const() const { return 0; }$/;\"\tf\tclass:Int\tfile:\noperator struct Point*const\tinput-1.cpp\t/^  operator struct Point *const() const { return 0; }$/;\"\tf\tclass:Int\tfile:\nval\tinput-1.cpp\t/^  int val;$/;\"\tm\tclass:Int\ttyperef:typename:int\tfile:\np\tinput-1.cpp\t/^  struct Point p;$/;\"\tm\tclass:Int\ttyperef:struct:Point\tfile:\nmain\tinput-1.cpp\t/^int main(void)$/;\"\tf\ttyperef:typename:int\nmuchar\tinput-2.cpp\t/^typedef char muchar;$/;\"\tt\ttyperef:typename:char\tfile:\nRange\tinput-2.cpp\t/^struct Range {$/;\"\ts\tfile:\nRange\tinput-2.cpp\t/^  Range (int b, int e): begin(b), end(end) {}$/;\"\tf\tstruct:Range\tfile:\nbegin\tinput-2.cpp\t/^  int begin, end;$/;\"\tm\tstruct:Range\ttyperef:typename:int\tfile:\nend\tinput-2.cpp\t/^  int begin, end;$/;\"\tm\tstruct:Range\ttyperef:typename:int\tfile:\nChar\tinput-2.cpp\t/^class Char {$/;\"\tc\tfile:\nChar\tinput-2.cpp\t/^  Char (char i = 0): val(i), r(i, i) {}$/;\"\tf\tclass:Char\tfile:\noperator volatile muchar\tinput-2.cpp\t/^  operator volatile muchar() const { return val; }$/;\"\tf\tclass:Char\tfile:\noperator volatile const muchar*\tinput-2.cpp\t/^  operator volatile const muchar*() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile const muchar*const\tinput-2.cpp\t/^  operator volatile const muchar*const() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile int*\tinput-2.cpp\t/^  operator volatile int *() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile int*volatile\tinput-2.cpp\t/^  operator volatile int *volatile() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator int*volatile\tinput-2.cpp\t/^  operator int *volatile() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile const int*\tinput-2.cpp\t/^  operator volatile const int *() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile const int*volatile\tinput-2.cpp\t/^  operator volatile const int *volatile() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator int*volatile const\tinput-2.cpp\t/^  operator int *volatile const() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile const int*\tinput-2.cpp\t/^  operator volatile const int *() volatile { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile const int*volatile\tinput-2.cpp\t/^  operator volatile const int *volatile() volatile { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator int*volatile const\tinput-2.cpp\t/^  operator int *volatile const() volatile { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile struct Range*\tinput-2.cpp\t/^  operator volatile struct Range *() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile struct Range*volatile\tinput-2.cpp\t/^  operator volatile struct Range *volatile() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator struct Range*volatile\tinput-2.cpp\t/^  operator struct Range *volatile() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile const struct Range*\tinput-2.cpp\t/^  operator volatile const struct Range *() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile const struct Range*volatile\tinput-2.cpp\t/^  operator volatile const struct Range *volatile() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator struct Range*volatile const\tinput-2.cpp\t/^  operator struct Range *volatile const() const { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile const struct Range*\tinput-2.cpp\t/^  operator volatile const struct Range *() volatile { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator volatile const struct Range*volatile\tinput-2.cpp\t/^  operator volatile const struct Range *volatile() volatile { return 0; }$/;\"\tf\tclass:Char\tfile:\noperator struct Range*volatile const\tinput-2.cpp\t/^  operator struct Range *volatile const() volatile { return 0; }      $/;\"\tf\tclass:Char\tfile:\nval\tinput-2.cpp\t/^  int val;$/;\"\tm\tclass:Char\ttyperef:typename:int\tfile:\nr\tinput-2.cpp\t/^  struct Range r;$/;\"\tm\tclass:Char\ttyperef:struct:Range\tfile:\nmain\tinput-2.cpp\t/^int main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-3019.d/input-1.cpp",
    "content": "typedef int myint;\n\nstruct Point {\n  Point (int i): x(i), y(i) {}\n  int x,y;\n};\n\nclass Int {\npublic:\n  Int (int i = 0): val(i), p(i) {}\n\n  operator myint() const { return val; }\n  operator const myint() const { return val; }\n  operator myint*() const { return NULL; }\n  operator const myint*() const { return NULL; }\n\n  operator myint*const() const { return NULL; }\n  operator const myint*const() const { return NULL; }\n  \n  operator int() const { return val; }\n\n  operator int *() const { return 0; }\n  operator const int *() const { return 0; }\n  operator const int *const() const { return 0; }\n  operator int *const() const { return 0; }\n\n  operator struct Point *() const { return (Point *)&p; }\n  operator const struct Point *() const { return 0; }\n  operator const struct Point *const() const { return 0; }\n  operator struct Point *const() const { return 0; }\n\nprivate:\n  int val;\n  struct Point p;\n};\n\nint main(void)\n{\n  return Int ();\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-3019.d/input-2.cpp",
    "content": "typedef char muchar;\n\nstruct Range {\n  Range (int b, int e): begin(b), end(end) {}\n  int begin, end;\n};\n\nclass Char {\npublic:\n  Char (char i = 0): val(i), r(i, i) {}\n\n  operator volatile muchar() const { return val; }\n  operator volatile const muchar*() const { return 0; }\n  operator volatile const muchar*const() const { return 0; }\n  operator volatile int *() const { return 0; }\n  operator volatile int *volatile() const { return 0; }\n  operator int *volatile() const { return 0; }\n  operator volatile const int *() const { return 0; }\n  operator volatile const int *volatile() const { return 0; }\n  operator int *volatile const() const { return 0; }\n\n  operator volatile const int *() volatile { return 0; }\n  operator volatile const int *volatile() volatile { return 0; }\n  operator int *volatile const() volatile { return 0; }\n\n  operator volatile struct Range *() const { return 0; }\n  operator volatile struct Range *volatile() const { return 0; }\n  operator struct Range *volatile() const { return 0; }\n  \n  operator volatile const struct Range *() const { return 0; }\n  operator volatile const struct Range *volatile() const { return 0; }\n  operator struct Range *volatile const() const { return 0; }\n\n  operator volatile const struct Range *() volatile { return 0; }\n  operator volatile const struct Range *volatile() volatile { return 0; }\n  operator struct Range *volatile const() volatile { return 0; }      \n  \nprivate:\n  int val;\n  struct Range r;\n};\n\nint main(void)\n{\n  return Char ();\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-3019.d/input.cpp",
    "content": "// Taken from #3019 submitted by @hammockt\nstruct X {\n    //implicit conversion\n    operator int() const { return 7; }\n \n    // explicit conversion\n    explicit operator int*() const { return nullptr; }\n \n//   Error: array operator not allowed in conversion-type-id\n//   operator int(*)[3]() const { return nullptr; }\n    using arr_t = int[3];\n    operator arr_t*() const { return nullptr; } // OK if done through typedef\n//  operator arr_t () const; // Error: conversion to array not allowed in any case\n};\n \nint main()\n{\n    X x;\n \n    int n = static_cast<int>(x);   // OK: sets n to 7\n    int m = x;                     // OK: sets m to 7\n \n    int* p = static_cast<int*>(x);  // OK: sets p to null\n//  int* q = x; // Error: no implicit conversion\n \n    int (*pa)[3] = x;  // OK\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-3413.cpp.d/README",
    "content": "This is a crash test. So no expected.tags here.\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-3413.cpp.d/input.hpp",
    "content": "struct S<P<T, <>\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-871.cpp.d/args.ctags",
    "content": "--kinds-c++=*\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-871.cpp.d/expected.tags",
    "content": "funa\tinput.cpp\t/^bool funa()$/;\"\tf\ttyperef:typename:bool\nfunb\tinput.cpp\t/^int funb()$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-871.cpp.d/input.cpp",
    "content": "// Bug reported by hierabyss on github.com.\n// funb() was not present in the ctags output.\n\nbool funa()\n{\n    if (first) return false;\n\n#if defined (MACRO)\n    if (a)\n    {\n        if (second)\n#else               \n    if (a)\n    {\n#endif              \n        return false;\n    }\n\n    return true;\n}\n\nint funb()\n{\n}"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-pull-972.cpp.d/args.ctags",
    "content": "--sort=no\n--fields=+StiZK\n--fields-c++=+{template}{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-pull-972.cpp.d/expected.tags",
    "content": "A\tinput.cpp\t/^class A : public T$/;\"\tclass\tfile:\tinherits:T\ttemplate:<typename T=void,bool B1=true>\nthis_type\tinput.cpp\t/^    typedef A<T, B1> this_type;$/;\"\ttypedef\tscope:class:A\ttyperef:typename:A<T,B1>\tfile:\nA\tinput.cpp\t/^    A(int i ) : m_i(i)$/;\"\tfunction\tscope:class:A\tfile:\tsignature:(int i)\ncreate\tinput.cpp\t/^    static A create(int i)$/;\"\tfunction\tscope:class:A\ttyperef:typename:A\tfile:\tsignature:(int i)\tproperties:static\ng_i\tinput.cpp\t/^    static int g_i;$/;\"\tmember\tscope:class:A\ttyperef:typename:int\tfile:\tproperties:static\nm_i\tinput.cpp\t/^    int m_i;$/;\"\tmember\tscope:class:A\ttyperef:typename:int\tfile:\ng_i\tinput.cpp\t/^int A<T, B1>::g_i; \\/\\/ (3) fail during parsing static member definition/;\"\tmember\tscope:class:A<T, B1>\ttyperef:typename:int\ttemplate:<typename T,bool B1>\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-github-pull-972.cpp.d/input.cpp",
    "content": "// Reported by Przemyslaw Szymanski on 02.06.2016\n\ntemplate <typename T = void, bool B1 = true> // (1) fail if there are multiple params with default values\nclass A : public T\n{\npublic:\n    typedef A<T, B1> this_type;\n\n    A(int i ) : m_i(i)\n    {\n    }\n\n    static A create(int i)\n    {\n        return this_type(i); // (2) fail here\n    }\n\n    static int g_i;\nprivate:\n    int m_i;\n};\n\ntemplate <typename T, bool B1>\nint A<T, B1>::g_i; // (3) fail during parsing static member definition"
  },
  {
    "path": "Units/parser-cxx.r/bug-issue-3166.d/args.ctags",
    "content": "--sort=no\n--fields=+e\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-issue-3166.d/expected.tags",
    "content": "DEAMER_LANGUAGE_DATASTRUCTURE_DEFINITION_OBJECT_MAIN_THREAT_THREAT_ANALYZER_DEAMER_LEXICON_TYPE_H\tinput.cxx\t/^#define DEAMER_LANGUAGE_DATASTRUCTURE_DEFINITION_OBJECT_MAIN_THREAT_THREAT_ANALYZER_DEAMER_LEXIC/;\"\td\tfile:\tend:24\ndeamer\tinput.cxx\t/^namespace deamer::language::type::definition::object::main::threat::deamer::lexicon$/;\"\tn\tfile:\tend:42\nlanguage\tinput.cxx\t/^namespace deamer::language::type::definition::object::main::threat::deamer::lexicon$/;\"\tn\tnamespace:deamer\tfile:\tend:42\ntype\tinput.cxx\t/^namespace deamer::language::type::definition::object::main::threat::deamer::lexicon$/;\"\tn\tnamespace:deamer::language\tfile:\tend:42\ndefinition\tinput.cxx\t/^namespace deamer::language::type::definition::object::main::threat::deamer::lexicon$/;\"\tn\tnamespace:deamer::language::type\tfile:\tend:42\nobject\tinput.cxx\t/^namespace deamer::language::type::definition::object::main::threat::deamer::lexicon$/;\"\tn\tnamespace:deamer::language::type::definition\tfile:\tend:42\nmain\tinput.cxx\t/^namespace deamer::language::type::definition::object::main::threat::deamer::lexicon$/;\"\tn\tnamespace:deamer::language::type::definition::object\tfile:\tend:42\nthreat\tinput.cxx\t/^namespace deamer::language::type::definition::object::main::threat::deamer::lexicon$/;\"\tn\tnamespace:deamer::language::type::definition::object::main\tfile:\tend:42\ndeamer\tinput.cxx\t/^namespace deamer::language::type::definition::object::main::threat::deamer::lexicon$/;\"\tn\tnamespace:deamer::language::type::definition::object::main::threat\tfile:\tend:42\nlexicon\tinput.cxx\t/^namespace deamer::language::type::definition::object::main::threat::deamer::lexicon$/;\"\tn\tnamespace:deamer::language::type::definition::object::main::threat::deamer\tfile:\tend:42\nType\tinput.cxx\t/^\tenum class Type$/;\"\tg\tnamespace:deamer::language::type::definition::object::main::threat::deamer::lexicon\tfile:\tend:41\nUnknown\tinput.cxx\t/^\t\tUnknown = 0,$/;\"\te\tenum:deamer::language::type::definition::object::main::threat::deamer::lexicon::Type\tfile:\nUnusedTerminal\tinput.cxx\t/^\t\tUnusedTerminal = 1,$/;\"\te\tenum:deamer::language::type::definition::object::main::threat::deamer::lexicon::Type\tfile:\nDeletedTerminalReferencedInGrammar\tinput.cxx\t/^\t\tDeletedTerminalReferencedInGrammar = 2,$/;\"\te\tenum:deamer::language::type::definition::object::main::threat::deamer::lexicon::Type\tfile:\nCrashTerminalReferencedInGrammar\tinput.cxx\t/^\t\tCrashTerminalReferencedInGrammar = 3,$/;\"\te\tenum:deamer::language::type::definition::object::main::threat::deamer::lexicon::Type\tfile:\nTerminalIsBaseSetOfLaterTerminal\tinput.cxx\t/^\t\tTerminalIsBaseSetOfLaterTerminal = 4,$/;\"\te\tenum:deamer::language::type::definition::object::main::threat::deamer::lexicon::Type\tfile:\nNonStandardNamingConvention\tinput.cxx\t/^\t\tNonStandardNamingConvention = 5,$/;\"\te\tenum:deamer::language::type::definition::object::main::threat::deamer::lexicon::Type\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug-issue-3166.d/input.cxx",
    "content": "// Taken from theDeamerProject/Deamer/include/Deamer/Language/Type/Definition/Object/Main/Threat/Threat/Analyzer/Deamer/Lexicon/Type.h\n// of https://github.com/Deruago/theDeamerProject\n/*\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; either version 3\n * of the License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n */\n/*\n * Part of the DeamerProject.\n * For more information go to: https://github.com/Deruago/theDeamerProject\n */\n\n#ifndef DEAMER_LANGUAGE_DATASTRUCTURE_DEFINITION_OBJECT_MAIN_THREAT_THREAT_ANALYZER_DEAMER_LEXICON_TYPE_H\n#define DEAMER_LANGUAGE_DATASTRUCTURE_DEFINITION_OBJECT_MAIN_THREAT_THREAT_ANALYZER_DEAMER_LEXICON_TYPE_H\n\nnamespace deamer::language::type::definition::object::main::threat::deamer::lexicon\n{\n\t/*! \\enum Type\n\t *\n\t *\t\\brief All lexicon threats\n\t */\n\tenum class Type\n\t{\n\t\tUnknown = 0,\n\n\t\tUnusedTerminal = 1,\n\t\tDeletedTerminalReferencedInGrammar = 2,\n\t\tCrashTerminalReferencedInGrammar = 3,\n\t\tTerminalIsBaseSetOfLaterTerminal = 4,\n\t\tNonStandardNamingConvention = 5,\n\t};\n}\n\n#endif // DEAMER_LANGUAGE_DATASTRUCTURE_DEFINITION_OBJECT_MAIN_THREAT_THREAT_ANALYZER_DEAMER_LEXICON_TYPE_H\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1020715.cpp.d/expected.tags",
    "content": "f\tinput.cpp\t/^void f() {$/;\"\tf\ttyperef:typename:void\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1020715.cpp.d/input.cpp",
    "content": "void f() {\n done(a<<1);\n a->a;\n if (a->a) {\n }\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1093123.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1093123.cpp.d/expected.tags",
    "content": "main\tinput.cpp\t/^int main() {$/;\"\tf\ttyperef:typename:int\nstd\tinput.cpp\t/^using namespace std;$/;\"\tU\tfunction:main\nm\tinput.cpp\t/^int m;$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1093123.cpp.d/input.cpp",
    "content": "#include <iostream>\n\nint main() {\nusing namespace std;\ncout << 0 << endl;\nint m;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1187505.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1187505.cpp.d/expected.tags",
    "content": "Abra\tinput.cpp\t/^class Abra : public Kadabra$/;\"\tc\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1187505.cpp.d/input.cpp",
    "content": "MY_MACRO(qwerty < 1);\n\nclass Abra : public Kadabra\n{\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1252.cpp.d/expected.tags",
    "content": "_PyNone_Type\tinput.cpp\t/^PyAPI_DATA(PyTypeObject) _PyNone_Type;/;\"\tv\ttyperef:typename:PyAPI_DATA (PyTypeObject)\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1252.cpp.d/input.cpp",
    "content": "PyAPI_DATA(PyTypeObject) _PyNone_Type;"
  },
  {
    "path": "Units/parser-cxx.r/bug1548443.cpp.d/args.ctags",
    "content": "--kinds-c++=+p\n--fields=+iaS\n--extras=+q\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1548443.cpp.d/expected.tags",
    "content": "TestStruct\tinput.cpp\t/^struct TestStruct$/;\"\ts\tfile:\nTestStruct::_number\tinput.cpp\t/^int _number;$/;\"\tm\tstruct:TestStruct\ttyperef:typename:int\tfile:\taccess:public\nTestUnion\tinput.cpp\t/^union TestUnion$/;\"\tu\tfile:\nTestUnion::_number\tinput.cpp\t/^int _number;$/;\"\tm\tunion:TestUnion\ttyperef:typename:int\tfile:\taccess:public\n_number\tinput.cpp\t/^int _number;$/;\"\tm\tstruct:TestStruct\ttyperef:typename:int\tfile:\taccess:public\n_number\tinput.cpp\t/^int _number;$/;\"\tm\tunion:TestUnion\ttyperef:typename:int\tfile:\taccess:public\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1548443.cpp.d/input.cpp",
    "content": "union TestUnion\n{\nint _number;\n};\n\nstruct TestStruct\n{\nint _number;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1563476.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1563476.cpp.d/expected.tags",
    "content": "g\tinput.cpp\t/^int g() {$/;\"\tf\ttyperef:typename:int\nIntroduceBitDef\tinput.cpp\t/^struct IntroduceBitDef< Accessor, typename$/;\"\ts\tfile:\nAccessor\tinput.cpp\t/^template< typename Accessor >$/;\"\tZ\tstruct:IntroduceBitDef\ttyperef:meta:typename\nf\tinput.cpp\t/^ int f() { }$/;\"\tf\tstruct:IntroduceBitDef\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1563476.cpp.d/input.cpp",
    "content": "int g() {\n}\n\ntemplate< typename Accessor, typename bEnable = void >\nstruct IntroduceBitDef;\n\ntemplate< typename Accessor >\nstruct IntroduceBitDef< Accessor, typename\nboost::enable_if_c< CoreConfig::VERSION <= 3 >::type >\n{\n\n// class body here\n// anything after this point is not parsed by ctags\n int f() { }\n\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1575055.cpp.d/README",
    "content": "'m' kind is given to the `variable' in the input.\nI, Masatake YAMATO, think 'v' kind should be ginve instead.\n\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1575055.cpp.d/expected.tags",
    "content": "MyClass\tinput.cpp\t/^\tclass MyClass { };$/;\"\tc\tnamespace:TheNamespace\tfile:\nTheNamespace\tinput.cpp\t/^namespace TheNamespace {$/;\"\tn\tfile:\nvariable\tinput.cpp\t/^\tint variable;$/;\"\tv\tnamespace:TheNamespace\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1575055.cpp.d/input.cpp",
    "content": "namespace TheNamespace {\n\tclass MyClass { };\n\tint variable;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1585745.cpp.d/expected.tags",
    "content": "Class5\tinput.cpp\t/^class Class5 {$/;\"\tc\tfile:\n~Class1\tinput.cpp\t/^Class1::~Class1() { }$/;\"\tf\tclass:Class1\n~Class2\tinput.cpp\t/^Class2::~ Class2() { }$/;\"\tf\tclass:Class2\n~Class3\tinput.cpp\t/^Class3:: ~Class3() { }$/;\"\tf\tclass:Class3\n~Class4\tinput.cpp\t/^Class4:: ~ Class4() { }$/;\"\tf\tclass:Class4\n~Class5\tinput.cpp\t/^    public: ~ Class5() { }$/;\"\tf\tclass:Class5\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1585745.cpp.d/input.cpp",
    "content": "// Despite the weird whitespace, all these destructors should be recognized and tagged.\nClass1::~Class1() { }\nClass2::~ Class2() { }\nClass3:: ~Class3() { }\nClass4:: ~ Class4() { }\nclass Class5 {\n    public: ~ Class5() { }\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1770479.cpp.d/args.ctags",
    "content": "--kinds-c++=+l\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1770479.cpp.d/expected.tags",
    "content": "a\tinput.cpp\t/^  std::ostringstream a;$/;\"\tl\tfunction:main\ttyperef:typename:std::ostringstream\tfile:\nb\tinput.cpp\t/^  std::ostringstream b;$/;\"\tl\tfunction:main\ttyperef:typename:std::ostringstream\tfile:\nfoo\tinput.cpp\t/^int foo (int i)$/;\"\tf\ttyperef:typename:int\nmain\tinput.cpp\t/^int main (int argc, char **argv)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1770479.cpp.d/input.cpp",
    "content": "#include <sstream>\n\nint main (int argc, char **argv)\n{\n  std::ostringstream a;\n  a << \"a\";\n\n  std::ostringstream b;\n  b << \"b\";\n\n  return 0;\n}\n\nint foo (int i)\n{\n  return i;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1773926.cpp.d/args.ctags",
    "content": "-n\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1773926.cpp.d/expected.tags",
    "content": "ERROR_HAPPENED\tinput.cpp\t3;\"\td\tfile:\nNEXT_DEFINE\tinput.cpp\t5;\"\td\tfile:\nOK\tinput.cpp\t4;\"\td\tfile:\nmain\tinput.cpp\t7;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1773926.cpp.d/input.cpp",
    "content": "#include <stdio.h>\r\n\r\n#define ERROR_HAPPENED\r 50 \r\r\r\r\n#define OK 2\r\n#define NEXT_DEFINE 3\r\n\r\nint main(int argc, char* argv[])\r\n{\r\n    printf(\"Hello world\\n\");\r\n    return 0;\r\n}\r\n\r\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1799340.cpp.d/expected.tags",
    "content": "f1\tinput.cpp\t/^std::string & f1() {}$/;\"\tf\ttyperef:typename:std::string &\nf2\tinput.cpp\t/^const std::string & f2() {}$/;\"\tf\ttyperef:typename:const std::string &\nf3\tinput.cpp\t/^std::string const & f3() {}$/;\"\tf\ttyperef:typename:std::string const &\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1799340.cpp.d/input.cpp",
    "content": "std::string & f1() {}\nconst std::string & f2() {}\nstd::string const & f3() {}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1799343-1.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1799343-1.cpp.d/expected.tags",
    "content": "C\tinput.cpp\t/^struct C { int x; };$/;\"\ts\tfile:\nx\tinput.cpp\t/^struct C { int x; };$/;\"\tm\tstruct:C\ttyperef:typename:int\tfile:\nD\tinput.cpp\t/^struct D : ::C {$/;\"\ts\tfile:\nD\tinput.cpp\t/^ D() { x = 123; }$/;\"\tf\tstruct:D\tfile:\n~D\tinput.cpp\t/^ ~D() { std::cout << x << std::endl; }$/;\"\tf\tstruct:D\tfile:\nmain\tinput.cpp\t/^int main(void) {$/;\"\tf\ttyperef:typename:int\nd\tinput.cpp\t/^ D d;$/;\"\tl\tfunction:main\ttyperef:typename:D\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1799343-1.cpp.d/input.cpp",
    "content": "#include <iostream>\nstruct C { int x; };\nstruct D : ::C {\n D() { x = 123; }\n ~D() { std::cout << x << std::endl; }\n};\nint main(void) {\n D d;\n return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1799343-2.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1799343-2.cpp.d/expected.tags",
    "content": "P\tinput.cpp\t/^class P {$/;\"\tc\tfile:\nx\tinput.cpp\t/^   int x;$/;\"\tm\tclass:P\ttyperef:typename:int\tfile:\nA\tinput.cpp\t/^namespace A {$/;\"\tn\tfile:\nP\tinput.cpp\t/^   class P {$/;\"\tc\tnamespace:A\tfile:\nx\tinput.cpp\t/^     int x;$/;\"\tm\tclass:A::P\ttyperef:typename:int\tfile:\nQ\tinput.cpp\t/^   class Q {$/;\"\tc\tnamespace:A\tfile:\ny\tinput.cpp\t/^     int y;$/;\"\tm\tclass:A::Q\ttyperef:typename:int\tfile:\nC\tinput.cpp\t/^   namespace C {$/;\"\tn\tnamespace:A\tfile:\nR\tinput.cpp\t/^     class R: ::P, A::Q {$/;\"\tc\tnamespace:A::C\tfile:\nz\tinput.cpp\t/^       int z;$/;\"\tm\tclass:A::C::R\ttyperef:typename:int\tfile:\nf\tinput.cpp\t/^       int f (int v) { return v + x; }$/;\"\tf\tclass:A::C::R\ttyperef:typename:int\tfile:\nv\tinput.cpp\t/^       int f (int v) { return v + x; }$/;\"\tz\tfunction:A::C::R::f\ttyperef:typename:int\tfile:\nB\tinput.cpp\t/^namespace B {$/;\"\tn\tfile:\nS\tinput.cpp\t/^   class S : A::C::R {$/;\"\tc\tnamespace:B\tfile:\nt\tinput.cpp\t/^     int t;$/;\"\tm\tclass:B::S\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1799343-2.cpp.d/input.cpp",
    "content": "class P {\n  protected:\n   int x;\n};\n\nnamespace A {\n   class P {\n  protected:\n     int x;\n   };\n   class Q {\n     int y;\n   };\n\n   namespace C {\n     class R: ::P, A::Q {\n       int z;\n       int f (int v) { return v + x; }\n     };\n   }\n}\n\nnamespace B {\n   class S : A::C::R {\n     int t;\n   };\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1907083.cpp.d/expected.tags",
    "content": "m1\tinput.cpp\t/^C::T * C::m1() {}$/;\"\tf\tclass:C\ttyperef:typename:C::T *\nm2\tinput.cpp\t/^C::T * const C::m2() {}$/;\"\tf\tclass:C\ttyperef:typename:C::T * const\nm3\tinput.cpp\t/^C::T const * C::m3() {}$/;\"\tf\tclass:C\ttyperef:typename:C::T const *\nm4\tinput.cpp\t/^C::T const * const C::m4() {}$/;\"\tf\tclass:C\ttyperef:typename:C::T const * const\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1907083.cpp.d/input.cpp",
    "content": "// All of these should have \"class:C\", but m2-m4 have \"class C::C\" with ctags 5.7.\nC::T * C::m1() {}\nC::T * const C::m2() {}\nC::T const * C::m3() {}\nC::T const * const C::m4() {}\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1924919.cpp.d/README",
    "content": "The orignal bug report can be found in https://sourceforge.net/p/ctags/bugs/217/\n\nI, Masatake YAMATO, think both a bug report and developer of e-ctags go wrong.\n\nLet's consider following input:\n\n    #include <string>\n    namespace mud {\n\t    std::string MajorVersion;\n\t    std::string MinorVersion;\n\t    int (* foo) (void);\n    };\n    \n\nAll MajorVersion, MinorVersion and foo are tagged with 'm' kind.\nThis is less informative. Whether they are members or not can\nbe known from \"namespace:mud\" field of tags file.\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1924919.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1924919.cpp.d/expected.tags",
    "content": "mud\tinput.cpp\t/^namespace mud {$/;\"\tn\tfile:\nMajorVersion\tinput.cpp\t/^\tstd::string MajorVersion;$/;\"\tv\tnamespace:mud\ttyperef:typename:std::string\nMinorVersion\tinput.cpp\t/^\tstd::string MinorVersion;$/;\"\tv\tnamespace:mud\ttyperef:typename:std::string\nfoo\tinput.cpp\t/^\tint (* foo) (void);$/;\"\tv\tnamespace:mud\ttyperef:typename:int (*)(void)\n"
  },
  {
    "path": "Units/parser-cxx.r/bug1924919.cpp.d/input.cpp",
    "content": "#include <string>\nnamespace mud {\n\tstd::string MajorVersion;\n\tstd::string MinorVersion;\n\tint (* foo) (void);\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/bug639639.cpp.d/expected.tags",
    "content": "Namespace1\tinput.h\t/^namespace Namespace1$/;\"\tn\n__anon4605901a0103\tinput.h\t/^enum {anon2=1000};$/;\"\tg\nanon2\tinput.h\t/^enum {anon2=1000};$/;\"\te\tenum:__anon4605901a0103\n"
  },
  {
    "path": "Units/parser-cxx.r/bug639639.cpp.d/input.h",
    "content": "/*\nDate: Sun, 17 Nov 2002 04:41:42 -0800\nSubject: [ ctags-Bugs-639639 ] incorrect enum field for C++ header\n\nBugs item #639639, was opened at 2002-11-17 13:41\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=639639&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Matthias S. Benkmann (mbenkmann)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: incorrect enum field for C++ header\n\nInitial Comment:\n----------- temp2.h -------------\n*/\nnamespace Namespace1\n{\n  int function2(char* str);\n}\n\nenum {anon2=1000};\n----------------------------  \n/*\n> ctags --excmd=number --fields=+kKmnsSz\n--file-scope=no -f - temp2.h\n\nNamespace1      temp2.h 1;\"     kind:namespace  line:1\nanon2   temp2.h 6;\"     kind:enumerator line:6 \nenum:Namespace1\n\n\nAs you can see ctags thinks that anon2 belongs to enum\nNamespace1 which it obviously doesn't (Namespace1 is\nnot even an enum). It should be enum:<anonymous>.\n\n\n----------------------------------------------------------------------\n\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=639639&group_id=6556\n*/\n"
  },
  {
    "path": "Units/parser-cxx.r/bug639644.cpp.d/expected.tags",
    "content": "__anon21d591360111\tinput.h\t/^{$/;\"\tn\nfoo\tinput.h\t/^  int foo;$/;\"\tv\tnamespace:__anon21d591360111\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/bug639644.cpp.d/input.h",
    "content": "/*\nDate: Sun, 17 Nov 2002 04:57:43 -0800\nSubject: [ ctags-Bugs-639644 ] anonymous namespaces in headers\n\nBugs item #639644, was opened at 2002-11-17 13:57\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=639644&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Matthias S. Benkmann (mbenkmann)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: anonymous namespaces in headers\n\nInitial Comment:\n--------------------temp3.h----------------\n*/\nnamespace\n{\n  int foo;\n}\n/*\n---------------------------------------------\n\n> ctags -f - temp3.h\n\nfoo     temp3.h /^  int foo;$/;\"        m       namespace:\n\nThat last field should be \"namespace:<anonymous>\"\nand the kind field should be variable, not member.\n\n\n\n----------------------------------------------------------------------\n\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=639644&group_id=6556\n*/\n"
  },
  {
    "path": "Units/parser-cxx.r/bug665086.cpp.d/expected.tags",
    "content": "C12\tinput.cpp\t/^    class C12{}$/;\"\tc\tnamespace:N1::N2\tfile:\nN1\tinput.cpp\t/^namespace N1$/;\"\tn\tfile:\nN2\tinput.cpp\t/^  namespace N2$/;\"\tn\tnamespace:N1\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug665086.cpp.d/input.cpp",
    "content": "/*\nBugs item #665086, was opened at 2003-01-09 15:30\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=665086&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Welti Marco (cider101)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: nested namespaces\n\nInitial Comment:\nhi\n\nit seems that ctags has ommits the scope for nested \nnamespaces.\n*/\nnamespace N1\n{\n  namespace N2\n  {\n    class C12{}\n  }\n}\n/*\nN1\ttest.h\t/^namespace N1$/;\"\tnamespace\tline:1\nN2\ttest.h\t/^namespace N2$/;\"\tnamespace\tline:3\nC12\ttest.h\t/^  class C12{};$/;\"\tclass\tline:5\tnamespace:N1::N2\n*/\n"
  },
  {
    "path": "Units/parser-cxx.r/bug834.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n"
  },
  {
    "path": "Units/parser-cxx.r/bug834.cpp.d/expected.tags",
    "content": "std\tinput.cpp\t/^using namespace std;$/;\"\tU\tfile:\nC\tinput.cpp\t/^vector<vector<int>> C;$/;\"\tv\ttyperef:typename:vector<vector<int>>\nA\tinput.cpp\t/^struct A {$/;\"\ts\tfile:\na\tinput.cpp\t/^    int a;$/;\"\tm\tstruct:A\ttyperef:typename:int\tfile:\nb\tinput.cpp\t/^    int b;$/;\"\tm\tstruct:A\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug834.cpp.d/input.cpp",
    "content": "/*\n  github issue 834 reported by hierabyss on 2016.03.12\n  \n  [...] after run ctags test1.cpp, there is no tag in the tags file.\n\n*/\n\n#include <vector>\n\nusing namespace std;\n\nvector<vector<int>> C;\n\nstruct A {\n    int a;\n    int b;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/bug849591.cpp.d/expected.tags",
    "content": "Foo\tinput.cpp\t/^void MainClass< ParamClass1&, ParamClass2>::Foo()$/;\"\tf\tclass:MainClass\ttyperef:typename:void\nFoo\tinput.cpp\t/^void MainClass<ParamClass1&, ParamClass2>::Foo()$/;\"\tf\tclass:MainClass\ttyperef:typename:void\n"
  },
  {
    "path": "Units/parser-cxx.r/bug849591.cpp.d/input.cpp",
    "content": "/*\nBugs item #849591, was opened at 2003-11-26 11:35\nMessage generated for change (Tracker Item Submitted) made by Item Submitter\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=849591&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Igor Proskuriakov (proskig)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: C++ Member templates \n\nInitial Comment:\nHi,\nThere seems to be a problem with how ctags treats C++ \nmember templates. Example:\n*/\nvoid MainClass< ParamClass1&, ParamClass2>::Foo()\n{\n  exit(0);\n};\n/*\nGenerates erroneous tag\nParamClass1\ttest.cpp\t/^void MainClass< ParamClass1&, ParamClass2>::Foo()$/;\"\tv\n\nFull ctags file:\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tDarren Hiebert\t/dhiebert@users.sourceforge.net/\n!_TAG_PROGRAM_NAME\tExuberant Ctags\t//\n!_TAG_PROGRAM_URL\thttp://ctags.sourceforge.net\t/official site/\n!_TAG_PROGRAM_VERSION\t5.5.2\t//\nFoo\ttest.cpp\t/^void MainClass< const ParamClass1&, ParamClass2>::Foo()$/;\"\tf\tclass:ParamClass2\nParamClass1\ttest.cpp\t/^void MainClass< ParamClass1&, ParamClass2>::Foo()$/;\"\tv\n\n-----\n\nRemoving space after first angle bracket:\n*/\nvoid MainClass<ParamClass1&, ParamClass2>::Foo()\n{\n  exit(0);\n};\n/*\nmakes ctags to drop first letter from parameter class \nname:\n\naramClass1\ttest.cpp\t/^void MainClass<ParamClass1&, ParamClass2>::Foo()$/;\"\tv\n\n\nLet me know if you need any clarification with this issue.\nMany thanks in advance!\n*/\n"
  },
  {
    "path": "Units/parser-cxx.r/bug852368.cpp.d/args.ctags",
    "content": "--kinds-C++=+p\n--fields=+S\n"
  },
  {
    "path": "Units/parser-cxx.r/bug852368.cpp.d/expected.tags",
    "content": "foo\tinput.cpp\t/^void foo(std::vector<float> &);$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(std::vector<float> &)\n"
  },
  {
    "path": "Units/parser-cxx.r/bug852368.cpp.d/input.cpp",
    "content": "/*\nBugs item #852368, was opened at 2003-12-01 23:20\nMessage generated for change (Tracker Item Submitted) made by Item Submitter\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=852368&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Welti Marco (cider101)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: c/c++ unabalanced template brackets in signature\n\nInitial Comment:\nhi,\n\nctags 5.5x generates unbalanced template brackets in \nthe  method/function signature if a function parameter \nis a template.\n\ni.e.\n*/\nvoid foo(std::vector<float> &);\n/*\ngenerates the following signature\nsignature:void (std::vector<<float>&)\n\nlet me know if you need more details.\n\nregards\ncider\n*/\n"
  },
  {
    "path": "Units/parser-cxx.r/bug872494.cpp.d/expected.tags",
    "content": "FooClass2\tinput.cpp\t/^class FooClass2{};$/;\"\tc\tfile:\nTemplClass\tinput.cpp\t/^template<> class TemplClass< char* > { int i;};$/;\"\tc\tfile:\nTemplClass\tinput.cpp\t/^template<class T> class TemplClass { double i;};$/;\"\tc\tfile:\ni\tinput.cpp\t/^template<> class TemplClass< char* > { int i;};$/;\"\tm\tclass:TemplClass\ttyperef:typename:int\tfile:\ni\tinput.cpp\t/^template<class T> class TemplClass { double i;};$/;\"\tm\tclass:TemplClass\ttyperef:typename:double\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/bug872494.cpp.d/input.cpp",
    "content": "/*\nBugs item #872494, was opened at 2004-01-07 16:33\nMessage generated for change (Tracker Item Submitted) made by Item Submitter\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=872494&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Igor Proskuriakov (proskig)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: C++ class template specialization\n\nInitial Comment:\nHi, \nsome time ago I posted a bug related to C++ member \ntemplate, which was fixed using patch bug849591.diff. \nMany thanks - it really fixed the problem ! \nNow about a different one.\nWhen parsing C++ file ctags seems to ignore template \nspecialization, but I think that it maybe useful to add it \nas a configurable feature. Another problem is that \ntemplate specialization seems to confuse patched \nversion of ctags (patch bug849591.diff). When running a \npatched version against the following file\n*/\ntemplate<class T> class TemplClass { double i;};\n\ntemplate<> class TemplClass< char* > { int i;};\n\nclass FooClass2{};\n/*\nit does not generate tag for FooClass2 while ctags 5.5.2 \ndoes generate tag for FooClass2. Neither of them \ngenerate tag for specialization TemplClass<char *>.\n\nthanks in advance and let me know should you need \nmore info!\n\nIgor\n*/\n"
  },
  {
    "path": "Units/parser-cxx.r/c-header-as-cpp.d/args.ctags",
    "content": "--kinds-c++=+px\n"
  },
  {
    "path": "Units/parser-cxx.r/c-header-as-cpp.d/expected.tags",
    "content": "private\tinput.h\t/^extern int private;$/;\"\tx\ttyperef:typename:int\nprotected\tinput.h\t/^typedef int protected;$/;\"\tt\ttyperef:typename:int\npublic\tinput.h\t/^static inline int public(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/c-header-as-cpp.d/input.h",
    "content": "/*\nReported by masatake in issue #930@github.\n\n.h files are always parsed in C++ mode, for safety.\nHowever they may actually contain C code, which may\nuse C++ keywords as variable names.\n\nThis test checks the C++ parser capabilities to guess such occurences.\n\n\n*/\n\nextern int private;\nstatic inline int public(void)\n{\n\treturn private;\n}\n\ntypedef int protected;\n\n"
  },
  {
    "path": "Units/parser-cxx.r/class-inheritance.cpp.d/args.ctags",
    "content": "--kinds-c++=c\n--fields=i\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/class-inheritance.cpp.d/expected.tags",
    "content": "A\tinput.cpp\t/^class A$/\nB\tinput.cpp\t/^class B$/\nC\tinput.cpp\t/^template<typename X,typename Y> class C$/\nD\tinput.cpp\t/^class D : public A$/;\"\tinherits:A\nE\tinput.cpp\t/^class E : public A, public B$/;\"\tinherits:A,B\nF\tinput.cpp\t/^class F : private A, public B$/;\"\tinherits:A,B\nG\tinput.cpp\t/^class G : virtual D$/;\"\tinherits:D\nH\tinput.cpp\t/^class H : public A, virtual B$/;\"\tinherits:A,B\nI\tinput.cpp\t/^class I : public C<A,B>$/;\"\tinherits:C<A,B>\nJ\tinput.cpp\t/^class J : private A, public C<A,B>$/;\"\tinherits:A,C<A,B>\n"
  },
  {
    "path": "Units/parser-cxx.r/class-inheritance.cpp.d/input.cpp",
    "content": "\n\nclass A\n{\n};\n\nclass B\n{\n};\n\ntemplate<typename X,typename Y> class C\n{\n};\n\nclass D : public A\n{\n};\n\nclass E : public A, public B\n{\n};\n\nclass F : private A, public B\n{\n};\n\nclass G : virtual D\n{\n};\n\nclass H : public A, virtual B\n{\n};\n\nclass I : public C<A,B>\n{\n};\n\nclass J : private A, public C<A,B>\n{\n};\n\n"
  },
  {
    "path": "Units/parser-cxx.r/class.cpp.d/args.ctags",
    "content": "--kinds-c++=*\n--sort=no\n--fields=+{end}\n"
  },
  {
    "path": "Units/parser-cxx.r/class.cpp.d/expected.tags",
    "content": "C01\tinput.cpp\t/^MACRO03 __attribute__(\"fancy\") __declspec(dllexport) class MY_API C01$/;\"\tc\tfile:\tend:15\n"
  },
  {
    "path": "Units/parser-cxx.r/class.cpp.d/input.cpp",
    "content": "\n// These should be ignored.\nMACRO01 MACRO02() class N01;\nMACRO03 class __attribute__(\"cool\") N02;\n\nnamespace X;\n\n// This should be reported.\nMACRO03 __attribute__(\"fancy\") __declspec(dllexport) class MY_API C01\n{\n\t// These should be ignored.\n\tfriend class N03;\n\tMACRO04 friend class N04;\n\tfriend class X::N05;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/complex-macros.d/README",
    "content": "input-0.cpp is a crash test.\n"
  },
  {
    "path": "Units/parser-cxx.r/complex-macros.d/args.ctags",
    "content": "--kinds-c++=*\n--fields-c++=+{properties}\n--fields=+S\n--sort=no\n-D DECLARE_FUNCTION_1=int p0()\n-D DECLARE_FUNCTION_1A()=int p0A()\n-D DECLARE_FUNCTION_2(_ret,_name)=_ret _name();\n-D DECLARE_FUNCTION_3(_ret,_name,...)=_ret _name(__VA_ARGS__);\n-D DEPRECATED(...)=__VA_ARGS__ __attribute__((deprecated))\n-D ENUM_GNUX(n,e...)=enum n { e }\n-D DECLARE_TWO_VERSIONS_OF_FUNCTIONS(_prefix1,_prefix2)=DECLARE_FUNCTION_2(int,_prefix1 ## a) DECLARE_FUNCTION_2(int,_prefix2 ## a)\n-D STRINGIFY(token)=#token\n-D IMPLEMENT_FUNCTIONS(_prefix)=void _prefix ## a(){ }; void _prefix ## b(){ };\n-D DECLARE_VARS(_prefix)=int _prefix ## a; int _prefix ## b;\n-D DECLARE_FUNCTION_4(Ret,Class,Method,...)=Ret Class##__##Method(Class *that, ##__VA_ARGS__)\n-D DECLARE_FUNCTION_4_BEGIN(...)={\n-D DECLARE_FUNCTION_4_END(...)=}\n-D var(X)=X\n"
  },
  {
    "path": "Units/parser-cxx.r/complex-macros.d/expected.tags",
    "content": "DECLARE_FUNCTION_1\tinput.cpp\t/^#define DECLARE_FUNCTION_1 /;\"\td\tfile:\np0\tinput.cpp\t/^DECLARE_FUNCTION_1;$/;\"\tp\ttyperef:typename:int\tfile:\tsignature:()\nDECLARE_FUNCTION_1A\tinput.cpp\t/^#define DECLARE_FUNCTION_1A(/;\"\td\tfile:\tsignature:()\np0A\tinput.cpp\t/^unsigned DECLARE_FUNCTION_1A();\t\\/\\/ expand$/;\"\tp\ttyperef:typename:unsigned int\tfile:\tsignature:()\n_ret\tinput.cpp\t/^#define DECLARE_FUNCTION_2(_ret,_name) _ret _name();$/;\"\tD\tmacro:DECLARE_FUNCTION_2\n_name\tinput.cpp\t/^#define DECLARE_FUNCTION_2(_ret,_name) _ret _name();$/;\"\tD\tmacro:DECLARE_FUNCTION_2\nDECLARE_FUNCTION_2\tinput.cpp\t/^#define DECLARE_FUNCTION_2(/;\"\td\tfile:\tsignature:(_ret,_name)\np1\tinput.cpp\t/^DECLARE_FUNCTION_2(int,p1);$/;\"\tp\ttyperef:typename:int\tfile:\tsignature:()\np2\tinput.cpp\t/^DECLARE_FUNCTION_2(std::string,p2);$/;\"\tp\ttyperef:typename:std::string\tfile:\tsignature:()\n_ret\tinput.cpp\t/^#define DECLARE_FUNCTION_3(_ret,_name,...) _ret _name(__VA_ARGS__);$/;\"\tD\tmacro:DECLARE_FUNCTION_3\n_name\tinput.cpp\t/^#define DECLARE_FUNCTION_3(_ret,_name,...) _ret _name(__VA_ARGS__);$/;\"\tD\tmacro:DECLARE_FUNCTION_3\nDECLARE_FUNCTION_3\tinput.cpp\t/^#define DECLARE_FUNCTION_3(/;\"\td\tfile:\tsignature:(_ret,_name,...)\np3\tinput.cpp\t/^DECLARE_FUNCTION_3(int,p3,int a,int b);$/;\"\tp\ttyperef:typename:int\tfile:\tsignature:(int a,int b)\na\tinput.cpp\t/^DECLARE_FUNCTION_3(int,p3,int a,int b);$/;\"\tz\tprototype:p3\ttyperef:typename:int\tfile:\nb\tinput.cpp\t/^DECLARE_FUNCTION_3(int,p3,int a,int b);$/;\"\tz\tprototype:p3\ttyperef:typename:int\tfile:\nDEPRECATED\tinput.cpp\t/^#define DEPRECATED(/;\"\td\tfile:\tsignature:(...)\np4\tinput.cpp\t/^DEPRECATED(int p4());$/;\"\tp\ttyperef:typename:int\tfile:\tsignature:()\tproperties:deprecated\nn\tinput.cpp\t/^#define ENUM_GNUX(n,e...) enum n { e }$/;\"\tD\tmacro:ENUM_GNUX\ne\tinput.cpp\t/^#define ENUM_GNUX(n,e...) enum n { e }$/;\"\tD\tmacro:ENUM_GNUX\nENUM_GNUX\tinput.cpp\t/^#define ENUM_GNUX(/;\"\td\tfile:\tsignature:(n,e...)\ncolor\tinput.cpp\t/^ENUM_GNUX(color, red, blue, green);$/;\"\tg\tfile:\nred\tinput.cpp\t/^ENUM_GNUX(color, red, blue, green);$/;\"\te\tenum:color\tfile:\nblue\tinput.cpp\t/^ENUM_GNUX(color, red, blue, green);$/;\"\te\tenum:color\tfile:\ngreen\tinput.cpp\t/^ENUM_GNUX(color, red, blue, green);$/;\"\te\tenum:color\tfile:\n_prefix1\tinput.cpp\t/^#define DECLARE_TWO_VERSIONS_OF_FUNCTIONS(_prefix1,_prefix2) \\\\$/;\"\tD\tmacro:DECLARE_TWO_VERSIONS_OF_FUNCTIONS\n_prefix2\tinput.cpp\t/^#define DECLARE_TWO_VERSIONS_OF_FUNCTIONS(_prefix1,_prefix2) \\\\$/;\"\tD\tmacro:DECLARE_TWO_VERSIONS_OF_FUNCTIONS\nDECLARE_TWO_VERSIONS_OF_FUNCTIONS\tinput.cpp\t/^#define DECLARE_TWO_VERSIONS_OF_FUNCTIONS(/;\"\td\tfile:\tsignature:(_prefix1,_prefix2)\np5a\tinput.cpp\t/^DECLARE_TWO_VERSIONS_OF_FUNCTIONS(p5,p6)$/;\"\tp\ttyperef:typename:int\tfile:\tsignature:()\np6a\tinput.cpp\t/^DECLARE_TWO_VERSIONS_OF_FUNCTIONS(p5,p6)$/;\"\tp\ttyperef:typename:int\tfile:\tsignature:()\ntoken\tinput.cpp\t/^#define STRINGIFY(token) #token$/;\"\tD\tmacro:STRINGIFY\nSTRINGIFY\tinput.cpp\t/^#define STRINGIFY(/;\"\td\tfile:\tsignature:(token)\ntest\tinput.cpp\t/^const char * test = \"\" STRINGIFY(; int notVisible;);$/;\"\tv\ttyperef:typename:const char *\nRet\tinput.cpp\t/^#define DECLARE_FUNCTION_4(Ret,Class,Method,...) Ret Class##__##Method(Class *that, ##__VA_ARGS_/;\"\tD\tmacro:DECLARE_FUNCTION_4\nClass\tinput.cpp\t/^#define DECLARE_FUNCTION_4(Ret,Class,Method,...) Ret Class##__##Method(Class *that, ##__VA_ARGS_/;\"\tD\tmacro:DECLARE_FUNCTION_4\nMethod\tinput.cpp\t/^#define DECLARE_FUNCTION_4(Ret,Class,Method,...) Ret Class##__##Method(Class *that, ##__VA_ARGS_/;\"\tD\tmacro:DECLARE_FUNCTION_4\nDECLARE_FUNCTION_4\tinput.cpp\t/^#define DECLARE_FUNCTION_4(/;\"\td\tfile:\tsignature:(Ret,Class,Method,...)\nDECLARE_FUNCTION_4_BEGIN\tinput.cpp\t/^#define DECLARE_FUNCTION_4_BEGIN(/;\"\td\tfile:\tsignature:(...)\nDECLARE_FUNCTION_4_END\tinput.cpp\t/^#define DECLARE_FUNCTION_4_END(/;\"\td\tfile:\tsignature:(...)\nfoo__bar\tinput.cpp\t/^DECLARE_FUNCTION_4(int,foo,bar,int x)$/;\"\tf\ttyperef:typename:int\tsignature:(foo * that,int x)\nthat\tinput.cpp\t/^DECLARE_FUNCTION_4(int,foo,bar,int x)$/;\"\tz\tfunction:foo__bar\ttyperef:typename:foo *\tfile:\nx\tinput.cpp\t/^DECLARE_FUNCTION_4(int,foo,bar,int x)$/;\"\tz\tfunction:foo__bar\ttyperef:typename:int\tfile:\n_prefix\tinput.cpp\t/^#define IMPLEMENT_FUNCTIONS(_prefix) \\\\$/;\"\tD\tmacro:IMPLEMENT_FUNCTIONS\nIMPLEMENT_FUNCTIONS\tinput.cpp\t/^#define IMPLEMENT_FUNCTIONS(/;\"\td\tfile:\tsignature:(_prefix)\nf1a\tinput.cpp\t/^IMPLEMENT_FUNCTIONS(f1);$/;\"\tf\ttyperef:typename:void\tsignature:()\nf1b\tinput.cpp\t/^IMPLEMENT_FUNCTIONS(f1);$/;\"\tf\ttyperef:typename:void\tsignature:()\n_prefix\tinput.cpp\t/^#define DECLARE_VARS(_prefix) int _prefix ## a; int _prefix ## b;$/;\"\tD\tmacro:DECLARE_VARS\nDECLARE_VARS\tinput.cpp\t/^#define DECLARE_VARS(/;\"\td\tfile:\tsignature:(_prefix)\nmain\tinput.cpp\t/^int main(int,char **)$/;\"\tf\ttyperef:typename:int\tsignature:(int,char **)\n__anonb64b5bec010d\tinput.cpp\t/^int main(int,char **)$/;\"\tz\tfunction:main\ttyperef:typename:int\tfile:\n__anonb64b5bec020d\tinput.cpp\t/^int main(int,char **)$/;\"\tz\tfunction:main\ttyperef:typename:char **\tfile:\nla\tinput.cpp\t/^\tDECLARE_VARS(l);$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nlb\tinput.cpp\t/^\tDECLARE_VARS(l);$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\ninput0\tinput-0.cpp\t/^int input0;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/complex-macros.d/input-0.cpp",
    "content": "int input0;\nint var(input1\n\n"
  },
  {
    "path": "Units/parser-cxx.r/complex-macros.d/input.cpp",
    "content": "#include <string>\n\n// Macro without parameters\n#define DECLARE_FUNCTION_1 int p0()\n\nDECLARE_FUNCTION_1;\n\n// Macro without parameters\n#define DECLARE_FUNCTION_1A() int p0A()\n\nDECLARE_FUNCTION_1A; // don't expand\nunsigned DECLARE_FUNCTION_1A();\t// expand\n\n// Simple macro with parameters\n\n#define DECLARE_FUNCTION_2(_ret,_name) _ret _name();\n\nDECLARE_FUNCTION_2(int,p1);\nDECLARE_FUNCTION_2(std::string,p2);\n\n// Var args\n\n#define DECLARE_FUNCTION_3(_ret,_name,...) _ret _name(__VA_ARGS__);\n\nDECLARE_FUNCTION_3(int,p3,int a,int b);\n\n#define DEPRECATED(...) __VA_ARGS__ __attribute__((deprecated))\n\nDEPRECATED(int p4());\n\n#define ENUM_GNUX(n,e...) enum n { e }\n\nENUM_GNUX(color, red, blue, green);\n\n// Recursive macro expansion\n\n#define DECLARE_TWO_VERSIONS_OF_FUNCTIONS(_prefix1,_prefix2) \\\n\tDECLARE_FUNCTION_2(int,_prefix1 ## a) \\\n\tDECLARE_FUNCTION_2(int,_prefix2 ## a)\n\nDECLARE_TWO_VERSIONS_OF_FUNCTIONS(p5,p6)\n\n// Stringification\n#define STRINGIFY(token) #token\n\nconst char * test = \"\" STRINGIFY(; int notVisible;);\n\n// Unbalanced brackets (this comes from a nasty example in a github issue)\n#define DECLARE_FUNCTION_4(Ret,Class,Method,...) Ret Class##__##Method(Class *that, ##__VA_ARGS__)\n#define DECLARE_FUNCTION_4_BEGIN(...) { /*not really this, but this is what ctags should see*/\n#define DECLARE_FUNCTION_4_END(...) } /*not really this, but this is what ctags should see*/\n\n// Unbalanced brackets\nDECLARE_FUNCTION_4(int,foo,bar,int x)\nDECLARE_FUNCTION_4_BEGIN({)\nDECLARE_FUNCTION_4_END(},{ /*dtors*/ })\n\n// Token pasting\n\n#define IMPLEMENT_FUNCTIONS(_prefix) \\\n\tvoid _prefix ## a(){ }; \\\n\tvoid _prefix ## b(){ };\n\nIMPLEMENT_FUNCTIONS(f1);\n\n#define DECLARE_VARS(_prefix) int _prefix ## a; int _prefix ## b;\n\nint main(int,char **)\n{\n\tDECLARE_VARS(l);\n\treturn 0;\n}"
  },
  {
    "path": "Units/parser-cxx.r/cpp-type-alias-with-using-keyword.d/expected.tags",
    "content": "Integer\tinput.cpp\t/^using Integer = int;$/;\"\tt\ttyperef:typename:int\tfile:\nVector\tinput.cpp\t/^using Vector = std::vector<T>;$/;\"\tt\ttyperef:typename:std::vector<T>\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/cpp-type-alias-with-using-keyword.d/input.cpp",
    "content": "/* C++11 introduced the \"using name = type;\" construct as an alternative\n  to typedefs. Process them as typedefs. Contributed by Maxime Coste */\n\nusing Integer = int;\n\ntemplate <typename T>\nusing Vector = std::vector<T>;\n"
  },
  {
    "path": "Units/parser-cxx.r/cpp_destructor.cpp.d/expected.tags",
    "content": "~A\tinput.cpp\t/^A::~A() { }$/;\"\tf\tclass:A\n~B\tinput.cpp\t/^B:: ~B () { }$/;\"\tf\tclass:B\n~C\tinput.cpp\t/^C:: ~ C () { }$/;\"\tf\tclass:C\n~D\tinput.cpp\t/^D:: ~D() { }$/;\"\tf\tclass:D\n~E\tinput.cpp\t/^E:: ~ E() { }$/;\"\tf\tclass:E\n~F\tinput.cpp\t/^F::~F(){ }$/;\"\tf\tclass:F\n~G\tinput.cpp\t/^G:: ~G (){ }$/;\"\tf\tclass:G\n~H\tinput.cpp\t/^H:: ~ H (){ }$/;\"\tf\tclass:H\n~I\tinput.cpp\t/^I:: ~I(){ }$/;\"\tf\tclass:I\n~J\tinput.cpp\t/^J:: ~ J(){ }$/;\"\tf\tclass:J\n"
  },
  {
    "path": "Units/parser-cxx.r/cpp_destructor.cpp.d/input.cpp",
    "content": "A::~A() { }\n\nB:: ~B () { }\n\n// bug 1585745\nC:: ~ C () { }\n\nD:: ~D() { }\nE:: ~ E() { }\n\n\nF::~F(){ }\nG:: ~G (){ }\nH:: ~ H (){ }\nI:: ~I(){ }\nJ:: ~ J(){ }\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-keyword-alignas.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-keyword-alignas.d/expected.tags",
    "content": "buf0\tinput.cxx\t/^alignas(64) int buf0[8192];$/;\"\tv\ttyperef:typename:int[8192]\nbuf1\tinput.cxx\t/^alignas(void *) int buf1[8192];$/;\"\tv\ttyperef:typename:int[8192]\nS\tinput.cxx\t/^struct alignas(32) S {$/;\"\ts\tfile:\ni\tinput.cxx\t/^  alignas(4) int i;$/;\"\tm\tstruct:S\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-keyword-alignas.d/input.cxx",
    "content": "alignas(64) int buf0[8192];\nalignas(void *) int buf1[8192];\nstruct alignas(32) S {\n  alignas(4) int i;\n};\n\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-keywords-as-c-identifiers.b/README",
    "content": "gen-input.sh generates a header file in which C++ keywords are used as C identifiers.\ngen-expected-tags.sh generates an incomplete expected.tags.\n\nCopyed from #930:\n\n    I found this case in linux kernel.\n\n    Consider a C language header having .h suffix.\n    In C language private is not a keyword.\n    New Cxx parser doesn't record a variable named private because\n    the parser recognized it as C++ keyword.``\n    Old Cxx parser\n\n    [yamato@x201]/tmp% cat foo.h\n    extern int private;\n    static inline int f(void)\n    {\n      return private;\n    }\n    typedef int int32;\n\n\n    [yamato@x201]/tmp% u-ctags -o - /tmp/foo.h \n    # nothing is captured.\n\n    [yamato@x201]/tmp% u-ctags --languages=+OldC++ --language-force=OldC++ -o - /tmp/foo.h\n    f   /tmp/foo.h  /^static inline int f(void)$/;\" f\n    int32   /tmp/foo.h  /^typedef int int32;$/;\"    t\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-keywords-as-c-identifiers.b/args.ctags",
    "content": "--sort=no\n--kinds-C++=+px\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-keywords-as-c-identifiers.b/expected.tags",
    "content": "NotKeyword\tinput.h\t/^struct NotKeyword {int x;} v0;$/;\"\ts\nx\tinput.h\t/^struct NotKeyword {int x;} v0;$/;\"\tm\tstruct:NotKeyword\ttyperef:typename:int\nv0\tinput.h\t/^struct NotKeyword {int x;} v0;$/;\"\tv\ttyperef:struct:NotKeyword\nalignas\tinput.h\t/^struct alignas {int x;} v1;$/;\"\ts\nx\tinput.h\t/^struct alignas {int x;} v1;$/;\"\tm\tstruct:alignas\ttyperef:typename:int\nv1\tinput.h\t/^struct alignas {int x;} v1;$/;\"\tv\ttyperef:struct:alignas\nalignof\tinput.h\t/^struct alignof {int x;} v2;$/;\"\ts\nx\tinput.h\t/^struct alignof {int x;} v2;$/;\"\tm\tstruct:alignof\ttyperef:typename:int\nv2\tinput.h\t/^struct alignof {int x;} v2;$/;\"\tv\ttyperef:struct:alignof\n__anon9f26d24b0108\tinput.h\t/^struct bool {int x;} v3;$/;\"\ts\nx\tinput.h\t/^struct bool {int x;} v3;$/;\"\tm\tstruct:__anon9f26d24b0108\ttyperef:typename:int\nv3\tinput.h\t/^struct bool {int x;} v3;$/;\"\tv\ttyperef:struct:__anon9f26d24b0108\ncatch\tinput.h\t/^struct catch {int x;} v4;$/;\"\ts\nx\tinput.h\t/^struct catch {int x;} v4;$/;\"\tm\tstruct:catch\ttyperef:typename:int\nv4\tinput.h\t/^struct catch {int x;} v4;$/;\"\tv\ttyperef:struct:catch\nchar16_t\tinput.h\t/^struct char16_t {int x;} v5;$/;\"\ts\nx\tinput.h\t/^struct char16_t {int x;} v5;$/;\"\tm\tstruct:char16_t\ttyperef:typename:int\nv5\tinput.h\t/^struct char16_t {int x;} v5;$/;\"\tv\ttyperef:struct:char16_t\nchar32_t\tinput.h\t/^struct char32_t {int x;} v6;$/;\"\ts\nx\tinput.h\t/^struct char32_t {int x;} v6;$/;\"\tm\tstruct:char32_t\ttyperef:typename:int\nv6\tinput.h\t/^struct char32_t {int x;} v6;$/;\"\tv\ttyperef:struct:char32_t\nclass\tinput.h\t/^struct class {int x;} v7;$/;\"\ts\nx\tinput.h\t/^struct class {int x;} v7;$/;\"\tm\tstruct:class\ttyperef:typename:int\nv7\tinput.h\t/^struct class {int x;} v7;$/;\"\tv\ttyperef:struct:class\nconcept\tinput.h\t/^struct concept {int x;} v8;$/;\"\ts\nx\tinput.h\t/^struct concept {int x;} v8;$/;\"\tm\tstruct:concept\ttyperef:typename:int\nv8\tinput.h\t/^struct concept {int x;} v8;$/;\"\tv\ttyperef:struct:concept\nconstexpr\tinput.h\t/^struct constexpr {int x;} v9;$/;\"\ts\nx\tinput.h\t/^struct constexpr {int x;} v9;$/;\"\tm\tstruct:constexpr\ttyperef:typename:int\nv9\tinput.h\t/^struct constexpr {int x;} v9;$/;\"\tv\ttyperef:struct:constexpr\nconst_cast\tinput.h\t/^struct const_cast {int x;} v10;$/;\"\ts\nx\tinput.h\t/^struct const_cast {int x;} v10;$/;\"\tm\tstruct:const_cast\ttyperef:typename:int\nv10\tinput.h\t/^struct const_cast {int x;} v10;$/;\"\tv\ttyperef:struct:const_cast\ndecltype\tinput.h\t/^struct decltype {int x;} v11;$/;\"\ts\nx\tinput.h\t/^struct decltype {int x;} v11;$/;\"\tm\tstruct:decltype\ttyperef:typename:int\nv11\tinput.h\t/^struct decltype {int x;} v11;$/;\"\tv\ttyperef:struct:decltype\ndelete\tinput.h\t/^struct delete {int x;} v12;$/;\"\ts\nx\tinput.h\t/^struct delete {int x;} v12;$/;\"\tm\tstruct:delete\ttyperef:typename:int\nv12\tinput.h\t/^struct delete {int x;} v12;$/;\"\tv\ttyperef:struct:delete\ndynamic_cast\tinput.h\t/^struct dynamic_cast {int x;} v13;$/;\"\ts\nx\tinput.h\t/^struct dynamic_cast {int x;} v13;$/;\"\tm\tstruct:dynamic_cast\ttyperef:typename:int\nv13\tinput.h\t/^struct dynamic_cast {int x;} v13;$/;\"\tv\ttyperef:struct:dynamic_cast\nexplicit\tinput.h\t/^struct explicit {int x;} v14;$/;\"\ts\nx\tinput.h\t/^struct explicit {int x;} v14;$/;\"\tm\tstruct:explicit\ttyperef:typename:int\nv14\tinput.h\t/^struct explicit {int x;} v14;$/;\"\tv\ttyperef:struct:explicit\nexport\tinput.h\t/^struct export {int x;} v15;$/;\"\ts\nx\tinput.h\t/^struct export {int x;} v15;$/;\"\tm\tstruct:export\ttyperef:typename:int\nv15\tinput.h\t/^struct export {int x;} v15;$/;\"\tv\ttyperef:struct:export\nfinal\tinput.h\t/^struct final {int x;} v16;$/;\"\ts\nx\tinput.h\t/^struct final {int x;} v16;$/;\"\tm\tstruct:final\ttyperef:typename:int\nv16\tinput.h\t/^struct final {int x;} v16;$/;\"\tv\ttyperef:struct:final\nfriend\tinput.h\t/^struct friend {int x;} v17;$/;\"\ts\nx\tinput.h\t/^struct friend {int x;} v17;$/;\"\tm\tstruct:friend\ttyperef:typename:int\nv17\tinput.h\t/^struct friend {int x;} v17;$/;\"\tv\ttyperef:struct:friend\nmutable\tinput.h\t/^struct mutable {int x;} v18;$/;\"\ts\nx\tinput.h\t/^struct mutable {int x;} v18;$/;\"\tm\tstruct:mutable\ttyperef:typename:int\nv18\tinput.h\t/^struct mutable {int x;} v18;$/;\"\tv\ttyperef:struct:mutable\nnamespace\tinput.h\t/^struct namespace {int x;} v19;$/;\"\ts\nx\tinput.h\t/^struct namespace {int x;} v19;$/;\"\tm\tstruct:namespace\ttyperef:typename:int\nv19\tinput.h\t/^struct namespace {int x;} v19;$/;\"\tv\ttyperef:struct:namespace\nnew\tinput.h\t/^struct new {int x;} v20;$/;\"\ts\nx\tinput.h\t/^struct new {int x;} v20;$/;\"\tm\tstruct:new\ttyperef:typename:int\nv20\tinput.h\t/^struct new {int x;} v20;$/;\"\tv\ttyperef:struct:new\nnoexcept\tinput.h\t/^struct noexcept {int x;} v21;$/;\"\ts\nx\tinput.h\t/^struct noexcept {int x;} v21;$/;\"\tm\tstruct:noexcept\ttyperef:typename:int\nv21\tinput.h\t/^struct noexcept {int x;} v21;$/;\"\tv\ttyperef:struct:noexcept\nnullptr\tinput.h\t/^struct nullptr {int x;} v22;$/;\"\ts\nx\tinput.h\t/^struct nullptr {int x;} v22;$/;\"\tm\tstruct:nullptr\ttyperef:typename:int\nv22\tinput.h\t/^struct nullptr {int x;} v22;$/;\"\tv\ttyperef:struct:nullptr\noperator\tinput.h\t/^struct operator {int x;} v23;$/;\"\ts\nx\tinput.h\t/^struct operator {int x;} v23;$/;\"\tm\tstruct:operator\ttyperef:typename:int\nv23\tinput.h\t/^struct operator {int x;} v23;$/;\"\tv\ttyperef:struct:operator\nprivate\tinput.h\t/^struct private {int x;} v24;$/;\"\ts\nx\tinput.h\t/^struct private {int x;} v24;$/;\"\tm\tstruct:private\ttyperef:typename:int\nv24\tinput.h\t/^struct private {int x;} v24;$/;\"\tv\ttyperef:struct:private\nprotected\tinput.h\t/^struct protected {int x;} v25;$/;\"\ts\nx\tinput.h\t/^struct protected {int x;} v25;$/;\"\tm\tstruct:protected\ttyperef:typename:int\nv25\tinput.h\t/^struct protected {int x;} v25;$/;\"\tv\ttyperef:struct:protected\npublic\tinput.h\t/^struct public {int x;} v26;$/;\"\ts\nx\tinput.h\t/^struct public {int x;} v26;$/;\"\tm\tstruct:public\ttyperef:typename:int\nv26\tinput.h\t/^struct public {int x;} v26;$/;\"\tv\ttyperef:struct:public\nreinterpret_cast\tinput.h\t/^struct reinterpret_cast {int x;} v27;$/;\"\ts\nx\tinput.h\t/^struct reinterpret_cast {int x;} v27;$/;\"\tm\tstruct:reinterpret_cast\ttyperef:typename:int\nv27\tinput.h\t/^struct reinterpret_cast {int x;} v27;$/;\"\tv\ttyperef:struct:reinterpret_cast\nrequires\tinput.h\t/^struct requires {int x;} v28;$/;\"\ts\nx\tinput.h\t/^struct requires {int x;} v28;$/;\"\tm\tstruct:requires\ttyperef:typename:int\nv28\tinput.h\t/^struct requires {int x;} v28;$/;\"\tv\ttyperef:struct:requires\nstatic_assert\tinput.h\t/^struct static_assert {int x;} v29;$/;\"\ts\nx\tinput.h\t/^struct static_assert {int x;} v29;$/;\"\tm\tstruct:static_assert\ttyperef:typename:int\nv29\tinput.h\t/^struct static_assert {int x;} v29;$/;\"\tv\ttyperef:struct:static_assert\nstatic_cast\tinput.h\t/^struct static_cast {int x;} v30;$/;\"\ts\nx\tinput.h\t/^struct static_cast {int x;} v30;$/;\"\tm\tstruct:static_cast\ttyperef:typename:int\nv30\tinput.h\t/^struct static_cast {int x;} v30;$/;\"\tv\ttyperef:struct:static_cast\ntemplate\tinput.h\t/^struct template {int x;} v31;$/;\"\ts\nx\tinput.h\t/^struct template {int x;} v31;$/;\"\tm\tstruct:template\ttyperef:typename:int\nv31\tinput.h\t/^struct template {int x;} v31;$/;\"\tv\ttyperef:struct:template\nthis\tinput.h\t/^struct this {int x;} v32;$/;\"\ts\nx\tinput.h\t/^struct this {int x;} v32;$/;\"\tm\tstruct:this\ttyperef:typename:int\nv32\tinput.h\t/^struct this {int x;} v32;$/;\"\tv\ttyperef:struct:this\nthread_local\tinput.h\t/^struct thread_local {int x;} v33;$/;\"\ts\nx\tinput.h\t/^struct thread_local {int x;} v33;$/;\"\tm\tstruct:thread_local\ttyperef:typename:int\nv33\tinput.h\t/^struct thread_local {int x;} v33;$/;\"\tv\ttyperef:struct:thread_local\nthrow\tinput.h\t/^struct throw {int x;} v34;$/;\"\ts\nx\tinput.h\t/^struct throw {int x;} v34;$/;\"\tm\tstruct:throw\ttyperef:typename:int\nv34\tinput.h\t/^struct throw {int x;} v34;$/;\"\tv\ttyperef:struct:throw\ntry\tinput.h\t/^struct try {int x;} v35;$/;\"\ts\nx\tinput.h\t/^struct try {int x;} v35;$/;\"\tm\tstruct:try\ttyperef:typename:int\nv35\tinput.h\t/^struct try {int x;} v35;$/;\"\tv\ttyperef:struct:try\ntypeid\tinput.h\t/^struct typeid {int x;} v36;$/;\"\ts\nx\tinput.h\t/^struct typeid {int x;} v36;$/;\"\tm\tstruct:typeid\ttyperef:typename:int\nv36\tinput.h\t/^struct typeid {int x;} v36;$/;\"\tv\ttyperef:struct:typeid\ntypename\tinput.h\t/^struct typename {int x;} v37;$/;\"\ts\nx\tinput.h\t/^struct typename {int x;} v37;$/;\"\tm\tstruct:typename\ttyperef:typename:int\nv37\tinput.h\t/^struct typename {int x;} v37;$/;\"\tv\ttyperef:struct:typename\nusing\tinput.h\t/^struct using {int x;} v38;$/;\"\ts\nx\tinput.h\t/^struct using {int x;} v38;$/;\"\tm\tstruct:using\ttyperef:typename:int\nv38\tinput.h\t/^struct using {int x;} v38;$/;\"\tv\ttyperef:struct:using\nvirtual\tinput.h\t/^struct virtual {int x;} v39;$/;\"\ts\nx\tinput.h\t/^struct virtual {int x;} v39;$/;\"\tm\tstruct:virtual\ttyperef:typename:int\nv39\tinput.h\t/^struct virtual {int x;} v39;$/;\"\tv\ttyperef:struct:virtual\ns0\tinput.h\t/^struct s0 {int NotKeyword;} ;$/;\"\ts\nNotKeyword\tinput.h\t/^struct s0 {int NotKeyword;} ;$/;\"\tm\tstruct:s0\ttyperef:typename:int\ns1\tinput.h\t/^struct s1 {int alignas;} ;$/;\"\ts\nalignas\tinput.h\t/^struct s1 {int alignas;} ;$/;\"\tm\tstruct:s1\ttyperef:typename:int\ns2\tinput.h\t/^struct s2 {int alignof;} ;$/;\"\ts\nalignof\tinput.h\t/^struct s2 {int alignof;} ;$/;\"\tm\tstruct:s2\ttyperef:typename:int\ns3\tinput.h\t/^struct s3 {int bool;} ;$/;\"\ts\ns4\tinput.h\t/^struct s4 {int catch;} ;$/;\"\ts\ncatch\tinput.h\t/^struct s4 {int catch;} ;$/;\"\tm\tstruct:s4\ttyperef:typename:int\ns5\tinput.h\t/^struct s5 {int char16_t;} ;$/;\"\ts\nchar16_t\tinput.h\t/^struct s5 {int char16_t;} ;$/;\"\tm\tstruct:s5\ttyperef:typename:int\ns6\tinput.h\t/^struct s6 {int char32_t;} ;$/;\"\ts\nchar32_t\tinput.h\t/^struct s6 {int char32_t;} ;$/;\"\tm\tstruct:s6\ttyperef:typename:int\ns7\tinput.h\t/^struct s7 {int class;} ;$/;\"\ts\nclass\tinput.h\t/^struct s7 {int class;} ;$/;\"\tm\tstruct:s7\ttyperef:typename:int\ns8\tinput.h\t/^struct s8 {int concept;} ;$/;\"\ts\nconcept\tinput.h\t/^struct s8 {int concept;} ;$/;\"\tm\tstruct:s8\ttyperef:typename:int\ns9\tinput.h\t/^struct s9 {int constexpr;} ;$/;\"\ts\nconstexpr\tinput.h\t/^struct s9 {int constexpr;} ;$/;\"\tm\tstruct:s9\ttyperef:typename:int\ns10\tinput.h\t/^struct s10 {int const_cast;} ;$/;\"\ts\nconst_cast\tinput.h\t/^struct s10 {int const_cast;} ;$/;\"\tm\tstruct:s10\ttyperef:typename:int\ns11\tinput.h\t/^struct s11 {int decltype;} ;$/;\"\ts\ndecltype\tinput.h\t/^struct s11 {int decltype;} ;$/;\"\tm\tstruct:s11\ttyperef:typename:int\ns12\tinput.h\t/^struct s12 {int delete;} ;$/;\"\ts\ndelete\tinput.h\t/^struct s12 {int delete;} ;$/;\"\tm\tstruct:s12\ttyperef:typename:int\ns13\tinput.h\t/^struct s13 {int dynamic_cast;} ;$/;\"\ts\ndynamic_cast\tinput.h\t/^struct s13 {int dynamic_cast;} ;$/;\"\tm\tstruct:s13\ttyperef:typename:int\ns14\tinput.h\t/^struct s14 {int explicit;} ;$/;\"\ts\nexplicit\tinput.h\t/^struct s14 {int explicit;} ;$/;\"\tm\tstruct:s14\ttyperef:typename:int\ns15\tinput.h\t/^struct s15 {int export;} ;$/;\"\ts\nexport\tinput.h\t/^struct s15 {int export;} ;$/;\"\tm\tstruct:s15\ttyperef:typename:int\ns16\tinput.h\t/^struct s16 {int final;} ;$/;\"\ts\nfinal\tinput.h\t/^struct s16 {int final;} ;$/;\"\tm\tstruct:s16\ttyperef:typename:int\ns17\tinput.h\t/^struct s17 {int friend;} ;$/;\"\ts\nfriend\tinput.h\t/^struct s17 {int friend;} ;$/;\"\tm\tstruct:s17\ttyperef:typename:int\ns18\tinput.h\t/^struct s18 {int mutable;} ;$/;\"\ts\nmutable\tinput.h\t/^struct s18 {int mutable;} ;$/;\"\tm\tstruct:s18\ttyperef:typename:int\ns19\tinput.h\t/^struct s19 {int namespace;} ;$/;\"\ts\nnamespace\tinput.h\t/^struct s19 {int namespace;} ;$/;\"\tm\tstruct:s19\ttyperef:typename:int\ns20\tinput.h\t/^struct s20 {int new;} ;$/;\"\ts\nnew\tinput.h\t/^struct s20 {int new;} ;$/;\"\tm\tstruct:s20\ttyperef:typename:int\ns21\tinput.h\t/^struct s21 {int noexcept;} ;$/;\"\ts\nnoexcept\tinput.h\t/^struct s21 {int noexcept;} ;$/;\"\tm\tstruct:s21\ttyperef:typename:int\ns22\tinput.h\t/^struct s22 {int nullptr;} ;$/;\"\ts\nnullptr\tinput.h\t/^struct s22 {int nullptr;} ;$/;\"\tm\tstruct:s22\ttyperef:typename:int\ns23\tinput.h\t/^struct s23 {int operator;} ;$/;\"\ts\noperator\tinput.h\t/^struct s23 {int operator;} ;$/;\"\tm\tstruct:s23\ttyperef:typename:int\ns24\tinput.h\t/^struct s24 {int private;} ;$/;\"\ts\nprivate\tinput.h\t/^struct s24 {int private;} ;$/;\"\tm\tstruct:s24\ttyperef:typename:int\ns25\tinput.h\t/^struct s25 {int protected;} ;$/;\"\ts\nprotected\tinput.h\t/^struct s25 {int protected;} ;$/;\"\tm\tstruct:s25\ttyperef:typename:int\ns26\tinput.h\t/^struct s26 {int public;} ;$/;\"\ts\npublic\tinput.h\t/^struct s26 {int public;} ;$/;\"\tm\tstruct:s26\ttyperef:typename:int\ns27\tinput.h\t/^struct s27 {int reinterpret_cast;} ;$/;\"\ts\nreinterpret_cast\tinput.h\t/^struct s27 {int reinterpret_cast;} ;$/;\"\tm\tstruct:s27\ttyperef:typename:int\ns28\tinput.h\t/^struct s28 {int requires;} ;$/;\"\ts\nrequires\tinput.h\t/^struct s28 {int requires;} ;$/;\"\tm\tstruct:s28\ttyperef:typename:int\ns29\tinput.h\t/^struct s29 {int static_assert;} ;$/;\"\ts\nstatic_assert\tinput.h\t/^struct s29 {int static_assert;} ;$/;\"\tm\tstruct:s29\ttyperef:typename:int\ns30\tinput.h\t/^struct s30 {int static_cast;} ;$/;\"\ts\nstatic_cast\tinput.h\t/^struct s30 {int static_cast;} ;$/;\"\tm\tstruct:s30\ttyperef:typename:int\ns31\tinput.h\t/^struct s31 {int template;} ;$/;\"\ts\ntemplate\tinput.h\t/^struct s31 {int template;} ;$/;\"\tm\tstruct:s31\ttyperef:typename:int\ns32\tinput.h\t/^struct s32 {int this;} ;$/;\"\ts\nthis\tinput.h\t/^struct s32 {int this;} ;$/;\"\tm\tstruct:s32\ttyperef:typename:int\ns33\tinput.h\t/^struct s33 {int thread_local;} ;$/;\"\ts\nthread_local\tinput.h\t/^struct s33 {int thread_local;} ;$/;\"\tm\tstruct:s33\ttyperef:typename:int\ns34\tinput.h\t/^struct s34 {int throw;} ;$/;\"\ts\nthrow\tinput.h\t/^struct s34 {int throw;} ;$/;\"\tm\tstruct:s34\ttyperef:typename:int\ns35\tinput.h\t/^struct s35 {int try;} ;$/;\"\ts\ntry\tinput.h\t/^struct s35 {int try;} ;$/;\"\tm\tstruct:s35\ttyperef:typename:int\ns36\tinput.h\t/^struct s36 {int typeid;} ;$/;\"\ts\ntypeid\tinput.h\t/^struct s36 {int typeid;} ;$/;\"\tm\tstruct:s36\ttyperef:typename:int\ns37\tinput.h\t/^struct s37 {int typename;} ;$/;\"\ts\ntypename\tinput.h\t/^struct s37 {int typename;} ;$/;\"\tm\tstruct:s37\ttyperef:typename:int\ns38\tinput.h\t/^struct s38 {int using;} ;$/;\"\ts\nusing\tinput.h\t/^struct s38 {int using;} ;$/;\"\tm\tstruct:s38\ttyperef:typename:int\ns39\tinput.h\t/^struct s39 {int virtual;} ;$/;\"\ts\nvirtual\tinput.h\t/^struct s39 {int virtual;} ;$/;\"\tm\tstruct:s39\ttyperef:typename:int\nNotKeyword\tinput.h\t/^typedef int NotKeyword; \\/* 0 *\\/$/;\"\tt\ttyperef:typename:int\nalignas\tinput.h\t/^typedef int alignas; \\/* 1 *\\/$/;\"\tt\ttyperef:typename:int\nalignof\tinput.h\t/^typedef int alignof; \\/* 2 *\\/$/;\"\tt\ttyperef:typename:int\ncatch\tinput.h\t/^typedef int catch; \\/* 4 *\\/$/;\"\tt\ttyperef:typename:int\nchar16_t\tinput.h\t/^typedef int char16_t; \\/* 5 *\\/$/;\"\tt\ttyperef:typename:int\nchar32_t\tinput.h\t/^typedef int char32_t; \\/* 6 *\\/$/;\"\tt\ttyperef:typename:int\nclass\tinput.h\t/^typedef int class; \\/* 7 *\\/$/;\"\tt\ttyperef:typename:int\nconcept\tinput.h\t/^typedef int concept; \\/* 8 *\\/$/;\"\tt\ttyperef:typename:int\nconstexpr\tinput.h\t/^typedef int constexpr; \\/* 9 *\\/$/;\"\tt\ttyperef:typename:int\nconst_cast\tinput.h\t/^typedef int const_cast; \\/* 10 *\\/$/;\"\tt\ttyperef:typename:int\ndecltype\tinput.h\t/^typedef int decltype; \\/* 11 *\\/$/;\"\tt\ttyperef:typename:int\ndelete\tinput.h\t/^typedef int delete; \\/* 12 *\\/$/;\"\tt\ttyperef:typename:int\ndynamic_cast\tinput.h\t/^typedef int dynamic_cast; \\/* 13 *\\/$/;\"\tt\ttyperef:typename:int\nexplicit\tinput.h\t/^typedef int explicit; \\/* 14 *\\/$/;\"\tt\ttyperef:typename:int\nexport\tinput.h\t/^typedef int export; \\/* 15 *\\/$/;\"\tt\ttyperef:typename:int\nfinal\tinput.h\t/^typedef int final; \\/* 16 *\\/$/;\"\tt\ttyperef:typename:int\nfriend\tinput.h\t/^typedef int friend; \\/* 17 *\\/$/;\"\tt\ttyperef:typename:int\nmutable\tinput.h\t/^typedef int mutable; \\/* 18 *\\/$/;\"\tt\ttyperef:typename:int\nnamespace\tinput.h\t/^typedef int namespace; \\/* 19 *\\/$/;\"\tt\ttyperef:typename:int\nnew\tinput.h\t/^typedef int new; \\/* 20 *\\/$/;\"\tt\ttyperef:typename:int\nnoexcept\tinput.h\t/^typedef int noexcept; \\/* 21 *\\/$/;\"\tt\ttyperef:typename:int\nnullptr\tinput.h\t/^typedef int nullptr; \\/* 22 *\\/$/;\"\tt\ttyperef:typename:int\noperator\tinput.h\t/^typedef int operator; \\/* 23 *\\/$/;\"\tt\ttyperef:typename:int\nprivate\tinput.h\t/^typedef int private; \\/* 24 *\\/$/;\"\tt\ttyperef:typename:int\nprotected\tinput.h\t/^typedef int protected; \\/* 25 *\\/$/;\"\tt\ttyperef:typename:int\npublic\tinput.h\t/^typedef int public; \\/* 26 *\\/$/;\"\tt\ttyperef:typename:int\nreinterpret_cast\tinput.h\t/^typedef int reinterpret_cast; \\/* 27 *\\/$/;\"\tt\ttyperef:typename:int\nrequires\tinput.h\t/^typedef int requires; \\/* 28 *\\/$/;\"\tt\ttyperef:typename:int\nstatic_assert\tinput.h\t/^typedef int static_assert; \\/* 29 *\\/$/;\"\tt\ttyperef:typename:int\nstatic_cast\tinput.h\t/^typedef int static_cast; \\/* 30 *\\/$/;\"\tt\ttyperef:typename:int\ntemplate\tinput.h\t/^typedef int template; \\/* 31 *\\/$/;\"\tt\ttyperef:typename:int\nthis\tinput.h\t/^typedef int this; \\/* 32 *\\/$/;\"\tt\ttyperef:typename:int\nthread_local\tinput.h\t/^typedef int thread_local; \\/* 33 *\\/$/;\"\tt\ttyperef:typename:int\nthrow\tinput.h\t/^typedef int throw; \\/* 34 *\\/$/;\"\tt\ttyperef:typename:int\ntry\tinput.h\t/^typedef int try; \\/* 35 *\\/$/;\"\tt\ttyperef:typename:int\ntypeid\tinput.h\t/^typedef int typeid; \\/* 36 *\\/$/;\"\tt\ttyperef:typename:int\ntypename\tinput.h\t/^typedef int typename; \\/* 37 *\\/$/;\"\tt\ttyperef:typename:int\nusing\tinput.h\t/^typedef int using; \\/* 38 *\\/$/;\"\tt\ttyperef:typename:int\nvirtual\tinput.h\t/^typedef int virtual; \\/* 39 *\\/$/;\"\tt\ttyperef:typename:int\nv0\tinput.h\t/^int v0, NotKeyword;$/;\"\tv\ttyperef:typename:int\nNotKeyword\tinput.h\t/^int v0, NotKeyword;$/;\"\tv\ttyperef:typename:int\nv1\tinput.h\t/^int v1, alignas;$/;\"\tv\ttyperef:typename:int\nalignas\tinput.h\t/^int v1, alignas;$/;\"\tv\ttyperef:typename:int\nv2\tinput.h\t/^int v2, alignof;$/;\"\tv\ttyperef:typename:int\nalignof\tinput.h\t/^int v2, alignof;$/;\"\tv\ttyperef:typename:int\nv3\tinput.h\t/^int v3, bool;$/;\"\tv\ttyperef:typename:int\nv4\tinput.h\t/^int v4, catch;$/;\"\tv\ttyperef:typename:int\ncatch\tinput.h\t/^int v4, catch;$/;\"\tv\ttyperef:typename:int\nv5\tinput.h\t/^int v5, char16_t;$/;\"\tv\ttyperef:typename:int\nchar16_t\tinput.h\t/^int v5, char16_t;$/;\"\tv\ttyperef:typename:int\nv6\tinput.h\t/^int v6, char32_t;$/;\"\tv\ttyperef:typename:int\nchar32_t\tinput.h\t/^int v6, char32_t;$/;\"\tv\ttyperef:typename:int\nv7\tinput.h\t/^int v7, class;$/;\"\tv\ttyperef:typename:int\nclass\tinput.h\t/^int v7, class;$/;\"\tv\ttyperef:typename:int\nv8\tinput.h\t/^int v8, concept;$/;\"\tv\ttyperef:typename:int\nconcept\tinput.h\t/^int v8, concept;$/;\"\tv\ttyperef:typename:int\nv9\tinput.h\t/^int v9, constexpr;$/;\"\tv\ttyperef:typename:int\nconstexpr\tinput.h\t/^int v9, constexpr;$/;\"\tv\ttyperef:typename:int\nv10\tinput.h\t/^int v10, const_cast;$/;\"\tv\ttyperef:typename:int\nconst_cast\tinput.h\t/^int v10, const_cast;$/;\"\tv\ttyperef:typename:int\nv11\tinput.h\t/^int v11, decltype;$/;\"\tv\ttyperef:typename:int\ndecltype\tinput.h\t/^int v11, decltype;$/;\"\tv\ttyperef:typename:int\nv12\tinput.h\t/^int v12, delete;$/;\"\tv\ttyperef:typename:int\ndelete\tinput.h\t/^int v12, delete;$/;\"\tv\ttyperef:typename:int\nv13\tinput.h\t/^int v13, dynamic_cast;$/;\"\tv\ttyperef:typename:int\ndynamic_cast\tinput.h\t/^int v13, dynamic_cast;$/;\"\tv\ttyperef:typename:int\nv14\tinput.h\t/^int v14, explicit;$/;\"\tv\ttyperef:typename:int\nexplicit\tinput.h\t/^int v14, explicit;$/;\"\tv\ttyperef:typename:int\nv15\tinput.h\t/^int v15, export;$/;\"\tv\ttyperef:typename:int\nexport\tinput.h\t/^int v15, export;$/;\"\tv\ttyperef:typename:int\nv16\tinput.h\t/^int v16, final;$/;\"\tv\ttyperef:typename:int\nfinal\tinput.h\t/^int v16, final;$/;\"\tv\ttyperef:typename:int\nv17\tinput.h\t/^int v17, friend;$/;\"\tv\ttyperef:typename:int\nfriend\tinput.h\t/^int v17, friend;$/;\"\tv\ttyperef:typename:int\nv18\tinput.h\t/^int v18, mutable;$/;\"\tv\ttyperef:typename:int\nmutable\tinput.h\t/^int v18, mutable;$/;\"\tv\ttyperef:typename:int\nv19\tinput.h\t/^int v19, namespace;$/;\"\tv\ttyperef:typename:int\nnamespace\tinput.h\t/^int v19, namespace;$/;\"\tv\ttyperef:typename:int\nv20\tinput.h\t/^int v20, new;$/;\"\tv\ttyperef:typename:int\nnew\tinput.h\t/^int v20, new;$/;\"\tv\ttyperef:typename:int\nv21\tinput.h\t/^int v21, noexcept;$/;\"\tv\ttyperef:typename:int\nnoexcept\tinput.h\t/^int v21, noexcept;$/;\"\tv\ttyperef:typename:int\nv22\tinput.h\t/^int v22, nullptr;$/;\"\tv\ttyperef:typename:int\nnullptr\tinput.h\t/^int v22, nullptr;$/;\"\tv\ttyperef:typename:int\nv23\tinput.h\t/^int v23, operator;$/;\"\tv\ttyperef:typename:int\noperator\tinput.h\t/^int v23, operator;$/;\"\tv\ttyperef:typename:int\nv24\tinput.h\t/^int v24, private;$/;\"\tv\ttyperef:typename:int\nprivate\tinput.h\t/^int v24, private;$/;\"\tv\ttyperef:typename:int\nv25\tinput.h\t/^int v25, protected;$/;\"\tv\ttyperef:typename:int\nprotected\tinput.h\t/^int v25, protected;$/;\"\tv\ttyperef:typename:int\nv26\tinput.h\t/^int v26, public;$/;\"\tv\ttyperef:typename:int\npublic\tinput.h\t/^int v26, public;$/;\"\tv\ttyperef:typename:int\nv27\tinput.h\t/^int v27, reinterpret_cast;$/;\"\tv\ttyperef:typename:int\nreinterpret_cast\tinput.h\t/^int v27, reinterpret_cast;$/;\"\tv\ttyperef:typename:int\nv28\tinput.h\t/^int v28, requires;$/;\"\tv\ttyperef:typename:int\nrequires\tinput.h\t/^int v28, requires;$/;\"\tv\ttyperef:typename:int\nv29\tinput.h\t/^int v29, static_assert;$/;\"\tv\ttyperef:typename:int\nstatic_assert\tinput.h\t/^int v29, static_assert;$/;\"\tv\ttyperef:typename:int\nv30\tinput.h\t/^int v30, static_cast;$/;\"\tv\ttyperef:typename:int\nstatic_cast\tinput.h\t/^int v30, static_cast;$/;\"\tv\ttyperef:typename:int\nv31\tinput.h\t/^int v31, template;$/;\"\tv\ttyperef:typename:int\ntemplate\tinput.h\t/^int v31, template;$/;\"\tv\ttyperef:typename:int\nv32\tinput.h\t/^int v32, this;$/;\"\tv\ttyperef:typename:int\nthis\tinput.h\t/^int v32, this;$/;\"\tv\ttyperef:typename:int\nv33\tinput.h\t/^int v33, thread_local;$/;\"\tv\ttyperef:typename:int\nthread_local\tinput.h\t/^int v33, thread_local;$/;\"\tv\ttyperef:typename:int\nv34\tinput.h\t/^int v34, throw;$/;\"\tv\ttyperef:typename:int\nthrow\tinput.h\t/^int v34, throw;$/;\"\tv\ttyperef:typename:int\nv35\tinput.h\t/^int v35, try;$/;\"\tv\ttyperef:typename:int\ntry\tinput.h\t/^int v35, try;$/;\"\tv\ttyperef:typename:int\nv36\tinput.h\t/^int v36, typeid;$/;\"\tv\ttyperef:typename:int\ntypeid\tinput.h\t/^int v36, typeid;$/;\"\tv\ttyperef:typename:int\nv37\tinput.h\t/^int v37, typename;$/;\"\tv\ttyperef:typename:int\ntypename\tinput.h\t/^int v37, typename;$/;\"\tv\ttyperef:typename:int\nv38\tinput.h\t/^int v38, using;$/;\"\tv\ttyperef:typename:int\nusing\tinput.h\t/^int v38, using;$/;\"\tv\ttyperef:typename:int\nv39\tinput.h\t/^int v39, virtual;$/;\"\tv\ttyperef:typename:int\nvirtual\tinput.h\t/^int v39, virtual;$/;\"\tv\ttyperef:typename:int\nNotKeyword\tinput.h\t/^int NotKeyword (int a0);$/;\"\tp\ttyperef:typename:int\nalignas\tinput.h\t/^int alignas (int a1);$/;\"\tp\ttyperef:typename:int\nalignof\tinput.h\t/^int alignof (int a2);$/;\"\tp\ttyperef:typename:int\ncatch\tinput.h\t/^int catch (int a4);$/;\"\tp\ttyperef:typename:int\nchar16_t\tinput.h\t/^int char16_t (int a5);$/;\"\tp\ttyperef:typename:int\nchar32_t\tinput.h\t/^int char32_t (int a6);$/;\"\tp\ttyperef:typename:int\nclass\tinput.h\t/^int class (int a7);$/;\"\tp\ttyperef:typename:int\nconcept\tinput.h\t/^int concept (int a8);$/;\"\tp\ttyperef:typename:int\nconstexpr\tinput.h\t/^int constexpr (int a9);$/;\"\tp\ttyperef:typename:int\nconst_cast\tinput.h\t/^int const_cast (int a10);$/;\"\tp\ttyperef:typename:int\ndecltype\tinput.h\t/^int decltype (int a11);$/;\"\tp\ttyperef:typename:int\ndelete\tinput.h\t/^int delete (int a12);$/;\"\tp\ttyperef:typename:int\ndynamic_cast\tinput.h\t/^int dynamic_cast (int a13);$/;\"\tp\ttyperef:typename:int\nexplicit\tinput.h\t/^int explicit (int a14);$/;\"\tp\ttyperef:typename:int\nexport\tinput.h\t/^int export (int a15);$/;\"\tp\ttyperef:typename:int\nfinal\tinput.h\t/^int final (int a16);$/;\"\tp\ttyperef:typename:int\nfriend\tinput.h\t/^int friend (int a17);$/;\"\tp\ttyperef:typename:int\nmutable\tinput.h\t/^int mutable (int a18);$/;\"\tp\ttyperef:typename:int\nnamespace\tinput.h\t/^int namespace (int a19);$/;\"\tp\ttyperef:typename:int\nnew\tinput.h\t/^int new (int a20);$/;\"\tp\ttyperef:typename:int\nnoexcept\tinput.h\t/^int noexcept (int a21);$/;\"\tp\ttyperef:typename:int\nnullptr\tinput.h\t/^int nullptr (int a22);$/;\"\tp\ttyperef:typename:int\noperator\tinput.h\t/^int operator (int a23);$/;\"\tp\ttyperef:typename:int\nprivate\tinput.h\t/^int private (int a24);$/;\"\tp\ttyperef:typename:int\nprotected\tinput.h\t/^int protected (int a25);$/;\"\tp\ttyperef:typename:int\npublic\tinput.h\t/^int public (int a26);$/;\"\tp\ttyperef:typename:int\nreinterpret_cast\tinput.h\t/^int reinterpret_cast (int a27);$/;\"\tp\ttyperef:typename:int\nrequires\tinput.h\t/^int requires (int a28);$/;\"\tp\ttyperef:typename:int\nstatic_assert\tinput.h\t/^int static_assert (int a29);$/;\"\tp\ttyperef:typename:int\nstatic_cast\tinput.h\t/^int static_cast (int a30);$/;\"\tp\ttyperef:typename:int\ntemplate\tinput.h\t/^int template (int a31);$/;\"\tp\ttyperef:typename:int\nthis\tinput.h\t/^int this (int a32);$/;\"\tp\ttyperef:typename:int\nthread_local\tinput.h\t/^int thread_local (int a33);$/;\"\tp\ttyperef:typename:int\nthrow\tinput.h\t/^int throw (int a34);$/;\"\tp\ttyperef:typename:int\ntry\tinput.h\t/^int try (int a35);$/;\"\tp\ttyperef:typename:int\ntypeid\tinput.h\t/^int typeid (int a36);$/;\"\tp\ttyperef:typename:int\ntypename\tinput.h\t/^int typename (int a37);$/;\"\tp\ttyperef:typename:int\nusing\tinput.h\t/^int using (int a38);$/;\"\tp\ttyperef:typename:int\nvirtual\tinput.h\t/^int virtual (int a39);$/;\"\tp\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-keywords-as-c-identifiers.b/gen-expected-tags.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\n. ./keywords.sh\n\ngen_struct_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\n$k\tinput.h\t/^struct $k {int x;} v$i;\\$/;\"\ts\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_member_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\n$k\tinput.h\t/^struct s$i {int $k;} ;\\$/;\"\tm\tstruct:s$i\ttyperef:typename:int\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_typedef_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\n$k\tinput.h\t/^typedef int $k; \\/* $i *\\/\\$/;\"\tt\ttyperef:typename:int\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_var_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\n$k\tinput.h\t/^int v$i, $k;\\$/;\"\tv\ttyperef:typename:int\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_func_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\n$k\tinput.h\t/^int $k (int a$i);\\$/;\"\tp\ttyperef:typename:int\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_struct_tags\ngen_member_tags\ngen_typedef_tags\ngen_var_tags\ngen_func_tags\n\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-keywords-as-c-identifiers.b/gen-input.sh",
    "content": "#!/bin/sh\n\n# Copyright: 2016 Masatake YAMATO\n# License: GPL-2\n\n. ./keywords.sh\n\ngen_struct_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\nstruct $k {int x;} v$i;\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_member_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\nstruct s$i {int $k;} ;\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_typedef_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\ntypedef int $k; /* $i */\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_var_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\nint v$i, $k;\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_func_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\nint $k (int a$i);\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_label_tags ()\n{\n    i=0\n    for k in $keywords; do\n\tcat<<EOF\nvoid f$i (void) { goto $k; $k: return; }\nEOF\n\ti=$(( i + 1 ))\n    done\n}\n\ngen_struct_tags\ngen_member_tags\ngen_typedef_tags\ngen_var_tags\ngen_func_tags\n# gen_label_tags\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-keywords-as-c-identifiers.b/input.h",
    "content": "struct NotKeyword {int x;} v0;\nstruct alignas {int x;} v1;\nstruct alignof {int x;} v2;\nstruct bool {int x;} v3;\nstruct catch {int x;} v4;\nstruct char16_t {int x;} v5;\nstruct char32_t {int x;} v6;\nstruct class {int x;} v7;\nstruct concept {int x;} v8;\nstruct constexpr {int x;} v9;\nstruct const_cast {int x;} v10;\nstruct decltype {int x;} v11;\nstruct delete {int x;} v12;\nstruct dynamic_cast {int x;} v13;\nstruct explicit {int x;} v14;\nstruct export {int x;} v15;\nstruct final {int x;} v16;\nstruct friend {int x;} v17;\nstruct mutable {int x;} v18;\nstruct namespace {int x;} v19;\nstruct new {int x;} v20;\nstruct noexcept {int x;} v21;\nstruct nullptr {int x;} v22;\nstruct operator {int x;} v23;\nstruct private {int x;} v24;\nstruct protected {int x;} v25;\nstruct public {int x;} v26;\nstruct reinterpret_cast {int x;} v27;\nstruct requires {int x;} v28;\nstruct static_assert {int x;} v29;\nstruct static_cast {int x;} v30;\nstruct template {int x;} v31;\nstruct this {int x;} v32;\nstruct thread_local {int x;} v33;\nstruct throw {int x;} v34;\nstruct try {int x;} v35;\nstruct typeid {int x;} v36;\nstruct typename {int x;} v37;\nstruct using {int x;} v38;\nstruct virtual {int x;} v39;\nstruct s0 {int NotKeyword;} ;\nstruct s1 {int alignas;} ;\nstruct s2 {int alignof;} ;\nstruct s3 {int bool;} ;\nstruct s4 {int catch;} ;\nstruct s5 {int char16_t;} ;\nstruct s6 {int char32_t;} ;\nstruct s7 {int class;} ;\nstruct s8 {int concept;} ;\nstruct s9 {int constexpr;} ;\nstruct s10 {int const_cast;} ;\nstruct s11 {int decltype;} ;\nstruct s12 {int delete;} ;\nstruct s13 {int dynamic_cast;} ;\nstruct s14 {int explicit;} ;\nstruct s15 {int export;} ;\nstruct s16 {int final;} ;\nstruct s17 {int friend;} ;\nstruct s18 {int mutable;} ;\nstruct s19 {int namespace;} ;\nstruct s20 {int new;} ;\nstruct s21 {int noexcept;} ;\nstruct s22 {int nullptr;} ;\nstruct s23 {int operator;} ;\nstruct s24 {int private;} ;\nstruct s25 {int protected;} ;\nstruct s26 {int public;} ;\nstruct s27 {int reinterpret_cast;} ;\nstruct s28 {int requires;} ;\nstruct s29 {int static_assert;} ;\nstruct s30 {int static_cast;} ;\nstruct s31 {int template;} ;\nstruct s32 {int this;} ;\nstruct s33 {int thread_local;} ;\nstruct s34 {int throw;} ;\nstruct s35 {int try;} ;\nstruct s36 {int typeid;} ;\nstruct s37 {int typename;} ;\nstruct s38 {int using;} ;\nstruct s39 {int virtual;} ;\ntypedef int NotKeyword; /* 0 */\ntypedef int alignas; /* 1 */\ntypedef int alignof; /* 2 */\ntypedef int bool; /* 3 */\ntypedef int catch; /* 4 */\ntypedef int char16_t; /* 5 */\ntypedef int char32_t; /* 6 */\ntypedef int class; /* 7 */\ntypedef int concept; /* 8 */\ntypedef int constexpr; /* 9 */\ntypedef int const_cast; /* 10 */\ntypedef int decltype; /* 11 */\ntypedef int delete; /* 12 */\ntypedef int dynamic_cast; /* 13 */\ntypedef int explicit; /* 14 */\ntypedef int export; /* 15 */\ntypedef int final; /* 16 */\ntypedef int friend; /* 17 */\ntypedef int mutable; /* 18 */\ntypedef int namespace; /* 19 */\ntypedef int new; /* 20 */\ntypedef int noexcept; /* 21 */\ntypedef int nullptr; /* 22 */\ntypedef int operator; /* 23 */\ntypedef int private; /* 24 */\ntypedef int protected; /* 25 */\ntypedef int public; /* 26 */\ntypedef int reinterpret_cast; /* 27 */\ntypedef int requires; /* 28 */\ntypedef int static_assert; /* 29 */\ntypedef int static_cast; /* 30 */\ntypedef int template; /* 31 */\ntypedef int this; /* 32 */\ntypedef int thread_local; /* 33 */\ntypedef int throw; /* 34 */\ntypedef int try; /* 35 */\ntypedef int typeid; /* 36 */\ntypedef int typename; /* 37 */\ntypedef int using; /* 38 */\ntypedef int virtual; /* 39 */\nint v0, NotKeyword;\nint v1, alignas;\nint v2, alignof;\nint v3, bool;\nint v4, catch;\nint v5, char16_t;\nint v6, char32_t;\nint v7, class;\nint v8, concept;\nint v9, constexpr;\nint v10, const_cast;\nint v11, decltype;\nint v12, delete;\nint v13, dynamic_cast;\nint v14, explicit;\nint v15, export;\nint v16, final;\nint v17, friend;\nint v18, mutable;\nint v19, namespace;\nint v20, new;\nint v21, noexcept;\nint v22, nullptr;\nint v23, operator;\nint v24, private;\nint v25, protected;\nint v26, public;\nint v27, reinterpret_cast;\nint v28, requires;\nint v29, static_assert;\nint v30, static_cast;\nint v31, template;\nint v32, this;\nint v33, thread_local;\nint v34, throw;\nint v35, try;\nint v36, typeid;\nint v37, typename;\nint v38, using;\nint v39, virtual;\nint NotKeyword (int a0);\nint alignas (int a1);\nint alignof (int a2);\nint bool (int a3);\nint catch (int a4);\nint char16_t (int a5);\nint char32_t (int a6);\nint class (int a7);\nint concept (int a8);\nint constexpr (int a9);\nint const_cast (int a10);\nint decltype (int a11);\nint delete (int a12);\nint dynamic_cast (int a13);\nint explicit (int a14);\nint export (int a15);\nint final (int a16);\nint friend (int a17);\nint mutable (int a18);\nint namespace (int a19);\nint new (int a20);\nint noexcept (int a21);\nint nullptr (int a22);\nint operator (int a23);\nint private (int a24);\nint protected (int a25);\nint public (int a26);\nint reinterpret_cast (int a27);\nint requires (int a28);\nint static_assert (int a29);\nint static_cast (int a30);\nint template (int a31);\nint this (int a32);\nint thread_local (int a33);\nint throw (int a34);\nint try (int a35);\nint typeid (int a36);\nint typename (int a37);\nint using (int a38);\nint virtual (int a39);\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-keywords-as-c-identifiers.b/keywords.sh",
    "content": "keywords=\"\nNotKeyword\nalignas\nalignof\nbool\ncatch\nchar16_t\nchar32_t\nclass\nconcept\nconstexpr\nconst_cast\ndecltype\ndelete\ndynamic_cast\nexplicit\nexport\nfinal\nfriend\nmutable\nnamespace\nnew\nnoexcept\nnullptr\noperator\nprivate\nprotected\npublic\nreinterpret_cast\nrequires\nstatic_assert\nstatic_cast\ntemplate\nthis\nthread_local\nthrow\ntry\ntypeid\ntypename\nusing\nvirtual\n\"\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-shift-operators-in-template-parameters.d/README",
    "content": "Taken from issue #807 reported by @focalintent.\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-shift-operators-in-template-parameters.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-shift-operators-in-template-parameters.d/expected.tags",
    "content": "c\tinput.cpp\t/^template <int P> class c {};$/;\"\tc\tfile:\nbVar\tinput.cpp\t/^c< 8 > bVar;$/;\"\tv\ttyperef:typename:c<8>\naVar\tinput.cpp\t/^c< 1<<8 > aVar;$/;\"\tv\ttyperef:typename:c<1<<8>\nf12\tinput.cpp\t/^template<int X> f12( c< 1<<X> & aVar) { };$/;\"\tf\tsignature:(c<1<<X> & aVar)\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx-shift-operators-in-template-parameters.d/input.cpp",
    "content": "template <int P> class c {};\nc< 8 > bVar;\nc< 1<<8 > aVar;\ntemplate<int X> f12( c< 1<<X> & aVar) { };\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-attributes.cpp.d/args.ctags",
    "content": "--kinds-c++=*\n--fields-C++=+{properties}\n--fields=+tS\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-attributes.cpp.d/expected.tags",
    "content": "f\tinput.cpp\t/^inline int f(); \\/\\/ declare f with four attributes$/;\"\tp\ttyperef:typename:int\tfile:\tsignature:()\tproperties:inline\ng\tinput.cpp\t/^int g(); \\/\\/ same as above, but uses a single attr specifier that contains four attributes$/;\"\tp\ttyperef:typename:int\tfile:\tsignature:()\tproperties:inline\nh\tinput.cpp\t/^int h[[gnu::always_inline]](); \\/\\/ an attribute may appear in multiple specifiers$/;\"\tp\ttyperef:typename:int\tfile:\tsignature:()\tproperties:inline\ni\tinput.cpp\t/^int i() { return 0; }$/;\"\tf\ttyperef:typename:int\tsignature:()\nj\tinput.cpp\t/^[ [ deprecated ] ] int j(int k) {$/;\"\tf\ttyperef:typename:int\tsignature:(int k)\tproperties:deprecated\nk\tinput.cpp\t/^[ [ deprecated ] ] int j(int k) {$/;\"\tz\tfunction:j\ttyperef:typename:int\tfile:\nv1\tinput.cpp\t/^\tint v1;$/;\"\tl\tfunction:j\ttyperef:typename:int\tfile:\nfoo\tinput.cpp\t/^void foo();$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:()\nmain\tinput.cpp\t/^int main([[maybe_unused]]int argc, [[maybe_unused]]char *argv[]) {$/;\"\tf\ttyperef:typename:int\tsignature:(int argc,char * argv[])\nargc\tinput.cpp\t/^int main([[maybe_unused]]int argc, [[maybe_unused]]char *argv[]) {$/;\"\tz\tfunction:main\ttyperef:typename:int\tfile:\nargv\tinput.cpp\t/^int main([[maybe_unused]]int argc, [[maybe_unused]]char *argv[]) {$/;\"\tz\tfunction:main\ttyperef:typename:char * []\tfile:\nalpha\tinput.cpp\t/^  int alpha;$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nbravo\tinput.cpp\t/^  int bravo;$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\ncharlie\tinput.cpp\t/^  int charlie;$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-attributes.cpp.d/input.cpp",
    "content": "// Taken from https://en.cppreference.com/w/cpp/language/attributes\n[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]]\ninline int f(); // declare f with four attributes\n\n[[gnu::always_inline, gnu::const, gnu::hot, nodiscard]]\nint g(); // same as above, but uses a single attr specifier that contains four attributes\n\n// C++17:\n[[using gnu : const, always_inline, hot]] [[nodiscard]]\nint h[[gnu::always_inline]](); // an attribute may appear in multiple specifiers\n\nint i() { return 0; }\n\n[ [ deprecated ] ] int j(int k) {\n\tswitch(k)\n\t{\n\t\tcase 1:\n\t\t\t[[fallthrough]];\n\t\tcase 2:\n\t\t\t[[likely]]\n\t\t\treturn 3;\n\t}\n\t\n\tint v1;\n\t\n\treturn -1;\n}\n\n/* Taken from issue #2364 opened by andrejlevkovitch. */\n\nvoid foo();\n\nint main([[maybe_unused]]int argc, [[maybe_unused]]char *argv[]) {\n  int alpha;\n  int bravo;\n  int charlie;\n\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-broken-nested-attributes.cpp.d/expected.tags",
    "content": "i\tinput.cxx\t/^int i;$/;\"\tv\ttyperef:typename:int\nj\tinput-0.cxx\t/^[[)int j;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-broken-nested-attributes.cpp.d/input-0.cxx",
    "content": "[[)int j;\n// This is a broken input; extracting j is not a must.\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-broken-nested-attributes.cpp.d/input.cxx",
    "content": "[[[]]]\n// This is a crash test.\nint i;\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-constexpr-variable.d/expected.tags",
    "content": "a_int\tinput.cpp\t/^constexpr int a_int = 1;$/;\"\tv\ttyperef:typename:int\nb_int\tinput.cpp\t/^constexpr const int b_int = 2;$/;\"\tv\ttyperef:typename:const int\nc_int\tinput.cpp\t/^static constexpr const int c_int = 3;$/;\"\tv\ttyperef:typename:const int\tfile:\nd_int\tinput.cpp\t/^static constexpr int d_int = 4;$/;\"\tv\ttyperef:typename:int\tfile:\ne_int\tinput.cpp\t/^constexpr static const int e_int = 5;$/;\"\tv\ttyperef:typename:const int\tfile:\nf_int\tinput.cpp\t/^constexpr static int f_int = 6;$/;\"\tv\ttyperef:typename:int\tfile:\ng_auto\tinput.cpp\t/^constexpr auto g_auto = 7;$/;\"\tv\ttyperef:typename:auto\nh_char_ptr\tinput.cpp\t/^constexpr static const char* const h_char_ptr = \"this is valid\";$/;\"\tv\ttyperef:typename:const char * const\tfile:\ni_char_array\tinput.cpp\t/^static constexpr const char i_char_array[] = \"this is also valid\";$/;\"\tv\ttyperef:typename:const char[]\tfile:\nj_ref\tinput.cpp\t/^static constexpr int const& j_ref = 42;$/;\"\tv\ttyperef:typename:int const &\tfile:\nk_int_ptr\tinput.cpp\t/^constexpr const int *k_int_ptr = &a_int;$/;\"\tv\ttyperef:typename:const int *\nl_raw\tinput.cpp\t/^static constexpr const char* const l_raw = R\"(setfacl {} -m g:{}:{} {})\";$/;\"\tv\ttyperef:typename:const char * const\tfile:\nm_int64\tinput.cpp\t/^static constexpr const int64_t m_int64 = 120'000;$/;\"\tv\ttyperef:typename:const int64_t\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-constexpr-variable.d/input.cpp",
    "content": "constexpr int a_int = 1;\nconstexpr const int b_int = 2;\nstatic constexpr const int c_int = 3;\nstatic constexpr int d_int = 4;\nconstexpr static const int e_int = 5;\nconstexpr static int f_int = 6;\n\nconstexpr auto g_auto = 7;\n\nconstexpr static const char* const h_char_ptr = \"this is valid\";\n\nstatic constexpr const char i_char_array[] = \"this is also valid\";\n\nstatic constexpr int const& j_ref = 42;\n\nconstexpr const int *k_int_ptr = &a_int;\n\nstatic constexpr const char* const l_raw = R\"(setfacl {} -m g:{}:{} {})\";\n\nstatic constexpr const int64_t m_int64 = 120'000;\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-delete.d/args.ctags",
    "content": "--kinds-c++=+p\n--fields=+S\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-delete.d/expected.tags",
    "content": "Del\tinput.cpp\t/^    Del(const Del &) = delete;$/;\"\tp\tclass:Del\tfile:\tsignature:(const Del &)\nDel\tinput.cpp\t/^class Del$/;\"\tc\tfile:\noperator =\tinput.cpp\t/^    void operator=(const Del& rDel) = delete;$/;\"\tp\tclass:Del\ttyperef:typename:void\tfile:\tsignature:(const Del & rDel)\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-delete.d/input.cpp",
    "content": "class Del\n{\nprivate:\n    Del(const Del &) = delete;\n    void operator=(const Del& rDel) = delete;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-final.d/args.ctags",
    "content": "--kinds-c++=+p\n--fields=+S\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-final.d/expected.tags",
    "content": "Base\tinput.cpp\t/^class Base$/;\"\tc\tfile:\nDerived\tinput.cpp\t/^class Derived final : public Base$/;\"\tc\tfile:\nfinal\tinput.cpp\t/^\tvirtual void final();$/;\"\tp\tclass:Derived\ttyperef:typename:void\tfile:\tsignature:()\nfinal\tinput.cpp\t/^void Derived::final()$/;\"\tf\tclass:Derived\ttyperef:typename:void\tsignature:()\nfoo\tinput.cpp\t/^\tvirtual void foo() = 0;$/;\"\tp\tclass:Base\ttyperef:typename:void\tfile:\tsignature:()\nfoo\tinput.cpp\t/^\tvirtual void foo() final;$/;\"\tp\tclass:Derived\ttyperef:typename:void\tfile:\tsignature:()\nfoo\tinput.cpp\t/^void Base::foo()$/;\"\tf\tclass:Base\ttyperef:typename:void\tsignature:()\nfoo\tinput.cpp\t/^void Derived::foo()$/;\"\tf\tclass:Derived\ttyperef:typename:void\tsignature:()\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-final.d/input.cpp",
    "content": "class Base\n{\npublic:\n\tvirtual void foo() = 0;\n};\n\nclass Derived final : public Base\n{\n\tvirtual void foo() final;\n\tvirtual void final();\n};\n\nvoid Base::foo()\n{\n}\n\nvoid Derived::foo()\n{\n}\n\nvoid Derived::final()\n{\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-lambdas.d/args.ctags",
    "content": "--kinds-c++=+pflz\n--fields=+SsKe\n--fields-c++=+{captures}\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-lambdas.d/expected.tags",
    "content": "call\tinput.cpp\t/^template<typename T> int call(T x)$/;\"\tfunction\ttyperef:typename:int\tsignature:(T x)\tend:6\nx\tinput.cpp\t/^template<typename T> int call(T x)$/;\"\tparameter\tfunction:call\ttyperef:typename:T\tfile:\nX\tinput.cpp\t/^template<typename A,typename B> class X$/;\"\tclass\tfile:\tend:10\ntest\tinput.cpp\t/^int test()$/;\"\tfunction\ttyperef:typename:int\tsignature:()\tend:30\n__anon4e7b1b580102\tinput.cpp\t/^\tauto l1 = [] { return 0; };$/;\"\tfunction\tfunction:test\tfile:\tend:14\tcaptures:[] \nl1\tinput.cpp\t/^\tauto l1 = [] { return 0; };$/;\"\tlocal\tfunction:test\ttyperef:typename:auto\tfile:\tend:14\n__anon4e7b1b580202\tinput.cpp\t/^\tauto l2 = [](int a,int b) { return a > b ? a : b; };$/;\"\tfunction\tfunction:test\tfile:\tsignature:(int a,int b) \tend:16\tcaptures:[]\na\tinput.cpp\t/^\tauto l2 = [](int a,int b) { return a > b ? a : b; };$/;\"\tparameter\tfunction:test::__anon4e7b1b580202\ttyperef:typename:int\tfile:\nb\tinput.cpp\t/^\tauto l2 = [](int a,int b) { return a > b ? a : b; };$/;\"\tparameter\tfunction:test::__anon4e7b1b580202\ttyperef:typename:int\tfile:\nl2\tinput.cpp\t/^\tauto l2 = [](int a,int b) { return a > b ? a : b; };$/;\"\tlocal\tfunction:test\ttyperef:typename:auto\tfile:\tend:16\n__anon4e7b1b580302\tinput.cpp\t/^\tauto l3 = [=](int a,int b) -> int {$/;\"\tfunction\tfunction:test\ttyperef:typename:int\tfile:\tsignature:(int a,int b) \tend:21\tcaptures:[=]\na\tinput.cpp\t/^\tauto l3 = [=](int a,int b) -> int {$/;\"\tparameter\tfunction:test::__anon4e7b1b580302\ttyperef:typename:int\tfile:\nb\tinput.cpp\t/^\tauto l3 = [=](int a,int b) -> int {$/;\"\tparameter\tfunction:test::__anon4e7b1b580302\ttyperef:typename:int\tfile:\n__anon4e7b1b580402\tinput.cpp\t/^\t\tauto l4 = [a,b](int c){ return a+b+c; };$/;\"\tfunction\tfunction:test::__anon4e7b1b580302\tfile:\tsignature:(int c)\tend:19\tcaptures:[a,b]\nc\tinput.cpp\t/^\t\tauto l4 = [a,b](int c){ return a+b+c; };$/;\"\tparameter\tfunction:test::__anon4e7b1b580302::__anon4e7b1b580402\ttyperef:typename:int\tfile:\nl4\tinput.cpp\t/^\t\tauto l4 = [a,b](int c){ return a+b+c; };$/;\"\tlocal\tfunction:test::__anon4e7b1b580302\ttyperef:typename:auto\tfile:\tend:19\nl3\tinput.cpp\t/^\tauto l3 = [=](int a,int b) -> int {$/;\"\tlocal\tfunction:test\ttyperef:typename:auto\tfile:\tend:21\n__anon4e7b1b580502\tinput.cpp\t/^\tauto l5 = [](X<int,int> x,X<long,long>) -> X<double,double> { return X<double,double>(); };$/;\"\tfunction\tfunction:test\ttyperef:typename:X<double,double>\tfile:\tsignature:(X<int,int> x,X<long,long>) \tend:23\tcaptures:[]\nx\tinput.cpp\t/^\tauto l5 = [](X<int,int> x,X<long,long>) -> X<double,double> { return X<double,double>(); };$/;\"\tparameter\tfunction:test::__anon4e7b1b580502\ttyperef:typename:X<int,int>\tfile:\n__anon4e7b1b58060d\tinput.cpp\t/^\tauto l5 = [](X<int,int> x,X<long,long>) -> X<double,double> { return X<double,double>(); };$/;\"\tparameter\tfunction:test::__anon4e7b1b580502\ttyperef:typename:X<long,long>\tfile:\nl5\tinput.cpp\t/^\tauto l5 = [](X<int,int> x,X<long,long>) -> X<double,double> { return X<double,double>(); };$/;\"\tlocal\tfunction:test\ttyperef:typename:auto\tfile:\n__anon4e7b1b580702\tinput.cpp\t/^\t\t\t[l1,l2,l3](int a,int b) -> int {$/;\"\tfunction\tfunction:test\ttyperef:typename:int\tfile:\tsignature:(int a,int b) \tend:28\tcaptures:[l1,l2,l3]\na\tinput.cpp\t/^\t\t\t[l1,l2,l3](int a,int b) -> int {$/;\"\tparameter\tfunction:test::__anon4e7b1b580702\ttyperef:typename:int\tfile:\nb\tinput.cpp\t/^\t\t\t[l1,l2,l3](int a,int b) -> int {$/;\"\tparameter\tfunction:test::__anon4e7b1b580702\ttyperef:typename:int\tfile:\nv1\tinput.cpp\t/^\tint v1 = call($/;\"\tlocal\tfunction:test\ttyperef:typename:int\tfile:\tend:29\n__anon4e7b1b580802\tinput.cpp\t/^auto lg1 = [] { return 0; };$/;\"\tfunction\tfile:\tend:32\tcaptures:[] \nlg1\tinput.cpp\t/^auto lg1 = [] { return 0; };$/;\"\tvariable\ttyperef:typename:auto\tend:32\n__anon4e7b1b580902\tinput.cpp\t/^auto lg2 = [](int a,int b) { return a > b ? a : b; };$/;\"\tfunction\tfile:\tsignature:(int a,int b) \tend:34\tcaptures:[]\na\tinput.cpp\t/^auto lg2 = [](int a,int b) { return a > b ? a : b; };$/;\"\tparameter\tfunction:__anon4e7b1b580902\ttyperef:typename:int\tfile:\nb\tinput.cpp\t/^auto lg2 = [](int a,int b) { return a > b ? a : b; };$/;\"\tparameter\tfunction:__anon4e7b1b580902\ttyperef:typename:int\tfile:\nlg2\tinput.cpp\t/^auto lg2 = [](int a,int b) { return a > b ? a : b; };$/;\"\tvariable\ttyperef:typename:auto\tend:34\n__anon4e7b1b580a02\tinput.cpp\t/^auto lg3 = [=](int a,int b) -> int {$/;\"\tfunction\ttyperef:typename:int\tfile:\tsignature:(int a,int b) \tend:39\tcaptures:[=]\na\tinput.cpp\t/^auto lg3 = [=](int a,int b) -> int {$/;\"\tparameter\tfunction:__anon4e7b1b580a02\ttyperef:typename:int\tfile:\nb\tinput.cpp\t/^auto lg3 = [=](int a,int b) -> int {$/;\"\tparameter\tfunction:__anon4e7b1b580a02\ttyperef:typename:int\tfile:\n__anon4e7b1b580b02\tinput.cpp\t/^\tauto lg4 = [a,b](int c){ return a+b+c; };$/;\"\tfunction\tfunction:__anon4e7b1b580a02\tfile:\tsignature:(int c)\tend:37\tcaptures:[a,b]\nc\tinput.cpp\t/^\tauto lg4 = [a,b](int c){ return a+b+c; };$/;\"\tparameter\tfunction:__anon4e7b1b580a02::__anon4e7b1b580b02\ttyperef:typename:int\tfile:\nlg4\tinput.cpp\t/^\tauto lg4 = [a,b](int c){ return a+b+c; };$/;\"\tlocal\tfunction:__anon4e7b1b580a02\ttyperef:typename:auto\tfile:\tend:37\nlg3\tinput.cpp\t/^auto lg3 = [=](int a,int b) -> int {$/;\"\tvariable\ttyperef:typename:auto\tend:39\n__anon4e7b1b580c02\tinput.cpp\t/^auto lg5 = [](X<int,int> x,X<long,long>) -> X<double,double> { return X<double,double>(); };$/;\"\tfunction\ttyperef:typename:X<double,double>\tfile:\tsignature:(X<int,int> x,X<long,long>) \tend:41\tcaptures:[]\nx\tinput.cpp\t/^auto lg5 = [](X<int,int> x,X<long,long>) -> X<double,double> { return X<double,double>(); };$/;\"\tparameter\tfunction:__anon4e7b1b580c02\ttyperef:typename:X<int,int>\tfile:\n__anon4e7b1b580d0d\tinput.cpp\t/^auto lg5 = [](X<int,int> x,X<long,long>) -> X<double,double> { return X<double,double>(); };$/;\"\tparameter\tfunction:__anon4e7b1b580c02\ttyperef:typename:X<long,long>\tfile:\nlg5\tinput.cpp\t/^auto lg5 = [](X<int,int> x,X<long,long>) -> X<double,double> { return X<double,double>(); };$/;\"\tvariable\ttyperef:typename:auto\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-lambdas.d/input.cpp",
    "content": "// This code compiles with\n//  gcc -std=c++11 input.cpp\n\ntemplate<typename T> int call(T x)\n{\n}\n\ntemplate<typename A,typename B> class X\n{\n};\n\nint test()\n{\n\tauto l1 = [] { return 0; };\n\n\tauto l2 = [](int a,int b) { return a > b ? a : b; };\n\n\tauto l3 = [=](int a,int b) -> int {\n\t\tauto l4 = [a,b](int c){ return a+b+c; };\n\t\treturn l4(5);\n\t};\n\t\n\tauto l5 = [](X<int,int> x,X<long,long>) -> X<double,double> { return X<double,double>(); };\n\n\tint v1 = call(\n\t\t\t[l1,l2,l3](int a,int b) -> int {\n\t\t\t\treturn l1() + l2(a,b) + l3(a,b);\n\t\t\t}\n\t);\n}\n\nauto lg1 = [] { return 0; };\n\nauto lg2 = [](int a,int b) { return a > b ? a : b; };\n\nauto lg3 = [=](int a,int b) -> int {\n\tauto lg4 = [a,b](int c){ return a+b+c; };\n\treturn lg4(5);\n};\n\nauto lg5 = [](X<int,int> x,X<long,long>) -> X<double,double> { return X<double,double>(); };\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-noexcept.d/args.ctags",
    "content": "--kinds-c++=+p\n--fields=+S\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-noexcept.d/expected.tags",
    "content": "Base\tinput.cpp\t/^class Base$/;\"\tc\tfile:\nbar\tinput.cpp\t/^\tvirtual void bar() const noexcept = 0;$/;\"\tp\tclass:Base\ttyperef:typename:void\tfile:\tsignature:() const\nbaz\tinput.cpp\t/^\tint baz() noexcept { return 42; }$/;\"\tf\tclass:Base\ttyperef:typename:int\tfile:\tsignature:()\nfoo\tinput.cpp\t/^\tvirtual void foo() noexcept = 0;$/;\"\tp\tclass:Base\ttyperef:typename:void\tfile:\tsignature:()\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-noexcept.d/input.cpp",
    "content": "class Base\n{\npublic:\n\tvirtual void foo() noexcept = 0;\n\tvirtual void bar() const noexcept = 0;\n\tint baz() noexcept { return 42; }\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-override.d/args.ctags",
    "content": "--kinds-c++=+p\n--fields=+S\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-override.d/expected.tags",
    "content": "Base\tinput.cpp\t/^class Base$/;\"\tc\tfile:\nDerived\tinput.cpp\t/^class Derived : public Base$/;\"\tc\tfile:\nfoo\tinput.cpp\t/^\tvirtual void foo() = 0;$/;\"\tp\tclass:Base\ttyperef:typename:void\tfile:\tsignature:()\nfoo\tinput.cpp\t/^\tvirtual void foo() const override;$/;\"\tp\tclass:Derived\ttyperef:typename:void\tfile:\tsignature:() const\nfoo\tinput.cpp\t/^\tvirtual void foo() override;$/;\"\tp\tclass:Derived\ttyperef:typename:void\tfile:\tsignature:()\nfoo\tinput.cpp\t/^void Base::foo()$/;\"\tf\tclass:Base\ttyperef:typename:void\tsignature:()\nfoo\tinput.cpp\t/^void Derived::foo()$/;\"\tf\tclass:Derived\ttyperef:typename:void\tsignature:()\noverride\tinput.cpp\t/^\tvirtual void override();$/;\"\tp\tclass:Derived\ttyperef:typename:void\tfile:\tsignature:()\noverride\tinput.cpp\t/^void Derived::override()$/;\"\tf\tclass:Derived\ttyperef:typename:void\tsignature:()\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-override.d/input.cpp",
    "content": "class Base\n{\npublic:\n\tvirtual void foo() = 0;\n};\n\nclass Derived : public Base\n{\n\tvirtual void foo() override;\n\tvirtual void foo() const override;\n\tvirtual void override();\n};\n\nvoid Base::foo()\n{\n}\n\nvoid Derived::foo()\n{\n}\n\nvoid Derived::override()\n{\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-raw-strings.d/expected.tags",
    "content": "FOUR\tinput.cpp\t/^#define FOUR /;\"\td\tfile:\nmemb1\tinput.cpp\t/^struct typ1 { int memb1; };$/;\"\tm\tstruct:typ1\ttyperef:typename:int\tfile:\nmemb2\tinput.cpp\t/^struct typ2 { int memb2; };$/;\"\tm\tstruct:typ2\ttyperef:typename:int\tfile:\nmemb3\tinput.cpp\t/^struct typ3 { int memb3; };$/;\"\tm\tstruct:typ3\ttyperef:typename:int\tfile:\nmemb4\tinput.cpp\t/^struct typ4 { int memb4; };$/;\"\tm\tstruct:typ4\ttyperef:typename:int\tfile:\nmemb5\tinput.cpp\t/^struct typ5 { int memb5; };$/;\"\tm\tstruct:typ5\ttyperef:typename:int\tfile:\nmemb6\tinput.cpp\t/^struct typ6 { int memb6; };$/;\"\tm\tstruct:typ6\ttyperef:typename:int\tfile:\nmemb7\tinput.cpp\t/^struct typ7 { int memb7; };$/;\"\tm\tstruct:typ7\ttyperef:typename:int\tfile:\nstr1\tinput.cpp\t/^static const char* str1 = R\"blah($/;\"\tv\ttyperef:typename:const char *\tfile:\nstr2\tinput.cpp\t/^static const char* str2 = R\"blah($/;\"\tv\ttyperef:typename:const char *\tfile:\nstr3\tinput.cpp\t/^static const char* str3 = FOUR\"f(iv)e\";$/;\"\tv\ttyperef:typename:const char *\tfile:\nstr4\tinput.cpp\t/^static const char* str4 = LR\"blah(\";int bug4;)blah\";$/;\"\tv\ttyperef:typename:const char *\tfile:\nstr5\tinput.cpp\t/^static const char* str5 = u8R\"blah(\";int bug5;)blah\";$/;\"\tv\ttyperef:typename:const char *\tfile:\nstr6\tinput.cpp\t/^static const char* str6 = uR\"blah(\";int bug6;)blah\";$/;\"\tv\ttyperef:typename:const char *\tfile:\nstr7\tinput.cpp\t/^static const char* str7 = UR\"blah(\";int bug7;)blah\";$/;\"\tv\ttyperef:typename:const char *\tfile:\ntyp1\tinput.cpp\t/^struct typ1 { int memb1; };$/;\"\ts\tfile:\ntyp2\tinput.cpp\t/^struct typ2 { int memb2; };$/;\"\ts\tfile:\ntyp3\tinput.cpp\t/^struct typ3 { int memb3; };$/;\"\ts\tfile:\ntyp4\tinput.cpp\t/^struct typ4 { int memb4; };$/;\"\ts\tfile:\ntyp5\tinput.cpp\t/^struct typ5 { int memb5; };$/;\"\ts\tfile:\ntyp6\tinput.cpp\t/^struct typ6 { int memb6; };$/;\"\ts\tfile:\ntyp7\tinput.cpp\t/^struct typ7 { int memb7; };$/;\"\ts\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-raw-strings.d/input.cpp",
    "content": "\nstatic const char* str1 = R\"blah(\nlots\nof text\n)blah\";\n\nstruct typ1 { int memb1; };\n\nstatic const char* str2 = R\"blah(\nlots\nof text including a quote\"\n)blah\";\n\nstruct typ2 { int memb2; };\n\n/* check we don't get confused by string concatenation */\n#define FOUR \"four\"\n\nstatic const char* str3 = FOUR\"f(iv)e\";\n\nstruct typ3 { int memb3; };\n\n/* check for prefixes */\nstatic const char* str4 = LR\"blah(\";int bug4;)blah\";\nstruct typ4 { int memb4; };\n\nstatic const char* str5 = u8R\"blah(\";int bug5;)blah\";\nstruct typ5 { int memb5; };\n\nstatic const char* str6 = uR\"blah(\";int bug6;)blah\";\nstruct typ6 { int memb6; };\n\nstatic const char* str7 = UR\"blah(\";int bug7;)blah\";\nstruct typ7 { int memb7; };\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-user-defined-literals.d/expected.tags",
    "content": "operator \"\"_e\tinput.h\t/^float operator \"\"_e(const char*)$/;\"\tf\ttyperef:typename:float\noperator \"\"_print\tinput.h\t/^void operator\"\" _print ( const char* str )$/;\"\tf\ttyperef:typename:void\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11-user-defined-literals.d/input.h",
    "content": "// Quoted from https://en.cppreference.com/w/cpp/language/user_literal:\n\n// used for side-effects\nvoid operator\"\" _print ( const char* str )\n{\n    std::cout << str << '\\n';\n}\n\nfloat operator \"\"_e(const char*)\n{\n\treturn 0.0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11enum.cpp.d/args.ctags",
    "content": "--kinds-c++=*\n--sort=no\n--fields=+{end}\n--fields-c++=+{properties}\n--fields-c=+{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11enum.cpp.d/expected.tags",
    "content": "a\tinput.cpp\t/^#define SOME_MACRO(a,b) 1$/;\"\tD\tmacro:SOME_MACRO\nb\tinput.cpp\t/^#define SOME_MACRO(a,b) 1$/;\"\tD\tmacro:SOME_MACRO\nSOME_MACRO\tinput.cpp\t/^#define SOME_MACRO(/;\"\td\tfile:\tend:2\nwhatever_t\tinput.cpp\t/^typedef int whatever_t;$/;\"\tt\ttyperef:typename:int\tfile:\nuint8_t\tinput.cpp\t/^typedef unsigned char uint8_t;$/;\"\tt\ttyperef:typename:unsigned char\tfile:\nE1\tinput.cpp\t/^enum E1 : int { E1_member1, E1_member2 };$/;\"\tg\ttyperef:typename:int\tfile:\tend:7\nE1_member1\tinput.cpp\t/^enum E1 : int { E1_member1, E1_member2 };$/;\"\te\tenum:E1\tfile:\nE1_member2\tinput.cpp\t/^enum E1 : int { E1_member1, E1_member2 };$/;\"\te\tenum:E1\tfile:\nE2\tinput.cpp\t/^enum E2 : long { E2_member1 };$/;\"\tg\ttyperef:typename:long\tfile:\tend:8\nE2_member1\tinput.cpp\t/^enum E2 : long { E2_member1 };$/;\"\te\tenum:E2\tfile:\nE3\tinput.cpp\t/^enum E3 : unsigned int { E3_member1 };$/;\"\tg\ttyperef:typename:unsigned int\tfile:\tend:9\nE3_member1\tinput.cpp\t/^enum E3 : unsigned int { E3_member1 };$/;\"\te\tenum:E3\tfile:\nE4\tinput.cpp\t/^enum E4 : unsigned long long int { } E4_var1, E4_var2;$/;\"\tg\ttyperef:typename:unsigned long long int\tfile:\tend:10\nE4_var1\tinput.cpp\t/^enum E4 : unsigned long long int { } E4_var1, E4_var2;$/;\"\tv\ttyperef:enum:E4\tend:10\nE4_var2\tinput.cpp\t/^enum E4 : unsigned long long int { } E4_var1, E4_var2;$/;\"\tv\ttyperef:enum:E4\tend:10\nE5\tinput.cpp\t/^enum E5 : whatever_t { E5_member1 } E5_var1;$/;\"\tg\ttyperef:typename:whatever_t\tfile:\tend:11\nE5_member1\tinput.cpp\t/^enum E5 : whatever_t { E5_member1 } E5_var1;$/;\"\te\tenum:E5\tfile:\nE5_var1\tinput.cpp\t/^enum E5 : whatever_t { E5_member1 } E5_var1;$/;\"\tv\ttyperef:enum:E5\tend:11\nEC1\tinput.cpp\t/^enum class EC1 { };$/;\"\tg\tfile:\tend:13\tproperties:scopedenum\nEC2\tinput.cpp\t/^enum class EC2 : short { EC2_member1, EC2_member2 };$/;\"\tg\ttyperef:typename:short\tfile:\tend:14\tproperties:scopedenum\nEC2_member1\tinput.cpp\t/^enum class EC2 : short { EC2_member1, EC2_member2 };$/;\"\te\tenum:EC2\tfile:\nEC2_member2\tinput.cpp\t/^enum class EC2 : short { EC2_member1, EC2_member2 };$/;\"\te\tenum:EC2\tfile:\nES1\tinput.cpp\t/^enum struct ES1 { };$/;\"\tg\tfile:\tend:16\tproperties:scopedenum\nES2\tinput.cpp\t/^enum struct ES2 : unsigned { ES2_member1, ES2_member2 };$/;\"\tg\ttyperef:typename:unsigned\tfile:\tend:17\tproperties:scopedenum\nES2_member1\tinput.cpp\t/^enum struct ES2 : unsigned { ES2_member1, ES2_member2 };$/;\"\te\tenum:ES2\tfile:\nES2_member2\tinput.cpp\t/^enum struct ES2 : unsigned { ES2_member1, ES2_member2 };$/;\"\te\tenum:ES2\tfile:\nES3\tinput.cpp\t/^enum struct ES3 : uint8_t { ES3_member1 = SOME_MACRO(1,whatever appears here), ES3_member2 };$/;\"\tg\ttyperef:typename:uint8_t\tfile:\tend:18\tproperties:scopedenum\nES3_member1\tinput.cpp\t/^enum struct ES3 : uint8_t { ES3_member1 = SOME_MACRO(1,whatever appears here), ES3_member2 };$/;\"\te\tenum:ES3\tfile:\nES3_member2\tinput.cpp\t/^enum struct ES3 : uint8_t { ES3_member1 = SOME_MACRO(1,whatever appears here), ES3_member2 };$/;\"\te\tenum:ES3\tfile:\nES4\tinput.cpp\t/^enum struct ES4 : unsigned long long int { ES4_member1 = (1234 * 10) << 1 };$/;\"\tg\ttyperef:typename:unsigned long long int\tfile:\tend:19\tproperties:scopedenum\nES4_member1\tinput.cpp\t/^enum struct ES4 : unsigned long long int { ES4_member1 = (1234 * 10) << 1 };$/;\"\te\tenum:ES4\tfile:\nES5\tinput.cpp\t/^enum struct ES5 : signed whatever_t { } ES4_var1[10];$/;\"\tg\ttyperef:typename:signed whatever_t\tfile:\tend:20\tproperties:scopedenum\nES4_var1\tinput.cpp\t/^enum struct ES5 : signed whatever_t { } ES4_var1[10];$/;\"\tv\ttyperef:enum:ES5[10]\tend:20\n__anon5f0fdc1d0103\tinput.cpp\t/^enum { Anon1_member1, Anon1_member2 };$/;\"\tg\tfile:\tend:22\nAnon1_member1\tinput.cpp\t/^enum { Anon1_member1, Anon1_member2 };$/;\"\te\tenum:__anon5f0fdc1d0103\tfile:\nAnon1_member2\tinput.cpp\t/^enum { Anon1_member1, Anon1_member2 };$/;\"\te\tenum:__anon5f0fdc1d0103\tfile:\n__anon5f0fdc1d0203\tinput.cpp\t/^enum : unsigned int { Anon2_member1 };$/;\"\tg\ttyperef:typename:unsigned int\tfile:\tend:23\nAnon2_member1\tinput.cpp\t/^enum : unsigned int { Anon2_member1 };$/;\"\te\tenum:__anon5f0fdc1d0203\tfile:\n__anon5f0fdc1d0303\tinput.cpp\t/^enum : whatever_t { Anon3_member1 };$/;\"\tg\ttyperef:typename:whatever_t\tfile:\tend:24\nAnon3_member1\tinput.cpp\t/^enum : whatever_t { Anon3_member1 };$/;\"\te\tenum:__anon5f0fdc1d0303\tfile:\nClass\tinput.cpp\t/^class Class$/;\"\tc\tfile:\tend:32\nCE1\tinput.cpp\t/^\tenum CE1 : int { CE1_member1 = 10, CE1_member2 = (CE1_member1 << 10) };$/;\"\tg\tclass:Class\ttyperef:typename:int\tfile:\tend:28\nCE1_member1\tinput.cpp\t/^\tenum CE1 : int { CE1_member1 = 10, CE1_member2 = (CE1_member1 << 10) };$/;\"\te\tenum:Class::CE1\tfile:\nCE1_member2\tinput.cpp\t/^\tenum CE1 : int { CE1_member1 = 10, CE1_member2 = (CE1_member1 << 10) };$/;\"\te\tenum:Class::CE1\tfile:\nCEC1\tinput.cpp\t/^\tenum class CEC1 : unsigned long int { CEC1_member1 };$/;\"\tg\tclass:Class\ttyperef:typename:unsigned long int\tfile:\tend:29\tproperties:scopedenum\nCEC1_member1\tinput.cpp\t/^\tenum class CEC1 : unsigned long int { CEC1_member1 };$/;\"\te\tenum:Class::CEC1\tfile:\nCES1\tinput.cpp\t/^\tenum struct CES1 : int { CES1_member1 };$/;\"\tg\tclass:Class\ttyperef:typename:int\tfile:\tend:30\tproperties:scopedenum\nCES1_member1\tinput.cpp\t/^\tenum struct CES1 : int { CES1_member1 };$/;\"\te\tenum:Class::CES1\tfile:\nFunction1\tinput.cpp\t/^\tvirtual enum CEC1 Function1(enum CE1 parameter);$/;\"\tp\tclass:Class\ttyperef:enum:CEC1\tfile:\tend:31\tproperties:virtual\nparameter\tinput.cpp\t/^\tvirtual enum CEC1 Function1(enum CE1 parameter);$/;\"\tz\tprototype:Class::Function1\ttyperef:enum:CE1\tfile:\nE1_var1\tinput.cpp\t/^enum E1 E1_var1;$/;\"\tv\ttyperef:enum:E1\tend:41\nEC1_var1\tinput.cpp\t/^enum EC1 EC1_var1[10][10];$/;\"\tv\ttyperef:enum:EC1[10][10]\tend:42\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx11enum.cpp.d/input.cpp",
    "content": "\n#define SOME_MACRO(a,b) 1\n\ntypedef int whatever_t;\ntypedef unsigned char uint8_t;\n\nenum E1 : int { E1_member1, E1_member2 };\nenum E2 : long { E2_member1 };\nenum E3 : unsigned int { E3_member1 };\nenum E4 : unsigned long long int { } E4_var1, E4_var2;\nenum E5 : whatever_t { E5_member1 } E5_var1;\n\nenum class EC1 { };\nenum class EC2 : short { EC2_member1, EC2_member2 };\n\nenum struct ES1 { };\nenum struct ES2 : unsigned { ES2_member1, ES2_member2 };\nenum struct ES3 : uint8_t { ES3_member1 = SOME_MACRO(1,whatever appears here), ES3_member2 };\nenum struct ES4 : unsigned long long int { ES4_member1 = (1234 * 10) << 1 };\nenum struct ES5 : signed whatever_t { } ES4_var1[10];\n\nenum { Anon1_member1, Anon1_member2 };\nenum : unsigned int { Anon2_member1 };\nenum : whatever_t { Anon3_member1 };\n\nclass Class\n{\n\tenum CE1 : int { CE1_member1 = 10, CE1_member2 = (CE1_member1 << 10) };\n\tenum class CEC1 : unsigned long int { CEC1_member1 };\n\tenum struct CES1 : int { CES1_member1 };\n\tvirtual enum CEC1 Function1(enum CE1 parameter);\n};\n\n// Forward declarations: we ignore them.\nenum F1 : whatever_t;\nenum class F2;\nenum class F3 : whatever_t;\nenum struct F4 : unsigned int;\n\n// variable declarations\nenum E1 E1_var1;\nenum EC1 EC1_var1[10][10];\n//enum class EC2 EC2_var1; <-- this is NOT valid C++11\n\n\n\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx14-combined.d/args.ctags",
    "content": "--kinds-c++=+p\n--fields=+S\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx14-combined.d/expected.tags",
    "content": "Base\tinput.cpp\t/^struct Base {$/;\"\ts\tfile:\nFoo\tinput.cpp\t/^struct Foo final : public Base {$/;\"\ts\tfile:\nbar\tinput.cpp\t/^  static constexpr auto bar() noexcept { return 1; }$/;\"\tf\tstruct:Foo\ttyperef:typename:auto\tfile:\tsignature:()\nbaz\tinput.cpp\t/^  virtual void baz() const throw() = 0;$/;\"\tp\tstruct:Base\ttyperef:typename:void\tfile:\tsignature:() const\nbaz\tinput.cpp\t/^  virtual void baz() const throw() final override;$/;\"\tp\tstruct:Foo\ttyperef:typename:void\tfile:\tsignature:() const\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx14-combined.d/input.cpp",
    "content": "struct Base {\n  virtual void baz() const throw() = 0;\n};\n\nstruct Foo final : public Base {\n  static constexpr auto bar() noexcept { return 1; }\n  virtual void baz() const throw() final override;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx14-digit-separator.d/args.ctags",
    "content": "--kinds-c++=+l"
  },
  {
    "path": "Units/parser-cxx.r/cxx14-digit-separator.d/expected.tags",
    "content": "X\tinput.cpp\t/^class X$/;\"\tc\tfile:\na1\tinput.cpp\t/^long a1=1'048'576;$/;\"\tv\ttyperef:typename:long\na2\tinput.cpp\t/^long a2=0x10'0000;$/;\"\tv\ttyperef:typename:long\na3\tinput.cpp\t/^long a3=00'04'00'00'00;$/;\"\tv\ttyperef:typename:long\na4\tinput.cpp\t/^long a4=0b100'000000'000000'000000;$/;\"\tv\ttyperef:typename:long\nb1\tinput.cpp\t/^\tlong b1=1'048'576;$/;\"\tl\tfunction:test\ttyperef:typename:long\tfile:\nb2\tinput.cpp\t/^\tlong b2=0x10'0000;$/;\"\tl\tfunction:test\ttyperef:typename:long\tfile:\nb3\tinput.cpp\t/^\tlong b3=00'04'00'00'00;$/;\"\tl\tfunction:test\ttyperef:typename:long\tfile:\nb4\tinput.cpp\t/^\tlong b4=0b100'000000'000000'000000;$/;\"\tl\tfunction:test\ttyperef:typename:long\tfile:\nc1\tinput.cpp\t/^\tlong c1 = 'a';$/;\"\tl\tfunction:test\ttyperef:typename:long\tfile:\nc2\tinput.cpp\t/^\tlong c2 = 'a';$/;\"\tl\tfunction:test\ttyperef:typename:long\tfile:\nc3\tinput.cpp\t/^\tlong c3 = 'a';$/;\"\tl\tfunction:test\ttyperef:typename:long\tfile:\nc4\tinput.cpp\t/^\tlong c4 = 'a';$/;\"\tl\tfunction:test\ttyperef:typename:long\tfile:\nm1\tinput.cpp\t/^\tlong m1=1'048'576;$/;\"\tm\tclass:X\ttyperef:typename:long\tfile:\nm2\tinput.cpp\t/^\tlong m2=0x10'0000;$/;\"\tm\tclass:X\ttyperef:typename:long\tfile:\nm3\tinput.cpp\t/^\tlong m3=00'04'00'00'00;$/;\"\tm\tclass:X\ttyperef:typename:long\tfile:\nm4\tinput.cpp\t/^\tlong m4=0b100'000000'000000'000000;$/;\"\tm\tclass:X\ttyperef:typename:long\tfile:\ntest\tinput.cpp\t/^void test()$/;\"\tf\ttyperef:typename:void\n"
  },
  {
    "path": "Units/parser-cxx.r/cxx14-digit-separator.d/input.cpp",
    "content": "long a1=1'048'576;\nlong a2=0x10'0000;\nlong a3=00'04'00'00'00;\nlong a4=0b100'000000'000000'000000;\n\nvoid test()\n{\n\tcall(1'048'576);\n\tcall(1'048'576,0x10'0000,'a',00'04'00'00'00);\n\n\tlong b1=1'048'576;\n\tlong c1 = 'a';\n\tlong b2=0x10'0000;\n\tlong c2 = 'a';\n\tlong b3=00'04'00'00'00;\n\tlong c3 = 'a';\n\tlong b4=0b100'000000'000000'000000;\n\tlong c4 = 'a';\n}\n\nclass X\n{\npublic:\n\tlong m1=1'048'576;\n\tlong m2=0x10'0000;\n\tlong m3=00'04'00'00'00;\n\tlong m4=0b100'000000'000000'000000;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/digraph-and-template-angle-confliction.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/digraph-and-template-angle-confliction.d/expected.tags",
    "content": "std\tinput.hh\t/^namespace std {$/;\"\tn\nhash\tinput.hh\t/^  struct hash<::sockaddr_in> {$/;\"\ts\tnamespace:std\na\tinput.hh\t/^    int a;$/;\"\tm\tstruct:std::hash\ttyperef:typename:int\nA\tinput.hh\t/^int A <::> = {1, 2};$/;\"\tv\ttyperef:typename:int[]\nB\tinput.hh\t/^int B <:2:> = {1, 2};$/;\"\tv\ttyperef:typename:int[2]\nN\tinput.hh\t/^#define N /;\"\td\nC\tinput.hh\t/^int C <:N:> = {1, 2};$/;\"\tv\ttyperef:typename:int[]\nD\tinput.hh\t/^int D [] = {1, 2};$/;\"\tv\ttyperef:typename:int[]\nM\tinput.hh\t/^const int M = 3;$/;\"\tv\ttyperef:typename:const int\nE\tinput.hh\t/^int E <:::M:> = {1, 2};$/;\"\tv\ttyperef:typename:int[]\nfoo\tinput.hh\t/^int foo (void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/digraph-and-template-angle-confliction.d/input.hh",
    "content": "#include <netinet/ip.h>\n#include <map>\n\nnamespace std {\n  template <>\n  struct hash<::sockaddr_in> {\n    int a;\n  };\n};\n\nint A <::> = {1, 2};\nint B <:2:> = {1, 2};\n#define N 2\nint C <:N:> = {1, 2};\nint D [] = {1, 2};\n\nconst int M = 3;\nint E <:::M:> = {1, 2};\n\nint foo (void)\n{\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/end-field-for-prototype-kind.d/args.ctags",
    "content": "--fields=+ne\n--kinds-C++=p\n"
  },
  {
    "path": "Units/parser-cxx.r/end-field-for-prototype-kind.d/expected.tags",
    "content": "main\tinput.h\t/^main$/;\"\tp\tline:2\ttyperef:typename:int\tend:11\n"
  },
  {
    "path": "Units/parser-cxx.r/end-field-for-prototype-kind.d/input.h",
    "content": "int\nmain\n(\n\tint\n\targc\n\t,\n\tchar\n\t*\n\t*\n\targv\n\t);\n"
  },
  {
    "path": "Units/parser-cxx.r/enum-in-a-struct--with-q-extra.d/README",
    "content": "S::T::E::alpha and S::T::E::beta are not included intentionally\nTaken from the comments of cxx_tag.c::\n\n\t// If the scope kind is enumeration then we need to remove the\n\t// last scope part. This is what old ctags did.\n\n"
  },
  {
    "path": "Units/parser-cxx.r/enum-in-a-struct--with-q-extra.d/args.ctags",
    "content": "--sort=no\n--extra=+q\n"
  },
  {
    "path": "Units/parser-cxx.r/enum-in-a-struct--with-q-extra.d/expected.tags",
    "content": "S\tinput.cc\t/^namespace S {$/;\"\tn\tfile:\nT\tinput.cc\t/^  struct T {$/;\"\ts\tnamespace:S\tfile:\nS::T\tinput.cc\t/^  struct T {$/;\"\ts\tnamespace:S\tfile:\nE\tinput.cc\t/^    enum E {$/;\"\tg\tstruct:S::T\tfile:\nS::T::E\tinput.cc\t/^    enum E {$/;\"\tg\tstruct:S::T\tfile:\nalpha\tinput.cc\t/^      alpha, beta,$/;\"\te\tenum:S::T::E\tfile:\nS::T::alpha\tinput.cc\t/^      alpha, beta,$/;\"\te\tenum:S::T::E\tfile:\nbeta\tinput.cc\t/^      alpha, beta,$/;\"\te\tenum:S::T::E\tfile:\nS::T::beta\tinput.cc\t/^      alpha, beta,$/;\"\te\tenum:S::T::E\tfile:\nelt\tinput.cc\t/^    } elt;$/;\"\tm\tstruct:S::T\ttyperef:enum:S::T::E\tfile:\nS::T::elt\tinput.cc\t/^    } elt;$/;\"\tm\tstruct:S::T\ttyperef:enum:S::T::E\tfile:\ns\tinput.cc\t/^struct S::T s = { .elt = S::T::E::alpha };$/;\"\tv\ttyperef:struct:S::T\n"
  },
  {
    "path": "Units/parser-cxx.r/enum-in-a-struct--with-q-extra.d/input.cc",
    "content": "namespace S {\n  struct T {\n    enum E {\n      alpha, beta,\n    } elt;\n  };\n}\n\nstruct S::T s = { .elt = S::T::E::alpha };\n"
  },
  {
    "path": "Units/parser-cxx.r/export-2.d/README.md",
    "content": "The test case testing parts of the syntax (2) in https://en.cppreference.com/w/cpp/language/modules.\n\n\texport declaration  (2)\n"
  },
  {
    "path": "Units/parser-cxx.r/export-2.d/args.ctags",
    "content": "--sort=no\n--fields-C++=+{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/export-2.d/expected.tags",
    "content": "A\tinput.cpp\t/^export module A; \\/\\/ declares the primary module interface unit for named module 'A'$/;\"\tM\tproperties:export\nhello\tinput.cpp\t/^export char const* hello() { return \"hello\"; }$/;\"\tf\ttyperef:typename:char const *\tproperties:export\nworld\tinput.cpp\t/^char const* world() { return \"world\"; }$/;\"\tf\ttyperef:typename:char const *\nhi\tinput.cpp\t/^export namespace hi$/;\"\tn\tproperties:export\nenglish\tinput.cpp\t/^    char const* english() { return \"Hi!\"; }$/;\"\tf\tnamespace:hi\ttyperef:typename:char const *\nfrench\tinput.cpp\t/^    char const* french()  { return \"Salut!\"; }$/;\"\tf\tnamespace:hi\ttyperef:typename:char const *\nx\tinput.cpp\t/^export enum x { a = 1 };$/;\"\tg\tproperties:export\na\tinput.cpp\t/^export enum x { a = 1 };$/;\"\te\tenum:x\ntd\tinput.cpp\t/^export typedef int td;$/;\"\tt\ttyperef:typename:int\tproperties:export\ns_\tinput.cpp\t/^struct s_ {$/;\"\ts\tfile:\nmbr\tinput.cpp\t/^  int mbr;$/;\"\tm\tstruct:s_\ttyperef:typename:int\tfile:\ns\tinput.cpp\t/^export struct s {$/;\"\ts\tproperties:export\nmbr\tinput.cpp\t/^  int mbr;$/;\"\tm\tstruct:s\ttyperef:typename:int\ns__\tinput.cpp\t/^struct s__ {$/;\"\ts\tfile:\nmbr\tinput.cpp\t/^  int mbr;$/;\"\tm\tstruct:s__\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/export-2.d/input.cpp",
    "content": "// Taken from https://en.cppreference.com/w/cpp/language/modules\n\nexport module A; // declares the primary module interface unit for named module 'A'\n\n// hello() will be visible by translations units importing 'A'\nexport char const* hello() { return \"hello\"; }\n\n// world() will NOT be visible.\nchar const* world() { return \"world\"; }\n\nexport namespace hi\n{\n    char const* english() { return \"Hi!\"; }\n    char const* french()  { return \"Salut!\"; }\n}\n\nexport enum x { a = 1 };\n\nexport typedef int td;\n\nstruct s_ {\n  int mbr;\n};\n\nexport struct s {\n  int mbr;\n};\n\nstruct s__ {\n  int mbr;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/export-2.d/validator",
    "content": "cxx20+module\n\n"
  },
  {
    "path": "Units/parser-cxx.r/export-3.d/README.md",
    "content": "The test case testing parts of the syntax (3) in https://en.cppreference.com/w/cpp/language/modules.\n\n\texport { declaration-seq(optional) }  (3)\n"
  },
  {
    "path": "Units/parser-cxx.r/export-3.d/args.ctags",
    "content": "--sort=no\n--fields-C++=+{properties}\n--kinds-C++=+p\n"
  },
  {
    "path": "Units/parser-cxx.r/export-3.d/expected.tags",
    "content": "Y\tinput.cpp\t/^export module Y;$/;\"\tM\tproperties:export\nZ0\tinput.cpp\t/^  namespace Z0 {$/;\"\tn\tproperties:export\nz0\tinput.cpp\t/^    int z0;$/;\"\tv\tnamespace:Z0\ttyperef:typename:int\nX\tinput.cpp\t/^namespace X {$/;\"\tn\tfile:\na\tinput.cpp\t/^  int a;$/;\"\tv\tnamespace:X\ttyperef:typename:int\nx\tinput.cpp\t/^    int x;$/;\"\tv\tnamespace:X\ttyperef:typename:int\tproperties:export\nf\tinput.cpp\t/^    int f(int i);$/;\"\tp\tnamespace:X\ttyperef:typename:int\tproperties:export\nu\tinput.cpp\t/^    union u {$/;\"\tu\tnamespace:X\tproperties:export\nmbr\tinput.cpp\t/^    int mbr;$/;\"\tm\tunion:X::u\ttyperef:typename:int\nb\tinput.cpp\t/^  int b;$/;\"\tv\tnamespace:X\ttyperef:typename:int\nm\tinput.cpp\t/^int m;$/;\"\tv\ttyperef:typename:int\nz\tinput.cpp\t/^  int z;$/;\"\tv\ttyperef:typename:int\tproperties:export\nE\tinput.cpp\t/^  enum E { a = 1 };$/;\"\tg\tproperties:export\na\tinput.cpp\t/^  enum E { a = 1 };$/;\"\te\tenum:E\ntd\tinput.cpp\t/^  typedef int td;$/;\"\tt\ttyperef:typename:int\tproperties:export\nc\tinput.cpp\t/^  class c {$/;\"\tc\tproperties:export\nmbr\tinput.cpp\t/^    int mbr;$/;\"\tm\tclass:c\ttyperef:typename:int\nn\tinput.cpp\t/^int n;$/;\"\tv\ttyperef:typename:int\no\tinput.cpp\t/^static int o;$/;\"\tv\ttyperef:typename:int\tfile:\tproperties:static\n"
  },
  {
    "path": "Units/parser-cxx.r/export-3.d/input.cpp",
    "content": "export module Y;\n\nexport {\n  namespace Z0 {\n    int z0;\n  };\n}\n\nnamespace X {\n  int a;\n  export {\n    int x;\n    int f(int i);\n    union u {\n    int mbr;\n  };\n\n  }\n  int b;\n};\n\n\nint m;\nexport {\n  int z;\n  enum E { a = 1 };\n  typedef int td;\n  class c {\n    int mbr;\n  };\n}\nint n;\nstatic int o;\n"
  },
  {
    "path": "Units/parser-cxx.r/export-3.d/validator",
    "content": "cxx20+module\n\n"
  },
  {
    "path": "Units/parser-cxx.r/export-namespace-alias.d/args.ctags",
    "content": "--sort=no\n--fields-C++=+{properties}\n--fields=+K\n--kinds-C++=+{alias}\n"
  },
  {
    "path": "Units/parser-cxx.r/export-namespace-alias.d/expected.tags",
    "content": "mylib\tinput.cpp\t/^export module mylib;$/;\"\tmodule\tproperties:export\nX\tinput.cpp\t/^export namespace X {$/;\"\tnamespace\tproperties:export\ni\tinput.cpp\t/^\t int i;$/;\"\tvariable\tnamespace:X\ttyperef:typename:int\nZ\tinput.cpp\t/^export namespace Z = X;$/;\"\talias\tproperties:export\tname:X\n"
  },
  {
    "path": "Units/parser-cxx.r/export-namespace-alias.d/input.cpp",
    "content": "export module mylib;\n\nexport namespace X {\n\t int i;\n}\n\nexport namespace Z = X;\n"
  },
  {
    "path": "Units/parser-cxx.r/export-namespace-alias.d/validator",
    "content": "cxx20+module\n"
  },
  {
    "path": "Units/parser-cxx.r/export-using.d/args.ctags",
    "content": "--sort=no\n--fields=+K\n--kinds-C++=+MtNp\n--fields-C++=+{properties}\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-cxx.r/export-using.d/expected.tags",
    "content": "Delta\tinput.cpp\t/^export module Delta;$/;\"\tmodule\troles:def\tproperties:export\nParam\tinput.cpp\t/^export using Param = int;$/;\"\ttypedef\ttyperef:typename:int\troles:def\tproperties:export\nParam\tinput.cpp\t/^export using ::Param;$/;\"\tname\troles:def\tproperties:export\nParam\tinput.cpp\t/^export using ::Param;\t\t\\/\\/ We can declare an object more than twice.$/;\"\tname\troles:def\tproperties:export\nfn\tinput.cpp\t/^export void fn();$/;\"\tprototype\ttyperef:typename:void\troles:def\tproperties:export\n"
  },
  {
    "path": "Units/parser-cxx.r/export-using.d/input.cpp",
    "content": "// Derived from https://github.com/universal-ctags/ctags/issues/4003 submitted by @adrianconstantin-leroy.\nexport module Delta;\n\nexport using Param = int;\nexport using ::Param;\nexport using ::Param;\t\t// We can declare an object more than twice.\nexport void fn();\n"
  },
  {
    "path": "Units/parser-cxx.r/export-using.d/validator",
    "content": "cxx20+module\n"
  },
  {
    "path": "Units/parser-cxx.r/extern.d/args.ctags",
    "content": "--kinds-c++=+px\n--fields-c++=+{properties}"
  },
  {
    "path": "Units/parser-cxx.r/extern.d/expected.tags",
    "content": "f\tinput.cpp\t/^extern \"C\" void f(void);$/;\"\tp\ttyperef:typename:void\tfile:\tproperties:extern\ng\tinput.cpp\t/^extern \"C\" void g(void) {}$/;\"\tf\ttyperef:typename:void\tproperties:extern\nh\tinput.cpp\t/^  void h(void);$/;\"\tp\ttyperef:typename:void\tfile:\ni\tinput.cpp\t/^  int i;$/;\"\tv\ttyperef:typename:int\nj\tinput.cpp\t/^  extern int j;$/;\"\tx\ttyperef:typename:int\tproperties:extern\n"
  },
  {
    "path": "Units/parser-cxx.r/extern.d/input.cpp",
    "content": "// This was initially reported as bug 931@github reported by Corax26 on\n// 12/05/2016: the extern \"C\" declarations were missing from the ctags output.\n//\n// Additionally this test checks the +{c.properties} field for the \"extern\"\n// property being properly set.\n\nextern \"C\" void f(void);\nextern \"C\" void g(void) {}\n\nextern \"C\"\n{\n  // Please note that h() and i have internal linkage (but their name\n  // mangling is C-style). h() is just a prototype while i is both\n  // a declaration AND a definition of variable.\n  void h(void);\n  int i;\n\n  // j has external linkage (declaration only).\n  extern int j;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/field-nth.d/args.ctags",
    "content": "--sort=no\n--fields=+oS\n--kinds-C++=+DzZ\n--fields-C++={template}\n"
  },
  {
    "path": "Units/parser-cxx.r/field-nth.d/expected.tags",
    "content": "f\tinput.h\t/^inline void f(int x, int y) {}$/;\"\tf\ttyperef:typename:void\tsignature:(int x,int y)\nx\tinput.h\t/^inline void f(int x, int y) {}$/;\"\tz\tfunction:f\ttyperef:typename:int\tfile:\tnth:0\ny\tinput.h\t/^inline void f(int x, int y) {}$/;\"\tz\tfunction:f\ttyperef:typename:int\tfile:\tnth:1\nX\tinput.h\t/^#define F(X,Y) (X+Y)$/;\"\tD\tmacro:F\tnth:0\nY\tinput.h\t/^#define F(X,Y) (X+Y)$/;\"\tD\tmacro:F\tnth:1\nF\tinput.h\t/^#define F(/;\"\td\tsignature:(X,Y)\nC\tinput.h\t/^class C {};$/;\"\tc\ttemplate:<class T1,class T2,int I>\nT1\tinput.h\t/^template<class T1, class T2, int I>$/;\"\tZ\tclass:C\ttyperef:meta:class\tnth:0\nT2\tinput.h\t/^template<class T1, class T2, int I>$/;\"\tZ\tclass:C\ttyperef:meta:class\tnth:1\nI\tinput.h\t/^template<class T1, class T2, int I>$/;\"\tZ\tclass:C\ttyperef:typename:int\tnth:2\nD\tinput.h\t/^class D {$/;\"\tc\ni\tinput.h\t/^\tint i, j;$/;\"\tm\tclass:D\ttyperef:typename:int\tnth:0\nj\tinput.h\t/^\tint i, j;$/;\"\tm\tclass:D\ttyperef:typename:int\tnth:1\nc\tinput.h\t/^\tchar c;$/;\"\tm\tclass:D\ttyperef:typename:char\tnth:2\ncolor\tinput.h\t/^enum color {$/;\"\tg\nred\tinput.h\t/^\tred, green, blue,$/;\"\te\tenum:color\tnth:0\ngreen\tinput.h\t/^\tred, green, blue,$/;\"\te\tenum:color\tnth:1\nblue\tinput.h\t/^\tred, green, blue,$/;\"\te\tenum:color\tnth:2\n"
  },
  {
    "path": "Units/parser-cxx.r/field-nth.d/input.h",
    "content": "inline void f(int x, int y) {}\n#define F(X,Y) (X+Y)\n\ntemplate<class T1, class T2, int I>\nclass C {};\n\nclass D {\n\tint i, j;\n\tchar c;\n};\n\nenum color {\n\tred, green, blue,\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/foreach.d/args.ctags",
    "content": "--kinds-c++=+pxl\n-D foreach(arg1,...)=for(arg1;;)\n"
  },
  {
    "path": "Units/parser-cxx.r/foreach.d/expected.tags",
    "content": "a\tinput.cpp\t/^int a,b;$/;\"\tv\ttyperef:typename:int\nb\tinput.cpp\t/^int a,b;$/;\"\tv\ttyperef:typename:int\nforeach\tinput.cpp\t/^#define foreach(/;\"\td\tfile:\nmain\tinput.cpp\t/^int main(int,char **)$/;\"\tf\ttyperef:typename:int\np\tinput.cpp\t/^\tforeach(char * p,pointers)$/;\"\tl\tfunction:main\ttyperef:typename:char *\tfile:\npointers\tinput.cpp\t/^char * pointers[10];$/;\"\tv\ttyperef:typename:char * [10]\n"
  },
  {
    "path": "Units/parser-cxx.r/foreach.d/input.cpp",
    "content": "\n// In real world this would have a (rather complex) implementation.\n// See Q_FOREACH() and foreach() macros in Qt as example.\n#define foreach(_a,_b)\n\nchar * pointers[10];\nint a,b;\n\nint main(int,char **)\n{\n\t\n\t//...\n\t\n\t// p is declared inside foreach() parenthesis.\n\t// pointers is NOT declared here\n\tforeach(char * p,pointers)\n\t{\n\n\t}\n\n\t// This is not a variable declaration.\n\tif(a * b)\n\t{\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/func-name-in-parentheses.d/args.ctags",
    "content": "--sort=no\n--kinds-C=+p\n--kinds-C++=+p\n--fields=+KzS\n"
  },
  {
    "path": "Units/parser-cxx.r/func-name-in-parentheses.d/expected.tags",
    "content": "gboolean\tinput.c\t/^typedef boolean gboolean;$/;\"\tkind:typedef\ttyperef:typename:boolean\tfile:\ngchar\tinput.c\t/^typedef char gchar;$/;\"\tkind:typedef\ttyperef:typename:char\tfile:\ng_str_has_prefix\tinput.c\t/^gboolean             (g_str_has_prefix) (const gchar *str,$/;\"\tkind:prototype\ttyperef:typename:gboolean\tfile:\tsignature:(const gchar * str,const gchar * prefix)\nI\tinput.c\t/^typedef int I;$/;\"\tkind:typedef\ttyperef:typename:int\tfile:\nfp\tinput.c\t/^I (fp) (void);$/;\"\tkind:prototype\ttyperef:typename:I\tfile:\tsignature:(void)\nfi\tinput.c\t/^I (fi) (void) { return 0; }$/;\"\tkind:function\ttyperef:typename:I\tsignature:(void)\ngp\tinput.c\t/^I* (gp) (void);$/;\"\tkind:prototype\ttyperef:typename:I *\tfile:\tsignature:(void)\ngi\tinput.c\t/^I* (gi) (void) { return NULL; }$/;\"\tkind:function\ttyperef:typename:I *\tsignature:(void)\nPoint\tinput-0.cpp\t/^class Point {$/;\"\tkind:class\tfile:\nx\tinput-0.cpp\t/^  double x, y;$/;\"\tkind:member\tclass:Point\ttyperef:typename:double\tfile:\ny\tinput-0.cpp\t/^  double x, y;$/;\"\tkind:member\tclass:Point\ttyperef:typename:double\tfile:\nmyns\tinput-0.cpp\t/^namespace myns {$/;\"\tkind:namespace\tfile:\ng\tinput-0.cpp\t/^  class Point * (g)();$/;\"\tkind:prototype\tnamespace:myns\ttyperef:class:Point *\tfile:\tsignature:()\nmysubns\tinput-0.cpp\t/^  namespace mysubns {$/;\"\tkind:namespace\tnamespace:myns\tfile:\nh\tinput-0.cpp\t/^    class Point * ((h))();$/;\"\tkind:prototype\tnamespace:myns::mysubns\ttyperef:class:Point *\tfile:\tsignature:()\nf\tinput-0.cpp\t/^class Point * (f)() {$/;\"\tkind:function\ttyperef:class:Point *\tsignature:()\n"
  },
  {
    "path": "Units/parser-cxx.r/func-name-in-parentheses.d/input-0.cpp",
    "content": "class Point {\n  double x, y;\n};\n\nnamespace myns {\n  class Point * (g)();\n  namespace mysubns {\n    class Point * ((h))();\n  };\n};\n\nclass Point * (f)() {\n  return nullptr;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/func-name-in-parentheses.d/input.c",
    "content": "typedef boolean gboolean;\ntypedef char gchar;\n\ngboolean             (g_str_has_prefix) (const gchar *str,\n                                         const gchar *prefix);\ntypedef int I;\n\nI (fp) (void);\nI (fi) (void) { return 0; }\nI* (gp) (void);\nI* (gi) (void) { return NULL; }\n"
  },
  {
    "path": "Units/parser-cxx.r/function-return-type-via-macro.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=fpvx\n--fields=+s\n"
  },
  {
    "path": "Units/parser-cxx.r/function-return-type-via-macro.d/expected.tags",
    "content": "PL_ClearArenaPool\tinput.cpp\t/^PR_EXTERN(void) PL_ClearArenaPool(PLArenaPool *pool, PRInt32 pattern);$/;\"\tp\ttyperef:typename:void\tfile:\ndeflateBound\tinput.cpp\t/^GIT_INLINE(size_t) deflateBound(z_streamp stream, size_t s)$/;\"\tf\ttyperef:typename:size_t\nap_os_create_privileged_process\tinput.cpp\t/^AP_DECLARE(apr_status_t) ap_os_create_privileged_process($/;\"\tp\ttyperef:typename:apr_status_t\tfile:\nhandleError\tinput.cpp\t/^LOCAL(struct errRecord *) handleError(z_streamp stream, size_t s) MAY_EXIT$/;\"\tf\ttyperef:struct:errRecord *\n"
  },
  {
    "path": "Units/parser-cxx.r/function-return-type-via-macro.d/input.cpp",
    "content": "// Various bugs reported by Ivc.\n\nPR_EXTERN(void) PL_ClearArenaPool(PLArenaPool *pool, PRInt32 pattern);\n\nGIT_INLINE(size_t) deflateBound(z_streamp stream, size_t s)\n{\n\treturn (s + ((s + 7) >> 3) + ((s + 63) >> 6) + 11);\n}\n\nAP_DECLARE(apr_status_t) ap_os_create_privileged_process(\n\tconst request_rec *r,\n\tapr_proc_t *newproc,\n\tconst char *progname,\n\tconst char * const *args,\n\tconst char * const *env,\n\tapr_procattr_t *attr,\n\tapr_pool_t *p);\n\t\nLOCAL(struct errRecord *) handleError(z_streamp stream, size_t s) MAY_EXIT\n{\n\tif (size == 0)\n\t\texit (1);\n\treturn ERR_REC;\n}\n\n"
  },
  {
    "path": "Units/parser-cxx.r/function-return-types.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=fpm\n--fields=+te\n--fields-c++=+{template}\n"
  },
  {
    "path": "Units/parser-cxx.r/function-return-types.d/expected.tags",
    "content": "p00\tinput.cpp\t/^void p00();$/;\"\tp\ttyperef:typename:void\tfile:\tend:20\np01\tinput.cpp\t/^int p01();$/;\"\tp\ttyperef:typename:int\tfile:\tend:21\np02\tinput.cpp\t/^unsigned int p02();$/;\"\tp\ttyperef:typename:unsigned int\tfile:\tend:22\np03\tinput.cpp\t/^auto p03() -> int;$/;\"\tp\ttyperef:typename:int\tfile:\tend:23\np04\tinput.cpp\t/^int * p04();$/;\"\tp\ttyperef:typename:int *\tfile:\tend:24\np05\tinput.cpp\t/^const unsigned long long int & p05();$/;\"\tp\ttyperef:typename:const unsigned long long int &\tfile:\tend:25\np06\tinput.cpp\t/^static inline int * p06();$/;\"\tp\ttyperef:typename:int *\tfile:\tend:26\np07\tinput.cpp\t/^std::string & p07();$/;\"\tp\ttyperef:typename:std::string &\tfile:\tend:27\np08\tinput.cpp\t/^std::vector<std::string> * p08();$/;\"\tp\ttyperef:typename:std::vector<std::string> *\tfile:\tend:28\np09\tinput.cpp\t/^auto p09() -> std::vector<std::string> ***;$/;\"\tp\ttyperef:typename:std::vector<std::string> ***\tfile:\tend:29\np10\tinput.cpp\t/^auto p10() -> std::string;$/;\"\tp\ttyperef:typename:std::string\tfile:\tend:30\np11\tinput.cpp\t/^auto p11() -> int (*)(int);$/;\"\tp\ttyperef:typename:int (*)(int)\tfile:\tend:31\np12\tinput.cpp\t/^struct Struct p12();$/;\"\tp\ttyperef:struct:Struct\tfile:\tend:32\np13\tinput.cpp\t/^Struct p13();$/;\"\tp\ttyperef:typename:Struct\tfile:\tend:33\np14\tinput.cpp\t/^union Union p14();$/;\"\tp\ttyperef:union:Union\tfile:\tend:34\np15\tinput.cpp\t/^Union p15();$/;\"\tp\ttyperef:typename:Union\tfile:\tend:35\np15p\tinput.cpp\t/^class Class * p15p();$/;\"\tp\ttyperef:class:Class *\tfile:\tend:36\np16\tinput.cpp\t/^Class & p16();$/;\"\tp\ttyperef:typename:Class &\tfile:\tend:37\np17\tinput.cpp\t/^const enum Enum p17();$/;\"\tp\ttyperef:typename:const enum Enum\tfile:\tend:38\np18\tinput.cpp\t/^Enum p18();$/;\"\tp\ttyperef:typename:Enum\tfile:\tend:39\nf00\tinput.cpp\t/^void f00()$/;\"\tf\ttyperef:typename:void\tend:43\nf01\tinput.cpp\t/^int f01()$/;\"\tf\ttyperef:typename:int\tend:48\nf02\tinput.cpp\t/^unsigned int f02()$/;\"\tf\ttyperef:typename:unsigned int\tend:53\nf03\tinput.cpp\t/^auto f03() -> int$/;\"\tf\ttyperef:typename:int\tend:58\nf04\tinput.cpp\t/^int * f04()$/;\"\tf\ttyperef:typename:int *\tend:63\nf05\tinput.cpp\t/^const unsigned long long int & f05()$/;\"\tf\ttyperef:typename:const unsigned long long int &\tend:69\nf06\tinput.cpp\t/^static inline int * f06()$/;\"\tf\ttyperef:typename:int *\tfile:\tend:74\nf07\tinput.cpp\t/^std::string & f07()$/;\"\tf\ttyperef:typename:std::string &\tend:80\nf08\tinput.cpp\t/^std::vector<std::string> * f08()$/;\"\tf\ttyperef:typename:std::vector<std::string> *\tend:85\np09\tinput.cpp\t/^auto p09() -> std::vector<std::string> ***$/;\"\tf\ttyperef:typename:std::vector<std::string> ***\tend:90\nf10\tinput.cpp\t/^auto f10() -> std::string$/;\"\tf\ttyperef:typename:std::string\tend:96\nf11\tinput.cpp\t/^auto f11() -> int (*)(int)$/;\"\tf\ttyperef:typename:int (*)(int)\tend:101\nf13\tinput.cpp\t/^template<typename A> std::vector<A> * f13()$/;\"\tf\ttyperef:typename:std::vector<A> *\tend:106\ttemplate:<typename A>\nf14\tinput.cpp\t/^template<typename A> auto f14() -> std::vector<A> *$/;\"\tf\ttyperef:typename:std::vector<A> *\tend:111\ttemplate:<typename A>\nm00\tinput.cpp\t/^\tvoid m00();$/;\"\tp\tclass:X\ttyperef:typename:void\tfile:\tend:116\nm01\tinput.cpp\t/^\tconstexpr int m01(){ return 0; };$/;\"\tf\tclass:X\ttyperef:typename:int\tfile:\tend:117\nm02\tinput.cpp\t/^\tunsigned int m02();$/;\"\tp\tclass:X\ttyperef:typename:unsigned int\tfile:\tend:118\nm03\tinput.cpp\t/^\tstatic auto m03() -> int;$/;\"\tp\tclass:X\ttyperef:typename:int\tfile:\tend:119\nm04\tinput.cpp\t/^\tint * m04();$/;\"\tp\tclass:X\ttyperef:typename:int *\tfile:\tend:120\nm05\tinput.cpp\t/^\tconst unsigned long long int & m05();$/;\"\tp\tclass:X\ttyperef:typename:const unsigned long long int &\tfile:\tend:121\nm06\tinput.cpp\t/^\tstatic inline int * m06();$/;\"\tp\tclass:X\ttyperef:typename:int *\tfile:\tend:122\nm07\tinput.cpp\t/^\tvirtual std::string & m07();$/;\"\tp\tclass:X\ttyperef:typename:std::string &\tfile:\tend:123\nm08\tinput.cpp\t/^\tstd::vector<std::string> * m08();$/;\"\tp\tclass:X\ttyperef:typename:std::vector<std::string> *\tfile:\tend:124\nm09\tinput.cpp\t/^\tauto m09() -> std::vector<std::string> ***;$/;\"\tp\tclass:X\ttyperef:typename:std::vector<std::string> ***\tfile:\tend:125\nm10\tinput.cpp\t/^\tvirtual auto m10() const -> std::string;$/;\"\tp\tclass:X\ttyperef:typename:std::string\tfile:\tend:126\nm11\tinput.cpp\t/^\tvirtual auto m11() const -> int (*)(int);$/;\"\tp\tclass:X\ttyperef:typename:int (*)(int)\tfile:\tend:127\n"
  },
  {
    "path": "Units/parser-cxx.r/function-return-types.d/input.cpp",
    "content": "#include <string>\n#include <vector>\n\nstruct Struct\n{\n};\n\nenum Enum\n{\n};\n\nclass Class\n{\n};\n\nunion Union\n{\n};\n\nvoid p00();\nint p01();\nunsigned int p02();\nauto p03() -> int;\nint * p04();\nconst unsigned long long int & p05();\nstatic inline int * p06();\nstd::string & p07();\nstd::vector<std::string> * p08();\nauto p09() -> std::vector<std::string> ***;\nauto p10() -> std::string;\nauto p11() -> int (*)(int);\nstruct Struct p12();\nStruct p13();\nunion Union p14();\nUnion p15();\nclass Class * p15p();\nClass & p16();\nconst enum Enum p17();\nEnum p18();\n\nvoid f00()\n{\n}\n\nint f01()\n{\n\treturn 0;\n}\n\nunsigned int f02()\n{\n\treturn 0;\n}\n\nauto f03() -> int\n{\n\treturn 0;\n}\n\nint * f04()\n{\n\treturn 0;\n}\n\nconst unsigned long long int & f05()\n{\n\tunsigned long long int x;\n\treturn x;\n}\n\nstatic inline int * f06()\n{\n\treturn 0;\n}\n\nstd::string & f07()\n{\n\tstd::string x;\n\treturn x;\n}\n\nstd::vector<std::string> * f08()\n{\n\treturn 0;\n}\n\nauto p09() -> std::vector<std::string> ***\n{\n\treturn 0;\n}\n\nauto f10() -> std::string\n{\n\tstd::string x;\n\treturn x;\n}\n\nauto f11() -> int (*)(int)\n{\n\treturn 0;\n}\n\ntemplate<typename A> std::vector<A> * f13()\n{\n\treturn 0;\n}\n\ntemplate<typename A> auto f14() -> std::vector<A> *\n{\n\treturn 0;\n}\n\nclass X\n{\npublic:\n\tvoid m00();\n\tconstexpr int m01(){ return 0; };\n\tunsigned int m02();\n\tstatic auto m03() -> int;\n\tint * m04();\n\tconst unsigned long long int & m05();\n\tstatic inline int * m06();\n\tvirtual std::string & m07();\n\tstd::vector<std::string> * m08();\n\tauto m09() -> std::vector<std::string> ***;\n\tvirtual auto m10() const -> std::string;\n\tvirtual auto m11() const -> int (*)(int);\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/function_try_block.d/args.ctags",
    "content": "--kinds-c++=+pflz\n--fields=+SsKe\n--fields-c++=+{captures}+{properties}\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/function_try_block.d/expected.tags",
    "content": "S\tinput.cxx\t/^struct S {$/;\"\tstruct\tfile:\tend:11\nm\tinput.cxx\t/^    std::string m;$/;\"\tmember\tstruct:S\ttyperef:typename:std::string\tfile:\tend:5\nS\tinput.cxx\t/^    S(const std::string& arg) try : m(arg, 100) {$/;\"\tfunction\tstruct:S\tfile:\tsignature:(const std::string & arg)\tend:10\tproperties:fntryblock\narg\tinput.cxx\t/^    S(const std::string& arg) try : m(arg, 100) {$/;\"\tparameter\tfunction:S::S\ttyperef:typename:const std::string &\tfile:\ne\tinput.cxx\t/^    } catch(const std::exception& e) {$/;\"\tlocal\tfunction:S::S\ttyperef:typename:const std::exception &\tfile:\tend:8\nf\tinput.cxx\t/^int f(int n = 2) try {$/;\"\tfunction\ttyperef:typename:int\tsignature:(int n=2)\tend:20\tproperties:fntryblock\nn\tinput.cxx\t/^int f(int n = 2) try {$/;\"\tparameter\tfunction:f\ttyperef:typename:int\tfile:\nf2\tinput.cxx\t/^int f2() try {$/;\"\tfunction\ttyperef:typename:int\tsignature:()\tend:28\tproperties:fntryblock\nf2v1\tinput.cxx\t/^} catch(SomeKindOfException &f2v1)$/;\"\tlocal\tfunction:f2\ttyperef:typename:SomeKindOfException &\tfile:\tend:23\nf2v2\tinput.cxx\t/^} catch(SomeOtherKindOfException &f2v2)$/;\"\tlocal\tfunction:f2\ttyperef:typename:SomeOtherKindOfException &\tfile:\tend:25\nf3\tinput.cxx\t/^int f3()$/;\"\tfunction\ttyperef:typename:int\tsignature:()\tend:38\nf3v1\tinput.cxx\t/^\t\tint f3v1 = 10;$/;\"\tlocal\tfunction:f3\ttyperef:typename:int\tfile:\tend:34\nf3v2\tinput.cxx\t/^\t} catch(std::exception & f3v2)$/;\"\tlocal\tfunction:f3\ttyperef:typename:std::exception &\tfile:\tend:35\nf4\tinput.cxx\t/^auto f4() -> void try {$/;\"\tfunction\ttyperef:typename:void try\tsignature:()\tend:43\tproperties:fntryblock\n"
  },
  {
    "path": "Units/parser-cxx.r/function_try_block.d/input.cxx",
    "content": "/* Taken from\n * http://en.cppreference.com/w/cpp/language/function-try-block */\n\nstruct S {\n    std::string m;\n    S(const std::string& arg) try : m(arg, 100) {\n        std::cout << \"constructed, mn = \" << m << '\\n';\n    } catch(const std::exception& e) {\n        std::cerr << \"arg=\" << arg << \" failed: \" << e.what() << '\\n';\n    } // implicit throw; here\n};\n\nint f(int n = 2) try {\n   ++n; // increments the function parameter\n   throw n;\n} catch(...) {\n   ++n; // n is in scope and still refers to the function parameter\n   assert(n == 4);\n   return n;\n}\n\nint f2() try {\n} catch(SomeKindOfException &f2v1)\n{\n} catch(SomeOtherKindOfException &f2v2)\n{\n} catch(...) {\n}\n\nint f3()\n{\n\t// This is NOT a function-try-block\n\ttry {\n\t\tint f3v1 = 10;\n\t} catch(std::exception & f3v2)\n\t{\n\t}\n}\n\nauto f4() -> void try {\n} catch(...)\n{\n}"
  },
  {
    "path": "Units/parser-cxx.r/functions.cpp.d/args.ctags",
    "content": "--kinds-c++=pfz\n--fields=+Se\n"
  },
  {
    "path": "Units/parser-cxx.r/functions.cpp.d/expected.tags",
    "content": "f01\tinput.cpp\t/^int f01(int f01a01,int f01a02)$/;\"\tf\ttyperef:typename:int\tsignature:(int f01a01,int f01a02)\tend:34\nf01a01\tinput.cpp\t/^int f01(int f01a01,int f01a02)$/;\"\tz\tfunction:f01\ttyperef:typename:int\tfile:\nf01a02\tinput.cpp\t/^int f01(int f01a01,int f01a02)$/;\"\tz\tfunction:f01\ttyperef:typename:int\tfile:\nf02\tinput.cpp\t/^unsigned short int * f02(unsigned int & f02a01,...)$/;\"\tf\ttyperef:typename:unsigned short int *\tsignature:(unsigned int & f02a01,...)\tend:39\nf02a01\tinput.cpp\t/^unsigned short int * f02(unsigned int & f02a01,...)$/;\"\tz\tfunction:f02\ttyperef:typename:unsigned int &\tfile:\nf03\tinput.cpp\t/^auto f03(const int & f03a01,void * f03a02) -> const int &$/;\"\tf\ttyperef:typename:const int &\tsignature:(const int & f03a01,void * f03a02)\tend:44\nf03a01\tinput.cpp\t/^auto f03(const int & f03a01,void * f03a02) -> const int &$/;\"\tz\tfunction:f03\ttyperef:typename:const int &\tfile:\nf03a02\tinput.cpp\t/^auto f03(const int & f03a01,void * f03a02) -> const int &$/;\"\tz\tfunction:f03\ttyperef:typename:void *\tfile:\nf04\tinput.cpp\t/^auto f04() -> int (*)(int)$/;\"\tf\ttyperef:typename:int (*)(int)\tsignature:()\tend:49\nf05\tinput.cpp\t/^static inline std::string f05(const int *** f05a01)$/;\"\tf\ttyperef:typename:std::string\tfile:\tsignature:(const int *** f05a01)\tend:54\nf05a01\tinput.cpp\t/^static inline std::string f05(const int *** f05a01)$/;\"\tz\tfunction:f05\ttyperef:typename:const int ***\tfile:\nf06\tinput.cpp\t/^\t\tauto f06(n01::c01 && f06a01) -> type01 *;$/;\"\tp\tnamespace:n01::n02\ttyperef:typename:type01 *\tfile:\tsignature:(n01::c01 && f06a01)\tend:15\nf06\tinput.cpp\t/^auto n01::n02::f06(n01::c01 && f06a01) -> n01::n02::type01 *$/;\"\tf\tclass:n01::n02\ttyperef:typename:n01::n02::type01 *\tsignature:(n01::c01 && f06a01)\tend:59\nf06a01\tinput.cpp\t/^\t\tauto f06(n01::c01 && f06a01) -> type01 *;$/;\"\tz\tprototype:n01::n02::f06\ttyperef:typename:n01::c01 &&\tfile:\nf06a01\tinput.cpp\t/^auto n01::n02::f06(n01::c01 && f06a01) -> n01::n02::type01 *$/;\"\tz\tfunction:n01::n02::f06\ttyperef:typename:n01::c01 &&\tfile:\nf07\tinput.cpp\t/^unsigned int f07(int (*f07a01)(int * x1,int x2),...)$/;\"\tf\ttyperef:typename:unsigned int\tsignature:(int (* f07a01)(int * x1,int x2),...)\tend:64\nf07a01\tinput.cpp\t/^unsigned int f07(int (*f07a01)(int * x1,int x2),...)$/;\"\tz\tfunction:f07\ttyperef:typename:int (*)(int * x1,int x2)\tfile:\nf08\tinput.cpp\t/^void (*f08(void (*)(int *f08a01)))(int *)$/;\"\tf\ttyperef:typename:void (*)(int *)\tsignature:(void (*)(int * f08a01))\tend:69\nf08a01\tinput.cpp\t/^void (*f08(void (*)(int *f08a01)))(int *)$/;\"\tz\tfunction:f08\ttyperef:typename:void (*)(int *)\tfile:\nf09\tinput.cpp\t/^int f09(char *((*f09a01)()))$/;\"\tf\ttyperef:typename:int\tsignature:(char * ((* f09a01)()))\tend:74\nf09a01\tinput.cpp\t/^int f09(char *((*f09a01)()))$/;\"\tz\tfunction:f09\ttyperef:typename:char * ((*)())\tfile:\nf10\tinput.cpp\t/^int f10(int f10a01,int f10a02[],int f10a03[2][3],int (f10a04)[],int (f10a05)[][5])$/;\"\tf\ttyperef:typename:int\tsignature:(int f10a01,int f10a02[],int f10a03[2][3],int (f10a04)[],int (f10a05)[][5])\tend:79\nf10a01\tinput.cpp\t/^int f10(int f10a01,int f10a02[],int f10a03[2][3],int (f10a04)[],int (f10a05)[][5])$/;\"\tz\tfunction:f10\ttyperef:typename:int\tfile:\nf10a02\tinput.cpp\t/^int f10(int f10a01,int f10a02[],int f10a03[2][3],int (f10a04)[],int (f10a05)[][5])$/;\"\tz\tfunction:f10\ttyperef:typename:int[]\tfile:\nf10a03\tinput.cpp\t/^int f10(int f10a01,int f10a02[],int f10a03[2][3],int (f10a04)[],int (f10a05)[][5])$/;\"\tz\tfunction:f10\ttyperef:typename:int[2][3]\tfile:\nf10a04\tinput.cpp\t/^int f10(int f10a01,int f10a02[],int f10a03[2][3],int (f10a04)[],int (f10a05)[][5])$/;\"\tz\tfunction:f10\ttyperef:typename:int ()[]\tfile:\nf10a05\tinput.cpp\t/^int f10(int f10a01,int f10a02[],int f10a03[2][3],int (f10a04)[],int (f10a05)[][5])$/;\"\tz\tfunction:f10\ttyperef:typename:int ()[][5]\tfile:\np01\tinput.cpp\t/^int p01(int p01a01,int p01a02);$/;\"\tp\ttyperef:typename:int\tfile:\tsignature:(int p01a01,int p01a02)\tend:21\np01a01\tinput.cpp\t/^int p01(int p01a01,int p01a02);$/;\"\tz\tprototype:p01\ttyperef:typename:int\tfile:\np01a02\tinput.cpp\t/^int p01(int p01a01,int p01a02);$/;\"\tz\tprototype:p01\ttyperef:typename:int\tfile:\np02\tinput.cpp\t/^unsigned short int * p02(unsigned int & p02a01,...);$/;\"\tp\ttyperef:typename:unsigned short int *\tfile:\tsignature:(unsigned int & p02a01,...)\tend:22\np02a01\tinput.cpp\t/^unsigned short int * p02(unsigned int & p02a01,...);$/;\"\tz\tprototype:p02\ttyperef:typename:unsigned int &\tfile:\np03\tinput.cpp\t/^auto p03(const int & p03a01,void * p03a02) -> const int &;$/;\"\tp\ttyperef:typename:const int &\tfile:\tsignature:(const int & p03a01,void * p03a02)\tend:23\np03a01\tinput.cpp\t/^auto p03(const int & p03a01,void * p03a02) -> const int &;$/;\"\tz\tprototype:p03\ttyperef:typename:const int &\tfile:\np03a02\tinput.cpp\t/^auto p03(const int & p03a01,void * p03a02) -> const int &;$/;\"\tz\tprototype:p03\ttyperef:typename:void *\tfile:\np04\tinput.cpp\t/^auto p04() -> int (*)(int);$/;\"\tp\ttyperef:typename:int (*)(int)\tfile:\tsignature:()\tend:24\np05\tinput.cpp\t/^static std::string p05(const int *** p05a01);$/;\"\tp\ttyperef:typename:std::string\tfile:\tsignature:(const int *** p05a01)\tend:25\np05a01\tinput.cpp\t/^static std::string p05(const int *** p05a01);$/;\"\tz\tprototype:p05\ttyperef:typename:const int ***\tfile:\np06\tinput.cpp\t/^\t\tauto p06(n01::c01 && p06a01) -> type01 *;$/;\"\tp\tnamespace:n01::n02\ttyperef:typename:type01 *\tfile:\tsignature:(n01::c01 && p06a01)\tend:16\np06\tinput.cpp\t/^auto n01::n02::p06(n01::c01 && p06a01) -> n01::n02::type01 *;$/;\"\tp\tclass:n01::n02\ttyperef:typename:n01::n02::type01 *\tfile:\tsignature:(n01::c01 && p06a01)\tend:26\np06a01\tinput.cpp\t/^\t\tauto p06(n01::c01 && p06a01) -> type01 *;$/;\"\tz\tprototype:n01::n02::p06\ttyperef:typename:n01::c01 &&\tfile:\np06a01\tinput.cpp\t/^auto n01::n02::p06(n01::c01 && p06a01) -> n01::n02::type01 *;$/;\"\tz\tprototype:n01::n02::p06\ttyperef:typename:n01::c01 &&\tfile:\np07\tinput.cpp\t/^unsigned int p07(int (*p07a01)(int * x1,int x2),...);$/;\"\tp\ttyperef:typename:unsigned int\tfile:\tsignature:(int (* p07a01)(int * x1,int x2),...)\tend:27\np07a01\tinput.cpp\t/^unsigned int p07(int (*p07a01)(int * x1,int x2),...);$/;\"\tz\tprototype:p07\ttyperef:typename:int (*)(int * x1,int x2)\tfile:\np08\tinput.cpp\t/^void (*p08(void (*)(int *p08a01)))(int *);$/;\"\tp\ttyperef:typename:void (*)(int *)\tfile:\tsignature:(void (*)(int * p08a01))\tend:28\np08a01\tinput.cpp\t/^void (*p08(void (*)(int *p08a01)))(int *);$/;\"\tz\tprototype:p08\ttyperef:typename:void (*)(int *)\tfile:\nt01\tinput.cpp\t/^template <typename T> std::unique_ptr<T> t01(T && t01a01)$/;\"\tf\ttyperef:typename:std::unique_ptr<T>\tsignature:(T && t01a01)\tend:85\nt01a01\tinput.cpp\t/^template <typename T> std::unique_ptr<T> t01(T && t01a01)$/;\"\tz\tfunction:t01\ttyperef:typename:T &&\tfile:\nt02\tinput.cpp\t/^template <typename T> auto t02(T && t02a01) -> std::unique_ptr<T>$/;\"\tf\ttyperef:typename:std::unique_ptr<T>\tsignature:(T && t02a01)\tend:94\nt02a01\tinput.cpp\t/^template <typename T> auto t02(T && t02a01) -> std::unique_ptr<T>$/;\"\tz\tfunction:t02\ttyperef:typename:T &&\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/functions.cpp.d/input.cpp",
    "content": "#include <string>\n#include <memory>\n\nnamespace n01\n{\n\tclass c01\n\t{\n\t};\n\n\tnamespace n02\n\t{\n\t\ttypedef unsigned int type01;\n\n\t\t// These declarations are required by C++ standard for the ones below to compile properly\n\t\tauto f06(n01::c01 && f06a01) -> type01 *;\n\t\tauto p06(n01::c01 && p06a01) -> type01 *;\n\t}\n};\n\n// Valid function prototypes\nint p01(int p01a01,int p01a02);\nunsigned short int * p02(unsigned int & p02a01,...);\nauto p03(const int & p03a01,void * p03a02) -> const int &;\nauto p04() -> int (*)(int);\nstatic std::string p05(const int *** p05a01);\nauto n01::n02::p06(n01::c01 && p06a01) -> n01::n02::type01 *;\nunsigned int p07(int (*p07a01)(int * x1,int x2),...);\nvoid (*p08(void (*)(int *p08a01)))(int *);\n\n// Valid function declarations\nint f01(int f01a01,int f01a02)\n{\n\treturn 0;\n}\n\nunsigned short int * f02(unsigned int & f02a01,...)\n{\n\treturn 0;\n}\n\nauto f03(const int & f03a01,void * f03a02) -> const int &\n{\n\treturn 0;\n}\n\nauto f04() -> int (*)(int)\n{\n\treturn 0;\n}\n\nstatic inline std::string f05(const int *** f05a01)\n{\n\treturn std::string();\n}\n\nauto n01::n02::f06(n01::c01 && f06a01) -> n01::n02::type01 *\n{\n\treturn 0;\n}\n\nunsigned int f07(int (*f07a01)(int * x1,int x2),...)\n{\n\treturn 0;\n}\n\nvoid (*f08(void (*)(int *f08a01)))(int *)\n{\n\treturn 0;\n}\n\nint f09(char *((*f09a01)()))\n{\n\treturn 0;\n}\n\nint f10(int f10a01,int f10a02[],int f10a03[2][3],int (f10a04)[],int (f10a05)[][5])\n{\n\treturn 0;\n}\n\n// Valid function templates\ntemplate <typename T> std::unique_ptr<T> t01(T && t01a01)\n{\n    return std::unique_ptr<T>(NULL);\n}\n\n#define MACRO_TEXT \"\"\n\ntemplate <typename T> auto t02(T && t02a01) -> std::unique_ptr<T>\n{\n\t// throw may look like a prototype, but it isn't\n\tthrow std::string(MACRO_TEXT);\n    return std::unique_ptr<T>(NULL);\n}\n\n// Things that might look similar to function prototypes but are NOT function prototypes (but still valid C++)\nstd::string x01(\"test\");\n\n#if NOTVALIDCPP\n\t// This is not really valid C++ because it appears in the wrong context.\n\t// However we simulate the parser being wrong about the current state (it happens).\n\t// This should be NOT marked as a prototype even if found out of a function.\n\tthrow std::string(MACRO_TEXT);\n#endif\n"
  },
  {
    "path": "Units/parser-cxx.r/ignoring-macro-with-parameters.d/args.ctags",
    "content": "-I _GLIBCXX_VISIBILITY+\n-I _MY_INT=int\n\n"
  },
  {
    "path": "Units/parser-cxx.r/ignoring-macro-with-parameters.d/expected.tags",
    "content": "foo\tinput.hxx\t/^namespace foo _GLIBCXX_VISIBILITY(default)$/;\"\tn\nx\tinput.hxx\t/^  int x;$/;\"\tv\tnamespace:foo\ttyperef:typename:int\ny\tinput.hxx\t/^  _MY_INT y;$/;\"\tv\tnamespace:foo\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/ignoring-macro-with-parameters.d/input.hxx",
    "content": "namespace foo _GLIBCXX_VISIBILITY(default)\n{\n  int x;\n  _MY_INT y;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/README.md",
    "content": "https://en.cppreference.com/w/cpp/language/modules\n\n\texport(optional) import module-name attr ﻿(optional) ; \t(4)\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/args.ctags",
    "content": "--sort=no\n--extras=+rq\n--fields=+r\n--fields-C++=+{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/expected.tags",
    "content": "X\tinput.cpp\t/^import X  [[something]];$/;\"\tM\troles:imported\nimport\tinput.cpp\t/^int import;$/;\"\tv\ttyperef:typename:int\troles:def\nX.Y\tinput-0.cpp\t/^import X.Y [[something]];$/;\"\tM\troles:imported\nX\tinput-2.cpp\t/^export import X  [[something]];$/;\"\tM\troles:imported\tproperties:export\nX.Y\tinput-3.cpp\t/^export import X.Y [[something]];$/;\"\tM\troles:imported\tproperties:export\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/input-0.cpp",
    "content": "import X.Y [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/input-1.cpp",
    "content": "import;\t\t\t\t// broken input\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/input-2.cpp",
    "content": "export import X  [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/input-3.cpp",
    "content": "export import X.Y [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/input-4.cpp",
    "content": "export import;\t\t\t\t// broken input\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/input-5.cpp",
    "content": "import\t\t\t\t// broken input\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/input-6.cpp",
    "content": "export import\n"
  },
  {
    "path": "Units/parser-cxx.r/import-4.d/input.cpp",
    "content": "import X  [[something]];\n\nint import;\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/README.md",
    "content": "https://en.cppreference.com/w/cpp/language/modules\n\n\texport(optional) import module-partition attr ﻿(optional) ; \t(5)\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/args.ctags",
    "content": "--sort=no\n--extras=+rq\n--fields=+r\n--fields-C++=+{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/expected.tags",
    "content": "X\tinput.cpp\t/^import X:P [[something]];$/;\"\tM\troles:partOwner\nP\tinput.cpp\t/^import X:P [[something]];$/;\"\tP\tmodule:X\troles:imported\nX:P\tinput.cpp\t/^import X:P [[something]];$/;\"\tP\tmodule:X\troles:imported\nX.Y\tinput-0.cpp\t/^import X.Y:P [[something]];$/;\"\tM\troles:partOwner\nP\tinput-0.cpp\t/^import X.Y:P [[something]];$/;\"\tP\tmodule:X.Y\troles:imported\nX.Y:P\tinput-0.cpp\t/^import X.Y:P [[something]];$/;\"\tP\tmodule:X.Y\troles:imported\nX\tinput-1.cpp\t/^import X:P.Q [[something]];$/;\"\tM\troles:partOwner\nP.Q\tinput-1.cpp\t/^import X:P.Q [[something]];$/;\"\tP\tmodule:X\troles:imported\nX:P.Q\tinput-1.cpp\t/^import X:P.Q [[something]];$/;\"\tP\tmodule:X\troles:imported\nX.Y\tinput-2.cpp\t/^import X.Y:P.Q [[something]];$/;\"\tM\troles:partOwner\nP.Q\tinput-2.cpp\t/^import X.Y:P.Q [[something]];$/;\"\tP\tmodule:X.Y\troles:imported\nX.Y:P.Q\tinput-2.cpp\t/^import X.Y:P.Q [[something]];$/;\"\tP\tmodule:X.Y\troles:imported\nX\tinput-3.cpp\t/^export import X:P [[something]];$/;\"\tM\troles:partOwner\nP\tinput-3.cpp\t/^export import X:P [[something]];$/;\"\tP\tmodule:X\troles:imported\tproperties:export\nX:P\tinput-3.cpp\t/^export import X:P [[something]];$/;\"\tP\tmodule:X\troles:imported\tproperties:export\nX.Y\tinput-4.cpp\t/^export import X.Y:P [[something]];$/;\"\tM\troles:partOwner\nP\tinput-4.cpp\t/^export import X.Y:P [[something]];$/;\"\tP\tmodule:X.Y\troles:imported\tproperties:export\nX.Y:P\tinput-4.cpp\t/^export import X.Y:P [[something]];$/;\"\tP\tmodule:X.Y\troles:imported\tproperties:export\nX\tinput-5.cpp\t/^export import X:P.Q [[something]];$/;\"\tM\troles:partOwner\nP.Q\tinput-5.cpp\t/^export import X:P.Q [[something]];$/;\"\tP\tmodule:X\troles:imported\tproperties:export\nX:P.Q\tinput-5.cpp\t/^export import X:P.Q [[something]];$/;\"\tP\tmodule:X\troles:imported\tproperties:export\nX\tinput-6.cpp\t/^export import X:P.Q [[something]];$/;\"\tM\troles:partOwner\nP.Q\tinput-6.cpp\t/^export import X:P.Q [[something]];$/;\"\tP\tmodule:X\troles:imported\tproperties:export\nX:P.Q\tinput-6.cpp\t/^export import X:P.Q [[something]];$/;\"\tP\tmodule:X\troles:imported\tproperties:export\nA\tinput-7.cpp\t/^export module A;     \\/\\/ primary module interface unit$/;\"\tM\troles:def\tproperties:export\nB\tinput-7.cpp\t/^export import :B;    \\/\\/ Hello() is visible when importing 'A'.$/;\"\tP\tmodule:A\troles:imported\tproperties:export\nA:B\tinput-7.cpp\t/^export import :B;    \\/\\/ Hello() is visible when importing 'A'.$/;\"\tP\tmodule:A\troles:imported\tproperties:export\nC\tinput-7.cpp\t/^import :C;           \\/\\/ WorldImpl() is now visible only for 'A.cpp'.$/;\"\tP\tmodule:A\troles:imported\nA:C\tinput-7.cpp\t/^import :C;           \\/\\/ WorldImpl() is now visible only for 'A.cpp'.$/;\"\tP\tmodule:A\troles:imported\nWorld\tinput-7.cpp\t/^export char const* World()$/;\"\tf\ttyperef:typename:char const *\troles:def\tproperties:export\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/input-0.cpp",
    "content": "import X.Y:P [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/input-1.cpp",
    "content": "import X:P.Q [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/input-2.cpp",
    "content": "import X.Y:P.Q [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/input-3.cpp",
    "content": "export import X:P [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/input-4.cpp",
    "content": "export import X.Y:P [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/input-5.cpp",
    "content": "export import X:P.Q [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/input-6.cpp",
    "content": "export import X:P.Q [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/input-7.cpp",
    "content": "// Taken from https://en.cppreference.com/w/cpp/language/modules\n\n///////  A.cpp\nexport module A;     // primary module interface unit\n\nexport import :B;    // Hello() is visible when importing 'A'.\nimport :C;           // WorldImpl() is now visible only for 'A.cpp'.\n// export import :C; // ERROR: Cannot export a module implementation unit.\n\n// World() is visible by any translation unit importing 'A'.\nexport char const* World()\n{\n    return WorldImpl();\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/import-5.d/input.cpp",
    "content": "import X:P [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-6.d/README.md",
    "content": "https://en.cppreference.com/w/cpp/language/modules\n\n\texport(optional) import header-name attr ﻿(optional) ; \t(6)\n"
  },
  {
    "path": "Units/parser-cxx.r/import-6.d/args.ctags",
    "content": "--sort=no\n--extras=+rq\n--fields=+r\n--fields-C++=+{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/import-6.d/expected.tags",
    "content": "a.h\tinput.cpp\t/^import <a.h> [[something]];$/;\"\th\troles:system,imported\nb.h\tinput-0.cpp\t/^import \"b.h\" [[something]];$/;\"\th\troles:local,imported\na.h\tinput-1.cpp\t/^export import <a.h> [[something]];$/;\"\th\troles:system,imported,exported\nb.h\tinput-2.cpp\t/^export import \"b.h\" [[something]];$/;\"\th\troles:local,imported,exported\n"
  },
  {
    "path": "Units/parser-cxx.r/import-6.d/input-0.cpp",
    "content": "import \"b.h\" [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-6.d/input-1.cpp",
    "content": "export import <a.h> [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-6.d/input-2.cpp",
    "content": "export import \"b.h\" [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/import-6.d/input.cpp",
    "content": "import <a.h> [[something]];\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/args.ctags",
    "content": "--sort=no\n--langmap=c:.h.c\n--kinds-C++=+lz\n--kinds-C=+lz\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/expected.tags",
    "content": "cs\tinput.h\t/^struct cs {$/;\"\ts\ni\tinput.h\t/^  int i;$/;\"\tm\tstruct:cs\ttyperef:typename:int\nfs\tinput.h\t/^} fs(int x) { struct cs d = {.i = x}; return d;};$/;\"\tf\ttyperef:struct:cs\nx\tinput.h\t/^} fs(int x) { struct cs d = {.i = x}; return d;};$/;\"\tz\tfunction:fs\ttyperef:typename:int\tfile:\nd\tinput.h\t/^} fs(int x) { struct cs d = {.i = x}; return d;};$/;\"\tl\tfunction:fs\ttyperef:struct:cs\tfile:\nce\tinput.h\t/^enum ce {$/;\"\tg\nX\tinput.h\t/^  X,$/;\"\te\tenum:ce\nfe\tinput.h\t/^} fe(void) { return X; }$/;\"\tf\ttyperef:enum:ce\nmain\tinput-0.cpp\t/^int main()$/;\"\tf\ttyperef:typename:int\na0\tinput-0.cpp\t/^  std::vector a0 {1, 2, 30};$/;\"\tl\tfunction:main\ttyperef:typename:std::vector\tfile:\na1\tinput-0.cpp\t/^  std::vector a1 {1};$/;\"\tl\tfunction:main\ttyperef:typename:std::vector\tfile:\na2\tinput-0.cpp\t/^  std::vector a2 = {1, 2, 30};$/;\"\tl\tfunction:main\ttyperef:typename:std::vector\tfile:\na3\tinput-0.cpp\t/^  std::vector a3 = {1};$/;\"\tl\tfunction:main\ttyperef:typename:std::vector\tfile:\na4\tinput-0.cpp\t/^  std::vector a4 = {1}, a5 = {1};$/;\"\tl\tfunction:main\ttyperef:typename:std::vector\tfile:\na5\tinput-0.cpp\t/^  std::vector a4 = {1}, a5 = {1};$/;\"\tl\tfunction:main\ttyperef:typename:std::vector\tfile:\na6\tinput-0.cpp\t/^  std::vector a6 = {1}, a7 {1};$/;\"\tl\tfunction:main\ttyperef:typename:std::vector\tfile:\na7\tinput-0.cpp\t/^  std::vector a6 = {1}, a7 {1};$/;\"\tl\tfunction:main\ttyperef:typename:std::vector\tfile:\na8\tinput-0.cpp\t/^  std::vector a8 {1}, a9 = {1};$/;\"\tl\tfunction:main\ttyperef:typename:std::vector\tfile:\na9\tinput-0.cpp\t/^  std::vector a8 {1}, a9 = {1};$/;\"\tl\tfunction:main\ttyperef:typename:std::vector\tfile:\nb\tinput-1.cpp\t/^int b()$/;\"\tf\ttyperef:typename:int\nb0\tinput-1.cpp\t/^  std::vector b0 {1, 2, 30}, b1 {1};$/;\"\tl\tfunction:b\ttyperef:typename:std::vector\tfile:\nb1\tinput-1.cpp\t/^  std::vector b0 {1, 2, 30}, b1 {1};$/;\"\tl\tfunction:b\ttyperef:typename:std::vector\tfile:\nb2\tinput-1.cpp\t/^  std::vector b2 = {1, 2, 30}, b3 = {1};$/;\"\tl\tfunction:b\ttyperef:typename:std::vector\tfile:\nb3\tinput-1.cpp\t/^  std::vector b2 = {1, 2, 30}, b3 = {1};$/;\"\tl\tfunction:b\ttyperef:typename:std::vector\tfile:\nc\tinput-2.cpp\t/^int c()$/;\"\tf\ttyperef:typename:int\nc0\tinput-2.cpp\t/^  std::vector c0 {1, 2, 30}, c1 {1}, c2 = {1, 2, 30}, c3 = {1};$/;\"\tl\tfunction:c\ttyperef:typename:std::vector\tfile:\nc1\tinput-2.cpp\t/^  std::vector c0 {1, 2, 30}, c1 {1}, c2 = {1, 2, 30}, c3 = {1};$/;\"\tl\tfunction:c\ttyperef:typename:std::vector\tfile:\nc2\tinput-2.cpp\t/^  std::vector c0 {1, 2, 30}, c1 {1}, c2 = {1, 2, 30}, c3 = {1};$/;\"\tl\tfunction:c\ttyperef:typename:std::vector\tfile:\nc3\tinput-2.cpp\t/^  std::vector c0 {1, 2, 30}, c1 {1}, c2 = {1, 2, 30}, c3 = {1};$/;\"\tl\tfunction:c\ttyperef:typename:std::vector\tfile:\nd\tinput-3.cpp\t/^int d()$/;\"\tf\ttyperef:typename:int\nD\tinput-3.cpp\t/^  class D {$/;\"\tc\tfunction:d\tfile:\ni\tinput-3.cpp\t/^    int i;$/;\"\tm\tclass:d::D\ttyperef:typename:int\tfile:\nD\tinput-3.cpp\t/^    D( int j,...):i(j){}$/;\"\tf\tclass:d::D\tfile:\nj\tinput-3.cpp\t/^    D( int j,...):i(j){}$/;\"\tz\tfunction:d::D::D\ttyperef:typename:int\tfile:\nf\tinput-3.cpp\t/^    int f(){ return i; }$/;\"\tf\tclass:d::D\ttyperef:typename:int\tfile:\ndx\tinput-3.cpp\t/^  } dx{1};$/;\"\tl\tfunction:d\ttyperef:class:d::D\tfile:\nE\tinput-3.cpp\t/^  class E {$/;\"\tc\tfunction:d\tfile:\nj\tinput-3.cpp\t/^    int j;$/;\"\tm\tclass:d::E\ttyperef:typename:int\tfile:\nE\tinput-3.cpp\t/^    E( int k,...):j(k){}$/;\"\tf\tclass:d::E\tfile:\nk\tinput-3.cpp\t/^    E( int k,...):j(k){}$/;\"\tz\tfunction:d::E::E\ttyperef:typename:int\tfile:\nf\tinput-3.cpp\t/^    int f(){ return j; }$/;\"\tf\tclass:d::E\ttyperef:typename:int\tfile:\ne0\tinput-3.cpp\t/^  } e0 {1, 2, 30}, e1 {1}, e2 = {1, 2, 30}, e3 = {1};$/;\"\tl\tfunction:d\ttyperef:class:d::E\tfile:\ne1\tinput-3.cpp\t/^  } e0 {1, 2, 30}, e1 {1}, e2 = {1, 2, 30}, e3 = {1};$/;\"\tl\tfunction:d\ttyperef:class:d::E\tfile:\ne2\tinput-3.cpp\t/^  } e0 {1, 2, 30}, e1 {1}, e2 = {1, 2, 30}, e3 = {1};$/;\"\tl\tfunction:d\ttyperef:class:d::E\tfile:\ne3\tinput-3.cpp\t/^  } e0 {1, 2, 30}, e1 {1}, e2 = {1, 2, 30}, e3 = {1};$/;\"\tl\tfunction:d\ttyperef:class:d::E\tfile:\nc\tinput-4.cpp\t/^enum c {$/;\"\tg\tfile:\nX\tinput-4.cpp\t/^  X, Y$/;\"\te\tenum:c\tfile:\nY\tinput-4.cpp\t/^  X, Y$/;\"\te\tenum:c\tfile:\nc0\tinput-4.cpp\t/^} c0{X}, c1{Y};$/;\"\tv\ttyperef:enum:c\nc1\tinput-4.cpp\t/^} c0{X}, c1{Y};$/;\"\tv\ttyperef:enum:c\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/input-0.cpp",
    "content": "#include <vector>\nint main()\n{\n  std::vector a0 {1, 2, 30};\n  std::vector a1 {1};\n  std::vector a2 = {1, 2, 30};\n  std::vector a3 = {1};\n  std::vector a4 = {1}, a5 = {1};\n  std::vector a6 = {1}, a7 {1};\n  std::vector a8 {1}, a9 = {1};\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/input-1.cpp",
    "content": "#include <vector>\nint b()\n{\n  std::vector b0 {1, 2, 30}, b1 {1};\n  std::vector b2 = {1, 2, 30}, b3 = {1};\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/input-2.cpp",
    "content": "#include <vector>\nint c()\n{\n  std::vector c0 {1, 2, 30}, c1 {1}, c2 = {1, 2, 30}, c3 = {1};\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/input-3.cpp",
    "content": "int d()\n{\n  class D {\n    int i;\n  public:\n    D( int j,...):i(j){}\n    int f(){ return i; }\n  } dx{1};\n\n  class E {\n    int j;\n  public:\n    E( int k,...):j(k){}\n    int f(){ return j; }\n  } e0 {1, 2, 30}, e1 {1}, e2 = {1, 2, 30}, e3 = {1};\n\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/input-4.cpp",
    "content": "enum c {\n  X, Y\n} c0{X}, c1{Y};\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/input.h",
    "content": "struct cs {\n  int i;\n} fs(int x) { struct cs d = {.i = x}; return d;};\n\nenum ce {\n  X,\n} fe(void) { return X; }\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/validator",
    "content": "c\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/validator-0",
    "content": "cxx17\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/validator-1",
    "content": "cxx17\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/validator-2",
    "content": "cxx17\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/validator-3",
    "content": "cxx11\n"
  },
  {
    "path": "Units/parser-cxx.r/initializer-list.d/validator-4",
    "content": "cxx11\n"
  },
  {
    "path": "Units/parser-cxx.r/inline-variables.cpp.d/args.ctags",
    "content": "--kinds-c++=vm\n--fields-c++=+{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/inline-variables.cpp.d/expected.tags",
    "content": "gv1\tinput.cpp\t/^static inline int gv1;$/;\"\tv\ttyperef:typename:int\tfile:\tproperties:inline,static\ngv2\tinput.cpp\t/^inline int gv2;$/;\"\tv\ttyperef:typename:int\tproperties:inline\nvar1\tinput.cpp\t/^\tstatic inline int var1;$/;\"\tm\tclass:C1\ttyperef:typename:int\tfile:\tproperties:inline,static\nvar2\tinput.cpp\t/^\tinline int var2;$/;\"\tm\tclass:C1\ttyperef:typename:int\tfile:\tproperties:inline\n"
  },
  {
    "path": "Units/parser-cxx.r/inline-variables.cpp.d/input.cpp",
    "content": "class C1\n{\npublic:\n\tstatic inline int var1;\n\tinline int var2;\n\t\n\tinline void fn(){};\n};\n\nstatic inline int gv1;\ninline int gv2;\n\n"
  },
  {
    "path": "Units/parser-cxx.r/instantiation.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/instantiation.d/expected.tags",
    "content": "X\tinput.hpp\t/^template <class T> struct X { };$/;\"\ts\nY\tinput.hpp\t/^template <int N> struct Y { };$/;\"\ts\nM\tinput.hpp\t/^#define M /;\"\td\nS\tinput.hpp\t/^struct S {$/;\"\ts\ni\tinput.hpp\t/^\tint i;$/;\"\tm\tstruct:S\ttyperef:typename:int\ny\tinput.hpp\t/^\tY<0> y;$/;\"\tm\tstruct:S\ttyperef:typename:Y<0>\nx0\tinput.hpp\t/^\tX< Y< 1 > > x0;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<1>>\nx1\tinput.hpp\t/^\tX< Y< 1 + 2 > > x1;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<1+2>>\nx2\tinput.hpp\t/^\tX< Y< 1 << 2 > > x2;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<1<<2>>\nx3\tinput.hpp\t/^\tX< Y< M << 2 > > x3;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<M<<2>>\nx4\tinput.hpp\t/^\tX< Y< M << M > > x4;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<M<<M>>\nd\tinput.hpp\t/^\tdouble d;$/;\"\tm\tstruct:S\ttyperef:typename:double\n"
  },
  {
    "path": "Units/parser-cxx.r/instantiation.d/input.hpp",
    "content": "// Based on an example in https://cpplover.blogspot.com/2013/12/c03c11_3905.html (in Japanese)\n\ntemplate <class T> struct X { };\ntemplate <int N> struct Y { };\n#define M 2\nstruct S {\n\tint i;\n\tY<0> y;\n\tX< Y< 1 > > x0;\n\tX< Y< 1 + 2 > > x1;\n\tX< Y< 1 << 2 > > x2;\n\tX< Y< M << 2 > > x3;\n\tX< Y< M << M > > x4;\n\tdouble d;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/instantiation.d/validator",
    "content": "cxx11\n"
  },
  {
    "path": "Units/parser-cxx.r/instantiation2.b/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/instantiation2.b/expected.tags",
    "content": "X\tinput.hpp\t/^template <class T> struct X { };$/;\"\ts\nY\tinput.hpp\t/^template <int N> struct Y { };$/;\"\ts\nM\tinput.hpp\t/^#define M /;\"\td\nS\tinput.hpp\t/^struct S {$/;\"\ts\ni\tinput.hpp\t/^\tint i;$/;\"\tm\tstruct:S\ttyperef:typename:int\nx2\tinput.hpp\t/^\tX< Y< 1 >> 2 > > x2;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<1>>2>>\nx3\tinput.hpp\t/^\tX< Y< M >> 2 > > x3;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<M>>2>>\nx4\tinput.hpp\t/^\tX< Y< M >> M > > x4;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<M>>M>>\nx5\tinput.hpp\t/^\tX< Y< 1 < 2 > > x5;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<1<2>>\nx6\tinput.hpp\t/^\tX< Y< M < 2 > > x6;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<M<2>>\nx7\tinput.hpp\t/^\tX< Y< M < M > > x7;$/;\"\tm\tstruct:S\ttyperef:typename:X<Y<M<M>>\nd\tinput.hpp\t/^\tdouble d;$/;\"\tm\tstruct:S\ttyperef:typename:double\n"
  },
  {
    "path": "Units/parser-cxx.r/instantiation2.b/input.hpp",
    "content": "// Based on an example in https://cpplover.blogspot.com/2013/12/c03c11_3905.html (in Japanese)\n// A C++03 compiler accept this input but a C++11 compiler does not.\ntemplate <class T> struct X { };\ntemplate <int N> struct Y { };\n#define M 2\nstruct S {\n\tint i;\n\tX< Y< 1 >> 2 > > x2;\n\tX< Y< M >> 2 > > x3;\n\tX< Y< M >> M > > x4;\n\tX< Y< 1 < 2 > > x5;\n\tX< Y< M < 2 > > x6;\n\tX< Y< M < M > > x7;\n  /*    Too ambiguous even in C++03\n\t---------------------------\n\tX< Y< 1 > 2 > > x8;\n\tX< Y< M > 2 > > x9;\n\tX< Y< M > M > > xa;\t*/\n\tdouble d;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/instantiation2.b/validator",
    "content": "cxx03\n"
  },
  {
    "path": "Units/parser-cxx.r/iostream.d/args.ctags",
    "content": "--kinds-c++=+l\n"
  },
  {
    "path": "Units/parser-cxx.r/iostream.d/expected.tags",
    "content": "foo\tinput.cpp\t/^void foo (int &x, int y, int z)$/;\"\tf\ttyperef:typename:void\n"
  },
  {
    "path": "Units/parser-cxx.r/iostream.d/input.cpp",
    "content": "#include <iostream>\nvoid foo (int &x, int y, int z)\n{\n\tstd::cin >> x;\n\tstd::cout << y;\n\tstd::cout << z << endl;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/k-and-r.d/args.ctags",
    "content": "--kinds-c=*\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/k-and-r.d/expected.tags",
    "content": "f00\tinput.c\t/^void f00(a00) int  a00; {}$/;\"\tf\na00\tinput.c\t/^void f00(a00) int  a00; {}$/;\"\tz\tfunction:f00\ttyperef:typename:int\tfile:\nf01\tinput.c\t/^void f01(a01) int *a01; {}$/;\"\tf\na01\tinput.c\t/^void f01(a01) int *a01; {}$/;\"\tz\tfunction:f01\ttyperef:typename:int *\tfile:\nf10\tinput.c\t/^void f10(a10) struct file *a10; {}$/;\"\tf\na10\tinput.c\t/^void f10(a10) struct file *a10; {}$/;\"\tz\tfunction:f10\ttyperef:struct:file *\tfile:\nf11\tinput.c\t/^void f11(a11, a12) struct file *a11; int a12; {}$/;\"\tf\na11\tinput.c\t/^void f11(a11, a12) struct file *a11; int a12; {}$/;\"\tz\tfunction:f11\ttyperef:struct:file *\tfile:\na12\tinput.c\t/^void f11(a11, a12) struct file *a11; int a12; {}$/;\"\tz\tfunction:f11\ttyperef:typename:int\tfile:\nf12\tinput.c\t/^void f12(a13, a14) int a13; struct file *a14; {}$/;\"\tf\na13\tinput.c\t/^void f12(a13, a14) int a13; struct file *a14; {}$/;\"\tz\tfunction:f12\ttyperef:typename:int\tfile:\na14\tinput.c\t/^void f12(a13, a14) int a13; struct file *a14; {}$/;\"\tz\tfunction:f12\ttyperef:struct:file *\tfile:\nf13\tinput.c\t/^void f13(a15) register struct file *a15; {}$/;\"\tf\na15\tinput.c\t/^void f13(a15) register struct file *a15; {}$/;\"\tz\tfunction:f13\ttyperef:typename:register struct file *\tfile:\nf14\tinput.c\t/^void f14(a16, a17) register struct file *a16; int a17; {}$/;\"\tf\na16\tinput.c\t/^void f14(a16, a17) register struct file *a16; int a17; {}$/;\"\tz\tfunction:f14\ttyperef:typename:register struct file *\tfile:\na17\tinput.c\t/^void f14(a16, a17) register struct file *a16; int a17; {}$/;\"\tz\tfunction:f14\ttyperef:typename:int\tfile:\nf15\tinput.c\t/^void f15(a18, a19) register int a18; struct file *a19; {}$/;\"\tf\na18\tinput.c\t/^void f15(a18, a19) register int a18; struct file *a19; {}$/;\"\tz\tfunction:f15\ttyperef:typename:register int\tfile:\na19\tinput.c\t/^void f15(a18, a19) register int a18; struct file *a19; {}$/;\"\tz\tfunction:f15\ttyperef:struct:file *\tfile:\nf16\tinput.c\t/^void f16(a19_1) const struct file *a19_1; {}$/;\"\tf\na19_1\tinput.c\t/^void f16(a19_1) const struct file *a19_1; {}$/;\"\tz\tfunction:f16\ttyperef:typename:const struct file *\tfile:\nf17\tinput.c\t/^void f17(a19_2, a19_3) const struct file *a19_2; int a19_3; {}$/;\"\tf\na19_2\tinput.c\t/^void f17(a19_2, a19_3) const struct file *a19_2; int a19_3; {}$/;\"\tz\tfunction:f17\ttyperef:typename:const struct file *\tfile:\na19_3\tinput.c\t/^void f17(a19_2, a19_3) const struct file *a19_2; int a19_3; {}$/;\"\tz\tfunction:f17\ttyperef:typename:int\tfile:\nf18\tinput.c\t/^void f18(a19_4, a19_5) const int a19_4; struct file *a19_5; {}$/;\"\tf\na19_4\tinput.c\t/^void f18(a19_4, a19_5) const int a19_4; struct file *a19_5; {}$/;\"\tz\tfunction:f18\ttyperef:typename:const int\tfile:\na19_5\tinput.c\t/^void f18(a19_4, a19_5) const int a19_4; struct file *a19_5; {}$/;\"\tz\tfunction:f18\ttyperef:struct:file *\tfile:\nf20\tinput.c\t/^void f20(a20) union file *a20; {}$/;\"\tf\na20\tinput.c\t/^void f20(a20) union file *a20; {}$/;\"\tz\tfunction:f20\ttyperef:union:file *\tfile:\nf21\tinput.c\t/^void f21(a21, a22) union file *a21; int a22; {}$/;\"\tf\na21\tinput.c\t/^void f21(a21, a22) union file *a21; int a22; {}$/;\"\tz\tfunction:f21\ttyperef:union:file *\tfile:\na22\tinput.c\t/^void f21(a21, a22) union file *a21; int a22; {}$/;\"\tz\tfunction:f21\ttyperef:typename:int\tfile:\nf22\tinput.c\t/^void f22(a23, a24) int a23; union file *a24; {}$/;\"\tf\na23\tinput.c\t/^void f22(a23, a24) int a23; union file *a24; {}$/;\"\tz\tfunction:f22\ttyperef:typename:int\tfile:\na24\tinput.c\t/^void f22(a23, a24) int a23; union file *a24; {}$/;\"\tz\tfunction:f22\ttyperef:union:file *\tfile:\nf30\tinput.c\t/^void f30(a30) enum file *a30; {}$/;\"\tf\na30\tinput.c\t/^void f30(a30) enum file *a30; {}$/;\"\tz\tfunction:f30\ttyperef:enum:file *\tfile:\nf31\tinput.c\t/^void f31(a31, a32) enum file *a31; int a32; {}$/;\"\tf\na31\tinput.c\t/^void f31(a31, a32) enum file *a31; int a32; {}$/;\"\tz\tfunction:f31\ttyperef:enum:file *\tfile:\na32\tinput.c\t/^void f31(a31, a32) enum file *a31; int a32; {}$/;\"\tz\tfunction:f31\ttyperef:typename:int\tfile:\nf32\tinput.c\t/^void f32(a33, a34) int a33; enum file *a34; {}$/;\"\tf\na33\tinput.c\t/^void f32(a33, a34) int a33; enum file *a34; {}$/;\"\tz\tfunction:f32\ttyperef:typename:int\tfile:\na34\tinput.c\t/^void f32(a33, a34) int a33; enum file *a34; {}$/;\"\tz\tfunction:f32\ttyperef:enum:file *\tfile:\nf40\tinput.c\t/^void f40 (a41, a42, a43) struct file a41;  union file a42; enum file a43; {}$/;\"\tf\na41\tinput.c\t/^void f40 (a41, a42, a43) struct file a41;  union file a42; enum file a43; {}$/;\"\tz\tfunction:f40\ttyperef:struct:file\tfile:\na42\tinput.c\t/^void f40 (a41, a42, a43) struct file a41;  union file a42; enum file a43; {}$/;\"\tz\tfunction:f40\ttyperef:union:file\tfile:\na43\tinput.c\t/^void f40 (a41, a42, a43) struct file a41;  union file a42; enum file a43; {}$/;\"\tz\tfunction:f40\ttyperef:enum:file\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/k-and-r.d/input.c",
    "content": "void f00(a00) int  a00; {}\nvoid f01(a01) int *a01; {}\n\n/* struct */\nvoid f10(a10) struct file *a10; {}\nvoid f11(a11, a12) struct file *a11; int a12; {}\nvoid f12(a13, a14) int a13; struct file *a14; {}\n\nvoid f13(a15) register struct file *a15; {}\nvoid f14(a16, a17) register struct file *a16; int a17; {}\nvoid f15(a18, a19) register int a18; struct file *a19; {}\n\nvoid f16(a19_1) const struct file *a19_1; {}\nvoid f17(a19_2, a19_3) const struct file *a19_2; int a19_3; {}\nvoid f18(a19_4, a19_5) const int a19_4; struct file *a19_5; {}\n\n/* union */\nvoid f20(a20) union file *a20; {}\nvoid f21(a21, a22) union file *a21; int a22; {}\nvoid f22(a23, a24) int a23; union file *a24; {}\n\n/* enum */\nvoid f30(a30) enum file *a30; {}\nvoid f31(a31, a32) enum file *a31; int a32; {}\nvoid f32(a33, a34) int a33; enum file *a34; {}\n\n/* struct union enum */\nvoid f40 (a41, a42, a43) struct file a41;  union file a42; enum file a43; {}\n"
  },
  {
    "path": "Units/parser-cxx.r/keyword-in-return-type.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=+p\n"
  },
  {
    "path": "Units/parser-cxx.r/keyword-in-return-type.d/expected.tags",
    "content": "a\tinput.cc\t/^struct Class0 * a();$/;\"\tp\ttyperef:struct:Class0 *\tfile:\nb\tinput.cc\t/^struct Class0 * b() { exit(0); }$/;\"\tf\ttyperef:struct:Class0 *\nc\tinput.cc\t/^class Class1 * c();$/;\"\tp\ttyperef:class:Class1 *\tfile:\nd\tinput.cc\t/^class Class1 * d() { exit(0); }$/;\"\tf\ttyperef:class:Class1 *\ne\tinput.cc\t/^union Class1 * e();$/;\"\tp\ttyperef:union:Class1 *\tfile:\nf\tinput.cc\t/^union Class1 * f() { exit(0); }$/;\"\tf\ttyperef:union:Class1 *\n"
  },
  {
    "path": "Units/parser-cxx.r/keyword-in-return-type.d/input.cc",
    "content": "struct Class0 * a();\nstruct Class0 * b() { exit(0); }\n\nclass Class1 * c();\nclass Class1 * d() { exit(0); }\n\nunion Class1 * e();\nunion Class1 * f() { exit(0); }\n"
  },
  {
    "path": "Units/parser-cxx.r/less-than-operator-between-anglebrackets.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/less-than-operator-between-anglebrackets.d/expected.tags",
    "content": "f0\tinput.cpp\t/^template<char i, bool B = (i>0)>     void f0(void) { }$/;\"\tf\ttyperef:typename:void\nf1\tinput.cpp\t/^template<char i, bool B = i < 10>    void f1(void) { }$/;\"\tf\ttyperef:typename:void\nf2\tinput.cpp\t/^template<char i, long j = (i << 10)> void f2(void) { }$/;\"\tf\ttyperef:typename:void\nf3\tinput.cpp\t/^template<char i, long j = i << 10>   void f3(void) { }$/;\"\tf\ttyperef:typename:void\nf4\tinput.cpp\t/^template<char i, long j = (i >> 10)> void f4(void) { }$/;\"\tf\ttyperef:typename:void\nf5\tinput.cpp\t/^template<char i, long j = (i > 10)>  void f5(void) { }$/;\"\tf\ttyperef:typename:void\nf6\tinput.cpp\t/^template<char i, bool B = (i <= 10)> void f6(void) { }$/;\"\tf\ttyperef:typename:void\nf7\tinput.cpp\t/^template<char i, bool B = (i >= 10)> void f7(void) { }$/;\"\tf\ttyperef:typename:void\nf8\tinput.cpp\t/^template<char i, char j, bool B = i < 10 && (30 > j)> void f8(void) { }$/;\"\tf\ttyperef:typename:void\nf9\tinput.cpp\t/^template<char i, char j, bool B = i < (10 && 30 > j)> void f9(void) { }$/;\"\tf\ttyperef:typename:void\nf10\tinput.cpp\t/^template<char i, char j, bool B = (i < 10 && 30 > j)> void f10(void) { }$/;\"\tf\ttyperef:typename:void\nf11\tinput.cpp\t/^template<bool b = 0 < 2 && 2 < 4> void f11(void) { }$/;\"\tf\ttyperef:typename:void\nmain\tinput.cpp\t/^int main(void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/less-than-operator-between-anglebrackets.d/input.cpp",
    "content": "/* \"gcc input.cpp -c -std=c++11\" accepts this source code. */\n\ntemplate<char i, bool B = (i>0)>     void f0(void) { }\ntemplate<char i, bool B = i < 10>    void f1(void) { }\ntemplate<char i, long j = (i << 10)> void f2(void) { }\ntemplate<char i, long j = i << 10>   void f3(void) { }\ntemplate<char i, long j = (i >> 10)> void f4(void) { }\ntemplate<char i, long j = (i > 10)>  void f5(void) { }\ntemplate<char i, bool B = (i <= 10)> void f6(void) { }\ntemplate<char i, bool B = (i >= 10)> void f7(void) { }\ntemplate<char i, char j, bool B = i < 10 && (30 > j)> void f8(void) { }\ntemplate<char i, char j, bool B = i < (10 && 30 > j)> void f9(void) { }\ntemplate<char i, char j, bool B = (i < 10 && 30 > j)> void f10(void) { }\ntemplate<bool b = 0 < 2 && 2 < 4> void f11(void) { }\ntemplate<typename T1, typename T2> class A;\nint main(void) { return 0; }\n"
  },
  {
    "path": "Units/parser-cxx.r/member-with-initial-value.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/member-with-initial-value.d/expected.tags",
    "content": "__anon0afffb470108\tinput.cc\t/^typedef struct {$/;\"\ts\tfile:\ni\tinput.cc\t/^  int i;$/;\"\tm\tstruct:__anon0afffb470108\ttyperef:typename:int\tfile:\nS\tinput.cc\t/^} S;$/;\"\tt\ttyperef:struct:__anon0afffb470108\tfile:\nc\tinput.cc\t/^class c {$/;\"\tc\tfile:\na\tinput.cc\t/^  S a = {0};$/;\"\tm\tclass:c\ttyperef:typename:S\tfile:\ni\tinput.cc\t/^  int i;$/;\"\tm\tclass:c\ttyperef:typename:int\tfile:\nt\tinput.cc\t/^struct t {$/;\"\ts\tfile:\nb\tinput.cc\t/^  S b = {0};$/;\"\tm\tstruct:t\ttyperef:typename:S\tfile:\nj\tinput.cc\t/^  int j;$/;\"\tm\tstruct:t\ttyperef:typename:int\tfile:\nu\tinput.cc\t/^union u {$/;\"\tu\tfile:\nc\tinput.cc\t/^  S c = {0};$/;\"\tm\tunion:u\ttyperef:typename:S\tfile:\nk\tinput.cc\t/^  int k;$/;\"\tm\tunion:u\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/member-with-initial-value.d/input.cc",
    "content": "typedef struct {\n  int i;\n} S;\n\nclass c {\n  S a = {0};\n  int i;\n};\n\nstruct t {\n  S b = {0};\n  int j;\n};\n\nunion u {\n  S c = {0};\n  int k;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/args.ctags",
    "content": "--sort=no\n--fields=+{typeref}\n--fields-C++=+{properties}\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/expected.tags",
    "content": "A\tinput.cpp\t/^export module A;   \\/\\/ declares the primary module interface unit for named module 'A'$/;\"\tM\troles:def\tproperties:export\nA\tinput-0.cpp\t/^module A;          \\/\\/ declares a module implementation unit for named module 'A'$/;\"\tM\troles:def\nA.B\tinput-1.cpp\t/^export module A.B; \\/\\/ declares the primary module interface unit for named module 'A.B'$/;\"\tM\troles:def\tproperties:export\nA.B\tinput-2.cpp\t/^module A.B;        \\/\\/ declares a module implementation unit for named module 'A.B'$/;\"\tM\troles:def\nmodule\tinput-3.cpp\t/^int module;$/;\"\tv\ttyperef:typename:int\troles:def\nmoudle\tinput-4.cpp\t/^void moudle (void)$/;\"\tf\ttyperef:typename:void\troles:def\nmodule\tinput-5.cpp\t/^typedef int module;$/;\"\tt\ttyperef:typename:int\tfile:\troles:def\nM\tinput-5.cpp\t/^typedef module M;$/;\"\tt\ttyperef:typename:module\tfile:\troles:def\nmodule\tinput-6.cpp\t/^struct module$/;\"\ts\tfile:\troles:def\nname\tinput-6.cpp\t/^  const char *name;$/;\"\tm\tstruct:module\ttyperef:typename:const char *\tfile:\troles:def\nC\tinput-7.cpp\t/^export module C;$/;\"\tM\troles:def\tproperties:export\nmoudle\tinput-7.cpp\t/^void moudle(T x)$/;\"\tf\ttyperef:typename:void\troles:def\tproperties:export\nMy.App.ConfigModule\tinput-8.cpp\t/^export module My.App . ConfigModule  [[cats::meow(-1,8, \"de\"[1])]] ;$/;\"\tM\troles:def\tproperties:export\nMy.App.AlgoModule\tinput-9.cpp\t/^module My.App . AlgoModule  [[cats::meow(-1,8, \"de\"[1])]] ;$/;\"\tM\troles:def\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input-0.cpp",
    "content": "module A;          // declares a module implementation unit for named module 'A'\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input-1.cpp",
    "content": "export module A.B; // declares the primary module interface unit for named module 'A.B'\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input-2.cpp",
    "content": "module A.B;        // declares a module implementation unit for named module 'A.B'\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input-3.cpp",
    "content": "int module;\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input-4.cpp",
    "content": "void moudle (void)\n{\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input-5.cpp",
    "content": "typedef int module;\ntypedef module M;\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input-6.cpp",
    "content": "struct module\n{\n  const char *name;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input-7.cpp",
    "content": "export module C;\n\nexport template<typename T>\nvoid moudle(T x)\n{\n  return;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input-8.cpp",
    "content": "// Taken from a comment in https://github.com/universal-ctags/ctags/issues/3932 submitted by @terminatorul\nexport module My.App . ConfigModule  [[cats::meow(-1,8, \"de\"[1])]] ;\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input-9.cpp",
    "content": "// Derived from a comment in https://github.com/universal-ctags/ctags/issues/3932 submitted by @terminatorul\nmodule My.App . AlgoModule  [[cats::meow(-1,8, \"de\"[1])]] ;\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/input.cpp",
    "content": "export module A;   // declares the primary module interface unit for named module 'A'\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/validator",
    "content": "cxx20+module\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/validator-0",
    "content": "NONE\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/validator-2",
    "content": "NONE\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/validator-8",
    "content": "NONE\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-1.d/validator-9",
    "content": "NONE\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-8.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--fields-C++=+{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-8.d/expected.tags",
    "content": "__gmod_a88571800116\tinput.cpp\t/^module;$/;\"\tM\nA\tinput.cpp\t/^export module A;$/;\"\tM\tproperties:export\nprivate\tinput.cpp\t/^module :private;$/;\"\tP\tmodule:A\nA:private\tinput.cpp\t/^module :private;$/;\"\tP\tmodule:A\n__gmod_d9936dbd0116\tinput-0.cpp\t/^module;$/;\"\tM\nB\tinput-0.cpp\t/^export module B;$/;\"\tM\tproperties:export\nprivate\tinput-0.cpp\t/^module :private;$/;\"\tP\tmodule:B\nB:private\tinput-0.cpp\t/^module :private;$/;\"\tP\tmodule:B\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-8.d/input-0.cpp",
    "content": "module;\n\nexport module B;\n\nmodule :private;\n"
  },
  {
    "path": "Units/parser-cxx.r/modules-8.d/input.cpp",
    "content": "module;\n\nexport module A;\n\nmodule :private;\n"
  },
  {
    "path": "Units/parser-cxx.r/more-decltypes.d/args.ctags",
    "content": "--sort=no\n--fields-C++={properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/more-decltypes.d/expected.tags",
    "content": "a\tinput.cxx\t/^int a;$/;\"\tv\ttyperef:typename:int\nb\tinput.cxx\t/^decltype(a) b;$/;\"\tv\ttyperef:typename:decltype(a)\nc\tinput.cxx\t/^typeof(a) c;$/;\"\tv\ttyperef:typename:typeof(a)\nd\tinput.cxx\t/^__typeof__(a) d;$/;\"\tv\ttyperef:typename:__typeof__(a)\nd0\tinput.cxx\t/^__typeof(a) d0;$/;\"\tv\ttyperef:typename:__typeof(a)\ne\tinput.cxx\t/^decltype(a) const e = 1;$/;\"\tv\ttyperef:typename:decltype(a) const\nf\tinput.cxx\t/^typeof(a) const f = 2;$/;\"\tv\ttyperef:typename:typeof(a) const\ng\tinput.cxx\t/^__typeof__(a) const g = 3;$/;\"\tv\ttyperef:typename:__typeof__(a) const\ng0\tinput.cxx\t/^__typeof(a) const g0 = 3;$/;\"\tv\ttyperef:typename:__typeof(a) const\nh\tinput.cxx\t/^static decltype(a) const h = 4;$/;\"\tv\ttyperef:typename:decltype(a) const\tfile:\tproperties:static\ni\tinput.cxx\t/^static typeof(a) const i = 5;$/;\"\tv\ttyperef:typename:typeof(a) const\tfile:\tproperties:static\nj\tinput.cxx\t/^static __typeof__(a) const j = 6;$/;\"\tv\ttyperef:typename:__typeof__(a) const\tfile:\tproperties:static\nj0\tinput.cxx\t/^static __typeof(a) const j0 = 6;$/;\"\tv\ttyperef:typename:__typeof(a) const\tfile:\tproperties:static\nk\tinput.cxx\t/^static const decltype(a) k = 7;$/;\"\tv\ttyperef:typename:const decltype(a)\tfile:\tproperties:static\nl\tinput.cxx\t/^static const typeof(a) l = 8;$/;\"\tv\ttyperef:typename:const typeof(a)\tfile:\tproperties:static\nm\tinput.cxx\t/^static const __typeof__(a) m = 9;$/;\"\tv\ttyperef:typename:const __typeof__(a)\tfile:\tproperties:static\nm0\tinput.cxx\t/^static const __typeof(a) m0 = 10;$/;\"\tv\ttyperef:typename:const __typeof(a)\tfile:\tproperties:static\n"
  },
  {
    "path": "Units/parser-cxx.r/more-decltypes.d/input.cxx",
    "content": "int a;\n\ndecltype(a) b;\ntypeof(a) c;\n__typeof__(a) d;\n__typeof(a) d0;\n\ndecltype(a) const e = 1;\ntypeof(a) const f = 2;\n__typeof__(a) const g = 3;\n__typeof(a) const g0 = 3;\n\nstatic decltype(a) const h = 4;\nstatic typeof(a) const i = 5;\nstatic __typeof__(a) const j = 6;\nstatic __typeof(a) const j0 = 6;\n\nstatic const decltype(a) k = 7;\nstatic const typeof(a) l = 8;\nstatic const __typeof__(a) m = 9;\nstatic const __typeof(a) m0 = 10;\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace-alias-in-function.d/args.ctags",
    "content": "--kinds-C++=+A\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace-alias-in-function.d/expected.tags",
    "content": "ABC\tinput.cpp\t/^namespace ABC {$/;\"\tn\tfile:\nX\tinput.cpp\t/^  namespace X = ABC;$/;\"\tA\tfunction:foo\tfile:\tname:ABC\nfoo\tinput.cpp\t/^int foo (void)$/;\"\tf\ttyperef:typename:int\nx\tinput.cpp\t/^  int x = 1;$/;\"\tv\tnamespace:ABC\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace-alias-in-function.d/input.cpp",
    "content": "namespace ABC {\n  int x = 1;\n}\n\nint foo (void)\n{\n  namespace X = ABC;\n  return X::x;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace-and-preprocessor.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*"
  },
  {
    "path": "Units/parser-cxx.r/namespace-and-preprocessor.cpp.d/expected.tags",
    "content": "Name\tinput.cpp\t/^\tName {$/;\"\tn\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace-and-preprocessor.cpp.d/input.cpp",
    "content": "#ifdef SOMETHING\n\tnamespace\n#else\n\tclass\n#endif\n\tName {\n\t};\n\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace-and-scope.b/args.ctags",
    "content": "--kinds-C++=*\n--fields=+K\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace-and-scope.b/expected.tags",
    "content": "X\tinput.cpp\t/^namespace X {$/;\"\tnamespace\tfile:\nf\tinput.cpp\t/^\tvoid f (void);$/;\"\tprototype\tnamespace:X\tfile:\nf\tinput.cpp\t/^void X::f (void) {}$/;\"\tfunction\tnamespace:X\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace-and-scope.b/input.cpp",
    "content": "namespace X {\n\tvoid f (void);\n};\nvoid X::f (void) {}\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace.cpp.d/args.ctags",
    "content": "--sort=no\n--fields=+e\n--fields-c++=+{properties}\n--kinds-c++=+A\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace.cpp.d/expected.tags",
    "content": "__anon396601200111\tinput.cpp\t/^namespace {$/;\"\tn\tfile:\tend:8\nanon_f\tinput.cpp\t/^\tvoid anon_f() { };$/;\"\tf\tnamespace:__anon396601200111\ttyperef:typename:void\tend:3\n__anon396601200211\tinput.cpp\t/^\tnamespace {$/;\"\tn\tnamespace:__anon396601200111\tfile:\tend:7\nanon_anon_f\tinput.cpp\t/^\t\tvoid anon_anon_f() { };$/;\"\tf\tnamespace:__anon396601200111::__anon396601200211\ttyperef:typename:void\tend:6\na1\tinput.cpp\t/^namespace a1 {$/;\"\tn\tfile:\tend:24\na1_f\tinput.cpp\t/^\tvoid a1_f() { }$/;\"\tf\tnamespace:a1\ttyperef:typename:void\tend:11\na2\tinput.cpp\t/^\tnamespace a2 {$/;\"\tn\tnamespace:a1\tfile:\tend:19\na1_a2_f\tinput.cpp\t/^\t\tvoid a1_a2_f() { }$/;\"\tf\tnamespace:a1::a2\ttyperef:typename:void\tend:14\na3\tinput.cpp\t/^\t\tnamespace a3 {$/;\"\tn\tnamespace:a1::a2\tfile:\tend:18\na1_a2_a3_f\tinput.cpp\t/^\t\t\tvoid a1_a2_a3_f() { };$/;\"\tf\tnamespace:a1::a2::a3\ttyperef:typename:void\tend:17\n__anon396601200311\tinput.cpp\t/^\tnamespace {$/;\"\tn\tnamespace:a1\tfile:\tend:23\na1_anon_f\tinput.cpp\t/^\t\tvoid a1_anon_f() { };$/;\"\tf\tnamespace:a1::__anon396601200311\ttyperef:typename:void\tend:22\nb1\tinput.cpp\t/^namespace b1::b2 {$/;\"\tn\tfile:\tend:32\nb2\tinput.cpp\t/^namespace b1::b2 {$/;\"\tn\tnamespace:b1\tfile:\tend:32\nb1_b2_f\tinput.cpp\t/^\tvoid b1_b2_f() { };$/;\"\tf\tnamespace:b1::b2\ttyperef:typename:void\tend:27\nb3\tinput.cpp\t/^\tnamespace b3::b4 {$/;\"\tn\tnamespace:b1::b2\tfile:\tend:31\nb4\tinput.cpp\t/^\tnamespace b3::b4 {$/;\"\tn\tnamespace:b1::b2::b3\tfile:\tend:31\nb1_b2_b3_b4_f\tinput.cpp\t/^\t\tvoid b1_b2_b3_b4_f() { };$/;\"\tf\tnamespace:b1::b2::b3::b4\ttyperef:typename:void\tend:30\nc1\tinput.cpp\t/^inline namespace c1 {$/;\"\tn\tfile:\tend:38\tproperties:inline\nc2\tinput.cpp\t/^\tnamespace c2 {$/;\"\tn\tnamespace:c1\tfile:\tend:37\nc1_c2_f\tinput.cpp\t/^\t\tvoid c1_c2_f() { };$/;\"\tf\tnamespace:c1::c2\ttyperef:typename:void\tend:36\nd1\tinput.cpp\t/^inline namespace d1::d2 {$/;\"\tn\tfile:\tend:46\tproperties:inline\nd2\tinput.cpp\t/^inline namespace d1::d2 {$/;\"\tn\tnamespace:d1\tfile:\tend:46\tproperties:inline\nd1_d2_f\tinput.cpp\t/^\tvoid d1_d2_f() { };$/;\"\tf\tnamespace:d1::d2\ttyperef:typename:void\tend:41\nd3\tinput.cpp\t/^\tinline namespace d3::d4 {$/;\"\tn\tnamespace:d1::d2\tfile:\tend:45\tproperties:inline\nd4\tinput.cpp\t/^\tinline namespace d3::d4 {$/;\"\tn\tnamespace:d1::d2::d3\tfile:\tend:45\tproperties:inline\nd1_d2_d3_d4_f\tinput.cpp\t/^\t\tvoid d1_d2_d3_d4_f() { }$/;\"\tf\tnamespace:d1::d2::d3::d4\ttyperef:typename:void\tend:44\ne1\tinput.cpp\t/^namespace e1 = a1::a2::a3;$/;\"\tA\tfile:\tname:a1::a2::a3\ne2\tinput.cpp\t/^namespace e2 = b1::b2 __attribute__((abi_tag(\"blah\")));$/;\"\tA\tfile:\tname:b1::b2\nf1\tinput.cpp\t/^namespace f1 _SOME_MACRO(default)$/;\"\tn\tfile:\tend:54\nf2\tinput.cpp\t/^namespace f2::f3 _SOME_MACRO(\"blah\",\"foo\")$/;\"\tn\tfile:\tend:58\nf3\tinput.cpp\t/^namespace f2::f3 _SOME_MACRO(\"blah\",\"foo\")$/;\"\tn\tnamespace:f2\tfile:\tend:58\nz1\tinput.cpp\t/^namespace z1 { };$/;\"\tn\tfile:\tend:60\n"
  },
  {
    "path": "Units/parser-cxx.r/namespace.cpp.d/input.cpp",
    "content": "\nnamespace {\n\tvoid anon_f() { };\n\t\n\tnamespace {\n\t\tvoid anon_anon_f() { };\n\t}\n}\n\nnamespace a1 {\n\tvoid a1_f() { }\n\n\tnamespace a2 {\n\t\tvoid a1_a2_f() { }\n\t\t\n\t\tnamespace a3 {\n\t\t\tvoid a1_a2_a3_f() { };\n\t\t}\n\t}\n\t\n\tnamespace {\n\t\tvoid a1_anon_f() { };\n\t}\n}\n\nnamespace b1::b2 {\n\tvoid b1_b2_f() { };\n\n\tnamespace b3::b4 {\n\t\tvoid b1_b2_b3_b4_f() { };\n\t}\n}\n\ninline namespace c1 {\n\tnamespace c2 {\n\t\tvoid c1_c2_f() { };\n\t}\n}\n\ninline namespace d1::d2 {\n\tvoid d1_d2_f() { };\n\t\n\tinline namespace d3::d4 {\n\t\tvoid d1_d2_d3_d4_f() { }\n\t}\n}\n\nnamespace e1 = a1::a2::a3;\n\nnamespace e2 = b1::b2 __attribute__((abi_tag(\"blah\")));\n\nnamespace f1 _SOME_MACRO(default)\n{\n}\n\nnamespace f2::f3 _SOME_MACRO(\"blah\",\"foo\")\n{\n}\n\nnamespace z1 { };\n\n\n"
  },
  {
    "path": "Units/parser-cxx.r/new-delete.d/args.ctags",
    "content": "--kinds-c++=*\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/new-delete.d/expected.tags",
    "content": "fn\tinput.cpp\t/^Class fn()$/;\"\tf\ttyperef:typename:Class\n"
  },
  {
    "path": "Units/parser-cxx.r/new-delete.d/input.cpp",
    "content": "// Only fn() should be reported here.\nClass fn()\n{\n\tdelete x;\n\tdelete[] x;\n\tnew Class();\n\t(void)new Class();\n\treturn new Class();\n}"
  },
  {
    "path": "Units/parser-cxx.r/operators.cpp.d/args.ctags",
    "content": "--kinds-c++=pf\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/operators.cpp.d/expected.tags",
    "content": "operator =\tinput.cpp\t/^\tX & operator = (const X &x)$/;\"\tf\tclass:X\ttyperef:typename:X &\tfile:\noperator ==\tinput.cpp\t/^\tbool operator == (const X &x)$/;\"\tf\tclass:X\ttyperef:typename:bool\tfile:\noperator -=\tinput.cpp\t/^\tinline X & operator-=(const X &x)$/;\"\tf\tclass:X\ttyperef:typename:X &\tfile:\noperator +=\tinput.cpp\t/^\tinline X & operator += (const X &x)$/;\"\tf\tclass:X\ttyperef:typename:X &\tfile:\noperator *=\tinput.cpp\t/^\tX & operator *= (int x);$/;\"\tp\tclass:X\ttyperef:typename:X &\tfile:\noperator *=\tinput.cpp\t/^\tX & operator *= (const X & x);$/;\"\tp\tclass:X\ttyperef:typename:X &\tfile:\noperator &&\tinput.cpp\t/^\tX operator && (const X &a);$/;\"\tp\tclass:X\ttyperef:typename:X\tfile:\noperator /=\tinput.cpp\t/^\tinline void operator \\/= (int)$/;\"\tf\tclass:X\ttyperef:typename:void\tfile:\noperator ()\tinput.cpp\t/^\tinline void *** operator()()$/;\"\tf\tclass:X\ttyperef:typename:void ***\tfile:\noperator ++\tinput.cpp\t/^\tinline X & operator++()$/;\"\tf\tclass:X\ttyperef:typename:X &\tfile:\noperator --\tinput.cpp\t/^\tX & operator--()$/;\"\tf\tclass:X\ttyperef:typename:X &\tfile:\noperator []\tinput.cpp\t/^\tint operator[](int)$/;\"\tf\tclass:X\ttyperef:typename:int\tfile:\noperator []\tinput.cpp\t/^\tint operator[](const X &a) const$/;\"\tf\tclass:X\ttyperef:typename:int\tfile:\noperator *\tinput.cpp\t/^\tinline friend X operator*(const X &a, const X &b)$/;\"\tf\ttyperef:typename:X\tfile:\noperator new\tinput.cpp\t/^\tvoid * operator new(size_t);$/;\"\tp\tclass:X\ttyperef:typename:void *\tfile:\noperator delete\tinput.cpp\t/^\tvoid operator delete(void *);$/;\"\tp\tclass:X\ttyperef:typename:void\tfile:\noperator new[]\tinput.cpp\t/^\tvoid * operator new[](size_t);$/;\"\tp\tclass:X\ttyperef:typename:void *\tfile:\noperator delete[]\tinput.cpp\t/^\tvoid operator delete[](void *);$/;\"\tp\tclass:X\ttyperef:typename:void\tfile:\noperator Type\tinput.cpp\t/^\toperator Type() const;$/;\"\tp\tclass:X\tfile:\noperator <=>\tinput.cpp\t/^\tauto operator<=>(const X&a) const -> decltype(1 <=> 2)$/;\"\tf\tclass:X\ttyperef:typename:decltype(1<=>2)\tfile:\noperator *=\tinput.cpp\t/^X & X::operator *= (int x)$/;\"\tf\tclass:X\ttyperef:typename:X &\noperator *=\tinput.cpp\t/^X & X::operator *= (const X & x)$/;\"\tf\tclass:X\ttyperef:typename:X &\noperator &&\tinput.cpp\t/^X X::operator && (const X &a)$/;\"\tf\tclass:X\ttyperef:typename:X\noperator new\tinput.cpp\t/^void * X::operator new(size_t)$/;\"\tf\tclass:X\ttyperef:typename:void *\noperator delete\tinput.cpp\t/^void X::operator delete(void *)$/;\"\tf\tclass:X\ttyperef:typename:void\noperator new[]\tinput.cpp\t/^void * X::operator new[](size_t)$/;\"\tf\tclass:X\ttyperef:typename:void *\noperator delete[]\tinput.cpp\t/^void X::operator delete[](void *)$/;\"\tf\tclass:X\ttyperef:typename:void\nmain\tinput.cpp\t/^int main(int argc,char ** argv)$/;\"\tf\ttyperef:typename:int\noperator Type\tinput.cpp\t/^X::operator Type() const$/;\"\tf\tclass:X\noperator Eigen::Transform<T,3,Eigen::Affine,(Eigen::RowMajor)>\tinput.cpp\t/^template<typename T> inline cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine, (Eige/;\"\tf\tclass:cv::Affine3\n"
  },
  {
    "path": "Units/parser-cxx.r/operators.cpp.d/input.cpp",
    "content": "#include <string>\n#include <memory>\n\nclass Type {};\n\nclass X\n{\npublic:\n\tX & operator = (const X &x)\n\t{\n\t\treturn *this;\n\t}\n\t\n\tbool operator == (const X &x)\n\t{\n\t\treturn true;\n\t}\n\t\n\tinline X & operator-=(const X &x)\n\t{\n\t\treturn *this;\n\t}\n\t\n\tinline X & operator += (const X &x)\n\t{\n\t\treturn *this;\n\t}\n\t\n\tX & operator *= (int x);\n\tX & operator *= (const X & x);\n\tX operator && (const X &a);\n\n\tinline void operator /= (int)\n\t{\n\t}\n\t\n\tinline void *** operator()()\n\t{\n\t\treturn 0;\n\t}\n\t\n\tinline X & operator++()\n\t{\n\t\treturn *this;\n\t}\n\n\n\tX & operator--()\n\t{\n\t\treturn *this;\n\t}\n\t\n\tint operator[](int)\n\t{\n\t\treturn 0;\n\t}\n\t\n\tint operator[](const X &a) const\n\t{\n\t\treturn 0;\n\t}\n\t\n\t// This should appear as member of the global namespace\n\tinline friend X operator*(const X &a, const X &b)\n\t{\n\t\treturn X();\n\t}\n\t\n\t// This should NOT appear at all\n\tfriend X operator && (const X &a,const X & b);\n\t\n\tvoid * operator new(size_t);\n\tvoid operator delete(void *);\n\tvoid * operator new[](size_t);\n\tvoid operator delete[](void *);\n\n\toperator Type() const;\n\n\t// requires -std=c++20 to compile\n\tauto operator<=>(const X&a) const -> decltype(1 <=> 2)\n\t{\n\t\treturn std::strong_ordering::less;\n\t}\n};\n\nX & X::operator *= (int x)\n{\n\treturn *this;\n}\n\nX & X::operator *= (const X & x)\n{\n\treturn *this;\n}\n\nX X::operator && (const X &a)\n{\n\treturn *this;\n}\n\nvoid * X::operator new(size_t)\n{\n\treturn NULL;\n}\n\nvoid X::operator delete(void *)\n{\n}\n\nvoid * X::operator new[](size_t)\n{\n\treturn NULL;\n}\n\nvoid X::operator delete[](void *)\n{\n}\n\nint main(int argc,char ** argv)\n{\n\tX x;\n\treturn x[0];\n}\n\nX::operator Type() const\n{\n\treturn Type();\n}\n\n#ifdef DONT_CARE_ABOUT_COMPILATION\n// This doesn't compile because it lacks the necessary definitions. But it's still extracted.\n\ntemplate<typename T> inline cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const\n{\n\tEigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)> r;\n\tcv::Mat hdr(4, 4, cv::traits::Type<T>::value, r.matrix().data());\n\tcv::Mat(matrix, false).copyTo(hdr);\n\treturn r;\n}\n\n#endif\n"
  },
  {
    "path": "Units/parser-cxx.r/out-range-input-for-isspace.d/expected.tags",
    "content": "main\tinput.cpp\t/^int main() {}$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/out-range-input-for-isspace.d/input.cpp",
    "content": "extern \"C\"{\n};\n\nint main() {}\n"
  },
  {
    "path": "Units/parser-cxx.r/partition.d/args.ctags",
    "content": "--sort=no\n--fields=+{scope}{roles}\n--fields-C++=+{properties}\n--extras=+rq\n"
  },
  {
    "path": "Units/parser-cxx.r/partition.d/expected.tags",
    "content": "My.App.ConfigModule\tinput.cpp\t/^export module My.App . ConfigModule: ConfigData. IniSettings ;$/;\"\tM\troles:partOwner\nConfigData.IniSettings\tinput.cpp\t/^export module My.App . ConfigModule: ConfigData. IniSettings ;$/;\"\tP\tscope:module:My.App.ConfigModule\troles:def\tproperties:export\nMy.App.ConfigModule:ConfigData.IniSettings\tinput.cpp\t/^export module My.App . ConfigModule: ConfigData. IniSettings ;$/;\"\tP\tscope:module:My.App.ConfigModule\troles:def\tproperties:export\nMy.App.ConfigModule\tinput-0.cpp\t/^module My.App . ConfigModule: Config.Data. IniSettings ;$/;\"\tM\troles:partOwner\nConfig.Data.IniSettings\tinput-0.cpp\t/^module My.App . ConfigModule: Config.Data. IniSettings ;$/;\"\tP\tscope:module:My.App.ConfigModule\troles:def\nMy.App.ConfigModule:Config.Data.IniSettings\tinput-0.cpp\t/^module My.App . ConfigModule: Config.Data. IniSettings ;$/;\"\tP\tscope:module:My.App.ConfigModule\troles:def\nA\tinput-1.cpp\t/^export module A: ConfigData. IniSettings ;$/;\"\tM\troles:partOwner\nConfigData.IniSettings\tinput-1.cpp\t/^export module A: ConfigData. IniSettings ;$/;\"\tP\tscope:module:A\troles:def\tproperties:export\nA:ConfigData.IniSettings\tinput-1.cpp\t/^export module A: ConfigData. IniSettings ;$/;\"\tP\tscope:module:A\troles:def\tproperties:export\nMy.App.ConfigModule\tinput-2.cpp\t/^export module My.App . ConfigModule: B ;$/;\"\tM\troles:partOwner\nB\tinput-2.cpp\t/^export module My.App . ConfigModule: B ;$/;\"\tP\tscope:module:My.App.ConfigModule\troles:def\tproperties:export\nMy.App.ConfigModule:B\tinput-2.cpp\t/^export module My.App . ConfigModule: B ;$/;\"\tP\tscope:module:My.App.ConfigModule\troles:def\tproperties:export\nMy.App.ConfigModule\tinput-3.cpp\t/^export module My.App . ConfigModule: ;$/;\"\tM\troles:def\tproperties:export\n"
  },
  {
    "path": "Units/parser-cxx.r/partition.d/input-0.cpp",
    "content": "module My.App . ConfigModule: Config.Data. IniSettings ;\n"
  },
  {
    "path": "Units/parser-cxx.r/partition.d/input-1.cpp",
    "content": "export module A: ConfigData. IniSettings ;\n"
  },
  {
    "path": "Units/parser-cxx.r/partition.d/input-2.cpp",
    "content": "export module My.App . ConfigModule: B ;\n"
  },
  {
    "path": "Units/parser-cxx.r/partition.d/input-3.cpp",
    "content": "export module My.App . ConfigModule: ;\n"
  },
  {
    "path": "Units/parser-cxx.r/partition.d/input-4.cpp",
    "content": "module : Config.Data. IniSettings ; // Illegal syntax\n"
  },
  {
    "path": "Units/parser-cxx.r/partition.d/input.cpp",
    "content": "export module My.App . ConfigModule: ConfigData. IniSettings ;\n"
  },
  {
    "path": "Units/parser-cxx.r/pointer-to-array.d/args.ctags",
    "content": "--kinds-c=+l\n"
  },
  {
    "path": "Units/parser-cxx.r/pointer-to-array.d/expected.tags",
    "content": "arr\tinput.c\t/^  int (*arr)[] = foo();$/;\"\tl\tfunction:main\ttyperef:typename:int (*)[]\tfile:\nbar\tinput.c\t/^int2ptr_func bar = foo;$/;\"\tv\ttyperef:typename:int2ptr_func\nbaz\tinput.c\t/^int2ptr (*baz)(void) = foo;$/;\"\tv\ttyperef:typename:int2ptr (*)(void)\nfoo\tinput.c\t/^static int (*foo(void))[2] {$/;\"\tf\ttyperef:typename:int (*)[2]\tfile:\nfoo_arr\tinput.c\t/^  static int foo_arr[2] = {1, 2};$/;\"\tl\tfunction:foo\ttyperef:typename:int[2]\tfile:\nint2ptr\tinput.c\t/^typedef int (*int2ptr)[2];$/;\"\tt\ttyperef:typename:int (*)[2]\tfile:\nint2ptr_func\tinput.c\t/^typedef int (*(*int2ptr_func)(void))[2];$/;\"\tt\ttyperef:typename:int (* (*)(void))[2]\tfile:\nmain\tinput.c\t/^int main(void) {$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/pointer-to-array.d/input.c",
    "content": "\n#include <stdio.h>\n\ntypedef int (*int2ptr)[2];\ntypedef int (*(*int2ptr_func)(void))[2];\n\nstatic int (*foo(void))[2] {\n  static int foo_arr[2] = {1, 2};\n  return &foo_arr;\n}\n\nint2ptr (*baz)(void) = foo;\nint2ptr_func bar = foo;\n\nint main(void) {\n  int (*arr)[] = foo();\n  printf(\"array[0] = %d\\n\", (*arr)[0]);\n  printf(\"array[1] = %d\\n\", (*arr)[1]);\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/properties-consteval.d/args.ctags",
    "content": "--sort=no\n--kinds-c++=*-{parameter}\n--fields=+x\n--fields-c++=+{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/properties-consteval.d/expected.tags",
    "content": "sqr\tinput.cc\t/^consteval int sqr(int n)$/;\"\tf\ttyperef:typename:int\tproperties:consteval\nr\tinput.cc\t/^constexpr int r = sqr(100); \\/\\/ OK$/;\"\tv\ttyperef:typename:int\tproperties:constexpr\nx\tinput.cc\t/^int x = 100;$/;\"\tv\ttyperef:typename:int\nr2\tinput.cc\t/^int r2 = sqr(x);            \\/\\/ Error: Call does not produce a constant$/;\"\tv\ttyperef:typename:int\nsqrsqr\tinput.cc\t/^consteval int sqrsqr(int n)$/;\"\tf\ttyperef:typename:int\tproperties:consteval\ndblsqr\tinput.cc\t/^constexpr int dblsqr(int n)$/;\"\tf\ttyperef:typename:int\tproperties:constexpr\nf\tinput.cc\t/^consteval int f() { return 42; }$/;\"\tf\ttyperef:typename:int\tproperties:consteval\ng\tinput.cc\t/^consteval auto g() { return &f; }$/;\"\tf\ttyperef:typename:auto\tproperties:consteval\nh\tinput.cc\t/^consteval int h(int (*p)() = g()) { return p(); }$/;\"\tf\ttyperef:typename:int\tproperties:consteval\n"
  },
  {
    "path": "Units/parser-cxx.r/properties-consteval.d/input.cc",
    "content": "// Taken from https://en.cppreference.com/w/cpp/language/consteval\nconsteval int sqr(int n)\n{\n    return n*n;\n}\nconstexpr int r = sqr(100); // OK\n \nint x = 100;\nint r2 = sqr(x);            // Error: Call does not produce a constant\n \nconsteval int sqrsqr(int n)\n{\n    return sqr(sqr(n));     // Not a constant expression at this point, but OK\n}\n \nconstexpr int dblsqr(int n)\n{\n    return 2 * sqr(n);      // Error: Enclosing function is not consteval\n                            // and sqr(n) is not a constant\n}\n\nconsteval int f() { return 42; }\nconsteval auto g() { return &f; }\nconsteval int h(int (*p)() = g()) { return p(); }\n\n"
  },
  {
    "path": "Units/parser-cxx.r/properties-constexpr.d/args.ctags",
    "content": "--sort=no\n--kinds-c++=*\n--fields=+x\n--fields-c++=+{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/properties-constexpr.d/expected.tags",
    "content": "factorial\tinput.cc\t/^constexpr int factorial(int n)$/;\"\tf\ttyperef:typename:int\tproperties:constexpr\nn\tinput.cc\t/^constexpr int factorial(int n)$/;\"\tz\tfunction:factorial\ttyperef:typename:int\tfile:\nfactorial_cxx14\tinput.cc\t/^constexpr int factorial_cxx14(int n)$/;\"\tf\ttyperef:typename:int\tproperties:constexpr\nn\tinput.cc\t/^constexpr int factorial_cxx14(int n)$/;\"\tz\tfunction:factorial_cxx14\ttyperef:typename:int\tfile:\nres\tinput.cc\t/^    int res = 1;$/;\"\tl\tfunction:factorial_cxx14\ttyperef:typename:int\tfile:\nconststr\tinput.cc\t/^class conststr$/;\"\tc\tfile:\np\tinput.cc\t/^    const char* p;$/;\"\tm\tclass:conststr\ttyperef:typename:const char *\tfile:\nsz\tinput.cc\t/^    std::size_t sz;$/;\"\tm\tclass:conststr\ttyperef:typename:std::size_t\tfile:\nconststr\tinput.cc\t/^    constexpr conststr(const char(&a)[N]): p(a), sz(N - 1) {}$/;\"\tf\tclass:conststr\tfile:\tproperties:constexpr\na\tinput.cc\t/^    constexpr conststr(const char(&a)[N]): p(a), sz(N - 1) {}$/;\"\tz\tfunction:conststr::conststr\ttyperef:typename:const char (&)[N]\tfile:\noperator []\tinput.cc\t/^    constexpr char operator[](std::size_t n) const$/;\"\tf\tclass:conststr\ttyperef:typename:char\tfile:\tproperties:const,constexpr\nn\tinput.cc\t/^    constexpr char operator[](std::size_t n) const$/;\"\tz\tfunction:conststr::operator []\ttyperef:typename:std::size_t\tfile:\nsize\tinput.cc\t/^    constexpr std::size_t size() const { return sz; }$/;\"\tf\tclass:conststr\ttyperef:typename:std::size_t\tfile:\tproperties:const,constexpr\ncountlower\tinput.cc\t/^constexpr std::size_t countlower(conststr s, std::size_t n = 0,$/;\"\tf\ttyperef:typename:std::size_t\tproperties:constexpr\ns\tinput.cc\t/^constexpr std::size_t countlower(conststr s, std::size_t n = 0,$/;\"\tz\tfunction:countlower\ttyperef:typename:conststr\tfile:\nn\tinput.cc\t/^constexpr std::size_t countlower(conststr s, std::size_t n = 0,$/;\"\tz\tfunction:countlower\ttyperef:typename:std::size_t\tfile:\nc\tinput.cc\t/^\t\t\t\t\t     std::size_t c = 0)$/;\"\tz\tfunction:countlower\ttyperef:typename:std::size_t\tfile:\nconstN\tinput.cc\t/^struct constN$/;\"\ts\tfile:\nn\tinput.cc\t/^template<int n>$/;\"\tZ\tstruct:constN\ttyperef:typename:int\nconstN\tinput.cc\t/^    constN() { std::cout << n << '\\\\n'; }$/;\"\tf\tstruct:constN\tfile:\nmain\tinput.cc\t/^int main()$/;\"\tf\ttyperef:typename:int\nout1\tinput.cc\t/^    constN<factorial(4)> out1; \\/\\/ computed at compile time$/;\"\tl\tfunction:main\ttyperef:typename:constN<factorial (4)>\tfile:\nk\tinput.cc\t/^    volatile int k = 8; \\/\\/ disallow optimization using volatile$/;\"\tl\tfunction:main\ttyperef:typename:volatile int\tfile:\nout2\tinput.cc\t/^    constN<countlower(\"Hello, world!\")> out2; \\/\\/ implicitly converted to conststr$/;\"\tl\tfunction:main\ttyperef:typename:constN<countlower (\"Hello, world!\")>\tfile:\na\tinput.cc\t/^    constexpr int a[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8};$/;\"\tl\tfunction:main\ttyperef:typename:int[12]\tfile:\tproperties:constexpr\nlength_a\tinput.cc\t/^    constexpr int length_a = sizeof(a)\\/sizeof(int); \\/\\/ std::size(a) in C++17,$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\tproperties:constexpr\ni\tinput.cc\t/^    for (int i = 0; i < length_a; ++i)$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/properties-constexpr.d/input.cc",
    "content": "// Taken from https://en.cppreference.com/w/cpp/language/constexpr\n\n#include <iostream>\n#include <stdexcept>\n\n// C++11 constexpr functions use recursion rather than iteration\nconstexpr int factorial(int n)\n{\n    return n <= 1 ? 1 : (n * factorial(n - 1));\n}\n\n// C++14 constexpr functions may use local variables and loops\n#if __cplusplus >= 201402L\nconstexpr int factorial_cxx14(int n)\n{\n    int res = 1;\n    while (n > 1)\n\tres *= n--;\n    return res;\n}\n#endif // C++14\n\n// literal class\nclass conststr\n{\n    const char* p;\n    std::size_t sz;\npublic:\n    template<std::size_t N>\n    constexpr conststr(const char(&a)[N]): p(a), sz(N - 1) {}\n\n    // constexpr functions signal errors by throwing exceptions\n    // in C++11, they must do so from the conditional operator ?:\n    constexpr char operator[](std::size_t n) const\n    {\n\treturn n < sz ? p[n] : throw std::out_of_range(\"\");\n    }\n\n    constexpr std::size_t size() const { return sz; }\n};\n\n// C++11 constexpr functions had to put everything in a single return statement\n// (C++14 doesn't have that requirement)\nconstexpr std::size_t countlower(conststr s, std::size_t n = 0,\n\t\t\t\t\t     std::size_t c = 0)\n{\n    return n == s.size() ? c :\n\t'a' <= s[n] && s[n] <= 'z' ? countlower(s, n + 1, c + 1) :\n\t\t\t\t     countlower(s, n + 1, c);\n}\n\n// output function that requires a compile-time constant, for testing\ntemplate<int n>\nstruct constN\n{\n    constN() { std::cout << n << '\\n'; }\n};\n\nint main()\n{\n    std::cout << \"4! = \" ;\n    constN<factorial(4)> out1; // computed at compile time\n\n    volatile int k = 8; // disallow optimization using volatile\n    std::cout << k << \"! = \" << factorial(k) << '\\n'; // computed at run time\n\n    std::cout << \"the number of lowercase letters in \\\"Hello, world!\\\" is \";\n    constN<countlower(\"Hello, world!\")> out2; // implicitly converted to conststr\n\n    constexpr int a[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8};\n    constexpr int length_a = sizeof(a)/sizeof(int); // std::size(a) in C++17,\n\t\t\t\t\t\t    // std::ssize(a) in C++20\n    std::cout << \"array of length \" << length_a << \" has elements: \";\n    for (int i = 0; i < length_a; ++i)\n\tstd::cout << a[i] << \" \";\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/properties-constinit.d/args.ctags",
    "content": "--sort=no\n--kinds-c++=*-{parameter}\n--fields=+x\n--fields-c++=+{properties}\n"
  },
  {
    "path": "Units/parser-cxx.r/properties-constinit.d/expected.tags",
    "content": "g\tinput.cc\t/^const char *g() { return \"dynamic initialization\"; }$/;\"\tf\ttyperef:typename:const char *\nf\tinput.cc\t/^constexpr const char *f(bool p) { return p ? \"constant initializer\" : g(); }$/;\"\tf\ttyperef:typename:const char *\tproperties:constexpr\nc\tinput.cc\t/^constinit const char *c = f(true); \\/\\/ OK$/;\"\tv\ttyperef:typename:const char *\tproperties:constinit\nx\tinput.cc\t/^extern thread_local constinit int x;$/;\"\tx\ttyperef:typename:int\tproperties:extern,constinit,thread_local\nf\tinput.cc\t/^int f() { return x; } \\/\\/ no check of a guard variable needed$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/properties-constinit.d/input.cc",
    "content": "// Taken from https://en.cppreference.com/w/cpp/language/constinit\nconst char *g() { return \"dynamic initialization\"; }\nconstexpr const char *f(bool p) { return p ? \"constant initializer\" : g(); }\n\nconstinit const char *c = f(true); // OK\n\nextern thread_local constinit int x;\nint f() { return x; } // no check of a guard variable needed\n"
  },
  {
    "path": "Units/parser-cxx.r/properties.cpp.d/args.ctags",
    "content": "--sort=no\n--kinds-c++=*\n--fields=+x\n--fields-c++=+{properties}"
  },
  {
    "path": "Units/parser-cxx.r/properties.cpp.d/expected.tags",
    "content": "C01\tinput.cpp\t/^class C01$/;\"\tc\tfile:\nC01\tinput.cpp\t/^\tC01() = default;$/;\"\tp\tclass:C01\tfile:\tproperties:default\nmp01\tinput.cpp\t/^\tstatic int mp01;$/;\"\tm\tclass:C01\ttyperef:typename:int\tfile:\tproperties:static\nmp02\tinput.cpp\t/^\tmutable int mp02;$/;\"\tm\tclass:C01\ttyperef:typename:int\tfile:\tproperties:mutable\nmf01\tinput.cpp\t/^\tvirtual void mf01();$/;\"\tp\tclass:C01\ttyperef:typename:void\tfile:\tproperties:virtual\nmf02\tinput.cpp\t/^\tvirtual void mf02() final;$/;\"\tp\tclass:C01\ttyperef:typename:void\tfile:\tproperties:final,virtual\nC02\tinput.cpp\t/^class C02 : public C01$/;\"\tc\tfile:\nC02\tinput.cpp\t/^\tC02() = delete;$/;\"\tp\tclass:C02\tfile:\tproperties:delete\nC02\tinput.cpp\t/^\texplicit C02(int i)$/;\"\tf\tclass:C02\tfile:\tproperties:explicit\ni\tinput.cpp\t/^\texplicit C02(int i)$/;\"\tz\tfunction:C02::C02\ttyperef:typename:int\tfile:\nmf01\tinput.cpp\t/^\tvoid mf01() override;$/;\"\tp\tclass:C02\ttyperef:typename:void\tfile:\tproperties:override,virtual\nmf03\tinput.cpp\t/^\tvirtual void mf03() = 0;$/;\"\tp\tclass:C02\ttyperef:typename:void\tfile:\tproperties:pure,virtual\nmf04\tinput.cpp\t/^\tvirtual void mf04() final;$/;\"\tp\tclass:C02\ttyperef:typename:void\tfile:\tproperties:final,virtual\nmf05\tinput.cpp\t/^\tstatic inline void mf05()$/;\"\tf\tclass:C02\ttyperef:typename:void\tfile:\tproperties:inline,static\nmf06\tinput.cpp\t/^\tinline void mf06() const;$/;\"\tp\tclass:C02\ttyperef:typename:void\tfile:\tproperties:const,inline\nmf07\tinput.cpp\t/^\tvoid static mf07() volatile;$/;\"\tp\tclass:C02\ttyperef:typename:void\tfile:\tproperties:static,volatile\nv01\tinput.cpp\t/^extern int v01;$/;\"\tx\ttyperef:typename:int\tproperties:extern\nv02\tinput.cpp\t/^static volatile int v02;$/;\"\tv\ttyperef:typename:volatile int\tfile:\tproperties:static\np01\tinput.cpp\t/^static void p01();$/;\"\tp\ttyperef:typename:void\tfile:\tproperties:static\np02\tinput.cpp\t/^extern void p02();$/;\"\tp\ttyperef:typename:void\tfile:\tproperties:extern\nf01\tinput.cpp\t/^static void f01()$/;\"\tf\ttyperef:typename:void\tfile:\tproperties:static\nf02\tinput.cpp\t/^static inline void f02()$/;\"\tf\ttyperef:typename:void\tfile:\tproperties:inline,static\npoint\tinput.cpp\t/^static struct point { float x, y; } p0, p1;$/;\"\ts\tfile:\nx\tinput.cpp\t/^static struct point { float x, y; } p0, p1;$/;\"\tm\tstruct:point\ttyperef:typename:float\tfile:\ny\tinput.cpp\t/^static struct point { float x, y; } p0, p1;$/;\"\tm\tstruct:point\ttyperef:typename:float\tfile:\np0\tinput.cpp\t/^static struct point { float x, y; } p0, p1;$/;\"\tv\ttyperef:struct:point\tfile:\tproperties:static\np1\tinput.cpp\t/^static struct point { float x, y; } p0, p1;$/;\"\tv\ttyperef:struct:point\tfile:\tproperties:static\n"
  },
  {
    "path": "Units/parser-cxx.r/properties.cpp.d/input.cpp",
    "content": "\nclass C01\n{\npublic:\n\tC01() = default;\n\n\tstatic int mp01;\n\tmutable int mp02;\n\n\tvirtual void mf01();\n\tvirtual void mf02() final;\n};\n\nclass C02 : public C01\n{\npublic:\n\tC02() = delete;\n\texplicit C02(int i)\n\t{\n\t}\n\t\n\tvoid mf01() override;\n\tvirtual void mf03() = 0;\n\tvirtual void mf04() final;\n\tstatic inline void mf05()\n\t{\n\t}\n\tinline void mf06() const;\n\tvoid static mf07() volatile;\n};\n\nextern int v01;\nstatic volatile int v02;\n\nstatic void p01();\nextern void p02();\n\nstatic void f01()\n{\n}\n\nstatic inline void f02()\n{\n}\n\nstatic struct point { float x, y; } p0, p1;\n"
  },
  {
    "path": "Units/parser-cxx.r/prototype-starting-from-scope-op.d/args.ctags",
    "content": "--sort=no\n--C++-kinds=+p\n"
  },
  {
    "path": "Units/parser-cxx.r/prototype-starting-from-scope-op.d/expected.tags",
    "content": "bar\tinput.cpp\t/^::std::string bar();$/;\"\tp\ttyperef:typename:::std::string\tfile:\nbaz\tinput.cpp\t/^::std::string baz() { return \"not a prototype\"; }$/;\"\tf\ttyperef:typename:::std::string\n"
  },
  {
    "path": "Units/parser-cxx.r/prototype-starting-from-scope-op.d/input.cpp",
    "content": "// Taken from #3693 submitted by @b4n\n#include <string>\n\n::std::string bar();\n::std::string baz() { return \"not a prototype\"; }\n"
  },
  {
    "path": "Units/parser-cxx.r/rojas.h.d/args.ctags",
    "content": "--kinds-C++=+p\n"
  },
  {
    "path": "Units/parser-cxx.r/rojas.h.d/expected.tags",
    "content": "FFunc\tinput.h\t/^typedef uint32 (*FFunc) (const astruct * pP, int n);$/;\"\tt\ttyperef:typename:uint32 (*)(const astruct * pP,int n)\nFooBar\tinput.h\t/^typedef void * FooBar;$/;\"\tt\ttyperef:typename:void *\nafunc\tinput.h\t/^FooBar * afunc (const char * aparam);$/;\"\tp\ttyperef:typename:FooBar *\nastruct\tinput.h\t/^struct astruct$/;\"\ts\nastruct\tinput.h\t/^typedef struct astruct astruct;$/;\"\tt\ttyperef:struct:astruct\nm_member\tinput.h\t/^    int m_member;$/;\"\tm\tstruct:astruct\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/rojas.h.d/input.h",
    "content": "/* Problem reported by Emil Rojas <emil@lapel.com> on 22 May 2002 */\n/* Fixed by reinitializing statement when either of \"extern\", \"static\", or\n * \"typedef\" keywords are read.\n */\n# ifdef NOT_DEFINED\n    typedef unsigned long uint32 //; // remove comment before \";\" to make ctags work\n# endif\n\nextern \"C\" {\n\ntypedef void * FooBar;\nFooBar * afunc (const char * aparam);\nstruct astruct\n{\n    int m_member;\n};\ntypedef struct astruct astruct;\ntypedef uint32 (*FFunc) (const astruct * pP, int n);\n\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/scope-of-using-in-lambda-in-enum.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n"
  },
  {
    "path": "Units/parser-cxx.r/scope-of-using-in-lambda-in-enum.d/expected.tags",
    "content": "e\tinput.cpp\t/^enum e {$/;\"\tg\tfile:\n__anon92a0b9a90102\tinput.cpp\t/^  x = [] {$/;\"\tf\tenum:e\tfile:\nT3\tinput.cpp\t/^    using T3 = int;$/;\"\tt\tfunction:e::__anon92a0b9a90102\ttyperef:typename:int\tfile:\nx\tinput.cpp\t/^  x = [] {$/;\"\te\tenum:e\tfile:\nmain\tinput.cpp\t/^int main(void)$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/scope-of-using-in-lambda-in-enum.d/input.cpp",
    "content": "enum e {\n  x = [] {\n    using T3 = int;\n    return 1;\n  }()\n};\n\n\nint main(void)\n{\n  return e::x;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/scope-of-using-in-lambda-in-enum.d/validator",
    "content": "cxx20+module\n"
  },
  {
    "path": "Units/parser-cxx.r/signature.cpp.d/README",
    "content": "\n\tint bar (a, b) int a; char b; {}\n\nI wonder how we should do with a, b.\n\n"
  },
  {
    "path": "Units/parser-cxx.r/signature.cpp.d/args.ctags",
    "content": "--fields=+S\n--extras=+q\n--kinds-C++=+p\n"
  },
  {
    "path": "Units/parser-cxx.r/signature.cpp.d/expected.tags",
    "content": "BAR::bar\tinput.cpp\t/^char *BAR::bar (char *c, double d[]) const {}$/;\"\tf\tclass:BAR\ttyperef:typename:char *\tsignature:(char * c,double d[]) const\nbar\tinput.cpp\t/^char *BAR::bar (char *c, double d[]) const {}$/;\"\tf\tclass:BAR\ttyperef:typename:char *\tsignature:(char * c,double d[]) const\nfoo\tinput.cpp\t/^void foo (int a, char b) {}$/;\"\tf\ttyperef:typename:void\tsignature:(int a,char b)\nfoobar\tinput.cpp\t/^void foobar __ARGS ((int a, char b));$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(int a,char b)\nparams1\tinput.cpp\t/^void params1(const char * c = \"blah\");$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(const char * c=\"blah\")\nparams2\tinput.cpp\t/^void params2(char x = 'x');$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(char x='x')\nparams3\tinput.cpp\t/^void params3(char x = ' ');$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(char x=' ')\nparams4\tinput.cpp\t/^void params4(char x = ',');$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(char x=',')\nparams5\tinput.cpp\t/^void params5(char x = '\\\\n');$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(char x='\\\\n')\nparams6\tinput.cpp\t/^void params6(char x = '\\\\t',int n = 10,const char * v = \"a string with\\\\na newline\");$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(char x='\\\\t',int n=10,const char * v=\"a string with\\\\na newline\")\nparams7\tinput.cpp\t/^void params7(char x = '\t',\t\\/\\/ This is  tab char$/;\"\tp\ttyperef:typename:void\tfile:\tsignature:(char x='\\t',float p=3.14,const char * v=\"a string with a tab char:\\t\")\n"
  },
  {
    "path": "Units/parser-cxx.r/signature.cpp.d/input.cpp",
    "content": "/* Tests for collection of signature */\n\nvoid foo (int a, char b) {}\n\n/* note that K&R style declarations are not valid in C++ */\n//int bar (a, b) int a; char b; {}\n\nchar *BAR::bar (char *c, double d[]) const {}\n\nvoid foobar __ARGS ((int a, char b));\n\n\nvoid params1(const char * c = \"blah\");\nvoid params2(char x = 'x');\nvoid params3(char x = ' ');\nvoid params4(char x = ',');\nvoid params5(char x = '\\n');\nvoid params6(char x = '\\t',int n = 10,const char * v = \"a string with\\na newline\");\nvoid params7(char x = '\t',\t// This is  tab char\n\t     float p = 3.14,\n\t     const char * v = \"a string with a tab char:\t\"\n\t     );\n"
  },
  {
    "path": "Units/parser-cxx.r/struct-keyword-not-for-defining-struct.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=+plz\n"
  },
  {
    "path": "Units/parser-cxx.r/struct-keyword-not-for-defining-struct.d/expected.tags",
    "content": "Currency\tinput.cc\t/^typedef struct Currency$/;\"\ts\tfile:\nDollar\tinput.cc\t/^    int Dollar;$/;\"\tm\tstruct:Currency\ttyperef:typename:int\tfile:\nCents\tinput.cc\t/^    int Cents;$/;\"\tm\tstruct:Currency\ttyperef:typename:int\tfile:\noperator =\tinput.cc\t/^    struct Currency &operator=(Currency& value)$/;\"\tf\tstruct:Currency\ttyperef:struct:Currency &\tfile:\nvalue\tinput.cc\t/^    struct Currency &operator=(Currency& value)$/;\"\tz\tfunction:Currency::operator =\ttyperef:typename:Currency &\tfile:\ntest\tinput.cc\t/^void test()$/;\"\tf\ttyperef:typename:void\n"
  },
  {
    "path": "Units/parser-cxx.r/struct-keyword-not-for-defining-struct.d/input.cc",
    "content": "// Taken from #2840 submitted by @chongchal\ntypedef struct Currency\n{\n    int Dollar;\n    int Cents;\n\n    struct Currency &operator=(Currency& value)\n    {\n        Dollar = value.Dollar;\n        Cents = value.Cents;\n        return *this;\n    }\n};\n\nvoid test()\n{\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/template-member-forward-declaration.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=m\n"
  },
  {
    "path": "Units/parser-cxx.r/template-member-forward-declaration.d/expected.tags",
    "content": "p\tinput.cpp\t/^\tClass *p;$/;\"\tm\tclass:A\ttyperef:typename:Class *\tfile:\na_c_forward\tinput.cpp\t/^\tA<class C> a_c_forward;$/;\"\tm\tclass:B\ttyperef:typename:A<class C>\tfile:\na_s_forward\tinput.cpp\t/^\tA<struct S> a_s_forward;$/;\"\tm\tclass:B\ttyperef:typename:A<struct S>\tfile:\na_u_forward\tinput.cpp\t/^\tA<union U> a_u_forward;$/;\"\tm\tclass:B\ttyperef:typename:A<union U>\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/template-member-forward-declaration.d/input.cpp",
    "content": "template <class Class>\nclass A\n{\npublic:\n\tA() { p = new Class(); }\n\tClass *p;\n};\n\nclass B {\npublic:\n\t// forward declaration okay because only used as pointer in Template\n\tA<class C> a_c_forward;\n\tA<struct S> a_s_forward;\n\tA<union U> a_u_forward;\n};\n\n"
  },
  {
    "path": "Units/parser-cxx.r/template-member-function-pointer-scope.d/args.ctags",
    "content": "--sort=no\n--fields=+{signature}\n--kinds-C++=+fstz\n"
  },
  {
    "path": "Units/parser-cxx.r/template-member-function-pointer-scope.d/expected.tags",
    "content": "TestUtil\tinput.cpp\t/^struct TestUtil {$/;\"\ts\tfile:\nisNull\tinput.cpp\t/^    static bool isNull(const T&) { return false; }$/;\"\tf\tstruct:TestUtil\ttyperef:typename:bool\tfile:\tsignature:(const T &)\n__anon39cbdfcb010d\tinput.cpp\t/^    static bool isNull(const T&) { return false; }$/;\"\tz\tfunction:TestUtil::isNull\ttyperef:typename:const T &\tfile:\nTestUtil\tinput.cpp\t/^struct TestUtil<T*> {$/;\"\ts\tfile:\nisNull\tinput.cpp\t/^    static bool isNull(T* f) { return 0 == f; }$/;\"\tf\tstruct:TestUtil\ttyperef:typename:bool\tfile:\tsignature:(T * f)\nf\tinput.cpp\t/^    static bool isNull(T* f) { return 0 == f; }$/;\"\tz\tfunction:TestUtil::isNull\ttyperef:typename:T *\tfile:\nmemtype\tinput.cpp\t/^struct memtype {};$/;\"\ts\tfile:\nklass\tinput.cpp\t/^struct klass {};$/;\"\ts\tfile:\nisNull\tinput.cpp\t/^TestUtil<const memtype klass::*&>::isNull(const memtype klass::* &f)$/;\"\tf\tclass:TestUtil\ttyperef:typename:bool\tsignature:(const memtype klass::* & f)\nf\tinput.cpp\t/^TestUtil<const memtype klass::*&>::isNull(const memtype klass::* &f)$/;\"\tz\tfunction:TestUtil::isNull\ttyperef:typename:const memtype klass::* &\tfile:\nHandler\tinput.cpp\t/^struct Handler {$/;\"\ts\tfile:\nprocess\tinput.cpp\t/^    void process(T value) { }$/;\"\tf\tstruct:Handler\ttyperef:typename:void\tfile:\tsignature:(T value)\nvalue\tinput.cpp\t/^    void process(T value) { }$/;\"\tz\tfunction:Handler::process\ttyperef:typename:T\tfile:\nHandler\tinput.cpp\t/^struct Handler<R (C::*)()> {$/;\"\ts\tfile:\nprocess\tinput.cpp\t/^    void process(R (C::*method)()) { }$/;\"\tf\tstruct:Handler\ttyperef:typename:void\tfile:\tsignature:(R (C::* method)())\nmethod\tinput.cpp\t/^    void process(R (C::*method)()) { }$/;\"\tz\tfunction:Handler::process\ttyperef:typename:R (C::*)()\tfile:\nHandler\tinput.cpp\t/^struct Handler<R (C::*)(A)> {$/;\"\ts\tfile:\nprocess\tinput.cpp\t/^    void process(R (C::*method)(A)) { }$/;\"\tf\tstruct:Handler\ttyperef:typename:void\tfile:\tsignature:(R (C::* method)(A))\nmethod\tinput.cpp\t/^    void process(R (C::*method)(A)) { }$/;\"\tz\tfunction:Handler::process\ttyperef:typename:R (C::*)(A)\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/template-member-function-pointer-scope.d/input.cpp",
    "content": "// Derived from #4348 submitted by @gaborbernat.\n\n// C++ template specialization that previously triggered scope management crash\n// Test case for issue 4344: assertion failure in cxxScopePushTop\ntemplate <class T>\nstruct TestUtil {\n    static bool isNull(const T&) { return false; }\n};\n\ntemplate <class T>\nstruct TestUtil<T*> {\n    static bool isNull(T* f) { return 0 == f; }\n};\n\nstruct memtype {};\nstruct klass {};\n\ntemplate <>\ninline\nbool\nTestUtil<const memtype klass::*&>::isNull(const memtype klass::* &f)\n{\n    return 0 == f;\n}\n\n// Additional test cases for complex template specializations\ntemplate <typename T>\nstruct Handler {\n    void process(T value) { }\n};\n\ntemplate <typename R, typename C>\nstruct Handler<R (C::*)()> {\n    void process(R (C::*method)()) { }\n};\n\ntemplate <typename R, typename C, typename A>\nstruct Handler<R (C::*)(A)> {\n    void process(R (C::*method)(A)) { }\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/template-member-function-pointer-scope.d/validator",
    "content": "cxx11\n"
  },
  {
    "path": "Units/parser-cxx.r/template-nested-triangle-brackets.d/args.ctags",
    "content": "--sort=no\n--kinds-c++=+Z\n--fields-c++={template}{specialization}\n"
  },
  {
    "path": "Units/parser-cxx.r/template-nested-triangle-brackets.d/expected.tags",
    "content": "Test\tinput.hpp\t/^class Test : public set<int> {$/;\"\tc\ttemplate:<int,class _Comp0=less<int>,class _Comp1=less<pair<int,int>>>\n_Comp0\tinput.hpp\t/^         class _Comp0=less<int>,$/;\"\tZ\tclass:Test\ttyperef:meta:class\n_Comp1\tinput.hpp\t/^         class _Comp1=less<pair<int, int> > >$/;\"\tZ\tclass:Test\ttyperef:meta:class\nxxx\tinput.hpp\t/^  typedef int xxx;$/;\"\tt\tclass:Test\ttyperef:typename:int\nFoo\tinput-0.hpp\t/^class Foo {};$/;\"\tc\ttemplate:<typename X>\nX\tinput-0.hpp\t/^template <typename X>$/;\"\tZ\tclass:Foo\ttyperef:meta:typename\nbar\tinput-0.hpp\t/^constexpr Foo<Y> bar {};$/;\"\tv\ttyperef:typename:Foo<Y>\ttemplate:<typename Y=Foo<int>>\nY\tinput-0.hpp\t/^template <typename Y = Foo<int>>$/;\"\tZ\tvariable:bar\ttyperef:meta:typename\ni\tinput-0.hpp\t/^const int i = 3;$/;\"\tv\ttyperef:typename:const int\nfailure\tinput-1.hpp\t/^class failure {};$/;\"\tc\ttemplate:<class T,class Hash=std::hash<T>>\nT\tinput-1.hpp\t/^template <class T, class Hash=std::hash<T>>$/;\"\tZ\tclass:failure\ttyperef:meta:class\nHash\tinput-1.hpp\t/^template <class T, class Hash=std::hash<T>>$/;\"\tZ\tclass:failure\ttyperef:meta:class\nV\tinput-2.hpp\t/^const int V = 10;$/;\"\tv\ttyperef:typename:const int\nfuncA\tinput-2.hpp\t/^template<typename T,int I = V << 1 > void funcA(T t)$/;\"\tf\ttyperef:typename:void\ttemplate:<typename T,int I=V<<1>\nT\tinput-2.hpp\t/^template<typename T,int I = V << 1 > void funcA(T t)$/;\"\tZ\tfunction:funcA\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I = V << 1 > void funcA(T t)$/;\"\tZ\tfunction:funcA\ttyperef:typename:int\nK\tinput-2.hpp\t/^typedef int K;$/;\"\tt\ttyperef:typename:int\nfuncB\tinput-2.hpp\t/^template<typename T,int I,int J = I < V> void funcB(T t)$/;\"\tf\ttyperef:typename:void\ttemplate:<typename T,int I,int J=I<V>\nT\tinput-2.hpp\t/^template<typename T,int I,int J = I < V> void funcB(T t)$/;\"\tZ\tfunction:funcB\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int J = I < V> void funcB(T t)$/;\"\tZ\tfunction:funcB\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int J = I < V> void funcB(T t)$/;\"\tZ\tfunction:funcB\ttyperef:typename:int\nfuncC\tinput-2.hpp\t/^template<typename T,int I,int J = I < V> K funcC(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,int J=I<V>\nT\tinput-2.hpp\t/^template<typename T,int I,int J = I < V> K funcC(T t)$/;\"\tZ\tfunction:funcC\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int J = I < V> K funcC(T t)$/;\"\tZ\tfunction:funcC\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int J = I < V> K funcC(T t)$/;\"\tZ\tfunction:funcC\ttyperef:typename:int\nfuncD\tinput-2.hpp\t/^template<typename T,int I,int J = (I >> 2)> K funcD(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,int J=(I>>2)>\nT\tinput-2.hpp\t/^template<typename T,int I,int J = (I >> 2)> K funcD(T t)$/;\"\tZ\tfunction:funcD\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int J = (I >> 2)> K funcD(T t)$/;\"\tZ\tfunction:funcD\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int J = (I >> 2)> K funcD(T t)$/;\"\tZ\tfunction:funcD\ttyperef:typename:int\nfuncE\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> I)> K funcE(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,int J=(1>> I)>\nT\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> I)> K funcE(T t)$/;\"\tZ\tfunction:funcE\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> I)> K funcE(T t)$/;\"\tZ\tfunction:funcE\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> I)> K funcE(T t)$/;\"\tZ\tfunction:funcE\ttyperef:typename:int\nfuncF\tinput-2.hpp\t/^template<typename T,int I,int L,int J = (I >> L)> K funcF(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,int L,int J=(I>> L)>\nT\tinput-2.hpp\t/^template<typename T,int I,int L,int J = (I >> L)> K funcF(T t)$/;\"\tZ\tfunction:funcF\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int L,int J = (I >> L)> K funcF(T t)$/;\"\tZ\tfunction:funcF\ttyperef:typename:int\nL\tinput-2.hpp\t/^template<typename T,int I,int L,int J = (I >> L)> K funcF(T t)$/;\"\tZ\tfunction:funcF\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int L,int J = (I >> L)> K funcF(T t)$/;\"\tZ\tfunction:funcF\ttyperef:typename:int\nfuncG\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> V)> K funcG(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,int J=(1>> V)>\nT\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> V)> K funcG(T t)$/;\"\tZ\tfunction:funcG\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> V)> K funcG(T t)$/;\"\tZ\tfunction:funcG\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> V)> K funcG(T t)$/;\"\tZ\tfunction:funcG\ttyperef:typename:int\nfuncH\tinput-2.hpp\t/^template<typename T,int I,int J = (I >> V)> K funcH(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,int J=(I>> V)>\nT\tinput-2.hpp\t/^template<typename T,int I,int J = (I >> V)> K funcH(T t)$/;\"\tZ\tfunction:funcH\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int J = (I >> V)> K funcH(T t)$/;\"\tZ\tfunction:funcH\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int J = (I >> V)> K funcH(T t)$/;\"\tZ\tfunction:funcH\ttyperef:typename:int\nfuncI\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> (1+2))> K funcI(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,int J=(1>> (1+2))>\nT\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> (1+2))> K funcI(T t)$/;\"\tZ\tfunction:funcI\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> (1+2))> K funcI(T t)$/;\"\tZ\tfunction:funcI\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int J = (1 >> (1+2))> K funcI(T t)$/;\"\tZ\tfunction:funcI\ttyperef:typename:int\nfuncJ\tinput-2.hpp\t/^template<typename T,int I,int J = (I > 2)> K funcJ(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,int J=(I>2)>\nT\tinput-2.hpp\t/^template<typename T,int I,int J = (I > 2)> K funcJ(T t)$/;\"\tZ\tfunction:funcJ\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int J = (I > 2)> K funcJ(T t)$/;\"\tZ\tfunction:funcJ\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int J = (I > 2)> K funcJ(T t)$/;\"\tZ\tfunction:funcJ\ttyperef:typename:int\nfuncK\tinput-2.hpp\t/^template<typename T,int I,int J = (1 > I)> K funcK(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,int J=(1> I)>\nT\tinput-2.hpp\t/^template<typename T,int I,int J = (1 > I)> K funcK(T t)$/;\"\tZ\tfunction:funcK\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int J = (1 > I)> K funcK(T t)$/;\"\tZ\tfunction:funcK\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int J = (1 > I)> K funcK(T t)$/;\"\tZ\tfunction:funcK\ttyperef:typename:int\nfuncL\tinput-2.hpp\t/^template<typename T,int I,int L,int J = (I > L)> K funcL(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,int L,int J=(I> L)>\nT\tinput-2.hpp\t/^template<typename T,int I,int L,int J = (I > L)> K funcL(T t)$/;\"\tZ\tfunction:funcL\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,int L,int J = (I > L)> K funcL(T t)$/;\"\tZ\tfunction:funcL\ttyperef:typename:int\nL\tinput-2.hpp\t/^template<typename T,int I,int L,int J = (I > L)> K funcL(T t)$/;\"\tZ\tfunction:funcL\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,int L,int J = (I > L)> K funcL(T t)$/;\"\tZ\tfunction:funcL\ttyperef:typename:int\nfuncO\tinput-2.hpp\t/^template<typename T,int I,unsigned int J = (1 > (1+2))> K funcO(T t)$/;\"\tf\ttyperef:typename:K\ttemplate:<typename T,int I,unsigned int J=(1> (1+2))>\nT\tinput-2.hpp\t/^template<typename T,int I,unsigned int J = (1 > (1+2))> K funcO(T t)$/;\"\tZ\tfunction:funcO\ttyperef:meta:typename\nI\tinput-2.hpp\t/^template<typename T,int I,unsigned int J = (1 > (1+2))> K funcO(T t)$/;\"\tZ\tfunction:funcO\ttyperef:typename:int\nJ\tinput-2.hpp\t/^template<typename T,int I,unsigned int J = (1 > (1+2))> K funcO(T t)$/;\"\tZ\tfunction:funcO\ttyperef:typename:unsigned int\nTestStruct\tinput-3.hpp\t/^template <typename T> struct TestStruct {};$/;\"\ts\ttemplate:<typename T>\nT\tinput-3.hpp\t/^template <typename T> struct TestStruct {};$/;\"\tZ\tstruct:TestStruct\ttyperef:meta:typename\nTemplateParameterStruct\tinput-3.hpp\t/^template <typename T> struct TemplateParameterStruct {};$/;\"\ts\ttemplate:<typename T>\nT\tinput-3.hpp\t/^template <typename T> struct TemplateParameterStruct {};$/;\"\tZ\tstruct:TemplateParameterStruct\ttyperef:meta:typename\nParameterStruct\tinput-3.hpp\t/^struct ParameterStruct {};$/;\"\ts\nTestStruct\tinput-3.hpp\t/^template <> struct TestStruct<ParameterStruct> {};$/;\"\ts\ttemplate:<>\tspecialization:<ParameterStruct>\nTestStruct\tinput-3.hpp\t/^template <typename P> struct TestStruct<TemplateParameterStruct<P>> {};$/;\"\ts\ttemplate:<typename P>\tspecialization:<TemplateParameterStruct<P>>\nP\tinput-3.hpp\t/^template <typename P> struct TestStruct<TemplateParameterStruct<P>> {};$/;\"\tZ\tstruct:TestStruct\ttyperef:meta:typename\n"
  },
  {
    "path": "Units/parser-cxx.r/template-nested-triangle-brackets.d/input-0.hpp",
    "content": "template <typename X>\nclass Foo {};\n\ntemplate <typename Y = Foo<int>>\nconstexpr Foo<Y> bar {};\n\nconst int i = 3;\n"
  },
  {
    "path": "Units/parser-cxx.r/template-nested-triangle-brackets.d/input-1.hpp",
    "content": "// Derived from issued #2060 submitted by @dmhacker\n#include <hashtable.h>\ntemplate <class T, class Hash=std::hash<T>>\nclass failure {};\n"
  },
  {
    "path": "Units/parser-cxx.r/template-nested-triangle-brackets.d/input-2.hpp",
    "content": "const int V = 10;\n\ntemplate<typename T,int I = V << 1 > void funcA(T t)\n{\n}\n\ntypedef int K;\n\ntemplate<typename T,int I,int J = I < V> void funcB(T t)\n{\n}\n\ntemplate<typename T,int I,int J = I < V> K funcC(T t)\n{\n\treturn 0;\n}\n\n// The original comment: This stuff is allowed by C++03\n//    template<typename T,int I,int J = I >> 2> K funcD(T t)\n// However, the above input is rejected with:\n//    error: default template arguments may not be used in function templates\n//           without `-std=c++11' or `-std=gnu++11'\ntemplate<typename T,int I,int J = (I >> 2)> K funcD(T t)\n{\n\treturn 0;\n}\n\ntemplate<typename T,int I,int J = (1 >> I)> K funcE(T t)\n{\n\treturn 0;\n}\n\ntemplate<typename T,int I,int L,int J = (I >> L)> K funcF(T t)\n{\n\treturn 0;\n}\n\ntemplate<typename T,int I,int J = (1 >> V)> K funcG(T t)\n{\n\treturn 0;\n}\n\ntemplate<typename T,int I,int J = (I >> V)> K funcH(T t)\n{\n\treturn 0;\n}\n\ntemplate<typename T,int I,int J = (1 >> (1+2))> K funcI(T t)\n{\n\treturn 0;\n}\n\n\n\ntemplate<typename T,int I,int J = (I > 2)> K funcJ(T t)\n{\n\treturn 0;\n}\n\ntemplate<typename T,int I,int J = (1 > I)> K funcK(T t)\n{\n\treturn 0;\n}\n\ntemplate<typename T,int I,int L,int J = (I > L)> K funcL(T t)\n{\n\treturn 0;\n}\n\n/*\n\nWithout the knowledge of V these two are too ambiguous.\n\ntemplate<typename T,int I,long int J = 1 > V> K funcM(T t)\n{\n\treturn 0;\n}\n\ntemplate<typename T,int I,unsigned long int J = I > V> K funcN(T t)\n{\n\treturn 0;\n}\n*/\n\ntemplate<typename T,int I,unsigned int J = (1 > (1+2))> K funcO(T t)\n{\n\treturn 0;\n}\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Units/parser-cxx.r/template-nested-triangle-brackets.d/input-3.hpp",
    "content": "// Taken from the issue #2433 submitted by @andrejlevkovitch\n\ntemplate <typename T> struct TestStruct {};\n\ntemplate <typename T> struct TemplateParameterStruct {};\n\nstruct ParameterStruct {};\n\ntemplate <> struct TestStruct<ParameterStruct> {};\n\ntemplate <typename P> struct TestStruct<TemplateParameterStruct<P>> {};\n"
  },
  {
    "path": "Units/parser-cxx.r/template-nested-triangle-brackets.d/input.hpp",
    "content": "template <int,\n         class _Comp0=less<int>,\n         class _Comp1=less<pair<int, int> > >\nclass Test : public set<int> {\n  typedef int xxx;\n};\n// Taken from #1750 submitted by @tuarba.\n"
  },
  {
    "path": "Units/parser-cxx.r/template-nested-triangle-brackets.d/validator-2",
    "content": "cxx11\n"
  },
  {
    "path": "Units/parser-cxx.r/template-parameters.d/README",
    "content": "This reproduced a memory access error.\nSpecify VG=1 when running make for reproducing the original issue.\n\n"
  },
  {
    "path": "Units/parser-cxx.r/template-parameters.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/template-parameters.d/expected.tags",
    "content": "B\tinput.h\t/^template<class A> class B {$/;\"\tc\na\tinput.h\t/^\tA a;$/;\"\tm\tclass:B\ttyperef:typename:A\nC\tinput.h\t/^template<class A> class C {$/;\"\tc\nb\tinput.h\t/^  class B<A> b;$/;\"\tm\tclass:C\ttyperef:class:B\n"
  },
  {
    "path": "Units/parser-cxx.r/template-parameters.d/input.h",
    "content": "// -*- c++ -*-\ntemplate<class A> class B {\n\tA a;\n};\ntemplate<class A> class C {\n  class B<A> b;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/template-prototype.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=+pZ\n--fields=+K\n"
  },
  {
    "path": "Units/parser-cxx.r/template-prototype.d/expected.tags",
    "content": "f\tinput.cc\t/^template <class T> int f (T t);$/;\"\tprototype\ttyperef:typename:int\tfile:\nT\tinput.cc\t/^template <class T> int f (T t);$/;\"\ttparam\tprototype:f\ttyperef:meta:class\ng\tinput.cc\t/^template <class S> int g (S s) {$/;\"\tfunction\ttyperef:typename:int\nS\tinput.cc\t/^template <class S> int g (S s) {$/;\"\ttparam\tfunction:g\ttyperef:meta:class\n"
  },
  {
    "path": "Units/parser-cxx.r/template-prototype.d/input.cc",
    "content": "template <class T> int f (T t);\ntemplate <class S> int g (S s) {\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/template-specializations-including-op.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/template-specializations-including-op.d/expected.tags",
    "content": "Point\tinput.cpp\t/^struct Point {$/;\"\ts\tfile:\ndistance\tinput.cpp\t/^  int distance(void) {$/;\"\tf\tstruct:Point\ttyperef:typename:int\tfile:\nNS\tinput.cpp\t/^namespace NS {$/;\"\tn\tfile:\nMyReal\tinput.cpp\t/^  using MyReal = float;$/;\"\tt\tnamespace:NS\ttyperef:typename:float\tfile:\nMyVec\tinput.cpp\t/^  using MyVec = T[2];$/;\"\tt\tnamespace:NS\ttyperef:typename:T[2]\tfile:\ndistance\tinput.cpp\t/^int Point<int>::distance(void) { return 1; }$/;\"\tf\tclass:Point\ttyperef:typename:int\ndistance\tinput.cpp\t/^int Point<NS::MyReal>::distance(void) { return 1; }$/;\"\tf\tclass:Point\ttyperef:typename:int\ndistance\tinput.cpp\t/^int Point<NS::MyVec<int>>::distance(void) { return 1; }$/;\"\tf\tclass:Point\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/template-specializations-including-op.d/input.cpp",
    "content": "template <class T>\nstruct Point {\n  int distance(void) {\n    return 0;\n  }\n};\n\nnamespace NS {\n  using MyReal = float;\n  template <class T>\n  using MyVec = T[2];\n};\n\ntemplate<>\nint Point<int>::distance(void) { return 1; }\n\ntemplate<>\nint Point<NS::MyReal>::distance(void) { return 1; }\n\ntemplate<>\nint Point<NS::MyVec<int>>::distance(void) { return 1; }\n"
  },
  {
    "path": "Units/parser-cxx.r/template-specializations-including-op.d/validator",
    "content": "cxx11\n"
  },
  {
    "path": "Units/parser-cxx.r/template-specializations.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n--fields=+sS\n--fields-c++=+{template}{properties}{specialization}\n"
  },
  {
    "path": "Units/parser-cxx.r/template-specializations.d/expected.tags",
    "content": "A\tinput.cpp\t/^struct A {$/;\"\ts\tfile:\ttemplate:<typename T>\nT\tinput.cpp\t/^template<typename T>$/;\"\tZ\tstruct:A\ttyperef:meta:typename\nf\tinput.cpp\t/^    void f(T); \\/\\/ member, declared in the primary template$/;\"\tp\tstruct:A\ttyperef:typename:void\tfile:\tsignature:(T)\n__anonc12ce61d010d\tinput.cpp\t/^    void f(T); \\/\\/ member, declared in the primary template$/;\"\tz\tprototype:A::f\ttyperef:typename:T\tfile:\nh\tinput.cpp\t/^    void h(T) {} \\/\\/ member, defined in the primary template$/;\"\tf\tstruct:A\ttyperef:typename:void\tfile:\tsignature:(T)\n__anonc12ce61d020d\tinput.cpp\t/^    void h(T) {} \\/\\/ member, defined in the primary template$/;\"\tz\tfunction:A::h\ttyperef:typename:T\tfile:\ng1\tinput.cpp\t/^    template<class X1> void g1(T, X1); \\/\\/ member template$/;\"\tp\tstruct:A\ttyperef:typename:void\tfile:\tsignature:(T,X1)\ttemplate:<class X1>\nX1\tinput.cpp\t/^    template<class X1> void g1(T, X1); \\/\\/ member template$/;\"\tZ\tprototype:A::g1\ttyperef:meta:class\n__anonc12ce61d030d\tinput.cpp\t/^    template<class X1> void g1(T, X1); \\/\\/ member template$/;\"\tz\tprototype:A::g1\ttyperef:typename:T\tfile:\n__anonc12ce61d040d\tinput.cpp\t/^    template<class X1> void g1(T, X1); \\/\\/ member template$/;\"\tz\tprototype:A::g1\ttyperef:typename:X1\tfile:\ng2\tinput.cpp\t/^    template<class X2> void g2(T, X2); \\/\\/ member template$/;\"\tp\tstruct:A\ttyperef:typename:void\tfile:\tsignature:(T,X2)\ttemplate:<class X2>\nX2\tinput.cpp\t/^    template<class X2> void g2(T, X2); \\/\\/ member template$/;\"\tZ\tprototype:A::g2\ttyperef:meta:class\n__anonc12ce61d050d\tinput.cpp\t/^    template<class X2> void g2(T, X2); \\/\\/ member template$/;\"\tz\tprototype:A::g2\ttyperef:typename:T\tfile:\n__anonc12ce61d060d\tinput.cpp\t/^    template<class X2> void g2(T, X2); \\/\\/ member template$/;\"\tz\tprototype:A::g2\ttyperef:typename:X2\tfile:\nf\tinput.cpp\t/^template<> void A<int>::f(int);$/;\"\tp\tclass:A\ttyperef:typename:void\tfile:\tsignature:(int)\ttemplate:<>\tproperties:scopespecialization,specialization\n__anonc12ce61d070d\tinput.cpp\t/^template<> void A<int>::f(int);$/;\"\tz\tprototype:A::f\ttyperef:typename:int\tfile:\nh\tinput.cpp\t/^template<> void A<int>::h(int) {}$/;\"\tf\tclass:A\ttyperef:typename:void\tsignature:(int)\ttemplate:<>\tproperties:scopespecialization,specialization\n__anonc12ce61d080d\tinput.cpp\t/^template<> void A<int>::h(int) {}$/;\"\tz\tfunction:A::h\ttyperef:typename:int\tfile:\ng1\tinput.cpp\t/^template<class X1> void A<T>::g1(T, X1) { }$/;\"\tf\tclass:A\ttyperef:typename:void\tsignature:(T,X1)\ttemplate:<class X1>\tproperties:scopespecialization,specialization\nX1\tinput.cpp\t/^template<class X1> void A<T>::g1(T, X1) { }$/;\"\tZ\tfunction:A::g1\ttyperef:meta:class\n__anonc12ce61d090d\tinput.cpp\t/^template<class X1> void A<T>::g1(T, X1) { }$/;\"\tz\tfunction:A::g1\ttyperef:typename:T\tfile:\n__anonc12ce61d0a0d\tinput.cpp\t/^template<class X1> void A<T>::g1(T, X1) { }$/;\"\tz\tfunction:A::g1\ttyperef:typename:X1\tfile:\ng1\tinput.cpp\t/^template<class X1> void A<int>::g1(int, X1);$/;\"\tp\tclass:A\ttyperef:typename:void\tfile:\tsignature:(int,X1)\ttemplate:<class X1>\tproperties:scopespecialization,specialization\nX1\tinput.cpp\t/^template<class X1> void A<int>::g1(int, X1);$/;\"\tZ\tprototype:A::g1\ttyperef:meta:class\n__anonc12ce61d0b0d\tinput.cpp\t/^template<class X1> void A<int>::g1(int, X1);$/;\"\tz\tprototype:A::g1\ttyperef:typename:int\tfile:\n__anonc12ce61d0c0d\tinput.cpp\t/^template<class X1> void A<int>::g1(int, X1);$/;\"\tz\tprototype:A::g1\ttyperef:typename:X1\tfile:\ng2\tinput.cpp\t/^template<> void A<int>::g2<char>(int, char); \\/\\/ for X2 = char$/;\"\tp\tclass:A\ttyperef:typename:void\tfile:\tsignature:(int,char)\ttemplate:<>\tspecialization:<char>\tproperties:scopespecialization,specialization\n__anonc12ce61d0d0d\tinput.cpp\t/^template<> void A<int>::g2<char>(int, char); \\/\\/ for X2 = char$/;\"\tz\tprototype:A::g2\ttyperef:typename:int\tfile:\n__anonc12ce61d0e0d\tinput.cpp\t/^template<> void A<int>::g2<char>(int, char); \\/\\/ for X2 = char$/;\"\tz\tprototype:A::g2\ttyperef:typename:char\tfile:\ng1\tinput.cpp\t/^template<> void A<int>::g1(int, char);$/;\"\tp\tclass:A\ttyperef:typename:void\tfile:\tsignature:(int,char)\ttemplate:<>\tproperties:scopespecialization,specialization\n__anonc12ce61d0f0d\tinput.cpp\t/^template<> void A<int>::g1(int, char);$/;\"\tz\tprototype:A::g1\ttyperef:typename:int\tfile:\n__anonc12ce61d100d\tinput.cpp\t/^template<> void A<int>::g1(int, char);$/;\"\tz\tprototype:A::g1\ttyperef:typename:char\tfile:\nm\tinput.cpp\t/^template<typename X> void m(X)$/;\"\tf\ttyperef:typename:void\tsignature:(X)\ttemplate:<typename X>\nX\tinput.cpp\t/^template<typename X> void m(X)$/;\"\tZ\tfunction:m\ttyperef:meta:typename\n__anonc12ce61d110d\tinput.cpp\t/^template<typename X> void m(X)$/;\"\tz\tfunction:m\ttyperef:typename:X\tfile:\nm\tinput.cpp\t/^template<> void m<int>(int)$/;\"\tf\ttyperef:typename:void\tsignature:(int)\ttemplate:<>\tspecialization:<int>\tproperties:specialization\n__anonc12ce61d120d\tinput.cpp\t/^template<> void m<int>(int)$/;\"\tz\tfunction:m\ttyperef:typename:int\tfile:\nm\tinput.cpp\t/^template<> void m<A<int>>(A<int> a)$/;\"\tf\ttyperef:typename:void\tsignature:(A<int> a)\ttemplate:<>\tspecialization:<A<int>>\tproperties:specialization\na\tinput.cpp\t/^template<> void m<A<int>>(A<int> a)$/;\"\tz\tfunction:m\ttyperef:typename:A<int>\tfile:\nB\tinput.cpp\t/^struct B { };$/;\"\ts\tfile:\nm\tinput.cpp\t/^template<> void m<B>(B)$/;\"\tf\ttyperef:typename:void\tsignature:(B)\ttemplate:<>\tspecialization:<B>\tproperties:specialization\n__anonc12ce61d130d\tinput.cpp\t/^template<> void m<B>(B)$/;\"\tz\tfunction:m\ttyperef:typename:B\tfile:\nm\tinput.cpp\t/^template<> void m(char)$/;\"\tf\ttyperef:typename:void\tsignature:(char)\ttemplate:<>\tproperties:specialization\n__anonc12ce61d140d\tinput.cpp\t/^template<> void m(char)$/;\"\tz\tfunction:m\ttyperef:typename:char\tfile:\nC\tinput.cpp\t/^class C {};$/;\"\tc\tfile:\ttemplate:<class T1,class T2,int I>\nT1\tinput.cpp\t/^template<class T1, class T2, int I>$/;\"\tZ\tclass:C\ttyperef:meta:class\nT2\tinput.cpp\t/^template<class T1, class T2, int I>$/;\"\tZ\tclass:C\ttyperef:meta:class\nI\tinput.cpp\t/^template<class T1, class T2, int I>$/;\"\tZ\tclass:C\ttyperef:typename:int\nC\tinput.cpp\t/^class C<T, T*, I> {};$/;\"\tc\tfile:\ttemplate:<class T,int I>\tspecialization:<T,T *,I>\nT\tinput.cpp\t/^template<class T, int I>$/;\"\tZ\tclass:C\ttyperef:meta:class\nI\tinput.cpp\t/^template<class T, int I>$/;\"\tZ\tclass:C\ttyperef:typename:int\nC\tinput.cpp\t/^class C<T*, T2, I> {};$/;\"\tc\tfile:\ttemplate:<class T,class T2,int I>\tspecialization:<T *,T2,I>\nT\tinput.cpp\t/^template<class T, class T2, int I>$/;\"\tZ\tclass:C\ttyperef:meta:class\nT2\tinput.cpp\t/^template<class T, class T2, int I>$/;\"\tZ\tclass:C\ttyperef:meta:class\nI\tinput.cpp\t/^template<class T, class T2, int I>$/;\"\tZ\tclass:C\ttyperef:typename:int\nC\tinput.cpp\t/^class C<int, T*, 5> {};$/;\"\tc\tfile:\ttemplate:<class T>\tspecialization:<int,T *,5>\nT\tinput.cpp\t/^template<class T>$/;\"\tZ\tclass:C\ttyperef:meta:class\nC\tinput.cpp\t/^class C<X, T*, I> {};$/;\"\tc\tfile:\ttemplate:<class X,class T,int I>\tspecialization:<X,T *,I>\nX\tinput.cpp\t/^template<class X, class T, int I>$/;\"\tZ\tclass:C\ttyperef:meta:class\nT\tinput.cpp\t/^template<class X, class T, int I>$/;\"\tZ\tclass:C\ttyperef:meta:class\nI\tinput.cpp\t/^template<class X, class T, int I>$/;\"\tZ\tclass:C\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/template-specializations.d/input.cpp",
    "content": "template<typename T>\nstruct A {\n    void f(T); // member, declared in the primary template\n    void h(T) {} // member, defined in the primary template\n    template<class X1> void g1(T, X1); // member template\n    template<class X2> void g2(T, X2); // member template\n};\n\n// specialization of a member\ntemplate<> void A<int>::f(int);\n// member specialization OK even if defined in-class\ntemplate<> void A<int>::h(int) {}\n\n// out of class member template definition\ntemplate<class T>\ntemplate<class X1> void A<T>::g1(T, X1) { }\n\n// member template specialization\ntemplate<>\ntemplate<class X1> void A<int>::g1(int, X1);\n\n// member template specialization\ntemplate<>\ntemplate<> void A<int>::g2<char>(int, char); // for X2 = char\n// same, using template argument deduction (X1 = char)\ntemplate<>\ntemplate<> void A<int>::g1(int, char);\n\ntemplate<typename X> void m(X)\n{\n}\n\ntemplate<> void m<int>(int)\n{\n}\n\ntemplate<> void m<A<int>>(A<int> a)\n{\n}\n\n// bug #2181\nstruct B { };\ntemplate<> void m<B>(B)\n{\n}\n\ntemplate<> void m(char)\n{\n}\n\n#if HANDLE_BROKEN_INPUT\n\t// This is broken input. Should *not* be extracted.\n\ttemplate <> void int<int>(int a);\n#endif\n\n\n// Examples from the \"manual\".\n\n// primary template\ntemplate<class T1, class T2, int I>\nclass C {};\n\n//partial specialization where T2 is a pointer to T1\ntemplate<class T, int I>\nclass C<T, T*, I> {};\n\n// partial specialization where T1 is a pointer\ntemplate<class T, class T2, int I>\nclass C<T*, T2, I> {};\n\n// partial specialization where T1 is int, I is 5, and T2 is a pointer\ntemplate<class T>\nclass C<int, T*, 5> {};\n\n// partial specialization where T2 is a pointer\ntemplate<class X, class T, int I>\nclass C<X, T*, I> {};\n"
  },
  {
    "path": "Units/parser-cxx.r/templates-enable-if.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n--fields-c++=+{template}"
  },
  {
    "path": "Units/parser-cxx.r/templates-enable-if.d/expected.tags",
    "content": "A\tinput.cpp\t/^class A$/;\"\tc\tfile:\nf1\tinput.cpp\t/^\t\ttypename std::enable_if<2 << 3,int>::type f1(X x)$/;\"\tf\tclass:A\ttyperef:typename:std::enable_if<2<<3,int>::type\tfile:\ttemplate:<typename X>\nX\tinput.cpp\t/^\ttemplate<typename X> $/;\"\tZ\tfunction:A::f1\ttyperef:meta:typename\nx\tinput.cpp\t/^\t\ttypename std::enable_if<2 << 3,int>::type f1(X x)$/;\"\tz\tfunction:A::f1\ttyperef:typename:X\tfile:\nf2\tinput.cpp\t/^\t\ttypename std::enable_if<!false,int>::type f2(X x)$/;\"\tf\tclass:A\ttyperef:typename:std::enable_if<!false,int>::type\tfile:\ttemplate:<typename X>\nX\tinput.cpp\t/^\ttemplate<typename X> $/;\"\tZ\tfunction:A::f2\ttyperef:meta:typename\nx\tinput.cpp\t/^\t\ttypename std::enable_if<!false,int>::type f2(X x)$/;\"\tz\tfunction:A::f2\ttyperef:typename:X\tfile:\nB\tinput.cpp\t/^class B$/;\"\tc\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/templates-enable-if.d/input.cpp",
    "content": "#include <type_traits>\n\nclass A\n{\npublic:\n\ttemplate<typename X> \n\t\ttypename std::enable_if<2 << 3,int>::type f1(X x)\n\t\t{\n\t\t\treturn (int)x;\n\t\t};\n\t\n\ttemplate<typename X> \n\t\ttypename std::enable_if<!false,int>::type f2(X x)\n\t\t{\n\t\t\treturn (int)x;\n\t\t};\n};\n\nclass B\n{\n};"
  },
  {
    "path": "Units/parser-cxx.r/templates-in-labmdas-1.cpp.d/args.ctags",
    "content": "--kinds-c++=+cfl\n--fields=+SsK\n--fields-c++=+{captures}\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/templates-in-labmdas-1.cpp.d/expected.tags",
    "content": "Bar\tinput.cpp\t/^class Bar$/;\"\tclass\tfile:\nfoo\tinput.cpp\t/^    A foo()$/;\"\tfunction\tclass:Bar\ttyperef:typename:A\tfile:\tsignature:()\nf1\tinput.cpp\t/^int f1()$/;\"\tfunction\ttyperef:typename:int\tsignature:()\nb\tinput.cpp\t/^    Bar<int> b;$/;\"\tlocal\tfunction:f1\ttyperef:typename:Bar<int>\tfile:\nt\tinput.cpp\t/^    auto t = b.template foo<int>();$/;\"\tlocal\tfunction:f1\ttyperef:typename:auto\tfile:\nf2\tinput.cpp\t/^int f2()$/;\"\tfunction\ttyperef:typename:int\tsignature:()\nb\tinput.cpp\t/^    Bar<int> b;$/;\"\tlocal\tfunction:f2\ttyperef:typename:Bar<int>\tfile:\n__anon1763e7850102\tinput.cpp\t/^    auto l = [](auto & p){ return p.template foo<int>();};$/;\"\tfunction\tfunction:f2\tfile:\tsignature:(auto & p)\tcaptures:[]\nl\tinput.cpp\t/^    auto l = [](auto & p){ return p.template foo<int>();};$/;\"\tlocal\tfunction:f2\ttyperef:typename:auto\tfile:\nmain\tinput.cpp\t/^int main()$/;\"\tfunction\ttyperef:typename:int\tsignature:()\n"
  },
  {
    "path": "Units/parser-cxx.r/templates-in-labmdas-1.cpp.d/input.cpp",
    "content": "// Bug reported by akrzyz on github.\n\ntemplate<class T>\nclass Bar\n{\npublic:\n    template <class A>\n    A foo()\n    {\n        return A{};\n    }\n};\n\nint f1()\n{\n    Bar<int> b;\n    auto t = b.template foo<int>();\n    return t;\n}\n\nint f2()\n{\n    Bar<int> b;\n    auto l = [](auto & p){ return p.template foo<int>();};\n    return l(b);\n}\n\nint main()\n{\n    return f1() + f2();\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/templates-in-labmdas-2.cpp.d/args.ctags",
    "content": "--kinds-c++=+cfl\n--fields=+SsKe\n--fields-c++=+{template}{captures}\n--sort=no"
  },
  {
    "path": "Units/parser-cxx.r/templates-in-labmdas-2.cpp.d/expected.tags",
    "content": "Foo\tinput.cpp\t/^namespace Foo$/;\"\tnamespace\tfile:\tend:10\nbar\tinput.cpp\t/^T bar() $/;\"\tfunction\tnamespace:Foo\ttyperef:typename:T\tsignature:()\tend:9\ttemplate:<class T>\nmain\tinput.cpp\t/^int main()$/;\"\tfunction\ttyperef:typename:int\tsignature:()\tend:16\n__anonaa3dc9860102\tinput.cpp\t/^    auto l = []{return Foo::template bar<int>();};$/;\"\tfunction\tfunction:main\tfile:\tend:14\tcaptures:[]\nl\tinput.cpp\t/^    auto l = []{return Foo::template bar<int>();};$/;\"\tlocal\tfunction:main\ttyperef:typename:auto\tfile:\tend:14\n"
  },
  {
    "path": "Units/parser-cxx.r/templates-in-labmdas-2.cpp.d/input.cpp",
    "content": "// Bug reported by akrzyz on github.\n\nnamespace Foo\n{\ntemplate <class T>\nT bar() \n{\n    return T{};\n};\n}\n\nint main()\n{\n    auto l = []{return Foo::template bar<int>();};\n    return l();\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/templates.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--kinds-C++=*\n--fields-c++=+{template}"
  },
  {
    "path": "Units/parser-cxx.r/templates.d/expected.tags",
    "content": "zero\tinput.cpp\t/^zero (const T &v1, const T &v2)$/;\"\tf\ttyperef:typename:int\ttemplate:<typename T>\nT\tinput.cpp\t/^template <typename T> int $/;\"\tZ\tfunction:zero\ttyperef:meta:typename\nv1\tinput.cpp\t/^zero (const T &v1, const T &v2)$/;\"\tz\tfunction:zero\ttyperef:typename:const T &\tfile:\nv2\tinput.cpp\t/^zero (const T &v1, const T &v2)$/;\"\tz\tfunction:zero\ttyperef:typename:const T &\tfile:\nmin\tinput.cpp\t/^min(const T&v1, const T&v2)$/;\"\tf\ttyperef:typename:T\ttemplate:<typename T>\nT\tinput.cpp\t/^template <typename T> inline T $/;\"\tZ\tfunction:min\ttyperef:meta:typename\nv1\tinput.cpp\t/^min(const T&v1, const T&v2)$/;\"\tz\tfunction:min\ttyperef:typename:const T &\tfile:\nv2\tinput.cpp\t/^min(const T&v1, const T&v2)$/;\"\tz\tfunction:min\ttyperef:typename:const T &\tfile:\nItem\tinput.cpp\t/^class Item$/;\"\tc\tfile:\ttemplate:<class Type>\nType\tinput.cpp\t/^template <class Type> $/;\"\tZ\tclass:Item\ttyperef:meta:class\nItem::Type\tinput.cpp\t/^template <class Type> $/;\"\tZ\tclass:Item\ttyperef:meta:class\nItem\tinput.cpp\t/^  Item(const Type &t) : item (t), next (0) { }$/;\"\tf\tclass:Item\tfile:\nItem::Item\tinput.cpp\t/^  Item(const Type &t) : item (t), next (0) { }$/;\"\tf\tclass:Item\tfile:\nt\tinput.cpp\t/^  Item(const Type &t) : item (t), next (0) { }$/;\"\tz\tfunction:Item::Item\ttyperef:typename:const Type &\tfile:\nitem\tinput.cpp\t/^  Type item;$/;\"\tm\tclass:Item\ttyperef:typename:Type\tfile:\nItem::item\tinput.cpp\t/^  Type item;$/;\"\tm\tclass:Item\ttyperef:typename:Type\tfile:\nnext\tinput.cpp\t/^  Item *next;$/;\"\tm\tclass:Item\ttyperef:typename:Item *\tfile:\nItem::next\tinput.cpp\t/^  Item *next;$/;\"\tm\tclass:Item\ttyperef:typename:Item *\tfile:\nconstant\tinput.cpp\t/^template<typename T> const T constant = T(10.0);/;\"\tv\ttyperef:typename:const T\ttemplate:<typename T>\nT\tinput.cpp\t/^template<typename T> const T constant = T(10.0);/;\"\tZ\tvariable:constant\ttyperef:meta:typename\nconstant::T\tinput.cpp\t/^template<typename T> const T constant = T(10.0);/;\"\tZ\tvariable:constant\ttyperef:meta:typename\n"
  },
  {
    "path": "Units/parser-cxx.r/templates.d/input.cpp",
    "content": "template <typename T> int \nzero (const T &v1, const T &v2)\n{\n  return 0;\n}\n\ntemplate <typename T> inline T \nmin(const T&v1, const T&v2)\n{\n  if (v1 < v2)\n    return v1;\n  else\n    return v2;\n}\n\ntemplate <class Type> \nclass Item\n{\n  Item(const Type &t) : item (t), next (0) { }\n  Type item;\n  Item *next;\n};\n\ntemplate<typename T> const T constant = T(10.0);"
  },
  {
    "path": "Units/parser-cxx.r/templates2.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--kinds-C++=*\n--fields-c++=+{template}"
  },
  {
    "path": "Units/parser-cxx.r/templates2.d/expected.tags",
    "content": "foo1\tinput.cpp\t/^auto foo1(const Container<Elem> & p_container)$/;\"\tf\ttyperef:typename:auto\ttemplate:<template<class...> class Container,class Elem>\nElem\tinput.cpp\t/^template<template<class...> class Container, class Elem>$/;\"\tZ\tfunction:foo1\ttyperef:meta:class\np_container\tinput.cpp\t/^auto foo1(const Container<Elem> & p_container)$/;\"\tz\tfunction:foo1\ttyperef:typename:const Container<Elem> &\tfile:\nfoo2\tinput.cpp\t/^auto foo2(const Container<Key,Elem> & p_container)$/;\"\tf\ttyperef:typename:auto\ttemplate:<template<class...> class Container,class Key,class Elem>\nKey\tinput.cpp\t/^template<template<class...> class Container, class Key, class Elem>$/;\"\tZ\tfunction:foo2\ttyperef:meta:class\nElem\tinput.cpp\t/^template<template<class...> class Container, class Key, class Elem>$/;\"\tZ\tfunction:foo2\ttyperef:meta:class\np_container\tinput.cpp\t/^auto foo2(const Container<Key,Elem> & p_container)$/;\"\tz\tfunction:foo2\ttyperef:typename:const Container<Key,Elem> &\tfile:\nbar\tinput.cpp\t/^void bar()$/;\"\tf\ttyperef:typename:void\nmain\tinput.cpp\t/^int main()$/;\"\tf\ttyperef:typename:int\nv\tinput.cpp\t/^    auto v = foo1(std::vector<int>{1,2,3});$/;\"\tl\tfunction:main\ttyperef:typename:auto\tfile:\nm\tinput.cpp\t/^    auto m = foo2(std::map<int,int>{{1,2}});$/;\"\tl\tfunction:main\ttyperef:typename:auto\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/templates2.d/input.cpp",
    "content": "/* bug reported by akrzyz on 2016.03.10: no tags were emitted */\n\n#include <vector>\n#include <map>\n\ntemplate<template<class...> class Container, class Elem>\nauto foo1(const Container<Elem> & p_container)\n{\n    return Container<Elem>{};\n}\n\ntemplate<template<class...> class Container, class Key, class Elem>\nauto foo2(const Container<Key,Elem> & p_container)\n{\n    return Container<Key,Elem>{};\n}\n\nvoid bar()\n{\n}\n\nint main()\n{\n    auto v = foo1(std::vector<int>{1,2,3});\n    auto m = foo2(std::map<int,int>{{1,2}});\n    return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/templates3.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--kinds-C++=*\n--fields-c++=+{template}"
  },
  {
    "path": "Units/parser-cxx.r/templates3.d/expected.tags",
    "content": "makeArrayRef\tinput.cpp\t/^makeArrayRef(ValueType (&p_data)[N], SizeType& p_size)$/;\"\tf\ttyperef:typename:boost::disable_if_c<N==1,ArrayRef<ValueType,SizeType>>::type\ttemplate:<typename ValueType,int N,typename SizeType>\nValueType\tinput.cpp\t/^template <typename ValueType, int N, typename SizeType>$/;\"\tZ\tfunction:makeArrayRef\ttyperef:meta:typename\nN\tinput.cpp\t/^template <typename ValueType, int N, typename SizeType>$/;\"\tZ\tfunction:makeArrayRef\ttyperef:typename:int\nSizeType\tinput.cpp\t/^template <typename ValueType, int N, typename SizeType>$/;\"\tZ\tfunction:makeArrayRef\ttyperef:meta:typename\np_data\tinput.cpp\t/^makeArrayRef(ValueType (&p_data)[N], SizeType& p_size)$/;\"\tz\tfunction:makeArrayRef\ttyperef:typename:ValueType (&)[N]\tfile:\np_size\tinput.cpp\t/^makeArrayRef(ValueType (&p_data)[N], SizeType& p_size)$/;\"\tz\tfunction:makeArrayRef\ttyperef:typename:SizeType &\tfile:\nfoo\tinput.cpp\t/^void foo()$/;\"\tf\ttyperef:typename:void\n"
  },
  {
    "path": "Units/parser-cxx.r/templates3.d/input.cpp",
    "content": "/* bug reported by akrzyz on 2016.03.10: tags for makeArrayRef were not emitted */\n\ntemplate <typename ValueType, int N, typename SizeType>\ntypename boost::disable_if_c<N == 1, ArrayRef<ValueType, SizeType> >::type\nmakeArrayRef(ValueType (&p_data)[N], SizeType& p_size)\n{\n    return ArrayRef<ValueType, SizeType>(p_data, p_size);\n}\n\nvoid foo()\n{\n}\n\n"
  },
  {
    "path": "Units/parser-cxx.r/templates4.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--kinds-C++=*\n--fields-c++=+{template}"
  },
  {
    "path": "Units/parser-cxx.r/templates4.d/expected.tags",
    "content": "INT\tinput.cpp\t/^#define INT /;\"\td\tfile:\nx\tinput.cpp\t/^template<char i, bool B = i < 10> INT x(void) { return 0; }$/;\"\tf\ttyperef:typename:INT\ttemplate:<char i,bool B=i<10>\ni\tinput.cpp\t/^template<char i, bool B = i < 10> INT x(void) { return 0; }$/;\"\tZ\tfunction:x\ttyperef:typename:char\nB\tinput.cpp\t/^template<char i, bool B = i < 10> INT x(void) { return 0; }$/;\"\tZ\tfunction:x\ttyperef:typename:bool\n"
  },
  {
    "path": "Units/parser-cxx.r/templates4.d/input.cpp",
    "content": "#define INT int\n\ntemplate<char i, bool B = i < 10> INT x(void) { return 0; }\n\n"
  },
  {
    "path": "Units/parser-cxx.r/templates5.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n--fields-c++=+{template}"
  },
  {
    "path": "Units/parser-cxx.r/templates5.d/expected.tags",
    "content": "Checks\tinput.cpp\t/^struct Checks$/;\"\ts\tfile:\nCheck\tinput.cpp\t/^\ttemplate <typename X> static constexpr bool Check()$/;\"\tf\tstruct:Checks\ttyperef:typename:bool\tfile:\ttemplate:<typename X>\nX\tinput.cpp\t/^\ttemplate <typename X> static constexpr bool Check()$/;\"\tZ\tfunction:Checks::Check\ttyperef:meta:typename\nS\tinput.cpp\t/^template<typename A, typename std::enable_if<Checks::template Check<A>(),bool>::type = true> cla/;\"\tc\tfile:\ttemplate:<typename A,typename std::enable_if<Checks::template Check<A> (),bool>::type=true>\nA\tinput.cpp\t/^template<typename A, typename std::enable_if<Checks::template Check<A>(),bool>::type = true> cla/;\"\tZ\tclass:S\ttyperef:meta:typename\nfoo\tinput.cpp\t/^\ttemplate<typename U> void foo(){}$/;\"\tf\tclass:S\ttyperef:typename:void\tfile:\ttemplate:<typename U>\nU\tinput.cpp\t/^\ttemplate<typename U> void foo(){}$/;\"\tZ\tfunction:S::foo\ttyperef:meta:typename\nbar\tinput.cpp\t/^template<typename T> void bar()$/;\"\tf\ttyperef:typename:void\ttemplate:<typename T>\nT\tinput.cpp\t/^template<typename T> void bar()$/;\"\tZ\tfunction:bar\ttyperef:meta:typename\ns\tinput.cpp\t/^\tS<T> s;$/;\"\tl\tfunction:bar\ttyperef:typename:S<T>\tfile:\nmarker\tinput.cpp\t/^int marker;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/templates5.d/input.cpp",
    "content": "// template keyword used as disambiguator for dependent names\n\n#include <type_traits>\n\nstruct Checks\n{\n\ttemplate <typename X> static constexpr bool Check()\n\t{\n\t\treturn true;\n\t}\n};\n\ntemplate<typename A, typename std::enable_if<Checks::template Check<A>(),bool>::type = true> class S\n{\n\ttemplate<typename U> void foo(){}\n};\n\ntemplate<typename T> void bar()\n{\n\tS<T> s;\n\ts.template foo<T>();\n}\n\n// Marker to make sure the parser doesn't bail out before this line.\nint marker;\n"
  },
  {
    "path": "Units/parser-cxx.r/templates6.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/templates6.d/expected.tags",
    "content": "X\tinput.hpp\t/^namespace X {$/;\"\tn\nC\tinput.hpp\t/^template<typename T> class X::C$/;\"\tc\tclass:X\nC\tinput.hpp\t/^  C<T>(void) {$/;\"\tf\tclass:X::C\nD\tinput.hpp\t/^template<typename T> class D$/;\"\tc\nD\tinput.hpp\t/^  D<T>(void) {$/;\"\tf\tclass:D\nStack\tinput-0.cpp\t/^class Stack$/;\"\tc\tfile:\nsize\tinput-0.cpp\t/^  std::size_t size;$/;\"\tm\tclass:Stack\ttyperef:typename:std::size_t\tfile:\nstack\tinput-0.cpp\t/^  std::vector<T> stack;$/;\"\tm\tclass:Stack\ttyperef:typename:std::vector<T>\tfile:\n~Stack\tinput-0.cpp\t/^  ~Stack(){};$/;\"\tf\tclass:Stack\tfile:\nStack\tinput-0.cpp\t/^  Stack<T>(std::size_t n) {$/;\"\tf\tclass:Stack\tfile:\nmain\tinput-0.cpp\t/^int main() {$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/templates6.d/input-0.cpp",
    "content": "// Taken from #3390 submitted by @delsner\n#include <iostream>\n#include <vector>\n\ntemplate<typename T>\nclass Stack\n{\nprivate:\n  std::size_t size;\n  std::vector<T> stack;\n\npublic:\n  ~Stack(){};\n\n  // Not recognized by ctags.\n  Stack<T>(std::size_t n) {\n    size = n;\n    std::cout << \"Constructing a `Stack<T>`\\n\";\n  }\n};\n\nint main() {\n  Stack<float> sf{2};\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/templates6.d/input.hpp",
    "content": "namespace X {\ntemplate<typename T> class C;\n};\n\ntemplate<typename T> class X::C\n{\npublic:\n  C<T>(void) {\n  }\n};\n\ntemplate<typename T> class D\n{\npublic:\n  D<T>(void) {\n  }\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/templates6.d/validator",
    "content": "cxx11\n"
  },
  {
    "path": "Units/parser-cxx.r/templates7.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n--fields-c++=+{template}"
  },
  {
    "path": "Units/parser-cxx.r/templates7.d/expected.tags",
    "content": "foo\tinput.hpp\t/^A foo()$/;\"\tf\ttyperef:typename:A\ttemplate:<typename A,typename B>\nA\tinput.hpp\t/^template<typename A, typename B>$/;\"\tZ\tfunction:foo\ttyperef:meta:typename\nB\tinput.hpp\t/^template<typename A, typename B>$/;\"\tZ\tfunction:foo\ttyperef:meta:typename\nbar\tinput.hpp\t/^A& bar(A& a, const B& b)$/;\"\tf\ttyperef:typename:A &\ttemplate:<typename A,typename B>\nA\tinput.hpp\t/^template<typename A, typename B>$/;\"\tZ\tfunction:bar\ttyperef:meta:typename\nB\tinput.hpp\t/^template<typename A, typename B>$/;\"\tZ\tfunction:bar\ttyperef:meta:typename\na\tinput.hpp\t/^A& bar(A& a, const B& b)$/;\"\tz\tfunction:bar\ttyperef:typename:A &\tfile:\nb\tinput.hpp\t/^A& bar(A& a, const B& b)$/;\"\tz\tfunction:bar\ttyperef:typename:const B &\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/templates7.d/input.hpp",
    "content": "template<typename A, typename B>\nA foo()\n{\n    return A();\n}\n\ntemplate<typename A, typename B>\nA& bar(A& a, const B& b)\n{\n    return a;\n}"
  },
  {
    "path": "Units/parser-cxx.r/templates7.d/validator",
    "content": "cxx11\n"
  },
  {
    "path": "Units/parser-cxx.r/templates8.d/README",
    "content": "This is a crash test.\nThe input is invalid as C++ code.\n"
  },
  {
    "path": "Units/parser-cxx.r/templates8.d/input.cpp",
    "content": "template <class T>\nstruct A\n{\n\tS<F>();\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/typedef-of-function-ptr-with-macro.d/expected.tags",
    "content": "a\tinput.cpp\t/^typedef void (WINAPI  a) (void);$/;\"\tt\ttyperef:typename:void (WINAPI)(void)\tfile:\nb\tinput.cpp\t/^typedef void (WINAPI* b) (void);$/;\"\tt\ttyperef:typename:void (WINAPI *)(void)\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/typedef-of-function-ptr-with-macro.d/input.cpp",
    "content": "typedef void (WINAPI  a) (void);\ntypedef void (WINAPI* b) (void);\n"
  },
  {
    "path": "Units/parser-cxx.r/typedefs.cpp.d/args.ctags",
    "content": "--kinds-c++=t\n--fields=+t\n--sort=no\n"
  },
  {
    "path": "Units/parser-cxx.r/typedefs.cpp.d/expected.tags",
    "content": "T001\tinput.cpp\t/^typedef struct AStruct T001;$/;\"\tt\ttyperef:struct:AStruct\tfile:\nT002\tinput.cpp\t/^typedef class AClass T002;$/;\"\tt\ttyperef:class:AClass\tfile:\nT003\tinput.cpp\t/^typedef union AUnion T003;$/;\"\tt\ttyperef:union:AUnion\tfile:\nT004\tinput.cpp\t/^typedef enum AEnum T004;$/;\"\tt\ttyperef:enum:AEnum\tfile:\nT101\tinput.cpp\t/^typedef struct { int a; } T101;$/;\"\tt\ttyperef:struct:__anon0e56f3370108\tfile:\nT102\tinput.cpp\t/^typedef union { int a; int b; } T102;$/;\"\tt\ttyperef:union:__anon0e56f337020a\tfile:\nT103\tinput.cpp\t/^typedef enum { E2 } T103;$/;\"\tt\ttyperef:enum:__anon0e56f3370303\tfile:\nT201\tinput.cpp\t/^typedef int* T201;$/;\"\tt\ttyperef:typename:int *\tfile:\nT202\tinput.cpp\t/^typedef const AClass* *  T202;$/;\"\tt\ttyperef:typename:const AClass **\tfile:\nT301\tinput.cpp\t/^typedef int (*T301) (int &,int , AUnion *);$/;\"\tt\ttyperef:typename:int (*)(int &,int,AUnion *)\tfile:\nT302\tinput.cpp\t/^typedef AClass &(* T302)(AClass &);$/;\"\tt\ttyperef:typename:AClass & (*)(AClass &)\tfile:\nT303\tinput.cpp\t/^typedef struct AStruct (*T303)(struct AStruct &);$/;\"\tt\ttyperef:struct:AStruct (*)(struct AStruct &)\tfile:\nT304\tinput.cpp\t/^typedef int (T304)(int);$/;\"\tt\ttyperef:typename:int ()(int)\tfile:\nT305\tinput.cpp\t/^typedef struct AStruct (T305)(int);$/;\"\tt\ttyperef:struct:AStruct ()(int)\tfile:\nT306\tinput.cpp\t/^typedef union AUnion & (T306)(int);$/;\"\tt\ttyperef:union:AUnion & ()(int)\tfile:\nT307\tinput.cpp\t/^typedef AClass (T307)(int);$/;\"\tt\ttyperef:typename:AClass ()(int)\tfile:\nT308\tinput.cpp\t/^typedef enum AEnum (T308)(int);$/;\"\tt\ttyperef:enum:AEnum ()(int)\tfile:\nT309\tinput.cpp\t/^typedef int T309(int);$/;\"\tt\ttyperef:typename:int ()(int)\tfile:\nT310\tinput.cpp\t/^typedef int T310(AUnion *);$/;\"\tt\ttyperef:typename:int ()(AUnion *)\tfile:\nT401\tinput.cpp\t/^typedef int T401 [ 10];$/;\"\tt\ttyperef:typename:int[10]\tfile:\nT501\tinput.cpp\t/^typedef ATemplate1<int > T501;$/;\"\tt\ttyperef:typename:ATemplate1<int>\tfile:\nT502\tinput.cpp\t/^typedef ATemplate1< unsigned short int> T502;$/;\"\tt\ttyperef:typename:ATemplate1<unsigned short int>\tfile:\nT503\tinput.cpp\t/^typedef ATemplate1<ATemplate2 < AStruct,AClass> > T503;$/;\"\tt\ttyperef:typename:ATemplate1<ATemplate2<AStruct,AClass>>\tfile:\nT504\tinput.cpp\t/^typedef ATemplate1<int > (*T504)();$/;\"\tt\ttyperef:typename:ATemplate1<int> (*)()\tfile:\nT601\tinput.cpp\t/^\ttypedef typename Type::iterator1 T601;$/;\"\tt\tclass:Container\ttyperef:typename:Type::iterator1\tfile:\nT602\tinput.cpp\t/^\ttypedef typename Type :: iterator2 T602;$/;\"\tt\tclass:Container\ttyperef:typename:Type::iterator2\tfile:\nT603\tinput.cpp\t/^\ttypedef ATemplate1<AClass> T603;$/;\"\tt\tclass:Container\ttyperef:typename:ATemplate1<AClass>\tfile:\nT604\tinput.cpp\t/^\ttypedef int (*T604)(ATemplate1<AUnion> &);$/;\"\tt\tclass:Container\ttyperef:typename:int (*)(ATemplate1<AUnion> &)\tfile:\nT701\tinput.cpp\t/^typedef DECLPOINTER(struct AStruct) T701;$/;\"\tt\tfile:\nT801\tinput.cpp\t/^} T801, *T802;$/;\"\tt\ttyperef:struct:_ABC\tfile:\nT802\tinput.cpp\t/^} T801, *T802;$/;\"\tt\ttyperef:struct:_ABC *\tfile:\nT803\tinput.cpp\t/^typedef int T803, *T804, **T805;$/;\"\tt\ttyperef:typename:int\tfile:\nT804\tinput.cpp\t/^typedef int T803, *T804, **T805;$/;\"\tt\ttyperef:typename:int *\tfile:\nT805\tinput.cpp\t/^typedef int T803, *T804, **T805;$/;\"\tt\ttyperef:typename:int **\tfile:\nT806\tinput.cpp\t/^typedef ATemplate2< ATemplate2< ATemplate1<int *>, AClass>, AStruct> T806, **T807;$/;\"\tt\ttyperef:typename:ATemplate2<ATemplate2<ATemplate1<int * >,AClass>,AStruct>\tfile:\nT807\tinput.cpp\t/^typedef ATemplate2< ATemplate2< ATemplate1<int *>, AClass>, AStruct> T806, **T807;$/;\"\tt\ttyperef:typename:ATemplate2<ATemplate2<ATemplate1<int * >,AClass>,AStruct> **\tfile:\nT808\tinput.cpp\t/^typedef int T808, *T809, (&T810)(int, int *), T811[10], &T812;$/;\"\tt\ttyperef:typename:int\tfile:\nT809\tinput.cpp\t/^typedef int T808, *T809, (&T810)(int, int *), T811[10], &T812;$/;\"\tt\ttyperef:typename:int *\tfile:\nT810\tinput.cpp\t/^typedef int T808, *T809, (&T810)(int, int *), T811[10], &T812;$/;\"\tt\ttyperef:typename:int (&)(int,int *)\tfile:\nT811\tinput.cpp\t/^typedef int T808, *T809, (&T810)(int, int *), T811[10], &T812;$/;\"\tt\ttyperef:typename:int[10]\tfile:\nT812\tinput.cpp\t/^typedef int T808, *T809, (&T810)(int, int *), T811[10], &T812;$/;\"\tt\ttyperef:typename:int &\tfile:\nT901\tinput.cpp\t/^} T901, *T902;$/;\"\tt\ttyperef:typename:const struct AStruct1\tfile:\nT902\tinput.cpp\t/^} T901, *T902;$/;\"\tt\ttyperef:typename:const struct AStruct1 *\tfile:\nT903\tinput.cpp\t/^typedef const struct AStruct1 T903;$/;\"\tt\ttyperef:typename:const struct AStruct1\tfile:\nT904\tinput.cpp\t/^typedef const struct AStruct1 * T904,* T905;$/;\"\tt\ttyperef:typename:const struct AStruct1 *\tfile:\nT905\tinput.cpp\t/^typedef const struct AStruct1 * T904,* T905;$/;\"\tt\ttyperef:typename:const struct AStruct1 *\tfile:\nT906\tinput.cpp\t/^typedef volatile struct AStruct1 * T906;$/;\"\tt\ttyperef:typename:volatile struct AStruct1 *\tfile:\nT907\tinput.cpp\t/^typedef const enum AEnum T907, &T908;$/;\"\tt\ttyperef:typename:const enum AEnum\tfile:\nT908\tinput.cpp\t/^typedef const enum AEnum T907, &T908;$/;\"\tt\ttyperef:typename:const enum AEnum &\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/typedefs.cpp.d/input.cpp",
    "content": "// Note that in this file spacing matters: ctags should normalize it.\n\n// Auxiliary declarations\nstruct AStruct {};\nclass AClass {};\nunion AUnion {};\nenum AEnum { E1 };\ntemplate<typename AType> class ATemplate1;\ntemplate<typename AType1,typename AType2> class ATemplate2;\n\n// class/struct/union/enum typedefs\ntypedef struct AStruct T001;\ntypedef class AClass T002;\ntypedef union AUnion T003;\ntypedef enum AEnum T004;\n\n// typedefs with anonymous types\ntypedef struct { int a; } T101;\ntypedef union { int a; int b; } T102;\ntypedef enum { E2 } T103;\n\n// plain types, pointers etc\ntypedef int* T201;\ntypedef const AClass* *  T202;\n\n// function pointers and functions\ntypedef int (*T301) (int &,int , AUnion *);\ntypedef AClass &(* T302)(AClass &);\ntypedef struct AStruct (*T303)(struct AStruct &);\ntypedef int (T304)(int);\ntypedef struct AStruct (T305)(int);\ntypedef union AUnion & (T306)(int);\ntypedef AClass (T307)(int);\ntypedef enum AEnum (T308)(int);\ntypedef int T309(int);\ntypedef int T310(AUnion *);\n#if 0\n\t// broken input (to make coveralls happy)\n\ttypedef int int(int);\n#endif\n\n// arrays\ntypedef int T401 [ 10];\n\n// stuff containing template instantiations\ntypedef ATemplate1<int > T501;\ntypedef ATemplate1< unsigned short int> T502;\ntypedef ATemplate1<ATemplate2 < AStruct,AClass> > T503;\ntypedef ATemplate1<int > (*T504)();\n\n// typedefs within a class\ntemplate<typename Type> class Container\n{\npublic:\n\ttypedef typename Type::iterator1 T601;\n\ttypedef typename Type :: iterator2 T602;\n\ttypedef ATemplate1<AClass> T603;\n\ttypedef int (*T604)(ATemplate1<AUnion> &);\n};\n\n// This should appear as typedef but have not typeref since we can't resolve macros\n#define DECLPOINTER(name) name *\n\ntypedef DECLPOINTER(struct AStruct) T701;\n\n// Multiple typedefs\ntypedef struct _ABC {\n\tint a;\n\tint b;\n} T801, *T802;\n\ntypedef int T803, *T804, **T805;\ntypedef ATemplate2< ATemplate2< ATemplate1<int *>, AClass>, AStruct> T806, **T807;\ntypedef int T808, *T809, (&T810)(int, int *), T811[10], &T812;\n\n// Typedefs with const/volatile prefix\ntypedef const struct AStruct1 {\n\tint a;\n} T901, *T902;\n\ntypedef const struct AStruct1 T903;\ntypedef const struct AStruct1 * T904,* T905;\ntypedef volatile struct AStruct1 * T906;\ntypedef const enum AEnum T907, &T908;\n"
  },
  {
    "path": "Units/parser-cxx.r/unclosed-angle-bracket.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-cxx.r/unclosed-angle-bracket.d/input.cxx",
    "content": "class<><{[]{class<\n"
  },
  {
    "path": "Units/parser-cxx.r/using-in-template.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=*\n--fields=+stKZ\n--fields-C++=+{template}\n"
  },
  {
    "path": "Units/parser-cxx.r/using-in-template.d/expected.tags",
    "content": "V\tinput.cpp\t/^using V = std::vector<T>;$/;\"\ttypedef\ttyperef:typename:std::vector<T>\tfile:\ttemplate:<class T>\nT\tinput.cpp\t/^template <class T>$/;\"\ttparam\tscope:typedef:V\ttyperef:meta:class\n"
  },
  {
    "path": "Units/parser-cxx.r/using-in-template.d/input.cpp",
    "content": "#include <vector>\n\ntemplate <class T>\nusing V = std::vector<T>;\n"
  },
  {
    "path": "Units/parser-cxx.r/using.cpp.d/args.ctags",
    "content": "--fields=+SKr\n--kinds-C++=+pUN\n--extras=+r\n"
  },
  {
    "path": "Units/parser-cxx.r/using.cpp.d/expected.tags",
    "content": "A\tinput.cpp\t/^class A$/;\"\tclass\tfile:\troles:def\nB\tinput.cpp\t/^class B : public A$/;\"\tclass\tfile:\troles:def\noperator ()\tinput.cpp\t/^\tusing A::operator();$/;\"\tname\tclass:B\troles:def\noperator ()\tinput.cpp\t/^\tvoid operator ()() {};$/;\"\tfunction\tclass:A\ttyperef:typename:void\tfile:\tsignature:()\troles:def\noperator +\tinput.cpp\t/^\tint operator +(int i) { return i; };$/;\"\tfunction\tclass:A\ttyperef:typename:int\tfile:\tsignature:(int i)\troles:def\noperator +\tinput.cpp\t/^\tusing A::operator+;$/;\"\tname\tclass:B\troles:def\nstd\tinput.cpp\t/^using namespace std;$/;\"\tusing\tfile:\troles:def\nstring\tinput.cpp\t/^#include <string>/;\"\theader\troles:system\nstring\tinput.cpp\t/^using std::string;$/;\"\tname\tfile:\troles:def\ntest\tinput.cpp\t/^\tusing A::test;$/;\"\tname\tclass:B\troles:def\ntest\tinput.cpp\t/^\tvoid test();$/;\"\tprototype\tclass:A\ttyperef:typename:void\tfile:\tsignature:()\troles:def\ntest\tinput.cpp\t/^\tvoid test(x t);$/;\"\tprototype\tclass:B\ttyperef:typename:void\tfile:\tsignature:(x t)\troles:def\nx\tinput.cpp\t/^using x = std::string;$/;\"\ttypedef\ttyperef:typename:std::string\tfile:\troles:def\n"
  },
  {
    "path": "Units/parser-cxx.r/using.cpp.d/input.cpp",
    "content": "#include <string>\n\nusing namespace std;\nusing std::string;\nusing x = std::string;\n\nclass A\n{\npublic:\n\tvoid test();\n\tvoid operator ()() {};\n\tint operator +(int i) { return i; };\n};\n\nclass B : public A\n{\npublic:\n\tvoid test(x t);\n\tusing A::test;\n\tusing A::operator();\n\tusing A::operator+;\n};\n"
  },
  {
    "path": "Units/parser-cxx.r/variable-declarations.cpp.d/args.ctags",
    "content": "--kinds-c++=lvm\n\n# for testing that the parser can skip __declspec\n--kinds-c++=+d\n--param-CPreProcessor._expand=true\n--fields=+{signature}\n--fields-c++=+{macrodef}\n"
  },
  {
    "path": "Units/parser-cxx.r/variable-declarations.cpp.d/expected.tags",
    "content": "MY_API\tinput.cpp\t/^#define MY_API /;\"\td\tfile:\tmacrodef:__declspec(dllexport)\nSIZE\tinput.cpp\t/^#define SIZE /;\"\td\tfile:\tmacrodef:25\nl01\tinput.cpp\t/^\tunsigned short int l01;$/;\"\tl\tfunction:main\ttyperef:typename:unsigned short int\tfile:\nl02\tinput.cpp\t/^\tunsigned long long int * const l02 = NULL, * l03 = NULL;$/;\"\tl\tfunction:main\ttyperef:typename:unsigned long long int * const\tfile:\nl03\tinput.cpp\t/^\tunsigned long long int * const l02 = NULL, * l03 = NULL;$/;\"\tl\tfunction:main\ttyperef:typename:unsigned long long int * const *\tfile:\nl04\tinput.cpp\t/^\tregister int ** l04 = 0;$/;\"\tl\tfunction:main\ttyperef:typename:register int **\tfile:\nl05\tinput.cpp\t/^\tstd::string l05;$/;\"\tl\tfunction:main\ttyperef:typename:std::string\tfile:\nl06\tinput.cpp\t/^\tstd::string l06(\"test\");$/;\"\tl\tfunction:main\ttyperef:typename:std::string\tfile:\nl07\tinput.cpp\t/^\tstd::string l07 = \"test\";$/;\"\tl\tfunction:main\ttyperef:typename:std::string\tfile:\nl08\tinput.cpp\t/^\tconst std::string & l08 = l07, l09 = l07;$/;\"\tl\tfunction:main\ttyperef:typename:const std::string &\tfile:\nl09\tinput.cpp\t/^\tconst std::string & l08 = l07, l09 = l07;$/;\"\tl\tfunction:main\ttyperef:typename:const std::string\tfile:\nl10\tinput.cpp\t/^\tconst void * (*l10)() = NULL;$/;\"\tl\tfunction:main\ttyperef:typename:const void * (*)()\tfile:\nl11\tinput.cpp\t/^\tunsigned long int & (*l11)(void *);$/;\"\tl\tfunction:main\ttyperef:typename:unsigned long int & (*)(void *)\tfile:\nl12\tinput.cpp\t/^\tstd::string & (*l12)(void);$/;\"\tl\tfunction:main\ttyperef:typename:std::string & (*)(void)\tfile:\nl13\tinput.cpp\t/^\tstd::string ** (*l13)(int a,int b);$/;\"\tl\tfunction:main\ttyperef:typename:std::string ** (*)(int a,int b)\tfile:\nl14\tinput.cpp\t/^\tstd::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > l14;$/;\"\tl\tfunction:main\ttyperef:typename:std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>\tfile:\nl15\tinput.cpp\t/^\tstruct Struct1 l15;$/;\"\tl\tfunction:main\ttyperef:struct:Struct1\tfile:\nl16\tinput.cpp\t/^\tstruct Struct1 * l16, l17, l18[10];$/;\"\tl\tfunction:main\ttyperef:struct:Struct1 *\tfile:\nl17\tinput.cpp\t/^\tstruct Struct1 * l16, l17, l18[10];$/;\"\tl\tfunction:main\ttyperef:struct:Struct1\tfile:\nl18\tinput.cpp\t/^\tstruct Struct1 * l16, l17, l18[10];$/;\"\tl\tfunction:main\ttyperef:struct:Struct1[10]\tfile:\nl19\tinput.cpp\t/^\tStruct1 l19 = {};$/;\"\tl\tfunction:main\ttyperef:typename:Struct1\tfile:\nl20\tinput.cpp\t/^\tstd::string ** l20[SIZE];$/;\"\tl\tfunction:main\ttyperef:typename:std::string ** [25]\tfile:\nl21\tinput.cpp\t/^\tstd::string l21[1 << 2];$/;\"\tl\tfunction:main\ttyperef:typename:std::string[]\tfile:\nl22\tinput.cpp\t/^\tstd::string * l22[SIZE][SIZE];$/;\"\tl\tfunction:main\ttyperef:typename:std::string * [25][25]\tfile:\nl23\tinput.cpp\t/^\tstd::string l23[5][2];$/;\"\tl\tfunction:main\ttyperef:typename:std::string[5][2]\tfile:\nl24\tinput.cpp\t/^\tstd::string * const l24 = 0;$/;\"\tl\tfunction:main\ttyperef:typename:std::string * const\tfile:\nl25\tinput.cpp\t/^\twchar_t l25[] = { L\"кошка\" };$/;\"\tl\tfunction:main\ttyperef:typename:wchar_t[]\tfile:\nl26\tinput.cpp\t/^\twchar_t l26[] { L'к', L'о', L'ш', L'к', L'а', L'\\\\0' };$/;\"\tl\tfunction:main\ttyperef:typename:wchar_t[]\tfile:\nl27\tinput.cpp\t/^\tstd::string l27[] = { std::string(\"one\"),\"two\",{'t', 'h', 'r', 'e', 'e'} };$/;\"\tl\tfunction:main\ttyperef:typename:std::string[]\tfile:\nl28\tinput.cpp\t/^\tint l28 {};$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nl29\tinput.cpp\t/^\tbool l29 { false };$/;\"\tl\tfunction:main\ttyperef:typename:bool\tfile:\nl30\tinput.cpp\t/^\tstd::string * l30{ new std::string(\"test\") };$/;\"\tl\tfunction:main\ttyperef:typename:std::string *\tfile:\nl31\tinput.cpp\t/^\tstd::string * l31(new std::string(\"test\"));$/;\"\tl\tfunction:main\ttyperef:typename:std::string *\tfile:\nl32\tinput.cpp\t/^\tauto l32 = new std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >;$/;\"\tl\tfunction:main\ttyperef:typename:auto\tfile:\nl32_33_0\tinput.cpp\t/^class MY_API n06 l32_33_0;$/;\"\tv\ttyperef:class:n06\nl32_33_1\tinput.cpp\t/^class __declspec(dllexport) n07 l32_33_1;$/;\"\tv\ttyperef:class:n07\nl33\tinput.cpp\t/^\tvoid (Struct1::*l33)() = NULL;$/;\"\tl\tfunction:anotherFunc\ttyperef:typename:void (Struct1::*)()\tfile:\nl34\tinput.cpp\t/^\tvoid (Struct1::*l34)(int) = NULL;$/;\"\tl\tfunction:anotherFunc\ttyperef:typename:void (Struct1::*)(int)\tfile:\nl35\tinput.cpp\t/^\tdecltype(l36) l35;$/;\"\tl\tfunction:anotherFunc\ttyperef:typename:decltype(l36)\tfile:\nl35\tinput.cpp\t/^\tint (Struct1::*l35)(int) = NULL;$/;\"\tl\tfunction:anotherFunc\ttyperef:typename:int (Struct1::*)(int)\tfile:\nm01\tinput.cpp\t/^\tunsigned int m01;$/;\"\tm\tstruct:Struct1\ttyperef:typename:unsigned int\tfile:\nm02\tinput.cpp\t/^\tstd::string m02;$/;\"\tm\tstruct:Struct1\ttyperef:typename:std::string\tfile:\nm03\tinput.cpp\t/^\tstd::string ** m03, m04;$/;\"\tm\tstruct:Struct1\ttyperef:typename:std::string **\tfile:\nm04\tinput.cpp\t/^\tstd::string ** m03, m04;$/;\"\tm\tstruct:Struct1\ttyperef:typename:std::string\tfile:\nm05\tinput.cpp\t/^\tstd::string & (*m05)(int a,int b);$/;\"\tm\tstruct:Struct1\ttyperef:typename:std::string & (*)(int a,int b)\tfile:\nm06\tinput.cpp\t/^\tstd::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > m06[10];$/;\"\tm\tstruct:Struct1\ttyperef:typename:std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>[10]\tfile:\nm07\tinput.cpp\t/^\tstd::string m07 { \"test\" }; \\/\\/ C++11$/;\"\tm\tstruct:Struct1\ttyperef:typename:std::string\tfile:\nm08\tinput.cpp\t/^\tstd::string m08[2] { \"a\", \"b\" };$/;\"\tm\tstruct:Struct1\ttyperef:typename:std::string[2]\tfile:\nm09\tinput.cpp\t/^\tint m09 {};$/;\"\tm\tstruct:Struct1\ttyperef:typename:int\tfile:\nm10\tinput.cpp\t/^\tint m10[2][2]{{1, 2}, {3, 4}};$/;\"\tm\tstruct:Struct1\ttyperef:typename:int[2][2]\tfile:\nm11\tinput.cpp\t/^\tstd::array<int, 3> m11 { {1,2,3} };$/;\"\tm\tstruct:Struct1\ttyperef:typename:std::array<int,3>\tfile:\nm12\tinput.cpp\t/^\tstd::string m12[3] { std::string(\"one\"),\"two\",{'t', 'h', 'r', 'e', 'e'} };$/;\"\tm\tstruct:Struct1\ttyperef:typename:std::string[3]\tfile:\nm13\tinput.cpp\t/^\tint m13 {false};$/;\"\tm\tstruct:Struct1\ttyperef:typename:int\tfile:\nm14\tinput.cpp\t/^\tstd::string * m14 { new std::string(\"test\") };$/;\"\tm\tstruct:Struct1\ttyperef:typename:std::string *\tfile:\nm15\tinput.cpp\t/^\tdecltype(int) m15;$/;\"\tm\tstruct:Struct1\ttyperef:typename:decltype(int)\tfile:\nv01\tinput.cpp\t/^} v01, v02[10];$/;\"\tv\ttyperef:struct:Struct1\nv02\tinput.cpp\t/^} v01, v02[10];$/;\"\tv\ttyperef:struct:Struct1[10]\nv03\tinput.cpp\t/^} v03, * v04;$/;\"\tv\ttyperef:enum:Enum1\nv04\tinput.cpp\t/^} v03, * v04;$/;\"\tv\ttyperef:enum:Enum1 *\nv05\tinput.cpp\t/^struct Struct1 v05, * v06 = NULL;$/;\"\tv\ttyperef:struct:Struct1\nv06\tinput.cpp\t/^struct Struct1 v05, * v06 = NULL;$/;\"\tv\ttyperef:struct:Struct1 *\nv07\tinput.cpp\t/^std::string v07(\"test\"), v08(\"test\");$/;\"\tv\ttyperef:typename:std::string\nv08\tinput.cpp\t/^std::string v07(\"test\"), v08(\"test\");$/;\"\tv\ttyperef:typename:std::string\nv09\tinput.cpp\t/^std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > ** v09;$/;\"\tv\ttyperef:typename:std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> **\n"
  },
  {
    "path": "Units/parser-cxx.r/variable-declarations.cpp.d/input.cpp",
    "content": "#include <string>\n#include <array>\n\n// All the m*, l* and v* are valid variable declarations. The n* are NOT valid declarations.\n\nstruct Struct1\n{\n\tunsigned int m01;\n\tstd::string m02;\n\tstd::string ** m03, m04;\n\tstd::string & (*m05)(int a,int b);\n\tstd::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > m06[10];\n\tstd::string m07 { \"test\" }; // C++11\n\tstd::string m08[2] { \"a\", \"b\" };\n\tint m09 {};\n\tint m10[2][2]{{1, 2}, {3, 4}};\n\tstd::array<int, 3> m11 { {1,2,3} };\n\tstd::string m12[3] { std::string(\"one\"),\"two\",{'t', 'h', 'r', 'e', 'e'} };\n\tint m13 {false};\n\tstd::string * m14 { new std::string(\"test\") };\n\tdecltype(int) m15;\n} v01, v02[10];\n\nenum Enum1\n{\n\tE1\n} v03, * v04;\n\nstruct Struct1 v05, * v06 = NULL;\nstd::string v07(\"test\"), v08(\"test\");\nstd::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > ** v09;\n\nint main(int argc,char ** argv)\n{\n\tunsigned short int l01;\n\tunsigned long long int * const l02 = NULL, * l03 = NULL;\n\tregister int ** l04 = 0;\n\n\tstd::string l05;\n\tstd::string l06(\"test\");\n\tstd::string l07 = \"test\";\n\tconst std::string & l08 = l07, l09 = l07;\n\n\tconst void * (*l10)() = NULL;\n\tunsigned long int & (*l11)(void *);\n\tstd::string & (*l12)(void);\n\tstd::string ** (*l13)(int a,int b);\n\n\tstd::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > l14;\n\n\tstruct Struct1 l15;\n\tstruct Struct1 * l16, l17, l18[10];\n\tStruct1 l19 = {};\n\n#define SIZE 25\n\tstd::string ** l20[SIZE];\n\tstd::string l21[1 << 2];\n\tstd::string * l22[SIZE][SIZE];\n\tstd::string l23[5][2];\n\tstd::string * const l24 = 0;\n\n\twchar_t l25[] = { L\"кошка\" };\n\twchar_t l26[] { L'к', L'о', L'ш', L'к', L'а', L'\\0' };\n\tstd::string l27[] = { std::string(\"one\"),\"two\",{'t', 'h', 'r', 'e', 'e'} };\n\tint l28 {};\n\tbool l29 { false };\n\tstd::string * l30{ new std::string(\"test\") };\n\tstd::string * l31(new std::string(\"test\"));\n\n\tauto l32 = new std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >;\n\n\treturn 0;\n}\n\n// All of these are NOT valid variable declarations (but still valid C++)\ntypedef struct X n01;\ntypedef unsigned short int n02;\ntypedef enum Enum1 n03;\n\n#define MY_API __declspec(dllexport)\nclass MY_API n04;\n\n// This would be nice: parse inside a block surrounded by ifdef/endif.\n// #ifdef _MSVC\n\tclass __declspec(dllexport) n05;\n// #endif\n\nclass MY_API n06 l32_33_0;\nclass __declspec(dllexport) n07 l32_33_1;\n\n// Note that function parameters are NOT extracted in this test.\n\ntemplate<typename X> X func(X p1)\n{\n\treturn p1+1;\n}\n\nint anotherFunc(int n06)\n{\n\tfunc<int>(n06);\n\n\tvoid (Struct1::*l33)() = NULL;\n\tvoid (Struct1::*l34)(int) = NULL;\n\tint (Struct1::*l35)(int) = NULL;\n\tdecltype(l36) l35;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/variable-templates.d/args.ctags",
    "content": "--sort=no\n--fields-C++=+{properties}{specialization}{template}\n--kinds-C++=+Z\n"
  },
  {
    "path": "Units/parser-cxx.r/variable-templates.d/expected.tags",
    "content": "chip\tinput.cpp\t/^enum chip {$/;\"\tg\tfile:\nA6XX\tinput.cpp\t/^\tA6XX = 6,$/;\"\te\tenum:chip\tfile:\nA7XX\tinput.cpp\t/^\tA7XX = 7,$/;\"\te\tenum:chip\tfile:\nCMD_REGS\tinput.cpp\t/^template<chip CHIP>  int CMD_REGS[] = {};$/;\"\tv\ttyperef:typename:int[]\ttemplate:<chip CHIP>\nCHIP\tinput.cpp\t/^template<chip CHIP>  int CMD_REGS[] = {};$/;\"\tZ\tvariable:CMD_REGS\ttyperef:typename:chip\nCMD_REGS\tinput.cpp\t/^template<>           int CMD_REGS<A6XX>[] = {$/;\"\tv\ttyperef:typename:int[]\tproperties:specialization\ttemplate:<>\tspecialization:<A6XX>\nCMD_REGS\tinput.cpp\t/^template<>           int CMD_REGS<A7XX>[][1] = {$/;\"\tv\ttyperef:typename:int[][1]\tproperties:specialization\ttemplate:<>\tspecialization:<A7XX>\nmain\tinput.cpp\t/^int main(void)$/;\"\tf\ttyperef:typename:int\nis_integral_v\tinput-0.cpp\t/^constexpr bool is_integral_v = false;$/;\"\tv\ttyperef:typename:bool\tproperties:constexpr\ttemplate:<class T>\nT\tinput-0.cpp\t/^template <class T>$/;\"\tZ\tvariable:is_integral_v\ttyperef:meta:class\nis_integral_v\tinput-0.cpp\t/^constexpr bool is_integral_v<int> = true;$/;\"\tv\ttyperef:typename:bool\tproperties:specialization,constexpr\ttemplate:<>\tspecialization:<int>\nmain\tinput-0.cpp\t/^int main()$/;\"\tf\ttyperef:typename:int\nzero\tinput-1.cpp\t/^constexpr T zero = 0;$/;\"\tv\ttyperef:typename:T\tproperties:constexpr\ttemplate:<class T>\nT\tinput-1.cpp\t/^template <class T>$/;\"\tZ\tvariable:zero\ttyperef:meta:class\nzero\tinput-1.cpp\t/^constexpr T* zero<T*> = nullptr;$/;\"\tv\ttyperef:typename:T *\tproperties:specialization,constexpr\ttemplate:<class T>\tspecialization:<T*>\nT\tinput-1.cpp\t/^template <class T>$/;\"\tZ\tvariable:zero\ttyperef:meta:class\nmain\tinput-1.cpp\t/^int main() {$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-cxx.r/variable-templates.d/input-0.cpp",
    "content": "// Taken from https://cpprefjp.github.io/lang/cpp14/variable_templates.html\ntemplate <class T>\nconstexpr bool is_integral_v = false;\n\ntemplate <>\nconstexpr bool is_integral_v<int> = true;\n\nint main()\n{\n  if (is_integral_v<int>) {}\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/variable-templates.d/input-1.cpp",
    "content": "// Taken from https://cpprefjp.github.io/lang/cpp23/generalized_wording_for_partial_specializations.html\n#include <iostream>\n\ntemplate <class T>\nconstexpr T zero = 0;\n\ntemplate <class T>\nconstexpr T* zero<T*> = nullptr;\n\nint main() {\n  int x = zero<int>;\n  int* y = zero<int*>;\n\n  std::cout << x << std::endl;\n  std::cout << y << std::endl;\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/variable-templates.d/input.cpp",
    "content": "enum chip {\n\tA6XX = 6,\n\tA7XX = 7,\n};\n\ntemplate<chip CHIP>  int CMD_REGS[] = {};\ntemplate<>           int CMD_REGS<A6XX>[] = {\n\t0x3,\n};\n\ntemplate<>           int CMD_REGS<A7XX>[][1] = {\n  {0x4},\n};\n\nint main(void)\n{\n  return CMD_REGS<A6XX>[0];\n}\n"
  },
  {
    "path": "Units/parser-cxx.r/variables-in-control-statements.d/args.ctags",
    "content": "--kinds-C++=l\n"
  },
  {
    "path": "Units/parser-cxx.r/variables-in-control-statements.d/expected.tags",
    "content": "f01\tinput.cpp\t/^\tfor(int f01=0;f01<10;f01++)$/;\"\tl\tfunction:test\ttyperef:typename:int\tfile:\nf02\tinput.cpp\t/^\tfor(int f02 = getUShort(), * f03 = getPointer();f03 < (getPointer() + 10);f03++)$/;\"\tl\tfunction:test\ttyperef:typename:int\tfile:\nf03\tinput.cpp\t/^\tfor(int f02 = getUShort(), * f03 = getPointer();f03 < (getPointer() + 10);f03++)$/;\"\tl\tfunction:test\ttyperef:typename:int *\tfile:\nf04\tinput.cpp\t/^\tfor(int f04=0,f05=5,f06=10;f04<10;f04++)$/;\"\tl\tfunction:test\ttyperef:typename:int\tfile:\nf05\tinput.cpp\t/^\tfor(int f04=0,f05=5,f06=10;f04<10;f04++)$/;\"\tl\tfunction:test\ttyperef:typename:int\tfile:\nf06\tinput.cpp\t/^\tfor(int f04=0,f05=5,f06=10;f04<10;f04++)$/;\"\tl\tfunction:test\ttyperef:typename:int\tfile:\nf07\tinput.cpp\t/^\tfor(std::string f07 = \"test\";;)$/;\"\tl\tfunction:test\ttyperef:typename:std::string\tfile:\nf09\tinput.cpp\t/^\tfor(std::unique_ptr<int> f09 = 0;;)$/;\"\tl\tfunction:test\ttyperef:typename:std::unique_ptr<int>\tfile:\nf10\tinput.cpp\t/^\tfor(std::unique_ptr<int> f10(getPointer());;)$/;\"\tl\tfunction:test\ttyperef:typename:std::unique_ptr<int>\tfile:\nf11\tinput.cpp\t/^\tfor(std::pair<int,int> f11;;)$/;\"\tl\tfunction:test\ttyperef:typename:std::pair<int,int>\tfile:\ni01\tinput.cpp\t/^\tif(int i01 = 10 + 20)$/;\"\tl\tfunction:test\ttyperef:typename:int\tfile:\ni02\tinput.cpp\t/^\tif(INT * i02 = 0)$/;\"\tl\tfunction:test\ttyperef:typename:INT *\tfile:\ni03\tinput.cpp\t/^\tif(INT & i03 = n01)$/;\"\tl\tfunction:test\ttyperef:typename:INT &\tfile:\nw01\tinput.cpp\t/^\twhile(unsigned short int w01 = getUShort())$/;\"\tl\tfunction:test\ttyperef:typename:unsigned short int\tfile:\n"
  },
  {
    "path": "Units/parser-cxx.r/variables-in-control-statements.d/input.cpp",
    "content": "#include <string>\n#include <memory>\n\n// Helpers (should be hidden in ctags output)\n\nunsigned short int getUShort()\n{\n\treturn 10;\n}\n\nint * getPointer()\n{\n\treturn 0;\n}\n\nint n01;\nunsigned short n02;\nint * n03;\n\ntypedef int INT;\n\nint n04()\n{\n\treturn 0;\n}\n\nint n05,n06,n07,n08,n09,n10,n11,n12,n13,n14,n15,n16;\n\ntemplate<typename T> func(int no){ return no; };\n\n// The real test starts here\n\nvoid test()\n{\n\t// Valid variable declarations inside a for loop control structure\n\tfor(int f01=0;f01<10;f01++)\n\t{\n\t}\n\n\tfor(int f02 = getUShort(), * f03 = getPointer();f03 < (getPointer() + 10);f03++)\n\t{\n\t}\n\n\tfor(int f04=0,f05=5,f06=10;f04<10;f04++)\n\t{\n\t}\n\n\tfor(std::string f07 = \"test\";;)\n\t{\n\t}\n\n\tfor(int f08 : { 1,2,3,4,5 })\n\t{\n\t}\n\n\tfor(std::unique_ptr<int> f09 = 0;;)\n\t{\n\t}\n\n\tfor(std::unique_ptr<int> f10(getPointer());;)\n\t{\n\t}\n\n\tfor(std::pair<int,int> f11;;)\n\t{\n\t}\n\n\tfor(auto f12 : { 't','e','s','t' })\n\t{\n\t}\n\n\t// Non valid variable declarations inside for\n\tfor(;;)\n\t{\n\t}\n\n\tfor(n01 = 0;n01 < 10;n01++)\n\t{\n\t}\n\n\tfor(n02 = getUShort(), n03 = getPointer();;)\n\t{\n\t}\n\n\tfor(n04();n04();)\n\t{\n\t}\n\n\t// Valid variable declaration inside an if\n\tif(int i01 = 10 + 20)\n\t{\n\t}\n\n\tif(INT * i02 = 0)\n\t{\n\t}\n\n\tif(INT & i03 = n01)\n\t{\n\t}\n\n\t// non valid declarations inside if\n\tif(n05 & n06)\n\t{\n\t}\n\n\tif(n07 * n08)\n\t{\n\t}\n\n\tif(n09 && n10)\n\t{\n\t}\n\n\tif(n11 < n12 || n13 > n14)\n\t{\n\t}\n\n\tif(static_cast<short>(n15) < n14)\n\t{\n\t}\n\n\tif(func<int>(n16))\n\t{\n\t}\n\n\t// Valid variable declarations inside a while\n\twhile(unsigned short int w01 = getUShort())\n\t{\n\t}\n}"
  },
  {
    "path": "Units/parser-cxx.r/variables-prototypes-2.cpp.d/args.ctags",
    "content": "--kinds-c++=+plv\n--fields=SKn\n"
  },
  {
    "path": "Units/parser-cxx.r/variables-prototypes-2.cpp.d/expected.tags",
    "content": "listOfStrings\tinput.cpp\t/^\tList<String> listOfStrings(argv); \\/\\/ local$/;\"\tlocal\tline:4\nmain\tinput.cpp\t/^int  main( int  argc, char ** argv )$/;\"\tfunction\tline:1\tsignature:(int argc,char ** argv)\nsample\tinput.cpp\t/^\tString sample(argc); \\/\\/ local$/;\"\tlocal\tline:3\n"
  },
  {
    "path": "Units/parser-cxx.r/variables-prototypes-2.cpp.d/input.cpp",
    "content": "int  main( int  argc, char ** argv )\n{\n\tString sample(argc); // local\n\tList<String> listOfStrings(argv); // local\n\n\tforeach(String * p,listOfStrings) // NOT a prototype\n\t{\n\t\tp->dump(); // NOT a prototype\n\t}\n\n}"
  },
  {
    "path": "Units/parser-cxx.r/variables-prototypes.cpp.b/args.ctags",
    "content": "--kinds-c++=+pl\n--fields=+S\n"
  },
  {
    "path": "Units/parser-cxx.r/variables-prototypes.cpp.b/expected.tags",
    "content": "A1\tinput.cpp\t/^int  A1 = i < 7 ? i : 7;$/;\"\tv\nA2\tinput.cpp\t/^int  A2 = 8;$/;\"\tv\nA3\tinput.cpp\t/^int  A3 = 9;$/;\"\tv\nA4\tinput.cpp\t/^int  A4 = p->data;$/;\"\tv\nA5\tinput.cpp\t/^int  A5 = 8;$/;\"\tv\nA6\tinput.cpp\t/^int ( *A6 )( int, char ** ) = &main;$/;\"\tv\nA7\tinput.cpp\t/^int  A7( short ( *p )( int ) );$/;\"\tp\tfile:\tsignature:( short ( *p )( int ) )\nB1\tinput.cpp\t/^const char *B1( \"uuu\" );                \\/\\/variable$/;\"\tv\nB2\tinput.cpp\t/^int B2( int ooo, const char* o );       \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int ooo, const char* o )\nB3\tinput.cpp\t/^int B3( int( 7 ) );                     \\/\\/variable$/;\"\tv\nC1\tinput.cpp\t/^int C1( a >> ooo );                     \\/\\/variable$/;\"\tv\nC2\tinput.cpp\t/^int C2( int * h );                      \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int * h )\nC3\tinput.cpp\t/^int C3( std::map<int>( 9 ) );           \\/\\/variable$/;\"\tv\nC4\tinput.cpp\t/^int C4( std::map<int> a );              \\/\\/prototype$/;\"\tp\tfile:\tsignature:( std::map<int> a )\nC5\tinput.cpp\t/^int C5( map<int>  & a );                \\/\\/prototype$/;\"\tp\tfile:\tsignature:( map<int> & a )\nC6\tinput.cpp\t/^int C6( ooo & a );                      \\/\\/prototype$/;\"\tp\tfile:\tsignature:( ooo & a )\nC7\tinput.cpp\t/^int C7( int & a );                      \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int & a )\nC8\tinput.cpp\t/^int C8( map<int> a );                   \\/\\/prototype$/;\"\tp\tfile:\tsignature:( map<int> a )\nC9\tinput.cpp\t/^int C9( int a );                        \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int a )\nD1\tinput.cpp\t/^ind D1( a * 2 );                        \\/\\/variable$/;\"\tv\nD2\tinput.cpp\t/^ind D2( \"a\" * 2 );                      \\/\\/variable$/;\"\tv\nD3\tinput.cpp\t/^int D3( *j );                           \\/\\/variable$/;\"\tv\nF1\tinput.cpp\t/^int F1( SomeType (*p)( int ) );         \\/\\/prototype$/;\"\tp\tfile:\tsignature:( SomeType (*p)( int ) )\nF2\tinput.cpp\t/^SomeType (*F2)( int o );                \\/\\/variable$/;\"\tv\nF3\tinput.cpp\t/^int F3( std::map<int> & a );            \\/\\/prototype$/;\"\tp\tfile:\tsignature:( std::map<int> & a )\nG1\tinput.cpp\t/^int G1( SomeType a );                   \\/\\/prototype$/;\"\tp\tfile:\tsignature:( SomeType a )\nH1\tinput.cpp\t/^char H1( const char *a = \"a\" );         \\/\\/prototype$/;\"\tp\tfile:\tsignature:( const char *a = <String> )\nH2\tinput.cpp\t/^int H2();                               \\/\\/prototype$/;\"\tp\tfile:\tsignature:()\nH3\tinput.cpp\t/^char H3( double );                      \\/\\/prototype$/;\"\tp\tfile:\tsignature:( double )\nH4\tinput.cpp\t/^int H4( h u );                          \\/\\/prototype$/;\"\tp\tfile:\tsignature:( h u )\nP1\tinput.cpp\t/^int (*P1)( int o );                     \\/\\/variable$/;\"\tv\nV4\tinput.cpp\t/^int V4( iii( 'o' ) );                   \\/\\/variable$/;\"\tv\nV5\tinput.cpp\t/^int V5( iii( o ) );                     \\/\\/variable$/;\"\tv\nV6\tinput.cpp\t/^int V6( int (*p)( int ) );              \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int (*p)( int ) )\nV7\tinput.cpp\t/^int V7( 89 );                           \\/\\/variable$/;\"\tv\nV8\tinput.cpp\t/^int V8( ooo );                          \\/\\/variable$/;\"\tv\nW1\tinput.cpp\t/^int W1 __ARGS (( int a )){}             \\/\\/function$/;\"\tf\tsignature:( int a )\nW2\tinput.cpp\t/^int W2 (( a - 5 ) \\/ 6 );                \\/\\/variable$/;\"\tv\nX1\tinput.cpp\t/^int X1( a.b );                          \\/\\/variable$/;\"\tv\nX2\tinput.cpp\t/^int X2( a->b );                         \\/\\/variable$/;\"\tv\nX3\tinput.cpp\t/^int X3( NS::a  b );                     \\/\\/prototype$/;\"\tp\tfile:\tsignature:( NS::a b )\nX4\tinput.cpp\t/^int X4( a ^ b );                        \\/\\/variable $/;\"\tv\nX5\tinput.cpp\t/^int X5( a ^ 6 );                        \\/\\/variable$/;\"\tv\nX6\tinput.cpp\t/^int X6( a | b );                        \\/\\/variable$/;\"\tv\nX8\tinput.cpp\t/^int X8( a & b & 2 );                    \\/\\/variable$/;\"\tv\nX9\tinput.cpp\t/^int X9( a && b );                       \\/\\/variable$/;\"\tv\na1\tinput.cpp\t/^    int  a1 = i < 7 ? i : 7;$/;\"\tl\na2\tinput.cpp\t/^    int  a2 = 8;$/;\"\tl\na3\tinput.cpp\t/^    int  a3 = 9;$/;\"\tl\na4\tinput.cpp\t/^    int  a4 = p->data;$/;\"\tl\na5\tinput.cpp\t/^    int  a5 = 8;$/;\"\tl\na6\tinput.cpp\t/^    int ( *a6 )( int, char ** ) = &main;$/;\"\tl\na7\tinput.cpp\t/^    int  a7( short ( *p )( int ) );$/;\"\tp\tfile:\tsignature:( short ( *p )( int ) )\na8\tinput.cpp\t/^    short a8 = i;$/;\"\tl\nb1\tinput.cpp\t/^    const char *b1( \"uuu\" );                \\/\\/variable$/;\"\tl\nb2\tinput.cpp\t/^    int b2( int ooo, const char* o );       \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int ooo, const char* o )\nb3\tinput.cpp\t/^    int b3( int( 7 ) );                     \\/\\/variable$/;\"\tl\nc1\tinput.cpp\t/^    int c1( a >> ooo );                     \\/\\/variable$/;\"\tl\nc2\tinput.cpp\t/^    int c2( int * h );                      \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int * h )\nc3\tinput.cpp\t/^    int c3( std::map<int>( 9 ) );           \\/\\/variable$/;\"\tl\nc4\tinput.cpp\t/^    int c4( std::map<int> a );              \\/\\/prototype$/;\"\tp\tfile:\tsignature:( std::map<int> a )\nc5\tinput.cpp\t/^    int c5( map<int>  & a );                \\/\\/prototype$/;\"\tp\tfile:\tsignature:( map<int> & a )\nc6\tinput.cpp\t/^    int c6( ooo & a );                      \\/\\/prototype$/;\"\tp\tfile:\tsignature:( ooo & a )\nc7\tinput.cpp\t/^    int c7( int & a );                      \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int & a )\nc8\tinput.cpp\t/^    int c8( map<int> a );                   \\/\\/prototype$/;\"\tp\tfile:\tsignature:( map<int> a )\nc9\tinput.cpp\t/^    int c9( int a );                        \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int a )\nd1\tinput.cpp\t/^    ind d1( a * 2 );                        \\/\\/variable$/;\"\tl\nd2\tinput.cpp\t/^    ind d2( \"a\" * 2 );                      \\/\\/variable$/;\"\tl\nd3\tinput.cpp\t/^    int d3( *j );                           \\/\\/variable$/;\"\tl\nf1\tinput.cpp\t/^    int f1( SomeType (*p)( int ) );         \\/\\/prototype$/;\"\tp\tfile:\tsignature:( SomeType (*p)( int ) )\nf2\tinput.cpp\t/^    SomeType (*f2)( int o );                \\/\\/variable$/;\"\tl\nf3\tinput.cpp\t/^    int f3( std::map<int> & a );            \\/\\/prototype$/;\"\tp\tfile:\tsignature:( std::map<int> & a )\ng1\tinput.cpp\t/^    int g1( SomeType a );                   \\/\\/prototype$/;\"\tp\tfile:\tsignature:( SomeType a )\nh1\tinput.cpp\t/^    char h1( const char *a = \"a\" );         \\/\\/prototype$/;\"\tp\tfile:\tsignature:( const char *a = <String> )\nh2\tinput.cpp\t/^    int h2();                               \\/\\/prototype$/;\"\tp\tfile:\tsignature:()\nh3\tinput.cpp\t/^    char h3( double );                      \\/\\/prototype$/;\"\tp\tfile:\tsignature:( double )\nh4\tinput.cpp\t/^    int h4( h u );                          \\/\\/prototype$/;\"\tp\tfile:\tsignature:( h u )\nmain\tinput.cpp\t/^int  main( int  argc, char ** argv )$/;\"\tf\tsignature:( int argc, char ** argv )\np1\tinput.cpp\t/^    int (*p1)( int o );                     \\/\\/variable$/;\"\tl\nv4\tinput.cpp\t/^    int v4( iii( 'o' ) );                   \\/\\/variable$/;\"\tl\nv5\tinput.cpp\t/^    int v5( iii( o ) );                     \\/\\/variable$/;\"\tl\nv6\tinput.cpp\t/^    int v6( int (*p)( int ) );              \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int (*p)( int ) )\nv7\tinput.cpp\t/^    int v7( 89 );                           \\/\\/variable$/;\"\tl\nv8\tinput.cpp\t/^    int v8( ooo );                          \\/\\/variable$/;\"\tl\nw1\tinput.cpp\t/^    int w1 __ARGS (( int a ));              \\/\\/prototype$/;\"\tp\tfile:\tsignature:( int a )\nw2\tinput.cpp\t/^    int w2 (( a - 5 ) \\/ 6 );                \\/\\/variable$/;\"\tl\nx1\tinput.cpp\t/^    int x1( a.b );                          \\/\\/variable$/;\"\tl\nx2\tinput.cpp\t/^    int x2( a->b );                         \\/\\/variable$/;\"\tl\nx3\tinput.cpp\t/^    int x3( NS::a  b );                     \\/\\/prototype$/;\"\tp\tfile:\tsignature:( NS::a b )\nx4\tinput.cpp\t/^    int x4( a ^ b );                        \\/\\/variable $/;\"\tl\nx5\tinput.cpp\t/^    int x5( a ^ 6 );                        \\/\\/variable$/;\"\tl\nx6\tinput.cpp\t/^    int x6( a | b );                        \\/\\/variable$/;\"\tl\nx8\tinput.cpp\t/^    int x8( a & b & 2 );                    \\/\\/variable$/;\"\tl\nx9\tinput.cpp\t/^    int x9( a && b );                       \\/\\/variable$/;\"\tl\n"
  },
  {
    "path": "Units/parser-cxx.r/variables-prototypes.cpp.b/input.cpp",
    "content": "int  main( int  argc, char ** argv )\n{\n    // 1. Angle brackets handling bug\n    // As of now a2, a3 and a4 will be skipped\n\n    int  a1 = i < 7 ? i : 7;\n    int  a2 = 8;\n    int  a3 = 9;\n    int  a4 = p->data;\n    int  a5 = 8;\n\n\n    // 2. Function pointer decl bug\n    // As of now a6 will be skipped\n\n    int ( *a6 )( int, char ** ) = &main;\n\n\n    // 3. Wrong prototype will be written\n    // As of now prototype will be ( SomeType ( p )( int ) )\n\n    int  a7( short ( *p )( int ) );\n\n\n    // 4. DECL_IGNORE bug\n    // As of now a8 will be skipped\n\n    if ( argc > 0 )\n        return 0;\n\n    short a8 = i;\n\n\n    // 5. Local variables support\n\t// As of now all the identifiers below are either reported as prototypes,\n\t// or not recognized at all\n\t// The comments on the right specify which kind of tag should be generated\n\n    const char *b1( \"uuu\" );                //variable\n    int b2( int ooo, const char* o );       //prototype\n    int b3( int( 7 ) );                     //variable\n    int c1( a >> ooo );                     //variable\n    int c2( int * h );                      //prototype\n    int c3( std::map<int>( 9 ) );           //variable\n    int c4( std::map<int> a );              //prototype\n    int c5( map<int>  & a );                //prototype\n    int c6( ooo & a );                      //prototype (ambiguous)\n    int c7( int & a );                      //prototype\n    int c8( map<int> a );                   //prototype\n    int c9( int a );                        //prototype\n    ind d1( a * 2 );                        //variable\n    ind d2( \"a\" * 2 );                      //variable\n    int d3( *j );                           //variable\n    int f1( SomeType (*p)( int ) );         //prototype\n    SomeType (*f2)( int o );                //variable\n    int f3( std::map<int> & a );            //prototype\n    int g1( SomeType a );                   //prototype\n\t// As of now, the signature of h1 will be \"( int a = R )\",\n\t// 'R' is to be replaced by something clearer to denote a\n\t// string literal\n    char h1( const char *a = \"a\" );         //prototype\n    int h2();                               //prototype\n    char h3( double );                      //prototype\n    int h4( h u );                          //prototype\n    int (*p1)( int o );                     //variable\n    int v4( iii( 'o' ) );                   //variable\n    int v5( iii( o ) );                     //variable\n    int v6( int (*p)( int ) );              //prototype\n    int v7( 89 );                           //variable\n    int v8( ooo );                          //variable\n    // __ARGS(x) is a compatibility macro which optionally\n\t// expands to x when prototypes are supported, so\n\t// w1 should be parsed as a prototype\n    int w1 __ARGS (( int a ));              //prototype\n    int w2 (( a - 5 ) / 6 );                //variable\n    int x1( a.b );                          //variable\n    int x2( a->b );                         //variable\n    int x3( NS::a  b );                     //prototype\n    int x4( a ^ b );                        //variable \n    int x5( a ^ 6 );                        //variable\n    int x6( a | b );                        //variable\n\t// As of now, x7 is not recognized at all; it should\n\t// give a variable tag but it's tricky to get it\n\t// right because of '&' which suggests a prototype,\n\t// so for now let's just ignore it\n    //int x7( a & b & c );                  //variable\n    int x8( a & b & 2 );                    //variable\n    int x9( a && b );                       //variable\n}\n\n/* \n * Below is a copy/paste of the local identifiers above made uppercase,\n * but with a global scope instead.\n */\n\n// 1. Angle brackets handling bug\nint  A1 = i < 7 ? i : 7;\nint  A2 = 8;\nint  A3 = 9;\nint  A4 = p->data;\nint  A5 = 8;\n\n\n// 2. Function pointer decl bug\nint ( *A6 )( int, char ** ) = &main;\n\n\n// 3. Wrong prototype will be written\nint  A7( short ( *p )( int ) );\n\n\n// 4. Global variables support\nconst char *B1( \"uuu\" );                //variable\nint B2( int ooo, const char* o );       //prototype\nint B3( int( 7 ) );                     //variable\nint C1( a >> ooo );                     //variable\nint C2( int * h );                      //prototype\nint C3( std::map<int>( 9 ) );           //variable\nint C4( std::map<int> a );              //prototype\nint C5( map<int>  & a );                //prototype\nint C6( ooo & a );                      //prototype (ambiguous)\nint C7( int & a );                      //prototype\nint C8( map<int> a );                   //prototype\nint C9( int a );                        //prototype\nind D1( a * 2 );                        //variable\nind D2( \"a\" * 2 );                      //variable\nint D3( *j );                           //variable\nint F1( SomeType (*p)( int ) );         //prototype\nSomeType (*F2)( int o );                //variable\nint F3( std::map<int> & a );            //prototype\nint G1( SomeType a );                   //prototype\nchar H1( const char *a = \"a\" );         //prototype\nint H2();                               //prototype\nchar H3( double );                      //prototype\nint H4( h u );                          //prototype\nint (*P1)( int o );                     //variable\nint V4( iii( 'o' ) );                   //variable\nint V5( iii( o ) );                     //variable (ambiguous)\nint V6( int (*p)( int ) );              //prototype\nint V7( 89 );                           //variable\nint V8( ooo );                          //variable (ambiguous)\nint W1 __ARGS (( int a )){}             //function\nint W2 (( a - 5 ) / 6 );                //variable\nint X1( a.b );                          //variable\nint X2( a->b );                         //variable\nint X3( NS::a  b );                     //prototype\nint X4( a ^ b );                        //variable \nint X5( a ^ 6 );                        //variable\nint X6( a | b );                        //variable\n//int X7( a & b & c );                  //variable\nint X8( a & b & 2 );                    //variable\nint X9( a && b );                       //variable (ambiguous in C++)\n"
  },
  {
    "path": "Units/parser-d.r/d-accessmod.d/args.ctags",
    "content": "--fields=nksSaf\n"
  },
  {
    "path": "Units/parser-d.r/d-accessmod.d/expected.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tDarren Hiebert\t/dhiebert@users.sourceforge.net/\n!_TAG_PROGRAM_NAME\tExuberant Ctags\t//\n!_TAG_PROGRAM_URL\thttps://github.com/fishman/ctags\t/official site/\n!_TAG_PROGRAM_VERSION\tDevelopment\t//\nA\tinput.d\t/^class A$/;\"\tc\tline:4\tfile:\nB\tinput.d\t/^        class B {$/;\"\tc\tline:47\tclass:A\tfile:\taccess:protected\nC\tinput.d\t/^            private class C {$/;\"\tc\tline:54\tclass:A.B\tfile:\taccess:private\nD\tinput.d\t/^                class D {$/;\"\tc\tline:63\tclass:A.B\tfile:\taccess:protected\na\tinput.d\t/^    void a()$/;\"\tf\tline:6\tclass:A\taccess:public\tsignature:()\nb\tinput.d\t/^    private void b()$/;\"\tf\tline:10\tclass:A\tfile:\taccess:private\tsignature:()\nbar\tinput.d\t/^    int bar;$/;\"\tm\tline:91\tfile:\taccess:public\nc\tinput.d\t/^    protected void c()$/;\"\tf\tline:15\tclass:A\taccess:protected\tsignature:()\nd\tinput.d\t/^        void d() $/;\"\tf\tline:23\tclass:A\tfile:\taccess:private\tsignature:()\ne\tinput.d\t/^        void e() $/;\"\tf\tline:26\tclass:A\tfile:\taccess:private\tsignature:()\nf\tinput.d\t/^        void f() $/;\"\tf\tline:33\tclass:A\taccess:public\tsignature:()\nfoo\tinput.d\t/^    int foo;$/;\"\tm\tline:86\tfile:\taccess:private\ng\tinput.d\t/^        void g() $/;\"\tf\tline:36\tclass:A\taccess:public\tsignature:()\nh\tinput.d\t/^        void h()$/;\"\tf\tline:43\tclass:A\taccess:protected\tsignature:()\ni\tinput.d\t/^            void i() {$/;\"\tf\tline:49\tclass:A.B\taccess:public\tsignature:()\nj\tinput.d\t/^            void j() {$/;\"\tf\tline:51\tclass:A.B\taccess:public\tsignature:()\nk\tinput.d\t/^                void k() {$/;\"\tf\tline:56\tclass:A.B.C\taccess:public\tsignature:()\nl\tinput.d\t/^                private void l() {$/;\"\tf\tline:58\tclass:A.B.C\tfile:\taccess:private\tsignature:()\nm\tinput.d\t/^                    void m() {$/;\"\tf\tline:65\tclass:A.B.D\taccess:public\tsignature:()\nn\tinput.d\t/^                    public void n() {$/;\"\tf\tline:67\tclass:A.B.D\taccess:public\tsignature:()\no\tinput.d\t/^    int o;$/;\"\tm\tline:73\tclass:A\tfile:\taccess:public\np\tinput.d\t/^        int p;$/;\"\tm\tline:75\tclass:A\tfile:\taccess:private\nq\tinput.d\t/^        int q;$/;\"\tm\tline:76\tclass:A\tfile:\taccess:private\nr\tinput.d\t/^        int r;$/;\"\tm\tline:78\tclass:A\tfile:\taccess:protected\ns\tinput.d\t/^        int s;$/;\"\tm\tline:79\tclass:A\tfile:\taccess:protected\nw\tinput.d\t/^        int w;$/;\"\tm\tline:22\tclass:A\tfile:\taccess:private\nx\tinput.d\t/^            protected int x;$/;\"\tm\tline:48\tclass:A.B\tfile:\taccess:protected\ny\tinput.d\t/^                private int y;$/;\"\tm\tline:55\tclass:A.B.C\tfile:\taccess:private\nz\tinput.d\t/^                    int z;$/;\"\tm\tline:64\tclass:A.B.D\tfile:\taccess:public\n"
  },
  {
    "path": "Units/parser-d.r/d-accessmod.d/input.d",
    "content": "\n\n\nclass A\n{\n    void a()\n    {\n    }\n\n    private void b()\n    {\n    }\n\n\n    protected void c()\n    {\n    }\n\n\n    private \n    {\n        int w;\n        void d() \n        {\n        }\n        void e() \n        {\n        }\n    }\n\n    public\n    {\n        void f() \n        {\n        }\n        void g() \n        {\n        }\n    }\n\n    protected\n    {\n        void h()\n        {\n        }\n\n        class B {\n            protected int x;\n            void i() {\n            }\n            void j() {\n            }\n\n            private class C {\n                private int y;\n                void k() {\n                }\n                private void l() {\n                }\n            }\n\n            protected {\n                class D {\n                    int z;\n                    void m() {\n                    }\n                    public void n() {\n                    }\n                }\n            }\n        }\n    }\n    int o;\n    private:\n        int p;\n        int q;\n    protected:\n        int r;\n        int s;\n}\n\n\n\nprivate\n{\n    int foo;\n}\n\npublic\n{\n    int bar;\n}\n\n"
  },
  {
    "path": "Units/parser-d.r/d-size_t-wchar_t-alias.d/expected.tags",
    "content": "size_t\tinput.d\t/^alias size_t = int;$/;\"\ta\tfile:\nwchar_t\tinput.d\t/^alias wchar_t = int;$/;\"\ta\tfile:\n"
  },
  {
    "path": "Units/parser-d.r/d-size_t-wchar_t-alias.d/input.d",
    "content": "\nalias size_t = int;\nalias wchar_t = int;\n"
  },
  {
    "path": "Units/parser-d.r/simple.d.d/expected.tags",
    "content": "AliasInt\tinput.d\t/^alias AliasInt = int;$/;\"\ta\tfile:\nCT\tinput.d\t/^\tclass CT(T)$/;\"\tc\tclass:Class\tfile:\nClass\tinput.d\t/^class Class : Interface$/;\"\tc\tfile:\nEnum\tinput.d\t/^enum Enum : int$/;\"\tg\tfile:\nInterface\tinput.d\t/^interface Interface$/;\"\ti\tfile:\nStruct\tinput.d\t/^struct Struct$/;\"\ts\tfile:\nUnion\tinput.d\t/^\tunion Union$/;\"\tu\tstruct:Struct\tfile:\n_bar\tinput.d\t/^\tprivate AliasInt _bar;$/;\"\tm\tclass:Class\tfile:\nattr_anon\tinput.d\t/^@(obj) T attr_anon;$/;\"\tv\nattr_decl\tinput.d\t/^@attr(i) int attr_decl = 1;$/;\"\tv\nbar\tinput.d\t/^\tbar,$/;\"\te\tenum:Enum\tfile:\nbar\tinput.d\t/^\tpublic AliasInt bar()$/;\"\tf\tclass:Class\nconditional\tinput.d\t/^\tT conditional;$/;\"\tv\tfile:\nfoo\tinput.d\t/^\tfoo,$/;\"\te\tenum:Enum\tfile:\ng_inout\tinput.d\t/^inout(int)* g_inout(inout(int)* p) { return p; }$/;\"\tf\nglobalVar\tinput.d\t/^__gshared int globalVar;$/;\"\tv\ni\tinput.d\t/^int i;$/;\"\tv\nmain\tinput.d\t/^void main(string[] args)$/;\"\tf\tfile:\nmember\tinput.d\t/^\t\tT member;$/;\"\tm\tclass:Class.CT\tfile:\nmodulevar\tinput.d\t/^\tint modulevar;$/;\"\tm\tfile:\nobj\tinput.d\t/^Object obj;$/;\"\tv\nout_contract\tinput.d\t/^void out_contract()$/;\"\tf\tfile:\nqar\tinput.d\t/^\t\tint qar;$/;\"\tm\tunion:Struct.Union\tfile:\nquxx\tinput.d\t/^\t\tbool quxx;$/;\"\tm\tunion:Struct.Union\tfile:\ntest.simple\tinput.d\t/^module test.simple;$/;\"\tM\ntfun\tinput.d\t/^\tauto tfun(T)(T v)$/;\"\tf\tclass:Class\nthis\tinput.d\t/^\tpublic this(AliasInt x)$/;\"\tf\tclass:Class\ntoString\tinput.d\t/^\toverride string toString() { return \"\"; }$/;\"\tf\tclass:Class\ntype_con\tinput.d\t/^const(int)* type_con;$/;\"\tv\ntype_imm\tinput.d\t/^immutable(int)* type_imm;$/;\"\tv\ntype_shar\tinput.d\t/^shared(int)[] type_shar;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-d.r/simple.d.d/input.d",
    "content": "module test.simple;\n\nimport std.stdio;\n\nalias AliasInt = int;\n\nstruct Struct\n{\n\tunion Union\n\t{\n\t\tbool quxx;\n\t\tint qar;\n\t}\n}\n\nenum Enum : int\n{\n\tfoo,\n\tbar,\n}\n\ninterface Interface\n{\n\tpublic AliasInt bar(); // FIXME prototypes\n}\n\nclass Class : Interface\n{\n\tprivate AliasInt _bar;\n\n\tpublic this(AliasInt x)\n\t{\n\t\tthis._bar = x;\n\t}\n\n\toverride string toString() { return \"\"; }\n\n\tpublic AliasInt bar()\n\t{\n\t\treturn this._bar;\n\t}\n\t\n\tprotected:\n\tauto tfun(T)(T v)\n\t{\n\t\treturn v;\n\t}\n\t\n\tclass CT(T)\n\t{\n\t\tT member;\n\t\tenum missing = T.init; // FIXME\n\t}\n}\n\npublic\n{\n\tint modulevar;\n}\n\nObject obj;\n\nconst(int)* type_con;\nimmutable(int)* type_imm;\ninout(int)* f_inout(inout Object); // FIXME prototypes\ninout(int)* g_inout(inout(int)* p) { return p; }\nshared(int)[] type_shar;\n\nprivate:\nint i;\n\n/+ \nint error;\n +/\n\n@attr(i) int attr_decl = 1;\n@attr(i) attr_decl_infer = 1; // FIXME\n@(obj) T attr_anon;\nvoid attr_post() @attr(obj); // FIXME prototypes\n\nstatic if (is(typeof(__traits(getMember, a, name)) == function))\n\tT conditional;\n\nstatic assert( num < TL.length, \"Name '\"~name~\"' is not found\");\n\n__gshared int globalVar;\n\nvoid out_contract()\nout(r; r > 0) {}\n\nvoid main(string[] args)\nin(args.length > 0)\n{\n\tauto foo = new Class(1337);\n\n\talias string AliasString;\n\tAliasString baz = \"Hello, World!\";\n\n\twritefln(\"%s\", foo.bar());\n}\n"
  },
  {
    "path": "Units/parser-d.r/templates.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-d.r/templates.d/expected.tags",
    "content": "Template\tinput.d\t/^template Template(alias a, T...)$/;\"\tT\tfile:\nTemplateAlias\tinput.d\t/^    alias TemplateAlias = a!T;$/;\"\ta\ttemplate:Template\tfile:\nmemb\tinput.d\t/^    int memb;$/;\"\tm\ttemplate:Template\tfile:\nb\tinput.d\t/^Foo!x b;$/;\"\tv\nc\tinput.d\t/^Foo!(x) c;$/;\"\tv\nd\tinput.d\t/^Foo!(x < 2) d;$/;\"\tv\ng\tinput.d\t/^void g(Foo!x) {}$/;\"\tf\neach\tinput.d\t/^template each(alias fun = \"a\")$/;\"\tT\tfile:\nchild\tinput.d\t/^    template child(){}$/;\"\tT\ttemplate:each\tfile:\ntmethod\tinput.d\t/^    void tmethod()(){}$/;\"\tf\ttemplate:each\nImplementLength\tinput.d\t/^mixin ImplementLength!source; \\/\\/ FIXME source too!$/;\"\tX\nsource\tinput.d\t/^mixin ImplementLength!source; \\/\\/ FIXME source too!$/;\"\tX\nIT\tinput.d\t/^interface IT(T){}$/;\"\ti\tfile:\nST\tinput.d\t/^struct ST(T){}$/;\"\ts\tfile:\nUT\tinput.d\t/^union UT(T){}$/;\"\tu\tfile:\n"
  },
  {
    "path": "Units/parser-d.r/templates.d/input.d",
    "content": "template Template(alias a, T...)\nif (is(typeof(a)))\n{\nprivate:\n    // no parent:\n    alias TemplateAlias = a!T;\n    int memb;\n}\n\nFoo!x b;\nFoo!(x) c;\nFoo!(x < 2) d;\nvoid f(Foo!x); // FIXME prototypes\nvoid g(Foo!x) {}\n\ntemplate each(alias fun = \"a\")\n{\n    template child(){}\n    void tmethod()(){}\n}\n\n// FIXME\n/+\nint vt(alias a) = 0; // not parsed\n// parsed as T:\nalias AT(T) = T;\nenum ET(T) = T.init;\n+/\n\nmixin ImplementLength!source; // FIXME source too!\n\n// declaration templates\ninterface IT(T){}\nstruct ST(T){}\nunion UT(T){}\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/node-as-root-with-dtd.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/node-as-root-with-dtd.d/expected.tags",
    "content": "org.gnome.Terminal.Factory0\tinput.xml\t/^  <interface name=\"org.gnome.Terminal.Factory0\">$/;\"\ti\nCreateInstance\tinput.xml\t/^    <method name=\"CreateInstance\">$/;\"\tm\tinterface:org.gnome.Terminal.Factory0\noptions\tinput.xml\t/^      <arg type=\"a{sv}\" name=\"options\" direction=\"in\" \\/>$/;\"\ta\tmethod:org.gnome.Terminal.Factory0.CreateInstance\nreceiver\tinput.xml\t/^      <arg type=\"o\" name=\"receiver\" direction=\"out\" \\/>$/;\"\ta\tmethod:org.gnome.Terminal.Factory0.CreateInstance\norg.gnome.Terminal.Terminal0\tinput.xml\t/^  <interface name=\"org.gnome.Terminal.Terminal0\">$/;\"\ti\nExec\tinput.xml\t/^    <method name=\"Exec\">$/;\"\tm\tinterface:org.gnome.Terminal.Terminal0\noptions\tinput.xml\t/^      <arg type=\"a{sv}\" name=\"options\" direction=\"in\" \\/>$/;\"\ta\tmethod:org.gnome.Terminal.Terminal0.Exec\narguments\tinput.xml\t/^      <arg type=\"aay\" name=\"arguments\" direction=\"in\">$/;\"\ta\tmethod:org.gnome.Terminal.Terminal0.Exec\nChildExited\tinput.xml\t/^    <signal name=\"ChildExited\">$/;\"\ts\tinterface:org.gnome.Terminal.Terminal0\nexit_code\tinput.xml\t/^      <arg type=\"i\" name=\"exit_code\" direction=\"in\" \\/>$/;\"\ta\tsignal:org.gnome.Terminal.Terminal0.ChildExited\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/node-as-root-with-dtd.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/node-as-root-with-dtd.d/input.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Introspection 0.1//EN\"\n                      \"http://www.freedesktop.org/software/dbus/introspection.dtd\">\n<!-- TAKEN FROM gnome-terminal-3.28.2 -->\n<!--\n  Copyright © 2011 Christian Persch\n\n  This program is free software; you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation; either version 3, or (at your option)\n  any later version.\n\n  This program is distributed in the hope conf it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n-->\n<node>\n  <interface name=\"org.gnome.Terminal.Factory0\">\n    <annotation name=\"org.gtk.GDBus.C.Name\" value=\"Factory\" />\n    <method name=\"CreateInstance\">\n      <arg type=\"a{sv}\" name=\"options\" direction=\"in\" />\n      <arg type=\"o\" name=\"receiver\" direction=\"out\" />\n    </method>\n  </interface>\n\n  <interface name=\"org.gnome.Terminal.Terminal0\">\n    <annotation name=\"org.gtk.GDBus.C.Name\" value=\"Receiver\" />\n    <method name=\"Exec\">\n      <annotation name=\"org.gtk.GDBus.C.UnixFD\" value=\"true\" />\n      <arg type=\"a{sv}\" name=\"options\" direction=\"in\" />\n      <arg type=\"aay\" name=\"arguments\" direction=\"in\">\n        <annotation name=\"org.gtk.GDBus.C.ForceGVariant\" value=\"true\" />\n      </arg>\n    </method>\n    \n    <signal name=\"ChildExited\">\n      <arg type=\"i\" name=\"exit_code\" direction=\"in\" />\n    </signal>\n  </interface>\n</node>\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/node-as-root-without-dtd.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/node-as-root-without-dtd.d/expected.tags",
    "content": "/\tinput.xml\t/^<node name=\"\\/\">$/;\"\tn\norg.freedesktop.NetworkManager.Device.Ppp\tinput.xml\t/^  <interface name=\"org.freedesktop.NetworkManager.Device.Ppp\">$/;\"\ti\tnode:/\nPropertiesChanged\tinput.xml\t/^    <signal name=\"PropertiesChanged\">$/;\"\ts\tinterface:/.org.freedesktop.NetworkManager.Device.Ppp\nproperties\tinput.xml\t/^      <arg name=\"properties\" type=\"a{sv}\"\\/>$/;\"\ta\tsignal:/.org.freedesktop.NetworkManager.Device.Ppp.PropertiesChanged\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/node-as-root-without-dtd.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/node-as-root-without-dtd.d/input.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<node name=\"/\">\n  <!-- Taken from NetworkManager-1.12.0/introspection/org.freedesktop.NetworkManager.Device.Ppp.xml -->\n  <!--\n      org.freedesktop.NetworkManager.Device.Ppp:\n      @short_description: PPP Device\n\n  -->\n  <interface name=\"org.freedesktop.NetworkManager.Device.Ppp\">\n\n    <!--\n        PropertiesChanged:\n        @properties: A dictionary mapping property names to variant boxed values\n\n        DEPRECATED. Use the standard \"PropertiesChanged\" signal from \"org.freedesktop.DBus.Properties\" instead which exists since version NetworkManager 1.2.0.\n    -->\n    <signal name=\"PropertiesChanged\">\n      <arg name=\"properties\" type=\"a{sv}\"/>\n    </signal>\n  </interface>\n</node>\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/simple-dbus-inspect.d/args.ctags",
    "content": "--fields=+l\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/simple-dbus-inspect.d/expected.tags",
    "content": "ClientAdded\tinput.xml\t/^    <signal name=\"ClientAdded\">$/;\"\ts\tlanguage:DBusIntrospect\tinterface:org.gnome.SessionManager\nSessionName\tinput.xml\t/^    <property name=\"SessionName\" type=\"s\" access=\"read\">$/;\"\tp\tlanguage:DBusIntrospect\tinterface:org.gnome.SessionManager\nSetenv\tinput.xml\t/^    <method name=\"Setenv\">$/;\"\tm\tlanguage:DBusIntrospect\tinterface:org.gnome.SessionManager\ndoc\tinput.xml\t/^<node xmlns:doc=\"http:\\/\\/www.freedesktop.org\\/dbus\\/1.0\\/doc.dtd\">$/;\"\tn\tlanguage:XML\turi:http://www.freedesktop.org/dbus/1.0/doc.dtd\nid\tinput.xml\t/^      <arg name=\"id\" type=\"o\">$/;\"\ta\tlanguage:DBusIntrospect\tsignal:org.gnome.SessionManager.ClientAdded\norg.gnome.SessionManager\tinput.xml\t/^  <interface name=\"org.gnome.SessionManager\">$/;\"\ti\tlanguage:DBusIntrospect\nvalue\tinput.xml\t/^      <arg name=\"value\" type=\"s\" direction=\"in\">$/;\"\ta\tlanguage:DBusIntrospect\tmethod:org.gnome.SessionManager.Setenv\nvariable\tinput.xml\t/^      <arg name=\"variable\" type=\"s\" direction=\"in\">$/;\"\ta\tlanguage:DBusIntrospect\tmethod:org.gnome.SessionManager.Setenv\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/simple-dbus-inspect.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-dbus-inspect.r/simple-dbus-inspect.d/input.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n<node xmlns:doc=\"http://www.freedesktop.org/dbus/1.0/doc.dtd\">\n  <interface name=\"org.gnome.SessionManager\">\n\n    <!-- Initialization phase interfaces -->\n\n    <method name=\"Setenv\">\n      <arg name=\"variable\" type=\"s\" direction=\"in\">\n        <doc:doc>\n          <doc:summary>The variable name</doc:summary>\n        </doc:doc>\n      </arg>\n      <arg name=\"value\" type=\"s\" direction=\"in\">\n        <doc:doc>\n          <doc:summary>The value</doc:summary>\n        </doc:doc>\n      </arg>\n      <doc:doc>\n        <doc:description>\n          <doc:para>Adds the variable name to the application launch environment with the specified value.  May only be used during the Session Manager initialization phase.</doc:para>\n        </doc:description>\n      </doc:doc>\n    </method>\n\n    <!-- Signals -->\n\n    <signal name=\"ClientAdded\">\n      <arg name=\"id\" type=\"o\">\n        <doc:doc>\n          <doc:summary>The object path for the added client</doc:summary>\n        </doc:doc>\n      </arg>\n      <doc:doc>\n        <doc:description>\n          <doc:para>Emitted when a client has been added to the session manager.\n          </doc:para>\n        </doc:description>\n      </doc:doc>\n    </signal>\n\n    <!-- Properties -->\n\n    <property name=\"SessionName\" type=\"s\" access=\"read\">\n      <doc:doc>\n        <doc:description>\n          <doc:para>The name of the session that has been loaded.</doc:para>\n        </doc:description>\n      </doc:doc>\n    </property>\n\n\n  </interface>\n</node>\n"
  },
  {
    "path": "Units/parser-dbus-service.r/simple.d/README",
    "content": "The test input is taken from libvirt-dbus-1.4.1-6.fc42.x86_64.\n"
  },
  {
    "path": "Units/parser-dbus-service.r/simple.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-dbus-service.r/simple.d/expected.tags",
    "content": "D-BUS Service\tinput.service\t/^[D-BUS Service]$/;\"\ts\troles:def\nName\tinput.service\t/^Name=org.libvirt$/;\"\tk\tsection:D-BUS Service\troles:def\norg.libvirt\tinput.service\t/^Name=org.libvirt$/;\"\tn\troles:def\nExec\tinput.service\t/^Exec=\\/bin\\/false$/;\"\tk\tsection:D-BUS Service\troles:def\nSystemdService\tinput.service\t/^SystemdService=libvirt-dbus.service$/;\"\tk\tsection:D-BUS Service\troles:def\nlibvirt-dbus.service\tinput.service\t/^SystemdService=libvirt-dbus.service$/;\"\tu\troles:foreignlang\n"
  },
  {
    "path": "Units/parser-dbus-service.r/simple.d/input.service",
    "content": "[D-BUS Service]\nName=org.libvirt\nExec=/bin/false\nSystemdService=libvirt-dbus.service\n"
  },
  {
    "path": "Units/parser-dtd.r/colons-in-name.d/args.ctags",
    "content": "--sort=no\n--fields=+reK\n--extras=+r\n"
  },
  {
    "path": "Units/parser-dtd.r/colons-in-name.d/expected.tags",
    "content": "boolean\tinput.dtd\t/^<!ENTITY % boolean\t\t\"(true|false)\">$/;\"\tparameterEntity\troles:def\tend:32\naccel:acceleratorlist\tinput.dtd\t/^<!ELEMENT accel:acceleratorlist (accel:item*)>$/;\"\telement\troles:def\tend:34\naccel:acceleratorlist\tinput.dtd\t/^<!ATTLIST accel:acceleratorlist$/;\"\telement\troles:attOwner\tend:38\nxmlns:accel\tinput.dtd\t/^\txmlns:accel CDATA #FIXED \"http:\\/\\/openoffice.org\\/2001\\/accel\"$/;\"\tattribute\telement:accel:acceleratorlist\troles:def\nxmlns:xlink\tinput.dtd\t/^\txmlns:xlink CDATA #FIXED \"http:\\/\\/www.w3.org\\/1999\\/xlink\"$/;\"\tattribute\telement:accel:acceleratorlist\troles:def\naccel:item\tinput.dtd\t/^<!ELEMENT accel:item EMPTY>$/;\"\telement\troles:def\tend:40\naccel:item\tinput.dtd\t/^<!ATTLIST accel:item$/;\"\telement\troles:attOwner\tend:47\naccel:code\tinput.dtd\t/^\taccel:code CDATA #REQUIRED$/;\"\tattribute\telement:accel:item\troles:def\naccel:shift\tinput.dtd\t/^\taccel:shift %boolean; \"false\"$/;\"\tattribute\telement:accel:item\troles:def\nboolean\tinput.dtd\t/^\taccel:shift %boolean; \"false\"$/;\"\tparameterEntity\telement:accel:item\troles:partOfAttDef\naccel:mod1\tinput.dtd\t/^\taccel:mod1 %boolean; \"false\"$/;\"\tattribute\telement:accel:item\troles:def\nboolean\tinput.dtd\t/^\taccel:mod1 %boolean; \"false\"$/;\"\tparameterEntity\telement:accel:item\troles:partOfAttDef\naccel:mod2\tinput.dtd\t/^\taccel:mod2 %boolean; \"false\"$/;\"\tattribute\telement:accel:item\troles:def\nboolean\tinput.dtd\t/^\taccel:mod2 %boolean; \"false\"$/;\"\tparameterEntity\telement:accel:item\troles:partOfAttDef\nxlink:href\tinput.dtd\t/^\txlink:href CDATA #REQUIRED$/;\"\tattribute\telement:accel:item\troles:def\n"
  },
  {
    "path": "Units/parser-dtd.r/colons-in-name.d/input.dtd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!-- Taken from OOO320_m19/framework/dtd/accelerator.dtd -->\n\n<!--\n\n  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\n  Copyright 2000, 2010 Oracle and/or its affiliates.\n\n  OpenOffice.org - a multi-platform office productivity suite\n\n  This file is part of OpenOffice.org.\n\n  OpenOffice.org is free software: you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License version 3\n  only, as published by the Free Software Foundation.\n\n  OpenOffice.org is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License version 3 for more details\n  (a copy is included in the LICENSE file that accompanied this code).\n\n  You should have received a copy of the GNU Lesser General Public License\n  version 3 along with OpenOffice.org.  If not, see\n  <http://www.openoffice.org/license.html>\n  for a copy of the LGPLv3 License.\n\n-->\n\n<!ENTITY % boolean\t\t\"(true|false)\">\n\n<!ELEMENT accel:acceleratorlist (accel:item*)>\n<!ATTLIST accel:acceleratorlist\n\txmlns:accel CDATA #FIXED \"http://openoffice.org/2001/accel\"\n\txmlns:xlink CDATA #FIXED \"http://www.w3.org/1999/xlink\"\n>\n\n<!ELEMENT accel:item EMPTY>\n<!ATTLIST accel:item\n\taccel:code CDATA #REQUIRED\n\taccel:shift %boolean; \"false\"\n\taccel:mod1 %boolean; \"false\"\n\taccel:mod2 %boolean; \"false\"\n\txlink:href CDATA #REQUIRED\n>\n"
  },
  {
    "path": "Units/parser-dtd.r/condtion.d/args.ctags",
    "content": "--sort=no\n--fields=+re\n--extras=+r\n"
  },
  {
    "path": "Units/parser-dtd.r/condtion.d/expected.tags",
    "content": "x\tinput.dtd\t/^<![%x;[$/;\"\tp\troles:condition\tend:5\nxhtml-struct.mod\tinput.dtd\t/^<!ENTITY % xhtml-struct.mod$/;\"\tp\troles:def\tend:4\n"
  },
  {
    "path": "Units/parser-dtd.r/condtion.d/input.dtd",
    "content": "<![%x;[\n<!ENTITY % xhtml-struct.mod\n     PUBLIC \"-//W3C//ELEMENTS XHTML Document Structure 1.0//EN\"\n            \"http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-struct-1.mod\" >\n]]>\n"
  },
  {
    "path": "Units/parser-dtd.r/elements.d/args.ctags",
    "content": "--sort=no\n--fields=+re\n--extras=+r\n"
  },
  {
    "path": "Units/parser-dtd.r/elements.d/expected.tags",
    "content": "SUB\tinput.mod\t/^<!ELEMENT (SUB|SUP) - - (%inline;)*    -- subscript, superscript -->$/;\"\te\troles:def\tend:1\nSUP\tinput.mod\t/^<!ELEMENT (SUB|SUP) - - (%inline;)*    -- subscript, superscript -->$/;\"\te\troles:def\tend:1\n"
  },
  {
    "path": "Units/parser-dtd.r/elements.d/input.mod",
    "content": "<!ELEMENT (SUB|SUP) - - (%inline;)*    -- subscript, superscript -->\n\t\t\t\t\t\t\t\t \n"
  },
  {
    "path": "Units/parser-dtd.r/fq.d/args.ctags",
    "content": "--sort=no\n--extras=+rq\n--fields=+rE\n"
  },
  {
    "path": "Units/parser-dtd.r/fq.d/expected.tags",
    "content": "a\tinput.dtd\t/^<!ELEMENT a (b)>$/;\"\te\troles:def\na\tinput.dtd\t/^<!ATTLIST a$/;\"\te\troles:attOwner\textras:reference\nid-attr\tinput.dtd\t/^        %id-attr;$/;\"\tp\telement:a\troles:partOfAttDef\textras:reference\na/%id-attr\tinput.dtd\t/^        %id-attr;$/;\"\tp\telement:a\troles:partOfAttDef\textras:qualified,reference\ntype\tinput.dtd\t/^        type CDATA      \"text\\/smil-basic-layout\"$/;\"\ta\telement:a\troles:def\na/@type\tinput.dtd\t/^        type CDATA      \"text\\/smil-basic-layout\"$/;\"\ta\telement:a\troles:def\textras:qualified\n"
  },
  {
    "path": "Units/parser-dtd.r/fq.d/input.dtd",
    "content": "<!ELEMENT a (b)>\n<!ATTLIST a\n        %id-attr;\n        type CDATA      \"text/smil-basic-layout\"\n>\n"
  },
  {
    "path": "Units/parser-dtd.r/notation.d/expected.tags",
    "content": "WEB-JSPTAGLIB.1_2\tinput.dtd\t/^<!NOTATION WEB-JSPTAGLIB.1_2 PUBLIC$/;\"\tn\n"
  },
  {
    "path": "Units/parser-dtd.r/notation.d/input.dtd",
    "content": "<!-- Taken from apache-tomcat-apis-0.1/servlet2.4jsp2.0/jsr154/src/share/dtd/web-jsptaglibrary_1_2.dtd -->\n\n<!NOTATION WEB-JSPTAGLIB.1_2 PUBLIC\n          \"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN\">\n"
  },
  {
    "path": "Units/parser-dtd.r/parameter-entities.d/args.ctags",
    "content": "--sort=no\n--fields=+reK\n--extras=+r\n"
  },
  {
    "path": "Units/parser-dtd.r/parameter-entities.d/expected.tags",
    "content": "id-attr\tinput.dtd\t/^<!ENTITY % id-attr \"id ID #IMPLIED\">$/;\"\tparameterEntity\troles:def\tend:27\ntitle-attr\tinput.dtd\t/^<!ENTITY % title-attr \"title CDATA #IMPLIED\">$/;\"\tparameterEntity\troles:def\tend:28\nskip-attr\tinput.dtd\t/^<!ENTITY % skip-attr \"skip-content (true|false) 'true'\">$/;\"\tparameterEntity\troles:def\tend:29\ndesc-attr\tinput.dtd\t/^<!ENTITY % desc-attr \"$/;\"\tparameterEntity\troles:def\tend:35\nsmil\tinput.dtd\t/^<!ELEMENT smil (head?,body?)>$/;\"\telement\troles:def\tend:41\nsmil\tinput.dtd\t/^<!ATTLIST smil$/;\"\telement\troles:attOwner\tend:44\nid-attr\tinput.dtd\t/^        %id-attr;$/;\"\tparameterEntity\telement:smil\troles:partOfAttDef\nlayout-section\tinput.dtd\t/^<!ENTITY % layout-section \"layout|switch\">$/;\"\tparameterEntity\troles:def\tend:47\nhead-element\tinput.dtd\t/^<!ENTITY % head-element \"(meta*,((%layout-section;), meta*))?\">$/;\"\tparameterEntity\troles:def\tend:49\nhead\tinput.dtd\t/^<!ELEMENT head %head-element;>$/;\"\telement\troles:def\tend:51\nhead\tinput.dtd\t/^<!ATTLIST head %id-attr;>$/;\"\telement\troles:attOwner\tend:52\nid-attr\tinput.dtd\t/^<!ATTLIST head %id-attr;>$/;\"\tparameterEntity\telement:head\troles:partOfAttDef\nlayout\tinput.dtd\t/^<!ELEMENT layout (region|root-layout)>$/;\"\telement\troles:def\tend:61\nlayout\tinput.dtd\t/^<!ATTLIST layout$/;\"\telement\troles:attOwner\tend:65\nid-attr\tinput.dtd\t/^        %id-attr;$/;\"\tparameterEntity\telement:layout\troles:partOfAttDef\ntype\tinput.dtd\t/^        type CDATA      \"text\\/smil-basic-layout\"$/;\"\tattribute\telement:layout\troles:def\nviewport-attrs\tinput.dtd\t/^<!ENTITY % viewport-attrs \"$/;\"\tparameterEntity\troles:def\tend:73\nregion\tinput.dtd\t/^<!ELEMENT region EMPTY>$/;\"\telement\troles:def\tend:75\nregion\tinput.dtd\t/^<!ATTLIST region$/;\"\telement\troles:attOwner\tend:85\nid-attr\tinput.dtd\t/^        %id-attr;$/;\"\tparameterEntity\telement:region\troles:partOfAttDef\ntitle-attr\tinput.dtd\t/^        %title-attr;$/;\"\tparameterEntity\telement:region\troles:partOfAttDef\nviewport-attrs\tinput.dtd\t/^        %viewport-attrs;$/;\"\tparameterEntity\telement:region\troles:partOfAttDef\nleft\tinput.dtd\t/^        left                CDATA    \"0\"$/;\"\tattribute\telement:region\troles:def\ntop\tinput.dtd\t/^        top                 CDATA    \"0\"$/;\"\tattribute\telement:region\troles:def\nz-index\tinput.dtd\t/^        z-index             CDATA    \"0\"$/;\"\tattribute\telement:region\troles:def\nfit\tinput.dtd\t/^        fit                 (hidden|fill|meet|scroll|slice)    \"hidden\"$/;\"\tattribute\telement:region\troles:def\nskip-attr\tinput.dtd\t/^        %skip-attr;$/;\"\tparameterEntity\telement:region\troles:partOfAttDef\nroot-layout\tinput.dtd\t/^<!ELEMENT root-layout EMPTY>$/;\"\telement\troles:def\tend:88\nroot-layout\tinput.dtd\t/^<!ATTLIST root-layout$/;\"\telement\troles:attOwner\tend:94\nid-attr\tinput.dtd\t/^        %id-attr;$/;\"\tparameterEntity\telement:root-layout\troles:partOfAttDef\ntitle-attr\tinput.dtd\t/^        %title-attr;$/;\"\tparameterEntity\telement:root-layout\troles:partOfAttDef\nviewport-attrs\tinput.dtd\t/^        %viewport-attrs;$/;\"\tparameterEntity\telement:root-layout\troles:partOfAttDef\nskip-attr\tinput.dtd\t/^        %skip-attr;$/;\"\tparameterEntity\telement:root-layout\troles:partOfAttDef\nmeta\tinput.dtd\t/^<!ELEMENT meta EMPTY>$/;\"\telement\troles:def\tend:98\nmeta\tinput.dtd\t/^<!ATTLIST meta$/;\"\telement\troles:attOwner\tend:103\nname\tinput.dtd\t/^        name    NMTOKEN #REQUIRED$/;\"\tattribute\telement:meta\troles:def\ncontent\tinput.dtd\t/^        content CDATA   #REQUIRED$/;\"\tattribute\telement:meta\troles:def\nskip-attr\tinput.dtd\t/^        %skip-attr;$/;\"\tparameterEntity\telement:meta\troles:partOfAttDef\nmedia-object\tinput.dtd\t/^<!ENTITY % media-object \"audio|video|text|img|animation|textstream|ref\">$/;\"\tparameterEntity\troles:def\tend:106\nschedule\tinput.dtd\t/^<!ENTITY % schedule \"par|seq|(%media-object;)\">$/;\"\tparameterEntity\troles:def\tend:107\ninline-link\tinput.dtd\t/^<!ENTITY % inline-link \"a\">$/;\"\tparameterEntity\troles:def\tend:108\nassoc-link\tinput.dtd\t/^<!ENTITY % assoc-link \"anchor\">$/;\"\tparameterEntity\troles:def\tend:109\nlink\tinput.dtd\t/^<!ENTITY % link \"%inline-link;\">$/;\"\tparameterEntity\troles:def\tend:110\ncontainer-content\tinput.dtd\t/^<!ENTITY % container-content \"(%schedule;)|switch|(%link;)\">$/;\"\tparameterEntity\troles:def\tend:111\nbody-content\tinput.dtd\t/^<!ENTITY % body-content \"(%container-content;)\">$/;\"\tparameterEntity\troles:def\tend:112\nbody\tinput.dtd\t/^<!ELEMENT body (%body-content;)*>$/;\"\telement\troles:def\tend:114\nbody\tinput.dtd\t/^<!ATTLIST body %id-attr;>$/;\"\telement\troles:attOwner\tend:115\nid-attr\tinput.dtd\t/^<!ATTLIST body %id-attr;>$/;\"\tparameterEntity\telement:body\troles:partOfAttDef\nsync-attributes\tinput.dtd\t/^<!ENTITY % sync-attributes \"$/;\"\tparameterEntity\troles:def\tend:121\nsystem-attribute\tinput.dtd\t/^<!ENTITY % system-attribute \"$/;\"\tparameterEntity\troles:def\tend:132\nfill-attribute\tinput.dtd\t/^<!ENTITY % fill-attribute \"$/;\"\tparameterEntity\troles:def\tend:137\npar-content\tinput.dtd\t/^<!ENTITY % par-content \"%container-content;\">$/;\"\tparameterEntity\troles:def\tend:141\npar\tinput.dtd\t/^<!ELEMENT par    (%par-content;)*>$/;\"\telement\troles:def\tend:142\npar\tinput.dtd\t/^<!ATTLIST par$/;\"\telement\troles:attOwner\tend:152\nid-attr\tinput.dtd\t/^        %id-attr;$/;\"\tparameterEntity\telement:par\troles:partOfAttDef\ndesc-attr\tinput.dtd\t/^        %desc-attr;$/;\"\tparameterEntity\telement:par\troles:partOfAttDef\nendsync\tinput.dtd\t/^        endsync CDATA           \"last\"$/;\"\tattribute\telement:par\troles:def\ndur\tinput.dtd\t/^        dur     CDATA           #IMPLIED$/;\"\tattribute\telement:par\troles:def\nrepeat\tinput.dtd\t/^        repeat  CDATA           \"1\"$/;\"\tattribute\telement:par\troles:def\nregion\tinput.dtd\t/^        region  IDREF           #IMPLIED$/;\"\tattribute\telement:par\troles:def\nsync-attributes\tinput.dtd\t/^        %sync-attributes;$/;\"\tparameterEntity\telement:par\troles:partOfAttDef\nsystem-attribute\tinput.dtd\t/^        %system-attribute;$/;\"\tparameterEntity\telement:par\troles:partOfAttDef\nseq-content\tinput.dtd\t/^<!ENTITY % seq-content \"%container-content;\">$/;\"\tparameterEntity\troles:def\tend:155\nseq\tinput.dtd\t/^<!ELEMENT seq    (%seq-content;)*>$/;\"\telement\troles:def\tend:156\nseq\tinput.dtd\t/^<!ATTLIST seq$/;\"\telement\troles:attOwner\tend:165\nid-attr\tinput.dtd\t/^        %id-attr;$/;\"\tparameterEntity\telement:seq\troles:partOfAttDef\ndesc-attr\tinput.dtd\t/^        %desc-attr;$/;\"\tparameterEntity\telement:seq\troles:partOfAttDef\ndur\tinput.dtd\t/^        dur     CDATA           #IMPLIED$/;\"\tattribute\telement:seq\troles:def\nrepeat\tinput.dtd\t/^        repeat  CDATA           \"1\"$/;\"\tattribute\telement:seq\troles:def\nregion\tinput.dtd\t/^        region  IDREF           #IMPLIED$/;\"\tattribute\telement:seq\troles:def\nsync-attributes\tinput.dtd\t/^        %sync-attributes;$/;\"\tparameterEntity\telement:seq\troles:partOfAttDef\nsystem-attribute\tinput.dtd\t/^        %system-attribute;$/;\"\tparameterEntity\telement:seq\troles:partOfAttDef\nswitch-content\tinput.dtd\t/^<!ENTITY % switch-content \"layout|(%container-content;)\">$/;\"\tparameterEntity\troles:def\tend:173\nswitch\tinput.dtd\t/^<!ELEMENT switch (%switch-content;)*>$/;\"\telement\troles:def\tend:174\nswitch\tinput.dtd\t/^<!ATTLIST switch$/;\"\telement\troles:attOwner\tend:178\nid-attr\tinput.dtd\t/^        %id-attr;$/;\"\tparameterEntity\telement:switch\troles:partOfAttDef\ntitle-attr\tinput.dtd\t/^        %title-attr;$/;\"\tparameterEntity\telement:switch\troles:partOfAttDef\nmo-attributes\tinput.dtd\t/^<!ENTITY % mo-attributes \"$/;\"\tparameterEntity\troles:def\tend:201\nmo-content\tinput.dtd\t/^<!ENTITY % mo-content \"(%assoc-link;)*\">$/;\"\tparameterEntity\troles:def\tend:207\nclip-attrs\tinput.dtd\t/^<!ENTITY % clip-attrs \"$/;\"\tparameterEntity\troles:def\tend:211\nref\tinput.dtd\t/^<!ELEMENT ref           %mo-content;>$/;\"\telement\troles:def\tend:213\naudio\tinput.dtd\t/^<!ELEMENT audio         %mo-content;>$/;\"\telement\troles:def\tend:214\nimg\tinput.dtd\t/^<!ELEMENT img           %mo-content;>$/;\"\telement\troles:def\tend:215\nvideo\tinput.dtd\t/^<!ELEMENT video         %mo-content;>$/;\"\telement\troles:def\tend:216\ntext\tinput.dtd\t/^<!ELEMENT text          %mo-content;>$/;\"\telement\troles:def\tend:217\ntextstream\tinput.dtd\t/^<!ELEMENT textstream    %mo-content;>$/;\"\telement\troles:def\tend:218\nanimation\tinput.dtd\t/^<!ELEMENT animation     %mo-content;>$/;\"\telement\troles:def\tend:219\nref\tinput.dtd\t/^<!ATTLIST ref           %mo-attributes; %clip-attrs;>$/;\"\telement\troles:attOwner\tend:221\nmo-attributes\tinput.dtd\t/^<!ATTLIST ref           %mo-attributes; %clip-attrs;>$/;\"\tparameterEntity\telement:ref\troles:partOfAttDef\nclip-attrs\tinput.dtd\t/^<!ATTLIST ref           %mo-attributes; %clip-attrs;>$/;\"\tparameterEntity\telement:ref\troles:partOfAttDef\naudio\tinput.dtd\t/^<!ATTLIST audio         %mo-attributes; %clip-attrs;>$/;\"\telement\troles:attOwner\tend:222\nmo-attributes\tinput.dtd\t/^<!ATTLIST audio         %mo-attributes; %clip-attrs;>$/;\"\tparameterEntity\telement:audio\troles:partOfAttDef\nclip-attrs\tinput.dtd\t/^<!ATTLIST audio         %mo-attributes; %clip-attrs;>$/;\"\tparameterEntity\telement:audio\troles:partOfAttDef\nvideo\tinput.dtd\t/^<!ATTLIST video         %mo-attributes; %clip-attrs;>$/;\"\telement\troles:attOwner\tend:223\nmo-attributes\tinput.dtd\t/^<!ATTLIST video         %mo-attributes; %clip-attrs;>$/;\"\tparameterEntity\telement:video\troles:partOfAttDef\nclip-attrs\tinput.dtd\t/^<!ATTLIST video         %mo-attributes; %clip-attrs;>$/;\"\tparameterEntity\telement:video\troles:partOfAttDef\nanimation\tinput.dtd\t/^<!ATTLIST animation     %mo-attributes; %clip-attrs;>$/;\"\telement\troles:attOwner\tend:224\nmo-attributes\tinput.dtd\t/^<!ATTLIST animation     %mo-attributes; %clip-attrs;>$/;\"\tparameterEntity\telement:animation\troles:partOfAttDef\nclip-attrs\tinput.dtd\t/^<!ATTLIST animation     %mo-attributes; %clip-attrs;>$/;\"\tparameterEntity\telement:animation\troles:partOfAttDef\ntextstream\tinput.dtd\t/^<!ATTLIST textstream    %mo-attributes; %clip-attrs;>$/;\"\telement\troles:attOwner\tend:225\nmo-attributes\tinput.dtd\t/^<!ATTLIST textstream    %mo-attributes; %clip-attrs;>$/;\"\tparameterEntity\telement:textstream\troles:partOfAttDef\nclip-attrs\tinput.dtd\t/^<!ATTLIST textstream    %mo-attributes; %clip-attrs;>$/;\"\tparameterEntity\telement:textstream\troles:partOfAttDef\ntext\tinput.dtd\t/^<!ATTLIST text          %mo-attributes;>$/;\"\telement\troles:attOwner\tend:226\nmo-attributes\tinput.dtd\t/^<!ATTLIST text          %mo-attributes;>$/;\"\tparameterEntity\telement:text\troles:partOfAttDef\nimg\tinput.dtd\t/^<!ATTLIST img           %mo-attributes;>$/;\"\telement\troles:attOwner\tend:227\nmo-attributes\tinput.dtd\t/^<!ATTLIST img           %mo-attributes;>$/;\"\tparameterEntity\telement:img\troles:partOfAttDef\nsmil-link-attributes\tinput.dtd\t/^<!ENTITY % smil-link-attributes \"$/;\"\tparameterEntity\troles:def\tend:236\na\tinput.dtd\t/^<!ELEMENT a (%schedule;|switch)*>$/;\"\telement\troles:def\tend:240\na\tinput.dtd\t/^<!ATTLIST a$/;\"\telement\troles:attOwner\tend:243\nsmil-link-attributes\tinput.dtd\t/^        %smil-link-attributes;$/;\"\tparameterEntity\telement:a\troles:partOfAttDef\nanchor\tinput.dtd\t/^<!ELEMENT anchor EMPTY>$/;\"\telement\troles:def\tend:247\nanchor\tinput.dtd\t/^<!ATTLIST anchor$/;\"\telement\troles:attOwner\tend:253\nskip-attr\tinput.dtd\t/^        %skip-attr;$/;\"\tparameterEntity\telement:anchor\troles:partOfAttDef\nsmil-link-attributes\tinput.dtd\t/^        %smil-link-attributes;$/;\"\tparameterEntity\telement:anchor\troles:partOfAttDef\nsync-attributes\tinput.dtd\t/^        %sync-attributes;$/;\"\tparameterEntity\telement:anchor\troles:partOfAttDef\ncoords\tinput.dtd\t/^        coords          CDATA                   #IMPLIED$/;\"\tattribute\telement:anchor\troles:def\n"
  },
  {
    "path": "Units/parser-dtd.r/parameter-entities.d/input.dtd",
    "content": "<!-- TAKEN from wireshark/dtds/smil.dtd -->\n\n<? wireshark:protocol\n\tproto_name=\"smil\"\n\tmedia=\"application/smil\"\n\tdescription=\"Synchronized Multimedia Integration Language\"\n\t?>\n\n<!--\n\n    This is the XML document type definition (DTD) for SMIL 1.0.\n\n    Date: 1998/06/15 08:56:30\n\n    Authors: \n        Jacco van Ossenbruggen <jrvosse@cwi.nl> \n        Sjoerd Mullender       <sjoerd@cwi.nl>\n        \n    Further information about SMIL is available at:\n\n          http://www.w3.org/AudioVideo/\n\n-->\n\n\n<!-- Generally useful entities -->\n<!ENTITY % id-attr \"id ID #IMPLIED\">\n<!ENTITY % title-attr \"title CDATA #IMPLIED\">\n<!ENTITY % skip-attr \"skip-content (true|false) 'true'\">\n<!ENTITY % desc-attr \"\n        %title-attr;\n        abstract        CDATA   #IMPLIED\n        author          CDATA   #IMPLIED\n        copyright       CDATA   #IMPLIED\n\">\n\n<!--=================== SMIL Document =====================================-->\n<!--\n     The root element SMIL contains all other elements.\n-->\n<!ELEMENT smil (head?,body?)>\n<!ATTLIST smil\n        %id-attr;\n>\n\n<!--=================== The Document Head =================================-->\n<!ENTITY % layout-section \"layout|switch\">\n\n<!ENTITY % head-element \"(meta*,((%layout-section;), meta*))?\">\n\n<!ELEMENT head %head-element;>\n<!ATTLIST head %id-attr;>\n\n\n<!--=================== Layout Element ====================================-->\n<!--\n     Layout contains the region and root-layout elements defined by\n     smil-basic-layout or other elements defined an external layout \n     mechanism.\n-->\n<!ELEMENT layout (region|root-layout)>\n<!ATTLIST layout\n        %id-attr;\n        type CDATA      \"text/smil-basic-layout\"\n>\n\n\n<!--=================== Region Element ===================================-->\n<!ENTITY % viewport-attrs \"\n        height              CDATA    #IMPLIED\n        width               CDATA    #IMPLIED\n        background-color    CDATA    #IMPLIED\n\">\n\n<!ELEMENT region EMPTY>\n<!ATTLIST region\n        %id-attr;\n        %title-attr;\n        %viewport-attrs;\n        left                CDATA    \"0\"\n        top                 CDATA    \"0\"\n        z-index             CDATA    \"0\"\n        fit                 (hidden|fill|meet|scroll|slice)    \"hidden\"\n        %skip-attr;\n>\n\n<!--=================== Root-layout Element ================================-->\n<!ELEMENT root-layout EMPTY>\n<!ATTLIST root-layout\n        %id-attr;\n        %title-attr;\n        %viewport-attrs;\n        %skip-attr;\n>\n\n\n<!--=================== Meta Element=======================================-->\n<!ELEMENT meta EMPTY>\n<!ATTLIST meta\n        name    NMTOKEN #REQUIRED\n        content CDATA   #REQUIRED\n        %skip-attr;\n>\n\n<!--=================== The Document Body =================================-->\n<!ENTITY % media-object \"audio|video|text|img|animation|textstream|ref\">\n<!ENTITY % schedule \"par|seq|(%media-object;)\">\n<!ENTITY % inline-link \"a\">\n<!ENTITY % assoc-link \"anchor\">\n<!ENTITY % link \"%inline-link;\">\n<!ENTITY % container-content \"(%schedule;)|switch|(%link;)\">\n<!ENTITY % body-content \"(%container-content;)\">\n\n<!ELEMENT body (%body-content;)*>\n<!ATTLIST body %id-attr;>\n\n<!--=================== Synchronization Attributes ========================-->\n<!ENTITY % sync-attributes \"\n        begin   CDATA   #IMPLIED\n        end     CDATA   #IMPLIED\n\">\n\n<!--=================== Switch Parameter Attributes =======================-->\n<!ENTITY % system-attribute \"\n        system-bitrate             CDATA                #IMPLIED\n        system-language            CDATA                #IMPLIED\n        system-required            NMTOKEN              #IMPLIED\n        system-screen-size         CDATA                #IMPLIED\n        system-screen-depth        CDATA                #IMPLIED\n        system-captions            (on|off)             #IMPLIED\n        system-overdub-or-caption  (caption|overdub)    #IMPLIED\n\">\n\n<!--=================== Fill Attribute ====================================-->\n<!ENTITY % fill-attribute \"\n        fill    (remove|freeze)    'remove'\n\">\n\n\n<!--=================== The Parallel Element ==============================-->\n<!ENTITY % par-content \"%container-content;\">\n<!ELEMENT par    (%par-content;)*>\n<!ATTLIST par\n        %id-attr;\n        %desc-attr;\n        endsync CDATA           \"last\"\n        dur     CDATA           #IMPLIED\n        repeat  CDATA           \"1\"\n        region  IDREF           #IMPLIED\n        %sync-attributes;\n        %system-attribute;\n>\n\n<!--=================== The Sequential Element ============================-->\n<!ENTITY % seq-content \"%container-content;\">\n<!ELEMENT seq    (%seq-content;)*>\n<!ATTLIST seq\n        %id-attr;\n        %desc-attr;\n        dur     CDATA           #IMPLIED\n        repeat  CDATA           \"1\"\n        region  IDREF           #IMPLIED\n        %sync-attributes;\n        %system-attribute;\n>\n\n<!--=================== The Switch Element ================================-->\n<!-- In the head, a switch may contain only layout elements,\n     in the body, only container elements. However, this\n     constraint cannot be expressed in the DTD (?), so\n     we allow both:\n-->\n<!ENTITY % switch-content \"layout|(%container-content;)\">\n<!ELEMENT switch (%switch-content;)*>\n<!ATTLIST switch\n        %id-attr;\n        %title-attr;\n>\n\n<!--=================== Media Object Elements =============================-->\n<!-- SMIL only defines the structure. The real media data is\n     referenced by the src attribute of the media objects.\n-->\n\n<!-- Furthermore, they have the following attributes as defined\n     in the SMIL specification:\n-->\n<!ENTITY % mo-attributes \"\n        %id-attr;\n        %desc-attr;\n        region     IDREF           #IMPLIED\n        alt        CDATA           #IMPLIED\n        longdesc   CDATA           #IMPLIED\n        src        CDATA           #IMPLIED\n        type       CDATA           #IMPLIED\n        dur        CDATA           #IMPLIED\n        repeat     CDATA           '1'\n        %fill-attribute;\n        %sync-attributes;\n        %system-attribute;\n\">\n\n<!--\n     Most info is in the attributes, media objects are empty or\n     contain associated link elements:\n-->\n<!ENTITY % mo-content \"(%assoc-link;)*\">\n<!ENTITY % clip-attrs \"\n        clip-begin      CDATA   #IMPLIED\n        clip-end        CDATA   #IMPLIED\n\">\n\n<!ELEMENT ref           %mo-content;>\n<!ELEMENT audio         %mo-content;>\n<!ELEMENT img           %mo-content;>\n<!ELEMENT video         %mo-content;>\n<!ELEMENT text          %mo-content;>\n<!ELEMENT textstream    %mo-content;>\n<!ELEMENT animation     %mo-content;>\n\n<!ATTLIST ref           %mo-attributes; %clip-attrs;>\n<!ATTLIST audio         %mo-attributes; %clip-attrs;>\n<!ATTLIST video         %mo-attributes; %clip-attrs;>\n<!ATTLIST animation     %mo-attributes; %clip-attrs;>\n<!ATTLIST textstream    %mo-attributes; %clip-attrs;>\n<!ATTLIST text          %mo-attributes;>\n<!ATTLIST img           %mo-attributes;>\n\n<!--=================== Link Elements =====================================-->\n\n<!ENTITY % smil-link-attributes \"\n        %id-attr;\n        %title-attr;\n        href            CDATA                   #REQUIRED\n        show            (replace|new|pause)     'replace'\n\">\n\n\n<!--=================== Inline Link Element ===============================-->\n<!ELEMENT a (%schedule;|switch)*>\n<!ATTLIST a\n        %smil-link-attributes;\n>\n\n\n<!--=================== Associated Link Element ===========================-->\n<!ELEMENT anchor EMPTY>\n<!ATTLIST anchor\n        %skip-attr;\n        %smil-link-attributes;\n        %sync-attributes;\n        coords          CDATA                   #IMPLIED\n>\n\n"
  },
  {
    "path": "Units/parser-dtd.r/simple-dtd.d/args.ctags",
    "content": "--sort=no\n--fields=+reK\n--extras=+r\n"
  },
  {
    "path": "Units/parser-dtd.r/simple-dtd.d/expected.tags",
    "content": "resource-agent\tinput.dtd\t/^<!ELEMENT resource-agent (version,longdesc,shortdesc,parameters?,actions) >$/;\"\telement\troles:def\tend:5\nresource-agent\tinput.dtd\t/^<!ATTLIST resource-agent$/;\"\telement\troles:attOwner\tend:8\nname\tinput.dtd\t/^        name    CDATA   #REQUIRED$/;\"\tattribute\telement:resource-agent\troles:def\nversion\tinput.dtd\t/^        version CDATA   #IMPLIED>$/;\"\tattribute\telement:resource-agent\troles:def\nversion\tinput.dtd\t/^<!ELEMENT version (#PCDATA)>$/;\"\telement\troles:def\tend:10\nparameters\tinput.dtd\t/^<!ELEMENT parameters (parameter*)>$/;\"\telement\troles:def\tend:12\nactions\tinput.dtd\t/^<!ELEMENT actions (action*)>$/;\"\telement\troles:def\tend:14\nparameter\tinput.dtd\t/^<!ELEMENT parameter (longdesc+,shortdesc+,content)>$/;\"\telement\troles:def\tend:16\nparameter\tinput.dtd\t/^<!ATTLIST parameter$/;\"\telement\troles:attOwner\tend:20\nname\tinput.dtd\t/^        name    CDATA   #REQUIRED$/;\"\tattribute\telement:parameter\troles:def\nrequired\tinput.dtd\t/^        required  (1|0)   \"0\"$/;\"\tattribute\telement:parameter\troles:def\nunique\tinput.dtd\t/^        unique  (1|0)   \"0\">$/;\"\tattribute\telement:parameter\troles:def\nlongdesc\tinput.dtd\t/^<!ELEMENT longdesc ANY>$/;\"\telement\troles:def\tend:22\nlongdesc\tinput.dtd\t/^<!ATTLIST longdesc$/;\"\telement\troles:attOwner\tend:24\nlang\tinput.dtd\t/^        lang    NMTOKEN #IMPLIED>$/;\"\tattribute\telement:longdesc\troles:def\nshortdesc\tinput.dtd\t/^<!ELEMENT shortdesc ANY>$/;\"\telement\troles:def\tend:26\nshortdesc\tinput.dtd\t/^<!ATTLIST shortdesc$/;\"\telement\troles:attOwner\tend:28\nlang\tinput.dtd\t/^        lang    NMTOKEN #IMPLIED>$/;\"\tattribute\telement:shortdesc\troles:def\ncontent\tinput.dtd\t/^<!ELEMENT content EMPTY>$/;\"\telement\troles:def\tend:30\ncontent\tinput.dtd\t/^<!ATTLIST content$/;\"\telement\troles:attOwner\tend:33\ntype\tinput.dtd\t/^        type    (string|integer|boolean|time)        #REQUIRED$/;\"\tattribute\telement:content\troles:def\ndefault\tinput.dtd\t/^        default CDATA   #IMPLIED>$/;\"\tattribute\telement:content\troles:def\naction\tinput.dtd\t/^<!ELEMENT action EMPTY>$/;\"\telement\troles:def\tend:35\naction\tinput.dtd\t/^<!ATTLIST action$/;\"\telement\troles:attOwner\tend:42\nname\tinput.dtd\t/^        name (start|stop|recover|monitor|restart|migrate_to|migrate_from|promote|demote|notify|s/;\"\tattribute\telement:action\troles:def\ntimeout\tinput.dtd\t/^        timeout         CDATA   #REQUIRED$/;\"\tattribute\telement:action\troles:def\ninterval\tinput.dtd\t/^        interval        CDATA   #IMPLIED$/;\"\tattribute\telement:action\troles:def\nstart-delay\tinput.dtd\t/^        start-delay     CDATA   #IMPLIED$/;\"\tattribute\telement:action\troles:def\nrole\tinput.dtd\t/^        role            CDATA   #IMPLIED$/;\"\tattribute\telement:action\troles:def\ndepth\tinput.dtd\t/^        depth           CDATA   #IMPLIED>$/;\"\tattribute\telement:action\troles:def\n"
  },
  {
    "path": "Units/parser-dtd.r/simple-dtd.d/input.dtd",
    "content": "<!-- Taken from pacemaker/src/resource-agents/heartbeat/ra-api-1.dtd  -->\n\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!ELEMENT resource-agent (version,longdesc,shortdesc,parameters?,actions) >\n<!ATTLIST resource-agent\n        name    CDATA   #REQUIRED\n        version CDATA   #IMPLIED>\n\n<!ELEMENT version (#PCDATA)>\n\n<!ELEMENT parameters (parameter*)>\n\n<!ELEMENT actions (action*)>\n\n<!ELEMENT parameter (longdesc+,shortdesc+,content)>\n<!ATTLIST parameter\n        name    CDATA   #REQUIRED\n        required  (1|0)   \"0\"\n        unique  (1|0)   \"0\">\n\n<!ELEMENT longdesc ANY>\n<!ATTLIST longdesc\n        lang    NMTOKEN #IMPLIED>\n\n<!ELEMENT shortdesc ANY>\n<!ATTLIST shortdesc\n        lang    NMTOKEN #IMPLIED>\n\n<!ELEMENT content EMPTY>\n<!ATTLIST content\n        type    (string|integer|boolean|time)        #REQUIRED\n        default CDATA   #IMPLIED>\n\n<!ELEMENT action EMPTY>\n<!ATTLIST action\n        name (start|stop|recover|monitor|restart|migrate_to|migrate_from|promote|demote|notify|status|reload|meta-data|usage|methods|validate-all) #REQUIRED\n        timeout         CDATA   #REQUIRED\n        interval        CDATA   #IMPLIED\n        start-delay     CDATA   #IMPLIED\n        role            CDATA   #IMPLIED\n        depth           CDATA   #IMPLIED>\n"
  },
  {
    "path": "Units/parser-dts.r/dts-core-dump.d/input.dts",
    "content": "m{"
  },
  {
    "path": "Units/parser-dts.r/dts-fq-core-dump.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-dts.r/dts-fq-core-dump.d/args.ctags",
    "content": "--extras=+q\n"
  },
  {
    "path": "Units/parser-dts.r/dts-fq-core-dump.d/input.dts",
    "content": "m{"
  },
  {
    "path": "Units/parser-dts.r/dts-fq-without-scope-field.d/README",
    "content": "This test case verifies a corner use case of Cork based automatic full\nqualified tag generator(FQgen).\n\nFQgen caches scope informations built just before emitting it as value\nfor scope fields. Therefore when --field=-s(disabling scope field) is\ngiven, FQ tags were not generated.\n"
  },
  {
    "path": "Units/parser-dts.r/dts-fq-without-scope-field.d/args.ctags",
    "content": "--fields=+r-s\n--extras=+rq\n"
  },
  {
    "path": "Units/parser-dts.r/dts-fq-without-scope-field.d/expected.tags",
    "content": "0x00\tinput.dts\t/^\t     phandle = <0x00>;$/;\"\tp\troles:def\nbar\tinput.dts\t/^#define bar /;\"\td\tfile:\troles:def\nbar\tinput.dts\t/^#undef bar$/;\"\td\tfile:\troles:undef\nfoo.dtsi\tinput.dts\t/^#include \"foo.dtsi\"/;\"\th\troles:local\nlabel\tinput.dts\t/^label: test {$/;\"\tl\troles:def\nlabel.0x00\tinput.dts\t/^\t     phandle = <0x00>;$/;\"\tp\troles:def\nlabel.label2\tinput.dts\t/^\t     label2: chosen { } ;$/;\"\tl\troles:def\nlabel2\tinput.dts\t/^\t     label2: chosen { } ;$/;\"\tl\troles:def\n"
  },
  {
    "path": "Units/parser-dts.r/dts-fq-without-scope-field.d/input.dts",
    "content": "/dts-v1/;\n\n#include \"foo.dtsi\"\n#define bar 98\n\nlabel: test {\n       dummy {\n\t     label2: chosen { } ;\n\t     phandle = <0x00>;\n       };\n};\n#undef bar\n"
  },
  {
    "path": "Units/parser-dts.r/dts-simple.d/args.ctags",
    "content": "--fields=+Zrl\n--extras=+rq\n"
  },
  {
    "path": "Units/parser-dts.r/dts-simple.d/expected.tags",
    "content": "0x00\tinput.dts\t/^\t     phandle = <0x00>;$/;\"\tp\tlanguage:DTS\tscope:label:label\troles:def\nbar\tinput.dts\t/^#define bar /;\"\td\tlanguage:CPreProcessor\tfile:\troles:def\nbar\tinput.dts\t/^#undef bar$/;\"\td\tlanguage:CPreProcessor\tfile:\troles:undef\nfoo.dtsi\tinput.dts\t/^#include \"foo.dtsi\"/;\"\th\tlanguage:CPreProcessor\troles:local\nlabel\tinput.dts\t/^label: test {$/;\"\tl\tlanguage:DTS\troles:def\nlabel.0x00\tinput.dts\t/^\t     phandle = <0x00>;$/;\"\tp\tlanguage:DTS\tscope:label:label\troles:def\nlabel.label2\tinput.dts\t/^\t     label2: chosen { } ;$/;\"\tl\tlanguage:DTS\tscope:label:label\troles:def\nlabel2\tinput.dts\t/^\t     label2: chosen { } ;$/;\"\tl\tlanguage:DTS\tscope:label:label\troles:def\n"
  },
  {
    "path": "Units/parser-dts.r/dts-simple.d/input.dts",
    "content": "/dts-v1/;\n\n#include \"foo.dtsi\"\n#define bar 98\n\nlabel: test {\n       dummy {\n\t     label2: chosen { } ;\n\t     phandle = <0x00>;\n       };\n};\n#undef bar\n"
  },
  {
    "path": "Units/parser-eiffel.r/aliases.e.d/expected.tags",
    "content": "<\tinput.e\t/^\ta alias \"<\", b (other: like Current): BOOLEAN$/;\"\tf\tclass:ALIASES\nALIASES\tinput.e\t/^class ALIASES$/;\"\tc\n^\tinput.e\t/^\tyor alias \"^\", zor (other: like Current): INTEGER$/;\"\tf\tclass:ALIASES\na\tinput.e\t/^\ta alias \"<\", b (other: like Current): BOOLEAN$/;\"\tf\tclass:ALIASES\nattribute_a\tinput.e\t/^\tattribute_a, attribute_b: INTEGER$/;\"\tf\tclass:ALIASES\nattribute_b\tinput.e\t/^\tattribute_a, attribute_b: INTEGER$/;\"\tf\tclass:ALIASES\nb\tinput.e\t/^\ta alias \"<\", b (other: like Current): BOOLEAN$/;\"\tf\tclass:ALIASES\nconstant_a\tinput.e\t/^\tconstant_a, constant_b: INTEGER = 1$/;\"\tf\tclass:ALIASES\nconstant_b\tinput.e\t/^\tconstant_a, constant_b: INTEGER = 1$/;\"\tf\tclass:ALIASES\nfunction1a\tinput.e\t/^\tfunction1a, function1b (one: DOUBLE): DOUBLE$/;\"\tf\tclass:ALIASES\nfunction1b\tinput.e\t/^\tfunction1a, function1b (one: DOUBLE): DOUBLE$/;\"\tf\tclass:ALIASES\nprocedure1a\tinput.e\t/^\tprocedure1a, procedure1b (one: DOUBLE)$/;\"\tf\tclass:ALIASES\nprocedure1b\tinput.e\t/^\tprocedure1a, procedure1b (one: DOUBLE)$/;\"\tf\tclass:ALIASES\nyor\tinput.e\t/^\tyor alias \"^\", zor (other: like Current): INTEGER$/;\"\tf\tclass:ALIASES\nzor\tinput.e\t/^\tyor alias \"^\", zor (other: like Current): INTEGER$/;\"\tf\tclass:ALIASES\n"
  },
  {
    "path": "Units/parser-eiffel.r/aliases.e.d/input.e",
    "content": "class ALIASES\n\nfeature -- One\n\n\tattribute_a, attribute_b: INTEGER\n\n\tconstant_a, constant_b: INTEGER = 1\n\nfeature -- Two\n\n\tfunction1a, function1b (one: DOUBLE): DOUBLE\n\t\tdo\n\t\tend\n\nfeature -- Three\n\n\tprocedure1a, procedure1b (one: DOUBLE)\n\t\tdo\n\t\tend\n\n\ta alias \"<\", b (other: like Current): BOOLEAN\n\t\tdo\n\t\tend\n\n\tyor alias \"^\", zor (other: like Current): INTEGER\n\t\tdo\n\t\tend\n\nend\n"
  },
  {
    "path": "Units/parser-eiffel.r/attributes.e.d/expected.tags",
    "content": "ATTRIBUTES\tinput.e\t/^expanded class ATTRIBUTES$/;\"\tc\nanchored\tinput.e\t/^\tanchored: like one$/;\"\tf\tclass:ATTRIBUTES\nattribute_full\tinput.e\t/^\tattribute_full: STRING$/;\"\tf\tclass:ATTRIBUTES\nattribute_short\tinput.e\t/^\tattribute_short: STRING$/;\"\tf\tclass:ATTRIBUTES\neight\tinput.e\t/^\teight: DOUBLE = 2.0$/;\"\tf\tclass:ATTRIBUTES\nfinal_feature\tinput.e\t/^\tfinal_feature$/;\"\tf\tclass:ATTRIBUTES\nfive\tinput.e\t/^\tfive, six: INTEGER = unique$/;\"\tf\tclass:ATTRIBUTES\nfour\tinput.e\t/^\tfour: DOUBLE$/;\"\tf\tclass:ATTRIBUTES\nnine\tinput.e\t/^\tnine: STRING = \"abc\"$/;\"\tf\tclass:ATTRIBUTES\none\tinput.e\t/^\tone: INTEGER$/;\"\tf\tclass:ATTRIBUTES\nseven\tinput.e\t/^\tseven: INTEGER = 1$/;\"\tf\tclass:ATTRIBUTES\nsix\tinput.e\t/^\tfive, six: INTEGER = unique$/;\"\tf\tclass:ATTRIBUTES\nthree\tinput.e\t/^\tthree: HASH_TABLE [ARRAY [DOUBLE], STRING]$/;\"\tf\tclass:ATTRIBUTES\ntwo\tinput.e\t/^\ttwo: ARRAY [STRING]$/;\"\tf\tclass:ATTRIBUTES\n"
  },
  {
    "path": "Units/parser-eiffel.r/attributes.e.d/input.e",
    "content": "expanded class ATTRIBUTES\n\nfeature\n\n\tone: INTEGER\n\t\t\t-- Header comment\n\n\ttwo: ARRAY [STRING]\n\t\t\t-- Header comment\n\n\tthree: HASH_TABLE [ARRAY [DOUBLE], STRING]\n\t\t\t-- Header comment\n\n\tfour: DOUBLE\n\t\t\t-- Header comment\n\n\tfive, six: INTEGER = unique\n\t\t\t-- Header comment\n\n\tseven: INTEGER = 1\n\t\t\t-- Header comment\n\n\teight: DOUBLE = 2.0\n\t\t\t-- Header comment\n\n\tnine: STRING = \"abc\"\n\t\t\t-- Header comment\n\n\tanchored: like one\n\t\t\t-- Header comment\n\n\tattribute_short: STRING\n\t\t\t-- Header comment\n\t\tattribute\n\t\tend\n\n\tattribute_full: STRING\n\t\t\t-- Header comment\n\t\tnote\n\t\tobsolete\n\t\t\t\"Obsolete message\"\n\t\trequire\n\t\tlocal\n\t\tattribute\n\t\t\t-- Implementation\n\t\tensure\n\t\trescue\n\t\tend\n\n\tfinal_feature\n\t\tdo\n\t\tend\n\nend\n"
  },
  {
    "path": "Units/parser-eiffel.r/class.e.d/expected.tags",
    "content": "//\tinput.e\t/^\t\t\tinfix \"\\/\" as infix \"\\/\\/\"$/;\"\tf\tclass:UBER_CLASS\nUBER_CLASS\tinput.e\t/^deferred class UBER_CLASS [G -> CONSTRAINT] obsolete \"message\"$/;\"\tc\nguard\tinput.e\t/^\tguard: INTEGER$/;\"\tf\tclass:UBER_CLASS\nmake\tinput.e\t/^\tmake$/;\"\tf\tclass:UBER_CLASS\nmake2\tinput.e\t/^\tmake2$/;\"\tf\tclass:UBER_CLASS\nmake3\tinput.e\t/^\tmake3$/;\"\tf\tclass:UBER_CLASS\nmy_generating_type\tinput.e\t/^\t\t\tgenerating_type as my_generating_type,$/;\"\tf\tclass:UBER_CLASS\nmy_generator\tinput.e\t/^\t\t\tgenerator as my_generator,$/;\"\tf\tclass:UBER_CLASS\nprocedure_full\tinput.e\t/^\tprocedure_full$/;\"\tf\tclass:UBER_CLASS\n"
  },
  {
    "path": "Units/parser-eiffel.r/class.e.d/input.e",
    "content": "note\n\n\tdescription: \"Try everything\"\n\ndeferred class UBER_CLASS [G -> CONSTRAINT] obsolete \"message\"\n\ninherit\n\n\tANY\n\t\trename\n\t\t\tgenerator as my_generator,\n\t\t\tgenerating_type as my_generating_type,\n\t\t\tinfix \"/\" as infix \"//\"\n\t\texport\n\t\t\t{NONE} my_generator, my_generating_type;\n\t\t\t{ANY} same_type\n\t\tundefine\n\t\t\tis_equal\n\t\tredefine\n\t\t\tconforms_to\n\t\tselect\n\t\t\tconsitent\n\t\tend\n\n\tLINKED_LIST [G]\n\t\texport {NONE}\n\t\t\tall\n\t\tend\n\ncreate\n\n\tmake, make2\n\ncreate {SOMETHING}\n\n\tmake3\n\nfeature -- Initialization\n\n\tmake\n\t\tdo\n\t\tend\n\n\tmake2\n\t\tdo\n\t\tend\n\n\tmake3\n\t\tdo\n\t\tend\n\nfeature {ANY, NONE} -- Feature clause comment\n\n\tprocedure_full\n\t\trequire else\n\t\tlocal\n\t\tdo\n\t\tensure then\n\t\trescue\n\t\tend\n\n\tguard: INTEGER\n\ninvariant\n\n\tlabel: condition\n\nnote\n\n\tlicense: \"May not be used for any purpose\"\n\nend\n"
  },
  {
    "path": "Units/parser-eiffel.r/deprecated-syntax.e.d/README",
    "content": "Currently (July 2016) the keywords \"indexing\", \"is\", and \"creation\" are all\ndeprecated in both the Eiffel Software and Liberty Eiffel dialects.\n\nThe \"infix\" and \"prefix\" keywords are deprecated by Eiffel Software. Liberty\nEiffel currently still supports them alongside \"alias\" though this is expected\nto change in the near future.\n"
  },
  {
    "path": "Units/parser-eiffel.r/deprecated-syntax.e.d/expected.tags",
    "content": "+\tinput.e\t/^\tprefix \"+\": like Current$/;\"\tf\tclass:DEPRECATED_SYNTAX_TEST\n//\tinput.e\t/^\t\t\tinfix \"\\/\" as infix \"\\/\\/\"$/;\"\tf\tclass:DEPRECATED_SYNTAX_TEST\n<\tinput.e\t/^\tinfix \"<\" (other: like Current): BOOLEAN$/;\"\tf\tclass:DEPRECATED_SYNTAX_TEST\nDEPRECATED_SYNTAX_TEST\tinput.e\t/^\tDEPRECATED_SYNTAX_TEST$/;\"\tc\nfeature1\tinput.e\t/^\tfeature1 is$/;\"\tf\tclass:DEPRECATED_SYNTAX_TEST\nfeature2\tinput.e\t/^\tfeature2: INTEGER is 42$/;\"\tf\tclass:DEPRECATED_SYNTAX_TEST\nmake\tinput.e\t/^\tmake is$/;\"\tf\tclass:DEPRECATED_SYNTAX_TEST\n"
  },
  {
    "path": "Units/parser-eiffel.r/deprecated-syntax.e.d/input.e",
    "content": "indexing\n\tlabel1: \"value\"\n\nclass\n\tDEPRECATED_SYNTAX_TEST\n\ninherit\n\tANY\n\t\trename\n\t\t\tinfix \"/\" as infix \"//\"\n\t\tend\ncreation\n\tmake\n\nfeature\n\tmake is\n\t\tdo\n\t\tend\n\n\tfeature1 is\n\t\t\t-- Header comment\n\t\tindexing\n\t\tobsolete\n\t\t\t\"Obsolete message\"\n\t\trequire\n\t\tlocal\n\t\tdo\n\t\tend\n\n\tfeature2: INTEGER is 42\n\n\tinfix \"<\" (other: like Current): BOOLEAN\n\t\tdo\n\t\tend\n\n\tprefix \"+\": like Current\n\t\tdo\n\t\tend\n\nindexing\n\tlabel2: \"value\"\nend\n"
  },
  {
    "path": "Units/parser-eiffel.r/functions.e.d/expected.tags",
    "content": "+\tinput.e\t/^\tprefix_alias alias \"+\": like Current$/;\"\tf\tclass:FUNCTIONS\n<\tinput.e\t/^\tinfix_alias alias \"<\" (other: like Current): BOOLEAN$/;\"\tf\tclass:FUNCTIONS\nFUNCTIONS\tinput.e\t/^deferred class FUNCTIONS$/;\"\tc\nfunction0\tinput.e\t/^\tfunction0: INTEGER$/;\"\tf\tclass:FUNCTIONS\nfunction1\tinput.e\t/^\tfunction1 (one: STRING)$/;\"\tf\tclass:FUNCTIONS\nfunction2\tinput.e\t/^\tfunction2 (one: INTEGER; two: STRING): INTEGER$/;\"\tf\tclass:FUNCTIONS\nfunction_anchored\tinput.e\t/^\tfunction_anchored: like function0$/;\"\tf\tclass:FUNCTIONS\nfunction_full\tinput.e\t/^\tfunction_full (one: STRING)$/;\"\tf\tclass:FUNCTIONS\ninfix_alias\tinput.e\t/^\tinfix_alias alias \"<\" (other: like Current): BOOLEAN$/;\"\tf\tclass:FUNCTIONS\nprefix_alias\tinput.e\t/^\tprefix_alias alias \"+\": like Current$/;\"\tf\tclass:FUNCTIONS\n"
  },
  {
    "path": "Units/parser-eiffel.r/functions.e.d/input.e",
    "content": "deferred class FUNCTIONS\n\nfeature -- One\n\n\tfunction0: INTEGER\n\t\tdo\n\t\tend\n\nfeature -- Two\n\n\tfunction1 (one: STRING)\n\t\tonce\n\t\tend\n\n\tfunction2 (one: INTEGER; two: STRING): INTEGER\n\t\tdeferred\n\t\tend\n\n\tfunction_anchored: like function0\n\t\tdo\n\t\tend\n\n\tfunction_full (one: STRING)\n\t\t\t-- header comment\n\t\tnote\n\t\tobsolete\n\t\t\t\"Obsolete message\"\n\t\trequire\n\t\tlocal\n\t\tdo\n\t\t\t-- Implementation\n\t\tensure\n\t\trescue\n\t\tend\n\n\tinfix_alias alias \"<\" (other: like Current): BOOLEAN\n\t\tdo\n\t\tend\n\n\tprefix_alias alias \"+\": like Current\n\t\tdo\n\t\tend\n\nend\n"
  },
  {
    "path": "Units/parser-eiffel.r/inherit-rename.e.d/expected.tags",
    "content": "INHERIT_RENAME_TEST\tinput.e\t/^class INHERIT_RENAME_TEST$/;\"\tc\nfeat2\tinput.e\t/^         feat1 as feat2$/;\"\tf\tclass:INHERIT_RENAME_TEST\nfeat4\tinput.e\t/^         feat3 as feat4$/;\"\tf\tclass:INHERIT_RENAME_TEST\n"
  },
  {
    "path": "Units/parser-eiffel.r/inherit-rename.e.d/input.e",
    "content": "class INHERIT_RENAME_TEST\n\ninherit\n\n   FOO\n      rename\n         feat1 as feat2\n      end\n\ninsert\n\n   BAR\n      rename\n         feat3 as feat4\n      end\n\nend\n"
  },
  {
    "path": "Units/parser-eiffel.r/local-kind.e.d/args.ctags",
    "content": "--kinds-Eiffel=+l\n"
  },
  {
    "path": "Units/parser-eiffel.r/local-kind.e.d/expected.tags",
    "content": "LOCAL_KIND_TEST\tinput.e\t/^class LOCAL_KIND_TEST$/;\"\tc\nc\tinput.e\t/^         s: STRING; c: CHARACTER$/;\"\tl\tfeature:LOCAL_KIND_TEST.feature1\tfile:\nfeature1\tinput.e\t/^   feature1$/;\"\tf\tclass:LOCAL_KIND_TEST\ni\tinput.e\t/^         i: INTEGER$/;\"\tl\tfeature:LOCAL_KIND_TEST.feature1\tfile:\nj\tinput.e\t/^         j, k: INTEGER$/;\"\tl\tfeature:LOCAL_KIND_TEST.feature1\tfile:\nk\tinput.e\t/^         j, k: INTEGER$/;\"\tl\tfeature:LOCAL_KIND_TEST.feature1\tfile:\ns\tinput.e\t/^         s: STRING; c: CHARACTER$/;\"\tl\tfeature:LOCAL_KIND_TEST.feature1\tfile:\n"
  },
  {
    "path": "Units/parser-eiffel.r/local-kind.e.d/input.e",
    "content": "class LOCAL_KIND_TEST\n\nfeature\n\n   feature1\n      local\n         i: INTEGER\n         j, k: INTEGER\n         s: STRING; c: CHARACTER\n      do\n      end\n\nend\n"
  },
  {
    "path": "Units/parser-eiffel.r/note.e.d/expected.tags",
    "content": "NOTE_\tinput.e\t/^class NOTE_$/;\"\tc\n"
  },
  {
    "path": "Units/parser-eiffel.r/note.e.d/input.e",
    "content": "note\n\n\tdescription: \"A simple description\"\n\nclass NOTE_\n\nnote\n\n\tlicense: \"Eiffel Forum License, version 1\"\n\nend\n"
  },
  {
    "path": "Units/parser-eiffel.r/obsolete.e.d/expected.tags",
    "content": "OBSOLETE_\tinput.e\t/^class OBSOLETE_ obsolete \"Use a different one\"$/;\"\tc\nobsolete_attribute\tinput.e\t/^\tobsolete_attribute: INTEGER obsolete \"Use something else\"$/;\"\tf\tclass:OBSOLETE_\nobsolete_function\tinput.e\t/^\tobsolete_function (one: INTEGER): INTEGER obsolete \"Use something else\"$/;\"\tf\tclass:OBSOLETE_\nobsolete_procedure\tinput.e\t/^\tobsolete_procedure (one: INTEGER) obsolete \"Use something else\"$/;\"\tf\tclass:OBSOLETE_\n"
  },
  {
    "path": "Units/parser-eiffel.r/obsolete.e.d/input.e",
    "content": "class OBSOLETE_ obsolete \"Use a different one\"\n\nfeature\n\n\tobsolete_attribute: INTEGER obsolete \"Use something else\"\n\t\tattribute\n\t\tend\n\n\tobsolete_function (one: INTEGER): INTEGER obsolete \"Use something else\"\n\t\tdo\n\t\tend\n\n\tobsolete_procedure (one: INTEGER) obsolete \"Use something else\"\n\t\tdo\n\t\tend\n\nend\n"
  },
  {
    "path": "Units/parser-eiffel.r/procedures.e.d/expected.tags",
    "content": "PROCEDURES\tinput.e\t/^deferred class PROCEDURES$/;\"\tc\nprocedure0\tinput.e\t/^\tprocedure0$/;\"\tf\tclass:PROCEDURES\nprocedure1\tinput.e\t/^\tprocedure1 (one: STRING)$/;\"\tf\tclass:PROCEDURES\nprocedure2\tinput.e\t/^\tprocedure2 (one: INTEGER; two: STRING)$/;\"\tf\tclass:PROCEDURES\nprocedure_full\tinput.e\t/^\tprocedure_full (one: STRING)$/;\"\tf\tclass:PROCEDURES\n"
  },
  {
    "path": "Units/parser-eiffel.r/procedures.e.d/input.e",
    "content": "deferred class PROCEDURES\n\nfeature -- One\n\n\tprocedure0\n\t\tdo\n\t\tend\n\nfeature -- Two\n\n\tprocedure1 (one: STRING)\n\t\tonce\n\t\tend\n\n\tprocedure2 (one: INTEGER; two: STRING)\n\t\tdeferred\n\t\tend\n\n\tprocedure_full (one: STRING)\n\t\t\t-- header comment\n\t\tnote\n\t\tobsolete\n\t\t\t\"Obsolete message\"\n\t\trequire\n\t\tlocal\n\t\tdo\n\t\t\t-- Implementation\n\t\tensure\n\t\trescue\n\t\tend\n\nend\n"
  },
  {
    "path": "Units/parser-eiffel.r/verbatim.e.d/expected.tags",
    "content": "VERBATIM\tinput.e\t/^class VERBATIM$/;\"\tc\nconstant\tinput.e\t/^\tconstant: STRING = \"[$/;\"\tf\tclass:VERBATIM\ncpp_query\tinput.e\t/^\tcpp_query (obj: FX_OBJECT; app: POINTER): POINTER$/;\"\tf\tclass:VERBATIM\tfile:\ntail_attribute\tinput.e\t/^\ttail_attribute: INTEGER$/;\"\tf\tclass:VERBATIM\tfile:\n"
  },
  {
    "path": "Units/parser-eiffel.r/verbatim.e.d/input.e",
    "content": "note\n\n\tdescription: \"[\n\t\tThis is a verbatim string.\n\t\t]\"\n\nclass VERBATIM\n\nfeature -- Sample\n\n\tconstant: STRING = \"[\n\t\t\tVertbatim constant\n\t\t\t]\"\n\nfeature {NONE} -- Implementation\n\n\tcpp_query (obj: FX_OBJECT; app: POINTER): POINTER\n\t\t\t-- Header comment\n\t\texternal \"[\n\t\t\tC++ [ClassName %\"EFXVisual.h%\"]\n\t\t\t(EIF_OBJECT, FXApp*): void*\n\t\t\t]\"\n\t\tend\n\n\ttail_attribute: INTEGER\n\nnote\n\n\tlibrary: \"[\n\t\t\tEiffelBase: Library of reusable components for Eiffel.\n\t\t\t]\"\n\n\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-callbacks.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-callbacks.d/expected.tags",
    "content": "CallbackModule\tinput.ex\t/^defmodule CallbackModule do$/;\"\tmodule\nnew_callback\tinput.ex\t/^  @callback new_callback() :: integer$/;\"\tcallback\tmodule:CallbackModule\nold_callback\tinput.ex\t/^  defcallback old_callback(info :: integer) :: integer$/;\"\tcallback\tmodule:CallbackModule\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-callbacks.d/input.ex",
    "content": "defmodule CallbackModule do\n  use Behaviour\n  # This is the new callback syntax\n  @callback new_callback() :: integer\n\n  # This is the old (deprecated) callback syntax\n  defcallback old_callback(info :: integer) :: integer\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-exceptions.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-exceptions.d/expected.tags",
    "content": "ModuleError\tinput.ex\t/^defmodule ModuleError do$/;\"\tmodule\nModuleError\tinput.ex\t/^  defexception [:message]$/;\"\texception\tmodule:ModuleError\nexception\tinput.ex\t/^  def exception(value) do$/;\"\tfunction\tmodule:ModuleError\taccess:public\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-exceptions.d/input.ex",
    "content": "defmodule ModuleError do\n  defexception [:message]\n\n  @impl true\n  def exception(value) do\n    msg = \"did not get what was expected, got: #{inspect(value)}\"\n    %ModuleError{message: msg}\n  end\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-functions.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-functions.d/expected.tags",
    "content": "FunctionModule\tinput.ex\t/^defmodule FunctionModule do$/;\"\tmodule\none_liner_func\tinput.ex\t/^  def one_liner_func, do: :baz$/;\"\tfunction\tmodule:FunctionModule\taccess:public\nfunc_no_params\tinput.ex\t/^  def func_no_params do$/;\"\tfunction\tmodule:FunctionModule\taccess:public\nfunc_head\tinput.ex\t/^  def func_head(string1, string2 \\\\\\\\ nil, separator \\\\\\\\ \" \")$/;\"\tfunction\tmodule:FunctionModule\taccess:public\nfunc_one_arity\tinput.ex\t/^  def func_one_arity(string1, nil, _separator) do$/;\"\tfunction\tmodule:FunctionModule\taccess:public\nnormal_func\tinput.ex\t/^  def normal_func(string1, string2, separator) do$/;\"\tfunction\tmodule:FunctionModule\taccess:public\nprivate_func\tinput.ex\t/^  defp private_func(a), do: a <> \" alone\"$/;\"\tfunction\tmodule:FunctionModule\taccess:private\nprivate_func_no_params\tinput.ex\t/^  defp private_func_no_params do$/;\"\tfunction\tmodule:FunctionModule\taccess:private\nfunction_with_comma\tinput.ex\t/^  def function_with_comma,$/;\"\tfunction\tmodule:FunctionModule\taccess:public\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-functions.d/input.ex",
    "content": "defmodule FunctionModule do\n  def one_liner_func, do: :baz\n\n  def func_no_params do\n    #\n  end\n\n  # Function head\n  def func_head(string1, string2 \\\\ nil, separator \\\\ \" \")\n\n  # Function with 1 arity\n  def func_one_arity(string1, nil, _separator) do\n    private_function(string1)\n  end\n\n  # Normal function\n  def normal_func(string1, string2, separator) do\n    string1 <> separator <> string2\n  end\n\n  # Private function\n  defp private_func(a), do: a <> \" alone\"\n\n  defp private_func_no_params do\n    #\n  end\n\n  def function_with_comma,\n    do: :some_constant\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-macros.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-macros.d/expected.tags",
    "content": "MacroModule\tinput.ex\t/^defmodule MacroModule do$/;\"\tmodule\nmacro\tinput.ex\t/^  defmacro macro(expr, opts) do$/;\"\tmacro\tmodule:MacroModule\taccess:public\nmacro_no_params\tinput.ex\t/^  defmacro macro_no_params do$/;\"\tmacro\tmodule:MacroModule\taccess:public\nprivate_macro\tinput.ex\t/^  defmacrop private_macro(expr, opts) do$/;\"\tmacro\tmodule:MacroModule\taccess:private\nprivate_macro_no_params\tinput.ex\t/^  defmacrop private_macro_no_params do$/;\"\tmacro\tmodule:MacroModule\taccess:private\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-macros.d/input.ex",
    "content": "defmodule MacroModule do\n  defmacro macro(expr, opts) do\n    #\n  end\n\n  defmacro macro_no_params do\n    #\n  end\n\n  defmacrop private_macro(expr, opts) do\n    #\n  end\n\n  defmacrop private_macro_no_params do\n    #\n  end\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-modules.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-modules.d/expected.tags",
    "content": "Foo\tinput.ex\t/^defmodule Foo do$/;\"\tmodule\nBar\tinput.ex\t/^defmodule Foo.Bar do$/;\"\tmodule\nBaz\tinput.ex\t/^  defmodule Baz do$/;\"\tmodule\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-modules.d/input.ex",
    "content": "defmodule Foo do\nend\n\ndefmodule Foo.Bar do\n  defmodule Baz do\n  end\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-records.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-records.d/expected.tags",
    "content": "RecordsModule\tinput.ex\t/^defmodule RecordsModule do$/;\"\tmodule\nuser1\tinput.ex\t/^  Record.defrecord(:user1, name: \"megan\", age: \"25\")$/;\"\trecord\tmodule:RecordsModule\taccess:public\nuser2\tinput.ex\t/^  Record.defrecordp :user2, name: \"ivan\", age: \"23\"$/;\"\trecord\tmodule:RecordsModule\taccess:private\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-records.d/input.ex",
    "content": "defmodule RecordsModule do\n  require Record\n  Record.defrecord(:user1, name: \"megan\", age: \"25\")\n  Record.defrecordp :user2, name: \"ivan\", age: \"23\"\n  # This is not a typo but an intentional bad test, used to test the parser\n  Record.defrecordp:bad, name: \"ivan\", age: \"23\"\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-sign-operators.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-sign-operators.d/expected.tags",
    "content": "OperatorModule\tinput.ex\t/^defmodule OperatorModule do$/;\"\tmodule\n+\tinput.ex\t/^  def a + b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n-\tinput.ex\t/^  def a - b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n*\tinput.ex\t/^  def a * b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n/\tinput.ex\t/^  def a \\/ b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n=\tinput.ex\t/^  def a = b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n.\tinput.ex\t/^  def a . b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n|\tinput.ex\t/^  def a | b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n|||\tinput.ex\t/^  def _ ||| b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n&&&\tinput.ex\t/^  def a &&& _, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n<<<\tinput.ex\t/^  def a <<< b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n>>>\tinput.ex\t/^  defp a >>> b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n<<~\tinput.ex\t/^  defp _ <<~ _, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n~>>\tinput.ex\t/^  defp a ~>> b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n<~\tinput.ex\t/^  defmacro a <~ b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n~>\tinput.ex\t/^  defmacro _ ~> b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n<~>\tinput.ex\t/^  defmacro a <~> _, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n<|>\tinput.ex\t/^  defmacrop a <|> b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n^^^\tinput.ex\t/^  defmacrop _ ^^^ _, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n~~~\tinput.ex\t/^  defmacrop a ~~~ b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-sign-operators.d/input.ex",
    "content": "defmodule OperatorModule do\n  def a + b, do: max(a, b)\n  def a - b, do: max(a, b)\n  def a * b, do: max(a, b)\n  def a / b, do: max(a, b)\n  def a = b, do: max(a, b)\n  def a . b, do: max(a, b)\n\n  # The 13 operators bellow are ALL the operators that Elixir is CAPABLE of\n  # parsing and are not used by default, so the user can\n  def a | b, do: max(a, b)\n  def _ ||| b, do: max(a, b)\n  def a &&& _, do: max(a, b)\n  def a <<< b, do: max(a, b)\n  defp a >>> b, do: max(a, b)\n  defp _ <<~ _, do: max(a, b)\n  defp a ~>> b, do: max(a, b)\n  defmacro a <~ b, do: max(a, b)\n  defmacro _ ~> b, do: max(a, b)\n  defmacro a <~> _, do: max(a, b)\n  defmacrop a <|> b, do: max(a, b)\n  defmacrop _ ^^^ _, do: max(a, b)\n  defmacrop a ~~~ b, do: max(a, b)\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-simple.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-simple.d/expected.tags",
    "content": "MyList\tinput.ex\t/^defmodule MyList do$/;\"\tmodule\nreverse\tinput.ex\t/^  defdelegate reverse(list), to: Enum$/;\"\tdelegate\tmodule:MyList\nother_reverse\tinput.ex\t/^  defdelegate other_reverse(list), to: Enum, as: :reverse$/;\"\tdelegate\tmodule:MyList\nSize\tinput.ex\t/^defprotocol Size do$/;\"\tprotocol\nsize\tinput.ex\t/^  def size(data)$/;\"\tfunction\tprotocol:Size\taccess:public\nMyGuards\tinput.ex\t/^defmodule Integer.MyGuards do$/;\"\tmodule\nis_even\tinput.ex\t/^  defguard is_even(value) when is_integer(value) and rem(value, 2) == 0$/;\"\tguard\tmodule:MyGuards\taccess:public\nis_odd\tinput.ex\t/^  defguardp is_odd(value) when is_integer(value) and rem(value, 2) != 0$/;\"\tguard\tmodule:MyGuards\taccess:private\nSize\tinput.ex\t/^defimpl Size, for: BitString do$/;\"\timplementation\tmodule:MyGuards\nsize\tinput.ex\t/^  def size(binary), do: byte_size(binary)$/;\"\tfunction\tmodule:MyGuards\taccess:public\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-simple.d/input.ex",
    "content": "# Most of this code is taken from the official Elixir documentation.\n# With comments and modifications\n# by Ivan Gonzalez Polanco <ivan14polanco@gmail.com>\n#\n# This code doesn't compile, since it's supposed to test de ctags elixir\n# parser, not the elixir elixir parser.\n\n#\n# d delegates (defdelegate ...)\n#\ndefmodule MyList do\n  defdelegate reverse(list), to: Enum\n  defdelegate other_reverse(list), to: Enum, as: :reverse\nend\n\n#\n# p protocols (defprotocol ...)\n#\ndefprotocol Size do\n  @doc \"Calculates the size (and not the length!) of a data structure\"\n  def size(data)\nend\n\n#\n# g guards (defguard ...)\n#\ndefmodule Integer.MyGuards do\n  defguard is_even(value) when is_integer(value) and rem(value, 2) == 0\n  defguardp is_odd(value) when is_integer(value) and rem(value, 2) != 0\nend\n\n#\n# i implementations (defimpl ...)\n#\ndefimpl Size, for: BitString do\n  def size(binary), do: byte_size(binary)\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-tests.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-tests.d/expected.tags",
    "content": "TestModule\tinput.ex\t/^defmodule TestModule do$/;\"\tmodule\ngood with spaces\tinput.ex\t/^  test \"good with spaces\" do$/;\"\ttest\tmodule:TestModule\ngood with parens\tinput.ex\t/^  test(\"good with parens\") do$/;\"\ttest\tmodule:TestModule\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-tests.d/input.ex",
    "content": "defmodule TestModule do\n  use ExUnit.Case, async: true\n\n  test \"good with spaces\" do\n    assert 1 + 1 == 2\n  end\n\n  test(\"good with parens\") do\n    assert 1 + 1 == 2\n  end\n  test\"bad without spaces\" do\n    assert 1 + 1 == 2\n  end\n\n  test \"bad without 'do' word\"\n    assert 1 + 1 == 2\n  end\n\n  test 'bad with single quotes' do\n    assert 1 + 1 == 2\n  end\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-types.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-types.d/expected.tags",
    "content": "TypeModule\tinput.ex\t/^defmodule TypeModule do$/;\"\tmodule\nt\tinput.ex\t/^  @opaque t :: pid$/;\"\ttype\tmodule:TypeModule\taccess:public\ncredentials\tinput.ex\t/^  @type credentials :: {atom, password}$/;\"\ttype\tmodule:TypeModule\taccess:public\npassword\tinput.ex\t/^  @typep password :: binary$/;\"\ttype\tmodule:TypeModule\taccess:private\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-types.d/input.ex",
    "content": "defmodule TypeModule do\n  @opaque t :: pid\n\n  @type credentials :: {atom, password}\n\n  @typep password :: binary\nend\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-word-operators.d/args.ctags",
    "content": "--sort=no\n--fields=+Ka\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-word-operators.d/expected.tags",
    "content": "OperatorModule\tinput.ex\t/^defmodule OperatorModule do$/;\"\tmodule\nand\tinput.ex\t/^  def a and b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\nor\tinput.ex\t/^  def a or b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\nnot\tinput.ex\t/^  defp a not b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\nin\tinput.ex\t/^  defmacro a in b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\nnot in\tinput.ex\t/^  defmacrop a not in b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\nwhen\tinput.ex\t/^  defmacrop a when b, do: max(a, b)$/;\"\toperator\tmodule:OperatorModule\n"
  },
  {
    "path": "Units/parser-elixir.r/elixir-word-operators.d/input.ex",
    "content": "defmodule OperatorModule do\n  def a and b, do: max(a, b)\n  def a or b, do: max(a, b)\n  defp a not b, do: max(a, b)\n  defmacro a in b, do: max(a, b)\n  defmacrop a not in b, do: max(a, b)\n  defmacrop a when b, do: max(a, b)\nend\n"
  },
  {
    "path": "Units/parser-elm.r/elm-aliases.d/args.ctags",
    "content": "--sort=no\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-aliases.d/expected.tags",
    "content": "MyAlias1\tinput.elm\t/^type alias MyAlias1 = String$/;\"\ta\troles:def\nMyAlias2\tinput.elm\t/^type alias MyAlias2 =$/;\"\ta\troles:def\nMyAlias3\tinput.elm\t/^    MyAlias3$/;\"\ta\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-aliases.d/input.elm",
    "content": "type alias MyAlias1 = String\n\ntype alias MyAlias2 =\n    String\n\ntype\n    alias\n    MyAlias3\n    =\n    { x:Float, y:Float }\n\n"
  },
  {
    "path": "Units/parser-elm.r/elm-bad-lines.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-bad-lines.d/expected.tags",
    "content": "Input\tinput.elm\t/^import Input exposing (..)$/;\"\tm\troles:imported\ninput1a\tinput-1.elm\t/^input1a = 1$/;\"\tf\troles:def\ninput1b\tinput-1.elm\t/^input1b = 2$/;\"\tf\ttyperef:typename:Int\troles:def\ninput2b\tinput-2.elm\t/^input2b = 1$/;\"\tf\troles:def\ninput2c\tinput-2.elm\t/^input2c = 3$/;\"\tf\troles:def\nmodule2d\tinput-2.elm\t/^module2d = 4$/;\"\tf\troles:def\ninput3b\tinput-3.elm\t/^input3b = 1$/;\"\tf\troles:def\ninput3d\tinput-3.elm\t/^input3d = 1$/;\"\tf\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-bad-lines.d/input-1.elm",
    "content": "type alias Input1a *= ConsA\n\ninput1a = 1\n\ntype alias Input1b *= ConsB\n\ninput1b : Int\ninput1b = 2\n"
  },
  {
    "path": "Units/parser-elm.r/elm-bad-lines.d/input-2.elm",
    "content": "type Input2a = Cons2A1 | Cons2A2 *\n\ninput2b = 1\n\nmodule = 2\n\ninput2c = 3\n\nmodule2d = 4\n"
  },
  {
    "path": "Units/parser-elm.r/elm-bad-lines.d/input-3.elm",
    "content": "-- Should be able to ignore a function where only part of the body\n-- parses successfully\n\ninput3a i3_1 i3_2 =\n    (]? x &&\n\ninput3b = 1\n\ninput3c i3_1 i3_2 =\n    (]? x &&\n\ninput3d = 1\n\n"
  },
  {
    "path": "Units/parser-elm.r/elm-bad-lines.d/input.elm",
    "content": "import Input exposinx?*\n\nimport Input exposing (..)\n"
  },
  {
    "path": "Units/parser-elm.r/elm-case-statements.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-case-statements.d/expected.tags",
    "content": "funcA\tinput.elm\t/^funcA a1 a2 =$/;\"\tf\troles:def\nfuncB\tinput.elm\t/^funcB b1 =$/;\"\tf\troles:def\nfuncC\tinput.elm\t/^funcC c1 c2 =$/;\"\tf\troles:def\nc2\tinput.elm\t/^                c2 = 2$/;\"\tf\tfunction:funcC\troles:def\nc3\tinput.elm\t/^                c3 = 3$/;\"\tf\tfunction:funcC\troles:def\nfuncD\tinput.elm\t/^funcD str =$/;\"\tf\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-case-statements.d/input.elm",
    "content": "-- A function with a case statement\n\n-- The code below won't compile, but it is\n-- syntactically correct\n\nfuncA a1 a2 =\n    case (complex ex pression + 12) of\n        \"Literal\" ->\n            a + b\n        'l' ->\n            Cons a b\n        Cons a b ->\n            a +\n            b\n        _ ->\n            False\n\n-- Check we can still read a simple function\n\nfuncB b1 =\n    True\n\n-- Can we catch functions defined inside case statements?\n\nfuncC c1 c2 =\n    case (complex ex pression + 12) of\n        \"Literal\" ->\n            let\n                c2 = 2\n                c3 = 3\n            in\n            c2 + c3\n        _ -> False\n\n-- This previously exposed a bug...\n\nfuncD str =\n    case str of\n      Just c1 ->\n        c1 / 255\n      _ ->\n        0\n\n"
  },
  {
    "path": "Units/parser-elm.r/elm-comments.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-comments.d/expected.tags",
    "content": "f\tinput.elm\t/^f = 6 {- another comment -}$/;\"\tf\troles:def\nh\tinput.elm\t/^h = 9$/;\"\tf\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-comments.d/input.elm",
    "content": "-- a = 1\n\n{- b = 2 -}\n\n{-\nc = 3\n-}\n\n{-* d = 4 -}\n\n{-*\ne = 5\n -}\n\n{- some comment -}\nf = 6 {- another comment -}\n\n  -- This should be ignored\n\n-- This next line is not top level\n{- so should continue the above -} + 1\n\n-- A top level statement\n\nh = 9\n\n{-\ncomment\n    {- nested comment -}\ni = 9\n-}\n"
  },
  {
    "path": "Units/parser-elm.r/elm-complex-types.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r-t\n"
  },
  {
    "path": "Units/parser-elm.r/elm-complex-types.d/expected.tags",
    "content": "A\tinput.elm\t/^type A = ACons { x : Float, y : Float }$/;\"\tt\troles:def\nACons\tinput.elm\t/^type A = ACons { x : Float, y : Float }$/;\"\tc\ttype:A\troles:def\nB\tinput.elm\t/^type B$/;\"\tt\troles:def\nB1Cons\tinput.elm\t/^    = B1Cons$/;\"\tc\ttype:B\troles:def\nB2Cons\tinput.elm\t/^    | B2Cons String Integer$/;\"\tc\ttype:B\troles:def\nB3Cons\tinput.elm\t/^    | B3Cons$/;\"\tc\ttype:B\troles:def\nC\tinput.elm\t/^type C=CCons{x:Float,y:Float}$/;\"\tt\troles:def\nCCons\tinput.elm\t/^type C=CCons{x:Float,y:Float}$/;\"\tc\ttype:C\troles:def\nD\tinput.elm\t/^type D = DCons (String, Float, {x:String, y:Float})$/;\"\tt\troles:def\nDCons\tinput.elm\t/^type D = DCons (String, Float, {x:String, y:Float})$/;\"\tc\ttype:D\troles:def\nE\tinput.elm\t/^type E$/;\"\tt\troles:def\nE1Cons\tinput.elm\t/^    = E1Cons {}$/;\"\tc\ttype:E\troles:def\nE2Cons\tinput.elm\t/^    | E2Cons ()$/;\"\tc\ttype:E\troles:def\nF\tinput.elm\t/^type F$/;\"\tt\troles:def\nF1Cons\tinput.elm\t/^    = F1Cons (String -> Int)$/;\"\tc\ttype:F\troles:def\nF2Cons\tinput.elm\t/^    | F2Cons (Float -> String -> (String -> {x:Float, y:Float}))$/;\"\tc\ttype:F\troles:def\nF3Cons\tinput.elm\t/^    | F3Cons$/;\"\tc\ttype:F\troles:def\nG\tinput.elm\t/^type G a$/;\"\tt\troles:def\nG1Cons\tinput.elm\t/^    = G1Cons a Int$/;\"\tc\ttype:G\troles:def\nG2Cons\tinput.elm\t/^    | G2Cons { a | name : String}$/;\"\tc\ttype:G\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-complex-types.d/input.elm",
    "content": "-- A type with a record spec\n\ntype A = ACons { x : Float, y : Float }\n\n-- A type with more complex spec\n\ntype B\n    = B1Cons\n      { x : Float\n      , y : Float\n      }\n    | B2Cons String Integer\n    | B3Cons\n\n-- With a lack of spacing\n\ntype C=CCons{x:Float,y:Float}\n\n-- Tuples\n\ntype D = DCons (String, Float, {x:String, y:Float})\n\n-- Empty records and tuples\n\ntype E\n    = E1Cons {}\n    | E2Cons ()\n\n-- With functions as type specifications\n\ntype F\n    = F1Cons (String -> Int)\n    | F2Cons (Float -> String -> (String -> {x:Float, y:Float}))\n    | F3Cons\n\n-- With vertical bars within the type\n\ntype G a\n    = G1Cons a Int\n    | G2Cons { a | name : String}\n"
  },
  {
    "path": "Units/parser-elm.r/elm-constructor-signatures.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-constructor-signatures.d/expected.tags",
    "content": "B\tinput.elm\t/^type B$/;\"\tt\troles:def\nB1Cons\tinput.elm\t/^    = B1Cons$/;\"\tc\ttype:B\ttyperef:typename:{ x : Float , y : Float } -> B\troles:def\nB2Cons\tinput.elm\t/^    | B2Cons String Integer$/;\"\tc\ttype:B\ttyperef:typename:String -> Integer -> B\troles:def\nB3Cons\tinput.elm\t/^    | B3Cons$/;\"\tc\ttype:B\ttyperef:typename:B\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-constructor-signatures.d/input.elm",
    "content": "type B\n    = B1Cons\n      { x : Float\n      , y : Float\n      }\n    | B2Cons String Integer\n    | B3Cons\n"
  },
  {
    "path": "Units/parser-elm.r/elm-expressions.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-expressions.d/expected.tags",
    "content": "funcA\tinput.elm\t/^funcA =$/;\"\tf\troles:def\nfuncB\tinput.elm\t/^funcB = (\\\\b1 b2 b3 -> 42)$/;\"\tf\troles:def\nfuncC\tinput.elm\t/^funcC =$/;\"\tf\troles:def\nfuncD\tinput.elm\t/^funcD =$/;\"\tf\troles:def\nfuncE\tinput.elm\t/^funcE e1 e2 =$/;\"\tf\troles:def\nfuncF\tinput.elm\t/^funcF = []$/;\"\tf\troles:def\nfuncG\tinput.elm\t/^funcG =$/;\"\tf\troles:def\nfuncH\tinput.elm\t/^funcH h =$/;\"\tf\troles:def\nfuncI\tinput.elm\t/^funcI i1 i2 =$/;\"\tf\troles:def\nfuncJ1\tinput.elm\t/^funcJ1 =$/;\"\tf\troles:def\nfuncJ2\tinput.elm\t/^funcJ2 =$/;\"\tf\troles:def\nfuncJ3\tinput.elm\t/^funcJ3 =$/;\"\tf\troles:def\nfuncJ4\tinput.elm\t/^funcJ4 =$/;\"\tf\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-expressions.d/input.elm",
    "content": "-- Expressions with parentheses\n\nfuncA =\n    (23 + 34)\n\n-- Anonymous functions\n\nfuncB = (\\b1 b2 b3 -> 42)\n\n-- Allow us to call constructors as functions\n\nfuncC =\n    Cons a b\n\n-- Allow us to functions and constructors using their module names\n\nfuncD =\n    (List.Deep.Cons a b) + (Main.add a b)\n\n-- Basic lists\n\nfuncE e1 e2 =\n    e1 :: [e2, e1 + e2]\n\n-- Empty lists\n\nfuncF = []\n\n-- Tuples, including an empty tuple\n\nfuncG =\n    (12, 0x034, ('a')) ++ ()\n\n-- Record names as function calls\n\nfuncH h =\n    (3) + (.age h.family.person)\n\n-- Binary operators as function calls\n\nfuncI i1 i2 =\n    (++) (i1 // i2) 99\n\n-- Records\n\nfuncJ1 =\n    {x = 2 , y = 3 , z = 4}\n\nfuncJ2 =\n    { point | x = point.x + 1 , y = Cons a b }\n\nfuncJ3 =\n    {}\n\n-- Record with spaces\n\nfuncJ4 =\n    { model\n    | width = width\n    }\n"
  },
  {
    "path": "Units/parser-elm.r/elm-functions.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-functions.d/expected.tags",
    "content": "funcA\tinput.elm\t/^funcA a1 a2 = a1 + a2$/;\"\tf\troles:def\nfuncB\tinput.elm\t/^funcB b =$/;\"\tf\troles:def\nfuncC\tinput.elm\t/^funcC = 2 + 1$/;\"\tf\troles:def\nfuncD\tinput.elm\t/^funcD   d1$/;\"\tf\troles:def\nfuncE\tinput.elm\t/^funcE=2$/;\"\tf\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-functions.d/input.elm",
    "content": "-- Simple function with some parameters.\n\nfuncA a1 a2 = a1 + a2\n\n-- Function over multiple lines\n\nfuncB b =\n    b + 1\n\n-- Function with no parameter\n\nfuncC = 2 + 1\n\n-- Function with whitespace - ideally this will be stripped in the type description\n\nfuncD   d1\n    d2   = d1 + d2\n\n-- Function with no whitespace after the name\n\nfuncE=2\n\n"
  },
  {
    "path": "Units/parser-elm.r/elm-if-then-else.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-if-then-else.d/expected.tags",
    "content": "funcA\tinput.elm\t/^funcA a1 a2 =$/;\"\tf\troles:def\nfuncB\tinput.elm\t/^funcB b1 =$/;\"\tf\troles:def\nfuncC\tinput.elm\t/^funcC c1 c2 =$/;\"\tf\troles:def\nc2\tinput.elm\t/^            c2 = 2$/;\"\tf\tfunction:funcC\troles:def\nc3\tinput.elm\t/^            c3 = 3$/;\"\tf\tfunction:funcC\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-if-then-else.d/input.elm",
    "content": "-- A function with an if/then/else statement\n\n-- The code below won't compile, but it is\n-- syntactically correct\n\nfuncA a1 a2 =\n    if (complex ex pression + 12) == \"Literal\"\n    then\n        a + b\n    else\n        a +\n        b\n\n-- Check we can still read a simple function?\n\nfuncB b1 =\n    True\n\n-- Can we catch functions defined inside if statements?\n\nfuncC c1 c2 =\n    if (complex ex pression + 12) == \"Literal\"\n    then\n        let\n            c2 = 2\n            c3 = 3\n        in\n        c2 + c3\n    else\n        a +\n        b\n"
  },
  {
    "path": "Units/parser-elm.r/elm-imports.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r-t\n"
  },
  {
    "path": "Units/parser-elm.r/elm-imports.d/expected.tags",
    "content": "SomeMod\tinput.elm\t/^module SomeMod exposing (..)$/;\"\tm\troles:def\nPlainImport\tinput.elm\t/^import PlainImport$/;\"\tm\troles:imported\nMyMod\tinput.elm\t/^import MyMod exposing$/;\"\tm\troles:imported\nmap\tinput.elm\t/^    ( map, foldl$/;\"\tf\tmodule:MyMod\troles:exposed\nfoldl\tinput.elm\t/^    ( map, foldl$/;\"\tf\tmodule:MyMod\troles:exposed\nMaybe\tinput.elm\t/^    , Maybe, Possibly$/;\"\tt\tmodule:MyMod\troles:exposed\nPossibly\tinput.elm\t/^    , Maybe, Possibly$/;\"\tt\tmodule:MyMod\troles:exposed\nResult\tinput.elm\t/^    , Result(..)$/;\"\tt\tmodule:MyMod\troles:exposed\nMyList\tinput.elm\t/^    , MyList(Empty), Tree(Node, Value, Special) )$/;\"\tt\tmodule:MyMod\troles:exposed\nEmpty\tinput.elm\t/^    , MyList(Empty), Tree(Node, Value, Special) )$/;\"\tc\ttype:MyMod.MyList\troles:exposed\nTree\tinput.elm\t/^    , MyList(Empty), Tree(Node, Value, Special) )$/;\"\tt\tmodule:MyMod\troles:exposed\nNode\tinput.elm\t/^    , MyList(Empty), Tree(Node, Value, Special) )$/;\"\tc\ttype:MyMod.Tree\troles:exposed\nValue\tinput.elm\t/^    , MyList(Empty), Tree(Node, Value, Special) )$/;\"\tc\ttype:MyMod.Tree\troles:exposed\nSpecial\tinput.elm\t/^    , MyList(Empty), Tree(Node, Value, Special) )$/;\"\tc\ttype:MyMod.Tree\troles:exposed\notherMod\tinput.elm\t/^import otherMod exposing (Coin)$/;\"\tm\troles:imported\nCoin\tinput.elm\t/^import otherMod exposing (Coin)$/;\"\tt\tmodule:otherMod\troles:exposed\nDotted.name.Here\tinput.elm\t/^import Dotted.name.Here exposing (Dot(Cons))$/;\"\tm\troles:imported\nDot\tinput.elm\t/^import Dotted.name.Here exposing (Dot(Cons))$/;\"\tt\tmodule:Dotted.name.Here\troles:exposed\nCons\tinput.elm\t/^import Dotted.name.Here exposing (Dot(Cons))$/;\"\tc\ttype:Dotted.name.Here.Dot\troles:exposed\nfunc\tinput.elm\t/^func x =$/;\"\tf\tmodule:SomeMod\troles:def\nString\tinput-1.elm\t/^import String$/;\"\tm\troles:imported\nA\tinput-1.elm\t/^type A = B$/;\"\tt\troles:def\nB\tinput-1.elm\t/^type A = B$/;\"\tc\ttype:A\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-imports.d/input-1.elm",
    "content": "import String\n\ntype A = B\n"
  },
  {
    "path": "Units/parser-elm.r/elm-imports.d/input.elm",
    "content": "module SomeMod exposing (..)\n\nimport PlainImport\n\nimport MyMod exposing\n    ( map, foldl\n    , Maybe, Possibly\n    , Result(..)\n    , MyList(Empty), Tree(Node, Value, Special) )\n\n-- Allow a bit of looseness in module naming, even though the\n-- compiler will reject it\n\nimport otherMod exposing (Coin)\n\n-- Allow a dotted module name\n\nimport Dotted.name.Here exposing (Dot(Cons))\n\nfunc x =\n    42 + 24\n"
  },
  {
    "path": "Units/parser-elm.r/elm-just-comments.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-elm.r/elm-just-comments.d/input.elm",
    "content": "-- a = 1\n\n{- b = 2 -}\n\n{-\nc = 3\n-}\n\n{-* d = 4 -}\n\n{-*\ne = 5\n -}\n\n{- comment -} {- another comment -}\n\n{-\ncomment\n    {- nested comment -}\ng = 7\n-}\n"
  },
  {
    "path": "Units/parser-elm.r/elm-let-in.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-let-in.d/expected.tags",
    "content": "funcA\tinput.elm\t/^funcA =$/;\"\tf\troles:def\na1\tinput.elm\t/^        a1 = 1$/;\"\tf\tfunction:funcA\troles:def\na2\tinput.elm\t/^        a2 x y = x + y$/;\"\tf\tfunction:funcA\troles:def\nfuncB\tinput.elm\t/^funcB b =$/;\"\tf\troles:def\nb1\tinput.elm\t/^        b1 =$/;\"\tf\tfunction:funcB\troles:def\nb2\tinput.elm\t/^                b2 x y =$/;\"\tf\tfunction:funcB\troles:def\nb3\tinput.elm\t/^                    b3 x y =$/;\"\tf\tfunction:funcB\troles:def\nb4\tinput.elm\t/^                    b4 v w =$/;\"\tf\tfunction:funcB\troles:def\nb5\tinput.elm\t/^        b5 i j = i + j$/;\"\tf\tfunction:funcB\troles:def\nfuncC\tinput.elm\t/^funcC =$/;\"\tf\troles:def\nc1\tinput.elm\t/^        c1 = 1$/;\"\tf\tfunction:funcC\troles:def\nc2\tinput.elm\t/^        c2 x y = x + y$/;\"\tf\tfunction:funcC\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-let-in.d/input.elm",
    "content": "-- Basic let/in block\n\nfuncA =\n    let\n        a1 = 1\n        a2 x y = x + y\n    in\n    a1 << a2\n\n-- Nested let/in blocks\n\nfuncB b =\n    let\n        b1 =\n            let\n                b2 x y =\n                let\n                    b3 x y =\n                        x * y\n                    b4 v w =\n                        v * w\n                in\n                b3 b2 99\n            in\n            (flip << b2) 77\n        b5 i j = i + j\n    in\n    b1 b\n\n-- Let/in block with type annotation\n\nfuncC =\n    let\n        c1 : Int\n        c1 = 1\n\n        c2 : Int Float -> Something\n        c2 x y = x + y\n    in\n    c1 << c2\n"
  },
  {
    "path": "Units/parser-elm.r/elm-modules.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-modules.d/expected.tags",
    "content": "Amodule\tinput.elm\t/^module Amodule exposing (expo)$/;\"\tm\troles:def\nsomeFunc\tinput.elm\t/^someFunc a =$/;\"\tf\tmodule:Amodule\troles:def\nA1module\tinput-1.elm\t/^module A1module exposing (expo)$/;\"\tm\troles:def\nsomeFunc1\tinput-1.elm\t/^someFunc1 a =$/;\"\tf\tmodule:A1module\troles:def\nexpo\tinput-1.elm\t/^expo a =$/;\"\tf\tmodule:A1module\troles:def\nA2_1\tinput-2.elm\t/^module A2_1 exposing (expo)$/;\"\tm\troles:def\nfunc2_1\tinput-2.elm\t/^func2_1 a =$/;\"\tf\tmodule:A2_1\troles:def\nfunc2_2\tinput-2.elm\t/^func2_2 a =$/;\"\tf\tmodule:A2_1\troles:def\nA3Module\tinput-3.elm\t/^module A3Module exposing$/;\"\tm\troles:def\na4Module\tinput-4.elm\t/^module a4Module exposing (..)$/;\"\tm\troles:def\na5.Module.Deep\tinput-5.elm\t/^module a5.Module.Deep exposing (..)$/;\"\tm\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-modules.d/input-1.elm",
    "content": "module A1module exposing (expo)\n\nsomeFunc1 a =\n   42 + 24 \n\nexpo a =\n    42 + 24\n"
  },
  {
    "path": "Units/parser-elm.r/elm-modules.d/input-2.elm",
    "content": "{- Only the first module declaration should be recognised -}\n\nmodule A2_1 exposing (expo)\n\nmodule A2_2 exposing (expo)\n\nfunc2_1 a =\n    42 + 24\n\nmodule A2_3 exposing (expo)\n\nfunc2_2 a =\n    42 + 24\n\n"
  },
  {
    "path": "Units/parser-elm.r/elm-modules.d/input-3.elm",
    "content": "-- Should be able to parse multiple exposed items in a module declaration\n\nmodule A3Module exposing\n    ( map, foldl\n    , Maybe, Possibly\n    , Result(..)\n    , MyList(Empty), Tree(Node, Value, Special) )\n\n"
  },
  {
    "path": "Units/parser-elm.r/elm-modules.d/input-4.elm",
    "content": "-- Be relaxed about module name capitalisation\n\nmodule a4Module exposing (..)\n"
  },
  {
    "path": "Units/parser-elm.r/elm-modules.d/input-5.elm",
    "content": "-- Be relaxed about module name capitalisation\n\nmodule a5.Module.Deep exposing (..)\n"
  },
  {
    "path": "Units/parser-elm.r/elm-modules.d/input.elm",
    "content": "module Amodule exposing (expo)\n\nsomeFunc a =\n    42 + 24\n"
  },
  {
    "path": "Units/parser-elm.r/elm-multiline-strings.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-multiline-strings.d/expected.tags",
    "content": "funcA\tinput.elm\t/^funcA a1 a2 = a1 + a2$/;\"\tf\troles:def\nfuncB\tinput.elm\t/^funcB b =$/;\"\tf\troles:def\nfuncD\tinput.elm\t/^funcD d1 =$/;\"\tf\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-multiline-strings.d/input.elm",
    "content": "-- We should be able to parse this function\n\nfuncA a1 a2 = a1 + a2\n\n-- We should get only funcB, not funcC\n\nfuncB b =\n    b + \"\"\"This is a multiline\nstring, which ends after\n\nfuncC = 3\n\"\"\"\n\nfuncD d1 =\n    (d1 + 34)\n\n-- The end\n"
  },
  {
    "path": "Units/parser-elm.r/elm-namespaces.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-namespaces.d/expected.tags",
    "content": "A1Mod\tinput.elm\t/^module A1Mod exposing (..)$/;\"\tm\troles:def\nA1NameSpace\tinput.elm\t/^import A1Import as A1NameSpace exposing (a1ImpFunc)$/;\"\tn\tmodule:A1Mod\troles:def\tmoduleName:A1Import\nA1Import\tinput.elm\t/^import A1Import as A1NameSpace exposing (a1ImpFunc)$/;\"\tm\troles:imported\na1ImpFunc\tinput.elm\t/^import A1Import as A1NameSpace exposing (a1ImpFunc)$/;\"\tf\tmodule:A1Import\troles:exposed\nfunc\tinput.elm\t/^func a1 =$/;\"\tf\tmodule:A1Mod\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-namespaces.d/input.elm",
    "content": "module A1Mod exposing (..)\n\nimport A1Import as A1NameSpace exposing (a1ImpFunc)\n\nfunc a1 =\n    42 + 24\n"
  },
  {
    "path": "Units/parser-elm.r/elm-optlist-compatibility.d/README.md",
    "content": "This directory contains the tests from the previous Elm parser, which used\nthe optlib parser. The tests are included to here to check compatibility.\nHowever, the output from this PEG parser (and hence the contents of\nexpected.tags) is enhanced.\n"
  },
  {
    "path": "Units/parser-elm.r/elm-optlist-compatibility.d/args.ctags",
    "content": "--sort=no\n--fields=+r-t\n--extras=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-optlist-compatibility.d/expected.tags",
    "content": "Main\tinput.elm\t/^port module Main exposing (..)$/;\"\tm\troles:def\nList\tinput.elm\t/^import List$/;\"\tm\troles:imported\nMaybe\tinput.elm\t/^import Maybe exposing (withDefault)$/;\"\tm\troles:imported\nwithDefault\tinput.elm\t/^import Maybe exposing (withDefault)$/;\"\tf\tmodule:Maybe\troles:exposed\nJe\tinput.elm\t/^import Json.Encode as Je$/;\"\tn\tmodule:Main\troles:def\tmoduleName:Json.Encode\nJson.Encode\tinput.elm\t/^import Json.Encode as Je$/;\"\tm\troles:imported\nThing\tinput.elm\t/^type Thing$/;\"\tt\tmodule:Main\troles:def\nOne\tinput.elm\t/^    = One$/;\"\tc\ttype:Main.Thing\troles:def\nTwo\tinput.elm\t/^    | Two Int$/;\"\tc\ttype:Main.Thing\troles:def\nParam\tinput.elm\t/^type Param a$/;\"\tt\tmodule:Main\troles:def\nCons\tinput.elm\t/^    = Cons a$/;\"\tc\ttype:Main.Param\troles:def\nOther\tinput.elm\t/^    | Other a$/;\"\tc\ttype:Main.Param\troles:def\nNum\tinput.elm\t/^type alias Num =$/;\"\ta\tmodule:Main\troles:def\noutward\tinput.elm\t/^port outward : String -> Cmd a$/;\"\tp\tmodule:Main\troles:def\ninward\tinput.elm\t/^port inward : (b -> a) -> Sub a$/;\"\tp\tmodule:Main\troles:def\nfoo\tinput.elm\t/^foo a =$/;\"\tf\tmodule:Main\troles:def\nbar\tinput.elm\t/^bar =$/;\"\tf\tmodule:Main\troles:def\nbas\tinput.elm\t/^        bas =$/;\"\tf\tfunction:Main.bar\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-optlist-compatibility.d/input.elm",
    "content": "port module Main exposing (..)\n\nimport List\nimport Maybe exposing (withDefault)\nimport Json.Encode as Je\n\n\ntype Thing\n    = One\n    | Two Int\n\n\ntype Param a\n    = Cons a\n    | Other a\n\n\ntype alias Num =\n    Int\n\n\nport outward : String -> Cmd a\n\n\nport inward : (b -> a) -> Sub a\n\n\nfoo : Int -> Int\nfoo a =\n    a + 1\n\n\nbar =\n    let\n        bas =\n            1\n    in\n        bas\n"
  },
  {
    "path": "Units/parser-elm.r/elm-parameter-capture.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+rS\n"
  },
  {
    "path": "Units/parser-elm.r/elm-parameter-capture.d/expected.tags",
    "content": "funcA\tinput.elm\t/^funcA a1 a2 =$/;\"\tf\tsignature:a1 a2\troles:def\nfuncB\tinput.elm\t/^funcB b1$/;\"\tf\ttyperef:typename:Int -> Int -> Int\tsignature:b1 b2\troles:def\nfuncC\tinput.elm\t/^funcC (c1, c2) {c3} (C4Cons c4 c5) =$/;\"\tf\tsignature:(c1, c2) {c3} (C4Cons c4 c5)\troles:def\nfuncD\tinput.elm\t/^funcD = 4$/;\"\tf\tsignature:\troles:def\nfuncE\tinput.elm\t/^funcE=5$/;\"\tf\tsignature:\troles:def\nfuncF1\tinput.elm\t/^funcF1 =$/;\"\tf\tsignature:\troles:def\nfuncF2\tinput.elm\t/^        funcF2 f1 f2 = 6$/;\"\tf\tfunction:funcF1\tsignature:f1 f2\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-parameter-capture.d/input.elm",
    "content": "-- Simple paramaeters\n\nfuncA a1 a2 =\n    a1 + a2\n\n-- With extra whitespace and type annotation\n\nfuncB : Int -> Int -> Int\nfuncB b1\n    b2\n    =\n    b1 + b2\n\n-- Complex parameters\n\nfuncC (c1, c2) {c3} (C4Cons c4 c5) =\n    c1 + c2\n\n-- No parameters\n\nfuncD = 4\n\n-- No whitespace\n\nfuncE=5\n\n-- Functions inside let/in block\n\nfuncF1 =\n    let\n        funcF2 f1 f2 = 6\n    in\n    6\n"
  },
  {
    "path": "Units/parser-elm.r/elm-parameter-patterns.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-parameter-patterns.d/expected.tags",
    "content": "funcA\tinput.elm\t/^funcA (a1, _, a2) =$/;\"\tf\troles:def\nfuncB\tinput.elm\t/^funcB (b1, b2) (b3, b4) =$/;\"\tf\troles:def\nfuncC\tinput.elm\t/^funcC {c1} {c2, c3} =$/;\"\tf\troles:def\nfuncD\tinput.elm\t/^funcD (D1Cons a b) (D2Cons a b, D3Cons a b) =$/;\"\tf\troles:def\nfuncE\tinput.elm\t/^funcE (D1Cons {a, b} c) d =$/;\"\tf\troles:def\nfuncF\tinput.elm\t/^funcF (D1Cons ({a, b} as ab) c) (d as d2) =$/;\"\tf\troles:def\nfuncG\tinput.elm\t/^funcG =$/;\"\tf\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-parameter-patterns.d/input.elm",
    "content": "-- Patterns can be found at https://elmprogramming.com/pattern-matching.html\n\n-- Simple tuple\n\nfuncA (a1, _, a2) =\n    a1 + a2\n\n-- Multiple tuples\n\nfuncB (b1, b2) (b3, b4) =\n    b1 + b2\n\n-- Records with named fields\n\nfuncC {c1} {c2, c3} =\n   c1 + c2 + c3\n\n-- Constructor patterns\n \nfuncD (D1Cons a b) (D2Cons a b, D3Cons a b) =\n    b + 1\n\n-- Combining the above\n \nfuncE (D1Cons {a, b} c) d =\n    c + 1\n\n-- Using 'as' clauses\n \nfuncF (D1Cons ({a, b} as ab) c) (d as d2) =\n    c + 1\n\n-- Make sure complex parameters can be used in anonymous functions\n\nfuncG =\n    (\\ (D1Cons {a, b} c) d -> a + b + c + d)\n"
  },
  {
    "path": "Units/parser-elm.r/elm-ports.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-ports.d/expected.tags",
    "content": "Main\tinput.elm\t/^port module Main exposing (..)$/;\"\tm\troles:def\noutgoing\tinput.elm\t/^port outgoing : Enc.Value -> Cmd msg$/;\"\tp\tmodule:Main\ttyperef:typename:Enc.Value -> Cmd msg\troles:def\nincoming\tinput.elm\t/^port incoming : (Enc.Value -> msg) -> Sub msg$/;\"\tp\tmodule:Main\ttyperef:typename:(Enc.Value -> msg) -> Sub msg\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-ports.d/input.elm",
    "content": "port module Main exposing (..)\n\nport outgoing : Enc.Value -> Cmd msg\n\nport incoming : (Enc.Value -> msg) -> Sub msg\n\n"
  },
  {
    "path": "Units/parser-elm.r/elm-single-expressions.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-single-expressions.d/expected.tags",
    "content": "funcA\tinput.elm\t/^funcA a1 a2 =$/;\"\tf\troles:def\nfuncB\tinput.elm\t/^funcB b1 b2 =$/;\"\tf\troles:def\nfuncC\tinput.elm\t/^funcC c1 =$/;\"\tf\troles:def\nfuncD\tinput.elm\t/^funcD d1 d2 =$/;\"\tf\troles:def\nfuncE\tinput.elm\t/^funcE e1 =$/;\"\tf\troles:def\nfuncF\tinput.elm\t/^funcF f1 =$/;\"\tf\troles:def\nfuncG\tinput.elm\t/^funcG g1 =$/;\"\tf\troles:def\nfuncH\tinput.elm\t/^funcH h1 =$/;\"\tf\troles:def\nfuncI\tinput.elm\t/^funcI i1 =$/;\"\tf\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-single-expressions.d/input.elm",
    "content": "-- Binary operators and decimals\n\nfuncA a1 a2 =\n    a1 + a2 - 3.3 * 3e-3 / .1\n\n-- More binary operators\n\nfuncB b1 b2 =\n    b1 |> b2 >> 3.3 /= 4 + 5\n\n-- Hex numbers\n\nfuncC c1 =\n    0xfa0 /= 0xFAE0\n\n-- Parentheses\n\nfuncD d1 d2 =\n    (3e4 + (5^7 - 0xe) // .2)\n\n-- Call prefix functions\n\nfuncE e1 =\n    e1 + myFunc 3 4 + 5\n\n-- Multiline strings\n\nfuncF f1 =\n    f1 ++ \"\"\"This is a multiline\nstring, which ends after\nthis line\n\"\"\"\n\n-- Strings\n\nfuncG g1 =\n    \"Double q\\\"uote, \\n, etc\" ++\n    \"uni\\u{04FA2}code\"\n\n-- Characters\n\nfuncH h1 =\n    'D' ++ '\\\"' ++ '\\'' ++ '\\n' ++\n    '\\u{04FA2}'\n\n-- Anonymous functions\n\nfuncI i1 =\n    (\\ x y z -> x+y - z)\n\n"
  },
  {
    "path": "Units/parser-elm.r/elm-type-annotations.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-elm.r/elm-type-annotations.d/expected.tags",
    "content": "funcA\tinput.elm\t/^funcA a = 1$/;\"\tf\ttyperef:typename:Int -> Float -> Float\troles:def\nfuncB\tinput.elm\t/^funcB b =$/;\"\tf\ttyperef:typename:String -> Float\troles:def\nfuncC\tinput.elm\t/^funcC c = 3$/;\"\tf\ttyperef:typename:Int -> {c: String}\troles:def\nfuncD\tinput.elm\t/^funcD = 4$/;\"\tf\ttyperef:typename:(Int, Int) -> String\troles:def\nfuncE\tinput.elm\t/^funcE = 5$/;\"\tf\ttyperef:typename:Float -> (Int -> Int -> Int -> String)\troles:def\nfuncF\tinput.elm\t/^funcF = 6$/;\"\tf\ttyperef:typename:String -> {- Old ->-} Int\troles:def\nfuncG\tinput.elm\t/^funcG = 7$/;\"\tf\ttyperef:typename:G.Int -> G.Other\troles:def\nfuncH\tinput.elm\t/^funcH h =$/;\"\tf\ttyperef:typename:Int -> Int\troles:def\nh2\tinput.elm\t/^        h2 = 34$/;\"\tf\tfunction:funcH\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-type-annotations.d/input.elm",
    "content": "-- Simple function with a type annotation\n\nfuncA : Int -> Float -> Float\nfuncA a = 1\n\n-- Type annotation over multiple lines\n\nfuncB :\n    String ->\n    Float\nfuncB b =\n    b + 1\n\n-- Function with a record in the type annotation\n\nfuncC : Int -> {c: String}\nfuncC c = 3\n\n-- Function with a tuple in the type annotation\n\nfuncD : (Int, Int) -> String\n\nfuncD = 4\n\n-- Functions in the type annotation\n\nfuncE : Float -> (Int -> Int -> Int -> String)\n\nfuncE = 5\n\n-- Comments in the type annotation\n\nfuncF : -- Comment\n    String -> {- Old ->-} Int {-- End--}\nfuncF = 6\n\n-- Dotted types in the type annotation\n\nfuncG : G.Int -> G.Other\nfuncG = 7\n\n-- Functions with type annotations should provide scope\n\nfuncH : Int -> Int\nfuncH h =\n    let\n        h2 = 34\n    in\n    h + h2\n"
  },
  {
    "path": "Units/parser-elm.r/elm-types.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r-t\n"
  },
  {
    "path": "Units/parser-elm.r/elm-types.d/expected.tags",
    "content": "Apple\tinput.elm\t/^type Apple = Cox | Braeburn$/;\"\tt\troles:def\nCox\tinput.elm\t/^type Apple = Cox | Braeburn$/;\"\tc\ttype:Apple\troles:def\nBraeburn\tinput.elm\t/^type Apple = Cox | Braeburn$/;\"\tc\ttype:Apple\troles:def\nBox\tinput.elm\t/^type Box a = Cardboard a | Wooden$/;\"\tt\troles:def\nCardboard\tinput.elm\t/^type Box a = Cardboard a | Wooden$/;\"\tc\ttype:Box\troles:def\nWooden\tinput.elm\t/^type Box a = Cardboard a | Wooden$/;\"\tc\ttype:Box\troles:def\nClog\tinput.elm\t/^type Clog a b = Dutch | English$/;\"\tt\troles:def\nDutch\tinput.elm\t/^type Clog a b = Dutch | English$/;\"\tc\ttype:Clog\troles:def\nEnglish\tinput.elm\t/^type Clog a b = Dutch | English$/;\"\tc\ttype:Clog\troles:def\nDType\tinput.elm\t/^type DType$/;\"\tt\troles:def\nD1Cons\tinput.elm\t/^    = D1Cons { x : String, y:Maybe Int}$/;\"\tc\ttype:DType\troles:def\nD2Cons\tinput.elm\t/^    | D2Cons Float Float Clog$/;\"\tc\ttype:DType\troles:def\nTypesTwo\tinput-1.elm\t/^module TypesTwo exposing (..)$/;\"\tm\troles:def\nT2a\tinput-1.elm\t/^type T2a = T2a_1 | T2a_2$/;\"\tt\tmodule:TypesTwo\troles:def\nT2a_1\tinput-1.elm\t/^type T2a = T2a_1 | T2a_2$/;\"\tc\ttype:TypesTwo.T2a\troles:def\nT2a_2\tinput-1.elm\t/^type T2a = T2a_1 | T2a_2$/;\"\tc\ttype:TypesTwo.T2a\troles:def\nfuncT2\tinput-1.elm\t/^funcT2 = \"T2\"$/;\"\tf\tmodule:TypesTwo\troles:def\nT2b\tinput-1.elm\t/^type T2b = T2b_1 | T2b_2$/;\"\tt\tmodule:TypesTwo\troles:def\nT2b_1\tinput-1.elm\t/^type T2b = T2b_1 | T2b_2$/;\"\tc\ttype:TypesTwo.T2b\troles:def\nT2b_2\tinput-1.elm\t/^type T2b = T2b_1 | T2b_2$/;\"\tc\ttype:TypesTwo.T2b\troles:def\n"
  },
  {
    "path": "Units/parser-elm.r/elm-types.d/input-1.elm",
    "content": "-- This is to check scoping still works okay\n\nmodule TypesTwo exposing (..)\n\ntype T2a = T2a_1 | T2a_2\n\nfuncT2 = \"T2\"\n\ntype T2b = T2b_1 | T2b_2\n"
  },
  {
    "path": "Units/parser-elm.r/elm-types.d/input.elm",
    "content": "type Apple = Cox | Braeburn\n\n-- Parameterised types\n\ntype Box a = Cardboard a | Wooden\n\ntype Clog a b = Dutch | English\n\n-- Constructors with types\n\ntype DType\n    = D1Cons { x : String, y:Maybe Int}\n    | D2Cons Float Float Clog\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/definitions.d/args.ctags",
    "content": "--fields=+K\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/definitions.d/expected.tags",
    "content": "a0\tinput.el\t/^(defun a0 (n) (+ 1 n))$/;\"\tfunction\nb0\tinput.el\t/^(defvar b0 3)$/;\"\tvariable\nc0\tinput.el\t/^(defconstant c0 5)$/;\"\tunknown\tdefiner:defconstant\ndefunknown0\tinput.el\t/^(defmacro defunknown0 (s)$/;\"\tmacro\ndefunknown1\tinput.el\t/^(defmacro* defunknown1 (s)$/;\"\tmacro\ne0\tinput.el\t/^(defalias 'e0 'a0)$/;\"\talias\nf0\tinput.el\t/^(defvaralias 'f0 'b0)$/;\"\tvaralias\ng0\tinput.el\t/^(defsubst g0 () nil)$/;\"\tsubst\nh0\tinput.el\t/^(define-error 'h0 (purecopy \"TEST\"))$/;\"\terror\nh1\tinput.el\t/^(define-error (quote h1) (purecopy \"TEST\"))$/;\"\terror\ni0\tinput.el\t/^(define-minor-mode i0 \"DOC\")$/;\"\tminorMode\nj0\tinput.el\t/^(define-derived-mode j0 nil \"TEST\")$/;\"\tderivedMode\nk0\tinput.el\t/^(defcustom k0 t$/;\"\tcustom\nl0\tinput.el\t/^(defgroup l0 nil \"DOC\" :group 'editing)$/;\"\tgroup\nm0\tinput.el\t/^(defface m0$/;\"\tface\nn0\tinput.el\t/^(deftheme n0 \"DOC\")$/;\"\ttheme\no0\tinput.el\t/^(defvar-local o0 1)$/;\"\tvariable\np0\tinput.el\t/^(define-globalized-minor-mode p0$/;\"\tminorMode\nq0\tinput.el\t/^(define-obsolete-function-alias 'q0 'f0)$/;\"\talias\nr0\tinput.el\t/^(define-global-minor-mode r0$/;\"\tminorMode\ns0\tinput.el\t/^(define-inline s0 (n)$/;\"\tinline\nt0\tinput.el\t/^(defun* t0 (n)$/;\"\tfunction\nu0\tinput.el\t/^(defsubst* u0 () nil)$/;\"\tsubst\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/definitions.d/input.el",
    "content": "(defun a0 (n) (+ 1 n))\n\n(defvar b0 3)\n\n(defconstant c0 5)\n\n(defmacro defunknown0 (s)\n  `(defconstant ,s 'unknown))\n\n(defalias 'e0 'a0)\n\n(defvaralias 'f0 'b0)\n\n(defsubst g0 () nil)\n\n(define-error 'h0 (purecopy \"TEST\"))\n(define-error (quote h1) (purecopy \"TEST\"))\n\n(define-minor-mode i0 \"DOC\")\n\n(define-derived-mode j0 nil \"TEST\")\n\n(defcustom k0 t\n  \"doc\"\n  :type 'number\n  :group 'l0\n  :version \"22.1\")\n\n(defgroup l0 nil \"DOC\" :group 'editing)\n\n(defface m0\n  '((t (:inherit region)))\n  \"DOC\"\n  :group 'l0\n  :version \"22.1\")\n\n(deftheme n0 \"DOC\")\n\n(condition-case nil\n(define-key dont-capture-me-map \"m\" 'ctags)\n(error nil))\n\n(defvar-local o0 1)\n\n\n(define-globalized-minor-mode p0\n  visual-line-mode turn-on-visual-line-mode)\n\n(define-obsolete-function-alias 'q0 'f0)\n\n(define-global-minor-mode r0\n  subword-mode turn-on-subword-mode)\n\n(define-inline s0 (n)\n  (+ n 1))\n\n(defun* t0 (n)\n  (+ n 1))\n\n(defmacro* defunknown1 (s)\n  `(defconstant ,s 'unknown))\n\n(defsubst* u0 () nil)\n\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/misleading-names.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/misleading-names.d/expected.tags",
    "content": "a\tinput.el\t/^(defvar a)$/;\"\tv\nb\tinput.el\t/^(defvar b)$/;\"\tv\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/misleading-names.d/input.el",
    "content": "(defvar a)\n\n;; ctags should not tag 'x':\n(default x)\n(definition y0)\n(definitionz y1)\n\n(defvar b)\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/newline.b/expected.tags",
    "content": "f\tinput.el\t/^    f () 1)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/newline.b/input.el",
    "content": "(defun\n    f () 1)\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/simple-emacsLisp.d/README",
    "content": "The input is taken from simple.el of GNU Emacs.  I didn't check all\nthe entries of expected.tags because it has so many entires. However,\nI put this to our git repository because there are so various def* in\nsimple.el. So when we change the code of EmacsLisp parser, this test\ncase may notify something useful.\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/simple-emacsLisp.d/args.ctags",
    "content": "--sort=no\n--fields=+K\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/simple-emacsLisp.d/expected.tags",
    "content": "compilation-current-error\tinput.el\t/^(defvar compilation-current-error)$/;\"\tvariable\ncompilation-context-lines\tinput.el\t/^(defvar compilation-context-lines)$/;\"\tvariable\nshell-command-dont-erase-buffer\tinput.el\t/^(defcustom shell-command-dont-erase-buffer nil$/;\"\tcustom\nshell-command-saved-pos\tinput.el\t/^(defvar shell-command-saved-pos nil$/;\"\tvariable\nidle-update-delay\tinput.el\t/^(defcustom idle-update-delay 0.5$/;\"\tcustom\nkilling\tinput.el\t/^(defgroup killing nil$/;\"\tgroup\nparen-matching\tinput.el\t/^(defgroup paren-matching nil$/;\"\tgroup\nnext-error\tinput.el\t/^(defgroup next-error nil$/;\"\tgroup\nnext-error\tinput.el\t/^(defface next-error$/;\"\tface\nnext-error-highlight\tinput.el\t/^(defcustom next-error-highlight 0.5$/;\"\tcustom\nnext-error-highlight-no-select\tinput.el\t/^(defcustom next-error-highlight-no-select 0.5$/;\"\tcustom\nnext-error-recenter\tinput.el\t/^(defcustom next-error-recenter nil$/;\"\tcustom\nnext-error-hook\tinput.el\t/^(defcustom next-error-hook nil$/;\"\tcustom\nnext-error-highlight-timer\tinput.el\t/^(defvar next-error-highlight-timer nil)$/;\"\tvariable\nnext-error-overlay-arrow-position\tinput.el\t/^(defvar next-error-overlay-arrow-position nil)$/;\"\tvariable\nnext-error-last-buffer\tinput.el\t/^(defvar next-error-last-buffer nil$/;\"\tvariable\nnext-error-function\tinput.el\t/^(defvar next-error-function nil$/;\"\tvariable\nnext-error-move-function\tinput.el\t/^(defvar next-error-move-function nil$/;\"\tvariable\nnext-error-buffer-p\tinput.el\t/^(defsubst next-error-buffer-p (buffer$/;\"\tsubst\nnext-error-find-buffer\tinput.el\t/^(defun next-error-find-buffer (&optional avoid-current$/;\"\tfunction\nnext-error\tinput.el\t/^(defun next-error (&optional arg reset)$/;\"\tfunction\nnext-error-internal\tinput.el\t/^(defun next-error-internal ()$/;\"\tfunction\ngoto-next-locus\tinput.el\t/^(defalias 'goto-next-locus 'next-error)$/;\"\talias\nnext-match\tinput.el\t/^(defalias 'next-match 'next-error)$/;\"\talias\nprevious-error\tinput.el\t/^(defun previous-error (&optional n)$/;\"\tfunction\nfirst-error\tinput.el\t/^(defun first-error (&optional n)$/;\"\tfunction\nnext-error-no-select\tinput.el\t/^(defun next-error-no-select (&optional n)$/;\"\tfunction\nprevious-error-no-select\tinput.el\t/^(defun previous-error-no-select (&optional n)$/;\"\tfunction\nnext-error-follow-last-line\tinput.el\t/^(defvar next-error-follow-last-line nil)$/;\"\tvariable\nnext-error-follow-minor-mode\tinput.el\t/^(define-minor-mode next-error-follow-minor-mode$/;\"\tminorMode\nnext-error-follow-mode-post-command-hook\tinput.el\t/^(defun next-error-follow-mode-post-command-hook ()$/;\"\tfunction\nfundamental-mode\tinput.el\t/^(defun fundamental-mode ()$/;\"\tfunction\nspecial-mode-map\tinput.el\t/^(defvar special-mode-map$/;\"\tvariable\nspecial-mode\tinput.el\t/^(define-derived-mode special-mode nil \"Special\"$/;\"\tderivedMode\nself-insert-uses-region-functions\tinput.el\t/^(defvar self-insert-uses-region-functions nil$/;\"\tvariable\nhard-newline\tinput.el\t/^(defvar hard-newline (propertize \"\\\\n\" 'hard t 'rear-nonsticky '(hard))$/;\"\tvariable\nnewline\tinput.el\t/^(defun newline (&optional arg interactive)$/;\"\tfunction\nset-hard-newline-properties\tinput.el\t/^(defun set-hard-newline-properties (from to)$/;\"\tfunction\nopen-line\tinput.el\t/^(defun open-line (n)$/;\"\tfunction\nsplit-line\tinput.el\t/^(defun split-line (&optional arg)$/;\"\tfunction\ndelete-indentation\tinput.el\t/^(defun delete-indentation (&optional arg)$/;\"\tfunction\njoin-line\tinput.el\t/^(defalias 'join-line #'delete-indentation) ; easier to find$/;\"\talias\ndelete-blank-lines\tinput.el\t/^(defun delete-blank-lines ()$/;\"\tfunction\ndelete-trailing-lines\tinput.el\t/^(defcustom delete-trailing-lines t$/;\"\tcustom\nregion-modifiable-p\tinput.el\t/^(defun region-modifiable-p (start end)$/;\"\tfunction\ndelete-trailing-whitespace\tinput.el\t/^(defun delete-trailing-whitespace (&optional start end)$/;\"\tfunction\nnewline-and-indent\tinput.el\t/^(defun newline-and-indent ()$/;\"\tfunction\nreindent-then-newline-and-indent\tinput.el\t/^(defun reindent-then-newline-and-indent ()$/;\"\tfunction\nread-quoted-char-radix\tinput.el\t/^(defcustom read-quoted-char-radix 8$/;\"\tcustom\nread-quoted-char\tinput.el\t/^(defun read-quoted-char (&optional prompt)$/;\"\tfunction\nquoted-insert\tinput.el\t/^(defun quoted-insert (arg)$/;\"\tfunction\nforward-to-indentation\tinput.el\t/^(defun forward-to-indentation (&optional arg)$/;\"\tfunction\nbackward-to-indentation\tinput.el\t/^(defun backward-to-indentation (&optional arg)$/;\"\tfunction\nback-to-indentation\tinput.el\t/^(defun back-to-indentation ()$/;\"\tfunction\nfixup-whitespace\tinput.el\t/^(defun fixup-whitespace ()$/;\"\tfunction\ndelete-horizontal-space\tinput.el\t/^(defun delete-horizontal-space (&optional backward-only)$/;\"\tfunction\njust-one-space\tinput.el\t/^(defun just-one-space (&optional n)$/;\"\tfunction\ncycle-spacing--context\tinput.el\t/^(defvar cycle-spacing--context nil$/;\"\tvariable\ncycle-spacing\tinput.el\t/^(defun cycle-spacing (&optional n preserve-nl-back mode)$/;\"\tfunction\nbeginning-of-buffer\tinput.el\t/^(defun beginning-of-buffer (&optional arg)$/;\"\tfunction\nend-of-buffer\tinput.el\t/^(defun end-of-buffer (&optional arg)$/;\"\tfunction\ndelete-active-region\tinput.el\t/^(defcustom delete-active-region t$/;\"\tcustom\nregion-extract-function\tinput.el\t/^(defvar region-extract-function$/;\"\tvariable\nregion-insert-function\tinput.el\t/^(defvar region-insert-function$/;\"\tvariable\ndelete-backward-char\tinput.el\t/^(defun delete-backward-char (n &optional killflag)$/;\"\tfunction\ndelete-forward-char\tinput.el\t/^(defun delete-forward-char (n &optional killflag)$/;\"\tfunction\nmark-whole-buffer\tinput.el\t/^(defun mark-whole-buffer ()$/;\"\tfunction\ngoto-line\tinput.el\t/^(defun goto-line (line &optional buffer)$/;\"\tfunction\ncount-words-region\tinput.el\t/^(defun count-words-region (start end &optional arg)$/;\"\tfunction\ncount-words\tinput.el\t/^(defun count-words (start end)$/;\"\tfunction\ncount-words--buffer-message\tinput.el\t/^(defun count-words--buffer-message ()$/;\"\tfunction\ncount-words--message\tinput.el\t/^(defun count-words--message (str start end)$/;\"\tfunction\ncount-lines-region\tinput.el\t/^(define-obsolete-function-alias 'count-lines-region 'count-words-region \"24.1\")$/;\"\talias\nwhat-line\tinput.el\t/^(defun what-line ()$/;\"\tfunction\ncount-lines\tinput.el\t/^(defun count-lines (start end)$/;\"\tfunction\nline-number-at-pos\tinput.el\t/^(defun line-number-at-pos (&optional pos absolute)$/;\"\tfunction\nwhat-cursor-position\tinput.el\t/^(defun what-cursor-position (&optional detail)$/;\"\tfunction\nread-expression-map\tinput.el\t/^(defvar read-expression-map$/;\"\tvariable\nread-minibuffer\tinput.el\t/^(defun read-minibuffer (prompt &optional initial-contents)$/;\"\tfunction\neval-minibuffer\tinput.el\t/^(defun eval-minibuffer (prompt &optional initial-contents)$/;\"\tfunction\nminibuffer-completing-symbol\tinput.el\t/^(defvar minibuffer-completing-symbol nil$/;\"\tvariable\nminibuffer-default\tinput.el\t/^(defvar minibuffer-default nil$/;\"\tvariable\neval-expression-print-level\tinput.el\t/^(defcustom eval-expression-print-level 4$/;\"\tcustom\neval-expression-print-length\tinput.el\t/^(defcustom eval-expression-print-length 12$/;\"\tcustom\neval-expression-debug-on-error\tinput.el\t/^(defcustom eval-expression-debug-on-error t$/;\"\tcustom\neval-expression-print-maximum-character\tinput.el\t/^(defcustom eval-expression-print-maximum-character 127$/;\"\tcustom\neval-expression-print-format\tinput.el\t/^(defun eval-expression-print-format (value)$/;\"\tfunction\neval-expression-minibuffer-setup-hook\tinput.el\t/^(defvar eval-expression-minibuffer-setup-hook nil$/;\"\tvariable\nread--expression\tinput.el\t/^(defun read--expression (prompt &optional initial-contents)$/;\"\tfunction\neval-expression-get-print-arguments\tinput.el\t/^(defun eval-expression-get-print-arguments (prefix-argument)$/;\"\tfunction\neval-expression\tinput.el\t/^(defun eval-expression (exp &optional insert-value no-truncate char-print-limit)$/;\"\tfunction\nedit-and-eval-command\tinput.el\t/^(defun edit-and-eval-command (prompt command)$/;\"\tfunction\nrepeat-complex-command\tinput.el\t/^(defun repeat-complex-command (arg)$/;\"\tfunction\nextended-command-history\tinput.el\t/^(defvar extended-command-history nil)$/;\"\tvariable\nexecute-extended-command--last-typed\tinput.el\t/^(defvar execute-extended-command--last-typed nil)$/;\"\tvariable\nread-extended-command\tinput.el\t/^(defun read-extended-command ()$/;\"\tfunction\nsuggest-key-bindings\tinput.el\t/^(defcustom suggest-key-bindings t$/;\"\tcustom\nextended-command-suggest-shorter\tinput.el\t/^(defcustom extended-command-suggest-shorter t$/;\"\tcustom\nexecute-extended-command--shorter-1\tinput.el\t/^(defun execute-extended-command--shorter-1 (name length)$/;\"\tfunction\nexecute-extended-command--shorter\tinput.el\t/^(defun execute-extended-command--shorter (name typed)$/;\"\tfunction\nexecute-extended-command\tinput.el\t/^(defun execute-extended-command (prefixarg &optional command-name typed)$/;\"\tfunction\ncommand-execute\tinput.el\t/^(defun command-execute (cmd &optional record-flag keys special)$/;\"\tfunction\nminibuffer-history\tinput.el\t/^(defvar minibuffer-history nil$/;\"\tvariable\nminibuffer-history-sexp-flag\tinput.el\t/^(defvar minibuffer-history-sexp-flag nil$/;\"\tvariable\nminibuffer-history-search-history\tinput.el\t/^(defvar minibuffer-history-search-history nil)$/;\"\tvariable\nminibuffer-text-before-history\tinput.el\t/^(defvar minibuffer-text-before-history nil$/;\"\tvariable\nminibuffer-history-initialize\tinput.el\t/^(defun minibuffer-history-initialize ()$/;\"\tfunction\nminibuffer-avoid-prompt\tinput.el\t/^(defun minibuffer-avoid-prompt (_new _old)$/;\"\tfunction\nminibuffer-history-case-insensitive-variables\tinput.el\t/^(defcustom minibuffer-history-case-insensitive-variables nil$/;\"\tcustom\nprevious-matching-history-element\tinput.el\t/^(defun previous-matching-history-element (regexp n)$/;\"\tfunction\nnext-matching-history-element\tinput.el\t/^(defun next-matching-history-element (regexp n)$/;\"\tfunction\nminibuffer-temporary-goal-position\tinput.el\t/^(defvar minibuffer-temporary-goal-position nil)$/;\"\tvariable\nminibuffer-default-add-function\tinput.el\t/^(defvar minibuffer-default-add-function 'minibuffer-default-add-completions$/;\"\tvariable\nminibuffer-default-add-done\tinput.el\t/^(defvar minibuffer-default-add-done nil$/;\"\tvariable\nminibuffer-default-add-completions\tinput.el\t/^(defun minibuffer-default-add-completions ()$/;\"\tfunction\ngoto-history-element\tinput.el\t/^(defun goto-history-element (nabs)$/;\"\tfunction\nnext-history-element\tinput.el\t/^(defun next-history-element (n)$/;\"\tfunction\nprevious-history-element\tinput.el\t/^(defun previous-history-element (n)$/;\"\tfunction\nnext-line-or-history-element\tinput.el\t/^(defun next-line-or-history-element (&optional arg)$/;\"\tfunction\nprevious-line-or-history-element\tinput.el\t/^(defun previous-line-or-history-element (&optional arg)$/;\"\tfunction\nnext-complete-history-element\tinput.el\t/^(defun next-complete-history-element (n)$/;\"\tfunction\nprevious-complete-history-element\tinput.el\t/^(defun previous-complete-history-element (n)$/;\"\tfunction\nminibuffer-prompt-width\tinput.el\t/^(defun minibuffer-prompt-width ()$/;\"\tfunction\nminibuffer-history-isearch-message-overlay\tinput.el\t/^(defvar minibuffer-history-isearch-message-overlay)$/;\"\tvariable\nminibuffer-history-isearch-setup\tinput.el\t/^(defun minibuffer-history-isearch-setup ()$/;\"\tfunction\nminibuffer-history-isearch-end\tinput.el\t/^(defun minibuffer-history-isearch-end ()$/;\"\tfunction\nminibuffer-history-isearch-search\tinput.el\t/^(defun minibuffer-history-isearch-search ()$/;\"\tfunction\nminibuffer-history-isearch-message\tinput.el\t/^(defun minibuffer-history-isearch-message (&optional c-q-hack ellipsis)$/;\"\tfunction\nminibuffer-history-isearch-wrap\tinput.el\t/^(defun minibuffer-history-isearch-wrap ()$/;\"\tfunction\nminibuffer-history-isearch-push-state\tinput.el\t/^(defun minibuffer-history-isearch-push-state ()$/;\"\tfunction\nminibuffer-history-isearch-pop-state\tinput.el\t/^(defun minibuffer-history-isearch-pop-state (_cmd hist-pos)$/;\"\tfunction\nadvertised-undo\tinput.el\t/^(define-obsolete-function-alias 'advertised-undo 'undo \"23.2\")$/;\"\talias\nundo-equiv-table\tinput.el\t/^(defconst undo-equiv-table (make-hash-table :test 'eq :weakness t)$/;\"\tconst\nundo-in-region\tinput.el\t/^(defvar undo-in-region nil$/;\"\tvariable\nundo-no-redo\tinput.el\t/^(defvar undo-no-redo nil$/;\"\tvariable\npending-undo-list\tinput.el\t/^(defvar pending-undo-list nil$/;\"\tvariable\nundo\tinput.el\t/^(defun undo (&optional arg)$/;\"\tfunction\nbuffer-disable-undo\tinput.el\t/^(defun buffer-disable-undo (&optional buffer)$/;\"\tfunction\nundo-only\tinput.el\t/^(defun undo-only (&optional arg)$/;\"\tfunction\nundo-in-progress\tinput.el\t/^(defvar undo-in-progress nil$/;\"\tvariable\nundo-more\tinput.el\t/^(defun undo-more (n)$/;\"\tfunction\nprimitive-undo\tinput.el\t/^(defun primitive-undo (n list)$/;\"\tfunction\nundo-copy-list\tinput.el\t/^(defun undo-copy-list (list)$/;\"\tfunction\nundo-copy-list-1\tinput.el\t/^(defun undo-copy-list-1 (elt)$/;\"\tfunction\nundo-start\tinput.el\t/^(defun undo-start (&optional beg end)$/;\"\tfunction\nundo-make-selective-list\tinput.el\t/^(defun undo-make-selective-list (start end)$/;\"\tfunction\nundo-elt-in-region\tinput.el\t/^(defun undo-elt-in-region (undo-elt start end)$/;\"\tfunction\nundo-elt-crosses-region\tinput.el\t/^(defun undo-elt-crosses-region (undo-elt start end)$/;\"\tfunction\nundo-adjust-elt\tinput.el\t/^(defun undo-adjust-elt (elt deltas)$/;\"\tfunction\nundo-adjust-beg-end\tinput.el\t/^(defun undo-adjust-beg-end (beg end deltas)$/;\"\tfunction\nundo-adjust-pos\tinput.el\t/^(defun undo-adjust-pos (pos deltas &optional use-<)$/;\"\tfunction\nundo-delta\tinput.el\t/^(defun undo-delta (undo-elt)$/;\"\tfunction\nundo-auto--last-boundary-cause\tinput.el\t/^(defvar-local undo-auto--last-boundary-cause nil$/;\"\tvariable\nundo-auto-current-boundary-timer\tinput.el\t/^(defvar undo-auto-current-boundary-timer nil$/;\"\tvariable\nundo-auto--this-command-amalgamating\tinput.el\t/^(defvar undo-auto--this-command-amalgamating nil$/;\"\tvariable\nundo-auto--needs-boundary-p\tinput.el\t/^(defun undo-auto--needs-boundary-p ()$/;\"\tfunction\nundo-auto--last-boundary-amalgamating-number\tinput.el\t/^(defun undo-auto--last-boundary-amalgamating-number ()$/;\"\tfunction\nundo-auto--ensure-boundary\tinput.el\t/^(defun undo-auto--ensure-boundary (cause)$/;\"\tfunction\nundo-auto--boundaries\tinput.el\t/^(defun undo-auto--boundaries (cause)$/;\"\tfunction\nundo-auto--boundary-timer\tinput.el\t/^(defun undo-auto--boundary-timer ()$/;\"\tfunction\nundo-auto--boundary-ensure-timer\tinput.el\t/^(defun undo-auto--boundary-ensure-timer ()$/;\"\tfunction\nundo-auto--undoably-changed-buffers\tinput.el\t/^(defvar undo-auto--undoably-changed-buffers nil$/;\"\tvariable\nundo-auto--add-boundary\tinput.el\t/^(defun undo-auto--add-boundary ()$/;\"\tfunction\nundo-auto-amalgamate\tinput.el\t/^(defun undo-auto-amalgamate ()$/;\"\tfunction\nundo-auto--undoable-change\tinput.el\t/^(defun undo-auto--undoable-change ()$/;\"\tfunction\nundo-amalgamate-change-group\tinput.el\t/^(defun undo-amalgamate-change-group (handle)$/;\"\tfunction\nundo-ask-before-discard\tinput.el\t/^(defcustom undo-ask-before-discard nil$/;\"\tcustom\nundo-extra-outer-limit\tinput.el\t/^(defvar undo-extra-outer-limit nil$/;\"\tvariable\nundo-outer-limit-truncate\tinput.el\t/^(defun undo-outer-limit-truncate (size)$/;\"\tfunction\npassword-word-equivalents\tinput.el\t/^(defcustom password-word-equivalents$/;\"\tcustom\nshell-command-history\tinput.el\t/^(defvar shell-command-history nil$/;\"\tvariable\nshell-command-switch\tinput.el\t/^(defvar shell-command-switch (purecopy \"-c\")$/;\"\tvariable\nshell-command-default-error-buffer\tinput.el\t/^(defvar shell-command-default-error-buffer nil$/;\"\tvariable\nminibuffer-default-add-shell-commands\tinput.el\t/^(defun minibuffer-default-add-shell-commands ()$/;\"\tfunction\nminibuffer-local-shell-command-map\tinput.el\t/^(defvar minibuffer-local-shell-command-map$/;\"\tvariable\nread-shell-command\tinput.el\t/^(defun read-shell-command (prompt &optional initial-contents hist &rest args)$/;\"\tfunction\nasync-shell-command-buffer\tinput.el\t/^(defcustom async-shell-command-buffer 'confirm-new-buffer$/;\"\tcustom\nasync-shell-command-display-buffer\tinput.el\t/^(defcustom async-shell-command-display-buffer t$/;\"\tcustom\nshell-command--save-pos-or-erase\tinput.el\t/^(defun shell-command--save-pos-or-erase ()$/;\"\tfunction\nshell-command--set-point-after-cmd\tinput.el\t/^(defun shell-command--set-point-after-cmd (&optional buffer)$/;\"\tfunction\nasync-shell-command\tinput.el\t/^(defun async-shell-command (command &optional output-buffer error-buffer)$/;\"\tfunction\nshell-command\tinput.el\t/^(defun shell-command (command &optional output-buffer error-buffer)$/;\"\tfunction\ndisplay-message-or-buffer\tinput.el\t/^(defun display-message-or-buffer (message &optional buffer-name action frame)$/;\"\tfunction\nshell-command-sentinel\tinput.el\t/^(defun shell-command-sentinel (process signal)$/;\"\tfunction\nshell-command-on-region\tinput.el\t/^(defun shell-command-on-region (start end command$/;\"\tfunction\nshell-command-to-string\tinput.el\t/^(defun shell-command-to-string (command)$/;\"\tfunction\nprocess-file\tinput.el\t/^(defun process-file (program &optional infile buffer display &rest args)$/;\"\tfunction\nprocess-file-side-effects\tinput.el\t/^(defvar process-file-side-effects t$/;\"\tvariable\nstart-file-process\tinput.el\t/^(defun start-file-process (name buffer program &rest program-args)$/;\"\tfunction\ntabulated-list-format\tinput.el\t/^(defvar tabulated-list-format)$/;\"\tvariable\ntabulated-list-entries\tinput.el\t/^(defvar tabulated-list-entries)$/;\"\tvariable\ntabulated-list-sort-key\tinput.el\t/^(defvar tabulated-list-sort-key)$/;\"\tvariable\nprocess-menu-query-only\tinput.el\t/^(defvar process-menu-query-only nil)$/;\"\tvariable\nprocess-menu-mode-map\tinput.el\t/^(defvar process-menu-mode-map$/;\"\tvariable\nprocess-menu-mode\tinput.el\t/^(define-derived-mode process-menu-mode tabulated-list-mode \"Process Menu\"$/;\"\tderivedMode\nprocess-menu-delete-process\tinput.el\t/^(defun process-menu-delete-process ()$/;\"\tfunction\nlist-processes--refresh\tinput.el\t/^(defun list-processes--refresh ()$/;\"\tfunction\nprocess-menu-visit-buffer\tinput.el\t/^(defun process-menu-visit-buffer (button)$/;\"\tfunction\nlist-processes\tinput.el\t/^(defun list-processes (&optional query-only buffer)$/;\"\tfunction\ninternal-echo-keystrokes-prefix\tinput.el\t/^(defun internal-echo-keystrokes-prefix ()$/;\"\tfunction\nprefix-command-echo-keystrokes-functions\tinput.el\t/^(defvar prefix-command-echo-keystrokes-functions nil$/;\"\tvariable\nprefix-command-update\tinput.el\t/^(defun prefix-command-update ()$/;\"\tfunction\nprefix-command-preserve-state-hook\tinput.el\t/^(defvar prefix-command-preserve-state-hook nil$/;\"\tvariable\nprefix-command-preserve-state\tinput.el\t/^(defun prefix-command-preserve-state ()$/;\"\tfunction\nreset-this-command-lengths\tinput.el\t/^(defun reset-this-command-lengths ()$/;\"\tfunction\nuniversal-argument--description\tinput.el\t/^(defun universal-argument--description ()$/;\"\tfunction\nuniversal-argument--preserve\tinput.el\t/^(defun universal-argument--preserve ()$/;\"\tfunction\nuniversal-argument-map\tinput.el\t/^(defvar universal-argument-map$/;\"\tvariable\nuniversal-argument--mode\tinput.el\t/^(defun universal-argument--mode ()$/;\"\tfunction\nuniversal-argument\tinput.el\t/^(defun universal-argument ()$/;\"\tfunction\nuniversal-argument-more\tinput.el\t/^(defun universal-argument-more (arg)$/;\"\tfunction\nnegative-argument\tinput.el\t/^(defun negative-argument (arg)$/;\"\tfunction\ndigit-argument\tinput.el\t/^(defun digit-argument (arg)$/;\"\tfunction\nfilter-buffer-substring-functions\tinput.el\t/^(defvar filter-buffer-substring-functions nil$/;\"\tvariable\nfilter-buffer-substring-function\tinput.el\t/^(defvar filter-buffer-substring-function #'buffer-substring--filter$/;\"\tvariable\nbuffer-substring-filters\tinput.el\t/^(defvar buffer-substring-filters nil$/;\"\tvariable\nfilter-buffer-substring\tinput.el\t/^(defun filter-buffer-substring (beg end &optional delete)$/;\"\tfunction\nbuffer-substring--filter\tinput.el\t/^(defun buffer-substring--filter (beg end &optional delete)$/;\"\tfunction\ninterprogram-cut-function\tinput.el\t/^(defvar interprogram-cut-function #'gui-select-text$/;\"\tvariable\ninterprogram-paste-function\tinput.el\t/^(defvar interprogram-paste-function #'gui-selection-value$/;\"\tvariable\nkill-ring\tinput.el\t/^(defvar kill-ring nil$/;\"\tvariable\nkill-ring-max\tinput.el\t/^(defcustom kill-ring-max 60$/;\"\tcustom\nkill-ring-yank-pointer\tinput.el\t/^(defvar kill-ring-yank-pointer nil$/;\"\tvariable\nsave-interprogram-paste-before-kill\tinput.el\t/^(defcustom save-interprogram-paste-before-kill nil$/;\"\tcustom\nkill-do-not-save-duplicates\tinput.el\t/^(defcustom kill-do-not-save-duplicates nil$/;\"\tcustom\nkill-new\tinput.el\t/^(defun kill-new (string &optional replace)$/;\"\tfunction\nkill-append-merge-undo\tinput.el\t/^(defcustom kill-append-merge-undo nil$/;\"\tcustom\nkill-append\tinput.el\t/^(defun kill-append (string before-p)$/;\"\tfunction\nyank-pop-change-selection\tinput.el\t/^(defcustom yank-pop-change-selection nil$/;\"\tcustom\ncurrent-kill\tinput.el\t/^(defun current-kill (n &optional do-not-move)$/;\"\tfunction\nkill-read-only-ok\tinput.el\t/^(defcustom kill-read-only-ok nil$/;\"\tcustom\nkill-region\tinput.el\t/^(defun kill-region (beg end &optional region)$/;\"\tfunction\ncopy-region-as-kill\tinput.el\t/^(defun copy-region-as-kill (beg end &optional region)$/;\"\tfunction\nkill-ring-save\tinput.el\t/^(defun kill-ring-save (beg end &optional region)$/;\"\tfunction\nindicate-copied-region\tinput.el\t/^(defun indicate-copied-region (&optional message-len)$/;\"\tfunction\nappend-next-kill\tinput.el\t/^(defun append-next-kill (&optional interactive)$/;\"\tfunction\nbidi-directional-controls-chars\tinput.el\t/^(defvar bidi-directional-controls-chars \"\\\\x202a-\\\\x202e\\\\x2066-\\\\x2069\"$/;\"\tvariable\nbidi-directional-non-controls-chars\tinput.el\t/^(defvar bidi-directional-non-controls-chars \"^\\\\x202a-\\\\x202e\\\\x2066-\\\\x2069\"$/;\"\tvariable\nsqueeze-bidi-context-1\tinput.el\t/^(defun squeeze-bidi-context-1 (from to category replacement)$/;\"\tfunction\nsqueeze-bidi-context\tinput.el\t/^(defun squeeze-bidi-context (from to)$/;\"\tfunction\nline-substring-with-bidi-context\tinput.el\t/^(defun line-substring-with-bidi-context (start end &optional no-properties)$/;\"\tfunction\nbuffer-substring-with-bidi-context\tinput.el\t/^(defun buffer-substring-with-bidi-context (start end &optional no-properties)$/;\"\tfunction\nyank-handled-properties\tinput.el\t/^(defcustom yank-handled-properties$/;\"\tcustom\nyank-excluded-properties\tinput.el\t/^(defcustom yank-excluded-properties$/;\"\tcustom\nyank-window-start\tinput.el\t/^(defvar yank-window-start nil)$/;\"\tvariable\nyank-undo-function\tinput.el\t/^(defvar yank-undo-function nil$/;\"\tvariable\nyank-pop\tinput.el\t/^(defun yank-pop (&optional arg)$/;\"\tfunction\nyank\tinput.el\t/^(defun yank (&optional arg)$/;\"\tfunction\nrotate-yank-pointer\tinput.el\t/^(defun rotate-yank-pointer (arg)$/;\"\tfunction\nkill-forward-chars\tinput.el\t/^(defun kill-forward-chars (arg)$/;\"\tfunction\nkill-backward-chars\tinput.el\t/^(defun kill-backward-chars (arg)$/;\"\tfunction\nbackward-delete-char-untabify-method\tinput.el\t/^(defcustom backward-delete-char-untabify-method 'untabify$/;\"\tcustom\nbackward-delete-char-untabify\tinput.el\t/^(defun backward-delete-char-untabify (arg &optional killp)$/;\"\tfunction\nzap-to-char\tinput.el\t/^(defun zap-to-char (arg char)$/;\"\tfunction\nkill-whole-line\tinput.el\t/^(defcustom kill-whole-line nil$/;\"\tcustom\nkill-line\tinput.el\t/^(defun kill-line (&optional arg)$/;\"\tfunction\nkill-whole-line\tinput.el\t/^(defun kill-whole-line (&optional arg)$/;\"\tfunction\nforward-visible-line\tinput.el\t/^(defun forward-visible-line (arg)$/;\"\tfunction\nend-of-visible-line\tinput.el\t/^(defun end-of-visible-line ()$/;\"\tfunction\nkill-current-buffer\tinput.el\t/^(defun kill-current-buffer ()$/;\"\tfunction\ninsert-buffer\tinput.el\t/^(defun insert-buffer (buffer)$/;\"\tfunction\nappend-to-buffer\tinput.el\t/^(defun append-to-buffer (buffer start end)$/;\"\tfunction\nprepend-to-buffer\tinput.el\t/^(defun prepend-to-buffer (buffer start end)$/;\"\tfunction\ncopy-to-buffer\tinput.el\t/^(defun copy-to-buffer (buffer start end)$/;\"\tfunction\nmark-inactive\tinput.el\t/^(define-error 'mark-inactive (purecopy \"The mark is not active now\"))$/;\"\terror\nactivate-mark-hook\tinput.el\t/^(defvar activate-mark-hook nil$/;\"\tvariable\ndeactivate-mark-hook\tinput.el\t/^(defvar deactivate-mark-hook nil$/;\"\tvariable\nmark\tinput.el\t/^(defun mark (&optional force)$/;\"\tfunction\ndeactivate-mark\tinput.el\t/^(defun deactivate-mark (&optional force)$/;\"\tfunction\nactivate-mark\tinput.el\t/^(defun activate-mark (&optional no-tmm)$/;\"\tfunction\nset-mark\tinput.el\t/^(defun set-mark (pos)$/;\"\tfunction\nsave-mark-and-excursion--save\tinput.el\t/^(defun save-mark-and-excursion--save ()$/;\"\tfunction\nsave-mark-and-excursion--restore\tinput.el\t/^(defun save-mark-and-excursion--restore (saved-mark-info)$/;\"\tfunction\nsave-mark-and-excursion\tinput.el\t/^(defmacro save-mark-and-excursion (&rest body)$/;\"\tmacro\nuse-empty-active-region\tinput.el\t/^(defcustom use-empty-active-region nil$/;\"\tcustom\nuse-region-p\tinput.el\t/^(defun use-region-p ()$/;\"\tfunction\nregion-active-p\tinput.el\t/^(defun region-active-p ()$/;\"\tfunction\nregion-bounds\tinput.el\t/^(defun region-bounds ()$/;\"\tfunction\nregion-noncontiguous-p\tinput.el\t/^(defun region-noncontiguous-p ()$/;\"\tfunction\nredisplay-unhighlight-region-function\tinput.el\t/^(defvar redisplay-unhighlight-region-function$/;\"\tvariable\nredisplay-highlight-region-function\tinput.el\t/^(defvar redisplay-highlight-region-function$/;\"\tvariable\nredisplay--update-region-highlight\tinput.el\t/^(defun redisplay--update-region-highlight (window)$/;\"\tfunction\npre-redisplay-functions\tinput.el\t/^(defvar pre-redisplay-functions (list #'redisplay--update-region-highlight)$/;\"\tvariable\nredisplay--pre-redisplay-functions\tinput.el\t/^(defun redisplay--pre-redisplay-functions (windows)$/;\"\tfunction\nmark-ring\tinput.el\t/^(defvar-local mark-ring nil$/;\"\tvariable\nmark-ring-max\tinput.el\t/^(defcustom mark-ring-max 16$/;\"\tcustom\nglobal-mark-ring\tinput.el\t/^(defvar global-mark-ring nil$/;\"\tvariable\nglobal-mark-ring-max\tinput.el\t/^(defcustom global-mark-ring-max 16$/;\"\tcustom\npop-to-mark-command\tinput.el\t/^(defun pop-to-mark-command ()$/;\"\tfunction\npush-mark-command\tinput.el\t/^(defun push-mark-command (arg &optional nomsg)$/;\"\tfunction\nset-mark-command-repeat-pop\tinput.el\t/^(defcustom set-mark-command-repeat-pop nil$/;\"\tcustom\nset-mark-command\tinput.el\t/^(defun set-mark-command (arg)$/;\"\tfunction\npush-mark\tinput.el\t/^(defun push-mark (&optional location nomsg activate)$/;\"\tfunction\npop-mark\tinput.el\t/^(defun pop-mark ()$/;\"\tfunction\nexchange-dot-and-mark\tinput.el\t/^(define-obsolete-function-alias 'exchange-dot-and-mark$/;\"\talias\nexchange-point-and-mark\tinput.el\t/^(defun exchange-point-and-mark (&optional arg)$/;\"\tfunction\nshift-select-mode\tinput.el\t/^(defcustom shift-select-mode t$/;\"\tcustom\nhandle-shift-selection\tinput.el\t/^(defun handle-shift-selection ()$/;\"\tfunction\ntransient-mark-mode\tinput.el\t/^(define-minor-mode transient-mark-mode$/;\"\tminorMode\nwiden-automatically\tinput.el\t/^(defvar widen-automatically t$/;\"\tvariable\nnon-essential\tinput.el\t/^(defvar non-essential nil$/;\"\tvariable\npop-global-mark\tinput.el\t/^(defun pop-global-mark ()$/;\"\tfunction\nnext-line-add-newlines\tinput.el\t/^(defcustom next-line-add-newlines nil$/;\"\tcustom\nnext-line\tinput.el\t/^(defun next-line (&optional arg try-vscroll)$/;\"\tfunction\nprevious-line\tinput.el\t/^(defun previous-line (&optional arg try-vscroll)$/;\"\tfunction\ntrack-eol\tinput.el\t/^(defcustom track-eol nil$/;\"\tcustom\ngoal-column\tinput.el\t/^(defcustom goal-column nil$/;\"\tcustom\ntemporary-goal-column\tinput.el\t/^(defvar temporary-goal-column 0$/;\"\tvariable\nlast--line-number-width\tinput.el\t/^(defvar last--line-number-width 0$/;\"\tvariable\nline-move-ignore-invisible\tinput.el\t/^(defcustom line-move-ignore-invisible t$/;\"\tcustom\nline-move-visual\tinput.el\t/^(defcustom line-move-visual t$/;\"\tcustom\ndefault-font-height\tinput.el\t/^(defun default-font-height ()$/;\"\tfunction\ndefault-font-width\tinput.el\t/^(defun default-font-width ()$/;\"\tfunction\ndefault-line-height\tinput.el\t/^(defun default-line-height ()$/;\"\tfunction\nwindow-screen-lines\tinput.el\t/^(defun window-screen-lines ()$/;\"\tfunction\nline-move-partial\tinput.el\t/^(defun line-move-partial (arg noerror &optional _to-end)$/;\"\tfunction\nline-move\tinput.el\t/^(defun line-move (arg &optional noerror _to-end try-vscroll)$/;\"\tfunction\nline-move-visual\tinput.el\t/^(defun line-move-visual (arg &optional noerror)$/;\"\tfunction\nline-move-1\tinput.el\t/^(defun line-move-1 (arg &optional noerror _to-end)$/;\"\tfunction\nline-move-finish\tinput.el\t/^(defun line-move-finish (column opoint forward)$/;\"\tfunction\nline-move-to-column\tinput.el\t/^(defun line-move-to-column (col)$/;\"\tfunction\nmove-end-of-line\tinput.el\t/^(defun move-end-of-line (arg)$/;\"\tfunction\nmove-beginning-of-line\tinput.el\t/^(defun move-beginning-of-line (arg)$/;\"\tfunction\nset-goal-column\tinput.el\t/^(defun set-goal-column (arg)$/;\"\tfunction\nend-of-visual-line\tinput.el\t/^(defun end-of-visual-line (&optional n)$/;\"\tfunction\nbeginning-of-visual-line\tinput.el\t/^(defun beginning-of-visual-line (&optional n)$/;\"\tfunction\nkill-visual-line\tinput.el\t/^(defun kill-visual-line (&optional arg)$/;\"\tfunction\nnext-logical-line\tinput.el\t/^(defun next-logical-line (&optional arg try-vscroll)$/;\"\tfunction\nprevious-logical-line\tinput.el\t/^(defun previous-logical-line (&optional arg try-vscroll)$/;\"\tfunction\nvisual-line\tinput.el\t/^(defgroup visual-line nil$/;\"\tgroup\nvisual-line-mode-map\tinput.el\t/^(defvar visual-line-mode-map$/;\"\tvariable\nvisual-line-fringe-indicators\tinput.el\t/^(defcustom visual-line-fringe-indicators '(nil nil)$/;\"\tcustom\nvisual-line--saved-state\tinput.el\t/^(defvar visual-line--saved-state nil)$/;\"\tvariable\nvisual-line-mode\tinput.el\t/^(define-minor-mode visual-line-mode$/;\"\tminorMode\nturn-on-visual-line-mode\tinput.el\t/^(defun turn-on-visual-line-mode ()$/;\"\tfunction\nglobal-visual-line-mode\tinput.el\t/^(define-globalized-minor-mode global-visual-line-mode$/;\"\tminorMode\ntranspose-chars\tinput.el\t/^(defun transpose-chars (arg)$/;\"\tfunction\ntranspose-words\tinput.el\t/^(defun transpose-words (arg)$/;\"\tfunction\ntranspose-sexps\tinput.el\t/^(defun transpose-sexps (arg)$/;\"\tfunction\ntranspose-lines\tinput.el\t/^(defun transpose-lines (arg)$/;\"\tfunction\ntranspose-subr\tinput.el\t/^(defun transpose-subr (mover arg &optional special)$/;\"\tfunction\ntranspose-subr-1\tinput.el\t/^(defun transpose-subr-1 (pos1 pos2)$/;\"\tfunction\nbackward-word\tinput.el\t/^(defun backward-word (&optional arg)$/;\"\tfunction\nmark-word\tinput.el\t/^(defun mark-word (&optional arg allow-extend)$/;\"\tfunction\nkill-word\tinput.el\t/^(defun kill-word (arg)$/;\"\tfunction\nbackward-kill-word\tinput.el\t/^(defun backward-kill-word (arg)$/;\"\tfunction\ncurrent-word\tinput.el\t/^(defun current-word (&optional strict really-word)$/;\"\tfunction\nfill-prefix\tinput.el\t/^(defcustom fill-prefix nil$/;\"\tcustom\nauto-fill-inhibit-regexp\tinput.el\t/^(defcustom auto-fill-inhibit-regexp nil$/;\"\tcustom\ndo-auto-fill\tinput.el\t/^(defun do-auto-fill ()$/;\"\tfunction\ncomment-line-break-function\tinput.el\t/^(defvar comment-line-break-function 'comment-indent-new-line$/;\"\tvariable\ndefault-indent-new-line\tinput.el\t/^(defun default-indent-new-line (&optional soft)$/;\"\tfunction\ninternal-auto-fill\tinput.el\t/^(defun internal-auto-fill ()$/;\"\tfunction\nnormal-auto-fill-function\tinput.el\t/^(defvar normal-auto-fill-function 'do-auto-fill$/;\"\tvariable\nauto-fill-mode\tinput.el\t/^(define-minor-mode auto-fill-mode$/;\"\tminorMode\nauto-fill-function\tinput.el\t/^(defun auto-fill-function ()$/;\"\tfunction\nturn-on-auto-fill\tinput.el\t/^(defun turn-on-auto-fill ()$/;\"\tfunction\nturn-off-auto-fill\tinput.el\t/^(defun turn-off-auto-fill ()$/;\"\tfunction\nset-fill-column\tinput.el\t/^(defun set-fill-column (arg)$/;\"\tfunction\nset-selective-display\tinput.el\t/^(defun set-selective-display (arg)$/;\"\tfunction\nindicate-unused-lines\tinput.el\t/^(defvaralias 'indicate-unused-lines 'indicate-empty-lines)$/;\"\tvaralias\ntoggle-truncate-lines\tinput.el\t/^(defun toggle-truncate-lines (&optional arg)$/;\"\tfunction\ntoggle-word-wrap\tinput.el\t/^(defun toggle-word-wrap (&optional arg)$/;\"\tfunction\noverwrite-mode-textual\tinput.el\t/^(defvar overwrite-mode-textual (purecopy \" Ovwrt\")$/;\"\tvariable\noverwrite-mode-binary\tinput.el\t/^(defvar overwrite-mode-binary (purecopy \" Bin Ovwrt\")$/;\"\tvariable\noverwrite-mode\tinput.el\t/^(define-minor-mode overwrite-mode$/;\"\tminorMode\nbinary-overwrite-mode\tinput.el\t/^(define-minor-mode binary-overwrite-mode$/;\"\tminorMode\nline-number-mode\tinput.el\t/^(define-minor-mode line-number-mode$/;\"\tminorMode\ncolumn-number-mode\tinput.el\t/^(define-minor-mode column-number-mode$/;\"\tminorMode\nsize-indication-mode\tinput.el\t/^(define-minor-mode size-indication-mode$/;\"\tminorMode\nauto-save-mode\tinput.el\t/^(define-minor-mode auto-save-mode$/;\"\tminorMode\nparen-blinking\tinput.el\t/^(defgroup paren-blinking nil$/;\"\tgroup\nblink-matching-paren\tinput.el\t/^(defcustom blink-matching-paren t$/;\"\tcustom\nblink-matching-paren-on-screen\tinput.el\t/^(defcustom blink-matching-paren-on-screen t$/;\"\tcustom\nblink-matching-paren-distance\tinput.el\t/^(defcustom blink-matching-paren-distance (* 100 1024)$/;\"\tcustom\nblink-matching-delay\tinput.el\t/^(defcustom blink-matching-delay 1$/;\"\tcustom\nblink-matching-paren-dont-ignore-comments\tinput.el\t/^(defcustom blink-matching-paren-dont-ignore-comments nil$/;\"\tcustom\nblink-matching-check-mismatch\tinput.el\t/^(defun blink-matching-check-mismatch (start end)$/;\"\tfunction\nblink-matching-check-function\tinput.el\t/^(defvar blink-matching-check-function #'blink-matching-check-mismatch$/;\"\tvariable\nblink-matching--overlay\tinput.el\t/^(defvar blink-matching--overlay$/;\"\tvariable\nblink-matching-open\tinput.el\t/^(defun blink-matching-open ()$/;\"\tfunction\nblink-paren-function\tinput.el\t/^(defvar blink-paren-function 'blink-matching-open$/;\"\tvariable\nblink-paren-post-self-insert-function\tinput.el\t/^(defun blink-paren-post-self-insert-function ()$/;\"\tfunction\nkeyboard-quit\tinput.el\t/^(defun keyboard-quit ()$/;\"\tfunction\nbuffer-quit-function\tinput.el\t/^(defvar buffer-quit-function nil$/;\"\tvariable\nkeyboard-escape-quit\tinput.el\t/^(defun keyboard-escape-quit ()$/;\"\tfunction\nplay-sound-file\tinput.el\t/^(defun play-sound-file (file &optional volume device)$/;\"\tfunction\nread-mail-command\tinput.el\t/^(defcustom read-mail-command 'rmail$/;\"\tcustom\nmail-user-agent\tinput.el\t/^(defcustom mail-user-agent 'message-user-agent$/;\"\tcustom\ncompose-mail-user-agent-warnings\tinput.el\t/^(defcustom compose-mail-user-agent-warnings t$/;\"\tcustom\nrfc822-goto-eoh\tinput.el\t/^(defun rfc822-goto-eoh ()$/;\"\tfunction\nmail-encode-mml\tinput.el\t/^(defvar mail-encode-mml nil$/;\"\tvariable\ncompose-mail\tinput.el\t/^(defun compose-mail (&optional to subject other-headers continue$/;\"\tfunction\ncompose-mail-other-window\tinput.el\t/^(defun compose-mail-other-window (&optional to subject other-headers continue$/;\"\tfunction\ncompose-mail-other-frame\tinput.el\t/^(defun compose-mail-other-frame (&optional to subject other-headers continue$/;\"\tfunction\nset-variable-value-history\tinput.el\t/^(defvar set-variable-value-history nil$/;\"\tvariable\nset-variable\tinput.el\t/^(defun set-variable (variable value &optional make-local)$/;\"\tfunction\ncompletion-list-mode-map\tinput.el\t/^(defvar completion-list-mode-map$/;\"\tvariable\ncompletion-reference-buffer\tinput.el\t/^(defvar completion-reference-buffer nil$/;\"\tvariable\ncompletion-no-auto-exit\tinput.el\t/^(defvar completion-no-auto-exit nil$/;\"\tvariable\ncompletion-base-position\tinput.el\t/^(defvar completion-base-position nil$/;\"\tvariable\ncompletion-list-insert-choice-function\tinput.el\t/^(defvar completion-list-insert-choice-function #'completion--replace$/;\"\tvariable\ncompletion-base-size\tinput.el\t/^(defvar completion-base-size nil$/;\"\tvariable\ndelete-completion-window\tinput.el\t/^(defun delete-completion-window ()$/;\"\tfunction\nprevious-completion\tinput.el\t/^(defun previous-completion (n)$/;\"\tfunction\nnext-completion\tinput.el\t/^(defun next-completion (n)$/;\"\tfunction\nchoose-completion\tinput.el\t/^(defun choose-completion (&optional event)$/;\"\tfunction\nchoose-completion-guess-base-position\tinput.el\t/^(defun choose-completion-guess-base-position (string)$/;\"\tfunction\nchoose-completion-delete-max-match\tinput.el\t/^(defun choose-completion-delete-max-match (string)$/;\"\tfunction\nchoose-completion-string-functions\tinput.el\t/^(defvar choose-completion-string-functions nil$/;\"\tvariable\nchoose-completion-string\tinput.el\t/^(defun choose-completion-string (choice &optional$/;\"\tfunction\ncompletion-list-mode\tinput.el\t/^(define-derived-mode completion-list-mode nil \"Completion List\"$/;\"\tderivedMode\ncompletion-list-mode-finish\tinput.el\t/^(defun completion-list-mode-finish ()$/;\"\tfunction\ncompletion-show-help\tinput.el\t/^(defcustom completion-show-help t$/;\"\tcustom\ncompletion-setup-function\tinput.el\t/^(defun completion-setup-function ()$/;\"\tfunction\nswitch-to-completions\tinput.el\t/^(defun switch-to-completions ()$/;\"\tfunction\nevent-apply-alt-modifier\tinput.el\t/^(defun event-apply-alt-modifier (_ignore-prompt)$/;\"\tfunction\nevent-apply-super-modifier\tinput.el\t/^(defun event-apply-super-modifier (_ignore-prompt)$/;\"\tfunction\nevent-apply-hyper-modifier\tinput.el\t/^(defun event-apply-hyper-modifier (_ignore-prompt)$/;\"\tfunction\nevent-apply-shift-modifier\tinput.el\t/^(defun event-apply-shift-modifier (_ignore-prompt)$/;\"\tfunction\nevent-apply-control-modifier\tinput.el\t/^(defun event-apply-control-modifier (_ignore-prompt)$/;\"\tfunction\nevent-apply-meta-modifier\tinput.el\t/^(defun event-apply-meta-modifier (_ignore-prompt)$/;\"\tfunction\nevent-apply-modifier\tinput.el\t/^(defun event-apply-modifier (event symbol lshiftby prefix)$/;\"\tfunction\nclone-buffer-hook\tinput.el\t/^(defvar clone-buffer-hook nil$/;\"\tvariable\nclone-indirect-buffer-hook\tinput.el\t/^(defvar clone-indirect-buffer-hook nil$/;\"\tvariable\nclone-process\tinput.el\t/^(defun clone-process (process &optional newname)$/;\"\tfunction\nclone-buffer\tinput.el\t/^(defun clone-buffer (&optional newname display-flag)$/;\"\tfunction\nclone-indirect-buffer\tinput.el\t/^(defun clone-indirect-buffer (newname display-flag &optional norecord)$/;\"\tfunction\nclone-indirect-buffer-other-window\tinput.el\t/^(defun clone-indirect-buffer-other-window (newname display-flag &optional norecord)$/;\"\tfunction\nnormal-erase-is-backspace\tinput.el\t/^(defcustom normal-erase-is-backspace 'maybe$/;\"\tcustom\nnormal-erase-is-backspace-setup-frame\tinput.el\t/^(defun normal-erase-is-backspace-setup-frame (&optional frame)$/;\"\tfunction\nnormal-erase-is-backspace-mode\tinput.el\t/^(define-minor-mode normal-erase-is-backspace-mode$/;\"\tminorMode\nvis-mode-saved-buffer-invisibility-spec\tinput.el\t/^(defvar vis-mode-saved-buffer-invisibility-spec nil$/;\"\tvariable\nread-only-mode\tinput.el\t/^(define-minor-mode read-only-mode$/;\"\tminorMode\nvisible-mode\tinput.el\t/^(define-minor-mode visible-mode$/;\"\tminorMode\nmessages-buffer-mode-map\tinput.el\t/^(defvar messages-buffer-mode-map$/;\"\tvariable\nmessages-buffer-mode\tinput.el\t/^(define-derived-mode messages-buffer-mode special-mode \"Messages\"$/;\"\tderivedMode\nmessages-buffer\tinput.el\t/^(defun messages-buffer ()$/;\"\tfunction\nbad-packages-alist\tinput.el\t/^(defconst bad-packages-alist$/;\"\tconst\nbad-package-check\tinput.el\t/^(defun bad-package-check (package)$/;\"\tfunction\ndefine-alternatives\tinput.el\t/^(defmacro define-alternatives (command &rest customizations)$/;\"\tmacro\nupcase-dwim\tinput.el\t/^(defun upcase-dwim (arg)$/;\"\tfunction\ndowncase-dwim\tinput.el\t/^(defun downcase-dwim (arg)$/;\"\tfunction\ncapitalize-dwim\tinput.el\t/^(defun capitalize-dwim (arg)$/;\"\tfunction\n"
  },
  {
    "path": "Units/parser-emacsLisp.r/simple-emacsLisp.d/input.el",
    "content": ";;; simple.el --- basic editing commands for Emacs  -*- lexical-binding: t -*-\n\n;; Copyright (C) 1985-1987, 1993-2018 Free Software Foundation, Inc.\n\n;; Maintainer: emacs-devel@gnu.org\n;; Keywords: internal\n;; Package: emacs\n\n;; This file is part of GNU Emacs.\n\n;; GNU Emacs is free software: you can redistribute it and/or modify\n;; it under the terms of the GNU General Public License as published by\n;; the Free Software Foundation, either version 3 of the License, or\n;; (at your option) any later version.\n\n;; GNU Emacs is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n\n;; You should have received a copy of the GNU General Public License\n;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.\n\n;;; Commentary:\n\n;; A grab-bag of basic Emacs commands not specifically related to some\n;; major mode or to file-handling.\n\n;;; Code:\n\n(eval-when-compile (require 'cl-lib))\n\n(declare-function widget-convert \"wid-edit\" (type &rest args))\n(declare-function shell-mode \"shell\" ())\n\n;;; From compile.el\n(defvar compilation-current-error)\n(defvar compilation-context-lines)\n\n(defcustom shell-command-dont-erase-buffer nil\n  \"If non-nil, output buffer is not erased between shell commands.\nAlso, a non-nil value sets the point in the output buffer\nonce the command completes.\nThe value `beg-last-out' sets point at the beginning of the output,\n`end-last-out' sets point at the end of the buffer, `save-point'\nrestores the buffer position before the command.\"\n  :type '(choice\n          (const :tag \"Erase buffer\" nil)\n          (const :tag \"Set point to beginning of last output\" beg-last-out)\n          (const :tag \"Set point to end of last output\" end-last-out)\n          (const :tag \"Save point\" save-point))\n  :group 'shell\n  :version \"26.1\")\n\n(defvar shell-command-saved-pos nil\n  \"Record of point positions in output buffers after command completion.\nThe value is an alist whose elements are of the form (BUFFER . POS),\nwhere BUFFER is the output buffer, and POS is the point position\nin BUFFER once the command finishes.\nThis variable is used when `shell-command-dont-erase-buffer' is non-nil.\")\n\n(defcustom idle-update-delay 0.5\n  \"Idle time delay before updating various things on the screen.\nVarious Emacs features that update auxiliary information when point moves\nwait this many seconds after Emacs becomes idle before doing an update.\"\n  :type 'number\n  :group 'display\n  :version \"22.1\")\n\n(defgroup killing nil\n  \"Killing and yanking commands.\"\n  :group 'editing)\n\n(defgroup paren-matching nil\n  \"Highlight (un)matching of parens and expressions.\"\n  :group 'matching)\n\f\n;;; next-error support framework\n\n(defgroup next-error nil\n  \"`next-error' support framework.\"\n  :group 'compilation\n  :version \"22.1\")\n\n(defface next-error\n  '((t (:inherit region)))\n  \"Face used to highlight next error locus.\"\n  :group 'next-error\n  :version \"22.1\")\n\n(defcustom next-error-highlight 0.5\n  \"Highlighting of locations in selected source buffers.\nIf a number, highlight the locus in `next-error' face for the given time\nin seconds, or until the next command is executed.\nIf t, highlight the locus until the next command is executed, or until\nsome other locus replaces it.\nIf nil, don't highlight the locus in the source buffer.\nIf `fringe-arrow', indicate the locus by the fringe arrow\nindefinitely until some other locus replaces it.\"\n  :type '(choice (number :tag \"Highlight for specified time\")\n                 (const :tag \"Semipermanent highlighting\" t)\n                 (const :tag \"No highlighting\" nil)\n                 (const :tag \"Fringe arrow\" fringe-arrow))\n  :group 'next-error\n  :version \"22.1\")\n\n(defcustom next-error-highlight-no-select 0.5\n  \"Highlighting of locations in `next-error-no-select'.\nIf number, highlight the locus in `next-error' face for given time in seconds.\nIf t, highlight the locus indefinitely until some other locus replaces it.\nIf nil, don't highlight the locus in the source buffer.\nIf `fringe-arrow', indicate the locus by the fringe arrow\nindefinitely until some other locus replaces it.\"\n  :type '(choice (number :tag \"Highlight for specified time\")\n                 (const :tag \"Semipermanent highlighting\" t)\n                 (const :tag \"No highlighting\" nil)\n                 (const :tag \"Fringe arrow\" fringe-arrow))\n  :group 'next-error\n  :version \"22.1\")\n\n(defcustom next-error-recenter nil\n  \"Display the line in the visited source file recentered as specified.\nIf non-nil, the value is passed directly to `recenter'.\"\n  :type '(choice (integer :tag \"Line to recenter to\")\n                 (const :tag \"Center of window\" (4))\n                 (const :tag \"No recentering\" nil))\n  :group 'next-error\n  :version \"23.1\")\n\n(defcustom next-error-hook nil\n  \"List of hook functions run by `next-error' after visiting source file.\"\n  :type 'hook\n  :group 'next-error)\n\n(defvar next-error-highlight-timer nil)\n\n(defvar next-error-overlay-arrow-position nil)\n(put 'next-error-overlay-arrow-position 'overlay-arrow-string (purecopy \"=>\"))\n(add-to-list 'overlay-arrow-variable-list 'next-error-overlay-arrow-position)\n\n(defvar next-error-last-buffer nil\n  \"The most recent `next-error' buffer.\nA buffer becomes most recent when its compilation, grep, or\nsimilar mode is started, or when it is used with \\\\[next-error]\nor \\\\[compile-goto-error].\")\n\n(defvar next-error-function nil\n  \"Function to use to find the next error in the current buffer.\nThe function is called with 2 parameters:\nARG is an integer specifying by how many errors to move.\nRESET is a boolean which, if non-nil, says to go back to the beginning\nof the errors before moving.\nMajor modes providing compile-like functionality should set this variable\nto indicate to `next-error' that this is a candidate buffer and how\nto navigate in it.\")\n(make-variable-buffer-local 'next-error-function)\n\n(defvar next-error-move-function nil\n  \"Function to use to move to an error locus.\nIt takes two arguments, a buffer position in the error buffer\nand a buffer position in the error locus buffer.\nThe buffer for the error locus should already be current.\nnil means use goto-char using the second argument position.\")\n(make-variable-buffer-local 'next-error-move-function)\n\n(defsubst next-error-buffer-p (buffer\n\t\t\t       &optional avoid-current\n\t\t\t       extra-test-inclusive\n\t\t\t       extra-test-exclusive)\n  \"Return non-nil if BUFFER is a `next-error' capable buffer.\nIf AVOID-CURRENT is non-nil, and BUFFER is the current buffer,\nreturn nil.\n\nThe function EXTRA-TEST-INCLUSIVE, if non-nil, is called if\nBUFFER would not normally qualify.  If it returns non-nil, BUFFER\nis considered `next-error' capable, anyway, and the function\nreturns non-nil.\n\nThe function EXTRA-TEST-EXCLUSIVE, if non-nil, is called if the\nbuffer would normally qualify.  If it returns nil, BUFFER is\nrejected, and the function returns nil.\"\n  (and (buffer-name buffer)\t\t;First make sure it's live.\n       (not (and avoid-current (eq buffer (current-buffer))))\n       (with-current-buffer buffer\n\t (if next-error-function   ; This is the normal test.\n\t     ;; Optionally reject some buffers.\n\t     (if extra-test-exclusive\n\t\t (funcall extra-test-exclusive)\n\t       t)\n\t   ;; Optionally accept some other buffers.\n\t   (and extra-test-inclusive\n\t\t(funcall extra-test-inclusive))))))\n\n(defun next-error-find-buffer (&optional avoid-current\n\t\t\t\t\t extra-test-inclusive\n\t\t\t\t\t extra-test-exclusive)\n  \"Return a `next-error' capable buffer.\n\nIf AVOID-CURRENT is non-nil, treat the current buffer\nas an absolute last resort only.\n\nThe function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer\nthat normally would not qualify.  If it returns t, the buffer\nin question is treated as usable.\n\nThe function EXTRA-TEST-EXCLUSIVE, if non-nil, is called in each buffer\nthat would normally be considered usable.  If it returns nil,\nthat buffer is rejected.\"\n  (or\n   ;; 1. If one window on the selected frame displays such buffer, return it.\n   (let ((window-buffers\n          (delete-dups\n           (delq nil (mapcar (lambda (w)\n                               (if (next-error-buffer-p\n\t\t\t\t    (window-buffer w)\n                                    avoid-current\n                                    extra-test-inclusive extra-test-exclusive)\n                                   (window-buffer w)))\n                             (window-list))))))\n     (if (eq (length window-buffers) 1)\n         (car window-buffers)))\n   ;; 2. If next-error-last-buffer is an acceptable buffer, use that.\n   (if (and next-error-last-buffer\n            (next-error-buffer-p next-error-last-buffer avoid-current\n                                 extra-test-inclusive extra-test-exclusive))\n       next-error-last-buffer)\n   ;; 3. If the current buffer is acceptable, choose it.\n   (if (next-error-buffer-p (current-buffer) avoid-current\n\t\t\t    extra-test-inclusive extra-test-exclusive)\n       (current-buffer))\n   ;; 4. Look for any acceptable buffer.\n   (let ((buffers (buffer-list)))\n     (while (and buffers\n                 (not (next-error-buffer-p\n\t\t       (car buffers) avoid-current\n\t\t       extra-test-inclusive extra-test-exclusive)))\n       (setq buffers (cdr buffers)))\n     (car buffers))\n   ;; 5. Use the current buffer as a last resort if it qualifies,\n   ;; even despite AVOID-CURRENT.\n   (and avoid-current\n\t(next-error-buffer-p (current-buffer) nil\n\t\t\t     extra-test-inclusive extra-test-exclusive)\n\t(progn\n\t  (message \"This is the only buffer with error message locations\")\n\t  (current-buffer)))\n   ;; 6. Give up.\n   (error \"No buffers contain error message locations\")))\n\n(defun next-error (&optional arg reset)\n  \"Visit next `next-error' message and corresponding source code.\n\nIf all the error messages parsed so far have been processed already,\nthe message buffer is checked for new ones.\n\nA prefix ARG specifies how many error messages to move;\nnegative means move back to previous error messages.\nJust \\\\[universal-argument] as a prefix means reparse the error message buffer\nand start at the first error.\n\nThe RESET argument specifies that we should restart from the beginning.\n\n\\\\[next-error] normally uses the most recently started\ncompilation, grep, or occur buffer.  It can also operate on any\nbuffer with output from the \\\\[compile], \\\\[grep] commands, or,\nmore generally, on any buffer in Compilation mode or with\nCompilation Minor mode enabled, or any buffer in which\n`next-error-function' is bound to an appropriate function.\nTo specify use of a particular buffer for error messages, type\n\\\\[next-error] in that buffer when it is the only one displayed\nin the current frame.\n\nOnce \\\\[next-error] has chosen the buffer for error messages, it\nruns `next-error-hook' with `run-hooks', and stays with that buffer\nuntil you use it in some other buffer which uses Compilation mode\nor Compilation Minor mode.\n\nTo control which errors are matched, customize the variable\n`compilation-error-regexp-alist'.\"\n  (interactive \"P\")\n  (if (consp arg) (setq reset t arg nil))\n  (when (setq next-error-last-buffer (next-error-find-buffer))\n    ;; we know here that next-error-function is a valid symbol we can funcall\n    (with-current-buffer next-error-last-buffer\n      (funcall next-error-function (prefix-numeric-value arg) reset)\n      (when next-error-recenter\n        (recenter next-error-recenter))\n      (run-hooks 'next-error-hook))))\n\n(defun next-error-internal ()\n  \"Visit the source code corresponding to the `next-error' message at point.\"\n  (setq next-error-last-buffer (current-buffer))\n  ;; we know here that next-error-function is a valid symbol we can funcall\n  (with-current-buffer next-error-last-buffer\n    (funcall next-error-function 0 nil)\n    (when next-error-recenter\n      (recenter next-error-recenter))\n    (run-hooks 'next-error-hook)))\n\n(defalias 'goto-next-locus 'next-error)\n(defalias 'next-match 'next-error)\n\n(defun previous-error (&optional n)\n  \"Visit previous `next-error' message and corresponding source code.\n\nPrefix arg N says how many error messages to move backwards (or\nforwards, if negative).\n\nThis operates on the output from the \\\\[compile] and \\\\[grep] commands.\"\n  (interactive \"p\")\n  (next-error (- (or n 1))))\n\n(defun first-error (&optional n)\n  \"Restart at the first error.\nVisit corresponding source code.\nWith prefix arg N, visit the source code of the Nth error.\nThis operates on the output from the \\\\[compile] command, for instance.\"\n  (interactive \"p\")\n  (next-error n t))\n\n(defun next-error-no-select (&optional n)\n  \"Move point to the next error in the `next-error' buffer and highlight match.\nPrefix arg N says how many error messages to move forwards (or\nbackwards, if negative).\nFinds and highlights the source line like \\\\[next-error], but does not\nselect the source buffer.\"\n  (interactive \"p\")\n  (let ((next-error-highlight next-error-highlight-no-select))\n    (next-error n))\n  (pop-to-buffer next-error-last-buffer))\n\n(defun previous-error-no-select (&optional n)\n  \"Move point to the previous error in the `next-error' buffer and highlight match.\nPrefix arg N says how many error messages to move backwards (or\nforwards, if negative).\nFinds and highlights the source line like \\\\[previous-error], but does not\nselect the source buffer.\"\n  (interactive \"p\")\n  (next-error-no-select (- (or n 1))))\n\n;; Internal variable for `next-error-follow-mode-post-command-hook'.\n(defvar next-error-follow-last-line nil)\n\n(define-minor-mode next-error-follow-minor-mode\n  \"Minor mode for compilation, occur and diff modes.\nWith a prefix argument ARG, enable mode if ARG is positive, and\ndisable it otherwise.  If called from Lisp, enable mode if ARG is\nomitted or nil.\nWhen turned on, cursor motion in the compilation, grep, occur or diff\nbuffer causes automatic display of the corresponding source code location.\"\n  :group 'next-error :init-value nil :lighter \" Fol\"\n  (if (not next-error-follow-minor-mode)\n      (remove-hook 'post-command-hook 'next-error-follow-mode-post-command-hook t)\n    (add-hook 'post-command-hook 'next-error-follow-mode-post-command-hook nil t)\n    (make-local-variable 'next-error-follow-last-line)))\n\n;; Used as a `post-command-hook' by `next-error-follow-mode'\n;; for the *Compilation* *grep* and *Occur* buffers.\n(defun next-error-follow-mode-post-command-hook ()\n  (unless (equal next-error-follow-last-line (line-number-at-pos))\n    (setq next-error-follow-last-line (line-number-at-pos))\n    (condition-case nil\n\t(let ((compilation-context-lines nil))\n\t  (setq compilation-current-error (point))\n\t  (next-error-no-select 0))\n      (error t))))\n\n\f\n;;;\n\n(defun fundamental-mode ()\n  \"Major mode not specialized for anything in particular.\nOther major modes are defined by comparison with this one.\"\n  (interactive)\n  (kill-all-local-variables)\n  (run-mode-hooks))\n\n;; Special major modes to view specially formatted data rather than files.\n\n(defvar special-mode-map\n  (let ((map (make-sparse-keymap)))\n    (suppress-keymap map)\n    (define-key map \"q\" 'quit-window)\n    (define-key map \" \" 'scroll-up-command)\n    (define-key map [?\\S-\\ ] 'scroll-down-command)\n    (define-key map \"\\C-?\" 'scroll-down-command)\n    (define-key map \"?\" 'describe-mode)\n    (define-key map \"h\" 'describe-mode)\n    (define-key map \">\" 'end-of-buffer)\n    (define-key map \"<\" 'beginning-of-buffer)\n    (define-key map \"g\" 'revert-buffer)\n    map))\n\n(put 'special-mode 'mode-class 'special)\n(define-derived-mode special-mode nil \"Special\"\n  \"Parent major mode from which special major modes should inherit.\"\n  (setq buffer-read-only t))\n\n;; Making and deleting lines.\n\n(defvar self-insert-uses-region-functions nil\n  \"Special hook to tell if `self-insert-command' will use the region.\nIt must be called via `run-hook-with-args-until-success' with no arguments.\n\nIf any function on this hook returns a non-nil value, `delete-selection-mode'\nwill act on that value (see `delete-selection-helper'), and will\nusually delete the region.  If all the functions on this hook return\nnil, it is an indiction that `self-insert-command' needs the region\nuntouched by `delete-selection-mode', and will itself do whatever is\nappropriate with the region.\nAny function on `post-self-insert-hook' which act on the region should\nadd a function to this hook so that `delete-selection-mode' could\nrefrain from deleting the region before `post-self-insert-hook'\nfunctions are called.\nThis hook is run by `delete-selection-uses-region-p', which see.\")\n\n(defvar hard-newline (propertize \"\\n\" 'hard t 'rear-nonsticky '(hard))\n  \"Propertized string representing a hard newline character.\")\n\n(defun newline (&optional arg interactive)\n  \"Insert a newline, and move to left margin of the new line if it's blank.\nIf option `use-hard-newlines' is non-nil, the newline is marked with the\ntext-property `hard'.\nWith ARG, insert that many newlines.\n\nIf `electric-indent-mode' is enabled, this indents the final new line\nthat it adds, and reindents the preceding line.  To just insert\na newline, use \\\\[electric-indent-just-newline].\n\nCalls `auto-fill-function' if the current column number is greater\nthan the value of `fill-column' and ARG is nil.\nA non-nil INTERACTIVE argument means to run the `post-self-insert-hook'.\"\n  (interactive \"*P\\np\")\n  (barf-if-buffer-read-only)\n  ;; Call self-insert so that auto-fill, abbrev expansion etc. happens.\n  ;; Set last-command-event to tell self-insert what to insert.\n  (let* ((was-page-start (and (bolp) (looking-at page-delimiter)))\n         (beforepos (point))\n         (last-command-event ?\\n)\n         ;; Don't auto-fill if we have a numeric argument.\n         (auto-fill-function (if arg nil auto-fill-function))\n         (arg (prefix-numeric-value arg))\n         (postproc\n          ;; Do the rest in post-self-insert-hook, because we want to do it\n          ;; *before* other functions on that hook.\n          (lambda ()\n            ;; Mark the newline(s) `hard'.\n            (if use-hard-newlines\n                (set-hard-newline-properties\n                 (- (point) arg) (point)))\n            ;; If the newline leaves the previous line blank, and we\n            ;; have a left margin, delete that from the blank line.\n            (save-excursion\n              (goto-char beforepos)\n              (beginning-of-line)\n              (and (looking-at \"[ \\t]$\")\n                   (> (current-left-margin) 0)\n                   (delete-region (point)\n                                  (line-end-position))))\n            ;; Indent the line after the newline, except in one case:\n            ;; when we added the newline at the beginning of a line which\n            ;; starts a page.\n            (or was-page-start\n                (move-to-left-margin nil t)))))\n    (if (not interactive)\n\t;; FIXME: For non-interactive uses, many calls actually\n\t;; just want (insert \"\\n\"), so maybe we should do just\n\t;; that, so as to avoid the risk of filling or running\n\t;; abbrevs unexpectedly.\n\t(let ((post-self-insert-hook (list postproc)))\n\t  (self-insert-command arg))\n      (unwind-protect\n\t  (progn\n\t    (add-hook 'post-self-insert-hook postproc nil t)\n\t    (self-insert-command arg))\n\t;; We first used let-binding to protect the hook, but that\n\t;; was naive since add-hook affects the symbol-default\n\t;; value of the variable, whereas the let-binding might\n\t;; only protect the buffer-local value.\n\t(remove-hook 'post-self-insert-hook postproc t))))\n  nil)\n\n(defun set-hard-newline-properties (from to)\n  (let ((sticky (get-text-property from 'rear-nonsticky)))\n    (put-text-property from to 'hard 't)\n    ;; If rear-nonsticky is not \"t\", add 'hard to rear-nonsticky list\n    (if (and (listp sticky) (not (memq 'hard sticky)))\n\t(put-text-property from (point) 'rear-nonsticky\n\t\t\t   (cons 'hard sticky)))))\n\n(defun open-line (n)\n  \"Insert a newline and leave point before it.\nIf there is a fill prefix and/or a `left-margin', insert them on\nthe new line if the line would have been blank.\nWith arg N, insert N newlines.\"\n  (interactive \"*p\")\n  (let* ((do-fill-prefix (and fill-prefix (bolp)))\n\t (do-left-margin (and (bolp) (> (current-left-margin) 0)))\n\t (loc (point-marker))\n         ;; Don't expand an abbrev before point.\n\t (abbrev-mode nil))\n    (newline n)\n    (goto-char loc)\n    (while (> n 0)\n      (cond ((bolp)\n\t     (if do-left-margin (indent-to (current-left-margin)))\n\t     (if do-fill-prefix (insert-and-inherit fill-prefix))))\n      (forward-line 1)\n      (setq n (1- n)))\n    (goto-char loc)\n    ;; Necessary in case a margin or prefix was inserted.\n    (end-of-line)))\n\n(defun split-line (&optional arg)\n  \"Split current line, moving portion beyond point vertically down.\nIf the current line starts with `fill-prefix', insert it on the new\nline as well.  With prefix ARG, don't insert `fill-prefix' on new line.\n\nWhen called from Lisp code, ARG may be a prefix string to copy.\"\n  (interactive \"*P\")\n  (skip-chars-forward \" \\t\")\n  (let* ((col (current-column))\n\t (pos (point))\n\t ;; What prefix should we check for (nil means don't).\n\t (prefix (cond ((stringp arg) arg)\n\t\t       (arg nil)\n\t\t       (t fill-prefix)))\n\t ;; Does this line start with it?\n\t (have-prfx (and prefix\n\t\t\t (save-excursion\n\t\t\t   (beginning-of-line)\n\t\t\t   (looking-at (regexp-quote prefix))))))\n    (newline 1)\n    (if have-prfx (insert-and-inherit prefix))\n    (indent-to col 0)\n    (goto-char pos)))\n\n(defun delete-indentation (&optional arg)\n  \"Join this line to previous and fix up whitespace at join.\nIf there is a fill prefix, delete it from the beginning of this line.\nWith argument, join this line to following line.\"\n  (interactive \"*P\")\n  (beginning-of-line)\n  (if arg (forward-line 1))\n  (if (eq (preceding-char) ?\\n)\n      (progn\n\t(delete-region (point) (1- (point)))\n\t;; If the second line started with the fill prefix,\n\t;; delete the prefix.\n\t(if (and fill-prefix\n\t\t (<= (+ (point) (length fill-prefix)) (point-max))\n\t\t (string= fill-prefix\n\t\t\t  (buffer-substring (point)\n\t\t\t\t\t    (+ (point) (length fill-prefix)))))\n\t    (delete-region (point) (+ (point) (length fill-prefix))))\n\t(fixup-whitespace))))\n\n(defalias 'join-line #'delete-indentation) ; easier to find\n\n(defun delete-blank-lines ()\n  \"On blank line, delete all surrounding blank lines, leaving just one.\nOn isolated blank line, delete that one.\nOn nonblank line, delete any immediately following blank lines.\"\n  (interactive \"*\")\n  (let (thisblank singleblank)\n    (save-excursion\n      (beginning-of-line)\n      (setq thisblank (looking-at \"[ \\t]*$\"))\n      ;; Set singleblank if there is just one blank line here.\n      (setq singleblank\n\t    (and thisblank\n\t\t (not (looking-at \"[ \\t]*\\n[ \\t]*$\"))\n\t\t (or (bobp)\n\t\t     (progn (forward-line -1)\n\t\t\t    (not (looking-at \"[ \\t]*$\")))))))\n    ;; Delete preceding blank lines, and this one too if it's the only one.\n    (if thisblank\n\t(progn\n\t  (beginning-of-line)\n\t  (if singleblank (forward-line 1))\n\t  (delete-region (point)\n\t\t\t (if (re-search-backward \"[^ \\t\\n]\" nil t)\n\t\t\t     (progn (forward-line 1) (point))\n\t\t\t   (point-min)))))\n    ;; Delete following blank lines, unless the current line is blank\n    ;; and there are no following blank lines.\n    (if (not (and thisblank singleblank))\n\t(save-excursion\n\t  (end-of-line)\n\t  (forward-line 1)\n\t  (delete-region (point)\n\t\t\t (if (re-search-forward \"[^ \\t\\n]\" nil t)\n\t\t\t     (progn (beginning-of-line) (point))\n\t\t\t   (point-max)))))\n    ;; Handle the special case where point is followed by newline and eob.\n    ;; Delete the line, leaving point at eob.\n    (if (looking-at \"^[ \\t]*\\n\\\\'\")\n\t(delete-region (point) (point-max)))))\n\n(defcustom delete-trailing-lines t\n  \"If non-nil, \\\\[delete-trailing-whitespace] deletes trailing lines.\nTrailing lines are deleted only if `delete-trailing-whitespace'\nis called on the entire buffer (rather than an active region).\"\n  :type 'boolean\n  :group 'editing\n  :version \"24.3\")\n\n(defun region-modifiable-p (start end)\n  \"Return non-nil if the region contains no read-only text.\"\n  (and (not (get-text-property start 'read-only))\n       (eq end (next-single-property-change start 'read-only nil end))))\n\n(defun delete-trailing-whitespace (&optional start end)\n  \"Delete trailing whitespace between START and END.\nIf called interactively, START and END are the start/end of the\nregion if the mark is active, or of the buffer's accessible\nportion if the mark is inactive.\n\nThis command deletes whitespace characters after the last\nnon-whitespace character in each line between START and END.  It\ndoes not consider formfeed characters to be whitespace.\n\nIf this command acts on the entire buffer (i.e. if called\ninteractively with the mark inactive, or called from Lisp with\nEND nil), it also deletes all trailing lines at the end of the\nbuffer if the variable `delete-trailing-lines' is non-nil.\"\n  (interactive (progn\n                 (barf-if-buffer-read-only)\n                 (if (use-region-p)\n                     (list (region-beginning) (region-end))\n                   (list nil nil))))\n  (save-match-data\n    (save-excursion\n      (let ((end-marker (and end (copy-marker end))))\n        (goto-char (or start (point-min)))\n        (with-syntax-table (make-syntax-table (syntax-table))\n          ;; Don't delete formfeeds, even if they are considered whitespace.\n          (modify-syntax-entry ?\\f \"_\")\n          (while (re-search-forward \"\\\\s-$\" end-marker t)\n            (skip-syntax-backward \"-\" (line-beginning-position))\n            (let ((b (point)) (e (match-end 0)))\n              (when (region-modifiable-p b e)\n                (delete-region b e)))))\n        (if end\n            (set-marker end-marker nil)\n          ;; Delete trailing empty lines.\n          (and delete-trailing-lines\n               ;; Really the end of buffer.\n               (= (goto-char (point-max)) (1+ (buffer-size)))\n               (<= (skip-chars-backward \"\\n\") -2)\n               (region-modifiable-p (1+ (point)) (point-max))\n               (delete-region (1+ (point)) (point-max)))))))\n  ;; Return nil for the benefit of `write-file-functions'.\n  nil)\n\n(defun newline-and-indent ()\n  \"Insert a newline, then indent according to major mode.\nIndentation is done using the value of `indent-line-function'.\nIn programming language modes, this is the same as TAB.\nIn some text modes, where TAB inserts a tab, this command indents to the\ncolumn specified by the function `current-left-margin'.\"\n  (interactive \"*\")\n  (delete-horizontal-space t)\n  (newline nil t)\n  (indent-according-to-mode))\n\n(defun reindent-then-newline-and-indent ()\n  \"Reindent current line, insert newline, then indent the new line.\nIndentation of both lines is done according to the current major mode,\nwhich means calling the current value of `indent-line-function'.\nIn programming language modes, this is the same as TAB.\nIn some text modes, where TAB inserts a tab, this indents to the\ncolumn specified by the function `current-left-margin'.\"\n  (interactive \"*\")\n  (let ((pos (point)))\n    ;; Be careful to insert the newline before indenting the line.\n    ;; Otherwise, the indentation might be wrong.\n    (newline)\n    (save-excursion\n      (goto-char pos)\n      ;; We are at EOL before the call to indent-according-to-mode, and\n      ;; after it we usually are as well, but not always.  We tried to\n      ;; address it with `save-excursion' but that uses a normal marker\n      ;; whereas we need `move after insertion', so we do the save/restore\n      ;; by hand.\n      (setq pos (copy-marker pos t))\n      (indent-according-to-mode)\n      (goto-char pos)\n      ;; Remove the trailing white-space after indentation because\n      ;; indentation may introduce the whitespace.\n      (delete-horizontal-space t))\n    (indent-according-to-mode)))\n\n(defcustom read-quoted-char-radix 8\n  \"Radix for \\\\[quoted-insert] and other uses of `read-quoted-char'.\nLegitimate radix values are 8, 10 and 16.\"\n :type '(choice (const 8) (const 10) (const 16))\n :group 'editing-basics)\n\n(defun read-quoted-char (&optional prompt)\n  \"Like `read-char', but do not allow quitting.\nAlso, if the first character read is an octal digit,\nwe read any number of octal digits and return the\nspecified character code.  Any nondigit terminates the sequence.\nIf the terminator is RET, it is discarded;\nany other terminator is used itself as input.\n\nThe optional argument PROMPT specifies a string to use to prompt the user.\nThe variable `read-quoted-char-radix' controls which radix to use\nfor numeric input.\"\n  (let ((message-log-max nil)\n\t(help-events (delq nil (mapcar (lambda (c) (unless (characterp c) c))\n\t\t\t\t       help-event-list)))\n\tdone (first t) (code 0) char translated)\n    (while (not done)\n      (let ((inhibit-quit first)\n\t    ;; Don't let C-h or other help chars get the help\n\t    ;; message--only help function keys.  See bug#16617.\n\t    (help-char nil)\n\t    (help-event-list help-events)\n\t    (help-form\n\t     \"Type the special character you want to use,\nor the octal character code.\nRET terminates the character code and is discarded;\nany other non-digit terminates the character code and is then used as input.\"))\n\t(setq char (read-event (and prompt (format \"%s-\" prompt)) t))\n\t(if inhibit-quit (setq quit-flag nil)))\n      ;; Translate TAB key into control-I ASCII character, and so on.\n      ;; Note: `read-char' does it using the `ascii-character' property.\n      ;; We tried using read-key instead, but that disables the keystroke\n      ;; echo produced by 'C-q', see bug#24635.\n      (let ((translation (lookup-key local-function-key-map (vector char))))\n\t(setq translated (if (arrayp translation)\n\t\t\t     (aref translation 0)\n\t\t\t   char)))\n      (if (integerp translated)\n\t  (setq translated (char-resolve-modifiers translated)))\n      (cond ((null translated))\n\t    ((not (integerp translated))\n\t     (setq unread-command-events (list char)\n\t\t   done t))\n\t    ((/= (logand translated ?\\M-\\^@) 0)\n\t     ;; Turn a meta-character into a character with the 0200 bit set.\n\t     (setq code (logior (logand translated (lognot ?\\M-\\^@)) 128)\n\t\t   done t))\n\t    ((and (<= ?0 translated)\n                  (< translated (+ ?0 (min 10 read-quoted-char-radix))))\n\t     (setq code (+ (* code read-quoted-char-radix) (- translated ?0)))\n\t     (and prompt (setq prompt (message \"%s %c\" prompt translated))))\n\t    ((and (<= ?a (downcase translated))\n\t\t  (< (downcase translated)\n                     (+ ?a -10 (min 36 read-quoted-char-radix))))\n\t     (setq code (+ (* code read-quoted-char-radix)\n\t\t\t   (+ 10 (- (downcase translated) ?a))))\n\t     (and prompt (setq prompt (message \"%s %c\" prompt translated))))\n\t    ((and (not first) (eq translated ?\\C-m))\n\t     (setq done t))\n\t    ((not first)\n\t     (setq unread-command-events (list char)\n\t\t   done t))\n\t    (t (setq code translated\n\t\t     done t)))\n      (setq first nil))\n    code))\n\n(defun quoted-insert (arg)\n  \"Read next input character and insert it.\nThis is useful for inserting control characters.\nWith argument, insert ARG copies of the character.\n\nIf the first character you type after this command is an octal digit,\nyou should type a sequence of octal digits which specify a character code.\nAny nondigit terminates the sequence.  If the terminator is a RET,\nit is discarded; any other terminator is used itself as input.\nThe variable `read-quoted-char-radix' specifies the radix for this feature;\nset it to 10 or 16 to use decimal or hex instead of octal.\n\nIn overwrite mode, this function inserts the character anyway, and\ndoes not handle octal digits specially.  This means that if you use\noverwrite as your normal editing mode, you can use this function to\ninsert characters when necessary.\n\nIn binary overwrite mode, this function does overwrite, and octal\ndigits are interpreted as a character code.  This is intended to be\nuseful for editing binary files.\"\n  (interactive \"*p\")\n  (let* ((char\n\t  ;; Avoid \"obsolete\" warnings for translation-table-for-input.\n\t  (with-no-warnings\n\t    (let (translation-table-for-input input-method-function)\n\t      (if (or (not overwrite-mode)\n\t\t      (eq overwrite-mode 'overwrite-mode-binary))\n\t\t  (read-quoted-char)\n\t\t(read-char))))))\n    ;; This used to assume character codes 0240 - 0377 stand for\n    ;; characters in some single-byte character set, and converted them\n    ;; to Emacs characters.  But in 23.1 this feature is deprecated\n    ;; in favor of inserting the corresponding Unicode characters.\n    ;; (if (and enable-multibyte-characters\n    ;;          (>= char ?\\240)\n    ;;          (<= char ?\\377))\n    ;;     (setq char (unibyte-char-to-multibyte char)))\n    (unless (characterp char)\n      (user-error \"%s is not a valid character\"\n\t\t  (key-description (vector char))))\n    (if (> arg 0)\n\t(if (eq overwrite-mode 'overwrite-mode-binary)\n\t    (delete-char arg)))\n    (while (> arg 0)\n      (insert-and-inherit char)\n      (setq arg (1- arg)))))\n\n(defun forward-to-indentation (&optional arg)\n  \"Move forward ARG lines and position at first nonblank character.\"\n  (interactive \"^p\")\n  (forward-line (or arg 1))\n  (skip-chars-forward \" \\t\"))\n\n(defun backward-to-indentation (&optional arg)\n  \"Move backward ARG lines and position at first nonblank character.\"\n  (interactive \"^p\")\n  (forward-line (- (or arg 1)))\n  (skip-chars-forward \" \\t\"))\n\n(defun back-to-indentation ()\n  \"Move point to the first non-whitespace character on this line.\"\n  (interactive \"^\")\n  (beginning-of-line 1)\n  (skip-syntax-forward \" \" (line-end-position))\n  ;; Move back over chars that have whitespace syntax but have the p flag.\n  (backward-prefix-chars))\n\n(defun fixup-whitespace ()\n  \"Fixup white space between objects around point.\nLeave one space or none, according to the context.\"\n  (interactive \"*\")\n  (save-excursion\n    (delete-horizontal-space)\n    (if (or (looking-at \"^\\\\|$\\\\|\\\\s)\")\n\t    (save-excursion (forward-char -1)\n\t\t\t    (looking-at \"$\\\\|\\\\s(\\\\|\\\\s'\")))\n\tnil\n      (insert ?\\s))))\n\n(defun delete-horizontal-space (&optional backward-only)\n  \"Delete all spaces and tabs around point.\nIf BACKWARD-ONLY is non-nil, only delete them before point.\"\n  (interactive \"*P\")\n  (let ((orig-pos (point)))\n    (delete-region\n     (if backward-only\n\t orig-pos\n       (progn\n\t (skip-chars-forward \" \\t\")\n\t (constrain-to-field nil orig-pos t)))\n     (progn\n       (skip-chars-backward \" \\t\")\n       (constrain-to-field nil orig-pos)))))\n\n(defun just-one-space (&optional n)\n  \"Delete all spaces and tabs around point, leaving one space (or N spaces).\nIf N is negative, delete newlines as well, leaving -N spaces.\nSee also `cycle-spacing'.\"\n  (interactive \"*p\")\n  (cycle-spacing n nil 'single-shot))\n\n(defvar cycle-spacing--context nil\n  \"Store context used in consecutive calls to `cycle-spacing' command.\nThe first time `cycle-spacing' runs, it saves in this variable:\nits N argument, the original point position, and the original spacing\naround point.\")\n\n(defun cycle-spacing (&optional n preserve-nl-back mode)\n  \"Manipulate whitespace around point in a smart way.\nIn interactive use, this function behaves differently in successive\nconsecutive calls.\n\nThe first call in a sequence acts like `just-one-space'.\nIt deletes all spaces and tabs around point, leaving one space\n\\(or N spaces).  N is the prefix argument.  If N is negative,\nit deletes newlines as well, leaving -N spaces.\n\\(If PRESERVE-NL-BACK is non-nil, it does not delete newlines before point.)\n\nThe second call in a sequence deletes all spaces.\n\nThe third call in a sequence restores the original whitespace (and point).\n\nIf MODE is `single-shot', it only performs the first step in the sequence.\nIf MODE is `fast' and the first step would not result in any change\n\\(i.e., there are exactly (abs N) spaces around point),\nthe function goes straight to the second step.\n\nRepeatedly calling the function with different values of N starts a\nnew sequence each time.\"\n  (interactive \"*p\")\n  (let ((orig-pos\t (point))\n\t(skip-characters (if (and n (< n 0)) \" \\t\\n\\r\" \" \\t\"))\n\t(num\t\t (abs (or n 1))))\n    (skip-chars-backward (if preserve-nl-back \" \\t\" skip-characters))\n    (constrain-to-field nil orig-pos)\n    (cond\n     ;; Command run for the first time, single-shot mode or different argument\n     ((or (eq 'single-shot mode)\n\t  (not (equal last-command this-command))\n\t  (not cycle-spacing--context)\n\t  (not (eq (car cycle-spacing--context) n)))\n      (let* ((start (point))\n\t     (num   (- num (skip-chars-forward \" \" (+ num (point)))))\n\t     (mid   (point))\n\t     (end   (progn\n\t\t      (skip-chars-forward skip-characters)\n\t\t      (constrain-to-field nil orig-pos t))))\n\t(setq cycle-spacing--context  ;; Save for later.\n\t      ;; Special handling for case where there was no space at all.\n\t      (unless (= start end)\n                (cons n (cons orig-pos (buffer-substring start (point))))))\n\t;; If this run causes no change in buffer content, delete all spaces,\n\t;; otherwise delete all excess spaces.\n\t(delete-region (if (and (eq mode 'fast) (zerop num) (= mid end))\n\t\t\t   start mid) end)\n        (insert (make-string num ?\\s))))\n\n     ;; Command run for the second time.\n     ((not (equal orig-pos (point)))\n      (delete-region (point) orig-pos))\n\n     ;; Command run for the third time.\n     (t\n      (insert (cddr cycle-spacing--context))\n      (goto-char (cadr cycle-spacing--context))\n      (setq cycle-spacing--context nil)))))\n\f\n(defun beginning-of-buffer (&optional arg)\n  \"Move point to the beginning of the buffer.\nWith numeric arg N, put point N/10 of the way from the beginning.\nIf the buffer is narrowed, this command uses the beginning of the\naccessible part of the buffer.\n\nPush mark at previous position, unless either a \\\\[universal-argument] prefix\nis supplied, or Transient Mark mode is enabled and the mark is active.\"\n  (declare (interactive-only \"use `(goto-char (point-min))' instead.\"))\n  (interactive \"^P\")\n  (or (consp arg)\n      (region-active-p)\n      (push-mark))\n  (let ((size (- (point-max) (point-min))))\n    (goto-char (if (and arg (not (consp arg)))\n\t\t   (+ (point-min)\n\t\t      (if (> size 10000)\n\t\t\t  ;; Avoid overflow for large buffer sizes!\n\t\t\t  (* (prefix-numeric-value arg)\n\t\t\t     (/ size 10))\n\t\t\t(/ (+ 10 (* size (prefix-numeric-value arg))) 10)))\n\t\t (point-min))))\n  (if (and arg (not (consp arg))) (forward-line 1)))\n\n(defun end-of-buffer (&optional arg)\n  \"Move point to the end of the buffer.\nWith numeric arg N, put point N/10 of the way from the end.\nIf the buffer is narrowed, this command uses the end of the\naccessible part of the buffer.\n\nPush mark at previous position, unless either a \\\\[universal-argument] prefix\nis supplied, or Transient Mark mode is enabled and the mark is active.\"\n  (declare (interactive-only \"use `(goto-char (point-max))' instead.\"))\n  (interactive \"^P\")\n  (or (consp arg) (region-active-p) (push-mark))\n  (let ((size (- (point-max) (point-min))))\n    (goto-char (if (and arg (not (consp arg)))\n\t\t   (- (point-max)\n\t\t      (if (> size 10000)\n\t\t\t  ;; Avoid overflow for large buffer sizes!\n\t\t\t  (* (prefix-numeric-value arg)\n\t\t\t     (/ size 10))\n\t\t\t(/ (* size (prefix-numeric-value arg)) 10)))\n\t\t (point-max))))\n  ;; If we went to a place in the middle of the buffer,\n  ;; adjust it to the beginning of a line.\n  (cond ((and arg (not (consp arg))) (forward-line 1))\n\t((and (eq (current-buffer) (window-buffer))\n              (> (point) (window-end nil t)))\n\t ;; If the end of the buffer is not already on the screen,\n\t ;; then scroll specially to put it near, but not at, the bottom.\n\t (overlay-recenter (point))\n\t (recenter -3))))\n\n(defcustom delete-active-region t\n  \"Whether single-char deletion commands delete an active region.\nThis has an effect only if Transient Mark mode is enabled, and\naffects `delete-forward-char' and `delete-backward-char', though\nnot `delete-char'.\n\nIf the value is the symbol `kill', the active region is killed\ninstead of deleted.\"\n  :type '(choice (const :tag \"Delete active region\" t)\n                 (const :tag \"Kill active region\" kill)\n                 (const :tag \"Do ordinary deletion\" nil))\n  :group 'killing\n  :version \"24.1\")\n\n(defvar region-extract-function\n  (lambda (method)\n    (when (region-beginning)\n      (cond\n       ((eq method 'bounds)\n        (list (cons (region-beginning) (region-end))))\n       ((eq method 'delete-only)\n        (delete-region (region-beginning) (region-end)))\n       (t\n        (filter-buffer-substring (region-beginning) (region-end) method)))))\n  \"Function to get the region's content.\nCalled with one argument METHOD which can be:\n- nil: return the content as a string.\n- `delete-only': delete the region; the return value is undefined.\n- `bounds': return the boundaries of the region as a list of cons\n  cells of the form (START . END).\n- anything else: delete the region and return its content\n  as a string, after filtering it with `filter-buffer-substring', which\n  is called with METHOD as its 3rd argument.\")\n\n(defvar region-insert-function\n  (lambda (lines)\n    (let ((first t))\n      (while lines\n        (or first\n            (insert ?\\n))\n        (insert-for-yank (car lines))\n        (setq lines (cdr lines)\n              first nil))))\n  \"Function to insert the region's content.\nCalled with one argument LINES.\nInsert the region as a list of lines.\")\n\n(defun delete-backward-char (n &optional killflag)\n  \"Delete the previous N characters (following if N is negative).\nIf Transient Mark mode is enabled, the mark is active, and N is 1,\ndelete the text in the region and deactivate the mark instead.\nTo disable this, set option `delete-active-region' to nil.\n\nOptional second arg KILLFLAG, if non-nil, means to kill (save in\nkill ring) instead of delete.  Interactively, N is the prefix\narg, and KILLFLAG is set if N is explicitly specified.\n\nWhen killing, the killed text is filtered by\n`filter-buffer-substring' before it is saved in the kill ring, so\nthe actual saved text might be different from what was killed.\n\nIn Overwrite mode, single character backward deletion may replace\ntabs with spaces so as to back over columns, unless point is at\nthe end of the line.\"\n  (declare (interactive-only delete-char))\n  (interactive \"p\\nP\")\n  (unless (integerp n)\n    (signal 'wrong-type-argument (list 'integerp n)))\n  (cond ((and (use-region-p)\n\t      delete-active-region\n\t      (= n 1))\n\t ;; If a region is active, kill or delete it.\n\t (if (eq delete-active-region 'kill)\n\t     (kill-region (region-beginning) (region-end) 'region)\n           (funcall region-extract-function 'delete-only)))\n\t;; In Overwrite mode, maybe untabify while deleting\n\t((null (or (null overwrite-mode)\n\t\t   (<= n 0)\n\t\t   (memq (char-before) '(?\\t ?\\n))\n\t\t   (eobp)\n\t\t   (eq (char-after) ?\\n)))\n\t (let ((ocol (current-column)))\n           (delete-char (- n) killflag)\n\t   (save-excursion\n\t     (insert-char ?\\s (- ocol (current-column)) nil))))\n\t;; Otherwise, do simple deletion.\n\t(t (delete-char (- n) killflag))))\n\n(defun delete-forward-char (n &optional killflag)\n  \"Delete the following N characters (previous if N is negative).\nIf Transient Mark mode is enabled, the mark is active, and N is 1,\ndelete the text in the region and deactivate the mark instead.\nTo disable this, set variable `delete-active-region' to nil.\n\nOptional second arg KILLFLAG non-nil means to kill (save in kill\nring) instead of delete.  Interactively, N is the prefix arg, and\nKILLFLAG is set if N was explicitly specified.\n\nWhen killing, the killed text is filtered by\n`filter-buffer-substring' before it is saved in the kill ring, so\nthe actual saved text might be different from what was killed.\"\n  (declare (interactive-only delete-char))\n  (interactive \"p\\nP\")\n  (unless (integerp n)\n    (signal 'wrong-type-argument (list 'integerp n)))\n  (cond ((and (use-region-p)\n\t      delete-active-region\n\t      (= n 1))\n\t ;; If a region is active, kill or delete it.\n\t (if (eq delete-active-region 'kill)\n\t     (kill-region (region-beginning) (region-end) 'region)\n\t   (funcall region-extract-function 'delete-only)))\n\n\t;; Otherwise, do simple deletion.\n\t(t (delete-char n killflag))))\n\n(defun mark-whole-buffer ()\n  \"Put point at beginning and mark at end of buffer.\nIf narrowing is in effect, only uses the accessible part of the buffer.\nYou probably should not use this function in Lisp programs;\nit is usually a mistake for a Lisp function to use any subroutine\nthat uses or sets the mark.\"\n  (declare (interactive-only t))\n  (interactive)\n  (push-mark)\n  (push-mark (point-max) nil t)\n  ;; This is really `point-min' in most cases, but if we're in the\n  ;; minibuffer, this is at the end of the prompt.\n  (goto-char (minibuffer-prompt-end)))\n\f\n\n;; Counting lines, one way or another.\n\n(defun goto-line (line &optional buffer)\n  \"Go to LINE, counting from line 1 at beginning of buffer.\nIf called interactively, a numeric prefix argument specifies\nLINE; without a numeric prefix argument, read LINE from the\nminibuffer.\n\nIf optional argument BUFFER is non-nil, switch to that buffer and\nmove to line LINE there.  If called interactively with \\\\[universal-argument]\nas argument, BUFFER is the most recently selected other buffer.\n\nPrior to moving point, this function sets the mark (without\nactivating it), unless Transient Mark mode is enabled and the\nmark is already active.\n\nThis function is usually the wrong thing to use in a Lisp program.\nWhat you probably want instead is something like:\n  (goto-char (point-min))\n  (forward-line (1- N))\nIf at all possible, an even better solution is to use char counts\nrather than line counts.\"\n  (declare (interactive-only forward-line))\n  (interactive\n   (if (and current-prefix-arg (not (consp current-prefix-arg)))\n       (list (prefix-numeric-value current-prefix-arg))\n     ;; Look for a default, a number in the buffer at point.\n     (let* ((default\n\t      (save-excursion\n\t\t(skip-chars-backward \"0-9\")\n\t\t(if (looking-at \"[0-9]\")\n\t\t    (string-to-number\n\t\t     (buffer-substring-no-properties\n\t\t      (point)\n\t\t      (progn (skip-chars-forward \"0-9\")\n\t\t\t     (point)))))))\n\t    ;; Decide if we're switching buffers.\n\t    (buffer\n\t     (if (consp current-prefix-arg)\n\t\t (other-buffer (current-buffer) t)))\n\t    (buffer-prompt\n\t     (if buffer\n\t\t (concat \" in \" (buffer-name buffer))\n\t       \"\")))\n       ;; Read the argument, offering that number (if any) as default.\n       (list (read-number (format \"Goto line%s: \" buffer-prompt)\n                          (list default (line-number-at-pos)))\n\t     buffer))))\n  ;; Switch to the desired buffer, one way or another.\n  (if buffer\n      (let ((window (get-buffer-window buffer)))\n\t(if window (select-window window)\n\t  (switch-to-buffer-other-window buffer))))\n  ;; Leave mark at previous position\n  (or (region-active-p) (push-mark))\n  ;; Move to the specified line number in that buffer.\n  (save-restriction\n    (widen)\n    (goto-char (point-min))\n    (if (eq selective-display t)\n\t(re-search-forward \"[\\n\\C-m]\" nil 'end (1- line))\n      (forward-line (1- line)))))\n\n(defun count-words-region (start end &optional arg)\n  \"Count the number of words in the region.\nIf called interactively, print a message reporting the number of\nlines, words, and characters in the region (whether or not the\nregion is active); with prefix ARG, report for the entire buffer\nrather than the region.\n\nIf called from Lisp, return the number of words between positions\nSTART and END.\"\n  (interactive (if current-prefix-arg\n\t\t   (list nil nil current-prefix-arg)\n\t\t (list (region-beginning) (region-end) nil)))\n  (cond ((not (called-interactively-p 'any))\n\t (count-words start end))\n\t(arg\n\t (count-words--buffer-message))\n\t(t\n\t (count-words--message \"Region\" start end))))\n\n(defun count-words (start end)\n  \"Count words between START and END.\nIf called interactively, START and END are normally the start and\nend of the buffer; but if the region is active, START and END are\nthe start and end of the region.  Print a message reporting the\nnumber of lines, words, and chars.\n\nIf called from Lisp, return the number of words between START and\nEND, without printing any message.\"\n  (interactive (list nil nil))\n  (cond ((not (called-interactively-p 'any))\n\t (let ((words 0))\n\t   (save-excursion\n\t     (save-restriction\n\t       (narrow-to-region start end)\n\t       (goto-char (point-min))\n\t       (while (forward-word-strictly 1)\n\t\t (setq words (1+ words)))))\n\t   words))\n\t((use-region-p)\n\t (call-interactively 'count-words-region))\n\t(t\n\t (count-words--buffer-message))))\n\n(defun count-words--buffer-message ()\n  (count-words--message\n   (if (buffer-narrowed-p) \"Narrowed part of buffer\" \"Buffer\")\n   (point-min) (point-max)))\n\n(defun count-words--message (str start end)\n  (let ((lines (count-lines start end))\n\t(words (count-words start end))\n\t(chars (- end start)))\n    (message \"%s has %d line%s, %d word%s, and %d character%s.\"\n\t     str\n\t     lines (if (= lines 1) \"\" \"s\")\n\t     words (if (= words 1) \"\" \"s\")\n\t     chars (if (= chars 1) \"\" \"s\"))))\n\n(define-obsolete-function-alias 'count-lines-region 'count-words-region \"24.1\")\n\n(defun what-line ()\n  \"Print the current buffer line number and narrowed line number of point.\"\n  (interactive)\n  (let ((start (point-min))\n\t(n (line-number-at-pos)))\n    (if (= start 1)\n\t(message \"Line %d\" n)\n      (save-excursion\n\t(save-restriction\n\t  (widen)\n\t  (message \"line %d (narrowed line %d)\"\n\t\t   (+ n (line-number-at-pos start) -1) n))))))\n\n(defun count-lines (start end)\n  \"Return number of lines between START and END.\nThis is usually the number of newlines between them,\nbut can be one more if START is not equal to END\nand the greater of them is not at the start of a line.\"\n  (save-excursion\n    (save-restriction\n      (narrow-to-region start end)\n      (goto-char (point-min))\n      (if (eq selective-display t)\n\t  (save-match-data\n\t    (let ((done 0))\n                     (while (re-search-forward \"[\\n\\C-m]\" nil t 40)\n                       (setq done (+ 40 done)))\n                     (while (re-search-forward \"[\\n\\C-m]\" nil t 1)\n                       (setq done (+ 1 done)))\n                     (goto-char (point-max))\n                     (if (and (/= start end)\n\t\t       (not (bolp)))\n\t\t  (1+ done)\n\t\tdone)))\n\t(- (buffer-size) (forward-line (buffer-size)))))))\n\n(defun line-number-at-pos (&optional pos absolute)\n  \"Return buffer line number at position POS.\nIf POS is nil, use current buffer location.\n\nIf ABSOLUTE is nil, the default, counting starts\nat (point-min), so the value refers to the contents of the\naccessible portion of the (potentially narrowed) buffer.  If\nABSOLUTE is non-nil, ignore any narrowing and return the\nabsolute line number.\"\n  (save-restriction\n    (when absolute\n      (widen))\n    (let ((opoint (or pos (point))) start)\n      (save-excursion\n        (goto-char (point-min))\n        (setq start (point))\n        (goto-char opoint)\n        (forward-line 0)\n        (1+ (count-lines start (point)))))))\n\n(defun what-cursor-position (&optional detail)\n  \"Print info on cursor position (on screen and within buffer).\nAlso describe the character after point, and give its character code\nin octal, decimal and hex.\n\nFor a non-ASCII multibyte character, also give its encoding in the\nbuffer's selected coding system if the coding system encodes the\ncharacter safely.  If the character is encoded into one byte, that\ncode is shown in hex.  If the character is encoded into more than one\nbyte, just \\\"...\\\" is shown.\n\nIn addition, with prefix argument, show details about that character\nin *Help* buffer.  See also the command `describe-char'.\"\n  (interactive \"P\")\n  (let* ((char (following-char))\n\t (bidi-fixer\n\t  ;; If the character is one of LRE, LRO, RLE, RLO, it will\n\t  ;; start a directional embedding, which could completely\n\t  ;; disrupt the rest of the line (e.g., RLO will display the\n\t  ;; rest of the line right-to-left).  So we put an invisible\n\t  ;; PDF character after these characters, to end the\n\t  ;; embedding, which eliminates any effects on the rest of\n\t  ;; the line.  For RLE and RLO we also append an invisible\n\t  ;; LRM, to avoid reordering the following numerical\n\t  ;; characters.  For LRI/RLI/FSI we append a PDI.\n\t  (cond ((memq char '(?\\x202a ?\\x202d))\n\t\t (propertize (string ?\\x202c) 'invisible t))\n\t\t((memq char '(?\\x202b ?\\x202e))\n\t\t (propertize (string ?\\x202c ?\\x200e) 'invisible t))\n\t\t((memq char '(?\\x2066 ?\\x2067 ?\\x2068))\n\t\t (propertize (string ?\\x2069) 'invisible t))\n\t\t;; Strong right-to-left characters cause reordering of\n\t\t;; the following numerical characters which show the\n\t\t;; codepoint, so append LRM to countermand that.\n\t\t((memq (get-char-code-property char 'bidi-class) '(R AL))\n\t\t (propertize (string ?\\x200e) 'invisible t))\n\t\t(t\n\t\t \"\")))\n\t (beg (point-min))\n\t (end (point-max))\n         (pos (point))\n\t (total (buffer-size))\n\t (percent (round (* 100.0 (1- pos)) (max 1 total)))\n\t (hscroll (if (= (window-hscroll) 0)\n\t\t      \"\"\n\t\t    (format \" Hscroll=%d\" (window-hscroll))))\n\t (col (current-column)))\n    (if (= pos end)\n\t(if (or (/= beg 1) (/= end (1+ total)))\n\t    (message \"point=%d of %d (%d%%) <%d-%d> column=%d%s\"\n\t\t     pos total percent beg end col hscroll)\n\t  (message \"point=%d of %d (EOB) column=%d%s\"\n\t\t   pos total col hscroll))\n      (let ((coding buffer-file-coding-system)\n\t    encoded encoding-msg display-prop under-display)\n\t(if (or (not coding)\n\t\t(eq (coding-system-type coding) t))\n\t    (setq coding (default-value 'buffer-file-coding-system)))\n\t(if (eq (char-charset char) 'eight-bit)\n\t    (setq encoding-msg\n\t\t  (format \"(%d, #o%o, #x%x, raw-byte)\" char char char))\n\t  ;; Check if the character is displayed with some `display'\n\t  ;; text property.  In that case, set under-display to the\n\t  ;; buffer substring covered by that property.\n\t  (setq display-prop (get-char-property pos 'display))\n\t  (if display-prop\n\t      (let ((to (or (next-single-char-property-change pos 'display)\n\t\t\t    (point-max))))\n\t\t(if (< to (+ pos 4))\n\t\t    (setq under-display \"\")\n\t\t  (setq under-display \"...\"\n\t\t\tto (+ pos 4)))\n\t\t(setq under-display\n\t\t      (concat (buffer-substring-no-properties pos to)\n\t\t\t      under-display)))\n\t    (setq encoded (and (>= char 128) (encode-coding-char char coding))))\n\t  (setq encoding-msg\n\t\t(if display-prop\n\t\t    (if (not (stringp display-prop))\n\t\t\t(format \"(%d, #o%o, #x%x, part of display \\\"%s\\\")\"\n\t\t\t\tchar char char under-display)\n\t\t      (format \"(%d, #o%o, #x%x, part of display \\\"%s\\\"->\\\"%s\\\")\"\n\t\t\t      char char char under-display display-prop))\n\t\t  (if encoded\n\t\t      (format \"(%d, #o%o, #x%x, file %s)\"\n\t\t\t      char char char\n\t\t\t      (if (> (length encoded) 1)\n\t\t\t\t  \"...\"\n\t\t\t\t(encoded-string-description encoded coding)))\n\t\t    (format \"(%d, #o%o, #x%x)\" char char char)))))\n\t(if detail\n\t    ;; We show the detailed information about CHAR.\n\t    (describe-char (point)))\n\t(if (or (/= beg 1) (/= end (1+ total)))\n\t    (message \"Char: %s%s %s point=%d of %d (%d%%) <%d-%d> column=%d%s\"\n\t\t     (if (< char 256)\n\t\t\t (single-key-description char)\n\t\t       (buffer-substring-no-properties (point) (1+ (point))))\n\t\t     bidi-fixer\n\t\t     encoding-msg pos total percent beg end col hscroll)\n\t  (message \"Char: %s%s %s point=%d of %d (%d%%) column=%d%s\"\n\t\t   (if enable-multibyte-characters\n\t\t       (if (< char 128)\n\t\t\t   (single-key-description char)\n\t\t\t (buffer-substring-no-properties (point) (1+ (point))))\n\t\t     (single-key-description char))\n\t\t   bidi-fixer encoding-msg pos total percent col hscroll))))))\n\f\n;; Initialize read-expression-map.  It is defined at C level.\n(defvar read-expression-map\n  (let ((m (make-sparse-keymap)))\n    (define-key m \"\\M-\\t\" 'completion-at-point)\n    ;; Might as well bind TAB to completion, since inserting a TAB char is\n    ;; much too rarely useful.\n    (define-key m \"\\t\" 'completion-at-point)\n    (set-keymap-parent m minibuffer-local-map)\n    m))\n\n(defun read-minibuffer (prompt &optional initial-contents)\n  \"Return a Lisp object read using the minibuffer, unevaluated.\nPrompt with PROMPT.  If non-nil, optional second arg INITIAL-CONTENTS\nis a string to insert in the minibuffer before reading.\n\\(INITIAL-CONTENTS can also be a cons of a string and an integer.\nSuch arguments are used as in `read-from-minibuffer'.)\"\n  ;; Used for interactive spec `x'.\n  (read-from-minibuffer prompt initial-contents minibuffer-local-map\n                        t 'minibuffer-history))\n\n(defun eval-minibuffer (prompt &optional initial-contents)\n  \"Return value of Lisp expression read using the minibuffer.\nPrompt with PROMPT.  If non-nil, optional second arg INITIAL-CONTENTS\nis a string to insert in the minibuffer before reading.\n\\(INITIAL-CONTENTS can also be a cons of a string and an integer.\nSuch arguments are used as in `read-from-minibuffer'.)\"\n  ;; Used for interactive spec `X'.\n  (eval (read--expression prompt initial-contents)))\n\n(defvar minibuffer-completing-symbol nil\n  \"Non-nil means completing a Lisp symbol in the minibuffer.\")\n(make-obsolete-variable 'minibuffer-completing-symbol nil \"24.1\" 'get)\n\n(defvar minibuffer-default nil\n  \"The current default value or list of default values in the minibuffer.\nThe functions `read-from-minibuffer' and `completing-read' bind\nthis variable locally.\")\n\n(defcustom eval-expression-print-level 4\n  \"Value for `print-level' while printing value in `eval-expression'.\nA value of nil means no limit.\"\n  :group 'lisp\n  :type '(choice (const :tag \"No Limit\" nil) integer)\n  :version \"21.1\")\n\n(defcustom eval-expression-print-length 12\n  \"Value for `print-length' while printing value in `eval-expression'.\nA value of nil means no limit.\"\n  :group 'lisp\n  :type '(choice (const :tag \"No Limit\" nil) integer)\n  :version \"21.1\")\n\n(defcustom eval-expression-debug-on-error t\n  \"If non-nil set `debug-on-error' to t in `eval-expression'.\nIf nil, don't change the value of `debug-on-error'.\"\n  :group 'lisp\n  :type 'boolean\n  :version \"21.1\")\n\n(defcustom eval-expression-print-maximum-character 127\n  \"The largest integer that will be displayed as a character.\nThis affects printing by `eval-expression' (via\n`eval-expression-print-format').\"\n  :group 'lisp\n  :type 'integer\n  :version \"26.1\")\n\n(defun eval-expression-print-format (value)\n  \"If VALUE in an integer, return a specially formatted string.\nThis string will typically look like \\\" (#o1, #x1, ?\\\\C-a)\\\".\nIf VALUE is not an integer, nil is returned.\nThis function is used by commands like `eval-expression' that\ndisplay the result of expression evaluation.\"\n  (when (integerp value)\n    (let ((char-string\n           (and (characterp value)\n                (<= value eval-expression-print-maximum-character)\n                (char-displayable-p value)\n                (prin1-char value))))\n      (if char-string\n          (format \" (#o%o, #x%x, %s)\" value value char-string)\n        (format \" (#o%o, #x%x)\" value value)))))\n\n(defvar eval-expression-minibuffer-setup-hook nil\n  \"Hook run by `eval-expression' when entering the minibuffer.\")\n\n(defun read--expression (prompt &optional initial-contents)\n  (let ((minibuffer-completing-symbol t))\n    (minibuffer-with-setup-hook\n        (lambda ()\n          ;; FIXME: call emacs-lisp-mode?\n          (add-function :before-until (local 'eldoc-documentation-function)\n                        #'elisp-eldoc-documentation-function)\n          (eldoc-mode 1)\n          (add-hook 'completion-at-point-functions\n                    #'elisp-completion-at-point nil t)\n          (run-hooks 'eval-expression-minibuffer-setup-hook))\n      (read-from-minibuffer prompt initial-contents\n                            read-expression-map t\n                            'read-expression-history))))\n\n(defun eval-expression-get-print-arguments (prefix-argument)\n  \"Get arguments for commands that print an expression result.\nReturns a list (INSERT-VALUE NO-TRUNCATE CHAR-PRINT-LIMIT)\nbased on PREFIX-ARG.  This function determines the interpretation\nof the prefix argument for `eval-expression' and\n`eval-last-sexp'.\"\n  (let ((num (prefix-numeric-value prefix-argument)))\n    (list (not (memq prefix-argument '(- nil)))\n          (= num 0)\n          (cond ((not (memq prefix-argument '(0 -1 - nil))) nil)\n                ((= num -1) most-positive-fixnum)\n                (t eval-expression-print-maximum-character)))))\n\n;; We define this, rather than making `eval' interactive,\n;; for the sake of completion of names like eval-region, eval-buffer.\n(defun eval-expression (exp &optional insert-value no-truncate char-print-limit)\n  \"Evaluate EXP and print value in the echo area.\nWhen called interactively, read an Emacs Lisp expression and\nevaluate it.  Value is also consed on to front of the variable\n`values'.  Optional argument INSERT-VALUE non-nil (interactively,\nwith a non `-' prefix argument) means insert the result into the\ncurrent buffer instead of printing it in the echo area.\n\nNormally, this function truncates long output according to the\nvalue of the variables `eval-expression-print-length' and\n`eval-expression-print-level'.  When NO-TRUNCATE is\nnon-nil (interactively, with a prefix argument of zero), however,\nthere is no such truncation.\n\nIf the resulting value is an integer, and CHAR-PRINT-LIMIT is\nnon-nil (interactively, unless given a positive prefix argument)\nit will be printed in several additional formats (octal,\nhexadecimal, and character).  The character format is only used\nif the value is below CHAR-PRINT-LIMIT (interactively, if the\nprefix argument is -1 or the value is below\n`eval-expression-print-maximum-character').\n\nRuns the hook `eval-expression-minibuffer-setup-hook' on entering the\nminibuffer.\n\nIf `eval-expression-debug-on-error' is non-nil, which is the default,\nthis command arranges for all errors to enter the debugger.\"\n  (interactive\n   (cons (read--expression \"Eval: \")\n         (eval-expression-get-print-arguments current-prefix-arg)))\n\n  (if (null eval-expression-debug-on-error)\n      (push (eval exp lexical-binding) values)\n    (let ((old-value (make-symbol \"t\")) new-value)\n      ;; Bind debug-on-error to something unique so that we can\n      ;; detect when evalled code changes it.\n      (let ((debug-on-error old-value))\n\t(push (eval (macroexpand-all exp) lexical-binding) values)\n\t(setq new-value debug-on-error))\n      ;; If evalled code has changed the value of debug-on-error,\n      ;; propagate that change to the global binding.\n      (unless (eq old-value new-value)\n\t(setq debug-on-error new-value))))\n\n  (let ((print-length (unless no-truncate eval-expression-print-length))\n        (print-level  (unless no-truncate eval-expression-print-level))\n        (eval-expression-print-maximum-character char-print-limit)\n        (deactivate-mark))\n    (let ((out (if insert-value (current-buffer) t)))\n      (prog1\n          (prin1 (car values) out)\n        (let ((str (and char-print-limit\n                        (eval-expression-print-format (car values)))))\n          (when str (princ str out)))))))\n\n(defun edit-and-eval-command (prompt command)\n  \"Prompting with PROMPT, let user edit COMMAND and eval result.\nCOMMAND is a Lisp expression.  Let user edit that expression in\nthe minibuffer, then read and evaluate the result.\"\n  (let ((command\n\t (let ((print-level nil)\n\t       (minibuffer-history-sexp-flag (1+ (minibuffer-depth))))\n\t   (unwind-protect\n\t       (read-from-minibuffer prompt\n\t\t\t\t     (prin1-to-string command)\n\t\t\t\t     read-expression-map t\n\t\t\t\t     'command-history)\n\t     ;; If command was added to command-history as a string,\n\t     ;; get rid of that.  We want only evaluable expressions there.\n\t     (if (stringp (car command-history))\n\t\t (setq command-history (cdr command-history)))))))\n\n    ;; If command to be redone does not match front of history,\n    ;; add it to the history.\n    (or (equal command (car command-history))\n\t(setq command-history (cons command command-history)))\n    (eval command)))\n\n(defun repeat-complex-command (arg)\n  \"Edit and re-evaluate last complex command, or ARGth from last.\nA complex command is one which used the minibuffer.\nThe command is placed in the minibuffer as a Lisp form for editing.\nThe result is executed, repeating the command as changed.\nIf the command has been changed or is not the most recent previous\ncommand it is added to the front of the command history.\nYou can use the minibuffer history commands \\\n\\\\<minibuffer-local-map>\\\\[next-history-element] and \\\\[previous-history-element]\nto get different commands to edit and resubmit.\"\n  (interactive \"p\")\n  (let ((elt (nth (1- arg) command-history))\n\tnewcmd)\n    (if elt\n\t(progn\n\t  (setq newcmd\n\t\t(let ((print-level nil)\n\t\t      (minibuffer-history-position arg)\n\t\t      (minibuffer-history-sexp-flag (1+ (minibuffer-depth))))\n\t\t  (unwind-protect\n\t\t      (read-from-minibuffer\n\t\t       \"Redo: \" (prin1-to-string elt) read-expression-map t\n\t\t       (cons 'command-history arg))\n\n\t\t    ;; If command was added to command-history as a\n\t\t    ;; string, get rid of that.  We want only\n\t\t    ;; evaluable expressions there.\n\t\t    (if (stringp (car command-history))\n\t\t\t(setq command-history (cdr command-history))))))\n\n\t  ;; If command to be redone does not match front of history,\n\t  ;; add it to the history.\n\t  (or (equal newcmd (car command-history))\n\t      (setq command-history (cons newcmd command-history)))\n          (apply #'funcall-interactively\n\t\t (car newcmd)\n\t\t (mapcar (lambda (e) (eval e t)) (cdr newcmd))))\n      (if command-history\n\t  (error \"Argument %d is beyond length of command history\" arg)\n\t(error \"There are no previous complex commands to repeat\")))))\n\n\n(defvar extended-command-history nil)\n(defvar execute-extended-command--last-typed nil)\n\n(defun read-extended-command ()\n  \"Read command name to invoke in `execute-extended-command'.\"\n  (minibuffer-with-setup-hook\n      (lambda ()\n        (add-hook 'post-self-insert-hook\n                  (lambda ()\n                    (setq execute-extended-command--last-typed\n                              (minibuffer-contents)))\n                  nil 'local)\n\t(set (make-local-variable 'minibuffer-default-add-function)\n\t     (lambda ()\n\t       ;; Get a command name at point in the original buffer\n\t       ;; to propose it after M-n.\n\t       (with-current-buffer (window-buffer (minibuffer-selected-window))\n\t\t (and (commandp (function-called-at-point))\n\t\t      (format \"%S\" (function-called-at-point)))))))\n    ;; Read a string, completing from and restricting to the set of\n    ;; all defined commands.  Don't provide any initial input.\n    ;; Save the command read on the extended-command history list.\n    (completing-read\n     (concat (cond\n\t      ((eq current-prefix-arg '-) \"- \")\n\t      ((and (consp current-prefix-arg)\n\t\t    (eq (car current-prefix-arg) 4)) \"C-u \")\n\t      ((and (consp current-prefix-arg)\n\t\t    (integerp (car current-prefix-arg)))\n\t       (format \"%d \" (car current-prefix-arg)))\n\t      ((integerp current-prefix-arg)\n\t       (format \"%d \" current-prefix-arg)))\n\t     ;; This isn't strictly correct if `execute-extended-command'\n\t     ;; is bound to anything else (e.g. [menu]).\n\t     ;; It could use (key-description (this-single-command-keys)),\n\t     ;; but actually a prompt other than \"M-x\" would be confusing,\n\t     ;; because \"M-x\" is a well-known prompt to read a command\n\t     ;; and it serves as a shorthand for \"Extended command: \".\n\t     \"M-x \")\n     (lambda (string pred action)\n       (let ((pred\n              (if (memq action '(nil t))\n                  ;; Exclude obsolete commands from completions.\n                  (lambda (sym)\n                    (and (funcall pred sym)\n                         (or (equal string (symbol-name sym))\n                             (not (get sym 'byte-obsolete-info)))))\n                pred)))\n         (complete-with-action action obarray string pred)))\n     #'commandp t nil 'extended-command-history)))\n\n(defcustom suggest-key-bindings t\n  \"Non-nil means show the equivalent key-binding when M-x command has one.\nThe value can be a length of time to show the message for.\nIf the value is non-nil and not a number, we wait 2 seconds.\"\n  :group 'keyboard\n  :type '(choice (const :tag \"off\" nil)\n                 (integer :tag \"time\" 2)\n                 (other :tag \"on\")))\n\n(defcustom extended-command-suggest-shorter t\n  \"If non-nil, show a shorter M-x invocation when there is one.\"\n  :group 'keyboard\n  :type 'boolean\n  :version \"26.1\")\n\n(defun execute-extended-command--shorter-1 (name length)\n  (cond\n   ((zerop length) (list \"\"))\n   ((equal name \"\") nil)\n   (t\n    (nconc (mapcar (lambda (s) (concat (substring name 0 1) s))\n                   (execute-extended-command--shorter-1\n                    (substring name 1) (1- length)))\n           (when (string-match \"\\\\`\\\\(-\\\\)?[^-]*\" name)\n             (execute-extended-command--shorter-1\n              (substring name (match-end 0)) length))))))\n\n(defun execute-extended-command--shorter (name typed)\n  (let ((candidates '())\n        (max (length typed))\n        (len 1)\n        binding)\n    (while (and (not binding)\n                (progn\n                  (unless candidates\n                    (setq len (1+ len))\n                    (setq candidates (execute-extended-command--shorter-1\n                                      name len)))\n                  ;; Don't show the help message if the binding isn't\n                  ;; significantly shorter than the M-x command the user typed.\n                  (< len (- max 5))))\n      (input-pending-p)    ;Dummy call to trigger input-processing, bug#23002.\n      (let ((candidate (pop candidates)))\n        (when (equal name\n                       (car-safe (completion-try-completion\n                                  candidate obarray 'commandp len)))\n          (setq binding candidate))))\n    binding))\n\n(defun execute-extended-command (prefixarg &optional command-name typed)\n  ;; Based on Fexecute_extended_command in keyboard.c of Emacs.\n  ;; Aaron S. Hawley <aaron.s.hawley(at)gmail.com> 2009-08-24\n  \"Read a command name, then read the arguments and call the command.\nTo pass a prefix argument to the command you are\ninvoking, give a prefix argument to `execute-extended-command'.\"\n  (declare (interactive-only command-execute))\n  ;; FIXME: Remember the actual text typed by the user before completion,\n  ;; so that we don't later on suggest the same shortening.\n  (interactive\n   (let ((execute-extended-command--last-typed nil))\n     (list current-prefix-arg\n           (read-extended-command)\n           execute-extended-command--last-typed)))\n  ;; Emacs<24 calling-convention was with a single `prefixarg' argument.\n  (unless command-name\n    (let ((current-prefix-arg prefixarg) ; for prompt\n          (execute-extended-command--last-typed nil))\n      (setq command-name (read-extended-command))\n      (setq typed execute-extended-command--last-typed)))\n  (let* ((function (and (stringp command-name) (intern-soft command-name)))\n         (binding (and suggest-key-bindings\n\t\t       (not executing-kbd-macro)\n\t\t       (where-is-internal function overriding-local-map t))))\n    (unless (commandp function)\n      (error \"`%s' is not a valid command name\" command-name))\n    ;; Some features, such as novice.el, rely on this-command-keys\n    ;; including M-x COMMAND-NAME RET.\n    (set--this-command-keys (concat \"\\M-x\" (symbol-name function) \"\\r\"))\n    (setq this-command function)\n    ;; Normally `real-this-command' should never be changed, but here we really\n    ;; want to pretend that M-x <cmd> RET is nothing more than a \"key\n    ;; binding\" for <cmd>, so the command the user really wanted to run is\n    ;; `function' and not `execute-extended-command'.  The difference is\n    ;; visible in cases such as M-x <cmd> RET and then C-x z (bug#11506).\n    (setq real-this-command function)\n    (let ((prefix-arg prefixarg))\n      (command-execute function 'record))\n    ;; If enabled, show which key runs this command.\n    ;; But first wait, and skip the message if there is input.\n    (let* ((waited\n            ;; If this command displayed something in the echo area;\n            ;; wait a few seconds, then display our suggestion message.\n            ;; FIXME: Wait *after* running post-command-hook!\n            ;; FIXME: Don't wait if execute-extended-command--shorter won't\n            ;; find a better answer anyway!\n            (when suggest-key-bindings\n              (sit-for (cond\n                        ((zerop (length (current-message))) 0)\n                        ((numberp suggest-key-bindings) suggest-key-bindings)\n                        (t 2))))))\n      (when (and waited (not (consp unread-command-events)))\n        (unless (or (not extended-command-suggest-shorter)\n                    binding executing-kbd-macro (not (symbolp function))\n                    (<= (length (symbol-name function)) 2))\n          ;; There's no binding for CMD.  Let's try and find the shortest\n          ;; string to use in M-x.\n          ;; FIXME: Can be slow.  Cache it maybe?\n          (while-no-input\n            (setq binding (execute-extended-command--shorter\n                           (symbol-name function) typed))))\n        (when binding\n          (with-temp-message\n              (format-message \"You can run the command `%s' with %s\"\n                              function\n                              (if (stringp binding)\n                                  (concat \"M-x \" binding \" RET\")\n                                (key-description binding)))\n            (sit-for (if (numberp suggest-key-bindings)\n                         suggest-key-bindings\n                       2))))))))\n\n(defun command-execute (cmd &optional record-flag keys special)\n  ;; BEWARE: Called directly from the C code.\n  \"Execute CMD as an editor command.\nCMD must be a symbol that satisfies the `commandp' predicate.\nOptional second arg RECORD-FLAG non-nil\nmeans unconditionally put this command in the variable `command-history'.\nOtherwise, that is done only if an arg is read using the minibuffer.\nThe argument KEYS specifies the value to use instead of (this-command-keys)\nwhen reading the arguments; if it is nil, (this-command-keys) is used.\nThe argument SPECIAL, if non-nil, means that this command is executing\na special event, so ignore the prefix argument and don't clear it.\"\n  (setq debug-on-next-call nil)\n  (let ((prefixarg (unless special\n                     ;; FIXME: This should probably be done around\n                     ;; pre-command-hook rather than here!\n                     (prog1 prefix-arg\n                       (setq current-prefix-arg prefix-arg)\n                       (setq prefix-arg nil)\n                       (when current-prefix-arg\n                         (prefix-command-update))))))\n    (if (and (symbolp cmd)\n             (get cmd 'disabled)\n             disabled-command-function)\n        ;; FIXME: Weird calling convention!\n        (run-hooks 'disabled-command-function)\n      (let ((final cmd))\n        (while\n            (progn\n              (setq final (indirect-function final))\n              (if (autoloadp final)\n                  (setq final (autoload-do-load final cmd)))))\n        (cond\n         ((arrayp final)\n          ;; If requested, place the macro in the command history.  For\n          ;; other sorts of commands, call-interactively takes care of this.\n          (when record-flag\n            (push `(execute-kbd-macro ,final ,prefixarg) command-history)\n            ;; Don't keep command history around forever.\n            (when (and (numberp history-length) (> history-length 0))\n              (let ((cell (nthcdr history-length command-history)))\n                (if (consp cell) (setcdr cell nil)))))\n          (execute-kbd-macro final prefixarg))\n         (t\n          ;; Pass `cmd' rather than `final', for the backtrace's sake.\n          (prog1 (call-interactively cmd record-flag keys)\n            (when (and (symbolp cmd)\n                       (get cmd 'byte-obsolete-info)\n                       (not (get cmd 'command-execute-obsolete-warned)))\n              (put cmd 'command-execute-obsolete-warned t)\n              (message \"%s\" (macroexp--obsolete-warning\n                             cmd (get cmd 'byte-obsolete-info) \"command\"))))))))))\n\f\n(defvar minibuffer-history nil\n  \"Default minibuffer history list.\nThis is used for all minibuffer input\nexcept when an alternate history list is specified.\n\nMaximum length of the history list is determined by the value\nof `history-length', which see.\")\n(defvar minibuffer-history-sexp-flag nil\n  \"Control whether history list elements are expressions or strings.\nIf the value of this variable equals current minibuffer depth,\nthey are expressions; otherwise they are strings.\n\\(That convention is designed to do the right thing for\nrecursive uses of the minibuffer.)\")\n(setq minibuffer-history-variable 'minibuffer-history)\n(setq minibuffer-history-position nil)  ;; Defvar is in C code.\n(defvar minibuffer-history-search-history nil)\n\n(defvar minibuffer-text-before-history nil\n  \"Text that was in this minibuffer before any history commands.\nThis is nil if there have not yet been any history commands\nin this use of the minibuffer.\")\n\n(add-hook 'minibuffer-setup-hook 'minibuffer-history-initialize)\n\n(defun minibuffer-history-initialize ()\n  (setq minibuffer-text-before-history nil))\n\n(defun minibuffer-avoid-prompt (_new _old)\n  \"A point-motion hook for the minibuffer, that moves point out of the prompt.\"\n  (declare (obsolete cursor-intangible-mode \"25.1\"))\n  (constrain-to-field nil (point-max)))\n\n(defcustom minibuffer-history-case-insensitive-variables nil\n  \"Minibuffer history variables for which matching should ignore case.\nIf a history variable is a member of this list, then the\n\\\\[previous-matching-history-element] and \\\\[next-matching-history-element]\\\n commands ignore case when searching it, regardless of `case-fold-search'.\"\n  :type '(repeat variable)\n  :group 'minibuffer)\n\n(defun previous-matching-history-element (regexp n)\n  \"Find the previous history element that matches REGEXP.\n\\(Previous history elements refer to earlier actions.)\nWith prefix argument N, search for Nth previous match.\nIf N is negative, find the next or Nth next match.\nNormally, history elements are matched case-insensitively if\n`case-fold-search' is non-nil, but an uppercase letter in REGEXP\nmakes the search case-sensitive.\nSee also `minibuffer-history-case-insensitive-variables'.\"\n  (interactive\n   (let* ((enable-recursive-minibuffers t)\n\t  (regexp (read-from-minibuffer \"Previous element matching (regexp): \"\n\t\t\t\t\tnil\n\t\t\t\t\tminibuffer-local-map\n\t\t\t\t\tnil\n\t\t\t\t\t'minibuffer-history-search-history\n\t\t\t\t\t(car minibuffer-history-search-history))))\n     ;; Use the last regexp specified, by default, if input is empty.\n     (list (if (string= regexp \"\")\n\t       (if minibuffer-history-search-history\n\t\t   (car minibuffer-history-search-history)\n\t\t (user-error \"No previous history search regexp\"))\n\t     regexp)\n\t   (prefix-numeric-value current-prefix-arg))))\n  (unless (zerop n)\n    (if (and (zerop minibuffer-history-position)\n\t     (null minibuffer-text-before-history))\n\t(setq minibuffer-text-before-history\n\t      (minibuffer-contents-no-properties)))\n    (let ((history (symbol-value minibuffer-history-variable))\n\t  (case-fold-search\n\t   (if (isearch-no-upper-case-p regexp t) ; assume isearch.el is dumped\n\t       ;; On some systems, ignore case for file names.\n\t       (if (memq minibuffer-history-variable\n\t\t\t minibuffer-history-case-insensitive-variables)\n\t\t   t\n\t\t ;; Respect the user's setting for case-fold-search:\n\t\t case-fold-search)\n\t     nil))\n\t  prevpos\n\t  match-string\n\t  match-offset\n\t  (pos minibuffer-history-position))\n      (while (/= n 0)\n\t(setq prevpos pos)\n\t(setq pos (min (max 1 (+ pos (if (< n 0) -1 1))) (length history)))\n\t(when (= pos prevpos)\n\t  (user-error (if (= pos 1)\n                          \"No later matching history item\"\n                        \"No earlier matching history item\")))\n\t(setq match-string\n\t      (if (eq minibuffer-history-sexp-flag (minibuffer-depth))\n\t\t  (let ((print-level nil))\n\t\t    (prin1-to-string (nth (1- pos) history)))\n\t\t(nth (1- pos) history)))\n\t(setq match-offset\n\t      (if (< n 0)\n\t\t  (and (string-match regexp match-string)\n\t\t       (match-end 0))\n\t\t(and (string-match (concat \".*\\\\(\" regexp \"\\\\)\") match-string)\n\t\t     (match-beginning 1))))\n\t(when match-offset\n\t  (setq n (+ n (if (< n 0) 1 -1)))))\n      (setq minibuffer-history-position pos)\n      (goto-char (point-max))\n      (delete-minibuffer-contents)\n      (insert match-string)\n      (goto-char (+ (minibuffer-prompt-end) match-offset))))\n  (if (memq (car (car command-history)) '(previous-matching-history-element\n\t\t\t\t\t  next-matching-history-element))\n      (setq command-history (cdr command-history))))\n\n(defun next-matching-history-element (regexp n)\n  \"Find the next history element that matches REGEXP.\n\\(The next history element refers to a more recent action.)\nWith prefix argument N, search for Nth next match.\nIf N is negative, find the previous or Nth previous match.\nNormally, history elements are matched case-insensitively if\n`case-fold-search' is non-nil, but an uppercase letter in REGEXP\nmakes the search case-sensitive.\"\n  (interactive\n   (let* ((enable-recursive-minibuffers t)\n\t  (regexp (read-from-minibuffer \"Next element matching (regexp): \"\n\t\t\t\t\tnil\n\t\t\t\t\tminibuffer-local-map\n\t\t\t\t\tnil\n\t\t\t\t\t'minibuffer-history-search-history\n \t\t\t\t\t(car minibuffer-history-search-history))))\n     ;; Use the last regexp specified, by default, if input is empty.\n     (list (if (string= regexp \"\")\n\t       (if minibuffer-history-search-history\n\t\t   (car minibuffer-history-search-history)\n\t\t (user-error \"No previous history search regexp\"))\n\t     regexp)\n\t   (prefix-numeric-value current-prefix-arg))))\n  (previous-matching-history-element regexp (- n)))\n\n(defvar minibuffer-temporary-goal-position nil)\n\n(defvar minibuffer-default-add-function 'minibuffer-default-add-completions\n  \"Function run by `goto-history-element' before consuming default values.\nThis is useful to dynamically add more elements to the list of default values\nwhen `goto-history-element' reaches the end of this list.\nBefore calling this function `goto-history-element' sets the variable\n`minibuffer-default-add-done' to t, so it will call this function only\nonce.  In special cases, when this function needs to be called more\nthan once, it can set `minibuffer-default-add-done' to nil explicitly,\noverriding the setting of this variable to t in `goto-history-element'.\")\n\n(defvar minibuffer-default-add-done nil\n  \"When nil, add more elements to the end of the list of default values.\nThe value nil causes `goto-history-element' to add more elements to\nthe list of defaults when it reaches the end of this list.  It does\nthis by calling a function defined by `minibuffer-default-add-function'.\")\n\n(make-variable-buffer-local 'minibuffer-default-add-done)\n\n(defun minibuffer-default-add-completions ()\n  \"Return a list of all completions without the default value.\nThis function is used to add all elements of the completion table to\nthe end of the list of defaults just after the default value.\"\n  (let ((def minibuffer-default)\n\t(all (all-completions \"\"\n\t\t\t      minibuffer-completion-table\n\t\t\t      minibuffer-completion-predicate)))\n    (if (listp def)\n\t(append def all)\n      (cons def (delete def all)))))\n\n(defun goto-history-element (nabs)\n  \"Puts element of the minibuffer history in the minibuffer.\nThe argument NABS specifies the absolute history position.\"\n  (interactive \"p\")\n  (when (and (not minibuffer-default-add-done)\n\t     (functionp minibuffer-default-add-function)\n\t     (< nabs (- (if (listp minibuffer-default)\n\t\t\t    (length minibuffer-default)\n\t\t\t  1))))\n    (setq minibuffer-default-add-done t\n\t  minibuffer-default (funcall minibuffer-default-add-function)))\n  (let ((minimum (if minibuffer-default\n\t\t     (- (if (listp minibuffer-default)\n\t\t\t    (length minibuffer-default)\n\t\t\t  1))\n\t\t   0))\n\telt minibuffer-returned-to-present)\n    (if (and (zerop minibuffer-history-position)\n\t     (null minibuffer-text-before-history))\n\t(setq minibuffer-text-before-history\n\t      (minibuffer-contents-no-properties)))\n    (if (< nabs minimum)\n\t(user-error (if minibuffer-default\n                        \"End of defaults; no next item\"\n                      \"End of history; no default available\")))\n    (if (> nabs (if (listp (symbol-value minibuffer-history-variable))\n                    (length (symbol-value minibuffer-history-variable))\n                  0))\n\t(user-error \"Beginning of history; no preceding item\"))\n    (unless (memq last-command '(next-history-element\n\t\t\t\t previous-history-element))\n      (let ((prompt-end (minibuffer-prompt-end)))\n\t(set (make-local-variable 'minibuffer-temporary-goal-position)\n\t     (cond ((<= (point) prompt-end) prompt-end)\n\t\t   ((eobp) nil)\n\t\t   (t (point))))))\n    (goto-char (point-max))\n    (delete-minibuffer-contents)\n    (setq minibuffer-history-position nabs)\n    (cond ((< nabs 0)\n\t   (setq elt (if (listp minibuffer-default)\n\t\t\t (nth (1- (abs nabs)) minibuffer-default)\n\t\t       minibuffer-default)))\n\t  ((= nabs 0)\n\t   (setq elt (or minibuffer-text-before-history \"\"))\n\t   (setq minibuffer-returned-to-present t)\n\t   (setq minibuffer-text-before-history nil))\n\t  (t (setq elt (nth (1- minibuffer-history-position)\n\t\t\t    (symbol-value minibuffer-history-variable)))))\n    (insert\n     (if (and (eq minibuffer-history-sexp-flag (minibuffer-depth))\n\t      (not minibuffer-returned-to-present))\n\t (let ((print-level nil))\n\t   (prin1-to-string elt))\n       elt))\n    (goto-char (or minibuffer-temporary-goal-position (point-max)))))\n\n(defun next-history-element (n)\n  \"Puts next element of the minibuffer history in the minibuffer.\nWith argument N, it uses the Nth following element.\"\n  (interactive \"p\")\n  (or (zerop n)\n      (goto-history-element (- minibuffer-history-position n))))\n\n(defun previous-history-element (n)\n  \"Puts previous element of the minibuffer history in the minibuffer.\nWith argument N, it uses the Nth previous element.\"\n  (interactive \"p\")\n  (or (zerop n)\n      (goto-history-element (+ minibuffer-history-position n))))\n\n(defun next-line-or-history-element (&optional arg)\n  \"Move cursor vertically down ARG lines, or to the next history element.\nWhen point moves over the bottom line of multi-line minibuffer, puts ARGth\nnext element of the minibuffer history in the minibuffer.\"\n  (interactive \"^p\")\n  (or arg (setq arg 1))\n  (let* ((old-point (point))\n         ;; Don't add newlines if they have the mode enabled globally.\n         (next-line-add-newlines nil)\n\t ;; Remember the original goal column of possibly multi-line input\n\t ;; excluding the length of the prompt on the first line.\n\t (prompt-end (minibuffer-prompt-end))\n\t (old-column (unless (and (eolp) (> (point) prompt-end))\n\t\t       (if (= (line-number-at-pos) 1)\n\t\t\t   (max (- (current-column) (1- prompt-end)) 0)\n\t\t\t (current-column)))))\n    (condition-case nil\n\t(with-no-warnings\n\t  (next-line arg))\n      (end-of-buffer\n       ;; Restore old position since `line-move-visual' moves point to\n       ;; the end of the line when it fails to go to the next line.\n       (goto-char old-point)\n       (next-history-element arg)\n       ;; Reset `temporary-goal-column' because a correct value is not\n       ;; calculated when `next-line' above fails by bumping against\n       ;; the bottom of the minibuffer (bug#22544).\n       (setq temporary-goal-column 0)\n       ;; Restore the original goal column on the last line\n       ;; of possibly multi-line input.\n       (goto-char (point-max))\n       (when old-column\n\t (if (= (line-number-at-pos) 1)\n\t     (move-to-column (+ old-column (1- (minibuffer-prompt-end))))\n\t   (move-to-column old-column)))))))\n\n(defun previous-line-or-history-element (&optional arg)\n  \"Move cursor vertically up ARG lines, or to the previous history element.\nWhen point moves over the top line of multi-line minibuffer, puts ARGth\nprevious element of the minibuffer history in the minibuffer.\"\n  (interactive \"^p\")\n  (or arg (setq arg 1))\n  (let* ((old-point (point))\n\t ;; Remember the original goal column of possibly multi-line input\n\t ;; excluding the length of the prompt on the first line.\n\t (prompt-end (minibuffer-prompt-end))\n\t (old-column (unless (and (eolp) (> (point) prompt-end))\n\t\t       (if (= (line-number-at-pos) 1)\n\t\t\t   (max (- (current-column) (1- prompt-end)) 0)\n\t\t\t (current-column)))))\n    (condition-case nil\n\t(with-no-warnings\n\t  (previous-line arg))\n      (beginning-of-buffer\n       ;; Restore old position since `line-move-visual' moves point to\n       ;; the beginning of the line when it fails to go to the previous line.\n       (goto-char old-point)\n       (previous-history-element arg)\n       ;; Reset `temporary-goal-column' because a correct value is not\n       ;; calculated when `previous-line' above fails by bumping against\n       ;; the top of the minibuffer (bug#22544).\n       (setq temporary-goal-column 0)\n       ;; Restore the original goal column on the first line\n       ;; of possibly multi-line input.\n       (goto-char (minibuffer-prompt-end))\n       (if old-column\n\t   (if (= (line-number-at-pos) 1)\n\t       (move-to-column (+ old-column (1- (minibuffer-prompt-end))))\n\t     (move-to-column old-column))\n\t ;; Put the cursor at the end of the visual line instead of the\n\t ;; logical line, so the next `previous-line-or-history-element'\n\t ;; would move to the previous history element, not to a possible upper\n\t ;; visual line from the end of logical line in `line-move-visual' mode.\n\t (end-of-visual-line)\n\t ;; Since `end-of-visual-line' puts the cursor at the beginning\n\t ;; of the next visual line, move it one char back to the end\n\t ;; of the first visual line (bug#22544).\n\t (unless (eolp) (backward-char 1)))))))\n\n(defun next-complete-history-element (n)\n  \"Get next history element which completes the minibuffer before the point.\nThe contents of the minibuffer after the point are deleted, and replaced\nby the new completion.\"\n  (interactive \"p\")\n  (let ((point-at-start (point)))\n    (next-matching-history-element\n     (concat\n      \"^\" (regexp-quote (buffer-substring (minibuffer-prompt-end) (point))))\n     n)\n    ;; next-matching-history-element always puts us at (point-min).\n    ;; Move to the position we were at before changing the buffer contents.\n    ;; This is still sensible, because the text before point has not changed.\n    (goto-char point-at-start)))\n\n(defun previous-complete-history-element (n)\n  \"\\\nGet previous history element which completes the minibuffer before the point.\nThe contents of the minibuffer after the point are deleted, and replaced\nby the new completion.\"\n  (interactive \"p\")\n  (next-complete-history-element (- n)))\n\n;; For compatibility with the old subr of the same name.\n(defun minibuffer-prompt-width ()\n  \"Return the display width of the minibuffer prompt.\nReturn 0 if current buffer is not a minibuffer.\"\n  ;; Return the width of everything before the field at the end of\n  ;; the buffer; this should be 0 for normal buffers.\n  (1- (minibuffer-prompt-end)))\n\f\n;; isearch minibuffer history\n(add-hook 'minibuffer-setup-hook 'minibuffer-history-isearch-setup)\n\n(defvar minibuffer-history-isearch-message-overlay)\n(make-variable-buffer-local 'minibuffer-history-isearch-message-overlay)\n\n(defun minibuffer-history-isearch-setup ()\n  \"Set up a minibuffer for using isearch to search the minibuffer history.\nIntended to be added to `minibuffer-setup-hook'.\"\n  (set (make-local-variable 'isearch-search-fun-function)\n       'minibuffer-history-isearch-search)\n  (set (make-local-variable 'isearch-message-function)\n       'minibuffer-history-isearch-message)\n  (set (make-local-variable 'isearch-wrap-function)\n       'minibuffer-history-isearch-wrap)\n  (set (make-local-variable 'isearch-push-state-function)\n       'minibuffer-history-isearch-push-state)\n  (add-hook 'isearch-mode-end-hook 'minibuffer-history-isearch-end nil t))\n\n(defun minibuffer-history-isearch-end ()\n  \"Clean up the minibuffer after terminating isearch in the minibuffer.\"\n  (if minibuffer-history-isearch-message-overlay\n      (delete-overlay minibuffer-history-isearch-message-overlay)))\n\n(defun minibuffer-history-isearch-search ()\n  \"Return the proper search function, for isearch in minibuffer history.\"\n  (lambda (string bound noerror)\n    (let ((search-fun\n\t   ;; Use standard functions to search within minibuffer text\n\t   (isearch-search-fun-default))\n\t  found)\n      ;; Avoid lazy-highlighting matches in the minibuffer prompt when\n      ;; searching forward.  Lazy-highlight calls this lambda with the\n      ;; bound arg, so skip the minibuffer prompt.\n      (if (and bound isearch-forward (< (point) (minibuffer-prompt-end)))\n\t  (goto-char (minibuffer-prompt-end)))\n      (or\n       ;; 1. First try searching in the initial minibuffer text\n       (funcall search-fun string\n\t\t(if isearch-forward bound (minibuffer-prompt-end))\n\t\tnoerror)\n       ;; 2. If the above search fails, start putting next/prev history\n       ;; elements in the minibuffer successively, and search the string\n       ;; in them.  Do this only when bound is nil (i.e. not while\n       ;; lazy-highlighting search strings in the current minibuffer text).\n       (unless bound\n\t (condition-case nil\n\t     (progn\n\t       (while (not found)\n\t\t (cond (isearch-forward\n\t\t\t(next-history-element 1)\n\t\t\t(goto-char (minibuffer-prompt-end)))\n\t\t       (t\n\t\t\t(previous-history-element 1)\n\t\t\t(goto-char (point-max))))\n\t\t (setq isearch-barrier (point) isearch-opoint (point))\n\t\t ;; After putting the next/prev history element, search\n\t\t ;; the string in them again, until next-history-element\n\t\t ;; or previous-history-element raises an error at the\n\t\t ;; beginning/end of history.\n\t\t (setq found (funcall search-fun string\n\t\t\t\t      (unless isearch-forward\n\t\t\t\t\t;; For backward search, don't search\n\t\t\t\t\t;; in the minibuffer prompt\n\t\t\t\t\t(minibuffer-prompt-end))\n\t\t\t\t      noerror)))\n\t       ;; Return point of the new search result\n\t       (point))\n\t   ;; Return nil when next(prev)-history-element fails\n\t   (error nil)))))))\n\n(defun minibuffer-history-isearch-message (&optional c-q-hack ellipsis)\n  \"Display the minibuffer history search prompt.\nIf there are no search errors, this function displays an overlay with\nthe isearch prompt which replaces the original minibuffer prompt.\nOtherwise, it displays the standard isearch message returned from\nthe function `isearch-message'.\"\n  (if (not (and (minibufferp) isearch-success (not isearch-error)))\n      ;; Use standard function `isearch-message' when not in the minibuffer,\n      ;; or search fails, or has an error (like incomplete regexp).\n      ;; This function overwrites minibuffer text with isearch message,\n      ;; so it's possible to see what is wrong in the search string.\n      (isearch-message c-q-hack ellipsis)\n    ;; Otherwise, put the overlay with the standard isearch prompt over\n    ;; the initial minibuffer prompt.\n    (if (overlayp minibuffer-history-isearch-message-overlay)\n\t(move-overlay minibuffer-history-isearch-message-overlay\n\t\t      (point-min) (minibuffer-prompt-end))\n      (setq minibuffer-history-isearch-message-overlay\n\t    (make-overlay (point-min) (minibuffer-prompt-end)))\n      (overlay-put minibuffer-history-isearch-message-overlay 'evaporate t))\n    (overlay-put minibuffer-history-isearch-message-overlay\n\t\t 'display (isearch-message-prefix c-q-hack ellipsis))\n    ;; And clear any previous isearch message.\n    (message \"\")))\n\n(defun minibuffer-history-isearch-wrap ()\n  \"Wrap the minibuffer history search when search fails.\nMove point to the first history element for a forward search,\nor to the last history element for a backward search.\"\n  ;; When `minibuffer-history-isearch-search' fails on reaching the\n  ;; beginning/end of the history, wrap the search to the first/last\n  ;; minibuffer history element.\n  (if isearch-forward\n      (goto-history-element (length (symbol-value minibuffer-history-variable)))\n    (goto-history-element 0))\n  (setq isearch-success t)\n  (goto-char (if isearch-forward (minibuffer-prompt-end) (point-max))))\n\n(defun minibuffer-history-isearch-push-state ()\n  \"Save a function restoring the state of minibuffer history search.\nSave `minibuffer-history-position' to the additional state parameter\nin the search status stack.\"\n  (let ((pos minibuffer-history-position))\n    (lambda (cmd)\n      (minibuffer-history-isearch-pop-state cmd pos))))\n\n(defun minibuffer-history-isearch-pop-state (_cmd hist-pos)\n  \"Restore the minibuffer history search state.\nGo to the history element by the absolute history position HIST-POS.\"\n  (goto-history-element hist-pos))\n\n\f\n;Put this on C-x u, so we can force that rather than C-_ into startup msg\n(define-obsolete-function-alias 'advertised-undo 'undo \"23.2\")\n\n(defconst undo-equiv-table (make-hash-table :test 'eq :weakness t)\n  \"Table mapping redo records to the corresponding undo one.\nA redo record for undo-in-region maps to t.\nA redo record for ordinary undo maps to the following (earlier) undo.\")\n\n(defvar undo-in-region nil\n  \"Non-nil if `pending-undo-list' is not just a tail of `buffer-undo-list'.\")\n\n(defvar undo-no-redo nil\n  \"If t, `undo' doesn't go through redo entries.\")\n\n(defvar pending-undo-list nil\n  \"Within a run of consecutive undo commands, list remaining to be undone.\nIf t, we undid all the way to the end of it.\")\n\n(defun undo (&optional arg)\n  \"Undo some previous changes.\nRepeat this command to undo more changes.\nA numeric ARG serves as a repeat count.\n\nIn Transient Mark mode when the mark is active, only undo changes within\nthe current region.  Similarly, when not in Transient Mark mode, just \\\\[universal-argument]\nas an argument limits undo to changes within the current region.\"\n  (interactive \"*P\")\n  ;; Make last-command indicate for the next command that this was an undo.\n  ;; That way, another undo will undo more.\n  ;; If we get to the end of the undo history and get an error,\n  ;; another undo command will find the undo history empty\n  ;; and will get another error.  To begin undoing the undos,\n  ;; you must type some other command.\n  (let* ((modified (buffer-modified-p))\n\t ;; For an indirect buffer, look in the base buffer for the\n\t ;; auto-save data.\n\t (base-buffer (or (buffer-base-buffer) (current-buffer)))\n\t (recent-save (with-current-buffer base-buffer\n\t\t\t(recent-auto-save-p)))\n\t message)\n    ;; If we get an error in undo-start,\n    ;; the next command should not be a \"consecutive undo\".\n    ;; So set `this-command' to something other than `undo'.\n    (setq this-command 'undo-start)\n\n    (unless (and (eq last-command 'undo)\n\t\t (or (eq pending-undo-list t)\n\t\t     ;; If something (a timer or filter?) changed the buffer\n\t\t     ;; since the previous command, don't continue the undo seq.\n\t\t     (let ((list buffer-undo-list))\n\t\t       (while (eq (car list) nil)\n\t\t\t (setq list (cdr list)))\n\t\t       ;; If the last undo record made was made by undo\n\t\t       ;; it shows nothing else happened in between.\n\t\t       (gethash list undo-equiv-table))))\n      (setq undo-in-region\n\t    (or (region-active-p) (and arg (not (numberp arg)))))\n      (if undo-in-region\n\t  (undo-start (region-beginning) (region-end))\n\t(undo-start))\n      ;; get rid of initial undo boundary\n      (undo-more 1))\n    ;; If we got this far, the next command should be a consecutive undo.\n    (setq this-command 'undo)\n    ;; Check to see whether we're hitting a redo record, and if\n    ;; so, ask the user whether she wants to skip the redo/undo pair.\n    (let ((equiv (gethash pending-undo-list undo-equiv-table)))\n      (or (eq (selected-window) (minibuffer-window))\n\t  (setq message (format \"%s%s!\"\n                                (if (or undo-no-redo (not equiv))\n                                    \"Undo\" \"Redo\")\n                                (if undo-in-region \" in region\" \"\"))))\n      (when (and (consp equiv) undo-no-redo)\n\t;; The equiv entry might point to another redo record if we have done\n\t;; undo-redo-undo-redo-... so skip to the very last equiv.\n\t(while (let ((next (gethash equiv undo-equiv-table)))\n\t\t (if next (setq equiv next))))\n\t(setq pending-undo-list equiv)))\n    (undo-more\n     (if (numberp arg)\n\t (prefix-numeric-value arg)\n       1))\n    ;; Record the fact that the just-generated undo records come from an\n    ;; undo operation--that is, they are redo records.\n    ;; In the ordinary case (not within a region), map the redo\n    ;; record to the following undos.\n    ;; I don't know how to do that in the undo-in-region case.\n    (let ((list buffer-undo-list))\n      ;; Strip any leading undo boundaries there might be, like we do\n      ;; above when checking.\n      (while (eq (car list) nil)\n\t(setq list (cdr list)))\n      (puthash list\n               ;; Prevent identity mapping.  This can happen if\n               ;; consecutive nils are erroneously in undo list.\n               (if (or undo-in-region (eq list pending-undo-list))\n                   t\n                 pending-undo-list)\n\t       undo-equiv-table))\n    ;; Don't specify a position in the undo record for the undo command.\n    ;; Instead, undoing this should move point to where the change is.\n    (let ((tail buffer-undo-list)\n\t  (prev nil))\n      (while (car tail)\n\t(when (integerp (car tail))\n\t  (let ((pos (car tail)))\n\t    (if prev\n\t\t(setcdr prev (cdr tail))\n\t      (setq buffer-undo-list (cdr tail)))\n\t    (setq tail (cdr tail))\n\t    (while (car tail)\n\t      (if (eq pos (car tail))\n\t\t  (if prev\n\t\t      (setcdr prev (cdr tail))\n\t\t    (setq buffer-undo-list (cdr tail)))\n\t\t(setq prev tail))\n\t      (setq tail (cdr tail)))\n\t    (setq tail nil)))\n\t(setq prev tail tail (cdr tail))))\n    ;; Record what the current undo list says,\n    ;; so the next command can tell if the buffer was modified in between.\n    (and modified (not (buffer-modified-p))\n\t (with-current-buffer base-buffer\n\t   (delete-auto-save-file-if-necessary recent-save)))\n    ;; Display a message announcing success.\n    (if message\n\t(message \"%s\" message))))\n\n(defun buffer-disable-undo (&optional buffer)\n  \"Make BUFFER stop keeping undo information.\nNo argument or nil as argument means do this for the current buffer.\"\n  (interactive)\n  (with-current-buffer (if buffer (get-buffer buffer) (current-buffer))\n    (setq buffer-undo-list t)))\n\n(defun undo-only (&optional arg)\n  \"Undo some previous changes.\nRepeat this command to undo more changes.\nA numeric ARG serves as a repeat count.\nContrary to `undo', this will not redo a previous undo.\"\n  (interactive \"*p\")\n  (let ((undo-no-redo t)) (undo arg)))\n\n(defvar undo-in-progress nil\n  \"Non-nil while performing an undo.\nSome change-hooks test this variable to do something different.\")\n\n(defun undo-more (n)\n  \"Undo back N undo-boundaries beyond what was already undone recently.\nCall `undo-start' to get ready to undo recent changes,\nthen call `undo-more' one or more times to undo them.\"\n  (or (listp pending-undo-list)\n      (user-error (concat \"No further undo information\"\n                          (and undo-in-region \" for region\"))))\n  (let ((undo-in-progress t))\n    ;; Note: The following, while pulling elements off\n    ;; `pending-undo-list' will call primitive change functions which\n    ;; will push more elements onto `buffer-undo-list'.\n    (setq pending-undo-list (primitive-undo n pending-undo-list))\n    (if (null pending-undo-list)\n\t(setq pending-undo-list t))))\n\n(defun primitive-undo (n list)\n  \"Undo N records from the front of the list LIST.\nReturn what remains of the list.\"\n\n  ;; This is a good feature, but would make undo-start\n  ;; unable to do what is expected.\n  ;;(when (null (car (list)))\n  ;;  ;; If the head of the list is a boundary, it is the boundary\n  ;;  ;; preceding this command.  Get rid of it and don't count it.\n  ;;  (setq list (cdr list))))\n\n  (let ((arg n)\n        ;; In a writable buffer, enable undoing read-only text that is\n        ;; so because of text properties.\n        (inhibit-read-only t)\n        ;; Don't let `intangible' properties interfere with undo.\n        (inhibit-point-motion-hooks t)\n        ;; We use oldlist only to check for EQ.  ++kfs\n        (oldlist buffer-undo-list)\n        (did-apply nil)\n        (next nil))\n    (while (> arg 0)\n      (while (setq next (pop list))     ;Exit inner loop at undo boundary.\n        ;; Handle an integer by setting point to that value.\n        (pcase next\n          ((pred integerp) (goto-char next))\n          ;; Element (t . TIME) records previous modtime.\n          ;; Preserve any flag of NONEXISTENT_MODTIME_NSECS or\n          ;; UNKNOWN_MODTIME_NSECS.\n          (`(t . ,time)\n           ;; If this records an obsolete save\n           ;; (not matching the actual disk file)\n           ;; then don't mark unmodified.\n           (when (or (equal time (visited-file-modtime))\n                     (and (consp time)\n                          (equal (list (car time) (cdr time))\n                                 (visited-file-modtime))))\n             (when (fboundp 'unlock-buffer)\n               (unlock-buffer))\n             (set-buffer-modified-p nil)))\n          ;; Element (nil PROP VAL BEG . END) is property change.\n          (`(nil . ,(or `(,prop ,val ,beg . ,end) pcase--dontcare))\n           (when (or (> (point-min) beg) (< (point-max) end))\n             (error \"Changes to be undone are outside visible portion of buffer\"))\n           (put-text-property beg end prop val))\n          ;; Element (BEG . END) means range was inserted.\n          (`(,(and beg (pred integerp)) . ,(and end (pred integerp)))\n           ;; (and `(,beg . ,end) `(,(pred integerp) . ,(pred integerp)))\n           ;; Ideally: `(,(pred integerp beg) . ,(pred integerp end))\n           (when (or (> (point-min) beg) (< (point-max) end))\n             (error \"Changes to be undone are outside visible portion of buffer\"))\n           ;; Set point first thing, so that undoing this undo\n           ;; does not send point back to where it is now.\n           (goto-char beg)\n           (delete-region beg end))\n          ;; Element (apply FUN . ARGS) means call FUN to undo.\n          (`(apply . ,fun-args)\n           (let ((currbuff (current-buffer)))\n             (if (integerp (car fun-args))\n                 ;; Long format: (apply DELTA START END FUN . ARGS).\n                 (pcase-let* ((`(,delta ,start ,end ,fun . ,args) fun-args)\n                              (start-mark (copy-marker start nil))\n                              (end-mark (copy-marker end t)))\n                   (when (or (> (point-min) start) (< (point-max) end))\n                     (error \"Changes to be undone are outside visible portion of buffer\"))\n                   (apply fun args) ;; Use `save-current-buffer'?\n                   ;; Check that the function did what the entry\n                   ;; said it would do.\n                   (unless (and (= start start-mark)\n                                (= (+ delta end) end-mark))\n                     (error \"Changes to be undone by function different than announced\"))\n                   (set-marker start-mark nil)\n                   (set-marker end-mark nil))\n               (apply fun-args))\n             (unless (eq currbuff (current-buffer))\n               (error \"Undo function switched buffer\"))\n             (setq did-apply t)))\n          ;; Element (STRING . POS) means STRING was deleted.\n          (`(,(and string (pred stringp)) . ,(and pos (pred integerp)))\n           (let ((valid-marker-adjustments nil)\n                 (apos (abs pos)))\n             (when (or (< apos (point-min)) (> apos (point-max)))\n               (error \"Changes to be undone are outside visible portion of buffer\"))\n             ;; Check that marker adjustments which were recorded\n             ;; with the (STRING . POS) record are still valid, ie\n             ;; the markers haven't moved.  We check their validity\n             ;; before reinserting the string so as we don't need to\n             ;; mind marker insertion-type.\n             (while (and (markerp (car-safe (car list)))\n                         (integerp (cdr-safe (car list))))\n               (let* ((marker-adj (pop list))\n                      (m (car marker-adj)))\n                 (and (eq (marker-buffer m) (current-buffer))\n                      (= apos m)\n                      (push marker-adj valid-marker-adjustments))))\n             ;; Insert string and adjust point\n             (if (< pos 0)\n                 (progn\n                   (goto-char (- pos))\n                   (insert string))\n               (goto-char pos)\n               (insert string)\n               (goto-char pos))\n             ;; Adjust the valid marker adjustments\n             (dolist (adj valid-marker-adjustments)\n               ;; Insert might have invalidated some of the markers\n               ;; via modification hooks.  Update only the currently\n               ;; valid ones (bug#25599).\n               (if (marker-buffer (car adj))\n                   (set-marker (car adj)\n                               (- (car adj) (cdr adj)))))))\n          ;; (MARKER . OFFSET) means a marker MARKER was adjusted by OFFSET.\n          (`(,(and marker (pred markerp)) . ,(and offset (pred integerp)))\n           (warn \"Encountered %S entry in undo list with no matching (TEXT . POS) entry\"\n                 next)\n           ;; Even though these elements are not expected in the undo\n           ;; list, adjust them to be conservative for the 24.4\n           ;; release.  (Bug#16818)\n           (when (marker-buffer marker)\n             (set-marker marker\n                         (- marker offset)\n                         (marker-buffer marker))))\n          (_ (error \"Unrecognized entry in undo list %S\" next))))\n      (setq arg (1- arg)))\n    ;; Make sure an apply entry produces at least one undo entry,\n    ;; so the test in `undo' for continuing an undo series\n    ;; will work right.\n    (if (and did-apply\n             (eq oldlist buffer-undo-list))\n        (setq buffer-undo-list\n              (cons (list 'apply 'cdr nil) buffer-undo-list))))\n  list)\n\n;; Deep copy of a list\n(defun undo-copy-list (list)\n  \"Make a copy of undo list LIST.\"\n  (mapcar 'undo-copy-list-1 list))\n\n(defun undo-copy-list-1 (elt)\n  (if (consp elt)\n      (cons (car elt) (undo-copy-list-1 (cdr elt)))\n    elt))\n\n(defun undo-start (&optional beg end)\n  \"Set `pending-undo-list' to the front of the undo list.\nThe next call to `undo-more' will undo the most recently made change.\nIf BEG and END are specified, then only undo elements\nthat apply to text between BEG and END are used; other undo elements\nare ignored.  If BEG and END are nil, all undo elements are used.\"\n  (if (eq buffer-undo-list t)\n      (user-error \"No undo information in this buffer\"))\n  (setq pending-undo-list\n\t(if (and beg end (not (= beg end)))\n\t    (undo-make-selective-list (min beg end) (max beg end))\n\t  buffer-undo-list)))\n\n;; The positions given in elements of the undo list are the positions\n;; as of the time that element was recorded to undo history.  In\n;; general, subsequent buffer edits render those positions invalid in\n;; the current buffer, unless adjusted according to the intervening\n;; undo elements.\n;;\n;; Undo in region is a use case that requires adjustments to undo\n;; elements.  It must adjust positions of elements in the region based\n;; on newer elements not in the region so as they may be correctly\n;; applied in the current buffer.  undo-make-selective-list\n;; accomplishes this with its undo-deltas list of adjustments.  An\n;; example undo history from oldest to newest:\n;;\n;; buf pos:\n;; 123456789 buffer-undo-list undo-deltas\n;; --------- ---------------- -----------\n;; aaa       (1 . 4)          (1 . -3)\n;; aaba      (3 . 4)          N/A (in region)\n;; ccaaba    (1 . 3)          (1 . -2)\n;; ccaabaddd (7 . 10)         (7 . -3)\n;; ccaabdd   (\"ad\" . 6)       (6 . 2)\n;; ccaabaddd (6 . 8)          (6 . -2)\n;;  |   |<-- region: \"caab\", from 2 to 6\n;;\n;; When the user starts a run of undos in region,\n;; undo-make-selective-list is called to create the full list of in\n;; region elements.  Each element is adjusted forward chronologically\n;; through undo-deltas to determine if it is in the region.\n;;\n;; In the above example, the insertion of \"b\" is (3 . 4) in the\n;; buffer-undo-list.  The undo-delta (1 . -2) causes (3 . 4) to become\n;; (5 . 6).  The next three undo-deltas cause no adjustment, so (5\n;; . 6) is assessed as in the region and placed in the selective list.\n;; Notably, the end of region itself adjusts from \"2 to 6\" to \"2 to 5\"\n;; due to the selected element.  The \"b\" insertion is the only element\n;; fully in the region, so in this example undo-make-selective-list\n;; returns (nil (5 . 6)).\n;;\n;; The adjustment of the (7 . 10) insertion of \"ddd\" shows an edge\n;; case.  It is adjusted through the undo-deltas: ((6 . 2) (6 . -2)).\n;; Normally an undo-delta of (6 . 2) would cause positions after 6 to\n;; adjust by 2.  However, they shouldn't adjust to less than 6, so (7\n;; . 10) adjusts to (6 . 8) due to the first undo delta.\n;;\n;; More interesting is how to adjust the \"ddd\" insertion due to the\n;; next undo-delta: (6 . -2), corresponding to reinsertion of \"ad\".\n;; If the reinsertion was a manual retyping of \"ad\", then the total\n;; adjustment should be (7 . 10) -> (6 . 8) -> (8 . 10).  However, if\n;; the reinsertion was due to undo, one might expect the first \"d\"\n;; character would again be a part of the \"ddd\" text, meaning its\n;; total adjustment would be (7 . 10) -> (6 . 8) -> (7 . 10).\n;;\n;; undo-make-selective-list assumes in this situation that \"ad\" was a\n;; new edit, even if it was inserted because of an undo.\n;; Consequently, if the user undos in region \"8 to 10\" of the\n;; \"ccaabaddd\" buffer, they could be surprised that it becomes\n;; \"ccaabad\", as though the first \"d\" became detached from the\n;; original \"ddd\" insertion.  This quirk is a FIXME.\n\n(defun undo-make-selective-list (start end)\n  \"Return a list of undo elements for the region START to END.\nThe elements come from `buffer-undo-list', but we keep only the\nelements inside this region, and discard those outside this\nregion.  The elements' positions are adjusted so as the returned\nlist can be applied to the current buffer.\"\n  (let ((ulist buffer-undo-list)\n        ;; A list of position adjusted undo elements in the region.\n        (selective-list (list nil))\n        ;; A list of undo-deltas for out of region undo elements.\n        undo-deltas\n        undo-elt)\n    (while ulist\n      (when undo-no-redo\n        (while (gethash ulist undo-equiv-table)\n          (setq ulist (gethash ulist undo-equiv-table))))\n      (setq undo-elt (car ulist))\n      (cond\n       ((null undo-elt)\n        ;; Don't put two nils together in the list\n        (when (car selective-list)\n          (push nil selective-list)))\n       ((and (consp undo-elt) (eq (car undo-elt) t))\n        ;; This is a \"was unmodified\" element.  Keep it\n        ;; if we have kept everything thus far.\n        (when (not undo-deltas)\n          (push undo-elt selective-list)))\n       ;; Skip over marker adjustments, instead relying\n       ;; on finding them after (TEXT . POS) elements\n       ((markerp (car-safe undo-elt))\n        nil)\n       (t\n        (let ((adjusted-undo-elt (undo-adjust-elt undo-elt\n                                                  undo-deltas)))\n          (if (undo-elt-in-region adjusted-undo-elt start end)\n              (progn\n                (setq end (+ end (cdr (undo-delta adjusted-undo-elt))))\n                (push adjusted-undo-elt selective-list)\n                ;; Keep (MARKER . ADJUSTMENT) if their (TEXT . POS) was\n                ;; kept.  primitive-undo may discard them later.\n                (when (and (stringp (car-safe adjusted-undo-elt))\n                           (integerp (cdr-safe adjusted-undo-elt)))\n                  (let ((list-i (cdr ulist)))\n                    (while (markerp (car-safe (car list-i)))\n                      (push (pop list-i) selective-list)))))\n            (let ((delta (undo-delta undo-elt)))\n              (when (/= 0 (cdr delta))\n                (push delta undo-deltas)))))))\n      (pop ulist))\n    (nreverse selective-list)))\n\n(defun undo-elt-in-region (undo-elt start end)\n  \"Determine whether UNDO-ELT falls inside the region START ... END.\nIf it crosses the edge, we return nil.\n\nGenerally this function is not useful for determining\nwhether (MARKER . ADJUSTMENT) undo elements are in the region,\nbecause markers can be arbitrarily relocated.  Instead, pass the\nmarker adjustment's corresponding (TEXT . POS) element.\"\n  (cond ((integerp undo-elt)\n\t (and (>= undo-elt start)\n\t      (<= undo-elt end)))\n\t((eq undo-elt nil)\n\t t)\n\t((atom undo-elt)\n\t nil)\n\t((stringp (car undo-elt))\n\t ;; (TEXT . POSITION)\n\t (and (>= (abs (cdr undo-elt)) start)\n\t      (<= (abs (cdr undo-elt)) end)))\n\t((and (consp undo-elt) (markerp (car undo-elt)))\n\t ;; (MARKER . ADJUSTMENT)\n         (<= start (car undo-elt) end))\n\t((null (car undo-elt))\n\t ;; (nil PROPERTY VALUE BEG . END)\n\t (let ((tail (nthcdr 3 undo-elt)))\n\t   (and (>= (car tail) start)\n\t\t(<= (cdr tail) end))))\n\t((integerp (car undo-elt))\n\t ;; (BEGIN . END)\n\t (and (>= (car undo-elt) start)\n\t      (<= (cdr undo-elt) end)))))\n\n(defun undo-elt-crosses-region (undo-elt start end)\n  \"Test whether UNDO-ELT crosses one edge of that region START ... END.\nThis assumes we have already decided that UNDO-ELT\nis not *inside* the region START...END.\"\n  (declare (obsolete nil \"25.1\"))\n  (cond ((atom undo-elt) nil)\n\t((null (car undo-elt))\n\t ;; (nil PROPERTY VALUE BEG . END)\n\t (let ((tail (nthcdr 3 undo-elt)))\n\t   (and (< (car tail) end)\n\t\t(> (cdr tail) start))))\n\t((integerp (car undo-elt))\n\t ;; (BEGIN . END)\n\t (and (< (car undo-elt) end)\n\t      (> (cdr undo-elt) start)))))\n\n(defun undo-adjust-elt (elt deltas)\n  \"Return adjustment of undo element ELT by the undo DELTAS\nlist.\"\n  (pcase elt\n    ;; POSITION\n    ((pred integerp)\n     (undo-adjust-pos elt deltas))\n    ;; (BEG . END)\n    (`(,(and beg (pred integerp)) . ,(and end (pred integerp)))\n     (undo-adjust-beg-end beg end deltas))\n    ;; (TEXT . POSITION)\n    (`(,(and text (pred stringp)) . ,(and pos (pred integerp)))\n     (cons text (* (if (< pos 0) -1 1)\n                   (undo-adjust-pos (abs pos) deltas))))\n    ;; (nil PROPERTY VALUE BEG . END)\n    (`(nil . ,(or `(,prop ,val ,beg . ,end) pcase--dontcare))\n     `(nil ,prop ,val . ,(undo-adjust-beg-end beg end deltas)))\n    ;; (apply DELTA START END FUN . ARGS)\n    ;; FIXME\n    ;; All others return same elt\n    (_ elt)))\n\n;; (BEG . END) can adjust to the same positions, commonly when an\n;; insertion was undone and they are out of region, for example:\n;;\n;; buf pos:\n;; 123456789 buffer-undo-list undo-deltas\n;; --------- ---------------- -----------\n;; [...]\n;; abbaa     (2 . 4)          (2 . -2)\n;; aaa       (\"bb\" . 2)       (2 . 2)\n;; [...]\n;;\n;; \"bb\" insertion (2 . 4) adjusts to (2 . 2) because of the subsequent\n;; undo.  Further adjustments to such an element should be the same as\n;; for (TEXT . POSITION) elements.  The options are:\n;;\n;;   1: POSITION adjusts using <= (use-< nil), resulting in behavior\n;;      analogous to marker insertion-type t.\n;;\n;;   2: POSITION adjusts using <, resulting in behavior analogous to\n;;      marker insertion-type nil.\n;;\n;; There was no strong reason to prefer one or the other, except that\n;; the first is more consistent with prior undo in region behavior.\n(defun undo-adjust-beg-end (beg end deltas)\n  \"Return cons of adjustments to BEG and END by the undo DELTAS\nlist.\"\n  (let ((adj-beg (undo-adjust-pos beg deltas)))\n    ;; Note: option 2 above would be like (cons (min ...) adj-end)\n    (cons adj-beg\n          (max adj-beg (undo-adjust-pos end deltas t)))))\n\n(defun undo-adjust-pos (pos deltas &optional use-<)\n  \"Return adjustment of POS by the undo DELTAS list, comparing\nwith < or <= based on USE-<.\"\n  (dolist (d deltas pos)\n    (when (if use-<\n              (< (car d) pos)\n            (<= (car d) pos))\n      (setq pos\n            ;; Don't allow pos to become less than the undo-delta\n            ;; position.  This edge case is described in the overview\n            ;; comments.\n            (max (car d) (- pos (cdr d)))))))\n\n;; Return the first affected buffer position and the delta for an undo element\n;; delta is defined as the change in subsequent buffer positions if we *did*\n;; the undo.\n(defun undo-delta (undo-elt)\n  (if (consp undo-elt)\n      (cond ((stringp (car undo-elt))\n\t     ;; (TEXT . POSITION)\n\t     (cons (abs (cdr undo-elt)) (length (car undo-elt))))\n\t    ((integerp (car undo-elt))\n\t     ;; (BEGIN . END)\n\t     (cons (car undo-elt) (- (car undo-elt) (cdr undo-elt))))\n\t    (t\n\t     '(0 . 0)))\n    '(0 . 0)))\n\n;;; Default undo-boundary addition\n;;\n;; This section adds a new undo-boundary at either after a command is\n;; called or in some cases on a timer called after a change is made in\n;; any buffer.\n(defvar-local undo-auto--last-boundary-cause nil\n  \"Describe the cause of the last undo-boundary.\n\nIf `explicit', the last boundary was caused by an explicit call to\n`undo-boundary', that is one not called by the code in this\nsection.\n\nIf it is equal to `timer', then the last boundary was inserted\nby `undo-auto--boundary-timer'.\n\nIf it is equal to `command', then the last boundary was inserted\nautomatically after a command, that is by the code defined in\nthis section.\n\nIf it is equal to a list, then the last boundary was inserted by\nan amalgamating command.  The car of the list is the number of\ntimes an amalgamating command has been called, and the cdr are the\nbuffers that were changed during the last command.\")\n\n(defvar undo-auto-current-boundary-timer nil\n  \"Current timer which will run `undo-auto--boundary-timer' or nil.\n\nIf set to non-nil, this will effectively disable the timer.\")\n\n(defvar undo-auto--this-command-amalgamating nil\n  \"Non-nil if `this-command' should be amalgamated.\nThis variable is set to nil by `undo-auto--boundaries' and is set\nby `undo-auto-amalgamate'.\" )\n\n(defun undo-auto--needs-boundary-p ()\n  \"Return non-nil if `buffer-undo-list' needs a boundary at the start.\"\n  (car-safe buffer-undo-list))\n\n(defun undo-auto--last-boundary-amalgamating-number ()\n  \"Return the number of amalgamating last commands or nil.\nAmalgamating commands are, by default, either\n`self-insert-command' and `delete-char', but can be any command\nthat calls `undo-auto-amalgamate'.\"\n  (car-safe undo-auto--last-boundary-cause))\n\n(defun undo-auto--ensure-boundary (cause)\n  \"Add an `undo-boundary' to the current buffer if needed.\nREASON describes the reason that the boundary is being added; see\n`undo-auto--last-boundary' for more information.\"\n  (when (and\n         (undo-auto--needs-boundary-p))\n    (let ((last-amalgamating\n           (undo-auto--last-boundary-amalgamating-number)))\n      (undo-boundary)\n      (setq undo-auto--last-boundary-cause\n            (if (eq 'amalgamate cause)\n                (cons\n                 (if last-amalgamating (1+ last-amalgamating) 0)\n                 undo-auto--undoably-changed-buffers)\n              cause)))))\n\n(defun undo-auto--boundaries (cause)\n  \"Check recently changed buffers and add a boundary if necessary.\nREASON describes the reason that the boundary is being added; see\n`undo-last-boundary' for more information.\"\n  ;; (Bug #23785) All commands should ensure that there is an undo\n  ;; boundary whether they have changed the current buffer or not.\n  (when (eq cause 'command)\n    (add-to-list 'undo-auto--undoably-changed-buffers (current-buffer)))\n  (dolist (b undo-auto--undoably-changed-buffers)\n          (when (buffer-live-p b)\n            (with-current-buffer b\n              (undo-auto--ensure-boundary cause))))\n  (setq undo-auto--undoably-changed-buffers nil))\n\n(defun undo-auto--boundary-timer ()\n  \"Timer function run by `undo-auto-current-boundary-timer'.\"\n  (setq undo-auto-current-boundary-timer nil)\n  (undo-auto--boundaries 'timer))\n\n(defun undo-auto--boundary-ensure-timer ()\n  \"Ensure that the `undo-auto-current-boundary-timer' is set.\"\n  (unless undo-auto-current-boundary-timer\n    (setq undo-auto-current-boundary-timer\n          (run-at-time 10 nil #'undo-auto--boundary-timer))))\n\n(defvar undo-auto--undoably-changed-buffers nil\n  \"List of buffers that have changed recently.\n\nThis list is maintained by `undo-auto--undoable-change' and\n`undo-auto--boundaries' and can be affected by changes to their\ndefault values.\")\n\n(defun undo-auto--add-boundary ()\n  \"Add an `undo-boundary' in appropriate buffers.\"\n  (undo-auto--boundaries\n   (let ((amal undo-auto--this-command-amalgamating))\n       (setq undo-auto--this-command-amalgamating nil)\n       (if amal\n           'amalgamate\n         'command))))\n\n(defun undo-auto-amalgamate ()\n  \"Amalgamate undo if necessary.\nThis function can be called before an amalgamating command.  It\nremoves the previous `undo-boundary' if a series of such calls\nhave been made.  By default `self-insert-command' and\n`delete-char' are the only amalgamating commands, although this\nfunction could be called by any command wishing to have this\nbehavior.\"\n  (let ((last-amalgamating-count\n         (undo-auto--last-boundary-amalgamating-number)))\n    (setq undo-auto--this-command-amalgamating t)\n    (when\n        last-amalgamating-count\n      (if\n          (and\n           (< last-amalgamating-count 20)\n           (eq this-command last-command))\n          ;; Amalgamate all buffers that have changed.\n          (dolist (b (cdr undo-auto--last-boundary-cause))\n            (when (buffer-live-p b)\n              (with-current-buffer\n                  b\n                (when\n                    ;; The head of `buffer-undo-list' is nil.\n                    ;; `car-safe' doesn't work because\n                    ;; `buffer-undo-list' need not be a list!\n                    (and (listp buffer-undo-list)\n                         (not (car buffer-undo-list)))\n                  (setq buffer-undo-list\n                        (cdr buffer-undo-list))))))\n        (setq undo-auto--last-boundary-cause 0)))))\n\n(defun undo-auto--undoable-change ()\n  \"Called after every undoable buffer change.\"\n  (add-to-list 'undo-auto--undoably-changed-buffers (current-buffer))\n  (undo-auto--boundary-ensure-timer))\n;; End auto-boundary section\n\n(defun undo-amalgamate-change-group (handle)\n  \"Amalgamate changes in change-group since HANDLE.\nRemove all undo boundaries between the state of HANDLE and now.\nHANDLE is as returned by `prepare-change-group'.\"\n  (dolist (elt handle)\n    (with-current-buffer (car elt)\n      (setq elt (cdr elt))\n      (when (consp buffer-undo-list)\n        (let ((old-car (car-safe elt))\n              (old-cdr (cdr-safe elt)))\n          (unwind-protect\n              (progn\n                ;; Temporarily truncate the undo log at ELT.\n                (when (consp elt)\n                  (setcar elt t) (setcdr elt nil))\n                (when\n                    (or (null elt)        ;The undo-log was empty.\n                        ;; `elt' is still in the log: normal case.\n                        (eq elt (last buffer-undo-list))\n                        ;; `elt' is not in the log any more, but that's because\n                        ;; the log is \"all new\", so we should remove all\n                        ;; boundaries from it.\n                        (not (eq (last buffer-undo-list) (last old-cdr))))\n                  (cl-callf (lambda (x) (delq nil x))\n                      (if (car buffer-undo-list)\n                          buffer-undo-list\n                        ;; Preserve the undo-boundaries at either ends of the\n                        ;; change-groups.\n                        (cdr buffer-undo-list)))))\n            ;; Reset the modified cons cell ELT to its original content.\n            (when (consp elt)\n              (setcar elt old-car)\n              (setcdr elt old-cdr))))))))\n\n\n(defcustom undo-ask-before-discard nil\n  \"If non-nil ask about discarding undo info for the current command.\nNormally, Emacs discards the undo info for the current command if\nit exceeds `undo-outer-limit'.  But if you set this option\nnon-nil, it asks in the echo area whether to discard the info.\nIf you answer no, there is a slight risk that Emacs might crash, so\nonly do it if you really want to undo the command.\n\nThis option is mainly intended for debugging.  You have to be\ncareful if you use it for other purposes.  Garbage collection is\ninhibited while the question is asked, meaning that Emacs might\nleak memory.  So you should make sure that you do not wait\nexcessively long before answering the question.\"\n  :type 'boolean\n  :group 'undo\n  :version \"22.1\")\n\n(defvar undo-extra-outer-limit nil\n  \"If non-nil, an extra level of size that's ok in an undo item.\nWe don't ask the user about truncating the undo list until the\ncurrent item gets bigger than this amount.\n\nThis variable only matters if `undo-ask-before-discard' is non-nil.\")\n(make-variable-buffer-local 'undo-extra-outer-limit)\n\n;; When the first undo batch in an undo list is longer than\n;; undo-outer-limit, this function gets called to warn the user that\n;; the undo info for the current command was discarded.  Garbage\n;; collection is inhibited around the call, so it had better not do a\n;; lot of consing.\n(setq undo-outer-limit-function 'undo-outer-limit-truncate)\n(defun undo-outer-limit-truncate (size)\n  (if undo-ask-before-discard\n      (when (or (null undo-extra-outer-limit)\n\t\t(> size undo-extra-outer-limit))\n\t;; Don't ask the question again unless it gets even bigger.\n\t;; This applies, in particular, if the user quits from the question.\n\t;; Such a quit quits out of GC, but something else will call GC\n\t;; again momentarily.  It will call this function again,\n\t;; but we don't want to ask the question again.\n\t(setq undo-extra-outer-limit (+ size 50000))\n\t(if (let (use-dialog-box track-mouse executing-kbd-macro )\n\t      (yes-or-no-p (format-message\n                            \"Buffer `%s' undo info is %d bytes long; discard it? \"\n                            (buffer-name) size)))\n\t    (progn (setq buffer-undo-list nil)\n\t\t   (setq undo-extra-outer-limit nil)\n\t\t   t)\n\t  nil))\n    (display-warning '(undo discard-info)\n\t\t     (concat\n\t\t      (format-message\n                       \"Buffer `%s' undo info was %d bytes long.\\n\"\n                       (buffer-name) size)\n\t\t      \"The undo info was discarded because it exceeded \\\n`undo-outer-limit'.\n\nThis is normal if you executed a command that made a huge change\nto the buffer.  In that case, to prevent similar problems in the\nfuture, set `undo-outer-limit' to a value that is large enough to\ncover the maximum size of normal changes you expect a single\ncommand to make, but not so large that it might exceed the\nmaximum memory allotted to Emacs.\n\nIf you did not execute any such command, the situation is\nprobably due to a bug and you should report it.\n\nYou can disable the popping up of this buffer by adding the entry\n\\(undo discard-info) to the user option `warning-suppress-types',\nwhich is defined in the `warnings' library.\\n\")\n\t\t     :warning)\n    (setq buffer-undo-list nil)\n    t))\n\f\n(defcustom password-word-equivalents\n  '(\"password\" \"passcode\" \"passphrase\" \"pass phrase\"\n    ; These are sorted according to the GNU en_US locale.\n    \"암호\"\t\t; ko\n    \"パスワード\"\t; ja\n    \"ପ୍ରବେଶ ସଙ୍କେତ\"\t; or\n    \"ពាក្យសម្ងាត់\"\t\t; km\n    \"adgangskode\"\t; da\n    \"contraseña\"\t; es\n    \"contrasenya\"\t; ca\n    \"geslo\"\t\t; sl\n    \"hasło\"\t\t; pl\n    \"heslo\"\t\t; cs, sk\n    \"iphasiwedi\"\t; zu\n    \"jelszó\"\t\t; hu\n    \"lösenord\"\t\t; sv\n    \"lozinka\"\t\t; hr, sr\n    \"mật khẩu\"\t\t; vi\n    \"mot de passe\"\t; fr\n    \"parola\"\t\t; tr\n    \"pasahitza\"\t\t; eu\n    \"passord\"\t\t; nb\n    \"passwort\"\t\t; de\n    \"pasvorto\"\t\t; eo\n    \"salasana\"\t\t; fi\n    \"senha\"\t\t; pt\n    \"slaptažodis\"\t; lt\n    \"wachtwoord\"\t; nl\n    \"كلمة السر\"\t\t; ar\n    \"ססמה\"\t\t; he\n    \"лозинка\"\t\t; sr\n    \"пароль\"\t\t; kk, ru, uk\n    \"गुप्तशब्द\"\t\t; mr\n    \"शब्दकूट\"\t\t; hi\n    \"પાસવર્ડ\"\t\t; gu\n    \"సంకేతపదము\"\t\t; te\n    \"ਪਾਸਵਰਡ\"\t\t; pa\n    \"ಗುಪ್ತಪದ\"\t\t; kn\n    \"கடவுச்சொல்\"\t\t; ta\n    \"അടയാളവാക്ക്\"\t\t; ml\n    \"গুপ্তশব্দ\"\t\t; as\n    \"পাসওয়ার্ড\"\t\t; bn_IN\n    \"රහස්පදය\"\t\t; si\n    \"密码\"\t\t; zh_CN\n    \"密碼\"\t\t; zh_TW\n    )\n  \"List of words equivalent to \\\"password\\\".\nThis is used by Shell mode and other parts of Emacs to recognize\npassword prompts, including prompts in languages other than\nEnglish.  Different case choices should not be assumed to be\nincluded; callers should bind `case-fold-search' to t.\"\n  :type '(repeat string)\n  :version \"24.4\"\n  :group 'processes)\n\n(defvar shell-command-history nil\n  \"History list for some commands that read shell commands.\n\nMaximum length of the history list is determined by the value\nof `history-length', which see.\")\n\n(defvar shell-command-switch (purecopy \"-c\")\n  \"Switch used to have the shell execute its command line argument.\")\n\n(defvar shell-command-default-error-buffer nil\n  \"Buffer name for `shell-command' and `shell-command-on-region' error output.\nThis buffer is used when `shell-command' or `shell-command-on-region'\nis run interactively.  A value of nil means that output to stderr and\nstdout will be intermixed in the output stream.\")\n\n(declare-function mailcap-file-default-commands \"mailcap\" (files))\n(declare-function dired-get-filename \"dired\" (&optional localp no-error-if-not-filep))\n\n(defun minibuffer-default-add-shell-commands ()\n  \"Return a list of all commands associated with the current file.\nThis function is used to add all related commands retrieved by `mailcap'\nto the end of the list of defaults just after the default value.\"\n  (interactive)\n  (let* ((filename (if (listp minibuffer-default)\n\t\t       (car minibuffer-default)\n\t\t     minibuffer-default))\n\t (commands (and filename (require 'mailcap nil t)\n\t\t\t(mailcap-file-default-commands (list filename)))))\n    (setq commands (mapcar (lambda (command)\n\t\t\t     (concat command \" \" filename))\n\t\t\t   commands))\n    (if (listp minibuffer-default)\n\t(append minibuffer-default commands)\n      (cons minibuffer-default commands))))\n\n(declare-function shell-completion-vars \"shell\" ())\n\n(defvar minibuffer-local-shell-command-map\n  (let ((map (make-sparse-keymap)))\n    (set-keymap-parent map minibuffer-local-map)\n    (define-key map \"\\t\" 'completion-at-point)\n    map)\n  \"Keymap used for completing shell commands in minibuffer.\")\n\n(defun read-shell-command (prompt &optional initial-contents hist &rest args)\n  \"Read a shell command from the minibuffer.\nThe arguments are the same as the ones of `read-from-minibuffer',\nexcept READ and KEYMAP are missing and HIST defaults\nto `shell-command-history'.\"\n  (require 'shell)\n  (minibuffer-with-setup-hook\n      (lambda ()\n        (shell-completion-vars)\n\t(set (make-local-variable 'minibuffer-default-add-function)\n\t     'minibuffer-default-add-shell-commands))\n    (apply 'read-from-minibuffer prompt initial-contents\n\t   minibuffer-local-shell-command-map\n\t   nil\n\t   (or hist 'shell-command-history)\n\t   args)))\n\n(defcustom async-shell-command-buffer 'confirm-new-buffer\n  \"What to do when the output buffer is used by another shell command.\nThis option specifies how to resolve the conflict where a new command\nwants to direct its output to the buffer `*Async Shell Command*',\nbut this buffer is already taken by another running shell command.\n\nThe value `confirm-kill-process' is used to ask for confirmation before\nkilling the already running process and running a new process\nin the same buffer, `confirm-new-buffer' for confirmation before running\nthe command in a new buffer with a name other than the default buffer name,\n`new-buffer' for doing the same without confirmation,\n`confirm-rename-buffer' for confirmation before renaming the existing\noutput buffer and running a new command in the default buffer,\n`rename-buffer' for doing the same without confirmation.\"\n  :type '(choice (const :tag \"Confirm killing of running command\"\n\t\t\tconfirm-kill-process)\n\t\t (const :tag \"Confirm creation of a new buffer\"\n\t\t\tconfirm-new-buffer)\n\t\t (const :tag \"Create a new buffer\"\n\t\t\tnew-buffer)\n\t\t (const :tag \"Confirm renaming of existing buffer\"\n\t\t\tconfirm-rename-buffer)\n\t\t (const :tag \"Rename the existing buffer\"\n\t\t\trename-buffer))\n  :group 'shell\n  :version \"24.3\")\n\n(defcustom async-shell-command-display-buffer t\n  \"Whether to display the command buffer immediately.\nIf t, display the buffer immediately; if nil, wait until there\nis output.\"\n  :type '(choice (const :tag \"Display buffer immediately\"\n\t\t\tt)\n\t\t (const :tag \"Display buffer on output\"\n\t\t\tnil))\n  :group 'shell\n  :version \"26.1\")\n\n(defun shell-command--save-pos-or-erase ()\n  \"Store a buffer position or erase the buffer.\nSee `shell-command-dont-erase-buffer'.\"\n  (let ((sym shell-command-dont-erase-buffer)\n        pos)\n    (setq buffer-read-only nil)\n    ;; Setting buffer-read-only to nil doesn't suffice\n    ;; if some text has a non-nil read-only property,\n    ;; which comint sometimes adds for prompts.\n    (setq pos\n          (cond ((eq sym 'save-point) (point))\n                ((eq sym 'beg-last-out) (point-max))\n                ((not sym)\n                 (let ((inhibit-read-only t))\n                   (erase-buffer) nil))))\n    (when pos\n      (goto-char (point-max))\n      (push (cons (current-buffer) pos)\n            shell-command-saved-pos))))\n\n(defun shell-command--set-point-after-cmd (&optional buffer)\n  \"Set point in BUFFER after command complete.\nBUFFER is the output buffer of the command; if nil, then defaults\nto the current BUFFER.\nSet point to the `cdr' of the element in `shell-command-saved-pos'\nwhose `car' is BUFFER.\"\n  (when shell-command-dont-erase-buffer\n    (let* ((sym  shell-command-dont-erase-buffer)\n           (buf  (or buffer (current-buffer)))\n           (pos  (alist-get buf shell-command-saved-pos)))\n      (setq shell-command-saved-pos\n            (assq-delete-all buf shell-command-saved-pos))\n      (when (buffer-live-p buf)\n        (let ((win   (car (get-buffer-window-list buf)))\n              (pmax  (with-current-buffer buf (point-max))))\n          (unless (and pos (memq sym '(save-point beg-last-out)))\n            (setq pos pmax))\n          ;; Set point in the window displaying buf, if any; otherwise\n          ;; display buf temporary in selected frame and set the point.\n          (if win\n              (set-window-point win pos)\n            (save-window-excursion\n              (let ((win (display-buffer\n                          buf\n                          '(nil (inhibit-switch-frame . t)))))\n                (set-window-point win pos)))))))))\n\n(defun async-shell-command (command &optional output-buffer error-buffer)\n  \"Execute string COMMAND asynchronously in background.\n\nLike `shell-command', but adds `&' at the end of COMMAND\nto execute it asynchronously.\n\nThe output appears in the buffer `*Async Shell Command*'.\nThat buffer is in shell mode.\n\nYou can configure `async-shell-command-buffer' to specify what to do\nwhen the `*Async Shell Command*' buffer is already taken by another\nrunning shell command.  To run COMMAND without displaying the output\nin a window you can configure `display-buffer-alist' to use the action\n`display-buffer-no-window' for the buffer `*Async Shell Command*'.\n\nIn Elisp, you will often be better served by calling `start-process'\ndirectly, since it offers more control and does not impose the use of\na shell (with its need to quote arguments).\"\n  (interactive\n   (list\n    (read-shell-command \"Async shell command: \" nil nil\n\t\t\t(let ((filename\n\t\t\t       (cond\n\t\t\t\t(buffer-file-name)\n\t\t\t\t((eq major-mode 'dired-mode)\n\t\t\t\t (dired-get-filename nil t)))))\n\t\t\t  (and filename (file-relative-name filename))))\n    current-prefix-arg\n    shell-command-default-error-buffer))\n  (unless (string-match \"&[ \\t]*\\\\'\" command)\n    (setq command (concat command \" &\")))\n  (shell-command command output-buffer error-buffer))\n\n(defun shell-command (command &optional output-buffer error-buffer)\n  \"Execute string COMMAND in inferior shell; display output, if any.\nWith prefix argument, insert the COMMAND's output at point.\n\nInteractively, prompt for COMMAND in the minibuffer.\n\nIf COMMAND ends in `&', execute it asynchronously.\nThe output appears in the buffer `*Async Shell Command*'.\nThat buffer is in shell mode.  You can also use\n`async-shell-command' that automatically adds `&'.\n\nOtherwise, COMMAND is executed synchronously.  The output appears in\nthe buffer `*Shell Command Output*'.  If the output is short enough to\ndisplay in the echo area (which is determined by the variables\n`resize-mini-windows' and `max-mini-window-height'), it is shown\nthere, but it is nonetheless available in buffer `*Shell Command\nOutput*' even though that buffer is not automatically displayed.\n\nTo specify a coding system for converting non-ASCII characters\nin the shell command output, use \\\\[universal-coding-system-argument] \\\nbefore this command.\n\nNoninteractive callers can specify coding systems by binding\n`coding-system-for-read' and `coding-system-for-write'.\n\nThe optional second argument OUTPUT-BUFFER, if non-nil,\nsays to put the output in some other buffer.\nIf OUTPUT-BUFFER is a buffer or buffer name, erase that buffer\nand insert the output there; a non-nil value of\n`shell-command-dont-erase-buffer' prevents the buffer from being\nerased.  If OUTPUT-BUFFER is not a buffer and not nil, insert the\noutput in current buffer after point leaving mark after it.  This\ncannot be done asynchronously.\n\nIf the command terminates without error, but generates output,\nand you did not specify \\\"insert it in the current buffer\\\",\nthe output can be displayed in the echo area or in its buffer.\nIf the output is short enough to display in the echo area\n\\(determined by the variable `max-mini-window-height' if\n`resize-mini-windows' is non-nil), it is shown there.\nOtherwise, the buffer containing the output is displayed.\n\nIf there is output and an error, and you did not specify \\\"insert it\nin the current buffer\\\", a message about the error goes at the end\nof the output.\n\nIf the optional third argument ERROR-BUFFER is non-nil, it is a buffer\nor buffer name to which to direct the command's standard error output.\nIf it is nil, error output is mingled with regular output.\nIn an interactive call, the variable `shell-command-default-error-buffer'\nspecifies the value of ERROR-BUFFER.\n\nIn Elisp, you will often be better served by calling `call-process' or\n`start-process' directly, since they offer more control and do not\nimpose the use of a shell (with its need to quote arguments).\"\n\n  (interactive\n   (list\n    (read-shell-command \"Shell command: \" nil nil\n\t\t\t(let ((filename\n\t\t\t       (cond\n\t\t\t\t(buffer-file-name)\n\t\t\t\t((eq major-mode 'dired-mode)\n\t\t\t\t (dired-get-filename nil t)))))\n\t\t\t  (and filename (file-relative-name filename))))\n    current-prefix-arg\n    shell-command-default-error-buffer))\n  ;; Look for a handler in case default-directory is a remote file name.\n  (let ((handler\n\t (find-file-name-handler (directory-file-name default-directory)\n\t\t\t\t 'shell-command)))\n    (if handler\n\t(funcall handler 'shell-command command output-buffer error-buffer)\n      (if (and output-buffer\n\t       (not (or (bufferp output-buffer)  (stringp output-buffer))))\n\t  ;; Output goes in current buffer.\n\t  (let ((error-file\n\t\t (if error-buffer\n\t\t     (make-temp-file\n\t\t      (expand-file-name \"scor\"\n\t\t\t\t\t(or small-temporary-file-directory\n\t\t\t\t\t    temporary-file-directory)))\n\t\t   nil)))\n\t    (barf-if-buffer-read-only)\n\t    (push-mark nil t)\n\t    ;; We do not use -f for csh; we will not support broken use of\n\t    ;; .cshrcs.  Even the BSD csh manual says to use\n\t    ;; \"if ($?prompt) exit\" before things which are not useful\n\t    ;; non-interactively.  Besides, if someone wants their other\n\t    ;; aliases for shell commands then they can still have them.\n\t    (call-process shell-file-name nil\n\t\t\t  (if error-file\n\t\t\t      (list t error-file)\n\t\t\t    t)\n\t\t\t  nil shell-command-switch command)\n\t    (when (and error-file (file-exists-p error-file))\n\t      (if (< 0 (nth 7 (file-attributes error-file)))\n\t\t  (with-current-buffer (get-buffer-create error-buffer)\n\t\t    (let ((pos-from-end (- (point-max) (point))))\n\t\t      (or (bobp)\n\t\t\t  (insert \"\\f\\n\"))\n\t\t      ;; Do no formatting while reading error file,\n\t\t      ;; because that can run a shell command, and we\n\t\t      ;; don't want that to cause an infinite recursion.\n\t\t      (format-insert-file error-file nil)\n\t\t      ;; Put point after the inserted errors.\n\t\t      (goto-char (- (point-max) pos-from-end)))\n\t\t    (display-buffer (current-buffer))))\n\t      (delete-file error-file))\n\t    ;; This is like exchange-point-and-mark, but doesn't\n\t    ;; activate the mark.  It is cleaner to avoid activation,\n\t    ;; even though the command loop would deactivate the mark\n\t    ;; because we inserted text.\n\t    (goto-char (prog1 (mark t)\n\t\t\t (set-marker (mark-marker) (point)\n\t\t\t\t     (current-buffer)))))\n\t;; Output goes in a separate buffer.\n\t;; Preserve the match data in case called from a program.\n        ;; FIXME: It'd be ridiculous for an Elisp function to call\n        ;; shell-command and assume that it won't mess the match-data!\n\t(save-match-data\n\t  (if (string-match \"[ \\t]*&[ \\t]*\\\\'\" command)\n\t      ;; Command ending with ampersand means asynchronous.\n              (let* ((buffer (get-buffer-create\n                              (or output-buffer \"*Async Shell Command*\")))\n                     (bname (buffer-name buffer))\n                     (directory default-directory)\n                     proc)\n\t\t;; Remove the ampersand.\n\t\t(setq command (substring command 0 (match-beginning 0)))\n\t\t;; Ask the user what to do with already running process.\n\t\t(setq proc (get-buffer-process buffer))\n\t\t(when proc\n\t\t  (cond\n\t\t   ((eq async-shell-command-buffer 'confirm-kill-process)\n\t\t    ;; If will kill a process, query first.\n\t\t    (if (yes-or-no-p \"A command is running in the default buffer.  Kill it? \")\n\t\t\t(kill-process proc)\n\t\t      (error \"Shell command in progress\")))\n\t\t   ((eq async-shell-command-buffer 'confirm-new-buffer)\n\t\t    ;; If will create a new buffer, query first.\n\t\t    (if (yes-or-no-p \"A command is running in the default buffer.  Use a new buffer? \")\n                        (setq buffer (generate-new-buffer bname))\n\t\t      (error \"Shell command in progress\")))\n\t\t   ((eq async-shell-command-buffer 'new-buffer)\n\t\t    ;; It will create a new buffer.\n                    (setq buffer (generate-new-buffer bname)))\n\t\t   ((eq async-shell-command-buffer 'confirm-rename-buffer)\n\t\t    ;; If will rename the buffer, query first.\n\t\t    (if (yes-or-no-p \"A command is running in the default buffer.  Rename it? \")\n\t\t\t(progn\n\t\t\t  (with-current-buffer buffer\n\t\t\t    (rename-uniquely))\n                          (setq buffer (get-buffer-create bname)))\n\t\t      (error \"Shell command in progress\")))\n\t\t   ((eq async-shell-command-buffer 'rename-buffer)\n\t\t    ;; It will rename the buffer.\n\t\t    (with-current-buffer buffer\n\t\t      (rename-uniquely))\n                    (setq buffer (get-buffer-create bname)))))\n\t\t(with-current-buffer buffer\n                  (shell-command--save-pos-or-erase)\n\t\t  (setq default-directory directory)\n\t\t  (setq proc (start-process \"Shell\" buffer shell-file-name\n\t\t\t\t\t    shell-command-switch command))\n\t\t  (setq mode-line-process '(\":%s\"))\n\t\t  (require 'shell) (shell-mode)\n\t\t  (set-process-sentinel proc 'shell-command-sentinel)\n\t\t  ;; Use the comint filter for proper handling of\n\t\t  ;; carriage motion (see comint-inhibit-carriage-motion).\n\t\t  (set-process-filter proc 'comint-output-filter)\n                  (if async-shell-command-display-buffer\n                      ;; Display buffer immediately.\n                      (display-buffer buffer '(nil (allow-no-window . t)))\n                    ;; Defer displaying buffer until first process output.\n                    ;; Use disposable named advice so that the buffer is\n                    ;; displayed at most once per process lifetime.\n                    (let ((nonce (make-symbol \"nonce\")))\n                      (add-function :before (process-filter proc)\n                                    (lambda (proc _string)\n                                      (let ((buf (process-buffer proc)))\n                                        (when (buffer-live-p buf)\n                                          (remove-function (process-filter proc)\n                                                           nonce)\n                                          (display-buffer buf))))\n                                    `((name . ,nonce)))))))\n\t    ;; Otherwise, command is executed synchronously.\n\t    (shell-command-on-region (point) (point) command\n\t\t\t\t     output-buffer nil error-buffer)))))))\n\n(defun display-message-or-buffer (message &optional buffer-name action frame)\n  \"Display MESSAGE in the echo area if possible, otherwise in a pop-up buffer.\nMESSAGE may be either a string or a buffer.\n\nA pop-up buffer is displayed using `display-buffer' if MESSAGE is too long\nfor maximum height of the echo area, as defined by `max-mini-window-height'\nif `resize-mini-windows' is non-nil.\n\nReturns either the string shown in the echo area, or when a pop-up\nbuffer is used, the window used to display it.\n\nIf MESSAGE is a string, then the optional argument BUFFER-NAME is the\nname of the buffer used to display it in the case where a pop-up buffer\nis used, defaulting to `*Message*'.  In the case where MESSAGE is a\nstring and it is displayed in the echo area, it is not specified whether\nthe contents are inserted into the buffer anyway.\n\nOptional arguments ACTION and FRAME are as for `display-buffer',\nand are only used if a pop-up buffer is displayed.\"\n  (cond ((and (stringp message) (not (string-match \"\\n\" message)))\n\t ;; Trivial case where we can use the echo area\n\t (message \"%s\" message))\n\t((and (stringp message)\n\t      (= (string-match \"\\n\" message) (1- (length message))))\n\t ;; Trivial case where we can just remove single trailing newline\n\t (message \"%s\" (substring message 0 (1- (length message)))))\n\t(t\n\t ;; General case\n\t (with-current-buffer\n\t     (if (bufferp message)\n\t\t message\n\t       (get-buffer-create (or buffer-name \"*Message*\")))\n\n\t   (unless (bufferp message)\n\t     (erase-buffer)\n\t     (insert message))\n\n\t   (let ((lines\n\t\t  (if (= (buffer-size) 0)\n\t\t      0\n\t\t    (count-screen-lines nil nil nil (minibuffer-window)))))\n\t     (cond ((= lines 0))\n\t\t   ((and (or (<= lines 1)\n\t\t\t     (<= lines\n\t\t\t\t (if resize-mini-windows\n\t\t\t\t     (cond ((floatp max-mini-window-height)\n\t\t\t\t\t    (* (frame-height)\n\t\t\t\t\t       max-mini-window-height))\n\t\t\t\t\t   ((integerp max-mini-window-height)\n\t\t\t\t\t    max-mini-window-height)\n\t\t\t\t\t   (t\n\t\t\t\t\t    1))\n\t\t\t\t   1)))\n\t\t\t ;; Don't use the echo area if the output buffer is\n\t\t\t ;; already displayed in the selected frame.\n\t\t\t (not (get-buffer-window (current-buffer))))\n\t\t    ;; Echo area\n\t\t    (goto-char (point-max))\n\t\t    (when (bolp)\n\t\t      (backward-char 1))\n\t\t    (message \"%s\" (buffer-substring (point-min) (point))))\n\t\t   (t\n\t\t    ;; Buffer\n\t\t    (goto-char (point-min))\n\t\t    (display-buffer (current-buffer) action frame))))))))\n\n\n;; We have a sentinel to prevent insertion of a termination message\n;; in the buffer itself, and to set the point in the buffer when\n;; `shell-command-dont-erase-buffer' is non-nil.\n(defun shell-command-sentinel (process signal)\n  (when (memq (process-status process) '(exit signal))\n    (shell-command--set-point-after-cmd (process-buffer process))\n    (message \"%s: %s.\"\n             (car (cdr (cdr (process-command process))))\n             (substring signal 0 -1))))\n\n(defun shell-command-on-region (start end command\n\t\t\t\t      &optional output-buffer replace\n\t\t\t\t      error-buffer display-error-buffer\n\t\t\t\t      region-noncontiguous-p)\n  \"Execute string COMMAND in inferior shell with region as input.\nNormally display output (if any) in temp buffer `*Shell Command Output*';\nPrefix arg means replace the region with it.  Return the exit code of\nCOMMAND.\n\nTo specify a coding system for converting non-ASCII characters\nin the input and output to the shell command, use \\\\[universal-coding-system-argument]\nbefore this command.  By default, the input (from the current buffer)\nis encoded using coding-system specified by `process-coding-system-alist',\nfalling back to `default-process-coding-system' if no match for COMMAND\nis found in `process-coding-system-alist'.\n\nNoninteractive callers can specify coding systems by binding\n`coding-system-for-read' and `coding-system-for-write'.\n\nIf the command generates output, the output may be displayed\nin the echo area or in a buffer.\nIf the output is short enough to display in the echo area\n\\(determined by the variable `max-mini-window-height' if\n`resize-mini-windows' is non-nil), it is shown there.\nOtherwise it is displayed in the buffer `*Shell Command Output*'.\nThe output is available in that buffer in both cases.\n\nIf there is output and an error, a message about the error\nappears at the end of the output.\n\nOptional fourth arg OUTPUT-BUFFER specifies where to put the\ncommand's output.  If the value is a buffer or buffer name,\nerase that buffer and insert the output there; a non-nil value of\n`shell-command-dont-erase-buffer' prevent to erase the buffer.\nIf the value is nil, use the buffer `*Shell Command Output*'.\nAny other non-nil value means to insert the output in the\ncurrent buffer after START.\n\nOptional fifth arg REPLACE, if non-nil, means to insert the\noutput in place of text from START to END, putting point and mark\naround it.\n\nOptional sixth arg ERROR-BUFFER, if non-nil, specifies a buffer\nor buffer name to which to direct the command's standard error\noutput.  If nil, error output is mingled with regular output.\nWhen called interactively, `shell-command-default-error-buffer'\nis used for ERROR-BUFFER.\n\nOptional seventh arg DISPLAY-ERROR-BUFFER, if non-nil, means to\ndisplay the error buffer if there were any errors.  When called\ninteractively, this is t.\"\n  (interactive (let (string)\n\t\t (unless (mark)\n\t\t   (user-error \"The mark is not set now, so there is no region\"))\n\t\t ;; Do this before calling region-beginning\n\t\t ;; and region-end, in case subprocess output\n\t\t ;; relocates them while we are in the minibuffer.\n\t\t (setq string (read-shell-command \"Shell command on region: \"))\n\t\t ;; call-interactively recognizes region-beginning and\n\t\t ;; region-end specially, leaving them in the history.\n\t\t (list (region-beginning) (region-end)\n\t\t       string\n\t\t       current-prefix-arg\n\t\t       current-prefix-arg\n\t\t       shell-command-default-error-buffer\n\t\t       t\n\t\t       (region-noncontiguous-p))))\n  (let ((error-file\n\t (if error-buffer\n\t     (make-temp-file\n\t      (expand-file-name \"scor\"\n\t\t\t\t(or small-temporary-file-directory\n\t\t\t\t    temporary-file-directory)))\n\t   nil))\n\texit-status)\n    ;; Unless a single contiguous chunk is selected, operate on multiple chunks.\n    (if region-noncontiguous-p\n        (let ((input (concat (funcall region-extract-function 'delete) \"\\n\"))\n              output)\n          (with-temp-buffer\n            (insert input)\n            (call-process-region (point-min) (point-max)\n                                 shell-file-name t t\n                                 nil shell-command-switch\n                                 command)\n            (setq output (split-string (buffer-string) \"\\n\")))\n          (goto-char start)\n          (funcall region-insert-function output))\n      (if (or replace\n              (and output-buffer\n                   (not (or (bufferp output-buffer) (stringp output-buffer)))))\n          ;; Replace specified region with output from command.\n          (let ((swap (and replace (< start end))))\n            ;; Don't muck with mark unless REPLACE says we should.\n            (goto-char start)\n            (and replace (push-mark (point) 'nomsg))\n            (setq exit-status\n                  (call-shell-region start end command replace\n                                       (if error-file\n                                           (list t error-file)\n                                         t)))\n            ;; It is rude to delete a buffer which the command is not using.\n            ;; (let ((shell-buffer (get-buffer \"*Shell Command Output*\")))\n            ;;   (and shell-buffer (not (eq shell-buffer (current-buffer)))\n            ;; \t (kill-buffer shell-buffer)))\n            ;; Don't muck with mark unless REPLACE says we should.\n            (and replace swap (exchange-point-and-mark)))\n        ;; No prefix argument: put the output in a temp buffer,\n        ;; replacing its entire contents.\n        (let ((buffer (get-buffer-create\n                       (or output-buffer \"*Shell Command Output*\"))))\n          (unwind-protect\n              (if (and (eq buffer (current-buffer))\n                       (or (not shell-command-dont-erase-buffer)\n                           (and (not (eq buffer (get-buffer \"*Shell Command Output*\")))\n                                (not (region-active-p)))))\n                  ;; If the input is the same buffer as the output,\n                  ;; delete everything but the specified region,\n                  ;; then replace that region with the output.\n                  (progn (setq buffer-read-only nil)\n                         (delete-region (max start end) (point-max))\n                         (delete-region (point-min) (min start end))\n                         (setq exit-status\n                               (call-process-region (point-min) (point-max)\n                                                    shell-file-name t\n                                                    (if error-file\n                                                        (list t error-file)\n                                                      t)\n                                                    nil shell-command-switch\n                                                    command)))\n                ;; Clear the output buffer, then run the command with\n                ;; output there.\n                (let ((directory default-directory))\n                  (with-current-buffer buffer\n                    (if (not output-buffer)\n                        (setq default-directory directory))\n                    (shell-command--save-pos-or-erase)))\n                (setq exit-status\n                      (call-shell-region start end command nil\n                                           (if error-file\n                                               (list buffer error-file)\n                                             buffer))))\n            ;; Report the output.\n            (with-current-buffer buffer\n              (setq mode-line-process\n                    (cond ((null exit-status)\n                           \" - Error\")\n                          ((stringp exit-status)\n                           (format \" - Signal [%s]\" exit-status))\n                          ((not (equal 0 exit-status))\n                           (format \" - Exit [%d]\" exit-status)))))\n            (if (with-current-buffer buffer (> (point-max) (point-min)))\n                ;; There's some output, display it\n                (progn\n                  (display-message-or-buffer buffer)\n                  (shell-command--set-point-after-cmd buffer))\n            ;; No output; error?\n              (let ((output\n                     (if (and error-file\n                              (< 0 (nth 7 (file-attributes error-file))))\n                         (format \"some error output%s\"\n                                 (if shell-command-default-error-buffer\n                                     (format \" to the \\\"%s\\\" buffer\"\n                                             shell-command-default-error-buffer)\n                                   \"\"))\n                       \"no output\")))\n                (cond ((null exit-status)\n                       (message \"(Shell command failed with error)\"))\n                      ((equal 0 exit-status)\n                       (message \"(Shell command succeeded with %s)\"\n                                output))\n                      ((stringp exit-status)\n                       (message \"(Shell command killed by signal %s)\"\n                                exit-status))\n                      (t\n                       (message \"(Shell command failed with code %d and %s)\"\n                                exit-status output))))\n              ;; Don't kill: there might be useful info in the undo-log.\n              ;; (kill-buffer buffer)\n              )))))\n\n    (when (and error-file (file-exists-p error-file))\n      (if (< 0 (nth 7 (file-attributes error-file)))\n\t  (with-current-buffer (get-buffer-create error-buffer)\n\t    (let ((pos-from-end (- (point-max) (point))))\n\t      (or (bobp)\n\t\t  (insert \"\\f\\n\"))\n\t      ;; Do no formatting while reading error file,\n\t      ;; because that can run a shell command, and we\n\t      ;; don't want that to cause an infinite recursion.\n\t      (format-insert-file error-file nil)\n\t      ;; Put point after the inserted errors.\n\t      (goto-char (- (point-max) pos-from-end)))\n\t    (and display-error-buffer\n\t\t (display-buffer (current-buffer)))))\n      (delete-file error-file))\n    exit-status))\n\n(defun shell-command-to-string (command)\n  \"Execute shell command COMMAND and return its output as a string.\"\n  (with-output-to-string\n    (with-current-buffer\n      standard-output\n      (process-file shell-file-name nil t nil shell-command-switch command))))\n\n(defun process-file (program &optional infile buffer display &rest args)\n  \"Process files synchronously in a separate process.\nSimilar to `call-process', but may invoke a file handler based on\n`default-directory'.  The current working directory of the\nsubprocess is `default-directory'.\n\nFile names in INFILE and BUFFER are handled normally, but file\nnames in ARGS should be relative to `default-directory', as they\nare passed to the process verbatim.  (This is a difference to\n`call-process' which does not support file handlers for INFILE\nand BUFFER.)\n\nSome file handlers might not support all variants, for example\nthey might behave as if DISPLAY was nil, regardless of the actual\nvalue passed.\"\n  (let ((fh (find-file-name-handler default-directory 'process-file))\n        lc stderr-file)\n    (unwind-protect\n        (if fh (apply fh 'process-file program infile buffer display args)\n          (when infile (setq lc (file-local-copy infile)))\n          (setq stderr-file (when (and (consp buffer) (stringp (cadr buffer)))\n                              (make-temp-file \"emacs\")))\n          (prog1\n              (apply 'call-process program\n                     (or lc infile)\n                     (if stderr-file (list (car buffer) stderr-file) buffer)\n                     display args)\n            (when stderr-file (copy-file stderr-file (cadr buffer) t))))\n      (when stderr-file (delete-file stderr-file))\n      (when lc (delete-file lc)))))\n\n(defvar process-file-side-effects t\n  \"Whether a call of `process-file' changes remote files.\n\nBy default, this variable is always set to t, meaning that a\ncall of `process-file' could potentially change any file on a\nremote host.  When set to nil, a file handler could optimize\nits behavior with respect to remote file attribute caching.\n\nYou should only ever change this variable with a let-binding;\nnever with `setq'.\")\n\n(defun start-file-process (name buffer program &rest program-args)\n  \"Start a program in a subprocess.  Return the process object for it.\n\nSimilar to `start-process', but may invoke a file handler based on\n`default-directory'.  See Info node `(elisp)Magic File Names'.\n\nThis handler ought to run PROGRAM, perhaps on the local host,\nperhaps on a remote host that corresponds to `default-directory'.\nIn the latter case, the local part of `default-directory' becomes\nthe working directory of the process.\n\nPROGRAM and PROGRAM-ARGS might be file names.  They are not\nobjects of file handler invocation.  File handlers might not\nsupport pty association, if PROGRAM is nil.\"\n  (let ((fh (find-file-name-handler default-directory 'start-file-process)))\n    (if fh (apply fh 'start-file-process name buffer program program-args)\n      (apply 'start-process name buffer program program-args))))\n\f\n;;;; Process menu\n\n(defvar tabulated-list-format)\n(defvar tabulated-list-entries)\n(defvar tabulated-list-sort-key)\n(declare-function tabulated-list-init-header  \"tabulated-list\" ())\n(declare-function tabulated-list-print \"tabulated-list\"\n                  (&optional remember-pos update))\n\n(defvar process-menu-query-only nil)\n\n(defvar process-menu-mode-map\n  (let ((map (make-sparse-keymap)))\n    (define-key map [?d] 'process-menu-delete-process)\n    map))\n\n(define-derived-mode process-menu-mode tabulated-list-mode \"Process Menu\"\n  \"Major mode for listing the processes called by Emacs.\"\n  (setq tabulated-list-format [(\"Process\" 15 t)\n\t\t\t       (\"PID\"      7 t)\n\t\t\t       (\"Status\"   7 t)\n\t\t\t       (\"Buffer\"  15 t)\n\t\t\t       (\"TTY\"     12 t)\n\t\t\t       (\"Command\"  0 t)])\n  (make-local-variable 'process-menu-query-only)\n  (setq tabulated-list-sort-key (cons \"Process\" nil))\n  (add-hook 'tabulated-list-revert-hook 'list-processes--refresh nil t))\n\n(defun process-menu-delete-process ()\n  \"Kill process at point in a `list-processes' buffer.\"\n  (interactive)\n  (let ((pos (point)))\n    (delete-process (tabulated-list-get-id))\n    (revert-buffer)\n    (goto-char (min pos (point-max)))\n    (if (eobp)\n        (forward-line -1)\n      (beginning-of-line))))\n\n(defun list-processes--refresh ()\n  \"Recompute the list of processes for the Process List buffer.\nAlso, delete any process that is exited or signaled.\"\n  (setq tabulated-list-entries nil)\n  (dolist (p (process-list))\n    (cond ((memq (process-status p) '(exit signal closed))\n\t   (delete-process p))\n\t  ((or (not process-menu-query-only)\n\t       (process-query-on-exit-flag p))\n\t   (let* ((buf (process-buffer p))\n\t\t  (type (process-type p))\n\t\t  (pid  (if (process-id p) (format \"%d\" (process-id p)) \"--\"))\n\t\t  (name (process-name p))\n\t\t  (status (symbol-name (process-status p)))\n\t\t  (buf-label (if (buffer-live-p buf)\n\t\t\t\t `(,(buffer-name buf)\n\t\t\t\t   face link\n\t\t\t\t   help-echo ,(format-message\n\t\t\t\t\t       \"Visit buffer `%s'\"\n\t\t\t\t\t       (buffer-name buf))\n\t\t\t\t   follow-link t\n\t\t\t\t   process-buffer ,buf\n\t\t\t\t   action process-menu-visit-buffer)\n\t\t\t       \"--\"))\n\t\t  (tty (or (process-tty-name p) \"--\"))\n\t\t  (cmd\n\t\t   (if (memq type '(network serial))\n\t\t       (let ((contact (process-contact p t)))\n\t\t\t (if (eq type 'network)\n\t\t\t     (format \"(%s %s)\"\n\t\t\t\t     (if (plist-get contact :type)\n\t\t\t\t\t \"datagram\"\n\t\t\t\t       \"network\")\n\t\t\t\t     (if (plist-get contact :server)\n\t\t\t\t\t (format \"server on %s\"\n\t\t\t\t\t\t (or\n\t\t\t\t\t\t  (plist-get contact :host)\n\t\t\t\t\t\t  (plist-get contact :local)))\n\t\t\t\t       (format \"connection to %s\"\n\t\t\t\t\t       (plist-get contact :host))))\n\t\t\t   (format \"(serial port %s%s)\"\n\t\t\t\t   (or (plist-get contact :port) \"?\")\n\t\t\t\t   (let ((speed (plist-get contact :speed)))\n\t\t\t\t     (if speed\n\t\t\t\t\t (format \" at %s b/s\" speed)\n\t\t\t\t       \"\")))))\n\t\t     (mapconcat 'identity (process-command p) \" \"))))\n\t     (push (list p (vector name pid status buf-label tty cmd))\n\t\t   tabulated-list-entries)))))\n  (tabulated-list-init-header))\n\n(defun process-menu-visit-buffer (button)\n  (display-buffer (button-get button 'process-buffer)))\n\n(defun list-processes (&optional query-only buffer)\n  \"Display a list of all processes that are Emacs sub-processes.\nIf optional argument QUERY-ONLY is non-nil, only processes with\nthe query-on-exit flag set are listed.\nAny process listed as exited or signaled is actually eliminated\nafter the listing is made.\nOptional argument BUFFER specifies a buffer to use, instead of\n\\\"*Process List*\\\".\nThe return value is always nil.\n\nThis function lists only processes that were launched by Emacs.  To\nsee other processes running on the system, use `list-system-processes'.\"\n  (interactive)\n  (or (fboundp 'process-list)\n      (error \"Asynchronous subprocesses are not supported on this system\"))\n  (unless (bufferp buffer)\n    (setq buffer (get-buffer-create \"*Process List*\")))\n  (with-current-buffer buffer\n    (process-menu-mode)\n    (setq process-menu-query-only query-only)\n    (list-processes--refresh)\n    (tabulated-list-print))\n  (display-buffer buffer)\n  nil)\n\f\n;;;; Prefix commands\n\n(setq prefix-command--needs-update nil)\n(setq prefix-command--last-echo nil)\n\n(defun internal-echo-keystrokes-prefix ()\n  ;; BEWARE: Called directly from C code.\n  ;; If the return value is non-nil, it means we are in the middle of\n  ;; a command with prefix, such as a command invoked with prefix-arg.\n  (if (not prefix-command--needs-update)\n      prefix-command--last-echo\n    (setq prefix-command--last-echo\n          (let ((strs nil))\n            (run-hook-wrapped 'prefix-command-echo-keystrokes-functions\n                              (lambda (fun) (push (funcall fun) strs)))\n            (setq strs (delq nil strs))\n            (when strs (mapconcat #'identity strs \" \"))))))\n\n(defvar prefix-command-echo-keystrokes-functions nil\n  \"Abnormal hook which constructs the description of the current prefix state.\nEach function is called with no argument, should return a string or nil.\")\n\n(defun prefix-command-update ()\n  \"Update state of prefix commands.\nCall it whenever you change the \\\"prefix command state\\\".\"\n  (setq prefix-command--needs-update t))\n\n(defvar prefix-command-preserve-state-hook nil\n  \"Normal hook run when a command needs to preserve the prefix.\")\n\n(defun prefix-command-preserve-state ()\n  \"Pass the current prefix command state to the next command.\nShould be called by all prefix commands.\nRuns `prefix-command-preserve-state-hook'.\"\n  (run-hooks 'prefix-command-preserve-state-hook)\n  ;; If the current command is a prefix command, we don't want the next (real)\n  ;; command to have `last-command' set to, say, `universal-argument'.\n  (setq this-command last-command)\n  (setq real-this-command real-last-command)\n  (prefix-command-update))\n\n(defun reset-this-command-lengths ()\n  (declare (obsolete prefix-command-preserve-state \"25.1\"))\n  nil)\n\n;;;;; The main prefix command.\n\n;; FIXME: Declaration of `prefix-arg' should be moved here!?\n\n(add-hook 'prefix-command-echo-keystrokes-functions\n          #'universal-argument--description)\n(defun universal-argument--description ()\n  (when prefix-arg\n    (concat \"C-u\"\n            (pcase prefix-arg\n              (`(-) \" -\")\n              (`(,(and (pred integerp) n))\n               (let ((str \"\"))\n                 (while (and (> n 4) (= (mod n 4) 0))\n                   (setq str (concat str \" C-u\"))\n                   (setq n (/ n 4)))\n                 (if (= n 4) str (format \" %s\" prefix-arg))))\n              (_ (format \" %s\" prefix-arg))))))\n\n(add-hook 'prefix-command-preserve-state-hook\n          #'universal-argument--preserve)\n(defun universal-argument--preserve ()\n  (setq prefix-arg current-prefix-arg))\n\n(defvar universal-argument-map\n  (let ((map (make-sparse-keymap))\n        (universal-argument-minus\n         ;; For backward compatibility, minus with no modifiers is an ordinary\n         ;; command if digits have already been entered.\n         `(menu-item \"\" negative-argument\n                     :filter ,(lambda (cmd)\n                                (if (integerp prefix-arg) nil cmd)))))\n    (define-key map [switch-frame]\n      (lambda (e) (interactive \"e\")\n        (handle-switch-frame e) (universal-argument--mode)))\n    (define-key map [?\\C-u] 'universal-argument-more)\n    (define-key map [?-] universal-argument-minus)\n    (define-key map [?0] 'digit-argument)\n    (define-key map [?1] 'digit-argument)\n    (define-key map [?2] 'digit-argument)\n    (define-key map [?3] 'digit-argument)\n    (define-key map [?4] 'digit-argument)\n    (define-key map [?5] 'digit-argument)\n    (define-key map [?6] 'digit-argument)\n    (define-key map [?7] 'digit-argument)\n    (define-key map [?8] 'digit-argument)\n    (define-key map [?9] 'digit-argument)\n    (define-key map [kp-0] 'digit-argument)\n    (define-key map [kp-1] 'digit-argument)\n    (define-key map [kp-2] 'digit-argument)\n    (define-key map [kp-3] 'digit-argument)\n    (define-key map [kp-4] 'digit-argument)\n    (define-key map [kp-5] 'digit-argument)\n    (define-key map [kp-6] 'digit-argument)\n    (define-key map [kp-7] 'digit-argument)\n    (define-key map [kp-8] 'digit-argument)\n    (define-key map [kp-9] 'digit-argument)\n    (define-key map [kp-subtract] universal-argument-minus)\n    map)\n  \"Keymap used while processing \\\\[universal-argument].\")\n\n(defun universal-argument--mode ()\n  (prefix-command-update)\n  (set-transient-map universal-argument-map nil))\n\n(defun universal-argument ()\n  \"Begin a numeric argument for the following command.\nDigits or minus sign following \\\\[universal-argument] make up the numeric argument.\n\\\\[universal-argument] following the digits or minus sign ends the argument.\n\\\\[universal-argument] without digits or minus sign provides 4 as argument.\nRepeating \\\\[universal-argument] without digits or minus sign\n multiplies the argument by 4 each time.\nFor some commands, just \\\\[universal-argument] by itself serves as a flag\nwhich is different in effect from any particular numeric argument.\nThese commands include \\\\[set-mark-command] and \\\\[start-kbd-macro].\"\n  (interactive)\n  (prefix-command-preserve-state)\n  (setq prefix-arg (list 4))\n  (universal-argument--mode))\n\n(defun universal-argument-more (arg)\n  ;; A subsequent C-u means to multiply the factor by 4 if we've typed\n  ;; nothing but C-u's; otherwise it means to terminate the prefix arg.\n  (interactive \"P\")\n  (prefix-command-preserve-state)\n  (setq prefix-arg (if (consp arg)\n                       (list (* 4 (car arg)))\n                     (if (eq arg '-)\n                         (list -4)\n                       arg)))\n  (when (consp prefix-arg) (universal-argument--mode)))\n\n(defun negative-argument (arg)\n  \"Begin a negative numeric argument for the next command.\n\\\\[universal-argument] following digits or minus sign ends the argument.\"\n  (interactive \"P\")\n  (prefix-command-preserve-state)\n  (setq prefix-arg (cond ((integerp arg) (- arg))\n                         ((eq arg '-) nil)\n                         (t '-)))\n  (universal-argument--mode))\n\n(defun digit-argument (arg)\n  \"Part of the numeric argument for the next command.\n\\\\[universal-argument] following digits or minus sign ends the argument.\"\n  (interactive \"P\")\n  (prefix-command-preserve-state)\n  (let* ((char (if (integerp last-command-event)\n\t\t   last-command-event\n\t\t (get last-command-event 'ascii-character)))\n\t (digit (- (logand char ?\\177) ?0)))\n    (setq prefix-arg (cond ((integerp arg)\n                            (+ (* arg 10)\n\t\t\t       (if (< arg 0) (- digit) digit)))\n                           ((eq arg '-)\n                            ;; Treat -0 as just -, so that -01 will work.\n                            (if (zerop digit) '- (- digit)))\n                           (t\n                            digit))))\n  (universal-argument--mode))\n\f\n\n(defvar filter-buffer-substring-functions nil\n  \"This variable is a wrapper hook around `buffer-substring--filter'.\n\\(See `with-wrapper-hook' for details about wrapper hooks.)\")\n(make-obsolete-variable 'filter-buffer-substring-functions\n                        'filter-buffer-substring-function \"24.4\")\n\n(defvar filter-buffer-substring-function #'buffer-substring--filter\n  \"Function to perform the filtering in `filter-buffer-substring'.\nThe function is called with the same 3 arguments (BEG END DELETE)\nthat `filter-buffer-substring' received.  It should return the\nbuffer substring between BEG and END, after filtering.  If DELETE is\nnon-nil, it should delete the text between BEG and END from the buffer.\")\n\n(defvar buffer-substring-filters nil\n  \"List of filter functions for `buffer-substring--filter'.\nEach function must accept a single argument, a string, and return a string.\nThe buffer substring is passed to the first function in the list,\nand the return value of each function is passed to the next.\nAs a special convention, point is set to the start of the buffer text\nbeing operated on (i.e., the first argument of `buffer-substring--filter')\nbefore these functions are called.\")\n(make-obsolete-variable 'buffer-substring-filters\n                        'filter-buffer-substring-function \"24.1\")\n\n(defun filter-buffer-substring (beg end &optional delete)\n  \"Return the buffer substring between BEG and END, after filtering.\nIf DELETE is non-nil, delete the text between BEG and END from the buffer.\n\nThis calls the function that `filter-buffer-substring-function' specifies\n\\(passing the same three arguments that it received) to do the work,\nand returns whatever it does.  The default function does no filtering,\nunless a hook has been set.\n\nUse `filter-buffer-substring' instead of `buffer-substring',\n`buffer-substring-no-properties', or `delete-and-extract-region' when\nyou want to allow filtering to take place.  For example, major or minor\nmodes can use `filter-buffer-substring-function' to extract characters\nthat are special to a buffer, and should not be copied into other buffers.\"\n  (funcall filter-buffer-substring-function beg end delete))\n\n(defun buffer-substring--filter (beg end &optional delete)\n  \"Default function to use for `filter-buffer-substring-function'.\nIts arguments and return value are as specified for `filter-buffer-substring'.\nAlso respects the obsolete wrapper hook `filter-buffer-substring-functions'\n\\(see `with-wrapper-hook' for details about wrapper hooks),\nand the abnormal hook `buffer-substring-filters'.\nNo filtering is done unless a hook says to.\"\n  (subr--with-wrapper-hook-no-warnings\n    filter-buffer-substring-functions (beg end delete)\n    (cond\n     ((or delete buffer-substring-filters)\n      (save-excursion\n        (goto-char beg)\n        (let ((string (if delete (delete-and-extract-region beg end)\n                        (buffer-substring beg end))))\n          (dolist (filter buffer-substring-filters)\n            (setq string (funcall filter string)))\n          string)))\n     (t\n      (buffer-substring beg end)))))\n\n\n;;;; Window system cut and paste hooks.\n\n(defvar interprogram-cut-function #'gui-select-text\n  \"Function to call to make a killed region available to other programs.\nMost window systems provide a facility for cutting and pasting\ntext between different programs, such as the clipboard on X and\nMS-Windows, or the pasteboard on Nextstep/Mac OS.\n\nThis variable holds a function that Emacs calls whenever text is\nput in the kill ring, to make the new kill available to other\nprograms.  The function takes one argument, TEXT, which is a\nstring containing the text which should be made available.\")\n\n(defvar interprogram-paste-function #'gui-selection-value\n  \"Function to call to get text cut from other programs.\nMost window systems provide a facility for cutting and pasting\ntext between different programs, such as the clipboard on X and\nMS-Windows, or the pasteboard on Nextstep/Mac OS.\n\nThis variable holds a function that Emacs calls to obtain text\nthat other programs have provided for pasting.  The function is\ncalled with no arguments.  If no other program has provided text\nto paste, the function should return nil (in which case the\ncaller, usually `current-kill', should use the top of the Emacs\nkill ring).  If another program has provided text to paste, the\nfunction should return that text as a string (in which case the\ncaller should put this string in the kill ring as the latest\nkill).\n\nThe function may also return a list of strings if the window\nsystem supports multiple selections.  The first string will be\nused as the pasted text, but the other will be placed in the kill\nring for easy access via `yank-pop'.\n\nNote that the function should return a string only if a program\nother than Emacs has provided a string for pasting; if Emacs\nprovided the most recent string, the function should return nil.\nIf it is difficult to tell whether Emacs or some other program\nprovided the current string, it is probably good enough to return\nnil if the string is equal (according to `string=') to the last\ntext Emacs provided.\")\n\f\n\n\n;;;; The kill ring data structure.\n\n(defvar kill-ring nil\n  \"List of killed text sequences.\nSince the kill ring is supposed to interact nicely with cut-and-paste\nfacilities offered by window systems, use of this variable should\ninteract nicely with `interprogram-cut-function' and\n`interprogram-paste-function'.  The functions `kill-new',\n`kill-append', and `current-kill' are supposed to implement this\ninteraction; you may want to use them instead of manipulating the kill\nring directly.\")\n\n(defcustom kill-ring-max 60\n  \"Maximum length of kill ring before oldest elements are thrown away.\"\n  :type 'integer\n  :group 'killing)\n\n(defvar kill-ring-yank-pointer nil\n  \"The tail of the kill ring whose car is the last thing yanked.\")\n\n(defcustom save-interprogram-paste-before-kill nil\n  \"Save existing clipboard text into kill ring before replacing it.\nA non-nil value ensures that Emacs kill operations do not\nirrevocably overwrite existing clipboard text by saving it to the\n`kill-ring' prior to the kill.  Such text can subsequently be\nretrieved via \\\\[yank] \\\\[yank-pop]].\"\n  :type 'boolean\n  :group 'killing\n  :version \"23.2\")\n\n(defcustom kill-do-not-save-duplicates nil\n  \"Do not add a new string to `kill-ring' if it duplicates the last one.\nThe comparison is done using `equal-including-properties'.\"\n  :type 'boolean\n  :group 'killing\n  :version \"23.2\")\n\n(defun kill-new (string &optional replace)\n  \"Make STRING the latest kill in the kill ring.\nSet `kill-ring-yank-pointer' to point to it.\nIf `interprogram-cut-function' is non-nil, apply it to STRING.\nOptional second argument REPLACE non-nil means that STRING will replace\nthe front of the kill ring, rather than being added to the list.\n\nWhen `save-interprogram-paste-before-kill' and `interprogram-paste-function'\nare non-nil, save the interprogram paste string(s) into `kill-ring' before\nSTRING.\n\nWhen the yank handler has a non-nil PARAM element, the original STRING\nargument is not used by `insert-for-yank'.  However, since Lisp code\nmay access and use elements from the kill ring directly, the STRING\nargument should still be a \\\"useful\\\" string for such uses.\"\n  (unless (and kill-do-not-save-duplicates\n\t       ;; Due to text properties such as 'yank-handler that\n\t       ;; can alter the contents to yank, comparison using\n\t       ;; `equal' is unsafe.\n\t       (equal-including-properties string (car kill-ring)))\n    (if (fboundp 'menu-bar-update-yank-menu)\n\t(menu-bar-update-yank-menu string (and replace (car kill-ring)))))\n  (when save-interprogram-paste-before-kill\n    (let ((interprogram-paste (and interprogram-paste-function\n                                   (funcall interprogram-paste-function))))\n      (when interprogram-paste\n        (dolist (s (if (listp interprogram-paste)\n\t\t       (nreverse interprogram-paste)\n\t\t     (list interprogram-paste)))\n\t  (unless (and kill-do-not-save-duplicates\n\t\t       (equal-including-properties s (car kill-ring)))\n\t    (push s kill-ring))))))\n  (unless (and kill-do-not-save-duplicates\n\t       (equal-including-properties string (car kill-ring)))\n    (if (and replace kill-ring)\n\t(setcar kill-ring string)\n      (push string kill-ring)\n      (if (> (length kill-ring) kill-ring-max)\n\t  (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))))\n  (setq kill-ring-yank-pointer kill-ring)\n  (if interprogram-cut-function\n      (funcall interprogram-cut-function string)))\n\n;; It has been argued that this should work like `self-insert-command'\n;; which merges insertions in `buffer-undo-list' in groups of 20\n;; (hard-coded in `undo-auto-amalgamate').\n(defcustom kill-append-merge-undo nil\n  \"Amalgamate appending kills with the last kill for undo.\nWhen non-nil, appending or prepending text to the last kill makes\n\\\\[undo] restore both pieces of text simultaneously.\"\n  :type 'boolean\n  :group 'killing\n  :version \"25.1\")\n\n(defun kill-append (string before-p)\n  \"Append STRING to the end of the latest kill in the kill ring.\nIf BEFORE-P is non-nil, prepend STRING to the kill instead.\nIf `interprogram-cut-function' is non-nil, call it with the\nresulting kill.\nIf `kill-append-merge-undo' is non-nil, remove the last undo\nboundary in the current buffer.\"\n  (let* ((cur (car kill-ring)))\n    (kill-new (if before-p (concat string cur) (concat cur string))\n\t      (or (= (length cur) 0)\n\t\t  (equal nil (get-text-property 0 'yank-handler cur))))\n    (when (and kill-append-merge-undo (not buffer-read-only))\n      (let ((prev buffer-undo-list)\n            (next (cdr buffer-undo-list)))\n        ;; find the next undo boundary\n        (while (car next)\n          (pop next)\n          (pop prev))\n        ;; remove this undo boundary\n        (when prev\n          (setcdr prev (cdr next)))))))\n\n(defcustom yank-pop-change-selection nil\n  \"Whether rotating the kill ring changes the window system selection.\nIf non-nil, whenever the kill ring is rotated (usually via the\n`yank-pop' command), Emacs also calls `interprogram-cut-function'\nto copy the new kill to the window system selection.\"\n  :type 'boolean\n  :group 'killing\n  :version \"23.1\")\n\n(defun current-kill (n &optional do-not-move)\n  \"Rotate the yanking point by N places, and then return that kill.\nIf N is zero and `interprogram-paste-function' is set to a\nfunction that returns a string or a list of strings, and if that\nfunction doesn't return nil, then that string (or list) is added\nto the front of the kill ring and the string (or first string in\nthe list) is returned as the latest kill.\n\nIf N is not zero, and if `yank-pop-change-selection' is\nnon-nil, use `interprogram-cut-function' to transfer the\nkill at the new yank point into the window system selection.\n\nIf optional arg DO-NOT-MOVE is non-nil, then don't actually\nmove the yanking point; just return the Nth kill forward.\"\n\n  (let ((interprogram-paste (and (= n 0)\n\t\t\t\t interprogram-paste-function\n\t\t\t\t (funcall interprogram-paste-function))))\n    (if interprogram-paste\n\t(progn\n\t  ;; Disable the interprogram cut function when we add the new\n\t  ;; text to the kill ring, so Emacs doesn't try to own the\n\t  ;; selection, with identical text.\n\t  (let ((interprogram-cut-function nil))\n\t    (if (listp interprogram-paste)\n\t      (mapc 'kill-new (nreverse interprogram-paste))\n\t      (kill-new interprogram-paste)))\n\t  (car kill-ring))\n      (or kill-ring (error \"Kill ring is empty\"))\n      (let ((ARGth-kill-element\n\t     (nthcdr (mod (- n (length kill-ring-yank-pointer))\n\t\t\t  (length kill-ring))\n\t\t     kill-ring)))\n\t(unless do-not-move\n\t  (setq kill-ring-yank-pointer ARGth-kill-element)\n\t  (when (and yank-pop-change-selection\n\t\t     (> n 0)\n\t\t     interprogram-cut-function)\n\t    (funcall interprogram-cut-function (car ARGth-kill-element))))\n\t(car ARGth-kill-element)))))\n\n\n\n;;;; Commands for manipulating the kill ring.\n\n(defcustom kill-read-only-ok nil\n  \"Non-nil means don't signal an error for killing read-only text.\"\n  :type 'boolean\n  :group 'killing)\n\n(defun kill-region (beg end &optional region)\n  \"Kill (\\\"cut\\\") text between point and mark.\nThis deletes the text from the buffer and saves it in the kill ring.\nThe command \\\\[yank] can retrieve it from there.\n\\(If you want to save the region without killing it, use \\\\[kill-ring-save].)\n\nIf you want to append the killed region to the last killed text,\nuse \\\\[append-next-kill] before \\\\[kill-region].\n\nAny command that calls this function is a \\\"kill command\\\".\nIf the previous command was also a kill command,\nthe text killed this time appends to the text killed last time\nto make one entry in the kill ring.\n\nThe killed text is filtered by `filter-buffer-substring' before it is\nsaved in the kill ring, so the actual saved text might be different\nfrom what was killed.\n\nIf the buffer is read-only, Emacs will beep and refrain from deleting\nthe text, but put the text in the kill ring anyway.  This means that\nyou can use the killing commands to copy text from a read-only buffer.\n\nLisp programs should use this function for killing text.\n (To delete text, use `delete-region'.)\nSupply two arguments, character positions BEG and END indicating the\n stretch of text to be killed.  If the optional argument REGION is\n non-nil, the function ignores BEG and END, and kills the current\n region instead.\"\n  ;; Pass mark first, then point, because the order matters when\n  ;; calling `kill-append'.\n  (interactive (list (mark) (point) 'region))\n  (unless (and beg end)\n    (user-error \"The mark is not set now, so there is no region\"))\n  (condition-case nil\n      (let ((string (if region\n                        (funcall region-extract-function 'delete)\n                      (filter-buffer-substring beg end 'delete))))\n\t(when string\t\t\t;STRING is nil if BEG = END\n\t  ;; Add that string to the kill ring, one way or another.\n\t  (if (eq last-command 'kill-region)\n\t      (kill-append string (< end beg))\n\t    (kill-new string)))\n\t(when (or string (eq last-command 'kill-region))\n\t  (setq this-command 'kill-region))\n\t(setq deactivate-mark t)\n\tnil)\n    ((buffer-read-only text-read-only)\n     ;; The code above failed because the buffer, or some of the characters\n     ;; in the region, are read-only.\n     ;; We should beep, in case the user just isn't aware of this.\n     ;; However, there's no harm in putting\n     ;; the region's text in the kill ring, anyway.\n     (copy-region-as-kill beg end region)\n     ;; Set this-command now, so it will be set even if we get an error.\n     (setq this-command 'kill-region)\n     ;; This should barf, if appropriate, and give us the correct error.\n     (if kill-read-only-ok\n\t (progn (message \"Read only text copied to kill ring\") nil)\n       ;; Signal an error if the buffer is read-only.\n       (barf-if-buffer-read-only)\n       ;; If the buffer isn't read-only, the text is.\n       (signal 'text-read-only (list (current-buffer)))))))\n\n;; copy-region-as-kill no longer sets this-command, because it's confusing\n;; to get two copies of the text when the user accidentally types M-w and\n;; then corrects it with the intended C-w.\n(defun copy-region-as-kill (beg end &optional region)\n  \"Save the region as if killed, but don't kill it.\nIn Transient Mark mode, deactivate the mark.\nIf `interprogram-cut-function' is non-nil, also save the text for a window\nsystem cut and paste.\n\nThe copied text is filtered by `filter-buffer-substring' before it is\nsaved in the kill ring, so the actual saved text might be different\nfrom what was in the buffer.\n\nWhen called from Lisp, save in the kill ring the stretch of text\nbetween BEG and END, unless the optional argument REGION is\nnon-nil, in which case ignore BEG and END, and save the current\nregion instead.\n\nThis command's old key binding has been given to `kill-ring-save'.\"\n  ;; Pass mark first, then point, because the order matters when\n  ;; calling `kill-append'.\n  (interactive (list (mark) (point)\n\t\t     (prefix-numeric-value current-prefix-arg)))\n  (let ((str (if region\n                 (funcall region-extract-function nil)\n               (filter-buffer-substring beg end))))\n  (if (eq last-command 'kill-region)\n        (kill-append str (< end beg))\n      (kill-new str)))\n  (setq deactivate-mark t)\n  nil)\n\n(defun kill-ring-save (beg end &optional region)\n  \"Save the region as if killed, but don't kill it.\nIn Transient Mark mode, deactivate the mark.\nIf `interprogram-cut-function' is non-nil, also save the text for a window\nsystem cut and paste.\n\nIf you want to append the killed line to the last killed text,\nuse \\\\[append-next-kill] before \\\\[kill-ring-save].\n\nThe copied text is filtered by `filter-buffer-substring' before it is\nsaved in the kill ring, so the actual saved text might be different\nfrom what was in the buffer.\n\nWhen called from Lisp, save in the kill ring the stretch of text\nbetween BEG and END, unless the optional argument REGION is\nnon-nil, in which case ignore BEG and END, and save the current\nregion instead.\n\nThis command is similar to `copy-region-as-kill', except that it gives\nvisual feedback indicating the extent of the region being copied.\"\n  ;; Pass mark first, then point, because the order matters when\n  ;; calling `kill-append'.\n  (interactive (list (mark) (point)\n\t\t     (prefix-numeric-value current-prefix-arg)))\n  (copy-region-as-kill beg end region)\n  ;; This use of called-interactively-p is correct because the code it\n  ;; controls just gives the user visual feedback.\n  (if (called-interactively-p 'interactive)\n      (indicate-copied-region)))\n\n(defun indicate-copied-region (&optional message-len)\n  \"Indicate that the region text has been copied interactively.\nIf the mark is visible in the selected window, blink the cursor\nbetween point and mark if there is currently no active region\nhighlighting.\n\nIf the mark lies outside the selected window, display an\ninformative message containing a sample of the copied text.  The\noptional argument MESSAGE-LEN, if non-nil, specifies the length\nof this sample text; it defaults to 40.\"\n  (let ((mark (mark t))\n\t(point (point))\n\t;; Inhibit quitting so we can make a quit here\n\t;; look like a C-g typed as a command.\n\t(inhibit-quit t))\n    (if (pos-visible-in-window-p mark (selected-window))\n\t;; Swap point-and-mark quickly so as to show the region that\n\t;; was selected.  Don't do it if the region is highlighted.\n\t(unless (and (region-active-p)\n\t\t     (face-background 'region))\n\t  ;; Swap point and mark.\n\t  (set-marker (mark-marker) (point) (current-buffer))\n\t  (goto-char mark)\n\t  (sit-for blink-matching-delay)\n\t  ;; Swap back.\n\t  (set-marker (mark-marker) mark (current-buffer))\n\t  (goto-char point)\n\t  ;; If user quit, deactivate the mark\n\t  ;; as C-g would as a command.\n\t  (and quit-flag (region-active-p)\n\t       (deactivate-mark)))\n      (let ((len (min (abs (- mark point))\n\t\t      (or message-len 40))))\n\t(if (< point mark)\n\t    ;; Don't say \"killed\"; that is misleading.\n\t    (message \"Saved text until \\\"%s\\\"\"\n\t\t     (buffer-substring-no-properties (- mark len) mark))\n\t  (message \"Saved text from \\\"%s\\\"\"\n\t\t   (buffer-substring-no-properties mark (+ mark len))))))))\n\n(defun append-next-kill (&optional interactive)\n  \"Cause following command, if it kills, to add to previous kill.\nIf the next command kills forward from point, the kill is\nappended to the previous killed text.  If the command kills\nbackward, the kill is prepended.  Kill commands that act on the\nregion, such as `kill-region', are regarded as killing forward if\npoint is after mark, and killing backward if point is before\nmark.\n\nIf the next command is not a kill command, `append-next-kill' has\nno effect.\n\nThe argument is used for internal purposes; do not supply one.\"\n  (interactive \"p\")\n  ;; We don't use (interactive-p), since that breaks kbd macros.\n  (if interactive\n      (progn\n\t(setq this-command 'kill-region)\n\t(message \"If the next command is a kill, it will append\"))\n    (setq last-command 'kill-region)))\n\n(defvar bidi-directional-controls-chars \"\\x202a-\\x202e\\x2066-\\x2069\"\n  \"Character set that matches bidirectional formatting control characters.\")\n\n(defvar bidi-directional-non-controls-chars \"^\\x202a-\\x202e\\x2066-\\x2069\"\n  \"Character set that matches any character except bidirectional controls.\")\n\n(defun squeeze-bidi-context-1 (from to category replacement)\n  \"A subroutine of `squeeze-bidi-context'.\nFROM and TO should be markers, CATEGORY and REPLACEMENT should be strings.\"\n  (let ((pt (copy-marker from))\n\t(limit (copy-marker to))\n\t(old-pt 0)\n\tlim1)\n    (setq lim1 limit)\n    (goto-char pt)\n    (while (< pt limit)\n      (if (> pt old-pt)\n\t  (move-marker lim1\n\t\t       (save-excursion\n\t\t\t ;; L and R categories include embedding and\n\t\t\t ;; override controls, but we don't want to\n\t\t\t ;; replace them, because that might change\n\t\t\t ;; the visual order.  Likewise with PDF and\n\t\t\t ;; isolate controls.\n\t\t\t (+ pt (skip-chars-forward\n\t\t\t\tbidi-directional-non-controls-chars\n\t\t\t\tlimit)))))\n      ;; Replace any run of non-RTL characters by a single LRM.\n      (if (null (re-search-forward category lim1 t))\n\t  ;; No more characters of CATEGORY, we are done.\n\t  (setq pt limit)\n\t(replace-match replacement nil t)\n\t(move-marker pt (point)))\n      (setq old-pt pt)\n      ;; Skip directional controls, if any.\n      (move-marker\n       pt (+ pt (skip-chars-forward bidi-directional-controls-chars limit))))))\n\n(defun squeeze-bidi-context (from to)\n  \"Replace characters between FROM and TO while keeping bidi context.\n\nThis function replaces the region of text with as few characters\nas possible, while preserving the effect that region will have on\nbidirectional display before and after the region.\"\n  (let ((start (set-marker (make-marker)\n\t\t\t   (if (> from 0) from (+ (point-max) from))))\n\t(end (set-marker (make-marker) to))\n\t;; This is for when they copy text with read-only text\n\t;; properties.\n\t(inhibit-read-only t))\n    (if (null (marker-position end))\n\t(setq end (point-max-marker)))\n    ;; Replace each run of non-RTL characters with a single LRM.\n    (squeeze-bidi-context-1 start end \"\\\\CR+\" \"\\x200e\")\n    ;; Replace each run of non-LTR characters with a single RLM.  Note\n    ;; that the \\cR category includes both the Arabic Letter (AL) and\n    ;; R characters; here we ignore the distinction between them,\n    ;; because that distinction only affects Arabic Number (AN)\n    ;; characters, which are weak and don't affect the reordering.\n    (squeeze-bidi-context-1 start end \"\\\\CL+\" \"\\x200f\")))\n\n(defun line-substring-with-bidi-context (start end &optional no-properties)\n  \"Return buffer text between START and END with its bidi context.\n\nSTART and END are assumed to belong to the same physical line\nof buffer text.  This function prepends and appends to the text\nbetween START and END bidi control characters that preserve the\nvisual order of that text when it is inserted at some other place.\"\n  (if (or (< start (point-min))\n\t  (> end (point-max)))\n      (signal 'args-out-of-range (list (current-buffer) start end)))\n  (let ((buf (current-buffer))\n\tsubstr para-dir from to)\n    (save-excursion\n      (goto-char start)\n      (setq para-dir (current-bidi-paragraph-direction))\n      (setq from (line-beginning-position)\n\t    to (line-end-position))\n      (goto-char from)\n      ;; If we don't have any mixed directional characters in the\n      ;; entire line, we can just copy the substring without adding\n      ;; any context.\n      (if (or (looking-at-p \"\\\\CR*$\")\n\t      (looking-at-p \"\\\\CL*$\"))\n\t  (setq substr (if no-properties\n\t\t\t   (buffer-substring-no-properties start end)\n\t\t\t (buffer-substring start end)))\n\t(setq substr\n\t      (with-temp-buffer\n\t\t(if no-properties\n\t\t    (insert-buffer-substring-no-properties buf from to)\n\t\t  (insert-buffer-substring buf from to))\n\t\t(squeeze-bidi-context 1 (1+ (- start from)))\n\t\t(squeeze-bidi-context (- end to) nil)\n\t\t(buffer-substring 1 (point-max)))))\n\n      ;; Wrap the string in LRI/RLI..PDI pair to achieve 2 effects:\n      ;; (1) force the string to have the same base embedding\n      ;; direction as the paragraph direction at the source, no matter\n      ;; what is the paragraph direction at destination; and (2) avoid\n      ;; affecting the visual order of the surrounding text at\n      ;; destination if there are characters of different\n      ;; directionality there.\n      (concat (if (eq para-dir 'left-to-right) \"\\x2066\" \"\\x2067\")\n\t      substr \"\\x2069\"))))\n\n(defun buffer-substring-with-bidi-context (start end &optional no-properties)\n  \"Return portion of current buffer between START and END with bidi context.\n\nThis function works similar to `buffer-substring', but it prepends and\nappends to the text bidi directional control characters necessary to\npreserve the visual appearance of the text if it is inserted at another\nplace.  This is useful when the buffer substring includes bidirectional\ntext and control characters that cause non-trivial reordering on display.\nIf copied verbatim, such text can have a very different visual appearance,\nand can also change the visual appearance of the surrounding text at the\ndestination of the copy.\n\nOptional argument NO-PROPERTIES, if non-nil, means copy the text without\nthe text properties.\"\n  (let (line-end substr)\n    (if (or (< start (point-min))\n\t    (> end (point-max)))\n\t(signal 'args-out-of-range (list (current-buffer) start end)))\n    (save-excursion\n      (goto-char start)\n      (setq line-end (min end (line-end-position)))\n      (while (< start end)\n\t(setq substr\n\t      (concat substr\n\t\t      (if substr \"\\n\" \"\")\n\t\t      (line-substring-with-bidi-context start line-end\n\t\t\t\t\t\t\tno-properties)))\n\t(forward-line 1)\n\t(setq start (point))\n\t(setq line-end (min end (line-end-position))))\n      substr)))\n\f\n;; Yanking.\n\n(defcustom yank-handled-properties\n  '((font-lock-face . yank-handle-font-lock-face-property)\n    (category . yank-handle-category-property))\n  \"List of special text property handling conditions for yanking.\nEach element should have the form (PROP . FUN), where PROP is a\nproperty symbol and FUN is a function.  When the `yank' command\ninserts text into the buffer, it scans the inserted text for\nstretches of text that have `eq' values of the text property\nPROP; for each such stretch of text, FUN is called with three\narguments: the property's value in that text, and the start and\nend positions of the text.\n\nThis is done prior to removing the properties specified by\n`yank-excluded-properties'.\"\n  :group 'killing\n  :type '(repeat (cons (symbol :tag \"property symbol\")\n                       function))\n  :version \"24.3\")\n\n;; This is actually used in subr.el but defcustom does not work there.\n(defcustom yank-excluded-properties\n  '(category field follow-link fontified font-lock-face help-echo\n    intangible invisible keymap local-map mouse-face read-only\n    yank-handler)\n  \"Text properties to discard when yanking.\nThe value should be a list of text properties to discard or t,\nwhich means to discard all text properties.\n\nSee also `yank-handled-properties'.\"\n  :type '(choice (const :tag \"All\" t) (repeat symbol))\n  :group 'killing\n  :version \"24.3\")\n\n(defvar yank-window-start nil)\n(defvar yank-undo-function nil\n  \"If non-nil, function used by `yank-pop' to delete last stretch of yanked text.\nFunction is called with two parameters, START and END corresponding to\nthe value of the mark and point; it is guaranteed that START <= END.\nNormally set from the UNDO element of a yank-handler; see `insert-for-yank'.\")\n\n(defun yank-pop (&optional arg)\n  \"Replace just-yanked stretch of killed text with a different stretch.\nThis command is allowed only immediately after a `yank' or a `yank-pop'.\nAt such a time, the region contains a stretch of reinserted\npreviously-killed text.  `yank-pop' deletes that text and inserts in its\nplace a different stretch of killed text.\n\nWith no argument, the previous kill is inserted.\nWith argument N, insert the Nth previous kill.\nIf N is negative, this is a more recent kill.\n\nThe sequence of kills wraps around, so that after the oldest one\ncomes the newest one.\n\nThis command honors the `yank-handled-properties' and\n`yank-excluded-properties' variables, and the `yank-handler' text\nproperty, in the way that `yank' does.\"\n  (interactive \"*p\")\n  (if (not (eq last-command 'yank))\n      (user-error \"Previous command was not a yank\"))\n  (setq this-command 'yank)\n  (unless arg (setq arg 1))\n  (let ((inhibit-read-only t)\n\t(before (< (point) (mark t))))\n    (if before\n\t(funcall (or yank-undo-function 'delete-region) (point) (mark t))\n      (funcall (or yank-undo-function 'delete-region) (mark t) (point)))\n    (setq yank-undo-function nil)\n    (set-marker (mark-marker) (point) (current-buffer))\n    (insert-for-yank (current-kill arg))\n    ;; Set the window start back where it was in the yank command,\n    ;; if possible.\n    (set-window-start (selected-window) yank-window-start t)\n    (if before\n\t;; This is like exchange-point-and-mark, but doesn't activate the mark.\n\t;; It is cleaner to avoid activation, even though the command\n\t;; loop would deactivate the mark because we inserted text.\n\t(goto-char (prog1 (mark t)\n\t\t     (set-marker (mark-marker) (point) (current-buffer))))))\n  nil)\n\n(defun yank (&optional arg)\n  \"Reinsert (\\\"paste\\\") the last stretch of killed text.\nMore precisely, reinsert the most recent kill, which is the\nstretch of killed text most recently killed OR yanked.  Put point\nat the end, and set mark at the beginning without activating it.\nWith just \\\\[universal-argument] as argument, put point at beginning, and mark at end.\nWith argument N, reinsert the Nth most recent kill.\n\nThis command honors the `yank-handled-properties' and\n`yank-excluded-properties' variables, and the `yank-handler' text\nproperty, as described below.\n\nProperties listed in `yank-handled-properties' are processed,\nthen those listed in `yank-excluded-properties' are discarded.\n\nIf STRING has a non-nil `yank-handler' property anywhere, the\nnormal insert behavior is altered, and instead, for each contiguous\nsegment of STRING that has a given value of the `yank-handler'\nproperty, that value is used as follows:\n\nThe value of a `yank-handler' property must be a list of one to four\nelements, of the form (FUNCTION PARAM NOEXCLUDE UNDO).\nFUNCTION, if non-nil, should be a function of one argument (the\n object to insert); FUNCTION is called instead of `insert'.\nPARAM, if present and non-nil, is passed to FUNCTION (to be handled\n in whatever way is appropriate; e.g. if FUNCTION is `yank-rectangle',\n PARAM may be a list of strings to insert as a rectangle).  If PARAM\n is nil, then the current segment of STRING is used.\nIf NOEXCLUDE is present and non-nil, the normal removal of\n `yank-excluded-properties' is not performed; instead FUNCTION is\n responsible for the removal.  This may be necessary if FUNCTION\n adjusts point before or after inserting the object.\nUNDO, if present and non-nil, should be a function to be called\n by `yank-pop' to undo the insertion of the current PARAM.  It is\n given two arguments, the start and end of the region.  FUNCTION\n may set `yank-undo-function' to override UNDO.\n\nSee also the command `yank-pop' (\\\\[yank-pop]).\"\n  (interactive \"*P\")\n  (setq yank-window-start (window-start))\n  ;; If we don't get all the way thru, make last-command indicate that\n  ;; for the following command.\n  (setq this-command t)\n  (push-mark)\n  (insert-for-yank (current-kill (cond\n\t\t\t\t  ((listp arg) 0)\n\t\t\t\t  ((eq arg '-) -2)\n\t\t\t\t  (t (1- arg)))))\n  (if (consp arg)\n      ;; This is like exchange-point-and-mark, but doesn't activate the mark.\n      ;; It is cleaner to avoid activation, even though the command\n      ;; loop would deactivate the mark because we inserted text.\n      (goto-char (prog1 (mark t)\n\t\t   (set-marker (mark-marker) (point) (current-buffer)))))\n  ;; If we do get all the way thru, make this-command indicate that.\n  (if (eq this-command t)\n      (setq this-command 'yank))\n  nil)\n\n(defun rotate-yank-pointer (arg)\n  \"Rotate the yanking point in the kill ring.\nWith ARG, rotate that many kills forward (or backward, if negative).\"\n  (interactive \"p\")\n  (current-kill arg))\n\f\n;; Some kill commands.\n\n;; Internal subroutine of delete-char\n(defun kill-forward-chars (arg)\n  (if (listp arg) (setq arg (car arg)))\n  (if (eq arg '-) (setq arg -1))\n  (kill-region (point) (+ (point) arg)))\n\n;; Internal subroutine of backward-delete-char\n(defun kill-backward-chars (arg)\n  (if (listp arg) (setq arg (car arg)))\n  (if (eq arg '-) (setq arg -1))\n  (kill-region (point) (- (point) arg)))\n\n(defcustom backward-delete-char-untabify-method 'untabify\n  \"The method for untabifying when deleting backward.\nCan be `untabify' -- turn a tab to many spaces, then delete one space;\n       `hungry' -- delete all whitespace, both tabs and spaces;\n       `all' -- delete all whitespace, including tabs, spaces and newlines;\n       nil -- just delete one character.\"\n  :type '(choice (const untabify) (const hungry) (const all) (const nil))\n  :version \"20.3\"\n  :group 'killing)\n\n(defun backward-delete-char-untabify (arg &optional killp)\n  \"Delete characters backward, changing tabs into spaces.\nThe exact behavior depends on `backward-delete-char-untabify-method'.\nDelete ARG chars, and kill (save in kill ring) if KILLP is non-nil.\nInteractively, ARG is the prefix arg (default 1)\nand KILLP is t if a prefix arg was specified.\"\n  (interactive \"*p\\nP\")\n  (when (eq backward-delete-char-untabify-method 'untabify)\n    (let ((count arg))\n      (save-excursion\n\t(while (and (> count 0) (not (bobp)))\n\t  (if (= (preceding-char) ?\\t)\n\t      (let ((col (current-column)))\n\t\t(forward-char -1)\n\t\t(setq col (- col (current-column)))\n\t\t(insert-char ?\\s col)\n\t\t(delete-char 1)))\n\t  (forward-char -1)\n\t  (setq count (1- count))))))\n  (let* ((skip (cond ((eq backward-delete-char-untabify-method 'hungry) \" \\t\")\n                     ((eq backward-delete-char-untabify-method 'all)\n                      \" \\t\\n\\r\")))\n         (n (if skip\n                (let* ((oldpt (point))\n                       (wh (- oldpt (save-excursion\n                                      (skip-chars-backward skip)\n                                      (constrain-to-field nil oldpt)))))\n                  (+ arg (if (zerop wh) 0 (1- wh))))\n              arg)))\n    ;; Avoid warning about delete-backward-char\n    (with-no-warnings (delete-backward-char n killp))))\n\n(defun zap-to-char (arg char)\n  \"Kill up to and including ARGth occurrence of CHAR.\nCase is ignored if `case-fold-search' is non-nil in the current buffer.\nGoes backward if ARG is negative; error if CHAR not found.\"\n  (interactive (list (prefix-numeric-value current-prefix-arg)\n\t\t     (read-char \"Zap to char: \" t)))\n  ;; Avoid \"obsolete\" warnings for translation-table-for-input.\n  (with-no-warnings\n    (if (char-table-p translation-table-for-input)\n\t(setq char (or (aref translation-table-for-input char) char))))\n  (kill-region (point) (progn\n\t\t\t (search-forward (char-to-string char) nil nil arg)\n\t\t\t (point))))\n\n;; kill-line and its subroutines.\n\n(defcustom kill-whole-line nil\n  \"If non-nil, `kill-line' with no arg at start of line kills the whole line.\"\n  :type 'boolean\n  :group 'killing)\n\n(defun kill-line (&optional arg)\n  \"Kill the rest of the current line; if no nonblanks there, kill thru newline.\nWith prefix argument ARG, kill that many lines from point.\nNegative arguments kill lines backward.\nWith zero argument, kills the text before point on the current line.\n\nWhen calling from a program, nil means \\\"no arg\\\",\na number counts as a prefix arg.\n\nTo kill a whole line, when point is not at the beginning, type \\\n\\\\[move-beginning-of-line] \\\\[kill-line] \\\\[kill-line].\n\nIf `show-trailing-whitespace' is non-nil, this command will just\nkill the rest of the current line, even if there are no nonblanks\nthere.\n\nIf option `kill-whole-line' is non-nil, then this command kills the whole line\nincluding its terminating newline, when used at the beginning of a line\nwith no argument.  As a consequence, you can always kill a whole line\nby typing \\\\[move-beginning-of-line] \\\\[kill-line].\n\nIf you want to append the killed line to the last killed text,\nuse \\\\[append-next-kill] before \\\\[kill-line].\n\nIf the buffer is read-only, Emacs will beep and refrain from deleting\nthe line, but put the line in the kill ring anyway.  This means that\nyou can use this command to copy text from a read-only buffer.\n\\(If the variable `kill-read-only-ok' is non-nil, then this won't\neven beep.)\"\n  (interactive \"P\")\n  (kill-region (point)\n\t       ;; It is better to move point to the other end of the kill\n\t       ;; before killing.  That way, in a read-only buffer, point\n\t       ;; moves across the text that is copied to the kill ring.\n\t       ;; The choice has no effect on undo now that undo records\n\t       ;; the value of point from before the command was run.\n\t       (progn\n\t\t (if arg\n\t\t     (forward-visible-line (prefix-numeric-value arg))\n\t\t   (if (eobp)\n\t\t       (signal 'end-of-buffer nil))\n\t\t   (let ((end\n\t\t\t  (save-excursion\n\t\t\t    (end-of-visible-line) (point))))\n\t\t     (if (or (save-excursion\n\t\t\t       ;; If trailing whitespace is visible,\n\t\t\t       ;; don't treat it as nothing.\n\t\t\t       (unless show-trailing-whitespace\n\t\t\t\t (skip-chars-forward \" \\t\" end))\n\t\t\t       (= (point) end))\n\t\t\t     (and kill-whole-line (bolp)))\n\t\t\t (forward-visible-line 1)\n\t\t       (goto-char end))))\n\t\t (point))))\n\n(defun kill-whole-line (&optional arg)\n  \"Kill current line.\nWith prefix ARG, kill that many lines starting from the current line.\nIf ARG is negative, kill backward.  Also kill the preceding newline.\n\\(This is meant to make \\\\[repeat] work well with negative arguments.)\nIf ARG is zero, kill current line but exclude the trailing newline.\"\n  (interactive \"p\")\n  (or arg (setq arg 1))\n  (if (and (> arg 0) (eobp) (save-excursion (forward-visible-line 0) (eobp)))\n      (signal 'end-of-buffer nil))\n  (if (and (< arg 0) (bobp) (save-excursion (end-of-visible-line) (bobp)))\n      (signal 'beginning-of-buffer nil))\n  (unless (eq last-command 'kill-region)\n    (kill-new \"\")\n    (setq last-command 'kill-region))\n  (cond ((zerop arg)\n\t ;; We need to kill in two steps, because the previous command\n\t ;; could have been a kill command, in which case the text\n\t ;; before point needs to be prepended to the current kill\n\t ;; ring entry and the text after point appended.  Also, we\n\t ;; need to use save-excursion to avoid copying the same text\n\t ;; twice to the kill ring in read-only buffers.\n\t (save-excursion\n\t   (kill-region (point) (progn (forward-visible-line 0) (point))))\n\t (kill-region (point) (progn (end-of-visible-line) (point))))\n\t((< arg 0)\n\t (save-excursion\n\t   (kill-region (point) (progn (end-of-visible-line) (point))))\n\t (kill-region (point)\n\t\t      (progn (forward-visible-line (1+ arg))\n\t\t\t     (unless (bobp) (backward-char))\n\t\t\t     (point))))\n\t(t\n\t (save-excursion\n\t   (kill-region (point) (progn (forward-visible-line 0) (point))))\n\t (kill-region (point)\n\t\t      (progn (forward-visible-line arg) (point))))))\n\n(defun forward-visible-line (arg)\n  \"Move forward by ARG lines, ignoring currently invisible newlines only.\nIf ARG is negative, move backward -ARG lines.\nIf ARG is zero, move to the beginning of the current line.\"\n  (condition-case nil\n      (if (> arg 0)\n\t  (progn\n\t    (while (> arg 0)\n\t      (or (zerop (forward-line 1))\n\t\t  (signal 'end-of-buffer nil))\n\t      ;; If the newline we just skipped is invisible,\n\t      ;; don't count it.\n\t      (let ((prop\n\t\t     (get-char-property (1- (point)) 'invisible)))\n\t\t(if (if (eq buffer-invisibility-spec t)\n\t\t\tprop\n\t\t      (or (memq prop buffer-invisibility-spec)\n\t\t\t  (assq prop buffer-invisibility-spec)))\n\t\t    (setq arg (1+ arg))))\n\t      (setq arg (1- arg)))\n\t    ;; If invisible text follows, and it is a number of complete lines,\n\t    ;; skip it.\n\t    (let ((opoint (point)))\n\t      (while (and (not (eobp))\n\t\t\t  (let ((prop\n\t\t\t\t (get-char-property (point) 'invisible)))\n\t\t\t    (if (eq buffer-invisibility-spec t)\n\t\t\t\tprop\n\t\t\t      (or (memq prop buffer-invisibility-spec)\n\t\t\t\t  (assq prop buffer-invisibility-spec)))))\n\t\t(goto-char\n\t\t (if (get-text-property (point) 'invisible)\n\t\t     (or (next-single-property-change (point) 'invisible)\n\t\t\t (point-max))\n\t\t   (next-overlay-change (point)))))\n\t      (unless (bolp)\n\t\t(goto-char opoint))))\n\t(let ((first t))\n\t  (while (or first (<= arg 0))\n\t    (if first\n\t\t(beginning-of-line)\n\t      (or (zerop (forward-line -1))\n\t\t  (signal 'beginning-of-buffer nil)))\n\t    ;; If the newline we just moved to is invisible,\n\t    ;; don't count it.\n\t    (unless (bobp)\n\t      (let ((prop\n\t\t     (get-char-property (1- (point)) 'invisible)))\n\t\t(unless (if (eq buffer-invisibility-spec t)\n\t\t\t    prop\n\t\t\t  (or (memq prop buffer-invisibility-spec)\n\t\t\t      (assq prop buffer-invisibility-spec)))\n\t\t  (setq arg (1+ arg)))))\n\t    (setq first nil))\n\t  ;; If invisible text follows, and it is a number of complete lines,\n\t  ;; skip it.\n\t  (let ((opoint (point)))\n\t    (while (and (not (bobp))\n\t\t\t(let ((prop\n\t\t\t       (get-char-property (1- (point)) 'invisible)))\n\t\t\t  (if (eq buffer-invisibility-spec t)\n\t\t\t      prop\n\t\t\t    (or (memq prop buffer-invisibility-spec)\n\t\t\t\t(assq prop buffer-invisibility-spec)))))\n\t      (goto-char\n\t       (if (get-text-property (1- (point)) 'invisible)\n\t\t   (or (previous-single-property-change (point) 'invisible)\n\t\t       (point-min))\n\t\t (previous-overlay-change (point)))))\n\t    (unless (bolp)\n\t      (goto-char opoint)))))\n    ((beginning-of-buffer end-of-buffer)\n     nil)))\n\n(defun end-of-visible-line ()\n  \"Move to end of current visible line.\"\n  (end-of-line)\n  ;; If the following character is currently invisible,\n  ;; skip all characters with that same `invisible' property value,\n  ;; then find the next newline.\n  (while (and (not (eobp))\n\t      (save-excursion\n\t\t(skip-chars-forward \"^\\n\")\n\t\t(let ((prop\n\t\t       (get-char-property (point) 'invisible)))\n\t\t  (if (eq buffer-invisibility-spec t)\n\t\t      prop\n\t\t    (or (memq prop buffer-invisibility-spec)\n\t\t\t(assq prop buffer-invisibility-spec))))))\n    (skip-chars-forward \"^\\n\")\n    (if (get-text-property (point) 'invisible)\n\t(goto-char (or (next-single-property-change (point) 'invisible)\n\t\t       (point-max)))\n      (goto-char (next-overlay-change (point))))\n    (end-of-line)))\n\n(defun kill-current-buffer ()\n  \"Kill the current buffer.\nWhen called in the minibuffer, get out of the minibuffer\nusing `abort-recursive-edit'.\n\nThis is like `kill-this-buffer', but it doesn't have to be invoked\nvia the menu bar, and pays no attention to the menu-bar's frame.\"\n  (interactive)\n  (let ((frame (selected-frame)))\n    (if (and (frame-live-p frame)\n             (not (window-minibuffer-p (frame-selected-window frame))))\n        (kill-buffer (current-buffer))\n      (abort-recursive-edit))))\n\n\f\n(defun insert-buffer (buffer)\n  \"Insert after point the contents of BUFFER.\nPuts mark after the inserted text.\nBUFFER may be a buffer or a buffer name.\"\n  (declare (interactive-only insert-buffer-substring))\n  (interactive\n   (list\n    (progn\n      (barf-if-buffer-read-only)\n      (read-buffer \"Insert buffer: \"\n\t\t   (if (eq (selected-window) (next-window))\n\t\t       (other-buffer (current-buffer))\n\t\t     (window-buffer (next-window)))\n\t\t   t))))\n  (push-mark\n   (save-excursion\n     (insert-buffer-substring (get-buffer buffer))\n     (point)))\n  nil)\n\n(defun append-to-buffer (buffer start end)\n  \"Append to specified buffer the text of the region.\nIt is inserted into that buffer before its point.\n\nWhen calling from a program, give three arguments:\nBUFFER (or buffer name), START and END.\nSTART and END specify the portion of the current buffer to be copied.\"\n  (interactive\n   (list (read-buffer \"Append to buffer: \" (other-buffer (current-buffer) t))\n\t (region-beginning) (region-end)))\n  (let* ((oldbuf (current-buffer))\n         (append-to (get-buffer-create buffer))\n         (windows (get-buffer-window-list append-to t t))\n         point)\n    (save-excursion\n      (with-current-buffer append-to\n        (setq point (point))\n        (barf-if-buffer-read-only)\n        (insert-buffer-substring oldbuf start end)\n        (dolist (window windows)\n          (when (= (window-point window) point)\n            (set-window-point window (point))))))))\n\n(defun prepend-to-buffer (buffer start end)\n  \"Prepend to specified buffer the text of the region.\nIt is inserted into that buffer after its point.\n\nWhen calling from a program, give three arguments:\nBUFFER (or buffer name), START and END.\nSTART and END specify the portion of the current buffer to be copied.\"\n  (interactive \"BPrepend to buffer: \\nr\")\n  (let ((oldbuf (current-buffer)))\n    (with-current-buffer (get-buffer-create buffer)\n      (barf-if-buffer-read-only)\n      (save-excursion\n\t(insert-buffer-substring oldbuf start end)))))\n\n(defun copy-to-buffer (buffer start end)\n  \"Copy to specified buffer the text of the region.\nIt is inserted into that buffer, replacing existing text there.\n\nWhen calling from a program, give three arguments:\nBUFFER (or buffer name), START and END.\nSTART and END specify the portion of the current buffer to be copied.\"\n  (interactive \"BCopy to buffer: \\nr\")\n  (let ((oldbuf (current-buffer)))\n    (with-current-buffer (get-buffer-create buffer)\n      (barf-if-buffer-read-only)\n      (erase-buffer)\n      (save-excursion\n\t(insert-buffer-substring oldbuf start end)))))\n\f\n(define-error 'mark-inactive (purecopy \"The mark is not active now\"))\n\n(defvar activate-mark-hook nil\n  \"Hook run when the mark becomes active.\nIt is also run at the end of a command, if the mark is active and\nit is possible that the region may have changed.\")\n\n(defvar deactivate-mark-hook nil\n  \"Hook run when the mark becomes inactive.\")\n\n(defun mark (&optional force)\n  \"Return this buffer's mark value as integer, or nil if never set.\n\nIn Transient Mark mode, this function signals an error if\nthe mark is not active.  However, if `mark-even-if-inactive' is non-nil,\nor the argument FORCE is non-nil, it disregards whether the mark\nis active, and returns an integer or nil in the usual way.\n\nIf you are using this in an editing command, you are most likely making\na mistake; see the documentation of `set-mark'.\"\n  (if (or force (not transient-mark-mode) mark-active mark-even-if-inactive)\n      (marker-position (mark-marker))\n    (signal 'mark-inactive nil)))\n\n;; Behind display-selections-p.\n\n(defun deactivate-mark (&optional force)\n  \"Deactivate the mark.\nIf Transient Mark mode is disabled, this function normally does\nnothing; but if FORCE is non-nil, it deactivates the mark anyway.\n\nDeactivating the mark sets `mark-active' to nil, updates the\nprimary selection according to `select-active-regions', and runs\n`deactivate-mark-hook'.\n\nIf Transient Mark mode was temporarily enabled, reset the value\nof the variable `transient-mark-mode'; if this causes Transient\nMark mode to be disabled, don't change `mark-active' to nil or\nrun `deactivate-mark-hook'.\"\n  (when (or (region-active-p) force)\n    (when (and (if (eq select-active-regions 'only)\n\t\t   (eq (car-safe transient-mark-mode) 'only)\n\t\t select-active-regions)\n\t       (region-active-p)\n\t       (display-selections-p))\n      ;; The var `saved-region-selection', if non-nil, is the text in\n      ;; the region prior to the last command modifying the buffer.\n      ;; Set the selection to that, or to the current region.\n      (cond (saved-region-selection\n\t     (if (gui-backend-selection-owner-p 'PRIMARY)\n\t\t (gui-set-selection 'PRIMARY saved-region-selection))\n\t     (setq saved-region-selection nil))\n\t    ;; If another program has acquired the selection, region\n\t    ;; deactivation should not clobber it (Bug#11772).\n\t    ((and (/= (region-beginning) (region-end))\n\t\t  (or (gui-backend-selection-owner-p 'PRIMARY)\n\t\t      (null (gui-backend-selection-exists-p 'PRIMARY))))\n\t     (gui-set-selection 'PRIMARY\n                                (funcall region-extract-function nil)))))\n    (when mark-active (force-mode-line-update)) ;Refresh toolbar (bug#16382).\n    (cond\n     ((eq (car-safe transient-mark-mode) 'only)\n      (setq transient-mark-mode (cdr transient-mark-mode))\n      (if (eq transient-mark-mode (default-value 'transient-mark-mode))\n          (kill-local-variable 'transient-mark-mode)))\n     ((eq transient-mark-mode 'lambda)\n      (kill-local-variable 'transient-mark-mode)))\n    (setq mark-active nil)\n    (run-hooks 'deactivate-mark-hook)\n    (redisplay--update-region-highlight (selected-window))))\n\n(defun activate-mark (&optional no-tmm)\n  \"Activate the mark.\nIf NO-TMM is non-nil, leave `transient-mark-mode' alone.\"\n  (when (mark t)\n    (unless (region-active-p)\n      (force-mode-line-update) ;Refresh toolbar (bug#16382).\n      (setq mark-active t)\n      (unless (or transient-mark-mode no-tmm)\n        (setq-local transient-mark-mode 'lambda))\n      (run-hooks 'activate-mark-hook))))\n\n(defun set-mark (pos)\n  \"Set this buffer's mark to POS.  Don't use this function!\nThat is to say, don't use this function unless you want\nthe user to see that the mark has moved, and you want the previous\nmark position to be lost.\n\nNormally, when a new mark is set, the old one should go on the stack.\nThis is why most applications should use `push-mark', not `set-mark'.\n\nNovice Emacs Lisp programmers often try to use the mark for the wrong\npurposes.  The mark saves a location for the user's convenience.\nMost editing commands should not alter the mark.\nTo remember a location for internal use in the Lisp program,\nstore it in a Lisp variable.  Example:\n\n   (let ((beg (point))) (forward-line 1) (delete-region beg (point))).\"\n  (if pos\n      (progn\n        (set-marker (mark-marker) pos (current-buffer))\n        (activate-mark 'no-tmm))\n    ;; Normally we never clear mark-active except in Transient Mark mode.\n    ;; But when we actually clear out the mark value too, we must\n    ;; clear mark-active in any mode.\n    (deactivate-mark t)\n    ;; `deactivate-mark' sometimes leaves mark-active non-nil, but\n    ;; it should never be nil if the mark is nil.\n    (setq mark-active nil)\n    (set-marker (mark-marker) nil)))\n\n(defun save-mark-and-excursion--save ()\n  (cons\n   (let ((mark (mark-marker)))\n     (and (marker-position mark) (copy-marker mark)))\n   mark-active))\n\n(defun save-mark-and-excursion--restore (saved-mark-info)\n  (let ((saved-mark (car saved-mark-info))\n        (omark (marker-position (mark-marker)))\n        (nmark nil)\n        (saved-mark-active (cdr saved-mark-info)))\n    ;; Mark marker\n    (if (null saved-mark)\n        (set-marker (mark-marker) nil)\n      (setf nmark (marker-position saved-mark))\n      (set-marker (mark-marker) nmark)\n      (set-marker saved-mark nil))\n    ;; Mark active\n    (let ((cur-mark-active mark-active))\n      (setq mark-active saved-mark-active)\n      ;; If mark is active now, and either was not active or was at a\n      ;; different place, run the activate hook.\n      (if saved-mark-active\n          (when (or (not cur-mark-active)\n                    (not (eq omark nmark)))\n            (run-hooks 'activate-mark-hook))\n        ;; If mark has ceased to be active, run deactivate hook.\n        (when cur-mark-active\n          (run-hooks 'deactivate-mark-hook))))))\n\n(defmacro save-mark-and-excursion (&rest body)\n  \"Like `save-excursion', but also save and restore the mark state.\nThis macro does what `save-excursion' did before Emacs 25.1.\"\n  (declare (indent 0) (debug t))\n  (let ((saved-marker-sym (make-symbol \"saved-marker\")))\n    `(let ((,saved-marker-sym (save-mark-and-excursion--save)))\n       (unwind-protect\n            (save-excursion ,@body)\n         (save-mark-and-excursion--restore ,saved-marker-sym)))))\n\n(defcustom use-empty-active-region nil\n  \"Whether \\\"region-aware\\\" commands should act on empty regions.\nIf nil, region-aware commands treat the empty region as inactive.\nIf non-nil, region-aware commands treat the region as active as\nlong as the mark is active, even if the region is empty.\n\nRegion-aware commands are those that act on the region if it is\nactive and Transient Mark mode is enabled, and on the text near\npoint otherwise.\"\n  :type 'boolean\n  :version \"23.1\"\n  :group 'editing-basics)\n\n(defun use-region-p ()\n  \"Return t if the region is active and it is appropriate to act on it.\nThis is used by commands that act specially on the region under\nTransient Mark mode.\n\nThe return value is t if Transient Mark mode is enabled and the\nmark is active; furthermore, if `use-empty-active-region' is nil,\nthe region must not be empty.  Otherwise, the return value is nil.\n\nFor some commands, it may be appropriate to ignore the value of\n`use-empty-active-region'; in that case, use `region-active-p'.\"\n  (and (region-active-p)\n       (or use-empty-active-region (> (region-end) (region-beginning)))))\n\n(defun region-active-p ()\n  \"Return non-nil if Transient Mark mode is enabled and the mark is active.\n\nSome commands act specially on the region when Transient Mark\nmode is enabled.  Usually, such commands should use\n`use-region-p' instead of this function, because `use-region-p'\nalso checks the value of `use-empty-active-region'.\"\n  (and transient-mark-mode mark-active\n       ;; FIXME: Somehow we sometimes end up with mark-active non-nil but\n       ;; without the mark being set (e.g. bug#17324).  We really should fix\n       ;; that problem, but in the mean time, let's make sure we don't say the\n       ;; region is active when there's no mark.\n       (progn (cl-assert (mark)) t)))\n\n(defun region-bounds ()\n  \"Return the boundaries of the region as a pair of positions.\nValue is a list of cons cells of the form (START . END).\"\n  (funcall region-extract-function 'bounds))\n\n(defun region-noncontiguous-p ()\n  \"Return non-nil if the region contains several pieces.\nAn example is a rectangular region handled as a list of\nseparate contiguous regions for each line.\"\n  (> (length (region-bounds)) 1))\n\n(defvar redisplay-unhighlight-region-function\n  (lambda (rol) (when (overlayp rol) (delete-overlay rol))))\n\n(defvar redisplay-highlight-region-function\n  (lambda (start end window rol)\n    (if (not (overlayp rol))\n        (let ((nrol (make-overlay start end)))\n          (funcall redisplay-unhighlight-region-function rol)\n          (overlay-put nrol 'window window)\n          (overlay-put nrol 'face 'region)\n          ;; Normal priority so that a large region doesn't hide all the\n          ;; overlays within it, but high secondary priority so that if it\n          ;; ends/starts in the middle of a small overlay, that small overlay\n          ;; won't hide the region's boundaries.\n          (overlay-put nrol 'priority '(nil . 100))\n          nrol)\n      (unless (and (eq (overlay-buffer rol) (current-buffer))\n                   (eq (overlay-start rol) start)\n                   (eq (overlay-end rol) end))\n        (move-overlay rol start end (current-buffer)))\n      rol)))\n\n(defun redisplay--update-region-highlight (window)\n  (let ((rol (window-parameter window 'internal-region-overlay)))\n    (if (not (and (region-active-p)\n                  (or highlight-nonselected-windows\n                      (eq window (selected-window))\n                      (and (window-minibuffer-p)\n                           (eq window (minibuffer-selected-window))))))\n        (funcall redisplay-unhighlight-region-function rol)\n      (let* ((pt (window-point window))\n             (mark (mark))\n             (start (min pt mark))\n             (end   (max pt mark))\n             (new\n              (funcall redisplay-highlight-region-function\n                       start end window rol)))\n        (unless (equal new rol)\n          (set-window-parameter window 'internal-region-overlay\n                                new))))))\n\n(defvar pre-redisplay-functions (list #'redisplay--update-region-highlight)\n  \"Hook run just before redisplay.\nIt is called in each window that is to be redisplayed.  It takes one argument,\nwhich is the window that will be redisplayed.  When run, the `current-buffer'\nis set to the buffer displayed in that window.\")\n\n(defun redisplay--pre-redisplay-functions (windows)\n  (with-demoted-errors \"redisplay--pre-redisplay-functions: %S\"\n    (if (null windows)\n        (with-current-buffer (window-buffer (selected-window))\n          (run-hook-with-args 'pre-redisplay-functions (selected-window)))\n      (dolist (win (if (listp windows) windows (window-list-1 nil nil t)))\n        (with-current-buffer (window-buffer win)\n          (run-hook-with-args 'pre-redisplay-functions win))))))\n\n(add-function :before pre-redisplay-function\n              #'redisplay--pre-redisplay-functions)\n\n\n(defvar-local mark-ring nil\n  \"The list of former marks of the current buffer, most recent first.\")\n(put 'mark-ring 'permanent-local t)\n\n(defcustom mark-ring-max 16\n  \"Maximum size of mark ring.  Start discarding off end if gets this big.\"\n  :type 'integer\n  :group 'editing-basics)\n\n(defvar global-mark-ring nil\n  \"The list of saved global marks, most recent first.\")\n\n(defcustom global-mark-ring-max 16\n  \"Maximum size of global mark ring.  \\\nStart discarding off end if gets this big.\"\n  :type 'integer\n  :group 'editing-basics)\n\n(defun pop-to-mark-command ()\n  \"Jump to mark, and pop a new position for mark off the ring.\n\\(Does not affect global mark ring).\"\n  (interactive)\n  (if (null (mark t))\n      (user-error \"No mark set in this buffer\")\n    (if (= (point) (mark t))\n\t(message \"Mark popped\"))\n    (goto-char (mark t))\n    (pop-mark)))\n\n(defun push-mark-command (arg &optional nomsg)\n  \"Set mark at where point is.\nIf no prefix ARG and mark is already set there, just activate it.\nDisplay `Mark set' unless the optional second arg NOMSG is non-nil.\"\n  (interactive \"P\")\n  (let ((mark (mark t)))\n    (if (or arg (null mark) (/= mark (point)))\n\t(push-mark nil nomsg t)\n      (activate-mark 'no-tmm)\n      (unless nomsg\n\t(message \"Mark activated\")))))\n\n(defcustom set-mark-command-repeat-pop nil\n  \"Non-nil means repeating \\\\[set-mark-command] after popping mark pops it again.\nThat means that C-u \\\\[set-mark-command] \\\\[set-mark-command]\nwill pop the mark twice, and\nC-u \\\\[set-mark-command] \\\\[set-mark-command] \\\\[set-mark-command]\nwill pop the mark three times.\n\nA value of nil means \\\\[set-mark-command]'s behavior does not change\nafter C-u \\\\[set-mark-command].\"\n  :type 'boolean\n  :group 'editing-basics)\n\n(defun set-mark-command (arg)\n  \"Set the mark where point is, and activate it; or jump to the mark.\nSetting the mark also alters the region, which is the text\nbetween point and mark; this is the closest equivalent in\nEmacs to what some editors call the \\\"selection\\\".\n\nWith no prefix argument, set the mark at point, and push the\nold mark position on local mark ring.  Also push the new mark on\nglobal mark ring, if the previous mark was set in another buffer.\n\nWhen Transient Mark Mode is off, immediately repeating this\ncommand activates `transient-mark-mode' temporarily.\n\nWith prefix argument (e.g., \\\\[universal-argument] \\\\[set-mark-command]), \\\njump to the mark, and set the mark from\nposition popped off the local mark ring (this does not affect the global\nmark ring).  Use \\\\[pop-global-mark] to jump to a mark popped off the global\nmark ring (see `pop-global-mark').\n\nIf `set-mark-command-repeat-pop' is non-nil, repeating\nthe \\\\[set-mark-command] command with no prefix argument pops the next position\noff the local (or global) mark ring and jumps there.\n\nWith \\\\[universal-argument] \\\\[universal-argument] as prefix\nargument, unconditionally set mark where point is, even if\n`set-mark-command-repeat-pop' is non-nil.\n\nNovice Emacs Lisp programmers often try to use the mark for the wrong\npurposes.  See the documentation of `set-mark' for more information.\"\n  (interactive \"P\")\n  (cond ((eq transient-mark-mode 'lambda)\n\t (kill-local-variable 'transient-mark-mode))\n\t((eq (car-safe transient-mark-mode) 'only)\n\t (deactivate-mark)))\n  (cond\n   ((and (consp arg) (> (prefix-numeric-value arg) 4))\n    (push-mark-command nil))\n   ((not (eq this-command 'set-mark-command))\n    (if arg\n\t(pop-to-mark-command)\n      (push-mark-command t)))\n   ((and set-mark-command-repeat-pop\n\t (eq last-command 'pop-global-mark)\n\t (not arg))\n    (setq this-command 'pop-global-mark)\n    (pop-global-mark))\n   ((or (and set-mark-command-repeat-pop\n             (eq last-command 'pop-to-mark-command))\n        arg)\n    (setq this-command 'pop-to-mark-command)\n    (pop-to-mark-command))\n   ((eq last-command 'set-mark-command)\n    (if (region-active-p)\n        (progn\n          (deactivate-mark)\n          (message \"Mark deactivated\"))\n      (activate-mark)\n      (message \"Mark activated\")))\n   (t\n    (push-mark-command nil))))\n\n(defun push-mark (&optional location nomsg activate)\n  \"Set mark at LOCATION (point, by default) and push old mark on mark ring.\nIf the last global mark pushed was not in the current buffer,\nalso push LOCATION on the global mark ring.\nDisplay `Mark set' unless the optional second arg NOMSG is non-nil.\n\nNovice Emacs Lisp programmers often try to use the mark for the wrong\npurposes.  See the documentation of `set-mark' for more information.\n\nIn Transient Mark mode, activate mark if optional third arg ACTIVATE non-nil.\"\n  (unless (null (mark t))\n    (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))\n    (when (> (length mark-ring) mark-ring-max)\n      (move-marker (car (nthcdr mark-ring-max mark-ring)) nil)\n      (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil)))\n  (set-marker (mark-marker) (or location (point)) (current-buffer))\n  ;; Now push the mark on the global mark ring.\n  (if (and global-mark-ring\n\t   (eq (marker-buffer (car global-mark-ring)) (current-buffer)))\n      ;; The last global mark pushed was in this same buffer.\n      ;; Don't push another one.\n      nil\n    (setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring))\n    (when (> (length global-mark-ring) global-mark-ring-max)\n      (move-marker (car (nthcdr global-mark-ring-max global-mark-ring)) nil)\n      (setcdr (nthcdr (1- global-mark-ring-max) global-mark-ring) nil)))\n  (or nomsg executing-kbd-macro (> (minibuffer-depth) 0)\n      (message \"Mark set\"))\n  (if (or activate (not transient-mark-mode))\n      (set-mark (mark t)))\n  nil)\n\n(defun pop-mark ()\n  \"Pop off mark ring into the buffer's actual mark.\nDoes not set point.  Does nothing if mark ring is empty.\"\n  (when mark-ring\n    (setq mark-ring (nconc mark-ring (list (copy-marker (mark-marker)))))\n    (set-marker (mark-marker) (+ 0 (car mark-ring)) (current-buffer))\n    (move-marker (car mark-ring) nil)\n    (if (null (mark t)) (ding))\n    (setq mark-ring (cdr mark-ring)))\n  (deactivate-mark))\n\n;; The parser cannot handle a newline after def*.\n;; This bug is already recorded in\n;; parser-lisp.r/newline-between-tokens.b/\n;; (define-obsolete-function-alias\n;;  'exchange-dot-and-mark 'exchange-point-and-mark \"23.3\")\n(define-obsolete-function-alias 'exchange-dot-and-mark\n  'exchange-point-and-mark \"23.3\")\n\n(defun exchange-point-and-mark (&optional arg)\n  \"Put the mark where point is now, and point where the mark is now.\nThis command works even when the mark is not active,\nand it reactivates the mark.\n\nIf Transient Mark mode is on, a prefix ARG deactivates the mark\nif it is active, and otherwise avoids reactivating it.  If\nTransient Mark mode is off, a prefix ARG enables Transient Mark\nmode temporarily.\"\n  (interactive \"P\")\n  (let ((omark (mark t))\n\t(temp-highlight (eq (car-safe transient-mark-mode) 'only)))\n    (if (null omark)\n        (user-error \"No mark set in this buffer\"))\n    (set-mark (point))\n    (goto-char omark)\n    (cond (temp-highlight\n\t   (setq-local transient-mark-mode (cons 'only transient-mark-mode)))\n\t  ((or (and arg (region-active-p)) ; (xor arg (not (region-active-p)))\n\t       (not (or arg (region-active-p))))\n\t   (deactivate-mark))\n\t  (t (activate-mark)))\n    nil))\n\n(defcustom shift-select-mode t\n  \"When non-nil, shifted motion keys activate the mark momentarily.\n\nWhile the mark is activated in this way, any shift-translated point\nmotion key extends the region, and if Transient Mark mode was off, it\nis temporarily turned on.  Furthermore, the mark will be deactivated\nby any subsequent point motion key that was not shift-translated, or\nby any action that normally deactivates the mark in Transient Mark mode.\n\nSee `this-command-keys-shift-translated' for the meaning of\nshift-translation.\"\n  :type 'boolean\n  :group 'editing-basics)\n\n(defun handle-shift-selection ()\n  \"Activate/deactivate mark depending on invocation thru shift translation.\nThis function is called by `call-interactively' when a command\nwith a `^' character in its `interactive' spec is invoked, before\nrunning the command itself.\n\nIf `shift-select-mode' is enabled and the command was invoked\nthrough shift translation, set the mark and activate the region\ntemporarily, unless it was already set in this way.  See\n`this-command-keys-shift-translated' for the meaning of shift\ntranslation.\n\nOtherwise, if the region has been activated temporarily,\ndeactivate it, and restore the variable `transient-mark-mode' to\nits earlier value.\"\n  (cond ((and shift-select-mode this-command-keys-shift-translated)\n         (unless (and mark-active\n\t\t      (eq (car-safe transient-mark-mode) 'only))\n\t   (setq-local transient-mark-mode\n                       (cons 'only\n                             (unless (eq transient-mark-mode 'lambda)\n                               transient-mark-mode)))\n           (push-mark nil nil t)))\n        ((eq (car-safe transient-mark-mode) 'only)\n         (setq transient-mark-mode (cdr transient-mark-mode))\n         (if (eq transient-mark-mode (default-value 'transient-mark-mode))\n             (kill-local-variable 'transient-mark-mode))\n         (deactivate-mark))))\n\n(define-minor-mode transient-mark-mode\n  \"Toggle Transient Mark mode.\nWith a prefix argument ARG, enable Transient Mark mode if ARG is\npositive, and disable it otherwise.  If called from Lisp, enable\nTransient Mark mode if ARG is omitted or nil.\n\nTransient Mark mode is a global minor mode.  When enabled, the\nregion is highlighted with the `region' face whenever the mark\nis active.  The mark is \\\"deactivated\\\" by changing the buffer,\nand after certain other operations that set the mark but whose\nmain purpose is something else--for example, incremental search,\n\\\\[beginning-of-buffer], and \\\\[end-of-buffer].\n\nYou can also deactivate the mark by typing \\\\[keyboard-quit] or\n\\\\[keyboard-escape-quit].\n\nMany commands change their behavior when Transient Mark mode is\nin effect and the mark is active, by acting on the region instead\nof their usual default part of the buffer's text.  Examples of\nsuch commands include \\\\[comment-dwim], \\\\[flush-lines], \\\\[keep-lines],\n\\\\[query-replace], \\\\[query-replace-regexp], \\\\[ispell], and \\\\[undo].\nTo see the documentation of commands which are sensitive to the\nTransient Mark mode, invoke \\\\[apropos-documentation] and type \\\"transient\\\"\nor \\\"mark.*active\\\" at the prompt.\"\n  :global t\n  ;; It's defined in C/cus-start, this stops the d-m-m macro defining it again.\n  :variable (default-value 'transient-mark-mode))\n\n(defvar widen-automatically t\n  \"Non-nil means it is ok for commands to call `widen' when they want to.\nSome commands will do this in order to go to positions outside\nthe current accessible part of the buffer.\n\nIf `widen-automatically' is nil, these commands will do something else\nas a fallback, and won't change the buffer bounds.\")\n\n(defvar non-essential nil\n  \"Whether the currently executing code is performing an essential task.\nThis variable should be non-nil only when running code which should not\ndisturb the user.  E.g. it can be used to prevent Tramp from prompting the\nuser for a password when we are simply scanning a set of files in the\nbackground or displaying possible completions before the user even asked\nfor it.\")\n\n(defun pop-global-mark ()\n  \"Pop off global mark ring and jump to the top location.\"\n  (interactive)\n  ;; Pop entries which refer to non-existent buffers.\n  (while (and global-mark-ring (not (marker-buffer (car global-mark-ring))))\n    (setq global-mark-ring (cdr global-mark-ring)))\n  (or global-mark-ring\n      (error \"No global mark set\"))\n  (let* ((marker (car global-mark-ring))\n\t (buffer (marker-buffer marker))\n\t (position (marker-position marker)))\n    (setq global-mark-ring (nconc (cdr global-mark-ring)\n\t\t\t\t  (list (car global-mark-ring))))\n    (set-buffer buffer)\n    (or (and (>= position (point-min))\n\t     (<= position (point-max)))\n\t(if widen-automatically\n\t    (widen)\n\t  (error \"Global mark position is outside accessible part of buffer\")))\n    (goto-char position)\n    (switch-to-buffer buffer)))\n\f\n(defcustom next-line-add-newlines nil\n  \"If non-nil, `next-line' inserts newline to avoid `end of buffer' error.\"\n  :type 'boolean\n  :version \"21.1\"\n  :group 'editing-basics)\n\n(defun next-line (&optional arg try-vscroll)\n  \"Move cursor vertically down ARG lines.\nInteractively, vscroll tall lines if `auto-window-vscroll' is enabled.\nNon-interactively, use TRY-VSCROLL to control whether to vscroll tall\nlines: if either `auto-window-vscroll' or TRY-VSCROLL is nil, this\nfunction will not vscroll.\n\nARG defaults to 1.\n\nIf there is no character in the target line exactly under the current column,\nthe cursor is positioned after the character in that line which spans this\ncolumn, or at the end of the line if it is not long enough.\nIf there is no line in the buffer after this one, behavior depends on the\nvalue of `next-line-add-newlines'.  If non-nil, it inserts a newline character\nto create a line, and moves the cursor to that line.  Otherwise it moves the\ncursor to the end of the buffer.\n\nIf the variable `line-move-visual' is non-nil, this command moves\nby display lines.  Otherwise, it moves by buffer lines, without\ntaking variable-width characters or continued lines into account.\nSee \\\\[next-logical-line] for a command that always moves by buffer lines.\n\nThe command \\\\[set-goal-column] can be used to create\na semipermanent goal column for this command.\nThen instead of trying to move exactly vertically (or as close as possible),\nthis command moves to the specified goal column (or as close as possible).\nThe goal column is stored in the variable `goal-column', which is nil\nwhen there is no goal column.  Note that setting `goal-column'\noverrides `line-move-visual' and causes this command to move by buffer\nlines rather than by display lines.\"\n  (declare (interactive-only forward-line))\n  (interactive \"^p\\np\")\n  (or arg (setq arg 1))\n  (if (and next-line-add-newlines (= arg 1))\n      (if (save-excursion (end-of-line) (eobp))\n\t  ;; When adding a newline, don't expand an abbrev.\n\t  (let ((abbrev-mode nil))\n\t    (end-of-line)\n\t    (insert (if use-hard-newlines hard-newline \"\\n\")))\n\t(line-move arg nil nil try-vscroll))\n    (if (called-interactively-p 'interactive)\n\t(condition-case err\n\t    (line-move arg nil nil try-vscroll)\n\t  ((beginning-of-buffer end-of-buffer)\n\t   (signal (car err) (cdr err))))\n      (line-move arg nil nil try-vscroll)))\n  nil)\n\n(defun previous-line (&optional arg try-vscroll)\n  \"Move cursor vertically up ARG lines.\nInteractively, vscroll tall lines if `auto-window-vscroll' is enabled.\nNon-interactively, use TRY-VSCROLL to control whether to vscroll tall\nlines: if either `auto-window-vscroll' or TRY-VSCROLL is nil, this\nfunction will not vscroll.\n\nARG defaults to 1.\n\nIf there is no character in the target line exactly over the current column,\nthe cursor is positioned after the character in that line which spans this\ncolumn, or at the end of the line if it is not long enough.\n\nIf the variable `line-move-visual' is non-nil, this command moves\nby display lines.  Otherwise, it moves by buffer lines, without\ntaking variable-width characters or continued lines into account.\nSee \\\\[previous-logical-line] for a command that always moves by buffer lines.\n\nThe command \\\\[set-goal-column] can be used to create\na semipermanent goal column for this command.\nThen instead of trying to move exactly vertically (or as close as possible),\nthis command moves to the specified goal column (or as close as possible).\nThe goal column is stored in the variable `goal-column', which is nil\nwhen there is no goal column.  Note that setting `goal-column'\noverrides `line-move-visual' and causes this command to move by buffer\nlines rather than by display lines.\"\n  (declare (interactive-only\n            \"use `forward-line' with negative argument instead.\"))\n  (interactive \"^p\\np\")\n  (or arg (setq arg 1))\n  (if (called-interactively-p 'interactive)\n      (condition-case err\n\t  (line-move (- arg) nil nil try-vscroll)\n\t((beginning-of-buffer end-of-buffer)\n\t (signal (car err) (cdr err))))\n    (line-move (- arg) nil nil try-vscroll))\n  nil)\n\n(defcustom track-eol nil\n  \"Non-nil means vertical motion starting at end of line keeps to ends of lines.\nThis means moving to the end of each line moved onto.\nThe beginning of a blank line does not count as the end of a line.\nThis has no effect when the variable `line-move-visual' is non-nil.\"\n  :type 'boolean\n  :group 'editing-basics)\n\n(defcustom goal-column nil\n  \"Semipermanent goal column for vertical motion, as set by \\\\[set-goal-column], or nil.\nA non-nil setting overrides the variable `line-move-visual', which see.\"\n  :type '(choice integer\n\t\t (const :tag \"None\" nil))\n  :group 'editing-basics)\n(make-variable-buffer-local 'goal-column)\n\n(defvar temporary-goal-column 0\n  \"Current goal column for vertical motion.\nIt is the column where point was at the start of the current run\nof vertical motion commands.\n\nWhen moving by visual lines via the function `line-move-visual', it is a cons\ncell (COL . HSCROLL), where COL is the x-position, in pixels,\ndivided by the default column width, and HSCROLL is the number of\ncolumns by which window is scrolled from left margin.\n\nWhen the `track-eol' feature is doing its job, the value is\n`most-positive-fixnum'.\")\n\n(defvar last--line-number-width 0\n  \"Last value of width used for displaying line numbers.\nUsed internally by `line-move-visual'.\")\n\n(defcustom line-move-ignore-invisible t\n  \"Non-nil means commands that move by lines ignore invisible newlines.\nWhen this option is non-nil, \\\\[next-line], \\\\[previous-line], \\\\[move-end-of-line], and \\\\[move-beginning-of-line] behave\nas if newlines that are invisible didn't exist, and count\nonly visible newlines.  Thus, moving across 2 newlines\none of which is invisible will be counted as a one-line move.\nAlso, a non-nil value causes invisible text to be ignored when\ncounting columns for the purposes of keeping point in the same\ncolumn by \\\\[next-line] and \\\\[previous-line].\n\nOutline mode sets this.\"\n  :type 'boolean\n  :group 'editing-basics)\n\n(defcustom line-move-visual t\n  \"When non-nil, `line-move' moves point by visual lines.\nThis movement is based on where the cursor is displayed on the\nscreen, instead of relying on buffer contents alone.  It takes\ninto account variable-width characters and line continuation.\nIf nil, `line-move' moves point by logical lines.\nA non-nil setting of `goal-column' overrides the value of this variable\nand forces movement by logical lines.\nA window that is  horizontally scrolled also forces movement by logical\nlines.\"\n  :type 'boolean\n  :group 'editing-basics\n  :version \"23.1\")\n\n;; Only used if display-graphic-p.\n(declare-function font-info \"font.c\" (name &optional frame))\n\n(defun default-font-height ()\n  \"Return the height in pixels of the current buffer's default face font.\n\nIf the default font is remapped (see `face-remapping-alist'), the\nfunction returns the height of the remapped face.\"\n  (let ((default-font (face-font 'default)))\n    (cond\n     ((and (display-multi-font-p)\n\t   ;; Avoid calling font-info if the frame's default font was\n\t   ;; not changed since the frame was created.  That's because\n\t   ;; font-info is expensive for some fonts, see bug #14838.\n\t   (not (string= (frame-parameter nil 'font) default-font)))\n      (aref (font-info default-font) 3))\n     (t (frame-char-height)))))\n\n(defun default-font-width ()\n  \"Return the width in pixels of the current buffer's default face font.\n\nIf the default font is remapped (see `face-remapping-alist'), the\nfunction returns the width of the remapped face.\"\n  (let ((default-font (face-font 'default)))\n    (cond\n     ((and (display-multi-font-p)\n\t   ;; Avoid calling font-info if the frame's default font was\n\t   ;; not changed since the frame was created.  That's because\n\t   ;; font-info is expensive for some fonts, see bug #14838.\n\t   (not (string= (frame-parameter nil 'font) default-font)))\n      (let* ((info (font-info (face-font 'default)))\n\t     (width (aref info 11)))\n\t(if (> width 0)\n\t    width\n\t  (aref info 10))))\n     (t (frame-char-width)))))\n\n(defun default-line-height ()\n  \"Return the pixel height of current buffer's default-face text line.\n\nThe value includes `line-spacing', if any, defined for the buffer\nor the frame.\"\n  (let ((dfh (default-font-height))\n\t(lsp (if (display-graphic-p)\n\t\t (or line-spacing\n\t\t     (default-value 'line-spacing)\n\t\t     (frame-parameter nil 'line-spacing)\n\t\t     0)\n\t       0)))\n    (if (floatp lsp)\n\t(setq lsp (truncate (* (frame-char-height) lsp))))\n    (+ dfh lsp)))\n\n(defun window-screen-lines ()\n  \"Return the number of screen lines in the text area of the selected window.\n\nThis is different from `window-text-height' in that this function counts\nlines in units of the height of the font used by the default face displayed\nin the window, not in units of the frame's default font, and also accounts\nfor `line-spacing', if any, defined for the window's buffer or frame.\n\nThe value is a floating-point number.\"\n  (let ((edges (window-inside-pixel-edges))\n\t(dlh (default-line-height)))\n    (/ (float (- (nth 3 edges) (nth 1 edges))) dlh)))\n\n;; Returns non-nil if partial move was done.\n(defun line-move-partial (arg noerror &optional _to-end)\n  (if (< arg 0)\n      ;; Move backward (up).\n      ;; If already vscrolled, reduce vscroll\n      (let ((vs (window-vscroll nil t))\n\t    (dlh (default-line-height)))\n\t(when (> vs dlh)\n\t  (set-window-vscroll nil (- vs dlh) t)))\n\n    ;; Move forward (down).\n    (let* ((lh (window-line-height -1))\n\t   (rowh (car lh))\n\t   (vpos (nth 1 lh))\n\t   (ypos (nth 2 lh))\n\t   (rbot (nth 3 lh))\n\t   (this-lh (window-line-height))\n\t   (this-height (car this-lh))\n\t   (this-ypos (nth 2 this-lh))\n\t   (dlh (default-line-height))\n\t   (wslines (window-screen-lines))\n\t   (edges (window-inside-pixel-edges))\n\t   (winh (- (nth 3 edges) (nth 1 edges) 1))\n\t   py vs last-line)\n      (if (> (mod wslines 1.0) 0.0)\n\t  (setq wslines (round (+ wslines 0.5))))\n      (when (or (null lh)\n\t\t(>= rbot dlh)\n\t\t(<= ypos (- dlh))\n\t\t(null this-lh)\n\t\t(<= this-ypos (- dlh)))\n\t(unless lh\n\t  (let ((wend (pos-visible-in-window-p t nil t)))\n\t    (setq rbot (nth 3 wend)\n\t\t  rowh  (nth 4 wend)\n\t\t  vpos (nth 5 wend))))\n\t(unless this-lh\n\t  (let ((wstart (pos-visible-in-window-p nil nil t)))\n\t    (setq this-ypos (nth 2 wstart)\n\t\t  this-height (nth 4 wstart))))\n\t(setq py\n\t      (or (nth 1 this-lh)\n\t\t  (let ((ppos (posn-at-point))\n\t\t\tcol-row)\n\t\t    (setq col-row (posn-actual-col-row ppos))\n\t\t    (if col-row\n\t\t\t(- (cdr col-row) (window-vscroll))\n\t\t      (cdr (posn-col-row ppos))))))\n\t;; VPOS > 0 means the last line is only partially visible.\n\t;; But if the part that is visible is at least as tall as the\n\t;; default font, that means the line is actually fully\n\t;; readable, and something like line-spacing is hidden.  So in\n\t;; that case we accept the last line in the window as still\n\t;; visible, and consider the margin as starting one line\n\t;; later.\n\t(if (and vpos (> vpos 0))\n\t    (if (and rowh\n\t\t     (>= rowh (default-font-height))\n\t\t     (< rowh dlh))\n\t\t(setq last-line (min (- wslines scroll-margin) vpos))\n\t      (setq last-line (min (- wslines scroll-margin 1) (1- vpos)))))\n\t(cond\n\t ;; If last line of window is fully visible, and vscrolling\n\t ;; more would make this line invisible, move forward.\n\t ((and (or (< (setq vs (window-vscroll nil t)) dlh)\n\t\t   (null this-height)\n\t\t   (<= this-height dlh))\n\t       (or (null rbot) (= rbot 0)))\n\t  nil)\n\t ;; If cursor is not in the bottom scroll margin, and the\n\t ;; current line is not too tall, move forward.\n\t ((and (or (null this-height) (<= this-height winh))\n\t       vpos\n\t       (> vpos 0)\n\t       (< py last-line))\n\t  nil)\n\t ;; When already vscrolled, we vscroll some more if we can,\n\t ;; or clear vscroll and move forward at end of tall image.\n\t ((> vs 0)\n\t  (when (or (and rbot (> rbot 0))\n\t\t    (and this-height (> this-height dlh)))\n\t    (set-window-vscroll nil (+ vs dlh) t)))\n\t ;; If cursor just entered the bottom scroll margin, move forward,\n\t ;; but also optionally vscroll one line so redisplay won't recenter.\n\t ((and vpos\n\t       (> vpos 0)\n\t       (= py last-line))\n\t  ;; Don't vscroll if the partially-visible line at window\n\t  ;; bottom is not too tall (a.k.a. \"just one more text\n\t  ;; line\"): in that case, we do want redisplay to behave\n\t  ;; normally, i.e. recenter or whatever.\n\t  ;;\n\t  ;; Note: ROWH + RBOT from the value returned by\n\t  ;; pos-visible-in-window-p give the total height of the\n\t  ;; partially-visible glyph row at the end of the window.  As\n\t  ;; we are dealing with floats, we disregard sub-pixel\n\t  ;; discrepancies between that and DLH.\n\t  (if (and rowh rbot (>= (- (+ rowh rbot) winh) 1))\n\t      (set-window-vscroll nil dlh t))\n\t  (line-move-1 arg noerror)\n\t  t)\n\t ;; If there are lines above the last line, scroll-up one line.\n\t ((and vpos (> vpos 0))\n\t  (scroll-up 1)\n\t  t)\n\t ;; Finally, start vscroll.\n\t (t\n\t  (set-window-vscroll nil dlh t)))))))\n\n\n;; This is like line-move-1 except that it also performs\n;; vertical scrolling of tall images if appropriate.\n;; That is not really a clean thing to do, since it mixes\n;; scrolling with cursor motion.  But so far we don't have\n;; a cleaner solution to the problem of making C-n do something\n;; useful given a tall image.\n(defun line-move (arg &optional noerror _to-end try-vscroll)\n  \"Move forward ARG lines.\nIf NOERROR, don't signal an error if we can't move ARG lines.\nTO-END is unused.\nTRY-VSCROLL controls whether to vscroll tall lines: if either\n`auto-window-vscroll' or TRY-VSCROLL is nil, this function will\nnot vscroll.\"\n  (if noninteractive\n      (line-move-1 arg noerror)\n    (unless (and auto-window-vscroll try-vscroll\n\t\t ;; Only vscroll for single line moves\n\t\t (= (abs arg) 1)\n\t\t ;; Under scroll-conservatively, the display engine\n\t\t ;; does this better.\n\t\t (zerop scroll-conservatively)\n\t\t ;; But don't vscroll in a keyboard macro.\n\t\t (not defining-kbd-macro)\n\t\t (not executing-kbd-macro)\n\t\t (line-move-partial arg noerror))\n      (set-window-vscroll nil 0 t)\n      (if (and line-move-visual\n\t       ;; Display-based column are incompatible with goal-column.\n\t       (not goal-column)\n\t       ;; When the text in the window is scrolled to the left,\n\t       ;; display-based motion doesn't make sense (because each\n\t       ;; logical line occupies exactly one screen line).\n\t       (not (> (window-hscroll) 0))\n\t       ;; Likewise when the text _was_ scrolled to the left\n\t       ;; when the current run of vertical motion commands\n\t       ;; started.\n\t       (not (and (memq last-command\n\t\t\t       `(next-line previous-line ,this-command))\n\t\t\t auto-hscroll-mode\n\t\t\t (numberp temporary-goal-column)\n\t\t\t (>= temporary-goal-column\n\t\t\t    (- (window-width) hscroll-margin)))))\n\t  (prog1 (line-move-visual arg noerror)\n\t    ;; If we moved into a tall line, set vscroll to make\n\t    ;; scrolling through tall images more smooth.\n\t    (let ((lh (line-pixel-height))\n\t\t  (edges (window-inside-pixel-edges))\n\t\t  (dlh (default-line-height))\n\t\t  winh)\n\t      (setq winh (- (nth 3 edges) (nth 1 edges) 1))\n\t      (if (and (< arg 0)\n\t\t       (< (point) (window-start))\n\t\t       (> lh winh))\n\t\t  (set-window-vscroll\n\t\t   nil\n\t\t   (- lh dlh) t))))\n\t(line-move-1 arg noerror)))))\n\n;; Display-based alternative to line-move-1.\n;; Arg says how many lines to move.  The value is t if we can move the\n;; specified number of lines.\n(defun line-move-visual (arg &optional noerror)\n  \"Move ARG lines forward.\nIf NOERROR, don't signal an error if we can't move that many lines.\"\n  (let ((opoint (point))\n\t(hscroll (window-hscroll))\n        (lnum-width (line-number-display-width t))\n\ttarget-hscroll)\n    ;; Check if the previous command was a line-motion command, or if\n    ;; we were called from some other command.\n    (if (and (consp temporary-goal-column)\n\t     (memq last-command `(next-line previous-line ,this-command)))\n\t;; If so, there's no need to reset `temporary-goal-column',\n\t;; but we may need to hscroll.\n        (progn\n          (if (or (/= (cdr temporary-goal-column) hscroll)\n                  (>  (cdr temporary-goal-column) 0))\n              (setq target-hscroll (cdr temporary-goal-column)))\n          ;; Update the COLUMN part of temporary-goal-column if the\n          ;; line-number display changed its width since the last\n          ;; time.\n          (setq temporary-goal-column\n                (cons (+ (car temporary-goal-column)\n                         (/ (float (- lnum-width last--line-number-width))\n                            (frame-char-width)))\n                      (cdr temporary-goal-column)))\n          (setq last--line-number-width lnum-width))\n      ;; Otherwise, we should reset `temporary-goal-column'.\n      (let ((posn (posn-at-point))\n\t    x-pos)\n\t(cond\n\t ;; Handle the `overflow-newline-into-fringe' case\n\t ;; (left-fringe is for the R2L case):\n\t ((memq (nth 1 posn) '(right-fringe left-fringe))\n\t  (setq temporary-goal-column (cons (window-width) hscroll)))\n\t ((car (posn-x-y posn))\n\t  (setq x-pos (car (posn-x-y posn)))\n\t  ;; In R2L lines, the X pixel coordinate is measured from the\n\t  ;; left edge of the window, but columns are still counted\n\t  ;; from the logical-order beginning of the line, i.e. from\n\t  ;; the right edge in this case.  We need to adjust for that.\n\t  (if (eq (current-bidi-paragraph-direction) 'right-to-left)\n\t      (setq x-pos (- (window-body-width nil t) 1 x-pos)))\n\t  (setq temporary-goal-column\n\t\t(cons (/ (float x-pos)\n\t\t\t (frame-char-width))\n                      hscroll)))\n\t (executing-kbd-macro\n\t  ;; When we move beyond the first/last character visible in\n\t  ;; the window, posn-at-point will return nil, so we need to\n\t  ;; approximate the goal column as below.\n\t  (setq temporary-goal-column\n\t\t(mod (current-column) (window-text-width)))))))\n    (if target-hscroll\n\t(set-window-hscroll (selected-window) target-hscroll))\n    ;; vertical-motion can move more than it was asked to if it moves\n    ;; across display strings with newlines.  We don't want to ring\n    ;; the bell and announce beginning/end of buffer in that case.\n    (or (and (or (and (>= arg 0)\n\t\t      (>= (vertical-motion\n\t\t\t   (cons (or goal-column\n\t\t\t\t     (if (consp temporary-goal-column)\n\t\t\t\t\t (car temporary-goal-column)\n\t\t\t\t       temporary-goal-column))\n\t\t\t\t arg))\n\t\t\t  arg))\n\t\t (and (< arg 0)\n\t\t      (<= (vertical-motion\n\t\t\t   (cons (or goal-column\n\t\t\t\t     (if (consp temporary-goal-column)\n\t\t\t\t\t (car temporary-goal-column)\n\t\t\t\t       temporary-goal-column))\n\t\t\t\t arg))\n\t\t\t  arg)))\n\t     (or (>= arg 0)\n\t\t (/= (point) opoint)\n\t\t ;; If the goal column lies on a display string,\n\t\t ;; `vertical-motion' advances the cursor to the end\n\t\t ;; of the string.  For arg < 0, this can cause the\n\t\t ;; cursor to get stuck.  (Bug#3020).\n\t\t (= (vertical-motion arg) arg)))\n\t(unless noerror\n\t  (signal (if (< arg 0) 'beginning-of-buffer 'end-of-buffer)\n\t\t  nil)))))\n\n;; This is the guts of next-line and previous-line.\n;; Arg says how many lines to move.\n;; The value is t if we can move the specified number of lines.\n(defun line-move-1 (arg &optional noerror _to-end)\n  ;; Don't run any point-motion hooks, and disregard intangibility,\n  ;; for intermediate positions.\n  (let ((inhibit-point-motion-hooks t)\n\t(opoint (point))\n\t(orig-arg arg))\n    (if (consp temporary-goal-column)\n\t(setq temporary-goal-column (+ (car temporary-goal-column)\n\t\t\t\t       (cdr temporary-goal-column))))\n    (unwind-protect\n\t(progn\n\t  (if (not (memq last-command '(next-line previous-line)))\n\t      (setq temporary-goal-column\n\t\t    (if (and track-eol (eolp)\n\t\t\t     ;; Don't count beg of empty line as end of line\n\t\t\t     ;; unless we just did explicit end-of-line.\n\t\t\t     (or (not (bolp)) (eq last-command 'move-end-of-line)))\n\t\t\tmost-positive-fixnum\n\t\t      (current-column))))\n\n\t  (if (not (or (integerp selective-display)\n                       line-move-ignore-invisible))\n\t      ;; Use just newline characters.\n\t      ;; Set ARG to 0 if we move as many lines as requested.\n\t      (or (if (> arg 0)\n\t\t      (progn (if (> arg 1) (forward-line (1- arg)))\n\t\t\t     ;; This way of moving forward ARG lines\n\t\t\t     ;; verifies that we have a newline after the last one.\n\t\t\t     ;; It doesn't get confused by intangible text.\n\t\t\t     (end-of-line)\n\t\t\t     (if (zerop (forward-line 1))\n\t\t\t\t (setq arg 0)))\n\t\t    (and (zerop (forward-line arg))\n\t\t\t (bolp)\n\t\t\t (setq arg 0)))\n\t\t  (unless noerror\n\t\t    (signal (if (< arg 0)\n\t\t\t\t'beginning-of-buffer\n\t\t\t      'end-of-buffer)\n\t\t\t    nil)))\n\t    ;; Move by arg lines, but ignore invisible ones.\n\t    (let (done)\n\t      (while (and (> arg 0) (not done))\n\t\t;; If the following character is currently invisible,\n\t\t;; skip all characters with that same `invisible' property value.\n\t\t(while (and (not (eobp)) (invisible-p (point)))\n\t\t  (goto-char (next-char-property-change (point))))\n\t\t;; Move a line.\n\t\t;; We don't use `end-of-line', since we want to escape\n\t\t;; from field boundaries occurring exactly at point.\n\t\t(goto-char (constrain-to-field\n\t\t\t    (let ((inhibit-field-text-motion t))\n\t\t\t      (line-end-position))\n\t\t\t    (point) t t\n\t\t\t    'inhibit-line-move-field-capture))\n\t\t;; If there's no invisibility here, move over the newline.\n\t\t(cond\n\t\t ((eobp)\n\t\t  (if (not noerror)\n\t\t      (signal 'end-of-buffer nil)\n\t\t    (setq done t)))\n\t\t ((and (> arg 1)  ;; Use vertical-motion for last move\n\t\t       (not (integerp selective-display))\n\t\t       (not (invisible-p (point))))\n\t\t  ;; We avoid vertical-motion when possible\n\t\t  ;; because that has to fontify.\n\t\t  (forward-line 1))\n\t\t ;; Otherwise move a more sophisticated way.\n\t\t ((zerop (vertical-motion 1))\n\t\t  (if (not noerror)\n\t\t      (signal 'end-of-buffer nil)\n\t\t    (setq done t))))\n\t\t(unless done\n\t\t  (setq arg (1- arg))))\n\t      ;; The logic of this is the same as the loop above,\n\t      ;; it just goes in the other direction.\n\t      (while (and (< arg 0) (not done))\n\t\t;; For completely consistency with the forward-motion\n\t\t;; case, we should call beginning-of-line here.\n\t\t;; However, if point is inside a field and on a\n\t\t;; continued line, the call to (vertical-motion -1)\n\t\t;; below won't move us back far enough; then we return\n\t\t;; to the same column in line-move-finish, and point\n\t\t;; gets stuck -- cyd\n\t\t(forward-line 0)\n\t\t(cond\n\t\t ((bobp)\n\t\t  (if (not noerror)\n\t\t      (signal 'beginning-of-buffer nil)\n\t\t    (setq done t)))\n\t\t ((and (< arg -1) ;; Use vertical-motion for last move\n\t\t       (not (integerp selective-display))\n\t\t       (not (invisible-p (1- (point)))))\n\t\t  (forward-line -1))\n\t\t ((zerop (vertical-motion -1))\n\t\t  (if (not noerror)\n\t\t      (signal 'beginning-of-buffer nil)\n\t\t    (setq done t))))\n\t\t(unless done\n\t\t  (setq arg (1+ arg))\n\t\t  (while (and ;; Don't move over previous invis lines\n\t\t\t  ;; if our target is the middle of this line.\n\t\t\t  (or (zerop (or goal-column temporary-goal-column))\n\t\t\t      (< arg 0))\n\t\t\t  (not (bobp)) (invisible-p (1- (point))))\n\t\t    (goto-char (previous-char-property-change (point))))))))\n\t  ;; This is the value the function returns.\n\t  (= arg 0))\n\n      (cond ((> arg 0)\n\t     ;; If we did not move down as far as desired, at least go\n\t     ;; to end of line.  Be sure to call point-entered and\n\t     ;; point-left-hooks.\n\t     (let* ((npoint (prog1 (line-end-position)\n\t\t\t      (goto-char opoint)))\n\t\t    (inhibit-point-motion-hooks nil))\n\t       (goto-char npoint)))\n\t    ((< arg 0)\n\t     ;; If we did not move up as far as desired,\n\t     ;; at least go to beginning of line.\n\t     (let* ((npoint (prog1 (line-beginning-position)\n\t\t\t      (goto-char opoint)))\n\t\t    (inhibit-point-motion-hooks nil))\n\t       (goto-char npoint)))\n\t    (t\n\t     (line-move-finish (or goal-column temporary-goal-column)\n\t\t\t       opoint (> orig-arg 0)))))))\n\n(defun line-move-finish (column opoint forward)\n  (let ((repeat t))\n    (while repeat\n      ;; Set REPEAT to t to repeat the whole thing.\n      (setq repeat nil)\n\n      (let (new\n\t    (old (point))\n\t    (line-beg (line-beginning-position))\n\t    (line-end\n\t     ;; Compute the end of the line\n\t     ;; ignoring effectively invisible newlines.\n\t     (save-excursion\n\t       ;; Like end-of-line but ignores fields.\n\t       (skip-chars-forward \"^\\n\")\n\t       (while (and (not (eobp)) (invisible-p (point)))\n\t\t (goto-char (next-char-property-change (point)))\n\t\t (skip-chars-forward \"^\\n\"))\n\t       (point))))\n\n\t;; Move to the desired column.\n        (if (and line-move-visual\n                 (not (or truncate-lines truncate-partial-width-windows)))\n            ;; Under line-move-visual, goal-column should be\n            ;; interpreted in units of the frame's canonical character\n            ;; width, which is exactly what vertical-motion does.\n            (vertical-motion (cons column 0))\n          (line-move-to-column (truncate column)))\n\n\t;; Corner case: suppose we start out in a field boundary in\n\t;; the middle of a continued line.  When we get to\n\t;; line-move-finish, point is at the start of a new *screen*\n\t;; line but the same text line; then line-move-to-column would\n\t;; move us backwards.  Test using C-n with point on the \"x\" in\n\t;;   (insert \"a\" (propertize \"x\" 'field t) (make-string 89 ?y))\n\t(and forward\n\t     (< (point) old)\n\t     (goto-char old))\n\n\t(setq new (point))\n\n\t;; Process intangibility within a line.\n\t;; With inhibit-point-motion-hooks bound to nil, a call to\n\t;; goto-char moves point past intangible text.\n\n\t;; However, inhibit-point-motion-hooks controls both the\n\t;; intangibility and the point-entered/point-left hooks.  The\n\t;; following hack avoids calling the point-* hooks\n\t;; unnecessarily.  Note that we move *forward* past intangible\n\t;; text when the initial and final points are the same.\n\t(goto-char new)\n\t(let ((inhibit-point-motion-hooks nil))\n\t  (goto-char new)\n\n\t  ;; If intangibility moves us to a different (later) place\n\t  ;; in the same line, use that as the destination.\n\t  (if (<= (point) line-end)\n\t      (setq new (point))\n\t    ;; If that position is \"too late\",\n\t    ;; try the previous allowable position.\n\t    ;; See if it is ok.\n\t    (backward-char)\n\t    (if (if forward\n\t\t    ;; If going forward, don't accept the previous\n\t\t    ;; allowable position if it is before the target line.\n\t\t    (< line-beg (point))\n\t\t  ;; If going backward, don't accept the previous\n\t\t  ;; allowable position if it is still after the target line.\n\t\t  (<= (point) line-end))\n\t\t(setq new (point))\n\t      ;; As a last resort, use the end of the line.\n\t      (setq new line-end))))\n\n\t;; Now move to the updated destination, processing fields\n\t;; as well as intangibility.\n\t(goto-char opoint)\n\t(let ((inhibit-point-motion-hooks nil))\n\t  (goto-char\n\t   ;; Ignore field boundaries if the initial and final\n\t   ;; positions have the same `field' property, even if the\n\t   ;; fields are non-contiguous.  This seems to be \"nicer\"\n\t   ;; behavior in many situations.\n\t   (if (eq (get-char-property new 'field)\n\t   \t   (get-char-property opoint 'field))\n\t       new\n\t     (constrain-to-field new opoint t t\n\t\t\t\t 'inhibit-line-move-field-capture))))\n\n\t;; If all this moved us to a different line,\n\t;; retry everything within that new line.\n\t(when (or (< (point) line-beg) (> (point) line-end))\n\t  ;; Repeat the intangibility and field processing.\n\t  (setq repeat t))))))\n\n(defun line-move-to-column (col)\n  \"Try to find column COL, considering invisibility.\nThis function works only in certain cases,\nbecause what we really need is for `move-to-column'\nand `current-column' to be able to ignore invisible text.\"\n  (if (zerop col)\n      (beginning-of-line)\n    (move-to-column col))\n\n  (when (and line-move-ignore-invisible\n\t     (not (bolp)) (invisible-p (1- (point))))\n    (let ((normal-location (point))\n\t  (normal-column (current-column)))\n      ;; If the following character is currently invisible,\n      ;; skip all characters with that same `invisible' property value.\n      (while (and (not (eobp))\n\t\t  (invisible-p (point)))\n\t(goto-char (next-char-property-change (point))))\n      ;; Have we advanced to a larger column position?\n      (if (> (current-column) normal-column)\n\t  ;; We have made some progress towards the desired column.\n\t  ;; See if we can make any further progress.\n\t  (line-move-to-column (+ (current-column) (- col normal-column)))\n\t;; Otherwise, go to the place we originally found\n\t;; and move back over invisible text.\n\t;; that will get us to the same place on the screen\n\t;; but with a more reasonable buffer position.\n\t(goto-char normal-location)\n\t(let ((line-beg\n               ;; We want the real line beginning, so it's consistent\n               ;; with bolp below, otherwise we might infloop.\n               (let ((inhibit-field-text-motion t))\n                 (line-beginning-position))))\n\t  (while (and (not (bolp)) (invisible-p (1- (point))))\n\t    (goto-char (previous-char-property-change (point) line-beg))))))))\n\n(defun move-end-of-line (arg)\n  \"Move point to end of current line as displayed.\nWith argument ARG not nil or 1, move forward ARG - 1 lines first.\nIf point reaches the beginning or end of buffer, it stops there.\n\nTo ignore the effects of the `intangible' text or overlay\nproperty, bind `inhibit-point-motion-hooks' to t.\nIf there is an image in the current line, this function\ndisregards newlines that are part of the text on which the image\nrests.\"\n  (interactive \"^p\")\n  (or arg (setq arg 1))\n  (let (done)\n    (while (not done)\n      (let ((newpos\n\t     (save-excursion\n\t       (let ((goal-column 0)\n\t\t     (line-move-visual nil))\n\t\t (and (line-move arg t)\n\t\t      ;; With bidi reordering, we may not be at bol,\n\t\t      ;; so make sure we are.\n\t\t      (skip-chars-backward \"^\\n\")\n\t\t      (not (bobp))\n\t\t      (progn\n\t\t\t(while (and (not (bobp)) (invisible-p (1- (point))))\n\t\t\t  (goto-char (previous-single-char-property-change\n                                      (point) 'invisible)))\n\t\t\t(backward-char 1)))\n\t\t (point)))))\n\t(goto-char newpos)\n\t(if (and (> (point) newpos)\n\t\t (eq (preceding-char) ?\\n))\n\t    (backward-char 1)\n\t  (if (and (> (point) newpos) (not (eobp))\n\t\t   (not (eq (following-char) ?\\n)))\n\t      ;; If we skipped something intangible and now we're not\n\t      ;; really at eol, keep going.\n\t      (setq arg 1)\n\t    (setq done t)))))))\n\n(defun move-beginning-of-line (arg)\n  \"Move point to beginning of current line as displayed.\n\\(If there's an image in the line, this disregards newlines\nwhich are part of the text that the image rests on.)\n\nWith argument ARG not nil or 1, move forward ARG - 1 lines first.\nIf point reaches the beginning or end of buffer, it stops there.\n\\(But if the buffer doesn't end in a newline, it stops at the\nbeginning of the last line.)\nTo ignore intangibility, bind `inhibit-point-motion-hooks' to t.\"\n  (interactive \"^p\")\n  (or arg (setq arg 1))\n\n  (let ((orig (point))\n\tfirst-vis first-vis-field-value)\n\n    ;; Move by lines, if ARG is not 1 (the default).\n    (if (/= arg 1)\n\t(let ((line-move-visual nil))\n\t  (line-move (1- arg) t)))\n\n    ;; Move to beginning-of-line, ignoring fields and invisible text.\n    (skip-chars-backward \"^\\n\")\n    (while (and (not (bobp)) (invisible-p (1- (point))))\n      (goto-char (previous-char-property-change (point)))\n      (skip-chars-backward \"^\\n\"))\n\n    ;; Now find first visible char in the line.\n    (while (and (< (point) orig) (invisible-p (point)))\n      (goto-char (next-char-property-change (point) orig)))\n    (setq first-vis (point))\n\n    ;; See if fields would stop us from reaching FIRST-VIS.\n    (setq first-vis-field-value\n\t  (constrain-to-field first-vis orig (/= arg 1) t nil))\n\n    (goto-char (if (/= first-vis-field-value first-vis)\n\t\t   ;; If yes, obey them.\n\t\t   first-vis-field-value\n\t\t ;; Otherwise, move to START with attention to fields.\n\t\t ;; (It is possible that fields never matter in this case.)\n\t\t (constrain-to-field (point) orig\n\t\t\t\t     (/= arg 1) t nil)))))\n\n\n;; Many people have said they rarely use this feature, and often type\n;; it by accident.  Maybe it shouldn't even be on a key.\n(put 'set-goal-column 'disabled t)\n\n(defun set-goal-column (arg)\n  \"Set the current horizontal position as a goal for \\\\[next-line] and \\\\[previous-line].\nThose commands will move to this position in the line moved to\nrather than trying to keep the same horizontal position.\nWith a non-nil argument ARG, clears out the goal column\nso that \\\\[next-line] and \\\\[previous-line] resume vertical motion.\nThe goal column is stored in the variable `goal-column'.\nThis is a buffer-local setting.\"\n  (interactive \"P\")\n  (if arg\n      (progn\n        (setq goal-column nil)\n        (message \"No goal column\"))\n    (setq goal-column (current-column))\n    ;; The older method below can be erroneous if `set-goal-column' is bound\n    ;; to a sequence containing %\n    ;;(message (substitute-command-keys\n    ;;\"Goal column %d (use \\\\[set-goal-column] with an arg to unset it)\")\n    ;;goal-column)\n    (message \"%s\"\n\t     (concat\n\t      (format \"Goal column %d \" goal-column)\n\t      (substitute-command-keys\n\t       \"(use \\\\[set-goal-column] with an arg to unset it)\")))\n\n    )\n  nil)\n\f\n;;; Editing based on visual lines, as opposed to logical lines.\n\n(defun end-of-visual-line (&optional n)\n  \"Move point to end of current visual line.\nWith argument N not nil or 1, move forward N - 1 visual lines first.\nIf point reaches the beginning or end of buffer, it stops there.\nTo ignore intangibility, bind `inhibit-point-motion-hooks' to t.\"\n  (interactive \"^p\")\n  (or n (setq n 1))\n  (if (/= n 1)\n      (let ((line-move-visual t))\n\t(line-move (1- n) t)))\n  ;; Unlike `move-beginning-of-line', `move-end-of-line' doesn't\n  ;; constrain to field boundaries, so we don't either.\n  (vertical-motion (cons (window-width) 0)))\n\n(defun beginning-of-visual-line (&optional n)\n  \"Move point to beginning of current visual line.\nWith argument N not nil or 1, move forward N - 1 visual lines first.\nIf point reaches the beginning or end of buffer, it stops there.\n\\(But if the buffer doesn't end in a newline, it stops at the\nbeginning of the last visual line.)\nTo ignore intangibility, bind `inhibit-point-motion-hooks' to t.\"\n  (interactive \"^p\")\n  (or n (setq n 1))\n  (let ((opoint (point)))\n    (if (/= n 1)\n\t(let ((line-move-visual t))\n\t  (line-move (1- n) t)))\n    (vertical-motion 0)\n    ;; Constrain to field boundaries, like `move-beginning-of-line'.\n    (goto-char (constrain-to-field (point) opoint (/= n 1)))))\n\n(defun kill-visual-line (&optional arg)\n  \"Kill the rest of the visual line.\nWith prefix argument ARG, kill that many visual lines from point.\nIf ARG is negative, kill visual lines backward.\nIf ARG is zero, kill the text before point on the current visual\nline.\n\nIf you want to append the killed line to the last killed text,\nuse \\\\[append-next-kill] before \\\\[kill-line].\n\nIf the buffer is read-only, Emacs will beep and refrain from deleting\nthe line, but put the line in the kill ring anyway.  This means that\nyou can use this command to copy text from a read-only buffer.\n\\(If the variable `kill-read-only-ok' is non-nil, then this won't\neven beep.)\"\n  (interactive \"P\")\n  ;; Like in `kill-line', it's better to move point to the other end\n  ;; of the kill before killing.\n  (let ((opoint (point))\n\t(kill-whole-line (and kill-whole-line (bolp))))\n    (if arg\n\t(vertical-motion (prefix-numeric-value arg))\n      (end-of-visual-line 1)\n      (if (= (point) opoint)\n\t  (vertical-motion 1)\n\t;; Skip any trailing whitespace at the end of the visual line.\n\t;; We used to do this only if `show-trailing-whitespace' is\n\t;; nil, but that's wrong; the correct thing would be to check\n\t;; whether the trailing whitespace is highlighted.  But, it's\n\t;; OK to just do this unconditionally.\n\t(skip-chars-forward \" \\t\")))\n    (kill-region opoint (if (and kill-whole-line (= (following-char) ?\\n))\n\t\t\t    (1+ (point))\n\t\t\t  (point)))))\n\n(defun next-logical-line (&optional arg try-vscroll)\n  \"Move cursor vertically down ARG lines.\nThis is identical to `next-line', except that it always moves\nby logical lines instead of visual lines, ignoring the value of\nthe variable `line-move-visual'.\"\n  (interactive \"^p\\np\")\n  (let ((line-move-visual nil))\n    (with-no-warnings\n      (next-line arg try-vscroll))))\n\n(defun previous-logical-line (&optional arg try-vscroll)\n  \"Move cursor vertically up ARG lines.\nThis is identical to `previous-line', except that it always moves\nby logical lines instead of visual lines, ignoring the value of\nthe variable `line-move-visual'.\"\n  (interactive \"^p\\np\")\n  (let ((line-move-visual nil))\n    (with-no-warnings\n      (previous-line arg try-vscroll))))\n\n(defgroup visual-line nil\n  \"Editing based on visual lines.\"\n  :group 'convenience\n  :version \"23.1\")\n\n(defvar visual-line-mode-map\n  (let ((map (make-sparse-keymap)))\n    (define-key map [remap kill-line] 'kill-visual-line)\n    (define-key map [remap move-beginning-of-line] 'beginning-of-visual-line)\n    (define-key map [remap move-end-of-line]  'end-of-visual-line)\n    ;; These keybindings interfere with xterm function keys.  Are\n    ;; there any other suitable bindings?\n    ;; (define-key map \"\\M-[\" 'previous-logical-line)\n    ;; (define-key map \"\\M-]\" 'next-logical-line)\n    map))\n\n(defcustom visual-line-fringe-indicators '(nil nil)\n  \"How fringe indicators are shown for wrapped lines in `visual-line-mode'.\nThe value should be a list of the form (LEFT RIGHT), where LEFT\nand RIGHT are symbols representing the bitmaps to display, to\nindicate wrapped lines, in the left and right fringes respectively.\nSee also `fringe-indicator-alist'.\nThe default is not to display fringe indicators for wrapped lines.\nThis variable does not affect fringe indicators displayed for\nother purposes.\"\n  :type '(list (choice (const :tag \"Hide left indicator\" nil)\n\t\t       (const :tag \"Left curly arrow\" left-curly-arrow)\n\t\t       (symbol :tag \"Other bitmap\"))\n\t       (choice (const :tag \"Hide right indicator\" nil)\n\t\t       (const :tag \"Right curly arrow\" right-curly-arrow)\n\t\t       (symbol :tag \"Other bitmap\")))\n  :set (lambda (symbol value)\n\t (dolist (buf (buffer-list))\n\t   (with-current-buffer buf\n\t     (when (and (boundp 'visual-line-mode)\n\t\t\t(symbol-value 'visual-line-mode))\n\t       (setq fringe-indicator-alist\n\t\t     (cons (cons 'continuation value)\n\t\t\t   (assq-delete-all\n\t\t\t    'continuation\n\t\t\t    (copy-tree fringe-indicator-alist)))))))\n\t (set-default symbol value)))\n\n(defvar visual-line--saved-state nil)\n\n(define-minor-mode visual-line-mode\n  \"Toggle visual line based editing (Visual Line mode) in the current buffer.\nInteractively, with a prefix argument, enable\nVisual Line mode if the prefix argument is positive,\nand disable it otherwise.  If called from Lisp, toggle\nthe mode if ARG is `toggle', disable the mode if ARG is\na non-positive integer, and enable the mode otherwise\n\\(including if ARG is omitted or nil or a positive integer).\n\nWhen Visual Line mode is enabled, `word-wrap' is turned on in\nthis buffer, and simple editing commands are redefined to act on\nvisual lines, not logical lines.  See Info node `Visual Line\nMode' for details.\"\n  :keymap visual-line-mode-map\n  :group 'visual-line\n  :lighter \" Wrap\"\n  (if visual-line-mode\n      (progn\n\t(set (make-local-variable 'visual-line--saved-state) nil)\n\t;; Save the local values of some variables, to be restored if\n\t;; visual-line-mode is turned off.\n\t(dolist (var '(line-move-visual truncate-lines\n\t\t       truncate-partial-width-windows\n\t\t       word-wrap fringe-indicator-alist))\n\t  (if (local-variable-p var)\n\t      (push (cons var (symbol-value var))\n\t\t    visual-line--saved-state)))\n\t(set (make-local-variable 'line-move-visual) t)\n\t(set (make-local-variable 'truncate-partial-width-windows) nil)\n\t(setq truncate-lines nil\n\t      word-wrap t\n\t      fringe-indicator-alist\n\t      (cons (cons 'continuation visual-line-fringe-indicators)\n\t\t    fringe-indicator-alist)))\n    (kill-local-variable 'line-move-visual)\n    (kill-local-variable 'word-wrap)\n    (kill-local-variable 'truncate-lines)\n    (kill-local-variable 'truncate-partial-width-windows)\n    (kill-local-variable 'fringe-indicator-alist)\n    (dolist (saved visual-line--saved-state)\n      (set (make-local-variable (car saved)) (cdr saved)))\n    (kill-local-variable 'visual-line--saved-state)))\n\n(defun turn-on-visual-line-mode ()\n  (visual-line-mode 1))\n\n(define-globalized-minor-mode global-visual-line-mode\n  visual-line-mode turn-on-visual-line-mode)\n\n\f\n(defun transpose-chars (arg)\n  \"Interchange characters around point, moving forward one character.\nWith prefix arg ARG, effect is to take character before point\nand drag it forward past ARG other characters (backward if ARG negative).\nIf no argument and at end of line, the previous two chars are exchanged.\"\n  (interactive \"*P\")\n  (when (and (null arg) (eolp) (not (bobp))\n\t     (not (get-text-property (1- (point)) 'read-only)))\n    (forward-char -1))\n  (transpose-subr 'forward-char (prefix-numeric-value arg)))\n\n(defun transpose-words (arg)\n  \"Interchange words around point, leaving point at end of them.\nWith prefix arg ARG, effect is to take word before or around point\nand drag it forward past ARG other words (backward if ARG negative).\nIf ARG is zero, the words around or after point and around or after mark\nare interchanged.\"\n  ;; FIXME: `foo a!nd bar' should transpose into `bar and foo'.\n  (interactive \"*p\")\n  (transpose-subr 'forward-word arg))\n\n(defun transpose-sexps (arg)\n  \"Like \\\\[transpose-chars] (`transpose-chars'), but applies to sexps.\nUnlike `transpose-words', point must be between the two sexps and not\nin the middle of a sexp to be transposed.\nWith non-zero prefix arg ARG, effect is to take the sexp before point\nand drag it forward past ARG other sexps (backward if ARG is negative).\nIf ARG is zero, the sexps ending at or after point and at or after mark\nare interchanged.\"\n  (interactive \"*p\")\n  (transpose-subr\n   (lambda (arg)\n     ;; Here we should try to simulate the behavior of\n     ;; (cons (progn (forward-sexp x) (point))\n     ;;       (progn (forward-sexp (- x)) (point)))\n     ;; Except that we don't want to rely on the second forward-sexp\n     ;; putting us back to where we want to be, since forward-sexp-function\n     ;; might do funny things like infix-precedence.\n     (if (if (> arg 0)\n\t     (looking-at \"\\\\sw\\\\|\\\\s_\")\n\t   (and (not (bobp))\n\t\t(save-excursion (forward-char -1) (looking-at \"\\\\sw\\\\|\\\\s_\"))))\n\t ;; Jumping over a symbol.  We might be inside it, mind you.\n\t (progn (funcall (if (> arg 0)\n\t\t\t     'skip-syntax-backward 'skip-syntax-forward)\n\t\t\t \"w_\")\n\t\t(cons (save-excursion (forward-sexp arg) (point)) (point)))\n       ;; Otherwise, we're between sexps.  Take a step back before jumping\n       ;; to make sure we'll obey the same precedence no matter which direction\n       ;; we're going.\n       (funcall (if (> arg 0) 'skip-syntax-backward 'skip-syntax-forward) \" .\")\n       (cons (save-excursion (forward-sexp arg) (point))\n\t     (progn (while (or (forward-comment (if (> arg 0) 1 -1))\n\t\t\t       (not (zerop (funcall (if (> arg 0)\n\t\t\t\t\t\t\t'skip-syntax-forward\n\t\t\t\t\t\t      'skip-syntax-backward)\n\t\t\t\t\t\t    \".\")))))\n\t\t    (point)))))\n   arg 'special))\n\n(defun transpose-lines (arg)\n  \"Exchange current line and previous line, leaving point after both.\nWith argument ARG, takes previous line and moves it past ARG lines.\nWith argument 0, interchanges line point is in with line mark is in.\"\n  (interactive \"*p\")\n  (transpose-subr (function\n\t\t   (lambda (arg)\n\t\t     (if (> arg 0)\n\t\t\t (progn\n\t\t\t   ;; Move forward over ARG lines,\n\t\t\t   ;; but create newlines if necessary.\n\t\t\t   (setq arg (forward-line arg))\n\t\t\t   (if (/= (preceding-char) ?\\n)\n\t\t\t       (setq arg (1+ arg)))\n\t\t\t   (if (> arg 0)\n\t\t\t       (newline arg)))\n\t\t       (forward-line arg))))\n\t\t  arg))\n\n;; FIXME seems to leave point BEFORE the current object when ARG = 0,\n;; which seems inconsistent with the ARG /= 0 case.\n;; FIXME document SPECIAL.\n(defun transpose-subr (mover arg &optional special)\n  \"Subroutine to do the work of transposing objects.\nWorks for lines, sentences, paragraphs, etc.  MOVER is a function that\nmoves forward by units of the given object (e.g. forward-sentence,\nforward-paragraph).  If ARG is zero, exchanges the current object\nwith the one containing mark.  If ARG is an integer, moves the\ncurrent object past ARG following (if ARG is positive) or\npreceding (if ARG is negative) objects, leaving point after the\ncurrent object.\"\n  (let ((aux (if special mover\n\t       (lambda (x)\n\t\t (cons (progn (funcall mover x) (point))\n\t\t       (progn (funcall mover (- x)) (point))))))\n\tpos1 pos2)\n    (cond\n     ((= arg 0)\n      (save-excursion\n\t(setq pos1 (funcall aux 1))\n\t(goto-char (or (mark) (error \"No mark set in this buffer\")))\n\t(setq pos2 (funcall aux 1))\n\t(transpose-subr-1 pos1 pos2))\n      (exchange-point-and-mark))\n     ((> arg 0)\n      (setq pos1 (funcall aux -1))\n      (setq pos2 (funcall aux arg))\n      (transpose-subr-1 pos1 pos2)\n      (goto-char (car pos2)))\n     (t\n      (setq pos1 (funcall aux -1))\n      (goto-char (car pos1))\n      (setq pos2 (funcall aux arg))\n      (transpose-subr-1 pos1 pos2)\n      (goto-char (+ (car pos2) (- (cdr pos1) (car pos1))))))))\n\n(defun transpose-subr-1 (pos1 pos2)\n  (when (> (car pos1) (cdr pos1)) (setq pos1 (cons (cdr pos1) (car pos1))))\n  (when (> (car pos2) (cdr pos2)) (setq pos2 (cons (cdr pos2) (car pos2))))\n  (when (> (car pos1) (car pos2))\n    (let ((swap pos1))\n      (setq pos1 pos2 pos2 swap)))\n  (if (> (cdr pos1) (car pos2)) (error \"Don't have two things to transpose\"))\n  (atomic-change-group\n    ;; This sequence of insertions attempts to preserve marker\n    ;; positions at the start and end of the transposed objects.\n    (let* ((word (buffer-substring (car pos2) (cdr pos2)))\n\t   (len1 (- (cdr pos1) (car pos1)))\n\t   (len2 (length word))\n\t   (boundary (make-marker)))\n      (set-marker boundary (car pos2))\n      (goto-char (cdr pos1))\n      (insert-before-markers word)\n      (setq word (delete-and-extract-region (car pos1) (+ (car pos1) len1)))\n      (goto-char boundary)\n      (insert word)\n      (goto-char (+ boundary len1))\n      (delete-region (point) (+ (point) len2))\n      (set-marker boundary nil))))\n\f\n(defun backward-word (&optional arg)\n  \"Move backward until encountering the beginning of a word.\nWith argument ARG, do this that many times.\nIf ARG is omitted or nil, move point backward one word.\n\nThe word boundaries are normally determined by the buffer's\nsyntax table and character script (according to\n`char-script-table'), but `find-word-boundary-function-table',\nsuch as set up by `subword-mode', can change that.  If a Lisp\nprogram needs to move by words determined strictly by the syntax\ntable, it should use `backward-word-strictly' instead.  See Info\nnode `(elisp) Word Motion' for details.\"\n  (interactive \"^p\")\n  (forward-word (- (or arg 1))))\n\n(defun mark-word (&optional arg allow-extend)\n  \"Set mark ARG words away from point.\nThe place mark goes is the same place \\\\[forward-word] would\nmove to with the same argument.\nInteractively, if this command is repeated\nor (in Transient Mark mode) if the mark is active,\nit marks the next ARG words after the ones already marked.\"\n  (interactive \"P\\np\")\n  (cond ((and allow-extend\n\t      (or (and (eq last-command this-command) (mark t))\n\t\t  (region-active-p)))\n\t (setq arg (if arg (prefix-numeric-value arg)\n\t\t     (if (< (mark) (point)) -1 1)))\n\t (set-mark\n\t  (save-excursion\n\t    (goto-char (mark))\n\t    (forward-word arg)\n\t    (point))))\n\t(t\n\t (push-mark\n\t  (save-excursion\n\t    (forward-word (prefix-numeric-value arg))\n\t    (point))\n\t  nil t))))\n\n(defun kill-word (arg)\n  \"Kill characters forward until encountering the end of a word.\nWith argument ARG, do this that many times.\"\n  (interactive \"p\")\n  (kill-region (point) (progn (forward-word arg) (point))))\n\n(defun backward-kill-word (arg)\n  \"Kill characters backward until encountering the beginning of a word.\nWith argument ARG, do this that many times.\"\n  (interactive \"p\")\n  (kill-word (- arg)))\n\n(defun current-word (&optional strict really-word)\n  \"Return the word at or near point, as a string.\nThe return value includes no text properties.\n\nIf optional arg STRICT is non-nil, return nil unless point is\nwithin or adjacent to a word, otherwise look for a word within\npoint's line.  If there is no word anywhere on point's line, the\nvalue is nil regardless of STRICT.\n\nBy default, this function treats as a single word any sequence of\ncharacters that have either word or symbol syntax.  If optional\narg REALLY-WORD is non-nil, only characters of word syntax can\nconstitute a word.\"\n  (save-excursion\n    (let* ((oldpoint (point)) (start (point)) (end (point))\n\t   (syntaxes (if really-word \"w\" \"w_\"))\n\t   (not-syntaxes (concat \"^\" syntaxes)))\n      (skip-syntax-backward syntaxes) (setq start (point))\n      (goto-char oldpoint)\n      (skip-syntax-forward syntaxes) (setq end (point))\n      (when (and (eq start oldpoint) (eq end oldpoint)\n\t\t ;; Point is neither within nor adjacent to a word.\n\t\t (not strict))\n\t;; Look for preceding word in same line.\n\t(skip-syntax-backward not-syntaxes (line-beginning-position))\n\t(if (bolp)\n\t    ;; No preceding word in same line.\n\t    ;; Look for following word in same line.\n\t    (progn\n\t      (skip-syntax-forward not-syntaxes (line-end-position))\n\t      (setq start (point))\n\t      (skip-syntax-forward syntaxes)\n\t      (setq end (point)))\n\t  (setq end (point))\n\t  (skip-syntax-backward syntaxes)\n\t  (setq start (point))))\n      ;; If we found something nonempty, return it as a string.\n      (unless (= start end)\n\t(buffer-substring-no-properties start end)))))\n\f\n(defcustom fill-prefix nil\n  \"String for filling to insert at front of new line, or nil for none.\"\n  :type '(choice (const :tag \"None\" nil)\n\t\t string)\n  :group 'fill)\n(make-variable-buffer-local 'fill-prefix)\n(put 'fill-prefix 'safe-local-variable 'string-or-null-p)\n\n(defcustom auto-fill-inhibit-regexp nil\n  \"Regexp to match lines which should not be auto-filled.\"\n  :type '(choice (const :tag \"None\" nil)\n\t\t regexp)\n  :group 'fill)\n\n(defun do-auto-fill ()\n  \"The default value for `normal-auto-fill-function'.\nThis is the default auto-fill function, some major modes use a different one.\nReturns t if it really did any work.\"\n  (let (fc justify give-up\n\t   (fill-prefix fill-prefix))\n    (if (or (not (setq justify (current-justification)))\n\t    (null (setq fc (current-fill-column)))\n\t    (and (eq justify 'left)\n\t\t (<= (current-column) fc))\n\t    (and auto-fill-inhibit-regexp\n\t\t (save-excursion (beginning-of-line)\n\t\t\t\t (looking-at auto-fill-inhibit-regexp))))\n\tnil ;; Auto-filling not required\n      (if (memq justify '(full center right))\n\t  (save-excursion (unjustify-current-line)))\n\n      ;; Choose a fill-prefix automatically.\n      (when (and adaptive-fill-mode\n\t\t (or (null fill-prefix) (string= fill-prefix \"\")))\n\t(let ((prefix\n\t       (fill-context-prefix\n\t\t(save-excursion (fill-forward-paragraph -1) (point))\n\t\t(save-excursion (fill-forward-paragraph 1) (point)))))\n\t  (and prefix (not (equal prefix \"\"))\n\t       ;; Use auto-indentation rather than a guessed empty prefix.\n\t       (not (and fill-indent-according-to-mode\n\t\t\t (string-match \"\\\\`[ \\t]*\\\\'\" prefix)))\n\t       (setq fill-prefix prefix))))\n\n      (while (and (not give-up) (> (current-column) fc))\n        ;; Determine where to split the line.\n        (let ((fill-point\n               (save-excursion\n                 (beginning-of-line)\n                 ;; Don't split earlier in the line than the length of the\n                 ;; fill prefix, since the resulting line would be longer.\n                 (when fill-prefix\n                   (move-to-column (string-width fill-prefix)))\n                 (let ((after-prefix (point)))\n                    (move-to-column (1+ fc))\n                    (fill-move-to-break-point after-prefix)\n                    (point)))))\n\n\t  ;; See whether the place we found is any good.\n\t  (if (save-excursion\n\t\t(goto-char fill-point)\n\t\t(or (bolp)\n\t\t    ;; There is no use breaking at end of line.\n\t\t    (save-excursion (skip-chars-forward \" \") (eolp))\n\t\t    ;; Don't split right after a comment starter\n\t\t    ;; since we would just make another comment starter.\n\t\t    (and comment-start-skip\n\t\t\t (let ((limit (point)))\n\t\t\t   (beginning-of-line)\n\t\t\t   (and (re-search-forward comment-start-skip\n\t\t\t\t\t\t   limit t)\n\t\t\t\t(eq (point) limit))))))\n\t      ;; No good place to break => stop trying.\n\t      (setq give-up t)\n\t    ;; Ok, we have a useful place to break the line.  Do it.\n\t    (let ((prev-column (current-column)))\n\t      ;; If point is at the fill-point, do not `save-excursion'.\n\t      ;; Otherwise, if a comment prefix or fill-prefix is inserted,\n\t      ;; point will end up before it rather than after it.\n\t      (if (save-excursion\n\t\t    (skip-chars-backward \" \\t\")\n\t\t    (= (point) fill-point))\n\t\t  (default-indent-new-line t)\n\t\t(save-excursion\n\t\t  (goto-char fill-point)\n\t\t  (default-indent-new-line t)))\n\t      ;; Now do justification, if required\n\t      (if (not (eq justify 'left))\n\t\t  (save-excursion\n\t\t    (end-of-line 0)\n\t\t    (justify-current-line justify nil t)))\n\t      ;; If making the new line didn't reduce the hpos of\n\t      ;; the end of the line, then give up now;\n\t      ;; trying again will not help.\n\t      (if (>= (current-column) prev-column)\n\t\t  (setq give-up t))))))\n      ;; Justify last line.\n      (justify-current-line justify t t)\n      t)))\n\n(defvar comment-line-break-function 'comment-indent-new-line\n  \"Mode-specific function which line breaks and continues a comment.\nThis function is called during auto-filling when a comment syntax\nis defined.\nThe function should take a single optional argument, which is a flag\nindicating whether it should use soft newlines.\")\n\n(defun default-indent-new-line (&optional soft)\n  \"Break line at point and indent.\nIf a comment syntax is defined, call `comment-indent-new-line'.\n\nThe inserted newline is marked hard if variable `use-hard-newlines' is true,\nunless optional argument SOFT is non-nil.\"\n  (interactive)\n  (if comment-start\n      (funcall comment-line-break-function soft)\n    ;; Insert the newline before removing empty space so that markers\n    ;; get preserved better.\n    (if soft (insert-and-inherit ?\\n) (newline 1))\n    (save-excursion (forward-char -1) (delete-horizontal-space))\n    (delete-horizontal-space)\n\n    (if (and fill-prefix (not adaptive-fill-mode))\n\t;; Blindly trust a non-adaptive fill-prefix.\n\t(progn\n\t  (indent-to-left-margin)\n\t  (insert-before-markers-and-inherit fill-prefix))\n\n      (cond\n       ;; If there's an adaptive prefix, use it unless we're inside\n       ;; a comment and the prefix is not a comment starter.\n       (fill-prefix\n\t(indent-to-left-margin)\n\t(insert-and-inherit fill-prefix))\n       ;; If we're not inside a comment, just try to indent.\n       (t (indent-according-to-mode))))))\n\n(defun internal-auto-fill ()\n  \"The function called by `self-insert-command' to perform auto-filling.\"\n  (when (or (not comment-start)\n            (not comment-auto-fill-only-comments)\n            (nth 4 (syntax-ppss)))\n    (funcall auto-fill-function)))\n\n(defvar normal-auto-fill-function 'do-auto-fill\n  \"The function to use for `auto-fill-function' if Auto Fill mode is turned on.\nSome major modes set this.\")\n\n(put 'auto-fill-function :minor-mode-function 'auto-fill-mode)\n;; `functions' and `hooks' are usually unsafe to set, but setting\n;; auto-fill-function to nil in a file-local setting is safe and\n;; can be useful to prevent auto-filling.\n(put 'auto-fill-function 'safe-local-variable 'null)\n\n(define-minor-mode auto-fill-mode\n  \"Toggle automatic line breaking (Auto Fill mode).\nInteractively, with a prefix argument, enable\nAuto Fill mode if the prefix argument is positive,\nand disable it otherwise.  If called from Lisp, toggle\nthe mode if ARG is `toggle', disable the mode if ARG is\na non-positive integer, and enable the mode otherwise\n\\(including if ARG is omitted or nil or a positive integer).\n\nWhen Auto Fill mode is enabled, inserting a space at a column\nbeyond `current-fill-column' automatically breaks the line at a\nprevious space.\n\nWhen `auto-fill-mode' is on, the `auto-fill-function' variable is\nnon-nil.\n\nThe value of `normal-auto-fill-function' specifies the function to use\nfor `auto-fill-function' when turning Auto Fill mode on.\"\n  :variable (auto-fill-function\n             . (lambda (v) (setq auto-fill-function\n                            (if v normal-auto-fill-function)))))\n\n;; This holds a document string used to document auto-fill-mode.\n(defun auto-fill-function ()\n  \"Automatically break line at a previous space, in insertion of text.\"\n  nil)\n\n(defun turn-on-auto-fill ()\n  \"Unconditionally turn on Auto Fill mode.\"\n  (auto-fill-mode 1))\n\n(defun turn-off-auto-fill ()\n  \"Unconditionally turn off Auto Fill mode.\"\n  (auto-fill-mode -1))\n\n(custom-add-option 'text-mode-hook 'turn-on-auto-fill)\n\n(defun set-fill-column (arg)\n  \"Set `fill-column' to specified argument.\nUse \\\\[universal-argument] followed by a number to specify a column.\nJust \\\\[universal-argument] as argument means to use the current column.\"\n  (interactive\n   (list (or current-prefix-arg\n             ;; We used to use current-column silently, but C-x f is too easily\n             ;; typed as a typo for C-x C-f, so we turned it into an error and\n             ;; now an interactive prompt.\n             (read-number \"Set fill-column to: \" (current-column)))))\n  (if (consp arg)\n      (setq arg (current-column)))\n  (if (not (integerp arg))\n      ;; Disallow missing argument; it's probably a typo for C-x C-f.\n      (error \"set-fill-column requires an explicit argument\")\n    (message \"Fill column set to %d (was %d)\" arg fill-column)\n    (setq fill-column arg)))\n\f\n(defun set-selective-display (arg)\n  \"Set `selective-display' to ARG; clear it if no arg.\nWhen the value of `selective-display' is a number > 0,\nlines whose indentation is >= that value are not displayed.\nThe variable `selective-display' has a separate value for each buffer.\"\n  (interactive \"P\")\n  (if (eq selective-display t)\n      (error \"selective-display already in use for marked lines\"))\n  (let ((current-vpos\n\t (save-restriction\n\t   (narrow-to-region (point-min) (point))\n\t   (goto-char (window-start))\n\t   (vertical-motion (window-height)))))\n    (setq selective-display\n\t  (and arg (prefix-numeric-value arg)))\n    (recenter current-vpos))\n  (set-window-start (selected-window) (window-start))\n  (princ \"selective-display set to \" t)\n  (prin1 selective-display t)\n  (princ \".\" t))\n\n(defvaralias 'indicate-unused-lines 'indicate-empty-lines)\n\n(defun toggle-truncate-lines (&optional arg)\n  \"Toggle truncating of long lines for the current buffer.\nWhen truncating is off, long lines are folded.\nWith prefix argument ARG, truncate long lines if ARG is positive,\notherwise fold them.  Note that in side-by-side windows, this\ncommand has no effect if `truncate-partial-width-windows' is\nnon-nil.\"\n  (interactive \"P\")\n  (setq truncate-lines\n\t(if (null arg)\n\t    (not truncate-lines)\n\t  (> (prefix-numeric-value arg) 0)))\n  (force-mode-line-update)\n  (unless truncate-lines\n    (let ((buffer (current-buffer)))\n      (walk-windows (lambda (window)\n\t\t      (if (eq buffer (window-buffer window))\n\t\t\t  (set-window-hscroll window 0)))\n\t\t    nil t)))\n  (message \"Truncate long lines %s\"\n\t   (if truncate-lines \"enabled\" \"disabled\")))\n\n(defun toggle-word-wrap (&optional arg)\n  \"Toggle whether to use word-wrapping for continuation lines.\nWith prefix argument ARG, wrap continuation lines at word boundaries\nif ARG is positive, otherwise wrap them at the right screen edge.\nThis command toggles the value of `word-wrap'.  It has no effect\nif long lines are truncated.\"\n  (interactive \"P\")\n  (setq word-wrap\n\t(if (null arg)\n\t    (not word-wrap)\n\t  (> (prefix-numeric-value arg) 0)))\n  (force-mode-line-update)\n  (message \"Word wrapping %s\"\n\t   (if word-wrap \"enabled\" \"disabled\")))\n\n(defvar overwrite-mode-textual (purecopy \" Ovwrt\")\n  \"The string displayed in the mode line when in overwrite mode.\")\n(defvar overwrite-mode-binary (purecopy \" Bin Ovwrt\")\n  \"The string displayed in the mode line when in binary overwrite mode.\")\n\n(define-minor-mode overwrite-mode\n  \"Toggle Overwrite mode.\nWith a prefix argument ARG, enable Overwrite mode if ARG is\npositive, and disable it otherwise.  If called from Lisp, enable\nthe mode if ARG is omitted or nil.\n\nWhen Overwrite mode is enabled, printing characters typed in\nreplace existing text on a one-for-one basis, rather than pushing\nit to the right.  At the end of a line, such characters extend\nthe line.  Before a tab, such characters insert until the tab is\nfilled in.  \\\\[quoted-insert] still inserts characters in\noverwrite mode; this is supposed to make it easier to insert\ncharacters when necessary.\"\n  :variable (overwrite-mode\n             . (lambda (v) (setq overwrite-mode (if v 'overwrite-mode-textual)))))\n\n(define-minor-mode binary-overwrite-mode\n  \"Toggle Binary Overwrite mode.\nWith a prefix argument ARG, enable Binary Overwrite mode if ARG\nis positive, and disable it otherwise.  If called from Lisp,\nenable the mode if ARG is omitted or nil.\n\nWhen Binary Overwrite mode is enabled, printing characters typed\nin replace existing text.  Newlines are not treated specially, so\ntyping at the end of a line joins the line to the next, with the\ntyped character between them.  Typing before a tab character\nsimply replaces the tab with the character typed.\n\\\\[quoted-insert] replaces the text at the cursor, just as\nordinary typing characters do.\n\nNote that Binary Overwrite mode is not its own minor mode; it is\na specialization of overwrite mode, entered by setting the\n`overwrite-mode' variable to `overwrite-mode-binary'.\"\n  :variable (overwrite-mode\n             . (lambda (v) (setq overwrite-mode (if v 'overwrite-mode-binary)))))\n\n(define-minor-mode line-number-mode\n  \"Toggle line number display in the mode line (Line Number mode).\nWith a prefix argument ARG, enable Line Number mode if ARG is\npositive, and disable it otherwise.  If called from Lisp, enable\nthe mode if ARG is omitted or nil.\n\nLine numbers do not appear for very large buffers and buffers\nwith very long lines; see variables `line-number-display-limit'\nand `line-number-display-limit-width'.\"\n  :init-value t :global t :group 'mode-line)\n\n(define-minor-mode column-number-mode\n  \"Toggle column number display in the mode line (Column Number mode).\nWith a prefix argument ARG, enable Column Number mode if ARG is\npositive, and disable it otherwise.\n\nIf called from Lisp, enable the mode if ARG is omitted or nil.\"\n  :global t :group 'mode-line)\n\n(define-minor-mode size-indication-mode\n  \"Toggle buffer size display in the mode line (Size Indication mode).\nWith a prefix argument ARG, enable Size Indication mode if ARG is\npositive, and disable it otherwise.\n\nIf called from Lisp, enable the mode if ARG is omitted or nil.\"\n  :global t :group 'mode-line)\n\n(define-minor-mode auto-save-mode\n  \"Toggle auto-saving in the current buffer (Auto Save mode).\nWith a prefix argument ARG, enable Auto Save mode if ARG is\npositive, and disable it otherwise.\n\nIf called from Lisp, enable the mode if ARG is omitted or nil.\"\n  :variable ((and buffer-auto-save-file-name\n                  ;; If auto-save is off because buffer has shrunk,\n                  ;; then toggling should turn it on.\n                  (>= buffer-saved-size 0))\n             . (lambda (val)\n                 (setq buffer-auto-save-file-name\n                       (cond\n                        ((null val) nil)\n                        ((and buffer-file-name auto-save-visited-file-name\n                              (not buffer-read-only))\n                         buffer-file-name)\n                        (t (make-auto-save-file-name))))))\n  ;; If -1 was stored here, to temporarily turn off saving,\n  ;; turn it back on.\n  (and (< buffer-saved-size 0)\n       (setq buffer-saved-size 0)))\n\f\n(defgroup paren-blinking nil\n  \"Blinking matching of parens and expressions.\"\n  :prefix \"blink-matching-\"\n  :group 'paren-matching)\n\n(defcustom blink-matching-paren t\n  \"Non-nil means show matching open-paren when close-paren is inserted.\nIf t, highlight the paren.  If `jump', briefly move cursor to its\nposition.  If `jump-offscreen', move cursor there even if the\nposition is off screen.  With any other non-nil value, the\noff-screen position of the opening paren will be shown in the\necho area.\"\n  :type '(choice\n          (const :tag \"Disable\" nil)\n          (const :tag \"Highlight\" t)\n          (const :tag \"Move cursor\" jump)\n          (const :tag \"Move cursor, even if off screen\" jump-offscreen))\n  :group 'paren-blinking)\n\n(defcustom blink-matching-paren-on-screen t\n  \"Non-nil means show matching open-paren when it is on screen.\nIf nil, don't show it (but the open-paren can still be shown\nin the echo area when it is off screen).\n\nThis variable has no effect if `blink-matching-paren' is nil.\n\\(In that case, the open-paren is never shown.)\nIt is also ignored if `show-paren-mode' is enabled.\"\n  :type 'boolean\n  :group 'paren-blinking)\n\n(defcustom blink-matching-paren-distance (* 100 1024)\n  \"If non-nil, maximum distance to search backwards for matching open-paren.\nIf nil, search stops at the beginning of the accessible portion of the buffer.\"\n  :version \"23.2\"                       ; 25->100k\n  :type '(choice (const nil) integer)\n  :group 'paren-blinking)\n\n(defcustom blink-matching-delay 1\n  \"Time in seconds to delay after showing a matching paren.\"\n  :type 'number\n  :group 'paren-blinking)\n\n(defcustom blink-matching-paren-dont-ignore-comments nil\n  \"If nil, `blink-matching-paren' ignores comments.\nMore precisely, when looking for the matching parenthesis,\nit skips the contents of comments that end before point.\"\n  :type 'boolean\n  :group 'paren-blinking)\n\n(defun blink-matching-check-mismatch (start end)\n  \"Return whether or not START...END are matching parens.\nEND is the current point and START is the blink position.\nSTART might be nil if no matching starter was found.\nReturns non-nil if we find there is a mismatch.\"\n  (let* ((end-syntax (syntax-after (1- end)))\n         (matching-paren (and (consp end-syntax)\n                              (eq (syntax-class end-syntax) 5)\n                              (cdr end-syntax))))\n    ;; For self-matched chars like \" and $, we can't know when they're\n    ;; mismatched or unmatched, so we can only do it for parens.\n    (when matching-paren\n      (not (and start\n                (or\n                 (eq (char-after start) matching-paren)\n                 ;; The cdr might hold a new paren-class info rather than\n                 ;; a matching-char info, in which case the two CDRs\n                 ;; should match.\n                 (eq matching-paren (cdr-safe (syntax-after start)))))))))\n\n(defvar blink-matching-check-function #'blink-matching-check-mismatch\n  \"Function to check parentheses mismatches.\nThe function takes two arguments (START and END) where START is the\nposition just before the opening token and END is the position right after.\nSTART can be nil, if it was not found.\nThe function should return non-nil if the two tokens do not match.\")\n\n(defvar blink-matching--overlay\n  (let ((ol (make-overlay (point) (point) nil t)))\n    (overlay-put ol 'face 'show-paren-match)\n    (delete-overlay ol)\n    ol)\n  \"Overlay used to highlight the matching paren.\")\n\n(defun blink-matching-open ()\n  \"Momentarily highlight the beginning of the sexp before point.\"\n  (interactive)\n  (when (and (not (bobp))\n\t     blink-matching-paren)\n    (let* ((oldpos (point))\n\t   (message-log-max nil) ; Don't log messages about paren matching.\n\t   (blinkpos\n            (save-excursion\n              (save-restriction\n                (if blink-matching-paren-distance\n                    (narrow-to-region\n                     (max (minibuffer-prompt-end) ;(point-min) unless minibuf.\n                          (- (point) blink-matching-paren-distance))\n                     oldpos))\n                (let ((parse-sexp-ignore-comments\n                       (and parse-sexp-ignore-comments\n                            (not blink-matching-paren-dont-ignore-comments))))\n                  (condition-case ()\n                      (progn\n\t\t\t(syntax-propertize (point))\n                        (forward-sexp -1)\n                        ;; backward-sexp skips backward over prefix chars,\n                        ;; so move back to the matching paren.\n                        (while (and (< (point) (1- oldpos))\n                                    (let ((code (syntax-after (point))))\n                                      (or (eq (syntax-class code) 6)\n                                          (eq (logand 1048576 (car code))\n                                              1048576))))\n                          (forward-char 1))\n                        (point))\n                    (error nil))))))\n           (mismatch (funcall blink-matching-check-function blinkpos oldpos)))\n      (cond\n       (mismatch\n        (if blinkpos\n            (if (minibufferp)\n                (minibuffer-message \"Mismatched parentheses\")\n              (message \"Mismatched parentheses\"))\n          (if (minibufferp)\n              (minibuffer-message \"No matching parenthesis found\")\n            (message \"No matching parenthesis found\"))))\n       ((not blinkpos) nil)\n       ((or\n         (eq blink-matching-paren 'jump-offscreen)\n         (pos-visible-in-window-p blinkpos))\n        ;; Matching open within window, temporarily move to or highlight\n        ;; char after blinkpos but only if `blink-matching-paren-on-screen'\n        ;; is non-nil.\n        (and blink-matching-paren-on-screen\n             (not show-paren-mode)\n             (if (memq blink-matching-paren '(jump jump-offscreen))\n                 (save-excursion\n                   (goto-char blinkpos)\n                   (sit-for blink-matching-delay))\n               (unwind-protect\n                   (progn\n                     (move-overlay blink-matching--overlay blinkpos (1+ blinkpos)\n                                   (current-buffer))\n                     (sit-for blink-matching-delay))\n                 (delete-overlay blink-matching--overlay)))))\n       (t\n        (let ((open-paren-line-string\n               (save-excursion\n                 (goto-char blinkpos)\n                 ;; Show what precedes the open in its line, if anything.\n                 (cond\n                  ((save-excursion (skip-chars-backward \" \\t\") (not (bolp)))\n                   (buffer-substring (line-beginning-position)\n                                     (1+ blinkpos)))\n                  ;; Show what follows the open in its line, if anything.\n                  ((save-excursion\n                     (forward-char 1)\n                     (skip-chars-forward \" \\t\")\n                     (not (eolp)))\n                   (buffer-substring blinkpos\n                                     (line-end-position)))\n                  ;; Otherwise show the previous nonblank line,\n                  ;; if there is one.\n                  ((save-excursion (skip-chars-backward \"\\n \\t\") (not (bobp)))\n                   (concat\n                    (buffer-substring (progn\n                                        (skip-chars-backward \"\\n \\t\")\n                                        (line-beginning-position))\n                                      (progn (end-of-line)\n                                             (skip-chars-backward \" \\t\")\n                                             (point)))\n                    ;; Replace the newline and other whitespace with `...'.\n                    \"...\"\n                    (buffer-substring blinkpos (1+ blinkpos))))\n                  ;; There is nothing to show except the char itself.\n                  (t (buffer-substring blinkpos (1+ blinkpos)))))))\n          (minibuffer-message\n           \"Matches %s\"\n           (substring-no-properties open-paren-line-string))))))))\n\n(defvar blink-paren-function 'blink-matching-open\n  \"Function called, if non-nil, whenever a close parenthesis is inserted.\nMore precisely, a char with closeparen syntax is self-inserted.\")\n\n(defun blink-paren-post-self-insert-function ()\n  (when (and (eq (char-before) last-command-event) ; Sanity check.\n             (memq (char-syntax last-command-event) '(?\\) ?\\$))\n             blink-paren-function\n             (not executing-kbd-macro)\n             (not noninteractive)\n\t     ;; Verify an even number of quoting characters precede the close.\n             ;; FIXME: Also check if this parenthesis closes a comment as\n             ;; can happen in Pascal and SML.\n\t     (= 1 (logand 1 (- (point)\n\t\t\t       (save-excursion\n\t\t\t\t (forward-char -1)\n\t\t\t\t (skip-syntax-backward \"/\\\\\")\n\t\t\t\t (point))))))\n    (funcall blink-paren-function)))\n\n(put 'blink-paren-post-self-insert-function 'priority 100)\n\n(add-hook 'post-self-insert-hook #'blink-paren-post-self-insert-function\n          ;; Most likely, this hook is nil, so this arg doesn't matter,\n          ;; but I use it as a reminder that this function usually\n          ;; likes to be run after others since it does\n          ;; `sit-for'. That's also the reason it get a `priority' prop\n          ;; of 100.\n          'append)\n\f\n;; This executes C-g typed while Emacs is waiting for a command.\n;; Quitting out of a program does not go through here;\n;; that happens in the maybe_quit function at the C code level.\n(defun keyboard-quit ()\n  \"Signal a `quit' condition.\nDuring execution of Lisp code, this character causes a quit directly.\nAt top-level, as an editor command, this simply beeps.\"\n  (interactive)\n  ;; Avoid adding the region to the window selection.\n  (setq saved-region-selection nil)\n  (let (select-active-regions)\n    (deactivate-mark))\n  (if (fboundp 'kmacro-keyboard-quit)\n      (kmacro-keyboard-quit))\n  (when completion-in-region-mode\n    (completion-in-region-mode -1))\n  ;; Force the next redisplay cycle to remove the \"Def\" indicator from\n  ;; all the mode lines.\n  (if defining-kbd-macro\n      (force-mode-line-update t))\n  (setq defining-kbd-macro nil)\n  (let ((debug-on-quit nil))\n    (signal 'quit nil)))\n\n(defvar buffer-quit-function nil\n  \"Function to call to \\\"quit\\\" the current buffer, or nil if none.\n\\\\[keyboard-escape-quit] calls this function when its more local actions\n\\(such as canceling a prefix argument, minibuffer or region) do not apply.\")\n\n(defun keyboard-escape-quit ()\n  \"Exit the current \\\"mode\\\" (in a generalized sense of the word).\nThis command can exit an interactive command such as `query-replace',\ncan clear out a prefix argument or a region,\ncan get out of the minibuffer or other recursive edit,\ncancel the use of the current buffer (for special-purpose buffers),\nor go back to just one window (by deleting all but the selected window).\"\n  (interactive)\n  (cond ((eq last-command 'mode-exited) nil)\n\t((region-active-p)\n\t (deactivate-mark))\n\t((> (minibuffer-depth) 0)\n\t (abort-recursive-edit))\n\t(current-prefix-arg\n\t nil)\n\t((> (recursion-depth) 0)\n\t (exit-recursive-edit))\n\t(buffer-quit-function\n\t (funcall buffer-quit-function))\n\t((not (one-window-p t))\n\t (delete-other-windows))\n\t((string-match \"^ \\\\*\" (buffer-name (current-buffer)))\n\t (bury-buffer))))\n\n(defun play-sound-file (file &optional volume device)\n  \"Play sound stored in FILE.\nVOLUME and DEVICE correspond to the keywords of the sound\nspecification for `play-sound'.\"\n  (interactive \"fPlay sound file: \")\n  (let ((sound (list :file file)))\n    (if volume\n\t(plist-put sound :volume volume))\n    (if device\n\t(plist-put sound :device device))\n    (push 'sound sound)\n    (play-sound sound)))\n\n\f\n(defcustom read-mail-command 'rmail\n  \"Your preference for a mail reading package.\nThis is used by some keybindings which support reading mail.\nSee also `mail-user-agent' concerning sending mail.\"\n  :type '(radio (function-item :tag \"Rmail\" :format \"%t\\n\" rmail)\n                (function-item :tag \"Gnus\" :format \"%t\\n\" gnus)\n                (function-item :tag \"Emacs interface to MH\"\n                               :format \"%t\\n\" mh-rmail)\n                (function :tag \"Other\"))\n  :version \"21.1\"\n  :group 'mail)\n\n(defcustom mail-user-agent 'message-user-agent\n  \"Your preference for a mail composition package.\nVarious Emacs Lisp packages (e.g. Reporter) require you to compose an\noutgoing email message.  This variable lets you specify which\nmail-sending package you prefer.\n\nValid values include:\n\n  `message-user-agent'  -- use the Message package.\n                           See Info node `(message)'.\n  `sendmail-user-agent' -- use the Mail package.\n                           See Info node `(emacs)Sending Mail'.\n  `mh-e-user-agent'     -- use the Emacs interface to the MH mail system.\n                           See Info node `(mh-e)'.\n  `gnus-user-agent'     -- like `message-user-agent', but with Gnus\n                           paraphernalia if Gnus is running, particularly\n                           the Gcc: header for archiving.\n\nAdditional valid symbols may be available; check with the author of\nyour package for details.  The function should return non-nil if it\nsucceeds.\n\nSee also `read-mail-command' concerning reading mail.\"\n  :type '(radio (function-item :tag \"Message package\"\n\t\t\t       :format \"%t\\n\"\n\t\t\t       message-user-agent)\n\t\t(function-item :tag \"Mail package\"\n\t\t\t       :format \"%t\\n\"\n\t\t\t       sendmail-user-agent)\n\t\t(function-item :tag \"Emacs interface to MH\"\n\t\t\t       :format \"%t\\n\"\n\t\t\t       mh-e-user-agent)\n\t\t(function-item :tag \"Message with full Gnus features\"\n\t\t\t       :format \"%t\\n\"\n\t\t\t       gnus-user-agent)\n\t\t(function :tag \"Other\"))\n  :version \"23.2\"                       ; sendmail->message\n  :group 'mail)\n\n(defcustom compose-mail-user-agent-warnings t\n  \"If non-nil, `compose-mail' warns about changes in `mail-user-agent'.\nIf the value of `mail-user-agent' is the default, and the user\nappears to have customizations applying to the old default,\n`compose-mail' issues a warning.\"\n  :type 'boolean\n  :version \"23.2\"\n  :group 'mail)\n\n(defun rfc822-goto-eoh ()\n  \"If the buffer starts with a mail header, move point to the header's end.\nOtherwise, moves to `point-min'.\nThe end of the header is the start of the next line, if there is one,\nelse the end of the last line.  This function obeys RFC822.\"\n  (goto-char (point-min))\n  (when (re-search-forward\n\t \"^\\\\([:\\n]\\\\|[^: \\t\\n]+[ \\t\\n]\\\\)\" nil 'move)\n    (goto-char (match-beginning 0))))\n\n;; Used by Rmail (e.g., rmail-forward).\n(defvar mail-encode-mml nil\n  \"If non-nil, mail-user-agent's `sendfunc' command should mml-encode\nthe outgoing message before sending it.\")\n\n(defun compose-mail (&optional to subject other-headers continue\n\t\t     switch-function yank-action send-actions\n\t\t     return-action)\n  \"Start composing a mail message to send.\nThis uses the user's chosen mail composition package\nas selected with the variable `mail-user-agent'.\nThe optional arguments TO and SUBJECT specify recipients\nand the initial Subject field, respectively.\n\nOTHER-HEADERS is an alist specifying additional\nheader fields.  Elements look like (HEADER . VALUE) where both\nHEADER and VALUE are strings.\n\nCONTINUE, if non-nil, says to continue editing a message already\nbeing composed.  Interactively, CONTINUE is the prefix argument.\n\nSWITCH-FUNCTION, if non-nil, is a function to use to\nswitch to and display the buffer used for mail composition.\n\nYANK-ACTION, if non-nil, is an action to perform, if and when necessary,\nto insert the raw text of the message being replied to.\nIt has the form (FUNCTION . ARGS).  The user agent will apply\nFUNCTION to ARGS, to insert the raw text of the original message.\n\\(The user agent will also run `mail-citation-hook', *after* the\noriginal text has been inserted in this way.)\n\nSEND-ACTIONS is a list of actions to call when the message is sent.\nEach action has the form (FUNCTION . ARGS).\n\nRETURN-ACTION, if non-nil, is an action for returning to the\ncaller.  It has the form (FUNCTION . ARGS).  The function is\ncalled after the mail has been sent or put aside, and the mail\nbuffer buried.\"\n  (interactive\n   (list nil nil nil current-prefix-arg))\n\n  ;; In Emacs 23.2, the default value of `mail-user-agent' changed\n  ;; from sendmail-user-agent to message-user-agent.  Some users may\n  ;; encounter incompatibilities.  This hack tries to detect problems\n  ;; and warn about them.\n  (and compose-mail-user-agent-warnings\n       (eq mail-user-agent 'message-user-agent)\n       (let (warn-vars)\n\t (dolist (var '(mail-mode-hook mail-send-hook mail-setup-hook\n\t\t\tmail-yank-hooks mail-archive-file-name\n\t\t\tmail-default-reply-to mail-mailing-lists\n\t\t\tmail-self-blind))\n\t   (and (boundp var)\n\t\t(symbol-value var)\n\t\t(push var warn-vars)))\n\t (when warn-vars\n\t   (display-warning 'mail\n\t\t\t    (format-message \"\\\nThe default mail mode is now Message mode.\nYou have the following Mail mode variable%s customized:\n\\n  %s\\n\\nTo use Mail mode, set `mail-user-agent' to sendmail-user-agent.\nTo disable this warning, set `compose-mail-user-agent-warnings' to nil.\"\n\t\t\t\t    (if (> (length warn-vars) 1) \"s\" \"\")\n\t\t\t\t    (mapconcat 'symbol-name\n\t\t\t\t\t       warn-vars \" \"))))))\n\n  (let ((function (get mail-user-agent 'composefunc)))\n    (funcall function to subject other-headers continue switch-function\n\t     yank-action send-actions return-action)))\n\n(defun compose-mail-other-window (&optional to subject other-headers continue\n\t\t\t\t\t    yank-action send-actions\n\t\t\t\t\t    return-action)\n  \"Like \\\\[compose-mail], but edit the outgoing message in another window.\"\n  (interactive (list nil nil nil current-prefix-arg))\n  (compose-mail to subject other-headers continue\n\t\t'switch-to-buffer-other-window yank-action send-actions\n\t\treturn-action))\n\n(defun compose-mail-other-frame (&optional to subject other-headers continue\n\t\t\t\t\t    yank-action send-actions\n\t\t\t\t\t    return-action)\n  \"Like \\\\[compose-mail], but edit the outgoing message in another frame.\"\n  (interactive (list nil nil nil current-prefix-arg))\n  (compose-mail to subject other-headers continue\n\t\t'switch-to-buffer-other-frame yank-action send-actions\n\t\treturn-action))\n\n\f\n(defvar set-variable-value-history nil\n  \"History of values entered with `set-variable'.\n\nMaximum length of the history list is determined by the value\nof `history-length', which see.\")\n\n(defun set-variable (variable value &optional make-local)\n  \"Set VARIABLE to VALUE.  VALUE is a Lisp object.\nVARIABLE should be a user option variable name, a Lisp variable\nmeant to be customized by users.  You should enter VALUE in Lisp syntax,\nso if you want VALUE to be a string, you must surround it with doublequotes.\nVALUE is used literally, not evaluated.\n\nIf VARIABLE has a `variable-interactive' property, that is used as if\nit were the arg to `interactive' (which see) to interactively read VALUE.\n\nIf VARIABLE has been defined with `defcustom', then the type information\nin the definition is used to check that VALUE is valid.\n\nNote that this function is at heart equivalent to the basic `set' function.\nFor a variable defined with `defcustom', it does not pay attention to\nany :set property that the variable might have (if you want that, use\n\\\\[customize-set-variable] instead).\n\nWith a prefix argument, set VARIABLE to VALUE buffer-locally.\"\n  (interactive\n   (let* ((default-var (variable-at-point))\n          (var (if (custom-variable-p default-var)\n\t\t   (read-variable (format \"Set variable (default %s): \" default-var)\n\t\t\t\t  default-var)\n\t\t (read-variable \"Set variable: \")))\n\t  (minibuffer-help-form '(describe-variable var))\n\t  (prop (get var 'variable-interactive))\n          (obsolete (car (get var 'byte-obsolete-variable)))\n\t  (prompt (format \"Set %s %s to value: \" var\n\t\t\t  (cond ((local-variable-p var)\n\t\t\t\t \"(buffer-local)\")\n\t\t\t\t((or current-prefix-arg\n\t\t\t\t     (local-variable-if-set-p var))\n\t\t\t\t \"buffer-locally\")\n\t\t\t\t(t \"globally\"))))\n\t  (val (progn\n                 (when obsolete\n                   (message (concat \"`%S' is obsolete; \"\n                                    (if (symbolp obsolete) \"use `%S' instead\" \"%s\"))\n                            var obsolete)\n                   (sit-for 3))\n                 (if prop\n                     ;; Use VAR's `variable-interactive' property\n                     ;; as an interactive spec for prompting.\n                     (call-interactively `(lambda (arg)\n                                            (interactive ,prop)\n                                            arg))\n                   (read-from-minibuffer prompt nil\n                                         read-expression-map t\n                                         'set-variable-value-history\n                                         (format \"%S\" (symbol-value var)))))))\n     (list var val current-prefix-arg)))\n\n  (and (custom-variable-p variable)\n       (not (get variable 'custom-type))\n       (custom-load-symbol variable))\n  (let ((type (get variable 'custom-type)))\n    (when type\n      ;; Match with custom type.\n      (require 'cus-edit)\n      (setq type (widget-convert type))\n      (unless (widget-apply type :match value)\n\t(user-error \"Value `%S' does not match type %S of %S\"\n\t\t    value (car type) variable))))\n\n  (if make-local\n      (make-local-variable variable))\n\n  (set variable value)\n\n  ;; Force a thorough redisplay for the case that the variable\n  ;; has an effect on the display, like `tab-width' has.\n  (force-mode-line-update))\n\f\n;; Define the major mode for lists of completions.\n\n(defvar completion-list-mode-map\n  (let ((map (make-sparse-keymap)))\n    (define-key map [mouse-2] 'choose-completion)\n    (define-key map [follow-link] 'mouse-face)\n    (define-key map [down-mouse-2] nil)\n    (define-key map \"\\C-m\" 'choose-completion)\n    (define-key map \"\\e\\e\\e\" 'delete-completion-window)\n    (define-key map [left] 'previous-completion)\n    (define-key map [right] 'next-completion)\n    (define-key map [?\\t] 'next-completion)\n    (define-key map [backtab] 'previous-completion)\n    (define-key map \"q\" 'quit-window)\n    (define-key map \"z\" 'kill-current-buffer)\n    map)\n  \"Local map for completion list buffers.\")\n\n;; Completion mode is suitable only for specially formatted data.\n(put 'completion-list-mode 'mode-class 'special)\n\n(defvar completion-reference-buffer nil\n  \"Record the buffer that was current when the completion list was requested.\nThis is a local variable in the completion list buffer.\nInitial value is nil to avoid some compiler warnings.\")\n\n(defvar completion-no-auto-exit nil\n  \"Non-nil means `choose-completion-string' should never exit the minibuffer.\nThis also applies to other functions such as `choose-completion'.\")\n\n(defvar completion-base-position nil\n  \"Position of the base of the text corresponding to the shown completions.\nThis variable is used in the *Completions* buffers.\nIts value is a list of the form (START END) where START is the place\nwhere the completion should be inserted and END (if non-nil) is the end\nof the text to replace.  If END is nil, point is used instead.\")\n\n(defvar completion-list-insert-choice-function #'completion--replace\n  \"Function to use to insert the text chosen in *Completions*.\nCalled with three arguments (BEG END TEXT), it should replace the text\nbetween BEG and END with TEXT.  Expected to be set buffer-locally\nin the *Completions* buffer.\")\n\n(defvar completion-base-size nil\n  \"Number of chars before point not involved in completion.\nThis is a local variable in the completion list buffer.\nIt refers to the chars in the minibuffer if completing in the\nminibuffer, or in `completion-reference-buffer' otherwise.\nOnly characters in the field at point are included.\n\nIf nil, Emacs determines which part of the tail end of the\nbuffer's text is involved in completion by comparing the text\ndirectly.\")\n(make-obsolete-variable 'completion-base-size 'completion-base-position \"23.2\")\n\n(defun delete-completion-window ()\n  \"Delete the completion list window.\nGo to the window from which completion was requested.\"\n  (interactive)\n  (let ((buf completion-reference-buffer))\n    (if (one-window-p t)\n\t(if (window-dedicated-p) (delete-frame))\n      (delete-window (selected-window))\n      (if (get-buffer-window buf)\n\t  (select-window (get-buffer-window buf))))))\n\n(defun previous-completion (n)\n  \"Move to the previous item in the completion list.\"\n  (interactive \"p\")\n  (next-completion (- n)))\n\n(defun next-completion (n)\n  \"Move to the next item in the completion list.\nWith prefix argument N, move N items (negative N means move backward).\"\n  (interactive \"p\")\n  (let ((beg (point-min)) (end (point-max)))\n    (while (and (> n 0) (not (eobp)))\n      ;; If in a completion, move to the end of it.\n      (when (get-text-property (point) 'mouse-face)\n\t(goto-char (next-single-property-change (point) 'mouse-face nil end)))\n      ;; Move to start of next one.\n      (unless (get-text-property (point) 'mouse-face)\n\t(goto-char (next-single-property-change (point) 'mouse-face nil end)))\n      (setq n (1- n)))\n    (while (and (< n 0) (not (bobp)))\n      (let ((prop (get-text-property (1- (point)) 'mouse-face)))\n\t;; If in a completion, move to the start of it.\n\t(when (and prop (eq prop (get-text-property (point) 'mouse-face)))\n\t  (goto-char (previous-single-property-change\n\t\t      (point) 'mouse-face nil beg)))\n\t;; Move to end of the previous completion.\n\t(unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))\n\t  (goto-char (previous-single-property-change\n\t\t      (point) 'mouse-face nil beg)))\n\t;; Move to the start of that one.\n\t(goto-char (previous-single-property-change\n\t\t    (point) 'mouse-face nil beg))\n\t(setq n (1+ n))))))\n\n(defun choose-completion (&optional event)\n  \"Choose the completion at point.\nIf EVENT, use EVENT's position to determine the starting position.\"\n  (interactive (list last-nonmenu-event))\n  ;; In case this is run via the mouse, give temporary modes such as\n  ;; isearch a chance to turn off.\n  (run-hooks 'mouse-leave-buffer-hook)\n  (with-current-buffer (window-buffer (posn-window (event-start event)))\n    (let ((buffer completion-reference-buffer)\n          (base-size completion-base-size)\n          (base-position completion-base-position)\n          (insert-function completion-list-insert-choice-function)\n          (choice\n           (save-excursion\n             (goto-char (posn-point (event-start event)))\n             (let (beg end)\n               (cond\n                ((and (not (eobp)) (get-text-property (point) 'mouse-face))\n                 (setq end (point) beg (1+ (point))))\n                ((and (not (bobp))\n                      (get-text-property (1- (point)) 'mouse-face))\n                 (setq end (1- (point)) beg (point)))\n                (t (error \"No completion here\")))\n               (setq beg (previous-single-property-change beg 'mouse-face))\n               (setq end (or (next-single-property-change end 'mouse-face)\n                             (point-max)))\n               (buffer-substring-no-properties beg end)))))\n\n      (unless (buffer-live-p buffer)\n        (error \"Destination buffer is dead\"))\n      (quit-window nil (posn-window (event-start event)))\n\n      (with-current-buffer buffer\n        (choose-completion-string\n         choice buffer\n         (or base-position\n             (when base-size\n               ;; Someone's using old completion code that doesn't know\n               ;; about base-position yet.\n               (list (+ base-size (field-beginning))))\n             ;; If all else fails, just guess.\n             (list (choose-completion-guess-base-position choice)))\n         insert-function)))))\n\n;; Delete the longest partial match for STRING\n;; that can be found before POINT.\n(defun choose-completion-guess-base-position (string)\n  (save-excursion\n    (let ((opoint (point))\n          len)\n      ;; Try moving back by the length of the string.\n      (goto-char (max (- (point) (length string))\n                      (minibuffer-prompt-end)))\n      ;; See how far back we were actually able to move.  That is the\n      ;; upper bound on how much we can match and delete.\n      (setq len (- opoint (point)))\n      (if completion-ignore-case\n          (setq string (downcase string)))\n      (while (and (> len 0)\n                  (let ((tail (buffer-substring (point) opoint)))\n                    (if completion-ignore-case\n                        (setq tail (downcase tail)))\n                    (not (string= tail (substring string 0 len)))))\n        (setq len (1- len))\n        (forward-char 1))\n      (point))))\n\n(defun choose-completion-delete-max-match (string)\n  (declare (obsolete choose-completion-guess-base-position \"23.2\"))\n  (delete-region (choose-completion-guess-base-position string) (point)))\n\n(defvar choose-completion-string-functions nil\n  \"Functions that may override the normal insertion of a completion choice.\nThese functions are called in order with three arguments:\nCHOICE - the string to insert in the buffer,\nBUFFER - the buffer in which the choice should be inserted,\nBASE-POSITION - where to insert the completion.\n\nIf a function in the list returns non-nil, that function is supposed\nto have inserted the CHOICE in the BUFFER, and possibly exited\nthe minibuffer; no further functions will be called.\n\nIf all functions in the list return nil, that means to use\nthe default method of inserting the completion in BUFFER.\")\n\n(defun choose-completion-string (choice &optional\n                                        buffer base-position insert-function)\n  \"Switch to BUFFER and insert the completion choice CHOICE.\nBASE-POSITION says where to insert the completion.\nINSERT-FUNCTION says how to insert the completion and falls\nback on `completion-list-insert-choice-function' when nil.\"\n\n  ;; If BUFFER is the minibuffer, exit the minibuffer\n  ;; unless it is reading a file name and CHOICE is a directory,\n  ;; or completion-no-auto-exit is non-nil.\n\n  ;; Some older code may call us passing `base-size' instead of\n  ;; `base-position'.  It's difficult to make any use of `base-size',\n  ;; so we just ignore it.\n  (unless (consp base-position)\n    (message \"Obsolete `base-size' passed to choose-completion-string\")\n    (setq base-position nil))\n\n  (let* ((buffer (or buffer completion-reference-buffer))\n\t (mini-p (minibufferp buffer)))\n    ;; If BUFFER is a minibuffer, barf unless it's the currently\n    ;; active minibuffer.\n    (if (and mini-p\n             (not (and (active-minibuffer-window)\n                       (equal buffer\n\t\t\t     (window-buffer (active-minibuffer-window))))))\n\t(error \"Minibuffer is not active for completion\")\n      ;; Set buffer so buffer-local choose-completion-string-functions works.\n      (set-buffer buffer)\n      (unless (run-hook-with-args-until-success\n\t       'choose-completion-string-functions\n               ;; The fourth arg used to be `mini-p' but was useless\n               ;; (since minibufferp can be used on the `buffer' arg)\n               ;; and indeed unused.  The last used to be `base-size', so we\n               ;; keep it to try and avoid breaking old code.\n\t       choice buffer base-position nil)\n        ;; This remove-text-properties should be unnecessary since `choice'\n        ;; comes from buffer-substring-no-properties.\n        ;;(remove-text-properties 0 (length choice) '(mouse-face nil) choice)\n\t;; Insert the completion into the buffer where it was requested.\n        (funcall (or insert-function completion-list-insert-choice-function)\n                 (or (car base-position) (point))\n                 (or (cadr base-position) (point))\n                 choice)\n        ;; Update point in the window that BUFFER is showing in.\n\t(let ((window (get-buffer-window buffer t)))\n\t  (set-window-point window (point)))\n\t;; If completing for the minibuffer, exit it with this choice.\n\t(and (not completion-no-auto-exit)\n             (minibufferp buffer)\n\t     minibuffer-completion-table\n\t     ;; If this is reading a file name, and the file name chosen\n\t     ;; is a directory, don't exit the minibuffer.\n             (let* ((result (buffer-substring (field-beginning) (point)))\n                    (bounds\n                     (completion-boundaries result minibuffer-completion-table\n                                            minibuffer-completion-predicate\n                                            \"\")))\n               (if (eq (car bounds) (length result))\n                   ;; The completion chosen leads to a new set of completions\n                   ;; (e.g. it's a directory): don't exit the minibuffer yet.\n                   (let ((mini (active-minibuffer-window)))\n                     (select-window mini)\n                     (when minibuffer-auto-raise\n                       (raise-frame (window-frame mini))))\n                 (exit-minibuffer))))))))\n\n(define-derived-mode completion-list-mode nil \"Completion List\"\n  \"Major mode for buffers showing lists of possible completions.\nType \\\\<completion-list-mode-map>\\\\[choose-completion] in the completion list\\\n to select the completion near point.\nOr click to select one with the mouse.\n\n\\\\{completion-list-mode-map}\"\n  (set (make-local-variable 'completion-base-size) nil))\n\n(defun completion-list-mode-finish ()\n  \"Finish setup of the completions buffer.\nCalled from `temp-buffer-show-hook'.\"\n  (when (eq major-mode 'completion-list-mode)\n    (setq buffer-read-only t)))\n\n(add-hook 'temp-buffer-show-hook 'completion-list-mode-finish)\n\n\n;; Variables and faces used in `completion-setup-function'.\n\n(defcustom completion-show-help t\n  \"Non-nil means show help message in *Completions* buffer.\"\n  :type 'boolean\n  :version \"22.1\"\n  :group 'completion)\n\n;; This function goes in completion-setup-hook, so that it is called\n;; after the text of the completion list buffer is written.\n(defun completion-setup-function ()\n  (let* ((mainbuf (current-buffer))\n         (base-dir\n          ;; FIXME: This is a bad hack.  We try to set the default-directory\n          ;; in the *Completions* buffer so that the relative file names\n          ;; displayed there can be treated as valid file names, independently\n          ;; from the completion context.  But this suffers from many problems:\n          ;; - It's not clear when the completions are file names.  With some\n          ;;   completion tables (e.g. bzr revision specs), the listed\n          ;;   completions can mix file names and other things.\n          ;; - It doesn't pay attention to possible quoting.\n          ;; - With fancy completion styles, the code below will not always\n          ;;   find the right base directory.\n          (if minibuffer-completing-file-name\n              (file-name-as-directory\n               (expand-file-name\n                (buffer-substring (minibuffer-prompt-end)\n                                  (- (point) (or completion-base-size 0))))))))\n    (with-current-buffer standard-output\n      (let ((base-size completion-base-size) ;Read before killing localvars.\n            (base-position completion-base-position)\n            (insert-fun completion-list-insert-choice-function))\n        (completion-list-mode)\n        (set (make-local-variable 'completion-base-size) base-size)\n        (set (make-local-variable 'completion-base-position) base-position)\n        (set (make-local-variable 'completion-list-insert-choice-function)\n\t     insert-fun))\n      (set (make-local-variable 'completion-reference-buffer) mainbuf)\n      (if base-dir (setq default-directory base-dir))\n      ;; Maybe insert help string.\n      (when completion-show-help\n\t(goto-char (point-min))\n\t(if (display-mouse-p)\n\t    (insert \"Click on a completion to select it.\\n\"))\n\t(insert (substitute-command-keys\n\t\t \"In this buffer, type \\\\[choose-completion] to \\\nselect the completion near point.\\n\\n\"))))))\n\n(add-hook 'completion-setup-hook 'completion-setup-function)\n\n(define-key minibuffer-local-completion-map [prior] 'switch-to-completions)\n(define-key minibuffer-local-completion-map \"\\M-v\"  'switch-to-completions)\n\n(defun switch-to-completions ()\n  \"Select the completion list window.\"\n  (interactive)\n  (let ((window (or (get-buffer-window \"*Completions*\" 0)\n\t\t    ;; Make sure we have a completions window.\n                    (progn (minibuffer-completion-help)\n                           (get-buffer-window \"*Completions*\" 0)))))\n    (when window\n      (select-window window)\n      ;; In the new buffer, go to the first completion.\n      ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.\n      (when (bobp)\n\t(next-completion 1)))))\n\f\n;;; Support keyboard commands to turn on various modifiers.\n\n;; These functions -- which are not commands -- each add one modifier\n;; to the following event.\n\n(defun event-apply-alt-modifier (_ignore-prompt)\n  \"\\\\<function-key-map>Add the Alt modifier to the following event.\nFor example, type \\\\[event-apply-alt-modifier] & to enter Alt-&.\"\n  (vector (event-apply-modifier (read-event) 'alt 22 \"A-\")))\n(defun event-apply-super-modifier (_ignore-prompt)\n  \"\\\\<function-key-map>Add the Super modifier to the following event.\nFor example, type \\\\[event-apply-super-modifier] & to enter Super-&.\"\n  (vector (event-apply-modifier (read-event) 'super 23 \"s-\")))\n(defun event-apply-hyper-modifier (_ignore-prompt)\n  \"\\\\<function-key-map>Add the Hyper modifier to the following event.\nFor example, type \\\\[event-apply-hyper-modifier] & to enter Hyper-&.\"\n  (vector (event-apply-modifier (read-event) 'hyper 24 \"H-\")))\n(defun event-apply-shift-modifier (_ignore-prompt)\n  \"\\\\<function-key-map>Add the Shift modifier to the following event.\nFor example, type \\\\[event-apply-shift-modifier] & to enter Shift-&.\"\n  (vector (event-apply-modifier (read-event) 'shift 25 \"S-\")))\n(defun event-apply-control-modifier (_ignore-prompt)\n  \"\\\\<function-key-map>Add the Ctrl modifier to the following event.\nFor example, type \\\\[event-apply-control-modifier] & to enter Ctrl-&.\"\n  (vector (event-apply-modifier (read-event) 'control 26 \"C-\")))\n(defun event-apply-meta-modifier (_ignore-prompt)\n  \"\\\\<function-key-map>Add the Meta modifier to the following event.\nFor example, type \\\\[event-apply-meta-modifier] & to enter Meta-&.\"\n  (vector (event-apply-modifier (read-event) 'meta 27 \"M-\")))\n\n(defun event-apply-modifier (event symbol lshiftby prefix)\n  \"Apply a modifier flag to event EVENT.\nSYMBOL is the name of this modifier, as a symbol.\nLSHIFTBY is the numeric value of this modifier, in keyboard events.\nPREFIX is the string that represents this modifier in an event type symbol.\"\n  (if (numberp event)\n      (cond ((eq symbol 'control)\n\t     (if (and (<= (downcase event) ?z)\n\t\t      (>= (downcase event) ?a))\n\t\t (- (downcase event) ?a -1)\n\t       (if (and (<= (downcase event) ?Z)\n\t\t\t(>= (downcase event) ?A))\n\t\t   (- (downcase event) ?A -1)\n\t\t (logior (lsh 1 lshiftby) event))))\n\t    ((eq symbol 'shift)\n\t     (if (and (<= (downcase event) ?z)\n\t\t      (>= (downcase event) ?a))\n\t\t (upcase event)\n\t       (logior (lsh 1 lshiftby) event)))\n\t    (t\n\t     (logior (lsh 1 lshiftby) event)))\n    (if (memq symbol (event-modifiers event))\n\tevent\n      (let ((event-type (if (symbolp event) event (car event))))\n\t(setq event-type (intern (concat prefix (symbol-name event-type))))\n\t(if (symbolp event)\n\t    event-type\n\t  (cons event-type (cdr event)))))))\n\n(define-key function-key-map [?\\C-x ?@ ?h] 'event-apply-hyper-modifier)\n(define-key function-key-map [?\\C-x ?@ ?s] 'event-apply-super-modifier)\n(define-key function-key-map [?\\C-x ?@ ?m] 'event-apply-meta-modifier)\n(define-key function-key-map [?\\C-x ?@ ?a] 'event-apply-alt-modifier)\n(define-key function-key-map [?\\C-x ?@ ?S] 'event-apply-shift-modifier)\n(define-key function-key-map [?\\C-x ?@ ?c] 'event-apply-control-modifier)\n\f\n;;;; Keypad support.\n\n;; Make the keypad keys act like ordinary typing keys.  If people add\n;; bindings for the function key symbols, then those bindings will\n;; override these, so this shouldn't interfere with any existing\n;; bindings.\n\n;; Also tell read-char how to handle these keys.\n(mapc\n (lambda (keypad-normal)\n   (let ((keypad (nth 0 keypad-normal))\n\t (normal (nth 1 keypad-normal)))\n     (put keypad 'ascii-character normal)\n     (define-key function-key-map (vector keypad) (vector normal))))\n ;; See also kp-keys bound in bindings.el.\n '((kp-space ?\\s)\n   (kp-tab ?\\t)\n   (kp-enter ?\\r)\n   (kp-separator ?,)\n   (kp-equal ?=)\n   ;; Do the same for various keys that are represented as symbols under\n   ;; GUIs but naturally correspond to characters.\n   (backspace 127)\n   (delete 127)\n   (tab ?\\t)\n   (linefeed ?\\n)\n   (clear ?\\C-l)\n   (return ?\\C-m)\n   (escape ?\\e)\n   ))\n\f\n;;;;\n;;;; forking a twin copy of a buffer.\n;;;;\n\n(defvar clone-buffer-hook nil\n  \"Normal hook to run in the new buffer at the end of `clone-buffer'.\")\n\n(defvar clone-indirect-buffer-hook nil\n  \"Normal hook to run in the new buffer at the end of `clone-indirect-buffer'.\")\n\n(defun clone-process (process &optional newname)\n  \"Create a twin copy of PROCESS.\nIf NEWNAME is nil, it defaults to PROCESS' name;\nNEWNAME is modified by adding or incrementing <N> at the end as necessary.\nIf PROCESS is associated with a buffer, the new process will be associated\n  with the current buffer instead.\nReturns nil if PROCESS has already terminated.\"\n  (setq newname (or newname (process-name process)))\n  (if (string-match \"<[0-9]+>\\\\'\" newname)\n      (setq newname (substring newname 0 (match-beginning 0))))\n  (when (memq (process-status process) '(run stop open))\n    (let* ((process-connection-type (process-tty-name process))\n\t   (new-process\n\t    (if (memq (process-status process) '(open))\n\t\t(let ((args (process-contact process t)))\n\t\t  (setq args (plist-put args :name newname))\n\t\t  (setq args (plist-put args :buffer\n\t\t\t\t\t(if (process-buffer process)\n\t\t\t\t\t    (current-buffer))))\n\t\t  (apply 'make-network-process args))\n\t      (apply 'start-process newname\n\t\t     (if (process-buffer process) (current-buffer))\n\t\t     (process-command process)))))\n      (set-process-query-on-exit-flag\n       new-process (process-query-on-exit-flag process))\n      (set-process-inherit-coding-system-flag\n       new-process (process-inherit-coding-system-flag process))\n      (set-process-filter new-process (process-filter process))\n      (set-process-sentinel new-process (process-sentinel process))\n      (set-process-plist new-process (copy-sequence (process-plist process)))\n      new-process)))\n\n;; things to maybe add (currently partly covered by `funcall mode'):\n;; - syntax-table\n;; - overlays\n(defun clone-buffer (&optional newname display-flag)\n  \"Create and return a twin copy of the current buffer.\nUnlike an indirect buffer, the new buffer can be edited\nindependently of the old one (if it is not read-only).\nNEWNAME is the name of the new buffer.  It may be modified by\nadding or incrementing <N> at the end as necessary to create a\nunique buffer name.  If nil, it defaults to the name of the\ncurrent buffer, with the proper suffix.  If DISPLAY-FLAG is\nnon-nil, the new buffer is shown with `pop-to-buffer'.  Trying to\nclone a file-visiting buffer, or a buffer whose major mode symbol\nhas a non-nil `no-clone' property, results in an error.\n\nInteractively, DISPLAY-FLAG is t and NEWNAME is the name of the\ncurrent buffer with appropriate suffix.  However, if a prefix\nargument is given, then the command prompts for NEWNAME in the\nminibuffer.\n\nThis runs the normal hook `clone-buffer-hook' in the new buffer\nafter it has been set up properly in other respects.\"\n  (interactive\n   (progn\n     (if buffer-file-name\n\t (error \"Cannot clone a file-visiting buffer\"))\n     (if (get major-mode 'no-clone)\n\t (error \"Cannot clone a buffer in %s mode\" mode-name))\n     (list (if current-prefix-arg\n\t       (read-buffer \"Name of new cloned buffer: \" (current-buffer)))\n\t   t)))\n  (if buffer-file-name\n      (error \"Cannot clone a file-visiting buffer\"))\n  (if (get major-mode 'no-clone)\n      (error \"Cannot clone a buffer in %s mode\" mode-name))\n  (setq newname (or newname (buffer-name)))\n  (if (string-match \"<[0-9]+>\\\\'\" newname)\n      (setq newname (substring newname 0 (match-beginning 0))))\n  (let ((buf (current-buffer))\n\t(ptmin (point-min))\n\t(ptmax (point-max))\n\t(pt (point))\n\t(mk (if mark-active (mark t)))\n\t(modified (buffer-modified-p))\n\t(mode major-mode)\n\t(lvars (buffer-local-variables))\n\t(process (get-buffer-process (current-buffer)))\n\t(new (generate-new-buffer (or newname (buffer-name)))))\n    (save-restriction\n      (widen)\n      (with-current-buffer new\n\t(insert-buffer-substring buf)))\n    (with-current-buffer new\n      (narrow-to-region ptmin ptmax)\n      (goto-char pt)\n      (if mk (set-mark mk))\n      (set-buffer-modified-p modified)\n\n      ;; Clone the old buffer's process, if any.\n      (when process (clone-process process))\n\n      ;; Now set up the major mode.\n      (funcall mode)\n\n      ;; Set up other local variables.\n      (mapc (lambda (v)\n\t      (condition-case ()\t;in case var is read-only\n\t\t  (if (symbolp v)\n\t\t      (makunbound v)\n\t\t    (set (make-local-variable (car v)) (cdr v)))\n\t\t(error nil)))\n\t    lvars)\n\n      ;; Run any hooks (typically set up by the major mode\n      ;; for cloning to work properly).\n      (run-hooks 'clone-buffer-hook))\n    (if display-flag\n        ;; Presumably the current buffer is shown in the selected frame, so\n        ;; we want to display the clone elsewhere.\n        (let ((same-window-regexps nil)\n              (same-window-buffer-names))\n          (pop-to-buffer new)))\n    new))\n\n\n(defun clone-indirect-buffer (newname display-flag &optional norecord)\n  \"Create an indirect buffer that is a twin copy of the current buffer.\n\nGive the indirect buffer name NEWNAME.  Interactively, read NEWNAME\nfrom the minibuffer when invoked with a prefix arg.  If NEWNAME is nil\nor if not called with a prefix arg, NEWNAME defaults to the current\nbuffer's name.  The name is modified by adding a `<N>' suffix to it\nor by incrementing the N in an existing suffix.  Trying to clone a\nbuffer whose major mode symbol has a non-nil `no-clone-indirect'\nproperty results in an error.\n\nDISPLAY-FLAG non-nil means show the new buffer with `pop-to-buffer'.\nThis is always done when called interactively.\n\nOptional third arg NORECORD non-nil means do not put this buffer at the\nfront of the list of recently selected ones.\n\nReturns the newly created indirect buffer.\"\n  (interactive\n   (progn\n     (if (get major-mode 'no-clone-indirect)\n\t (error \"Cannot indirectly clone a buffer in %s mode\" mode-name))\n     (list (if current-prefix-arg\n\t       (read-buffer \"Name of indirect buffer: \" (current-buffer)))\n\t   t)))\n  (if (get major-mode 'no-clone-indirect)\n      (error \"Cannot indirectly clone a buffer in %s mode\" mode-name))\n  (setq newname (or newname (buffer-name)))\n  (if (string-match \"<[0-9]+>\\\\'\" newname)\n      (setq newname (substring newname 0 (match-beginning 0))))\n  (let* ((name (generate-new-buffer-name newname))\n\t (buffer (make-indirect-buffer (current-buffer) name t)))\n    (with-current-buffer buffer\n      (run-hooks 'clone-indirect-buffer-hook))\n    (when display-flag\n      (pop-to-buffer buffer nil norecord))\n    buffer))\n\n\n(defun clone-indirect-buffer-other-window (newname display-flag &optional norecord)\n  \"Like `clone-indirect-buffer' but display in another window.\"\n  (interactive\n   (progn\n     (if (get major-mode 'no-clone-indirect)\n\t (error \"Cannot indirectly clone a buffer in %s mode\" mode-name))\n     (list (if current-prefix-arg\n\t       (read-buffer \"Name of indirect buffer: \" (current-buffer)))\n\t   t)))\n  (let ((pop-up-windows t))\n    (clone-indirect-buffer newname display-flag norecord)))\n\n\f\n;;; Handling of Backspace and Delete keys.\n\n(defcustom normal-erase-is-backspace 'maybe\n  \"Set the default behavior of the Delete and Backspace keys.\n\nIf set to t, Delete key deletes forward and Backspace key deletes\nbackward.\n\nIf set to nil, both Delete and Backspace keys delete backward.\n\nIf set to `maybe' (which is the default), Emacs automatically\nselects a behavior.  On window systems, the behavior depends on\nthe keyboard used.  If the keyboard has both a Backspace key and\na Delete key, and both are mapped to their usual meanings, the\noption's default value is set to t, so that Backspace can be used\nto delete backward, and Delete can be used to delete forward.\n\nIf not running under a window system, customizing this option\naccomplishes a similar effect by mapping C-h, which is usually\ngenerated by the Backspace key, to DEL, and by mapping DEL to C-d\nvia `keyboard-translate'.  The former functionality of C-h is\navailable on the F1 key.  You should probably not use this\nsetting if you don't have both Backspace, Delete and F1 keys.\n\nSetting this variable with setq doesn't take effect.  Programmatically,\ncall `normal-erase-is-backspace-mode' (which see) instead.\"\n  :type '(choice (const :tag \"Off\" nil)\n\t\t (const :tag \"Maybe\" maybe)\n\t\t (other :tag \"On\" t))\n  :group 'editing-basics\n  :version \"21.1\"\n  :set (lambda (symbol value)\n\t ;; The fboundp is because of a problem with :set when\n\t ;; dumping Emacs.  It doesn't really matter.\n\t (if (fboundp 'normal-erase-is-backspace-mode)\n\t     (normal-erase-is-backspace-mode (or value 0))\n\t   (set-default symbol value))))\n\n(defun normal-erase-is-backspace-setup-frame (&optional frame)\n  \"Set up `normal-erase-is-backspace-mode' on FRAME, if necessary.\"\n  (unless frame (setq frame (selected-frame)))\n  (with-selected-frame frame\n    (unless (terminal-parameter nil 'normal-erase-is-backspace)\n      (normal-erase-is-backspace-mode\n       (if (if (eq normal-erase-is-backspace 'maybe)\n               (and (not noninteractive)\n                    (or (memq system-type '(ms-dos windows-nt))\n\t\t\t(memq window-system '(w32 ns))\n                        (and (memq window-system '(x))\n                             (fboundp 'x-backspace-delete-keys-p)\n                             (x-backspace-delete-keys-p))\n                        ;; If the terminal Emacs is running on has erase char\n                        ;; set to ^H, use the Backspace key for deleting\n                        ;; backward, and the Delete key for deleting forward.\n                        (and (null window-system)\n                             (eq tty-erase-char ?\\^H))))\n             normal-erase-is-backspace)\n           1 0)))))\n\n(define-minor-mode normal-erase-is-backspace-mode\n  \"Toggle the Erase and Delete mode of the Backspace and Delete keys.\nWith a prefix argument ARG, enable this feature if ARG is\npositive, and disable it otherwise.  If called from Lisp, enable\nthe mode if ARG is omitted or nil.\n\nOn window systems, when this mode is on, Delete is mapped to C-d\nand Backspace is mapped to DEL; when this mode is off, both\nDelete and Backspace are mapped to DEL.  (The remapping goes via\n`local-function-key-map', so binding Delete or Backspace in the\nglobal or local keymap will override that.)\n\nIn addition, on window systems, the bindings of C-Delete, M-Delete,\nC-M-Delete, C-Backspace, M-Backspace, and C-M-Backspace are changed in\nthe global keymap in accordance with the functionality of Delete and\nBackspace.  For example, if Delete is remapped to C-d, which deletes\nforward, C-Delete is bound to `kill-word', but if Delete is remapped\nto DEL, which deletes backward, C-Delete is bound to\n`backward-kill-word'.\n\nIf not running on a window system, a similar effect is accomplished by\nremapping C-h (normally produced by the Backspace key) and DEL via\n`keyboard-translate': if this mode is on, C-h is mapped to DEL and DEL\nto C-d; if it's off, the keys are not remapped.\n\nWhen not running on a window system, and this mode is turned on, the\nformer functionality of C-h is available on the F1 key.  You should\nprobably not turn on this mode on a text-only terminal if you don't\nhave both Backspace, Delete and F1 keys.\n\nSee also `normal-erase-is-backspace'.\"\n  :variable ((eq (terminal-parameter nil 'normal-erase-is-backspace) 1)\n             . (lambda (v)\n                 (setf (terminal-parameter nil 'normal-erase-is-backspace)\n                       (if v 1 0))))\n  (let ((enabled (eq 1 (terminal-parameter\n                        nil 'normal-erase-is-backspace))))\n\n    (cond ((or (memq window-system '(x w32 ns pc))\n\t       (memq system-type '(ms-dos windows-nt)))\n\t   (let ((bindings\n\t\t  `(([M-delete] [M-backspace])\n\t\t    ([C-M-delete] [C-M-backspace])\n\t\t    ([?\\e C-delete] [?\\e C-backspace]))))\n\n\t     (if enabled\n\t\t (progn\n\t\t   (define-key local-function-key-map [delete] [deletechar])\n\t\t   (define-key local-function-key-map [kp-delete] [deletechar])\n\t\t   (define-key local-function-key-map [backspace] [?\\C-?])\n                   (dolist (b bindings)\n                     ;; Not sure if input-decode-map is really right, but\n                     ;; keyboard-translate-table (used below) only works\n                     ;; for integer events, and key-translation-table is\n                     ;; global (like the global-map, used earlier).\n                     (define-key input-decode-map (car b) nil)\n                     (define-key input-decode-map (cadr b) nil)))\n\t       (define-key local-function-key-map [delete] [?\\C-?])\n\t       (define-key local-function-key-map [kp-delete] [?\\C-?])\n\t       (define-key local-function-key-map [backspace] [?\\C-?])\n               (dolist (b bindings)\n                 (define-key input-decode-map (car b) (cadr b))\n                 (define-key input-decode-map (cadr b) (car b))))))\n\t  (t\n\t   (if enabled\n\t       (progn\n\t\t (keyboard-translate ?\\C-h ?\\C-?)\n\t\t (keyboard-translate ?\\C-? ?\\C-d))\n\t     (keyboard-translate ?\\C-h ?\\C-h)\n\t     (keyboard-translate ?\\C-? ?\\C-?))))\n\n    (if (called-interactively-p 'interactive)\n\t(message \"Delete key deletes %s\"\n\t\t (if (eq 1 (terminal-parameter nil 'normal-erase-is-backspace))\n\t\t     \"forward\" \"backward\")))))\n\f\n(defvar vis-mode-saved-buffer-invisibility-spec nil\n  \"Saved value of `buffer-invisibility-spec' when Visible mode is on.\")\n\n(define-minor-mode read-only-mode\n  \"Change whether the current buffer is read-only.\nWith prefix argument ARG, make the buffer read-only if ARG is\npositive, otherwise make it writable.  If buffer is read-only\nand `view-read-only' is non-nil, enter view mode.\n\nDo not call this from a Lisp program unless you really intend to\ndo the same thing as the \\\\[read-only-mode] command, including\npossibly enabling or disabling View mode.  Also, note that this\ncommand works by setting the variable `buffer-read-only', which\ndoes not affect read-only regions caused by text properties.  To\nignore read-only status in a Lisp program (whether due to text\nproperties or buffer state), bind `inhibit-read-only' temporarily\nto a non-nil value.\"\n  :variable buffer-read-only\n  (cond\n   ((and (not buffer-read-only) view-mode)\n    (View-exit-and-edit)\n    (make-local-variable 'view-read-only)\n    (setq view-read-only t))\t\t; Must leave view mode.\n   ((and buffer-read-only view-read-only\n         ;; If view-mode is already active, `view-mode-enter' is a nop.\n         (not view-mode)\n         (not (eq (get major-mode 'mode-class) 'special)))\n    (view-mode-enter))))\n\n(define-minor-mode visible-mode\n  \"Toggle making all invisible text temporarily visible (Visible mode).\nWith a prefix argument ARG, enable Visible mode if ARG is\npositive, and disable it otherwise.  If called from Lisp, enable\nthe mode if ARG is omitted or nil.\n\nThis mode works by saving the value of `buffer-invisibility-spec'\nand setting it to nil.\"\n  :lighter \" Vis\"\n  :group 'editing-basics\n  (when (local-variable-p 'vis-mode-saved-buffer-invisibility-spec)\n    (setq buffer-invisibility-spec vis-mode-saved-buffer-invisibility-spec)\n    (kill-local-variable 'vis-mode-saved-buffer-invisibility-spec))\n  (when visible-mode\n    (set (make-local-variable 'vis-mode-saved-buffer-invisibility-spec)\n\t buffer-invisibility-spec)\n    (setq buffer-invisibility-spec nil)))\n\f\n(defvar messages-buffer-mode-map\n  (let ((map (make-sparse-keymap)))\n    (set-keymap-parent map special-mode-map)\n    (define-key map \"g\" nil)            ; nothing to revert\n    map))\n\n(define-derived-mode messages-buffer-mode special-mode \"Messages\"\n  \"Major mode used in the \\\"*Messages*\\\" buffer.\")\n\n(defun messages-buffer ()\n  \"Return the \\\"*Messages*\\\" buffer.\nIf it does not exist, create and it switch it to `messages-buffer-mode'.\"\n  (or (get-buffer \"*Messages*\")\n      (with-current-buffer (get-buffer-create \"*Messages*\")\n        (messages-buffer-mode)\n        (current-buffer))))\n\n\f\n;; Minibuffer prompt stuff.\n\n;;(defun minibuffer-prompt-modification (start end)\n;;  (error \"You cannot modify the prompt\"))\n;;\n;;\n;;(defun minibuffer-prompt-insertion (start end)\n;;  (let ((inhibit-modification-hooks t))\n;;    (delete-region start end)\n;;    ;; Discard undo information for the text insertion itself\n;;    ;; and for the text deletion.above.\n;;    (when (consp buffer-undo-list)\n;;      (setq buffer-undo-list (cddr buffer-undo-list)))\n;;    (message \"You cannot modify the prompt\")))\n;;\n;;\n;;(setq minibuffer-prompt-properties\n;;  (list 'modification-hooks '(minibuffer-prompt-modification)\n;;\t'insert-in-front-hooks '(minibuffer-prompt-insertion)))\n\n\f\n;;;; Problematic external packages.\n\n;; rms says this should be done by specifying symbols that define\n;; versions together with bad values.  This is therefore not as\n;; flexible as it could be.  See the thread:\n;; https://lists.gnu.org/r/emacs-devel/2007-08/msg00300.html\n(defconst bad-packages-alist\n  ;; Not sure exactly which semantic versions have problems.\n  ;; Definitely 2.0pre3, probably all 2.0pre's before this.\n  '((semantic semantic-version \"\\\\`2\\\\.0pre[1-3]\\\\'\"\n              \"The version of `semantic' loaded does not work in Emacs 22.\nIt can cause constant high CPU load.\nUpgrade to at least Semantic 2.0pre4 (distributed with CEDET 1.0pre4).\")\n    ;; CUA-mode does not work with GNU Emacs version 22.1 and newer.\n    ;; Except for version 1.2, all of the 1.x and 2.x version of cua-mode\n    ;; provided the `CUA-mode' feature.  Since this is no longer true,\n    ;; we can warn the user if the `CUA-mode' feature is ever provided.\n    (CUA-mode t nil\n\"CUA-mode is now part of the standard GNU Emacs distribution,\nso you can now enable CUA via the Options menu or by customizing `cua-mode'.\n\nYou have loaded an older version of CUA-mode which does not work\ncorrectly with this version of Emacs.  You should remove the old\nversion and use the one distributed with Emacs.\"))\n  \"Alist of packages known to cause problems in this version of Emacs.\nEach element has the form (PACKAGE SYMBOL REGEXP STRING).\nPACKAGE is either a regular expression to match file names, or a\nsymbol (a feature name), like for `with-eval-after-load'.\nSYMBOL is either the name of a string variable, or t.  Upon\nloading PACKAGE, if SYMBOL is t or matches REGEXP, display a\nwarning using STRING as the message.\")\n\n(defun bad-package-check (package)\n  \"Run a check using the element from `bad-packages-alist' matching PACKAGE.\"\n  (condition-case nil\n      (let* ((list (assoc package bad-packages-alist))\n             (symbol (nth 1 list)))\n        (and list\n             (boundp symbol)\n             (or (eq symbol t)\n                 (and (stringp (setq symbol (eval symbol)))\n                      (string-match-p (nth 2 list) symbol)))\n             (display-warning package (nth 3 list) :warning)))\n    (error nil)))\n\n(dolist (elem bad-packages-alist)\n  (let ((pkg (car elem)))\n    (with-eval-after-load pkg\n      (bad-package-check pkg))))\n\n\f\n;;; Generic dispatcher commands\n\n;; Macro `define-alternatives' is used to create generic commands.\n;; Generic commands are these (like web, mail, news, encrypt, irc, etc.)\n;; that can have different alternative implementations where choosing\n;; among them is exclusively a matter of user preference.\n\n;; (define-alternatives COMMAND) creates a new interactive command\n;; M-x COMMAND and a customizable variable COMMAND-alternatives.\n;; Typically, the user will not need to customize this variable; packages\n;; wanting to add alternative implementations should use\n;;\n;; ;;;###autoload (push '(\"My impl name\" . my-impl-symbol) COMMAND-alternatives\n\n(defmacro define-alternatives (command &rest customizations)\n  \"Define the new command `COMMAND'.\n\nThe argument `COMMAND' should be a symbol.\n\nRunning `M-x COMMAND RET' for the first time prompts for which\nalternative to use and records the selected command as a custom\nvariable.\n\nRunning `C-u M-x COMMAND RET' prompts again for an alternative\nand overwrites the previous choice.\n\nThe variable `COMMAND-alternatives' contains an alist with\nalternative implementations of COMMAND.  `define-alternatives'\ndoes not have any effect until this variable is set.\n\nCUSTOMIZATIONS, if non-nil, should be composed of alternating\n`defcustom' keywords and values to add to the declaration of\n`COMMAND-alternatives' (typically :group and :version).\"\n  (let* ((command-name (symbol-name command))\n         (varalt-name (concat command-name \"-alternatives\"))\n         (varalt-sym (intern varalt-name))\n         (varimp-sym (intern (concat command-name \"--implementation\"))))\n    `(progn\n\n       (defcustom ,varalt-sym nil\n         ,(format \"Alist of alternative implementations for the `%s' command.\n\nEach entry must be a pair (ALTNAME . ALTFUN), where:\nALTNAME - The name shown at user to describe the alternative implementation.\nALTFUN  - The function called to implement this alternative.\"\n                  command-name)\n         :type '(alist :key-type string :value-type function)\n         ,@customizations)\n\n       (put ',varalt-sym 'definition-name ',command)\n       (defvar ,varimp-sym nil \"Internal use only.\")\n\n       (defun ,command (&optional arg)\n         ,(format \"Run generic command `%s'.\nIf used for the first time, or with interactive ARG, ask the user which\nimplementation to use for `%s'.  The variable `%s'\ncontains the list of implementations currently supported for this command.\"\n                  command-name command-name varalt-name)\n         (interactive \"P\")\n         (when (or arg (null ,varimp-sym))\n           (let ((val (completing-read\n\t\t       ,(format-message\n                         \"Select implementation for command `%s': \"\n                         command-name)\n\t\t       ,varalt-sym nil t)))\n             (unless (string-equal val \"\")\n\t       (when (null ,varimp-sym)\n\t\t (message\n\t\t  \"Use C-u M-x %s RET`to select another implementation\"\n\t\t  ,command-name)\n\t\t (sit-for 3))\n\t       (customize-save-variable ',varimp-sym\n\t\t\t\t\t(cdr (assoc-string val ,varalt-sym))))))\n         (if ,varimp-sym\n             (call-interactively ,varimp-sym)\n           (message \"%s\" ,(format-message\n                           \"No implementation selected for command `%s'\"\n                           command-name)))))))\n\n\f\n;;; Functions for changing capitalization that Do What I Mean\n(defun upcase-dwim (arg)\n  \"Upcase words in the region, if active; if not, upcase word at point.\nIf the region is active, this function calls `upcase-region'.\nOtherwise, it calls `upcase-word', with prefix argument passed to it\nto upcase ARG words.\"\n  (interactive \"*p\")\n  (if (use-region-p)\n      (upcase-region (region-beginning) (region-end))\n    (upcase-word arg)))\n\n(defun downcase-dwim (arg)\n    \"Downcase words in the region, if active; if not, downcase word at point.\nIf the region is active, this function calls `downcase-region'.\nOtherwise, it calls `downcase-word', with prefix argument passed to it\nto downcase ARG words.\"\n  (interactive \"*p\")\n  (if (use-region-p)\n      (downcase-region (region-beginning) (region-end))\n    (downcase-word arg)))\n\n(defun capitalize-dwim (arg)\n  \"Capitalize words in the region, if active; if not, capitalize word at point.\nIf the region is active, this function calls `capitalize-region'.\nOtherwise, it calls `capitalize-word', with prefix argument passed to it\nto capitalize ARG words.\"\n  (interactive \"*p\")\n  (if (use-region-p)\n      (capitalize-region (region-beginning) (region-end))\n    (capitalize-word arg)))\n\n\f\n\n(provide 'simple)\n\n;;; simple.el ends here\n"
  },
  {
    "path": "Units/parser-erlang.r/crash1.d/input.erl",
    "content": "% long directives used to possibly crash the parser\n% (and always make Valgrind angry)\n-some_extremely_loooong_directive\n-even_longer_might_crash_more_often_than_not_but_anyway_valgrind_would_not_be_hayyp_either_way\n\n"
  },
  {
    "path": "Units/parser-flex.r/as-first-token.d/expected.tags",
    "content": "f1\tinput.as\t/^function f1():void {}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-flex.r/as-first-token.d/input.as",
    "content": "function f1():void {}\n"
  },
  {
    "path": "Units/parser-flex.r/classes.d/args.ctags",
    "content": "--fields=+Z\n--extras=+q\n"
  },
  {
    "path": "Units/parser-flex.r/classes.d/expected.tags",
    "content": "C1\tinput.as\t/^  class C1 {$/;\"\tc\nC1.m1\tinput.as\t/^    public function m1():Boolean { return 0; }$/;\"\tm\tscope:class:C1\nC2\tinput.as\t/^  class C2 extends C1 {}$/;\"\tc\nC3\tinput.as\t/^  class C3 {}$/;\"\tc\nC4\tinput.as\t/^  class C4 implements I1 {}$/;\"\tc\nC5\tinput.as\t/^  class C5 extends C3 implements I1 {}$/;\"\tc\nC6\tinput.as\t/^  class C6 extends C3 implements I1, I2 {}$/;\"\tc\nC7\tinput.as\t/^  dynamic class C7{}$/;\"\tc\nI1\tinput.as\t/^  interface I1 {}$/;\"\ti\nI2\tinput.as\t/^  interface I2 {}$/;\"\ti\nI3\tinput.as\t/^  interface I3 extends I1, I2 {}$/;\"\ti\nI4\tinput.as\t/^  interface I4 extends I3 {}$/;\"\ti\nm1\tinput.as\t/^    public function m1():Boolean { return 0; }$/;\"\tm\tscope:class:C1\n"
  },
  {
    "path": "Units/parser-flex.r/classes.d/input.as",
    "content": "package {\n  class C1 {\n    public function m1():Boolean { return 0; }\n  }\n  class C2 extends C1 {}\n  class C3 {}\n  interface I1 {}\n  interface I2 {}\n  interface I3 extends I1, I2 {}\n  interface I4 extends I3 {}\n  class C4 implements I1 {}\n  class C5 extends C3 implements I1 {}\n  class C6 extends C3 implements I1, I2 {}\n\n  dynamic class C7{}\n}\n"
  },
  {
    "path": "Units/parser-flex.r/const.d/args.ctags",
    "content": "--kinds-flex=+l\n"
  },
  {
    "path": "Units/parser-flex.r/const.d/expected.tags",
    "content": "AlarmClock\tinput.as\t/^public class AlarmClock {$/;\"\tc\nMODE_AUDIO\tinput.as\t/^  public static const MODE_AUDIO  = 2;$/;\"\tC\tclass:AlarmClock\nMODE_BOTH\tinput.as\t/^  public static const MODE_BOTH   = 3;$/;\"\tC\tclass:AlarmClock\nMODE_VISUAL\tinput.as\t/^  public static const MODE_VISUAL = 1;$/;\"\tC\tclass:AlarmClock\nmode\tinput.as\t/^  private var mode = AlarmClock.MODE_AUDIO;$/;\"\tl\tclass:AlarmClock\n"
  },
  {
    "path": "Units/parser-flex.r/const.d/input.as",
    "content": "// https://www.oreilly.com/library/view/essential-actionscript-30/0596526946/ch04s02.html\npublic class AlarmClock {\n  public static const MODE_VISUAL = 1;\n  public static const MODE_AUDIO  = 2;\n  public static const MODE_BOTH   = 3;\n\n  private var mode = AlarmClock.MODE_AUDIO;\n}\n"
  },
  {
    "path": "Units/parser-flex.r/const2.d/expected.tags",
    "content": "MIN_AGE\tinput.as\t/^const MIN_AGE:int = 21;$/;\"\tC\nproduct_array\tinput.as\t/^const product_array:Array = new Array(\"Studio\", \"Dreamweaver\", \"Flash\", \"ColdFusion\", \"Contribut/;\"\tC\n"
  },
  {
    "path": "Units/parser-flex.r/const2.d/input.as",
    "content": "// https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/statements.html#const\nconst MIN_AGE:int = 21;\n\nconst product_array:Array = new Array(\"Studio\", \"Dreamweaver\", \"Flash\", \"ColdFusion\", \"Contribute\", \"Breeze\"); \nproduct_array.push(\"Flex\"); // array operations are allowed\nproduct_array = [\"Other\"];  // assignment is an error\ntrace(product_array);\n"
  },
  {
    "path": "Units/parser-flex.r/flex_comment.mxml.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-flex.r/flex_comment.mxml.d/input.mxml",
    "content": "<!--  this is a comment \r\n\t<mx:Array id=\"forms\">\r\n\t\t<mx:Object label=\"Login-with-a-dash\"                  data=\"0\"  custom=\"loginScreen\" />\r\n\t</mx:Array>\r\n\t-->\r\n"
  },
  {
    "path": "Units/parser-flex.r/flex_only_mxml.mxml.d/expected.tags",
    "content": "form_login_screen\tinput.mxml\t/^\t\t<mx:Form label=\"{logInOut}\" width=\"100%\" height=\"100%\" id=\"form_login_screen\">$/;\"\tx\tmxtag:Form\nforms\tinput.mxml\t/^\t<mx:Array id=\"forms\">$/;\"\tx\tmxtag:Array\nls_bt_log_in_out\tinput.mxml\t/^\t\t\t\t\t<mx:Button id=\"ls_bt_log_in_out\" x=\"240\" y=\"238\" label=\"{logInOut}\" enabled=\"true\" click=\"o/;\"\tx\tmxtag:Button\nls_lb_welcome\tinput.mxml\t/^\t\t\t\t\t<mx:Label x=\"194\" y=\"287\" width=\"315\" id=\"ls_lb_welcome\" fontSize=\"16\" fontWeight=\"bold\"\\/>$/;\"\tx\tmxtag:Label\nls_ti_passwd\tinput.mxml\t/^\t\t\t\t\t<mx:TextInput id=\"ls_ti_passwd\" x=\"240\" y=\"206\" displayAsPassword=\"true\" text=\"Demo05\"\\/>$/;\"\tx\tmxtag:TextInput\nls_ti_username\tinput.mxml\t/^\t\t\t\t\t<mx:TextInput id=\"ls_ti_username\" x=\"240\" y=\"174\" text=\"admin\"\\/>$/;\"\tx\tmxtag:TextInput\nmyHTTPService\tinput.mxml\t/^\t\tid=\"myHTTPService\"$/;\"\tx\tmxtag:HTTPService\nviewstack1\tinput.mxml\t/^\t<mx:ViewStack x=\"149\" y=\"55\" id=\"viewstack1\" width=\"831\" height=\"605\" change=\"onChangeViewStack/;\"\tx\tmxtag:ViewStack\n"
  },
  {
    "path": "Units/parser-flex.r/flex_only_mxml.mxml.d/input.mxml",
    "content": "<!--?xml version=\"1.0\" encoding=\"utf-8\"?-->\r\n<mx:Application xmlns:mx=\"http://www.adobe.com/2006/mxml\" >\r\n\r\n\t<mx:Label x=\"162\" y=\"176\" text=\"Username:\"/>\r\n\t<mx:Array id=\"forms\">\r\n\t\t<mx:Object label=\"Issue Tracking\"         data=\"12\" custom=\"issueTracking\" />\r\n\t</mx:Array>\r\n\r\n\t<mx:ViewStack x=\"149\" y=\"55\" id=\"viewstack1\" width=\"831\" height=\"605\" change=\"onChangeViewStack(event);\" >\r\n\t\t<mx:Form label=\"{logInOut}\" width=\"100%\" height=\"100%\" id=\"form_login_screen\">\r\n\t\t\t<mx:FormItem>\r\n\t\t\t\t<mx:Canvas width=\"623\" height=\"511\">\r\n\t\t\t\t\t<mx:Label x=\"162\" y=\"176\" text=\"Username:\"/>\r\n\t\t\t\t\t<mx:Label x=\"162\" y=\"208\" text=\"Password\"/>\r\n\t\t\t\t\t<mx:TextInput id=\"ls_ti_username\" x=\"240\" y=\"174\" text=\"admin\"/>\r\n\t\t\t\t\t<mx:TextInput id=\"ls_ti_passwd\" x=\"240\" y=\"206\" displayAsPassword=\"true\" text=\"Demo05\"/>\r\n\t\t\t\t\t<mx:Button id=\"ls_bt_log_in_out\" x=\"240\" y=\"238\" label=\"{logInOut}\" enabled=\"true\" click=\"onButtonClick(event)\"/>\r\n\t\t\t\t\t<mx:Label x=\"194\" y=\"287\" width=\"315\" id=\"ls_lb_welcome\" fontSize=\"16\" fontWeight=\"bold\"/>\r\n\t\t\t\t</mx:Canvas>\r\n\t\t\t</mx:FormItem>\r\n\t\t</mx:Form>\r\n\t</mx:ViewStack>\r\n\r\n\t<mx:HTTPService \r\n\t\tid=\"myHTTPService\"\r\n\t\tresult=\"resultHandler(event);\"\r\n\t\t/>\r\n\r\n</mx:Application>\r\n"
  },
  {
    "path": "Units/parser-flex.r/flex_with_actionscript.mxml.d/expected.tags",
    "content": "ajaxData\tinput.mxml\t/^\t\tid=\"ajaxData\"$/;\"\tx\tmxtag:HTTPService\ndateToYYYYMMDD\tinput.mxml\t/^\tpublic function dateToYYYYMMDD(aDate:Date):String {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-flex.r/flex_with_actionscript.mxml.d/input.mxml",
    "content": "<!--?xml version=\"1.0\" encoding=\"utf-8\"?-->\r\n<mx:Application xmlns:mx=\"http://www.adobe.com/2006/mxml\">\r\n\t<mx:Script>\r\n\t<![CDATA[\r\n\tpublic function dateToYYYYMMDD(aDate:Date):String {\r\n\t\treturn sDate; \r\n\t}\r\n\t]]>\r\n\t</mx:Script>\r\n\r\n\t<mx:HTTPService \r\n\t\tid=\"ajaxData\"\r\n\t\t/>\r\n\r\n</mx:Application>\r\n\r\n"
  },
  {
    "path": "Units/parser-flex.r/method-attributes.d/expected.tags",
    "content": "C\tinput.as\t/^class C {$/;\"\tc\nf1\tinput.as\t/^  public function f1():void {}$/;\"\tm\tclass:C\nf2\tinput.as\t/^  private function f2():void {}$/;\"\tm\tclass:C\nf3\tinput.as\t/^  protected function f3():void {}$/;\"\tm\tclass:C\nf4\tinput.as\t/^  internal function f4():void {}$/;\"\tm\tclass:C\nf5\tinput.as\t/^  public function f5():void {}$/;\"\tm\tclass:C\nf6\tinput.as\t/^  public override function f6():void {}$/;\"\tm\tclass:C\nf7\tinput.as\t/^  final function f7():void {}$/;\"\tm\tclass:C\nf8\tinput.as\t/^  native function f8():void {}$/;\"\tm\tclass:C\n"
  },
  {
    "path": "Units/parser-flex.r/method-attributes.d/input.as",
    "content": "/* Not sure it's really valid, but the goal is to check not choking on\n * attributes, so so long as it's valid attributes it's fine */\nclass C {\n  public function f1():void {}\n  private function f2():void {}\n  protected function f3():void {}\n  internal function f4():void {}\n  public function f5():void {}\n  public override function f6():void {}\n  final function f7():void {}\n  native function f8():void {}\n}\n"
  },
  {
    "path": "Units/parser-flex.r/packages.d/expected.tags",
    "content": "C1\tinput.as\t/^  class C1 {}$/;\"\tc\tclass:P3\nP1\tinput.as\t/^package P1 {}$/;\"\tP\nP2\tinput.as\t/^package P2 {$/;\"\tP\nP3\tinput.as\t/^package P3 {$/;\"\tP\nf1\tinput.as\t/^  function f1() {}$/;\"\tf\tfunction:P2\nqualified.test.pkg\tinput.as\t/^package qualified.test . pkg {$/;\"\tP\n"
  },
  {
    "path": "Units/parser-flex.r/packages.d/input.as",
    "content": "package P1 {}\npackage P2 {\n  function f1() {}\n}\npackage P3 {\n  class C1 {}\n}\npackage qualified.test . pkg {\n}\n"
  },
  {
    "path": "Units/parser-flex.r/sampler.d/args.ctags",
    "content": "--kinds-flex=+l\n--fields=+rZ\n--extras=+r\n"
  },
  {
    "path": "Units/parser-flex.r/sampler.d/expected.tags",
    "content": "assert\tinput.as\t/^        private function assert(e:Boolean, mess:String=null):void {$/;\"\tm\tscope:class:sampleTypes\troles:def\nb\tinput.as\t/^      var b:Boolean = true$/;\"\tl\tscope:class:sampleTypes\troles:def\ncpuSamples\tinput.as\t/^            var cpuSamples:Array=[];$/;\"\tl\tscope:class:sampleTypes.sampleTypes\troles:def\ndelSamples\tinput.as\t/^            var delSamples:Array=[];$/;\"\tl\tscope:class:sampleTypes.sampleTypes\troles:def\ndos\tinput.as\t/^                var dos = DeleteObjectSample(s);$/;\"\tl\tscope:class:sampleTypes.sampleTypes\troles:def\nflash.display.Sprite\tinput.as\t/^    import flash.display.Sprite$/;\"\tI\troles:import\nflash.sampler.*\tinput.as\t/^    import flash.sampler.*$/;\"\tI\troles:import\nflash.system.*\tinput.as\t/^    import flash.system.*$/;\"\tI\troles:import\nflash.utils.*\tinput.as\t/^    import flash.utils.*$/;\"\tI\troles:import\nids\tinput.as\t/^            var ids:Array=[]$/;\"\tl\tscope:class:sampleTypes.sampleTypes\troles:def\nlastTime\tinput.as\t/^            var lastTime:Number=0;$/;\"\tl\tscope:class:sampleTypes.sampleTypes\troles:def\nnewSamples\tinput.as\t/^            var newSamples:Array=[];$/;\"\tl\tscope:class:sampleTypes.sampleTypes\troles:def\nnos\tinput.as\t/^                var nos = NewObjectSample(s);$/;\"\tl\tscope:class:sampleTypes.sampleTypes\troles:def\nsampleTypes\tinput.as\t/^        public function sampleTypes() {$/;\"\tm\tscope:class:sampleTypes\troles:def\nsampleTypes\tinput.as\t/^    public class sampleTypes extends Sprite$/;\"\tc\troles:def\n"
  },
  {
    "path": "Units/parser-flex.r/sampler.d/input.as",
    "content": "// https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/sampler/Sample.html\npackage \n{\n    import flash.sampler.*\n    import flash.system.*\n    import flash.utils.*\n    import flash.display.Sprite\n    public class sampleTypes extends Sprite\n    {\n      var b:Boolean = true\n        public function sampleTypes() {\n            flash.sampler.startSampling();\n            for(var i:int=0;i<10000;i++)\n              new Object();\n\n            var cpuSamples:Array=[];\n            var newSamples:Array=[];\n            var delSamples:Array=[];\n            var ids:Array=[]\n\n            var lastTime:Number=0;\n            for each(var s:Sample in getSamples()) {\n              \n              assert(s.time > 0); // positive\n              assert(Math.floor(s.time) == s.time, s.time); // integral\n              assert(s.time >= lastTime, s.time + \":\" + lastTime); // ascending\n              assert(s.stack == null || s.stack is Array)\n              if(s.stack) {\n                assert(s.stack[0] is StackFrame);\n                assert(s.stack[0].name is String);\n            }\n              \n              if(s is NewObjectSample) {\n                var nos = NewObjectSample(s);\n                assert(s.id > 0, s.id);\n                assert(s.type is Class, getQualifiedClassName(s.type));\n                newSamples.push(s);\n                ids[s.id] = \"got one\";\n              } else if(s is DeleteObjectSample) {\n                var dos = DeleteObjectSample(s);\n                delSamples.push(s);\n                assert(ids[dos.id] == \"got one\");\n              } else if(s is Sample)\n                cpuSamples.push(s);\n              else {\n                assert(false);\n              }\n              lastTime = s.time;\n            }\n\n            trace(b)\n            trace(newSamples.length > 0)\n            trace(cpuSamples.length > 0)\n            trace(delSamples.length > 0)\n\n        }\n\n        private function assert(e:Boolean, mess:String=null):void {\n          b = e && b;\n          if(true && !e) {\n            if(mess) trace(mess);\n            trace(new Error().getStackTrace());\n          }     \n        }         \n    }\n}\n"
  },
  {
    "path": "Units/parser-forth.r/simple-forth.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-forth.r/simple-forth.d/expected.tags",
    "content": "DUMMY1\tinput.fth\t/^10 constant DUMMY1$/;\"\tc\nDUMMY2\tinput.fth\t/^12 CONSTANT DUMMY2$/;\"\tc\ndummy3\tinput.fth\t/^variable dummy3$/;\"\tv\ndummy4\tinput.fth\t/^variable dummy4$/;\"\tv\ndummy5\tinput.fth\t/^VARIABLE dummy5$/;\"\tv\nfizz?\tinput.fth\t/^: fizz?  \\\\ a simple comment $/;\"\tw\nbuzz?\tinput.fth\t/^: buzz?  $/;\"\tw\nfizz-buzz?\tinput.fth\t/^: fizz-buzz?  $/;\"\tw\ndo-fizz-buzz\tinput.fth\t/^: do-fizz-buzz  $/;\"\tw\n"
  },
  {
    "path": "Units/parser-forth.r/simple-forth.d/input.fth",
    "content": "\n( https://rosettacode.org/wiki/FizzBuzz#Forth / https://skilldrick.github.io/easyforth/ ) \n\n\\ Works in gforth and other ANS forth. Other Forth may differ.\n\n10 constant DUMMY1\n12 CONSTANT DUMMY2\n\nvariable dummy3\nvariable dummy4\nVARIABLE dummy5\n\n11 dummy3 !\n13 dummy4 !\n\n: fizz?  \\ a simple comment \n3 mod 0 = dup if .\" Fizz\" then ;\n: buzz?  \n5 mod 0 = dup if .\" Buzz\" then ;\n\n: fizz-buzz?  \ndup fizz? swap buzz? or invert ;\n\n: do-fizz-buzz  \n25 1 do cr i fizz-buzz? if i . then loop ;\n\ndo-fizz-buzz\ncr\n\nquit\n\\ bye\n"
  },
  {
    "path": "Units/parser-fortran.r/array-spec.f90.d/expected.tags",
    "content": "df_mb_data\tinput.f90\t/^       df_mb_data(/;\"\tk\ttype:df_type\ndf_mb_time\tinput.f90\t/^       df_mb_time(/;\"\tk\ttype:df_type\ndf_type\tinput.f90\t/^      TYPE df_type$/;\"\tt\tmodule:inm_df\ndf_wb_data\tinput.f90\t/^       df_mb_data(:,:),  df_wb_data(/;\"\tk\ttype:df_type\ndf_wb_time\tinput.f90\t/^       df_mb_time(:),              df_wb_time(/;\"\tk\ttype:df_type\ninm_df\tinput.f90\t/^      MODULE inm_df$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/array-spec.f90.d/input.f90",
    "content": "      MODULE inm_df\n      IMPLICIT none\n      SAVE\n      TYPE df_type\n      REAL(8), POINTER :: &\n       df_mb_time(:),              df_wb_time(:)\n      REAL(4), POINTER :: &\n       df_mb_data(:,:),  df_wb_data(:,:)\n      END TYPE\n      END MODULE inm_df\n"
  },
  {
    "path": "Units/parser-fortran.r/array_spec.f90.d/expected.tags",
    "content": "Global_Variables\tinput.f90\t/^module Global_Variables$/;\"\tm\nH\tinput.f90\t/^H /;\"\tv\tmodule:Global_Variables\nH0\tinput.f90\t/^H0(/;\"\tv\tmodule:Global_Variables\nH1\tinput.f90\t/^H1(/;\"\tv\tmodule:Global_Variables\nH2\tinput.f90\t/^H2(/;\"\tv\tmodule:Global_Variables\nH3\tinput.f90\t/^H3(/;\"\tv\tmodule:Global_Variables\nH4\tinput.f90\t/^H4(/;\"\tv\tmodule:Global_Variables\nH5\tinput.f90\t/^H5(/;\"\tv\tmodule:Global_Variables\n"
  },
  {
    "path": "Units/parser-fortran.r/array_spec.f90.d/input.f90",
    "content": "! Bug reported by Jim Chen on 31 Dec 2002\nmodule Global_Variables\nimplicit none\n\n! Example of array-spec in entity-decl\nreal*8, save ::         &\nH (NDIM, NDIM) = 0.D0,  &\nH0(NDIM, NDIM),         &\nH1(NDIM, NDIM) = 0.D0,  &\nH2(NDIM, NDIM) = 0.D0,  &\nH3(NDIM, NDIM) = 0.D0,  &\nH4(NDIM, NDIM) = 0.D0,  &\nH5(NDIM, NDIM) = 0.D0\n\nend module Global_Variables\n"
  },
  {
    "path": "Units/parser-fortran.r/auto.f.d/expected.tags",
    "content": "AUTO_TEST\tinput.f\t/^\tprogram AUTO_TEST$/;\"\tp\nD\tinput.f\t/^\tAUTOMATIC REAL P, D,/;\"\tv\tprogram:AUTO_TEST\nP\tinput.f\t/^\tAUTOMATIC REAL P,/;\"\tv\tprogram:AUTO_TEST\nQ\tinput.f\t/^\tAUTOMATIC REAL P, D, Q /;\"\tv\tprogram:AUTO_TEST\n"
  },
  {
    "path": "Units/parser-fortran.r/auto.f.d/input.f",
    "content": "! Provided by Brian Helsinki, 7 March 2003\n\tprogram AUTO_TEST\n\tAUTOMATIC A, B, C \n\tAUTOMATIC REAL P, D, Q \n\t!IMPLICIT AUTOMATIC REAL (X-Z) \n\tEND\n\n"
  },
  {
    "path": "Units/parser-fortran.r/bug565813.f90.d/expected.tags",
    "content": "N\tinput.f90\t/^    integer, parameter :: N /;\"\tv\tmodule:ctags_bug\nbar\tinput.f90\t/^        integer :: bar$/;\"\tk\ttype:foo_t\nctags_bug\tinput.f90\t/^module ctags_bug$/;\"\tm\nfoo_getbar\tinput.f90\t/^    integer function foo_getbar /;\"\tf\tmodule:ctags_bug\nfoo_set_bar\tinput.f90\t/^    pure subroutine foo_set_bar /;\"\ts\tmodule:ctags_bug\nfoo_setbar\tinput.f90\t/^    subroutine foo_setbar /;\"\ts\tmodule:ctags_bug\nfoo_t\tinput.f90\t/^    type :: foo_t$/;\"\tt\tmodule:ctags_bug\n"
  },
  {
    "path": "Units/parser-fortran.r/bug565813.f90.d/input.f90",
    "content": "module ctags_bug\n\n    implicit none\n    private\n    save\n\n    type :: foo_t\n        integer :: bar\n    end type foo_t\n\n    integer, parameter :: N = 1000\n\n    public :: foo_t\n    public :: foo_setbar\n    public :: foo_set_bar\n    public :: foo_getbar\n\ncontains\n\n    subroutine foo_setbar (f,b)\n        type(foo_t), intent(out) :: f\n        integer, intent(in) :: b\n\n        f%bar = b\n    end subroutine foo_setbar\n\n\n    pure subroutine foo_set_bar (f,b)\n        type(foo_t), intent(out) :: f\n        integer, intent(in) :: b\n\n        f%bar = b\n    end subroutine foo_set_bar\n\n\n    integer function foo_getbar (f)\n        type(foo_t), intent(in) :: f\n\n        foo_getbar = f%bar\n    end function foo_getbar\n\nend module ctags_bug\n"
  },
  {
    "path": "Units/parser-fortran.r/bug620288.f.d/expected.tags",
    "content": "bar\tinput.f\t/^\tdouble precision function bar(/;\"\tf\nfoo\tinput.f\t/^\tinteger function foo(/;\"\tf\n"
  },
  {
    "path": "Units/parser-fortran.r/bug620288.f.d/input.f",
    "content": "C Bugs item #620288, was opened at 2002-10-08 08:15\nC You can respond by visiting: \nC https://sourceforge.net/tracker/?func=detail&atid=106556&aid=620288&group_id=6556\nC \nC Category: None\nC Group: None\nC Status: Open\nC Resolution: None\nC Priority: 5\nC Submitted By: Nobody/Anonymous (nobody)\nC Assigned to: Nobody/Anonymous (nobody)\nC Summary: fortran function definition\nC \nC Initial Comment:\nC \nC System Information:\nC --------------\nC ctags version: \nC Exuberant Ctags 5.3.1, Copyright (C) 1996-2002 Darren \nC Hiebert\nC   Compiled: Sep 12 2002, 10:22:42\nC   Addresses: <dhiebert@users.sourceforge.net>, \nC http://ctags.sourceforge.net\nC   Optional compiled features: +wildcards, +regex\nC \nC Unix:\nC HP-UX B.11.00 A 9000/800 551726527\nC --------------\nC \nC Symptoms:\nC --------------\nC I have a fortran file that has a single function.  This \nC function has a\nC return type of double precision.  I type $ctags bar.f .  \nC This produces the expected \nC tags file.  However, tags does not contain the function \nC definition.\nC \nC This does not occur when the same function's return \nC type has been changed to \nC a integer or character data return type.\nC --------------\nC \nC \nC Examples in which I can repeat the experience with their \nC respective tags files:\nC --------------\nC \nC \nC foo.f\nC --------------\n\tinteger function foo(a)\n\n\tinteger a\n\tfoo = a\n\tend\nC --------------\nC \nC \nC tags\nC --------------\nC !_TAG_FILE_FORMAT\t2\t/extended \nC format; --format=1 will not append ;\" to lines/\nC !_TAG_FILE_SORTED\t1\nC \t/0=unsorted, 1=sorted, 2=foldcase/\nC !_TAG_PROGRAM_AUTHOR\tDarren Hiebert\nC \t/dhiebert@users.sourceforge.net/\nC !_TAG_PROGRAM_NAME\tExuberant Ctags\t//\nC !_TAG_PROGRAM_URL\nC \thttp://ctags.sourceforge.net\t/official site/\nC !_TAG_PROGRAM_VERSION\t5.3.1\t//\nC foo\tfoo.f\t/^\tinteger function foo(/;\"\tf\nC --------------\nC \nC \nC \nC bar.f\t\nC ---------------\n\tdouble precision function bar(a)\n\t\n\tdouble precision a\n\tbar = a\n\tend\nC --------------\t\nC \nC tags\nC ---------------\nC !_TAG_FILE_FORMAT\t2\t/extended \nC format; --format=1 will not append ;\" to lines/\nC !_TAG_FILE_SORTED\t1\nC \t/0=unsorted, 1=sorted, 2=foldcase/\nC !_TAG_PROGRAM_AUTHOR\tDarren Hiebert\nC \t/dhiebert@users.sourceforge.net/\nC !_TAG_PROGRAM_NAME\tExuberant Ctags\t//\nC !_TAG_PROGRAM_URL\nC \thttp://ctags.sourceforge.net\t/official site/\nC !_TAG_PROGRAM_VERSION\t5.3.1\t//\nC ---------------\n"
  },
  {
    "path": "Units/parser-fortran.r/bug629.d/args.ctags",
    "content": "--language-force=Fortran\n"
  },
  {
    "path": "Units/parser-fortran.r/bug629.d/expected.tags",
    "content": "test_enumeration\tinput.c\t/^enum test_enumeration /;\"\tE\n"
  },
  {
    "path": "Units/parser-fortran.r/bug629.d/input.c",
    "content": "enum test_enumeration {\n    ENUM_1 = 1,\n    ENUM_2,\n    ENUM_3\n};\n"
  },
  {
    "path": "Units/parser-fortran.r/bug670433.f90.d/README",
    "content": "This test has the truncation issue #333.\n"
  },
  {
    "path": "Units/parser-fortran.r/bug670433.f90.d/expected.tags",
    "content": "bar\tinput.f90\t/^    subroutine bar /;\"\ts\tmodule:foobar\nf\tinput.f90\t/^        real function f(/;\"\tf\tfunction:foo\nfoo\tinput.f90\t/^    integer function foo /;\"\tf\tmodule:foobar\nfoobar\tinput.f90\t/^module foobar$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/bug670433.f90.d/input.f90",
    "content": "! Bugs item #670443, was opened at 2003-01-18 22:44\n! You can respond by visiting: \n! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=670443&group_id=6556\n! \n! Category: None\n! Group: None\n! Status: Open\n! Resolution: None\n! Priority: 5\n! Submitted By: Erik Edelmann (fanerier)\n! Assigned to: Nobody/Anonymous (nobody)\n! Summary: Fortran: Internal procedures causes trouble\n! \n! Initial Comment:\n! If a function in a module has an internal procedure\n! (after a CONTAINS-statement), everything in the module\n! after the parent function will be skipped.  I.e. in the\n! attached file, the subroutine 'bar' will not be listed\n! in the 'tags' file.  Note that this problem arises only\n! when the parent procedure is a function, if it is a\n! subroutine everything works fine.\n\nmodule foobar\n\ncontains\n\n    integer function foo (i)\n\n    contains    \n        \n        real function f(x)\n        end function f\n\n    end function foo\n\n\n    subroutine bar (n)\n    end subroutine bar\n\nend module foobar\n"
  },
  {
    "path": "Units/parser-fortran.r/bug726712.f90.d/expected.tags",
    "content": "sub1\tinput.f90\t/^      subroutine sub1(/;\"\ts\nsub2\tinput.f90\t/^      subroutine sub2(/;\"\ts\ntagstest_ctrl\tinput.f90\t/^      subroutine tagstest_ctrl(/;\"\ts\n"
  },
  {
    "path": "Units/parser-fortran.r/bug726712.f90.d/input.f90",
    "content": "! Bugs item #726712, was opened at 2003-04-24 08:36\n! Message generated for change (Comment added) made by schubidu\n! You can respond by visiting: \n! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=726712&group_id=6556\n! \n! Category: None\n! Group: None\n! Status: Open\n! Resolution: None\n! Priority: 5\n! Submitted By: sandra schrdter (schubidu)\n! Assigned to: Darren Hiebert (dhiebert)\n! Summary: ctags 5.5 and f90: \"endsubroutine\" not recognized\n! \n! Initial Comment:\n! Dear Ctags'ers. :)\n! \n! First of all: good tool! :) I stumbled across ctags for\n! my gvim6, wanted to use the nice plugin taglist.\n! \n! My System: HP-Unix and ctags 5.5\n! \n! My problem is the following. The command:\n! \n! \"ctags tagstest.f90\"\n! \n! builds a tagsfile that lacks 1 of the declared 3\n! subroutines. \n! The problem disappears when the declaration of the\n! subroutine ends in \"end subroutine\" and not in\n! \"endsubroutine\", although \"endsubroutine\" is correct\n! Fortran90 syntax, AFAIK.\n! \n! Is there a chance to get this corrected?\n! \n! \n! The example file tagstest.f90:\n\n      subroutine tagstest_ctrl()\n         real :: a\n         a = 0.0\n         call sub1( a)\n         call sub2( a)\n      endsubroutine tagstest_ctrl\n\n      subroutine sub1( a)\n      real,intent( inout) ::a\n      a = 1.1\n      endsubroutine sub1\n      \n      subroutine sub2( a)\n      real,intent( inout) ::a\n      a = 2.2\n      endsubroutine sub2\n\n! ----------------------------------------------------------------------\n! \n! Comment By: sandra schrdter (schubidu)\n! Date: 2003-05-28 13:17\n! \n! Message:\n! Logged In: YES \n! user_id=763447\n! \n! I realized that there are also problems when a subroutine\n! ends only with the keyword\n! end\n! \n! The following subroutine is listed but cannot be selected\n! (that is, the cursor won't go there)\n! \n! ----------------------------------------------------------------------\n"
  },
  {
    "path": "Units/parser-fortran.r/bug726875.f90.d/expected.tags",
    "content": "coma\tinput.f90\t19;\"\tc\ncomb\tinput.f90\t22;\"\tc\ncomc\tinput.f90\t24;\"\tc\n"
  },
  {
    "path": "Units/parser-fortran.r/bug726875.f90.d/input.f90",
    "content": "! Bugs item #726875, was opened at 2003-04-24 15:30\n! Message generated for change (Tracker Item Submitted) made by Item Submitter\n! You can respond by visiting: \n! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=726875&group_id=6556\n!\n! Category: None\n! Group: None\n! Status: Open\n! Resolution: None\n! Priority: 5\n! Submitted By: sandra schrdter (schubidu)\n! Assigned to: Nobody/Anonymous (nobody)\n! Summary: ctags 5.5 and f90: common and !\n! \n! Initial Comment:\n! ctags won't add a common-block definition to the tags\n! file when the following occurs:\n\n        common /coma/ a,b,!foobar\n     +                c,d\n\n        common /comb/ e,f\n\n        common /comc/ g,h\n\n! The problem seems to be based on the fact that the\n! comment \"! foobar\" is followed by a continuation line\n! (\"+\" in column 6 shows that)\n"
  },
  {
    "path": "Units/parser-fortran.r/bug734933.f90.d/expected.tags",
    "content": "ADD_COMPONENTS\tinput.f90\t/^      SUBROUTINE ADD_COMPONENTS$/;\"\ts\tmodule:MDCOMPONENTS\nCOMP\tinput.f90\t/^      TYPE (COMPONENT), POINTER :: COMP$/;\"\tv\tmodule:MDCOMPONENTS\nCOMPONENT\tinput.f90\t/^      TYPE COMPONENT$/;\"\tt\tmodule:MDCOMPONENTS\nCOMPONENTS\tinput.f90\t/^      TYPE (COMPONENT_POINTER), DIMENSION(LIM_COMPONENTS) :: COMPONENTS, COMPONENTS_/;\"\tv\tmodule:MDCOMPONENTS\nCOMPONENTS_TMP\tinput.f90\t/^      TYPE (COMPONENT_POINTER), DIMENSION(LIM_COMPONENTS) :: COMPONENTS, COMPONENTS_TMP$/;\"\tv\tmodule:MDCOMPONENTS\nCOMPONENT_POINTER\tinput.f90\t/^      TYPE COMPONENT_POINTER /;\"\tt\tmodule:MDCOMPONENTS\nCOMP_TMP\tinput.f90\t/^      TYPE (COMPONENT_POINTER) :: COMP_TMP$/;\"\tv\tmodule:MDCOMPONENTS\nLIM_COMPONENTS\tinput.f90\t/^      INTEGER (INT4), PARAMETER :: LIM_COMPONENTS /;\"\tv\tmodule:MDCOMPONENTS\nMDCOMPONENTS\tinput.f90\t/^      MODULE MDCOMPONENTS$/;\"\tm\nMEMDEALLOC\tinput.f90\t/^      INTERFACE MEMDEALLOC$/;\"\ti\tmodule:MDCOMPONENTS\nNAME\tinput.f90\t/^        CHARACTER (LEN=30) :: NAME$/;\"\tk\ttype:COMPONENT\nNCOMP\tinput.f90\t/^      INTEGER (INT4) :: NUM_COMPONENTS = 0, NCOMP;/;\"\tv\tmodule:MDCOMPONENTS\nNUM_COMPONENTS\tinput.f90\t/^      INTEGER (INT4) :: NUM_COMPONENTS /;\"\tv\tmodule:MDCOMPONENTS\nNUM_PART\tinput.f90\t/^        INTEGER (INT4) :: NUM_PART$/;\"\tk\ttype:COMPONENT\nP\tinput.f90\t/^        TYPE (COMPONENT), POINTER :: P$/;\"\tk\ttype:COMPONENT_POINTER\nPART_LIST\tinput.f90\t/^        REAL (REAL8), DIMENSION(:), POINTER :: PART_LIST$/;\"\tk\ttype:COMPONENT\n"
  },
  {
    "path": "Units/parser-fortran.r/bug734933.f90.d/input.f90",
    "content": "      MODULE MDCOMPONENTS\n      \n      USE kindef\n      USE memory\n\n      IMPLICIT NONE\n\n      SAVE\n\n      INTEGER (INT4), PARAMETER :: LIM_COMPONENTS = 1000;\n      INTEGER (INT4) :: NUM_COMPONENTS = 0, NCOMP;\n      TYPE COMPONENT\n        CHARACTER (LEN=30) :: NAME\n        INTEGER (INT4) :: NUM_PART\n        REAL (REAL8), DIMENSION(:), POINTER :: PART_LIST\n      END TYPE\n\n      TYPE COMPONENT_POINTER \n        TYPE (COMPONENT), POINTER :: P\n      END TYPE\n\n      TYPE (COMPONENT), POINTER :: COMP\n      TYPE (COMPONENT_POINTER) :: COMP_TMP\n      TYPE (COMPONENT_POINTER), DIMENSION(LIM_COMPONENTS) :: COMPONENTS, COMPONENTS_TMP\n\n      INTERFACE MEMDEALLOC\n        MODULE PROCEDURE MEMDEALLOC_COMPONENTS_PTR\n      END INTERFACE\n  \n      CONTAINS\n\n      SUBROUTINE ADD_COMPONENTS\n\n      NUM_COMPONENTS = NUM_COMPONENTS + 1\n      CALL MEMALLOC (COMPONENTS(NUM_COMPONENTS)%P, IDALL999)\n\n      END SUBROUTINE ADD_COMPONENTS\n\n      END MODULE MDCOMPONENTS\n"
  },
  {
    "path": "Units/parser-fortran.r/bug858165.f90.d/expected.tags",
    "content": "a\tinput.f90\t/^integer :: a, &   !comment on variable a$/;\"\tv\tprogram:test\nb\tinput.f90\t/^           b, &   !comment on variable b$/;\"\tv\tprogram:test\nc\tinput.f90\t/^           c, &   !comment on variable c$/;\"\tv\tprogram:test\nd\tinput.f90\t/^           d      !comment on variable d$/;\"\tv\tprogram:test\ntest\tinput.f90\t/^program test$/;\"\tp\n"
  },
  {
    "path": "Units/parser-fortran.r/bug858165.f90.d/input.f90",
    "content": "! Bugs item #858165, was opened at 2003-12-11 10:09\n! Message generated for change (Tracker Item Submitted) made by Item Submitter\n! You can respond by visiting: \n! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=858165&group_id=6556\n! \n! Category: None\n! Group: None\n! Status: Open\n! Resolution: None\n! Priority: 5\n! Submitted By: Blazej Krzeminski (blazk)\n! Assigned to: Nobody/Anonymous (nobody)\n! Summary: Fortran90: comment line after continuation character &\n! \n! Initial Comment:\nprogram test\n\ninteger :: a, &   !comment on variable a\n           b, &   !comment on variable b\n                  !more comment on variable b, CTAGS STOPS HERE\n           c, &   !comment on variable c\n           d      !comment on variable d\nend program test\n\n! ctags will index program test, a,b but not c,d\n"
  },
  {
    "path": "Units/parser-fortran.r/bug877956.f90.d/args.ctags",
    "content": "--kinds-Fortran=v\n"
  },
  {
    "path": "Units/parser-fortran.r/bug877956.f90.d/expected.tags-x",
    "content": "c2               variable     25 input.f90 INTEGER :: cm1 =-1, c2 = 2\nc2               variable     39 input.f90 INTEGER :: cm1 = -1, c2 = 2\ncm1              variable     25 input.f90 INTEGER :: cm1 =-1, c2 = 2\ncm1              variable     39 input.f90 INTEGER :: cm1 = -1, c2 = 2\n"
  },
  {
    "path": "Units/parser-fortran.r/bug877956.f90.d/input.f90",
    "content": "! Bugs item #877956, was opened at 2004-01-15 17:59\n! Message generated for change (Tracker Item Submitted) made by Item Submitter\n! You can respond by visiting: \n! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=877956&group_id=6556\n!\n! Category: None\n! Group: None\n! Status: Open\n! Resolution: None\n! Priority: 5\n! Submitted By: Randy Hood (randy762)\n! Assigned to: Nobody/Anonymous (nobody)\n! Summary: Broken Fortran variable listing after =-1\n!\n! Initial Comment:\n! When I run ctags v5.5.2 on Redhat Linux 9 with the command\n!\n! ctags --kinds-Fortran=v  -x test.f90\n!                                      \n! where test.f90 is\n! ----------------------------------\nPROGRAM test\n\n IMPLICIT NONE\n INTEGER :: cm1 =-1, c2 = 2\n\nEND PROGRAM test\n! -------------------------------------\n!                                      \n! I only get this one line of output\n!\n! cm1              variable      4 test.f90        INTEGER :: cm1 =-1, c2 = 2\n!                                                      \n! If I change one line of test.f90 so that it is now\n! ----------------------------------------\nPROGRAM test\n\n IMPLICIT NONE\n INTEGER :: cm1 = -1, c2 = 2\n\nEND PROGRAM test\n! -----------------------------------------\n! and run the command\n!                                      \n! ctags --kinds-Fortran=v  -x test.f90\n!                                      \n! I get this correct output\n!                                      \n! c2               variable      4 test.f90        INTEGER :: cm1 = -1, c2 = 2\n! cm1              variable      4 test.f90        INTEGER :: cm1 = -1, c2 = 2\n!\n! ----------------------------------------------------------------------\n! You can respond by visiting: \n! https://sourceforge.net/tracker/?func=detail&atid=106556&aid=877956&group_id=6556\n"
  },
  {
    "path": "Units/parser-fortran.r/byte.f.d/expected.tags",
    "content": "A\tinput.f\t/^\tBYTE A,/;\"\tv\tprogram:byte_test\nA1\tinput.f\t/^\tBYTE A1,/;\"\tv\tprogram:byte_test\nA2\tinput.f\t/^\tBYTE A2 /;\"\tv\tprogram:byte_test\nB\tinput.f\t/^\tBYTE A, B,/;\"\tv\tprogram:byte_test\nB1\tinput.f\t/^\tBYTE A1, B1,/;\"\tv\tprogram:byte_test\nB2\tinput.f\t/^\tBYTE A2 \\/'x'\\/, B2 /;\"\tv\tprogram:byte_test\nC\tinput.f\t/^\tBYTE A, B, C /;\"\tv\tprogram:byte_test\nC1\tinput.f\t/^\tBYTE A1, B1, C1(/;\"\tv\tprogram:byte_test\nC2\tinput.f\t/^\tBYTE A2 \\/'x'\\/, B2 \\/255\\/, C2(/;\"\tv\tprogram:byte_test\nbyte_test\tinput.f\t/^\tprogram byte_test$/;\"\tp\n"
  },
  {
    "path": "Units/parser-fortran.r/byte.f.d/input.f",
    "content": "! Provided by Brian Helsinki, 7 March 2003\n\tprogram byte_test\n\tBYTE A, B, C \n\tBYTE A1, B1, C1(10) \n\tBYTE A2 /'x'/, B2 /255/, C2(10)\n\tEND\n\n"
  },
  {
    "path": "Units/parser-fortran.r/char-selector.f90.d/expected.tags",
    "content": "MXDDI\tinput.f90\t/^      INTEGER(4), PRIVATE, PARAMETER :: MXDDI=/;\"\tv\tmodule:OUT_RD5\nOUT_RD5\tinput.f90\t/^      MODULE OUT_RD5$/;\"\tm\nfpshape\tinput.f90\t/^      CHARACTER(1024) :: fpshape$/;\"\tv\tmodule:OUT_RD5\nfpshape2\tinput.f90\t/^      CHARACTER*(1024) :: fpshape2$/;\"\tv\tmodule:OUT_RD5\nlast\tinput.f90\t/^      INTEGER(4), PRIVATE :: last$/;\"\tv\tmodule:OUT_RD5\nlist\tinput.f90\t/^      INTEGER(4), PRIVATE, DIMENSION (MXDDI+1) :: list$/;\"\tv\tmodule:OUT_RD5\nnout\tinput.f90\t/^      INTEGER(4), PRIVATE :: nout$/;\"\tv\tmodule:OUT_RD5\ntemp\tinput.f90\t/^      CHARACTER*(MXPATHLNGTH) temp$/;\"\tv\tmodule:OUT_RD5\ntitles\tinput.f90\t/^      CHARACTER*40 titles(/;\"\tv\tmodule:OUT_RD5\nunits\tinput.f90\t/^      CHARACTER*12 units(/;\"\tv\tmodule:OUT_RD5\n"
  },
  {
    "path": "Units/parser-fortran.r/char-selector.f90.d/input.f90",
    "content": "! Test for bug in parsing of char-selector\n      MODULE OUT_RD5\n      USE inmdmx\n      IMPLICIT NONE\n      SAVE\n\n      CHARACTER*(MXPATHLNGTH) temp\n      PRIVATE :: temp\n      INTEGER(4), PRIVATE, PARAMETER :: MXDDI=45\n      CHARACTER*40 titles(MXDDI)\n      PRIVATE :: titles\n      CHARACTER*12 units(MXDDI)\n      PRIVATE :: units\n      INTEGER(4), PRIVATE, DIMENSION (MXDDI+1) :: list\n      CHARACTER(1024) :: fpshape\n      INTEGER(4), PRIVATE :: nout\n      CHARACTER*(1024) :: fpshape2\n      INTEGER(4), PRIVATE :: last\n      END MODULE OUT_RD5\n"
  },
  {
    "path": "Units/parser-fortran.r/common-json.f.d/expected.tags-json",
    "content": "{\"_type\": \"tag\", \"name\": \"common1\", \"path\": \"input.f\", \"pattern\": \"/^        COMMON \\\\/common1\\\\//\", \"kind\": \"common\", \"scope\": \"main\", \"scopeKind\": \"program\"}\n{\"_type\": \"tag\", \"name\": \"common2\", \"path\": \"input.f\", \"pattern\": \"/^        COMMON \\\\/common2\\\\//\", \"kind\": \"common\", \"scope\": \"main\", \"scopeKind\": \"program\"}\n{\"_type\": \"tag\", \"name\": \"common3\", \"path\": \"input.f\", \"pattern\": \"/^        COMMON \\\\/common2\\\\/ c2a (1:3), c2b \\\\/common3\\\\//\", \"kind\": \"common\", \"scope\": \"main\", \"scopeKind\": \"program\"}\n{\"_type\": \"tag\", \"name\": \"main\", \"path\": \"input.f\", \"pattern\": \"/^        PROGRAM main$/\", \"kind\": \"program\"}\n"
  },
  {
    "path": "Units/parser-fortran.r/common-json.f.d/input.f",
    "content": "        PROGRAM main\n        COMMON /common1/ c1a, c1b\n        COMMON /common2/ c2a (1:3), c2b /common3/ c3a, c3b\n        END\n"
  },
  {
    "path": "Units/parser-fortran.r/common-xref.f.d/args.ctags",
    "content": "--_xformat=%-16N %-10K %4n %-16F %P\n"
  },
  {
    "path": "Units/parser-fortran.r/common-xref.f.d/expected.tags-x",
    "content": "common1          common        2 input.f /^        COMMON \\/common1\\//\ncommon2          common        3 input.f /^        COMMON \\/common2\\//\ncommon3          common        3 input.f /^        COMMON \\/common2\\/ c2a (1:3), c2b \\/common3\\//\nmain             program       1 input.f /^        PROGRAM main$/\n"
  },
  {
    "path": "Units/parser-fortran.r/common-xref.f.d/input.f",
    "content": "        PROGRAM main\n        COMMON /common1/ c1a, c1b\n        COMMON /common2/ c2a (1:3), c2b /common3/ c3a, c3b\n        END\n"
  },
  {
    "path": "Units/parser-fortran.r/common.f.d/expected.tags",
    "content": "common1\tinput.f\t2;\"\tc\tprogram:main\ncommon2\tinput.f\t3;\"\tc\tprogram:main\ncommon3\tinput.f\t3;\"\tc\tprogram:main\nmain\tinput.f\t/^        PROGRAM main$/;\"\tp\n"
  },
  {
    "path": "Units/parser-fortran.r/common.f.d/input.f",
    "content": "        PROGRAM main\n        COMMON /common1/ c1a, c1b\n        COMMON /common2/ c2a (1:3), c2b /common3/ c3a, c3b\n        END\n"
  },
  {
    "path": "Units/parser-fortran.r/continuation.f90.d/expected.tags",
    "content": "para_a\tinput.f90\t/^para_a,       & ! para_a /;\"\tv\tmodule:test\npara_b\tinput.f90\t/^para_b,       & ! para_b /;\"\tv\tmodule:test\npara_c\tinput.f90\t/^para_c          ! para_c /;\"\tv\tmodule:test\ntest\tinput.f90\t/^module test$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/continuation.f90.d/input.f90",
    "content": "! Problem reported by Jim on 7 Jul 2002\nmodule test\nreal*8 ::     &\npara_a,       & ! para_a is ...\npara_b,       & ! para_b is ...\npara_c          ! para_c is ...\n"
  },
  {
    "path": "Units/parser-fortran.r/debian_432872.f90.d/expected.tags",
    "content": "FOO\tinput.f90\t/^  subroutine FOO /;\"\ts\tmodule:FOO\nFOO\tinput.f90\t/^module FOO$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/debian_432872.f90.d/input.f90",
    "content": "! { dg-do compile } \n! PR18923 segfault after subroutine name confusion.\nmodule FOO\ncontains\n  subroutine FOO ! { dg-error \"conflicts with PROCEDURE\" }\n    character(len=selected_int_kind(0)) :: C ! { dg-error \"data declaration statement\" }\n  end subroutine ! { dg-error \"Expecting END MODULE statement\" }\nend ! { dg-warning \"CONTAINS statement without FUNCTION\" }"
  },
  {
    "path": "Units/parser-fortran.r/dollars-in-names.d/args.ctags",
    "content": "--sort=no\n--kinds-Fortran=+L\n"
  },
  {
    "path": "Units/parser-fortran.r/dollars-in-names.d/expected.tags",
    "content": "name$\tinput.f\t/^      function name$(/;\"\tf\nname$\tinput.f\t/^      integer name\\$$/;\"\tL\tfunction:name$\tfile:\nmain\tinput.f\t/^      program main$/;\"\tp\nret$\tinput.f\t/^      integer ret\\$$/;\"\tv\tprogram:main\n"
  },
  {
    "path": "Units/parser-fortran.r/dollars-in-names.d/input.f",
    "content": "C     Taken from #4033 submitted by @navinp0304.\n      function name$()\n      integer name$\n      name$ = 42\n      end function\n\n      program main\n      integer ret$\n      ret$=name$()\n      print *,ret$\n      end program\n"
  },
  {
    "path": "Units/parser-fortran.r/dollars-in-names.d/validator",
    "content": "fortran+dollar-ok\n"
  },
  {
    "path": "Units/parser-fortran.r/dopbl2.f.d/expected.tags",
    "content": "DOPBL2\tinput.f\t/^      DOUBLE PRECISION FUNCTION DOPBL2(/;\"\tf\n"
  },
  {
    "path": "Units/parser-fortran.r/dopbl2.f.d/input.f",
    "content": "! Bug reported by Brian Helinski <bjh@absoft.com> on 4 Feb 2003\n      DOUBLE PRECISION FUNCTION DOPBL2( SUBNAM, M, N, KKL, KKU )\n*\n*  -- LAPACK timing routine (version 3.0) --\n*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,\n*     Courant Institute, Argonne National Lab, and Rice University\n*     June 30, 1999\n*\n*     .. Scalar Arguments ..\n      CHARACTER*6        SUBNAM\n      INTEGER            KKL, KKU, M, N\n*     ..\n*\n*  Purpose\n*  =======\n*\n*  DOPBL2 computes an approximation of the number of floating point\n*  operations used by a subroutine SUBNAM with the given values\n*  of the parameters M, N, KL, and KU.\n*\n*  This version counts operations for the Level 2 BLAS.\n*\n*  Arguments\n*  =========\n*\n*  SUBNAM  (input) CHARACTER*6\n*          The name of the subroutine.\n*\n*  M       (input) INTEGER\n*          The number of rows of the coefficient matrix.  M >= 0.\n*\n*  N       (input) INTEGER\n*          The number of columns of the coefficient matrix.\n*          If the matrix is square (such as in a solve routine) then\n*          N is the number of right hand sides.  N >= 0.\n*\n*  KKL     (input) INTEGER\n*          The lower band width of the coefficient matrix.\n*          KL is set to max( 0, min( M-1, KKL ) ).\n*\n*  KKU     (input) INTEGER\n*          The upper band width of the coefficient matrix.\n*          KU is set to max( 0, min( N-1, KKU ) ).\n*\n*  =====================================================================\n*\n*     .. Local Scalars ..\n      CHARACTER          C1\n      CHARACTER*2        C2\n      CHARACTER*3        C3\n      DOUBLE PRECISION   ADDS, EK, EM, EN, KL, KU, MULTS\n*     ..\n*     .. External Functions ..\n      LOGICAL            LSAME, LSAMEN\n      EXTERNAL           LSAME, LSAMEN\n*     ..\n*     .. Intrinsic Functions ..\n      INTRINSIC          MAX, MIN\n*     ..\n*     .. Executable Statements ..\n*\n*     Quick return if possible\n*\n      IF( M.LE.0 .OR. .NOT.( LSAME( SUBNAM, 'S' ) .OR. LSAME( SUBNAM,\n     $    'D' ) .OR. LSAME( SUBNAM, 'C' ) .OR. LSAME( SUBNAM, 'Z' ) ) )\n     $     THEN\n         DOPBL2 = 0\n         RETURN\n      END IF\n*\n      C1 = SUBNAM( 1: 1 )\n      C2 = SUBNAM( 2: 3 )\n      C3 = SUBNAM( 4: 6 )\n      MULTS = 0\n      ADDS = 0\n      KL = MAX( 0, MIN( M-1, KKL ) )\n      KU = MAX( 0, MIN( N-1, KKU ) )\n      EM = M\n      EN = N\n      EK = KL\n*\n*     -------------------------------\n*     Matrix-vector multiply routines\n*     -------------------------------\n*\n      IF( LSAMEN( 3, C3, 'MV ' ) ) THEN\n*\n         IF( LSAMEN( 2, C2, 'GE' ) ) THEN\n*\n            MULTS = EM*( EN+1.D0 )\n            ADDS = EM*EN\n*\n*        Assume M <= N + KL and KL < M\n*               N <= M + KU and KU < N\n*        so that the zero sections are triangles.\n*\n         ELSE IF( LSAMEN( 2, C2, 'GB' ) ) THEN\n*\n            MULTS = EM*( EN+1.D0 ) - ( EM-1.D0-KL )*( EM-KL ) / 2.D0 -\n     $              ( EN-1.D0-KU )*( EN-KU ) / 2.D0\n            ADDS = EM*( EN+1.D0 ) - ( EM-1.D0-KL )*( EM-KL ) / 2.D0 -\n     $             ( EN-1.D0-KU )*( EN-KU ) / 2.D0\n*\n         ELSE IF( LSAMEN( 2, C2, 'SY' ) .OR. LSAMEN( 2, C2, 'SP' ) .OR.\n     $            LSAMEN( 3, SUBNAM, 'CHE' ) .OR.\n     $            LSAMEN( 3, SUBNAM, 'ZHE' ) .OR.\n     $            LSAMEN( 3, SUBNAM, 'CHP' ) .OR.\n     $            LSAMEN( 3, SUBNAM, 'ZHP' ) ) THEN\n*\n            MULTS = EM*( EM+1.D0 )\n            ADDS = EM*EM\n*\n         ELSE IF( LSAMEN( 2, C2, 'SB' ) .OR.\n     $            LSAMEN( 3, SUBNAM, 'CHB' ) .OR.\n     $            LSAMEN( 3, SUBNAM, 'ZHB' ) ) THEN\n*\n            MULTS = EM*( EM+1.D0 ) - ( EM-1.D0-EK )*( EM-EK )\n            ADDS = EM*EM - ( EM-1.D0-EK )*( EM-EK )\n*\n         ELSE IF( LSAMEN( 2, C2, 'TR' ) .OR. LSAMEN( 2, C2, 'TP' ) )\n     $             THEN\n*\n            MULTS = EM*( EM+1.D0 ) / 2.D0\n            ADDS = ( EM-1.D0 )*EM / 2.D0\n*\n         ELSE IF( LSAMEN( 2, C2, 'TB' ) ) THEN\n*\n            MULTS = EM*( EM+1.D0 ) / 2.D0 -\n     $              ( EM-EK-1.D0 )*( EM-EK ) / 2.D0\n            ADDS = ( EM-1.D0 )*EM / 2.D0 -\n     $             ( EM-EK-1.D0 )*( EM-EK ) / 2.D0\n*\n         END IF\n*\n*     ---------------------\n*     Matrix solve routines\n*     ---------------------\n*\n      ELSE IF( LSAMEN( 3, C3, 'SV ' ) ) THEN\n*\n         IF( LSAMEN( 2, C2, 'TR' ) .OR. LSAMEN( 2, C2, 'TP' ) ) THEN\n*\n            MULTS = EM*( EM+1.D0 ) / 2.D0\n            ADDS = ( EM-1.D0 )*EM / 2.D0\n*\n         ELSE IF( LSAMEN( 2, C2, 'TB' ) ) THEN\n*\n            MULTS = EM*( EM+1.D0 ) / 2.D0 -\n     $              ( EM-EK-1.D0 )*( EM-EK ) / 2.D0\n            ADDS = ( EM-1.D0 )*EM / 2.D0 -\n     $             ( EM-EK-1.D0 )*( EM-EK ) / 2.D0\n*\n         END IF\n*\n*     ----------------\n*     Rank-one updates\n*     ----------------\n*\n      ELSE IF( LSAMEN( 3, C3, 'R  ' ) ) THEN\n*\n         IF( LSAMEN( 3, SUBNAM, 'SGE' ) .OR.\n     $       LSAMEN( 3, SUBNAM, 'DGE' ) ) THEN\n*\n            MULTS = EM*EN + MIN( EM, EN )\n            ADDS = EM*EN\n*\n         ELSE IF( LSAMEN( 2, C2, 'SY' ) .OR. LSAMEN( 2, C2, 'SP' ) .OR.\n     $            LSAMEN( 3, SUBNAM, 'CHE' ) .OR.\n     $            LSAMEN( 3, SUBNAM, 'CHP' ) .OR.\n     $            LSAMEN( 3, SUBNAM, 'ZHE' ) .OR.\n     $            LSAMEN( 3, SUBNAM, 'ZHP' ) ) THEN\n*\n            MULTS = EM*( EM+1.D0 ) / 2.D0 + EM\n            ADDS = EM*( EM+1.D0 ) / 2.D0\n*\n         END IF\n*\n      ELSE IF( LSAMEN( 3, C3, 'RC ' ) .OR. LSAMEN( 3, C3, 'RU ' ) ) THEN\n*\n         IF( LSAMEN( 3, SUBNAM, 'CGE' ) .OR.\n     $       LSAMEN( 3, SUBNAM, 'ZGE' ) ) THEN\n*\n            MULTS = EM*EN + MIN( EM, EN )\n            ADDS = EM*EN\n*\n         END IF\n*\n*     ----------------\n*     Rank-two updates\n*     ----------------\n*\n      ELSE IF( LSAMEN( 3, C3, 'R2 ' ) ) THEN\n         IF( LSAMEN( 2, C2, 'SY' ) .OR. LSAMEN( 2, C2, 'SP' ) .OR.\n     $       LSAMEN( 3, SUBNAM, 'CHE' ) .OR.\n     $       LSAMEN( 3, SUBNAM, 'CHP' ) .OR.\n     $       LSAMEN( 3, SUBNAM, 'ZHE' ) .OR.\n     $       LSAMEN( 3, SUBNAM, 'ZHP' ) ) THEN\n*\n            MULTS = EM*( EM+1.D0 ) + 2.D0*EM\n            ADDS = EM*( EM+1.D0 )\n*\n         END IF\n      END IF\n*\n*     ------------------------------------------------\n*     Compute the total number of operations.\n*     For real and double precision routines, count\n*        1 for each multiply and 1 for each add.\n*     For complex and complex*16 routines, count\n*        6 for each multiply and 2 for each add.\n*     ------------------------------------------------\n*\n      IF( LSAME( C1, 'S' ) .OR. LSAME( C1, 'D' ) ) THEN\n*\n         DOPBL2 = MULTS + ADDS\n*\n      ELSE\n*\n         DOPBL2 = 6*MULTS + 2*ADDS\n*\n      END IF\n*\n      RETURN\n*\n*     End of DOPBL2\n*\n      END\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-abstract-implementation.d/args.ctags",
    "content": "--fields=+m\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-abstract-implementation.d/expected.tags",
    "content": "list_type\tinput.f90\t/^  type, abstract :: list_type$/;\"\tt\tmodule:test_implementation\timplementation:abstract\ntest_implementation\tinput.f90\t/^module test_implementation$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-abstract-implementation.d/input.f90",
    "content": "module test_implementation\n  type, abstract :: list_type\n  end type list_type\nend module test_implementation\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-abstract-interface.d/args.ctags",
    "content": "--kinds-Fortran=+PL\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-abstract-interface.d/expected.tags",
    "content": "__anonadfcf4320105\tinput.f90\t/^  abstract interface$/;\"\ti\tmodule:test\nadd\tinput.f90\t/^    procedure(suba), deferred :: add$/;\"\tM\ttype:atype\natype\tinput.f90\t/^  type, abstract :: atype$/;\"\tt\tmodule:test\nb\tinput.f90\t/^      class(atype) :: self, b$/;\"\tL\tprototype:suba\tfile:\nbtype\tinput.f90\t/^  type, abstract, extends(atype) :: btype$/;\"\tt\tmodule:test\nc\tinput.f90\t/^      integer c,/;\"\tL\tprototype:suba\tfile:\nd\tinput.f90\t/^      integer c, d$/;\"\tL\tprototype:suba\tfile:\nself\tinput.f90\t/^      class(atype) :: self,/;\"\tL\tprototype:suba\tfile:\nsuba\tinput.f90\t/^    subroutine suba(/;\"\tP\tinterface:__anonadfcf4320105\ntest\tinput.f90\t/^module test$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-abstract-interface.d/input.f90",
    "content": "module test\n\n  type, abstract :: atype\n  contains\n    procedure(suba), deferred :: add\n  end type\n  type, abstract, extends(atype) :: btype\n  end type\n\n  abstract interface\n    subroutine suba(self, b)\n      use, intrinsic :: iso_c_binding\n      import :: atype\n      import btype\n      implicit none\n      integer c, d\n      class(atype) :: self, b\n    end subroutine\n  end interface\n\nend module test\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-associate.d/expected.tags",
    "content": "a\tinput.f90\t/^  real :: a$/;\"\tv\tmodule:with_associate\ndo_other_stuff\tinput.f90\t/^  subroutine do_other_stuff(/;\"\ts\tmodule:with_associate\ndo_stuff\tinput.f90\t/^  function do_stuff(/;\"\tf\tmodule:with_associate\nwith_associate\tinput.f90\t/^module with_associate$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-associate.d/input.f90",
    "content": "module with_associate\n  real :: a\n\ncontains\n\n  function do_stuff(a) result(c)\n    real, intent(in) :: a\n\n    associate (b => a)\n      c = b\n    end associate\n  end function do_stuff\n\n  subroutine do_other_stuff(a)\n    real, intent(in out) :: a\n\n    a = 2 * a\n  end subroutine do_other_stuff\n\nend module with_associate\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-bind-c.d/args.ctags",
    "content": "--kinds-Fortran=+P\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-bind-c.d/expected.tags",
    "content": "__anon73f11bcd0105\tinput.f90\t/^  interface$/;\"\ti\tmodule:test_bind_c\na\tinput.f90\t/^    real(c_double) :: a$/;\"\tk\ttype:atype\natype\tinput.f90\t/^  type, bind(c) :: atype$/;\"\tt\tmodule:test_bind_c\nglobal_flag\tinput.f90\t/^  integer(C_INT), bind(C, name=\"_MyProject_flags\") :: global_flag$/;\"\tv\tmodule:test_bind_c\nprint_c\tinput.f90\t/^    subroutine print_c(/;\"\tP\tinterface:__anon73f11bcd0105\ntest_bind_c\tinput.f90\t/^module test_bind_c$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-bind-c.d/input.f90",
    "content": "! See https://gcc.gnu.org/onlinedocs/gfortran/Interoperability-with-C.html\nmodule test_bind_c\n  use iso_c_binding\n\n  ! test derived type\n  type, bind(c) :: atype\n    real(c_double) :: a\n  end type atype\n  ! this is\n  ! struct {\n  !   double a;\n  ! } atype;\n  ! in C language\n\n  ! test interoperable global variable\n  integer(C_INT), bind(C, name=\"_MyProject_flags\") :: global_flag\n\n  ! test Interoperable Subroutines and Functions\n  interface\n    subroutine print_c(string) bind(C, name=\"print_C\")\n      use iso_c_binding, only: c_char\n      character(kind=c_char) :: string(*)\n    end subroutine print_c\n  end interface\nend module test_bind_c\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-block.d/expected.tags",
    "content": "suba\tinput.f90\t/^  SUBROUTINE suba(/;\"\ts\tmodule:test_block\nsubb\tinput.f90\t/^  subroutine subb$/;\"\ts\tmodule:test_block\ntest_block\tinput.f90\t/^module test_block$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-block.d/input.f90",
    "content": "module test_block\n\ncontains\n\n  SUBROUTINE suba()\n    INTEGER :: a\n    \n    a = 5\n    BLOCK\n      INTEGER :: b\n      b = a + 2\n    END BLOCK\n  END SUBROUTINE\n\n  subroutine subb\n  \n  end subroutine\n\nend module test_block\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-derived-type-params.d/args.ctags",
    "content": "--fields=+m\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-derived-type-params.d/expected.tags",
    "content": "Members\tinput.f90\t/^module Members$/;\"\tm\nMySubroutine\tinput.f90\t/^  subroutine MySubroutine(/;\"\ts\tmodule:Members\ncoordinates\tinput.f90\t/^    REAL :: coordinates(/;\"\tk\ttype:general_point\nd\tinput.f90\t/^    INTEGER(selected_int_kind(12)), LEN :: d$/;\"\tk\ttype:humongous_matrix\ndim\tinput.f90\t/^    INTEGER, KIND :: dim$/;\"\tk\ttype:general_point\nelement\tinput.f90\t/^    REAL(k) :: element(/;\"\tk\ttype:humongous_matrix\ngeneral_point\tinput.f90\t/^  TYPE general_point(/;\"\tt\tmodule:Members\nhumongous_matrix\tinput.f90\t/^  TYPE humongous_matrix(/;\"\tt\tmodule:Members\nk\tinput.f90\t/^    INTEGER, KIND :: k = ki/;\"\tk\ttype:humongous_matrix\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-derived-type-params.d/input.f90",
    "content": "module Members\n  implicit none\n\n  TYPE humongous_matrix(k, d)\n    !-- Derived-type parameters\n    INTEGER, KIND :: k = kind(0.0)\n    INTEGER(selected_int_kind(12)), LEN :: d\n    REAL(k) :: element(d,d)\n  END TYPE\n\n  TYPE general_point(dim)\n    INTEGER, KIND :: dim\n    REAL :: coordinates(dim)\n  END TYPE\n\ncontains\n\n  subroutine MySubroutine(arg)\n  ! ...\n  end subroutine MySubroutine\n\nend module Members\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-enum.d/expected.tags",
    "content": "Constants\tinput.f90\t/^module Constants$/;\"\tm\nE_e\tinput.f90\t/^  real, parameter :: E_e /;\"\tv\tmodule:Constants\nNamed1\tinput.f90\t/^  enum :: Named1$/;\"\tE\tmodule:Constants\nNamed2\tinput.f90\t/^  enum Named2$/;\"\tE\tmodule:Constants\nNamed3\tinput.f90\t/^  enum(8) Named3$/;\"\tE\tmodule:Constants\nNamed4\tinput.f90\t/^  enum*8 Named4$/;\"\tE\tmodule:Constants\nNamed5\tinput.f90\t/^  enum(8) :: Named5$/;\"\tE\tmodule:Constants\nNamed6\tinput.f90\t/^  enum*8 :: Named6$/;\"\tE\tmodule:Constants\nNamed7\tinput.f90\t/^  enum, bind(c) :: Named7$/;\"\tE\tmodule:Constants\n__anoncfbded350103\tinput.f90\t/^  enum, bind(c) ! unnamed 1$/;\"\tE\tmodule:Constants\n__anoncfbded350203\tinput.f90\t/^  enum ! unnamed 2$/;\"\tE\tmodule:Constants\na\tinput.f90\t/^    enumerator :: a,/;\"\tN\tenum:__anoncfbded350203\nb\tinput.f90\t/^    enumerator :: a, b,/;\"\tN\tenum:__anoncfbded350203\nblack\tinput.f90\t/^    enumerator :: red =1, blue, black /;\"\tN\tenum:__anoncfbded350103\nblue\tinput.f90\t/^    enumerator :: red =1, blue,/;\"\tN\tenum:__anoncfbded350103\nbronze\tinput.f90\t/^    enumerator gold, silver, bronze$/;\"\tN\tenum:__anoncfbded350103\nc\tinput.f90\t/^    enumerator :: a, b, c$/;\"\tN\tenum:__anoncfbded350203\ngold\tinput.f90\t/^    enumerator gold,/;\"\tN\tenum:__anoncfbded350103\nhc\tinput.f90\t/^  real, parameter :: hc /;\"\tv\tmodule:Constants\nlavender\tinput.f90\t/^    enumerator :: pink, lavender$/;\"\tN\tenum:__anoncfbded350103\npi\tinput.f90\t/^  real, parameter :: pi /;\"\tv\tmodule:Constants\npink\tinput.f90\t/^    enumerator :: pink,/;\"\tN\tenum:__anoncfbded350103\npurple\tinput.f90\t/^    enumerator :: purple$/;\"\tN\tenum:__anoncfbded350103\nred\tinput.f90\t/^    enumerator :: red /;\"\tN\tenum:__anoncfbded350103\nsilver\tinput.f90\t/^    enumerator gold, silver,/;\"\tN\tenum:__anoncfbded350103\nx1\tinput.f90\t/^    enumerator :: x1,/;\"\tN\tenum:Named1\nx2\tinput.f90\t/^    enumerator :: x2,/;\"\tN\tenum:Named2\nx3\tinput.f90\t/^    enumerator :: x3,/;\"\tN\tenum:Named3\nx4\tinput.f90\t/^    enumerator :: x4,/;\"\tN\tenum:Named4\nx5\tinput.f90\t/^    enumerator :: x5,/;\"\tN\tenum:Named5\nx6\tinput.f90\t/^    enumerator :: x6,/;\"\tN\tenum:Named6\nx7\tinput.f90\t/^    enumerator :: x7,/;\"\tN\tenum:Named7\ny1\tinput.f90\t/^    enumerator :: x1, y1,/;\"\tN\tenum:Named1\ny2\tinput.f90\t/^    enumerator :: x2, y2,/;\"\tN\tenum:Named2\ny3\tinput.f90\t/^    enumerator :: x3, y3,/;\"\tN\tenum:Named3\ny4\tinput.f90\t/^    enumerator :: x4, y4,/;\"\tN\tenum:Named4\ny5\tinput.f90\t/^    enumerator :: x5, y5,/;\"\tN\tenum:Named5\ny6\tinput.f90\t/^    enumerator :: x6, y6,/;\"\tN\tenum:Named6\ny7\tinput.f90\t/^    enumerator :: x7, y7,/;\"\tN\tenum:Named7\nyellow\tinput.f90\t/^    enumerator yellow$/;\"\tN\tenum:__anoncfbded350103\nz1\tinput.f90\t/^    enumerator :: x1, y1, z1$/;\"\tN\tenum:Named1\nz2\tinput.f90\t/^    enumerator :: x2, y2, z2$/;\"\tN\tenum:Named2\nz3\tinput.f90\t/^    enumerator :: x3, y3, z3$/;\"\tN\tenum:Named3\nz4\tinput.f90\t/^    enumerator :: x4, y4, z4$/;\"\tN\tenum:Named4\nz5\tinput.f90\t/^    enumerator :: x5, y5, z5$/;\"\tN\tenum:Named5\nz6\tinput.f90\t/^    enumerator :: x6, y6, z6$/;\"\tN\tenum:Named6\nz7\tinput.f90\t/^    enumerator :: x7, y7, z7$/;\"\tN\tenum:Named7\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-enum.d/input.f90",
    "content": "module Constants\n  implicit none\n\n  real, parameter :: pi = 4 * atan(1.0)\n  real, parameter :: E_e = 510998.91013\n\n  ! we now have enumerators in F2003/8, for the sake of interop with C\n  enum, bind(c) ! unnamed 1\n    enumerator :: red =1, blue, black =5\n    enumerator yellow\n    enumerator gold, silver, bronze\n    enumerator :: purple\n    enumerator :: pink, lavender\n  end enum\n\n  enum ! unnamed 2\n    enumerator :: a, b, c\n  end enum\n\n  enum :: Named1\n    enumerator :: x1, y1, z1\n  end enum\n\n  enum Named2\n    enumerator :: x2, y2, z2\n  end enum\n\n  enum(8) Named3\n    enumerator :: x3, y3, z3\n  end enum\n\n  enum*8 Named4\n    enumerator :: x4, y4, z4\n  end enum\n\n  enum(8) :: Named5\n    enumerator :: x5, y5, z5\n  end enum\n\n  enum*8 :: Named6\n    enumerator :: x6, y6, z6\n  end enum\n\n  enum, bind(c) :: Named7\n    enumerator :: x7, y7, z7\n  end enum\n\n  real, parameter :: hc = 12398.4193\n\n  public\n\nend module Constants\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-extends-qualifier.d/args.ctags",
    "content": "--fields=+i\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-extends-qualifier.d/expected.tags",
    "content": "color\tinput.f90\t/^    integer :: color$/;\"\tk\ttype:shape\nfilled\tinput.f90\t/^    logical :: filled$/;\"\tk\ttype:shape\nlength\tinput.f90\t/^    integer :: length$/;\"\tk\ttype:rectangle\nrectangle\tinput.f90\t/^  type, extends(shape) :: rectangle$/;\"\tt\tmodule:test_extends\tinherits:shape\nshape\tinput.f90\t/^  type shape$/;\"\tt\tmodule:test_extends\ntest_extends\tinput.f90\t/^module test_extends$/;\"\tm\nwidth\tinput.f90\t/^    integer :: width$/;\"\tk\ttype:rectangle\nx\tinput.f90\t/^    integer :: x$/;\"\tk\ttype:shape\ny\tinput.f90\t/^    integer :: y$/;\"\tk\ttype:shape\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-extends-qualifier.d/input.f90",
    "content": "module test_extends\n  type shape\n    integer :: color\n    logical :: filled\n    integer :: x\n    integer :: y\n  end type shape\n  type, extends(shape) :: rectangle\n    integer :: length\n    integer :: width\n  end type rectangle\nend module test_extends\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-forall.d/expected.tags",
    "content": "a\tinput.f90\t/^  real :: a$/;\"\tv\tmodule:with_forall\nsub_with_forall\tinput.f90\t/^  subroutine sub_with_forall(/;\"\ts\tmodule:with_forall\ntwo\tinput.f90\t/^  function two(/;\"\tf\tmodule:with_forall\nwith_forall\tinput.f90\t/^module with_forall$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-forall.d/input.f90",
    "content": "! a module that uses a forall block\n\nmodule with_forall\n\n  real :: a\n\ncontains\n\n  subroutine sub_with_forall(x)\n    real, intent(inout) :: x(:)\n\n    integer :: i\n\n    forall(i=1:size(x))\n       x(i) = 0.5**i\n    end forall\n  end subroutine sub_with_forall\n\n\n  function two() result(res)\n    real :: res\n\n    res = 2.0\n  end function two\n\nend module with_forall\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-interface.d/args.ctags",
    "content": "--kinds-Fortran=+P\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-interface.d/expected.tags",
    "content": "+\tinput.f90\t/^  interface operator(+)/;\"\ti\tmodule:test_interface\n__anon502b83b10105\tinput.f90\t/^  interface ! anonymous interface$/;\"\ti\tmodule:test_interface\nadd\tinput.f90\t/^    type(atype) function add(/;\"\tP\tmodule:test_interface\natype\tinput.f90\t/^  type atype$/;\"\tt\tmodule:test_interface\nget\tinput.f90\t/^  interface get$/;\"\ti\tmodule:test_interface\nget_1d\tinput.f90\t/^  subroutine get_1d(/;\"\ts\tmodule:test_interface\nget_2d\tinput.f90\t/^  subroutine get_2d(/;\"\ts\tmodule:test_interface\nsuba\tinput.f90\t/^    subroutine suba(/;\"\tP\tinterface:__anon502b83b10105\nsubb\tinput.f90\t/^    subroutine subb(/;\"\tP\tinterface:__anon502b83b10105\ntest_interface\tinput.f90\t/^module test_interface$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-interface.d/input.f90",
    "content": "module test_interface\n  type atype\n  end type atype\n  ! operator overload\n  interface operator(+)\n    ! subprogram prototype\n    type(atype) function add(a, b)\n      import atype\n      type(atype), intent(in) :: a, b\n    end function add\n  end interface operator(+)\n  ! wrap subprogram prototypes\n  interface ! anonymous interface\n    subroutine suba()\n    end subroutine suba\n    subroutine subb()\n    end subroutine subb\n  end interface\n  ! define generic subprograms\n  interface get\n    ! subprogram name list\n    module procedure get_1d\n    module procedure get_2d\n  end interface get\ncontains\n  ! definition of subprograms\n  subroutine get_1d(a)\n    real a(:)\n  end subroutine get_1d\n  subroutine get_2d(a)\n    real a(:, :)\n  end subroutine get_2d\nend module test_interface\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-linkname.d/args.ctags",
    "content": "--sort=no\n--extras-Fortran={linkName}\n--fields=+{extras}\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-linkname.d/expected.tags",
    "content": "my_mod\tinput.f\t/^      module my_mod$/;\"\tm\n__anon9b9a88660103\tinput.f\t/^        enumerator :: my_constr = 1, my_second_constr = 4$/;\"\tE\tmodule:my_mod\textras:anonymous\nmy_constr\tinput.f\t/^        enumerator :: my_constr /;\"\tN\tenum:__anon9b9a88660103\nmy_second_constr\tinput.f\t/^        enumerator :: my_constr = 1, my_second_constr /;\"\tN\tenum:__anon9b9a88660103\nmy_type\tinput.f\t/^      type my_type$/;\"\tt\tmodule:my_mod\na\tinput.f\t/^        integer a$/;\"\tk\ttype:my_type\nb\tinput.f\t/^        integer b$/;\"\tk\ttype:my_type\nc\tinput.f\t/^        integer c$/;\"\tk\ttype:my_type\nmy_proc\tinput.f\t/^        procedure :: my_proc /;\"\tM\ttype:my_type\nmy_sequence_type\tinput.f\t/^      type my_sequence_type$/;\"\tt\tmodule:my_mod\na\tinput.f\t/^        integer a$/;\"\tk\ttype:my_sequence_type\nb\tinput.f\t/^        integer b$/;\"\tk\ttype:my_sequence_type\nmy_mod_type\tinput.f\t/^      type(my_sequence_type) :: my_mod_type$/;\"\tv\tmodule:my_mod\nmy_mod_common\tinput.f\t23;\"\tc\tmodule:my_mod\nmy_mod_common_\tinput.f\t23;\"\tc\tmodule:my_mod\textras:linkName\nmy_func\tinput.f\t/^      function my_func(/;\"\tf\tmodule:my_mod\nmy_func_\tinput.f\t/^      function my_func(x)$/;\"\tf\tmodule:my_mod\textras:linkName\nmy_block\tinput.f\t/^      block data my_block$/;\"\tb\nmy_block_\tinput.f\t/^      block data my_block$/;\"\tb\textras:linkName\nmy_var\tinput.f\t/^        integer my_var$/;\"\tv\tblockData:my_block\nmy_common\tinput.f\t40;\"\tc\tblockData:my_block\nmy_common_\tinput.f\t40;\"\tc\tblockData:my_block\textras:linkName\nmy_subr\tinput.f\t/^      subroutine my_subr$/;\"\ts\nmy_subr_\tinput.f\t/^      subroutine my_subr$/;\"\ts\textras:linkName\nmy_entry\tinput.f\t/^        entry my_entry$/;\"\te\tsubroutine:my_subr\nmy_entry_\tinput.f\t/^        entry my_entry$/;\"\te\tsubroutine:my_subr\textras:linkName\nmy_main\tinput.f\t/^      program my_main$/;\"\tp\nmy_interface\tinput.f\t/^        interface my_interface$/;\"\ti\tprogram:my_main\nmy_var\tinput.f\t/^        integer my_var$/;\"\tv\tprogram:my_main\nmy_namelist\tinput.f\t/^        namelist \\/my_namelist\\//;\"\tn\tprogram:my_main\nmy_conc_type\tinput.f\t/^        type(my_type) :: my_conc_type$/;\"\tv\tprogram:my_main\nmy_common\tinput.f\t64;\"\tc\tprogram:my_main\nmy_common_\tinput.f\t64;\"\tc\tprogram:my_main\textras:linkName\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-linkname.d/input.f",
    "content": "      module my_mod\n\n      enum, bind(c)\n        enumerator :: my_constr = 1, my_second_constr = 4\n      end enum\n\n      type my_type\n        integer a\n        integer b\n        integer c\n      contains\n        procedure :: my_proc => my_func\n      end type my_type\n\n      type my_sequence_type\n        sequence\n        integer a\n        integer b\n      end type\n\n      type(my_sequence_type) :: my_mod_type\n\n      common /my_mod_common/ my_mod_type\n\n      contains\n\n      function my_func(x)\n        class(my_type), intent(in) :: x\n        my_func = x%a\n        return\n        my_func = 2\n        return\n      end function my_func\n\n\n      end module\n\n      block data my_block\n        integer my_var\n        common /my_common/ my_var\n        data my_var/123/\n      end\n\n      subroutine my_subr\n        use my_mod\n        integer :: my_enum = my_constr\n        print *, my_enum\n        return\n        entry my_entry\n        print *, \"an entry!\"\n      end subroutine my_subr\n\n\n      program my_main\n        use my_mod\n        interface my_interface\n          subroutine my_subr()\n          end subroutine my_subr\n        end interface\n\n        integer my_var\n        namelist /my_namelist/ my_var\n        type(my_type) :: my_conc_type\n        common /my_common/ my_var\n        call my_subr()\n        print *, my_conc_type%my_proc()\n      end program my_main\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-method.d/args.ctags",
    "content": "--fields=+m\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-method.d/expected.tags",
    "content": "+\tinput.f90\t/^    generic :: operator(+)/;\"\tM\ttype:atype\n=\tinput.f90\t/^    generic :: assignment(=) =>/;\"\tM\ttype:atype\nadd\tinput.f90\t/^    generic :: add => add_/;\"\tM\ttype:atype\nadd_1d\tinput.f90\t/^    procedure, deferred :: add_1d,/;\"\tM\ttype:atype\timplementation:deferred\nadd_2d\tinput.f90\t/^    procedure, deferred :: add_1d, add_2d,/;\"\tM\ttype:atype\timplementation:deferred\nadd_3d\tinput.f90\t/^    procedure, deferred :: add_1d, add_2d, add_3d$/;\"\tM\ttype:atype\timplementation:deferred\nadd_4d\tinput.f90\t/^    procedure, non_overridable :: add_4d$/;\"\tM\ttype:atype\timplementation:non_overridable\natype\tinput.f90\t/^  type :: atype$/;\"\tt\tmodule:test_method\nclean\tinput.f90\t/^    final clean$/;\"\tM\ttype:atype\ntest_method\tinput.f90\t/^module test_method$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-method.d/input.f90",
    "content": "module test_method\n  type :: atype\n  contains\n    generic :: add => add_1d, &\n      add_2d, &\n      add_3d\n    generic :: operator(+) => add_1d, add_2d\n    generic :: assignment(=) => assigns\n    procedure, deferred :: add_1d, add_2d, add_3d\n    procedure, non_overridable :: add_4d\n    final clean\n  end type atype\nend module test_method\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-pointer.d/expected.tags",
    "content": "Main\tinput.f90\t/^program Main$/;\"\tp\nMyOtherProc\tinput.f90\t/^  MyOtherProc /;\"\tv\tmodule:Test\nMyProc\tinput.f90\t/^  procedure(ProcOne), pointer :: MyProc /;\"\tv\tmodule:Test\nProcOne\tinput.f90\t/^  function ProcOne(/;\"\tf\tmodule:Test\nProcPointOne\tinput.f90\t/^  procedure(:), pointer :: ProcPointOne /;\"\tv\tprogram:Main\nProcPointTwo\tinput.f90\t/^  => null(), ProcPointTwo /;\"\tv\tprogram:Main\nProcTwo\tinput.f90\t/^  function ProcTwo(/;\"\tf\tmodule:Test\nTest\tinput.f90\t/^module Test$/;\"\tm\nmyparameter\tinput.f90\t/^  real, parameter :: myparameter$/;\"\tv\tmodule:Test\nvariable\tinput.f90\t/^  real :: variable, variable_/;\"\tv\tprogram:Main\nvariable_three\tinput.f90\t/^  integer :: variable_three$/;\"\tv\tprogram:Main\nvariable_two\tinput.f90\t/^  real :: variable, variable_two$/;\"\tv\tprogram:Main\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-pointer.d/input.f90",
    "content": "module Test\n  implicit none\n\n  procedure(ProcOne), pointer :: MyProc => null(), &\n  MyOtherProc => ProcTwo\n  real, parameter :: myparameter\n\ncontains\n\n  function ProcOne(arg1, optformat)\n    ! not relevant\n  end function ProcOne\n\n  function ProcTwo(arg1, optformat)\n    ! not relevant\n  end function ProcTwo\n\nend module Test\n\nprogram Main\n  implicit none\n\n  ! deliberately break up the line to make sure the tagparser doesn't choke on awkward cases\n  procedure(:), pointer :: ProcPointOne &\n  => null(), ProcPointTwo => &\n  null()\n  real :: variable, variable_two\n  integer :: variable_three\n\n  ProcPointOne => ProcTwo\n\nend program Main\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-procedure-qualifiers.d/expected.tags",
    "content": "add\tinput.f90\t/^    procedure, pass :: add$/;\"\tM\ttype:atype\nappend\tinput.f90\t/^    procedure, pass(self) :: append$/;\"\tM\ttype:atype\natype\tinput.f90\t/^  type atype$/;\"\tt\tmodule:test\nlist\tinput.f90\t/^    procedure, deferred :: list$/;\"\tM\ttype:atype\nprint\tinput.f90\t/^    procedure, nopass :: print$/;\"\tM\ttype:atype\ntest\tinput.f90\t/^module test$/;\"\tm\nwrite\tinput.f90\t/^    procedure, non_overridable :: write$/;\"\tM\ttype:atype\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-procedure-qualifiers.d/input.f90",
    "content": "module test\n  type atype\n  contains\n    procedure, pass :: add\n    procedure, pass(self) :: append\n    procedure, nopass :: print\n    procedure, non_overridable :: write\n    procedure, deferred :: list\n  end type atype\nend module test\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-procedure.d/expected.tags",
    "content": "a\tinput.f90\t/^  real :: a$/;\"\tv\tmodule:proc_pointer\nmy_pointer\tinput.f90\t/^  procedure(sub), pointer :: my_pointer$/;\"\tv\tmodule:proc_pointer\nproc_pointer\tinput.f90\t/^module proc_pointer$/;\"\tm\nsub\tinput.f90\t/^  subroutine sub(/;\"\ts\tmodule:proc_pointer\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-procedure.d/input.f90",
    "content": "! a module that uses procedure pointer\nmodule proc_pointer\n\n  real :: a\n  procedure(sub), pointer :: my_pointer\n\ncontains\n\n  subroutine sub(x)\n    real, intent(inout) :: x(:)\n\n    integer :: i\n\n    do i=1,size(x)\n      x(i) = 0.5**i\n    end do\n  end subroutine sub\n\nend module proc_pointer\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-protected.d/expected.tags",
    "content": "i\tinput.f90\t/^  integer, public, protected :: i$/;\"\tv\tmodule:test_implementation\ntest_implementation\tinput.f90\t/^module test_implementation$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-protected.d/input.f90",
    "content": "module test_implementation\n  integer, public, protected :: i\nend module test_implementation\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-signature.d/args.ctags",
    "content": "--fields=+S \n--kinds-Fortran=+LP\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-signature.d/expected.tags",
    "content": "__anon06616a720105\tinput.f90\t/^  interface$/;\"\ti\tmodule:test_signature\na\tinput.f90\t/^    integer :: a$/;\"\tL\tsubroutine:fnb\tfile:\na\tinput.f90\t/^    integer a,/;\"\tL\tsubroutine:suba\tfile:\narg\tinput.f90\t/^      type(atype) :: arg$/;\"\tL\tprototype:subb\tfile:\nb\tinput.f90\t/^    integer a, b$/;\"\tL\tsubroutine:suba\tfile:\nfna\tinput.f90\t/^  real function fna(/;\"\tf\tmodule:test_signature\nfnb\tinput.f90\t/^  subroutine fnb$/;\"\ts\tmodule:test_signature\nsuba\tinput.f90\t/^  subroutine suba /;\"\ts\tmodule:test_signature\tsignature:(a, b)\nsubb\tinput.f90\t/^    subroutine subb /;\"\tP\tinterface:__anon06616a720105\tsignature:(arg)\ntest_signature\tinput.f90\t/^module test_signature$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-signature.d/input.f90",
    "content": "module test_signature\n\n  interface\n    subroutine subb (arg)\n      type(atype) :: arg\n    end subroutine\n  end interface\n  \ncontains\n  subroutine suba &\n      (a, &\n      ! comment\n    b)\n    integer a, b\n  end subroutine\n\n  real function fna()\n    use, intrinsic :: iso_c_binding\n  end function\n\n  subroutine fnb\n    integer :: a\n  end subroutine\n\nend module test_signature\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-square-parens.d/expected.tags",
    "content": "Symmetry\tinput.f90\t/^  type Symmetry$/;\"\tt\tmodule:squaretest\nassignee\tinput.f90\t/^  real, allocatable :: assignee[/;\"\tv\tmodule:squaretest\nexecute\tinput.f90\t/^  subroutine execute(/;\"\ts\tmodule:squaretest\ninvisible\tinput.f90\t/^  integer :: invisible$/;\"\tv\tmodule:squaretest\ninvisible_four\tinput.f90\t/^  integer :: invisible_four$/;\"\tv\tmodule:squaretest\ninvisible_three\tinput.f90\t/^  integer :: invisible_three$/;\"\tv\tmodule:squaretest\ninvisible_two\tinput.f90\t/^  integer :: invisible_two$/;\"\tv\tmodule:squaretest\niterations\tinput.f90\t/^    integer :: matrix(3,3), iterations$/;\"\tk\ttype:Symmetry\nmain\tinput.f90\t/^program main$/;\"\tp\nmatrix\tinput.f90\t/^    integer :: matrix(/;\"\tk\ttype:Symmetry\nsquaretest\tinput.f90\t/^module squaretest$/;\"\tm\nstate\tinput.f90\t/^  real, allocatable :: state(/;\"\tv\tmodule:squaretest\nstate_two\tinput.f90\t/^  real, intent(in), allocatable, dimension(:), codimension[:] :: state_two$/;\"\tv\tmodule:squaretest\nsymmetries\tinput.f90\t/^  type(Symmetry), parameter :: symmetries(/;\"\tv\tmodule:squaretest\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-square-parens.d/input.f90",
    "content": "module squaretest\n  implicit none\n\n  type Symmetry\n    integer :: matrix(3,3), iterations\n  end type Symmetry\n\n\n  ! make sure F2003 '[]' arrays don't break the symbol list\n  type(Symmetry), parameter :: symmetries(14) = &\n     [ Symmetry(reshape([1,0,0,  0,1,0,  0,0,1], [3,3]),1), &\n       Symmetry(reshape([1,0,0,  0,0,1,  0,-1,0],[3,3]),3), &\n       Symmetry(reshape([0,0,-1, 0,1,0,  1,0,0], [3,3]),3) ]\n  integer :: invisible\n\n  ! make sure coarray syntax doesn't break the symbol list\n  real, allocatable :: state(:)[:]\n  integer :: invisible_two\n\n  ! there are multiple ways to specify `dimension` and `codimension`\n  ! a normal dimension and a codimension\n  real, intent(in), allocatable, dimension(:), codimension[:] :: state_two\n  integer :: invisible_three\n\n  ! a 'normal' scalar (no '()'), but with a codimension '[]'\n  real, allocatable :: assignee[:]\n  integer :: invisible_four\n\ncontains\n\n  subroutine execute(state)\n    real, intent(in) :: state(:)[:]\n  end subroutine execute\n\nend module squaretest\n\nprogram main\n  use module squaretest\nend program main\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-submodule.d/README",
    "content": "x, y are tagged because the submodule statement of example_sssmod is\nbroken. Ctags makes garbage from garbage.\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-submodule.d/args.ctags",
    "content": "--sort=no\n--fields=+K{inherits}\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-submodule.d/expected.tags",
    "content": "example_smod\tinput.f90\t/^submodule (example_mod) example_smod$/;\"\tsubmodule\tinherits:example_mod\ng\tinput.f90\t/^    module function g(/;\"\tfunction\tsubmodule:example_smod\nexample_ssmod\tinput.f90\t/^submodule (example_mod:example_smod) example_ssmod$/;\"\tsubmodule\tinherits:example_mod:example_smod\ng2\tinput.f90\t/^    module function g2(/;\"\tfunction\tsubmodule:example_ssmod\nfunction\tinput.f90\t/^    module function /;\"\tmodule\nx\tinput.f90\t/^        integer :: x,/;\"\tvariable\tmodule:function\ny\tinput.f90\t/^        integer :: x,y$/;\"\tvariable\tmodule:function\n"
  },
  {
    "path": "Units/parser-fortran.r/fortran-submodule.d/input.f90",
    "content": "!\n! Derived from comment #1616 submitted by @cbcoutinho\n!\nsubmodule (example_mod) example_smod\ncontains\n    module function g(x) result(y)\n        integer :: x,y\n        y = x * 2\n    end function g\nend submodule example_smod\n\nsubmodule (example_mod:example_smod) example_ssmod\ncontains\n    module function g2(x) result(y)\n        integer :: x,y\n        y = x * 2\n    end function g2\nend submodule example_ssmod\n\nsubmodule (example_mod:example_smod:example_ssmod*broken*) example_sssmod\ncontains\n    module function g3(x) result(y)\n        integer :: x,y\n        y = x * 2\n    end function g3\nend submodule example_sssmod\n\n"
  },
  {
    "path": "Units/parser-fortran.r/implied_program.f.d/expected.tags",
    "content": "i\tinput.f\t/^\tinteger i$/;\"\tv\n"
  },
  {
    "path": "Units/parser-fortran.r/implied_program.f.d/input.f",
    "content": "C Bug reported by Brian Helinski <bjh@absoft.com> on 28 Feb 2003\n\t! implicit program main\n\tinteger i\n\ti = 5\n\twrite(*,*) i\n\tend\n"
  },
  {
    "path": "Units/parser-fortran.r/initialization.f90.d/expected.tags",
    "content": "funcon\tinput.f90\t/^      MODULE funcon$/;\"\tm\nimat\tinput.f90\t/^         imat=/;\"\tv\tmodule:funcon\nimat6\tinput.f90\t/^         imat6=/;\"\tv\tmodule:funcon\n"
  },
  {
    "path": "Units/parser-fortran.r/initialization.f90.d/input.f90",
    "content": "! Tests for correct parsing of complicated initialization\n      MODULE funcon\n      IMPLICIT NONE\n      REAL(8),DIMENSION(3,3),PARAMETER :: &\n         imat= reshape((/1.d0,0.d0,0.d0, &\n                         0.d0,1.d0,0.d0, &\n                         0.d0,0.d0,1.d0/),(/3,3/))\n      REAL(8),DIMENSION(6,6),PARAMETER :: &\n         imat6= reshape((/1.d0,0.d0,0.d0,0.d0,0.d0,0.d0, &\n                          0.d0,1.d0,0.d0,0.d0,0.d0,0.d0, &\n\t\t \t  0.d0,0.d0,1.d0,0.d0,0.d0,0.d0, &\n                          0.d0,0.d0,0.d0,1.d0,0.d0,0.d0, &\n\t\t\t  0.d0,0.d0,0.d0,0.d0,1.d0,0.d0, &\n                          0.d0,0.d0,0.d0,0.d0,0.d0,1.d0/),(/6,6/))\t\t\t \n\n      END MODULE funcon\n"
  },
  {
    "path": "Units/parser-fortran.r/invalid_name.f90.d/expected.tags",
    "content": "Activity\tinput.f90\t/^         Integer(2) :: Activity$/;\"\tk\ttype:Detection_Record\nDR_Filename\tinput.f90\t/^      Character*1024  DR_Filename$/;\"\tv\tmodule:TR_DetectionRecording\nDR_Lun\tinput.f90\t/^      Integer :: DR_Lun$/;\"\tv\tmodule:TR_DetectionRecording\nDetection_Record\tinput.f90\t/^      Type Detection_Record$/;\"\tt\tmodule:TR_DetectionRecording\nFace\tinput.f90\t/^         Integer(2) :: Face$/;\"\tk\ttype:Detection_Record\nTR_DetectionRecording\tinput.f90\t/^      Module TR_DetectionRecording$/;\"\tm\nType\tinput.f90\t/^         Integer(2) :: Type           ! \"Type\"/;\"\tk\ttype:Detection_Record\n"
  },
  {
    "path": "Units/parser-fortran.r/invalid_name.f90.d/input.f90",
    "content": "! Test of parsing type with invalid name\n      Module TR_DetectionRecording\n      Implicit None\n      Save\n      Integer :: DR_Lun\n      Character*1024  DR_Filename\n      Type Detection_Record\n         Integer(2) :: Activity\n         Integer(2) :: Type           ! \"Type\" not valid entity name\n         Integer(2) :: Face\n      End Type Detection_Record\n      End Module TR_DetectionRecording\n"
  },
  {
    "path": "Units/parser-fortran.r/lanus.for.d/expected.tags",
    "content": "FAC010\tinput.for\t/^        character*5     FAC010 /;\"\tv\nFEC010\tinput.for\t/^        character*6     FEC010 /;\"\tv\nPER010\tinput.for\t/^        character*40    PER010 /;\"\tv\nREM010\tinput.for\t/^        character*5     REM010 /;\"\tv\nURE010\tinput.for\t/^        character*5     URE010 /;\"\tv\n"
  },
  {
    "path": "Units/parser-fortran.r/lanus.for.d/input.for",
    "content": "* From jlanus@netscape.net Thu Jan 16 20:38:12 2003\n* Date: Tue, 24 Sep 2002 12:20:07 -0400\n* From: Juan Lanus <jlanus@netscape.net>\n* To: ctags-users@lists.sourceforge.net\n* Subject: [Ctags] seeking for help to set ctags to work with old FORTRAN\n* \n* Hi\n* \n* I'm trying to set ctags to work with some old FORTRAN 77 programs.\n* I'm in Windows 2000, vim 6.1 and exuberant ctags 5.3.1.\n* The programs are for VAX FORTRAN 77 as of 1988. Written with tabs and 132 columns line length.\n* \n* [...]\n* \n* What am I doing wrong? This is my first contact with tags files of any sort and I'm vexed.\n* \n* A sample .DES file is included at the bottom. \n* \n* TIA\n* \n* Juan Lanus\n* TECNOSOL\n* Argentina\n* \n* \n****************\n*********************************************************************\n*                                                                   *\n* Sistema Personalizado - descripcion de registros - CGA - 1/12/89  *\n*                                                                   *\n* De tablas generales PERTAB012 - tabla 010                         *\n*                                                                   *\n*********************************************************************\n\n        character*6     FEC010          !Fecha de Proceso aa/mm/dd\n        character*5     URE010          !Ultimo Numero de Pedido\n        character*5     REM010          !Ultimo Numero de Remito\n        character*5     FAC010          !Ultimo Numero de Factura\n\n        character*40    PER010          !Registro de Fecha\n\n        equivalence     (PER010(1:1)  ,FEC010(1:1))\n        equivalence     (PER010(7:7)  ,URE010(1:1))\n        equivalence     (PER010(12:12),REM010(1:1))\n        equivalence     (PER010(17:17),FAC010(1:1))\n\n******************  Fin Registro de Fecha  ***********************************\n"
  },
  {
    "path": "Units/parser-fortran.r/misc_types.f.d/expected.tags",
    "content": "INFOOBAR\tinput.f\t/^\tINTEGER INFOOBAR$/;\"\tv\tprogram:specs\nM\tinput.f\t/^\tINTEGER M(/;\"\tv\tprogram:specs\nspecs\tinput.f\t/^\tprogram specs$/;\"\tp\n"
  },
  {
    "path": "Units/parser-fortran.r/misc_types.f.d/input.f",
    "content": "! Provided by Brian Helsinki, 7 March 2003\n!\tcexternal\n!\tcglobal\n!\tpexternal\n!\tpglobal\n!\tinline \n!\tvirtual\n!\tvolatile\n!\tpascal\n\tprogram specs\n\n\tVIRTUAL M(10,10), Y(100) \n\tVOLATILE V, Z, MAT, /INI/ \n\n\tEXTERNAL ABS ! variations of external and global\n\tCEXTERNAL ABS1 ! not supported\n\tCGLOBAL ABS2 ! not supported\n\tPEXTERNAL ABS3 ! not supported\n$IF DEFINED(MAC_DEP)\n\tPASCAL EXTERNAL ABS3_var2 ! not supported\n$ENDIF\n\tPGLOBAL ABS4\n\t\n\tINTEGER INFOOBAR\n\tINLINE (INFOOBAR=00000) ! not supported\n\n\tINTEGER M(5)\n\tDATA M/5*0/\n\t\n\tCALL INFOOBAR(5,4)\n\tEND\n\n"
  },
  {
    "path": "Units/parser-fortran.r/misc_types.f90.d/expected.tags",
    "content": "align_second_16\tinput.f90\t/^\tinteger(2) :: align_second_16$/;\"\tk\ttype:my_struct\nbase_type\tinput.f90\t/^\tinteger base_type$/;\"\tv\tprogram:testalloc\nfirst_byte\tinput.f90\t/^\tinteger(1) :: first_byte$/;\"\tk\ttype:my_struct\ni\tinput.f90\t/^\tinteger i,/;\"\tv\tprogram:testalloc\ni2\tinput.f90\t/^\tinteger i2$/;\"\tv\tprogram:testalloc\ni3\tinput.f90\t/^\tinteger i3$/;\"\tv\tprogram:testalloc\ni4\tinput.f90\t/^\tinteger i4$/;\"\tv\tprogram:testalloc\ni5\tinput.f90\t/^\tinteger i5$/;\"\tv\tprogram:testalloc\ni6\tinput.f90\t/^\tinteger i6$/;\"\tv\tprogram:testalloc\ni7\tinput.f90\t/^\tinteger i7$/;\"\tv\tprogram:testalloc\ni8\tinput.f90\t/^\tinteger i8$/;\"\tv\tprogram:testalloc\nlist\tinput.f90\t/^\treal, dimension (:), allocatable :: list /;\"\tv\tprogram:testalloc\nmy_struct\tinput.f90\t/^\tstructure \\/my_struct\\//;\"\tt\tprogram:testalloc\nstatus\tinput.f90\t/^\tinteger i, status$/;\"\tv\tprogram:testalloc\ntestalloc\tinput.f90\t/^\tprogram testalloc$/;\"\tp\nthe_struct\tinput.f90\t/^\trecord \\/m_struct\\/ the_struct /;\"\tv\tprogram:testalloc\n"
  },
  {
    "path": "Units/parser-fortran.r/misc_types.f90.d/input.f90",
    "content": "! Provided by Brian Helsinki, 7 March 2003\n\tprogram testalloc\n\tinteger base_type\n\tautomatic foobar_var \t! automatic breaks parsing\n\tinteger i2\n\tstatic s_var\t\t! static breaks parsing\n\tinteger i3\n\tvolatile v_var\t\t! volatile breaks var parsing\n\tinteger i4\n\t\n\tDLL_IMPORT foobar2\t! break var parsing\n\tDLL_EXPORT foobar\t! breaks var parsing\n\n\tinteger i5\n        common foobar_var, s_var, v_var\n\tinteger i6\n\t\n\tstructure /my_struct/\n\tinteger(1) :: first_byte\n\tinteger(1) :: %fill\n\tinteger(2) :: align_second_16\n\tend structure\n\t\n\tinteger i7\n\t\n\trecord /m_struct/ the_struct ! break var parsing\n\tinteger i8\n\t\n\treal, dimension (:), allocatable :: list ! allocatable\n\tinteger i, status\n\t\n\t\n\ti = 99\n\tallocate (list(i), stat=status ) ! create array allocate\n\tlist (1) = 1.2\n\tdeallocate (list) \t! deallocate\n\t\n\tdo i=1,100\n\t\tj=i\n\tend do\n\tstop\n\tend\n\n"
  },
  {
    "path": "Units/parser-fortran.r/multi-input-fixed-then-free.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-fortran.r/multi-input-fixed-then-free.d/expected.tags",
    "content": "p1\tinput.f\t/^      program p1$/;\"\tp\ns\tinput.f\t/^      character*5  s$/;\"\tv\tprogram:p1\nr\tinput.f\t/^      character*5  r$/;\"\tv\tprogram:p1\ns1\tinput-0.f90\t/^subroutine s1$/;\"\ts\n"
  },
  {
    "path": "Units/parser-fortran.r/multi-input-fixed-then-free.d/input-0.f90",
    "content": "subroutine s1\nreal            :: a,b,c,d\nif (a .eq. b .and. &\n     c. eq. d) then\n   a=0\nendif\nend\n"
  },
  {
    "path": "Units/parser-fortran.r/multi-input-fixed-then-free.d/input.f",
    "content": "      program p1\n      character*5  s\nc\n      character*5  r\n      r=\"abcde\"\n      end\n"
  },
  {
    "path": "Units/parser-fortran.r/multi-input-free-then-fixed.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-fortran.r/multi-input-free-then-fixed.d/expected.tags",
    "content": "s1\tinput.f90\t/^subroutine s1$/;\"\ts\np1\tinput-0.f\t/^      program p1$/;\"\tp\ns\tinput-0.f\t/^      character*5  s$/;\"\tv\tprogram:p1\nr\tinput-0.f\t/^      character*5  r$/;\"\tv\tprogram:p1\n"
  },
  {
    "path": "Units/parser-fortran.r/multi-input-free-then-fixed.d/input-0.f",
    "content": "      program p1\n      character*5  s\nc\n      character*5  r\n      r=\"abcde\"\n      end\n"
  },
  {
    "path": "Units/parser-fortran.r/multi-input-free-then-fixed.d/input.f90",
    "content": "subroutine s1\nreal            :: a,b,c,d\nif (a .eq. b .and. &\n     c. eq. d) then\n   a=0\nendif\nend\n"
  },
  {
    "path": "Units/parser-fortran.r/namelist.f.d/expected.tags",
    "content": "main\tinput.f\t/^        PROGRAM main$/;\"\tp\nnamelist1\tinput.f\t/^        NAMELIST \\/namelist1\\//;\"\tn\tprogram:main\nnamelist2\tinput.f\t/^        NAMELIST \\/namelist2\\//;\"\tn\tprogram:main\nnamelist3\tinput.f\t/^        NAMELIST \\/namelist2\\/ n2a, n2b \\/namelist3\\//;\"\tn\tprogram:main\n"
  },
  {
    "path": "Units/parser-fortran.r/namelist.f.d/input.f",
    "content": "        PROGRAM main\n        NAMELIST /namelist1/ n1a, n1b\n        NAMELIST /namelist2/ n2a, n2b /namelist3/ n3a, n3b\n        END\n"
  },
  {
    "path": "Units/parser-fortran.r/numlib.f90.d/args.ctags",
    "content": "--kinds-Fortran=+P\n"
  },
  {
    "path": "Units/parser-fortran.r/numlib.f90.d/expected.tags",
    "content": "__anon1963f93b0305\tinput.f90\t/^      interface$/;\"\ti\tmodule:numerical_libraries\n__anon1963f93b0405\tinput.f90\t/^      interface$/;\"\ti\tprototype:b2lsf\na2ald\tinput.f90\t/^      subroutine a2ald /;\"\tP\tinterface:__anon1963f93b0305\nb2lsf\tinput.f90\t/^      subroutine b2lsf /;\"\tP\tinterface:__anon1963f93b0305\nfcn\tinput.f90\t/^         subroutine fcn(/;\"\tP\tinterface:__anon1963f93b0405\nnumerical_libraries\tinput.f90\t/^      module numerical_libraries$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fortran.r/numlib.f90.d/input.f90",
    "content": "! Bug reported by Brian Helinski <bjh@absoft.com> on 4 Feb 2003\n      module numerical_libraries\n      interface\n      \n      subroutine a2ald (nf, nl, y, nrf, indrf, nef, nfef, indef, conper, iprint&\n         , model, aov, ems, vc, ldvc, ymeans, wk, iwk, c13ksp) \n      integer, intent(in) :: nf \n      integer, dimension(*), intent(in) :: nl \n      real(kind(1e0)), dimension(*) :: y \n      integer, intent(in) :: nrf \n      integer, dimension(*), intent(in) :: indrf \n      integer, intent(in) :: nef \n      integer, dimension(*), intent(in) :: nfef \n      integer, dimension(*), intent(in) :: indef \n      real(kind(1e0)), intent(in) :: conper \n      integer, intent(in) :: iprint \n      integer, intent(in) :: model \n      real(kind(1e0)), dimension(*), intent(in) :: aov \n      real(kind(1e0)), dimension(*), intent(inout) :: ems \n      real(kind(1e0)), dimension(ldvc,*), intent(inout) :: vc \n      integer, intent(in) :: ldvc \n      real(kind(1e0)), dimension(*), intent(in) :: ymeans \n      real(kind(1e0)), dimension(*), intent(inout) :: wk \n      integer, dimension(*), intent(in) :: iwk \n      character (len = 13), dimension(*), intent(out) :: c13ksp \n      end subroutine  \n\n      \n      subroutine b2lsf (fcn, m, n, xguess, ibtype, xlb, xub, xscale, fscale&\n         , iparam, rparam, x, fvec, fjac, ldfjac, wk, iwk) \n      integer, intent(in) :: m \n      integer, intent(in) :: n \n      real(kind(1e0)), dimension(*) :: xguess \n      integer, intent(in) :: ibtype \n      real(kind(1e0)), dimension(*), intent(inout) :: xlb \n      real(kind(1e0)), dimension(*), intent(inout) :: xub \n      real(kind(1e0)), dimension(*) :: xscale \n      real(kind(1e0)), dimension(*) :: fscale \n      integer, dimension(*) :: iparam \n      real(kind(1e0)), dimension(*) :: rparam \n      real(kind(1e0)), dimension(*) :: x \n      real(kind(1e0)), dimension(*) :: fvec \n      real(kind(1e0)), dimension(*) :: fjac \n      integer, intent(in) :: ldfjac \n      real(kind(1e0)), dimension(*) :: wk \n      integer, dimension(*) :: iwk \n      interface\n         subroutine fcn(m, n, x, f)\n         integer, intent(in) :: m, n\n         real(kind(1e0)), intent(in) :: x(*)\n         real(kind(1e0)), intent(out) :: f(*)\n         end subroutine\n      end interface\n      end subroutine\n       \n      END INTERFACE \n      end module\n"
  },
  {
    "path": "Units/parser-fortran.r/pure_elem.f95.d/README",
    "content": "This test has the truncation issue #333.\n"
  },
  {
    "path": "Units/parser-fortran.r/pure_elem.f95.d/expected.tags",
    "content": "F\tinput.f95\t/^\tPURE REAL FUNCTION F(x,y) ! pure broken returns 'PURE REAL FU/;\"\tf\nelem_maxabs\tinput.f95\t/^\tELEMENTAL REAL FUNCTION elem_maxabs(/;\"\tf\npure_func\tinput.f95\t/^\tPURE REAL FUNCTION pure_func(/;\"\tf\npure_maxabs2\tinput.f95\t/^\tPURE REAL FUNCTION pure_maxabs2(/;\"\tf\n"
  },
  {
    "path": "Units/parser-fortran.r/pure_elem.f95.d/input.f95",
    "content": "!\telemental\n!\n!Pure procedures are procedures declared with the PURE keyword and which \n!satisfy certain constraints that ensure they have no side \n!effects. They can be used in specification expressions and \n!within FORALL constructs and statements. \n\n!Elemental procedures can be written in Fortran 95 using the ELEMENTAL \n!keyword. Elemental procedures are automatically ``pure''. \n\n!Example: \n\n\tPURE REAL FUNCTION pure_func(x,y) ! pure okay\n\t\tIMPLICIT NONE\n\t\tREAL, INTENT(IN) ::  x, y\n\t\tpure_func = x*x + y*y + 2*x*y + ASIN(MIN(x/y,y/x))\n\tEND FUNCTION pure_func\n\n\tPURE REAL FUNCTION F(x,y) ! pure broken returns 'PURE REAL FU'\n\t\tIMPLICIT NONE\n\t\tREAL, INTENT(IN) ::  x, y\n\t\tF = x*x + y*y + 2*x*y + ASIN(MIN(x/y,y/x))\n\tEND FUNCTION F\n\n\n\tELEMENTAL REAL FUNCTION elem_maxabs(a,b) ! elemental broke\n\t\tIMPLICIT NONE\n\t\tREAL,INTENT(IN) :: a,b\n\t\telem_maxabs = MAX(ABS(a),ABS(b))\n\tEND\n\n\tPURE REAL FUNCTION pure_maxabs2(a,b) ! pure okay\n\t\tIMPLICIT NONE\n\t\tREAL,INTENT(IN) :: a,b\n\t\tpure_maxabs2 = MAX(ABS(a),ABS(b))\n\tEND\n\n"
  },
  {
    "path": "Units/parser-fortran.r/recursive.f95.d/args.ctags",
    "content": "--kinds-Fortran=+P\n"
  },
  {
    "path": "Units/parser-fortran.r/recursive.f95.d/expected.tags",
    "content": "__anon8fb642160105\tinput.f95\t/^\t\t$/;\"\ti\tmodule:approx\n__anon8fb642160205\tinput.f95\t/^\t$/;\"\ti\tmodule:approx2\napprox\tinput.f95\t/^\tMODULE approx$/;\"\tm\napprox2\tinput.f95\t/^\tMODULE approx2$/;\"\tm\narcsin\tinput.f95\t/^\trecursive function arcsin /;\"\tP\tinterface:__anon8fb642160105\narcsin1\tinput.f95\t/^\trecursive function arcsin1 /;\"\tP\tinterface:__anon8fb642160105\narcsin2\tinput.f95\t/^\tdouble precision recursive function arcsin2 /;\"\tP\tinterface:__anon8fb642160105\narcsin3\tinput.f95\t/^\trecursive double precision function arcsin3 /;\"\tP\tinterface:__anon8fb642160105\nas\tinput.f95\t/^\tdouble precision recursive function as /;\"\tP\tinterface:__anon8fb642160205\nas1\tinput.f95\t/^\trecursive double precision function as1 /;\"\tP\tinterface:__anon8fb642160205\nas2\tinput.f95\t/^\trecursive function as2 /;\"\tP\tinterface:__anon8fb642160205\nas3\tinput.f95\t/^\trecursive function as3 /;\"\tP\tinterface:__anon8fb642160205\nparts\tinput.f95\t/^\tinteger :: parts$/;\"\tv\tmodule:approx\nparts2\tinput.f95\t/^\tinteger :: parts2$/;\"\tv\tmodule:approx2\ny\tinput.f95\t/^\tdouble precision :: y$/;\"\tv\tmodule:approx\nz\tinput.f95\t/^\tdouble precision :: z$/;\"\tv\tmodule:approx2\n"
  },
  {
    "path": "Units/parser-fortran.r/recursive.f95.d/input.f95",
    "content": "!\tresult/recursive broken\n\tMODULE approx\n\tinterface\n\t\t\n\trecursive function arcsin (angle, terms) ! no result keyword\n\t\tdouble precision arcsin1\n\t\tdouble precision angle\n\t\tinteger terms\n\tend function arcsin\n\t\t\n\trecursive function arcsin1 (angle, terms) result (value) ! no explicit type\n\t\tdouble precision angle\n\t\tinteger terms\n\t\tdouble precision value\n\tend function arcsin1\n\t\n\tdouble precision recursive function arcsin2 (angle, terms) result (value) ! type + recurs\n\t\tdouble precision angle\n\t\tinteger terms\n\tend function arcsin2\n\t\t\t\n\t\t\t\n\t! only this function seems to be found\n\trecursive double precision function arcsin3 (angle, terms) result (value ) ! recurs + type\n\t\tdouble precision angle\n\t\tinteger terms\n\tend function arcsin3\n\t\n\t\t\n\tend interface\n\tdouble precision :: y\n\tinteger :: parts\n\tEND MODULE\n\n\n\tMODULE approx2\n\tinterface\n\t\n\tdouble precision recursive function as (angle, terms) result (value) ! type + recurs\n\t\tdouble precision angle\n\t\tinteger terms\n\tend function as\n\t\t\t\n\trecursive double precision function as1 (angle, terms) result (value ) ! recurs + type\n\t\tdouble precision angle\n\t\tinteger terms\n\tend function as1\n\t\n\t! but now I can see this one \n\trecursive function as2 (angle, terms) ! no result keyword\n\t\tdouble precision arcsin1\n\t\tdouble precision angle\n\t\tinteger terms\n\tend function as2\n\t\t\n\t! .. and this one!\n\trecursive function as3 (angle, terms) result (value) ! no explicit type\n\t\tdouble precision angle\n\t\tinteger terms\n\t\tdouble precision value\n\tend function as3\n\t\n\t\t\n\tend interface\n\tdouble precision :: z\n\tinteger :: parts2\n\tEND MODULE\n\n"
  },
  {
    "path": "Units/parser-fortran.r/reset-newline-state.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-fortran.r/reset-newline-state.d/expected.tags",
    "content": "mod1\tinput-1.f90\t/^  MODULE mod1$/;\"\tm\nvar1\tinput-1.f90\t/^     integer :: var1$/;\"\tv\tmodule:mod1\nmod2\tinput-2.f90\t/^  MODULE mod2$/;\"\tm\nvar2\tinput-2.f90\t/^     integer :: var2$/;\"\tv\tmodule:mod2\n"
  },
  {
    "path": "Units/parser-fortran.r/reset-newline-state.d/input-1.f90",
    "content": "#include \"in.fpp\"\n\n  MODULE mod1\n     implicit none\n     integer :: var1\n  END MODULE mod1\n"
  },
  {
    "path": "Units/parser-fortran.r/reset-newline-state.d/input-2.f90",
    "content": "#include \"in.fpp\"\n\n  MODULE mod2\n     implicit none\n     integer :: var2\n  END MODULE\n"
  },
  {
    "path": "Units/parser-fortran.r/reset-newline-state.d/input.f90",
    "content": "  ! Dummy file\n"
  },
  {
    "path": "Units/parser-fortran.r/semicolon.f90.d/expected.tags",
    "content": "SEMI\tinput.f90\t/^      MODULE SEMI$/;\"\tm\nVAR1\tinput.f90\t/^      INTEGER (4) :: VAR1;/;\"\tv\tmodule:SEMI\nVAR2\tinput.f90\t/^      INTEGER (4) :: VAR1; INTEGER (4) VAR2$/;\"\tv\tmodule:SEMI\n"
  },
  {
    "path": "Units/parser-fortran.r/semicolon.f90.d/input.f90",
    "content": "      MODULE SEMI\n      \n      INTEGER (4) :: VAR1; INTEGER (4) VAR2\n\n      END MODULE SEMI\n"
  },
  {
    "path": "Units/parser-fortran.r/stdcall.f.d/expected.tags",
    "content": "20\tinput.f\t/^   20 CONTINUE$/;\"\tl\tfile:\n40\tinput.f\t/^   40 CONTINUE$/;\"\tl\tfile:\n60\tinput.f\t/^   60 CONTINUE$/;\"\tl\tfile:\n80\tinput.f\t/^   80 CONTINUE$/;\"\tl\tfile:\n99996\tinput.f\t/^99996 FORMAT (1X,F8.2,3F13.5)$/;\"\tl\tfile:\n99997\tinput.f\t/^99997 FORMAT (1X,A,3F13.5)$/;\"\tl\tfile:\n99998\tinput.f\t/^99998 FORMAT (1X,A,F7.3)$/;\"\tl\tfile:\n99999\tinput.f\t/^99999 FORMAT (1X,A,D8.1)$/;\"\tl\tfile:\n99999\tinput.f\t/^99999 FORMAT (1X,F8.2,3F13.5)$/;\"\tl\tsubroutine:OUT\tfile:\nD02CJW\tinput.f\t/^      DOUBLE PRECISION D02CJW,/;\"\tv\nFCN\tinput.f\t/^      STDCALL SUBROUTINE FCN(/;\"\ts\nG\tinput.f\t/^      DOUBLE PRECISION D02CJW, G,/;\"\tv\nG\tinput.f\t/^      STDCALL DOUBLE PRECISION FUNCTION G(T,Y)                          !CHANGE/;\"\tf\nH\tinput.f\t/^      DOUBLE PRECISION H,/;\"\tv\nI\tinput.f\t/^      INTEGER          I, IFAIL/;\"\tv\nIFAIL\tinput.f\t/^      INTEGER          I, IFAIL,/;\"\tv\nIW\tinput.f\t/^      INTEGER          N, IW$/;\"\tv\nJ\tinput.f\t/^      INTEGER          I, IFAIL, J$/;\"\tv\nK\tinput.f\t/^      INTEGER          K$/;\"\tv\nN\tinput.f\t/^      INTEGER          N,/;\"\tv\nNOUT\tinput.f\t/^      INTEGER          NOUT$/;\"\tv\nOUT\tinput.f\t/^      STDCALL SUBROUTINE OUT(/;\"\ts\nPI\tinput.f\t/^      DOUBLE PRECISION PI,/;\"\tv\nRELABS\tinput.f\t/^      CHARACTER        RELABS*/;\"\tv\nTOL\tinput.f\t/^      DOUBLE PRECISION PI, TOL,/;\"\tv\nW\tinput.f\t/^      DOUBLE PRECISION W(IW)/;\"\tv\nX\tinput.f\t/^      DOUBLE PRECISION PI, TOL, X$/;\"\tv\nX01AAF\tinput.f\t/^      DOUBLE PRECISION D02CJW, G, X01AAF$/;\"\tv\nXEND\tinput.f\t/^      DOUBLE PRECISION H, XEND$/;\"\tv\nY\tinput.f\t/^      DOUBLE PRECISION W(IW), Y(/;\"\tv\n"
  },
  {
    "path": "Units/parser-fortran.r/stdcall.f.d/input.f",
    "content": "* Obtained from http://www.nag.com/local/nagping/np006a3.asp\n*     D02CJF Example Program Text\n*     Mark 14 Revised.  NAG Copyright 1989.\n*     .. Parameters ..\n      CHARACTER        RELABS*15                                        !NEW\n      INTEGER          NOUT\n      PARAMETER        (NOUT=6)\n      INTEGER          N, IW\n      PARAMETER        (N=3,IW=21*N+28)\n*     .. Scalars in Common ..\n      DOUBLE PRECISION H, XEND\n      INTEGER          K\n*     .. Local Scalars ..\n      DOUBLE PRECISION PI, TOL, X\n      INTEGER          I, IFAIL, J\n*     .. Local Arrays ..\n      DOUBLE PRECISION W(IW), Y(N)\n*     .. External Functions ..\n      DOUBLE PRECISION D02CJW, G, X01AAF\n      STDCALL EXTERNAL D02CJW, G, X01AAF                                !CHANGE\n*     .. External Subroutines ..\n      STDCALL EXTERNAL D02CJF, D02CJX, FCN, OUT                         !CHANGE\n*     .. Intrinsic Functions ..\n      INTRINSIC        DBLE\n*     .. Common blocks ..\n      COMMON           XEND, H, K\n*     .. Executable Statements ..\n      WRITE (NOUT,*) 'D02CJF Example Program Results'\n      RELABS = \"Default\"                                                !NEW\n      XEND = 10.0D0\n      PI = X01AAF(0.0D0)\n      WRITE (NOUT,*)\n      WRITE (NOUT,*) 'Case 1: intermediate output, root-finding'\n      DO 20 J = 4, 5\n         TOL = 10.0D0**(-J)\n         WRITE (NOUT,*)\n         WRITE (NOUT,99999) ' Calculation with TOL =', TOL\n         X = 0.0D0\n         Y(1) = 0.5D0\n         Y(2) = 0.5D0\n         Y(3) = PI/5.0D0\n         K = 4\n         H = (XEND-X)/DBLE(K+1)\n         WRITE (NOUT,*) '     X         Y(1)         Y(2)         Y(3)'\n         IFAIL = 0\n*\n         CALL D02CJF(X,XEND,N,Y,FCN,TOL,VAL(LOC(RELABS)),VAL(7),OUT,G,W,!CHANGE\n     +               IFAIL)\n*\n         WRITE (NOUT,99998) '  Root of Y(1) = 0.0 at', X\n         WRITE (NOUT,99997) '  Solution is', (Y(I),I=1,N)\n   20 CONTINUE\n      WRITE (NOUT,*)\n      WRITE (NOUT,*)\n      WRITE (NOUT,*) 'Case 2: no intermediate output, root-finding'\n      DO 40 J = 4, 5\n         TOL = 10.0D0**(-J)\n         WRITE (NOUT,*)\n         WRITE (NOUT,99999) ' Calculation with TOL =', TOL\n         X = 0.0D0\n         Y(1) = 0.5D0\n         Y(2) = 0.5D0\n         Y(3) = PI/5.0D0\n         IFAIL = 0\n*\n         CALL D02CJF(X,XEND,N,Y,FCN,TOL,VAL(LOC(RELABS)),VAL(7),D02CJX, !CHANGE\n     +               G,W,IFAIL)\n*\n         WRITE (NOUT,99998) '  Root of Y(1) = 0.0 at', X\n         WRITE (NOUT,99997) '  Solution is', (Y(I),I=1,N)\n   40 CONTINUE\n      WRITE (NOUT,*)\n      WRITE (NOUT,*)\n      WRITE (NOUT,*) 'Case 3: intermediate output, no root-finding'\n      DO 60 J = 4, 5\n         TOL = 10.0D0**(-J)\n         WRITE (NOUT,*)\n         WRITE (NOUT,99999) ' Calculation with TOL =', TOL\n         X = 0.0D0\n         Y(1) = 0.5D0\n         Y(2) = 0.5D0\n         Y(3) = PI/5.0D0\n         K = 4\n         H = (XEND-X)/DBLE(K+1)\n         WRITE (NOUT,*) '     X         Y(1)         Y(2)         Y(3)'\n         IFAIL = 0\n*\n         CALL D02CJF(X,XEND,N,Y,FCN,TOL,VAL(LOC(RELABS)),VAL(7),OUT,    CHANGE\n     +               D02CJW,W,IFAIL)\n*\n   60 CONTINUE\n      WRITE (NOUT,*)\n      WRITE (NOUT,*)\n      WRITE (NOUT,*)\n     +'Case 4: no intermediate output, no root-finding ( integrate to XE\n     +ND)'\n      DO 80 J = 4, 5\n         TOL = 10.0D0**(-J)\n         WRITE (NOUT,*)\n         WRITE (NOUT,99999) ' Calculation with TOL =', TOL\n         X = 0.0D0\n         Y(1) = 0.5D0\n         Y(2) = 0.5D0\n         Y(3) = PI/5.0D0\n         WRITE (NOUT,*) '     X         Y(1)         Y(2)         Y(3)'\n         WRITE (NOUT,99996) X, (Y(I),I=1,N)\n         IFAIL = 0\n*\n         CALL D02CJF(X,XEND,N,Y,FCN,TOL,VAL(LOC(RELABS)),VAL(7),D02CJX, !CHANGE\n     +               D02CJW,W,IFAIL)\n*\n         WRITE (NOUT,99996) X, (Y(I),I=1,N)\n   80 CONTINUE\n      STOP\n*\n99999 FORMAT (1X,A,D8.1)\n99998 FORMAT (1X,A,F7.3)\n99997 FORMAT (1X,A,3F13.5)\n99996 FORMAT (1X,F8.2,3F13.5)\n      END\n*\n      STDCALL SUBROUTINE OUT(X,Y)                                       !CHANGE\n*     .. Parameters ..\n      INTEGER        NOUT\n      PARAMETER      (NOUT=6)\n      INTEGER        N\n      PARAMETER      (N=3)\n*     .. Scalar Arguments ..\n      DOUBLE PRECISION X\n*     .. Array Arguments ..\n      DOUBLE PRECISION Y(N)\n*     .. Scalars in Common ..\n      DOUBLE PRECISION H, XEND\n      INTEGER        I\n*     .. Local Scalars ..\n      INTEGER        J\n*     .. Intrinsic Functions ..\n      INTRINSIC      DBLE\n*     .. Common blocks ..\n      COMMON         XEND, H, I\n*     .. Executable Statements ..\n      WRITE (NOUT,99999) X, (Y(J),J=1,N)\n      X = XEND - DBLE(I)*H\n      I = I - 1\n      RETURN\n*\n99999 FORMAT (1X,F8.2,3F13.5)\n      END\n*\n      STDCALL SUBROUTINE FCN(T,Y,F)                                     !CHANGE\n*     .. Parameters ..\n      INTEGER        N\n      PARAMETER      (N=3)\n*     .. Scalar Arguments ..\n      DOUBLE PRECISION T\n*     .. Array Arguments ..\n      DOUBLE PRECISION F(N), Y(N)\n*     .. Intrinsic Functions ..\n      INTRINSIC      COS, TAN\n*     .. Executable Statements ..\n      F(1) = TAN(Y(3))\n      F(2) = -0.032D0*TAN(Y(3))/Y(2) - 0.02D0*Y(2)/COS(Y(3))\n      F(3) = -0.032D0/Y(2)**2\n      RETURN\n      END\n*\n      STDCALL DOUBLE PRECISION FUNCTION G(T,Y)                          !CHANGE\n*     .. Parameters ..\n      INTEGER                     N\n      PARAMETER                   (N=3)\n*     .. Scalar Arguments ..\n      DOUBLE PRECISION            T\n*     .. Array Arguments ..\n      DOUBLE PRECISION            Y(N)\n*     .. Executable Statements ..\n      G = Y(1)\n      RETURN\n      END\n"
  },
  {
    "path": "Units/parser-fortran.r/structure.f.d/expected.tags",
    "content": "__anon76fabc930106\tinput.f\t/^                structure level3a, level3b$/;\"\tt\ttype:nested\na\tinput.f\t/^                    integer a$/;\"\tk\ttype:__anon76fabc930106\nclouds\tinput.f\t/^                character*20  clouds /;\"\tk\ttype:weather\nclouds\tinput.f\t/^        character*20   clouds$/;\"\tk\ttype:weather\nday\tinput.f\t/^                integer*1     month \\/08\\/, day /;\"\tk\ttype:weather\nday\tinput.f\t/^        integer        month, day,/;\"\tk\ttype:weather\ninitialized_structure\tinput.f\t/^        program initialized_structure$/;\"\tp\nlatest\tinput.f\t/^        record \\/weather\\/ latest$/;\"\tv\tprogram:initialized_structure\nlatest\tinput.f\t/^        record \\/weather\\/ latest$/;\"\tv\tprogram:uninitialized_structure\nlevel2\tinput.f\t/^            structure \\/nested\\/ level2$/;\"\tk\ttype:top\nlevel3a\tinput.f\t/^                structure level3a,/;\"\tk\ttype:nested\nlevel3b\tinput.f\t/^                structure level3a, level3b$/;\"\tk\ttype:nested\nmonth\tinput.f\t/^                integer*1     month /;\"\tk\ttype:weather\nmonth\tinput.f\t/^        integer        month,/;\"\tk\ttype:weather\nnested\tinput.f\t/^            structure \\/nested\\//;\"\tt\ttype:top\nnested_structure\tinput.f\t/^        program nested_structure$/;\"\tp\nrainfall\tinput.f\t/^                real   rainfall /;\"\tk\ttype:weather\nrainfall\tinput.f\t/^        real           rainfall$/;\"\tk\ttype:weather\ntop\tinput.f\t/^        structure \\/top\\//;\"\tt\tprogram:nested_structure\nuninitialized_structure\tinput.f\t/^        program uninitialized_structure$/;\"\tp\nweather\tinput.f\t/^        structure \\/weather\\//;\"\tt\tprogram:initialized_structure\nweather\tinput.f\t/^        structure \\/weather\\//;\"\tt\tprogram:uninitialized_structure\nyear\tinput.f\t/^                integer*1     month \\/08\\/, day \\/10\\/, year /;\"\tk\ttype:weather\nyear\tinput.f\t/^        integer        month, day, year$/;\"\tk\ttype:weather\n"
  },
  {
    "path": "Units/parser-fortran.r/structure.f.d/input.f",
    "content": "        program uninitialized_structure\n        structure /weather/\n        integer        month, day, year\n        character*20   clouds\n        real           rainfall\n        end structure\n        record /weather/ latest\n        end\n\n        program initialized_structure\n        structure /weather/\n                integer*1     month /08/, day /10/, year /89/\n                character*20  clouds /' overcast'/\n                real   rainfall /3.12/\n        end structure\n        record /weather/ latest\n        print *, latest.month, latest.day, latest.year, \n      + latest.clouds, latest.rainfall\n        end program\n\n        program nested_structure\n        structure /top/\n            structure /nested/ level2\n                structure level3a, level3b\n                    integer a\n                end structure\n            end structure\n        end structure\n        end program\n"
  },
  {
    "path": "Units/parser-fortran.r/union.f.d/expected.tags",
    "content": "10\tinput.f\t/^10      format (a)$/;\"\tl\tprogram:writedate\tfile:\ndate\tinput.f\t/^                    character*6 date$/;\"\tk\ttype:start\nday\tinput.f\t/^                    character*2 day$/;\"\tk\ttype:start\nmonth\tinput.f\t/^                    character*2 month$/;\"\tk\ttype:start\nsdate\tinput.f\t/^        record \\/start\\/ sdate$/;\"\tv\tprogram:writedate\nstart\tinput.f\t/^        structure \\/start\\//;\"\tt\tprogram:writedate\nwritedate\tinput.f\t/^        program writedate$/;\"\tp\nyear\tinput.f\t/^                    character*2 year$/;\"\tk\ttype:start\n"
  },
  {
    "path": "Units/parser-fortran.r/union.f.d/input.f",
    "content": "        program writedate\n        structure /start/\n            union\n                map\n                    character*2 month\n                    character*2 day\n                    character*2 year\n                end map\n                map\n                    character*6 date\n                end map\n            end union\n        end structure\n        record /start/ sdate\n        sdate.month = '08'\n        sdate.day =   '10'\n        sdate.year =  '89'\n        write (*, 10) sdate.date\n10      format (a)\n        stop\n        end\n"
  },
  {
    "path": "Units/parser-fortran.r/value.f.d/expected.tags",
    "content": "aa\tinput.f\t/^\tREAL aa$/;\"\tv\tprogram:figure\nfig\tinput.f\t/^\tinteger fig$/;\"\tv\tprogram:figure\nfigure\tinput.f\t/^\tprogram figure(/;\"\tp\n"
  },
  {
    "path": "Units/parser-fortran.r/value.f.d/input.f",
    "content": "! Provided by Brian Helsinki, 7 March 2003\n\tprogram figure(aa)\n\tREAL aa\n\tVALUE aa ! not supported breaks fig; pass by value\n\tinteger fig\n\tcall fig2(aa)\n\tRETURN\n\tEND\t\n\n"
  },
  {
    "path": "Units/parser-function-parameters.r/perl-fp-test.d/expected.tags",
    "content": "Jim::Butler\tinput.pl\t/^package Jim::Butler;$/;\"\tp\nmy_function\tinput.pl\t/^fun my_function() {}$/;\"\tf\nmy_method\tinput.pl\t/^method my_method() {}$/;\"\tm\nmy_subroutine\tinput.pl\t/^sub my_subroutine {}$/;\"\ts\n"
  },
  {
    "path": "Units/parser-function-parameters.r/perl-fp-test.d/input.pl",
    "content": "package Jim::Butler;\n\nuse Function::Parameters;\n\nmethod my_method() {}\n\nfun my_function() {}\n\nsub my_subroutine {}\n\n1;"
  },
  {
    "path": "Units/parser-function-parameters.r/simple.d/args.ctags",
    "content": "--sort=no\n--fields=+lK\n"
  },
  {
    "path": "Units/parser-function-parameters.r/simple.d/expected.tags",
    "content": "foo\tinput.pl\t/^fun foo($x, $y, $z = 5) {$/;\"\tfun\tlanguage:FunctionParameters\nbar\tinput.pl\t/^method bar($label, $n) {$/;\"\tmethod\tlanguage:FunctionParameters\ncreate_point\tinput.pl\t/^fun create_point(:$x, :$y, :$color) {$/;\"\tfun\tlanguage:FunctionParameters\nDerived\tinput.pl\t/^package Derived {$/;\"\tpackage\tlanguage:Perl\nDerived\tinput.pl\t/^package Derived {$/;\"\tclass\tlanguage:Moose\ngo_big\tinput.pl\t/^    has 'go_big' => ($/;\"\tattribute\tlanguage:Moose\tclass:Derived\nsize\tinput.pl\t/^    around size($x, $y) {$/;\"\twrapper\tlanguage:Moose\tclass:Derived\twrapping:around\nDerived0\tinput-0.pl\t/^package Derived0 {$/;\"\tpackage\tlanguage:Perl\nDerived0\tinput-0.pl\t/^package Derived0 {$/;\"\tclass\tlanguage:Moose\ngo_big0\tinput-0.pl\t/^    has 'go_big0' => ($/;\"\tattribute\tlanguage:Moose\tclass:Derived0\n"
  },
  {
    "path": "Units/parser-function-parameters.r/simple.d/input-0.pl",
    "content": "package Derived0 {\n    use Function::Parameters qw(\n\t:std\n\t);\n    use Moo;\n\n    extends 'Base';\n\n    has 'go_big0' => (\n\tis => 'ro',\n    );\n\n    # \"around\" method with implicit $orig and $self\n    around size0_dont_capture_me() {\n\treturn $self->$orig() * 2 if $self->go_big;\n\treturn $self->$orig();\n    }\n}\n"
  },
  {
    "path": "Units/parser-function-parameters.r/simple.d/input.pl",
    "content": "# Taken from https://metacpan.org/pod/Function::Parameters\nuse Function::Parameters;\n \n# plain function\nfun foo($x, $y, $z = 5) {\n    return $x + $y + $z;\n}\nprint foo(1, 2), \"\\n\";  # 8\n \n# method with implicit $self\nmethod bar($label, $n) {\n    return \"$label: \" . ($n * $self->scale);\n}\n \n# named arguments: order doesn't matter in the call\nfun create_point(:$x, :$y, :$color) {\n    print \"creating a $color point at ($x, $y)\\n\";\n}\ncreate_point(\n    color => \"red\",\n    x     => 10,\n    y     => 5,\n);\n \npackage Derived {\n    use Function::Parameters qw(\n\t:std\n\t:modifiers\n\t);\n    use Moo;\n \n    extends 'Base';\n \n    has 'go_big' => (\n        is => 'ro',\n    );\n \n    # \"around\" method with implicit $orig and $self\n    around size($x, $y) {\n        return $self->$orig() * 2 if $self->go_big;\n        return $self->$orig();\n    }\n}\n"
  },
  {
    "path": "Units/parser-fypp.r/cont.d/args.ctags",
    "content": "--extras=+g\n"
  },
  {
    "path": "Units/parser-fypp.r/cont.d/expected.tags",
    "content": "helloworld\tinput.fy\t/^program helloworld$/;\"\tp\n"
  },
  {
    "path": "Units/parser-fypp.r/cont.d/input.fy",
    "content": "#! Taken from https://fypp.readthedocs.io/en/stable/fypp.html#preprocessor-language\n@:assertEqual(size(coords, dim=2), &\n    & size(atomtypes))\nprogram helloworld\nprint *, \"Hello, world.\"\nend program helloworld\n"
  },
  {
    "path": "Units/parser-fypp.r/emptyline.d/README",
    "content": "input.fy caused a valgrind error.\n\nFor running this test:\n\n   $ make units LANGUAGES=Fypp VG=1\n"
  },
  {
    "path": "Units/parser-fypp.r/emptyline.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-fypp.r/emptyline.d/input.fy",
    "content": "#:for ind in range(repeat)\n\n#:endfor\n"
  },
  {
    "path": "Units/parser-fypp.r/first-if-area.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n"
  },
  {
    "path": "Units/parser-fypp.r/first-if-area.d/expected.tags",
    "content": "STRU\tinput.fy\t/^STRUCTURE \\/STRU\\//;\"\tt\nX\tinput.fy\t/^\tINTEGER*4 X$/;\"\tk\ttype:STRU\nA0\tinput.fy\t/^\tINTEGER*4 A0$/;\"\tk\ttype:STRU\nB0\tinput.fy\t/^\tINTEGER*4 B0$/;\"\tk\ttype:STRU\nC\tinput.fy\t/^\tINTEGER*4 C$/;\"\tk\ttype:STRU\nB1\tinput.fy\t/^\tINTEGER*4 B1$/;\"\tk\ttype:STRU\nA1\tinput.fy\t/^\tINTEGER*4 A1$/;\"\tk\ttype:STRU\nY\tinput.fy\t/^\tINTEGER*4 Y$/;\"\tk\ttype:STRU\n"
  },
  {
    "path": "Units/parser-fypp.r/first-if-area.d/input.fy",
    "content": "#! Taken from https://github.com/aradi/fypp\nSTRUCTURE /STRU/\n\tINTEGER*4 X\n#:if cA > 0\n\tINTEGER*4 A0\n#:if cB > 0\n\tINTEGER*4 B0\n#:if cC > 0\n\tINTEGER*4 C\n#:elif cCELIF > 0\n\tINTEGER*4 CELIF\n#:else\n\tINTEGER*4 CELSE\n#:endif\n\tINTEGER*4 B1\n#:elif cBELIF > 0\n\tINTEGER*4 BELIF\n#:else\n\tINTEGER*4 BELSE\n#:endif\n\tINTEGER*4 A1\n#:elif cAELIF > 0\n\tINTEGER*4 AELIF\n#:else\n\tINTEGER*4 AELSE\n#:endif\n\tINTEGER*4 Y\nEND STRUCTURE\n"
  },
  {
    "path": "Units/parser-fypp.r/if-cont.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n"
  },
  {
    "path": "Units/parser-fypp.r/if-cont.d/expected.tags",
    "content": "STRU\tinput.fy\t/^STRUCTURE \\/STRU\\//;\"\tt\nX\tinput.fy\t/^\tINTEGER*4 X$/;\"\tk\ttype:STRU\nA0\tinput.fy\t/^\tINTEGER*4 A0$/;\"\tk\ttype:STRU\nB0\tinput.fy\t/^\tINTEGER*4 B0$/;\"\tk\ttype:STRU\nC\tinput.fy\t/^\tINTEGER*4 C$/;\"\tk\ttype:STRU\nB1\tinput.fy\t/^\tINTEGER*4 B1$/;\"\tk\ttype:STRU\nA1\tinput.fy\t/^\tINTEGER*4 A1$/;\"\tk\ttype:STRU\nY\tinput.fy\t/^\tINTEGER*4 Y$/;\"\tk\ttype:STRU\n"
  },
  {
    "path": "Units/parser-fypp.r/if-cont.d/input.fy",
    "content": "STRUCTURE /STRU/\n\tINTEGER*4 X\n#:if cA > 0 &\n     DEBUG > 0 &\n     TRACE > 0\n\tINTEGER*4 A0\n#:if cB > 0 &\n     DEBUG > 0\n\tINTEGER*4 B0\n#:if cC > 0 &\n     DEBUG > 0\n\tINTEGER*4 C\n#:elif cCELIF > 0 &\n     DEBUG > 0\n\tINTEGER*4 CELIF\n#:else\n\tINTEGER*4 CELSE\n#:endif\n\tINTEGER*4 B1\n#:elif cBELIF > 0 &\n     DEBUG > 0\n\tINTEGER*4 BELIF\n#:else\n\tINTEGER*4 BELSE\n#:endif\n\tINTEGER*4 A1\n#:elif cAELIF > 0 &\n     DEBUG > 0\n\tINTEGER*4 AELIF\n#:else\n\tINTEGER*4 AELSE\n#:endif\n\tINTEGER*4 Y\nEND STRUCTURE\n"
  },
  {
    "path": "Units/parser-fypp.r/if-with-no-endif.d/expected.tags",
    "content": "foo\tinput.fy\t/^#:def foo(cond) cond + 1$/;\"\tm\n"
  },
  {
    "path": "Units/parser-fypp.r/if-with-no-endif.d/input.fy",
    "content": "#:if DEBUG\n#:def foo(cond) cond + 1\n#! endif is not given.\n"
  },
  {
    "path": "Units/parser-fypp.r/run-alt-guest.d/args.ctags",
    "content": "--fields=+e\n# The next redundant options are for improve the test coverage.\n--param-Fypp.guest=Lisp\n--param-Fypp.guest=NONE\n--param-Fypp.guest=Java\n--extras=+g\n"
  },
  {
    "path": "Units/parser-fypp.r/run-alt-guest.d/expected.tags",
    "content": "A\tinput.fy\t/^\tA,    \\/\\/ should be 'e', not 'f'$/;\"\te\tenum:e\tfile:\tend:10\nB\tinput.fy\t/^\tB(),  \\/\\/ should be 'e', not 'm'$/;\"\te\tenum:e\tfile:\tend:11\nC\tinput.fy\t/^\tC(1), \\/\\/ should be 'e', not missing$/;\"\te\tenum:e\tfile:\tend:12\nD\tinput.fy\t/^\tD,    \\/\\/ should be 'e', not 'f'$/;\"\te\tenum:e\tfile:\tend:20\nE\tinput.fy\t/^\tE(),  \\/\\/ should be 'e', not 'm'$/;\"\te\tenum:e\tfile:\tend:21\nF\tinput.fy\t/^\tF(1), \\/\\/ should be 'e', not missing$/;\"\te\tenum:e\tfile:\tend:22\ndebug_code\tinput.fy\t/^#:def debug_code(code)$/;\"\tm\tend:8\ne\tinput.fy\t/^        e() {}$/;\"\tm\tclass:e\tend:32\ne\tinput.fy\t/^        e(int x) {}$/;\"\tm\tclass:e\tend:31\ne\tinput.fy\t/^public enum e {$/;\"\tg\tend:51\ngetShape\tinput.fy\t/^\tpublic final Shape getShape() {$/;\"\tm\tclass:e\tend:46\ngetString\tinput.fy\t/^\tpublic String getString() {$/;\"\tm\tclass:e\tend:41\nrepeat_code\tinput.fy\t/^#:def repeat_code(code, repeat)$/;\"\tm\tend:29\nshape\tinput.fy\t/^\tpublic final Shape shape;$/;\"\tf\tclass:e\tend:35\nstring\tinput.fy\t/^\tpublic String string;$/;\"\tf\tclass:e\tend:34\ntwoKeywordsInARow\tinput.fy\t/^\tpublic final boolean twoKeywordsInARow;$/;\"\tf\tclass:e\tend:36\n"
  },
  {
    "path": "Units/parser-fypp.r/run-alt-guest.d/input.fy",
    "content": "#! This test case is derived from #1810, a pull request submitted by @p-vitt\n#! and parser-java.r/enum.java.d/input.java\n#! Callable needs only string argument\n#:def debug_code(code)\n  #:if DEBUG > 0\n    $:code\n  #:endif\n#:enddef debug_code\npublic enum e {\n\tA,    // should be 'e', not 'f'\n\tB(),  // should be 'e', not 'm'\n\tC(1), // should be 'e', not missing\n\n#! Pass code block as first positional argument\n#:call debug_code\n  if (size(array) > 100) then\n    print *, \"DEBUG: spuriously large array\"x\n  end if\n#:endcall debug_code\n\tD,    // should be 'e', not 'f'\n\tE(),  // should be 'e', not 'm'\n\tF(1), // should be 'e', not missing\n\t;\n#! Callable needs also non-string argument types\n#:def repeat_code(code, repeat)\n  #:for ind in range(repeat)\n    $:code\n  #:endfor\n#:enddef repeat_code\n\n        e(int x) {}\n        e() {}\n\n\tpublic String string;\n\tpublic final Shape shape;\n\tpublic final boolean twoKeywordsInARow;\n\n#! fypp preprocessor comments  here, and\n\tpublic String getString() {\n\t\treturn string;\n\t}\n\n#! there\n\tpublic final Shape getShape() {\n\t\treturn shape;\n\t}\n#! Pass code block as positional argument and 3 as keyword argument \"repeat\"\n#:call repeat_code(repeat=3)\nthis will be repeated 3 times\n#:endcall repeat_code\n}\n"
  },
  {
    "path": "Units/parser-fypp.r/run-guest.d/args.ctags",
    "content": "--fields=+ne\n--extras=+g\n--kinds-Fortran=+P\n"
  },
  {
    "path": "Units/parser-fypp.r/run-guest.d/expected.tags",
    "content": "+\tinput.fy\t/^  interface operator(+)/;\"\ti\tline:31\tmodule:test_interface\n__anonca2bcf340105\tinput.fy\t/^  interface ! anonymous interface$/;\"\ti\tline:39\tmodule:test_interface\nadd\tinput.fy\t/^    type(atype) function add(/;\"\tP\tline:33\tmodule:test_interface\natype\tinput.fy\t/^  type atype$/;\"\tt\tline:28\tmodule:test_interface\ndebug_code\tinput.fy\t/^#:def debug_code(code)$/;\"\tm\tline:4\tend:8\nget\tinput.fy\t/^  interface get$/;\"\ti\tline:47\tmodule:test_interface\nget_1d\tinput.fy\t/^  subroutine get_1d(/;\"\ts\tline:55\tmodule:test_interface\nget_2d\tinput.fy\t/^  subroutine get_2d(/;\"\ts\tline:62\tmodule:test_interface\nhelloworld\tinput.fy\t/^program helloworld$/;\"\tp\tline:17\nrepeat_code\tinput.fy\t/^#:def repeat_code(code, repeat)$/;\"\tm\tline:23\tend:27\nsuba\tinput.fy\t/^    subroutine suba(/;\"\tP\tline:40\tinterface:__anonca2bcf340105\nsubb\tinput.fy\t/^    subroutine subb(/;\"\tP\tline:42\tinterface:__anonca2bcf340105\ntest_interface\tinput.fy\t/^module test_interface$/;\"\tm\tline:21\n"
  },
  {
    "path": "Units/parser-fypp.r/run-guest.d/input.fy",
    "content": "#! This test case is derived from #1810, a pull request submitted by @p-vitt\n#! and parser-fortran.r/fortran-interface.d/input.f90.\n#! Callable needs only string argument\n#:def debug_code(code)\n  #:if DEBUG > 0\n    $:code\n  #:endif\n#:enddef debug_code\n\n#! Pass code block as first positional argument\n#:call debug_code\n  if (size(array) > 100) then\n    print *, \"DEBUG: spuriously large array\"\n  end if\n#:endcall debug_code\n\nprogram helloworld\nprint *, \"Hello, world.\"\nend program helloworld\n\nmodule test_interface\n#! Callable needs also non-string argument types\n#:def repeat_code(code, repeat)\n  #:for ind in range(repeat)\n    $:code\n  #:endfor\n#:enddef repeat_code\n  type atype\n  end type atype\n  ! operator overload\n  interface operator(+)\n    ! subprogram prototype\n    type(atype) function add(a, b)\n      import atype\n      type(atype), intent(in) :: a, b\n    end function add\n  end interface operator(+)\n  ! wrap subprogram prototypes\n  interface ! anonymous interface\n    subroutine suba()\n    end subroutine suba\n    subroutine subb()\n    end subroutine subb\n  end interface\n  ! define generic subprograms\n#! fypp preprocessor comments  here, and\n  interface get\n#! there\n    ! subprogram name list\n    module procedure get_1d\n    module procedure get_2d\n  end interface get\ncontains\n  ! definition of subprograms\n  subroutine get_1d(a)\n    real a(:)\n  end subroutine get_1d\n#! Pass code block as positional argument and 3 as keyword argument \"repeat\"\n#:call repeat_code(repeat=3)\nthis will be repeated 3 times\n#:endcall repeat_code\n  subroutine get_2d(a)\n    real a(:, :)\n  end subroutine get_2d\nend module test_interface\n\n\n"
  },
  {
    "path": "Units/parser-fypp.r/segv.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-fypp.r/segv.d/args.ctags",
    "content": "--extras=+g\n"
  },
  {
    "path": "Units/parser-fypp.r/segv.d/input.fy",
    "content": "\n#:"
  },
  {
    "path": "Units/parser-fypp.r/simple-fypp.d/args.ctags",
    "content": "--fields=+Sne\n"
  },
  {
    "path": "Units/parser-fypp.r/simple-fypp.d/expected.tags",
    "content": "assertTrue\tinput.fy\t/^#:def assertTrue(cond)$/;\"\tm\tline:2\tsignature:(cond)\tend:7\n"
  },
  {
    "path": "Units/parser-fypp.r/simple-fypp.d/input.fy",
    "content": "#! This test case is taken from #1810, a pull request submitted by @p-vitt.\n#:def assertTrue(cond)\nif (.not. ${cond}$) then\n  print *, \"Assert failed\"\n  error stop\nend if\n#:enddef assertTrue\n"
  },
  {
    "path": "Units/parser-gdscript.r/broken-input.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-gdscript.r/broken-input.d/input.gd",
    "content": "@foo\nvar\n"
  },
  {
    "path": "Units/parser-gdscript.r/class_name-extends-no-implicit-class.d/args.ctags",
    "content": "--sort=no\n--fields=+irKE\n--extras=+r\n--extras-GDScript=-{implicitClass}\n"
  },
  {
    "path": "Units/parser-gdscript.r/class_name-extends-no-implicit-class.d/expected.tags",
    "content": "Node\tinput.gd\t/^class_name MyNode extends Node$/;\"\tclass\troles:extended\textras:reference\nMyNode\tinput.gd\t/^class_name MyNode extends Node$/;\"\tclass\tinherits:Node\troles:def\n"
  },
  {
    "path": "Units/parser-gdscript.r/class_name-extends-no-implicit-class.d/input.gd",
    "content": "class_name MyNode extends Node\n"
  },
  {
    "path": "Units/parser-gdscript.r/class_name-extends.d/args.ctags",
    "content": "--sort=no\n--fields=+irKE\n--extras=+r\n--extras-GDScript=+{implicitClass}\n"
  },
  {
    "path": "Units/parser-gdscript.r/class_name-extends.d/expected.tags",
    "content": "MyNode\tinput.gd\t/^class_name MyNode extends Node$/;\"\tclass\tinherits:Node\troles:def\nNode\tinput.gd\t/^class_name MyNode extends Node$/;\"\tclass\troles:extended\textras:reference\n"
  },
  {
    "path": "Units/parser-gdscript.r/class_name-extends.d/input.gd",
    "content": "class_name MyNode extends Node\n"
  },
  {
    "path": "Units/parser-gdscript.r/inner-class.d/args.ctags",
    "content": "--sort=no\n--fields=+{inherits}{signature}{extras}\n--kinds-GDScript=-{local}\n--kinds-GDScript=-{parameter}\n--extras-GDScript=+{implicitClass}\n"
  },
  {
    "path": "Units/parser-gdscript.r/inner-class.d/expected.tags",
    "content": "anon_class_186e00360100\tinput.gd\t/^# Taken from godot-demo-projects\\/networking\\/webrtc_signaling\\/server\\/ws_webrtc_server.gd$/;\"\tc\tinherits:Node\textras:anonymous,implicitClass\nTIMEOUT\tinput.gd\t/^const TIMEOUT = 1000 # Unresponsive clients times out after 1 sec$/;\"\tC\tclass:anon_class_186e00360100\nSEAL_TIME\tinput.gd\t/^const SEAL_TIME = 10000 # A sealed room will be closed after this time$/;\"\tC\tclass:anon_class_186e00360100\nALFNUM\tinput.gd\t/^const ALFNUM = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"$/;\"\tC\tclass:anon_class_186e00360100\n_alfnum\tinput.gd\t/^var _alfnum = ALFNUM.to_ascii()$/;\"\tv\tclass:anon_class_186e00360100\nrand\tinput.gd\t/^var rand: RandomNumberGenerator = RandomNumberGenerator.new()$/;\"\tv\tclass:anon_class_186e00360100\ttyperef:typename:RandomNumberGenerator\nlobbies\tinput.gd\t/^var lobbies: Dictionary = {}$/;\"\tv\tclass:anon_class_186e00360100\ttyperef:typename:Dictionary\nserver\tinput.gd\t/^var server: WebSocketServer = WebSocketServer.new()$/;\"\tv\tclass:anon_class_186e00360100\ttyperef:typename:WebSocketServer\npeers\tinput.gd\t/^var peers: Dictionary = {}$/;\"\tv\tclass:anon_class_186e00360100\ttyperef:typename:Dictionary\nPeer\tinput.gd\t/^class Peer extends Reference:$/;\"\tc\tclass:anon_class_186e00360100\tinherits:Reference\nid\tinput.gd\t/^\tvar id = -1$/;\"\tv\tclass:anon_class_186e00360100.Peer\nlobby\tinput.gd\t/^\tvar lobby = \"\"$/;\"\tv\tclass:anon_class_186e00360100.Peer\ntime\tinput.gd\t/^\tvar time = OS.get_ticks_msec()$/;\"\tv\tclass:anon_class_186e00360100.Peer\n_init\tinput.gd\t/^\tfunc _init(peer_id):$/;\"\tm\tclass:anon_class_186e00360100.Peer\tsignature:(peer_id)\nLobby\tinput.gd\t/^class Lobby extends Reference:$/;\"\tc\tclass:anon_class_186e00360100\tinherits:Reference\npeers\tinput.gd\t/^\tvar peers: Array = []$/;\"\tv\tclass:anon_class_186e00360100.Lobby\ttyperef:typename:Array\nhost\tinput.gd\t/^\tvar host: int = -1$/;\"\tv\tclass:anon_class_186e00360100.Lobby\ttyperef:typename:int\nsealed\tinput.gd\t/^\tvar sealed: bool = false$/;\"\tv\tclass:anon_class_186e00360100.Lobby\ttyperef:typename:bool\ntime\tinput.gd\t/^\tvar time = 0$/;\"\tv\tclass:anon_class_186e00360100.Lobby\n_init\tinput.gd\t/^\tfunc _init(host_id: int):$/;\"\tm\tclass:anon_class_186e00360100.Lobby\tsignature:(host_id: int)\njoin\tinput.gd\t/^\tfunc join(peer_id, server) -> bool:$/;\"\tm\tclass:anon_class_186e00360100.Lobby\ttyperef:typename:bool\tsignature:(peer_id, server)\nleave\tinput.gd\t/^\tfunc leave(peer_id, server) -> bool:$/;\"\tm\tclass:anon_class_186e00360100.Lobby\ttyperef:typename:bool\tsignature:(peer_id, server)\nseal\tinput.gd\t/^\tfunc seal(peer_id, server) -> bool:$/;\"\tm\tclass:anon_class_186e00360100.Lobby\ttyperef:typename:bool\tsignature:(peer_id, server)\nCircle2D\tinput.gd\t/^class Circle2D:$/;\"\tc\tclass:anon_class_186e00360100\tinherits:Node2D\ncenter\tinput.gd\t/^\tvar center$/;\"\tv\tclass:anon_class_186e00360100.Circle2D\nradius\tinput.gd\t/^\tvar radius$/;\"\tv\tclass:anon_class_186e00360100.Circle2D\ncolor\tinput.gd\t/^\tvar color$/;\"\tv\tclass:anon_class_186e00360100.Circle2D\n_draw\tinput.gd\t/^\tfunc _draw():$/;\"\tm\tclass:anon_class_186e00360100.Circle2D\tsignature:()\n_init\tinput.gd\t/^func _init():$/;\"\tm\tclass:anon_class_186e00360100\tsignature:()\n"
  },
  {
    "path": "Units/parser-gdscript.r/inner-class.d/input.gd",
    "content": "# Taken from godot-demo-projects/networking/webrtc_signaling/server/ws_webrtc_server.gd\n# of https://github.com/godotengine/godot-demo-projects.git\n\nextends Node\n\nconst TIMEOUT = 1000 # Unresponsive clients times out after 1 sec\nconst SEAL_TIME = 10000 # A sealed room will be closed after this time\nconst ALFNUM = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"\n\nvar _alfnum = ALFNUM.to_ascii()\n\nvar rand: RandomNumberGenerator = RandomNumberGenerator.new()\nvar lobbies: Dictionary = {}\nvar server: WebSocketServer = WebSocketServer.new()\nvar peers: Dictionary = {}\n\nclass Peer extends Reference:\n\tvar id = -1\n\tvar lobby = \"\"\n\tvar time = OS.get_ticks_msec()\n\n\tfunc _init(peer_id):\n\t\tid = peer_id\n\n\n\nclass Lobby extends Reference:\n\tvar peers: Array = []\n\tvar host: int = -1\n\tvar sealed: bool = false\n\tvar time = 0\n\n\tfunc _init(host_id: int):\n\t\thost = host_id\n\n\tfunc join(peer_id, server) -> bool:\n\t\tif sealed: return false\n\t\tif not server.has_peer(peer_id): return false\n\t\tvar new_peer: WebSocketPeer = server.get_peer(peer_id)\n\t\tnew_peer.put_packet((\"I: %d\\n\" % (1 if peer_id == host else peer_id)).to_utf8())\n\t\tfor p in peers:\n\t\t\tif not server.has_peer(p):\n\t\t\t\tcontinue\n\t\t\tserver.get_peer(p).put_packet((\"N: %d\\n\" % peer_id).to_utf8())\n\t\t\tnew_peer.put_packet((\"N: %d\\n\" % (1 if p == host else p)).to_utf8())\n\t\tpeers.push_back(peer_id)\n\t\treturn true\n\n\n\tfunc leave(peer_id, server) -> bool:\n\t\tif not peers.has(peer_id): return false\n\t\tpeers.erase(peer_id)\n\t\tvar close = false\n\t\tif peer_id == host:\n\t\t\t# The room host disconnected, will disconnect all peers.\n\t\t\tclose = true\n\t\tif sealed: return close\n\t\t# Notify other peers.\n\t\tfor p in peers:\n\t\t\tif not server.has_peer(p): return close\n\t\t\tif close:\n\t\t\t\t# Disconnect peers.\n\t\t\t\tserver.disconnect_peer(p)\n\t\t\telse:\n\t\t\t\t# Notify disconnection.\n\t\t\t\tserver.get_peer(p).put_packet((\"D: %d\\n\" % peer_id).to_utf8())\n\t\treturn close\n\n\n\tfunc seal(peer_id, server) -> bool:\n\t\t# Only host can seal the room.\n\t\tif host != peer_id: return false\n\t\tsealed = true\n\t\tfor p in peers:\n\t\t\tserver.get_peer(p).put_packet(\"S: \\n\".to_utf8())\n\t\ttime = OS.get_ticks_msec()\n\t\treturn true\n\n\n# Taken from godot-demo-projects/2d/physics_tests/test.gd\nclass Circle2D:\n\textends Node2D\n\tvar center\n\tvar radius\n\tvar color\n\n\tfunc _draw():\n\t\tdraw_circle(center, radius, color)\n\nfunc _init():\n\tserver.connect(\"data_received\", self, \"_on_data\")\n\tserver.connect(\"client_connected\", self, \"_peer_connected\")\n\tserver.connect(\"client_disconnected\", self, \"_peer_disconnected\")\n\n\n# ...\n"
  },
  {
    "path": "Units/parser-gdscript.r/modifiers.d/args.ctags",
    "content": "--sort=no\n--kinds-GDScript=+zl\n--fields=+E\n--fields-GDScript={annotations}\n--extras-GDScript=+{implicitClass}\n"
  },
  {
    "path": "Units/parser-gdscript.r/modifiers.d/expected.tags",
    "content": "anon_class_025551790100\tinput.gd\t/^# Taken from godot-demo-projects\\/3d\\/voxel\\/world\\/chunk.gd$/;\"\tc\textras:anonymous,implicitClass\n_create_block_collider\tinput.gd\t/^func _create_block_collider(block_sub_position):$/;\"\tm\tclass:anon_class_025551790100\nblock_sub_position\tinput.gd\t/^func _create_block_collider(block_sub_position):$/;\"\tz\tmethod:anon_class_025551790100._create_block_collider\tfile:\ncollider\tinput.gd\t/^        var collider = CollisionShape.new()$/;\"\tl\tmethod:anon_class_025551790100._create_block_collider\tfile:\ncalculate_block_uvs\tinput.gd\t/^static func calculate_block_uvs(block_id):$/;\"\tm\tclass:anon_class_025551790100\tannotations:static\nblock_id\tinput.gd\t/^static func calculate_block_uvs(block_id):$/;\"\tz\tmethod:anon_class_025551790100.calculate_block_uvs\tfile:\nrow\tinput.gd\t/^        var row = block_id \\/ TEXTURE_SHEET_WIDTH$/;\"\tl\tmethod:anon_class_025551790100.calculate_block_uvs\tfile:\ncol\tinput.gd\t/^        var col = block_id % TEXTURE_SHEET_WIDTH$/;\"\tl\tmethod:anon_class_025551790100.calculate_block_uvs\tfile:\nid\tinput.gd\t/^func id(a):$/;\"\tm\tclass:anon_class_025551790100\na\tinput.gd\t/^func id(a):$/;\"\tz\tmethod:anon_class_025551790100.id\tfile:\nr\tinput.gd\t/^remote func r(b):$/;\"\tm\tclass:anon_class_025551790100\tannotations:remote\nb\tinput.gd\t/^remote func r(b):$/;\"\tz\tmethod:anon_class_025551790100.r\tfile:\nx\tinput.gd\t/^remote static func x(c):$/;\"\tm\tclass:anon_class_025551790100\tannotations:remote,static\nc\tinput.gd\t/^remote static func x(c):$/;\"\tz\tmethod:anon_class_025551790100.x\tfile:\n"
  },
  {
    "path": "Units/parser-gdscript.r/modifiers.d/input.gd",
    "content": "# Taken from godot-demo-projects/3d/voxel/world/chunk.gd\nfunc _create_block_collider(block_sub_position):\n        var collider = CollisionShape.new()\n        collider.shape = BoxShape.new()\n        collider.shape.extents = Vector3.ONE / 2\n        collider.transform.origin = block_sub_position + Vector3.ONE / 2\n        add_child(collider)\n\nstatic func calculate_block_uvs(block_id):\n        # This method only supports square texture sheets.\n        var row = block_id / TEXTURE_SHEET_WIDTH\n        var col = block_id % TEXTURE_SHEET_WIDTH\n\n        return [\n                TEXTURE_TILE_SIZE * Vector2(col, row),\n                TEXTURE_TILE_SIZE * Vector2(col, row + 1),\n                TEXTURE_TILE_SIZE * Vector2(col + 1, row),\n                TEXTURE_TILE_SIZE * Vector2(col + 1, row + 1),\n        ]\n\nfunc id(a):\n\treturn a\n\nremote func r(b):\n\treturn b\n\nremote static func x(c):\n\treturn c\n"
  },
  {
    "path": "Units/parser-gdscript.r/no-implicit-class.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+rEiS\n"
  },
  {
    "path": "Units/parser-gdscript.r/no-implicit-class.d/expected.tags",
    "content": "BaseClass\tinput.gd\t/^extends BaseClass$/;\"\tc\troles:extended\textras:reference\nMyClass\tinput.gd\t/^class_name MyClass, \"res:\\/\\/path\\/to\\/optional\\/icon.svg\"$/;\"\tc\troles:def\na\tinput.gd\t/^@export_range(start=0, end=100, step=1) var a = 5$/;\"\tv\troles:def\tannotations:export_range(start=0, end=100, step=1)\ns\tinput.gd\t/^var s = \"Hello\"$/;\"\tv\troles:def\tannotations:export\narr\tinput.gd\t/^@onready var arr = [1, 2, 3]$/;\"\tv\troles:def\tannotations:onready\ndict\tinput.gd\t/^var dict = {\"key\": \"value\", 2: 3}$/;\"\tv\troles:def\ntyped_var\tinput.gd\t/^var typed_var: int$/;\"\tv\ttyperef:typename:int\troles:def\ninferred_type\tinput.gd\t/^inferred_type\\\\$/;\"\tv\troles:def\tannotations:onready,export_multiline\nANSWER\tinput.gd\t/^const ANSWER = 42$/;\"\tC\troles:def\nTHE_NAME\tinput.gd\t/^const THE_NAME:String = \"Charly\"$/;\"\tC\ttyperef:typename:String\troles:def\nanon_enum_84e343bf0104\tinput.gd\t/^enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}$/;\"\tg\troles:def\textras:anonymous\nUNIT_NEUTRAL\tinput.gd\t/^enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}$/;\"\te\tenum:anon_enum_84e343bf0104\tfile:\troles:def\nUNIT_ENEMY\tinput.gd\t/^enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}$/;\"\te\tenum:anon_enum_84e343bf0104\tfile:\troles:def\nUNIT_ALL\tinput.gd\t/^enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}$/;\"\te\tenum:anon_enum_84e343bf0104\tfile:\troles:def\nNamed\tinput.gd\t/^enum Named {THING_1, THING_2, ANOTHER_THING=1}$/;\"\tg\troles:def\nTHING_1\tinput.gd\t/^enum Named {THING_1, THING_2, ANOTHER_THING=1}$/;\"\te\tenum:Named\tfile:\troles:def\nTHING_2\tinput.gd\t/^enum Named {THING_1, THING_2, ANOTHER_THING=1}$/;\"\te\tenum:Named\tfile:\troles:def\nANOTHER_THING\tinput.gd\t/^enum Named {THING_1, THING_2, ANOTHER_THING=1}$/;\"\te\tenum:Named\tfile:\troles:def\nv2\tinput.gd\t/^var v2 = Vector2(1, 2)$/;\"\tv\troles:def\nv3\tinput.gd\t/^var v3 = Vector3(1, 2, 3)$/;\"\tv\troles:def\nsome_function\tinput.gd\t/^func some_function(param1: Vector3, param2: int) -> int:$/;\"\tm\ttyperef:typename:int\tsignature:(param1: Vector3, param2: int)\troles:def\tannotations:master\nsomething\tinput.gd\t/^func something(p1, p2):$/;\"\tm\tsignature:(p1, p2)\troles:def\tannotations:puppet\nSomething\tinput.gd\t/^class Something:$/;\"\tc\tinherits:\troles:def\na\tinput.gd\t/^    var a = 10$/;\"\tv\tclass:Something\troles:def\n_private_var\tinput.gd\t/^    const _private_var:String = \"hi\\\\n\\\\\\\\escape\"$/;\"\tC\tclass:Something\ttyperef:typename:String\troles:def\nfoooooooo\tinput.gd\t/^\tfunc foooooooo() -> String:$/;\"\tm\tclass:Something\ttyperef:typename:String\tsignature:()\troles:def\n_init\tinput.gd\t/^func _init():$/;\"\tm\tsignature:()\troles:def\n"
  },
  {
    "path": "Units/parser-gdscript.r/no-implicit-class.d/input.gd",
    "content": "# Derived from https://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/gdscript_basics.html\n\n# A file is a class but it has no name. The name is given only when\n# class_name is used.\n\n# Inheritance\n\nextends BaseClass\n\n# (optional) class definition with a custom icon\n\nclass_name MyClass, \"res://path/to/optional/icon.svg\"\n\n\n# Member variables\n\n@export_range(start=0, end=100, step=1) var a = 5\n@export\nvar s = \"Hello\"\n@onready var arr = [1, 2, 3]\nvar dict = {\"key\": \"value\", 2: 3}\nvar typed_var: int\n@onready\n@export_multiline\nvar\\\ninferred_type\\\n:=\\\n\"String\"\n\n# Constants\n\nconst ANSWER = 42\nconst THE_NAME:String = \"Charly\"\n\n# Enums\n\nenum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}\nenum Named {THING_1, THING_2, ANOTHER_THING=1}\n\n# Built-in vector types\n\nvar v2 = Vector2(1, 2)\nvar v3 = Vector3(1, 2, 3)\n\n\n# Function\n\n@master\nfunc some_function(param1: Vector3, param2: int) -> int:\n    var local_var = 5\n\n    if param1 < local_var:\n        print(param1)\n    elif param2 > 5:\n        print(param2)\n    elif param2 == 2:\n        print(20)\n    elif param2 <= 2:\n        print((-20 %\n\n\n\n3) / 5)\n    else:\n        print(\"Fail!\")\n\n    for i in range(20):\n        print(i)\n\n    while param2 != 0:\n        param2 -= 1\n\n    var local_var2 = param1 + 3\n    return local_var2\n\n\n# Functions override functions with the same name on the base/parent class.\n# If you still want to call them, use '.' (like 'super' in other languages).\n@puppet\nfunc something(p1, p2):\n    .something(p1, p2)\n\n\n# Inner class\n\nclass Something:\n    var a = 10\n    const _private_var:String = \"hi\\n\\\\escape\"\n\tfunc foooooooo() -> String:\n\t\tprint(\"\"\"\n\t\ttest\\\\\n\t\t\n\t\ttest\"\"\")\n        return \"\"\n\n# Constructor\n\nfunc _init():\n    print(\"Constructed!\")\n    var lv = Something.new()\n    print(lv.a)\n"
  },
  {
    "path": "Units/parser-gdscript.r/sample.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+rEiS\n--extras-GDScript=+{implicitClass}\n"
  },
  {
    "path": "Units/parser-gdscript.r/sample.d/expected.tags",
    "content": "MyClass\tinput.gd\t/^class_name MyClass, \"res:\\/\\/path\\/to\\/optional\\/icon.svg\"$/;\"\tc\tinherits:BaseClass\troles:def\nBaseClass\tinput.gd\t/^extends BaseClass$/;\"\tc\troles:extended\textras:reference\na\tinput.gd\t/^@export_range(start=0, end=100, step=1) var a = 5$/;\"\tv\tclass:MyClass\troles:def\tannotations:export_range(start=0, end=100, step=1)\ns\tinput.gd\t/^var s = \"Hello\"$/;\"\tv\tclass:MyClass\troles:def\tannotations:export\narr\tinput.gd\t/^@onready var arr = [1, 2, 3]$/;\"\tv\tclass:MyClass\troles:def\tannotations:onready\ndict\tinput.gd\t/^var dict = {\"key\": \"value\", 2: 3}$/;\"\tv\tclass:MyClass\troles:def\ntyped_var\tinput.gd\t/^var typed_var: int$/;\"\tv\tclass:MyClass\ttyperef:typename:int\troles:def\ninferred_type\tinput.gd\t/^inferred_type\\\\$/;\"\tv\tclass:MyClass\troles:def\tannotations:onready,export_multiline\nANSWER\tinput.gd\t/^const ANSWER = 42$/;\"\tC\tclass:MyClass\troles:def\nTHE_NAME\tinput.gd\t/^const THE_NAME:String = \"Charly\"$/;\"\tC\tclass:MyClass\ttyperef:typename:String\troles:def\nanon_enum_e3cc11790204\tinput.gd\t/^enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}$/;\"\tg\tclass:MyClass\troles:def\textras:anonymous\nUNIT_NEUTRAL\tinput.gd\t/^enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}$/;\"\te\tenum:MyClass.anon_enum_e3cc11790204\tfile:\troles:def\nUNIT_ENEMY\tinput.gd\t/^enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}$/;\"\te\tenum:MyClass.anon_enum_e3cc11790204\tfile:\troles:def\nUNIT_ALL\tinput.gd\t/^enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}$/;\"\te\tenum:MyClass.anon_enum_e3cc11790204\tfile:\troles:def\nNamed\tinput.gd\t/^enum Named {THING_1, THING_2, ANOTHER_THING=1}$/;\"\tg\tclass:MyClass\troles:def\nTHING_1\tinput.gd\t/^enum Named {THING_1, THING_2, ANOTHER_THING=1}$/;\"\te\tenum:MyClass.Named\tfile:\troles:def\nTHING_2\tinput.gd\t/^enum Named {THING_1, THING_2, ANOTHER_THING=1}$/;\"\te\tenum:MyClass.Named\tfile:\troles:def\nANOTHER_THING\tinput.gd\t/^enum Named {THING_1, THING_2, ANOTHER_THING=1}$/;\"\te\tenum:MyClass.Named\tfile:\troles:def\nv2\tinput.gd\t/^var v2 = Vector2(1, 2)$/;\"\tv\tclass:MyClass\troles:def\nv3\tinput.gd\t/^var v3 = Vector3(1, 2, 3)$/;\"\tv\tclass:MyClass\troles:def\nsome_function\tinput.gd\t/^func some_function(param1: Vector3, param2: int) -> int:$/;\"\tm\tclass:MyClass\ttyperef:typename:int\tsignature:(param1: Vector3, param2: int)\troles:def\tannotations:master\nsomething\tinput.gd\t/^func something(p1, p2):$/;\"\tm\tclass:MyClass\tsignature:(p1, p2)\troles:def\tannotations:puppet\nSomething\tinput.gd\t/^class Something:$/;\"\tc\tclass:MyClass\tinherits:\troles:def\na\tinput.gd\t/^    var a = 10$/;\"\tv\tclass:MyClass.Something\troles:def\n_private_var\tinput.gd\t/^    const _private_var:String = \"hi\\\\n\\\\\\\\escape\"$/;\"\tC\tclass:MyClass.Something\ttyperef:typename:String\troles:def\nfoooooooo\tinput.gd\t/^\tfunc foooooooo() -> String:$/;\"\tm\tclass:MyClass.Something\ttyperef:typename:String\tsignature:()\troles:def\n_init\tinput.gd\t/^func _init():$/;\"\tm\tclass:MyClass\tsignature:()\troles:def\n"
  },
  {
    "path": "Units/parser-gdscript.r/sample.d/input.gd",
    "content": "# Derived from https://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/gdscript_basics.html\n\n# A file is a class!\n\n# Inheritance\n\nextends BaseClass\n\n# (optional) class definition with a custom icon\n\nclass_name MyClass, \"res://path/to/optional/icon.svg\"\n\n\n# Member variables\n\n@export_range(start=0, end=100, step=1) var a = 5\n@export\nvar s = \"Hello\"\n@onready var arr = [1, 2, 3]\nvar dict = {\"key\": \"value\", 2: 3}\nvar typed_var: int\n@onready\n@export_multiline\nvar\\\ninferred_type\\\n:=\\\n\"String\"\n\n# Constants\n\nconst ANSWER = 42\nconst THE_NAME:String = \"Charly\"\n\n# Enums\n\nenum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}\nenum Named {THING_1, THING_2, ANOTHER_THING=1}\n\n# Built-in vector types\n\nvar v2 = Vector2(1, 2)\nvar v3 = Vector3(1, 2, 3)\n\n\n# Function\n\n@master\nfunc some_function(param1: Vector3, param2: int) -> int:\n    var local_var = 5\n\n    if param1 < local_var:\n        print(param1)\n    elif param2 > 5:\n        print(param2)\n    elif param2 == 2:\n        print(20)\n    elif param2 <= 2:\n        print((-20 %\n\n\n\n3) / 5)\n    else:\n        print(\"Fail!\")\n\n    for i in range(20):\n        print(i)\n\n    while param2 != 0:\n        param2 -= 1\n\n    var local_var2 = param1 + 3\n    return local_var2\n\n\n# Functions override functions with the same name on the base/parent class.\n# If you still want to call them, use '.' (like 'super' in other languages).\n@puppet\nfunc something(p1, p2):\n    .something(p1, p2)\n\n\n# Inner class\n\nclass Something:\n    var a = 10\n    const _private_var:String = \"hi\\n\\\\escape\"\n\tfunc foooooooo() -> String:\n\t\tprint(\"\"\"\n\t\ttest\\\\\n\t\t\n\t\ttest\"\"\")\n        return \"\"\n\n# Constructor\n\nfunc _init():\n    print(\"Constructed!\")\n    var lv = Something.new()\n    print(lv.a)\n"
  },
  {
    "path": "Units/parser-gdscript.r/signal.d/args.ctags",
    "content": "--sort=no\n--fields=+SKiE\n--kinds-GDScript=+z\n--extras-GDScript=+{implicitClass}\n"
  },
  {
    "path": "Units/parser-gdscript.r/signal.d/expected.tags",
    "content": "anon_class_e8da5fd50100\tinput.gd\t/^extends Node$/;\"\tclass\tinherits:Node\textras:anonymous,implicitClass\nfinished\tinput.gd\t/^signal finished(next_state_name)$/;\"\tsignal\tclass:anon_class_e8da5fd50100\tsignature:(next_state_name)\nnext_state_name\tinput.gd\t/^signal finished(next_state_name)$/;\"\tparameter\tsignal:anon_class_e8da5fd50100.finished\tfile:\nenter\tinput.gd\t/^func enter():$/;\"\tmethod\tclass:anon_class_e8da5fd50100\tsignature:()\nexit\tinput.gd\t/^func exit():$/;\"\tmethod\tclass:anon_class_e8da5fd50100\tsignature:()\nhandle_input\tinput.gd\t/^func handle_input(_event):$/;\"\tmethod\tclass:anon_class_e8da5fd50100\tsignature:(_event)\n_event\tinput.gd\t/^func handle_input(_event):$/;\"\tparameter\tmethod:anon_class_e8da5fd50100.handle_input\tfile:\nupdate\tinput.gd\t/^func update(_delta):$/;\"\tmethod\tclass:anon_class_e8da5fd50100\tsignature:(_delta)\n_delta\tinput.gd\t/^func update(_delta):$/;\"\tparameter\tmethod:anon_class_e8da5fd50100.update\tfile:\n_on_animation_finished\tinput.gd\t/^func _on_animation_finished(_anim_name):$/;\"\tmethod\tclass:anon_class_e8da5fd50100\tsignature:(_anim_name)\n_anim_name\tinput.gd\t/^func _on_animation_finished(_anim_name):$/;\"\tparameter\tmethod:anon_class_e8da5fd50100._on_animation_finished\tfile:\nanon_class_88c08fb20100\tinput-0.gd\t/^signal start_game$/;\"\tclass\textras:anonymous,implicitClass\nstart_game\tinput-0.gd\t/^signal start_game$/;\"\tsignal\tclass:anon_class_88c08fb20100\nC\tinput-1.gd\t/^class_name C, \"res:\\/\\/path\\/to\\/optional\\/icon.svg\"$/;\"\tclass\tinherits:B\nsdf\tinput-1.gd\t/^signal sdf$/;\"\tsignal\tclass:C\ns\tinput-1.gd\t/^var s = \"hello\"$/;\"\tvariable\tclass:C\n"
  },
  {
    "path": "Units/parser-gdscript.r/signal.d/input-0.gd",
    "content": "signal start_game\n"
  },
  {
    "path": "Units/parser-gdscript.r/signal.d/input-1.gd",
    "content": "extends B\n\nsignal sdf\nclass_name C, \"res://path/to/optional/icon.svg\"\n\nvar s = \"hello\"\n"
  },
  {
    "path": "Units/parser-gdscript.r/signal.d/input.gd",
    "content": "extends Node\n# Base interface for all states: it doesn't do anything by itself,\n# but forces us to pass the right arguments to the methods below\n# and makes sure every State object had all of these methods.\n\n# warning-ignore:unused_signal\nsignal finished(next_state_name)\n\n# Initialize the state. E.g. change the animation.\nfunc enter():\n\tpass\n\n\n# Clean up the state. Reinitialize values like a timer.\nfunc exit():\n\tpass\n\n\nfunc handle_input(_event):\n\tpass\n\n\nfunc update(_delta):\n\tpass\n\n\nfunc _on_animation_finished(_anim_name):\n\tpass\n\n"
  },
  {
    "path": "Units/parser-gemspec.r/simple-gemspec.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-gemspec.r/simple-gemspec.d/expected.tags",
    "content": "rspec/core/version\tinput.gemspec\t/^require \"rspec\\/core\\/version\"$/;\"\tL\troles:required\nrspec-core\tinput.gemspec\t/^  s.name        = \"rspec-core\"$/;\"\tg\troles:def\nrspec-support\tinput.gemspec\t/^    s.add_runtime_dependency \"rspec-support\", \"= #{RSpec::Core::Version::STRING}\"$/;\"\tg\troles:runtimeDep\nrspec-support\tinput.gemspec\t/^    s.add_runtime_dependency \"rspec-support\", \"~> #{RSpec::Core::Version::STRING.split('.')[0..1/;\"\tg\troles:runtimeDep\ncucumber\tinput.gemspec\t/^  s.add_development_dependency \"cucumber\", \"~> 1.3\"$/;\"\tg\troles:develDep\nminitest\tinput.gemspec\t/^  s.add_development_dependency \"minitest\", \"~> 5.3\"$/;\"\tg\troles:develDep\naruba\tinput.gemspec\t/^  s.add_development_dependency %q{aruba},    \"~> 0.14.9\"$/;\"\tg\troles:develDep\ncoderay\tinput.gemspec\t/^  s.add_development_dependency %q[coderay],  \"~> 1.1.1\"$/;\"\tg\troles:develDep\nmocha\tinput.gemspec\t/^  s.add_development_dependency %q(mocha),        \"~> 0.13.0\"$/;\"\tg\troles:develDep\nrr\tinput.gemspec\t/^  s.add_development_dependency %q<rr>,           \"~> 1.0.4\"$/;\"\tg\troles:develDep\nflexmock\tinput.gemspec\t/^  s.add_development_dependency %q flexmock ,     \"~> 0.9.0\"$/;\"\tg\troles:develDep\nthread_order\tinput.gemspec\t/^  s.add_development_dependency %q!thread_order!, \"~> 1.1.0\"$/;\"\tg\troles:develDep\nstrange{name}(just){-}<for>{-}{testing}\tinput.gemspec\t/^  s.add_runtime_dependency %q{strange{name}(just){-}<for>{-}{testing}}.freeze, [\">= 1.2.4\".freez/;\"\tg\troles:runtimeDep\nnet-ssh\tinput.gemspec\t/^  s.add_runtime_dependency(\"net-ssh\", \">= 1.0.1\")$/;\"\tg\troles:runtimeDep\ned25519\tinput.gemspec\t/^  s.add_runtime_dependency(%q<ed25519>.freeze, [\">= 1.2.4\".freeze, \"< 1.4\".freeze])$/;\"\tg\troles:runtimeDep\nstrange<name>just-for-testing\tinput.gemspec\t/^  s.add_runtime_dependency(%q<strange<name>just-for-testing>.freeze, [\">= 1.2.4\".freeze, \"< 1.4\"/;\"\tg\troles:runtimeDep\nkatello/version\tinput-0.gemspec\t/^require \"katello\\/version\"$/;\"\tL\troles:required\nkatello\tinput-0.gemspec\t/^  gem.name        = \"katello\"$/;\"\tg\troles:def\nrails\tinput-0.gemspec\t/^  gem.add_dependency \"rails\"$/;\"\tg\troles:runtimeDep\nG1\tinput-1.gemspec\t/^  gem.name        = %q!G1!$/;\"\tg\troles:def\n"
  },
  {
    "path": "Units/parser-gemspec.r/simple-gemspec.d/input-0.gemspec",
    "content": "# Derrived from katello/katello.gemspec\n$LOAD_PATH.push File.expand_path(\"../lib\", __FILE__)\n\n# Maintain your gem's version:\nrequire \"katello/version\"\n\n# Describe your gem and declare its dependencies:\nGem::Specification.new do |gem|\n  gem.name        = \"katello\"\n  gem.version     = Katello::VERSION\n  gem.authors     = [\"N/A\"]\n  gem.email       = [\"katello-devel@redhat.com\"]\n  gem.homepage    = \"http://www.katello.org\"\n  gem.summary     = \"\"\n  gem.description = \"Content and Subscription Management plugin for Foreman\"\n\n  gem.files = Dir[\"{app,vendor,lib,db,ca,config,locale}/**/*\"] + [\"LICENSE.txt\", \"README.md\"]\n  gem.files += Dir[\"engines/bastion_katello/{app,vendor,lib,config}/**/*\"]\n  gem.files += Dir[\"engines/bastion_katello/{README.md,bastion_katello.gemspec}\"]\n\n  gem.require_paths = [\"lib\"]\n\n  # Core Dependencies\n  gem.add_dependency \"rails\"\n\n  # ...\nend\n"
  },
  {
    "path": "Units/parser-gemspec.r/simple-gemspec.d/input-1.gemspec",
    "content": "Gem::Specification.new do |gem|\n  gem.name        = %q!G1!\n  # ...\nend\n"
  },
  {
    "path": "Units/parser-gemspec.r/simple-gemspec.d/input.gemspec",
    "content": "# Taken from rspec-core/rspec-core.gemspec\n\n# -*- encoding: utf-8 -*-\n$LOAD_PATH.unshift File.expand_path(\"../lib\", __FILE__)\nrequire \"rspec/core/version\"\n\nGem::Specification.new do |s|\n  s.name        = \"rspec-core\"\n  s.version     = RSpec::Core::Version::STRING\n  s.platform    = Gem::Platform::RUBY\n  s.license     = \"MIT\"\n  s.authors     = [\"Steven Baker\", \"David Chelimsky\", \"Chad Humphries\", \"Myron Marston\"]\n  s.email       = \"rspec@googlegroups.com\"\n  s.homepage    = \"https://github.com/rspec/rspec-core\"\n  s.summary     = \"rspec-core-#{RSpec::Core::Version::STRING}\"\n  s.description = \"BDD for Ruby. RSpec runner and example groups.\"\n\n  s.metadata = {\n    'bug_tracker_uri'   => 'https://github.com/rspec/rspec-core/issues',\n    'changelog_uri'     => \"https://github.com/rspec/rspec-core/blob/v#{s.version}/Changelog.md\",\n    'documentation_uri' => 'https://rspec.info/documentation/',\n    'mailing_list_uri'  => 'https://groups.google.com/forum/#!forum/rspec',\n    'source_code_uri'   => 'https://github.com/rspec/rspec-core',\n  }\n\n  s.files            = `git ls-files -- lib/*`.split(\"\\n\")\n  s.files           += %w[README.md LICENSE.md Changelog.md .yardopts .document]\n  s.test_files       = []\n  s.bindir           = 'exe'\n  s.executables      = `git ls-files -- exe/*`.split(\"\\n\").map{ |f| File.basename(f) }\n  s.rdoc_options     = [\"--charset=UTF-8\"]\n  s.require_path     = \"lib\"\n\n  s.required_ruby_version = '>= 1.8.7'\n\n  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')\n  if File.exist?(private_key)\n    s.signing_key = private_key\n    s.cert_chain = [File.expand_path('~/.gem/rspec-gem-public_cert.pem')]\n  end\n\n  if RSpec::Core::Version::STRING =~ /[a-zA-Z]+/\n    # rspec-support is locked to our version when running pre,rc etc\n    s.add_runtime_dependency \"rspec-support\", \"= #{RSpec::Core::Version::STRING}\"\n  else\n    # rspec-support must otherwise match our major/minor version\n    s.add_runtime_dependency \"rspec-support\", \"~> #{RSpec::Core::Version::STRING.split('.')[0..1].concat(['0']).join('.')}\"\n  end\n\n  s.add_development_dependency \"cucumber\", \"~> 1.3\"\n  s.add_development_dependency \"minitest\", \"~> 5.3\"\n  s.add_development_dependency %q{aruba},    \"~> 0.14.9\"\n\n  s.add_development_dependency %q[coderay],  \"~> 1.1.1\"\n\n  s.add_development_dependency %q(mocha),        \"~> 0.13.0\"\n  s.add_development_dependency %q<rr>,           \"~> 1.0.4\"\n  s.add_development_dependency %q flexmock ,     \"~> 0.9.0\"\n  s.add_development_dependency %q!thread_order!, \"~> 1.1.0\"\n  s.add_development_dependency %qadonttagmea, \"~> 1.1.0\"\n  s.add_runtime_dependency %q{strange{name}(just){-}<for>{-}{testing}}.freeze, [\">= 1.2.4\".freeze, \"< 1.4\".freeze]\n  s.add_runtime_dependency(\"net-ssh\", \">= 1.0.1\")\n  s.add_runtime_dependency(%q<ed25519>.freeze, [\">= 1.2.4\".freeze, \"< 1.4\".freeze])\n  s.add_runtime_dependency(%q<strange<name>just-for-testing>.freeze, [\">= 1.2.4\".freeze, \"< 1.4\".freeze])\nend\n"
  },
  {
    "path": "Units/parser-go.r/github-issue-2430.d/README",
    "content": "THis is a carsh test.\nSpecifying --kinds-Go=f makes tags output empty.\n\n"
  },
  {
    "path": "Units/parser-go.r/github-issue-2430.d/args.ctags",
    "content": "--kinds-GO=f\n"
  },
  {
    "path": "Units/parser-go.r/github-issue-2430.d/expected.tags",
    "content": "main\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\n"
  },
  {
    "path": "Units/parser-go.r/github-issue-2430.d/input.go",
    "content": "// Taken from an issue #2430 opened by @aleb\npackage main\n\ntype Interval struct {\n        Start, Stop string\n}\n\nfunc main() {\n}\n"
  },
  {
    "path": "Units/parser-go.r/github-issue-2430.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-anonmember.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-go.r/go-anonmember.d/expected.tags",
    "content": "X\tinput.go\t/^type X struct {$/;\"\ts\nT1\tinput.go\t/^\tT1$/;\"\tM\tstruct:X\ttyperef:typename:T1\nT2\tinput.go\t/^\t*T2$/;\"\tM\tstruct:X\ttyperef:typename:*T2\nT3\tinput.go\t/^\tP.T3$/;\"\tM\tstruct:X\ttyperef:typename:P.T3\nT4\tinput.go\t/^\t*P.T4$/;\"\tM\tstruct:X\ttyperef:typename:*P.T4\nage\tinput.go\t/^\tage T5$/;\"\tm\tstruct:X\ttyperef:typename:T5\nskill\tinput.go\t/^\tskill *T6$/;\"\tm\tstruct:X\ttyperef:typename:*T6\naddress\tinput.go\t/^\taddress, hometown T7$/;\"\tm\tstruct:X\ttyperef:typename:T7\nhometown\tinput.go\t/^\taddress, hometown T7$/;\"\tm\tstruct:X\ttyperef:typename:T7\nnatualLang\tinput.go\t/^\tnatualLang,programmingLang *T8$/;\"\tm\tstruct:X\ttyperef:typename:*T8\nprogrammingLang\tinput.go\t/^\tnatualLang,programmingLang *T8$/;\"\tm\tstruct:X\ttyperef:typename:*T8\nperson\tinput.go\t/^\tperson P.T9$/;\"\tm\tstruct:X\ttyperef:typename:P.T9\nparent\tinput.go\t/^\tparent *P.T10$/;\"\tm\tstruct:X\ttyperef:typename:*P.T10\nlang1\tinput.go\t/^\tlang1, lang2 P.LANG$/;\"\tm\tstruct:X\ttyperef:typename:P.LANG\nlang2\tinput.go\t/^\tlang1, lang2 P.LANG$/;\"\tm\tstruct:X\ttyperef:typename:P.LANG\nlang3\tinput.go\t/^\tlang3, lang4 *P.LANG$/;\"\tm\tstruct:X\ttyperef:typename:*P.LANG\nlang4\tinput.go\t/^\tlang3, lang4 *P.LANG$/;\"\tm\tstruct:X\ttyperef:typename:*P.LANG\nQ\tinput.go\t/^\tP.Q$/;\"\tM\tstruct:X\ttyperef:typename:P.Q\nQ\tinput.go\t/^\t*P.Q$/;\"\tM\tstruct:X\ttyperef:typename:*P.Q\nY\tinput.go\t/^type Y struct {$/;\"\ts\nbyte\tinput.go\t/^\tbyte$/;\"\tM\tstruct:Y\ttyperef:typename:byte\nb\tinput.go\t/^\tb byte$/;\"\tm\tstruct:Y\ttyperef:typename:byte\nss\tinput.go\t/^\tss []string$/;\"\tm\tstruct:Y\ttyperef:typename:[]string\nbss\tinput.go\t/^\tbss [][]byte$/;\"\tm\tstruct:Y\ttyperef:typename:[][]byte\nf\tinput.go\t/^\tf func() error$/;\"\tm\tstruct:Y\ttyperef:typename:func() error\nifaces\tinput.go\t/^\tifaces []interface{}$/;\"\tm\tstruct:Y\ttyperef:typename:[]interface{}\ntags\tinput.go\t/^\ttags  map[string]struct{}$/;\"\tm\tstruct:Y\ttyperef:typename:map[string]struct{}\nnotify\tinput.go\t/^\tnotify chan<- struct{}$/;\"\tm\tstruct:Y\ttyperef:typename:chan<- struct{}\np\tinput.go\t/^\tp *struct {$/;\"\tm\tstruct:Y\ttyperef:typename:*struct { x int; y int; z int; }\n"
  },
  {
    "path": "Units/parser-go.r/go-anonmember.d/input.go",
    "content": "type X struct {\n\tT1\n\t*T2\n\tP.T3\n\t*P.T4\n\tage T5\n\tskill *T6\n\taddress, hometown T7\n\tnatualLang,programmingLang *T8\n\tperson P.T9\n\tparent *P.T10\n\tlang1, lang2 P.LANG\n\tlang3, lang4 *P.LANG\n\tP.Q\n\t*P.Q\n}\n\ntype Y struct {\n\tbyte\n\tb byte\n\tss []string\n\tbss [][]byte\n\tf func() error\n\tifaces []interface{}\n\ttags  map[string]struct{}\n\tnotify chan<- struct{}\n\tp *struct {\n\t\tx int\n\t\ty int\n\t\tz int\n\t}\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-crash-issue-2220.d/args.ctags",
    "content": "--fields=nksSaf\n--file-scope=yes\n--sort=no\n--kinds-go=picsmtfv\n"
  },
  {
    "path": "Units/parser-go.r/go-crash-issue-2220.d/expected.tags",
    "content": "temp\tinput.go\t/^package temp$/;\"\tp\tline:2\n"
  },
  {
    "path": "Units/parser-go.r/go-crash-issue-2220.d/input.go",
    "content": "// Taken fro #2220 reported by @epheien\npackage temp\ntype Symbol = int\n"
  },
  {
    "path": "Units/parser-go.r/go-crash-issue-2220.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-dont-solve-type-for-underscore-var.d/expected.tags",
    "content": "main\tinput.go\t/^func main () {$/;\"\tf\tpackage:main\nmain\tinput.go\t/^package main$/;\"\tp\n"
  },
  {
    "path": "Units/parser-go.r/go-dont-solve-type-for-underscore-var.d/input.go",
    "content": "package main\n\nvar (\n\t_ int   = 1\n)\n\nfunc main () {\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-dont-solve-type-for-underscore-var.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-end-field-for-types.d/args.ctags",
    "content": "--sort=no\n--fields=+{end}\n"
  },
  {
    "path": "Units/parser-go.r/go-end-field-for-types.d/expected.tags",
    "content": "A\tinput.go\t/^package A$/;\"\tp\nPoint\tinput.go\t/^\tPoint struct {$/;\"\ts\tpackage:A\tend:7\nX\tinput.go\t/^\t\tX int$/;\"\tm\tstruct:A.Point\ttyperef:typename:int\nY\tinput.go\t/^\t\tY int$/;\"\tm\tstruct:A.Point\ttyperef:typename:int\nPoint3D\tinput.go\t/^\tPoint3D struct {$/;\"\ts\tpackage:A\tend:12\nX\tinput.go\t/^\t\tX int$/;\"\tm\tstruct:A.Point3D\ttyperef:typename:int\nY\tinput.go\t/^\t\tY int$/;\"\tm\tstruct:A.Point3D\ttyperef:typename:int\nZ\tinput.go\t/^\t\tZ int$/;\"\tm\tstruct:A.Point3D\ttyperef:typename:int\nRange\tinput.go\t/^type Range struct {$/;\"\ts\tpackage:A\tend:18\nstart\tinput.go\t/^\tstart int$/;\"\tm\tstruct:A.Range\ttyperef:typename:int\nend\tinput.go\t/^\tend int$/;\"\tm\tstruct:A.Range\ttyperef:typename:int\ns\tinput.go\t/^var s, t =$/;\"\tv\tpackage:A\nt\tinput.go\t/^var s, t =$/;\"\tv\tpackage:A\n"
  },
  {
    "path": "Units/parser-go.r/go-end-field-for-types.d/input.go",
    "content": "package A\n\ntype (\n\tPoint struct {\n\t\tX int\n\t\tY int\n\t}\n\tPoint3D struct {\n\t\tX int\n\t\tY int\n\t\tZ int\n\t}\n)\n\ntype Range struct {\n\tstart int\n\tend int\n}\n\nvar s, t =\n\tPoint {X: 3, Y: 8},\n\tPoint {X: 3, Y: 8}\n"
  },
  {
    "path": "Units/parser-go.r/go-end-field-for-types.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-funcs.d/args.ctags",
    "content": "--fields=+Se\n--kinds-Go=+R\n--fields-Go=+{receiver}\n"
  },
  {
    "path": "Units/parser-go.r/go-funcs.d/expected.tags",
    "content": "T\tinput.go\t/^type T int$/;\"\tt\tpackage:main\ttyperef:typename:int\tend:19\nf1\tinput.go\t/^func f1() {$/;\"\tf\tpackage:main\tsignature:()\tend:6\nf2\tinput.go\t/^func f2(a int) {$/;\"\tf\tpackage:main\tsignature:(a int)\tend:9\nf3\tinput.go\t/^func f3(a int) string {$/;\"\tf\tpackage:main\ttyperef:typename:string\tsignature:(a int)\tend:13\nf4\tinput.go\t/^func f4(a, b, c <-chan int, d, e, f string) (A, B, C int, D string) {$/;\"\tf\tpackage:main\ttyperef:typename:(A, B, C int, D string)\tsignature:(a, b, c <-chan int, d, e, f string)\tend:17\nf5\tinput.go\t/^func (t *T) f5(\\/* comment *\\/ a, \\/*comment*\\/ \\/*comment*\\/       b string, $/;\"\tf\ttype:main.T\ttyperef:typename:(int, string)\tsignature:(a, b string, c []int)\tend:24\treceiver:t\nf6\tinput.go\t/^func (t *(T)) f6(r struct {a int `foo`; b string `bar`}) net.IP {$/;\"\tf\ttype:main.T\ttyperef:typename:net.IP\tsignature:(r struct {a int `foo`; b string `bar`})\tend:28\treceiver:t\nmain\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\tsignature:()\tend:31\nmain\tinput.go\t/^package main$/;\"\tp\nt\tinput.go\t/^func (t *(T)) f6(r struct {a int `foo`; b string `bar`}) net.IP {$/;\"\tR\tfunc:main.T.f6\ttyperef:typename:T\nt\tinput.go\t/^func (t *T) f5(\\/* comment *\\/ a, \\/*comment*\\/ \\/*comment*\\/       b string, $/;\"\tR\tfunc:main.T.f5\ttyperef:typename:T\n"
  },
  {
    "path": "Units/parser-go.r/go-funcs.d/input.go",
    "content": "package main\n\nimport \"net\"\n\nfunc f1() {\n}\n\nfunc f2(a int) {\n}\n\nfunc f3(a int) string {\n\treturn \"\"\n}\n\nfunc f4(a, b, c <-chan int, d, e, f string) (A, B, C int, D string) {\n\treturn 1, 2, 3, \"\"\n}\n\ntype T int\n\nfunc (t *T) f5(/* comment */ a, /*comment*/ /*comment*/       b string, \n\tc  \t\t[]int) (  /* */ int, string ) {\n\treturn 1, \"\"\n}\n\nfunc (t *(T)) f6(r struct {a int `foo`; b string `bar`}) net.IP {\n\treturn net.IP{}\n}\n\nfunc main() {\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-funcs.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-goroutines.d/args.ctags",
    "content": "--fields=+S\n"
  },
  {
    "path": "Units/parser-go.r/go-goroutines.d/expected.tags",
    "content": "f\tinput.go\t/^func f(from string) {$/;\"\tf\tpackage:main\tsignature:(from string)\nmain\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\tsignature:()\nmain\tinput.go\t/^package main$/;\"\tp\n"
  },
  {
    "path": "Units/parser-go.r/go-goroutines.d/input.go",
    "content": "/* https://gobyexample.com/goroutines\n * Copyright (C) Mark McGranaghan CC-BY 3.0\n * https://github.com/mmcgrana/gobyexample#license */\n// A _goroutine_ is a lightweight thread of execution.\n\npackage main\n\nimport \"fmt\"\n\nfunc f(from string) {\n    for i := 0; i < 3; i++ {\n        fmt.Println(from, \":\", i)\n    }\n}\n\nfunc main() {\n\n    // Suppose we have a function call `f(s)`. Here's how\n    // we'd call that in the usual way, running it\n    // synchronously.\n    f(\"direct\")\n\n    // To invoke this function in a goroutine, use\n    // `go f(s)`. This new goroutine will execute\n    // concurrently with the calling one.\n    go f(\"goroutine\")\n\n    // You can also start a goroutine for an anonymous\n    // function call.\n    go func(msg string) {\n        fmt.Println(msg)\n    }(\"going\")\n\n    // Our two goroutines are running asynchronously in\n    // separate goroutines now, so execution falls through\n    // to here. This `Scanln` code requires we press a key\n    // before the program exits.\n    var input string\n    fmt.Scanln(&input)\n    fmt.Println(\"done\")\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-goroutines.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-helloworld.d/args.ctags",
    "content": "--fields=+S\n"
  },
  {
    "path": "Units/parser-go.r/go-helloworld.d/expected.tags",
    "content": "main\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\tsignature:()\nmain\tinput.go\t/^package main$/;\"\tp\n"
  },
  {
    "path": "Units/parser-go.r/go-helloworld.d/input.go",
    "content": "/* from https://gobyexample.com/hello-world\n * Copyright (C) Mark McGranaghan CC-BY 3.0\n * https://github.com/mmcgrana/gobyexample#license */\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n    fmt.Println(\"hello world\")\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-helloworld.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-ignore-underscore-var.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-go.r/go-ignore-underscore-var.d/expected.tags",
    "content": "main\tinput.go\t/^package main$/;\"\tp\nF\tinput.go\t/^func F() (int, int) {$/;\"\tf\tpackage:main\ttyperef:typename:(int, int)\nx0\tinput.go\t/^var x0, y0 = F()$/;\"\tv\tpackage:main\ny0\tinput.go\t/^var x0, y0 = F()$/;\"\tv\tpackage:main\nx\tinput.go\t/^var x, _ = F()$/;\"\tv\tpackage:main\nmain\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\n"
  },
  {
    "path": "Units/parser-go.r/go-ignore-underscore-var.d/input.go",
    "content": "package main\n\nfunc F() (int, int) {\n\treturn 1, 2\n}\n\nvar x0, y0 = F()\nvar x, _ = F()\nfunc main() {\n\tprint (x)\n\treturn\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-ignore-underscore-var.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/args.ctags",
    "content": "--fields=+rK\n--extras=+r\n--fields-Go=+{howImported}\n--sort=no\n\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/expected.tags",
    "content": "main\tinput.go\t/^package main$/;\"\tpackage\troles:def\nfmt\tinput.go\t/^import \"fmt\"$/;\"\tpackage\troles:imported\nmain\tinput.go\t/^func main() {$/;\"\tfunc\tpackage:main\troles:def\nmain\tinput-0.go\t/^package main$/;\"\tpackage\troles:def\nf\tinput-0.go\t/^import f \"fmt\"$/;\"\tpackageName\troles:def\tpackage:fmt\nfmt\tinput-0.go\t/^import f \"fmt\"$/;\"\tpackage\troles:imported\tpackageName:f\nmain\tinput-0.go\t/^func main() {$/;\"\tfunc\tpackage:main\troles:def\nmain\tinput-1.go\t/^package main$/;\"\tpackage\troles:def\nfmt\tinput-1.go\t/^\t\"fmt\"$/;\"\tpackage\troles:imported\nmain\tinput-1.go\t/^func main() {$/;\"\tfunc\tpackage:main\troles:def\nmain\tinput-2.go\t/^package main$/;\"\tpackage\troles:def\nf\tinput-2.go\t/^\tf \"fmt\"$/;\"\tpackageName\troles:def\tpackage:fmt\nfmt\tinput-2.go\t/^\tf \"fmt\"$/;\"\tpackage\troles:imported\tpackageName:f\nmain\tinput-2.go\t/^func main() {$/;\"\tfunc\tpackage:main\troles:def\nmain\tinput-3.go\t/^package main$/;\"\tpackage\troles:def\ntime\tinput-3.go\t/^\t\"time\"$/;\"\tpackage\troles:imported\nfmt\tinput-3.go\t/^\t\"fmt\"$/;\"\tpackage\troles:imported\nmain\tinput-3.go\t/^func main() {$/;\"\tfunc\tpackage:main\troles:def\nmain\tinput-4.go\t/^package main$/;\"\tpackage\troles:def\nt\tinput-4.go\t/^\tt \"time\"$/;\"\tpackageName\troles:def\tpackage:time\ntime\tinput-4.go\t/^\tt \"time\"$/;\"\tpackage\troles:imported\tpackageName:t\nfmt\tinput-4.go\t/^\t\"fmt\"$/;\"\tpackage\troles:imported\nmain\tinput-4.go\t/^func main() {$/;\"\tfunc\tpackage:main\troles:def\nmain\tinput-5.go\t/^package main$/;\"\tpackage\troles:def\ntime\tinput-5.go\t/^\t\"time\"$/;\"\tpackage\troles:imported\nf\tinput-5.go\t/^\tf \"fmt\"$/;\"\tpackageName\troles:def\tpackage:fmt\nfmt\tinput-5.go\t/^\tf \"fmt\"$/;\"\tpackage\troles:imported\tpackageName:f\nmain\tinput-5.go\t/^func main() {$/;\"\tfunc\tpackage:main\troles:def\nmain\tinput-6.go\t/^package main$/;\"\tpackage\troles:def\nt\tinput-6.go\t/^\tt \"time\"$/;\"\tpackageName\troles:def\tpackage:time\ntime\tinput-6.go\t/^\tt \"time\"$/;\"\tpackage\troles:imported\tpackageName:t\nf\tinput-6.go\t/^\tf \"fmt\"$/;\"\tpackageName\troles:def\tpackage:fmt\nfmt\tinput-6.go\t/^\tf \"fmt\"$/;\"\tpackage\troles:imported\tpackageName:f\nmain\tinput-6.go\t/^func main() {$/;\"\tfunc\tpackage:main\troles:def\nmain\tinput-7.go\t/^package main$/;\"\tpackage\troles:def\nfmt\tinput-7.go\t/^\t. \"fmt\"$/;\"\tpackage\troles:imported\thowImported:inline\ntime\tinput-7.go\t/^\t_ \"time\"$/;\"\tpackage\troles:imported\thowImported:init\nmain\tinput-7.go\t/^func main() {$/;\"\tfunc\tpackage:main\troles:def\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/input-0.go",
    "content": "package main\nimport f \"fmt\"\nfunc main() {\n\tf.Println(\"Hello, World!\")\n}\n\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/input-1.go",
    "content": "package main\nimport (\n\t\"fmt\"\n)\n\nfunc main() {\n\tfmt.Println(\"Hello, World!\")\n}\n\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/input-2.go",
    "content": "package main\nimport (\n\tf \"fmt\"\n)\n\nfunc main() {\n\tf.Println(\"Hello, World!\")\n}\n\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/input-3.go",
    "content": "package main\nimport (\n\t\"time\"\n\t\"fmt\"\n)\nfunc main() {\n\tfmt.Println(\"<%s> Hello, World!\", t.Now(()\n}\n\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/input-4.go",
    "content": "package main\nimport (\n\tt \"time\"\n\t\"fmt\"\n)\nfunc main() {\n\tfmt.Println(\"<%s> Hello, World!\", t.Now(()\n}\n\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/input-5.go",
    "content": "package main\nimport (\n\t\"time\"\n\tf \"fmt\"\n)\nfunc main() {\n\tf.Println(\"<%s> Hello, World!\", time.Now(()\n}\n\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/input-6.go",
    "content": "package main\nimport (\n\tt \"time\"\n\tf \"fmt\"\n)\nfunc main() {\n\tf.Println(\"<%s> Hello, World!\", t.Now(()\n}\n\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/input-7.go",
    "content": "package main\nimport (\n\t. \"fmt\"\n\t_ \"time\"\n)\n\nfunc main() {\n\tPrintln(\"Hello, World!\")\n}\n\n"
  },
  {
    "path": "Units/parser-go.r/go-import.d/input.go",
    "content": "package main\nimport \"fmt\"\nfunc main() {\n\tfmt.Println(\"Hello, World!\")\n}\n\n"
  },
  {
    "path": "Units/parser-go.r/go-incomplete-func.d/input.go",
    "content": "func ()\n"
  },
  {
    "path": "Units/parser-go.r/go-incomplete-input.d/args.ctags",
    "content": "--fields=+S\n"
  },
  {
    "path": "Units/parser-go.r/go-incomplete-input.d/input.go",
    "content": "var (a,"
  },
  {
    "path": "Units/parser-go.r/go-interface.d/README",
    "content": "File(s) under \"src\" directory is/are used as a test input for ctags.\nThe file(s) is/are needed to compile \"input.go\".\n\n"
  },
  {
    "path": "Units/parser-go.r/go-interface.d/args.ctags",
    "content": "--sort=no\n--fields=+{typeref}{inherits}{signature}{scope}{kind}{end}K\n"
  },
  {
    "path": "Units/parser-go.r/go-interface.d/expected.tags",
    "content": "main\tinput.go\t/^package main$/;\"\tkind:package\nBuffer\tinput.go\t/^type Buffer interface {$/;\"\tkind:interface\tscope:package:main\tend:11\nLocker\tinput.go\t/^type Locker interface {$/;\"\tkind:interface\tscope:package:main\tend:16\nLock\tinput.go\t/^\tLock()$/;\"\tkind:methodSpec\tscope:interface:main.Locker\tsignature:()\nUnlock\tinput.go\t/^\tUnlock()$/;\"\tkind:methodSpec\tscope:interface:main.Locker\tsignature:()\nReadWriter\tinput.go\t/^type ReadWriter interface {$/;\"\tkind:interface\tscope:package:main\tend:21\nRead\tinput.go\t/^\tRead(b Buffer) bool$/;\"\tkind:methodSpec\tscope:interface:main.ReadWriter\ttyperef:typename:bool\tsignature:(b Buffer)\nWrite\tinput.go\t/^\tWrite(b Buffer) bool$/;\"\tkind:methodSpec\tscope:interface:main.ReadWriter\ttyperef:typename:bool\tsignature:(b Buffer)\nFile\tinput.go\t/^type File interface {$/;\"\tkind:interface\tscope:package:main\tinherits:ReadWriter,Locker,ext.Processor\tend:29\nClose\tinput.go\t/^\tClose()$/;\"\tkind:methodSpec\tscope:interface:main.File\tsignature:()\nListAttr\tinput.go\t/^\tListAttr() ([][]byte, error)$/;\"\tkind:methodSpec\tscope:interface:main.File\ttyperef:typename:([][]byte, error)\tsignature:()\nmain\tinput.go\t/^func main () {$/;\"\tkind:func\tscope:package:main\tsignature:()\tend:32\n"
  },
  {
    "path": "Units/parser-go.r/go-interface.d/input.go",
    "content": "//\n// Taken from https://golang.org/ref/spec#Interface_types\n//\n// GOPATH=$SOMEWHERE/ctags/Units/parser-go.r/go-interface.d go run $SOMEWHERE/ctags/Units/parser-go.r/go-interface.d/input.go\n//\npackage main\n\nimport \"ext\"\n\ntype Buffer interface {\n}\n\ntype Locker interface {\n\tLock()\n\tUnlock()\n}\n\ntype ReadWriter interface {\n\tRead(b Buffer) bool\n\tWrite(b Buffer) bool\n}\n\ntype File interface {\n\tReadWriter  // same as adding the methods of ReadWriter\n\tLocker      // same as adding the methods of Locker\n\text.Processor\n\tClose()\n\tListAttr() ([][]byte, error)\n}\n\nfunc main () {\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-interface.d/src/ext/iface.go",
    "content": "package ext\n\ntype Processor interface  {\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-op-less-than.d/args.ctags",
    "content": "--fields=+S\n"
  },
  {
    "path": "Units/parser-go.r/go-op-less-than.d/expected.tags",
    "content": "f1\tinput.go\t/^func f1(a int, b int) int {$/;\"\tf\tpackage:test\ttyperef:typename:int\tsignature:(a int, b int)\nf2\tinput.go\t/^func f2(a int, b int) int {$/;\"\tf\tpackage:test\ttyperef:typename:int\tsignature:(a int, b int)\nf3\tinput.go\t/^func f3() {}$/;\"\tf\tpackage:test\tsignature:()\ntest\tinput.go\t/^package test$/;\"\tp\n"
  },
  {
    "path": "Units/parser-go.r/go-op-less-than.d/input.go",
    "content": "package test\n\nfunc f1(a int, b int) int {\n  if a </* }\n  func bug() { */ 42 {\n    return 1\n  }\n  return a\n}\n\nfunc f2(a int, b int) int {\n  return a + b\n}\n\nfunc f3() {}\n"
  },
  {
    "path": "Units/parser-go.r/go-op-less-than.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-scope.d/args.ctags",
    "content": "--extras=+q\n--sort=no\n\n"
  },
  {
    "path": "Units/parser-go.r/go-scope.d/expected.tags",
    "content": "main\tinput.go\t/^package main$/;\"\tp\nPoint\tinput.go\t/^type Point struct { X, Y int }$/;\"\ts\tpackage:main\nmain.Point\tinput.go\t/^type Point struct { X, Y int }$/;\"\ts\tpackage:main\nX\tinput.go\t/^type Point struct { X, Y int }$/;\"\tm\tstruct:main.Point\ttyperef:typename:int\nmain.Point.X\tinput.go\t/^type Point struct { X, Y int }$/;\"\tm\tstruct:main.Point\ttyperef:typename:int\nY\tinput.go\t/^type Point struct { X, Y int }$/;\"\tm\tstruct:main.Point\ttyperef:typename:int\nmain.Point.Y\tinput.go\t/^type Point struct { X, Y int }$/;\"\tm\tstruct:main.Point\ttyperef:typename:int\nRender\tinput.go\t/^func (p *Point) Render() {$/;\"\tf\tstruct:main.Point\nmain.Point.Render\tinput.go\t/^func (p *Point) Render() {$/;\"\tf\tstruct:main.Point\nmain\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\nmain.main\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\ndoNothing0\tinput.go\t/^func (*Point) doNothing0() {$/;\"\tf\tstruct:main.Point\nmain.Point.doNothing0\tinput.go\t/^func (*Point) doNothing0() {$/;\"\tf\tstruct:main.Point\ndoNothing1\tinput.go\t/^func (Point) doNothing1() {$/;\"\tf\tstruct:main.Point\nmain.Point.doNothing1\tinput.go\t/^func (Point) doNothing1() {$/;\"\tf\tstruct:main.Point\nwrongSyntax0\tinput.go\t/^func () wrongSyntax0() {$/;\"\tf\tpackage:main\nmain.wrongSyntax0\tinput.go\t/^func () wrongSyntax0() {$/;\"\tf\tpackage:main\nwrongSyntax1\tinput.go\t/^func (+) wrongSyntax1() {$/;\"\tf\tpackage:main\nmain.wrongSyntax1\tinput.go\t/^func (+) wrongSyntax1() {$/;\"\tf\tpackage:main\nwrongSyntax2\tinput.go\t/^func (a-) wrongSyntax2() {$/;\"\tf\tunknown:main.a\nmain.a.wrongSyntax2\tinput.go\t/^func (a-) wrongSyntax2() {$/;\"\tf\tunknown:main.a\n"
  },
  {
    "path": "Units/parser-go.r/go-scope.d/input.go",
    "content": "package main\nimport (\n\t\"fmt\"\n)\n\ntype Point struct { X, Y int }\n\nfunc (p *Point) Render() {\n\tfmt.Printf(\"<%d,%d>\\n\", p.X, p.Y)\n}\n\nfunc main() {\n\tp := &Point{X: 5, Y: 12}\n\tp.Render()\n}\n\nfunc (*Point) doNothing0() {\n}\n\nfunc (Point) doNothing1() {\n}\n\nfunc () wrongSyntax0() {\n}\n\nfunc (+) wrongSyntax1() {\n}\n\nfunc (a-) wrongSyntax2() {\n}\n\nfunc (brokenInput\n"
  },
  {
    "path": "Units/parser-go.r/go-timeouts.d/args.ctags",
    "content": "--fields=+S\n"
  },
  {
    "path": "Units/parser-go.r/go-timeouts.d/expected.tags",
    "content": "main\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\tsignature:()\nmain\tinput.go\t/^package main$/;\"\tp\n"
  },
  {
    "path": "Units/parser-go.r/go-timeouts.d/input.go",
    "content": "/* from https://gobyexample.com/timeouts\n * Copyright (C) Mark McGranaghan CC-BY 3.0\n * https://github.com/mmcgrana/gobyexample#license */\n// _Timeouts_ are important for programs that connect to\n// external resources or that otherwise need to bound\n// execution time. Implementing timeouts in Go is easy and\n// elegant thanks to channels and `select`.\n\npackage main\n\nimport \"time\"\nimport \"fmt\"\n\nfunc main() {\n\n    // For our example, suppose we're executing an external\n    // call that returns its result on a channel `c1`\n    // after 2s.\n    c1 := make(chan string, 1)\n    go func() {\n        time.Sleep(time.Second * 2)\n        c1 <- \"result 1\"\n    }()\n\n    // Here's the `select` implementing a timeout.\n    // `res := <-c1` awaits the result and `<-Time.After`\n    // awaits a value to be sent after the timeout of\n    // 1s. Since `select` proceeds with the first\n    // receive that's ready, we'll take the timeout case\n    // if the operation takes more than the allowed 1s.\n    select {\n    case res := <-c1:\n        fmt.Println(res)\n    case <-time.After(time.Second * 1):\n        fmt.Println(\"timeout 1\")\n    }\n\n    // If we allow a longer timeout of 3s, then the receive\n    // from `c2` will succeed and we'll print the result.\n    c2 := make(chan string, 1)\n    go func() {\n        time.Sleep(time.Second * 2)\n        c2 <- \"result 2\"\n    }()\n    select {\n    case res := <-c2:\n        fmt.Println(res)\n    case <-time.After(time.Second * 3):\n        fmt.Println(\"timeout 2\")\n    }\n}\n\n// todo: cancellation?\n\n"
  },
  {
    "path": "Units/parser-go.r/go-timeouts.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-torture.d/args.ctags",
    "content": "--fields=+Se\n"
  },
  {
    "path": "Units/parser-go.r/go-torture.d/expected.tags",
    "content": "A\tinput.go\t/^const (A = iota;B;C;$/;\"\tc\tpackage:main\nB\tinput.go\t/^const (A = iota;B;C;$/;\"\tc\tpackage:main\nC\tinput.go\t/^const (A = iota;B;C;$/;\"\tc\tpackage:main\nD\tinput.go\t/^\tD = iota << (1 + iota*2)$/;\"\tc\tpackage:main\nE\tinput.go\t/^\tE$/;\"\tc\tpackage:main\nF\tinput.go\t/^\tF=3.14*(1+2*3)\\/34e7;I=1)$/;\"\tc\tpackage:main\nG\tinput.go\t/^const ignored int*\\/const (G=6); var g int$/;\"\tc\tpackage:main\nH\tinput.go\t/^func (tt * T7) f4(a func () func ()) (func (), int) {return func (){}, 1};func f5(){};const H=1$/;\"\tc\tpackage:main\nI\tinput.go\t/^\tF=3.14*(1+2*3)\\/34e7;I=1)$/;\"\tc\tpackage:main\nReader\tinput.go\t/^\t\tReader()$/;\"\tn\tinterface:main.T5\tsignature:()\nT1\tinput.go\t/^\tT1 `annotation`$/;\"\tM\tstruct:main.T6\ttyperef:typename:T1\nT1\tinput.go\t/^\tT1 map[string]int$/;\"\tt\tpackage:main\ttyperef:typename:map[string]int\tend:6\nT2\tinput.go\t/^\t*T2$/;\"\tM\tstruct:main.T6\ttyperef:typename:*T2\nT2\tinput.go\t/^\tT2 <-chan float32$/;\"\tt\tpackage:main\ttyperef:typename:<-chan float32\tend:7\nT3\tinput.go\t/^\tT3 chan []string$/;\"\tt\tpackage:main\ttyperef:typename:chan []string\tend:8\nT4\tinput.go\t/^\tT4 chan<- *[12]string$/;\"\tt\tpackage:main\ttyperef:typename:chan<- *[12]string\tend:9\nT5\tinput.go\t/^\tT5 interface {$/;\"\ti\tpackage:main\tend:14\nT6\tinput.go\t/^type T6 struct {$/;\"\ts\tpackage:main\tend:24\nT7\tinput.go\t/^type (T7 func (a struct{_ int; _ float32}, b int) (int, map[string]int);T8 float32)$/;\"\tt\tpackage:main\ttyperef:typename:func (a struct{_ int; _ float32}, b int) (int, map[string]int)\tend:31\nT8\tinput.go\t/^type (T7 func (a struct{_ int; _ float32}, b int) (int, map[string]int);T8 float32)$/;\"\tt\tpackage:main\ttyperef:typename:float32\tend:31\nT9\tinput.go\t/^func f1() {};func f2() {};type\\/*no newline here*\\/T9 int\\/*var ignored int$/;\"\tt\tpackage:main\ttyperef:typename:int\tend:39\nWriter\tinput.go\t/^\t\tWriter()$/;\"\tn\tinterface:main.T5\tsignature:()\n_a\tinput.go\t/^\t_a, _b, _c, _d int$/;\"\tm\tstruct:main.T6\ttyperef:typename:int\n_b\tinput.go\t/^\t_a, _b, _c, _d int$/;\"\tm\tstruct:main.T6\ttyperef:typename:int\n_c\tinput.go\t/^\t_a, _b, _c, _d int$/;\"\tm\tstruct:main.T6\ttyperef:typename:int\n_d\tinput.go\t/^\t_a, _b, _c, _d int$/;\"\tm\tstruct:main.T6\ttyperef:typename:int\n_e\tinput.go\t/^\t_e float32$/;\"\tm\tstruct:main.T6\ttyperef:typename:float32\na\tinput.go\t/^var (a, b, c int$/;\"\tv\tpackage:main\ttyperef:typename:int\nb\tinput.go\t/^var (a, b, c int$/;\"\tv\tpackage:main\ttyperef:typename:int\nc\tinput.go\t/^var (a, b, c int$/;\"\tv\tpackage:main\ttyperef:typename:int\nd\tinput.go\t/^d T5$/;\"\tv\tpackage:main\ttyperef:interface:T5\ne\tinput.go\t/^e T4$/;\"\tv\tpackage:main\ttyperef:type:T4\nf\tinput.go\t/^f interface{})$/;\"\tv\tpackage:main\ttyperef:typename:interface{}\nf1\tinput.go\t/^func f1() {};func f2() {};type\\/*no newline here*\\/T9 int\\/*var ignored int$/;\"\tf\tpackage:main\tsignature:()\tend:38\nf2\tinput.go\t/^func f1() {};func f2() {};type\\/*no newline here*\\/T9 int\\/*var ignored int$/;\"\tf\tpackage:main\tsignature:()\tend:38\nf3\tinput.go\t/^func (t *T1) f3() (a, b int){$/;\"\tf\ttype:main.T1\ttyperef:typename:(a, b int)\tsignature:()\tend:43\nf4\tinput.go\t/^func (tt * T7) f4(a func () func ()) (func (), int) {return func (){}, 1};func f5(){};const H=1$/;\"\tf\ttype:main.T7\ttyperef:typename:(func (), int)\tsignature:(a func () func ())\tend:45\nf5\tinput.go\t/^func (tt * T7) f4(a func () func ()) (func (), int) {return func (){}, 1};func f5(){};const H=1$/;\"\tf\tpackage:main\tsignature:()\tend:45\nfoo\tinput.go\t/^\t\tfoo()$/;\"\tn\tinterface:main.T5\tsignature:()\ng\tinput.go\t/^const ignored int*\\/const (G=6); var g int$/;\"\tv\tpackage:main\ttyperef:typename:int\nh\tinput.go\t/^}; var h int$/;\"\tv\tpackage:main\ttyperef:typename:int\nint\tinput.go\t/^\tint$/;\"\tM\tstruct:main.T6\ttyperef:typename:int\nmain\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\tsignature:()\tend:50\nmain\tinput.go\t/^package main$/;\"\tp\n"
  },
  {
    "path": "Units/parser-go.r/go-torture.d/input.go",
    "content": "package main\n\nimport \"fmt\"\n\ntype (\n\tT1 map[string]int\n\tT2 <-chan float32\n\tT3 chan []string\n\tT4 chan<- *[12]string\n\tT5 interface {\n\t\tReader()\n\t\tWriter()\n\t\tfoo()\n\t}\n)\n\ntype T6 struct {\n\t_a, _b, _c, _d int\n\tint\n\tT1 `annotation`\n\t*T2\n\t_e float32\n\t//ignored int\n}\n\nconst (A = iota;B;C;\n\tD = iota << (1 + iota*2)\n\tE\n\tF=3.14*(1+2*3)/34e7;I=1)\n\ntype (T7 func (a struct{_ int; _ float32}, b int) (int, map[string]int);T8 float32)\n\nvar (a, b, c int\nd T5\ne T4\nf interface{})\n\nfunc f1() {};func f2() {};type/*no newline here*/T9 int/*var ignored int\nconst ignored int*/const (G=6); var g int\n\nfunc (t *T1) f3() (a, b int){\n\treturn 1, 2\n}; var h int\n\nfunc (tt * T7) f4(a func () func ()) (func (), int) {return func (){}, 1};func f5(){};const H=1\n\nfunc main() {\n\tgo func (){}()\n\tfmt.Println(\"Hello, 世界\")\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-torture.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-type-aliases.d/args.ctags",
    "content": "--sort=no\n--fields=+e\n\n"
  },
  {
    "path": "Units/parser-go.r/go-type-aliases.d/expected.tags",
    "content": "main\tinput.go\t/^package main$/;\"\tp\ny\tinput.go\t/^type y int$/;\"\tt\tpackage:main\ttyperef:typename:int\tend:4\nT2\tinput.go\t/^type T2 int$/;\"\tt\tpackage:main\ttyperef:typename:int\tend:5\nt\tinput.go\t/^type t y$/;\"\tt\tpackage:main\ttyperef:typename:y\tend:7\nT1\tinput.go\t/^type T1 = T2$/;\"\ta\tpackage:main\ttyperef:typename:T2\tend:8\nName1\tinput.go\t/^type Name1 map[string]string$/;\"\tt\tpackage:main\ttyperef:typename:map[string]string\tend:9\nName2\tinput.go\t/^type Name2 map[string]string$/;\"\tt\tpackage:main\ttyperef:typename:map[string]string\tend:10\nAlias\tinput.go\t/^type Alias = map[string]string$/;\"\ta\tpackage:main\ttyperef:typename:map[string]string\tend:11\nX\tinput.go\t/^type X =$/;\"\ta\tpackage:main\ttyperef:typename:map [ string;] string\tend:16\nmain\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\tend:20\n"
  },
  {
    "path": "Units/parser-go.r/go-type-aliases.d/input.go",
    "content": "// Taken from https://go.googlesource.com/proposal/+/master/design/18130-type-alias.md\npackage main\n\ntype y int\ntype T2 int\n\ntype t y\ntype T1 = T2\ntype Name1 map[string]string\ntype Name2 map[string]string\ntype Alias = map[string]string\n\ntype X =\n\tmap [\n\tstring\n] string\n\nfunc main() {\n\treturn;\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-variadic-dots-broken.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-go.r/go-variadic-dots-broken.d/input.go",
    "content": "package main\n\nfunc f0(nums..int) {\n\treturn\n}\n\nfunc f1(nums  ..\tinterface{}) {\n\treturn\n}\n\nfunc f10(nums..\tinterface{}) {\n\treturn\n}\n\nfunc f11(nums  ..interface{}) {\n\treturn\n}\n\nfunc f2(o int, nums ..int) {\n\treturn\n}\n\nfunc f3(o int, nums..  /* .. */\t\tint) {\n\treturn\n}\n\nfunc f4(o              int,          p   int) {\n}\n\nfunc main() {\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-variadic-dots.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-go.r/go-variadic-dots.d/expected.tags",
    "content": "main\tinput.go\t/^package main$/;\"\tp\nf0\tinput.go\t/^func f0(nums...int) {$/;\"\tf\tpackage:main\tsignature:(nums ...int)\nf1\tinput.go\t/^func f1(nums  ...\tinterface{}) {$/;\"\tf\tpackage:main\tsignature:(nums ...interface{})\nf10\tinput.go\t/^func f10(nums...\tinterface{}) {$/;\"\tf\tpackage:main\tsignature:(nums ...interface{})\nf11\tinput.go\t/^func f11(nums  ...interface{}) {$/;\"\tf\tpackage:main\tsignature:(nums ...interface{})\nf2\tinput.go\t/^func f2(o int, nums ...int) {$/;\"\tf\tpackage:main\tsignature:(o int, nums ...int)\nf3\tinput.go\t/^func f3(o int, nums...  \\/* ... *\\/\t\tint) {$/;\"\tf\tpackage:main\tsignature:(o int, nums ...int)\nf4\tinput.go\t/^func f4(o              int,          p   int) {$/;\"\tf\tpackage:main\tsignature:(o int, p int)\nmain\tinput.go\t/^func main() {$/;\"\tf\tpackage:main\tsignature:()\n"
  },
  {
    "path": "Units/parser-go.r/go-variadic-dots.d/input.go",
    "content": "package main\n\nfunc f0(nums...int) {\n\treturn\n}\n\nfunc f1(nums  ...\tinterface{}) {\n\treturn\n}\n\nfunc f10(nums...\tinterface{}) {\n\treturn\n}\n\nfunc f11(nums  ...interface{}) {\n\treturn\n}\n\nfunc f2(o int, nums ...int) {\n\treturn\n}\n\nfunc f3(o int, nums...  /* ... */\t\tint) {\n\treturn\n}\n\nfunc f4(o              int,          p   int) {\n}\n\nfunc main() {\n}\n"
  },
  {
    "path": "Units/parser-go.r/go-variadic-dots.d/validator",
    "content": "go\n"
  },
  {
    "path": "Units/parser-go.r/go-vars.d/args.ctags",
    "content": "--sort=no\n--fields=+t\n"
  },
  {
    "path": "Units/parser-go.r/go-vars.d/expected.tags",
    "content": "x\tinput.go\t/^var x, y, z int$/;\"\tv\ttyperef:typename:int\ny\tinput.go\t/^var x, y, z int$/;\"\tv\ttyperef:typename:int\nz\tinput.go\t/^var x, y, z int$/;\"\tv\ttyperef:typename:int\na\tinput.go\t/^\ta, b int$/;\"\tv\ttyperef:typename:int\nb\tinput.go\t/^\ta, b int$/;\"\tv\ttyperef:typename:int\nn\tinput.go\t/^\tn = 0$/;\"\tv\ns\tinput.go\t/^\ts string$/;\"\tv\ttyperef:typename:string\ni\tinput.go\t/^\ti interface{}$/;\"\tv\ttyperef:typename:interface{}\nc\tinput.go\t/^const c int$/;\"\tc\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-go.r/go-vars.d/input.go",
    "content": "var x, y, z int\nvar (\n\ta, b int\n\tn = 0\n\ts string\n\ti interface{}\n)\nconst c int\n"
  },
  {
    "path": "Units/parser-gperf.r/simple.d/args.ctags",
    "content": "--sort=no\n--extras=+rg\n"
  },
  {
    "path": "Units/parser-gperf.r/simple.d/expected.tags",
    "content": "resolved_gperf_hash\tinput.perf\t/^%define hash-function-name resolved_gperf_hash$/;\"\th\nresolved_gperf_lookup\tinput.perf\t/^%define lookup-function-name resolved_gperf_lookup$/;\"\tl\nMyNameSpace::MyClass\tinput.perf\t/^%define class-name MyNameSpace::MyClass$/;\"\tc\nHUP\tinput.perf\t/^HUP, 1$/;\"\tk\nINT\tinput.perf\t/^INT, 2$/;\"\tk\nQUIT\tinput.perf\t/^QUIT, 3$/;\"\tk\nILL\tinput.perf\t/^ILL, 4$/;\"\tk\nTRAP\tinput.perf\t/^TRAP, 5$/;\"\tk\nABRT\tinput.perf\t/^ABRT, 6$/;\"\tk\nBUS\tinput.perf\t/^BUS, 7$/;\"\tk\nFPE\tinput.perf\t/^FPE, 8$/;\"\tk\nKILL\tinput.perf\t/^KILL, 9$/;\"\tk\nUSR1\tinput.perf\t/^USR1, 10$/;\"\tk\nSEGV\tinput.perf\t/^SEGV, 11$/;\"\tk\nUSR2\tinput.perf\t/^USR2, 12$/;\"\tk\nPIPE\tinput.perf\t/^PIPE, 13$/;\"\tk\nALRM\tinput.perf\t/^ALRM, 14$/;\"\tk\nTERM\tinput.perf\t/^TERM, 15$/;\"\tk\nSTKFLT\tinput.perf\t/^STKFLT, 16$/;\"\tk\nCHLD\tinput.perf\t/^CHLD, 17$/;\"\tk\nCONT\tinput.perf\t/^CONT, 18$/;\"\tk\nSTOP\tinput.perf\t/^STOP, 19$/;\"\tk\nTSTP\tinput.perf\t/^TSTP, 20$/;\"\tk\nTTIN\tinput.perf\t/^TTIN, 21$/;\"\tk\nTTOU\tinput.perf\t/^TTOU, 22$/;\"\tk\nURG\tinput.perf\t/^URG, 23$/;\"\tk\nXCPU\tinput.perf\t/^XCPU, 24$/;\"\tk\nXFSZ\tinput.perf\t/^XFSZ, 25$/;\"\tk\nVTALRM\tinput.perf\t/^VTALRM, 26$/;\"\tk\nPROF\tinput.perf\t/^PROF, 27$/;\"\tk\nWINCH\tinput.perf\t/^WINCH, 28$/;\"\tk\nIO\tinput.perf\t/^IO, 29$/;\"\tk\nPWR\tinput.perf\t/^PWR, 30$/;\"\tk\nSYS\tinput.perf\t/^SYS, 31$/;\"\tk\nRTMIN\tinput.perf\t/^RTMIN, 34$/;\"\tk\nRTMIN+1\tinput.perf\t/^RTMIN+1, 35$/;\"\tk\nRTMIN+2\tinput.perf\t/^RTMIN+2, 36$/;\"\tk\nRTMIN+3\tinput.perf\t/^RTMIN+3, 37$/;\"\tk\nRTMIN+4\tinput.perf\t/^RTMIN+4, 38$/;\"\tk\nRTMIN+5\tinput.perf\t/^RTMIN+5, 39$/;\"\tk\nRTMIN+6\tinput.perf\t/^RTMIN+6, 40$/;\"\tk\nRTMIN+7\tinput.perf\t/^RTMIN+7, 41$/;\"\tk\nRTMIN+8\tinput.perf\t/^RTMIN+8, 42$/;\"\tk\nRTMIN+9\tinput.perf\t/^RTMIN+9, 43$/;\"\tk\nRTMIN+10\tinput.perf\t/^RTMIN+10, 44$/;\"\tk\nRTMIN+11\tinput.perf\t/^RTMIN+11, 45$/;\"\tk\nRTMIN+12\tinput.perf\t/^RTMIN+12, 46$/;\"\tk\nRTMIN+13\tinput.perf\t/^RTMIN+13, 47$/;\"\tk\nRTMIN+14\tinput.perf\t/^RTMIN+14, 48$/;\"\tk\nRTMIN+15\tinput.perf\t/^RTMIN+15, 49$/;\"\tk\nRTMAX-14\tinput.perf\t/^RTMAX-14, 50$/;\"\tk\nRTMAX-13\tinput.perf\t/^RTMAX-13, 51$/;\"\tk\nRTMAX-12\tinput.perf\t/^RTMAX-12, 52$/;\"\tk\nRTMAX-11\tinput.perf\t/^RTMAX-11, 53$/;\"\tk\nRTMAX-10\tinput.perf\t/^RTMAX-10, 54$/;\"\tk\nRTMAX-9\tinput.perf\t/^RTMAX-9, 55$/;\"\tk\nRTMAX-8\tinput.perf\t/^RTMAX-8, 56$/;\"\tk\nRTMAX-7\tinput.perf\t/^RTMAX-7, 57$/;\"\tk\nRTMAX-6\tinput.perf\t/^RTMAX-6, 58$/;\"\tk\nRTMAX-5\tinput.perf\t/^RTMAX-5, 59$/;\"\tk\nRTMAX-4\tinput.perf\t/^RTMAX-4, 60$/;\"\tk\nRTMAX-3\tinput.perf\t/^RTMAX-3, 61$/;\"\tk\nRTMAX-2\tinput.perf\t/^RTMAX-2, 62$/;\"\tk\nRTMAX-1\tinput.perf\t/^RTMAX-1, 63$/;\"\tk\nRTMAX\tinput.perf\t/^RTMAX, 64$/;\"\tk\n_GNU_SOURCE\tinput.perf\t/^#define _GNU_SOURCE$/;\"\td\tfile:\nconfig.h\tinput.perf\t/^#include <config.h>/;\"\th\nstddef.h\tinput.perf\t/^#include <stddef.h>/;\"\th\nstdlib.h\tinput.perf\t/^#include <stdlib.h>/;\"\th\nutils.h\tinput.perf\t/^#include \"utils.h\"/;\"\th\nsignal_s\tinput.perf\t/^struct signal_s$/;\"\ts\tfile:\nname\tinput.perf\t/^  int name;$/;\"\tm\tstruct:signal_s\ttyperef:typename:int\tfile:\nvalue\tinput.perf\t/^  int value;$/;\"\tm\tstruct:signal_s\ttyperef:typename:int\tfile:\nsender_s\tinput.perf\t/^  struct sender_s {$/;\"\ts\tstruct:signal_s\tfile:\npid\tinput.perf\t/^     pid_t pid; \\/*$/;\"\tm\tstruct:signal_s::sender_s\ttyperef:typename:pid_t\tfile:\ncomm\tinput.perf\t/^     char comm[16];$/;\"\tm\tstruct:signal_s::sender_s\ttyperef:typename:char[16]\tfile:\nsender\tinput.perf\t/^  } sender;$/;\"\tm\tstruct:signal_s\ttyperef:struct:signal_s::sender_s\tfile:\nstr2sig\tinput.perf\t/^str2sig (const char *name)$/;\"\tf\ttyperef:typename:int\nkconf_id_hash\tinput-0.gperf\t/^%define hash-function-name kconf_id_hash$/;\"\th\nkconf_id_lookup\tinput-0.gperf\t/^%define lookup-function-name kconf_id_lookup$/;\"\tl\nkconf_id_strings\tinput-0.gperf\t/^%define string-pool-name kconf_id_strings$/;\"\ts\nmainmenu\tinput-0.gperf\t/^mainmenu,\tT_MAINMENU,\tTF_COMMAND$/;\"\tk\nmenu\tinput-0.gperf\t/^menu,\t\tT_MENU,\t\tTF_COMMAND$/;\"\tk\nEXPORT_SYMBOL\tinput-1.perf\t/^EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW$/;\"\tk\nresword\tinput-1.perf\t/^struct resword { const char *name; int token; }$/;\"\ts\tfile:\nname\tinput-1.perf\t/^struct resword { const char *name; int token; }$/;\"\tm\tstruct:resword\ttyperef:typename:const char *\tfile:\ntoken\tinput-1.perf\t/^struct resword { const char *name; int token; }$/;\"\tm\tstruct:resword\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-gperf.r/simple.d/input-0.gperf",
    "content": "/* Taken from\n   https://kernel.googlesource.com/pub/scm/linux/kernel/git/konrad/xen/+/stable/for-linus-3.10-rc5-tag/scripts/kconfig/zconf.gperf */\n%language=ANSI-C\n%define hash-function-name kconf_id_hash\n%define lookup-function-name kconf_id_lookup\n%define string-pool-name kconf_id_strings\n%compare-strncmp\n%enum\n%pic\n%struct-type\nstruct kconf_id;\nstatic const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);\n%%\nmainmenu,\tT_MAINMENU,\tTF_COMMAND\nmenu,\t\tT_MENU,\t\tTF_COMMAND\n%%\n"
  },
  {
    "path": "Units/parser-gperf.r/simple.d/input-1.perf",
    "content": "/* Derrived from\n   https://kernel.googlesource.com/pub/scm/linux/kernel/git/dhowells/linux-asm_system/+/refs/tags/v2.6.15-rc7/scripts/genksyms/keywords.gperf */\n%{\n%}\nstruct resword { const char *name; int token; }\n%%\nEXPORT_SYMBOL, EXPORT_SYMBOL_KEYW\n"
  },
  {
    "path": "Units/parser-gperf.r/simple.d/input.perf",
    "content": "/* Derrived FROM crun-1.4.4/src/libcrun/signals.perf\n   and systemd/src/resolve/resolved-gperf.gperf */\n/*\n * crun - OCI runtime written in C\n *\n * Copyright (C) 2017, 2018, 2019 Giuseppe Scrivano <giuseppe@scrivano.org>\n * crun is free software; you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * crun is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with crun.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n%{\n#define _GNU_SOURCE\n\n#include <config.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include \"utils.h\"\n%}\nstruct signal_s\n{\n  int name;\n  int value;\n  struct sender_s {\n     pid_t pid; /*\n}\n%%\n*/\n     char comm[16];\n  } sender;\n};\n%null_strings\n%language=ANSI-C\n%define slot-name section_and_lvalue\n%define hash-function-name resolved_gperf_hash\n%define lookup-function-name resolved_gperf_lookup\n%define class-name MyNameSpace::MyClass\n%readonly-tables\n%omit-struct-type\n%struct-type\n%includes\n%%\nHUP, 1\nINT, 2\nQUIT, 3\nILL, 4\nTRAP, 5\nABRT, 6\nBUS, 7\nFPE, 8\nKILL, 9\nUSR1, 10\nSEGV, 11\nUSR2, 12\nPIPE, 13\n#IGNOREME\nALRM, 14\nTERM, 15\nSTKFLT, 16\nCHLD, 17\nCONT, 18\nSTOP, 19\nTSTP, 20\nTTIN, 21\nTTOU, 22\nURG, 23\nXCPU, 24\nXFSZ, 25\nVTALRM, 26\nPROF, 27\nWINCH, 28\nIO, 29\nPWR, 30\nSYS, 31\nRTMIN, 34\nRTMIN+1, 35\nRTMIN+2, 36\nRTMIN+3, 37\nRTMIN+4, 38\nRTMIN+5, 39\nRTMIN+6, 40\nRTMIN+7, 41\nRTMIN+8, 42\nRTMIN+9, 43\nRTMIN+10, 44\nRTMIN+11, 45\nRTMIN+12, 46\nRTMIN+13, 47\nRTMIN+14, 48\nRTMIN+15, 49\nRTMAX-14, 50\nRTMAX-13, 51\nRTMAX-12, 52\nRTMAX-11, 53\nRTMAX-10, 54\nRTMAX-9, 55\nRTMAX-8, 56\nRTMAX-7, 57\nRTMAX-6, 58\nRTMAX-5, 59\nRTMAX-4, 60\nRTMAX-3, 61\nRTMAX-2, 62\nRTMAX-1, 63\nRTMAX, 64\n%%\nint\nstr2sig (const char *name)\n{\n  const struct signal_s *s;\n\n  if (has_prefix (name, \"SIG\"))\n    name += 3;\n\n  s = libcrun_signal_in_word_set (name, strlen (name));\n  if (s == NULL)\n    {\n      long int value;\n\n      errno = 0;\n      value = strtol (name, NULL, 10);\n      if (errno == 0)\n        return value;\n\n      errno = ENOENT;\n      return -1;\n    }\n\n  return s->value;\n}\n"
  },
  {
    "path": "Units/parser-haskell.r/literate-haskell1.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-haskell.r/literate-haskell1.d/expected.tags",
    "content": "main\tinput.lhs\t/^> main = do putStr \"Enter a number: \"$/;\"\tf\nfact\tinput.lhs\t/^> fact 0 = 1$/;\"\tf\nfact\tinput.lhs\t/^> fact n = n * fact (n-1)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-haskell.r/literate-haskell1.d/input.lhs",
    "content": ">Without space, this is just a comment\n\n   This literate program prompts the user for a number\n   and prints the factorial of that number:\n\n> main :: IO ()\n\n> main = do putStr \"Enter a number: \"\n>           l <- readLine\n>           putStr \"n!= \"\n>           print (fact (read l))\n          \n  This is the factorial function.\n\n> fact :: Integer -> Integer\n> fact 0 = 1\n> fact n = n * fact (n-1)\n\n"
  },
  {
    "path": "Units/parser-haskell.r/literate-haskell2.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-haskell.r/literate-haskell2.d/expected.tags",
    "content": "main\tinput.lhs\t/^main =  print [ (n, product [1..n]) | n <- [1..20]]$/;\"\tf\n"
  },
  {
    "path": "Units/parser-haskell.r/literate-haskell2.d/input.lhs",
    "content": "\\documentstyle{article}\n\n\\begin{document}\n\n\\section{Introduction}\n\nThis is a trivial program that prints the first 20 factorials.\n\n\\begin{code}\nmain :: IO ()\nmain =  print [ (n, product [1..n]) | n <- [1..20]]\n\\end{code}\n\n\\end{document}\n\n"
  },
  {
    "path": "Units/parser-haskell.r/multi-line-type-signature.d/README",
    "content": "Taken from #4013 submitted by Robin Palotai (@robinp).\n"
  },
  {
    "path": "Units/parser-haskell.r/multi-line-type-signature.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-haskell.r/multi-line-type-signature.d/expected.tags",
    "content": "Foo\tinput.hs\t/^module Foo () where$/;\"\tm\nthing\tinput.hs\t/^thing x = pure x$/;\"\tf\n"
  },
  {
    "path": "Units/parser-haskell.r/multi-line-type-signature.d/input.hs",
    "content": "module Foo () where\n\n\nthing\n    :: App m\n    => Int\n    -> m Int\nthing x = pure x\n\n"
  },
  {
    "path": "Units/parser-haskell.r/simple-haskell.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-haskell.r/simple-haskell.d/expected.tags",
    "content": "Cards\tinput.hs\t/^module Cards where$/;\"\tm\nInt\tinput.hs\t/^data Int = -2147483648 | -2147483647 | ... | -1 | 0 | 1 | 2 | ... | 2147483647$/;\"\tt\nFd\tinput.hs\t/^newtype Fd = Fd CInt$/;\"\tt\nFd\tinput.hs\t/^newtype Fd = Fd CInt$/;\"\tc\nBool\tinput.hs\t/^data Bool $/;\"\tt\nTrue\tinput.hs\t/^  = True | False$/;\"\tc\nFalse\tinput.hs\t/^  = True | False$/;\"\tc\nName\tinput.hs\t/^type Name = String$/;\"\tt\ngetSpareBuffer\tinput.hs\t/^getSpareBuffer Handle__{haCharBuffer=ref, $/;\"\tf\nadd\tinput.hs\t/^add x y  = x + y$/;\"\tf\n"
  },
  {
    "path": "Units/parser-haskell.r/simple-haskell.d/input.hs",
    "content": "module Cards where\n\ndata Int = -2147483648 | -2147483647 | ... | -1 | 0 | 1 | 2 | ... | 2147483647\nnewtype Fd = Fd CInt\ndata Bool \n  = True | False\ntype Name = String\n\n\ngetSpareBuffer :: Handle__ -> IO (BufferMode, CharBuffer)\ngetSpareBuffer Handle__{haCharBuffer=ref, \n                    haBuffers=spare_ref,\n                    haBufferMode=mode}\n = do\n   case mode of\n     NoBuffering -> return (mode, error \"no buffer!\")\n     _ -> do\n          bufs <- readIORef spare_ref\n          buf  <- readIORef ref\n          case bufs of\n            BufferListCons b rest -> do\n                writeIORef spare_ref rest\n                return ( mode, emptyBuffer b (bufSize buf) WriteBuffer)\n            BufferListNil -> do\n                new_buf <- newCharBuffer (bufSize buf) WriteBuffer\n                return (mode, new_buf)\n\n\n{-|\n  This is a docstring\n-}\nadd :: Integer -> Integer -> Integer\nadd x y  = x + y\n"
  },
  {
    "path": "Units/parser-html.r/class-and-id.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-html.r/class-and-id.d/expected.tags",
    "content": "Home &middot; Universal Ctags\tinput.html\t/^  <\\/title>$/;\"\tj\troles:def\n/public/css/poole.css\tinput.html\t/^<link rel=\"stylesheet\" href=\"\\/public\\/css\\/poole.css\">$/;\"\tC\troles:extFile\n/public/css/syntax.css\tinput.html\t/^<link rel=\"stylesheet\" href=\"\\/public\\/css\\/syntax.css\">$/;\"\tC\troles:extFile\n/public/css/hyde.css\tinput.html\t/^<link rel=\"stylesheet\" href=\"\\/public\\/css\\/hyde.css\">$/;\"\tC\troles:extFile\nhttp://fonts.googleapis.com/css?family=PT+Sans:400,400italic,700|Abril+Fatface\tinput.html\t/^<link rel=\"stylesheet\" href=\"http:\\/\\/fonts.googleapis.com\\/css?family=PT+Sans:400,400italic,700/;\"\tC\troles:extFile\ntheme-base-0d\tinput.html\t/^<body class=\"theme-base-0d\">$/;\"\tc\troles:attribute\nsidebar\tinput.html\t/^<div class=\"sidebar\">$/;\"\tc\troles:attribute\ncontainer\tinput.html\t/^<div class=\"container sidebar-sticky\">$/;\"\tc\troles:attribute\nsidebar-sticky\tinput.html\t/^<div class=\"container sidebar-sticky\">$/;\"\tc\troles:attribute\nsidebar-about\tinput.html\t/^<div class=\"sidebar-about\">$/;\"\tc\troles:attribute\nUniversal Ctags\tinput.html\t/^<h1>Universal Ctags<\\/h1>$/;\"\th\troles:def\nlead\tinput.html\t/^<p class=\"lead\">A maintained ctags implementation<\\/p>$/;\"\tc\troles:attribute\nsidebar-nav\tinput.html\t/^<ul class=\"sidebar-nav\">$/;\"\tc\troles:attribute\nsidebar-nav-item\tinput.html\t/^<li class=\"sidebar-nav-item active\">$/;\"\tc\troles:attribute\nactive\tinput.html\t/^<li class=\"sidebar-nav-item active\">$/;\"\tc\troles:attribute\nsidebar-nav-item\tinput.html\t/^<li class=\"sidebar-nav-item\"><a href=\"http:\\/\\/docs.ctags.io\\/en\\/latest\\/\">Docs<\\/a><\\/li>$/;\"\tc\troles:attribute\nsidebar-nav-item\tinput.html\t/^<li class=\"sidebar-nav-item\"><a href=\"\\/blog\\/\">Blog<\\/a><\\/li>$/;\"\tc\troles:attribute\nsidebar-nav-item\tinput.html\t/^<li class=\"sidebar-nav-item\"><a href=\"https:\\/\\/github.com\\/universal-ctags\\/ctags\">GitHub proje/;\"\tc\troles:attribute\ncontent\tinput.html\t/^<div class=\"content container\">$/;\"\tc\troles:attribute\ncontainer\tinput.html\t/^<div class=\"content container\">$/;\"\tc\troles:attribute\nuniversal-ctags\tinput.html\t/^<h1 id=\"universal-ctags\">Universal Ctags<\\/h1>$/;\"\tI\troles:def\nUniversal Ctags\tinput.html\t/^<h1 id=\"universal-ctags\">Universal Ctags<\\/h1>$/;\"\th\troles:def\nget-involved\tinput.html\t/^<h2 id=\"get-involved\">Get Involved<\\/h2>$/;\"\tI\troles:def\nGet Involved\tinput.html\t/^<h2 id=\"get-involved\">Get Involved<\\/h2>$/;\"\ti\troles:def\n"
  },
  {
    "path": "Units/parser-html.r/class-and-id.d/input.html",
    "content": "<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en-us\">\n<head>\n<link href=\"http://gmpg.org/xfn/11\" rel=\"profile\">\n<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n<meta name=\"generator\" content=\"Jekyll v3.0.3\">\n<meta name=\"description\" content=\"A maintained ctags implementation\">\n\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1\">\n<title>\n    \n      Home &middot; Universal Ctags\n    \n  </title>\n\n<link rel=\"stylesheet\" href=\"/public/css/poole.css\">\n<link rel=\"stylesheet\" href=\"/public/css/syntax.css\">\n<link rel=\"stylesheet\" href=\"/public/css/hyde.css\">\n<link rel=\"stylesheet\" href=\"http://fonts.googleapis.com/css?family=PT+Sans:400,400italic,700|Abril+Fatface\">\n\n<link rel=\"apple-touch-icon-precomposed\" sizes=\"144x144\" href=\"/public/apple-touch-icon-144-precomposed.png\">\n<link rel=\"shortcut icon\" href=\"/public/favicon.ico\">\n\n<link rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS\" href=\"/atom.xml\">\n</head>\n<body class=\"theme-base-0d\">\n<div class=\"sidebar\">\n<div class=\"container sidebar-sticky\">\n<div class=\"sidebar-about\">\n<h1>Universal Ctags</h1>\n<p class=\"lead\">A maintained ctags implementation</p>\n</div>\n<ul class=\"sidebar-nav\">\n<li class=\"sidebar-nav-item active\">\n<a href=\"/\">Home</a>\n</li>\n<li class=\"sidebar-nav-item\"><a href=\"http://docs.ctags.io/en/latest/\">Docs</a></li>\n<li class=\"sidebar-nav-item\"><a href=\"/blog/\">Blog</a></li>\n<li class=\"sidebar-nav-item\"><a href=\"https://github.com/universal-ctags/ctags\">GitHub project</a></li>\n</ul>\n<p>&copy; 2016. All rights reserved.</p>\n</div>\n</div>\n<div class=\"content container\">\n<h1 id=\"universal-ctags\">Universal Ctags</h1>\n<p>universal-ctags has the objective of continuing the development from what existed\nin the Sourceforge area. Github exuberant-ctags repository was started by Reza\nJelveh and was later moved to the universal-ctags organization.</p>\n<p>The goal of the project is preparing and maintaining common/unified space where\npeople interested in making ctags better can work together.</p>\n<h2 id=\"get-involved\">Get Involved</h2>\n<p>We’d love to have additional help maintaining ctags! Here’s a few specific things\nyou can do to help us:</p>\n<ul>\n<li>You can take a look at the <a href=\"https://github.com/universal-ctags/ctags/pulls\">pull requests</a> and review the proposed changes.</li>\n<li>Our <a href=\"https://github.com/universal-ctags/ctags/tree/master/docs\">Hacking Guide</a> contains a lot of information on how to build and test ctags.</li>\n<li>You can <a href=\"https://github.com/universal-ctags/ctags/issues\">find an issue</a> to work on and submit your own pull request.</li>\n<li>You can <a href=\"https://github.com/universal-ctags/ctags/issues/354\">help us package ctags</a> for different platforms.</li>\n</ul>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "Units/parser-html.r/class-and-id.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/parser-html.r/comment-in-js-2.d/args.ctags",
    "content": "--sort=no\n--fields=+l\n--extras=+g\n"
  },
  {
    "path": "Units/parser-html.r/comment-in-js-2.d/expected.tags",
    "content": "HTML comments in JS\tinput.html\t/^<title>HTML comments in JS<\\/title>$/;\"\tj\tlanguage:HTML\nHTML comments in JS\tinput.html\t/^  <h1>HTML comments in JS<\\/h1>$/;\"\th\tlanguage:HTML\nfunc1\tinput.html\t/^function func1() {}; <!-- function bug2() {}$/;\"\tf\tlanguage:JavaScript\nfunc2\tinput.html\t/^function func2() {};$/;\"\tf\tlanguage:JavaScript\na\tinput.html\t/^let a = 1;$/;\"\tv\tlanguage:JavaScript\nb\tinput.html\t/^let b = a --> (function anonfunc1() { return 0; })();$/;\"\tv\tlanguage:JavaScript\nanonfunc1\tinput.html\t/^let b = a --> (function anonfunc1() { return 0; })();$/;\"\tf\tlanguage:JavaScript\nfunc3\tinput.html\t/^function func3() {}; \\/\\/ test for parser internal$/;\"\tf\tlanguage:JavaScript\nfunc4\tinput.html\t/^a --> 0; function func4() {}$/;\"\tf\tlanguage:JavaScript\nc\tinput.html\t/^let c = 1;$/;\"\tv\tlanguage:JavaScript\nfunc5\tinput.html\t/^function func5() {};$/;\"\tf\tlanguage:JavaScript\nd\tinput.html\t/^let d = c<!42;$/;\"\tv\tlanguage:JavaScript\nfunc6\tinput.html\t/^function func6() {};$/;\"\tf\tlanguage:JavaScript\ne\tinput.html\t/^let e = c<!-42;$/;\"\tv\tlanguage:JavaScript\nfunc7\tinput.html\t/^function func7() {};$/;\"\tf\tlanguage:JavaScript\n"
  },
  {
    "path": "Units/parser-html.r/comment-in-js-2.d/input.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>HTML comments in JS</title>\n<script language=\"JavaScript\">\n<!-- function bug1() {}\nfunction func1() {}; <!-- function bug2() {}\nfunction func2() {};\n--> function bug3() {}\nlet a = 1;\nlet b = a --> (function anonfunc1() { return 0; })();\nconsole.log(b); // true, because above should have read as \"let b = (a--) > 0\"\nfunction func3() {}; // test for parser internal\n--> function bug4() {}\na --> 0; function func4() {}\n\n/* just to cover all related logic in the parser (basically backup code paths) */\nlet c = 1;\n--c;\nfunction func5() {};\nlet d = c<!42;\nfunction func6() {};\nlet e = c<!-42;\nfunction func7() {};\n\nfunc4();\n</script>\n<body>\n  <h1>HTML comments in JS</h1>\n  <p>\n    See <a href=\"https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-html-like-comments\">ECMA-262 Annex B.1.1 HTML-like Comments</a>\n    and <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features#html_comments\">MDN's JavaScript Reference of Deprecated Features</a>.\n  </p>\n  <p>\n    In a nutshell, <code>&lt;!--</code> behaves the same as <code>//</code> (single-line) comments.\n    <code>--&gt;</code> behaves the same, but only at the start of a line (only allowing whitespaces and comments before).\n  </p>\n</body>\n</html>\n"
  },
  {
    "path": "Units/parser-html.r/comment-in-js.d/args.ctags",
    "content": "--sort=no\n--fields=+l\n--extras=+g\n"
  },
  {
    "path": "Units/parser-html.r/comment-in-js.d/expected.tags",
    "content": "simple_anchor\tinput.html\t/^  <a name=\"simple_anchor\"><\\/a>$/;\"\ta\tlanguage:HTML\nunquoted_anchor\tinput.html\t/^  <a name=unquoted_anchor><\\/a>$/;\"\ta\tlanguage:HTML\nprefixed_anchor\tinput.html\t/^  <a title=\"Title\" name=\"prefixed_anchor\"><\\/a>$/;\"\ta\tlanguage:HTML\npostfixed_anchor\tinput.html\t/^  <a name=postfixed_anchor href=\"http:\\/\\/darrenhiebert.com\"><\\/a>$/;\"\ta\tlanguage:HTML\nmessage\tinput.html\t/^function message()$/;\"\tf\tlanguage:JavaScript\n"
  },
  {
    "path": "Units/parser-html.r/comment-in-js.d/input.html",
    "content": "<html >\n<head>\n<script language=\"Javascript\" src=\"./test.js\"></script> \n<script language=\"JavaScript\">\n<!--\n\n//\tfunction commented_function1 () {}\n/* \n\tfunction commented_function2 () {} \n*/\n\nfunction message()\n{\n      alert( \"Hello.\");     \n}\n\n//-->\n</script>\n<body>\n  <a name=\"simple_anchor\"></a>\n  <a name=unquoted_anchor></a>\n  <a title=\"Title\" name=\"prefixed_anchor\"></a>\n  <a name=postfixed_anchor href=\"http://darrenhiebert.com\"></a>\n  <!-- <a name=\"commented_anchor\"></a> -->\n</body>\n</html>\n\n\n\n"
  },
  {
    "path": "Units/parser-html.r/comment-starter-in-script.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+Kl\n"
  },
  {
    "path": "Units/parser-html.r/comment-starter-in-script.d/expected.tags",
    "content": "Foo\tinput.html\t/^<h1>Foo<\\/h1>$/;\"\theading1\tlanguage:HTML\nBAR\tinput.html\t/^<h1>BAR<\\/h1>$/;\"\theading1\tlanguage:HTML\nx\tinput.html\t/^  var x/;\"\tvariable\tlanguage:JavaScript\n"
  },
  {
    "path": "Units/parser-html.r/comment-starter-in-script.d/input.html",
    "content": "<h1>Foo</h1>\n<script>\n  // <!--\n  var x\n</script>\n<h1>BAR</h1>\n"
  },
  {
    "path": "Units/parser-html.r/external-files.html.d/args.ctags",
    "content": "--sort=no\n--extras=+gr\n--fields=+r\n"
  },
  {
    "path": "Units/parser-html.r/external-files.html.d/expected.tags",
    "content": "A.css\tinput.html\t/^    <link href=\"A.css\" rel=\"stylesheet\" media=\"print\">$/;\"\tC\troles:extFile\nB.css\tinput.html\t/^    <link rel=\"stylesheet\" media=\"print\" href=\"B.css\">$/;\"\tC\troles:extFile\nC.css\tinput.html\t/^    <link media=\"print\" href=\"C.css\" rel=\"stylesheet\">$/;\"\tC\troles:extFile\nhttps://cdn.jsdelivr.net/npm/vue\tinput.html\t/^    <script src=\"https:\\/\\/cdn.jsdelivr.net\\/npm\\/vue\"><\\/script>$/;\"\tJ\troles:extFile\nD.css\tinput.html\t/^    <link rel=\"stylesheet\" href=\"D.css\" media=\"print\">$/;\"\tC\troles:extFile\nE.css\tinput.html\t/^    <link href=\"E.css\" media=\"print\" rel=\"stylesheet\">$/;\"\tC\troles:extFile\nF.css\tinput.html\t/^    <link media=\"print\" rel=\"stylesheet\" href=\"F.css\">$/;\"\tC\troles:extFile\njs/three.min.js\tinput.html\t/^    <script type=\"text\\/javascript\" src=\"js\\/three.min.js\"><\\/script>$/;\"\tJ\troles:extFile\ni\tinput.html\t/^      var i;$/;\"\tv\troles:def\nj\tinput.html\t/var j;/;\"\tv\troles:def\n"
  },
  {
    "path": "Units/parser-html.r/external-files.html.d/input.html",
    "content": "<html>\n  <head>\n    <link href=\"A.css\" rel=\"stylesheet\" media=\"print\">\n    <link rel=\"stylesheet\" media=\"print\" href=\"B.css\">\n    <link media=\"print\" href=\"C.css\" rel=\"stylesheet\">\n    <script src=\"https://cdn.jsdelivr.net/npm/vue\"></script>\n    <link rel=\"stylesheet\" href=\"D.css\" media=\"print\">\n    <script>\n      var i;\n      for (i = 0; i < 2; i++) {\n         console.log (\"hello\");\n      }\n    </script>\n    <link href=\"E.css\" media=\"print\" rel=\"stylesheet\">\n    <script>var j;</script>\n    <link media=\"print\" rel=\"stylesheet\" href=\"F.css\">\n    <script></script>\n    <script/>\n    <script type=\"text/javascript\" src=\"js/three.min.js\"></script>\n  </head>\n</html>\n"
  },
  {
    "path": "Units/parser-html.r/external-files.html.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/parser-html.r/jsp-with-bom.d/README",
    "content": "JSP tags shouldn't trigger the PHP parser.\n\nThis used to happen and trigger an infinite loop of a ping-pong effect\nwith the HTML parser asking the PHP parser to parse the JSP block, and\nthe PHP parser, not recognizing the input, asking the HTML one to deal\nwith it.  Rinse and repeat.\n"
  },
  {
    "path": "Units/parser-html.r/jsp-with-bom.d/args.ctags",
    "content": "--sort=no\n--extras='*'\n"
  },
  {
    "path": "Units/parser-html.r/jsp-with-bom.d/input.html",
    "content": "﻿<%=\n"
  },
  {
    "path": "Units/parser-html.r/jsp.d/README",
    "content": "JSP tags shouldn't trigger the PHP parser.\n\nThis used to happen and trigger an infinite loop of a ping-pong effect\nwith the HTML parser asking the PHP parser to parse the JSP block, and\nthe PHP parser, not recognizing the input, asking the HTML one to deal\nwith it.  Rinse and repeat.\n"
  },
  {
    "path": "Units/parser-html.r/jsp.d/args.ctags",
    "content": "--sort=no\n--extras='*'\n"
  },
  {
    "path": "Units/parser-html.r/jsp.d/input.html",
    "content": "<%=\n"
  },
  {
    "path": "Units/parser-html.r/script.html.d/args.ctags",
    "content": "--extras=+g\n"
  },
  {
    "path": "Units/parser-html.r/script.html.d/expected.tags",
    "content": "i\tinput.html\t/^      var i;$/;\"\tv\nj\tinput.html\t/var j;/;\"\tv\n"
  },
  {
    "path": "Units/parser-html.r/script.html.d/input.html",
    "content": "<html>\n  <head>\n    <script>\n      var i;\n      for (i = 0; i < 2; i++) {\n         console.log (\"hello\");\n      }\n    </script>\n    <script>var j;</script>\n    <script></script>\n    <script/>\n  </head>\n</html>\n"
  },
  {
    "path": "Units/parser-html.r/script.html.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/parser-html.r/simple.html.t/args.ctags",
    "content": "--extras=+g\n--fields=+l\n\n"
  },
  {
    "path": "Units/parser-html.r/simple.html.t/expected.tags",
    "content": "#firstname\tinput.html\t/#firstname { background-color: yellow;}/;\"\ti\tlanguage:CSS\n.intro\tinput.html\t/^.intro { $/;\"\tc\tlanguage:CSS\nMY_FAV\tinput.html\t/const MY_FAV = 7;/;\"\tC\tlanguage:JavaScript\nheading1\tinput.html\t/^  <h1>heading1<\\/h1>$/;\"\th\tlanguage:HTML\nheading2\tinput.html\t/^  <h2>heading2<\\/h2>$/;\"\ti\tlanguage:HTML\nheading3\tinput.html\t/^  <h1>head<!--ing1-->ing<!--ing2-->3<\\/h1>$/;\"\th\tlanguage:HTML\nhtml_commented_function\tinput.html\t/^function html_commented_function()$/;\"\tf\tlanguage:JavaScript\nmessage\tinput.html\t/^function message()$/;\"\tf\tlanguage:JavaScript\nmy heading3\tinput.html\t/^  <h3>my\theading3<\\/h3>$/;\"\tj\tlanguage:HTML\np\tinput.html\t/^p {color:blue;}$/;\"\ts\tlanguage:CSS\npostfixed_anchor\tinput.html\t/^  <a name=postfixed_anchor href=\"http:\\/\\/darrenhiebert.com\"><\\/a>$/;\"\ta\tlanguage:HTML\nprefixed_anchor\tinput.html\t/^  <a title=\"Title\" name=\"prefixed_anchor\"><\\/a>$/;\"\ta\tlanguage:HTML\nq\tinput.html\t/^var q = new Polygon();$/;\"\tv\tlanguage:JavaScript\nsimple_anchor\tinput.html\t/^  <a name=\"simple_anchor\"><\\/a>$/;\"\ta\tlanguage:HTML\nsome other heading1\tinput.html\t/^    <\\/h1>$/;\"\th\tlanguage:HTML\nunquoted_anchor\tinput.html\t/^  <a name=unquoted_anchor><\\/a>$/;\"\ta\tlanguage:HTML\n"
  },
  {
    "path": "Units/parser-html.r/simple.html.t/features",
    "content": "regex\n"
  },
  {
    "path": "Units/parser-html.r/simple.html.t/input.html",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html >\n<head>\n<style>\np {color:blue;}\n.intro { \n    background-color: yellow;\n}\n</style>\n<style>#firstname { background-color: yellow;}</style>\n<script language=\"Javascript\" src=\"./test.js\"></script> \n<script language=\"JavaScript\">\n\n//\tfunction commented_function1 () {}\n\n/*\n\tfunction commented_function2 () {} \n*/\n\nfunction message()\n{\n      alert( \"Hello.\");     \n}\n\nvar q = new Polygon();\n\n//<!--\n//HTML comment doesn't work right now\nfunction html_commented_function()\n{\n      alert( \"Hello.\");     \n}\n//-->\n</script>\n<script language=\"JavaScript\">const MY_FAV = 7;</script>\n<body>\n  <a name=\"simple_anchor\"></a>\n  <a name=unquoted_anchor></a>\n  <br/>\n  <a title=\"Title\" name=\"prefixed_anchor\"></a>\n  <a name=postfixed_anchor href=\"http://darrenhiebert.com\"></a>\n  <!-- <a name=\"commented_anchor\"></a> -->\n  <h1>heading1</h1>\n  <div>\n    <h1>some\n      <em>    other    </em>\n      heading1\n    </h1>\n  </div>\n  <h1>head<!--ing1-->ing<!--ing2-->3</h1>\n  <h2>heading2</h2>\n  <h3>my\theading3</h3>\n  \n</body>\n</html>\n\n\n\n"
  },
  {
    "path": "Units/parser-html.r/string-in-script.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+Kl\n"
  },
  {
    "path": "Units/parser-html.r/string-in-script.d/expected.tags",
    "content": "Foo\tinput.html\t/^<h1>Foo<\\/h1>$/;\"\theading1\tlanguage:HTML\nBAR\tinput.html\t/^<h1>BAR<\\/h1>$/;\"\theading1\tlanguage:HTML\nbar\tinput.html\t/^\tconst bar = 123$/;\"\tconstant\tlanguage:JavaScript\nbaz\tinput.html\t/^\tfunction baz () {$/;\"\tfunction\tlanguage:JavaScript\nbar2\tinput.html\t/^\tconst bar2 = 123$/;\"\tconstant\tlanguage:JavaScript\nbaz2\tinput.html\t/^\tfunction baz2 () {$/;\"\tfunction\tlanguage:JavaScript\n"
  },
  {
    "path": "Units/parser-html.r/string-in-script.d/input.html",
    "content": "<!-- Taken from #3581 submitted by @polyscone -->\n<h1>Foo</h1>\n\n<script>\n\tconst bar = 123\n\n\t// I don't know why, but an apostrophe breaks\n\t// the JavaScript guest language\n\tfunction baz () {\n\t\treturn 'abc'\n\t}\n</script>\n\n<script>\n\tconst bar2 = 123\n\n\t// I don\"t know why, but an apostrophe breaks\n\t// the JavaScript guest language\n\tfunction baz2 () {\n\t\treturn 'abc'\n\t}\n</script>\n\n<h1>BAR</h1>\n"
  },
  {
    "path": "Units/parser-html.r/whitespaces.html.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-html.r/whitespaces.html.d/expected.tags",
    "content": "heading1\tinput.html\t/^<\\/h1>$/;\"\th\nheading2\tinput.html\t/^<h1>  heading2  <\\/h1>$/;\"\th\nheading 3\tinput.html\t/^<h1>heading  3  <\\/h1>$/;\"\th\n"
  },
  {
    "path": "Units/parser-html.r/whitespaces.html.d/input.html",
    "content": "<h1>\n    heading1\n</h1>\n<h1>  heading2  </h1>\n<h1>heading  3  </h1>\n"
  },
  {
    "path": "Units/parser-html.r/whitespaces.html.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/parser-iPythonCell.r/customizing.d/args.ctags",
    "content": "--sort=no\n--fields=+{language}{extras}\n--extras=+{subparser}\n--regex-IPythonCell=/[ \\t]*# CTAGS:[ ]?(.*)$/\\1/c/\n"
  },
  {
    "path": "Units/parser-iPythonCell.r/customizing.d/expected.tags",
    "content": "x\tinput.py\t/^x=1$/;\"\tv\tlanguage:Python\nDEFINE F\tinput.py\t/^# CTAGS: DEFINE F$/;\"\tc\tlanguage:IPythonCell\textras:subparser\nF\tinput.py\t/^def F():$/;\"\tf\tlanguage:Python\nDO NOTING\tinput.py\t/^    # CTAGS: DO NOTING$/;\"\tc\tlanguage:IPythonCell\textras:subparser\n"
  },
  {
    "path": "Units/parser-iPythonCell.r/customizing.d/input.py",
    "content": "x=1\n# CTAGS: DEFINE F\ndef F():\n    # CTAGS: DO NOTING\n    pass\n"
  },
  {
    "path": "Units/parser-iPythonCell.r/default-formats.d/args.ctags",
    "content": "--sort=no\n--fields=+{language}\n--extras=+{subparser}\n"
  },
  {
    "path": "Units/parser-iPythonCell.r/default-formats.d/expected.tags",
    "content": "np\tinput.py\t/^import numpy as np$/;\"\tI\tlanguage:Python\tnameref:module:numpy\nplt\tinput.py\t/^from matplotlib import pyplot as plt$/;\"\tY\tlanguage:Python\tnameref:unknown:pyplot\ngenerate sound\tinput.py\t/^# %% generate sound$/;\"\tc\tlanguage:IPythonCell\nf\tinput.py\t/^f = 12000$/;\"\tv\tlanguage:Python\nfs\tinput.py\t/^fs = 44100$/;\"\tv\tlanguage:Python\nt\tinput.py\t/^t = np.arange(0, 1, 1\\/fs)$/;\"\tv\tlanguage:Python\nsound\tinput.py\t/^sound = np.sin(2*np.pi*f * t)$/;\"\tv\tlanguage:Python\nplot sound\tinput.py\t/^# %% plot sound$/;\"\tc\tlanguage:IPythonCell\nplay sound\tinput.py\t/^# %% play sound$/;\"\tc\tlanguage:IPythonCell\nno space\tinput.py\t/^#%% no space$/;\"\tc\tlanguage:IPythonCell\na\tinput.py\t/^a=1$/;\"\tv\tlanguage:Python\n% extra percent chars with space\tinput.py\t/^# %%% extra percent chars with space$/;\"\tc\tlanguage:IPythonCell\nb\tinput.py\t/^b=1$/;\"\tv\tlanguage:Python\n% extra percent chars without space\tinput.py\t/^#%%% extra percent chars without space$/;\"\tc\tlanguage:IPythonCell\nc\tinput.py\t/^c=1$/;\"\tv\tlanguage:Python\nf\tinput.py\t/^def f():$/;\"\tf\tlanguage:Python\nno space with prefix\tinput.py\t/^    #%% no space with prefix$/;\"\tc\tlanguage:IPythonCell\ng\tinput.py\t/^def g():$/;\"\tf\tlanguage:Python\n% extra percent chars with space and prefix\tinput.py\t/^    # %%% extra percent chars with space and prefix$/;\"\tc\tlanguage:IPythonCell\nh\tinput.py\t/^def h():$/;\"\tf\tlanguage:Python\n% extra percent chars without space with prefix\tinput.py\t/^    #%%% extra percent chars without space with prefix$/;\"\tc\tlanguage:IPythonCell\ntriangle without space\tinput.py\t/^# <codecell>triangle without space$/;\"\tc\tlanguage:IPythonCell\nA\tinput.py\t/^A=1$/;\"\tv\tlanguage:Python\ntriangle with space\tinput.py\t/^# <codecell> triangle with space$/;\"\tc\tlanguage:IPythonCell\nB\tinput.py\t/^B=1$/;\"\tv\tlanguage:Python\nF\tinput.py\t/^def F():$/;\"\tf\tlanguage:Python\ntriangle with space and prefix\tinput.py\t/^    # <codecell> triangle with space and prefix$/;\"\tc\tlanguage:IPythonCell\n"
  },
  {
    "path": "Units/parser-iPythonCell.r/default-formats.d/input.py",
    "content": "# Derived from https://github.com/universal-ctags/ctags/issues/2978\n# submitted by @gerazov.\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom scipy.io import wavfile\nimport os\n\n# %% generate sound\nf = 12000\nfs = 44100\nt = np.arange(0, 1, 1/fs)\nsound = np.sin(2*np.pi*f * t)\n\n# %% plot sound\nplt.plot(t, sound)\n\n# %% play sound\nwavfile.write('sound.wav', fs, np.int16(sound * 2**15))\nos.system('play sound.wav')\n\n#%% no space\na=1\n\n# %%% extra percent chars with space\nb=1\n\n#%%% extra percent chars without space\nc=1\n\ndef f():\n    #%% no space with prefix\n    pass\n\ndef g():\n    # %%% extra percent chars with space and prefix\n    pass\n\ndef h():\n    #%%% extra percent chars without space with prefix\n    pass\n\n# <codecell>triangle without space\nA=1\n\n# <codecell> triangle with space\nB=1\n\ndef F():\n    # <codecell> triangle with space and prefix\n    pass\n\n## IGNORE ME\n\n"
  },
  {
    "path": "Units/parser-iPythonCell.r/double-sharps.d/args.ctags",
    "content": "--sort=no\n--fields=+{language}{extras}\n--extras=+{subparser}\n--extras-IPythonCell=+{doubleSharps}\n"
  },
  {
    "path": "Units/parser-iPythonCell.r/double-sharps.d/expected.tags",
    "content": "np\tinput.py\t/^import numpy as np$/;\"\tI\tlanguage:Python\tnameref:module:numpy\nplt\tinput.py\t/^from matplotlib import pyplot as plt$/;\"\tY\tlanguage:Python\tnameref:unknown:pyplot\ngenerate sound\tinput.py\t/^## generate sound$/;\"\tc\tlanguage:IPythonCell\textras:subparser,doubleSharps\nf\tinput.py\t/^f = 12000$/;\"\tv\tlanguage:Python\nfs\tinput.py\t/^fs = 44100$/;\"\tv\tlanguage:Python\nt\tinput.py\t/^t = np.arange(0, 1, 1\\/fs)$/;\"\tv\tlanguage:Python\nsound\tinput.py\t/^sound = np.sin(2*np.pi*f * t)$/;\"\tv\tlanguage:Python\nplot sound\tinput.py\t/^##plot sound$/;\"\tc\tlanguage:IPythonCell\textras:subparser,doubleSharps\nplay sound\tinput.py\t/^##play sound$/;\"\tc\tlanguage:IPythonCell\textras:subparser,doubleSharps\nno prefix\tinput.py\t/^##no prefix$/;\"\tc\tlanguage:IPythonCell\textras:subparser,doubleSharps\na\tinput.py\t/^a=1$/;\"\tv\tlanguage:Python\n# extra sharp chars with space\tinput.py\t/^### extra sharp chars with space$/;\"\tc\tlanguage:IPythonCell\textras:subparser,doubleSharps\nb\tinput.py\t/^b=1$/;\"\tv\tlanguage:Python\n#extra sharp chars without space\tinput.py\t/^###extra sharp chars without space$/;\"\tc\tlanguage:IPythonCell\textras:subparser,doubleSharps\nc\tinput.py\t/^c=1$/;\"\tv\tlanguage:Python\nf\tinput.py\t/^def f():$/;\"\tf\tlanguage:Python\nno space with prefix\tinput.py\t/^    ##no space with prefix$/;\"\tc\tlanguage:IPythonCell\textras:subparser,doubleSharps\ng\tinput.py\t/^def g():$/;\"\tf\tlanguage:Python\n# extra sharp chars with space and prefix\tinput.py\t/^    ### extra sharp chars with space and prefix$/;\"\tc\tlanguage:IPythonCell\textras:subparser,doubleSharps\nh\tinput.py\t/^def h():$/;\"\tf\tlanguage:Python\n#extra sharp chars without space with prefix\tinput.py\t/^    ###extra sharp chars without space with prefix$/;\"\tc\tlanguage:IPythonCell\textras:subparser,doubleSharps\nDONT IGNORE ME\tinput.py\t/^## DONT IGNORE ME$/;\"\tc\tlanguage:IPythonCell\textras:subparser,doubleSharps\n"
  },
  {
    "path": "Units/parser-iPythonCell.r/double-sharps.d/input.py",
    "content": "# Derived from https://github.com/universal-ctags/ctags/issues/2978\n# submitted by @gerazov.\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom scipy.io import wavfile\nimport os\n\n## generate sound\nf = 12000\nfs = 44100\nt = np.arange(0, 1, 1/fs)\nsound = np.sin(2*np.pi*f * t)\n\n##plot sound\nplt.plot(t, sound)\n\n##play sound\nwavfile.write('sound.wav', fs, np.int16(sound * 2**15))\nos.system('play sound.wav')\n\n##no prefix\na=1\n\n### extra sharp chars with space\nb=1\n\n###extra sharp chars without space\nc=1\n\ndef f():\n    ##no space with prefix\n    pass\n\ndef g():\n    ### extra sharp chars with space and prefix\n    pass\n\ndef h():\n    ###extra sharp chars without space with prefix\n    pass\n\n## DONT IGNORE ME\n\n"
  },
  {
    "path": "Units/parser-iniconf.r/ignore-utf8-bom.d/args.ctags",
    "content": "--fields=+n\n"
  },
  {
    "path": "Units/parser-iniconf.r/ignore-utf8-bom.d/expected.tags",
    "content": "name1\tinput.ini\t/^[name1]$/;\"\ts\tline:1\nname2\tinput.ini\t/^name2=1$/;\"\tk\tline:2\tsection:name1\nname3\tinput.ini\t/^[name3]$/;\"\ts\tline:3\nname4\tinput.ini\t/^name4=2$/;\"\tk\tline:4\tsection:name3\n"
  },
  {
    "path": "Units/parser-iniconf.r/ignore-utf8-bom.d/input.ini",
    "content": "﻿[name1]\nname2=1\n[name3]\nname4=2\n\n"
  },
  {
    "path": "Units/parser-iniconf.r/toml-support-in-geany.d/args.ctags",
    "content": "--fields=+lK\n--langmap=Iniconf:.toml\n--sort=no\n"
  },
  {
    "path": "Units/parser-iniconf.r/toml-support-in-geany.d/expected.tags",
    "content": "table\tinput.toml\t/^[table]$/;\"\tsection\tlanguage:Iniconf\nkey\tinput.toml\t/^key = \"value\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\nbare_key\tinput.toml\t/^bare_key = \"value\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\nbare-key\tinput.toml\t/^bare-key = \"value\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\n1234\tinput.toml\t/^1234 = \"value\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\n\"127.0.0.1\"\tinput.toml\t/^\"127.0.0.1\" = \"value\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\n\"character encoding\"\tinput.toml\t/^\"character encoding\" = \"value\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\n'key2'\tinput.toml\t/^'key2' = \"value\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\n'quoted \"value\"'\tinput.toml\t/^'quoted \"value\"' = \"value\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\nname\tinput.toml\t/^name = \"Orange\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\nphysical.color\tinput.toml\t/^physical.color = \"orange\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\nphysical.shape\tinput.toml\t/^physical.shape = \"round\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\nsite.\"google.com\"\tinput.toml\t/^site.\"google.com\" = true$/;\"\tkey\tlanguage:Iniconf\tsection:table\nstr1\tinput.toml\t/^str1 = \"\"\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\nstr1\tinput.toml\t/^str1 = \"The quick brown fox jumps over the lazy dog.\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\nstr2\tinput.toml\t/^str2 = \"\"\"$/;\"\tkey\tlanguage:Iniconf\tsection:table\nstr3\tinput.toml\t/^str3 = \"\"\"\\\\$/;\"\tkey\tlanguage:Iniconf\tsection:table\nregex2\tinput.toml\t/^regex2 = '''I [dw]on't need \\\\d{2} apples'''$/;\"\tkey\tlanguage:Iniconf\tsection:table\nlines\tinput.toml\t/^lines  = '''$/;\"\tkey\tlanguage:Iniconf\tsection:table\ncontributors\tinput.toml\t/^contributors = [$/;\"\tkey\tlanguage:Iniconf\tsection:table\nintegers2\tinput.toml\t/^integers2 = [$/;\"\tkey\tlanguage:Iniconf\tsection:table\nintegers3\tinput.toml\t/^integers3 = [$/;\"\tkey\tlanguage:Iniconf\tsection:table\ntable-1\tinput.toml\t/^[table-1]$/;\"\tsection\tlanguage:Iniconf\nkey1\tinput.toml\t/^key1 = \"some string\"$/;\"\tkey\tlanguage:Iniconf\tsection:table-1\nkey2\tinput.toml\t/^key2 = 123$/;\"\tkey\tlanguage:Iniconf\tsection:table-1\ntable-2\tinput.toml\t/^[table-2]$/;\"\tsection\tlanguage:Iniconf\nkey1\tinput.toml\t/^key1 = \"another string\"$/;\"\tkey\tlanguage:Iniconf\tsection:table-2\nkey2\tinput.toml\t/^key2 = 456$/;\"\tkey\tlanguage:Iniconf\tsection:table-2\ndog.\"tater.man\"\tinput.toml\t/^[dog.\"tater.man\"]$/;\"\tsection\tlanguage:Iniconf\ntype.name\tinput.toml\t/^type.name = \"pug\"$/;\"\tkey\tlanguage:Iniconf\tsection:dog.\"tater.man\"\na.b.c\tinput.toml\t/^[a.b.c]            # this is best practice$/;\"\tsection\tlanguage:Iniconf\n\\x20d.e.f \tinput.toml\t/^[ d.e.f ]          # same as [d.e.f]$/;\"\tsection\tlanguage:Iniconf\n\\x20g .  h  . i \tinput.toml\t/^[ g .  h  . i ]    # same as [g.h.i]$/;\"\tsection\tlanguage:Iniconf\n[products]\tinput.toml\t/^[[products]]$/;\"\tsection\tlanguage:Iniconf\nname\tinput.toml\t/^name = \"Hammer\"$/;\"\tkey\tlanguage:Iniconf\tsection:[products]\nsku\tinput.toml\t/^sku = 738594937$/;\"\tkey\tlanguage:Iniconf\tsection:[products]\n[products]\tinput.toml\t/^[[products]]  # empty table within the array$/;\"\tsection\tlanguage:Iniconf\n[products]\tinput.toml\t/^[[products]]$/;\"\tsection\tlanguage:Iniconf\nname\tinput.toml\t/^name = \"Nail\"$/;\"\tkey\tlanguage:Iniconf\tsection:[products]\nsku\tinput.toml\t/^sku = 284758393$/;\"\tkey\tlanguage:Iniconf\tsection:[products]\npoints\tinput.toml\t/^points = [ { x = 1, y = 2, z = 3 },$/;\"\tkey\tlanguage:Iniconf\tsection:[products]\n"
  },
  {
    "path": "Units/parser-iniconf.r/toml-support-in-geany.d/input.toml",
    "content": "#\n# TAKEN FROM https://toml.io/en/v1.0.0#array-of-tables\n#\n\n[table]\nkey = \"value\"\nbare_key = \"value\"\nbare-key = \"value\"\n1234 = \"value\"\n\n\"127.0.0.1\" = \"value\"\n\"character encoding\" = \"value\"\n'key2' = \"value\"\n'quoted \"value\"' = \"value\"\n\nname = \"Orange\"\nphysical.color = \"orange\"\nphysical.shape = \"round\"\nsite.\"google.com\" = true\n\nstr1 = \"\"\"\nRoses are red\nViolets are blue\"\"\"\n\nstr1 = \"The quick brown fox jumps over the lazy dog.\"\n\nstr2 = \"\"\"\nThe quick brown \\\n\n\n  fox jumps over \\\n    the lazy dog.\"\"\"\n\nstr3 = \"\"\"\\\n       The quick brown \\\n       fox jumps over \\\n       the lazy dog.\\\n       \"\"\"\n\nregex2 = '''I [dw]on't need \\d{2} apples'''\nlines  = '''\nThe first newline is\ntrimmed in raw strings.\n   All other whitespace\n   is preserved.\n'''\n\ncontributors = [\n  \"Foo Bar <foo@example.com>\",\n  { name = \"Baz Qux\", email = \"bazqux@example.com\", url = \"https://example.com/bazqux\" }\n]\n\nintegers2 = [\n  1, 2, 3\n]\n\nintegers3 = [\n  1,\n  2, # this is ok\n]\n\n[table-1]\nkey1 = \"some string\"\nkey2 = 123\n\n[table-2]\nkey1 = \"another string\"\nkey2 = 456\n\n[dog.\"tater.man\"]\ntype.name = \"pug\"\n\n[a.b.c]            # this is best practice\n[ d.e.f ]          # same as [d.e.f]\n[ g .  h  . i ]    # same as [g.h.i]\n\n[[products]]\nname = \"Hammer\"\nsku = 738594937\n\n[[products]]  # empty table within the array\n\n[[products]]\nname = \"Nail\"\nsku = 284758393\n\npoints = [ { x = 1, y = 2, z = 3 },\n           { x = 7, y = 8, z = 9 },\n           { x = 2, y = 4, z = 8 } ]\n"
  },
  {
    "path": "Units/parser-inko.r/comments.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-inko.r/comments.d/expected.tags",
    "content": "this_method_should_be_tagged\tinput.inko\t/^def this_method_should_be_tagged {}$/;\"\tm\n"
  },
  {
    "path": "Units/parser-inko.r/comments.d/input.inko",
    "content": "# def this_should_be_ignored {}\n\ndef this_method_should_be_tagged {}\n"
  },
  {
    "path": "Units/parser-inko.r/everything.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-inko.r/everything.d/expected.tags",
    "content": "A\tinput.inko\t/^class A$/;\"\to\n@number\tinput.inko\t/^  @number: X$/;\"\ta\tclass:A\nin_a\tinput.inko\t/^  def in_a {$/;\"\tm\tclass:A\nanother\tinput.inko\t/^  def another {}$/;\"\tm\nfoo\tinput.inko\t/^def foo {}$/;\"\tm\nB\tinput.inko\t/^class B {$/;\"\to\nin_b\tinput.inko\t/^  def in_b {$/;\"\tm\tclass:B\nglobal\tinput.inko\t/^def global {}$/;\"\tm\nSomeTrait\tinput.inko\t/^trait SomeTrait {$/;\"\tt\nrequired_method\tinput.inko\t/^  def required_method$/;\"\tm\ttrait:SomeTrait\nSocket\tinput.inko\t/^class Socket {$/;\"\to\nquack\tinput.inko\t/^  def quack {}$/;\"\tm\tclass:Socket\nSocket\tinput.inko\t/^impl Bar for Socket {$/;\"\tr\timplements:Bar\nmoo\tinput.inko\t/^  def moo !! Integer {}$/;\"\tm\treopen:Socket\nChickens\tinput.inko\t/^impl Chickens {$/;\"\tr\nbok_bok\tinput.inko\t/^  def bok_bok {}$/;\"\tm\treopen:Chickens\nNUMBER\tinput.inko\t/^let NUMBER = 10$/;\"\tc\n"
  },
  {
    "path": "Units/parser-inko.r/everything.d/input.inko",
    "content": "{ 20 }\n\nclass A\n{\n  @number: X\n\n  def in_a {\n    { 20 }\n  }\n\n  def another {}\n}\n\ndef foo {}\n\nclass B {\n  def in_b {\n    { 10  }\n  }\n}\n\ndef global {}\n\ntrait SomeTrait {\n  # def this_should_be_ignored {}\n  def required_method\n}\n\nclass Socket {\n  def quack {}\n}\n\nimpl Bar for Socket {\n  def moo !! Integer {}\n}\n\nimpl Chickens {\n  def bok_bok {}\n}\n\nlet NUMBER = 10\n"
  },
  {
    "path": "Units/parser-inko.r/implementations.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-inko.r/implementations.d/expected.tags",
    "content": "SomeObject\tinput.inko\t/^impl SomeObject {$/;\"\tr\nfoo\tinput.inko\t/^  def foo {}$/;\"\tm\treopen:SomeObject\nSomeObject\tinput.inko\t/^impl SomeTrait for SomeObject {$/;\"\tr\timplements:SomeTrait\nbar\tinput.inko\t/^  def bar {}$/;\"\tm\treopen:SomeObject\n"
  },
  {
    "path": "Units/parser-inko.r/implementations.d/input.inko",
    "content": "impl SomeObject {\n  def foo {}\n}\n\nimpl SomeTrait for SomeObject {\n  def bar {}\n}\n"
  },
  {
    "path": "Units/parser-inko.r/let.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-inko.r/let.d/expected.tags",
    "content": "FOO\tinput.inko\t/^let FOO = 10$/;\"\tc\nBAR\tinput.inko\t/^let BAR = 20$/;\"\tc\n"
  },
  {
    "path": "Units/parser-inko.r/let.d/input.inko",
    "content": "let FOO = 10\nlet BAR = 20\nlet foo: Bla = 30\n"
  },
  {
    "path": "Units/parser-inko.r/methods.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-inko.r/methods.d/expected.tags",
    "content": "A\tinput.inko\t/^class A {$/;\"\to\nmethod_a\tinput.inko\t/^  def method_a {}$/;\"\tm\tclass:A\nB\tinput.inko\t/^class B {$/;\"\to\nmethod_b\tinput.inko\t/^  def method_b {}$/;\"\tm\tclass:B\n+\tinput.inko\t/^def + {}$/;\"\tm\n-\tinput.inko\t/^def - {}$/;\"\tm\n*\tinput.inko\t/^def * {}$/;\"\tm\n/\tinput.inko\t/^def \\/ {}$/;\"\tm\n%\tinput.inko\t/^def % {}$/;\"\tm\n^\tinput.inko\t/^def ^ {}$/;\"\tm\n[]\tinput.inko\t/^def [] {}$/;\"\tm\n[]=\tinput.inko\t/^def []= {}$/;\"\tm\n"
  },
  {
    "path": "Units/parser-inko.r/methods.d/input.inko",
    "content": "class A {\n  def method_a {}\n}\n\nclass B {\n  def method_b {}\n}\n\ndef + {}\ndef - {}\ndef * {}\ndef / {}\ndef % {}\ndef ^ {}\ndef [] {}\ndef []= {}\n"
  },
  {
    "path": "Units/parser-inko.r/objects.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-inko.r/objects.d/expected.tags",
    "content": "A\tinput.inko\t/^class A {}$/;\"\to\nB\tinput.inko\t/^class B {}$/;\"\to\nC\tinput.inko\t/^class C {$/;\"\to\n@foo\tinput.inko\t/^  @foo: X$/;\"\ta\tclass:C\n"
  },
  {
    "path": "Units/parser-inko.r/objects.d/input.inko",
    "content": "class A {}\nclass B {}\n\nclass C {\n  @foo: X\n}\n"
  },
  {
    "path": "Units/parser-inko.r/strings.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-inko.r/strings.d/expected.tags",
    "content": "Foo\tinput.inko\t/^class Foo {}$/;\"\to\n"
  },
  {
    "path": "Units/parser-inko.r/strings.d/input.inko",
    "content": "'foo'\n'let A = 10'\n'class B {}'\n'trait C {}'\n\"trait D {}\"\n\n'foo \\' class AA {}'\n\"foo \\\" class AA {}\"\n\n`trait Hello {}`\n\nclass Foo {}\n"
  },
  {
    "path": "Units/parser-inko.r/traits.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-inko.r/traits.d/expected.tags",
    "content": "A\tinput.inko\t/^trait A {}$/;\"\tt\nB\tinput.inko\t/^trait B: SomeRequiredTrait {}$/;\"\tt\nC\tinput.inko\t/^trait C {$/;\"\tt\nfoo\tinput.inko\t/^  def foo() {}$/;\"\tm\ttrait:C\nbar\tinput.inko\t/^  def bar() {}$/;\"\tm\ttrait:C\nrequired_method_foo\tinput.inko\t/^  def required_method_foo$/;\"\tm\ttrait:C\nrequired_method_bar\tinput.inko\t/^  def required_method_bar$/;\"\tm\ttrait:C\nwrapped_required_method\tinput.inko\t/^  def wrapped_required_method($/;\"\tm\ttrait:C\nwrapped_default_method\tinput.inko\t/^  def wrapped_default_method($/;\"\tm\ttrait:C\nblabla\tinput.inko\t/^  def blabla {}$/;\"\tm\ttrait:C\nD\tinput.inko\t/^trait D {}$/;\"\tt\n"
  },
  {
    "path": "Units/parser-inko.r/traits.d/input.inko",
    "content": "trait A {}\ntrait B: SomeRequiredTrait {}\ntrait C {\n  def foo() {}\n  def bar() {}\n\n  def required_method_foo\n  def required_method_bar\n\n  def wrapped_required_method(\n    a: A\n  )\n\n  def wrapped_default_method(\n    a: A\n  ) {}\n\n  def blabla {}\n}\ntrait D {}\n"
  },
  {
    "path": "Units/parser-itcl.r/force-use.d/args.ctags",
    "content": "--sort=no\n--param-ITcl.forceUse=1\n--fields=+{language}\n"
  },
  {
    "path": "Units/parser-itcl.r/force-use.d/expected.tags",
    "content": "MyClass\tinput.tcl\t/^class MyClass {$/;\"\tc\tlanguage:ITcl\nfoo\tinput.tcl\t/^    public method foo {} {$/;\"\tm\tlanguage:ITcl\tclass:MyClass\n"
  },
  {
    "path": "Units/parser-itcl.r/force-use.d/input.tcl",
    "content": "# Assume this source file is loaded from\n# another source file:\n# \n#   package require Itcl\n#   namespace import itcl::*\n#   source input.tcl\n#\nclass MyClass {\n    public method foo {} {\n    }\n}\n\nbody MyClass::foo {} {\n}\n"
  },
  {
    "path": "Units/parser-itcl.r/fq-with-namespace.b/args.ctags",
    "content": "--sort=no\n--extras=+q\n"
  },
  {
    "path": "Units/parser-itcl.r/fq-with-namespace.b/expected.tags",
    "content": "A\tinput.tcl\t/^namespace eval A {$/;\"\tn\nB\tinput.tcl\t/^    itcl::class B {$/;\"\tc\tnamespace:A\nA::B\tinput.tcl\t/^    itcl::class B {$/;\"\tc\tnamespace:A\n"
  },
  {
    "path": "Units/parser-itcl.r/fq-with-namespace.b/input.tcl",
    "content": "package require Itcl\n\nnamespace eval A {\n    itcl::class B {\n    }\n}\n\n"
  },
  {
    "path": "Units/parser-itcl.r/itcl-1.d/args.ctags",
    "content": "--fields=+l\n"
  },
  {
    "path": "Units/parser-itcl.r/itcl-1.d/expected.tags",
    "content": "A\tinput.tcl\t/^itcl::class A {$/;\"\tc\tlanguage:ITcl\n"
  },
  {
    "path": "Units/parser-itcl.r/itcl-1.d/input.tcl",
    "content": "package require Itcl\n\nitcl::class A {\n}\n\n# Next one should be ignored.\nclass B {\n}\n"
  },
  {
    "path": "Units/parser-itcl.r/itcl-2.d/args.ctags",
    "content": "--fields=+l\n"
  },
  {
    "path": "Units/parser-itcl.r/itcl-2.d/expected.tags",
    "content": "A\tinput.tcl\t/^itcl::class A {$/;\"\tc\tlanguage:ITcl\nB\tinput.tcl\t/^class B {$/;\"\tc\tlanguage:ITcl\n"
  },
  {
    "path": "Units/parser-itcl.r/itcl-2.d/input.tcl",
    "content": "package require Itcl\nnamespace import itcl::*\n\nitcl::class A {\n}\n\nclass B {\n}\n"
  },
  {
    "path": "Units/parser-itcl.r/itcl-3.d/expected.tags",
    "content": "Toaster\tinput.tcl\t/^itcl::class Toaster {$/;\"\tc\n"
  },
  {
    "path": "Units/parser-itcl.r/itcl-3.d/input.tcl",
    "content": "# Toaster should be tagged though Itcl is not required.\n# See #3136. A scrip can be sourced from another script that\n# required ITcl.\nitcl::class Toaster {\n}\n"
  },
  {
    "path": "Units/parser-itcl.r/no-itcl-2.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-itcl.r/no-itcl-2.d/input.tcl",
    "content": "# Toaster should be ignored because itcl:: is not imported.\npackage require Itcl\nclass Toaster {\n}\n"
  },
  {
    "path": "Units/parser-itcl.r/simple-itcl.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--fields=*\n"
  },
  {
    "path": "Units/parser-itcl.r/simple-itcl.d/expected.tags",
    "content": "Toaster\tinput.tcl\t/^itcl::class Toaster {$/;\"\tkind:class\tline:6\tlanguage:ITcl\troles:def\textras:subparser\ncrumbs\tinput.tcl\t/^    variable crumbs 0$/;\"\tkind:variable\tline:7\tlanguage:ITcl\tscope:class:Toaster\troles:def\textras:subparser\tend:7\nToaster::crumbs\tinput.tcl\t/^    variable crumbs 0$/;\"\tkind:variable\tline:7\tlanguage:ITcl\tscope:class:Toaster\troles:def\textras:qualified,subparser\tend:7\ntoast\tinput.tcl\t/^    method toast {nslices} {$/;\"\tkind:method\tline:8\tlanguage:ITcl\tscope:class:Toaster\troles:def\textras:subparser\tend:13\nToaster::toast\tinput.tcl\t/^    method toast {nslices} {$/;\"\tkind:method\tline:8\tlanguage:ITcl\tscope:class:Toaster\troles:def\textras:qualified,subparser\tend:13\nclean\tinput.tcl\t/^    method clean {} {$/;\"\tkind:method\tline:14\tlanguage:ITcl\tscope:class:Toaster\troles:def\textras:subparser\tend:16\nToaster::clean\tinput.tcl\t/^    method clean {} {$/;\"\tkind:method\tline:14\tlanguage:ITcl\tscope:class:Toaster\troles:def\textras:qualified,subparser\tend:16\nSmartToaster\tinput.tcl\t/^itcl::class SmartToaster {$/;\"\tkind:class\tline:19\tlanguage:ITcl\tinherits:Toaster\troles:def\textras:subparser\ntoast\tinput.tcl\t/^    method toast {nslices} {$/;\"\tkind:method\tline:21\tlanguage:ITcl\tscope:class:SmartToaster\troles:def\textras:subparser\tend:26\nSmartToaster::toast\tinput.tcl\t/^    method toast {nslices} {$/;\"\tkind:method\tline:21\tlanguage:ITcl\tscope:class:SmartToaster\troles:def\textras:qualified,subparser\tend:26\ndoSomethingPublic\tinput.tcl\t/^    public method doSomethingPublic {} {$/;\"\tkind:method\tline:28\tlanguage:ITcl\tscope:class:SmartToaster\taccess:public\troles:def\textras:subparser\tend:29\nSmartToaster::doSomethingPublic\tinput.tcl\t/^    public method doSomethingPublic {} {$/;\"\tkind:method\tline:28\tlanguage:ITcl\tscope:class:SmartToaster\taccess:public\troles:def\textras:qualified,subparser\tend:29\ndoSomethingProtected\tinput.tcl\t/^    protected method doSomethingProtected {} {$/;\"\tkind:method\tline:30\tlanguage:ITcl\tscope:class:SmartToaster\taccess:protected\troles:def\textras:subparser\tend:31\nSmartToaster::doSomethingProtected\tinput.tcl\t/^    protected method doSomethingProtected {} {$/;\"\tkind:method\tline:30\tlanguage:ITcl\tscope:class:SmartToaster\taccess:protected\troles:def\textras:qualified,subparser\tend:31\ndoSomethingPrivate\tinput.tcl\t/^    private method doSomethingPrivate {} {$/;\"\tkind:method\tline:32\tlanguage:ITcl\tscope:class:SmartToaster\taccess:private\troles:def\textras:subparser\tend:33\nSmartToaster::doSomethingPrivate\tinput.tcl\t/^    private method doSomethingPrivate {} {$/;\"\tkind:method\tline:32\tlanguage:ITcl\tscope:class:SmartToaster\taccess:private\troles:def\textras:qualified,subparser\tend:33\nprocNoProtection\tinput.tcl\t/^    proc procNoProtection {} {$/;\"\tkind:procedure\tline:35\tlanguage:ITcl\tscope:class:SmartToaster\troles:def\textras:subparser\tend:36\nSmartToaster::procNoProtection\tinput.tcl\t/^    proc procNoProtection {} {$/;\"\tkind:procedure\tline:35\tlanguage:ITcl\tscope:class:SmartToaster\troles:def\textras:qualified,subparser\tend:36\nprocPublic\tinput.tcl\t/^    public proc procPublic {} {$/;\"\tkind:procedure\tline:38\tlanguage:ITcl\tscope:class:SmartToaster\taccess:public\troles:def\textras:subparser\tend:39\nSmartToaster::procPublic\tinput.tcl\t/^    public proc procPublic {} {$/;\"\tkind:procedure\tline:38\tlanguage:ITcl\tscope:class:SmartToaster\taccess:public\troles:def\textras:qualified,subparser\tend:39\nprocProtected\tinput.tcl\t/^    protected proc procProtected {} {$/;\"\tkind:procedure\tline:40\tlanguage:ITcl\tscope:class:SmartToaster\taccess:protected\troles:def\textras:subparser\tend:41\nSmartToaster::procProtected\tinput.tcl\t/^    protected proc procProtected {} {$/;\"\tkind:procedure\tline:40\tlanguage:ITcl\tscope:class:SmartToaster\taccess:protected\troles:def\textras:qualified,subparser\tend:41\nprocPrivate\tinput.tcl\t/^    private proc procPrivate {} {$/;\"\tkind:procedure\tline:42\tlanguage:ITcl\tscope:class:SmartToaster\taccess:private\troles:def\textras:subparser\tend:43\nSmartToaster::procPrivate\tinput.tcl\t/^    private proc procPrivate {} {$/;\"\tkind:procedure\tline:42\tlanguage:ITcl\tscope:class:SmartToaster\taccess:private\troles:def\textras:qualified,subparser\tend:43\ncommonNoProtection\tinput.tcl\t/^    common commonNoProtection 0$/;\"\tkind:common\tline:45\tlanguage:ITcl\tscope:class:SmartToaster\troles:def\textras:subparser\tend:45\nSmartToaster::commonNoProtection\tinput.tcl\t/^    common commonNoProtection 0$/;\"\tkind:common\tline:45\tlanguage:ITcl\tscope:class:SmartToaster\troles:def\textras:qualified,subparser\tend:45\ncommonPublic\tinput.tcl\t/^    public proc commonPublic \"a\"$/;\"\tkind:procedure\tline:47\tlanguage:ITcl\tscope:class:SmartToaster\taccess:public\troles:def\textras:subparser\tend:47\nSmartToaster::commonPublic\tinput.tcl\t/^    public proc commonPublic \"a\"$/;\"\tkind:procedure\tline:47\tlanguage:ITcl\tscope:class:SmartToaster\taccess:public\troles:def\textras:qualified,subparser\tend:47\ncommonProtected\tinput.tcl\t/^    protected proc commonProtected \"b\"$/;\"\tkind:procedure\tline:48\tlanguage:ITcl\tscope:class:SmartToaster\taccess:protected\troles:def\textras:subparser\tend:48\nSmartToaster::commonProtected\tinput.tcl\t/^    protected proc commonProtected \"b\"$/;\"\tkind:procedure\tline:48\tlanguage:ITcl\tscope:class:SmartToaster\taccess:protected\troles:def\textras:qualified,subparser\tend:48\ncommonPrivate\tinput.tcl\t/^    private proc commonPrivate \"c\"$/;\"\tkind:procedure\tline:49\tlanguage:ITcl\tscope:class:SmartToaster\taccess:private\troles:def\textras:subparser\tend:49\nSmartToaster::commonPrivate\tinput.tcl\t/^    private proc commonPrivate \"c\"$/;\"\tkind:procedure\tline:49\tlanguage:ITcl\tscope:class:SmartToaster\taccess:private\troles:def\textras:qualified,subparser\tend:49\nX\tinput.tcl\t/^itcl::class X {$/;\"\tkind:class\tline:51\tlanguage:ITcl\troles:def\textras:subparser\nx\tinput.tcl\t/^    variable x 0$/;\"\tkind:variable\tline:52\tlanguage:ITcl\tscope:class:X\troles:def\textras:subparser\tend:52\nX::x\tinput.tcl\t/^    variable x 0$/;\"\tkind:variable\tline:52\tlanguage:ITcl\tscope:class:X\troles:def\textras:qualified,subparser\tend:52\nY\tinput.tcl\t/^itcl::class Y {$/;\"\tkind:class\tline:54\tlanguage:ITcl\troles:def\textras:subparser\ny\tinput.tcl\t/^    variable y 0$/;\"\tkind:variable\tline:55\tlanguage:ITcl\tscope:class:Y\troles:def\textras:subparser\tend:55\nY::y\tinput.tcl\t/^    variable y 0$/;\"\tkind:variable\tline:55\tlanguage:ITcl\tscope:class:Y\troles:def\textras:qualified,subparser\tend:55\n"
  },
  {
    "path": "Units/parser-itcl.r/simple-itcl.d/input.tcl",
    "content": "#\n# Derived from class.n man page of itcl\n#\npackage require Itcl\n\nitcl::class Toaster {\n    variable crumbs 0\n    method toast {nslices} {\n        if {$crumbs > 50} {\n            error \"== FIRE! FIRE! ==\"\n        }\n        set crumbs [expr $crumbs+4*$nslices]\n    }\n    method clean {} {\n        set crumbs 0\n    }\n}\n\nitcl::class SmartToaster {\n    inherit Toaster\n    method toast {nslices} {\n        if {$crumbs > 40} {\n            clean\n        }\n        return [chain $nslices]\n    }\n\n    public method doSomethingPublic {} {\n    }\n    protected method doSomethingProtected {} {\n    }\n    private method doSomethingPrivate {} {\n    }\n\n    proc procNoProtection {} {\n    }\n    \n    public proc procPublic {} {\n    }\n    protected proc procProtected {} {\n    }\n    private proc procPrivate {} {\n    }\n\n    common commonNoProtection 0\n    \n    public proc commonPublic \"a\"\n    protected proc commonProtected \"b\"\n    private proc commonPrivate \"c\"\n}\nitcl::class X {\n    variable x 0\n}\nitcl::class Y {\n    variable y 0\n}\n\nset toaster [SmartToaster #auto]\n$toaster toast 2\n\n"
  },
  {
    "path": "Units/parser-java.r/accented-latin1-identifiers.java.d/README",
    "content": "Test that the parser allows for the subset of extended ASCII characters in the\nrange 0xC0-0xFF. \n\nThe specific range of characters allowed suggests the intent of this addition\nwas to catch accented Latin 1 identifier characters.  It's clearly less useful\nin other encodings.\n\nThis is handled as a special case for Java and C# identifiers only.\n\nSee commits dce8772 and c9bd254.\n"
  },
  {
    "path": "Units/parser-java.r/accented-latin1-identifiers.java.d/expected.tags",
    "content": "ueberweisen\tinput.java\t/^    void ueberweisen ( Konto empfnger, int betrag ) {$/;\"\tm\n"
  },
  {
    "path": "Units/parser-java.r/accented-latin1-identifiers.java.d/input.java",
    "content": "    void ueberweisen ( Konto empfnger, int betrag ) {\n\tabheben(betrag);\n\tempfnger.einzahlen(betrag);\n    }\n"
  },
  {
    "path": "Units/parser-java.r/anonymous-class.b/args.ctags",
    "content": "--sort=no\n--fields=+n\n--kinds-Java=+l\n"
  },
  {
    "path": "Units/parser-java.r/anonymous-class.b/expected.tags",
    "content": "input\tinput.java\t/^public class input {$/;\"\tc\tline:2\ngreeting\tinput.java\t/^    interface greeting {$/;\"\ti\tline:3\tclass:input\ngreet\tinput.java\t/^\tpublic void greet(String word);$/;\"\tm\tline:4\tinterface:input.greeting\nhello\tinput.java\t/^    public void hello () {$/;\"\tm\tline:7\tclass:input\ng\tinput.java\t/^\tgreeting g = new greeting() {$/;\"\tl\tline:8\tmethod:input.hello\nanonXXX\tinput.java\t/^\tgreeting g = new greeting() {$/;\"\tc\tline:8\tmethod:input.hello\ngreet\tinput.java\t/^\t\tpublic void greet (String word) {$/;\"\tm\tline:9\tmethod:input.hello.anonXXX\nbye\tinput.java\t/^    public void bye () {$/;\"\tm\tline:14\tclass:input\nh\tinput.java\t/^\tgreeting h = new greeting() {$/;\"\tl\tline:15\nanonYYY\tinput.java\t/^\tgreeting g = new greeting() {$/;\"\tc\tline:15\tmethod:input.bye\ngreet\tinput.java\t/^\t\tpublic void greet (String word) {$/;\"\tm\tline:16\tmethod:input.hello.anonYYY\n"
  },
  {
    "path": "Units/parser-java.r/anonymous-class.b/input.java",
    "content": "// See #1739\npublic class input {\n    interface greeting {\n\tpublic void greet(String word);\n    }\n\n    public void hello () {\n\tgreeting g = new greeting() {\n\t\tpublic void greet (String word) {\n\t\t}\n\t};\n\tg.greet(\"hello\");\n    }\n    public void bye () {\n\tgreeting h = new greeting() {\n\t\tpublic void greet (String word) {\n\t\t}\n\t};\n\th.greet(\"bye\");\n    }\n\n}\n"
  },
  {
    "path": "Units/parser-java.r/bug1447756.java.d/expected.tags",
    "content": "Foo\tinput.java\t/^\t      public interface Foo<T> {$/;\"\ti\nbar\tinput.java\t/^\t\t      public T bar();$/;\"\tm\tinterface:Foo\n"
  },
  {
    "path": "Units/parser-java.r/bug1447756.java.d/input.java",
    "content": "// Java 1.5 generic interfaces appear to be tagged on the\n// parameterized type name instead of the interface name,\n// e.g.,\n\n\t      public interface Foo<T> {\n\t\t      public T bar();\n\t      }\n\n// is tagged on 'T' instead of 'Foo'.\n"
  },
  {
    "path": "Units/parser-java.r/bug1691412.java.d/expected.tags",
    "content": "C\tinput.java\t/^public class C {$/;\"\tc\nCustomAnnotation\tinput.java\t/^public @interface CustomAnnotation {$/;\"\ta\nnewInstance\tinput.java\t/^ public static DefaultCipherDialog newInstance() {$/;\"\tm\tclass:C\ntoString\tinput.java\t/^ public String toString() { return \"hello\"; }$/;\"\tm\tclass:C\n"
  },
  {
    "path": "Units/parser-java.r/bug1691412.java.d/input.java",
    "content": "public class C {\n @NonNull\n @CheckReturnValue(explanation = \"When this function returns, the caller can get the Cipher name selected by the user in the Dialog.\")\n public static DefaultCipherDialog newInstance() {\n  DefaultCipherDialog instance = new DefaultCipherDialog();\n  instance.init();\n  return instance;\n }\n\n @Override\n public String toString() { return \"hello\"; }\n}\n\n@Target(ElementType.METHOD)\n@Retention(RetentionPolicy.SOURCE)\npublic @interface CustomAnnotation {\n}\n"
  },
  {
    "path": "Units/parser-java.r/bug1777340.java.d/expected.tags",
    "content": "bug1777340\tinput.java\t/^public @interface bug1777340 {$/;\"\ta\nm\tinput.java\t/^    String m();$/;\"\tm\tannotation:bug1777340\nn\tinput.java\t/^    String n() default \"ninjas; monkeys!\";$/;\"\tm\tannotation:bug1777340\n"
  },
  {
    "path": "Units/parser-java.r/bug1777340.java.d/input.java",
    "content": "public @interface bug1777340 {\n    String n() default \"ninjas; monkeys!\";\n    String m();\n}\n"
  },
  {
    "path": "Units/parser-java.r/bug1777344.java.b/expected.tags",
    "content": "b\tinput.java\t/^    private boolean b = (1 < 3), c;$/;\"\tf\tclass:bug1777344\tfile:\nbug1777344\tinput.java\t/^public class bug1777344<K, V> {$/;\"\tc\nc\tinput.java\t/^    private boolean b = (1 < 3), c;$/;\"\tf\tclass:bug1777344\tfile:\nd\tinput.java\t/^    private boolean d = 1 < 3, e;$/;\"\tf\tclass:bug1777344\tfile:\ne\tinput.java\t/^    private boolean d = 1 < 3, e;$/;\"\tf\tclass:bug1777344\tfile:\nmap1\tinput.java\t/^    private HashMap<K,V> map1;$/;\"\tf\tclass:bug1777344\tfile:\nmap2\tinput.java\t/^    private HashMap<K,V> map2 = new HashMap<K,V>(), map3;$/;\"\tf\tclass:bug1777344\tfile:\nmap3\tinput.java\t/^    private HashMap<K,V> map2 = new HashMap<K,V>(), map3;$/;\"\tf\tclass:bug1777344\tfile:\n"
  },
  {
    "path": "Units/parser-java.r/bug1777344.java.b/input.java",
    "content": "import java.util.*;\npublic class bug1777344<K, V> {\n    private HashMap<K,V> map1;\n    private HashMap<K,V> map2 = new HashMap<K,V>(), map3;\n    private boolean b = (1 < 3), c;\n    private boolean d = 1 < 3, e;\n}\n"
  },
  {
    "path": "Units/parser-java.r/bug2049723.java.d/expected.tags",
    "content": "bug2049723\tinput.java\t/^public class bug2049723 {$/;\"\tc\nm1\tinput.java\t/^  public void m1(String arg) {}$/;\"\tm\tclass:bug2049723\nm2\tinput.java\t/^  public void m2(@Nonnull String arg) {}$/;\"\tm\tclass:bug2049723\n"
  },
  {
    "path": "Units/parser-java.r/bug2049723.java.d/input.java",
    "content": "import javax.annotation.Nonnull;\n\npublic class bug2049723 {\n  public void m1(String arg) {}\n  public void m2(@Nonnull String arg) {}\n}\n"
  },
  {
    "path": "Units/parser-java.r/bug2117073.java.d/expected.tags",
    "content": "AAssignmentExp\tinput.java\t/^  public AAssignmentExp(@SuppressWarnings(\"hiding\") TAssign _token_,$/;\"\tm\tclass:AAssignmentExp\nAAssignmentExp\tinput.java\t/^public class AAssignmentExp {$/;\"\tc\nremoveChild\tinput.java\t/^  @Override void removeChild(@SuppressWarnings(\"unused\") Node child) {$/;\"\tm\tclass:AAssignmentExp\n"
  },
  {
    "path": "Units/parser-java.r/bug2117073.java.d/input.java",
    "content": "public class AAssignmentExp {\n  public AAssignmentExp(@SuppressWarnings(\"hiding\") TAssign _token_,\n                        @SuppressWarnings(\"hiding\") PLvalue _lvalue_,\n                        @SuppressWarnings(\"hiding\") PExp _exp_) {\n    setToken(_token_);\n    setLvalue(_lvalue_);\n    setExp(_exp_);\n  }\n\n  @Override void removeChild(@SuppressWarnings(\"unused\") Node child) {\n  }\n}\n"
  },
  {
    "path": "Units/parser-java.r/bug814263.java.d/expected.tags",
    "content": "bug814263\tinput.java\t/^public class bug814263 {$/;\"\tc\nmap1\tinput.java\t/^ protected java.util.Map map1;$/;\"\tf\tclass:bug814263\nmap2\tinput.java\t/^ protected Map map2;$/;\"\tf\tclass:bug814263\n"
  },
  {
    "path": "Units/parser-java.r/bug814263.java.d/input.java",
    "content": "import java.util.Map;\n\npublic class bug814263 {\n protected java.util.Map map1;\n protected Map map2;\n}\n"
  },
  {
    "path": "Units/parser-java.r/default-literals.d/README",
    "content": "This is the test case for the behavior of CPreProcessor parser.\nAs the Java program, the input.java may not valid.\n"
  },
  {
    "path": "Units/parser-java.r/default-literals.d/args.ctags",
    "content": "--sort=no\n--fields=+{signature}\n"
  },
  {
    "path": "Units/parser-java.r/default-literals.d/expected.tags",
    "content": "Input\tinput.java\t/^public class Input {$/;\"\tc\nf\tinput.java\t/^    public void f(String prefix = \"abc\\\\\"\") {}$/;\"\tm\tclass:Input\tsignature:(String prefix = \"abc\\\\\"\")\ng\tinput.java\t/^    public void g(char = '\\\\'') {}$/;\"\tm\tclass:Input\tsignature:(char = '\\\\'')\n"
  },
  {
    "path": "Units/parser-java.r/default-literals.d/input.java",
    "content": "public class Input {\n    public void f(String prefix = \"abc\\\"\") {}\n    public void g(char = '\\'') {}\n}\n\n"
  },
  {
    "path": "Units/parser-java.r/enum.java.d/args.ctags",
    "content": "--fields=+e\n"
  },
  {
    "path": "Units/parser-java.r/enum.java.d/expected.tags",
    "content": "A\tinput.java\t/^\tA,    \\/\\/ should be 'e', not 'f'$/;\"\te\tenum:e\tfile:\tend:2\nB\tinput.java\t/^\tB(),  \\/\\/ should be 'e', not 'm'$/;\"\te\tenum:e\tfile:\tend:3\nC\tinput.java\t/^\tC(1), \\/\\/ should be 'e', not missing$/;\"\te\tenum:e\tfile:\tend:4\nD\tinput.java\t/^\tD,    \\/\\/ should be 'e', not 'f'$/;\"\te\tenum:e\tfile:\tend:5\nE\tinput.java\t/^\tE(),  \\/\\/ should be 'e', not 'm'$/;\"\te\tenum:e\tfile:\tend:6\nF\tinput.java\t/^\tF(1), \\/\\/ should be 'e', not missing$/;\"\te\tenum:e\tfile:\tend:7\ne\tinput.java\t/^        e() {}$/;\"\tm\tclass:e\tend:11\ne\tinput.java\t/^        e(int x) {}$/;\"\tm\tclass:e\tend:10\ne\tinput.java\t/^public enum e {$/;\"\tg\tend:23\ngetShape\tinput.java\t/^\tpublic final Shape getShape() {$/;\"\tm\tclass:e\tend:22\ngetString\tinput.java\t/^\tpublic String getString() {$/;\"\tm\tclass:e\tend:19\nshape\tinput.java\t/^\tpublic final Shape shape;$/;\"\tf\tclass:e\tend:14\nstring\tinput.java\t/^\tpublic String string;$/;\"\tf\tclass:e\tend:13\ntwoKeywordsInARow\tinput.java\t/^\tpublic final boolean twoKeywordsInARow;$/;\"\tf\tclass:e\tend:15\n"
  },
  {
    "path": "Units/parser-java.r/enum.java.d/input.java",
    "content": "public enum e {\n\tA,    // should be 'e', not 'f'\n\tB(),  // should be 'e', not 'm'\n\tC(1), // should be 'e', not missing\n\tD,    // should be 'e', not 'f'\n\tE(),  // should be 'e', not 'm'\n\tF(1), // should be 'e', not missing\n\t;\n\n        e(int x) {}\n        e() {}\n\n\tpublic String string;\n\tpublic final Shape shape;\n\tpublic final boolean twoKeywordsInARow;\n\n\tpublic String getString() {\n\t\treturn string;\n\t}\n\tpublic final Shape getShape() {\n\t\treturn shape;\n\t}\n}\n"
  },
  {
    "path": "Units/parser-java.r/imported-role.d/args.ctags",
    "content": "--extras=+r\n--fields=+r\n--sort=no\n"
  },
  {
    "path": "Units/parser-java.r/imported-role.d/expected.tags",
    "content": "X\tinput.java\t/^package X;$/;\"\tp\troles:def\njava.util.Map\tinput.java\t/^import java.util.Map;$/;\"\tp\troles:imported\njava.util.*\tinput.java\t/^import java.util.*;$/;\"\tp\troles:imported\n"
  },
  {
    "path": "Units/parser-java.r/imported-role.d/input.java",
    "content": "package X;\nimport java.util.Map;\nimport java.util.*;\n"
  },
  {
    "path": "Units/parser-java.r/infinite_loop.java.d/expected.tags",
    "content": "C\tinput.java\t/^class C {$/;\"\tc\n"
  },
  {
    "path": "Units/parser-java.r/infinite_loop.java.d/input.java",
    "content": "class C {\n void main"
  },
  {
    "path": "Units/parser-java.r/java-catch-block.d/args.ctags",
    "content": "--fields=+Ke\n--kinds-java=+l\n\n"
  },
  {
    "path": "Units/parser-java.r/java-catch-block.d/expected.tags",
    "content": "C\tinput.java\t/^class C {$/;\"\tclass\tend:7\nm\tinput.java\t/^   public void m(String a[]) {$/;\"\tmethod\tclass:C\tend:6\n"
  },
  {
    "path": "Units/parser-java.r/java-catch-block.d/input.java",
    "content": "// Based on code reported by @brate in #797\nclass C {\n   public void m(String a[]) {\n       try {}\n       catch (Exception e) {}\n   }\n}\n"
  },
  {
    "path": "Units/parser-java.r/java_enum.java.d/args.ctags",
    "content": "--fields=+e\n"
  },
  {
    "path": "Units/parser-java.r/java_enum.java.d/expected.tags",
    "content": "A\tinput.java\t/^\t\tA(1), B(2);$/;\"\te\tenum:C.FancyEnum\tfile:\tend:7\nB\tinput.java\t/^\t\tA(1), B(2);$/;\"\te\tenum:C.FancyEnum\tfile:\tend:7\nC\tinput.java\t/^public class C {$/;\"\tc\tend:15\nFIRST_VALUE\tinput.java\t/^\t\tFIRST_VALUE,$/;\"\te\tenum:C.TrivialEnum\tfile:\tend:3\nFancyEnum\tinput.java\t/^\t\tFancyEnum(int i) {$/;\"\tm\tclass:C.FancyEnum\tend:11\nFancyEnum\tinput.java\t/^\tpublic enum FancyEnum {$/;\"\tg\tclass:C\tend:14\nSECOND_VALUE\tinput.java\t/^\t\tSECOND_VALUE$/;\"\te\tenum:C.TrivialEnum\tfile:\tend:4\nStringEnum\tinput.java\t/^\tprivate StringEnum(String _s) {$/;\"\tm\tclass:StringEnum\tfile:\tend:25\nStringEnum\tinput.java\t/^public enum StringEnum {$/;\"\tg\tend:28\nTrivialEnum\tinput.java\t/^\tpublic enum TrivialEnum {$/;\"\tg\tclass:C\tend:5\nX\tinput.java\t/^\tX(\"X\"),$/;\"\te\tenum:StringEnum\tfile:\tend:19\nY\tinput.java\t/^\tY(\"Y\"),$/;\"\te\tenum:StringEnum\tfile:\tend:20\nZ\tinput.java\t/^\tZ(\"Z\");$/;\"\te\tenum:StringEnum\tfile:\tend:21\ni\tinput.java\t/^\t\tprivate int i;$/;\"\tf\tclass:C.FancyEnum\tfile:\tend:8\nm\tinput.java\t/^\t\tvoid m() {$/;\"\tm\tclass:C.FancyEnum\tend:13\ns\tinput.java\t/^\tprivate final String s;$/;\"\tf\tclass:StringEnum\tfile:\tend:27\n"
  },
  {
    "path": "Units/parser-java.r/java_enum.java.d/input.java",
    "content": "public class C {\n\tpublic enum TrivialEnum {\n\t\tFIRST_VALUE,\n\t\tSECOND_VALUE\n\t}\n\tpublic enum FancyEnum {\n\t\tA(1), B(2);\n\t\tprivate int i;\n\t\tFancyEnum(int i) {\n\t\t\tthis.i = i;\n\t\t}\n\t\tvoid m() {\n\t\t}\n\t}\n}\n\npublic enum StringEnum {\n\n\tX(\"X\"),\n\tY(\"Y\"),\n\tZ(\"Z\");\n\n\tprivate StringEnum(String _s) {\n\t\ts = _s;\n\t}\n\n\tprivate final String s;\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/1795612.js.d/README",
    "content": "Though the original comment expects generating full qualified tags,\nJavaScript parser doesn't support generating them.\n"
  },
  {
    "path": "Units/parser-javascript.r/1795612.js.d/expected.tags",
    "content": "Test.RPC\tinput.js\t/^Test.RPC =$/;\"\tp\nasyncMethod\tinput.js\t/^\tasyncMethod: function($/;\"\tm\tproperty:Test.RPC\nasyncRequest\tinput.js\t/^\tasyncRequest: function($/;\"\tm\tproperty:Test.RPC\nrequest_id\tinput.js\t/^\trequest_id: 0,$/;\"\tp\tproperty:Test.RPC\n"
  },
  {
    "path": "Units/parser-javascript.r/1795612.js.d/input.js",
    "content": "\r\n// This file should generate the following tags:\r\n//    classes\r\n//      Test.RPC\r\n//    methods\r\n//      Test.RPC.asyncMethod\r\n//      Test.RPC.asyncRequest\r\n//    properties\r\n//      Test.RPC.request_id\r\nTest.RPC =\r\n{\r\n\trequest_id: 0,\r\n\r\n\tasyncRequest: function(\r\n\t\t/* string */\turi,\r\n\t\t/* object */\tdata,\r\n\t\t/* object */\tcallback)\r\n\t{\r\n\t},\r\n\r\n\tasyncMethod: function(\r\n\t\t/* string */\turi,\r\n\t\t/* string */\tmethod,\r\n\t\t/* array */\t\tparams,\r\n\t\t/* object */\tcallback)\r\n\t{\r\n\t}\r\n};\r\n\r\n"
  },
  {
    "path": "Units/parser-javascript.r/1850914.js.d/expected.tags",
    "content": "objLiteralMethod\tinput.js\t/^objLiteralMethod : function(){}$/;\"\tm\tvariable:objectLiteral\nobjLiteralProperty\tinput.js\t/^objLiteralProperty : 1,$/;\"\tp\tvariable:objectLiteral\nobjectLiteral\tinput.js\t/^var objectLiteral = {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/1850914.js.d/input.js",
    "content": "// This file should generate the following tags:\r\n//\r\n//   classes\r\n//     objectLiteral\r\n//   methods\r\n//     objectLiteral.objLiteralMethod\r\n//   properties\r\n//     objectLiteral.objLiteralProperty\r\n\r\n\r\n/**\r\n* This is an object literal\r\n*/\r\nvar objectLiteral = {\r\n/**\r\n* This is a literal object property\r\n*/\r\nobjLiteralProperty : 1,\r\n/**\r\n* This is a literal object method\r\n*/\r\nobjLiteralMethod : function(){}\r\n}\r\n\r\n"
  },
  {
    "path": "Units/parser-javascript.r/1878155.js.d/expected.tags",
    "content": "RE\tinput.js\t/^var RE={\"bar\":\\/foo\\\\\"\\/};$/;\"\tv\nbar\tinput.js\t/^var RE={\"bar\":\\/foo\\\\\"\\/};$/;\"\tp\tvariable:RE\nfoo\tinput.js\t/^var foo=\"foo \\\\\" some other stuff\";$/;\"\tv\nmy_function\tinput.js\t/^function my_function() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/1878155.js.d/input.js",
    "content": "// Tags should include:\r\n//   functions\r\n//       my_function\r\n//   classes\r\n//       RE\r\n//   global variables\r\n//       foo\r\n//\r\n\r\n// This should handle the escaped quote\r\nvar RE={\"bar\":/foo\\\"/};\r\n\r\n// This should also handle the escaped quote\r\n// A tag should be created for the global variable \"foo\".\r\nvar foo=\"foo \\\" some other stuff\";\r\n\r\n// A tag should be created for this function \"my_function\".\r\nfunction my_function() {\r\n}\r\n"
  },
  {
    "path": "Units/parser-javascript.r/1880687.js.d/expected.tags",
    "content": "MyClass\tinput.js\t/^MyClass = {$/;\"\tv\nMyClass_sub1\tinput.js\t/^    MyClass_sub1: function(x){$/;\"\tm\tvariable:MyClass\nMyClass_sub2\tinput.js\t/^    MyClass_sub2: function(x){$/;\"\tm\tvariable:MyClass\na\tinput.js\t/^function a(flag){$/;\"\tf\naa\tinput.js\t/^function aa(){$/;\"\tf\naa_sub1\tinput.js\t/^    function aa_sub1(){$/;\"\tf\tfunction:aa\naa_sub2\tinput.js\t/^    function aa_sub2(){$/;\"\tf\tfunction:aa\nb\tinput.js\t/^function b(){$/;\"\tf\nbaz\tinput.js\t/^    function baz() {$/;\"\tf\tfunction:f\nc\tinput.js\t/^function c(flag){$/;\"\tf\nd\tinput.js\t/^function d(){$/;\"\tf\ne\tinput.js\t/^function e(flag){$/;\"\tf\nf\tinput.js\t/^function f(){$/;\"\tf\ng\tinput.js\t/^function g(flag){$/;\"\tf\nh\tinput.js\t/^function h(){$/;\"\tf\ni\tinput.js\t/^function i(flag){$/;\"\tf\nj\tinput.js\t/^function j(){$/;\"\tf\nk\tinput.js\t/^function k(flag){$/;\"\tf\nl\tinput.js\t/^function l(){$/;\"\tf\nm\tinput.js\t/^function m(flag){$/;\"\tf\nn\tinput.js\t/^function n(){$/;\"\tf\no\tinput.js\t/^function o(){$/;\"\tf\np\tinput.js\t/^function p(){$/;\"\tf\nq\tinput.js\t/^function q(){$/;\"\tf\nr\tinput.js\t/^function r(flag){$/;\"\tf\ns\tinput.js\t/^function s(){$/;\"\tf\nt\tinput.js\t/^function t(flag){$/;\"\tf\nu\tinput.js\t/^function u(flag){$/;\"\tf\nv\tinput.js\t/^function v(flag){$/;\"\tf\nw\tinput.js\t/^function w(){$/;\"\tf\nw_sub1\tinput.js\t/^    function w_sub1(x){$/;\"\tf\tfunction:w\nw_sub2\tinput.js\t/^    function w_sub2(){$/;\"\tf\tfunction:w\nx\tinput.js\t/^function x(){$/;\"\tf\nx_sub1\tinput.js\t/^    function x_sub1(){$/;\"\tf\tfunction:x\nx_sub2\tinput.js\t/^    function x_sub2(){$/;\"\tf\tfunction:x\ny\tinput.js\t/^function y(){$/;\"\tf\ny_sub1\tinput.js\t/^    function y_sub1(){$/;\"\tf\tfunction:y\ny_sub2\tinput.js\t/^    function y_sub2(){$/;\"\tf\tfunction:y\nz\tinput.js\t/^function z(){$/;\"\tf\nz_sub1\tinput.js\t/^    function z_sub1(){$/;\"\tf\tfunction:z\nz_sub2\tinput.js\t/^    function z_sub2(){$/;\"\tf\tfunction:z\n"
  },
  {
    "path": "Units/parser-javascript.r/1880687.js.d/input.js",
    "content": "\r\n// All these examples contain various forms of statements\r\n// with missing semicolons.  Each of these are valid and must\r\n// be accommodated.\r\n//\r\n// After running ctags: ctags -f tags 1880687.js\r\n// The following tags should be generated:\r\n//     functions\r\n//       a\r\n//       aa\r\n//       aa_sub1 [aa]\r\n//       aa_sub2 [aa]\r\n//       b\r\n//       baz [f]\r\n//       c\r\n//       d\r\n//       e\r\n//       f\r\n//       g\r\n//       h\r\n//       i\r\n//       j\r\n//       k\r\n//       l\r\n//       m\r\n//       n\r\n//       o\r\n//       p\r\n//       q\r\n//       r\r\n//       s\r\n//       t\r\n//       u\r\n//       v\r\n//       w\r\n//       w_sub1 [w]\r\n//       w_sub2 [w]\r\n//       x\r\n//       x_sub1 [x]\r\n//       x_sub2 [x]\r\n//       y\r\n//       y_sub1 [y]\r\n//       y_sub2 [y]\r\n//       z\r\n//       z_sub1 [z]\r\n//       z_sub2 [z]\r\n//     classes\r\n//       MyClass\r\n//     methods\r\n//       MyClass_sub1 [MyClass]\r\n//       MyClass_sub2 [MyClass]\r\n\r\nfunction a(flag){\r\n    if(flag)\r\n        test(1);\r\n    else\r\n        test(2)\r\n}\r\n\r\nfunction b(){\r\n    var b= 33;\r\n}\r\n\r\nfunction c(flag){\r\n    if(flag)\r\n        test(1);\r\n}\r\n\r\nfunction d(){\r\n    var b= 33;\r\n}\r\n\r\nfunction e(flag){\r\n    if(flag)\r\n        test(1)\r\n}\r\n\r\nfunction f(){\r\n    var b= 33;\r\n    if (foo)\r\n            bar();\r\n    else\r\n        test(2);\r\n    function baz() {\r\n    }\r\n}\r\n\r\nfunction g(flag){\r\n    if(flag) {\r\n        test(1)\r\n    }\r\n}\r\n\r\nfunction h(){\r\n    var b= 33;\r\n}\r\n\r\nfunction i(flag){\r\n    if(flag) {\r\n        test(1);\r\n    }\r\n}\r\n\r\nfunction j(){\r\n    var b= 33;\r\n}\r\n\r\nfunction k(flag){\r\n    if(flag) {\r\n        test(1);\r\n    }\r\n    else\r\n        flag = false;\r\n}\r\n\r\nfunction l(){\r\n    var b= 33;\r\n}\r\n\r\nfunction m(flag){\r\n    if(flag) {\r\n        test(1);\r\n    }\r\n    else {\r\n        flag = false;\r\n    }\r\n}\r\n\r\nfunction n(){\r\n    var b= 33;\r\n}\r\n\r\nif (1)\r\n    l();\r\nfunction o(){\r\n    var b= 33;\r\n}\r\n\r\nif (1){\r\n    l();\r\n}\r\nfunction p(){\r\n    var b= 33;\r\n}\r\n\r\nif (1){\r\n    l();\r\n} else\r\n    l();\r\nfunction q(){\r\n    var b= 33;\r\n}\r\n\r\nfunction r(flag){\r\n    if (flag) {\r\n        value = 33\r\n    }\r\n}\r\n\r\nfunction s(){\r\n    var b= 33;\r\n}\r\n\r\nfunction t(flag){\r\n    if (flag) {\r\n        b= new Object()\r\n    }\r\n}\r\n\r\nfunction u(flag){\r\n    if (flag) {\r\n        b= ({})\r\n    }\r\n}\r\n\r\nfunction v(flag){\r\n    if (flag) {\r\n        b= {}\r\n    }\r\n}\r\n\r\nfunction w(){\r\n    function w_sub1(x){\r\n        if (! x)\r\n            x = {foo:bar};\r\n        \r\n        var dummy1, dummy2;\r\n    }\r\n    function w_sub2(){\r\n    }\r\n}\r\n\r\nMyClass = {\r\n    MyClass_sub1: function(x){\r\n        if (! x)\r\n            x = { };\r\n        \r\n        var dummy3, dummy4;\r\n    },\r\n    MyClass_sub2: function(x){\r\n        var dummy5 = 42;\r\n    }\r\n};\r\n\r\nfunction x(){\r\n    function x_sub1(){\r\n        while (1)\r\n            x_sub2()\r\n    }\r\n    function x_sub2(){\r\n    }\r\n}\r\n\r\nfunction y(){\r\n    function y_sub1(){\r\n        while (1) {\r\n            y_sub2()\r\n        }\r\n    }\r\n    function y_sub2(){\r\n    }\r\n}\r\n\r\nfunction z(){\r\n    function z_sub1(){\r\n        do {\r\n            z_sub2()\r\n        } while (0)\r\n    }\r\n    function z_sub2(){\r\n    }\r\n}\r\n\r\nfunction aa(){\r\n    function aa_sub1(){\r\n        do\r\n            aa_sub2()\r\n        while (0)\r\n    }\r\n    function aa_sub2(){\r\n    }\r\n}\r\n"
  },
  {
    "path": "Units/parser-javascript.r/2023624.js.d/expected.tags",
    "content": "f1\tinput.js\t/^function f1() {$/;\"\tf\nf2\tinput.js\t/^function f2() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/2023624.js.d/input.js",
    "content": "/*\r\n * Both functions should be tagged.\r\n * The embedded quote was fixed in issue:\r\n * [ 1878155 ] Javascript escaped quotation mark brakes output\r\n * [ 2023712 ] parseString for javascript broken on embedded quote\r\n * The fix will be part of the 5.8 release.\r\n */\r\n\r\nfunction f1() {\r\n    var str = 'This function will be listed.';\r\n}\r\n\r\nfunction f2() {\r\n    var str = 'This function won\\'t.';\r\n}\r\n"
  },
  {
    "path": "Units/parser-javascript.r/3470609.js.d/expected.tags",
    "content": "array\tinput.js\t/^    'array' : [1, 2, 3],$/;\"\tp\tvariable:root\ndecimal\tinput.js\t/^    'decimal' : 1.3,$/;\"\tp\tvariable:root\nf\tinput.js\t/^function f() {$/;\"\tf\nid\tinput.js\t/^    'id' : 1,$/;\"\tp\tvariable:root\nmethod\tinput.js\t/^    'method' : function() {$/;\"\tm\tvariable:root\nneg\tinput.js\t/^    'neg' : -1,$/;\"\tp\tvariable:root\nparentheses\tinput.js\t/^    'parentheses' : (2 * (2 + 3))$/;\"\tp\tvariable:root\nroot\tinput.js\t/^var root = {$/;\"\tv\nstring\tinput.js\t/^    'string' : 'hello world',$/;\"\tp\tvariable:root\nsubFunction\tinput.js\t/^        'subFunction': function() {$/;\"\tm\tproperty:root.subObject\nsubObject\tinput.js\t/^    'subObject' : {$/;\"\tp\tvariable:root\nsubProperty\tinput.js\t/^        'subProperty': 42,$/;\"\tp\tproperty:root.subObject\n"
  },
  {
    "path": "Units/parser-javascript.r/3470609.js.d/input.js",
    "content": "/*\r\n * Test for properties values.  Everything is valid here and must be\r\n * correctly parsed.\r\n * \r\n * Output of ctags -f - 3470609.js should be:\r\n * \r\n * Properties:\r\n *    root.array\r\n *    root.decimal\r\n *    root.id\r\n *    root.neg\r\n *    root.parentheses\r\n *    root.string\r\n *    root.subObject.subProperty\r\n * \r\n * Classes:\r\n *    root\r\n *    root.subObject\r\n * \r\n * Methods:\r\n *    root.method\r\n *    root.subObject.subFunction\r\n * \r\n * Functions:\r\n *    f\r\n */\r\n\r\nvar root = {\r\n    'string' : 'hello world',\r\n    'method' : function() {\r\n        x = 42;\r\n    },\r\n    'id' : 1,\r\n    'neg' : -1,\r\n    'decimal' : 1.3,\r\n    'subObject' : {\r\n        'subProperty': 42,\r\n        'subFunction': function() {\r\n            y = 43;\r\n        }\r\n    },\r\n    'array' : [1, 2, 3],\r\n    'parentheses' : (2 * (2 + 3))\r\n}\r\n\r\nfunction f() {\r\n\r\n}\r\n"
  },
  {
    "path": "Units/parser-javascript.r/babel-decorators.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/babel-decorators.d/expected.tags",
    "content": "Example\tinput.js\t/^class Example {$/;\"\tc\ndoSomething\tinput.js\t/^  doSomething() {$/;\"\tm\tclass:Example\nMyClass\tinput.js\t/^class MyClass {$/;\"\tc\nmy_method\tinput.js\t/^  my_method() {}$/;\"\tm\tclass:MyClass\nYourClass\tinput.js\t/^class YourClass {$/;\"\tc\nyour_method\tinput.js\t/^  @decorator @dec(arg1, arg2) @namespace.decorator @(complex ? dec1 : dec2) your_method() {}$/;\"\tm\tclass:YourClass\n"
  },
  {
    "path": "Units/parser-javascript.r/babel-decorators.d/input.js",
    "content": "// Taken from https://www.sitepoint.com/javascript-decorators-what-they-are/\n@log()\n@immutable()\nclass Example {\n  @time('demo')\n  doSomething() {\n    //\n  }\n}\n\n// Taken from https://babeljs.io/blog/2018/09/17/decorators\nclass MyClass {\n  @decorator\n  @dec(arg1, arg2)\n  @namespace.decorator\n  @(complex ? dec1 : dec2)\n  my_method() {}\n}\n\nclass YourClass {\n  @decorator @dec(arg1, arg2) @namespace.decorator @(complex ? dec1 : dec2) your_method() {}\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/bug1950327.js.d/expected.tags",
    "content": "*\tinput.js\t/^\t\tcontainer.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false}\t\t$/;\"\tp\tproperty:container.dirtyTab\nDifferent\tinput.js\t/^Different.prototype = {$/;\"\tc\nTabChrome\tinput.js\t/^TabChrome.prototype = {$/;\"\tc\ncontainer.dirtyTab\tinput.js\t/^\t\tcontainer.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false}\t\t$/;\"\tp\ncreateTabTile\tinput.js\t/^\tcreateTabTile: function(browser) $/;\"\tm\tclass:Different\ncreateTabTile\tinput.js\t/^\tcreateTabTile: function(browser) $/;\"\tm\tclass:TabChrome\ndestroyTabTile\tinput.js\t/^\tdestroyTabTile: function(tile)$/;\"\tm\tclass:Different\ndestroyTabTile\tinput.js\t/^\tdestroyTabTile: function(tile)$/;\"\tm\tclass:TabChrome\ninit\tinput.js\t/^\tinit: function() $/;\"\tm\tclass:Different\ninit\tinput.js\t/^\tinit: function() $/;\"\tm\tclass:TabChrome\nsnapshot\tinput.js\t/^\t\tcontainer.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false}\t\t$/;\"\tp\tproperty:container.dirtyTab\ntitle\tinput.js\t/^\t\tcontainer.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false}\t\t$/;\"\tp\tproperty:container.dirtyTab\nurl\tinput.js\t/^\t\tcontainer.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false}\t\t$/;\"\tp\tproperty:container.dirtyTab\n"
  },
  {
    "path": "Units/parser-javascript.r/bug1950327.js.d/input.js",
    "content": "// I've attached the simple test case as bugDemo.js. Trigger the bug by\r\n// uncommenting line 8. Attached are tags files with line 21 commented/not\r\n// commented. This is the current tip, svn r663.\r\n//\r\n// When the container.dirtyTab line is uncommented you see these methods:\r\n//     TabChrome.createTabTile\r\n//     TabChrome.init\r\n//\r\n// When the container.dirtyTab line is commented you see these methods:\r\n//     TabChrome.createTabTile\r\n//     TabChrome.destroyTabTile\r\n//     TabChrome.init\r\n//\r\nTabChrome.prototype = {\r\n\tinit: function() \r\n\t{\r\n\t\tthis.browserMap = new Object();\r\n\t},\r\n\tcreateTabTile: function(browser) \r\n\t{\r\n\t\t//container.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false}\t\t\r\n\t\treturn container;\r\n\t},\r\n\tdestroyTabTile: function(tile)\r\n\t{\r\n\t}\r\n}\r\nDifferent.prototype = {\r\n\tinit: function() \r\n\t{\r\n\t\tthis.browserMap = new Object();\r\n\t},\r\n\tcreateTabTile: function(browser) \r\n\t{\r\n\t\tcontainer.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false}\t\t\r\n\t\treturn container;\r\n\t},\r\n\tdestroyTabTile: function(tile)\r\n\t{\r\n\t}\r\n}\r\n"
  },
  {
    "path": "Units/parser-javascript.r/bug2777310.js.d/expected.tags",
    "content": "a\tinput.js\t/^var a = (42 + 1) * 2;$/;\"\tv\nb\tinput.js\t/^var b = 2 * (42 + 1);$/;\"\tv\nx\tinput.js\t/^var x = 1;$/;\"\tv\ny\tinput.js\t/^var y = [];$/;\"\tv\nz\tinput.js\t/^var z = {};$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/bug2777310.js.d/input.js",
    "content": "var x = 1;\nvar z = {};\nvar y = [];\nvar a = (42 + 1) * 2;\nvar b = 2 * (42 + 1);\n\n"
  },
  {
    "path": "Units/parser-javascript.r/bug2888482.js.d/expected.tags",
    "content": "onsubmit\tinput.js\t/^\t\teditFormEl.onsubmit = function() {$/;\"\tf\tvariable:editFormEl\nscrollEditBox\tinput.js\t/^function scrollEditBox() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/bug2888482.js.d/input.js",
    "content": "function scrollEditBox() {\n\tvar editBoxEl = document.getElementById(\"wpTextbox1\");\n\tvar scrollTopEl = document.getElementById(\"wpScrolltop\");\n\tvar editFormEl = document.getElementById(\"editform\");\n\n\tif (editBoxEl && scrollTopEl) {\n\t\tif (scrollTopEl.value) editBoxEl.scrollTop = scrollTopEl.value;\n\t\teditFormEl.onsubmit = function() {\n\t\t\tdocument.getElementById(\"wpScrolltop\").value = document.getElementById(\"wpTextbox1\").scrollTop;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/bug3036476.js.d/expected.tags",
    "content": "container\tinput.js\t/^var container = {};$/;\"\tv\nmethod1\tinput.js\t/^container.object.method1 = function() {}$/;\"\tf\tfunction:container.object\nmethod2\tinput.js\t/^container.object.method2 = function() {}$/;\"\tf\tfunction:container.object\nobject\tinput.js\t/^container.object = function() {}$/;\"\tf\tvariable:container\n"
  },
  {
    "path": "Units/parser-javascript.r/bug3036476.js.d/input.js",
    "content": "/*\r\n * \"Lowercase \"object\" isn't a keyword\"\r\n * \r\n * ctags -f - bug3036476.js should output:\r\n * \r\n * variables:\r\n *    container\r\n * \r\n * functions:\r\n *    container.object\r\n *    container.object.method1\r\n *    container.object.method2\r\n */\r\n\r\nvar container = {};\r\n\r\ncontainer.object = function() {}\r\ncontainer.object.method1 = function() {}\r\ncontainer.object.method2 = function() {}\r\n\r\n"
  },
  {
    "path": "Units/parser-javascript.r/bug3571233.js.d/expected.tags",
    "content": "MyClass\tinput.js\t/^function MyClass() {$/;\"\tc\nfunction1\tinput.js\t/^function function1() {$/;\"\tf\nfunction2\tinput.js\t/^function2 = function() {$/;\"\tf\nmethod2\tinput.js\t/^MyClass.prototype.method2 = function() {$/;\"\tm\tclass:MyClass\nnestedFunction1\tinput.js\t/^  function nestedFunction1() {$/;\"\tf\tmethod:MyClass.method2\nnestedFunction2\tinput.js\t/^  function nestedFunction2() {$/;\"\tf\tmethod:MyClass.method2\nnestedFunction3\tinput.js\t/^  function nestedFunction3() {$/;\"\tf\tfunction:function1\nnestedFunction4\tinput.js\t/^  function nestedFunction4() {$/;\"\tf\tfunction:function2\nnestedFunction5\tinput.js\t/^  function nestedFunction5() {$/;\"\tf\tfunction:function2\n"
  },
  {
    "path": "Units/parser-javascript.r/bug3571233.js.d/input.js",
    "content": "/*\r\n * \"Functions nested inside methods show improper scope with the parent method\r\n * being reported as \"function\"\"\r\n * \r\n * ctags -f - bug3571233.js should output:\r\n * \r\n * classes\r\n *    MyClass\r\n * \r\n * methods\r\n *    MyClass.method2\r\n * \r\n * functions\r\n *    MyClass.method2.nestedFunction1\r\n *    MyClass.method2.nestedFunction2\r\n *    function1\r\n *    function1.nestedFunction3\r\n *    function2\r\n *    function2.nestedFunction4\r\n *    function2.nestedFunction5\r\n * \r\n * \r\n * Note that MyClass is shown both as a class and as a function (the parser\r\n * discovers it actually is a class only later on).  This isn't really easy to\r\n * fix because a JavaScript function is only a class if it happen to be used as\r\n * one, for example it has prototypes.\r\n */\r\n\r\nfunction MyClass() {\r\n}\r\n\r\nMyClass.prototype.method2 = function() {\r\n  // these functions have improper scope\r\n  function nestedFunction1() {\r\n    \r\n  }\r\n  \r\n  function nestedFunction2() {\r\n    \r\n  }\r\n};\r\n\r\n// following work fine, just here as a reference\r\nfunction function1() {\r\n  function nestedFunction3() {\r\n  }\r\n};\r\n\r\nfunction2 = function() {\r\n  function nestedFunction4() {\r\n  }\r\n  \r\n  function nestedFunction5() {\r\n  }\r\n};\r\n\r\n"
  },
  {
    "path": "Units/parser-javascript.r/contextual.d/expected.tags",
    "content": "Function\tinput.js\t/^  Function() { return 0x32 }$/;\"\tm\tclass:Syn3\nFunction\tinput.js\t/^  Function() { return Syn2; },$/;\"\tm\tclass:Syn2\nFunction\tinput.js\t/^  Function:function() { return Syn1; },$/;\"\tm\tclass:Syn1\nFunction\tinput.js\t/^function Function() { return 0x103; }$/;\"\tc\nObject\tinput.js\t/^  Object() { return 0x31 }$/;\"\tm\tclass:Syn3\nObject\tinput.js\t/^  Object() { return this; },$/;\"\tm\tclass:Syn2\nObject\tinput.js\t/^  Object:function() { return this; },$/;\"\tm\tclass:Syn1\nObject\tinput.js\t/^function Object() { return 0x102; }$/;\"\tc\nSyn1\tinput.js\t/^let Syn1=function(){}$/;\"\tc\nSyn2\tinput.js\t/^let Syn2=function(){}$/;\"\tc\nSyn3\tinput.js\t/^class Syn3 {$/;\"\tc\nas\tinput.js\t/^  as() { return 0x21; }$/;\"\tm\tclass:Syn3\nas\tinput.js\t/^  as() { return 0x21; },$/;\"\tm\tclass:Syn2\nas\tinput.js\t/^  as:function() { return 0x21; },$/;\"\tm\tclass:Syn1\nas\tinput.js\t/^function as() { return 0x21; }$/;\"\tf\nasync\tinput.js\t/^  async() { return 0x20; }$/;\"\tm\tclass:Syn3\nasync\tinput.js\t/^  async() {$/;\"\tm\tclass:Syn2\nasync\tinput.js\t/^  async:function() {$/;\"\tm\tclass:Syn1\nasync\tinput.js\t/^function async() { return 0x22; }$/;\"\tf\nawait\tinput.js\t/^  await() { return 0x01; }$/;\"\tm\tclass:Syn3\nawait\tinput.js\t/^  await() { return 0x01; },$/;\"\tm\tclass:Syn2\nawait\tinput.js\t/^  await:function() { return 0x01; },$/;\"\tm\tclass:Syn1\nawait\tinput.js\t/^function await() { return 0x01; }$/;\"\tf\nfrom\tinput.js\t/^  from() { return 0x22; }$/;\"\tm\tclass:Syn3\nfrom\tinput.js\t/^  from() { return 0x22; },$/;\"\tm\tclass:Syn2\nfrom\tinput.js\t/^  from:function() { return 0x22; },$/;\"\tm\tclass:Syn1\nfrom\tinput.js\t/^function from() { return 0x23; }$/;\"\tf\nget\tinput.js\t/^  get() { return 0x24; }$/;\"\tm\tclass:Syn3\nget\tinput.js\t/^  get() {$/;\"\tm\tclass:Syn2\nget\tinput.js\t/^  get:function() {$/;\"\tm\tclass:Syn1\nget\tinput.js\t/^function get() { return 0x24; }$/;\"\tf\nimplements\tinput.js\t/^  implements() { return 0x13; }$/;\"\tm\tclass:Syn3\nimplements\tinput.js\t/^  implements() { return 0x13; },$/;\"\tm\tclass:Syn2\nimplements\tinput.js\t/^  implements:function() { return 0x13; },$/;\"\tm\tclass:Syn1\nimplements\tinput.js\t/^function implements() { return 0x13; }$/;\"\tf\ninterface\tinput.js\t/^  interface() { return 0x14; }$/;\"\tm\tclass:Syn3\ninterface\tinput.js\t/^  interface() { return 0x14; },$/;\"\tm\tclass:Syn2\ninterface\tinput.js\t/^  interface:function() { return 0x14; },$/;\"\tm\tclass:Syn1\ninterface\tinput.js\t/^function interface() { return 0x14; }$/;\"\tf\nlength\tinput.js\t/^  length:0,$/;\"\tp\tclass:Syn1\nlength\tinput.js\t/^  length:0,$/;\"\tp\tclass:Syn2\nlet\tinput.js\t/^  let() { return 0x11; }$/;\"\tm\tclass:Syn3\nlet\tinput.js\t/^  let() { return 0x11; },$/;\"\tm\tclass:Syn2\nlet\tinput.js\t/^  let:function() { return 0x11; },$/;\"\tm\tclass:Syn1\nlet\tinput.js\t/^function let() { return 0x11; }$/;\"\tf\nmeta\tinput.js\t/^  meta() { return 0x23; }$/;\"\tm\tclass:Syn3\nmeta\tinput.js\t/^  meta() { return 0x23; },$/;\"\tm\tclass:Syn2\nmeta\tinput.js\t/^  meta:function() { return 0x23; },$/;\"\tm\tclass:Syn1\nmeta\tinput.js\t/^function meta() { return 0x25; }$/;\"\tf\nof\tinput.js\t/^  of() { return 0x24; }$/;\"\tm\tclass:Syn3\nof\tinput.js\t/^  of() { return 0x24; },$/;\"\tm\tclass:Syn2\nof\tinput.js\t/^  of:function() { return 0x24; },$/;\"\tm\tclass:Syn1\nof\tinput.js\t/^function of() { return 0x26; }$/;\"\tf\npackage\tinput.js\t/^  package() { return 0x15; }$/;\"\tm\tclass:Syn3\npackage\tinput.js\t/^  package() { return 0x15; },$/;\"\tm\tclass:Syn2\npackage\tinput.js\t/^  package:function() { return 0x15; },$/;\"\tm\tclass:Syn1\npackage\tinput.js\t/^function package() { return 0x15; }$/;\"\tf\nprivate\tinput.js\t/^  private() { return 0x16; }$/;\"\tm\tclass:Syn3\nprivate\tinput.js\t/^  private() { return 0x16; },$/;\"\tm\tclass:Syn2\nprivate\tinput.js\t/^  private:function() { return 0x16; },$/;\"\tm\tclass:Syn1\nprivate\tinput.js\t/^function private() { return 0x16; }$/;\"\tf\nprotected\tinput.js\t/^  protected() { return 0x17; }$/;\"\tm\tclass:Syn3\nprotected\tinput.js\t/^  protected() { return 0x17; },$/;\"\tm\tclass:Syn2\nprotected\tinput.js\t/^  protected:function() { return 0x17; },$/;\"\tm\tclass:Syn1\nprotected\tinput.js\t/^function protected() { return 0x17; }$/;\"\tf\nprototype\tinput.js\t/^  prototype() { return 0x30 }$/;\"\tm\tclass:Syn3\nprototype\tinput.js\t/^  prototype() { return this.prototype; },$/;\"\tm\tclass:Syn2\nprototype\tinput.js\t/^  prototype:function() { return this.prototype; },$/;\"\tm\tclass:Syn1\nprototype\tinput.js\t/^function prototype() { return 0x101; }$/;\"\tf\npublic\tinput.js\t/^  public() { return 0x18; }$/;\"\tm\tclass:Syn3\npublic\tinput.js\t/^  public() { return 0x18; },$/;\"\tm\tclass:Syn2\npublic\tinput.js\t/^  public:function() { return 0x18; },$/;\"\tm\tclass:Syn1\npublic\tinput.js\t/^function public() { return 0x18; }$/;\"\tf\ns1\tinput.js\t/^let s1 = new Syn1();$/;\"\tv\ns2\tinput.js\t/^let s2 = new Syn2();$/;\"\tv\nsap\tinput.js\t/^  sap() { return \"sap\"; },$/;\"\tm\tclass:Syn2\nsap\tinput.js\t/^  sap() { return 0x33 }$/;\"\tm\tclass:Syn3\nsap\tinput.js\t/^  sap:function() { return \"sap\"; },$/;\"\tm\tclass:Syn1\nsap\tinput.js\t/^function sap() { return 0x104; }$/;\"\tf\nset\tinput.js\t/^  set(n) { return 0x25; }$/;\"\tm\tclass:Syn3\nset\tinput.js\t/^  set(n) {$/;\"\tm\tclass:Syn2\nset\tinput.js\t/^  set:function(n) {$/;\"\tm\tclass:Syn1\nset\tinput.js\t/^function set() { return 0x27; }$/;\"\tf\nstatic\tinput.js\t/^  static() { return 0x12; }$/;\"\tm\tclass:Syn3\nstatic\tinput.js\t/^  static() { return 0x12; },$/;\"\tm\tclass:Syn2\nstatic\tinput.js\t/^  static:function() { return 0x12; },$/;\"\tm\tclass:Syn1\nstatic\tinput.js\t/^function static() { return 0x12; }$/;\"\tf\ntarget\tinput.js\t/^  target() { return 0x25; },$/;\"\tm\tclass:Syn2\ntarget\tinput.js\t/^  target() { return 0x26; }$/;\"\tm\tclass:Syn3\ntarget\tinput.js\t/^  target:function() { return 0x25; },$/;\"\tm\tclass:Syn1\ntarget\tinput.js\t/^function target() { return 0x28; }$/;\"\tf\nyield\tinput.js\t/^  yield() { return 0x02; }$/;\"\tm\tclass:Syn3\nyield\tinput.js\t/^  yield() { return 0x02; },$/;\"\tm\tclass:Syn2\nyield\tinput.js\t/^  yield:function() { return 0x02; },$/;\"\tm\tclass:Syn1\nyield\tinput.js\t/^function yield() { return 0x02; } \\/\\/ invalid in strict mode$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/contextual.d/input.js",
    "content": "#!/usr/bin/env gjs\n//~ \"use strict\"\n\nlet Syn1=function(){}\nSyn1.prototype = {\n  await:function() { return 0x01; },\n  yield:function() { return 0x02; },\n  // strict-mode keywords (that are still allowed in some situations)\n  let:function() { return 0x11; },\n  static:function() { return 0x12; },\n  implements:function() { return 0x13; },\n  interface:function() { return 0x14; },\n  package:function() { return 0x15; },\n  private:function() { return 0x16; },\n  protected:function() { return 0x17; },\n  public:function() { return 0x18; },\n  // not keywords\n  as:function() { return 0x21; },\n  from:function() { return 0x22; },\n  meta:function() { return 0x23; },\n  of:function() { return 0x24; },\n  target:function() { return 0x25; },\n  get:function() {\n    return this.length;\n  },\n  length:0,\n  set:function(n) {\n    this.length=n;\n  },\n  async:function() {\n    return -this.length;\n  },\n  // stuff specific to the uctags parser\n  prototype:function() { return this.prototype; },\n  Object:function() { return this; },\n  Function:function() { return Syn1; },\n  sap:function() { return \"sap\"; },\n}\n\nlet Syn2=function(){}\nSyn2.prototype = {\n  await() { return 0x01; },\n  yield() { return 0x02; },\n  // strict-mode keywords (that are still allowed in some situations)\n  let() { return 0x11; },\n  static() { return 0x12; },\n  implements() { return 0x13; },\n  interface() { return 0x14; },\n  package() { return 0x15; },\n  private() { return 0x16; },\n  protected() { return 0x17; },\n  public() { return 0x18; },\n  // not keywords\n  as() { return 0x21; },\n  from() { return 0x22; },\n  meta() { return 0x23; },\n  of() { return 0x24; },\n  target() { return 0x25; },\n  get() {\n    return this.length;\n  },\n  length:0,\n  set(n) {\n    this.length=n;\n  },\n  async() {\n    return -this.length;\n  },\n  // stuff specific to the uctags parser\n  prototype() { return this.prototype; },\n  Object() { return this; },\n  Function() { return Syn2; },\n  sap() { return \"sap\"; },\n}\n\nclass Syn3 {\n  await() { return 0x01; }\n  yield() { return 0x02; }\n  // strict-mode keywords (that are still allowed in some situations)\n  let() { return 0x11; }\n  static() { return 0x12; }\n  implements() { return 0x13; }\n  interface() { return 0x14; }\n  package() { return 0x15; }\n  private() { return 0x16; }\n  protected() { return 0x17; }\n  public() { return 0x18; }\n  // not keywords\n  async() { return 0x20; }\n  as() { return 0x21; }\n  from() { return 0x22; }\n  get() { return 0x24; }\n  meta() { return 0x23; }\n  of() { return 0x24; }\n  set(n) { return 0x25; }\n  target() { return 0x26; }\n  // stuff specific to the uctags parser\n  prototype() { return 0x30 }\n  Object() { return 0x31 }\n  Function() { return 0x32 }\n  sap() { return 0x33 }\n}\n\nlet s1 = new Syn1();\nlet s2 = new Syn2();\nconsole.log(s1.await(), s2.await());\nconsole.log(s1.yield(), s2.yield());\nconsole.log(s1.let(), s2.let());\nconsole.log(s1.static(), s2.static());\nconsole.log(s1.implements(), s2.implements());\nconsole.log(s1.interface(), s2.interface());\nconsole.log(s1.package(), s2.package());\nconsole.log(s1.private(), s2.private());\nconsole.log(s1.protected(), s2.protected());\nconsole.log(s1.public(), s2.public());\nconsole.log(s1.as(), s2.as());\nconsole.log(s1.from(), s2.from());\nconsole.log(s1.meta(), s2.meta());\nconsole.log(s1.of(), s2.of());\nconsole.log(s1.target(), s2.target());\nconsole.log(s1.get(), s2.get());\ns1.set(21);\ns2.set(21);\nconsole.log(s1.get(), s2.get());\nconsole.log(s1.async(), s2.async());\nconsole.log(s1.prototype(), s2.prototype());\nconsole.log(s1.Object(), s2.Object());\nconsole.log(s1.Function(), s2.Function());\nconsole.log(s1.sap(), s2.sap());\n\n/* functions */\n\nfunction await() { return 0x01; }\nfunction yield() { return 0x02; } // invalid in strict mode\n// strict-mode keywords, all invalid in strict mode in this case\nfunction let() { return 0x11; }\nfunction static() { return 0x12; }\nfunction implements() { return 0x13; }\nfunction interface() { return 0x14; }\nfunction package() { return 0x15; }\nfunction private() { return 0x16; }\nfunction protected() { return 0x17; }\nfunction public() { return 0x18; }\n// not keywords\nfunction as() { return 0x21; }\nfunction async() { return 0x22; }\nfunction from() { return 0x23; }\nfunction get() { return 0x24; }\nfunction meta() { return 0x25; }\nfunction of() { return 0x26; }\nfunction set() { return 0x27; }\nfunction target() { return 0x28; }\n// stuff specific to the uctags parser\nfunction prototype() { return 0x101; }\nfunction Object() { return 0x102; }\nfunction Function() { return 0x103; }\nfunction sap() { return 0x104; }\n\nconsole.log(await())\nconsole.log(yield()) // invalid in strict mode\nconsole.log(let()) // invalid in strict mode\nconsole.log(static()) // invalid in strict mode\nconsole.log(implements()) // invalid in strict mode\nconsole.log(interface()) // invalid in strict mode\nconsole.log(package()) // invalid in strict mode\nconsole.log(private()) // invalid in strict mode\nconsole.log(protected()) // invalid in strict mode\nconsole.log(public()) // invalid in strict mode\nconsole.log(as())\nconsole.log(async())\nconsole.log(from())\nconsole.log(get())\nconsole.log(meta())\nconsole.log(of())\nconsole.log(set())\nconsole.log(target())\nconsole.log(prototype())\nconsole.log(Object())\nconsole.log(Function())\nconsole.log(sap())\n"
  },
  {
    "path": "Units/parser-javascript.r/dont-append-eof-to-repr.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-javascript.r/dont-append-eof-to-repr.d/input.js",
    "content": "t=(}\n"
  },
  {
    "path": "Units/parser-javascript.r/generators.d/expected.tags",
    "content": "g1\tinput.js\t/^  g1: function*() {$/;\"\tg\tvariable:obj1\ng2\tinput.js\t/^function *g2() {$/;\"\tg\ng3\tinput.js\t/^var g3 = function*g4(x) {$/;\"\tg\ng4\tinput.js\t/^var g3 = function*g4(x) {$/;\"\tg\ng5\tinput.js\t/^  this.g5 = function*g6() {$/;\"\tg\tfunction:obj2\ng6\tinput.js\t/^  this.g5 = function*g6() {$/;\"\tg\tfunction:obj2\nobj1\tinput.js\t/^var obj1 = {$/;\"\tv\nobj2\tinput.js\t/^var obj2 = function() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/generators.d/input.js",
    "content": "// from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions\nvar obj1 = {\n  g1: function*() {\n    var index = 0;\n    while(true)\n      yield index++;\n  }\n};\n\n// more examples\nfunction *g2() {\n  yield 42;\n}\n\nvar g3 = function*g4(x) {\n  while(true) {\n    yield x;\n    x*=x;\n  }\n}\n\nvar obj2 = function() {\n  this.x = 0;\n  this.g5 = function*g6() {\n    yield this.x;\n  }\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-1389.d/expected.tags",
    "content": "Namespace\tinput.js\t/^var Namespace = Ember.Namespace = Ember.Object.extend=({$/;\"\tv\nanonymousObject80ca49fb0105\tinput.js\t/^var Namespace = Ember.Namespace = Ember.Object.extend=({$/;\"\tv\ninit\tinput.js\t/^  init: function() {$/;\"\tm\tvariable:anonymousObject80ca49fb0105\nisNamespace\tinput.js\t/^  isNamespace: true,$/;\"\tp\tvariable:anonymousObject80ca49fb0105\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-1389.d/input.js",
    "content": "var Namespace = Ember.Namespace = Ember.Object.extend=({\n  isNamespace: true,\n\n  init: function() {\n    Ember.Namespace.NAMESPACES.push(this);\n    Ember.Namespace.PROCESSED = false;\n  }\n});\n\n// https://github.com/universal-ctags/ctags/issues/1389\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-1933.d/args.ctags",
    "content": "--fields=+S\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-1933.d/expected.tags",
    "content": "func1\tinput.js\t/^  func1: () => {$/;\"\tm\tvariable:testobj\tsignature:()\nfunc2\tinput.js\t/^  func2: () => {$/;\"\tm\tvariable:testobj\tsignature:()\nfunc3\tinput.js\t/^  func3: x => {$/;\"\tm\tvariable:testobj\tsignature:(x)\ntestobj\tinput.js\t/^testobj = {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-1933.d/input.js",
    "content": "testobj = {\n  func1: () => {\n    console.log('test1');\n  },\n  func2: () => {\n    console.log('test2');\n  },\n  func3: x => {\n    console.log(x);\n  }\n};\n\n// https://github.com/universal-ctags/ctags/issues/1933\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-3641.d/expected.tags",
    "content": "Foo\tinput.js\t/^Foo.prototype.get = function() {};$/;\"\tc\ndefinedWithFunctionAfter\tinput.js\t/^function definedWithFunctionAfter() {};$/;\"\tf\ndefinedWithFunctionBefore\tinput.js\t/^function definedWithFunctionBefore() {};$/;\"\tf\nfunctionExpressionAfter\tinput.js\t/^const functionExpressionAfter = () => {};$/;\"\tf\nfunctionExpressionBefore\tinput.js\t/^const functionExpressionBefore = () => {};$/;\"\tf\nget\tinput.js\t/^Foo.prototype.get = function() {};$/;\"\tm\tclass:Foo\nget\tinput.js\t/^function get() {};$/;\"\tf\nset\tinput.js\t/^Foo.prototype.set = () => {};$/;\"\tm\tclass:Foo\nvariableAfter\tinput.js\t/^let variableAfter = \"bar\";$/;\"\tv\nvariableBefore\tinput.js\t/^let variableBefore = \"foo\";$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-3641.d/input.js",
    "content": "function definedWithFunctionBefore() {};\nconst functionExpressionBefore = () => {};\nlet variableBefore = \"foo\";\nfunction get() {};\nfunction definedWithFunctionAfter() {};\nconst functionExpressionAfter = () => {};\nlet variableAfter = \"bar\";\n\nFoo.prototype.get = function() {};\nFoo.prototype.set = () => {};\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-4005.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-4005.d/expected.tags",
    "content": "test1\tinput.js\t/^test1 = ({}) => {}$/;\"\tf\ntest2\tinput.js\t/^test2 = ({}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-4005.d/input.js",
    "content": "test1 = ({}) => {}\n\ntest2 = ({}\n) => {}\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-780.d/expected.tags",
    "content": "Bar\tinput.js\t/^const Bar = Foo.create({$/;\"\tC\nanonymousObject6b70cce50105\tinput.js\t/^const Bar = Foo.create({$/;\"\tv\njump\tinput.js\t/^  jump() {$/;\"\tm\tvariable:anonymousObject6b70cce50105\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-780.d/input.js",
    "content": "import Foo from './foo';\n\nconst Bar = Foo.create({\n  jump() {\n    return 123;\n  }\n})\n\nexport default Bar;\n\n// https://github.com/universal-ctags/ctags/issues/780\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-900.d/expected.tags",
    "content": "anonymousFunction66f8f41f0100\tinput.js\t/^    this[0] = function() {};$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/github-issue-900.d/input.js",
    "content": "if (true) {\n    this[0] = function() {};\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-arraylist.d/expected.tags",
    "content": "a\tinput.js\t/^    { a: {}, b: {} }$/;\"\tp\tvariable:class.anonymousObjectecad86450505\na\tinput.js\t/^    { a: {}, b: {} },$/;\"\tp\tvariable:class.anonymousObjectecad86450405\na\tinput.js\t/^  { a: \"hello\", b: 42 },$/;\"\tp\tvariable:anonymousObjectecad86450105\na\tinput.js\t/^  { a: \"hi\", b: 41 }$/;\"\tp\tvariable:anonymousObjectecad86450205\na\tinput.js\t/^var a = [];$/;\"\tv\nanonymousObjectecad86450105\tinput.js\t/^  { a: \"hello\", b: 42 },$/;\"\tv\nanonymousObjectecad86450205\tinput.js\t/^  { a: \"hi\", b: 41 }$/;\"\tv\nanonymousObjectecad86450405\tinput.js\t/^    { a: {}, b: {} },$/;\"\tv\tfunction:class\nanonymousObjectecad86450505\tinput.js\t/^    { a: {}, b: {} }$/;\"\tv\tfunction:class\nb\tinput.js\t/^    { a: {}, b: {} }$/;\"\tp\tvariable:class.anonymousObjectecad86450505\nb\tinput.js\t/^    { a: {}, b: {} },$/;\"\tp\tvariable:class.anonymousObjectecad86450405\nb\tinput.js\t/^  { a: \"hello\", b: 42 },$/;\"\tp\tvariable:anonymousObjectecad86450105\nb\tinput.js\t/^  { a: \"hi\", b: 41 }$/;\"\tp\tvariable:anonymousObjectecad86450205\nb\tinput.js\t/^var b = [1, 2, 3];$/;\"\tv\nbar\tinput.js\t/^    bar: [ 4, 5, 9]$/;\"\tp\tproperty:class.test1\nc\tinput.js\t/^var c = [$/;\"\tv\nclass\tinput.js\t/^var class = function() {$/;\"\tf\nd\tinput.js\t/^var d = [$/;\"\tv\nfoo\tinput.js\t/^    foo: [ 1, 2, 3],$/;\"\tp\tproperty:class.test1\ntest1\tinput.js\t/^  this.test1 = {$/;\"\tp\tfunction:class\ntest2\tinput.js\t/^  this.test2 = [$/;\"\tp\tfunction:class\ntest3\tinput.js\t/^  this.test3 = function() {}$/;\"\tm\tfunction:class\n"
  },
  {
    "path": "Units/parser-javascript.r/js-arraylist.d/input.js",
    "content": "\nvar a = [];\nvar b = [1, 2, 3];\nvar c = [\n  { a: \"hello\", b: 42 },\n  { a: \"hi\", b: 41 }\n];\nvar d = [\n  [1, 2],\n  [3, 4],\n  [5, 6],\n  [7, [8, 9]]\n];\n\nvar class = function() {\n  this.test1 = {\n    foo: [ 1, 2, 3],\n    bar: [ 4, 5, 9]\n  };\n  this.test2 = [\n    { a: {}, b: {} },\n    { a: {}, b: {} }\n  ];\n  this.test3 = function() {}\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-arrow-funcs.d/args.ctags",
    "content": "--sort=no\n--fields=+SK\n"
  },
  {
    "path": "Units/parser-javascript.r/js-arrow-funcs.d/expected.tags",
    "content": "f0\tinput.js\t/^var f0 = (x) => {$/;\"\tfunction\tsignature:(x)\nf1\tinput.js\t/^var f1 = (x, y) => {$/;\"\tfunction\tsignature:(x, y)\nf2\tinput.js\t/^const f2 = x => {$/;\"\tfunction\tsignature:(x)\nf3\tinput.js\t/^let f3 = () => {$/;\"\tfunction\tsignature:()\nf4\tinput.js\t/^let f4 = (...x) => {$/;\"\tfunction\tsignature:(...x)\nf5\tinput.js\t/^let f5 = (x,...y) => {$/;\"\tfunction\tsignature:(x,...y)\nf6\tinput.js\t/^let f6 = (x,y,...z) => {$/;\"\tfunction\tsignature:(x,y,...z)\na\tinput.js\t/^var a = {}$/;\"\tvariable\nb\tinput.js\t/^var b = {}$/;\"\tvariable\nf7\tinput.js\t/^a.f7 = x => {$/;\"\tfunction\tvariable:a\tsignature:(x)\nf8\tinput.js\t/^a.f8 = async () => {$/;\"\tfunction\tvariable:a\tsignature:()\nf9\tinput.js\t/^b.f9 = (async () => {$/;\"\tfunction\tvariable:b\tsignature:()\nf10\tinput.js\t/^b.f10 = (async x => {$/;\"\tfunction\tvariable:b\tsignature:(x)\na\tinput-0.js\t/^function a() {$/;\"\tfunction\tsignature:()\nb\tinput-0.js\t/^  function b() {$/;\"\tfunction\tfunction:a\tsignature:()\nc\tinput-0.js\t/^function c() {$/;\"\tfunction\tsignature:()\nd\tinput-0.js\t/^  let d = () => {$/;\"\tfunction\tfunction:c\tsignature:()\nd2\tinput-0.js\t/^  function d2() {$/;\"\tfunction\tfunction:c\tsignature:()\ne\tinput-0.js\t/^let e = () => {$/;\"\tfunction\tsignature:()\nf\tinput-0.js\t/^  function f() {$/;\"\tfunction\tfunction:e\tsignature:()\ng\tinput-0.js\t/^let g = () => {$/;\"\tfunction\tsignature:()\nh\tinput-0.js\t/^  let h = () => {$/;\"\tfunction\tfunction:g\tsignature:()\ni\tinput-0.js\t/^  let i = x => {$/;\"\tfunction\tfunction:g\tsignature:(x)\nj\tinput-0.js\t/^  let j = () => {$/;\"\tfunction\tfunction:g\tsignature:()\nk\tinput-0.js\t/^function k() {}$/;\"\tfunction\tsignature:()\n"
  },
  {
    "path": "Units/parser-javascript.r/js-arrow-funcs.d/input-0.js",
    "content": "function a() {\n  function b() {\n    let x = 42;\n    return x;\n  }\n  let y = b();\n  return y\n}\n\nfunction c() {\n  let d = () => {\n    return 42;\n  }\n\n  function d2() {\n    return 1;\n  }\n}\n\nlet e = () => {\n  function f() {\n\n  }\n}\n\nlet g = () => {\n  let h = () => {\n    return 42;\n  }\n  let i = x => {\n    return x * 42;\n  }\n  let j = () => {\n    return 42;\n  }\n}\n\nfunction k() {}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-arrow-funcs.d/input.js",
    "content": "var f0 = (x) => {\n    const ignoreme = 1;\n    console.log('hello');\n}\n\nvar f1 = (x, y) => {\n    var ignoreme = 1;\n    console.log('hello');\n}\n\nconst f2 = x => {\n    let ignoreme = 1;\n    console.log('hello');\n}\n\nlet f3 = () => {\n    const ignoreme = 1;\n    console.log('hello');\n}\n\nlet f4 = (...x) => {\n    const ignoreme = 1;\n    console.log('hello');\n}\n\nlet f5 = (x,...y) => {\n    const ignoreme = 1;\n    console.log('hello');\n}\n\nlet f6 = (x,y,...z) => {\n    const ignoreme = 1;\n    console.log('hello');\n}\n\n// Make this input acceptable as the input for nodejs.\nvar a = {}\nvar b = {}\n\na.f7 = x => {\n    const ignoreme = 1;\n    console.log('hello');\n}\n\na.f8 = async () => {\n    const ignoreme = 1;\n    console.log('hello');\n}\n\nb.f9 = (async () => {\n    const ignoreme = 1;\n    console.log('hello');\n})\n\nb.f10 = (async x => {\n    const ignoreme = 1;\n    console.log('hello');\n})\n"
  },
  {
    "path": "Units/parser-javascript.r/js-arrow-funcs.d/validator",
    "content": "node\n"
  },
  {
    "path": "Units/parser-javascript.r/js-async1.d/expected.tags",
    "content": "add1\tinput.js\t/^async function add1(x) {$/;\"\tf\nadd2\tinput.js\t/^async function add2(x) {$/;\"\tf\nresolveAfter2Seconds\tinput.js\t/^function resolveAfter2Seconds(x) {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-async1.d/input.js",
    "content": "/* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#Simple_example */\n\nfunction resolveAfter2Seconds(x) {\n  return new Promise(resolve => {\n    setTimeout(() => {\n      resolve(x);\n    }, 2000);\n  });\n}\n\nasync function add1(x) {\n  var a = resolveAfter2Seconds(20);\n  var b = resolveAfter2Seconds(30);\n  return x + await a + await b;\n}\n\nadd1(10).then(v => {\n  console.log(v);  // prints 60 after 2 seconds.\n});\n\nasync function add2(x) {\n  var a = await resolveAfter2Seconds(20);\n  var b = await resolveAfter2Seconds(30);\n  return x + a + b;\n}\n\nadd2(10).then(v => {\n  console.log(v);  // prints 60 after 4 seconds.\n});\n"
  },
  {
    "path": "Units/parser-javascript.r/js-async2.d/expected.tags",
    "content": "Class\tinput.js\t/^var Class = {$/;\"\tv\nES6Class\tinput.js\t/^class ES6Class {$/;\"\tc\nasyncAnonymousFunc\tinput.js\t/^var asyncAnonymousFunc = async function() {$/;\"\tf\nes6AsyncMethod\tinput.js\t/^  async es6AsyncMethod() {}$/;\"\tm\tclass:ES6Class\nes6Method\tinput.js\t/^  es6Method() {}$/;\"\tm\tclass:ES6Class\nmethod1\tinput.js\t/^  method1 : function() {$/;\"\tm\tvariable:Class\nmethod2\tinput.js\t/^  method2 : async function() {$/;\"\tm\tvariable:Class\nmethod3\tinput.js\t/^  method3() {$/;\"\tm\tvariable:Class\nmethod4\tinput.js\t/^  async method4() {$/;\"\tm\tvariable:Class\n"
  },
  {
    "path": "Units/parser-javascript.r/js-async2.d/input.js",
    "content": "var Class = {\n  method1 : function() {\n    return 0;\n  },\n  method2 : async function() {\n    return await resolveAfter2Seconds(42);\n  },\n  // ES6 shorthand methods\n  method3() {\n  },\n  async method4() {\n  },\n};\n\nvar asyncAnonymousFunc = async function() {\n}\n\nclass ES6Class {\n  async es6AsyncMethod() {}\n  es6Method() {}\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-broken-strings.d/expected.tags",
    "content": "s1\tinput.js\t/^var s1 = \"I'm invalid because not terminated$/;\"\tv\ns2\tinput.js\t/^var s2 = \"I'm valid, I have a line continuation:\\\\$/;\"\tv\ns3\tinput.js\t/^var s3 = \"I'm invalid because I'm not terminated either \\\\$/;\"\tv\ns4\tinput.js\t/^var s4 = 'this is a separate, valid string'$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-broken-strings.d/input.js",
    "content": "// this file willfully uses CR-LF line endings to check their handling\r\n\r\nvar s1 = \"I'm invalid because not terminated\r\n\r\nvar s2 = \"I'm valid, I have a line continuation:\\\r\n; function bug1(){}\";\r\n\r\nvar s3 = \"I'm invalid because I'm not terminated either \\\r\nvar bug2 = 'this is inside the s3 string'\r\nvar s4 = 'this is a separate, valid string'\r\n"
  },
  {
    "path": "Units/parser-javascript.r/js-broken-template-backslash.d/expected.tags",
    "content": "\\\\\tinput.js\t/^let `\\\\/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-broken-template-backslash.d/input.js",
    "content": "let `\\"
  },
  {
    "path": "Units/parser-javascript.r/js-broken-template-dollar.d/expected.tags",
    "content": "$\tinput.js\t/^let `$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-broken-template-dollar.d/input.js",
    "content": "let `$"
  },
  {
    "path": "Units/parser-javascript.r/js-broken-template.d/expected.tags",
    "content": "\\n\tinput.js\t/^let`$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-broken-template.d/input.js",
    "content": "let`\n"
  },
  {
    "path": "Units/parser-javascript.r/js-class-related-unterminated.d/expected.tags",
    "content": "A\tinput.js\t/^  A: {}$/;\"\tp\tvariable:Cls\nB\tinput.js\t/^Cls.B = function(a, b) {$/;\"\tc\tvariable:Cls\nC\tinput.js\t/^Cls.C = function () {$/;\"\tc\tvariable:Cls\nCls\tinput.js\t/^var Cls = {$/;\"\tv\nSub\tinput.js\t/^Cls.B.Sub = function() {$/;\"\tc\tclass:Cls.B\ndyn1\tinput.js\t/^  Cls.B.Sub.prototype.dyn1 = this.m4$/;\"\tm\tclass:Cls.B.Sub\nm1\tinput.js\t/^Cls.B.prototype.m1 = function(a) {$/;\"\tm\tclass:Cls.B\nm2\tinput.js\t/^Cls.B.prototype.m2 = function(b) {$/;\"\tm\tclass:Cls.B\nm3\tinput.js\t/^Cls.B.prototype.m3 = function(c) {$/;\"\tm\tclass:Cls.B\nm4\tinput.js\t/^Cls.B.prototype.m4 = function(d) {$/;\"\tm\tclass:Cls.B\nm5\tinput.js\t/^Cls.B.prototype.m5 = function(e) {$/;\"\tm\tclass:Cls.B\nm6\tinput.js\t/^Cls.B.prototype.m6 = function(f) {$/;\"\tm\tclass:Cls.B\nmain\tinput.js\t/^function main() {$/;\"\tf\nn1\tinput.js\t/^  n1: function() {$/;\"\tm\tclass:Cls.C\nn2\tinput.js\t/^  n2: function() {$/;\"\tm\tclass:Cls.C\n"
  },
  {
    "path": "Units/parser-javascript.r/js-class-related-unterminated.d/input.js",
    "content": "\nvar Cls = {\n  A: {}\n}\n\nCls.B = function(a, b) {\n  this.a = a;\n  this.b = b;\n}\n\nCls.B.Sub = function() {\n  this.a = 0\n}\n\nCls.B.prototype.m1 = function(a) {\n  this.a = a;\n  if (a > 2) {\n    this.a *= 2\n  }\n}\nCls.B.prototype.m2 = function(b) {\n  var a = b\n}\nCls.B.prototype.m3 = function(c) {\n  this.c = c\n}\nCls.B.prototype.m4 = function(d) {\n  this.d = d\n}\nCls.B.prototype.m5 = function(e) {\n  /* this should rather be written `Cls.B.Sub.prototype.dyn1 = this.m6`, but\n   * then parser then thinks it's a child of this very scope.  it isn't really\n   * possible to fix this as the only reason it's actually not a child of the\n   * current scope is because it exists in the root scope but not in this one */\n  //var Sub = Cls.B.Sub;\n  //Sub.prototype.dyn1 = this.m4\n  Cls.B.Sub.prototype.dyn1 = this.m4\n}\nCls.B.prototype.m6 = function(f) {\n}\n\nCls.C = function () {\n  this.a = 0;\n}\n\nCls.C.prototype = {\n  n1: function() {\n    Cls.C.prototype = Cls.C.prototype\n  },\n  n2: function() {\n  }\n}\n\nfunction main() {\n  var c = new Cls.B(1, 2);\n  var d = new Cls.B.Sub();\n  print(d.dyn1);\n  c.m5();\n  print(d.dyn1);\n}\n\nmain();\n"
  },
  {
    "path": "Units/parser-javascript.r/js-comma-at-end-of-object.d/expected.tags",
    "content": "one\tinput.js\t/^\tvar one = {$/;\"\tv\tfunction:test\ntest\tinput.js\t/^function test () {$/;\"\tf\ntwo\tinput.js\t/^\tvar two = {$/;\"\tv\tfunction:test\nval\tinput.js\t/^\t\tval: 1$/;\"\tp\tvariable:test.one\nval\tinput.js\t/^\t\tval: 2,$/;\"\tp\tvariable:test.two\n"
  },
  {
    "path": "Units/parser-javascript.r/js-comma-at-end-of-object.d/input.js",
    "content": "function test () {\n\tvar one = {\n\t\tval: 1\n\t};\n\n\tvar two = {\n\t\tval: 2,\n\t\t/* the trailing comma used to break recognizing as a class, and as local\n\t\t * variables are not emitted `val` was orphaned */\n\t};\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-commas-and-missing-semicolons.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-commas-and-missing-semicolons.d/expected.tags",
    "content": "A\tinput.js\t/^var A = {}, b = 2;$/;\"\tv\nb\tinput.js\t/^var A = {}, b = 2;$/;\"\tv\nc\tinput.js\t/^var c = 3, d = 4;$/;\"\tv\nd\tinput.js\t/^var c = 3, d = 4;$/;\"\tv\nmem1\tinput.js\t/^A.mem1 = function() {return 42;}, A.mem2 = function() {return 43;}$/;\"\tf\tvariable:A\nmem2\tinput.js\t/^A.mem1 = function() {return 42;}, A.mem2 = function() {return 43;}$/;\"\tf\tvariable:A\nx\tinput.js\t/^var x = {}, y = {}, z = {}$/;\"\tv\ny\tinput.js\t/^var x = {}, y = {}, z = {}$/;\"\tv\nz\tinput.js\t/^var x = {}, y = {}, z = {}$/;\"\tv\nfunc1\tinput.js\t/^function func1(){var x = {}} function func2(){}$/;\"\tf\nfunc2\tinput.js\t/^function func1(){var x = {}} function func2(){}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-commas-and-missing-semicolons.d/input.js",
    "content": "\nvar A = {}, b = 2;\nvar c = 3, d = 4;\nA.mem1 = function() {return 42;}, A.mem2 = function() {return 43;}\nvar x = {}, y = {}, z = {}\n\n/* verify handling of unterminated assignation to '{}' */\nfunction func1(){var x = {}} function func2(){}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-complex-return.d/expected.tags",
    "content": "Class1\tinput.js\t/^var Class1 = function() {$/;\"\tc\nClass2\tinput.js\t/^var Class2 = function() {$/;\"\tc\nClass3\tinput.js\t/^var Class3 = function() {$/;\"\tc\nClass4\tinput.js\t/^var Class4 = function() {$/;\"\tc\nanonymousFunctiona815156f0800\tinput.js\t/^    c2m3(function() {$/;\"\tf\tmethod:Class2.c2m1\nanonymousFunctiona815156f0d00\tinput.js\t/^    return function(n) {$/;\"\tf\tmethod:Class3.c3m1\nc2m1\tinput.js\t/^  this.c2m1 = function() {$/;\"\tm\tclass:Class2\nc2m2\tinput.js\t/^  this.c2m2 = function(f) {$/;\"\tm\tclass:Class2\nc2m3\tinput.js\t/^  this.c2m3 = function(f) {$/;\"\tm\tclass:Class2\nc3m1\tinput.js\t/^  this.c3m1 = function() {$/;\"\tm\tclass:Class3\nc3m2\tinput.js\t/^  this.c3m2 = function() {$/;\"\tm\tclass:Class3\nfunc1\tinput.js\t/^function func1() {$/;\"\tf\nfunc2\tinput.js\t/^function func2() {$/;\"\tf\nmethod1\tinput.js\t/^  this.method1 = function() {$/;\"\tm\tclass:Class1\nmethod1\tinput.js\t/^  this.method1 = function() {$/;\"\tm\tclass:Class4\nmethod2\tinput.js\t/^  this.method2 = function() {$/;\"\tm\tclass:Class1\nmethod2\tinput.js\t/^  this.method2 = function() {$/;\"\tm\tclass:Class4\nmethod3\tinput.js\t/^  this.method3 = function() {$/;\"\tm\tclass:Class1\nmethod4\tinput.js\t/^  this.method4 = function() {$/;\"\tm\tclass:Class1\n"
  },
  {
    "path": "Units/parser-javascript.r/js-complex-return.d/input.js",
    "content": "\nfunction func1() {\n  return { a: 1, b:2 };\n}\n\nfunction func2() {\n  return 42;\n}\n\nvar Class1 = function() {\n  this.method1 = function() {\n    return 42;\n  };\n  this.method2 = function() {\n    return { a:1, b:2 };\n  };\n  this.method3 = function() {\n    return [1, 2, 3];\n  };\n  this.method4 = function() {\n    return \"hello\";\n  };\n};\n\nvar Class2 = function() {\n  this.c2m1 = function() {\n    c2m3(function() {\n      return { 'test': {} };\n    });\n  };\n  this.c2m2 = function(f) {\n    return { 'ret': f() };\n  };\n  this.c2m3 = function(f) {\n    return f();\n  };\n};\n\nvar Class3 = function() {\n  this.c3m1 = function() {\n    return function(n) {\n      if (n == 42) {\n        return 0;\n      } else {\n        return (n + 1) % 42;\n      }\n    };\n  };\n  this.c3m2 = function() {\n    return 0;\n  };\n}\n\nvar Class4 = function() {\n  this.method1 = function() {\n    return [{a:1, b:2}, {a:3, b:4}, {a:5, b:6}];\n  };\n  this.method2 = function() {\n    return 0;\n  };\n};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-computed-propname.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-computed-propname.d/expected.tags",
    "content": "prop\tinput.js\t/^var prop = 'foo';$/;\"\tv\nx\tinput.js\t/^var x = 'c';$/;\"\tv\ny\tinput.js\t/^var y = ['d', 'e'];$/;\"\tv\n['a' + y [0]]\tinput.js\t/^    ['a' + y [0]]: {},$/;\"\tp\tvariable:o\na\tinput.js\t/^    ['a']: {},\t\t\t\\/\\/ Tagging$/;\"\tp\tvariable:o\n['a' + 'b']\tinput.js\t/^    ['a' + 'b']: {},\t\t\\/\\/ Tagging whole    \\\\$/;\"\tp\tvariable:o\n[x]\tinput.js\t/^    [x]: {},\t\t\t\\/\\/ expressions with \\\\$/;\"\tp\tvariable:o\n['a' + x]\tinput.js\t/^    ['a' + x]: {},        \t\\/\\/ `[' and `]'$/;\"\tp\tvariable:o\no\tinput.js\t/^var o = {$/;\"\tv\nModel\tinput.js\t/^class Model {$/;\"\tc\nUser\tinput.js\t/^class User extends Model {$/;\"\tc\ntableName\tinput.js\t/^  static get tableName() {$/;\"\tG\tclass:User\njson-schema\tinput.js\t/^  static get [\"json-schema\"]() {$/;\"\tG\tclass:User\nsubnum\tinput.js\t/^\t\tsubnum: function (){}$/;\"\tm\tproperty:p.[(1+2)*3]\n[(1+2)*3]\tinput.js\t/^\t[(1+2)*3]: {$/;\"\tp\tvariable:p\np\tinput.js\t/^var p = {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-computed-propname.d/input.js",
    "content": "//\n// \"node --experimental-modules\" accepts this input.\n//\n\n// Computed property names (ES2015)\nvar prop = 'foo';\nvar x = 'c';\nvar y = ['d', 'e'];\nvar o = {\n    ['a' + y [0]]: {},\n    ['a']: {},\t\t\t// Tagging\n    ['a' + 'b']: {},\t\t// Tagging whole    \\\n    [x]: {},\t\t\t// expressions with \\\n    ['a' + x]: {},        \t// `[' and `]'\n    \n};\n\nclass Model {\n}\n\nclass User extends Model {\n  static get tableName() {\n    return \"users\"\n  }\n\n  static get [\"json-schema\"]() {\n    return {\n      type: \"object\",\n      optional: [\n        \"passwordHash\",\n        \"passwordResetRequestedAt\",\n        \"passwordResetToken\",\n        \"verificationToken\",\n        \"verifiedAt\",\n      ]\n    }\n  }\n}\n\nvar p = {\n\t[(1+2)*3]: {\n\t\tsubnum: function (){}\n\t},\n};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-const.d/expected.tags",
    "content": "A\tinput.js\t/^const A = 1;$/;\"\tC\nB\tinput.js\t/^const B = 1;$/;\"\tC\nGroup\tinput.js\t/^const Group = {$/;\"\tv\nX\tinput.js\t/^  X:1,$/;\"\tp\tvariable:Group\nY\tinput.js\t/^  Y:2,$/;\"\tp\tvariable:Group\nZ\tinput.js\t/^  Z:3$/;\"\tp\tvariable:Group\nfunc\tinput.js\t/^const func = function () {}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-const.d/input.js",
    "content": "\nconst A = 1;\nconst B = 1;\nconst Group = {\n  X:1,\n  Y:2,\n  Z:3\n};\n\nconst func = function () {}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-crlf.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-crlf.d/expected.tags",
    "content": "v1\tinput.js\t/^var v1, v2$/;\"\tv\nv2\tinput.js\t/^var v1, v2$/;\"\tv\nv3\tinput.js\t/^var v3 = 1$/;\"\tv\nv4\tinput.js\t/^,   v4 = 2$/;\"\tv\nv5\tinput.js\t/^,   v5 = 3$/;\"\tv\nf1\tinput.js\t/^function f1() {$/;\"\tf\nf1_c1_m1\tinput.js\t/^    f1_c1_m1:$/;\"\tm\tvariable:f1.f1_c1\nf1_c1_m2\tinput.js\t/^    f1_c1_m2$/;\"\tm\tvariable:f1.f1_c1\nf1_c1\tinput.js\t/^  var f1_c1 = {$/;\"\tv\tfunction:f1\nv6\tinput.js\t/^var v6 = \"hello\\\\$/;\"\tv\nv7\tinput.js\t/^var v7 = \"hello\\\\$/;\"\tv\nv8\tinput.js\t/^var v8;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-crlf.d/input.js",
    "content": "\r\nvar v1, v2\r\nvar v3 = 1\r\n,   v4 = 2\r\n,   v5 = 3\r\r\nfunction f1() {\r\n  var f1_c1 = {\r\n    f1_c1_m1:\r\n    function() {\r\n    }\r\n    ,\r\n    f1_c1_m2\r\n    :\r\n    function\r\n    (\r\n    )\r\n    {\r\n    }\r\n  }\r\n}\r\n\r\nvar v6 = \"hello\\\r\nvar bug1 = world;\"\r\nvar v7 = \"hello\\\rvar bug2 = world\"\r\nvar v8;\r\n"
  },
  {
    "path": "Units/parser-javascript.r/js-default-export.d/expected.tags",
    "content": "cube\tinput.js\t/^export default function cube(x) {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-default-export.d/input.js",
    "content": "/* https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export#Using_the_default_export */\n\nexport default function cube(x) {\n  return x * x * x;\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding-todo.b/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding-todo.b/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding-todo.b/input-1.js",
    "content": "// See #3435.\n// f should be tagged with function kind.\nlet [f] = [function() {}];\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding-todo.b/input.js",
    "content": "// See #3435.\n//  If an object literal is specified as a default value in object restructuring,\n// the parser may fail to extract the variable (or constant):\nvar{ c = {a: 1} } = { c: undefined };\nvar{ d = {a: 1} } = {d: 3};\nvar a = 1\nvar [x = {a: 2}, y] = [, 4];\nvar [x = [a, 2], z] = [, 4];\nvar { 'alpha': q = {'x': 9} } = {'alpha': 3};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding.d/expected.tags",
    "content": "x\tinput.js\t/^const [x] = [1];$/;\"\tC\ny\tinput.js\t/^const [y, z] = [1, 2, 3, 4, 5];$/;\"\tC\nz\tinput.js\t/^const [y, z] = [1, 2, 3, 4, 5];$/;\"\tC\na\tinput.js\t/^let [a=5, b=7] = [1];$/;\"\tv\nb\tinput.js\t/^let [a=5, b=7] = [1];$/;\"\tv\nc\tinput.js\t/^let [c, , d] = [1, 2, 3];$/;\"\tv\nd\tinput.js\t/^let [c, , d] = [1, 2, 3];$/;\"\tv\ne\tinput.js\t/^let [e, f = 0, , g] = [1, 2, 3, 4];$/;\"\tv\nf\tinput.js\t/^let [e, f = 0, , g] = [1, 2, 3, 4];$/;\"\tv\ng\tinput.js\t/^let [e, f = 0, , g] = [1, 2, 3, 4];$/;\"\tv\nh\tinput.js\t/^const [h, i, ...[j, k]] = [1, 2, 3, 4];$/;\"\tC\ni\tinput.js\t/^const [h, i, ...[j, k]] = [1, 2, 3, 4];$/;\"\tC\nj\tinput.js\t/^const [h, i, ...[j, k]] = [1, 2, 3, 4];$/;\"\tC\nk\tinput.js\t/^const [h, i, ...[j, k]] = [1, 2, 3, 4];$/;\"\tC\nl\tinput.js\t/^const [l, m, ...[n, o, ...[p, q]]] = [1, 2, 3, 4, 5, 6];$/;\"\tC\nm\tinput.js\t/^const [l, m, ...[n, o, ...[p, q]]] = [1, 2, 3, 4, 5, 6];$/;\"\tC\nn\tinput.js\t/^const [l, m, ...[n, o, ...[p, q]]] = [1, 2, 3, 4, 5, 6];$/;\"\tC\no\tinput.js\t/^const [l, m, ...[n, o, ...[p, q]]] = [1, 2, 3, 4, 5, 6];$/;\"\tC\np\tinput.js\t/^const [l, m, ...[n, o, ...[p, q]]] = [1, 2, 3, 4, 5, 6];$/;\"\tC\nq\tinput.js\t/^const [l, m, ...[n, o, ...[p, q]]] = [1, 2, 3, 4, 5, 6];$/;\"\tC\nA\tinput.js\t/^const [A, B, ...{ C, D }] = []$/;\"\tC\nB\tinput.js\t/^const [A, B, ...{ C, D }] = []$/;\"\tC\nC\tinput.js\t/^const [A, B, ...{ C, D }] = []$/;\"\tC\nD\tinput.js\t/^const [A, B, ...{ C, D }] = []$/;\"\tC\nE\tinput.js\t/^    E: 42,$/;\"\tp\tvariable:user\nF\tinput.js\t/^    F: true$/;\"\tp\tvariable:user\nuser\tinput.js\t/^const user = {$/;\"\tv\nE\tinput.js\t/^const {E, F} = user;$/;\"\tC\nF\tinput.js\t/^const {E, F} = user;$/;\"\tC\nG\tinput.js\t/^const {E: G, F: H} = user;$/;\"\tC\nH\tinput.js\t/^const {E: G, F: H} = user;$/;\"\tC\nI\tinput.js\t/^const {I = 10, J = 5} = {I: 3};$/;\"\tC\nJ\tinput.js\t/^const {I = 10, J = 5} = {I: 3};$/;\"\tC\nI\tinput.js\t/^const {I = 10, J = 5} = {I: 3};$/;\"\tp\tvariable:anonymousObject785a93f40105\nanonymousObject785a93f40105\tinput.js\t/^const {I = 10, J = 5} = {I: 3};$/;\"\tv\nK\tinput.js\t/^let {a: K = 10, b: L = 5} = {a: 3};$/;\"\tv\nL\tinput.js\t/^let {a: K = 10, b: L = 5} = {a: 3};$/;\"\tv\na\tinput.js\t/^let {a: K = 10, b: L = 5} = {a: 3};$/;\"\tp\tvariable:anonymousObject785a93f40205\nanonymousObject785a93f40205\tinput.js\t/^let {a: K = 10, b: L = 5} = {a: 3};$/;\"\tv\nM\tinput.js\t/^let {M, N, ...O} = {M: 10, N: 20, c: 30, d: 40}$/;\"\tv\nN\tinput.js\t/^let {M, N, ...O} = {M: 10, N: 20, c: 30, d: 40}$/;\"\tv\nO\tinput.js\t/^let {M, N, ...O} = {M: 10, N: 20, c: 30, d: 40}$/;\"\tv\nM\tinput.js\t/^let {M, N, ...O} = {M: 10, N: 20, c: 30, d: 40}$/;\"\tp\tvariable:anonymousObject785a93f40305\nN\tinput.js\t/^let {M, N, ...O} = {M: 10, N: 20, c: 30, d: 40}$/;\"\tp\tvariable:anonymousObject785a93f40305\nc\tinput.js\t/^let {M, N, ...O} = {M: 10, N: 20, c: 30, d: 40}$/;\"\tp\tvariable:anonymousObject785a93f40305\nd\tinput.js\t/^let {M, N, ...O} = {M: 10, N: 20, c: 30, d: 40}$/;\"\tp\tvariable:anonymousObject785a93f40305\nanonymousObject785a93f40305\tinput.js\t/^let {M, N, ...O} = {M: 10, N: 20, c: 30, d: 40}$/;\"\tv\ntitle\tinput.js\t/^  title: 'Scratchpad',$/;\"\tp\tvariable:metadata\nanonymousObject785a93f40405\tinput.js\t/^    {$/;\"\tv\tvariable:metadata\nlocale\tinput.js\t/^      locale: 'de',$/;\"\tp\tvariable:metadata.anonymousObject785a93f40405\nlocalization_tags\tinput.js\t/^      localization_tags: [],$/;\"\tp\tvariable:metadata.anonymousObject785a93f40405\nlast_edit\tinput.js\t/^      last_edit: '2014-04-14T08:43:37',$/;\"\tp\tvariable:metadata.anonymousObject785a93f40405\nurl\tinput.js\t/^      url: '\\/de\\/docs\\/Tools\\/Scratchpad',$/;\"\tp\tvariable:metadata.anonymousObject785a93f40405\ntitle\tinput.js\t/^      title: 'JavaScript-Umgebung'$/;\"\tp\tvariable:metadata.anonymousObject785a93f40405\ntranslations\tinput.js\t/^  translations: [$/;\"\tp\tvariable:metadata\nurl\tinput.js\t/^  url: '\\/en-US\\/docs\\/Tools\\/Scratchpad'$/;\"\tp\tvariable:metadata\nmetadata\tinput.js\t/^const metadata = {$/;\"\tv\nenglishTitle\tinput.js\t/^  title: englishTitle, \\/\\/ rename$/;\"\tv\nlocaleTitle\tinput.js\t/^       title: localeTitle, \\/\\/ rename$/;\"\tv\nuserDisplayName\tinput-0.js\t/^function userDisplayName({displayName: dname}) {$/;\"\tf\tsignature:({displayName: dname})\nwhois\tinput-0.js\t/^function whois({displayName, fullName: {firstName: name}}) {$/;\"\tf\tsignature:({displayName, fullName: {firstName: name}})\ndrawChart\tinput-0.js\t/^function drawChart({size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}) {$/;\"\tf\tsignature:({size = 'big', coords = {x: 0, y: 0}, radius = 25} = {})\nf\tinput-1.js\t/^function f({ u, x }) {$/;\"\tf\tsignature:({ u, x })\nanonymousObjectf91cef720105\tinput-1.js\t/^f({u: 1, x: 2})$/;\"\tv\nu\tinput-1.js\t/^f({u: 1, x: 2})$/;\"\tp\tvariable:anonymousObjectf91cef720105\nx\tinput-1.js\t/^f({u: 1, x: 2})$/;\"\tp\tvariable:anonymousObjectf91cef720105\nf\tinput-2.js\t/^function f(x, y, z) {$/;\"\tf\tsignature:(x, y, z)\nanonymousObjectf91d7bd30105\tinput-2.js\t/^f({x, y, z})$/;\"\tv\nx\tinput-2.js\t/^f({x, y, z})$/;\"\tp\tvariable:anonymousObjectf91d7bd30105\ny\tinput-2.js\t/^f({x, y, z})$/;\"\tp\tvariable:anonymousObjectf91d7bd30105\nz\tinput-2.js\t/^f({x, y, z})$/;\"\tp\tvariable:anonymousObjectf91d7bd30105\nkey0\tinput-3.js\t/^let key0 = 'z';$/;\"\tv\nfoo\tinput-3.js\t/^let {[key0]: foo} = {z: 'alpha'};$/;\"\tv\nz\tinput-3.js\t/^let {[key0]: foo} = {z: 'alpha'};$/;\"\tp\tvariable:anonymousObjectf91e08340105\nanonymousObjectf91e08340105\tinput-3.js\t/^let {[key0]: foo} = {z: 'alpha'};$/;\"\tv\nkey1\tinput-3.js\t/^let key1 = 'x';$/;\"\tv\nbar\tinput-3.js\t/^let {[key0]: bar = 'X', [key1]: baz} = {x: 'beta'};$/;\"\tv\nbaz\tinput-3.js\t/^let {[key0]: bar = 'X', [key1]: baz} = {x: 'beta'};$/;\"\tv\nx\tinput-3.js\t/^let {[key0]: bar = 'X', [key1]: baz} = {x: 'beta'};$/;\"\tp\tvariable:anonymousObjectf91e08340205\nanonymousObjectf91e08340205\tinput-3.js\t/^let {[key0]: bar = 'X', [key1]: baz} = {x: 'beta'};$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding.d/input-0.js",
    "content": "// Derrived from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment\nfunction userDisplayName({displayName: dname}) {\n  return dname;\n}\n\nfunction whois({displayName, fullName: {firstName: name}}) {\n  return `${displayName} is ${name}`;\n}\n\nfunction drawChart({size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}) {\n  console.log(size, coords, radius);\n  // do some chart drawing\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding.d/input-1.js",
    "content": "function f({ u, x }) {\n    return (u + x)\n}\n\nf({u: 1, x: 2})\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding.d/input-2.js",
    "content": "function f(x, y, z) {\n    return x + y + z\n}\n\nx = 1\ny = 1\nz = 1\nf({x, y, z})\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding.d/input-3.js",
    "content": "// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment\n//   - Computed object property names and destructuring\nlet key0 = 'z';\nlet {[key0]: foo} = {z: 'alpha'};\n\nlet key1 = 'x';\nlet {[key0]: bar = 'X', [key1]: baz} = {x: 'beta'};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding.d/input.js",
    "content": "// Derrived from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment\nconst [x] = [1];\nconst [y, z] = [1, 2, 3, 4, 5];\nlet [a=5, b=7] = [1];\n\nlet [c, , d] = [1, 2, 3];\nlet [e, f = 0, , g] = [1, 2, 3, 4];\n\nlet [,,] = [1, 2, 3];\nlet [,]  = [1, 2, 3];\nlet []   = [1, 2, 3];\n\nconst [h, i, ...[j, k]] = [1, 2, 3, 4];\nconst [l, m, ...[n, o, ...[p, q]]] = [1, 2, 3, 4, 5, 6];\n\nconst [A, B, ...{ C, D }] = []\n\nconst user = {\n    E: 42,\n    F: true\n};\n\nconst {E, F} = user;\n\nconst {E: G, F: H} = user;\n\n\nconst {I = 10, J = 5} = {I: 3};\n\nlet {a: K = 10, b: L = 5} = {a: 3};\n\nlet {M, N, ...O} = {M: 10, N: 20, c: 30, d: 40}\n\n\nconst metadata = {\n  title: 'Scratchpad',\n  translations: [\n    {\n      locale: 'de',\n      localization_tags: [],\n      last_edit: '2014-04-14T08:43:37',\n      url: '/de/docs/Tools/Scratchpad',\n      title: 'JavaScript-Umgebung'\n    }\n  ],\n  url: '/en-US/docs/Tools/Scratchpad'\n};\n\nlet {\n  title: englishTitle, // rename\n  translations: [\n    {\n       title: localeTitle, // rename\n    },\n  ],\n} = metadata;\n"
  },
  {
    "path": "Units/parser-javascript.r/js-destructural-binding.d/validator",
    "content": "node\n"
  },
  {
    "path": "Units/parser-javascript.r/js-do-while.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-do-while.d/expected.tags",
    "content": "v1\tinput.js\t/^var v1 = 1;$/;\"\tv\nv2\tinput.js\t/^do {} while (0) var v2 = 2;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-do-while.d/input.js",
    "content": "var v1 = 1;\n// oddly enough it's perfectly valid syntax\ndo {} while (0) var v2 = 2;\n"
  },
  {
    "path": "Units/parser-javascript.r/js-empty-class-name.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-empty-class-name.d/expected.tags",
    "content": "prop\tinput.js\t/^var {prop} = { prop: \"value\" };$/;\"\tv\nprop\tinput.js\t/^var {prop} = { prop: \"value\" };$/;\"\tp\tvariable:anonymousObject4ca5b60a0105\nanonymousObject4ca5b60a0105\tinput.js\t/^var {prop} = { prop: \"value\" };$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-empty-class-name.d/input.js",
    "content": "var {prop} = { prop: \"value\" };\n"
  },
  {
    "path": "Units/parser-javascript.r/js-es6-class-private.d/args.ctags",
    "content": "--fields=+a\n--fields-javascript=+{properties}\n--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-es6-class-private.d/expected.tags",
    "content": "Class1\tinput.js\t/^class Class1$/;\"\tc\n#value1\tinput.js\t/^\t#value1$/;\"\tM\tclass:Class1\taccess:private\n#value2\tinput.js\t/^\tstatic #value2$/;\"\tM\tclass:Class1\taccess:private\tproperties:static\nmethod1\tinput.js\t/^\tmethod1(arg1,arg2)$/;\"\tm\tclass:Class1\n#method2\tinput.js\t/^\t#method2(arg1,arg2)$/;\"\tm\tclass:Class1\taccess:private\nClass2\tinput.js\t/^class Class2$/;\"\tc\n#method3\tinput.js\t/^\tstatic #method3(arg = 10)$/;\"\tm\tclass:Class2\taccess:private\tproperties:static\nClass3\tinput.js\t/^var Class3 = class {$/;\"\tc\n#method4\tinput.js\t/^\t#method4(){}$/;\"\tm\tclass:Class3\taccess:private\nmethod5\tinput.js\t/^\tstatic method5(){}$/;\"\tm\tclass:Class3\tproperties:static\nClass4\tinput.js\t/^var Class4 = class Class4_2 {$/;\"\tc\nClass4_2\tinput.js\t/^var Class4 = class Class4_2 {$/;\"\tc\nmethod6\tinput.js\t/^\tmethod6(){}$/;\"\tm\tclass:Class4\nmethod7\tinput.js\t/^\tstatic method7(){}$/;\"\tm\tclass:Class4\tproperties:static\nAnonymousClass1fa6c9a30101\tinput.js\t/^class {$/;\"\tc\nmethod8\tinput.js\t/^\tmethod8(n) { return n * n; }$/;\"\tm\tclass:AnonymousClass1fa6c9a30101\nfunc1\tinput.js\t/^function func1() {$/;\"\tf\nInnerClass1\tinput.js\t/^\tclass InnerClass1 {$/;\"\tc\tfunction:func1\n#method9\tinput.js\t/^\t\t#method9() {$/;\"\tm\tclass:func1.InnerClass1\taccess:private\nInnerClass2\tinput.js\t/^\tclass InnerClass2 {$/;\"\tc\tfunction:func1\nmethod10\tinput.js\t/^\t\tmethod10() {$/;\"\tm\tclass:func1.InnerClass2\nClass5\tinput.js\t/^class Class5 {$/;\"\tc\nmethod11\tinput.js\t/^\tmethod11() {};$/;\"\tm\tclass:Class5\n#method12\tinput.js\t/^\t#method12() {};$/;\"\tm\tclass:Class5\taccess:private\nfunc2\tinput.js\t/^function func2() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-es6-class-private.d/input.js",
    "content": "\nclass Class1\n{\n\t#value1\n\tstatic #value2\n\n\tmethod1(arg1,arg2)\n\t{\n\t}\n\n\t#method2(arg1,arg2)\n\t{\n\t}\n}\n\nclass Class2\n{\n\tstatic #method3(arg = 10)\n\t{\n\t}\n}\n\nvar Class3 = class {\n\t#method4(){}\n\tstatic method5(){}\n}\n\nvar Class4 = class Class4_2 {\n\tmethod6(){}\n\tstatic method7(){}\n}\n\nclass {\n\tmethod8(n) { return n * n; }\n}\n\nfunction func1() {\n\tclass InnerClass1 {\n\t\t#method9() {\n\t\t}\n\t}\n\tclass InnerClass2 {\n\t\tmethod10() {\n\t\t}\n\t}\n}\n\nclass Class5 {\n\tmethod11() {};\n\t#method12() {};\n}\n\nfunction func2() {\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-es6-class.d/expected.tags",
    "content": "AnonymousClass152c525b0101\tinput.js\t/^class {$/;\"\tc\nClass1\tinput.js\t/^class Class1$/;\"\tc\nClass2\tinput.js\t/^class Class2$/;\"\tc\nClass3\tinput.js\t/^var Class3 = class {$/;\"\tc\nClass4\tinput.js\t/^var Class4 = class Class4_2 {$/;\"\tc\nClass4_2\tinput.js\t/^var Class4 = class Class4_2 {$/;\"\tc\nClass5\tinput.js\t/^class Class5 {$/;\"\tc\nInnerClass1\tinput.js\t/^\tclass InnerClass1 {$/;\"\tc\tfunction:func1\nInnerClass2\tinput.js\t/^\tclass InnerClass2 {$/;\"\tc\tfunction:func1\nfunc1\tinput.js\t/^function func1() {$/;\"\tf\nfunc2\tinput.js\t/^function func2() {$/;\"\tf\nmethod1\tinput.js\t/^\tmethod1(arg1,arg2)$/;\"\tm\tclass:Class1\nmethod10\tinput.js\t/^\t\tmethod10() {$/;\"\tm\tclass:func1.InnerClass2\nmethod11\tinput.js\t/^\tmethod11() {};$/;\"\tm\tclass:Class5\nmethod12\tinput.js\t/^\tmethod12() {};$/;\"\tm\tclass:Class5\nmethod2\tinput.js\t/^\tmethod2(arg1,arg2)$/;\"\tm\tclass:Class1\nmethod3\tinput.js\t/^\tstatic method3(arg = 10)$/;\"\tm\tclass:Class2\nmethod4\tinput.js\t/^\tmethod4(){}$/;\"\tm\tclass:Class3\nmethod5\tinput.js\t/^\tstatic method5(){}$/;\"\tm\tclass:Class3\nmethod6\tinput.js\t/^\tmethod6(){}$/;\"\tm\tclass:Class4\nmethod7\tinput.js\t/^\tstatic method7(){}$/;\"\tm\tclass:Class4\nmethod8\tinput.js\t/^\tmethod8(n) { return n * n; }$/;\"\tm\tclass:AnonymousClass152c525b0101\nmethod9\tinput.js\t/^\t\tmethod9() {$/;\"\tm\tclass:func1.InnerClass1\n"
  },
  {
    "path": "Units/parser-javascript.r/js-es6-class.d/input.js",
    "content": "\nclass Class1\n{\n\tmethod1(arg1,arg2)\n\t{\n\t}\n\n\tmethod2(arg1,arg2)\n\t{\n\t}\n}\n\nclass Class2\n{\n\tstatic method3(arg = 10)\n\t{\n\t}\n}\n\nvar Class3 = class {\n\tmethod4(){}\n\tstatic method5(){}\n}\n\nvar Class4 = class Class4_2 {\n\tmethod6(){}\n\tstatic method7(){}\n}\n\nclass {\n\tmethod8(n) { return n * n; }\n}\n\nfunction func1() {\n\tclass InnerClass1 {\n\t\tmethod9() {\n\t\t}\n\t}\n\tclass InnerClass2 {\n\t\tmethod10() {\n\t\t}\n\t}\n}\n\nclass Class5 {\n\tmethod11() {};\n\tmethod12() {};\n}\n\nfunction func2() {\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-es6-mixin.d/args.ctags",
    "content": "--fields=+i\n"
  },
  {
    "path": "Units/parser-javascript.r/js-es6-mixin.d/expected.tags",
    "content": "AnonymousClasse9b77f6a0101\tinput.js\t/^  return class extends superclass {$/;\"\tc\tclass:Mixin\tinherits:superclass\nBar\tinput.js\t/^class Bar extends Foo {$/;\"\tc\tinherits:Foo\nBaz\tinput.js\t/^class Baz extends Mixin(Bar) {$/;\"\tc\tinherits:Mixin(Bar)\nFoo\tinput.js\t/^class Foo {$/;\"\tc\nMixin\tinput.js\t/^function Mixin(superclass) {$/;\"\tc\nbar\tinput.js\t/^  bar() { return \"bar\"; }$/;\"\tm\tclass:Bar\nfoo\tinput.js\t/^  foo() { return \"foo\"; }$/;\"\tm\tclass:Foo\nhello\tinput.js\t/^    hello() {$/;\"\tm\tclass:Mixin.AnonymousClasse9b77f6a0101\nhi\tinput.js\t/^  hi() {$/;\"\tm\tclass:Baz\ni\tinput.js\t/^var i = new Baz();$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-es6-mixin.d/input.js",
    "content": "\nclass Foo {\n  foo() { return \"foo\"; }\n}\n\nclass Bar extends Foo {\n  bar() { return \"bar\"; }\n}\n\nfunction Mixin(superclass) {\n  return class extends superclass {\n    hello() {\n      return \"hello from mixin\";\n    }\n  }\n}\n\nclass Baz extends Mixin(Bar) {\n  hi() {\n    return \"hi\";\n  }\n}\n\nvar i = new Baz();\ni.foo();\ni.bar();\ni.hello();\ni.hi();\n"
  },
  {
    "path": "Units/parser-javascript.r/js-export.d/expected.tags",
    "content": "cube\tinput.js\t/^export function cube(x) {$/;\"\tf\nfoo\tinput.js\t/^const foo = Math.PI + Math.SQRT2;$/;\"\tC\npie\tinput.js\t/^export const pie = Math.PI;$/;\"\tC\n"
  },
  {
    "path": "Units/parser-javascript.r/js-export.d/input.js",
    "content": "/* https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export#Using_named_exports */\n\nexport function cube(x) {\n  return x * x * x;\n}\nconst foo = Math.PI + Math.SQRT2;\nexport { cube, foo };\n\n/* augmented from the reference */\nexport const pie = Math.PI;\n"
  },
  {
    "path": "Units/parser-javascript.r/js-extract-empty-property-in-json.d/args.ctags",
    "content": "--sort=no\n--extras=+{nulltag}\n--fields=+{extras}\n--output-format=json\n"
  },
  {
    "path": "Units/parser-javascript.r/js-extract-empty-property-in-json.d/expected.tags-json",
    "content": "{\"_type\": \"tag\", \"name\": \"\", \"path\": \"input.js\", \"pattern\": \"/^var variable = { \\\"\\\": \\\"value\\\" };$/\", \"kind\": \"property\", \"scope\": \"variable\", \"scopeKind\": \"variable\", \"extras\": \"nulltag\"}\n{\"_type\": \"tag\", \"name\": \"variable\", \"path\": \"input.js\", \"pattern\": \"/^var variable = { \\\"\\\": \\\"value\\\" };$/\", \"kind\": \"variable\"}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-extract-empty-property-in-json.d/features",
    "content": "json\n"
  },
  {
    "path": "Units/parser-javascript.r/js-extract-empty-property-in-json.d/input.js",
    "content": "var variable = { \"\": \"value\" };\n"
  },
  {
    "path": "Units/parser-javascript.r/js-extract-empty-property.d/args.ctags",
    "content": "--sort=no\n--extras=+{nulltag}\n--fields=+{extras}\n-x\n--_xformat=%-16N %-10K %4n input.js %C\n"
  },
  {
    "path": "Units/parser-javascript.r/js-extract-empty-property.d/expected.tags-x",
    "content": "                 property      1 input.js var variable = { \"\": \"value\" };\nvariable         variable      1 input.js var variable = { \"\": \"value\" };\n"
  },
  {
    "path": "Units/parser-javascript.r/js-extract-empty-property.d/input.js",
    "content": "var variable = { \"\": \"value\" };\n"
  },
  {
    "path": "Units/parser-javascript.r/js-fields.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-fields.d/expected.tags",
    "content": "fun0\tinput.js\t/^var fun0 = function() {}$/;\"\tf\nClass0\tinput.js\t/^class Class0 {$/;\"\tc\nfield1\tinput.js\t/^    field1 = []$/;\"\tM\tclass:Class0\nfield2\tinput.js\t/^    field2;$/;\"\tM\tclass:Class0\nfield3\tinput.js\t/^    field3$/;\"\tM\tclass:Class0\nfield4\tinput.js\t/^    field4$/;\"\tM\tclass:Class0\nfield5\tinput.js\t/^    field5$/;\"\tM\tclass:Class0\nfield6\tinput.js\t/^    field6;$/;\"\tM\tclass:Class0\nfield7\tinput.js\t/^    field7$/;\"\tM\tclass:Class0\nfield8\tinput.js\t/^    field8 = 1;$/;\"\tM\tclass:Class0\nfield9\tinput.js\t/^    field9 = \"abc\"$/;\"\tM\tclass:Class0\nfield10\tinput.js\t/^    field10 = {}$/;\"\tM\tclass:Class0\nfield11\tinput.js\t/^    field11 = function(x, y) {$/;\"\tm\tclass:Class0\nmethod1\tinput.js\t/^    method1() {$/;\"\tm\tclass:Class0\nfield12\tinput.js\t/^    ['field12'] = 1$/;\"\tM\tclass:Class0\nfield13\tinput.js\t/^    ['field13'];$/;\"\tM\tclass:Class0\n['field1' + '4']\tinput.js\t/^    ['field1' + '4']$/;\"\tM\tclass:Class0\nfield15\tinput.js\t/^    field15 = 1$/;\"\tM\tclass:Class0\nfield16\tinput.js\t/^    field16 = [ function() {return}, function() {return} ]$/;\"\tM\tclass:Class0\nanonymousFunction391993410200\tinput.js\t/^    field16 = [ function() {return}, function() {return} ]$/;\"\tf\tclass:Class0\nanonymousFunction391993410300\tinput.js\t/^    field16 = [ function() {return}, function() {return} ]$/;\"\tf\tclass:Class0\nmethod2\tinput.js\t/^    method2() {$/;\"\tm\tclass:Class0\nmethod3\tinput.js\t/^    method3() {$/;\"\tm\tclass:Class0\nClass1\tinput.js\t/^class Class1 {$/;\"\tc\nfield10\tinput.js\t/^    field10$/;\"\tM\tclass:Class1\nmethod10\tinput.js\t/^    method10() {$/;\"\tm\tclass:Class1\nClass2\tinput.js\t/^class Class2 {field20}$/;\"\tc\nfield20\tinput.js\t/^class Class2 {field20}$/;\"\tM\tclass:Class2\nClass3\tinput.js\t/^class Class3 {field30$/;\"\tc\nfield30\tinput.js\t/^class Class3 {field30$/;\"\tM\tclass:Class3\nClass4\tinput.js\t/^class Class4 {$/;\"\tc\nfield40\tinput.js\t/^    field40$/;\"\tM\tclass:Class4\n"
  },
  {
    "path": "Units/parser-javascript.r/js-fields.d/input.js",
    "content": "var fun0 = function() {}\nclass Class0 {\n    field1 = []\n    field2;\n    field3\n    field4\n    field5\n    field6;\n    field7\n    field8 = 1;\n    field9 = \"abc\"\n    field10 = {}\n    field11 = function(x, y) {\n\treturn x + y\n    }\n\n    method1() {\n\treturn\n    }\n    ['field12'] = 1\n    ['field13'];\n    ['field1' + '4']\n    field15 = 1\n    field16 = [ function() {return}, function() {return} ]\n\n    method2() {\n\treturn\n    }\n    method3() {\n\treturn\n    }\n}\n\nclass Class1 {\n    field10\n    method10() {\n    }\n}\n\nclass Class2 {field20}\nclass Class3 {field30\n}\nclass Class4 {\n    field40\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-fq-tags.d/args.ctags",
    "content": "--extras=+q\n--fields=+K\n--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-fq-tags.d/expected.tags",
    "content": "log\tinput.js\t/^  log: ['a', 'b', 'c'],$/;\"\tproperty\tvariable:obj\nobj.log\tinput.js\t/^  log: ['a', 'b', 'c'],$/;\"\tproperty\tvariable:obj\nget\tinput.js\t/^  get: function() {$/;\"\tmethod\tvariable:obj\nobj.get\tinput.js\t/^  get: function() {$/;\"\tmethod\tvariable:obj\nobj\tinput.js\t/^var obj = {$/;\"\tvariable\nset\tinput.js\t/^  set: function(str) {$/;\"\tmethod\tvariable:o\no.set\tinput.js\t/^  set: function(str) {$/;\"\tmethod\tvariable:o\nlog\tinput.js\t/^  log: []$/;\"\tproperty\tvariable:o\no.log\tinput.js\t/^  log: []$/;\"\tproperty\tvariable:o\no\tinput.js\t/^var o = {$/;\"\tvariable\n"
  },
  {
    "path": "Units/parser-javascript.r/js-fq-tags.d/input.js",
    "content": "// Modified from\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get\nvar obj = {\n  log: ['a', 'b', 'c'],\n  get: function() {\n    if (this.log.length == 0) {\n      return undefined;\n    }\n    return this.log[this.log.length - 1];\n  }\n}\n\n// Modified from\n// https://developer.mozilla.org/en/docs/JavaScript/Reference/Operators/set\nvar o = {\n  set: function(str) {\n    this.log[this.log.length] = str;\n  },\n  log: []\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-func-in-method.d/README",
    "content": "a tag for a function defined in a method should have scope:method:...\nHowever, it had scope:function.\n"
  },
  {
    "path": "Units/parser-javascript.r/js-func-in-method.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-func-in-method.d/expected.tags",
    "content": "Class0\tinput.js\t/^class Class0 {$/;\"\tc\nf0\tinput.js\t/^    f0() {$/;\"\tm\tclass:Class0\nf00\tinput.js\t/^\tf00 = function() {}$/;\"\tf\tmethod:Class0.f0\n"
  },
  {
    "path": "Units/parser-javascript.r/js-func-in-method.d/input.js",
    "content": "class Class0 {\n    f0() {\n\tf00 = function() {}\n\treturn 0\n    }\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-function-in-arglist.d/expected.tags",
    "content": "func1\tinput.js\t/^    Test.func1 = function func1(){ console.log('func1'); };$/;\"\tf\nfunc1\tinput.js\t/^    Test.func1 = function func1(){ console.log('func1'); };$/;\"\tf\tvariable:Test\nfunc2\tinput.js\t/^    Test.func2 = function func2(){ console.log('func2'); };$/;\"\tf\nfunc2\tinput.js\t/^    Test.func2 = function func2(){ console.log('func2'); };$/;\"\tf\tvariable:Test\nfuncGen\tinput.js\t/^  function funcGen(A){$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-function-in-arglist.d/input.js",
    "content": "// Taken from #1014 submitted by @caneta\nAUI().use(\n  function funcGen(A){\n    var Test;\n    Test.func1 = function func1(){ console.log('func1'); };\n    Test.func2 = function func2(){ console.log('func2'); };\n  }\n);\n"
  },
  {
    "path": "Units/parser-javascript.r/js-get-and-set.d/args.ctags",
    "content": "--fields=+K\n--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-get-and-set.d/expected.tags",
    "content": "log\tinput.js\t/^  log: ['a', 'b', 'c'],$/;\"\tproperty\tvariable:obj\nget\tinput.js\t/^  get() {$/;\"\tmethod\tvariable:obj\nobj\tinput.js\t/^var obj = {$/;\"\tvariable\nset\tinput.js\t/^  set(str) {$/;\"\tmethod\tvariable:o\nlog\tinput.js\t/^  log: []$/;\"\tproperty\tvariable:o\no\tinput.js\t/^var o = {$/;\"\tvariable\n"
  },
  {
    "path": "Units/parser-javascript.r/js-get-and-set.d/input.js",
    "content": "// Modified from\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get\nvar obj = {\n  log: ['a', 'b', 'c'],\n  get() {\n    if (this.log.length == 0) {\n      return undefined;\n    }\n    return this.log[this.log.length - 1];\n  }\n}\n\n// Modified from\n// https://developer.mozilla.org/en/docs/JavaScript/Reference/Operators/set\nvar o = {\n  set(str) {\n    this.log[this.log.length] = str;\n  },\n  log: []\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-get-and-set2.d/args.ctags",
    "content": "--fields=+K\n--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-get-and-set2.d/expected.tags",
    "content": "log\tinput.js\t/^  log: ['a', 'b', 'c'],$/;\"\tproperty\tvariable:obj\nget\tinput.js\t/^  get: function() {$/;\"\tmethod\tvariable:obj\nobj\tinput.js\t/^var obj = {$/;\"\tvariable\nset\tinput.js\t/^  set: function(str) {$/;\"\tmethod\tvariable:o\nlog\tinput.js\t/^  log: []$/;\"\tproperty\tvariable:o\no\tinput.js\t/^var o = {$/;\"\tvariable\n"
  },
  {
    "path": "Units/parser-javascript.r/js-get-and-set2.d/input.js",
    "content": "// Modified from\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get\nvar obj = {\n  log: ['a', 'b', 'c'],\n  get: function() {\n    if (this.log.length == 0) {\n      return undefined;\n    }\n    return this.log[this.log.length - 1];\n  }\n}\n\n// Modified from\n// https://developer.mozilla.org/en/docs/JavaScript/Reference/Operators/set\nvar o = {\n  set: function(str) {\n    this.log[this.log.length] = str;\n  },\n  log: []\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-getter-and-setter.d/args.ctags",
    "content": "--fields=+K\n"
  },
  {
    "path": "Units/parser-javascript.r/js-getter-and-setter.d/expected.tags",
    "content": "current\tinput.js\t/^  set current (str) {$/;\"\tsetter\tvariable:o\nlatest\tinput.js\t/^  get latest() {$/;\"\tgetter\tvariable:obj\nlog\tinput.js\t/^  log: ['a', 'b', 'c'],$/;\"\tproperty\tvariable:obj\nlog\tinput.js\t/^  log: []$/;\"\tproperty\tvariable:o\no\tinput.js\t/^var o = {$/;\"\tvariable\nobj\tinput.js\t/^var obj = {$/;\"\tvariable\n"
  },
  {
    "path": "Units/parser-javascript.r/js-getter-and-setter.d/input.js",
    "content": "// Taken from\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get\nvar obj = {\n  log: ['a', 'b', 'c'],\n  get latest() {\n    if (this.log.length == 0) {\n      return undefined;\n    }\n    return this.log[this.log.length - 1];\n  }\n}\n\n// Taken from\n// https://developer.mozilla.org/en/docs/JavaScript/Reference/Operators/set\nvar o = {\n  set current (str) {\n    this.log[this.log.length] = str;\n  },\n  log: []\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-implicit-semicolons.d/expected.tags",
    "content": "a\tinput.js\t/^var a = 1$/;\"\tv\nb\tinput.js\t/^var b = function(){}$/;\"\tf\nc\tinput.js\t/^function c() {}$/;\"\tf\nd\tinput.js\t/^var d = {}$/;\"\tv\ne\tinput.js\t/^function e() {}$/;\"\tf\nf\tinput.js\t/^var f = []$/;\"\tv\ng\tinput.js\t/^function g() {}$/;\"\tf\nh\tinput.js\t/^var h = (1)$/;\"\tv\ni\tinput.js\t/^function i() {}$/;\"\tf\nj\tinput.js\t/^function j() {}$/;\"\tf\nk\tinput.js\t/^var k = new Function('a','b','return a+b')$/;\"\tf\nl\tinput.js\t/^function l() {}$/;\"\tf\nm\tinput.js\t/^var m = 0 \\/\\/ a single comment doesn't eat the newline$/;\"\tv\nn\tinput.js\t/^function n() {}$/;\"\tf\no\tinput.js\t/^var o = () => {$/;\"\tf\np\tinput.js\t/^var p$/;\"\tv\nq\tinput.js\t/^function q() {}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-implicit-semicolons.d/input.js",
    "content": "var a = 1\nvar b = function(){}\nfunction c() {}\nvar d = {}\nfunction e() {}\nvar f = []\nfunction g() {}\nvar h = (1)\nfunction i() {}\ndo {\n} while(0)\nfunction j() {}\nvar k = new Function('a','b','return a+b')\nfunction l() {}\nvar m = 0 // a single comment doesn't eat the newline\nfunction n() {}\n/* test from https://github.com/universal-ctags/ctags/issues/4192 */\nvar o = () => {\n  return 0\n}\nvar p\nfunction q() {}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-let.d/expected.tags",
    "content": "a\tinput.js\t/^let a = 1;$/;\"\tv\nb\tinput.js\t/^let b = 0;$/;\"\tv\nfunc\tinput.js\t/^let func = function(){}$/;\"\tf\ngroup\tinput.js\t/^let group = {$/;\"\tv\nx\tinput.js\t/^  x:1,$/;\"\tp\tvariable:group\ny\tinput.js\t/^  y:1,$/;\"\tp\tvariable:group\nz\tinput.js\t/^  z:1,$/;\"\tp\tvariable:group\n"
  },
  {
    "path": "Units/parser-javascript.r/js-let.d/input.js",
    "content": "let a = 1;\nlet b = 0;\nlet group = {\n  x:1,\n  y:1,\n  z:1,\n};\nlet func = function(){}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-many-functions.d/expected.tags",
    "content": "C1\tinput.js\t/^var C1 = {$/;\"\tv\nK1\tinput.js\t/^class K1 {$/;\"\tc\na\tinput.js\t/^function a() {$/;\"\tf\nanonymousFunction8797a7c50100\tinput.js\t/^  return function(x) {$/;\"\tf\tfunction:f1\nb\tinput.js\t/^  function b() {$/;\"\tf\tfunction:a\nc\tinput.js\t/^    function c() {$/;\"\tf\tfunction:a.b\nf1\tinput.js\t/^function f1(y) {$/;\"\tf\nf2\tinput.js\t/^function f2() {$/;\"\tf\nf2i1\tinput.js\t/^  return function f2i1() {$/;\"\tf\tfunction:f2\nf2i1i1\tinput.js\t/^    function f2i1i1() {$/;\"\tf\tfunction:f2.f2i1\nfi1\tinput.js\t/^    function fi1(x) {$/;\"\tf\tmethod:C1.m2\ngi1\tinput.js\t/^    function gi1(x) {$/;\"\tf\tmethod:K1.l2\nl1\tinput.js\t/^  l1() {$/;\"\tm\tclass:K1\nl2\tinput.js\t/^  l2(n) {$/;\"\tm\tclass:K1\nm1\tinput.js\t/^  m1: function() {$/;\"\tm\tvariable:C1\nm2\tinput.js\t/^  m2: function(n) {$/;\"\tm\tvariable:C1\n"
  },
  {
    "path": "Units/parser-javascript.r/js-many-functions.d/input.js",
    "content": "function a() {\n  function b() {\n    function c() {\n    }\n  }\n}\n\nvar C1 = {\n  m1: function() {\n    this._p = 42;\n  },\n  m2: function(n) {\n    function fi1(x) {\n      return x*n;\n    }\n    return fi1;\n  }\n};\n\nclass K1 {\n  l1() {\n    this._p = 42;\n  }\n  l2(n) {\n    function gi1(x) {\n      return x*n;\n    }\n    return gi1;\n  }\n}\n\nfunction f1(y) {\n  return function(x) {\n    return x*y;\n  }\n}\n\nfunction f2() {\n  return function f2i1() {\n    function f2i1i1() {\n      return 0;\n    }\n    return f2i1i1;\n  }\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-methods.d/expected.tags",
    "content": "Obj\tinput.js\t/^var Obj = {$/;\"\tv\nmyGenerator\tinput.js\t/^    *myGenerator(a, b) {$/;\"\tg\tvariable:Obj\nmyMethod\tinput.js\t/^    myMethod(a, b) {$/;\"\tm\tvariable:Obj\n"
  },
  {
    "path": "Units/parser-javascript.r/js-methods.d/input.js",
    "content": "// methods (functions of objects)\n// see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions\n// http://www.ecma-international.org/ecma-262/6.0/#sec-method-definitions\nvar Obj = {\n    myMethod(a, b) {\n    },\n    *myGenerator(a, b) {\n    }\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-multiple-vars.d/expected.tags",
    "content": "A\tinput.js\t/^const A, B;$/;\"\tC\nB\tinput.js\t/^const A, B;$/;\"\tC\nC\tinput.js\t/^const C = 1, D = 2;$/;\"\tC\nD\tinput.js\t/^const C = 1, D = 2;$/;\"\tC\na\tinput.js\t/^var a, b;$/;\"\tv\nb\tinput.js\t/^var a, b;$/;\"\tv\nc\tinput.js\t/^let c, d;$/;\"\tv\nd\tinput.js\t/^let c, d;$/;\"\tv\ne\tinput.js\t/^var e = 2, f = 3;$/;\"\tv\nf\tinput.js\t/^var e = 2, f = 3;$/;\"\tv\nfunc1\tinput.js\t/^var func1=function() { return 1; }, func2=function() { return 2; }$/;\"\tf\nfunc2\tinput.js\t/^var func1=function() { return 1; }, func2=function() { return 2; }$/;\"\tf\ng\tinput.js\t/^let g = 4, h = 5;$/;\"\tv\nh\tinput.js\t/^let g = 4, h = 5;$/;\"\tv\ni\tinput.js\t/^var i,$/;\"\tv\nj\tinput.js\t/^    j,$/;\"\tv\nk\tinput.js\t/^    k;$/;\"\tv\nl\tinput.js\t/^var l = 2,$/;\"\tv\nm\tinput.js\t/^    m = 2,$/;\"\tv\nn\tinput.js\t/^    n = 2;$/;\"\tv\no\tinput.js\t/^var o = 2,$/;\"\tv\np\tinput.js\t/^    p = 3$/;\"\tv\nq\tinput.js\t/^var q = 4$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-multiple-vars.d/input.js",
    "content": "\n// declarations\nvar a, b;\nlet c, d;\nconst A, B;\n\n// definitions\nvar e = 2, f = 3;\nlet g = 4, h = 5;\nconst C = 1, D = 2;\n\nvar func1=function() { return 1; }, func2=function() { return 2; }\n\n// with newlines in-between\nvar i,\n    j,\n    k;\nvar l = 2,\n    m = 2,\n    n = 2;\n\n// with missing semicolons\nvar o = 2,\n    p = 3\nvar q = 4\n"
  },
  {
    "path": "Units/parser-javascript.r/js-naked-blocks.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-naked-blocks.d/expected.tags",
    "content": "v1\tinput.js\t/^  var v1 = 1;$/;\"\tv\nv2\tinput.js\t/^    var v2 = 2;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-naked-blocks.d/input.js",
    "content": "\nif (1) {\n  var v1 = 1;\n  {\n    var v2 = 2;\n  }\n}\n\n// here v1 and v2 are available\nprint(v1);\nprint(v2);\n"
  },
  {
    "path": "Units/parser-javascript.r/js-non-printable-in-signature.d/args.ctags",
    "content": "--fields=+S\n--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-non-printable-in-signature.d/expected.tags",
    "content": "f01\tinput.js\t/^function f01(a\u0001) {}$/;\"\tf\tsignature:(a )\nf02\tinput.js\t/^function f02(a\u0002) {}$/;\"\tf\tsignature:(a )\nf03\tinput.js\t/^function f03(a\u0003) {}$/;\"\tf\tsignature:(a )\nf04\tinput.js\t/^function f04(a\u0004) {}$/;\"\tf\tsignature:(a )\nf05\tinput.js\t/^function f05(a\u0005) {}$/;\"\tf\tsignature:(a )\nf06\tinput.js\t/^function f06(a\u0006) {}$/;\"\tf\tsignature:(a )\nf07\tinput.js\t/^function f07(a\u0007) {}$/;\"\tf\tsignature:(a )\nf08\tinput.js\t/^function f08(a\b) {}$/;\"\tf\tsignature:(a )\nf09\tinput.js\t/^function f09(a\t) {}$/;\"\tf\tsignature:(a )\nf10\tinput.js\t/^function f10(a\u000b) {}$/;\"\tf\tsignature:(a )\nf11\tinput.js\t/^function f11(a\f) {}$/;\"\tf\tsignature:(a )\nf12\tinput.js\t/^function f12(a\u000e) {}$/;\"\tf\tsignature:(a )\nf13\tinput.js\t/^function f13(a\u000f) {}$/;\"\tf\tsignature:(a )\nf14\tinput.js\t/^function f14(a\u0010) {}$/;\"\tf\tsignature:(a )\nf15\tinput.js\t/^function f15(a\u0011) {}$/;\"\tf\tsignature:(a )\nf16\tinput.js\t/^function f16(a\u0012) {}$/;\"\tf\tsignature:(a )\nf17\tinput.js\t/^function f17(a\u0013) {}$/;\"\tf\tsignature:(a )\nf18\tinput.js\t/^function f18(a\u0014) {}$/;\"\tf\tsignature:(a )\nf19\tinput.js\t/^function f19(a\u0015) {}$/;\"\tf\tsignature:(a )\nf20\tinput.js\t/^function f20(a\u0016) {}$/;\"\tf\tsignature:(a )\nf21\tinput.js\t/^function f21(a\u0017) {}$/;\"\tf\tsignature:(a )\nf22\tinput.js\t/^function f22(a\u0018) {}$/;\"\tf\tsignature:(a )\nf23\tinput.js\t/^function f23(a\u0019) {}$/;\"\tf\tsignature:(a )\nf24\tinput.js\t/^function f24(a\u001a) {}$/;\"\tf\tsignature:(a )\nf25\tinput.js\t/^function f25(a\u001b) {}$/;\"\tf\tsignature:(a )\nf26\tinput.js\t/^function f26(a\u001c) {}$/;\"\tf\tsignature:(a )\nf27\tinput.js\t/^function f27(a\u001d) {}$/;\"\tf\tsignature:(a )\nf28\tinput.js\t/^function f28(a\u001e) {}$/;\"\tf\tsignature:(a )\nf29\tinput.js\t/^function f29(a\u001f) {}$/;\"\tf\tsignature:(a )\nf30\tinput.js\t/^function f30(a) {}$/;\"\tf\tsignature:(a )\n"
  },
  {
    "path": "Units/parser-javascript.r/js-non-printable-in-signature.d/input.js",
    "content": "function f01(a\u0001) {}\nfunction f02(a\u0002) {}\nfunction f03(a\u0003) {}\nfunction f04(a\u0004) {}\nfunction f05(a\u0005) {}\nfunction f06(a\u0006) {}\nfunction f07(a\u0007) {}\nfunction f08(a\b) {}\nfunction f09(a\t) {}\nfunction f10(a\u000b) {}\nfunction f11(a\f) {}\nfunction f12(a\u000e) {}\nfunction f13(a\u000f) {}\nfunction f14(a\u0010) {}\nfunction f15(a\u0011) {}\nfunction f16(a\u0012) {}\nfunction f17(a\u0013) {}\nfunction f18(a\u0014) {}\nfunction f19(a\u0015) {}\nfunction f20(a\u0016) {}\nfunction f21(a\u0017) {}\nfunction f22(a\u0018) {}\nfunction f23(a\u0019) {}\nfunction f24(a\u001a) {}\nfunction f25(a\u001b) {}\nfunction f26(a\u001c) {}\nfunction f27(a\u001d) {}\nfunction f28(a\u001e) {}\nfunction f29(a\u001f) {}\nfunction f30(a) {}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input0.d/args.ctags",
    "content": "--_fatal-warnings\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input0.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input0.d/input.js",
    "content": "function){\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input1.d/args.ctags",
    "content": "--_fatal-warnings\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input1.d/expected.tags",
    "content": ".\tinput.js\t/^X = {'.': 1};$/;\"\tp\tvariable:X\nX\tinput.js\t/^X = {'.': 1};$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input1.d/input.js",
    "content": "X = {'.': 1};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input2.d/args.ctags",
    "content": "--_fatal-warnings\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input2.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input2.d/input.js",
    "content": ":d.prototype\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input3.d/README",
    "content": "This one never causes a \"null tag\" warning.\n(input.js is valid javascript code.)\n\nHowever, the fix for js-null-tag-for-broken-input2.d\nhad possibility to introduce another bug.\nTo avoid the introduction I add this extra test\ncase here.\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input3.d/args.ctags",
    "content": "--_fatal-warnings\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input3.d/expected.tags",
    "content": "a\tinput.js\t/^\"a\".prototype = function() {}$/;\"\tc\nanonymousFunction2e03ffc00100\tinput.js\t/^\"a\".prototype = function() {}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input3.d/input.js",
    "content": "\"a\".prototype = function() {}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input4.d/README",
    "content": "This is invalid input.\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input4.d/args.ctags",
    "content": "--_fatal-warnings\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input4.d/expected.tags",
    "content": "anonymousFunction5ef75d210100\tinput.js\t/^var.prototype=function(){}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-null-tag-for-broken-input4.d/input.js",
    "content": "var.prototype=function(){}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-object-value-shortcut.d/expected.tags",
    "content": "email2\tinput.js\t/^const x = { name1, email2, other:1 };$/;\"\tp\tvariable:x\nname1\tinput.js\t/^const x = { name1, email2, other:1 };$/;\"\tp\tvariable:x\nother\tinput.js\t/^const x = { name1, email2, other:1 };$/;\"\tp\tvariable:x\nx\tinput.js\t/^const x = { name1, email2, other:1 };$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-object-value-shortcut.d/input.js",
    "content": "const x = { name1, email2, other:1 };\n"
  },
  {
    "path": "Units/parser-javascript.r/js-odd-method-names.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-odd-method-names.d/expected.tags",
    "content": "\\x21hello\tinput.js\t/^  '!hello': function(){},$/;\"\tm\tvariable:object\n\\x20hello\tinput.js\t/^  ' hello': function(){},$/;\"\tm\tvariable:object\n<hello\tinput.js\t/^  '<hello': function(){},$/;\"\tm\tvariable:object\n>hello\tinput.js\t/^  '>hello': function(){},$/;\"\tm\tvariable:object\n\\thello\tinput.js\t/^  '\thello': function(){},$/;\"\tm\tvariable:object\n\\\\hello\tinput.js\t/^  '\\\\\\\\hello': function(){},$/;\"\tm\tvariable:object\n;\"hello\tinput.js\t/^  ';\"hello': function(){},$/;\"\tm\tvariable:object\n\"hello\tinput.js\t/^  '\"hello': function(){},$/;\"\tm\tvariable:object\n'hello\tinput.js\t/^  \"'hello\": function(){},$/;\"\tm\tvariable:object\nhello!\tinput.js\t/^  'hello!': function(){},$/;\"\tm\tvariable:object\nhello \tinput.js\t/^  'hello ': function(){},$/;\"\tm\tvariable:object\nobject\tinput.js\t/^var object = {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-odd-method-names.d/input.js",
    "content": "var object = {\n  '!hello': function(){},\n  ' hello': function(){},\n  '<hello': function(){},\n  '>hello': function(){},\n  '\thello': function(){},\n  '\\\\hello': function(){},\n  ';\"hello': function(){},\n  '\"hello': function(){},\n  \"'hello\": function(){},\n  'hello!': function(){},\n  'hello ': function(){},\n};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-parenthesis-rvalue.d/expected.tags",
    "content": "a\tinput.js\t/^var d1 = {a:'hello',b:'hi'};$/;\"\tp\tvariable:d1\na\tinput.js\t/^var d2 = ({a:'hello',b:'hi'});$/;\"\tp\tvariable:d2\na1\tinput.js\t/^var a1 = 42;$/;\"\tv\na2\tinput.js\t/^var a2 = (42);$/;\"\tv\nb\tinput.js\t/^var d1 = {a:'hello',b:'hi'};$/;\"\tp\tvariable:d1\nb\tinput.js\t/^var d2 = ({a:'hello',b:'hi'});$/;\"\tp\tvariable:d2\nb1\tinput.js\t/^var b1 = function(){$/;\"\tf\nb1sub\tinput.js\t/^  function b1sub(){}$/;\"\tf\tfunction:b1\nb2\tinput.js\t/^var b2 = (function(){$/;\"\tf\nb2sub\tinput.js\t/^  function b2sub(){}$/;\"\tf\tfunction:b2\nb3\tinput.js\t/^var b3 = ((function(){$/;\"\tf\nb3sub\tinput.js\t/^  function b3sub(){}$/;\"\tf\tfunction:b3\nc1\tinput.js\t/^var c1 = {};$/;\"\tv\nc2\tinput.js\t/^var c2 = ({});$/;\"\tv\nd1\tinput.js\t/^var d1 = {a:'hello',b:'hi'};$/;\"\tv\nd2\tinput.js\t/^var d2 = ({a:'hello',b:'hi'});$/;\"\tv\ne1\tinput.js\t/^var e1 = function(){$/;\"\tf\ne1sub\tinput.js\t/^  function e1sub(){}$/;\"\tf\tfunction:e1\ne2\tinput.js\t/^var e2 = (function(){$/;\"\tf\ne2sub\tinput.js\t/^  function e2sub(){}$/;\"\tf\tfunction:e2\ne3\tinput.js\t/^var e3 = ((function(){$/;\"\tf\ne3sub\tinput.js\t/^  function e3sub(){}$/;\"\tf\tfunction:e3\n"
  },
  {
    "path": "Units/parser-javascript.r/js-parenthesis-rvalue.d/input.js",
    "content": "\n// plain values\nvar a1 = 42;\nvar a2 = (42);\n\n// functions\nvar b1 = function(){\n  function b1sub(){}\n};\nvar b2 = (function(){\n  function b2sub(){}\n});\nvar b3 = ((function(){\n  function b3sub(){}\n}));\n\n// objects\nvar c1 = {};\nvar c2 = ({});\nvar d1 = {a:'hello',b:'hi'};\nvar d2 = ({a:'hello',b:'hi'});\n\n// function expressions called straight away\nvar e1 = function(){\n  function e1sub(){}\n  return 42;\n}();\nvar e2 = (function(){\n  function e2sub(){}\n  return 42\n})();\nvar e3 = ((function(){\n  function e3sub(){}\n  return 42\n})());\n"
  },
  {
    "path": "Units/parser-javascript.r/js-parse-function-block.d/args.ctags",
    "content": "--fields=+K\n"
  },
  {
    "path": "Units/parser-javascript.r/js-parse-function-block.d/expected.tags",
    "content": "anonymousFunctionf0f039f00100\tinput.js\t/^A.add('X', function(Y) {$/;\"\tfunction\nc\tinput.js\t/^B.c = function(type, field)$/;\"\tfunction\tvariable:B\nd\tinput.js\t/^B.d = function(id)$/;\"\tfunction\tvariable:B\n"
  },
  {
    "path": "Units/parser-javascript.r/js-parse-function-block.d/input.js",
    "content": "A.add('X', function(Y) {\n\nB.c = function(type, field)\n{\n\tvar min = 5,\n\t\t  is_int = (min != 'a');\n};\n\nB.d = function(id)\n{\n};\n\n});\n"
  },
  {
    "path": "Units/parser-javascript.r/js-qualified-name-after-new-op.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-qualified-name-after-new-op.d/expected.tags",
    "content": "Car\tinput.js\t/^function Car(make, model, year) {$/;\"\tc\ncontainer\tinput.js\t/^var container = {}$/;\"\tv\ncar1\tinput.js\t/^var car1 = new container.car('Eagle', 'Talon TSi', 1993);$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-qualified-name-after-new-op.d/input.js",
    "content": "// Derived from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new\n\nfunction Car(make, model, year) {\n  this.make = make;\n  this.model = model;\n  this.year = year;\n}\n\nvar container = {}\ncontainer.car = Car;\n\nvar car1 = new container.car('Eagle', 'Talon TSi', 1993);\n\nconsole.log(car1.make);\n// expected output: \"Eagle\"\n"
  },
  {
    "path": "Units/parser-javascript.r/js-rest-parameters.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-javascript.r/js-rest-parameters.d/expected.tags",
    "content": "rf0\tinput.js\t/^function rf0(a,  b, ...manyMoreArgs0) {$/;\"\tf\tsignature:(a, b, ...manyMoreArgs0)\nrf1\tinput.js\t/^function rf1(...manyMoreArgs1) {$/;\"\tf\tsignature:(...manyMoreArgs1)\nrf2\tinput.js\t/^function rf2(a,  b, ...$/;\"\tf\tsignature:(a, b, ... manyMoreArgs0)\nrf3\tinput.js\t/^function rf3(...$/;\"\tf\tsignature:(... manyMoreArgs1)\n"
  },
  {
    "path": "Units/parser-javascript.r/js-rest-parameters.d/input.js",
    "content": "/* Derrived from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters */\nfunction rf0(a,  b, ...manyMoreArgs0) {\n  console.log(\"a\", a)\n  console.log(\"b\", b)\n  console.log(\"manyMoreArgs\", manyMoreArgs0)\n}\n\nfunction rf1(...manyMoreArgs1) {\n  console.log(\"manyMoreArgs\", manyMoreArgs1)\n}\n\nfunction rf2(a,  b, ...\n\t     manyMoreArgs0) {\n  console.log(\"a\", a)\n  console.log(\"b\", b)\n  console.log(\"manyMoreArgs\", manyMoreArgs0)\n}\n\nfunction rf3(...\n\t     manyMoreArgs1) {\n  console.log(\"manyMoreArgs\", manyMoreArgs1)\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-rest-parameters.d/validator",
    "content": "node\n"
  },
  {
    "path": "Units/parser-javascript.r/js-scope-resolution.b/args.ctags",
    "content": "--fields=+n\n"
  },
  {
    "path": "Units/parser-javascript.r/js-scope-resolution.b/expected.tags",
    "content": "Cls\tinput.js\t/^  var Cls = function() {$/;\"\tc\tline:16\tfunction:doesnt_extend\nCls\tinput.js\t/^var Cls = function() {$/;\"\tc\tline:1\nassert\tinput.js\t/^  function assert(expr, message) {$/;\"\tf\tline:37\tfunction:main\ndoesnt_extend\tinput.js\t/^function doesnt_extend() {$/;\"\tf\tline:14\ndummy1\tinput.js\t/^    this.dummy1 = function() {}$/;\"\tm\tline:18\tclass:doesnt_extend.Cls\ndummy2\tinput.js\t/^  Cls.prototype.dummy2 = function() {$/;\"\tm\tline:20\tclass:doesnt_extend.Cls\nextend\tinput.js\t/^function extend() {$/;\"\tf\tline:7\nextended\tinput.js\t/^  Cls.prototype.extended = function() {$/;\"\tm\tline:9\tclass:Cls\ninit\tinput.js\t/^  this.init = function() {$/;\"\tm\tline:2\tclass:Cls\nmain\tinput.js\t/^function main() {$/;\"\tf\tline:36\n"
  },
  {
    "path": "Units/parser-javascript.r/js-scope-resolution.b/input.js",
    "content": "var Cls = function() {\n  this.init = function() {\n    print(\"hello\")\n  }\n}\n\nfunction extend() {\n  /* this extends 'Cls' at the root scope */\n  Cls.prototype.extended = function() {\n    print(\"extended\")\n  }\n}\n\nfunction doesnt_extend() {\n  /* this extends the local Cls class */\n  var Cls = function() {\n    // just so the parser sees a class\n    this.dummy1 = function() {}\n  }\n  Cls.prototype.dummy2 = function() {\n    print(\"dummy\")\n  }\n}\n\n//function extend_dyn(cls) {\n//  /* here it's just not possible to figure it out, as it's extending a class\n//   * dynamically -- cls is the function's argument.  The only way is to\n//   * actually run the code and see on which class(es) this was called.  */\n//  cls.prototype.dynamic = function() {\n//    print('dynamic')\n//  }\n//}\n\n/*----------------*/\n\nfunction main() {\n  function assert(expr, message) {\n    if (! expr) {\n      throw new Error(message || \"Assertion failed\");\n    }\n  }\n\n  var ci = new Cls()\n  ci.init();\n\n  assert(ci.extended == undefined)\n  extend()\n  assert(ci.extended != undefined)\n\n  assert(ci.dummy == undefined)\n  doesnt_extend()\n  assert(ci.dummy == undefined)\n\n  //assert(ci.dynamic == undefined)\n  //extend_dyn(Cls)\n  //assert(ci.dynamic != undefined)\n}\nmain()\n"
  },
  {
    "path": "Units/parser-javascript.r/js-scope.d/expected.tags",
    "content": "A\tinput.js\t/^function A() {$/;\"\tc\nm1\tinput.js\t/^    m1 : function() {$/;\"\tm\tclass:A\nm2\tinput.js\t/^    m2: function() {$/;\"\tm\tclass:A\nm3\tinput.js\t/^A.prototype.m3 =$/;\"\tm\tclass:A\nm4\tinput.js\t/^B.prototype.m4 =$/;\"\tm\tclass:B\nm5\tinput.js\t/^A.prototype.m5 = () => {};$/;\"\tm\tclass:A\n"
  },
  {
    "path": "Units/parser-javascript.r/js-scope.d/input.js",
    "content": "\nfunction A() {\n    this.a = 1;\n}\n\nA.prototype = {\n    m1 : function() {\n        this.a = 2;\n\n        foo.bar.baz.hello(1);\n        foo.bar.baz.hello(2);\n        foo.bar.baz.hello(3);\n    },\n    \n    m2: function() {\n        return this.a;\n    },\n};\n\nA.prototype.m3 =\nB.prototype.m4 =\nA.prototype.m5 = () => {};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-self-invoking-anon-func.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-self-invoking-anon-func.d/expected.ctags",
    "content": "anonymousFunction204aa80e0100\tinput.js\t/^(function(x) {$/;\"\tf\na\tinput.js\t/^    var a = function (o) { return o; };$/;\"\tf\tfunction:anonymousFunction204aa80e0100\nanonymousFunction204aa80e0200\tinput.js\t/^(function(y) {$/;\"\tf\nb\tinput.js\t/^    const b = function (p) { return p; };$/;\"\tf\tfunction:anonymousFunction204aa80e0200\nanonymousFunction204aa80e0300\tinput.js\t/^!function(z) {$/;\"\tf\nc\tinput.js\t/^    const c = function (r) { return r; };$/;\"\tf\tfunction:anonymousFunction204aa80e0300\nanonymousFunction204aa80e0400\tinput.js\t/^console.log(\"a\" + (function (A) {$/;\"\tf\nanonymousFunction204aa80e0500\tinput.js\t/^}((function (B) {$/;\"\tf\nanonymousFunction204aa80e0600\tinput.js\t/^}(!function(C) {$/;\"\tf\nf\tinput.js\t/^    var f = function (t) {$/;\"\tf\tfunction:anonymousFunction204aa80e0600\n"
  },
  {
    "path": "Units/parser-javascript.r/js-self-invoking-anon-func.d/input.js",
    "content": "(function(x) {\n    var a = function (o) { return o; };\n    return x + a (1);\n})(1);\n\n(function(y) {\n    const b = function (p) { return p; };\n    return y - b (1);\n}(1));\n\n!function(z) {\n    const c = function (r) { return r; };\n    return z * c (1);\n}(1);\n\nconsole.log(\"a\" + (function (A) {\n    return A;\n}((function (B) {\n    return B;\n}(!function(C) {\n    var f = function (t) {\n\treturn !t;\n    }\n    return f(C);\n}(true)\n )))));\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-gjs.d/args.ctags",
    "content": "--fields=+l\n--guess-language-eagerly\n\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-gjs.d/expected.tags",
    "content": "f\tinput.nolang\t/^function f(){}$/;\"\tf\tlanguage:JavaScript\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-gjs.d/input.nolang",
    "content": "#!/usr/bin/env gjs\n\nfunction f(){}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-node.d/args.ctags",
    "content": "--fields=+l\n--guess-language-eagerly\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-node.d/expected.tags",
    "content": "f\tinput.nolang\t/^function f(){}$/;\"\tf\tlanguage:JavaScript\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-node.d/input.nolang",
    "content": "#!/usr/bin/env node\n\nfunction f(){}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-nodejs.d/args.ctags",
    "content": "--fields=+l\n--guess-language-eagerly\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-nodejs.d/expected.tags",
    "content": "f\tinput.nolang\t/^function f(){}$/;\"\tf\tlanguage:JavaScript\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-nodejs.d/input.nolang",
    "content": "#!/usr/bin/env nodejs\n\nfunction f(){}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-seed.d/args.ctags",
    "content": "--fields=+l\n--guess-language-eagerly\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-seed.d/expected.tags",
    "content": "f\tinput.nolang\t/^function f(){}$/;\"\tf\tlanguage:JavaScript\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang-seed.d/input.nolang",
    "content": "#!/usr/bin/env seed\n\nfunction f(){}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang.d/expected.tags",
    "content": "f\tinput.js\t/^function f(){}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-shebang.d/input.js",
    "content": "#!/usr/bin/env nodejs\n\nfunction f(){}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-signature.d/args.ctags",
    "content": "--fields=+S\n"
  },
  {
    "path": "Units/parser-javascript.r/js-signature.d/expected.tags",
    "content": "Cls\tinput.js\t/^function Cls(name) {$/;\"\tc\tsignature:(name)\nf1\tinput.js\t/^function f1() {$/;\"\tf\tsignature:()\nf2\tinput.js\t/^function f2(arg1, arg2) {$/;\"\tf\tsignature:(arg1, arg2)\nf3\tinput.js\t/^function f3($/;\"\tf\tsignature:( arg1,  arg2,  arg3 )\nf4\tinput.js\t/^function f4(a, b, c) {$/;\"\tf\tsignature:(a, b, c)\nf5\tinput.js\t/^function f5(a=\"hello\", b='hi', c=42){}$/;\"\tf\tsignature:(a=\"hello\", b='hi', c=42)\nget_name\tinput.js\t/^  get_name: function() {$/;\"\tm\tclass:Cls\tsignature:()\nhello\tinput.js\t/^Cls.prototype.hello = function(tpl) {$/;\"\tm\tclass:Cls\tsignature:(tpl)\nmain\tinput.js\t/^main = function() {$/;\"\tf\tsignature:()\nset_name\tinput.js\t/^  set_name: function(name) {$/;\"\tm\tclass:Cls\tsignature:(name)\n"
  },
  {
    "path": "Units/parser-javascript.r/js-signature.d/input.js",
    "content": "\nfunction f1() {\n}\nfunction f2(arg1, arg2) {\n}\nfunction f3(\n  arg1, // first\n  arg2, // second\n  arg3  // last\n) {\n  // ...\n}\nfunction f4(a, b, c) {\n}\n\nfunction f5(a=\"hello\", b='hi', c=42){}\n\nfunction Cls(name) {\n  this.name = name;\n}\nCls.prototype = {\n  get_name: function() {\n    return this.name;\n  },\n  set_name: function(name) {\n    this.name = name;\n  },\n}\n\nCls.prototype.hello = function(tpl) {\n  if (tpl == undefined) tpl = \"hello {}\";\n  return tpl.replace ('{}', this.name);\n}\n\nmain = function() {\n  c = new Cls(\"John\");\n  print(c.hello());\n}\n\nmain();\n"
  },
  {
    "path": "Units/parser-javascript.r/js-skip-empty-property.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-skip-empty-property.d/expected.tags",
    "content": "variable\tinput.js\t/^var variable = { \"\": \"value\" };$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-skip-empty-property.d/input.js",
    "content": "var variable = { \"\": \"value\" };\n"
  },
  {
    "path": "Units/parser-javascript.r/js-static-block.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-static-block.d/expected.tags",
    "content": "a\tinput.js\t/^class a {$/;\"\tc\nb\tinput.js\t/^    static { class b {} }$/;\"\tc\tclass:a\nfld0\tinput.js\t/^    fld0;$/;\"\tM\tclass:a\nc\tinput.js\t/^    static { class c {} }$/;\"\tc\tclass:a\nfld1\tinput.js\t/^    static fld1;$/;\"\tM\tclass:a\nd\tinput.js\t/^    static { class d {} }$/;\"\tc\tclass:a\nfld2\tinput.js\t/^    static fld2 = 1;$/;\"\tM\tclass:a\n"
  },
  {
    "path": "Units/parser-javascript.r/js-static-block.d/input.js",
    "content": "// Derived from #3948 submitted by @cpardotortosa\nclass a {\n    static { class b {} }\n    fld0;\n    static { class c {} }\n    static fld1;\n    static { class d {} }\n    static fld2 = 1;\n}\na.b\n"
  },
  {
    "path": "Units/parser-javascript.r/js-static-block.d/validator",
    "content": "node\n"
  },
  {
    "path": "Units/parser-javascript.r/js-string-continuation.d/expected.tags",
    "content": "first\tinput.js\t/^  \"first\": function(){},$/;\"\tm\tvariable:o\nfourth\tinput.js\t/^  \"fourth\": function(){},$/;\"\tm\tvariable:o\no\tinput.js\t/^var o = {$/;\"\tv\nsecond\tinput.js\t/^ond\": function(){},$/;\"\tm\tvariable:o\nthird\tinput.js\t/^\": function(){},$/;\"\tm\tvariable:o\n"
  },
  {
    "path": "Units/parser-javascript.r/js-string-continuation.d/input.js",
    "content": "\nvar o = {\n  \"first\": function(){},\n  \"sec\\\nond\": function(){},\n  \"\\\nt\\\nh\\\ni\\\nr\\\nd\\\n\": function(){},\n  \"fourth\": function(){},\n};\n\no.first();\no.second();\no.third();\no.fourth();\n"
  },
  {
    "path": "Units/parser-javascript.r/js-sub-block-scope.d/expected.tags",
    "content": "bar\tinput.js\t/^  function bar() {$/;\"\tf\tfunction:parent\nfoo\tinput.js\t/^  function foo() {$/;\"\tf\tfunction:parent\nhello\tinput.js\t/^      function hello() {$/;\"\tf\tfunction:parent.foo\nhello2\tinput.js\t/^    function hello2() {}$/;\"\tf\tfunction:parent.bar\nhi\tinput.js\t/^      function hi() {$/;\"\tf\tfunction:parent.foo\nhi2\tinput.js\t/^    function hi2() {}$/;\"\tf\tfunction:parent.bar\nparent\tinput.js\t/^function parent() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-sub-block-scope.d/input.js",
    "content": "\nfunction parent() {\n  function foo() {\n    if (test) {\n      function hello() {\n      }\n    } else {\n      function hi() {\n      }\n    }\n  }\n\n  function bar() {\n    function hello2() {}\n    function hi2() {}\n  }\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-template-strings.d/expected.tags",
    "content": "a\tinput.js\t/^var a = `he$llo${`lala`\\/*+{}*\\/\\/\\/;var bug1=2;$/;\"\tv\nb\tinput.js\t/^var b = 2;$/;\"\tv\nc\tinput.js\t/^var c = `$/;\"\tv\nd\tinput.js\t/^var d = `$\\\\{42`;$/;\"\tv\ne\tinput.js\t/^var e = `${{_:{}} || 1}`;$/;\"\tv\nf\tinput.js\t/^function f() {$/;\"\tf\nf2\tinput.js\t/^function f2() {}$/;\"\tf\nz\tinput.js\t/^var z = 42;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-template-strings.d/input.js",
    "content": "\nvar a = `he$llo${`lala`/*+{}*///;var bug1=2;\n}\nvar bug2 = 3;\nfunction bug3() {}\nguys\\`${2}`;\n\nvar b = 2;\n\nfunction f() {\n    return `hello\npeople\\` of \\` the $world$\n;\nfunction bug4() {\n    return 1;\n}`;\n}\n\nfunction f2() {}\n\nvar c = `\n\\${42`;\n\nvar d = `$\\{42`;\n\nvar e = `${{_:{}} || 1}`;\n\n// just to be sure the last element is not eaten\nvar z = 42;\n"
  },
  {
    "path": "Units/parser-javascript.r/js-tricky-newlines.d/expected.tags",
    "content": "a\tinput.js\t/^var a = 1$/;\"\tv\nb\tinput.js\t/^,   b = 1$/;\"\tv\nc\tinput.js\t/^,   c = 1$/;\"\tv\nd\tinput.js\t/^let d$/;\"\tv\ne\tinput.js\t/^,   e$/;\"\tv\nf\tinput.js\t/^,   f$/;\"\tv\ng\tinput.js\t/^var g, h$/;\"\tv\nh\tinput.js\t/^var g, h$/;\"\tv\ni\tinput.js\t/^var i, j$/;\"\tv\nj\tinput.js\t/^var i, j$/;\"\tv\nk\tinput.js\t/^var k$/;\"\tf\nl\tinput.js\t/^l$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-tricky-newlines.d/input.js",
    "content": "\nvar a = 1\n,   b = 1\n,   c = 1\n\nlet d\n,   e\n,   f\n\nvar g, h\nvar i, j\n\nvar k\n=\nfunction() {}\n,\nl\n=\nfunction(){}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-two-vars.d/expected.tags",
    "content": "x\tinput.js\t/^var x,y;$/;\"\tv\ny\tinput.js\t/^var x,y;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-two-vars.d/input.js",
    "content": "var x,y;\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape-iconv.d/args.ctags",
    "content": "--sort=no\n# just so iconv kicks in\n--input-encoding=UTF-8\n--output-encoding=UTF-8\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape-iconv.d/expected.tags",
    "content": "é_1\tinput.js\t/^function é_1() {}$/;\"\tf\né_2\tinput.js\t/^function \\\\u00E9_2() {}$/;\"\tf\né_3\tinput.js\t/^function \\\\u00e9_3() {}$/;\"\tf\né_4\tinput.js\t/^function \\\\u{e9}_4() {}$/;\"\tf\né_5\tinput.js\t/^function \\\\u{0000000000000000000e9}_5() {}$/;\"\tf\né_6\tinput.js\t/^function \\\\u{65}\\\\u0301_6() {}$/;\"\tf\n𐌀_1\tinput.js\t/^  '𐌀_1': function(){},$/;\"\tm\tvariable:object\n𐌀_2\tinput.js\t/^  '\\\\uD800\\\\uDF00_2': function(){},$/;\"\tm\tvariable:object\n𐌀_3\tinput.js\t/^  '\\\\u{10300}_3': function(){},$/;\"\tm\tvariable:object\nobject\tinput.js\t/^var object = {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape-iconv.d/features",
    "content": "iconv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape-iconv.d/input.js",
    "content": "// literal\nfunction é_1() {}\n// UTF-16 escape\nfunction \\u00E9_2() {}\nfunction \\u00e9_3() {}\n// code point escape\nfunction \\u{e9}_4() {}\n// leading zeros don't matter\nfunction \\u{0000000000000000000e9}_5() {}\n// mixed with a diacritic\nfunction \\u{65}\\u0301_6() {}\n\n// similar with a non-BMP character\n/* (this tests strings, mostly because I was unable to find a valid identifier\n *  character outside of the BMP) */\nvar object = {\n  '𐌀_1': function(){},\n  '\\uD800\\uDF00_2': function(){},\n  '\\u{10300}_3': function(){},\n};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape-iconv.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape-naked-surrogate.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape-naked-surrogate.d/expected.tags",
    "content": "\tinput.js\t/^  '\\\\uD800': function() {},$/;\"\tm\tvariable:object\n\tinput.js\t/^  '\\\\uDF00': function() {},$/;\"\tm\tvariable:object\n\tinput.js\t/^  '\\\\uDF00\\\\uD800': function() {},$/;\"\tm\tvariable:object\n𐌀\tinput.js\t/^  '\\\\uDF00\\\\uD800\\\\uDF00': function() {},$/;\"\tm\tvariable:object\n𐌀\tinput.js\t/^  '\\\\uD800\\\\uD800\\\\uDF00': function() {},$/;\"\tm\tvariable:object\na1\tinput.js\t/^  '\\\\uD800a1': function() {},$/;\"\tm\tvariable:object\na2\tinput.js\t/^  '\\\\uD800\\\\u{61}2': function() {},$/;\"\tm\tvariable:object\na1\tinput.js\t/^  '\\\\uDF00a1': function() {},$/;\"\tm\tvariable:object\na2\tinput.js\t/^  '\\\\uDF00\\\\u{61}2': function() {},$/;\"\tm\tvariable:object\na1\tinput.js\t/^  '\\\\uDF00\\\\uD800a1': function() {},$/;\"\tm\tvariable:object\na2\tinput.js\t/^  '\\\\uDF00\\\\uD800\\\\u{61}2': function() {},$/;\"\tm\tvariable:object\nobject\tinput.js\t/^var object = {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape-naked-surrogate.d/input.js",
    "content": "/* test behavior of \"naked\" UTF-16 surrogates */\nvar object = {\n  // high surrogate alone\n  '\\uD800': function() {},\n  // low surrogate alone\n  '\\uDF00': function() {},\n  // swapped high and low surrogates\n  '\\uDF00\\uD800': function() {},\n  // naked low surrogate, plus valid pair\n  '\\uDF00\\uD800\\uDF00': function() {},\n  // naked high surrogate, plus valid pair\n  '\\uD800\\uD800\\uDF00': function() {},\n\n/* same, but with extra stuff after */\n  // high surrogate alone\n  '\\uD800a1': function() {},\n  '\\uD800\\u{61}2': function() {},\n  // low surrogate alone\n  '\\uDF00a1': function() {},\n  '\\uDF00\\u{61}2': function() {},\n  // swapped high and low surrogates\n  '\\uDF00\\uD800a1': function() {},\n  '\\uDF00\\uD800\\u{61}2': function() {},\n};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape-naked-surrogate.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape.d/expected.tags",
    "content": "é_1\tinput.js\t/^function é_1() {}$/;\"\tf\né_2\tinput.js\t/^function \\\\u00E9_2() {}$/;\"\tf\né_3\tinput.js\t/^function \\\\u00e9_3() {}$/;\"\tf\né_4\tinput.js\t/^function \\\\u{e9}_4() {}$/;\"\tf\né_5\tinput.js\t/^function \\\\u{0000000000000000000e9}_5() {}$/;\"\tf\né_6\tinput.js\t/^function \\\\u{65}\\\\u0301_6() {}$/;\"\tf\n𐌀_1\tinput.js\t/^  '𐌀_1': function(){},$/;\"\tm\tvariable:object\n𐌀_2\tinput.js\t/^  '\\\\uD800\\\\uDF00_2': function(){},$/;\"\tm\tvariable:object\n𐌀_3\tinput.js\t/^  '\\\\u{10300}_3': function(){},$/;\"\tm\tvariable:object\nobject\tinput.js\t/^var object = {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unicode-escape.d/input.js",
    "content": "// literal\nfunction é_1() {}\n// UTF-16 escape\nfunction \\u00E9_2() {}\nfunction \\u00e9_3() {}\n// code point escape\nfunction \\u{e9}_4() {}\n// leading zeros don't matter\nfunction \\u{0000000000000000000e9}_5() {}\n// mixed with a diacritic\nfunction \\u{65}\\u0301_6() {}\n\n// similar with a non-BMP character\n/* (this tests strings, mostly because I was unable to find a valid identifier\n *  character outside of the BMP) */\nvar object = {\n  '𐌀_1': function(){},\n  '\\uD800\\uDF00_2': function(){},\n  '\\u{10300}_3': function(){},\n};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unknown-construct-nesting.d/expected.tags",
    "content": "aa\tinput.js\t/^  aa: function () {$/;\"\tm\tvariable:o\nbb\tinput.js\t/^  bb: function (a) {$/;\"\tm\tvariable:o\ncc\tinput.js\t/^  cc: function() {}$/;\"\tm\tvariable:o\no\tinput.js\t/^var o = {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unknown-construct-nesting.d/input.js",
    "content": "\nvar o = {\n  aa: function () {\n    foo: {\n      return ;\n    }\n  },\n  \n  bb: function (a) {\n    switch (a) {\n      case 1:\n        if (1) {\n          return 32\n        }\n        break;\n      case 2:\n        return 31;\n    }\n    return 1;\n  },\n  \n  cc: function() {}\n};\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unterminated-leak.d/input.js",
    "content": "function f() {\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unterminated-new.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unterminated-new.d/expected.tags",
    "content": "f1\tinput.js\t/^function f1() {$/;\"\tf\nf2\tinput.js\t/^function f2() {$/;\"\tf\nf3\tinput.js\t/^function f3() {$/;\"\tf\nf4\tinput.js\t/^function f4() {}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/js-unterminated-new.d/input.js",
    "content": "function f1() {\n  var o1 = new Object()}\nfunction f2() {\n  var o2 = new Function()}\nfunction f3() {\n  var o3 = (new Object())}\nfunction f4() {}\n"
  },
  {
    "path": "Units/parser-javascript.r/js-var-at-eof.d/expected.tags",
    "content": "x\tinput.js\t/^var x$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/js-var-at-eof.d/input.js",
    "content": "var x\n"
  },
  {
    "path": "Units/parser-javascript.r/jsFunc_tutorial.js.d/expected.tags",
    "content": "Ball1\tinput.js\t/^function Ball1()       \\/\\/ it may seem odd, but this declaration$/;\"\tc\nBall3\tinput.js\t/^function Ball3()       \\/\\/ it may seem odd, but declaration$/;\"\tc\nD1\tinput.js\t/^function D1(a, b) $/;\"\tc\nD2\tinput.js\t/^var D2=function(a, b) $/;\"\tc\nD2A\tinput.js\t/^var D2A=function theAdd(a, b) $/;\"\tc\nD3\tinput.js\t/^var D3=new Function(\"a\", \"b\", \"return a+b;\");$/;\"\tc\nD4\tinput.js\t/^var D4=new Function(\"a\", \"b\", $/;\"\tc\nD5\tinput.js\t/^function D5(myOperator)$/;\"\tc\nDT1\tinput.js\t/^function DT1()$/;\"\tc\nDT2\tinput.js\t/^function DT2(message)$/;\"\tc\nDT2A\tinput.js\t/^function DT2A(message)$/;\"\tc\nDT3\tinput.js\t/^function DT3()$/;\"\tc\nDT4\tinput.js\t/^function DT4(message, specifiedName)$/;\"\tc\nDT5\tinput.js\t/^function DT5(color, specifiedName, owner, weight)$/;\"\tc\nDT6\tinput.js\t/^function DT6(name, salary, mySupervisor)$/;\"\tc\nDT7\tinput.js\t/^function DT7(name, salary)$/;\"\tc\nDT7A\tinput.js\t/^function DT7A(name, salary)$/;\"\tc\nDT8\tinput.js\t/^function DT8(name, salary)$/;\"\tc\nDT9\tinput.js\t/^function DT9(name, salary)$/;\"\tc\nPT1\tinput.js\t/^function PT1()$/;\"\tc\nPT2\tinput.js\t/^function PT2(name, color)$/;\"\tc\nPT3\tinput.js\t/^function PT3(name, salary)$/;\"\tc\nadd\tinput.js\t/^myObject.add=function(a,b){return a+b};  $/;\"\tf\tvariable:myObject\nadd\tinput.js\t/^var add=D5(\"+\");                \\/\\/ creates \"add\" function$/;\"\tv\naddSalary\tinput.js\t/^PT3.prototype.addSalary=function addSalaryFunction(addition)$/;\"\tm\tclass:PT3\naddSalaryFunction\tinput.js\t/^function addSalaryFunction(addition)$/;\"\tf\naddSalaryFunctionDT9\tinput.js\t/^function addSalaryFunctionDT9(addition)$/;\"\tf\nball0\tinput.js\t/^var ball0=new DT1(); \\/\\/ ball0 now points to a new object$/;\"\tv\nball1\tinput.js\t/^var ball1=new DT2(\"creating new Ball\");  \\/\\/ creates object & $/;\"\tv\nball2\tinput.js\t/^var ball2=new Object();$/;\"\tv\nball3\tinput.js\t/^var ball3=new DT3(); \\/\\/ ball0 now points to a new instance of type Ball$/;\"\tv\nball4\tinput.js\t/^var ball4=new DT3();$/;\"\tv\nball5\tinput.js\t/^var ball5=new DT3();$/;\"\tv\nball6\tinput.js\t/^var ball6=new DT4(\"creating new Ball\", \"Soccer Ball\");  $/;\"\tv\nball7\tinput.js\t/^var ball7=new DT5(\"black\\/white\", \"Soccer Ball\", \"John\", 20);  $/;\"\tv\nball8\tinput.js\t/^var ball8=new DT5(\"gray\", \"Bowling Ball\", \"John\", 30);  $/;\"\tv\nball9\tinput.js\t/^var ball9=new DT5(\"yellow\", \"Golf Ball\", \"John\", 55);  $/;\"\tv\nballoon\tinput.js\t/^var balloon=new DT5(\"red\", \"Balloon\", \"Pete\", 10);  $/;\"\tv\nboss\tinput.js\t/^var boss=new DT6(\"John\", 200);$/;\"\tv\nboss\tinput.js\t/^var boss=new DT7(\"John\", 200000);$/;\"\tv\nboss\tinput.js\t/^var boss=new DT7A(\"John\", 200000);$/;\"\tv\nboss1\tinput.js\t/^var boss1=new DT8(\"John\", 200000);$/;\"\tv\nboss2\tinput.js\t/^var boss2=new DT7A(\"Joan\", 200000);$/;\"\tv\nboss2\tinput.js\t/^var boss2=new DT8(\"Joan\", 200000);$/;\"\tv\nboss3\tinput.js\t/^var boss3=new DT7A(\"Kim\", 200000);$/;\"\tv\ncalculate\tinput.js\t/^  function calculate(number)$/;\"\tf\tfunction:getHalfOf7\ncalculate\tinput.js\t/^  function calculate(number)$/;\"\tf\tfunction:getHalfOf8\ncalculate8\tinput.js\t/^function calculate8(number)$/;\"\tf\ngetHalfOf7\tinput.js\t/^function getHalfOf7(num1, num2, num3)     $/;\"\tf\ngetHalfOf8\tinput.js\t/^function getHalfOf8(num1, num2, num3)     $/;\"\tf\ngetSalary\tinput.js\t/^  this.getSalary=function()$/;\"\tm\tclass:DT7\ngetSalary\tinput.js\t/^  this.getSalary=function()$/;\"\tm\tclass:DT7A\ngetSalary\tinput.js\t/^  this.getSalary=function()$/;\"\tm\tclass:DT8\ngetSalary\tinput.js\t/^PT3.prototype.getSalary=function getSalaryFunction()$/;\"\tm\tclass:PT3\ngetSalaryFunctionDT9\tinput.js\t/^function getSalaryFunctionDT9()$/;\"\tf\nlivesIn\tinput.js\t/^PT2.prototype.livesIn=\"water\";$/;\"\tm\tclass:PT2\nmanager\tinput.js\t/^var manager=new DT6(\"Joan\", 50, boss);  $/;\"\tv\nmultiply\tinput.js\t/^var multiply=D5(\"*\");           \\/\\/ created \"multiply\" function$/;\"\tv\nmyFunction4\tinput.js\t/^function myFunction4(message) $/;\"\tf\nmyFunction5\tinput.js\t/^function myFunction5() $/;\"\tf\nmyFunction6\tinput.js\t/^function myFunction6() $/;\"\tf\nmyFunction6A\tinput.js\t/^function myFunction6A() $/;\"\tf\nmyFunction6AE\tinput.js\t/^myFunction6AE=function()$/;\"\tf\nmyFunction6B\tinput.js\t/^function myFunction6B() $/;\"\tf\nmyFunction6E\tinput.js\t/^myFunction6E=function()$/;\"\tf\nmyObject\tinput.js\t/^var myObject=new Object();$/;\"\tv\nmy_global_var1\tinput.js\t/^var my_global_var1 = 'global';$/;\"\tv\nobject1\tinput.js\t/^var object1=new Object();      \\/\\/ creates 3 objects$/;\"\tv\nobject2\tinput.js\t/^var object2=new Object();$/;\"\tv\nobject3\tinput.js\t/^var object3=new Object();$/;\"\tv\nprice\tinput.js\t/^PT2.prototype.price=20;$/;\"\tm\tclass:PT2\nptr\tinput.js\t/^var ptr=myFunction4;  \\/\\/ ptr points to myFunction$/;\"\tv\nptr1\tinput.js\t/^var ptr1=myFunction5;                 \\/\\/ ptr1 points to myFunction$/;\"\tv\nptr2\tinput.js\t/^var ptr2=myFunction5;                 \\/\\/ ptr2 also points to myFunction$/;\"\tv\nresultString\tinput.js\t/^var resultString=getHalfOf7(10,20,30);$/;\"\tv\nsavedFunc\tinput.js\t/^var savedFunc=myFunction6B;$/;\"\tv\nsavedFunc6B\tinput.js\t/^savedFunc6B=function()$/;\"\tf\nsavedFunction\tinput.js\t/^var savedFunction=myFunction6A;$/;\"\tv\nsayName4A\tinput.js\t/^function sayName4A(name) $/;\"\tf\nsubtract\tinput.js\t/^var subtract=D5(\"-\");           \\/\\/ creates \"subtract\" function$/;\"\tv\nteamLeader\tinput.js\t/^var teamLeader=new DT6(\"Rose\", 50, boss);  $/;\"\tv\ntheAdd\tinput.js\t/^var D2A=function theAdd(a, b) $/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/jsFunc_tutorial.js.d/input.js",
    "content": "\r\n/*\r\n * These samples were retrieved from this website:\r\n * http://www.permadi.com/tutorial/jsFunc/\r\n *\r\n * This the output you should see from running:\r\n * ctags -f - Test/jsFunc_tutorial.js\r\n *    functions\r\n *      Ball1\r\n *      Ball3\r\n *      D1\r\n *      D2\r\n *      D2A\r\n *      D3\r\n *      D4\r\n *      D5\r\n *      DT1\r\n *      DT2\r\n *      DT2A\r\n *      DT3\r\n *      PT1\r\n *      calculate8\r\n *      getHalfOf7\r\n *      getHalfOf7.calculate\r\n *      getHalfOf8\r\n *      getSalaryFunctionDT9\r\n *      myFunction4\r\n *      myFunction5\r\n *      myFunction6\r\n *      myFunction6A\r\n *      myFunction6AE\r\n *      myFunction6B\r\n *      myFunction6E\r\n *      myObject.add\r\n *      savedFunc6B\r\n *      sayName4A\r\n *      theAdd\r\n *    classes\r\n *      DT4\r\n *      DT5\r\n *      DT6\r\n *      DT7\r\n *      DT7A\r\n *      DT8\r\n *      DT9\r\n *      PT2\r\n *      PT3\r\n *      addSalaryFunction\r\n *      addSalaryFunctionDT9\r\n *    methods\r\n *      DT7.getSalary\r\n *      DT7A.getSalary\r\n *      DT8.getSalary\r\n *      PT2.livesIn\r\n *      PT2.price\r\n *      PT3.addSalary\r\n *      PT3.getSalary\r\n *    variables\r\n *      my_global_var1\r\n */\r\n\r\n// Example D1\r\n\r\nfunction D1(a, b) \r\n{                     \r\n  return a+b;\r\n}      \r\nalert(D1(1,2));        // produces 3\r\n\r\nvar my_global_var1 = 'global';\r\n\r\n// Example D2\r\n\r\nvar D2=function(a, b) \r\n{                     \r\n  return a+b;\r\n}                     \r\nalert(D2(1,2));        // produces 3\r\n\r\n\r\n// Example D2A\r\n\r\nvar D2A=function theAdd(a, b) \r\n{                     \r\n  return a+b;\r\n}                     \r\nalert(D2A(1,2));           // produces 3\r\nalert(theAdd(1,2));        // also produces 3\r\n\r\nvar myObject=new Object();\r\nmyObject.add=function(a,b){return a+b};  \r\n// myObject now has a property/a method named \"add\"\r\n// and I can use it like below\r\nmyObject.add(1, 2);\r\n\r\n\r\n// Example D3\r\n\r\nvar D3=new Function(\"a\", \"b\", \"return a+b;\");\r\nalert(D3(3,4));        // produces 7\r\n\r\n\r\n// Example D4\r\n\r\nvar D4=new Function(\"a\", \"b\", \r\n    // separate string using \"\\\"\r\n  \"('adding '+a+' and ' +b);\\\r\n   return a+b;\");\r\nalert(D4(3,4));        // produces 7\r\n\r\n\r\n// Example D5\r\n\r\nfunction D5(myOperator)\r\n{\r\n  return new Function(\"a\", \"b\", \"return a\" + myOperator + \"b;\");\r\n}\r\n\r\nvar add=D5(\"+\");                // creates \"add\" function\r\nvar subtract=D5(\"-\");           // creates \"subtract\" function\r\nvar multiply=D5(\"*\");           // created \"multiply\" function\r\n\r\n// test the functions\r\nalert(\"result of add=\"+add(10,2));            // result is 12\r\nalert(\"result of subtract=\"+subtract(10,2));  // result is 8\r\nalert(\"result of multiply=\"+multiply(10,2));  // result is 20\r\nalert(add);\r\n\r\n\r\n// Example 1\r\n\r\nfunction Ball1()       // it may seem odd, but this declaration\r\n{                     // creates a object named Ball\r\n  i=1;\r\n}                     \r\nalert(typeof Ball1);     // produces \"function\"\r\n\r\n\r\n// Example 3\r\n\r\nfunction Ball3()       // it may seem odd, but declaration\r\n{                     // creates an object named Ball, and you can \r\n}                     // refer to it or add properties to it like below\r\nBall3.callsign=\"The Ball\"; // add property to Ball\r\nalert(Ball3.callsign); // produces \"The Ball\"\r\n\r\n\r\n// Example 4\r\n\r\nfunction myFunction4(message) \r\n{ \r\n  alert(message);\r\n}\r\nvar ptr=myFunction4;  // ptr points to myFunction\r\nptr(\"hello\");\t     // executes myFunction which will prints \"hello\"\r\n\r\n\r\n// Example 4A\r\n\r\nfunction sayName4A(name) \r\n{ \r\n  alert(name);\r\n}\r\n\r\nvar object1=new Object();      // creates 3 objects\r\nvar object2=new Object();\r\nvar object3=new Object();\r\nobject1.sayMyName4A=sayName;       // assign the function to all objects\r\nobject2.sayMyName4A=sayName;\r\nobject3.sayMyName4A=sayName;\r\n  \r\nobject1.sayMyName4A(\"object1\");    // prints \"object1\"\r\nobject2.sayMyName4A(\"object2\");    // prints \"object2\"\r\nobject3.sayMyName4A(\"object3\");    // prints \"object3\"\r\n\r\n\r\n// Example 5\r\n\r\nfunction myFunction5() \r\n{ \r\n  alert(myFunction.message);\r\n}\r\nmyFunction5.message=\"old\";\r\nvar ptr1=myFunction5;                 // ptr1 points to myFunction\r\nvar ptr2=myFunction5;                 // ptr2 also points to myFunction\r\n\r\nptr1();\t\t\t\t     // prints \"old\"\r\nptr2();                              // prints \"old\"\r\n\r\nmyFunction5.message=\"new\";\r\n\r\nptr1();\t\t\t\t     // prints \"new\"\r\nptr2();                              // prints \"new\"\r\n\r\n\r\n//Example 6:\r\n\r\nfunction myFunction6() \r\n{ \r\n  alert(\"Old\");\r\n}\r\nmyFunction6(); // prints \"Old\"\r\n\r\nmyFunction6E=function()\r\n{\r\n  alert(\"New\");\r\n};\r\nmyFunction6E(); // prints \"New\"\r\n\r\n\r\n//Example 6A:\r\n\r\nfunction myFunction6A() \r\n{ \r\n  alert(\"Old\");\r\n}\r\nvar savedFunction=myFunction6A;\r\n\r\nmyFunction6AE=function()\r\n{\r\n  alert(\"New\");\r\n};\r\nmyFunction6AE();    // prints \"New\"\r\nsavedFunction();  // printf \"Old\"\r\n\r\n//Example 6B:\r\n\r\nfunction myFunction6B() \r\n{ \r\n  alert(\"Old\");\r\n}\r\nvar savedFunc=myFunction6B;\r\nsavedFunc6B=function()\r\n{\r\n  alert(\"New\");\r\n};\r\nmyFunction6B();            // prints \"Old\"\r\nsavedFunc6B();             // prints \"New\"\r\n\r\n// Example 7\r\n\r\nfunction getHalfOf7(num1, num2, num3)     \r\n{ \r\n  function calculate(number)\r\n  {\r\n    return number/2;\r\n  }\r\n\r\n  var result=\"\";\r\n  result+=calculate(num1)+\" \";\r\n  result+=calculate(num2)+\" \";\r\n  result+=calculate(num3);\r\n}         \r\nvar resultString=getHalfOf7(10,20,30);\r\nalert(resultString);         // prints \"5 10 15\"\r\n\r\n// Example 8\r\n\r\nfunction calculate8(number)\r\n{\r\n  return number/3;\r\n}\r\n\r\nfunction getHalfOf8(num1, num2, num3)     \r\n{ \r\n  function calculate(number)\r\n  {\r\n    return number/2;\r\n  }\r\n\r\n  var result=\"\";\r\n  result+=calculate(num1)+\" \";\r\n  result+=calculate(num2)+\" \";\r\n  result+=calculate(num3);\r\n}         \r\nvar resultString=getHalfOf8(10,20,30);\r\nalert(resultString);         // prints \"5 10 15\"\r\n\r\n// Example DT1\r\nfunction DT1()\r\n{\r\n}\r\nvar ball0=new DT1(); // ball0 now points to a new object\r\n\r\nalert(ball0);         // prints \"Object\" because ball0 is now an Object\r\n\r\n\r\n// Example DT2\r\n\r\nfunction DT2(message)\r\n{\r\n  alert(message);\r\n}\r\nvar ball1=new DT2(\"creating new Ball\");  // creates object & \r\n                                          // prints the message\r\nball1.name=\"ball-1\";                      // ball0 now has a \"name\" property\r\nalert(ball1.name);                        // prints \"ball-0\"\r\n\r\n\r\n// Example DT2A\r\n\r\nfunction DT2A(message)\r\n{\r\n  alert(message);\r\n}\r\nvar ball2=new Object();\r\nball2.construct=DT2A;\r\nball2.construct(\"creating new ball2\");  // executes ball0.Ball(\"creating..\");\r\nball2.name=\"ball-2\";                      \r\nalert(ball2.name);                        \r\n\r\n\r\n// Example DT3 (creates 3 ball objects)\r\n\r\nfunction DT3()\r\n{\r\n}\r\nvar ball3=new DT3(); // ball0 now points to a new instance of type Ball\r\nball3.name=\"ball-3\";  // ball0 now has a \"name\" property\r\n\r\nvar ball4=new DT3();\r\nball4.name=\"ball-4\";\r\n\r\nvar ball5=new DT3();\r\n\r\nalert(ball0.name);    // prints \"ball-0\"\r\nalert(ball1.name);    // prints \"ball-1\"\r\nalert(ball2.name);    // oops, I forgot to add \"name\" to ball2!\r\n\r\n\r\n// Example DT4\r\n\r\nfunction DT4(message, specifiedName)\r\n{\r\n  alert(message);\r\n  this.name=specifiedName;                \r\n}\r\nvar ball6=new DT4(\"creating new Ball\", \"Soccer Ball\");  \r\nalert(ball6.name);                   // prints \"Soccer Ball\"\r\n\r\n\r\n// Example DT5\r\n\r\nfunction DT5(color, specifiedName, owner, weight)\r\n{\r\n  this.name=specifiedName;                \r\n  this.color=color;\r\n  this.owner=owner;\r\n  this.weight=weigth;\r\n}\r\nvar ball7=new DT5(\"black/white\", \"Soccer Ball\", \"John\", 20);  \r\nvar ball8=new DT5(\"gray\", \"Bowling Ball\", \"John\", 30);  \r\nvar ball9=new DT5(\"yellow\", \"Golf Ball\", \"John\", 55);  \r\nvar balloon=new DT5(\"red\", \"Balloon\", \"Pete\", 10);  \r\n\r\nalert(ball7.name);                        // prints \"Soccer Ball\"\r\nalert(balloon.name);                      // prints \"Balloon\"\r\nalert(ball9.weight);                      // prints \"55\"\r\n\r\n\r\n// Example DT6\r\n\r\nfunction DT6(name, salary, mySupervisor)\r\n{\r\n  this.name=name;                \r\n  this.salary=salary;\r\n  this.supervisor=mySupervisor;\r\n}\r\nvar boss=new DT6(\"John\", 200);\r\n\r\nvar manager=new DT6(\"Joan\", 50, boss);  \r\nvar teamLeader=new DT6(\"Rose\", 50, boss);  \r\n\r\nalert(manager.supervisor.name+\" is the supervisor of \"+manager.name);\r\nalert(manager.name+\"\\'s supervisor is \"+manager.supervisor.name);  \r\n\r\n\r\n// Example DT7\r\n\r\nfunction DT7(name, salary)\r\n{\r\n  this.name=name;                \r\n  this.salary=salary;\r\n\r\n  this.addSalary=addSalaryFunction;\r\n\r\n  this.getSalary=function()\r\n                 {\r\n                   return this.salary;\r\n                 };\r\n}\r\n\r\nfunction addSalaryFunction(addition)\r\n{\r\n  this.salary=this.salary+addition;\r\n}\r\n\r\nvar boss=new DT7(\"John\", 200000);\r\nboss.addSalary(10000);                    // boss gets 10K raise\r\nalert(boss.getSalary());                  // print 210K\r\n\r\n\r\n\r\nfunction DT7A(name, salary)\r\n{\r\n  this.name=name;                \r\n  this.salary=salary;\r\n\r\n  this.addSalary=addSalaryFunction;\r\n\r\n  this.getSalary=function()\r\n                 {\r\n                   return this.salary;\r\n                 };\r\n}\r\n\r\nfunction addSalaryFunction(addition)\r\n{\r\n  this.salary=this.salary+addition;\r\n}\r\n\r\nvar boss=new DT7A(\"John\", 200000);\r\nvar boss2=new DT7A(\"Joan\", 200000);\r\nvar boss3=new DT7A(\"Kim\", 200000);\r\n\r\n\r\n// Example DT8\r\n\r\nfunction DT8(name, salary)\r\n{\r\n  this.name=name;                \r\n  this.salary=salary;\r\n\r\n  this.addSalary=addSalaryFunction;\r\n  this.getSalary=function()\r\n                 {\r\n                   return this.salary;\r\n                 };\r\n}\r\n\r\nfunction addSalaryFunction(addition)\r\n{\r\n  this.salary=this.salary+addition;\r\n}\r\n\r\nvar boss1=new DT8(\"John\", 200000);\r\nvar boss2=new DT8(\"Joan\", 200000);\r\n\r\n\r\n// add properties to getSalary function object.\r\nboss1.getSalary.owner=\"boss1\";\r\nboss2.getSalary.owner=\"boss2\";\r\nalert(boss1.getSalary.owner);   // prints \"boss1\"\r\nalert(boss2.getSalary.owner);   // prints \"boss2\"\r\n// if both objects are pointing to the same function object, then \r\n// both output above should have printed \"boss2\". \r\n\r\n// add properties to addSalary function object.\r\nboss1.addSalary.owner=\"boss1\";\r\nboss1.addSalary.owner=\"boss2\";\r\nalert(boss1.addSalary.owner);   // prints \"boss2\"\r\nalert(boss2.addSalary.owner);   // prints \"boss2\"\r\n// since both objects are not pointing to the same function, \r\n// then changes in one, affects all instances (so, both prints \"boss2\"). \r\n\r\n\r\n// Example DT9\r\n\r\nfunction DT9(name, salary)\r\n{\r\n  this.name=name;                \r\n  this.salary=salary;\r\n\r\n  this.addSalary=addSalaryFunctionDT9;\r\n  this.getSalary=getSalaryFunctionDT9;\r\n}\r\n\r\nfunction getSalaryFunctionDT9()\r\n{\r\n  return this.salary;\r\n}\r\n\r\nfunction addSalaryFunctionDT9(addition)\r\n{\r\n  this.salary=this.salary+addition;\r\n}\r\n\r\n\r\n// Example PT1\r\n\r\nfunction PT1()\r\n{\r\n}\r\nalert(PT1.prototype);  // prints \"Object\"\r\n\r\n\r\n// Example PT2\r\n\r\nfunction PT2(name, color)\r\n{\r\n  this.name=name;\r\n  this.color=color;\r\n}\r\nPT2.prototype.livesIn=\"water\";\r\nPT2.prototype.price=20;\r\n\r\n\r\n// Example PT3\r\n\r\nfunction PT3(name, salary)\r\n{\r\n  this.name=name;                \r\n  this.salary=salary;\r\n}\r\n\r\nPT3.prototype.getSalary=function getSalaryFunction()\r\n{\r\n  return this.salary;\r\n}\r\n\r\nPT3.prototype.addSalary=function addSalaryFunction(addition)\r\n{\r\n  this.salary=this.salary+addition;\r\n}\r\n"
  },
  {
    "path": "Units/parser-javascript.r/no_terminator.js.d/expected.tags",
    "content": "checkForUpdate\tinput.js\t/^function checkForUpdate() {$/;\"\tf\ncheckForUpdate2\tinput.js\t/^function checkForUpdate2() {$/;\"\tf\ngetParent\tinput.js\t/^function getParent(el, pTagName) {$/;\"\tf\nts_resortTable\tinput.js\t/^function ts_resortTable(lnk) {$/;\"\tf\nts_sort_currency\tinput.js\t/^function ts_sort_currency(a,b) { $/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/no_terminator.js.d/input.js",
    "content": "function ts_resortTable(lnk) {\r\n    if (span.getAttribute(\"sortdir\") == 'down') {\r\n        span.setAttribute('sortdir','up');\r\n    } else {\r\n        span.setAttribute('sortdir','down');\r\n    }\r\n}\r\nfunction getParent(el, pTagName) {\r\n\tif (el == null) return null;\r\n\telse if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())\t// Gecko bug, supposed to be uppercase\r\n\t\treturn el;\r\n\telse\r\n\t\treturn getParent(el.parentNode, pTagName);\r\n}\r\nfunction ts_sort_currency(a,b) { \r\n    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');\r\n    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');\r\n    return parseFloat(aa) - parseFloat(bb);\r\n}\r\nfunction checkForUpdate() {\r\n    if( 1==1 ) {\r\n        document.write(\"hello from checkForUpdate<br>\")\r\n    }\r\n    return 1;\r\n}\r\nfunction checkForUpdate2() {\r\n    if( 1==1 ) {\r\n        document.write(\"hello from checkForUpdate<br>\");\r\n    }\r\n    return 2;\r\n}\r\n\r\n"
  },
  {
    "path": "Units/parser-javascript.r/qualified-contextual.d/expected.tags",
    "content": "Foo\tinput.js\t/^class Foo {$/;\"\tc\nasync\tinput.js\t/^  async async() {}$/;\"\tm\tclass:Foo\nasync\tinput.js\t/^  static async async() {}$/;\"\tm\tclass:Foo\nstatic\tinput.js\t/^  static static() {}$/;\"\tm\tclass:Foo\nstaticProperty\tinput.js\t/^  static staticProperty = 42;$/;\"\tM\tclass:Foo\n"
  },
  {
    "path": "Units/parser-javascript.r/qualified-contextual.d/input.js",
    "content": "\nclass Foo {\n  async async() {}\n  static async async() {}\n  static static() {}\n  static staticProperty = 42;\n  static {\n    console.log('Class static initialization block called');\n  }\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/regexp.js.d/expected.tags",
    "content": "func1\tinput.js\t/^function func1() {$/;\"\tf\nfunc2\tinput.js\t/^function func2() {$/;\"\tf\nno_re1\tinput.js\t/^var no_re1 = 1 \\/ 2;$/;\"\tv\nno_re2\tinput.js\t/^var no_re2 = 1 + (1 + 2) \\/ 3;$/;\"\tv\nno_re3\tinput.js\t/^var no_re3 = 1 + {0:1}[0] \\/ 2;$/;\"\tv\nno_re4\tinput.js\t/^var no_re4 = 1 + {0:1} \\/ 8; \\/\\/ gives NaN$/;\"\tv\nno_re5\tinput.js\t/^var no_re5 = \"foo\" \\/ 2; \\/\\/ so does this$/;\"\tv\nno_re6\tinput.js\t/^var no_re6 = no_re1 \\/ 2;$/;\"\tv\nre1\tinput.js\t/^var re1 = \\/foo\\/;$/;\"\tv\nre2\tinput.js\t/^var re2 = \\/\\\\\\/\\/;$/;\"\tv\nre3\tinput.js\t/^var re3 = \\/[\\/]\\/;$/;\"\tv\nre4\tinput.js\t/^var re4 = \\/'\\/;$/;\"\tv\nre5\tinput.js\t/^var re5 = \\/[\"'\\/]\\/;$/;\"\tv\nre6\tinput.js\t/^var re6 = \\/\\\\(([a-z]*_)+\\/;$/;\"\tv\nstr1\tinput.js\t/^var str1 = \"a\\/b\\/c\".replace(\\/\\\\\\/\\/g, '-');$/;\"\tv\nstr2\tinput.js\t/^var str2 = \"Hello\".replace(\\/O\\/ig, 'O');$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/regexp.js.d/input.js",
    "content": "/*\r\n * ctags should return the following for parsing this file using:\r\n * ctags -f - simple.js\r\n * \r\n * functions:\r\n *    func1\r\n *    func2\r\n * \r\n * variables:\r\n *    no_re1\r\n *    no_re2\r\n *    no_re3\r\n *    no_re4\r\n *    no_re5\r\n *    no_re6\r\n *    re1\r\n *    re2\r\n *    re3\r\n *    re4\r\n *    re5\r\n *    re6\r\n *    str1\r\n *    str2\r\n */\r\n\r\nvar no_re1 = 1 / 2;\r\nvar no_re2 = 1 + (1 + 2) / 3;\r\nvar no_re3 = 1 + {0:1}[0] / 2;\r\nvar no_re4 = 1 + {0:1} / 8; // gives NaN\r\nvar no_re5 = \"foo\" / 2; // so does this\r\nvar no_re6 = no_re1 / 2;\r\n\r\nvar re1 = /foo/;\r\nvar re2 = /\\//;\r\nvar re3 = /[/]/;\r\nvar re4 = /'/;\r\nvar re5 = /[\"'/]/;\r\nvar re6 = /\\(([a-z]*_)+/;\r\n\r\nvar str1 = \"a/b/c\".replace(/\\//g, '-');\r\nvar str2 = \"Hello\".replace(/O/ig, 'O');\r\n\r\nfunction func1() {\r\n  return /function bug1(foo){/;\r\n}\r\n\r\nfunction func2() {\r\n  return /\\(/;\r\n}\r\n"
  },
  {
    "path": "Units/parser-javascript.r/secondary_fcn_name.js.d/expected.tags",
    "content": "D1\tinput.js\t/^function D1(a, b) $/;\"\tc\nD2\tinput.js\t/^var D2=function(a, b) $/;\"\tc\nD2A\tinput.js\t/^var D2A=function theAdd(a, b) $/;\"\tc\nmy_global_var1\tinput.js\t/^var my_global_var1 = 'global';$/;\"\tv\ntheAdd\tinput.js\t/^var D2A=function theAdd(a, b) $/;\"\tf\n"
  },
  {
    "path": "Units/parser-javascript.r/secondary_fcn_name.js.d/input.js",
    "content": "/*\r\n * ctags should return the following for parsing this file using:\r\n * ctags -f - test.js\r\n *    functions\r\n *      D1\r\n *      D2\r\n *      D2A\r\n *      theAdd\r\n *    variables\r\n *      my_global_var1\r\n */\r\nfunction D1(a, b) \r\n{                     \r\n    var my_local_var1 = 'local';\r\n    return a+b;\r\n}      \r\nalert(D1(1,2));        // produces 3\r\n\r\n\r\n// Example D2\r\n\r\nvar D2=function(a, b) \r\n{                     \r\n  return a+b;\r\n}                     \r\nalert(D2(1,2));        // produces 3\r\n\r\nvar my_global_var1 = 'global';\r\n\r\n// Example D2A\r\n\r\n// Tags should be generated for both:\r\n//    D2A\r\n//    theAdd\r\nvar D2A=function theAdd(a, b) \r\n{                     \r\n  return a+b;\r\n}                     \r\nalert(D2A(1,2));           // produces 3\r\nalert(theAdd(1,2));        // also produces 3\r\n"
  },
  {
    "path": "Units/parser-javascript.r/shift-op-jsx.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-javascript.r/shift-op-jsx.d/args.ctags",
    "content": "--input-encoding=UTF-8\n"
  },
  {
    "path": "Units/parser-javascript.r/shift-op-jsx.d/input-0.js",
    "content": "\"\\uFEFF\"<<={\n"
  },
  {
    "path": "Units/parser-javascript.r/shift-op-jsx.d/input-1.js",
    "content": "\"\\uFEFF\"<={\n"
  },
  {
    "path": "Units/parser-javascript.r/shift-op-jsx.d/input.js",
    "content": "\"\\uFEFF\"<<{\n"
  },
  {
    "path": "Units/parser-javascript.r/simple-jsx-no-guest.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+lr\n"
  },
  {
    "path": "Units/parser-javascript.r/simple-jsx-no-guest.d/expected.tags",
    "content": "foo\tinput.jsx\t/^function foo() {$/;\"\tf\tlanguage:JavaScript\troles:def\nComp1\tinput-0.jsx\t/^const Comp1 = () => {$/;\"\tf\tlanguage:JavaScript\troles:def\nx\tinput-0.jsx\t/^    const x = (arg) => console.log(arg)$/;\"\tf\tlanguage:JavaScript\tfunction:Comp1\troles:def\nComp2\tinput-0.jsx\t/^const Comp2 = (props) => {$/;\"\tf\tlanguage:JavaScript\troles:def\nComp3\tinput-0.jsx\t/^const Comp3 = (str) => {$/;\"\tf\tlanguage:JavaScript\troles:def\nComp4\tinput-0.jsx\t/^const Comp4 = (str) => {$/;\"\tf\tlanguage:JavaScript\troles:def\nComp5\tinput-0.jsx\t/^const Comp5 = (str) => {$/;\"\tf\tlanguage:JavaScript\troles:def\nz0\tinput-0.jsx\t/^var z0$/;\"\tv\tlanguage:JavaScript\troles:def\n"
  },
  {
    "path": "Units/parser-javascript.r/simple-jsx-no-guest.d/input-0.jsx",
    "content": "const Comp1 = () => {\n    const x = (arg) => console.log(arg)\n    x(4)\n    return(<Comp2 text={<p>Some Text</p>}/>)\n}\n\nconst Comp2 = (props) => {\n    return (\n\tprops.text\n    )\n}\n\nconst Comp3 = (str) => {\n    return(<div>\n\t       <h1>hello</h1>\n\t       something: {str}\n\t       <h1>bye</h1>\n\t   </div>)\n}\n\nconst Comp4 = (str) => {\n    return(<>\n\t       <h1>bonjour</h1>\n\t       something: {str}\n\t       {<h2>frag{subtitle}ment</h2>}\n\t       <h1>au revoir</h1>\n\t   </>)\n}\n\nconst Comp5 = (str) => {\n    return <x/>\n}\n\nvar z0\n\n// Taken from https://stackoverflow.com/questions/79395369/why-does-universal-ctags-fail-to-record-some-functions-in-the-tags-file-for-a-pr\n"
  },
  {
    "path": "Units/parser-javascript.r/simple-jsx-no-guest.d/input.jsx",
    "content": "function foo() {\n  var x = <div>\n    <Menu />\n  <div>;\n\n  return x;\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/simple-jsx.d/args.ctags",
    "content": "--sort=no\n--extras=+{guest}r\n--fields=+lr\n"
  },
  {
    "path": "Units/parser-javascript.r/simple-jsx.d/expected.tags",
    "content": "foo\tinput.jsx\t/^function foo() {$/;\"\tf\tlanguage:JavaScript\troles:def\nComp1\tinput-0.jsx\t/^const Comp1 = () => {$/;\"\tf\tlanguage:JavaScript\troles:def\nx\tinput-0.jsx\t/^    const x = (arg) => console.log(arg)$/;\"\tf\tlanguage:JavaScript\tfunction:Comp1\troles:def\nComp2\tinput-0.jsx\t/^const Comp2 = (props) => {$/;\"\tf\tlanguage:JavaScript\troles:def\nComp3\tinput-0.jsx\t/^const Comp3 = (str) => {$/;\"\tf\tlanguage:JavaScript\troles:def\nhello\tinput-0.jsx\t/^\t       <h1>hello<\\/h1>$/;\"\th\tlanguage:HTML\troles:def\nbye\tinput-0.jsx\t/^\t       <h1>bye<\\/h1>$/;\"\th\tlanguage:HTML\troles:def\nComp4\tinput-0.jsx\t/^const Comp4 = (str) => {$/;\"\tf\tlanguage:JavaScript\troles:def\nbonjour\tinput-0.jsx\t/^\t       <h1>bonjour<\\/h1>$/;\"\th\tlanguage:HTML\troles:def\nfrag ment\tinput-0.jsx\t/^\t       {<h2>frag{subtitle}ment<\\/h2>}$/;\"\ti\tlanguage:HTML\troles:def\nau revoir\tinput-0.jsx\t/^\t       <h1>au revoir<\\/h1>$/;\"\th\tlanguage:HTML\troles:def\nComp5\tinput-0.jsx\t/^const Comp5 = (str) => {$/;\"\tf\tlanguage:JavaScript\troles:def\nz0\tinput-0.jsx\t/^var z0$/;\"\tv\tlanguage:JavaScript\troles:def\n"
  },
  {
    "path": "Units/parser-javascript.r/simple-jsx.d/input-0.jsx",
    "content": "const Comp1 = () => {\n    const x = (arg) => console.log(arg)\n    x(4)\n    return(<Comp2 text={<p>Some Text</p>}/>)\n}\n\nconst Comp2 = (props) => {\n    return (\n\tprops.text\n    )\n}\n\nconst Comp3 = (str) => {\n    return(<div>\n\t       <h1>hello</h1>\n\t       something: {str}\n\t       <h1>bye</h1>\n\t   </div>)\n}\n\nconst Comp4 = (str) => {\n    return(<>\n\t       <h1>bonjour</h1>\n\t       something: {str}\n\t       {<h2>frag{subtitle}ment</h2>}\n\t       <h1>au revoir</h1>\n\t   </>)\n}\n\nconst Comp5 = (str) => {\n    return <x/>\n}\n\nvar z0\n\n// Taken from https://stackoverflow.com/questions/79395369/why-does-universal-ctags-fail-to-record-some-functions-in-the-tags-file-for-a-pr\n"
  },
  {
    "path": "Units/parser-javascript.r/simple-jsx.d/input.jsx",
    "content": "function foo() {\n  var x = <div>\n    <Menu />\n  <div>;\n\n  return x;\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/simple.js.d/expected.tags",
    "content": "Database\tinput.js\t/^Database.prototype.getTodaysDate = Database_getTodaysDate;$/;\"\tc\nValidClassOne\tinput.js\t/^testlib.extras.ValidClassOne = function(a,b) { $/;\"\tc\tclass:testlib.extras\nValidClassTwo\tinput.js\t/^ValidClassTwo = function () $/;\"\tc\ncalculate\tinput.js\t/^  function calculate(number)$/;\"\tf\tfunction:getHalfOf\nexecuteQueryString\tinput.js\t/^Database.prototype.executeQueryString = Db_executeQueryString;$/;\"\tm\tclass:Database\ngetHalfOf\tinput.js\t/^function getHalfOf(num1, num2, num3)     $/;\"\tf\ngetTodaysDate\tinput.js\t/^Database.prototype.getTodaysDate = Database_getTodaysDate;$/;\"\tm\tclass:Database\ninnerThree\tinput.js\t/^    var innerThree = function(a,b) {}$/;\"\tf\tfunction:validFunctionThree\ninvalidInnerFunction\tinput.js\t/^    var invalidInnerFunction = function(a,b) {}$/;\"\tf\nmy_global_var1\tinput.js\t/^var my_global_var1 = 33;$/;\"\tv\nmy_global_var2\tinput.js\t/^var my_global_var2 = \"Something\";$/;\"\tv\nmy_global_var3\tinput.js\t/^var my_global_var3;$/;\"\tv\nmy_global_var4\tinput.js\t/^var my_global_var4 = document.getElementsByTagName(\"input\");$/;\"\tv\nonchange\tinput.js\t/^    my_global_var4[i].onchange = function () {$/;\"\tf\tvariable:my_global_var4\noriginalvalue\tinput.js\t/^    var originalvalue = my_global_var4[i].value;$/;\"\tv\nvalidFunctionFive\tinput.js\t/^testlib.validFunctionFive = function(a,b) {}$/;\"\tf\tvariable:testlib\nvalidFunctionOne\tinput.js\t/^validFunctionOne = function(a,b) {}$/;\"\tf\nvalidFunctionSix\tinput.js\t/^testlib.core.validFunctionSix = function(a,b) {}$/;\"\tf\tvariable:testlib.core\nvalidFunctionThree\tinput.js\t/^function validFunctionThree(a,b) {$/;\"\tf\nvalidFunctionTwo\tinput.js\t/^function validFunctionTwo(a,b) {}$/;\"\tf\nvalidMethodFour\tinput.js\t/^    this.validMethodFour = function() {}$/;\"\tm\tclass:ValidClassTwo\nvalidMethodOne\tinput.js\t/^    'validMethodOne' : function(a,b) {},$/;\"\tm\tclass:testlib.extras.ValidClassOne\nvalidMethodThree\tinput.js\t/^    this.validMethodThree = function() {}$/;\"\tm\tclass:ValidClassTwo\nvalidMethodTwo\tinput.js\t/^    'validMethodTwo' : function(a,b) {}$/;\"\tm\tclass:testlib.extras.ValidClassOne\n"
  },
  {
    "path": "Units/parser-javascript.r/simple.js.d/input.js",
    "content": "/*\n * ctags should return the following for parsing this file using:\n * ctags -f - simple.js\n *\n * functions\n *   getHalfOf\n *   getHalfOf.calculate\n *   testlib.core.validFunctionSix\n *   testlib.validFunctionFive\n *   validFunctionOne\n *   validFunctionThree\n *   validFunctionThree.innerThree\n *   validFunctionTwo\n * classes\n *   Database\n *   ValidClassTwo\n *   testlib.extras.ValidClassOne\n * methods\n *   Database.executeQueryString\n *   Database.getTodaysDate\n *   ValidClassTwo.validMethodFour\n *   ValidClassTwo.validMethodThree\n *   testlib.extras.ValidClassOne.validMethodOne\n *   testlib.extras.ValidClassOne.validMethodTwo\n * variables\n *   my_global_var1\n *   my_global_var2\n *   my_global_var3\n *   my_global_var4\n */\n\nvalidFunctionOne = function(a,b) {}\n\nfunction validFunctionTwo(a,b) {}\n\nfunction validFunctionThree(a,b) {\n    var innerThree = function(a,b) {}\n}\n\nvar my_global_var1 = 33;\n\n//pseudo-module setup\ntestlib = {}\ntestlib.core = {}\ntestlib.extras = {}\n\nvar my_global_var2 = \"Something\";\n\ntestlib.validFunctionFive = function(a,b) {}\n\n    var invalidInnerFunction = function(a,b) {}\n\ntestlib.core.validFunctionSix = function(a,b) {}\n\ntestlib.extras.ValidClassOne = function(a,b) { \n    this.a = a; \n}\n\ntestlib.extras.ValidClassOne.prototype = {\n    'validMethodOne' : function(a,b) {},\n    'validMethodTwo' : function(a,b) {}\n}\n\nValidClassTwo = function () \n{\n    this.validMethodThree = function() {}\n\n    // unnamed method\n    this.validMethodFour = function() {}\n}\n\nvar my_global_var4 = document.getElementsByTagName(\"input\");\nfor (var i = 0; i < my_global_var4.length; i++) {\n    var originalvalue = my_global_var4[i].value;\n    my_global_var4[i].onchange = function () {\n        alert(this.value + \" == \" + originalvalue);\n    }\n}\n\nfunction getHalfOf(num1, num2, num3)     \n{ \n  function calculate(number)\n  {\n    return number/2;\n  }\n\n  var result=\"\";\n  result+=calculate(num1)+\" \";\n  result+=calculate(num2)+\" \";\n  result+=calculate(num3);\n}         \n\nvar my_global_var3;\n\nDatabase.prototype.getTodaysDate = Database_getTodaysDate;\nDatabase.prototype.executeQueryString = Db_executeQueryString;\n\n\n"
  },
  {
    "path": "Units/parser-javascript.r/spread-operator.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-javascript.r/spread-operator.d/expected.tags",
    "content": "foo\tinput.js\t/^const embedded = { foo: 'bar' }$/;\"\tp\tvariable:embedded\nembedded\tinput.js\t/^const embedded = { foo: 'bar' }$/;\"\tv\nbaz\tinput.js\t/^  baz: 'fox',$/;\"\tp\tvariable:something\nsomething\tinput.js\t/^const something = {$/;\"\tv\nmapGetters\tinput.js\t/^const mapGetters = function() {}$/;\"\tf\ncomputed\tinput.js\t/^const computed = {$/;\"\tC\nfn\tinput.js\t/^  fn: () => { \\/* doing something *\\/ },$/;\"\tm\tvariable:FNO\nFNO\tinput.js\t/^const FNO = {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-javascript.r/spread-operator.d/input.js",
    "content": "//\n// This test input is based on the comment submitted by @AdrienGiboire in #3435\n//\n\nconst embedded = { foo: 'bar' }\nconst something = {\n  ...embedded,\n  baz: 'fox',\n}\n\nconst mapGetters = function() {}\nconst computed = {\n  ...mapGetters([\n    'getAsylumAssistant',\n    'getModel',\n    'getType',\n  ]),\n}\n\nconst FNO = {\n  fn: () => { /* doing something */ },\n}\n"
  },
  {
    "path": "Units/parser-javascript.r/tagging-empty-name.d/README",
    "content": "This is a crash test.\nSee #900, #1112, and #3427.\n"
  },
  {
    "path": "Units/parser-javascript.r/tagging-empty-name.d/input.js",
    "content": "const\n"
  },
  {
    "path": "Units/parser-javascript.r/ui5.controller.js.d/expected.tags",
    "content": "app.my_form\tinput.js\t/^sap.ui.controller(\"app.my_form\", {$/;\"\tc\nonInit\tinput.js\t/^    onInit : function () {$/;\"\tm\tclass:app.my_form\nrefreshForm\tinput.js\t/^    refreshForm : function (AUFNR) {$/;\"\tm\tclass:app.my_form\nrefreshSettlements\tinput.js\t/^    refreshSettlements : function (AUFNR) {$/;\"\tm\tclass:app.my_form\nsetRefreshed\tinput.js\t/^    setRefreshed : function (value) {$/;\"\tm\tclass:app.my_form\nsuccessfulRequest\tinput.js\t/^    successfulRequest: function(data) {$/;\"\tm\tclass:app.my_form\n"
  },
  {
    "path": "Units/parser-javascript.r/ui5.controller.js.d/input.js",
    "content": "sap.ui.controller(\"app.my_form\", {\r\n\r\n    successfulRequest: function(data) {\r\n        switch( data.mParameters.headers.SAAP_SERVICE ) {\r\n            case SAAP_SERVICE.APPROVAL_DETAIL:\r\n                if (thisForm.getController().mApproval) {\r\n                }\r\n        }\r\n    },\r\n\r\n    onInit : function () {\r\n        this.selectListView = null;\r\n        sap.ui.getCore().byId(\"id_createButton\").setEnabled(true);\r\n    },\r\n\r\n    refreshForm : function (AUFNR) {\r\n        if (AUFNR && AUFNR !== '') {\r\n            this.objId = this.oView.sId;\r\n        }\r\n        return;\r\n    },\r\n\r\n    refreshSettlements : function (AUFNR) {\r\n    },\r\n\r\n    setRefreshed : function (value) {\r\n        this.refreshed = value;\r\n    },\r\n});\r\n\r\n\r\n"
  },
  {
    "path": "Units/parser-jni.r/broken.d/args.ctags",
    "content": "--sort=no\n--extras=+s\n--fields=+S\n--kinds-C=+l\n"
  },
  {
    "path": "Units/parser-jni.r/broken.d/expected.tags",
    "content": "a\tinput.c\t/^int a;$/;\"\tv\ttyperef:typename:int\ngMethods00\tinput.c\t/^static JNINativeMethod gMethods00[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods01\tinput.c\t/^static JNINativeMethod gMethods01[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods02\tinput.c\t/^static JNINativeMethod gMethods02[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods03\tinput.c\t/^static JNINativeMethod gMethods03[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods04\tinput.c\t/^static JNINativeMethod gMethods04[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods05\tinput.c\t/^static JNINativeMethod gMethods05[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods06\tinput.c\t/^static JNINativeMethod gMethods06[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods10\tinput.c\t/^static JNINativeMethod gMethods10[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods20\tinput.c\t/^static JNINativeMethod gMethods20[] =;$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods21\tinput.c\t/^static JNINativeMethod gMethods21[] = 1;$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods22\tinput.c\t/^static JNINativeMethod gMethods22[] = \"a\";$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods23\tinput.c\t/^static JNINativeMethod gMethods23[] = ['a'];$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods24\tinput.c\t/^static JNINativeMethod gMethods24[] = [NULL];$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods25\tinput.c\t/^static JNINativeMethod gMethods25[] = [[NULL]];$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods30\tinput.c\t/^static JNINativeMethod gMethods30[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\ngMethods40\tinput.c\t/^static JNINativeMethod gMethods40[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\nb\tinput.c\t/^int b;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-jni.r/broken.d/input.c",
    "content": "int a;\nstatic JNINativeMethod gMethods00[] = {\n};\nstatic JNINativeMethod gMethods01[] = {\n\t,\n};\nstatic JNINativeMethod gMethods02[] = {\n\t{}\n};\nstatic JNINativeMethod gMethods03[] = {\n\t{,}\n};\nstatic JNINativeMethod gMethods04[] = {\n\t{,,}\n};\nstatic JNINativeMethod gMethods05[] = {\n\t,,\n};\nstatic JNINativeMethod gMethods06[] = {\n\t,{},\n};\n\nstatic JNINativeMethod gMethods10[] = {\n\t{\"M0\"},\n\t{\"M1\",},\n\t{\"M2\",\"S\"},\n\t{\"M3\",[], \"S\"},\n\tNULL,\n\t{4},\n\t{NULL},\n\t{\"\"},\n\t{\"\",},\n\t{,\"\"},\n\t{NULL, \"\"},\n\t{\"\",NULL},\n\t{NULL,\"\"},\n};\n\nstatic JNINativeMethod gMethods20[] =;\nstatic JNINativeMethod gMethods21[] = 1;\nstatic JNINativeMethod gMethods22[] = \"a\";\nstatic JNINativeMethod gMethods23[] = ['a'];\nstatic JNINativeMethod gMethods24[] = [NULL];\nstatic JNINativeMethod gMethods25[] = [[NULL]];\n\nstatic JNINativeMethod gMethods30[] = {\n\t{\"m0\", \"()\"},\n\t{\"m1\", \"(\"},\n\t{\"m2\", \")\"},\n\t{\"m3\", \"i\"},\n};\n\nstatic JNINativeMethod gMethods40[] = {\n\t{\"\", \"(I)V\"},\n};\n\nint b;\n"
  },
  {
    "path": "Units/parser-jni.r/simple.d/args.ctags",
    "content": "--sort=no\n--extras=+s\n--fields=+S\n--kinds-C++=+l\n"
  },
  {
    "path": "Units/parser-jni.r/simple.d/expected.tags",
    "content": "gMethods\tinput.cpp\t/^static JNINativeMethod gMethods[] = {$/;\"\tv\ttyperef:typename:JNINativeMethod[]\tfile:\nnGetMaximumTextureWidth\tinput.cpp\t/^        {\"nGetMaximumTextureWidth\", \"()I\", (void*)android_view_DisplayListCanvas_getMaxTextureSi/;\"\tm\tvariable:gMethods\ttyperef:typename:I\tsignature:()\nnGetMaximumTextureHeight\tinput.cpp\t/^        {\"nGetMaximumTextureHeight\", \"()I\",$/;\"\tm\tvariable:gMethods\ttyperef:typename:I\tsignature:()\nnCreateDisplayListCanvas\tinput.cpp\t/^        {\"nCreateDisplayListCanvas\", \"(JII)J\",$/;\"\tm\tvariable:gMethods\ttyperef:typename:J\tsignature:(JII)\nnResetDisplayListCanvas\tinput.cpp\t/^        {\"nResetDisplayListCanvas\", \"(JJII)V\",$/;\"\tm\tvariable:gMethods\ttyperef:typename:V\tsignature:(JJII)\nnEnableZ\tinput.cpp\t/^        {\"nEnableZ\", \"(JZ)V\", (void*)android_view_DisplayListCanvas_enableZ},$/;\"\tm\tvariable:gMethods\ttyperef:typename:V\tsignature:(JZ)\nnFinishRecording\tinput.cpp\t/^        {\"nFinishRecording\", \"(JJ)V\", (void*)android_view_DisplayListCanvas_finishRecording},$/;\"\tm\tvariable:gMethods\ttyperef:typename:V\tsignature:(JJ)\nnDrawRenderNode\tinput.cpp\t/^        {\"nDrawRenderNode\", \"(JJ)V\", (void*)android_view_DisplayListCanvas_drawRenderNode},$/;\"\tm\tvariable:gMethods\ttyperef:typename:V\tsignature:(JJ)\nnDrawTextureLayer\tinput.cpp\t/^        {\"nDrawTextureLayer\", \"(JJ)V\", (void*)android_view_DisplayListCanvas_drawTextureLayer},$/;\"\tm\tvariable:gMethods\ttyperef:typename:V\tsignature:(JJ)\nnDrawCircle\tinput.cpp\t/^        {\"nDrawCircle\", \"(JJJJJ)V\", (void*)android_view_DisplayListCanvas_drawCircleProps},$/;\"\tm\tvariable:gMethods\ttyperef:typename:V\tsignature:(JJJJJ)\nnDrawRoundRect\tinput.cpp\t/^        {\"nDrawRoundRect\", \"(JJJJJJJJ)V\", (void*)android_view_DisplayListCanvas_drawRoundRectPro/;\"\tm\tvariable:gMethods\ttyperef:typename:V\tsignature:(JJJJJJJJ)\nnDrawWebViewFunctor\tinput.cpp\t/^        {\"nDrawWebViewFunctor\", \"(JI)V\", (void*)android_view_DisplayListCanvas_drawWebViewFuncto/;\"\tm\tvariable:gMethods\ttyperef:typename:V\tsignature:(JI)\nnDrawRipple\tinput.cpp\t/^        {\"nDrawRipple\", \"(JJJJJJJIJ)V\", (void*)android_view_DisplayListCanvas_drawRippleProps},$/;\"\tm\tvariable:gMethods\ttyperef:typename:V\tsignature:(JJJJJJJIJ)\nlanguages\tinput.cpp\t/^static Lanaguage languages [] = {$/;\"\tv\ttyperef:typename:Lanaguage[]\tfile:\nfoo\tinput-0.cpp\t/^static void foo()$/;\"\tf\ttyperef:typename:void\tfile:\tsignature:()\nLocalMethods\tinput-0.cpp\t/^  static JNINativeMethod LocalMethods[] = {{\"aLocalMethod\", \"()I\", (void*)localMethod},};$/;\"\tl\tfunction:foo\ttyperef:typename:JNINativeMethod[]\tfile:\naLocalMethod\tinput-0.cpp\t/^  static JNINativeMethod LocalMethods[] = {{\"aLocalMethod\", \"()I\", (void*)localMethod},};$/;\"\tm\tlocal:foo.LocalMethods\ttyperef:typename:I\tsignature:()\nCC\tinput-1.cpp\t/^#define CC /;\"\td\tfile:\nFN_PTR\tinput-1.cpp\t/^#define FN_PTR(f) CAST_FROM_FN_PTR(/;\"\td\tfile:\tsignature:(f)\nLANG\tinput-1.cpp\t/^#define LANG /;\"\td\tfile:\nUH_methods\tinput-1.cpp\t/^static JNINativeMethod UH_methods[] = {$/;\"\tv\ttyperef:typename:JVM_END JNINativeMethod[]\tfile:\nfreeUpcallStub0\tinput-1.cpp\t/^  {CC \"freeUpcallStub0\",     CC \"(J)Z\",                FN_PTR(UH_FreeUpcallStub0)}$/;\"\tm\tvariable:UH_methods\ttyperef:typename:Z\tsignature:(J)\n"
  },
  {
    "path": "Units/parser-jni.r/simple.d/input-0.cpp",
    "content": "static void foo()\n{\n  static JNINativeMethod LocalMethods[] = {{\"aLocalMethod\", \"()I\", (void*)localMethod},};\n}\n// The line: and the end: of LocalMethods are the same.\n"
  },
  {
    "path": "Units/parser-jni.r/simple.d/input-1.cpp",
    "content": "// Taken from java-21-openjdk/jdk-21.0.6+7/src/hotspot/share/prims/upcallStubs.cpp\n/*\n * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n *\n * This code is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License version 2 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n * version 2 for more details (a copy is included in the LICENSE file that\n * accompanied this code).\n *\n * You should have received a copy of the GNU General Public License version\n * 2 along with this work; if not, write to the Free Software Foundation,\n * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\n\n#include \"precompiled.hpp\"\n#include \"code/codeBlob.hpp\"\n#include \"code/codeCache.hpp\"\n#include \"runtime/interfaceSupport.inline.hpp\"\n\nJVM_ENTRY(static jboolean, UH_FreeUpcallStub0(JNIEnv *env, jobject _unused, jlong addr))\n  // safe to call 'find_blob' without code cache lock, because stub is always alive\n  CodeBlob* cb = CodeCache::find_blob((char*)addr);\n  if (cb == nullptr) {\n    return false;\n  }\n  UpcallStub::free(cb->as_upcall_stub());\n  return true;\nJVM_END\n\n#define CC (char*)  /*cast a literal from (const char*)*/\n#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)\n#define LANG \"Ljava/lang/\"\n\n// These are the native methods on jdk.internal.foreign.NativeInvoker.\nstatic JNINativeMethod UH_methods[] = {\n  {CC \"freeUpcallStub0\",     CC \"(J)Z\",                FN_PTR(UH_FreeUpcallStub0)}\n};\n\n/**\n * This one function is exported, used by NativeLookup.\n */\nJVM_LEAF(void, JVM_RegisterUpcallHandlerMethods(JNIEnv *env, jclass UH_class))\n  int status = env->RegisterNatives(UH_class, UH_methods, sizeof(UH_methods)/sizeof(JNINativeMethod));\n  guarantee(status == JNI_OK && !env->ExceptionOccurred(),\n            \"register jdk.internal.foreign.abi.UpcallStubs natives\");\nJVM_END\n"
  },
  {
    "path": "Units/parser-jni.r/simple.d/input.cpp",
    "content": "// Taken from base/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp\n// in https://android.googlesource.com/platform/frameworks/base\n/*\n * Copyright (C) 2010 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nstatic JNINativeMethod gMethods[] = {\n        {\"nGetMaximumTextureWidth\", \"()I\", (void*)android_view_DisplayListCanvas_getMaxTextureSize},\n        {\"nGetMaximumTextureHeight\", \"()I\",\n         (void*)android_view_DisplayListCanvas_getMaxTextureSize},\n        // ------------ @CriticalNative --------------\n        {\"nCreateDisplayListCanvas\", \"(JII)J\",\n         (void*)android_view_DisplayListCanvas_createDisplayListCanvas},\n        {\"nResetDisplayListCanvas\", \"(JJII)V\",\n         (void*)android_view_DisplayListCanvas_resetDisplayListCanvas},\n        {\"nEnableZ\", \"(JZ)V\", (void*)android_view_DisplayListCanvas_enableZ},\n        {\"nFinishRecording\", \"(JJ)V\", (void*)android_view_DisplayListCanvas_finishRecording},\n        {\"nDrawRenderNode\", \"(JJ)V\", (void*)android_view_DisplayListCanvas_drawRenderNode},\n        {\"nDrawTextureLayer\", \"(JJ)V\", (void*)android_view_DisplayListCanvas_drawTextureLayer},\n        {\"nDrawCircle\", \"(JJJJJ)V\", (void*)android_view_DisplayListCanvas_drawCircleProps},\n        {\"nDrawRoundRect\", \"(JJJJJJJJ)V\", (void*)android_view_DisplayListCanvas_drawRoundRectProps},\n        {\"nDrawWebViewFunctor\", \"(JI)V\", (void*)android_view_DisplayListCanvas_drawWebViewFunctor},\n        {\"nDrawRipple\", \"(JJJJJJJIJ)V\", (void*)android_view_DisplayListCanvas_drawRippleProps},\n};\n\n\nstatic Lanaguage languages [] = {\n  {\"C\", 1},\n  {\"D\", 1},\n  {\"Lisp\", 0},\n};\n"
  },
  {
    "path": "Units/parser-json.r/dotted-names.d/expected.tags",
    "content": "0\tinput.json\t/^    {$/;\"\to\tarray:phone.numbers\n1\tinput.json\t/^    {$/;\"\to\tarray:phone.numbers\naddress\tinput.json\t/^  \"address\": {$/;\"\to\nage\tinput.json\t/^  \"age\": 25,$/;\"\tn\nchildren\tinput.json\t/^  \"children\": [],$/;\"\ta\ncity\tinput.json\t/^    \"city\": \"New York\",$/;\"\ts\tobject:address\nfirst.name\tinput.json\t/^  \"first.name\": \"John\",$/;\"\ts\nheight_cm\tinput.json\t/^  \"height_cm\": 167.6,$/;\"\tn\nis.alive\tinput.json\t/^  \"is.alive\": true,$/;\"\tb\nlast.name\tinput.json\t/^  \"last.name\": \"Smith\",$/;\"\ts\nnumber\tinput.json\t/^      \"number\": \"212 555-1234\"$/;\"\ts\tobject:phone.numbers.0\nnumber\tinput.json\t/^      \"number\": \"646 555-4567\"$/;\"\ts\tobject:phone.numbers.1\nphone.numbers\tinput.json\t/^  \"phone.numbers\": [$/;\"\ta\npostal.code\tinput.json\t/^    \"postal.code\": \"10021-3100\"$/;\"\ts\tobject:address\nspouse\tinput.json\t/^  \"spouse\": null$/;\"\tz\nstate\tinput.json\t/^    \"state\": \"NY\",$/;\"\ts\tobject:address\nstreet.address\tinput.json\t/^    \"street.address\": \"21 2nd Street\",$/;\"\ts\tobject:address\ntype\tinput.json\t/^      \"type\": \"home\",$/;\"\ts\tobject:phone.numbers.0\ntype\tinput.json\t/^      \"type\": \"office\",$/;\"\ts\tobject:phone.numbers.1\n"
  },
  {
    "path": "Units/parser-json.r/dotted-names.d/input.json",
    "content": "{\n  \"first.name\": \"John\",\n  \"last.name\": \"Smith\",\n  \"is.alive\": true,\n  \"age\": 25,\n  \"height_cm\": 167.6,\n  \"address\": {\n    \"street.address\": \"21 2nd Street\",\n    \"city\": \"New York\",\n    \"state\": \"NY\",\n    \"postal.code\": \"10021-3100\"\n  },\n  \"phone.numbers\": [\n    {\n      \"type\": \"home\",\n      \"number\": \"212 555-1234\"\n    },\n    {\n      \"type\": \"office\",\n      \"number\": \"646 555-4567\"\n    }\n  ],\n  \"children\": [],\n  \"spouse\": null\n}\n"
  },
  {
    "path": "Units/parser-json.r/fq-tags.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--fields=+oe\n"
  },
  {
    "path": "Units/parser-json.r/fq-tags.d/expected.tags",
    "content": "0\tinput.json\t/^      \"b\": [1, true, {}],$/;\"\tn\tarray:welcome.x.b\tend:4\tnth:0\nwelcome.x.b.0\tinput.json\t/^      \"b\": [1, true, {}],$/;\"\tn\tarray:welcome.x.b\tend:4\tnth:0\n1\tinput.json\t/^      \"b\": [1, true, {}],$/;\"\tb\tarray:welcome.x.b\tend:4\tnth:1\nwelcome.x.b.1\tinput.json\t/^      \"b\": [1, true, {}],$/;\"\tb\tarray:welcome.x.b\tend:4\tnth:1\n2\tinput.json\t/^      \"b\": [1, true, {}],$/;\"\to\tarray:welcome.x.b\tend:4\tnth:2\nwelcome.x.b.2\tinput.json\t/^      \"b\": [1, true, {}],$/;\"\to\tarray:welcome.x.b\tend:4\tnth:2\nb\tinput.json\t/^      \"b\": [1, true, {}],$/;\"\ta\tobject:welcome.x\tend:4\nwelcome.x.b\tinput.json\t/^      \"b\": [1, true, {}],$/;\"\ta\tobject:welcome.x\tend:4\nc\tinput.json\t/^      \"c\": \"hello {{.Name}}\"$/;\"\ts\tobject:welcome.x\tend:5\nwelcome.x.c\tinput.json\t/^      \"c\": \"hello {{.Name}}\"$/;\"\ts\tobject:welcome.x\tend:5\nx\tinput.json\t/^    \"x\": {$/;\"\to\tobject:welcome\tend:6\nwelcome.x\tinput.json\t/^    \"x\": {$/;\"\to\tobject:welcome\tend:6\nwelcome\tinput.json\t/^  \"welcome\": {$/;\"\to\tend:7\n"
  },
  {
    "path": "Units/parser-json.r/fq-tags.d/input.json",
    "content": "{\n  \"welcome\": {\n    \"x\": {\n      \"b\": [1, true, {}],\n      \"c\": \"hello {{.Name}}\"\n    }\n  }\n}\n"
  },
  {
    "path": "Units/parser-json.r/nulltags.d/args.ctags",
    "content": "--sort=no\n--extras=+{nulltag}\n--_xformat=%-16N %-10K %4n/%-4{end} %C %{scopeKind}:%{scope}\n"
  },
  {
    "path": "Units/parser-json.r/nulltags.d/expected.tags-x",
    "content": "<e>              string        3/3    \"<e>\": \"Empty\", object:legend\n<n>              string        4/4    \"<n>\": \"Nonempty\" object:legend\nlegend           object        2/5    \"legend\": { :\n                 string        9/9    \"\": \"Empty\", :\neeen             string       10/10   \"eeen\": \"Nonempty\" :\n                 object        8/11   \"\": { :\n                 string       13/13   \"\": \"Empty\", object:een\neenn             string       14/14   \"eenn\": \"Nonempty\" object:een\neen              object       12/15   \"een\": { :\n                 object        7/16   \"\": { :\n                 string       19/19   \"\": \"Empty\", object:en.\nenen             string       20/20   \"enen\": \"Nonempty\" object:en.\n                 object       18/21   \"\": { object:en\n                 string       23/23   \"\": \"Empty\", object:en.enn\nennn             string       24/24   \"ennn\": \"Nonempty\" object:en.enn\nenn              object       22/25   \"enn\": { object:en\nen               object       17/26   \"en\": { :\n                 object        6/27   \"\": { :\n                 string       31/31   \"\": \"Empty\", object:n..\nneen             string       32/32   \"neen\": \"Nonempty\" object:n..\n                 object       30/33   \"\": { object:n.\n                 string       35/35   \"\": \"Empty\", object:n..nen\nnenn             string       36/36   \"nenn\": \"Nonempty\" object:n..nen\nnen              object       34/37   \"nen\": { object:n.\n                 object       29/38   \"\": { object:n\n                 string       41/41   \"\": \"Empty\", object:n.nn.\nnnen             string       42/42   \"nnen\": \"Nonempty\" object:n.nn.\n                 object       40/43   \"\": { object:n.nn\n                 string       45/45   \"\": \"Empty\", object:n.nn.nnn\nnnnn             string       46/46   \"nnnn\": \"Nonempty\" object:n.nn.nnn\nnnn              object       44/47   \"nnn\": { object:n.nn\nnn               object       39/48   \"nn\": { object:n\nn                object       28/49   \"n\": { :\n"
  },
  {
    "path": "Units/parser-json.r/nulltags.d/input.json",
    "content": "{\n   \"legend\": {\n       \"<e>\": \"Empty\",\n       \"<n>\": \"Nonempty\"\n   },\n   \"\": {\n       \"\": {\n           \"\": {\n               \"\":     \"Empty\",\n               \"eeen\": \"Nonempty\"\n           },\n           \"een\": {\n               \"\":     \"Empty\",\n               \"eenn\": \"Nonempty\"\n           }\n       },\n       \"en\": {\n           \"\": {\n               \"\":     \"Empty\",\n               \"enen\": \"Nonempty\"\n           },\n           \"enn\": {\n               \"\":     \"Empty\",\n               \"ennn\": \"Nonempty\"\n           }\n       }\n   },\n   \"n\": {\n       \"\": {\n           \"\": {\n               \"\":     \"Empty\",\n               \"neen\": \"Nonempty\"\n           },\n           \"nen\": {\n               \"\":     \"Empty\",\n               \"nenn\": \"Nonempty\"\n           }\n       },\n       \"nn\": {\n           \"\": {\n               \"\":     \"Empty\",\n               \"nnen\": \"Nonempty\"\n           },\n           \"nnn\": {\n               \"\":     \"Empty\",\n               \"nnnn\": \"Nonempty\"\n           }\n       }\n   }\n}\n"
  },
  {
    "path": "Units/parser-json.r/simple-json.d/args.ctags",
    "content": "--fields=+o\n"
  },
  {
    "path": "Units/parser-json.r/simple-json.d/expected.tags",
    "content": "0\tinput.json\t/^    {$/;\"\to\tarray:phoneNumbers\tnth:0\n1\tinput.json\t/^    {$/;\"\to\tarray:phoneNumbers\tnth:1\naddress\tinput.json\t/^  \"address\": {$/;\"\to\nage\tinput.json\t/^  \"age\": 25,$/;\"\tn\nchildren\tinput.json\t/^  \"children\": [],$/;\"\ta\ncity\tinput.json\t/^    \"city\": \"New York\",$/;\"\ts\tobject:address\nfirstName\tinput.json\t/^  \"firstName\": \"John\",$/;\"\ts\nheight_cm\tinput.json\t/^  \"height_cm\": 167.6,$/;\"\tn\nisAlive\tinput.json\t/^  \"isAlive\": true,$/;\"\tb\nlastName\tinput.json\t/^  \"lastName\": \"Smith\",$/;\"\ts\nnumber\tinput.json\t/^      \"number\": \"212 555-1234\"$/;\"\ts\tobject:phoneNumbers.0\nnumber\tinput.json\t/^      \"number\": \"646 555-4567\"$/;\"\ts\tobject:phoneNumbers.1\nphoneNumbers\tinput.json\t/^  \"phoneNumbers\": [$/;\"\ta\npostalCode\tinput.json\t/^    \"postalCode\": \"10021-3100\"$/;\"\ts\tobject:address\nspouse\tinput.json\t/^  \"spouse\": null$/;\"\tz\nstate\tinput.json\t/^    \"state\": \"NY\",$/;\"\ts\tobject:address\nstreetAddress\tinput.json\t/^    \"streetAddress\": \"21 2nd Street\",$/;\"\ts\tobject:address\ntype\tinput.json\t/^      \"type\": \"home\",$/;\"\ts\tobject:phoneNumbers.0\ntype\tinput.json\t/^      \"type\": \"office\",$/;\"\ts\tobject:phoneNumbers.1\n"
  },
  {
    "path": "Units/parser-json.r/simple-json.d/input.json",
    "content": "{\n  \"firstName\": \"John\",\n  \"lastName\": \"Smith\",\n  \"isAlive\": true,\n  \"age\": 25,\n  \"height_cm\": 167.6,\n  \"address\": {\n    \"streetAddress\": \"21 2nd Street\",\n    \"city\": \"New York\",\n    \"state\": \"NY\",\n    \"postalCode\": \"10021-3100\"\n  },\n  \"phoneNumbers\": [\n    {\n      \"type\": \"home\",\n      \"number\": \"212 555-1234\"\n    },\n    {\n      \"type\": \"office\",\n      \"number\": \"646 555-4567\"\n    }\n  ],\n  \"children\": [],\n  \"spouse\": null\n}\n"
  },
  {
    "path": "Units/parser-json.r/simple-json.d/validator",
    "content": "jq\n"
  },
  {
    "path": "Units/parser-julia.r/corner_cases.d/expected.tags",
    "content": "Foo\tinput.jl\t/^abstract type Foo <: Bar end$/;\"\tt\nFoo\tinput.jl\t/^mutable struct Foo$/;\"\ts\nFoo\tinput.jl\t/^struct Foo$/;\"\ts\nMod1\tinput.jl\t/^baremodule Mod1$/;\"\tn\nMod2\tinput.jl\t/^module Mod2$/;\"\tn\nPoint\tinput.jl\t/^struct Point{T} <: Pointy{T}$/;\"\ts\nPointy\tinput.jl\t/^abstract type Pointy{T} end$/;\"\tt\nbar\tinput.jl\t/^function Foo.bar(x, y)$/;\"\tf\tmodule:Foo\ncell\tinput.jl\t/^cell(dims::(Integer...)) = Array(Any, convert((Int...), dims))$/;\"\tf\nelsize\tinput.jl\t/^elsize(::AbstractArray{T}) where {T} = sizeof(T)$/;\"\tf\nelsize\tinput.jl\t/^function elsize(::AbstractArray{T}) where T$/;\"\tf\nf\tinput.jl\t/^f(x::FooBar) = x$/;\"\tf\nfoo\tinput.jl\t/^Baz.foo(x) = 1$/;\"\tf\tmodule:Baz\nfoo\tinput.jl\t/^foo(x::(Int,)) = 1$/;\"\tf\nfoo\tinput.jl\t/^function foo()$/;\"\tf\nfoo_bar!\tinput.jl\t/^foo_bar!(x,y) = x + y$/;\"\tf\nfoo_bar!\tinput.jl\t/^function foo_bar!(x,y)$/;\"\tf\ng\tinput.jl\t/^function g(x, y)::Int8$/;\"\tf\nmyfun\tinput.jl\t/^@inline myfun() = println(\"myfun\")$/;\"\tf\nnorm\tinput.jl\t/^function norm(p::Point{<:Real})$/;\"\tf\nsame_type_numeric\tinput.jl\t/^same_type_numeric(x::T, y::T) where T = false$/;\"\tf\nsame_type_numeric\tinput.jl\t/^same_type_numeric(x::T, y::T) where {T <: Number} = true$/;\"\tf\ntest\tinput.jl\t/^function test(x)$/;\"\tf\nx\tinput.jl\t/^    x::Bar$/;\"\tg\tstruct:Foo\nx\tinput.jl\t/^    x::T$/;\"\tg\tstruct:Point\ny\tinput.jl\t/^    y::T$/;\"\tg\tstruct:Point\ny\tinput.jl\t/^const y = \"hello world\"$/;\"\tc\n"
  },
  {
    "path": "Units/parser-julia.r/corner_cases.d/input.jl",
    "content": "#= Julia syntax highlighting test.\r\n\r\nModified from https://github.com/JuliaEditorSupport/julia-syntax-test-cases\r\n\r\nThis file derives from https://gist.github.com/Wilfred/f1aca44c61ed6e1df603\r\nwhose author is [@Wilfred](https://github.com/Wilfred). @Wilfred has put it in\r\nthe public domain:\r\n  https://gist.github.com/Wilfred/f1aca44c61ed6e1df603#gistcomment-2948526\r\n\r\nChanges from the original are governed by the license of the repository in\r\nwhich this file is found.\r\n\r\nThis file is designed to test various corner cases of Julia\r\nsyntax highlighting.\r\n=#\r\n\r\nbaremodule Mod1\r\n    # Nothing here\r\nend\r\n\r\nmodule Mod2\r\n    # Here neither\r\nend\r\n\r\n## Simple function definitions.\r\n# Expected: `function` should be highlighted, as should `foo_bar!`.\r\nfunction foo_bar!(x,y)\r\n    x + y + 1\r\nend\r\n\r\n# Expected: `foo_bar!` should be highlighted.\r\nfoo_bar!(x,y) = x + y\r\n\r\n# Expected: `foo` should be highlighted.\r\nBaz.foo(x) = 1\r\n\r\n# Expected: `foo` should be highlighted.\r\nfoo(x::(Int,)) = 1\r\n\r\n# Expected: `foo` should be highlighted.\r\nfoo(x, y=length(x))\r\n\r\n## Function definitions in namespaces.\r\n# Expected: `bar` should be highlighted.\r\nfunction Foo.bar(x, y)\r\n    x + 1\r\nend\r\n\r\n## Function definitions with type variables.\r\n# Expected: `elsize` should be highlighted.\r\nelsize(::AbstractArray{T}) where {T} = sizeof(T)\r\n\r\nfunction elsize(::AbstractArray{T}) where T\r\n    sizeof(T)\r\nend\r\n\r\n## Nested brackets in function definitions.\r\n# Expected: `cell` should be highlighted.\r\ncell(dims::(Integer...)) = Array(Any, convert((Int...), dims))\r\n\r\n# TODO: find an example with a nested type expression.\r\n\r\n## Macro usage\r\n# Expected: `@hello_world!` should be highlighted.\r\n@hello_world! foo\r\n\r\n# Expected: highlight `myfun`\r\n@inline myfun() = println(\"myfun\")\r\n\r\n## Builtin functions.\r\n# Expected: `throw`, `error` and `super` should not be highlighted. There are\r\n# too many built-in functions for this to be useful.\r\n# https://github.com/JuliaLang/julia/commit/134867c69096fcb52afa5d5a7433892b5127e981\r\n# https://github.com/JuliaLang/julia/pull/7963#issuecomment-52586261\r\nthrow(foo)\r\nerror(\"foo\", bar, \"baz\")\r\nsuper(Int)\r\n\r\n## Strings\r\n# Expected: highlight the string.\r\nx = \"foo \\\"bar\\\" baz\"\r\n\r\n# Expected: highlight the whole string.\r\nx = \"foo\r\nbar\"\r\n\r\n# Expected: highlight the whole triple-quoted string.\r\nx = \"\"\"hello \"world\" foobar\"\"\"\r\ny = \"\"\"foo\\\\\"\"\"\r\nz = \"\"\"bar\\\"\"\"\"\r\nw = \"\"\"\"bar\"\"\"\r\n\r\n# Expected: highlight `$user`\r\nx = \"hello $user\"\r\n\r\n# Expected: don't highlight `$user`\r\nx = \"hello \\$user\"\r\n\r\n# Expected: highlight `$val`\r\nx = \"\"\"(a=\"$val\")\"\"\"\r\n\r\n# Expected: treat r as part of the string, so `r\"a\"` is highlighted.\r\nx = r\"0.1\"\r\n\r\n# Expected: treat ismx as part of the string, so `r\"a\"ismx` is highlighted.\r\nx = r\"a\"ismx\r\n\r\n# Expected: highlight `r\"\"\"a \"b\" c\"\"\"`\r\nx = r\"\"\"a \"b\" c\"\"\"\r\n\r\n# Expected: treat v as part of the string, so `v\"0.1\"` is highlighted.\r\nx = v\"0.1\"\r\n\r\n# Expected: treat b as part of the string, so `b\"a\"` is highlighted.\r\nx = b\"a\"\r\n\r\n# Bonus points:\r\n# Expected: highlight the interpolation brackets `$(` and `)`\r\nx = \"hello $(user * user)\"\r\n\r\n# Bonus points:\r\n# Expected: highlight regexp metacharacters `[` and `]`\r\nx = r\"[abc]\"\r\n\r\n# Bonus points:\r\n# Expected: highlight escape sequences `\\xff` and `\\u2200`\r\nx = b\"DATA\\xff\\u2200\"\r\n\r\n# Bonus points:\r\n# Expected: don't highlight `$user`\r\nx = raw\"hello $user\"\r\n\r\n## Characters\r\n# Expected: highlight the character.\r\nx = 'a'\r\ny = '\\u0'\r\nz = '\\U10ffff'\r\nw = '\\x41'\r\na = ' '\r\nb = '\"'\r\nc = '''\r\nd = '\\''\r\ne = '\\\\'\r\n\r\n# Expected: don't highlight, as ' is an operator here, not a character delimiter.\r\na = b' + c'\r\nA'''\r\n\r\n# Bonus points:\r\n# Expected: don't highlight the character\r\nx = 'way too long so not a character'\r\nx = ''\r\n\r\n## Comments\r\n# Expected: highlight `# foo`\r\n# foo\r\n\r\n# Expected: highlight `#= foo\\n bar =#`\r\n#= foo\r\nbar =#\r\n\r\n# Expected: highlight `#= #= =# =#` (comments can nest).\r\n#= #= =# =#\r\n\r\n# Expected: highlight `'` as adjoint operator\r\nA#==#'\r\n(A)#==#'\r\nA[1]#==#'\r\n\r\n## Type declarations\r\n\r\n# Expected highlight `Foo` and `Bar`\r\nmutable struct Foo\r\n    x::Bar\r\nend\r\n\r\n# Expected highlight `Foo` and `Bar`\r\nstruct Foo\r\n    x::Bar\r\nend\r\n\r\n# Expected: highlight `Foo` and `Bar`\r\nabstract type Foo <: Bar end\r\n\r\n# Expected: don't highlight x or y\r\nx <: y\r\n\r\n## Type annotations\r\n\r\n# Expected: highlight `FooBar`\r\nf(x::FooBar) = x\r\n\r\n# Expected: highlight `Int8`\r\nfunction foo()\r\n    local x::Int8 = 5\r\n    x\r\nend\r\n\r\n# Expected: highlight `Point` and `Real` as types\r\nfunction norm(p::Point{<:Real})\r\n    sqrt(p.x^2 + p.y^2)\r\nend\r\n\r\n# Expected: highlight `g` as function and `Int8` as type\r\nfunction g(x, y)::Int8\r\n   return x * y\r\nend\r\n       \r\n# Expected: highlight `T` and `Number`\r\nsame_type_numeric(x::T, y::T) where {T <: Number} = true\r\nsame_type_numeric(x::T, y::T) where T = false\r\n\r\n## Parametric type declaration\r\n\r\n# Expected: highlight `Pointy` and `T`\r\nabstract type Pointy{T} end\r\n\r\n# Expected: highlight `Point`, `Pointy` and `T`\r\nstruct Point{T} <: Pointy{T}\r\n    x::T\r\n    y::T\r\nend\r\n\r\n## Variable declarations\r\n\r\n# Expected: highlight `x` and `y`\r\nglobal x = \"foo, bar = 2\", y = 3\r\n\r\n# Expected: highlight `x` and `y`\r\nglobal x = foo(a, b), y = 3\r\n\r\n# Expected: highlight `y`\r\nconst y = \"hello world\"\r\n\r\n# Expected: highlight `x` and `y`\r\nfunction foo()\r\n    local x = f(1, 2), y = f(3, 4)\r\n    x + y\r\nend\r\n\r\n# Expected: highlight `x` and `y`\r\nlet x = f(1, 2), y = f(3, 4)\r\n    x + y\r\nend\r\n\r\n## Colons and end\r\n\r\n# Expected: highlight `:foo`, `:end` and `:function`\r\n:foo\r\nx = :foo\r\ny = :function\r\nz = :end\r\n\r\n# Expected: highlight index `[end]` differently to block delimiter `end`\r\nif foo[end]\r\nend\r\n\r\n# Expected: highlight as index `end`\r\nfoo[bar:end]\r\n\r\n# Expected: highlight as index `begin`\r\nfoo[begin:4]\r\n\r\n# Expected: don't highlight `:123`\r\nx = :123\r\n\r\n# Expected: don't highlight `:baz`\r\nfoo[bar:baz]\r\n\r\n# Expected: highlight `:baz`\r\nfoo[:baz]\r\n\r\n# Expected: highlight both `:baz`\r\nfoo(:baz,:baz)\r\n\r\n# Note that `: foo` is currently a valid quoted symbol, this will hopefully\r\n# change in 0.4: https://github.com/JuliaLang/julia/issues/5997\r\n\r\n# Expected: highlight `:foo`\r\n[1 :foo]\r\n\r\n# Expected: highlight `:end`\r\n[1 :end]\r\n\r\n# Expected: highlight `:two`\r\n@eval :one+:two\r\n\r\n# Expected: don't highlight `:end` but `end` as index\r\n[(1+1):end]\r\n\r\n# Expected: don't highlight `:end` but `end` as index\r\n[a[1]:end]\r\n\r\n# Expected: don't highlight `:foo`\r\nfor x=1:foo\r\n    print(x)\r\nend\r\n\r\n## Range detection\r\n\r\n# Bonus points:\r\n# Expected: don't highlight `:s2`\r\npush!(a, s1 :s2)\r\n\r\n# Bonus points:\r\n# Expected: don't highlight `:end`\r\na[begin :end]\r\n\r\n## Expression evaluation\r\n\r\n# Expected: highlight `:` as operator\r\na = :(x = 2)\r\n\r\n# Expected: highlight `:call` and `:b` as symbols\r\n# Debatable: highlight `:+` as operator\r\nex = Expr(:call, :+, a, :b)\r\n\r\n## Number highlighting\r\n\r\n# Expected: highlight all these as numbers\r\nx = 123\r\nx = 1.1\r\nx = .5\r\nx = 0x123abcdef\r\nx = 0o7\r\nx = 0b1011\r\nx = 2.5e-4\r\nx = 2.5E-4\r\nx = 1e+00\r\nx = 2.5f-4\r\nx = 0x.4p-1\r\nx = 1_000\r\n\r\n# Expected: highlight these as numbers or built-ins\r\nx = Inf\r\nx = NaN\r\n\r\n# Expected: highlight `123`, not the letter\r\ny = 123x\r\ny = 123e\r\n\r\n# Expected: highlight `1e+1` and `1e-1`\r\n1e+1+1e-1\r\n\r\n# Expected: highlight `1.` and `.1`\r\n1. +.1\r\n# Note that `1.+1` is currently ambiguous and gives an error\r\n\r\n# Bonus points:\r\n# Expected: don't highlight `..`\r\nx = 1..3\r\n\r\n# Bonus points:\r\n# Debatable: highlight the first two digits, not the following digits\r\n# or show an error\r\nx = 0o1291\r\nx = 0b1091\r\n\r\n# Debatable: highlight `π` as a number or built-in\r\n# (note that `πx` is a single symbol, not `π * x`)\r\nx = π\r\n\r\n## List comprehension\r\n# Expected: highlight `for` and `if` without the `end` keyword\r\n[i for i in 1:5 if i%2==0]\r\n\r\n## Broadcasting\r\n# Expected: highlight `.+` as operator\r\na.+1\r\n\r\n## Command\r\n# Expected: highlight \"`echo 1`\"\r\nc = `echo 1`\r\n\r\n# Expected: highlight \"```echo `hello 1` ```\"\r\nc = ```echo `hello 1` ```\r\n\r\n# Expected: highlight \"raw`echo $1`\"\r\nc = raw`echo $1`\r\n\r\n## Non-standard identifiers\r\n# Bonus points:\r\n# Expected: highlight `var\"##\"` as a function\r\nfunction var\"##\"(x)\r\n    println(x)\r\nend\r\n\r\n# Bonus points:\r\n# Expected: highlight `var\"%%\"` as a function\r\nvar\"%%\"(x) = println(x)\r\n\r\n# Bonus points:\r\n# Expected: highlight `$var` as string and `##\"\"` as comment\r\n\"$var\"##\"\"\r\n\r\n# Bonus points:\r\n# Expected: highlight `$(var\")(\")` as string interpolation\r\n\"$(var\")(\")\"\r\n\r\n# Bonus points:\r\n# Expected: highlight `'` as adjoint operator\r\nvar\"##mat\"'\r\n\r\n## Code folding: for and if in list comprehension\r\n# Expected: fold between function and last end\r\nfunction test(x)\r\n    a = (if x; 0 else 1 end)\r\n    println(a)\r\nend\r\n"
  },
  {
    "path": "Units/parser-julia.r/empty_line.d/expected.tags",
    "content": "a\tinput.jl\t/^struct a end$/;\"\ts\n"
  },
  {
    "path": "Units/parser-julia.r/empty_line.d/input.jl",
    "content": "\r\nstruct a end\r\n"
  },
  {
    "path": "Units/parser-julia.r/function_scope.d/args.ctags",
    "content": "--fields=+Zs\n--sort=no\n"
  },
  {
    "path": "Units/parser-julia.r/function_scope.d/expected.tags",
    "content": "func1\tinput.jl\t/^function func1(a::Int)$/;\"\tf\nfunc2\tinput.jl\t/^function SomeModule.func2(a::Int)$/;\"\tf\tscope:module:SomeModule\nMyModule\tinput.jl\t/^module MyModule$/;\"\tn\nfunc3\tinput.jl\t/^function func3(a::Int)$/;\"\tf\tscope:module:MyModule\nfunc4\tinput.jl\t/^function func4(a::Int)$/;\"\tf\tscope:module:MyModule\nfunc5\tinput.jl\t/^    function func5(b::Int)$/;\"\tf\tscope:function:MyModule.func4\n"
  },
  {
    "path": "Units/parser-julia.r/function_scope.d/input.jl",
    "content": "function func1(a::Int)\n    a\nend\n\nfunction SomeModule.func2(a::Int)\n    a\nend\n\nmodule MyModule\nfunction func3(a::Int)\n    a\nend\n\nfunction func4(a::Int)\n    function func5(b::Int)\n        b\n    end\n    func5(a)\nend\n\nend\n"
  },
  {
    "path": "Units/parser-julia.r/import_module.d/args.ctags",
    "content": "--fields=Ks{kind}{roles}{scope}\n--extras=+{reference}\n--sort=no\n"
  },
  {
    "path": "Units/parser-julia.r/import_module.d/expected.tags",
    "content": "Module1\tinput.jl\t/^using Module1$/;\"\tkind:module\troles:used\nModule2\tinput.jl\t/^using Module2: func1, func2$/;\"\tkind:module\troles:namespace\nfunc1\tinput.jl\t/^using Module2: func1, func2$/;\"\tkind:unknown\tscope:module:Module2\troles:used\nfunc2\tinput.jl\t/^using Module2: func1, func2$/;\"\tkind:unknown\tscope:module:Module2\troles:used\nModule3\tinput.jl\t/^import Module3$/;\"\tkind:module\troles:imported\nModule4\tinput.jl\t/^import Module4.func1, Module5, Module6.func2$/;\"\tkind:module\troles:namespace\nfunc1\tinput.jl\t/^import Module4.func1, Module5, Module6.func2$/;\"\tkind:unknown\tscope:module:Module4\troles:imported\nModule5\tinput.jl\t/^import Module4.func1, Module5, Module6.func2$/;\"\tkind:module\troles:imported\nModule6\tinput.jl\t/^import Module4.func1, Module5, Module6.func2$/;\"\tkind:module\troles:namespace\nfunc2\tinput.jl\t/^import Module4.func1, Module5, Module6.func2$/;\"\tkind:unknown\tscope:module:Module6\troles:imported\nModule7\tinput.jl\t/^import Module7: func1, func2$/;\"\tkind:module\troles:namespace\nfunc1\tinput.jl\t/^import Module7: func1, func2$/;\"\tkind:unknown\tscope:module:Module7\troles:imported\nfunc2\tinput.jl\t/^import Module7: func1, func2$/;\"\tkind:unknown\tscope:module:Module7\troles:imported\nMyModule\tinput.jl\t/^module MyModule$/;\"\tkind:module\troles:def\nModule8\tinput.jl\t/^using Module8,$/;\"\tkind:module\tscope:module:MyModule\troles:used\nModule9\tinput.jl\t/^      Module9,$/;\"\tkind:module\tscope:module:MyModule\troles:used\nModule10\tinput.jl\t/^      Module10$/;\"\tkind:module\tscope:module:MyModule\troles:used\nModule11\tinput.jl\t/^using Module11: func1,$/;\"\tkind:module\tscope:module:MyModule\troles:namespace\nfunc1\tinput.jl\t/^using Module11: func1,$/;\"\tkind:unknown\tscope:module:Module11\troles:used\nfunc2\tinput.jl\t/^                func2,$/;\"\tkind:unknown\tscope:module:Module11\troles:used\nfunc3\tinput.jl\t/^                func3$/;\"\tkind:unknown\tscope:module:Module11\troles:used\n"
  },
  {
    "path": "Units/parser-julia.r/import_module.d/input.jl",
    "content": "using Module1\nusing Module2: func1, func2\nimport Module3\nimport Module4.func1, Module5, Module6.func2\nimport Module7: func1, func2\n\nmodule MyModule\nusing Module8,\n      Module9,\n      Module10\n\nusing Module11: func1,\n                func2,\n                func3\nend\n"
  },
  {
    "path": "Units/parser-julia.r/infinite_loop.d/expected.tags",
    "content": "X\tinput.jl\t/^struct X$/;\"\ts\n"
  },
  {
    "path": "Units/parser-julia.r/infinite_loop.d/input.jl",
    "content": "struct X\n    X\nend\n"
  },
  {
    "path": "Units/parser-julia.r/julia_test.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-julia.r/julia_test.d/expected.tags",
    "content": "a\tinput.jl\t/^const a::Int = 'c'  # struct Struct_wrong3 end$/;\"\tc\ntest_macro\tinput.jl\t/^macro test_macro() end$/;\"\tm\ntest_fun\tinput.jl\t/^function test_fun(a::Int, b::T) where #$/;\"\tf\nifelse\tinput.jl\t/^function Base.ifelse(a::Int)$/;\"\tf\tmodule:Base\nlone_function\tinput.jl\t/^function lone_function end$/;\"\tf\nrun_test\tinput.jl\t/^function run_test(a::T) where T<:Int; a::Int end$/;\"\tf\neq\tinput.jl\t/^eq(c=4; b=(1,2,3), c=:a=>5) = a == b$/;\"\tf\neq\tinput.jl\t/^eq(a::T, b::T, c=4; b=(1,2,3), c=:a=>5)::T where T<:Real = (a == b; a)$/;\"\tf\nATest\tinput.jl\t/^abstract type ATest end$/;\"\tt\nSTest\tinput.jl\t/^mutable struct STest <: ATest; a::Int end$/;\"\ts\na\tinput.jl\t/^mutable struct STest <: ATest; a::Int end$/;\"\tg\tstruct:STest\nTest1\tinput.jl\t/^struct Test1 <: ATest$/;\"\ts\na\tinput.jl\t/^    a::Int$/;\"\tg\tstruct:Test1\nα\tinput.jl\t/^    α::Real$/;\"\tg\tstruct:Test1\nTest1\tinput.jl\t/^    Test1() = new(0)$/;\"\tf\tstruct:Test1\nTest1\tinput.jl\t/^    Test1(a) = new(1)$/;\"\tf\tstruct:Test1\nTest1\tinput.jl\t/^    Test1(a, b) = begin new(2) end$/;\"\tf\tstruct:Test1\n"
  },
  {
    "path": "Units/parser-julia.r/julia_test.d/input.jl",
    "content": "using Revise\r\nimport Distributions: Normal\r\nusing Random.randn\r\n\r\nusing Plots, Makie\r\n\r\n\r\nconst a::Int = 'c'  # struct Struct_wrong3 end\r\n\r\nmacro test_macro() end\r\n\r\n\"\"\"\r\n    test_fun(a::Int)\r\nFor test only\r\n\"\"\"\r\nfunction test_fun(a::Int, b::T) where #\r\n        T <:Array{S} where S <: Number\r\n    println(a)\r\n    println(\"foo\")\r\nend\r\n\r\n\r\nfunction Base.ifelse(a::Int)\r\n    println(\"bar\")\r\nend\r\nfunction lone_function end\r\n\r\nfunction run_test(a::T) where T<:Int; a::Int end\r\n\r\neq(c=4; b=(1,2,3), c=:a=>5) = a == b\r\neq(a::T, b::T, c=4; b=(1,2,3), c=:a=>5)::T where T<:Real = (a == b; a)\r\n\r\n#=\r\n  Structs\r\n=#\r\nabstract type ATest end\r\n\r\nmutable struct STest <: ATest; a::Int end\r\n\r\n\r\nstruct Test1 <: ATest\r\n    a::Int\r\n    α::Real\r\n\r\n    Test1() = new(0)\r\n    Test1(a) = new(1)\r\n    Test1(a, b) = begin new(2) end\r\nend\r\n"
  },
  {
    "path": "Units/parser-julia.r/parametric_constructor.d/expected.tags",
    "content": "OurRational\tinput.jl\t/^struct OurRational{T<:Integer} <: Real$/;\"\ts\nOurRational{Int16}\tinput.jl\t/^OurRational{Int16}(num::T, den::T) where T<:Integer = new(num, den)$/;\"\tf\nOurRational{Int64}\tinput.jl\t/^    OurRational{Int64}(num::T, den::T, test::T) where T<:Integer = new(num, den, test)$/;\"\tf\tstruct:OurRational\nOurRational{Int8}\tinput.jl\t/^    OurRational{Int8}(num::T, den::T) where T<:Integer = new(convert(Int8, num), convert(Int8, d/;\"\tf\tstruct:OurRational\nOurRational{T}\tinput.jl\t/^    function OurRational{T}(num::T, den::T) where T<:Integer$/;\"\tf\tstruct:OurRational\nden\tinput.jl\t/^    den::T$/;\"\tg\tstruct:OurRational\nnum\tinput.jl\t/^    num::T$/;\"\tg\tstruct:OurRational\ntest\tinput.jl\t/^    test::T$/;\"\tg\tstruct:OurRational\n"
  },
  {
    "path": "Units/parser-julia.r/parametric_constructor.d/input.jl",
    "content": "struct OurRational{T<:Integer} <: Real\n    \"Numerator\"\n    num::T\n\n    \"Denominator\"\n    den::T\n\n    OurRational{Int8}(num::T, den::T) where T<:Integer = new(convert(Int8, num), convert(Int8, den))\n\n    \"\"\"\n    Parametric inner constructor\n    \"\"\"\n    function OurRational{T}(num::T, den::T) where T<:Integer\n        if num == 0 && den == 0\n            error(\"invalid rational: 0//0\")\n        end\n        # Bug with short function misidentification of == and =>\n        length(num) == 0\n        length(den) => 0\n        \n        g = gcd(den, num)\n        num = div(num, g)\n        den = div(den, g)\n        new(num, den)\n    end\n\n    test::T\n\n    OurRational{Int64}(num::T, den::T, test::T) where T<:Integer = new(num, den, test)\nend\n\nOurRational{Int16}(num::T, den::T) where T<:Integer = new(num, den)\n"
  },
  {
    "path": "Units/parser-julia.r/scoped_macro.d/args.ctags",
    "content": "--fields=+Zs\n--sort=no\n"
  },
  {
    "path": "Units/parser-julia.r/scoped_macro.d/expected.tags",
    "content": "fun1\tinput.jl\t/^@eval fun1(x) = $a$/;\"\tf\nfun2\tinput.jl\t/^Base.@eval fun2(x) = $a$/;\"\tf\nfun3\tinput.jl\t/^@eval function fun3(x)$/;\"\tf\nfun4\tinput.jl\t/^Base.@eval function fun4(x)$/;\"\tf\nTest1\tinput.jl\t/^@eval struct Test1$/;\"\ts\na\tinput.jl\t/^    a::$T$/;\"\tg\tscope:struct:Test1\nTest2\tinput.jl\t/^Base.@eval struct Test2$/;\"\ts\na\tinput.jl\t/^    a::$T$/;\"\tg\tscope:struct:Test2\nmacro1\tinput.jl\t/^@eval macro macro1(x)$/;\"\tm\nmacro2\tinput.jl\t/^Base.@eval macro macro2(x)$/;\"\tm\n"
  },
  {
    "path": "Units/parser-julia.r/scoped_macro.d/input.jl",
    "content": "@eval fun1(x) = $a\r\nBase.@eval fun2(x) = $a\r\n\r\n@eval function fun3(x)\r\n    $a\r\nend\r\nBase.@eval function fun4(x)\r\n    $a\r\nend\r\n\r\n@eval struct Test1\r\n    a::$T\r\nend\r\nBase.@eval struct Test2\r\n    a::$T\r\nend\r\n\r\n@eval macro macro1(x)\r\n    $a\r\nend\r\nBase.@eval macro macro2(x)\r\n    $a\r\nend\r\n"
  },
  {
    "path": "Units/parser-julia.r/struct_attributes.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-julia.r/struct_attributes.d/expected.tags",
    "content": "Test\tinput.jl\t/^Base.@kwdef struct Test$/;\"\ts\na\tinput.jl\t/^    a::Float64 = 1E12$/;\"\tg\tstruct:Test\nb\tinput.jl\t/^    b::Float64 = pi$/;\"\tg\tstruct:Test\n"
  },
  {
    "path": "Units/parser-julia.r/struct_attributes.d/input.jl",
    "content": "Base.@kwdef struct Test\r\n    a::Float64 = 1E12\r\n    b::Float64 = pi\r\nend\r\n"
  },
  {
    "path": "Units/parser-kconfig.r/comment-starting-from-middle-of-lines.d/args.ctags",
    "content": "--sort=no\n--map-Kconfig=.kconfig\n--extras-Kconfig=-{configPrefixed}\n--fields=+e\n--extras=+r\n"
  },
  {
    "path": "Units/parser-kconfig.r/comment-starting-from-middle-of-lines.d/expected.tags",
    "content": "A\tinput.kconfig\t/^config A # ...$/;\"\tc\ttyperef:typename:bool\tend:3\nB\tinput.kconfig\t/^\tprompt \"B\"$/;\"\tC\tend:10\nC\tinput.kconfig\t/^config C # ...$/;\"\tc\tchoice:B\ttyperef:typename:bool\tend:9\nD\tinput.kconfig\t/^menu \"D\" # ...$/;\"\tm\tend:17\nE\tinput.kconfig\t/^config E # ...$/;\"\tc\tmenu:D\ttyperef:typename:bool\tend:16\nF\tinput.kconfig\t/^menuconfig F # ...$/;\"\tc\tend:19\n"
  },
  {
    "path": "Units/parser-kconfig.r/comment-starting-from-middle-of-lines.d/input.kconfig",
    "content": "config A # ...\n        bool\n\nchoice # ...\n\tprompt \"B\"\n\nconfig C # ...\n       bool\n\nendchoice # ...\n\nmenu \"D\" # ...\n\nconfig E # ...\n       bool\n\nendmenu # ...\n\nmenuconfig F # ...\n"
  },
  {
    "path": "Units/parser-kconfig.r/macros.d/args.ctags",
    "content": "--sort=no\n--map-Kconfig=.kconfig\n"
  },
  {
    "path": "Units/parser-kconfig.r/macros.d/expected.tags",
    "content": "CC\tinput.kconfig\t/^CC := gcc$/;\"\tv\nCC_HAS_FOO\tinput.kconfig\t/^config CC_HAS_FOO$/;\"\tc\ttyperef:typename:bool\nCONFIG_CC_HAS_FOO\tinput.kconfig\t/^config CC_HAS_FOO$/;\"\tc\nCONFIG_CC_HAS_FOO_MODULE\tinput.kconfig\t/^config CC_HAS_FOO$/;\"\tc\nstringify\tinput.kconfig\t/^stringify = $(squote)$(quote)$1$(quote)$(squote)$/;\"\tv\n"
  },
  {
    "path": "Units/parser-kconfig.r/macros.d/input.kconfig",
    "content": "# Taken from https://www.kernel.org/doc/html/latest/kbuild/kconfig-macro-language.html\nCC := gcc\n\nconfig CC_HAS_FOO\n        def_bool $(shell, $(srctree)/scripts/gcc-check-foo.sh $(CC))\n\n# Taken from linux/scripts/Kbuild.include\n###\n# Quote a string to pass it to C files. foo => '\"foo\"'\nstringify = $(squote)$(quote)$1$(quote)$(squote)\n"
  },
  {
    "path": "Units/parser-kconfig.r/simple-kconfig.d/args.ctags",
    "content": "--map-Kconfig=.kconfig\n--extras=+r\n--fields=+r\n--sort=no\n"
  },
  {
    "path": "Units/parser-kconfig.r/simple-kconfig.d/expected.tags",
    "content": "Linux/$(ARCH) $(KERNELVERSION) Kernel Configuration\tinput.kconfig\t/^mainmenu \"Linux\\/$(ARCH) $(KERNELVERSION) Kernel Configuration\"$/;\"\tM\troles:def\nscripts/Kconfig.include\tinput.kconfig\t/^source \"scripts\\/Kconfig.include\"$/;\"\tk\troles:source\ninit/Kconfig\tinput.kconfig\t/^source \"init\\/Kconfig\"$/;\"\tk\troles:source\nkernel/Kconfig.freezer\tinput.kconfig\t/^source \"kernel\\/Kconfig.freezer\"$/;\"\tk\troles:source\nfs/Kconfig.binfmt\tinput.kconfig\t/^source \"fs\\/Kconfig.binfmt\"$/;\"\tk\troles:source\nmm/Kconfig\tinput.kconfig\t/^source \"mm\\/Kconfig\"$/;\"\tk\troles:source\nnet/Kconfig\tinput.kconfig\t/^source \"net\\/Kconfig\"$/;\"\tk\troles:source\ndrivers/Kconfig\tinput.kconfig\t/^source \"drivers\\/Kconfig\"$/;\"\tk\troles:source\nfs/Kconfig\tinput.kconfig\t/^source \"fs\\/Kconfig\"$/;\"\tk\troles:source\nsecurity/Kconfig\tinput.kconfig\t/^source \"security\\/Kconfig\"$/;\"\tk\troles:source\ncrypto/Kconfig\tinput.kconfig\t/^source \"crypto\\/Kconfig\"$/;\"\tk\troles:source\nlib/Kconfig\tinput.kconfig\t/^source \"lib\\/Kconfig\"$/;\"\tk\troles:source\nlib/Kconfig.debug\tinput.kconfig\t/^source \"lib\\/Kconfig.debug\"$/;\"\tk\troles:source\nDocumentation/Kconfig\tinput.kconfig\t/^source \"Documentation\\/Kconfig\"$/;\"\tk\troles:source\nJFFS2_FS\tinput-1.kconfig\t/^config JFFS2_FS$/;\"\tc\ttyperef:typename:tristate\troles:def\nCONFIG_JFFS2_FS\tinput-1.kconfig\t/^config JFFS2_FS$/;\"\tc\troles:def\nCONFIG_JFFS2_FS_MODULE\tinput-1.kconfig\t/^config JFFS2_FS$/;\"\tc\troles:def\nJFFS2_FS_DEBUG\tinput-1.kconfig\t/^config JFFS2_FS_DEBUG$/;\"\tc\ttyperef:typename:int\troles:def\nCONFIG_JFFS2_FS_DEBUG\tinput-1.kconfig\t/^config JFFS2_FS_DEBUG$/;\"\tc\troles:def\nCONFIG_JFFS2_FS_DEBUG_MODULE\tinput-1.kconfig\t/^config JFFS2_FS_DEBUG$/;\"\tc\troles:def\nJFFS2_FS_WRITEBUFFER\tinput-1.kconfig\t/^config JFFS2_FS_WRITEBUFFER$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_FS_WRITEBUFFER\tinput-1.kconfig\t/^config JFFS2_FS_WRITEBUFFER$/;\"\tc\troles:def\nCONFIG_JFFS2_FS_WRITEBUFFER_MODULE\tinput-1.kconfig\t/^config JFFS2_FS_WRITEBUFFER$/;\"\tc\troles:def\nJFFS2_FS_WBUF_VERIFY\tinput-1.kconfig\t/^config JFFS2_FS_WBUF_VERIFY$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_FS_WBUF_VERIFY\tinput-1.kconfig\t/^config JFFS2_FS_WBUF_VERIFY$/;\"\tc\troles:def\nCONFIG_JFFS2_FS_WBUF_VERIFY_MODULE\tinput-1.kconfig\t/^config JFFS2_FS_WBUF_VERIFY$/;\"\tc\troles:def\nJFFS2_SUMMARY\tinput-1.kconfig\t/^config JFFS2_SUMMARY$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_SUMMARY\tinput-1.kconfig\t/^config JFFS2_SUMMARY$/;\"\tc\troles:def\nCONFIG_JFFS2_SUMMARY_MODULE\tinput-1.kconfig\t/^config JFFS2_SUMMARY$/;\"\tc\troles:def\nJFFS2_FS_XATTR\tinput-1.kconfig\t/^config JFFS2_FS_XATTR$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_FS_XATTR\tinput-1.kconfig\t/^config JFFS2_FS_XATTR$/;\"\tc\troles:def\nCONFIG_JFFS2_FS_XATTR_MODULE\tinput-1.kconfig\t/^config JFFS2_FS_XATTR$/;\"\tc\troles:def\nJFFS2_FS_POSIX_ACL\tinput-1.kconfig\t/^config JFFS2_FS_POSIX_ACL$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_FS_POSIX_ACL\tinput-1.kconfig\t/^config JFFS2_FS_POSIX_ACL$/;\"\tc\troles:def\nCONFIG_JFFS2_FS_POSIX_ACL_MODULE\tinput-1.kconfig\t/^config JFFS2_FS_POSIX_ACL$/;\"\tc\troles:def\nJFFS2_FS_SECURITY\tinput-1.kconfig\t/^config JFFS2_FS_SECURITY$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_FS_SECURITY\tinput-1.kconfig\t/^config JFFS2_FS_SECURITY$/;\"\tc\troles:def\nCONFIG_JFFS2_FS_SECURITY_MODULE\tinput-1.kconfig\t/^config JFFS2_FS_SECURITY$/;\"\tc\troles:def\nJFFS2_COMPRESSION_OPTIONS\tinput-1.kconfig\t/^config JFFS2_COMPRESSION_OPTIONS$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_COMPRESSION_OPTIONS\tinput-1.kconfig\t/^config JFFS2_COMPRESSION_OPTIONS$/;\"\tc\troles:def\nCONFIG_JFFS2_COMPRESSION_OPTIONS_MODULE\tinput-1.kconfig\t/^config JFFS2_COMPRESSION_OPTIONS$/;\"\tc\troles:def\nJFFS2_ZLIB\tinput-1.kconfig\t/^config JFFS2_ZLIB$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_ZLIB\tinput-1.kconfig\t/^config JFFS2_ZLIB$/;\"\tc\troles:def\nCONFIG_JFFS2_ZLIB_MODULE\tinput-1.kconfig\t/^config JFFS2_ZLIB$/;\"\tc\troles:def\nJFFS2_LZO\tinput-1.kconfig\t/^config JFFS2_LZO$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_LZO\tinput-1.kconfig\t/^config JFFS2_LZO$/;\"\tc\troles:def\nCONFIG_JFFS2_LZO_MODULE\tinput-1.kconfig\t/^config JFFS2_LZO$/;\"\tc\troles:def\nJFFS2_RTIME\tinput-1.kconfig\t/^config JFFS2_RTIME$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_RTIME\tinput-1.kconfig\t/^config JFFS2_RTIME$/;\"\tc\troles:def\nCONFIG_JFFS2_RTIME_MODULE\tinput-1.kconfig\t/^config JFFS2_RTIME$/;\"\tc\troles:def\nJFFS2_RUBIN\tinput-1.kconfig\t/^config JFFS2_RUBIN$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_RUBIN\tinput-1.kconfig\t/^config JFFS2_RUBIN$/;\"\tc\troles:def\nCONFIG_JFFS2_RUBIN_MODULE\tinput-1.kconfig\t/^config JFFS2_RUBIN$/;\"\tc\troles:def\nJFFS2 default compression mode\tinput-1.kconfig\t/^\tprompt \"JFFS2 default compression mode\" if JFFS2_COMPRESSION_OPTIONS$/;\"\tC\troles:def\nJFFS2_CMODE_NONE\tinput-1.kconfig\t/^config JFFS2_CMODE_NONE$/;\"\tc\tchoice:JFFS2 default compression mode\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_CMODE_NONE\tinput-1.kconfig\t/^config JFFS2_CMODE_NONE$/;\"\tc\tchoice:JFFS2 default compression mode\troles:def\nCONFIG_JFFS2_CMODE_NONE_MODULE\tinput-1.kconfig\t/^config JFFS2_CMODE_NONE$/;\"\tc\tchoice:JFFS2 default compression mode\troles:def\nJFFS2_CMODE_PRIORITY\tinput-1.kconfig\t/^config JFFS2_CMODE_PRIORITY$/;\"\tc\tchoice:JFFS2 default compression mode\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_CMODE_PRIORITY\tinput-1.kconfig\t/^config JFFS2_CMODE_PRIORITY$/;\"\tc\tchoice:JFFS2 default compression mode\troles:def\nCONFIG_JFFS2_CMODE_PRIORITY_MODULE\tinput-1.kconfig\t/^config JFFS2_CMODE_PRIORITY$/;\"\tc\tchoice:JFFS2 default compression mode\troles:def\nJFFS2_CMODE_SIZE\tinput-1.kconfig\t/^config JFFS2_CMODE_SIZE$/;\"\tc\tchoice:JFFS2 default compression mode\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_CMODE_SIZE\tinput-1.kconfig\t/^config JFFS2_CMODE_SIZE$/;\"\tc\tchoice:JFFS2 default compression mode\troles:def\nCONFIG_JFFS2_CMODE_SIZE_MODULE\tinput-1.kconfig\t/^config JFFS2_CMODE_SIZE$/;\"\tc\tchoice:JFFS2 default compression mode\troles:def\nJFFS2_CMODE_FAVOURLZO\tinput-1.kconfig\t/^config JFFS2_CMODE_FAVOURLZO$/;\"\tc\tchoice:JFFS2 default compression mode\ttyperef:typename:bool\troles:def\nCONFIG_JFFS2_CMODE_FAVOURLZO\tinput-1.kconfig\t/^config JFFS2_CMODE_FAVOURLZO$/;\"\tc\tchoice:JFFS2 default compression mode\troles:def\nCONFIG_JFFS2_CMODE_FAVOURLZO_MODULE\tinput-1.kconfig\t/^config JFFS2_CMODE_FAVOURLZO$/;\"\tc\tchoice:JFFS2 default compression mode\troles:def\nHAVE_ARCH_KGDB\tinput-2.kconfig\t/^config HAVE_ARCH_KGDB$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_HAVE_ARCH_KGDB\tinput-2.kconfig\t/^config HAVE_ARCH_KGDB$/;\"\tc\troles:def\nCONFIG_HAVE_ARCH_KGDB_MODULE\tinput-2.kconfig\t/^config HAVE_ARCH_KGDB$/;\"\tc\troles:def\nKGDB\tinput-2.kconfig\t/^menuconfig KGDB$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_KGDB\tinput-2.kconfig\t/^menuconfig KGDB$/;\"\tc\troles:def\nCONFIG_KGDB_MODULE\tinput-2.kconfig\t/^menuconfig KGDB$/;\"\tc\troles:def\nKGDB_SERIAL_CONSOLE\tinput-2.kconfig\t/^config KGDB_SERIAL_CONSOLE$/;\"\tc\ttyperef:typename:tristate\troles:def\nCONFIG_KGDB_SERIAL_CONSOLE\tinput-2.kconfig\t/^config KGDB_SERIAL_CONSOLE$/;\"\tc\troles:def\nCONFIG_KGDB_SERIAL_CONSOLE_MODULE\tinput-2.kconfig\t/^config KGDB_SERIAL_CONSOLE$/;\"\tc\troles:def\nKGDB_TESTS\tinput-2.kconfig\t/^config KGDB_TESTS$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_KGDB_TESTS\tinput-2.kconfig\t/^config KGDB_TESTS$/;\"\tc\troles:def\nCONFIG_KGDB_TESTS_MODULE\tinput-2.kconfig\t/^config KGDB_TESTS$/;\"\tc\troles:def\nKGDB_TESTS_ON_BOOT\tinput-2.kconfig\t/^config KGDB_TESTS_ON_BOOT$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_KGDB_TESTS_ON_BOOT\tinput-2.kconfig\t/^config KGDB_TESTS_ON_BOOT$/;\"\tc\troles:def\nCONFIG_KGDB_TESTS_ON_BOOT_MODULE\tinput-2.kconfig\t/^config KGDB_TESTS_ON_BOOT$/;\"\tc\troles:def\nKGDB_TESTS_BOOT_STRING\tinput-2.kconfig\t/^config KGDB_TESTS_BOOT_STRING$/;\"\tc\ttyperef:typename:string\troles:def\nCONFIG_KGDB_TESTS_BOOT_STRING\tinput-2.kconfig\t/^config KGDB_TESTS_BOOT_STRING$/;\"\tc\troles:def\nCONFIG_KGDB_TESTS_BOOT_STRING_MODULE\tinput-2.kconfig\t/^config KGDB_TESTS_BOOT_STRING$/;\"\tc\troles:def\nKGDB_LOW_LEVEL_TRAP\tinput-2.kconfig\t/^config KGDB_LOW_LEVEL_TRAP$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_KGDB_LOW_LEVEL_TRAP\tinput-2.kconfig\t/^config KGDB_LOW_LEVEL_TRAP$/;\"\tc\troles:def\nCONFIG_KGDB_LOW_LEVEL_TRAP_MODULE\tinput-2.kconfig\t/^config KGDB_LOW_LEVEL_TRAP$/;\"\tc\troles:def\nKGDB_KDB\tinput-2.kconfig\t/^config KGDB_KDB$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_KGDB_KDB\tinput-2.kconfig\t/^config KGDB_KDB$/;\"\tc\troles:def\nCONFIG_KGDB_KDB_MODULE\tinput-2.kconfig\t/^config KGDB_KDB$/;\"\tc\troles:def\nKDB_DEFAULT_ENABLE\tinput-2.kconfig\t/^config KDB_DEFAULT_ENABLE$/;\"\tc\ttyperef:typename:hex\troles:def\nCONFIG_KDB_DEFAULT_ENABLE\tinput-2.kconfig\t/^config KDB_DEFAULT_ENABLE$/;\"\tc\troles:def\nCONFIG_KDB_DEFAULT_ENABLE_MODULE\tinput-2.kconfig\t/^config KDB_DEFAULT_ENABLE$/;\"\tc\troles:def\nKDB_KEYBOARD\tinput-2.kconfig\t/^config KDB_KEYBOARD$/;\"\tc\ttyperef:typename:bool\troles:def\nCONFIG_KDB_KEYBOARD\tinput-2.kconfig\t/^config KDB_KEYBOARD$/;\"\tc\troles:def\nCONFIG_KDB_KEYBOARD_MODULE\tinput-2.kconfig\t/^config KDB_KEYBOARD$/;\"\tc\troles:def\nKDB_CONTINUE_CATASTROPHIC\tinput-2.kconfig\t/^config KDB_CONTINUE_CATASTROPHIC$/;\"\tc\ttyperef:typename:int\troles:def\nCONFIG_KDB_CONTINUE_CATASTROPHIC\tinput-2.kconfig\t/^config KDB_CONTINUE_CATASTROPHIC$/;\"\tc\troles:def\nCONFIG_KDB_CONTINUE_CATASTROPHIC_MODULE\tinput-2.kconfig\t/^config KDB_CONTINUE_CATASTROPHIC$/;\"\tc\troles:def\nNetworking options\tinput-3.kconfig\t/^menu \"Networking options\"$/;\"\tm\troles:def\nnet/packet/Kconfig\tinput-3.kconfig\t/^source \"net\\/packet\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/unix/Kconfig\tinput-3.kconfig\t/^source \"net\\/unix\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/tls/Kconfig\tinput-3.kconfig\t/^source \"net\\/tls\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/xfrm/Kconfig\tinput-3.kconfig\t/^source \"net\\/xfrm\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/iucv/Kconfig\tinput-3.kconfig\t/^source \"net\\/iucv\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/smc/Kconfig\tinput-3.kconfig\t/^source \"net\\/smc\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/xdp/Kconfig\tinput-3.kconfig\t/^source \"net\\/xdp\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nINET\tinput-3.kconfig\t/^config INET$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_INET\tinput-3.kconfig\t/^config INET$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_INET_MODULE\tinput-3.kconfig\t/^config INET$/;\"\tc\tmenu:Networking options\troles:def\nnet/ipv4/Kconfig\tinput-3.kconfig\t/^source \"net\\/ipv4\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/ipv6/Kconfig\tinput-3.kconfig\t/^source \"net\\/ipv6\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/netlabel/Kconfig\tinput-3.kconfig\t/^source \"net\\/netlabel\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/mptcp/Kconfig\tinput-3.kconfig\t/^source \"net\\/mptcp\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nNETWORK_SECMARK\tinput-3.kconfig\t/^config NETWORK_SECMARK$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_NETWORK_SECMARK\tinput-3.kconfig\t/^config NETWORK_SECMARK$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_NETWORK_SECMARK_MODULE\tinput-3.kconfig\t/^config NETWORK_SECMARK$/;\"\tc\tmenu:Networking options\troles:def\nNET_PTP_CLASSIFY\tinput-3.kconfig\t/^config NET_PTP_CLASSIFY$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_NET_PTP_CLASSIFY\tinput-3.kconfig\t/^config NET_PTP_CLASSIFY$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_NET_PTP_CLASSIFY_MODULE\tinput-3.kconfig\t/^config NET_PTP_CLASSIFY$/;\"\tc\tmenu:Networking options\troles:def\nNETWORK_PHY_TIMESTAMPING\tinput-3.kconfig\t/^config NETWORK_PHY_TIMESTAMPING$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_NETWORK_PHY_TIMESTAMPING\tinput-3.kconfig\t/^config NETWORK_PHY_TIMESTAMPING$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_NETWORK_PHY_TIMESTAMPING_MODULE\tinput-3.kconfig\t/^config NETWORK_PHY_TIMESTAMPING$/;\"\tc\tmenu:Networking options\troles:def\nNETFILTER\tinput-3.kconfig\t/^menuconfig NETFILTER$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_NETFILTER\tinput-3.kconfig\t/^menuconfig NETFILTER$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_NETFILTER_MODULE\tinput-3.kconfig\t/^menuconfig NETFILTER$/;\"\tc\tmenu:Networking options\troles:def\nNETFILTER_ADVANCED\tinput-3.kconfig\t/^config NETFILTER_ADVANCED$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_NETFILTER_ADVANCED\tinput-3.kconfig\t/^config NETFILTER_ADVANCED$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_NETFILTER_ADVANCED_MODULE\tinput-3.kconfig\t/^config NETFILTER_ADVANCED$/;\"\tc\tmenu:Networking options\troles:def\nBRIDGE_NETFILTER\tinput-3.kconfig\t/^config BRIDGE_NETFILTER$/;\"\tc\tmenu:Networking options\ttyperef:typename:tristate\troles:def\nCONFIG_BRIDGE_NETFILTER\tinput-3.kconfig\t/^config BRIDGE_NETFILTER$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_BRIDGE_NETFILTER_MODULE\tinput-3.kconfig\t/^config BRIDGE_NETFILTER$/;\"\tc\tmenu:Networking options\troles:def\nnet/netfilter/Kconfig\tinput-3.kconfig\t/^source \"net\\/netfilter\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/ipv4/netfilter/Kconfig\tinput-3.kconfig\t/^source \"net\\/ipv4\\/netfilter\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/ipv6/netfilter/Kconfig\tinput-3.kconfig\t/^source \"net\\/ipv6\\/netfilter\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/decnet/netfilter/Kconfig\tinput-3.kconfig\t/^source \"net\\/decnet\\/netfilter\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/bridge/netfilter/Kconfig\tinput-3.kconfig\t/^source \"net\\/bridge\\/netfilter\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/bpfilter/Kconfig\tinput-3.kconfig\t/^source \"net\\/bpfilter\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/dccp/Kconfig\tinput-3.kconfig\t/^source \"net\\/dccp\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/sctp/Kconfig\tinput-3.kconfig\t/^source \"net\\/sctp\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/rds/Kconfig\tinput-3.kconfig\t/^source \"net\\/rds\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/tipc/Kconfig\tinput-3.kconfig\t/^source \"net\\/tipc\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/atm/Kconfig\tinput-3.kconfig\t/^source \"net\\/atm\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/l2tp/Kconfig\tinput-3.kconfig\t/^source \"net\\/l2tp\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/802/Kconfig\tinput-3.kconfig\t/^source \"net\\/802\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/bridge/Kconfig\tinput-3.kconfig\t/^source \"net\\/bridge\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/dsa/Kconfig\tinput-3.kconfig\t/^source \"net\\/dsa\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/8021q/Kconfig\tinput-3.kconfig\t/^source \"net\\/8021q\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/decnet/Kconfig\tinput-3.kconfig\t/^source \"net\\/decnet\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/llc/Kconfig\tinput-3.kconfig\t/^source \"net\\/llc\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\ndrivers/net/appletalk/Kconfig\tinput-3.kconfig\t/^source \"drivers\\/net\\/appletalk\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/x25/Kconfig\tinput-3.kconfig\t/^source \"net\\/x25\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/lapb/Kconfig\tinput-3.kconfig\t/^source \"net\\/lapb\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/phonet/Kconfig\tinput-3.kconfig\t/^source \"net\\/phonet\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/6lowpan/Kconfig\tinput-3.kconfig\t/^source \"net\\/6lowpan\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/ieee802154/Kconfig\tinput-3.kconfig\t/^source \"net\\/ieee802154\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/mac802154/Kconfig\tinput-3.kconfig\t/^source \"net\\/mac802154\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/sched/Kconfig\tinput-3.kconfig\t/^source \"net\\/sched\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/dcb/Kconfig\tinput-3.kconfig\t/^source \"net\\/dcb\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/dns_resolver/Kconfig\tinput-3.kconfig\t/^source \"net\\/dns_resolver\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/batman-adv/Kconfig\tinput-3.kconfig\t/^source \"net\\/batman-adv\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/openvswitch/Kconfig\tinput-3.kconfig\t/^source \"net\\/openvswitch\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/vmw_vsock/Kconfig\tinput-3.kconfig\t/^source \"net\\/vmw_vsock\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/netlink/Kconfig\tinput-3.kconfig\t/^source \"net\\/netlink\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/mpls/Kconfig\tinput-3.kconfig\t/^source \"net\\/mpls\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/nsh/Kconfig\tinput-3.kconfig\t/^source \"net\\/nsh\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/hsr/Kconfig\tinput-3.kconfig\t/^source \"net\\/hsr\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/switchdev/Kconfig\tinput-3.kconfig\t/^source \"net\\/switchdev\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/l3mdev/Kconfig\tinput-3.kconfig\t/^source \"net\\/l3mdev\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/qrtr/Kconfig\tinput-3.kconfig\t/^source \"net\\/qrtr\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nnet/ncsi/Kconfig\tinput-3.kconfig\t/^source \"net\\/ncsi\\/Kconfig\"$/;\"\tk\tmenu:Networking options\troles:source\nRPS\tinput-3.kconfig\t/^config RPS$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_RPS\tinput-3.kconfig\t/^config RPS$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_RPS_MODULE\tinput-3.kconfig\t/^config RPS$/;\"\tc\tmenu:Networking options\troles:def\nRFS_ACCEL\tinput-3.kconfig\t/^config RFS_ACCEL$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_RFS_ACCEL\tinput-3.kconfig\t/^config RFS_ACCEL$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_RFS_ACCEL_MODULE\tinput-3.kconfig\t/^config RFS_ACCEL$/;\"\tc\tmenu:Networking options\troles:def\nXPS\tinput-3.kconfig\t/^config XPS$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_XPS\tinput-3.kconfig\t/^config XPS$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_XPS_MODULE\tinput-3.kconfig\t/^config XPS$/;\"\tc\tmenu:Networking options\troles:def\nHWBM\tinput-3.kconfig\t/^config HWBM$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_HWBM\tinput-3.kconfig\t/^config HWBM$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_HWBM_MODULE\tinput-3.kconfig\t/^config HWBM$/;\"\tc\tmenu:Networking options\troles:def\nCGROUP_NET_PRIO\tinput-3.kconfig\t/^config CGROUP_NET_PRIO$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_CGROUP_NET_PRIO\tinput-3.kconfig\t/^config CGROUP_NET_PRIO$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_CGROUP_NET_PRIO_MODULE\tinput-3.kconfig\t/^config CGROUP_NET_PRIO$/;\"\tc\tmenu:Networking options\troles:def\nCGROUP_NET_CLASSID\tinput-3.kconfig\t/^config CGROUP_NET_CLASSID$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_CGROUP_NET_CLASSID\tinput-3.kconfig\t/^config CGROUP_NET_CLASSID$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_CGROUP_NET_CLASSID_MODULE\tinput-3.kconfig\t/^config CGROUP_NET_CLASSID$/;\"\tc\tmenu:Networking options\troles:def\nNET_RX_BUSY_POLL\tinput-3.kconfig\t/^config NET_RX_BUSY_POLL$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_NET_RX_BUSY_POLL\tinput-3.kconfig\t/^config NET_RX_BUSY_POLL$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_NET_RX_BUSY_POLL_MODULE\tinput-3.kconfig\t/^config NET_RX_BUSY_POLL$/;\"\tc\tmenu:Networking options\troles:def\nBQL\tinput-3.kconfig\t/^config BQL$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_BQL\tinput-3.kconfig\t/^config BQL$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_BQL_MODULE\tinput-3.kconfig\t/^config BQL$/;\"\tc\tmenu:Networking options\troles:def\nBPF_JIT\tinput-3.kconfig\t/^config BPF_JIT$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_BPF_JIT\tinput-3.kconfig\t/^config BPF_JIT$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_BPF_JIT_MODULE\tinput-3.kconfig\t/^config BPF_JIT$/;\"\tc\tmenu:Networking options\troles:def\nBPF_STREAM_PARSER\tinput-3.kconfig\t/^config BPF_STREAM_PARSER$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_BPF_STREAM_PARSER\tinput-3.kconfig\t/^config BPF_STREAM_PARSER$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_BPF_STREAM_PARSER_MODULE\tinput-3.kconfig\t/^config BPF_STREAM_PARSER$/;\"\tc\tmenu:Networking options\troles:def\nNET_FLOW_LIMIT\tinput-3.kconfig\t/^config NET_FLOW_LIMIT$/;\"\tc\tmenu:Networking options\ttyperef:typename:bool\troles:def\nCONFIG_NET_FLOW_LIMIT\tinput-3.kconfig\t/^config NET_FLOW_LIMIT$/;\"\tc\tmenu:Networking options\troles:def\nCONFIG_NET_FLOW_LIMIT_MODULE\tinput-3.kconfig\t/^config NET_FLOW_LIMIT$/;\"\tc\tmenu:Networking options\troles:def\nNetwork testing\tinput-3.kconfig\t/^menu \"Network testing\"$/;\"\tm\tmenu:Networking options\troles:def\nNET_PKTGEN\tinput-3.kconfig\t/^config NET_PKTGEN$/;\"\tc\tmenu:Networking options\"\"Network testing\ttyperef:typename:tristate\troles:def\nCONFIG_NET_PKTGEN\tinput-3.kconfig\t/^config NET_PKTGEN$/;\"\tc\tmenu:Networking options\"\"Network testing\troles:def\nCONFIG_NET_PKTGEN_MODULE\tinput-3.kconfig\t/^config NET_PKTGEN$/;\"\tc\tmenu:Networking options\"\"Network testing\troles:def\nNET_DROP_MONITOR\tinput-3.kconfig\t/^config NET_DROP_MONITOR$/;\"\tc\tmenu:Networking options\"\"Network testing\ttyperef:typename:tristate\troles:def\nCONFIG_NET_DROP_MONITOR\tinput-3.kconfig\t/^config NET_DROP_MONITOR$/;\"\tc\tmenu:Networking options\"\"Network testing\troles:def\nCONFIG_NET_DROP_MONITOR_MODULE\tinput-3.kconfig\t/^config NET_DROP_MONITOR$/;\"\tc\tmenu:Networking options\"\"Network testing\troles:def\nKconfig.host\tinput-4.kconfig\t/^source Kconfig.host$/;\"\tk\troles:source\nbackends/Kconfig\tinput-4.kconfig\t/^source backends\\/Kconfig$/;\"\tk\troles:source\naccel/Kconfig\tinput-4.kconfig\t/^source accel\\/Kconfig$/;\"\tk\troles:source\nhw/Kconfig\tinput-4.kconfig\t/^source hw\\/Kconfig$/;\"\tk\troles:source\n"
  },
  {
    "path": "Units/parser-kconfig.r/simple-kconfig.d/input-1.kconfig",
    "content": "# SPDX-License-Identifier: GPL-2.0-only\nconfig JFFS2_FS\n\ttristate \"Journalling Flash File System v2 (JFFS2) support\"\n\tselect CRC32\n\tdepends on MTD\n\thelp\n\t  JFFS2 is the second generation of the Journalling Flash File System\n\t  for use on diskless embedded devices. It provides improved wear\n\t  levelling, compression and support for hard links. You cannot use\n\t  this on normal block devices, only on 'MTD' devices.\n\n\t  Further information on the design and implementation of JFFS2 is\n\t  available at <http://sources.redhat.com/jffs2/>.\n\nconfig JFFS2_FS_DEBUG\n\tint \"JFFS2 debugging verbosity (0 = quiet, 2 = noisy)\"\n\tdepends on JFFS2_FS\n\tdefault \"0\"\n\thelp\n\t  This controls the amount of debugging messages produced by the JFFS2\n\t  code. Set it to zero for use in production systems. For evaluation,\n\t  testing and debugging, it's advisable to set it to one. This will\n\t  enable a few assertions and will print debugging messages at the\n\t  KERN_DEBUG loglevel, where they won't normally be visible. Level 2\n\t  is unlikely to be useful - it enables extra debugging in certain\n\t  areas which at one point needed debugging, but when the bugs were\n\t  located and fixed, the detailed messages were relegated to level 2.\n\n\t  If reporting bugs, please try to have available a full dump of the\n\t  messages at debug level 1 while the misbehaviour was occurring.\n\nconfig JFFS2_FS_WRITEBUFFER\n\tbool \"JFFS2 write-buffering support\"\n\tdepends on JFFS2_FS\n\tdefault y\n\thelp\n\t  This enables the write-buffering support in JFFS2.\n\n\t  This functionality is required to support JFFS2 on the following\n\t  types of flash devices:\n\t    - NAND flash\n\t    - NOR flash with transparent ECC\n\t    - DataFlash\n\nconfig JFFS2_FS_WBUF_VERIFY\n\tbool \"Verify JFFS2 write-buffer reads\"\n\tdepends on JFFS2_FS_WRITEBUFFER\n\tdefault n\n\thelp\n\t  This causes JFFS2 to read back every page written through the\n\t  write-buffer, and check for errors.\n\nconfig JFFS2_SUMMARY\n\tbool \"JFFS2 summary support\"\n\tdepends on JFFS2_FS\n\tdefault n\n\thelp\n\t  This feature makes it possible to use summary information\n\t  for faster filesystem mount.\n\n\t  The summary information can be inserted into a filesystem image\n\t  by the utility 'sumtool'.\n\n\t  If unsure, say 'N'.\n\nconfig JFFS2_FS_XATTR\n\tbool \"JFFS2 XATTR support\"\n\tdepends on JFFS2_FS\n\tdefault n\n\thelp\n\t  Extended attributes are name:value pairs associated with inodes by\n\t  the kernel or by users (see the attr(5) manual page for details).\n\n\t  If unsure, say N.\n\nconfig JFFS2_FS_POSIX_ACL\n\tbool \"JFFS2 POSIX Access Control Lists\"\n\tdepends on JFFS2_FS_XATTR\n\tdefault y\n\tselect FS_POSIX_ACL\n\thelp\n\t  Posix Access Control Lists (ACLs) support permissions for users and\n\t  groups beyond the owner/group/world scheme.\n\n\t  If you don't know what Access Control Lists are, say N\n\nconfig JFFS2_FS_SECURITY\n\tbool \"JFFS2 Security Labels\"\n\tdepends on JFFS2_FS_XATTR\n\tdefault y\n\thelp\n\t  Security labels support alternative access control models\n\t  implemented by security modules like SELinux.  This option\n\t  enables an extended attribute handler for file security\n\t  labels in the jffs2 filesystem.\n\n\t  If you are not using a security module that requires using\n\t  extended attributes for file security labels, say N.\n\nconfig JFFS2_COMPRESSION_OPTIONS\n\tbool \"Advanced compression options for JFFS2\"\n\tdepends on JFFS2_FS\n\tdefault n\n\thelp\n\t  Enabling this option allows you to explicitly choose which\n\t  compression modules, if any, are enabled in JFFS2. Removing\n\t  compressors can mean you cannot read existing file systems,\n\t  and enabling experimental compressors can mean that you\n\t  write a file system which cannot be read by a standard kernel.\n\n\t  If unsure, you should _definitely_ say 'N'.\n\nconfig JFFS2_ZLIB\n\tbool \"JFFS2 ZLIB compression support\" if JFFS2_COMPRESSION_OPTIONS\n\tselect ZLIB_INFLATE\n\tselect ZLIB_DEFLATE\n\tdepends on JFFS2_FS\n\tdefault y\n\thelp\n\t  Zlib is designed to be a free, general-purpose, legally unencumbered,\n\t  lossless data-compression library for use on virtually any computer\n\t  hardware and operating system. See <http://www.gzip.org/zlib/> for\n\t  further information.\n\n\t  Say 'Y' if unsure.\n\nconfig JFFS2_LZO\n\tbool \"JFFS2 LZO compression support\" if JFFS2_COMPRESSION_OPTIONS\n\tselect LZO_COMPRESS\n\tselect LZO_DECOMPRESS\n\tdepends on JFFS2_FS\n\tdefault n\n\thelp\n\t  minilzo-based compression. Generally works better than Zlib.\n\n\t  This feature was added in July, 2007. Say 'N' if you need\n\t  compatibility with older bootloaders or kernels.\n\nconfig JFFS2_RTIME\n\tbool \"JFFS2 RTIME compression support\" if JFFS2_COMPRESSION_OPTIONS\n\tdepends on JFFS2_FS\n\tdefault y\n\thelp\n\t  Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.\n\nconfig JFFS2_RUBIN\n\tbool \"JFFS2 RUBIN compression support\" if JFFS2_COMPRESSION_OPTIONS\n\tdepends on JFFS2_FS\n\tdefault n\n\thelp\n\t  RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.\n\nchoice\n\tprompt \"JFFS2 default compression mode\" if JFFS2_COMPRESSION_OPTIONS\n\tdefault JFFS2_CMODE_PRIORITY\n\tdepends on JFFS2_FS\n\thelp\n\t  You can set here the default compression mode of JFFS2 from\n\t  the available compression modes. Don't touch if unsure.\n\nconfig JFFS2_CMODE_NONE\n\tbool \"no compression\"\n\thelp\n\t  Uses no compression.\n\nconfig JFFS2_CMODE_PRIORITY\n\tbool \"priority\"\n\thelp\n\t  Tries the compressors in a predefined order and chooses the first\n\t  successful one.\n\nconfig JFFS2_CMODE_SIZE\n\tbool \"size\"\n\thelp\n\t  Tries all compressors and chooses the one which has the smallest\n\t  result.\n\nconfig JFFS2_CMODE_FAVOURLZO\n\tbool \"Favour LZO\"\n\thelp\n\t  Tries all compressors and chooses the one which has the smallest\n\t  result but gives some preference to LZO (which has faster\n\t  decompression) at the expense of size.\n\nendchoice\n\n#\n# This test input for u-ctags is taken from linux/fs/jffs2/Kconfig\n#\n"
  },
  {
    "path": "Units/parser-kconfig.r/simple-kconfig.d/input-2.kconfig",
    "content": "# SPDX-License-Identifier: GPL-2.0-only\n\nconfig HAVE_ARCH_KGDB\n\tbool\n\nmenuconfig KGDB\n\tbool \"KGDB: kernel debugger\"\n\tdepends on HAVE_ARCH_KGDB\n\tdepends on DEBUG_KERNEL\n\thelp\n\t  If you say Y here, it will be possible to remotely debug the\n\t  kernel using gdb.  It is recommended but not required, that\n\t  you also turn on the kernel config option\n\t  CONFIG_FRAME_POINTER to aid in producing more reliable stack\n\t  backtraces in the external debugger.  Documentation of\n\t  kernel debugger is available at http://kgdb.sourceforge.net\n\t  as well as in Documentation/dev-tools/kgdb.rst.  If\n\t  unsure, say N.\n\nif KGDB\n\nconfig KGDB_SERIAL_CONSOLE\n\ttristate \"KGDB: use kgdb over the serial console\"\n\tselect CONSOLE_POLL\n\tselect MAGIC_SYSRQ\n\tdepends on TTY && HW_CONSOLE\n\tdefault y\n\thelp\n\t  Share a serial console with kgdb. Sysrq-g must be used\n\t  to break in initially.\n\nconfig KGDB_TESTS\n\tbool \"KGDB: internal test suite\"\n\tdefault n\n\thelp\n\t  This is a kgdb I/O module specifically designed to test\n\t  kgdb's internal functions.  This kgdb I/O module is\n\t  intended to for the development of new kgdb stubs\n\t  as well as regression testing the kgdb internals.\n\t  See the drivers/misc/kgdbts.c for the details about\n\t  the tests.  The most basic of this I/O module is to boot\n\t  a kernel boot arguments \"kgdbwait kgdbts=V1F100\"\n\nconfig KGDB_TESTS_ON_BOOT\n\tbool \"KGDB: Run tests on boot\"\n\tdepends on KGDB_TESTS\n\tdefault n\n\thelp\n\t  Run the kgdb tests on boot up automatically without the need\n\t  to pass in a kernel parameter\n\nconfig KGDB_TESTS_BOOT_STRING\n\tstring \"KGDB: which internal kgdb tests to run\"\n\tdepends on KGDB_TESTS_ON_BOOT\n\tdefault \"V1F100\"\n\thelp\n\t  This is the command string to send the kgdb test suite on\n\t  boot.  See the drivers/misc/kgdbts.c for detailed\n\t  information about other strings you could use beyond the\n\t  default of V1F100.\n\nconfig KGDB_LOW_LEVEL_TRAP\n       bool \"KGDB: Allow debugging with traps in notifiers\"\n       depends on X86 || MIPS\n       default n\n       help\n\t This will add an extra call back to kgdb for the breakpoint\n\t exception handler which will allow kgdb to step through a\n\t notify handler.\n\nconfig KGDB_KDB\n\tbool \"KGDB_KDB: include kdb frontend for kgdb\"\n\tdefault n\n\thelp\n\t  KDB frontend for kernel\n\nconfig KDB_DEFAULT_ENABLE\n\thex \"KDB: Select kdb command functions to be enabled by default\"\n\tdepends on KGDB_KDB\n\tdefault 0x1\n\thelp\n\t  Specifiers which kdb commands are enabled by default. This may\n\t  be set to 1 or 0 to enable all commands or disable almost all\n\t  commands.\n\n\t  Alternatively the following bitmask applies:\n\n\t    0x0002 - allow arbitrary reads from memory and symbol lookup\n\t    0x0004 - allow arbitrary writes to memory\n\t    0x0008 - allow current register state to be inspected\n\t    0x0010 - allow current register state to be modified\n\t    0x0020 - allow passive inspection (backtrace, process list, lsmod)\n\t    0x0040 - allow flow control management (breakpoint, single step)\n\t    0x0080 - enable signalling of processes\n\t    0x0100 - allow machine to be rebooted\n\n\t  The config option merely sets the default at boot time. Both\n\t  issuing 'echo X > /sys/module/kdb/parameters/cmd_enable' or\n\t  setting with kdb.cmd_enable=X kernel command line option will\n\t  override the default settings.\n\nconfig KDB_KEYBOARD\n\tbool \"KGDB_KDB: keyboard as input device\"\n\tdepends on VT && KGDB_KDB\n\tdefault n\n\thelp\n\t  KDB can use a PS/2 type keyboard for an input device\n\nconfig KDB_CONTINUE_CATASTROPHIC\n\tint \"KDB: continue after catastrophic errors\"\n\tdepends on KGDB_KDB\n\tdefault \"0\"\n\thelp\n\t  This integer controls the behaviour of kdb when the kernel gets a\n\t  catastrophic error, i.e. for a panic or oops.\n\t  When KDB is active and a catastrophic error occurs, nothing extra\n\t  will happen until you type 'go'.\n\t  CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default). The first time\n\t  you type 'go', you will be warned by kdb. The secend time you type\n\t  'go', KDB tries to continue. No guarantees that the\n\t  kernel is still usable in this situation.\n\t  CONFIG_KDB_CONTINUE_CATASTROPHIC == 1. KDB tries to continue.\n\t  No guarantees that the kernel is still usable in this situation.\n\t  CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. KDB forces a reboot.\n\t  If you are not sure, say 0.\n\nendif # KGDB\n\n#\n# This test input for u-ctags is taken from linux/lib/Kconfig.kgdb\n#\n"
  },
  {
    "path": "Units/parser-kconfig.r/simple-kconfig.d/input-3.kconfig",
    "content": "# SPDX-License-Identifier: GPL-2.0-only\n#\n# Network configuration\n#\n\nmenu \"Networking options\"\n\nsource \"net/packet/Kconfig\"\nsource \"net/unix/Kconfig\"\nsource \"net/tls/Kconfig\"\nsource \"net/xfrm/Kconfig\"\nsource \"net/iucv/Kconfig\"\nsource \"net/smc/Kconfig\"\nsource \"net/xdp/Kconfig\"\n\nconfig INET\n\tbool \"TCP/IP networking\"\n\t---help---\n\t  These are the protocols used on the Internet and on most local\n\t  Ethernets. It is highly recommended to say Y here (this will enlarge\n\t  your kernel by about 400 KB), since some programs (e.g. the X window\n\t  system) use TCP/IP even if your machine is not connected to any\n\t  other computer. You will get the so-called loopback device which\n\t  allows you to ping yourself (great fun, that!).\n\n\t  For an excellent introduction to Linux networking, please read the\n\t  Linux Networking HOWTO, available from\n\t  <http://www.tldp.org/docs.html#howto>.\n\n\t  If you say Y here and also to \"/proc file system support\" and\n\t  \"Sysctl support\" below, you can change various aspects of the\n\t  behavior of the TCP/IP code by writing to the (virtual) files in\n\t  /proc/sys/net/ipv4/*; the options are explained in the file\n\t  <file:Documentation/networking/ip-sysctl.txt>.\n\n\t  Short answer: say Y.\n\nif INET\nsource \"net/ipv4/Kconfig\"\nsource \"net/ipv6/Kconfig\"\nsource \"net/netlabel/Kconfig\"\nsource \"net/mptcp/Kconfig\"\n\nendif # if INET\n\nconfig NETWORK_SECMARK\n\tbool \"Security Marking\"\n\thelp\n\t  This enables security marking of network packets, similar\n\t  to nfmark, but designated for security purposes.\n\t  If you are unsure how to answer this question, answer N.\n\nconfig NET_PTP_CLASSIFY\n\tdef_bool n\n\nconfig NETWORK_PHY_TIMESTAMPING\n\tbool \"Timestamping in PHY devices\"\n\tselect NET_PTP_CLASSIFY\n\thelp\n\t  This allows timestamping of network packets by PHYs (or\n\t  other MII bus snooping devices) with hardware timestamping\n\t  capabilities. This option adds some overhead in the transmit\n\t  and receive paths.\n\n\t  If you are unsure how to answer this question, answer N.\n\nmenuconfig NETFILTER\n\tbool \"Network packet filtering framework (Netfilter)\"\n\t---help---\n\t  Netfilter is a framework for filtering and mangling network packets\n\t  that pass through your Linux box.\n\n\t  The most common use of packet filtering is to run your Linux box as\n\t  a firewall protecting a local network from the Internet. The type of\n\t  firewall provided by this kernel support is called a \"packet\n\t  filter\", which means that it can reject individual network packets\n\t  based on type, source, destination etc. The other kind of firewall,\n\t  a \"proxy-based\" one, is more secure but more intrusive and more\n\t  bothersome to set up; it inspects the network traffic much more\n\t  closely, modifies it and has knowledge about the higher level\n\t  protocols, which a packet filter lacks. Moreover, proxy-based\n\t  firewalls often require changes to the programs running on the local\n\t  clients. Proxy-based firewalls don't need support by the kernel, but\n\t  they are often combined with a packet filter, which only works if\n\t  you say Y here.\n\n\t  You should also say Y here if you intend to use your Linux box as\n\t  the gateway to the Internet for a local network of machines without\n\t  globally valid IP addresses. This is called \"masquerading\": if one\n\t  of the computers on your local network wants to send something to\n\t  the outside, your box can \"masquerade\" as that computer, i.e. it\n\t  forwards the traffic to the intended outside destination, but\n\t  modifies the packets to make it look like they came from the\n\t  firewall box itself. It works both ways: if the outside host\n\t  replies, the Linux box will silently forward the traffic to the\n\t  correct local computer. This way, the computers on your local net\n\t  are completely invisible to the outside world, even though they can\n\t  reach the outside and can receive replies. It is even possible to\n\t  run globally visible servers from within a masqueraded local network\n\t  using a mechanism called portforwarding. Masquerading is also often\n\t  called NAT (Network Address Translation).\n\n\t  Another use of Netfilter is in transparent proxying: if a machine on\n\t  the local network tries to connect to an outside host, your Linux\n\t  box can transparently forward the traffic to a local server,\n\t  typically a caching proxy server.\n\n\t  Yet another use of Netfilter is building a bridging firewall. Using\n\t  a bridge with Network packet filtering enabled makes iptables \"see\"\n\t  the bridged traffic. For filtering on the lower network and Ethernet\n\t  protocols over the bridge, use ebtables (under bridge netfilter\n\t  configuration).\n\n\t  Various modules exist for netfilter which replace the previous\n\t  masquerading (ipmasqadm), packet filtering (ipchains), transparent\n\t  proxying, and portforwarding mechanisms. Please see\n\t  <file:Documentation/Changes> under \"iptables\" for the location of\n\t  these packages.\n\nif NETFILTER\n\nconfig NETFILTER_ADVANCED\n\tbool \"Advanced netfilter configuration\"\n\tdepends on NETFILTER\n\tdefault y\n\thelp\n\t  If you say Y here you can select between all the netfilter modules.\n\t  If you say N the more unusual ones will not be shown and the\n\t  basic ones needed by most people will default to 'M'.\n\n\t  If unsure, say Y.\n\nconfig BRIDGE_NETFILTER\n\ttristate \"Bridged IP/ARP packets filtering\"\n\tdepends on BRIDGE\n\tdepends on NETFILTER && INET\n\tdepends on NETFILTER_ADVANCED\n\tselect NETFILTER_FAMILY_BRIDGE\n\tselect SKB_EXTENSIONS\n\t---help---\n\t  Enabling this option will let arptables resp. iptables see bridged\n\t  ARP resp. IP traffic. If you want a bridging firewall, you probably\n\t  want this option enabled.\n\t  Enabling or disabling this option doesn't enable or disable\n\t  ebtables.\n\n\t  If unsure, say N.\n\nsource \"net/netfilter/Kconfig\"\nsource \"net/ipv4/netfilter/Kconfig\"\nsource \"net/ipv6/netfilter/Kconfig\"\nsource \"net/decnet/netfilter/Kconfig\"\nsource \"net/bridge/netfilter/Kconfig\"\n\nendif\n\nsource \"net/bpfilter/Kconfig\"\n\nsource \"net/dccp/Kconfig\"\nsource \"net/sctp/Kconfig\"\nsource \"net/rds/Kconfig\"\nsource \"net/tipc/Kconfig\"\nsource \"net/atm/Kconfig\"\nsource \"net/l2tp/Kconfig\"\nsource \"net/802/Kconfig\"\nsource \"net/bridge/Kconfig\"\nsource \"net/dsa/Kconfig\"\nsource \"net/8021q/Kconfig\"\nsource \"net/decnet/Kconfig\"\nsource \"net/llc/Kconfig\"\nsource \"drivers/net/appletalk/Kconfig\"\nsource \"net/x25/Kconfig\"\nsource \"net/lapb/Kconfig\"\nsource \"net/phonet/Kconfig\"\nsource \"net/6lowpan/Kconfig\"\nsource \"net/ieee802154/Kconfig\"\nsource \"net/mac802154/Kconfig\"\nsource \"net/sched/Kconfig\"\nsource \"net/dcb/Kconfig\"\nsource \"net/dns_resolver/Kconfig\"\nsource \"net/batman-adv/Kconfig\"\nsource \"net/openvswitch/Kconfig\"\nsource \"net/vmw_vsock/Kconfig\"\nsource \"net/netlink/Kconfig\"\nsource \"net/mpls/Kconfig\"\nsource \"net/nsh/Kconfig\"\nsource \"net/hsr/Kconfig\"\nsource \"net/switchdev/Kconfig\"\nsource \"net/l3mdev/Kconfig\"\nsource \"net/qrtr/Kconfig\"\nsource \"net/ncsi/Kconfig\"\n\nconfig RPS\n\tbool\n\tdepends on SMP && SYSFS\n\tdefault y\n\nconfig RFS_ACCEL\n\tbool\n\tdepends on RPS\n\tselect CPU_RMAP\n\tdefault y\n\nconfig XPS\n\tbool\n\tdepends on SMP\n\tdefault y\n\nconfig HWBM\n\tbool\n\nconfig CGROUP_NET_PRIO\n\tbool \"Network priority cgroup\"\n\tdepends on CGROUPS\n\tselect SOCK_CGROUP_DATA\n\t---help---\n\t  Cgroup subsystem for use in assigning processes to network priorities on\n\t  a per-interface basis.\n\nconfig CGROUP_NET_CLASSID\n\tbool \"Network classid cgroup\"\n\tdepends on CGROUPS\n\tselect SOCK_CGROUP_DATA\n\t---help---\n\t  Cgroup subsystem for use as general purpose socket classid marker that is\n\t  being used in cls_cgroup and for netfilter matching.\n\nconfig NET_RX_BUSY_POLL\n\tbool\n\tdefault y\n\nconfig BQL\n\tbool\n\tdepends on SYSFS\n\tselect DQL\n\tdefault y\n\nconfig BPF_JIT\n\tbool \"enable BPF Just In Time compiler\"\n\tdepends on HAVE_CBPF_JIT || HAVE_EBPF_JIT\n\tdepends on MODULES\n\t---help---\n\t  Berkeley Packet Filter filtering capabilities are normally handled\n\t  by an interpreter. This option allows kernel to generate a native\n\t  code when filter is loaded in memory. This should speedup\n\t  packet sniffing (libpcap/tcpdump).\n\n\t  Note, admin should enable this feature changing:\n\t  /proc/sys/net/core/bpf_jit_enable\n\t  /proc/sys/net/core/bpf_jit_harden   (optional)\n\t  /proc/sys/net/core/bpf_jit_kallsyms (optional)\n\nconfig BPF_STREAM_PARSER\n\tbool \"enable BPF STREAM_PARSER\"\n\tdepends on INET\n\tdepends on BPF_SYSCALL\n\tdepends on CGROUP_BPF\n\tselect STREAM_PARSER\n\tselect NET_SOCK_MSG\n\t---help---\n\t  Enabling this allows a stream parser to be used with\n\t  BPF_MAP_TYPE_SOCKMAP.\n\n\t  BPF_MAP_TYPE_SOCKMAP provides a map type to use with network sockets.\n\t  It can be used to enforce socket policy, implement socket redirects,\n\t  etc.\n\nconfig NET_FLOW_LIMIT\n\tbool\n\tdepends on RPS\n\tdefault y\n\t---help---\n\t  The network stack has to drop packets when a receive processing CPU's\n\t  backlog reaches netdev_max_backlog. If a few out of many active flows\n\t  generate the vast majority of load, drop their traffic earlier to\n\t  maintain capacity for the other flows. This feature provides servers\n\t  with many clients some protection against DoS by a single (spoofed)\n\t  flow that greatly exceeds average workload.\n\nmenu \"Network testing\"\n\nconfig NET_PKTGEN\n\ttristate \"Packet Generator (USE WITH CAUTION)\"\n\tdepends on INET && PROC_FS\n\t---help---\n\t  This module will inject preconfigured packets, at a configurable\n\t  rate, out of a given interface.  It is used for network interface\n\t  stress testing and performance analysis.  If you don't understand\n\t  what was just said, you don't need it: say N.\n\n\t  Documentation on how to use the packet generator can be found\n\t  at <file:Documentation/networking/pktgen.txt>.\n\n\t  To compile this code as a module, choose M here: the\n\t  module will be called pktgen.\n\nconfig NET_DROP_MONITOR\n\ttristate \"Network packet drop alerting service\"\n\tdepends on INET && TRACEPOINTS\n\t---help---\n\t  This feature provides an alerting service to userspace in the\n\t  event that packets are discarded in the network stack.  Alerts\n\t  are broadcast via netlink socket to any listening user space\n\t  process.  If you don't need network drop alerts, or if you are ok\n\t  just checking the various proc files and other utilities for\n\t  drop statistics, say N here.\n\nendmenu\n\nendmenu\n\n#\n# This test input for u-ctags is partially taken from linux/net/Kconfig\n#\n"
  },
  {
    "path": "Units/parser-kconfig.r/simple-kconfig.d/input-4.kconfig",
    "content": "# Taken from qemu/Kconfig\nsource Kconfig.host\nsource backends/Kconfig\nsource accel/Kconfig\nsource hw/Kconfig\n"
  },
  {
    "path": "Units/parser-kconfig.r/simple-kconfig.d/input.kconfig",
    "content": "# SPDX-License-Identifier: GPL-2.0\n#\n# For a description of the syntax of this configuration file,\n# see Documentation/kbuild/kconfig-language.rst.\n#\nmainmenu \"Linux/$(ARCH) $(KERNELVERSION) Kernel Configuration\"\n\ncomment \"Compiler: $(CC_VERSION_TEXT)\"\n\nsource \"scripts/Kconfig.include\"\n\nsource \"init/Kconfig\"\n\nsource \"kernel/Kconfig.freezer\"\n\nsource \"fs/Kconfig.binfmt\"\n\nsource \"mm/Kconfig\"\n\nsource \"net/Kconfig\"\n\nsource \"drivers/Kconfig\"\n\nsource \"fs/Kconfig\"\n\nsource \"security/Kconfig\"\n\nsource \"crypto/Kconfig\"\n\nsource \"lib/Kconfig\"\n\nsource \"lib/Kconfig.debug\"\n\nsource \"Documentation/Kconfig\"\n\n#\n# This test input for u-ctags is taken from linux/Kconfig\n#\n"
  },
  {
    "path": "Units/parser-kconfig.r/unbalance.d/args.ctags",
    "content": "--sort=no\n--map-Kconfig=.kconfig\n--extras-Kconfig=-{configPrefixed}\n--fields=+e\n--extras=+r\n"
  },
  {
    "path": "Units/parser-kconfig.r/unbalance.d/expected.tags",
    "content": "A\tinput.kconfig\t/^config A$/;\"\tc\ttyperef:typename:bool\tend:5\nB\tinput.kconfig\t/^config B$/;\"\tc\ttyperef:typename:bool\tend:7\nY\tinput-0.kconfig\t/^menu \"Y\"$/;\"\tm\tend:11\nC\tinput-0.kconfig\t/^config C$/;\"\tc\tmenu:Y\ttyperef:typename:bool\tend:7\nD\tinput-0.kconfig\t/^config D$/;\"\tc\tmenu:Y\ttyperef:typename:bool\tend:10\nE\tinput-1.kconfig\t/^config E$/;\"\tc\ttyperef:typename:bool\tend:5\nF\tinput-1.kconfig\t/^config F$/;\"\tc\ttyperef:typename:bool\tend:8\nW\tinput-2.kconfig\t/^choice W$/;\"\tC\tend:8\nG\tinput-2.kconfig\t/^\tconfig G$/;\"\tc\tchoice:W\ttyperef:typename:bool\tend:7\nH\tinput-3.kconfig\t/^config H$/;\"\tc\ttyperef:typename:bool\tend:4\n"
  },
  {
    "path": "Units/parser-kconfig.r/unbalance.d/input-0.kconfig",
    "content": "menu \"Y\"\n\nconfig C\n       bool\n       help\n         endmenu - a dummy\n\nconfig D\n       bool\n\nendmenu\n"
  },
  {
    "path": "Units/parser-kconfig.r/unbalance.d/input-1.kconfig",
    "content": "config E\n       bool\n       help\n\t choice Z0 or Z1\n\nconfig F\n       bool\n\n"
  },
  {
    "path": "Units/parser-kconfig.r/unbalance.d/input-2.kconfig",
    "content": "choice W\n\thelp\n\t  endchoice but this is a part of help message\n\n\tconfig G\n\t       bool\n\nendchoice\n"
  },
  {
    "path": "Units/parser-kconfig.r/unbalance.d/input-3.kconfig",
    "content": "config H\n       bool\n       help\n         source \"V\" is a part of a help message.\n"
  },
  {
    "path": "Units/parser-kconfig.r/unbalance.d/input.kconfig",
    "content": "config A\n\tbool\n\thelp\n\t  menu \"X\" rest\n\nconfig B\n       bool\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-annotations.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-annotations.d/expected.tags",
    "content": "f1\tinput.kt\t/^fun f1(@a2 x: @a3 () -> Unit) {}$/;\"\tm\nf2\tinput.kt\t/^fun f2(@a5() x: @a6() () -> Unit) {}$/;\"\tm\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-annotations.d/input.kt",
    "content": "@a1\nfun f1(@a2 x: @a3 () -> Unit) {}\n\n@a4()\nfun f2(@a5() x: @a6() () -> Unit) {}\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-backticks.d/expected.tags",
    "content": "main\tinput.kt\t/^fun `main`(args:Array<String>) {$/;\"\tm\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-backticks.d/input.kt",
    "content": "fun `main`(args:Array<String>) {\n    println(\"hello, world!\")\n}\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-comments.d/expected.tags",
    "content": "f\tinput.kt\t/^\\/* comment *\\/ var f = 6 \\/* another comment *\\/$/;\"\tv\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-comments.d/input.kt",
    "content": "// var a = 1\n\n/* var b = 2 */\n\n/*\nvar c = 3\n*/\n\n/** var d = 4 */\n\n/**\n * var e = 5\n */\n\n/* comment */ var f = 6 /* another comment */\n\n/*\ncomment\n    /* nested comment */\nvar g = 7\n*/\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-destructuring.d/expected.tags",
    "content": "a\tinput.kt\t/^val (a, b) = functionReturningPair()$/;\"\tC\nb\tinput.kt\t/^val (a, b) = functionReturningPair()$/;\"\tC\nc\tinput.kt\t/^val (c: Int, d: String) = functionReturningPair()$/;\"\tC\nd\tinput.kt\t/^val (c: Int, d: String) = functionReturningPair()$/;\"\tC\ne\tinput.kt\t/^var (e, f) = functionReturningPair()$/;\"\tv\nf\tinput.kt\t/^var (e, f) = functionReturningPair()$/;\"\tv\ng\tinput.kt\t/^var (g: Int, h: Pair<String, Int>) = functionReturningPair()$/;\"\tv\nh\tinput.kt\t/^var (g: Int, h: Pair<String, Int>) = functionReturningPair()$/;\"\tv\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-destructuring.d/input.kt",
    "content": "val (a, b) = functionReturningPair()\nval (c: Int, d: String) = functionReturningPair()\nvar (e, f) = functionReturningPair()\nvar (g: Int, h: Pair<String, Int>) = functionReturningPair()\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-extensions.d/expected.tags",
    "content": "A\tinput.kt\t/^class A$/;\"\tc\ntest\tinput.kt\t/^fun A.test() = true$/;\"\tm\nvalue\tinput.kt\t/^val A.value$/;\"\tC\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-extensions.d/input.kt",
    "content": "class A\n\nfun A.test() = true\n\nval A.value\n\tget() = \"AAA\"\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-generics.d/expected.tags",
    "content": "Bar\tinput.kt\t/^class Bar<T, U>(val a: T, val b: U): Foo<T>$/;\"\tc\nBaz\tinput.kt\t/^class Baz <T, U: Pair<String,Pair<T, Double>>>(val c: T, val d: U): Foo<T>$/;\"\tc\nFoo\tinput.kt\t/^interface Foo<T> {$/;\"\ti\na\tinput.kt\t/^class Bar<T, U>(val a: T, val b: U): Foo<T>$/;\"\tC\tclass:Bar\nb\tinput.kt\t/^class Bar<T, U>(val a: T, val b: U): Foo<T>$/;\"\tC\tclass:Bar\nc\tinput.kt\t/^class Baz <T, U: Pair<String,Pair<T, Double>>>(val c: T, val d: U): Foo<T>$/;\"\tC\tclass:Baz\nd\tinput.kt\t/^class Baz <T, U: Pair<String,Pair<T, Double>>>(val c: T, val d: U): Foo<T>$/;\"\tC\tclass:Baz\ngenericFunction1\tinput.kt\t/^    fun<T: Any> genericFunction1() = 41$/;\"\tm\tinterface:Foo\ngenericFunction2\tinput.kt\t/^    fun<T: Pair<String,Pair<Int, T>>> genericFunction2() = 42$/;\"\tm\tinterface:Foo\ngenericFunction3\tinput.kt\t/^    fun <T> genericFunction3() = 43$/;\"\tm\tinterface:Foo\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-generics.d/input.kt",
    "content": "interface Foo<T> {\n    fun<T: Any> genericFunction1() = 41\n    fun<T: Pair<String,Pair<Int, T>>> genericFunction2() = 42\n    fun <T> genericFunction3() = 43\n}\n\nclass Bar<T, U>(val a: T, val b: U): Foo<T>\nclass Baz <T, U: Pair<String,Pair<T, Double>>>(val c: T, val d: U): Foo<T>\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-invalid-input.d/expected.tags",
    "content": "A\tinput.kt\t/^val A=1$/;\"\tC\nB\tinput.kt\t/^val B=2$/;\"\tC\nC\tinput.kt\t/^val C=3$/;\"\tC\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-invalid-input.d/input.kt",
    "content": "// this is not valid Kotlin code, but the parser should recover and continue parsing\nval A=1\n...\n...\nval B=2\n...\nval C=3\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-rawstrings.d/expected.tags",
    "content": "used1\tinput.kt\t/^var used1 = \"\"\"var unused1 = 1\"\"\"$/;\"\tv\nused2\tinput.kt\t/^var used2 = \"\"\"$/;\"\tv\nused3\tinput.kt\t/^var used3 = \"\"\"var unused3a = 3\"\"\" + \"\"\"var unused3b = 3\"\"\"$/;\"\tv\nused4\tinput.kt\t/^var used4 = \"\"\"...\"val unused4\"...\"\"\"$/;\"\tv\nused5\tinput.kt\t/^var used5 = \"\"\"${process(\"\"\"var unused5 = 5\"\"\")}\"\"\"$/;\"\tv\nused6\tinput.kt\t/^var used6 = \"\"\"\"val unused6=6\"\"\"\"$/;\"\tv\nused7\tinput.kt\t/^var used7 = \"\"\"\"\"var unused6=6\"\"\"\"\"$/;\"\tv\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-rawstrings.d/input.kt",
    "content": "var used1 = \"\"\"var unused1 = 1\"\"\"\nvar used2 = \"\"\"\n    var unused2 = 2\n\"\"\"\nvar used3 = \"\"\"var unused3a = 3\"\"\" + \"\"\"var unused3b = 3\"\"\"\nvar used4 = \"\"\"...\"val unused4\"...\"\"\"\nvar used5 = \"\"\"${process(\"\"\"var unused5 = 5\"\"\")}\"\"\"\nvar used6 = \"\"\"\"val unused6=6\"\"\"\"\nvar used7 = \"\"\"\"\"var unused6=6\"\"\"\"\"\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-scope.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-scope.d/expected.tags",
    "content": "com.example.test\tinput.kt\t/^package com.example.test$/;\"\tp\nTestObject\tinput.kt\t/^object TestObject {$/;\"\to\tpackage:com.example.test\na\tinput.kt\t/^    val a = 1$/;\"\tC\tobject:com.example.test.TestObject\nf1\tinput.kt\t/^    fun f1(): String {$/;\"\tm\tobject:com.example.test.TestObject\nb\tinput.kt\t/^        val b = \"hi\"$/;\"\tC\tmethod:com.example.test.TestObject.f1\nTestClass\tinput.kt\t/^class TestClass(val c: String, var d: Int) {$/;\"\tc\tpackage:com.example.test\nc\tinput.kt\t/^class TestClass(val c: String, var d: Int) {$/;\"\tC\tclass:com.example.test.TestClass\nd\tinput.kt\t/^class TestClass(val c: String, var d: Int) {$/;\"\tv\tclass:com.example.test.TestClass\ne\tinput.kt\t/^    val e = 2$/;\"\tC\tclass:com.example.test.TestClass\nf2\tinput.kt\t/^    fun f2(): String {$/;\"\tm\tclass:com.example.test.TestClass\nf\tinput.kt\t/^        var f = 42 * 12$/;\"\tv\tmethod:com.example.test.TestClass.f2\nTestInterface\tinput.kt\t/^interface TestInterface {$/;\"\ti\tpackage:com.example.test\ng\tinput.kt\t/^    abstract val g: Int$/;\"\tC\tinterface:com.example.test.TestInterface\nf3\tinput.kt\t/^    fun f3(): String {$/;\"\tm\tinterface:com.example.test.TestInterface\nlmbd\tinput.kt\t/^        val lmbd: () -> String = {$/;\"\tC\tmethod:com.example.test.TestInterface.f3\n<lambda>\tinput.kt\t/^        val lmbd: () -> String = {$/;\"\tm\tmethod:com.example.test.TestInterface.f3\nh\tinput.kt\t/^            val h = \"B\".toLowerCase()$/;\"\tC\tmethod:com.example.test.TestInterface.f3.<lambda>\nanonymousFunction\tinput.kt\t/^val anonymousFunction = fun(x: Int, y: Int): Int {$/;\"\tC\tpackage:com.example.test\n<anonymous>\tinput.kt\t/^val anonymousFunction = fun(x: Int, y: Int): Int {$/;\"\tm\tpackage:com.example.test\nsum\tinput.kt\t/^    val sum = x + y$/;\"\tC\tmethod:com.example.test.<anonymous>\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-scope.d/input.kt",
    "content": "package com.example.test\n\nobject TestObject {\n    val a = 1\n    fun f1(): String {\n        val b = \"hi\"\n        return b\n    }\n}\n\nclass TestClass(val c: String, var d: Int) {\n    val e = 2\n    fun f2(): String {\n        var f = 42 * 12\n        return f.toString()\n    }\n}\n\ninterface TestInterface {\n    abstract val g: Int\n    fun f3(): String {\n        val lmbd: () -> String = {\n            val h = \"B\".toLowerCase()\n            h\n        }\n        return lmbd()\n    }\n}\n\nval anonymousFunction = fun(x: Int, y: Int): Int {\n    val sum = x + y\n    return sum\n}\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-strings.d/expected.tags",
    "content": "used1\tinput.kt\t/^var used1 = \"var unused1 = 1\"$/;\"\tv\nused2\tinput.kt\t/^var used2 = \"\\\\\"var\\\\\" unused2 = 2\"$/;\"\tv\nused3\tinput.kt\t/^var used3 = \"\"$/;\"\tv\nused4\tinput.kt\t/^var used4 = \"${process(\"var unused4 = 4\")}\"$/;\"\tv\nused5\tinput.kt\t/^var used5 = '\\\\\"'$/;\"\tv\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-strings.d/input.kt",
    "content": "var used1 = \"var unused1 = 1\"\nvar used2 = \"\\\"var\\\" unused2 = 2\"\nvar used3 = \"\"\nvar used4 = \"${process(\"var unused4 = 4\")}\"\n// quote in character literal must not break parser\nvar used5 = '\\\"'\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-syntax.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-syntax.d/expected.tags",
    "content": "com.example.helloworld\tinput.kt\t/^package com.example.helloworld$/;\"\tp\nAbstractWorker\tinput.kt\t/^interface AbstractWorker {$/;\"\ti\tpackage:com.example.helloworld\nprocess\tinput.kt\t/^    abstract fun process(): String$/;\"\tm\tinterface:com.example.helloworld.AbstractWorker\nWorker\tinput.kt\t/^class Worker<T>(val name: T): AbstractWorker {$/;\"\tc\tpackage:com.example.helloworld\nname\tinput.kt\t/^class Worker<T>(val name: T): AbstractWorker {$/;\"\tC\tclass:com.example.helloworld.Worker\nprocess\tinput.kt\t/^    override fun process(): String = name.toString()$/;\"\tm\tclass:com.example.helloworld.Worker\nGlobal\tinput.kt\t/^object Global {$/;\"\to\tpackage:com.example.helloworld\ngreeting\tinput.kt\t/^    const val greeting = \"Hello\"$/;\"\tC\tobject:com.example.helloworld.Global\nStringWorker\tinput.kt\t/^typealias StringWorker = Worker<String>$/;\"\tT\tpackage:com.example.helloworld\nmain\tinput.kt\t/^fun main() {$/;\"\tm\tpackage:com.example.helloworld\nresult\tinput.kt\t/^    var result: String = Global.greeting$/;\"\tv\tmethod:com.example.helloworld.main\n"
  },
  {
    "path": "Units/parser-kotlin.r/kotlin-syntax.d/input.kt",
    "content": "package com.example.helloworld\n\ninterface AbstractWorker {\n    abstract fun process(): String\n}\n\nclass Worker<T>(val name: T): AbstractWorker {\n    override fun process(): String = name.toString()\n}\n\nobject Global {\n    const val greeting = \"Hello\"\n}\n\ntypealias StringWorker = Worker<String>\n\nfun main() {\n    var result: String = Global.greeting\n    result = \"$result \" + StringWorker(\"World\").process()\n    result += \"!\"\n    println(result)\n}\n"
  },
  {
    "path": "Units/parser-ldscript.r/anon-version.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ldscript.r/anon-version.d/expected.tags",
    "content": "jiffies\tinput.lds\t/^jiffies = jiffies_64;$/;\"\ts\nverd85df1730102\tinput.lds\t/^  {$/;\"\tv\n__executable_start\tinput.lds\t/^  PROVIDE (__executable_start = START);$/;\"\ts\tassignment:provide\n__binary_start\tinput.lds\t/^  __binary_start = START;$/;\"\ts\n"
  },
  {
    "path": "Units/parser-ldscript.r/anon-version.d/input.lds",
    "content": "/* Taken from linux/arch/um/kernel/uml.lds.S */\n/* SPDX-License-Identifier: GPL-2.0 */\n#include <asm/vmlinux.lds.h>\n#include <asm/page.h>\n\nOUTPUT_FORMAT(ELF_FORMAT)\nOUTPUT_ARCH(ELF_ARCH)\nENTRY(_start)\njiffies = jiffies_64;\n\nVERSION {\n  {\n    local: *;\n  };\n}\n\nSECTIONS\n{\n  /* This must contain the right address - not quite the default ELF one.*/\n  PROVIDE (__executable_start = START);\n  /* Static binaries stick stuff here, like the sigreturn trampoline,\n   * invisibly to objdump.  So, just make __binary_start equal to the very\n   * beginning of the executable, and if there are unmapped pages after this,\n   * they are forever unusable.\n   */\n  __binary_start = START;\n  /* ... */\n}\n"
  },
  {
    "path": "Units/parser-ldscript.r/cpp-out-of-band-chars.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-ldscript.r/cpp-out-of-band-chars.d/input-0.lds",
    "content": "0\"x\"\n"
  },
  {
    "path": "Units/parser-ldscript.r/cpp-out-of-band-chars.d/input-1.lds",
    "content": "0'x'\n"
  },
  {
    "path": "Units/parser-ldscript.r/cpp-out-of-band-chars.d/input.lds",
    "content": "/* Nothing here */\n"
  },
  {
    "path": "Units/parser-ldscript.r/crash-when-deleting-token.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-ldscript.r/crash-when-deleting-token.d/args.ctags",
    "content": "-Iconst\n"
  },
  {
    "path": "Units/parser-ldscript.r/crash-when-deleting-token.d/input.lds",
    "content": "const\n"
  },
  {
    "path": "Units/parser-ldscript.r/discard.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-ldscript.r/discard.d/expected.tags",
    "content": ".eh_frame\tinput.lds\t/^\t.eh_frame\t: { KEEP (*(.eh_frame)) }\t:text$/;\"\tS\troles:def\n.eh_frame\tinput.lds\t/^\t.eh_frame\t: { KEEP (*(.eh_frame)) }\t:text$/;\"\ti\tsection:.eh_frame\troles:mapped\n.dynamic\tinput.lds\t/^\t.dynamic\t: { *(.dynamic) }\t\t:text\t:dynamic$/;\"\tS\troles:def\n.dynamic\tinput.lds\t/^\t.dynamic\t: { *(.dynamic) }\t\t:text\t:dynamic$/;\"\ti\tsection:.dynamic\troles:mapped\n.note.GNU-stack\tinput.lds\t/^\t\t*(.note.GNU-stack)$/;\"\ti\troles:discarded\n.data\tinput.lds\t/^\t\t*(.data .data.* .gnu.linkonce.d.* .sdata*)$/;\"\ti\troles:discarded\n.data.\tinput.lds\t/^\t\t*(.data .data.* .gnu.linkonce.d.* .sdata*)$/;\"\ti\troles:discarded\n.gnu.linkonce.d.\tinput.lds\t/^\t\t*(.data .data.* .gnu.linkonce.d.* .sdata*)$/;\"\ti\troles:discarded\n.sdata\tinput.lds\t/^\t\t*(.data .data.* .gnu.linkonce.d.* .sdata*)$/;\"\ti\troles:discarded\n.bss\tinput.lds\t/^\t\t*(.bss .sbss .dynbss .dynsbss)$/;\"\ti\troles:discarded\n.sbss\tinput.lds\t/^\t\t*(.bss .sbss .dynbss .dynsbss)$/;\"\ti\troles:discarded\n.dynbss\tinput.lds\t/^\t\t*(.bss .sbss .dynbss .dynsbss)$/;\"\ti\troles:discarded\n.dynsbss\tinput.lds\t/^\t\t*(.bss .sbss .dynbss .dynsbss)$/;\"\ti\troles:discarded\n"
  },
  {
    "path": "Units/parser-ldscript.r/discard.d/input.lds",
    "content": "SECTIONS {\n\t.eh_frame\t: { KEEP (*(.eh_frame)) }\t:text\n\n\t.dynamic\t: { *(.dynamic) }\t\t:text\t:dynamic\n\t/DISCARD/\t: {\n\t\t*(.note.GNU-stack)\n\t\t*(.data .data.* .gnu.linkonce.d.* .sdata*)\n\t\t*(.bss .sbss .dynbss .dynsbss)\n\t}\n}\n"
  },
  {
    "path": "Units/parser-ldscript.r/input-sections.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n--languages=-CPreProcessor\n"
  },
  {
    "path": "Units/parser-ldscript.r/input-sections.d/expected.tags",
    "content": "outputa\tinput.lds\t/^       outputa 0x10000 :$/;\"\tS\troles:def\n.input1\tinput.lds\t/^         foo.o (.input1)$/;\"\ti\tsection:outputa\troles:mapped\noutputb\tinput.lds\t/^       outputb :$/;\"\tS\troles:def\n.input2\tinput.lds\t/^         foo.o (.input2)$/;\"\ti\tsection:outputb\troles:mapped\n.input1\tinput.lds\t/^         foo1.o (.input1)$/;\"\ti\tsection:outputb\troles:mapped\noutputc\tinput.lds\t/^       outputc :$/;\"\tS\troles:def\n.input1\tinput.lds\t/^         *(.input1)$/;\"\ti\tsection:outputc\troles:mapped\n.input2\tinput.lds\t/^         *(.input2)$/;\"\ti\tsection:outputc\troles:mapped\n.text\tinput.lds\t/^       .text : { *(.text) }$/;\"\tS\troles:def\n.text\tinput.lds\t/^       .text : { *(.text) }$/;\"\ti\tsection:.text\troles:mapped\n.DATA\tinput.lds\t/^       .DATA : { [A-Z]*(.data) }$/;\"\tS\troles:def\n.data\tinput.lds\t/^       .DATA : { [A-Z]*(.data) }$/;\"\ti\tsection:.DATA\troles:mapped\n.DATA2\tinput.lds\t/^       .DATA2 : { *[A-Z](.data) }       $/;\"\tS\troles:def\n.data\tinput.lds\t/^       .DATA2 : { *[A-Z](.data) }       $/;\"\ti\tsection:.DATA2\troles:mapped\n.data\tinput.lds\t/^       .data : { *(.data) }$/;\"\tS\troles:def\n.data\tinput.lds\t/^       .data : { *(.data) }$/;\"\ti\tsection:.data\troles:mapped\n.bss\tinput.lds\t/^       .bss : { *(.bss) }$/;\"\tS\troles:def\n.bss\tinput.lds\t/^       .bss : { *(.bss) }$/;\"\ti\tsection:.bss\troles:mapped\n.foo\tinput.lds\t/^       .foo : { a.?(.foo) }$/;\"\tS\troles:def\n.foo\tinput.lds\t/^       .foo : { a.?(.foo) }$/;\"\ti\tsection:.foo\troles:mapped\n.bar\tinput.lds\t/^       .bar : { b.*(*.bar)  *(COMMON) }$/;\"\tS\troles:def\n.bar\tinput.lds\t/^       .bar : { b.*(*.bar)  *(COMMON) }$/;\"\ti\tsection:.bar\troles:mapped\n.baz\tinput.lds\t/^       .baz : { b.*(*.alpha .beta.text)  *(COMMON) }$/;\"\tS\troles:def\n.alpha\tinput.lds\t/^       .baz : { b.*(*.alpha .beta.text)  *(COMMON) }$/;\"\ti\tsection:.baz\troles:mapped\n.beta.text\tinput.lds\t/^       .baz : { b.*(*.alpha .beta.text)  *(COMMON) }$/;\"\ti\tsection:.baz\troles:mapped\n.note\tinput.lds\t/^\t.note : { *(.note*) }$/;\"\tS\troles:def\n.note\tinput.lds\t/^\t.note : { *(.note*) }$/;\"\ti\tsection:.note\troles:mapped\nall\tinput.lds\t/^\tall :\t{*(*)}$/;\"\tS\troles:def\n"
  },
  {
    "path": "Units/parser-ldscript.r/input-sections.d/input.lds",
    "content": "/* Taken from info document of GNU ld.  */\nSECTIONS {\n       outputa 0x10000 :\n         {\n         all.o\n         foo.o (.input1)\n         }\n       outputb :\n         {\n         foo.o (.input2)\n         foo1.o (.input1)\n         }\n       outputc :\n         {\n         *(.input1)\n         *(.input2)\n         }\n       .text : { *(.text) }\n       .DATA : { [A-Z]*(.data) }\n       .DATA2 : { *[A-Z](.data) }       \n       .data : { *(.data) }\n       .bss : { *(.bss) }\n       .foo : { a.?(.foo) }\n       .bar : { b.*(*.bar)  *(COMMON) }\n       .baz : { b.*(*.alpha .beta.text)  *(COMMON) }\n\t.note : { *(.note*) }\n\tall :\t{*(*)}\n     }\n\t \n}\n\n"
  },
  {
    "path": "Units/parser-ldscript.r/ld-hello.d/LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    {description}\n    Copyright (C) {year}  {fullname}\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  {signature of Ty Coon}, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "Units/parser-ldscript.r/ld-hello.d/README",
    "content": "Taken from https://github.com/satoru-takeuchi/ld-hello/blob/master/hello.ld .\n"
  },
  {
    "path": "Units/parser-ldscript.r/ld-hello.d/expected.tags",
    "content": ".rodata\tinput.ld\t/^  .rodata : {$/;\"\tS\n.text\tinput.ld\t/^  .text : {$/;\"\tS\n_start\tinput.ld\t/^    _start = .;$/;\"\ts\tsection:.text\nmessage\tinput.ld\t/^    message = .;$/;\"\ts\tsection:.rodata\n"
  },
  {
    "path": "Units/parser-ldscript.r/ld-hello.d/input.ld",
    "content": "OUTPUT_FORMAT(\"elf64-x86-64\", \"elf64-x86-64\", \"elf64-x86-64\")\nOUTPUT_ARCH(i386:x86-64)\nENTRY(_start)\n\nSECTIONS\n{\n  . = 0x400000 + SIZEOF_HEADERS;\n  .text : {\n    _start = .;\n    /* The syscall calling convention for linux on x86_64. */\n    /* Set the following registers and call \"syscall\" instruction. */\n    /*   %rax: syscall number */\n    /*   %rdi: arg0 */\n    /*   %rsi: arg1 */\n    /*   %rdx: arg2 */\n    /*   %r10: arg3 */\n    /*   %r8:  arg4 */\n    /*   %r9:  arg5 */\n\n    /* set the syscall number of write(2) */\n    /* mov $0x1,%rax */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc0);\n    BYTE(0x01);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n\n    /* set arg0(== 1 == STDOUT_FILENO) of write(2) */\n    /* mov $0x1,%rdi */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc7);\n    BYTE(0x01);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n\n    /* set arg1 of write(2) */\n    /* mov $message,$rsi */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc6);\n    LONG(message);\n\n    /* set arg2 (length of message) of write(2) */\n    /* mov $0xe,%rdx */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc2);\n    BYTE(0x0e);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n\n    /* call write(2) */\n    /* syscall */\n    BYTE(0x0f);\n    BYTE(0x05);\n\n    /* set the syscall number of exit(2) */\n    /* mov $0x3c,%rax */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc0);\n    BYTE(0x3c);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n\n    /* set arg0 of exit(2) */\n    /* mov $9x9,%rdi */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc7);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n\n    /* call exit(2) */\n    /* syscall */\n    BYTE(0x0f);\n    BYTE(0x05);\n  }\n\n  .rodata : {\n    message = .;\n    /* \"Hello, world!\\n\" */\n    BYTE(0x48)\n    BYTE(0x65)\n    BYTE(0x6c)\n    BYTE(0x6c)\n    BYTE(0x6f)\n    BYTE(0x2c)\n    BYTE(0x20)\n    BYTE(0x77)\n    BYTE(0x6f)\n    BYTE(0x72)\n    BYTE(0x6c)\n    BYTE(0x64)\n    BYTE(0x21)\n    BYTE(0x0a)\n  }\n}\n"
  },
  {
    "path": "Units/parser-ldscript.r/ld-symtab.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-ldscript.r/ld-symtab.d/args.ctags",
    "content": "--param-CPreProcessor._expand=1\n--fields-CPreProcessor=+{macrodef}\n--fields=+{signature}\n"
  },
  {
    "path": "Units/parser-ldscript.r/ld-symtab.d/features",
    "content": "debug\n"
  },
  {
    "path": "Units/parser-ldscript.r/ld-symtab.d/input.lds",
    "content": "OUTPUT_FORMAT(\"elf64-x86-64\", \"elf64-x86-64\", \"elf64-x86-64\")\nOUTPUT_ARCH(i386:x86-64)\nENTRY(_start)\n\n#define BYTE(X) .byte X\n\nSECTIONS\n{\n  . = 0x400000 + SIZEOF_HEADERS;\n  .text : {\n    _start = .;\n    /* The syscall calling convention for linux on x86_64. */\n    /* Set the following registers and call \"syscall\" instruction. */\n    /*   %rax: syscall number */\n    /*   %rdi: arg0 */\n    /*   %rsi: arg1 */\n    /*   %rdx: arg2 */\n    /*   %r10: arg3 */\n    /*   %r8:  arg4 */\n    /*   %r9:  arg5 */\n\n    /* set the syscall number of write(2) */\n    /* mov $0x1,%rax */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc0);\n    BYTE(0x01);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n\n    /* set arg0(== 1 == STDOUT_FILENO) of write(2) */\n    /* mov $0x1,%rdi */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc7);\n    BYTE(0x01);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n\n    /* set arg1 of write(2) */\n    /* mov $message,$rsi */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc6);\n    LONG(message);\n\n    /* set arg2 (length of message) of write(2) */\n    /* mov $0xe,%rdx */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc2);\n    BYTE(0x0e);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n\n    /* call write(2) */\n    /* syscall */\n    BYTE(0x0f);\n    BYTE(0x05);\n\n    /* set the syscall number of exit(2) */\n    /* mov $0x3c,%rax */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc0);\n    BYTE(0x3c);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n\n    /* set arg0 of exit(2) */\n    /* mov $9x9,%rdi */\n    BYTE(0x48);\n    BYTE(0xc7);\n    BYTE(0xc7);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n    BYTE(0x00);\n\n    /* call exit(2) */\n    /* syscall */\n    BYTE(0x0f);\n    BYTE(0x05);\n  }\n\n  .rodata : {\n    message = .;\n    /* \"Hello, world!\\n\" */\n    BYTE(0x48)\n    BYTE(0x65)\n    BYTE(0x6c)\n    BYTE(0x6c)\n    BYTE(0x6f)\n    BYTE(0x2c)\n    BYTE(0x20)\n    BYTE(0x77)\n    BYTE(0x6f)\n    BYTE(0x72)\n    BYTE(0x6c)\n    BYTE(0x64)\n    BYTE(0x21)\n    BYTE(0x0a)\n  }\n}\n"
  },
  {
    "path": "Units/parser-ldscript.r/lds-invalid-macro-call.d/args.ctags",
    "content": "--sort=no\n--param-CPreProcessor._expand=1\n--fields=+{signature}{roles}{line}\n--fields-CPreProcessor=+{macrodef}\n--extras=+r\n"
  },
  {
    "path": "Units/parser-ldscript.r/lds-invalid-macro-call.d/expected.tags",
    "content": "S\tinput.lds.S\t/^#define S(A) A: AT(ADDR(.altinstr_aux) - LOAD_OFFSE/;\"\td\tline:1\tfile:\tsignature:(A)\troles:def\tmacrodef:A: AT(ADDR(.altinstr_aux) - LOAD_OFFSET) { *(A) }\n_etext\tinput.lds.S\t/^\t_etext = .;$/;\"\ts\tline:7\troles:def\n"
  },
  {
    "path": "Units/parser-ldscript.r/lds-invalid-macro-call.d/input.lds.S",
    "content": "#define S(A) A: AT(ADDR(.altinstr_aux) - LOAD_OFFSET) { \\\n             *(A) \\\n}\n\nSECTIONS\n{\n\t_etext = .;\n\tS(.altinstr_aux\n}\n"
  },
  {
    "path": "Units/parser-ldscript.r/lds-macro-expansion.d/args.ctags",
    "content": "--sort=no\n--param-CPreProcessor._expand=1\n--fields=+{signature}{roles}{line}\n--fields-CPreProcessor=+{macrodef}\n--extras=+r\n"
  },
  {
    "path": "Units/parser-ldscript.r/lds-macro-expansion.d/expected.tags",
    "content": "MEM_DISCARD\tinput.lds.S\t/^#define MEM_DISCARD(/;\"\td\tline:4\tfile:\tsignature:(sec)\troles:def\tmacrodef:*(.mem##sec)\nINIT_TEXT\tinput.lds.S\t/^#define INIT_TEXT(/;\"\td\tline:6\tfile:\tsignature:(X,A)\troles:def\tmacrodef:*A *X MEM_DISCARD(init.text*)\nINIT_TEXT_SECTION\tinput.lds.S\t/^#define INIT_TEXT_SECTION(/;\"\td\tline:11\tfile:\tsignature:(inittext_align,Y,B)\troles:def\tmacrodef:. = ALIGN(inittext_align); .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { _sinittext = .; INIT_TEXT(Y,B) _einittext = .; }\n.init.text\tinput.lds.S\t/^\tINIT_TEXT_SECTION(PAGE_SIZE$/;\"\tS\tline:22\troles:def\n_sinittext\tinput.lds.S\t/^\tINIT_TEXT_SECTION(PAGE_SIZE$/;\"\ts\tline:22\tsection:.init.text\troles:def\n.init.text\tinput.lds.S\t/^\t(.init.text .init.text.*)$/;\"\ti\tline:26\tsection:.init.text\troles:mapped\n.init.text.\tinput.lds.S\t/^\t(.init.text .init.text.*)$/;\"\ti\tline:26\tsection:.init.text\troles:mapped\n.text.startup\tinput.lds.S\t/^\t(.text.startup)$/;\"\ti\tline:24\tsection:.init.text\troles:mapped\n.meminit.text\tinput.lds.S\t/^\tINIT_TEXT_SECTION(PAGE_SIZE$/;\"\ti\tline:22\tsection:.init.text\troles:mapped\n_einittext\tinput.lds.S\t/^\tINIT_TEXT_SECTION(PAGE_SIZE$/;\"\ts\tline:22\tsection:.init.text\troles:def\n"
  },
  {
    "path": "Units/parser-ldscript.r/lds-macro-expansion.d/input.lds.S",
    "content": "/* Based on linux/include/asm-generic/vmlinux.lds.h and\n * linux/arch/x86/kernel/vmlinux.lds.S */\n\n#define MEM_DISCARD(sec) *(.mem##sec)\n\n#define INIT_TEXT(X,A)\t\t\t\t\\\n\t*A\t\t\t\t\t\\\n\t*X\t\t\t\t\t\\\n\tMEM_DISCARD(init.text*)\n\n#define INIT_TEXT_SECTION(inittext_align,Y,B)\t\t\t\t\\\n\t. = ALIGN(inittext_align);\t\t\t\t\t\\\n\t.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {\t\t\\\n\t\t_sinittext = .;\t\t\t\t\t\t\\\n\t\tINIT_TEXT(Y,B)\t\t\t\t\t\t\\\n\t\t_einittext = .;\t\t\t\t\t\t\\\n\t}\n\n\nSECTIONS\n{\n\tINIT_TEXT_SECTION(PAGE_SIZE\n\t,\n\t(.text.startup)\n\t,\n\t(.init.text .init.text.*)\n\t)\n#ifdef CONFIG_X86_64\n\t:init\n#endif\n}\n\n"
  },
  {
    "path": "Units/parser-ldscript.r/multi-versions.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ldscript.r/multi-versions.d/expected.tags",
    "content": "VERS_1.1\tinput.lds\t/^     VERS_1.1 {$/;\"\tv\nVERS_1.2\tinput.lds\t/^     VERS_1.2 {$/;\"\tv\nVERS_2.0\tinput.lds\t/^     VERS_2.0 {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-ldscript.r/multi-versions.d/input.lds",
    "content": "/* Taken from info manual of ld */\nVERSION {\n     VERS_1.1 {\n     \t global:\n     \t\t foo1;\n     \t local:\n     \t\t old*;\n     \t\t original*;\n     \t\t new*;\n     };\n\n     VERS_1.2 {\n     \t\t foo2;\n     } VERS_1.1;\n\n     VERS_2.0 {\n     \t\t bar1; bar2;\n     \t extern \"C++\" {\n     \t\t ns::*;\n     \t\t \"f(int, double)\";\n     \t };\n     } VERS_1.2;\n}\n"
  },
  {
    "path": "Units/parser-ldscript.r/simple-ldscript.d/README",
    "content": "This test case is taken from linux/arch/x86/kernel/vmlinux.lds.S.\n\nFollowing /DISCARD/ block isn't handled well.\n\n\tDISCARDS\n\t/DISCARD/ : {\n\t\t*(.eh_frame)\n\t\t*(__func_stack_frame_non_standard)\n\t}\n\nDISCARDS before /DISCARD/ makes the parser being confused.\n"
  },
  {
    "path": "Units/parser-ldscript.r/simple-ldscript.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n--languages=-CPreProcessor\n"
  },
  {
    "path": "Units/parser-ldscript.r/simple-ldscript.d/expected.tags",
    "content": "phys_startup_32\tinput.lds.S\t/^ENTRY(phys_startup_32)$/;\"\ts\troles:entrypoint\njiffies\tinput.lds.S\t/^jiffies = jiffies_64;$/;\"\ts\troles:def\nphys_startup_64\tinput.lds.S\t/^ENTRY(phys_startup_64)$/;\"\ts\troles:entrypoint\njiffies_64\tinput.lds.S\t/^jiffies_64 = jiffies;$/;\"\ts\troles:def\nphys_startup_32\tinput.lds.S\t/^\tphys_startup_32 = ABSOLUTE(startup_32 - LOAD_OFFSET);$/;\"\ts\troles:def\nphys_startup_64\tinput.lds.S\t/^\tphys_startup_64 = ABSOLUTE(startup_64 - LOAD_OFFSET);$/;\"\ts\troles:def\n.text\tinput.lds.S\t/^\t.text :  AT(ADDR(.text) - LOAD_OFFSET) {$/;\"\tS\troles:def\n_text\tinput.lds.S\t/^\t\t_text = .;$/;\"\ts\tsection:.text\troles:def\n_stext\tinput.lds.S\t/^\t\t_stext = .;$/;\"\ts\tsection:.text\troles:def\n.fixup\tinput.lds.S\t/^\t\t*(.fixup)$/;\"\ti\tsection:.text\troles:mapped\n.gnu.warning\tinput.lds.S\t/^\t\t*(.gnu.warning)$/;\"\ti\tsection:.text\troles:mapped\n_etext\tinput.lds.S\t/^\t\t_etext = .;$/;\"\ts\tsection:.text\troles:def\n.data\tinput.lds.S\t/^\t.data : AT(ADDR(.data) - LOAD_OFFSET) {$/;\"\tS\troles:def\n_sdata\tinput.lds.S\t/^\t\t_sdata = .;$/;\"\ts\tsection:.data\troles:def\nTHREAD_SIZE\tinput.lds.S\t/^\t\tINIT_TASK_DATA(THREAD_SIZE)$/;\"\ti\tsection:.data\troles:mapped\nPAGE_SIZE\tinput.lds.S\t/^\t\tPAGE_ALIGNED_DATA(PAGE_SIZE)$/;\"\ti\tsection:.data\troles:mapped\nL1_CACHE_BYTES\tinput.lds.S\t/^\t\tCACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)$/;\"\ti\tsection:.data\troles:mapped\nINTERNODE_CACHE_BYTES\tinput.lds.S\t/^\t\tREAD_MOSTLY_DATA(INTERNODE_CACHE_BYTES)$/;\"\ti\tsection:.data\troles:mapped\n_edata\tinput.lds.S\t/^\t\t_edata = .;$/;\"\ts\tsection:.data\troles:def\n__vvar_page\tinput.lds.S\t/^\t__vvar_page = .;$/;\"\ts\troles:def\n.vvar\tinput.lds.S\t/^\t.vvar : AT(ADDR(.vvar) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__vvar_beginning_hack\tinput.lds.S\t/^\t\t__vvar_beginning_hack = .;$/;\"\ts\tsection:.vvar\troles:def\n.init.begin\tinput.lds.S\t/^\t.init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__init_begin\tinput.lds.S\t/^\t\t__init_begin = .; \\/* paired with __init_end *\\/$/;\"\ts\tsection:.init.begin\troles:def\n.altinstr_aux\tinput.lds.S\t/^\t.altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) {$/;\"\tS\troles:def\n.altinstr_aux\tinput.lds.S\t/^\t\t*(.altinstr_aux)$/;\"\ti\tsection:.altinstr_aux\troles:mapped\n.x86_cpu_dev.init\tinput.lds.S\t/^\t.x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__x86_cpu_dev_start\tinput.lds.S\t/^\t\t__x86_cpu_dev_start = .;$/;\"\ts\tsection:.x86_cpu_dev.init\troles:def\n.x86_cpu_dev.init\tinput.lds.S\t/^\t\t*(.x86_cpu_dev.init)$/;\"\ti\tsection:.x86_cpu_dev.init\troles:mapped\n__x86_cpu_dev_end\tinput.lds.S\t/^\t\t__x86_cpu_dev_end = .;$/;\"\ts\tsection:.x86_cpu_dev.init\troles:def\n.x86_intel_mid_dev.init\tinput.lds.S\t/^\t.x86_intel_mid_dev.init : AT(ADDR(.x86_intel_mid_dev.init) - \\\\$/;\"\tS\troles:def\n__x86_intel_mid_dev_start\tinput.lds.S\t/^\t\t__x86_intel_mid_dev_start = .;$/;\"\ts\tsection:.x86_intel_mid_dev.init\troles:def\n.x86_intel_mid_dev.init\tinput.lds.S\t/^\t\t*(.x86_intel_mid_dev.init)$/;\"\ti\tsection:.x86_intel_mid_dev.init\troles:mapped\n__x86_intel_mid_dev_end\tinput.lds.S\t/^\t\t__x86_intel_mid_dev_end = .;$/;\"\ts\tsection:.x86_intel_mid_dev.init\troles:def\n.parainstructions\tinput.lds.S\t/^\t.parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__parainstructions\tinput.lds.S\t/^\t\t__parainstructions = .;$/;\"\ts\tsection:.parainstructions\troles:def\n.parainstructions\tinput.lds.S\t/^\t\t*(.parainstructions)$/;\"\ti\tsection:.parainstructions\troles:mapped\n__parainstructions_end\tinput.lds.S\t/^\t\t__parainstructions_end = .;$/;\"\ts\tsection:.parainstructions\troles:def\n.altinstructions\tinput.lds.S\t/^\t.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__alt_instructions\tinput.lds.S\t/^\t\t__alt_instructions = .;$/;\"\ts\tsection:.altinstructions\troles:def\n.altinstructions\tinput.lds.S\t/^\t\t*(.altinstructions)$/;\"\ti\tsection:.altinstructions\troles:mapped\n__alt_instructions_end\tinput.lds.S\t/^\t\t__alt_instructions_end = .;$/;\"\ts\tsection:.altinstructions\troles:def\n.altinstr_replacement\tinput.lds.S\t/^\t.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {$/;\"\tS\troles:def\n.altinstr_replacement\tinput.lds.S\t/^\t\t*(.altinstr_replacement)$/;\"\ti\tsection:.altinstr_replacement\troles:mapped\n.iommu_table\tinput.lds.S\t/^\t.iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__iommu_table\tinput.lds.S\t/^\t\t__iommu_table = .;$/;\"\ts\tsection:.iommu_table\troles:def\n.iommu_table\tinput.lds.S\t/^\t\t*(.iommu_table)$/;\"\ti\tsection:.iommu_table\troles:mapped\n__iommu_table_end\tinput.lds.S\t/^\t\t__iommu_table_end = .;$/;\"\ts\tsection:.iommu_table\troles:def\n.apicdrivers\tinput.lds.S\t/^\t.apicdrivers : AT(ADDR(.apicdrivers) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__apicdrivers\tinput.lds.S\t/^\t\t__apicdrivers = .;$/;\"\ts\tsection:.apicdrivers\troles:def\n.apicdrivers\tinput.lds.S\t/^\t\t*(.apicdrivers);$/;\"\ti\tsection:.apicdrivers\troles:mapped\n__apicdrivers_end\tinput.lds.S\t/^\t\t__apicdrivers_end = .;$/;\"\ts\tsection:.apicdrivers\troles:def\n.exit.text\tinput.lds.S\t/^\t.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {$/;\"\tS\troles:def\n.exit.data\tinput.lds.S\t/^\t.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {$/;\"\tS\troles:def\n.init.end\tinput.lds.S\t/^\t.init.end : AT(ADDR(.init.end) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__init_end\tinput.lds.S\t/^\t\t__init_end = .;$/;\"\ts\tsection:.init.end\troles:def\n.smp_locks\tinput.lds.S\t/^\t.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__smp_locks\tinput.lds.S\t/^\t\t__smp_locks = .;$/;\"\ts\tsection:.smp_locks\troles:def\n.smp_locks\tinput.lds.S\t/^\t\t*(.smp_locks)$/;\"\ti\tsection:.smp_locks\troles:mapped\n__smp_locks_end\tinput.lds.S\t/^\t\t__smp_locks_end = .;$/;\"\ts\tsection:.smp_locks\troles:def\n.data_nosave\tinput.lds.S\t/^\t.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {$/;\"\tS\troles:def\n.bss\tinput.lds.S\t/^\t.bss : AT(ADDR(.bss) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__bss_start\tinput.lds.S\t/^\t\t__bss_start = .;$/;\"\ts\tsection:.bss\troles:def\n.bss..page_aligned\tinput.lds.S\t/^\t\t*(.bss..page_aligned)$/;\"\ti\tsection:.bss\troles:mapped\n.bss\tinput.lds.S\t/^\t\t*(.bss)$/;\"\ti\tsection:.bss\troles:mapped\n__bss_stop\tinput.lds.S\t/^\t\t__bss_stop = .;$/;\"\ts\tsection:.bss\troles:def\n.brk\tinput.lds.S\t/^\t.brk : AT(ADDR(.brk) - LOAD_OFFSET) {$/;\"\tS\troles:def\n__brk_base\tinput.lds.S\t/^\t\t__brk_base = .;$/;\"\ts\tsection:.brk\troles:def\n.brk_reservation\tinput.lds.S\t/^\t\t*(.brk_reservation)\t\\/* areas brk users have reserved *\\/$/;\"\ti\tsection:.brk\troles:mapped\n__brk_limit\tinput.lds.S\t/^\t\t__brk_limit = .;$/;\"\ts\tsection:.brk\troles:def\n_end\tinput.lds.S\t/^\t_end = .;$/;\"\ts\troles:def\n"
  },
  {
    "path": "Units/parser-ldscript.r/simple-ldscript.d/input.lds.S",
    "content": "/*\n * ld script for the x86 kernel\n *\n * Historic 32-bit version written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>\n *\n * Modernisation, unification and other changes and fixes:\n *   Copyright (C) 2007-2009  Sam Ravnborg <sam@ravnborg.org>\n *\n *\n * Don't define absolute symbols until and unless you know that symbol\n * value is should remain constant even if kernel image is relocated\n * at run time. Absolute symbols are not relocated. If symbol value should\n * change if kernel is relocated, make the symbol section relative and\n * put it inside the section definition.\n */\n\n#ifdef CONFIG_X86_32\n#define LOAD_OFFSET __PAGE_OFFSET\n#else\n#define LOAD_OFFSET __START_KERNEL_map\n#endif\n\n#include <asm-generic/vmlinux.lds.h>\n#include <asm/asm-offsets.h>\n#include <asm/thread_info.h>\n#include <asm/page_types.h>\n#include <asm/cache.h>\n#include <asm/boot.h>\n\n#undef i386     /* in case the preprocessor is a 32bit one */\n\nOUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT)\n\n#ifdef CONFIG_X86_32\nOUTPUT_ARCH(i386)\nENTRY(phys_startup_32)\njiffies = jiffies_64;\n#else\nOUTPUT_ARCH(i386:x86-64)\nENTRY(phys_startup_64)\njiffies_64 = jiffies;\n#endif\n\n#if defined(CONFIG_X86_64)\n/*\n * On 64-bit, align RODATA to 2MB so we retain large page mappings for\n * boundaries spanning kernel text, rodata and data sections.\n *\n * However, kernel identity mappings will have different RWX permissions\n * to the pages mapping to text and to the pages padding (which are freed) the\n * text section. Hence kernel identity mappings will be broken to smaller\n * pages. For 64-bit, kernel text and kernel identity mappings are different,\n * so we can enable protection checks as well as retain 2MB large page\n * mappings for kernel text.\n */\n#define X64_ALIGN_RODATA_BEGIN\t. = ALIGN(HPAGE_SIZE);\n\n#define X64_ALIGN_RODATA_END\t\t\t\t\t\\\n\t\t. = ALIGN(HPAGE_SIZE);\t\t\t\t\\\n\t\t__end_rodata_hpage_align = .;\n\n#else\n\n#define X64_ALIGN_RODATA_BEGIN\n#define X64_ALIGN_RODATA_END\n\n#endif\n\nPHDRS {\n\ttext PT_LOAD FLAGS(5);          /* R_E */\n\tdata PT_LOAD FLAGS(6);          /* RW_ */\n#ifdef CONFIG_X86_64\n#ifdef CONFIG_SMP\n\tpercpu PT_LOAD FLAGS(6);        /* RW_ */\n#endif\n\tinit PT_LOAD FLAGS(7);          /* RWE */\n#endif\n\tnote PT_NOTE FLAGS(0);          /* ___ */\n}\n\nSECTIONS\n{\n#ifdef CONFIG_X86_32\n\t. = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;\n\tphys_startup_32 = ABSOLUTE(startup_32 - LOAD_OFFSET);\n#else\n\t. = __START_KERNEL;\n\tphys_startup_64 = ABSOLUTE(startup_64 - LOAD_OFFSET);\n#endif\n\n\t/* Text and read-only data */\n\t.text :  AT(ADDR(.text) - LOAD_OFFSET) {\n\t\t_text = .;\n\t\t/* bootstrapping code */\n\t\tHEAD_TEXT\n\t\t. = ALIGN(8);\n\t\t_stext = .;\n\t\tTEXT_TEXT\n\t\tSCHED_TEXT\n\t\tLOCK_TEXT\n\t\tKPROBES_TEXT\n\t\tENTRY_TEXT\n\t\tIRQENTRY_TEXT\n\t\tSOFTIRQENTRY_TEXT\n\t\t*(.fixup)\n\t\t*(.gnu.warning)\n\t\t/* End of text section */\n\t\t_etext = .;\n\t} :text = 0x9090\n\n\tNOTES :text :note\n\n\tEXCEPTION_TABLE(16) :text = 0x9090\n\n\t/* .text should occupy whole number of pages */\n\t. = ALIGN(PAGE_SIZE);\n\tX64_ALIGN_RODATA_BEGIN\n\tRO_DATA(PAGE_SIZE)\n\tX64_ALIGN_RODATA_END\n\n\t/* Data */\n\t.data : AT(ADDR(.data) - LOAD_OFFSET) {\n\t\t/* Start of data section */\n\t\t_sdata = .;\n\n\t\t/* init_task */\n\t\tINIT_TASK_DATA(THREAD_SIZE)\n\n#ifdef CONFIG_X86_32\n\t\t/* 32 bit has nosave before _edata */\n\t\tNOSAVE_DATA\n#endif\n\n\t\tPAGE_ALIGNED_DATA(PAGE_SIZE)\n\n\t\tCACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)\n\n\t\tDATA_DATA\n\t\tCONSTRUCTORS\n\n\t\t/* rarely changed data like cpu maps */\n\t\tREAD_MOSTLY_DATA(INTERNODE_CACHE_BYTES)\n\n\t\t/* End of data section */\n\t\t_edata = .;\n\t} :data\n\n\n\t. = ALIGN(PAGE_SIZE);\n\t__vvar_page = .;\n\n\t.vvar : AT(ADDR(.vvar) - LOAD_OFFSET) {\n\t\t/* work around gold bug 13023 */\n\t\t__vvar_beginning_hack = .;\n\n\t\t/* Place all vvars at the offsets in asm/vvar.h. */\n#define EMIT_VVAR(name, offset) \t\t\t\\\n\t\t. = __vvar_beginning_hack + offset;\t\\\n\t\t*(.vvar_ ## name)\n#define __VVAR_KERNEL_LDS\n#include <asm/vvar.h>\n#undef __VVAR_KERNEL_LDS\n#undef EMIT_VVAR\n\n\t\t/*\n\t\t * Pad the rest of the page with zeros.  Otherwise the loader\n\t\t * can leave garbage here.\n\t\t */\n\t\t. = __vvar_beginning_hack + PAGE_SIZE;\n\t} :data\n\n       . = ALIGN(__vvar_page + PAGE_SIZE, PAGE_SIZE);\n\n\t/* Init code and data - will be freed after init */\n\t. = ALIGN(PAGE_SIZE);\n\t.init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {\n\t\t__init_begin = .; /* paired with __init_end */\n\t}\n\n#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)\n\t/*\n\t * percpu offsets are zero-based on SMP.  PERCPU_VADDR() changes the\n\t * output PHDR, so the next output section - .init.text - should\n\t * start another segment - init.\n\t */\n\tPERCPU_VADDR(INTERNODE_CACHE_BYTES, 0, :percpu)\n\tASSERT(SIZEOF(.data..percpu) < CONFIG_PHYSICAL_START,\n\t       \"per-CPU data too large - increase CONFIG_PHYSICAL_START\")\n#endif\n\n\tINIT_TEXT_SECTION(PAGE_SIZE)\n#ifdef CONFIG_X86_64\n\t:init\n#endif\n\n\t/*\n\t * Section for code used exclusively before alternatives are run. All\n\t * references to such code must be patched out by alternatives, normally\n\t * by using X86_FEATURE_ALWAYS CPU feature bit.\n\t *\n\t * See static_cpu_has() for an example.\n\t */\n\t.altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) {\n\t\t*(.altinstr_aux)\n\t}\n\n\tINIT_DATA_SECTION(16)\n\n\t.x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {\n\t\t__x86_cpu_dev_start = .;\n\t\t*(.x86_cpu_dev.init)\n\t\t__x86_cpu_dev_end = .;\n\t}\n\n#ifdef CONFIG_X86_INTEL_MID\n\t.x86_intel_mid_dev.init : AT(ADDR(.x86_intel_mid_dev.init) - \\\n\t\t\t\t\t\t\t\tLOAD_OFFSET) {\n\t\t__x86_intel_mid_dev_start = .;\n\t\t*(.x86_intel_mid_dev.init)\n\t\t__x86_intel_mid_dev_end = .;\n\t}\n#endif\n\n\t/*\n\t * start address and size of operations which during runtime\n\t * can be patched with virtualization friendly instructions or\n\t * baremetal native ones. Think page table operations.\n\t * Details in paravirt_types.h\n\t */\n\t. = ALIGN(8);\n\t.parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {\n\t\t__parainstructions = .;\n\t\t*(.parainstructions)\n\t\t__parainstructions_end = .;\n\t}\n\n\t/*\n\t * struct alt_inst entries. From the header (alternative.h):\n\t * \"Alternative instructions for different CPU types or capabilities\"\n\t * Think locking instructions on spinlocks.\n\t */\n\t. = ALIGN(8);\n\t.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {\n\t\t__alt_instructions = .;\n\t\t*(.altinstructions)\n\t\t__alt_instructions_end = .;\n\t}\n\n\t/*\n\t * And here are the replacement instructions. The linker sticks\n\t * them as binary blobs. The .altinstructions has enough data to\n\t * get the address and the length of them to patch the kernel safely.\n\t */\n\t.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {\n\t\t*(.altinstr_replacement)\n\t}\n\n\t/*\n\t * struct iommu_table_entry entries are injected in this section.\n\t * It is an array of IOMMUs which during run time gets sorted depending\n\t * on its dependency order. After rootfs_initcall is complete\n\t * this section can be safely removed.\n\t */\n\t.iommu_table : AT(ADDR(.iommu_table) - LOAD_OFFSET) {\n\t\t__iommu_table = .;\n\t\t*(.iommu_table)\n\t\t__iommu_table_end = .;\n\t}\n\n\t. = ALIGN(8);\n\t.apicdrivers : AT(ADDR(.apicdrivers) - LOAD_OFFSET) {\n\t\t__apicdrivers = .;\n\t\t*(.apicdrivers);\n\t\t__apicdrivers_end = .;\n\t}\n\n\t. = ALIGN(8);\n\t/*\n\t * .exit.text is discard at runtime, not link time, to deal with\n\t *  references from .altinstructions and .eh_frame\n\t */\n\t.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {\n\t\tEXIT_TEXT\n\t}\n\n\t.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {\n\t\tEXIT_DATA\n\t}\n\n#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)\n\tPERCPU_SECTION(INTERNODE_CACHE_BYTES)\n#endif\n\n\t. = ALIGN(PAGE_SIZE);\n\n\t/* freed after init ends here */\n\t.init.end : AT(ADDR(.init.end) - LOAD_OFFSET) {\n\t\t__init_end = .;\n\t}\n\n\t/*\n\t * smp_locks might be freed after init\n\t * start/end must be page aligned\n\t */\n\t. = ALIGN(PAGE_SIZE);\n\t.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {\n\t\t__smp_locks = .;\n\t\t*(.smp_locks)\n\t\t. = ALIGN(PAGE_SIZE);\n\t\t__smp_locks_end = .;\n\t}\n\n#ifdef CONFIG_X86_64\n\t.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {\n\t\tNOSAVE_DATA\n\t}\n#endif\n\n\t/* BSS */\n\t. = ALIGN(PAGE_SIZE);\n\t.bss : AT(ADDR(.bss) - LOAD_OFFSET) {\n\t\t__bss_start = .;\n\t\t*(.bss..page_aligned)\n\t\t*(.bss)\n\t\t. = ALIGN(PAGE_SIZE);\n\t\t__bss_stop = .;\n\t}\n\n\t. = ALIGN(PAGE_SIZE);\n\t.brk : AT(ADDR(.brk) - LOAD_OFFSET) {\n\t\t__brk_base = .;\n\t\t. += 64 * 1024;\t\t/* 64k alignment slop space */\n\t\t*(.brk_reservation)\t/* areas brk users have reserved */\n\t\t__brk_limit = .;\n\t}\n\n\t. = ALIGN(PAGE_SIZE);\t\t/* keep VO_INIT_SIZE page aligned */\n\t_end = .;\n\n        STABS_DEBUG\n        DWARF_DEBUG\n\n\t/* Sections to be discarded */\n\tDISCARDS\n\t/DISCARD/ : {\n\t\t*(.eh_frame)\n\t\t*(__func_stack_frame_non_standard)\n\t}\n}\n\n\n#ifdef CONFIG_X86_32\n/*\n * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:\n */\n. = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),\n\t   \"kernel image bigger than KERNEL_IMAGE_SIZE\");\n#else\n/*\n * Per-cpu symbols which need to be offset from __per_cpu_load\n * for the boot processor.\n */\n#define INIT_PER_CPU(x) init_per_cpu__##x = x + __per_cpu_load\nINIT_PER_CPU(gdt_page);\nINIT_PER_CPU(irq_stack_union);\n\n/*\n * Build-time check on the image size:\n */\n. = ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),\n\t   \"kernel image bigger than KERNEL_IMAGE_SIZE\");\n\n#ifdef CONFIG_SMP\n. = ASSERT((irq_stack_union == 0),\n           \"irq_stack_union is not at start of per-cpu area\");\n#endif\n\n#endif /* CONFIG_X86_32 */\n\n#ifdef CONFIG_KEXEC_CORE\n#include <asm/kexec.h>\n\n. = ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE,\n           \"kexec control code size is too big\");\n#endif\n\n"
  },
  {
    "path": "Units/parser-ldscript.r/sort.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-ldscript.r/sort.d/expected.tags",
    "content": ".discard\tinput.lds\t/^\t\t*(.discard)$/;\"\ti\troles:discarded\n.discard.\tinput.lds\t/^\t\t*(.discard.*)$/;\"\ti\troles:discarded\n__ksymtab\tinput.lds\t/^\t__ksymtab\t\t0 : { *(SORT(___ksymtab+*)) }$/;\"\tS\troles:def\n___ksymtab\tinput.lds\t/^\t__ksymtab\t\t0 : { *(SORT(___ksymtab+*)) }$/;\"\ti\tsection:__ksymtab\troles:mapped\n__ksymtab_gpl\tinput.lds\t/^\t__ksymtab_gpl\t\t0 : { *(SORT(___ksymtab_gpl+*)) }$/;\"\tS\troles:def\n___ksymtab_gpl\tinput.lds\t/^\t__ksymtab_gpl\t\t0 : { *(SORT(___ksymtab_gpl+*)) }$/;\"\ti\tsection:__ksymtab_gpl\troles:mapped\n__ksymtab_unused\tinput.lds\t/^\t__ksymtab_unused\t0 : { *(SORT(___ksymtab_unused+*)) }$/;\"\tS\troles:def\n___ksymtab_unused\tinput.lds\t/^\t__ksymtab_unused\t0 : { *(SORT(___ksymtab_unused+*)) }$/;\"\ti\tsection:__ksymtab_unused\troles:mapped\n__ksymtab_unused_gpl\tinput.lds\t/^\t__ksymtab_unused_gpl\t0 : { *(SORT(___ksymtab_unused_gpl+*)) }$/;\"\tS\troles:def\n___ksymtab_unused_gpl\tinput.lds\t/^\t__ksymtab_unused_gpl\t0 : { *(SORT(___ksymtab_unused_gpl+*)) }$/;\"\ti\tsection:__ksymtab_unused_gpl\troles:mapped\n__ksymtab_gpl_future\tinput.lds\t/^\t__ksymtab_gpl_future\t0 : { *(SORT(___ksymtab_gpl_future+*)) }$/;\"\tS\troles:def\n___ksymtab_gpl_future\tinput.lds\t/^\t__ksymtab_gpl_future\t0 : { *(SORT(___ksymtab_gpl_future+*)) }$/;\"\ti\tsection:__ksymtab_gpl_future\troles:mapped\n__kcrctab\tinput.lds\t/^\t__kcrctab\t\t0 : { *(SORT(___kcrctab+*)) }$/;\"\tS\troles:def\n___kcrctab\tinput.lds\t/^\t__kcrctab\t\t0 : { *(SORT(___kcrctab+*)) }$/;\"\ti\tsection:__kcrctab\troles:mapped\n__kcrctab_gpl\tinput.lds\t/^\t__kcrctab_gpl\t\t0 : { *(SORT(___kcrctab_gpl+*)) }$/;\"\tS\troles:def\n___kcrctab_gpl\tinput.lds\t/^\t__kcrctab_gpl\t\t0 : { *(SORT(___kcrctab_gpl+*)) }$/;\"\ti\tsection:__kcrctab_gpl\troles:mapped\n__kcrctab_unused\tinput.lds\t/^\t__kcrctab_unused\t0 : { *(SORT(___kcrctab_unused+*)) }$/;\"\tS\troles:def\n___kcrctab_unused\tinput.lds\t/^\t__kcrctab_unused\t0 : { *(SORT(___kcrctab_unused+*)) }$/;\"\ti\tsection:__kcrctab_unused\troles:mapped\n__kcrctab_unused_gpl\tinput.lds\t/^\t__kcrctab_unused_gpl\t0 : { *(SORT(___kcrctab_unused_gpl+*)) }$/;\"\tS\troles:def\n___kcrctab_unused_gpl\tinput.lds\t/^\t__kcrctab_unused_gpl\t0 : { *(SORT(___kcrctab_unused_gpl+*)) }$/;\"\ti\tsection:__kcrctab_unused_gpl\troles:mapped\n__kcrctab_gpl_future\tinput.lds\t/^\t__kcrctab_gpl_future\t0 : { *(SORT(___kcrctab_gpl_future+*)) }$/;\"\tS\troles:def\n___kcrctab_gpl_future\tinput.lds\t/^\t__kcrctab_gpl_future\t0 : { *(SORT(___kcrctab_gpl_future+*)) }$/;\"\ti\tsection:__kcrctab_gpl_future\troles:mapped\n.init_array\tinput.lds\t/^\t.init_array\t\t0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) }$/;\"\tS\troles:def\n.init_array.\tinput.lds\t/^\t.init_array\t\t0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) }$/;\"\ti\tsection:.init_array\troles:mapped\n.init_array\tinput.lds\t/^\t.init_array\t\t0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) }$/;\"\ti\tsection:.init_array\troles:mapped\n__jump_table\tinput.lds\t/^\t__jump_table\t\t0 : ALIGN(8) { KEEP(*(__jump_table)) }$/;\"\tS\troles:def\n__jump_table\tinput.lds\t/^\t__jump_table\t\t0 : ALIGN(8) { KEEP(*(__jump_table)) }$/;\"\ti\tsection:__jump_table\troles:mapped\n"
  },
  {
    "path": "Units/parser-ldscript.r/sort.d/input.lds",
    "content": "/* Taken from linux/scripts/module-common.lds */\n/*\n * Common module linker script, always used when linking a module.\n * Archs are free to supply their own linker scripts.  ld will\n * combine them automatically.\n */\nSECTIONS {\n\t/DISCARD/ : {\n\t\t*(.discard)\n\t\t*(.discard.*)\n\t}\n\n\t__ksymtab\t\t0 : { *(SORT(___ksymtab+*)) }\n\t__ksymtab_gpl\t\t0 : { *(SORT(___ksymtab_gpl+*)) }\n\t__ksymtab_unused\t0 : { *(SORT(___ksymtab_unused+*)) }\n\t__ksymtab_unused_gpl\t0 : { *(SORT(___ksymtab_unused_gpl+*)) }\n\t__ksymtab_gpl_future\t0 : { *(SORT(___ksymtab_gpl_future+*)) }\n\t__kcrctab\t\t0 : { *(SORT(___kcrctab+*)) }\n\t__kcrctab_gpl\t\t0 : { *(SORT(___kcrctab_gpl+*)) }\n\t__kcrctab_unused\t0 : { *(SORT(___kcrctab_unused+*)) }\n\t__kcrctab_unused_gpl\t0 : { *(SORT(___kcrctab_unused_gpl+*)) }\n\t__kcrctab_gpl_future\t0 : { *(SORT(___kcrctab_gpl_future+*)) }\n\n\t.init_array\t\t0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) }\n\n\t__jump_table\t\t0 : ALIGN(8) { KEEP(*(__jump_table)) }\n}\n"
  },
  {
    "path": "Units/parser-ldscript.r/versions.d/README",
    "content": "This test case is taken from linux/arch/arm64/kernel/vdso/vdso.lds.S.\n"
  },
  {
    "path": "Units/parser-ldscript.r/versions.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ldscript.r/versions.d/expected.tags",
    "content": "_vdso_data\tinput.lds\t/^\tPROVIDE(_vdso_data = . - PAGE_SIZE);$/;\"\ts\tassignment:provide\n.hash\tinput.lds\t/^\t.hash\t\t: { *(.hash) }\t\t\t:text$/;\"\tS\n.gnu.hash\tinput.lds\t/^\t.gnu.hash\t: { *(.gnu.hash) }$/;\"\tS\n.dynsym\tinput.lds\t/^\t.dynsym\t\t: { *(.dynsym) }$/;\"\tS\n.dynstr\tinput.lds\t/^\t.dynstr\t\t: { *(.dynstr) }$/;\"\tS\n.gnu.version\tinput.lds\t/^\t.gnu.version\t: { *(.gnu.version) }$/;\"\tS\n.gnu.version_d\tinput.lds\t/^\t.gnu.version_d\t: { *(.gnu.version_d) }$/;\"\tS\n.gnu.version_r\tinput.lds\t/^\t.gnu.version_r\t: { *(.gnu.version_r) }$/;\"\tS\n.note\tinput.lds\t/^\t.note\t\t: { *(.note.*) }\t\t:text\t:note$/;\"\tS\n.text\tinput.lds\t/^\t.text\t\t: { *(.text*) }\t\t\t:text\t=0xd503201f$/;\"\tS\n__etext\tinput.lds\t/^\tPROVIDE (__etext = .);$/;\"\ts\tassignment:provide\n_etext\tinput.lds\t/^\tPROVIDE (_etext = .);$/;\"\ts\tassignment:provide\netext\tinput.lds\t/^\tPROVIDE (etext = .);$/;\"\ts\tassignment:provide\n.eh_frame_hdr\tinput.lds\t/^\t.eh_frame_hdr\t: { *(.eh_frame_hdr) }\t\t:text\t:eh_frame_hdr$/;\"\tS\n.eh_frame\tinput.lds\t/^\t.eh_frame\t: { KEEP (*(.eh_frame)) }\t:text$/;\"\tS\n.dynamic\tinput.lds\t/^\t.dynamic\t: { *(.dynamic) }\t\t:text\t:dynamic$/;\"\tS\n.rodata\tinput.lds\t/^\t.rodata\t\t: { *(.rodata*) }\t\t:text$/;\"\tS\n_end\tinput.lds\t/^\t_end = .;$/;\"\ts\nend\tinput.lds\t/^\tPROVIDE(end = .);$/;\"\ts\tassignment:provide\nLINUX_2.6.39\tinput.lds\t/^\tLINUX_2.6.39 {$/;\"\tv\nVDSO_sigtramp\tinput.lds\t/^VDSO_sigtramp\t\t= __kernel_rt_sigreturn;$/;\"\ts\n"
  },
  {
    "path": "Units/parser-ldscript.r/versions.d/input.lds",
    "content": "/*\n * GNU linker script for the VDSO library.\n*\n * Copyright (C) 2012 ARM Limited\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n *\n * Author: Will Deacon <will.deacon@arm.com>\n * Heavily based on the vDSO linker scripts for other archs.\n */\n\n#include <linux/const.h>\n#include <asm/page.h>\n#include <asm/vdso.h>\n\nOUTPUT_FORMAT(\"elf64-littleaarch64\", \"elf64-bigaarch64\", \"elf64-littleaarch64\")\nOUTPUT_ARCH(aarch64)\n\nSECTIONS\n{\n\tPROVIDE(_vdso_data = . - PAGE_SIZE);\n\t. = VDSO_LBASE + SIZEOF_HEADERS;\n\n\t.hash\t\t: { *(.hash) }\t\t\t:text\n\t.gnu.hash\t: { *(.gnu.hash) }\n\t.dynsym\t\t: { *(.dynsym) }\n\t.dynstr\t\t: { *(.dynstr) }\n\t.gnu.version\t: { *(.gnu.version) }\n\t.gnu.version_d\t: { *(.gnu.version_d) }\n\t.gnu.version_r\t: { *(.gnu.version_r) }\n\n\t.note\t\t: { *(.note.*) }\t\t:text\t:note\n\n\t. = ALIGN(16);\n\n\t.text\t\t: { *(.text*) }\t\t\t:text\t=0xd503201f\n\tPROVIDE (__etext = .);\n\tPROVIDE (_etext = .);\n\tPROVIDE (etext = .);\n\n\t.eh_frame_hdr\t: { *(.eh_frame_hdr) }\t\t:text\t:eh_frame_hdr\n\t.eh_frame\t: { KEEP (*(.eh_frame)) }\t:text\n\n\t.dynamic\t: { *(.dynamic) }\t\t:text\t:dynamic\n\n\t.rodata\t\t: { *(.rodata*) }\t\t:text\n\n\t_end = .;\n\tPROVIDE(end = .);\n\n\t/DISCARD/\t: {\n\t\t*(.note.GNU-stack)\n\t\t*(.data .data.* .gnu.linkonce.d.* .sdata*)\n\t\t*(.bss .sbss .dynbss .dynsbss)\n\t}\n}\n\n/*\n * We must supply the ELF program headers explicitly to get just one\n * PT_LOAD segment, and set the flags explicitly to make segments read-only.\n */\nPHDRS\n{\n\ttext\t\tPT_LOAD\t\tFLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */\n\tdynamic\t\tPT_DYNAMIC\tFLAGS(4);\t\t/* PF_R */\n\tnote\t\tPT_NOTE\t\tFLAGS(4);\t\t/* PF_R */\n\teh_frame_hdr\tPT_GNU_EH_FRAME;\n}\n\n/*\n * This controls what symbols we export from the DSO.\n */\nVERSION\n{\n\tLINUX_2.6.39 {\n\tglobal:\n\t\t__kernel_rt_sigreturn;\n\t\t__kernel_gettimeofday;\n\t\t__kernel_clock_gettime;\n\t\t__kernel_clock_getres;\n\tlocal: *;\n\t};\n}\n\n/*\n * Make the sigreturn code visible to the kernel.\n */\nVDSO_sigtramp\t\t= __kernel_rt_sigreturn;\n"
  },
  {
    "path": "Units/parser-lex.r/simple-lex.d/args.ctags",
    "content": "--sort=no\n--fields=+lr\n--extras=+gr\n"
  },
  {
    "path": "Units/parser-lex.r/simple-lex.d/expected.tags",
    "content": "B_ENVIRONMENT\tinput.l\t/^%x B_ENVIRONMENT E_ENVIRONMENT VERBATIM INCLUDE MATH COMMENT VERB DEF$/;\"\tc\tlanguage:LEX\troles:def\nE_ENVIRONMENT\tinput.l\t/^%x B_ENVIRONMENT E_ENVIRONMENT VERBATIM INCLUDE MATH COMMENT VERB DEF$/;\"\tc\tlanguage:LEX\troles:def\nVERBATIM\tinput.l\t/^%x B_ENVIRONMENT E_ENVIRONMENT VERBATIM INCLUDE MATH COMMENT VERB DEF$/;\"\tc\tlanguage:LEX\troles:def\nINCLUDE\tinput.l\t/^%x B_ENVIRONMENT E_ENVIRONMENT VERBATIM INCLUDE MATH COMMENT VERB DEF$/;\"\tc\tlanguage:LEX\troles:def\nMATH\tinput.l\t/^%x B_ENVIRONMENT E_ENVIRONMENT VERBATIM INCLUDE MATH COMMENT VERB DEF$/;\"\tc\tlanguage:LEX\troles:def\nCOMMENT\tinput.l\t/^%x B_ENVIRONMENT E_ENVIRONMENT VERBATIM INCLUDE MATH COMMENT VERB DEF$/;\"\tc\tlanguage:LEX\troles:def\nVERB\tinput.l\t/^%x B_ENVIRONMENT E_ENVIRONMENT VERBATIM INCLUDE MATH COMMENT VERB DEF$/;\"\tc\tlanguage:LEX\troles:def\nDEF\tinput.l\t/^%x B_ENVIRONMENT E_ENVIRONMENT VERBATIM INCLUDE MATH COMMENT VERB DEF$/;\"\tc\tlanguage:LEX\troles:def\nAFTER_DISPLAY\tinput.l\t/^%x AFTER_DISPLAY ENV_DEF ICOR GETICOR$/;\"\tc\tlanguage:LEX\troles:def\nENV_DEF\tinput.l\t/^%x AFTER_DISPLAY ENV_DEF ICOR GETICOR$/;\"\tc\tlanguage:LEX\troles:def\nICOR\tinput.l\t/^%x AFTER_DISPLAY ENV_DEF ICOR GETICOR$/;\"\tc\tlanguage:LEX\troles:def\nGETICOR\tinput.l\t/^%x AFTER_DISPLAY ENV_DEF ICOR GETICOR$/;\"\tc\tlanguage:LEX\troles:def\nSTART\tinput.l\t/^%s START$/;\"\tc\tlanguage:LEX\troles:def\nb_group\tinput.l\t/^b_group (\"{\"|\\\\\\\\bgroup)$/;\"\tr\tlanguage:LEX\troles:def\ne_group\tinput.l\t/^e_group (\"}\"|\\\\\\\\egroup)$/;\"\tr\tlanguage:LEX\troles:def\nb_math\tinput.l\t/^b_math \\\\\\\\\\\\($/;\"\tr\tlanguage:LEX\troles:def\ne_math\tinput.l\t/^e_math \\\\\\\\\\\\)$/;\"\tr\tlanguage:LEX\troles:def\nmath\tinput.l\t/^math \\\\\\$$/;\"\tr\tlanguage:LEX\troles:def\nb_display\tinput.l\t/^b_display \\\\\\\\\\\\[$/;\"\tr\tlanguage:LEX\troles:def\ne_display\tinput.l\t/^e_display \\\\\\\\\\\\]$/;\"\tr\tlanguage:LEX\troles:def\ndisplay\tinput.l\t/^display \\\\$\\\\\\$$/;\"\tr\tlanguage:LEX\troles:def\npar\tinput.l\t/^par ([ \\\\t]*\\\\n[ \\\\t]*\\\\n[ \\\\t\\\\n]*)$/;\"\tr\tlanguage:LEX\troles:def\nnon_par_ws\tinput.l\t/^non_par_ws ([ \\\\t]+\\\\n?[ \\\\t]*|[ \\\\t]*\\\\n[ \\\\t]*|[ \\\\t]*\\\\n?[ \\\\t]+)$/;\"\tr\tlanguage:LEX\troles:def\nws\tinput.l\t/^ws [ \\\\n\\\\t](%[^\\\\n]\\\\n)*$/;\"\tr\tlanguage:LEX\troles:def\nspace\tinput.l\t/^space ({ws}|\\\\~|\\\\\\\\space)$/;\"\tr\tlanguage:LEX\troles:def\nhard_space\tinput.l\t/^hard_space (\\\\~|\\\\\\\\space)$/;\"\tr\tlanguage:LEX\troles:def\nu_letter\tinput.l\t/^u_letter [A-ZÆØÅ] $/;\"\tr\tlanguage:LEX\troles:def\nl_letter\tinput.l\t/^l_letter [a-zæøå] $/;\"\tr\tlanguage:LEX\troles:def\npunct\tinput.l\t/^punct [\\\\!\\\\.\\\\?]$/;\"\tr\tlanguage:LEX\troles:def\natoz\tinput.l\t/^atoz [a-zA-Z]$/;\"\tr\tlanguage:LEX\troles:def\nletter\tinput.l\t/^letter [A-ZÆØÅa-zæøå]$/;\"\tr\tlanguage:LEX\troles:def\nc_bin\tinput.l\t/^c_bin (\"-\"|\"+\"|\"\\\\\\\\cdot\"|\"\\\\\\\\oplus\"|\"\\\\\\\\otimes\"|\"\\\\\\\\times\")$/;\"\tr\tlanguage:LEX\troles:def\nl_bin\tinput.l\t/^l_bin (\",\")$/;\"\tr\tlanguage:LEX\troles:def\ngeneral_abbrev\tinput.l\t/^general_abbrev {letter}+{punct}$/;\"\tr\tlanguage:LEX\troles:def\nnon_abbrev\tinput.l\t/^non_abbrev {u_letter}{u_letter}+{punct}$/;\"\tr\tlanguage:LEX\troles:def\nitalic_spec\tinput.l\t/^italic_spec (sl|it)$/;\"\tr\tlanguage:LEX\troles:def\nnormal_spec\tinput.l\t/^normal_spec normalshape$/;\"\tr\tlanguage:LEX\troles:def\nswap_spec\tinput.l\t/^swap_spec em$/;\"\tr\tlanguage:LEX\troles:def\nfont_spec\tinput.l\t/^font_spec (rm|bf|{italic_spec}|tt|{swap_spec}|mediumseries|{normal_spec})$/;\"\tr\tlanguage:LEX\troles:def\nprimitive\tinput.l\t/^primitive \\\\\\\\(above|advance|catcode|chardef|closein|closeout|copy|count|countdef|cr|crcr|csname/;\"\tr\tlanguage:LEX\troles:def\nsymbol\tinput.l\t/^symbol (\"$\"(\"\\\\\\\\\"{atoz}+|.)\"$\"|\"\\\\\\\\#\"|\"\\\\\\\\$\"|\"\\\\\\\\%\"|\"\\\\\\\\ref\")$/;\"\tr\tlanguage:LEX\troles:def\nB_ENVIRONMENT\tinput.l\t/^<B_ENVIRONMENT> {$/;\"\tc\tlanguage:LEX\troles:grouping\nstdio.h\tinput.l\t/^#include <stdio.h>/;\"\th\tlanguage:C\troles:system\nstring.h\tinput.l\t/^#include <string.h>/;\"\th\tlanguage:C\troles:system\nwin32lib.h\tinput.l\t/^#include <win32lib.h>/;\"\th\tlanguage:C\troles:system\nYY_SKIP_YYWRAP\tinput.l\t/^#define YY_SKIP_YYWRAP$/;\"\td\tlanguage:C\tfile:\troles:def\nyywrap\tinput.l\t/^int yywrap() { return 1; }$/;\"\tf\tlanguage:C\ttyperef:typename:int\troles:def\nGROUP_STACK_SIZE\tinput.l\t/^#define GROUP_STACK_SIZE /;\"\td\tlanguage:C\tfile:\troles:def\nINPUT_STACK_SIZE\tinput.l\t/^#define INPUT_STACK_SIZE /;\"\td\tlanguage:C\tfile:\troles:def\nPROGNAME\tinput.l\t/^#define PROGNAME /;\"\td\tlanguage:C\tfile:\troles:def\nCG_NAME\tinput.l\t/^#define CG_NAME /;\"\td\tlanguage:C\tfile:\troles:def\nCG_TYPE\tinput.l\t/^#define CG_TYPE /;\"\td\tlanguage:C\tfile:\troles:def\nCG_LINE\tinput.l\t/^#define CG_LINE /;\"\td\tlanguage:C\tfile:\troles:def\nCG_ITALIC\tinput.l\t/^#define CG_ITALIC /;\"\td\tlanguage:C\tfile:\troles:def\nCG_FILE\tinput.l\t/^#define CG_FILE /;\"\td\tlanguage:C\tfile:\troles:def\nreturnval\tinput.l\t/^char returnval[100];$/;\"\tv\tlanguage:C\ttyperef:typename:char[100]\troles:def\nline_count\tinput.l\t/^int line_count = 1;$/;\"\tv\tlanguage:C\ttyperef:typename:int\troles:def\nwarn_count\tinput.l\t/^int warn_count = 0;$/;\"\tv\tlanguage:C\ttyperef:typename:int\troles:def\nfile_name\tinput.l\t/^char *file_name;$/;\"\tv\tlanguage:C\ttyperef:typename:char *\troles:def\nverb_char\tinput.l\t/^char verb_char;$/;\"\tv\tlanguage:C\ttyperef:typename:char\troles:def\ntex_group\tinput.l\t/^typedef struct tex_group $/;\"\ts\tlanguage:C\tfile:\troles:def\ns_name\tinput.l\t/^    unsigned char *s_name;$/;\"\tm\tlanguage:C\tstruct:tex_group\ttyperef:typename:unsigned char *\tfile:\troles:def\ns_type\tinput.l\t/^    int s_type;$/;\"\tm\tlanguage:C\tstruct:tex_group\ttyperef:typename:int\tfile:\troles:def\ns_line\tinput.l\t/^    int s_line;$/;\"\tm\tlanguage:C\tstruct:tex_group\ttyperef:typename:int\tfile:\troles:def\nitalic\tinput.l\t/^    int italic;$/;\"\tm\tlanguage:C\tstruct:tex_group\ttyperef:typename:int\tfile:\troles:def\ns_file\tinput.l\t/^    char *s_file; $/;\"\tm\tlanguage:C\tstruct:tex_group\ttyperef:typename:char *\tfile:\troles:def\ntex_group\tinput.l\t/^ } tex_group;$/;\"\tt\tlanguage:C\ttyperef:struct:tex_group\tfile:\troles:def\ngstack\tinput.l\t/^tex_group *gstack;$/;\"\tv\tlanguage:C\ttyperef:typename:tex_group *\troles:def\ngstack_size\tinput.l\t/^int gstack_size = GROUP_STACK_SIZE;$/;\"\tv\tlanguage:C\ttyperef:typename:int\troles:def\ngstackp\tinput.l\t/^int gstackp = 0;$/;\"\tv\tlanguage:C\ttyperef:typename:int\troles:def\ninput_\tinput.l\t/^typedef struct input_ $/;\"\ts\tlanguage:C\tfile:\troles:def\nstream\tinput.l\t/^    YY_BUFFER_STATE stream;$/;\"\tm\tlanguage:C\tstruct:input_\ttyperef:typename:YY_BUFFER_STATE\tfile:\troles:def\nname\tinput.l\t/^    char *name;$/;\"\tm\tlanguage:C\tstruct:input_\ttyperef:typename:char *\tfile:\troles:def\nlinenum\tinput.l\t/^    int linenum;$/;\"\tm\tlanguage:C\tstruct:input_\ttyperef:typename:int\tfile:\troles:def\ninput_\tinput.l\t/^ } input_;$/;\"\tt\tlanguage:C\ttyperef:struct:input_\tfile:\troles:def\nistack\tinput.l\t/^input_ *istack;$/;\"\tv\tlanguage:C\ttyperef:typename:input_ *\troles:def\nistack_size\tinput.l\t/^int istack_size = INPUT_STACK_SIZE;$/;\"\tv\tlanguage:C\ttyperef:typename:int\troles:def\nistackp\tinput.l\t/^int istackp = 0;$/;\"\tv\tlanguage:C\ttyperef:typename:int\troles:def\ndef_count\tinput.l\t/^int def_count = 0;$/;\"\tv\tlanguage:C\ttyperef:typename:int\troles:def\nmain\tinput.l\t/^int main( argc, argv )$/;\"\tf\tlanguage:C\troles:def\nstrstr\tinput.l\t/^strstr(string, substring)$/;\"\tf\tlanguage:C\troles:def\npush\tinput.l\t/^void push(p_name, p_type, p_line)$/;\"\tf\tlanguage:C\troles:def\ninput_file\tinput.l\t/^void input_file(file_nam)$/;\"\tf\tlanguage:C\troles:def\npop\tinput.l\t/^void pop()$/;\"\tf\tlanguage:C\ttyperef:typename:void\troles:def\nbg_command\tinput.l\t/^char *bg_command(name)$/;\"\tf\tlanguage:C\troles:def\neg_command\tinput.l\t/^char *eg_command(name,type)$/;\"\tf\tlanguage:C\troles:def\ng_checkend\tinput.l\t/^void g_checkend(n)$/;\"\tf\tlanguage:C\troles:def\ne_checkend\tinput.l\t/^void e_checkend(n, name)$/;\"\tf\tlanguage:C\troles:def\nf_checkend\tinput.l\t/^void f_checkend(name)$/;\"\tf\tlanguage:C\troles:def\nprint_bad_match\tinput.l\t/^void print_bad_match(end_command,type)$/;\"\tf\tlanguage:C\troles:def\ncheck_top_level_end\tinput.l\t/^int check_top_level_end(end_command,type)$/;\"\tf\tlanguage:C\troles:def\nlinecount\tinput.l\t/^void linecount()$/;\"\tf\tlanguage:C\ttyperef:typename:void\troles:def\n"
  },
  {
    "path": "Units/parser-lex.r/simple-lex.d/input.l",
    "content": "/* \n * Taken from texlive-2007/texk/lacheck/lacheck.lex\n * with a minor modification.\n */\n\n/*                    -*- Mode: C -*-\n * \n * lacheck.lex - A consistency checker checker for LaTeX documents\n *\t\n * Copyright (C) 1991, 1992 Kresten Krab Thorup.\n * Copyright (C) 1993 --- 1998 Per Abrahamsen.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 1, or (at your option)\n * any later version.\n * \n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n * \n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n *\n * Please send bugs, suggestions, and queries to auc-tex_mgr@sunsite.auc.dk.\n * \n * $Revision: 1.26 $\n * Author          : Kresten Krab Thorup\n * Created On      : Sun May 26 18:11:58 1991\n * \n * HISTORY\n * 07-Mar-1998\t\tPer Abrahamsen\n *    Added return to yywrap.  Patch by Fabrice POPINEAU \n *    <popineau@esemetz.ese-metz.fr>.\n * 14-Jan-1998\t\tPer Abrahamsen\n *    Added GPL blurp.\n * 27-Oct-1997\t\tPer Abrahamsen\n *    Count newline after newenvironment and newcommand.\n * 12-Jan-1996          Per Abrahamsen\n *    \\\\} used not to end a group in definitions.  Reported by Piet\n *    van Oostrum <piet@cs.ruu.nl>.\n * 03-Jan-1995\t\tPer Abrahamsen\n *    Fix bug which prevented detection of multiple illegal characters\n *    in labels.  Reported by eeide@jaguar.cs.utah.edu (Eric Eide).\n * 30-Jul-1994\t\tPer Abrahamsen\n *    Define dummy yywrap so we no longer depend on `libl.a'.\n * 26-Apr-1994\t\tPer Abrahamsen\n *    Removed a few warnings, by Richard Lloyd <R.K.Lloyd@csc.liv.ac.uk>.\n * 23-Apr-1994\t\tPer Abrahamsen\n *    Changed all `%i' to `%d' for VMS portability.  Reported by\n *    Stephen Harker <PHS172M@vaxc.cc.monash.edu.au>.\n * 16-Feb-1994\t\tPer Abrahamsen\n *    Try file name with `.tex' appended before trying it bare.  This\n *    will make the case where a directory and a TeX file share the\n *    same name work.\n * 19-Jan-1994\t\tPer Abrahamsen\n *    Comments don't imply whitespace.  Pointed out by Jacco van\n *    Ossenbruggen <jrvosse@cs.vu.nl>.\n * 14-Jan-1994\t\tPer Abrahamsen\n *    Don't complain about \\ref at the beginning of a paragraph.\n *    Suggested by Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>.\n * 11-Jan-1994\t\tPer Abrahamsen\n *    Added version string to usage message.  Suggested by Uwe Bonnes\n *    <bon@LTE.E-TECHNIK.uni-erlangen.de> .\n * 04-Jan-1994\t\tPer Abrahamsen\n *    Warn about newlines in \\verb.  Suggested by Mark Burton\n *    <markb@ordern.demon.co.uk>.  The LaTeX Book agrees (p. 168).\n * 10-Sep-1993          Per Abrahamsen\n *    Removed complain about missing ~ before \\cite.  Requested by \n *    Nelson H. F. Beebe <beebe@math.utah.edu>.  The LaTeX Book seems\n *    to agree.  \n * 03-Sep-1993\t        Per Abrahamsen\n *    Check for illegal characters in labels.\n * 16-Aug-1993\t        Per Abrahamsen\n *    Recognize \\endinput.  Suggested by Stefan Farestam\n *    <Stefan.Farestam@cerfacs.fr>.\n * 13-Aug-1993          Per Abrahamsen\n *    } was eaten after display math.  Reported by Eckhard Rüggeberg\n *    <eckhard@ts.go.dlr.de>.\n * 13-Aug-1993          Per Abrahamsen\n *    Recognize \\verb*.  Reported by Eckhard Rüggeberg\n *    <eckhard@ts.go.dlr.de>.  \n * 08-Aug-1993          Per Abrahamsen\n *    Better catch begin and end without arguments.\n * 08-Aug-1993          Per Abrahamsen\n *    Removed free(NULL) as reported by Darrel R. Hankerson \n *    <hankedr@mail.auburn.edu>.\n * 08-Aug-1993\t\tPer Abrahamsen\n *    Removed declaration of realloc for some C compilers.  Reported by \n *    Darrel R. Hankerson <hankedr@mail.auburn.edu>\n * 30-Jul-1993          Per Abrahamsen\n *    Added check for italic correction after normal text.\n * 29-Jul-1993          Per Abrahamsen\n *    Added cast for (char*) malloc as suggested by John Interrante\n *    <interran@uluru.Stanford.EDU>.\n * 29-Jul-1993          Per Abrahamsen\n *    Added check for missing and extra italic correction.\n * 29-Jul-1993\t        Per Abrahamsen\n *    Made line number counting more reliable (but it still needs a rewrite)!\n * 28-Jul-1993\t        Per Abrahamsen\n *    Added check for italic correction before point or comma.\n * 6-Jun-1992\t\tKresten Krab Thorup\t\n *    Last Modified: Sat Jun  6 16:37:44 1992 #48 (Kresten Krab Thorup)\n *    Added test for whitespace before punctuation mark\n * 17-Dec-1991  (Last Mod: Tue Dec 17 21:01:24 1991 #41)  Kresten Krab Thorup\n *    Added 'word word` and missing ~ before cite and ref\n * 18-Jun-1991  (Last Mod: Tue Jun 18 19:20:43 1991 #17)  Kresten Krab Thorup\n *    Added check (or rather management) for \\newenvironment and\n *    \\newcommand - as suggested by Per Abrahamsen abrham@hugin.dk\n * 30-May-1991  (Last Mod: Thu May 30 02:22:33 1991 #15)  Kresten Krab Thorup\n *    Added check for `$${punct}' and `{punct}$' constructions\n * 30-May-1991  (Last Mod: Wed May 29 10:31:35 1991 #6)  Kresten Krab Thorup\n *    Improved (dynamic) stack management from Andreas Stolcke ...\n *                                       <stolcke@ICSI.Berkeley.EDU> \n * 26-May-1991  Kresten Krab Thorup\n *    Initial distribution version.\n */\n\n%{ \n\n#include <stdio.h>\n#include <string.h>\n\n#ifdef WIN32\n#include <win32lib.h>\n#endif\n/* #include <sys/param.h> */\n\n/* extern char *realloc(); */\n\n#define YY_SKIP_YYWRAP\nint yywrap() { return 1; }\n\n#ifdef NEED_STRSTR\nchar *strstr();\n#endif\n\n#define GROUP_STACK_SIZE 10\n#define INPUT_STACK_SIZE 10\n\n#define PROGNAME \"LaCheck\"\n\n  /* macros */\n\n#define CG_NAME (char *)gstack[gstackp-1].s_name\n#define CG_TYPE gstack[gstackp-1].s_type\n#define CG_LINE gstack[gstackp-1].s_line\n#define CG_ITALIC gstack[gstackp-1].italic\n#define CG_FILE gstack[gstackp-1].s_file\n\nchar *bg_command();\nvoid pop();\nvoid push();\nvoid linecount();\nvoid g_checkend();\nvoid e_checkend();\nvoid f_checkend();\nvoid input_file();\nvoid print_bad_match();\nint check_top_level_end();\n\n  /* global variables */\n\nchar returnval[100];\nint line_count = 1;\nint warn_count = 0;\nchar *file_name;\nchar verb_char;\n\n  /* the group stack */\n\ntypedef struct tex_group \n {\n    unsigned char *s_name;\n    int s_type;\n    int s_line;\n    int italic;\n    char *s_file; \n } tex_group;\n\ntex_group *gstack;\nint gstack_size = GROUP_STACK_SIZE;\nint gstackp = 0;\n\ntypedef struct input_ \n {\n    YY_BUFFER_STATE stream;\n    char *name;\n    int linenum;\n } input_;\n\ninput_ *istack;\nint istack_size = INPUT_STACK_SIZE;\nint istackp = 0;\n\nint def_count = 0;\n\n%}\n\n%x B_ENVIRONMENT E_ENVIRONMENT VERBATIM INCLUDE MATH COMMENT VERB DEF\n%x AFTER_DISPLAY ENV_DEF ICOR GETICOR\n\n%s START\n\nb_group (\"{\"|\\\\bgroup)\ne_group (\"}\"|\\\\egroup)\n\nb_math \\\\\\(\ne_math \\\\\\)\nmath \\$\n\nb_display \\\\\\[\ne_display \\\\\\]\ndisplay \\$\\$\n\npar ([ \\t]*\\n[ \\t]*\\n[ \\t\\n]*)\nnon_par_ws ([ \\t]+\\n?[ \\t]*|[ \\t]*\\n[ \\t]*|[ \\t]*\\n?[ \\t]+)\n\nws [ \\n\\t](%[^\\n]\\n)*\nspace ({ws}|\\~|\\\\space)\nhard_space (\\~|\\\\space)\n\nu_letter [A-ZÆØÅ] \nl_letter [a-zæøå] \npunct [\\!\\.\\?]\natoz [a-zA-Z]\nletter [A-ZÆØÅa-zæøå]\n\nc_bin (\"-\"|\"+\"|\"\\\\cdot\"|\"\\\\oplus\"|\"\\\\otimes\"|\"\\\\times\")\nl_bin (\",\")\n\ngeneral_abbrev {letter}+{punct}\n\nnon_abbrev {u_letter}{u_letter}+{punct}\n\nitalic_spec (sl|it)\nnormal_spec normalshape\nswap_spec em\nfont_spec (rm|bf|{italic_spec}|tt|{swap_spec}|mediumseries|{normal_spec})\n\nprimitive \\\\(above|advance|catcode|chardef|closein|closeout|copy|count|countdef|cr|crcr|csname|delcode|dimendef|dimen|divide|expandafter|font|hskp|vskip|openout)\n\nsymbol (\"$\"(\"\\\\\"{atoz}+|.)\"$\"|\"\\\\#\"|\"\\\\$\"|\"\\\\%\"|\"\\\\ref\")\n\n%%\n\n<*>\"\\\\\\\\\" { ; }\n\n<ENV_DEF,DEF,INITIAL>\"\\\\\\%\" { ; }\n\n<ICOR,GETICOR,ENV_DEF,DEF,INITIAL>\"%\"[^\\n]*\\n { line_count++; }\n\n<ICOR,GETICOR,ENV_DEF,DEF,INITIAL>\\n \t{ line_count++; }\n\n<ENV_DEF,DEF,INITIAL>\"\\\\\\{\" { ; }\n\n<ENV_DEF,DEF,INITIAL>\"\\\\\\}\" { ; }\n\n\"\\\\\\$\" { ; }\n\n<ICOR,INITIAL,GETICOR>\"{\"{ws} {  \n  if (CG_TYPE != 4 && CG_TYPE != 5) {\n    if (!(CG_TYPE == 2 && strstr(CG_NAME, \"array\"))) {\n      printf( \"\\\"%s\\\", line %d: possible unwanted space at \\\"{\\\"\\n\", \n\t     file_name, line_count); \n      ++warn_count ;\n    }\n  }\n  push( \"{\", 0, line_count);\n  linecount();\n }\n\n<ICOR,INITIAL,GETICOR>{b_group} {  push( \"{\", 0, line_count);}\n\n<INITIAL,GETICOR>{e_group} {  \n  {\n    int italic = CG_ITALIC;\n    g_checkend(0); \n    if (italic && !CG_ITALIC)\n      BEGIN(GETICOR) ;\n    else\n      BEGIN(INITIAL);\n  }}\n\n<ICOR>{e_group} {  g_checkend(0); }\n\n<GETICOR>[A-Za-zæøåÆØÅ0-9;:!()]+ {\n {\n   if (!CG_ITALIC)\n     {\n       printf(\"\\\"%s\\\", line %d: you may need a \\\\/ before \\\"%s\\\"\\n\",\n\t      file_name, line_count, yytext); \n       ++warn_count;\n     }\n    BEGIN(INITIAL); \n }}\n\n<ICOR>[A-Za-zæøåÆØÅ0-9;:!?()`']+ {\n {\n   if (CG_ITALIC)\n     {\n       printf(\"\\\"%s\\\", line %d: \\\\/ not needed before italic text \\\"%s\\\"\\n\",\n\t      file_name, line_count, yytext); \n       ++warn_count;\n     }\n    BEGIN(INITIAL); \n }}\n\n^[A-Za-zæøåÆØÅ0-9;:!?()`',.]+{ws}*/\\\\\\/ {\n  {\n   linecount();\n   if (!CG_ITALIC)\n     {\n       printf(\"\\\"%s\\\", line %d: \\\\/ not needed after non-italic text \\\"%s\\\"\\n\",\n              file_name, line_count, yytext);\n       ++warn_count;\n     }\n }}\n\n{ws}[A-Za-zæøåÆØÅ0-9;:!?()`',.]+{ws}*/\\\\\\/ {\n  {\n   linecount();\n   if (!CG_ITALIC)\n     {\n       printf(\"\\\"%s\\\", line %d: \\\\/ is not needed after non-italic \\\"%s\\\"\\n\",\n              file_name, line_count, yytext);\n       ++warn_count;\n     }\n }}\n\n<GETICOR>\\\\\\/ { BEGIN(INITIAL); }\n\n<INITIAL>\\\\\\/ { BEGIN(ICOR); }\n\n<ICOR>\\\\\\/ {\n  {\n    printf(\"\\\"%s\\\", line %d: double \\\\/ found \\\"%s\\\"\\n\",\n           file_name, line_count, yytext);\n    ++warn_count;\n    BEGIN(ICOR);\n  }}\n\n<INITIAL,GETICOR,ICOR>\\\\{italic_spec}/[^a-zA-Z] { CG_ITALIC = 1; }\n\n<INITIAL,GETICOR>\\\\{normal_spec}/[^a-zA-Z] {\n  {\n    if(CG_ITALIC)\n      BEGIN(GETICOR);\n    else\n      BEGIN(INITIAL);\n    CG_ITALIC = 0;\n  }}\n\n<ICOR>\\\\{normal_spec}/[^a-zA-Z] { CG_ITALIC = 0; }\n\n<INITIAL,GETICOR>\\\\{swap_spec}/[^a-zA-Z] {\n  {\n    if(CG_ITALIC)\n      BEGIN(GETICOR);\n    else\n      BEGIN(INITIAL);\n    CG_ITALIC = !CG_ITALIC;\n  }}\n\n<ICOR>\\\\{swap_spec}/[^a-zA-Z] { CG_ITALIC = !CG_ITALIC; }\n\n<ICOR>[,.] {\n {\n    printf(\"\\\"%s\\\", line %d: do not use \\\\/ before \\\"%s\\\"\\n\",\n\t   file_name, line_count, yytext); \n    ++warn_count; \n    BEGIN(INITIAL);\n }}\n\n<GETICOR,ICOR>{ws} { ; }\n\n<GETICOR,ICOR>~ { ; }\n\n<GETICOR,ICOR>[^\\n] { \n  {\n    unput(yytext[0]);\n    BEGIN(INITIAL); \n  }}\n\n\"\\\\\"[exg]?(def|newcommand)[^\\n\\{]+ \tBEGIN(DEF);\n\n<DEF>{b_group} { ++def_count; }\n\n<DEF>{e_group} { --def_count;\n\t\t if(def_count == 0)\n\t\t     BEGIN(INITIAL); }\n\n<DEF>. { ; }\n\n\"\\\\\"newenvironment\"{\"[a-zA-Z]+\"}\"[^\\n\\{]+ \tBEGIN(ENV_DEF);\n\n<ENV_DEF>{b_group} { ++def_count; }\n\n<ENV_DEF>{e_group} { --def_count;\n\t\t if(def_count == 0)\n\t\t     BEGIN(DEF); }\n\n<ENV_DEF>. { ; }\n\n{b_math} {\n    if(CG_TYPE == 4 || CG_TYPE == 5)\n\tprint_bad_match(yytext,4);\n    else\n    {\n\tpush( yytext, 4, line_count);\n    }}\n\n{e_math} {  g_checkend(4); }\n\n{b_display} {\n    if(CG_TYPE == 4 || CG_TYPE == 5)\n\tprint_bad_match(yytext,5);\n    else \n    {\n\tpush( yytext, 5, line_count);\n    }}\n\n\n{e_display} {  g_checkend(5);     BEGIN(AFTER_DISPLAY);}\n\n<AFTER_DISPLAY>{punct} { \n\n    printf( \"\\\"%s\\\", line %d: punctuation mark \\\"%s\\\" should be placed before end of displaymath\\n\", \n\t   file_name, line_count, yytext); \n    ++warn_count ; \n\n  BEGIN(INITIAL); }\n\n<AFTER_DISPLAY>(\\n|.) { unput(yytext[0]); BEGIN(INITIAL); }\n\n<ICOR,INITIAL,GETICOR>{punct}/(\"\\$\"|\"\\\\)\") { if (CG_TYPE == 4)\n       {\n\t printf( \"\\\"%s\\\", line %d: punctuation mark \\\"%s\\\" should be placed after end of math mode\\n\", \n\t\tfile_name, line_count, yytext); \n\t ++warn_count ;\n\t BEGIN(INITIAL);\n       }}\n\n{math} {\n\n    if(CG_TYPE == 5)\n\tprint_bad_match(yytext, 4);\n    else \n\n    if(CG_TYPE == 4)\n    {\n\te_checkend(4, yytext);\n    }\n    else\n    {\n\tpush( yytext, 4, line_count); \n    }}\n\n\n{display}  {\n\n    if(CG_TYPE == 4)\n\tprint_bad_match(yytext,5);\n    else \n\n    if(CG_TYPE == 5)\n    {\n\te_checkend(5, yytext);\n        BEGIN(AFTER_DISPLAY);\n    }\n    else\n    {\n\tpush( yytext, 5, line_count);\n    }}\n\n\\\\begingroup/[^a-zA-Z]  {\n {\n    push((unsigned char *)\"\\\\begingroup\", 1, line_count); \n }}\n\n\n\\\\endgroup/[^a-zA-Z]  {\n {\n    g_checkend(1);\n }}\n\n\n\\\\begin[ \\t]*\"{\" { BEGIN(B_ENVIRONMENT); }\n\n\\\\begin[ \\t]*(%[^\\n]*)?/\\n { \n {\n    \n    printf(\"\\\"%s\\\", line %d: {argument} missing for \\\\begin\\n\",\n\t   file_name, line_count) ;\n    ++warn_count;\n }}\n\n<B_ENVIRONMENT> {\n\n[^\\}\\n]+ {\n    if (strcmp( yytext, \"verbatim\" ) == 0 )\n\t{\n\t input();\n\t BEGIN(VERBATIM);\n\t}\n    else\n\t{\n    \t push(yytext, 2, line_count);\n\n\t if (   strcmp (yytext, \"sl\" ) == 0\n\t     || strcmp (yytext, \"it\" ) == 0)\n\t   CG_ITALIC = 1;\n\t else if (strcmp (yytext, \"normalshape\") == 0)\n\t   CG_ITALIC = 0;\n\t else if (strcmp (yytext, \"em\") == 0)\n\t   CG_ITALIC = !CG_ITALIC;\n\t   \n \t input();\n\t BEGIN(INITIAL);\n\t}\n }}\n\n<VERBATIM>\\\\end[ \\t]*\\{verbatim\\} { BEGIN(INITIAL); }\n\n<VERBATIM>\\t {\n     printf(\"\\\"%s\\\", line %d: TAB character in verbatim environment\\n\",\n\t   file_name, line_count) ;\n    ++warn_count;\n }\n\n<VERBATIM>. { ; }\n\n<VERBATIM>\\n { ++line_count; }\n\n\n<ICOR,INITIAL,GETICOR>\\\\verb\\*?. { \n          verb_char = yytext[yyleng-1];\n\t  BEGIN(VERB); \n\t}\n\n<VERB>\\n {\n  printf(\"\\\"%s\\\", line %d: \\\\verb should not contain end of line characters\\n\",\n\t file_name, line_count) ;\n  ++line_count;\n} \n\n<VERB>. {\n  if ( *yytext == verb_char )\n    BEGIN(INITIAL); \n} \n\n\n\\\\end[ \\t]*\"{\" { BEGIN(E_ENVIRONMENT); }\n\n\\\\end[ \\t]*(%[^\\n]*)?/\\n { \n {\n    printf(\"\\\"%s\\\", line %d: {argument} missing for \\\\end\\n\",\n\t   file_name, line_count) ;\n    ++warn_count;\n }}\n\n\n<E_ENVIRONMENT>[^\\}\\n]+ { \n {\n    e_checkend(2, yytext);\n    input();\n    \n    BEGIN(INITIAL);\n }}\n\n\n<ICOR,INITIAL,GETICOR>{ws}({letter}\".\")*{letter}*{l_letter}\".\"/{non_par_ws}+{l_letter}    { \n {\n    linecount();\n    printf( \"\\\"%s\\\", line %d: missing `\\\\ ' after \\\"%s\\\"\\n\", \n\t   file_name, line_count, ++yytext); \n    ++warn_count ;\n    BEGIN(INITIAL);\n }}\n\n<ICOR,INITIAL,GETICOR>({l_letter}\".\")*{letter}*{l_letter}\".\"/{non_par_ws}+{l_letter}    { \n {\n    printf( \"\\\"%s\\\", line %d: missing `\\\\ ' after \\\"%s\\\"\\n\", \n\t   file_name, line_count, yytext); \n    ++warn_count ; \n    BEGIN(INITIAL);\n }}\n\n<ICOR,INITIAL,GETICOR>{non_abbrev}/{non_par_ws}{u_letter}   { \n {\n   linecount();\n   printf(\"\\\"%s\\\", line %d: missing `\\\\@' before `.' in \\\"%s\\\"\\n\", \n\t  file_name, line_count, yytext); \n   ++warn_count ; \n   BEGIN(INITIAL);\n }}\n\n<ICOR,INITIAL,GETICOR>({hard_space}{space}|{space}{hard_space})  { \n\n    printf(\"\\\"%s\\\", line %d: double space at \\\"%s\\\"\\n\",\n\t   file_name, line_count, yytext); \n    ++warn_count;\n\tlinecount();\n    BEGIN(INITIAL);\n  }\n\n{c_bin}{ws}?(\\\\(\\.|\\,|\\;|\\:))*{ws}?\\\\ldots{ws}?(\\\\(\\.|\\,|\\;|\\:))*{ws}?{c_bin} {\n\tprintf(\"\\\"%s\\\", line %d: \\\\ldots should be \\\\cdots in \\\"%s\\\"\\n\",\n\t   file_name, line_count, yytext); \n\t++warn_count;\n\tlinecount();\n  }\n\n<ICOR,INITIAL,GETICOR>[^\\\\]{l_bin}{ws}?(\\\\(\\.|\\,|\\;|\\:))*{ws}?\\\\cdots{ws}?(\\\\(\\.|\\,|\\;|\\:))*{ws}?[^\\\\]{l_bin} {\n\tprintf(\"\\\"%s\\\", line %d: \\\\cdots should be \\\\ldots in \\\"%s\\\"\\n\",\n\t   file_name, line_count, yytext); \n\t++warn_count;\n\tlinecount();\n    BEGIN(INITIAL);\n  }\n\n{c_bin}{ws}?(\\\\(\\.|\\,|\\;|\\:))*{ws}?\".\"+{ws}?(\\\\(\\.|\\,|\\;|\\:))*{ws}?{c_bin} {\n\tprintf(\"\\\"%s\\\", line %d: Dots should be \\\\cdots in \\\"%s\\\"\\n\",\n\t   file_name, line_count, yytext); \n\t++warn_count;\n\tlinecount();\n  }\n\n<ICOR,INITIAL,GETICOR>[^\\\\]{l_bin}{ws}?(\\\\(\\.|\\,|\\;|\\:))*{ws}?\".\"+{ws}?(\\\\(\\.|\\,|\\;|\\:))*{ws}?[^\\\\]{l_bin} {\n\tprintf(\"\\\"%s\\\", line %d: Dots should be \\\\ldots in \\\"%s\\\"\\n\",\n\t   file_name, line_count, yytext); \n\t++warn_count;\n\tlinecount();\n    BEGIN(INITIAL);\n  }\n\n\n<ICOR,INITIAL,GETICOR>\\.\\.\\. { \n    printf(\"\\\"%s\\\", line %d: Dots should be ellipsis \\\"%s\\\"\\n\",\n\t   file_name, line_count, yytext); \n    ++warn_count;\n    BEGIN(INITIAL);\n  }\n\n<ICOR,INITIAL,GETICOR>\\\\label\\{[^#$%^&*+={\\~\"<>\\n\\t }]*[#$%^&*+={\\~\"<>\\n\\t ][^%}]*\\} {\n    linecount();\n    printf(\"\\\"%s\\\", line %d: bad character in label \\\"%s\\\", see C.10.2\\n\",\n           file_name, line_count, yytext);\n  }\n    \n<ICOR,INITIAL,GETICOR>{par}\"\\\\\"ref/[^A-Za-z]  {\n    linecount();\n    BEGIN(INITIAL);\n  }\n\n<ICOR,INITIAL,GETICOR>{ws}\"\\\\\"ref/[^A-Za-z]  {\n    linecount();\n    printf(\"\\\"%s\\\", line %d: perhaps you should insert a `~' before \\\"%s\\\"\\n\",\n\t   file_name, line_count, ++yytext); \n    BEGIN(INITIAL);\n  }\n\n<ICOR,INITIAL,GETICOR>{ws}\"\\\\\"footnote/[^A-Za-z]  {\n    linecount();\n    printf(\"\\\"%s\\\", line %d: whitespace before footnote in \\\"%s\\\"\\n\",\n\t   file_name, line_count, ++yytext); \n    BEGIN(INITIAL);\n  }\n\n \n{primitive}/[^a-zA-Z] {\n {\n    printf(\"\\\"%s\\\", line %d: Don't use \\\"%s\\\" in LaTeX documents\\n\", \n\t   file_name, line_count, yytext); \n    ++warn_count ; \n }}    \n\n\\\\left{ws}*\\\\?. { linecount() ;}\n\\\\right{ws}*\\\\?. {\tlinecount(); }\n\n<ICOR,INITIAL,GETICOR>[^\\{]\\\\{font_spec}/[ \\t]*\"{\" { \n {\n   linecount();\n    printf(\"\\\"%s\\\", line %d: Fontspecifiers don't take arguments. \\\"%s\\\"\\n\", \n\t   file_name, line_count, yytext); \n    ++warn_count; \n  /*    (void) input(); */\n    BEGIN(INITIAL);\n }}\n\n\\\\([a-zA-Z\\@]+\\@[a-zA-Z\\@]*|[a-zA-Z\\@]*\\@[a-zA-Z\\@]+) { \n {\n    printf(\"\\\"%s\\\", line %d: Do not use @ in LaTeX macro names. \\\"%s\\\"\\n\", \n\t   file_name, line_count, yytext); \n    ++warn_count; \n }}\n\n<ICOR,INITIAL,GETICOR>{ws}\"'\"+{letter}+ { \n {\n   linecount();\n    printf(\"\\\"%s\\\", line %d: Use ` to begin quotation, not ' \\\"%s\\\"\\n\", \n\t   file_name, line_count, yytext); \n    ++warn_count; \n    BEGIN(INITIAL);\n }}\n\n<ICOR,INITIAL,GETICOR>{letter}+\"`\" { \n {\n    printf(\"\\\"%s\\\", line %d: Use ' to end quotation, not ` \\\"%s\\\"\\n\", \n\t   file_name, line_count, yytext); \n    ++warn_count; \n    BEGIN(INITIAL);\n }}\n\n\n<ICOR,INITIAL,GETICOR>{ws}+{punct} { \n {\n    printf(\"\\\"%s\\\", line %d: Whitespace before punctation mark in \\\"%s\\\"\\n\", \n\t   file_name, line_count, yytext); \n    ++warn_count; \n\tlinecount();\n    BEGIN(INITIAL);\n }}\n\n\"%\"  { BEGIN(COMMENT); }\n\n<COMMENT>\\n\t{ BEGIN(INITIAL); ++line_count; }\n\n<COMMENT>.\t{ ; }\n\n\n\\\\(input|include)([ \\t]|\"{\")\t{ BEGIN(INCLUDE); }\n\n<INCLUDE>[^\\}\\n]+\t{\n {\n\tif ( strstr(yytext,\".sty\") == NULL )\n\t{\n\t  printf(\"** %s:\\n\", yytext);\n\t  input_file(yytext);\n\t}\n\telse\n\t{\n\t\tprintf(\"\\\"%s\\\", line %d: Style file `%s\\' omitted.\\n\",\n\t\t\tfile_name,\n\t\t\tline_count,\n\t\t\tyytext);\n\t\tinput();\n\t}\n\tBEGIN(INITIAL);\n }}\n\n\\\\endinput/[^A-Za-z] |\n<<EOF>> { \n\t  if (--istackp < 0)\n\t\t  yyterminate(); \n\n\t  else\n\t\t{ \n\t\t  fclose(yyin);\n\t  \t  f_checkend(file_name);\n\t\t  yy_switch_to_buffer(istack[istackp].stream);\n\t\t  free(file_name);\n\t\t  line_count = istack[istackp].linenum;\n\t\t  file_name = istack[istackp].name;\n\t\t  input();\n\t\t  BEGIN(INITIAL);\n\t\t}    \t\n\t \n\t}\n\n\n. { ; }\n%%\nint main( argc, argv )\nint argc;\nchar *argv[];\n{\n    /* allocate initial stacks */\n    gstack = (tex_group *)malloc(gstack_size * sizeof(tex_group));\n    istack = (input_ *)malloc(istack_size * sizeof(input_));\n    if ( gstack == NULL || istack == NULL ) {\n\tfprintf(stderr, \"%s: not enough memory for stacks\\n\", PROGNAME);\n\texit(3);\n    }\n\t\n    if(argc > 1)\n    {\n        if ( (file_name = (char*) malloc(strlen(argv[1]) + 5)) == NULL ) {\n\t\tfprintf(stderr, \"%s: out of memory\\n\", PROGNAME);\n\t\texit(3);\n\t}\n\t\n\tstrcpy(file_name, argv[1]);\n\tstrcat(file_name, \".tex\" );\n\t\n\tif ((yyin = fopen( file_name, \"r\")) != NULL )\n\t{\n\t    push(file_name, 3, 1);\n\t    yylex();\n\t    f_checkend(file_name);\n\t}\n\telse {   \n                 file_name[strlen(file_name) - 4] = '\\0';\n\t\t if ((yyin = fopen( file_name, \"r\")) != NULL )\n\t\t {\n\t\t     push(file_name, 3, 1);\n\t\t     yylex();\n\t\t     f_checkend(file_name);\n\t\t }\n\t\t else\n\t\t     fprintf(stderr,\n\t\t\t     \"%s: Could not open : %s\\n\",PROGNAME, argv[1]);\n\t     }\n    }\n    else\n    {\n\tprintf(\"\\n* %s *\\n\\n\",PROGNAME);\n\tprintf(\"\\t...a consistency checker for LaTeX documents.\\n\");\n\tprintf(\"$Id: lacheck.lex,v 1.26 1998/03/07 07:46:45 abraham Exp $\\n\\n\");\n\n\tprintf(\"Usage:\\n\\tlacheck filename[.tex] <return>\\n\\n\\n\");\n\n\tprintf(\"\\tFrom within Emacs:\\n\\n\");\n\tprintf(\"\\tM-x compile RET lacheck filename[.tex] RET\\n\\n\");\n\tprintf(\"\\tUse C-x ` to step through the messages.\\n\\n\");\n\tprintf(\"\\n\\tThe found context is displayed in \\\"double quotes\\\"\\n\\n\");\n\tprintf(\"Remark:\\n\\tAll messages are only warnings!\\n\\n\");\n\tprintf(\"\\tYour document may be right even though LaCheck says \");\n\tprintf(\"something else.\\n\\n\");\n    }\n    return(0);\n}\n\n#ifdef NEED_STRSTR\nchar *\nstrstr(string, substring)\n    register char *string;\t/* String to search. */\n    char *substring;\t\t/* Substring to try to find in string. */\n{\n    register char *a, *b;\n\n    /* First scan quickly through the two strings looking for a\n     * single-character match.  When it's found, then compare the\n     * rest of the substring.\n     */\n\n    b = substring;\n    if (*b == 0) {\n\treturn string;\n    }\n    for ( ; *string != 0; string += 1) {\n\tif (*string != *b) {\n\t    continue;\n\t}\n\ta = string;\n\twhile (1) {\n\t    if (*b == 0) {\n\t\treturn string;\n\t    }\n\t    if (*a++ != *b++) {\n\t\tbreak;\n\t    }\n\t}\n\tb = substring;\n    }\n    return (char *) 0;\n}\n#endif /* NEED_STRSTR */\n\nvoid push(p_name, p_type, p_line)\nunsigned char *p_name;\nint p_type;\nint p_line;\n{\n    if ( gstackp == gstack_size ) {\t/* extend stack */\n\tgstack_size *= 2;\n\tgstack = (tex_group *)realloc(gstack, gstack_size * sizeof(tex_group));\n\tif ( gstack == NULL ) {\n\t\tfprintf(stderr, \"%s: stack out of memory\", PROGNAME);\n\texit(3);\n    }\n    }\n    \n    if ( (gstack[gstackp].s_name =\n\t\t(unsigned char *)malloc(strlen((char *)p_name) + 1)) == NULL ||\n         (gstack[gstackp].s_file =\n\t\t(char *)malloc(strlen(file_name) + 1)) == NULL ) {\n\tfprintf(stderr, \"%s: out of memory\\n\", PROGNAME);\n\texit(3);\n    }\n\n    strcpy((char *)gstack[gstackp].s_name,(char *)p_name);\n    gstack[gstackp].s_type = p_type;\n    gstack[gstackp].s_line = p_line;\t\n    gstack[gstackp].italic = (  (p_type == 4 || p_type == 5)\n\t\t\t      ? 1\n\t\t\t      : (  gstackp\n\t\t\t\t ? gstack[gstackp - 1].italic\n\t\t\t\t : 0));\n    strcpy(gstack[gstackp].s_file,file_name);\n    ++gstackp;\t\n\n}\n\nvoid input_file(file_nam)\nchar *file_nam;\n{\n    char *tmp_file_name;\n    FILE *tmp_yyin;\n\n    if ( (tmp_file_name = (char*) malloc(strlen(file_nam) + 5)) == NULL ) {\n\tfprintf(stderr, \"%s: out of memory\\n\", PROGNAME);\n\texit(3);\n    }\n    strcpy(tmp_file_name,file_nam);\n\n    if (istackp == istack_size) {\t/* extend stack */\n\tistack_size *= 2;\n\tistack = (input_ *)realloc(istack, istack_size * sizeof(input_));\n\tif ( istack == NULL ) {\n\t\tfprintf(stderr, \"%s: \\\\input stack out of memory\\n\", PROGNAME);\n\texit(3);\n        } \n    } \n    \t\n    istack[istackp].stream = YY_CURRENT_BUFFER;\n    istack[istackp].linenum = line_count;\n    istack[istackp].name = file_name;\n    ++istackp;    \n\n    (void) strcat(tmp_file_name, \".tex\");\n    if ((tmp_yyin = fopen( tmp_file_name, \"r\")) != NULL )\n\t{\n\t  yyin = tmp_yyin;\n\t  yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));\n\t  file_name = tmp_file_name;\n\t  push(file_name, 3, 1);\n          line_count = 1;\n\t}\n    else {\n          tmp_file_name[strlen(tmp_file_name) - 4] = '\\0';\n\t  if ((tmp_yyin = fopen( tmp_file_name , \"r\")) != NULL )\n\t    {\n\t\tyyin = tmp_yyin;\n\t   \tyy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));\n\t\tfile_name = tmp_file_name;\n\t\tpush(file_name, 3, 1);\n   \t        line_count = 1;\n\t    }\n          else\n\t  {\n\t       --istackp;\n\t       free(tmp_file_name);\n\t       printf(\"\\\"%s\\\", line %d: Could not open \\\"%s\\\"\\n\", \n\t\t\tfile_name,\n\t\t\tline_count,\n\t\t\tfile_nam);\n\t       input();\n\t  }\n\t }\n}\n\nvoid pop()\n{\n    if ( gstackp == 0 )\n    {\n       \tfprintf(stderr, \"%s: Stack underflow\\n\", PROGNAME);\n\texit(4);\n    }\n    --gstackp;\n\n    free(gstack[gstackp].s_name);\n    free(gstack[gstackp].s_file);\n}\n\nchar *bg_command(name)\nchar *name;\n{\n    \n    switch (CG_TYPE) {\n\t\n    case 2:\n\t(void) strcpy( returnval, \"\\\\begin{\" );\n\t(void) strcat( returnval, (char *) name);\n\t(void) strcat( returnval, \"}\" );\n\tbreak;\n\t\n    case 3:\n\t(void) strcpy( returnval, \"beginning of file \" );\n\t(void) strcat( returnval, (char *) name);\n\tbreak;\n    \n    case 4:\n\t(void) strcpy( returnval, \"math begin \" );\n\t(void) strcat( returnval, (char *) name);\n\tbreak;\n    \n    case 5:\n\t(void) strcpy( returnval, \"display math begin \" );\n\t(void) strcat( returnval, (char *) name);\n\tbreak;\n    \n    default:\n    \t(void) strcpy( returnval, name );\n\t\n    }\n    \n    return ((char *)returnval);\n}\n\nchar *eg_command(name,type)\nint type;\nchar *name;\n{\n    \n    switch (type) {\n\t\n    case 2:\n\t(void) strcpy( returnval, \"\\\\end{\" );\n\t(void) strcat( returnval, (char *) name);\n\t(void) strcat( returnval, \"}\" );\n\tbreak;\n\t\n    case 3:\n\t(void) strcpy( returnval, \"end of file \" );\n\t(void) strcat( returnval, (char *) name);\n\tbreak;\n    \n    case 4:\n\t(void) strcpy( returnval, \"math end \" );\n\t(void) strcat( returnval, (char *) name);\n\tbreak;\n    \n    case 5:\n\t(void) strcpy( returnval, \"display math end \" );\n\t(void) strcat( returnval, (char *) name);\n\tbreak;\n    \n    default:\n    \t(void) strcpy( returnval, name );\n\tbreak;\n    }\n    \n    return ((char *)returnval);\n}\n\n\nvoid g_checkend(n)\nint n;\n{\n    if ( check_top_level_end(yytext,n) == 1 ) {\n       if (  CG_TYPE != n  )\n\t print_bad_match(yytext,n);\n       else\n\tpop();\n    }\n}\n\nvoid e_checkend(n, name)\nint n;\nchar *name;\n{\n   if ( check_top_level_end(name,n) == 1 )\n    {\n     if (  CG_TYPE != n  ||  strcmp( CG_NAME, name ) != 0 )\n    \tprint_bad_match(name,n);\n\n     pop();\n\n    }\n}\n\nvoid f_checkend(name)\nchar *name;\n{\n    if ( check_top_level_end(name,3) == 1 )\n     {\n       if (  CG_TYPE != 3  ||  strcmp( CG_NAME, name ) != 0 )\n\n    \twhile( CG_TYPE != 3  )\n\t{\n\t  print_bad_match(name,3);\n          pop();\n          if (gstackp <= 0) return;\n        }\n\n         pop();  \n     }\n}\n\nvoid print_bad_match(end_command,type)\nchar *end_command;\t      \nint type;\n{\n\t  printf(\"\\\"%s\\\", line %d: <- unmatched \\\"%s\\\"\\n\",\n\t         file_name, \n\t\t line_count, \n\t\t eg_command( end_command , type) ) ;\n\n\t  if (gstackp > 0) {\n\t\t printf(\"\\\"%s\\\", line %d: -> unmatched \\\"%s\\\"\\n\",\n\t\t \t CG_FILE, \n\t\t \t CG_LINE, \n\t\t \t bg_command( CG_NAME ) ) ;\n\t\t warn_count += 2;\n\t  }\n}\n\nint check_top_level_end(end_command,type)\nchar *end_command;\t      \nint type;\n{\n    if ( gstackp == 0 )\n\t{\n\t printf(\"\\\"%s\\\", line %d: \\\"%s\\\" found at top level\\n\",\n\t       file_name, \n\t       line_count, \n\t       eg_command( end_command, type )) ;\n\t ++warn_count;\n         return(0);\n\t}\n    else\n    \treturn(1);\n}\n\nvoid linecount()\n{\n  int i;\n  for (i = 0; i < yyleng; i++)\n    if(yytext[i] == '\\n')\n      line_count++;\n}\n\n"
  },
  {
    "path": "Units/parser-lisp.r/misleading-names.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-lisp.r/misleading-names.d/expected.tags",
    "content": "a\tinput.lisp\t/^(defvar a)$/;\"\tv\nb\tinput.lisp\t/^(defvar b)$/;\"\tv\n"
  },
  {
    "path": "Units/parser-lisp.r/misleading-names.d/input.lisp",
    "content": "(defvar a)\n\n;; ctags should not extract:\n(DEFAULT x0)\n(DEfaULT x1)\n\n(DEFINITION y0)\n(DEFINITIONZ y1)\n(DEFInitioN y2)\n(DEFInitioNs y3)\n\n(defvar b)\n"
  },
  {
    "path": "Units/parser-lisp.r/more-defsomething.d/args.ctags",
    "content": "--sort=no\n--fields=+KkZz\n"
  },
  {
    "path": "Units/parser-lisp.r/more-defsomething.d/expected.tags",
    "content": "url\tinput.lisp\t/^(defmethod url ((url quri:uri))$/;\"\tkind:method\nurl-designator\tinput.lisp\t/^(deftype url-designator ()$/;\"\tkind:type\nrenderer-scheme\tinput.lisp\t/^(defclass renderer-scheme ()$/;\"\tkind:class\nscheme\tinput.lisp\t/^(define-class scheme (renderer-scheme)$/;\"\tkind:unknown\tdefiner:DEFINE-CLASS\nbrowser-schemes\tinput.lisp\t/^(defgeneric browser-schemes (browser)$/;\"\tkind:generic\n%buffer\tinput.lisp\t/^(defparameter %buffer nil)$/;\"\tkind:parameter\n:nyxt/renderer/gtk\tinput.lisp\t/^(nyxt:define-package :nyxt\\/renderer\\/gtk$/;\"\tkind:unknown\tdefiner:DEFINE-PACKAGE\nrenderer-history-entry\tinput.lisp\t/^(defstruct renderer-history-entry$/;\"\tkind:struct\nlocal-p\tinput.lisp\t/^(defmethod (setf local-p) (value (scheme gtk-scheme))$/;\"\tkind:method\nlocal-pp\tinput.lisp\t/^(defmethod (setf  local-pp) (a0))$/;\"\tkind:method\nlocal-ppp\tinput.lisp\t/^(defmethod (SETF   local-ppp) (a1))$/;\"\tkind:method\n"
  },
  {
    "path": "Units/parser-lisp.r/more-defsomething.d/input.lisp",
    "content": ";; Taken from https://github.com/atlas-engineer/nyxt.git\n\n(defmethod url ((url quri:uri))\n  url)\n\n(deftype url-designator ()\n  \"Type for anything URL-like.\nMeans that `url' can be applied to it to get `quri:uri'.\"\n  `(satisfies has-url-method-p))\n\n(defclass renderer-scheme ()\n  ()\n  (:metaclass interface-class)\n  (:documentation \"Renderer-specific representation of the custom scheme.\nShould be redefined by the renderer.\"))\n\n(define-class scheme (renderer-scheme)\n  ((name\n    (alex:required-argument 'name)\n    :documentation \"The custom scheme name to handle.\nHTTPS or FILE are examples of schemes.\")\n   (callback\n    nil\n    :type (or null function)\n    :documentation \"A function called on URL load that returns the page contents.\n\nIt takes the URL as an argument and returns up to 5 values:\n- The data for page contents (either as string or as a unsigned byte array)\n- The MIME type for the contents\n- The status code for the request\n- An alist of headers for the request\n- A status reason phrase\")\n   (error-callback\n    nil\n    :type (or null function)\n    :documentation \"Callback to use when a condition is signaled.\n\nAccepts only one argument: the signaled condition.\"))\n  (:export-class-name-p t)\n  (:export-accessor-names-p t)\n  (:documentation \"Representation of Nyxt-specific internal schemes.\nHas `name' it can be accessed with. When accessed, runs `callback' to return\ncontent. In case something goes wrong, runs `error-callback'.\")\n  (:metaclass user-class))\n\n(defgeneric browser-schemes (browser)\n  (:method-combination append)\n  (:documentation \"Return a list of schemes supported by BROWSER.\"))\n\n(defparameter %buffer nil)\n\n(nyxt:define-package :nyxt/renderer/gtk\n    (:documentation \"GTK renderer using direct CFFI bindings.\"))\n\n(defstruct renderer-history-entry\n  title\n  url\n  original-url\n  gtk-object)\n\n\n(defmethod (setf local-p) (value (scheme gtk-scheme))\n  (when value\n    (webkit:webkit-security-manager-register-uri-scheme-as-local (manager scheme)\n                                                                 (name scheme)))\n  (setf (slot-value scheme 'local-p) value))\n\n(defmethod (setf  local-pp) (a0))\n(defmethod (SETF   local-ppp) (a1))\n"
  },
  {
    "path": "Units/parser-lisp.r/newline-between-tokens.b/expected.tags",
    "content": "f\tinput.l\t/^ f () 1)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-lisp.r/newline-between-tokens.b/input.l",
    "content": "(defun\n f () 1)\n"
  },
  {
    "path": "Units/parser-lisp.r/simple-lisp.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-lisp.r/simple-lisp.d/expected.tags",
    "content": "a0\tinput.l\t/^(defun a0 (n) (+ 1 n))$/;\"\tf\nA1\tinput.l\t/^(DEFUN A1 (n) (+ 2 n))$/;\"\tf\nb0\tinput.l\t/^(defvar b0 3)$/;\"\tv\nB1\tinput.l\t/^(DEFVAR B1 4)$/;\"\tv\nc0\tinput.l\t/^(defconstant c0 5)$/;\"\tc\nC1\tinput.l\t/^(DEFCONSTANT C1 6)$/;\"\tc\ndefunknown0\tinput.l\t/^(defmacro defunknown0 (s)$/;\"\tm\nDEFUNKNOWN1\tinput.l\t/^(DEFMACRO DEFUNKNOWN1 (s)$/;\"\tm\nunknown\tinput.l\t/^(defunknown1 unknown)$/;\"\tY\tdefiner:DEFUNKNOWN1\n"
  },
  {
    "path": "Units/parser-lisp.r/simple-lisp.d/input.l",
    "content": "(defun a0 (n) (+ 1 n))\n(DEFUN A1 (n) (+ 2 n))\n\n(defvar b0 3)\n(DEFVAR B1 4)\n\n(defconstant c0 5)\n(DEFCONSTANT C1 6)\n\n(defmacro defunknown0 (s)\n  `(defconstant ,s 'unknown))\n\n(DEFMACRO DEFUNKNOWN1 (s)\n   `(defconstant ,s 'unknown))\n\n(defunknown1 unknown)\n\n"
  },
  {
    "path": "Units/parser-lua.r/lua-broken-nested-tables.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-lua.r/lua-broken-nested-tables.d/args.ctags",
    "content": "--extras=+q\n"
  },
  {
    "path": "Units/parser-lua.r/lua-broken-nested-tables.d/input.lua",
    "content": "a = {}\na..b = {}\na..b..c = function()\n      print \"hello\"\nend\na..b..c()\n\nax = {}\nax..by = {}\nax..by..cz = function()\n      print \"hello\"\nend\nax..by..cz()\n\n\n.aX = function()\n      print \"hello\"\nend\n\n.aX.bY = function()\n      print \"hello\"\nend\n\n.aX.bY( = function()\n      print \"hello\"\nend\n\n.(aX.bY = function()\n      print \"hello\"\nend\n\n..aX.bY = function()\n      print \"hello\"\nend\n\n.aX.bY.cZ. = function()\n      print \"hello\"\nend\n\n..aX.bY.cZ. = function()\n      print \"hello\"\nend\n\n.aX.bY.cZ.. = function()\n      print \"hello\"\nend\n\n.aX.b(Y.cZ.. = function()\n      print \"hello\"\nend\n\n.aX.(bY.cZ.. = function()\n      print \"hello\"\nend\n\n.aX(.bY.cZ.. = function()\n      print \"hello\"\nend\n"
  },
  {
    "path": "Units/parser-lua.r/lua-double-equals.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-lua.r/lua-double-equals.d/input.lua",
    "content": "if type(v) == \"function\" then\n==function\nI0 ==function\nI1 == function\nfunction ==\nfunction ==IGNOREME0\nfunction == IGNOREME1\n"
  },
  {
    "path": "Units/parser-lua.r/lua-equal-after-function.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-lua.r/lua-equal-after-function.d/input.lua",
    "content": "\"function\" ~= P0\n\"function\" ~=Q0\n\"function\" ~=\n"
  },
  {
    "path": "Units/parser-lua.r/lua-function-in-nested-tables.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--fields=-+E\n"
  },
  {
    "path": "Units/parser-lua.r/lua-function-in-nested-tables.d/expected.tags",
    "content": "c\tinput.lua\t/^a.b.c = function()$/;\"\tf\tunknown:a.b\na.b.c\tinput.lua\t/^a.b.c = function()$/;\"\tf\tunknown:a.b\textras:qualified\ncz\tinput.lua\t/^ax.by.cz = function()$/;\"\tf\tunknown:ax.by\nax.by.cz\tinput.lua\t/^ax.by.cz = function()$/;\"\tf\tunknown:ax.by\textras:qualified\n"
  },
  {
    "path": "Units/parser-lua.r/lua-function-in-nested-tables.d/input.lua",
    "content": "a = {}\na.b = {}\na.b.c = function()\n      print \"hello\"\nend\na.b.c()\n\nax = {}\nax.by = {}\nax.by.cz = function()\n      print \"hello\"\nend\nax.by.cz()\n"
  },
  {
    "path": "Units/parser-lua.r/lua-function-in-string-literal.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-lua.r/lua-function-in-string-literal.d/expected.tags",
    "content": "caller\tinput.lua\t/^local function caller(str, foo)$/;\"\tf\na\tinput.lua\t/^function a()$/;\"\tf\nab\tinput.lua\t/^function ab()$/;\"\tf\nabc\tinput.lua\t/^function abc ()$/;\"\tf\ne\tinput.lua\t/^function e ()$/;\"\tf\nef\tinput.lua\t/^function ef ()$/;\"\tf\nx\tinput.lua\t/^x = function()$/;\"\tf\ny\tinput.lua\t/^y = function ()$/;\"\tf\nz\tinput.lua\t/^z = function  ()$/;\"\tf\n"
  },
  {
    "path": "Units/parser-lua.r/lua-function-in-string-literal.d/input.lua",
    "content": "-- Taken from issue #2439 opened by @andrejlevkovitch\nlocal function caller(str, foo)\n  foo()\n  print(str)\nend\n\ncaller(\"foo called\", function()\nend)\n\ncaller(\"functional\", function()\nend)\n\ncaller(\"function foo\", function()\nend)\n\nfunction a()\nend\n\nfunction ab()\nend\n\nfunction abc ()\nend\n\nfunction e ()\nend\n\nfunction ef ()\nend\n\nx = function()\nend\n\ny = function ()\nend\n\nz = function  ()\nend\n"
  },
  {
    "path": "Units/parser-lua.r/lua-skip-curly-brackets.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-lua.r/lua-skip-curly-brackets.d/expected.tags",
    "content": "__index\tinput.lua\t/^setmetatable(t, {__index=function(self,k) return k end})$/;\"\tf\n"
  },
  {
    "path": "Units/parser-lua.r/lua-skip-curly-brackets.d/input.lua",
    "content": "setmetatable(t, {__index=function(self,k) return k end})\n-- Taken from #3346 reported by @jubnzv.\n"
  },
  {
    "path": "Units/parser-lua.r/lua-skip-whitespaces-in-name.d/expected.tags",
    "content": "a\tinput.lua\t/^function  a(x)$/;\"\tf\nb\tinput.lua\t/^  function  b(x)$/;\"\tf\nc\tinput.lua\t/^  function  c  (x)$/;\"\tf\nd\tinput.lua\t/^function  d  (x)$/;\"\tf\ne\tinput.lua\t/^e=function  (x)$/;\"\tf\nf\tinput.lua\t/^f  =function  (x)$/;\"\tf\ng\tinput.lua\t/^g  =  function  (x)$/;\"\tf\nh\tinput.lua\t/^h=  function  (x)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-lua.r/lua-skip-whitespaces-in-name.d/input.lua",
    "content": "\nfunction  a(x)\n   print\"hello\"\nend\n\n  function  b(x)\n   print\"hello\"\nend\n\n  function  c  (x)\n   print\"hello\"\nend\n\nfunction  d  (x)\n   print\"hello\"\nend\n\ne=function  (x)\n\tprint\"hello\"\nend\n\nf  =function  (x)\n\tprint\"hello\"\nend\n\ng  =  function  (x)\n\tprint\"hello\"\nend\n\nh=  function  (x)\n\tprint\"hello\"\nend\n\n=broken1(\n =broken2(\n = broken3(\n\n)=broken4(\n) =broken5(\n) = broken6(\n\n )=broken7(\n )= broken8(\n  =)broken9(\n"
  },
  {
    "path": "Units/parser-lua.r/lua-skip-whitespaces-in-name.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/parser-lua.r/simple.lua.d/expected.tags",
    "content": "i_123\tinput.lua\t/^ test.i_123 = function  (x)$/;\"\tf\tunknown:test\nme_12a\tinput.lua\t/^function test.me_12a(one, two)$/;\"\tf\tunknown:test\nme_12b\tinput.lua\t/^function test.me_12b (one, two)$/;\"\tf\tunknown:test\n"
  },
  {
    "path": "Units/parser-lua.r/simple.lua.d/input.lua",
    "content": "-- Comment line\n  -- Indented comment line\ntest = {}\n\nfunction test.me_12a(one, two)\n\tprint\"me_12a\"\nend\n\nfunction test.me_12b (one, two)\n\tprint\"me_12b\"\nend\n\n\n test.i_123 = function  (x)\n\tprint\"i_123\"\nend\n\n\ntest.me_12a(1,2)\ntest.i_123(1)\n"
  },
  {
    "path": "Units/parser-m4.r/disabling-autoconf.d/args.ctags",
    "content": "--sort=no\n--fields=+elnr\n--extras=+fr\n--languages=-Autoconf\n"
  },
  {
    "path": "Units/parser-m4.r/disabling-autoconf.d/expected.tags",
    "content": "x\tinput.m4\t/^define(`x', 1)$/;\"\td\tline:1\tlanguage:M4\troles:def\tend:1\n[PKG_MACROS_VERSION]\tinput.m4\t/^[m4_define([PKG_MACROS_VERSION], [0.29])$/;\"\td\tline:3\tlanguage:M4\troles:def\tend:3\n[y]\tinput.m4\t/^m4_define([y], 2)$/;\"\td\tline:7\tlanguage:M4\troles:def\tend:7\nz\tinput.m4\t/^define(`z', 3)$/;\"\td\tline:9\tlanguage:M4\troles:def\tend:9\ninput.m4\tinput.m4\t1;\"\tF\tline:1\tlanguage:M4\troles:def\tend:10\n"
  },
  {
    "path": "Units/parser-m4.r/disabling-autoconf.d/input.m4",
    "content": "define(`x', 1)\nAC_DEFUN([PKG_PREREQ],\n[m4_define([PKG_MACROS_VERSION], [0.29])\nm4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,\n    [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])\n])dnl PKG_PREREQ\nm4_define([y], 2)\nm4_changequote([`],['])\ndefine(`z', 3)\n\n"
  },
  {
    "path": "Units/parser-m4.r/disabling-subparser.d/args.ctags",
    "content": "--sort=no\n--fields=+elnr\n--extras=+fr-s\n\n"
  },
  {
    "path": "Units/parser-m4.r/disabling-subparser.d/expected.tags",
    "content": "x\tinput.m4\t/^define(`x', 1)$/;\"\td\tline:1\tlanguage:M4\troles:def\tend:1\n[PKG_MACROS_VERSION]\tinput.m4\t/^[m4_define([PKG_MACROS_VERSION], [0.29])$/;\"\td\tline:3\tlanguage:M4\troles:def\tend:3\n[y]\tinput.m4\t/^m4_define([y], 2)$/;\"\td\tline:7\tlanguage:M4\troles:def\tend:7\nz\tinput.m4\t/^define(`z', 3)$/;\"\td\tline:9\tlanguage:M4\troles:def\tend:9\ninput.m4\tinput.m4\t1;\"\tF\tline:1\tlanguage:M4\troles:def\tend:10\n"
  },
  {
    "path": "Units/parser-m4.r/disabling-subparser.d/input.m4",
    "content": "define(`x', 1)\nAC_DEFUN([PKG_PREREQ],\n[m4_define([PKG_MACROS_VERSION], [0.29])\nm4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,\n    [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])\n])dnl PKG_PREREQ\nm4_define([y], 2)\nm4_changequote([`],['])\ndefine(`z', 3)\n\n"
  },
  {
    "path": "Units/parser-m4.r/m4-autoconf-and-optlib.d/README",
    "content": "This case is inteded to be run under valgrind.\n"
  },
  {
    "path": "Units/parser-m4.r/m4-autoconf-and-optlib.d/args.ctags",
    "content": "--langdef=NEWLANG{base=M4}\n--kinddef-NEWLANG=a,abc,abc def ghi\n--regex-NEWLANG=/SAMPLE (.*)/\\1/a/\n"
  },
  {
    "path": "Units/parser-m4.r/m4-autoconf-and-optlib.d/expected.tags",
    "content": "x\tinput.m4\t/^define(x,1)$/;\"\td\n"
  },
  {
    "path": "Units/parser-m4.r/m4-autoconf-and-optlib.d/input.m4",
    "content": "SAMPLE(INPUT)\ndefine(x,1)\n`abc'\ndnl x\n\n"
  },
  {
    "path": "Units/parser-m4.r/m4-comment.d/args.ctags",
    "content": "--sort=no\n--fields=+eln\n--extras=+f\n"
  },
  {
    "path": "Units/parser-m4.r/m4-comment.d/expected.tags",
    "content": "CAPTUREME\tinput.m4\t/^-   define(CAPTUREME,val0)$/;\"\td\tline:1\tlanguage:M4\tend:1\ninput.m4\tinput.m4\t1;\"\tF\tline:1\tlanguage:M4\tend:3\n"
  },
  {
    "path": "Units/parser-m4.r/m4-comment.d/input.m4",
    "content": "-   define(CAPTUREME,val0)\n-   dnl define(IGNORED,val1)\ndnl include(IGNORED)\n"
  },
  {
    "path": "Units/parser-m4.r/m4-multi-undef.d/args.ctags",
    "content": "--sort=no\n--fields=+elnr\n--extras=+fr\n"
  },
  {
    "path": "Units/parser-m4.r/m4-multi-undef.d/expected.tags",
    "content": "a\tinput.m4\t/^undefine(a,b,c)$/;\"\td\tline:1\tlanguage:M4\troles:undef\nb\tinput.m4\t/^undefine(a,b,c)$/;\"\td\tline:1\tlanguage:M4\troles:undef\nc\tinput.m4\t/^undefine(a,b,c)$/;\"\td\tline:1\tlanguage:M4\troles:undef\ninput.m4\tinput.m4\t1;\"\tF\tline:1\tlanguage:M4\troles:def\tend:1\n"
  },
  {
    "path": "Units/parser-m4.r/m4-multi-undef.d/input.m4",
    "content": "undefine(a,b,c)\n"
  },
  {
    "path": "Units/parser-m4.r/m4-quotestring.b/DESC.rst",
    "content": "Quote strings\n==========================================================\n\nFor quoting in m4, strings can be used for starting and ending.\nThe current implementation cannot handle this well. \n\ne.g.\n\n.. code-block:: m4\n\n\t\tquotestring(`<<',`>>')\n\t\t\n"
  },
  {
    "path": "Units/parser-m4.r/m4-quotestring.b/expected.tags",
    "content": "X\tinput.m4\t/^define(<<X>>,1)$/;\"\td\nX\tinput.m4\t/^define([Y],1)$/;\"\td\n"
  },
  {
    "path": "Units/parser-m4.r/m4-quotestring.b/input.m4",
    "content": "changequote(`<<',`>>')\ndefine(<<X>>,1)\nchangequote(<<[>>,<<]>>)\ndefine([Y],1)\n"
  },
  {
    "path": "Units/parser-m4.r/m4-simple.d/args.ctags",
    "content": "--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-m4.r/m4-simple.d/expected.tags",
    "content": "A0\tinput.m4\t/^undefine(`A0')$/;\"\td\troles:undef\nA4\tinput.m4\t/^m4_undefine(`A4')$/;\"\td\troles:undef\nB0\tinput.m4\t/^undefine([B0])$/;\"\td\troles:undef\nB4\tinput.m4\t/^m4_undefine([B4])$/;\"\td\troles:undef\nC0\tinput.m4\t/^undefine(C0)$/;\"\td\troles:undef\nI0\tinput.m4\t/^include(`I0')$/;\"\tI\troles:included\nI4\tinput.m4\t/^m4_include(`I4')$/;\"\tI\troles:included\nINDENT_1\tinput.m4\t/^  define(`INDENT_1',x)$/;\"\td\troles:def\nINDENT_2\tinput.m4\t/^ define([INDENT_2],y)$/;\"\td\troles:def\nINDENT_3\tinput.m4\t/^ define({INDENT_3},z)$/;\"\td\troles:def\nINDENT_5\tinput.m4\t/^ define(INDENT_5, v)$/;\"\td\troles:def\nINDENT_6\tinput.m4\t/^    m4_define(`INDENT_6',x)$/;\"\td\troles:def\nINDENT_7\tinput.m4\t/^    m4_define([INDENT_7],y)$/;\"\td\troles:def\nINDENT_8\tinput.m4\t/^    m4_define({INDENT_8},z)$/;\"\td\troles:def\nINDENT_A\tinput.m4\t/^    m4_define(INDENT_A,v)$/;\"\td\troles:def\nINDENT_B\tinput.m4\t/^    undefine(`INDENT_B')$/;\"\td\troles:undef\nINDENT_C\tinput.m4\t/^    undefine([INDENT_C])$/;\"\td\troles:undef\nINDENT_D\tinput.m4\t/^    undefine(INDENT_D)$/;\"\td\troles:undef\nINDENT_E\tinput.m4\t/^    m4_undefine(`INDENT_E')$/;\"\td\troles:undef\nINDENT_F\tinput.m4\t/^    m4_undefine([INDENT_F])$/;\"\td\troles:undef\nINDENT_G\tinput.m4\t/^\tinclude(`INDENT_G')$/;\"\tI\troles:included\nINDENT_H\tinput.m4\t/^\tm4_include(`INDENT_H')$/;\"\tI\troles:included\nINDENT_I\tinput.m4\t/^\tsinclude(`INDENT_I')$/;\"\tI\troles:sincluded\nINDENT_J\tinput.m4\t/^\tm4_sinclude(`INDENT_J')$/;\"\tI\troles:sincluded\nINDENT_K\tinput.m4\t/^\tinclude([INDENT_K])$/;\"\tI\troles:included\nINDENT_L\tinput.m4\t/^\tm4_include([INDENT_L])$/;\"\tI\troles:included\nINDENT_M\tinput.m4\t/^\tsinclude([INDENT_M])$/;\"\tI\troles:sincluded\nINDENT_N\tinput.m4\t/^\tm4_sinclude([INDENT_N])$/;\"\tI\troles:sincluded\nINDENT_O\tinput.m4\t/^\tinclude(INDENT_O)$/;\"\tI\troles:included\nINDENT_P\tinput.m4\t/^\tm4_include(INDENT_P)$/;\"\tI\troles:included\nINDENT_Q\tinput.m4\t/^\tsinclude(INDENT_Q)$/;\"\tI\troles:sincluded\nINDENT_R\tinput.m4\t/^\tm4_sinclude(INDENT_R)$/;\"\tI\troles:sincluded\nJ0\tinput.m4\t/^include([J0])$/;\"\tI\troles:included\nJ4\tinput.m4\t/^m4_include([J4])$/;\"\tI\troles:included\nK0\tinput.m4\t/^include(K0)$/;\"\tI\troles:included\nK4\tinput.m4\t/^m4_include(K4)$/;\"\tI\troles:included\nS0\tinput.m4\t/^sinclude(`S0')$/;\"\tI\troles:sincluded\nS4\tinput.m4\t/^m4_sinclude(`S4')$/;\"\tI\troles:sincluded\nT0\tinput.m4\t/^sinclude([T0])$/;\"\tI\troles:sincluded\nT4\tinput.m4\t/^m4_sinclude([T4])$/;\"\tI\troles:sincluded\nU0\tinput.m4\t/^sinclude(U0)$/;\"\tI\troles:sincluded\nU4\tinput.m4\t/^m4_sinclude(U4)$/;\"\tI\troles:sincluded\nV0\tinput.m4\t/^define(V0, v)$/;\"\td\troles:def\nV4\tinput.m4\t/^m4_define(V4,v)$/;\"\td\troles:def\nX0\tinput.m4\t/^define(`X0',x)$/;\"\td\troles:def\nX4\tinput.m4\t/^m4_define(`X4',x)$/;\"\td\troles:def\nY0\tinput.m4\t/^define([Y0],y)$/;\"\td\troles:def\nY4\tinput.m4\t/^m4_define([Y4],y)$/;\"\td\troles:def\nZ0\tinput.m4\t/^define({Z0},z)$/;\"\td\troles:def\nZ4\tinput.m4\t/^m4_define({Z4},z)$/;\"\td\troles:def\n"
  },
  {
    "path": "Units/parser-m4.r/m4-simple.d/input.m4",
    "content": "define(`X0',x)\n  define(`INDENT_1',x)\nchangequote(`[',`]')\ndefine([Y0],y)\n define([INDENT_2],y)\nchangequote([{],[}])\ndefine({Z0},z)\n define({INDENT_3},z)\ndefine(V0, v)\n define(INDENT_5, v)\n\n    changequote()\n    Zdefine(`DROPX3',x)\n    changequote(`[',`]')\n    Zdefine([DROPY3],y)\n    changequote([{],[}])\n    Zdefine({DROPZ3},z)\n\nm4_changequote()\nm4_define(`X4',x)\nm4_changequote(`[',`]')\nm4_define([Y4],y)\nm4_changequote([{],[}])\nm4_define({Z4},z)\nm4_define(V4,v)\n\n    m4_changequote()\n    m4_define(`INDENT_6',x)\n    m4_changequote(`[',`]')\n    m4_define([INDENT_7],y)\n    m4_changequote([{],[}])\n    m4_define({INDENT_8},z)\n    m4_define(INDENT_A,v)\n\nm4_changequote()\nundefine(`A0')\nm4_changequote(`[',`]')\nundefine([B0])\nundefine(C0)\n\n    m4_changequote()\n    undefine(`INDENT_B')\n    m4_changequote(`[',`]')\n    undefine([INDENT_C])\n    undefine(INDENT_D)\n\n    m4_changequote()\n    Zundefine(`DROPA2')\n    m4_changequote(`[',`]')\n    Zundefine([DROPB2])\n    Zundefine(DROPC2)\n\nm4_changequote()\nm4_undefine(`A4')\nm4_changequote(`[',`]')\nm4_undefine([B4])\n\n    m4_changequote()\n    m4_undefine(`INDENT_E')\n    m4_changequote(`[',`]')\n    m4_undefine([INDENT_F])\n\n    m4_changequote()\n\tZm4_undefine(`DROPA6')\n    m4_changequote(`[',`]')\n\tZm4_undefine([DROPB6])\n\nm4_changequote()\n\ninclude(`I0')\n\tinclude(`INDENT_G')\n\tFinclude(`DROPI2')\nm4_include(`I4')\n\tm4_include(`INDENT_H')\n\tZm4_include(`DROPI6')\n\nsinclude(`S0')\n\tsinclude(`INDENT_I')\n\tFsinclude(`DROPS2')\nm4_sinclude(`S4')\n\tm4_sinclude(`INDENT_J')\n\tZm4_sinclude(`DROPS6')\n\nm4_changequote(`[',`]')\ninclude([J0])\n\tinclude([INDENT_K])\n\tFinclude([DROPJ2])\nm4_include([J4])\n\tm4_include([INDENT_L])\n\tZm4_include([DROPJ6])\n\nsinclude([T0])\n\tsinclude([INDENT_M])\n\tFsinclude([DROPT2])\nm4_sinclude([T4])\n\tm4_sinclude([INDENT_N])\n\tZm4_sinclude([DROPT6])\n\ninclude(K0)\n\tinclude(INDENT_O)\n\tFinclude(DROPK2)\nm4_include(K4)\n\tm4_include(INDENT_P)\n\tZm4_include(DROPK6)\n\nsinclude(U0)\n\tsinclude(INDENT_Q)\n\tFsinclude(DROPU2)\nm4_sinclude(U4)\n\tm4_sinclude(INDENT_R)\n\tZm4_sinclude(DROPU6)\n"
  },
  {
    "path": "Units/parser-m4.r/m4-switch-lang-by-ac.d/args.ctags",
    "content": "--sort=no\n--fields=+elnr\n--extras=+fr\n"
  },
  {
    "path": "Units/parser-m4.r/m4-switch-lang-by-ac.d/expected.tags",
    "content": "x\tinput.m4\t/^define(`x', 1)$/;\"\td\tline:1\tlanguage:M4\troles:def\tend:1\nPKG_PREREQ\tinput.m4\t/^AC_DEFUN([PKG_PREREQ],$/;\"\tm\tline:2\tlanguage:Autoconf\troles:def\tend:6\nPKG_MACROS_VERSION\tinput.m4\t/^[m4_define([PKG_MACROS_VERSION], [0.29])$/;\"\td\tline:3\tlanguage:M4\troles:def\tend:3\ny\tinput.m4\t/^m4_define([y], 2)$/;\"\td\tline:7\tlanguage:M4\troles:def\tend:7\nz\tinput.m4\t/^define(`z', 3)$/;\"\td\tline:9\tlanguage:M4\troles:def\tend:9\ninput.m4\tinput.m4\t1;\"\tF\tline:1\tlanguage:Autoconf\troles:def\tend:10\n"
  },
  {
    "path": "Units/parser-m4.r/m4-switch-lang-by-ac.d/input.m4",
    "content": "define(`x', 1)\nAC_DEFUN([PKG_PREREQ],\n[m4_define([PKG_MACROS_VERSION], [0.29])\nm4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,\n    [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])\n])dnl PKG_PREREQ\nm4_define([y], 2)\nm4_changequote([`],['])\ndefine(`z', 3)\n\n"
  },
  {
    "path": "Units/parser-m4.r/m4-switch-lang-by-m4.d/args.ctags",
    "content": "--sort=no\n--fields=+elnr\n--extras=+fr\n"
  },
  {
    "path": "Units/parser-m4.r/m4-switch-lang-by-m4.d/expected.tags",
    "content": "y\tinput.m4\t/^m4_define([y], 2)$/;\"\td\tline:1\tlanguage:M4\troles:def\tend:1\nz\tinput.m4\t/^define(`z', 3)$/;\"\td\tline:3\tlanguage:M4\troles:def\tend:3\ninput.m4\tinput.m4\t1;\"\tF\tline:1\tlanguage:Autoconf\troles:def\tend:3\n"
  },
  {
    "path": "Units/parser-m4.r/m4-switch-lang-by-m4.d/input.m4",
    "content": "m4_define([y], 2)\nm4_changequote([`],['])\ndefine(`z', 3)\n"
  },
  {
    "path": "Units/parser-make.r/bug2959889.mak.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-make.r/bug2959889.mak.d/input.mak",
    "content": "{"
  },
  {
    "path": "Units/parser-make.r/cpp-marcros.d/args.ctags",
    "content": "--sort=no\n--fields=+{language}{signature}\n--extras-Make=+{CppDef}\n"
  },
  {
    "path": "Units/parser-make.r/cpp-marcros.d/expected.tags",
    "content": "REALMODE_CFLAGS\tinput.mak\t/^REALMODE_CFLAGS\t:= -std=gnu11 -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \\\\$/;\"\tm\tlanguage:Make\nDISABLE_BRANCH_PROFILING\tinput.mak\t/^REALMODE_CFLAGS\t:= -std=gnu11 -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \\\\$/;\"\td\tlanguage:CPreProcessor\n__DISABLE_EXPORTS\tinput.mak\t/^REALMODE_CFLAGS\t:= -std=gnu11 -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEF\tinput.mak\t/^\t\t   -DMYDEF=1 \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEF0\tinput.mak\t/^\t\t   -DMYDEF0   \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEF1\tinput.mak\t/^\t\t   -DMYDEF1=1 \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEF2\tinput.mak\t/^\t\t   -DMYDEF2(X)=X   \\\\$/;\"\td\tlanguage:CPreProcessor\tsignature:(X)\nMYDEF3\tinput.mak\t/^\t\t   -D MYDEF3      \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEF4\tinput.mak\t/^\t\t   -D MYDEF4=1    \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEF5\tinput.mak\t/^\t\t   -D MYDEF5(X)=X \\\\$/;\"\td\tlanguage:CPreProcessor\tsignature:(X)\nMYDEF6\tinput.mak\t/^\t\t   -D'MYDEF6'      \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEF7\tinput.mak\t/^\t\t   -D'MYDEF7=1'    \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEF8\tinput.mak\t/^\t\t   -D'MYDEF8(X)=X' \\\\$/;\"\td\tlanguage:CPreProcessor\tsignature:(X)\nMYDEF9\tinput.mak\t/^\t\t   -D 'MYDEF9'      \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEFa\tinput.mak\t/^\t\t   -D 'MYDEFa=1'    \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEFb\tinput.mak\t/^\t\t   -D 'MYDEFb(X)=X' \\\\$/;\"\td\tlanguage:CPreProcessor\tsignature:(X)\nMYDEFc\tinput.mak\t/^\t\t   -D\"MYDEFc\"      \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEFd\tinput.mak\t/^\t\t   -D\"MYDEFd=1\"    \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEFe\tinput.mak\t/^\t\t   -D\"MYDEFe(X)=X\" \\\\$/;\"\td\tlanguage:CPreProcessor\tsignature:(X)\nMYDEFf\tinput.mak\t/^\t\t   -D \"MYDEFf\"      \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEFg\tinput.mak\t/^\t\t   -D \"MYDEFg=1\"    \\\\$/;\"\td\tlanguage:CPreProcessor\nMYDEFh\tinput.mak\t/^\t\t   -D \"MYDEFh(X)=X\" \\\\$/;\"\td\tlanguage:CPreProcessor\tsignature:(X)\nKBUILD_CPPFLAGS\tinput.mak\t/^KBUILD_CPPFLAGS := -D__KERNEL__$/;\"\tm\tlanguage:Make\n__KERNEL__\tinput.mak\t/^KBUILD_CPPFLAGS := -D__KERNEL__$/;\"\td\tlanguage:CPreProcessor\nKBUILD_RUSTFLAGS\tinput.mak\t/^KBUILD_RUSTFLAGS := $(rust_common_flags) \\\\$/;\"\tm\tlanguage:Make\nclippy::float_arithmetic\tinput.mak\t/^\t\t    -Dclippy::float_arithmetic$/;\"\td\tlanguage:CPreProcessor\nKBUILD_AFLAGS_KERNEL\tinput.mak\t/^KBUILD_AFLAGS_KERNEL :=$/;\"\tm\tlanguage:Make\nKBUILD_CFLAGS_KERNEL\tinput.mak\t/^KBUILD_CFLAGS_KERNEL :=$/;\"\tm\tlanguage:Make\nKBUILD_RUSTFLAGS_KERNEL\tinput.mak\t/^KBUILD_RUSTFLAGS_KERNEL :=$/;\"\tm\tlanguage:Make\nKBUILD_AFLAGS_MODULE\tinput.mak\t/^KBUILD_AFLAGS_MODULE  := -DMODULE$/;\"\tm\tlanguage:Make\nMODULE\tinput.mak\t/^KBUILD_AFLAGS_MODULE  := -DMODULE$/;\"\td\tlanguage:CPreProcessor\nKBUILD_CFLAGS_MODULE\tinput.mak\t/^KBUILD_CFLAGS_MODULE  := -DMODULE$/;\"\tm\tlanguage:Make\nMODULE\tinput.mak\t/^KBUILD_CFLAGS_MODULE  := -DMODULE$/;\"\td\tlanguage:CPreProcessor\nKBUILD_RUSTFLAGS_MODULE\tinput.mak\t/^KBUILD_RUSTFLAGS_MODULE := --cfg MODULE$/;\"\tm\tlanguage:Make\nall\tinput.mak\t/^all:$/;\"\tt\tlanguage:Make\nFOO\tinput.mak\t/^\t$(CC) -DFOO ...$/;\"\td\tlanguage:CPreProcessor\nmacdef\tinput.mak\t/^define macdef$/;\"\tm\tlanguage:Make\nMACDEF_CPPFLAGS\tinput.mak\t/^       MACDEF_CPPFLAGS  = -DMACDEFMAC0(X0,Y0,Z0)$/;\"\tm\tlanguage:Make\tmacro:macdef\nMACDEFMAC0\tinput.mak\t/^       MACDEF_CPPFLAGS  = -DMACDEFMAC0(X0,Y0,Z0)$/;\"\td\tlanguage:CPreProcessor\tsignature:(X0,Y0,Z0)\nMACDEFMAC1\tinput.mak\t/^       MACDEF_CPPFLAGS += -DMACDEFMAC1(X1,Y1,Z1)=X1##Y1##Z1$/;\"\td\tlanguage:CPreProcessor\tsignature:(X1,Y1,Z1)\nMACDEF_CPPFLAGS_BROKEN0\tinput.mak\t/^       MACDEF_CPPFLAGS_BROKEN0 = -DMACDEFMAC_BROKEN0(A0,B0,C0$/;\"\tm\tlanguage:Make\tmacro:macdef\nMACDEFMAC_BROKEN0\tinput.mak\t/^       MACDEF_CPPFLAGS_BROKEN0 = -DMACDEFMAC_BROKEN0(A0,B0,C0$/;\"\td\tlanguage:CPreProcessor\nMACDEF_CPPFLAGS_BROKEN1\tinput.mak\t/^       MACDEF_CPPFLAGS_BROKEN1 = -D MACDEFMAC_BROKEN1(A1,B1,C1$/;\"\tm\tlanguage:Make\tmacro:macdef\nMACDEFMAC_BROKEN1\tinput.mak\t/^       MACDEF_CPPFLAGS_BROKEN1 = -D MACDEFMAC_BROKEN1(A1,B1,C1$/;\"\td\tlanguage:CPreProcessor\nMACDEFMAC2\tinput.mak\t/^       MACDEF_CPPFLAGS += -DMACDEFMAC2(X2,Y2,Z2)=\"f b\"$/;\"\td\tlanguage:CPreProcessor\tsignature:(X2,Y2,Z2)\ninstall-man\tinput-0.mak\t/^install-man: $(srctree)\\/man\\/pfrut.8$/;\"\tt\tlanguage:Make\ninstall\tinput-0.mak\t/^install:$/;\"\tt\tlanguage:Make\nACPI_DEBUGGER0\tinput-1.mak\t/^CFLAGS0 += -DACPI_DEBUGGER0\\\\$/;\"\td\tlanguage:CPreProcessor\nCFLAGS1\tinput-1.mak\t/^CFLAGS1 ?= -DACPI_DEBUGGER1\\\\$/;\"\tm\tlanguage:Make\nACPI_DEBUGGER1\tinput-1.mak\t/^CFLAGS1 ?= -DACPI_DEBUGGER1\\\\$/;\"\td\tlanguage:CPreProcessor\nCFLAGS2\tinput-1.mak\t/^CFLAGS2 := -DACPI_DEBUGGER2\\\\$/;\"\tm\tlanguage:Make\nACPI_DEBUGGER2\tinput-1.mak\t/^CFLAGS2 := -DACPI_DEBUGGER2\\\\$/;\"\td\tlanguage:CPreProcessor\nCFLAGS3\tinput-1.mak\t/^CFLAGS3 = -DACPI_DEBUGGER3\\\\$/;\"\tm\tlanguage:Make\nACPI_DEBUGGER3\tinput-1.mak\t/^CFLAGS3 = -DACPI_DEBUGGER3\\\\$/;\"\td\tlanguage:CPreProcessor\nFOO_$(VAL)\tinput-2.mak\t/^X += -DFOO_$(VAL)$/;\"\td\tlanguage:CPreProcessor\nARM_ARCH_SELECTOR\tinput-2.mak\t/^ARM_ARCH_SELECTOR := $(filter -D__LINUX_ARM_ARCH__%, $(KBUILD_CFLAGS))$/;\"\tm\tlanguage:Make\n__LINUX_ARM_ARCH__%\tinput-2.mak\t/^ARM_ARCH_SELECTOR := $(filter -D__LINUX_ARM_ARCH__%, $(KBUILD_CFLAGS))$/;\"\td\tlanguage:CPreProcessor\n"
  },
  {
    "path": "Units/parser-make.r/cpp-marcros.d/input-0.mak",
    "content": "# Taken from linux/tools/power/acpi/tools/pfrut/Makefile\n# Don't capture object starting from $.\ninstall-man: $(srctree)/man/pfrut.8\n\t$(ECHO) \"  INST    \" pfrut.8\n\t$(QUIET) $(INSTALL_DATA) -D $< $(DESTDIR)$(mandir)/man8/pfrut.8\n\n# Taken from linux/arch/loongarch/Makefile\n# Don't capture object starting from -.h\ninstall:\n\t$(Q)install -D -m 755 $(KBUILD_IMAGE) $(INSTALL_PATH)/$(image-name-y)-$(KERNELRELEASE)\n\t$(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE)\n\t$(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)\n"
  },
  {
    "path": "Units/parser-make.r/cpp-marcros.d/input-1.mak",
    "content": "CFLAGS0 += -DACPI_DEBUGGER0\\\n\t-I.\n\nCFLAGS1 ?= -DACPI_DEBUGGER1\\\n\t-I.\n\nCFLAGS2 := -DACPI_DEBUGGER2\\\n\t-I.\n\nCFLAGS3 = -DACPI_DEBUGGER3\\\n\t-I.\n"
  },
  {
    "path": "Units/parser-make.r/cpp-marcros.d/input-2.mak",
    "content": "X += -DFOO_$(VAL)\nARM_ARCH_SELECTOR := $(filter -D__LINUX_ARM_ARCH__%, $(KBUILD_CFLAGS))\n"
  },
  {
    "path": "Units/parser-make.r/cpp-marcros.d/input.mak",
    "content": "# Derrived from linux/Makefile\n\nREALMODE_CFLAGS\t:= -std=gnu11 -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \\\n\t\t   -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \\\n\t\t   -fno-strict-aliasing -fomit-frame-pointer -fno-pic \\\n\t\t   -DMYDEF=1 \\\n\t\t   -DMYDEF0   \\\n\t\t   -DMYDEF1=1 \\\n\t\t   -DMYDEF2(X)=X   \\\n\t\t   -D MYDEF3      \\\n\t\t   -D MYDEF4=1    \\\n\t\t   -D MYDEF5(X)=X \\\n\t\t   -D'MYDEF6'      \\\n\t\t   -D'MYDEF7=1'    \\\n\t\t   -D'MYDEF8(X)=X' \\\n\t\t   -D 'MYDEF9'      \\\n\t\t   -D 'MYDEFa=1'    \\\n\t\t   -D 'MYDEFb(X)=X' \\\n\t\t   -D\"MYDEFc\"      \\\n\t\t   -D\"MYDEFd=1\"    \\\n\t\t   -D\"MYDEFe(X)=X\" \\\n\t\t   -D \"MYDEFf\"      \\\n\t\t   -D \"MYDEFg=1\"    \\\n\t\t   -D \"MYDEFh(X)=X\" \\\n\t\t   -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none)\n\nKBUILD_CPPFLAGS := -D__KERNEL__\nKBUILD_RUSTFLAGS := $(rust_common_flags) \\\n\t\t    -Cpanic=abort -Cembed-bitcode=n -Clto=n \\\n\t\t    -Cforce-unwind-tables=n -Ccodegen-units=1 \\\n\t\t    -Csymbol-mangling-version=v0 \\\n\t\t    -Crelocation-model=static \\\n\t\t    -Zfunction-sections=n \\\n\t\t    -Dclippy::float_arithmetic\n\nKBUILD_AFLAGS_KERNEL :=\nKBUILD_CFLAGS_KERNEL :=\nKBUILD_RUSTFLAGS_KERNEL :=\nKBUILD_AFLAGS_MODULE  := -DMODULE\nKBUILD_CFLAGS_MODULE  := -DMODULE\nKBUILD_RUSTFLAGS_MODULE := --cfg MODULE\n\nall:\n\t$(CC) -DFOO ...\n\ndefine macdef\n       MACDEF_CPPFLAGS  = -DMACDEFMAC0(X0,Y0,Z0)\n       MACDEF_CPPFLAGS += -DMACDEFMAC1(X1,Y1,Z1)=X1##Y1##Z1\n       MACDEF_CPPFLAGS_BROKEN0 = -DMACDEFMAC_BROKEN0(A0,B0,C0\n       MACDEF_CPPFLAGS_BROKEN1 = -D MACDEFMAC_BROKEN1(A1,B1,C1\n       MACDEF_CPPFLAGS += -DMACDEFMAC2(X2,Y2,Z2)=\"f b\"\nendif\n"
  },
  {
    "path": "Units/parser-make.r/in-define.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-make.r/in-define.d/expected.tags",
    "content": "m\tinput.mak\t/^define m$/;\"\tm\nx.mak\tinput.mak\t/^include x.mak$/;\"\tI\tmacro:m\nY\tinput.mak\t/^\tY=1$/;\"\tm\tmacro:m\n"
  },
  {
    "path": "Units/parser-make.r/in-define.d/input.mak",
    "content": "define m\ninclude x.mak\n\tY=1\nendef\n\n$(eval $(call m))\n"
  },
  {
    "path": "Units/parser-make.r/make.comment-in-rule.d/expected.tags",
    "content": "all\tinput.mak\t/^all:$/;\"\tt\n"
  },
  {
    "path": "Units/parser-make.r/make.comment-in-rule.d/input.mak",
    "content": "# all this is one single rule\nall:\n\ta=1; echo \"$$a\"\n# foo\n\tb=2; echo \"$$b\"\n  # foo\n\tc=3; echo \"$$c\"\n\u000b# foo\n\td=4; echo \"$$d\"\n\f# foo\n\te=5; echo \"$$e\"\n\n\n\tf=6; echo \"$$f\"\n # foo\n\n\tg=7; echo \"$$g\"\n"
  },
  {
    "path": "Units/parser-make.r/make.continuation.d/expected.tags",
    "content": "A\tinput.mak\t/^A = \\\\$/;\"\tm\nB\tinput.mak\t/^B = dummy$/;\"\tm\n"
  },
  {
    "path": "Units/parser-make.r/make.continuation.d/input.mak",
    "content": "\nA = \\\na=b \\\n \\\nb=c \\\n\t\\\nc=d \\\n\\\nd=e \\\n\nB = dummy\n"
  },
  {
    "path": "Units/parser-make.r/make.gnumake-not-special-targets.d/expected.tags",
    "content": ".all\tinput.mak\t/^.all:$/;\"\tt\n"
  },
  {
    "path": "Units/parser-make.r/make.gnumake-not-special-targets.d/input.mak",
    "content": ".SUFFIXES: .c .$(OBJEXT)\n.PHONY: check units fuzz noise tmain tinst clean-units clean-gcov run-gcov codecheck\n.all:\n\ta command here\n\n"
  },
  {
    "path": "Units/parser-make.r/make.gnumake-pattern-rules.d/expected.tags",
    "content": "%.o\tinput.mak\t/^%.o: %.c$/;\"\tt\n%.p\tinput.mak\t/^%.p %.q: %.d$/;\"\tt\n%.q\tinput.mak\t/^%.p %.q: %.d$/;\"\tt\n%a\tinput.mak\t/^%a b%:$/;\"\tt\nb%\tinput.mak\t/^%a b%:$/;\"\tt\n"
  },
  {
    "path": "Units/parser-make.r/make.gnumake-pattern-rules.d/input.mak",
    "content": "%.o: %.c\n\ttouch $@\n\n%.p %.q: %.d\n\ttouch $@\n\n%a b%:\n\ttouch $@\n"
  },
  {
    "path": "Units/parser-make.r/make.include.d/args.ctags",
    "content": "--extras=+r\n--fields=+re\n"
  },
  {
    "path": "Units/parser-make.r/make.include.d/expected.tags",
    "content": "$(1)\tinput.mk\t/^include $(1) $* Z0 $(shell) $(wildcard *.h) $(SHELL)$/;\"\tI\troles:included\n$(2)\tinput.mk\t/^sinclude $(2)$/;\"\tI\troles:optional\n$(3)\tinput.mk\t/^-include $(3)$/;\"\tI\troles:optional\n$(SHELL)\tinput.mk\t/^include $(1) $* Z0 $(shell) $(wildcard *.h) $(SHELL)$/;\"\tI\troles:included\n$(shell)\tinput.mk\t/^include $(1) $* Z0 $(shell) $(wildcard *.h) $(SHELL)$/;\"\tI\troles:included\n$(wildcard *.h)\tinput.mk\t/^include $(1) $* Z0 $(shell) $(wildcard *.h) $(SHELL)$/;\"\tI\troles:included\nA\tinput.mk\t/^include A$/;\"\tI\troles:included\nB\tinput.mk\t/^sinclude B$/;\"\tI\troles:optional\nC\tinput.mk\t/^-include C$/;\"\tI\troles:optional\nD\tinput.mk\t/^define D$/;\"\tm\troles:def\tend:11\nE\tinput.mk\t/^include E$/;\"\tI\tmacro:D\troles:included\nF\tinput.mk\t/^include F G H$/;\"\tI\troles:included\nG\tinput.mk\t/^include F G H$/;\"\tI\troles:included\nH\tinput.mk\t/^include F G H$/;\"\tI\troles:included\nI\tinput.mk\t/^sinclude I J K$/;\"\tI\troles:optional\nJ\tinput.mk\t/^sinclude I J K$/;\"\tI\troles:optional\nK\tinput.mk\t/^sinclude I J K$/;\"\tI\troles:optional\nL\tinput.mk\t/^-include L M N$/;\"\tI\troles:optional\nM\tinput.mk\t/^-include L M N$/;\"\tI\troles:optional\nN\tinput.mk\t/^-include L M N$/;\"\tI\troles:optional\nZ0\tinput.mk\t/^include $(1) $* Z0 $(shell) $(wildcard *.h) $(SHELL)$/;\"\tI\troles:included\na/b\tinput.mk\t/^include $@ $* $< &AND a\\/b a_b.mak #ABC$/;\"\tI\troles:included\na_b.mak\tinput.mk\t/^include $@ $* $< &AND a\\/b a_b.mak #ABC$/;\"\tI\troles:included\n"
  },
  {
    "path": "Units/parser-make.r/make.include.d/input.mk",
    "content": "include A\nsinclude B\n-include C\nincludeX\nsincludeY\n-includeZ\n=include I\n=includeJ\ndefine D\ninclude E\nendef\n\ninclude $@ $* $< &AND a/b a_b.mak #ABC\ninclude $(1) $* Z0 $(shell) $(wildcard *.h) $(SHELL)\nsinclude $(2)\n-include $(3)\n\ninclude F G H\nsinclude I J K\n-include L M N\n\n"
  },
  {
    "path": "Units/parser-make.r/make.multi-target.d/args.ctags",
    "content": "--fields=+en\n"
  },
  {
    "path": "Units/parser-make.r/make.multi-target.d/expected.tags",
    "content": "all\tinput.mak\t/^all: foo bar$/;\"\tt\tline:2\tend:3\nbar\tinput.mak\t/^foo bar: baz$/;\"\tt\tline:4\tend:6\nbaz\tinput.mak\t/^baz:$/;\"\tt\tline:7\tend:8\nfoo\tinput.mak\t/^foo bar: baz$/;\"\tt\tline:4\tend:6\n"
  },
  {
    "path": "Units/parser-make.r/make.multi-target.d/input.mak",
    "content": "\nall: foo bar\n\nfoo bar: baz\n\techo $@\n\nbaz:\n\techo $@\n"
  },
  {
    "path": "Units/parser-make.r/make.parenthesis.d/expected.tags",
    "content": "$(A)-$(A:.c=.o)\tinput.mk\t/^$(A)-$(A:.c=.o):$/;\"\tt\n${B}-${B:.c=.o}\tinput.mk\t/^${B}-${B:.c=.o}:$/;\"\tt\nA\tinput.mk\t/^A=X.c$/;\"\tm\nB\tinput.mk\t/^B=Y.c$/;\"\tm\n"
  },
  {
    "path": "Units/parser-make.r/make.parenthesis.d/input.mk",
    "content": "A=X.c\nB=Y.c\n$(A)-$(A:.c=.o):\n\techo $@\n${B}-${B:.c=.o}:\n\techo $@\n"
  },
  {
    "path": "Units/parser-make.r/make.target-with-parentheses.d/expected.tags",
    "content": "$(obj)/raid6int1.c\tinput.mak\t/^$(obj)\\/raid6int1.c:   F := 6$/;\"\tt\nF\tinput.mak\t/^$(obj)\\/raid6int1.c:   F := 6$/;\"\tm\n"
  },
  {
    "path": "Units/parser-make.r/make.target-with-parentheses.d/input.mak",
    "content": "$(obj)/raid6int1.c:   F := 6\n"
  },
  {
    "path": "Units/parser-make.r/make.variable-on-cmdline.d/expected.tags",
    "content": "fixme\tinput.mak\t/^fixme:$/;\"\tt\n"
  },
  {
    "path": "Units/parser-make.r/make.variable-on-cmdline.d/input.mak",
    "content": "fixme:\n\tcmd -g FOO=BAR\n"
  },
  {
    "path": "Units/parser-make.r/make.variable-set-if-undefined.d/expected.tags",
    "content": "FOO\tinput.mak\t/^FOO ?= bar$/;\"\tm\nURL\tinput.mak\t/^URL ?= \\\\$/;\"\tm\n"
  },
  {
    "path": "Units/parser-make.r/make.variable-set-if-undefined.d/input.mak",
    "content": "FOO ?= bar\nURL ?= \\\nhttps://docs.ctags.io\n"
  },
  {
    "path": "Units/parser-make.r/override-directive.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-make.r/override-directive.d/expected.tags",
    "content": "RUN_TESTS\tinput.mak\t/^override define RUN_TESTS$/;\"\tm\nINSTALL_RULE\tinput.mak\t/^override define INSTALL_RULE$/;\"\tm\nKBUILD_VERBOSE\tinput.mak\t/^override KBUILD_VERBOSE :=$/;\"\tm\n"
  },
  {
    "path": "Units/parser-make.r/override-directive.d/input.mak",
    "content": "# Taken from linux/tools/testing/selftests/powerpc/Makefile\noverride define RUN_TESTS\n\t+@for TARGET in $(SUB_DIRS); do \\\n\t\tBUILD_TARGET=$(OUTPUT)/$$TARGET;\t\\\n\t\t$(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\\\n\tdone;\nendef\n\noverride define INSTALL_RULE\n\t+@for TARGET in $(SUB_DIRS); do \\\n\t\tBUILD_TARGET=$(OUTPUT)/$$TARGET;\t\\\n\t\t$(MAKE) OUTPUT=$$BUILD_TARGET INSTALL_PATH=$$INSTALL_PATH/$$TARGET -C $$TARGET install;\\\n\tdone;\nendef\n\nifneq ($(findstring s,$(short-opts)),)\nquiet=silent_\noverride KBUILD_VERBOSE :=\nendif\n"
  },
  {
    "path": "Units/parser-make.r/same-line.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-make.r/same-line.d/expected.tags",
    "content": "target\tinput.mak\t/^target: macro = 1$/;\"\tt\tline:2\tend:2\nmacro\tinput.mak\t/^target: macro = 1$/;\"\tm\tline:2\n"
  },
  {
    "path": "Units/parser-make.r/same-line.d/input.mak",
    "content": "#\ntarget: macro = 1\n"
  },
  {
    "path": "Units/parser-make.r/shell-assignment-op.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-make.r/shell-assignment-op.d/expected.tags",
    "content": "hash\tinput.mak\t/^hash != printf '\\\\043'$/;\"\tm\nfile_list\tinput.mak\t/^file_list != find . -name '*.c'$/;\"\tm\n"
  },
  {
    "path": "Units/parser-make.r/shell-assignment-op.d/input.mak",
    "content": "hash != printf '\\043'\nfile_list != find . -name '*.c'\n"
  },
  {
    "path": "Units/parser-make.r/simple.mak.t/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-make.r/simple.mak.t/expected.tags",
    "content": "A\tinput.mak\t/^A = 1$/;\"\tm\nB\tinput.mak\t/^B := 2$/;\"\tm\nC\tinput.mak\t/^define C$/;\"\tm\na.o\tinput.mak\t/^a.o: D = 4$/;\"\tt\nD\tinput.mak\t/^a.o: D = 4$/;\"\tm\nE\tinput.mak\t/^\tE = 5$/;\"\tm\nb.o\tinput.mak\t/^b.o:$/;\"\tt\n$(obj)/raid6int1.c\tinput.mak\t/^$(obj)\\/raid6int1.c:   F := 6$/;\"\tt\nF\tinput.mak\t/^$(obj)\\/raid6int1.c:   F := 6$/;\"\tm\ndefault\tinput.mak\t/^default:$/;\"\tt\nG\tinput.mak\t/^G = 7 # ignore comment$/;\"\tm\nH\tinput.mak\t/^H = $(A:.y=.c) ${B:.l=.c}$/;\"\tm\nI\tinput.mak\t/^export I = 8$/;\"\tm\n"
  },
  {
    "path": "Units/parser-make.r/simple.mak.t/input.mak",
    "content": "A = 1\nB := 2\ndefine C\n3\nendef\n\n# D and E are target specific MAKE variables;\n# they are captured as a macro.\na.o: D = 4\n\tE = 5\n# ENV_VAR1 is not a target specific MAKE variables.\n# It is a shell variable in a recipe.\nb.o:\n\tENV_VAR1=something command\n$(obj)/raid6int1.c:   F := 6\ndefault:\n\tENV_VAR2=something command\n# COMMENT = nada\nG = 7 # ignore comment\nH = $(A:.y=.c) ${B:.l=.c}\nexport I = 8\nNO_TAG1 += \\\n-DA=0x00000000L \\\n-DB=0x00000000L\n"
  },
  {
    "path": "Units/parser-man.r/double-quoted.d/args.ctags",
    "content": "--sort=no\n--fields=+e\n"
  },
  {
    "path": "Units/parser-man.r/double-quoted.d/expected.tags",
    "content": "CTAGS\tinput.1\t/^.TH \"CTAGS\" 1 \"Version 0.0.0\" \"Darren Hiebert\" \"Universal Ctags\"$/;\"\tt\tend:7\nNAME\tinput.1\t/^.SH \"NAME\"$/;\"\ts\ttitle:CTAGS\tend:7\n"
  },
  {
    "path": "Units/parser-man.r/double-quoted.d/input.1",
    "content": ".TH \"CTAGS\" 1 \"Version 0.0.0\" \"Darren Hiebert\" \"Universal Ctags\"\n\n\n.SH \"NAME\"\nctags \\- Generate tag files for source code\n\n\n"
  },
  {
    "path": "Units/parser-man.r/simple.d/args.ctags",
    "content": "--sort=no\n--fields=+e\n"
  },
  {
    "path": "Units/parser-man.r/simple.d/expected.tags",
    "content": "CTAGS\tinput.1\t/^.TH CTAGS 1 \"Version 0.0.0\" \"Darren Hiebert\" \"Universal Ctags\"$/;\"\tt\tend:89\nNAME\tinput.1\t/^.SH \"NAME\"$/;\"\ts\ttitle:CTAGS\tend:6\nABSTRACT\tinput.1\t/^ABSTRACT$/;\"\ts\ttitle:CTAGS\tend:9\nSYNOPSIS\tinput.1\t/^.SH SYNOPSIS$/;\"\ts\ttitle:CTAGS\tend:16\nDESCRIPTION\tinput.1\t/^.SH \"DESCRIPTION\"$/;\"\ts\ttitle:CTAGS\tend:25\nAUTHOR\tinput.1\t/^AUTHOR$/;\"\ts\ttitle:CTAGS\tend:52\nsubsection1\tinput.1\t/^.SS subsection1$/;\"\tS\tsection:CTAGS\"\"AUTHOR\tend:34\nsubsection2\tinput.1\t/^.SS \"subsection2\"$/;\"\tS\tsection:CTAGS\"\"AUTHOR\tend:38\nsubsection3\tinput.1\t/^subsection3$/;\"\tS\tsection:CTAGS\"\"AUTHOR\tend:43\nsub section 4\tinput.1\t/^.SS sub section 4$/;\"\tS\tsection:CTAGS\"\"AUTHOR\tend:47\nsub section 5\tinput.1\t/^sub section 5$/;\"\tS\tsection:CTAGS\"\"AUTHOR\tend:52\nACKNOWLEDGMENT\tinput.1\t/^ACKNOWLEDGMENT$/;\"\ts\ttitle:CTAGS\tend:83\nsubsection6\tinput.1\t/^subsection6$/;\"\tS\tsection:CTAGS\"\"ACKNOWLEDGMENT\tend:61\nsubsection7\tinput.1\t/^subsection7$/;\"\tS\tsection:CTAGS\"\"ACKNOWLEDGMENT\tend:66\nsubsection8\tinput.1\t/^.SS \"subsection8\"$/;\"\tS\tsection:CTAGS\"\"ACKNOWLEDGMENT\tend:70\nsubsection9\tinput.1\t/^.SS subsection9$/;\"\tS\tsection:CTAGS\"\"ACKNOWLEDGMENT\tend:74\nsub section 10\tinput.1\t/^.SS sub section 10$/;\"\tS\tsection:CTAGS\"\"ACKNOWLEDGMENT\tend:78\nsub section 11\tinput.1\t/^sub section 11$/;\"\tS\tsection:CTAGS\"\"ACKNOWLEDGMENT\tend:83\nSEE ALSO\tinput.1\t/^.SH SEE ALSO$/;\"\ts\ttitle:CTAGS\tend:89\nsub section 12\tinput.1\t/^sub section 12$/;\"\tS\tsection:CTAGS\"\"SEE ALSO\tend:89\n"
  },
  {
    "path": "Units/parser-man.r/simple.d/input.1",
    "content": ".TH CTAGS 1 \"Version 0.0.0\" \"Darren Hiebert\" \"Universal Ctags\"\n\n\n.SH \"NAME\"\nctags \\- Generate tag files for source code\n\n.SH\nABSTRACT\n\n.SH SYNOPSIS\n.TP 6\n\\fBctags\\fP [\\fBoptions\\fP] [\\fIfile(s)\\fP]\n.TP 6\n\\fBetags\\fP [\\fBoptions\\fP] [\\fIfile(s)\\fP]\n\n\n.SH \"DESCRIPTION\"\nThe \\fBctags\\fP and \\fBetags\\fP programs (hereinafter collectively referred to\nas \\fBctags\\fP, except where distinguished) generate an index (or \"tag\") file\nfor a variety of language objects found in \\fIfile(s)\\fP.\nThis tag file allows these items to be quickly and easily located by a text\neditor or other utility. A \"tag\" signifies a language object for which an\nindex entry is available (or, alternatively, the index entry created for that\nobject).\n\n.SH\nAUTHOR\n.sp\nThe Developers.\n\n.SS subsection1\n.sp\nThis is the first subsection.\n\n.SS \"subsection2\"\n.sp\nThis is the second subsection.\n\n.SS\nsubsection3\n.sp\nThis is the third subsection.\n\n.SS sub section 4\n.sp\nThis is the fourth subsection.\n\n.SS\nsub section 5\n.sp\nThis is the fifth subsection.\n\n.SH\nACKNOWLEDGMENT\n.sp\n\n.SS\nsubsection6\n.sp\nThis is the sixth subsection.\n\n.SS\nsubsection7\n.sp\nThis is the seventh subsection.\n\n.SS \"subsection8\"\n.sp\nThis is the eight subsection.\n\n.SS subsection9\n.sp\nThis is the ninth subsection.\n\n.SS sub section 10\n.sp\nThis is the tenth subsection.\n\n.SS\nsub section 11\n.sp\nThis is the eleventh subsection.\n\n.SH SEE ALSO\n.sp\nSee tags(5) for the details of tags file format.\n\n.SS\nsub section 12\n"
  },
  {
    "path": "Units/parser-markdown.r/backquote.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-markdown.r/backquote.d/expected.tags",
    "content": "A\tinput.md\t/^# A$/;\"\tc\n"
  },
  {
    "path": "Units/parser-markdown.r/backquote.d/input.md",
    "content": "  `O`\n# A\n\n"
  },
  {
    "path": "Units/parser-markdown.r/c-guest.d/README",
    "content": "This triggered an assertion failure in mio_setpos.\n"
  },
  {
    "path": "Units/parser-markdown.r/c-guest.d/args.ctags",
    "content": "--extras=+g\n"
  },
  {
    "path": "Units/parser-markdown.r/c-guest.d/expected.tags",
    "content": "foo\tinput.md\t/^int foo(void) {$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-markdown.r/c-guest.d/input.md",
    "content": "```c\nint foo(void) {\n```\n```c\n\n```\n```c\n\n```\n\n"
  },
  {
    "path": "Units/parser-markdown.r/code-block-under-items.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+{language}\n"
  },
  {
    "path": "Units/parser-markdown.r/code-block-under-items.d/expected.tags",
    "content": "test\tinput.md\t/^# test$/;\"\tc\tlanguage:Markdown\ndepartment2\tinput.md\t/^  create table department2($/;\"\tt\tlanguage:SQL\nid\tinput.md\t/^      id int primary key,$/;\"\tE\tlanguage:SQL\ttable:department2\nname\tinput.md\t/^      name varchar(20),$/;\"\tE\tlanguage:SQL\ttable:department2\ncomment\tinput.md\t/^      comment varchar(100)$/;\"\tE\tlanguage:SQL\ttable:department2\ndepartment3\tinput.md\t/^  create table department3($/;\"\tt\tlanguage:SQL\nid\tinput.md\t/^      id int,$/;\"\tE\tlanguage:SQL\ttable:department3\nname\tinput.md\t/^      name varchar(20),$/;\"\tE\tlanguage:SQL\ttable:department3\ncomment\tinput.md\t/^      comment varchar(100),$/;\"\tE\tlanguage:SQL\ttable:department3\nfoo\tinput.md\t/^  foo()$/;\"\tf\tlanguage:Sh\n"
  },
  {
    "path": "Units/parser-markdown.r/code-block-under-items.d/input.md",
    "content": "<!-- Taken from #3625 submitted by @jiz4oh -->\n# test\n\n- primary key：\n\n  ```sql\n  # method 1\n  create table department2(\n      id int primary key,\n      name varchar(20),\n      comment varchar(100)\n      );\n  \n  # method 2\n  create table department3(\n      id int,\n      name varchar(20),\n      comment varchar(100),\n      constraint pk_name primary key(id); \n  ```\n\n- second key:\n\n  ```sh\n  foo()\n  {\n\t  :\n  }\n  ```\n"
  },
  {
    "path": "Units/parser-markdown.r/empty-frontmatter.d/README",
    "content": "This is a crash test.\nThe input is taken from linux-5.14.0-362.8.1.el9.x86_64/redhat/rhdocs/content/docs/_index.md .\n"
  },
  {
    "path": "Units/parser-markdown.r/empty-frontmatter.d/args.ctags",
    "content": "--extras=*\n--fields=*\n--kinds-all=*\n"
  },
  {
    "path": "Units/parser-markdown.r/empty-frontmatter.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-markdown.r/empty-frontmatter.d/input.md",
    "content": "---\n---\n{{< toc-tree >}}\n"
  },
  {
    "path": "Units/parser-markdown.r/footnotes.d/args.ctags",
    "content": "--sort=no\n--fields=+nK\n"
  },
  {
    "path": "Units/parser-markdown.r/footnotes.d/expected.tags",
    "content": "1\tinput.md\t/^[^1]: This is the first footnote.$/;\"\tfootnote\tline:4\nbignote\tinput.md\t/^[^bignote]: Here's one with multiple paragraphs and code.$/;\"\tfootnote\tline:6\n"
  },
  {
    "path": "Units/parser-markdown.r/footnotes.d/input.md",
    "content": "<!-- Taken from https://www.markdownguide.org/extended-syntax/#footnotes -->\nHere's a simple footnote,[^1] and here's a longer one.[^bignote]\n\n[^1]: This is the first footnote.\n\n[^bignote]: Here's one with multiple paragraphs and code.\n\n    Indent paragraphs to include them in the footnote.\n\n    `{ my code }`\n\n    Add as many paragraphs as you like.\n"
  },
  {
    "path": "Units/parser-markdown.r/frontmatter.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n"
  },
  {
    "path": "Units/parser-markdown.r/frontmatter.d/expected.tags",
    "content": "About this input\tinput.md\t/^# About this input$/;\"\tc\nPython\tinput.md\t/^title: Python$/;\"\tt\nTITLE in region ended with ...\tinput-0.md\t/^title: TITLE in region ended with .../;\"\tt\n"
  },
  {
    "path": "Units/parser-markdown.r/frontmatter.d/input-0.md",
    "content": "---\ntitle: TITLE in region ended with ...\n...\n"
  },
  {
    "path": "Units/parser-markdown.r/frontmatter.d/input.md",
    "content": "---\ntitle: Python\ndraft: false\ndate: 2021-05-16T13:15:31-05:00\ntags: ['code','python']\nmenu:\n    main:\n        parent: 'code'\nlayout: default\n---\n\n# About this input\n\nThis input is taken from #3027 at github submitted by @rickalex21.\n"
  },
  {
    "path": "Units/parser-markdown.r/frontmatter.d/languages",
    "content": "Yaml\n"
  },
  {
    "path": "Units/parser-markdown.r/gaps-in-section-hierarchy.d/args.ctags",
    "content": "--sort=no\n--fields=+Ke\n--fields-Markdown=+{sectionMarker}\n--_scopesep-Markdown=*/*:|\n"
  },
  {
    "path": "Units/parser-markdown.r/gaps-in-section-hierarchy.d/expected.tags",
    "content": "A\tinput.md\t/^# A$/;\"\tchapter\tend:10\tsectionMarker:#\nB\tinput.md\t/^### B$/;\"\tsubsection\tchapter:A\tend:4\tsectionMarker:#\nC\tinput.md\t/^## C$/;\"\tsection\tchapter:A\tend:8\tsectionMarker:#\nD\tinput.md\t/^### D$/;\"\tsubsection\tsection:A|C\tend:8\tsectionMarker:#\nE\tinput.md\t/^## E$/;\"\tsection\tchapter:A\tend:10\tsectionMarker:#\nF\tinput.md\t/^# F$/;\"\tchapter\tend:22\tsectionMarker:#\nH\tinput.md\t/^###### H$/;\"\tl5subsection\tchapter:F\tend:14\tsectionMarker:#\nI\tinput.md\t/^##### I$/;\"\tl4subsection\tchapter:F\tend:16\tsectionMarker:#\nJ\tinput.md\t/^#### J$/;\"\tsubsubsection\tchapter:F\tend:18\tsectionMarker:#\nK\tinput.md\t/^### K$/;\"\tsubsection\tchapter:F\tend:20\tsectionMarker:#\nL\tinput.md\t/^## L$/;\"\tsection\tchapter:F\tend:22\tsectionMarker:#\nM\tinput.md\t/^# M$/;\"\tchapter\tend:34\tsectionMarker:#\nN\tinput.md\t/^### N ###$/;\"\tsubsection\tchapter:M\tend:26\tsectionMarker:##\nO\tinput.md\t/^## O ##$/;\"\tsection\tchapter:M\tend:34\tsectionMarker:##\nP\tinput.md\t/^###### P ######$/;\"\tl5subsection\tsection:M|O\tend:30\tsectionMarker:##\nQ\tinput.md\t/^### Q ###$/;\"\tsubsection\tsection:M|O\tend:34\tsectionMarker:##\nR\tinput.md\t/^###### R ######$/;\"\tl5subsection\tsubsection:M|O|Q\tend:34\tsectionMarker:##\nS\tinput.md\t/^S$/;\"\tchapter\tend:42\tsectionMarker:=\nT\tinput.md\t/^###### T ######$/;\"\tl5subsection\tchapter:S\tend:39\tsectionMarker:##\nU\tinput.md\t/^U$/;\"\tsection\tchapter:S\tend:42\tsectionMarker:-\nV\tinput.md\t/^# V #$/;\"\tchapter\tend:47\tsectionMarker:##\nW\tinput.md\t/^W$/;\"\tsection\tchapter:V\tend:47\tsectionMarker:-\nX\tinput.md\t/^X$/;\"\tchapter\tend:53\tsectionMarker:=\nY\tinput.md\t/^#### Y ####$/;\"\tsubsubsection\tchapter:X\tend:53\tsectionMarker:##\nZ\tinput.md\t/^###### Z ######$/;\"\tl5subsection\tsubsubsection:X|Y\tend:53\tsectionMarker:##\n"
  },
  {
    "path": "Units/parser-markdown.r/gaps-in-section-hierarchy.d/input.md",
    "content": "# A\n\n### B\n\n## C\n\n### D\n\n## E\n\n# F\n\n###### H\n\n##### I\n\n#### J\n\n### K\n\n## L\n\n# M\n\n### N ###\n\n## O ##\n\n###### P ######\n\n### Q ###\n\n###### R ######\n\nS\n=============\n\n###### T ######\n\nU\n--------------\n\n# V #\n\nW\n--------------\n\nX\n=============\n\n#### Y ####\n\n###### Z ######\n"
  },
  {
    "path": "Units/parser-markdown.r/hashtags-utf8.d/args.ctags",
    "content": "--sort=no\n--fields=+e\n--fields-Markdown=+{sectionMarker}\n--extras=+g\n"
  },
  {
    "path": "Units/parser-markdown.r/hashtags-utf8.d/expected.tags",
    "content": "标签\tinput.md\t/^#标签 #태그 #وسم   $/;\"\th\n태그\tinput.md\t/^#标签 #태그 #وسم   $/;\"\th\nوسم\tinput.md\t/^#标签 #태그 #وسم   $/;\"\th\nt1\tinput.md\t/^#t1 #t2#invalid#invalid2$/;\"\th\nt2\tinput.md\t/^#t1 #t2#invalid#invalid2$/;\"\th\nta\tinput.md\t/^#ta #123$/;\"\th\n9_\tinput.md\t/^#9_$/;\"\th\n-_-\tinput.md\t/^#-_-$/;\"\th\nt/s1\tinput.md\t/^#t\\/s1 #t\\/s2$/;\"\th\nt/s2\tinput.md\t/^#t\\/s1 #t\\/s2$/;\"\th\nt4-5-6\tinput.md\t/^#t4-5-6+excluded  #t7;excluded    #t8#excluded#excluded$/;\"\th\nt7\tinput.md\t/^#t4-5-6+excluded  #t7;excluded    #t8#excluded#excluded$/;\"\th\nt8\tinput.md\t/^#t4-5-6+excluded  #t7;excluded    #t8#excluded#excluded$/;\"\th\nhashtag\tinput.md\t/^text#text #hashtag text#text$/;\"\th\nincluded\tinput.md\t/^#included$/;\"\th\nincluded\tinput.md\t/^   #included$/;\"\th\nタブ1/タブ2\tinput.md\t/^ excluded #タブ1\\/タブ2 excluded$/;\"\th\nT_in_quote\tinput.md\t/^> #T_in_quote$/;\"\th\nT_in_quote\tinput.md\t/^>> #T_in_quote$/;\"\th\nTitle\tinput.md\t/^# Title #$/;\"\tc\tend:22\tsectionMarker:##\nt3\tinput.md\t/^# Title2 #t3$/;\"\th\tchapter:Title\nTitle2 #t3\tinput.md\t/^# Title2 #t3$/;\"\tc\tend:39\tsectionMarker:#\nt4\tinput.md\t/^#t4$/;\"\th\tchapter:Title2 #t3\ntag-in-list\tinput.md\t/^- #tag-in-list$/;\"\th\tchapter:Title2 #t3\n/\tinput.md\t/^#\\/$/;\"\th\tchapter:Title2 #t3\n//////\tinput.md\t/^#\\/\\/\\/\\/\\/\\/$/;\"\th\tchapter:Title2 #t3\n"
  },
  {
    "path": "Units/parser-markdown.r/hashtags-utf8.d/input.md",
    "content": "#标签 #태그 #وسم   \n#t1 #t2#invalid#invalid2\n\n123 and 4 are invalid\n#ta #123\n#4\n\n#9_\n#-_-\n#t/s1 #t/s2\n#t4-5-6+excluded  #t7;excluded    #t8#excluded#excluded\ntext#text #hashtag text#text\n#included\n    #excluded1\n\t#excluded2\n   #included\n excluded #タブ1/タブ2 excluded\n\n>#invalid\n> #T_in_quote\n>> #T_in_quote\n# Title #\n# Title2 #t3\n标签\n\n            #invalid3\n\n\n#t4\n===\n\n- #tag-in-list\n- item 2\n\n##invalid\n##invalid#invalid\n\n#/\n#//////\n"
  },
  {
    "path": "Units/parser-markdown.r/packcc-parser-running-within-code-block-with-bom.d/args.ctags",
    "content": "--languages=+TOML\n\n--extras=+g\n"
  },
  {
    "path": "Units/parser-markdown.r/packcc-parser-running-within-code-block-with-bom.d/expected.tags",
    "content": "d\tinput.md\t/^[d]$/;\"\tt\no\tinput.md\t/^[o]$/;\"\tt\n"
  },
  {
    "path": "Units/parser-markdown.r/packcc-parser-running-within-code-block-with-bom.d/features",
    "content": "packcc\n"
  },
  {
    "path": "Units/parser-markdown.r/packcc-parser-running-within-code-block-with-bom.d/input.md",
    "content": "﻿T\n```toml\n# Th\n[o]\n[d]\n```\n"
  },
  {
    "path": "Units/parser-markdown.r/packcc-parser-running-within-code-block.d/args.ctags",
    "content": "--languages=+TOML\n\n--extras=+g\n"
  },
  {
    "path": "Units/parser-markdown.r/packcc-parser-running-within-code-block.d/expected.tags",
    "content": "d\tinput.md\t/^[d]$/;\"\tt\no\tinput.md\t/^[o]$/;\"\tt\n"
  },
  {
    "path": "Units/parser-markdown.r/packcc-parser-running-within-code-block.d/features",
    "content": "packcc\n"
  },
  {
    "path": "Units/parser-markdown.r/packcc-parser-running-within-code-block.d/input.md",
    "content": "T\n```toml\n# Th\n[o]\n[d]\n```\n"
  },
  {
    "path": "Units/parser-markdown.r/scope-field-markdown.d/args.ctags",
    "content": "--sort=no\n--fields=+e\n"
  },
  {
    "path": "Units/parser-markdown.r/scope-field-markdown.d/expected.tags",
    "content": "a0\tinput.md\t/^# a0$/;\"\tc\tend:6\nb0\tinput.md\t/^## b0$/;\"\ts\tchapter:a0\tend:6\nc0\tinput.md\t/^### c0$/;\"\tS\tsection:a0\"\"b0\tend:6\na1\tinput.md\t/^# a1$/;\"\tc\tend:8\na2\tinput.md\t/^# a2$/;\"\tc\tend:25\nb20\tinput.md\t/^## b20$/;\"\ts\tchapter:a2\tend:12\nb21\tinput.md\t/^## b21$/;\"\ts\tchapter:a2\tend:16\nc21\tinput.md\t/^### c21$/;\"\tS\tsection:a2\"\"b21\tend:16\nb22\tinput.md\t/^## b22$/;\"\ts\tchapter:a2\tend:22\nc220\tinput.md\t/^### c220$/;\"\tS\tsection:a2\"\"b22\tend:20\nc221\tinput.md\t/^### c221$/;\"\tS\tsection:a2\"\"b22\tend:22\nb23\tinput.md\t/^b23$/;\"\ts\tchapter:a2\tend:25\na3\tinput.md\t/^a3$/;\"\tc\tend:37\nb31\tinput.md\t/^b31$/;\"\ts\tchapter:a3\tend:31\nb32\tinput.md\t/^b32$/;\"\ts\tchapter:a3\tend:37\nc320\tinput.md\t/^### c320$/;\"\tS\tsection:a3\"\"b32\tend:35\nc321\tinput.md\t/^### c321$/;\"\tS\tsection:a3\"\"b32\tend:37\na4\tinput.md\t/^a4$/;\"\tc\tend:39\n"
  },
  {
    "path": "Units/parser-markdown.r/scope-field-markdown.d/input.md",
    "content": "# a0\n\n## b0\n\n### c0\n\n# a1\n\n# a2\n\n## b20\n\n## b21\n\n### c21\n\n## b22\n\n### c220\n\n### c221\n\nb23\n---\n\na3\n===\n\nb31\n---\n\nb32\n---\n\n### c320\n### c321\n\na4\n===\n"
  },
  {
    "path": "Units/parser-markdown.r/section-prefixed-with-spaces.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-markdown.r/section-prefixed-with-spaces.d/expected.tags",
    "content": "should\tinput.md\t/^  #should NOT be included0 as a chapter$/;\"\th\nshould be included0 as a chapter\tinput.md\t/^  # should be included0 as a chapter$/;\"\tc\nshould\tinput.md\t/^ #should NOT be included1 as a chapter$/;\"\th\tchapter:should be included0 as a chapter\nshould be included1 as a chapter\tinput.md\t/^ # should be included1 as a chapter$/;\"\tc\nshould\tinput.md\t/^#should NOT be included2 as a chapter$/;\"\th\tchapter:should be included1 as a chapter\nshould be included2 as a chapter\tinput.md\t/^# should be included2 as a chapter$/;\"\tc\nnot-title-1\tinput.md\t/^   #not-title-1$/;\"\th\tchapter:should be included2 as a chapter\ntitle 1\tinput.md\t/^   # title 1$/;\"\tc\ntitle 2\tinput.md\t/^ ## title 2$/;\"\ts\tchapter:title 1\ntitle 3\tinput.md\t/^   # title 3$/;\"\tc\ntitle 4\tinput.md\t/^ ### title 4$/;\"\tS\tchapter:title 3\ntitle 5\tinput.md\t/^ #### title 5$/;\"\tt\tsubsection:title 3\"\"title 4\ntitle 6\tinput.md\t/^ ##### title 6$/;\"\tT\tsubsubsection:title 3\"\"title 4\"\"title 5\ntitle 7\tinput.md\t/^ ###### title 7$/;\"\tu\tl4subsection:title 3\"\"title 4\"\"title 5\"\"title 6\n"
  },
  {
    "path": "Units/parser-markdown.r/section-prefixed-with-spaces.d/input.md",
    "content": "  #should NOT be included0 as a chapter\n\n  # should be included0 as a chapter\n\n #should NOT be included1 as a chapter\n\n # should be included1 as a chapter\n\n#should NOT be included2 as a chapter\n\n# should be included2 as a chapter\n\nThese input is taken from Yinzuo Jiang (@jiangyinzuo)'s\ncommit in #3747.\n\n\n   #not-title-1\n\n\n   # title 1\n ## title 2\n   # title 3\n ### title 4\n #### title 5\n ##### title 6\n ###### title 7\n\nxxx# not title 2\nxxx## not title 3\nxxx### not title 4\nxxx#### not title 5\n\t# not title 6 when starting with tab\n\n..##### not title 7\n ####### not title 8\n"
  },
  {
    "path": "Units/parser-markdown.r/simple-markdown.d/args.ctags",
    "content": "--sort=no\n--fields=+e\n--fields-Markdown=+{sectionMarker}\n--extras=+g\n"
  },
  {
    "path": "Units/parser-markdown.r/simple-markdown.d/expected.tags",
    "content": "a\tinput.md\t/^# a$/;\"\tc\tend:12\tsectionMarker:#\nb\tinput.md\t/^## b$/;\"\ts\tchapter:a\tend:12\tsectionMarker:#\nc\tinput.md\t/^### c$/;\"\tS\tsection:a\"\"b\tend:12\tsectionMarker:#\nd\tinput.md\t/^#### d$/;\"\tt\tsubsection:a\"\"b\"\"c\tend:12\tsectionMarker:#\ne\tinput.md\t/^##### e$/;\"\tT\tsubsubsection:a\"\"b\"\"c\"\"d\tend:12\tsectionMarker:#\nf\tinput.md\t/^###### f$/;\"\tu\tl4subsection:a\"\"b\"\"c\"\"d\"\"e\tend:12\tsectionMarker:#\ng\tinput.md\t/^# g #$/;\"\tc\tend:13\tsectionMarker:##\nh\tinput.md\t/^# h ##$/;\"\tc\tend:61\tsectionMarker:##\ni\tinput.md\t/^## i #$/;\"\ts\tchapter:h\tend:16\tsectionMarker:##\nj\tinput.md\t/^## j ##$/;\"\ts\tchapter:h\tend:17\tsectionMarker:##\nk\tinput.md\t/^## k ###$/;\"\ts\tchapter:h\tend:61\tsectionMarker:##\nl\tinput.md\t/^### l #$/;\"\tS\tsection:h\"\"k\tend:20\tsectionMarker:##\nm\tinput.md\t/^### m ##$/;\"\tS\tsection:h\"\"k\tend:21\tsectionMarker:##\nn\tinput.md\t/^### n ###$/;\"\tS\tsection:h\"\"k\tend:22\tsectionMarker:##\no\tinput.md\t/^### o ###$/;\"\tS\tsection:h\"\"k\tend:61\tsectionMarker:##\np\tinput.md\t/^#### p #$/;\"\tt\tsubsection:h\"\"k\"\"o\tend:25\tsectionMarker:##\nq\tinput.md\t/^#### q #####$/;\"\tt\tsubsection:h\"\"k\"\"o\tend:61\tsectionMarker:##\nr\tinput.md\t/^##### r #$/;\"\tT\tsubsubsection:h\"\"k\"\"o\"\"q\tend:28\tsectionMarker:##\ns\tinput.md\t/^##### s ######$/;\"\tT\tsubsubsection:h\"\"k\"\"o\"\"q\tend:61\tsectionMarker:##\nt\tinput.md\t/^###### t #$/;\"\tu\tl4subsection:h\"\"k\"\"o\"\"q\"\"s\tend:59\tsectionMarker:##\nu\tinput.md\t/^###### u #######$/;\"\tu\tl4subsection:h\"\"k\"\"o\"\"q\"\"s\tend:61\tsectionMarker:##\nA\tinput.md\t/^A$/;\"\tc\tend:64\tsectionMarker:=\nB\tinput.md\t/^B$/;\"\tc\tend:74\tsectionMarker:=\nC\tinput.md\t/^C$/;\"\tc\tend:128\tsectionMarker:=\nD\tinput.md\t/^D$/;\"\ts\tchapter:C\tend:100\tsectionMarker:-\nE\tinput.md\t/^E$/;\"\ts\tchapter:C\tend:103\tsectionMarker:-\nF\tinput.md\t/^F$/;\"\ts\tchapter:C\tend:106\tsectionMarker:-\nG\tinput.md\t/^ G$/;\"\ts\tchapter:C\tend:109\tsectionMarker:-\nH\tinput.md\t/^  H$/;\"\ts\tchapter:C\tend:112\tsectionMarker:-\nI\tinput.md\t/^   I$/;\"\ts\tchapter:C\tend:128\tsectionMarker:-\nC\\\\#\tinput.md\t/^# C\\\\#$/;\"\tc\tend:146\tsectionMarker:#\nJ\tinput.md\t/^J$/;\"\ts\tchapter:C\\\\#\tend:133\tsectionMarker:-\nK\tinput.md\t/^K$/;\"\ts\tchapter:C\\\\#\tend:136\tsectionMarker:-\nL\tinput.md\t/^L$/;\"\ts\tchapter:C\\\\#\tend:146\tsectionMarker:-\nx\tinput.md\t/^function x$/;\"\tf\ny\tinput.md\t/^function y$/;\"\tf\nz\tinput.md\t/^z()$/;\"\tf\nf\tinput.md\t/^sub f {$/;\"\ts\ng\tinput.md\t/^sub g$/;\"\ts\nh\tinput.md\t/^sub h$/;\"\ts\n"
  },
  {
    "path": "Units/parser-markdown.r/simple-markdown.d/input.md",
    "content": "# a\n\n## b\n\n### c\n\n#### d\n\n##### e\n\n###### f\n\n# g #\n# h ##\n\n## i #\n## j ##\n## k ###\n\n### l #\n### m ##\n### n ###\n### o ###\n\n#### p #\n#### q #####\n\n##### r #\n##### s ######\n\n```sh\n# A COMMENT LINE in SHELL SYNTAX\nfunction x\n{\n\techo 'Hello, World!'\n}\n```\n###### t #\n```sh\n# THE OTHER COMMENT LINE in SHELL SYNTAX\nfunction y\n{\n\tcat <<<EOF\n\t~~~\n# ANOTHER COMMENT LINE in SHELL SYNTAX\n\t~~~\n~~~\n# ANOTHER COMMENT LINE in SHELL SYNTAX\n~~~\nEOF\n}\n```\n\n``` sh\nz()\n{\n}\n```\n\n###### u #######\n\nA\n=\n\nB\n==\n\n~~~perl\n# A COMMENT LINE in PERL SYNTAX\nsub f {\n    my ($line, $opts) = @_;\n\treturn $line;\n}\n~~~\nC\n===\n\n~~~perl\n# THE OTHER COMMENT LINE in PERL SYNTAX\nsub g\n{\n    print <<EOF;\n\t```\n# ANOTHER COMMENT LINE in PERL SYNTAX\n\t```\n```\n# ANOTHER COMMENT LINE in PERL SYNTAX\n```\nEOF\n}\n~~~\n\n~~~\tperl\nsub h\n{\n}\n~~~\t\nD\n-\n\nE\n--\n\nF\n---\n\n G\n-\n\n  H\n-\n\n   I\n-\n\n    indented\n-\n\n\tindented_with_tab\n-\n\n \tindented_with_space_and_tab\n-\n\ntext\n- ignored\n-\n\n# C\\#\n\nJ\n -\n\nK\n  -\n\nL\n   -\n\nignored\n    -\n\n```foo```\n\n> quoted\n---\n"
  },
  {
    "path": "Units/parser-markdown.r/xml-comment.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-markdown.r/xml-comment.d/expected.tags",
    "content": "EXTRACT ME 1\tinput.md\t/^# EXTRACT ME 1$/;\"\tc\n"
  },
  {
    "path": "Units/parser-markdown.r/xml-comment.d/input.md",
    "content": "<!--\n# SKIP ME 1\n-->\n\n<!-- # SKIP ME 2 -->\n\n# EXTRACT ME 1\n"
  },
  {
    "path": "Units/parser-markdown.r/yaml-in-code-block.d/README",
    "content": "Taken from https://github.com/universal-ctags/ctags/issues/2965 submitted by @rickalex21.\n"
  },
  {
    "path": "Units/parser-markdown.r/yaml-in-code-block.d/args.ctags",
    "content": "--sort=no\n--extras=+{guest}\n--fields=+{language}{end}\n"
  },
  {
    "path": "Units/parser-markdown.r/yaml-in-code-block.d/expected.tags",
    "content": "Mline\tinput.md\t/^### Mline$/;\"\tS\tlanguage:Markdown\tend:25\nMline2\tinput.md\t/^### Mline2$/;\"\tS\tlanguage:Markdown\tend:26\nEOF\tinput.md\t/^cat <<EOF$/;\"\th\tlanguage:Sh\tend:19\nhello\tinput.md\t/^hello()$/;\"\tf\tlanguage:Sh\n"
  },
  {
    "path": "Units/parser-markdown.r/yaml-in-code-block.d/input.md",
    "content": "I will be capturing these animal tags with ```--_mtable-regex```.\n\n```yaml\n---\ntitle: \"Animals\"\ndate: 2021-04-17T14:22:02-05:00\ndraft: false\ntags: ['dog','cat','bear','lion','monkey','tiger','dolphin','elephant','whale']\n---\n```\n\n### Mline\n\n---\n\n```sh\ncat <<EOF\n---------\nEOF\nhello()\n{\n\techo \"hello\"\n}\n```\n\n### Mline2\n"
  },
  {
    "path": "Units/parser-matlab.r/matchfail.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-matlab.r/matchfail.d/expected.tags",
    "content": "func1\tinput.m\t/^function [x,y,z] = func1 $/;\"\tf\nfunc2\tinput.m\t/^function x = func2 $/;\"\tf\nfunc3\tinput.m\t/^function func3 $/;\"\tf\nfunc4\tinput.m\t/^function y = func4(a, b, c)$/;\"\tf\nfunc5\tinput.m\t/^function func5   % this comment should be ignored --> X = FAIL5$/;\"\tf\nfunctionality\tinput.m\t/^functionality = FAIL6; % this is not a function and should not be parsed$/;\"\tv\n"
  },
  {
    "path": "Units/parser-matlab.r/matchfail.d/input.m",
    "content": "function [x,y,z] = func1 \nend\nfunction x = func2 \nend\nfunction func3 \nend\nfunction y = func4(a, b, c)\nend\nfunction func5   % this comment should be ignored --> X = FAIL5\nend\nfunctionality = FAIL6; % this is not a function and should not be parsed\n"
  },
  {
    "path": "Units/parser-matlab.r/matlab_backtracking.m.d/expected.tags",
    "content": "backtrack\tinput.m\t/^function [xn,fn,fcall] = backtrack(xc,d,fc,fnc,DDfnc,c,gamma,eps)$/;\"\tf\ncDDfnc\tinput.m\t/^        cDDfnc  =  gamma*cDDfnc;$/;\"\tv\ncDDfnc\tinput.m\t/^cDDfnc  =   c*DDfnc;$/;\"\tv\nd\tinput.m\t/^        d       =  gamma*d;$/;\"\tv\nfcall\tinput.m\t/^        fcall   =  fcall+1;$/;\"\tv\nfcall\tinput.m\t/^fcall   =   1 ;$/;\"\tv\nfn\tinput.m\t/^        fn      =  feval(fnc,xn);$/;\"\tv\nfn\tinput.m\t/^fn      =   feval(fnc,xn);$/;\"\tv\nxn\tinput.m\t/^                        xn  =  xc;$/;\"\tv\nxn\tinput.m\t/^        xn      =  xc+d;$/;\"\tv\nxn\tinput.m\t/^xn      =   xc+d;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-matlab.r/matlab_backtracking.m.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/parser-matlab.r/matlab_backtracking.m.d/input.m",
    "content": "% http://www.math.washington.edu/~burke/crs/516/HTML/backtrack.html\r\n% Backtracking Linesearch\r\n\r\nfunction [xn,fn,fcall] = backtrack(xc,d,fc,fnc,DDfnc,c,gamma,eps)\r\n%\r\n%GENERAL DESCRIPTION\r\n%\r\n%This function performs the basic backtracking subroutine.\r\n%The subroutine requires the following input:\r\n%       xc    = the current point,\r\n%       d     = the direction of search,\r\n%       fc    = the current function value,\r\n%       fnc   = a string variable for the function name,\r\n%       DDfnc = the directional derivative of fnc at xc in the\r\n%               direction d, must have  DDfnc < 0,\r\n%       c     = the slope modification parameter in (0,1),\r\n%       gamma = the backstepping parameter in (0,1),\r\n%       eps   = the stopping criteria for norm(xn - xc),\r\n%               that is, the main algorithm stops when\r\n%               norm(xn - xc) <= eps.\r\n%\r\n%The routine returns\r\n%       xn  = the new point,\r\n%       fn  = the function value at the new point,\r\n%       fnc = the number of calls to fnc.\r\n%\r\n%TERMINATION CRITERIA\r\n%\r\n%The backtracking is terminated if the step to the new point\r\n%xn is so small that it triggers termination in the main algorithm,\r\n%i.e. norm(xc - xn) <= eps. In this case we return xn = xc if\r\n%fn >= fc (we have not reduced the function value); otherwise,\r\n%we return xn.\r\n%\r\n%THE MATH\r\n%\r\n%The backtracking routing attempts to find a step size for\r\n%reducing the value of the function fnc given the current point xc\r\n%and a direction d. It does this by successively trying step sizes\r\n%of the form gamma^s for s = 0,1,2... to find the smallest\r\n%value of s for which the inequality\r\n%\r\n%       fnc(xc+gamma^s*d)\\le fnc(xc)+c*gamma^s*DD\r\n%\r\n% is satisfied. The new point to be returned is then given\r\n% by xn = xc+gamma^s*d.\r\n%\r\n%CHECK INPUT SPECIFICATIONS\r\n%\r\nif DDfnc >= 0,\r\n        error('The backtracking subroutine has been sent a direction of nondesce\r\nnt. Program has been terminated.')\r\nend\r\nif c<= 0 | c>= 1,\r\n        error('The slope modification parameter c in the backtracking subroutine\r\n is not in (0,1).')\r\nend\r\nif gamma<=0 | gamma >=1,\r\n        error('The backtracking parameter gamma is not in (0,1).')\r\nend\r\nif eps <= 0,\r\n        error('The termination criteria eps sent to the backtracking line search\r\n is not positive.')\r\nend\r\n\r\n%\r\n%CHECK DIMENSIONS\r\n%\r\nif size(xc)~=size(d)\r\n        error('The vectors sent to backtrack are not of the same dimension.')\r\nend\r\n\r\n%\r\n%\r\n%EXECUTE THE LINE SEARCH\r\n%\r\n%\r\n\r\nxn      =   xc+d;\r\ncDDfnc  =   c*DDfnc;\r\nfn      =   feval(fnc,xn);\r\nfcall   =   1 ;\r\n\r\nwhile fn > fc+cDDfnc,\r\n        d       =  gamma*d;\r\n        cDDfnc  =  gamma*cDDfnc;\r\n        xn      =  xc+d;\r\n        fn      =  feval(fnc,xn);\r\n        fcall   =  fcall+1;\r\n\r\n%Check if the step to xn is too small.\r\n        if norm(d) <= eps,\r\n        disp('linesearch step too small')\r\n                if fn >= fc,\r\n                        xn  =  xc;\r\n                end\r\n                break\r\n        end\r\nend\r\n\r\n\r\n"
  },
  {
    "path": "Units/parser-matlab.r/matlab_setget.m.d/args.ctags",
    "content": "--sort=no\n\n"
  },
  {
    "path": "Units/parser-matlab.r/matlab_setget.m.d/expected.tags",
    "content": "input\tinput.m\t/^classdef input < handle$/;\"\tc\nget.myproperty\tinput.m\t/^    function out=get.myproperty(obj)$/;\"\tf\nset.myproperty\tinput.m\t/^    function out=set.myproperty(obj,val)$/;\"\tf\nclassfunc1\tinput.m\t/^        function [x,y,z] = classfunc1$/;\"\tf\nclassfunc2\tinput.m\t/^        function x = classfunc2()$/;\"\tf\nx\tinput.m\t/^            x = func2(1);$/;\"\tv\nclassfunc3\tinput.m\t/^        function classfunc3;$/;\"\tf\nfunc1\tinput.m\t/^function [x,y,z] = func1() % Silly function with multiple outputs$/;\"\tf\nx\tinput.m\t/^    x = 1;$/;\"\tv\ny\tinput.m\t/^    y = 2;$/;\"\tv\nz\tinput.m\t/^    z = 3;$/;\"\tv\nfunc2\tinput.m\t/^function x = func2(arg)$/;\"\tf\nx\tinput.m\t/^    x = arg;$/;\"\tv\nfunc3\tinput.m\t/^function func3()$/;\"\tf\nA\tinput.m\t/^    A = magic(4);$/;\"\tv\nR\tinput.m\t/^    R = randn(3,4,5);$/;\"\tv\n"
  },
  {
    "path": "Units/parser-matlab.r/matlab_setget.m.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/parser-matlab.r/matlab_setget.m.d/input.m",
    "content": "classdef input < handle\n    properties\n        myproperty\n    end\n    properties(Hidden)\n        myproperty_\n    end\n    function out=get.myproperty(obj)\n        out=myproperty_;\n    end\n    function out=set.myproperty(obj,val)\n        myproperty_=val;\n    end\n    methods(Static)\n        function [x,y,z] = classfunc1\n            [x, y, z] = func1();\n        end\n        function x = classfunc2()\n            x = func2(1);\n        end\n        function classfunc3;\n            func3();\n        end\n    end\nend\n\nfunction [x,y,z] = func1() % Silly function with multiple outputs\n    x = 1;\n    y = 2;\n    z = 3;\nend\nfunction x = func2(arg)\n    x = arg;\nend\nfunction func3()\n    % Silly function without any arguments\n    A = magic(4);\n    R = randn(3,4,5);\n\n    disp('A:');\n    disp(A);\n\n    disp('R:');\n    disp(R);\nend\n"
  },
  {
    "path": "Units/parser-matlab.r/matlab_test.m.d/expected.tags",
    "content": "A\tinput.m\t/^    A = magic(4);$/;\"\tv\nR\tinput.m\t/^    R = randn(3,4,5);$/;\"\tv\nclassfunc1\tinput.m\t/^        function [x,y,z] = classfunc1$/;\"\tf\nclassfunc2\tinput.m\t/^        function x = classfunc2()$/;\"\tf\nclassfunc3\tinput.m\t/^        function classfunc3;$/;\"\tf\nfunc1\tinput.m\t/^function [x,y,z] = func1() % Silly function with multiple outputs$/;\"\tf\nfunc2\tinput.m\t/^function x = func2(arg) $/;\"\tf\nfunc3\tinput.m\t/^function func3() $/;\"\tf\ninput\tinput.m\t/^classdef input < handle$/;\"\tc\nx\tinput.m\t/^            x = func2(1);$/;\"\tv\nx\tinput.m\t/^    x = 1;$/;\"\tv\nx\tinput.m\t/^    x = arg;$/;\"\tv\ny\tinput.m\t/^    y = 2;$/;\"\tv\nz\tinput.m\t/^    z = 3;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-matlab.r/matlab_test.m.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/parser-matlab.r/matlab_test.m.d/input.m",
    "content": "classdef input < handle\r\n    methods(Static)\r\n        function [x,y,z] = classfunc1\r\n            [x, y, z] = func1();\r\n        end\r\n        function x = classfunc2()\r\n            x = func2(1);\r\n        end\r\n        function classfunc3;\r\n            func3();\r\n        end\r\n    end\r\nend\r\n\r\nfunction [x,y,z] = func1() % Silly function with multiple outputs\r\n    x = 1;\r\n    y = 2;\r\n    z = 3;\r\nend\r\nfunction x = func2(arg) \r\n    x = arg;\r\nend\r\nfunction func3() \r\n    % Silly function without any arguments\r\n    A = magic(4);\r\n    R = randn(3,4,5);\r\n\r\n    disp('A:');\r\n    disp(A);\r\n\r\n    disp('R:');\r\n    disp(R);\r\nend\r\n"
  },
  {
    "path": "Units/parser-meson.r/config-inline.d/args.ctags",
    "content": "--sort=no\n--map-Meson=+.meson\n--fields=+K\n"
  },
  {
    "path": "Units/parser-meson.r/config-inline.d/expected.tags",
    "content": "insights-client\tinput.meson\t/^project('insights-client',$/;\"\tproject\npython\tinput.meson\t/^python = import('python')$/;\"\tvariable\npython_installation\tinput.meson\t/^python_installation = python.find_installation(get_option('python'))$/;\"\tvariable\npython_exec\tinput.meson\t/^python_exec = '\\/usr\\/bin\\/python3'$/;\"\tvariable\nsystemd\tinput.meson\t/^systemd = dependency('systemd', version: '>=231')$/;\"\tvariable\nconfig_data\tinput.meson\t/^config_data = configuration_data({$/;\"\tcfgdata\nbindir\tinput.meson\t/^  'bindir': get_option('prefix') \\/ get_option('bindir'),$/;\"\tcfgvar\tcfgdata:config_data\nBINDIR\tinput.meson\t/^  'BINDIR': get_option('prefix') \\/ get_option('bindir'),$/;\"\tcfgvar\tcfgdata:config_data\nDATADIR\tinput.meson\t/^  'DATADIR': get_option('prefix') \\/ get_option('datadir'),$/;\"\tcfgvar\tcfgdata:config_data\nDATAROOTDIR\tinput.meson\t/^  'DATAROOTDIR':get_option('prefix') \\/ get_option('datadir'),$/;\"\tcfgvar\tcfgdata:config_data\nDOCDIR\tinput.meson\t/^  'DOCDIR': get_option('prefix') \\/ get_option('datadir') \\/ 'doc' \\/ meson.project_name(),$/;\"\tcfgvar\tcfgdata:config_data\nLIBEXECDIR\tinput.meson\t/^  'LIBEXECDIR': get_option('prefix') \\/ get_option('libexecdir'),$/;\"\tcfgvar\tcfgdata:config_data\nLOCALSTATEDIR\tinput.meson\t/^  'LOCALSTATEDIR': get_option('localstatedir'),$/;\"\tcfgvar\tcfgdata:config_data\nPACKAGE\tinput.meson\t/^  'PACKAGE': meson.project_name(),$/;\"\tcfgvar\tcfgdata:config_data\nPACKAGE_VERSION\tinput.meson\t/^  'PACKAGE_VERSION': meson.project_version(),$/;\"\tcfgvar\tcfgdata:config_data\npkgsysconfdir\tinput.meson\t/^  'pkgsysconfdir': '\\/' \\/ get_option('sysconfdir') \\/ meson.project_name(),$/;\"\tcfgvar\tcfgdata:config_data\nPREFIX\tinput.meson\t/^  'PREFIX': get_option('prefix'),$/;\"\tcfgvar\tcfgdata:config_data\nPYTHON\tinput.meson\t/^  'PYTHON': python_exec,$/;\"\tcfgvar\tcfgdata:config_data\npythondir\tinput.meson\t/^  'pythondir': python_installation.get_install_dir(),$/;\"\tcfgvar\tcfgdata:config_data\nSBINDIR\tinput.meson\t/^  'SBINDIR': get_option('prefix') \\/ get_option('sbindir'),$/;\"\tcfgvar\tcfgdata:config_data\nSYSCONFDIR\tinput.meson\t/^  'SYSCONFDIR': '\\/' \\/ get_option('sysconfdir'),$/;\"\tcfgvar\tcfgdata:config_data\nsysconfdir\tinput.meson\t/^  'sysconfdir': '\\/' \\/ get_option('sysconfdir'),$/;\"\tcfgvar\tcfgdata:config_data\ntop_srcdir\tinput.meson\t/^  'top_srcdir': meson.source_root()$/;\"\tcfgvar\tcfgdata:config_data\nupdate-egg\tinput.meson\t/^run_target('update-egg', command: 'scripts\\/01-upgrade-egg.sh')$/;\"\trun\ndata\tinput.meson\t/^subdir('data')$/;\"\tsubdir\ndocs\tinput.meson\t/^subdir('docs')$/;\"\tsubdir\nsrc\tinput.meson\t/^subdir('src')$/;\"\tsubdir\nconfiguration\tinput.meson\t/^configuration = '**Configuration**\\\\n'$/;\"\tvariable\ncfgf5631d8f0109\tinput-0.meson\t/^configuration_data({$/;\"\tcfgdata\na\tinput-0.meson\t/^  'a': get_option('prefix') \\/ get_option('bindir'),$/;\"\tcfgvar\tcfgdata:cfgf5631d8f0109\nb\tinput-0.meson\t/^  'b': meson.source_root()$/;\"\tcfgvar\tcfgdata:cfgf5631d8f0109\nupdate-eggx\tinput-0.meson\t/^run_target('update-eggx', command: 'scripts\\/01-upgrade-egg.sh')$/;\"\trun\n"
  },
  {
    "path": "Units/parser-meson.r/config-inline.d/input-0.meson",
    "content": "configuration_data({\n  'a': get_option('prefix') / get_option('bindir'),\n  # ...\n  'b': meson.source_root()\n})\n\nrun_target('update-eggx', command: 'scripts/01-upgrade-egg.sh')\n"
  },
  {
    "path": "Units/parser-meson.r/config-inline.d/input.meson",
    "content": "# Taken from insights-client-3.2.8/meson.build\n\nproject('insights-client',\n  version: '3.2.8',\n  meson_version: '>=0.49'\n)\n\npython = import('python')\n\npython_installation = python.find_installation(get_option('python'))\n\npython_exec = '/usr/bin/python3'\n\nsystemd = dependency('systemd', version: '>=231')\n\nconfig_data = configuration_data({\n  'bindir': get_option('prefix') / get_option('bindir'),\n  'BINDIR': get_option('prefix') / get_option('bindir'),\n  'DATADIR': get_option('prefix') / get_option('datadir'),\n  'DATAROOTDIR':get_option('prefix') / get_option('datadir'),\n  'DOCDIR': get_option('prefix') / get_option('datadir') / 'doc' / meson.project_name(),\n  'LIBEXECDIR': get_option('prefix') / get_option('libexecdir'),\n  'LOCALSTATEDIR': get_option('localstatedir'),\n  'PACKAGE': meson.project_name(),\n  'PACKAGE_VERSION': meson.project_version(),\n  'pkgsysconfdir': '/' / get_option('sysconfdir') / meson.project_name(),\n  'PREFIX': get_option('prefix'),\n  'PYTHON': python_exec,\n  'pythondir': python_installation.get_install_dir(),\n  'SBINDIR': get_option('prefix') / get_option('sbindir'),\n  'SYSCONFDIR': '/' / get_option('sysconfdir'),\n  'sysconfdir': '/' / get_option('sysconfdir'),\n  'top_srcdir': meson.source_root()\n})\n\nrun_target('update-egg', command: 'scripts/01-upgrade-egg.sh')\n\nsubdir('data')\nsubdir('docs')\nsubdir('src')\n\nconfiguration = '**Configuration**\\n'\nconfiguration += '\\tpython\\t\\t\\t: ' + get_option('python') + '\\n'\nif get_option('checkin').enabled()\n configuration += '\\tcheckin\\t: ' + 'enabled' + '\\n'\nelse\n configuration += '\\tcheckin\\t: ' + 'disabled' + '\\n'\nendif\nif get_option('auto_registration').enabled()\n  configuration += '\\tauto_registration\\t: ' + 'enabled' + '\\n'\nelse \n  configuration += '\\tauto_registration\\t: ' + 'disabled' + '\\n'\nendif\nmessage(configuration)\n"
  },
  {
    "path": "Units/parser-meson.r/config.d/args.ctags",
    "content": "--sort=no\n--map-Meson=+.meson\n--fields=+K\n"
  },
  {
    "path": "Units/parser-meson.r/config.d/expected.tags",
    "content": "systemd\tinput.meson\t/^project('systemd', 'c',$/;\"\tproject\nproject_major_version\tinput.meson\t/^project_major_version = meson.project_version().split('.')[0].split('~')[0]$/;\"\tvariable\nproject_minor_version\tinput.meson\t/^        project_minor_version = meson.project_version().split('.')[-1].split('~')[0]$/;\"\tvariable\nproject_minor_version\tinput.meson\t/^        project_minor_version = '0'$/;\"\tvariable\nlibsystemd_version\tinput.meson\t/^libsystemd_version = '0.39.0'$/;\"\tvariable\nlibudev_version\tinput.meson\t/^libudev_version = '1.7.9'$/;\"\tvariable\nconf\tinput.meson\t/^conf = configuration_data()$/;\"\tcfgdata\nPROJECT_URL\tinput.meson\t/^conf.set_quoted('PROJECT_URL', 'https:\\/\\/systemd.io\\/')$/;\"\tcfgvar\tcfgdata:conf\nPROJECT_VERSION\tinput.meson\t/^conf.set('PROJECT_VERSION', project_major_version,$/;\"\tcfgvar\tcfgdata:conf\nPROJECT_VERSION_FULL\tinput.meson\t/^conf.set_quoted('PROJECT_VERSION_FULL', meson.project_version(), description : 'Full project ver/;\"\tcfgvar\tcfgdata:conf\nconf2\tinput.meson\t/^conf2 = configuration_data()$/;\"\tcfgdata\nPROJECT_URL_ALT\tinput.meson\t/^conf2.set_quoted('PROJECT_URL_ALT', 'https:\\/\\/systemd.io\\/')$/;\"\tcfgvar\tcfgdata:conf2\nproject_source_root\tinput.meson\t/^project_source_root = meson.current_source_dir()$/;\"\tvariable\nproject_build_root\tinput.meson\t/^project_build_root = meson.current_build_dir()$/;\"\tvariable\nrelative_source_path\tinput.meson\t/^relative_source_path = run_command('realpath',$/;\"\tvariable\nRELATIVE_SOURCE_PATH\tinput.meson\t/^conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path)$/;\"\tcfgvar\tcfgdata:conf\nBUILD_MODE_DEVELOPER\tinput.meson\t/^conf.set10('BUILD_MODE_DEVELOPER', get_option('mode') == 'developer',$/;\"\tcfgvar\tcfgdata:conf\n"
  },
  {
    "path": "Units/parser-meson.r/config.d/input.meson",
    "content": "#\n# Taken from meson.build of systemd\n#\n\n# SPDX-License-Identifier: LGPL-2.1-or-later\n\nproject('systemd', 'c',\n        version : files('meson.version'),\n        license : 'LGPLv2+',\n        default_options: [\n                'c_std=gnu11',\n                'prefix=/usr',\n                'sysconfdir=/etc',\n                'localstatedir=/var',\n                'warning_level=2',\n        ],\n        meson_version : '>= 0.60.0',\n       )\n\nproject_major_version = meson.project_version().split('.')[0].split('~')[0]\nif meson.project_version().contains('.')\n        project_minor_version = meson.project_version().split('.')[-1].split('~')[0]\nelse\n        project_minor_version = '0'\nendif\n\nlibsystemd_version = '0.39.0'\nlibudev_version = '1.7.9'\n\nconf = configuration_data()\nconf.set_quoted('PROJECT_URL', 'https://systemd.io/')\nconf.set('PROJECT_VERSION', project_major_version,\n         description : 'Numerical project version (used where a simple number is expected)')\nconf.set_quoted('PROJECT_VERSION_FULL', meson.project_version(), description : 'Full project version')\n\nconf2 = configuration_data()\nconf2.set_quoted('PROJECT_URL_ALT', 'https://systemd.io/')\n\n# This is to be used instead of meson.source_root(), as the latter will return\n# the wrong result when systemd is being built as a meson subproject\nproject_source_root = meson.current_source_dir()\nproject_build_root = meson.current_build_dir()\nrelative_source_path = run_command('realpath',\n                                   '--relative-to=@0@'.format(project_build_root),\n                                   project_source_root,\n                                   check : true).stdout().strip()\nconf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path)\n\nconf.set10('BUILD_MODE_DEVELOPER', get_option('mode') == 'developer',\n           description : 'tailor build to development or release builds')\n"
  },
  {
    "path": "Units/parser-meson.r/escape-in-string.d/args.ctags",
    "content": "--sort=no\n--fields=+r\n-G\n"
  },
  {
    "path": "Units/parser-meson.r/escape-in-string.d/expected.tags",
    "content": "v\tinput.meson\t/^        v = get_option(tuple[0])$/;\"\tV\troles:def\nv\tinput.meson\t/^                v = run_command($/;\"\tV\troles:def\nv\tinput.meson\t/^                        v = tuple[2]$/;\"\tV\troles:def\nv\tinput.meson\t/^                        v = v.to_int()$/;\"\tV\troles:def\ndynamic_uid_min\tinput.meson\t/^dynamic_uid_min = get_option('dynamic-uid-min')$/;\"\tV\troles:def\nv_eof\tinput.meson\t/^v_eof=$/;\"\tV\troles:def\n"
  },
  {
    "path": "Units/parser-meson.r/escape-in-string.d/input.meson",
    "content": "# -*- Meson -*-\n# Partially taken from meson.build in the source tree of systemd.\n#\nforeach tuple : [['system-alloc-uid-min', 'SYS_UID_MIN', 1],  # Also see login.defs(5).\n                 ['system-uid-max',       'SYS_UID_MAX', 999],\n                 ['system-alloc-gid-min', 'SYS_GID_MIN', 1],\n                 ['system-gid-max',       'SYS_GID_MAX', 999]]\n        v = get_option(tuple[0])\n        if v <= 0\n                v = run_command(\n                        awk,\n                        '/^\\s*@0@\\s+/ { uid=$2 } END { print uid }'.format(tuple[1]),\n                        '/etc/login.defs',\n                        check : false).stdout().strip()\n                if v == ''\n                        v = tuple[2]\n                else\n                        v = v.to_int()\n                endif\n        endif\n        conf.set(tuple[0].underscorify().to_upper(), v)\nendforeach\nif conf.get('SYSTEM_ALLOC_UID_MIN') >= conf.get('SYSTEM_UID_MAX')\n        error('Invalid uid allocation range')\nendif\nif conf.get('SYSTEM_ALLOC_GID_MIN') >= conf.get('SYSTEM_GID_MAX')\n        error('Invalid gid allocation range')\nendif\n\ndynamic_uid_min = get_option('dynamic-uid-min')\nv_eof=\n"
  },
  {
    "path": "Units/parser-meson.r/modules.d/args.ctags",
    "content": "--sort=no\n--map-Meson=+.meson\n--fields=+Kr\n--extras=+r\n"
  },
  {
    "path": "Units/parser-meson.r/modules.d/expected.tags",
    "content": "keyval\tinput.meson\t/^  keyval = import('keyval')$/;\"\tvariable\troles:def\nkeyval\tinput.meson\t/^  keyval = import('keyval')$/;\"\tmodule\troles:imported\nkeyval\tinput.meson\t/^  keyval = import('unstable-keyval')$/;\"\tvariable\troles:def\nunstable-keyval\tinput.meson\t/^  keyval = import('unstable-keyval')$/;\"\tmodule\troles:imported\nss\tinput.meson\t/^ss = import('sourceset')$/;\"\tvariable\troles:def\nsourceset\tinput.meson\t/^ss = import('sourceset')$/;\"\tmodule\troles:imported\nfs\tinput.meson\t/^fs = import('fs')$/;\"\tvariable\troles:def\nfs\tinput.meson\t/^fs = import('fs')$/;\"\tmodule\troles:imported\n"
  },
  {
    "path": "Units/parser-meson.r/modules.d/input.meson",
    "content": "if meson.version().version_compare('>=0.56.0')\n  keyval = import('keyval')\nelse\n  keyval = import('unstable-keyval')\nendif\nss = import('sourceset')\nfs = import('fs')\n"
  },
  {
    "path": "Units/parser-meson.r/simple-meson.d/args.ctags",
    "content": "--sort=no\n--map-Meson=+.meson\n--fields=+K\n"
  },
  {
    "path": "Units/parser-meson.r/simple-meson.d/expected.tags",
    "content": "c++ foolib\tinput.meson\t/^project('c++ foolib', 'cpp',$/;\"\tproject\nglib_dep\tinput.meson\t/^glib_dep = dependency('glib-2.0')$/;\"\tvariable\ninc\tinput.meson\t/^inc = include_directories('include')$/;\"\tvariable\ninclude\tinput.meson\t/^subdir('include')$/;\"\tsubdir\nsrc\tinput.meson\t/^subdir('src')$/;\"\tsubdir\ntest\tinput.meson\t/^subdir('test')$/;\"\tsubdir\npkg_mod\tinput.meson\t/^pkg_mod = import('pkgconfig')$/;\"\tvariable\nfoo_sources\tinput-1.meson\t/^foo_sources = ['source1.cpp', 'source2.cpp']$/;\"\tvariable\nfoolib\tinput-1.meson\t/^foolib = shared_library('foo',$/;\"\tvariable\nfoo\tinput-1.meson\t/^foolib = shared_library('foo',$/;\"\tbuild\nfoolib0\tinput-1.meson\t/^foolib0 = library('foo0',$/;\"\tvariable\nfoo0\tinput-1.meson\t/^foolib0 = library('foo0',$/;\"\tbuild\nfoolib1\tinput-1.meson\t/^foolib1 = both_library('foo1',$/;\"\tvariable\nfoo1\tinput-1.meson\t/^foolib1 = both_library('foo1',$/;\"\tbuild\nfoolib2\tinput-1.meson\t/^foolib2 = static_library('foo2',$/;\"\tvariable\nfoo2\tinput-1.meson\t/^foolib2 = static_library('foo2',$/;\"\tbuild\ntestexe\tinput-2.meson\t/^testexe = executable('testexe', 'footest.cpp',$/;\"\tvariable\ntestexe\tinput-2.meson\t/^testexe = executable('testexe', 'footest.cpp',$/;\"\tbuild\nfoolib test\tinput-2.meson\t/^test('foolib test', testexe)$/;\"\ttest\ncomp\tinput-3.meson\t/^comp = find_program('custom_compiler')$/;\"\tvariable\ninfile\tinput-3.meson\t/^infile = 'source_code.txt'$/;\"\tvariable\noutfile\tinput-3.meson\t/^outfile = 'output.bin'$/;\"\tvariable\nmytarget\tinput-3.meson\t/^mytarget = custom_target('targetname',$/;\"\tvariable\ntargetname\tinput-3.meson\t/^mytarget = custom_target('targetname',$/;\"\tcustom\ninspector\tinput-4.meson\t/^run_target('inspector',$/;\"\trun\ntest_kwargs\tinput-5.meson\t/^test_kwargs = {$/;\"\tvariable\nbench_connect\tinput-5.meson\t/^bench_connect = executable('bench-connect', sources: ['bench-connect.c'], kwargs: test_kwargs)$/;\"\tvariable\nbench-connect\tinput-5.meson\t/^bench_connect = executable('bench-connect', sources: ['bench-connect.c'], kwargs: test_kwargs)$/;\"\tbuild\nbench_message\tinput-5.meson\t/^bench_message = executable('bench-message', sources: ['bench-message.c'], kwargs: test_kwargs)$/;\"\tvariable\nbench-message\tinput-5.meson\t/^bench_message = executable('bench-message', sources: ['bench-message.c'], kwargs: test_kwargs)$/;\"\tbuild\nsuites\tinput-5.meson\t/^suites = [$/;\"\tvariable\nConnection\tinput-5.meson\t/^        benchmark('Connection', bench_connect, timeout: 60, kwargs: suite)$/;\"\tbenchmark\nMessage passing\tinput-5.meson\t/^        benchmark('Message passing', bench_message, timeout: 120, kwargs: suite)$/;\"\tbenchmark\ngi_docgen\tinput-6.meson\t/^gi_docgen = find_program('gi-docgen')$/;\"\tvariable\ngck\tinput-6.meson\t/^subdir('gck')$/;\"\tsubdir\ngcr\tinput-6.meson\t/^subdir('gcr')$/;\"\tsubdir\ndocs\tinput-6.meson\t/^alias_target('docs',$/;\"\trun\n"
  },
  {
    "path": "Units/parser-meson.r/simple-meson.d/input-0.meson",
    "content": "# Taken from https://mesonbuild.com/IndepthTutorial.html\ninstall_headers('foolib.h')\n"
  },
  {
    "path": "Units/parser-meson.r/simple-meson.d/input-1.meson",
    "content": "# Taken from https://mesonbuild.com/IndepthTutorial.html\nfoo_sources = ['source1.cpp', 'source2.cpp']\nfoolib = shared_library('foo',\n                        foo_sources,\n                        include_directories : inc,\n                        dependencies : glib_dep,\n                        install : true)\n\nfoolib0 = library('foo0',\n                        foo_sources,\n                        include_directories : inc,\n                        dependencies : glib_dep,\n                        install : true)\nfoolib1 = both_library('foo1',\n                        foo_sources,\n                        include_directories : inc,\n                        dependencies : glib_dep,\n                        install : true)\nfoolib2 = static_library('foo2',\n                        foo_sources,\n                        include_directories : inc,\n                        dependencies : glib_dep,\n                        install : true)\n"
  },
  {
    "path": "Units/parser-meson.r/simple-meson.d/input-2.meson",
    "content": "# Taken from https://mesonbuild.com/IndepthTutorial.html\ntestexe = executable('testexe', 'footest.cpp',\n                     include_directories : inc,\n                     link_with : foolib)\ntest('foolib test', testexe)\n'''\ntestexe3 = executable('testexe2', 'footest2.cpp',\n                     include_directories : inc,\n                     link_with : foolib)\ntest('foolib test2', testexe)\n'''\n"
  },
  {
    "path": "Units/parser-meson.r/simple-meson.d/input-3.meson",
    "content": "# Taken fromh https://mesonbuild.com/Custom-build-targets.html\ncomp = find_program('custom_compiler')\n\ninfile = 'source_code.txt'\noutfile = 'output.bin'\n\nmytarget = custom_target('targetname',\n  output : outfile,\n  input : infile,\n  command : [comp, '@INPUT@', '@OUTPUT@'],\n  install : true,\n  install_dir : 'subdir')\n"
  },
  {
    "path": "Units/parser-meson.r/simple-meson.d/input-4.meson",
    "content": "# Taken from https://mesonbuild.com/Run-targets.html\nrun_target('inspector',\n  command : ['scripts/inspect.sh', '--exclude', 'tests'])\n"
  },
  {
    "path": "Units/parser-meson.r/simple-meson.d/input-5.meson",
    "content": "# -*- Meson -*-\n# Derrived from test/dbus/meson.build of dbus-broker\ntest_kwargs = {\n        'dependencies': [dep_test],\n        'install': use_tests,\n        'install_dir': conf.get('testdir') / 'dbus',\n}\n\nbench_connect = executable('bench-connect', sources: ['bench-connect.c'], kwargs: test_kwargs)\nbench_message = executable('bench-message', sources: ['bench-message.c'], kwargs: test_kwargs)\n\nsuites = [\n        { 'suite': 'dbus-broker', 'env': ['DBUS_BROKER_TEST_BROKER=' + exe_dbus_broker.full_path()]},\n]\n\nforeach suite : suites\n        benchmark('Connection', bench_connect, timeout: 60, kwargs: suite)\n        benchmark('Message passing', bench_message, timeout: 120, kwargs: suite)\nendforeach\n"
  },
  {
    "path": "Units/parser-meson.r/simple-meson.d/input-6.meson",
    "content": "# -*- Meson -*- \n# Taken from docs/meson.build of gcr\n#\ngi_docgen = find_program('gi-docgen')\n\nsubdir('gck')\nsubdir('gcr')\n\n# Create a pseudo target that build all docs at once\nalias_target('docs',\n  gck_docs,\n  gcr_docs,\n)\n"
  },
  {
    "path": "Units/parser-meson.r/simple-meson.d/input.meson",
    "content": "# Taken from https://mesonbuild.com/IndepthTutorial.html\nproject('c++ foolib', 'cpp',\n  version : '1.0.0',\n  license : 'MIT')\nadd_global_arguments('-DSOME_TOKEN=value', language : 'cpp')\nglib_dep = dependency('glib-2.0')\n\ninc = include_directories('include')\n\nsubdir('include')\nsubdir('src')\nsubdir('test')\n\npkg_mod = import('pkgconfig')\npkg_mod.generate(libraries : foolib,\n                 version : '1.0',\n                 name : 'libfoobar',\n                 filebase : 'foobar',\n                 description : 'A Library to barnicate your foos.')\n\n"
  },
  {
    "path": "Units/parser-moose.r/no-use-only.d/input.pm",
    "content": "# This is a crash test. No output expectation.\nno Moose\n"
  },
  {
    "path": "Units/parser-moose.r/parse-overrun.d/args.ctags",
    "content": "--sort=no\n--extras=+{subparser}\n# If guest is turned on, the crash isn't reproduced.\n--extras=-{guest}\n--fields=+lKzZ\n"
  },
  {
    "path": "Units/parser-moose.r/parse-overrun.d/expected.tags",
    "content": "Throwable::Error\tinput.pm\t/^package Throwable::Error;$/;\"\tkind:package\tlanguage:Perl\nThrowable::Error\tinput.pm\t/^package Throwable::Error;$/;\"\tkind:class\tlanguage:Moose\nmessage\tinput.pm\t/^has message => ($/;\"\tkind:attribute\tlanguage:Moose\tscope:class:Throwable::Error\nas_string\tinput.pm\t/^sub as_string {$/;\"\tkind:subroutine\tlanguage:Perl\nas_string\tinput.pm\t/^sub as_string {$/;\"\tkind:method\tlanguage:Moose\tscope:class:Throwable::Error\nBUILDARGS\tinput.pm\t/^around BUILDARGS => sub {$/;\"\tkind:wrapper\tlanguage:Moose\tscope:class:Throwable::Error\twrapping:around\n"
  },
  {
    "path": "Units/parser-moose.r/parse-overrun.d/input.pm",
    "content": "# Taken from The test case is taken from Throwable-1.001/lib/Throwable/Error.pm:\n\n# This software is copyright (c) 2022 by Ricardo SIGNES.\n\n# This is free software; you can redistribute it and/or modify it under\n# the same terms as the Perl 5 programming language system itself.\n\n# Terms of the Perl programming language system itself\n\n# a) the GNU General Public License as published by the Free\n#    Software Foundation; either version 1, or (at your option) any\n#    later version, or\n# b) the \"Artistic License\"\n\npackage Throwable::Error;\n# ABSTRACT: an easy-to-use class for error objects\n$Throwable::Error::VERSION = '1.001';\nuse Moo 1.000001;\nwith 'Throwable', 'StackTrace::Auto';\n\n#pod =head1 SYNOPSIS\n#pod\n#pod   package MyApp::Error;\n#pod   # NOTE: Moo can also be used here instead of Moose\n#pod   use Moose;\n#pod   extends 'Throwable::Error';\n#pod\n#pod   has execution_phase => (\n#pod     is  => 'ro',\n#pod     isa => 'MyApp::Phase',\n#pod     default => 'startup',\n#pod   );\n#pod\n#pod ...and in your app...\n#pod\n#pod   MyApp::Error->throw(\"all communications offline\");\n#pod\n#pod   # or...\n#pod\n#pod   MyApp::Error->throw({\n#pod     message         => \"all communications offline\",\n#pod     execution_phase => 'shutdown',\n#pod   });\n#pod\n#pod =head1 DESCRIPTION\n#pod\n#pod Throwable::Error is a base class for exceptions that will be thrown to signal\n#pod errors and abort normal program flow.  Throwable::Error is an alternative to\n#pod L<Exception::Class|Exception::Class>, the features of which are largely\n#pod provided by the Moo object system atop which Throwable::Error is built.\n#pod\n#pod Throwable::Error performs the L<Throwable|Throwable> and L<StackTrace::Auto>\n#pod roles.  That means you can call C<throw> on it to create and throw an error\n#pod object in one call, and that every error object will have a stack trace for its\n#pod creation.\n#pod\n#pod =cut\n\nuse overload\n  q{\"\"}    => 'as_string',\n  fallback => 1;\n\n#pod =attr message\n#pod\n#pod This attribute must be defined and must contain a string describing the error\n#pod condition.  This string will be printed at the top of the stack trace when the\n#pod error is stringified.\n#pod\n#pod =cut\n\nhas message => (\n  is       => 'ro',\n  isa      => Sub::Quote::quote_sub(q{\n      die \"message must be a string\"\n          unless defined($_[0]) && !ref($_[0]);\n  }),,\n  required => 1,\n);\n\n#pod =attr stack_trace\n#pod\n#pod This attribute, provided by L<StackTrace::Auto>, will contain a stack trace\n#pod object guaranteed to respond to the C<as_string> method.  For more information\n#pod about the stack trace and associated behavior, consult the L<StackTrace::Auto>\n#pod docs.\n#pod\n#pod =method as_string\n#pod\n#pod This method will provide a string representing the error, containing the\n#pod error's message followed by the its stack trace.\n#pod\n#pod =cut\n\nsub as_string {\n  my ($self) = @_;\n\n  my $str = $self->message;\n  $str .= \"\\n\\n\" . $self->stack_trace->as_string;\n\n  return $str;\n}\n\naround BUILDARGS => sub {\n  my $orig = shift;\n  my $self = shift;\n\n  return {} unless @_;\n  return {} if @_ == 1 and ! defined $_[0];\n\n  if (@_ == 1 and (!ref $_[0]) and defined $_[0] and length $_[0]) {\n    return { message => $_[0] };\n  }\n\n  return $self->$orig(@_);\n};\n\n1;\n\n__END__\n\n=pod\n\n=encoding UTF-8\n\n=head1 NAME\n\nThrowable::Error - an easy-to-use class for error objects\n\n=head1 VERSION\n\nversion 1.001\n\n=head1 SYNOPSIS\n\n  package MyApp::Error;\n  # NOTE: Moo can also be used here instead of Moose\n  use Moose;\n  extends 'Throwable::Error';\n\n  has execution_phase => (\n    is  => 'ro',\n    isa => 'MyApp::Phase',\n    default => 'startup',\n  );\n\n...and in your app...\n\n  MyApp::Error->throw(\"all communications offline\");\n\n  # or...\n\n  MyApp::Error->throw({\n    message         => \"all communications offline\",\n    execution_phase => 'shutdown',\n  });\n\n=head1 DESCRIPTION\n\nThrowable::Error is a base class for exceptions that will be thrown to signal\nerrors and abort normal program flow.  Throwable::Error is an alternative to\nL<Exception::Class|Exception::Class>, the features of which are largely\nprovided by the Moo object system atop which Throwable::Error is built.\n\nThrowable::Error performs the L<Throwable|Throwable> and L<StackTrace::Auto>\nroles.  That means you can call C<throw> on it to create and throw an error\nobject in one call, and that every error object will have a stack trace for its\ncreation.\n\n=head1 PERL VERSION\n\nThis library should run on perls released even a long time ago.  It should work\non any version of perl released in the last five years.\n\nAlthough it may work on older versions of perl, no guarantee is made that the\nminimum required version will not be increased.  The version may be increased\nfor any reason, and there is no promise that patches will be accepted to lower\nthe minimum required perl.\n\n=head1 ATTRIBUTES\n\n=head2 message\n\nThis attribute must be defined and must contain a string describing the error\ncondition.  This string will be printed at the top of the stack trace when the\nerror is stringified.\n\n=head2 stack_trace\n\nThis attribute, provided by L<StackTrace::Auto>, will contain a stack trace\nobject guaranteed to respond to the C<as_string> method.  For more information\nabout the stack trace and associated behavior, consult the L<StackTrace::Auto>\ndocs.\n\n=head1 METHODS\n\n=head2 as_string\n\nThis method will provide a string representing the error, containing the\nerror's message followed by the its stack trace.\n\n=head1 AUTHORS\n\n=over 4\n\n=item *\n\nRicardo SIGNES <cpan@semiotic.systems>\n\n=item *\n\nFlorian Ragwitz <rafl@debian.org>\n\n=back\n\n=head1 COPYRIGHT AND LICENSE\n\nThis software is copyright (c) 2022 by Ricardo SIGNES.\n\nThis is free software; you can redistribute it and/or modify it under\nthe same terms as the Perl 5 programming language system itself.\n\n=cut\n"
  },
  {
    "path": "Units/parser-moose.r/role.d/args.ctags",
    "content": "--sort=no\n--extras=+s\n--fields=+i\n"
  },
  {
    "path": "Units/parser-moose.r/role.d/expected.tags",
    "content": "Eq\tinput.pl\t/^package Eq;$/;\"\tp\nEq\tinput.pl\t/^package Eq;$/;\"\tr\nno_equal\tinput.pl\t/^sub no_equal {$/;\"\ts\nno_equal\tinput.pl\t/^sub no_equal {$/;\"\tm\trole:Eq\nR0\tinput.pl\t/^package R0;$/;\"\tp\nR0\tinput.pl\t/^package R0;$/;\"\tr\nR1\tinput.pl\t/^package R1;$/;\"\tp\nR1\tinput.pl\t/^package R1;$/;\"\tr\nR2\tinput.pl\t/^package R2;$/;\"\tp\nR2\tinput.pl\t/^package R2;$/;\"\tr\nC0\tinput.pl\t/^package C0;$/;\"\tp\nC0\tinput.pl\t/^package C0;$/;\"\tc\nC1\tinput.pl\t/^package C1;$/;\"\tp\nC1\tinput.pl\t/^package C1;$/;\"\tc\nC2\tinput.pl\t/^package C2;$/;\"\tp\nC2\tinput.pl\t/^package C2;$/;\"\tc\nCurrency\tinput.pl\t/^package Currency;$/;\"\tp\nCurrency\tinput.pl\t/^package Currency;$/;\"\tc\tinherits:C1,Eq,C2,C3,R0,R1,R2\nequal\tinput.pl\t/^sub equal {$/;\"\ts\nequal\tinput.pl\t/^sub equal {$/;\"\tm\tclass:Currency\n"
  },
  {
    "path": "Units/parser-moose.r/role.d/input.pl",
    "content": "# Derrived from https://metacpan.org/pod/Moose::Role\n\npackage Eq;\nuse Moose::Role; # automatically turns on strict and warnings\n \nrequires 'equal';\n \nsub no_equal {\n    my ($self, $other) = @_;\n    !$self->equal($other);\n}\n\npackage R0;\nuse Moose::Role;\n\npackage R1;\nuse Moose::Role;\n\npackage R2;\nuse Moose::Role;\n\npackage C0;\nuse Moose;\n\npackage C1;\nuse Moose;\n\npackage C2;\nuse Moose;\n\n# ... then in your classes\n \npackage Currency;\nuse Moose; # automatically turns on strict and warnings\n\nextends 'C1';\nwith 'Eq';\nextends 'C2',\n    'C3';\nwith 'R0';\nwith 'R1', 'R2';\n \nsub equal {\n}\n"
  },
  {
    "path": "Units/parser-moose.r/simple-moose.d/args.ctags",
    "content": "--sort=no\n--fields=+lineK\n--extras=+s\n#\n# NOTE: Moose parser works without following options.\n#\n--kinds-Perl=+M\n--extras=+r\n"
  },
  {
    "path": "Units/parser-moose.r/simple-moose.d/expected.tags",
    "content": "Point\tinput.pl\t/^package Point;$/;\"\tpackage\tline:2\tlanguage:Perl\nMoose\tinput.pl\t/^use Moose; # automatically turns on strict and warnings$/;\"\tmodule\tline:3\tlanguage:Perl\nPoint\tinput.pl\t/^package Point;$/;\"\tclass\tline:2\tlanguage:Moose\nx\tinput.pl\t/^has 'x' => (is => 'rw', isa => 'Int');$/;\"\tattribute\tline:5\tlanguage:Moose\tclass:Point\ny\tinput.pl\t/^has 'y' => (is => 'rw', isa => 'Int');$/;\"\tattribute\tline:6\tlanguage:Moose\tclass:Point\nz0\tinput.pl\t/^has z0 => (is => 'rw');$/;\"\tattribute\tline:8\tlanguage:Moose\tclass:Point\nz1\tinput.pl\t/^has 'z1' => (is => 'rw');$/;\"\tattribute\tline:9\tlanguage:Moose\tclass:Point\nz2\tinput.pl\t/^has \"z2\" => (is => 'rw');$/;\"\tattribute\tline:10\tlanguage:Moose\tclass:Point\nz0p\tinput.pl\t/^has (z0p => (is => 'rw'));$/;\"\tattribute\tline:12\tlanguage:Moose\tclass:Point\nz1p\tinput.pl\t/^has ('z1p' => (is => 'rw'));$/;\"\tattribute\tline:13\tlanguage:Moose\tclass:Point\nz2p\tinput.pl\t/^has (\"z2p\" => (is => 'rw'));$/;\"\tattribute\tline:14\tlanguage:Moose\tclass:Point\nz0ps\tinput.pl\t/^has (\tz0ps => (is => 'rw'));$/;\"\tattribute\tline:16\tlanguage:Moose\tclass:Point\nz1ps\tinput.pl\t/^has (\t'z1ps' => (is => 'rw'));$/;\"\tattribute\tline:17\tlanguage:Moose\tclass:Point\nz2ps\tinput.pl\t/^has (\t\"z2ps\" => (is => 'rw'));$/;\"\tattribute\tline:18\tlanguage:Moose\tclass:Point\nz3\tinput.pl\t/^has [qw#z3\tz4 z5#] => ((is => 'rw'),(is => 'rw'),(is => 'rw'));$/;\"\tattribute\tline:20\tlanguage:Moose\tclass:Point\nz4\tinput.pl\t/^has [qw#z3\tz4 z5#] => ((is => 'rw'),(is => 'rw'),(is => 'rw'));$/;\"\tattribute\tline:20\tlanguage:Moose\tclass:Point\nz5\tinput.pl\t/^has [qw#z3\tz4 z5#] => ((is => 'rw'),(is => 'rw'),(is => 'rw'));$/;\"\tattribute\tline:20\tlanguage:Moose\tclass:Point\nz6\tinput.pl\t/^has ([qw|z6\tz7|] => (is => 'rw'), (is => 'rw'));$/;\"\tattribute\tline:21\tlanguage:Moose\tclass:Point\nz7\tinput.pl\t/^has ([qw|z6\tz7|] => (is => 'rw'), (is => 'rw'));$/;\"\tattribute\tline:21\tlanguage:Moose\tclass:Point\nclear\tinput.pl\t/^sub clear {$/;\"\tsubroutine\tline:23\tlanguage:Perl\nclear\tinput.pl\t/^sub clear {$/;\"\tmethod\tline:23\tlanguage:Moose\tclass:Point\nPoint3D\tinput.pl\t/^package Point3D;$/;\"\tpackage\tline:29\tlanguage:Perl\nMoose\tinput.pl\t/^use Moose;$/;\"\tmodule\tline:30\tlanguage:Perl\nPoint3D\tinput.pl\t/^package Point3D;$/;\"\tclass\tline:29\tlanguage:Moose\tinherits:Point\nz\tinput.pl\t/^has 'z' => (is => 'rw', isa => 'Int');$/;\"\tattribute\tline:34\tlanguage:Moose\tclass:Point3D\nclear\tinput.pl\t/^before 'clear' => sub {$/;\"\twrapper\tline:36\tlanguage:Moose\tclass:Point3D\twrapping:before\nclear\tinput.pl\t/^after 'clear' => sub {$/;\"\twrapper\tline:39\tlanguage:Moose\tclass:Point3D\twrapping:after\nclear\tinput.pl\t/^around 'clear' => sub {$/;\"\twrapper\tline:42\tlanguage:Moose\tclass:Point3D\twrapping:around\nTimeAxis\tinput.pl\t/^package TimeAxis;$/;\"\tpackage\tline:45\tlanguage:Perl\nMoose\tinput.pl\t/^use Moose;$/;\"\tmodule\tline:46\tlanguage:Perl\nTimeAxis\tinput.pl\t/^package TimeAxis;$/;\"\tclass\tline:45\tlanguage:Moose\nPoint4D\tinput.pl\t/^package Point4D;$/;\"\tpackage\tline:48\tlanguage:Perl\nMoose\tinput.pl\t/^use Moose;$/;\"\tmodule\tline:49\tlanguage:Perl\nPoint4D\tinput.pl\t/^package Point4D;$/;\"\tclass\tline:48\tlanguage:Moose\tinherits:Point3D,TimeAxis\tend:57\nclear\tinput.pl\t/^override \"clear\" => sub {$/;\"\tmethod\tline:54\tlanguage:Moose\tclass:Point4D\nMoose\tinput.pl\t/^no Moose;$/;\"\tmodule\tline:57\tlanguage:Perl\nLine\tinput.pl\t/^package Line;$/;\"\tpackage\tline:58\tlanguage:Perl\nCat::Food\tinput-0.pl\t/^package Cat::Food;$/;\"\tpackage\tline:2\tlanguage:Perl\nMoo\tinput-0.pl\t/^use Moo;$/;\"\tmodule\tline:4\tlanguage:Perl\nCat::Food\tinput-0.pl\t/^package Cat::Food;$/;\"\tclass\tline:2\tlanguage:Moose\tend:31\nstrictures\tinput-0.pl\t/^use strictures 2;$/;\"\tmodule\tline:5\tlanguage:Perl\nnamespace::clean\tinput-0.pl\t/^use namespace::clean;$/;\"\tmodule\tline:6\tlanguage:Perl\nfeed_lion\tinput-0.pl\t/^sub feed_lion {$/;\"\tsubroutine\tline:8\tlanguage:Perl\nfeed_lion\tinput-0.pl\t/^sub feed_lion {$/;\"\tmethod\tline:8\tlanguage:Moose\tclass:Cat::Food\ntaste\tinput-0.pl\t/^has taste => ($/;\"\tattribute\tline:15\tlanguage:Moose\tclass:Cat::Food\nbrand\tinput-0.pl\t/^has brand => ($/;\"\tattribute\tline:19\tlanguage:Moose\tclass:Cat::Food\npounds\tinput-0.pl\t/^has pounds => ($/;\"\tattribute\tline:26\tlanguage:Moose\tclass:Cat::Food\n"
  },
  {
    "path": "Units/parser-moose.r/simple-moose.d/input-0.pl",
    "content": "# Taken from https://metacpan.org/pod/Moo\npackage Cat::Food;\n \nuse Moo;\nuse strictures 2;\nuse namespace::clean;\n \nsub feed_lion {\n  my $self = shift;\n  my $amount = shift || 1;\n \n  $self->pounds( $self->pounds - $amount );\n}\n \nhas taste => (\n  is => 'ro',\n);\n \nhas brand => (\n  is  => 'ro',\n  isa => sub {\n    die \"Only SWEET-TREATZ supported!\" unless $_[0] eq 'SWEET-TREATZ'\n  },\n);\n \nhas pounds => (\n  is  => 'rw',\n  isa => sub { die \"$_[0] is too much cat food!\" unless $_[0] < 15 },\n);\n \n1;\n"
  },
  {
    "path": "Units/parser-moose.r/simple-moose.d/input.pl",
    "content": "# Taken from https://metacpan.org/pod/Moose\npackage Point;\nuse Moose; # automatically turns on strict and warnings\n\nhas 'x' => (is => 'rw', isa => 'Int');\nhas 'y' => (is => 'rw', isa => 'Int');\n\nhas z0 => (is => 'rw');\nhas 'z1' => (is => 'rw');\nhas \"z2\" => (is => 'rw');\n\nhas (z0p => (is => 'rw'));\nhas ('z1p' => (is => 'rw'));\nhas (\"z2p\" => (is => 'rw'));\n\nhas (\tz0ps => (is => 'rw'));\nhas (\t'z1ps' => (is => 'rw'));\nhas (\t\"z2ps\" => (is => 'rw'));\n\nhas [qw#z3\tz4 z5#] => ((is => 'rw'),(is => 'rw'),(is => 'rw'));\nhas ([qw|z6\tz7|] => (is => 'rw'), (is => 'rw'));\n\nsub clear {\n    my $self = shift;\n    $self->x(0);\n    $self->y(0);\n}\n\npackage Point3D;\nuse Moose;\n\nextends 'Point';\n\nhas 'z' => (is => 'rw', isa => 'Int');\n\nbefore 'clear' => sub {\n};\n\nafter 'clear' => sub {\n};\n\naround 'clear' => sub {\n};\n\npackage TimeAxis;\nuse Moose;\n\npackage Point4D;\nuse Moose;\n\nextends 'Point3D',\n    'TimeAxis' ;\n\noverride \"clear\" => sub {\n};\n\nno Moose;\npackage Line;\n"
  },
  {
    "path": "Units/parser-moose.r/wrong-position.d/args.ctags",
    "content": "--fields=+nlK\n"
  },
  {
    "path": "Units/parser-moose.r/wrong-position.d/expected.tags",
    "content": "Test\tinput.pl\t/^package Test;$/;\"\tclass\tline:1\tlanguage:Moose\nTest\tinput.pl\t/^package Test;$/;\"\tpackage\tline:1\tlanguage:Perl\nget_by_id\tinput.pl\t/^sub get_by_id ()$/;\"\tmethod\tline:5\tlanguage:Moose\tclass:Test\nget_by_id\tinput.pl\t/^sub get_by_id ()$/;\"\tsubroutine\tline:5\tlanguage:Perl\n"
  },
  {
    "path": "Units/parser-moose.r/wrong-position.d/input.pl",
    "content": "package Test;\n\nuse Moose;\n\nsub get_by_id ()\n{\n}\n# Taken from github issue #3086 reported by @brtastic.\n"
  },
  {
    "path": "Units/parser-myrddin.r/simple.d/expected.tags",
    "content": "complex_def\tinput.myr\t/^type complex_def = struct$/;\"\tt\nsimple_def\tinput.myr\t/^type simple_def = int$/;\"\tt\ntest_const666\tinput.myr\t/^const test_const666 = \"foo\"$/;\"\tc\ntest_init_const666\tinput.myr\t/^const test_init_const666 = \"foo\"$/;\"\tc\ntest_init_func\tinput.myr\t/^const test_init_func = {; func_body() }$/;\"\tf\ntest_init_var999\tinput.myr\t/^var test_init_var999 = 123$/;\"\tv\ntest_package123\tinput.myr\t/^pkg test_package123 =$/;\"\tp\ntest_var999\tinput.myr\t/^var test_var999$/;\"\tv\n"
  },
  {
    "path": "Units/parser-myrddin.r/simple.d/input.myr",
    "content": "pkg test_package123 =\n;;\n\nconst test_init_func = {; func_body() }\nconst test_init_const666 = \"foo\"\nconst test_const666 = \"foo\"\nvar test_init_var999 = 123\nvar test_var999\ntype simple_def = int\ntype complex_def = struct\n    x : int\n    y : char\n;;\n\n"
  },
  {
    "path": "Units/parser-nftables.r/family-and-hook.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nftables.r/family-and-hook.d/expected.tags",
    "content": "ip\tinput.nft\t/^family ip {$/;\"\tf\nprerouting\tinput.nft\t/^\thook prerouting {$/;\"\th\tfamily:ip\ninput\tinput.nft\t/^\thook input {$/;\"\th\tfamily:ip\nforward\tinput.nft\t/^\thook forward {$/;\"\th\tfamily:ip\noutput\tinput.nft\t/^\thook output {$/;\"\th\tfamily:ip\npostrouting\tinput.nft\t/^\thook postrouting {$/;\"\th\tfamily:ip\nip6\tinput.nft\t/^family ip6 {$/;\"\tf\nprerouting\tinput.nft\t/^\thook prerouting {$/;\"\th\tfamily:ip6\ninput\tinput.nft\t/^\thook input {$/;\"\th\tfamily:ip6\nforward\tinput.nft\t/^\thook forward {$/;\"\th\tfamily:ip6\noutput\tinput.nft\t/^\thook output {$/;\"\th\tfamily:ip6\npostrouting\tinput.nft\t/^\thook postrouting {$/;\"\th\tfamily:ip6\n"
  },
  {
    "path": "Units/parser-nftables.r/family-and-hook.d/input.nft",
    "content": "# nft list hooks\nfamily ip {\n\thook prerouting {\n\t\t-0000000400 ipv4_conntrack_defrag [nf_defrag_ipv4]\n\t\t-0000000300 ipt_do_table [ip_tables]\n\t\t-0000000200 ipv4_conntrack_in [nf_conntrack]\n\t\t-0000000150 iptable_mangle_hook [iptable_mangle]\n\t\t-0000000140 chain inet firewalld mangle_PREROUTING [nf_tables]\n\t\t-0000000100 nf_nat_ipv4_pre_routing [nf_nat]\n\t\t+0000000010 chain inet firewalld filter_PREROUTING [nf_tables]\n\t}\n\thook input {\n\t\t-0000000150 iptable_mangle_hook [iptable_mangle]\n\t\t 0000000000 ipt_do_table [ip_tables]\n\t\t+0000000010 chain inet firewalld filter_INPUT [nf_tables]\n\t\t+0000000050 ipt_do_table [ip_tables]\n\t\t+0000000100 nf_nat_ipv4_local_in [nf_nat]\n\t\t+2147483647 nf_confirm [nf_conntrack]\n\t}\n\thook forward {\n\t\t-0000000225 selinux_ip_forward\n\t\t-0000000150 iptable_mangle_hook [iptable_mangle]\n\t\t 0000000000 chain ip libvirt_network forward [nf_tables]\n\t\t 0000000000 ipt_do_table [ip_tables]\n\t\t+0000000010 chain inet firewalld filter_FORWARD [nf_tables]\n\t\t+0000000050 ipt_do_table [ip_tables]\n\t}\n\thook output {\n\t\t-0000000400 ipv4_conntrack_defrag [nf_defrag_ipv4]\n\t\t-0000000300 ipt_do_table [ip_tables]\n\t\t-0000000225 selinux_ip_output\n\t\t-0000000200 ipv4_conntrack_local [nf_conntrack]\n\t\t-0000000150 iptable_mangle_hook [iptable_mangle]\n\t\t-0000000100 nf_nat_ipv4_local_fn [nf_nat]\n\t\t 0000000000 ipt_do_table [ip_tables]\n\t\t+0000000010 chain inet firewalld filter_OUTPUT [nf_tables]\n\t\t+0000000050 ipt_do_table [ip_tables]\n\t}\n\thook postrouting {\n\t\t-0000000150 iptable_mangle_hook [iptable_mangle]\n\t\t+0000000100 nf_nat_ipv4_out [nf_nat]\n\t\t+0000000225 selinux_ip_postroute\n\t\t+2147483647 nf_confirm [nf_conntrack]\n\t}\n}\nfamily ip6 {\n\thook prerouting {\n\t\t-0000000400 ipv6_defrag [nf_defrag_ipv6]\n\t\t-0000000300 ip6t_do_table [ip6_tables]\n\t\t-0000000200 ipv6_conntrack_in [nf_conntrack]\n\t\t-0000000150 ip6table_mangle_hook [ip6table_mangle]\n\t\t-0000000140 chain inet firewalld mangle_PREROUTING [nf_tables]\n\t\t-0000000100 nf_nat_ipv6_in [nf_nat]\n\t\t+0000000010 chain inet firewalld filter_PREROUTING [nf_tables]\n\t}\n\thook input {\n\t\t-0000000150 ip6table_mangle_hook [ip6table_mangle]\n\t\t 0000000000 ip6t_do_table [ip6_tables]\n\t\t+0000000010 chain inet firewalld filter_INPUT [nf_tables]\n\t\t+0000000050 ip6t_do_table [ip6_tables]\n\t\t+0000000100 nf_nat_ipv6_local_in [nf_nat]\n\t\t+2147483646 nf_confirm [nf_conntrack]\n\t}\n\thook forward {\n\t\t-0000000225 selinux_ip_forward\n\t\t-0000000150 ip6table_mangle_hook [ip6table_mangle]\n\t\t 0000000000 chain ip6 libvirt_network forward [nf_tables]\n\t\t 0000000000 ip6t_do_table [ip6_tables]\n\t\t+0000000010 chain inet firewalld filter_FORWARD [nf_tables]\n\t\t+0000000050 ip6t_do_table [ip6_tables]\n\t}\n\thook output {\n\t\t-0000000400 ipv6_defrag [nf_defrag_ipv6]\n\t\t-0000000300 ip6t_do_table [ip6_tables]\n\t\t-0000000225 selinux_ip_output\n\t\t-0000000200 ipv6_conntrack_local [nf_conntrack]\n\t\t-0000000150 ip6table_mangle_hook [ip6table_mangle]\n\t\t-0000000100 nf_nat_ipv6_local_fn [nf_nat]\n\t\t 0000000000 ip6t_do_table [ip6_tables]\n\t\t+0000000010 chain inet firewalld filter_OUTPUT [nf_tables]\n\t\t+0000000050 ip6t_do_table [ip6_tables]\n\t}\n\thook postrouting {\n\t\t-0000000150 ip6table_mangle_hook [ip6table_mangle]\n\t\t+0000000100 nf_nat_ipv6_out [nf_nat]\n\t\t+0000000225 selinux_ip_postroute\n\t\t+2147483647 nf_confirm [nf_conntrack]\n\t}\n}\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-all-in-one.d/README",
    "content": "The input is taken from nftables/files/nftables/all-in-one.nft.\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-all-in-one.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-all-in-one.d/expected.tags",
    "content": "./inet-filter.nft\tinput.nft\t/^include \".\\/inet-filter.nft\"$/;\"\tR\n./inet-nat.nft\tinput.nft\t/^include \".\\/inet-nat.nft\"$/;\"\tR\n./netdev-ingress.nft\tinput.nft\t/^include \".\\/netdev-ingress.nft\"$/;\"\tR\n./ipv4-filter.nft\tinput.nft\t/^include \".\\/ipv4-filter.nft\"$/;\"\tR\n./ipv4-mangle.nft\tinput.nft\t/^include \".\\/ipv4-mangle.nft\"$/;\"\tR\n./ipv4-nat.nft\tinput.nft\t/^include \".\\/ipv4-nat.nft\"$/;\"\tR\n./ipv4-raw.nft\tinput.nft\t/^include \".\\/ipv4-raw.nft\"$/;\"\tR\n./ipv6-filter.nft\tinput.nft\t/^include \".\\/ipv6-filter.nft\"$/;\"\tR\n./ipv6-mangle.nft\tinput.nft\t/^include \".\\/ipv6-mangle.nft\"$/;\"\tR\n./ipv6-nat.nft\tinput.nft\t/^include \".\\/ipv6-nat.nft\"$/;\"\tR\n./ipv6-raw.nft\tinput.nft\t/^include \".\\/ipv6-raw.nft\"$/;\"\tR\n./arp-filter.nft\tinput.nft\t/^include \".\\/arp-filter.nft\"$/;\"\tR\n./bridge-filter.nft\tinput.nft\t/^include \".\\/bridge-filter.nft\"$/;\"\tR\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-all-in-one.d/input.nft",
    "content": "# Here is an example of different families, hooks and priorities in the\n# nftables framework, all mixed together.\n#\n# more examples are located in files/examples in nftables source.\n# For up-to-date information please visit https://wiki.nftables.org\n#\n# This script is meant to be loaded with `nft -f <file>`\n\n# clear all prior state\nflush ruleset\n\n# native dual stack IPv4 & IPv6 family\ninclude \"./inet-filter.nft\"\ninclude \"./inet-nat.nft\"\n\n# netdev family at ingress hook. Attached to a given NIC\ninclude \"./netdev-ingress.nft\"\n\n# IPv4 family, typical iptables tables/chains layout\ninclude \"./ipv4-filter.nft\"\ninclude \"./ipv4-mangle.nft\"\ninclude \"./ipv4-nat.nft\"\ninclude \"./ipv4-raw.nft\"\n\n# IPv6 family, typical ip6tables tables/chains layout\ninclude \"./ipv6-filter.nft\"\ninclude \"./ipv6-mangle.nft\"\ninclude \"./ipv6-nat.nft\"\ninclude \"./ipv6-raw.nft\"\n\n# ARP family, typical arptables tables/chain layout\ninclude \"./arp-filter.nft\"\n\n# bridge family, typical ebtables tables/chain layout\ninclude \"./bridge-filter.nft\"\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-counter.d/README",
    "content": "The input file is taken from nftables/tests/shell/testcases/sets/dumps/0073flat_interval_set.nft.\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-counter.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-counter.d/expected.tags",
    "content": "filter\tinput.nft\t/^table inet filter {$/;\"\tt\tfamily:inet\nTEST\tinput.nft\t/^\tcounter TEST {$/;\"\tC\ttable:inet.filter\ntestmap\tinput.nft\t/^\tmap testmap {$/;\"\tm\ttable:inet.filter\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-counter.d/input.nft",
    "content": "table inet filter {\n\tcounter TEST {\n\t\tpackets 0 bytes 0\n\t}\n\n\tmap testmap {\n\t\ttype ipv4_addr : counter\n\t\tflags interval\n\t\telements = { 192.168.0.0/24 : \"TEST\" }\n\t}\n}\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-ct_helpers.d/README",
    "content": "The input is taken from nftables/files/examples/ct_helpers.nft.\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-ct_helpers.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-ct_helpers.d/expected.tags",
    "content": "filter\tinput.nft\t/^table inet filter {$/;\"\tt\tfamily:inet\nftp-standard\tinput.nft\t/^\tct helper ftp-standard {$/;\"\tH\ttable:inet.filter\nsip-5060\tinput.nft\t/^\tct helper sip-5060 {$/;\"\tH\ttable:inet.filter\ntftp-69\tinput.nft\t/^\tct helper tftp-69 {$/;\"\tH\ttable:inet.filter\ninput\tinput.nft\t/^\tchain input {$/;\"\tc\ttable:inet.filter\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-ct_helpers.d/input.nft",
    "content": "#!/usr/sbin/nft -f\n\n# This example file shows how to use ct helpers in the nftables framework.\n# Note that nftables includes interesting improvements compared to how this\n# was done with iptables, such as loading multiple helpers with a single rule\n# This script is meant to be loaded with `nft -f <file>`\n# You require linux kernel >= 4.12 and nft >= 0.8\n# For up-to-date information please visit https://wiki.nftables.org\n\n# Using ct helpers is an important security feature when doing stateful\n# firewalling, since it mitigate certain networking attacks.\n# More info at: https://home.regit.org/netfilter-en/secure-use-of-helpers/\n\n\nflush ruleset\ntable inet filter {\n\t# declare helpers of this table\n\tct helper ftp-standard {\n\t\ttype \"ftp\" protocol tcp;\n\t\tl3proto inet\n\t}\n\tct helper sip-5060 {\n\t\ttype \"sip\" protocol udp;\n\t\tl3proto inet\n\t}\n\tct helper tftp-69 {\n\t\ttype \"tftp\" protocol udp\n\t\tl3proto inet\n\t}\n\n\tchain input {\n\t\ttype filter hook input priority 0; policy drop;\n\t\tct state established,related accept\n\n\t\t# assign a single helper in a single rule\n\t\ttcp dport 21 ct helper set \"ftp-standard\"\n\n\t\t# assign multiple helpers in a single rule\n\t\tct helper set udp dport map {\n\t                        69 : \"tftp-69\", \\\n\t\t                5060 : \"sip-5060\" }\n\t}\n}\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-define_sets_and_maps.d/README",
    "content": "The input is taken from nftables/files/examples/sets_and_maps.nft.\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-define_sets_and_maps.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-define_sets_and_maps.d/expected.tags",
    "content": "int_if1\tinput.nft\t/^define int_if1\t = eth0$/;\"\tD\nint_if2\tinput.nft\t/^define int_if2\t = eth1$/;\"\tD\nint_ifs\tinput.nft\t/^define int_ifs\t = { $int_if1, $int_if2 }$/;\"\tD\next_if1\tinput.nft\t/^define ext_if1\t = eth2$/;\"\tD\next_if2\tinput.nft\t/^define ext_if2\t = eth3$/;\"\tD\next_ifs\tinput.nft\t/^define ext_ifs\t = { $ext_if1, $ext_if2 }$/;\"\tD\nlocal_ifs\tinput.nft\t/^define local_ifs = { $int_ifs, $ext_ifs }$/;\"\tD\ntcp_ports\tinput.nft\t/^define tcp_ports = { ssh, domain, https, 123-125 }$/;\"\tD\nfilter\tinput.nft\t/^table filter {$/;\"\tt\nlocal_ifs\tinput.nft\t/^\tset local_ifs {$/;\"\ts\ttable:filter\nnat_map\tinput.nft\t/^\tmap nat_map {$/;\"\tm\ttable:filter\njump_map\tinput.nft\t/^\tmap jump_map {$/;\"\tm\ttable:filter\ninput_1\tinput.nft\t/^\tchain input_1 { counter; }$/;\"\tc\ttable:filter\ninput_2\tinput.nft\t/^\tchain input_2 { counter; }$/;\"\tc\ttable:filter\ninput\tinput.nft\t/^\tchain input {$/;\"\tc\ttable:filter\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-define_sets_and_maps.d/input.nft",
    "content": "#!/usr/sbin/nft -f\n\n# This example file shows how to use sets and maps in the nftables framework.\n# This script is meant to be loaded with `nft -f <file>`\n# For up-to-date information please visit https://wiki.nftables.org\n\n# symbolic anonymous set definition built from symbolic singleton definitions\ndefine int_if1\t = eth0\ndefine int_if2\t = eth1\ndefine int_ifs\t = { $int_if1, $int_if2 }\n\ndefine ext_if1\t = eth2\ndefine ext_if2\t = eth3\ndefine ext_ifs\t = { $ext_if1, $ext_if2 }\n\n# recursive symbolic anonymous set definition\ndefine local_ifs = { $int_ifs, $ext_ifs }\n\n# symbolic anonymous set definition\ndefine tcp_ports = { ssh, domain, https, 123-125 }\n\ndelete table filter\ntable filter {\n\t# named set of type iface_index\n\tset local_ifs {\n\t\ttype iface_index\n\t}\n\n\t# named map of type iface_index : ipv4_addr\n\tmap nat_map {\n\t\ttype iface_index : ipv4_addr\n\t}\n\n\tmap jump_map {\n\t\ttype iface_index : verdict\n\t}\n\n\tchain input_1 { counter; }\n\tchain input_2 { counter; }\n\tchain input {\n\t\ttype filter hook input priority 0\n\n\t\t# symbolic anonymous sets\n\t\tmeta iif $local_ifs tcp dport $tcp_ports counter\n\n\t\t# literal anonymous set\n\t\tmeta iif { eth0, eth1 } counter\n\n\t\tmeta iif @local_ifs counter\n\t\tmeta iif vmap @jump_map\n\n\t\t#meta iif vmap { eth0 : jump input1, eth1 : jump input2 }\n\t}\n}\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-flowtable.d/README",
    "content": "The input is taken from nftables/tests/shell/testcases/flowtable/dumps/0001flowtable_0.nft.\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-flowtable.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-flowtable.d/expected.tags",
    "content": "t\tinput.nft\t/^table inet t {$/;\"\tt\tfamily:inet\nf\tinput.nft\t/^\tflowtable f {$/;\"\tW\ttable:inet.t\nc\tinput.nft\t/^\tchain c {$/;\"\tc\ttable:inet.t\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-flowtable.d/input.nft",
    "content": "table inet t {\n\tflowtable f {\n\t\thook ingress priority filter + 10\n\t\tdevices = { lo }\n\t}\n\n\tchain c {\n\t\tflow add @f\n\t}\n}\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-limits.d/README",
    "content": "The input file is taken from nftables/tests/shell/testcases/maps/dumps/named_limits.nft.\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-limits.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-limits.d/expected.tags",
    "content": "filter\tinput.nft\t/^table inet filter {$/;\"\tt\tfamily:inet\ntarpit-pps\tinput.nft\t/^\tlimit tarpit-pps {$/;\"\tL\ttable:inet.filter\ntarpit-bps\tinput.nft\t/^\tlimit tarpit-bps {$/;\"\tL\ttable:inet.filter\nhttp-bulk-rl-1m\tinput.nft\t/^\tlimit http-bulk-rl-1m {$/;\"\tL\ttable:inet.filter\nhttp-bulk-rl-10m\tinput.nft\t/^\tlimit http-bulk-rl-10m {$/;\"\tL\ttable:inet.filter\ntarpit4\tinput.nft\t/^\tset tarpit4 {$/;\"\ts\ttable:inet.filter\ntarpit6\tinput.nft\t/^\tset tarpit6 {$/;\"\ts\ttable:inet.filter\naddr4limit\tinput.nft\t/^\tmap addr4limit {$/;\"\tm\ttable:inet.filter\nsaddr6limit\tinput.nft\t/^\tmap saddr6limit {$/;\"\tm\ttable:inet.filter\ninput\tinput.nft\t/^\tchain input {$/;\"\tc\ttable:inet.filter\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-limits.d/input.nft",
    "content": "table inet filter {\n\tlimit tarpit-pps {\n\t\trate 1/second\n\t}\n\n\tlimit tarpit-bps {\n\t\trate 1 kbytes/second\n\t}\n\n\tlimit http-bulk-rl-1m {\n\t\trate 1 mbytes/second\n\t}\n\n\tlimit http-bulk-rl-10m {\n\t\trate 10 mbytes/second\n\t}\n\n\tset tarpit4 {\n\t\ttypeof ip saddr\n\t\tsize 10000\n\t\tflags dynamic,timeout\n\t\ttimeout 1m\n\t}\n\n\tset tarpit6 {\n\t\ttypeof ip6 saddr\n\t\tsize 10000\n\t\tflags dynamic,timeout\n\t\ttimeout 1m\n\t}\n\n\tmap addr4limit {\n\t\ttypeof meta l4proto . ip saddr . tcp sport : limit\n\t\tflags interval\n\t\telements = { tcp . 192.168.0.0/16 . 1-65535 : \"tarpit-bps\",\n\t\t\t     udp . 192.168.0.0/16 . 1-65535 : \"tarpit-pps\",\n\t\t\t     tcp . 127.0.0.1-127.1.2.3 . 1-1024 : \"tarpit-pps\",\n\t\t\t     tcp . 10.0.0.1-10.0.0.255 . 80 : \"http-bulk-rl-1m\",\n\t\t\t     tcp . 10.0.0.1-10.0.0.255 . 443 : \"http-bulk-rl-1m\",\n\t\t\t     tcp . 10.0.1.0/24 . 1024-65535 : \"http-bulk-rl-10m\",\n\t\t\t     tcp . 10.0.2.1 . 22 : \"http-bulk-rl-10m\" }\n\t}\n\n\tmap saddr6limit {\n\t\ttypeof ip6 saddr : limit\n\t\tflags interval\n\t\telements = { dead::beef-dead::1:aced : \"tarpit-pps\" }\n\t}\n\n\tchain input {\n\t\ttype filter hook input priority filter; policy accept;\n\t\tlimit name meta l4proto . ip saddr . th sport map @addr4limit\n\t\tlimit name ip6 saddr map @saddr6limit\n\t}\n}\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-named_ct_objects.d/README",
    "content": "The input is taken from nftables/tests/shell/testcases/maps/dumps/named_ct_objects.nft.\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-named_ct_objects.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-named_ct_objects.d/expected.tags",
    "content": "t\tinput.nft\t/^table inet t {$/;\"\tt\tfamily:inet\nexp1\tinput.nft\t/^\tct expectation exp1 {$/;\"\tE\ttable:inet.t\nexp2\tinput.nft\t/^\tct expectation exp2 {$/;\"\tE\ttable:inet.t\nmyftp\tinput.nft\t/^\tct helper myftp {$/;\"\tH\ttable:inet.t\ndns\tinput.nft\t/^\tct timeout dns {$/;\"\tT\ttable:inet.t\nexp\tinput.nft\t/^\tmap exp {$/;\"\tm\ttable:inet.t\nexp6\tinput.nft\t/^\tmap exp6 {$/;\"\tm\ttable:inet.t\nhelpobj\tinput.nft\t/^\tmap helpobj {$/;\"\tm\ttable:inet.t\ntimeoutmap\tinput.nft\t/^\tmap timeoutmap {$/;\"\tm\ttable:inet.t\nhelpname\tinput.nft\t/^\tset helpname {$/;\"\ts\ttable:inet.t\ny\tinput.nft\t/^\tchain y {$/;\"\tc\ttable:inet.t\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-named_ct_objects.d/input.nft",
    "content": "table inet t {\n\tct expectation exp1 {\n\t\tprotocol tcp\n\t\tdport 9876\n\t\ttimeout 1m\n\t\tsize 12\n\t\tl3proto ip\n\t}\n\n\tct expectation exp2 {\n\t\tprotocol tcp\n\t\tdport 9876\n\t\ttimeout 3s\n\t\tsize 13\n\t\tl3proto ip6\n\t}\n\n\tct helper myftp {\n\t\ttype \"ftp\" protocol tcp\n\t\tl3proto inet\n\t}\n\n\tct timeout dns {\n\t\tprotocol tcp\n\t\tl3proto ip\n\t\tpolicy = { established : 3s, close : 1s }\n\t}\n\n\tmap exp {\n\t\ttypeof ip saddr : ct expectation\n\t\telements = { 192.168.2.2 : \"exp1\" }\n\t}\n\n\tmap exp6 {\n\t\ttypeof ip6 saddr : ct expectation\n\t\tflags interval\n\t\telements = { dead:beef::/64 : \"exp2\" }\n\t}\n\n\tmap helpobj {\n\t\ttypeof ip6 saddr : ct helper\n\t\tflags interval\n\t\telements = { dead:beef::/64 : \"myftp\" }\n\t}\n\n\tmap timeoutmap {\n\t\ttypeof ip daddr : ct timeout\n\t\telements = { 192.168.0.1 : \"dns\" }\n\t}\n\n\tset helpname {\n\t\ttypeof ct helper\n\t\telements = { \"sip\",\n\t\t\t     \"ftp\" }\n\t}\n\n\tchain y {\n\t\tct expectation set ip saddr map @exp\n\t\tct expectation set ip6 saddr map { dead::beef : \"exp2\" }\n\t\tct expectation set ip6 daddr map { dead::beef : \"exp2\", feed::17 : \"exp2\" }\n\t\tct expectation set ip6 daddr . tcp dport map { feed::17 . 512 : \"exp2\", dead::beef . 123 : \"exp2\" }\n\t\tct helper set ip6 saddr map { 1c3::c01d : \"myftp\", dead::beef : \"myftp\" }\n\t\tct helper set ip6 saddr map @helpobj\n\t\tct timeout set ip daddr map @timeoutmap\n\t\tct timeout set ip daddr map { 1.2.3.4 : \"dns\", 5.6.7.8 : \"dns\", 192.168.8.0/24 : \"dns\" }\n\t\tct timeout set ip daddr map { 1.2.3.4-1.2.3.8 : \"dns\" }\n\t\tct timeout set ip6 daddr map { 1ce::/64 : \"dns\", dead::beef : \"dns\" }\n\t\tct helper @helpname accept\n\t\tip saddr 192.168.1.1 ct timeout set \"dns\"\n\t}\n}\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-quota.d/README",
    "content": "The input file is taken from nftables/tests/shell/testcases/maps/dumps/0024named_objects_0.nft.\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-quota.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-quota.d/expected.tags",
    "content": "x\tinput.nft\t/^table inet x {$/;\"\tt\tfamily:inet\nuser123\tinput.nft\t/^\tcounter user123 {$/;\"\tC\ttable:inet.x\nuser321\tinput.nft\t/^\tcounter user321 {$/;\"\tC\ttable:inet.x\nuser123\tinput.nft\t/^\tquota user123 {$/;\"\tQ\ttable:inet.x\nuser124\tinput.nft\t/^\tquota user124 {$/;\"\tQ\ttable:inet.x\ny\tinput.nft\t/^\tset y {$/;\"\ts\ttable:inet.x\ntest\tinput.nft\t/^\tmap test {$/;\"\tm\ttable:inet.x\ny\tinput.nft\t/^\tchain y {$/;\"\tc\ttable:inet.x\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-quota.d/input.nft",
    "content": "table inet x {\n\tcounter user123 {\n\t\tpackets 12 bytes 1433\n\t}\n\n\tcounter user321 {\n\t\tpackets 0 bytes 0\n\t}\n\n\tquota user123 {\n\t\tover 2000 bytes\n\t}\n\n\tquota user124 {\n\t\tover 2000 bytes\n\t}\n\n\tset y {\n\t\ttype ipv4_addr\n\t}\n\n\tmap test {\n\t\ttype ipv4_addr : quota\n\t\telements = { 192.168.2.2 : \"user124\",\n\t\t\t     192.168.2.3 : \"user124\" }\n\t}\n\n\tchain y {\n\t\ttype filter hook input priority filter; policy accept;\n\t\tcounter name ip saddr map { 1.1.1.1 : \"user123\", 2.2.2.2 : \"user123\", 192.168.2.2 : \"user123\" }\n\t\tquota name ip saddr map @test drop\n\t}\n}\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-secmark.d/README",
    "content": "The input is taken from nftables/files/examples/semark.nft.\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-secmark.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-secmark.d/expected.tags",
    "content": "x\tinput.nft\t/^table inet x {$/;\"\tt\tfamily:inet\nssh_server\tinput.nft\t/^\tsecmark ssh_server {$/;\"\tS\ttable:inet.x\ndns_client\tinput.nft\t/^\tsecmark dns_client {$/;\"\tS\ttable:inet.x\nhttp_client\tinput.nft\t/^\tsecmark http_client {$/;\"\tS\ttable:inet.x\nhttps_client\tinput.nft\t/^\tsecmark https_client {$/;\"\tS\ttable:inet.x\nntp_client\tinput.nft\t/^\tsecmark ntp_client {$/;\"\tS\ttable:inet.x\nicmp_client\tinput.nft\t/^\tsecmark icmp_client {$/;\"\tS\ttable:inet.x\nicmp_server\tinput.nft\t/^\tsecmark icmp_server {$/;\"\tS\ttable:inet.x\nssh_client\tinput.nft\t/^\tsecmark ssh_client {$/;\"\tS\ttable:inet.x\ngit_client\tinput.nft\t/^\tsecmark git_client {$/;\"\tS\ttable:inet.x\nsecmapping_in\tinput.nft\t/^\tmap secmapping_in {$/;\"\tm\ttable:inet.x\nsecmapping_out\tinput.nft\t/^\tmap secmapping_out {$/;\"\tm\ttable:inet.x\ny\tinput.nft\t/^\tchain y {$/;\"\tc\ttable:inet.x\nz\tinput.nft\t/^\tchain z {$/;\"\tc\ttable:inet.x\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-secmark.d/input.nft",
    "content": "#!/usr/sbin/nft -f\n\n# This example file shows how to use secmark labels with the nftables framework.\n# This script is meant to be loaded with `nft -f <file>`\n# You require linux kernel >= 4.20 and nft >= 0.9.3\n# This example is SELinux based, for the secmark objects you require\n# SELinux enabled and a SELinux policy defining the stated contexts\n# For up-to-date information please visit https://wiki.nftables.org\n\n\nflush ruleset\n\ntable inet x {\n\tsecmark ssh_server {\n\t\t\"system_u:object_r:ssh_server_packet_t:s0\"\n\t}\n\n\tsecmark dns_client {\n\t\t\"system_u:object_r:dns_client_packet_t:s0\"\n\t}\n\n\tsecmark http_client {\n\t\t\"system_u:object_r:http_client_packet_t:s0\"\n\t}\n\n\tsecmark https_client {\n\t\t\"system_u:object_r:http_client_packet_t:s0\"\n\t}\n\n\tsecmark ntp_client {\n\t\t\"system_u:object_r:ntp_client_packet_t:s0\"\n\t}\n\n\tsecmark icmp_client {\n\t\t\"system_u:object_r:icmp_client_packet_t:s0\"\n\t}\n\n\tsecmark icmp_server {\n\t\t\"system_u:object_r:icmp_server_packet_t:s0\"\n\t}\n\n\tsecmark ssh_client {\n\t\t\"system_u:object_r:ssh_client_packet_t:s0\"\n\t}\n\n\tsecmark git_client {\n\t\t\"system_u:object_r:git_client_packet_t:s0\"\n\t}\n\n\tmap secmapping_in {\n\t\ttype inet_service : secmark\n\t\telements = { 22 : \"ssh_server\" }\n\t}\n\n\tmap secmapping_out {\n\t\ttype inet_service : secmark\n\t\telements = { 22 : \"ssh_client\", 53 : \"dns_client\", 80 : \"http_client\", 123 : \"ntp_client\", 443 : \"http_client\", 9418 : \"git_client\" }\n\t}\n\n\tchain y {\n\t\ttype filter hook input priority -225;\n\n\t\t# label new incoming packets and add to connection\n\t\tct state new meta secmark set tcp dport map @secmapping_in\n\t\tct state new meta secmark set udp dport map @secmapping_in\n\t\tct state new ip protocol icmp meta secmark set \"icmp_server\"\n\t\tct state new ip6 nexthdr icmpv6 meta secmark set \"icmp_server\"\n\t\tct state new ct secmark set meta secmark\n\n\t\t# set label for est/rel packets from connection\n\t\tct state established,related meta secmark set ct secmark\n\t}\n\n\tchain z {\n\t\ttype filter hook output priority 225;\n\n\t\t# label new outgoing packets and add to connection\n\t\tct state new meta secmark set tcp dport map @secmapping_out\n\t\tct state new meta secmark set udp dport map @secmapping_out\n\t\tct state new ip protocol icmp meta secmark set \"icmp_client\"\n\t\tct state new ip6 nexthdr icmpv6 meta secmark set \"icmp_client\"\n\t\tct state new ct secmark set meta secmark\n\n\t\t# set label for est/rel packets from connection\n\t\tct state established,related meta secmark set ct secmark\n\t}\n}\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-synproxy.d/README",
    "content": "The input is taken from nftables/tests/shell/testcases/sets/dumps/0024synproxy_0.nft.\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-synproxy.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-synproxy.d/expected.tags",
    "content": "x\tinput.nft\t/^table inet x {$/;\"\tt\tfamily:inet\nhttps-synproxy\tinput.nft\t/^\tsynproxy https-synproxy {$/;\"\tP\ttable:inet.x\nother-synproxy\tinput.nft\t/^\tsynproxy other-synproxy {$/;\"\tP\ttable:inet.x\ntest2\tinput.nft\t/^\tmap test2 {$/;\"\tm\ttable:inet.x\ny\tinput.nft\t/^\tchain y {$/;\"\tc\ttable:inet.x\n"
  },
  {
    "path": "Units/parser-nftables.r/nftables-synproxy.d/input.nft",
    "content": "table inet x {\n\tsynproxy https-synproxy {\n\t\tmss 1460\n\t\twscale 7\n\t\ttimestamp sack-perm\n\t}\n\n\tsynproxy other-synproxy {\n\t\tmss 1460\n\t\twscale 5\n\t}\n\n\tmap test2 {\n\t\ttype ipv4_addr : synproxy\n\t\tflags interval\n\t\telements = { 192.168.1.0/24 : \"https-synproxy\",\n\t\t\t     192.168.2.0/24 : \"other-synproxy\" }\n\t}\n\n\tchain y {\n\t\ttype filter hook input priority filter; policy accept;\n\t\tsynproxy name ip saddr map { 192.168.1.0/24 : \"https-synproxy\", 192.168.2.0/24 : \"other-synproxy\" }\n\t}\n}\n"
  },
  {
    "path": "Units/parser-nsis.r/include.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-nsis.r/include.d/expected.tags",
    "content": "WinMessages.nsh\tinput.nsi\t/^!include WinMessages.nsh$/;\"\ti\troles:included\nLibrary.nsh\tinput.nsi\t/^!include Library.nsh$/;\"\ti\troles:included\nC:\\\\MyConfig.nsi\tinput.nsi\t/^!include \\/CHARSET=CP1252 C:\\\\MyConfig.nsi$/;\"\ti\troles:included\n..\\\\MyConfig.nsh\tinput.nsi\t/^!include ..\\\\MyConfig.nsh$/;\"\ti\troles:included\nfile_that_may_exist_or_not.nsh\tinput.nsi\t/^!include \\/NONFATAL file_that_may_exist_or_not.nsh$/;\"\ti\troles:included\na.nsh\tinput.nsi\t/^!include a.nsh                         # COMMENT$/;\"\ti\troles:included\nb.nsh\tinput.nsi\t/^!include b.nsh                         ; COMMENT$/;\"\ti\troles:included\n"
  },
  {
    "path": "Units/parser-nsis.r/include.d/input.nsi",
    "content": "# Taken from https://nsis.sourceforge.io/Docs/Chapter5.html#include\n!include WinMessages.nsh\n!include Library.nsh\n!include /CHARSET=CP1252 C:\\MyConfig.nsi\n!include ..\\MyConfig.nsh\n!include /NONFATAL file_that_may_exist_or_not.nsh\n\n\n!include a.nsh                         # COMMENT\n!include b.nsh                         ; COMMENT\n"
  },
  {
    "path": "Units/parser-nsis.r/langstr.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nsis.r/langstr.d/expected.tags",
    "content": "message\tinput.nsi\t/^LangString message ${LANG_ENGLISH} \"English message\"$/;\"\tl\tlangid:${LANG_ENGLISH}\nmessage\tinput.nsi\t/^LangString message ${LANG_FRENCH} \"French message\"$/;\"\tl\tlangid:${LANG_FRENCH}\nmessage\tinput.nsi\t/^LangString message ${LANG_KOREAN} \"Korean message\"$/;\"\tl\tlangid:${LANG_KOREAN}\nlicense\tinput.nsi\t/^LicenseLangString license ${LANG_ENGLISH} license-english.txt$/;\"\tl\tlangid:${LANG_ENGLISH}\nlicense\tinput.nsi\t/^LicenseLangString license ${LANG_FRENCH} license-french.txt$/;\"\tl\tlangid:${LANG_FRENCH}\nlicense\tinput.nsi\t/^LicenseLangString license ${LANG_GERMAN} license-german.txt$/;\"\tl\tlangid:${LANG_GERMAN}\n^SetupCaption\tinput.nsi\t/^LangString ^SetupCaption     ${LANG_ENGLISH} \\\\$/;\"\tl\tlangid:${LANG_ENGLISH}\n^UninstallCaption\tinput.nsi\t/^LangString ^UninstallCaption ${LANG_ENGLISH} \\\\$/;\"\tl\tlangid:${LANG_ENGLISH}\n"
  },
  {
    "path": "Units/parser-nsis.r/langstr.d/input.nsi",
    "content": ";; https://nsis.sourceforge.io/Docs/Chapter4.html#langstring\n\nLangString message ${LANG_ENGLISH} \"English message\"\nLangString message ${LANG_FRENCH} \"French message\"\nLangString message ${LANG_KOREAN} \"Korean message\"\n\nMessageBox MB_OK \"A translated message: $(message)\"\n\n;; https://nsis.sourceforge.io/Docs/Chapter4.html#licenselangstring\nLicenseLangString license ${LANG_ENGLISH} license-english.txt\nLicenseLangString license ${LANG_FRENCH} license-french.txt\nLicenseLangString license ${LANG_GERMAN} license-german.txt\n\nLicenseData $(license)\n\n;; Taken from vim/nsis/lang/english.nsi\n\n# Overwrite the default translation.\n# These strings should be always English.  Otherwise dosinst.c fails.\nLangString ^SetupCaption     ${LANG_ENGLISH} \\\n        \"$(^Name) Setup\"\nLangString ^UninstallCaption ${LANG_ENGLISH} \\\n        \"$(^Name) Uninstall\"\n\n"
  },
  {
    "path": "Units/parser-nsis.r/section_groups.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nsis.r/section_groups.d/expected.tags",
    "content": "some stuff\tinput.nsi\t/^SectionGroup \"some stuff\"$/;\"\tS\na section\tinput.nsi\t/^Section \"a section\"$/;\"\ts\tsectionGroup:some stuff\nanother section\tinput.nsi\t/^Section \"another section\"$/;\"\ts\tsectionGroup:some stuff\nsome item\tinput.nsi\t/^SectionGroup \"some item\"$/;\"\tS\nb section\tinput.nsi\t/^Section \"b section\"$/;\"\ts\tsectionGroup:some item\nalt section\tinput.nsi\t/^Section \"alt section\"$/;\"\ts\tsectionGroup:some item\nthe rest (その他)\tinput.nsi\t/^SectionGroup \"the rest (その他)\"$/;\"\tS\nc section\tinput.nsi\t/^Section \"c section\"$/;\"\ts\tsectionGroup:the rest (その他)\nd section\tinput.nsi\t/^Section \"d section\"$/;\"\ts\tsectionGroup:the rest (その他)\n${SG0}\tinput.nsi\t/^SectionGroup \"${SG0}\" SG0$/;\"\tS\nSG0\tinput.nsi\t/^SectionGroup \"${SG0}\" SG0$/;\"\td\ne section\tinput.nsi\t/^Section \"e section\"$/;\"\ts\tsectionGroup:${SG0}\nf section\tinput.nsi\t/^Section \"f section\"$/;\"\ts\tsectionGroup:${SG0}\n$(SG1)\tinput.nsi\t/^SectionGroup \"$(SG1)\" SG1$/;\"\tS\nSG1\tinput.nsi\t/^SectionGroup \"$(SG1)\" SG1$/;\"\td\ng section\tinput.nsi\t/^Section \"g section\"$/;\"\ts\tsectionGroup:$(SG1)\nh section\tinput.nsi\t/^Section \"h section\"$/;\"\ts\tsectionGroup:$(SG1)\nAnonymousSectionGroup91b7d5e70105\tinput.nsi\t/^SectionGroup \"\" EMPTY0$/;\"\tS\nEMPTY0\tinput.nsi\t/^SectionGroup \"\" EMPTY0$/;\"\td\ni section\tinput.nsi\t/^Section \"i section\"$/;\"\ts\tsectionGroup:AnonymousSectionGroup91b7d5e70105\nj section\tinput.nsi\t/^Section \"j section\"$/;\"\ts\tsectionGroup:AnonymousSectionGroup91b7d5e70105\nx$\\\\\"y\tinput.nsi\t/^SectionGroup \"x$\\\\\"y\" XQY$/;\"\tS\nXQY\tinput.nsi\t/^SectionGroup \"x$\\\\\"y\" XQY$/;\"\td\nk section\tinput.nsi\t/^Section \"k section\"$/;\"\ts\tsectionGroup:x$\\\\\"y\nl section\tinput.nsi\t/^Section \"l section\"$/;\"\ts\tsectionGroup:x$\\\\\"y\n"
  },
  {
    "path": "Units/parser-nsis.r/section_groups.d/input.nsi",
    "content": "; Taken from https://nsis.sourceforge.io/Docs/Chapter4.html#sections\nSectionGroup \"some stuff\"\nSection \"a section\"\nSectionEnd\nSection \"another section\"\nSectionEnd\nSectionGroupEnd\n\nSectionGroup \"some item\"\nSection \"b section\"\nSectionEnd\nSection \"alt section\"\nSectionEnd\nSectionGroupEnd\n\nSectionGroup \"the rest (その他)\"\nSection \"c section\"\nSectionEnd\nSection \"d section\"\nSectionEnd\nSectionGroupEnd\n\nSectionGroup \"${SG0}\" SG0\nSection \"e section\"\nSectionEnd\nSection \"f section\"\nSectionEnd\nSectionGroupEnd\n\nSectionGroup \"$(SG1)\" SG1\nSection \"g section\"\nSectionEnd\nSection \"h section\"\nSectionEnd\nSectionGroupEnd\n\nSectionGroup \"\" EMPTY0\nSection \"i section\"\nSectionEnd\nSection \"j section\"\nSectionEnd\nSectionGroupEnd\n\nSectionGroup \"x$\\\"y\" XQY\nSection \"k section\"\nSectionEnd\nSection \"l section\"\nSectionEnd\nSectionGroupEnd\n"
  },
  {
    "path": "Units/parser-nsis.r/simple-nsis.d/args.ctags",
    "content": "--sort=no\n--kinds-nsis=+p\n"
  },
  {
    "path": "Units/parser-nsis.r/simple-nsis.d/expected.tags",
    "content": "PRODUCT_NAME\tinput.nsi\t/^!define PRODUCT_NAME \"Geany\"$/;\"\td\nPRODUCT_VERSION\tinput.nsi\t/^!define PRODUCT_VERSION \"1.35\"$/;\"\td\nPRODUCT_VERSION_ID\tinput.nsi\t/^!define PRODUCT_VERSION_ID \"1.35.0.0\"$/;\"\td\nPRODUCT_PUBLISHER\tinput.nsi\t/^!define PRODUCT_PUBLISHER \"The Geany developer team\"$/;\"\td\nPRODUCT_WEB_SITE\tinput.nsi\t/^!define PRODUCT_WEB_SITE \"https:\\/\\/www.geany.org\\/\"$/;\"\td\nPRODUCT_DIR_REGKEY\tinput.nsi\t/^!define PRODUCT_DIR_REGKEY \"Software\\\\Geany\"$/;\"\td\nPRODUCT_UNINST_KEY\tinput.nsi\t/^!define PRODUCT_UNINST_KEY \"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall\\\\${PRODUCT_N/;\"\td\nPRODUCT_EXE\tinput.nsi\t/^!define PRODUCT_EXE \"$INSTDIR\\\\bin\\\\Geany.exe\"$/;\"\td\nPRODUCT_REGNAME\tinput.nsi\t/^!define PRODUCT_REGNAME \"Geany.ProjectFile\"$/;\"\td\nPRODUCT_EXT\tinput.nsi\t/^!define PRODUCT_EXT \".geany\"$/;\"\td\nRESOURCEDIR\tinput.nsi\t/^!define RESOURCEDIR \"geany-${PRODUCT_VERSION}\"$/;\"\td\nGTK_VERSION\tinput.nsi\t/^!define GTK_VERSION 2.24.30$/;\"\td\nAnswer\tinput.nsi\t/^Var Answer$/;\"\tv\nUserName\tinput.nsi\t/^Var UserName$/;\"\tv\nStartmenuFolder\tinput.nsi\t/^Var StartmenuFolder$/;\"\tv\nUNINSTDIR\tinput.nsi\t/^Var UNINSTDIR$/;\"\tv\nMUI_ABORTWARNING\tinput.nsi\t/^!define MUI_ABORTWARNING$/;\"\td\nMUI_ICON\tinput.nsi\t/^!define MUI_ICON \"icons\\\\geany.ico\"$/;\"\td\nMUI_UNICON\tinput.nsi\t/^!define MUI_UNICON \"${NSISDIR}\\\\Contrib\\\\Graphics\\\\Icons\\\\modern-uninstall-full.ico\"$/;\"\td\nMUI_PAGE_CUSTOMFUNCTION_LEAVE\tinput.nsi\t/^!define MUI_PAGE_CUSTOMFUNCTION_LEAVE OnDirLeave$/;\"\td\nMUI_STARTMENUPAGE_DEFAULTFOLDER\tinput.nsi\t/^!define MUI_STARTMENUPAGE_DEFAULTFOLDER \"Geany\"$/;\"\td\nMUI_STARTMENUPAGE_REGISTRY_ROOT\tinput.nsi\t/^!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM$/;\"\td\nMUI_STARTMENUPAGE_REGISTRY_KEY\tinput.nsi\t/^!define MUI_STARTMENUPAGE_REGISTRY_KEY \"${PRODUCT_UNINST_KEY}\"$/;\"\td\nMUI_STARTMENUPAGE_REGISTRY_VALUENAME\tinput.nsi\t/^!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME \"Start Menu Folder\"$/;\"\td\nMUI_FINISHPAGE_SHOWREADME\tinput.nsi\t/^!define MUI_FINISHPAGE_SHOWREADME \"$INSTDIR\\\\News.txt\"$/;\"\td\nMUI_FINISHPAGE_SHOWREADME_TEXT\tinput.nsi\t/^!define MUI_FINISHPAGE_SHOWREADME_TEXT \"Show Release Notes\"$/;\"\td\nMUI_FINISHPAGE_SHOWREADME_NOTCHECKED\tinput.nsi\t/^!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED$/;\"\td\nMUI_FINISHPAGE_RUN\tinput.nsi\t/^!define MUI_FINISHPAGE_RUN \"$INSTDIR\\\\bin\\\\Geany.exe\"$/;\"\td\nMUI_FINISHPAGE_RUN_NOTCHECKED\tinput.nsi\t/^!define MUI_FINISHPAGE_RUN_NOTCHECKED$/;\"\td\n\\x21Program Files\tinput.nsi\t/^Section \"!Program Files\" SEC01$/;\"\ts\nSEC01\tinput.nsi\t/^Section \"!Program Files\" SEC01$/;\"\td\nPlugins\tinput.nsi\t/^Section \"Plugins\" SEC02$/;\"\ts\nSEC02\tinput.nsi\t/^Section \"Plugins\" SEC02$/;\"\td\nLanguage Files\tinput.nsi\t/^Section \"Language Files\" SEC03$/;\"\ts\nSEC03\tinput.nsi\t/^Section \"Language Files\" SEC03$/;\"\td\nDocumentation\tinput.nsi\t/^Section \"Documentation\" SEC04$/;\"\ts\nSEC04\tinput.nsi\t/^Section \"Documentation\" SEC04$/;\"\td\nAutocompletion Tags\tinput.nsi\t/^Section \"Autocompletion Tags\" SEC05$/;\"\ts\nSEC05\tinput.nsi\t/^Section \"Autocompletion Tags\" SEC05$/;\"\td\nGTK ${GTK_VERSION} Runtime Environment\tinput.nsi\t/^Section \"GTK ${GTK_VERSION} Runtime Environment\" SEC06$/;\"\ts\nSEC06\tinput.nsi\t/^Section \"GTK ${GTK_VERSION} Runtime Environment\" SEC06$/;\"\td\nContext Menus\tinput.nsi\t/^Section \"Context Menus\" SEC07$/;\"\ts\nSEC07\tinput.nsi\t/^Section \"Context Menus\" SEC07$/;\"\td\nDesktop Shortcuts\tinput.nsi\t/^Section \"Desktop Shortcuts\" SEC08$/;\"\ts\nSEC08\tinput.nsi\t/^Section \"Desktop Shortcuts\" SEC08$/;\"\td\nDevelopment files\tinput.nsi\t/^Section \"Development files\" SEC09$/;\"\ts\nSEC09\tinput.nsi\t/^Section \"Development files\" SEC09$/;\"\td\n-AdditionalIcons\tinput.nsi\t/^Section -AdditionalIcons$/;\"\ts\n-Post\tinput.nsi\t/^Section -Post$/;\"\ts\nUninstall\tinput.nsi\t/^Section Uninstall$/;\"\ts\nIsUserAdmin\tinput.nsi\t/^!macro IsUserAdmin Result UName$/;\"\tm\nResult\tinput.nsi\t/^!macro IsUserAdmin Result UName$/;\"\tp\tmacro:IsUserAdmin\nUName\tinput.nsi\t/^!macro IsUserAdmin Result UName$/;\"\tp\tmacro:IsUserAdmin\n.onInit\tinput.nsi\t/^Function .onInit$/;\"\tf\nun.onUninstSuccess\tinput.nsi\t/^Function un.onUninstSuccess$/;\"\tf\nun.onInit\tinput.nsi\t/^Function un.onInit$/;\"\tf\nOnDirLeave\tinput.nsi\t/^Function OnDirLeave$/;\"\tf\n"
  },
  {
    "path": "Units/parser-nsis.r/simple-nsis.d/input.nsi",
    "content": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n; geany.nsi - this file is part of Geany, a fast and lightweight IDE\n;\n; Copyright 2007-2012 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>\n; Copyright 2007-2012 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>\n;\n; This program is free software; you can redistribute it and/or modify\n; it under the terms of the GNU General Public License as published by\n; the Free Software Foundation; either version 2 of the License, or\n; (at your option) any later version.\n;\n; This program is distributed in the hope that it will be useful,\n; but WITHOUT ANY WARRANTY; without even the implied warranty of\n; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n; GNU General Public License for more details.\n;\n; You should have received a copy of the GNU General Public License\n; along with this program; if not, write to the Free Software\n; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n;\n;\n; Installer script for Geany (Windows Installer)\n; (Script originally generated by the HM NIS Edit Script Wizard)\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n\n; Do a Cyclic Redundancy Check to make sure the installer was not corrupted by the download\nCRCCheck force\nRequestExecutionLevel highest ; set execution level for Windows Vista\n\n;;;;;;;;;;;;;;;;;;;\n; helper defines  ;\n;;;;;;;;;;;;;;;;;;;\n!define PRODUCT_NAME \"Geany\"\n!define PRODUCT_VERSION \"1.35\"\n!define PRODUCT_VERSION_ID \"1.35.0.0\"\n!define PRODUCT_PUBLISHER \"The Geany developer team\"\n!define PRODUCT_WEB_SITE \"https://www.geany.org/\"\n!define PRODUCT_DIR_REGKEY \"Software\\Geany\"\n!define PRODUCT_UNINST_KEY \"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${PRODUCT_NAME}\"\n!define PRODUCT_EXE \"$INSTDIR\\bin\\Geany.exe\"\n!define PRODUCT_REGNAME \"Geany.ProjectFile\"\n!define PRODUCT_EXT \".geany\"\n!define RESOURCEDIR \"geany-${PRODUCT_VERSION}\"\n!define GTK_VERSION 2.24.30\n\n;;;;;;;;;;;;;;;;;;;;;\n; Version resource  ;\n;;;;;;;;;;;;;;;;;;;;;\nVIProductVersion \"${PRODUCT_VERSION_ID}\"\nVIAddVersionKey \"ProductName\" \"${PRODUCT_NAME}\"\nVIAddVersionKey \"FileVersion\" \"${PRODUCT_VERSION}\"\nVIAddVersionKey \"ProductVersion\" \"${PRODUCT_VERSION}\"\nVIAddVersionKey \"LegalCopyright\" \"Copyright 2005-2018 by the Geany developer team\"\nVIAddVersionKey \"FileDescription\" \"${PRODUCT_NAME} Installer\"\n\nBrandingText \"$(^NAME) installer (NSIS 2.51)\"\nInstallDir \"$PROGRAMFILES\\Geany\"\nName \"${PRODUCT_NAME} ${PRODUCT_VERSION}\"\nSetCompressor /SOLID lzma\nShowInstDetails hide\nShowUnInstDetails hide\nXPStyle on\n!ifdef INCLUDE_GTK\nOutFile \"geany-${PRODUCT_VERSION}_setup.exe\"\n!else\nOutFile \"geany-${PRODUCT_VERSION}_nogtk_setup.exe\"\n!endif\n\nVar Answer\nVar UserName\nVar StartmenuFolder\nVar UNINSTDIR\n\n;;;;;;;;;;;;;;;;\n; MUI Settings ;\n;;;;;;;;;;;;;;;;\n!include \"MUI2.nsh\"\n\n;Reserve files used in .onInit, for faster start-up\nReserveFile \"${NSISDIR}\\Plugins\\System.dll\"\nReserveFile \"${NSISDIR}\\Plugins\\UserInfo.dll\"\nReserveFile \"${NSISDIR}\\Plugins\\InstallOptions.dll\"\nReserveFile \"${NSISDIR}\\Plugins\\LangDLL.dll\"\n\n!define MUI_ABORTWARNING\n!define MUI_ICON \"icons\\geany.ico\"\n!define MUI_UNICON \"${NSISDIR}\\Contrib\\Graphics\\Icons\\modern-uninstall-full.ico\"\n\n; Welcome page\n!insertmacro MUI_PAGE_WELCOME\n; License page\n;!define MUI_LICENSEPAGE_RADIOBUTTONS\n!insertmacro MUI_PAGE_LICENSE \"${RESOURCEDIR}\\Copying.txt\"\n; Components page\n!insertmacro MUI_PAGE_COMPONENTS\n; Directory page\n!define MUI_PAGE_CUSTOMFUNCTION_LEAVE OnDirLeave\n!insertmacro MUI_PAGE_DIRECTORY\n; Start menu page\n!define MUI_STARTMENUPAGE_DEFAULTFOLDER \"Geany\"\n!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM\n!define MUI_STARTMENUPAGE_REGISTRY_KEY \"${PRODUCT_UNINST_KEY}\"\n!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME \"Start Menu Folder\"\n!insertmacro MUI_PAGE_STARTMENU ${PRODUCT_NAME} \"$StartmenuFolder\"\n; Instfiles page\n!insertmacro MUI_PAGE_INSTFILES\n; Finish page\n!define MUI_FINISHPAGE_SHOWREADME \"$INSTDIR\\News.txt\"\n!define MUI_FINISHPAGE_SHOWREADME_TEXT \"Show Release Notes\"\n!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED\n!define MUI_FINISHPAGE_RUN \"$INSTDIR\\bin\\Geany.exe\"\n!define MUI_FINISHPAGE_RUN_NOTCHECKED\n!insertmacro MUI_PAGE_FINISH\n\n!insertmacro MUI_UNPAGE_INSTFILES ; Uninstaller page\n!insertmacro MUI_LANGUAGE \"English\" ; Language file\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;\n; Sections and InstTypes  ;\n;;;;;;;;;;;;;;;;;;;;;;;;;;;\nInstType \"Full\"\nInstType \"Minimal\"\n\nSection \"!Program Files\" SEC01\n\tSectionIn RO 1 2\n\tSetOverwrite ifnewer\n\n\tSetOutPath \"$INSTDIR\"\n\tFile \"${RESOURCEDIR}\\*.txt\"\n\n\tSetOutPath \"$INSTDIR\\bin\"\n\tFile \"${RESOURCEDIR}\\bin\\Geany.exe\"\n\tFile \"${RESOURCEDIR}\\bin\\*Geany*.dll\"\n\t# non-GTK dependencies\n\tFile \"gtk\\bin\\libgcc_s_dw*.dll\"\n\tFile \"gtk\\bin\\libstdc++-*.dll\"\n\tFile \"gtk\\bin\\libwinpthread*.dll\"\n\n\tSetOutPath \"$INSTDIR\\libexec\"\n\tFile /r \"${RESOURCEDIR}\\libexec\\*\"\n\n\tSetOutPath \"$INSTDIR\\data\"\n\tFile \"${RESOURCEDIR}\\data\\GPL-2\"\n\tFile \"${RESOURCEDIR}\\data\\filetype_extensions.conf\"\n\tFile \"${RESOURCEDIR}\\data\\geany.glade\"\n!if ${GTK_VERSION} >= 3\n\tFile \"${RESOURCEDIR}\\data\\geany-3.20.css\"\n\tFile \"${RESOURCEDIR}\\data\\geany.css\"\n!else\n\tFile \"${RESOURCEDIR}\\data\\geany.gtkrc\"\n!endif\n\tFile \"${RESOURCEDIR}\\data\\snippets.conf\"\n\tFile \"${RESOURCEDIR}\\data\\ui_toolbar.xml\"\n\n\tSetOutPath \"$INSTDIR\\data\\filedefs\"\n\tFile /r \"${RESOURCEDIR}\\data\\filedefs\\*\"\n\n\tSetOutPath \"$INSTDIR\\data\\templates\"\n\tFile /r \"${RESOURCEDIR}\\data\\templates\\*\"\n\n\tSetOutPath \"$INSTDIR\\data\\colorschemes\"\n\tFile /r \"${RESOURCEDIR}\\data\\colorschemes\\*\"\n\t# Geany color schemes project, don't bail out if they are missing\n\tFile /nonfatal /r \"..\\geany-themes\\colorschemes\\*.conf\"\n\n\tSetOutPath \"$INSTDIR\\share\\icons\"\n\tFile /r \"${RESOURCEDIR}\\share\\icons\\*\"\n\n\tSetOutPath \"$INSTDIR\"\n\n\tCreateShortCut \"$INSTDIR\\Geany.lnk\" \"$INSTDIR\\bin\\Geany.exe\"\n\t!insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME}\n\tCreateDirectory \"$SMPROGRAMS\\$StartmenuFolder\"\n\tCreateShortCut \"$SMPROGRAMS\\$StartmenuFolder\\Geany.lnk\" \"$INSTDIR\\bin\\Geany.exe\"\n\t!insertmacro MUI_STARTMENU_WRITE_END\n\n\t; register the extension .geany\n\t; write information about file type\n\tWriteRegStr SHCTX \"Software\\Classes\\${PRODUCT_REGNAME}\" \"\" \"${PRODUCT_NAME} Project File\"\n\tWriteRegStr SHCTX \"Software\\Classes\\${PRODUCT_REGNAME}\\DefaultIcon\" \"\" \"${PRODUCT_EXE},0\"\n\tWriteRegStr SHCTX \"Software\\Classes\\${PRODUCT_REGNAME}\\Shell\\open\\command\" \"\" '\"${PRODUCT_EXE}\" \"%1\"'\n\t; write information about file extensions\n\tWriteRegStr SHCTX \"Software\\Classes\\${PRODUCT_EXT}\" \"\" \"${PRODUCT_REGNAME}\"\n\t; refresh shell\n\tSystem::Call 'shell32.dll::SHChangeNotify(i, i, i, i) (0x08000000, 0, 0, 0)'\nSectionEnd\n\nSection \"Plugins\" SEC02\n\tSectionIn 1\n\tSetOverwrite ifnewer\n\tSetOutPath \"$INSTDIR\\lib\\geany\"\n\tFile \"${RESOURCEDIR}\\lib\\geany\\*.dll\"\nSectionEnd\n\nSection \"Language Files\" SEC03\n\tSectionIn 1\n\tSetOutPath \"$INSTDIR\\share\\locale\"\n\tFile /r \"${RESOURCEDIR}\\share\\locale\\*\"\n!ifdef INCLUDE_GTK\n\tSetOutPath \"$INSTDIR\\share\\locale\"\n\tFile /r \"gtk\\share\\locale\\*\"\n!endif\nSectionEnd\n\nSection \"Documentation\" SEC04\n\tSectionIn 1\n\tSetOverwrite ifnewer\n\tSetOutPath \"$INSTDIR\\share\\doc\"\n\tFile /r \"${RESOURCEDIR}\\share\\doc\\*\"\n\tWriteIniStr \"$INSTDIR\\Documentation.url\" \"InternetShortcut\" \"URL\" \"$INSTDIR\\share\\doc\\geany\\html\\index.html\"\n\t!insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME}\n\tCreateShortCut \"$SMPROGRAMS\\$StartmenuFolder\\Documentation.lnk\" \"$INSTDIR\\Documentation.url\"\n\t!insertmacro MUI_STARTMENU_WRITE_END\nSectionEnd\n\nSection \"Autocompletion Tags\" SEC05\n\tSectionIn 1\n\tSetOverwrite ifnewer\n\tSetOutPath \"$INSTDIR\\data\\tags\"\n\tFile /r \"${RESOURCEDIR}\\data\\tags\\*\"\nSectionEnd\n\n; Include GTK runtime library but only if desired from command line\n!ifdef INCLUDE_GTK\nSection \"GTK ${GTK_VERSION} Runtime Environment\" SEC06\n\tSectionIn 1\n\tSetOverwrite ifnewer\n\tSetOutPath \"$INSTDIR\"\n\tFile \"gtk\\ReadMe.Dependencies.Geany.txt\"\n\tSetOutPath \"$INSTDIR\\bin\"\n\tFile /r \"gtk\\bin\\*\"\n\tSetOutPath \"$INSTDIR\\etc\"\n\tFile /r \"gtk\\etc\\*\"\n\tSetOutPath \"$INSTDIR\\lib\"\n\tFile /r \"gtk\\lib\\*\"\n\tSetOutPath \"$INSTDIR\\share\"\n\tFile /r \"gtk\\share\\*\"\nSectionEnd\n!endif\n\nSection \"Context Menus\" SEC07\n\tSectionIn 1\n\tWriteRegStr HKCR \"*\\shell\\OpenWithGeany\" \"\" \"Open with Geany\"\n\tWriteRegStr HKCR \"*\\shell\\OpenWithGeany\" \"Icon\" \"$INSTDIR\\bin\\geany.exe\"\n\tWriteRegStr HKCR \"*\\shell\\OpenWithGeany\\command\" \"\" '\"$INSTDIR\\bin\\geany.exe\" \"%1\"'\nSectionEnd\n\nSection \"Desktop Shortcuts\" SEC08\n\tSectionIn 1\n\tCreateShortCut \"$DESKTOP\\Geany.lnk\" \"$INSTDIR\\bin\\Geany.exe\"\n\tCreateShortCut \"$QUICKLAUNCH\\Geany.lnk\" \"$INSTDIR\\bin\\Geany.exe\"\nSectionEnd\n\n; Development files\nSection \"Development files\" SEC09\n\tSetOverwrite ifnewer\n\tSetOutPath \"$INSTDIR\\include\"\n\tFile /r \"${RESOURCEDIR}\\include\\*\"\n\n\tSetOutPath \"$INSTDIR\\lib\\pkgconfig\"\n\tFile \"${RESOURCEDIR}\\lib\\pkgconfig\\geany.pc\"\nSectionEnd\n\nSection -AdditionalIcons\n\tSetOutPath $INSTDIR\n\t!insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT_NAME}\n\tWriteIniStr \"$INSTDIR\\Website.url\" \"InternetShortcut\" \"URL\" \"${PRODUCT_WEB_SITE}\"\n\tCreateShortCut \"$SMPROGRAMS\\$StartmenuFolder\\Website.lnk\" \"$INSTDIR\\Website.url\"\n\tCreateShortCut \"$SMPROGRAMS\\$StartmenuFolder\\Uninstall.lnk\" \"$INSTDIR\\uninst.exe\"\n\t!insertmacro MUI_STARTMENU_WRITE_END\nSectionEnd\n\nSection -Post\n\tWriteUninstaller \"$INSTDIR\\uninst.exe\"\n\tWriteRegStr SHCTX \"${PRODUCT_DIR_REGKEY}\" Path \"$INSTDIR\"\n\tWriteRegStr SHCTX \"${PRODUCT_UNINST_KEY}\" \"StartMenu\" \"$SMPROGRAMS\\$StartmenuFolder\"\n\t${if} $Answer == \"yes\" ; if user is admin\n\t\tWriteRegStr SHCTX \"${PRODUCT_UNINST_KEY}\" \"DisplayName\" \"$(^Name)\"\n\t\tWriteRegStr SHCTX \"${PRODUCT_UNINST_KEY}\" \"UninstallString\" \"$INSTDIR\\uninst.exe\"\n\t\tWriteRegStr SHCTX \"${PRODUCT_UNINST_KEY}\" \"DisplayIcon\" \"$INSTDIR\\bin\\Geany.exe\"\n\t\tWriteRegStr SHCTX \"${PRODUCT_UNINST_KEY}\" \"DisplayVersion\" \"${PRODUCT_VERSION}\"\n\t\tWriteRegStr SHCTX \"${PRODUCT_UNINST_KEY}\" \"URLInfoAbout\" \"${PRODUCT_WEB_SITE}\"\n\t\tWriteRegStr SHCTX \"${PRODUCT_UNINST_KEY}\" \"URLUpdateInfo\" \"${PRODUCT_WEB_SITE}\"\n\t\tWriteRegStr SHCTX \"${PRODUCT_UNINST_KEY}\" \"Publisher\" \"${PRODUCT_PUBLISHER}\"\n\t\tWriteRegDWORD SHCTX \"${PRODUCT_UNINST_KEY}\" \"NoModify\" 0x00000001\n\t\tWriteRegDWORD SHCTX \"${PRODUCT_UNINST_KEY}\" \"NoRepair\" 0x00000001\n\t${endif}\nSectionEnd\n\nSection Uninstall\n\tDelete \"$INSTDIR\\Website.url\"\n\tDelete \"$INSTDIR\\Documentation.url\"\n\tDelete \"$INSTDIR\\uninst.exe\"\n\tDelete \"$INSTDIR\\News.txt\"\n\tDelete \"$INSTDIR\\ReadMe.txt\"\n\tDelete \"$INSTDIR\\ReadMe.Dependencies.Geany.txt\"\n\tDelete \"$INSTDIR\\Thanks.txt\"\n\tDelete \"$INSTDIR\\ToDo.txt\"\n\tDelete \"$INSTDIR\\Authors.txt\"\n\tDelete \"$INSTDIR\\ChangeLog.txt\"\n\tDelete \"$INSTDIR\\Copying.txt\"\n\tDelete \"$INSTDIR\\Geany.lnk\"\n\n\t; delete start menu entry\n\tReadRegStr $0 SHCTX \"${PRODUCT_UNINST_KEY}\" \"StartMenu\"\n\tRMDir /r \"$0\"\n\n\tDelete \"$QUICKLAUNCH\\Geany.lnk\"\n\tDelete \"$DESKTOP\\Geany.lnk\"\n\n\tRMDir /r \"$INSTDIR\\bin\"\n\tRMDir /r \"$INSTDIR\\data\"\n\tRMDir /r \"$INSTDIR\\etc\"\n\tRMDir /r \"$INSTDIR\\include\"\n\tRMDir /r \"$INSTDIR\\lib\"\n\tRMDir /r \"$INSTDIR\\libexec\"\n\tRMDir /r \"$INSTDIR\\share\"\n\tRMDir \"$INSTDIR\"\n\n\t; remove .geany file extension\n\tReadRegStr $R0 SHCTX \"Software\\Classes\\${PRODUCT_EXT}\" \"\"\n\t${if} $R0 == \"${PRODUCT_REGNAME}\"\n\t\tDeleteRegKey SHCTX \"${PRODUCT_EXT}\"\n\t\tDeleteRegKey HKCR \"${PRODUCT_EXT}\"\n\t\tDeleteRegKey SHCTX \"${PRODUCT_REGNAME}\"\n\t\tDeleteRegKey HKCR \"${PRODUCT_REGNAME}\"\n\t${endif}\n\n\tDeleteRegKey HKCR \"*\\shell\\OpenWithGeany\"\n\n\tDeleteRegKey SHCTX \"${PRODUCT_UNINST_KEY}\"\n\tDeleteRegKey HKCU \"${PRODUCT_UNINST_KEY}\"\n\tDeleteRegKey SHCTX \"${PRODUCT_DIR_REGKEY}\"\n\tDeleteRegKey HKCU \"${PRODUCT_DIR_REGKEY}\"\n\n\tSetAutoClose true\nSectionEnd\n\n;;;;;;;;;;;;;;;;;;;;;;;;;\n; Section descriptions  ;\n;;;;;;;;;;;;;;;;;;;;;;;;;\n!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN\n!insertmacro MUI_DESCRIPTION_TEXT ${SEC01} \"Required program files. You cannot skip these files.\"\n!insertmacro MUI_DESCRIPTION_TEXT ${SEC02} \"Available plugins like 'Version Diff', 'Class Builder' and 'Insert Special Characters'.\"\n!insertmacro MUI_DESCRIPTION_TEXT ${SEC03} \"Various translations of Geany's interface.\"\n!insertmacro MUI_DESCRIPTION_TEXT ${SEC04} \"Manual in Text and HTML format.\"\n!insertmacro MUI_DESCRIPTION_TEXT ${SEC05} \"Symbol lists necessary for auto completion of symbols.\"\n!ifdef INCLUDE_GTK\n!insertmacro MUI_DESCRIPTION_TEXT ${SEC06} \"You need these files to run Geany. If you have already installed a GTK Runtime Environment (${GTK_VERSION} or higher), you can skip it.\"\n!endif\n!insertmacro MUI_DESCRIPTION_TEXT ${SEC07} \"Add context menu item 'Open With Geany'\"\n!insertmacro MUI_DESCRIPTION_TEXT ${SEC08} \"Create shortcuts for Geany on the desktop and in the Quicklaunch Bar\"\n!insertmacro MUI_DESCRIPTION_TEXT ${SEC09} \"You need these files only if you want to develop own plugins for Geany. If unsure, you can skip it.\"\n!insertmacro MUI_FUNCTION_DESCRIPTION_END\n\n;;;;;;;;;;;;;;;;;;;;;\n; helper functions  ;\n;;;;;;;;;;;;;;;;;;;;;\n\n; (from http://jabref.svn.sourceforge.net/viewvc/jabref/trunk/jabref/src/windows/nsis/setup.nsi)\n!macro IsUserAdmin Result UName\n\tClearErrors\n\tUserInfo::GetName\n\tIfErrors Win9x\n\tPop $0\n\tStrCpy ${UName} $0\n\tUserInfo::GetAccountType\n\tPop $1\n\t${if} $1 == \"Admin\"\n\t\tStrCpy ${Result} \"yes\"\n\t${else}\n\t\tStrCpy ${Result} \"no\"\n\t${endif}\n\tGoto done\n\nWin9x:\n\tStrCpy ${Result} \"yes\"\ndone:\n!macroend\n\nFunction .onInit\n\tStrCpy \"$StartmenuFolder\" \"Geany\"\n\n\t; (from http://jabref.svn.sourceforge.net/viewvc/jabref/trunk/jabref/src/windows/nsis/setup.nsi)\n\t; If the user does *not* have administrator privileges, abort\n\tStrCpy $Answer \"\"\n\tStrCpy $UserName \"\"\n\t!insertmacro IsUserAdmin $Answer $UserName ; macro from LyXUtils.nsh\n\t${if} $Answer == \"yes\"\n\t\tSetShellVarContext all ; set that e.g. shortcuts will be created for all users\n\t${else}\n\t\tSetShellVarContext current\n\t\t; TODO is this really what we want? $PROGRAMFILES is not much better because\n\t\t; probably the unprivileged user can't write it anyways\n\t\tStrCpy $INSTDIR \"$PROFILE\\$(^Name)\"\n\t${endif}\n\n\t; prevent running multiple instances of the installer\n\tSystem::Call 'kernel32::CreateMutexA(i 0, i 0, t \"geany_installer\") i .r1 ?e'\n\tPop $R0\n\tStrCmp $R0 0 +3\n\tMessageBox MB_OK|MB_ICONEXCLAMATION \"The installer is already running.\" /SD IDOK\n\tAbort\n\t; warn about a new install over an existing installation\n\tReadRegStr $R0 SHCTX \"${PRODUCT_UNINST_KEY}\" \"UninstallString\"\n\tStrCmp $R0 \"\" finish\n\n\tMessageBox MB_YESNO|MB_ICONEXCLAMATION \\\n\t\"Geany has already been installed. $\\nDo you want to remove the previous version before installing $(^Name) ?\" \\\n\t\t/SD IDYES IDYES remove IDNO finish\n\nremove:\n\t; run the uninstaller\n\tClearErrors\n\t; we read the installation path of the old installation from the Registry\n\tReadRegStr $UNINSTDIR SHCTX \"${PRODUCT_DIR_REGKEY}\" \"Path\"\n\tIfSilent dosilent nonsilent\ndosilent:\n\tExecWait '$R0 /S _?=$UNINSTDIR' ;Do not copy the uninstaller to a temp file\n\tGoto finish\nnonsilent:\n\tExecWait '$R0 _?=$UNINSTDIR' ;Do not copy the uninstaller to a temp file\nfinish:\nFunctionEnd\n\nFunction un.onUninstSuccess\n\tHideWindow\n\tMessageBox MB_ICONINFORMATION|MB_OK \"$(^Name) was successfully removed from your computer.\" \\\n\t\t/SD IDOK\nFunctionEnd\n\nFunction un.onInit\n\t; If the user does *not* have administrator privileges, abort\n\tStrCpy $Answer \"\"\n\t!insertmacro IsUserAdmin $Answer $UserName\n\t${if} $Answer == \"yes\"\n\t\tSetShellVarContext all\n\t${else}\n\t\t; check if the Geany has been installed with admin permisions\n\t\tReadRegStr $0 HKLM \"${PRODUCT_UNINST_KEY}\" \"Publisher\"\n\t\t${if} $0 != \"\"\n\t\t\tMessageBox MB_OK|MB_ICONSTOP \"You need administrator privileges to uninstall Geany!\" \\\n\t\t\t\t/SD IDOK\n\t\t\tAbort\n\t\t${endif}\n\t\tSetShellVarContext current\n\t${endif}\n\n\tMessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \"Are you sure you want to completely remove $(^Name) and all of its components?\" \\\n\t\t/SD IDYES IDYES +2\n\tAbort\nFunctionEnd\n\nFunction OnDirLeave\n\tClearErrors\n\tSetOutPath \"$INSTDIR\" ; what about IfError creating $INSTDIR?\n\tGetTempFileName $1 \"$INSTDIR\" ; creates tmp file (or fails)\n\tFileOpen $0 \"$1\" \"w\" ; error to open?\n\tFileWriteByte $0 \"0\"\n\tIfErrors notPossible possible\n\nnotPossible:\n\tRMDir \"$INSTDIR\" ; removes folder if empty\n\tMessageBox MB_OK \"The given directory is not writeable. Please choose another one!\" /SD IDOK\n\tAbort\npossible:\n\tFileClose $0\n\tDelete \"$1\"\nFunctionEnd\n"
  },
  {
    "path": "Units/parser-nsis.r/various-sections.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-nsis.r/various-sections.d/expected.tags",
    "content": "-hidden section\tinput.nsi\t/^Section \"-hidden section\"$/;\"\ts\n\\x21bold section\tinput.nsi\t/^Section \"!bold section\"$/;\"\ts\noptional\tinput.nsi\t/^Section \\/o \"optional\"$/;\"\ts\ninstall something\tinput.nsi\t/^Section \"install something\" SEC_IDX$/;\"\ts\nSEC_IDX\tinput.nsi\t/^Section \"install something\" SEC_IDX$/;\"\td\nインストール (install in Japanese)\tinput.nsi\t/^Section \"インストール (install in Japanese)\" SEC_J_IDX$/;\"\ts\nSEC_J_IDX\tinput.nsi\t/^Section \"インストール (install in Japanese)\" SEC_J_IDX$/;\"\td\n${SOMETHING0}\tinput.nsi\t/^Section \"${SOMETHING0}\" SEC_S0_IDX$/;\"\ts\nSEC_S0_IDX\tinput.nsi\t/^Section \"${SOMETHING0}\" SEC_S0_IDX$/;\"\td\n$(SOMETHING1)\tinput.nsi\t/^Section \"$(SOMETHING1)\" SEC_S1_IDX$/;\"\ts\nSEC_S1_IDX\tinput.nsi\t/^Section \"$(SOMETHING1)\" SEC_S1_IDX$/;\"\td\nAnonymousSectiondbd5e5d10100\tinput.nsi\t/^Section \"\" EMPTY_IDX$/;\"\ts\nEMPTY_IDX\tinput.nsi\t/^Section \"\" EMPTY_IDX$/;\"\td\na$\\\\\"\tinput.nsi\t/^Section \"a$\\\\\"\" A_Q_IDX$/;\"\ts\nA_Q_IDX\tinput.nsi\t/^Section \"a$\\\\\"\" A_Q_IDX$/;\"\td\nb$\\\\\"c\tinput.nsi\t/^Section \"b$\\\\\"c\" B_Q_C_IDX$/;\"\ts\nB_Q_C_IDX\tinput.nsi\t/^Section \"b$\\\\\"c\" B_Q_C_IDX$/;\"\td\nd$\\\\ne\tinput.nsi\t/^Section \"d$\\\\ne\" D_Q_E_IDX$/;\"\ts\nD_Q_E_IDX\tinput.nsi\t/^Section \"d$\\\\ne\" D_Q_E_IDX$/;\"\td\nSingle Quote\tinput.nsi\t/^Section 'Single Quote'$/;\"\ts\nDouble Quote\tinput.nsi\t/^Section \"Double Quote\"$/;\"\ts\nBack Quote\tinput.nsi\t/^Section `Back Quote`$/;\"\ts\n"
  },
  {
    "path": "Units/parser-nsis.r/various-sections.d/input.nsi",
    "content": "# Taken from https://nsis.sourceforge.io/Reference/Section\nSection \"-hidden section\"\nSectionEnd\n\nSection # hidden section\nSectionEnd\n\nSection \"!bold section\"\nSectionEnd\n\nSection /o \"optional\"\nSectionEnd\n\nSection \"install something\" SEC_IDX\nSectionEnd\n\nSection \"インストール (install in Japanese)\" SEC_J_IDX\nSectionEnd\n\nSection \"${SOMETHING0}\" SEC_S0_IDX\nSectionEnd\n\nSection \"$(SOMETHING1)\" SEC_S1_IDX\nSectionEnd\n\nSection \"\" EMPTY_IDX\nSectionEnd\n\nSection \"a$\\\"\" A_Q_IDX\nSectionEnd\n\nSection \"b$\\\"c\" B_Q_C_IDX\nSectionEnd\n\nSection \"d$\\ne\" D_Q_E_IDX\nSectionEnd\n\nSection 'Single Quote'\nSectionEnd\n\nSection \"Double Quote\"\nSectionEnd\n\nSection `Back Quote`\nSectionEnd\n"
  },
  {
    "path": "Units/parser-objectivec.r/crash-in-parsing-protocol.d/args.ctags",
    "content": "--languages=ObjectiveC\n--fields=+i\n"
  },
  {
    "path": "Units/parser-objectivec.r/crash-in-parsing-protocol.d/expected.tags",
    "content": "NSFileAccessIntent\tinput.h\t/^@interface NSFileAccessIntent : NSObject$/;\"\ti\tinherits:NSObject\nNSFileCoordinator\tinput.h\t/^@interface NSFileCoordinator : NSObject$/;\"\ti\tinherits:NSObject\nNSFilePresenter\tinput-0.h\t/^@protocol NSFilePresenter <NSObject>$/;\"\tP\tprotocols:NSObject\n__NSFileCoordinator_h_GNUSTEP_BASE_INCLUDE\tinput-0.h\t/^#define __NSFileCoordinator_h_GNUSTEP_BASE_INCLUDE$/;\"\tM\n__NSFileCoordinator_h_GNUSTEP_BASE_INCLUDE\tinput.h\t/^#define __NSFileCoordinator_h_GNUSTEP_BASE_INCLUDE$/;\"\tM\n"
  },
  {
    "path": "Units/parser-objectivec.r/crash-in-parsing-protocol.d/input-0.h",
    "content": "// Input files are Taken from https://github.com/gnustep/libs-base.git\n#ifndef __NSFileCoordinator_h_GNUSTEP_BASE_INCLUDE\n#define __NSFileCoordinator_h_GNUSTEP_BASE_INCLUDE\n\n#import <Foundation/NSObject.h>\n\n#if OS_API_VERSION(MAC_OS_X_VERSION_10_7,GS_API_LATEST)\n@protocol NSFilePresenter <NSObject>\n@end\n\n#endif\n#endif\n"
  },
  {
    "path": "Units/parser-objectivec.r/crash-in-parsing-protocol.d/input.h",
    "content": "// Input files are Taken from https://github.com/gnustep/libs-base.git\n#ifndef __NSFileCoordinator_h_GNUSTEP_BASE_INCLUDE\n#define __NSFileCoordinator_h_GNUSTEP_BASE_INCLUDE\n\n#import <Foundation/NSObject.h>\n\n#if OS_API_VERSION(MAC_OS_X_VERSION_10_7,GS_API_LATEST)\n\n@interface NSFileAccessIntent : NSObject\n@end\n\n@interface NSFileCoordinator : NSObject\n@end\n\n#endif\n#endif\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc-extern-c.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc-extern-c.d/expected.tags",
    "content": "__NSCompoundPredicate_h_GNUSTEP_BASE_INCLUDE\tinput.h\t/^#define __NSCompoundPredicate_h_GNUSTEP_BASE_INCLUDE$/;\"\tM\nNSCompoundPredicateType\tinput.h\t/^typedef NSUInteger NSCompoundPredicateType;$/;\"\tt\nNSCompoundPredicate\tinput.h\t/^@interface NSCompoundPredicate : NSPredicate$/;\"\ti\n_subs\tinput.h\t/^  NSArray\t*_subs;$/;\"\tE\tinterface:NSCompoundPredicate\nandPredicateWithSubpredicates:\tinput.h\t/^+ (NSPredicate *) andPredicateWithSubpredicates: (NSArray *)list;$/;\"\tc\tinterface:NSCompoundPredicate\nnotPredicateWithSubpredicate:\tinput.h\t/^+ (NSPredicate *) notPredicateWithSubpredicate: (NSPredicate *)predicate;$/;\"\tc\tinterface:NSCompoundPredicate\norPredicateWithSubpredicates:\tinput.h\t/^+ (NSPredicate *) orPredicateWithSubpredicates: (NSArray *)list;$/;\"\tc\tinterface:NSCompoundPredicate\nsubpredicates\tinput.h\t/^- (NSArray *) subpredicates;$/;\"\tm\tinterface:NSCompoundPredicate\nfoo\tinput-0.m\t/^extern int foo (void)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc-extern-c.d/input-0.m",
    "content": "// -*- mode: objc -*-\n\n/* Verify code handling\n *\n * \textern \"C\" { ...\n *\n * doesn't break the other area of objectivec parser.\n */\n\nextern int foo (void)\n{\n  return 0;\n}\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc-extern-c.d/input.h",
    "content": "/* Interface for NSCompoundPredicate for GNUStep\n   Copyright (C) 2005 Free Software Foundation, Inc.\n\n   Written by:  Dr. H. Nikolaus Schaller\n   Created: 2005\n\n   This file is part of the GNUstep Base Library.\n\n   This library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2 of the License, or (at your option) any later version.\n\n   This library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Library General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with this library; if not, write to the Free\n   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n   Boston, MA 02111 USA.\n   */\n\n#ifndef __NSCompoundPredicate_h_GNUSTEP_BASE_INCLUDE\n#define __NSCompoundPredicate_h_GNUSTEP_BASE_INCLUDE\n#import\t<GNUstepBase/GSVersionMacros.h>\n\n#if\tOS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)\n\n#import\t<Foundation/NSPredicate.h>\n\n#if\tdefined(__cplusplus)\nextern \"C\" {\n#endif\n\ntypedef NSUInteger NSCompoundPredicateType;\n\n@interface NSCompoundPredicate : NSPredicate\n{\n#if\tGS_EXPOSE(NSCompoundPredicate)\n  NSArray\t*_subs;\n#endif\n}\n\n+ (NSPredicate *) andPredicateWithSubpredicates: (NSArray *)list;\n+ (NSPredicate *) notPredicateWithSubpredicate: (NSPredicate *)predicate;\n+ (NSPredicate *) orPredicateWithSubpredicates: (NSArray *)list;\n\n- (NSArray *) subpredicates;\n\n@end\n\n#if\tdefined(__cplusplus)\n}\n#endif\n\n#endif\t/* 100400 */\n#endif\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc-signature.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc-signature.d/expected.tags",
    "content": "X\tinput.m\t/^@interface X: NSObject$/;\"\ti\ndoNothing\tinput.m\t/^- doNothing;$/;\"\tm\tinterface:X\tsignature:()\ndoVoidReturn\tinput.m\t/^- (void)doVoidReturn;$/;\"\tm\tinterface:X\tsignature:()\ndoVoidPtrReturn\tinput.m\t/^- (void*)doVoidPtrReturn;$/;\"\tm\tinterface:X\tsignature:()\ndoNothing:\tinput.m\t/^- doNothing: idarg;$/;\"\tm\tinterface:X\tsignature:(id)\ndoNothing:\tinput.m\t/^- doNothing:(id) idargExplicit;$/;\"\tm\tinterface:X\tsignature:(id)\ndoNothing:with:\tinput.m\t/^- doNothing: idarg1 with: idarg2;$/;\"\tm\tinterface:X\tsignature:(id,id)\ndoNothing:with:\tinput.m\t/^- doNothing: idarg1 with: (id) idarg2Explicit;$/;\"\tm\tinterface:X\tsignature:(id,id)\ndoNothing:and:\tinput.m\t/^- doNothing: idarg1 and: (id*) idarg2PtrExplicit;$/;\"\tm\tinterface:X\tsignature:(id,id*)\ndoVoidReturn:with:\tinput.m\t/^- (void)doVoidReturn: idarg1 with: idarg2;$/;\"\tm\tinterface:X\tsignature:(id,id)\ndoVoidReturn:withId:\tinput.m\t/^- (void)doVoidReturn: idarg1 withId: (id) idarg2Explicit;$/;\"\tm\tinterface:X\tsignature:(id,id)\ndoVoidReturn:and:\tinput.m\t/^- (void)doVoidReturn: idarg1 and: (id*) idarg2PtrExplicit;$/;\"\tm\tinterface:X\tsignature:(id,id*)\ndoVoidPtr:with:\tinput.m\t/^- (void*)doVoidPtr: idarg1 with: idarg2;$/;\"\tm\tinterface:X\tsignature:(id,id)\ndoVoidPtr:and:\tinput.m\t/^- (void*)doVoidPtr: idarg1 and: (id) idarg2Explicit;$/;\"\tm\tinterface:X\tsignature:(id,id)\ndoVoidPtr:andWith:\tinput.m\t/^- (void*)doVoidPtr: idarg1 andWith: (id**) idarg2PtrExplicit;$/;\"\tm\tinterface:X\tsignature:(id,id**)\ndoVoidPtr:andWithStruct:\tinput.m\t/^- (void*)doVoidPtr: idarg1 andWithStruct: (struct foo *) idarg2PtrExplicit;$/;\"\tm\tinterface:X\tsignature:(id,struct foo*)\ndoVoidUInt:andWithStruct:\tinput.m\t/^- (void*)doVoidUInt: (unsigned int) idarg1 andWithStruct: (struct foo *) idarg2PtrExplicit;$/;\"\tm\tinterface:X\tsignature:(unsigned int,struct foo*)\nX\tinput.m\t/^@implementation X$/;\"\tI\ndoNothing\tinput.m\t/^- doNothing$/;\"\tm\timplementation:X\tsignature:()\ndoNothing:\tinput.m\t/^- doNothing: idarg$/;\"\tm\timplementation:X\tsignature:(id)\ndoVoidUInt:andWithStruct:\tinput.m\t/^- (void*)doVoidUInt: (unsigned int) idarg1 andWithStruct: (struct foo *) idarg2PtrExplicit$/;\"\tm\timplementation:X\tsignature:(unsigned int,struct foo*)\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc-signature.d/input.m",
    "content": "@interface X: NSObject\n- doNothing;\n- (void)doVoidReturn;\n- (void*)doVoidPtrReturn;\n- doNothing: idarg;\n- doNothing:(id) idargExplicit;\n- doNothing: idarg1 with: idarg2;\n- doNothing: idarg1 with: (id) idarg2Explicit;\n- doNothing: idarg1 and: (id*) idarg2PtrExplicit;\n- (void)doVoidReturn: idarg1 with: idarg2;\n- (void)doVoidReturn: idarg1 withId: (id) idarg2Explicit;\n- (void)doVoidReturn: idarg1 and: (id*) idarg2PtrExplicit;\n- (void*)doVoidPtr: idarg1 with: idarg2;\n- (void*)doVoidPtr: idarg1 and: (id) idarg2Explicit;\n- (void*)doVoidPtr: idarg1 andWith: (id**) idarg2PtrExplicit;\n- (void*)doVoidPtr: idarg1 andWithStruct: (struct foo *) idarg2PtrExplicit;\n- (void*)doVoidUInt: (unsigned int) idarg1 andWithStruct: (struct foo *) idarg2PtrExplicit;\n@end\n\n@implementation X\n- doNothing\n{\n  return nil;\n}\n- doNothing: idarg\n{\n  return nil;\n}\n- (void*)doVoidUInt: (unsigned int) idarg1 andWithStruct: (struct foo *) idarg2PtrExplicit\n{\n  return NULL;\n}\n@end\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc.m.d/expected.tags",
    "content": "MyClass\tinput.m\t/^@implementation MyClass$/;\"\tI\nmyClassMethod:with:\tinput.m\t/^+ (void)myClassMethod:(int)arg1 with:(id)arg2;$/;\"\tc\timplementation:MyClass\nmyInstanceMethod:with:\tinput.m\t/^- (void)myInstanceMethod:(int)arg1 with:(id)arg2;$/;\"\tm\timplementation:MyClass\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc.m.d/input.m",
    "content": "@implementation MyClass\n\n+ (void)myClassMethod:(int)arg1 with:(id)arg2;\n- (void)myInstanceMethod:(int)arg1 with:(id)arg2;\n\n@end\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc_underscore.d/expected.tags",
    "content": "Grumble\tinput.mm\t/^int Foo::Grumble(void)$/;\"\tf\nMyOtherFunction\tinput.mm\t/^void MyOtherFunction(void)$/;\"\tf\n_Mumble\tinput.mm\t/^int\tFoo::_Mumble(void)$/;\"\tf\n_MyFunction\tinput.mm\t/^void _MyFunction(void)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-objectivec.r/objc_underscore.d/input.mm",
    "content": "static\nvoid _MyFunction(void)\n{\n\n}\n\nstatic\nvoid MyOtherFunction(void)\n{\n\n}\n\nclass Foo\n{\n\tint _Mumble(void);\n\tint Grumble(void);\n};\n\nint\tFoo::_Mumble(void)\n{\n\t_MyFunction();\n\treturn 0;\n}\n\nint Foo::Grumble(void)\n{\n\tMyOtherFunction();\n\treturn 0;\n}\n"
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_implementation.m.d/args.ctags",
    "content": "--fields-ObjectiveC=+{category}\n"
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_implementation.m.d/expected.tags",
    "content": "Extension\tinput.m\t/^@implementation NSString (Extension)$/;\"\tC\timplementation:NSString\nFileTree\tinput.m\t/^@implementation FileTree$/;\"\tI\nFolderTree\tinput.m\t/^@implementation FolderTree$/;\"\tI\nNSString\tinput.m\t/^@implementation NSString (Extension)$/;\"\tI\tcategory:Extension\naddChild:\tinput.m\t/^- (FolderTree*)addChild:(FileTree*)subTree$/;\"\tm\timplementation:FolderTree\ncreateFileList:atPlace:\tinput.m\t/^+ (void) createFileList: (NSString*)root atPlace:(FolderTree*)parentFolder$/;\"\tc\timplementation:FolderTree\ncreateLayoutTree\tinput.m\t/^- (LayoutTree*)createLayoutTree$/;\"\tm\timplementation:FileTree\ncreateLayoutTree\tinput.m\t/^- (LayoutTree*)createLayoutTree$/;\"\tm\timplementation:FolderTree\ndealloc\tinput.m\t/^- (void)dealloc$/;\"\tm\timplementation:FileTree\ndealloc\tinput.m\t/^- (void)dealloc$/;\"\tm\timplementation:FolderTree\ndoSomething\tinput.m\t/^- (void)doSomething$/;\"\tm\timplementation:NSString\tcategory:Extension\ngetDiskSize\tinput.m\t/^- (FileSize)getDiskSize$/;\"\tm\timplementation:FileTree\ninitWithName:andSize:atPlace:\tinput.m\t/^- (id)initWithName:(NSString*)treeName$/;\"\tm\timplementation:FileTree\ninitWithName:atPlace:\tinput.m\t/^- (id)initWithName:(NSString*)treeName$/;\"\tm\timplementation:FileTree\ninitWithName:atPlace:\tinput.m\t/^- (id)initWithName:(NSString*)treeName$/;\"\tm\timplementation:FolderTree\npopulateChildList:\tinput.m\t/^- (void) populateChildList:(NSString*)root$/;\"\tm\timplementation:FolderTree\n"
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_implementation.m.d/input.m",
    "content": "\n@implementation FileTree\n- (FileSize)getDiskSize\n{\n    return diskSize;\n}\n\n- (id)initWithName:(NSString*)treeName\n           atPlace:(FolderTree*)parentFolder\n{\n    self = [super init];\n\n    diskSize = 0;\n    name = treeName;\n    parent = parentFolder;\n    [name retain];\n    representation = nil;\n\n    return self;\n}\n\n- (id)initWithName:(NSString*)treeName\n           andSize:(FileSize)size\n           atPlace:(FolderTree*)parentFolder\n{\n    self = [super init];\n\n    diskSize = size;\n    name = treeName;\n    parent = parentFolder;\n    [name retain];\n    representation = nil;\n\n    return self;\n}\n\n- (void)dealloc\n{\n    [name release];\n    [representation release];\n    [super dealloc];\n}\n\n- (LayoutTree*)createLayoutTree\n{\n    return nil;\n}\n@end\n\n@implementation FolderTree\n- (id)initWithName:(NSString*)treeName\n           atPlace:(FolderTree*)parentFolder\n{\n    self = [super initWithName:treeName\n                       atPlace:parentFolder];\n\n    children = [[NSMutableArray alloc] init];\n    return self;\n}\n\n- (void)dealloc\n{\n    [children release];\n    [super dealloc];\n}\n\n+ (void) createFileList: (NSString*)root atPlace:(FolderTree*)parentFolder\n{\n\tNSFileManager *localFileManager = [[NSFileManager alloc] init];\n\tNSURL\t\t  *rootUrl = [NSURL fileURLWithPath:root];\n\tNSDirectoryEnumerator *dirEnumerator = [localFileManager enumeratorAtURL:rootUrl\n\t\t\t\t\t\t\t\t\t\t\t\n                                                  includingPropertiesForKeys:[NSArray arrayWithObjects:\n                                                                              NSURLNameKey,\n                                                                              NSURLIsDirectoryKey,\n                                                                              nil]\n\t\t\t\t\t\t\t\t\t\t\t\n                                                                     options:NSDirectoryEnumerationSkipsHiddenFiles\n\t\t\t\t\t\t\t\t\t\t\t\n                                                                errorHandler:nil];\n    \n\tfor (NSURL *theURL in dirEnumerator)\n\t{\n        [theURL getResourceValue:&fileName\n\t\t\t\t\t\t  forKey:NSURLNameKey\n\t\t\t\t\t\t   error:NULL];\n        \n        // Ignore files under the _extras directory\n        if ([isDirectory boolValue]==YES)\n        {\n            [folder populateChildList:root];\n        }\n        else if ([isDirectory boolValue]==NO)\n        {\n            [parentFolder addChild:f];\n        }\t\t\n    }\n}\n\n- (void) populateChildList:(NSString*)root\n{\n    NSString *thisRoot = [[root stringByAppendingString:@\"/\"]\n                                stringByAppendingString:name];\n    \n    [FolderTree createFileList:thisRoot\n                       atPlace:self];\n    \n    for ( FileTree *f in children )\n        diskSize += [f getDiskSize];\n}\n\n- (FolderTree*)addChild:(FileTree*)subTree\n{\n    [children addObject:subTree];\n    return self;\n}\n\n- (LayoutTree*)createLayoutTree\n{\n    return\n        [[LayoutTree alloc] initWithFileList:children\n                                andTotalSize:diskSize];\n}\n@end\n\n@implementation NSString (Extension)\n- (void)doSomething\n{\n}\n@end\n"
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_interface.h.d/args.ctags",
    "content": "--fields=*\n--fields=-Z\n--fields-ObjectiveC=+{category}{protocols}\n"
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_interface.h.d/expected.tags",
    "content": "ANOTHER_MACRO\tinput.h\t/^ # define ANOTHER_MACRO( WITH, MOAR ) \\\\$/;\"\tkind:macro\tline:21\tlanguage:ObjectiveC\troles:def\nA_MACRO_TEST\tinput.h\t/^#define       A_MACRO_TEST$/;\"\tkind:macro\tline:15\tlanguage:ObjectiveC\troles:def\nExtension\tinput.h\t/^@interface NSString (Extension)$/;\"\tkind:category\tline:65\tlanguage:ObjectiveC\tinterface:NSString\troles:def\nExtension2\tinput.h\t/^@interface NSString (Extension2) <Proto2>$/;\"\tkind:category\tline:69\tlanguage:ObjectiveC\tinterface:NSString\troles:def\tprotocols:Proto2\nExtension34\tinput.h\t/^@interface NSString (Extension34) <Proto3, Proto4>$/;\"\tkind:category\tline:73\tlanguage:ObjectiveC\tinterface:NSString\troles:def\tprotocols:Proto3,Proto4\nFileTree\tinput.h\t/^@interface FileTree : NSObject {$/;\"\tkind:interface\tline:33\tlanguage:ObjectiveC\tstruct:aStruct\tinherits:NSObject\troles:def\nFolderTree\tinput.h\t/^@interface FolderTree : FileTree {$/;\"\tkind:interface\tline:52\tlanguage:ObjectiveC\tinherits:FileTree\troles:def\nMyString\tinput.h\t/^@interface MyString <Proto5>$/;\"\tkind:interface\tline:77\tlanguage:ObjectiveC\troles:def\tprotocols:Proto5\nNSString\tinput.h\t/^@interface NSString (Extension)$/;\"\tkind:interface\tline:65\tlanguage:ObjectiveC\troles:def\tcategory:Extension\nNSString\tinput.h\t/^@interface NSString (Extension2) <Proto2>$/;\"\tkind:interface\tline:69\tlanguage:ObjectiveC\troles:def\tcategory:Extension2\tprotocols:Proto2\nNSString\tinput.h\t/^@interface NSString (Extension34) <Proto3, Proto4>$/;\"\tkind:interface\tline:73\tlanguage:ObjectiveC\troles:def\tcategory:Extension34\tprotocols:Proto3,Proto4\nSampleTypedefObjC\tinput.h\t/^typedef something SampleTypedefObjC;$/;\"\tkind:typedef\tline:17\tlanguage:ObjectiveC\troles:def\nYourString\tinput.h\t/^@interface YourString <Proto6, Proto7>$/;\"\tkind:interface\tline:81\tlanguage:ObjectiveC\troles:def\tprotocols:Proto6,Proto7\naStruct\tinput.h\t/^struct aStruct$/;\"\tkind:struct\tline:25\tlanguage:ObjectiveC\troles:def\naStructMember\tinput.h\t/^    int aStructMember;$/;\"\tkind:field\tline:27\tlanguage:ObjectiveC\tstruct:aStruct\troles:def\naddChild:\tinput.h\t/^- (FolderTree*)addChild:(FileTree*)subTree;$/;\"\tkind:method\tline:60\tlanguage:ObjectiveC\tinterface:FolderTree\tsignature:(FileTree*)\troles:def\nanotherStructMember\tinput.h\t/^    char *anotherStructMember[ NOT_IN_TAG ];$/;\"\tkind:field\tline:28\tlanguage:ObjectiveC\tstruct:aStruct\troles:def\nchildren\tinput.h\t/^    NSMutableArray     *children;$/;\"\tkind:field\tline:53\tlanguage:ObjectiveC\tinterface:FolderTree\troles:def\ncreateLayoutTree\tinput.h\t/^- (LayoutTree*)createLayoutTree;$/;\"\tkind:method\tline:49\tlanguage:ObjectiveC\tinterface:FileTree\tsignature:()\troles:def\ncreateLayoutTree\tinput.h\t/^- (LayoutTree*)createLayoutTree;$/;\"\tkind:method\tline:62\tlanguage:ObjectiveC\tinterface:FolderTree\tsignature:()\troles:def\ndealloc\tinput.h\t/^- (void)dealloc;$/;\"\tkind:method\tline:46\tlanguage:ObjectiveC\tinterface:FileTree\tsignature:()\troles:def\ndealloc\tinput.h\t/^- (void)dealloc;$/;\"\tkind:method\tline:58\tlanguage:ObjectiveC\tinterface:FolderTree\tsignature:()\troles:def\ndiskSize\tinput.h\t/^    FileSize    diskSize;$/;\"\tkind:field\tline:37\tlanguage:ObjectiveC\tinterface:FileTree\troles:def\ndoSomething\tinput.h\t/^- (void)doSomething;$/;\"\tkind:method\tline:66\tlanguage:ObjectiveC\tinterface:NSString\tsignature:()\troles:def\tcategory:Extension\ndoSomething2\tinput.h\t/^- (void)doSomething2;$/;\"\tkind:method\tline:70\tlanguage:ObjectiveC\tinterface:NSString\tsignature:()\troles:def\tcategory:Extension2\ndoSomething34\tinput.h\t/^- (void)doSomething34;$/;\"\tkind:method\tline:74\tlanguage:ObjectiveC\tinterface:NSString\tsignature:()\troles:def\tcategory:Extension34\ndoSomething5\tinput.h\t/^- (void)doSomething5;$/;\"\tkind:method\tline:78\tlanguage:ObjectiveC\tinterface:MyString\tsignature:()\troles:def\ndoSomething67\tinput.h\t/^- (void)doSomething67;$/;\"\tkind:method\tline:82\tlanguage:ObjectiveC\tinterface:YourString\tsignature:()\troles:def\ngetDiskSize\tinput.h\t/^- (FileSize)getDiskSize;$/;\"\tkind:method\tline:48\tlanguage:ObjectiveC\tinterface:FileTree\tsignature:()\troles:def\ninitWithName:andSize:atPlace:\tinput.h\t/^- (id)initWithName:(NSString*)treeName$/;\"\tkind:method\tline:39\tlanguage:ObjectiveC\tinterface:FileTree\tsignature:(NSString*,uint64_t,FolderTree*)\troles:def\ninitWithName:atPlace:\tinput.h\t/^- (id)initWithName:(NSString*)treeName$/;\"\tkind:method\tline:43\tlanguage:ObjectiveC\tinterface:FileTree\tsignature:(NSString*,FolderTree*)\troles:def\ninitWithName:atPlace:\tinput.h\t/^- (id)initWithName:(NSString*)treeName$/;\"\tkind:method\tline:56\tlanguage:ObjectiveC\tinterface:FolderTree\tsignature:(NSString*,FolderTree*)\troles:def\nname\tinput.h\t/^\tNSString\t*name;$/;\"\tkind:field\tline:34\tlanguage:ObjectiveC\tinterface:FileTree\troles:def\nparent\tinput.h\t/^    FolderTree  *parent[THISISNOTATAG];$/;\"\tkind:field\tline:36\tlanguage:ObjectiveC\tinterface:FileTree\troles:def\npopulateChildList:\tinput.h\t/^- (void) populateChildList:(NSString*)root;$/;\"\tkind:method\tline:61\tlanguage:ObjectiveC\tinterface:FolderTree\tsignature:(NSString*)\troles:def\nrepresentation\tinput.h\t/^    LayoutTree  *representation;$/;\"\tkind:field\tline:35\tlanguage:ObjectiveC\tinterface:FileTree\troles:def\n"
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_interface.h.d/input.h",
    "content": "//\n//  commentary test\n//  SupaView\n//\n//  Created by Vincent Berthoux on 14/06/10.\n//  Copyright 2010 __MyCompanyName__. All rights reserved.\n//\n\n#import <Cocoa/Cocoa.h>\n#import \"LayoutTree.h\"\n\n@class LayoutTree;\n@class FolderTree;\n\n#define       A_MACRO_TEST\n\ntypedef something SampleTypedefObjC;\n\n// Mer & no_struct_name must not be present in output\n// tag\n # define ANOTHER_MACRO( WITH, MOAR ) \\\n                Mer( ) \\\n                struct no_struct_name\n\nstruct aStruct\n{\n    int aStructMember;\n    char *anotherStructMember[ NOT_IN_TAG ];\n};\n\n#pragma DONTCARE /* :-) */\n\n@interface FileTree : NSObject {\n\tNSString\t*name;\n    LayoutTree  *representation;\n    FolderTree  *parent[THISISNOTATAG];\n    FileSize    diskSize;\n}\n- (id)initWithName:(NSString*)treeName\n           andSize:(uint64_t)size\n           atPlace:(FolderTree*)parentFolder;\n\n- (id)initWithName:(NSString*)treeName\n           atPlace:(FolderTree*)parentFolder;\n\n- (void)dealloc;\n\n- (FileSize)getDiskSize;\n- (LayoutTree*)createLayoutTree;\n@end\n\n@interface FolderTree : FileTree {\n    NSMutableArray     *children;\n}\n\n- (id)initWithName:(NSString*)treeName\n           atPlace:(FolderTree*)parentFolder;\n- (void)dealloc;\n\n- (FolderTree*)addChild:(FileTree*)subTree;\n- (void) populateChildList:(NSString*)root;\n- (LayoutTree*)createLayoutTree;\n@end\n\n@interface NSString (Extension)\n- (void)doSomething;\n@end\n\n@interface NSString (Extension2) <Proto2>\n- (void)doSomething2;\n@end\n\n@interface NSString (Extension34) <Proto3, Proto4>\n- (void)doSomething34;\n@end\n\n@interface MyString <Proto5>\n- (void)doSomething5;\n@end\n\n@interface YourString <Proto6, Proto7>\n- (void)doSomething67;\n@end\n"
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_property.h.d/args.ctags",
    "content": ""
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_property.h.d/expected.tags",
    "content": "Person\tinput.h\t/^@interface Person : NSObject {$/;\"\ti\ninitWithAge:\tinput.h\t/^-(id)initWithAge:(int)age;$/;\"\tm\tinterface:Person\nm_age\tinput.h\t/^        int m_age;$/;\"\tE\tinterface:Person\nm_name\tinput.h\t/^        NSString *m_name;$/;\"\tE\tinterface:Person\npersonAge\tinput.h\t/^@property(readonly) int personAge;$/;\"\tp\tinterface:Person\npersonName\tinput.h\t/^@property(copy) NSString *personName;$/;\"\tp\tinterface:Person\n"
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_property.h.d/input.h",
    "content": "\n@interface Person : NSObject {\n    @public\n        NSString *m_name;\n    @private\n        int m_age;\n}\n \n@property(copy) NSString *personName;\n@property(readonly) int personAge;\n \n-(id)initWithAge:(int)age;\n@end\n"
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_protocol.h.d/args.ctags",
    "content": ""
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_protocol.h.d/expected.tags",
    "content": "Locking\tinput.h\t/^@protocol Locking$/;\"\tP\nlock\tinput.h\t/^- (void)lock;$/;\"\tm\tprotocol:Locking\nunlock\tinput.h\t/^- (void)unlock;$/;\"\tm\tprotocol:Locking\n"
  },
  {
    "path": "Units/parser-objectivec.r/objectivec_protocol.h.d/input.h",
    "content": "\n@protocol Locking\n- (void)lock;\n- (void)unlock;\n@end\n\n"
  },
  {
    "path": "Units/parser-ocaml.r/github-451-improved.d/args.ctags",
    "content": "--sort=no\n--fields=+K\n"
  },
  {
    "path": "Units/parser-ocaml.r/github-451-improved.d/expected.tags",
    "content": "Input\tinput.ml\t/^(* \"let rec ... and ...\" *)$/;\"\tmodule\nf\tinput.ml\t/^let rec f x = (g x) + 1$/;\"\tfunction\ng\tinput.ml\t/^and g x = (f x) - 1$/;\"\tfunction\nA\tinput.ml\t/^module rec A : sig$/;\"\tmodule\nt\tinput.ml\t/^                 type t = Leaf of string | Node of ASet.t$/;\"\ttype\tmodule:A\nLeaf\tinput.ml\t/^                 type t = Leaf of string | Node of ASet.t$/;\"\tConstructor\ttype:A/t\nNode\tinput.ml\t/^                 type t = Leaf of string | Node of ASet.t$/;\"\tConstructor\ttype:A/t\ncompare\tinput.ml\t/^                 val compare: t -> t -> int$/;\"\tval\ttype:A/t\nt\tinput.ml\t/^                 type t = Leaf of string | Node of ASet.t$/;\"\ttype\tmodule:A\nLeaf\tinput.ml\t/^                 type t = Leaf of string | Node of ASet.t$/;\"\tConstructor\ttype:A/t\nNode\tinput.ml\t/^                 type t = Leaf of string | Node of ASet.t$/;\"\tConstructor\ttype:A/t\ncompare\tinput.ml\t/^                 let compare t1 t2 =$/;\"\tfunction\tmodule:A\nASet\tinput.ml\t/^        and ASet : Set.S with type elt = A.t$/;\"\tmodule\nelt\tinput.ml\t/^        and ASet : Set.S with type elt = A.t$/;\"\ttype\n"
  },
  {
    "path": "Units/parser-ocaml.r/github-451-improved.d/input.ml",
    "content": "(* \"let rec ... and ...\" *)\nlet rec f x = (g x) + 1\nand g x = (f x) - 1\n\n(* Taken from http://caml.inria.fr/pub/docs/manual-ocaml/extn.html\n   \"module [rec] M : sig ... end = struct ... end\" *)\nmodule rec A : sig\n                 type t = Leaf of string | Node of ASet.t\n                 val compare: t -> t -> int\n               end\n             = struct\n                 type t = Leaf of string | Node of ASet.t\n                 let compare t1 t2 =\n                   match (t1, t2) with\n                     (Leaf s1, Leaf s2) -> Pervasives.compare s1 s2\n                   | (Leaf _, Node _) -> 1\n                   | (Node _, Leaf _) -> -1\n                   | (Node n1, Node n2) -> ASet.compare n1 n2\n               end\n        and ASet : Set.S with type elt = A.t\n                 = Set.Make(A)\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocamlAllKinds.ml.t/args.ctags",
    "content": "--sort=no\n--fields=+K\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocamlAllKinds.ml.t/expected.tags",
    "content": "Input\tinput.ml\t/^module ModuleFoo = struct$/;\"\tmodule\nModuleFoo\tinput.ml\t/^module ModuleFoo = struct$/;\"\tmodule\nfoobar\tinput.ml\t/^    type foobar =$/;\"\ttype\tmodule:ModuleFoo\nConstructorFoo\tinput.ml\t/^          ConstructorFoo$/;\"\tConstructor\ttype:ModuleFoo/foobar\nConstructorBar\tinput.ml\t/^        | ConstructorBar of int * char list$/;\"\tConstructor\ttype:ModuleFoo/foobar\nfoorecord\tinput.ml\t/^type 'a foorecord =$/;\"\ttype\nfoofield\tinput.ml\t/^    { foofield : 'a;$/;\"\tRecordField\ttype:foorecord\nbarfield\tinput.ml\t/^     barfield : int;$/;\"\tRecordField\ttype:foorecord\nfoobarfield\tinput.ml\t/^     mutable foobarfield : list char -> int -> unit }$/;\"\tRecordField\ttype:foorecord\n+-\tinput.ml\t/^let (+-) a b =$/;\"\tfunction\nshall_appear\tinput.ml\t/^let shall_appear () =$/;\"\tfunction\nfoo_function\tinput.ml\t/^let foo_function a b = (a, b)$/;\"\tfunction\nfooClass\tinput.ml\t/^class  fooClass =$/;\"\tclass\nx\tinput.ml\t/^    val x = ()$/;\"\tval\tclass:fooClass\nfooMethod\tinput.ml\t/^    method fooMethod = x$/;\"\tmethod\tclass:fooClass\nConnectionNotReachable\tinput.ml\t/^exception ConnectionNotReachable$/;\"\tException\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocamlAllKinds.ml.t/input.ml",
    "content": "module ModuleFoo = struct\n    type foobar =\n          ConstructorFoo\n        | ConstructorBar of int * char list\nend\n\ntype 'a foorecord =\n    { foofield : 'a;\n     barfield : int;\n     mutable foobarfield : list char -> int -> unit }\n\n(* op redif *)\nlet (+-) a b =\n    let aplus = a + b\n    and aminus = a - b\n    in\n    (aplus, aminus)\n\nlet shall_appear () =\n    let sub_not 1 = 2\n    and shall_not_either fu = () in\n    let nope = 3\nand must_appear_also 4 = ()\n\n\nlet foo_function a b = (a, b)\n\nclass  fooClass =\nobject (self)\n    val x = ()\n    method fooMethod = x\nend\n\nexception ConnectionNotReachable\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocamlCommentInStringAllowed.ml.d/expected.tags",
    "content": "Input\tinput.ml\t/^(* the string \"(*\" does NOT start a comment *)$/;\"\tM\n_\tinput.ml\t/^let _ = p \"foo\"$/;\"\tf\np\tinput.ml\t/^let p = print_endline$/;\"\tv\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocamlCommentInStringAllowed.ml.d/input.ml",
    "content": "(* the string \"(*\" does NOT start a comment *)\nlet p = print_endline\nlet _ = p \"foo\"\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_empty.ml.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_empty.ml.d/input.ml",
    "content": ""
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_empty.ml_etags.d/expected.tags-e",
    "content": "\f\ninput.ml,0\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_empty.ml_etags.d/input.ml",
    "content": ""
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_empty.ml_xref.d/expected.tags-x",
    "content": ""
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_empty.ml_xref.d/input.ml",
    "content": ""
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_only_str.ml.d/expected.tags",
    "content": "Input\tinput.ml\t/^\"(*)(*)\"$/;\"\tM\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_only_str.ml.d/input.ml",
    "content": "\"(*)(*)\"\n\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_string_tests.ml.d/expected.tags",
    "content": "Input\tinput.ml\t/^$/;\"\tM\nvalueStr\tinput.ml\t/^let valueStr = \"(*)(*)\"$/;\"\tv\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_string_tests.ml.d/input.ml",
    "content": "\nlet valueStr = \"(*)(*)\"\n\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_two_files.d/args.ctags",
    "content": "--sort=no\n--fields=+n\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_two_files.d/expected.tags",
    "content": "Input\tinput.ml\t/^let foo_function a b = (a, b)$/;\"\tM\tline:1\nfoo_function\tinput.ml\t/^let foo_function a b = (a, b)$/;\"\tf\tline:1\nInput-0\tinput-0.ml\t/^let bar_function x y = (x, y)$/;\"\tM\tline:1\nbar_function\tinput-0.ml\t/^let bar_function x y = (x, y)$/;\"\tf\tline:1\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_two_files.d/input-0.ml",
    "content": "let bar_function x y = (x, y)\n"
  },
  {
    "path": "Units/parser-ocaml.r/ocaml_two_files.d/input.ml",
    "content": "let foo_function a b = (a, b)\n(*\n SOMETHING HERE\n *)\n\n"
  },
  {
    "path": "Units/parser-odin.r/odin-attributes.d/args.ctags",
    "content": "--sort=no\n--fields=+K\n"
  },
  {
    "path": "Units/parser-odin.r/odin-attributes.d/expected.tags",
    "content": "attrs\tinput.odin\t/^package attrs$/;\"\tpackage\ninternal_state\tinput.odin\t/^internal_state := 10$/;\"\tvar\tpackage:attrs\nrestore_mode\tinput.odin\t/^restore_mode :: proc() {}$/;\"\tproc\tpackage:attrs\ncleanup\tinput.odin\t/^cleanup :: proc() {}$/;\"\tproc\tpackage:attrs\nhidden\tinput.odin\t/^hidden :: proc() {}$/;\"\tproc\tpackage:attrs\ndestroy\tinput.odin\t/^destroy :: proc() {}$/;\"\tproc\tpackage:attrs\n"
  },
  {
    "path": "Units/parser-odin.r/odin-attributes.d/input.odin",
    "content": "#+build linux, darwin\npackage attrs\n\n@(private)\ninternal_state := 10\n\n@(private = \"file\")\nrestore_mode :: proc() {}\n\n@(deprecated = \"use destroy\", private = \"file\")\ncleanup :: proc() {}\n\n@private\nhidden :: proc() {}\n\ndestroy :: proc() {}\n"
  },
  {
    "path": "Units/parser-odin.r/odin-basic.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-odin.r/odin-basic.d/expected.tags",
    "content": "main\tinput.odin\t/^package main$/;\"\tp\tline:1\nVec2\tinput.odin\t/^Vec2 :: struct {$/;\"\ts\tline:3\tpackage:main\tend:6\nx\tinput.odin\t/^    x: f32,$/;\"\tm\tline:4\tstruct:main.Vec2\ny\tinput.odin\t/^    y: f32,$/;\"\tm\tline:5\tstruct:main.Vec2\nDirection\tinput.odin\t/^Direction :: enum {$/;\"\te\tline:8\tpackage:main\tend:13\nNorth\tinput.odin\t/^    North,$/;\"\tn\tline:9\tenum:main.Direction\nEast\tinput.odin\t/^    East,$/;\"\tn\tline:10\tenum:main.Direction\nSouth\tinput.odin\t/^    South,$/;\"\tn\tline:11\tenum:main.Direction\nWest\tinput.odin\t/^    West,$/;\"\tn\tline:12\tenum:main.Direction\nadd\tinput.odin\t/^add :: proc(a, b: Vec2) -> Vec2 {$/;\"\tf\tline:15\tpackage:main\tend:17\nmain\tinput.odin\t/^main :: proc() {$/;\"\tf\tline:19\tpackage:main\tend:21\n"
  },
  {
    "path": "Units/parser-odin.r/odin-basic.d/input.odin",
    "content": "package main\n\nVec2 :: struct {\n    x: f32,\n    y: f32,\n}\n\nDirection :: enum {\n    North,\n    East,\n    South,\n    West,\n}\n\nadd :: proc(a, b: Vec2) -> Vec2 {\n    return Vec2{a.x + b.x, a.y + b.y}\n}\n\nmain :: proc() {\n    v := Vec2{1, 2}\n}\n"
  },
  {
    "path": "Units/parser-odin.r/odin-comments.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-odin.r/odin-comments.d/expected.tags",
    "content": "comments\tinput.odin\t/^package comments$/;\"\tp\nafter_nested\tinput.odin\t/^after_nested :: proc() {}$/;\"\tf\tpackage:comments\nafter_line\tinput.odin\t/^after_line :: proc() {}$/;\"\tf\tpackage:comments\nafter_multi\tinput.odin\t/^after_multi :: proc() {}$/;\"\tf\tpackage:comments\nafter_deep\tinput.odin\t/^after_deep :: proc() {}$/;\"\tf\tpackage:comments\nafter_slash\tinput.odin\t/^after_slash :: proc() {}$/;\"\tf\tpackage:comments\nafter_complex\tinput.odin\t/^after_complex :: proc() {}$/;\"\tf\tpackage:comments\n"
  },
  {
    "path": "Units/parser-odin.r/odin-comments.d/input.odin",
    "content": "package comments\n\n/* Outer /* nested */ comment */\nafter_nested :: proc() {}\n\n// Line comment\nafter_line :: proc() {}\n\n/* Multi\n   line\n   comment */\nafter_multi :: proc() {}\n\n/* Outer /* mid /* deep */ mid */ outer */\nafter_deep :: proc() {}\n\n/* has a / slash and a * star inside */\nafter_slash :: proc() {}\n\n/* /* nested\n   with newline and a * star and a / slash\n*/ done */\nafter_complex :: proc() {}\n"
  },
  {
    "path": "Units/parser-odin.r/odin-enums.d/args.ctags",
    "content": "--sort=no\n--fields=+neK\n"
  },
  {
    "path": "Units/parser-odin.r/odin-enums.d/expected.tags",
    "content": "enums\tinput.odin\t/^package enums$/;\"\tpackage\tline:1\nColor\tinput.odin\t/^Color :: enum {$/;\"\tenum\tline:3\tpackage:enums\tend:7\nRed\tinput.odin\t/^    Red,$/;\"\tenumerator\tline:4\tenum:enums.Color\nGreen\tinput.odin\t/^    Green,$/;\"\tenumerator\tline:5\tenum:enums.Color\nBlue\tinput.odin\t/^    Blue,$/;\"\tenumerator\tline:6\tenum:enums.Color\nSmall\tinput.odin\t/^Small :: enum u8 {$/;\"\tenum\tline:9\tpackage:enums\ttyperef:typename:u8\tend:13\nA\tinput.odin\t/^    A,$/;\"\tenumerator\tline:10\tenum:enums.Small\nB\tinput.odin\t/^    B,$/;\"\tenumerator\tline:11\tenum:enums.Small\nC\tinput.odin\t/^    C,$/;\"\tenumerator\tline:12\tenum:enums.Small\nExplicit\tinput.odin\t/^Explicit :: enum {$/;\"\tenum\tline:15\tpackage:enums\tend:19\nFirst\tinput.odin\t/^    First = 1,$/;\"\tenumerator\tline:16\tenum:enums.Explicit\nSecond\tinput.odin\t/^    Second = 5,$/;\"\tenumerator\tline:17\tenum:enums.Explicit\nThird\tinput.odin\t/^    Third = 10,$/;\"\tenumerator\tline:18\tenum:enums.Explicit\n"
  },
  {
    "path": "Units/parser-odin.r/odin-enums.d/input.odin",
    "content": "package enums\n\nColor :: enum {\n    Red,\n    Green,\n    Blue,\n}\n\nSmall :: enum u8 {\n    A,\n    B,\n    C,\n}\n\nExplicit :: enum {\n    First = 1,\n    Second = 5,\n    Third = 10,\n}\n\n"
  },
  {
    "path": "Units/parser-odin.r/odin-foreign.d/args.ctags",
    "content": "--sort=no\n--fields=+neKSr\n--extras=+r\n"
  },
  {
    "path": "Units/parser-odin.r/odin-foreign.d/expected.tags",
    "content": "ffi\tinput.odin\t/^package ffi$/;\"\tpackage\tline:1\troles:def\nlibc\tinput.odin\t/^foreign import libc \"system:libc.so\"$/;\"\tforeign\tline:3\tpackage:ffi\troles:def\nsystem\tinput.odin\t/^foreign import libc \"system:libc.so\"$/;\"\tcollection\tline:3\troles:referenced\nlibc.so\tinput.odin\t/^foreign import libc \"system:libc.so\"$/;\"\tccode\tline:3\tcollection:system\troles:imported\timportName:libc\nputs\tinput.odin\t/^    puts :: proc \"c\" (s: cstring) -> i32 ---$/;\"\tproc\tline:6\tpackage:ffi\tsignature:(s: cstring)\troles:def\nexit\tinput.odin\t/^    exit :: proc \"c\" (code: i32) ---$/;\"\tproc\tline:7\tpackage:ffi\tsignature:(code: i32)\troles:def\nerrno\tinput.odin\t/^    errno: i32$/;\"\tvar\tline:8\tpackage:ffi\troles:def\nsignal_handler\tinput.odin\t/^    signal_handler: proc \"c\" (sig: i32)$/;\"\tvar\tline:9\tpackage:ffi\troles:def\nmruby\tinput.odin\t/^foreign import mruby \"libmruby.a\"$/;\"\tforeign\tline:12\tpackage:ffi\troles:def\nlibmruby.a\tinput.odin\t/^foreign import mruby \"libmruby.a\"$/;\"\tccode\tline:12\troles:imported\timportName:mruby\nopen\tinput.odin\t/^    open :: proc() -> rawptr ---$/;\"\tproc\tline:17\tpackage:ffi\tsignature:()\troles:def\nclose\tinput.odin\t/^    close :: proc(state: rawptr) ---$/;\"\tproc\tline:18\tpackage:ffi\tsignature:(state: rawptr)\troles:def\ngl\tinput.odin\t/^foreign import gl { \"system:opengl32.lib\", \"system:glu32.lib\" }$/;\"\tforeign\tline:21\tpackage:ffi\troles:def\nsystem\tinput.odin\t/^foreign import gl { \"system:opengl32.lib\", \"system:glu32.lib\" }$/;\"\tcollection\tline:21\troles:referenced\nopengl32.lib\tinput.odin\t/^foreign import gl { \"system:opengl32.lib\", \"system:glu32.lib\" }$/;\"\tccode\tline:21\tcollection:system\troles:imported\timportName:gl\nsystem\tinput.odin\t/^foreign import gl { \"system:opengl32.lib\", \"system:glu32.lib\" }$/;\"\tcollection\tline:21\troles:referenced\nglu32.lib\tinput.odin\t/^foreign import gl { \"system:opengl32.lib\", \"system:glu32.lib\" }$/;\"\tccode\tline:21\tcollection:system\troles:imported\timportName:gl\nLIB\tinput.odin\t/^LIB :: \"\"$/;\"\tconst\tline:23\tpackage:ffi\troles:def\nstbi\tinput.odin\t/^foreign import stbi {$/;\"\tforeign\tline:25\tpackage:ffi\troles:def\nsystem\tinput.odin\t/^    LIB when LIB != \"\" else \"system:stb_image\",$/;\"\tcollection\tline:26\troles:referenced\nstb_image\tinput.odin\t/^    LIB when LIB != \"\" else \"system:stb_image\",$/;\"\tccode\tline:26\tcollection:system\troles:imported\timportName:stbi\ninternal_init\tinput.odin\t/^    internal_init :: proc \"c\" () ---$/;\"\tproc\tline:31\tpackage:ffi\tsignature:()\troles:def\nreadv\tinput.odin\t/^    readv :: proc \"c\" (fd: i32, iov: rawptr, cnt: i32) -> i32 ---$/;\"\tproc\tline:32\tpackage:ffi\tsignature:(fd: i32, iov: rawptr, cnt: i32)\troles:def\ngetres\tinput.odin\t/^    getres :: proc \"c\" (w: ^i32, h: ^i32) -> (i32, i32) ---$/;\"\tproc\tline:33\tpackage:ffi\tsignature:(w: ^i32, h: ^i32)\troles:def\nprintf\tinput.odin\t/^    printf :: proc \"c\" (fmt: cstring, #c_vararg args: ..any) -> i32 ---$/;\"\tproc\tline:34\tpackage:ffi\tsignature:(fmt: cstring, #c_vararg args: ..any)\troles:def\nget_buf\tinput.odin\t/^    get_buf :: proc \"c\" (n: i32) -> [4]i32 ---$/;\"\tproc\tline:35\tpackage:ffi\tsignature:(n: i32)\troles:def\nepoll_create\tinput.odin\t/^        epoll_create :: proc \"c\" (size: i32) -> i32 ---$/;\"\tproc\tline:37\tpackage:ffi\tsignature:(size: i32)\troles:def\nlowlevel\tinput.odin\t/^foreign import lowlevel \"lowlevel.asm\"$/;\"\tforeign\tline:42\tpackage:ffi\troles:def\nlowlevel.asm\tinput.odin\t/^foreign import lowlevel \"lowlevel.asm\"$/;\"\tasmfile\tline:42\troles:imported\timportName:lowlevel\n__get_flags\tinput.odin\t/^    __get_flags :: proc \"c\" () -> u64 ---$/;\"\tproc\tline:44\tpackage:ffi\tsignature:()\troles:def\nlowlevelalt\tinput.odin\t/^foreign import lowlevelalt {$/;\"\tforeign\tline:47\tpackage:ffi\troles:def\nlowlevelalt0.s\tinput.odin\t/^    \"lowlevelalt0.s\",$/;\"\tasmfile\tline:48\troles:imported\timportName:lowlevelalt\nlowlevelalt0.S\tinput.odin\t/^    \"lowlevelalt0.S\"$/;\"\tasmfile\tline:49\troles:imported\timportName:lowlevelalt\nbroken0\tinput.odin\t/^foreign import broken0 \":broken0.so\"$/;\"\tforeign\tline:53\tpackage:ffi\troles:def\nbroken0.so\tinput.odin\t/^foreign import broken0 \":broken0.so\"$/;\"\tccode\tline:53\troles:imported\timportName:broken0\nbroken1\tinput.odin\t/^foreign import broken1 \":broken1.s\"$/;\"\tforeign\tline:54\tpackage:ffi\troles:def\nbroken1.s\tinput.odin\t/^foreign import broken1 \":broken1.s\"$/;\"\tasmfile\tline:54\troles:imported\timportName:broken1\nbroken2\tinput.odin\t/^foreign import broken2 \"system:\"$/;\"\tforeign\tline:57\tpackage:ffi\troles:def\nsystem\tinput.odin\t/^foreign import broken2 \"system:\"$/;\"\tcollection\tline:57\troles:referenced\n"
  },
  {
    "path": "Units/parser-odin.r/odin-foreign.d/input.odin",
    "content": "package ffi\n\nforeign import libc \"system:libc.so\"\n\nforeign libc {\n    puts :: proc \"c\" (s: cstring) -> i32 ---\n    exit :: proc \"c\" (code: i32) ---\n    errno: i32\n    signal_handler: proc \"c\" (sig: i32)\n}\n\nforeign import mruby \"libmruby.a\"\n\n@(default_calling_convention = \"c\")\nforeign mruby {\n    @(link_name = \"mrb_open\")\n    open :: proc() -> rawptr ---\n    close :: proc(state: rawptr) ---\n}\n\nforeign import gl { \"system:opengl32.lib\", \"system:glu32.lib\" }\n\nLIB :: \"\"\n\nforeign import stbi {\n    LIB when LIB != \"\" else \"system:stb_image\",\n}\n\nforeign libc {\n    @private\n    internal_init :: proc \"c\" () ---\n    readv :: proc \"c\" (fd: i32, iov: rawptr, cnt: i32) -> i32 ---\n    getres :: proc \"c\" (w: ^i32, h: ^i32) -> (i32, i32) ---\n    printf :: proc \"c\" (fmt: cstring, #c_vararg args: ..any) -> i32 ---\n    get_buf :: proc \"c\" (n: i32) -> [4]i32 ---\n    when ODIN_OS == .Linux {\n        epoll_create :: proc \"c\" (size: i32) -> i32 ---\n    }\n}\n\n// Taken from https://odin-lang.org/docs/overview/#foreign-system\nforeign import lowlevel \"lowlevel.asm\"\nforeign lowlevel {\n    __get_flags :: proc \"c\" () -> u64 ---\n}\n\nforeign import lowlevelalt {\n    \"lowlevelalt0.s\",\n    \"lowlevelalt0.S\"\n}\n\n/* The collection is an empty string. The parser should not crash. */\nforeign import broken0 \":broken0.so\"\nforeign import broken1 \":broken1.s\"\n\n/* The ccode (or asmfile) is an empty string. The parser should not crash. */\nforeign import broken2 \"system:\"\n"
  },
  {
    "path": "Units/parser-odin.r/odin-imports.d/args.ctags",
    "content": "--sort=no\n--fields=+rKE\n--extras=+r\n"
  },
  {
    "path": "Units/parser-odin.r/odin-imports.d/expected.tags",
    "content": "imports\tinput.odin\t/^package imports$/;\"\tpackage\troles:def\ncore\tinput.odin\t/^import \"core:fmt\"$/;\"\tcollection\troles:referenced\textras:reference\nfmt\tinput.odin\t/^import \"core:fmt\"$/;\"\tpackage\tcollection:core\troles:imported\textras:reference\ncore\tinput.odin\t/^import \"core:os\"$/;\"\tcollection\troles:referenced\textras:reference\nos\tinput.odin\t/^import \"core:os\"$/;\"\tpackage\tcollection:core\troles:imported\textras:reference\nm\tinput.odin\t/^import m \"core:math\"$/;\"\timportName\troles:def\ncore\tinput.odin\t/^import m \"core:math\"$/;\"\tcollection\troles:referenced\textras:reference\nmath\tinput.odin\t/^import m \"core:math\"$/;\"\tpackage\tcollection:core\troles:imported\textras:reference\timportName:m\ncol\tinput.odin\t/^import \"col:lib\\/sublib0\"$/;\"\tcollection\troles:referenced\textras:reference\nlib/sublib0\tinput.odin\t/^import \"col:lib\\/sublib0\"$/;\"\tpackage\tcollection:col\troles:imported\textras:reference\timportName:sublib0\nsublib0\tinput.odin\t/^import \"col:lib\\/sublib0\"$/;\"\timportName\troles:def\textras:implicitImportName\nmysublib\tinput.odin\t/^import mysublib \"col:lib\\/sublib1\"$/;\"\timportName\troles:def\ncol\tinput.odin\t/^import mysublib \"col:lib\\/sublib1\"$/;\"\tcollection\troles:referenced\textras:reference\nlib/sublib1\tinput.odin\t/^import mysublib \"col:lib\\/sublib1\"$/;\"\tpackage\tcollection:col\troles:imported\textras:reference\timportName:mysublib\n"
  },
  {
    "path": "Units/parser-odin.r/odin-imports.d/input.odin",
    "content": "package imports\n\nimport \"core:fmt\"\nimport \"core:os\"\nimport m \"core:math\"\n\nimport \"col:lib/sublib0\"\nimport mysublib \"col:lib/sublib1\"\n"
  },
  {
    "path": "Units/parser-odin.r/odin-incomplete.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-odin.r/odin-incomplete.d/expected.tags",
    "content": "incomplete\tinput.odin\t/^package incomplete$/;\"\tp\nfoo\tinput.odin\t/^foo :: proc($/;\"\tt\tpackage:incomplete\n"
  },
  {
    "path": "Units/parser-odin.r/odin-incomplete.d/input.odin",
    "content": "package incomplete\n\nfoo :: proc(\n"
  },
  {
    "path": "Units/parser-odin.r/odin-procs.d/args.ctags",
    "content": "--sort=no\n--fields=+neS\n"
  },
  {
    "path": "Units/parser-odin.r/odin-procs.d/expected.tags",
    "content": "procs\tinput.odin\t/^package procs$/;\"\tp\tline:1\nComparator\tinput.odin\t/^Comparator :: #type proc(x, y: int) -> int$/;\"\tt\tline:5\tpackage:procs\tsignature:(x, y: int)\ninit\tinput.odin\t/^init :: proc() {$/;\"\tf\tline:7\tpackage:procs\tsignature:()\tend:8\nvec2_add\tinput.odin\t/^vec2_add :: proc(x, y: f32) -> f32 {$/;\"\tf\tline:10\tpackage:procs\tsignature:(x, y: f32)\tend:12\ndiv_check\tinput.odin\t/^div_check :: proc(a: f32) -> (int, bool) {$/;\"\tf\tline:14\tpackage:procs\tsignature:(a: f32)\tend:16\nwrite_bytes\tinput.odin\t/^write_bytes :: proc \"c\" (n: i32, data: rawptr) {$/;\"\tf\tline:18\tpackage:procs\tsignature:(n: i32, data: rawptr)\tend:19\nget_errno\tinput.odin\t/^get_errno :: proc \"cdecl\" () -> i32 {$/;\"\tf\tline:21\tpackage:procs\tsignature:()\tend:23\nclamp_value\tinput.odin\t/^clamp_value :: proc(x: $T) -> T where T == int {$/;\"\tf\tline:25\tpackage:procs\tsignature:(x: $T)\tend:27\nadd_ints\tinput.odin\t/^add_ints :: proc(a, b: int) -> int {return a + b}$/;\"\tf\tline:29\tpackage:procs\tsignature:(a, b: int)\tend:29\nadd_floats\tinput.odin\t/^add_floats :: proc(a, b: f32) -> f32 {return a + b}$/;\"\tf\tline:30\tpackage:procs\tsignature:(a, b: f32)\tend:30\nadd\tinput.odin\t/^add :: proc {$/;\"\tf\tline:31\tpackage:procs\nMy_Callback\tinput.odin\t/^My_Callback :: proc(x: int) -> bool$/;\"\tt\tline:36\tpackage:procs\tsignature:(x: int)\nLoader\tinput.odin\t/^Loader :: proc(path: string) -> ^u8$/;\"\tt\tline:37\tpackage:procs\tsignature:(path: string)\nalloc_buf\tinput.odin\t/^alloc_buf :: proc(size: int, allocator := context.allocator) -> []u8 {$/;\"\tf\tline:38\tpackage:procs\tsignature:(size: int, allocator := context.allocator)\tend:40\nget_items\tinput.odin\t/^get_items :: proc() -> [dynamic]int {$/;\"\tf\tline:41\tpackage:procs\tsignature:()\tend:43\nmake_handler\tinput.odin\t/^make_handler :: proc() -> proc(int) {$/;\"\tf\tline:44\tpackage:procs\tsignature:()\tend:46\nget_builder\tinput.odin\t/^get_builder :: proc() -> strings.Builder {$/;\"\tf\tline:47\tpackage:procs\tsignature:()\tend:49\nget_lookup\tinput.odin\t/^get_lookup :: proc() -> map[string]int {$/;\"\tf\tline:51\tpackage:procs\tsignature:()\tend:53\nget_c_callback\tinput.odin\t/^get_c_callback :: proc() -> proc \"c\" (i32) {$/;\"\tf\tline:55\tpackage:procs\tsignature:()\tend:57\nget_transform\tinput.odin\t/^get_transform :: proc() -> proc(int) -> int {$/;\"\tf\tline:59\tpackage:procs\tsignature:()\tend:61\nget_checker\tinput.odin\t/^get_checker :: proc() -> proc(int) -> (bool, int) {$/;\"\tf\tline:63\tpackage:procs\tsignature:()\tend:65\nget_simd\tinput.odin\t/^get_simd :: proc() -> #simd[4]f32 {$/;\"\tf\tline:67\tpackage:procs\tsignature:()\tend:69\nNumber\tinput.odin\t/^Number :: struct($T: typeid) { val: T }$/;\"\ts\tline:71\tpackage:procs\tend:71\nval\tinput.odin\t/^Number :: struct($T: typeid) { val: T }$/;\"\tm\tline:71\tstruct:procs.Number\nget_number\tinput.odin\t/^get_number :: proc() -> Number(int) {$/;\"\tf\tline:72\tpackage:procs\tsignature:()\tend:74\nfoo_no_alias\tinput.odin\t/^foo_no_alias :: proc(#no_alias a, b: ^int) {}$/;\"\tf\tline:76\tpackage:procs\tsignature:(#no_alias a, b: ^int)\tend:76\nprint_caller_location\tinput.odin\t/^print_caller_location :: proc(loc := #caller_location) {}$/;\"\tf\tline:78\tpackage:procs\tsignature:(loc := #caller_location)\tend:78\noptional_result\tinput.odin\t/^optional_result :: proc(x: int) -> (value: int, ok: bool) #optional_ok {$/;\"\tf\tline:80\tpackage:procs\tsignature:(x: int)\tend:82\nproc_no_type_assert\tinput.odin\t/^proc_no_type_assert :: proc(a: any) -> int #no_type_assert {$/;\"\tf\tline:84\tpackage:procs\tsignature:(a: any)\tend:86\napply\tinput.odin\t/^apply :: proc(f: proc(int) -> int, x: int) -> int {$/;\"\tf\tline:88\tpackage:procs\tsignature:(f: proc(int) -> int, x: int)\tend:90\nadd_inline\tinput.odin\t/^add_inline :: #force_inline proc(a, b: int) -> int {$/;\"\tf\tline:92\tpackage:procs\tsignature:(a, b: int)\tend:94\nspaced\tinput.odin\t/^spaced :: proc(a: int ) -> int {$/;\"\tf\tline:96\tpackage:procs\tsignature:(a: int)\tend:98\n"
  },
  {
    "path": "Units/parser-odin.r/odin-procs.d/input.odin",
    "content": "package procs\n\nimport \"core:strings\"\n\nComparator :: #type proc(x, y: int) -> int\n\ninit :: proc() {\n}\n\nvec2_add :: proc(x, y: f32) -> f32 {\n    return x + y\n}\n\ndiv_check :: proc(a: f32) -> (int, bool) {\n    return int(a), a > 0\n}\n\nwrite_bytes :: proc \"c\" (n: i32, data: rawptr) {\n}\n\nget_errno :: proc \"cdecl\" () -> i32 {\n    return 0\n}\n\nclamp_value :: proc(x: $T) -> T where T == int {\n    return x\n}\n\nadd_ints :: proc(a, b: int) -> int {return a + b}\nadd_floats :: proc(a, b: f32) -> f32 {return a + b}\nadd :: proc {\n    add_ints,\n    add_floats,\n}\n\nMy_Callback :: proc(x: int) -> bool\nLoader :: proc(path: string) -> ^u8\nalloc_buf :: proc(size: int, allocator := context.allocator) -> []u8 {\n    return nil\n}\nget_items :: proc() -> [dynamic]int {\n    return nil\n}\nmake_handler :: proc() -> proc(int) {\n    return nil\n}\nget_builder :: proc() -> strings.Builder {\n    return {}\n}\n\nget_lookup :: proc() -> map[string]int {\n    return nil\n}\n\nget_c_callback :: proc() -> proc \"c\" (i32) {\n    return nil\n}\n\nget_transform :: proc() -> proc(int) -> int {\n    return nil\n}\n\nget_checker :: proc() -> proc(int) -> (bool, int) {\n    return nil\n}\n\nget_simd :: proc() -> #simd[4]f32 {\n    return {}\n}\n\nNumber :: struct($T: typeid) { val: T }\nget_number :: proc() -> Number(int) {\n    return {}\n}\n\nfoo_no_alias :: proc(#no_alias a, b: ^int) {}\n\nprint_caller_location :: proc(loc := #caller_location) {}\n\noptional_result :: proc(x: int) -> (value: int, ok: bool) #optional_ok {\n    return x, true\n}\n\nproc_no_type_assert :: proc(a: any) -> int #no_type_assert {\n    return 0\n}\n\napply :: proc(f: proc(int) -> int, x: int) -> int {\n    return f(x)\n}\n\nadd_inline :: #force_inline proc(a, b: int) -> int {\n    return a + b\n}\n\nspaced :: proc(a: int ) -> int {\n    return a\n}\n"
  },
  {
    "path": "Units/parser-odin.r/odin-scope.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n"
  },
  {
    "path": "Units/parser-odin.r/odin-scope.d/expected.tags",
    "content": "scope\tinput.odin\t/^package scope$/;\"\tp\nPoint\tinput.odin\t/^Point :: struct {$/;\"\ts\tpackage:scope\nscope.Point\tinput.odin\t/^Point :: struct {$/;\"\ts\tpackage:scope\nx\tinput.odin\t/^    x: f32,$/;\"\tm\tstruct:scope.Point\nscope.Point.x\tinput.odin\t/^    x: f32,$/;\"\tm\tstruct:scope.Point\ny\tinput.odin\t/^    y: f32,$/;\"\tm\tstruct:scope.Point\nscope.Point.y\tinput.odin\t/^    y: f32,$/;\"\tm\tstruct:scope.Point\nColor\tinput.odin\t/^Color :: enum {$/;\"\te\tpackage:scope\nscope.Color\tinput.odin\t/^Color :: enum {$/;\"\te\tpackage:scope\nRed\tinput.odin\t/^    Red,$/;\"\tn\tenum:scope.Color\nscope.Color.Red\tinput.odin\t/^    Red,$/;\"\tn\tenum:scope.Color\nGreen\tinput.odin\t/^    Green,$/;\"\tn\tenum:scope.Color\nscope.Color.Green\tinput.odin\t/^    Green,$/;\"\tn\tenum:scope.Color\nBlue\tinput.odin\t/^    Blue,$/;\"\tn\tenum:scope.Color\nscope.Color.Blue\tinput.odin\t/^    Blue,$/;\"\tn\tenum:scope.Color\norigin\tinput.odin\t/^origin :: proc() -> Point {$/;\"\tf\tpackage:scope\nscope.origin\tinput.odin\t/^origin :: proc() -> Point {$/;\"\tf\tpackage:scope\n"
  },
  {
    "path": "Units/parser-odin.r/odin-scope.d/input.odin",
    "content": "package scope\n\nPoint :: struct {\n    x: f32,\n    y: f32,\n}\n\nColor :: enum {\n    Red,\n    Green,\n    Blue,\n}\n\norigin :: proc() -> Point {\n    return Point{0, 0}\n}\n"
  },
  {
    "path": "Units/parser-odin.r/odin-structs.d/args.ctags",
    "content": "--sort=no\n--fields=+neK\n"
  },
  {
    "path": "Units/parser-odin.r/odin-structs.d/expected.tags",
    "content": "structs\tinput.odin\t/^package structs$/;\"\tpackage\tline:1\nPoint\tinput.odin\t/^Point :: struct {$/;\"\tstruct\tline:3\tpackage:structs\tend:5\nx\tinput.odin\t/^    x, y: f32,$/;\"\tmember\tline:4\tstruct:structs.Point\ny\tinput.odin\t/^    x, y: f32,$/;\"\tmember\tline:4\tstruct:structs.Point\nColor\tinput.odin\t/^Color :: struct #packed {$/;\"\tstruct\tline:7\tpackage:structs\tend:9\nr\tinput.odin\t/^    r, g, b, a: u8,$/;\"\tmember\tline:8\tstruct:structs.Color\ng\tinput.odin\t/^    r, g, b, a: u8,$/;\"\tmember\tline:8\tstruct:structs.Color\nb\tinput.odin\t/^    r, g, b, a: u8,$/;\"\tmember\tline:8\tstruct:structs.Color\na\tinput.odin\t/^    r, g, b, a: u8,$/;\"\tmember\tline:8\tstruct:structs.Color\nEntity\tinput.odin\t/^Entity :: struct {$/;\"\tstruct\tline:11\tpackage:structs\tend:14\npos\tinput.odin\t/^    using pos: ^Point,$/;\"\tmember\tline:12\tstruct:structs.Entity\nname\tinput.odin\t/^    name:      string,$/;\"\tmember\tline:13\tstruct:structs.Entity\nGeneric_Pair\tinput.odin\t/^Generic_Pair :: struct($T: typeid) {$/;\"\tstruct\tline:16\tpackage:structs\tend:19\nfirst\tinput.odin\t/^    first:  T,$/;\"\tmember\tline:17\tstruct:structs.Generic_Pair\nsecond\tinput.odin\t/^    second: T,$/;\"\tmember\tline:18\tstruct:structs.Generic_Pair\nAligned\tinput.odin\t/^Aligned :: struct #align(8) {$/;\"\tstruct\tline:21\tpackage:structs\tend:24\nval\tinput.odin\t/^    val: i32,$/;\"\tmember\tline:22\tstruct:structs.Aligned\ndata\tinput.odin\t/^    using data: [4]u8,$/;\"\tmember\tline:23\tstruct:structs.Aligned\nEngine\tinput.odin\t/^Engine :: struct {$/;\"\tstruct\tline:26\tpackage:structs\tend:41\ntitle\tinput.odin\t/^    title:      string,$/;\"\tmember\tline:27\tstruct:structs.Engine\nresolution\tinput.odin\t/^    resolution: [2]f32,$/;\"\tmember\tline:28\tstruct:structs.Engine\ndebug\tinput.odin\t/^    debug:      bool,$/;\"\tmember\tline:29\tstruct:structs.Engine\nfonts\tinput.odin\t/^    fonts:      struct {$/;\"\tmember\tline:30\tstruct:structs.Engine\nmetrics\tinput.odin\t/^    metrics:    struct {$/;\"\tmember\tline:34\tstruct:structs.Engine\n_\tinput.odin\t/^    _:          struct {$/;\"\tmember\tline:38\tstruct:structs.Engine\n"
  },
  {
    "path": "Units/parser-odin.r/odin-structs.d/input.odin",
    "content": "package structs\n\nPoint :: struct {\n    x, y: f32,\n}\n\nColor :: struct #packed {\n    r, g, b, a: u8,\n}\n\nEntity :: struct {\n    using pos: ^Point,\n    name:      string,\n}\n\nGeneric_Pair :: struct($T: typeid) {\n    first:  T,\n    second: T,\n}\n\nAligned :: struct #align(8) {\n    val: i32,\n    using data: [4]u8,\n}\n\nEngine :: struct {\n    title:      string,\n    resolution: [2]f32,\n    debug:      bool,\n    fonts:      struct {\n        small:  rawptr,\n        medium: rawptr,\n    },\n    metrics:    struct {\n        fps_current: f32,\n        frame_count: u32,\n    },\n    _:          struct {\n        reserved: [8]u8,\n    },\n}\n"
  },
  {
    "path": "Units/parser-odin.r/odin-types.d/args.ctags",
    "content": "--sort=no\n--fields=+neK\n"
  },
  {
    "path": "Units/parser-odin.r/odin-types.d/expected.tags",
    "content": "types\tinput.odin\t/^package types$/;\"\tpackage\tline:1\nMeter\tinput.odin\t/^Meter :: distinct f64$/;\"\ttype\tline:3\tpackage:types\nHandle\tinput.odin\t/^Handle :: distinct rawptr$/;\"\ttype\tline:4\tpackage:types\nRef\tinput.odin\t/^Ref :: u8$/;\"\ttype\tline:6\tpackage:types\nLookup\tinput.odin\t/^Lookup :: map[string]int$/;\"\ttype\tline:7\tpackage:types\nDays\tinput.odin\t/^Days :: enum {$/;\"\tenum\tline:9\tpackage:types\tend:17\nMon\tinput.odin\t/^    Mon,$/;\"\tenumerator\tline:10\tenum:types.Days\nTue\tinput.odin\t/^    Tue,$/;\"\tenumerator\tline:11\tenum:types.Days\nWed\tinput.odin\t/^    Wed,$/;\"\tenumerator\tline:12\tenum:types.Days\nThu\tinput.odin\t/^    Thu,$/;\"\tenumerator\tline:13\tenum:types.Days\nFri\tinput.odin\t/^    Fri,$/;\"\tenumerator\tline:14\tenum:types.Days\nSat\tinput.odin\t/^    Sat,$/;\"\tenumerator\tline:15\tenum:types.Days\nSun\tinput.odin\t/^    Sun,$/;\"\tenumerator\tline:16\tenum:types.Days\nDay_Set\tinput.odin\t/^Day_Set :: bit_set[Days]$/;\"\ttype\tline:19\tpackage:types\nFlags\tinput.odin\t/^Flags :: bit_field u16 {$/;\"\ttype\tline:21\tpackage:types\tend:25\nx\tinput.odin\t/^    x: i32  | 3,$/;\"\tmember\tline:22\ttype:types.Flags\ny\tinput.odin\t/^    y: u16  | 5,$/;\"\tmember\tline:23\ttype:types.Flags\nz\tinput.odin\t/^    z: bool | 1,$/;\"\tmember\tline:24\ttype:types.Flags\nVec3\tinput.odin\t/^Vec3 :: [3]f32$/;\"\ttype\tline:27\tpackage:types\nPtr_Int\tinput.odin\t/^Ptr_Int :: ^int$/;\"\ttype\tline:28\tpackage:types\nId_Map\tinput.odin\t/^Id_Map :: distinct map[string]int$/;\"\ttype\tline:30\tpackage:types\nTile_Row\tinput.odin\t/^Tile_Row :: distinct [16]u8$/;\"\ttype\tline:31\tpackage:types\nPtr_Handle\tinput.odin\t/^Ptr_Handle :: distinct ^u8$/;\"\ttype\tline:32\tpackage:types\nKey\tinput.odin\t/^Key :: enum {$/;\"\tenum\tline:33\tpackage:types\tend:37\nBronze\tinput.odin\t/^    Bronze =  1,$/;\"\tenumerator\tline:34\tenum:types.Key\nSilver\tinput.odin\t/^    Silver =  5,$/;\"\tenumerator\tline:35\tenum:types.Key\nGold\tinput.odin\t/^    Gold   = 10,$/;\"\tenumerator\tline:36\tenum:types.Key\nKey_Descriptions\tinput.odin\t/^Key_Descriptions :: #sparse[Key]string {$/;\"\ttype\tline:38\tpackage:types\nINIT_VALUE\tinput.odin\t/^INIT_VALUE :: (100 + 200)$/;\"\tconst\tline:44\tpackage:types\n"
  },
  {
    "path": "Units/parser-odin.r/odin-types.d/input.odin",
    "content": "package types\n\nMeter :: distinct f64\nHandle :: distinct rawptr\n\nRef :: u8\nLookup :: map[string]int\n\nDays :: enum {\n    Mon,\n    Tue,\n    Wed,\n    Thu,\n    Fri,\n    Sat,\n    Sun,\n}\n\nDay_Set :: bit_set[Days]\n\nFlags :: bit_field u16 {\n    x: i32  | 3,\n    y: u16  | 5,\n    z: bool | 1,\n}\n\nVec3 :: [3]f32\nPtr_Int :: ^int\n\nId_Map :: distinct map[string]int\nTile_Row :: distinct [16]u8\nPtr_Handle :: distinct ^u8\nKey :: enum {\n    Bronze =  1,\n    Silver =  5,\n    Gold   = 10,\n}\nKey_Descriptions :: #sparse[Key]string {\n    .Bronze = \"a blocky bronze key\",\n    .Silver = \"a shiny silver key\",\n    .Gold   = \"a glittering gold key\",\n}\n\nINIT_VALUE :: (100 + 200)\n"
  },
  {
    "path": "Units/parser-odin.r/odin-unions.d/args.ctags",
    "content": "--sort=no\n--fields=+neK\n"
  },
  {
    "path": "Units/parser-odin.r/odin-unions.d/expected.tags",
    "content": "unions\tinput.odin\t/^package unions$/;\"\tpackage\tline:1\nValue\tinput.odin\t/^Value :: union {$/;\"\tunion\tline:3\tpackage:unions\tend:8\nNon_Nil\tinput.odin\t/^Non_Nil :: union #no_nil {$/;\"\tunion\tline:10\tpackage:unions\tend:13\nResult\tinput.odin\t/^Result :: union($T: typeid) {$/;\"\tunion\tline:15\tpackage:unions\tend:18\n"
  },
  {
    "path": "Units/parser-odin.r/odin-unions.d/input.odin",
    "content": "package unions\n\nValue :: union {\n    bool,\n    i32,\n    f32,\n    string,\n}\n\nNon_Nil :: union #no_nil {\n    int,\n    string,\n}\n\nResult :: union($T: typeid) {\n    T,\n    string,\n}\n"
  },
  {
    "path": "Units/parser-odin.r/odin-vars-consts.d/args.ctags",
    "content": "--sort=no\n--fields=+K\n"
  },
  {
    "path": "Units/parser-odin.r/odin-vars-consts.d/expected.tags",
    "content": "vars\tinput.odin\t/^package vars$/;\"\tpackage\nPI\tinput.odin\t/^PI :: 3.14159$/;\"\tconst\tpackage:vars\nMAX_BUFFER_SIZE\tinput.odin\t/^MAX_BUFFER_SIZE :: 1024$/;\"\tconst\tpackage:vars\nDEFAULT_PROMPT\tinput.odin\t/^DEFAULT_PROMPT :: \">\"$/;\"\tconst\tpackage:vars\ninitial_capacity\tinput.odin\t/^initial_capacity: int : 42$/;\"\tconst\tpackage:vars\nlog_level\tinput.odin\t/^log_level: int = 10$/;\"\tvar\tpackage:vars\nframe_count\tinput.odin\t/^frame_count := 20$/;\"\tvar\tpackage:vars\nwidth\tinput.odin\t/^width, height, depth := 1, 2, 3$/;\"\tvar\tpackage:vars\nheight\tinput.odin\t/^width, height, depth := 1, 2, 3$/;\"\tvar\tpackage:vars\ndepth\tinput.odin\t/^width, height, depth := 1, 2, 3$/;\"\tvar\tpackage:vars\nhandler\tinput.odin\t/^handler: proc(i32) = nil$/;\"\tvar\tpackage:vars\nHALF\tinput.odin\t/^HALF :: 1024 \\/ 2$/;\"\tconst\tpackage:vars\nENABLE_DEBUG\tinput.odin\t/^ENABLE_DEBUG :: #config(ENABLE_DEBUG, false)$/;\"\tconst\tpackage:vars\na\tinput.odin\t/^a := 1; b := 2$/;\"\tvar\tpackage:vars\nb\tinput.odin\t/^a := 1; b := 2$/;\"\tvar\tpackage:vars\n"
  },
  {
    "path": "Units/parser-odin.r/odin-vars-consts.d/input.odin",
    "content": "package vars\n\nPI :: 3.14159\nMAX_BUFFER_SIZE :: 1024\nDEFAULT_PROMPT :: \">\"\n\ninitial_capacity: int : 42\n\nlog_level: int = 10\nframe_count := 20\nwidth, height, depth := 1, 2, 3\n\n_ := 99\n\nhandler: proc(i32) = nil\n\nHALF :: 1024 / 2\n\nENABLE_DEBUG :: #config(ENABLE_DEBUG, false)\n\na := 1; b := 2\n"
  },
  {
    "path": "Units/parser-odin.r/odin-when.d/args.ctags",
    "content": "--sort=no\n--fields=+K\n"
  },
  {
    "path": "Units/parser-odin.r/odin-when.d/expected.tags",
    "content": "when_test\tinput.odin\t/^package when_test$/;\"\tpackage\nPATH_SEP\tinput.odin\t/^    PATH_SEP :: \"\\\\\\\\\"$/;\"\tconst\tpackage:when_test\nplatform_init\tinput.odin\t/^    platform_init :: proc() {}$/;\"\tproc\tpackage:when_test\nPATH_SEP\tinput.odin\t/^    PATH_SEP :: \"\\/\"$/;\"\tconst\tpackage:when_test\nplatform_init\tinput.odin\t/^    platform_init :: proc() {}$/;\"\tproc\tpackage:when_test\nPATH_SEP\tinput.odin\t/^    PATH_SEP :: \"\\/\"$/;\"\tconst\tpackage:when_test\nplatform_init\tinput.odin\t/^    platform_init :: proc() {}$/;\"\tproc\tpackage:when_test\nARCH_64\tinput.odin\t/^    ARCH_64 :: true$/;\"\tconst\tpackage:when_test\nWORD_SIZE\tinput.odin\t/^    WORD_SIZE :: 8$/;\"\tconst\tpackage:when_test\n"
  },
  {
    "path": "Units/parser-odin.r/odin-when.d/input.odin",
    "content": "package when_test\n\nwhen ODIN_OS == .Windows {\n    PATH_SEP :: \"\\\\\"\n    platform_init :: proc() {}\n} else when ODIN_OS == .Linux {\n    PATH_SEP :: \"/\"\n    platform_init :: proc() {}\n} else {\n    PATH_SEP :: \"/\"\n    platform_init :: proc() {}\n}\n\nwhen size_of(rawptr) == 8 {\n    ARCH_64 :: true\n}\n\nwhen #config(ENABLE_EXTRAS, false) {\n    WORD_SIZE :: 8\n}\n"
  },
  {
    "path": "Units/parser-openapi.r/broken-input.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-openapi.r/broken-input.d/args.ctags",
    "content": "--language-force=OpenAPI\n"
  },
  {
    "path": "Units/parser-openapi.r/broken-input.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-openapi.r/broken-input.d/input.yml",
    "content": "f: x\n    y:\n"
  },
  {
    "path": "Units/parser-openapi.r/crash-test.d/README",
    "content": "This is a crash test.\nThe code is derived from puppet/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/data/bad.yaml.\n\n    REPO=https://github.com/puppetlabs/puppet.git\n    ALIGNMENT=6.2.0\n    LANGUAGES=Ruby,PuppetManifest\n"
  },
  {
    "path": "Units/parser-openapi.r/crash-test.d/input.yml",
    "content": "{x:\n"
  },
  {
    "path": "Units/parser-openapi.r/openapi.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-openapi.r/openapi.d/expected.tags",
    "content": "test\tinput.yaml\t/^    title: test$/;\"\tt\nhttp://example.com\tinput.yaml\t/^  - url: http:\\/\\/example.com$/;\"\ts\n/sample/path\tinput.yaml\t/^    \\/sample\\/path:$/;\"\tp\n/sample/other/path\tinput.yaml\t/^    \\/sample\\/other\\/path:$/;\"\tp\nNullableField\tinput.yaml\t/^        NullableField:$/;\"\td\nNullableFieldStringEnum\tinput.yaml\t/^        NullableFieldStringEnum:$/;\"\td\nCustomHeader\tinput.yaml\t/^        CustomHeader:$/;\"\tP\nResponse1\tinput.yaml\t/^        Response1:$/;\"\tR\nResponse2\tinput.yaml\t/^        Response2:$/;\"\tR\nandroid_handler\tinput.yaml\t/^  - name: android_handler$/;\"\tT\nios_handler\tinput.yaml\t/^  - name: ios_handler$/;\"\tT\n"
  },
  {
    "path": "Units/parser-openapi.r/openapi.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-openapi.r/openapi.d/input.yaml",
    "content": "openapi: 3.0.0\ninfo:\n    title: test\n    description: test\n    version: '1.0'\n\nservers:\n  - url: http://example.com\n    description: production\n\npaths:\n    /sample/path:\n        get:\n            summary: simple handler\n            responses: {}\n\n    /sample/other/path:\n        get:\n            responses: {}\n        post:\n            summary: xxx\n            responses: {}\n\ncomponents:\n    schemas:\n        NullableField:\n            type: object\n            properties: {}\n        NullableFieldStringEnum:\n            type: object\n            properties: {}\n\n    parameters:\n        CustomHeader:\n            in: header\n            name: X-Custom-Header\n            required: false\n            schema:\n                type: string\n\n    responses:\n        Response1:\n            description: Payment Required\n            content:\n                application/json:\n                    schema:\n                        type: object\n                        properties: {}\n        Response2:\n            description: smth 2\n            content:\n                application/json:\n                    schema:\n                        type: object\n                        properties: {}\n\ntags:\n  - name: android_handler\n    description: Handler for Android clients\n  - name: ios_handler\n    description: Handler for iOS clients\n"
  },
  {
    "path": "Units/parser-openapi.r/swagger.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-openapi.r/swagger.d/expected.tags",
    "content": "test\tinput.yaml\t/^    title: test$/;\"\tt\nexample.com\tinput.yaml\t/^host: example.com$/;\"\ts\n/sample/path\tinput.yaml\t/^    \\/sample\\/path:$/;\"\tp\n/sample/other/path\tinput.yaml\t/^    \\/sample\\/other\\/path:$/;\"\tp\nPolymorphicString\tinput.yaml\t/^    PolymorphicString:$/;\"\td\nPolymorphicInteger\tinput.yaml\t/^    PolymorphicInteger:$/;\"\td\nParam1\tinput.yaml\t/^    Param1:$/;\"\tP\nParam2\tinput.yaml\t/^    Param2:$/;\"\tP\nResponse1\tinput.yaml\t/^    Response1:$/;\"\tR\nResponse2\tinput.yaml\t/^    Response2:$/;\"\tR\n"
  },
  {
    "path": "Units/parser-openapi.r/swagger.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-openapi.r/swagger.d/input.yaml",
    "content": "swagger: '2.0'\ninfo:\n    description: test\n    title: test\n    version: '1.0'\nhost: example.com\n\npaths:\n    /sample/path:\n        post:\n            description: test\n            responses:\n              200:\n                description: xxx\n\n    /sample/other/path:\n        get:\n            description: smth\n            responses:\n              200:\n                description: xxx\n\ndefinitions:\n    PolymorphicString:\n        type: object\n        required:\n          - type\n          - value\n        additionalProperties: false\n        properties:\n            type:\n                type: string\n            value:\n                type: string\n\n    PolymorphicInteger:\n        type: object\n        required:\n          - type\n          - value\n        additionalProperties: false\n        properties:\n            type:\n                type: string\n            value:\n                type: integer\n\nparameters:\n    Param1:\n        name: test1\n        in: query\n        type: boolean\n\n    Param2:\n        name: test2\n        in: query\n        type: boolean\n\nresponses:\n    Response1:\n        description: aaa\n\n    Response2:\n        description: bbb\n"
  },
  {
    "path": "Units/parser-org.r/simple-org.d/args.ctags",
    "content": "--extras=+g\n--sort=no\n--fields=+l\n"
  },
  {
    "path": "Units/parser-org.r/simple-org.d/expected.tags",
    "content": "my section 1\tinput.org\t/^* my section 1$/;\"\tp\tlanguage:Org\nR bloc1\tinput.org\t/^#+name: R bloc1$/;\"\td\tlanguage:Org\nmy section 2\tinput.org\t/^* my section 2$/;\"\tp\tlanguage:Org\npython  !\tinput.org\t/^** python  !$/;\"\tc\tlanguage:Org\npython ou Python\tinput.org\t/^** python ou Python$/;\"\tc\tlanguage:Org\npython bloc2\tinput.org\t/^#+NAME: python bloc2$/;\"\td\tlanguage:Org\nmyf\tinput.org\t/^myf <- function(x) {$/;\"\tf\tlanguage:R\nmyf\tinput.org\t/^def myf(x):$/;\"\tf\tlanguage:Python\nmyff\tinput.org\t/^def myff(x):$/;\"\tf\tlanguage:Python\n"
  },
  {
    "path": "Units/parser-org.r/simple-org.d/input.org",
    "content": "* my section 1\n#+name: R bloc1\n#+begin_src R :results none :session :exports code :comments org\nmyf <- function(x) {\nreturn(x*x)\n    }\n#+end_src\n* my section 2\n** python  !\n#+begin_src Python :results none :session :exports code :comments org\ndef myf(x):\n    return x\n#+end_src\n** python ou Python\n#+NAME: python bloc2\n#+begin_src python :results none :session :exports code :comments org\ndef myff(x):\n    return(x*x)\n#+end_src\n"
  },
  {
    "path": "Units/parser-pascal.r/bug612019.pas.t/expected.tags",
    "content": "Test1\tinput.pas\t/^    procedure Test1;$/;\"\tp\nTest2\tinput.pas\t/^    procedure  Test2;$/;\"\tp\nTest3\tinput.pas\t/^    procedure   Test3;$/;\"\tp\n"
  },
  {
    "path": "Units/parser-pascal.r/bug612019.pas.t/input.pas",
    "content": "(*\nBugs item #612019, was opened at 2002-09-20 15:29\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=612019&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Konstantin Stupnik (xecutor)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: pascal parser\n\nInitial Comment:\nIn attached sample there are some lines from tags file\ngenerated for object pascal sources.\nThere are some problems with this lines.\nGenerally speaking they are parsed incorrectly.\n*)\nunit a;\n\ninterface\ntype\n  TTest=class\n    procedure Test1;\n    procedure  Test2;\n    procedure   Test3;\n  end;\n\nimplementation\n\nend.\n"
  },
  {
    "path": "Units/parser-pascal.r/comment-after-keyword.d/expected.tags",
    "content": "Fun1\tinput.pas\t/^function {} Fun1: integer;$/;\"\tf\ttyperef:typename:integer\n"
  },
  {
    "path": "Units/parser-pascal.r/comment-after-keyword.d/input.pas",
    "content": "program hello;\n\nfunction {} Fun1: integer;\nbegin\n   Fun1 := 1;\nend;\n\nbegin\n   Fun1();\nend.\n"
  },
  {
    "path": "Units/parser-pascal.r/simple-pascal.d/args.ctags",
    "content": "--fields=+tS\n--sort=no\n"
  },
  {
    "path": "Units/parser-pascal.r/simple-pascal.d/expected.tags",
    "content": "helloproc\tinput.pas\t/^PROCEDURE helloproc(param1: STRING; param2: BYTE);$/;\"\tp\tsignature:(param1: STRING; param2: BYTE)\nmax\tinput.pas\t/^FUNCTION max(num1, num2: INTEGER): INTEGER;$/;\"\tf\ttyperef:typename:INTEGER\tsignature:(num1, num2: INTEGER)\nnoargs\tinput.pas\t/^FUNCTION noargs: STRING;$/;\"\tf\ttyperef:typename:STRING\tsignature:()\nemptyargs\tinput.pas\t/^FUNCTION emptyargs(): STRING;$/;\"\tf\ttyperef:typename:STRING\tsignature:()\n"
  },
  {
    "path": "Units/parser-pascal.r/simple-pascal.d/input.pas",
    "content": "PROGRAM hello;\n\nTYPE\n\tsimpletype = RECORD\n\t\t\t\t\tone: INTEGER;\n\t\t\t\t END;\n\n\nPROCEDURE helloproc(param1: STRING; param2: BYTE);\nBEGIN\n\twriteln('Hello World!');\nEND;\n\n\nFUNCTION max(num1, num2: INTEGER): INTEGER;\nVAR\n   result: INTEGER;\nBEGIN\n   if (num1 > num2) then\n      result := num1\n\n   else\n      result := num2;\n   max := result;\nEND;\n\n\nFUNCTION noargs: STRING;\nBEGIN\n   noargs := 'functon without arguments';\nEND;\n\nFUNCTION emptyargs(): STRING;\nBEGIN\n   emptyargs := 'functon without arguments';\nEND;\n\n\nVAR result : INTEGER;\nBEGIN\n\thelloproc('ignored', 1);\n\tresult := max(73, 42);\n\twriteln('Result: ', result);\nEND.\n"
  },
  {
    "path": "Units/parser-pascal.r/various-comments.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-pascal.r/various-comments.d/expected.tags",
    "content": "foo0\tinput.pas\t/^procedure foo0;$/;\"\tp\n"
  },
  {
    "path": "Units/parser-pascal.r/various-comments.d/input.pas",
    "content": "{ Derrived from https://wiki.freepascal.org/Procedure }\nprogram procedureDemo(input, output, stderr);\n\nvar\n   x: longint;\n\nprocedure foo0;\nbegin\n   inc(x);\nend;\n\n// procedure foo1;\n// begin\n//   inc(x);\n// end;\n\n{\nprocedure foo2;\nbegin\n   inc(x);\nend;\n}\n\n(*\nprocedure foo3;\nbegin\n   inc(x);\nend;\n*)\n\nbegin\n   x := 42;\n   foo0;\n   // foo1;\n   { foo2; }\n   (* foo3; *)\n   writeLn(x);\nend.\n"
  },
  {
    "path": "Units/parser-perl.r/bug612621.pl.d/expected.tags",
    "content": "bar\tinput.pl\t/^sub bar() $/;\"\ts\nfoo\tinput.pl\t/^sub foo {$/;\"\ts\n"
  },
  {
    "path": "Units/parser-perl.r/bug612621.pl.d/input.pl",
    "content": "=pod\nBugs item #612621, was opened at 2002-09-21 21:23\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=612621&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Richard Donkin (rdonkin)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: Perl POD syntax -> incomplete tags file\n\nInitial Comment:\nIn the following test file, ctags 5.2.3 (compiled from \nsource on Cygwin) only adds the first subroutine (bar) to \nthe tags file, when run using:\n\nctags --totals --\nlanguage-force=perl temp\n\n-----------------\n=cut\nsub bar() \n{\n\n    print \"blah\\n\";\n\n=for\n    print \"blah2\\n\";\n    # \nNote: next line has trailing space\n=cut \n\n\n}\n\nsub foo {\n    print \"hello\\n\";\n}\n=pod\nThe \ntags file looks like \nthis:\n!_TAG_FILE_FORMAT\t2\t/extended format; -- format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted/\n!_TAG_PROGRAM_AUTHOR\tDarren Hiebert\t/dhiebert@users.sourceforge.net/\n!_TAG_PROGRAM_NAME\tExuberant Ctags\t//\n!_TAG_PROGRAM_URL\thttp://ctags.sourceforge.net\t/official site/\n!_TAG_PROGRAM_VERSION\t5.2.3\t//\nbar\ttemp\t/^sub bar() {$/;\"\ts\n\nThe workaround is to delete the \ntrailing space at the end of the '=cut' line.\n\n=cut\n"
  },
  {
    "path": "Units/parser-perl.r/bug842077.pl.d/args.ctags",
    "content": "--kinds-Perl=+h\n"
  },
  {
    "path": "Units/parser-perl.r/bug842077.pl.d/expected.tags",
    "content": "EOM\tinput.pl\t/^$this->print_log(<<EOM);$/;\"\th\ntest\tinput.pl\t/^sub test {$/;\"\ts\n"
  },
  {
    "path": "Units/parser-perl.r/bug842077.pl.d/input.pl",
    "content": "# Bugs item #842077, was opened at 2003-11-14 10:57\n# Message generated for change (Tracker Item Submitted) made by Item Submitter\n# You can respond by visiting: \n# https://sourceforge.net/tracker/?func=detail&atid=106556&aid=842077&group_id=6556\n\n# Category: None\n# Group: None\n# Status: Open\n# Resolution: None\n# Priority: 5\n# Submitted By: Christian Reis (kiko_async)\n# Assigned to: Nobody/Anonymous (nobody)\n# Summary: wrong precedence applied to perl POD and \"here document\"\n\n# Initial Comment:\n# Basically, ctags stops parsing when it reaches code\n# with the syntax below:\n\n# ...\n$this->print_log(<<EOM);\n== Tinderbox Info\n...\n== End Tinderbox Client Info\nEOM\n# ...\n\nsub test {\n# This subroutine is missed when bug is present.\n}\n\n# It sounds to me like ctags thinks it's a POD comment\n# when it\n# isn't--wrong precedence of POD vs. here document.\n"
  },
  {
    "path": "Units/parser-perl.r/curly-bracket.d/expected.tags",
    "content": "X\tinput.pl\t/^{  package X;$/;\"\tp\nfoo\tinput.pl\t/^}  sub foo { return 42 }$/;\"\ts\n"
  },
  {
    "path": "Units/parser-perl.r/curly-bracket.d/input.pl",
    "content": "{  package X;\n}  sub foo { return 42 }\n"
  },
  {
    "path": "Units/parser-perl.r/format.pl.d/expected.tags",
    "content": "STDOUT\tinput.pl\t/^format =$/;\"\tf\nXYZ\tinput.pl\t/^format XYZ =$/;\"\tf\n"
  },
  {
    "path": "Units/parser-perl.r/format.pl.d/input.pl",
    "content": "# Test format tag generation.\n\nformat XYZ =\n@<<< @>>>\n\"1\", \"a\"\n.\n\nformat =\n    @>>>\n24\n.\n\nwrite;\n$~ = XYZ;\nwrite;\n"
  },
  {
    "path": "Units/parser-perl.r/no-heredoc.d/args.ctags",
    "content": "--sort=no\n--kinds-Perl=+{heredoc}\n"
  },
  {
    "path": "Units/parser-perl.r/no-heredoc.d/expected.tags",
    "content": "f0tag\tinput.pl\t/^sub f0tag() {}$/;\"\ts\nf1tag\tinput.pl\t/^sub f1tag() {}$/;\"\ts\nf2tag\tinput.pl\t/^sub f2tag() {}$/;\"\ts\nf3tag\tinput.pl\t/^sub f3tag() {}$/;\"\ts\nhereodc0tag\tinput.pl\t/^print 'cat <<<heredoct0notag' . <<hereodc0tag;$/;\"\th\nf4tag\tinput.pl\t/^sub f4tag() {}$/;\"\ts\nhereodc1tag\tinput.pl\t/^print \"cat <<<heredoct1notag\" . <<hereodc1tag;$/;\"\th\nf5tag\tinput.pl\t/^sub f5tag() {}$/;\"\ts\nhereodc2tag\tinput.pl\t/^print `cat <<<heredoct1notag` . <<hereodc2tag;$/;\"\th\nf6tag\tinput.pl\t/^sub f6tag() {}$/;\"\ts\nheredoc3tag\tinput.pl\t/^print \"abc\" . <<heredoc3tag . 'efg' . << \"heredoc4tag\" . `ls` . '<<hereodc5notag';$/;\"\th\nheredoc4tag\tinput.pl\t/^print \"abc\" . <<heredoc3tag . 'efg' . << \"heredoc4tag\" . `ls` . '<<hereodc5notag';$/;\"\th\nf7tag\tinput.pl\t/^sub f7tag() {}$/;\"\ts\nf8tag\tinput.pl\t/^sub f8tag() {}$/;\"\ts\nf9tag\tinput.pl\t/^sub f9tag() {}$/;\"\ts\nfive_sub\tinput-0.pl\t/^sub five_sub() {$/;\"\ts\nfive_mark0\tinput-0.pl\t/^print 3 + 2 . <<five_mark0;$/;\"\th\nfive_mark1\tinput-0.pl\t/^print 3 + 2 . <<~five_mark1;$/;\"\th\nfive_mark2\tinput-0.pl\t/^print 3 + 2 . << \"five_mark2\";$/;\"\th\n"
  },
  {
    "path": "Units/parser-perl.r/no-heredoc.d/input-0.pl",
    "content": "print 3 + 2 <<5;\n5\n    ;\n\nsub five_sub() {\n    return 5\n}\nprint 3 + 2 << five_sub;\nfive\n    ;\n\nprint 3 + 2 . <<five_mark0;\na\nfive_mark0\n\nprint 3 + 2 . <<~five_mark1;\na\nfive_mark1\n\nprint 3 + 2 << ~five_sub;\nfive_sub;\n\nprint 3 + 2 . << \"five_mark2\";\n\tox\nfive_mark2\n\n\n\n\n\n\n"
  },
  {
    "path": "Units/parser-perl.r/no-heredoc.d/input.pl",
    "content": "# Derrived from #3588 submitted by @petdance\n\nsub f0tag() {}\n\nmy $x = '<<NOT_A_HEREDOC0';\n\nsub f1tag() {}\n\nprint \"<<NOT_A_HEREDOC0\\n\";\n\nsub f2tag() {}\n\nprint `cat <<<BASH_HERE_STRING`;\n\nsub f3tag() {}\n\nprint 'cat <<<heredoct0notag' . <<hereodc0tag;\nsub f0notag() {}\nhereodc0tag\n\nsub f4tag() {}\n\nprint \"cat <<<heredoct1notag\" . <<hereodc1tag;\nsub f1notag() {}\nhereodc1tag\n\nsub f5tag() {}\n\nprint `cat <<<heredoct1notag` . <<hereodc2tag;\nsub f2notag() {}\nhereodc2tag\n\nsub f6tag() {}\n\nprint \"abc\" . <<heredoc3tag . 'efg' . << \"heredoc4tag\" . `ls` . '<<hereodc5notag';\nsub f3notag() {}\nheredoc3tag\nsub f4notag() {}\nheredoc4tag\nsub f7tag() {}\n\nsub f8tag() {}\n\nmy $i = 1;\nprint \"a\" . 3 << $i;\n\nsub f9tag() {}\n"
  },
  {
    "path": "Units/parser-perl.r/package.pm.d/expected.tags",
    "content": "CONST\tinput.pm\t/^CONST => 1;$/;\"\tc\nEND\tinput.pm\t/^END:$/;\"\tl\nEND2\tinput.pm\t/^END2  :$/;\"\tl\nTest\tinput.pm\t/^package Test;$/;\"\tp\nTest::One\tinput.pm\t/^package Test::One;$/;\"\tp\nTest::One::Two\tinput.pm\t/^package Test::One::Two;$/;\"\tp\ndude\tinput.pm\t/^dude$/;\"\ts\ninit\tinput.pm\t/^ init {$/;\"\ts\nquo\tinput.pm\t/^sub quo {$/;\"\ts\n"
  },
  {
    "path": "Units/parser-perl.r/package.pm.d/input.pm",
    "content": "# This file is intended to test package keyword support along with\n# multi-line subroutine definitions, like this:\n#   sub\n# \n#   somefunction\n#   {...\n\npackage Test::One;\n\npackage Test::One::Two;\n\npackage Test;\n\nuse strict;\nuse warnings;\n\nsub\n\n init {\n}\n\nuse constant\nCONST => 1;\n\n=head2 quo\n\nThis is 'quo' subroutine\n\n=cut\n\nsub quo;\n\nquo;\n\nTest::quo;\n\nsub quo {\n    goto END;\n    die;\nEND:\nEND2  :\n    print \"END!\\n\";\n    return;\n}\n\nsub xuz :lvalue;\n\nsub xtz (&@;$) :lvalue;\n  \nsub\n# This should create a tag\ndude\n{\n    1;\n}\n\n1;\n"
  },
  {
    "path": "Units/parser-perl.r/perl-autoloader.d/expected.tags",
    "content": "AL\tinput.pm\t/^package AL;$/;\"\tp\nxyz\tinput.pm\t/^sub xyz {$/;\"\ts\n"
  },
  {
    "path": "Units/parser-perl.r/perl-autoloader.d/input.pm",
    "content": "package AL;\n\nuse AutoLoader;\n\n$x = &xyz;\nprint \"hi: $x\\n\";\n\n1;\n\n__END__\n\nsub xyz {\n    return 1;\n}\n"
  },
  {
    "path": "Units/parser-perl.r/perl-module.d/args.ctags",
    "content": "--sort=no\n--fields=+rEn\n--extras=+r\n--kinds-Perl=+M\n"
  },
  {
    "path": "Units/parser-perl.r/perl-module.d/expected.tags",
    "content": "constant\tinput.pl\t/^use constant$/;\"\tM\tline:2\troles:used\textras:reference\nONE\tinput.pl\t/^ONE => 1;$/;\"\tc\tline:3\troles:def\ndiagnostics\tinput.pl\t/^use diagnostics;$/;\"\tM\tline:4\troles:used\textras:reference\ninteger\tinput.pl\t/^use integer;$/;\"\tM\tline:5\troles:used\textras:reference\nsigtrap\tinput.pl\t/^use sigtrap  qw(SEGV BUS);$/;\"\tM\tline:6\troles:used\textras:reference\nstrict\tinput.pl\t/^use strict   qw(subs vars refs);$/;\"\tM\tline:7\troles:used\textras:reference\nsubs\tinput.pl\t/^use subs     qw(afunc blurfl);$/;\"\tM\tline:8\troles:used\textras:reference\nwarnings\tinput.pl\t/^use warnings qw(all);$/;\"\tM\tline:9\troles:used\textras:reference\nsort\tinput.pl\t/^use sort     qw(stable _quicksort _mergesort);$/;\"\tM\tline:10\troles:used\textras:reference\ninteger\tinput.pl\t/^no integer;$/;\"\tM\tline:12\troles:unused\textras:reference\nstrict\tinput.pl\t/^no strict 'refs';$/;\"\tM\tline:13\troles:unused\textras:reference\nwarnings\tinput.pl\t/^no warnings;$/;\"\tM\tline:14\troles:unused\textras:reference\n5.006_001\tinput.pl\t/^use 5.006_001;$/;\"\tM\tline:16\troles:used\textras:reference\n5.006_001\tinput.pl\t/^no 5.006_001;$/;\"\tM\tline:17\troles:unused\textras:reference\n"
  },
  {
    "path": "Units/parser-perl.r/perl-module.d/input.pl",
    "content": "# Taken from https://perldoc.perl.org/functions/use.html\nuse constant\nONE => 1;\nuse diagnostics;\nuse integer;\nuse sigtrap  qw(SEGV BUS);\nuse strict   qw(subs vars refs);\nuse subs     qw(afunc blurfl);\nuse warnings qw(all);\nuse sort     qw(stable _quicksort _mergesort);\n\nno integer;\nno strict 'refs';\nno warnings;\n\nuse 5.006_001;\nno 5.006_001;\n"
  },
  {
    "path": "Units/parser-perl.r/perl-pod-after-end-no-guest.d/args.ctags",
    "content": "--extras=-g\n--fields=+l\n"
  },
  {
    "path": "Units/parser-perl.r/perl-pod-after-end-no-guest.d/expected.tags",
    "content": "data_do_nothing\tinput-1.pl\t/^sub data_do_nothing {$/;\"\ts\tlanguage:Perl\ndo_nothing\tinput.pl\t/^sub do_nothing {$/;\"\ts\tlanguage:Perl\n"
  },
  {
    "path": "Units/parser-perl.r/perl-pod-after-end-no-guest.d/input-1.pl",
    "content": "sub data_do_nothing {\n}\n\n__DATA__\n\nsub data_another_fn {\n}\n\n=head1 CAPTURE ME in DATA\n\n=cut\n"
  },
  {
    "path": "Units/parser-perl.r/perl-pod-after-end-no-guest.d/input.pl",
    "content": "sub do_nothing {\n}\n\n__END__\n\nsub another_fn {\n}\n\n=head1 CAPTURE ME\n\n=cut\n"
  },
  {
    "path": "Units/parser-perl.r/perl-pod-after-end.d/args.ctags",
    "content": "--extras=+g\n--fields=+l\n"
  },
  {
    "path": "Units/parser-perl.r/perl-pod-after-end.d/expected.tags",
    "content": "CAPTURE ME\tinput.pl\t/^=head1 CAPTURE ME$/;\"\tc\tlanguage:Pod\nCAPTURE ME in DATA\tinput-1.pl\t/^=head1 CAPTURE ME in DATA$/;\"\tc\tlanguage:Pod\ndata_do_nothing\tinput-1.pl\t/^sub data_do_nothing {$/;\"\ts\tlanguage:Perl\ndo_nothing\tinput.pl\t/^sub do_nothing {$/;\"\ts\tlanguage:Perl\n"
  },
  {
    "path": "Units/parser-perl.r/perl-pod-after-end.d/input-1.pl",
    "content": "sub data_do_nothing {\n}\n\n__DATA__\n\n=head1 CAPTURE ME in DATA\n\n=cut\n"
  },
  {
    "path": "Units/parser-perl.r/perl-pod-after-end.d/input.pl",
    "content": "sub do_nothing {\n}\n\n__END__\n\n=head1 CAPTURE ME\n\n=cut\n"
  },
  {
    "path": "Units/parser-perl.r/perl-selfloader.d/expected.tags",
    "content": "SL\tinput.pm\t/^package SL;$/;\"\tp\nxyz\tinput.pm\t/^sub xyz {$/;\"\ts\n"
  },
  {
    "path": "Units/parser-perl.r/perl-selfloader.d/input.pm",
    "content": "package SL;\n\nuse SelfLoader;\n\n$x = &xyz;\nprint \"hi: $x\\n\";\n\n1;\n\n__DATA__\n\nsub xyz {\n    return 1;\n}\n"
  },
  {
    "path": "Units/parser-perl.r/perl-two-line-package.d/args.ctags",
    "content": "--extras=q\n"
  },
  {
    "path": "Units/parser-perl.r/perl-two-line-package.d/expected.tags",
    "content": "AL\tinput.pm\t/^    AL;$/;\"\tp\nAL::wild_thing\tinput.pm\t/^sub wild_thing {$/;\"\ts\nPeggy\tinput.pm\t/^Peggy$/;\"\tp\nPeggy::eat_bonbons\tinput.pm\t/^sub eat_bonbons {$/;\"\ts\neat_bonbons\tinput.pm\t/^sub eat_bonbons {$/;\"\ts\nwild_thing\tinput.pm\t/^sub wild_thing {$/;\"\ts\n"
  },
  {
    "path": "Units/parser-perl.r/perl-two-line-package.d/input.pm",
    "content": "# This test case is for package declarations that span two lines.\n\npackage\n    AL;\n\nsub wild_thing {\n}\n\npackage\nPeggy\n;\n\nsub eat_bonbons {\n}\n\n1;\n"
  },
  {
    "path": "Units/parser-perl.r/simple.pl.d/args.ctags",
    "content": "--extras=+gq\n--fields=+l\n"
  },
  {
    "path": "Units/parser-perl.r/simple.pl.d/expected.tags",
    "content": "A\tinput.pl\t/^use constant A => 3;$/;\"\tc\tlanguage:Perl\nA::B\tinput.pl\t/^package A::B;$/;\"\tp\tlanguage:Perl\nA::B::A\tinput.pl\t/^use constant A => 3;$/;\"\tc\tlanguage:Perl\nA::B::MySub\tinput.pl\t/^sub MySub {}$/;\"\ts\tlanguage:Perl\nLABEL\tinput.pl\t/^LABEL:$/;\"\tl\tlanguage:Perl\nMySub\tinput.pl\t/^sub MySub {}$/;\"\ts\tlanguage:Perl\nNAME\tinput.pl\t/^=head1 NAME$/;\"\tc\tlanguage:Pod\n"
  },
  {
    "path": "Units/parser-perl.r/simple.pl.d/input.pl",
    "content": "=encoding utf-8\n\nSome more stuff to ignore\n\n  sub foo {\n      ...\n  }\n\n=cut\n\n=head1 NAME\nSome stuff to ignore\npackage NotAPackage;\nsub NotASub {}\n=cut\npackage A::B;\nsub MySub {}\nuse constant A => 3;\nLABEL:\n__END__\nsub IgnoreSub {}\n"
  },
  {
    "path": "Units/parser-perl.r/skip-heredoc.d/args.ctags",
    "content": "--sort=no\n--fields=+enr\n--extras=+r\n--kinds-Perl=*\n"
  },
  {
    "path": "Units/parser-perl.r/skip-heredoc.d/expected.tags",
    "content": "myfunc0\tinput.pl\t/^sub myfunc0$/;\"\ts\tline:1\troles:def\nfoo\tinput.pl\t/^   print <<\"foo\", <<~\\\\bar; # you can stack them$/;\"\th\tline:5\troles:def\tend:10\nbar\tinput.pl\t/^   print <<\"foo\", <<~\\\\bar; # you can stack them$/;\"\th\tline:5\troles:def\tend:15\nfoo\tinput.pl\t/^foo$/;\"\th\tline:10\troles:endmarker\nbar\tinput.pl\t/^    bar$/;\"\th\tline:15\troles:endmarker\nmyfunc3\tinput.pl\t/^sub myfunc3$/;\"\ts\tline:17\troles:def\nTHIS\tinput.pl\t/^   myfunc0(<< \"THIS\", 23, <<'THAT');$/;\"\th\tline:21\troles:def\tend:33\nTHAT\tinput.pl\t/^   myfunc0(<< \"THIS\", 23, <<'THAT');$/;\"\th\tline:21\troles:def\tend:41\nTHIS\tinput.pl\t/^THIS$/;\"\th\tline:33\troles:endmarker\nTHAT\tinput.pl\t/^THAT$/;\"\th\tline:41\troles:endmarker\nmyfunc9\tinput.pl\t/^sub myfunc9$/;\"\ts\tline:42\troles:def\nAB\"CD\tinput.pl\t/^myfunc0(<< \"AB\\\\\"CD\", << 'EF\\\\GH');$/;\"\th\tline:46\troles:def\tend:53\nEF\\\\GH\tinput.pl\t/^myfunc0(<< \"AB\\\\\"CD\", << 'EF\\\\GH');$/;\"\th\tline:46\troles:def\tend:59\nAB\"CD\tinput.pl\t/^AB\"CD$/;\"\th\tline:53\troles:endmarker\nEF\\\\GH\tinput.pl\t/^EF\\\\GH$/;\"\th\tline:59\troles:endmarker\nmyfunc12\tinput.pl\t/^sub myfunc12$/;\"\ts\tline:61\troles:def\nEND\tinput-0.pl\t/^(($argc == (1 << 0x1)) or ($argc >= (1<<1) and $opt_write)) or die <<END;$/;\"\th\tline:2\troles:def\tend:10\nEND\tinput-0.pl\t/^END$/;\"\th\tline:10\troles:endmarker\nfoo\tinput-0.pl\t/^sub foo {$/;\"\ts\tline:12\troles:def\n"
  },
  {
    "path": "Units/parser-perl.r/skip-heredoc.d/input-0.pl",
    "content": "# Derived from https://github.com/geany/geany/blob/master/scripts/fix-alignment.pl\n(($argc == (1 << 0x1)) or ($argc >= (1<<1) and $opt_write)) or die <<END;\nUsage:\n$scriptname sourcefile [>outfile]\n  Print formatted output to STDOUT or outfile.\n  Warning: do not use the same file for outfile.\n$scriptname -w sourcefile(s)\n  Writes to the file(s) in-place.\n  Warning: backup your file(s) first or use clean version control files.\nEND\n\nsub foo {\n    print \"hello\\n\";\n}\n"
  },
  {
    "path": "Units/parser-perl.r/skip-heredoc.d/input.pl",
    "content": "sub myfunc0\n{\n}\n\n   print <<\"foo\", <<~\\bar; # you can stack them\n    I said foo.\nsub myfunc1\n{\n}\nfoo\n    I said bar.\n    sub myfunc2\n    {\n    }\n    bar\n\nsub myfunc3\n{\n}\n\n   myfunc0(<< \"THIS\", 23, <<'THAT');\nsub myfunc4\n{\n}\nHere's a line\nsub myfunc5\n{\n}\nor two.\nsub myfunc6\n{\n}\nTHIS\nsub myfunc7\n{\n}\nand here's another.\nsub myfunc8\n{\n}\nTHAT\nsub myfunc9\n{\n}\n\nmyfunc0(<< \"AB\\\"CD\", << 'EF\\GH');\nlabel0:\nsub myfunc10\n{\nlabel1:\n}\nlabel2:\nAB\"CD\nsub myfunc11\n{\nlabel3:\n}\nlabel4:\nEF\\GH\n\nsub myfunc12\n{\n   print \"12\\n\";\n}\nmyfunc12();\n"
  },
  {
    "path": "Units/parser-php.r/anonymous_functions.php.d/expected.tags",
    "content": "_g\tinput.php\t/^$_g = 42;$/;\"\tv\na\tinput.php\t/^$a = function() {};$/;\"\tf\nb\tinput.php\t/^$b = function($x, $y) {};$/;\"\tf\nc\tinput.php\t/^$c = function() {$/;\"\tf\nd\tinput.php\t/^$d = function() {$/;\"\tf\ne\tinput.php\t/^$e = function&() {$/;\"\tf\nf\tinput.php\t/^$f = function&() use (&$_g) {$/;\"\tf\nf_sub\tinput.php\t/^  function f_sub() {}$/;\"\tf\tfunction:f\n"
  },
  {
    "path": "Units/parser-php.r/anonymous_functions.php.d/input.php",
    "content": "Tests for anonymous functions\n\nExpected output is\n\nfunctions:\n  a\n  b\n  c\n  d\n  e\n  f\n  f_sub [f]\n\nglobal variables:\n  _g\n\n<?php\n\n$a = function() {};\n\n$b = function($x, $y) {};\n\n/* return a value */\n$c = function() {\n  return 42;\n};\n\n/* return a function */\n$d = function() {\n  return function() {\n    return \"hello\";\n  };\n};\n\n/* return by reference */\n$_g = 42;\n$e = function&() {\n  global $_g;\n  return $_g;\n};\n\n$f = function&() use (&$_g) {\n  \n  function f_sub() {}\n  \n  return $_g;\n};\n"
  },
  {
    "path": "Units/parser-php.r/bug681824.php.d/expected.tags",
    "content": "db_query\tinput.php\t/^ function db_query$/;\"\tf\n"
  },
  {
    "path": "Units/parser-php.r/bug681824.php.d/input.php",
    "content": "<?php\n// Bugs item #681824, was opened at 2003-02-06 18:14\n// You can respond by visiting: \n// https://sourceforge.net/tracker/?func=detail&atid=106556&aid=681824&group_id=6556\n// \n// Category: None\n// Group: None\n// Status: Open\n// Resolution: None\n// Priority: 5\n// Submitted By: Thomi Dammann (thomi35)\n// Assigned to: Nobody/Anonymous (nobody)\n// Summary: Comments disturb ctags (v. 5.4)  scaning a PHP-file?\n// \n// Initial Comment:\n// If I have (correct) statements like\n// \n function db_query\n    ($pDB,\t\t\t\t// connection handle\n     $pQuery)\t\t  // query string\n  {\n...\n}\n// \n// it seems that ctags used with vim doesn't find the\n// function names anymore. I think that either the\n// comments or the distribution on more than one line\n// disturb the parser.\n// \n// Regards\n// \n// Thomi\n"
  },
  {
    "path": "Units/parser-php.r/classes.php.d/expected.tags",
    "content": "Bar\tinput.php\t/^class Bar {$/;\"\tc\nFoo\tinput.php\t/^class Foo {$/;\"\tc\n__construct\tinput.php\t/^\tfunction __construct () {$/;\"\tf\tclass:Bar\n__construct\tinput.php\t/^\tfunction __construct($a, $b) {$/;\"\tf\tclass:Foo\nmethod1\tinput.php\t/^\tfunction method1 () {$/;\"\tf\tclass:Bar\nmethod1\tinput.php\t/^\tfunction method1($arg) {$/;\"\tf\tclass:Foo\nmethod2\tinput.php\t/^\tfunction method2() {$/;\"\tf\tclass:Foo\n"
  },
  {
    "path": "Units/parser-php.r/classes.php.d/input.php",
    "content": "Expected output is\n\nclasses:\n\tBar\n\tFoo\n\nfunctions:\n\t__construct [Foo]\n\t__construct [Bar]\n\tmethod1 [Foo]\n\tmethod1 [Bar]\n\tmethod2 [Foo]\n\n<?php\n\nclass Foo {\n\tfunction __construct($a, $b) {\n\t\t// ...\n\t}\n\n\tfunction method1($arg) {\n\t\treturn 42;\n\t}\n\n\tfunction method2() {\n\t\t// ...\n\t}\n}\n\nclass Bar {\n\tfunction __construct () {\n\t\t/* ... */\n\t}\n\n\tfunction method1 () {\n\t\t// ...\n\t}\n}\n"
  },
  {
    "path": "Units/parser-php.r/combined.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+l\n"
  },
  {
    "path": "Units/parser-php.r/combined.d/expected.tags",
    "content": "paginate\tinput.php\t/^function paginate() {$/;\"\tf\tlanguage:PHP\nHome page\tinput.php\t/^<h1>Home page<\\/h1>$/;\"\th\tlanguage:HTML\nonload\tinput.php\t/^document.onload = function() {$/;\"\tf\tlanguage:JavaScript\tvariable:document\n"
  },
  {
    "path": "Units/parser-php.r/combined.d/input.php",
    "content": "<!DOCTYPE html>\n<head>\n<title><?= htmlspecialchars($title) ?></title>\n<script type=\"text/javascript\">\ndocument.onload = function() {\n  window.title += ' (fully loaded!)';\n}\n</script>\n</head>\n<body>\n\n<h1>Home page</h1>\n\n<?php\nfor ($entries as $entry) {\n  ?><h2><?= htmlspecialchars($entry['title']) ?></h2>\n  <p><?= htmlspecialchars($entry['body']) ?></p>\n  <div class=\"author\">By <?= htmlspecialchars($entry['author']) ?></div>\n<?php\n}\n\nfunction paginate() {\n  return $some_magic;\n}\n\npaginate($entries);\n?>\n</body>\n"
  },
  {
    "path": "Units/parser-php.r/coverage.d/args.ctags",
    "content": "--fields=+im\n"
  },
  {
    "path": "Units/parser-php.r/coverage.d/expected.tags",
    "content": "Acls1\tinput.php\t/^abstract class Acls1 {$/;\"\tc\timplementation:abstract\nAnonymousClass0314f3c80100\tinput.php\t/^$obj = new class(array(1, 2, 3), (1 + 2) * 3) {$/;\"\tc\nCls1\tinput.php\t/^class Cls1 extends Acls1 {$/;\"\tc\tinherits:Acls1\nWIDTH\tinput.php\t/^define('WIDTH', 36 * ((4 + 2) \\/ 3));$/;\"\td\n__construct\tinput.php\t/^  function __construct($a, $b) {$/;\"\tf\tclass:AnonymousClass0314f3c80100\n__construct\tinput.php\t/^  public function __construct ($args = null) {$/;\"\tf\tclass:Acls1\ncls1\tinput.php\t/^$cls1 = new Cls1();$/;\"\tv\nfunc1\tinput.php\t/^function func1($n, $c) {$/;\"\tf\nfunc2\tinput.php\t/^function func2($a, $b = ((4 + 1) * 2 - 4 \\/ 2)) {$/;\"\tf\nfunc3\tinput.php\t/^function func3($/;\"\tf\ttyperef:unknown:string\nname\tinput.php\t/^$$name = 'world';$/;\"\tv\nname\tinput.php\t/^$name = <<<NAME$/;\"\tv\nobj\tinput.php\t/^$obj = new class(array(1, 2, 3), (1 + 2) * 3) {$/;\"\tv\npresent\tinput.php\t/^  protected abstract function present($args);$/;\"\tf\tclass:Acls1\timplementation:abstract\npresent\tinput.php\t/^  protected function present($args) {$/;\"\tf\tclass:Cls1\nscisors\tinput.php\t/^function scisors($width) {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-php.r/coverage.d/input.php",
    "content": "<?php\n\n/* This is sample code just to exercise the parse a little, and cover most of\n * what it handles but other tests don't cover so we exercise most code paths.\n */\n\nfunction func1($n, $c) {\n  $str = '';\n  for ($i = 0; $i < $n; $i++) {\n    $str .= $c;\n  }\n  return strlen($str) > 0 ? $str : null;\n}\n\nfunction scisors($width) {\n  $left = (int) (($width - 4) / 2);\n  return func1($left, '-') . ' >8 ' . func1($width - 4 - $left, '-');\n}\n\nabstract class Acls1 {\n  public function __construct ($args = null) {\n    /* if args are not given, set up defaults */\n    if ($args == null)\n      $args = array('name' => 'doe', 'give-name' => 'john');\n\n    // make sure arguments are valid\n    foreach ($args as $k => $v)\n      assert(in_array($k, array('name', 'given-name', 'surname')));\n\n    $this->present($args);\n  }\n\n  protected abstract function present($args);\n}\n\nclass Cls1 extends Acls1 {\n  protected function present($args) {\n    foreach ($args as $k => $v) {\n      if ($k == 'name')\n        print \"My name is $v\\n\";\n      elseif ($k === 'surname')\n        print \"Call me $v\\n\";\n    }\n  }\n}\n\nfunction func2($a, $b = ((4 + 1) * 2 - 4 / 2)) {\n  while ($a > $b)\n    $a /= 2;\n  return $a;\n}\n\n/* this one is *really* silly */\nfunction func3(\n  $a = (0 ? 1 : 0) * 2,\n  $b = [1, 2, 3],\n  $c = \"Hello\",\n  $d = array('foo' => 42, 'bar' => 43)\n):string {\n  return $c.$d['foo'].$b[1].$a;\n}\n\ndefine('WIDTH', 36 * ((4 + 2) / 3));\n\n# --------------------------------------------------------------------------- #\necho scisors(WIDTH), \"\\n\";\n$cls1 = new Cls1();\necho scisors(72), \"\\n\";\n\necho func2(6, 5), \"\\n\";\n\n$name = <<<NAME\nhello\nNAME;\n$$name = 'world';\necho \"hello $hello\\n\";\n\necho func3(), \"\\n\";\n\n$obj = new class(array(1, 2, 3), (1 + 2) * 3) {\n  function __construct($a, $b) {\n    echo $b,\"\\n\";\n  }\n};\n"
  },
  {
    "path": "Units/parser-php.r/mode.php.d/expected.tags",
    "content": "a\tinput.php\t/^function a() {}$/;\"\tf\nb\tinput.php\t/^function b() {}$/;\"\tf\nc\tinput.php\t/^function c() {$/;\"\tf\nd\tinput.php\t/^function d() {$/;\"\tf\ne\tinput.php\t/^function e() {$/;\"\tf\nf\tinput.php\t/^function f() {}$/;\"\tf\ng\tinput.php\t/^function g() {}$/;\"\tf\nh\tinput.php\t/^function h() {}$/;\"\tf\ni\tinput.php\t/^function i() {}$/;\"\tf\nj\tinput.php\t/^function j() {}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-php.r/mode.php.d/input.php",
    "content": "Tests for entering and leaving PHP mode\n\nExpected output is\n\nfunctions:\n\ta\n\tb\n\tc\n\td\n\te\n\tf\n\tg\n\th\n\ti\n\tj\n\n\nfunction bug0() {\n\t// this should not appear\n}\n\n<?php // entering PHP mode, classic method\n\nfunction a() {}\n\n?> // PHP mode left\n\nfunction bug1() {}\n\n<? // entering PHP mode, short open tag\n\nfunction b() {}\n\n?> // PHP mode left\n\nfunction bug2() {}\n\n<?php // entering PHP mode\n\n// this WILL leave PHP mode: ?>\n\nfunction bug3() {}\n\n<? // entering PHP mode\n\nfunction c() {\n\t?> // PHP mode left\n\tfunction bug4() {\n\t}\n\t<? // back to PHP mode, still inside function c()\n}\n\nfunction d() {\n\t?> // same here\n\tfunction bug5() {\n\t}\n\t<?php // back to PHP mode, still inside function d()\n}\n\n// any open tag matches any close tag, so this is valid\n</script> // leaves PHP mode\n\nfunction bug4() {}\n\n?> <!-- just in case -->\n\n<script language=\"php\"> // enetered PHP mode\n\nfunction e() {\n\treturn 42;\n}\n\n?> // left PHP mode\n\nfunction bug5() {}\n\n// some valid long tag opening with inner whitespaces\n\n<script\n\tlanguage\n\t=\n\tphp\n> // entered\nfunction f() {}\n</script\n\t> // left\n\nfunction bug6() {}\n\n<script\tlanguage=\t'php'\t> // enter\nfunction g() {}\n</script > // leave\n\nfunction bug7() {}\n\n<?php\n// this WON'T leave PHP mode, it's in a comment  </script>\nfunction h() {}\n?>\n\nfunction bug8() {}\n\n<?php\n\nfunction i() {}\n// any open tag matches any close tag, so this is valid\n</script         \t  \t \n \t  \t        >\n\nfunction bug9() {}\n\n// this won't enter PHP, no spaces are allowed between the \"<\" and \"script\"\n< script language = php >\n\nfunction bug10() {}\n\n// does nothing, just resets mode for some tools not aware of the \"script\" thing\n?>\n\n<!-- <script> is OK anywhere, even in XML strings -->\n<p attr=\"<script language=php>\nfunction j() {}\n</script>\">\n\n</p>\n"
  },
  {
    "path": "Units/parser-php.r/nullable-return-type-decl.d/args.tags",
    "content": "--fields=+{typeref}\n"
  },
  {
    "path": "Units/parser-php.r/nullable-return-type-decl.d/expected.tags",
    "content": "get_item\tinput.php\t/^function get_item(): ?string {$/;\"\tf\ttyperef:unknown:?string\n"
  },
  {
    "path": "Units/parser-php.r/nullable-return-type-decl.d/input.php",
    "content": "// Taken from \"Example #7 Nullable return type declaration (as of PHP 7.1.0)\"\n// in http://php.net/manual/en/functions.returning-values.php\n\n<?php\nfunction get_item(): ?string {\n    if (isset($_GET['item'])) {\n        return $_GET['item'];\n    } else {\n        return null;\n    }\n}\n?>\n"
  },
  {
    "path": "Units/parser-php.r/php-7-4-typed-props-with-use-trait.d/args.ctags",
    "content": "--sort=no\n--fields=+{typeref}\n"
  },
  {
    "path": "Units/parser-php.r/php-7-4-typed-props-with-use-trait.d/expected.tags",
    "content": "SomeTrait\tinput.php\t/^trait SomeTrait$/;\"\tt\nsomeMethod\tinput.php\t/^    public function someMethod() {}$/;\"\tf\ttrait:SomeTrait\nSomeOtherTrait\tinput.php\t/^trait SomeOtherTrait$/;\"\tt\nsomeOtherMethod\tinput.php\t/^    public function someOtherMethod() {}$/;\"\tf\ttrait:SomeOtherTrait\nTest1\tinput.php\t/^class Test1$/;\"\tc\nid\tinput.php\t/^    public int $id;$/;\"\tv\tclass:Test1\ttyperef:unknown:int\nTest2\tinput.php\t/^class Test2$/;\"\tc\nid\tinput.php\t/^    public int $id;$/;\"\tv\tclass:Test2\ttyperef:unknown:int\nTest3\tinput.php\t/^class Test3$/;\"\tc\nid\tinput.php\t/^    public int $id;$/;\"\tv\tclass:Test3\ttyperef:unknown:int\nTest4\tinput.php\t/^class Test4$/;\"\tc\nid\tinput.php\t/^    public int $id;$/;\"\tv\tclass:Test4\ttyperef:unknown:int\nTest5\tinput.php\t/^class Test5$/;\"\tc\nid\tinput.php\t/^    public int $id;$/;\"\tv\tclass:Test5\ttyperef:unknown:int\n"
  },
  {
    "path": "Units/parser-php.r/php-7-4-typed-props-with-use-trait.d/input.php",
    "content": "<?php\n\ntrait SomeTrait\n{\n    public function someMethod() {}\n}\n\ntrait SomeOtherTrait\n{\n    public function someOtherMethod() {}\n}\n\nclass Test1\n{\n    use SomeTrait;\n    public int $id;\n}\n\nclass Test2\n{\n    use SomeTrait, SomeOtherTrait;\n    public int $id;\n}\n\nclass Test3\n{\n    use SomeTrait { someMethod as private; }\n    public int $id;\n}\n\nclass Test4\n{\n    use SomeTrait, SomeOtherTrait { someOtherMethod as protected; }\n    public int $id;\n}\n\nclass Test5\n{\n    use \\SomeTrait;\n    public int $id;\n}\n"
  },
  {
    "path": "Units/parser-php.r/php-7-4-typed-props.d/args.ctags",
    "content": "--sort=no\n--fields=+{typeref}{inherits}\n"
  },
  {
    "path": "Units/parser-php.r/php-7-4-typed-props.d/expected.tags",
    "content": "Person\tinput.php\t/^class Person$/;\"\tc\nage\tinput.php\t/^        public int $age;$/;\"\tv\tclass:Person\ttyperef:unknown:int\nUser\tinput.php\t/^class User extends Person$/;\"\tc\tinherits:Person\nid\tinput.php\t/^    public int $id;$/;\"\tv\tclass:User\ttyperef:unknown:int\nname\tinput.php\t/^    public ?string $name;$/;\"\tv\tclass:User\ttyperef:unknown:?string\nnext\tinput.php\t/^    public self $next;$/;\"\tv\tclass:User\ttyperef:class:User\nchild\tinput.php\t/^    public parent $child;$/;\"\tv\tclass:User\ttyperef:class:Person\n__construct\tinput.php\t/^    public function __construct($id, $name) {$/;\"\tf\tclass:User\nu\tinput.php\t/^$u = new User (0, \"A\");$/;\"\tv\n"
  },
  {
    "path": "Units/parser-php.r/php-7-4-typed-props.d/input.php",
    "content": "<?php\n// Derived from https://www.php.net/manual/en/migration74.new-features.php\nclass Person\n{\n        public int $age;\n}\n\nclass User extends Person\n{\n    public int $id;\n    public ?string $name;\n    public self $next;\n    public parent $child;\n    public function __construct($id, $name) {\n        $this->id = $id;\n        $this->name = $name;\n        $this->next = $this;\n        $this->child = $this;\n    }\n}\n$u = new User (0, \"A\");\necho $u->next->name;\n?>\n"
  },
  {
    "path": "Units/parser-php.r/php-anonymous-classes.d/args.ctags",
    "content": "--fields=afikmsS\n--fields=+E\n"
  },
  {
    "path": "Units/parser-php.r/php-anonymous-classes.d/expected.tags",
    "content": "AnonymousClassa6525f550100\tinput.php\t/^$c = new class {$/;\"\tc\textras:anonymous\nAnonymousClassa6525f550200\tinput.php\t/^$d = new class(42) {$/;\"\tc\textras:anonymous\nAnonymousClassa6525f550300\tinput.php\t/^$e = new class(64) extends SomeClass implements SomeInterface {$/;\"\tc\tinherits:SomeClass,SomeInterface\textras:anonymous\nSomeClass\tinput.php\t/^class SomeClass {}$/;\"\tc\nSomeInterface\tinput.php\t/^interface SomeInterface {}$/;\"\ti\nSomeTrait\tinput.php\t/^trait SomeTrait {}$/;\"\tt\n__construct\tinput.php\t/^\tpublic function __construct($n) { echo $n; }$/;\"\tf\tclass:AnonymousClassa6525f550200\taccess:public\tsignature:($n)\n__construct\tinput.php\t/^\tpublic function __construct($n) { echo $n; }$/;\"\tf\tclass:AnonymousClassa6525f550300\taccess:public\tsignature:($n)\nc\tinput.php\t/^$c = new class {$/;\"\tv\nd\tinput.php\t/^$d = new class(42) {$/;\"\tv\ne\tinput.php\t/^$e = new class(64) extends SomeClass implements SomeInterface {$/;\"\tv\nhello\tinput.php\t/^\tpublic function hello() { echo \"hello\"; }$/;\"\tf\tclass:AnonymousClassa6525f550100\taccess:public\tsignature:()\nhello\tinput.php\t/^\tpublic function hello() { echo \"hello\"; }$/;\"\tf\tclass:AnonymousClassa6525f550200\taccess:public\tsignature:()\nhello\tinput.php\t/^\tpublic function hello() { echo \"hello\"; }$/;\"\tf\tclass:AnonymousClassa6525f550300\taccess:public\tsignature:()\n"
  },
  {
    "path": "Units/parser-php.r/php-anonymous-classes.d/input.php",
    "content": "<?php\n\n$c = new class {\n\tpublic function hello() { echo \"hello\"; }\n};\n\n$c->hello();\n\n$d = new class(42) {\n\tpublic function __construct($n) { echo $n; }\n\tpublic function hello() { echo \"hello\"; }\n};\n\n$d->hello();\n\nclass SomeClass {}\ninterface SomeInterface {}\ntrait SomeTrait {}\n\n$e = new class(64) extends SomeClass implements SomeInterface {\n\tuse SomeTrait;\n\tpublic function __construct($n) { echo $n; }\n\tpublic function hello() { echo \"hello\"; }\n};\n\n$e->hello();\n"
  },
  {
    "path": "Units/parser-php.r/php-anonymous_functions.d/args.ctags",
    "content": "--fields=afikmsS\n"
  },
  {
    "path": "Units/parser-php.r/php-anonymous_functions.d/expected.tags",
    "content": "_g\tinput.php\t/^$_g = 42;$/;\"\tv\na\tinput.php\t/^$a = function() {};$/;\"\tf\tsignature:()\nb\tinput.php\t/^$b = function($x, $y) {};$/;\"\tf\tsignature:($x, $y)\nc\tinput.php\t/^$c = function() {$/;\"\tf\tsignature:()\nd\tinput.php\t/^$d = function() {$/;\"\tf\tsignature:()\ne\tinput.php\t/^$e = function&() {$/;\"\tf\tsignature:()\nf\tinput.php\t/^$f = function&() use (&$_g) {$/;\"\tf\tsignature:()\nf_sub\tinput.php\t/^  function f_sub() {}$/;\"\tf\tfunction:f\tsignature:()\n"
  },
  {
    "path": "Units/parser-php.r/php-anonymous_functions.d/input.php",
    "content": "<?php\n\n$a = function() {};\n\n$b = function($x, $y) {};\n\n/* return a value */\n$c = function() {\n  return 42;\n};\n\n/* return a function */\n$d = function() {\n  return function() {\n    return \"hello\";\n  };\n};\n\n/* return by reference */\n$_g = 42;\n$e = function&() {\n  global $_g;\n  return $_g;\n};\n\n$f = function&() use (&$_g) {\n  \n  function f_sub() {}\n  \n  return $_g;\n};\n"
  },
  {
    "path": "Units/parser-php.r/php-bug681824.d/args.ctags",
    "content": "--fields=fksS\n"
  },
  {
    "path": "Units/parser-php.r/php-bug681824.d/expected.tags",
    "content": "db_query\tinput.php\t/^ function db_query$/;\"\tf\tsignature:($pDB, $pQuery)\n"
  },
  {
    "path": "Units/parser-php.r/php-bug681824.d/input.php",
    "content": "<?php\n// Bugs item #681824, was opened at 2003-02-06 18:14\n// You can respond by visiting: \n// https://sourceforge.net/tracker/?func=detail&atid=106556&aid=681824&group_id=6556\n// \n// Category: None\n// Group: None\n// Status: Open\n// Resolution: None\n// Priority: 5\n// Submitted By: Thomi Dammann (thomi35)\n// Assigned to: Nobody/Anonymous (nobody)\n// Summary: Comments disturb ctags (v. 5.4)  scaning a PHP-file?\n// \n// Initial Comment:\n// If I have (correct) statements like\n// \n function db_query\n    ($pDB,\t\t\t\t// connection handle\n     $pQuery)\t\t  // query string\n  {\n...\n}\n// \n// it seems that ctags used with vim doesn't find the\n// function names anymore. I think that either the\n// comments or the distribution on more than one line\n// disturb the parser.\n// \n// Regards\n// \n// Thomi\n"
  },
  {
    "path": "Units/parser-php.r/php-case_sensitivity.d/expected.tags",
    "content": "A\tinput.php\t/^class A {}$/;\"\tc\nB\tinput.php\t/^CLASS B {}$/;\"\tc\nC\tinput.php\t/^Class C {}$/;\"\tc\nD\tinput.php\t/^ClAsS D {}$/;\"\tc\na\tinput.php\t/^function a() {}$/;\"\tf\nb\tinput.php\t/^FUNCTION b() {}$/;\"\tf\nc\tinput.php\t/^Function c() {}$/;\"\tf\nd\tinput.php\t/^FuNcTiOn d() {}$/;\"\tf\niA\tinput.php\t/^interface iA {}$/;\"\ti\niB\tinput.php\t/^INTERFACE iB {}$/;\"\ti\niC\tinput.php\t/^Interface iC {}$/;\"\ti\niD\tinput.php\t/^InTeRfAcE iD {}$/;\"\ti\ntA\tinput.php\t/^trait tA {}$/;\"\tt\ntB\tinput.php\t/^TRAIT tB {}$/;\"\tt\ntC\tinput.php\t/^Trait tC {}$/;\"\tt\ntD\tinput.php\t/^TrAiT tD {}$/;\"\tt\n"
  },
  {
    "path": "Units/parser-php.r/php-case_sensitivity.d/input.php",
    "content": "<?php\n// PHP is case insensitive about keywords\n\nclass A {}\n\nCLASS B {}\n\nClass C {}\n\nClAsS D {}\n\n\n\nfunction a() {}\n\nFUNCTION b() {}\n\nFunction c() {}\n\nFuNcTiOn d() {}\n\n\n\ntrait tA {}\n\nTRAIT tB {}\n\nTrait tC {}\n\nTrAiT tD {}\n\n\n\ninterface iA {}\n\nINTERFACE iB {}\n\nInterface iC {}\n\nInTeRfAcE iD {}\n"
  },
  {
    "path": "Units/parser-php.r/php-classes.d/args.ctags",
    "content": "--fields=+im\n"
  },
  {
    "path": "Units/parser-php.r/php-classes.d/expected.tags",
    "content": "Abstract1\tinput.php\t/^abstract class Abstract1 {$/;\"\tc\timplementation:abstract\nAbstracted\tinput.php\t/^class Abstracted extends Abstract1 {$/;\"\tc\tinherits:Abstract1\nBar\tinput.php\t/^class Bar {$/;\"\tc\nFoo\tinput.php\t/^class Foo {$/;\"\tc\nIface1\tinput.php\t/^interface Iface1 {$/;\"\ti\nIface2\tinput.php\t/^interface Iface2 {$/;\"\ti\nInherited\tinput.php\t/^class Inherited extends Bar {$/;\"\tc\tinherits:Bar\nInterfaced\tinput.php\t/^class Interfaced extends Inherited implements Iface1, Iface2 {$/;\"\tc\tinherits:Inherited,Iface1,Iface2\n__construct\tinput.php\t/^\tfunction __construct () {$/;\"\tf\tclass:Bar\n__construct\tinput.php\t/^\tfunction __construct($a, $b) {$/;\"\tf\tclass:Foo\nabstract_method1\tinput.php\t/^\tabstract function abstract_method1();$/;\"\tf\tclass:Abstract1\timplementation:abstract\nabstract_method1\tinput.php\t/^\tfunction abstract_method1() {$/;\"\tf\tclass:Abstracted\nabstract_method2\tinput.php\t/^\tabstract protected function abstract_method2();$/;\"\tf\tclass:Abstract1\timplementation:abstract\nabstract_method2\tinput.php\t/^\tprotected function abstract_method2() {$/;\"\tf\tclass:Abstracted\nifaced_method1\tinput.php\t/^\tfunction ifaced_method1 () {$/;\"\tf\tclass:Interfaced\nifaced_method1\tinput.php\t/^\tfunction ifaced_method1 ();$/;\"\tf\tinterface:Iface1\nifaced_method2\tinput.php\t/^\tfunction ifaced_method2 () {$/;\"\tf\tclass:Interfaced\nifaced_method2\tinput.php\t/^\tfunction ifaced_method2 ();$/;\"\tf\tinterface:Iface2\nmethod1\tinput.php\t/^\tfunction method1 () {$/;\"\tf\tclass:Bar\nmethod1\tinput.php\t/^\tfunction method1($arg) {$/;\"\tf\tclass:Foo\nmethod2\tinput.php\t/^\tfunction method2() {$/;\"\tf\tclass:Foo\nmethod3\tinput.php\t/^\tpublic function method3() {$/;\"\tf\tclass:Abstract1\n"
  },
  {
    "path": "Units/parser-php.r/php-classes.d/input.php",
    "content": "Expected output is\n\nclasses:\n\tAbstract1\n\tAbstracted\n\tBar\n\tFoo\n\tInherited\n\tInterfaced\n\nfunctions:\n\t__construct [Foo]\n\t__construct [Bar]\n\tabstract_method1 [Abstract1]\n\tabstract_method1 [Abstracted]\n\tabstract_method2 [Abstract1]\n\tabstract_method2 [Abstracted]\n\tifaced_method1 [Iface1]\n\tifaced_method1 [Interfaced]\n\tifaced_method2 [Iface2]\n\tifaced_method2 [Interfaced]\n\tmethod1 [Foo]\n\tmethod1 [Bar]\n\tmethod2 [Foo]\n\tmethod3 [Abstract1]\n\ninterfaces:\n\tIface1\n\tIface2\n\n<?php\n\nclass Foo {\n\tfunction __construct($a, $b) {\n\t\t// ...\n\t}\n\n\tfunction method1($arg) {\n\t\treturn 42;\n\t}\n\n\tfunction method2() {\n\t\t// ...\n\t}\n}\n\nclass Bar {\n\tfunction __construct () {\n\t\t/* ... */\n\t}\n\n\tfunction method1 () {\n\t\t// ...\n\t}\n}\n\nclass Inherited extends Bar {\n}\n\ninterface Iface1 {\n\tfunction ifaced_method1 ();\n}\n\ninterface Iface2 {\n\tfunction ifaced_method2 ();\n}\n\nclass Interfaced extends Inherited implements Iface1, Iface2 {\n\tfunction ifaced_method1 () {\n\t\t// ...\n\t}\n\n\tfunction ifaced_method2 () {\n\t\t// ...\n\t}\n}\n\nabstract class Abstract1 {\n\tabstract function abstract_method1();\n\tabstract protected function abstract_method2();\n\tpublic function method3() {\n\t\treturn 42;\n\t}\n}\n\nclass Abstracted extends Abstract1 {\n\tfunction abstract_method1() {\n\t\t// ...\n\t}\n\tprotected function abstract_method2() {\n\t\t// ...\n\t}\n}\n"
  },
  {
    "path": "Units/parser-php.r/php-echo-tag.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-php.r/php-echo-tag.d/expected.tags",
    "content": "function1\tinput.php\t/^function function1() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-php.r/php-echo-tag.d/input.php",
    "content": "<?= \"hello?><h1>Something</h1><?php function bug1() {}\" ?>\n<?= \"<?php\nfunction bug2() {};\n\" ?>\n<?= \"actually some PHP code\";\nfunction function1() {\n  echo \"hello\";\n};\nfunction1();\n"
  },
  {
    "path": "Units/parser-php.r/php-full-qualified-tags-no-esc.d/args.ctags",
    "content": "--extras=+qp\n--output-format=e-ctags\n--pseudo-tags=TAG_OUTPUT_MODE\n\n"
  },
  {
    "path": "Units/parser-php.r/php-full-qualified-tags-no-esc.d/expected.tags",
    "content": "!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n__construct\tinput.php\t/^    public function __construct() {$/;\"\tf\tclass:foo\\bar\nbar\tinput.php\t/^class bar {$/;\"\tc\tnamespace:foo\nfoo\tinput.php\t/^namespace foo;$/;\"\tn\nfoo\\bar\tinput.php\t/^class bar {$/;\"\tc\tnamespace:foo\nfoo\\bar::__construct\tinput.php\t/^    public function __construct() {$/;\"\tf\tclass:foo\\bar\n"
  },
  {
    "path": "Units/parser-php.r/php-full-qualified-tags-no-esc.d/input.php",
    "content": "Taken from an issue report (#787) by @sserbin\n\n<?php\nnamespace foo;\n\nclass bar {\n    public function __construct() {\n    }\n}\n>"
  },
  {
    "path": "Units/parser-php.r/php-full-qualified-tags.d/args.ctags",
    "content": "--extras=+q\n"
  },
  {
    "path": "Units/parser-php.r/php-full-qualified-tags.d/expected.tags",
    "content": "__construct\tinput.php\t/^    public function __construct() {$/;\"\tf\tclass:foo\\\\bar\nbar\tinput.php\t/^class bar {$/;\"\tc\tnamespace:foo\nfoo\tinput.php\t/^namespace foo;$/;\"\tn\nfoo\\\\bar\tinput.php\t/^class bar {$/;\"\tc\tnamespace:foo\nfoo\\\\bar::__construct\tinput.php\t/^    public function __construct() {$/;\"\tf\tclass:foo\\\\bar\n"
  },
  {
    "path": "Units/parser-php.r/php-full-qualified-tags.d/input.php",
    "content": "Taken from an issue report (#787) by @sserbin\n\n<?php\nnamespace foo;\n\nclass bar {\n    public function __construct() {\n    }\n}\n>"
  },
  {
    "path": "Units/parser-php.r/php-heredoc-cr.d/expected.tags",
    "content": "a\tinput.php\t/^<?php/;\"\tv\nb\tinput.php\t/^<?php/;\"\tv\nc\tinput.php\t/^<?php/;\"\tv\nconstant1\tinput.php\t/^<?php/;\"\td\nconstant2\tinput.php\t/^<?php/;\"\td\nconstant3\tinput.php\t/^<?php/;\"\td\nconstant4\tinput.php\t/^<?php/;\"\td\nd\tinput.php\t/^<?php/;\"\tv\ne\tinput.php\t/^<?php/;\"\tv\nf\tinput.php\t/^<?php/;\"\tv\ng\tinput.php\t/^<?php/;\"\tv\nzzz_end\tinput.php\t/^<?php/;\"\tv\n"
  },
  {
    "path": "Units/parser-php.r/php-heredoc-cr.d/input.php",
    "content": "<?php\r\r$a = <<<EOS\r; function bug1() {};\rEOS;\r\r$b = <<<'EOS'\r; function bug2() {};\rEOS;\r\r$c = <<<\"EOS\"\r; function bug3() {};\rEOS;\r\r/* PHP 7.3+ relaxed syntax */\r\r$d = <<<EOS\r; function bug4() {};\rEOS . 'suffix';\r\r\r$e = <<<EOS\r    ; function bug5() {};\r  EOS ;\r\r# $f = \"EOSNOTYES\"\r$f = <<<EOS\r    EOSNOT\r    ; function bug6() {};\r    EOS.\"YES\";\r\r# $g = 46\r$g = <<<EOS\r  42\r  EOS+4;\r\r/* check we get the right value out of the heredocs */\r\rdefine(<<<EOS\rconstant1\rEOS\r, 42);\r\rdefine(<<<EOS\rconstant2\rEOS, 43);\r\rdefine(<<<EOS\r  constant3\r  EOS, 43);\r\rdefine(<<<EOS\r\tconstant4\r\tEOS, 44);\r\r# just to check we're correctly out of a heredoc/nowdoc here\r$zzz_end = 42;\r"
  },
  {
    "path": "Units/parser-php.r/php-heredoc.d/expected.tags",
    "content": "a\tinput.php\t/^$a = <<<EOS$/;\"\tv\nb\tinput.php\t/^$b = <<<'EOS'$/;\"\tv\nc\tinput.php\t/^$c = <<<\"EOS\"$/;\"\tv\nconstant1\tinput.php\t/^define(<<<EOS$/;\"\td\nconstant2\tinput.php\t/^define(<<<EOS$/;\"\td\nconstant3\tinput.php\t/^define(<<<EOS$/;\"\td\nconstant4\tinput.php\t/^define(<<<EOS$/;\"\td\nd\tinput.php\t/^$d = <<<EOS$/;\"\tv\ne\tinput.php\t/^$e = <<<EOS$/;\"\tv\nf\tinput.php\t/^$f = <<<EOS$/;\"\tv\ng\tinput.php\t/^$g = <<<EOS$/;\"\tv\nzzz_end\tinput.php\t/^$zzz_end = 42;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-php.r/php-heredoc.d/input.php",
    "content": "<?php\n\n$a = <<<EOS\n; function bug1() {};\nEOS;\n\n$b = <<<'EOS'\n; function bug2() {};\nEOS;\n\n$c = <<<\"EOS\"\n; function bug3() {};\nEOS;\n\n/* PHP 7.3+ relaxed syntax */\n\n$d = <<<EOS\n; function bug4() {};\nEOS . 'suffix';\n\n\n$e = <<<EOS\n    ; function bug5() {};\n  EOS ;\n\n# $f = \"EOSNOTYES\"\n$f = <<<EOS\n    EOSNOT\n    ; function bug6() {};\n    EOS.\"YES\";\n\n# $g = 46\n$g = <<<EOS\n  42\n  EOS+4;\n\n/* check we get the right value out of the heredocs */\n\ndefine(<<<EOS\nconstant1\nEOS\n, 42);\n\ndefine(<<<EOS\nconstant2\nEOS, 43);\n\ndefine(<<<EOS\n  constant3\n  EOS, 43);\n\ndefine(<<<EOS\n\tconstant4\n\tEOS, 44);\n\n# just to check we're correctly out of a heredoc/nowdoc here\n$zzz_end = 42;\n"
  },
  {
    "path": "Units/parser-php.r/php-marker.d/args.ctags",
    "content": "-G\n--fields=+l\n\n"
  },
  {
    "path": "Units/parser-php.r/php-marker.d/expected.tags",
    "content": "a\tinput.unknown-lang\t/^function a() {$/;\"\tf\tlanguage:PHP\n"
  },
  {
    "path": "Units/parser-php.r/php-marker.d/input.unknown-lang",
    "content": "<?php\nfunction a() {\n\treturn true;\n}\n"
  },
  {
    "path": "Units/parser-php.r/php-mode.d/expected.tags",
    "content": "a\tinput.php\t/^function a() {}$/;\"\tf\nb\tinput.php\t/^function b() {}$/;\"\tf\nc\tinput.php\t/^function c() {$/;\"\tf\nd\tinput.php\t/^function d() {$/;\"\tf\ne\tinput.php\t/^function e() {$/;\"\tf\nf\tinput.php\t/^function f() {}$/;\"\tf\ng\tinput.php\t/^function g() {}$/;\"\tf\nh\tinput.php\t/^function h() {}$/;\"\tf\ni\tinput.php\t/^function i() {}$/;\"\tf\nj\tinput.php\t/^function j() {}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-php.r/php-mode.d/input.php",
    "content": "Tests for entering and leaving PHP mode\n\nExpected output is\n\nfunctions:\n\ta\n\tb\n\tc\n\td\n\te\n\tf\n\tg\n\th\n\ti\n\tj\n\n\nfunction bug0() {\n\t// this should not appear\n}\n\n<?php // entering PHP mode, classic method\n\nfunction a() {}\n\n?> // PHP mode left\n\nfunction bug1() {}\n\n<? // entering PHP mode, short open tag\n\nfunction b() {}\n\n?> // PHP mode left\n\nfunction bug2() {}\n\n<?php // entering PHP mode\n\n// this WILL leave PHP mode: ?>\n\nfunction bug3() {}\n\n<? // entering PHP mode\n\nfunction c() {\n\t?> // PHP mode left\n\tfunction bug4() {\n\t}\n\t<? // back to PHP mode, still inside function c()\n}\n\nfunction d() {\n\t?> // same here\n\tfunction bug5() {\n\t}\n\t<?php // back to PHP mode, still inside function d()\n}\n\n// any open tag matches any close tag, so this is valid\n</script> // leaves PHP mode\n\nfunction bug4() {}\n\n?> <!-- just in case -->\n\n<script language=\"php\"> // enetered PHP mode\n\nfunction e() {\n\treturn 42;\n}\n\n?> // left PHP mode\n\nfunction bug5() {}\n\n// some valid long tag opening with inner whitespaces\n\n<script\n\tlanguage\n\t=\n\tphp\n> // entered\nfunction f() {}\n</script\n\t> // left\n\nfunction bug6() {}\n\n<script\tlanguage=\t'php'\t> // enter\nfunction g() {}\n</script > // leave\n\nfunction bug7() {}\n\n<?php\n// this WON'T leave PHP mode, it's in a comment  </script>\nfunction h() {}\n?>\n\nfunction bug8() {}\n\n<?php\n\nfunction i() {}\n// any open tag matches any close tag, so this is valid\n</script         \t  \t \n \t  \t        >\n\nfunction bug9() {}\n\n// this won't enter PHP, no spaces are allowed between the \"<\" and \"script\"\n< script language = php >\n\nfunction bug10() {}\n\n// does nothing, just resets mode for some tools not aware of the \"script\" thing\n?>\n\n<!-- <script> is OK anywhere, even in XML strings -->\n<p attr=\"<script language=php>\nfunction j() {}\n</script>\">\n\n</p>\n"
  },
  {
    "path": "Units/parser-php.r/php-namespaces.d/expected.tags",
    "content": "B\tinput.php\t/^\tclass B {$/;\"\tc\tnamespace:Bar\\\\Baz\nBar\\\\Baz\tinput.php\t/^namespace Bar\\\\Baz {$/;\"\tn\nC\tinput.php\t/^\tclass C {$/;\"\tc\tnamespace:Foo\nFoo\tinput.php\t/^namespace Foo {$/;\"\tn\n__construct\tinput.php\t/^\t\tfunction __construct() {$/;\"\tf\tclass:Bar\\\\Baz\\\\B\n__construct\tinput.php\t/^\t\tfunction __construct() {$/;\"\tf\tclass:Foo\\\\C\na\tinput.php\t/^\tfunction a() {$/;\"\tf\tnamespace:Bar\\\\Baz\na\tinput.php\t/^\tfunction a() {$/;\"\tf\tnamespace:Foo\nb\tinput.php\t/^\tfunction b() {$/;\"\tf\tnamespace:Foo\nc\tinput.php\t/^\t\tfunction c() {$/;\"\tf\tclass:Bar\\\\Baz\\\\B\nd\tinput.php\t/^\t\tfunction d() {$/;\"\tf\tclass:Foo\\\\C\ninRoot\tinput.php\t/^\tfunction inRoot() {$/;\"\tf\nmeToo\tinput.php\t/^\tfunction meToo() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-php.r/php-namespaces.d/input.php",
    "content": "Tests for namespaces (braced version)\n\nExpected output is\n\nnamespaces:\n\tBar\\Baz\n\tFoo\n\nclasses:\n\tB [Bar\\Baz]\n\tC [Foo]\n\nfunctions:\n\t__construct [Foo\\C]\n\t__construct [Bar\\Baz\\B]\n\ta [Foo]\n\ta [Bar\\Baz]\n\tb [Foo]\n\tc [Bar\\Baz\\B]\n\td [Foo\\C]\n\tinRoot\n\tmeToo\n\n<?php\n\n/* namespace \"Foo\" */\nnamespace Foo {\n\tfunction a() {\n\t\treturn true;\n\t}\n\n\tfunction b() {\n\t\treturn false;\n\t}\n\n\tclass C {\n\t\tfunction __construct() {\n\t\t\t// ...\n\t\t}\n\n\t\tfunction d() {\n\t\t\treturn 42;\n\t\t}\n\t}\n}\n\n/* namespace \"Bar\\Baz\" */\nnamespace Bar\\Baz {\n\tfunction a() {\n\t\treturn true;\n\t}\n\n\tclass B {\n\t\tfunction __construct() {\n\t\t\t// ...\n\t\t}\n\n\t\tfunction c() {\n\t\t\treturn 42;\n\t\t}\n\t}\n}\n\n/* back to root namespace */\nnamespace {\n\tfunction inRoot() {\n\t\treturn true;\n\t}\n\n\tfunction meToo() {\n\t\treturn true;\n\t}\n}\n"
  },
  {
    "path": "Units/parser-php.r/php-namespaces2.d/expected.tags",
    "content": "B\tinput.php\t/^class B {$/;\"\tc\tnamespace:Bar\\\\Baz\nBar\\\\Baz\tinput.php\t/^namespace Bar\\\\Baz;$/;\"\tn\nC\tinput.php\t/^class C {$/;\"\tc\tnamespace:Foo\nFoo\tinput.php\t/^namespace Foo;$/;\"\tn\n__construct\tinput.php\t/^\tfunction __construct() {$/;\"\tf\tclass:Bar\\\\Baz\\\\B\n__construct\tinput.php\t/^\tfunction __construct() {$/;\"\tf\tclass:Foo\\\\C\na\tinput.php\t/^function a() {$/;\"\tf\tnamespace:Bar\\\\Baz\na\tinput.php\t/^function a() {$/;\"\tf\tnamespace:Foo\nb\tinput.php\t/^function b() {$/;\"\tf\tnamespace:Foo\nc\tinput.php\t/^\tfunction c() {$/;\"\tf\tclass:Bar\\\\Baz\\\\B\nd\tinput.php\t/^\tfunction d() {$/;\"\tf\tclass:Foo\\\\C\n"
  },
  {
    "path": "Units/parser-php.r/php-namespaces2.d/input.php",
    "content": "Tests for namespaces (unbraced version)\n\nExpected output is\n\nnamespaces:\n\tBar\\Baz\n\tFoo\n\nclasses:\n\tB [Bar\\Baz]\n\tC [Foo]\n\nfunctions:\n\t__construct [Foo\\C]\n\t__construct [Bar\\Baz\\B]\n\ta [Foo]\n\ta [Bar\\Baz]\n\tb [Foo]\n\tc [Bar\\Baz\\B]\n\td [Foo\\C]\n\n<?php\n\n/* namespace \"Foo\" */\nnamespace Foo;\n\nfunction a() {\n\treturn true;\n}\n\nfunction b() {\n\treturn false;\n}\n\nclass C {\n\tfunction __construct() {\n\t\t// ...\n\t}\n\n\tfunction d() {\n\t\treturn 42;\n\t}\n}\n\n/* namespace \"Bar\\Baz\" */\nnamespace Bar\\Baz;\n\nfunction a() {\n\treturn true;\n}\n\nclass B {\n\tfunction __construct() {\n\t\t// ...\n\t}\n\n\tfunction c() {\n\t\treturn 42;\n\t}\n}\n"
  },
  {
    "path": "Units/parser-php.r/php-php5_5_class_kw.d/expected.tags",
    "content": "A\tinput.php\t/^class A {$/;\"\tc\nB\tinput.php\t/^class B {$/;\"\tc\nC\tinput.php\t/^class C {$/;\"\tc\n__construct\tinput.php\t/^  public function __construct () {$/;\"\tf\tclass:B\n"
  },
  {
    "path": "Units/parser-php.r/php-php5_5_class_kw.d/input.php",
    "content": "<?php\n\nclass A {\n  \n}\n\necho A::class . \"\\n\";\n\nclass B {\n  public function __construct () {\n    echo this::class;\n  }\n}\n\nnew B();\n\nclass C {\n  \n}\n"
  },
  {
    "path": "Units/parser-php.r/php-return-type-declaration.d/args.ctags",
    "content": "--kinds-php=+l\n--fields=afikmsSt\n"
  },
  {
    "path": "Units/parser-php.r/php-return-type-declaration.d/expected.tags",
    "content": "A\tinput.php\t/^namespace A {$/;\"\tn\nSubAT\tinput.php\t/^    class SubAT extends \\\\A \\\\ T$/;\"\tc\tinherits:\\\\A\\\\T\nSubTest\tinput.php\t/^    class SubTest extends Test$/;\"\tc\tinherits:Test\nT\tinput.php\t/^    class T {}$/;\"\tc\tnamespace:A\nTest\tinput.php\t/^    class Test$/;\"\tc\nat\tinput.php\t/^    $at = $s->fourth();$/;\"\tv\nfifth\tinput.php\t/^        public function fifth() : \\\\ A \\\\ T$/;\"\tf\tclass:SubTest\ttyperef:unknown:\\\\A\\\\T\taccess:public\tsignature:()\nfirst\tinput.php\t/^        public function first(string $str) : Closure$/;\"\tf\tclass:Test\ttyperef:unknown:Closure\taccess:public\tsignature:(string $str)\nfourth\tinput.php\t/^        public function fourth() : \\\\A\\\\T$/;\"\tf\tclass:SubTest\ttyperef:unknown:\\\\A\\\\T\taccess:public\tsignature:()\ns\tinput.php\t/^    $s = new SubTest;$/;\"\tv\nsecond\tinput.php\t/^        public function second() : self$/;\"\tf\tclass:Test\ttyperef:class:Test\taccess:public\tsignature:()\nseventh\tinput.php\t/^        public function seventh() : parent$/;\"\tf\tclass:SubAT\ttyperef:class:\\\\A\\\\T\taccess:public\tsignature:()\nsixth\tinput.php\t/^        public function &sixth(\\\\A\\\\T &$t) : \\\\A\\\\T$/;\"\tf\tclass:SubTest\ttyperef:unknown:\\\\A\\\\T\taccess:public\tsignature:(\\\\A\\\\T& $t)\nt\tinput.php\t/^    $t = $s->third();$/;\"\tv\nthird\tinput.php\t/^        public function third() : parent$/;\"\tf\tclass:SubTest\ttyperef:class:Test\taccess:public\tsignature:()\ntmp\tinput.php\t/^            $tmp = function() use ($str) : int {$/;\"\tf\tfunction:Test::first\ttyperef:unknown:int\tsignature:()\n"
  },
  {
    "path": "Units/parser-php.r/php-return-type-declaration.d/input.php",
    "content": "<?php\n\nnamespace A {\n    class T {}\n}\n\nnamespace\n{\n    class Test\n    {\n        public function first(string $str) : Closure\n        {\n            /* closure with return type declaration and use() clause */\n            $tmp = function() use ($str) : int {\n                return strlen($str);\n            };\n            return $tmp;\n        }\n\n        public function second() : self\n        {\n            return $this;\n        }\n    }\n\n    class SubTest extends Test\n    {\n        public function third() : parent\n        {\n            return $this;\n        }\n\n        /* returning a namespace-qualified type */\n        public function fourth() : \\A\\T\n        {\n            return new \\A\\T;\n        }\n\n        /* spaces are allowed around elements of the namespace */\n        public function fifth() : \\ A \\ T\n        {\n            return $this->fourth();\n        }\n\n        public function &sixth(\\A\\T &$t) : \\A\\T\n        {\n            return $t;\n        }\n    }\n\n    class SubAT extends \\A \\ T\n    {\n        public function seventh() : parent\n        {\n            return $this;\n        }\n    }\n\n    /* runtime test */\n    $s = new SubTest;\n    $t = $s->third();\n    var_dump(($t->second()->first(\"hello\"))());\n    var_dump($s->fourth());\n    var_dump($s->fifth());\n    $at = $s->fourth();\n    var_dump($s->sixth($at));\n\n    var_dump((new SubAT)->seventh());\n}\n"
  },
  {
    "path": "Units/parser-php.r/php-semi-reserved-keywords.d/expected.tags",
    "content": "C\tinput.php\t/^class C {$/;\"\tc\nabstract\tinput.php\t/^    public function abstract() {}$/;\"\tf\tclass:C\nc\tinput.php\t/^$c = C::new();$/;\"\tv\ncall_c_function\tinput.php\t/^function call_c_function($c) {$/;\"\tf\nclass\tinput.php\t/^    public static function class() { return new self; }$/;\"\tf\tclass:C\nconst\tinput.php\t/^    const const = 1;$/;\"\td\tclass:C\nfor\tinput.php\t/^    public function for() {}$/;\"\tf\tclass:C\nfunc1\tinput.php\t/^function func1() {}$/;\"\tf\nfunc2\tinput.php\t/^function func2() {}$/;\"\tf\nfunc3\tinput.php\t/^function func3() {}$/;\"\tf\nfunc4\tinput.php\t/^function func4() {}$/;\"\tf\nfunc5\tinput.php\t/^function func5() {}$/;\"\tf\nfunc6\tinput.php\t/^function func6() {}$/;\"\tf\nfunc7\tinput.php\t/^function func7() {}$/;\"\tf\nfunc8\tinput.php\t/^function func8() {}$/;\"\tf\nfunc9\tinput.php\t/^function func9() {}$/;\"\tf\nfunction\tinput.php\t/^    public function function() {}$/;\"\tf\tclass:C\nnamespace\tinput.php\t/^    public static function namespace() { return new self; }$/;\"\tf\tclass:C\nnew\tinput.php\t/^    public static function new() { return new self; }$/;\"\tf\tclass:C\nprivate\tinput.php\t/^    private function private() {}$/;\"\tf\tclass:C\nprotected\tinput.php\t/^    protected function protected() {}$/;\"\tf\tclass:C\npublic\tinput.php\t/^    public function public() {}$/;\"\tf\tclass:C\nsomething\tinput.php\t/^function something() {}$/;\"\tf\nstatic\tinput.php\t/^    const static = 2;$/;\"\td\tclass:C\ntest1\tinput.php\t/^    public function test1() {}$/;\"\tf\tclass:C\ntest2\tinput.php\t/^    public function test2() {}$/;\"\tf\tclass:C\ntest3\tinput.php\t/^    public function test3() {}$/;\"\tf\tclass:C\ntest4\tinput.php\t/^    public function test4() {}$/;\"\tf\tclass:C\ntest5\tinput.php\t/^    public function test5() {}$/;\"\tf\tclass:C\ntest6\tinput.php\t/^    public function test6() {}$/;\"\tf\tclass:C\ntest7\tinput.php\t/^    public function test7() {}$/;\"\tf\tclass:C\ntest8\tinput.php\t/^    public function test8() {}$/;\"\tf\tclass:C\ntest9\tinput.php\t/^    public function test9() {}$/;\"\tf\tclass:C\ntrait\tinput.php\t/^    public static function trait() { return new self; }$/;\"\tf\tclass:C\nwhile\tinput.php\t/^    public function while() {}$/;\"\tf\tclass:C\n"
  },
  {
    "path": "Units/parser-php.r/php-semi-reserved-keywords.d/input.php",
    "content": "<?php\n\nclass C {\n    const const = 1;\n    const static = 2;\n    \n    public static function new() { return new self; }\n    public function function() {}\n    public static function class() { return new self; }\n    public function for() {}\n    public function while() {}\n    public function abstract() {}\n    public function public() {}\n    protected function protected() {}\n    private function private() {}\n    public static function namespace() { return new self; }\n    public static function trait() { return new self; }\n\n    public function test1() {}\n    public function test2() {}\n    public function test3() {}\n    public function test4() {}\n    public function test5() {}\n    public function test6() {}\n    public function test7() {}\n    public function test8() {}\n    public function test9() {}\n}\n\nfunction call_c_function($c) {\n    return $c->function();\n}\n\n$c = C::new();\ncall_c_function($c);\n$c->class();\n$c->namespace();\n$c->trait();\n\n$c->class()->test1();\nfunction func1() {}\n$c->namespace()->test2();\nfunction func2() {}\n$c->trait()->test3();\nfunction func3() {}\n\n$c->class()->namespace()->test4();\nfunction func4() {}\n$c->namespace()->trait()->test5();\nfunction func5() {}\n$c->trait()->class()->test6();\nfunction func6() {}\n\nC::class()->test7();\nfunction func7() {}\nC::namespace()->test8();\nfunction func8() {}\nC::trait()->test9();\nfunction func9() {}\n\nfunction something() {}\n"
  },
  {
    "path": "Units/parser-php.r/php-simple.d/args.ctags",
    "content": "--fields=afikmsS\n"
  },
  {
    "path": "Units/parser-php.r/php-simple.d/expected.tags",
    "content": "4site\tinput.php\t/^$4site = 'not yet';     \\/\\/ invalid; starts with a number$/;\"\tv\nCONSTANT\tinput.php\t/^define(\"CONSTANT\", \"Hello world.\");$/;\"\td\nCart\tinput.php\t/^class Cart$/;\"\tc\nVar\tinput.php\t/^$Var = \"Joe\";$/;\"\tv\n_4site\tinput.php\t/^$_4site = 'not yet';    \\/\\/ valid; starts with an underscore$/;\"\tv\nadd_item\tinput.php\t/^    function add_item ($artnr, $num)$/;\"\tf\tclass:Cart\tsignature:($artnr, $num)\nfoo\tinput.php\t/^function foo ($arg_1, $arg_2, ..., $arg_n)$/;\"\tf\tsignature:($arg_1, $arg_2, ..., $arg_n)\nitems\tinput.php\t/^    var $items;  \\/\\/ Items in our shopping cart$/;\"\tv\tclass:Cart\taccess:public\nremove_item\tinput.php\t/^    function remove_item ($artnr, $num)$/;\"\tf\tclass:Cart\tsignature:($artnr, $num)\ntyte\tinput.php\t/^$tyte = 'mansikka';    \\/\\/ valid; '' is ASCII 228.$/;\"\tv\nvar\tinput.php\t/^$var = \"Bob\";$/;\"\tv\n"
  },
  {
    "path": "Units/parser-php.r/php-simple.d/input.php",
    "content": "// Examples from PHP Language Reference at\n//   http://www.php.net/manual/en/langref.php\n\n<?php\n$var = \"Bob\";\n$Var = \"Joe\";\necho \"$var, $Var\";      // outputs \"Bob, Joe\"\n\n$4site = 'not yet';     // invalid; starts with a number\n$_4site = 'not yet';    // valid; starts with an underscore\n$tyte = 'mansikka';    // valid; '' is ASCII 228.\n?>\n\n<?php\ndefine(\"CONSTANT\", \"Hello world.\");\necho CONSTANT; // outputs \"Hello world.\"\necho Constant; // outputs \"Constant\" and issues a notice.\n?>\n\n<?php\nfunction foo ($arg_1, $arg_2, ..., $arg_n)\n{\n    echo \"Example function.\\n\";\n    return $retval;\n}\n\nclass Cart\n{\n    var $items;  // Items in our shopping cart\n   \n    // Add $num articles of $artnr to the cart\n \n    function add_item ($artnr, $num)\n    {\n        $this->items[$artnr] += $num;\n    }\n   \n    // Take $num articles of $artnr out of the cart\n \n    function remove_item ($artnr, $num)\n    {\n        if ($this->items[$artnr] > $num) {\n            $this->items[$artnr] -= $num;\n            return true;\n        } else {\n            return false;\n        }   \n    }\n}\n"
  },
  {
    "path": "Units/parser-php.r/php-strings.d/expected.tags",
    "content": "a\tinput.php\t/^$a = \"hello\";$/;\"\tv\nb\tinput.php\t/^$b = 'hello';$/;\"\tv\nc\tinput.php\t/^$c = \"hello \\\\\"buddy\\\\\"\";$/;\"\tv\nd\tinput.php\t/^$d = 'hello \\\\'buddy\\\\'';$/;\"\tv\ne\tinput.php\t/^$e = <<<EOS$/;\"\tv\nf\tinput.php\t/^$f = <<<'EOS'$/;\"\tv\ng\tinput.php\t/^$g = <<<\"EOS\"$/;\"\tv\nzzz_end\tinput.php\t/^$zzz_end = 42;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-php.r/php-strings.d/input.php",
    "content": "<?php\n\n$a = \"hello\";\n\n$b = 'hello';\n\n$c = \"hello \\\"buddy\\\"\";\n\n$d = 'hello \\'buddy\\'';\n\n$e = <<<EOS\nhello buddy\nEOS;\n\n$f = <<<'EOS'\nhello buddy\nEOS;\n\n$g = <<<\"EOS\"\nhello buddy\nEOS;\n\n# just to check we're correctly out of a string here\n$zzz_end = 42;\n"
  },
  {
    "path": "Units/parser-php.r/php-traits.d/args.ctags",
    "content": "--fields=afikmsS\n"
  },
  {
    "path": "Units/parser-php.r/php-traits.d/expected.tags",
    "content": "A\tinput.php\t/^class A {$/;\"\tc\nB\tinput.php\t/^class B {$/;\"\tc\n__construct\tinput.php\t/^\tpublic function __construct($p) {$/;\"\tf\tclass:B\taccess:public\tsignature:($p)\n__construct\tinput.php\t/^\tpublic function __construct() {$/;\"\tf\tclass:A\taccess:public\tsignature:()\nprop1\tinput.php\t/^\tprotected $prop1 = 0;$/;\"\tv\ttrait:tBar\taccess:protected\nprop2\tinput.php\t/^\tprotected $prop2;$/;\"\tv\ttrait:tBar\taccess:protected\nstuff\tinput.php\t/^\tprotected function stuff($arg1, $arg2) {$/;\"\tf\ttrait:tBar\taccess:protected\tsignature:($arg1, $arg2)\nstuff\tinput.php\t/^\tpublic function stuff() {$/;\"\tf\ttrait:tFoo\taccess:public\tsignature:()\ntBar\tinput.php\t/^trait tBar {$/;\"\tt\ntFoo\tinput.php\t/^trait tFoo {$/;\"\tt\n"
  },
  {
    "path": "Units/parser-php.r/php-traits.d/input.php",
    "content": "Tests for traits\n\nExpected output is\n\ntraits:\n\ttBar\n\ttFoo\n\nclasses:\n\tA\n\tB\n\nfunctions:\n\t__construct [A]\n\t__construct [B]\n\tstuff [tFoo]\n\tstuff [tBar]\n\nvariables:\n\tprop1 [tBar]\n\tprop2 [tBar]\n\n<?php\n\ntrait tFoo {\n\tpublic function stuff() {\n\t\t// ...\n\t}\n}\n\nclass A {\n\tuse tFoo;\n\t\n\tpublic function __construct() {\n\t\t// ...\n\t}\n}\n\ntrait tBar {\n\tprotected $prop1 = 0;\n\tprotected $prop2;\n\n\tprotected function stuff($arg1, $arg2) {\n\t\t// ...\n\t}\n}\n\nclass B {\n\tuse tBar;\n\t\n\tpublic function __construct($p) {\n\t\t// ...\n\t}\n}\n"
  },
  {
    "path": "Units/parser-php.r/php-use.d/expected.tags",
    "content": "CONST\tinput.php\t/^    const CONST = 1;$/;\"\td\tclass:NS\\\\Cls\nClassFour\tinput.php\t/^  use NS2\\\\{NS30 as NameSpaceTreePointO, NS31\\\\Cls4 as ClassFour};$/;\"\ta\ttyperef:unknown:NS2\\\\NS31\\\\Cls4\nCls\tinput.php\t/^  class Cls implements Iface {$/;\"\tc\tnamespace:NS\nCls\tinput.php\t/^  class Cls implements NSIface {$/;\"\tc\tnamespace:NS2\nCls\tinput.php\t/^  use NS\\\\Cls;$/;\"\ta\ttyperef:unknown:NS\\\\Cls\nCls2\tinput.php\t/^  use NS2\\\\Cls as Cls2;$/;\"\ta\ttyperef:unknown:NS2\\\\Cls\nCls3\tinput.php\t/^  class Cls3 {}$/;\"\tc\tnamespace:NS2\\\\NS30\nCls4\tinput.php\t/^  class Cls4 {}$/;\"\tc\tnamespace:NS2\\\\NS31\nCls4\tinput.php\t/^  use NS2\\\\{NS30, NS31\\\\Cls4};$/;\"\ta\ttyperef:unknown:NS2\\\\NS31\\\\Cls4\nFOO\tinput.php\t/^  const FOO = 1;$/;\"\td\tnamespace:NS\nFOO\tinput.php\t/^  use const NS\\\\FOO;$/;\"\ta\tnamespace:NS2\ttyperef:define:NS\\\\FOO\nIface\tinput.php\t/^  interface Iface extends NSIface {$/;\"\ti\tnamespace:NS2\nIface\tinput.php\t/^  interface Iface {$/;\"\ti\tnamespace:NS\nIface\tinput.php\t/^  use NS2\\\\{Cls as NS2Cls, Iface};$/;\"\ta\ttyperef:unknown:NS2\\\\Iface\nMYCONST\tinput.php\t/^  use const NS\\\\FOO as MYCONST;$/;\"\ta\ttyperef:define:NS\\\\FOO\nNS\tinput.php\t/^namespace NS {$/;\"\tn\nNS2\tinput.php\t/^namespace NS2 {$/;\"\tn\nNS2Cls\tinput.php\t/^  use NS2\\\\{Cls as NS2Cls, Iface};$/;\"\ta\ttyperef:unknown:NS2\\\\Cls\nNS2\\\\NS30\tinput.php\t/^namespace NS2\\\\NS30 {$/;\"\tn\nNS2\\\\NS30\\\\NS301\tinput.php\t/^namespace NS2\\\\NS30\\\\NS301 {}$/;\"\tn\nNS2\\\\NS30\\\\NS302\tinput.php\t/^namespace NS2\\\\NS30\\\\NS302 {}$/;\"\tn\nNS2\\\\NS31\tinput.php\t/^namespace NS2\\\\NS31 {$/;\"\tn\nNS30\tinput.php\t/^  use NS2\\\\{NS30, NS31\\\\Cls4};$/;\"\ta\ttyperef:unknown:NS2\\\\NS30\nNSCls\tinput.php\t/^  use NS\\\\Iface as NSIface, NS\\\\Cls as NSCls;$/;\"\ta\tnamespace:NS2\ttyperef:unknown:NS\\\\Cls\nNSIface\tinput.php\t/^  use NS\\\\Iface as NSIface, NS\\\\Cls as NSCls;$/;\"\ta\tnamespace:NS2\ttyperef:unknown:NS\\\\Iface\nNameSpaceTreePointO\tinput.php\t/^  use NS2\\\\{NS30 as NameSpaceTreePointO, NS31\\\\Cls4 as ClassFour};$/;\"\ta\ttyperef:unknown:NS2\\\\NS30\nNameSpaceTreePointZero\tinput.php\t/^  use NS2\\\\{NS30 as NameSpaceTreePointZero,};$/;\"\ta\ttyperef:unknown:NS2\\\\NS30\nSomeAliasedNS\tinput.php\t/^  use NS as SomeAliasedNS;$/;\"\ta\ttyperef:unknown:NS\ncls\tinput.php\t/^  $cls = new Cls2;$/;\"\tv\ncls\tinput.php\t/^  $cls = new Cls;$/;\"\tv\nfoo\tinput.php\t/^    private $foo = FOO;$/;\"\tv\tclass:NS2\\\\Cls\nhello\tinput.php\t/^    public function hello() {$/;\"\tf\tclass:NS2\\\\Cls\nhello\tinput.php\t/^    public function hello() {$/;\"\tf\tclass:NS\\\\Cls\nhello\tinput.php\t/^    public function hello();$/;\"\tf\tinterface:NS\\\\Iface\ntest\tinput.php\t/^  function test() {$/;\"\tf\tnamespace:NS\ntest\tinput.php\t/^  use function NS\\\\test;$/;\"\ta\ttyperef:function:NS\\\\test\n"
  },
  {
    "path": "Units/parser-php.r/php-use.d/input.php",
    "content": "<?php\n\nnamespace NS {\n  const FOO = 1;\n  \n  interface Iface {\n    public function hello();\n  }\n  \n  class Cls implements Iface {\n    const CONST = 1;\n    \n    public function hello() {\n      echo \"hi\\n\";\n    }\n  }\n    \n  function test() {\n    echo \"test\\n\";\n  }\n}\n\nnamespace NS2 {\n  use NS\\Iface as NSIface, NS\\Cls as NSCls;\n  use const NS\\FOO;\n  \n  interface Iface extends NSIface {\n    \n  }\n  \n  class Cls implements NSIface {\n    private $foo = FOO;\n    \n    public function hello() {\n      echo \"hello \",$this->foo,\"\\n\";\n    }\n  }\n}\n\nnamespace NS2\\NS30 {\n  class Cls3 {}\n}\n\nnamespace NS2\\NS31 {\n  class Cls4 {}\n}\n\nnamespace NS2\\NS30\\NS301 {}\nnamespace NS2\\NS30\\NS302 {}\n\nnamespace {\n  use NS as SomeAliasedNS;\n  use NS\\Cls;\n  use NS2\\Cls as Cls2;\n  use const NS\\FOO as MYCONST;\n  use function NS\\test;\n  use NS2\\{Cls as NS2Cls, Iface};\n  use NS2\\{NS30, NS31\\Cls4};\n  use NS2\\{NS30 as NameSpaceTreePointO, NS31\\Cls4 as ClassFour};\n  use NS2\\{NS30 as NameSpaceTreePointZero,};\n  \n  $cls = new Cls;\n  echo $cls::CONST, \"\\n\";\n  echo MYCONST, \"\\n\";\n  \n  $cls->hello();\n  \n  test();\n  \n  $cls = new Cls2;\n  $cls->hello();\n  \n  new ClassFour;\n  new NameSpaceTreePointO\\Cls3;\n}\n"
  },
  {
    "path": "Units/parser-php.r/php-whitespaces.d/expected.tags",
    "content": "a\tinput.php\t/^function\ta\t()\t{}$/;\"\tf\nb\tinput.php\t/^b$/;\"\tf\nc\tinput.php\t/^function\u000bc\u000b()\u000b{}$/;\"\tf\nd\tinput.php\t/^function\fd\f()\f{}$/;\"\tf\ne\tinput.php\t/^function$/;\"\tf\nf\tinput.php\t/^function f () {}$/;\"\tf\ng\tinput.php\t/^\u000b\f$/;\"\tf\nh\tinput.php\t/^function h(){}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-php.r/php-whitespaces.d/input.php",
    "content": "<?php\n\nfunction\ta\t()\t{}\n\nfunction\nb\n()\n{}\n\nfunction\u000bc\u000b()\u000b{}\n\nfunction\fd\f()\f{}\n\nfunction\re\r()\r{}\n\nfunction f () {}\n\nfunction\t\n\u000b\f\r g\t\n \u000b\f ()\t\n \u000b\f {}\n\nfunction h(){}\n\n\n/* for live PHP tests */\nvar_dump(a());\nvar_dump(b());\nvar_dump(c());\nvar_dump(d());\nvar_dump(e());\nvar_dump(f());\nvar_dump(g());\nvar_dump(h());\n"
  },
  {
    "path": "Units/parser-php.r/php-whitespaces.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/parser-php.r/run-as-guest-with-bom.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+en\n"
  },
  {
    "path": "Units/parser-php.r/run-as-guest-with-bom.d/expected.tags",
    "content": "EOF\tinput.sh\t/^cat > input.php <<'EOF'$/;\"\th\tline:1\tend:5\ndraw\tinput.sh\t/^<html><head><title>X<\\/title><?php function draw($x) {echo \"$x\";} ?><\\/head><body><h1>Y<\\/h1><\\//;\"\tf\tline:2\nX\tinput.sh\t/^<html><head><title>X<\\/title>/;\"\tj\tline:2\nY\tinput.sh\t/<\\/head><body><h1>Y<\\/h1><\\/body>$/;\"\th\tline:2\nZ\tinput.sh\t/^<h1>Z<\\/h1><\\/body>$/;\"\th\tline:3\n"
  },
  {
    "path": "Units/parser-php.r/run-as-guest-with-bom.d/input.sh",
    "content": "﻿cat > input.php <<'EOF'\n<html><head><title>X</title><?php function draw($x) {echo \"$x\";} ?></head><body><h1>Y</h1></body>\n<h1>Z</h1></body>\n</html>\nEOF\n"
  },
  {
    "path": "Units/parser-php.r/run-as-guest.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+en\n"
  },
  {
    "path": "Units/parser-php.r/run-as-guest.d/expected.tags",
    "content": "EOF\tinput.sh\t/^cat > input.php <<'EOF'$/;\"\th\tline:1\tend:5\ndraw\tinput.sh\t/^<html><head><title>X<\\/title><?php function draw($x) {echo \"$x\";} ?><\\/head><body><h1>Y<\\/h1><\\//;\"\tf\tline:2\nX\tinput.sh\t/^<html><head><title>X<\\/title>/;\"\tj\tline:2\nY\tinput.sh\t/<\\/head><body><h1>Y<\\/h1><\\/body>$/;\"\th\tline:2\nZ\tinput.sh\t/^<h1>Z<\\/h1><\\/body>$/;\"\th\tline:3\n"
  },
  {
    "path": "Units/parser-php.r/run-as-guest.d/input.sh",
    "content": "cat > input.php <<'EOF'\n<html><head><title>X</title><?php function draw($x) {echo \"$x\";} ?></head><body><h1>Y</h1></body>\n<h1>Z</h1></body>\n</html>\nEOF\n"
  },
  {
    "path": "Units/parser-php.r/run-guest-nested.d/args.ctags",
    "content": "--sort=yes\n--extras=+rg\n--fields=+rln\n--language-force=html\n"
  },
  {
    "path": "Units/parser-php.r/run-guest-nested.d/expected.tags",
    "content": ".blarg\tinput.php\t/^.blarg {$/;\"\tc\tline:31\tlanguage:CSS\troles:def\nMy Home Page\tinput.php\t/^    <title>My Home Page<\\/title>$/;\"\tj\tline:8\tlanguage:HTML\troles:def\nX\tinput.php\t/^<html><head><title>X<\\/title>$/;\"\tj\tline:1\tlanguage:HTML\troles:def\ncss/general.css\tinput.php\t/^    <link rel=\"stylesheet\" href=\"css\\/general.css\" type=\"text\\/css\">$/;\"\tC\tline:9\tlanguage:HTML\troles:extFile\ndraw\tinput.php\t/^  function draw($x) {$/;\"\tf\tline:3\tlanguage:PHP\troles:def\nf1\tinput.php\t/^    var f1 = function (n) {$/;\"\tf\tline:21\tlanguage:JavaScript\troles:def\nf2\tinput.php\t/^    var f2 = function (m) {$/;\"\tf\tline:26\tlanguage:JavaScript\troles:def\nnothing\tinput.php\t/^  function nothing($x) {$/;\"\tf\tline:36\tlanguage:PHP\troles:def\nstuff\tinput.php\t/^    <h1>stuff<\\/h1>$/;\"\th\tline:13\tlanguage:HTML\troles:def\n"
  },
  {
    "path": "Units/parser-php.r/run-guest-nested.d/input.php",
    "content": "<html><head><title>X</title>\n<?php // This test input is derived from #2256 submitted by @StephenWall.\n  function draw($x) {\n      echo \"$x\";\n  }\n?>\n    <meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\">\n    <title>My Home Page</title>\n    <link rel=\"stylesheet\" href=\"css/general.css\" type=\"text/css\">\n    <style type=\"text/css\"></stylE>\n  </head>\n  <body>\n    <h1>stuff</h1>\n    <a href=\"/blah\">nowhere</a>\n    <?=draw('nowhere')?>\n    <a href=\"/blech\">somewhere</a>\n    <?=draw('somewhere')?>\n  </body>\n</html>\n<script>\n    var f1 = function (n) {\n\treturn n + <?php /* some value */ ?>;\n    }\n</script>\n<script>\n    var f2 = function (m) {\n\treturn m + <% /* some value from JSP */ %>;\n    }\n</script>\n<style>\n.blarg {\n    position: relative;\n}\n</style>\n<?php\n  function nothing($x) {\n      ;\n  }\n?>\n"
  },
  {
    "path": "Units/parser-php.r/run-guest-with-bom.d/args.ctags",
    "content": "--sort=no\n--extras=+rg\n--fields=+rln\n"
  },
  {
    "path": "Units/parser-php.r/run-guest-with-bom.d/expected.tags",
    "content": "draw\tinput.php\t/^  function draw($x) {$/;\"\tf\tline:3\tlanguage:PHP\troles:def\nnothing\tinput.php\t/^  function nothing($x) {$/;\"\tf\tline:31\tlanguage:PHP\troles:def\nX\tinput.php\t/^<html><head><title>X<\\/title>$/;\"\tj\tline:1\tlanguage:HTML\troles:def\nMy Home Page\tinput.php\t/^    <title>My Home Page<\\/title>$/;\"\tj\tline:8\tlanguage:HTML\troles:def\ncss/general.css\tinput.php\t/^    <link rel=\"stylesheet\" href=\"css\\/general.css\" type=\"text\\/css\">$/;\"\tC\tline:9\tlanguage:HTML\troles:extFile\nstuff\tinput.php\t/^    <h1>stuff<\\/h1>$/;\"\th\tline:13\tlanguage:HTML\troles:def\nf\tinput.php\t/^    var f = function (n) {$/;\"\tf\tline:21\tlanguage:JavaScript\troles:def\n.blarg\tinput.php\t/^.blarg {$/;\"\tc\tline:26\tlanguage:CSS\troles:def\n"
  },
  {
    "path": "Units/parser-php.r/run-guest-with-bom.d/input.php",
    "content": "﻿<html><head><title>X</title>\n<?php // This test input is derived from #2256 submitted by @StephenWall.\n  function draw($x) {\n      echo \"$x\";\n  }\n?>\n    <meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\">\n    <title>My Home Page</title>\n    <link rel=\"stylesheet\" href=\"css/general.css\" type=\"text/css\">\n    <style type=\"text/css\"></stylE>\n  </head>\n  <body>\n    <h1>stuff</h1>\n    <a href=\"/blah\">nowhere</a>\n    <?=draw('nowhere')?>\n    <a href=\"/blech\">somewhere</a>\n    <?=draw('somewhere')?>\n  </body>\n</html>\n<script>\n    var f = function (n) {\n\treturn n + 1;\n    }\n</script>\n<style>\n.blarg {\n    position: relative;\n}\n</style>\n<?php\n  function nothing($x) {\n      ;\n  }\n?>"
  },
  {
    "path": "Units/parser-php.r/run-guest.d/args.ctags",
    "content": "--sort=no\n--extras=+rg\n--fields=+rln\n"
  },
  {
    "path": "Units/parser-php.r/run-guest.d/expected.tags",
    "content": "draw\tinput.php\t/^  function draw($x) {$/;\"\tf\tline:3\tlanguage:PHP\troles:def\nnothing\tinput.php\t/^  function nothing($x) {$/;\"\tf\tline:31\tlanguage:PHP\troles:def\nX\tinput.php\t/^<html><head><title>X<\\/title>$/;\"\tj\tline:1\tlanguage:HTML\troles:def\nMy Home Page\tinput.php\t/^    <title>My Home Page<\\/title>$/;\"\tj\tline:8\tlanguage:HTML\troles:def\ncss/general.css\tinput.php\t/^    <link rel=\"stylesheet\" href=\"css\\/general.css\" type=\"text\\/css\">$/;\"\tC\tline:9\tlanguage:HTML\troles:extFile\nstuff\tinput.php\t/^    <h1>stuff<\\/h1>$/;\"\th\tline:13\tlanguage:HTML\troles:def\nf\tinput.php\t/^    var f = function (n) {$/;\"\tf\tline:21\tlanguage:JavaScript\troles:def\n.blarg\tinput.php\t/^.blarg {$/;\"\tc\tline:26\tlanguage:CSS\troles:def\n"
  },
  {
    "path": "Units/parser-php.r/run-guest.d/input.php",
    "content": "<html><head><title>X</title>\n<?php // This test input is derived from #2256 submitted by @StephenWall.\n  function draw($x) {\n      echo \"$x\";\n  }\n?>\n    <meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\">\n    <title>My Home Page</title>\n    <link rel=\"stylesheet\" href=\"css/general.css\" type=\"text/css\">\n    <style type=\"text/css\"></stylE>\n  </head>\n  <body>\n    <h1>stuff</h1>\n    <a href=\"/blah\">nowhere</a>\n    <?=draw('nowhere')?>\n    <a href=\"/blech\">somewhere</a>\n    <?=draw('somewhere')?>\n  </body>\n</html>\n<script>\n    var f = function (n) {\n\treturn n + 1;\n    }\n</script>\n<style>\n.blarg {\n    position: relative;\n}\n</style>\n<?php\n  function nothing($x) {\n      ;\n  }\n?>"
  },
  {
    "path": "Units/parser-php.r/simple.php.d/expected.tags",
    "content": "4site\tinput.php\t/^$4site = 'not yet';     \\/\\/ invalid; starts with a number$/;\"\tv\nCONSTANT\tinput.php\t/^define(\"CONSTANT\", \"Hello world.\");$/;\"\td\nCart\tinput.php\t/^class Cart$/;\"\tc\nVar\tinput.php\t/^$Var = \"Joe\";$/;\"\tv\n_4site\tinput.php\t/^$_4site = 'not yet';    \\/\\/ valid; starts with an underscore$/;\"\tv\nadd_item\tinput.php\t/^    function add_item ($artnr, $num)$/;\"\tf\tclass:Cart\nfoo\tinput.php\t/^function foo ($arg_1, $arg_2, ..., $arg_n)$/;\"\tf\nitems\tinput.php\t/^    var $items;  \\/\\/ Items in our shopping cart$/;\"\tv\tclass:Cart\nremove_item\tinput.php\t/^    function remove_item ($artnr, $num)$/;\"\tf\tclass:Cart\ntyte\tinput.php\t/^$tyte = 'mansikka';    \\/\\/ valid; '' is ASCII 228.$/;\"\tv\nvar\tinput.php\t/^$var = \"Bob\";$/;\"\tv\n"
  },
  {
    "path": "Units/parser-php.r/simple.php.d/input.php",
    "content": "// Examples from PHP Language Reference at\n//   http://www.php.net/manual/en/langref.php\n\n<?php\n$var = \"Bob\";\n$Var = \"Joe\";\necho \"$var, $Var\";      // outputs \"Bob, Joe\"\n\n$4site = 'not yet';     // invalid; starts with a number\n$_4site = 'not yet';    // valid; starts with an underscore\n$tyte = 'mansikka';    // valid; '' is ASCII 228.\n?>\n\n<?php\ndefine(\"CONSTANT\", \"Hello world.\");\necho CONSTANT; // outputs \"Hello world.\"\necho Constant; // outputs \"Constant\" and issues a notice.\n?>\n\n<?php\nfunction foo ($arg_1, $arg_2, ..., $arg_n)\n{\n    echo \"Example function.\\n\";\n    return $retval;\n}\n\nclass Cart\n{\n    var $items;  // Items in our shopping cart\n   \n    // Add $num articles of $artnr to the cart\n \n    function add_item ($artnr, $num)\n    {\n        $this->items[$artnr] += $num;\n    }\n   \n    // Take $num articles of $artnr out of the cart\n \n    function remove_item ($artnr, $num)\n    {\n        if ($this->items[$artnr] > $num) {\n            $this->items[$artnr] -= $num;\n            return true;\n        } else {\n            return false;\n        }   \n    }\n}\n"
  },
  {
    "path": "Units/parser-php.r/traits.php.d/expected.tags",
    "content": "A\tinput.php\t/^class A {$/;\"\tc\nB\tinput.php\t/^class B {$/;\"\tc\n__construct\tinput.php\t/^\tpublic function __construct($p) {$/;\"\tf\tclass:B\n__construct\tinput.php\t/^\tpublic function __construct() {$/;\"\tf\tclass:A\nstuff\tinput.php\t/^\tprotected function stuff($arg1, $arg2) {$/;\"\tf\ttrait:tBar\nstuff\tinput.php\t/^\tpublic function stuff() {$/;\"\tf\ttrait:tFoo\ntBar\tinput.php\t/^trait tBar {$/;\"\tt\ntFoo\tinput.php\t/^trait tFoo {$/;\"\tt\n"
  },
  {
    "path": "Units/parser-php.r/traits.php.d/input.php",
    "content": "Tests for traits\n\nExpected output is\n\ntraits:\n\ttBar\n\ttFoo\n\nclasses:\n\tA\n\tB\n\nfunctions:\n\t__construct [A]\n\t__construct [B]\n\tstuff [tFoo]\n\tstuff [tBar]\n\n<?php\n\ntrait tFoo {\n\tpublic function stuff() {\n\t\t// ...\n\t}\n}\n\nclass A {\n\tuse tFoo;\n\t\n\tpublic function __construct() {\n\t\t// ...\n\t}\n}\n\ntrait tBar {\n\tprotected function stuff($arg1, $arg2) {\n\t\t// ...\n\t}\n}\n\nclass B {\n\tuse tBar;\n\t\n\tpublic function __construct($p) {\n\t\t// ...\n\t}\n}\n"
  },
  {
    "path": "Units/parser-php.r/whitespaces.php.d/expected.tags",
    "content": "a\tinput.php\t/^function\ta\t()\t{}$/;\"\tf\nb\tinput.php\t/^b$/;\"\tf\nc\tinput.php\t/^function\u000bc\u000b()\u000b{}$/;\"\tf\nd\tinput.php\t/^function\fd\f()\f{}$/;\"\tf\ne\tinput.php\t/^function$/;\"\tf\nf\tinput.php\t/^function f () {}$/;\"\tf\ng\tinput.php\t/^\u000b\f$/;\"\tf\nh\tinput.php\t/^function h(){}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-php.r/whitespaces.php.d/input.php",
    "content": "Tests for whitespaces\n\nExpected output is\n\nfunctions:\n\ta\n\tb\n\tc\n\td\n\te\n\tf\n\tg\n\th\n\n<?php\n\nfunction\ta\t()\t{}\n\nfunction\nb\n()\n{}\n\nfunction\u000bc\u000b()\u000b{}\n\nfunction\fd\f()\f{}\n\nfunction\re\r()\r{}\n\nfunction f () {}\n\nfunction\t\n\u000b\f\r g\t\n \u000b\f ()\t\n \u000b\f {}\n\nfunction h(){}\n\n\n/* for live PHP tests */\nvar_dump(a());\nvar_dump(b());\nvar_dump(c());\nvar_dump(d());\nvar_dump(e());\nvar_dump(f());\nvar_dump(g());\nvar_dump(h());\n"
  },
  {
    "path": "Units/parser-php.r/whitespaces.php.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/parser-php.r/wp-guest-crlf.b/.gitattributes",
    "content": "input.php text eol=crlf\n"
  },
  {
    "path": "Units/parser-php.r/wp-guest-crlf.b/args.ctags",
    "content": "--sort=no\n--extras=+rg\n--fields=+rln\n"
  },
  {
    "path": "Units/parser-php.r/wp-guest-crlf.b/expected.tags",
    "content": "top\tinput.php\t/^<div id=\"top\">$/;\"\tI\tline:3\tlanguage:HTML\troles:def\ninner\tinput.php\t/^ <div class=\"inner\">$/;\"\tc\tline:4\tlanguage:HTML\troles:attribute\nlogo\tinput.php\t/^<div id=\"logo\">$/;\"\tI\tline:6\tlanguage:HTML\troles:def\npages\tinput.php\t/^<div id=\"pages\">$/;\"\tI\tline:12\tlanguage:HTML\troles:def\nmenubar\tinput.php\t/^<ul class=\"menubar\" id=\"menubar\">$/;\"\tc\tline:13\tlanguage:HTML\troles:attribute\nmenubar\tinput.php\t/^<ul class=\"menubar\" id=\"menubar\">$/;\"\tI\tline:13\tlanguage:HTML\troles:def\nbody\tinput.php\t/^<div id=\"body\">$/;\"\tI\tline:26\tlanguage:HTML\troles:def\ncontent\tinput.php\t/^  <main id=\"content\">$/;\"\tI\tline:27\tlanguage:HTML\troles:def\npost\tinput.php\t/^  <article class=\"post\" id=\"post-/;\"\tc\tline:31\tlanguage:HTML\troles:attribute\npost-\tinput.php\t/^  <article class=\"post\" id=\"post-/;\"\tI\tline:31\tlanguage:HTML\troles:def\nstorybody\tinput.php\t/^    <div class=\"storybody\"><br \\/>/;\"\tc\tline:37\tlanguage:HTML\troles:attribute\npostmetadata\tinput.php\t/^    <p class=\"postmetadata\"><\\/p>$/;\"\tc\tline:38\tlanguage:HTML\troles:attribute\nstorybody\tinput.php\t/^     <div class=\"storybody\">/;\"\tc\tline:41\tlanguage:HTML\troles:attribute\nleft\tinput.php\t/^  <aside id=\"left\">/;\"\tI\tline:52\tlanguage:HTML\troles:def\n"
  },
  {
    "path": "Units/parser-php.r/wp-guest-crlf.b/input.php",
    "content": "<?php get_header(); ?>\r\n\r\n<div id=\"top\">\r\n <div class=\"inner\">\r\n  <br clear=\"all\" />\r\n<div id=\"logo\">\r\n<h2><a href=\"<?php bloginfo('url'); ?>\"><?php bloginfo('name'); ?></a></h2>\r\n<p>\r\n  <?php bloginfo('description'); ?>\r\n</p>\r\n</div>\r\n<div id=\"pages\">\r\n<ul class=\"menubar\" id=\"menubar\">\r\n  <li><a href=\"<?php bloginfo('url'); ?>\">Accueil</a></li>\r\n  <?php montheme_list_pages( array( 'depth' => 1 ) ); ?>\r\n</ul>\r\n<!--[if !IE]><-->\r\n<script type=\"text/javascript\">\r\n  initMenu (document.getElementById ('menubar'), 0);\r\n</script>\r\n<!--><![endif]-->\r\n</div>\r\n </div>\r\n</div>\r\n\r\n<div id=\"body\">\r\n  <main id=\"content\">\r\n\r\n  <?php if (have_posts()) : while (have_posts()) : the_post(); ?><br /><br />\r\n\r\n  <article class=\"post\" id=\"post-<?php the_ID(); ?>\">\r\n\r\n   <div class=\"storycontent\">\r\n\r\n    <h3><a href=\"<?php the_permalink() ?>\" rel=\"bookmark\"><?php the_title(); ?></a></h3>\r\n   \r\n    <div class=\"storybody\"><br /><?php the_content(__('(more...)')); ?></div>\r\n    <p class=\"postmetadata\"></p>\r\n    \r\n   </div>\r\n     <div class=\"storybody\"><?php comments_template(); // Get wp-comments.php template ?></div>\r\n  </article>\r\n\r\n\r\n  <?php endwhile; else: ?>\r\n  <p><?php _e('Sorry, no posts matched your criteria.'); ?></p>\r\n  <?php endif; ?>\r\n\r\n  <?php posts_nav_link(' &#8212; ', __('&laquo; Previous Page'), __('Next Page &raquo;')); ?>\r\n\r\n  </main>\r\n  <aside id=\"left\"><?php get_sidebar(); ?></aside>\r\n</div>\r\n\r\n<?php get_footer(); ?>\r\n"
  },
  {
    "path": "Units/parser-php.r/wp-guest-with-bom.d/args.ctags",
    "content": "--sort=no\n--extras=+rg\n--fields=+rln\n"
  },
  {
    "path": "Units/parser-php.r/wp-guest-with-bom.d/expected.tags",
    "content": "top\tinput.php\t/^<div id=\"top\">$/;\"\tI\tline:3\tlanguage:HTML\troles:def\ninner\tinput.php\t/^ <div class=\"inner\">$/;\"\tc\tline:4\tlanguage:HTML\troles:attribute\nlogo\tinput.php\t/^<div id=\"logo\">$/;\"\tI\tline:6\tlanguage:HTML\troles:def\npages\tinput.php\t/^<div id=\"pages\">$/;\"\tI\tline:12\tlanguage:HTML\troles:def\nmenubar\tinput.php\t/^<ul class=\"menubar\" id=\"menubar\">$/;\"\tc\tline:13\tlanguage:HTML\troles:attribute\nmenubar\tinput.php\t/^<ul class=\"menubar\" id=\"menubar\">$/;\"\tI\tline:13\tlanguage:HTML\troles:def\nbody\tinput.php\t/^<div id=\"body\">$/;\"\tI\tline:26\tlanguage:HTML\troles:def\ncontent\tinput.php\t/^  <main id=\"content\">$/;\"\tI\tline:27\tlanguage:HTML\troles:def\npost\tinput.php\t/^  <article class=\"post\" id=\"post-/;\"\tc\tline:31\tlanguage:HTML\troles:attribute\npost-\tinput.php\t/^  <article class=\"post\" id=\"post-/;\"\tI\tline:31\tlanguage:HTML\troles:def\nstorybody\tinput.php\t/^    <div class=\"storybody\"><br \\/>/;\"\tc\tline:37\tlanguage:HTML\troles:attribute\npostmetadata\tinput.php\t/^    <p class=\"postmetadata\"><\\/p>$/;\"\tc\tline:38\tlanguage:HTML\troles:attribute\nstorybody\tinput.php\t/^     <div class=\"storybody\">/;\"\tc\tline:41\tlanguage:HTML\troles:attribute\nleft\tinput.php\t/^  <aside id=\"left\">/;\"\tI\tline:52\tlanguage:HTML\troles:def\n"
  },
  {
    "path": "Units/parser-php.r/wp-guest-with-bom.d/input.php",
    "content": "﻿<?php get_header(); ?>\n\n<div id=\"top\">\n <div class=\"inner\">\n  <br clear=\"all\" />\n<div id=\"logo\">\n<h2><a href=\"<?php bloginfo('url'); ?>\"><?php bloginfo('name'); ?></a></h2>\n<p>\n  <?php bloginfo('description'); ?>\n</p>\n</div>\n<div id=\"pages\">\n<ul class=\"menubar\" id=\"menubar\">\n  <li><a href=\"<?php bloginfo('url'); ?>\">Accueil</a></li>\n  <?php montheme_list_pages( array( 'depth' => 1 ) ); ?>\n</ul>\n<!--[if !IE]><-->\n<script type=\"text/javascript\">\n  initMenu (document.getElementById ('menubar'), 0);\n</script>\n<!--><![endif]-->\n</div>\n </div>\n</div>\n\n<div id=\"body\">\n  <main id=\"content\">\n\n  <?php if (have_posts()) : while (have_posts()) : the_post(); ?><br /><br />\n\n  <article class=\"post\" id=\"post-<?php the_ID(); ?>\">\n\n   <div class=\"storycontent\">\n\n    <h3><a href=\"<?php the_permalink() ?>\" rel=\"bookmark\"><?php the_title(); ?></a></h3>\n   \n    <div class=\"storybody\"><br /><?php the_content(__('(more...)')); ?></div>\n    <p class=\"postmetadata\"></p>\n    \n   </div>\n     <div class=\"storybody\"><?php comments_template(); // Get wp-comments.php template ?></div>\n  </article>\n\n\n  <?php endwhile; else: ?>\n  <p><?php _e('Sorry, no posts matched your criteria.'); ?></p>\n  <?php endif; ?>\n\n  <?php posts_nav_link(' &#8212; ', __('&laquo; Previous Page'), __('Next Page &raquo;')); ?>\n\n  </main>\n  <aside id=\"left\"><?php get_sidebar(); ?></aside>\n</div>\n\n<?php get_footer(); ?>\n"
  },
  {
    "path": "Units/parser-php.r/wp-guest.d/args.ctags",
    "content": "--sort=no\n--extras=+rg\n--fields=+rln\n"
  },
  {
    "path": "Units/parser-php.r/wp-guest.d/expected.tags",
    "content": "top\tinput.php\t/^<div id=\"top\">$/;\"\tI\tline:3\tlanguage:HTML\troles:def\ninner\tinput.php\t/^ <div class=\"inner\">$/;\"\tc\tline:4\tlanguage:HTML\troles:attribute\nlogo\tinput.php\t/^<div id=\"logo\">$/;\"\tI\tline:6\tlanguage:HTML\troles:def\npages\tinput.php\t/^<div id=\"pages\">$/;\"\tI\tline:12\tlanguage:HTML\troles:def\nmenubar\tinput.php\t/^<ul class=\"menubar\" id=\"menubar\">$/;\"\tc\tline:13\tlanguage:HTML\troles:attribute\nmenubar\tinput.php\t/^<ul class=\"menubar\" id=\"menubar\">$/;\"\tI\tline:13\tlanguage:HTML\troles:def\nbody\tinput.php\t/^<div id=\"body\">$/;\"\tI\tline:26\tlanguage:HTML\troles:def\ncontent\tinput.php\t/^  <main id=\"content\">$/;\"\tI\tline:27\tlanguage:HTML\troles:def\npost\tinput.php\t/^  <article class=\"post\" id=\"post-/;\"\tc\tline:31\tlanguage:HTML\troles:attribute\npost-\tinput.php\t/^  <article class=\"post\" id=\"post-/;\"\tI\tline:31\tlanguage:HTML\troles:def\nstorybody\tinput.php\t/^    <div class=\"storybody\"><br \\/>/;\"\tc\tline:37\tlanguage:HTML\troles:attribute\npostmetadata\tinput.php\t/^    <p class=\"postmetadata\"><\\/p>$/;\"\tc\tline:38\tlanguage:HTML\troles:attribute\nstorybody\tinput.php\t/^     <div class=\"storybody\">/;\"\tc\tline:41\tlanguage:HTML\troles:attribute\nleft\tinput.php\t/^  <aside id=\"left\">/;\"\tI\tline:52\tlanguage:HTML\troles:def\n"
  },
  {
    "path": "Units/parser-php.r/wp-guest.d/input.php",
    "content": "<?php get_header(); ?>\n\n<div id=\"top\">\n <div class=\"inner\">\n  <br clear=\"all\" />\n<div id=\"logo\">\n<h2><a href=\"<?php bloginfo('url'); ?>\"><?php bloginfo('name'); ?></a></h2>\n<p>\n  <?php bloginfo('description'); ?>\n</p>\n</div>\n<div id=\"pages\">\n<ul class=\"menubar\" id=\"menubar\">\n  <li><a href=\"<?php bloginfo('url'); ?>\">Accueil</a></li>\n  <?php montheme_list_pages( array( 'depth' => 1 ) ); ?>\n</ul>\n<!--[if !IE]><-->\n<script type=\"text/javascript\">\n  initMenu (document.getElementById ('menubar'), 0);\n</script>\n<!--><![endif]-->\n</div>\n </div>\n</div>\n\n<div id=\"body\">\n  <main id=\"content\">\n\n  <?php if (have_posts()) : while (have_posts()) : the_post(); ?><br /><br />\n\n  <article class=\"post\" id=\"post-<?php the_ID(); ?>\">\n\n   <div class=\"storycontent\">\n\n    <h3><a href=\"<?php the_permalink() ?>\" rel=\"bookmark\"><?php the_title(); ?></a></h3>\n   \n    <div class=\"storybody\"><br /><?php the_content(__('(more...)')); ?></div>\n    <p class=\"postmetadata\"></p>\n    \n   </div>\n     <div class=\"storybody\"><?php comments_template(); // Get wp-comments.php template ?></div>\n  </article>\n\n\n  <?php endwhile; else: ?>\n  <p><?php _e('Sorry, no posts matched your criteria.'); ?></p>\n  <?php endif; ?>\n\n  <?php posts_nav_link(' &#8212; ', __('&laquo; Previous Page'), __('Next Page &raquo;')); ?>\n\n  </main>\n  <aside id=\"left\"><?php get_sidebar(); ?></aside>\n</div>\n\n<?php get_footer(); ?>\n"
  },
  {
    "path": "Units/parser-php.r/xml.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-php.r/xml.d/input.php",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n<?php foreach ([1, 2, 3] as $id): ?>\n  <group id=\"<?=$id?>\">\n  <?php foreach (array('a', 'b', 'c') as $type): ?>\n    <node type=\"<?=$type?>\">A node of type <?=$type?></node>\n  <?php endforeach ?>\n  </group>\n<?php endforeach ?>\n</root>\n"
  },
  {
    "path": "Units/parser-pod.r/broken-levels.d/args.ctags",
    "content": "--sort=no\n--fields=+en\n"
  },
  {
    "path": "Units/parser-pod.r/broken-levels.d/expected.tags",
    "content": "L1\tinput.pod\t/^=head1 L1$/;\"\tc\tline:1\tend:6\nL3\tinput.pod\t/^=head3 L3$/;\"\tS\tline:2\tchapter:L1\tend:3\nL4\tinput.pod\t/^=head4 L4$/;\"\tt\tline:3\tsubsection:L1\"\"L3\tend:3\nL2\tinput.pod\t/^=head2 L2$/;\"\ts\tline:4\tchapter:L1\tend:6\nL3'\tinput.pod\t/^=head3 L3'$/;\"\tS\tline:5\tsection:L1\"\"L2\tend:6\n"
  },
  {
    "path": "Units/parser-pod.r/broken-levels.d/input.pod",
    "content": "=head1 L1\n=head3 L3\n=head4 L4\n=head2 L2\n=head3 L3'\n\n"
  },
  {
    "path": "Units/parser-pod.r/simple-pod.d/args.ctags",
    "content": "--sort=no\n--fields=+en\n"
  },
  {
    "path": "Units/parser-pod.r/simple-pod.d/expected.tags",
    "content": "NAME\tinput.pod\t/^=head1 NAME$/;\"\tc\tline:3\tend:6\nSYNOPSIS\tinput.pod\t/^=head1 SYNOPSIS$/;\"\tc\tline:7\tend:11\nDESCRIPTION\tinput.pod\t/^=head1 DESCRIPTION$/;\"\tc\tline:12\tend:13\nCONCEPTS\tinput.pod\t/^=head1 CONCEPTS$/;\"\tc\tline:14\tend:31\nKINDS\tinput.pod\t/^=head2 KINDS$/;\"\ts\tline:16\tchapter:CONCEPTS\tend:27\nC\tinput.pod\t/^=head3 C$/;\"\tS\tline:18\tsection:CONCEPTS\"\"KINDS\tend:22\nfunction\tinput.pod\t/^=head4 function$/;\"\tt\tline:20\tsubsection:CONCEPTS\"\"KINDS\"\"C\tend:20\nvariable\tinput.pod\t/^=head4 variable$/;\"\tt\tline:21\tsubsection:CONCEPTS\"\"KINDS\"\"C\tend:22\nPYTHON\tinput.pod\t/^=head3 PYTHON$/;\"\tS\tline:23\tsection:CONCEPTS\"\"KINDS\tend:27\nclass\tinput.pod\t/^=head4 class$/;\"\tt\tline:25\tsubsection:CONCEPTS\"\"KINDS\"\"PYTHON\tend:25\nmethod\tinput.pod\t/^=head4 method$/;\"\tt\tline:26\tsubsection:CONCEPTS\"\"KINDS\"\"PYTHON\tend:27\nFILEDS\tinput.pod\t/^=head2 FILEDS$/;\"\ts\tline:28\tchapter:CONCEPTS\tend:28\nEXTRA\tinput.pod\t/^=head2 EXTRA$/;\"\ts\tline:29\tchapter:CONCEPTS\tend:31\n"
  },
  {
    "path": "Units/parser-pod.r/simple-pod.d/input.pod",
    "content": "=pod\n\n=head1 NAME\n\nctags - Generate tag files for source code\n\n=head1 SYNOPSIS\n\n\tctags [options] [files]\n\tetags [options] [files]\n\n=head1 DESCRIPTION\n\n=head1 CONCEPTS\n\n=head2 KINDS\n\n=head3 C\n\n=head4 function\n=head4 variable\n\n=head3 PYTHON\n\n=head4 class\n=head4 method\n\n=head2 FILEDS\n=head2 EXTRA\n\n=cut\n"
  },
  {
    "path": "Units/parser-powershell.r/class-powershell.d/args.ctags",
    "content": "--sort=no\n# \"qualified\" extra doesn't work.\n# --extras=+q\n--fields=+S\n"
  },
  {
    "path": "Units/parser-powershell.r/class-powershell.d/expected.tags",
    "content": "MyException\tinput.ps1\t/^class MyException : Exception {$/;\"\tc\nDerived\tinput.ps1\t/^class Derived : Base {$/;\"\tc\nDerived2\tinput.ps1\t/^class Derived2: Base {$/;\"\tc\nFoo\tinput.ps1\t/^class Foo {$/;\"\tc\nGetBar\tinput.ps1\t/^function GetBar {$/;\"\tf\nGetBaz\tinput.ps1\t/^function GetBaz() {$/;\"\tf\tsignature:()\n"
  },
  {
    "path": "Units/parser-powershell.r/class-powershell.d/input.ps1",
    "content": "class MyException : Exception {\n    MyException([String]$Message) : base([String]$Message) {\n        Write-Host \"dummy\"\n    }\n}\n\nclass Derived : Base {\n}\n\nclass Derived2: Base {\n}\n\nclass Foo {\n    $Property1\n    $Property2 = 20\n    Method($Arg1) {\n        $LocalVar1 = 100\n        Write-Host \"dummy\"\n    }\n}\n\nfunction GetBar {\n    $LocalVar2 = 200\n    Write-Host \"dummy\"\n}\n\nfunction GetBaz() {\n    Write-Host \"dummy\"\n}\n"
  },
  {
    "path": "Units/parser-powershell.r/enum-powershell.d/args.ctags",
    "content": "--sort=no\n# \"qualified\" extra doesn't work.\n# --extras=+q\n--fields=+S\n"
  },
  {
    "path": "Units/parser-powershell.r/enum-powershell.d/expected.tags",
    "content": "EnumName1\tinput.ps1\t/^enum EnumName1 {$/;\"\tg\nLabel11\tinput.ps1\t/^    Label11$/;\"\te\tenum:EnumName1\nLabel12\tinput.ps1\t/^    Label12 = 10$/;\"\te\tenum:EnumName1\nEnumName2\tinput.ps1\t/^enum EnumName2 {$/;\"\tg\nLabel21\tinput.ps1\t/^    Label21$/;\"\te\tenum:EnumName2\nLabel22\tinput.ps1\t/^    Label22 = 20$/;\"\te\tenum:EnumName2\nEnumName3\tinput.ps1\t/^Enum EnumName3 {$/;\"\tg\nLabel31\tinput.ps1\t/^    Label31$/;\"\te\tenum:EnumName3\nLabel32\tinput.ps1\t/^    Label32 = 30$/;\"\te\tenum:EnumName3\nEnumName4\tinput.ps1\t/^[Flags()] enum EnumName4 {$/;\"\tg\nLabel41\tinput.ps1\t/^    Label41$/;\"\te\tenum:EnumName4\nLabel42\tinput.ps1\t/^    Label42 = 40$/;\"\te\tenum:EnumName4\n"
  },
  {
    "path": "Units/parser-powershell.r/enum-powershell.d/input.ps1",
    "content": "# EnumName1\nenum EnumName1 {\n    Label11\n    Label12 = 10\n}\n\n# EnumName2\nenum EnumName2 {\n    Label21\n    Label22 = 20\n}\n\n# EnumName3\nEnum EnumName3 {\n    Label31\n    Label32 = 30\n}\n\n# EnumName4\n[Flags()] enum EnumName4 {\n    Label41\n    Label42 = 40\n}\n"
  },
  {
    "path": "Units/parser-powershell.r/filter-powershell.d/args.ctags",
    "content": "--sort=no\n# \"qualified\" extra doesn't work.\n# --extras=+q\n--fields=+S\n"
  },
  {
    "path": "Units/parser-powershell.r/filter-powershell.d/expected.tags",
    "content": "f1\tinput.ps1\t/^filter f1 {$/;\"\ti\nf2\tinput.ps1\t/^filter f2() {$/;\"\ti\tsignature:()\nf3\tinput.ps1\t/^filter f3([switch]$Message) {$/;\"\ti\tsignature:([switch] $Message)\nf4\tinput.ps1\t/^filter f4 {$/;\"\ti\n"
  },
  {
    "path": "Units/parser-powershell.r/filter-powershell.d/input.ps1",
    "content": "filter f1 {\n}\n\nfilter f2() {\n}\n\nfilter f3([switch]$Message) {\n}\n\nfilter f4 {\n    $LocalVariable = 1\n}\n"
  },
  {
    "path": "Units/parser-powershell.r/herestring.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-powershell.r/herestring.d/expected.tags",
    "content": "a\tinput.ps1\t/^function a$/;\"\tf\nb\tinput.ps1\t/^function b$/;\"\tf\nc\tinput-0.ps1\t/^function c$/;\"\tf\nd\tinput-0.ps1\t/^function d$/;\"\tf\ne\tinput-1.ps1\t/^function e$/;\"\tf\nf\tinput-2.ps1\t/^function f$/;\"\tf\ng\tinput-3.ps1\t/^function g$/;\"\tf\nh\tinput-4.ps1\t/^function h$/;\"\tf\ni\tinput-5.ps1\t/^function i$/;\"\tf\nj\tinput-6.ps1\t/^function j$/;\"\tf\nk\tinput-6.ps1\t/^function k$/;\"\tf\n"
  },
  {
    "path": "Units/parser-powershell.r/herestring.d/input-0.ps1",
    "content": "function c\n{\n    $i = 1\n    $heredoc0 =\n@'\n'\"' $i\n'@\n    Write-Host $heredoc\n}\nfunction d\n{\n    Write-Host d\n}\nc\nd\npause\n"
  },
  {
    "path": "Units/parser-powershell.r/herestring.d/input-1.ps1",
    "content": "function e\n{\n    $i = 1\n    $heredoc0 =\n@'\n    Write-Host $heredoc\n}\nfunction inherestr\n{\n    Write-Host d\n}\nc\nd\npause\n\n'\"' $i\n'@\n}\n"
  },
  {
    "path": "Units/parser-powershell.r/herestring.d/input-2.ps1",
    "content": "function f\n{\n    $i = 1\n    $heredoc0 =\n@'\n    Write-Host $heredoc\n@\n@'\n"
  },
  {
    "path": "Units/parser-powershell.r/herestring.d/input-3.ps1",
    "content": "function g\n{\n    $i = 1\n    $heredoc0 =\n@'\n    Write-Host $heredoc\n@\n@\n\n"
  },
  {
    "path": "Units/parser-powershell.r/herestring.d/input-4.ps1",
    "content": "function h\n{\n    $i = 1\n    $heredoc0 =\n@\"\n    Write-Host $heredoc\n@\n@\"\n"
  },
  {
    "path": "Units/parser-powershell.r/herestring.d/input-5.ps1",
    "content": "function i\n{\n    $i = 1\n    $heredoc0 =\n@'\n    Write-Host $heredoc\n@\n@\"\n}\n\nfunction donttagme\n{\n}\n"
  },
  {
    "path": "Units/parser-powershell.r/herestring.d/input-6.ps1",
    "content": "function j\n{\n    $i = 1\n    $heredoc0 =\n@brokeninput\n# So ctags can do as it wants but the current implementation\n# intents extracting the next `k`.\n}\n\nfunction k\n{\n}\n"
  },
  {
    "path": "Units/parser-powershell.r/herestring.d/input.ps1",
    "content": "function a\n{\n    $i = 1\n    $heredoc =\n@\"\n\"\"\" $i\n\"@\n    Write-Host $heredoc\n}\nfunction b\n{\n    Write-Host b\n}\na\nb\npause\n"
  },
  {
    "path": "Units/parser-powershell.r/simple-powershell.d/args.ctags",
    "content": "--sort=no\n# \"qualified\" extra doesn't work.\n# --extras=+q\n--fields=+S\n"
  },
  {
    "path": "Units/parser-powershell.r/simple-powershell.d/expected.tags",
    "content": "ErrorActionPreference\tinput.ps1\t/^$ErrorActionPreference = \"Stop\"$/;\"\tv\nSettings\tinput.ps1\t/^$Global:Settings = $null$/;\"\tv\nALocalVar\tinput.ps1\t/^$Local:ALocalVar = $null$/;\"\tv\nBasePath\tinput.ps1\t/^$BasePath = split-path -parent $Global:MyInvocation.InvocationName$/;\"\tv\ncDrive\tinput.ps1\t/^$cDrive=\"C:\\\\\"$/;\"\tv\nnextLine\tinput.ps1\t/^$nextLine=\"`n\"$/;\"\tv\nbacktick\tinput.ps1\t/^$backtick='`'$/;\"\tv\nRead-Configuration-File\tinput.ps1\t/^FUNCTION Read-Configuration-File() {$/;\"\tf\tsignature:()\nLogMessageOK\tinput.ps1\t/^Function LogMessageOK()$/;\"\tf\tsignature:()\nLogMessage\tinput.ps1\t/^function LogMessage() {$/;\"\tf\tsignature:()\nA-Global-Scope-Function\tinput.ps1\t/^function global:A-Global-Scope-Function() {$/;\"\tf\tsignature:()\nMyFilter\tinput.ps1\t/^filter Script:MyFilter {$/;\"\ti\nMyPrivateFilter\tinput.ps1\t/^Filter Private:MyPrivateFilter {$/;\"\ti\nLoadTemplate\tinput.ps1\t/^function LoadTemplate($template) {$/;\"\tf\tsignature:($template)\nTopLevelFunction\tinput.ps1\t/^function TopLevelFunction() {$/;\"\tf\tsignature:()\nSecondLevelNestedFunction\tinput.ps1\t/^    function SecondLevelNestedFunction() {$/;\"\tf\tfunction:TopLevelFunction\tsignature:()\nThirdLevelNestedFunction\tinput.ps1\t/^        function ThirdLevelNestedFunction() {$/;\"\tf\tfunction:TopLevelFunction::SecondLevelNestedFunction\tsignature:()\nMain\tinput.ps1\t/^function Main() {$/;\"\tf\tsignature:()\n"
  },
  {
    "path": "Units/parser-powershell.r/simple-powershell.d/input.ps1",
    "content": "# pseudo #!/PowerShell :)\n#\n# test file for the CTags/Geany PowerShell tag parser\n# based on real world code but simplified for automated tests\n\n<#\nmultiline comment including a function and variable, both should be ignored:\n\n$IgnoreThisVaribale = \"Stop\"\n\nfunction IgnoreThisFunction($arg1)  {\n    Write-Host \"dummy\"\n}\n#>\n\n# immediately stop the script if an errors occurs\n$ErrorActionPreference = \"Stop\"\n\n# a global scoped variable\n$Global:Settings = $null\n\n# a local scoped variable\n$Local:ALocalVar = $null\n\n# a usual variable\n$BasePath = split-path -parent $Global:MyInvocation.InvocationName\n\n# different type of escape in string\n$cDrive=\"C:\\\"\n$nextLine=\"`n\"\n$backtick='`'\n\nFUNCTION Read-Configuration-File() {\n    $Hostname = [System.Environment]::MachineName\n    $ConfigurationFileName = $BasePath + \"\\script-${Hostname}.conf\"\n    LogMessage \"Read configuration '${ConfigurationFileName}'\"\n\n    $ConfigFileContent = Get-Content -raw $ConfigurationFileName\n    $Global:Settings = Convertfrom-Stringdata $ConfigFileContent\n}\n\nFunction LogMessageOK()\n{\n    $x = [Console]::WindowWidth - 6\n    $y = [Console]::CursorTop\n    Try {\n        [Console]::setcursorposition($x, $y)\n    } Catch [system.exception] {\n        # intentionally left empty for redirect of outputs to file\n    }\n\n    Write-Host -foregroundcolor \"green\" \"[ok]\"\n}\n\nfunction LogMessage() {\n    param(\n        [Parameter(Mandatory=$false)][switch] $NoNewLine,\n        [Parameter(Mandatory=$true)][string] $Message\n    )\n    $Date = Get-Date -UFormat \"%Y-%m-%d %T: \"\n    Write-Host -foregroundcolor \"yellow\" -NoNewLine $Date\n\n    if ($NoNewLine) {\n        Write-Host -foregroundcolor \"green\" -NoNewLine $Message\n    } else {\n        Write-Host -foregroundcolor \"green\" $Message\n    }\n}\n\nfunction global:A-Global-Scope-Function() {\n    Write-Host \"dummy\"\n}\n\nfilter Script:MyFilter {\n    filter-something\n}\n\nFilter Private:MyPrivateFilter {\n    filter-something\n}\n\nfunction LoadTemplate($template) {\n    # woah, this is real magic,\n    # see http://stackoverflow.com/questions/10754582/string-interpolation-of-hashtable-values-in-powershell\n\n    # Set all unbound variables (@args) in the local context\n    while ($args)\n    {\n        ($key, $val, $args) = $args\n        Set-Variable -Name $key.SubString(1, $key.Length-2) -Value $val\n    }\n    $ExecutionContext.InvokeCommand.ExpandString($template)\n}\n\nfunction TopLevelFunction() {\n    function SecondLevelNestedFunction() {\n        function ThirdLevelNestedFunction() {\n            doSomething()\n        }\n        \n        ThirdLevelNestedFunction\n    }\n    \n    SecondLevelNestedFunction\n}\n\nfunction Main() {\n    Read-Configuration-File\n    LogMessage $(\"Working on Environment '{0}'\" -f $Settings[\"EnvironmentName\"])\n\n    LogMessage \"do something ...\"\n    Stripped-Down-Code\n    LogMessageOK\n}\n\nMain\n"
  },
  {
    "path": "Units/parser-prolog.r/code.d/args.ctags",
    "content": "-G\n--sort=no\n--extras=+q\n--fields=+neEK\n"
  },
  {
    "path": "Units/parser-prolog.r/code.d/expected.tags",
    "content": "unicode_file_name\tinput.pl\t/^unicode_file_name(Name) :-$/;\"\tpredicate\tline:44\tend:47\tarity:1\nunicode_file_name/1\tinput.pl\t/^unicode_file_name(Name) :-$/;\"\tpredicate\tline:44\textras:arityAppended\tend:47\tarity:1\nunicode_file\tinput.pl\t/^unicode_file(mkdir-1) :-                        % create Cyrillic directory$/;\"\tpredicate\tline:49\tend:58\tarity:1\nunicode_file/1\tinput.pl\t/^unicode_file(mkdir-1) :-                        % create Cyrillic directory$/;\"\tpredicate\tline:49\textras:arityAppended\tend:58\tarity:1\nunicode_file\tinput.pl\t/^unicode_file(file-1) :-                         % create Cyrillic file$/;\"\tpredicate\tline:59\tend:71\tarity:1\nunicode_file/1\tinput.pl\t/^unicode_file(file-1) :-                         % create Cyrillic file$/;\"\tpredicate\tline:59\textras:arityAppended\tend:71\tarity:1\nunicode_file\tinput.pl\t/^unicode_file(absfile-1) :-$/;\"\tpredicate\tline:72\tend:78\tarity:1\nunicode_file/1\tinput.pl\t/^unicode_file(absfile-1) :-$/;\"\tpredicate\tline:72\textras:arityAppended\tend:78\tarity:1\nunicode_file\tinput.pl\t/^unicode_file(ext-1) :-$/;\"\tpredicate\tline:79\tend:83\tarity:1\nunicode_file/1\tinput.pl\t/^unicode_file(ext-1) :-$/;\"\tpredicate\tline:79\textras:arityAppended\tend:83\tarity:1\nseek\tinput.pl\t/^seek(write-1) :-$/;\"\tpredicate\tline:90\tend:108\tarity:1\nseek/1\tinput.pl\t/^seek(write-1) :-$/;\"\tpredicate\tline:90\textras:arityAppended\tend:108\tarity:1\n"
  },
  {
    "path": "Units/parser-prolog.r/code.d/input.pl",
    "content": "% Taken from pl-9.2.9-build/swipl-9.2.9/src/test.pl\n% 0'. can be a trouble.\n\n/*  Part of SWI-Prolog\n\n    Author:        Jan Wielemaker and Anjo Anjewierden\n    E-mail:        J.Wielemaker@cs.vu.nl\n    WWW:           http://www.swi-prolog.org\n    Copyright (c)  1996-2023, University of Amsterdam\n                              VU University Amsterdam\n                              CWI, Amsterdam\n                              SWI-Prolog Solutions b.v.\n    All rights reserved.\n\n    Redistribution and use in source and binary forms, with or without\n    modification, are permitted provided that the following conditions\n    are met:\n\n    1. Redistributions of source code must retain the above copyright\n       notice, this list of conditions and the following disclaimer.\n\n    2. Redistributions in binary form must reproduce the above copyright\n       notice, this list of conditions and the following disclaimer in\n       the documentation and/or other materials provided with the\n       distribution.\n\n    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n    \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n    POSSIBILITY OF SUCH DAMAGE.\n*/\n                 /*******************************\n                 *      UNICODE FILENAMES       *\n                 *******************************/\n\nunicode_file_name(Name) :-\n    current_prolog_flag(pid, Pid),\n    atom_codes(Name0, [1074, 1086, 1079, 1076, 1091, 1093, 1072]),\n    atomic_list_concat([Name0, -, Pid], Name).\n\nunicode_file(mkdir-1) :-                        % create Cyrillic directory\n    unicode_file_name(Dir),\n    catch(delete_directory(Dir), _, true),\n    make_directory(Dir),\n    exists_directory(Dir),\n    working_directory(Old, Dir),\n    working_directory(O2, '..'),\n    same_file(Old, '.'),\n    same_file(O2, Dir),\n    delete_directory(Dir).\nunicode_file(file-1) :-                         % create Cyrillic file\n    unicode_file_name(File),\n    Term = hello(world),\n    catch(delete_file(File), _, true),\n    open(File, write, Out),\n    format(Out, '~q.~n', [Term]),\n    close(Out),\n    exists_file(File),\n    open(File, read, In),\n    read(In, Read),\n    close(In),\n    Read =@= Term,\n    delete_file(File).\nunicode_file(absfile-1) :-\n    unicode_file_name(File),\n    absolute_file_name(File, Path),\n    file_directory_name(Path, Dir),\n    same_file(Dir, '.'),\n    file_base_name(Path, Base),\n    Base == File.\nunicode_file(ext-1) :-\n    atom_codes(File, [1074, 1086, 1079, 1076, 0'., 1091, 1093, 1072]),\n    file_name_extension(Base, Ext, File),\n    atom_codes(Base, [1074, 1086, 1079, 1076]),\n    atom_codes(Ext, [1091, 1093, 1072]).\n\n\n                 /*******************************\n                 *              SEEK            *\n                 *******************************/\n\nseek(write-1) :-\n    tmp_file(seek, File),\n    open(File, write, S, [type(binary)]),\n    Max = 999,\n    forall(between(0, Max, _),\n           format(S, '1234567890~n', [])),\n    forall(between(0, Max, N),\n           (   Pos is N * 11 + 6,\n               seek(S, Pos, bof, _),\n               format(S, 'x', [])\n           )),\n    close(S),\n\n    open(File, read, In, [type(binary)]),\n    atom_codes('123456x890\\n', Bytes),\n    forall(between(0, Max, N),\n           must_read(Bytes, In)),\n    close(In),\n    delete_file(File).\n"
  },
  {
    "path": "Units/parser-prolog.r/dcg.d/args.ctags",
    "content": "-G\n--sort=no\n--fields=+neEK\n"
  },
  {
    "path": "Units/parser-prolog.r/dcg.d/expected.tags",
    "content": "server\tinput.pl\t/^server :-$/;\"\tpredicate\tline:27\tend:28\tarity:0\nserver/0\tinput.pl\t/^server :-$/;\"\tpredicate\tline:27\textras:arityAppended\tend:28\tarity:0\nserver\tinput.pl\t/^server(Port, Options) :-$/;\"\tpredicate\tline:30\tend:35\tarity:2\nserver/2\tinput.pl\t/^server(Port, Options) :-$/;\"\tpredicate\tline:30\textras:arityAppended\tend:35\tarity:2\nreply\tinput.pl\t/^reply(Request) :-$/;\"\tpredicate\tline:37\tend:39\tarity:1\nreply/1\tinput.pl\t/^reply(Request) :-$/;\"\tpredicate\tline:37\textras:arityAppended\tend:39\tarity:1\nreply\tinput.pl\t/^reply(\\/, _Request) :-$/;\"\tpredicate\tline:41\tend:45\tarity:2\nreply/2\tinput.pl\t/^reply(\\/, _Request) :-$/;\"\tpredicate\tline:41\textras:arityAppended\tend:45\tarity:2\nreply\tinput.pl\t/^reply('\\/calc', Request) :-$/;\"\tpredicate\tline:47\tend:56\tarity:2\nreply/2\tinput.pl\t/^reply('\\/calc', Request) :-$/;\"\tpredicate\tline:47\textras:arityAppended\tend:56\tarity:2\npage\tinput.pl\t/^page(Formula) :-$/;\"\tpredicate\tline:59\tend:74\tarity:1\npage/1\tinput.pl\t/^page(Formula) :-$/;\"\tpredicate\tline:59\textras:arityAppended\tend:74\tarity:1\nformula\tinput.pl\t/^formula(Formula) -->$/;\"\tgrammar\tline:76\tend:80\tarity:1\nformula/1\tinput.pl\t/^formula(Formula) -->$/;\"\tgrammar\tline:76\textras:arityAppended\tend:80\tarity:1\nops\tinput.pl\t/^ops -->$/;\"\tgrammar\tline:82\tend:88\tarity:0\nops/0\tinput.pl\t/^ops -->$/;\"\tgrammar\tline:82\textras:arityAppended\tend:88\tarity:0\nreply_page\tinput.pl\t/^reply_page(Title, Content) :-$/;\"\tpredicate\tline:90\tend:93\tarity:2\nreply_page/2\tinput.pl\t/^reply_page(Title, Content) :-$/;\"\tpredicate\tline:90\textras:arityAppended\tend:93\tarity:2\n"
  },
  {
    "path": "Units/parser-prolog.r/dcg.d/input.pl",
    "content": "% Taken from swipl-9.2.9\n/*  $Id$\n\n    Part of SWI-Prolog\n\n    Author:        Jan Wielemaker\n    E-mail:        wielemak@science.uva.nl\n    WWW:           http://www.swi-prolog.org\n    Copyright (C): Public domain\n*/\n\n:- use_module(library('http/thread_httpd')).\n:- use_module(library('http/html_write')).\n:- use_module(library('http/http_session')).\n:- use_module(library('http/http_error')).\n\n/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nThis demo shows session state  management   in  a very simple calculator\npackage. It also demonstrates the use of  the html_write library. To use\nit, start Prolog, load this file and run\n\n        ?- server.\n\nNow direct your browser to http://localhost:3000/\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\n\nserver :-\n    server(3000, []).\n\nserver(Port, Options) :-\n    http_server(reply,\n                [ port(Port),\n                  timeout(20)\n                | Options\n                ]).\n\nreply(Request) :-\n    memberchk(path(Path), Request),\n    reply(Path, Request).\n\nreply(/, _Request) :-\n    http_session_retractall(formula(_)),\n    Formula = 0,\n    http_session_assert(formula(Formula)),\n    page(Formula).\n\nreply('/calc', Request) :-\n    memberchk(search(Search), Request),\n    memberchk(operation=Op, Search),\n    memberchk(value=AtomVal, Search),\n    atom_number(AtomVal, Val),\n    http_session_retract(formula(Formula0)),\n    debug(calc, 'Formula0 = ~w', [Formula0]),\n    Formula =.. [Op, Formula0, Val],\n    http_session_assert(formula(Formula)),\n    page(Formula).\n\n\npage(Formula) :-\n    reply_page('HTTP Session DEMO',\n               [ h2('Simple session demo'),\n                 form([ action('/calc'),\n                        method('GET')\n                      ],\n                      table([align(center), border(1)],\n                            [ tr(td(\\formula(Formula))),\n                              tr(td([ \\ops,\n                                      input([ name(value) ]),\n                                      input([ type(submit),\n                                              value('Calc!')\n                                            ])\n                                    ]))\n                            ]))\n               ]).\n\nformula(Formula) -->\n    { sformat(S, '~w', [Formula]),\n      Value is Formula\n    },\n    html([ S, ' = ', Value ]).\n\nops -->\n    html(select(name(operation),\n                [ option([selected], +),\n                  option([], -),\n                  option([], /),\n                  option([], *)\n                ])).\n\nreply_page(Title, Content) :-\n    phrase(page(title(Title), Content), HTML),\n    format('Content-type: text/html~n~n'),\n    print_html(HTML).\n"
  },
  {
    "path": "Units/parser-prolog.r/module.d/args.ctags",
    "content": "-G\n--sort=no\n--extras=+q\n--fields=+neEK\n"
  },
  {
    "path": "Units/parser-prolog.r/module.d/expected.tags",
    "content": "clpq\tinput.pl\t/^:- module(clpq,$/;\"\tmodule\tline:42\nportray_message\tinput.pl\t/^user:portray_message(warning,import(_,_,clpq,private)).$/;\"\tpredicate\tline:67\tmodule:user\tend:67\tarity:2\nuser:portray_message\tinput.pl\t/^user:portray_message(warning,import(_,_,clpq,private)).$/;\"\tpredicate\tline:67\tmodule:user\textras:qualified\tend:67\tarity:2\nportray_message/2\tinput.pl\t/^user:portray_message(warning,import(_,_,clpq,private)).$/;\"\tpredicate\tline:67\tmodule:user\textras:arityAppended\tend:67\tarity:2\nuser:portray_message/2\tinput.pl\t/^user:portray_message(warning,import(_,_,clpq,private)).$/;\"\tpredicate\tline:67\tmodule:user\textras:qualified,arityAppended\tend:67\tarity:2\nmessage\tinput.pl\t/^prolog:message(query(YesNo,Bindings)) --> !,$/;\"\tgrammar\tline:93\tmodule:prolog\tend:96\tarity:1\nprolog:message\tinput.pl\t/^prolog:message(query(YesNo,Bindings)) --> !,$/;\"\tgrammar\tline:93\tmodule:prolog\textras:qualified\tend:96\tarity:1\nmessage/1\tinput.pl\t/^prolog:message(query(YesNo,Bindings)) --> !,$/;\"\tgrammar\tline:93\tmodule:prolog\textras:arityAppended\tend:96\tarity:1\nprolog:message/1\tinput.pl\t/^prolog:message(query(YesNo,Bindings)) --> !,$/;\"\tgrammar\tline:93\tmodule:prolog\textras:qualified,arityAppended\tend:96\tarity:1\ndump_toplevel_bindings\tinput.pl\t/^dump_toplevel_bindings(Bindings,Constraints) :-$/;\"\tpredicate\tline:98\tmodule:clpq\tend:100\tarity:2\nclpq:dump_toplevel_bindings\tinput.pl\t/^dump_toplevel_bindings(Bindings,Constraints) :-$/;\"\tpredicate\tline:98\tmodule:clpq\textras:qualified\tend:100\tarity:2\ndump_toplevel_bindings/2\tinput.pl\t/^dump_toplevel_bindings(Bindings,Constraints) :-$/;\"\tpredicate\tline:98\tmodule:clpq\textras:arityAppended\tend:100\tarity:2\nclpq:dump_toplevel_bindings/2\tinput.pl\t/^dump_toplevel_bindings(Bindings,Constraints) :-$/;\"\tpredicate\tline:98\tmodule:clpq\textras:qualified,arityAppended\tend:100\tarity:2\ndump_vars_names\tinput.pl\t/^dump_vars_names([],_,[],[]).$/;\"\tpredicate\tline:102\tmodule:clpq\tend:102\tarity:4\nclpq:dump_vars_names\tinput.pl\t/^dump_vars_names([],_,[],[]).$/;\"\tpredicate\tline:102\tmodule:clpq\textras:qualified\tend:102\tarity:4\ndump_vars_names/4\tinput.pl\t/^dump_vars_names([],_,[],[]).$/;\"\tpredicate\tline:102\tmodule:clpq\textras:arityAppended\tend:102\tarity:4\nclpq:dump_vars_names/4\tinput.pl\t/^dump_vars_names([],_,[],[]).$/;\"\tpredicate\tline:102\tmodule:clpq\textras:qualified,arityAppended\tend:102\tarity:4\ndump_vars_names\tinput.pl\t/^dump_vars_names([Name=Term|Rest],Seen,Vars,Names) :-$/;\"\tpredicate\tline:103\tmodule:clpq\tend:116\tarity:4\nclpq:dump_vars_names\tinput.pl\t/^dump_vars_names([Name=Term|Rest],Seen,Vars,Names) :-$/;\"\tpredicate\tline:103\tmodule:clpq\textras:qualified\tend:116\tarity:4\ndump_vars_names/4\tinput.pl\t/^dump_vars_names([Name=Term|Rest],Seen,Vars,Names) :-$/;\"\tpredicate\tline:103\tmodule:clpq\textras:arityAppended\tend:116\tarity:4\nclpq:dump_vars_names/4\tinput.pl\t/^dump_vars_names([Name=Term|Rest],Seen,Vars,Names) :-$/;\"\tpredicate\tline:103\tmodule:clpq\textras:qualified,arityAppended\tend:116\tarity:4\ndump_format\tinput.pl\t/^dump_format([]) --> [].$/;\"\tgrammar\tline:118\tmodule:clpq\tend:118\tarity:1\nclpq:dump_format\tinput.pl\t/^dump_format([]) --> [].$/;\"\tgrammar\tline:118\tmodule:clpq\textras:qualified\tend:118\tarity:1\ndump_format/1\tinput.pl\t/^dump_format([]) --> [].$/;\"\tgrammar\tline:118\tmodule:clpq\textras:arityAppended\tend:118\tarity:1\nclpq:dump_format/1\tinput.pl\t/^dump_format([]) --> [].$/;\"\tgrammar\tline:118\tmodule:clpq\textras:qualified,arityAppended\tend:118\tarity:1\ndump_format\tinput.pl\t/^dump_format([X|Xs]) -->$/;\"\tgrammar\tline:119\tmodule:clpq\tend:121\tarity:1\nclpq:dump_format\tinput.pl\t/^dump_format([X|Xs]) -->$/;\"\tgrammar\tline:119\tmodule:clpq\textras:qualified\tend:121\tarity:1\ndump_format/1\tinput.pl\t/^dump_format([X|Xs]) -->$/;\"\tgrammar\tline:119\tmodule:clpq\textras:arityAppended\tend:121\tarity:1\nclpq:dump_format/1\tinput.pl\t/^dump_format([X|Xs]) -->$/;\"\tgrammar\tline:119\tmodule:clpq\textras:qualified,arityAppended\tend:121\tarity:1\nmemberchk_eq\tinput.pl\t/^memberchk_eq(X,[Y|Ys]) :-$/;\"\tpredicate\tline:123\tmodule:clpq\tend:127\tarity:2\nclpq:memberchk_eq\tinput.pl\t/^memberchk_eq(X,[Y|Ys]) :-$/;\"\tpredicate\tline:123\tmodule:clpq\textras:qualified\tend:127\tarity:2\nmemberchk_eq/2\tinput.pl\t/^memberchk_eq(X,[Y|Ys]) :-$/;\"\tpredicate\tline:123\tmodule:clpq\textras:arityAppended\tend:127\tarity:2\nclpq:memberchk_eq/2\tinput.pl\t/^memberchk_eq(X,[Y|Ys]) :-$/;\"\tpredicate\tline:123\tmodule:clpq\textras:qualified,arityAppended\tend:127\tarity:2\n"
  },
  {
    "path": "Units/parser-prolog.r/module.d/input.pl",
    "content": "% Taken from swipl-9.2.9\n\n/*\n\n    Part of CLP(Q) (Constraint Logic Programming over Rationals)\n\n    Author:        Leslie De Koninck\n    E-mail:        Leslie.DeKoninck@cs.kuleuven.be\n    WWW:           http://www.swi-prolog.org\n\t\t   http://www.ai.univie.ac.at/cgi-bin/tr-online?number+95-09\n    Copyright (C): 2006, K.U. Leuven and\n\t\t   1992-1995, Austrian Research Institute for\n\t\t              Artificial Intelligence (OFAI),\n\t\t\t      Vienna, Austria\n\n    This software is based on CLP(Q,R) by Christian Holzbaur for SICStus\n    Prolog and distributed under the license details below with permission from\n    all mentioned authors.\n\n    This program is free software; you can redistribute it and/or\n    modify it under the terms of the GNU General Public License\n    as published by the Free Software Foundation; either version 2\n    of the License, or (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU Lesser General Public\n    License along with this library; if not, write to the Free Software\n    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n\n    As a special exception, if you link this library with other files,\n    compiled with a Free Software compiler, to produce an executable, this\n    library does not by itself cause the resulting executable to be covered\n    by the GNU General Public License. This exception does not however\n    invalidate any other reasons why the executable file might be covered by\n    the GNU General Public License.\n*/\n\n:- module(clpq,\n\t  [ {}/1,\n\t    maximize/1,\n\t    minimize/1,\n\t    inf/2, inf/4, sup/2, sup/4,\n\t    bb_inf/3,\n\t    bb_inf/4,\n\t    ordering/1,\n\t    entailed/1,\n\t    clp_type/2,\n\t    dump/3%, projecting_assert/1\n\t  ]).\n:- license(gpl_swipl, 'CLP(Q)').\n:- use_module(library(dialect)).\n:- expects_dialect(swi).\n\n%\n% Don't report export of private predicates from clpq\n%\n:- multifile\n\tuser:portray_message/2.\n\n:- dynamic\n\tuser:portray_message/2.\n%\nuser:portray_message(warning,import(_,_,clpq,private)).\n\n:- use_module([ clpq/bb_q,\n\t\tclpq/bv_q,\n\t\tclpq/fourmotz_q,\n\t\tclpq/ineq_q,\n\t\tclpq/itf_q,\n\t\tclpq/nf_q,\n\t\tclpq/store_q,\n\t\tclpqr/class,\n\t\tclpqr/dump,\n\t\tclpqr/geler,\n\t\tclpqr/itf,\n\t\tclpqr/ordering,\n\t\tclpqr/project,\n\t\tclpqr/redund,\n\t\tlibrary(ugraphs)\n\t      ]).\n\n\t\t /*******************************\n\t\t *\t TOPLEVEL PRINTING\t*\n\t\t *******************************/\n\n:- multifile\n\tprolog:message/3.\n\nprolog:message(query(YesNo,Bindings)) --> !,\n\t{dump_toplevel_bindings(Bindings,Constraints)},\n\tdump_format(Constraints),\n        '$messages':prolog_message(query(YesNo,Bindings)).\n\ndump_toplevel_bindings(Bindings,Constraints) :-\n\tdump_vars_names(Bindings,[],Vars,Names),\n\tdump(Vars,Names,Constraints).\n\ndump_vars_names([],_,[],[]).\ndump_vars_names([Name=Term|Rest],Seen,Vars,Names) :-\n\t(   var(Term),\n\t    (   get_attr(Term,clpqr_itf,_)\n\t    ;   get_attr(Term,clpqr_geler,_)\n\t    ),\n\t    \\+ memberchk_eq(Term,Seen)\n\t->  Vars = [Term|RVars],\n\t    Names = [Name|RNames],\n\t    NSeen = [Term|Seen]\n\t;   Vars = RVars,\n\t    Names = RNames,\n\t    Seen = NSeen\n\t),\n\tdump_vars_names(Rest,NSeen,RVars,RNames).\n\ndump_format([]) --> [].\ndump_format([X|Xs]) -->\n\t['{~w}'-[X], nl],\n\tdump_format(Xs).\n\nmemberchk_eq(X,[Y|Ys]) :-\n\t(   X == Y\n\t->  true\n\t;   memberchk_eq(X,Ys)\n\t).\n"
  },
  {
    "path": "Units/parser-prolog.r/module.d/validator",
    "content": "KNOWN-INVALIDATION\n"
  },
  {
    "path": "Units/parser-prolog.r/simple-flat-comment.d/args.ctags",
    "content": "-G\n--sort=no\n--fields=+nEK\n--param-Prolog.allowNestedComments=0\n"
  },
  {
    "path": "Units/parser-prolog.r/simple-flat-comment.d/expected.tags",
    "content": "mother_child\tinput.pl\t/^mother_child(trude, sally).$/;\"\tpredicate\tline:2\tarity:2\nmother_child/2\tinput.pl\t/^mother_child(trude, sally).$/;\"\tpredicate\tline:2\textras:arityAppended\tarity:2\nfather_child\tinput.pl\t/^father_child(tom, sally).$/;\"\tpredicate\tline:4\tarity:2\nfather_child/2\tinput.pl\t/^father_child(tom, sally).$/;\"\tpredicate\tline:4\textras:arityAppended\tarity:2\nfather_child\tinput.pl\t/^father_child(tom, erica).$/;\"\tpredicate\tline:5\tarity:2\nfather_child/2\tinput.pl\t/^father_child(tom, erica).$/;\"\tpredicate\tline:5\textras:arityAppended\tarity:2\nfather_child\tinput.pl\t/^father_child(mike, tom).$/;\"\tpredicate\tline:6\tarity:2\nfather_child/2\tinput.pl\t/^father_child(mike, tom).$/;\"\tpredicate\tline:6\textras:arityAppended\tarity:2\nsibling\tinput.pl\t/^sibling(X, Y)      :- parent_child(Z, X), parent_child(Z, Y).$/;\"\tpredicate\tline:8\tarity:2\nsibling/2\tinput.pl\t/^sibling(X, Y)      :- parent_child(Z, X), parent_child(Z, Y).$/;\"\tpredicate\tline:8\textras:arityAppended\tarity:2\nparent_child\tinput.pl\t/^parent_child(X, Y) :- father_child(X, Y).$/;\"\tpredicate\tline:10\tarity:2\nparent_child/2\tinput.pl\t/^parent_child(X, Y) :- father_child(X, Y).$/;\"\tpredicate\tline:10\textras:arityAppended\tarity:2\nparent_child\tinput.pl\t/^parent_child(X, Y) :- mother_child(X, Y).$/;\"\tpredicate\tline:11\tarity:2\nparent_child/2\tinput.pl\t/^parent_child(X, Y) :- mother_child(X, Y).$/;\"\tpredicate\tline:11\textras:arityAppended\tarity:2\nnot_dummy\tinput.pl\t/^not_dummy.$/;\"\tpredicate\tline:16\tarity:0\nnot_dummy/0\tinput.pl\t/^not_dummy.$/;\"\tpredicate\tline:16\textras:arityAppended\tarity:0\n'quoted predicate'\tinput.pl\t/^'quoted predicate'($/;\"\tpredicate\tline:18\tarity:1\n'quoted predicate'/1\tinput.pl\t/^'quoted predicate'($/;\"\tpredicate\tline:18\textras:arityAppended\tarity:1\nrel\tinput.pl\t/^rel(X,Y,Z) :- Z =:= X + Y + 0.25.$/;\"\tpredicate\tline:23\tarity:3\nrel/3\tinput.pl\t/^rel(X,Y,Z) :- Z =:= X + Y + 0.25.$/;\"\tpredicate\tline:23\textras:arityAppended\tarity:3\nrel\tinput.pl\t/^rel(X,Y) :- Y =:= X + 0.25.$/;\"\tpredicate\tline:24\tarity:2\nrel/2\tinput.pl\t/^rel(X,Y) :- Y =:= X + 0.25.$/;\"\tpredicate\tline:24\textras:arityAppended\tarity:2\nrel\tinput.pl\t/^rel(X) :- X =:= 100_000.$/;\"\tpredicate\tline:25\tarity:1\nrel/1\tinput.pl\t/^rel(X) :- X =:= 100_000.$/;\"\tpredicate\tline:25\textras:arityAppended\tarity:1\nrel0\tinput.pl\t/^rel0(X) :- X =:= 100_000 0.$/;\"\tpredicate\tline:27\tarity:1\nrel0/1\tinput.pl\t/^rel0(X) :- X =:= 100_000 0.$/;\"\tpredicate\tline:27\textras:arityAppended\tarity:1\nrel0\tinput.pl\t/^rel0(X, 100_000_11, Y) :- X =:= Y.$/;\"\tpredicate\tline:28\tarity:3\nrel0/3\tinput.pl\t/^rel0(X, 100_000_11, Y) :- X =:= Y.$/;\"\tpredicate\tline:28\textras:arityAppended\tarity:3\n"
  },
  {
    "path": "Units/parser-prolog.r/simple-flat-comment.d/input.pl",
    "content": "%% Taken from https://en.wikipedia.org/wiki/Prolog\nmother_child(trude, sally).\n\nfather_child(tom, sally).\nfather_child(tom, erica).\nfather_child(mike, tom).\n\nsibling(X, Y)      :- parent_child(Z, X), parent_child(Z, Y).\n\nparent_child(X, Y) :- father_child(X, Y).\nparent_child(X, Y) :- mother_child(X, Y).\n\n% dummy0()\n/* dummy1() */\n/* /* dummy2() */\nnot_dummy.\n\n'quoted predicate'(\nX\n) :-\n\tfather_child(tom, X).\n\nrel(X,Y,Z) :- Z =:= X + Y + 0.25.\nrel(X,Y) :- Y =:= X + 0.25.\nrel(X) :- X =:= 100_000.\n\nrel0(X) :- X =:= 100_000 0.\nrel0(X, 100_000_11, Y) :- X =:= Y.\n"
  },
  {
    "path": "Units/parser-prolog.r/simple-flat-comment.d/validator",
    "content": "KNOWN-INVALIDATION\n\n"
  },
  {
    "path": "Units/parser-prolog.r/simple.d/args.ctags",
    "content": "-G\n--sort=no\n--fields=+nEK\n--param-Prolog.allowNestedComments=1\n"
  },
  {
    "path": "Units/parser-prolog.r/simple.d/expected.tags",
    "content": "mother_child\tinput.pl\t/^mother_child(trude, sally).$/;\"\tpredicate\tline:2\tarity:2\nmother_child/2\tinput.pl\t/^mother_child(trude, sally).$/;\"\tpredicate\tline:2\textras:arityAppended\tarity:2\nfather_child\tinput.pl\t/^father_child(tom, sally).$/;\"\tpredicate\tline:4\tarity:2\nfather_child/2\tinput.pl\t/^father_child(tom, sally).$/;\"\tpredicate\tline:4\textras:arityAppended\tarity:2\nfather_child\tinput.pl\t/^father_child(tom, erica).$/;\"\tpredicate\tline:5\tarity:2\nfather_child/2\tinput.pl\t/^father_child(tom, erica).$/;\"\tpredicate\tline:5\textras:arityAppended\tarity:2\nfather_child\tinput.pl\t/^father_child(mike, tom).$/;\"\tpredicate\tline:6\tarity:2\nfather_child/2\tinput.pl\t/^father_child(mike, tom).$/;\"\tpredicate\tline:6\textras:arityAppended\tarity:2\nsibling\tinput.pl\t/^sibling(X, Y)      :- parent_child(Z, X), parent_child(Z, Y).$/;\"\tpredicate\tline:8\tarity:2\nsibling/2\tinput.pl\t/^sibling(X, Y)      :- parent_child(Z, X), parent_child(Z, Y).$/;\"\tpredicate\tline:8\textras:arityAppended\tarity:2\nparent_child\tinput.pl\t/^parent_child(X, Y) :- father_child(X, Y).$/;\"\tpredicate\tline:10\tarity:2\nparent_child/2\tinput.pl\t/^parent_child(X, Y) :- father_child(X, Y).$/;\"\tpredicate\tline:10\textras:arityAppended\tarity:2\nparent_child\tinput.pl\t/^parent_child(X, Y) :- mother_child(X, Y).$/;\"\tpredicate\tline:11\tarity:2\nparent_child/2\tinput.pl\t/^parent_child(X, Y) :- mother_child(X, Y).$/;\"\tpredicate\tline:11\textras:arityAppended\tarity:2\nnot_dummy\tinput.pl\t/^not_dummy.$/;\"\tpredicate\tline:16\tarity:0\nnot_dummy/0\tinput.pl\t/^not_dummy.$/;\"\tpredicate\tline:16\textras:arityAppended\tarity:0\n'quoted predicate'\tinput.pl\t/^'quoted predicate'($/;\"\tpredicate\tline:18\tarity:1\n'quoted predicate'/1\tinput.pl\t/^'quoted predicate'($/;\"\tpredicate\tline:18\textras:arityAppended\tarity:1\nrel\tinput.pl\t/^rel(X,Y,Z) :- Z =:= X + Y + 0.25.$/;\"\tpredicate\tline:23\tarity:3\nrel/3\tinput.pl\t/^rel(X,Y,Z) :- Z =:= X + Y + 0.25.$/;\"\tpredicate\tline:23\textras:arityAppended\tarity:3\nrel\tinput.pl\t/^rel(X,Y) :- Y =:= X + 0.25.$/;\"\tpredicate\tline:24\tarity:2\nrel/2\tinput.pl\t/^rel(X,Y) :- Y =:= X + 0.25.$/;\"\tpredicate\tline:24\textras:arityAppended\tarity:2\nrel\tinput.pl\t/^rel(X) :- X =:= 100_000.$/;\"\tpredicate\tline:25\tarity:1\nrel/1\tinput.pl\t/^rel(X) :- X =:= 100_000.$/;\"\tpredicate\tline:25\textras:arityAppended\tarity:1\nrel0\tinput.pl\t/^rel0(X) :- X =:= 100_000 0.$/;\"\tpredicate\tline:27\tarity:1\nrel0/1\tinput.pl\t/^rel0(X) :- X =:= 100_000 0.$/;\"\tpredicate\tline:27\textras:arityAppended\tarity:1\nrel0\tinput.pl\t/^rel0(X, 100_000_11, Y) :- X =:= Y.$/;\"\tpredicate\tline:28\tarity:3\nrel0/3\tinput.pl\t/^rel0(X, 100_000_11, Y) :- X =:= Y.$/;\"\tpredicate\tline:28\textras:arityAppended\tarity:3\n"
  },
  {
    "path": "Units/parser-prolog.r/simple.d/input.pl",
    "content": "%% Taken from https://en.wikipedia.org/wiki/Prolog\nmother_child(trude, sally).\n\nfather_child(tom, sally).\nfather_child(tom, erica).\nfather_child(mike, tom).\n\nsibling(X, Y)      :- parent_child(Z, X), parent_child(Z, Y).\n\nparent_child(X, Y) :- father_child(X, Y).\nparent_child(X, Y) :- mother_child(X, Y).\n\n% dummy0()\n/* dummy1() */\n/* /* dummy2() */ */\nnot_dummy.\n\n'quoted predicate'(\nX\n) :-\n\tfather_child(tom, X).\n\nrel(X,Y,Z) :- Z =:= X + Y + 0.25.\nrel(X,Y) :- Y =:= X + 0.25.\nrel(X) :- X =:= 100_000.\n\nrel0(X) :- X =:= 100_000 0.\nrel0(X, 100_000_11, Y) :- X =:= Y.\n"
  },
  {
    "path": "Units/parser-prolog.r/validator",
    "content": "swipl\n"
  },
  {
    "path": "Units/parser-protobuf.r/package-name-including-dot.d/expected.tags",
    "content": "foo.bar\tinput.proto\t/^package foo.bar;$/;\"\tp\n"
  },
  {
    "path": "Units/parser-protobuf.r/package-name-including-dot.d/input.proto",
    "content": "package foo.bar;\n"
  },
  {
    "path": "Units/parser-protobuf.r/protobuf-group.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r{end}\n"
  },
  {
    "path": "Units/parser-protobuf.r/protobuf-group.d/expected.tags",
    "content": "my.test\tinput.proto\t/^package my.test;  \\/\\/ dotted package name$/;\"\tp\troles:def\nmulti/multi1.proto\tinput.proto\t/^import \"multi\\/multi1.proto\";  \\/\\/ unused import$/;\"\tD\tpackage:my.test\troles:imported\nHatType\tinput.proto\t/^enum HatType {$/;\"\tg\tpackage:my.test\troles:def\tend:44\nFEDORA\tinput.proto\t/^  FEDORA = 1;$/;\"\te\tenum:my.test.HatType\troles:def\nFEZ\tinput.proto\t/^  FEZ = 2;$/;\"\te\tenum:my.test.HatType\troles:def\nDays\tinput.proto\t/^enum Days {$/;\"\tg\tpackage:my.test\troles:def\tend:53\nMONDAY\tinput.proto\t/^  MONDAY = 1;$/;\"\te\tenum:my.test.Days\troles:def\nTUESDAY\tinput.proto\t/^  TUESDAY = 2;$/;\"\te\tenum:my.test.Days\troles:def\nLUNDI\tinput.proto\t/^  LUNDI = 1;  \\/\\/ same value as MONDAY$/;\"\te\tenum:my.test.Days\troles:def\nRequest\tinput.proto\t/^message Request {$/;\"\tm\tpackage:my.test\troles:def\tend:86\nColor\tinput.proto\t/^  enum Color {$/;\"\tg\tmessage:my.test.Request\troles:def\tend:61\nRED\tinput.proto\t/^    RED = 0;$/;\"\te\tenum:my.test.Request.Color\troles:def\nGREEN\tinput.proto\t/^    GREEN = 1;$/;\"\te\tenum:my.test.Request.Color\troles:def\nBLUE\tinput.proto\t/^    BLUE = 2;$/;\"\te\tenum:my.test.Request.Color\troles:def\nkey\tinput.proto\t/^  repeated int64 key = 1;$/;\"\tf\tmessage:my.test.Request\ttyperef:typename:int64\troles:def\nhue\tinput.proto\t/^  optional Color hue = 3; \\/\\/ no default$/;\"\tf\tmessage:my.test.Request\ttyperef:typename:Color\troles:def\nhat\tinput.proto\t/^  optional HatType hat = 4 [default=FEDORA];$/;\"\tf\tmessage:my.test.Request\ttyperef:typename:HatType\troles:def\ndeadline\tinput.proto\t/^  optional float deadline = 7 [default=inf];$/;\"\tf\tmessage:my.test.Request\ttyperef:typename:float\troles:def\nSomeGroup\tinput.proto\t/^  optional group SomeGroup = 8 {$/;\"\tf\tmessage:my.test.Request\ttyperef:typename:group\troles:def\tend:70\ngroup_field\tinput.proto\t/^    optional int32 group_field = 9;$/;\"\tf\tfield:my.test.Request.SomeGroup\ttyperef:typename:int32\troles:def\nname_mapping\tinput.proto\t/^  map<int32, string> name_mapping = 14;$/;\"\tf\tmessage:my.test.Request\ttyperef:typename:map<int32,string>\troles:def\nmsg_mapping\tinput.proto\t/^  map<sint64, Reply> msg_mapping = 15;$/;\"\tf\tmessage:my.test.Request\ttyperef:typename:map<sint64,Reply>\troles:def\nreset\tinput.proto\t/^  optional int32 reset = 12;$/;\"\tf\tmessage:my.test.Request\ttyperef:typename:int32\troles:def\nget_key\tinput.proto\t/^  optional string get_key = 16;$/;\"\tf\tmessage:my.test.Request\ttyperef:typename:string\troles:def\nReply\tinput.proto\t/^message Reply {$/;\"\tm\tpackage:my.test\troles:def\tend:101\nEntry\tinput.proto\t/^  message Entry {$/;\"\tm\tmessage:my.test.Reply\troles:def\tend:97\nkey_that_needs_1234camel_CasIng\tinput.proto\t/^    required int64 key_that_needs_1234camel_CasIng = 1;$/;\"\tf\tmessage:my.test.Reply.Entry\ttyperef:typename:int64\troles:def\nvalue\tinput.proto\t/^    optional int64 value = 2 [default=7];$/;\"\tf\tmessage:my.test.Reply.Entry\ttyperef:typename:int64\troles:def\n_my_field_name_2\tinput.proto\t/^    optional int64 _my_field_name_2 = 3;$/;\"\tf\tmessage:my.test.Reply.Entry\ttyperef:typename:int64\troles:def\nGame\tinput.proto\t/^    enum Game {$/;\"\tg\tmessage:my.test.Reply.Entry\troles:def\tend:96\nFOOTBALL\tinput.proto\t/^      FOOTBALL = 1;$/;\"\te\tenum:my.test.Reply.Entry.Game\troles:def\nTENNIS\tinput.proto\t/^      TENNIS = 2;$/;\"\te\tenum:my.test.Reply.Entry.Game\troles:def\nfound\tinput.proto\t/^  repeated Entry found = 1;$/;\"\tf\tmessage:my.test.Reply\ttyperef:typename:Entry\troles:def\ncompact_keys\tinput.proto\t/^  repeated int32 compact_keys = 2 [packed=true];$/;\"\tf\tmessage:my.test.Reply\ttyperef:typename:int32\troles:def\nOtherBase\tinput.proto\t/^message OtherBase {$/;\"\tm\tpackage:my.test\troles:def\tend:106\nname\tinput.proto\t/^  optional string name = 1;$/;\"\tf\tmessage:my.test.OtherBase\ttyperef:typename:string\troles:def\nReplyExtensions\tinput.proto\t/^message ReplyExtensions {$/;\"\tm\tpackage:my.test\troles:def\tend:116\nReply\tinput.proto\t/^  extend Reply {$/;\"\tm\tmessage:my.test.ReplyExtensions\troles:extension\tend:112\ntime\tinput.proto\t/^    optional double time = 101;$/;\"\tf\tmessage:my.test.ReplyExtensions.Reply\ttyperef:typename:double\troles:def\ncarrot\tinput.proto\t/^    optional ReplyExtensions carrot = 105;$/;\"\tf\tmessage:my.test.ReplyExtensions.Reply\ttyperef:typename:ReplyExtensions\troles:def\nOtherBase\tinput.proto\t/^  extend OtherBase {$/;\"\tm\tmessage:my.test.ReplyExtensions\troles:extension\tend:115\ndonut\tinput.proto\t/^    optional ReplyExtensions donut = 101;$/;\"\tf\tmessage:my.test.ReplyExtensions.OtherBase\ttyperef:typename:ReplyExtensions\troles:def\nOtherReplyExtensions\tinput.proto\t/^message OtherReplyExtensions {$/;\"\tm\tpackage:my.test\troles:def\tend:120\nkey\tinput.proto\t/^  optional int32 key = 1;$/;\"\tf\tmessage:my.test.OtherReplyExtensions\ttyperef:typename:int32\troles:def\nReply\tinput.proto\t/^extend Reply {$/;\"\tm\tpackage:my.test\troles:extension\tend:127\ntag\tinput.proto\t/^  optional string tag = 103;$/;\"\tf\tmessage:my.test.Reply\ttyperef:typename:string\troles:def\ndonut\tinput.proto\t/^  optional OtherReplyExtensions donut = 106;$/;\"\tf\tmessage:my.test.Reply\ttyperef:typename:OtherReplyExtensions\troles:def\nOldReply\tinput.proto\t/^message OldReply {$/;\"\tm\tpackage:my.test\troles:def\tend:133\nCommunique\tinput.proto\t/^message Communique {$/;\"\tm\tpackage:my.test\troles:def\tend:155\nmake_me_cry\tinput.proto\t/^  optional bool make_me_cry = 1;$/;\"\tf\tmessage:my.test.Communique\ttyperef:typename:bool\troles:def\nunion\tinput.proto\t/^  oneof union {$/;\"\to\tmessage:my.test.Communique\troles:def\tend:152\nnumber\tinput.proto\t/^    int32 number = 5;$/;\"\tf\toneof:my.test.Communique.union\ttyperef:typename:int32\troles:def\nname\tinput.proto\t/^    string name = 6;$/;\"\tf\toneof:my.test.Communique.union\ttyperef:typename:string\troles:def\ndata\tinput.proto\t/^    bytes data = 7;$/;\"\tf\toneof:my.test.Communique.union\ttyperef:typename:bytes\troles:def\ntemp_c\tinput.proto\t/^    double temp_c = 8;$/;\"\tf\toneof:my.test.Communique.union\ttyperef:typename:double\troles:def\nheight\tinput.proto\t/^    float height = 9;$/;\"\tf\toneof:my.test.Communique.union\ttyperef:typename:float\troles:def\ntoday\tinput.proto\t/^    Days today = 10;$/;\"\tf\toneof:my.test.Communique.union\ttyperef:typename:Days\troles:def\nmaybe\tinput.proto\t/^    bool maybe = 11;$/;\"\tf\toneof:my.test.Communique.union\ttyperef:typename:bool\troles:def\ndelta\tinput.proto\t/^    sint32 delta = 12;  \\/\\/ name will conflict with Delta below$/;\"\tf\toneof:my.test.Communique.union\ttyperef:typename:sint32\troles:def\nmsg\tinput.proto\t/^    Reply msg = 13;$/;\"\tf\toneof:my.test.Communique.union\ttyperef:typename:Reply\troles:def\nSomeGroup\tinput.proto\t/^    group SomeGroup = 14 {$/;\"\tG\toneof:my.test.Communique.union\troles:def\tend:151\nmember\tinput.proto\t/^      optional string member = 15;$/;\"\tf\tgroup:my.test.Communique.union.SomeGroup\ttyperef:typename:string\troles:def\nDelta\tinput.proto\t/^  message Delta {}$/;\"\tm\tmessage:my.test.Communique\troles:def\tend:154\n"
  },
  {
    "path": "Units/parser-protobuf.r/protobuf-group.d/input.proto",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nsyntax = \"proto2\";\n\n// This package holds interesting messages.\npackage my.test;  // dotted package name\n\n//import \"imp.proto\";\nimport \"multi/multi1.proto\";  // unused import\n\nenum HatType {\n  // deliberately skipping 0\n  FEDORA = 1;\n  FEZ = 2;\n}\n\n// This enum represents days of the week.\nenum Days {\n  option allow_alias = true;\n\n  MONDAY = 1;\n  TUESDAY = 2;\n  LUNDI = 1;  // same value as MONDAY\n}\n\n// This is a message that might be sent somewhere.\nmessage Request {\n  enum Color {\n    RED = 0;\n    GREEN = 1;\n    BLUE = 2;\n  }\n  repeated int64 key = 1;\n//  optional imp.ImportedMessage imported_message = 2;\n  optional Color hue = 3; // no default\n  optional HatType hat = 4 [default=FEDORA];\n//  optional imp.ImportedMessage.Owner owner = 6;\n  optional float deadline = 7 [default=inf];\n  optional group SomeGroup = 8 {\n    optional int32 group_field = 9;\n  }\n\n  // These foreign types are in imp2.proto,\n  // which is publicly imported by imp.proto.\n//  optional imp.PubliclyImportedMessage pub = 10;\n//  optional imp.PubliclyImportedEnum pub_enum = 13 [default=HAIR];\n\n\n  // This is a map field. It will generate map[int32]string.\n  map<int32, string> name_mapping = 14;\n  // This is a map field whose value type is a message.\n  map<sint64, Reply> msg_mapping = 15;\n\n  optional int32 reset = 12;\n  // This field should not conflict with any getters.\n  optional string get_key = 16;\n}\n\nmessage Reply {\n  message Entry {\n    required int64 key_that_needs_1234camel_CasIng = 1;\n    optional int64 value = 2 [default=7];\n    optional int64 _my_field_name_2 = 3;\n    enum Game {\n      FOOTBALL = 1;\n      TENNIS = 2;\n    }\n  }\n  repeated Entry found = 1;\n  repeated int32 compact_keys = 2 [packed=true];\n  extensions 100 to max;\n}\n\nmessage OtherBase {\n  optional string name = 1;\n  extensions 100 to max;\n}\n\nmessage ReplyExtensions {\n  extend Reply {\n    optional double time = 101;\n    optional ReplyExtensions carrot = 105;\n  }\n  extend OtherBase {\n    optional ReplyExtensions donut = 101;\n  }\n}\n\nmessage OtherReplyExtensions {\n  optional int32 key = 1;\n}\n\n// top-level extension\nextend Reply {\n  optional string tag = 103;\n  optional OtherReplyExtensions donut = 106;\n//  optional imp.ImportedMessage elephant = 107;  // extend with message from another file.\n}\n\nmessage OldReply {\n  // Extensions will be encoded in MessageSet wire format.\n  option message_set_wire_format = true;\n  extensions 100 to max;\n}\n\nmessage Communique {\n  optional bool make_me_cry = 1;\n\n  // This is a oneof, called \"union\".\n  oneof union {\n    int32 number = 5;\n    string name = 6;\n    bytes data = 7;\n    double temp_c = 8;\n    float height = 9;\n    Days today = 10;\n    bool maybe = 11;\n    sint32 delta = 12;  // name will conflict with Delta below\n    Reply msg = 13;\n    group SomeGroup = 14 {\n      optional string member = 15;\n    }\n  }\n\n  message Delta {}\n}\n\n"
  },
  {
    "path": "Units/parser-protobuf.r/protobuf-oneof.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+K{end}\n"
  },
  {
    "path": "Units/parser-protobuf.r/protobuf-oneof.d/expected.tags",
    "content": "imp\tinput.proto\t/^package imp;$/;\"\tpackage\nimp2.proto\tinput.proto\t/^import \"imp2.proto\";$/;\"\tprotodef\tpackage:imp\nimp3.proto\tinput.proto\t/^import \"imp3.proto\";$/;\"\tprotodef\tpackage:imp\nImportedMessage\tinput.proto\t/^message ImportedMessage {$/;\"\tmessage\tpackage:imp\tend:62\nfield\tinput.proto\t/^  required int64 field = 1;$/;\"\tfield\tmessage:imp.ImportedMessage\ttyperef:typename:int64\nlocal_msg\tinput.proto\t/^  optional ImportedMessage2 local_msg = 2;$/;\"\tfield\tmessage:imp.ImportedMessage\ttyperef:typename:ImportedMessage2\nforeign_msg\tinput.proto\t/^  optional ForeignImportedMessage foreign_msg = 3;  \\/\\/ in imp3.proto$/;\"\tfield\tmessage:imp.ImportedMessage\ttyperef:typename:ForeignImportedMessage\nenum_field\tinput.proto\t/^  optional Owner enum_field = 4;$/;\"\tfield\tmessage:imp.ImportedMessage\ttyperef:typename:Owner\nunion\tinput.proto\t/^  oneof union {$/;\"\toneof\tmessage:imp.ImportedMessage\tend:48\nstate\tinput.proto\t/^    int32 state = 9;$/;\"\tfield\toneof:imp.ImportedMessage.union\ttyperef:typename:int32\nname\tinput.proto\t/^  repeated string name = 5;$/;\"\tfield\tmessage:imp.ImportedMessage\ttyperef:typename:string\nboss\tinput.proto\t/^  repeated Owner boss = 6;$/;\"\tfield\tmessage:imp.ImportedMessage\ttyperef:typename:Owner\nmemo\tinput.proto\t/^  repeated ImportedMessage2 memo = 7;$/;\"\tfield\tmessage:imp.ImportedMessage\ttyperef:typename:ImportedMessage2\nmsg_map\tinput.proto\t/^  map<string, ImportedMessage2> msg_map = 8;$/;\"\tfield\tmessage:imp.ImportedMessage\ttyperef:typename:map<string,ImportedMessage2>\nOwner\tinput.proto\t/^  enum Owner {$/;\"\tenum\tmessage:imp.ImportedMessage\tend:59\nDAVE\tinput.proto\t/^    DAVE = 1;$/;\"\tenumerator\tenum:imp.ImportedMessage.Owner\nMIKE\tinput.proto\t/^    MIKE = 2;$/;\"\tenumerator\tenum:imp.ImportedMessage.Owner\nImportedMessage2\tinput.proto\t/^message ImportedMessage2 {$/;\"\tmessage\tpackage:imp\tend:65\nImportedExtendable\tinput.proto\t/^message ImportedExtendable {$/;\"\tmessage\tpackage:imp\tend:70\n"
  },
  {
    "path": "Units/parser-protobuf.r/protobuf-oneof.d/input.proto",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nsyntax = \"proto2\";\n\npackage imp;\n\nimport \"imp2.proto\";\nimport \"imp3.proto\";\n\nmessage ImportedMessage {\n  required int64 field = 1;\n\n  // The forwarded getters for these fields are fiddly to get right.\n  optional ImportedMessage2 local_msg = 2;\n  optional ForeignImportedMessage foreign_msg = 3;  // in imp3.proto\n  optional Owner enum_field = 4;\n  oneof union {\n    int32 state = 9;\n  }\n\n  repeated string name = 5;\n  repeated Owner boss = 6;\n  repeated ImportedMessage2 memo = 7;\n\n  map<string, ImportedMessage2> msg_map = 8;\n\n  enum Owner {\n    DAVE = 1;\n    MIKE = 2;\n  }\n\n  extensions 90 to 100;\n}\n\nmessage ImportedMessage2 {\n}\n\nmessage ImportedExtendable {\n  option message_set_wire_format = true;\n  extensions 100 to max;\n}\n"
  },
  {
    "path": "Units/parser-protobuf.r/simple-protobuf.d/args.ctags",
    "content": "--fields=+zK{typeref}{signature}{end}\n--extras=+r\n--sort=no\n"
  },
  {
    "path": "Units/parser-protobuf.r/simple-protobuf.d/expected.tags",
    "content": "TestPackage\tinput.proto\t/^package TestPackage;$/;\"\tkind:package\nMessage1\tinput.proto\t/^message Message1 {$/;\"\tkind:message\tpackage:TestPackage\tend:39\nfield1\tinput.proto\t/^    required string field1 = 1 [default=\"; required string thisIsNotAField = 1;\"];$/;\"\tkind:field\tmessage:TestPackage.Message1\ttyperef:typename:string\nMessage2\tinput.proto\t/^message Message2 {$/;\"\tkind:message\tpackage:TestPackage\tend:53\nNestedMessage\tinput.proto\t/^    message NestedMessage {$/;\"\tkind:message\tmessage:TestPackage.Message2\tend:44\nfield2\tinput.proto\t/^        required string field2 = 2;$/;\"\tkind:field\tmessage:TestPackage.Message2.NestedMessage\ttyperef:typename:string\nEnum1\tinput.proto\t/^    enum Enum1 {$/;\"\tkind:enum\tmessage:TestPackage.Message2\tend:49\nYES\tinput.proto\t/^        YES = 1;$/;\"\tkind:enumerator\tenum:TestPackage.Message2.Enum1\nNO\tinput.proto\t/^        NO = 2;$/;\"\tkind:enumerator\tenum:TestPackage.Message2.Enum1\nfield3\tinput.proto\t/^    repeated NestedMessage field3 = 3;$/;\"\tkind:field\tmessage:TestPackage.Message2\ttyperef:typename:NestedMessage\nfield4\tinput.proto\t/^    optional Enum1 field4 = 4;$/;\"\tkind:field\tmessage:TestPackage.Message2\ttyperef:typename:Enum1\nMessage3\tinput.proto\t/^message Message3 {$/;\"\tkind:message\tpackage:TestPackage\tend:60\nfield5\tinput.proto\t/^    required Message2.NestedMessage field5 = 5;$/;\"\tkind:field\tmessage:TestPackage.Message3\ttyperef:typename:Message2.NestedMessage\nfield6\tinput.proto\t/^    required .TestPackage.Message2.Enum1 field6 = 6;$/;\"\tkind:field\tmessage:TestPackage.Message3\ttyperef:typename:.TestPackage.Message2.Enum1\nMessage3\tinput.proto\t/^extend Message3 {$/;\"\tkind:message\tpackage:TestPackage\tend:65\nfield7\tinput.proto\t/^    optional Message2 . NestedMessage field7 = 7;$/;\"\tkind:field\tmessage:TestPackage.Message3\ttyperef:typename:Message2.NestedMessage\nfield8\tinput.proto\t/^    repeated int32 field8 = 8 [packed=true];$/;\"\tkind:field\tmessage:TestPackage.Message3\ttyperef:typename:int32\nService1\tinput.proto\t/^service Service1 {$/;\"\tkind:service\tpackage:TestPackage\tend:69\nMethod1\tinput.proto\t/^    rpc Method1(Message1) returns(Message2);$/;\"\tkind:rpc\tservice:TestPackage.Service1\ttyperef:typename:Message2\tsignature:Message1\n"
  },
  {
    "path": "Units/parser-protobuf.r/simple-protobuf.d/input.proto",
    "content": "/*\n  Masatake YAMATO takes this from https://sourceforge.net/p/ctags/patches/74/\n  after getting following approval:\n  ===============================================================================\n  Message-ID: <CALPttHe+hSa_kjwx6GoWS6CsDf_OG0bcmhmPahb4shnKb8tkWg@mail.gmail.com>\n  Subject: Re: your protobuf.patch\n  From: Ivan Krasilnikov <infnty@gmail.com>\n  To: m_yamato@users.sf.net\n  Date: Fri, 8 Jul 2016 15:37:07 +0200\n\n  Hi, yes, it's fine, no problem.\n\n  --\n  Ivan\n\n  On 8 July 2016 at 06:31, <m_yamato@users.sf.net> wrote:\n\n  > Hi,\n  >\n  > I am a developer of universal ctags(http://ctags.io).\n  >\n  > I would like to merge your patch for protobuf in *GPL v2 or later*.\n  >\n  > Is it o.k.?\n  > ------------------------------\n  >\n  > This message was sent to you via the SourceForge web mail form.\n  > You may reply to this message directly, or at\n  > https://sourceforge.net/u/userid-2121776/profile/send_message\n  >\n  ===============================================================================\n*/\npackage TestPackage;\n\nmessage Message1 {\n    required string field1 = 1 [default=\"; required string thisIsNotAField = 1;\"];\n    //optional string commentedField2 = 2;\n    /* optional string commentedField3 = 3; */\n}\n\nmessage Message2 {\n    message NestedMessage {\n        required string field2 = 2;\n    }\n\n    enum Enum1 {\n        YES = 1;\n        NO = 2;\n    }\n\n    repeated NestedMessage field3 = 3;\n    optional Enum1 field4 = 4;\n}\n\nmessage Message3 {\n    required Message2.NestedMessage field5 = 5;\n    required .TestPackage.Message2.Enum1 field6 = 6;\n\n    extensions 7 to 8;\n}\n\nextend Message3 {\n    optional Message2 . NestedMessage field7 = 7;\n    repeated int32 field8 = 8 [packed=true];\n}\n\nservice Service1 {\n    rpc Method1(Message1) returns(Message2);\n}\n"
  },
  {
    "path": "Units/parser-protobuf.r/syntax-proto3.d/args.ctags",
    "content": "--sort=no\n--fields=+{end}{typeref}{scope}{line}{kind}\n--extras=+r\n"
  },
  {
    "path": "Units/parser-protobuf.r/syntax-proto3.d/expected.tags",
    "content": "other.proto\tinput.proto\t/^import public \"other.proto\";$/;\"\tkind:D\tline:3\nEnumAllowingAlias\tinput.proto\t/^enum EnumAllowingAlias {$/;\"\tkind:g\tline:5\tend:10\nUNKNOWN\tinput.proto\t/^  UNKNOWN = 0;$/;\"\tkind:e\tline:7\tscope:enum:EnumAllowingAlias\nSTARTED\tinput.proto\t/^  STARTED = 1;$/;\"\tkind:e\tline:8\tscope:enum:EnumAllowingAlias\nRUNNING\tinput.proto\t/^  RUNNING = 2 [(custom_option) = \"hello world\"];$/;\"\tkind:e\tline:9\tscope:enum:EnumAllowingAlias\nouter\tinput.proto\t/^message outer {$/;\"\tkind:m\tline:11\tend:19\ninner\tinput.proto\t/^  message inner {   \\/\\/ Level 2$/;\"\tkind:m\tline:13\tscope:message:outer\tend:15\nival\tinput.proto\t/^    int64 ival = 1;$/;\"\tkind:f\tline:14\tscope:message:outer.inner\ttyperef:typename:int64\ninner_message\tinput.proto\t/^  repeated inner inner_message = 2;$/;\"\tkind:f\tline:16\tscope:message:outer\ttyperef:typename:inner\nenum_field\tinput.proto\t/^  EnumAllowingAlias enum_field =3;$/;\"\tkind:f\tline:17\tscope:message:outer\ttyperef:typename:EnumAllowingAlias\nmy_map\tinput.proto\t/^  map<int32, string> my_map = 4;$/;\"\tkind:f\tline:18\tscope:message:outer\ttyperef:typename:map<int32,string>\n"
  },
  {
    "path": "Units/parser-protobuf.r/syntax-proto3.d/input.proto",
    "content": "// Taken from https://developers.google.com/protocol-buffers/docs/reference/proto3-spec\nsyntax = \"proto3\";\nimport public \"other.proto\";\noption java_package = \"com.example.foo\";\nenum EnumAllowingAlias {\n  option allow_alias = true;\n  UNKNOWN = 0;\n  STARTED = 1;\n  RUNNING = 2 [(custom_option) = \"hello world\"];\n}\nmessage outer {\n  option (my_option).a = true;\n  message inner {   // Level 2\n    int64 ival = 1;\n  }\n  repeated inner inner_message = 2;\n  EnumAllowingAlias enum_field =3;\n  map<int32, string> my_map = 4;\n}\n"
  },
  {
    "path": "Units/parser-protobuf.r/version-2-3-files.d/args.ctags",
    "content": "--sort=no\n--extras=+f\n"
  },
  {
    "path": "Units/parser-protobuf.r/version-2-3-files.d/expected.tags",
    "content": "input.proto\tinput.proto\t1;\"\tF\nData\tinput-0.proto\t/^message Data {$/;\"\tm\nMaxNodeID\tinput-0.proto\t/^\trequired uint64 MaxNodeID = 7;$/;\"\tf\tmessage:Data\ttyperef:typename:uint64\ninput-0.proto\tinput-0.proto\t1;\"\tF\n"
  },
  {
    "path": "Units/parser-protobuf.r/version-2-3-files.d/input-0.proto",
    "content": "/* THIS IS VERSION 2 FILE. */\n\nmessage Data {\n\trequired uint64 MaxNodeID = 7;\n}\n"
  },
  {
    "path": "Units/parser-protobuf.r/version-2-3-files.d/input.proto",
    "content": "syntax = \"proto3\";\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/README.md",
    "content": "puppetManifest parser is a test bench parser for evaluating\nthe quality and usefulness mtable regex metaparser.\n\nInput for test cases started from puppet- under this directory are\ntaken from puppet-3.8.7/spec/fixtures/unit/parser/lexer/*.pp.\n\n## Test Input Verification\n\n### Requirements\n\nInstall puppet-agent to your platform:\n[Linux](https://puppet.com/docs/puppet/5.3/install_linux.html),\n[Windows](https://puppet.com/docs/puppet/5.3/install_windows.html) or\n[macOS](https://puppet.com/docs/puppet/5.3/install_osx.html)\n\n### Execute Verification\n\nFrom the `<repo_root>/Units/parser-puppetManifest.r` directory execute the\nfollowing:\n\n```\nfind . -name \"*.pp\" | xargs -n 1 -I@ bash -c \" echo @ &&  /opt/puppetlabs/bin/puppet apply --noop @\"\n```\n\nIn that command we find all puppet files in the unit test directory. Then we\nrun `puppet apply --noop` on each of them, essentially checking the input\nfile.  The return value of the above command will be non-zero if any puppet\nrun fails.\n\n\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/class-with-parameters.d/args.ctags",
    "content": "--sort=no\n--fields=+iS\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/class-with-parameters.d/expected.tags",
    "content": "webserver::params\tinput.pp\t/^class webserver::params {$/;\"\tc\npackages\tinput.pp\t/^  $packages = $operatingsystem ? {$/;\"\tv\tclass:::webserver::params\nvhost_dir\tinput.pp\t/^  $vhost_dir = $operatingsystem ? {$/;\"\tv\tclass:::webserver::params\nwebserver\tinput.pp\t/^class webserver($/;\"\tc\tinherits:webserver::params\tsignature:($packages,$vhost_dir)\npackages\tinput.pp\t/^  String $packages  = $webserver::params::packages,$/;\"\tp\tclass:::webserver\nvhost_dir\tinput.pp\t/^  String $vhost_dir = $webserver::params::vhost_dir$/;\"\tp\tclass:::webserver\nvhost_dir\tinput.pp\t/^ file { 'vhost_dir':$/;\"\tr\tclass:::webserver\ttyperef:typename:file\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/class-with-parameters.d/input.pp",
    "content": "# Taken from https://puppet.com/docs/puppet/5.5/lang_classes.html\n\n# /etc/puppetlabs/code/modules/webserver/manifests/params.pp\n\nclass webserver::params {\n  $packages = $operatingsystem ? {\n    /(?i-mx:ubuntu|debian)/        => 'apache2',\n    /(?i-mx:centos|fedora|redhat)/ => 'httpd',\n  }\n  $vhost_dir = $operatingsystem ? {\n    /(?i-mx:ubuntu|debian)/        => '/etc/apache2/sites-enabled',\n    /(?i-mx:centos|fedora|redhat)/ => '/etc/httpd/conf.d',\n  }\n}\n\n# /etc/puppetlabs/code/modules/webserver/manifests/init.pp\n\nclass webserver(\n  String $packages  = $webserver::params::packages,\n  String $vhost_dir = $webserver::params::vhost_dir\n) inherits webserver::params {\n\n package { $packages: ensure => present }\n\n file { 'vhost_dir':\n   path   => $vhost_dir,\n   ensure => directory,\n   mode   => '0750',\n   owner  => 'www-data',\n   group  => 'root',\n }\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/nested-blocks.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/nested-blocks.d/expected.tags",
    "content": "myClass\tinput.pp\t/^class myClass {$/;\"\tc\n::myClass\tinput.pp\t/^class myClass {$/;\"\tc\nmy_variable\tinput.pp\t/^  $my_variable= 1209600$/;\"\tv\tclass:::myClass\n::myClass::my_variable\tinput.pp\t/^  $my_variable= 1209600$/;\"\tv\tclass:::myClass\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/nested-blocks.d/input.pp",
    "content": "#\n# Taken from an initial comment submitted by @ahakanbaba of issue 1991\n#\nclass myClass {\n  ensure_packages(['ksh','openssl'], {'ensure' => 'present'})\n  $my_variable= 1209600\n}\n\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/node.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/node.d/expected.tags",
    "content": "default\tinput.pp\t/^node 'default' {}$/;\"\tnode\tline:2\tlanguage:PuppetManifest\nwww1.example.com\tinput.pp\t/^node 'www1.example.com' {$/;\"\tnode\tline:3\tlanguage:PuppetManifest\nwww2.example.com\tinput.pp\t/^node 'www2.example.com', 'www3.example.com' {$/;\"\tnode\tline:13\tlanguage:PuppetManifest\nwww3.example.com\tinput.pp\t/^node 'www2.example.com', 'www3.example.com' {$/;\"\tnode\tline:13\tlanguage:PuppetManifest\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/node.d/input.pp",
    "content": "/* Taken from https://docs.puppet.com/puppet/5.1/lang_node_definitions.html */\nnode 'default' {}\nnode 'www1.example.com' {\n  include common\n  include apache\n  include squid\n}\n\nnode /^www\\d+$/ {\n  include common\n}\n\nnode 'www2.example.com', 'www3.example.com' {\n  include common\n  include apache, squid\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-aliastest.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-aliastest.d/expected.tags",
    "content": "a file\tinput.pp\t/^file { \"a file\":$/;\"\tresource\tline:1\tlanguage:PuppetManifest\ttyperef:typename:file\tend:4\nanother\tinput.pp\t/^file { \"another\":$/;\"\tresource\tline:6\tlanguage:PuppetManifest\ttyperef:typename:file\tend:10\na third\tinput.pp\t/^file { \"a third\":$/;\"\tresource\tline:12\tlanguage:PuppetManifest\ttyperef:typename:file\tend:16\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-aliastest.d/input.pp",
    "content": "file { \"a file\":\n    path => \"/tmp/aliastest\",\n    ensure => file\n}\n\nfile { \"another\":\n    path => \"/tmp/aliastest2\",\n    ensure => file,\n    require => File[\"a file\"]\n}\n\nfile { \"a third\":\n    path => \"/tmp/aliastest3\",\n    ensure => file,\n    require => File[\"/tmp/aliastest\"]\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-append.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-append.d/expected.tags",
    "content": "var\tinput.pp\t/^$var=['\\/tmp\\/file1','\\/tmp\\/file2']$/;\"\tvariable\tline:1\tlanguage:PuppetManifest\narraytest\tinput.pp\t/^class arraytest {$/;\"\tclass\tline:3\tlanguage:PuppetManifest\tend:9\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-append.d/input.pp",
    "content": "$var=['/tmp/file1','/tmp/file2']\n\nclass arraytest {\n    $var += ['/tmp/file3', '/tmp/file4']\n    file {\n        $var:\n            content => \"test\"\n    }\n}\n\ninclude arraytest\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-append.d/validator",
    "content": "#\n# The puppet validator reports this input as \"invalid\" because\n# += operator is obsoleted in puppet5.\n# @ahakanbaba in #1909 reported and proposed a fix for this already.\n#\n# However, @masatake kept this as is for following reasons:\n#\n# - valid in puppet4,\n# - testing KNOWN-INVALIDATION special validator, and\n# - testing '#' comment in a validator file.\n#\nKNOWN-INVALIDATION\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-argumentdefaults.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne{signature}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-argumentdefaults.d/expected.tags",
    "content": "testargs\tinput.pp\t/^define testargs($file, $mode = '0755') {$/;\"\tdefinition\tline:3\tlanguage:PuppetManifest\tsignature:($file,$mode)\tend:5\nfile\tinput.pp\t/^define testargs($file, $mode = '0755') {$/;\"\tparam\tline:3\tlanguage:PuppetManifest\tscope:definition:testargs\nmode\tinput.pp\t/^define testargs($file, $mode = '0755') {$/;\"\tparam\tline:3\tlanguage:PuppetManifest\tscope:definition:testargs\ntestingname\tinput.pp\t/^testargs { \"testingname\":$/;\"\tresource\tline:7\tlanguage:PuppetManifest\ttyperef:typename:testargs\tend:9\ntestingother\tinput.pp\t/^testargs { \"testingother\":$/;\"\tresource\tline:11\tlanguage:PuppetManifest\ttyperef:typename:testargs\tend:14\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-argumentdefaults.d/input.pp",
    "content": "# $Id$\n\ndefine testargs($file, $mode = '0755') {\n    file { $file: ensure => file, mode => $mode }\n}\n\ntestargs { \"testingname\":\n    file => \"/tmp/argumenttest1\"\n}\n\ntestargs { \"testingother\":\n    file => \"/tmp/argumenttest2\",\n    mode => '0644'\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-arithmetic_expression.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-arithmetic_expression.d/expected.tags",
    "content": "one\tinput.pp\t/^$one = 1.30$/;\"\tvariable\tline:2\tlanguage:PuppetManifest\ntwo\tinput.pp\t/^$two = 2.034e-2$/;\"\tvariable\tline:3\tlanguage:PuppetManifest\nresult\tinput.pp\t/^$result = ((( $two + 2) \\/ $one) + 4 * 5.45) - (6 << 7) + (0x800 + -9)$/;\"\tvariable\tline:5\tlanguage:PuppetManifest\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-arithmetic_expression.d/input.pp",
    "content": "\n$one = 1.30\n$two = 2.034e-2\n\n$result = ((( $two + 2) / $one) + 4 * 5.45) - (6 << 7) + (0x800 + -9)\n\n\nnotice(\"result is $result == 1295.87692307692\")\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-arraytrailingcomma.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-arraytrailingcomma.d/expected.tags",
    "content": "/tmp/arraytrailingcomma1\tinput.pp\t/^    [\"\\/tmp\\/arraytrailingcomma1\",\"\\/tmp\\/arraytrailingcomma2\", ]: content => \"tmp\"$/;\"\tresource\tline:2\tlanguage:PuppetManifest\ttyperef:typename:file\n/tmp/arraytrailingcomma2\tinput.pp\t/^    [\"\\/tmp\\/arraytrailingcomma1\",\"\\/tmp\\/arraytrailingcomma2\", ]: content => \"tmp\"$/;\"\tresource\tline:2\tlanguage:PuppetManifest\ttyperef:typename:file\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-arraytrailingcomma.d/input.pp",
    "content": "file {\n    [\"/tmp/arraytrailingcomma1\",\"/tmp/arraytrailingcomma2\", ]: content => \"tmp\"\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-casestatement.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-casestatement.d/expected.tags",
    "content": "var\tinput.pp\t/^$var = \"value\"$/;\"\tvariable\tline:3\tlanguage:PuppetManifest\n/tmp/fakefile\tinput.pp\t/^     file { \"\\/tmp\\/fakefile\": mode => '0644', ensure => file }$/;\"\tresource\tline:7\tlanguage:PuppetManifest\ttyperef:typename:file\tend:7\n/tmp/existsfile\tinput.pp\t/^     file { \"\\/tmp\\/existsfile\": mode => '0755', ensure => file }$/;\"\tresource\tline:10\tlanguage:PuppetManifest\ttyperef:typename:file\tend:10\novar\tinput.pp\t/^$ovar = \"yayness\"$/;\"\tvariable\tline:14\tlanguage:PuppetManifest\n/tmp/nostillexistsfile\tinput.pp\t/^         file { \"\\/tmp\\/nostillexistsfile\": mode => '0644', ensure => file }$/;\"\tresource\tline:18\tlanguage:PuppetManifest\ttyperef:typename:file\tend:18\n/tmp/noexistsfile\tinput.pp\t/^                 file { \"\\/tmp\\/noexistsfile\": mode => '0644', ensure => file }$/;\"\tresource\tline:23\tlanguage:PuppetManifest\ttyperef:typename:file\tend:23\n/tmp/existsfile2\tinput.pp\t/^                 file { \"\\/tmp\\/existsfile2\": mode => '0755', ensure => file }$/;\"\tresource\tline:26\tlanguage:PuppetManifest\ttyperef:typename:file\tend:26\n/tmp/nostillexistsfile\tinput.pp\t/^         file { \"\\/tmp\\/nostillexistsfile\": mode => '0644', ensure => file }$/;\"\tresource\tline:34\tlanguage:PuppetManifest\ttyperef:typename:file\tend:34\n/tmp/existsfile3\tinput.pp\t/^        file { \"\\/tmp\\/existsfile3\": mode => '0755', ensure => file }$/;\"\tresource\tline:37\tlanguage:PuppetManifest\ttyperef:typename:file\tend:37\nbool\tinput.pp\t/^$bool = true$/;\"\tvariable\tline:41\tlanguage:PuppetManifest\n/tmp/existsfile4\tinput.pp\t/^        file { \"\\/tmp\\/existsfile4\": mode => '0755', ensure => file }$/;\"\tresource\tline:45\tlanguage:PuppetManifest\ttyperef:typename:file\tend:45\nyay\tinput.pp\t/^$yay = yay$/;\"\tvariable\tline:49\tlanguage:PuppetManifest\na\tinput.pp\t/^$a = yay$/;\"\tvariable\tline:50\tlanguage:PuppetManifest\nb\tinput.pp\t/^$b = boo$/;\"\tvariable\tline:51\tlanguage:PuppetManifest\n/tmp/existsfile5\tinput.pp\t/^    $a: { file { \"\\/tmp\\/existsfile5\": mode => '0755', ensure => file } }$/;\"\tresource\tline:54\tlanguage:PuppetManifest\ttyperef:typename:file\tend:54\n/tmp/existsfile5\tinput.pp\t/^    $b: { file { \"\\/tmp\\/existsfile5\": mode => '0644', ensure => file } }$/;\"\tresource\tline:55\tlanguage:PuppetManifest\ttyperef:typename:file\tend:55\n/tmp/existsfile5\tinput.pp\t/^    default: { file { \"\\/tmp\\/existsfile5\": mode => '0711', ensure => file } }$/;\"\tresource\tline:56\tlanguage:PuppetManifest\ttyperef:typename:file\tend:56\nregexvar\tinput.pp\t/^$regexvar = \"exists regex\"$/;\"\tvariable\tline:60\tlanguage:PuppetManifest\n/tmp/existsfile6\tinput.pp\t/^    \"no match\": { file { \"\\/tmp\\/existsfile6\": mode => '0644', ensure => file } }$/;\"\tresource\tline:62\tlanguage:PuppetManifest\ttyperef:typename:file\tend:62\n/tmp/${1}file6\tinput.pp\t/^    \\/(.*) regex$\\/: { file { \"\\/tmp\\/${1}file6\": mode => '0755', ensure => file } }$/;\"\tresource\tline:63\tlanguage:PuppetManifest\ttyperef:typename:file\tend:63\n/tmp/existsfile6\tinput.pp\t/^    default: { file { \"\\/tmp\\/existsfile6\": mode => '0711', ensure => file } }$/;\"\tresource\tline:64\tlanguage:PuppetManifest\ttyperef:typename:file\tend:64\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-casestatement.d/input.pp",
    "content": "# $Id$\n\n$var = \"value\"\n\ncase $var {\n  \"nope\": {\n     file { \"/tmp/fakefile\": mode => '0644', ensure => file }\n  }\n  \"value\": {\n     file { \"/tmp/existsfile\": mode => '0755', ensure => file }\n  }\n}\n\n$ovar = \"yayness\"\n\ncase $ovar {\n    \"fooness\": {\n         file { \"/tmp/nostillexistsfile\": mode => '0644', ensure => file }\n    }\n    \"booness\", \"yayness\": {\n        case $var {\n            \"nep\": {\n                 file { \"/tmp/noexistsfile\": mode => '0644', ensure => file }\n            }\n            \"value\": {\n                 file { \"/tmp/existsfile2\": mode => '0755', ensure => file }\n            }\n        }\n    }\n}\n\ncase $ovar {\n    \"fooness\": {\n         file { \"/tmp/nostillexistsfile\": mode => '0644', ensure => file }\n    }\n    default: {\n        file { \"/tmp/existsfile3\": mode => '0755', ensure => file }\n    }\n}\n\n$bool = true\n\ncase $bool {\n    true: {\n        file { \"/tmp/existsfile4\": mode => '0755', ensure => file }\n    }\n}\n\n$yay = yay\n$a = yay\n$b = boo\n\ncase $yay {\n    $a: { file { \"/tmp/existsfile5\": mode => '0755', ensure => file } }\n    $b: { file { \"/tmp/existsfile5\": mode => '0644', ensure => file } }\n    default: { file { \"/tmp/existsfile5\": mode => '0711', ensure => file } }\n\n}\n\n$regexvar = \"exists regex\"\ncase $regexvar {\n    \"no match\": { file { \"/tmp/existsfile6\": mode => '0644', ensure => file } }\n    /(.*) regex$/: { file { \"/tmp/${1}file6\": mode => '0755', ensure => file } }\n    default: { file { \"/tmp/existsfile6\": mode => '0711', ensure => file } }\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classheirarchy.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlnei\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classheirarchy.d/expected.tags",
    "content": "base\tinput.pp\t/^class base {$/;\"\tclass\tline:3\tlanguage:PuppetManifest\tend:5\n/tmp/classheir1\tinput.pp\t/^    file { \"\\/tmp\\/classheir1\": ensure => file, mode => '0755' }$/;\"\tresource\tline:4\tlanguage:PuppetManifest\tscope:class:::base\ttyperef:typename:file\tend:4\nsub1\tinput.pp\t/^class sub1 inherits base {$/;\"\tclass\tline:7\tlanguage:PuppetManifest\tinherits:base\tend:9\n/tmp/classheir2\tinput.pp\t/^    file { \"\\/tmp\\/classheir2\": ensure => file, mode => '0755' }$/;\"\tresource\tline:8\tlanguage:PuppetManifest\tscope:class:::sub1\ttyperef:typename:file\tend:8\nsub2\tinput.pp\t/^class sub2 inherits base {$/;\"\tclass\tline:11\tlanguage:PuppetManifest\tinherits:base\tend:13\n/tmp/classheir3\tinput.pp\t/^    file { \"\\/tmp\\/classheir3\": ensure => file, mode => '0755' }$/;\"\tresource\tline:12\tlanguage:PuppetManifest\tscope:class:::sub2\ttyperef:typename:file\tend:12\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classheirarchy.d/input.pp",
    "content": "# $Id$\n\nclass base {\n    file { \"/tmp/classheir1\": ensure => file, mode => '0755' }\n}\n\nclass sub1 inherits base {\n    file { \"/tmp/classheir2\": ensure => file, mode => '0755' }\n}\n\nclass sub2 inherits base {\n    file { \"/tmp/classheir3\": ensure => file, mode => '0755' }\n}\n\ninclude sub1, sub2\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classincludes.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlnei\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classincludes.d/expected.tags",
    "content": "base\tinput.pp\t/^class base {$/;\"\tclass\tline:3\tlanguage:PuppetManifest\tend:5\n/tmp/classincludes1\tinput.pp\t/^    file { \"\\/tmp\\/classincludes1\": ensure => file, mode => '0755' }$/;\"\tresource\tline:4\tlanguage:PuppetManifest\tscope:class:::base\ttyperef:typename:file\tend:4\nsub1\tinput.pp\t/^class sub1 inherits base {$/;\"\tclass\tline:7\tlanguage:PuppetManifest\tinherits:base\tend:9\n/tmp/classincludes2\tinput.pp\t/^    file { \"\\/tmp\\/classincludes2\": ensure => file, mode => '0755' }$/;\"\tresource\tline:8\tlanguage:PuppetManifest\tscope:class:::sub1\ttyperef:typename:file\tend:8\nsub2\tinput.pp\t/^class sub2 inherits base {$/;\"\tclass\tline:11\tlanguage:PuppetManifest\tinherits:base\tend:13\n/tmp/classincludes3\tinput.pp\t/^    file { \"\\/tmp\\/classincludes3\": ensure => file, mode => '0755' }$/;\"\tresource\tline:12\tlanguage:PuppetManifest\tscope:class:::sub2\ttyperef:typename:file\tend:12\nsub\tinput.pp\t/^$sub = \"sub2\"$/;\"\tvariable\tline:15\tlanguage:PuppetManifest\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classincludes.d/input.pp",
    "content": "# $Id$\n\nclass base {\n    file { \"/tmp/classincludes1\": ensure => file, mode => '0755' }\n}\n\nclass sub1 inherits base {\n    file { \"/tmp/classincludes2\": ensure => file, mode => '0755' }\n}\n\nclass sub2 inherits base {\n    file { \"/tmp/classincludes3\": ensure => file, mode => '0755' }\n}\n\n$sub = \"sub2\"\n\ninclude sub1, $sub\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classname.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classname.d/expected.tags",
    "content": "t\tinput.pp\t/^class t {$/;\"\tclass\tline:1\tlanguage:PuppetManifest\tend:3\n/tmp/multipleclasst\tinput.pp\t/^    file { \"\\/tmp\\/multipleclasst\": content => \"one\" }$/;\"\tresource\tline:2\tlanguage:PuppetManifest\tscope:class:::t\ttyperef:typename:file\tend:2\none_\tinput.pp\t/^class one_ {$/;\"\tclass\tline:5\tlanguage:PuppetManifest\tend:7\n/tmp/multipleclassone_\tinput.pp\t/^    file { \"\\/tmp\\/multipleclassone_\": content => \"one\" }$/;\"\tresource\tline:6\tlanguage:PuppetManifest\tscope:class:::one_\ttyperef:typename:file\tend:6\non_e\tinput.pp\t/^class on_e {$/;\"\tclass\tline:9\tlanguage:PuppetManifest\tend:11\n/tmp/multipleclasson_e\tinput.pp\t/^    file { \"\\/tmp\\/multipleclasson_e\": content => \"one\" }$/;\"\tresource\tline:10\tlanguage:PuppetManifest\tscope:class:::on_e\ttyperef:typename:file\tend:10\no_ne::tw_o\tinput.pp\t/^class o_ne::tw_o {$/;\"\tclass\tline:14\tlanguage:PuppetManifest\tend:16\n/tmp/multipleclasso_netw_o\tinput.pp\t/^    file { \"\\/tmp\\/multipleclasso_netw_o\": content => \"two\" }$/;\"\tresource\tline:15\tlanguage:PuppetManifest\tscope:class:::o_ne::tw_o\ttyperef:typename:file\tend:15\no_ne::two_\tinput.pp\t/^class o_ne::two_ {$/;\"\tclass\tline:18\tlanguage:PuppetManifest\tend:20\n/tmp/multipleclasso_netwo_\tinput.pp\t/^    file { \"\\/tmp\\/multipleclasso_netwo_\": content => \"two\" }$/;\"\tresource\tline:19\tlanguage:PuppetManifest\tscope:class:::o_ne::two_\ttyperef:typename:file\tend:19\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classname.d/input.pp",
    "content": "class t {\n    file { \"/tmp/multipleclasst\": content => \"one\" }\n}\n\nclass one_ {\n    file { \"/tmp/multipleclassone_\": content => \"one\" }\n}\n\nclass on_e {\n    file { \"/tmp/multipleclasson_e\": content => \"one\" }\n}\n\n\nclass o_ne::tw_o {\n    file { \"/tmp/multipleclasso_netw_o\": content => \"two\" }\n}\n\nclass o_ne::two_ {\n    file { \"/tmp/multipleclasso_netwo_\": content => \"two\" }\n}\n\ninclude t\ninclude one_\ninclude on_e\ninclude o_ne::tw_o\ninclude o_ne::two_\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classpathtest.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classpathtest.d/expected.tags",
    "content": "mytype\tinput.pp\t/^define mytype {$/;\"\tdefinition\tline:3\tlanguage:PuppetManifest\tend:5\n/tmp/classtest\tinput.pp\t/^    file { \"\\/tmp\\/classtest\": ensure => file, mode => '0755' }$/;\"\tresource\tline:4\tlanguage:PuppetManifest\tscope:definition:mytype\ttyperef:typename:file\tend:4\ntesting\tinput.pp\t/^class testing {$/;\"\tclass\tline:7\tlanguage:PuppetManifest\tend:9\ncomponentname\tinput.pp\t/^    mytype { \"componentname\": }$/;\"\tresource\tline:8\tlanguage:PuppetManifest\tscope:class:::testing\ttyperef:typename:mytype\tend:8\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-classpathtest.d/input.pp",
    "content": "# $Id$\n\ndefine mytype {\n    file { \"/tmp/classtest\": ensure => file, mode => '0755' }\n}\n\nclass testing {\n    mytype { \"componentname\": }\n}\n\ninclude testing\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-collection.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-collection.d/expected.tags",
    "content": "one\tinput.pp\t/^class one {$/;\"\tclass\tline:1\tlanguage:PuppetManifest\tend:4\n/tmp/colltest1\tinput.pp\t/^    @file { \"\\/tmp\\/colltest1\": content => \"one\" }$/;\"\tvresource\tline:2\tlanguage:PuppetManifest\tscope:class:::one\ttyperef:typename:file\tend:2\n/tmp/colltest2\tinput.pp\t/^    @file { \"\\/tmp\\/colltest2\": content => \"two\" }$/;\"\tvresource\tline:3\tlanguage:PuppetManifest\tscope:class:::one\ttyperef:typename:file\tend:3\ntwo\tinput.pp\t/^class two {$/;\"\tclass\tline:6\tlanguage:PuppetManifest\tend:8\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-collection.d/input.pp",
    "content": "class one {\n    @file { \"/tmp/colltest1\": content => \"one\" }\n    @file { \"/tmp/colltest2\": content => \"two\" }\n}\n\nclass two {\n    File <| content == \"one\" |>\n}\n\ninclude one, two\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-collection_override.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-collection_override.d/expected.tags",
    "content": "/tmp/collection\tinput.pp\t/^    \"\\/tmp\\/collection\":$/;\"\tvresource\tline:2\tlanguage:PuppetManifest\ttyperef:typename:file\tend:4\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-collection_override.d/input.pp",
    "content": "@file {\n    \"/tmp/collection\":\n        content => \"whatever\"\n}\n\nFile<| |> {\n    mode => '0600'\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-collection_within_virtual_definitions.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-collection_within_virtual_definitions.d/expected.tags",
    "content": "test\tinput.pp\t/^define test($my_name) {$/;\"\tdefinition\tline:1\tlanguage:PuppetManifest\tend:6\n/tmp/collection_within_virtual_definitions1_$my_name.txt\tinput.pp\t/^    file {\"\\/tmp\\/collection_within_virtual_definitions1_$my_name.txt\":$/;\"\tresource\tline:2\tlanguage:PuppetManifest\tscope:definition:test\ttyperef:typename:file\tend:4\ntest2\tinput.pp\t/^define test2() {$/;\"\tdefinition\tline:8\tlanguage:PuppetManifest\tend:12\n/tmp/collection_within_virtual_definitions2_$name.txt\tinput.pp\t/^    file {\"\\/tmp\\/collection_within_virtual_definitions2_$name.txt\":$/;\"\tresource\tline:9\tlanguage:PuppetManifest\tscope:definition:test2\ttyperef:typename:file\tend:11\nfoo\tinput.pp\t/^    @test {\"foo\":$/;\"\tvresource\tline:15\tlanguage:PuppetManifest\ttyperef:typename:test\tend:17\nfoo2\tinput.pp\t/^    @test2 {\"foo2\": }$/;\"\tvresource\tline:18\tlanguage:PuppetManifest\ttyperef:typename:test2\tend:18\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-collection_within_virtual_definitions.d/input.pp",
    "content": "define test($my_name) {\n    file {\"/tmp/collection_within_virtual_definitions1_$my_name.txt\":\n        content => \"File name $my_name\\n\"\n    }\n    Test2 <||>\n}\n\ndefine test2() {\n    file {\"/tmp/collection_within_virtual_definitions2_$name.txt\":\n        content => \"This is a test\\n\"\n    }\n}\n\nnode default {\n    @test {\"foo\":\n        my_name => \"foo\"\n    }\n    @test2 {\"foo2\": }\n    Test <||>\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-componentmetaparams.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-componentmetaparams.d/expected.tags",
    "content": "/tmp/component1\tinput.pp\t/^file { \"\\/tmp\\/component1\":$/;\"\tresource\tline:1\tlanguage:PuppetManifest\ttyperef:typename:file\tend:3\nthing\tinput.pp\t/^define thing {$/;\"\tdefinition\tline:5\tlanguage:PuppetManifest\tend:7\n/tmp/component2\tinput.pp\t/^thing { \"\\/tmp\\/component2\":$/;\"\tresource\tline:9\tlanguage:PuppetManifest\ttyperef:typename:thing\tend:11\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-componentmetaparams.d/input.pp",
    "content": "file { \"/tmp/component1\":\n    ensure => file\n}\n\ndefine thing {\n    file { $name: ensure => file }\n}\n\nthing { \"/tmp/component2\":\n    require => File[\"/tmp/component1\"]\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-componentrequire.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-componentrequire.d/expected.tags",
    "content": "testfile\tinput.pp\t/^define testfile($mode) {$/;\"\tdefinition\tline:1\tlanguage:PuppetManifest\tend:3\n/tmp/testing_component_requires2\tinput.pp\t/^testfile { \"\\/tmp\\/testing_component_requires2\": mode => '0755' }$/;\"\tresource\tline:5\tlanguage:PuppetManifest\ttyperef:typename:testfile\tend:5\n/tmp/testing_component_requires1\tinput.pp\t/^file { \"\\/tmp\\/testing_component_requires1\": mode => '0755', ensure => present,$/;\"\tresource\tline:7\tlanguage:PuppetManifest\ttyperef:typename:file\tend:8\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-componentrequire.d/input.pp",
    "content": "define testfile($mode) {\n    file { $name: mode => $mode, ensure => present }\n}\n\ntestfile { \"/tmp/testing_component_requires2\": mode => '0755' }\n\nfile { \"/tmp/testing_component_requires1\": mode => '0755', ensure => present,\n    require => Testfile[\"/tmp/testing_component_requires2\"] }\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-deepclassheirarchy.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlnei\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-deepclassheirarchy.d/expected.tags",
    "content": "base\tinput.pp\t/^class base {$/;\"\tclass\tline:3\tlanguage:PuppetManifest\tend:5\n/tmp/deepclassheir1\tinput.pp\t/^    file { \"\\/tmp\\/deepclassheir1\": ensure => file, mode => '0755' }$/;\"\tresource\tline:4\tlanguage:PuppetManifest\tscope:class:::base\ttyperef:typename:file\tend:4\nsub1\tinput.pp\t/^class sub1 inherits base {$/;\"\tclass\tline:7\tlanguage:PuppetManifest\tinherits:base\tend:9\n/tmp/deepclassheir2\tinput.pp\t/^    file { \"\\/tmp\\/deepclassheir2\": ensure => file, mode => '0755' }$/;\"\tresource\tline:8\tlanguage:PuppetManifest\tscope:class:::sub1\ttyperef:typename:file\tend:8\nsub2\tinput.pp\t/^class sub2 inherits sub1 {$/;\"\tclass\tline:11\tlanguage:PuppetManifest\tinherits:sub1\tend:13\n/tmp/deepclassheir3\tinput.pp\t/^    file { \"\\/tmp\\/deepclassheir3\": ensure => file, mode => '0755' }$/;\"\tresource\tline:12\tlanguage:PuppetManifest\tscope:class:::sub2\ttyperef:typename:file\tend:12\nsub3\tinput.pp\t/^class sub3 inherits sub2 {$/;\"\tclass\tline:15\tlanguage:PuppetManifest\tinherits:sub2\tend:17\n/tmp/deepclassheir4\tinput.pp\t/^    file { \"\\/tmp\\/deepclassheir4\": ensure => file, mode => '0755' }$/;\"\tresource\tline:16\tlanguage:PuppetManifest\tscope:class:::sub3\ttyperef:typename:file\tend:16\nsub4\tinput.pp\t/^class sub4 inherits sub3 {$/;\"\tclass\tline:19\tlanguage:PuppetManifest\tinherits:sub3\tend:21\n/tmp/deepclassheir5\tinput.pp\t/^    file { \"\\/tmp\\/deepclassheir5\": ensure => file, mode => '0755' }$/;\"\tresource\tline:20\tlanguage:PuppetManifest\tscope:class:::sub4\ttyperef:typename:file\tend:20\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-deepclassheirarchy.d/input.pp",
    "content": "# $Id$\n\nclass base {\n    file { \"/tmp/deepclassheir1\": ensure => file, mode => '0755' }\n}\n\nclass sub1 inherits base {\n    file { \"/tmp/deepclassheir2\": ensure => file, mode => '0755' }\n}\n\nclass sub2 inherits sub1 {\n    file { \"/tmp/deepclassheir3\": ensure => file, mode => '0755' }\n}\n\nclass sub3 inherits sub2 {\n    file { \"/tmp/deepclassheir4\": ensure => file, mode => '0755' }\n}\n\nclass sub4 inherits sub3 {\n    file { \"/tmp/deepclassheir5\": ensure => file, mode => '0755' }\n}\n\ninclude sub4\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-defineoverrides.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlnei\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-defineoverrides.d/expected.tags",
    "content": "file\tinput.pp\t/^$file = \"\\/tmp\\/defineoverrides1\"$/;\"\tvariable\tline:3\tlanguage:PuppetManifest\nmyfile\tinput.pp\t/^define myfile($mode) {$/;\"\tdefinition\tline:5\tlanguage:PuppetManifest\tend:7\nbase\tinput.pp\t/^class base {$/;\"\tclass\tline:9\tlanguage:PuppetManifest\tend:11\nsub\tinput.pp\t/^class sub inherits base {$/;\"\tclass\tline:13\tlanguage:PuppetManifest\tinherits:base\tend:15\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-defineoverrides.d/input.pp",
    "content": "# $Id$\n\n$file = \"/tmp/defineoverrides1\"\n\ndefine myfile($mode) {\n    file { $name: ensure => file, mode => $mode }\n}\n\nclass base {\n    myfile { $file: mode => '0644' }\n}\n\nclass sub inherits base {\n    Myfile[$file] { mode => '0755', } # test the end-comma\n}\n\ninclude sub\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-definitionname.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-definitionname.d/expected.tags",
    "content": "t\tinput.pp\t/^define t {$/;\"\tdefinition\tline:2\tlanguage:PuppetManifest\tend:4\n/tmp/multipledefinet\tinput.pp\t/^    file { \"\\/tmp\\/multipledefinet\": content => \"one\" }$/;\"\tresource\tline:3\tlanguage:PuppetManifest\tscope:definition:t\ttyperef:typename:file\tend:3\none_\tinput.pp\t/^define one_ {$/;\"\tdefinition\tline:6\tlanguage:PuppetManifest\tend:8\n/tmp/multipledefineone_\tinput.pp\t/^    file { \"\\/tmp\\/multipledefineone_\": content => \"one\" }$/;\"\tresource\tline:7\tlanguage:PuppetManifest\tscope:definition:one_\ttyperef:typename:file\tend:7\non_e\tinput.pp\t/^define on_e {$/;\"\tdefinition\tline:10\tlanguage:PuppetManifest\tend:12\n/tmp/multipledefineon_e\tinput.pp\t/^    file { \"\\/tmp\\/multipledefineon_e\": content => \"one\" }$/;\"\tresource\tline:11\tlanguage:PuppetManifest\tscope:definition:on_e\ttyperef:typename:file\tend:11\no_ne::tw_o\tinput.pp\t/^define o_ne::tw_o {$/;\"\tdefinition\tline:15\tlanguage:PuppetManifest\tend:17\n/tmp/multipledefineo_netw_o\tinput.pp\t/^    file { \"\\/tmp\\/multipledefineo_netw_o\": content => \"two\" }$/;\"\tresource\tline:16\tlanguage:PuppetManifest\tscope:definition:o_ne::tw_o\ttyperef:typename:file\tend:16\no_ne::two_\tinput.pp\t/^define o_ne::two_ {$/;\"\tdefinition\tline:19\tlanguage:PuppetManifest\tend:21\n/tmp/multipledefineo_netwo_\tinput.pp\t/^    file { \"\\/tmp\\/multipledefineo_netwo_\": content => \"two\" }$/;\"\tresource\tline:20\tlanguage:PuppetManifest\tscope:definition:o_ne::two_\ttyperef:typename:file\tend:20\nt\tinput.pp\t/^t { 't': }$/;\"\tresource\tline:23\tlanguage:PuppetManifest\ttyperef:typename:t\tend:23\none_\tinput.pp\t/^one_ { 'one_': }$/;\"\tresource\tline:24\tlanguage:PuppetManifest\ttyperef:typename:one_\tend:24\non_e\tinput.pp\t/^on_e { 'on_e': }$/;\"\tresource\tline:25\tlanguage:PuppetManifest\ttyperef:typename:on_e\tend:25\no_ne::tw_o\tinput.pp\t/^o_ne::tw_o { 'o_ne::tw_o': }$/;\"\tresource\tline:26\tlanguage:PuppetManifest\ttyperef:typename:o_ne::tw_o\tend:26\no_ne::two_\tinput.pp\t/^o_ne::two_ { 'o_ne::two_': }$/;\"\tresource\tline:27\tlanguage:PuppetManifest\ttyperef:typename:o_ne::two_\tend:27\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-definitionname.d/input.pp",
    "content": "\ndefine t {\n    file { \"/tmp/multipledefinet\": content => \"one\" }\n}\n\ndefine one_ {\n    file { \"/tmp/multipledefineone_\": content => \"one\" }\n}\n\ndefine on_e {\n    file { \"/tmp/multipledefineon_e\": content => \"one\" }\n}\n\n\ndefine o_ne::tw_o {\n    file { \"/tmp/multipledefineo_netw_o\": content => \"two\" }\n}\n\ndefine o_ne::two_ {\n    file { \"/tmp/multipledefineo_netwo_\": content => \"two\" }\n}\n\nt { 't': }\none_ { 'one_': }\non_e { 'on_e': }\no_ne::tw_o { 'o_ne::tw_o': }\no_ne::two_ { 'o_ne::two_': }\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyclass.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyclass.d/expected.tags",
    "content": "component\tinput.pp\t/^define component {$/;\"\tdefinition\tline:3\tlanguage:PuppetManifest\tend:4\ntesting\tinput.pp\t/^class testing {$/;\"\tclass\tline:6\tlanguage:PuppetManifest\tend:7\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyclass.d/input.pp",
    "content": "# $Id$\n\ndefine component {\n}\n\nclass testing {\n}\n\ninclude testing\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyexec.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyexec.d/expected.tags",
    "content": "touch /tmp/emptyexectest\tinput.pp\t/^exec { \"touch \\/tmp\\/emptyexectest\":$/;\"\tresource\tline:1\tlanguage:PuppetManifest\ttyperef:typename:exec\tend:3\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyexec.d/input.pp",
    "content": "exec { \"touch /tmp/emptyexectest\":\n    path => \"/usr/bin:/bin\"\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyif.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyif.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyif.d/input.pp",
    "content": "\nif true {\n  # still nothing\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyifelse.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyifelse.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-emptyifelse.d/input.pp",
    "content": "\nif false {\n} else {\n  # nothing here\n}\n\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-falsevalues.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-falsevalues.d/expected.tags",
    "content": "value\tinput.pp\t/^$value = false$/;\"\tvariable\tline:1\tlanguage:PuppetManifest\n/tmp/falsevalues$value\tinput.pp\t/^file { \"\\/tmp\\/falsevalues$value\": ensure => file }$/;\"\tresource\tline:3\tlanguage:PuppetManifest\ttyperef:typename:file\tend:3\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-falsevalues.d/input.pp",
    "content": "$value = false\n\nfile { \"/tmp/falsevalues$value\": ensure => file }\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-filecreate.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-filecreate.d/expected.tags",
    "content": "/tmp/createatest\tinput.pp\t/^    \"\\/tmp\\/createatest\": ensure => file, mode => '0755';$/;\"\tresource\tline:4\tlanguage:PuppetManifest\ttyperef:typename:file\tend:4\n/tmp/createbtest\tinput.pp\t/^    \"\\/tmp\\/createbtest\": ensure => file, mode => '0755'$/;\"\tresource\tline:5\tlanguage:PuppetManifest\ttyperef:typename:file\tend:6\n/tmp/createctest\tinput.pp\t/^    \"\\/tmp\\/createctest\": ensure => file;$/;\"\tresource\tline:9\tlanguage:PuppetManifest\ttyperef:typename:file\tend:9\n/tmp/createdtest\tinput.pp\t/^    \"\\/tmp\\/createdtest\": ensure => file;$/;\"\tresource\tline:10\tlanguage:PuppetManifest\ttyperef:typename:file\tend:10\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-filecreate.d/input.pp",
    "content": "# $Id$\n\nfile {\n    \"/tmp/createatest\": ensure => file, mode => '0755';\n    \"/tmp/createbtest\": ensure => file, mode => '0755'\n}\n\nfile {\n    \"/tmp/createctest\": ensure => file;\n    \"/tmp/createdtest\": ensure => file;\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-fqdefinition.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-fqdefinition.d/expected.tags",
    "content": "one::two\tinput.pp\t/^define one::two($ensure) {$/;\"\tdefinition\tline:1\tlanguage:PuppetManifest\tend:3\n/tmp/fqdefinition\tinput.pp\t/^    file { \"\\/tmp\\/fqdefinition\": ensure => $ensure }$/;\"\tresource\tline:2\tlanguage:PuppetManifest\tscope:definition:one::two\ttyperef:typename:file\tend:2\n/tmp/fqdefinition\tinput.pp\t/^one::two { \"\\/tmp\\/fqdefinition\": ensure => file }$/;\"\tresource\tline:5\tlanguage:PuppetManifest\ttyperef:typename:one::two\tend:5\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-fqdefinition.d/input.pp",
    "content": "define one::two($ensure) {\n    file { \"/tmp/fqdefinition\": ensure => $ensure }\n}\n\none::two { \"/tmp/fqdefinition\": ensure => file }\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-fqparents.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlnei\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-fqparents.d/expected.tags",
    "content": "base\tinput.pp\t/^class base {$/;\"\tclass\tline:1\tlanguage:PuppetManifest\tend:5\none\tinput.pp\t/^    class one {$/;\"\tclass\tline:2\tlanguage:PuppetManifest\tscope:class:::base\tend:4\n/tmp/fqparent1\tinput.pp\t/^        file { \"\\/tmp\\/fqparent1\": ensure => file }$/;\"\tresource\tline:3\tlanguage:PuppetManifest\tscope:class:::base::one\ttyperef:typename:file\tend:3\ntwo::three\tinput.pp\t/^class two::three inherits base::one {$/;\"\tclass\tline:7\tlanguage:PuppetManifest\tinherits:base::one\tend:9\n/tmp/fqparent2\tinput.pp\t/^    file { \"\\/tmp\\/fqparent2\": ensure => file }$/;\"\tresource\tline:8\tlanguage:PuppetManifest\tscope:class:::two::three\ttyperef:typename:file\tend:8\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-fqparents.d/input.pp",
    "content": "class base {\n    class one {\n        file { \"/tmp/fqparent1\": ensure => file }\n    }\n}\n\nclass two::three inherits base::one {\n    file { \"/tmp/fqparent2\": ensure => file }\n}\n\ninclude two::three\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-funccomma.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-funccomma.d/expected.tags",
    "content": "/tmp/funccomma1\tinput.pp\t/^    [\"\\/tmp\\/funccomma1\",\"\\/tmp\\/funccomma2\"]: content => \"1\"$/;\"\tvresource\tline:2\tlanguage:PuppetManifest\ttyperef:typename:file\n/tmp/funccomma2\tinput.pp\t/^    [\"\\/tmp\\/funccomma1\",\"\\/tmp\\/funccomma2\"]: content => \"1\"$/;\"\tvresource\tline:2\tlanguage:PuppetManifest\ttyperef:typename:file\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-funccomma.d/input.pp",
    "content": "@file {\n    [\"/tmp/funccomma1\",\"/tmp/funccomma2\"]: content => \"1\"\n}\n\nrealize( File[\"/tmp/funccomma1\"], File[\"/tmp/funccomma2\"] , )\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-hash.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne{signature}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-hash.d/expected.tags",
    "content": "hash\tinput.pp\t/^$hash = { \"file\" => \"\\/tmp\\/myhashfile1\" }$/;\"\tvariable\tline:2\tlanguage:PuppetManifest\nhash2\tinput.pp\t/^$hash2 = { \"a\" => { key => \"\\/tmp\\/myhashfile2\" }}$/;\"\tvariable\tline:9\tlanguage:PuppetManifest\ntest\tinput.pp\t/^define test($a = { \"b\" => \"c\" }) {$/;\"\tdefinition\tline:16\tlanguage:PuppetManifest\tsignature:($a)\tend:21\na\tinput.pp\t/^define test($a = { \"b\" => \"c\" }) {$/;\"\tparam\tline:16\tlanguage:PuppetManifest\tscope:definition:test\ntest\tinput.pp\t/^    \"test\":$/;\"\tresource\tline:24\tlanguage:PuppetManifest\ttyperef:typename:test\tend:26\nhash3\tinput.pp\t/^$hash3 = { mykey => \"\\/tmp\\/myhashfile4\" }$/;\"\tvariable\tline:28\tlanguage:PuppetManifest\nkey\tinput.pp\t/^$key = \"mykey\"$/;\"\tvariable\tline:29\tlanguage:PuppetManifest\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-hash.d/input.pp",
    "content": "\n$hash = { \"file\" => \"/tmp/myhashfile1\" }\n\nfile {\n    $hash[\"file\"]:\n        ensure => file, content => \"content\";\n}\n\n$hash2 = { \"a\" => { key => \"/tmp/myhashfile2\" }}\n\nfile {\n    $hash2[\"a\"][key]:\n        ensure => file, content => \"content\";\n}\n\ndefine test($a = { \"b\" => \"c\" }) {\n    file {\n        $a[\"b\"]:\n            ensure => file, content => \"content\"\n    }\n}\n\ntest {\n    \"test\":\n        a => { \"b\" => \"/tmp/myhashfile3\" }\n}\n\n$hash3 = { mykey => \"/tmp/myhashfile4\" }\n$key = \"mykey\"\n\nfile {\n    $hash3[$key]: ensure => file, content => \"content\"\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-ifexpression.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-ifexpression.d/expected.tags",
    "content": "one\tinput.pp\t/^$one = 1$/;\"\tvariable\tline:1\tlanguage:PuppetManifest\ntwo\tinput.pp\t/^$two = 2$/;\"\tvariable\tline:2\tlanguage:PuppetManifest\n/tmp/${1}iftest\tinput.pp\t/^        \"\\/tmp\\/${1}iftest\": ensure => file, mode => '0755'$/;\"\tresource\tline:10\tlanguage:PuppetManifest\ttyperef:typename:file\tend:11\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-ifexpression.d/input.pp",
    "content": "$one = 1\n$two = 2\n\nif ($one < $two) and (($two < 3) or ($two == 2)) {\n    notice(\"True!\")\n}\n\nif \"test regex\" =~ /(.*) regex/ {\n    file {\n        \"/tmp/${1}iftest\": ensure => file, mode => '0755'\n    }\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-implicititeration.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-implicititeration.d/expected.tags",
    "content": "files\tinput.pp\t/^$files = [\"\\/tmp\\/iterationatest\", \"\\/tmp\\/iterationbtest\"]$/;\"\tvariable\tline:3\tlanguage:PuppetManifest\n/tmp/iterationctest\tinput.pp\t/^file { [\"\\/tmp\\/iterationctest\", \"\\/tmp\\/iterationdtest\"]:$/;\"\tresource\tline:7\tlanguage:PuppetManifest\ttyperef:typename:file\n/tmp/iterationdtest\tinput.pp\t/^file { [\"\\/tmp\\/iterationctest\", \"\\/tmp\\/iterationdtest\"]:$/;\"\tresource\tline:7\tlanguage:PuppetManifest\ttyperef:typename:file\n/tmp/iterationetest\tinput.pp\t/^    [\"\\/tmp\\/iterationetest\", \"\\/tmp\\/iterationftest\"]: ensure => file, mode => '0755';$/;\"\tresource\tline:13\tlanguage:PuppetManifest\ttyperef:typename:file\n/tmp/iterationftest\tinput.pp\t/^    [\"\\/tmp\\/iterationetest\", \"\\/tmp\\/iterationftest\"]: ensure => file, mode => '0755';$/;\"\tresource\tline:13\tlanguage:PuppetManifest\ttyperef:typename:file\n/tmp/iterationgtest\tinput.pp\t/^    [\"\\/tmp\\/iterationgtest\", \"\\/tmp\\/iterationhtest\"]: ensure => file, mode => '0755';$/;\"\tresource\tline:14\tlanguage:PuppetManifest\ttyperef:typename:file\n/tmp/iterationhtest\tinput.pp\t/^    [\"\\/tmp\\/iterationgtest\", \"\\/tmp\\/iterationhtest\"]: ensure => file, mode => '0755';$/;\"\tresource\tline:14\tlanguage:PuppetManifest\ttyperef:typename:file\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-implicititeration.d/input.pp",
    "content": "# $Id$\n\n$files = [\"/tmp/iterationatest\", \"/tmp/iterationbtest\"]\n\nfile { $files: ensure => file, mode => '0755' }\n\nfile { [\"/tmp/iterationctest\", \"/tmp/iterationdtest\"]:\n    ensure => file,\n    mode => '0755'\n}\n\nfile {\n    [\"/tmp/iterationetest\", \"/tmp/iterationftest\"]: ensure => file, mode => '0755';\n    [\"/tmp/iterationgtest\", \"/tmp/iterationhtest\"]: ensure => file, mode => '0755';\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multilinecomments.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multilinecomments.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multilinecomments.d/input.pp",
    "content": "\n/*\nfile {\n    \"/tmp/multilinecomments\": content => \"pouet\"\n}\n*/\n\n/* and another one for #2333, the whitespace after the \nend comment is here on purpose */  \n\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multipleclass.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multipleclass.d/expected.tags",
    "content": "one\tinput.pp\t/^class one {$/;\"\tclass\tline:1\tlanguage:PuppetManifest\tend:3\n/tmp/multipleclassone\tinput.pp\t/^    file { \"\\/tmp\\/multipleclassone\": content => \"one\" }$/;\"\tresource\tline:2\tlanguage:PuppetManifest\tscope:class:::one\ttyperef:typename:file\tend:2\ntwo\tinput.pp\t/^class two {$/;\"\tclass\tline:5\tlanguage:PuppetManifest\tend:7\n/tmp/multipleclasstwo\tinput.pp\t/^    file { \"\\/tmp\\/multipleclasstwo\": content => \"two\" }$/;\"\tresource\tline:6\tlanguage:PuppetManifest\tscope:class:::two\ttyperef:typename:file\tend:6\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multipleclass.d/input.pp",
    "content": "class one {\n    file { \"/tmp/multipleclassone\": content => \"one\" }\n}\n\nclass two {\n    file { \"/tmp/multipleclasstwo\": content => \"two\" }\n}\n\ninclude one\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multipleinstances.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multipleinstances.d/expected.tags",
    "content": "/tmp/multipleinstancesa\tinput.pp\t/^    \"\\/tmp\\/multipleinstancesa\": ensure => file, mode => '0755';$/;\"\tresource\tline:4\tlanguage:PuppetManifest\ttyperef:typename:file\tend:4\n/tmp/multipleinstancesb\tinput.pp\t/^    \"\\/tmp\\/multipleinstancesb\": ensure => file, mode => '0755';$/;\"\tresource\tline:5\tlanguage:PuppetManifest\ttyperef:typename:file\tend:5\n/tmp/multipleinstancesc\tinput.pp\t/^    \"\\/tmp\\/multipleinstancesc\": ensure => file, mode => '0755';$/;\"\tresource\tline:6\tlanguage:PuppetManifest\ttyperef:typename:file\tend:6\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multipleinstances.d/input.pp",
    "content": "# $Id$\n\nfile {\n    \"/tmp/multipleinstancesa\": ensure => file, mode => '0755';\n    \"/tmp/multipleinstancesb\": ensure => file, mode => '0755';\n    \"/tmp/multipleinstancesc\": ensure => file, mode => '0755';\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multisubs.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlnei\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multisubs.d/expected.tags",
    "content": "base\tinput.pp\t/^class base {$/;\"\tclass\tline:1\tlanguage:PuppetManifest\tend:3\n/tmp/multisubtest\tinput.pp\t/^    file { \"\\/tmp\\/multisubtest\": content => \"base\", mode => '0644' }$/;\"\tresource\tline:2\tlanguage:PuppetManifest\tscope:class:::base\ttyperef:typename:file\tend:2\nsub1\tinput.pp\t/^class sub1 inherits base {$/;\"\tclass\tline:5\tlanguage:PuppetManifest\tinherits:base\tend:7\nsub2\tinput.pp\t/^class sub2 inherits base {$/;\"\tclass\tline:9\tlanguage:PuppetManifest\tinherits:base\tend:11\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-multisubs.d/input.pp",
    "content": "class base {\n    file { \"/tmp/multisubtest\": content => \"base\", mode => '0644' }\n}\n\nclass sub1 inherits base {\n    File[\"/tmp/multisubtest\"] { mode => '0755' }\n}\n\nclass sub2 inherits base {\n    File[\"/tmp/multisubtest\"] { content => sub2 }\n}\n\ninclude sub1, sub2\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-namevartest.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne{signature}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-namevartest.d/expected.tags",
    "content": "filetest\tinput.pp\t/^define filetest($mode, $ensure = file) {$/;\"\tdefinition\tline:1\tlanguage:PuppetManifest\tsignature:($mode,$ensure)\tend:6\nmode\tinput.pp\t/^define filetest($mode, $ensure = file) {$/;\"\tparam\tline:1\tlanguage:PuppetManifest\tscope:definition:filetest\nensure\tinput.pp\t/^define filetest($mode, $ensure = file) {$/;\"\tparam\tline:1\tlanguage:PuppetManifest\tscope:definition:filetest\n/tmp/testfiletest\tinput.pp\t/^filetest { \"\\/tmp\\/testfiletest\": mode => '0644'}$/;\"\tresource\tline:8\tlanguage:PuppetManifest\ttyperef:typename:filetest\tend:8\n/tmp/testdirtest\tinput.pp\t/^filetest { \"\\/tmp\\/testdirtest\": mode => '0755', ensure => directory}$/;\"\tresource\tline:9\tlanguage:PuppetManifest\ttyperef:typename:filetest\tend:9\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-namevartest.d/input.pp",
    "content": "define filetest($mode, $ensure = file) {\n    file { $name:\n        mode => $mode,\n        ensure => $ensure\n    }\n}\n\nfiletest { \"/tmp/testfiletest\": mode => '0644'}\nfiletest { \"/tmp/testdirtest\": mode => '0755', ensure => directory}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-scopetest.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-scopetest.d/expected.tags",
    "content": "mode\tinput.pp\t/^$mode = \"640\"$/;\"\tvariable\tline:2\tlanguage:PuppetManifest\nthing\tinput.pp\t/^define thing {$/;\"\tdefinition\tline:4\tlanguage:PuppetManifest\tend:6\n/tmp/$name\tinput.pp\t/^    file { \"\\/tmp\\/$name\": ensure => file, mode => $mode }$/;\"\tresource\tline:5\tlanguage:PuppetManifest\tscope:definition:thing\ttyperef:typename:file\tend:5\ntesting\tinput.pp\t/^class testing {$/;\"\tclass\tline:8\tlanguage:PuppetManifest\tend:11\nmode\tinput.pp\t/^    $mode = \"755\"$/;\"\tvariable\tline:9\tlanguage:PuppetManifest\tscope:class:::testing\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-scopetest.d/input.pp",
    "content": "\n$mode = \"640\"\n\ndefine thing {\n    file { \"/tmp/$name\": ensure => file, mode => $mode }\n}\n\nclass testing {\n    $mode = \"755\"\n    thing {scopetest: }\n}\n\ninclude testing\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-selectorvalues.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-selectorvalues.d/expected.tags",
    "content": "value1\tinput.pp\t/^$value1 = \"\"$/;\"\tvariable\tline:1\tlanguage:PuppetManifest\nvalue2\tinput.pp\t/^$value2 = true$/;\"\tvariable\tline:2\tlanguage:PuppetManifest\nvalue3\tinput.pp\t/^$value3 = false$/;\"\tvariable\tline:3\tlanguage:PuppetManifest\nvalue4\tinput.pp\t/^$value4 = yay$/;\"\tvariable\tline:4\tlanguage:PuppetManifest\ntest\tinput.pp\t/^$test = \"yay\"$/;\"\tvariable\tline:6\tlanguage:PuppetManifest\nmode1\tinput.pp\t/^$mode1 = $value1 ? {$/;\"\tvariable\tline:8\tlanguage:PuppetManifest\nmode2\tinput.pp\t/^$mode2 = $value2 ? {$/;\"\tvariable\tline:13\tlanguage:PuppetManifest\nmode3\tinput.pp\t/^$mode3 = $value3 ? {$/;\"\tvariable\tline:18\tlanguage:PuppetManifest\nmode4\tinput.pp\t/^$mode4 = $value4 ? {$/;\"\tvariable\tline:23\tlanguage:PuppetManifest\nmode5\tinput.pp\t/^$mode5 = yay ? {$/;\"\tvariable\tline:28\tlanguage:PuppetManifest\nmode6\tinput.pp\t/^$mode6 = $mode5 ? {$/;\"\tvariable\tline:33\tlanguage:PuppetManifest\nmode7\tinput.pp\t/^$mode7 = \"test regex\" ? {$/;\"\tvariable\tline:37\tlanguage:PuppetManifest\n/tmp/selectorvalues1\tinput.pp\t/^file { \"\\/tmp\\/selectorvalues1\": ensure => file, mode => $mode1 }$/;\"\tresource\tline:43\tlanguage:PuppetManifest\ttyperef:typename:file\tend:43\n/tmp/selectorvalues2\tinput.pp\t/^file { \"\\/tmp\\/selectorvalues2\": ensure => file, mode => $mode2 }$/;\"\tresource\tline:44\tlanguage:PuppetManifest\ttyperef:typename:file\tend:44\n/tmp/selectorvalues3\tinput.pp\t/^file { \"\\/tmp\\/selectorvalues3\": ensure => file, mode => $mode3 }$/;\"\tresource\tline:45\tlanguage:PuppetManifest\ttyperef:typename:file\tend:45\n/tmp/selectorvalues4\tinput.pp\t/^file { \"\\/tmp\\/selectorvalues4\": ensure => file, mode => $mode4 }$/;\"\tresource\tline:46\tlanguage:PuppetManifest\ttyperef:typename:file\tend:46\n/tmp/selectorvalues5\tinput.pp\t/^file { \"\\/tmp\\/selectorvalues5\": ensure => file, mode => $mode5 }$/;\"\tresource\tline:47\tlanguage:PuppetManifest\ttyperef:typename:file\tend:47\n/tmp/selectorvalues6\tinput.pp\t/^file { \"\\/tmp\\/selectorvalues6\": ensure => file, mode => $mode6 }$/;\"\tresource\tline:48\tlanguage:PuppetManifest\ttyperef:typename:file\tend:48\n/tmp/selectorvalues7\tinput.pp\t/^file { \"\\/tmp\\/selectorvalues7\": ensure => file, mode => $mode7 }$/;\"\tresource\tline:49\tlanguage:PuppetManifest\ttyperef:typename:file\tend:49\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-selectorvalues.d/input.pp",
    "content": "$value1 = \"\"\n$value2 = true\n$value3 = false\n$value4 = yay\n\n$test = \"yay\"\n\n$mode1 = $value1 ? {\n    \"\" => \"755\",\n    default => \"644\"\n}\n\n$mode2 = $value2 ? {\n    true => \"755\",\n    default => \"644\"\n}\n\n$mode3 = $value3 ? {\n    false => \"755\",\n    default => \"644\"\n}\n\n$mode4 = $value4 ? {\n    $test => \"755\",\n    default => \"644\"\n}\n\n$mode5 = yay ? {\n    $test => \"755\",\n    default => \"644\"\n}\n\n$mode6 = $mode5 ? {\n    \"755\" => \"755\"\n}\n\n$mode7 = \"test regex\" ? {\n    /regex$/ => \"755\",\n    default => \"644\"\n}\n\n\nfile { \"/tmp/selectorvalues1\": ensure => file, mode => $mode1 }\nfile { \"/tmp/selectorvalues2\": ensure => file, mode => $mode2 }\nfile { \"/tmp/selectorvalues3\": ensure => file, mode => $mode3 }\nfile { \"/tmp/selectorvalues4\": ensure => file, mode => $mode4 }\nfile { \"/tmp/selectorvalues5\": ensure => file, mode => $mode5 }\nfile { \"/tmp/selectorvalues6\": ensure => file, mode => $mode6 }\nfile { \"/tmp/selectorvalues7\": ensure => file, mode => $mode7 }\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-simpledefaults.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-simpledefaults.d/expected.tags",
    "content": "/tmp/defaulttest\tinput.pp\t/^file { \"\\/tmp\\/defaulttest\": ensure => file }$/;\"\tresource\tline:5\tlanguage:PuppetManifest\ttyperef:typename:file\tend:5\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-simpledefaults.d/input.pp",
    "content": "# $Id$\n\nFile { mode => '0755' }\n\nfile { \"/tmp/defaulttest\": ensure => file }\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-simpleselector.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-simpleselector.d/expected.tags",
    "content": "var\tinput.pp\t/^$var = \"value\"$/;\"\tvariable\tline:3\tlanguage:PuppetManifest\n/tmp/snippetselectatest\tinput.pp\t/^file { \"\\/tmp\\/snippetselectatest\":$/;\"\tresource\tline:5\tlanguage:PuppetManifest\ttyperef:typename:file\tend:11\n/tmp/snippetselectbtest\tinput.pp\t/^file { \"\\/tmp\\/snippetselectbtest\":$/;\"\tresource\tline:13\tlanguage:PuppetManifest\ttyperef:typename:file\tend:19\nothervar\tinput.pp\t/^$othervar = \"complex value\"$/;\"\tvariable\tline:21\tlanguage:PuppetManifest\n/tmp/snippetselectctest\tinput.pp\t/^file { \"\\/tmp\\/snippetselectctest\":$/;\"\tresource\tline:23\tlanguage:PuppetManifest\ttyperef:typename:file\tend:29\nanothervar\tinput.pp\t/^$anothervar = \"Yayness\"$/;\"\tvariable\tline:30\tlanguage:PuppetManifest\n/tmp/snippetselectdtest\tinput.pp\t/^file { \"\\/tmp\\/snippetselectdtest\":$/;\"\tresource\tline:32\tlanguage:PuppetManifest\ttyperef:typename:file\tend:38\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-simpleselector.d/input.pp",
    "content": "# $Id$\n\n$var = \"value\"\n\nfile { \"/tmp/snippetselectatest\":\n    ensure => file,\n    mode => $var ? {\n        nottrue => \"641\",\n        value => \"755\"\n    }\n}\n\nfile { \"/tmp/snippetselectbtest\":\n    ensure => file,\n    mode => $var ? {\n        nottrue => \"644\",\n        default => \"755\"\n    }\n}\n\n$othervar = \"complex value\"\n\nfile { \"/tmp/snippetselectctest\":\n    ensure => file,\n    mode => $othervar ? {\n        \"complex value\" => \"755\",\n        default => \"644\"\n    }\n}\n$anothervar = \"Yayness\"\n\nfile { \"/tmp/snippetselectdtest\":\n    ensure => file,\n    mode => $anothervar ? {\n        \"Yayness\" => \"755\",\n        default => \"644\"\n    }\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-singleary.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-singleary.d/expected.tags",
    "content": "/tmp/singleary1\tinput.pp\t/^file { \"\\/tmp\\/singleary1\":$/;\"\tresource\tline:3\tlanguage:PuppetManifest\ttyperef:typename:file\tend:5\n/tmp/singleary2\tinput.pp\t/^file { \"\\/tmp\\/singleary2\":$/;\"\tresource\tline:7\tlanguage:PuppetManifest\ttyperef:typename:file\tend:9\n/tmp/singleary3\tinput.pp\t/^file { \"\\/tmp\\/singleary3\":$/;\"\tresource\tline:11\tlanguage:PuppetManifest\ttyperef:typename:file\tend:14\n/tmp/singleary4\tinput.pp\t/^file { \"\\/tmp\\/singleary4\":$/;\"\tresource\tline:16\tlanguage:PuppetManifest\ttyperef:typename:file\tend:19\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-singleary.d/input.pp",
    "content": "# $Id$\n\nfile { \"/tmp/singleary1\":\n    ensure => file\n}\n\nfile { \"/tmp/singleary2\":\n    ensure => file\n}\n\nfile { \"/tmp/singleary3\":\n    ensure => file,\n    require => [File[\"/tmp/singleary1\"], File[\"/tmp/singleary2\"]]\n}\n\nfile { \"/tmp/singleary4\":\n    ensure => file,\n    require => [File[\"/tmp/singleary1\"]]\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-singlequote.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-singlequote.d/expected.tags",
    "content": "/tmp/singlequote1\tinput.pp\t/^file { \"\\/tmp\\/singlequote1\":$/;\"\tresource\tline:3\tlanguage:PuppetManifest\ttyperef:typename:file\tend:6\n/tmp/singlequote2\tinput.pp\t/^file { \"\\/tmp\\/singlequote2\":$/;\"\tresource\tline:8\tlanguage:PuppetManifest\ttyperef:typename:file\tend:11\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-singlequote.d/input.pp",
    "content": "# $Id$\n\nfile { \"/tmp/singlequote1\":\n    ensure => file,\n    content => 'a $quote'\n}\n\nfile { \"/tmp/singlequote2\":\n    ensure => file,\n    content => 'some \"\\yayness\\\"'\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-singleselector.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-singleselector.d/expected.tags",
    "content": "value1\tinput.pp\t/^$value1 = \"\"$/;\"\tvariable\tline:1\tlanguage:PuppetManifest\nvalue2\tinput.pp\t/^$value2 = true$/;\"\tvariable\tline:2\tlanguage:PuppetManifest\nvalue3\tinput.pp\t/^$value3 = false$/;\"\tvariable\tline:3\tlanguage:PuppetManifest\nvalue4\tinput.pp\t/^$value4 = yay$/;\"\tvariable\tline:4\tlanguage:PuppetManifest\ntest\tinput.pp\t/^$test = \"yay\"$/;\"\tvariable\tline:6\tlanguage:PuppetManifest\nmode1\tinput.pp\t/^$mode1 = $value1 ? {$/;\"\tvariable\tline:8\tlanguage:PuppetManifest\nmode2\tinput.pp\t/^$mode2 = $value2 ? {$/;\"\tvariable\tline:12\tlanguage:PuppetManifest\nmode3\tinput.pp\t/^$mode3 = $value3 ? {$/;\"\tvariable\tline:16\tlanguage:PuppetManifest\n/tmp/singleselector1\tinput.pp\t/^file { \"\\/tmp\\/singleselector1\": ensure => file, mode => $mode1 }$/;\"\tresource\tline:20\tlanguage:PuppetManifest\ttyperef:typename:file\tend:20\n/tmp/singleselector2\tinput.pp\t/^file { \"\\/tmp\\/singleselector2\": ensure => file, mode => $mode2 }$/;\"\tresource\tline:21\tlanguage:PuppetManifest\ttyperef:typename:file\tend:21\n/tmp/singleselector3\tinput.pp\t/^file { \"\\/tmp\\/singleselector3\": ensure => file, mode => $mode3 }$/;\"\tresource\tline:22\tlanguage:PuppetManifest\ttyperef:typename:file\tend:22\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-singleselector.d/input.pp",
    "content": "$value1 = \"\"\n$value2 = true\n$value3 = false\n$value4 = yay\n\n$test = \"yay\"\n\n$mode1 = $value1 ? {\n    \"\" => \"755\"\n}\n\n$mode2 = $value2 ? {\n    true => \"755\"\n}\n\n$mode3 = $value3 ? {\n    default => \"755\"\n}\n\nfile { \"/tmp/singleselector1\": ensure => file, mode => $mode1 }\nfile { \"/tmp/singleselector2\": ensure => file, mode => $mode2 }\nfile { \"/tmp/singleselector3\": ensure => file, mode => $mode3 }\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-subclass_name_duplication.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-subclass_name_duplication.d/expected.tags",
    "content": "one::fake\tinput.pp\t/^class one::fake {$/;\"\tclass\tline:3\tlanguage:PuppetManifest\tend:5\n/tmp/subclass_name_duplication1\tinput.pp\t/^    file { \"\\/tmp\\/subclass_name_duplication1\": ensure => present }$/;\"\tresource\tline:4\tlanguage:PuppetManifest\tscope:class:::one::fake\ttyperef:typename:file\tend:4\ntwo::fake\tinput.pp\t/^class two::fake {$/;\"\tclass\tline:7\tlanguage:PuppetManifest\tend:9\n/tmp/subclass_name_duplication2\tinput.pp\t/^    file { \"\\/tmp\\/subclass_name_duplication2\": ensure => present }$/;\"\tresource\tline:8\tlanguage:PuppetManifest\tscope:class:::two::fake\ttyperef:typename:file\tend:8\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-subclass_name_duplication.d/input.pp",
    "content": "#!/usr/bin/env puppet\n\nclass one::fake {\n    file { \"/tmp/subclass_name_duplication1\": ensure => present }\n}\n\nclass two::fake {\n    file { \"/tmp/subclass_name_duplication2\": ensure => present }\n}\n\ninclude one::fake, two::fake\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-tag.b/README",
    "content": "This test case is a placeholder.\nI have not designed how ctags deals with tags of puppetManifest yet.\nSo I put only the input file here.\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-tag.b/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-tag.b/input.pp",
    "content": "# $Id$\n\n$variable = value\n\ntag yayness, rahness\n\ntag booness, $variable\n\nfile { \"/tmp/settestingness\": ensure => file }\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-tagged.b/README",
    "content": "This test case is a placeholder.\nI have not designed how ctags deals with tags of puppetManifest yet.\nSo I put only the input file here.\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-tagged.b/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-tagged.b/input.pp",
    "content": "# $Id$\n\ntag testing\ntag(funtest)\n\nclass tagdefine {\n    $path = tagged(tagdefine) ? {\n        true => \"true\", false => \"false\"\n    }\n\n    file { \"/tmp/taggeddefine$path\": ensure => file }\n}\n\ninclude tagdefine\n\n$yayness = tagged(yayness) ? {\n    true => \"true\", false => \"false\"\n}\n\n$funtest = tagged(testing) ? {\n    true => \"true\", false => \"false\"\n}\n\n$both = tagged(testing, yayness) ? {\n    true => \"true\", false => \"false\"\n}\n\n$bothtrue = tagged(testing, testing) ? {\n    true => \"true\", false => \"false\"\n}\n\nfile { \"/tmp/taggedyayness$yayness\": ensure => file }\nfile { \"/tmp/taggedtesting$funtest\": ensure => file }\nfile { \"/tmp/taggedboth$both\": ensure => file }\nfile { \"/tmp/taggedbothtrue$bothtrue\": ensure => file }\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-virtualresources.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-virtualresources.d/expected.tags",
    "content": "one\tinput.pp\t/^class one {$/;\"\tclass\tline:1\tlanguage:PuppetManifest\tend:6\n/tmp/virtualtest1\tinput.pp\t/^    @file { \"\\/tmp\\/virtualtest1\": content => \"one\" }$/;\"\tvresource\tline:2\tlanguage:PuppetManifest\tscope:class:::one\ttyperef:typename:file\tend:2\n/tmp/virtualtest2\tinput.pp\t/^    @file { \"\\/tmp\\/virtualtest2\": content => \"two\" }$/;\"\tvresource\tline:3\tlanguage:PuppetManifest\tscope:class:::one\ttyperef:typename:file\tend:3\n/tmp/virtualtest3\tinput.pp\t/^    @file { \"\\/tmp\\/virtualtest3\": content => \"three\" }$/;\"\tvresource\tline:4\tlanguage:PuppetManifest\tscope:class:::one\ttyperef:typename:file\tend:4\n/tmp/virtualtest4\tinput.pp\t/^    @file { \"\\/tmp\\/virtualtest4\": content => \"four\" }$/;\"\tvresource\tline:5\tlanguage:PuppetManifest\tscope:class:::one\ttyperef:typename:file\tend:5\ntwo\tinput.pp\t/^class two {$/;\"\tclass\tline:8\tlanguage:PuppetManifest\tend:12\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/puppet-virtualresources.d/input.pp",
    "content": "class one {\n    @file { \"/tmp/virtualtest1\": content => \"one\" }\n    @file { \"/tmp/virtualtest2\": content => \"two\" }\n    @file { \"/tmp/virtualtest3\": content => \"three\" }\n    @file { \"/tmp/virtualtest4\": content => \"four\" }\n}\n\nclass two {\n    File <| content == \"one\" |>\n    realize File[\"/tmp/virtualtest2\"]\n    realize(File[\"/tmp/virtualtest3\"], File[\"/tmp/virtualtest4\"])\n}\n\ninclude one, two\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/root-sep.d/args.ctags",
    "content": "--extras=+q\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/root-sep.d/expected.tags",
    "content": "/tmp/classheir1\tinput.pp\t/^   file { \"\\/tmp\\/classheir1\": ensure => file, mode => '0755' }$/;\"\tr\tclass:::base\ttyperef:typename:file\n::base\tinput.pp\t/^class base {$/;\"\tc\n::base::/tmp/classheir1\tinput.pp\t/^   file { \"\\/tmp\\/classheir1\": ensure => file, mode => '0755' }$/;\"\tr\tclass:::base\ttyperef:typename:file\nbase\tinput.pp\t/^class base {$/;\"\tc\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/root-sep.d/input.pp",
    "content": "class base {\n   file { \"/tmp/classheir1\": ensure => file, mode => '0755' }\n}\n\ninclude base\n\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/typealias.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/typealias.d/expected.tags",
    "content": "MyModule::Tree\tinput.pp\t/^type MyModule::Tree = Array[Variant[Data, Tree]]$/;\"\tt\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/typealias.d/input.pp",
    "content": "type MyModule::Tree = Array[Variant[Data, Tree]]\n\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/unless.d/args.ctags",
    "content": "--sort=no\n--fields=+KZlne\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/unless.d/expected.tags",
    "content": "array\tinput.pp\t/^$array = [ 3, 5, 7 ]$/;\"\tvariable\tline:1\tlanguage:PuppetManifest\n/tmp/x\tinput.pp\t/^       file { \"\\/tmp\\/x\": }$/;\"\tresource\tline:3\tlanguage:PuppetManifest\ttyperef:typename:file\tend:3\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/unless.d/input.pp",
    "content": "$array = [ 3, 5, 7 ]\nunless $array[0] > 5 {\n       file { \"/tmp/x\": }\n}\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/validator",
    "content": "puppet\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/varname.d/expected.tags",
    "content": "_msg\tinput.pp\t/^$_msg = 'hello, world!'$/;\"\tv\nhelloworld\tinput.pp\t/^class helloworld {$/;\"\tc\n"
  },
  {
    "path": "Units/parser-puppetManifest.r/varname.d/input.pp",
    "content": "$_msg = 'hello, world!'\nclass helloworld {\n    notify { $::_msg: }\n}\n"
  },
  {
    "path": "Units/parser-python.r/async.d/args.ctags",
    "content": "--sort=no\n--fields-python=+{decorators}\n"
  },
  {
    "path": "Units/parser-python.r/async.d/expected.tags",
    "content": "read_data\tinput.py\t/^async def read_data(db):$/;\"\tf\ncommit\tinput.py\t/^async def commit(session, data):$/;\"\tf\nCursor\tinput.py\t/^class Cursor:$/;\"\tc\n__init__\tinput.py\t/^    def __init__(self):$/;\"\tm\tclass:Cursor\n_prefetch\tinput.py\t/^    async def _prefetch(self):$/;\"\tm\tclass:Cursor\n__aiter__\tinput.py\t/^    def __aiter__(self):$/;\"\tm\tclass:Cursor\n__anext__\tinput.py\t/^    async def __anext__(self):$/;\"\tm\tclass:Cursor\nAsyncIteratorWrapper\tinput.py\t/^class AsyncIteratorWrapper:$/;\"\tc\n__init__\tinput.py\t/^    def __init__(self, obj):$/;\"\tm\tclass:AsyncIteratorWrapper\n__aiter__\tinput.py\t/^    def __aiter__(self):$/;\"\tm\tclass:AsyncIteratorWrapper\n__anext__\tinput.py\t/^    async def __anext__(self):$/;\"\tm\tclass:AsyncIteratorWrapper\nticker\tinput.py\t/^async def ticker(delay, to):$/;\"\tf\nTestDecorators\tinput.py\t/^class TestDecorators:$/;\"\tc\nsimplestuff\tinput.py\t/^    def simplestuff():$/;\"\tm\tclass:TestDecorators\tdecorators:staticmethod\nsomething\tinput.py\t/^    async def something(other):$/;\"\tm\tclass:TestDecorators\tdecorators:staticmethod\n"
  },
  {
    "path": "Units/parser-python.r/async.d/input.py",
    "content": "# https://www.python.org/dev/peps/pep-0492/\n\nasync def read_data(db):\n    pass\n\nasync def commit(session, data):\n    # ...\n\n    async with session.transaction():\n        # ...\n        await session.update(data)\n        # ...\n\nclass Cursor:\n    def __init__(self):\n        self.buffer = collections.deque()\n\n    async def _prefetch(self):\n        # ...\n        pass\n\n    def __aiter__(self):\n        return self\n\n    async def __anext__(self):\n        if not self.buffer:\n            self.buffer = await self._prefetch()\n            if not self.buffer:\n                raise StopAsyncIteration\n        return self.buffer.popleft()\n\nclass AsyncIteratorWrapper:\n    def __init__(self, obj):\n        self._it = iter(obj)\n\n    def __aiter__(self):\n        return self\n\n    async def __anext__(self):\n        try:\n            value = next(self._it)\n        except StopIteration:\n            raise StopAsyncIteration\n        return value\n\nasync for letter in AsyncIteratorWrapper(\"abc\"):\n    print(letter)\n\n# async generator from https://www.python.org/dev/peps/pep-0525/\nasync def ticker(delay, to):\n    \"\"\"Yield numbers from 0 to `to` every `delay` seconds.\"\"\"\n    for i in range(to):\n        yield i\n        await asyncio.sleep(delay)\n\n# check it doesn't affect decorators parsing\nclass TestDecorators:\n    @staticmethod\n    def simplestuff():\n        pass\n\n    @staticmethod\n    async def something(other):\n        await other\n"
  },
  {
    "path": "Units/parser-python.r/blanks.d/expected.tags",
    "content": "Bar\tinput.py\t/^class Bar:$/;\"\tc\nFoo\tinput.py\t/^class Foo:$/;\"\tc\nd1\tinput.py\t/^\tdef d1(): pass$/;\"\tm\tclass:Foo\nd2\tinput.py\t/^        def d2(): pass$/;\"\tm\tclass:Foo\nd3\tinput.py\t/^ \tdef d3(): pass$/;\"\tm\tclass:Foo\nd4\tinput.py\t/^        def d4(): pass$/;\"\tm\tclass:Foo\nd5\tinput.py\t/^    \f    def d5(): pass$/;\"\tm\tclass:Bar\nd6\tinput.py\t/^    def d6(): pass$/;\"\tm\tclass:Bar\nd7\tinput.py\t/^    def d7():$/;\"\tm\tclass:Bar\nd8\tinput.py\t/^    \f    def d8(): pass$/;\"\tm\tclass:Bar\n"
  },
  {
    "path": "Units/parser-python.r/blanks.d/input.py",
    "content": "\nclass Foo:\n\tdef d1(): pass\n        def d2(): pass\n \tdef d3(): pass\n\n        def d4(): pass\n\nclass Bar:\n    \f    def d5(): pass\n    def d6(): pass\n    \n    def d7():\n        pass\n    \f    def d8(): pass\n\n\nprint(Foo.d1)\nprint(Foo.d2)\nprint(Foo.d3)\nprint(Foo.d4)\nprint(Bar.d5)\nprint(Bar.d6)\nprint(Bar.d7)\nprint(Bar.d8)\n"
  },
  {
    "path": "Units/parser-python.r/bug1764148.d/args.ctags",
    "content": "--guess-language-eagerly"
  },
  {
    "path": "Units/parser-python.r/bug1764148.d/expected.tags",
    "content": "PyFunc\tinput.bug1764148\t/^def PyFunc(msg): print msg$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/bug1764148.d/input.bug1764148",
    "content": "#!/usr/bin/python\ndef PyFunc(msg): print msg\n"
  },
  {
    "path": "Units/parser-python.r/bug1809024.py.d/expected.tags",
    "content": "detach\tinput.py\t/^def detach (self):$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/bug1809024.py.d/input.py",
    "content": "def detach (self):\n\n     model = self.view.props.model\n     sort_id, sort_order = tree_sortable_get_sort_column_id (model)\n     if sort_id >= 0:\n         self.app.state.sort_column = self.find_item_class (id = sort_id)\n         if sort_order == gtk.SORT_ASCENDING:\n             self.app.state.sort_order = \"ascending\"\n         else:\n             self.app.state.sort_order = \"descending\"\n"
  },
  {
    "path": "Units/parser-python.r/bug1856363.py.d/expected.tags",
    "content": "main\tinput.py\t/^def main():$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/bug1856363.py.d/input.py",
    "content": "#!/usr/bin/python\n\ndef main():\n\t# A broken ctags will see a function \"initely_not_a_function\" here.\n\tdefinitely_not_a_function = 0\n\treturn\n\nif __name__ == 'main':\n\tmain()\n"
  },
  {
    "path": "Units/parser-python.r/bug1906062.py.d/expected.tags",
    "content": "include_file\tinput.py\t/^include_file = '''$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/bug1906062.py.d/input.py",
    "content": "include_file = '''\nclass (b)\n'''\n\n"
  },
  {
    "path": "Units/parser-python.r/bug1988026.py.d/expected.tags",
    "content": "im_a_function\tinput.py\t/^\tdef im_a_function():$/;\"\tf\nmain\tinput.py\t/^    def main():$/;\"\tm\tclass:testClass\nmy_var\tinput.py\t/^    my_var = 0$/;\"\tv\tclass:testClass\ntestClass\tinput.py\t/^class testClass:$/;\"\tc\n"
  },
  {
    "path": "Units/parser-python.r/bug1988026.py.d/input.py",
    "content": "\nclass testClass:\n    my_var = 0\n    def main():\n        pass\n\nif __name__ == '__main__': testClass.main()\n\tdef im_a_function():\n\t    pass\n"
  },
  {
    "path": "Units/parser-python.r/bug1988027.py.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-python.r/bug1988027.py.d/input.py",
    "content": "#!/usr/bin/env python\n# encoding: utf-8\n\n\n\"\"\"\nbla\n#\"\"\"\n\n\"\"\"make a tarball with all the sources in it; return (distdirname, tarballname)\"\"\"\n"
  },
  {
    "path": "Units/parser-python.r/bug1988130.py.d/expected.tags",
    "content": "main\tinput.py\t/^def main():$/;\"\tf\ntestFunc\tinput.py\t/^def testFunc():$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/bug1988130.py.d/input.py",
    "content": "def testFunc():\n    print 'The following works now' + '\"\"\"'\n\ndef main():\n    print 'nothing'\n    print 'This is another quoted triple string: \"\"\".'\n    return 0\n"
  },
  {
    "path": "Units/parser-python.r/bug2075402.py.d/expected.tags",
    "content": "x\tinput.py\t/^x = 2$/;\"\tv\ny\tinput.py\t/^y = 1 # \"\"\"$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/bug2075402.py.d/input.py",
    "content": "y = 1 # \"\"\"\nx = 2\n"
  },
  {
    "path": "Units/parser-python.r/bug3168705.py.d/expected.tags",
    "content": "A\tinput.py\t/^class A:$/;\"\tc\nfunc1\tinput.py\t/^    def func1():$/;\"\tm\tclass:A\nfunc2\tinput.py\t/^    def func2():$/;\"\tm\tclass:A\n"
  },
  {
    "path": "Units/parser-python.r/bug3168705.py.d/input.py",
    "content": "class A:\n    def func1():\n        \"\"\"this is\na comment\"\"\"\n        pass\n\n    def func2():\n        pass\n\n"
  },
  {
    "path": "Units/parser-python.r/bug699171.py.d/expected.tags",
    "content": "HEADER_TEMPLATE\tinput.py\t/^HEADER_TEMPLATE = {$/;\"\tv\nQuit\tinput.py\t/^def Quit(msg, exitcode=0): print msg ; sys.exit(exitcode)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/bug699171.py.d/input.py",
    "content": "# Test for Bug #699171.\n# Extracted from http://txt2tags.sourceforge.net/src/txt2tags-1.4.tar.gz\n\nHEADER_TEMPLATE = {\nr\"\"\"Multiline raw string\n\"\"\"\n}\ndef Quit(msg, exitcode=0): print msg ; sys.exit(exitcode)\n"
  },
  {
    "path": "Units/parser-python.r/cython-external.d/args.ctags",
    "content": "--sort=no\n--fields=+St\n--kinds-Python=+z\n"
  },
  {
    "path": "Units/parser-python.r/cython-external.d/expected.tags",
    "content": "order_spam1\tinput.pyx\t/^cdef extern void order_spam1(int tons)$/;\"\tf\tsignature:(int tons)\ntons\tinput.pyx\t/^cdef extern void order_spam1(int tons)$/;\"\tz\tfunction:order_spam1\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-python.r/cython-external.d/input.pyx",
    "content": "\ncdef extern void order_spam1(int tons)\n\n# we ignore those ATM\ncdef extern from \"spam.h\":\n    void order_spam2(int tons)\n\ncdef import from \"spam.h\":\n    void order_spam3(int tons)\n"
  },
  {
    "path": "Units/parser-python.r/cython_sample.pyx.d/args.ctags",
    "content": "--sort=no\n--fields=+St\n--kinds-Python=+z\n"
  },
  {
    "path": "Units/parser-python.r/cython_sample.pyx.d/expected.tags",
    "content": "python_var\tinput.pyx\t/^python_var = 1$/;\"\tv\nint_identity\tinput.pyx\t/^cdef int int_identity(int i) : return i  $/;\"\tf\tsignature:(int i)\ni\tinput.pyx\t/^cdef int int_identity(int i) : return i  $/;\"\tz\tfunction:int_identity\ttyperef:typename:int\tfile:\nint_identity2\tinput.pyx\t/^cdef (int) int_identity2(int i) : return i$/;\"\tf\tsignature:(int i)\ni\tinput.pyx\t/^cdef (int) int_identity2(int i) : return i$/;\"\tz\tfunction:int_identity2\ttyperef:typename:int\tfile:\nint_identity3\tinput.pyx\t/^cdef inline int int_identity3(int i) : return i$/;\"\tf\tsignature:(int i)\ni\tinput.pyx\t/^cdef inline int int_identity3(int i) : return i$/;\"\tz\tfunction:int_identity3\ttyperef:typename:int\tfile:\nint_identity4\tinput.pyx\t/^cdef inline (int) int_identity4(int i) : return i$/;\"\tf\tsignature:(int i)\ni\tinput.pyx\t/^cdef inline (int) int_identity4(int i) : return i$/;\"\tz\tfunction:int_identity4\ttyperef:typename:int\tfile:\nint2string\tinput.pyx\t/^cdef object int2string(int i) :$/;\"\tf\tsignature:(int i)\ni\tinput.pyx\t/^cdef object int2string(int i) :$/;\"\tz\tfunction:int2string\ttyperef:typename:int\tfile:\nCDefClass\tinput.pyx\t/^cdef class CDefClass :$/;\"\tc\n__init__\tinput.pyx\t/^    def __init__(self) :$/;\"\tm\tclass:CDefClass\tsignature:(self)\nself\tinput.pyx\t/^    def __init__(self) :$/;\"\tz\tmember:CDefClass.__init__\tfile:\nstandard_method\tinput.pyx\t/^    def standard_method(self,i) :$/;\"\tm\tclass:CDefClass\tsignature:(self,i)\nself\tinput.pyx\t/^    def standard_method(self,i) :$/;\"\tz\tmember:CDefClass.standard_method\tfile:\ni\tinput.pyx\t/^    def standard_method(self,i) :$/;\"\tz\tmember:CDefClass.standard_method\tfile:\nc_method\tinput.pyx\t/^    cdef int c_method(self,int i) :$/;\"\tm\tclass:CDefClass\tsignature:(self, int i)\nself\tinput.pyx\t/^    cdef int c_method(self,int i) :$/;\"\tz\tmember:CDefClass.c_method\tfile:\ni\tinput.pyx\t/^    cdef int c_method(self,int i) :$/;\"\tz\tmember:CDefClass.c_method\ttyperef:typename:int\tfile:\nidentity\tinput.pyx\t/^def identity(x) :$/;\"\tf\tsignature:(x)\nx\tinput.pyx\t/^def identity(x) :$/;\"\tz\tfunction:identity\tfile:\nStdClass\tinput.pyx\t/^class StdClass :$/;\"\tc\nreturn_me\tinput.pyx\t/^    def return_me(self) :$/;\"\tm\tclass:StdClass\tsignature:(self)\nself\tinput.pyx\t/^    def return_me(self) :$/;\"\tz\tmember:StdClass.return_me\tfile:\nstdObj\tinput.pyx\t/^stdObj  = StdClass()$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/cython_sample.pyx.d/input.pyx",
    "content": "#  -*- cython-mode -*-\n# test code for python/cython functionality\n\npython_var = 1\n\ncdef int i = 2   # cython identifiers are not indexed\ncdef :\n    int j = 3\ncdef k = 4 # no type here\n\ncdef int int_identity(int i) : return i  \ncdef (int) int_identity2(int i) : return i\ncdef inline int int_identity3(int i) : return i\ncdef inline (int) int_identity4(int i) : return i\n\n# here is a long one\ncdef object int2string(int i) :\n    return str(i)\n\n# a cdef class\ncdef class CDefClass :\n    def __init__(self) :\n        pass\n    def standard_method(self,i) :\n        return i\n    cdef int c_method(self,int i) :\n        return i\n\n# a python function\ndef identity(x) :\n    return x\n\n# a python class\nclass StdClass :\n    def return_me(self) :\n        return \"me\"\n\ncdef CDefClass cdefObj = CDefClass()\nstdObj  = StdClass()\n\nprint \"cython_sample: testing to make sure this file compiles and runs...\"\nprint \"i is: \", i\nprint \"j is: \", j\nprint \"i via identity: \", int_identity(i)\nprint \"i via int2string: \", int2string(i)\nprint \"cdefObj: \", cdefObj.c_method(i)\nprint \"k via py identity\", identity(k)\nprint \"py method call:\", stdObj.return_me()\n\n"
  },
  {
    "path": "Units/parser-python.r/cython_sample2.d/args.ctags",
    "content": "--fields=ksSt\n--kinds-Python=+z\n--extras=+r\n--sort=no\n"
  },
  {
    "path": "Units/parser-python.r/cython_sample2.d/expected.tags",
    "content": "numpy\tinput.pyx\t/^import numpy as np$/;\"\ti\nnp\tinput.pyx\t/^import numpy as np$/;\"\tI\tnameref:module:numpy\nnumpy\tinput.pyx\t/^cimport numpy as np$/;\"\ti\nnp\tinput.pyx\t/^cimport numpy as np$/;\"\tI\tnameref:module:numpy\nmy_fun\tinput.pyx\t/^cpdef np.ndarray[dtype=double, ndim=1] my_fun(np.ndarray[dtype=double, ndim=1] x):$/;\"\tf\tsignature:(np.ndarray[dtype=double, ndim=1] x)\nx\tinput.pyx\t/^cpdef np.ndarray[dtype=double, ndim=1] my_fun(np.ndarray[dtype=double, ndim=1] x):$/;\"\tz\tfunction:my_fun\ttyperef:typename:np.ndarray[dtype=double, ndim=1]\n"
  },
  {
    "path": "Units/parser-python.r/cython_sample2.d/input.pyx",
    "content": "#  -*- cython-mode -*-\n# test code for cython functionality with complex datatypes\n\nimport numpy as np\ncimport numpy as np\n\ncpdef np.ndarray[dtype=double, ndim=1] my_fun(np.ndarray[dtype=double, ndim=1] x):\n    cdef np.ndarray[dtype=double, ndim=1, mode=\"c\"] res\n\n    res = 2*x\n    return res\n"
  },
  {
    "path": "Units/parser-python.r/dotted-variable-leftovers.d/expected.tags",
    "content": "X\tinput.py\t/^class X(list):$/;\"\tc\na\tinput.py\t/^a, x.a = x$/;\"\tv\nx\tinput.py\t/^x = X()$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/dotted-variable-leftovers.d/input.py",
    "content": "class X(list):\n    pass\n\nx = X()\nx.append(1)\nx.append(2)\n\na, x.a = x\n"
  },
  {
    "path": "Units/parser-python.r/f-strings.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-python.r/f-strings.d/expected.tags",
    "content": "extra\tinput.py\t/^extra = f'{extra},waiters:{len(self._waiters)}'$/;\"\tv\nmethoddef_name\tinput.py\t/^methoddef_name = f\"{c_basename.upper()}_METHODDEF\"$/;\"\tv\nzzz\tinput.py\t/^zzz = 1$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/f-strings.d/input.py",
    "content": "# https://www.python.org/dev/peps/pep-0498/\n\nextra = f'{extra},waiters:{len(self._waiters)}'\n\nmessage.append(f\" [line {lineno:2d}]\")\n\nmethoddef_name = f\"{c_basename.upper()}_METHODDEF\"\n\nprint(f\"Usage: {sys.argv[0]} [{'|'.join('--'+opt for opt in valid_opts)}]\", file=sys.stderr)\n\n# check if nothing messed up parsing\nzzz = 1\n"
  },
  {
    "path": "Units/parser-python.r/matrix-multiplication-operator.d/args.ctags",
    "content": "--sort=no\n--fields-python=+{decorators}\n"
  },
  {
    "path": "Units/parser-python.r/matrix-multiplication-operator.d/expected.tags",
    "content": "np\tinput.py\t/^import numpy as np$/;\"\tI\tnameref:module:numpy\ndotFunc\tinput.py\t/^def dotFunc():$/;\"\tf\tdecorators:something\ndotMethod\tinput.py\t/^def dotMethod():$/;\"\tf\tdecorators:something\natOpv1\tinput.py\t/^def atOpv1():$/;\"\tf\tdecorators:something\natOpv2\tinput.py\t/^def atOpv2():$/;\"\tf\natOpv3\tinput.py\t/^def atOpv3():$/;\"\tf\tdecorators:something\n"
  },
  {
    "path": "Units/parser-python.r/matrix-multiplication-operator.d/input.py",
    "content": "# https://www.python.org/dev/peps/pep-0465/\n\nimport numpy as np\nfrom numpy.linalg import inv, solve\n\n@something\ndef dotFunc():\n    # Using dot function:\n    S = np.dot((np.dot(H, beta) - r).T,\n               np.dot(inv(np.dot(np.dot(H, V), H.T)), np.dot(H, beta) - r))\n\n@something\ndef dotMethod():\n    # Using dot method:\n    S = (H.dot(beta) - r).T.dot(inv(H.dot(V).dot(H.T))).dot(H.dot(beta) - r)\n\n@something\ndef atOpv1():\n    # Version 1\n    S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r)\n\ndef atOpv2():\n    # Version 2\n    trans_coef = H @ beta - r\n    S = trans_coef.T @ inv(H @ V @ H.T) @ trans_coef\n\n@something\ndef atOpv3():\n    # Version 3\n    S = trans_coef.T @ solve(H @ V @ H.T, trans_coef)\n"
  },
  {
    "path": "Units/parser-python.r/multiline-arglist.d/args.ctags",
    "content": "--fields=+S\n--sort=no\n"
  },
  {
    "path": "Units/parser-python.r/multiline-arglist.d/expected.tags",
    "content": "f\tinput.py\t/^def f ($/;\"\tf\tsignature:( a)\ng\tinput.py\t/^def g ($/;\"\tf\tsignature:( a = 3)\nx\tinput.py\t/^x = {$/;\"\tv\nz\tinput.py\t/^z = [$/;\"\tv\nFoo\tinput.py\t/^class Foo(object):$/;\"\tc\nbar\tinput.py\t/^    def bar(self,$/;\"\tm\tclass:Foo\tsignature:(self, default=None)\nbaz\tinput.py\t/^    baz = dict($/;\"\tv\tclass:Foo\nvariable\tinput.py\t/^variable = dict($/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/multiline-arglist.d/input.py",
    "content": "def f (\n        # IGNORE THIS COMMENT\n        a):\n    pass\ndef g (\n        # IGNORE THIS COMMENT\n        a = 3):\n    pass\n\nx = {\n    'y': 1\n}\n\nz = [\n    x\n]\n\n# https://github.com/universal-ctags/ctags/issues/750#issuecomment-169002893\n# Reported by @strokirk\nclass Foo(object):\n    def bar(self,\n            default=None):\n        pass\n    baz = dict(\n        argument=None,\n    )\n\nvariable = dict(\n    keyword=None,\n)\n"
  },
  {
    "path": "Units/parser-python.r/multiline-class-def.d/expected.tags",
    "content": "A\tinput.py\t/^class A(Foo,$/;\"\tc\nB\tinput.py\t/^class B():$/;\"\tc\na\tinput.py\t/^    a = 1$/;\"\tv\tclass:A\nb\tinput.py\t/^    b = 2$/;\"\tv\tclass:B\n"
  },
  {
    "path": "Units/parser-python.r/multiline-class-def.d/input.py",
    "content": "class A(Foo,\n        Bar):\n    a = 1\n\nclass B():\n    b = 2\n"
  },
  {
    "path": "Units/parser-python.r/multiline-def.d/expected.tags",
    "content": "x\tinput.py\t/^x=\\\\$/;\"\tv\ny\tinput.py\t/^y()\\\\$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/multiline-def.d/input.py",
    "content": "x=\\\n1\ndef \\\ny()\\\n:\n\tpass\n"
  },
  {
    "path": "Units/parser-python.r/nested-parenthesis.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-python.r/nested-parenthesis.d/expected.tags",
    "content": "foo\tinput.py\t/^def foo():$/;\"\tf\tsignature:()\nbar\tinput.py\t/^def bar():$/;\"\tf\tsignature:()\nbaz\tinput.py\t/^def baz(arg1, arg2=({()})):$/;\"\tf\tsignature:(arg1, arg2=({()}))\ngvar\tinput.py\t/^gvar = test(())$/;\"\tv\ntagme\tinput.py\t/^def tagme():$/;\"\tf\tsignature:()\n"
  },
  {
    "path": "Units/parser-python.r/nested-parenthesis.d/input.py",
    "content": "# Reported by @m-novikov in #763\ndef foo():\n    var = some1(some2())\n\ndef bar():\n    pass\n\ndef baz(arg1, arg2=({()})):\n    pass\n\ngvar = test(())\n\n\ndef tagme():\n    pass\n\n"
  },
  {
    "path": "Units/parser-python.r/newlines-cr.b/README",
    "content": "Tags are right, but location are not recorded correctly.\nLikely due to a bug in main part line number recording with CRs alone.\n"
  },
  {
    "path": "Units/parser-python.r/newlines-cr.b/expected.tags",
    "content": "Cls\tinput.py\t/^class Cls:$/;\"\tc\n__init__\tinput.py\t/^    def __init__():$/;\"\tm\tclass:Cls\nbar\tinput.py\t/^bar():$/;\"\tf\nfoo\tinput.py\t/^def foo():$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/newlines-cr.b/input.py",
    "content": "\rdef foo():\r    pass\r\rdef \\\rbar():\r    \"\"\" nothing to see here \"\"\"\r    pass\r\rclass Cls:\r    def __init__():\r        \"\"\" class constructor \"\"\"\r        pass\r"
  },
  {
    "path": "Units/parser-python.r/newlines-crlf.d/expected.tags",
    "content": "Cls\tinput.py\t/^class Cls:$/;\"\tc\n__init__\tinput.py\t/^    def __init__():$/;\"\tm\tclass:Cls\nbar\tinput.py\t/^bar():$/;\"\tf\nfoo\tinput.py\t/^def foo():$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/newlines-crlf.d/input.py",
    "content": "\r\ndef foo():\r\n    pass\r\n\r\ndef \\\r\nbar():\r\n    \"\"\" nothing to see here \"\"\"\r\n    pass\r\n\r\nclass Cls:\r\n    def __init__():\r\n        \"\"\" class constructor \"\"\"\r\n        pass\r\n"
  },
  {
    "path": "Units/parser-python.r/pep604-bar-operator-for-union.d/args.ctags",
    "content": "--sort=no\n--kinds-Python=+z\n"
  },
  {
    "path": "Units/parser-python.r/pep604-bar-operator-for-union.d/expected.tags",
    "content": "v\tinput.py\t/^v: float | str = 'a'$/;\"\tv\ttyperef:typename:float|str\nf\tinput.py\t/^def f(list: List[int|str], param: int | None) -> float|str:$/;\"\tf\ttyperef:typename:float|str\nlist\tinput.py\t/^def f(list: List[int|str], param: int | None) -> float|str:$/;\"\tz\tfunction:f\ttyperef:typename:List[int|str]\tfile:\nparam\tinput.py\t/^def f(list: List[int|str], param: int | None) -> float|str:$/;\"\tz\tfunction:f\ttyperef:typename:int|None\tfile:\n"
  },
  {
    "path": "Units/parser-python.r/pep604-bar-operator-for-union.d/input.py",
    "content": "from typing import List, Union\nv: float | str = 'a'\n\n# Taken from https://www.python.org/dev/peps/pep-0604/\ndef f(list: List[int|str], param: int | None) -> float|str:\n    pass\n"
  },
  {
    "path": "Units/parser-python.r/py-skipped-string.d/expected.tags",
    "content": "f1\tinput.py\t/^def f1():$/;\"\tf\nf2\tinput.py\t/^def f2():$/;\"\tf\nf3\tinput.py\t/^def f3():$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/py-skipped-string.d/input.py",
    "content": "# triple start string immediately after a normal string not detected\n\ndef f1():\n    ''\"\"\"\n    The string above was not detected as triple start string,\n    but the one below instead.\n    \"\"\"\n    print \"f1\"\n\ndef f2():\n    ''\"\"\"\n    The string above was then detected as end string,\n    and the one below as start string again.\n    \"\"\"\n    print \"f2\"\n\ndef f3():\n    \"\"\"\n    The string below is prepared so that ctags with the bug does not start a\n    new triple string. For a clean precondition for the next test.\n    ''\"\"\"\n    print \"f3\"\n\n# normal string immediately after a normal string not detected\n\n''\" import os\\\n\"\n\n\"\"' def fX():\\\n'\n"
  },
  {
    "path": "Units/parser-python.r/python-access.d/args.ctags",
    "content": "--fields=aks\n"
  },
  {
    "path": "Units/parser-python.r/python-access.d/expected.tags",
    "content": "C\tinput.py\t/^class C:$/;\"\tc\taccess:public\nClassesToo\tinput.py\t/^    class ClassesToo:$/;\"\tc\tfunction:_and_again\taccess:private\n_CONST1\tinput.py\t/^_CONST1 = 42$/;\"\tv\taccess:protected\n_ForReal\tinput.py\t/^    class _ForReal:$/;\"\tc\tfunction:_and_again\taccess:private\n_NotAutoImported\tinput.py\t/^class _NotAutoImported:$/;\"\tc\taccess:protected\n__CONST2\tinput.py\t/^__CONST2 = 43$/;\"\tv\taccess:protected\n__Cpriv\tinput.py\t/^    class __Cpriv:$/;\"\tc\tclass:C\taccess:private\n__JustTheSame\tinput.py\t/^class __JustTheSame:$/;\"\tc\taccess:protected\n__bar\tinput.py\t/^    def __bar(self):$/;\"\tm\tclass:C\taccess:private\n__init__\tinput.py\t/^    def __init__(self):$/;\"\tm\tclass:C\taccess:public\n__repr__\tinput.py\t/^    def __repr__(self):$/;\"\tm\tclass:C\taccess:public\n__still_the_same\tinput.py\t/^def __still_the_same():$/;\"\tf\taccess:protected\n_and_again\tinput.py\t/^def _and_again():$/;\"\tf\taccess:protected\n_even_with_underscore\tinput.py\t/^    def _even_with_underscore():$/;\"\tf\tfunction:_and_again\taccess:private\n_foo\tinput.py\t/^    def _foo(self):$/;\"\tm\tclass:C\taccess:protected\nbaz\tinput.py\t/^    def baz(self):$/;\"\tm\tclass:C\taccess:public\nbut_thankfully_im_pulic\tinput.py\t/^def but_thankfully_im_pulic():$/;\"\tf\taccess:public\nsub_is_private\tinput.py\t/^    def sub_is_private():$/;\"\tf\tfunction:_and_again\taccess:private\n"
  },
  {
    "path": "Units/parser-python.r/python-access.d/input.py",
    "content": "\n_CONST1 = 42\n__CONST2 = 43\n\nclass _NotAutoImported:\n    pass\n\nclass __JustTheSame:\n    pass\n\ndef _and_again():\n    def sub_is_private():\n        pass\n    def _even_with_underscore():\n        pass\n    class ClassesToo:\n        pass\n    class _ForReal:\n        pass\n    pass\n\ndef __still_the_same():\n    pass\n\ndef but_thankfully_im_pulic():\n    pass\n\nclass C:\n    def __init__(self):\n        pass\n\n    def __repr__(self):\n        return 'C'\n\n    def _foo(self):\n        pass\n\n    def __bar(self):\n        pass\n\n    def baz(self):\n        pass\n\n    class __Cpriv:\n        pass\n"
  },
  {
    "path": "Units/parser-python.r/python-anonymous-nestlevel_ctags-bug-356.d/expected.tags",
    "content": "Testclass\tinput.py\t/^class Testclass():$/;\"\tc\nmain\tinput.py\t/^    def main(self):$/;\"\tm\tclass:Testclass\nmodule_level_attribute\tinput.py\t/^    module_level_attribute = True$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/python-anonymous-nestlevel_ctags-bug-356.d/input.py",
    "content": "class Testclass():\n    def main(self):\n        variable = True\n\nif __name__ == \"__main__\":\n    module_level_attribute = True\n"
  },
  {
    "path": "Units/parser-python.r/python-arguments.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--kinds-python=+z\n"
  },
  {
    "path": "Units/parser-python.r/python-arguments.d/expected.tags",
    "content": "func1\tinput.py\t/^def func1():$/;\"\tf\nfunc2\tinput.py\t/^def func2(arg1):$/;\"\tf\narg1\tinput.py\t/^def func2(arg1):$/;\"\tz\tfunction:func2\tfile:\nfunc2.arg1\tinput.py\t/^def func2(arg1):$/;\"\tz\tfunction:func2\tfile:\nfunc3\tinput.py\t/^def func3(arg1, arg2):$/;\"\tf\narg1\tinput.py\t/^def func3(arg1, arg2):$/;\"\tz\tfunction:func3\tfile:\nfunc3.arg1\tinput.py\t/^def func3(arg1, arg2):$/;\"\tz\tfunction:func3\tfile:\narg2\tinput.py\t/^def func3(arg1, arg2):$/;\"\tz\tfunction:func3\tfile:\nfunc3.arg2\tinput.py\t/^def func3(arg1, arg2):$/;\"\tz\tfunction:func3\tfile:\nfunc4\tinput.py\t/^def func4( arg1 ,$/;\"\tf\narg1\tinput.py\t/^def func4( arg1 ,$/;\"\tz\tfunction:func4\tfile:\nfunc4.arg1\tinput.py\t/^def func4( arg1 ,$/;\"\tz\tfunction:func4\tfile:\narg2\tinput.py\t/^           arg2 ,$/;\"\tz\tfunction:func4\tfile:\nfunc4.arg2\tinput.py\t/^           arg2 ,$/;\"\tz\tfunction:func4\tfile:\narg3\tinput.py\t/^           arg3 ):$/;\"\tz\tfunction:func4\tfile:\nfunc4.arg3\tinput.py\t/^           arg3 ):$/;\"\tz\tfunction:func4\tfile:\nfunc5\tinput.py\t/^def func5( arg1 = 1,$/;\"\tf\narg1\tinput.py\t/^def func5( arg1 = 1,$/;\"\tz\tfunction:func5\tfile:\nfunc5.arg1\tinput.py\t/^def func5( arg1 = 1,$/;\"\tz\tfunction:func5\tfile:\narg2\tinput.py\t/^           arg2 = r'hello',$/;\"\tz\tfunction:func5\tfile:\nfunc5.arg2\tinput.py\t/^           arg2 = r'hello',$/;\"\tz\tfunction:func5\tfile:\narg3\tinput.py\t/^           arg3 = None):$/;\"\tz\tfunction:func5\tfile:\nfunc5.arg3\tinput.py\t/^           arg3 = None):$/;\"\tz\tfunction:func5\tfile:\nfunc6\tinput.py\t/^def func6(arg1, arg2, *args):$/;\"\tf\narg1\tinput.py\t/^def func6(arg1, arg2, *args):$/;\"\tz\tfunction:func6\tfile:\nfunc6.arg1\tinput.py\t/^def func6(arg1, arg2, *args):$/;\"\tz\tfunction:func6\tfile:\narg2\tinput.py\t/^def func6(arg1, arg2, *args):$/;\"\tz\tfunction:func6\tfile:\nfunc6.arg2\tinput.py\t/^def func6(arg1, arg2, *args):$/;\"\tz\tfunction:func6\tfile:\nargs\tinput.py\t/^def func6(arg1, arg2, *args):$/;\"\tz\tfunction:func6\tfile:\nfunc6.args\tinput.py\t/^def func6(arg1, arg2, *args):$/;\"\tz\tfunction:func6\tfile:\nfunc7\tinput.py\t/^def func7(*args, **kwargs):$/;\"\tf\nargs\tinput.py\t/^def func7(*args, **kwargs):$/;\"\tz\tfunction:func7\tfile:\nfunc7.args\tinput.py\t/^def func7(*args, **kwargs):$/;\"\tz\tfunction:func7\tfile:\nkwargs\tinput.py\t/^def func7(*args, **kwargs):$/;\"\tz\tfunction:func7\tfile:\nfunc7.kwargs\tinput.py\t/^def func7(*args, **kwargs):$/;\"\tz\tfunction:func7\tfile:\nfunc8\tinput.py\t/^def func8(arg1=1*2, arg2=func6(1, 2, 3, 4)):$/;\"\tf\narg1\tinput.py\t/^def func8(arg1=1*2, arg2=func6(1, 2, 3, 4)):$/;\"\tz\tfunction:func8\tfile:\nfunc8.arg1\tinput.py\t/^def func8(arg1=1*2, arg2=func6(1, 2, 3, 4)):$/;\"\tz\tfunction:func8\tfile:\narg2\tinput.py\t/^def func8(arg1=1*2, arg2=func6(1, 2, 3, 4)):$/;\"\tz\tfunction:func8\tfile:\nfunc8.arg2\tinput.py\t/^def func8(arg1=1*2, arg2=func6(1, 2, 3, 4)):$/;\"\tz\tfunction:func8\tfile:\nVAR1\tinput.py\t/^VAR1=0$/;\"\tv\nfunc9\tinput.py\t/^def func9(arg1=VAR1*VAR1):$/;\"\tf\narg1\tinput.py\t/^def func9(arg1=VAR1*VAR1):$/;\"\tz\tfunction:func9\tfile:\nfunc9.arg1\tinput.py\t/^def func9(arg1=VAR1*VAR1):$/;\"\tz\tfunction:func9\tfile:\nfunc10\tinput.py\t/^def func10(arg1=[VAR1,VAR1],$/;\"\tf\narg1\tinput.py\t/^def func10(arg1=[VAR1,VAR1],$/;\"\tz\tfunction:func10\tfile:\nfunc10.arg1\tinput.py\t/^def func10(arg1=[VAR1,VAR1],$/;\"\tz\tfunction:func10\tfile:\narg2\tinput.py\t/^           arg2={VAR1:VAR1}):$/;\"\tz\tfunction:func10\tfile:\nfunc10.arg2\tinput.py\t/^           arg2={VAR1:VAR1}):$/;\"\tz\tfunction:func10\tfile:\nCls\tinput.py\t/^class Cls(object):$/;\"\tc\n__init__\tinput.py\t/^    def __init__(self):$/;\"\tm\tclass:Cls\nCls.__init__\tinput.py\t/^    def __init__(self):$/;\"\tm\tclass:Cls\nself\tinput.py\t/^    def __init__(self):$/;\"\tz\tmember:Cls.__init__\tfile:\nCls.__init__.self\tinput.py\t/^    def __init__(self):$/;\"\tz\tmember:Cls.__init__\tfile:\nmethod1\tinput.py\t/^    def method1(self, arg1):$/;\"\tm\tclass:Cls\nCls.method1\tinput.py\t/^    def method1(self, arg1):$/;\"\tm\tclass:Cls\nself\tinput.py\t/^    def method1(self, arg1):$/;\"\tz\tmember:Cls.method1\tfile:\nCls.method1.self\tinput.py\t/^    def method1(self, arg1):$/;\"\tz\tmember:Cls.method1\tfile:\narg1\tinput.py\t/^    def method1(self, arg1):$/;\"\tz\tmember:Cls.method1\tfile:\nCls.method1.arg1\tinput.py\t/^    def method1(self, arg1):$/;\"\tz\tmember:Cls.method1\tfile:\nmethod2\tinput.py\t/^    def method2(self, arg1 = 0, arg2=None):$/;\"\tm\tclass:Cls\nCls.method2\tinput.py\t/^    def method2(self, arg1 = 0, arg2=None):$/;\"\tm\tclass:Cls\nself\tinput.py\t/^    def method2(self, arg1 = 0, arg2=None):$/;\"\tz\tmember:Cls.method2\tfile:\nCls.method2.self\tinput.py\t/^    def method2(self, arg1 = 0, arg2=None):$/;\"\tz\tmember:Cls.method2\tfile:\narg1\tinput.py\t/^    def method2(self, arg1 = 0, arg2=None):$/;\"\tz\tmember:Cls.method2\tfile:\nCls.method2.arg1\tinput.py\t/^    def method2(self, arg1 = 0, arg2=None):$/;\"\tz\tmember:Cls.method2\tfile:\narg2\tinput.py\t/^    def method2(self, arg1 = 0, arg2=None):$/;\"\tz\tmember:Cls.method2\tfile:\nCls.method2.arg2\tinput.py\t/^    def method2(self, arg1 = 0, arg2=None):$/;\"\tz\tmember:Cls.method2\tfile:\nmethod3\tinput.py\t/^    def method3(arg1, arg2=0):$/;\"\tm\tclass:Cls\nCls.method3\tinput.py\t/^    def method3(arg1, arg2=0):$/;\"\tm\tclass:Cls\narg1\tinput.py\t/^    def method3(arg1, arg2=0):$/;\"\tz\tmember:Cls.method3\tfile:\nCls.method3.arg1\tinput.py\t/^    def method3(arg1, arg2=0):$/;\"\tz\tmember:Cls.method3\tfile:\narg2\tinput.py\t/^    def method3(arg1, arg2=0):$/;\"\tz\tmember:Cls.method3\tfile:\nCls.method3.arg2\tinput.py\t/^    def method3(arg1, arg2=0):$/;\"\tz\tmember:Cls.method3\tfile:\n"
  },
  {
    "path": "Units/parser-python.r/python-arguments.d/input.py",
    "content": "\ndef func1():\n    pass\n\ndef func2(arg1):\n    pass\n\ndef func3(arg1, arg2):\n    pass\n\ndef func4( arg1 ,\n           arg2 ,\n           arg3 ):\n    pass\n\ndef func5( arg1 = 1,\n           arg2 = r'hello',\n           arg3 = None):\n    pass\n\ndef func6(arg1, arg2, *args):\n    return (arg1 + 1, arg2 + 2) + args\n\ndef func7(*args, **kwargs):\n    pass\n\ndef func8(arg1=1*2, arg2=func6(1, 2, 3, 4)):\n    pass\n\nVAR1=0\n\ndef func9(arg1=VAR1*VAR1):\n    pass\n\ndef func10(arg1=[VAR1,VAR1],\n           arg2={VAR1:VAR1}):\n    pass\n\n\nclass Cls(object):\n    def __init__(self):\n        pass\n\n    def method1(self, arg1):\n        pass\n\n    def method2(self, arg1 = 0, arg2=None):\n        pass\n\n    @staticmethod\n    def method3(arg1, arg2=0):\n        pass\n"
  },
  {
    "path": "Units/parser-python.r/python-comments.d/args.ctags",
    "content": "--extras=+r\n"
  },
  {
    "path": "Units/parser-python.r/python-comments.d/expected.tags",
    "content": "foo\tinput.py\t/^import foo ## as bug1$/;\"\ti\n"
  },
  {
    "path": "Units/parser-python.r/python-comments.d/input.py",
    "content": "\nimport foo ## as bug1\n\n\"hello\" ## import bug2\n\"hi\" # something # class bug3\n\nfor i in range(1, 2): ##class bug4\n    pass ## class bug5\n"
  },
  {
    "path": "Units/parser-python.r/python-decorators.d/args.ctags",
    "content": "--fields-python=+{decorators}\n"
  },
  {
    "path": "Units/parser-python.r/python-decorators.d/expected.tags",
    "content": "class01\tinput.py\t/^class class01(object):$/;\"\tc\tdecorators:noop\ndummy\tinput.py\t/^    def dummy():$/;\"\tm\tclass:class01\tdecorators:noopwrapper(1, 2, 3),staticmethod,noop\nfunc01\tinput.py\t/^def func01():$/;\"\tf\tdecorators:noop\nfunc02\tinput.py\t/^def func02(): pass$/;\"\tf\tdecorators:noop\nfunc03\tinput.py\t/^def func03(): pass$/;\"\tf\nfunc04\tinput.py\t/^def func04(): pass$/;\"\tf\tdecorators:noop\nfunc05\tinput.py\t/^def func05():$/;\"\tf\tdecorators:class01.tracer\nfunc06\tinput.py\t/^def func06():$/;\"\tf\tdecorators:class01.tracer\nhello\tinput.py\t/^    def hello():$/;\"\tm\tclass:class01\tdecorators:staticmethod\nhi\tinput.py\t/^    def hi(cls):$/;\"\tm\tclass:class01\tdecorators:classmethod\nnoop\tinput.py\t/^def noop(f):$/;\"\tf\nnoopwrapper\tinput.py\t/^def noopwrapper(*args):$/;\"\tf\ntracer\tinput.py\t/^    def tracer(f):$/;\"\tm\tclass:class01\tdecorators:staticmethod\nwrapper\tinput.py\t/^        def wrapper():$/;\"\tf\tmember:class01.tracer\tfile:\n"
  },
  {
    "path": "Units/parser-python.r/python-decorators.d/input.py",
    "content": "\ndef noop(f):\n    return f\n\ndef noopwrapper(*args):\n    return noop\n\n@noop\ndef func01():\n    pass\n\n@noop\ndef func02(): pass\ndef func03(): pass\n@noop\ndef func04(): pass\n\n\n@noop\nclass class01(object):\n    @staticmethod\n    def hello():\n        print(\"hello\")\n\n    @classmethod\n    def hi(cls):\n        print(\"hi from %s\" % cls.__name__)\n\n    @noopwrapper(1, 2, 3)\n\n    @   staticmethod\n    @noop\n    def dummy():\n        print(\"I'm not useful\")\n\n    @staticmethod\n    def tracer(f):\n        def wrapper():\n            print(\"tracing %s\" % f.__name__)\n            return f()\n        return wrapper\n\n\n@class01.tracer\ndef func05():\n    class01.hello()\n\n@ class01 .\ttracer\ndef func06():\n    class01.hi()\n"
  },
  {
    "path": "Units/parser-python.r/python-disable-member-kind.d/args.ctags",
    "content": "--kinds-python=f\n"
  },
  {
    "path": "Units/parser-python.r/python-disable-member-kind.d/input.py",
    "content": "class A:\n    def m():\n        pass\ndef f():\n    pass\n\n"
  },
  {
    "path": "Units/parser-python.r/python-dot-in-import.d/args.ctags",
    "content": "--fields=+r\n--extras=+r\n--sort=no\n"
  },
  {
    "path": "Units/parser-python.r/python-dot-in-import.d/expected.tags",
    "content": "A.B\tinput.py\t/^from A.B import C as D$/;\"\ti\troles:namespace\nC\tinput.py\t/^from A.B import C as D$/;\"\tY\tmodule:A.B\troles:indirectlyImported\nD\tinput.py\t/^from A.B import C as D$/;\"\tY\troles:def\tnameref:unknown:C\n.\tinput.py\t/^from . import E$/;\"\ti\troles:namespace\nE\tinput.py\t/^from . import E$/;\"\tY\tmodule:.\troles:imported\n.F\tinput.py\t/^from .F import G$/;\"\ti\troles:namespace\nG\tinput.py\t/^from .F import G$/;\"\tY\tmodule:.F\troles:imported\nH.I\tinput.py\t/^import H.I$/;\"\ti\troles:imported\n.J.K\tinput.py\t/^from .J.K import L$/;\"\ti\troles:namespace\nL\tinput.py\t/^from .J.K import L$/;\"\tY\tmodule:.J.K\troles:imported\n..M.N\tinput.py\t/^from ..M.N import O$/;\"\ti\troles:namespace\nO\tinput.py\t/^from ..M.N import O$/;\"\tY\tmodule:..M.N\troles:imported\n"
  },
  {
    "path": "Units/parser-python.r/python-dot-in-import.d/input.py",
    "content": "from A.B import C as D\nfrom . import E\nfrom .F import G\nimport H.I\n\nfrom .J.K import L\nfrom ..M.N import O\n"
  },
  {
    "path": "Units/parser-python.r/python-dotted-variable.d/README",
    "content": "FIXME: decide what tags are expected, and update the test case accordingly.\n"
  },
  {
    "path": "Units/parser-python.r/python-dotted-variable.d/expected.tags",
    "content": "Cls\tinput.py\t/^class Cls:$/;\"\tc\nVAR1\tinput.py\t/^VAR1 = Cls()$/;\"\tv\nVAR2\tinput.py\t/^VAR2, VAR1.extra_member1 = 2, 1.1$/;\"\tv\nVAR3\tinput.py\t/^VAR3, VAR1.extra_member3, VAR4 = 3, 1.3, 4$/;\"\tv\nVAR4\tinput.py\t/^VAR3, VAR1.extra_member3, VAR4 = 3, 1.3, 4$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/python-dotted-variable.d/input.py",
    "content": "\nclass Cls:\n    pass\n\nVAR1 = Cls()\n\nVAR2, VAR1.extra_member1 = 2, 1.1\nVAR1.extra_member2 = 1.2\nVAR3, VAR1.extra_member3, VAR4 = 3, 1.3, 4\n"
  },
  {
    "path": "Units/parser-python.r/python-end-field.d/args.ctags",
    "content": "--sort=no\n--fields=+{line}{end}\n--extras=qf\n\n"
  },
  {
    "path": "Units/parser-python.r/python-end-field.d/expected.tags",
    "content": "A\tinput.py\t/^class A(object):$/;\"\tc\tline:1\tend:18\nf\tinput.py\t/^    def f(self):$/;\"\tm\tline:3\tclass:A\tend:7\nA.f\tinput.py\t/^    def f(self):$/;\"\tm\tline:3\tclass:A\tend:7\ng\tinput.py\t/^        def g(x):$/;\"\tf\tline:4\tmember:A.f\tfile:\tend:5\nA.f.g\tinput.py\t/^        def g(x):$/;\"\tf\tline:4\tmember:A.f\tfile:\tend:5\ny\tinput.py\t/^    y = 1$/;\"\tv\tline:10\tclass:A\nA.y\tinput.py\t/^    y = 1$/;\"\tv\tline:10\tclass:A\nh\tinput.py\t/^    def h(self):$/;\"\tm\tline:12\tclass:A\tend:14\nA.h\tinput.py\t/^    def h(self):$/;\"\tm\tline:12\tclass:A\tend:14\ni\tinput.py\t/^    def i(self):$/;\"\tm\tline:16\tclass:A\tend:18\nA.i\tinput.py\t/^    def i(self):$/;\"\tm\tline:16\tclass:A\tend:18\ninput.py\tinput.py\t1;\"\tF\tline:1\tend:18\n"
  },
  {
    "path": "Units/parser-python.r/python-end-field.d/input.py",
    "content": "class A(object):\n\n    def f(self):\n        def g(x):\n            pass\n\n        pass\n\n\n    y = 1\n\n    def h(self):\n\n        pass\n\n    def i(self):\n        x = 1\n        pass\n"
  },
  {
    "path": "Units/parser-python.r/python-fullqualified-tags.d/args.ctags",
    "content": "--extras=+q\n"
  },
  {
    "path": "Units/parser-python.r/python-fullqualified-tags.d/expected.tags",
    "content": "Bar\tinput.py\t/^    class Bar():$/;\"\tc\tclass:Foo\nFoo\tinput.py\t/^class Foo():$/;\"\tc\nFoo.Bar\tinput.py\t/^    class Bar():$/;\"\tc\tclass:Foo\nFoo.Bar.f\tinput.py\t/^        def f(self):$/;\"\tm\tclass:Foo.Bar\nFoo.g\tinput.py\t/^    def g(self):$/;\"\tm\tclass:Foo\nf\tinput.py\t/^        def f(self):$/;\"\tm\tclass:Foo.Bar\ng\tinput.py\t/^    def g(self):$/;\"\tm\tclass:Foo\n"
  },
  {
    "path": "Units/parser-python.r/python-fullqualified-tags.d/input.py",
    "content": "class Foo():\n    def g(self):\n        pass\n    class Bar():\n        def f(self):\n            pass\n"
  },
  {
    "path": "Units/parser-python.r/python-geany-bug-612.d/expected.tags",
    "content": "DeviceSchema\tinput.py\t/^class DeviceSchema(colander.MappingSchema):$/;\"\tc\nidentifier\tinput.py\t/^    identifier = colander.SchemaNode($/;\"\tv\tclass:DeviceSchema\nmanufacturer\tinput.py\t/^    manufacturer = colander.SchemaNode($/;\"\tv\tclass:DeviceSchema\nresourceType\tinput.py\t/^    resourceType = colander.SchemaNode($/;\"\tv\tclass:DeviceSchema\ntype\tinput.py\t/^    type = colander.SchemaNode($/;\"\tv\tclass:DeviceSchema\n"
  },
  {
    "path": "Units/parser-python.r/python-geany-bug-612.d/input.py",
    "content": "# from issue https://github.com/geany/geany/issues/612\n\nimport colander\n\nclass DeviceSchema(colander.MappingSchema):\n    resourceType = colander.SchemaNode(\n        colander.String(),\n        description='ResourceType informs the parser which resource type this is',\n        missing='Device',\n        default='Device',\n        validator=colander.Function(lambda x: x == 'Device', msg=\"resourceType can't be changed\")\n    )\n    identifier = colander.SchemaNode(\n        colander.String(),\n        description='Instance id from manufacturer, owner and others',\n        missing=colander.drop,\n        default=colander.drop,\n    )\n    type = colander.SchemaNode(\n        colander.String(),\n        description=\"What kind of device this is\",\n        missing=colander.required,\n    )\n    manufacturer = colander.SchemaNode(\n        colander.String(),\n        description='Name of device manufacturer',\n        missing=colander.drop,\n    )\n"
  },
  {
    "path": "Units/parser-python.r/python-import.d/args.ctags",
    "content": "--sort=no\n--extras=+qr\n--fields=+rK\n"
  },
  {
    "path": "Units/parser-python.r/python-import.d/expected.tags",
    "content": "a\tinput.py\t/^import a$/;\"\tmodule\troles:imported\nc\tinput.py\t/^import c, d$/;\"\tmodule\troles:imported\nd\tinput.py\t/^import c, d$/;\"\tmodule\troles:imported\ne\tinput.py\t/^from e import f$/;\"\tmodule\troles:namespace\nf\tinput.py\t/^from e import f$/;\"\tunknown\tmodule:e\troles:imported\ne.f\tinput.py\t/^from e import f$/;\"\tunknown\tmodule:e\troles:imported\ng\tinput.py\t/^from g import h, i$/;\"\tmodule\troles:namespace\nh\tinput.py\t/^from g import h, i$/;\"\tunknown\tmodule:g\troles:imported\ng.h\tinput.py\t/^from g import h, i$/;\"\tunknown\tmodule:g\troles:imported\ni\tinput.py\t/^from g import h, i$/;\"\tunknown\tmodule:g\troles:imported\ng.i\tinput.py\t/^from g import h, i$/;\"\tunknown\tmodule:g\troles:imported\nj\tinput.py\t/^from j import *$/;\"\tmodule\troles:namespace\nk\tinput.py\t/^from k import l as m$/;\"\tmodule\troles:namespace\nl\tinput.py\t/^from k import l as m$/;\"\tunknown\tmodule:k\troles:indirectlyImported\nk.l\tinput.py\t/^from k import l as m$/;\"\tunknown\tmodule:k\troles:indirectlyImported\nm\tinput.py\t/^from k import l as m$/;\"\tunknown\troles:def\tnameref:unknown:l\nn\tinput.py\t/^import n as o$/;\"\tmodule\troles:indirectlyImported\no\tinput.py\t/^import n as o$/;\"\tnamespace\troles:def\tnameref:module:n\na1\tinput.py\t/^import a1, a2 as a3, a4, a5$/;\"\tmodule\troles:imported\na2\tinput.py\t/^import a1, a2 as a3, a4, a5$/;\"\tmodule\troles:indirectlyImported\na3\tinput.py\t/^import a1, a2 as a3, a4, a5$/;\"\tnamespace\troles:def\tnameref:module:a2\na4\tinput.py\t/^import a1, a2 as a3, a4, a5$/;\"\tmodule\troles:imported\na5\tinput.py\t/^import a1, a2 as a3, a4, a5$/;\"\tmodule\troles:imported\np\tinput.py\t/^from p import b1, b2 as b3, b4, b5$/;\"\tmodule\troles:namespace\nb1\tinput.py\t/^from p import b1, b2 as b3, b4, b5$/;\"\tunknown\tmodule:p\troles:imported\np.b1\tinput.py\t/^from p import b1, b2 as b3, b4, b5$/;\"\tunknown\tmodule:p\troles:imported\nb2\tinput.py\t/^from p import b1, b2 as b3, b4, b5$/;\"\tunknown\tmodule:p\troles:indirectlyImported\np.b2\tinput.py\t/^from p import b1, b2 as b3, b4, b5$/;\"\tunknown\tmodule:p\troles:indirectlyImported\nb3\tinput.py\t/^from p import b1, b2 as b3, b4, b5$/;\"\tunknown\troles:def\tnameref:unknown:b2\nb4\tinput.py\t/^from p import b1, b2 as b3, b4, b5$/;\"\tunknown\tmodule:p\troles:imported\np.b4\tinput.py\t/^from p import b1, b2 as b3, b4, b5$/;\"\tunknown\tmodule:p\troles:imported\nb5\tinput.py\t/^from p import b1, b2 as b3, b4, b5$/;\"\tunknown\tmodule:p\troles:imported\np.b5\tinput.py\t/^from p import b1, b2 as b3, b4, b5$/;\"\tunknown\tmodule:p\troles:imported\nx\tinput.py\t/^from x import (y as z1, z2,$/;\"\tmodule\troles:namespace\ny\tinput.py\t/^from x import (y as z1, z2,$/;\"\tunknown\tmodule:x\troles:indirectlyImported\nx.y\tinput.py\t/^from x import (y as z1, z2,$/;\"\tunknown\tmodule:x\troles:indirectlyImported\nz1\tinput.py\t/^from x import (y as z1, z2,$/;\"\tunknown\troles:def\tnameref:unknown:y\nz2\tinput.py\t/^from x import (y as z1, z2,$/;\"\tunknown\tmodule:x\troles:imported\nx.z2\tinput.py\t/^from x import (y as z1, z2,$/;\"\tunknown\tmodule:x\troles:imported\nz3\tinput.py\t/^                        z3, z4)$/;\"\tunknown\tmodule:x\troles:imported\nx.z3\tinput.py\t/^                        z3, z4)$/;\"\tunknown\tmodule:x\troles:imported\nz4\tinput.py\t/^                        z3, z4)$/;\"\tunknown\tmodule:x\troles:imported\nx.z4\tinput.py\t/^                        z3, z4)$/;\"\tunknown\tmodule:x\troles:imported\n"
  },
  {
    "path": "Units/parser-python.r/python-import.d/input.py",
    "content": "import a\nimport c, d\nfrom e import f\nfrom g import h, i\nfrom j import *\nfrom k import l as m\nimport n as o\n\nimport a1, a2 as a3, a4, a5\nfrom p import b1, b2 as b3, b4, b5\n\nfrom x import (y as z1, z2,\n                        z3, z4)\n"
  },
  {
    "path": "Units/parser-python.r/python-keyword-tabulation.d/expected.tags",
    "content": "Bar\tinput.py\t/^class\tBar:$/;\"\tc\nfoo\tinput.py\t/^def\tfoo():$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/python-keyword-tabulation.d/input.py",
    "content": "\ndef\tfoo():\n    pass\n\nclass\tBar:\n    pass\n"
  },
  {
    "path": "Units/parser-python.r/python-local-lambdas.d/expected.tags",
    "content": "class01\tinput.py\t/^class class01:$/;\"\tc\nfunc01\tinput.py\t/^def func01():$/;\"\tf\ngloballambda01\tinput.py\t/^globallambda01 = lambda x:x$/;\"\tf\nlocallambda01\tinput.py\t/^    locallambda01 = lambda x:x$/;\"\tf\tfunction:func01\tfile:\nlocallambda02\tinput.py\t/^        locallambda02 = lambda x:x$/;\"\tf\tmember:class01.member01\tfile:\nmember01\tinput.py\t/^    def member01(self):$/;\"\tm\tclass:class01\nmemberlambda01\tinput.py\t/^    memberlambda01 = lambda x:x$/;\"\tm\tclass:class01\n"
  },
  {
    "path": "Units/parser-python.r/python-local-lambdas.d/input.py",
    "content": "globallambda01 = lambda x:x\n\ndef func01():\n    locallambda01 = lambda x:x\n    localvar01 = 1  # ignored\n\nclass class01:\n    memberlambda01 = lambda x:x\n    def member01(self):\n        locallambda02 = lambda x:x\n        localvar02 = 2\n"
  },
  {
    "path": "Units/parser-python.r/python-local-variables.d/args.ctags",
    "content": "--kinds-python=+l\n"
  },
  {
    "path": "Units/parser-python.r/python-local-variables.d/expected.tags",
    "content": "Cls01\tinput.py\t/^class Cls01:$/;\"\tc\nfunc01\tinput.py\t/^def func01():$/;\"\tf\nfunc02\tinput.py\t/^def func02():$/;\"\tf\nfunc03\tinput.py\t/^def func03(x):$/;\"\tf\nfunc04\tinput.py\t/^def func04(x):$/;\"\tf\nglobal01\tinput.py\t/^global01 = 1$/;\"\tv\nlocal01\tinput.py\t/^    local01 = 1$/;\"\tl\tfunction:func01\tfile:\nlocal02\tinput.py\t/^    local02 = 2$/;\"\tl\tfunction:func02\tfile:\nlocal03\tinput.py\t/^    local03 = 3$/;\"\tl\tfunction:func02\tfile:\nlocal04\tinput.py\t/^        local04 = 4$/;\"\tl\tmember:Cls01.method01\tfile:\nlocalfunc01\tinput.py\t/^    def localfunc01():$/;\"\tf\tfunction:func04\tfile:\nlocallambda01\tinput.py\t/^    locallambda01 = lambda x:x$/;\"\tf\tfunction:func03\tfile:\nmember01\tinput.py\t/^    member01 = 1$/;\"\tv\tclass:Cls01\nmember02\tinput.py\t/^    member02 = 2$/;\"\tv\tclass:Cls01\nmethod01\tinput.py\t/^    def method01(self):$/;\"\tm\tclass:Cls01\n"
  },
  {
    "path": "Units/parser-python.r/python-local-variables.d/input.py",
    "content": "global01 = 1\n\ndef func01():\n    local01 = 1\n\ndef func02():\n    local02 = 2\n    local03 = 3\n\ndef func03(x):\n    locallambda01 = lambda x:x\n    return locallambda01\n\ndef func04(x):\n    def localfunc01():\n        return x\n    return localfunc01\n\nclass Cls01:\n    member01 = 1\n    def method01(self):\n        local04 = 4\n    member02 = 2\n"
  },
  {
    "path": "Units/parser-python.r/python-multivar-no-declaration.d/expected.tags",
    "content": "a\tinput.py\t/^a, b, c = 1, 2, 3$/;\"\tv\nb\tinput.py\t/^a, b, c = 1, 2, 3$/;\"\tv\nc\tinput.py\t/^a, b, c = 1, 2, 3$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/python-multivar-no-declaration.d/input.py",
    "content": "1, 2, 3\na, b, c = 1, 2, 3\na, b, c\n"
  },
  {
    "path": "Units/parser-python.r/python-multivar-statement-with-lambdas.d/expected.tags",
    "content": "LAMBDAa1\tinput.py\t/^VARa1, LAMBDAa1 = 1, lambda x: x*x$/;\"\tf\nLAMBDAa2\tinput.py\t/^LAMBDAa2, VARa2 = lambda x: x*x, 2$/;\"\tf\nLAMBDAa3\tinput.py\t/^VARa3, LAMBDAa3, VARa4 = 3, lambda x: x*x, 4$/;\"\tf\nLAMBDAb1\tinput.py\t/^VARb1, LAMBDAb1 = (1,1), lambda x: (x, x)$/;\"\tf\nLAMBDAb2\tinput.py\t/^LAMBDAb2, VARb2 = lambda x: (x, x), (2,2)$/;\"\tf\nLAMBDAb3\tinput.py\t/^VARb3, LAMBDAb3, VARb4 = (3,3), lambda x: (x, x), (4,4)$/;\"\tf\nLAMBDAc1\tinput.py\t/^VARc1, LAMBDAc1 = (1, 1), lambda x,y: x+y$/;\"\tf\nLAMBDAc2\tinput.py\t/^LAMBDAc2, VARc2 = lambda x,y: x+y, (2,2)$/;\"\tf\nLAMBDAc3\tinput.py\t/^VARc3, LAMBDAc3, VARc4 = (3,3), lambda x,y: x+y, (4,4)$/;\"\tf\nVARa1\tinput.py\t/^VARa1, LAMBDAa1 = 1, lambda x: x*x$/;\"\tv\nVARa2\tinput.py\t/^LAMBDAa2, VARa2 = lambda x: x*x, 2$/;\"\tv\nVARa3\tinput.py\t/^VARa3, LAMBDAa3, VARa4 = 3, lambda x: x*x, 4$/;\"\tv\nVARa4\tinput.py\t/^VARa3, LAMBDAa3, VARa4 = 3, lambda x: x*x, 4$/;\"\tv\nVARb1\tinput.py\t/^VARb1, LAMBDAb1 = (1,1), lambda x: (x, x)$/;\"\tv\nVARb2\tinput.py\t/^LAMBDAb2, VARb2 = lambda x: (x, x), (2,2)$/;\"\tv\nVARb3\tinput.py\t/^VARb3, LAMBDAb3, VARb4 = (3,3), lambda x: (x, x), (4,4)$/;\"\tv\nVARb4\tinput.py\t/^VARb3, LAMBDAb3, VARb4 = (3,3), lambda x: (x, x), (4,4)$/;\"\tv\nVARc1\tinput.py\t/^VARc1, LAMBDAc1 = (1, 1), lambda x,y: x+y$/;\"\tv\nVARc2\tinput.py\t/^LAMBDAc2, VARc2 = lambda x,y: x+y, (2,2)$/;\"\tv\nVARc3\tinput.py\t/^VARc3, LAMBDAc3, VARc4 = (3,3), lambda x,y: x+y, (4,4)$/;\"\tv\nVARc4\tinput.py\t/^VARc3, LAMBDAc3, VARc4 = (3,3), lambda x,y: x+y, (4,4)$/;\"\tv\nVARd1\tinput.py\t/^VARd1, VARd2 = (lambda x: (x, x+1))(1)$/;\"\tv\nVARd2\tinput.py\t/^VARd1, VARd2 = (lambda x: (x, x+1))(1)$/;\"\tv\nVARd3\tinput.py\t/^VARd3, VARd4 = (3, 4)$/;\"\tv\nVARd4\tinput.py\t/^VARd3, VARd4 = (3, 4)$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/python-multivar-statement-with-lambdas.d/input.py",
    "content": "\nVARa1, LAMBDAa1 = 1, lambda x: x*x\nLAMBDAa2, VARa2 = lambda x: x*x, 2\nVARa3, LAMBDAa3, VARa4 = 3, lambda x: x*x, 4\n\nVARb1, LAMBDAb1 = (1,1), lambda x: (x, x)\nLAMBDAb2, VARb2 = lambda x: (x, x), (2,2)\nVARb3, LAMBDAb3, VARb4 = (3,3), lambda x: (x, x), (4,4)\n\nVARc1, LAMBDAc1 = (1, 1), lambda x,y: x+y\nLAMBDAc2, VARc2 = lambda x,y: x+y, (2,2)\nVARc3, LAMBDAc3, VARc4 = (3,3), lambda x,y: x+y, (4,4)\n\nVARd1, VARd2 = (lambda x: (x, x+1))(1)\nVARd3, VARd4 = (3, 4)\n\n# check Python actually likes it\nassert(VARa1 == 1)\nassert(LAMBDAa1(1) == 1)\nassert(VARa2 == 2)\nassert(LAMBDAa2(2) == 4)\nassert(VARa3 == 3)\nassert(LAMBDAa3(3) == 9)\nassert(VARa4 == 4)\n\nassert(VARb1 == (1,1))\nassert(LAMBDAb1(1) == (1,1))\nassert(VARb2 == (2,2))\nassert(LAMBDAb2(2) == (2,2))\nassert(VARb3 == (3,3))\nassert(LAMBDAb3(3) == (3,3))\nassert(VARb4 == (4,4))\n\nassert(VARc1 == (1,1))\nassert(LAMBDAc1(1,1) == 2)\nassert(VARc2 == (2,2))\nassert(LAMBDAc2(2,2) == 4)\nassert(VARc3 == (3,3))\nassert(LAMBDAc3(3,3) == 6)\nassert(VARc4 == (4,4))\n\nassert(VARd1 == 1)\nassert(VARd2 == 2)\nassert(VARd3 == 3)\nassert(VARd4 == 4)\n"
  },
  {
    "path": "Units/parser-python.r/python-multivar-statement.d/expected.tags",
    "content": "VAR1\tinput.py\t/^VAR1, VAR2, VAR3 = 1, 2, 3$/;\"\tv\nVAR2\tinput.py\t/^VAR1, VAR2, VAR3 = 1, 2, 3$/;\"\tv\nVAR3\tinput.py\t/^VAR1, VAR2, VAR3 = 1, 2, 3$/;\"\tv\nVAR4\tinput.py\t/^VAR4 = 4$/;\"\tv\nVAR5\tinput.py\t/^VAR5, VAR6 = 5, 6$/;\"\tv\nVAR6\tinput.py\t/^VAR5, VAR6 = 5, 6$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/python-multivar-statement.d/input.py",
    "content": "VAR1, VAR2, VAR3 = 1, 2, 3\nVAR4 = 4\nVAR5, VAR6 = 5, 6\n"
  },
  {
    "path": "Units/parser-python.r/python-semicolon.d/expected.tags",
    "content": "Cls\tinput.py\t/^class Cls:$/;\"\tc\nVAR1\tinput.py\t/^VAR1 = 1; VAR2 = 2;$/;\"\tv\nVAR2\tinput.py\t/^VAR1 = 1; VAR2 = 2;$/;\"\tv\nfunc\tinput.py\t/^    def func(): pass;$/;\"\tm\tclass:Cls\nfunc2\tinput.py\t/^    def func2(x): x += 1; y = x + 1; return y;$/;\"\tm\tclass:Cls\nmemb1\tinput.py\t/^    memb1 = 1; memb2 = 2$/;\"\tv\tclass:Cls\nmemb2\tinput.py\t/^    memb1 = 1; memb2 = 2$/;\"\tv\tclass:Cls\n"
  },
  {
    "path": "Units/parser-python.r/python-semicolon.d/input.py",
    "content": "\nVAR1 = 1; VAR2 = 2;\n\nclass Cls:\n    memb1 = 1; memb2 = 2\n\n    def func(): pass;\n\n    @staticmethod\n    def func2(x): x += 1; y = x + 1; return y;\n\n\nassert(VAR1 == 1)\nassert(VAR2 == 2)\nassert(Cls.memb1 == 1)\nassert(Cls.memb2 == 2)\nassert(Cls.func2(2) == 4)\n"
  },
  {
    "path": "Units/parser-python.r/python2-arglists.d/args.ctags",
    "content": "--fields=+S\n"
  },
  {
    "path": "Units/parser-python.r/python2-arglists.d/expected.tags",
    "content": "func01\tinput.py\t/^def func01():$/;\"\tf\tsignature:()\nfunc02\tinput.py\t/^def func02(a):$/;\"\tf\tsignature:(a)\nfunc03\tinput.py\t/^def func03(a, b = 2):$/;\"\tf\tsignature:(a, b = 2)\nfunc04\tinput.py\t/^def func04(a = 1, b = 2):$/;\"\tf\tsignature:(a = 1, b = 2)\nfunc05\tinput.py\t/^def func05(*args):$/;\"\tf\tsignature:(*args)\nfunc06\tinput.py\t/^def func06(**kwargs):$/;\"\tf\tsignature:(**kwargs)\nfunc07\tinput.py\t/^def func07(*args, **kwargs):$/;\"\tf\tsignature:(*args, **kwargs)\nfunc08\tinput.py\t/^def func08(a, b = 2, *args):$/;\"\tf\tsignature:(a, b = 2, *args)\nfunc09\tinput.py\t/^def func09(a = [1, 2], b = 2, **kwargs):$/;\"\tf\tsignature:(a = [1, 2], b = 2, **kwargs)\nfunc10\tinput.py\t/^def func10(a = (1, 2), b = 2, *args, **kwargs):$/;\"\tf\tsignature:(a = (1, 2), b = 2, *args, **kwargs)\nfunc11\tinput.py\t/^def func11(a = {1:1, 2:1}, b = 2, *args, **kwargs):$/;\"\tf\tsignature:(a = {1:1, 2:1}, b = 2, *args, **kwargs)\nfunc12\tinput.py\t/^def func12((a1, a2)):$/;\"\tf\tsignature:((a1, a2))\nfunc13\tinput.py\t/^def func13((a1, a2), b):$/;\"\tf\tsignature:((a1, a2), b)\nfunc14\tinput.py\t/^def func14((a1, a2) = (1, 2), b = 2):$/;\"\tf\tsignature:((a1, a2) = (1, 2), b = 2)\nfunc15\tinput.py\t/^def func15((a1, a2), *args):$/;\"\tf\tsignature:((a1, a2), *args)\nlamb01\tinput.py\t/^lamb01 = lambda: 0$/;\"\tf\tsignature:()\nlamb02\tinput.py\t/^lamb02 = lambda a: 0$/;\"\tf\tsignature:(a)\nlamb03\tinput.py\t/^lamb03 = lambda a, b: 0$/;\"\tf\tsignature:(a, b)\nlamb04\tinput.py\t/^lamb04 = lambda a, b = 2: 0$/;\"\tf\tsignature:(a, b = 2)\nlamb05\tinput.py\t/^lamb05 = lambda *args: 0$/;\"\tf\tsignature:(*args)\nlamb06\tinput.py\t/^lamb06 = lambda *args, **kwargs: 0$/;\"\tf\tsignature:(*args, **kwargs)\nlamb07\tinput.py\t/^lamb07 = lambda a, *args, **kwargs: 0$/;\"\tf\tsignature:(a, *args, **kwargs)\nlamb08\tinput.py\t/^lamb08 = lambda a = 1, *args, **kwargs: 0$/;\"\tf\tsignature:(a = 1, *args, **kwargs)\nlamb09\tinput.py\t/^lamb09 = lambda a = [1, 2], *args, **kwargs: 0$/;\"\tf\tsignature:(a = [1, 2], *args, **kwargs)\nlamb10\tinput.py\t/^lamb10 = lambda a = (1, 2), *args, **kwargs: 0$/;\"\tf\tsignature:(a = (1, 2), *args, **kwargs)\nlamb11\tinput.py\t/^lamb11 = lambda a = {1:1, 2:1}, *args, **kwargs: 0$/;\"\tf\tsignature:(a = {1:1, 2:1}, *args, **kwargs)\nlamb12\tinput.py\t/^lamb12 = lambda a = lambda:0, *args, **kwargs: a$/;\"\tf\tsignature:(a = lambda:0, *args, **kwargs)\nlamb13\tinput.py\t/^lamb13 = lambda (a1, a2): 0$/;\"\tf\tsignature:((a1, a2))\nlamb14\tinput.py\t/^lamb14 = lambda (a1, a2), b: 0$/;\"\tf\tsignature:((a1, a2), b)\nlamb15\tinput.py\t/^lamb15 = lambda (a1, a2) = (1, 2), b = 2: 0$/;\"\tf\tsignature:((a1, a2) = (1, 2), b = 2)\nlamb16\tinput.py\t/^lamb16 = lambda (a1, a2), *args: 0$/;\"\tf\tsignature:((a1, a2), *args)\n"
  },
  {
    "path": "Units/parser-python.r/python2-arglists.d/input.py",
    "content": "#!/usr/bin/env python2\n\ndef func01():\n    pass\ndef func02(a):\n    pass\ndef func03(a, b = 2):\n    pass\ndef func04(a = 1, b = 2):\n    pass\ndef func05(*args):\n    pass\ndef func06(**kwargs):\n    pass\ndef func07(*args, **kwargs):\n    pass\ndef func08(a, b = 2, *args):\n    pass\ndef func09(a = [1, 2], b = 2, **kwargs):\n    pass\ndef func10(a = (1, 2), b = 2, *args, **kwargs):\n    pass\ndef func11(a = {1:1, 2:1}, b = 2, *args, **kwargs):\n    pass\n\n# Python2 only\ndef func12((a1, a2)):\n    pass\ndef func13((a1, a2), b):\n    pass\ndef func14((a1, a2) = (1, 2), b = 2):\n    pass\ndef func15((a1, a2), *args):\n    pass\n\nlamb01 = lambda: 0\nlamb02 = lambda a: 0\nlamb03 = lambda a, b: 0\nlamb04 = lambda a, b = 2: 0\nlamb05 = lambda *args: 0\nlamb06 = lambda *args, **kwargs: 0\nlamb07 = lambda a, *args, **kwargs: 0\nlamb08 = lambda a = 1, *args, **kwargs: 0\nlamb09 = lambda a = [1, 2], *args, **kwargs: 0\nlamb10 = lambda a = (1, 2), *args, **kwargs: 0\nlamb11 = lambda a = {1:1, 2:1}, *args, **kwargs: 0\nlamb12 = lambda a = lambda:0, *args, **kwargs: a\n\n# Python2 only\nlamb13 = lambda (a1, a2): 0\nlamb14 = lambda (a1, a2), b: 0\nlamb15 = lambda (a1, a2) = (1, 2), b = 2: 0\nlamb16 = lambda (a1, a2), *args: 0\n"
  },
  {
    "path": "Units/parser-python.r/python3-arglists.d/args.ctags",
    "content": "--fields=+S\n"
  },
  {
    "path": "Units/parser-python.r/python3-arglists.d/expected.tags",
    "content": "func01\tinput.py\t/^def func01():$/;\"\tf\tsignature:()\nfunc02\tinput.py\t/^def func02(a):$/;\"\tf\tsignature:(a)\nfunc03\tinput.py\t/^def func03(a, b = 2):$/;\"\tf\tsignature:(a, b = 2)\nfunc04\tinput.py\t/^def func04(a = 1, b = 2):$/;\"\tf\tsignature:(a = 1, b = 2)\nfunc05\tinput.py\t/^def func05(*args):$/;\"\tf\tsignature:(*args)\nfunc06\tinput.py\t/^def func06(**kwargs):$/;\"\tf\tsignature:(**kwargs)\nfunc07\tinput.py\t/^def func07(*args, **kwargs):$/;\"\tf\tsignature:(*args, **kwargs)\nfunc08\tinput.py\t/^def func08(a, b = 2, *args):$/;\"\tf\tsignature:(a, b = 2, *args)\nfunc09\tinput.py\t/^def func09(a = [1, 2], b = 2, **kwargs):$/;\"\tf\tsignature:(a = [1, 2], b = 2, **kwargs)\nfunc10\tinput.py\t/^def func10(a = (1, 2), b = 2, *args, **kwargs):$/;\"\tf\tsignature:(a = (1, 2), b = 2, *args, **kwargs)\nfunc11\tinput.py\t/^def func11(a = {1:1, 2:1}, b = 2, *args, **kwargs):$/;\"\tf\tsignature:(a = {1:1, 2:1}, b = 2, *args, **kwargs)\nfunc12\tinput.py\t/^def func12(a:\"first\", b:\"second\"):$/;\"\tf\tsignature:(a:\"first\", b:\"second\")\nfunc13\tinput.py\t/^def func13(a:\"first\", b):$/;\"\tf\tsignature:(a:\"first\", b)\nfunc14\tinput.py\t/^def func14(a:\"first\" = 1, b = 2):$/;\"\tf\tsignature:(a:\"first\" = 1, b = 2)\nfunc15\tinput.py\t/^def func15(a:\"first\" = (1, 2), *args:'more args'):$/;\"\tf\tsignature:(a:\"first\" = (1, 2), *args:'more args')\nfunc16\tinput.py\t/^def func16(a:1+1 = (1, 2), *args:2*2):$/;\"\tf\tsignature:(a:1+1 = (1, 2), *args:2*2)\nfunc17\tinput.py\t/^def func17(a:{\"1\":1, \"2\":2} = {\"1\":1, \"2\":2}, *args:lambda:0):$/;\"\tf\tsignature:(a:{\"1\":1, \"2\":2} = {\"1\":1, \"2\":2}, *args:lambda:0)\nfunc18\tinput.py\t/^def func18(a:lambda:[1,2][:1] = (2+2)*2, *args:lambda:0):$/;\"\tf\tsignature:(a:lambda:[1,2][:1] = (2+2)*2, *args:lambda:0)\nlamb01\tinput.py\t/^lamb01 = lambda: 0$/;\"\tf\tsignature:()\nlamb02\tinput.py\t/^lamb02 = lambda a: 0$/;\"\tf\tsignature:(a)\nlamb03\tinput.py\t/^lamb03 = lambda a, b: 0$/;\"\tf\tsignature:(a, b)\nlamb04\tinput.py\t/^lamb04 = lambda a, b = 2: 0$/;\"\tf\tsignature:(a, b = 2)\nlamb05\tinput.py\t/^lamb05 = lambda *args: 0$/;\"\tf\tsignature:(*args)\nlamb06\tinput.py\t/^lamb06 = lambda *args, **kwargs: 0$/;\"\tf\tsignature:(*args, **kwargs)\nlamb07\tinput.py\t/^lamb07 = lambda a, *args, **kwargs: 0$/;\"\tf\tsignature:(a, *args, **kwargs)\nlamb08\tinput.py\t/^lamb08 = lambda a = 1, *args, **kwargs: 0$/;\"\tf\tsignature:(a = 1, *args, **kwargs)\nlamb09\tinput.py\t/^lamb09 = lambda a = [1, 2], *args, **kwargs: 0$/;\"\tf\tsignature:(a = [1, 2], *args, **kwargs)\nlamb10\tinput.py\t/^lamb10 = lambda a = (1, 2), *args, **kwargs: 0$/;\"\tf\tsignature:(a = (1, 2), *args, **kwargs)\nlamb11\tinput.py\t/^lamb11 = lambda a = {1:1, 2:1}, *args, **kwargs: 0$/;\"\tf\tsignature:(a = {1:1, 2:1}, *args, **kwargs)\nlamb12\tinput.py\t/^lamb12 = lambda a = lambda:0, *args, **kwargs: a$/;\"\tf\tsignature:(a = lambda:0, *args, **kwargs)\n"
  },
  {
    "path": "Units/parser-python.r/python3-arglists.d/input.py",
    "content": "#!/usr/bin/env python3\n\ndef func01():\n    pass\ndef func02(a):\n    pass\ndef func03(a, b = 2):\n    pass\ndef func04(a = 1, b = 2):\n    pass\ndef func05(*args):\n    pass\ndef func06(**kwargs):\n    pass\ndef func07(*args, **kwargs):\n    pass\ndef func08(a, b = 2, *args):\n    pass\ndef func09(a = [1, 2], b = 2, **kwargs):\n    pass\ndef func10(a = (1, 2), b = 2, *args, **kwargs):\n    pass\ndef func11(a = {1:1, 2:1}, b = 2, *args, **kwargs):\n    pass\n\n# Python3 only\ndef func12(a:\"first\", b:\"second\"):\n    pass\ndef func13(a:\"first\", b):\n    pass\ndef func14(a:\"first\" = 1, b = 2):\n    pass\ndef func15(a:\"first\" = (1, 2), *args:'more args'):\n    pass\n# crazier, but supported (as what follows \":\" is an expression)\ndef func16(a:1+1 = (1, 2), *args:2*2):\n    pass\ndef func17(a:{\"1\":1, \"2\":2} = {\"1\":1, \"2\":2}, *args:lambda:0):\n    pass\ndef func18(a:lambda:[1,2][:1] = (2+2)*2, *args:lambda:0):\n    pass\n\nlamb01 = lambda: 0\nlamb02 = lambda a: 0\nlamb03 = lambda a, b: 0\nlamb04 = lambda a, b = 2: 0\nlamb05 = lambda *args: 0\nlamb06 = lambda *args, **kwargs: 0\nlamb07 = lambda a, *args, **kwargs: 0\nlamb08 = lambda a = 1, *args, **kwargs: 0\nlamb09 = lambda a = [1, 2], *args, **kwargs: 0\nlamb10 = lambda a = (1, 2), *args, **kwargs: 0\nlamb11 = lambda a = {1:1, 2:1}, *args, **kwargs: 0\nlamb12 = lambda a = lambda:0, *args, **kwargs: a\n"
  },
  {
    "path": "Units/parser-python.r/python3-function-annotations.d/args.ctags",
    "content": "--kinds-python=+z\n"
  },
  {
    "path": "Units/parser-python.r/python3-function-annotations.d/expected.tags",
    "content": "a\tinput.py\t/^def func03(a:\"hello\", b : 1 * 2 + 3 \\/ 4 = 5):$/;\"\tz\tfunction:func03\ttyperef:typename:\"hello\"\tfile:\na\tinput.py\t/^def func04(a:(1, 2, 3, 4)=(1, 2, 3, 4), b:[5,6]=[7,8], c=0) -> {'foo' : 'bar' }:$/;\"\tz\tfunction:func04\ttyperef:typename:(1,2,3,4)\tfile:\nb\tinput.py\t/^def func03(a:\"hello\", b : 1 * 2 + 3 \\/ 4 = 5):$/;\"\tz\tfunction:func03\ttyperef:typename:1*2+3/4\tfile:\nb\tinput.py\t/^def func04(a:(1, 2, 3, 4)=(1, 2, 3, 4), b:[5,6]=[7,8], c=0) -> {'foo' : 'bar' }:$/;\"\tz\tfunction:func04\ttyperef:typename:[5,6]\tfile:\nc\tinput.py\t/^def func04(a:(1, 2, 3, 4)=(1, 2, 3, 4), b:[5,6]=[7,8], c=0) -> {'foo' : 'bar' }:$/;\"\tz\tfunction:func04\tfile:\nfunc01\tinput.py\t/^def func01() -> \"returns something\":$/;\"\tf\ttyperef:typename:\"returns something\"\nfunc02\tinput.py\t/^def func02() -> 2 * 2 * 3 * 4:$/;\"\tf\ttyperef:typename:2*2*3*4\nfunc03\tinput.py\t/^def func03(a:\"hello\", b : 1 * 2 + 3 \\/ 4 = 5):$/;\"\tf\nfunc04\tinput.py\t/^def func04(a:(1, 2, 3, 4)=(1, 2, 3, 4), b:[5,6]=[7,8], c=0) -> {'foo' : 'bar' }:$/;\"\tf\ttyperef:typename:{'foo':'bar'}\nsub01\tinput.py\t/^    def sub01(): pass$/;\"\tf\tfunction:func01\tfile:\nsub02\tinput.py\t/^    def sub02(): pass$/;\"\tf\tfunction:func02\tfile:\nsub03\tinput.py\t/^    def sub03(): pass$/;\"\tf\tfunction:func03\tfile:\nsub04\tinput.py\t/^    def sub04(): pass$/;\"\tf\tfunction:func04\tfile:\n"
  },
  {
    "path": "Units/parser-python.r/python3-function-annotations.d/input.py",
    "content": "\ndef func01() -> \"returns something\":\n    def sub01(): pass\n\ndef func02() -> 2 * 2 * 3 * 4:\n    def sub02(): pass\n\ndef func03(a:\"hello\", b : 1 * 2 + 3 / 4 = 5):\n    def sub03(): pass\n\ndef func04(a:(1, 2, 3, 4)=(1, 2, 3, 4), b:[5,6]=[7,8], c=0) -> {'foo' : 'bar' }:\n    def sub04(): pass\n\n\n# test\nfor f in (\nfunc01,\nfunc02,\nfunc03,\nfunc04,\n):\n    print(f.__name__, f.__annotations__)\n"
  },
  {
    "path": "Units/parser-python.r/reserved-words.d/args.ctags",
    "content": "--sort=no\n--kinds-Python=*\n"
  },
  {
    "path": "Units/parser-python.r/reserved-words.d/expected.tags",
    "content": "x\tinput.py\t/^    x = 1$/;\"\tv\nx\tinput.py\t/^    x = 2$/;\"\tv\nf\tinput.py\t/^def f(text, pat):$/;\"\tf\ntext\tinput.py\t/^def f(text, pat):$/;\"\tz\tfunction:f\tfile:\npat\tinput.py\t/^def f(text, pat):$/;\"\tz\tfunction:f\tfile:\n"
  },
  {
    "path": "Units/parser-python.r/reserved-words.d/input.py",
    "content": "if True:\n    x = 1\nelse:\n    x = 2\n\ndef f(text, pat):\n    if \".\" in text:\n        return []\n    try: regexp = pat\n"
  },
  {
    "path": "Units/parser-python.r/simple.py.d/args.ctags",
    "content": "--sort=no\n--extras=*-p\n--fields-all=*\n--fields=*-T\n"
  },
  {
    "path": "Units/parser-python.r/simple.py.d/expected.tags",
    "content": "bsddb\tinput.py\t/^from bsddb import btopen$/;\"\tkind:module\tline:5\tlanguage:Python\troles:namespace\textras:reference\nbtopen\tinput.py\t/^from bsddb import btopen$/;\"\tkind:unknown\tline:5\tlanguage:Python\tscope:module:bsddb\troles:imported\textras:reference\nbsddb.btopen\tinput.py\t/^from bsddb import btopen$/;\"\tkind:unknown\tline:5\tlanguage:Python\tscope:module:bsddb\troles:imported\textras:qualified,reference\nVERSION\tinput.py\t/^VERSION = '1.2.0'$/;\"\tkind:variable\tline:9\tlanguage:Python\taccess:public\troles:def\nALL\tinput.py\t/^ALL = 0xff $/;\"\tkind:variable\tline:12\tlanguage:Python\taccess:public\troles:def\nKEY\tinput.py\t/^KEY = 0x01$/;\"\tkind:variable\tline:13\tlanguage:Python\taccess:public\troles:def\nTREEID\tinput.py\t/^TREEID = 0x02$/;\"\tkind:variable\tline:14\tlanguage:Python\taccess:public\troles:def\nINDENT\tinput.py\t/^INDENT = 0x04$/;\"\tkind:variable\tline:15\tlanguage:Python\taccess:public\troles:def\nDATA\tinput.py\t/^DATA = 0x08 # Used by dbtreedata$/;\"\tkind:variable\tline:16\tlanguage:Python\taccess:public\troles:def\none\tinput.py\t/^class one:$/;\"\tkind:class\tline:18\tlanguage:Python\tinherits:\taccess:public\troles:def\tend:34\nx\tinput.py\t/^    x = lambda x: x$/;\"\tkind:member\tline:20\tlanguage:Python\tscope:class:one\taccess:public\tsignature:(x)\troles:def\none.x\tinput.py\t/^    x = lambda x: x$/;\"\tkind:member\tline:20\tlanguage:Python\tscope:class:one\taccess:public\tsignature:(x)\troles:def\textras:qualified\ny\tinput.py\t/^    y = 0$/;\"\tkind:variable\tline:21\tlanguage:Python\tscope:class:one\taccess:public\troles:def\none.y\tinput.py\t/^    y = 0$/;\"\tkind:variable\tline:21\tlanguage:Python\tscope:class:one\taccess:public\troles:def\textras:qualified\n__init__\tinput.py\t/^    def __init__(self, filename, pathsep='', treegap=64):$/;\"\tkind:member\tline:23\tlanguage:Python\tscope:class:one\taccess:public\tsignature:(self, filename, pathsep='', treegap=64)\troles:def\tend:25\none.__init__\tinput.py\t/^    def __init__(self, filename, pathsep='', treegap=64):$/;\"\tkind:member\tline:23\tlanguage:Python\tscope:class:one\taccess:public\tsignature:(self, filename, pathsep='', treegap=64)\troles:def\textras:qualified\tend:25\n__private_function__\tinput.py\t/^    def __private_function__(self, key, data):$/;\"\tkind:member\tline:27\tlanguage:Python\tscope:class:one\taccess:public\tsignature:(self, key, data)\troles:def\tend:27\none.__private_function__\tinput.py\t/^    def __private_function__(self, key, data):$/;\"\tkind:member\tline:27\tlanguage:Python\tscope:class:one\taccess:public\tsignature:(self, key, data)\troles:def\textras:qualified\tend:27\npublic_function\tinput.py\t/^    def public_function(self, key):$/;\"\tkind:member\tline:29\tlanguage:Python\tscope:class:one\taccess:public\tsignature:(self, key)\troles:def\tend:30\none.public_function\tinput.py\t/^    def public_function(self, key):$/;\"\tkind:member\tline:29\tlanguage:Python\tscope:class:one\taccess:public\tsignature:(self, key)\troles:def\textras:qualified\tend:30\nthis_is_ignored\tinput.py\t/^        class this_is_ignored:$/;\"\tkind:class\tline:30\tlanguage:Python\tscope:member:one.public_function\tfile:\tinherits:\taccess:private\troles:def\tend:30\none.public_function.this_is_ignored\tinput.py\t/^        class this_is_ignored:$/;\"\tkind:class\tline:30\tlanguage:Python\tscope:member:one.public_function\tfile:\tinherits:\taccess:private\troles:def\textras:qualified\tend:30\n_pack\tinput.py\t/^    def _pack(self, key):$/;\"\tkind:member\tline:32\tlanguage:Python\tscope:class:one\taccess:protected\tsignature:(self, key)\troles:def\tend:33\none._pack\tinput.py\t/^    def _pack(self, key):$/;\"\tkind:member\tline:32\tlanguage:Python\tscope:class:one\taccess:protected\tsignature:(self, key)\troles:def\textras:qualified\tend:33\nso_is_this\tinput.py\t/^    class so_is_this:$/;\"\tkind:class\tline:34\tlanguage:Python\tscope:class:one\tinherits:\taccess:public\troles:def\tend:34\none.so_is_this\tinput.py\t/^    class so_is_this:$/;\"\tkind:class\tline:34\tlanguage:Python\tscope:class:one\tinherits:\taccess:public\troles:def\textras:qualified\tend:34\n_test\tinput.py\t/^def _test(test, code, outcome, exception):$/;\"\tkind:function\tline:36\tlanguage:Python\taccess:protected\tsignature:(test, code, outcome, exception)\troles:def\tend:42\nignored_function\tinput.py\t/^    def ignored_function():$/;\"\tkind:function\tline:37\tlanguage:Python\tscope:function:_test\tfile:\taccess:private\tsignature:()\troles:def\tend:42\n_test.ignored_function\tinput.py\t/^    def ignored_function():$/;\"\tkind:function\tline:37\tlanguage:Python\tscope:function:_test\tfile:\taccess:private\tsignature:()\troles:def\textras:qualified\tend:42\nmore_nesting\tinput.py\t/^        def more_nesting():$/;\"\tkind:function\tline:38\tlanguage:Python\tscope:function:_test.ignored_function\tfile:\taccess:private\tsignature:()\troles:def\tend:42\n_test.ignored_function.more_nesting\tinput.py\t/^        def more_nesting():$/;\"\tkind:function\tline:38\tlanguage:Python\tscope:function:_test.ignored_function\tfile:\taccess:private\tsignature:()\troles:def\textras:qualified\tend:42\ndeeply_nested\tinput.py\t/^            class deeply_nested():$/;\"\tkind:class\tline:39\tlanguage:Python\tscope:function:_test.ignored_function.more_nesting\tfile:\tinherits:\taccess:private\troles:def\tend:42\n_test.ignored_function.more_nesting.deeply_nested\tinput.py\t/^            class deeply_nested():$/;\"\tkind:class\tline:39\tlanguage:Python\tscope:function:_test.ignored_function.more_nesting\tfile:\tinherits:\taccess:private\troles:def\textras:qualified\tend:42\neven_more\tinput.py\t/^                def even_more():$/;\"\tkind:member\tline:40\tlanguage:Python\tscope:class:_test.ignored_function.more_nesting.deeply_nested\taccess:public\tsignature:()\troles:def\tend:42\n_test.ignored_function.more_nesting.deeply_nested.even_more\tinput.py\t/^                def even_more():$/;\"\tkind:member\tline:40\tlanguage:Python\tscope:class:_test.ignored_function.more_nesting.deeply_nested\taccess:public\tsignature:()\troles:def\textras:qualified\tend:42\nthis\tinput.py\t/^                    @blah class this is seen???$/;\"\tkind:class\tline:41\tlanguage:Python\tscope:member:_test.ignored_function.more_nesting.deeply_nested.even_more\tfile:\tinherits:\taccess:private\troles:def\tend:42\tdecorators:blah\n_test.ignored_function.more_nesting.deeply_nested.even_more.this\tinput.py\t/^                    @blah class this is seen???$/;\"\tkind:class\tline:41\tlanguage:Python\tscope:member:_test.ignored_function.more_nesting.deeply_nested.even_more\tfile:\tinherits:\taccess:private\troles:def\textras:qualified\tend:42\tdecorators:blah\nthis\tinput.py\t/^                        @bleh def this also? good!$/;\"\tkind:member\tline:42\tlanguage:Python\tscope:class:_test.ignored_function.more_nesting.deeply_nested.even_more.this\taccess:public\troles:def\tend:42\tdecorators:bleh\n_test.ignored_function.more_nesting.deeply_nested.even_more.this.this\tinput.py\t/^                        @bleh def this also? good!$/;\"\tkind:member\tline:42\tlanguage:Python\tscope:class:_test.ignored_function.more_nesting.deeply_nested.even_more.this\taccess:public\troles:def\textras:qualified\tend:42\tdecorators:bleh\ntwo\tinput.py\t/^class two (one):$/;\"\tkind:class\tline:46\tlanguage:Python\tinherits:one\taccess:public\troles:def\tend:48\nonly\tinput.py\t/^    def only(arg):$/;\"\tkind:member\tline:48\tlanguage:Python\tscope:class:two\taccess:public\tsignature:(arg)\troles:def\tend:48\ntwo.only\tinput.py\t/^    def only(arg):$/;\"\tkind:member\tline:48\tlanguage:Python\tscope:class:two\taccess:public\tsignature:(arg)\troles:def\textras:qualified\tend:48\nthree\tinput.py\t/^three\\\\$/;\"\tkind:class\tline:52\tlanguage:Python\tinherits:A, B, C\taccess:public\troles:def\tend:54\nfoo\tinput.py\t/^foo($/;\"\tkind:function\tline:57\tlanguage:Python\taccess:public\tsignature:( x , y, z)\troles:def\tend:60\ninput.py\tinput.py\t1;\"\tkind:file\tline:1\tlanguage:Python\troles:def\textras:inputFile\tend:60\n"
  },
  {
    "path": "Units/parser-python.r/simple.py.d/input.py",
    "content": "\"\"\"A long string\nliteral\n\"\"\"\n\nfrom bsddb import btopen\n\n# Public global constants\n\nVERSION = '1.2.0'\n\n# Flags for list() and children()\nALL = 0xff \nKEY = 0x01\nTREEID = 0x02\nINDENT = 0x04\nDATA = 0x08 # Used by dbtreedata\n\nclass one:\n    \n    x = lambda x: x\n    y = 0\n\n    def __init__(self, filename, pathsep='', treegap=64):\n        \"\"\"Another string\n    literal\"\"\"\n\n    def __private_function__(self, key, data):\n    \n    def public_function(self, key):\n        class this_is_ignored:\n\n    def _pack(self, key):\n        pass\n    class so_is_this:\n\ndef _test(test, code, outcome, exception):\n    def ignored_function():\n        def more_nesting():\n            class deeply_nested():\n                def even_more():\n                    @blah class this is seen???\n                        @bleh def this also? good!\n\nif __name__ == '__main__':\n\nclass two (one):\n\n    def only(arg):\n\n# line continuation\nclass\\\nthree\\\n(A, B,\nC):\n\ndef\\\nfoo(\nx\n,\ny,    z):\n"
  },
  {
    "path": "Units/parser-python.r/simpleNamespace.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-python.r/simpleNamespace.d/expected.tags",
    "content": "SA0\tinput.py\t/^SA0 = SimpleNamespace($/;\"\tI\nSA0a\tinput.py\t/^    SA0a=\"unknown\",$/;\"\tY\tnamespace:SA0\tfile:\nSA0b\tinput.py\t/^    SA0b=\"md5\",$/;\"\tY\tnamespace:SA0\tfile:\nsD\tinput.py\t/^sD= {$/;\"\tv\nSA1\tinput.py\t/^SA1 = SimpleNamespace(SA1a = lambda x:  x + 1, SA1b = 1, **sD)$/;\"\tI\nSA1a\tinput.py\t/^SA1 = SimpleNamespace(SA1a = lambda x:  x + 1, SA1b = 1, **sD)$/;\"\tf\tnamespace:SA1\tfile:\nSA1b\tinput.py\t/^SA1 = SimpleNamespace(SA1a = lambda x:  x + 1, SA1b = 1, **sD)$/;\"\tY\tnamespace:SA1\tfile:\nx\tinput.py\t/^x = SimpleNamespace$/;\"\tv\ny\tinput.py\t/^y = SimpleNamespace.mro()$/;\"\tv\nf\tinput.py\t/^def f():$/;\"\tf\ntSA0\tinput-0.py\t/^tSA0 = types.SimpleNamespace($/;\"\tI\ntSA0a\tinput-0.py\t/^    tSA0a=\"unknown\",$/;\"\tY\tnamespace:tSA0\tfile:\ntSA0b\tinput-0.py\t/^    tSA0b=\"md5\",$/;\"\tY\tnamespace:tSA0\tfile:\ntsD\tinput-0.py\t/^tsD= {$/;\"\tv\ntSA1\tinput-0.py\t/^tSA1 = types.SimpleNamespace(tSA1a = lambda x:  x + 1, tSA1b = 1, **tsD)$/;\"\tI\ntSA1a\tinput-0.py\t/^tSA1 = types.SimpleNamespace(tSA1a = lambda x:  x + 1, tSA1b = 1, **tsD)$/;\"\tf\tnamespace:tSA1\tfile:\ntSA1b\tinput-0.py\t/^tSA1 = types.SimpleNamespace(tSA1a = lambda x:  x + 1, tSA1b = 1, **tsD)$/;\"\tY\tnamespace:tSA1\tfile:\ntx\tinput-0.py\t/^tx = types.SimpleNamespace$/;\"\tv\nty\tinput-0.py\t/^ty = types.SimpleNamespace.mro()$/;\"\tv\ntf\tinput-0.py\t/^def tf():$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/simpleNamespace.d/input-0.py",
    "content": "import types\n\ntSA0 = types.SimpleNamespace(\n    tSA0a=\"unknown\",\n    tSA0b=\"md5\",\n)\n\ntsD= {\n    \"name\": 1\n}\n\ntSA1 = types.SimpleNamespace(tSA1a = lambda x:  x + 1, tSA1b = 1, **tsD)\n\ntx = types.SimpleNamespace\nty = types.SimpleNamespace.mro()\n\ndef tf():\n    pass\n"
  },
  {
    "path": "Units/parser-python.r/simpleNamespace.d/input.py",
    "content": "from types import SimpleNamespace\n\nSA0 = SimpleNamespace(\n    SA0a=\"unknown\",\n    SA0b=\"md5\",\n)\n\nsD= {\n    \"name\": 1\n}\n\nSA1 = SimpleNamespace(SA1a = lambda x:  x + 1, SA1b = 1, **sD)\n\nx = SimpleNamespace\ny = SimpleNamespace.mro()\n\ndef f():\n    pass\n"
  },
  {
    "path": "Units/parser-python.r/strings.d/expected.tags",
    "content": "VAR01\tinput.py\t/^VAR01 = \"\"$/;\"\tv\nVAR02\tinput.py\t/^VAR02 = \"hello\"$/;\"\tv\nVAR03\tinput.py\t/^VAR03 = ''$/;\"\tv\nVAR04\tinput.py\t/^VAR04 = 'hi'$/;\"\tv\nVAR05\tinput.py\t/^VAR05 = \"\\\\\"\"$/;\"\tv\nVAR06\tinput.py\t/^VAR06 = '\\\\''$/;\"\tv\nVAR07\tinput.py\t/^VAR07 = \"'''\"$/;\"\tv\nVAR08\tinput.py\t/^VAR08 = '\"\"\"'$/;\"\tv\nVAR21\tinput.py\t/^VAR21 = r\"\"$/;\"\tv\nVAR22\tinput.py\t/^VAR22 = u\"hello\"$/;\"\tv\nVAR23\tinput.py\t/^VAR23 = R''$/;\"\tv\nVAR24\tinput.py\t/^VAR24 = U'hi'$/;\"\tv\nVAR25\tinput.py\t/^VAR25 = b\"\\\\\"\"$/;\"\tv\nVAR26\tinput.py\t/^VAR26 = B'\\\\''$/;\"\tv\nVAR27\tinput.py\t/^VAR27 = br\"'''\"$/;\"\tv\nVAR28\tinput.py\t/^VAR28 = Br'\"\"\"'$/;\"\tv\nVAR29\tinput.py\t/^VAR29 = bR\"hello\"$/;\"\tv\nVAR30\tinput.py\t/^VAR30 = BR\"hello\"$/;\"\tv\nVAR31\tinput.py\t/^VAR31 = rb\"hello\"$/;\"\tv\nVAR32\tinput.py\t/^VAR32 = rB\"hello\"$/;\"\tv\nVAR33\tinput.py\t/^VAR33 = Rb\"hello\"$/;\"\tv\nVAR34\tinput.py\t/^VAR34 = RB\"hello\"$/;\"\tv\nVAR35\tinput.py\t/^VAR35 = ur\"hello\"$/;\"\tv\nVAR36\tinput.py\t/^VAR36 = UR\"hello\"$/;\"\tv\nVAR37\tinput.py\t/^VAR37 = uR\"hello\"$/;\"\tv\nVAR38\tinput.py\t/^VAR38 = Ur\"hello\"$/;\"\tv\nVAR80\tinput.py\t/^VAR80 = \"oops$/;\"\tv\nVAR81\tinput.py\t/^VAR81 = 'oopsie$/;\"\tv\nVAR82\tinput.py\t/^VAR82 = \"\\\\\"$/;\"\tv\nVAR83\tinput.py\t/^VAR83 = '\\\\'$/;\"\tv\nVAR84\tinput.py\t/^VAR84 = 42$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/strings.d/input.py",
    "content": "\nVAR01 = \"\"\nVAR02 = \"hello\"\nVAR03 = ''\nVAR04 = 'hi'\nVAR05 = \"\\\"\"\nVAR06 = '\\''\nVAR07 = \"'''\"\nVAR08 = '\"\"\"'\n\nVAR21 = r\"\"\nVAR22 = u\"hello\"\nVAR23 = R''\nVAR24 = U'hi'\nVAR25 = b\"\\\"\"\nVAR26 = B'\\''\nVAR27 = br\"'''\"\nVAR28 = Br'\"\"\"'\nVAR29 = bR\"hello\"\nVAR30 = BR\"hello\"\n# Python >= 3.3\nVAR31 = rb\"hello\"\nVAR32 = rB\"hello\"\nVAR33 = Rb\"hello\"\nVAR34 = RB\"hello\"\n# Python 2 only\nVAR35 = ur\"hello\"\nVAR36 = UR\"hello\"\nVAR37 = uR\"hello\"\nVAR38 = Ur\"hello\"\n\n# also test not-too-bad behavior when strings are not terminated properly\nVAR80 = \"oops\nVAR81 = 'oopsie\nVAR82 = \"\\\"\nVAR83 = '\\'\nVAR84 = 42\n"
  },
  {
    "path": "Units/parser-python.r/tabindent.py.d/expected.tags",
    "content": "find_heading\tinput.py\t/^def find_heading(self, position=0, direction=Direction.FORWARD, \\\\$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/tabindent.py.d/input.py",
    "content": "def find_heading(self, position=0, direction=Direction.FORWARD, \\\n\t\theading=Heading, connect_with_document=True):\n\tpass\n"
  },
  {
    "path": "Units/parser-python.r/test.py.d/expected.tags",
    "content": "main\tinput.py\t/^def main():$/;\"\tf\nvar\tinput.py\t/^var = 'hi'$/;\"\tv\nvar2\tinput.py\t/^var2 = 'hi' # blah = blah$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/test.py.d/input.py",
    "content": "#!/usr/bin/env python\n\ndef main():\n\t\n\treturn 0\n\nif __name__ == '__main__': main()\n\nvar = 'hi'\nvar2 = 'hi' # blah = blah\n"
  },
  {
    "path": "Units/parser-python.r/toplevel-funcall-with-keyword-args.d/expected.tags",
    "content": "bar\tinput.py\t/^def bar():$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/toplevel-funcall-with-keyword-args.d/input.py",
    "content": "foo (\n\tx = 1,\n\ty = 2\n\t)\ndef bar():\n    pass\n"
  },
  {
    "path": "Units/parser-python.r/triple-quotes-after-def.d/expected.tags",
    "content": "a\tinput.py\t/^def a(i, s): '''a'''$/;\"\tf\nb\tinput.py\t/^def b(i, s): \"\"\"b\"\"\"$/;\"\tf\nc\tinput.py\t/^def c(i, s): '''c$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/triple-quotes-after-def.d/input.py",
    "content": "def a(i, s): '''a'''\ndef b(i, s): \"\"\"b\"\"\"\ndef c(i, s): '''c\n\td'''\n"
  },
  {
    "path": "Units/parser-python.r/triple-quotes-in-class.d/expected.tags",
    "content": "Bar\tinput.py\t/^class Bar():$/;\"\tc\nFoo\tinput.py\t/^class Foo():$/;\"\tc\na\tinput.py\t/^    a=\"\"\"$/;\"\tv\tclass:Foo\n"
  },
  {
    "path": "Units/parser-python.r/triple-quotes-in-class.d/input.py",
    "content": "class Foo():\n    a=\"\"\"\n      baz\n      \"\"\"\n\n\nclass Bar():\n    pass\n"
  },
  {
    "path": "Units/parser-python.r/triple-quotes-in-default-arg.d/expected.tags",
    "content": "anothervar\tinput.py\t/^anothervar=1$/;\"\tv\nf\tinput.py\t/^def f(var=(\"\"\"$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/triple-quotes-in-default-arg.d/input.py",
    "content": "def f(var=(\"\"\"\nstr\n\"\"\",1)):\n\tpass\nanothervar=1\n"
  },
  {
    "path": "Units/parser-python.r/triple-quotes-in-list.d/expected.tags",
    "content": "Bar\tinput.py\t/^class Bar():$/;\"\tc\nFoo\tinput.py\t/^class Foo():$/;\"\tc\na\tinput.py\t/^    a=((\"\"\"$/;\"\tv\tclass:Foo\n"
  },
  {
    "path": "Units/parser-python.r/triple-quotes-in-list.d/input.py",
    "content": "class Foo():\n    a=((\"\"\"\na)))\"\"\", 1, \"\"\", c\n    baz\n    \"\"\", {}\n        d), \"\"\"\n        \"\"\")\n\nclass Bar():\n    pass\n"
  },
  {
    "path": "Units/parser-python.r/triple-quotes.d/expected.tags",
    "content": "VAR1\tinput.py\t/^VAR1 = '''$/;\"\tv\nVAR2\tinput.py\t/^VAR2 = \"\"\" \"\" \"\"\\\\\" \"\\\\\"\" \\\\\"\\\\\"\\\\\"\\\\\\\\\"\"\"$/;\"\tv\nZZZ\tinput.py\t/^ZZZ = True$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/triple-quotes.d/input.py",
    "content": "\nVAR1 = '''\ndef bug1():\n    pass\n''\ndef bug2():\n    pass\n'''\n\nVAR2 = \"\"\" \"\" \"\"\\\" \"\\\"\" \\\"\\\"\\\"\\\\\"\"\"\n\nZZZ = True\n"
  },
  {
    "path": "Units/parser-python.r/type-statements.d/args.ctags",
    "content": "--sort=no\n--kinds-Python=+z\n--fields=+{signature}{typeref}\n"
  },
  {
    "path": "Units/parser-python.r/type-statements.d/expected.tags",
    "content": "MyList0\tinput.py\t/^MyList0 = list[str]$/;\"\tv\nMyList1\tinput.py\t/^MyList1: TypeAlias = list[str]$/;\"\tv\ttyperef:typename:TypeAlias\nMyList2\tinput.py\t/^type MyList2 = list[str]$/;\"\tv\ttyperef:typename:TypeAliasType\nListOrSet\tinput.py\t/^type ListOrSet[T] = list[T] | set[T]$/;\"\tv\ttyperef:typename:TypeAliasType\nx\tinput-0.py\t/^x = type(1)$/;\"\tv\nf\tinput-0.py\t/^def f(x, a):$/;\"\tf\tsignature:(x, a)\nx\tinput-0.py\t/^def f(x, a):$/;\"\tz\tfunction:f\tfile:\na\tinput-0.py\t/^def f(x, a):$/;\"\tz\tfunction:f\tfile:\ny\tinput-0.py\t/^y = f(type, ...)$/;\"\tv\ntype\tinput-0.py\t/^class type: ...$/;\"\tc\ntype\tinput-0.py\t/^def type(a): ...$/;\"\tf\tsignature:(a)\na\tinput-0.py\t/^def type(a): ...$/;\"\tz\tfunction:type\tfile:\ntype\tinput-0.py\t/^type = lambda t: ...$/;\"\tf\tsignature:(t)\nfn\tinput-0.py\t/^def fn(type, a): ...$/;\"\tf\tsignature:(type, a)\ntype\tinput-0.py\t/^def fn(type, a): ...$/;\"\tz\tfunction:fn\tfile:\na\tinput-0.py\t/^def fn(type, a): ...$/;\"\tz\tfunction:fn\tfile:\n"
  },
  {
    "path": "Units/parser-python.r/type-statements.d/input-0.py",
    "content": "# Derived from the comment in #4351 submitted by @mgedmin\nx = type(1)\ndef f(x, a):\n    return 1\ny = f(type, ...)\nclass type: ...\ndef type(a): ...\ntype = lambda t: ...\ndef fn(type, a): ...\n"
  },
  {
    "path": "Units/parser-python.r/type-statements.d/input.py",
    "content": "from typing import TypeAlias\n\nMyList0 = list[str]\nMyList1: TypeAlias = list[str]\ntype MyList2 = list[str]\ntype ListOrSet[T] = list[T] | set[T]\n"
  },
  {
    "path": "Units/parser-python.r/typehint.d/args.ctags",
    "content": "--sort=no\n--fields=+t\n--kinds-Python=+zl\n"
  },
  {
    "path": "Units/parser-python.r/typehint.d/expected.tags",
    "content": "T\tinput.py\t/^T = TypeVar('T')$/;\"\tv\nfunc1\tinput.py\t/^def func1(a: str, b: Callable[[int, int], T]) -> T:$/;\"\tf\ttyperef:typename:T\na\tinput.py\t/^def func1(a: str, b: Callable[[int, int], T]) -> T:$/;\"\tz\tfunction:func1\ttyperef:typename:str\tfile:\nb\tinput.py\t/^def func1(a: str, b: Callable[[int, int], T]) -> T:$/;\"\tz\tfunction:func1\ttyperef:typename:Callable[[int,int],T]\tfile:\nfunc2\tinput.py\t/^def func2 (a: str) -> \"a string\":$/;\"\tf\ttyperef:typename:\"a string\"\na\tinput.py\t/^def func2 (a: str) -> \"a string\":$/;\"\tz\tfunction:func2\ttyperef:typename:str\tfile:\ni\tinput.py\t/^i:int = 10$/;\"\tv\ttyperef:typename:int\nt\tinput.py\t/^t: Tuple[str, ...] = ()$/;\"\tv\ttyperef:typename:Tuple[str, ...]\nfunc3\tinput.py\t/^def func3 () -> 3 + i:$/;\"\tf\ttyperef:typename:3+i\nid\tinput.py\t/^id: Callable[[int], int] = lambda var1: var1$/;\"\tv\ttyperef:typename:Callable[[int], int]\tnameref:function:anonFunc100067ac0101\nanonFunc100067ac0101\tinput.py\t/^id: Callable[[int], int] = lambda var1: var1$/;\"\tf\nid2\tinput.py\t/^id2 = lambda var2: var2$/;\"\tf\nid3\tinput.py\t/^id3: \\\\$/;\"\tv\ttyperef:typename:Callable[[int], int]\tnameref:function:anonFunc100067ac0201\nanonFunc100067ac0201\tinput.py\t/^        lambda var3: var3$/;\"\tf\n"
  },
  {
    "path": "Units/parser-python.r/typehint.d/input.py",
    "content": "from typing import Callable, TypeVar, List, Tuple\n\nT = TypeVar('T')\n\ndef func1(a: str, b: Callable[[int, int], T]) -> T:\n    pass\n\ndef func2 (a: str) -> \"a string\":\n    return a\n\ni:int = 10\nt: Tuple[str, ...] = ()\n\ndef func3 () -> 3 + i:\n    return 0\n\n# The type \"Callable[[int], int]\" given to \"id\" is not used well.\n# See comments in parseVariable() of parser/python.c the difficulties.\nid: Callable[[int], int] = lambda var1: var1\nid2 = lambda var2: var2\n\nid3: \\\n    Callable[[int], int] = \\\n        lambda var3: var3\n"
  },
  {
    "path": "Units/parser-python.r/typehint.d/validator",
    "content": "python\n"
  },
  {
    "path": "Units/parser-python.r/underscore-numeric-literals.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-python.r/underscore-numeric-literals.d/expected.tags",
    "content": "amount\tinput.py\t/^amount = 10_000_000.0$/;\"\tv\naddr\tinput.py\t/^addr = 0xCAFE_F00D$/;\"\tv\nflags\tinput.py\t/^flags = 0b_0011_1111_0100_1110$/;\"\tv\nflags2\tinput.py\t/^flags2 = int('0b_1111_0000', 2)$/;\"\tv\n"
  },
  {
    "path": "Units/parser-python.r/underscore-numeric-literals.d/input.py",
    "content": "# grouping decimal numbers by thousands\namount = 10_000_000.0\n\n# grouping hexadecimal addresses by words\naddr = 0xCAFE_F00D\n\n# grouping bits into nibbles in a binary literal\nflags = 0b_0011_1111_0100_1110\n\n# same, for string conversions\nflags2 = int('0b_1111_0000', 2)\n"
  },
  {
    "path": "Units/parser-python.r/variable-annotations.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-python.r/variable-annotations.d/expected.tags",
    "content": "primes\tinput.py\t/^primes: List[int] = []$/;\"\tv\ttyperef:typename:List[int]\nsome_list\tinput.py\t/^some_list: List[int] = []  # variable with initial value$/;\"\tv\ttyperef:typename:List[int]\nsane_world\tinput.py\t/^    sane_world = True$/;\"\tv\nsane_world\tinput.py\t/^    sane_world = False$/;\"\tv\nt\tinput.py\t/^t: Tuple[int, ...] = (1, 2, 3)$/;\"\tv\ttyperef:typename:Tuple[int, ...]\nheader\tinput.py\t/^header, kind, body = message$/;\"\tv\nkind\tinput.py\t/^header, kind, body = message$/;\"\tv\nbody\tinput.py\t/^header, kind, body = message$/;\"\tv\nBasicStarship\tinput.py\t/^class BasicStarship:$/;\"\tc\ncaptain\tinput.py\t/^    captain: str = 'Picard'               # instance variable with default$/;\"\tv\tclass:BasicStarship\ttyperef:typename:str\nstats\tinput.py\t/^    stats: ClassVar[Dict[str, int]] = {}  # class variable$/;\"\tv\tclass:BasicStarship\ttyperef:typename:ClassVar[Dict[str, int]]\nStarship\tinput.py\t/^class Starship:$/;\"\tc\ncaptain\tinput.py\t/^    captain: str = 'Picard'$/;\"\tv\tclass:Starship\ttyperef:typename:str\nstats\tinput.py\t/^    stats: ClassVar[Dict[str, int]] = {}$/;\"\tv\tclass:Starship\ttyperef:typename:ClassVar[Dict[str, int]]\n__init__\tinput.py\t/^    def __init__(self, damage: int, captain: str = None):$/;\"\tm\tclass:Starship\nhit\tinput.py\t/^    def hit(self):$/;\"\tm\tclass:Starship\nenterprise_d\tinput.py\t/^enterprise_d = Starship(3000)$/;\"\tv\nCls\tinput.py\t/^class Cls:$/;\"\tc\nc\tinput.py\t/^c = Cls()$/;\"\tv\nd\tinput.py\t/^d = {}$/;\"\tv\nqualified\tinput.py\t/^qualified: typing.Any = 'anything'$/;\"\tv\ttyperef:typename:typing.Any\n"
  },
  {
    "path": "Units/parser-python.r/variable-annotations.d/input.py",
    "content": "# https://www.python.org/dev/peps/pep-0526/\n\nprimes: List[int] = []\n\ncaptain: str  # Note: no initial value!\n\n\nsome_number: int           # variable without initial value\nsome_list: List[int] = []  # variable with initial value\n\nsane_world: bool\nif 2+2 == 4:\n    sane_world = True\nelse:\n    sane_world = False\n\n# Tuple packing with variable annotation syntax\nt: Tuple[int, ...] = (1, 2, 3)\n\n# Tuple unpacking with variable annotation syntax\nheader: str\nkind: int\nbody: Optional[List[str]]\nheader, kind, body = message\n\n\nclass BasicStarship:\n    captain: str = 'Picard'               # instance variable with default\n    damage: int                           # instance variable without default\n    stats: ClassVar[Dict[str, int]] = {}  # class variable\n\nclass Starship:\n    captain: str = 'Picard'\n    damage: int\n    stats: ClassVar[Dict[str, int]] = {}\n\n    def __init__(self, damage: int, captain: str = None):\n        self.damage = damage\n        if captain:\n            self.captain = captain  # Else keep the default\n\n    def hit(self):\n        Starship.stats['hits'] = Starship.stats.get('hits', 0) + 1\n\nenterprise_d = Starship(3000)\nenterprise_d.stats = {} # Flagged as error by a type checker\nStarship.stats = {} # This is OK\n\n\nclass Cls:\n    pass\n\nc = Cls()\nc.x: int = 0  # Annotates c.x with int.\nc.y: int      # Annotates c.y with int.\n\nd = {}\nd['a']: int = 0  # Annotates d['a'] with int.\nd['b']: int      # Annotates d['b'] with int.\n\n\nqualified: typing.Any = 'anything'\n"
  },
  {
    "path": "Units/parser-qemuhx.r/disable.d/README",
    "content": "Taken from hx files in qemu source code tree.\n"
  },
  {
    "path": "Units/parser-qemuhx.r/disable.d/args.ctags",
    "content": "--sort=no\n--extras-QemuHX=-{funcmap}\n--fields=+E\n--language-force=QemuHX\n"
  },
  {
    "path": "Units/parser-qemuhx.r/disable.d/expected.tags",
    "content": "help\tinput.hx\t/^        .name       = \"help|?\",$/;\"\tc\n?\tinput.hx\t/^        .name       = \"help|?\",$/;\"\tc\nhelp\tinput.hx\t/^@item help or ? [@var{cmd}]$/;\"\ti\nversion\tinput.hx\t/^DEF(\"version\", 0, QEMU_OPTION_version,$/;\"\tc\n-version\tinput.hx\t/^@item -version$/;\"\ti\ncheck\tinput.hx\t/^DEF(\"check\", img_check,$/;\"\tc\ncheck\tinput.hx\t/^@item check [-q] [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @v/;\"\ti\ncreate\tinput.hx\t/^DEF(\"create\", img_create,$/;\"\tc\ncreate\tinput.hx\t/^@item create [-q] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}]$/;\"\ti\nquit\tinput.hx\t/^quit$/;\"\tq\n"
  },
  {
    "path": "Units/parser-qemuhx.r/disable.d/input.hx",
    "content": "HXCOMM Use DEFHEADING() to define headings in both help text and texi\nHXCOMM Text between STEXI and ETEXI are copied to texi version and\nHXCOMM discarded from C version\nHXCOMM DEF(command, args, callback, arg_string, help) is used to construct\nHXCOMM monitor commands\nHXCOMM HXCOMM can be used for comments, discarded from both texi and C\n\nSTEXI\n@table @option\nETEXI\n\n    {\n        .name       = \"help|?\",\n        .args_type  = \"name:s?\",\n        .params     = \"[cmd]\",\n        .help       = \"show the help\",\n        .mhandler.cmd = do_help_cmd,\n    },\n\nSTEXI\n@item help or ? [@var{cmd}]\n@findex help\nShow the help for all commands or just for command @var{cmd}.\nETEXI\n\nDEF(\"version\", 0, QEMU_OPTION_version,\n    \"-version        display version information and exit\\n\", QEMU_ARCH_ALL)\nSTEXI\n@item -version\n@findex -version\nDisplay version information and exit\nETEXI\n\nDEF(\"check\", img_check,\n    \"check [-q] [-f fmt] [--output=ofmt] [-r [leaks | all]] [-T src_cache] filename\")\nSTEXI\n@item check [-q] [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @var{filename}\nETEXI\n\nDEF(\"create\", img_create,\n    \"create [-q] [-f fmt] [-o options] filename [size]\")\nSTEXI\n@item create [-q] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}]\nETEXI\n\nSQMP\nquit\n----\n\nQuit the emulator.\n\nArguments: None.\n\nExample:\n\n-> { \"execute\": \"quit\" }\n<- { \"return\": {} }\n\nEQMP\n"
  },
  {
    "path": "Units/parser-qemuhx.r/enable.d/README",
    "content": "Taken from hx files in qemu source code tree.\n"
  },
  {
    "path": "Units/parser-qemuhx.r/enable.d/args.ctags",
    "content": "--sort=no\n--extras-QemuHX=+{funcmap}\n--fields=+E\n--language-force=QemuHX\n\n"
  },
  {
    "path": "Units/parser-qemuhx.r/enable.d/expected.tags",
    "content": "help\tinput.hx\t/^        .name       = \"help|?\",$/;\"\tc\n?\tinput.hx\t/^        .name       = \"help|?\",$/;\"\tc\nhelp\tinput.hx\t/^@item help or ? [@var{cmd}]$/;\"\ti\nversion\tinput.hx\t/^DEF(\"version\", 0, QEMU_OPTION_version,$/;\"\tc\n-version\tinput.hx\t/^@item -version$/;\"\ti\ncheck\tinput.hx\t/^DEF(\"check\", img_check,$/;\"\tc\ncheck\tinput.hx\t/^@item check [-q] [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @v/;\"\ti\ncreate\tinput.hx\t/^DEF(\"create\", img_create,$/;\"\tc\ncreate\tinput.hx\t/^@item create [-q] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}]$/;\"\ti\nquit\tinput.hx\t/^quit$/;\"\tq\nqmp_quit\tinput.hx\t/^quit$/;\"\tq\textras:funcmap\n"
  },
  {
    "path": "Units/parser-qemuhx.r/enable.d/input.hx",
    "content": "HXCOMM Use DEFHEADING() to define headings in both help text and texi\nHXCOMM Text between STEXI and ETEXI are copied to texi version and\nHXCOMM discarded from C version\nHXCOMM DEF(command, args, callback, arg_string, help) is used to construct\nHXCOMM monitor commands\nHXCOMM HXCOMM can be used for comments, discarded from both texi and C\n\nSTEXI\n@table @option\nETEXI\n\n    {\n        .name       = \"help|?\",\n        .args_type  = \"name:s?\",\n        .params     = \"[cmd]\",\n        .help       = \"show the help\",\n        .mhandler.cmd = do_help_cmd,\n    },\n\nSTEXI\n@item help or ? [@var{cmd}]\n@findex help\nShow the help for all commands or just for command @var{cmd}.\nETEXI\n\nDEF(\"version\", 0, QEMU_OPTION_version,\n    \"-version        display version information and exit\\n\", QEMU_ARCH_ALL)\nSTEXI\n@item -version\n@findex -version\nDisplay version information and exit\nETEXI\n\nDEF(\"check\", img_check,\n    \"check [-q] [-f fmt] [--output=ofmt] [-r [leaks | all]] [-T src_cache] filename\")\nSTEXI\n@item check [-q] [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @var{filename}\nETEXI\n\nDEF(\"create\", img_create,\n    \"create [-q] [-f fmt] [-o options] filename [size]\")\nSTEXI\n@item create [-q] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}]\nETEXI\n\nSQMP\nquit\n----\n\nQuit the emulator.\n\nArguments: None.\n\nExample:\n\n-> { \"execute\": \"quit\" }\n<- { \"return\": {} }\n\nEQMP\n"
  },
  {
    "path": "Units/parser-qemuhx.r/optscript-translation.d/README",
    "content": "input.hx is taken from qemu-0.15.0/qmp-commands.hx with much modification.\n"
  },
  {
    "path": "Units/parser-qemuhx.r/optscript-translation.d/args.ctags",
    "content": "--sort=no\n--extras-QemuHX=+{funcmap}\n--fields=+E\n--language-force=QemuHX\n"
  },
  {
    "path": "Units/parser-qemuhx.r/optscript-translation.d/expected.tags",
    "content": "inject-nmi\tinput.hx\t/^        .name       = \"inject-nmi\",$/;\"\tc\ninject-nmi\tinput.hx\t/^inject-nmi$/;\"\tq\nqmp_inject_nmi\tinput.hx\t/^inject-nmi$/;\"\tq\textras:funcmap\nsystem_reset\tinput.hx\t/^        .name       = \"system_reset\",$/;\"\tc\nsystem_reset\tinput.hx\t/^system_reset$/;\"\tq\nqmp_system_reset\tinput.hx\t/^system_reset$/;\"\tq\textras:funcmap\n"
  },
  {
    "path": "Units/parser-qemuhx.r/optscript-translation.d/input.hx",
    "content": "HXCOMM QMP dispatch table and documentation\nHXCOMM Text between SQMP and EQMP is copied to the QMP documention file and\nHXCOMM does not show up in the other formats.\n\nSQMP\n                        QMP Supported Commands\n                        ----------------------\n\nThis document describes all commands currently supported by QMP.\n\nMost of the time their usage is exactly the same as in the user Monitor, this\nmeans that any other document which also describe commands (the manpage,\nQEMU's manual, etc) can and should be consulted.\n\nQMP has two types of commands: regular and query commands. Regular commands\nusually change the Virtual Machine's state someway, while query commands just\nreturn information. The sections below are divided accordingly.\n\nIt's important to observe that all communication examples are formatted in\na reader-friendly way, so that they're easier to understand. However, in real\nprotocol usage, they're emitted as a single line.\n\nAlso, the following notation is used to denote data flow:\n\n-> data issued by the Client\n<- Server data response\n\nPlease, refer to the QMP specification (QMP/qmp-spec.txt) for detailed\ninformation on the Server command and response formats.\n\nNOTE: This document is temporary and will be replaced soon.\n\n1. Stability Considerations\n===========================\n\nThe current QMP command set (described in this file) may be useful for a\nnumber of use cases, however it's limited and several commands have bad\ndefined semantics, specially with regard to command completion.\n\nThese problems are going to be solved incrementally in the next QEMU releases\nand we're going to establish a deprecation policy for badly defined commands.\n\nIf you're planning to adopt QMP, please observe the following:\n\n    1. The deprecation policy will take efect and be documented soon, please\n       check the documentation of each used command as soon as a new release of\n       QEMU is available\n\n    2. DO NOT rely on anything which is not explicit documented\n\n    3. Errors, in special, are not documented. Applications should NOT check\n       for specific errors classes or data (it's strongly recommended to only\n       check for the \"error\" key)\n\n2. Regular Commands\n===================\n\nServer's responses in the examples below are always a success response, please\nrefer to the QMP specification for more details on error responses.\n\nEQMP\n\n    {\n        .name       = \"inject-nmi\",\n        .args_type  = \"\",\n        .params     = \"\",\n        .help       = \"\",\n        .user_print = monitor_user_noop,\n        .mhandler.cmd_new = do_inject_nmi,\n    },\n\nSQMP\ninject-nmi\n----------\n\nInject an NMI on guest's CPUs.\n\nArguments: None.\n\nExample:\n\n-> { \"execute\": \"inject-nmi\" }\n<- { \"return\": {} }\n\nNote: inject-nmi is only supported for x86 guest currently, it will\n      returns \"Unsupported\" error for non-x86 guest.\n\nEQMP\n\n    {\n        .name       = \"system_reset\",\n        .args_type  = \"\",\n        .params     = \"\",\n        .help       = \"reset the system\",\n        .user_print = monitor_user_noop,\n        .mhandler.cmd_new = do_system_reset,\n    },\n\nSQMP\nsystem_reset\n------------\n\nReset the system.\n\nArguments: None.\n\nExample:\n\n-> { \"execute\": \"system_reset\" }\n<- { \"return\": {} }\n\nEQMP\n"
  },
  {
    "path": "Units/parser-qemuhx.r/rst.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n"
  },
  {
    "path": "Units/parser-qemuhx.r/rst.d/expected.tags",
    "content": "version\tinput.hx\t/^        .name       = \"version\",$/;\"\tc\ncryptodev\tinput.hx\t/^        .name       = \"cryptodev\",$/;\"\tc\n"
  },
  {
    "path": "Units/parser-qemuhx.r/rst.d/input.hx",
    "content": "1HXCOMM Taken fom hmp-commands-info.hx in qemu\nHXCOMM\nHXCOMM See docs/devel/docs.rst for the format of this file.\nHXCOMM\nHXCOMM This file defines the contents of an array of HMPCommand structs\nHXCOMM which specify the name, behaviour and help text for HMP commands.\nHXCOMM Text between SRST and ERST is rST format documentation.\nHXCOMM HXCOMM can be used for comments, discarded from both rST and C.\nHXCOMM\nHXCOMM In this file, generally SRST fragments should have two extra\nHXCOMM spaces of indent, so that the documentation list item for \"info foo\"\nHXCOMM appears inside the documentation list item for the top level\nHXCOMM \"info\" documentation entry. The exception is the first SRST\nHXCOMM fragment that defines that top level entry.\n\nHXCOMM See docs/devel/docs.rst for the format of this file.\nHXCOMM\nHXCOMM This file defines the contents of an array of HMPCommand structs\nHXCOMM which specify the name, behaviour and help text for HMP commands.\nHXCOMM Text between SRST and ERST is rST format documentation.\nHXCOMM HXCOMM can be used for comments, discarded from both rST and C.\nHXCOMM\nHXCOMM In this file, generally SRST fragments should have two extra\nHXCOMM spaces of indent, so that the documentation list item for \"info foo\"\nHXCOMM appears inside the documentation list item for the top level\nHXCOMM \"info\" documentation entry. The exception is the first SRST\nHXCOMM fragment that defines that top level entry.\n\nSRST\n``info`` *subcommand*\n  Show various information about the system state.\n\nERST\n\n    {\n        .name       = \"version\",\n        .args_type  = \"\",\n        .params     = \"\",\n        .help       = \"show the version of QEMU\",\n        .cmd        = hmp_info_version,\n        .flags      = \"p\",\n    },\n\nSRST\n  ``info version``\n    Show the version of QEMU.\nERST\n\n    {\n        .name       = \"cryptodev\",\n        .args_type  = \"\",\n        .params     = \"\",\n        .help       = \"show the crypto devices\",\n        .cmd        = hmp_info_cryptodev,\n        .flags      = \"p\",\n    },\n\nSRST\n  ``info cryptodev``\n    Show the crypto devices.\nERST\n"
  },
  {
    "path": "Units/parser-qtmoc.r/simple-qt.d/args.ctags",
    "content": "--sort=no\n--kinds-C++=+p\n--fields=+lK\n"
  },
  {
    "path": "Units/parser-qtmoc.r/simple-qt.d/expected.tags",
    "content": "ColumnPreferencesFrame\tinput.h\t/^class ColumnPreferencesFrame : public QFrame$/;\"\tclass\tlanguage:C++\nmethod0\tinput.h\t/^    void method0(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot0\tinput.h\t/^    void slot0(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot0\tinput.h\t/^    void slot0(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot1\tinput.h\t/^    void slot1(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot1\tinput.h\t/^    void slot1(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot2\tinput.h\t/^    void slot2(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot2\tinput.h\t/^    void slot2(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot3\tinput.h\t/^    void slot3(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot3\tinput.h\t/^    void slot3(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot4\tinput.h\t/^    void slot4(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot4\tinput.h\t/^    void slot4(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot5\tinput.h\t/^    void slot5(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot5\tinput.h\t/^    void slot5(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nfield0\tinput.h\t/^  int field0;$/;\"\tmember\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:int\nmethod1\tinput.h\t/^  virtual void method1(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot6\tinput.h\t/^  void slot6(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot6\tinput.h\t/^  void slot6(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot7\tinput.h\t/^  void slot7(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot7\tinput.h\t/^  void slot7(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot8\tinput.h\t/^  void slot8(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot8\tinput.h\t/^  void slot8(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot9\tinput.h\t/^  void slot9(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot9\tinput.h\t/^  void slot9(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot10\tinput.h\t/^  void slot10(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot10\tinput.h\t/^  void slot10(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot11\tinput.h\t/^  void slot11(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nslot11\tinput.h\t/^  void slot11(void);$/;\"\tslot\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nfield1\tinput.h\t/^  int field1;$/;\"\tmember\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:int\nsignal0\tinput.h\t/^  void signal0(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nsignal0\tinput.h\t/^  void signal0(void);$/;\"\tsignal\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nsignal1\tinput.h\t/^  void signal1(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nsignal1\tinput.h\t/^  void signal1(void);$/;\"\tsignal\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nfield2\tinput.h\t/^  int field2;$/;\"\tmember\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:int\nmethod2\tinput.h\t/^  virtual void method2(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nsignal2\tinput.h\t/^  void signal2(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nsignal2\tinput.h\t/^  void signal2(void);$/;\"\tsignal\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nsignal3\tinput.h\t/^  void signal3(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nsignal3\tinput.h\t/^  void signal3(void);$/;\"\tsignal\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:void\nfield3\tinput.h\t/^  int field3;$/;\"\tmember\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:int\nmethod3\tinput.h\t/^  virtual void method3(void);$/;\"\tprototype\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:void\ntext\tinput.h\t/^  Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)$/;\"\tproperty\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:QString\nShowNonprinting\tinput.h\t/^  Q_PROPERTY( bool ShowNonprinting READ showsNonprinting WRITE setShowsNonprinting )$/;\"\tproperty\tlanguage:QtMoc\tclass:ColumnPreferencesFrame\ttyperef:typename:bool\nfield4\tinput.h\t/^  int field4;$/;\"\tmember\tlanguage:C++\tclass:ColumnPreferencesFrame\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-qtmoc.r/simple-qt.d/input.h",
    "content": "class ColumnPreferencesFrame : public QFrame\n{\n    Q_OBJECT\n    void method0(void);\n\nprivate slots:\n    void slot0(void);\n    void slot1(void);\n\npublic slots:\n    void slot2(void);\n    void slot3(void);\n\nQ_SLOTS:\n    void slot4(void);\n    void slot5(void);\n\nprivate:\n  int field0;\n\nprotected:\n  virtual void method1(void);\n\nprivate Q_SLOTS:\n  void slot6(void);\n  void slot7(void);\n\npublic Q_SLOTS:\n  void slot8(void);\n  void slot9(void);\n\nslots:\n  void slot10(void);\n  void slot11(void);\n\nprivate:\n  int field1;\n\nsignals:\n  void signal0(void);\n  void signal1(void);\n\nprivate:\n  int field2;\n\nprotected:\n  virtual void method2(void);\n\nQ_SIGNALS:\n  void signal2(void);\n  void signal3(void);\n\nprivate:\n  int field3;\n\nprotected:\n  virtual void method3(void);\n\n  Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)\n  Q_PROPERTY( bool ShowNonprinting READ showsNonprinting WRITE setShowsNonprinting )\n\nprivate:\n  int field4;\n\n};\n"
  },
  {
    "path": "Units/parser-quarto.r/simple.d/args.ctags",
    "content": "--sort=no\n--extras=+{guest}\n--fields=+{end}{line}{language}\n"
  },
  {
    "path": "Units/parser-quarto.r/simple.d/expected.tags",
    "content": "defun\tinput.qmd\t/^#| label: defun$/;\"\tl\tline:2\tlanguage:Quarto\tend:6\nf\tinput.qmd\t/^def f():$/;\"\tf\tline:4\tlanguage:Python\tend:5\n"
  },
  {
    "path": "Units/parser-quarto.r/simple.d/input.qmd",
    "content": "```{python}\n#| label: defun\n#| fig-cap: \"Define a function\"\ndef f():\n    pass\n```\n\n"
  },
  {
    "path": "Units/parser-quarto.r/unexecuted-block.d/args.ctags",
    "content": "--sort=no\n--extras=+{guest}\n--fields=+{end}{line}{language}\n"
  },
  {
    "path": "Units/parser-quarto.r/unexecuted-block.d/expected.tags",
    "content": "__anon53b260bc0100\tinput.qmd\t/^```{python}$/;\"\tl\tline:1\tlanguage:Quarto\tend:4\n__anon53b260bc0200\tinput.qmd\t/^```{{python}}$/;\"\tl\tline:6\tlanguage:Quarto\tend:9\nf\tinput.qmd\t/^def f():$/;\"\tf\tline:2\tlanguage:Python\tend:3\ng\tinput.qmd\t/^def g():$/;\"\tf\tline:7\tlanguage:Python\tend:8\n"
  },
  {
    "path": "Units/parser-quarto.r/unexecuted-block.d/input.qmd",
    "content": "```{python}\ndef f():\n    pass\n```\n\n```{{python}}\ndef g():\n    pass\n```\n"
  },
  {
    "path": "Units/parser-r.r/r-avoid-duplication.d/args.ctags",
    "content": "--sort=no\n--fields=+n\n--kinds-R=+z\n"
  },
  {
    "path": "Units/parser-r.r/r-avoid-duplication.d/expected.tags",
    "content": "x\tinput.r\t/^x <- 1$/;\"\tg\tline:1\nx\tinput.r\t/^x <- 2$/;\"\tg\tline:2\nf\tinput.r\t/^f <- function () {$/;\"\tf\tline:4\nx\tinput.r\t/^  x <- 3$/;\"\tv\tline:5\tfunction:f\nf\tinput.r\t/^f <- function () {$/;\"\tf\tline:10\nx\tinput.r\t/^  x <- 4$/;\"\tv\tline:11\tfunction:f\nf\tinput.r\t/^f <- function (x) {$/;\"\tf\tline:14\nx\tinput.r\t/^f <- function (x) {$/;\"\tz\tline:14\tfunction:f\nf\tinput.r\t/^f <- function (x) {$/;\"\tf\tline:18\nx\tinput.r\t/^f <- function (x) {$/;\"\tz\tline:18\tfunction:f\ng\tinput.r\t/^  g <- function () {$/;\"\tf\tline:19\tfunction:f\nx\tinput.r\t/^    x <- 6$/;\"\tv\tline:20\tfunction:f.g\nf\tinput.r\t/^f <- function (x) {$/;\"\tf\tline:24\nx\tinput.r\t/^f <- function (x) {$/;\"\tz\tline:24\tfunction:f\ng\tinput.r\t/^  g <- function () {$/;\"\tf\tline:25\tfunction:f\nx\tinput.r\t/^    x <- 6$/;\"\tv\tline:26\tfunction:f.g\n"
  },
  {
    "path": "Units/parser-r.r/r-avoid-duplication.d/input.r",
    "content": "x <- 1\nx <- 2\n\nf <- function () {\n  x <- 3\n}\n\n# Next one `f' is captured because `f` is function\n# though `f' is already defined in the global scope.\nf <- function () {\n  x <- 4\n}\n\nf <- function (x) {\n  x <- 5\n}\n\nf <- function (x) {\n  g <- function () {\n    x <- 6\n  }\n}\n\nf <- function (x) {\n  g <- function () {\n    x <- 6\n  }\n  # Following `g' are not captured because `g' is functionVar\n  # and already defined.\n  g <- function (x) {\n    x <- 7\n  }\n  g <- function () {\n    x <- 8\n  }\n  g <- function () {\n    y <- 0\n  }\n}\n"
  },
  {
    "path": "Units/parser-r.r/r-broken-input.d/README",
    "content": "Input files are broken. Therefore no expected.tags is here.\n\n"
  },
  {
    "path": "Units/parser-r.r/r-broken-input.d/input-0.r",
    "content": "library(+)\n"
  },
  {
    "path": "Units/parser-r.r/r-broken-input.d/input-1.r",
    "content": "source(\"abc\"\n"
  },
  {
    "path": "Units/parser-r.r/r-broken-input.d/input-2.r",
    "content": "library(+,\n"
  },
  {
    "path": "Units/parser-r.r/r-broken-input.d/input.r",
    "content": "#\n"
  },
  {
    "path": "Units/parser-r.r/r-dataframe.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-r.r/r-dataframe.d/expected.tags",
    "content": "L3\tinput.r\t/^L3 <- LETTERS[1:3]$/;\"\tg\nfac\tinput.r\t/^fac <- sample(L3, 10, replace = TRUE)$/;\"\tg\nd\tinput.r\t/^(d <- data.frame(x = 1, y = 1:10, fac = fac))$/;\"\td\nx\tinput.r\t/^(d <- data.frame(x = 1, y = 1:10, fac = fac))$/;\"\tn\tdataframe:d\ny\tinput.r\t/^(d <- data.frame(x = 1, y = 1:10, fac = fac))$/;\"\tn\tdataframe:d\nfac\tinput.r\t/^(d <- data.frame(x = 1, y = 1:10, fac = fac))$/;\"\tn\tdataframe:d\nanonDataFrame083788b40108\tinput.r\t/^data.frame(n=1, 1:10, sample(L3, 10, replace = TRUE))$/;\"\td\nn\tinput.r\t/^data.frame(n=1, 1:10, sample(L3, 10, replace = TRUE))$/;\"\tn\tdataframe:anonDataFrame083788b40108\ndd\tinput.r\t/^(dd <- cbind(d, char = I(letters[1:10])))$/;\"\tg\nd0\tinput.r\t/^(d0  <- d[, FALSE])   # data frame with 0 columns and 10 rows$/;\"\tg\nd.0\tinput.r\t/^(d.0 <- d[FALSE, ])   # <0 rows> data frame  (3 named cols)$/;\"\tg\nd00\tinput.r\t/^(d00 <- d0[FALSE, ])  # data frame with 0 columns and 0 rows$/;\"\tg\n"
  },
  {
    "path": "Units/parser-r.r/r-dataframe.d/input.r",
    "content": "# Taken from https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/data.frame\n# NOT RUN {\nL3 <- LETTERS[1:3]\nfac <- sample(L3, 10, replace = TRUE)\n(d <- data.frame(x = 1, y = 1:10, fac = fac))\n## The \"same\" with automatic column names:\ndata.frame(n=1, 1:10, sample(L3, 10, replace = TRUE))\n\nis.data.frame(d)\n\n## do not convert to factor, using I() :\n(dd <- cbind(d, char = I(letters[1:10])))\nrbind(class = sapply(dd, class), mode = sapply(dd, mode))\n\nstopifnot(1:10 == row.names(d))  # {coercion}\n\n(d0  <- d[, FALSE])   # data frame with 0 columns and 10 rows\n(d.0 <- d[FALSE, ])   # <0 rows> data frame  (3 named cols)\n(d00 <- d0[FALSE, ])  # data frame with 0 columns and 0 rows\n# }\n"
  },
  {
    "path": "Units/parser-r.r/r-dots.d/args.ctags",
    "content": "--sort=no\n--kinds-R=+z\n--fields=+{signature}\n"
  },
  {
    "path": "Units/parser-r.r/r-dots.d/expected.tags",
    "content": "f0\tinput.r\t/^f0 <- function (x0) {$/;\"\tf\tsignature:(x0)\nx0\tinput.r\t/^f0 <- function (x0) {$/;\"\tz\tfunction:f0\nf1\tinput.r\t/^f1 <- function (x1 = c(1, 2, 3)) {$/;\"\tf\tsignature:(x1 = c (1, 2, 3))\nx1\tinput.r\t/^f1 <- function (x1 = c(1, 2, 3)) {$/;\"\tz\tfunction:f1\nf2\tinput.r\t/^f2 <- function (x2, y2) {$/;\"\tf\tsignature:(x2, y2)\nx2\tinput.r\t/^f2 <- function (x2, y2) {$/;\"\tz\tfunction:f2\ny2\tinput.r\t/^f2 <- function (x2, y2) {$/;\"\tz\tfunction:f2\nf3\tinput.r\t/^f3 <- function (x3 = c(1, 2, 3), y3 = c(c(1,2,3))) {$/;\"\tf\tsignature:(x3 = c (1, 2, 3), y3 = c (c (1, 2, 3)))\nx3\tinput.r\t/^f3 <- function (x3 = c(1, 2, 3), y3 = c(c(1,2,3))) {$/;\"\tz\tfunction:f3\ny3\tinput.r\t/^f3 <- function (x3 = c(1, 2, 3), y3 = c(c(1,2,3))) {$/;\"\tz\tfunction:f3\nf4\tinput.r\t/^f4 <- function (x4 = c(1, 2, 3), y4 = c(c(1,2,3)), ...) {$/;\"\tf\tsignature:(x4 = c (1, 2, 3), y4 = c (c (1, 2, 3)), ...)\nx4\tinput.r\t/^f4 <- function (x4 = c(1, 2, 3), y4 = c(c(1,2,3)), ...) {$/;\"\tz\tfunction:f4\ny4\tinput.r\t/^f4 <- function (x4 = c(1, 2, 3), y4 = c(c(1,2,3)), ...) {$/;\"\tz\tfunction:f4\n"
  },
  {
    "path": "Units/parser-r.r/r-dots.d/input.r",
    "content": "f0 <- function (x0) {\n   1\n}\n\nf1 <- function (x1 = c(1, 2, 3)) {\n   1\n}\n\nf2 <- function (x2, y2) {\n   1\n}\n\nf3 <- function (x3 = c(1, 2, 3), y3 = c(c(1,2,3))) {\n   1\n}\n\nf4 <- function (x4 = c(1, 2, 3), y4 = c(c(1,2,3)), ...) {\n   1\n}\n\n"
  },
  {
    "path": "Units/parser-r.r/r-extended.d/args.ctags",
    "content": "--extras=+r\n"
  },
  {
    "path": "Units/parser-r.r/r-extended.d/expected.tags",
    "content": "\"mystuff.R\"\tinput.r\t/^  source(\"mystuff.R\");$/;\"\ts\n.First\tinput.r\t/^.First <- function() {$/;\"\tf\nMASS\tinput.r\t/^  library(MASS)                         # attach a package$/;\"\tl\n"
  },
  {
    "path": "Units/parser-r.r/r-extended.d/input.r",
    "content": "# From:\n# https://cran.r-project.org/doc/manuals/r-release/R-intro.html#Customizing-the-environment\n.First <- function() {\n  options(prompt=\"$ \", continue=\"+\\t\")  # $ is the prompt\n  options(digits=5, length=999)         # custom numbers and printout\n  x11()                                 # for graphics\n  par(pch = \"+\")                        # plotting character\n  #\n  # In the following function call, \"mystuff.R\" should be\n  # captured. However, it is not easy.\n  #\n  # source(file.path(Sys.getenv(\"HOME\"), \"R\", \"mystuff.R\"))\n  #                                       # my personal functions\n  library(MASS)                         # attach a package\n  source(\"mystuff.R\");\n}\n"
  },
  {
    "path": "Units/parser-r.r/r-external-entities.d/args.ctags",
    "content": "--extras=+r\n--fields=+r\n--sort=no\n\n"
  },
  {
    "path": "Units/parser-r.r/r-external-entities.d/expected.tags",
    "content": "\"./input-0.r\"\tinput.r\t/^source(\".\\/input-0.r\", echo = T)$/;\"\ts\troles:source\nsplines\tinput.r\t/^library(splines)            # attach package 'splines'$/;\"\tl\troles:library\nbase\tinput.r\t/^require(base)$/;\"\tl\troles:require\nx\tinput-0.r\t/^x <- 1$/;\"\tg\troles:def\n"
  },
  {
    "path": "Units/parser-r.r/r-external-entities.d/input-0.r",
    "content": "x <- 1\n"
  },
  {
    "path": "Units/parser-r.r/r-external-entities.d/input.r",
    "content": "source(\"./input-0.r\", echo = T)\nlibrary()\n\n# Taken from\n# https://stat.ethz.ch/R-manual/R-devel/library/base/html/library.html\nlibrary(lib.loc = .Library) # list all packages in the default library\nlibrary(help = splines)     # documentation on package 'splines'\nlibrary(splines)            # attach package 'splines'\n\nrequire(base)\n"
  },
  {
    "path": "Units/parser-r.r/r-list-indexing.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-r.r/r-list-indexing.d/expected.tags",
    "content": "x\tinput.r\t/^x <- NULL$/;\"\tg\ny\tinput.r\t/^x$x1 <- y <- 1:10$/;\"\tg\nz\tinput.r\t/^x$x2 <- z <- 0:9 -> a$/;\"\tg\na\tinput.r\t/^x$x2 <- z <- 0:9 -> a$/;\"\tg\nf\tinput.r\t/^f <- function () {$/;\"\tf\nX\tinput.r\t/^\tX <- NULL$/;\"\tv\tfunction:f\nY\tinput.r\t/^\tX$x1 <- Y <- 1:10$/;\"\tv\tfunction:f\nZ\tinput.r\t/^\tX$x2 <- Z <- 0:9 -> A$/;\"\tv\tfunction:f\nA\tinput.r\t/^\tX$x2 <- Z <- 0:9 -> A$/;\"\tv\tfunction:f\n"
  },
  {
    "path": "Units/parser-r.r/r-list-indexing.d/input.r",
    "content": "x <- NULL\nx$x1 <- y <- 1:10\nx$x2 <- z <- 0:9 -> a\n\nf <- function () {\n\tX <- NULL\n\tX$x1 <- Y <- 1:10\n\tX$x2 <- Z <- 0:9 -> A\n}\n\n"
  },
  {
    "path": "Units/parser-r.r/r-loop-counters.d/args.ctags",
    "content": "--kinds-R=+vz\n--sort=no\n"
  },
  {
    "path": "Units/parser-r.r/r-loop-counters.d/expected.tags",
    "content": "`%*%`\tinput.r\t/^`%*%` <- function (v, p) {$/;\"\tf\nv\tinput.r\t/^`%*%` <- function (v, p) {$/;\"\tz\tfunction:`%*%`\np\tinput.r\t/^`%*%` <- function (v, p) {$/;\"\tz\tfunction:`%*%`\nr\tinput.r\t/^    r <- 1$/;\"\tv\tfunction:`%*%`\ni\tinput.r\t/^        for (i in 1:p) {$/;\"\tv\tfunction:`%*%`\nj\tinput.r\t/^for (j in 1:3) {$/;\"\tg\n"
  },
  {
    "path": "Units/parser-r.r/r-loop-counters.d/input.r",
    "content": "# defining an operator\n`%*%` <- function (v, p) {\n    r <- 1\n    if (p == 1) {\n        r <- v\n    } else {\n        for (i in 1:p) {\n            r <- r * v\n        }\n    }\n    r\n}\n\nprint (c(2 %*% 10, 2%*%2, 2%*%3)[1:2])\n\n# j introduced as a global var.\nfor (j in 1:3) {\n    print (j)\n}\nprint (j)\n"
  },
  {
    "path": "Units/parser-r.r/r-nested-vector.d/args.ctags",
    "content": "--sort=no\n--fields=+Ke\n\n"
  },
  {
    "path": "Units/parser-r.r/r-nested-vector.d/expected.tags",
    "content": "i\tinput.r\t/^i = c(1,2)$/;\"\tvector\tend:1\nv\tinput.r\t/^v = c (100, 100)$/;\"\tvector\tend:2\nf\tinput.r\t/^f = function() {$/;\"\tfunction\tend:5\nx\tinput.r\t/^x <- 1$/;\"\tglobalVar\tend:6\n"
  },
  {
    "path": "Units/parser-r.r/r-nested-vector.d/input.r",
    "content": "i = c(1,2)\nv = c (100, 100)\nf = function() {\n    v[i[1]]\n}\nx <- 1\n"
  },
  {
    "path": "Units/parser-r.r/r-scope.d/args.ctags",
    "content": "--sort=no\n--fields-R=+{assignmentop}\n--fields=+eSn\n--kinds-R=+z\n"
  },
  {
    "path": "Units/parser-r.r/r-scope.d/expected.tags",
    "content": "c00\tinput.r\t/^c00 = 1$/;\"\tg\tline:1\tend:1\tassignmentop:=\nc01\tinput.r\t/^c01 <- 2$/;\"\tg\tline:2\tend:2\tassignmentop:<-\nc02\tinput.r\t/^c02 <<- 3$/;\"\tg\tline:3\tend:3\tassignmentop:<<-\nf0\tinput.r\t/^f0 <- function() {$/;\"\tf\tline:5\tsignature:()\tend:7\tassignmentop:<-\nr0\tinput.r\t/^   r0 <- c00 + c01 + c02$/;\"\tv\tline:6\tfunction:f0\tend:6\tassignmentop:<-\nf1\tinput.r\t/^f1 <- function(a1) {$/;\"\tf\tline:9\tsignature:(a1)\tend:11\tassignmentop:<-\na1\tinput.r\t/^f1 <- function(a1) {$/;\"\tz\tline:9\tfunction:f1\nr1\tinput.r\t/^   r1 = c00 + c01 + c02 + a1$/;\"\tv\tline:10\tfunction:f1\tend:10\tassignmentop:=\nf2\tinput.r\t/^f2 <- function(a20, a21) {$/;\"\tf\tline:13\tsignature:(a20, a21)\tend:15\tassignmentop:<-\na20\tinput.r\t/^f2 <- function(a20, a21) {$/;\"\tz\tline:13\tfunction:f2\na21\tinput.r\t/^f2 <- function(a20, a21) {$/;\"\tz\tline:13\tfunction:f2\nr2\tinput.r\t/^   r2 <<- c00 + c01 + c02 + a20 + a21$/;\"\tg\tline:14\tend:14\tassignmentop:<<-\nf4\tinput.r\t/^f4 <- function() c02 +$/;\"\tf\tline:17\tsignature:()\tend:19\tassignmentop:<-\nf5\tinput.r\t/^f5 <- function(a5) c(1,$/;\"\tf\tline:21\tsignature:(a5)\tend:24\tassignmentop:<-\na5\tinput.r\t/^f5 <- function(a5) c(1,$/;\"\tz\tline:21\tfunction:f5\nr5\tinput.r\t/^r5 <- 3,$/;\"\tv\tline:23\tfunction:f5\tend:23\tassignmentop:<-\nc50\tinput.r\t/^f5((c50 = 4))$/;\"\tg\tline:27\tend:27\tassignmentop:=\nc51\tinput.r\t/^f5(c51 <- 4)$/;\"\tg\tline:28\tend:28\tassignmentop:<-\nc52\tinput.r\t/^f5(c52 <<- 4)$/;\"\tg\tline:29\tend:29\tassignmentop:<<-\nc0\tinput-2.r\t/^{c0 = 1$/;\"\tg\tline:1\tend:1\tassignmentop:=\nd0\tinput-2.r\t/^   d0 <- 2}$/;\"\tg\tline:3\tend:3\tassignmentop:<-\nf0\tinput-2.r\t/^{f0 = 1;$/;\"\tg\tline:5\tend:5\tassignmentop:=\ng0\tinput-2.r\t/^   g0 <- 2}$/;\"\tg\tline:6\tend:6\tassignmentop:<-\nh0\tinput-2.r\t/^{h0 = 1; j0 <- 2}$/;\"\tg\tline:8\tend:8\tassignmentop:=\nj0\tinput-2.r\t/^{h0 = 1; j0 <- 2}$/;\"\tg\tline:8\tend:8\tassignmentop:<-\nf\tinput-2.r\t/^f <- function () {$/;\"\tf\tline:10\tsignature:()\tend:32\tassignmentop:<-\nc1\tinput-2.r\t/^    {c1 = 1$/;\"\tv\tline:11\tfunction:f\tend:11\tassignmentop:=\nd1\tinput-2.r\t/^       d1 <- 2}$/;\"\tv\tline:13\tfunction:f\tend:13\tassignmentop:<-\nf1\tinput-2.r\t/^    {f1 = 1;$/;\"\tv\tline:15\tfunction:f\tend:15\tassignmentop:=\ng1\tinput-2.r\t/^       g1 <- 2}$/;\"\tv\tline:16\tfunction:f\tend:16\tassignmentop:<-\nh1\tinput-2.r\t/^    {h1 = 1; j1 <- 2}$/;\"\tv\tline:18\tfunction:f\tend:18\tassignmentop:=\nj1\tinput-2.r\t/^    {h1 = 1; j1 <- 2}$/;\"\tv\tline:18\tfunction:f\tend:18\tassignmentop:<-\ng\tinput-2.r\t/^    g = function () {$/;\"\tf\tline:19\tfunction:f\tsignature:()\tend:28\tassignmentop:=\nc2\tinput-2.r\t/^\t{c2 = 1$/;\"\tv\tline:20\tfunction:f.g\tend:20\tassignmentop:=\nd2\tinput-2.r\t/^\t   d2 <- 2}$/;\"\tv\tline:22\tfunction:f.g\tend:22\tassignmentop:<-\nf2\tinput-2.r\t/^\t{f2 = 1;$/;\"\tv\tline:24\tfunction:f.g\tend:24\tassignmentop:=\ng2\tinput-2.r\t/^\t   g2 <- 2}$/;\"\tv\tline:25\tfunction:f.g\tend:25\tassignmentop:<-\nh2\tinput-2.r\t/^\t{h2 = 1; j2 <- 2}$/;\"\tv\tline:27\tfunction:f.g\tend:27\tassignmentop:=\nj2\tinput-2.r\t/^\t{h2 = 1; j2 <- 2}$/;\"\tv\tline:27\tfunction:f.g\tend:27\tassignmentop:<-\nh0\tinput-2.r\t/^    }; h0 = function () {$/;\"\tf\tline:28\tfunction:f\tsignature:()\tend:31\tassignmentop:=\nk\tinput-2.r\t/^\t   k <<- 3$/;\"\tg\tline:29\tend:29\tassignmentop:<<-\nf\tinput-3.r\t/^f <- function () {$/;\"\tf\tline:1\tsignature:()\tend:8\tassignmentop:<-\nd\tinput-3.r\t/^\td <- ($/;\"\tv\tline:2\tfunction:f\tend:4\tassignmentop:<-\na\tinput-3.r\t/^\t<- 4) + 5)$/;\"\tv\tline:4\tfunction:f\tend:4\tassignmentop:<-\nf\tinput-4.r\t/^f <- function () {$/;\"\tf\tline:1\tsignature:()\tend:3\tassignmentop:<-\nc0\tinput-4.r\t/^  {;c0 = 1;}$/;\"\tv\tline:2\tfunction:f\tend:2\tassignmentop:=\ng\tinput-4.r\t/^}; g <- function () {$/;\"\tf\tline:3\tsignature:()\tend:5\tassignmentop:<-\nc1\tinput-4.r\t/^  {c1 = 2}$/;\"\tv\tline:4\tfunction:g\tend:4\tassignmentop:=\n`f<<-`\tinput-5.r\t/^`f<<-` <- function() {$/;\"\tf\tline:1\tsignature:()\tend:3\tassignmentop:<-\nf\tinput-6.r\t/^f <- function (x, y) {$/;\"\tf\tline:1\tsignature:(x, y)\tend:3\tassignmentop:<-\nx\tinput-6.r\t/^f <- function (x, y) {$/;\"\tz\tline:1\tfunction:f\ny\tinput-6.r\t/^f <- function (x, y) {$/;\"\tz\tline:1\tfunction:f\nz\tinput-6.r\t/^} + y + (z <- 3) + 4$/;\"\tv\tline:3\tfunction:f\tend:3\tassignmentop:<-\na\tinput-7.r\t/^\ta <- function ()$/;\"\tf\tline:2\tsignature:()\tend:5\tassignmentop:<-\nb\tinput-7.r\t/^\tb <- function (x)$/;\"\tf\tline:7\tsignature:(x)\tend:8\tassignmentop:<-\nx\tinput-7.r\t/^\tb <- function (x)$/;\"\tz\tline:7\tfunction:b\nc\tinput-7.r\t/^\tc <- function (x)$/;\"\tf\tline:10\tsignature:(x)\tend:11\tassignmentop:<-\nx\tinput-7.r\t/^\tc <- function (x)$/;\"\tz\tline:10\tfunction:c\nf8\tinput-8.r\t/^f8 <- function () {$/;\"\tf\tline:2\tsignature:()\tend:3\tassignmentop:<-\ng8\tinput-8.r\t/^} -> g8$/;\"\tv\tline:3\tfunction:f8\tassignmentop:->\nx8\tinput-8.r\t/^x8 <- 1 -> y8$/;\"\tg\tline:6\tend:6\tassignmentop:<-\ny8\tinput-8.r\t/^x8 <- 1 -> y8$/;\"\tg\tline:6\tassignmentop:->\n"
  },
  {
    "path": "Units/parser-r.r/r-scope.d/input-2.r",
    "content": "{c0 = 1\n   ;\n   d0 <- 2}\n\n{f0 = 1;\n   g0 <- 2}\n\n{h0 = 1; j0 <- 2}\n\nf <- function () {\n    {c1 = 1\n       ;\n       d1 <- 2}\n\n    {f1 = 1;\n       g1 <- 2}\n\n    {h1 = 1; j1 <- 2}\n    g = function () {\n\t{c2 = 1\n\t   ;\n\t   d2 <- 2}\n\n\t{f2 = 1;\n\t   g2 <- 2}\n\n\t{h2 = 1; j2 <- 2}\n    }; h0 = function () {\n\t   k <<- 3\n    } +\n    5\n}\n"
  },
  {
    "path": "Units/parser-r.r/r-scope.d/input-3.r",
    "content": "f <- function () {\n\td <- (\n\t  1 + 2 + 3 + (a\n\t<- 4) + 5)\n\n\n\n}\n"
  },
  {
    "path": "Units/parser-r.r/r-scope.d/input-4.r",
    "content": "f <- function () {\n  {;c0 = 1;}\n}; g <- function () {\n  {c1 = 2}\n}\n"
  },
  {
    "path": "Units/parser-r.r/r-scope.d/input-5.r",
    "content": "`f<<-` <- function() {\n       1\n}\n"
  },
  {
    "path": "Units/parser-r.r/r-scope.d/input-6.r",
    "content": "f <- function (x, y) {\n  x + z\n} + y + (z <- 3) + 4\n\nf(1,2)\n"
  },
  {
    "path": "Units/parser-r.r/r-scope.d/input-7.r",
    "content": "({\n\ta <- function ()\n\t{\n\t\t1\n\t}\n\n\tb <- function (x)\n\t  a()\n\n\tc <- function (x)\n\t  a() * a()\n})\n\na() + b() + c()\n"
  },
  {
    "path": "Units/parser-r.r/r-scope.d/input-8.r",
    "content": "# g8 is not in the global scope.\nf8 <- function () {\n} -> g8\n\n# y8 is in the global scope.\nx8 <- 1 -> y8\n"
  },
  {
    "path": "Units/parser-r.r/r-scope.d/input.r",
    "content": "c00 = 1\nc01 <- 2\nc02 <<- 3\n\nf0 <- function() {\n   r0 <- c00 + c01 + c02\n}\n\nf1 <- function(a1) {\n   r1 = c00 + c01 + c02 + a1\n}\n\nf2 <- function(a20, a21) {\n   r2 <<- c00 + c01 + c02 + a20 + a21\n}\n\nf4 <- function() c02 +\n   c01 +\n   c02\n\nf5 <- function(a5) c(1,\n1,\nr5 <- 3,\na5)\n\nf5(a5 = 4)\nf5((c50 = 4))\nf5(c51 <- 4)\nf5(c52 <<- 4)\n"
  },
  {
    "path": "Units/parser-r.r/r-signature.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n--kinds-R=+z\n"
  },
  {
    "path": "Units/parser-r.r/r-signature.d/expected.tags",
    "content": "g\tinput.r\t/^g <- function (x = 1, \ty = 2  ,$/;\"\tf\tsignature:(x = 1, y = 2, z = 3)\nx\tinput.r\t/^g <- function (x = 1, \ty = 2  ,$/;\"\tz\tfunction:g\ny\tinput.r\t/^g <- function (x = 1, \ty = 2  ,$/;\"\tz\tfunction:g\nz\tinput.r\t/^  z = 3$/;\"\tz\tfunction:g\n"
  },
  {
    "path": "Units/parser-r.r/r-signature.d/input.r",
    "content": "# TODO: z msut be captured.\n# f <- function (x = (z<<-1), y = 1) {\n#   x + y\n# }\n# c(X=1, Y=2)\n\ng <- function (x = 1, \ty = 2  ,\n  z = 3\n  ) {\n  x + y + z\n}\n"
  },
  {
    "path": "Units/parser-r.r/r-simple.d/expected.tags",
    "content": "foo\tinput.r\t/^foo <- function () {$/;\"\tf\nx\tinput.r\t/^x <- 1$/;\"\tg\ny\tinput.r\t/^    y <- 2$/;\"\tv\tfunction:foo\n"
  },
  {
    "path": "Units/parser-r.r/r-simple.d/input.r",
    "content": "# Copuied from:\n# http://stackoverflow.com/questions/32206608/ctags-and-r-regex\nx <- 1\nfoo <- function () {\n    y <- 2\n    return(y)\n}\n"
  },
  {
    "path": "Units/parser-r.r/r-upper-scope-assignement.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-r.r/r-upper-scope-assignement.d/expected.tags",
    "content": "f\tinput.r\t/^f <- function () {$/;\"\tf\nx\tinput.r\t/^  x <<- 1$/;\"\tg\ny\tinput.r\t/^y <- 1$/;\"\tg\ng\tinput.r\t/^g <- function () {$/;\"\tf\nh\tinput.r\t/^h <- function () {$/;\"\tf\nh0\tinput.r\t/^  h0 <- function () {$/;\"\tf\tfunction:h\ni\tinput.r\t/^i <- function () {$/;\"\tf\nz\tinput.r\t/^  z <- 1$/;\"\tv\tfunction:i\ni0\tinput.r\t/^  i0 <- function () {$/;\"\tf\tfunction:i\nv\tinput.r\t/^    v <<- 13$/;\"\tg\nu\tinput.r\t/^    v ->> u$/;\"\tg\n"
  },
  {
    "path": "Units/parser-r.r/r-upper-scope-assignement.d/input.r",
    "content": "f <- function () {\n  x <<- 1\n}\nf()\nprint (x)\n\ny <- 1\ng <- function () {\n  y <<- 2\n}\ng()\nprint (y)\n\n\n\nh <- function () {\n  h0 <- function () {\n    y <<- 9\n  }\n  h0()\n}\nh()\nprint(y)\n\ni <- function () {\n  z <- 1\n  i0 <- function () {\n    z <<- 12\n    v <<- 13\n    v ->> u\n  }\n  i0()\n  # 12\n  print(z)\n}\ni()\n\n# The next `z' is undefined.\n# print(z)\n"
  },
  {
    "path": "Units/parser-r.r/r-uppercase-extension.d/expected.tags",
    "content": "foo\tinput.R\t/^foo <- function () {$/;\"\tf\nx\tinput.R\t/^x <- 1$/;\"\tg\ny\tinput.R\t/^    y <- 2$/;\"\tv\tfunction:foo\n"
  },
  {
    "path": "Units/parser-r.r/r-uppercase-extension.d/input.R",
    "content": "# Copuied from:\n# http://stackoverflow.com/questions/32206608/ctags-and-r-regex\nx <- 1\nfoo <- function () {\n    y <- 2\n    return(y)\n}\n"
  },
  {
    "path": "Units/parser-r.r/r-vector.d/args.ctags",
    "content": "--sort=no\n--fields=+{end}n\n"
  },
  {
    "path": "Units/parser-r.r/r-vector.d/expected.tags",
    "content": "v\tinput.r\t/^v = c(x = function() 1,$/;\"\tc\tline:1\tend:3\nx\tinput.r\t/^v = c(x = function() 1,$/;\"\tn\tline:1\tvector:v\tend:1\tconstructor:function\ny\tinput.r\t/^      y = 2,$/;\"\tn\tline:2\tvector:v\tend:2\nz\tinput.r\t/^      z = function() { 2 })$/;\"\tn\tline:3\tvector:v\tend:3\tconstructor:function\nw\tinput.r\t/^w = 0$/;\"\tg\tline:4\tend:4\nanonVec1725f6020206\tinput.r\t/^c(a = function(arg) 1)$/;\"\tc\tline:6\tend:6\na\tinput.r\t/^c(a = function(arg) 1)$/;\"\tn\tline:6\tvector:anonVec1725f6020206\tend:6\tconstructor:function\nz\tinput.r\t/^z = c(w <- 1, b = 1)$/;\"\tc\tline:7\tend:7\nb\tinput.r\t/^z = c(w <- 1, b = 1)$/;\"\tn\tline:7\tvector:z\tend:7\n"
  },
  {
    "path": "Units/parser-r.r/r-vector.d/input.r",
    "content": "v = c(x = function() 1,\n      y = 2,\n      z = function() { 2 })\nw = 0\nc()\nc(a = function(arg) 1)\nz = c(w <- 1, b = 1)\n"
  },
  {
    "path": "Units/parser-r6class.r/infinite-loop.d/input-0.r",
    "content": "e <- R6Class(public = list({}}\n"
  },
  {
    "path": "Units/parser-r6class.r/infinite-loop.d/input.r",
    "content": "# NOTHING HERE\n\n"
  },
  {
    "path": "Units/parser-r6class.r/r6-null-pointer-regression.d/args.ctags",
    "content": "--sort=no\n--fields=+ilaKSe{extras}\n--extras=-p\n\n"
  },
  {
    "path": "Units/parser-r6class.r/r6-null-pointer-regression.d/expected.tags",
    "content": "TestCase1\tinput.r\t/^TestCase1 <- R6::SomethingElse(\"TestCase1\")$/;\"\tglobalVar\tlanguage:R\tend:6\nTestCase2\tinput.r\t/^TestCase2 <- R6::$/;\"\tglobalVar\tlanguage:R\tend:10\nTestCase3\tinput.r\t/^TestCase3 <- R6::R6Clas(\"TestCase3\")$/;\"\tglobalVar\tlanguage:R\tend:12\n"
  },
  {
    "path": "Units/parser-r6class.r/r6-null-pointer-regression.d/input.r",
    "content": "# Test case for R6 parser null pointer regression\n# This triggers the error path in r6ReadRightSideSymbol that was causing\n# tokenDelete to be called with NULL pointers\n\n# Case 1: R6:: followed by something other than R6Class\nTestCase1 <- R6::SomethingElse(\"TestCase1\")\n\n# Case 2: Incomplete R6 namespace reference\nTestCase2 <- R6::\n\n# Case 3: R6 followed by :: but with syntax error\nTestCase3 <- R6::R6Clas(\"TestCase3\")\n\n"
  },
  {
    "path": "Units/parser-r6class.r/r6prefix.d/README",
    "content": "\n\tp\tinput.r\t/^            p <<- fp[-1]$/;\"\tglobalVar\tlanguage:R\n\nin expected.tags is questionable. The parser knows p is field of eppFP as printing\n\n\tp\tinput.r\t/^        p = NULL,$/;\"\tfield\tlanguage:R6Class\tclass:eppFP\n\nSo the parser can emit\n\n\tp\tinput.r\t/^            p <<- fp[-1]$/;\"\tfield\tlanguage:R\troles:lval\n"
  },
  {
    "path": "Units/parser-r6class.r/r6prefix.d/args.ctags",
    "content": "--sort=no\n--fields=+lK\n"
  },
  {
    "path": "Units/parser-r6class.r/r6prefix.d/expected.tags",
    "content": "eppFP\tinput.r\t/^eppFP <- R6::R6Class(\"eppfp\", class=F, cloneable=F, portable=F, lock_objects=F,$/;\"\tclass\tlanguage:R6Class\np\tinput.r\t/^        p = NULL,$/;\"\tfield\tlanguage:R6Class\tclass:eppFP\ninitialize\tinput.r\t/^        initialize = function(fp) {$/;\"\tmethod\tlanguage:R6Class\tclass:eppFP\tconstructor:function\np\tinput.r\t/^            p <<- fp[-1]$/;\"\tglobalVar\tlanguage:R\n"
  },
  {
    "path": "Units/parser-r6class.r/r6prefix.d/input.r",
    "content": "# Taken from https://github.com/kklot/eppasm/blob/1988/R/popClass.R\n# EPP parameter super class: later improve the generating of fp as well\n#' @importFrom methods new\neppFP <- R6::R6Class(\"eppfp\", class=F, cloneable=F, portable=F, lock_objects=F,\n    public = list(\n        p = NULL,\n        initialize = function(fp) {\n            p <<- fp[-1]\n            list2env(fp$ss, self)\n        }\n    )\n)\n"
  },
  {
    "path": "Units/parser-r6class.r/simple-r6class.d/args.ctags",
    "content": "--sort=no\n--fields=+ilaKSe{extras}\n"
  },
  {
    "path": "Units/parser-r6class.r/simple-r6class.d/expected.tags",
    "content": "Queue\tinput.r\t/^Queue <- R6Class(\"Queue\",$/;\"\tclass\tlanguage:R6Class\textras:subparser\tend:28\ninitialize\tinput.r\t/^    initialize = function(...) {$/;\"\tmethod\tlanguage:R6Class\tclass:Queue\taccess:public\tsignature:(...)\textras:subparser\tend:11\tconstructor:function\nitem\tinput.r\t/^      for (item in list(...)) {$/;\"\tfunctionVar\tlanguage:R\tmethod:Queue.initialize\nadd\tinput.r\t/^    add = function(x) {$/;\"\tmethod\tlanguage:R6Class\tclass:Queue\taccess:public\tsignature:(x)\textras:subparser\tend:15\tconstructor:function\nremove\tinput.r\t/^    remove = function() {$/;\"\tmethod\tlanguage:R6Class\tclass:Queue\taccess:public\tsignature:()\textras:subparser\tend:22\tconstructor:function\nhead\tinput.r\t/^      head <- private$queue[[1]]$/;\"\tfunctionVar\tlanguage:R\tmethod:Queue.remove\tend:19\nqueue\tinput.r\t/^    queue = list(),$/;\"\tfield\tlanguage:R6Class\tclass:Queue\taccess:private\textras:subparser\tend:25\tconstructor:list\nlength\tinput.r\t/^    length = function() base::length(private$queue)$/;\"\tmethod\tlanguage:R6Class\tclass:Queue\taccess:private\tsignature:()\textras:subparser\tend:26\tconstructor:function\nNumbers\tinput.r\t/^Numbers <- R6Class(\"Numbers\",$/;\"\tclass\tlanguage:R6Class\textras:subparser\tend:42\nx\tinput.r\t/^    x = 100$/;\"\tfield\tlanguage:R6Class\tclass:Numbers\taccess:public\textras:subparser\tend:33\nx2\tinput.r\t/^    x2 = function(value) {$/;\"\tactiveBindingFunc\tlanguage:R6Class\tclass:Numbers\taccess:public\tsignature:(value)\textras:subparser\tend:39\tconstructor:function\nrand\tinput.r\t/^    rand = function() rnorm(1)$/;\"\tactiveBindingFunc\tlanguage:R6Class\tclass:Numbers\taccess:public\tsignature:()\textras:subparser\tend:40\tconstructor:function\nHistoryQueue\tinput.r\t/^HistoryQueue <- R6Class(\"HistoryQueue\",$/;\"\tclass\tlanguage:R6Class\tinherits:Queue\textras:subparser\tend:64\nshow\tinput.r\t/^    show = function() {$/;\"\tmethod\tlanguage:R6Class\tclass:HistoryQueue\taccess:public\tsignature:()\textras:subparser\tend:52\tconstructor:function\ni\tinput.r\t/^      for (i in seq_along(private$queue)) {$/;\"\tfunctionVar\tlanguage:R\tmethod:HistoryQueue.show\nremove\tinput.r\t/^    remove = function() {$/;\"\tmethod\tlanguage:R6Class\tclass:HistoryQueue\taccess:public\tsignature:()\textras:subparser\tend:59\tconstructor:function\nlocal_noise\tinput.r\t/^      local_noise <- 1$/;\"\tfunctionVar\tlanguage:R\tmethod:HistoryQueue.remove\tend:57\nhead_idx\tinput.r\t/^    head_idx = 0$/;\"\tfield\tlanguage:R6Class\tclass:HistoryQueue\taccess:private\textras:subparser\tend:62\n"
  },
  {
    "path": "Units/parser-r6class.r/simple-r6class.d/input.r",
    "content": "# Taken from https://www.rdocumentation.org/packages/R6/versions/2.4.1/topics/R6Class\n\nlibrary(R6)\n\nQueue <- R6Class(\"Queue\",\n  public = list(\n    initialize = function(...) {\n      for (item in list(...)) {\n        self$add(item)\n      }\n    },\n    add = function(x) {\n      private$queue <- c(private$queue, list(x))\n      invisible(self)\n    },\n    remove = function() {\n      if (private$length() == 0) return(NULL)\n      # Can use private$queue for explicit access\n      head <- private$queue[[1]]\n      private$queue <- private$queue[-1]\n      head\n    }\n  ),\n  private = list(\n    queue = list(),\n    length = function() base::length(private$queue)\n  )\n)\n\n# Active bindings -------------------------------------------------\nNumbers <- R6Class(\"Numbers\",\n  public = list(\n    x = 100\n  ),\n  active = list(\n    x2 = function(value) {\n      if (missing(value)) return(self$x * 2)\n      else self$x <- value/2\n    },\n    rand = function() rnorm(1)\n  )\n)\n\nHistoryQueue <- R6Class(\"HistoryQueue\",\n  inherit = Queue,\n  public = list(\n    show = function() {\n      cat(\"Next item is at index\", private$head_idx + 1, \"\\n\")\n      for (i in seq_along(private$queue)) {\n        cat(i, \": \", private$queue[[i]], \"\\n\", sep = \"\")\n      }\n    },\n    remove = function() {\n      if (private$length() - private$head_idx == 0) return(NULL)\n      private$head_idx <<- private$head_idx + 1\n      # For testing extras: field\n      local_noise <- 1\n      private$queue[[private$head_idx]]\n    }\n  ),\n  private = list(\n    head_idx = 0\n  )\n)\n"
  },
  {
    "path": "Units/parser-rake.r/anonymous.d/args.ctags",
    "content": "--sort=no\n--fields=+E\n"
  },
  {
    "path": "Units/parser-rake.r/anonymous.d/expected.tags",
    "content": "benchmark\tinput.rake\t/^namespace :benchmark do$/;\"\tn\textras:subparser\ngenerate_scenario_tasks\tinput.rake\t/^  def generate_scenario_tasks(location, name)$/;\"\tf\nname_f22764bb0100\tinput.rake\t/^    task name => \"#{name}:run\"$/;\"\tt\tnamespace:benchmark\textras:subparser,anonymous\nname_f22764bb0201\tinput.rake\t/^    namespace name do$/;\"\tn\tnamespace:benchmark\textras:subparser,anonymous\nsetup\tinput.rake\t/^      task :setup do$/;\"\tt\tnamespace:benchmark:name_f22764bb0201\textras:subparser\ngenerate\tinput.rake\t/^      task :generate => :setup do$/;\"\tt\tnamespace:benchmark:name_f22764bb0201\textras:subparser\n"
  },
  {
    "path": "Units/parser-rake.r/anonymous.d/input.rake",
    "content": "# Based on from puppet/tasks/benchmark.rake\nnamespace :benchmark do\n  def generate_scenario_tasks(location, name)\n    desc File.read(File.join(location, 'description'))\n    task name => \"#{name}:run\"\n    # Load a BenchmarkerTask to handle config of the benchmark\n    task_handler_file = File.expand_path(File.join(location, 'benchmarker_task.rb'))\n    if File.exist?(task_handler_file)\n      require task_handler_file\n      run_args = BenchmarkerTask.run_args\n    else\n      run_args = []\n    end\n\n    namespace name do\n      task :setup do\n        ENV['ITERATIONS'] ||= '10'\n        ENV['SIZE'] ||= '100'\n        ENV['TARGET'] ||= Dir.mktmpdir(name)\n        ENV['TARGET'] = File.expand_path(ENV['TARGET'])\n\n        mkdir_p(ENV['TARGET'])\n\n        require File.expand_path(File.join(location, 'benchmarker.rb'))\n\n        @benchmark = Benchmarker.new(ENV['TARGET'], ENV['SIZE'].to_i)\n      end\n\n      task :generate => :setup do\n        @benchmark.generate\n        @benchmark.setup\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "Units/parser-rake.r/crash.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-rake.r/crash.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-rake.r/crash.d/expected.tags",
    "content": "name_fd1c49c30102\tinput.rake\t/^      file name            => [ name.ext('xml'),     \"doc\\/man\\/po4a\\/po\\/#{language}.po\" ]$/;\"\tf\n"
  },
  {
    "path": "Units/parser-rake.r/crash.d/input.rake",
    "content": "if c?(:PO4A_WORKS)\n  $available_languages[:manpages].each do |language|\n    $manpages.each do |manpage|\n      name = manpage.gsub(/man\\//, \"man/#{language}/\")\n      file name            => [ name.ext('xml'),     \"doc/man/po4a/po/#{language}.po\" ]\n      file name.ext('xml') => [ manpage.ext('.xml'), \"doc/man/po4a/po/#{language}.po\" ] do |t|\n        runq \"po4a\", \"#{manpage.ext('.xml')} (#{language})\", \"#{c(:PO4A_TRANSLATE)} #{c(:PO4A_TRANSLATE_FLAGS)} -m #{manpage.ext('.xml')} -p doc/man/po4a/po/#{language}.po -l #{t.name}\", :filter_output => $po4a_output_filter\n      end\n    end\n  end\nend\n# Taken from #3333.\n# Sami Farin (@Safari77) made this short test case from mkvtoolnix Rakefile.\n"
  },
  {
    "path": "Units/parser-rake.r/simple-rake.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--fields=+K\n"
  },
  {
    "path": "Units/parser-rake.r/simple-rake.d/expected.tags",
    "content": "name0\tinput.rake\t/^task :name0$/;\"\ttask\nname1\tinput.rake\t/^task name1: [:prereq1, :prereq2]$/;\"\ttask\nname2\tinput.rake\t/^task 'name2' => %w[prereq1 prereq2]$/;\"\ttask\nname3\tinput.rake\t/^task name3: %w[prereq1 prereq2]$/;\"\ttask\nname4\tinput.rake\t/^task name4: [:prereq1, :prereq2] do |t|$/;\"\ttask\nprog\tinput.rake\t/^file \"prog\" => [\"a.o\", \"b.o\"] do |t|$/;\"\tFile\ntestdata/examples/doc\tinput.rake\t/^directory \"testdata\\/examples\\/doc\"$/;\"\tdirectory\ncopy_files\tinput.rake\t/^multitask copy_files: %w[copy_src copy_doc copy_bin] do$/;\"\tmultitask\nmain\tinput.rake\t/^namespace \"main\" do$/;\"\tnamespace\nbuild\tinput.rake\t/^  task :build do$/;\"\ttask\tnamespace:main\nmain:build\tinput.rake\t/^  task :build do$/;\"\ttask\tnamespace:main\nsamples\tinput.rake\t/^namespace \"samples\" do$/;\"\tnamespace\nbuild\tinput.rake\t/^  task :build do$/;\"\ttask\tnamespace:samples\nsamples:build\tinput.rake\t/^  task :build do$/;\"\ttask\tnamespace:samples\nbuild\tinput.rake\t/^task build: %w[main:build samples:build]$/;\"\ttask\nwarnings\tinput.rake\t/^task(:warnings) do$/;\"\ttask\n"
  },
  {
    "path": "Units/parser-rake.r/simple-rake.d/input.rake",
    "content": "# lines are taken from https://ruby.github.io/rake/doc/rakefile_rdoc.html\n\n\ntask :name0\n\ntask name1: [:prereq1, :prereq2]\n\ntask 'name2' => %w[prereq1 prereq2]\n\ntask name3: %w[prereq1 prereq2]\n\ntask name4: [:prereq1, :prereq2] do |t|\n  # actions (may reference t)\nend\n\nfile \"prog\" => [\"a.o\", \"b.o\"] do |t|\n  sh \"cc -o #{t.name} #{t.prerequisites.join(' ')}\"\nend\n\ndirectory \"testdata/examples/doc\"\n\nmultitask copy_files: %w[copy_src copy_doc copy_bin] do\n  puts \"All Copies Complete\"\nend\n\n# TODO\nrule '.o' => ['.c'] do |t|\n  sh \"cc #{t.source} -c -o #{t.name}\"\nend\n\n# TODO\nrule( /\\.o$/ => [\n  proc {|task_name| task_name.sub(/\\.[^.]+$/, '.c') }\n]) do |t|\n  sh \"cc #{t.source} -c -o #{t.name}\"\nend\n\n# TODO\nimport \".depends.mf\"\n\nnamespace \"main\" do\n  task :build do\n    # Build the main program\n  end\nend\n\nnamespace \"samples\" do\n  task :build do\n    # Build the sample programs\n  end\nend\n\ntask build: %w[main:build samples:build]\n\ntask(:warnings) do\n  # Do something\nend\n"
  },
  {
    "path": "Units/parser-rake.r/xtasks.d/args.ctags",
    "content": "--sort=no\n--fields=+{typeref}K\n"
  },
  {
    "path": "Units/parser-rake.r/xtasks.d/expected.tags",
    "content": "spec\tinput.rake\t/^namespace :spec do$/;\"\tnamespace\nsetup\tinput.rake\t/^  task :setup => [\"app:test:vmdb:setup\"]$/;\"\ttask\tnamespace:spec\nspec\tinput.rake\t/^RSpec::Core::RakeTask.new(:spec => ['app:test:spec_deps', 'app:test:providers_common']) do |t|$/;\"\txtask\ttyperef:typename:RSpec::Core::RakeTask.new\ncucumber\tinput.rake\t/^Cucumber::Rake::Task.new(:cucumber)$/;\"\txtask\ttyperef:typename:Cucumber::Rake::Task.new\nspec\tinput.rake\t/^RSpec::Core::RakeTask.new(:spec) do |t|$/;\"\txtask\ttyperef:typename:RSpec::Core::RakeTask.new\nspec\tinput.rake\t/^namespace :spec do$/;\"\tnamespace\nui\tinput.rake\t/^  RSpec::Core::RakeTask.new(:ui) do |t|$/;\"\txtask\tnamespace:spec\ttyperef:typename:RSpec::Core::RakeTask.new\nrubocop\tinput.rake\t/^task :rubocop do$/;\"\ttask\nclobber\tinput.rake\t/^task :clobber do$/;\"\ttask\nrdoc\tinput.rake\t/^task :rdoc do$/;\"\ttask\nrelish\tinput.rake\t/^task :relish, :version do |_t, args|$/;\"\ttask\nrelish_staging\tinput.rake\t/^task :relish_staging do$/;\"\ttask\ndefault\tinput.rake\t/^task :default => [:spec, :cucumber, :rubocop]$/;\"\ttask\nverify_private_key_present\tinput.rake\t/^task :verify_private_key_present do$/;\"\ttask\nbuild\tinput.rake\t/^task :build => :verify_private_key_present$/;\"\ttask\ndefault\tinput-0.rake\t/^task :default => :test$/;\"\ttask\ntest\tinput-0.rake\t/^Rake::TestTask.new 'test' do |t|$/;\"\txtask\ttyperef:typename:Rake::TestTask.new\nspec:rcovSingle\tinput-1.rake\t/^RSpec::Core::RakeTask.new(:'spec:rcovSingle') do |t|$/;\"\txtask\ttyperef:typename:RSpec::Core::RakeTask.new\nspec:rcovDouble\tinput-1.rake\t/^RSpec::Core::RakeTask.new(:\"spec:rcovDouble\") do |t|$/;\"\txtask\ttyperef:typename:RSpec::Core::RakeTask.new\n"
  },
  {
    "path": "Units/parser-rake.r/xtasks.d/input-0.rake",
    "content": "# Taken from https://github.com/tmm1/ripper-tags/blob/master/Rakefile\ntask :default => :test\n\nrequire 'rake/testtask'\nRake::TestTask.new 'test' do |t|\n  t.options = '--use-color' if ENV['GITHUB_ACTIONS']\n  t.test_files = FileList['test/test_*.rb']\nend\n"
  },
  {
    "path": "Units/parser-rake.r/xtasks.d/input-1.rake",
    "content": "# https://raw.githubusercontent.com/apache/thrift/master/lib/rb/Rakefile\nRSpec::Core::RakeTask.new(:'spec:rcovSingle') do |t|\n  t.rspec_opts = ['--color', '--format d']\n  t.rcov = true\n  t.rcov_opts = ['--exclude', '^spec,/gems/']\nend\n\nRSpec::Core::RakeTask.new(:\"spec:rcovDouble\") do |t|\n  t.rspec_opts = ['--color', '--format d']\n  t.rcov = true\n  t.rcov_opts = ['--exclude', '^spec,/gems/']\nend\n\n# The next one may be extracted.\nRSpec::Core::RakeTask.new(:) do |t|\n  t.rspec_opts = ['--color', '--format d']\n  t.rcov = true\n  t.rcov_opts = ['--exclude', '^spec,/gems/']\nend\n"
  },
  {
    "path": "Units/parser-rake.r/xtasks.d/input.rake",
    "content": "# Taken from https://github.com/ManageIQ/manageiq-providers-vmware/blob/master/lib/tasks_private/spec.rake\nnamespace :spec do\n  desc \"Setup environment specs\"\n  task :setup => [\"app:test:vmdb:setup\"]\nend\n\ndesc \"Run all specs\"\nRSpec::Core::RakeTask.new(:spec => ['app:test:spec_deps', 'app:test:providers_common']) do |t|\n  EvmTestHelper.init_rspec_task(t)\nend\n\n# Taken from https://github.com/rspec/rspec-core/blob/main/Rakefile\nrequire \"bundler\"\nBundler.setup\nBundler::GemHelper.install_tasks\n\nrequire \"rake\"\nrequire \"yaml\"\n\nrequire \"rspec/core/rake_task\"\n\nrequire \"cucumber/rake/task\"\nCucumber::Rake::Task.new(:cucumber)\n\ndesc \"Run all examples\"\nRSpec::Core::RakeTask.new(:spec) do |t|\n  t.ruby_opts = %w[-w]\nend\n\nnamespace :spec do\n  desc \"Run ui examples\"\n  RSpec::Core::RakeTask.new(:ui) do |t|\n    t.ruby_opts = %w[-w]\n    t.rspec_opts = %w[--tag ui]\n  end\nend\n\ndesc 'Run RuboCop on the lib directory'\ntask :rubocop do\n  sh 'bundle exec rubocop lib'\nend\n\ndesc \"delete generated files\"\ntask :clobber do\n  sh 'find . -name \"*.rbc\" | xargs rm'\n  sh 'rm -rf pkg'\n  sh 'rm -rf tmp'\n  sh 'rm -rf coverage'\n  sh 'rm -rf .yardoc'\n  sh 'rm -rf doc'\nend\n\ndesc \"generate rdoc\"\ntask :rdoc do\n  sh \"yardoc\"\nend\n\nwith_changelog_in_features = lambda do |&block|\n  begin\n    sh \"cp Changelog.md features/\"\n    block.call\n  ensure\n    sh \"rm features/Changelog.md\"\n  end\nend\n\ndesc \"Push docs/cukes to relishapp using the relish-client-gem\"\ntask :relish, :version do |_t, args|\n  raise \"rake relish[VERSION]\" unless args[:version]\n\n  with_changelog_in_features.call do\n    if `relish versions rspec/rspec-core`.split.map(&:strip).include? args[:version]\n      puts \"Version #{args[:version]} already exists\"\n    else\n      sh \"relish versions:add rspec/rspec-core:#{args[:version]}\"\n    end\n    sh \"relish push rspec/rspec-core:#{args[:version]}\"\n  end\nend\n\ndesc \"Push to relish staging environment\"\ntask :relish_staging do\n  with_changelog_in_features.call do\n    sh \"relish push rspec-staging/rspec-core\"\n  end\nend\n\ntask :default => [:spec, :cucumber, :rubocop]\n\ntask :verify_private_key_present do\n  private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')\n  unless File.exist?(private_key)\n    raise \"Your private key is not present. This gem should not be built without it.\"\n  end\nend\n\ntask :build => :verify_private_key_present\n"
  },
  {
    "path": "Units/parser-raku.r/raku-bunch1.d/expected.tags",
    "content": "JSONPrettyActions\tinput.rakumod\t/^my class JSONPrettyActions {$/;\"\tc\nJSONPrettyGrammar\tinput.rakumod\t/^my grammar JSONPrettyGrammar {$/;\"\tg\nTOP\tinput.rakumod\t/^    method TOP($\\/) {$/;\"\tm\nTOP\tinput.rakumod\t/^    token TOP       { ^ \\\\s* [ <object> | <array> ] \\\\s* $ }$/;\"\tt\narray\tinput.rakumod\t/^    method array($\\/) {$/;\"\tm\narray\tinput.rakumod\t/^    rule array      { '[' ~ ']' <arraylist>    }$/;\"\tu\narraylist\tinput.rakumod\t/^    method arraylist($\\/) {$/;\"\tm\narraylist\tinput.rakumod\t/^    rule arraylist  {  <value> * % [ \\\\, ]        }$/;\"\tu\nfrom-json\tinput.rakumod\t/^sub from-json($text) {$/;\"\ts\nobject\tinput.rakumod\t/^    method object($\\/) {$/;\"\tm\nobject\tinput.rakumod\t/^    rule object     { '{' ~ '}' <pairlist>     }$/;\"\tu\npair\tinput.rakumod\t/^    method pair($\\/) {$/;\"\tm\npair\tinput.rakumod\t/^    rule pair       { <string> ':' <value>     }$/;\"\tu\npairlist\tinput.rakumod\t/^    method pairlist($\\/) {$/;\"\tm\npairlist\tinput.rakumod\t/^    rule pairlist   { <pair> * % \\\\,            }$/;\"\tu\nstr\tinput.rakumod\t/^    method str($\\/)               { make ~$\\/ }$/;\"\tm\nstr\tinput.rakumod\t/^    token str {$/;\"\tt\nstr_escape\tinput.rakumod\t/^    method str_escape($\\/) {$/;\"\tm\nstr_escape\tinput.rakumod\t/^    token str_escape {$/;\"\tt\nstring\tinput.rakumod\t/^    method string($\\/) {$/;\"\tm\nstring\tinput.rakumod\t/^    token string {$/;\"\tt\nto-json\tinput.rakumod\t/^multi sub to-json(Associative:D $d, :$indent = 0, :$first = 0) {$/;\"\ts\nto-json\tinput.rakumod\t/^multi sub to-json(Bool:D $d, :$indent = 0, :$first = 0) { (' ' x $first) ~ ($d ?? 'true' !! 'fal/;\"\ts\nto-json\tinput.rakumod\t/^multi sub to-json(Mu:D $s, :$indent = 0, :$first = 0) {$/;\"\ts\nto-json\tinput.rakumod\t/^multi sub to-json(Mu:U $, :$indent = 0, :$first = 0) { 'null' }$/;\"\ts\nto-json\tinput.rakumod\t/^multi sub to-json(Positional:D $d, :$indent = 0, :$first = 0) {$/;\"\ts\nto-json\tinput.rakumod\t/^multi sub to-json(Real:D $d, :$indent = 0, :$first = 0) { (' ' x $first) ~ ~$d }$/;\"\ts\nto-json\tinput.rakumod\t/^multi sub to-json(Str:D $d, :$indent = 0, :$first = 0) {$/;\"\ts\nto-json\tinput.rakumod\t/^multi sub to-json(Version:D $v, :$indent = 0, :$first = 0) { to-json(~$v, :$indent, :$first) }$/;\"\ts\nto-json\tinput.rakumod\t/^proto sub to-json($, :$indent = 0, :$first = 0) {*}$/;\"\ts\nvalue\tinput.rakumod\t/^    proto token value {*};$/;\"\tt\nvalue:sym\tinput.rakumod\t/^    method value:sym<array>($\\/)  { make $<array>.ast }$/;\"\tm\nvalue:sym\tinput.rakumod\t/^    method value:sym<false>($\\/)  { make Bool::False }$/;\"\tm\nvalue:sym\tinput.rakumod\t/^    method value:sym<null>($\\/)   { make Any }$/;\"\tm\nvalue:sym\tinput.rakumod\t/^    method value:sym<number>($\\/) { make +$\\/.Str }$/;\"\tm\nvalue:sym\tinput.rakumod\t/^    method value:sym<object>($\\/) { make $<object>.ast }$/;\"\tm\nvalue:sym\tinput.rakumod\t/^    method value:sym<string>($\\/) { make $<string>.ast }$/;\"\tm\nvalue:sym\tinput.rakumod\t/^    method value:sym<true>($\\/)   { make Bool::True  }$/;\"\tm\nvalue:sym\tinput.rakumod\t/^    token value:sym<array>   { <array>  };$/;\"\tt\nvalue:sym\tinput.rakumod\t/^    token value:sym<false>   { <sym>    };$/;\"\tt\nvalue:sym\tinput.rakumod\t/^    token value:sym<null>    { <sym>    };$/;\"\tt\nvalue:sym\tinput.rakumod\t/^    token value:sym<number> {$/;\"\tt\nvalue:sym\tinput.rakumod\t/^    token value:sym<object>  { <object> };$/;\"\tt\nvalue:sym\tinput.rakumod\t/^    token value:sym<string>  { <string> }$/;\"\tt\nvalue:sym\tinput.rakumod\t/^    token value:sym<true>    { <sym>    };$/;\"\tt\n"
  },
  {
    "path": "Units/parser-raku.r/raku-bunch1.d/input.rakumod",
    "content": "my class JSONPrettyActions {\n    method TOP($/) {\n        make $/.values.[0].ast;\n    };\n    method object($/) {\n        make $<pairlist>.ast.hash.item;\n    }\n\n    method pairlist($/) {\n        make $<pair>>>.ast.flat;\n    }\n\n    method pair($/) {\n        make $<string>.ast => $<value>.ast;\n    }\n\n    method array($/) {\n        make $<arraylist>.ast.item;\n    }\n\n    method arraylist($/) {\n        make [$<value>>>.ast];\n    }\n\n    method string($/) {\n        make $0.elems == 1\n            ?? ($0[0].<str> || $0[0].<str_escape>).ast\n            !! join '', $0.list.map({ (.<str> || .<str_escape>).ast });\n    }\n    method value:sym<number>($/) { make +$/.Str }\n    method value:sym<string>($/) { make $<string>.ast }\n    method value:sym<true>($/)   { make Bool::True  }\n    method value:sym<false>($/)  { make Bool::False }\n    method value:sym<null>($/)   { make Any }\n    method value:sym<object>($/) { make $<object>.ast }\n    method value:sym<array>($/)  { make $<array>.ast }\n\n    method str($/)               { make ~$/ }\n\n    my %esc = '\\\\' => \"\\\\\",\n              '/'  => \"/\",\n              'b'  => \"\\b\",\n              'n'  => \"\\n\",\n              't'  => \"\\t\",\n              'f'  => \"\\f\",\n              'r'  => \"\\r\",\n              '\"'  => \"\\\"\";\n    method str_escape($/) {\n        make $<xdigit> ?? chr(:16($<xdigit>.join)) !! %esc.AT-KEY(~$/);\n    }\n}\n\nmy grammar JSONPrettyGrammar {\n    token TOP       { ^ \\s* [ <object> | <array> ] \\s* $ }\n    rule object     { '{' ~ '}' <pairlist>     }\n    rule pairlist   { <pair> * % \\,            }\n    rule pair       { <string> ':' <value>     }\n    rule array      { '[' ~ ']' <arraylist>    }\n    rule arraylist  {  <value> * % [ \\, ]        }\n\n    proto token value {*};\n    token value:sym<number> {\n        '-'?\n        [ 0 | <[1..9]> <[0..9]>* ]\n        [ \\. <[0..9]>+ ]?\n        [ <[eE]> [\\+|\\-]? <[0..9]>+ ]?\n    }\n    token value:sym<true>    { <sym>    };\n    token value:sym<false>   { <sym>    };\n    token value:sym<null>    { <sym>    };\n    token value:sym<object>  { <object> };\n    token value:sym<array>   { <array>  };\n    token value:sym<string>  { <string> }\n\n    token string {\n        \\\" ~ \\\" ( <str> | \\\\ <str_escape> )*\n    }\n\n    token str {\n        <-[\"\\\\\\t\\n]>+\n    }\n\n    token str_escape {\n        <[\"\\\\/bfnrt]> | u <xdigit>**4\n    }\n}\n\nproto sub to-json($, :$indent = 0, :$first = 0) {*}\n\nmulti sub to-json(Version:D $v, :$indent = 0, :$first = 0) { to-json(~$v, :$indent, :$first) }\nmulti sub to-json(Real:D $d, :$indent = 0, :$first = 0) { (' ' x $first) ~ ~$d }\nmulti sub to-json(Bool:D $d, :$indent = 0, :$first = 0) { (' ' x $first) ~ ($d ?? 'true' !! 'false') }\nmulti sub to-json(Str:D $d, :$indent = 0, :$first = 0) {\n    (' ' x $first) ~ '\"'\n    ~ $d.trans(['\"', '\\\\', \"\\b\", \"\\f\", \"\\n\", \"\\r\", \"\\t\"]\n            => ['\\\"', '\\\\\\\\', '\\b', '\\f', '\\n', '\\r', '\\t'])\\\n            .subst(/<-[\\c32..\\c126]>/, { ord(~$_).fmt('\\u%04x') }, :g)\n    ~ '\"'\n}\nmulti sub to-json(Positional:D $d, :$indent = 0, :$first = 0) {\n    (' ' x $first) ~ \"\\[\"\n            ~ ($d ?? $d.map({ \"\\n\" ~ to-json($_, :indent($indent + 2), :first($indent + 2)) }).join(\",\") ~ \"\\n\" ~ (' ' x $indent) !! ' ')\n            ~ ']';\n}\nmulti sub to-json(Associative:D $d, :$indent = 0, :$first = 0) {\n    (' ' x $first) ~ \"\\{\"\n            ~ ($d ?? $d.map({ \"\\n\" ~ to-json(.key, :first($indent + 2)) ~ ' : ' ~ to-json(.value, :indent($indent + 2)) }).join(\",\") ~ \"\\n\" ~ (' ' x $indent) !! ' ')\n            ~ '}';\n}\n\nmulti sub to-json(Mu:U $, :$indent = 0, :$first = 0) { 'null' }\nmulti sub to-json(Mu:D $s, :$indent = 0, :$first = 0) {\n    die \"Can't serialize an object of type \" ~ $s.WHAT.perl\n}\n\nsub from-json($text) {\n    my $a = JSONPrettyActions.new();\n    my $o = JSONPrettyGrammar.parse($text, :actions($a));\n    $o.ast;\n}\n"
  },
  {
    "path": "Units/parser-raku.r/raku-bunch2.d/expected.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tDarren Hiebert\t/dhiebert@users.sourceforge.net/\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t//\n!_TAG_PROGRAM_URL\thttps://github.com/universal-ctags/ctags\t/official site/\n!_TAG_PROGRAM_VERSION\tDevelopment\t//\nBUILD\tinput.rakumod\t/^        submethod BUILD(:&!setup) { }$/;\"\tb\nChannel\tinput.rakumod\t/^    method Channel(Supply:D:) {$/;\"\tm\nOnSupply\tinput.rakumod\t/^    my class OnSupply does Supply {$/;\"\tc\nPromise\tinput.rakumod\t/^    method Promise(Supply:D:) {$/;\"\tm\nSupply\tinput.rakumod\t/^    method Supply(Supply:) { self }$/;\"\tm\nSupply\tinput.rakumod\t/^my role Supply {$/;\"\tr\nSupplyOperations\tinput.rakumod\t/^my class SupplyOperations is repr('Uninstantiable') { ... }$/;\"\tc\nTap\tinput.rakumod\t/^my class Tap {$/;\"\tc\nX::Supply::Combinator\tinput.rakumod\t/^my class X::Supply::Combinator is Exception {$/;\"\tc\nX::Supply::On::BadSetup\tinput.rakumod\t/^my class X::Supply::On::BadSetup is Exception {$/;\"\tc\nX::Supply::On::NoEmit\tinput.rakumod\t/^my class X::Supply::On::NoEmit is Exception {$/;\"\tc\nact\tinput.rakumod\t/^    method act(Supply:D: &actor) {$/;\"\tm\nadd\tinput.rakumod\t/^            sub add ($source, $what, $index?) {$/;\"\ts\nadd_source\tinput.rakumod\t/^        method !add_source($/;\"\tm\nbatch\tinput.rakumod\t/^    method batch(Supply:D $self: :$elems, :$seconds ) {$/;\"\tm\ncategorize\tinput.rakumod\t/^    multi method categorize(Supply:D: %mapper )  {$/;\"\tm\ncategorize\tinput.rakumod\t/^    multi method categorize(Supply:D: &mapper )  {$/;\"\tm\ncategorize\tinput.rakumod\t/^    multi method categorize(Supply:D: @mapper )  {$/;\"\tm\ncategorize\tinput.rakumod\t/^    proto method categorize (|) { * }$/;\"\tm\nclassify\tinput.rakumod\t/^    multi method classify(Supply:D: %mapper )  {$/;\"\tm\nclassify\tinput.rakumod\t/^    multi method classify(Supply:D: &mapper )  {$/;\"\tm\nclassify\tinput.rakumod\t/^    multi method classify(Supply:D: @mapper )  {$/;\"\tm\nclose\tinput.rakumod\t/^    method close (Tap:D:) { $!supply.close(self) }$/;\"\tm\nclose\tinput.rakumod\t/^    multi method close(Supply:D: Tap $t) {$/;\"\tm\nclose\tinput.rakumod\t/^    multi method close(Supply:D:) { self.close($_) for self.tappers }$/;\"\tm\nclose\tinput.rakumod\t/^    proto method close(|) { * }$/;\"\tm\ndelay\tinput.rakumod\t/^    method delay(Supply:D: $time, :$scheduler = $*SCHEDULER) {$/;\"\tm\ndelayed\tinput.rakumod\t/^    method delayed(Supply:D: $time, :$scheduler = $*SCHEDULER) {$/;\"\tm\ndo\tinput.rakumod\t/^    method do(Supply:D $self: &side_effect) {$/;\"\tm\ndone\tinput.rakumod\t/^        method done() {$/;\"\tm\ndone\tinput.rakumod\t/^    method done(Supply:D:) {$/;\"\tm\nelems\tinput.rakumod\t/^    method elems(Supply:D $self: $seconds? ) {$/;\"\tm\nemit\tinput.rakumod\t/^        method emit(\\\\msg) {$/;\"\tm\nemit\tinput.rakumod\t/^    method emit(Supply:D: \\\\msg) {$/;\"\tm\nflat\tinput.rakumod\t/^    method flat(Supply:D: )              { SupplyOperations.flat(self) }$/;\"\tm\nflush\tinput.rakumod\t/^                sub flush {$/;\"\ts\nflush\tinput.rakumod\t/^                sub flush() {$/;\"\ts\nfor\tinput.rakumod\t/^    method for(Supply:U: |c) {$/;\"\tm\nfrom-list\tinput.rakumod\t/^    method from-list(Supply:U: |c)       { SupplyOperations.from-list(|c) }$/;\"\tm\ngrab\tinput.rakumod\t/^    method grab(Supply:D $self: &when_done) {$/;\"\tm\ngrep\tinput.rakumod\t/^    method grep(Supply:D: Mu $test)      { SupplyOperations.grep(self, $test) }$/;\"\tm\ninterval\tinput.rakumod\t/^    method interval(Supply:U: |c)        { SupplyOperations.interval(|c) }$/;\"\tm\nlast\tinput.rakumod\t/^    method last(Supply:D $self: Int $number = 1) {  # should be Natural$/;\"\tm\nlines\tinput.rakumod\t/^    method lines(Supply:D $self: :$chomp = True ) {$/;\"\tm\nlist\tinput.rakumod\t/^    method list(Supply:D:) {$/;\"\tm\nlive\tinput.rakumod\t/^        method live { $!live }$/;\"\tm\nlive\tinput.rakumod\t/^    method live(Supply:D:) { True };$/;\"\tm\nmap\tinput.rakumod\t/^    method map(Supply:D: &mapper)        { SupplyOperations.map(self, &mapper) }$/;\"\tm\nmax\tinput.rakumod\t/^    method max(Supply:D $self: &by = &infix:<cmp>) {$/;\"\tm\nmerge\tinput.rakumod\t/^    method merge(*@s) {$/;\"\tm\nmessage\tinput.rakumod\t/^    method message() { \"Can only use $!combinator to combine defined Supply objects\" }$/;\"\tm\nmessage\tinput.rakumod\t/^    method message() {$/;\"\tm\nmigrate\tinput.rakumod\t/^    method migrate(Supply:D: )           { SupplyOperations.migrate(self) }$/;\"\tm\nmin\tinput.rakumod\t/^    method min(Supply:D $self: &by = &infix:<cmp>) {$/;\"\tm\nminmax\tinput.rakumod\t/^    method minmax(Supply:D $self: &by = &infix:<cmp>) {$/;\"\tm\nmore\tinput.rakumod\t/^    method more(Supply:D: \\\\msg) {$/;\"\tm\nnext-batch\tinput.rakumod\t/^                sub next-batch() {$/;\"\ts\non\tinput.rakumod\t/^sub on(&setup) {$/;\"\ts\non-demand\tinput.rakumod\t/^    method on-demand(Supply:U: |c)       { SupplyOperations.on-demand(|c) }$/;\"\tm\non_demand\tinput.rakumod\t/^    method on_demand(Supply:U: |c)       {$/;\"\tm\nquit\tinput.rakumod\t/^        method quit($ex) {$/;\"\tm\nquit\tinput.rakumod\t/^    method quit(Supply:D: $ex) {$/;\"\tm\nreduce\tinput.rakumod\t/^    method reduce(Supply:D $self: &with) {$/;\"\tm\nreverse\tinput.rakumod\t/^    method reverse(Supply:D:)                 { self.grab( {.reverse} ) }$/;\"\tm\nrotor\tinput.rakumod\t/^    multi method rotor(Supply:D $self: *@cycle, :$partial) {$/;\"\tm\nrotor\tinput.rakumod\t/^    multi method rotor(Supply:D:) {$/;\"\tm\nrotor\tinput.rakumod\t/^    proto method rotor(|) {*}$/;\"\tm\nschedule-on\tinput.rakumod\t/^    method schedule-on(Supply:D: Scheduler $scheduler) {$/;\"\tm\nschedule_on\tinput.rakumod\t/^    method schedule_on(Supply:D: Scheduler $scheduler) {$/;\"\tm\nsort\tinput.rakumod\t/^    method sort(Supply:D: &by = &infix:<cmp>) { self.grab( {.sort(&by)} ) }$/;\"\tm\nsquish\tinput.rakumod\t/^    method squish(Supply:D $self: :&as, :&with is copy) {$/;\"\tm\nstable\tinput.rakumod\t/^    method stable(Supply:D: $time, :$scheduler = $*SCHEDULER) {$/;\"\tm\nstart\tinput.rakumod\t/^    method start(Supply:D: &startee)     { SupplyOperations.start(self, &startee) }$/;\"\tm\ntap\tinput.rakumod\t/^        method tap(|c) {$/;\"\tm\ntap\tinput.rakumod\t/^    method tap(Supply:D: &emit = -> $ { }, :&done,:&quit={die $_},:&closing) {$/;\"\tm\ntappers\tinput.rakumod\t/^    method tappers(Supply:D:) {$/;\"\tm\ntaps\tinput.rakumod\t/^    method taps(Supply:D:) { +@!tappers }$/;\"\tm\nuniq\tinput.rakumod\t/^    method uniq(Supply:D: |c) {$/;\"\tm\nunique\tinput.rakumod\t/^    method unique(Supply:D $self: :&as, :&with, :$expires) {$/;\"\tm\nwait\tinput.rakumod\t/^    method wait(Supply:D:) {$/;\"\tm\nwords\tinput.rakumod\t/^    method words(Supply:D $self:) {$/;\"\tm\nzip\tinput.rakumod\t/^    method zip(*@s, :&with is copy = &[,]) {$/;\"\tm\nzip-latest\tinput.rakumod\t/^    method zip-latest(*@s, :&with is copy = &[,], :$initial ) {$/;\"\tm\n"
  },
  {
    "path": "Units/parser-raku.r/raku-bunch2.d/input.rakumod",
    "content": "# Anything that can be subscribed to does this role. It provides the basic\n# supply management infrastructure, as well as various coercions that\n# turn Supply-like things into something else and convenience forms of calls\n# to SupplyOperations.\n\nmy class SupplyOperations is repr('Uninstantiable') { ... }\nmy class X::Supply::Combinator is Exception {\n    has $.combinator;\n    method message() { \"Can only use $!combinator to combine defined Supply objects\" }\n}\n\nmy class Tap {\n    has &.emit;\n    has &.done;\n    has &.quit;\n    has &.closing;\n    has $.supply;\n\n    method close (Tap:D:) { $!supply.close(self) }\n}\n\nmy role Supply {\n    has $!tappers_lock = Lock.new;\n    has @!tappers;\n    has $!been_tapped;\n    has @!paused;\n\n    method tap(Supply:D: &emit = -> $ { }, :&done,:&quit={die $_},:&closing) {\n        my $tap = Tap.new(:&emit, :&done, :&quit, :&closing, :supply(self));\n        $!tappers_lock.protect({\n            @!tappers.push($tap);\n            if @!paused -> \\todo {\n                $tap.emit().($_) for todo;\n                @!paused = ();\n            }\n            $!been_tapped = True;\n        });\n        $tap\n    }\n\n    proto method close(|) { * }\n    multi method close(Supply:D:) { self.close($_) for self.tappers }\n    multi method close(Supply:D: Tap $t) {\n        my $found;\n        $!tappers_lock.protect({\n            @!tappers .= grep( { $_ === $t ?? !($found = True) !! True } );\n        });\n        if $t.closing -> &closing {\n            closing();\n        }\n        $found // False;\n    }\n\n    method tappers(Supply:D:) {\n        # Shallow clone to provide safe snapshot.\n        my @tappers;\n        $!tappers_lock.protect({ @tappers = @!tappers });\n        @tappers\n    }\n\n    method emit(Supply:D: \\msg) {\n        if self.tappers -> \\tappers {\n            .emit().(msg) for tappers;\n        }\n        elsif !$!been_tapped {\n            $!tappers_lock.protect({ @!paused.push: msg });\n        }\n        Nil;\n    }\n\n    method more(Supply:D: \\msg) {\n        DEPRECATED('emit', |<2014.10 2015.09>);\n        self.emit(msg);\n    }\n\n    method done(Supply:D:) {\n        for self.tappers -> $t {\n            my $l = $t.done();\n            $l() if $l;\n        }\n        Nil;\n    }\n\n    method quit(Supply:D: $ex) {\n        for self.tappers -> $t {\n            my $f = $t.quit();\n            $f($ex) if $f;\n        }\n        Nil;\n    }\n\n    method taps(Supply:D:) { +@!tappers }\n    method live(Supply:D:) { True };\n\n    method Supply(Supply:) { self }\n    method Channel(Supply:D:) {\n        my $c = Channel.new();\n        self.tap( -> \\val { $c.send(val) },\n          done => { $c.close },\n          quit => -> $ex { $c.quit($ex) });\n        $c\n    }\n\n    method Promise(Supply:D:) {\n        my $l = Lock.new;\n        my $p = Promise.new;\n        my $v = $p.vow;\n        my $t = self.tap(\n          -> \\val {\n              $l.protect( {\n                  if $p.status == Planned {\n                      $v.keep(val);\n                      $t.close()\n                  }\n              } );\n          },\n          done => { $v.break(\"No value received\") },\n          quit => -> \\ex {\n              $l.protect( {\n                  if $p.status == Planned {\n                      $v.break(ex);\n                      $t.close()\n                  }\n              } );\n          },\n        );\n        $p\n    }\n\n    method wait(Supply:D:) {\n        my $l = Lock.new;\n        my $p = Promise.new;\n        my $t = self.tap( -> \\val {},\n          done => {\n              $l.protect( {\n                  if $p.status == Planned {\n                      $p.keep(True);\n                      $t.close()\n                  }\n              } );\n          },\n          quit => -> \\ex {\n              $l.protect( {\n                  if $p.status == Planned {\n                      $p.break(ex);\n                      $t.close()\n                  }\n              } );\n          },\n        );\n        $p.result\n    }\n\n    method list(Supply:D:) {\n        # Use a Channel to handle any asynchrony.\n        self.Channel.list;\n    }\n\n    method on-demand(Supply:U: |c)       { SupplyOperations.on-demand(|c) }\n    method from-list(Supply:U: |c)       { SupplyOperations.from-list(|c) }\n    method interval(Supply:U: |c)        { SupplyOperations.interval(|c) }\n    method flat(Supply:D: )              { SupplyOperations.flat(self) }\n    method grep(Supply:D: Mu $test)      { SupplyOperations.grep(self, $test) }\n    method map(Supply:D: &mapper)        { SupplyOperations.map(self, &mapper) }\n    method schedule-on(Supply:D: Scheduler $scheduler) {\n        SupplyOperations.schedule-on(self, $scheduler);\n    }\n    method start(Supply:D: &startee)     { SupplyOperations.start(self, &startee) }\n    method stable(Supply:D: $time, :$scheduler = $*SCHEDULER) {\n        SupplyOperations.stable(self, $time, :$scheduler);\n    }\n    method delay(Supply:D: $time, :$scheduler = $*SCHEDULER) {\n        DEPRECATED('delayed', '2015.02', '2015.09');\n        SupplyOperations.delayed(self, $time, :$scheduler);\n    }\n    method delayed(Supply:D: $time, :$scheduler = $*SCHEDULER) {\n        SupplyOperations.delayed(self, $time, :$scheduler)\n    }\n    method migrate(Supply:D: )           { SupplyOperations.migrate(self) }\n\n    multi method classify(Supply:D: &mapper )  {\n        SupplyOperations.classify(self, &mapper);\n    }\n    multi method classify(Supply:D: %mapper )  {\n        SupplyOperations.classify(self, { %mapper{$^a} });\n    }\n    multi method classify(Supply:D: @mapper )  {\n        SupplyOperations.classify(self, { @mapper[$^a] });\n    }\n\n    proto method categorize (|) { * }\n    multi method categorize(Supply:D: &mapper )  {\n        SupplyOperations.classify(self, &mapper, :multi);\n    }\n    multi method categorize(Supply:D: %mapper )  {\n        SupplyOperations.classify(self, { %mapper{$^a} }, :multi);\n    }\n    multi method categorize(Supply:D: @mapper )  {\n        SupplyOperations.classify(self, { @mapper[$^a] }, :multi);\n    }\n\n    method act(Supply:D: &actor) {\n        self.do(&actor).tap(|%_) # need \"do\" for serializing callbacks\n    }\n\n    method do(Supply:D $self: &side_effect) {\n        on -> $res {\n            $self => -> \\val { side_effect(val); $res.emit(val) }\n        }\n    }\n\n    method unique(Supply:D $self: :&as, :&with, :$expires) {\n        on -> $res {\n            $self => do {\n                if $expires {\n                    if &with and &with !=== &[===] {\n                        my @seen;  # really Mu, but doesn't work in settings\n                        my Mu $target;\n                        &as\n                          ?? -> \\val {\n                              my $now := now;\n                              $target = &as(val);\n                              my $index =\n                                @seen.first-index({&with($target,$_[0])});\n                              if $index.defined {\n                                  if $now > @seen[$index][1] {  # expired\n                                      @seen[$index][1] = $now+$expires;\n                                      $res.emit(val);\n                                  }\n                              }\n                              else {\n                                  @seen.push: [$target, $now+$expires];\n                                  $res.emit(val);\n                              }\n                          }\n                          !! -> \\val {\n                              my $now := now;\n                              my $index =\n                                @seen.first-index({&with(val,$_[0])});\n                              if $index.defined {\n                                  if $now > @seen[$index][1] {  # expired\n                                      @seen[$index][1] = $now+$expires;\n                                      $res.emit(val);\n                                  }\n                              }\n                              else {\n                                  @seen.push: [val, $now+$expires];\n                                  $res.emit(val);\n                              }\n                          };\n                    }\n                    else {\n                        my $seen := nqp::hash();\n                        my str $target;\n                        &as\n                          ?? -> \\val {\n                              my $now := now;\n                              $target = nqp::unbox_s(&as(val).WHICH);\n                              if !nqp::existskey($seen,$target) ||\n                                $now > nqp::atkey($seen,$target) { #expired\n                                  $res.emit(val);\n                                  nqp::bindkey($seen,$target,$now+$expires);\n                              }\n                          }\n                          !! -> \\val {\n                              my $now := now;\n                              $target = nqp::unbox_s(val.WHICH);\n                              if !nqp::existskey($seen,$target) ||\n                                $now > nqp::atkey($seen,$target) { #expired\n                                  $res.emit(val);\n                                  nqp::bindkey($seen,$target,$now+$expires);\n                              }\n                          };\n                    }\n                }\n                else { # !$!expires\n                    if &with and &with !=== &[===] {\n                        my @seen;  # really Mu, but doesn't work in settings\n                        my Mu $target;\n                        &as\n                          ?? -> \\val {\n                              $target = &as(val);\n                              if @seen.first({ &with($target,$_) } ) =:= Nil {\n                                  @seen.push($target);\n                                  $res.emit(val);\n                              }\n                          }\n                          !! -> \\val {\n                              if @seen.first({ &with(val,$_) } ) =:= Nil {\n                                  @seen.push(val);\n                                  $res.emit(val);\n                              }\n                          };\n                    }\n                    else {\n                        my $seen := nqp::hash();\n                        my str $target;\n                        &as\n                          ?? -> \\val {\n                              $target = nqp::unbox_s(&as(val).WHICH);\n                              unless nqp::existskey($seen, $target) {\n                                  nqp::bindkey($seen, $target, 1);\n                                  $res.emit(val);\n                              }\n                          }\n                          !! -> \\val {\n                              $target = nqp::unbox_s(val.WHICH);\n                              unless nqp::existskey($seen, $target) {\n                                  nqp::bindkey($seen, $target, 1);\n                                  $res.emit(val);\n                              }\n                          };\n                    }\n                }\n            }\n        }\n    }\n\n    method squish(Supply:D $self: :&as, :&with is copy) {\n        &with //= &[===];\n        on -> $res {\n            my @secret;\n            $self => do {\n                my Mu $last = @secret;\n                my Mu $target;\n                &as\n                  ?? -> \\val {\n                      $target = &as(val);\n                      unless &with($target,$last) {\n                          $last = $target;\n                          $res.emit(val);\n                      }\n                  }\n                  !! -> \\val {\n                      unless &with(val,$last) {\n                          $last = val;\n                          $res.emit(val);\n                      }\n                  };\n            }\n        }\n    }\n\n    proto method rotor(|) {*}\n    multi method rotor(Supply:D:) {\n        DEPRECATED('.rotor( $elems => -$gap )',|<2015.04 2015.09>);\n        self.rotor( (2 => -1) );\n    }\n    multi method rotor(Supply:D $self: *@cycle, :$partial) {\n        my @c := @cycle.infinite ?? @cycle !! @cycle xx *;\n\n        on -> $res {\n            $self => do {\n                my Int $elems;\n                my Int $gap;\n                my int $to-skip;\n                my int $skip;\n                sub next-batch() {\n                    given @c.shift {\n                        when Pair {\n                            $elems   = +.key;\n                            $gap     = +.value;\n                            $to-skip = $gap > 0 ?? $gap !! 0;\n                        }\n                        default {\n                            $elems   = +$_;\n                            $gap     = 0;\n                            $to-skip = 0;\n                        }\n                    }\n                }\n                next-batch;\n\n                my @batched;\n                sub flush() {\n                    $res.emit( [@batched] );\n                    @batched.splice( 0, +@batched + $gap );\n                    $skip = $to-skip;\n                }\n\n                {\n                    emit => -> \\val {\n                        @batched.push: val unless $skip && $skip--;\n                        if @batched.elems == $elems {\n                            flush;\n                            next-batch;\n                        }\n                    },\n                    done => {\n                        flush if @batched and $partial;\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method batch(Supply:D $self: :$elems, :$seconds ) {\n\n        return $self if (!$elems or $elems == 1) and !$seconds;  # nothing to do\n\n        on -> $res {\n            $self => do {\n                my @batched;\n                my $last_time;\n                sub flush {\n                    $res.emit([@batched]);\n                    @batched = ();\n                }\n\n                {\n                    emit => do {\n                        if $seconds {\n                            $last_time = time div $seconds;\n\n                            $elems # and $seconds\n                              ??  -> \\val {\n                                  my $this_time = time div $seconds;\n                                  if $this_time != $last_time {\n                                      flush if @batched;\n                                      $last_time = $this_time;\n                                      @batched.push: val;\n                                  }\n                                  else {\n                                      @batched.push: val;\n                                      flush if @batched.elems == $elems;\n                                  }\n                              }\n                              !! -> \\val {\n                                  my $this_time = time div $seconds;\n                                  if $this_time != $last_time {\n                                      flush if @batched;\n                                      $last_time = $this_time;\n                                  }\n                                  @batched.push: val;\n                              }\n                        }\n                        else { # just $elems\n                            -> \\val {\n                                @batched.push: val;\n                                flush if @batched.elems == $elems;\n                            }\n                        }\n                    },\n                    done => {\n                        flush if @batched;\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method lines(Supply:D $self: :$chomp = True ) {\n\n        on -> $res {\n            $self => do {\n                my str $str;\n                my int $chars;\n                my int $left;\n                my int $pos;\n                my int $nextpos;\n                my int $found;\n                my int $cr;\n                my int $crlf;\n\n                {\n                    emit => -> \\val {\n                        $str   = $str ~ nqp::unbox_s(val);\n                        $chars = nqp::chars($str);\n                        $pos   = 0;\n\n                        while ($left = $chars - $pos) > 0 {\n                            $nextpos = nqp::findcclass(\n                              nqp::const::CCLASS_NEWLINE, $str, $pos, $left\n                            );\n\n                            # no trailing line delimiter, so go buffer\n                            last unless nqp::iscclass(\n                              nqp::const::CCLASS_NEWLINE, $str, $nextpos\n                            );\n\n                            # potentially broken CRLF, so go buffer\n                            $cr = nqp::ordat($str, $nextpos) == 13;    # CR\n                            last if $cr == 1 and $nextpos + 1 == $chars;\n\n                            $crlf = $cr\n                              && nqp::ordat($str, $nextpos + 1) == 10; # LF\n\n                            if $chomp {\n                                $res.emit( ($found = $nextpos - $pos)\n                                  ?? nqp::box_s(\n                                       nqp::substr($str, $pos, $found), Str)\n                                  !! ''\n                                );\n                                $pos = $nextpos + 1 + $crlf;\n                            }\n                            else {\n                                $found = $nextpos - $pos + 1 + $crlf;\n                                $res.emit( nqp::box_s(\n                                  nqp::substr($str, $pos, $found), Str)\n                                );\n                                $pos = $pos + $found;\n                            }\n                        }\n                        $str = $pos < $chars\n                          ?? nqp::substr($str,$pos)\n                          !! '';\n                    },\n                    done => {\n                        if $str {\n                            $chars = nqp::chars($str);\n                            $res.emit( $chomp\n                              && nqp::ordat($str, $chars - 1) == 13    # CR\n                              ?? nqp::box_s(nqp::substr($str,0,$chars - 1),Str)\n                              !! nqp::box_s($str, Str)\n                            );\n                        }\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method words(Supply:D $self:) {\n\n        on -> $res {\n            $self => do {\n                my str $str;\n                my int $chars;\n                my int $left;\n                my int $pos;\n                my int $nextpos;\n                my int $found;\n                my int $cr;\n                my int $crlf;\n\n                {\n                    emit => -> \\val {\n                        $str   = $str ~ nqp::unbox_s(val);\n                        $chars = nqp::chars($str);\n                        $pos   = nqp::findnotcclass(\n                          nqp::const::CCLASS_WHITESPACE, $str, 0, $chars);\n\n                        while ($left = $chars - $pos) > 0 {\n                            $nextpos = nqp::findcclass(\n                              nqp::const::CCLASS_WHITESPACE, $str, $pos, $left\n                            );\n\n                            last unless $left = $chars - $nextpos; # broken word\n\n                            $res.emit( nqp::box_s(\n                              nqp::substr( $str, $pos, $nextpos - $pos ), Str)\n                            );\n\n                            $pos = nqp::findnotcclass(\n                              nqp::const::CCLASS_WHITESPACE,$str,$nextpos,$left);\n                        }\n                        $str = $pos < $chars\n                          ?? nqp::substr($str,$pos)\n                          !! '';\n                    },\n                    done => {\n                        $res.emit( nqp::box_s($str, Str) ) if $str;\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method elems(Supply:D $self: $seconds? ) {\n\n        on -> $res {\n            $self => do {\n                my $elems = 0;\n                my $last_time;\n                my $last_elems;\n\n                {\n                    emit => do {\n                        if $seconds {\n                            $last_time  = time div $seconds;\n                            $last_elems = $elems;\n                            -> \\val {\n                                  $last_elems = ++$elems;\n                                  my $this_time = time div $seconds;\n                                  if $this_time != $last_time {\n                                      $res.emit($elems);\n                                      $last_time = $this_time;\n                                  }\n                            }\n                        }\n                        else {\n                            -> \\val { $res.emit(++$elems) }\n                        }\n                    },\n                    done => {\n                        $res.emit($elems) if $seconds and $elems != $last_elems;\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method last(Supply:D $self: Int $number = 1) {  # should be Natural\n        on -> $res {\n            $self => do {\n                my @seen;\n                {\n                    emit => $number == 1\n                      ?? -> \\val { @seen[0] = val }\n                      !! -> \\val {\n                          @seen.shift if +@seen == $number;\n                          @seen.push: val;\n                      },\n                    done => {\n                        $res.emit($_) for @seen;\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method min(Supply:D $self: &by = &infix:<cmp>) {\n        my &cmp = &by.arity == 2 ?? &by !! { by($^a) cmp by($^b) }\n        on -> $res {\n            $self => do {\n                my $min;\n                {\n                    emit => -> \\val {\n                        if val.defined and !$min.defined || cmp(val,$min) < 0 {\n                            $res.emit( $min = val );\n                        }\n                    },\n                    done => { $res.done }\n                }\n            }\n        }\n    }\n\n    method max(Supply:D $self: &by = &infix:<cmp>) {\n        my &cmp = &by.arity == 2 ?? &by !! { by($^a) cmp by($^b) }\n        on -> $res {\n            $self => do {\n                my $max;\n                {\n                    emit => -> \\val {\n                        if val.defined and !$max.defined || cmp(val,$max) > 0 {\n                            $res.emit( $max = val );\n                        }\n                    },\n                    done => { $res.done }\n                }\n            }\n        }\n    }\n\n    method minmax(Supply:D $self: &by = &infix:<cmp>) {\n        my &cmp = &by.arity == 2 ?? &by !! { by($^a) cmp by($^b) }\n        on -> $res {\n            $self => do {\n                my $min;\n                my $max;\n                {\n                    emit => -> \\val {\n                        if val.defined {\n                            if !$min.defined {\n                                $res.emit( Range.new($min = val, $max = val) );\n                            }\n                            elsif cmp(val,$min) < 0 {\n                                $res.emit( Range.new( $min = val, $max ) );\n                            }\n                            elsif cmp(val,$max) > 0 {\n                                $res.emit( Range.new( $min, $max = val ) );\n                            }\n                        }\n                    },\n                    done => { $res.done }\n                }\n            }\n        }\n    }\n\n    method reduce(Supply:D $self: &with) {\n        on -> $res {\n            $self => do {\n                my $notfirst;\n                my $reduced;\n                {\n                    emit => -> \\val {\n                        $reduced = $notfirst ?? with($reduced,val) !! val;\n                        $res.emit($reduced);\n                        once $notfirst = True;\n                    },\n                    done => { $res.done }\n                }\n            }\n        }\n    }\n\n    method grab(Supply:D $self: &when_done) {\n        on -> $res {\n            $self => do {\n                my @seen;\n                {\n                    emit => -> \\val { @seen.push: val },\n                    done => {\n                        $res.emit($_) for when_done(@seen);\n                        $res.done;\n                    }\n                }\n            }\n        }\n    }\n\n    method reverse(Supply:D:)                 { self.grab( {.reverse} ) }\n    method sort(Supply:D: &by = &infix:<cmp>) { self.grab( {.sort(&by)} ) }\n\n    method merge(*@s) {\n        @s.unshift(self) if self.DEFINITE;  # add if instance method\n        return Supply unless +@s;           # nothing to be done\n\n        X::Supply::Combinator.new(\n           combinator => 'merge'\n        ).throw if NOT_ALL_DEFINED_TYPE(@s,Supply);\n\n        return @s[0]  if +@s == 1;          # nothing to be done\n\n        my $dones = 0;\n        on -> $res {\n            @s => {\n                emit => -> \\val { $res.emit(val) },\n                done => { $res.done() if ++$dones == +@s }\n            },\n        }\n    }\n\n    method zip(*@s, :&with is copy = &[,]) {\n        @s.unshift(self) if self.DEFINITE;  # add if instance method\n        return Supply unless +@s;           # nothing to be done\n\n        X::Supply::Combinator.new(\n           combinator => 'zip'\n        ).throw if NOT_ALL_DEFINED_TYPE(@s,Supply);\n\n        return @s[0]  if +@s == 1;          # nothing to be done\n\n        my @values = ( [] xx +@s );\n        on -> $res {\n            @s => -> $val, $index {\n                @values[$index].push($val);\n                if all(@values) {\n                    $res.emit( [[&with]] @values>>.shift );\n                }\n            }\n        }\n    }\n\n    method zip-latest(*@s, :&with is copy = &[,], :$initial ) {\n        @s.unshift(self) if self.DEFINITE;  # add if instance method\n        return Supply unless +@s;           # nothing to do.\n\n        X::Supply::Combinator.new(\n           combinator => 'zip-latest'\n        ).throw if NOT_ALL_DEFINED_TYPE(@s,Supply);\n\n        return @s[0] if +@s == 1;           # nothing to do.\n\n        my @values;\n\n        my $uninitialised = +@s; # how many supplies have yet to emit until we\n                                 # can start emitting, too?\n\n        if $initial {\n            @values = @$initial;\n            $uninitialised = 0 max $uninitialised - @$initial;\n        }\n\n        my $dones = 0;\n\n        on -> $res {\n            @s => do {\n                {\n                emit => -> $val, $index {\n                    if $uninitialised > 0 && not @values.EXISTS-POS($index) {\n                        --$uninitialised;\n                    }\n                    @values[$index] = $val;\n                    unless $uninitialised {\n                        $res.emit( [[&with]] @values );\n                    }\n                },\n                done => { $res.done() if ++$dones == +@s }\n                }\n            }\n        }\n    }\n\n    method for(Supply:U: |c) {\n        DEPRECATED('from-list',|<2015.01 2015.09>);\n        SupplyOperations.from-list(|c);\n    }\n    method on_demand(Supply:U: |c)       {\n        DEPRECATED('on-demand',|<2015.03 2015.09>);\n        SupplyOperations.on-demand(|c);\n    }\n    method schedule_on(Supply:D: Scheduler $scheduler) {\n        DEPRECATED('schedule-on',|<2015.03 2015.09>);\n        SupplyOperations.schedule-on(self, $scheduler);\n    }\n    method uniq(Supply:D: |c) {\n        DEPRECATED('unique', |<2014.11 2015.09>);\n        self.unique(|c);\n    }\n}\n\n# The on meta-combinator provides a mechanism for implementing thread-safe\n# combinators on Supplies. It subscribes to a bunch of sources, but will\n# only let one of the specified callbacks to handle their emit/done/quit run\n# at a time. A little bit actor-like.\nmy class X::Supply::On::BadSetup is Exception {\n    method message() {\n        \"on requires a callable that returns a list of pairs with Supply keys\"\n    }\n}\nmy class X::Supply::On::NoEmit is Exception {\n    method message() {\n        \"on requires that emit be specified for each supply\"\n    }\n}\nsub on(&setup) {\n    my class OnSupply does Supply {\n        has &!setup;\n        has Bool $!live = False;\n\n        submethod BUILD(:&!setup) { }\n\n        method !add_source(\n          $source, $lock, $index, :&done is copy, :&quit is copy,\n          :&emit is copy, :&more   # more deprecated, emit must be changeable\n        ) {\n            DEPRECATED('emit => {...}', |<2014.10 2015.09>) if &more;\n            $!live ||= True if $source.live;\n            &emit //= &more // X::Supply::On::NoEmit.new.throw;\n            &done //= { self.done };\n            &quit //= -> $ex { self.quit($ex) };\n\n            my &tap_emit = &emit.arity == 2\n              ?? -> \\val {\n                  $lock.protect({ emit(val,$index) });\n                  CATCH { default { self.quit($_) } }\n              }\n              !!  -> \\val {\n                  $lock.protect({ emit(val) });\n                  CATCH { default { self.quit($_) } }\n              };\n\n            my &tap_done = &done.arity == 1\n              ?? {\n                  $lock.protect({ done($index) });\n                  CATCH { default { self.quit($_) } }\n              }\n              !! {\n                  $lock.protect({ done() });\n                  CATCH { default { self.quit($_) } }\n              };\n\n            my &tap_quit = &quit.arity == 2\n              ?? -> $ex {\n                  $lock.protect({ quit($ex,$index) });\n                  CATCH { default { self.quit($_) } }\n              }\n              !! -> $ex {\n                  $lock.protect({ quit($ex) });\n                  CATCH { default { self.quit($_) } }\n              };\n\n            $source.tap( &tap_emit, done => &tap_done, quit => &tap_quit );\n        }\n\n        method live { $!live }\n        method tap(|c) {\n            my @to_close;\n            my $sub = self.Supply::tap( |c, closing => {.close for @to_close});\n            my @tappers = &!setup(self);\n            my $lock    = Lock.new;\n\n            sub add ($source, $what, $index?) {\n                unless nqp::istype($source,Supply) {\n                    X::Supply::On::BadSetup.new.throw;\n                }\n                given $what {\n                    when EnumMap {\n                        @to_close.push(self!add_source($source, $lock, $index, |$what));\n                    }\n                    when Callable {\n                        @to_close.push(self!add_source($source, $lock, $index, emit => $what));\n                    }\n                    default {\n                        X::Supply::On::BadSetup.new.throw;\n                    }\n                }\n            }\n\n            for @tappers -> $tap {\n                unless nqp::istype($tap,Pair) {\n                    X::Supply::On::BadSetup.new.throw;\n                }\n                given $tap.key {\n                    when Positional {\n                        my $todo := $tap.value;\n                        for .list.kv -> $index, $supply {\n                            add( $supply, $todo, $index );\n                        }\n                    }\n                    when Supply {\n                        add( $_, $tap.value );\n                    }\n                    default {\n                        X::Supply::On::BadSetup.new.throw;\n                    }\n                }\n            }\n            $sub\n        }\n\n        method emit(\\msg) {\n            for self.tappers {\n                .emit().(msg)\n            }\n            Nil;\n        }\n\n        method done() {\n            for self.tappers {\n                if .done -> $l { $l() }\n            }\n            Nil;\n        }\n\n        method quit($ex) {\n            for self.tappers {\n                if .quit -> $t { $t($ex) }\n            }\n            Nil;\n        }\n    }\n\n    OnSupply.new(:&setup)\n}\n\n# vim: ft=raku expandtab sw=4\n"
  },
  {
    "path": "Units/parser-raku.r/raku-package.d/expected.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\tDevelopment\t//\nFoo\tinput.rakumod\t/^package Foo {$/;\"\tp\nhello-world\tinput.rakumod\t/^    sub hello-world is export {$/;\"\ts\n"
  },
  {
    "path": "Units/parser-raku.r/raku-package.d/input.rakumod",
    "content": "use v6;\npackage Foo {\n    sub hello-world is export {\n        say \"hey there\";\n    }\n}\n"
  },
  {
    "path": "Units/parser-rdoc.r/run-as-guest.d/README",
    "content": "The input is taken from ruby/lib/rdoc/markup.rb.\n"
  },
  {
    "path": "Units/parser-rdoc.r/run-as-guest.d/args.ctags",
    "content": "--sort=no\n--fields=+lKne\n--extras=+g\n"
  },
  {
    "path": "Units/parser-rdoc.r/run-as-guest.d/expected.tags",
    "content": "Markup\tinput.rb\t/^class RDoc::Markup$/;\"\tclass\tline:737\tlanguage:Ruby\tmodule:RDoc\tend:867\nattribute_manager\tinput.rb\t/^  attr_reader :attribute_manager$/;\"\taccessor\tline:742\tlanguage:Ruby\tclass:Markup\nparse\tinput.rb\t/^  def self.parse str$/;\"\tsingletonMethod\tline:747\tlanguage:Ruby\tclass:Markup\tend:770\ninitialize\tinput.rb\t/^  def initialize attribute_manager = nil$/;\"\tmethod\tline:777\tlanguage:Ruby\tclass:Markup\tend:780\nadd_word_pair\tinput.rb\t/^  def add_word_pair(start, stop, name)$/;\"\tmethod\tline:787\tlanguage:Ruby\tclass:Markup\tend:789\nadd_html\tinput.rb\t/^  def add_html(tag, name)$/;\"\tmethod\tline:794\tlanguage:Ruby\tclass:Markup\tend:796\nadd_regexp_handling\tinput.rb\t/^  def add_regexp_handling(pattern, name)$/;\"\tmethod\tline:806\tlanguage:Ruby\tclass:Markup\tend:808\nconvert\tinput.rb\t/^  def convert input, formatter$/;\"\tmethod\tline:814\tlanguage:Ruby\tclass:Markup\tend:823\nSupported Formats\tinput.rb\t/^# = Supported Formats$/;\"\tL1Header\tline:13\tlanguage:RDoc\tend:43\nRDoc::Markup\tinput.rb\t/^# = RDoc::Markup$/;\"\tL1Header\tline:44\tlanguage:RDoc\tend:97\nSynopsis\tinput.rb\t/^# == Synopsis$/;\"\tL2Header\tline:55\tlanguage:RDoc\tL1Header:RDoc::Markup\tend:91\nEncoding\tinput.rb\t/^# == Encoding$/;\"\tL2Header\tline:92\tlanguage:RDoc\tL1Header:RDoc::Markup\tend:97\n\\\\RDoc Markup Reference\tinput.rb\t/^# = \\\\RDoc Markup Reference$/;\"\tL1Header\tline:98\tlanguage:RDoc\tend:868\nBlock Markup\tinput.rb\t/^# == Block Markup$/;\"\tL2Header\tline:100\tlanguage:RDoc\tL1Header:\\\\RDoc Markup Reference\tend:297\nParagraphs and Verbatim\tinput.rb\t/^# === Paragraphs and Verbatim$/;\"\tL3Header\tline:102\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Block Markup\tend:133\nHeaders\tinput.rb\t/^# === Headers$/;\"\tL3Header\tline:134\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Block Markup\tend:170\nRules\tinput.rb\t/^# === Rules$/;\"\tL3Header\tline:171\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Block Markup\tend:181\nSimple Lists\tinput.rb\t/^# === Simple Lists$/;\"\tL3Header\tline:182\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Block Markup\tend:216\nLabeled Lists\tinput.rb\t/^# === Labeled Lists$/;\"\tL3Header\tline:217\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Block Markup\tend:269\nLists and Verbatim\tinput.rb\t/^# === Lists and Verbatim$/;\"\tL3Header\tline:270\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Block Markup\tend:297\nText Markup\tinput.rb\t/^# == Text Markup$/;\"\tL2Header\tline:298\tlanguage:RDoc\tL1Header:\\\\RDoc Markup Reference\tend:440\nBold, Italic, Typewriter Text\tinput.rb\t/^# === Bold, Italic, Typewriter Text$/;\"\tL3Header\tline:300\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Text Markup\tend:325\nLinks\tinput.rb\t/^# === Links$/;\"\tL3Header\tline:326\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Text Markup\tend:383\nEscaping Text Markup\tinput.rb\t/^# === Escaping Text Markup$/;\"\tL3Header\tline:384\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Text Markup\tend:414\nConversion of characters\tinput.rb\t/^# === Conversion of characters$/;\"\tL3Header\tline:415\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Text Markup\tend:440\nDocumenting Source Code\tinput.rb\t/^# == Documenting Source Code$/;\"\tL2Header\tline:441\tlanguage:RDoc\tL1Header:\\\\RDoc Markup Reference\tend:514\nDirectives\tinput.rb\t/^# == Directives$/;\"\tL2Header\tline:515\tlanguage:RDoc\tL1Header:\\\\RDoc Markup Reference\tend:868\nControlling what is documented\tinput.rb\t/^# === Controlling what is documented$/;\"\tL3Header\tline:519\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Directives\tend:570\nMethod arguments\tinput.rb\t/^# === Method arguments$/;\"\tL3Header\tline:571\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Directives\tend:609\nSections\tinput.rb\t/^# === Sections$/;\"\tL3Header\tline:610\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Directives\tend:678\nOther directives\tinput.rb\t/^# === Other directives$/;\"\tL3Header\tline:679\tlanguage:RDoc\tL2Header:\\\\RDoc Markup Reference\"\"Directives\tend:868\n"
  },
  {
    "path": "Units/parser-rdoc.r/run-as-guest.d/input.rb",
    "content": "# frozen_string_literal: true\n##\n# RDoc::Markup parses plain text documents and attempts to decompose them into\n# their constituent parts.  Some of these parts are high-level: paragraphs,\n# chunks of verbatim text, list entries and the like.  Other parts happen at\n# the character level: a piece of bold text, a word in code font.  This markup\n# is similar in spirit to that used on WikiWiki webs, where folks create web\n# pages using a simple set of formatting rules.\n#\n# RDoc::Markup and other markup formats do no output formatting, this is\n# handled by the RDoc::Markup::Formatter subclasses.\n#\n# = Supported Formats\n#\n# Besides the RDoc::Markup format, the following formats are built in to RDoc:\n#\n# markdown::\n#   The markdown format as described by\n#   http://daringfireball.net/projects/markdown/.  See RDoc::Markdown for\n#   details on the parser and supported extensions.\n# rd::\n#   The rdtool format.  See RDoc::RD for details on the parser and format.\n# tomdoc::\n#   The TomDoc format as described by http://tomdoc.org/.  See RDoc::TomDoc\n#   for details on the parser and supported extensions.\n#\n# You can choose a markup format using the following methods:\n#\n# per project::\n#   If you build your documentation with rake use RDoc::Task#markup.\n#\n#   If you build your documentation by hand run:\n#\n#      rdoc --markup your_favorite_format --write-options\n#\n#   and commit <tt>.rdoc_options</tt> and ship it with your packaged gem.\n# per file::\n#   At the top of the file use the <tt>:markup:</tt> directive to set the\n#   default format for the rest of the file.\n# per comment::\n#   Use the <tt>:markup:</tt> directive at the top of a comment you want\n#   to write in a different format.\n#\n# = RDoc::Markup\n#\n# RDoc::Markup is extensible at runtime: you can add \\new markup elements to\n# be recognized in the documents that RDoc::Markup parses.\n#\n# RDoc::Markup is intended to be the basis for a family of tools which share\n# the common requirement that simple, plain-text should be rendered in a\n# variety of different output formats and media.  It is envisaged that\n# RDoc::Markup could be the basis for formatting RDoc style comment blocks,\n# Wiki entries, and online FAQs.\n#\n# == Synopsis\n#\n# This code converts +input_string+ to HTML.  The conversion takes place in\n# the +convert+ method, so you can use the same RDoc::Markup converter to\n# convert multiple input strings.\n#\n#   require 'rdoc'\n#\n#   h = RDoc::Markup::ToHtml.new(RDoc::Options.new)\n#\n#   puts h.convert(input_string)\n#\n# You can extend the RDoc::Markup parser to recognize new markup\n# sequences, and to add regexp handling. Here we make WikiWords significant to\n# the parser, and also make the sequences {word} and \\<no>text...</no> signify\n# strike-through text.  We then subclass the HTML output class to deal\n# with these:\n#\n#   require 'rdoc'\n#\n#   class WikiHtml < RDoc::Markup::ToHtml\n#     def handle_regexp_WIKIWORD(target)\n#       \"<font color=red>\" + target.text + \"</font>\"\n#     end\n#   end\n#\n#   markup = RDoc::Markup.new\n#   markup.add_word_pair(\"{\", \"}\", :STRIKE)\n#   markup.add_html(\"no\", :STRIKE)\n#\n#   markup.add_regexp_handling(/\\b([A-Z][a-z]+[A-Z]\\w+)/, :WIKIWORD)\n#\n#   wh = WikiHtml.new RDoc::Options.new, markup\n#   wh.add_tag(:STRIKE, \"<strike>\", \"</strike>\")\n#\n#   puts \"<body>#{wh.convert ARGF.read}</body>\"\n#\n# == Encoding\n#\n# Where Encoding support is available, RDoc will automatically convert all\n# documents to the same output encoding.  The output encoding can be set via\n# RDoc::Options#encoding and defaults to Encoding.default_external.\n#\n# = \\RDoc Markup Reference\n#\n# == Block Markup\n#\n# === Paragraphs and Verbatim\n#\n# The markup engine looks for a document's natural left margin.  This is\n# used as the initial margin for the document.\n#\n# Consecutive lines starting at this margin are considered to be a\n# paragraph. Empty lines separate paragraphs.\n#\n# Any line that starts to the right of the current margin is treated\n# as verbatim text.  This is useful for code listings:\n#\n#   3.times { puts \"Ruby\" }\n#\n# In verbatim text, two or more blank lines are collapsed into one,\n# and trailing blank lines are removed:\n#\n#   This is the first line\n#\n#\n#   This is the second non-blank line,\n#   after 2 blank lines in the source markup.\n#\n#\n# There were two trailing blank lines right above this paragraph, that\n# have been removed. In addition, the verbatim text has been shifted\n# left, so the amount of indentation of verbatim text is unimportant.\n#\n# For HTML output RDoc makes a small effort to determine if a verbatim section\n# contains Ruby source code.  If so, the verbatim block will be marked up as\n# HTML.  Triggers include \"def\", \"class\", \"module\", \"require\", the \"hash\n# rocket\"# (=>) or a block call with a parameter.\n#\n# === Headers\n#\n# A line starting with an equal sign (=) is treated as a\n# heading.  Level one headings have one equals sign, level two headings\n# have two, and so on until level six, which is the maximum\n# (seven hyphens or more result in a level six heading).\n#\n# For example, the above header was obtained with:\n#\n#   === Headers\n#\n# In HTML output headers have an id matching their name.  The above example's\n# HTML is:\n#\n#   <h3 id=\"label-Headers\">Headers</h3>\n#\n# If a heading is inside a method body the id will be prefixed with the\n# method's id.  If the above header where in the documentation for a method\n# such as:\n#\n#   ##\n#   # This method does fun things\n#   #\n#   # = Example\n#   #\n#   #   Example of fun things goes here ...\n#\n#   def do_fun_things\n#   end\n#\n# The header's id would be:\n#\n#   <h1 id=\"method-i-do_fun_things-label-Example\">Example</h1>\n#\n# The label can be linked-to using <tt>SomeClass@Headers</tt>.  See\n# {Links}[RDoc::Markup@Links] for further details.\n#\n# === Rules\n#\n# A line starting with three or more hyphens (at the current indent)\n# generates a horizontal rule.\n#\n#   ---\n#\n# produces:\n#\n# ---\n#\n# === Simple Lists\n#\n# If a paragraph starts with a \"*\", \"-\", \"<digit>.\" or \"<letter>.\",\n# then it is taken to be the start of a list.  The margin is increased to be\n# the first non-space following the list start flag.  Subsequent lines\n# should be indented to this new margin until the list ends.  For example:\n#\n#   * this is a list with three paragraphs in\n#     the first item.  This is the first paragraph.\n#\n#     And this is the second paragraph.\n#\n#     1. This is an indented, numbered list.\n#     2. This is the second item in that list\n#\n#     This is the third conventional paragraph in the\n#     first list item.\n#\n#   * This is the second item in the original list\n#\n# produces:\n#\n# * this is a list with three paragraphs in\n#   the first item.  This is the first paragraph.\n#\n#   And this is the second paragraph.\n#\n#   1. This is an indented, numbered list.\n#   2. This is the second item in that list\n#\n#   This is the third conventional paragraph in the\n#   first list item.\n#\n# * This is the second item in the original list\n#\n# === Labeled Lists\n#\n# You can also construct labeled lists, sometimes called description\n# or definition lists.  Do this by putting the label in square brackets\n# and indenting the list body:\n#\n#   [cat]  a small furry mammal\n#          that seems to sleep a lot\n#\n#   [ant]  a little insect that is known\n#          to enjoy picnics\n#\n# produces:\n#\n# [cat]  a small furry mammal\n#        that seems to sleep a lot\n#\n# [ant]  a little insect that is known\n#        to enjoy picnics\n#\n# If you want the list bodies to line up to the left of the labels,\n# use two colons:\n#\n#   cat::  a small furry mammal\n#          that seems to sleep a lot\n#\n#   ant::  a little insect that is known\n#          to enjoy picnics\n#\n# produces:\n#\n# cat::  a small furry mammal\n#        that seems to sleep a lot\n#\n# ant::  a little insect that is known\n#        to enjoy picnics\n#\n# Notice that blank lines right after the label are ignored in labeled lists:\n#\n#   [one]\n#\n#       definition 1\n#\n#   [two]\n#\n#       definition 2\n#\n# produces the same output as\n#\n#   [one]  definition 1\n#   [two]  definition 2\n#\n#\n# === Lists and Verbatim\n#\n# If you want to introduce a verbatim section right after a list, it has to be\n# less indented than the list item bodies, but more indented than the list\n# label, letter, digit or bullet. For instance:\n#\n#   *   point 1\n#\n#   *   point 2, first paragraph\n#\n#       point 2, second paragraph\n#         verbatim text inside point 2\n#       point 2, third paragraph\n#     verbatim text outside of the list (the list is therefore closed)\n#   regular paragraph after the list\n#\n# produces:\n#\n# *   point 1\n#\n# *   point 2, first paragraph\n#\n#     point 2, second paragraph\n#       verbatim text inside point 2\n#     point 2, third paragraph\n#   verbatim text outside of the list (the list is therefore closed)\n# regular paragraph after the list\n#\n# == Text Markup\n#\n# === Bold, Italic, Typewriter Text\n#\n# You can use markup within text (except verbatim) to change the\n# appearance of parts of that text.  Out of the box, RDoc::Markup\n# supports word-based and general markup.\n#\n# Word-based markup uses flag characters around individual words:\n#\n# <tt>\\*_word_\\*</tt>::  displays _word_ in a *bold* font\n# <tt>\\__word_\\_</tt>::  displays _word_ in an _emphasized_ font\n# <tt>\\+_word_\\+</tt>::  displays _word_ in a +code+ font\n#\n# General markup affects text between a start delimiter and an end\n# delimiter.  Not surprisingly, these delimiters look like HTML markup.\n#\n# <tt>\\<b>_text_</b></tt>::    displays _text_ in a *bold* font\n# <tt>\\<em>_text_</em></tt>::  displays _text_ in an _emphasized_ font\n#                              (alternate tag: <tt>\\<i></tt>)\n# <tt>\\<tt>_text_\\</tt></tt>:: displays _text_ in a +code+ font\n#                              (alternate tag: <tt>\\<code></tt>)\n#\n# Unlike conventional Wiki markup, general markup can cross line\n# boundaries.  You can turn off the interpretation of markup by\n# preceding the first character with a backslash (see <i>Escaping\n# Text Markup</i>, below).\n#\n# === Links\n#\n# Links to starting with +http:+, +https:+, +mailto:+, +ftp:+ or +www.+\n# are recognized.  An HTTP url that references an external image is converted\n# into an inline image element.\n#\n# Classes and methods will be automatically linked to their definition.  For\n# example, <tt>RDoc::Markup</tt> will link to this documentation.  By default\n# methods will only be automatically linked if they contain an <tt>_</tt> (all\n# methods can be automatically linked through the <tt>--hyperlink-all</tt>\n# command line option).\n#\n# Single-word methods can be linked by using the <tt>#</tt> character for\n# instance methods or <tt>::</tt> for class methods.  For example,\n# <tt>#convert</tt> links to #convert.  A class or method may be combined like\n# <tt>RDoc::Markup#convert</tt>.\n#\n# A heading inside the documentation can be linked by following the class\n# or method by an <tt>@</tt> then the heading name.\n# <tt>RDoc::Markup@Links</tt> will link to this section like this:\n# RDoc::Markup@Links.  Spaces in headings with multiple words must be escaped\n# with <tt>+</tt> like <tt>RDoc::Markup@Escaping+Text+Markup</tt>.\n# Punctuation and other special characters must be escaped like CGI.escape.\n#\n# The <tt>@</tt> can also be used to link to sections.  If a section and a\n# heading share the same name the section is preferred for the link.\n#\n# Links can also be of the form <tt>label[url]</tt>, in which case +label+ is\n# used in the displayed text, and +url+ is used as the target.  If +label+\n# contains multiple words, put it in braces: <tt>{multi word label}[url]</tt>.\n# The +url+ may be an +http:+-type link or a cross-reference to a class,\n# module or method with a label.\n#\n# Links with the <code>rdoc-image:</code> scheme will create an image tag for\n# HTML output.  Only fully-qualified URLs are supported.\n#\n# Links with the <tt>rdoc-ref:</tt> scheme will link to the referenced class,\n# module, method, file, etc.  If the referenced item is does not exist\n# no link will be generated and <tt>rdoc-ref:</tt> will be removed from the\n# resulting text.\n#\n# Links starting with <tt>rdoc-label:label_name</tt> will link to the\n# +label_name+.  You can create a label for the current link (for\n# bidirectional links) by supplying a name for the current link like\n# <tt>rdoc-label:label-other:label-mine</tt>.\n#\n# Links starting with +link:+ refer to local files whose path is relative to\n# the <tt>--op</tt> directory.  Use <tt>rdoc-ref:</tt> instead of\n# <tt>link:</tt> to link to files generated by RDoc as the link target may\n# be different across RDoc generators.\n#\n# Example links:\n#\n#   https://github.com/ruby/rdoc\n#   mailto:user@example.com\n#   {RDoc Documentation}[http://rdoc.rubyforge.org]\n#   {RDoc Markup}[rdoc-ref:RDoc::Markup]\n#\n# === Escaping Text Markup\n#\n# Text markup can be escaped with a backslash, as in \\<tt>, which was obtained\n# with <tt>\\\\<tt></tt>.  Except in verbatim sections and between \\<tt> tags,\n# to produce a backslash you have to double it unless it is followed by a\n# space, tab or newline. Otherwise, the HTML formatter will discard it, as it\n# is used to escape potential links:\n#\n#   * The \\ must be doubled if not followed by white space: \\\\.\n#   * But not in \\<tt> tags: in a Regexp, <tt>\\S</tt> matches non-space.\n#   * This is a link to {ruby-lang}[www.ruby-lang.org].\n#   * This is not a link, however: \\{ruby-lang.org}[www.ruby-lang.org].\n#   * This will not be linked to \\RDoc::RDoc#document\n#\n# generates:\n#\n# * The \\ must be doubled if not followed by white space: \\\\.\n# * But not in \\<tt> tags: in a Regexp, <tt>\\S</tt> matches non-space.\n# * This is a link to {ruby-lang}[www.ruby-lang.org]\n# * This is not a link, however: \\{ruby-lang.org}[www.ruby-lang.org]\n# * This will not be linked to \\RDoc::RDoc#document\n#\n# Inside \\<tt> tags, more precisely, leading backslashes are removed only if\n# followed by a markup character (<tt><*_+</tt>), a backslash, or a known link\n# reference (a known class or method). So in the example above, the backslash\n# of <tt>\\S</tt> would be removed if there was a class or module named +S+ in\n# the current context.\n#\n# This behavior is inherited from RDoc version 1, and has been kept for\n# compatibility with existing RDoc documentation.\n#\n# === Conversion of characters\n#\n# HTML will convert two/three dashes to an em-dash. Other common characters are\n# converted as well:\n#\n#   em-dash::  -- or ---\n#   ellipsis:: ...\n#\n#   single quotes:: 'text' or `text'\n#   double quotes:: \"text\" or ``text''\n#\n#   copyright:: (c)\n#   registered trademark:: (r)\n#\n# produces:\n#\n# em-dash::  -- or ---\n# ellipsis:: ...\n#\n# single quotes:: 'text' or `text'\n# double quotes:: \"text\" or ``text''\n#\n# copyright:: (c)\n# registered trademark:: (r)\n#\n#\n# == Documenting Source Code\n#\n# Comment blocks can be written fairly naturally, either using <tt>#</tt> on\n# successive lines of the comment, or by including the comment in\n# a <tt>=begin</tt>/<tt>=end</tt> block.  If you use the latter form,\n# the <tt>=begin</tt> line _must_ be flagged with an +rdoc+ tag:\n#\n#   =begin rdoc\n#   Documentation to be processed by RDoc.\n#\n#   ...\n#   =end\n#\n# RDoc stops processing comments if it finds a comment line starting\n# with <tt>--</tt> right after the <tt>#</tt> character (otherwise,\n# it will be treated as a rule if it has three dashes or more).\n# This can be used to separate external from internal comments,\n# or to stop a comment being associated with a method, class, or module.\n# Commenting can be turned back on with a line that starts with <tt>++</tt>.\n#\n#   ##\n#   # Extract the age and calculate the date-of-birth.\n#   #--\n#   # FIXME: fails if the birthday falls on February 29th\n#   #++\n#   # The DOB is returned as a Time object.\n#\n#   def get_dob(person)\n#     # ...\n#   end\n#\n# Names of classes, files, and any method names containing an underscore or\n# preceded by a hash character are automatically linked from comment text to\n# their description. This linking works inside the current class or module,\n# and with ancestor methods (in included modules or in the superclass).\n#\n# Method parameter lists are extracted and displayed with the method\n# description.  If a method calls +yield+, then the parameters passed to yield\n# will also be displayed:\n#\n#   def fred\n#     ...\n#     yield line, address\n#\n# This will get documented as:\n#\n#   fred() { |line, address| ... }\n#\n# You can override this using a comment containing ':yields: ...' immediately\n# after the method definition\n#\n#   def fred # :yields: index, position\n#     # ...\n#\n#     yield line, address\n#\n# which will get documented as\n#\n#    fred() { |index, position| ... }\n#\n# +:yields:+ is an example of a documentation directive.  These appear\n# immediately after the start of the document element they are modifying.\n#\n# RDoc automatically cross-references words with underscores or camel-case.\n# To suppress cross-references, prefix the word with a \\ character.  To\n# include special characters like \"<tt>\\n</tt>\", you'll need to use\n# two \\ characters in normal text, but only one in \\<tt> text:\n#\n#   \"\\\\n\" or \"<tt>\\n</tt>\"\n#\n# produces:\n#\n# \"\\\\n\" or \"<tt>\\n</tt>\"\n#\n# == Directives\n#\n# Directives are keywords surrounded by \":\" characters.\n#\n# === Controlling what is documented\n#\n# [+:nodoc:+ / <tt>:nodoc: all</tt>]\n#   This directive prevents documentation for the element from\n#   being generated.  For classes and modules, methods, aliases,\n#   constants, and attributes directly within the affected class or\n#   module also will be omitted.  By default, though, modules and\n#   classes within that class or module _will_ be documented.  This is\n#   turned off by adding the +all+ modifier.\n#\n#     module MyModule # :nodoc:\n#       class Input\n#       end\n#     end\n#\n#     module OtherModule # :nodoc: all\n#       class Output\n#       end\n#     end\n#\n#   In the above code, only class <tt>MyModule::Input</tt> will be documented.\n#\n#   The +:nodoc:+ directive, like +:enddoc:+, +:stopdoc:+ and +:startdoc:+\n#   presented below, is local to the current file: if you do not want to\n#   document a module that appears in several files, specify +:nodoc:+ on each\n#   appearance, at least once per file.\n#\n# [+:stopdoc:+ / +:startdoc:+]\n#   Stop and start adding new documentation elements to the current container.\n#   For example, if a class has a number of constants that you don't want to\n#   document, put a +:stopdoc:+ before the first, and a +:startdoc:+ after the\n#   last.  If you don't specify a +:startdoc:+ by the end of the container,\n#   disables documentation for the rest of the current file.\n#\n# [+:doc:+]\n#   Forces a method or attribute to be documented even if it wouldn't be\n#   otherwise.  Useful if, for example, you want to include documentation of a\n#   particular private method.\n#\n# [+:enddoc:+]\n#   Document nothing further at the current level: directives +:startdoc:+ and\n#   +:doc:+ that appear after this will not be honored for the current container\n#   (file, class or module), in the current file.\n#\n# [+:notnew:+ / +:not_new:+ / +:not-new:+ ]\n#   Only applicable to the +initialize+ instance method.  Normally RDoc\n#   assumes that the documentation and parameters for +initialize+ are\n#   actually for the +new+ method, and so fakes out a +new+ for the class.\n#   The +:notnew:+ directive stops this.  Remember that +initialize+ is private,\n#   so you won't see the documentation unless you use the +-a+ command line\n#   option.\n#\n# === Method arguments\n#\n# [+:arg:+ or +:args:+ _parameters_]\n#   Overrides the default argument handling with exactly these parameters.\n#\n#     ##\n#     #  :args: a, b\n#\n#     def some_method(*a)\n#     end\n#\n# [+:yield:+ or +:yields:+ _parameters_]\n#   Overrides the default yield discovery with these parameters.\n#\n#     ##\n#     # :yields: key, value\n#\n#     def each_thing &block\n#       @things.each(&block)\n#     end\n#\n# [+:call-seq:+]\n#   Lines up to the next blank line or lines with a common prefix in the\n#   comment are treated as the method's calling sequence, overriding the\n#   default parsing of method parameters and yield arguments.\n#\n#   Multiple lines may be used.\n#\n#     # :call-seq:\n#     #   ARGF.readlines(sep=$/)     -> array\n#     #   ARGF.readlines(limit)      -> array\n#     #   ARGF.readlines(sep, limit) -> array\n#     #\n#     #   ARGF.to_a(sep=$/)     -> array\n#     #   ARGF.to_a(limit)      -> array\n#     #   ARGF.to_a(sep, limit) -> array\n#     #\n#     # The remaining lines are documentation ...\n#\n# === Sections\n#\n# Sections allow you to group methods in a class into sensible containers.  If\n# you use the sections 'Public', 'Internal' and 'Deprecated' (the three\n# allowed method statuses from TomDoc) the sections will be displayed in that\n# order placing the most useful methods at the top.  Otherwise, sections will\n# be displayed in alphabetical order.\n#\n# [+:category:+ _section_]\n#   Adds this item to the named +section+ overriding the current section.  Use\n#   this to group methods by section in RDoc output while maintaining a\n#   sensible ordering (like alphabetical).\n#\n#     # :category: Utility Methods\n#     #\n#     # CGI escapes +text+\n#\n#     def convert_string text\n#       CGI.escapeHTML text\n#     end\n#\n#   An empty category will place the item in the default category:\n#\n#     # :category:\n#     #\n#     # This method is in the default category\n#\n#     def some_method\n#       # ...\n#     end\n#\n#   Unlike the :section: directive, :category: is not sticky.  The category\n#   only applies to the item immediately following the comment.\n#\n#   Use the :section: directive to provide introductory text for a section of\n#   documentation.\n#\n# [+:section:+ _title_]\n#   Provides section introductory text in RDoc output.  The title following\n#   +:section:+ is used as the section name and the remainder of the comment\n#   containing the section is used as introductory text.  A section's comment\n#   block must be separated from following comment blocks.  Use an empty title\n#   to switch to the default section.\n#\n#   The :section: directive is sticky, so subsequent methods, aliases,\n#   attributes, and classes will be contained in this section until the\n#   section is changed.  The :category: directive will override the :section:\n#   directive.\n#\n#   A :section: comment block may have one or more lines before the :section:\n#   directive.  These will be removed, and any identical lines at the end of\n#   the block are also removed.  This allows you to add visual cues to the\n#   section.\n#\n#   Example:\n#\n#     # ----------------------------------------\n#     # :section: My Section\n#     # This is the section that I wrote.\n#     # See it glisten in the noon-day sun.\n#     # ----------------------------------------\n#\n#     ##\n#     # Comment for some_method\n#\n#     def some_method\n#       # ...\n#     end\n#\n# === Other directives\n#\n# [+:markup:+ _type_]\n#   Overrides the default markup type for this comment with the specified\n#   markup type.  For Ruby files, if the first comment contains this directive\n#   it is applied automatically to all comments in the file.\n#\n#   Unless you are converting between markup formats you should use a\n#   <code>.rdoc_options</code> file to specify the default documentation\n#   format for your entire project.  See RDoc::Options@Saved+Options for\n#   instructions.\n#\n#   At the top of a file the +:markup:+ directive applies to the entire file:\n#\n#     # coding: UTF-8\n#     # :markup: TomDoc\n#\n#     # TomDoc comment here ...\n#\n#     class MyClass\n#       # ...\n#\n#   For just one comment:\n#\n#       # ...\n#     end\n#\n#     # :markup: RDoc\n#     #\n#     # This is a comment in RDoc markup format ...\n#\n#     def some_method\n#       # ...\n#\n#   See Markup@CONTRIBUTING for instructions on adding a new markup format.\n#\n# [+:include:+ _filename_]\n#   Include the contents of the named file at this point. This directive\n#   must appear alone on one line, possibly preceded by spaces. In this\n#   position, it can be escaped with a \\ in front of the first colon.\n#\n#   The file will be searched for in the directories listed by the +--include+\n#   option, or in the current directory by default.  The contents of the file\n#   will be shifted to have the same indentation as the ':' at the start of\n#   the +:include:+ directive.\n#\n# [+:title:+ _text_]\n#   Sets the title for the document.  Equivalent to the <tt>--title</tt>\n#   command line parameter.  (The command line parameter overrides any :title:\n#   directive in the source).\n#\n# [+:main:+ _name_]\n#   Equivalent to the <tt>--main</tt> command line parameter.\n#\n#--\n# Original Author:: Dave Thomas,  dave@pragmaticprogrammer.com\n# License:: Ruby license\n\nclass RDoc::Markup\n\n  ##\n  # An AttributeManager which handles inline markup.\n\n  attr_reader :attribute_manager\n\n  ##\n  # Parses +str+ into an RDoc::Markup::Document.\n\n  def self.parse str\n    RDoc::Markup::Parser.parse str\n  rescue RDoc::Markup::Parser::Error => e\n    $stderr.puts <<-EOF\nWhile parsing markup, RDoc encountered a #{e.class}:\n\n#{e}\n\\tfrom #{e.backtrace.join \"\\n\\tfrom \"}\n\n---8<---\n#{text}\n---8<---\n\nRDoc #{RDoc::VERSION}\n\nRuby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} #{RUBY_RELEASE_DATE}\n\nPlease file a bug report with the above information at:\n\nhttps://github.com/ruby/rdoc/issues\n\n    EOF\n    raise\n  end\n\n  ##\n  # Take a block of text and use various heuristics to determine its\n  # structure (paragraphs, lists, and so on).  Invoke an event handler as we\n  # identify significant chunks.\n\n  def initialize attribute_manager = nil\n    @attribute_manager = attribute_manager || RDoc::Markup::AttributeManager.new\n    @output = nil\n  end\n\n  ##\n  # Add to the sequences used to add formatting to an individual word (such\n  # as *bold*).  Matching entries will generate attributes that the output\n  # formatters can recognize by their +name+.\n\n  def add_word_pair(start, stop, name)\n    @attribute_manager.add_word_pair(start, stop, name)\n  end\n\n  ##\n  # Add to the sequences recognized as general markup.\n\n  def add_html(tag, name)\n    @attribute_manager.add_html(tag, name)\n  end\n\n  ##\n  # Add to other inline sequences.  For example, we could add WikiWords using\n  # something like:\n  #\n  #    parser.add_regexp_handling(/\\b([A-Z][a-z]+[A-Z]\\w+)/, :WIKIWORD)\n  #\n  # Each wiki word will be presented to the output formatter.\n\n  def add_regexp_handling(pattern, name)\n    @attribute_manager.add_regexp_handling(pattern, name)\n  end\n\n  ##\n  # We take +input+, parse it if necessary, then invoke the output +formatter+\n  # using a Visitor to render the result.\n\n  def convert input, formatter\n    document = case input\n               when RDoc::Markup::Document then\n                 input\n               else\n                 RDoc::Markup::Parser.parse input\n               end\n\n    document.accept formatter\n  end\n\n  autoload :Parser,                'rdoc/markup/parser'\n  autoload :PreProcess,            'rdoc/markup/pre_process'\n\n  # Inline markup classes\n  autoload :AttrChanger,           'rdoc/markup/attr_changer'\n  autoload :AttrSpan,              'rdoc/markup/attr_span'\n  autoload :Attributes,            'rdoc/markup/attributes'\n  autoload :AttributeManager,      'rdoc/markup/attribute_manager'\n  autoload :RegexpHandling,        'rdoc/markup/regexp_handling'\n\n  # RDoc::Markup AST\n  autoload :BlankLine,             'rdoc/markup/blank_line'\n  autoload :BlockQuote,            'rdoc/markup/block_quote'\n  autoload :Document,              'rdoc/markup/document'\n  autoload :HardBreak,             'rdoc/markup/hard_break'\n  autoload :Heading,               'rdoc/markup/heading'\n  autoload :Include,               'rdoc/markup/include'\n  autoload :IndentedParagraph,     'rdoc/markup/indented_paragraph'\n  autoload :List,                  'rdoc/markup/list'\n  autoload :ListItem,              'rdoc/markup/list_item'\n  autoload :Paragraph,             'rdoc/markup/paragraph'\n  autoload :Raw,                   'rdoc/markup/raw'\n  autoload :Rule,                  'rdoc/markup/rule'\n  autoload :Verbatim,              'rdoc/markup/verbatim'\n\n  # Formatters\n  autoload :Formatter,             'rdoc/markup/formatter'\n  autoload :FormatterTestCase,     'rdoc/markup/formatter_test_case'\n  autoload :TextFormatterTestCase, 'rdoc/markup/text_formatter_test_case'\n\n  autoload :ToAnsi,                'rdoc/markup/to_ansi'\n  autoload :ToBs,                  'rdoc/markup/to_bs'\n  autoload :ToHtml,                'rdoc/markup/to_html'\n  autoload :ToHtmlCrossref,        'rdoc/markup/to_html_crossref'\n  autoload :ToHtmlSnippet,         'rdoc/markup/to_html_snippet'\n  autoload :ToLabel,               'rdoc/markup/to_label'\n  autoload :ToMarkdown,            'rdoc/markup/to_markdown'\n  autoload :ToRdoc,                'rdoc/markup/to_rdoc'\n  autoload :ToTableOfContents,     'rdoc/markup/to_table_of_contents'\n  autoload :ToTest,                'rdoc/markup/to_test'\n  autoload :ToTtOnly,              'rdoc/markup/to_tt_only'\n\nend\n\n"
  },
  {
    "path": "Units/parser-rdoc.r/run-as-guest.d/languages",
    "content": "RDoc\n"
  },
  {
    "path": "Units/parser-rdoc.r/simple-rdoc.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-rdoc.r/simple-rdoc.d/expected.tags",
    "content": "a\tinput.rdoc\t/^= a$/;\"\th\tline:1\tend:14\nb\tinput.rdoc\t/^== b$/;\"\ti\tline:3\tL1Header:a\tend:8\nc\tinput.rdoc\t/^=== c$/;\"\tj\tline:5\tL2Header:a\"\"b\tend:6\nd\tinput.rdoc\t/^=== d$/;\"\tj\tline:7\tL2Header:a\"\"b\tend:8\ne\tinput.rdoc\t/^== e$/;\"\ti\tline:9\tL1Header:a\tend:14\nX\tinput.rdoc\t/^==== X$/;\"\tk\tline:11\tL2Header:a\"\"e\tend:14\nY\tinput.rdoc\t/^===== Y$/;\"\tl\tline:13\tL4Header:a\"\"e\"\"X\tend:14\nf\tinput.rdoc\t/^= f$/;\"\th\tline:15\tend:15\n"
  },
  {
    "path": "Units/parser-rdoc.r/simple-rdoc.d/input.rdoc",
    "content": "= a\n\n== b\n\n=== c\n\n=== d\n\n== e\n\n==== X\n\n===== Y\n\n= f\n"
  },
  {
    "path": "Units/parser-rdoc.r/simple-rdoc.d/languages",
    "content": "RDoc\n"
  },
  {
    "path": "Units/parser-rdoc.r/too-deep-level.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-rdoc.r/too-deep-level.d/expected.tags",
    "content": "level1\tinput.rdoc\t/^= level1$/;\"\th\tline:1\tend:8\nlevel2\tinput.rdoc\t/^== level2$/;\"\ti\tline:2\tL1Header:level1\tend:8\nlevel3\tinput.rdoc\t/^=== level3$/;\"\tj\tline:3\tL2Header:level1\"\"level2\tend:8\nlevel4\tinput.rdoc\t/^==== level4$/;\"\tk\tline:4\tL3Header:level1\"\"level2\"\"level3\tend:8\nlevel5\tinput.rdoc\t/^===== level5$/;\"\tl\tline:5\tL4Header:level1\"\"level2\"\"level3\"\"level4\tend:8\nlevel6\tinput.rdoc\t/^====== level6$/;\"\tm\tline:6\tL5Header:level1\"\"level2\"\"level3\"\"level4\"\"level5\tend:8\nlevel1'\tinput.rdoc\t/^= level1'$/;\"\th\tline:9\tend:23\nlevel2'\tinput.rdoc\t/^== level2'$/;\"\ti\tline:10\tL1Header:level1'\tend:22\nlevel3'\tinput.rdoc\t/^=== level3'$/;\"\tj\tline:11\tL2Header:level1'\"\"level2'\tend:21\nlevel4'\tinput.rdoc\t/^==== level4'$/;\"\tk\tline:12\tL3Header:level1'\"\"level2'\"\"level3'\tend:20\nlevel5'\tinput.rdoc\t/^===== level5'$/;\"\tl\tline:13\tL4Header:level1'\"\"level2'\"\"level3'\"\"level4'\tend:19\nlevel6'\tinput.rdoc\t/^====== level6'$/;\"\tm\tline:14\tL5Header:level1'\"\"level2'\"\"level3'\"\"level4'\"\"level5'\tend:18\nlevel6''\tinput.rdoc\t/^====== level6''$/;\"\tm\tline:19\tL5Header:level1'\"\"level2'\"\"level3'\"\"level4'\"\"level5'\tend:19\nlevel5''\tinput.rdoc\t/^===== level5''$/;\"\tl\tline:20\tL4Header:level1'\"\"level2'\"\"level3'\"\"level4'\tend:20\nlevel4''\tinput.rdoc\t/^==== level4''$/;\"\tk\tline:21\tL3Header:level1'\"\"level2'\"\"level3'\tend:21\nlevel3''\tinput.rdoc\t/^=== level3''$/;\"\tj\tline:22\tL2Header:level1'\"\"level2'\tend:22\nlevel2''\tinput.rdoc\t/^== level2''$/;\"\ti\tline:23\tL1Header:level1'\tend:23\nlevel1''\tinput.rdoc\t/^= level1''$/;\"\th\tline:24\tend:25\n"
  },
  {
    "path": "Units/parser-rdoc.r/too-deep-level.d/input.rdoc",
    "content": "= level1\n== level2\n=== level3\n==== level4\n===== level5\n====== level6\n======= level7\n======== level8\n= level1'\n== level2'\n=== level3'\n==== level4'\n===== level5'\n====== level6'\n======= level7'\n======== level8'\n======== level8''\n======= level7''\n====== level6''\n===== level5''\n==== level4''\n=== level3''\n== level2''\n= level1''\n\n"
  },
  {
    "path": "Units/parser-rdoc.r/too-deep-level.d/languages",
    "content": "RDoc\n"
  },
  {
    "path": "Units/parser-relaxng.r/element.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-relaxng.r/element.d/expected.tags",
    "content": "ns23baa9ce0101\tinput.rng\t/^<element name=\"script\" xmlns=\"http:\\/\\/relaxng.org\\/ns\\/structure\\/0.9\">$/;\"\tn\turi:http://relaxng.org/ns/structure/0.9\nscript\tinput.rng\t/^<element name=\"script\" xmlns=\"http:\\/\\/relaxng.org\\/ns\\/structure\\/0.9\">$/;\"\te\nfunction\tinput.rng\t/^    <element name=\"function\">$/;\"\te\telement:script\nvariable\tinput.rng\t/^\t<element name=\"variable\">$/;\"\te\telement:script.function\nreadonly\tinput.rng\t/^\t  <attribute name=\"readonly\">$/;\"\ta\telement:script.function.variable\n"
  },
  {
    "path": "Units/parser-relaxng.r/element.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-relaxng.r/element.d/input.rng",
    "content": "<element name=\"script\" xmlns=\"http://relaxng.org/ns/structure/0.9\">\n  <zeroOrMore>\n    <element name=\"function\">\n      <zeroOrMore>\n\t<element name=\"variable\">\n\t  <attribute name=\"readonly\">\n\t    <text/>\n\t  </attribute>\n\t  <text/>\n\t</element>\n      </zeroOrMore>\n    </element>\n  </zeroOrMore>\n</element>\n"
  },
  {
    "path": "Units/parser-relaxng.r/grammar.d/args.ctags",
    "content": "--sort=no\n--excmd=n\n"
  },
  {
    "path": "Units/parser-relaxng.r/grammar.d/expected.tags",
    "content": "ns47c728eb0101\tinput.rng\t26;\"\tn\turi:http://relaxng.org/ns/structure/1.0\na\tinput.rng\t26;\"\tn\turi:http://relaxng.org/ns/annotation/1.0\ngjdoc\tinput.rng\t26;\"\tn\turi:http://www.gnu.org/software/cp-tools/gjdocxml\nfirstSentenceTags-element\tinput.rng\t34;\"\tn\ngjdoc:firstSentenceTags\tinput.rng\t39;\"\te\tnamedPattern:firstSentenceTags-element\ninlineTags-element\tinput.rng\t44;\"\tn\ngjdoc:inlineTags\tinput.rng\t49;\"\te\tnamedPattern:inlineTags-element\nseeTags-element\tinput.rng\t54;\"\tn\ngjdoc:seeTags\tinput.rng\t59;\"\te\tnamedPattern:seeTags-element\ntags-element\tinput.rng\t65;\"\tn\ngjdoc:tags\tinput.rng\t70;\"\te\tnamedPattern:tags-element\ntags-contents\tinput.rng\t75;\"\tn\nimplements-element\tinput.rng\t86;\"\tn\ngjdoc:implements\tinput.rng\t87;\"\te\tnamedPattern:implements-element\nsuperimplements-element\tinput.rng\t97;\"\tn\ngjdoc:superimplements\tinput.rng\t98;\"\te\tnamedPattern:superimplements-element\ntypedef-attributes\tinput.rng\t110;\"\tn\ntypename\tinput.rng\t111;\"\ta\tnamedPattern:typedef-attributes\ndimension\tinput.rng\t124;\"\ta\tnamedPattern:typedef-attributes\nname-attribute\tinput.rng\t135;\"\tn\nname\tinput.rng\t136;\"\ta\tnamedPattern:name-attribute\nqualifiedtypename-attribute\tinput.rng\t146;\"\tn\nqualifiedtypename\tinput.rng\t147;\"\ta\tnamedPattern:qualifiedtypename-attribute\nsuperclass-element\tinput.rng\t156;\"\tn\ngjdoc:superclass\tinput.rng\t157;\"\te\tnamedPattern:superclass-element\ntag-element\tinput.rng\t166;\"\tn\ngjdoc:tag\tinput.rng\t167;\"\te\tnamedPattern:tag-element\nkind\tinput.rng\t169;\"\ta\telement:tag-element.gjdoc:tag\nexception-element\tinput.rng\t178;\"\tn\ngjdoc:exception\tinput.rng\t179;\"\te\tnamedPattern:exception-element\nTagContent\tinput.rng\t184;\"\tn\ncontainingPackage-element\tinput.rng\t212;\"\tn\ngjdoc:containingPackage\tinput.rng\t213;\"\te\tnamedPattern:containingPackage-element\nname\tinput.rng\t217;\"\ta\telement:containingPackage-element.gjdoc:containingPackage\ntagletText-element\tinput.rng\t223;\"\tn\ngjdoc:tagletText\tinput.rng\t224;\"\te\tnamedPattern:tagletText-element\ntagName\tinput.rng\t228;\"\ta\telement:tagletText-element.gjdoc:tagletText\nisError-element\tinput.rng\t237;\"\tn\ngjdoc:isError\tinput.rng\t238;\"\te\tnamedPattern:isError-element\nisException-element\tinput.rng\t246;\"\tn\ngjdoc:isException\tinput.rng\t247;\"\te\tnamedPattern:isException-element\nisInterface-element\tinput.rng\t255;\"\tn\ngjdoc:isInterface\tinput.rng\t256;\"\te\tnamedPattern:isInterface-element\n"
  },
  {
    "path": "Units/parser-relaxng.r/grammar.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-relaxng.r/grammar.d/input.rng",
    "content": "<?xml version=\"1.0\"?>\n\n<!-- gjdoc-common.rng\n     Copyright (C) 2003 Free Software Foundation, Inc.\n\nThis file is part of GNU Classpath.\n\nGNU Classpath is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 2, or (at your option)\nany later version.\n \nGNU Classpath is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\nGeneral Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with GNU Classpath; see the file COPYING.  If not, write to the\nFree Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\n02111-1307 USA. -->\n\n<grammar \n      xmlns=\"http://relaxng.org/ns/structure/1.0\" \n      xmlns:a=\"http://relaxng.org/ns/annotation/1.0\" \n      xmlns:gjdoc=\"http://www.gnu.org/software/cp-tools/gjdocxml\">\n   \n   <a:documentation>\n      A Relax NG grammar with definitions of elements and attributes\n      used by both the XML index file and the XML class files\n      generated by GNU Gjdoc.\n   </a:documentation>\n\n   <define name=\"firstSentenceTags-element\">\n      <a:documentation>\n\n      </a:documentation>\n\n      <element name=\"gjdoc:firstSentenceTags\">\n\t <ref name=\"tags-contents\"/>\n      </element>\n   </define>\n\n   <define name=\"inlineTags-element\">\n      <a:documentation>\n\n      </a:documentation>\n\n      <element name=\"gjdoc:inlineTags\">\n\t <ref name=\"tags-contents\"/>\n      </element>\n   </define>\n\n   <define name=\"seeTags-element\">\n      <a:documentation>\n\n      </a:documentation>\n\n      <element name=\"gjdoc:seeTags\">\n\t <ref name=\"tags-contents\"/>\n      </element>\n   </define>\n\n\n   <define name=\"tags-element\">\n      <a:documentation>\n\n      </a:documentation>\n\n      <element name=\"gjdoc:tags\">\n\t <ref name=\"tags-contents\"/>\n      </element>\n   </define>\n\n   <define name=\"tags-contents\">\n      <a:documentation>\n\t Specifies mixed content comprised of gjdoc tags,\n\t HTML tags, taglet output, and text.\n      </a:documentation>\n\n      <zeroOrMore>\n\t <ref name=\"TagContent\"/>\n      </zeroOrMore>\n   </define>\n\n   <define name=\"implements-element\">\n      <element name=\"gjdoc:implements\">\n\t <a:documentation>\n\t    Specifies an interface that the class implements.\n\t </a:documentation>\n\t \n\t <ref name=\"typedef-attributes\"/>\n      </element>\n   </define>\n\n\n   <define name=\"superimplements-element\">\n      <element name=\"gjdoc:superimplements\">\n\t <a:documentation>\n\t    Specifies an interface implemented by superclasses\n\t    (ancestors) of the class. Together with the interfaces\n\t    specified with tag `implements', this lists all interfaces\n\t    the class can be cast to.\n\t </a:documentation>\n\t \n\t <ref name=\"typedef-attributes\"/>\n      </element>\n   </define>\n\n   <define name=\"typedef-attributes\">\n      <attribute name=\"typename\">\n\t <a:documentation>\n\t    The name of the class, without package prefix. If the\n\t    class is an inner class, this includes the name of its\n\t    outer class.\n\t </a:documentation>\n\n\t <text/>\n      </attribute>\n      \n      <ref name=\"qualifiedtypename-attribute\"/>\n\n      <optional>\n\t <attribute name=\"dimension\">\n\t    <a:documentation>\n\t       The dimension of this typedef, represented by a zero or\n\t       more repetitions of the string \"[]\".\n\t    </a:documentation>\n\n\t    <text/>\n\t </attribute>\n      </optional>\n   </define>\n\n   <define name=\"name-attribute\">\n      <attribute name=\"name\">\n\t <a:documentation>\n\t    The name of some Java Entity (package, class, constructor,\n\t    method, field.)\n\t </a:documentation>\n\n\t <text/>\n      </attribute>\n   </define>\n\n   <define name=\"qualifiedtypename-attribute\">\n      <attribute name=\"qualifiedtypename\">\n\t <a:documentation>\n\t    The fully qualified name of the class.\n\t </a:documentation>\n\n\t <text/>\n      </attribute>\n   </define>\n\n   <define name=\"superclass-element\">\n      <element name=\"gjdoc:superclass\">\n\t <a:documentation>\n\t    Specifies the superclass of the class.\n\t </a:documentation>\n\t \n\t <ref name=\"typedef-attributes\"/>\n      </element>\n   </define>\n\n   <define name=\"tag-element\">\n      <element name=\"gjdoc:tag\">\n\t <ref name=\"name-attribute\"/>\n\t <attribute name=\"kind\">\n\t    <text/>\n\t </attribute>\n\t <zeroOrMore>\n\t    <ref name=\"TagContent\"/>\n\t </zeroOrMore>\n      </element>\n   </define>\n\n   <define name=\"exception-element\">\n      <element name=\"gjdoc:exception\">\n\t <ref name=\"typedef-attributes\"/>\n      </element>\n   </define>\n\n   <define name=\"TagContent\">\n      <choice>\n\t <element>\n\t    <anyName>\n\t       <except>\n\t\t  <nsName ns=\"gjdoc\"/>\n\t\t  <name>gjdoc:tag</name>\n\t       </except>\n\t    </anyName>\n\t    <zeroOrMore>\n\t       <attribute>\n\t\t  <anyName/>\n\t       </attribute>\n\t    </zeroOrMore>\n\t    <zeroOrMore>\n\t       <choice>\n\t\t  <text/>\n\t\t  <ref name=\"TagContent\"/>\n\t       </choice>\n\t    </zeroOrMore>\n\t </element>\n\t <ref name=\"tag-element\"/>\n\t <ref name=\"exception-element\"/>\n\t <ref name=\"tagletText-element\"/>\n\t <text/>\n      </choice>\n   </define>\n\n   <define name=\"containingPackage-element\">\n      <element name=\"gjdoc:containingPackage\">\n\t <a:documentation>\n\t    The full name of the package containing the class.\n\t </a:documentation>\n\t <attribute name=\"name\">\n\t    <text/>\n\t </attribute>\n      </element>\n   </define>\n\n   <define name=\"tagletText-element\">\n      <element name=\"gjdoc:tagletText\">\n\t <a:documentation>\n\t    A string generated by a Taglet.toString() method.\n\t </a:documentation>\n\t <attribute name=\"tagName\">\n            <a:documentation>\n               The name of the tag this Taglet was assigned to.\n            </a:documentation>\n\t    <text/>\n\t </attribute>\n      </element>\n   </define>\n\n   <define name=\"isError-element\">\n      <element name=\"gjdoc:isError\">\n\t <a:documentation>\n\t    Exists when the described class is a subclass of\n\t    java.lang.Error.\n\t </a:documentation>\n      </element>\n   </define>\n\n   <define name=\"isException-element\">\n      <element name=\"gjdoc:isException\">\n\t <a:documentation>\n\t    Exists when the described class is a subclass of\n\t    java.lang.Exception.\n\t </a:documentation>\n      </element>\n   </define>\n\n   <define name=\"isInterface-element\">\n      <element name=\"gjdoc:isInterface\">\n\t <a:documentation>\n\t    Exists when the described class is an interface.\n\t </a:documentation>\n      </element>\n   </define>\n\n</grammar>\n\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/citation.d/args.ctags",
    "content": "--sort=no\n--fields-ReStructuredText=+{overline}{sectionMarker}\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/citation.d/expected.tags",
    "content": "KVM VCPU Requests\tinput.rst\t/^KVM VCPU Requests$/;\"\tH\tsectionMarker:=\toverline:\nVCPU Request Internals\tinput.rst\t/^VCPU Request Internals$/;\"\tc\ttitle:KVM VCPU Requests\tsectionMarker:=\nReferences\tinput.rst\t/^References$/;\"\tc\ttitle:KVM VCPU Requests\tsectionMarker:=\natomic-ops\tinput.rst\t/^.. [atomic-ops] Documentation\\/core-api\\/atomic_ops.rst$/;\"\tC\tchapter:References\nmemory-barriers\tinput.rst\t/^.. [memory-barriers] Documentation\\/memory-barriers.txt$/;\"\tC\tchapter:References\nlwn-mb\tinput.rst\t/^.. [lwn-mb] https:\\/\\/lwn.net\\/Articles\\/573436\\/$/;\"\tC\tchapter:References\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/citation.d/input.rst",
    "content": "=================\nKVM VCPU Requests\n=================\n\nThis text is partially taken from documentation/virt/kvm/vcpu-requests.rst of\nLinux kernel.\n\n...\n\nVCPU Request Internals\n======================\n\nVCPU requests are simply bit indices of the ``vcpu->requests`` bitmap.\nThis means general bitops, like those documented in [atomic-ops]_ could\nalso be used, e.g. ::\n\n  clear_bit(KVM_REQ_UNHALT & KVM_REQUEST_MASK, &vcpu->requests);\n\nHowever, VCPU request users should refrain from doing so, as it would\nbreak the abstraction.  The first 8 bits are reserved for architecture\nindependent requests, all additional bits are available for architecture\ndependent requests.\n\n...\n\nReferences\n==========\n\n.. [atomic-ops] Documentation/core-api/atomic_ops.rst\n.. [memory-barriers] Documentation/memory-barriers.txt\n.. [lwn-mb] https://lwn.net/Articles/573436/\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/code-blocks.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+lE\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/code-blocks.d/expected.tags",
    "content": "C Language Example\tinput.rst\t/^C Language Example$/;\"\tH\tlanguage:ReStructuredText\nTest 1\tinput.rst\t/^Test 1$/;\"\tc\tlanguage:ReStructuredText\ttitle:C Language Example\nTest 2\tinput.rst\t/^Test 2$/;\"\tc\tlanguage:ReStructuredText\ttitle:C Language Example\ntest1_0\tinput.rst\t/^\tint test1_0(void)$/;\"\tf\tlanguage:C\ttyperef:typename:int\textras:guest\ntest1_1\tinput.rst\t/^\tint test1_1(void)$/;\"\tf\tlanguage:C\ttyperef:typename:int\textras:guest\ntest1_2\tinput.rst\t/^\tint test1_2(void)$/;\"\tf\tlanguage:C\ttyperef:typename:int\textras:guest\ntest1_3\tinput.rst\t/^\tint test1_3(void)$/;\"\tf\tlanguage:C\ttyperef:typename:int\textras:guest\ntest2_0\tinput.rst\t/^\tint test2_0(void)$/;\"\tf\tlanguage:C\ttyperef:typename:int\textras:guest\nTITLE\tinput-1.rst\t/^TITLE$/;\"\tH\tlanguage:ReStructuredText\nDEF\tinput-2.rst\t/^\t  #define DEF /;\"\td\tlanguage:C\tfile:\textras:fileScope,guest\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/code-blocks.d/input-0.rst",
    "content": "No thing here.\n.. code-block:: c\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/code-blocks.d/input-1.rst",
    "content": ".. code-block:: c\n.. code-block:: c\n.. code-block:: c\nTITLE\n---------------------\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/code-blocks.d/input-2.rst",
    "content": "* an item\n\n  .. code-block:: C\n\n\t  #define DEF 1\n\n  int this_is_not_c_code ();\n\n* another item\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/code-blocks.d/input.rst",
    "content": "==========================\nC Language Example\n==========================\n\nTest 1\n---------------------\n\n.. code-block:: c\n\n\tint test1_0(void)\n\t{\n\t\treturn 0;\n\t}\n\n\tint test1_1(void)\n\t{\n\t\treturn 0;\n\t}\n\nSome descriptions here.\n\n.. code-block:: c\n\n\tint test1_2(void)\n\t{\n\t\treturn 0;\n\t}\n\n\tint test1_3(void)\n\t{\n\t\treturn 0;\n\t}\n\nTest 2\n---------------------\n\nSome descriptions here.\n\n.. code-block:: c\n\n\tint test2_0(void)\n\t{\n\t\treturn 0;\n\t}\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/iso8859-1-restructuredtext.d/expected.tags",
    "content": "Chptr 1\tinput.rst\t/^Chptr 1$/;\"\tc\tsubtitle:Sbittl\nSubsubsection 1.1.1.1\tinput.rst\t/^Subsubsection 1.1.1.1$/;\"\tt\tsubsection:Sbs\nStin 1.1\tinput.rst\t/^Stin 1.1$/;\"\ts\tchapter:Chptr 1\nSbs\tinput.rst\t/^Sbs$/;\"\tS\tsection:Stin 1.1\nSbittl\tinput.rst\t/^Sbittl$/;\"\th\ttitle:Ttl\nTtl\tinput.rst\t/^Ttl$/;\"\tH\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/iso8859-1-restructuredtext.d/input.rst",
    "content": "=======================================\nTtl\n=======================================\n---------------------------------------\nSbittl\n---------------------------------------\n\nChptr 1\n=========\n\nIntro text of chapter 1\n\nStin 1.1\n-----------\n\nText of section 1.1\n\nSbs\n++++\n\nText of subsection 1.1.1\n\nSubsubsection 1.1.1.1\n~~~~~~~~~~~~~~~~~~~~~\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/markup-line-with-spaces.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/markup-line-with-spaces.d/expected.tags",
    "content": "OVERVIEW\tinput.rst\t/^  .. [OVERVIEW] `Satellite Overview, Concepts, and Deployment Considerations <https:\\/\\/access.r/;\"\tC\nADMIN\tinput.rst\t/^  .. [ADMIN] `Administering Red Hat Satellite <https:\\/\\/access.redhat.com\\/documentation\\/en-us/;\"\tC\nLOC\tinput.rst\t/^  .. [LOC] `Chapter 6. Managing Locations <https:\\/\\/access.redhat.com\\/documentation\\/en-us\\/re/;\"\tC\nUSERROLE\tinput.rst\t/^  .. [USERROLE] `Chapter 7. Managing Users and Roles <https:\\/\\/access.redhat.com\\/documentation/;\"\tC\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/markup-line-with-spaces.d/input.rst",
    "content": "* Satellite Overview\n\n  .. [OVERVIEW] `Satellite Overview, Concepts, and Deployment Considerations <https://access.redhat.com/documentation/en-us/red_hat_satellite/6.12/html/satellite_overview_concepts_and_deployment_considerations/index>`_\n\n* Administering Red Hat Satellite\n\n  .. [ADMIN] `Administering Red Hat Satellite <https://access.redhat.com/documentation/en-us/red_hat_satellite/6.12/html/administering_red_hat_satellite/index>`_\n\n  .. [LOC] `Chapter 6. Managing Locations <https://access.redhat.com/documentation/en-us/red_hat_satellite/6.12/html/administering_red_hat_satellite/managing_locations_admin>`_\n\n  .. [USERROLE] `Chapter 7. Managing Users and Roles <https://access.redhat.com/documentation/en-us/red_hat_satellite/6.12/html/administering_red_hat_satellite/managing_users_and_roles_admin#doc-wrapper>`_\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/simple-restructuredtext.d/args.ctags",
    "content": "--fields-all=+{sectionMarker}\n--fields=+{end}\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/simple-restructuredtext.d/expected.tags",
    "content": "Chapter 1\tinput.rst\t/^Chapter 1$/;\"\tc\tend:25\tsectionMarker:=\nChapter 2\tinput.rst\t/^Chapter 2$/;\"\tc\tend:39\tsectionMarker:=\nSection 1.1\tinput.rst\t/^Section 1.1$/;\"\ts\tchapter:Chapter 1\tend:20\tsectionMarker:-\nSection 1.2\tinput.rst\t/^Section 1.2$/;\"\ts\tchapter:Chapter 1\tend:25\tsectionMarker:-\nSection 2.1\tinput.rst\t/^Section 2.1$/;\"\ts\tchapter:Chapter 2\tend:35\tsectionMarker:-\nSection 2.2\tinput.rst\t/^Section 2.2$/;\"\ts\tchapter:Chapter 2\tend:39\tsectionMarker:-\nSubsection 1.1.1\tinput.rst\t/^Subsection 1.1.1$/;\"\tS\tsection:Section 1.1\tend:20\tsectionMarker:*\nSubsubsection 1.1.1.1\tinput.rst\t/^Subsubsection 1.1.1.1$/;\"\tt\tsubsection:Subsection 1.1.1\tend:20\tsectionMarker:~\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/simple-restructuredtext.d/input.rst",
    "content": "Chapter 1\n=========\n\nIntro text of chapter 1\n\nSection 1.1\n-----------\n\nText of section 1.1\n\nSubsection 1.1.1\n****************\n\nText of subsection 1.1.1\n\nSubsubsection 1.1.1.1\n~~~~~~~~~~~~~~~~~~~~~\n\nText of subsubsection 1.1.1.1\n\nSection 1.2\n-----------\n\nText of section 1.2\n\nChapter 2\n=========\n\nIntro text of chapter 2\n\nSection 2.1\n-----------\n\nText of section 2.1\n\nSection 2.2\n-----------\n\nText of section 2.2\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/substdef.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/substdef.d/expected.tags",
    "content": "struct cpuidle_state\tinput.rst\t/^.. |struct cpuidle_state| replace:: :c:type:`struct cpuidle_state <cpuidle_state>`$/;\"\td\ncpufreq\tinput.rst\t/^.. |cpufreq| replace:: :doc:`CPU Performance Scaling <cpufreq>`$/;\"\td\nCPU Idle Time Management\tinput.rst\t/^CPU Idle Time Management$/;\"\tH\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/substdef.d/input.rst",
    "content": ".. SPDX-License-Identifier: GPL-2.0\n\nThis text is partially taken from Documentation/admin-guide/pm/cpuidle.rst of\nLinux kernel.\n\n.. include:: <isonum.txt>\n\n.. |struct cpuidle_state| replace:: :c:type:`struct cpuidle_state <cpuidle_state>`\n.. |cpufreq| replace:: :doc:`CPU Performance Scaling <cpufreq>`\n\n========================\nCPU Idle Time Management\n========================\n\n:Copyright: |copy| 2018 Intel Corporation\n\n:Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/target-restructuredtext.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/target-restructuredtext.d/expected.tags",
    "content": "ANOTHER TITLE\tinput.rst\t/^ANOTHER TITLE$/;\"\tc\nTITLE\tinput.rst\t/^TITLE$/;\"\tc\ntitle-target\tinput.rst\t/^.. _title-target:$/;\"\tT\tchapter:TITLE\nsection0\tinput.rst\t/^section0$/;\"\ts\tchapter:TITLE\nsection target0\tinput.rst\t/^.. _`section target0`:$/;\"\tT\tsection:section0\nsection1\tinput.rst\t/^section1$/;\"\ts\tchapter:TITLE\nINCLUDING \\\\: in name\tinput.rst\t/^.. _INCLUDING \\\\: in name:$/;\"\tT\tsection:section1\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/target-restructuredtext.d/input.rst",
    "content": "===========================================\nANOTHER TITLE\n===========================================\n\n===========================================\nTITLE\n===========================================\n\n.. _title-target:\n\nsection0\n------------------------------------------\n\n.. _`section target0`:\n\nsection1\n------------------------------------------\n\n.. _       \t     `b r o k e n 2`   :\n\n..   \t  _broken1:\n\n.. _INCLUDING \\: in name:\n\n.. _\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/title.d/args.ctags",
    "content": "--sort=no\n--fields=+ZK\n--fields-ReStructuredText=+{sectionMarker}{overline}\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/title.d/expected.tags",
    "content": "TITLE\tinput.rst\t/^TITLE$/;\"\ttitle\tsectionMarker:=\toverline:\nSubtitle\tinput.rst\t/^Subtitle$/;\"\tsubtitle\tscope:title:TITLE\tsectionMarker:-\toverline:\na\tinput.rst\t/^.. [a] a.rst$/;\"\tcitation\tscope:subtitle:Subtitle\nChapter\tinput.rst\t/^Chapter$/;\"\tchapter\tscope:subtitle:Subtitle\tsectionMarker:=\nb\tinput.rst\t/^.. [b] b.rst$/;\"\tcitation\tscope:chapter:Chapter\nSection\tinput.rst\t/^Section$/;\"\tsection\tscope:chapter:Chapter\tsectionMarker:-\nc\tinput.rst\t/^.. [c] c.rst$/;\"\tcitation\tscope:section:Section\nSubsection\tinput.rst\t/^Subsection$/;\"\tsubsection\tscope:section:Section\tsectionMarker:|\nd\tinput.rst\t/^.. [d] d.rst$/;\"\tcitation\tscope:subsection:Subsection\nSubSubsection\tinput.rst\t/^SubSubsection$/;\"\tsubsubsection\tscope:subsection:Subsection\tsectionMarker:.\toverline:\ne\tinput.rst\t/^.. [e] e.rst$/;\"\tcitation\tscope:subsubsection:SubSubsection\nf\tinput.rst\t/^.. [f] f.rst$/;\"\tcitation\tscope:subsubsection:SubSubsection\ng\tinput.rst\t/^.. [g] g.rst$/;\"\tcitation\tscope:subsubsection:SubSubsection\nChapter2\tinput.rst\t/^Chapter2$/;\"\tchapter\tscope:subtitle:Subtitle\tsectionMarker:=\nh\tinput.rst\t/^.. [h] g.rst$/;\"\tcitation\tscope:chapter:Chapter2\nC0\tinput-0.rst\t/^C0$/;\"\tchapter\tsectionMarker:=\toverline:\nS0\tinput-0.rst\t/^S0$/;\"\tsection\tscope:chapter:C0\tsectionMarker:-\toverline:\ns0\tinput-0.rst\t/^s0$/;\"\tsubsection\tscope:section:S0\tsectionMarker:=\nC1\tinput-0.rst\t/^C1$/;\"\tchapter\tsectionMarker:=\toverline:\nS1\tinput-0.rst\t/^S1$/;\"\tsection\tscope:chapter:C1\tsectionMarker:-\toverline:\ns1\tinput-0.rst\t/^s1$/;\"\tsubsection\tscope:section:S1\tsectionMarker:=\nT0\tinput-1.rst\t/^                     T0$/;\"\ttitle\tsectionMarker:=\toverline:\nxC0\tinput-1.rst\t/^                     xC0$/;\"\tchapter\tscope:title:T0\tsectionMarker:-\toverline:\nxs0\tinput-1.rst\t/^xs0$/;\"\tsection\tscope:chapter:xC0\tsectionMarker:=\nxC1\tinput-1.rst\t/^xC1$/;\"\tchapter\tscope:title:T0\tsectionMarker:-\toverline:\nxs1\tinput-1.rst\t/^xs1$/;\"\tsection\tscope:chapter:xC1\tsectionMarker:=\nyT0\tinput-2.rst\t/^                   yT0$/;\"\ttitle\tsectionMarker:=\toverline:\nyST0\tinput-2.rst\t/^yST0$/;\"\tsubtitle\tscope:title:yT0\tsectionMarker:-\nyC0\tinput-2.rst\t/^yC0$/;\"\tchapter\tscope:subtitle:yST0\tsectionMarker:=\nyC1\tinput-2.rst\t/^yC1$/;\"\tchapter\tscope:subtitle:yST0\tsectionMarker:=\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/title.d/input-0.rst",
    "content": "==============================================\nC0\n==============================================\n----------------------------------------------\nS0\n----------------------------------------------\n\ns0\n==============================================\n\n==============================================\nC1\n==============================================\n----------------------------------------------\nS1\n----------------------------------------------\n\ns1\n==============================================\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/title.d/input-1.rst",
    "content": "==============================================\n                     T0\n==============================================\n----------------------------------------------\n                     xC0\n----------------------------------------------\n\nxs0\n==============================================\n\n----------------------------------------------\nxC1\n----------------------------------------------\n\nxs1\n==============================================\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/title.d/input-2.rst",
    "content": "==============================================\n                   yT0\n==============================================\n\nyST0\n----------------------------------------------\n\nyC0\n==============================================\n\n\nyC1\n==============================================\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/title.d/input.rst",
    "content": "==============================================\nTITLE\n==============================================\n----------------------------------------------\nSubtitle\n----------------------------------------------\n\n[a]_\n\n.. [a] a.rst\n\nChapter\n==============================================\n\n[b]_\n\n.. [b] b.rst\n\nSection\n---------------------------------------------\n\n[c]_\n\n.. [c] c.rst\n\nSubsection\n|||||||||||||||||||||||||||||||||||||||||||||\n\n[d]_\n\n.. [d] d.rst\n\n\n.............................................\nSubSubsection\n.............................................\n\n[e]_\n\n.. [e] e.rst\n\n\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\nSubSubSubsection will not be extracted.\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\n[f]_\n\n.. [f] f.rst\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\nSubSubSubSubsection will not be extracted.\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n[g]_\n\n.. [g] g.rst\n\nChapter2\n==============================================\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\nTitle level inconsistent:\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n[h]_\n\n.. [h] g.rst\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/utf8-restructuredtext.d/expected.tags",
    "content": "@Ѐ–𐀀\tinput.rst\t/^@Ѐ–𐀀$/;\"\tS\tsection:Šéçtiön 1.1\nChàptěr 1\tinput.rst\t/^Chàptěr 1$/;\"\tc\tsubtitle:Șůƀťițƚe\nSubsubsection 1.1.1.1\tinput.rst\t/^Subsubsection 1.1.1.1$/;\"\tt\tsubsection:@Ѐ–𐀀\nTitlə\tinput.rst\t/^Titlə$/;\"\tH\nŠéçtiön 1.1\tinput.rst\t/^Šéçtiön 1.1$/;\"\ts\tchapter:Chàptěr 1\nȘůƀťițƚe\tinput.rst\t/^Șůƀťițƚe$/;\"\th\ttitle:Titlə\n"
  },
  {
    "path": "Units/parser-restructuredtext.r/utf8-restructuredtext.d/input.rst",
    "content": "==========================================\nTitlə\n==========================================\n------------------------------------------\nȘůƀťițƚe\n------------------------------------------\n\nChàptěr 1\n=========\n\nIntro text of chapter 1\n\nŠéçtiön 1.1\n-----------\n\nText of section 1.1\n\n@Ѐ–𐀀\n++++\n\nText of subsection 1.1.1\n\nSubsubsection 1.1.1.1\n~~~~~~~~~~~~~~~~~~~~~\n"
  },
  {
    "path": "Units/parser-rmarkdown.r/frontmatter.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+KenlE\n"
  },
  {
    "path": "Units/parser-rmarkdown.r/frontmatter.d/expected.tags",
    "content": "S1\tinput.rmd\t/^# S1$/;\"\tchapter\tline:4\tlanguage:Markdown\tend:17\nxyX\tinput.rmd\t/^```{r xyX}$/;\"\tchunklabel\tline:6\tlanguage:RMarkdown\textras:subparser\tend:16\nS2\tinput.rmd\t/^# S2$/;\"\tchapter\tline:18\tlanguage:Markdown\tend:28\n__anon9d4e183a0100\tinput.rmd\t/^```{r, cache = TRUE, dependson = \"xyX\"}$/;\"\tchunklabel\tline:20\tlanguage:RMarkdown\textras:subparser,anonymous\tend:22\n__anon9d4e183a0200\tinput.rmd\t/^```{python}$/;\"\tchunklabel\tline:24\tlanguage:RMarkdown\textras:subparser,anonymous\tend:28\nS3\tinput.rmd\t/^# S3$/;\"\tchapter\tline:29\tlanguage:Markdown\tend:30\nx\tinput.rmd\t/^x <- 1$/;\"\tglobalVar\tline:8\tlanguage:R\textras:guest\tend:8\nfoo\tinput.rmd\t/^foo <- function () {$/;\"\tfunction\tline:9\tlanguage:R\textras:guest\tend:12\ny\tinput.rmd\t/^    y <- 2$/;\"\tfunctionVar\tline:10\tlanguage:R\tfunction:foo\textras:guest\tend:10\nX\tinput.rmd\t/^X <- func()$/;\"\tglobalVar\tline:14\tlanguage:R\textras:guest\tend:14\nf\tinput.rmd\t/^def f():$/;\"\tfunction\tline:25\tlanguage:Python\textras:guest\tend:27\nexample for u-ctags\tinput.rmd\t/^title: example for u-ctags/;\"\ttitle\tline:2\tlanguage:FrontMatter\textras:guest,subparser\n"
  },
  {
    "path": "Units/parser-rmarkdown.r/frontmatter.d/input.rmd",
    "content": "---\ntitle: example for u-ctags\n---\n# S1\n\n```{r xyX}\n\nx <- 1\nfoo <- function () {\n    y <- 2\n    return(y)\n}\n\nX <- func()\n\n```\n\n# S2\n\n```{r, cache = TRUE, dependson = \"xyX\"}\nmean(X)\n```\n\n```{python}\ndef f():\n   g()\n   return 3\n```\n# S3\n\n"
  },
  {
    "path": "Units/parser-rmarkdown.r/frontmatter.d/languages",
    "content": "Yaml\n"
  },
  {
    "path": "Units/parser-rmarkdown.r/simple-rmarkdown.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+KenlE\n"
  },
  {
    "path": "Units/parser-rmarkdown.r/simple-rmarkdown.d/expected.tags",
    "content": "S1\tinput.rmd\t/^# S1$/;\"\tchapter\tline:1\tlanguage:Markdown\tend:14\nxyX\tinput.rmd\t/^```{r xyX}$/;\"\tchunklabel\tline:3\tlanguage:RMarkdown\textras:subparser\tend:13\nS2\tinput.rmd\t/^# S2$/;\"\tchapter\tline:15\tlanguage:Markdown\tend:25\n__anon4a45a9700100\tinput.rmd\t/^```{r, cache = TRUE, dependson = \"xyX\"}$/;\"\tchunklabel\tline:17\tlanguage:RMarkdown\textras:subparser,anonymous\tend:19\n__anon4a45a9700200\tinput.rmd\t/^```{python}$/;\"\tchunklabel\tline:21\tlanguage:RMarkdown\textras:subparser,anonymous\tend:25\nS3\tinput.rmd\t/^# S3$/;\"\tchapter\tline:26\tlanguage:Markdown\tend:27\nx\tinput.rmd\t/^x <- 1$/;\"\tglobalVar\tline:5\tlanguage:R\textras:guest\tend:5\nfoo\tinput.rmd\t/^foo <- function () {$/;\"\tfunction\tline:6\tlanguage:R\textras:guest\tend:9\ny\tinput.rmd\t/^    y <- 2$/;\"\tfunctionVar\tline:7\tlanguage:R\tfunction:foo\textras:guest\tend:7\nX\tinput.rmd\t/^X <- func()$/;\"\tglobalVar\tline:11\tlanguage:R\textras:guest\tend:11\nf\tinput.rmd\t/^def f():$/;\"\tfunction\tline:22\tlanguage:Python\textras:guest\tend:24\n"
  },
  {
    "path": "Units/parser-rmarkdown.r/simple-rmarkdown.d/input.rmd",
    "content": "# S1\n\n```{r xyX}\n\nx <- 1\nfoo <- function () {\n    y <- 2\n    return(y)\n}\n\nX <- func()\n\n```\n\n# S2\n\n```{r, cache = TRUE, dependson = \"xyX\"}\nmean(X)\n```\n\n```{python}\ndef f():\n   g()\n   return 3\n```\n# S3\n\n"
  },
  {
    "path": "Units/parser-robot.r/dashes-in-identifiers.d/README",
    "content": "Taken from in a comment in #1406 posted by @mMontu.\n"
  },
  {
    "path": "Units/parser-robot.r/dashes-in-identifiers.d/expected.tags",
    "content": "My Keyword - Closed\tinput.robot\t/^My Keyword - Closed$/;\"\tk\nMy Keyword - Open\tinput.robot\t/^My Keyword - Open$/;\"\tk\nMy_Keyword_-_Closed\tinput.robot\t/^My Keyword - Closed$/;\"\tk\nMy_Keyword_-_Open\tinput.robot\t/^My Keyword - Open$/;\"\tk\n"
  },
  {
    "path": "Units/parser-robot.r/dashes-in-identifiers.d/input.robot",
    "content": "*** Keywords ***\n\nMy Keyword - Closed\n    Sleep  5s\n\nMy Keyword - Open\n    Sleep  5s\n"
  },
  {
    "path": "Units/parser-robot.r/keyword-started-from-varref.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-robot.r/keyword-started-from-varref.d/expected.tags",
    "content": "myvar\tinput.robot\t/^${myvar}    variable_value$/;\"\tv\nMy Regular Keyword\tinput.robot\t/^My Regular Keyword$/;\"\tk\nMy_Regular_Keyword\tinput.robot\t/^My Regular Keyword$/;\"\tk\n${embedded arg} Starting Single\tinput.robot\t/^${embedded arg} Starting Single$/;\"\tk\n${embedded_arg}_Starting_Single\tinput.robot\t/^${embedded arg} Starting Single$/;\"\tk\n${e} Starting Single Letter\tinput.robot\t/^${e} Starting Single Letter$/;\"\tk\n${e}_Starting_Single_Letter\tinput.robot\t/^${e} Starting Single Letter$/;\"\tk\n${embedded arg:value1|value2} Starting Single With Regex\tinput.robot\t/^${embedded arg:value1|value2} Starting Single With Regex$/;\"\tk\n${embedded_arg:value1|value2}_Starting_Single_With_Regex\tinput.robot\t/^${embedded arg:value1|value2} Starting Single With Regex$/;\"\tk\n${embedded arg1} Starting ${embedded arg2} Multiple\tinput.robot\t/^${embedded arg1} Starting ${embedded arg2} Multiple$/;\"\tk\n${embedded_arg1}_Starting_${embedded_arg2}_Multiple\tinput.robot\t/^${embedded arg1} Starting ${embedded arg2} Multiple$/;\"\tk\n${embedded arg1} Starting ${embedded arg2:value1|value2} Multiple With Regex\tinput.robot\t/^${embedded arg1} Starting ${embedded arg2:value1|value2} Multiple With Regex$/;\"\tk\n${embedded_arg1}_Starting_${embedded_arg2:value1|value2}_Multiple_With_Regex\tinput.robot\t/^${embedded arg1} Starting ${embedded arg2:value1|value2} Multiple With Regex$/;\"\tk\n${embedded arg1} Starting And ${embedded arg2} Ending ${embedded arg3}\tinput.robot\t/^${embedded arg1} Starting And ${embedded arg2} Ending ${embedded arg3}$/;\"\tk\n${embedded_arg1}_Starting_And_${embedded_arg2}_Ending_${embedded_arg3}\tinput.robot\t/^${embedded arg1} Starting And ${embedded arg2} Ending ${embedded arg3}$/;\"\tk\nMiddle ${embedded arg} Single Arguments\tinput.robot\t/^Middle ${embedded arg} Single Arguments$/;\"\tk\nMiddle_${embedded_arg}_Single_Arguments\tinput.robot\t/^Middle ${embedded arg} Single Arguments$/;\"\tk\nMiddle ${embedded arg1} Multiple ${embedded arg2} Arguments\tinput.robot\t/^Middle ${embedded arg1} Multiple ${embedded arg2} Arguments$/;\"\tk\nMiddle_${embedded_arg1}_Multiple_${embedded_arg2}_Arguments\tinput.robot\t/^Middle ${embedded arg1} Multiple ${embedded arg2} Arguments$/;\"\tk\nMiddle ${embedded arg:value1|value2} Single Arguments With Regex\tinput.robot\t/^Middle ${embedded arg:value1|value2} Single Arguments With Regex$/;\"\tk\nMiddle_${embedded_arg:value1|value2}_Single_Arguments_With_Regex\tinput.robot\t/^Middle ${embedded arg:value1|value2} Single Arguments With Regex$/;\"\tk\nMiddle ${e} Single Letter Arguments\tinput.robot\t/^Middle ${e} Single Letter Arguments$/;\"\tk\nMiddle_${e}_Single_Letter_Arguments\tinput.robot\t/^Middle ${e} Single Letter Arguments$/;\"\tk\nEnding Single ${embedded arg}\tinput.robot\t/^Ending Single ${embedded arg}$/;\"\tk\nEnding_Single_${embedded_arg}\tinput.robot\t/^Ending Single ${embedded arg}$/;\"\tk\nEnding Multiple ${embedded arg1} And ${embedded arg2}\tinput.robot\t/^Ending Multiple ${embedded arg1} And ${embedded arg2}$/;\"\tk\nEnding_Multiple_${embedded_arg1}_And_${embedded_arg2}\tinput.robot\t/^Ending Multiple ${embedded arg1} And ${embedded arg2}$/;\"\tk\nMy Keyword_with_underscore-and-dashes\tinput.robot\t/^My Keyword_with_underscore-and-dashes$/;\"\tk\nMy Keyword with underscore-and-dashes\tinput.robot\t/^My Keyword_with_underscore-and-dashes$/;\"\tk\nMy Keyword_With $ dollar sign\tinput.robot\t/^My Keyword_With $ dollar sign$/;\"\tk\nMy Keyword With $ dollar sign\tinput.robot\t/^My Keyword_With $ dollar sign$/;\"\tk\nMy Test With Template1\tinput.robot\t/^My Test With Template1        My Kw 1        My Kw 2$/;\"\tt\nMy_Test_With_Template1\tinput.robot\t/^My Test With Template1        My Kw 1        My Kw 2$/;\"\tt\n"
  },
  {
    "path": "Units/parser-robot.r/keyword-started-from-varref.d/input.robot",
    "content": "#\n# This test input is taken from #1572 opened by @mMontu.\n#\n*** Variables ***\n\n${myvar}    variable_value\n\n*** Keywords ***\n\nMy Regular Keyword\n    Sleep  5s\n\n${embedded arg} Starting Single\n    No Operation\n\n${e} Starting Single Letter\n    No Operation\n\n\n${embedded arg:value1|value2} Starting Single With Regex\n    No Operation\n\n${embedded arg1} Starting ${embedded arg2} Multiple\n    No Operation\n\n${embedded arg1} Starting ${embedded arg2:value1|value2} Multiple With Regex\n    No Operation\n\n${embedded arg1} Starting And ${embedded arg2} Ending ${embedded arg3}\n    No Operation\n\nMiddle ${embedded arg} Single Arguments\n    No Operation\n\nMiddle ${embedded arg1} Multiple ${embedded arg2} Arguments\n    No Operation\n\nMiddle ${embedded arg:value1|value2} Single Arguments With Regex\n    No Operation\n\nMiddle ${e} Single Letter Arguments\n    No Operation\n\nEnding Single ${embedded arg}\n    No Operation\n\nEnding Multiple ${embedded arg1} And ${embedded arg2}\n    No Operation\n\nMy Keyword_with_underscore-and-dashes\n    No Operation\n\nMy Keyword_With $ dollar sign\n    No Operation\n\n*** Test Cases ***\n\nMy Test With Template1        My Kw 1        My Kw 2\n"
  },
  {
    "path": "Units/parser-robot.r/simple-robot-no-extra.d/args.ctags",
    "content": "--extras-Robot=-{whitespaceSwapped}\n"
  },
  {
    "path": "Units/parser-robot.r/simple-robot-no-extra.d/expected.tags",
    "content": "Keyword ${with variable} name\tinput.robot\t/^Keyword ${with variable} name$/;\"\tk\nKeyword 1\tinput.robot\t/^Keyword 1$/;\"\tk\nKeyword 2\tinput.robot\t/^Keyword 2$/;\"\tk\nKeywordWithNoSpace\tinput.robot\t/^KeywordWithNoSpace$/;\"\tk\nKeyword_3\tinput.robot\t/^Keyword_3$/;\"\tk\nKeyword_4\tinput.robot\t/^Keyword_4    [Arguments]  @{arg1}$/;\"\tk\nTest case 1\tinput.robot\t/^Test case 1$/;\"\tt\nit's ok to be correct\tinput.robot\t/^it's ok to be correct$/;\"\tk\nlist 1\tinput.robot\t/^@{list 1}   a  b  c$/;\"\tv\nlist_2\tinput.robot\t/^@{list_2}  d  e  f$/;\"\tv\nvar 1\tinput.robot\t/^${var 1}  a$/;\"\tv\nvar_2\tinput.robot\t/^${var_2}   b$/;\"\tv\n"
  },
  {
    "path": "Units/parser-robot.r/simple-robot-no-extra.d/input.robot",
    "content": "* Settings ***\nLibrary           test.py\n\n*** Variables ***\n${var 1}  a\n${var_2}   b\n@{list 1}   a  b  c\n@{list_2}  d  e  f\n\n*** Test Cases ***\nTest case 1\n    Keyword 1  ${var 1}\n    Keyword_2  ${var_1}\n    Keyword 3  ${var 2}\n    Keyword 3  ${var_2}\n    Keyword 3  @{list 1}\n    Keyword 3  @{list_1}\n    Keyword 3  @{list 2}\n    Keyword 3  @{list_2}\n    Keyword 4  @{list_2}\n    Keyword with a variable name\n    it's ok to be correct\n\n*** Keywords ***\nKeyword 1\n    [Arguments]  ${arg}\n    python keyword 1\n\nKeyword 2\n    [Arguments]  ${arg}\n    python_keyword_2\n\nKeyword_3\n    [Arguments]  @{arg1}\n    Python_keyword_2\n\nKeyword_4    [Arguments]  @{arg1}\n    Python_keyword_2\n\nKeyword ${with variable} name\n    Python_keyword_2\n\nit's ok to be correct\n    Python_keyword_2\n\nKeywordWithNoSpace\n    [Arguments]  ${arg}\n    python keyword 1\n"
  },
  {
    "path": "Units/parser-robot.r/simple-robot.d/args.ctags",
    "content": "--fields=+E\n"
  },
  {
    "path": "Units/parser-robot.r/simple-robot.d/expected.tags",
    "content": "Keyword ${with variable} name\tinput.robot\t/^Keyword ${with variable} name$/;\"\tk\nKeyword 1\tinput.robot\t/^Keyword 1$/;\"\tk\nKeyword 2\tinput.robot\t/^Keyword 2$/;\"\tk\nKeyword 3\tinput.robot\t/^Keyword_3$/;\"\tk\textras:whitespaceSwapped\nKeyword 4\tinput.robot\t/^Keyword_4    [Arguments]  @{arg1}$/;\"\tk\textras:whitespaceSwapped\nKeywordWithNoSpace\tinput.robot\t/^KeywordWithNoSpace$/;\"\tk\nKeyword_${with_variable}_name\tinput.robot\t/^Keyword ${with variable} name$/;\"\tk\textras:whitespaceSwapped\nKeyword_1\tinput.robot\t/^Keyword 1$/;\"\tk\textras:whitespaceSwapped\nKeyword_2\tinput.robot\t/^Keyword 2$/;\"\tk\textras:whitespaceSwapped\nKeyword_3\tinput.robot\t/^Keyword_3$/;\"\tk\nKeyword_4\tinput.robot\t/^Keyword_4    [Arguments]  @{arg1}$/;\"\tk\nTest case 1\tinput.robot\t/^Test case 1$/;\"\tt\nTest_case_1\tinput.robot\t/^Test case 1$/;\"\tt\textras:whitespaceSwapped\nit's ok to be correct\tinput.robot\t/^it's ok to be correct$/;\"\tk\nit's_ok_to_be_correct\tinput.robot\t/^it's ok to be correct$/;\"\tk\textras:whitespaceSwapped\nlist 1\tinput.robot\t/^@{list 1}   a  b  c$/;\"\tv\nlist 2\tinput.robot\t/^@{list_2}  d  e  f$/;\"\tv\textras:whitespaceSwapped\nlist_1\tinput.robot\t/^@{list 1}   a  b  c$/;\"\tv\textras:whitespaceSwapped\nlist_2\tinput.robot\t/^@{list_2}  d  e  f$/;\"\tv\nvar 1\tinput.robot\t/^${var 1}  a$/;\"\tv\nvar 2\tinput.robot\t/^${var_2}   b$/;\"\tv\textras:whitespaceSwapped\nvar_1\tinput.robot\t/^${var 1}  a$/;\"\tv\textras:whitespaceSwapped\nvar_2\tinput.robot\t/^${var_2}   b$/;\"\tv\n"
  },
  {
    "path": "Units/parser-robot.r/simple-robot.d/input.robot",
    "content": "* Settings ***\nLibrary           test.py\n\n*** Variables ***\n${var 1}  a\n${var_2}   b\n@{list 1}   a  b  c\n@{list_2}  d  e  f\n\n*** Test Cases ***\nTest case 1\n    Keyword 1  ${var 1}\n    Keyword_2  ${var_1}\n    Keyword 3  ${var 2}\n    Keyword 3  ${var_2}\n    Keyword 3  @{list 1}\n    Keyword 3  @{list_1}\n    Keyword 3  @{list 2}\n    Keyword 3  @{list_2}\n    Keyword 4  @{list_2}\n    Keyword with a variable name\n    it's ok to be correct\n\n*** Keywords ***\nKeyword 1\n    [Arguments]  ${arg}\n    python keyword 1\n\nKeyword 2\n    [Arguments]  ${arg}\n    python_keyword_2\n\nKeyword_3\n    [Arguments]  @{arg1}\n    Python_keyword_2\n\nKeyword_4    [Arguments]  @{arg1}\n    Python_keyword_2\n\nKeyword ${with variable} name\n    Python_keyword_2\n\nit's ok to be correct\n    Python_keyword_2\n\nKeywordWithNoSpace\n    [Arguments]  ${arg}\n    python keyword 1\n"
  },
  {
    "path": "Units/parser-rpmMacros.r/lua.d/args.ctags",
    "content": "--sort=no\n--fields=+eS\n--map-RpmMacros=+.macros\n"
  },
  {
    "path": "Units/parser-rpmMacros.r/lua.d/expected.tags",
    "content": "add_sysuser\tinput.macros\t/^%add_sysuser(-) %{lua:$/;\"\tm\tsignature:(-)\tend:39\n"
  },
  {
    "path": "Units/parser-rpmMacros.r/lua.d/input.macros",
    "content": "#\n# Taken from rpm/macros.in\n#\n\n# Add a sysuser user/group to a package. Takes a sysusers.d(5) line as\n# arguments, eg `%add_sysuser g mygroup 515`.\n# -b option omits the \"Provides: \" to support formatting the entry outside\n# spec context.\n%add_sysuser(-) %{lua:\n    if arg[1] == '-b' then\n        prefix = ''\n        table.remove(arg, 1)\n    else\n        prefix = 'Provides: '\n    end\n    if #arg < 2 then\n        error('not enough arguments')\n    end\n    if arg[1] == 'g' then\n        type = 'group'\n    elseif arg[1] == 'u' then\n        type = 'user'\n    else\n        error('invalid sysuser type: '..arg[1])\n    end\n    name = arg[2]\n    line = table.concat(arg, ' ')\n    -- \\0-pad source string to avoid '=' in the output\n    llen = line:len()\n    ulen = math.ceil(4 * (llen / 3))\n    plen = 4 * math.ceil(llen / 3)\n    pad = string.rep('\\\\0', plen-ulen)\n    enc = rpm.b64encode(line..pad, 0);\n\n    print(string.format('%s%s(%s) = %s\\\\n', prefix, type, name, enc))\n    if type == 'user' then\n        print(string.format('%s%s(%s)\\\\n', prefix, 'group', name))\n    end\n}\n"
  },
  {
    "path": "Units/parser-rpmMacros.r/simple.d/args.ctags",
    "content": "--sort=no\n--fields=+eS\n--map-RpmMacros=+.macros\n"
  },
  {
    "path": "Units/parser-rpmMacros.r/simple.d/expected.tags",
    "content": "a\tinput.macros\t/^%a 1$/;\"\tm\nb\tinput.macros\t/^%b() %{nil}$/;\"\tm\tsignature:()\nc\tinput.macros\t/^%c a\\\\$/;\"\tm\tend:6\nd\tinput.macros\t/^%d 1$/;\"\tm\ne\tinput.macros\t/^%e 1$/;\"\tm\na0\tinput-0.macros\t/^%a0 1$/;\"\tm\nb0\tinput-0.macros\t/^%b0() %{nil}$/;\"\tm\tsignature:()\nc0\tinput-0.macros\t/^%c0 a\\\\$/;\"\tm\tend:5\nd0\tinput-0.macros\t/^%d0 1$/;\"\tm\ne0\tinput-0.macros\t/^%e0 1$/;\"\tm\na1\tinput-1.macros\t/^%a1 1$/;\"\tm\nb1\tinput-1.macros\t/^%b1() %{nil}$/;\"\tm\tsignature:()\nc1\tinput-1.macros\t/^%c1 a\\\\$/;\"\tm\tend:6\nd1\tinput-1.macros\t/^%d1 1$/;\"\tm\ne1\tinput-1.macros\t/^%e1 1$/;\"\tm\na2\tinput-2.macros\t/^%a2 1$/;\"\tm\nb2\tinput-2.macros\t/^%b2() %{nil}$/;\"\tm\tsignature:()\nc2\tinput-2.macros\t/^%c2 a\\\\$/;\"\tm\tend:6\nd2\tinput-2.macros\t/^%d2 1$/;\"\tm\ne2\tinput-2.macros\t/^%e2 1$/;\"\tm\n"
  },
  {
    "path": "Units/parser-rpmMacros.r/simple.d/input-0.macros",
    "content": "#%comment\n%a0 1\n%b0() %{nil}\n%c0 a\\\n\n%d0 1\n%e0 1\n"
  },
  {
    "path": "Units/parser-rpmMacros.r/simple.d/input-1.macros",
    "content": "#%comment\n%a1 1\n%b1() %{nil}\n%c1 a\\\n\\\n\n%d1 1\n%e1 1\n"
  },
  {
    "path": "Units/parser-rpmMacros.r/simple.d/input-2.macros",
    "content": "#%comment\n%a2 1\n%b2() %{nil}\n%c2 a\\\n\\\na\n%d2 1\n%e2 1\n"
  },
  {
    "path": "Units/parser-rpmMacros.r/simple.d/input.macros",
    "content": "#%comment\n%a 1\n%b() %{nil}\n%c a\\\n%B \\\n%C\n%d 1\n%e 1\n"
  },
  {
    "path": "Units/parser-rpmspec.r/empty-line-in-macro.d/args.ctags",
    "content": "--sort=no\n--fields=+en\n"
  },
  {
    "path": "Units/parser-rpmspec.r/empty-line-in-macro.d/expected.tags",
    "content": "m0\tinput.spec\t/^%define m0 \\\\$/;\"\tm\tline:1\tend:2\nm1\tinput.spec\t/^%define m1 1$/;\"\tm\tline:3\tend:3\n"
  },
  {
    "path": "Units/parser-rpmspec.r/empty-line-in-macro.d/input.spec",
    "content": "%define m0 \\\n\n%define m1 1\n"
  },
  {
    "path": "Units/parser-rpmspec.r/simple-rpmspec.d/args.ctags",
    "content": "--sort=no\n--extras=+rq\n--fields=+rSzKne\n"
  },
  {
    "path": "Units/parser-rpmspec.r/simple-rpmspec.d/expected.tags",
    "content": "Summary\tinput.spec\t/^Summary: Exuberant Ctags - a multi-language source code indexing tool$/;\"\tkind:tag\tline:1\troles:def\nName\tinput.spec\t/^Name: ctags$/;\"\tkind:tag\tline:2\troles:def\nctags\tinput.spec\t/^Name: ctags$/;\"\tkind:package\tline:2\troles:def\nVersion\tinput.spec\t/^Version: 99$/;\"\tkind:tag\tline:3\troles:def\nRelease\tinput.spec\t/^Release: 1$/;\"\tkind:tag\tline:4\troles:def\nLicense\tinput.spec\t/^License: GPLv2$/;\"\tkind:tag\tline:5\troles:def\nGroup\tinput.spec\t/^Group: Development\\/Tools$/;\"\tkind:tag\tline:6\troles:def\nSource\tinput.spec\t/^Source: http:\\/\\/prdownloads.sourceforge.net\\/ctags\\/ctags-%{version}.tar.gz$/;\"\tkind:tag\tline:7\troles:def\nURL\tinput.spec\t/^URL: http:\\/\\/ctags.sourceforge.net$/;\"\tkind:tag\tline:8\troles:def\nBuildroot\tinput.spec\t/^Buildroot: %{_tmppath}\\/%{name}-%{version}-root$/;\"\tkind:tag\tline:9\troles:def\nPatch0\tinput.spec\t/^Patch0: empty0.patch$/;\"\tkind:tag\tline:11\troles:def\nempty0.patch\tinput.spec\t/^Patch0: empty0.patch$/;\"\tkind:patch\tline:11\troles:decl\nPatch9999\tinput.spec\t/^Patch9999: dummy1.patch$/;\"\tkind:tag\tline:12\troles:def\ndummy1.patch\tinput.spec\t/^Patch9999: dummy1.patch$/;\"\tkind:patch\tline:12\troles:decl\n__scm_apply_git\tinput.spec\t/^%define __scm_apply_git(qp:m:) %{__git} am$/;\"\tkind:macro\tline:14\tsignature:(qp:m:)\troles:def\tend:14\nYES\tinput.spec\t/^%define YES yes$/;\"\tkind:macro\tline:16\troles:def\tend:16\n__scm_apply_git\tinput.spec\t/^%undef __scm_apply_git$/;\"\tkind:macro\tline:28\troles:undef\tend:28\nperf_make\tinput.spec\t/^%global perf_make make %{?_smp_mflags} -C tools\\/perf -s V=1 WERROR=0 NO_LIBUNWIND=1 HAVE_CPLUS_/;\"\tkind:global\tline:29\troles:def\tend:29\ninstall_post\tinput.spec\t/^%define install_post \\\\$/;\"\tkind:macro\tline:31\troles:def\tend:38\ndocs\tinput.spec\t/^%package docs$/;\"\tkind:package\tline:40\tpackage:ctags\troles:def\nctags-docs\tinput.spec\t/^%package docs$/;\"\tkind:package\tline:40\tpackage:ctags\troles:def\nuniversal-ctags-devel\tinput.spec\t/^%package -n universal-ctags-devel$/;\"\tkind:package\tline:44\tpackage:ctags\troles:def\ncond\tinput.spec\t/^%bcond cond1 0$/;\"\tkind:bcond\tline:48\troles:def\ncondw\tinput.spec\t/^%bcond_with condw$/;\"\tkind:bcond\tline:49\troles:def\ncondwo\tinput.spec\t/^%bcond_without condwo$/;\"\tkind:bcond\tline:50\troles:def\nlibxml\tinput.spec\t/^%configure --with-libxml=%{YES} --with-libyml=%{YES}\\\\$/;\"\tkind:optwith\tline:56\troles:cmdline\nlibyml\tinput.spec\t/^%configure --with-libxml=%{YES} --with-libyml=%{YES}\\\\$/;\"\tkind:optwith\tline:56\troles:cmdline\nfoo\tinput.spec\t/^\t   --without-foo --enable-bar \\\\$/;\"\tkind:optwith\tline:57\troles:cmdline\nbar\tinput.spec\t/^\t   --without-foo --enable-bar \\\\$/;\"\tkind:optenable\tline:57\troles:cmdline\nbaz\tinput.spec\t/^\t   --disable-baz\\\\$/;\"\tkind:optenable\tline:58\troles:cmdline\nbazz\tinput.spec\t/^\t   --with-bazz=0$/;\"\tkind:optwith\tline:59\troles:cmdline\n"
  },
  {
    "path": "Units/parser-rpmspec.r/simple-rpmspec.d/input.spec",
    "content": "Summary: Exuberant Ctags - a multi-language source code indexing tool\nName: ctags\nVersion: 99\nRelease: 1\nLicense: GPLv2\nGroup: Development/Tools\nSource: http://prdownloads.sourceforge.net/ctags/ctags-%{version}.tar.gz\nURL: http://ctags.sourceforge.net\nBuildroot: %{_tmppath}/%{name}-%{version}-root\n\nPatch0: empty0.patch\nPatch9999: dummy1.patch\n\n%define __scm_apply_git(qp:m:) %{__git} am\n\n%define YES yes\n%description\nExuberant Ctags generates an index (or tag) file of language objects\nfound in source files for many popular programming languages. This index\nmakes it easy for text editors and other tools to locate the indexed\nitems. Exuberant Ctags improves on traditional ctags because of its\nmultilanguage support, its ability for the user to define new languages\nsearched by regular expressions, and its ability to generate emacs-style\nTAGS files.\n\nInstall ctags if you are going to use your system for programming.\n\n%undef __scm_apply_git\n%global perf_make make %{?_smp_mflags} -C tools/perf -s V=1 WERROR=0 NO_LIBUNWIND=1 HAVE_CPLUS_DEMANGLE=1 NO_GTK2=1 NO_STRLCPY=1 prefix=%{_prefix} lib=%{_lib}\n\n%define install_post \\\n  if [ \"%{with_debug}\" -ne \"0\" ]; then \\\n    : \\\n  fi \\\n  if [ \"%{with_default}\" -ne \"0\" ]; then \\\n    : \\\n  fi \\\n%{nil}\n\n%package docs\n%description docs\nSomething must be written here.\n\n%package -n universal-ctags-devel\n%description universal-ctags-devel\nSomething must be written here.\n\n%bcond cond1 0\n%bcond_with condw\n%bcond_without condwo\n\n%prep\n%setup -q\n\n%build\n%configure --with-libxml=%{YES} --with-libyml=%{YES}\\\n\t   --without-foo --enable-bar \\\n\t   --disable-baz\\\n\t   --with-bazz=0\nmake\n\n%install\nrm -rf $RPM_BUILD_ROOT\n%makeinstall\n\n%clean\nrm -rf $RPM_BUILD_ROOT\n\n%files\n%defattr(-,root,root)\n%doc COPYING EXTENDING.html FAQ NEWS README ctags.html\n%{_bindir}/ctags\n%{_mandir}/man1/ctags*\n"
  },
  {
    "path": "Units/parser-rspec.r/broken-input.d/README",
    "content": "This csae is for observing the behavior of the parser when a broken\ninput file is given.\n"
  },
  {
    "path": "Units/parser-rspec.r/broken-input.d/args.ctags",
    "content": "--fields=+Klen\n--sort=no\n"
  },
  {
    "path": "Units/parser-rspec.r/broken-input.d/input.rb",
    "content": "RSpec.describe Order do\n  context \"with no items do\n    it \"behaves one way\" do\n      # ...\n    end\n  end\nend\n"
  },
  {
    "path": "Units/parser-rspec.r/simple-rspec.d/args.ctags",
    "content": "--fields=+Klen\n--sort=no\n"
  },
  {
    "path": "Units/parser-rspec.r/simple-rspec.d/expected.tags",
    "content": "Order\tinput.rb\t/^RSpec.describe Order do$/;\"\tdescribe\tline:6\tlanguage:RSpec\tend:18\nwith no items\tinput.rb\t/^  context \"with no items\" do$/;\"\tcontext\tline:7\tlanguage:RSpec\tdescribe:Order\tend:11\nbehaves one way\tinput.rb\t/^    it \"behaves one way\" do$/;\"\tit\tline:8\tlanguage:RSpec\tcontext:Order.with no items\tend:10\nwith one item\tinput.rb\t/^  context \"with one item\" do$/;\"\tcontext\tline:13\tlanguage:RSpec\tdescribe:Order\tend:17\nbehaves another way\tinput.rb\t/^    it \"behaves another way\" do$/;\"\tit\tline:14\tlanguage:RSpec\tcontext:Order.with one item\tend:16\nCalculator\tinput.rb\t/^RSpec.describe Calculator do$/;\"\tdescribe\tline:20\tlanguage:RSpec\tend:26\n#add\tinput.rb\t/^  describe '#add' do$/;\"\tdescribe\tline:21\tlanguage:RSpec\tdescribe:Calculator\tend:25\nreturns the sum of its arguments\tinput.rb\t/^    it 'returns the sum of its arguments' do$/;\"\tit\tline:22\tlanguage:RSpec\tdescribe:Calculator.#add\tend:24\nCore\tinput.rb\t/^module RSpec::Core$/;\"\tmodule\tline:29\tlanguage:Ruby\tmodule:RSpec\tend:48\nExampleGroup\tinput.rb\t/^  RSpec.describe ExampleGroup do$/;\"\tdescribe\tline:30\tlanguage:RSpec\tend:47\nwhen calling `#{method}`, an example group API, from within an example\tinput.rb\t/^      context \"when calling `#{method}`, an example group API, from within an example\" do$/;\"\tcontext\tline:32\tlanguage:RSpec\tdescribe:ExampleGroup\tend:42\ntells the user they are in the wrong scope for that API\tinput.rb\t/^        it \"tells the user they are in the wrong scope for that API\" do$/;\"\tit\tline:33\tlanguage:RSpec\tcontext:ExampleGroup.when calling `#{method}`, an example group API, from within an example\tend:41\nObject describing nested example_groups\tinput.rb\t/^    describe Object, \"describing nested example_groups\", :little_less_nested => 'yep' do$/;\"\tdescribe\tline:45\tlanguage:RSpec\tdescribe:ExampleGroup\tend:46\n"
  },
  {
    "path": "Units/parser-rspec.r/simple-rspec.d/input.rb",
    "content": "#\n# Randomly taken from https://github.com/rspec/rspec-core\n# https://github.com/rspec/rspec-core/blob/master/LICENSE.md\n#\n\nRSpec.describe Order do\n  context \"with no items\" do\n    it \"behaves one way\" do\n      # ...\n    end\n  end\n\n  context \"with one item\" do\n    it \"behaves another way\" do\n      # ...\n    end\n  end\nend\n\nRSpec.describe Calculator do\n  describe '#add' do\n    it 'returns the sum of its arguments' do\n      expect(Calculator.new.add(1, 2)).to eq(3)\n    end\n  end\nend\n\n# Taken from rspec-core/spec/rspec/core/example_group_spec.rb\nmodule RSpec::Core\n  RSpec.describe ExampleGroup do\n    %w[ describe context let before it it_behaves_like ].each do |method|\n      context \"when calling `#{method}`, an example group API, from within an example\" do\n        it \"tells the user they are in the wrong scope for that API\" do\n          ex = nil\n\n          RSpec.describe do\n            ex = example { __send__(method, \"foo\") }\n          end.run\n\n          expect(ex).to fail_with(ExampleGroup::WrongScopeError)\n        end\n      end\n    end\n\n    describe Object, \"describing nested example_groups\", :little_less_nested => 'yep' do\n    end\n  end\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/bug1742588.rb.d/expected.tags",
    "content": "A\tinput.rb\t/^class A$/;\"\tc\na\tinput.rb\t/^ def a()$/;\"\tf\tclass:A\nb\tinput.rb\t/^ def b()$/;\"\tf\tclass:A\n"
  },
  {
    "path": "Units/parser-ruby.r/bug1742588.rb.d/input.rb",
    "content": "class A\n def a()\n  super(\" do \")\n end\n def b()\n end\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-alias.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-alias.d/expected.tags",
    "content": "MyModule\tinput.rb\t/^module MyModule$/;\"\tm\nmy_method\tinput.rb\t/^  def my_method$/;\"\tf\tmodule:MyModule\nMyModule\tinput.rb\t/^module MyModule$/;\"\tm\nmy_alias\tinput.rb\t/^  alias my_alias my_method$/;\"\ta\tmodule:MyModule\n$new\tinput.rb\t/^  alias $new $old$/;\"\ta\nmy_alias_method0\tinput.rb\t/^  alias_method :my_alias_method0, :my_method$/;\"\ta\tmodule:MyModule\nmy_alias_method1\tinput.rb\t/^  alias_method \"my_alias_method1\", :my_method$/;\"\ta\tmodule:MyModule\nmy_alias_method2\tinput.rb\t/^  alias_method(:my_alias_method2, :my_method)$/;\"\ta\tmodule:MyModule\nmy_alias_method3\tinput.rb\t/^  alias_method(\"my_alias_method3\", :my_method)$/;\"\ta\tmodule:MyModule\nmy_alias_method4\tinput.rb\t/^  alias_method('my_alias_method4', :my_method)$/;\"\ta\tmodule:MyModule\nM\tinput-0.rb\t/^module M$/;\"\tm\nget\tinput-0.rb\t/^  def get(); end$/;\"\tf\tmodule:M\nset\tinput-0.rb\t/^  def set(); end$/;\"\tf\tmodule:M\n[]\tinput-0.rb\t/^  alias :\"[]\" :get$/;\"\ta\tmodule:M\n[]=\tinput-0.rb\t/^  alias :\"[]=\" :set$/;\"\ta\tmodule:M\nset\tinput-0.rb\t/^  alias :set :\"[]=\"$/;\"\ta\tmodule:M\nz\tinput-0.rb\t/^def z(); end$/;\"\tf\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-alias.d/input-0.rb",
    "content": "# Derived from https://github.com/tmm1/ripper-tags/blob/master/test/test_ripper_tags.rb\nmodule M\n  def get(); end\n  def set(); end\n\n  alias :\"[]\" :get\n  alias :\"[]=\" :set\n  alias :set :\"[]=\"\nend\n\ndef z(); end\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-alias.d/input.rb",
    "content": "# Taken from\n# * https://docs.ruby-lang.org/en/master/syntax/modules_and_classes_rdoc.html, and\n# * https://docs.ruby-lang.org/en/master/syntax/miscellaneous_rdoc.html\n\n$old = 0\nmodule MyModule\n  def my_method\n  end\nend\n\nmodule MyModule\n  alias my_alias my_method\n  alias $new $old\n  alias_method :my_alias_method0, :my_method\n  alias_method \"my_alias_method1\", :my_method\n  alias_method(:my_alias_method2, :my_method)\n  alias_method(\"my_alias_method3\", :my_method)\n  alias_method('my_alias_method4', :my_method)\nend\n\np $new # prints 0\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-anonymouse-class.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-anonymouse-class.d/expected.tags",
    "content": "__anonfe5966820100\tinput.rb\t/^Class.new do$/;\"\tc\nfoo\tinput.rb\t/^  def foo() end$/;\"\tS\tclass:__anonfe5966820100\nD\tinput.rb\t/^D = Class.new$/;\"\tc\nbar\tinput.rb\t/^def bar()$/;\"\tf\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-anonymouse-class.d/input.rb",
    "content": "# Taken from https://github.com/universal-ctags/ctags/issues/408 commented by @mislav.\nClass.new do\n  def foo() end\nend\n\nD = Class.new\ndef bar()\n  # This is not a part of D.\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-attr.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-attr.d/expected.tags",
    "content": "X\tinput.rb\t/^class X$/;\"\tc\nrr0\tinput.rb\t/^  attr_reader :rr0$/;\"\tA\tclass:X\nrr1\tinput.rb\t/^  attr_reader(:rr1)$/;\"\tA\tclass:X\nrr2\tinput.rb\t/^  attr_reader \"rr2\"$/;\"\tA\tclass:X\nrr3\tinput.rb\t/^  attr_reader :rr3, :rr4$/;\"\tA\tclass:X\nrr4\tinput.rb\t/^  attr_reader :rr3, :rr4$/;\"\tA\tclass:X\nrr5\tinput.rb\t/^  attr_reader \"rr5\", \"rr6\"$/;\"\tA\tclass:X\nrr6\tinput.rb\t/^  attr_reader \"rr5\", \"rr6\"$/;\"\tA\tclass:X\nrr7\tinput.rb\t/^  attr_reader :rr7, \"rr8\"$/;\"\tA\tclass:X\nrr8\tinput.rb\t/^  attr_reader :rr7, \"rr8\"$/;\"\tA\tclass:X\nrr9\tinput.rb\t/^  attr_reader \"rr9\", :rr10$/;\"\tA\tclass:X\nrr10\tinput.rb\t/^  attr_reader \"rr9\", :rr10$/;\"\tA\tclass:X\nrr11\tinput.rb\t/^  attr_reader(\"rr11\")$/;\"\tA\tclass:X\nrr12\tinput.rb\t/^  attr_reader 'rr12'$/;\"\tA\tclass:X\nrr13\tinput.rb\t/^  attr_reader 'rr13', 'rr14'$/;\"\tA\tclass:X\nrr14\tinput.rb\t/^  attr_reader 'rr13', 'rr14'$/;\"\tA\tclass:X\nrr15\tinput.rb\t/^  attr_reader :rr15, 'rr16'$/;\"\tA\tclass:X\nrr16\tinput.rb\t/^  attr_reader :rr15, 'rr16'$/;\"\tA\tclass:X\nrr17\tinput.rb\t/^  attr_reader 'rr17', :rr18$/;\"\tA\tclass:X\nrr18\tinput.rb\t/^  attr_reader 'rr17', :rr18$/;\"\tA\tclass:X\nrr19\tinput.rb\t/^  attr_reader('rr19')$/;\"\tA\tclass:X\nrr20\tinput.rb\t/^  attr_reader 'rr20', \"rr21\"$/;\"\tA\tclass:X\nrr21\tinput.rb\t/^  attr_reader 'rr20', \"rr21\"$/;\"\tA\tclass:X\nrr22\tinput.rb\t/^  attr_reader \"rr22\", 'rr23'$/;\"\tA\tclass:X\nrr23\tinput.rb\t/^  attr_reader \"rr22\", 'rr23'$/;\"\tA\tclass:X\nww0=\tinput.rb\t/^  attr_writer :ww0$/;\"\tA\tclass:X\nww1=\tinput.rb\t/^  attr_writer (:ww1)$/;\"\tA\tclass:X\nww2=\tinput.rb\t/^  attr_writer \"ww2\"$/;\"\tA\tclass:X\nww3=\tinput.rb\t/^  attr_writer :ww3, :ww4$/;\"\tA\tclass:X\nww4=\tinput.rb\t/^  attr_writer :ww3, :ww4$/;\"\tA\tclass:X\nww5=\tinput.rb\t/^  attr_writer \"ww5\", \"ww6\"$/;\"\tA\tclass:X\nww6=\tinput.rb\t/^  attr_writer \"ww5\", \"ww6\"$/;\"\tA\tclass:X\nww7=\tinput.rb\t/^  attr_writer :ww7, \"ww8\"$/;\"\tA\tclass:X\nww8=\tinput.rb\t/^  attr_writer :ww7, \"ww8\"$/;\"\tA\tclass:X\nww9=\tinput.rb\t/^  attr_writer \"ww9\", :ww10$/;\"\tA\tclass:X\nww10=\tinput.rb\t/^  attr_writer \"ww9\", :ww10$/;\"\tA\tclass:X\nww11=\tinput.rb\t/^  attr_writer (\"ww11\")$/;\"\tA\tclass:X\nrw0\tinput.rb\t/^  attr_accessor :rw0$/;\"\tA\tclass:X\nrw0=\tinput.rb\t/^  attr_accessor :rw0$/;\"\tA\tclass:X\nrw1\tinput.rb\t/^  attr_accessor (  :rw1)$/;\"\tA\tclass:X\nrw1=\tinput.rb\t/^  attr_accessor (  :rw1)$/;\"\tA\tclass:X\nrw2\tinput.rb\t/^  attr_accessor \"rw2\"$/;\"\tA\tclass:X\nrw2=\tinput.rb\t/^  attr_accessor \"rw2\"$/;\"\tA\tclass:X\nrw3\tinput.rb\t/^  attr_accessor :rw3, :rw4$/;\"\tA\tclass:X\nrw3=\tinput.rb\t/^  attr_accessor :rw3, :rw4$/;\"\tA\tclass:X\nrw4\tinput.rb\t/^  attr_accessor :rw3, :rw4$/;\"\tA\tclass:X\nrw4=\tinput.rb\t/^  attr_accessor :rw3, :rw4$/;\"\tA\tclass:X\nrw5\tinput.rb\t/^  attr_accessor \"rw5\", \"rw6\"$/;\"\tA\tclass:X\nrw5=\tinput.rb\t/^  attr_accessor \"rw5\", \"rw6\"$/;\"\tA\tclass:X\nrw6\tinput.rb\t/^  attr_accessor \"rw5\", \"rw6\"$/;\"\tA\tclass:X\nrw6=\tinput.rb\t/^  attr_accessor \"rw5\", \"rw6\"$/;\"\tA\tclass:X\nrw7\tinput.rb\t/^  attr_accessor :rw7, \"rw8\"$/;\"\tA\tclass:X\nrw7=\tinput.rb\t/^  attr_accessor :rw7, \"rw8\"$/;\"\tA\tclass:X\nrw8\tinput.rb\t/^  attr_accessor :rw7, \"rw8\"$/;\"\tA\tclass:X\nrw8=\tinput.rb\t/^  attr_accessor :rw7, \"rw8\"$/;\"\tA\tclass:X\nrw9\tinput.rb\t/^  attr_accessor \"rw9\", :rw10$/;\"\tA\tclass:X\nrw9=\tinput.rb\t/^  attr_accessor \"rw9\", :rw10$/;\"\tA\tclass:X\nrw10\tinput.rb\t/^  attr_accessor \"rw9\", :rw10$/;\"\tA\tclass:X\nrw10=\tinput.rb\t/^  attr_accessor \"rw9\", :rw10$/;\"\tA\tclass:X\nrw11\tinput.rb\t/^  attr_accessor (  \"rw11\")$/;\"\tA\tclass:X\nrw11=\tinput.rb\t/^  attr_accessor (  \"rw11\")$/;\"\tA\tclass:X\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-attr.d/input.rb",
    "content": "class X\n  @rr0 = 0\n  @rr1 = 0\n  @rr2 = 0\n  @rr3 = 0\n  @rr4 = 0\n  @rr5 = 0\n  @rr6 = 0\n  @rr7 = 0\n  @rr8 = 0\n  @rr9 = 0\n  @rr10 = 0\n  @rr11 = 0                    \n  attr_reader :rr0\n  attr_reader(:rr1)\n  attr_reader \"rr2\"\n  attr_reader :rr3, :rr4\n  attr_reader \"rr5\", \"rr6\"\n  attr_reader :rr7, \"rr8\"\n  attr_reader \"rr9\", :rr10\n  attr_reader(\"rr11\")\n\n  @rr12 = 0\n  @rr13 = 0\n  @rr14 = 0\n  @rr15 = 0\n  @rr16 = 0\n  @rr17 = 0\n  @rr18 = 0\n  @rr19 = 0\n  @rr20 = 0\n  @rr21 = 0\n  @rr22 = 0\n  @rr23 = 0\n  attr_reader 'rr12'\n  attr_reader 'rr13', 'rr14'\n  attr_reader :rr15, 'rr16'\n  attr_reader 'rr17', :rr18\n  attr_reader('rr19')\n  attr_reader 'rr20', \"rr21\"\n  attr_reader \"rr22\", 'rr23'\n\n  @ww0 = 0\n  @ww1 = 0\n  @ww2 = 0\n  @ww3 = 0\n  @ww4 = 0\n  @ww5 = 0\n  @ww6 = 0\n  @ww7 = 0    \n  @ww8 = 0\n  @ww9 = 0\n  @ww10 = 0\n  @ww11 = 0      \n  attr_writer :ww0\n  attr_writer (:ww1)\n  attr_writer \"ww2\"\n  attr_writer :ww3, :ww4\n  attr_writer \"ww5\", \"ww6\"\n  attr_writer :ww7, \"ww8\"\n  attr_writer \"ww9\", :ww10\n  attr_writer (\"ww11\")\n  @rw0 = 0\n  @rw1 = 0\n  @rw2 = 0\n  @rw3 = 0\n  @rw4 = 0\n  @rw5 = 0\n  @rw6 = 0\n  @rw7 = 0    \n  @rw8 = 0\n  @rw9 = 0\n  @rw10 = 0\n  @rw11 = 0        \n  attr_accessor :rw0\n  attr_accessor (  :rw1)\n  attr_accessor \"rw2\"\n  attr_accessor :rw3, :rw4\n  attr_accessor \"rw5\", \"rw6\"\n  attr_accessor :rw7, \"rw8\"\n  attr_accessor \"rw9\", :rw10\n  attr_accessor (  \"rw11\")\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-block-assign.d/expected.tags",
    "content": "Bar\tinput.rb\t/^c = class Bar$/;\"\tc\nFoo\tinput.rb\t/^m = module Foo$/;\"\tm\nQuux\tinput.rb\t/^m += module Quux$/;\"\tm\nZook\tinput.rb\t/^c ||= class Zook$/;\"\tc\nmethod_a\tinput.rb\t/^  x = def method_a$/;\"\tf\tclass:Bar\nmethod_b\tinput.rb\t/^  def method_b$/;\"\tf\tclass:Bar\nmethod_c\tinput.rb\t/^  def method_c$/;\"\tf\tclass:Bar\nmethod_d\tinput.rb\t/^  def method_d$/;\"\tf\tclass:Bar\nmethod_e\tinput.rb\t/^  def method_e$/;\"\tf\tclass:Bar\nmethod_f\tinput.rb\t/^  def method_f$/;\"\tf\tclass:Bar\nmethod_g\tinput.rb\t/^  def method_g$/;\"\tf\tclass:Bar\nmethod_h\tinput.rb\t/^  def method_h$/;\"\tf\tclass:Bar\nmethod_j\tinput.rb\t/^  def method_j$/;\"\tf\tclass:Bar\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-block-assign.d/input.rb",
    "content": "m = module Foo\nend\n\nm += module Quux\nend\n\nc = class Bar\n  x = def method_a\n    if 1\n    else\n    end\n  end\n\n  def method_b\n    x = while 1 do\n      break\n    end\n  end\n\n  def method_c\n    x = if 1\n    else\n    end\n  end\n\n  def method_d\n    x += if 1\n    else\n    end\n  end\n\n  def method_e\n    x ||= if 1\n    else\n    end\n  end\n\n  def method_f\n    @x = if 1\n    else\n    end\n  end\n  \n  def method_g\n    @@x = if 1\n    else\n    end\n  end\n  \n  def method_h\n    $x = if 1\n    else\n    end\n  end\n  \n  def method_j\n  end\nend\n\nc ||= class Zook\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-block-call.d/expected.tags",
    "content": "nothing\tinput.rb\t/^def nothing$/;\"\tf\nplop\tinput.rb\t/^def plop$/;\"\tf\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-block-call.d/input.rb",
    "content": "\ndef plop\n\t[ 1, 2, 3, 4 ].each do |x|\n\t\tx > 0\n\tend.all?\nend\n\ndef nothing\n\tputs \"nothing\"\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-class-method-in-lt-lt-self.d/expected.tags",
    "content": "C\tinput.rb\t/^class C$/;\"\tc\nfoo\tinput.rb\t/^    def foo() end$/;\"\tS\tclass:C\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-class-method-in-lt-lt-self.d/input.rb",
    "content": "# (Taken from #455 opened by @mislav).\nclass C\n  class << self\n    def foo() end\n  end\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-class-method-with-prefixing-self.d/args.ctags",
    "content": "--sort=no\n--extras=+{anonymous}\n--fields=+Ki\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-class-method-with-prefixing-self.d/expected.tags",
    "content": "Integration\tinput.rb\t/^class Integration < ApplicationRecord$/;\"\tclass\tinherits:ApplicationRecord\nUnknownType\tinput.rb\t/^  UnknownType = Class.new(StandardError)$/;\"\tclass\tclass:Integration\tinherits:StandardError\nfield\tinput.rb\t/^  def self.field(name, storage: field_storage, **attrs)$/;\"\tsingletonMethod\tclass:Integration\nf\tinput.rb\t/^  def UnknownType.f()$/;\"\tsingletonMethod\tmodule:Integration.UnknownType\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-class-method-with-prefixing-self.d/input.rb",
    "content": "# Derrived from gitlab/app/models/integration.rb\nclass Integration < ApplicationRecord\n  UnknownType = Class.new(StandardError)\n  self.inheritance_column = :type_new\n\n  def self.field(name, storage: field_storage, **attrs)\n    fields << ::Integrations::Field.new(name: name, integration_class: self, **attrs)\n\n    case storage\n    when :attribute\n      # noop\n    when :properties\n      prop_accessor(name)\n    when :data_fields\n      data_field(name)\n    else\n      raise ArgumentError, \"Unknown field storage: #{storage}\"\n    end\n\n    boolean_accessor(name) if attrs[:type] == 'checkbox' && storage != :attribute\n  end\n\n  def UnknownType.f()\n  end\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-curly-brackets.d/args.ctags",
    "content": "--sort=no\n--fields=+{end}{signature}\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-curly-brackets.d/expected.tags",
    "content": "__anona00f52fc0100\tinput.rb\t/^Class.new {$/;\"\tc\tend:5\nf\tinput.rb\t/^  def f(n)$/;\"\tS\tclass:__anona00f52fc0100\tsignature:(n)\tend:4\nx\tinput.rb\t/^def x$/;\"\tf\tsignature:()\tend:9\n__anone0f8ea590100\tinput-0.rb\t/^Class.new do$/;\"\tc\tend:3\nf0\tinput-0.rb\t/^  def f0(n) n end$/;\"\tS\tclass:__anone0f8ea590100\tsignature:(n)\tend:2\ny\tinput-0.rb\t/^def y$/;\"\tf\tsignature:()\tend:7\nC\tinput-1.rb\t/^class C$/;\"\tc\tend:5\nf1\tinput-1.rb\t/^    def f1(n) n end$/;\"\tS\tclass:C\tsignature:(n)\tend:3\nz\tinput-1.rb\t/^def z$/;\"\tf\tsignature:()\tend:9\n__anone0fa031b0100\tinput-2.rb\t/^Class.new {$/;\"\tc\tend:3\nf2\tinput-2.rb\t/^  def f2() end$/;\"\tS\tclass:__anone0fa031b0100\tsignature:()\tend:2\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-curly-brackets.d/input-0.rb",
    "content": "Class.new do\n  def f0(n) n end\nend\n\ndef y\n  y\nend\n\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-curly-brackets.d/input-1.rb",
    "content": "class C\n  class << self\n    def f1(n) n end\n  end\nend\n\ndef z\n  z\nend\n\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-curly-brackets.d/input-2.rb",
    "content": "Class.new {\n  def f2() end\n}\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-curly-brackets.d/input.rb",
    "content": "Class.new {\n  def f(n)\n    n\n  end\n}\n\ndef x\n  x\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-define-method.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-define-method.d/expected.tags",
    "content": "Foo\tinput.rb\t/^class Foo$/;\"\tc\tline:1\tend:21\nf0\tinput.rb\t/^  def f0() p :f0 end$/;\"\tf\tline:2\tclass:Foo\tend:2\nf1\tinput.rb\t/^  define_method(:f1, instance_method(:f0))$/;\"\tf\tline:3\tclass:Foo\tend:3\nf2\tinput.rb\t/^  define_method(:f2) {$/;\"\tf\tline:4\tclass:Foo\tend:6\nf3\tinput.rb\t/^  define_method(:f3) do$/;\"\tf\tline:7\tclass:Foo\tend:13\nf30\tinput.rb\t/^    define_method(:f30) do$/;\"\tf\tline:10\tmethod:Foo.f3\tend:12\nf4\tinput.rb\t/^  define_method :f4 do$/;\"\tf\tline:14\tclass:Foo\tend:16\nf5\tinput.rb\t/^  define_method 'f5' do$/;\"\tf\tline:18\tclass:Foo\tend:20\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-define-method.d/input.rb",
    "content": "class Foo\n  def f0() p :f0 end\n  define_method(:f1, instance_method(:f0))\n  define_method(:f2) {\n    puts \"f2\"\n  }\n  define_method(:f3) do\n    # Semantically, this doesn't make sense. However,\n    # Syntactically, this is acceptable.\n    define_method(:f30) do\n      puts \"f30\"\n    end\n  end\n  define_method :f4 do\n    puts \"f4\"\n  end\n\n  define_method 'f5' do\n    puts 'f5'\n  end\nend\n\nFoo.new.f3\n\n\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-doc.d/expected.tags",
    "content": "f0\tinput.rb\t/^def f0; end$/;\"\tf\nf1\tinput.rb\t/^def f1; end$/;\"\tf\nf2\tinput.rb\t/^def f2; end$/;\"\tf\nf3\tinput.rb\t/^def f3; end$/;\"\tf\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-doc.d/input.rb",
    "content": "def f0; end\n\n=begin\ndef bug1\nend\n=end\n\ndef f1; end\n\n=begin \ndef bug2\nend\n=end\n\ndef f2; end\n\n=begin\tdef doesntcount end\ndef bug3\nend\n=end def notparsed end\n\ndef f3; end\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-geany-sf-bug-302.d/expected.tags",
    "content": "UtilitiesController\tinput.rb\t/^class UtilitiesController$/;\"\tc\nnew\tinput.rb\t/^  def new$/;\"\tf\tclass:UtilitiesController\nset_utilities_class\tinput.rb\t/^  def set_utilities_class$/;\"\tf\tclass:UtilitiesController\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-geany-sf-bug-302.d/input.rb",
    "content": "# https://sourceforge.net/p/geany/bugs/302/\n\nclass UtilitiesController\n  def new\n    File.open(\"somefile\",\"r\") do |infile|\n      infile.readline\n    end\n    render :action => 'show'\n  end\n\n  def set_utilities_class\n    @utilities_class = \"current_menu\"\n  end\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-geany-sf-bug-542.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-geany-sf-bug-542.d/expected.tags",
    "content": "method_or_class\tinput.rb\t/^def method_or_class$/;\"\tf\tline:3\tend:8\nX\tinput.rb\t/^class X$/;\"\tc\tline:10\tend:11\nC\tinput.rb\t/^class C$/;\"\tc\tline:16\tend:88\nmethod1\tinput.rb\t/^  def method1$/;\"\tf\tline:18\tclass:C\tend:22\nmethod2\tinput.rb\t/^  def method2$/;\"\tf\tline:24\tclass:C\tend:29\nmethod3\tinput.rb\t/^  def method3$/;\"\tf\tline:31\tclass:C\tend:36\nmethod4\tinput.rb\t/^  def method4$/;\"\tf\tline:39\tclass:C\tend:44\nmethod5\tinput.rb\t/^  def method5$/;\"\tf\tline:46\tclass:C\tend:52\nmethod6\tinput.rb\t/^  def method6$/;\"\tf\tline:54\tclass:C\tend:60\nmethod7\tinput.rb\t/^  def method7$/;\"\tf\tline:63\tclass:C\tend:69\nmethod8\tinput.rb\t/^  def method8$/;\"\tf\tline:71\tclass:C\tend:78\nmethod9\tinput.rb\t/^  def method9$/;\"\tf\tline:80\tclass:C\tend:87\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-geany-sf-bug-542.d/input.rb",
    "content": "# https://sourceforge.net/p/geany/bugs/542/\n\ndef method_or_class\n  for x in 0..1 do\n    for y in 0..1 do\n    end\n  end\nend\n\nclass X\nend\n\n\n# more tests\n\nclass C\n  # do as separator\n  def method1\n    for x in 0..1 do\n      puts x\n    end\n  end\n\n  def method2\n    until 0 == 1 do\n      puts \"hello\"\n      break\n    end\n  end\n\n  def method3\n    while 1 == 1 do\n      puts \"hello\"\n      break\n    end\n  end\n\n  # semicolon as separator\n  def method4\n    for x in 1..2; [1,2,3].each do |y|\n        puts x*y\n      end\n    end\n  end\n\n  def method5\n    until 0 == 1; [1,2,3].each do |x|\n        puts x\n      end\n      break\n    end\n  end\n\n  def method6\n    while 1 == 1; [1,2,3].each do |x|\n        puts x\n      end\n      break\n    end\n  end\n\n  # newline as separator\n  def method7\n    for x in 1..2\n      [1,2,3].each do |y|\n        puts x*y\n      end\n    end\n  end\n\n  def method8\n    until 0 == 1\n      [1,2,3].each do |x|\n        puts x\n      end\n      break\n    end\n  end\n\n  def method9\n    while 1 == 1\n      [1,2,3].each do |x|\n        puts x\n      end\n      break\n    end\n  end\nend\n\n\n# check the code works\nc = C.new\nc.method1\nc.method2\nc.method3\nc.method4\nc.method5\nc.method6\nc.method7\nc.method8\nc.method9\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-inheritance.d/args.ctags",
    "content": "--sort=no\n--fields=+i\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-inheritance.d/expected.tags",
    "content": "A\tinput.rb\t/^class A$/;\"\tc\nB\tinput.rb\t/^class B < A$/;\"\tc\tinherits:A\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-inheritance.d/input.rb",
    "content": "class A\nend\n\nclass B < A\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-kind-option.d/args.ctags",
    "content": "--kinds-ruby=c\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-kind-option.d/expected.tags",
    "content": "Example\tinput.rb\t/^class Example$/;\"\tc\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-kind-option.d/input.rb",
    "content": "class Example\n  def method\n    puts \"in class_method\"\n  end\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-library.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-library.d/expected.tags",
    "content": "a\tinput.rb\t/^require \"a\"$/;\"\tL\troles:required\nb\tinput.rb\t/^require(\"b\")$/;\"\tL\troles:required\nc\tinput.rb\t/^require_relative \"c\"$/;\"\tL\troles:requiredRel\nd\tinput.rb\t/^require_relative(\"d\")$/;\"\tL\troles:requiredRel\ne.rb\tinput.rb\t/^load \"e.rb\"$/;\"\tL\troles:loaded\nf.rb\tinput.rb\t/^load(\"f.rb\")$/;\"\tL\troles:loaded\ni\tinput.rb\t/^require 'i'$/;\"\tL\troles:required\nj\tinput.rb\t/^require('j')$/;\"\tL\troles:required\nk\tinput.rb\t/^require_relative 'k'$/;\"\tL\troles:requiredRel\nl\tinput.rb\t/^require_relative('l')$/;\"\tL\troles:requiredRel\nm.rb\tinput.rb\t/^load 'm.rb'$/;\"\tL\troles:loaded\nn.rb\tinput.rb\t/^load('n.rb')$/;\"\tL\troles:loaded\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-library.d/input.rb",
    "content": "require \"a\"\nrequire(\"b\")\nrequire_relative \"c\"\nrequire_relative(\"d\")\nload \"e.rb\"\nload(\"f.rb\")\nautoload :C\nautoload :D, \"g\"\nautoload(:G)\nautoload(:H, \"h\")\n\nrequire 'i'\nrequire('j')\nrequire_relative 'k'\nrequire_relative('l')\nload 'm.rb'\nload('n.rb')\nautoload :I\nautoload :J, 'o'\nautoload(:K)\nautoload(:L, 'p')\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-methods-for-visiblity.d/expected.tags",
    "content": "Mod\tinput.rb\t/^module Mod$/;\"\tm\na\tinput.rb\t/^  public def a()  end$/;\"\tf\tmodule:Mod\nb\tinput.rb\t/^  private def b()  end$/;\"\tf\tmodule:Mod\nc\tinput.rb\t/^  protected def c()  end$/;\"\tf\tmodule:Mod\nd\tinput.rb\t/^  public_class_method def self.d()  end$/;\"\tS\tmodule:Mod\ne\tinput.rb\t/^  private_class_method def self.e()  end$/;\"\tS\tmodule:Mod\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-methods-for-visiblity.d/input.rb",
    "content": "# Skip public, protected, and private methods invocation\nmodule Mod\n  public def a()  end\n  private def b()  end\n  protected def c()  end\n  public_class_method def self.d()  end\n  private_class_method def self.e()  end\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-mixin-field.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-mixin-field.d/expected.tags",
    "content": "X\tinput.rb\t/^module X$/;\"\tm\nhi\tinput.rb\t/^  def hi$/;\"\tf\tmodule:X\nY\tinput.rb\t/^module Y$/;\"\tm\nhoi\tinput.rb\t/^  def hoi$/;\"\tf\tmodule:Y\nZ\tinput.rb\t/^module Z$/;\"\tm\nzoo\tinput.rb\t/^  def zoo$/;\"\tf\tmodule:Z\nA\tinput.rb\t/^class A$/;\"\tc\tmixin:include:X,include:Y\nhi\tinput.rb\t/^  def hi$/;\"\tf\tclass:A\nB\tinput.rb\t/^class B$/;\"\tc\tmixin:include:X\nprep\tinput.rb\t/^  def self.prep$/;\"\tS\tclass:B\nC\tinput.rb\t/^class C$/;\"\tc\tmixin:prepend:X,prepend:Y\nhi\tinput.rb\t/^  def hi$/;\"\tf\tclass:C\nD\tinput.rb\t/^class D$/;\"\tc\tmixin:prepend:X\nprep\tinput.rb\t/^  def self.prep$/;\"\tS\tclass:D\nE\tinput.rb\t/^class E$/;\"\tc\tmixin:extend:X,extend:Y,extend:Z\nhi\tinput.rb\t/^  def hi$/;\"\tf\tclass:E\nF\tinput.rb\t/^class F$/;\"\tc\tmixin:extend:X\nprep\tinput.rb\t/^  def self.prep$/;\"\tS\tclass:F\nG\tinput.rb\t/^class G$/;\"\tc\tmixin:include:X,prepend:Y,extend:Z\nprep\tinput.rb\t/^  def self.prep$/;\"\tS\tclass:G\nH\tinput.rb\t/^class H$/;\"\tc\tmixin:include:X,prepend:Y,extend:Z\nprep\tinput.rb\t/^  def self.prep$/;\"\tS\tclass:H\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-mixin-field.d/input.rb",
    "content": "# Taken from a comment in #2476 submitted by @AmaiKinono\n\nmodule X\n  def hi\n    p \"Calling 'hi' in X.\"\n  end\nend\n\nmodule Y\n  def hoi\n    p \"Calling 'hoi' in Y.\"\n  end\nend\n\nmodule Z\n  def zoo\n    p \"Calling 'zoo' in Z.\"\n  end\nend\n\nclass A\n  include X\n  def hi\n    p \"Calling 'hi' in A.\"\n  end\n  include Y\nend\n\nclass B\n  def self.prep\n    include X\n  end\nend\n\nclass C\n  prepend X\n  def hi\n    p \"Calling 'hi' in C.\"\n  end\n  prepend Y\nend\n\nclass D\n  def self.prep\n    prepend X\n  end\nend\n\nclass E\n  extend X\n  def hi\n    p \"Calling 'hi' in E.\"\n  end\n  extend Y\n  extend Z\nend\n\nclass F\n  def self.prep\n    extend X\n  end\nend\n\nclass G\n  include(X)\n  def self.prep\n    prepend (Y)\n  end\n  extend ( Z)\nend\n\nclass H\n  if true\n    unless false\n      include(X)\n    end\n  end\n  def self.prep\n    if true\n      unless false\n        prepend (Y)\n      end\n    end\n  end\n  extend ( Z)\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-modules-indirect.b/args.ctags",
    "content": "--sort=no\n--fields=+{inherits}\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-modules-indirect.b/expected.tags",
    "content": "B\tinput.rb\t/^module B$/;\"\tm\nD\tinput.rb\t/^  D =  Module.new() {|m|$/;\"\tm\tmodule:B\nfd\tinput.rb\t/^    def m.fd()$/;\"\tf\tmodule:B.D\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-modules-indirect.b/input.rb",
    "content": "module B\n  D =  Module.new() {\n    |m|\n    def m.fd0()\n      puts \"D.fd0\"\n    end\n  }\n  E =  Module.new() do\n    |m|\n    def m.fd1()\n      puts \"E.fd1\"\n    end\n  end\n\nend\n\nB::D.fd0\nB::E.fd1\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-modules.d/args.ctags",
    "content": "--sort=no\n--fields=+{inherits}\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-modules.d/expected.tags",
    "content": "A\tinput.rb\t/^module A$/;\"\tm\nFa\tinput.rb\t/^  def self.Fa()$/;\"\tS\tmodule:A\nB\tinput.rb\t/^module B$/;\"\tm\nfb\tinput.rb\t/^  def fb()$/;\"\tf\tmodule:B\nFb0\tinput.rb\t/^  def B.Fb0()$/;\"\tS\tmodule:B\nFb1\tinput.rb\t/^  def self.Fb1()$/;\"\tS\tmodule:B\nC\tinput.rb\t/^  C = Module.new() do$/;\"\tm\tmodule:B\nfc0\tinput.rb\t/^    def self.fc0()$/;\"\tS\tmodule:B.C\nfc1\tinput.rb\t/^    def fc1()$/;\"\tf\tmodule:B.C\nE\tinput.rb\t/^  E = Module.new()$/;\"\tm\tmodule:B\nfe\tinput.rb\t/^  def E.fe()$/;\"\tS\tmodule:B.E\ngb\tinput.rb\t/^  def gb()$/;\"\tf\tmodule:B\n__anond62b7f6a0102\tinput.rb\t/^  Module.new()$/;\"\tm\tmodule:B\nX\tinput.rb\t/^class X$/;\"\tc\tmixin:include:B\nY\tinput.rb\t/^class Y$/;\"\tc\tmixin:extend:A\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-modules.d/input.rb",
    "content": "module A\n  def self.Fa()\n    puts \"A.Fa\"\n  end\nend\nA.Fa\n\nmodule B\n  def fb()\n    puts \"B.fb\"\n  end\n\n  def B.Fb0()\n    puts \"B.Fb0\"\n  end\n\n  def self.Fb1()\n    puts \"B.Fb1\"\n  end\n\n  C = Module.new() do\n    def self.fc0()\n      puts 'C.fc0'\n    end\n    def fc1()\n    end\n  end\n\n  E = Module.new()\n\n  def E.fe()\n    puts \"E.fe\"\n  end\n\n  def gb()\n    puts \"B.gb\"\n  end\n\n  Module.new()\nend\n\nB.Fb0\nB.Fb1\nB::C.fc0\nB::E.fe\n\nclass X\n  include B\nend\n\nclass Y\n  extend A\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-namespaced-class.d/expected.tags",
    "content": "A\tinput.rb\t/^module A$/;\"\tm\nB\tinput.rb\t/^  module B$/;\"\tm\tmodule:A\nC\tinput.rb\t/^class A::B::C; end$/;\"\tc\tmodule:A.B\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-namespaced-class.d/input.rb",
    "content": "module A\n  module B\n  end\nend\n\nclass A::B::C; end\n\nputs A::B::C\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-scope-after-anonymous-class.d/expected.tags",
    "content": "C\tinput.rb\t/^class C$/;\"\tc\nD\tinput.rb\t/^class D$/;\"\tc\n__anon2ddc3f230100\tinput.rb\t/^  Class.new(C) do$/;\"\tc\tclass:D\nbar\tinput.rb\t/^  def bar(); end$/;\"\tf\tclass:C\nf0\tinput.rb\t/^    def f0()$/;\"\tS\tclass:D.__anon2ddc3f230100\nf1\tinput.rb\t/^  def f1()$/;\"\tf\tclass:D\nfoo\tinput.rb\t/^    def foo() end$/;\"\tS\tclass:C\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-scope-after-anonymous-class.d/input.rb",
    "content": "class C\n  class << self\n    def foo() end\n  end\n  \n  def bar(); end\nend\n\nputs C.foo\nputs C.new.bar\n\nclass D\n  Class.new(C) do\n    def f0()\n    end\n  end\n  def f1()\n  end\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-sending-define-method.b/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-sending-define-method.b/expected.tags",
    "content": "C\tinput.rb\t/^class C$/;\"\tc\tline:1\tend:2\nact\tinput.rb\t/^C.define_method :act do$/;\"\tf\tclass:C\tline:4\tend:6\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-sending-define-method.b/input.rb",
    "content": "class C\nend\n\nC.define_method :act do\n  puts \"hello\\n\"\nend\nc = C.new\n\nc.act\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-sf-bug-364.d/expected.tags",
    "content": "D\tinput.rb\t/^class D$/;\"\tc\n_a?\tinput.rb\t/^  def self._a?$/;\"\tS\tclass:D\n_b!\tinput.rb\t/^  def self._b!$/;\"\tS\tclass:D\n_c=\tinput.rb\t/^  def self._c=(a)$/;\"\tS\tclass:D\nx?\tinput.rb\t/^  def self.x?$/;\"\tS\tclass:D\ny!\tinput.rb\t/^  def self.y!$/;\"\tS\tclass:D\nz=\tinput.rb\t/^  def self.z=(a)$/;\"\tS\tclass:D\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-sf-bug-364.d/input.rb",
    "content": "class D\n  def self.x?\n  end\n  def self.y!\n  end\n  def self.z=(a)\n  end\n  def self._a?\n  end\n  def self._b!\n  end\n  def self._c=(a)\n  end\nend\nD._c=1\nD.z=1\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-signature-field-complicated.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-signature-field-complicated.d/expected.tags",
    "content": "X\tinput.rb\t/^class X$/;\"\tc\ncat\tinput.rb\t/^  def cat (n = ')',              # comment$/;\"\tf\tclass:X\tsignature:(n = ')', m = \"missing\")\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-signature-field-complicated.d/input.rb",
    "content": "class X\n  def cat (n = ')',              # comment\n           m = \"missing\")\n    return n + m\n  end\nend\n\np X.new.cat(\"a\",\"b\")\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-signature-field.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-signature-field.d/expected.tags",
    "content": "X\tinput.rb\t/^module X$/;\"\tm\nadd0\tinput.rb\t/^  def add0()$/;\"\tf\tmodule:X\tsignature:()\nadd00\tinput.rb\t/^  def add00$/;\"\tf\tmodule:X\tsignature:()\nadd1\tinput.rb\t/^  def add1(n)$/;\"\tf\tmodule:X\tsignature:(n)\nadd2\tinput.rb\t/^  def add2(n, m)$/;\"\tf\tmodule:X\tsignature:(n, m)\nadd3\tinput.rb\t/^  def add3(n = 0, m)$/;\"\tf\tmodule:X\tsignature:(n = 0, m)\nadd4\tinput.rb\t/^  def add4(n = 0, m = 0)$/;\"\tf\tmodule:X\tsignature:(n = 0, m = 0)\nadd5\tinput.rb\t/^  def add5(n    =     0    ,    m    =   0)$/;\"\tf\tmodule:X\tsignature:(n = 0, m = 0)\naddm\tinput.rb\t/^  def addm (n = 0,$/;\"\tf\tmodule:X\tsignature:(n = 0, m = 0)\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-signature-field.d/input.rb",
    "content": "module X\n  def add0()\n    return 0\n  end\n  def add00\n    return 0\n  end\n  def add1(n)\n    return n\n  end\n  def add2(n, m)\n    return n + m\n  end\n  def add3(n = 0, m)\n    return n + m\n  end\n  def add4(n = 0, m = 0)\n    return n + m\n  end\n  def add5(n    =     0    ,    m    =   0)\n    return n + m\n  end    \n  def addm (n = 0,\n            m = 0)\n    return n + m\n  end\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-skip-data.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-skip-data.d/expected.tags",
    "content": "a\tinput.rb\t/^def a()$/;\"\tf\n"
  },
  {
    "path": "Units/parser-ruby.r/ruby-skip-data.d/input.rb",
    "content": "def a()\nend\n__END__\ndef b()\nend\n"
  },
  {
    "path": "Units/parser-ruby.r/simple.rb.d/args.ctags",
    "content": "--fields=+{line}{end}\n\n"
  },
  {
    "path": "Units/parser-ruby.r/simple.rb.d/expected.tags",
    "content": "CONST1\tinput.rb\t/^    CONST1 = 1$/;\"\tC\tline:4\tmodule:ModuleExample\nClassExample\tinput.rb\t/^    class ClassExample$/;\"\tc\tline:5\tmodule:ModuleExample\tend:22\nConst2\tinput.rb\t/^        Const2 = \"a\"$/;\"\tC\tline:6\tclass:ModuleExample.ClassExample\nModuleExample\tinput.rb\t/^module ModuleExample$/;\"\tm\tline:3\tend:29\n`\tinput.rb\t/^        def `(command)$/;\"\tf\tline:19\tclass:ModuleExample.ClassExample\tend:21\nclass_method\tinput.rb\t/^        def class_method$/;\"\tf\tline:7\tclass:ModuleExample.ClassExample\tend:9\nclass_method_exclamation!\tinput.rb\t/^        def class_method_exclamation!$/;\"\tf\tline:13\tclass:ModuleExample.ClassExample\tend:15\nclass_method_question?\tinput.rb\t/^        def class_method_question?$/;\"\tf\tline:16\tclass:ModuleExample.ClassExample\tend:18\nmodule_method\tinput.rb\t/^    def module_method$/;\"\tf\tline:23\tmodule:ModuleExample\tend:25\nsingleton_class_method\tinput.rb\t/^        def ClassExample.singleton_class_method$/;\"\tS\tline:10\tclass:ModuleExample.ClassExample\tend:12\nsingleton_module_method\tinput.rb\t/^    def ModuleExample.singleton_module_method$/;\"\tS\tline:26\tmodule:ModuleExample\tend:28\n"
  },
  {
    "path": "Units/parser-ruby.r/simple.rb.d/input.rb",
    "content": "#!/usr/bin/ruby\n\nmodule ModuleExample\n    CONST1 = 1\n    class ClassExample\n        Const2 = \"a\"\n        def class_method\n            puts \"in class_method\"\n        end\n        def ClassExample.singleton_class_method\n            puts \"in singleton_class_method\"\n        end\n        def class_method_exclamation!\n            puts \"in class_method_exclamation!\"\n        end\n        def class_method_question?\n            puts \"in class_method_question?\"\n        end\n        def `(command)\n            return \"just testing a backquote override\"\n        end\n    end\n    def module_method\n        puts \"in module_method\"\n    end\n    def ModuleExample.singleton_module_method\n        puts \"in singleton_module_method\"\n    end\nend\n\nModuleExample::ClassExample.singleton_class_method\n"
  },
  {
    "path": "Units/parser-ruby.r/validator",
    "content": "ruby\n"
  },
  {
    "path": "Units/parser-rust.r/defs-in-macro-arguments.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-rust.r/defs-in-macro-arguments.d/expected.tags",
    "content": "Framed\tinput.rs\t/^    pub struct Framed<T, U> {$/;\"\ts\tmacro:pin_project\ninner\tinput.rs\t/^        inner: FramedImpl<T, U, RWFrames>$/;\"\tm\tstruct:Framed\tmacro:pin_project\n"
  },
  {
    "path": "Units/parser-rust.r/defs-in-macro-arguments.d/input.rs",
    "content": "// Taken from https://github.com/tokio-rs/tokio/blob/26de3187e759e06c25432413643ea57d8a79503c/tokio-util/src/codec/framed.rs#L38\n// Quoted from https://github.com/tokio-rs/tokio/blob/26de3187e759e06c25432413643ea57d8a79503c/LICENSE\n// MIT License\n//\n// Copyright (c) Tokio Contributors\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\nuse crate::codec::decoder::Decoder;\nuse crate::codec::encoder::Encoder;\nuse crate::codec::framed_impl::{FramedImpl, RWFrames, ReadFrame, WriteFrame};\n\nuse futures_core::Stream;\nuse tokio::io::{AsyncRead, AsyncWrite};\n\nuse bytes::BytesMut;\nuse futures_sink::Sink;\nuse pin_project_lite::pin_project;\nuse std::fmt;\nuse std::io;\nuse std::pin::Pin;\nuse std::task::{Context, Poll};\n\npin_project! {\n    /// A unified [`Stream`] and [`Sink`] interface to an underlying I/O object, using\n    /// the `Encoder` and `Decoder` traits to encode and decode frames.\n    ///\n    /// You can create a `Framed` instance by using the [`Decoder::framed`] adapter, or\n    /// by using the `new` function seen below.\n    ///\n    /// # Cancellation safety\n    ///\n    /// * [`futures_util::sink::SinkExt::send`]: if send is used as the event in a\n    /// `tokio::select!` statement and some other branch completes first, then it is\n    /// guaranteed that the message was not sent, but the message itself is lost.\n    /// * [`tokio_stream::StreamExt::next`]: This method is cancel safe. The returned\n    /// future only holds onto a reference to the underlying stream, so dropping it will\n    /// never lose a value.\n    ///\n    /// [`Stream`]: futures_core::Stream\n    /// [`Sink`]: futures_sink::Sink\n    /// [`AsyncRead`]: tokio::io::AsyncRead\n    /// [`Decoder::framed`]: crate::codec::Decoder::framed()\n    /// [`futures_util::sink::SinkExt::send`]: futures_util::sink::SinkExt::send\n    /// [`tokio_stream::StreamExt::next`]: https://docs.rs/tokio-stream/latest/tokio_stream/trait.StreamExt.html#method.next\n    pub struct Framed<T, U> {\n        #[pin]\n        inner: FramedImpl<T, U, RWFrames>\n    }\n}\n"
  },
  {
    "path": "Units/parser-rust.r/rust-const-fn.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-rust.r/rust-const-fn.d/expected.tags",
    "content": "build_error\tinput.rs\t/^pub const fn build_error(msg: &'static str) -> ! {$/;\"\tf\nsquare\tinput-0.rs\t/^const fn square(x: i32) -> i32 { x * x }$/;\"\tf\nVALUE\tinput-0.rs\t/^const VALUE: i32 = square(12);$/;\"\tC\n"
  },
  {
    "path": "Units/parser-rust.r/rust-const-fn.d/input-0.rs",
    "content": "// Taken from https://doc.rust-lang.org/reference/const_eval.html#const-functions\nconst fn square(x: i32) -> i32 { x * x }\n\nconst VALUE: i32 = square(12);\n"
  },
  {
    "path": "Units/parser-rust.r/rust-const-fn.d/input.rs",
    "content": "// SPDX-License-Identifier: GPL-2.0\n\n//! Build-time error.\n//!\n//! This crate provides a [const function][const-functions] `build_error`, which will panic in\n//! compile-time if executed in [const context][const-context], and will cause a build error\n//! if not executed at compile time and the optimizer does not optimise away the call.\n//!\n//! It is used by `build_assert!` in the kernel crate, allowing checking of\n//! conditions that could be checked statically, but could not be enforced in\n//! Rust yet (e.g. perform some checks in [const functions][const-functions], but those\n//! functions could still be called in the runtime).\n//!\n//! For details on constant evaluation in Rust, please see the [Reference][const-eval].\n//!\n//! [const-eval]: https://doc.rust-lang.org/reference/const_eval.html\n//! [const-functions]: https://doc.rust-lang.org/reference/const_eval.html#const-functions\n//! [const-context]: https://doc.rust-lang.org/reference/const_eval.html#const-context\n\n#![no_std]\n\n/// Panics if executed in [const context][const-context], or triggers a build error if not.\n///\n/// [const-context]: https://doc.rust-lang.org/reference/const_eval.html#const-context\n#[inline(never)]\n#[cold]\n#[export_name = \"rust_build_error\"]\n#[track_caller]\npub const fn build_error(msg: &'static str) -> ! {\n    panic!(\"{}\", msg);\n}\n"
  },
  {
    "path": "Units/parser-rust.r/rust-simple.d/args.ctags",
    "content": "--fields=afikmsS\n"
  },
  {
    "path": "Units/parser-rust.r/rust-simple.d/expected.tags",
    "content": "Circle\tinput.rs\t/^impl Circle {$/;\"\tc\nCircle\tinput.rs\t/^struct Circle {$/;\"\ts\narea\tinput.rs\t/^    fn area(&self) -> f64 {$/;\"\tP\timplementation:Circle\tsignature:(&self) -> f64\nmain\tinput.rs\t/^fn main() {$/;\"\tf\tsignature:()\nradius\tinput.rs\t/^    radius: f64,$/;\"\tm\tstruct:Circle\nx\tinput.rs\t/^    x: f64,$/;\"\tm\tstruct:Circle\ny\tinput.rs\t/^    y: f64,$/;\"\tm\tstruct:Circle\n"
  },
  {
    "path": "Units/parser-rust.r/rust-simple.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/parser-rust.r/rust-simple.d/input.rs",
    "content": "//\n// Taken from http://doc.rust-lang.org/guide.html\n//\nfn main() {\n\tprintln!(\"Hello, world!\");\n}\nstruct Circle {\n    x: f64,\n    y: f64,\n    radius: f64,\n}\n\nimpl Circle {\n    fn area(&self) -> f64 {\n        std::f64::consts::PI * (self.radius * self.radius)\n    }\n}\n"
  },
  {
    "path": "Units/parser-rust.r/rust-test_input.d/args.ctags",
    "content": "--fields=afikmsS\n"
  },
  {
    "path": "Units/parser-rust.r/rust-test_input.d/expected.tags",
    "content": "A\tinput.rs\t/^pub struct A$/;\"\ts\nAnimal\tinput.rs\t/^enum Animal {$/;\"\tg\nB\tinput.rs\t/^pub struct B$/;\"\ts\nBar\tinput.rs\t/^struct Bar(isize);$/;\"\ts\nBaz\tinput.rs\t/^struct Baz(isize);$/;\"\ts\nC\tinput.rs\t/^impl<T> D<T> for C<T> where T: Send$/;\"\tc\nC\tinput.rs\t/^pub struct C<T> where T: Send$/;\"\ts\nD\tinput.rs\t/^pub trait D<T> where T: Send$/;\"\ti\nDoZ\tinput.rs\t/^trait DoZ {$/;\"\ti\nFoo\tinput.rs\t/^impl DoZ for Foo {$/;\"\tc\nFoo\tinput.rs\t/^impl Foo {$/;\"\tc\nFoo\tinput.rs\t/^impl Testable for Foo {$/;\"\tc\nFoo\tinput.rs\t/^struct Foo{foo_field_1:isize}$/;\"\ts\nFoo2\tinput.rs\t/^struct Foo2 {$/;\"\ts\nN\tinput.rs\t/^const N: usize = 10;$/;\"\tC\nParametrizedTrait\tinput.rs\t/^trait ParametrizedTrait<T> {$/;\"\ti\nS1\tinput.rs\t/^struct S1 {$/;\"\ts\nSomeStruct\tinput.rs\t/^\tpub struct SomeStruct;$/;\"\ts\tmodule:test_input2\nSuperTraitTest\tinput.rs\t/^trait SuperTraitTest:Testable+DoZ {$/;\"\ti\nTestable\tinput.rs\t/^trait Testable $/;\"\ti\nTraitedStructTest\tinput.rs\t/^impl<T: Clone> ParametrizedTrait<T> for TraitedStructTest<T> {$/;\"\tc\nTraitedStructTest\tinput.rs\t/^struct TraitedStructTest<X> {$/;\"\ts\na\tinput.rs\t/^\ta: T$/;\"\tm\tstruct:C\na_anteater\tinput.rs\t/^\ta_anteater(isize),$/;\"\te\tenum:Animal\na_bear\tinput.rs\t/^\ta_bear(isize),$/;\"\te\tenum:Animal\na_cat\tinput.rs\t/^\ta_cat(isize),$/;\"\te\tenum:Animal\na_dog\tinput.rs\t/^\ta_dog(isize),$/;\"\te\tenum:Animal\narray_param\tinput.rs\t/^fn array_param(arr: [[u32; 3]; 4])$/;\"\tf\tsignature:(arr: [[u32; 3]; 4])\nbar\tinput.rs\t/^\tbar: isize$/;\"\tm\tstruct:A\nbar\tinput.rs\t/^\tbar: isize$/;\"\tm\tstruct:B\ndo_z\tinput.rs\t/^\tfn do_z(&self) {$/;\"\tP\timplementation:Foo\tsignature:(&self)\ndo_z\tinput.rs\t/^\tfn do_z(&self);$/;\"\tP\tinterface:DoZ\tsignature:(&self)\nfoo\tinput.rs\t/^\tfoo: fn() -> isize,$/;\"\tm\tstruct:A\nfoo\tinput.rs\t/^\tfoo: isize,$/;\"\tm\tstruct:B\nfoo_field_1\tinput.rs\t/^struct Foo{foo_field_1:isize}$/;\"\tm\tstruct:Foo\ngfunc\tinput.rs\t/^fn gfunc<X:Testable+DoZ>(x:&X) {$/;\"\tf\tsignature:<X:Testable+DoZ>(x:&X)\nignore\tinput.rs\t/^macro_rules! ignore {($($x:tt)*) => (())}$/;\"\tM\nignored_inside_macro0\tinput.rs\t/^\t\tfn ignored_inside_macro0() {}$/;\"\tf\tfunction:main\tsignature:()\tmacro:ignore\nignored_inside_macro1\tinput.rs\t/^\t\tfn ignored_inside_macro1() {}$/;\"\tf\tfunction:main\tsignature:()\tmacro:ignore\nignored_inside_macro2\tinput.rs\t/^\t\tfn ignored_inside_macro2() {}$/;\"\tf\tfunction:main\tsignature:()\tmacro:ignore\nlifetime_and_char\tinput.rs\t/^fn lifetime_and_char<'lifetime>(_: &'lifetime isize)$/;\"\tf\tsignature:<'lifetime>(_: &'lifetime isize)\nmain\tinput.rs\t/^fn main() {\t$/;\"\tf\tsignature:()\nmy_method\tinput.rs\t/^\tfn my_method(&self,_:isize){ println!(\"{}\", \"my_method of foo\");}$/;\"\tP\timplementation:Foo\tsignature:(&self,_:isize)\nnested\tinput.rs\t/^\tfn nested() {}$/;\"\tf\tfunction:main\tsignature:()\nnot_hidden_by_char\tinput.rs\t/^\tfn not_hidden_by_char() {}$/;\"\tf\tfunction:lifetime_and_char\tsignature:()\nonly_field\tinput.rs\t/^\tonly_field: [isize; size]$/;\"\tm\tstruct:S1\npreserve_string_delims\tinput.rs\t/^fn preserve_string_delims(_bar: extern r#\"C\"# fn()) {}$/;\"\tf\tsignature:(_bar: extern r#\"C\"# fn())\nsize\tinput.rs\t/^static size: usize = 1;$/;\"\tv\nsome2\tinput.rs\t/^fn some2(a:Animal) {$/;\"\tf\tsignature:(a:Animal)\ntest\tinput.rs\t/^\tfn test(&self) {$/;\"\tP\timplementation:Foo\tsignature:(&self)\ntest\tinput.rs\t/^\tfn test(&self) {$/;\"\tP\timplementation:TraitedStructTest\tsignature:(&self)\ntest\tinput.rs\t/^\tfn test(&self);$/;\"\tP\tinterface:ParametrizedTrait\tsignature:(&self)\ntest\tinput.rs\t/^{\tfn test(&self);$/;\"\tP\tinterface:Testable\tsignature:(&self)\ntest1\tinput.rs\t/^\tfn test1(&self) {$/;\"\tP\timplementation:Foo\tsignature:(&self)\ntest1\tinput.rs\t/^\tfn test1(&self);$/;\"\tP\tinterface:Testable\tsignature:(&self)\ntest2\tinput.rs\t/^\tfn test2(&self) {$/;\"\tP\timplementation:Foo\tsignature:(&self)\ntest2\tinput.rs\t/^\tfn test2(&self);$/;\"\tP\tinterface:Testable\tsignature:(&self)\ntest_input2\tinput.rs\t/^mod test_input2$/;\"\tn\ntest_macro\tinput.rs\t/^macro_rules! test_macro$/;\"\tM\nwhere_foo\tinput.rs\t/^pub fn where_foo<T>(a: T) where T: Send$/;\"\tf\tsignature:<T>(a: T) where T: Send\nx\tinput.rs\t/^\t\tx:isize,$/;\"\tm\tstruct:Foo2\nx\tinput.rs\t/^\tx:X$/;\"\tm\tstruct:TraitedStructTest\ny\tinput.rs\t/^\t\ty:isize$/;\"\tm\tstruct:Foo2\nyada\tinput.rs\t/^fn yada(a:isize, c:Foo, b:test_input2::SomeStruct) -> String {$/;\"\tf\tsignature:(a:isize, c:Foo, b:test_input2::SomeStruct) -> String\n"
  },
  {
    "path": "Units/parser-rust.r/rust-test_input.d/input.rs",
    "content": "#! fn ignored_in_comment() {}\n#![feature(globs)]\n#![feature(macro_rules)]\nuse std::*;\nmod test_input2\n{\n\tpub struct SomeStruct;\n}\n\nfn lifetime_and_char<'lifetime>(_: &'lifetime isize)\n{\n\tlet s = '\"';\n\tlet s = '}';\n\tlet s = '\\'';\n\tfn not_hidden_by_char() {}\n}\n\nfn preserve_string_delims(_bar: extern r#\"C\"# fn()) {}\n\npub struct A\n{\n\tfoo: fn() -> isize,\n\tbar: isize\n}\n\npub struct B\n{\n\t#[cfg(test)]\n\tfoo: isize,\n\tbar: isize\n}\n\npub struct C<T> where T: Send\n{\n\ta: T\n}\n\npub trait D<T> where T: Send\n{\n}\n\nimpl<T> D<T> for C<T> where T: Send\n{\n}\n\npub fn where_foo<T>(a: T) where T: Send\n{\n}\n\nfn array_param(arr: [[u32; 3]; 4])\n{\n}\n\n/*\n * fn ignored_in_comment() {}\n */\n\n// fn ignored_in_comment() {}\n\n/* /*\n * */\n fn ignored_in_nested_comment() {}\n */\n\nstatic size: usize = 1;\nconst N: usize = 10;\n\n#[cfg(test)]\nstruct S1 {\n\tonly_field: [isize; size]\n}\n\nmacro_rules! test_macro\n{\n\t() => {1}\n}\n\nmacro_rules! ignore {($($x:tt)*) => (())}\n\nfn yada(a:isize, c:Foo, b:test_input2::SomeStruct) -> String {\n\ta.to_string()\n}\n\nfn main() {\t\n\tuse test_input2::*;\n\tlet a=Foo{foo_field_1:2};\n\ta.my_method(1);\n\tlet c=Animal::a_cat(3);\n\tlet d=Foo{foo_field_1:a.foo_field_1+2}; a.test();\n\tprintln!(\"{}\", a.foo_field_1.to_string());\n\tignore!\n\t(\n\t\tfn ignored_inside_macro0() {}\n\t);\n\tignore!\n\t[\n\t\tfn ignored_inside_macro1() {}\n\t];\n\tignore!\n\t{\n\t\tfn ignored_inside_macro2() {}\n\t}\n\n\tlet _ = \"fn ignored_in_string() {}\n\t\";\n\n\tlet _ = r##\"fn ignored_in_raw_string() {}\"\"##;\n\n\tfn nested() {}\n}\n\nstruct Bar(isize);\n\nstruct Baz(isize);\n\nstruct Foo{foo_field_1:isize}\n\nstruct Foo2 {\n\t\tx:isize,\n\t\ty:isize\n}\n\nimpl Foo {\n\tfn my_method(&self,_:isize){ println!(\"{}\", \"my_method of foo\");}\n}\n\nenum Animal {\n\ta_anteater(isize),\n\ta_bear(isize),\n\ta_cat(isize),\n\ta_dog(isize),\n}\n\ntrait Testable \n{\tfn test(&self);\n\tfn test1(&self);\n\tfn test2(&self);\n}\n\ntrait DoZ {\n\tfn do_z(&self);\n}\n\nimpl Testable for Foo {\n\tfn test(&self) {\n\t\tprintln!(\"{}\", self.foo_field_1.to_string());\n\t}\n\n\tfn test1(&self) {\n\t\tprintln!(\"{}\", self.foo_field_1.to_string());\n\t}\n\n\tfn test2(&self) {\n\t\tprintln!(\"{}\", self.foo_field_1.to_string());\n\t}\n}\n\nimpl DoZ for Foo {\n\tfn do_z(&self) {\n\t\tprintln!(\"{}\", self.foo_field_1.to_string());\n\t}\n}\n\ntrait SuperTraitTest:Testable+DoZ {\n}\n\nfn gfunc<X:Testable+DoZ>(x:&X) {\n\tlet a1=Animal::a_anteater(1);\n\tlet a2=Animal::a_bear(1);\n\tlet a3=Animal::a_cat(1);\n\tlet a4=Animal::a_dog(1);\n\tx.test();\n\tx.do_z();\n}\n\nstruct TraitedStructTest<X> {\n\tx:X\n}\n\ntrait ParametrizedTrait<T> {\n\tfn test(&self);\n}\n\nimpl<T: Clone> ParametrizedTrait<T> for TraitedStructTest<T> {\n\tfn test(&self) {\n\t}\n}\n\nfn some2(a:Animal) {\n\tmatch a {\n\t\tAnimal::a_cat(x)=> println!(\"{}\", \"cat\"),\n\t\t_ => println!(\"{}\", \"not a cat\")\n\t}\n}\n"
  },
  {
    "path": "Units/parser-rust.r/rust-test_input2.d/args.ctags",
    "content": "--fields=afikmsS\n"
  },
  {
    "path": "Units/parser-rust.r/rust-test_input2.d/expected.tags",
    "content": "SomeLongStructName\tinput.rs\t/^impl SomeLongStructName {$/;\"\tc\nSomeLongStructName\tinput.rs\t/^pub struct SomeLongStructName {v:isize}$/;\"\ts\nSomeStruct\tinput.rs\t/^\tpub struct SomeStruct{$/;\"\ts\tmodule:fruit\nanother_function\tinput.rs\t/^\tpub fn another_function(a:isize,b:isize,c:isize)->isize {$/;\"\tf\tmodule:veg\tsignature:(a:isize,b:isize,c:isize)->isize\nbaaz\tinput.rs\t/^\tfn baaz() {$/;\"\tP\timplementation:SomeLongStructName\tsignature:()\nblue_value\tinput.rs\t/^\t\tpub blue_value: isize$/;\"\tm\tstruct:fruit::SomeStruct\nchalk\tinput.rs\t/^\tfn chalk() {$/;\"\tf\tmodule:mineral\tsignature:()\nfoo_bar_test_func\tinput.rs\t/^pub fn foo_bar_test_func(apples:fruit::SomeStruct,(oranges,lemon):(isize,isize))->isize{$/;\"\tf\tsignature:(apples:fruit::SomeStruct,(oranges,lemon):(isize,isize))->isize\nfooo\tinput.rs\t/^\tfn fooo() {$/;\"\tP\timplementation:SomeLongStructName\tsignature:()\nfree_func\tinput.rs\t/^fn free_func() {$/;\"\tf\tsignature:()\nfruit\tinput.rs\t/^pub mod fruit {$/;\"\tn\ngranite\tinput.rs\t/^\tfn granite() {$/;\"\tf\tmodule:mineral\tsignature:()\ngreen_value\tinput.rs\t/^\t\tpub green_value: isize,$/;\"\tm\tstruct:fruit::SomeStruct\nlimestone\tinput.rs\t/^\tfn limestone() {$/;\"\tf\tmodule:mineral\tsignature:()\nmain\tinput.rs\t/^fn main() {}$/;\"\tf\tsignature:()\nmineral\tinput.rs\t/^mod mineral {$/;\"\tn\nnot_hashbang\tinput.rs\t/^#![cfg(not(test))] fn not_hashbang() {}$/;\"\tf\tsignature:()\nred_value\tinput.rs\t/^\t\tpub red_value: isize,$/;\"\tm\tstruct:fruit::SomeStruct\nv\tinput.rs\t/^pub struct SomeLongStructName {v:isize}$/;\"\tm\tstruct:SomeLongStructName\nveg\tinput.rs\t/^mod veg{$/;\"\tn\n"
  },
  {
    "path": "Units/parser-rust.r/rust-test_input2.d/input.rs",
    "content": "#![cfg(not(test))] fn not_hashbang() {}\n\npub fn foo_bar_test_func(apples:fruit::SomeStruct,(oranges,lemon):(isize,isize))->isize{\n\tlet some_var_name=2*oranges;\n\tlet a=SomeLongStructName{v:0};\n\tprintln!(\"{}\", \"a\");\n\tveg::another_function(apples.red_value,oranges,lemon);\n\tsome_var_name-apples.red_value+lemon+a.v\n}\n\npub mod fruit {\n\tpub struct SomeStruct{\n\t\tpub red_value: isize,\n\t\tpub green_value: isize,\n\t\tpub blue_value: isize\n\t}\n}\n\nfn free_func() {\n}\n\nimpl SomeLongStructName {\n\tfn fooo() {\n\t}\n\tfn baaz() {\n\t}\n}\n\npub struct SomeLongStructName {v:isize}\n\nmod veg{\n\tpub fn another_function(a:isize,b:isize,c:isize)->isize {\n\t\ta+b+c\n\t}\n}\n\nmod mineral {\n\tfn granite() {\n\t}\n\tfn limestone() {\n\t}\n\tfn chalk() {\n\t}\n}\n\nfn main() {}\n"
  },
  {
    "path": "Units/parser-rust.r/rust-visibility-spec.d/args.crags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-rust.r/rust-visibility-spec.d/expected.tags",
    "content": "Test\tinput.rs\t/^struct Test {$/;\"\ts\nanother\tinput.rs\t/^    pub another: i32,$/;\"\tm\tstruct:Test\nfield\tinput.rs\t/^    field: i32,$/;\"\tm\tstruct:Test\nyet_another\tinput.rs\t/^    pub(crate) yet_another: i32,$/;\"\tm\tstruct:Test\n"
  },
  {
    "path": "Units/parser-rust.r/rust-visibility-spec.d/input.rs",
    "content": "// Taken from #2938 submitted by @versusvoid\nstruct Test {\n    field: i32,\n    pub another: i32,\n    pub(crate) yet_another: i32,\n}\n"
  },
  {
    "path": "Units/parser-rust.r/rust-vstringput-eof.d/README",
    "content": "This is a crash test.\n"
  },
  {
    "path": "Units/parser-rust.r/rust-vstringput-eof.d/input.rs",
    "content": "\"\n"
  },
  {
    "path": "Units/parser-scdoc.r/end-with-subsection.d/args.ctags",
    "content": "--sort=no\n--fields=+en\n"
  },
  {
    "path": "Units/parser-scdoc.r/end-with-subsection.d/expected.tags",
    "content": "foo\tinput.scd\t/^foo(1)$/;\"\tt\tline:1\tend:10\na\tinput.scd\t/^# a$/;\"\ts\tline:6\ttitle:foo\tend:7\nc\tinput.scd\t/^# c$/;\"\ts\tline:8\ttitle:foo\tend:10\nb\tinput.scd\t/^## b$/;\"\tS\tline:10\tsection:foo\"\"c\tend:10\n"
  },
  {
    "path": "Units/parser-scdoc.r/end-with-subsection.d/input.scd",
    "content": "foo(1)\n\n## This one should not be extracted\n because there is no section owns this.\n\n# a\n\n# c\n\n## b\n"
  },
  {
    "path": "Units/parser-scdoc.r/simple-scdoc.d/README",
    "content": "input.md is taken from https://git.sr.ht/~sircmpwn/scdoc/tree/master/item/scdoc.5.scd .\n"
  },
  {
    "path": "Units/parser-scdoc.r/simple-scdoc.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-scdoc.r/simple-scdoc.d/expected.tags",
    "content": "SCDOC\tinput.scd\t/^SCDOC(5)$/;\"\tt\tline:1\tend:213\nNAME\tinput.scd\t/^# NAME$/;\"\ts\tline:3\ttitle:SCDOC\tend:6\nSYNTAX\tinput.scd\t/^# SYNTAX$/;\"\ts\tline:7\ttitle:SCDOC\tend:200\nPreamble\tinput.scd\t/^## Preamble$/;\"\tS\tline:11\tsection:SCDOC\"\"SYNTAX\tend:23\nSection headers\tinput.scd\t/^## Section headers$/;\"\tS\tline:24\tsection:SCDOC\"\"SYNTAX\tend:33\nParagraphs\tinput.scd\t/^## Paragraphs$/;\"\tS\tline:34\tsection:SCDOC\"\"SYNTAX\tend:37\nLine breaks\tinput.scd\t/^## Line breaks$/;\"\tS\tline:38\tsection:SCDOC\"\"SYNTAX\tend:44\nFormatting\tinput.scd\t/^## Formatting$/;\"\tS\tline:45\tsection:SCDOC\"\"SYNTAX\tend:49\nIndentation\tinput.scd\t/^## Indentation$/;\"\tS\tline:50\tsection:SCDOC\"\"SYNTAX\tend:61\nLists\tinput.scd\t/^## Lists$/;\"\tS\tline:62\tsection:SCDOC\"\"SYNTAX\tend:98\nNumbered lists\tinput.scd\t/^## Numbered lists$/;\"\tS\tline:99\tsection:SCDOC\"\"SYNTAX\tend:115\nTables\tinput.scd\t/^## Tables$/;\"\tS\tline:116\tsection:SCDOC\"\"SYNTAX\tend:173\nLiteral text\tinput.scd\t/^## Literal text$/;\"\tS\tline:174\tsection:SCDOC\"\"SYNTAX\tend:192\nComments\tinput.scd\t/^## Comments$/;\"\tS\tline:193\tsection:SCDOC\"\"SYNTAX\tend:200\nCONVENTIONS\tinput.scd\t/^# CONVENTIONS$/;\"\ts\tline:201\ttitle:SCDOC\tend:204\nSEE ALSO\tinput.scd\t/^# SEE ALSO$/;\"\ts\tline:205\ttitle:SCDOC\tend:208\nAUTHORS\tinput.scd\t/^# AUTHORS$/;\"\ts\tline:209\ttitle:SCDOC\tend:213\n"
  },
  {
    "path": "Units/parser-scdoc.r/simple-scdoc.d/input.scd",
    "content": "SCDOC(5)\n\n# NAME\n\nscdoc - document format for writing manual pages\n\n# SYNTAX\n\nInput files must use the UTF-8 encoding.\n\n## Preamble\n\nEach scdoc file must begin with the following preamble:\n\n\t_NAME_(_section_) [\"left\\_footer\" [\"center\\_header\"]]\n\n_NAME_ is the name of the man page you are writing, and _section_ is the section\nyou're writing for (see _man_(1) for information on manual sections).\n\n_left\\_footer_ and _center\\_header_ are optional arguments which set the text\npositioned at those locations in the generated man page, and *must* be\nsurrounded with double quotes.\n\n## Section headers\n\nEach section of your man page should begin with something similar to the\nfollowing:\n\n\t# HEADER NAME\n\nSubsection headers are also understood - use two hashes. Each header must have\nan empty line on either side.\n\n## Paragraphs\n\nBegin a new paragraph with an empty line.\n\n## Line breaks\n\nInsert a line break by ending a line with \\+\\+.\n\nThe result looks++\nlike this.\n\n## Formatting\n\nText can be made *bold* or _underlined_ with asterisks and underscores: \\*bold\\*\nor \\_underlined\\_. Underscores in the_middle_of_words will be disregarded.\n\n## Indentation\n\nYou may indent lines with tab characters (*\\\\t*) to indent them by 4 spaces in\nthe output. Indented lines may not contain headers.\n\n\tThe result looks something like this.\n\n\tYou may use multiple lines and most _formatting_.\n\nDeindent to return to normal, or indent again to increase your indentation\ndepth.\n\n## Lists\n\nYou may start bulleted lists with dashes (-), like so:\n\n```\n- Item 1\n- Item 2\n\t- Subitem 1\n\t- Subitem 2\n- Item 3\n```\n\nThe result looks like this:\n\n- Item 1\n- Item 2\n\t- Subitem 1\n\t- Subitem 2\n- Item 3\n\nYou may also extend long entries onto another line by giving it the same indent\nlevel, plus two spaces. They will be rendered as a single list entry.\n\n```\n- Item 1 is pretty long so let's\n  break it up onto two lines\n- Item 2 is shorter\n\t- But its children can go on\n\t  for a while\n```\n\n- Item 1 is pretty long so let's\n  break it up onto two lines\n- Item 2 is shorter\n\t- But its children can go on\n\t  for a while\n\n## Numbered lists\n\nNumbered lists are similar to normal lists, but begin with periods (.) instead\nof dashes (-), like so:\n\n```\n. Item 1\n. Item 2\n. Item 3,\n  with multiple lines\n```\n\n. Item 1\n. Item 2\n. Item 3,\n  with multiple lines\n\n## Tables\n\nTo begin a table, add an empty line followed by any number of rows.\n\nEach line of a table should start with | or : to start a new row or column\nrespectively (or space to continue the previous cell on multiple lines),\nfollowed by [ or - or ] to align the contents to the left, center, or right,\nfollowed by a space and the contents of that cell. You may use a space instead\nof an alignment specifier to inherit the alignment of the same column in the\nprevious row. Each row must have the same number of columns; empty columns are\npermitted.\n\nThe first character of the first row is not limited to | and has special\nmeaning. [ will produce a table with borders around each cell. | will produce a\ntable with no borders. ] will produce a table with one border around the whole\ntable.\n\nTo conclude your table, add an empty line after the last row.\n\n```\n[[ *Foo*\n:- _Bar_\n:-\n|  *Row 1*\n:  Hello\n:] world!\n|  *Row 2*\n:  こんにちは\n:  世界\n   !\n```\n\n[[ *Foo*\n:- _Bar_\n:-\n|  *Row 1*\n:  Hello\n:] world!\n|  *Row 2*\n:  こんにちは\n:  世界\n   !\n\nYou may also cause columns to expand to fill the available space with < (left\nalign), = (center align), and > (right align), like so:\n\n```\n[[ *Normal column*\n:< Expanded column\n|  *Foo*\n:  Bar\n```\n\n[[ *Normal column*\n:< Expanded column\n|  *Foo*\n:  Bar\n\n## Literal text\n\nYou may turn off scdoc formatting and output literal text with escape codes and\nliteral blocks. Inserting a \\\\ into your source will cause the subsequent symbol\nto be treated as a literal and copied directly to the output. You may also make\nblocks of literal syntax like so:\n\n```\n\\```\n_This formatting_ will *not* be interpreted by scdoc.\n\\```\n```\n\nThese blocks will be indented one level. Note that literal text is shown\nliterally in the man viewer - that is, it's not a means for inserting your own\nroff macros into the output. Note that \\\\ is still interpreted within literal\nblocks, which for example can be useful to output \\``` inside of a literal\nblock.\n\n## Comments\n\nLines beginning with ; and a space are ignored.\n\n```\n; This is a comment\n```\n\n# CONVENTIONS\n\nBy convention, all scdoc documents should be hard wrapped at 80 columns.\n\n# SEE ALSO\n\n_scdoc_(1)\n\n# AUTHORS\n\nMaintained by Drew DeVault <sir@cmpwn.com>. Up-to-date sources can be found at\nhttps://git.sr.ht/~sircmpwn/scdoc and bugs/patches can be submitted by email to\n~sircmpwn/public-inbox@lists.sr.ht.\n"
  },
  {
    "path": "Units/parser-scheme.r/scheme-simple-define.d/expected.tags",
    "content": "a0\tinput.scm\t/^(define a0 1)$/;\"\tf\na1\tinput.scm\t/^(define a1 \"a\")$/;\"\tf\na2\tinput.scm\t/^(define a2 '(a))$/;\"\tf\na3\tinput.scm\t/^(define a3 '(a b))$/;\"\tf\na4\tinput.scm\t/^(define a4 '(a . b))$/;\"\tf\na5\tinput.scm\t/^(define a5 '(a b c))$/;\"\tf\na6\tinput.scm\t/^(define a6 '(a b . c))$/;\"\tf\na7\tinput.scm\t/^(define a7 '(a$/;\"\tf\na8\tinput.scm\t/^(define a8$/;\"\tf\na9\tinput.scm\t/^  a9 '(a b . c))$/;\"\tf\naa\tinput.scm\t/^  aa$/;\"\tf\nb0\tinput.scm\t/^(define (b0) 1)$/;\"\tf\nb1\tinput.scm\t/^(define (b1 a) 1)$/;\"\tf\nb2\tinput.scm\t/^(define (b2 a b) 1)$/;\"\tf\nb3\tinput.scm\t/^(define (b3 a . b) 1)$/;\"\tf\nb4\tinput.scm\t/^(define (b4 a$/;\"\tf\nb5\tinput.scm\t/^(define (b5$/;\"\tf\nb6\tinput.scm\t/^(define (b6$/;\"\tf\nb7\tinput.scm\t/^(define (b7$/;\"\tf\nb8\tinput.scm\t/^\t b8$/;\"\tf\nb9\tinput.scm\t/^   b9$/;\"\tf\nba\tinput.scm\t/^  (ba$/;\"\tf\nc0\tinput.scm\t/^(define ((c0)) 1)$/;\"\tf\nc1\tinput.scm\t/^(define ((c1) a) 1)$/;\"\tf\nc2\tinput.scm\t/^(define ((c2) a b) 1)$/;\"\tf\nc3\tinput.scm\t/^(define ((c3) a . b) 1)$/;\"\tf\nc4\tinput.scm\t/^(define ((c4) a$/;\"\tf\nc5\tinput.scm\t/^(define ((c5)$/;\"\tf\nc6\tinput.scm\t/^(define ((c6)$/;\"\tf\nc7\tinput.scm\t/^(define ((c7)$/;\"\tf\nc8\tinput.scm\t/^\t  c8)$/;\"\tf\nc9\tinput.scm\t/^\t  c9)$/;\"\tf\nca\tinput.scm\t/^    ca)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-scheme.r/scheme-simple-define.d/input.scm",
    "content": "(define a0 1)\n(define a1 \"a\")\n(define a2 '(a))\n(define a3 '(a b))\n(define a4 '(a . b))\n(define a5 '(a b c))\n(define a6 '(a b . c))\n(define a7 '(a\n\t     b . c))\n(define a8\n  '(a b . c))\n\n(define\n  a9 '(a b . c))\n\n(define\n  aa\n  '(a b . c))\n\n(define (b0) 1)\n(define (b1 a) 1)\n(define (b2 a b) 1)\n(define (b3 a . b) 1)\n(define (b4 a\n\t    b) 1)\n(define (b5\n\t a b) 1)\n(define (b6\n\t a . b) 1)\n(define (b7\n\t a . b)\n  1)\n\n(define (\n\t b8\n\t a . b)\n  1)\n\n(define\n  (\n   b9\n   a . b)\n  1)\n\n(define\n  (ba\n   a . b)\n  1)\n\n(define ((c0)) 1)\n(define ((c1) a) 1)\n(define ((c2) a b) 1)\n(define ((c3) a . b) 1)\n(define ((c4) a\n\t b) 1)\n(define ((c5)\n\t a b) 1)\n(define ((c6)\n\t a . b) 1)\n(define ((c7)\n\t a . b)\n  1)\n\n(define ((\n\t  c8)\n\t a . b)\n  1)\n\n(define (\n\t (\n\t  c9)\n\t a . b)\n  1)\n\n(define\n  (\n   (\n    ca)\n   a . b)\n  1)\n\n;; incomplete input\n(define \n"
  },
  {
    "path": "Units/parser-scheme.r/scheme-simple-setbang.d/expected.tags",
    "content": "a0\tinput.scm\t/^(set! a0 1)$/;\"\ts\na1\tinput.scm\t/^(set! a1 #f)$/;\"\ts\na2\tinput.scm\t/^(set! a2 \"a\")$/;\"\ts\na3\tinput.scm\t/^(set! a3 '(1))$/;\"\ts\na4\tinput.scm\t/^(set! a4 '(1 2))$/;\"\ts\na5\tinput.scm\t/^(set! a5 '(1 2 . 3)$/;\"\ts\na5\tinput.scm\t/^(set! a5 '(1 2 . 3))$/;\"\ts\na6\tinput.scm\t/^(set! a6 '(1 2 . 3$/;\"\ts\na7\tinput.scm\t/^(set! a7 '(1 2 .$/;\"\ts\na7\tinput.scm\t/^(set! a7 '(1 2$/;\"\ts\na8\tinput.scm\t/^(set! a8 '(1$/;\"\ts\na9\tinput.scm\t/^(set! a9 '($/;\"\ts\naa\tinput.scm\t/^(set! aa '$/;\"\ts\nab\tinput.scm\t/^(set! ab $/;\"\ts\nac\tinput.scm\t/^   ac '(1 2 . 3))$/;\"\ts\nad\tinput.scm\t/^   ad$/;\"\ts\n"
  },
  {
    "path": "Units/parser-scheme.r/scheme-simple-setbang.d/input.scm",
    "content": "(set! a0 1)\n(set! a1 #f)\n(set! a2 \"a\")\n(set! a3 '(1))\n(set! a4 '(1 2))\n(set! a5 '(1 2 . 3))\n(set! a5 '(1 2 . 3)\n   )\n(set! a6 '(1 2 . 3\n\t   ))\n(set! a7 '(1 2 .\n\t   3))\n(set! a7 '(1 2\n\t   . 3))\n(set! a8 '(1\n\t   2 . 3))\n(set! a9 '(\n\t   1 2 . 3))\n(set! aa '\n   (1 2 . 3))\n(set! ab \n   '(1 2 . 3))\n(set!\n   ac '(1 2 . 3))\n(set!\n   ad\n   '(1 2 . 3))\n;; incomplete input\n(set! "
  },
  {
    "path": "Units/parser-scheme.r/scheme-srfi-30-comment.b/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-scheme.r/scheme-srfi-30-comment.b/input.scm",
    "content": "#|\n(define a 1)\n(set! b #f)\n|#"
  },
  {
    "path": "Units/parser-scheme.r/scheme-string.b/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-scheme.r/scheme-string.b/input.scm",
    "content": "\"\n(define a 1)\n(set! b #f)\n\"\n"
  },
  {
    "path": "Units/parser-scss.r/function.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-scss.r/function.d/expected.tags",
    "content": "remove-where\tinput.scss\t/^@function remove-where($list, $condition) {$/;\"\tf\nlist\tinput.scss\t/^@function remove-where($list, $condition) {$/;\"\tz\ncondition\tinput.scss\t/^@function remove-where($list, $condition) {$/;\"\tz\nnew-list\tinput.scss\t/^  $new-list: ();$/;\"\tv\nseparator\tinput.scss\t/^  $separator: list-separator($list);$/;\"\tv\nelement\tinput.scss\t/^  @each $element in $list {$/;\"\tv\nnew-list\tinput.scss\t/^      $new-list: append($new-list, $element, $separator: $separator);$/;\"\tv\nfonts\tinput.scss\t/^$fonts: Tahoma, Geneva, \"Helvetica Neue\", Helvetica, Arial, sans-serif;$/;\"\tv\ncontains-helvetica\tinput.scss\t/^  @function contains-helvetica($string) {$/;\"\tf\nstring\tinput.scss\t/^  @function contains-helvetica($string) {$/;\"\tz\n"
  },
  {
    "path": "Units/parser-scss.r/function.d/input.scss",
    "content": "// Taken from https://sass-lang.com/documentation/values/functions\n/// Return a copy of $list with all elements for which $condition returns `true`\n/// removed.\n@function remove-where($list, $condition) {\n  $new-list: ();\n  $separator: list-separator($list);\n  @each $element in $list {\n    @if not call($condition, $element) {\n      $new-list: append($new-list, $element, $separator: $separator);\n    }\n  }\n  @return $new-list;\n}\n\n$fonts: Tahoma, Geneva, \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n\ncontent {\n  @function contains-helvetica($string) {\n    @return str-index($string, \"Helvetica\");\n  }\n  font-family: remove-where($fonts, get-function(\"contains-helvetica\"));\n}\n"
  },
  {
    "path": "Units/parser-scss.r/mixin.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-scss.r/mixin.d/expected.tags",
    "content": "reset-list\tinput.scss\t/^@mixin reset-list {$/;\"\tm\nhorizontal-list\tinput.scss\t/^@mixin horizontal-list {$/;\"\tm\n"
  },
  {
    "path": "Units/parser-scss.r/mixin.d/input.scss",
    "content": "// Taken from https://sass-lang.com/documentation/at-rules/mixin\n@mixin reset-list {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n\n@mixin horizontal-list {\n  @include reset-list;\n\n  li {\n    display: inline-block;\n    margin: {\n      left: -2px;\n      right: 2em;\n    }\n  }\n}\n\nnav ul {\n  @include horizontal-list;\n}\n"
  },
  {
    "path": "Units/parser-scss.r/placeholder.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-scss.r/placeholder.d/expected.tags",
    "content": "alert\tinput.scss\t/^.alert:hover, %strong-alert {$/;\"\tc\nstrong-alert\tinput.scss\t/^.alert:hover, %strong-alert {$/;\"\tP\nstrong-alert\tinput.scss\t/^%strong-alert:hover {$/;\"\tP\ntoolbelt\tinput.scss\t/^%toolbelt {$/;\"\tP\naction-buttons\tinput.scss\t/^.action-buttons {$/;\"\tc\nreset-buttons\tinput.scss\t/^.reset-buttons {$/;\"\tc\n"
  },
  {
    "path": "Units/parser-scss.r/placeholder.d/input.scss",
    "content": ".alert:hover, %strong-alert {\n  font-weight: bold;\n}\n\n%strong-alert:hover {\n  color: red;\n}\n\n%toolbelt {\n  box-sizing: border-box;\n  border-top: 1px rgba(#000, .12) solid;\n  padding: 16px 0;\n  width: 100%;\n\n  &:hover { border: 2px rgba(#000, .5) solid; }\n}\n\n.action-buttons {\n  @extend %toolbelt;\n  color: #4285f4;\n}\n\n.reset-buttons {\n  @extend %toolbelt;\n  color: #cddc39;\n}\n"
  },
  {
    "path": "Units/parser-scss.r/selectors.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-scss.r/selectors.d/expected.tags",
    "content": "alert\tinput.scss\t/^.alert, .warning {$/;\"\tc\nwarning\tinput.scss\t/^.alert, .warning {$/;\"\tc\nmodal-open\tinput.scss\t/^.modal-open {$/;\"\tc\nmodal\tinput.scss\t/^  .modal {$/;\"\tc\nfoo\tinput.scss\t/^  #foo {$/;\"\ti\n"
  },
  {
    "path": "Units/parser-scss.r/selectors.d/input.scss",
    "content": "/* Taken from https://sass-lang.com/documentation/style-rules */\n.alert, .warning {\n  ul, p {\n    margin-right: 0;\n    margin-left: 0;\n    padding-bottom: 0;\n  }\n}\n\n/* Taken from _bodal.scss of bootstrap */\n.modal-open {\n  // Kill the scroll on the body\n  overflow: hidden;\n\n  .modal {\n    overflow-x: hidden;\n    overflow-y: auto;\n  }\n\n  #foo {\n      color: red;\n  }\n}\n"
  },
  {
    "path": "Units/parser-scss.r/use.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-scss.r/use.d/expected.tags",
    "content": "X/y\tinput.scss\t/^@use \"X\\/y\";$/;\"\tM\troles:used\ny\tinput.scss\t/^@use \"X\\/y\";$/;\"\tn\troles:def\tmodule:X/y\nZ\tinput.scss\t/^@use \"Z\";$/;\"\tM\troles:used\nZ\tinput.scss\t/^@use \"Z\";$/;\"\tn\troles:def\tmodule:Z\nA\tinput.scss\t/^@use \"A\" as NS;$/;\"\tM\troles:used\nNS\tinput.scss\t/^@use \"A\" as NS;$/;\"\tn\troles:def\tmodule:A\nB/\tinput.scss\t/^@use \"B\\/\";$/;\"\tM\troles:used\nC/d/e\tinput.scss\t/^@use 'C\\/d\\/e';$/;\"\tM\troles:used\ne\tinput.scss\t/^@use 'C\\/d\\/e';$/;\"\tn\troles:def\tmodule:C/d/e\nP/q\tinput.scss\t/^@use 'P\\/q' as *;$/;\"\tM\troles:used\n"
  },
  {
    "path": "Units/parser-scss.r/use.d/input.scss",
    "content": "@use \"X/y\";\n@use \"Z\";\n@use \"A\" as NS;\n@use \"B/\";\n@use 'C/d/e';\n@use 'P/q' as *;\n"
  },
  {
    "path": "Units/parser-scss.r/variable.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-scss.r/variable.d/expected.tags",
    "content": "base-color\tinput.scss\t/^$base-color: #c6538c;$/;\"\tv\nborder-dark\tinput.scss\t/^$border-dark: rgba($base-color, 0.88);$/;\"\tv\nalert\tinput.scss\t/^.alert {$/;\"\tc\ni\tinput.scss\t/^@for $i from 1 through 3 {$/;\"\tv\nsizes\tinput.scss\t/^$sizes: 40px, 50px, 80px;$/;\"\tv\nsize\tinput.scss\t/^@each $size in $sizes {$/;\"\tv\nicon-\tinput.scss\t/^  .icon-#{$size} {$/;\"\tc\n"
  },
  {
    "path": "Units/parser-scss.r/variable.d/input.scss",
    "content": "// Taken from https://sass-lang.com/documentation/variables\n$base-color: #c6538c;\n$border-dark: rgba($base-color, 0.88);\n\n.alert {\n  border: 1px solid $border-dark;\n}\n\n// Taken from https://sass-lang.com/documentation/at-rules/control/for\n@for $i from 1 through 3 {\n  ul:nth-child(3n + #{$i}) {\n    background-color: lighten($base-color, $i * 5%);\n  }\n}\n\n// Taken from https://sass-lang.com/documentation/at-rules/control/each\n$sizes: 40px, 50px, 80px;\n\n@each $size in $sizes {\n  .icon-#{$size} {\n    font-size: $size;\n    height: $size;\n    width: $size;\n  }\n}\n"
  },
  {
    "path": "Units/parser-selinux-interface.r/simple.d/args.ctags",
    "content": "--sort=no\n--fields=+e\n"
  },
  {
    "path": "Units/parser-selinux-interface.r/simple.d/expected.tags",
    "content": "su_restricted_domain_template\tinput.if\t/^template(`su_restricted_domain_template', `$/;\"\tt\tend:140\nsu_role_template\tinput.if\t/^template(`su_role_template',`$/;\"\tt\tend:202\nsu_exec\tinput.if\t/^interface(`su_exec',`$/;\"\ti\tend:221\n"
  },
  {
    "path": "Units/parser-selinux-interface.r/simple.d/input.if",
    "content": "###\n### Taoken from selinux-policy-0113b35519369e628e7fcd87af000cfcd4b1fa6c/policy/modules/admin/su.if\n###\n\n## <summary>Run shells with substitute user and group</summary>\n\n#######################################\n## <summary>\n##\tRestricted su domain template.\n## </summary>\n## <desc>\n##\t<p>\n##\tThis template creates a derived domain which is allowed\n##\tto change the linux user id, to run shells as a different\n##\tuser.\n##\t</p>\n## </desc>\n## <param name=\"userdomain_prefix\">\n##\t<summary>\n##\tThe prefix of the user domain (e.g., user\n##\tis the prefix for user_t).\n##\t</summary>\n## </param>\n## <param name=\"user_domain\">\n##\t<summary>\n##\tThe type of the user domain.\n##\t</summary>\n## </param>\n## <param name=\"user_role\">\n##\t<summary>\n##\tThe role associated with the user domain.\n##\t</summary>\n## </param>\n#\ntemplate(`su_restricted_domain_template', `\n\tgen_require(`\n\t\ttype su_exec_t;\n\t')\n\n\ttype $1_su_t;\n\tdomain_entry_file($1_su_t, su_exec_t)\n\tdomain_type($1_su_t)\n\tdomain_interactive_fd($1_su_t)\n\trole $3 types $1_su_t;\n\n\tallow $2 $1_su_t:process signal;\n\n\tallow $1_su_t self:capability { audit_control audit_write setuid setgid net_bind_service chown dac_read_search  fowner sys_nice sys_resource };\n\tdontaudit $1_su_t self:capability sys_tty_config;\n\tallow $1_su_t self:key { search write };\n\tallow $1_su_t self:process { setexec setsched setrlimit };\n\tallow $1_su_t self:fifo_file rw_fifo_file_perms;\n\tallow $1_su_t self:netlink_audit_socket { nlmsg_relay create_netlink_socket_perms };\n\tallow $1_su_t self:unix_stream_socket create_stream_socket_perms;\n    allow $1_su_t self:netlink_selinux_socket create_socket_perms;\n\n\t# Transition from the user domain to this domain.\n\tdomtrans_pattern($2, su_exec_t, $1_su_t)\n\n\t# By default, revert to the calling domain when a shell is executed.\n\tcorecmd_shell_domtrans($1_su_t,$2)\n\tallow $2 $1_su_t:fd use;\n\tallow $2 $1_su_t:fifo_file rw_file_perms;\n\tallow $2 $1_su_t:process sigchld;\n\n    kernel_getattr_core_if($1_su_t)\n\tkernel_read_system_state($1_su_t)\n\tkernel_read_kernel_sysctls($1_su_t)\n\tkernel_search_key($1_su_t)\n\tkernel_link_key($1_su_t)\n\n\t# for SSP\n\tdev_read_urand($1_su_t)\n\n\tfiles_read_etc_files($1_su_t)\n\tfiles_read_etc_runtime_files($1_su_t)\n\tfiles_search_var_lib($1_su_t)\n\tfiles_dontaudit_getattr_tmp_dirs($1_su_t)\n\n\t# for the rootok check\n\tselinux_compute_access_vector($1_su_t)\n\n\tauth_domtrans_chk_passwd($1_su_t)\n\tauth_dontaudit_read_shadow($1_su_t)\n\tauth_use_nsswitch($1_su_t)\n\tauth_rw_faillog($1_su_t)\n\n\tdomain_use_interactive_fds($1_su_t)\n\n\tinit_dontaudit_use_fds($1_su_t)\n\tinit_dontaudit_use_script_ptys($1_su_t)\n\t# Write to utmp.\n\tinit_rw_utmp($1_su_t)\n\tinit_search_script_keys($1_su_t)\n    init_getattr_initctl($1_su_t)\n\n\tlogging_send_syslog_msg($1_su_t)\n\n\n\tifdef(`distro_redhat',`\n\t\t# RHEL5 and possibly newer releases incl. Fedora\n\t\tauth_domtrans_upd_passwd($1_su_t)\n\n\t\toptional_policy(`\n\t\t\tlocallogin_search_keys($1_su_t)\n\t\t')\n\t')\n\n\tifdef(`distro_rhel4',`\n\t\tdomain_role_change_exemption($1_su_t)\n\t\tdomain_subj_id_change_exemption($1_su_t)\n\t\tdomain_obj_id_change_exemption($1_su_t)\n\n\t\tselinux_get_fs_mount($1_su_t)\n\t\tselinux_validate_context($1_su_t)\n\t\tselinux_compute_access_vector($1_su_t)\n\t\tselinux_compute_create_context($1_su_t)\n\t\tselinux_compute_relabel_context($1_su_t)\n\t\tselinux_compute_user_contexts($1_su_t)\n\n\t\tseutil_read_config($1_su_t)\n\t\tseutil_read_default_contexts($1_su_t)\n\n\t\t# Only allow transitions to unprivileged user domains.\n\t\tuserdom_spec_domtrans_unpriv_users($1_su_t)\n\t')\n\n\toptional_policy(`\n\t\tcron_read_pipes($1_su_t)\n\t')\n\n\toptional_policy(`\n\t\tkerberos_use($1_su_t)\n\t')\n\n\toptional_policy(`\n\t\t# used when the password has expired\n\t\tusermanage_read_crack_db($1_su_t)\n\t')\n')\n\n#######################################\n## <summary>\n##\tThe role template for the su module.\n## </summary>\n## <param name=\"role_prefix\">\n##\t<summary>\n##\tThe prefix of the user role (e.g., user\n##\tis the prefix for user_r).\n##\t</summary>\n## </param>\n## <param name=\"user_role\">\n##\t<summary>\n##\tThe role associated with the user domain.\n##\t</summary>\n## </param>\n## <param name=\"user_domain\">\n##\t<summary>\n##\tThe type of the user domain.\n##\t</summary>\n## </param>\n#\ntemplate(`su_role_template',`\n\tgen_require(`\n\t\tattribute su_domain_type;\n\t\ttype su_exec_t;\n\t\tbool secure_mode;\n\t')\n\n\ttype $1_su_t, su_domain_type;\n\tuserdom_user_application_domain($1_su_t, su_exec_t)\n\tdomain_interactive_fd($1_su_t)\n\trole $2 types $1_su_t;\n\n    allow $1_su_t self:netlink_selinux_socket create_socket_perms;\n\n\tallow $3 $1_su_t:process signal;\n\tallow $1_su_t $3:key search;\n\n\t# Transition from the user domain to this domain.\n\tdomtrans_pattern($3, su_exec_t, $1_su_t)\n\n\tps_process_pattern($3, $1_su_t)\n\n\t# By default, revert to the calling domain when a shell is executed.\n\tcorecmd_shell_domtrans($1_su_t, $3)\n\tallow $3 $1_su_t:fd use;\n\tallow $3 $1_su_t:fifo_file rw_file_perms;\n\tallow $3 $1_su_t:process sigchld;\n\n\tkernel_read_system_state($1_su_t)\n\tkernel_dontaudit_getattr_core_if($1_su_t)\n\n\tauth_use_pam($1_su_t)\n\n\tinit_dontaudit_getattr_initctl($1_su_t)\n\n\tmls_file_write_all_levels($1_su_t)\n\n\tlogging_send_syslog_msg($1_su_t)\n\n')\n\n#######################################\n## <summary>\n##\tExecute su in the caller domain.\n## </summary>\n## <param name=\"domain\">\n##\t<summary>\n##\tDomain allowed access.\n##\t</summary>\n## </param>\n#\ninterface(`su_exec',`\n\tgen_require(`\n\t\ttype su_exec_t;\n\t')\n\n\tcorecmd_search_bin($1)\n\tcan_exec($1, su_exec_t)\n')\n\ndummy(`dont_tag_me',`')\n"
  },
  {
    "path": "Units/parser-selinux-type-enforcement.r/modules.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-selinux-type-enforcement.r/modules.d/expected.tags",
    "content": "bind\tinput.te\t/^module bind 1.0.0;$/;\"\tm\nbootloader\tinput-0.te\t/^policy_module(bootloader, 1.14.0)$/;\"\tm\n"
  },
  {
    "path": "Units/parser-selinux-type-enforcement.r/modules.d/input-0.te",
    "content": "# selinux-policy-0113b35519369e628e7fcd87af000cfcd4b1fa6c/policy/modules/admin/bootloader.te\npolicy_module(bootloader, 1.14.0)\n"
  },
  {
    "path": "Units/parser-selinux-type-enforcement.r/modules.d/input.te",
    "content": "# https://github.com/SELinuxProject/selinux-notebook/blob/main/src/modular_policy_statements.md#modular-policy-support-statements\nmodule bind 1.0.0;\n"
  },
  {
    "path": "Units/parser-selinux-type-enforcement.r/simple.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-selinux-type-enforcement.r/simple.d/expected.tags",
    "content": "dbus\tinput.te\t/^policy_module(dbus, 1.19.0)$/;\"\tm\ndbusd_unconfined\tinput.te\t/^attribute dbusd_unconfined;$/;\"\tT\nsystem_bus_type\tinput.te\t/^attribute system_bus_type;$/;\"\tT\ndbusd_etc_t\tinput.te\t/^type dbusd_etc_t;$/;\"\tt\ndbusd_exec_t\tinput.te\t/^type dbusd_exec_t;$/;\"\tt\nsystem_dbusd_exec_t\tinput.te\t/^typealias dbusd_exec_t alias system_dbusd_exec_t;$/;\"\ta\ttyperef:type:dbusd_exec_t\nsession_dbusd_tmp_t\tinput.te\t/^type session_dbusd_tmp_t;$/;\"\tt\nuser_dbusd_tmp_t\tinput.te\t/^typealias session_dbusd_tmp_t alias { user_dbusd_tmp_t staff_dbusd_tmp_t sysadm_dbusd_tmp_t };$/;\"\ta\ttyperef:type:session_dbusd_tmp_t\nstaff_dbusd_tmp_t\tinput.te\t/^typealias session_dbusd_tmp_t alias { user_dbusd_tmp_t staff_dbusd_tmp_t sysadm_dbusd_tmp_t };$/;\"\ta\ttyperef:type:session_dbusd_tmp_t\nsysadm_dbusd_tmp_t\tinput.te\t/^typealias session_dbusd_tmp_t alias { user_dbusd_tmp_t staff_dbusd_tmp_t sysadm_dbusd_tmp_t };$/;\"\ta\ttyperef:type:session_dbusd_tmp_t\nauditadm_dbusd_tmp_t\tinput.te\t/^typealias session_dbusd_tmp_t alias { auditadm_dbusd_tmp_t secadm_dbusd_tmp_t };$/;\"\ta\ttyperef:type:session_dbusd_tmp_t\nsecadm_dbusd_tmp_t\tinput.te\t/^typealias session_dbusd_tmp_t alias { auditadm_dbusd_tmp_t secadm_dbusd_tmp_t };$/;\"\ta\ttyperef:type:session_dbusd_tmp_t\nsystem_r\tinput.te\t/^role system_r types system_bus_type;$/;\"\tr\ngit_sys_content_t\tinput.te\t/^type git_sys_content_t alias git_system_content_t;$/;\"\tt\ngit_system_content_t\tinput.te\t/^type git_sys_content_t alias git_system_content_t;$/;\"\ta\ttyperef:type:git_sys_content_t\nkmod_t\tinput.te\t/^type kmod_t alias { update_modules_t depmod_t insmod_t };$/;\"\tt\nupdate_modules_t\tinput.te\t/^type kmod_t alias { update_modules_t depmod_t insmod_t };$/;\"\ta\ttyperef:type:kmod_t\ndepmod_t\tinput.te\t/^type kmod_t alias { update_modules_t depmod_t insmod_t };$/;\"\ta\ttyperef:type:kmod_t\ninsmod_t\tinput.te\t/^type kmod_t alias { update_modules_t depmod_t insmod_t };$/;\"\ta\ttyperef:type:kmod_t\nsystem_r\tinput.te\t/^role system_r types anaconda_t;$/;\"\tr\ninstall_roles\tinput.te\t/^attribute_role install_roles;$/;\"\tR\nantivirus_can_scan_system\tinput.te\t/^gen_tunable(antivirus_can_scan_system, false)$/;\"\tb\nsecure_mode_insmod\tinput.te\t/^gen_bool(secure_mode_insmod, false)$/;\"\tb\nallow_daemons_use_tty\tinput.te\t/^bool allow_daemons_use_tty true;$/;\"\tb\nxguest_u\tinput.te\t/^gen_user(xguest_u, user, xguest_r, s0, s0)$/;\"\tu\nsysadm_u\tinput.te\t/^user sysadm_u roles { sysadm_r } level s0 range s0-s15:c0.c255;$/;\"\tu\n"
  },
  {
    "path": "Units/parser-selinux-type-enforcement.r/simple.d/input.te",
    "content": "#\n# Derrived from policy/modules/contrib/dbus.te\n#\npolicy_module(dbus, 1.19.0)\n\ngen_require(`\n\tclass dbus all_dbus_perms;\n')\n\n##############################\n#\n# Delcarations\n#\n\nattribute dbusd_unconfined;\nattribute system_bus_type;\n\ntype dbusd_etc_t;\nfiles_config_file(dbusd_etc_t)\n\ntype dbusd_exec_t;\ncorecmd_executable_file(dbusd_exec_t)\ntypealias dbusd_exec_t alias system_dbusd_exec_t;\n\ntype session_dbusd_tmp_t;\ntypealias session_dbusd_tmp_t alias { user_dbusd_tmp_t staff_dbusd_tmp_t sysadm_dbusd_tmp_t };\ntypealias session_dbusd_tmp_t alias { auditadm_dbusd_tmp_t secadm_dbusd_tmp_t };\nuserdom_user_tmp_file(session_dbusd_tmp_t)\n\n# ...\n\n########################################\n#\n# system_bus_type rules\n#\nrole system_r types system_bus_type;\ndontaudit system_bus_type self:capability net_admin;\n\n# The next one should not be tagged.\ngen_require(`\n    type ssh_keygen_t;\n')\n\n\ntype git_sys_content_t alias git_system_content_t;\ntype kmod_t alias { update_modules_t depmod_t insmod_t };\n\nrole system_r types anaconda_t;\nattribute_role install_roles;\nroleattribute system_r install_roles;\n\ngen_tunable(antivirus_can_scan_system, false)\ngen_bool(secure_mode_insmod, false)\n\nbool allow_daemons_use_tty true;\n\ngen_user(xguest_u, user, xguest_r, s0, s0)\nuser sysadm_u roles { sysadm_r } level s0 range s0-s15:c0.c255;\n"
  },
  {
    "path": "Units/parser-sh.r/array-alike-function.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sh.r/array-alike-function.d/expected.tags",
    "content": "func\tinput.bash\t/^func() {$/;\"\tf\nfunc1=\tinput.bash\t/^function func1=$/;\"\tf\nfunc2=\tinput.bash\t/^function func2= {$/;\"\tf\nfunc3=\tinput.bash\t/^func3=() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/array-alike-function.d/input.bash",
    "content": "#!/bin/bash\nfunc() {\n    :\n}\nfuncs=()\n\nfunction func1=\n{\n    :\n}\n\nfunction func2= {\n    :\n}\n\nfunc3=() {\n    :\n}\n\nnotfunc=()\n{\n    :\n}\n"
  },
  {
    "path": "Units/parser-sh.r/function-identifiers-bash.d/expected.tags",
    "content": "foo!bar\tinput.bash\t/^function foo!bar() { echo 'foo!bar'; }$/;\"\tf\nfoo#bar\tinput.bash\t/^function foo#bar() { echo 'foo#bar'; }$/;\"\tf\nfoo%bar\tinput.bash\t/^function foo%bar() { echo 'foo%bar'; }$/;\"\tf\nfoo*bar\tinput.bash\t/^function foo*bar() { echo 'foo*bar'; }$/;\"\tf\nfoo+bar\tinput.bash\t/^function foo+bar() { echo 'foo+bar'; }$/;\"\tf\nfoo,bar\tinput.bash\t/^function foo,bar() { echo 'foo,bar'; }$/;\"\tf\nfoo-bar\tinput.bash\t/^function foo-bar() { echo 'foo-bar'; }$/;\"\tf\nfoo.bar\tinput.bash\t/^function foo.bar() { echo 'foo.bar'; }$/;\"\tf\nfoo/bar\tinput.bash\t/^function foo\\/bar() { echo 'foo\\/bar'; }$/;\"\tf\nfoo0bar\tinput.bash\t/^function foo0bar() { echo 'foo0bar'; }$/;\"\tf\nfoo1bar\tinput.bash\t/^function foo1bar() { echo 'foo1bar'; }$/;\"\tf\nfoo2bar\tinput.bash\t/^function foo2bar() { echo 'foo2bar'; }$/;\"\tf\nfoo3bar\tinput.bash\t/^function foo3bar() { echo 'foo3bar'; }$/;\"\tf\nfoo4bar\tinput.bash\t/^function foo4bar() { echo 'foo4bar'; }$/;\"\tf\nfoo5bar\tinput.bash\t/^function foo5bar() { echo 'foo5bar'; }$/;\"\tf\nfoo6bar\tinput.bash\t/^function foo6bar() { echo 'foo6bar'; }$/;\"\tf\nfoo7bar\tinput.bash\t/^function foo7bar() { echo 'foo7bar'; }$/;\"\tf\nfoo8bar\tinput.bash\t/^function foo8bar() { echo 'foo8bar'; }$/;\"\tf\nfoo9bar\tinput.bash\t/^function foo9bar() { echo 'foo9bar'; }$/;\"\tf\nfoo:bar\tinput.bash\t/^function foo:bar() { echo 'foo:bar'; }$/;\"\tf\nfoo=bar\tinput.bash\t/^function foo=bar() { echo 'foo=bar'; }$/;\"\tf\nfoo?bar\tinput.bash\t/^function foo?bar() { echo 'foo?bar'; }$/;\"\tf\nfoo@bar\tinput.bash\t/^function foo@bar() { echo 'foo@bar'; }$/;\"\tf\nfooAbar\tinput.bash\t/^function fooAbar() { echo 'fooAbar'; }$/;\"\tf\nfooBbar\tinput.bash\t/^function fooBbar() { echo 'fooBbar'; }$/;\"\tf\nfooCbar\tinput.bash\t/^function fooCbar() { echo 'fooCbar'; }$/;\"\tf\nfooDbar\tinput.bash\t/^function fooDbar() { echo 'fooDbar'; }$/;\"\tf\nfooEbar\tinput.bash\t/^function fooEbar() { echo 'fooEbar'; }$/;\"\tf\nfooFbar\tinput.bash\t/^function fooFbar() { echo 'fooFbar'; }$/;\"\tf\nfooGbar\tinput.bash\t/^function fooGbar() { echo 'fooGbar'; }$/;\"\tf\nfooHbar\tinput.bash\t/^function fooHbar() { echo 'fooHbar'; }$/;\"\tf\nfooIbar\tinput.bash\t/^function fooIbar() { echo 'fooIbar'; }$/;\"\tf\nfooJbar\tinput.bash\t/^function fooJbar() { echo 'fooJbar'; }$/;\"\tf\nfooKbar\tinput.bash\t/^function fooKbar() { echo 'fooKbar'; }$/;\"\tf\nfooLbar\tinput.bash\t/^function fooLbar() { echo 'fooLbar'; }$/;\"\tf\nfooMbar\tinput.bash\t/^function fooMbar() { echo 'fooMbar'; }$/;\"\tf\nfooNbar\tinput.bash\t/^function fooNbar() { echo 'fooNbar'; }$/;\"\tf\nfooObar\tinput.bash\t/^function fooObar() { echo 'fooObar'; }$/;\"\tf\nfooPbar\tinput.bash\t/^function fooPbar() { echo 'fooPbar'; }$/;\"\tf\nfooQbar\tinput.bash\t/^function fooQbar() { echo 'fooQbar'; }$/;\"\tf\nfooRbar\tinput.bash\t/^function fooRbar() { echo 'fooRbar'; }$/;\"\tf\nfooSbar\tinput.bash\t/^function fooSbar() { echo 'fooSbar'; }$/;\"\tf\nfooTbar\tinput.bash\t/^function fooTbar() { echo 'fooTbar'; }$/;\"\tf\nfooUbar\tinput.bash\t/^function fooUbar() { echo 'fooUbar'; }$/;\"\tf\nfooVbar\tinput.bash\t/^function fooVbar() { echo 'fooVbar'; }$/;\"\tf\nfooWbar\tinput.bash\t/^function fooWbar() { echo 'fooWbar'; }$/;\"\tf\nfooXbar\tinput.bash\t/^function fooXbar() { echo 'fooXbar'; }$/;\"\tf\nfooYbar\tinput.bash\t/^function fooYbar() { echo 'fooYbar'; }$/;\"\tf\nfooZbar\tinput.bash\t/^function fooZbar() { echo 'fooZbar'; }$/;\"\tf\nfoo[bar\tinput.bash\t/^function foo[bar() { echo 'foo[bar'; }$/;\"\tf\nfoo\\abar\tinput.bash\t/^function foo\u0007bar() { echo 'foo\u0007bar'; }$/;\"\tf\nfoo\\bbar\tinput.bash\t/^function foo\bbar() { echo 'foo\bbar'; }$/;\"\tf\nfoo\\fbar\tinput.bash\t/^function foo\fbar() { echo 'foo\fbar'; }$/;\"\tf\nfoo\\vbar\tinput.bash\t/^function foo\u000bbar() { echo 'foo\u000bbar'; }$/;\"\tf\nfoo\\x02bar\tinput.bash\t/^function foo\u0002bar() { echo 'foo\u0002bar'; }$/;\"\tf\nfoo\\x03bar\tinput.bash\t/^function foo\u0003bar() { echo 'foo\u0003bar'; }$/;\"\tf\nfoo\\x04bar\tinput.bash\t/^function foo\u0004bar() { echo 'foo\u0004bar'; }$/;\"\tf\nfoo\\x05bar\tinput.bash\t/^function foo\u0005bar() { echo 'foo\u0005bar'; }$/;\"\tf\nfoo\\x06bar\tinput.bash\t/^function foo\u0006bar() { echo 'foo\u0006bar'; }$/;\"\tf\nfoo\\x0Ebar\tinput.bash\t/^function foo\u000ebar() { echo 'foo\u000ebar'; }$/;\"\tf\nfoo\\x0Fbar\tinput.bash\t/^function foo\u000fbar() { echo 'foo\u000fbar'; }$/;\"\tf\nfoo\\x10bar\tinput.bash\t/^function foo\u0010bar() { echo 'foo\u0010bar'; }$/;\"\tf\nfoo\\x11bar\tinput.bash\t/^function foo\u0011bar() { echo 'foo\u0011bar'; }$/;\"\tf\nfoo\\x12bar\tinput.bash\t/^function foo\u0012bar() { echo 'foo\u0012bar'; }$/;\"\tf\nfoo\\x13bar\tinput.bash\t/^function foo\u0013bar() { echo 'foo\u0013bar'; }$/;\"\tf\nfoo\\x14bar\tinput.bash\t/^function foo\u0014bar() { echo 'foo\u0014bar'; }$/;\"\tf\nfoo\\x15bar\tinput.bash\t/^function foo\u0015bar() { echo 'foo\u0015bar'; }$/;\"\tf\nfoo\\x16bar\tinput.bash\t/^function foo\u0016bar() { echo 'foo\u0016bar'; }$/;\"\tf\nfoo\\x17bar\tinput.bash\t/^function foo\u0017bar() { echo 'foo\u0017bar'; }$/;\"\tf\nfoo\\x18bar\tinput.bash\t/^function foo\u0018bar() { echo 'foo\u0018bar'; }$/;\"\tf\nfoo\\x19bar\tinput.bash\t/^function foo\u0019bar() { echo 'foo\u0019bar'; }$/;\"\tf\nfoo\\x1Abar\tinput.bash\t/^function foo\u001abar() { echo 'foo\u001abar'; }$/;\"\tf\nfoo\\x1Bbar\tinput.bash\t/^function foo\u001bbar() { echo 'foo\u001bbar'; }$/;\"\tf\nfoo\\x1Cbar\tinput.bash\t/^function foo\u001cbar() { echo 'foo\u001cbar'; }$/;\"\tf\nfoo\\x1Dbar\tinput.bash\t/^function foo\u001dbar() { echo 'foo\u001dbar'; }$/;\"\tf\nfoo\\x1Ebar\tinput.bash\t/^function foo\u001ebar() { echo 'foo\u001ebar'; }$/;\"\tf\nfoo\\x1Fbar\tinput.bash\t/^function foo\u001fbar() { echo 'foo\u001fbar'; }$/;\"\tf\nfoo]bar\tinput.bash\t/^function foo]bar() { echo 'foo]bar'; }$/;\"\tf\nfoo^bar\tinput.bash\t/^function foo^bar() { echo 'foo^bar'; }$/;\"\tf\nfoo_bar\tinput.bash\t/^function foo_bar() { echo 'foo_bar'; }$/;\"\tf\nfooabar\tinput.bash\t/^function fooabar() { echo 'fooabar'; }$/;\"\tf\nfoobbar\tinput.bash\t/^function foobbar() { echo 'foobbar'; }$/;\"\tf\nfoocbar\tinput.bash\t/^function foocbar() { echo 'foocbar'; }$/;\"\tf\nfoodbar\tinput.bash\t/^function foodbar() { echo 'foodbar'; }$/;\"\tf\nfooebar\tinput.bash\t/^function fooebar() { echo 'fooebar'; }$/;\"\tf\nfoofbar\tinput.bash\t/^function foofbar() { echo 'foofbar'; }$/;\"\tf\nfoogbar\tinput.bash\t/^function foogbar() { echo 'foogbar'; }$/;\"\tf\nfoohbar\tinput.bash\t/^function foohbar() { echo 'foohbar'; }$/;\"\tf\nfooibar\tinput.bash\t/^function fooibar() { echo 'fooibar'; }$/;\"\tf\nfoojbar\tinput.bash\t/^function foojbar() { echo 'foojbar'; }$/;\"\tf\nfookbar\tinput.bash\t/^function fookbar() { echo 'fookbar'; }$/;\"\tf\nfoolbar\tinput.bash\t/^function foolbar() { echo 'foolbar'; }$/;\"\tf\nfoombar\tinput.bash\t/^function foombar() { echo 'foombar'; }$/;\"\tf\nfoonbar\tinput.bash\t/^function foonbar() { echo 'foonbar'; }$/;\"\tf\nfooobar\tinput.bash\t/^function fooobar() { echo 'fooobar'; }$/;\"\tf\nfoopbar\tinput.bash\t/^function foopbar() { echo 'foopbar'; }$/;\"\tf\nfooqbar\tinput.bash\t/^function fooqbar() { echo 'fooqbar'; }$/;\"\tf\nfoorbar\tinput.bash\t/^function foorbar() { echo 'foorbar'; }$/;\"\tf\nfoosbar\tinput.bash\t/^function foosbar() { echo 'foosbar'; }$/;\"\tf\nfootbar\tinput.bash\t/^function footbar() { echo 'footbar'; }$/;\"\tf\nfooubar\tinput.bash\t/^function fooubar() { echo 'fooubar'; }$/;\"\tf\nfoovbar\tinput.bash\t/^function foovbar() { echo 'foovbar'; }$/;\"\tf\nfoowbar\tinput.bash\t/^function foowbar() { echo 'foowbar'; }$/;\"\tf\nfooxbar\tinput.bash\t/^function fooxbar() { echo 'fooxbar'; }$/;\"\tf\nfooybar\tinput.bash\t/^function fooybar() { echo 'fooybar'; }$/;\"\tf\nfoozbar\tinput.bash\t/^function foozbar() { echo 'foozbar'; }$/;\"\tf\nfoo{bar\tinput.bash\t/^function foo{bar() { echo 'foo{bar'; }$/;\"\tf\nfoo}bar\tinput.bash\t/^function foo}bar() { echo 'foo}bar'; }$/;\"\tf\nfoo~bar\tinput.bash\t/^function foo~bar() { echo 'foo~bar'; }$/;\"\tf\nfoobar\tinput.bash\t/^function foobar() { echo 'foobar'; }$/;\"\tf\nfoobar\tinput.bash\t/^function foobar() { echo 'foobar'; }$/;\"\tf\nfoo bar\tinput.bash\t/^function foo bar() { echo 'foo bar'; }$/;\"\tf\nfooÿbar\tinput.bash\t/^function fooÿbar() { echo 'fooÿbar'; }$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/function-identifiers-bash.d/input.bash",
    "content": "#~ function foo\u0001bar() { echo 'foo\u0001bar'; }\n#~ foo\u0001bar\n\nfunction foo\u0002bar() { echo 'foo\u0002bar'; }\nfoo\u0002bar\n\nfunction foo\u0003bar() { echo 'foo\u0003bar'; }\nfoo\u0003bar\n\nfunction foo\u0004bar() { echo 'foo\u0004bar'; }\nfoo\u0004bar\n\nfunction foo\u0005bar() { echo 'foo\u0005bar'; }\nfoo\u0005bar\n\nfunction foo\u0006bar() { echo 'foo\u0006bar'; }\nfoo\u0006bar\n\nfunction foo\u0007bar() { echo 'foo\u0007bar'; }\nfoo\u0007bar\n\nfunction foo\bbar() { echo 'foo\bbar'; }\nfoo\bbar\n\n#~ function foo\tbar() { echo 'foo\tbar'; }\n#~ foo\tbar\n\n#~ function foo\n#~ bar() { echo 'foo\n#~ bar'; }\n#~ foo\n#~ bar\n\nfunction foo\u000bbar() { echo 'foo\u000bbar'; }\nfoo\u000bbar\n\nfunction foo\fbar() { echo 'foo\fbar'; }\nfoo\fbar\n\n# CR would actually be allowed by bash, but let's not be crazy\n#~ function foo\r#~ bar() { echo 'foo\r#~ bar'; }\n#~ foo\r#~ bar\n\nfunction foo\u000ebar() { echo 'foo\u000ebar'; }\nfoo\u000ebar\n\nfunction foo\u000fbar() { echo 'foo\u000fbar'; }\nfoo\u000fbar\n\nfunction foo\u0010bar() { echo 'foo\u0010bar'; }\nfoo\u0010bar\n\nfunction foo\u0011bar() { echo 'foo\u0011bar'; }\nfoo\u0011bar\n\nfunction foo\u0012bar() { echo 'foo\u0012bar'; }\nfoo\u0012bar\n\nfunction foo\u0013bar() { echo 'foo\u0013bar'; }\nfoo\u0013bar\n\nfunction foo\u0014bar() { echo 'foo\u0014bar'; }\nfoo\u0014bar\n\nfunction foo\u0015bar() { echo 'foo\u0015bar'; }\nfoo\u0015bar\n\nfunction foo\u0016bar() { echo 'foo\u0016bar'; }\nfoo\u0016bar\n\nfunction foo\u0017bar() { echo 'foo\u0017bar'; }\nfoo\u0017bar\n\nfunction foo\u0018bar() { echo 'foo\u0018bar'; }\nfoo\u0018bar\n\nfunction foo\u0019bar() { echo 'foo\u0019bar'; }\nfoo\u0019bar\n\nfunction foo\u001abar() { echo 'foo\u001abar'; }\nfoo\u001abar\n\nfunction foo\u001bbar() { echo 'foo\u001bbar'; }\nfoo\u001bbar\n\nfunction foo\u001cbar() { echo 'foo\u001cbar'; }\nfoo\u001cbar\n\nfunction foo\u001dbar() { echo 'foo\u001dbar'; }\nfoo\u001dbar\n\nfunction foo\u001ebar() { echo 'foo\u001ebar'; }\nfoo\u001ebar\n\nfunction foo\u001fbar() { echo 'foo\u001fbar'; }\nfoo\u001fbar\n\n#~ function foo bar() { echo 'foo bar'; }\n#~ foo bar\n\nfunction foo!bar() { echo 'foo!bar'; }\nfoo!bar\n\n#~ function foo\\\"bar() { echo 'foo\"bar'; }\n#~ foo\\\"bar\n\nfunction foo#bar() { echo 'foo#bar'; }\nfoo#bar\n\n#~ function foo$bar() { echo 'foo$bar'; }\n#~ foo$bar\n\nfunction foo%bar() { echo 'foo%bar'; }\nfoo%bar\n\n#~ function foo&bar() { echo 'foo&bar'; }\n#~ foo&bar\n\n#~ function foo\\'bar() { echo \"foo'bar\"; }\n#~ foo\\'bar\n\n#~ function foo(bar() { echo 'foo(bar'; }\n#~ foo(bar\n\n#~ function foo)bar() { echo 'foo)bar'; }\n#~ foo)bar\n\nfunction foo*bar() { echo 'foo*bar'; }\nfoo*bar\n\nfunction foo+bar() { echo 'foo+bar'; }\nfoo+bar\n\nfunction foo,bar() { echo 'foo,bar'; }\nfoo,bar\n\nfunction foo-bar() { echo 'foo-bar'; }\nfoo-bar\n\nfunction foo.bar() { echo 'foo.bar'; }\nfoo.bar\n\nfunction foo/bar() { echo 'foo/bar'; }\nfoo/bar\n\nfunction foo0bar() { echo 'foo0bar'; }\nfoo0bar\n\nfunction foo1bar() { echo 'foo1bar'; }\nfoo1bar\n\nfunction foo2bar() { echo 'foo2bar'; }\nfoo2bar\n\nfunction foo3bar() { echo 'foo3bar'; }\nfoo3bar\n\nfunction foo4bar() { echo 'foo4bar'; }\nfoo4bar\n\nfunction foo5bar() { echo 'foo5bar'; }\nfoo5bar\n\nfunction foo6bar() { echo 'foo6bar'; }\nfoo6bar\n\nfunction foo7bar() { echo 'foo7bar'; }\nfoo7bar\n\nfunction foo8bar() { echo 'foo8bar'; }\nfoo8bar\n\nfunction foo9bar() { echo 'foo9bar'; }\nfoo9bar\n\nfunction foo:bar() { echo 'foo:bar'; }\nfoo:bar\n\n#~ function foo;bar() { echo 'foo;bar'; }\n#~ foo;bar\n\n#~ function foo<bar() { echo 'foo<bar'; }\n#~ foo<bar\n\nfunction foo=bar() { echo 'foo=bar'; }\n'foo=bar'\n\n#~ function foo>bar() { echo 'foo>bar'; }\n#~ foo>bar\n\nfunction foo?bar() { echo 'foo?bar'; }\nfoo?bar\n\nfunction foo@bar() { echo 'foo@bar'; }\nfoo@bar\n\nfunction fooAbar() { echo 'fooAbar'; }\nfooAbar\n\nfunction fooBbar() { echo 'fooBbar'; }\nfooBbar\n\nfunction fooCbar() { echo 'fooCbar'; }\nfooCbar\n\nfunction fooDbar() { echo 'fooDbar'; }\nfooDbar\n\nfunction fooEbar() { echo 'fooEbar'; }\nfooEbar\n\nfunction fooFbar() { echo 'fooFbar'; }\nfooFbar\n\nfunction fooGbar() { echo 'fooGbar'; }\nfooGbar\n\nfunction fooHbar() { echo 'fooHbar'; }\nfooHbar\n\nfunction fooIbar() { echo 'fooIbar'; }\nfooIbar\n\nfunction fooJbar() { echo 'fooJbar'; }\nfooJbar\n\nfunction fooKbar() { echo 'fooKbar'; }\nfooKbar\n\nfunction fooLbar() { echo 'fooLbar'; }\nfooLbar\n\nfunction fooMbar() { echo 'fooMbar'; }\nfooMbar\n\nfunction fooNbar() { echo 'fooNbar'; }\nfooNbar\n\nfunction fooObar() { echo 'fooObar'; }\nfooObar\n\nfunction fooPbar() { echo 'fooPbar'; }\nfooPbar\n\nfunction fooQbar() { echo 'fooQbar'; }\nfooQbar\n\nfunction fooRbar() { echo 'fooRbar'; }\nfooRbar\n\nfunction fooSbar() { echo 'fooSbar'; }\nfooSbar\n\nfunction fooTbar() { echo 'fooTbar'; }\nfooTbar\n\nfunction fooUbar() { echo 'fooUbar'; }\nfooUbar\n\nfunction fooVbar() { echo 'fooVbar'; }\nfooVbar\n\nfunction fooWbar() { echo 'fooWbar'; }\nfooWbar\n\nfunction fooXbar() { echo 'fooXbar'; }\nfooXbar\n\nfunction fooYbar() { echo 'fooYbar'; }\nfooYbar\n\nfunction fooZbar() { echo 'fooZbar'; }\nfooZbar\n\nfunction foo[bar() { echo 'foo[bar'; }\n'foo[bar'\n\n#~ function foo\\bar() { echo 'foo\\bar'; }\n#~ foo\\bar\n\nfunction foo]bar() { echo 'foo]bar'; }\n'foo]bar'\n\nfunction foo^bar() { echo 'foo^bar'; }\nfoo^bar\n\nfunction foo_bar() { echo 'foo_bar'; }\nfoo_bar\n\n#~ function foo`bar() { echo 'foo`bar'; }\n#~ foo`bar\n\nfunction fooabar() { echo 'fooabar'; }\nfooabar\n\nfunction foobbar() { echo 'foobbar'; }\nfoobbar\n\nfunction foocbar() { echo 'foocbar'; }\nfoocbar\n\nfunction foodbar() { echo 'foodbar'; }\nfoodbar\n\nfunction fooebar() { echo 'fooebar'; }\nfooebar\n\nfunction foofbar() { echo 'foofbar'; }\nfoofbar\n\nfunction foogbar() { echo 'foogbar'; }\nfoogbar\n\nfunction foohbar() { echo 'foohbar'; }\nfoohbar\n\nfunction fooibar() { echo 'fooibar'; }\nfooibar\n\nfunction foojbar() { echo 'foojbar'; }\nfoojbar\n\nfunction fookbar() { echo 'fookbar'; }\nfookbar\n\nfunction foolbar() { echo 'foolbar'; }\nfoolbar\n\nfunction foombar() { echo 'foombar'; }\nfoombar\n\nfunction foonbar() { echo 'foonbar'; }\nfoonbar\n\nfunction fooobar() { echo 'fooobar'; }\nfooobar\n\nfunction foopbar() { echo 'foopbar'; }\nfoopbar\n\nfunction fooqbar() { echo 'fooqbar'; }\nfooqbar\n\nfunction foorbar() { echo 'foorbar'; }\nfoorbar\n\nfunction foosbar() { echo 'foosbar'; }\nfoosbar\n\nfunction footbar() { echo 'footbar'; }\nfootbar\n\nfunction fooubar() { echo 'fooubar'; }\nfooubar\n\nfunction foovbar() { echo 'foovbar'; }\nfoovbar\n\nfunction foowbar() { echo 'foowbar'; }\nfoowbar\n\nfunction fooxbar() { echo 'fooxbar'; }\nfooxbar\n\nfunction fooybar() { echo 'fooybar'; }\nfooybar\n\nfunction foozbar() { echo 'foozbar'; }\nfoozbar\n\nfunction foo{bar() { echo 'foo{bar'; }\nfoo{bar\n\nfunction foo}bar() { echo 'foo}bar'; }\nfoo}bar\n\nfunction foo~bar() { echo 'foo~bar'; }\nfoo~bar\n\n#~ function foobar() { echo 'foobar'; }\n#~ foobar\n\n# UTF-8\n\nfunction foobar() { echo 'foobar'; }\nfoobar\n\nfunction foobar() { echo 'foobar'; }\nfoobar\n\n# ...\n# and some printable stuff, too\n\nfunction foo bar() { echo 'foo bar'; }\nfoo bar\n\nfunction fooÿbar() { echo 'fooÿbar'; }\nfooÿbar\n"
  },
  {
    "path": "Units/parser-sh.r/function-identifiers-no-function-keyword-bash.d/expected.tags",
    "content": "a::anotherTest\tinput.bash\t/^function a::anotherTest() {$/;\"\tf\na::test\tinput.bash\t/^a::test() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/function-identifiers-no-function-keyword-bash.d/input.bash",
    "content": "#!/usr/bin/env bash\n\n#\n# Taken from the original bug report (https://github.com/universal-ctags/ctags/issues/1261)\n#\n\na::test() {\n    echo \"test\"\n}\n\nfunction a::anotherTest() {\n    echo \"another test\"\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-alias.d/expected.tags",
    "content": "GLOBAL_OPT\tinput-0.zsh\t/^alias -g GLOBAL_OPT=zsh$/;\"\ta\nZSH_X\tinput-0.zsh\t/^alias ZSH_X=ls$/;\"\ta\nafteralias\tinput.sh\t/^alias alias1=bar; afteralias() {}$/;\"\tf\nalias\tinput.sh\t/^function alias(); alias alias2=foo$/;\"\tf\nalias-with-dash\tinput.sh\t/^alias alias-with-dash=alias1$/;\"\ta\nalias1\tinput.sh\t/^alias alias1=bar; afteralias() {}$/;\"\ta\nalias2\tinput.sh\t/^function alias(); alias alias2=foo$/;\"\ta\nalias_in_func1\tinput.sh\t/^  alias alias_in_func1=ls$/;\"\ta\nalias_in_func2\tinput.sh\t/^func2() alias alias_in_func2=ls$/;\"\ta\nalias_in_func3\tinput.sh\t/^func3() { alias alias_in_func3=ls }$/;\"\ta\nfunc1\tinput.sh\t/^func1() {$/;\"\tf\nfunc2\tinput.sh\t/^func2() alias alias_in_func2=ls$/;\"\tf\nfunc3\tinput.sh\t/^func3() { alias alias_in_func3=ls }$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/sh-alias.d/input-0.zsh",
    "content": "alias ZSH_X=ls\nalias -r ZSH_X\nalias -L ZSH_X\nalias -m ZSH_X\nalias -g GLOBAL_OPT=zsh\n\n"
  },
  {
    "path": "Units/parser-sh.r/sh-alias.d/input.sh",
    "content": "alias alias1=bar; afteralias() {}\n\nfunction alias(); alias alias2=foo\n\nfunc1() {\n  alias alias_in_func1=ls\n}\nfunc2() alias alias_in_func2=ls\nfunc3() { alias alias_in_func3=ls }\n\nalias alias-with-dash=alias1\n\nalias -p\nalias\n"
  },
  {
    "path": "Units/parser-sh.r/sh-comments.d/expected.tags",
    "content": "afterpound1\tinput.sh\t/^foo=\"#\"; afterpound1() {}$/;\"\tf\nafterpound2\tinput.sh\t/^foo=\"#\\\\\"\"; afterpound2() {}$/;\"\tf\nafterpound3\tinput.sh\t/^foo='#'; afterpound3() {}$/;\"\tf\nafterpound4\tinput.sh\t/^foo='#'''; afterpound4() {}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/sh-comments.d/input.sh",
    "content": "# function foo() {}\n  # function bar() {}\n  #\nfoo=\"#\"; afterpound1() {}\nfoo=\"#\\\"\"; afterpound2() {}\nfoo='#'; afterpound3() {}\nfoo='#'''; afterpound4() {}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-broken.d/input.sh",
    "content": "c<<A <<B\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-broken2.d/input.sh",
    "content": "<<A"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-checks.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-checks.d/expected.tags",
    "content": "f1\tinput.sh\t/^f1()$/;\"\tf\tline:2\nEOF\tinput.sh\t/^  cat<<EOF$/;\"\th\tline:4\tend:5\nf2\tinput.sh\t/^f2(){ :; }$/;\"\tf\tline:8\nEOF\tinput.sh\t/^cat<<EOF$/;\"\th\tline:9\tend:11\nf3\tinput.sh\t/^f3(){ :; }$/;\"\tf\tline:13\nEOF\tinput.sh\t/^cat<<\"EOF\"$/;\"\th\tline:14\tend:16\nf4\tinput.sh\t/^f4(){ :; }$/;\"\tf\tline:18\nEOF\tinput.sh\t/^cat<<'EOF'$/;\"\th\tline:19\tend:21\nf5\tinput.sh\t/^f5(){ :; }$/;\"\tf\tline:23\nEnd Of File\tinput.sh\t/^cat<<'End Of File'$/;\"\th\tline:24\tend:26\nf6\tinput.sh\t/^f6(){ :; }$/;\"\tf\tline:28\nEOF\tinput.sh\t/^cat<<EOF $/;\"\th\tline:29\tend:36\nf7\tinput.sh\t/^f7(){ :; }$/;\"\tf\tline:38\nEnd Of \"File\"\tinput.sh\t/^cat<<\"End Of \\\\\"File\\\\\"\"$/;\"\th\tline:39\tend:41\nf8\tinput.sh\t/^f8(){ :; }$/;\"\tf\tline:43\nEOF\tinput.sh\t/^cat<<EOF; fancy() { echo hello; }$/;\"\th\tline:45\tend:47\nfancy\tinput.sh\t/^cat<<EOF; fancy() { echo hello; }$/;\"\tf\tline:45\nf9\tinput.sh\t/^f9(){ :; }$/;\"\tf\tline:49\nEOF\tinput.sh\t/^cat<<-EOF$/;\"\th\tline:50\tend:54\nf10\tinput.sh\t/^f10(){ :; }$/;\"\tf\tline:56\nEOF\tinput.sh\t/^cat << EOF$/;\"\th\tline:57\tend:59\nf11\tinput.sh\t/^f11(){ :; }$/;\"\tf\tline:61\nEOF\tinput.sh\t/^cat << \t \tEOF$/;\"\th\tline:62\tend:64\nf12\tinput.sh\t/^f12(){ :; }$/;\"\tf\tline:66\n-EOF\tinput.sh\t/^cat << -EOF$/;\"\th\tline:68\tend:70\nf13\tinput.sh\t/^f13(){ :; }$/;\"\tf\tline:72\nf14\tinput.sh\t/^f14(){ :; }$/;\"\tf\tline:78\nf15\tinput.sh\t/^f15(){ :; }$/;\"\tf\tline:83\nf16\tinput.sh\t/^f16(){ :; }$/;\"\tf\tline:88\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-checks.d/input.sh",
    "content": "\nf1()\n{\n  cat<<EOF\nEOF\n};\n\nf2(){ :; }\ncat<<EOF\nbug2(){ :; }\nEOF\n\nf3(){ :; }\ncat<<\"EOF\"\nbug3(){ :; }\nEOF\n\nf4(){ :; }\ncat<<'EOF'\nbug4(){ :; }\nEOF\n\nf5(){ :; }\ncat<<'End Of File'\nbug5(){ :; }\nEnd Of File\n\nf6(){ :; }\ncat<<EOF \nthis isn't terminated\n\nEOF#test\n EOF\n\nbug6(){ :; }\nEOF \n\nf7(){ :; }\ncat<<\"End Of \\\"File\\\"\"\nbug7(){ :; }\nEnd Of \"File\"\n\nf8(){ :; }\n# this is valid, the heredoc starts on the next line after the <<DELIM\ncat<<EOF; fancy() { echo hello; }\nbug8(){ :; }\nEOF\n\nf9(){ :; }\ncat<<-EOF\n\tbug9(){ :; }\n  this isn't the end, only tabulations are stripped, not spaces\n  EOF\n\tEOF\n\nf10(){ :; }\ncat << EOF\nbug10(){ :; }\nEOF\n\nf11(){ :; }\ncat << \t \tEOF\nbug11(){ :; }\nEOF\n\nf12(){ :; }\n# this is not an indented here-document but a \"-EOF\" delimiter\ncat << -EOF\nbug12(){ :; }\n-EOF\n\nf13(){ :; }\n# quoted empty delimiters are valid\ncat <<''\nbug13(){ :; }\n\n\nf14(){ :; }\ncat <<\"\"\nbug14(){ :; }\n\n\nf15(){ :; }\ncat <<-\"\"\nbug15(){ :; }\n\t\n\nf16(){ :; }\n\nfancy\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-env-with-no-command.d/input.sh",
    "content": "env> php<<E\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-role.d/args.ctags",
    "content": "--extras=+r\n--fields=+reln\n\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-role.d/expected.tags",
    "content": "EOF\tinput.sh\t/^EOF$/;\"\th\tline:3\tlanguage:Sh\troles:endmarker\nEOF\tinput.sh\t/^cat <<EOF$/;\"\th\tline:1\tlanguage:Sh\troles:def\tend:3\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-role.d/input.sh",
    "content": "cat <<EOF\n...\nEOF\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-external-libs-and-bom.d/args.ctags",
    "content": "--extras=+g\n--sort=no\n--fields=+lne\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-external-libs-and-bom.d/expected.tags",
    "content": "f\tinput.sh\t/^f()$/;\"\tf\tline:1\tlanguage:Sh\nEOFA\tinput.sh\t/^cat > foo.xml <<EOFA$/;\"\th\tline:6\tlanguage:Sh\tend:15\ng\tinput.sh\t/^g()$/;\"\tf\tline:17\tlanguage:Sh\nnsdd4b4d500101\tinput.sh\t/^       >$/;\"\tn\tline:10\tlanguage:XML\turi:https://ctags.io/root\nabc\tinput.sh\t/^       >$/;\"\tn\tline:10\tlanguage:XML\turi:https://ctags.io/nosuchthing\nunused\tinput.sh\t/^       >$/;\"\tn\tline:10\tlanguage:XML\turi:https://ctags.io/unused\nefg\tinput.sh\t/^<abc:UnKnownTag id=\"a\" xmlns:efg=\"https:\\/\\/ctags.io\\/nosuchthing2\">$/;\"\tn\tline:11\tlanguage:XML\turi:https://ctags.io/nosuchthing2\na\tinput.sh\t/^<abc:UnKnownTag id=\"a\" xmlns:efg=\"https:\\/\\/ctags.io\\/nosuchthing2\">$/;\"\ti\tline:11\tlanguage:XML\nb\tinput.sh\t/^  <efg:UnKnownTag2 id=\"b\"\\/>$/;\"\ti\tline:12\tlanguage:XML\nh\tinput-0.sh\t/^h()$/;\"\tf\tline:1\tlanguage:Sh\nEOFB\tinput-0.sh\t/^cat > bar.rmd <<EOFB$/;\"\th\tline:6\tlanguage:Sh\tend:18\ni\tinput-0.sh\t/^i()$/;\"\tf\tline:20\tlanguage:Sh\ntitle: example for u-ctags\tinput-0.sh\t/^title: example for u-ctags$/;\"\ts\tline:8\tlanguage:Markdown\tend:9\nS1\tinput-0.sh\t/^# S1$/;\"\tc\tline:10\tlanguage:Markdown\tend:13\nS2\tinput-0.sh\t/^# S2$/;\"\tc\tline:14\tlanguage:Markdown\tend:17\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-external-libs-and-bom.d/features",
    "content": "xpath\nyaml\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-external-libs-and-bom.d/input-0.sh",
    "content": "﻿h()\n{\n\t:\n}\n\ncat > bar.rmd <<EOFB\n---\ntitle: example for u-ctags\n---\n# S1\n\n...\n\n# S2\n\n...\n\nEOFB\n\ni()\n{\n\t:\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-external-libs-and-bom.d/input.sh",
    "content": "﻿f()\n{\n\t:\n}\n\ncat > foo.xml <<EOFA\n<input xmlns=\"https://ctags.io/root\"\n       xmlns:abc=\"https://ctags.io/nosuchthing\"\n       xmlns:unused=\"https://ctags.io/unused\"\n       >\n<abc:UnKnownTag id=\"a\" xmlns:efg=\"https://ctags.io/nosuchthing2\">\n  <efg:UnKnownTag2 id=\"b\"/>\n</abc:UnKnownTag>\n</input>\nEOFA\n\ng()\n{\n\t:\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-external-libs.d/args.ctags",
    "content": "--extras=+g\n--sort=no\n--fields=+lne\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-external-libs.d/expected.tags",
    "content": "f\tinput.sh\t/^f()$/;\"\tf\tline:1\tlanguage:Sh\nEOFA\tinput.sh\t/^cat > foo.xml <<EOFA$/;\"\th\tline:6\tlanguage:Sh\tend:15\ng\tinput.sh\t/^g()$/;\"\tf\tline:17\tlanguage:Sh\nnsb0d066450101\tinput.sh\t/^       >$/;\"\tn\tline:10\tlanguage:XML\turi:https://ctags.io/root\nabc\tinput.sh\t/^       >$/;\"\tn\tline:10\tlanguage:XML\turi:https://ctags.io/nosuchthing\nunused\tinput.sh\t/^       >$/;\"\tn\tline:10\tlanguage:XML\turi:https://ctags.io/unused\nefg\tinput.sh\t/^<abc:UnKnownTag id=\"a\" xmlns:efg=\"https:\\/\\/ctags.io\\/nosuchthing2\">$/;\"\tn\tline:11\tlanguage:XML\turi:https://ctags.io/nosuchthing2\na\tinput.sh\t/^<abc:UnKnownTag id=\"a\" xmlns:efg=\"https:\\/\\/ctags.io\\/nosuchthing2\">$/;\"\ti\tline:11\tlanguage:XML\nb\tinput.sh\t/^  <efg:UnKnownTag2 id=\"b\"\\/>$/;\"\ti\tline:12\tlanguage:XML\nh\tinput-0.sh\t/^h()$/;\"\tf\tline:1\tlanguage:Sh\nEOFB\tinput-0.sh\t/^cat > bar.rmd <<EOFB$/;\"\th\tline:6\tlanguage:Sh\tend:18\ni\tinput-0.sh\t/^i()$/;\"\tf\tline:20\tlanguage:Sh\ntitle: example for u-ctags\tinput-0.sh\t/^title: example for u-ctags$/;\"\ts\tline:8\tlanguage:Markdown\tend:9\nS1\tinput-0.sh\t/^# S1$/;\"\tc\tline:10\tlanguage:Markdown\tend:13\nS2\tinput-0.sh\t/^# S2$/;\"\tc\tline:14\tlanguage:Markdown\tend:17\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-external-libs.d/features",
    "content": "xpath\nyaml\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-external-libs.d/input-0.sh",
    "content": "h()\n{\n\t:\n}\n\ncat > bar.rmd <<EOFB\n---\ntitle: example for u-ctags\n---\n# S1\n\n...\n\n# S2\n\n...\n\nEOFB\n\ni()\n{\n\t:\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-external-libs.d/input.sh",
    "content": "f()\n{\n\t:\n}\n\ncat > foo.xml <<EOFA\n<input xmlns=\"https://ctags.io/root\"\n       xmlns:abc=\"https://ctags.io/nosuchthing\"\n       xmlns:unused=\"https://ctags.io/unused\"\n       >\n<abc:UnKnownTag id=\"a\" xmlns:efg=\"https://ctags.io/nosuchthing2\">\n  <efg:UnKnownTag2 id=\"b\"/>\n</abc:UnKnownTag>\n</input>\nEOFA\n\ng()\n{\n\t:\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-packcc-with-bom.d/args.ctags",
    "content": "--languages=+TOML\n\n--extras=+g\n--sort=no\n--fields=+lne\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-packcc-with-bom.d/expected.tags",
    "content": "j\tinput.sh\t/^j()$/;\"\tf\tline:1\tlanguage:Sh\nEOFC\tinput.sh\t/^cat > baz.md <<EOFC$/;\"\th\tline:6\tlanguage:Sh\tend:13\nk\tinput.sh\t/^k()$/;\"\tf\tline:15\tlanguage:Sh\nT\tinput.sh\t/^## T$/;\"\ts\tline:7\tlanguage:Markdown\tend:12\no\tinput.sh\t/^[o]$/;\"\tt\tline:10\tlanguage:TOML\tend:10\nd\tinput.sh\t/^[d]$/;\"\tt\tline:11\tlanguage:TOML\tend:11\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-packcc-with-bom.d/features",
    "content": "packcc\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-packcc-with-bom.d/input.sh",
    "content": "﻿j()\n{\n\t:\n}\n\ncat > baz.md <<EOFC\n## T\n```toml\n# Th\n[o]\n[d]\n```\nEOFC\n\nk()\n{\n\t:\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-packcc.d/args.ctags",
    "content": "--languages=+TOML\n\n--extras=+g\n--sort=no\n--fields=+lne\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-packcc.d/expected.tags",
    "content": "j\tinput.sh\t/^j()$/;\"\tf\tline:1\tlanguage:Sh\nEOFC\tinput.sh\t/^cat > baz.md <<EOFC$/;\"\th\tline:6\tlanguage:Sh\tend:13\nk\tinput.sh\t/^k()$/;\"\tf\tline:15\tlanguage:Sh\nT\tinput.sh\t/^## T$/;\"\ts\tline:7\tlanguage:Markdown\tend:12\no\tinput.sh\t/^[o]$/;\"\tt\tline:10\tlanguage:TOML\tend:10\nd\tinput.sh\t/^[d]$/;\"\tt\tline:11\tlanguage:TOML\tend:11\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-packcc.d/features",
    "content": "packcc\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser-with-packcc.d/input.sh",
    "content": "j()\n{\n\t:\n}\n\ncat > baz.md <<EOFC\n## T\n```toml\n# Th\n[o]\n[d]\n```\nEOFC\n\nk()\n{\n\t:\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser.d/args.ctags",
    "content": "--extras=+g\n--sort=no\n--fields=+lne\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser.d/expected.tags",
    "content": "sh0\tinput.sh\t/^function sh0$/;\"\tf\tline:3\tlanguage:Sh\nEOF1\tinput.sh\t/^\\/usr\\/bin\\/env php<<EOF1$/;\"\th\tline:8\tlanguage:Sh\tend:13\nEOF2\tinput.sh\t/^php<<EOF2$/;\"\th\tline:15\tlanguage:Sh\tend:20\nJSCODE1\tinput.sh\t/^node <<JSCODE1$/;\"\th\tline:22\tlanguage:Sh\tend:27\nJSCODE2\tinput.sh\t/^\\/usr\\/bin\\/node <<JSCODE2$/;\"\th\tline:29\tlanguage:Sh\tend:34\nJSCODE3\tinput.sh\t/^cat \\/usr\\/bin\\/node <<JSCODE3$/;\"\th\tline:36\tlanguage:Sh\tend:41\nJSCODE3\tinput.sh\t/^\\/usr\\/bin\\/env \\/usr\\/bin\\/node <<JSCODE3$/;\"\th\tline:43\tlanguage:Sh\tend:48\nJSCODE4\tinput.sh\t/^\\/usr\\/bin\\/env dummy node <<JSCODE4$/;\"\th\tline:50\tlanguage:Sh\tend:55\nEOF3\tinput.sh\t/^cat > foo.php <<EOF3$/;\"\th\tline:57\tlanguage:Sh\tend:62\nEOF4\tinput.sh\t/^cat <<EOF4 > foo.php$/;\"\th\tline:64\tlanguage:Sh\tend:69\nsh1\tinput.sh\t/^function sh1$/;\"\tf\tline:71\tlanguage:Sh\nx\tinput.sh\t/^$x = 5 \\/* + 15 *\\/ + 5;$/;\"\tv\tline:10\tlanguage:PHP\ny\tinput.sh\t/^$y = 5 \\/* + 15 *\\/ + 5;$/;\"\tv\tline:17\tlanguage:PHP\npr1\tinput.sh\t/^var pr1 = function (msg) {$/;\"\tf\tline:23\tlanguage:JavaScript\npr2\tinput.sh\t/^var pr2 = function (msg) {$/;\"\tf\tline:30\tlanguage:JavaScript\npr3\tinput.sh\t/^var pr3 = function (msg) {$/;\"\tf\tline:44\tlanguage:JavaScript\nz\tinput.sh\t/^$z = 5 \\/* + 15 *\\/ + 5;$/;\"\tv\tline:59\tlanguage:PHP\na\tinput.sh\t/^$a = 5 \\/* + 15 *\\/ + 5;$/;\"\tv\tline:66\tlanguage:PHP\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc-run-guest-parser.d/input.sh",
    "content": "#!/bin/sh\n\nfunction sh0\n{\n\t:\n}\n\n/usr/bin/env php<<EOF1\n<?php\n$x = 5 /* + 15 */ + 5;\necho $x;\n?>\nEOF1\n\nphp<<EOF2\n<?php\n$y = 5 /* + 15 */ + 5;\necho $y;\n?>\nEOF2\n\nnode <<JSCODE1\nvar pr1 = function (msg) {\n\tconsole.log(msg);\n}\npr1 ('hello');\nJSCODE1\n\n/usr/bin/node <<JSCODE2\nvar pr2 = function (msg) {\n\tconsole.log(msg);\n}\npr2 ('hello');\nJSCODE2\n\ncat /usr/bin/node <<JSCODE3\nvar n_pr0 = function (msg) {\n\tconsole.log(msg);\n}\nn_pr0 ('hello');\nJSCODE3\n\n/usr/bin/env /usr/bin/node <<JSCODE3\nvar pr3 = function (msg) {\n\tconsole.log(msg);\n}\npr3 ('hello');\nJSCODE3\n\n/usr/bin/env dummy node <<JSCODE4\nvar n_pr1 = function (msg) {\n\tconsole.log(msg);\n}\nn_pr1 ('hello');\nJSCODE4\n\ncat > foo.php <<EOF3\n<?php\n$z = 5 /* + 15 */ + 5;\necho $z;\n?>\nEOF3\n\ncat <<EOF4 > foo.php\n<?php\n$a = 5 /* + 15 */ + 5;\necho $a;\n?>\nEOF4\n\nfunction sh1\n{\n\t:\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc.d/args.ctags",
    "content": "--fields=+en\n--kinds-Sh=+h\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc.d/expected.tags",
    "content": "EOF\tinput.sh\t/^cat <<EOF$/;\"\th\tline:1\tend:5\n"
  },
  {
    "path": "Units/parser-sh.r/sh-heredoc.d/input.sh",
    "content": "cat <<EOF\n(cons '(\na ()\n) consider-generating-lisp-code)\nEOF\n"
  },
  {
    "path": "Units/parser-sh.r/sh-herestring.d/expected.tags",
    "content": "f1\tinput.sh\t/^f1(){ :; }$/;\"\tf\nf2\tinput.sh\t/^f2(){ :; }$/;\"\tf\nf3\tinput.sh\t/^f3(){ :; }$/;\"\tf\nf4\tinput.sh\t/^f4(){ :; }$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/sh-herestring.d/input.sh",
    "content": "#!/bin/bash\n# check for Bash's here-strings as they need not to be misinterpreted as\n# here-documents\n\nf1(){ :; }\ncat <<<hello\nf2(){ :; }\ncat <<<\"hello there\"\nf3(){ :; }\ncat <<<'hello there'\nf4(){ :; }\n"
  },
  {
    "path": "Units/parser-sh.r/sh-modeline-1-emacs-shell-script.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/parser-sh.r/sh-modeline-1-emacs-shell-script.d/expected.tags",
    "content": "afunc\tinput.nolang\t/^afunc()$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/sh-modeline-1-emacs-shell-script.d/input.nolang",
    "content": "# -*- shell-script -*-\nafunc()\n{\n    :\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-modeline-2-emacs-shell-script.d/args.ctags",
    "content": "--guess-language-eagerly\n"
  },
  {
    "path": "Units/parser-sh.r/sh-modeline-2-emacs-shell-script.d/expected.tags",
    "content": "afunc\tinput.nolang\t/^afunc()$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/sh-modeline-2-emacs-shell-script.d/input.nolang",
    "content": "# -*- mode: shell-script; -*-\nafunc()\n{\n    :\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-modeline-at-eof-emacs-shell-script.d/args.ctags",
    "content": "--guess-language-eagerly\n--fields=+l\n"
  },
  {
    "path": "Units/parser-sh.r/sh-modeline-at-eof-emacs-shell-script.d/expected.tags",
    "content": "afunc\tinput.nolang\t/^afunc()$/;\"\tf\tlanguage:Sh\n"
  },
  {
    "path": "Units/parser-sh.r/sh-modeline-at-eof-emacs-shell-script.d/input.nolang",
    "content": "afunc()\n{\n    :\n}\n# Local Variables:\n# mode: shell-script\n# End:\n"
  },
  {
    "path": "Units/parser-sh.r/sh-quoted-func.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-sh.r/sh-quoted-func.d/input.sh",
    "content": "echo 'bug(){ :; }'\n"
  },
  {
    "path": "Units/parser-sh.r/sh-quotes.d/expected.tags",
    "content": "afterpound1\tinput.sh\t/^foo=\"#\"; afterpound1() {}$/;\"\tf\nafterpound2\tinput.sh\t/^foo=\"#\\\\\"\"; afterpound2() {}$/;\"\tf\nafterpound3\tinput.sh\t/^foo='#'; afterpound3() {}$/;\"\tf\nafterpound4\tinput.sh\t/^foo='#'''; afterpound4() {}$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/sh-quotes.d/input.sh",
    "content": "foo=\"#\"; afterpound1() {}\nfoo=\"#\\\"\"; afterpound2() {}\nfoo='#'; afterpound3() {}\nfoo='#'''; afterpound4() {}\n\nfoo=\"nofunction()\"\n"
  },
  {
    "path": "Units/parser-sh.r/sh-source.d/args.ctags",
    "content": "--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-sh.r/sh-source.d/expected.tags",
    "content": "../a\tinput.sh\t/^. ..\\/a$/;\"\ts\troles:loaded\n../x\tinput.sh\t/^source ..\\/x$/;\"\ts\troles:loaded\n0.sh\tinput.sh\t/^source 0.sh$/;\"\ts\troles:loaded\n1.sh\tinput.sh\t/^. 1.sh$/;\"\ts\troles:loaded\na\tinput.sh\t/^. a$/;\"\ts\troles:loaded\na/b\tinput.sh\t/^. a\\/b$/;\"\ts\troles:loaded\nx\tinput.sh\t/^source x$/;\"\ts\troles:loaded\nx/y\tinput.sh\t/^source x\\/y$/;\"\ts\troles:loaded\n"
  },
  {
    "path": "Units/parser-sh.r/sh-source.d/input.sh",
    "content": "source x\nsource x/y\nsource ../x\n. a\n. a/b\n. ../a\n\nsourceX\n\nsource\nX\n\n.A\n\n.\nA\n\nsource 0.sh\n. 1.sh\n\n\nsource $(FILE1)\n. $(FILE2)\n\n"
  },
  {
    "path": "Units/parser-sh.r/sh-spaces-in-funcdef.d/expected.tags",
    "content": "func\tinput.sh\t/^func (                 \t)$/;\"\tf\nproc\tinput.sh\t/^function proc (  )$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/sh-spaces-in-funcdef.d/input.sh",
    "content": "func (                 \t)\n{\n    return 0\n}\n\nfunction proc (  )\n{\n    :\n}\n"
  },
  {
    "path": "Units/parser-sh.r/sh-spaces-in-funcdef.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/parser-sh.r/sh-statements.d/expected.tags",
    "content": "-starting-with-dash\tinput.sh\t/^function -starting-with-dash() {$/;\"\tf\n-starting-with-dash_2\tinput.sh\t/^  -starting-with-dash_2() {$/;\"\tf\n-starting-with-dash_inner\tinput.sh\t/^    -starting-with-dash_inner() baz$/;\"\tf\n_starting-with-underscore_inner\tinput.sh\t/^    _starting-with-underscore_inner() baz$/;\"\tf\nalias\tinput.sh\t/^mult1() echo 1; mult2() echo 2; mult3() { echo 1 }; alias alias=mult1$/;\"\ta\nbaz\tinput.sh\t/^function baz() {}$/;\"\tf\nbaz_2\tinput.sh\t/^function baz_2() {$/;\"\tf\nbaz_2_inner\tinput.sh\t/^  baz_2_inner() baz$/;\"\tf\nmult1\tinput.sh\t/^mult1() echo 1; mult2() echo 2; mult3() { echo 1 }; alias alias=mult1$/;\"\tf\nmult2\tinput.sh\t/^mult1() echo 1; mult2() echo 2; mult3() { echo 1 }; alias alias=mult1$/;\"\tf\nmult3\tinput.sh\t/^mult1() echo 1; mult2() echo 2; mult3() { echo 1 }; alias alias=mult1$/;\"\tf\nnoParen\tinput.sh\t/^function noParen {$/;\"\tf\nwith-dash\tinput.sh\t/^function with-dash() {$/;\"\tf\nwith-dash_2\tinput.sh\t/^  with-dash_2() {$/;\"\tf\nwith-dash_inner\tinput.sh\t/^    with-dash_inner() baz$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/sh-statements.d/input.sh",
    "content": "mult1() echo 1; mult2() echo 2; mult3() { echo 1 }; alias alias=mult1\n\nfunction baz() {}\nfunction baz_2() {\n  baz_2_inner() baz\n}\n\nfunction with-dash() {\n  with-dash_2() {\n    with-dash_inner() baz\n  }\n}\n\nfunction noParen {\n    :\n}\n\nfunction -starting-with-dash() {\n  -starting-with-dash_2() {\n    -starting-with-dash_inner() baz\n    _starting-with-underscore_inner() baz\n  }\n}\n"
  },
  {
    "path": "Units/parser-sh.r/simple.ksh.d/expected.tags",
    "content": "f1\tinput.ksh\t/^f1() {$/;\"\tf\nf2\tinput.ksh\t/^function f2 {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/simple.ksh.d/input.ksh",
    "content": "#!/bin/ksh\n\nf1() {\n}\n\nfunction f2 {\n}\n"
  },
  {
    "path": "Units/parser-sh.r/simple.sh.d/README",
    "content": "This is copied from Tests/simple.sh."
  },
  {
    "path": "Units/parser-sh.r/simple.sh.d/expected.tags",
    "content": "_a_b\tinput.sh\t/^function _a_b() {$/;\"\tf\nf1\tinput.sh\t/^f1() {$/;\"\tf\nf2\tinput.sh\t/^function f2() {$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/simple.sh.d/input.sh",
    "content": "#!/bin/sh\n\nf1() {\n}\n\nfunction f2() {\n}\n\nfunction _a_b() {\n}\n"
  },
  {
    "path": "Units/parser-sh.r/zsh-traced-function.d/expected.tags",
    "content": "f\tinput.zsh\t/^function -T f$/;\"\tf\n"
  },
  {
    "path": "Units/parser-sh.r/zsh-traced-function.d/input.zsh",
    "content": "function -T f\n{\n    return 0\n}\n"
  },
  {
    "path": "Units/parser-sinex.r/degraded_length.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-sinex.r/degraded_length.d/expected.tags",
    "content": "FILE/COMMENT\tinput.snx\t/^+FILE\\/COMMENT$/;\"\tb\tline:3\tend:6\nSITE/ID\tinput.snx\t/^+SITE\\/ID$/;\"\tb\tline:8\tend:15\nVERY_LONG_BLOCK_NAME_EXCEEDING_THE_NORMAL_EIGHTY_CHARACTER_LIMIT_WILL_BE_TRUNCA\tinput.snx\t/^+VERY_LONG_BLOCK_NAME_EXCEEDING_THE_NORMAL_EIGHTY_CHARACTER_LIMIT_WILL_BE_TRUNCATED$/;\"\tb\tline:25\tend:33\n"
  },
  {
    "path": "Units/parser-sinex.r/degraded_length.d/input.snx",
    "content": "%=SNX 2.01 IGN 16:122:00000 IGN 79:215:00000 19:001:00000 C 00036 2 X V\n*-------------------------------------------------------------------------------\n+FILE/COMMENT\n* One block with no name : must be omitted\n* One block with a name exceeding the SINEX format (80 chars) : truncated\n-FILE/COMMENT\n*-------------------------------------------------------------------------------\n+SITE/ID\n*CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_\n PERT  A 50133M001   Perth, Australia       115 53 06.9 -31 48 07.0    12.7\n TIDB  A 50103M108   Tidbinbilla, NSW, Aust 148 58 47.9 -35 23 57.1   665.3\n YAR1  A 50107M004   Mingenew, Australia    115 20 49.1 -29 02 47.5   241.3\n CEDU  A 50138M001   CEDU 50138M001         133 48 35.3 -31 51 59.9   144.7\n HOB2  A 50116M004   Hobart/Tasmania, Austr 147 26 19.4 -42 48 16.9    41.1\n-SITE/ID\n+\n*Code PT SOLN T Data_start__ Data_end____ Mean_epoch__\n PERT  A    1 C 94:004:00000 94:113:00000 94:058:43200\n TIDB  A    1 C 94:004:00000 96:177:86389 95:090:86394\n YAR1  A    1 C 94:004:00000 97:230:00000 95:300:00000\n PERT  A    2 C 94:117:00000 01:030:00000 97:256:00000\n CEDU  A    1 C 94:136:00000 95:277:00000 95:024:00000\n HOB2  A    1 C 94:187:00000 97:137:00000 95:345:00000\n-\n+VERY_LONG_BLOCK_NAME_EXCEEDING_THE_NORMAL_EIGHTY_CHARACTER_LIMIT_WILL_BE_TRUNCATED\n*INDEX TYPE__ CODE PT SOLN _REF_EPOCH__ UNIT S __ESTIMATED VALUE____ _STD_DEV___\n1        STAX PERT  A    1 10:001:00000  m   2 -.236868757866128E+07 0.74048E-03\n2        STAY PERT  A    1 10:001:00000  m   2 0.488131661461247E+07 0.91864E-03\n3        STAZ PERT  A    1 10:001:00000  m   2 -.334179548710761E+07 0.84688E-03\n4        VELX PERT  A    1 10:001:00000  m/y 2 -.472916775593191E-01 0.39163E-04\n5        VELY PERT  A    1 10:001:00000  m/y 2 0.822689567578196E-02 0.41751E-04\n6        VELZ PERT  A    1 10:001:00000  m/y 2 0.508006951054042E-01 0.44388E-04\n-VERY_LONG_BLOCK_NAME_EXCEEDING_THE_NORMAL_EIGHTY_CHARACTER_LIMIT_WILL_BE_TRUNCATED\n"
  },
  {
    "path": "Units/parser-sinex.r/degraded_missing_end.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-sinex.r/degraded_missing_end.d/expected.tags",
    "content": "FILE/COMMENT\tinput.snx\t/^+FILE\\/COMMENT$/;\"\tb\tline:3\tend:5\nSITE/ID\tinput.snx\t/^+SITE\\/ID$/;\"\tb\tline:7\tend:14\nSOLUTION/ESTIMATE\tinput.snx\t/^+SOLUTION\\/ESTIMATE$/;\"\tb\tline:23\tend:37\n"
  },
  {
    "path": "Units/parser-sinex.r/degraded_missing_end.d/input.snx",
    "content": "%=SNX 2.01 IGN 16:122:00000 IGN 79:215:00000 19:001:00000 C 00036 2 X V\n*-------------------------------------------------------------------------------\n+FILE/COMMENT\n* The end marker of the SOLUTION/EPOCHS block is missing : the block is ignored\n-FILE/COMMENT\n*-------------------------------------------------------------------------------\n+SITE/ID\n*CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_\n PERT  A 50133M001   Perth, Australia       115 53 06.9 -31 48 07.0    12.7\n TIDB  A 50103M108   Tidbinbilla, NSW, Aust 148 58 47.9 -35 23 57.1   665.3\n YAR1  A 50107M004   Mingenew, Australia    115 20 49.1 -29 02 47.5   241.3\n CEDU  A 50138M001   CEDU 50138M001         133 48 35.3 -31 51 59.9   144.7\n HOB2  A 50116M004   Hobart/Tasmania, Austr 147 26 19.4 -42 48 16.9    41.1\n-SITE/ID\n+SOLUTION/EPOCHS\n*Code PT SOLN T Data_start__ Data_end____ Mean_epoch__\n PERT  A    1 C 94:004:00000 94:113:00000 94:058:43200\n TIDB  A    1 C 94:004:00000 96:177:86389 95:090:86394\n YAR1  A    1 C 94:004:00000 97:230:00000 95:300:00000\n PERT  A    2 C 94:117:00000 01:030:00000 97:256:00000\n CEDU  A    1 C 94:136:00000 95:277:00000 95:024:00000\n HOB2  A    1 C 94:187:00000 97:137:00000 95:345:00000\n+SOLUTION/ESTIMATE\n*INDEX TYPE__ CODE PT SOLN _REF_EPOCH__ UNIT S __ESTIMATED VALUE____ _STD_DEV___\n1        STAX PERT  A    1 10:001:00000  m   2 -.236868757866128E+07 0.74048E-03\n2        STAY PERT  A    1 10:001:00000  m   2 0.488131661461247E+07 0.91864E-03\n3        STAZ PERT  A    1 10:001:00000  m   2 -.334179548710761E+07 0.84688E-03\n4        VELX PERT  A    1 10:001:00000  m/y 2 -.472916775593191E-01 0.39163E-04\n5        VELY PERT  A    1 10:001:00000  m/y 2 0.822689567578196E-02 0.41751E-04\n6        VELZ PERT  A    1 10:001:00000  m/y 2 0.508006951054042E-01 0.44388E-04\n7        STAX HOB2  A    1 10:001:00000  m   2 -.395007186683046E+07 0.68502E-03\n8        STAY HOB2  A    1 10:001:00000  m   2 0.252241528744047E+07 0.60906E-03\n9        STAZ HOB2  A    1 10:001:00000  m   2 -.431163782526727E+07 0.78320E-03\n10       VELX HOB2  A    1 10:001:00000  m/y 2 -.387112208023018E-01 0.40249E-04\n11       VELY HOB2  A    1 10:001:00000  m/y 2 0.792637786129052E-02 0.37662E-04\n12       VELZ HOB2  A    1 10:001:00000  m/y 2 0.412562272254610E-01 0.45803E-04\n-SOLUTION/ESTIMATE\n"
  },
  {
    "path": "Units/parser-sinex.r/degraded_missing_start.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-sinex.r/degraded_missing_start.d/expected.tags",
    "content": "FILE/COMMENT\tinput.snx\t/^+FILE\\/COMMENT$/;\"\tb\tline:3\tend:5\nSITE/ID\tinput.snx\t/^+SITE\\/ID$/;\"\tb\tline:7\tend:14\nSOLUTION/EPOCHS\tinput.snx\t/^+SOLUTION\\/EPOCHS$/;\"\tb\tline:15\tend:23\n"
  },
  {
    "path": "Units/parser-sinex.r/degraded_missing_start.d/input.snx",
    "content": "%=SNX 2.01 IGN 16:122:00000 IGN 79:215:00000 19:001:00000 C 00036 2 X V\n*-------------------------------------------------------------------------------\n+FILE/COMMENT\n* The marker of the SOLUTION/ESTIMATE block is missing : the block is ignored\n-FILE/COMMENT\n*-------------------------------------------------------------------------------\n+SITE/ID\n*CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_\n PERT  A 50133M001   Perth, Australia       115 53 06.9 -31 48 07.0    12.7\n TIDB  A 50103M108   Tidbinbilla, NSW, Aust 148 58 47.9 -35 23 57.1   665.3\n YAR1  A 50107M004   Mingenew, Australia    115 20 49.1 -29 02 47.5   241.3\n CEDU  A 50138M001   CEDU 50138M001         133 48 35.3 -31 51 59.9   144.7\n HOB2  A 50116M004   Hobart/Tasmania, Austr 147 26 19.4 -42 48 16.9    41.1\n-SITE/ID\n+SOLUTION/EPOCHS\n*Code PT SOLN T Data_start__ Data_end____ Mean_epoch__\n PERT  A    1 C 94:004:00000 94:113:00000 94:058:43200\n TIDB  A    1 C 94:004:00000 96:177:86389 95:090:86394\n YAR1  A    1 C 94:004:00000 97:230:00000 95:300:00000\n PERT  A    2 C 94:117:00000 01:030:00000 97:256:00000\n CEDU  A    1 C 94:136:00000 95:277:00000 95:024:00000\n HOB2  A    1 C 94:187:00000 97:137:00000 95:345:00000\n-SOLUTION/EPOCHS\n*INDEX TYPE__ CODE PT SOLN _REF_EPOCH__ UNIT S __ESTIMATED VALUE____ _STD_DEV___\n1        STAX PERT  A    1 10:001:00000  m   2 -.236868757866128E+07 0.74048E-03\n2        STAY PERT  A    1 10:001:00000  m   2 0.488131661461247E+07 0.91864E-03\n3        STAZ PERT  A    1 10:001:00000  m   2 -.334179548710761E+07 0.84688E-03\n4        VELX PERT  A    1 10:001:00000  m/y 2 -.472916775593191E-01 0.39163E-04\n5        VELY PERT  A    1 10:001:00000  m/y 2 0.822689567578196E-02 0.41751E-04\n6        VELZ PERT  A    1 10:001:00000  m/y 2 0.508006951054042E-01 0.44388E-04\n7        STAX HOB2  A    1 10:001:00000  m   2 -.395007186683046E+07 0.68502E-03\n8        STAY HOB2  A    1 10:001:00000  m   2 0.252241528744047E+07 0.60906E-03\n9        STAZ HOB2  A    1 10:001:00000  m   2 -.431163782526727E+07 0.78320E-03\n10       VELX HOB2  A    1 10:001:00000  m/y 2 -.387112208023018E-01 0.40249E-04\n11       VELY HOB2  A    1 10:001:00000  m/y 2 0.792637786129052E-02 0.37662E-04\n12       VELZ HOB2  A    1 10:001:00000  m/y 2 0.412562272254610E-01 0.45803E-04\n-SOLUTION/ESTIMATE\n"
  },
  {
    "path": "Units/parser-sinex.r/ok_4_blocks.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-sinex.r/ok_4_blocks.d/expected.tags",
    "content": "FILE/COMMENT\tinput.snx\t/^+FILE\\/COMMENT$/;\"\tb\tline:3\tend:5\nSITE/ID\tinput.snx\t/^+SITE\\/ID$/;\"\tb\tline:7\tend:14\nSOLUTION/EPOCHS\tinput.snx\t/^+SOLUTION\\/EPOCHS$/;\"\tb\tline:15\tend:23\nSOLUTION/ESTIMATE\tinput.snx\t/^+SOLUTION\\/ESTIMATE$/;\"\tb\tline:24\tend:40\n"
  },
  {
    "path": "Units/parser-sinex.r/ok_4_blocks.d/input.snx",
    "content": "%=SNX 2.01 IGN 16:122:00000 IGN 79:215:00000 19:001:00000 C 00036 2 X V\n*-------------------------------------------------------------------------------\n+FILE/COMMENT\n* File created by CATREF software (Z.Altamimi)\n-FILE/COMMENT\n*-------------------------------------------------------------------------------\n+SITE/ID\n*CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_\n PERT  A 50133M001   Perth, Australia       115 53 06.9 -31 48 07.0    12.7\n TIDB  A 50103M108   Tidbinbilla, NSW, Aust 148 58 47.9 -35 23 57.1   665.3\n YAR1  A 50107M004   Mingenew, Australia    115 20 49.1 -29 02 47.5   241.3\n CEDU  A 50138M001   CEDU 50138M001         133 48 35.3 -31 51 59.9   144.7\n HOB2  A 50116M004   Hobart/Tasmania, Austr 147 26 19.4 -42 48 16.9    41.1\n-SITE/ID\n+SOLUTION/EPOCHS\n*Code PT SOLN T Data_start__ Data_end____ Mean_epoch__\n PERT  A    1 C 94:004:00000 94:113:00000 94:058:43200\n TIDB  A    1 C 94:004:00000 96:177:86389 95:090:86394\n YAR1  A    1 C 94:004:00000 97:230:00000 95:300:00000\n PERT  A    2 C 94:117:00000 01:030:00000 97:256:00000\n CEDU  A    1 C 94:136:00000 95:277:00000 95:024:00000\n HOB2  A    1 C 94:187:00000 97:137:00000 95:345:00000\n-SOLUTION/EPOCHS\n+SOLUTION/ESTIMATE\n*INDEX TYPE__ CODE PT SOLN _REF_EPOCH__ UNIT S __ESTIMATED VALUE____ _STD_DEV___\n1        STAX PERT  A    1 10:001:00000  m   2 -.236868757866128E+07 0.74048E-03\n2        STAY PERT  A    1 10:001:00000  m   2 0.488131661461247E+07 0.91864E-03\n3        STAZ PERT  A    1 10:001:00000  m   2 -.334179548710761E+07 0.84688E-03\n4        VELX PERT  A    1 10:001:00000  m/y 2 -.472916775593191E-01 0.39163E-04\n5        VELY PERT  A    1 10:001:00000  m/y 2 0.822689567578196E-02 0.41751E-04\n6        VELZ PERT  A    1 10:001:00000  m/y 2 0.508006951054042E-01 0.44388E-04\n29       VELY CEDU  A    1 10:001:00000  m/y 2 0.172935957701062E-02 0.38085E-04\n30       VELZ CEDU  A    1 10:001:00000  m/y 2 0.504090658972641E-01 0.42917E-04\n31       STAX HOB2  A    1 10:001:00000  m   2 -.395007186683046E+07 0.68502E-03\n32       STAY HOB2  A    1 10:001:00000  m   2 0.252241528744047E+07 0.60906E-03\n33       STAZ HOB2  A    1 10:001:00000  m   2 -.431163782526727E+07 0.78320E-03\n34       VELX HOB2  A    1 10:001:00000  m/y 2 -.387112208023018E-01 0.40249E-04\n35       VELY HOB2  A    1 10:001:00000  m/y 2 0.792637786129052E-02 0.37662E-04\n36       VELZ HOB2  A    1 10:001:00000  m/y 2 0.412562272254610E-01 0.45803E-04\n-SOLUTION/ESTIMATE\n"
  },
  {
    "path": "Units/parser-sinex.r/trailing_spaces.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-sinex.r/trailing_spaces.d/expected.tags",
    "content": "FILE/REFERENCE\tinput.snx\t/^+FILE\\/REFERENCE                                                                 $/;\"\tb\tline:6\tend:13\nFILE/COMMENT\tinput.snx\t/^+FILE\\/COMMENT                                                                   $/;\"\tb\tline:15\tend:21\nINPUT/HISTORY\tinput.snx\t/^+INPUT\\/HISTORY$/;\"\tb\tline:23\tend:26\nSOLUTION/EPOCHS\tinput.snx\t/^+SOLUTION\\/EPOCHS$/;\"\tb\tline:41\tend:53\nSITE/ECCENTRICITY\tinput.snx\t/^+SITE\\/ECCENTRICITY                                                              $/;\"\tb\tline:55\tend:68\nMODEL/TIME_BIAS\tinput.snx\t/^+MODEL\\/TIME_BIAS                                                                $/;\"\tb\tline:70\tend:72\nMODEL/RANGE_BIAS\tinput.snx\t/^+MODEL\\/RANGE_BIAS                                                               $/;\"\tb\tline:74\tend:81\n"
  },
  {
    "path": "Units/parser-sinex.r/trailing_spaces.d/input.snx",
    "content": "%=SNX 2.00 PRD 24:327:64828 PRD 24:259:00858 24:265:86229 L 00192 0 E S        \n*-------------------------------------------------------------------------------\n*        1         2         3         4         5         6         7         8\n*2345678901234567890123456789012345678901234567890123456789012345678901234567890\n*-----------------------------------------------------------------------        \n+FILE/REFERENCE                                                                 \n DESCRIPTION        Producer Name                                               \n OUTPUT             BIAS                                                        \n CONTACT            producer@domain.com                                         \n SOFTWARE           MADEUP_NAME                                                 \n HARDWARE           Frontier II                                                 \n INPUT              LAGEOS 3 & ETALON 4 & SENTINEL-7                            \n-FILE/REFERENCE                                                                 \n*-----------------------------------------------------------------------        \n+FILE/COMMENT                                                                   \n*                                                                               \n* this file contains many lines with the maximum (80) line length because       \n* they are space padded.                                                        \n* This includes the start/end block lines...                                    \n*                                                                               \n-FILE/COMMENT\t                                                                \n*-------------------------------------------------------------------------------\n+INPUT/HISTORY\n +SNX 2.00 PRD 24:327:64828 PRD 24:259:00858 24:265:86229 L 00192 0 E S        \n =SNX 2.00 PRD 24:327:64828 PRD 24:259:00858 24:265:86229 L 00192 0 E S        \n-INPUT/HISTORY\n*-------------------------------------------------------------------------------\n+SITE/ID                                                                        \n*CODE PT __DOMES__ T _STATION DESCRIPTION__ APPROX_LON_ APPROX_LAT_ _APP_H_     \n 7090  A 50107M001 L Yarragadee MOBLAS-5    115 20 48.3 -29  2 47.3   242.0     \n 7105  A 40451M105 L Greenbelt  MOBLAS-2    283 10 20.3  39  1 14.2    19.9     \n 7110  A 40497M001 L Monument P MOBLAS-3    243 34 38.4  32 53 30.3  1839.8     \n 7124  A 92201M007 L Papeete    MOBLAS-8    210 23 37.6 -17 34 36.5    95.1     \n 7249  A 21601S004 L Beijing    BEIJ FIX    115 53 31.4  39 36 25.0    82.5     \n 7306  A 21797S001 L Tsukuba_SC TKBLAS      140  7 52.6  36  4  3.1    68.9     \n 7403  A 42202M003 L Arequipa   TLRS-3      288 30 25.4 -16 27 56.6  2489.7     \n 7501  A 30302M003 L Hartebeest MOBLAS-6     27 41 10.3 -25 53 22.9  1407.5     \n 7701  A 31336S001 L Izana      IZ1L        343 29 21.8  28 17 58.5  2430.4     \n 7825  A 50119S003 L Mount Stro STR2 FIX    149  0 35.6 -35 18 58.1   805.7     \n*-------------------------------------------                                    \n+SOLUTION/EPOCHS\n*CODE PT SOLN T _DATA_START_ __DATA_END__ _MEAN_EPOCH_                          \n 7090  A    1 L 24:259:00902 24:265:68157 24:262:33376                          \n 7105  A    1 L 24:260:13144 24:265:02544 24:263:54996                          \n 7110  A    1 L 24:262:07552 24:265:16588 24:263:68060                          \n 7124  A    1 L 24:262:64884 24:264:64832 24:263:52874                          \n 7249  A    1 L 24:264:54857 24:265:62974 24:265:37719                          \n 7306  A    1 L 24:261:35957 24:264:49928 24:262:85435                          \n 7403  A    1 L 24:259:07398 24:265:15429 24:263:14103                          \n 7501  A    1 L 24:263:63831 24:263:67703 24:263:65091                          \n 7701  A    1 L 24:259:73181 24:265:78073 24:262:23307                          \n 7825  A    1 L 24:259:00858 24:265:67728 24:262:08245                          \n-SOLUTION/EPOCHS                             \n*------------------------------                                                 \n+SITE/ECCENTRICITY                                                              \n*CODE PT SOLN T _DATA_START_ __DATA_END__ REF UP______ NORTH___ EAST____        \n 7090  A    1 L 76:122:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n 7105  A    1 L 05:244:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n 7306  A    1 L 22:174:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n 7396  A    1 L 19:152:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n 7701  A    1 L 21:172:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n 7825  A    1 L 04:001:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n 7840  A    1 L 83:001:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n 7841  A    1 L 01:001:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n 7845  A    1 L 97:001:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n 7941  A    1 L 00:001:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n 8834  A    1 L 90:244:00000 00:000:00000 XYZ   0.0000   0.0000   0.0000        \n-SITE/ECCENTRICITY                                                              \n*------------------------------                                                 \n+MODEL/TIME_BIAS                                                                \n*CODE PT SOLN T START_DATE__ END_DATE____ M __E-VALUE___ STD_DEV _E-RATE__ UNIT \n-MODEL/TIME_BIAS                                                                \n*------------------------------                                                 \n+MODEL/RANGE_BIAS                                                               \n*CODE PT SOLN T START_DATE__ END_DATE____ M __E-VALUE___ STD_DEV _E-RATE__ UNIT \n 1874 51  501 A 14:019:00000 00:000:00000 R        -16.8     0.7             mm \n 1874 52  501 A 14:019:00000 00:000:00000 R        -17.3     0.9             mm \n 1874 53  501 A 14:103:00000 00:000:00000 R        -12.8     1.5             mm \n 1874 54  501 A 14:103:00000 00:000:00000 R        -12.8     1.5             mm \n 7105 51  501 A 20:047:00000 00:000:00000 R         -5.1     0.4             mm \n-MODEL/RANGE_BIAS                                                               \n*---------------------------------------------------                            \n%ENDSNX\n"
  },
  {
    "path": "Units/parser-sql.r/3184782.sql.d/expected.tags",
    "content": "do_this_stuff\tinput.sql\t/^procedure do_this_stuff is begin$/;\"\tp\tpackage:p_test\nmyfn1\tinput.sql\t/^procedure myfn1 ($/;\"\tp\tpackage:p_test\nmyfn2\tinput.sql\t/^procedure myfn2 ($/;\"\tp\tpackage:p_test\np_test\tinput.sql\t/^create or replace package body p_test is$/;\"\tP\nprocess_this\tinput.sql\t/^procedure process_this ($/;\"\tp\tpackage:p_test\n"
  },
  {
    "path": "Units/parser-sql.r/3184782.sql.d/input.sql",
    "content": "create or replace package body p_test is\r\n\r\nprocedure do_this_stuff is begin\r\nif true then\r\n    for idx in z+1 .. myarr.last loop\r\n        if myarr.exists(idx) then\r\n            null;\r\n        end if;\r\n    end loop;\r\n\r\nelsif true then\r\n    for idx in myarr.first .. myarr.last loop\r\n        if myarr.exists(idx) then\r\n            null;\r\n        end if;\r\n    end loop;\r\nend if;\r\nend do_this_stuff;\r\n\r\nprocedure process_this (\r\n    p_flag in boolean\r\n) is\r\nbegin\r\n    null;\r\nend process_this;\r\n\r\nprocedure myfn1 (\r\n    p_str1 in varchar2,\r\n    p_str2 in varchar2\r\n) is begin\r\nprocess_this(false);\r\nend myfn1;\r\n\r\nprocedure myfn2 (\r\n    p_str1 in varchar2,\r\n    p_str2 in varchar2\r\n) is begin\r\nprocess_this(true);\r\nend myfn2;\r\n\r\nend p_test;\r\n"
  },
  {
    "path": "Units/parser-sql.r/bug1324663.sql.d/args.ctags",
    "content": "--excmd=pattern\n--fields=nks\n--kinds-SQL=cdfFlLPprstTvieURDVnxy\n"
  },
  {
    "path": "Units/parser-sql.r/bug1324663.sql.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-sql.r/bug1324663.sql.d/input.sql",
    "content": "-- The sql parser would go into an endless loop with the open but no closing comment.\r\n-- ctags -f - --format=2 --excmd=pattern --fields=nks  --sort=no  --sql-types=cdfFlLPprstTvieURDVnxy bug1324663.sql\r\n--\r\n'\\'/*'\r\n"
  },
  {
    "path": "Units/parser-sql.r/bug1428714.sql.d/args.ctags",
    "content": "--excmd=pattern\n--fields=nks\n--kinds-SQL=cdfFlLPprstTvieURDVnxy\n"
  },
  {
    "path": "Units/parser-sql.r/bug1428714.sql.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-sql.r/bug1428714.sql.d/input.sql",
    "content": "-- The sql parser would go into an endless loop with the open but no closing comment.\r\n-- ctags -f - --format=2 --excmd=pattern --fields=nks  --sort=no  --sql-types=cdfFlLPprstTvieURDVnxy bug1428714.sql\r\n--\r\n/*\r\n"
  },
  {
    "path": "Units/parser-sql.r/bug1570779.sql.d/args.ctags",
    "content": "--excmd=pattern\n--fields=nks\n--sort=no\n--kinds-SQL=cdfElLPprstTvieURDVnxy\n--extras=+q\n"
  },
  {
    "path": "Units/parser-sql.r/bug1570779.sql.d/expected.tags",
    "content": "employees\tinput.sql\t/^CREATE TABLE employees ($/;\"\tt\tline:8\nemployees.id\tinput.sql\t/^    id integer NOT NULL,$/;\"\tE\tline:9\ttable:employees\nid\tinput.sql\t/^    id integer NOT NULL,$/;\"\tE\tline:9\ttable:employees\nemployees.name\tinput.sql\t/^    name varchar(20),$/;\"\tE\tline:10\ttable:employees\nname\tinput.sql\t/^    name varchar(20),$/;\"\tE\tline:10\ttable:employees\nemployees.address\tinput.sql\t/^    address varchar(50),$/;\"\tE\tline:11\ttable:employees\naddress\tinput.sql\t/^    address varchar(50),$/;\"\tE\tline:11\ttable:employees\n"
  },
  {
    "path": "Units/parser-sql.r/bug1570779.sql.d/input.sql",
    "content": "-- This should find the \"address\" column when --sql-types=r is used\r\n-- ctags -f - --format=2 --excmd=pattern --fields=nks  --sort=no  --sql-types=cdfFlLPprstTvieURDVnxy bug1570779.sql\r\n-- employees       bug1570779.sql  /^CREATE TABLE employees ($/;\"  t       line:2\r\n-- employees.id    bug1570779.sql  /^    id integer NOT NULL,$/;\"  F       line:3\r\n-- employees.name  bug1570779.sql  /^    name varchar(20),$/;\"     F       line:4\r\n-- employees.address       bug1570779.sql  /^    address varchar(50),$/;\"  F   line:5\r\n\r\nCREATE TABLE employees (\r\n    id integer NOT NULL,\r\n    name varchar(20),\r\n    address varchar(50),\r\n    primary key (id)\r\n);\r\n\r\n"
  },
  {
    "path": "Units/parser-sql.r/bug1938565.sql.d/expected.tags",
    "content": "demo_pkg\tinput.sql\t/^CREATE OR REPLACE PACKAGE demo_pkg$/;\"\tP\nfunc1\tinput.sql\t/^FUNCTION func1( value in varchar ) RETURNS number IS$/;\"\tf\tpackage:demo_pkg\ttyperef:typename:number\nfunc2\tinput.sql\t/^FUNCTION func2( value in varchar ) RETURN number IS$/;\"\tf\tpackage:demo_pkg\ttyperef:typename:number\n"
  },
  {
    "path": "Units/parser-sql.r/bug1938565.sql.d/input.sql",
    "content": "CREATE OR REPLACE PACKAGE demo_pkg\nIS\n\nFUNCTION func1_proto( value in varchar ) RETURNS number;\nFUNCTION func2_proto( value in varchar ) RETURN number;\n\nFUNCTION func1( value in varchar ) RETURNS number IS\nBEGIN\n\tRETURN 1;\nEND func1;\n\nFUNCTION func2( value in varchar ) RETURN number IS\nBEGIN\n\tRETURN 2;\nEND func2;\n\nEND demo_pkg;\n/\n"
  },
  {
    "path": "Units/parser-sql.r/bug1944150.sql.d/expected.tags",
    "content": "tr_d_cash_trade_comment\tinput.sql\t/^CREATE TRIGGER [tr_d_cash_trade_comment] ON dbo.cash_trade_comment$/;\"\tT\ttable:cash_trade_comment\n"
  },
  {
    "path": "Units/parser-sql.r/bug1944150.sql.d/input.sql",
    "content": "CREATE TRIGGER [tr_d_cash_trade_comment] ON dbo.cash_trade_comment\r\nFOR DELETE\r\nAS\r\nBEGIN\r\nEND\r\nGO\r\n\r\n"
  },
  {
    "path": "Units/parser-sql.r/bug2961855.sql.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--kinds-SQL=+d\n"
  },
  {
    "path": "Units/parser-sql.r/bug2961855.sql.d/expected.tags",
    "content": "demo_pkg\tinput.sql\t/^create or replace package demo_pkg is$/;\"\tP\ndemo_pkg.test_var\tinput.sql\t/^test_var number;$/;\"\tv\tpackage:demo_pkg\ntest_var\tinput.sql\t/^test_var number;$/;\"\tv\tpackage:demo_pkg\ndemo_pkg.test_func\tinput.sql\t/^function test_func return varchar2;$/;\"\td\tpackage:demo_pkg\ntest_func\tinput.sql\t/^function test_func return varchar2;$/;\"\td\tpackage:demo_pkg\ndemo_pkg.more.test_func2\tinput.sql\t/^function more.test_func2 return varchar2;$/;\"\td\tfunction:demo_pkg.more\ntest_func2\tinput.sql\t/^function more.test_func2 return varchar2;$/;\"\td\tfunction:demo_pkg.more\ndemo_pkg.test_func3\tinput.sql\t/^function test_func3 return varchar2;$/;\"\td\tpackage:demo_pkg\ntest_func3\tinput.sql\t/^function test_func3 return varchar2;$/;\"\td\tpackage:demo_pkg\n"
  },
  {
    "path": "Units/parser-sql.r/bug2961855.sql.d/input.sql",
    "content": "// When it should be demo_pkg.test_func and demo_pkg.test_var\n// Tags are created for:\n//     packages    \n//          demo_pkg\n//     variables\n//          test_var\n//\n// But no tags for the function.\n//\n//\ncreate or replace package demo_pkg is\ntest_var number;\n\nfunction test_func return varchar2;\nfunction more.test_func2 return varchar2;\nfunction test_func3 return varchar2;\n\nend demo_pkg;\n\n"
  },
  {
    "path": "Units/parser-sql.r/bug629115.sql.d/expected.tags",
    "content": "variable1\tinput.sql\t/^   variable1 CLOB;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-sql.r/bug629115.sql.d/input.sql",
    "content": "/***/\nDECLARE\n   variable1 CLOB;\nBEGIN\nEND;\n"
  },
  {
    "path": "Units/parser-sql.r/bug722501.sql.d/args.ctags",
    "content": "--kinds-SQL=+l\n"
  },
  {
    "path": "Units/parser-sql.r/bug722501.sql.d/expected.tags",
    "content": "foo\tinput.sql\t/^CREATE OR REPLACE PROCEDURE foo$/;\"\tp\nl_foo\tinput.sql\t/^\t    l_foo NUMBER;$/;\"\tl\tprocedure:foo\n"
  },
  {
    "path": "Units/parser-sql.r/bug722501.sql.d/input.sql",
    "content": "/*\nThe PL/SQL parser (v1.6) does not parse a standalone\nprocedure or function (i.e., not part of a package) when\nthe SQL is in the form\n*/\nCREATE OR REPLACE PROCEDURE foo\nAS /* or IS*/\n    BEGIN\n\tDECLARE\n\t    l_foo NUMBER;\n\tBEGIN\n\t    l_foo := 1;\n\tEND;\n    END; \n/*\nWhen this is processed the only tag reported is\nProcedure foo. If you remove the line with AS, the\nvariable l_foo is seen, but then the procedure will not\ncompile in Oracle.\n\nFunctions seem to have similar problems in that the\nparser will not see inside the function, but removing the\nIS or AS does not remedy the problem for a function.\n*/\n"
  },
  {
    "path": "Units/parser-sql.r/bug823000.sql.d/expected.tags",
    "content": "TEST\tinput.sql\t/^CREATE OR REPLACE PACKAGE TEST IS$/;\"\tP\nTestFunc1\tinput.sql\t/^PROCEDURE TestFunc1$/;\"\tp\tpackage:TEST\nTestFunc2\tinput.sql\t/^PROCEDURE TestFunc2$/;\"\tp\tpackage:TEST\n"
  },
  {
    "path": "Units/parser-sql.r/bug823000.sql.d/input.sql",
    "content": "/*\nBugs item #823000, was opened at 2003-10-13 21:56\nMessage generated for change (Tracker Item Submitted) made by Item Submitter\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=823000&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Jozsef Nagy (brutal)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: PL/SQL functions and procedures\n\nInitial Comment:\nI've tried to use ctags (version 5.5.2) to navigate\nPL/SQL source codes in vim but jumping to\nfunction/procedure definitions worked not properly. I\nfigured out that the problem was that I've defined\nthese functions/procedures in multiline format, for\nexample:\n\ntest.pkb:\n*/\nCREATE OR REPLACE PACKAGE TEST IS\n\nPROCEDURE TestFunc1\n(\n  arg1  IN NUMBER,\n  arg2  IN NUMBER\n)\nIS\nBEGIN\n  NULL;\nEND TestFunc1;\n\nPROCEDURE TestFunc2\n(\n  arg1  IN NUMBER,\n  arg2  IN NUMBER\n)\nIS\nBEGIN\n  NULL;\nEND TestFunc2;\n\nEND TEST;\n/\n/*\nctags creates a regexp type pattern for my\nfunctions/procedures but unfortunately the pattern was\n/^IS$/ for each function/procedure, that's why the\njumping method worked really crappy. (see the output of\nctags 5.5.2 on this example code below)\n\nctags -f - --language-force=sql test.pkb\nTEST    test.pkb        /^CREATE OR REPLACE PACKAGE\nTEST IS$/;\" P\nTestFunc1       test.pkb        /^IS$/;\"        p\nTestFunc2       test.pkb        /^IS$/;\"        p\n\nI've looked into the ctags source code and I saw that\nin parseSubProgram() in sql.c called makeSqlTag() only\nwhen KEYWORD_is reached. I have modified this function\n so that makeSqlTag() is called immediately after a\nfunction/procedure keyword and name is read (I have\nattached the output of diff sql.c.5.5.2 sql.c). I don't\nknow much of ctags internals so I am not sure if this\nis the best solution but it worked for me. (see the\noutput of my modified ctags below)\n\nctags -f - --language-force=sql test.pkb\nTEST    test.pkb        /^CREATE OR REPLACE PACKAGE\nTEST IS$/;\" P\nTestFunc1       test.pkb        /^PROCEDURE\nTestFunc1$/;\"       p\nTestFunc2       test.pkb        /^PROCEDURE\nTestFunc2$/;\"       p\n*/\n"
  },
  {
    "path": "Units/parser-sql.r/comment-as-identifier.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/comment-as-identifier.d/expected.tags",
    "content": "comment\tinput.sql\t/^create table api.comment ($/;\"\tt\nid\tinput.sql\t/^  id serial primary key,$/;\"\tE\ttable:comment\nbody\tinput.sql\t/^  body character varying(250) not null,$/;\"\tE\ttable:comment\ncreated_at\tinput.sql\t/^  created_at timestamptz default now(),$/;\"\tE\ttable:comment\nupdated_at\tinput.sql\t/^  updated_at timestamptz default now()$/;\"\tE\ttable:comment\n"
  },
  {
    "path": "Units/parser-sql.r/comment-as-identifier.d/input.sql",
    "content": "-- Taken a comment posted by @akemrir in #2215\ncreate table api.comment (\n  id serial primary key,\n  body character varying(250) not null,\n  created_at timestamptz default now(),\n  updated_at timestamptz default now()\n);\n"
  },
  {
    "path": "Units/parser-sql.r/countall.sql.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/countall.sql.d/expected.tags",
    "content": "t_c1_tname\tinput.sql\t/^  t_c1_tname      user_tables.table_name%TYPE;$/;\"\tv\nt_command\tinput.sql\t/^  t_command       varchar2(200);$/;\"\tv\nt_cid\tinput.sql\t/^  t_cid           integer;$/;\"\tv\nt_total_records\tinput.sql\t/^  t_total_records number(10);$/;\"\tv\nstat\tinput.sql\t/^  stat            integer;$/;\"\tv\nrow_count\tinput.sql\t/^  row_count       integer;$/;\"\tv\nt_limit\tinput.sql\t/^  t_limit         integer := 0;    -- Only show tables with more rows$/;\"\tv\nc1\tinput.sql\t/^  cursor c1 is select table_name from user_tables order by table_name;$/;\"\tc\n"
  },
  {
    "path": "Units/parser-sql.r/countall.sql.d/input.sql",
    "content": "rem -----------------------------------------------------------------------\nrem URL:        http://www.orafaq.com/scripts/plsql/countall.txt\nrem Filename:   countall.sql\nrem Purpose:    Count the number of rows for ALL tables in current schema\nrem             using PL/SQL\nrem Date:       15-Apr-2000\nrem Author:     Eberhardt, Roberto (Bolton) (reberhar@husky.ca)\nrem -----------------------------------------------------------------------\n\nset serveroutput on size 1000000\n\nDECLARE\n  t_c1_tname      user_tables.table_name%TYPE;\n  t_command       varchar2(200);\n  t_cid           integer;\n  t_total_records number(10);\n  stat            integer;\n  row_count       integer;\n  t_limit         integer := 0;    -- Only show tables with more rows\n  cursor c1 is select table_name from user_tables order by table_name;\nBEGIN\n  t_limit := 0;\n  open c1;\n  loop\n        fetch c1 into t_c1_tname;\n        exit when c1%NOTFOUND;\n        t_command := 'SELECT COUNT(0) FROM '||t_c1_tname;\n        t_cid := DBMS_SQL.OPEN_CURSOR;\n        DBMS_SQL.PARSE(t_cid,t_command,dbms_sql.native);\n        DBMS_SQL.DEFINE_COLUMN(t_cid,1,t_total_records);\n        stat := DBMS_SQL.EXECUTE(t_cid);\n        row_count := DBMS_SQL.FETCH_ROWS(t_cid);\n        DBMS_SQL.COLUMN_VALUE(t_cid,1,t_total_records);\n        if t_total_records > t_limit then\n                DBMS_OUTPUT.PUT_LINE(rpad(t_c1_tname,55,' ')||\n                        to_char(t_total_records,'99999999')||' record(s)');\n\n        end if;\n        DBMS_SQL.CLOSE_CURSOR(t_cid);\n  end loop;\n  close c1;\nEND;\n/\n"
  },
  {
    "path": "Units/parser-sql.r/db-trig.sql.d/args.ctags",
    "content": "--kinds-SQL=+l\n"
  },
  {
    "path": "Units/parser-sql.r/db-trig.sql.d/expected.tags",
    "content": "evr_update_trigger_katello_rpms\tinput-0.sql\t/^CREATE TRIGGER evr_update_trigger_katello_rpms$/;\"\tT\ttable:katello_rpms\nflag\tinput.sql\t/^        flag number := 0;$/;\"\tl\ttrigger:restrict_login\nrestrict_login\tinput.sql\t/^create or replace trigger restrict_login$/;\"\tT\ttable:database\nstartup_db\tinput.sql\t/^CREATE OR REPLACE TRIGGER startup_db$/;\"\tT\ttable:database\n"
  },
  {
    "path": "Units/parser-sql.r/db-trig.sql.d/input-0.sql",
    "content": "CREATE TRIGGER evr_update_trigger_katello_rpms\n  BEFORE UPDATE OF epoch, version, release\n  ON katello_rpms\n  FOR EACH ROW\n  WHEN (\n    OLD.epoch IS DISTINCT FROM NEW.epoch OR\n    OLD.version IS DISTINCT FROM NEW.version OR\n    OLD.release IS DISTINCT FROM NEW.release\n  )\n  EXECUTE PROCEDURE evr_trigger();\n  -- Taken from katello-4.11.0.12/db/triggers/evr_update_trigger_katello_rpms_v01.sql\n"
  },
  {
    "path": "Units/parser-sql.r/db-trig.sql.d/input.sql",
    "content": "rem -----------------------------------------------------------------------\nrem URL:        http://www.orafaq.com/scripts/plsql/db-trig.txt\nrem Filename:   db-trig.sql\nrem Purpose:    Demonstrate database triggers (available from Oracle 8i)\nrem             Need DBA or CREATE ANY TRIGGER privs\nrem Date:       28-Aug-1998\nrem Author:     Frank Naude (frank@ibi.co.za)\nrem -----------------------------------------------------------------------\n\ncreate or replace trigger restrict_login\n        after logon       on database\ndeclare\n        flag number := 0;\nbegin\n        select 1 into flag from sys.v_$session where program like '%sqlplus%';\n        if flag = 1 then\n                raise_application_error(-20000, 'No access from sqlplus');\n        end if;\nend;\n/\nshow errors\n\n\nCREATE OR REPLACE TRIGGER startup_db\nafter startup on database\nbegin\n    dbms_shared_pool.keep ('SYS.STANDARD','P');\n    dbms_shared_pool.keep ('SYS.DBMS_STANDARD','P');\nend;\n/\nshow errors\n"
  },
  {
    "path": "Units/parser-sql.r/funcions.d/args.ctags",
    "content": "--sort=no\n--fields=+S\n--extras=+g\n--kinds-SQL=+r\n"
  },
  {
    "path": "Units/parser-sql.r/funcions.d/expected.tags",
    "content": "evr_array_item\tinput.sql\t/^create type evr_array_item as ($/;\"\tr\nn\tinput.sql\t/^  n       NUMERIC,$/;\"\tE\trecord:evr_array_item\ns\tinput.sql\t/^  s       TEXT$/;\"\tE\trecord:evr_array_item\nevr_t\tinput.sql\t/^create type evr_t as ($/;\"\tr\nepoch\tinput.sql\t/^  epoch INT,$/;\"\tE\trecord:evr_t\nversion\tinput.sql\t/^  version evr_array_item[],$/;\"\tE\trecord:evr_t\nrelease\tinput.sql\t/^  release evr_array_item[]$/;\"\tE\trecord:evr_t\nevr_trigger\tinput.sql\t/^CREATE FUNCTION evr_trigger() RETURNS trigger AS $\\$$/;\"\tf\ttyperef:typename:trigger\tsignature:()\nempty\tinput.sql\t/^create or replace FUNCTION empty(t TEXT)$/;\"\tf\ttyperef:typename:BOOLEAN\tsignature:(t TEXT)\nisalpha\tinput.sql\t/^create or replace FUNCTION isalpha(ch CHAR)$/;\"\tf\ttyperef:typename:BOOLEAN\tsignature:(ch CHAR)\nisalphanum\tinput.sql\t/^create or replace FUNCTION isalphanum(ch CHAR)$/;\"\tf\ttyperef:typename:BOOLEAN\tsignature:(ch CHAR)\nisdigit\tinput.sql\t/^create or replace function isdigit(ch CHAR)$/;\"\tf\ttyperef:typename:BOOLEAN\tsignature:(ch CHAR)\nrpmver_array\tinput.sql\t/^create or replace FUNCTION rpmver_array (string1 IN VARCHAR)$/;\"\tf\ttyperef:typename:evr_array_item[]\tsignature:(string1 IN VARCHAR)\nstr1\tinput.sql\t/^\t\tstr1 VARCHAR := string1;$/;\"\tv\ndigits\tinput.sql\t/^\t\tdigits VARCHAR(10) := '0123456789';$/;\"\tv\nlc_alpha\tinput.sql\t/^\t\tlc_alpha VARCHAR(27) := 'abcdefghijklmnopqrstuvwxyz';$/;\"\tv\nuc_alpha\tinput.sql\t/^\t\tuc_alpha VARCHAR(27) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';$/;\"\tv\nalpha\tinput.sql\t/^\t\talpha VARCHAR(54) := lc_alpha || uc_alpha;$/;\"\tv\none\tinput.sql\t/^\t\tone VARCHAR;$/;\"\tv\nisnum\tinput.sql\t/^\t\tisnum BOOLEAN;$/;\"\tv\nver_array\tinput.sql\t/^\t\tver_array evr_array_item[] := ARRAY[]::evr_array_item[];$/;\"\tv\nsegment_loop\tinput.sql\t/^\t\t<<segment_loop>>$/;\"\tL\ndfunc0\tinput-0.sql\t/^create function dfunc0(a text DEFAULT '->''Hello', b text DEFAULT 'World''') returns text as $\\$$/;\"\tf\ttyperef:typename:text\tsignature:(a text DEFAULT '->''Hello', b text DEFAULT 'World''')\ndfunc1\tinput-0.sql\t/^create function dfunc1(r numeric = 20.39, p numeric DEFAULT 99.88) returns numeric as $\\$$/;\"\tf\ttyperef:typename:numeric\tsignature:(r numeric = 20.39, p numeric DEFAULT 99.88)\ndfunc2\tinput-0.sql\t/^create function dfunc2(anyelement = 'World'::text) returns text as $\\$$/;\"\tf\ttyperef:typename:text\tsignature:(anyelement = 'World'::text)\ndfunc3\tinput-0.sql\t/^create function dfunc3(a variadic int[]) returns int as$/;\"\tf\ttyperef:typename:int\tsignature:(a variadic int[])\n"
  },
  {
    "path": "Units/parser-sql.r/funcions.d/input-0.sql",
    "content": "-- Derived from postgresql-13.16/src/test/regress/sql/polymorphism.sql\n\ncreate function dfunc0(a text DEFAULT '->''Hello', b text DEFAULT 'World''') returns text as $$\n  select $1 || ', ' || $2;\n$$ language sql;\ndrop function dfunc0(text, text);\n\ncreate function dfunc1(r numeric = 20.39, p numeric DEFAULT 99.88) returns numeric as $$\n  select $1 + $2;\n$$ language sql;\ndrop function dfunc1(numeric, numeric);\n\ncreate function dfunc2(anyelement = 'World'::text) returns text as $$\n  select 'Hello, ' || $1::text;\n$$ language sql;\ndrop function dfunc2(anyelement);\n\ncreate function dfunc3(a variadic int[]) returns int as\n$$ select array_upper($1, 1) $$ language sql;\n"
  },
  {
    "path": "Units/parser-sql.r/funcions.d/input.sql",
    "content": "-- Taken from postgresql-evr-0.0.2/evr--0.0.2.sql\n\\echo Use \"CREATE EXTENSION evr\" to load this file. \\quit\n\ncreate type evr_array_item as (\n  n       NUMERIC,\n  s       TEXT\n);\n\ncreate type evr_t as (\n  epoch INT,\n  version evr_array_item[],\n  release evr_array_item[]\n);\n\nCREATE FUNCTION evr_trigger() RETURNS trigger AS $$\n  BEGIN\n    NEW.evr = (select ROW(coalesce(NEW.epoch::numeric,0),\n                          rpmver_array(coalesce(NEW.version,'empty'))::evr_array_item[],\n                          rpmver_array(coalesce(NEW.release,'empty'))::evr_array_item[])::evr_t);\n    RETURN NEW;\n  END;\n$$ language 'plpgsql';\n\ncreate or replace FUNCTION empty(t TEXT)\n\tRETURNS BOOLEAN as $$\n\tBEGIN\n\t\treturn t ~ '^[[:space:]]*$';\n\tEND;\n$$ language 'plpgsql';\n\ncreate or replace FUNCTION isalpha(ch CHAR)\n  RETURNS BOOLEAN as $$\n  BEGIN\n    if ascii(ch) between ascii('a') and ascii('z') or\n        ascii(ch) between ascii('A') and ascii('Z')\n    then\n      return TRUE;\n    end if;\n    return FALSE;\n  END;\n$$ language 'plpgsql';\n\ncreate or replace FUNCTION isalphanum(ch CHAR)\n\tRETURNS BOOLEAN as $$\n\tBEGIN\n\t\tif ascii(ch) between ascii('a') and ascii('z') or\n\t\t\tascii(ch) between ascii('A') and ascii('Z') or\n\t\t\tascii(ch) between ascii('0') and ascii('9')\n\t\tthen\n\t\t\treturn TRUE;\n\t\tend if;\n\t\treturn FALSE;\n\tEND;\n$$ language 'plpgsql';\n\ncreate or replace function isdigit(ch CHAR)\n\tRETURNS BOOLEAN as $$\n\tBEGIN\n\t  if ascii(ch) between ascii('0') and ascii('9')\n\t  then\n\t\treturn TRUE;\n\t  end if;\n\t  return FALSE;\n\tEND ;\n$$ language 'plpgsql';\n\ncreate or replace FUNCTION rpmver_array (string1 IN VARCHAR)\n\tRETURNS evr_array_item[] as $$\n\tdeclare\n\t\tstr1 VARCHAR := string1;\n\t\tdigits VARCHAR(10) := '0123456789';\n\t\tlc_alpha VARCHAR(27) := 'abcdefghijklmnopqrstuvwxyz';\n\t\tuc_alpha VARCHAR(27) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\t\talpha VARCHAR(54) := lc_alpha || uc_alpha;\n\t\tone VARCHAR;\n\t\tisnum BOOLEAN;\n\t\tver_array evr_array_item[] := ARRAY[]::evr_array_item[];\n\tBEGIN\n\t\tif str1 is NULL\n\t\tthen\n\t\t\tRAISE EXCEPTION 'VALUE_ERROR.';\n\t\tend if;\n\n\t\tone := str1;\n\t\t<<segment_loop>>\n\t\twhile one <> ''\n\t\tloop\n\t\t\tdeclare\n\t\t\t\tsegm1 VARCHAR;\n\t\t\t\tsegm1_n NUMERIC := 0;\n\t\t\tbegin\n\t\t\t\t-- Throw out all non-alphanum characters\n\t\t\t\twhile one <> '' and not isalphanum(one)\n\t\t\t\tloop\n\t\t\t\t\tone := substr(one, 2);\n\t\t\t\tend loop;\n\t\t\t\tstr1 := one;\n\t\t\t\tif str1 <> '' and isdigit(str1)\n\t\t\t\tthen\n\t\t\t\t\tstr1 := ltrim(str1, digits);\n\t\t\t\t\tisnum := true;\n\t\t\t\telse\n\t\t\t\t\tstr1 := ltrim(str1, alpha);\n\t\t\t\t\tisnum := false;\n\t\t\t\tend if;\n\t\t\t\tif str1 <> ''\n\t\t\t\tthen segm1 := substr(one, 1, length(one) - length(str1));\n\t\t\t\telse segm1 := one;\n\t\t\t\tend if;\n\n\t\t\t\tif segm1 = '' then return ver_array; end if; /* arbitrary */\n\t\t\t\tif isnum\n\t\t\t\tthen\n\t\t\t\t\tsegm1 := ltrim(segm1, '0');\n\t\t\t\t\tif segm1 <> '' then segm1_n := segm1::numeric; end if;\n\t\t\t\t\tsegm1 := NULL;\n\t\t\t\telse\n\t\t\t\tend if;\n\t\t\t\tver_array := array_append(ver_array, (segm1_n, segm1)::evr_array_item);\n\t\t\t\tone := str1;\n\t\t\tend;\n\t\tend loop segment_loop;\n\n\t\treturn ver_array;\n\tEND ;\n$$ language 'plpgsql';\n"
  },
  {
    "path": "Units/parser-sql.r/hex2dec.sql.d/expected.tags",
    "content": "hex2dec\tinput.sql\t/^CREATE OR REPLACE FUNCTION hex2dec (hexnum in char) RETURN number IS$/;\"\tf\ttyperef:typename:number\nnum2hex\tinput.sql\t/^CREATE OR REPLACE FUNCTION num2hex (N in number) RETURN varchar2 IS$/;\"\tf\ttyperef:typename:varchar2\n"
  },
  {
    "path": "Units/parser-sql.r/hex2dec.sql.d/input.sql",
    "content": "rem -----------------------------------------------------------------------\nrem URL:        http://www.orafaq.com/scripts/plsql/hex2dec.txt\nrem Filename:   hex2dec.sql\nrem Purpose:    Functions to convert Hex to Decimal and vice versa\nrem Author:     Mark Malakanov, Feb-1999 + Anonymous\nrem -----------------------------------------------------------------------\n\nCREATE OR REPLACE FUNCTION hex2dec (hexnum in char) RETURN number IS\n  i                 number;\n  digits            number;\n  result            number := 0;\n  current_digit     char(1);\n  current_digit_dec number;\nBEGIN\n  digits := length(hexnum);\n  for i in 1..digits loop\n     current_digit := SUBSTR(hexnum, i, 1);\n     if current_digit in ('A','B','C','D','E','F') then\n        current_digit_dec := ascii(current_digit) - ascii('A') + 10;\n     else\n        current_digit_dec := to_number(current_digit);\n     end if;\n     result := (result * 16) + current_digit_dec;\n  end loop;\n  return result;\nEND hex2dec;\n/\nshow errors\n\nCREATE OR REPLACE FUNCTION num2hex (N in number) RETURN varchar2 IS\n  H  varchar2(64) :='';\n  N2 integer      := N;\nBEGIN\n  loop\n     select rawtohex(chr(N2))||H\n     into   H\n     from   dual;\n\n     N2 := trunc(N2 / 256);\n     exit when N2=0;\n  end loop;\n  return H;\nEND num2hex;\n/\nshow errors\n\n-- Examples:\nselect hex2dec('FF') from dual;\n\nselect num2hex(10) from dual;\n"
  },
  {
    "path": "Units/parser-sql.r/is-as-funcname.d/README",
    "content": "This test case is originally made for testing the change proposed in\n#2268. However, it doesn't verify the behavior affected by the change.\n\nIn Postgresql, \"is\" can be used as a function name.  In many of the\nother SQL DB implementations, \"is\" is a reserved word, Therefore, \"is\"\ncannot be used as a function name.\n\nWhen SQL parser of ctags reads a SQL input file, it doesn't care\nwhether an identifier appearing at the position where a function name\nis expected is a reserved word or not. Therefore, the change proposed\nin #2268 has no impact on the way to capture function name.\n\n"
  },
  {
    "path": "Units/parser-sql.r/is-as-funcname.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/is-as-funcname.d/expected.tags",
    "content": "is\tinput.sql\t/^CREATE FUNCTION is() RETURNS integer AS $\\$$/;\"\tf\ttyperef:typename:integer\n"
  },
  {
    "path": "Units/parser-sql.r/is-as-funcname.d/input.sql",
    "content": "CREATE FUNCTION is() RETURNS integer AS $$\nSELECT 1 as result;\n$$ LANGUAGE SQL;\n"
  },
  {
    "path": "Units/parser-sql.r/labels.sql.r/expected.tags",
    "content": "my_label\tinput.sql\t/^    <<my_label>>$/;\"\tL\tprocedure:outer_procedure\nouter_procedure\tinput.sql\t/^PROCEDURE outer_procedure IS$/;\"\tp\n"
  },
  {
    "path": "Units/parser-sql.r/labels.sql.r/input.sql",
    "content": "PROCEDURE outer_procedure IS\nBEGIN\n    <<my_label>>\n    DECLARE\n\tx INTEGER;\n    BEGIN\n    END my_label;\nEND\n"
  },
  {
    "path": "Units/parser-sql.r/partial.d/input.sql",
    "content": "type T is record\n"
  },
  {
    "path": "Units/parser-sql.r/random.sql.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/random.sql.d/expected.tags",
    "content": "random\tinput.sql\t/^create or replace package random$/;\"\tP\nrandom\tinput.sql\t/^create or replace package body random$/;\"\tP\nmultiplier\tinput.sql\t/^   multiplier   constant number := 22695477;$/;\"\tv\tpackage:random\nincrement\tinput.sql\t/^   increment    constant number := 1;$/;\"\tv\tpackage:random\nSeed\tinput.sql\t/^   Seed         number          := 1;$/;\"\tv\tpackage:random\nsmaller\tinput.sql\t/^   function  smaller(x IN number, y IN number) return number is$/;\"\tf\tpackage:random\ttyperef:typename:number\nrand_string\tinput.sql\t/^   function rand_string(ssiz IN number) return varchar2 is$/;\"\tf\tpackage:random\ttyperef:typename:varchar2\nsrand\tinput.sql\t/^   procedure srand(new_seed in number) is$/;\"\tp\tpackage:random\nrand\tinput.sql\t/^   function rand return number is$/;\"\tf\tpackage:random\ttyperef:typename:number\nget_rand\tinput.sql\t/^   procedure get_rand(r OUT number) is$/;\"\tp\tpackage:random\nrand_max\tinput.sql\t/^   function rand_max(n IN number) return number is$/;\"\tf\tpackage:random\ttyperef:typename:number\nget_rand_max\tinput.sql\t/^   procedure get_rand_max(r OUT number, n IN number) is$/;\"\tp\tpackage:random\n"
  },
  {
    "path": "Units/parser-sql.r/random.sql.d/input.sql",
    "content": "/*\n------------------------------------------------------------------------------\nURL:       http://www.orafaq.com/scripts/plsql/random.txt\nFilename:  random.txt\nPurpose:   Random number/ string generator package\nAuthor:    Unknown\nOriginal:  http://www.orafaq.org/scripts/sql/random.txt\nEdits:\n 19990908 Phil Rand <prand@spu.edu> Added functions rand_string(), smaller().\n------------------------------------------------------------------------------\n*/\n\ncreate or replace package random\nis\n   procedure srand(new_seed in number);\n   procedure get_rand(r OUT number);\n   procedure get_rand_max(r OUT number, n IN number);\n   function  rand return number;\n   function  rand_max(n IN number) return number;\n   function  rand_string(ssiz IN number) return varchar2;\n   function  smaller(x IN number, y IN number) return number;\n   pragma restrict_references(rand, WNDS);\n   pragma restrict_references(rand_max, WNDS);\n   pragma restrict_references(random, WNDS, RNPS);\n   pragma restrict_references(rand_string, WNDS);\n   pragma restrict_references(smaller, WNDS);\nend random;\n/\n\ncreate or replace package body random\nis\n   multiplier   constant number := 22695477;\n   increment    constant number := 1;\n   \"2^32\"       constant number := 2 ** 32;\n   \"2^16\"       constant number := 2 ** 16;\n   \"0x7fff\"     constant number := 32767;\n   Seed         number          := 1;\n\n   function  smaller(x IN number, y IN number) return number is\n   begin\n\tif x <= y then\n\t    return x;\n\telse\n\t    return y;\n\tend if;\n   end smaller;\n\n   function rand_string(ssiz IN number) return varchar2 is\n     i      number;\n     m      number;\n     c      char;\n     result varchar2(2000) := '';\n   begin\n\tm := smaller(ssiz,2000);\n\tfor i in 1..m loop\n\t    c := substr('abcdefghijklmnopqrstuvwxyz0123456789',rand_max(36),1);\n\t    result := result || c;\n        end loop;\n\treturn result;\n   end rand_string;\n\n   procedure srand(new_seed in number) is\n   begin\n     Seed := new_seed;\n   end srand;\n\n   function rand return number is\n   begin\n     Seed := mod(multiplier * Seed + increment, \"2^32\");\n     return bitand(Seed/\"2^16\", \"0x7fff\");\n   end rand;\n\n   procedure get_rand(r OUT number) is\n   begin\n     r := rand;\n   end get_rand;\n\n   function rand_max(n IN number) return number is\n   begin\n     return mod(rand, n) + 1;\n   end rand_max;\n\n   procedure get_rand_max(r OUT number, n IN number) is\n   begin\n     r := rand_max(n);\n   end get_rand_max;\n\nbegin\n   select userenv('SESSIONID')\n   into   Seed\n   from   dual;\nend random;\n/\n\n-- Some examples:\nselect random.rand_max(10) from dual;\nselect random.rand_max(10) from dual;\nselect random.rand_string(20) from dual;\nselect random.rand_string(20) from dual;\n\n"
  },
  {
    "path": "Units/parser-sql.r/readlob.sql.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/readlob.sql.d/expected.tags",
    "content": "lob_table\tinput.sql\t/^CREATE TABLE lob_table  ($/;\"\tt\nid\tinput.sql\t/^        id      INTEGER,$/;\"\tE\ttable:lob_table\nb_lob\tinput.sql\t/^        b_lob   BLOB,$/;\"\tE\ttable:lob_table\nc_lob\tinput.sql\t/^        c_lob   CLOB,$/;\"\tE\ttable:lob_table\nb_file\tinput.sql\t/^        b_file  BFILE );$/;\"\tE\ttable:lob_table\nclob_locator\tinput.sql\t/^   clob_locator CLOB;$/;\"\tv\ncharbuf\tinput.sql\t/^   charbuf      VARCHAR2(20);$/;\"\tv\nread_offset\tinput.sql\t/^   read_offset  INTEGER;$/;\"\tv\nread_amount\tinput.sql\t/^   read_amount  INTEGER;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-sql.r/readlob.sql.d/input.sql",
    "content": "rem -----------------------------------------------------------------------\nrem URL:        http://www.orafaq.com/scripts/plsql/readlob.txt\nrem Filename:   readlob.sql\nrem Purpose:    Fetch LOB column values piece-wise from PL/SQL\nrem Date:       12-Jun-2000\nrem Author:     Frank Naude (frank@ibi.co.za)\nrem -----------------------------------------------------------------------\n\nset serveroutput on\n\nDROP TABLE lob_table;                  -- Create table to hols LOBs\nCREATE TABLE lob_table  (\n        id      INTEGER,\n        b_lob   BLOB,\n        c_lob   CLOB,\n        b_file  BFILE );\n\nINSERT INTO lob_table                  -- Create sample record\n\tVALUES (1, EMPTY_BLOB(), 'abcde', NULL);\n\nDECLARE\n   clob_locator CLOB;\n   charbuf      VARCHAR2(20);\n   read_offset  INTEGER;\n   read_amount  INTEGER;\nBEGIN\n   -- First we need to get the lob locator\n   SELECT c_lob INTO clob_locator FROM lob_table WHERE id = 1;\n\n   DBMS_OUTPUT.PUT_LINE('CLOB Size: ' ||\n                       DBMS_LOB.GETLENGTH(clob_locator));\n\n   -- Read LOB field contents\n   read_offset := 1;\n   read_amount := 20;\n   dbms_lob.read(clob_locator, read_amount, read_offset, charbuf);\n   dbms_output.put_line('CLOB Value: ' || charbuf);\nEND;\n/\n"
  },
  {
    "path": "Units/parser-sql.r/readlong.sql.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/readlong.sql.d/expected.tags",
    "content": "longtable\tinput.sql\t/^create table longtable (longcol long) tablespace TOOLS;$/;\"\tt\nlongcol\tinput.sql\t/^create table longtable (longcol long) tablespace TOOLS;$/;\"\tE\ttable:longtable\ncur1\tinput.sql\t/^  cur1       PLS_INTEGER         := DBMS_SQL.OPEN_CURSOR;;$/;\"\tv\nrc\tinput.sql\t/^  rc         NUMBER;$/;\"\tv\nlong_piece\tinput.sql\t/^  long_piece VARCHAR2(256);$/;\"\tv\npiece_len\tinput.sql\t/^  piece_len  INTEGER             := 0;$/;\"\tv\nlong_tab\tinput.sql\t/^  long_tab   DBMS_SQL.VARCHAR2S;$/;\"\tv\nlong_len\tinput.sql\t/^  long_len   INTEGER             := 0;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-sql.r/readlong.sql.d/input.sql",
    "content": "rem -----------------------------------------------------------------------\nrem URL:        http://www.orafaq.com/scripts/plsql/readlong.txt\nrem Filename:   readlong.sql\nrem Purpose:    Fetch Long column values piece-wise from PL/SQL\nrem Date:       12-Jan-1999\nrem Author:     Frank Naude (frank@ibi.co.za)\nrem -----------------------------------------------------------------------\n\nset serveroutput on\n\n-- Create test table\ndrop table longtable;\ncreate table longtable (longcol long) tablespace TOOLS;\ninsert into longtable values ( rpad('x', 257, 'QWERTY') );\n\nDECLARE\n  cur1       PLS_INTEGER         := DBMS_SQL.OPEN_CURSOR;;\n  rc         NUMBER;\n  long_piece VARCHAR2(256);\n  piece_len  INTEGER             := 0;\n  long_tab   DBMS_SQL.VARCHAR2S;\n  long_len   INTEGER             := 0;\nBEGIN\n  DBMS_SQL.PARSE(cur1, 'select longcol from longtable', DBMS_SQL.NATIVE);\n  DBMS_SQL.DEFINE_COLUMN_LONG(cur1, 1);\n  rc := DBMS_SQL.EXECUTE(cur1);\n  rc := DBMS_SQL.FETCH_ROWS(cur1);                       -- Get one row\n\n  -- Loop until all pieces of the long column are processed\n  LOOP\n     DBMS_SQL.COLUMN_VALUE_LONG(cur1, 1, 256, long_len, long_piece, piece_len);\n     EXIT WHEN piece_len = 0;\n     DBMS_OUTPUT.PUT_LINE('Long piece len='|| piece_len);\n\n     long_tab( NVL(long_tab.LAST, 0)+1 ) := long_piece;  -- Add piece to table\n     long_len := long_len + piece_len;\n  END LOOP;\n  DBMS_SQL.CLOSE_CURSOR(cur1);\n  DBMS_OUTPUT.PUT_LINE('Total long col fetched, len='|| long_len);\nEND;\n/\n"
  },
  {
    "path": "Units/parser-sql.r/refcurs.sql.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/refcurs.sql.d/expected.tags",
    "content": "types\tinput.sql\t/^CREATE OR REPLACE PACKAGE types AS$/;\"\tP\ncursortyp\tinput.sql\t/^   TYPE cursortyp is REF CURSOR;   -- use weak form$/;\"\tc\tpackage:types\ntest_ref_cursor\tinput.sql\t/^CREATE OR REPLACE PACKAGE test_ref_cursor AS$/;\"\tP\ntest_ref_cursor\tinput.sql\t/^CREATE OR REPLACE PACKAGE BODY test_ref_cursor AS$/;\"\tP\nmain\tinput.sql\t/^  PROCEDURE main IS$/;\"\tp\tpackage:test_ref_cursor\nget_cursor_ref\tinput.sql\t/^  FUNCTION get_cursor_ref(typ NUMBER) RETURN types.cursortyp IS$/;\"\tf\tpackage:test_ref_cursor\ttyperef:typename:types.cursortyp\nprocess_cursor\tinput.sql\t/^  PROCEDURE process_cursor(cur types.cursortyp) IS$/;\"\tp\tpackage:test_ref_cursor\n"
  },
  {
    "path": "Units/parser-sql.r/refcurs.sql.d/input.sql",
    "content": "rem -----------------------------------------------------------------------\nrem URL:        http://www.orafaq.com/scripts/plsql/refcurs.txt\nrem Filename:   refcurs.sql\nrem Purpose:    Pass result sets (REF CURSOR) between procedures and \nrem\t\tfunctions\nrem Date:       15-Jun-2001\nrem Author:     Frank Naude (frank@ibi.co.za)\nrem -----------------------------------------------------------------------\n\nset serveroutput on\n\n-- Define TYPES package separately to be available to all programming\n-- environments...\nCREATE OR REPLACE PACKAGE types AS\n   TYPE cursortyp is REF CURSOR;   -- use weak form\nEND;\n/\n\n-- Create test package to demonstrate passing result sets...\nCREATE OR REPLACE PACKAGE test_ref_cursor AS\n   PROCEDURE main;\n   FUNCTION  get_cursor_ref(typ NUMBER) RETURN types.cursortyp;\n   PROCEDURE process_cursor(cur types.cursortyp);\nEND;\n/\nshow errors\n\n\nCREATE OR REPLACE PACKAGE BODY test_ref_cursor AS\n\n  -- Main program entry point\n  PROCEDURE main IS\n  BEGIN\n    process_cursor( get_cursor_ref(1) );\n    process_cursor( get_cursor_ref(2) );\n  END;\n\n  -- Get and return a CURSOR REF/ Result Set\n  FUNCTION get_cursor_ref(typ NUMBER) RETURN types.cursortyp IS\n    cur  types.cursortyp;\n  BEGIN\n    if typ = 1 THEN\n      OPEN cur FOR SELECT * FROM emp  WHERE ROWNUM < 5;\n    ELSE\n      OPEN cur FOR SELECT * FROM dept WHERE ROWNUM < 5;\n    END IF;\n    RETURN cur;\n  END;\n\n  -- Process rows for an EMP or DEPT cursor\n  PROCEDURE process_cursor(cur types.cursortyp) IS\n    empRec  emp%ROWTYPE;\n    deptRec dept%ROWTYPE;\n  BEGIN\n    LOOP\n      FETCH cur INTO empRec;    -- Maybe it was an EMP cursor, try to fetch...\n      EXIT WHEN cur%NOTFOUND;\n      dbms_output.put_line('EMP ROW: '||empRec.ename);\n    END LOOP;\n  EXCEPTION\n    WHEN ROWTYPE_MISMATCH THEN  -- OK, so it was't EMP, let's try DEPT.\n       LOOP\n         FETCH cur INTO deptRec;\n         EXIT WHEN cur%NOTFOUND;\n         dbms_output.put_line('DEPT ROW: '||deptRec.dname);\n       END LOOP;\n  END;\n\nEND;\n/\nshow errors\n\n\nEXEC test_ref_cursor.main;\n\n"
  },
  {
    "path": "Units/parser-sql.r/sharp-comment.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/sharp-comment.d/expected.tags",
    "content": "qrtz_job_details\tinput.sql\t/^CREATE TABLE qrtz_job_details$/;\"\tt\nJOB_NAME\tinput.sql\t/^JOB_NAME VARCHAR(200) NOT NULL,$/;\"\tE\ttable:qrtz_job_details\nJOB_GROUP\tinput.sql\t/^JOB_GROUP VARCHAR(200) NOT NULL,$/;\"\tE\ttable:qrtz_job_details\nDESCRIPTION\tinput.sql\t/^DESCRIPTION VARCHAR(250) NULL,$/;\"\tE\ttable:qrtz_job_details\nJOB_CLASS_NAME\tinput.sql\t/^JOB_CLASS_NAME VARCHAR(250) NOT NULL,$/;\"\tE\ttable:qrtz_job_details\nIS_DURABLE\tinput.sql\t/^IS_DURABLE BOOLEAN NOT NULL,$/;\"\tE\ttable:qrtz_job_details\nIS_VOLATILE\tinput.sql\t/^IS_VOLATILE BOOLEAN NOT NULL,$/;\"\tE\ttable:qrtz_job_details\nIS_STATEFUL\tinput.sql\t/^IS_STATEFUL BOOLEAN NOT NULL,$/;\"\tE\ttable:qrtz_job_details\nREQUESTS_RECOVERY\tinput.sql\t/^REQUESTS_RECOVERY BOOLEAN NOT NULL,$/;\"\tE\ttable:qrtz_job_details\nJOB_DATA\tinput.sql\t/^JOB_DATA BINARY NULL,$/;\"\tE\ttable:qrtz_job_details\n"
  },
  {
    "path": "Units/parser-sql.r/sharp-comment.d/input.sql",
    "content": "# Taken from candlepin-0.9.54.7/code/schema/quartz/tables_hsqldb.sql\n# ------------------------------------------------------------------\n#\n# In your Quartz properties file, you'll need to set \n# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.HSQLDBDelegate\n#\n\nDROP TABLE qrtz_locks IF EXISTS;\nDROP TABLE qrtz_scheduler_state IF EXISTS;\nDROP TABLE qrtz_fired_triggers IF EXISTS;\nDROP TABLE qrtz_paused_trigger_grps IF EXISTS;\nDROP TABLE qrtz_calendars IF EXISTS;\nDROP TABLE qrtz_trigger_listeners IF EXISTS;\nDROP TABLE qrtz_blob_triggers IF EXISTS;\nDROP TABLE qrtz_cron_triggers IF EXISTS;\nDROP TABLE qrtz_simple_triggers IF EXISTS;\nDROP TABLE qrtz_triggers IF EXISTS;\nDROP TABLE qrtz_job_listeners IF EXISTS;\nDROP TABLE qrtz_job_details IF EXISTS;\n\nCREATE TABLE qrtz_job_details\n(\nJOB_NAME VARCHAR(200) NOT NULL,\nJOB_GROUP VARCHAR(200) NOT NULL,\nDESCRIPTION VARCHAR(250) NULL,\nJOB_CLASS_NAME VARCHAR(250) NOT NULL,\nIS_DURABLE BOOLEAN NOT NULL,\nIS_VOLATILE BOOLEAN NOT NULL,\nIS_STATEFUL BOOLEAN NOT NULL,\nREQUESTS_RECOVERY BOOLEAN NOT NULL,\nJOB_DATA BINARY NULL,\nPRIMARY KEY (JOB_NAME,JOB_GROUP)\n);\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-database.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-database.d/expected.tags",
    "content": "lusiadas\tinput.sql\t/^CREATE DATABASE lusiadas;$/;\"\tb\nsales\tinput.sql\t/^CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace;$/;\"\tb\nmusic\tinput.sql\t/^CREATE DATABASE music$/;\"\tb\nmusic2\tinput.sql\t/^CREATE DATABASE music2$/;\"\tb\ntest\tinput.sql\t/^create database 'test' || replace(current_date, '-', '');$/;\"\tb\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-database.d/input.sql",
    "content": "-- Taken from https://www.postgresql.org/docs/current/sql-createdatabase.html\nCREATE DATABASE lusiadas;\nCREATE DATABASE sales OWNER salesapp TABLESPACE salesspace;\nCREATE DATABASE music\n    LOCALE 'sv_SE.utf8'\n    TEMPLATE template0;\nCREATE DATABASE music2\n    LOCALE 'sv_SE.iso885915'\n    ENCODING LATIN9\n    TEMPLATE template0;\n\n-- Taken from http://www.hplsql.org/create-database\ncreate database 'test' || replace(current_date, '-', '');\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-extension.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-extension.d/expected.tags",
    "content": "foo\tinput.sql\t/^CREATE TABLE public.foo ($/;\"\tt\nid\tinput.sql\t/^    id bigserial PRIMARY KEY,$/;\"\tE\ttable:foo\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-extension.d/input.sql",
    "content": "-- Taken from #2580 submitted by @nobrick\nCREATE EXTENSION IF NOT EXISTS \"pgcrypto\" WITH SCHEMA public;\n\nCREATE TABLE public.foo (\n    id bigserial PRIMARY KEY,\n);\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-schema.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-schema.d/expected.tags",
    "content": "myschema\tinput.sql\t/^CREATE SCHEMA myschema;$/;\"\tS\njoe\tinput.sql\t/^CREATE SCHEMA AUTHORIZATION joe;$/;\"\tS\ntest\tinput.sql\t/^CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe;$/;\"\tS\nhollywood\tinput.sql\t/^CREATE SCHEMA hollywood$/;\"\tS\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-schema.d/input.sql",
    "content": "-- https://www.postgresql.org/docs/current/sql-createschema.html\nCREATE SCHEMA myschema;\nCREATE SCHEMA AUTHORIZATION joe;\nCREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe;\nCREATE SCHEMA hollywood\n    CREATE TABLE films (title text, release date, awards text[])\n    CREATE VIEW winners AS\n        SELECT title, release FROM films WHERE awards IS NOT NULL;\n\n-- TODO: films and winners should be tagged.\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-as.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-as.d/expected.tags",
    "content": "foo\tinput.sql\t/^CREATE TABLE foo($/;\"\tt\ncol1\tinput.sql\t/^    col1 text$/;\"\tE\ttable:foo\nbar\tinput.sql\t/^CREATE TABLE bar AS$/;\"\tt\ncol2\tinput.sql\t/^SELECT 1 AS col2;$/;\"\tE\ttable:bar\ntable_with_subselect\tinput.sql\t/^CREATE TABLE table_with_subselect AS$/;\"\tt\nfoo\tinput.sql\t/^SELECT foo,$/;\"\tE\ttable:table_with_subselect\nbar\tinput.sql\t/^    2 AS bar$/;\"\tE\ttable:table_with_subselect\ntable_with_join\tinput.sql\t/^CREATE TABLE table_with_join AS$/;\"\tt\nfoo\tinput.sql\t/^SELECT foo,$/;\"\tE\ttable:table_with_join\nbar\tinput.sql\t/^    a.bar,$/;\"\tE\ttable:table_with_join\nb_bar\tinput.sql\t/^    b.bar AS b_bar$/;\"\tE\ttable:table_with_join\ntable_with_weird_expressions\tinput.sql\t/^CREATE TABLE table_with_weird_expressions AS$/;\"\tt\ncol1\tinput.sql\t/^SELECT 'string AS not_a_colname' AS col1,$/;\"\tE\ttable:table_with_weird_expressions\ncol3\tinput.sql\t/^    'two lines' AS col3,$/;\"\tE\ttable:table_with_weird_expressions\ncol4\tinput.sql\t/^    1 + (SELECT 1 AS inner_colname) AS col4$/;\"\tE\ttable:table_with_weird_expressions\ntable_with_subselect2\tinput.sql\t/^CREATE TABLE table_with_subselect2 AS$/;\"\tt\nfoo\tinput.sql\t/^SELECT foo,$/;\"\tE\ttable:table_with_subselect2\nbar\tinput.sql\t/^    2 AS bar$/;\"\tE\ttable:table_with_subselect2\ntmp_table0\tinput.sql\t/^CREATE TABLE tmp_table0 AS$/;\"\tt\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-as.d/input.sql",
    "content": "--\n-- Taken from #1658 submitted by @karlb\n--\nCREATE TABLE foo(\n    col1 text\n);\n\nCREATE TABLE bar AS\nSELECT 1 AS col2;\n\n--\n-- @karlb shows more complicated ones in #1733\n--\n\n-- has columns foo, bar\nCREATE TABLE table_with_subselect AS\nSELECT foo,\n    2 AS bar\nFROM (\n        SELECT 1 AS foo,\n               2 AS not_a_column\n    ) subsel;\n\n-- has columns foo, bar, b_bar\nCREATE TABLE table_with_join AS\nSELECT foo,\n    a.bar,\n    b.bar AS b_bar\nFROM table_with_subselect a\n    JOIN table_with_subselect b USING (foo);\n\n-- has columns col1, col3, col4\nCREATE TABLE table_with_weird_expressions AS\nSELECT 'string AS not_a_colname' AS col1,\n    'unknown colname; depends on db',\n    'string that goes over '\n    'two lines' AS col3,\n    1 + (SELECT 1 AS inner_colname) AS col4\nFROM (SELECT 1 AS foo) AS not_a_column;\n\n-- has columns foo, bar\nCREATE TABLE table_with_subselect2 AS\nSELECT foo,\n    2 AS bar\nFROM (\n        SELECT 1 AS foo\n    ) subsel;\n\n-- has columns nothing\nCREATE TABLE tmp_table0 AS\nSELECT tmp5 + tmp6 FROM tmp_table1;\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-extra-select.b/README",
    "content": "I'm not sure whether b should be captured once or twice.\n\nMasatake\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-extra-select.b/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-extra-select.b/expected.tags",
    "content": "test\tinput.sql\t/^CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,$/;\"\tt\na\tinput.sql\t/^CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,$/;\"\tE\ttable:test\nb\tinput.sql\t/^CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,$/;\"\tE\ttable:test\nb\tinput.sql\t/^       \t\t      ENGINE=MyISAM SELECT b,c FROM test2;$/;\"\tE\ttable:test\nc\tinput.sql\t/^       \t\t      ENGINE=MyISAM SELECT b,c FROM test2;$/;\"\tE\ttable:test\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-extra-select.b/input.sql",
    "content": "-- Taken from https://dev.mysql.com/doc/refman/5.7/en/create-table-select.html\n\n-- test, a, b, c\nCREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,\n\t\tPRIMARY KEY (a), KEY(b))\n\t\tENGINE=MyISAM SELECT b,c FROM test2;\n\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-if-not-exists.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-if-not-exists.d/expected.tags",
    "content": "test\tinput.sql\t/^CREATE TABLE IF NOT EXISTS test ($/;\"\tt\nid\tinput.sql\t/^    id     INTEGER NOT NULL PRIMARY KEY,$/;\"\tE\ttable:test\nmytext\tinput.sql\t/^    mytext TEXT    NOT NULL$/;\"\tE\ttable:test\nanother_test\tinput.sql\t/^CREATE TABLE another_test ($/;\"\tt\nid\tinput.sql\t/^    id    INTEGER NOT NULL PRIMARY KEY,$/;\"\tE\ttable:another_test\nmynum\tinput.sql\t/^    mynum INTEGER$/;\"\tE\ttable:another_test\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-if-not-exists.d/input.sql",
    "content": "-- Taken from github #2958 submitted by @LawrenceJGD\nCREATE TABLE IF NOT EXISTS test (\n    id     INTEGER NOT NULL PRIMARY KEY,\n    mytext TEXT    NOT NULL\n);\n\nCREATE TABLE another_test (\n    id    INTEGER NOT NULL PRIMARY KEY,\n    mynum INTEGER\n);\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-select.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-select.d/expected.tags",
    "content": "bar\tinput.sql\t/^CREATE TABLE bar (m INT) SELECT n FROM foo;$/;\"\tt\nm\tinput.sql\t/^CREATE TABLE bar (m INT) SELECT n FROM foo;$/;\"\tE\ttable:bar\nn\tinput.sql\t/^CREATE TABLE bar (m INT) SELECT n FROM foo;$/;\"\tE\ttable:bar\nbar\tinput.sql\t/^CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;$/;\"\tt\nn\tinput.sql\t/^CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;$/;\"\tE\ttable:bar\nartists_and_works\tinput.sql\t/^CREATE TABLE artists_and_works$/;\"\tt\nname\tinput.sql\t/^  SELECT artist.name, COUNT(work.artist_id) AS number_of_works$/;\"\tE\ttable:artists_and_works\nnumber_of_works\tinput.sql\t/^  SELECT artist.name, COUNT(work.artist_id) AS number_of_works$/;\"\tE\ttable:artists_and_works\nfoo\tinput.sql\t/^CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;$/;\"\tt\na\tinput.sql\t/^CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;$/;\"\tE\ttable:foo\na\tinput.sql\t/^CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;$/;\"\tE\ttable:foo\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-table-select.d/input.sql",
    "content": "-- Taken from https://dev.mysql.com/doc/refman/5.7/en/create-table-select.html\n\n-- bar, m, n\nCREATE TABLE bar (m INT) SELECT n FROM foo;\n\n-- bar, n\nCREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;\n\n-- artists_and_works, name, number_of_works,\nCREATE TABLE artists_and_works\n  SELECT artist.name, COUNT(work.artist_id) AS number_of_works\n  FROM artist LEFT JOIN work ON artist.id = work.artist_id\n  GROUP BY artist.id;\n\n-- foo, a, a\nCREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-view-if-not-exists.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-view-if-not-exists.d/expected.tags",
    "content": "messages_data\tinput.sql\t/^CREATE VIEW IF NOT EXISTS messages_data AS$/;\"\tV\n"
  },
  {
    "path": "Units/parser-sql.r/sql-create-view-if-not-exists.d/input.sql",
    "content": "-- Taken from leapp-0.15.1/res/schema/audit-layout.sql\n\nCREATE VIEW IF NOT EXISTS messages_data AS\n  SELECT\n    message.id        AS id,\n    message.context   AS context,\n    message.stamp     AS stamp,\n    message.topic     AS topic,\n    message.type      AS type,\n    data_source.actor AS actor,\n    data_source.phase AS phase,\n    msg_data.hash     AS message_hash,\n    msg_data.data     AS message_data,\n    host.hostname     AS hostname\n  FROM\n    message\n  JOIN\n    data_source              ON data_source.id            = message.data_source_id,\n    message_data AS msg_data ON message.message_data_hash = msg_data.hash,\n    host                     ON host.id                   = data_source.host_id\n;\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-ccflags.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-ccflags.d/expected.tags",
    "content": "UW_Flag\tinput.sql\t/^ALTER SESSION SET PLSQL_CCFlags = 'UW_Flag:1, Some_Flag:2, PLSQL_CCFlags:42';$/;\"\tC\nSome_Flag\tinput.sql\t/^ALTER SESSION SET PLSQL_CCFlags = 'UW_Flag:1, Some_Flag:2, PLSQL_CCFlags:42';$/;\"\tC\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-ccflags.d/input.sql",
    "content": "ALTER SESSION SET PLSQL_CCFlags = 'UW_Flag:1, Some_Flag:2, PLSQL_CCFlags:42';\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-inquiry-directive.d/README",
    "content": "This test case is taken from https://github.com/universal-ctags/ctags/issues/3006,\nan issue reported by @bagl.\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-inquiry-directive.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--kinds-SQL=+d\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-inquiry-directive.d/expected.tags",
    "content": "demo_pkg\tinput.sql\t/^create or replace package body demo_pkg is$/;\"\tP\ndemo_pkg.test_var\tinput.sql\t/^test_var varchar2(64) := $$PLSQL_UNIT;$/;\"\tv\tpackage:demo_pkg\ntest_var\tinput.sql\t/^test_var varchar2(64) := $$PLSQL_UNIT;$/;\"\tv\tpackage:demo_pkg\ndemo_pkg.test_func\tinput.sql\t/^function test_func return varchar2$/;\"\tf\tpackage:demo_pkg\ttyperef:typename:varchar2\ntest_func\tinput.sql\t/^function test_func return varchar2$/;\"\tf\tpackage:demo_pkg\ttyperef:typename:varchar2\ndemo_pkg1\tinput-1.sql\t/^create or replace package body demo_pkg1 is$/;\"\tP\ndemo_pkg1.test_var1\tinput-1.sql\t/^test_var1 varchar2(64) := $$PLSQL_UNIT_OWNER;$/;\"\tv\tpackage:demo_pkg1\ntest_var1\tinput-1.sql\t/^test_var1 varchar2(64) := $$PLSQL_UNIT_OWNER;$/;\"\tv\tpackage:demo_pkg1\ndemo_pkg1.test_func1\tinput-1.sql\t/^function test_func1 return varchar2$/;\"\tf\tpackage:demo_pkg1\ttyperef:typename:varchar2\ntest_func1\tinput-1.sql\t/^function test_func1 return varchar2$/;\"\tf\tpackage:demo_pkg1\ttyperef:typename:varchar2\nSome_Flag\tinput-2.sql\t/^PLSQL_CCFlags = 'Some_Flag:1, PLSQL_CCFlags:99'$/;\"\tC\nfoo\tinput-2.sql\t/^CREATE TABLE foo($/;\"\tt\nfoo.col\tinput-2.sql\t/^    col text$/;\"\tE\ttable:foo\ncol\tinput-2.sql\t/^    col text$/;\"\tE\ttable:foo\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-inquiry-directive.d/input-1.sql",
    "content": "-- Derrived from from https://github.com/universal-ctags/ctags/issues/3006\n-- submitted by bagl\ncreate or replace package body demo_pkg1 is\n\ntest_var1 varchar2(64) := $$PLSQL_UNIT_OWNER;\n\nfunction test_func1 return varchar2\nas\nbegin\n    return test_var1;\nend;\n\nend demo_pkg1;\n\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-inquiry-directive.d/input-2.sql",
    "content": "ALTER SESSION SET\nPLSQL_CCFlags = 'Some_Flag:1, PLSQL_CCFlags:99'\n/\nBEGIN\n  DBMS_OUTPUT.PUT_LINE($$Some_Flag);\nEND;\n/\n\nCREATE TABLE foo(\n    col text\n);\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-inquiry-directive.d/input.sql",
    "content": "-- Taken from https://github.com/universal-ctags/ctags/issues/3006\n-- submitted by bagl\n// Fails to create tags after PLSQL inquiry directive is used\n// https://docs.oracle.com/en/database/oracle/oracle-database/18/lnpls/plsql-language-fundamentals.html#GUID-E918087C-D5A8-4CEE-841B-5333DE6D4C15\n//\n// 'parseDollarQuote' causing troubles?\n//\ncreate or replace package body demo_pkg is\n\ntest_var varchar2(64) := $$PLSQL_UNIT;\n\nfunction test_func return varchar2\nas\nbegin\n    return test_var;\nend;\n\nend demo_pkg;\n\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-selection-directive.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--kinds-SQL=+d\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-selection-directive.d/expected.tags",
    "content": "demo_pkg\tinput.sql\t/^create or replace package body demo_pkg is$/;\"\tP\ndemo_pkg.test_func1\tinput.sql\t/^function test_func1 return INTEGER$/;\"\tf\tpackage:demo_pkg\ttyperef:typename:INTEGER\ntest_func1\tinput.sql\t/^function test_func1 return INTEGER$/;\"\tf\tpackage:demo_pkg\ttyperef:typename:INTEGER\ndemo_pkg.test_func2\tinput.sql\t/^function test_func2 return INTEGER$/;\"\tf\tpackage:demo_pkg\ttyperef:typename:INTEGER\ntest_func2\tinput.sql\t/^function test_func2 return INTEGER$/;\"\tf\tpackage:demo_pkg\ttyperef:typename:INTEGER\ndemo_pkg.test_func5\tinput.sql\t/^function test_func5 return INTEGER$/;\"\tf\tpackage:demo_pkg\ttyperef:typename:INTEGER\ntest_func5\tinput.sql\t/^function test_func5 return INTEGER$/;\"\tf\tpackage:demo_pkg\ttyperef:typename:INTEGER\n"
  },
  {
    "path": "Units/parser-sql.r/sql-plsql-selection-directive.d/input.sql",
    "content": "create or replace package body demo_pkg is\n\nfunction test_func1 return INTEGER\nas\nbegin\n    return 1;\nend;\n\n$IF $$MY_VERSION_CODE > 3 $THEN\n\nfunction test_func2 return INTEGER\nas\nbegin\n    return 3;\nend;\n\n$ELSIF $$MY_VERSION_CODE > 5 $THEN\n\nfunction test_func3 return INTEGER\nas\nbegin\n    return 5;\nend;\n\n$ELSE\n\nfunction test_func4 return INTEGER\nas\nbegin\n    return 7;\nend;\n\n$END\n\nfunction test_func5 return INTEGER\nas\nbegin\n    return 9;\nend;\n\nend demo_pkg;\n\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_dollar_quote.d/expected.tags",
    "content": "my_func\tinput.sql\t/^CREATE OR REPLACE FUNCTION my_func()$/;\"\tf\ttyperef:typename:void\nmy_view\tinput.sql\t/^CREATE OR REPLACE VIEW my_view AS$/;\"\tV\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_dollar_quote.d/input.sql",
    "content": "-- Taken from #1235\nCREATE OR REPLACE FUNCTION my_func()\nRETURNS void\nAS $$\n    SELECT 1\n$$ LANGUAGE sql IMMUTABLE;\n\nCREATE CAST (type_a AS type_b)\n    WITH FUNCTION type_conversion_function(type_a)\n    AS IMPLICIT;\n\nCREATE OR REPLACE VIEW my_view AS\nSELECT 1;\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_dollar_quote_complicated.d/expected.tags",
    "content": "my_func\tinput.sql\t/^CREATE OR REPLACE FUNCTION my_func()$/;\"\tf\ttyperef:typename:void\nmy_view\tinput.sql\t/^CREATE OR REPLACE VIEW my_view AS$/;\"\tV\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_dollar_quote_complicated.d/input.sql",
    "content": "-- Taken from #1235\nCREATE OR REPLACE FUNCTION my_func()\nRETURNS void\nAS $abc$\n   SELECT 1\n$abc$ LANGUAGE sql IMMUTABLE;\n\nCREATE CAST (type_a AS type_b)\n    WITH FUNCTION type_conversion_function(type_a)\n    AS IMPLICIT;\n\nCREATE OR REPLACE VIEW my_view AS\nSELECT 1;\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_empty_decl.d/expected.tags",
    "content": "X\tinput.sql\t/^CREATE FUNCTION X RETURNS void AS $\\$$/;\"\tf\ttyperef:typename:void\nY\tinput.sql\t/^CREATE OR REPLACE FUNCTION Y(i integer) RETURNS integer AS $\\$$/;\"\tf\ttyperef:typename:integer\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_empty_decl.d/input.sql",
    "content": "CREATE FUNCTION X RETURNS void AS $$\nBEGIN\n\tIF 0 = 0 THEN\n\t   ;\n\t END IF;\nEND;\n$$ LANGUAGE plpgsql;\n\n-- Taken from https://www.postgresql.jp/document/9.2/html/sql-createfunction.html\nCREATE OR REPLACE FUNCTION Y(i integer) RETURNS integer AS $$\n        BEGIN\n                RETURN i + 1;\n        END;\n$$ LANGUAGE plpgsql;\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_guest.d/args.ctags",
    "content": "--sort=no\n--extras=+{guest}\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_guest.d/expected.tags",
    "content": "fun1\tinput.sql\t/^CREATE OR REPLACE FUNCTION fun1() RETURNS VARCHAR AS '$/;\"\tf\ttyperef:typename:VARCHAR\nfun2\tinput.sql\t/^CREATE OR REPLACE FUNCTION fun2() RETURNS VARCHAR LANGUAGE plpgsql AS $\\$$/;\"\tf\ttyperef:typename:VARCHAR\ntest\tinput.sql\t/^CREATE FUNCTION test(keys text[], vals text[]) RETURNS text AS$/;\"\tf\ttyperef:typename:text\ntest2\tinput.sql\t/^CREATE FUNCTION test2(keys text[], vals text[]) RETURNS text AS $ABCDEFGHIJKLMNOPQRSTUVWXYZ\\$$/;\"\tf\ttyperef:typename:text\ntest1_var1\tinput.sql\t/^\ttest1_var1 VARCHAR(64) := $$ABC$$;$/;\"\tv\ntest1_var2\tinput.sql\t/^\ttest1_var2 VARCHAR(64) := $xyz$XYZ$xyz$;$/;\"\tv\ntest1_var3\tinput.sql\t/^\ttest1_var3     INTEGER := 1;$/;\"\tv\ntest2_var1\tinput.sql\t/^\ttest2_var1 VARCHAR(64) := 'ABC2';$/;\"\tv\ntest2_var2\tinput.sql\t/^\ttest2_var2 VARCHAR(64) := 'XYZ2';$/;\"\tv\ntest2_var3\tinput.sql\t/^\ttest2_var3        INTEGER := 2;$/;\"\tv\no\tinput.sql\t/^\tvar o = {};$/;\"\tv\nq\tinput.sql\t/^var q={}; return \"{}\";$/;\"\tv\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_guest.d/input.sql",
    "content": "-- Derived from a comment of https://github.com/universal-ctags/ctags/issues/3006\n-- submitted by @bagl.\nCREATE OR REPLACE FUNCTION fun1() RETURNS VARCHAR AS '\nDECLARE\n\ttest1_var1 VARCHAR(64) := $$ABC$$;\n\ttest1_var2 VARCHAR(64) := $xyz$XYZ$xyz$;\n\ttest1_var3     INTEGER := 1;\nBEGIN\n\tRETURN  TO_CHAR(test_var3, ''000'') || test1_var1 || test1_var2;\nEND;\n' LANGUAGE plpgsql;\n\n-- Derived from a comment of https://github.com/universal-ctags/ctags/issues/3006\n-- submitted by @bagl.\nCREATE OR REPLACE FUNCTION fun2() RETURNS VARCHAR LANGUAGE plpgsql AS $$\nDECLARE\n\ttest2_var1 VARCHAR(64) := 'ABC2';\n\ttest2_var2 VARCHAR(64) := 'XYZ2';\n\ttest2_var3        INTEGER := 2;\nBEGIN\n\tRETURN  TO_CHAR(test2_var3, '000') || test2_var1 || test2_var2;\nEND;\n$$;\n\n-- Derived from https://github.com/plv8/plv8/blob/r3.0alpha/sql/plv8.sql\nCREATE FUNCTION test(keys text[], vals text[]) RETURNS text AS\n$$\n\tvar o = {};\n\tfor (var i = 0; i < keys.length; i++)\n\t\to[keys[i]] = vals[i];\n\treturn JSON.stringify(o);\n$$\nLANGUAGE plv8 IMMUTABLE STRICT;\n\nCREATE FUNCTION test2(keys text[], vals text[]) RETURNS text AS $ABCDEFGHIJKLMNOPQRSTUVWXYZ$\nvar q={}; return \"{}\";\n $ABCDEFGHIJKLMNOPQRSTUVWXYZ$ LANGUAGE plv8 IMMUTABLE STRICT;\n-- The fist whitespace is needed to trigger the original bug.\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_with_function_x.d/expected.tags",
    "content": "my_view\tinput.sql\t/^CREATE OR REPLACE VIEW my_view AS$/;\"\tV\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_with_function_x.d/input.sql",
    "content": "CREATE CAST (type_a AS type_b)\n    WITH FUNCTION type_conversion_function(type_a)\n    AS IMPLICIT;\n\nCREATE OR REPLACE VIEW my_view AS\nSELECT 1;\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_with_language_internal.d/args.ctags",
    "content": "--sort=no\n--fields=+lSr\n--extras=+r\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_with_language_internal.d/expected.tags",
    "content": "isnlt\tinput.sql\t/^CREATE FUNCTION isnlt(ean13, ean13)$/;\"\tf\tlanguage:SQL\ttyperef:typename:boolean\tsignature:(ean13, ean13)\troles:def\nint8lt\tinput.sql\t/^        AS 'int8lt'$/;\"\tf\tlanguage:C\troles:foreigncall\nisnle\tinput.sql\t/^CREATE FUNCTION isnle(ean13, ean13)$/;\"\tf\tlanguage:SQL\ttyperef:typename:boolean\tsignature:(ean13, ean13)\troles:def\nint8le\tinput.sql\t/^        AS 'int8le'$/;\"\tf\tlanguage:C\troles:foreigncall\n"
  },
  {
    "path": "Units/parser-sql.r/sql_pgSQL_with_language_internal.d/input.sql",
    "content": "CREATE FUNCTION isnlt(ean13, ean13)\n        RETURNS boolean\n        AS 'int8lt'\n        LANGUAGE 'internal'\n        IMMUTABLE STRICT\n        PARALLEL SAFE;\nCREATE FUNCTION isnle(ean13, ean13)\n        RETURNS boolean\n        AS 'int8le'\n        LANGUAGE 'internal'\n        IMMUTABLE STRICT\n        PARALLEL SAFE;\n"
  },
  {
    "path": "Units/parser-sql.r/sql_single_quote.sql.d/expected.tags",
    "content": "p1\tinput.sql\t/^CREATE PROCEDURE \"p1\"($/;\"\tp\np2\tinput.sql\t/^CREATE PROCEDURE \"p2\"($/;\"\tp\np3\tinput.sql\t/^CREATE PROCEDURE \"p3\"($/;\"\tp\n"
  },
  {
    "path": "Units/parser-sql.r/sql_single_quote.sql.d/input.sql",
    "content": "CREATE PROCEDURE \"p1\"(\r\n)\r\nBEGIN\r\n        SET someting =  ChannelPath + '\\' + ChannelName;\r\nEND;\r\n\r\nCREATE PROCEDURE \"p2\"(\r\n)\r\nBEGIN\r\n        SET someting =  '''' + ChannelPath + '''';\r\nEND;\r\n\r\nCREATE PROCEDURE \"p3\"(\r\n)\r\nBEGIN\r\nEND;\r\n\r\n\r\n"
  },
  {
    "path": "Units/parser-sql.r/transaction.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-sql.r/transaction.d/expected.tags",
    "content": "neighborhoods\tinput.sql\t/^CREATE TABLE \"neighborhoods\" (gid serial,$/;\"\tt\ngid\tinput.sql\t/^CREATE TABLE \"neighborhoods\" (gid serial,$/;\"\tE\ttable:neighborhoods\nobjectid\tinput.sql\t/^\"objectid\" numeric(10,0),$/;\"\tE\ttable:neighborhoods\npri_neigh_\tinput.sql\t/^\"pri_neigh_\" varchar(3),$/;\"\tE\ttable:neighborhoods\npri_neigh\tinput.sql\t/^\"pri_neigh\" varchar(50),$/;\"\tE\ttable:neighborhoods\nsec_neigh_\tinput.sql\t/^\"sec_neigh_\" varchar(3),$/;\"\tE\ttable:neighborhoods\nsec_neigh\tinput.sql\t/^\"sec_neigh\" varchar(50),$/;\"\tE\ttable:neighborhoods\nshape_area\tinput.sql\t/^\"shape_area\" numeric,$/;\"\tE\ttable:neighborhoods\nshape_len\tinput.sql\t/^\"shape_len\" numeric);$/;\"\tE\ttable:neighborhoods\nneighborhoods_geom_gist\tinput.sql\t/^CREATE INDEX \"neighborhoods_geom_gist\" ON \"neighborhoods\" USING GIST (\"geom\");$/;\"\ti\ttable:neighborhoods\nplayer\tinput.sql\t/^CREATE TABLE \"player\" (uid serial, \"name\" varchar(50));$/;\"\tt\nuid\tinput.sql\t/^CREATE TABLE \"player\" (uid serial, \"name\" varchar(50));$/;\"\tE\ttable:player\nname\tinput.sql\t/^CREATE TABLE \"player\" (uid serial, \"name\" varchar(50));$/;\"\tE\ttable:player\n"
  },
  {
    "path": "Units/parser-sql.r/transaction.d/input.sql",
    "content": "-- Based on https://github.com/tonyta/ScrallWall/blob/master/db/data/neighborhoods.sql\nSET CLIENT_ENCODING TO UTF8;\nSET STANDARD_CONFORMING_STRINGS TO ON;\nBEGIN;\nCREATE TABLE \"neighborhoods\" (gid serial,\n\"objectid\" numeric(10,0),\n\"pri_neigh_\" varchar(3),\n\"pri_neigh\" varchar(50),\n\"sec_neigh_\" varchar(3),\n\"sec_neigh\" varchar(50),\n\"shape_area\" numeric,\n\"shape_len\" numeric);\nALTER TABLE \"neighborhoods\" ADD PRIMARY KEY (gid);\nCREATE INDEX \"neighborhoods_geom_gist\" ON \"neighborhoods\" USING GIST (\"geom\");\nCOMMIT;\n\nBEGIN TRANSACTION;\nCREATE TABLE \"player\" (uid serial, \"name\" varchar(50));\nCOMMIT;\n"
  },
  {
    "path": "Units/parser-sql.r/types.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n--roles-SQL.{type}=+{decl}\n"
  },
  {
    "path": "Units/parser-sql.r/types.d/expected.tags",
    "content": "compfoo\tinput.sql\t/^CREATE TYPE compfoo AS (f1 int, f2 text);$/;\"\tk\troles:def\nf1\tinput.sql\t/^CREATE TYPE compfoo AS (f1 int, f2 text);$/;\"\tE\ttype:compfoo\troles:def\nf2\tinput.sql\t/^CREATE TYPE compfoo AS (f1 int, f2 text);$/;\"\tE\ttype:compfoo\troles:def\ngetfoo\tinput.sql\t/^CREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $\\$$/;\"\tf\ttyperef:typename:SETOF compfoo\troles:def\nbug_status\tinput.sql\t/^CREATE TYPE bug_status AS ENUM ('new', 'open', 'closed');$/;\"\tk\troles:def\nbug\tinput.sql\t/^CREATE TABLE bug ($/;\"\tt\troles:def\nid\tinput.sql\t/^    id serial,$/;\"\tE\ttable:bug\troles:def\ndescription\tinput.sql\t/^    description text,$/;\"\tE\ttable:bug\troles:def\nstatus\tinput.sql\t/^    status bug_status$/;\"\tE\ttable:bug\troles:def\nfloat8_range\tinput.sql\t/^CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi);$/;\"\tk\troles:def\nbox\tinput.sql\t/^CREATE TYPE box;$/;\"\tk\troles:decl\nmy_box_in_function\tinput.sql\t/^CREATE FUNCTION my_box_in_function(cstring) RETURNS box AS $\\$$/;\"\tf\ttyperef:typename:box\troles:def\nmy_box_out_function\tinput.sql\t/^CREATE FUNCTION my_box_out_function(box) RETURNS cstring AS $\\$$/;\"\tf\ttyperef:typename:cstring\troles:def\nbox\tinput.sql\t/^CREATE TYPE box ($/;\"\tk\troles:def\nmyboxes\tinput.sql\t/^CREATE TABLE myboxes ($/;\"\tt\troles:def\nid\tinput.sql\t/^    id integer,$/;\"\tE\ttable:myboxes\troles:def\ndescription\tinput.sql\t/^    description box$/;\"\tE\ttable:myboxes\troles:def\nbigobj\tinput.sql\t/^CREATE TYPE bigobj ($/;\"\tk\troles:def\nbig_objs\tinput.sql\t/^CREATE TABLE big_objs ($/;\"\tt\troles:def\nid\tinput.sql\t/^    id integer,$/;\"\tE\ttable:big_objs\troles:def\nobj\tinput.sql\t/^    obj bigobj$/;\"\tE\ttable:big_objs\troles:def\ncasttesttype\tinput.sql\t/^CREATE TYPE casttesttype;$/;\"\tk\troles:decl\ncasttesttype_in\tinput.sql\t/^CREATE FUNCTION casttesttype_in(cstring)$/;\"\tf\ttyperef:typename:casttesttype\troles:def\ntextin\tinput.sql\t/^   AS 'textin'$/;\"\tf\troles:foreigncall\nanother_type\tinput.sql\t/^CREATE TYPE \"another_type\";$/;\"\tk\troles:decl\nlanguage\tinput.sql\t/^CREATE TYPE language;$/;\"\tk\troles:decl\ndatabase\tinput.sql\t/^CREATE TYPE \"public\".database;$/;\"\tk\troles:decl\ntststats\tinput-0.sql\t/^CREATE schema tststats;$/;\"\tS\troles:def\nty\tinput-0.sql\t/^CREATE TYPE tststats.ty AS (a int, b int, c text);$/;\"\tk\troles:def\na\tinput-0.sql\t/^CREATE TYPE tststats.ty AS (a int, b int, c text);$/;\"\tE\ttype:ty\troles:def\nb\tinput-0.sql\t/^CREATE TYPE tststats.ty AS (a int, b int, c text);$/;\"\tE\ttype:ty\troles:def\nc\tinput-0.sql\t/^CREATE TYPE tststats.ty AS (a int, b int, c text);$/;\"\tE\ttype:ty\troles:def\nemp_obj_typ\tinput-1.sql\t/^CREATE OR REPLACE TYPE BODY emp_obj_typ AS$/;\"\tk\troles:def\ndisplay_emp\tinput-1.sql\t/^    MEMBER PROCEDURE display_emp (SELF IN OUT emp_obj_typ)$/;\"\tp\troles:def\n"
  },
  {
    "path": "Units/parser-sql.r/types.d/input-0.sql",
    "content": "-- Taken from postgresql/src/test/regress/sql/stats_ext.sql\nCREATE schema tststats;\nCREATE TYPE tststats.ty AS (a int, b int, c text);\n"
  },
  {
    "path": "Units/parser-sql.r/types.d/input-1.sql",
    "content": "-- Taken from https://www.enterprisedb.com/docs/epas/latest/reference/oracle_compatibility_reference/epas_compat_sql/40_create_type_body/\nCREATE OR REPLACE TYPE BODY emp_obj_typ AS\n    MEMBER PROCEDURE display_emp (SELF IN OUT emp_obj_typ)\n    IS\n    BEGIN\n        DBMS_OUTPUT.PUT_LINE('Employee No   : ' || empno);\n        DBMS_OUTPUT.PUT_LINE('Name          : ' || ename);\n        DBMS_OUTPUT.PUT_LINE('Street        : ' || addr.street);\n        DBMS_OUTPUT.PUT_LINE('City/State/Zip: ' || addr.city || ', ' ||\n            addr.state || ' ' || LPAD(addr.zip,5,'0'));\n    END;\nEND;\n"
  },
  {
    "path": "Units/parser-sql.r/types.d/input.sql",
    "content": "-- Taken from https://www.postgresql.jp/document/17/html/sql-createtype.html\n\nCREATE TYPE compfoo AS (f1 int, f2 text);\n\nCREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $$\n    SELECT fooid, fooname FROM foo\n$$ LANGUAGE SQL;\n\nCREATE TYPE bug_status AS ENUM ('new', 'open', 'closed');\n\nCREATE TABLE bug (\n    id serial,\n    description text,\n    status bug_status\n);\n\nCREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi);\n\nCREATE TYPE box;\n\nCREATE FUNCTION my_box_in_function(cstring) RETURNS box AS $$\n...\t\t\t\t-- fix me\n$$ LANGUAGE SQL;\n\nCREATE FUNCTION my_box_out_function(box) RETURNS cstring AS $$\n...\t\t\t\t-- fix me\n$$ LANGUAGE SQL;\n\nCREATE TYPE box (\n    INTERNALLENGTH = 16,\n    INPUT = my_box_in_function,\n    OUTPUT = my_box_out_function\n);\n\nCREATE TABLE myboxes (\n    id integer,\n    description box\n);\n\nCREATE TYPE bigobj (\n    INPUT = lo_filein, OUTPUT = lo_fileout,\n    INTERNALLENGTH = VARIABLE\n);\nCREATE TABLE big_objs (\n    id integer,\n    obj bigobj\n);\n\n-- Taken from postgresql/src/test/regress/sql/create_cast.sql\nCREATE TYPE casttesttype;\n\nCREATE FUNCTION casttesttype_in(cstring)\n   RETURNS casttesttype\n   AS 'textin'\n   LANGUAGE internal STRICT IMMUTABLE;\n\n-- string literal\nCREATE TYPE \"another_type\";\n\n-- non-reserved word\nCREATE TYPE language;\n\n-- non-reserved word with schema name\nCREATE TYPE \"public\".database;\n"
  },
  {
    "path": "Units/parser-svg.r/defs.d/args.ctags",
    "content": "--fields=+l\n"
  },
  {
    "path": "Units/parser-svg.r/defs.d/expected.tags",
    "content": "Gradient01\tinput.svg\t/^    <linearGradient id=\"Gradient01\">$/;\"\td\tlanguage:SVG\nGradient01\tinput.svg\t/^    <linearGradient id=\"Gradient01\">$/;\"\ti\tlanguage:XML\nGradient02\tinput.svg\t/^    <linearGradient id=\"Gradient02\">$/;\"\td\tlanguage:SVG\nGradient02\tinput.svg\t/^    <linearGradient id=\"Gradient02\">$/;\"\ti\tlanguage:XML\nns6c64d62e0101\tinput.svg\t/^     xmlns=\"http:\\/\\/www.w3.org\\/2000\\/svg\">$/;\"\tn\tlanguage:XML\turi:http://www.w3.org/2000/svg\n"
  },
  {
    "path": "Units/parser-svg.r/defs.d/features",
    "content": "xpath\n\n"
  },
  {
    "path": "Units/parser-svg.r/simple-svg.d/args.ctags",
    "content": "--fields=+x\n"
  },
  {
    "path": "Units/parser-svg.r/simple-svg.d/expected.tags",
    "content": "cc\tinput.svg\t/^   width=\"12cm\">$/;\"\tn\turi:http://creativecommons.org/ns#\ndc\tinput.svg\t/^   width=\"12cm\">$/;\"\tn\turi:http://purl.org/dc/elements/1.1/\ndefs10\tinput.svg\t/^     id=\"defs10\" \\/>$/;\"\ti\txpath:/*/*[2]/@id\ndesc4\tinput.svg\t/^     id=\"desc4\">RECTANGLE<\\/desc>$/;\"\ti\txpath:/*/*[3]/@id\nmetadata12\tinput.svg\t/^     id=\"metadata12\">$/;\"\ti\txpath:/*/*[1]/@id\nns380f7e730101\tinput.svg\t/^   width=\"12cm\">$/;\"\tn\turi:http://www.w3.org/2000/svg\nrdf\tinput.svg\t/^   width=\"12cm\">$/;\"\tn\turi:http://www.w3.org/1999/02/22-rdf-syntax-ns#\nrect6\tinput.svg\t/^     x=\"19.018383\" \\/>$/;\"\ti\txpath:/*/*[4]/@id\nsvg\tinput.svg\t/^   width=\"12cm\">$/;\"\tn\turi:http://www.w3.org/2000/svg\nsvg2\tinput.svg\t/^   width=\"12cm\">$/;\"\ti\txpath:/*/@id\n"
  },
  {
    "path": "Units/parser-svg.r/simple-svg.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-systemdunit.r/simple-systemdunit.d/args.ctags",
    "content": "--extras=+r\n--fields=+rKle\n"
  },
  {
    "path": "Units/parser-systemdunit.r/simple-systemdunit.d/expected.tags",
    "content": "After\tinput.service\t/^After=network-online.target$/;\"\tkey\tlanguage:Iniconf\tsection:Unit\troles:def\nDescription\tinput.service\t/^Description=download the file specified in \\/home\\/yamato\\/var\\/promise\\/t_conf\\/rhel-server-6_5/;\"\tkey\tlanguage:Iniconf\tsection:Unit\troles:def\nExecStart\tinput.service\t/^ExecStart=\\/usr\\/bin\\/promise force \\/home\\/yamato\\/var\\/promise\\/t_conf\\/rhel-server-6_5-x86_64/;\"\tkey\tlanguage:Iniconf\tsection:Service\troles:def\nIOSchedulingClass\tinput.service\t/^IOSchedulingClass=3$/;\"\tkey\tlanguage:Iniconf\tsection:Service\troles:def\nIOSchedulingPriority\tinput.service\t/^IOSchedulingPriority=7$/;\"\tkey\tlanguage:Iniconf\tsection:Service\troles:def\nNice\tinput.service\t/^Nice=19$/;\"\tkey\tlanguage:Iniconf\tsection:Service\troles:def\nRequires\tinput.service\t/^Requires=network-online.target$/;\"\tkey\tlanguage:Iniconf\tsection:Unit\troles:def\nService\tinput.service\t/^[Service]$/;\"\tsection\tlanguage:Iniconf\troles:def\tend:11\nType\tinput.service\t/^Type=oneshot$/;\"\tkey\tlanguage:Iniconf\tsection:Service\troles:def\nUnit\tinput.service\t/^[Unit]$/;\"\tsection\tlanguage:Iniconf\troles:def\tend:5\nnetwork-online.target\tinput.service\t/^After=network-online.target$/;\"\tunit\tlanguage:SystemdUnit\troles:After\nnetwork-online.target\tinput.service\t/^Requires=network-online.target$/;\"\tunit\tlanguage:SystemdUnit\troles:Requires\n"
  },
  {
    "path": "Units/parser-systemdunit.r/simple-systemdunit.d/input.service",
    "content": "[Unit]\nDescription=download the file specified in /home/yamato/var/promise/t_conf/rhel-server-6_5-x86_64.promise and deploy it to the local file system\nAfter=network-online.target\nRequires=network-online.target\n\n[Service]\nType=oneshot\nNice=19\nIOSchedulingClass=3\nIOSchedulingPriority=7\nExecStart=/usr/bin/promise force /home/yamato/var/promise/t_conf/rhel-server-6_5-x86_64.promise\n"
  },
  {
    "path": "Units/parser-systemtap.r/functions.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-systemtap.r/functions.d/expected.tags",
    "content": "matched_str\tinput.stp\t/^function matched_str:string() { return matched(0) }$/;\"\tf\tline:24\ttyperef:typename:string\tend:24\nmatched\tinput.stp\t/^function matched:string(n:long)$/;\"\tf\tline:39\ttyperef:typename:string\tend:82\nngroups\tinput.stp\t/^function ngroups:long()$/;\"\tf\tline:96\ttyperef:typename:long\tend:105\n__asmlinkage_int_arg\tinput.stp\t/^function __asmlinkage_int_arg:long(n:long)$/;\"\tf\tline:116\ttyperef:typename:long\tend:120\n"
  },
  {
    "path": "Units/parser-systemtap.r/functions.d/input.stp",
    "content": "#\n# Taken from /usr/share/systemtap/tapset/regex.stp and registers.stp\n#\n// Regular expression subexpression tapset\n// Copyright (C) 2017 Serhei Makarov\n// Copyright (C) 2013 Red Hat, Inc.\n//\n// This file is part of systemtap, and is free software.  You can\n// redistribute it and/or modify it under the terms of the GNU General\n// Public License (GPL); either version 2, or (at your option) any\n// later version.\n\n%{\n#define STAP_NEED_CONTEXT_SUBEXPRESSION 1\n%}\n\n/**\n * sfunction matched_str - Return the last matched string.\n *\n * Description: returns the string matched by the last successful\n * use of the =~ regexp matching operator. Returns an error if the\n * last use of =~ led to a failed match.\n */\nfunction matched_str:string() { return matched(0) }\n\n/**\n * sfunction matched - Return a given matched subexpression.\n *\n * @n: index to the subexpression to return. 0 corresponds to the\n * entire regular expression.\n *\n * Description: returns the content of the n'th subexpression of the\n * last successful use of the =~ regex matching operator. Returns an\n * empty string if the n'th subexpression was not matched (e.g. due to\n * alternation). Throws an error if the last use of =~ was a failed\n * match, or if fewer than n subexpressions are present in the\n * original regexp.\n */\nfunction matched:string(n:long)\n%{ /* pure */ /* unprivileged */ /* pragma:tagged_dfa */\n  int start_ix, end_ix; // indices into tag buffer\n  int start, end, length; // actual coordinate values\n\n  if (!CONTEXT->last_match.result) {\n    snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),\n             \"Attempted to get subexpression %lld from failed match\", (long long) STAP_ARG_n);\n    CONTEXT->last_error = CONTEXT->error_buffer;\n  }\n\n  start_ix = 2 * STAP_ARG_n, end_ix = start_ix + 1;\n\n  if (end_ix >= CONTEXT->last_match.num_final_tags) {\n    snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),\n             \"Attempted to get nonexistent subexpression %lld\", (long long) STAP_ARG_n);\n    CONTEXT->last_error = CONTEXT->error_buffer;\n  }\n\n  start = CONTEXT->last_match.tag_vals[start_ix];\n  end = CONTEXT->last_match.tag_vals[end_ix];\n  // _stp_printf (\"**DEBUG** Extracted subexpression #%lld:(%d,%d) from %d to %d\\n\", STAP_ARG_n, start_ix, end_ix, start, end);\n\n  if (start < 0 || end < 0) {\n    // If indices are negative, the group was not matched. Return empty string:\n    start = end = 0;\n    // snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),\n    //          \"Unknown coordinates for subexpression %lld\", STAP_ARG_n);\n    // CONTEXT->last_error = CONTEXT->error_buffer;\n  }\n\n  if (start > end) {\n    // This should not happen.\n    snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),\n             \"BUG: inverted coordinates for subexpression %lld\", (long long) STAP_ARG_n);\n    CONTEXT->last_error = CONTEXT->error_buffer;\n  }\n\n  length = end - start;\n\n  // TODOXXX assert (start <= strlen(matched_str)) ??\n  // XXX: Must add 1 to length to account for NUL byte in strlcpy().\n  strlcpy(STAP_RETVALUE, CONTEXT->last_match.matched_str + start, length + 1);\n%}\n\n/**\n * sfunction ngroups - Number of subexpressions in the last match.\n *\n * Description: returns the number of subexpressions from the\n * last successful use of the =~ regex matching operator.\n *\n * Note that this number includes subexpressions which are present in\n * the regex but did not match any string; for example, given the\n * regex \"a|(b)\", the subexpressions will count the group for (b)\n * regardless of whether it matched a string or not. Throws an error\n * if the last use of =~ was a failed match.\n */\nfunction ngroups:long()\n%{ /* pure */ /* unprivileged */ /* pragma:tagged_dfa */\n  if (!CONTEXT->last_match.result) {\n    snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),\n             \"Attempted to get subexpression count from failed match\");\n    CONTEXT->last_error = CONTEXT->error_buffer;\n  }\n\n  STAP_RETVALUE = CONTEXT->last_match.num_final_tags / 2;\n%}\n\n// XXX: perhaps implement matched_start, matched_end to get indices?\n// XXX: some kind of find-replace functionality?\n// XXX: some kind of splitting / multiple-match functionality?\n\n/*\n * In nd_syscall.return probes, we sometimes need @entry() values. To\n * ensure we get the argument in the correct mode, we need a function\n * that calls asmlinkage() first.\n */\nfunction __asmlinkage_int_arg:long(n:long)\n{\n\tasmlinkage()\n\treturn int_arg(n)\n}\n"
  },
  {
    "path": "Units/parser-systemtap.r/macros.d/args.ctags",
    "content": "--sort=no\n--fields=+ne\n"
  },
  {
    "path": "Units/parser-systemtap.r/macros.d/expected.tags",
    "content": "m0\tinput.stpm\t/^@define m0$/;\"\tm\tline:4\tend:7\nm1\tinput.stpm\t/^@define m1(a0) %($/;\"\tm\tline:12\tend:14\nm2\tinput.stpm\t/^@define m2(a1,$/;\"\tm\tline:19\tend:22\n"
  },
  {
    "path": "Units/parser-systemtap.r/macros.d/input.stpm",
    "content": "#\n# sharp Comment\n#\n@define m0\n%(\n  0\n%)\n\n/* \n * C comment \n */\n@define m1(a0) %(\n    @a0\n%)\n\n//\n// C++  comment\n//\n@define m2(a1,\n\t   a2) %(\n %( @a1 + @a2 %)\n%)\n"
  },
  {
    "path": "Units/parser-systemtap.r/probes.d/args.ctags",
    "content": "--sort=no\n--fields=+ner\n--extras=+r\n--extras=+g\n"
  },
  {
    "path": "Units/parser-systemtap.r/probes.d/expected.tags",
    "content": "tcp_get_info_rto\tinput.stp\t/^function tcp_get_info_rto:long(sock:long)$/;\"\tf\tline:33\ttyperef:typename:long\troles:def\tend:44\ntcp_get_info_snd_cwnd\tinput.stp\t/^function tcp_get_info_snd_cwnd:long(sock:long)$/;\"\tf\tline:50\ttyperef:typename:long\troles:def\tend:60\ntcp_ts_get_info_state\tinput.stp\t/^function tcp_ts_get_info_state:long(sock:long)$/;\"\tf\tline:78\ttyperef:typename:long\troles:def\tend:83\n__tcp_sock_dport\tinput.stp\t/^function __tcp_sock_dport:long (sock:long)$/;\"\tf\tline:86\ttyperef:typename:long\troles:def\tend:93\n__get_skb_tcphdr_new\tinput.stp\t/^@__private30 function __get_skb_tcphdr_new:long(skb:long)$/;\"\tf\tline:96\ttyperef:typename:long\troles:def\tend:107\n__get_skb_tcphdr\tinput.stp\t/^function __get_skb_tcphdr:long(skb:long)$/;\"\tf\tline:110\ttyperef:typename:long\troles:def\tend:118\n__tcp_skb_urg\tinput.stp\t/^function __tcp_skb_urg:long (tcphdr:long)$/;\"\tf\tline:121\ttyperef:typename:long\troles:def\tend:124\n__tcp_skb_ack\tinput.stp\t/^function __tcp_skb_ack:long (tcphdr:long)$/;\"\tf\tline:127\ttyperef:typename:long\troles:def\tend:130\n__tcp_skb_psh\tinput.stp\t/^function __tcp_skb_psh:long (tcphdr:long)$/;\"\tf\tline:133\ttyperef:typename:long\troles:def\tend:136\n__tcp_skb_rst\tinput.stp\t/^function __tcp_skb_rst:long (tcphdr:long)$/;\"\tf\tline:139\ttyperef:typename:long\troles:def\tend:142\n__tcp_skb_syn\tinput.stp\t/^function __tcp_skb_syn:long (tcphdr:long)$/;\"\tf\tline:145\ttyperef:typename:long\troles:def\tend:148\n__tcp_skb_fin\tinput.stp\t/^function __tcp_skb_fin:long (tcphdr:long)$/;\"\tf\tline:151\ttyperef:typename:long\troles:def\tend:154\n__tcp_skb_sport\tinput.stp\t/^function __tcp_skb_sport:long (tcphdr:long)$/;\"\tf\tline:157\ttyperef:typename:long\troles:def\tend:160\n__tcp_skb_dport\tinput.stp\t/^function __tcp_skb_dport:long (tcphdr:long){$/;\"\tf\tline:163\ttyperef:typename:long\troles:def\tend:165\n__tcp_sock_sport\tinput.stp\t/^function __tcp_sock_sport:long (sock:long)$/;\"\tf\tline:168\ttyperef:typename:long\troles:def\tend:174\nsockstate\tinput.stp\t/^@__private30 global sockstate[12]$/;\"\tv\tline:176\troles:def\ninit\tinput.stp\t/^probe init {$/;\"\tp\tline:177\troles:attached\tend:190\ntcp_sockstate_str\tinput.stp\t/^function tcp_sockstate_str:string (state:long) {$/;\"\tf\tline:192\ttyperef:typename:string\troles:def\tend:194\ntcp_ts_get_info_snd_ssthresh\tinput.stp\t/^function tcp_ts_get_info_snd_ssthresh:long(sock:long)$/;\"\tf\tline:199\ttyperef:typename:long\troles:def\tend:209\ntcp_ts_get_info_rcv_mss\tinput.stp\t/^function tcp_ts_get_info_rcv_mss:long(sock:long)$/;\"\tf\tline:213\ttyperef:typename:long\troles:def\tend:224\n__sockopt\tinput.stp\t/^@__private30 global __sockopt[18]$/;\"\tv\tline:248\troles:def\ninit\tinput.stp\t/^probe init {$/;\"\tp\tline:249\troles:attached\tend:279\ntcp_sockopt_str\tinput.stp\t/^function tcp_sockopt_str:string (optname:long)$/;\"\tf\tline:281\ttyperef:typename:string\troles:def\tend:285\n__ipv6_sockopt\tinput.stp\t/^@__private30 global __ipv6_sockopt[55]$/;\"\tv\tline:349\troles:def\ninit\tinput.stp\t/^probe init {$/;\"\tp\tline:350\troles:attached\tend:465\ntcp_ipv6_sockopt_str\tinput.stp\t/^function tcp_ipv6_sockopt_str:string (optname:long)$/;\"\tf\tline:467\ttyperef:typename:string\troles:def\tend:471\ntcp.sendmsg\tinput.stp\t/^probe tcp.sendmsg = kernel.function(\"tcp_sendmsg\") {$/;\"\tp\tline:483\troles:def\tend:488\ntcp.sendmsg.return\tinput.stp\t/^probe tcp.sendmsg.return = kernel.function(\"tcp_sendmsg\").return {$/;\"\tp\tline:498\troles:def\tend:501\ntcp.recvmsg\tinput.stp\t/^probe tcp.recvmsg = kernel.function(\"tcp_recvmsg\") {$/;\"\tp\tline:516\troles:def\tend:525\ntcp.recvmsg.return\tinput.stp\t/^probe tcp.recvmsg.return = kernel.function(\"tcp_recvmsg\").return {$/;\"\tp\tline:540\troles:def\tend:548\ntcp.disconnect\tinput.stp\t/^probe tcp.disconnect = kernel.function(\"tcp_disconnect\") {$/;\"\tp\tline:564\troles:def\tend:573\ntcp.disconnect.return\tinput.stp\t/^probe tcp.disconnect.return = kernel.function(\"tcp_disconnect\").return {$/;\"\tp\tline:583\troles:def\tend:586\ntcp.setsockopt\tinput.stp\t/^probe tcp.setsockopt = tcp.ipv4.setsockopt, tcp.ipv6.setsockopt$/;\"\tp\tline:601\troles:def\tend:603\ntcp.ipv4.setsockopt\tinput.stp\t/^probe tcp.ipv4.setsockopt = kernel.function(\"tcp_setsockopt\")$/;\"\tp\tline:604\troles:def\tend:613\ntcp.ipv6.setsockopt\tinput.stp\t/^probe tcp.ipv6.setsockopt = kernel.function(\"ipv6_setsockopt\")!,$/;\"\tp\tline:614\troles:def\tend:624\ntcp.setsockopt.return\tinput.stp\t/^probe tcp.setsockopt.return = tcp.ipv4.setsockopt.return,$/;\"\tp\tline:634\troles:def\tend:637\ntcp.ipv4.setsockopt.return\tinput.stp\t/^probe tcp.ipv4.setsockopt.return = kernel.function(\"tcp_setsockopt\").return$/;\"\tp\tline:638\troles:def\tend:642\ntcp.ipv6.setsockopt.return\tinput.stp\t/^probe tcp.ipv6.setsockopt.return = kernel.function(\"ipv6_setsockopt\").return!,$/;\"\tp\tline:643\troles:def\tend:648\ntcp.receive\tinput.stp\t/^probe tcp.receive = tcp.ipv4.receive, tcp.ipv6.receive$/;\"\tp\tline:667\troles:def\tend:669\ntcp.ipv4.receive\tinput.stp\t/^probe tcp.ipv4.receive = kernel.function(\"tcp_v4_rcv\")$/;\"\tp\tline:671\troles:def\tend:694\ntcp.ipv6.receive\tinput.stp\t/^probe tcp.ipv6.receive = kernel.function(\"tcp_v6_rcv\")!,$/;\"\tp\tline:696\troles:def\tend:730\nlinux/version.h\tinput.stp\t/^#include <linux\\/version.h>/;\"\th\tline:22\troles:system\nnet/sock.h\tinput.stp\t/^#include <net\\/sock.h>/;\"\th\tline:23\troles:system\nnet/tcp.h\tinput.stp\t/^#include <net\\/tcp.h>/;\"\th\tline:24\troles:system\nnet/ip.h\tinput.stp\t/^#include <net\\/ip.h>/;\"\th\tline:25\troles:system\nlinux/skbuff.h\tinput.stp\t/^#include <linux\\/skbuff.h>/;\"\th\tline:26\troles:system\nTCP_CONGESTION\tinput.stp\t/^#define TCP_CONGESTION /;\"\td\tline:229\tfile:\troles:def\tend:229\nTCP_MD5SIG\tinput.stp\t/^#define TCP_MD5SIG /;\"\td\tline:232\tfile:\troles:def\tend:232\nTCP_COOKIE_TRANSACTIONS\tinput.stp\t/^#define TCP_COOKIE_TRANSACTIONS /;\"\td\tline:235\tfile:\troles:def\tend:235\nTCP_THIN_LINEAR_TIMEOUTS\tinput.stp\t/^#define TCP_THIN_LINEAR_TIMEOUTS /;\"\td\tline:238\tfile:\troles:def\tend:238\nTCP_THIN_DUPACK\tinput.stp\t/^#define TCP_THIN_DUPACK /;\"\td\tline:241\tfile:\troles:def\tend:241\nTCP_USER_TIMEOUT\tinput.stp\t/^#define TCP_USER_TIMEOUT /;\"\td\tline:244\tfile:\troles:def\tend:244\nlinux/in6.h\tinput.stp\t/^#include <linux\\/in6.h>/;\"\th\tline:289\troles:system\nIPV6_2292PKTINFO\tinput.stp\t/^#define IPV6_2292PKTINFO /;\"\td\tline:291\tfile:\troles:def\tend:291\nIPV6_2292HOPOPTS\tinput.stp\t/^#define IPV6_2292HOPOPTS /;\"\td\tline:294\tfile:\troles:def\tend:294\nIPV6_2292DSTOPTS\tinput.stp\t/^#define IPV6_2292DSTOPTS /;\"\td\tline:297\tfile:\troles:def\tend:297\nIPV6_2292RTHDR\tinput.stp\t/^#define IPV6_2292RTHDR /;\"\td\tline:300\tfile:\troles:def\tend:300\nIPV6_2292PKTOPTIONS\tinput.stp\t/^#define IPV6_2292PKTOPTIONS /;\"\td\tline:303\tfile:\troles:def\tend:303\nIPV6_2292HOPLIMIT\tinput.stp\t/^#define IPV6_2292HOPLIMIT /;\"\td\tline:306\tfile:\troles:def\tend:306\nIPV6_RECVPKTINFO\tinput.stp\t/^#define IPV6_RECVPKTINFO /;\"\td\tline:309\tfile:\troles:def\tend:309\nIPV6_RECVHOPLIMIT\tinput.stp\t/^#define IPV6_RECVHOPLIMIT /;\"\td\tline:312\tfile:\troles:def\tend:312\nIPV6_RECVHOPOPTS\tinput.stp\t/^#define IPV6_RECVHOPOPTS /;\"\td\tline:315\tfile:\troles:def\tend:315\nIPV6_RTHDRDSTOPTS\tinput.stp\t/^#define IPV6_RTHDRDSTOPTS /;\"\td\tline:318\tfile:\troles:def\tend:318\nIPV6_RECVRTHDR\tinput.stp\t/^#define IPV6_RECVRTHDR /;\"\td\tline:321\tfile:\troles:def\tend:321\nIPV6_RECVDSTOPTS\tinput.stp\t/^#define IPV6_RECVDSTOPTS /;\"\td\tline:324\tfile:\troles:def\tend:324\nIPV6_RECVPATHMTU\tinput.stp\t/^#define IPV6_RECVPATHMTU /;\"\td\tline:327\tfile:\troles:def\tend:327\nIPV6_PATHMTU\tinput.stp\t/^#define IPV6_PATHMTU /;\"\td\tline:330\tfile:\troles:def\tend:330\nIPV6_DONTFRAG\tinput.stp\t/^#define IPV6_DONTFRAG /;\"\td\tline:333\tfile:\troles:def\tend:333\nIPV6_ADDR_PREFERENCES\tinput.stp\t/^#define IPV6_ADDR_PREFERENCES /;\"\td\tline:336\tfile:\troles:def\tend:336\nIPV6_MINHOPCOUNT\tinput.stp\t/^#define IPV6_MINHOPCOUNT /;\"\td\tline:339\tfile:\troles:def\tend:339\nIPV6_RECVORIGDSTADDR\tinput.stp\t/^#define IPV6_RECVORIGDSTADDR /;\"\td\tline:342\tfile:\troles:def\tend:342\nIPV6_TRANSPARENT\tinput.stp\t/^#define IPV6_TRANSPARENT /;\"\td\tline:345\tfile:\troles:def\tend:345\n"
  },
  {
    "path": "Units/parser-systemtap.r/probes.d/input.stp",
    "content": "#\n# Taken from /usr/share/systemtap/tapset/linux/tcp.stp\n#\n// TCP tapset\n// Copyright (C) 2006 IBM Corp.\n// Copyright (C) 2006 Intel Corporation.\n// Copyright (C) 2007, 2010, 2012-2018 Red Hat, Inc.\n//\n// This file is part of systemtap, and is free software.  You can\n// redistribute it and/or modify it under the terms of the GNU General\n// Public License (GPL); either version 2, or (at your option) any\n// later version.\n// <tapsetdescription>\n// This family of probe points is used to probe events that occur in the TCP layer, \n// </tapsetdescription>\n\n// See the BZ1546179 block comment in tapset/linux/networking.stp for\n// an explanation of the try/catch statements around sk_buff structure\n// accesses.\n\n%{\n#include <linux/version.h>\n#include <net/sock.h>\n#include <net/tcp.h>\n#include <net/ip.h>\n#include <linux/skbuff.h>\n%}\n\n// Get retransmission timeout in usecs. RTO is initialized from default\n// retransmission time, but can be adjusted (increased) each time we \n// retransmit. It should always be less than the max value of TCP retransmission \n// timeout (TCP_RTO_MAX)\nfunction tcp_get_info_rto:long(sock:long)\n%{ /* pure */\n\tstruct sock *sk = (struct sock *)(uintptr_t) STAP_ARG_sock;\n#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)\n\tstruct tcp_opt *tp = tcp_sk(sk);\n\tSTAP_RETVALUE = (int64_t) jiffies_to_usecs(kread(&(tp->rto)));\n#else\n\tconst struct inet_connection_sock *icsk = inet_csk(sk);\n\tSTAP_RETVALUE = (int64_t) jiffies_to_usecs(kread(&(icsk->icsk_rto)));\n#endif\n\tCATCH_DEREF_FAULT();\n%}\n\n//Get congestion window segment size. Initial value of congestion window size \n//typically set to one segment (i.e., slow start algorithm, each segment can be 512 bytes).\n//This congestion window size can be dynamically increased based on whether TCP\n//is performing slow start or congestion avoidance. \nfunction tcp_get_info_snd_cwnd:long(sock:long)\n%{ /* pure */\n\tstruct sock *sk = (struct sock *)(uintptr_t) STAP_ARG_sock;\n#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)\n\tstruct tcp_opt *tp = tcp_sk(sk);\n#else\n\tstruct tcp_sock *tp = tcp_sk(sk);\n#endif\n\tSTAP_RETVALUE = (int64_t) kread(&(tp->snd_cwnd));\n\tCATCH_DEREF_FAULT();\n%}\n\n//\n//Definitions of the TCP protocol sk_state field listed below.\n//\n//     TCP_ESTABLISHED = 1,   Normal data transfer\n//     TCP_SYN_SENT   = 2,   App. has started to open a connection\n//     TCP_SYN_RECV   = 3,   A connection request has arrived; wait for ACK\n//     TCP_FIN_WAIT1  = 4,   App. has said it is finished\n//     TCP_FIN_WAIT2  = 5,   The other side has agreed to close\n//     TCP_TIME_WAIT  = 6,   Wait for all packets to die off\n//     TCP_CLOSE      = 7,   No connection is active or pending \n//     TCP_CLOSE_WAIT = 8,   The other side has initiated a release\n//     TCP_LAST_ACK   = 9,   Last ACK, wait for all packets to die off\n//     TCP_LISTEN     = 10,  Waiting for incoming call\n//     TCP_CLOSING    = 11,  Both sides have tried to close simultaneously\n//     TCP_MAX_STATES = 12   Max states number\n// \nfunction tcp_ts_get_info_state:long(sock:long)\n%{ /* pure */\n\tstruct sock *sk = (struct sock *)(uintptr_t) STAP_ARG_sock;\n\tSTAP_RETVALUE = (int64_t) kread(&(sk->sk_state));\n\tCATCH_DEREF_FAULT();\n%}\n\n/* return the TCP destination port for a given sock */\nfunction __tcp_sock_dport:long (sock:long)\n{\n  port = @choose_defined(@inet_sock_cast(sock)->sk->__sk_common->skc_dport, # kernel >= 3.8\n          @choose_defined(@inet_sock_cast(sock)->inet_dport, # kernel >= 2.6.33\n           @choose_defined(@inet_sock_cast(sock)->dport, # kernel >= 2.6.11\n                           @inet_sock_cast(sock)->inet->dport)))\n  return ntohs(port)\n}\n\n/* returns the TCP header for recent (<2.6.21) kernel */\n@__private30 function __get_skb_tcphdr_new:long(skb:long)\n%{ /* pure */\n\tstruct sk_buff *skb;\n\tskb = (struct sk_buff *)(uintptr_t)STAP_ARG_skb;\n\t/* as done by skb_transport_header() */\n\t#ifdef NET_SKBUFF_DATA_USES_OFFSET\n\t\tSTAP_RETVALUE = (long)(kread(&(skb->head)) + kread(&(skb->transport_header)));\n\t#else\n\t\tSTAP_RETVALUE = (long)kread(&(skb->transport_header));\n\t#endif\n\tCATCH_DEREF_FAULT();\n%}\n\n/* returns the TCP header for a given sk_buff structure */\nfunction __get_skb_tcphdr:long(skb:long)\n{\n%( kernel_v < \"2.6.21\" %?\n\ttcphdr = @cast(skb, \"sk_buff\")->h->raw\n\treturn tcphdr\n%:\n\treturn __get_skb_tcphdr_new(skb)\n%)\n}\n\n/* returns TCP URG flag for a given sk_buff structure */\nfunction __tcp_skb_urg:long (tcphdr:long)\n{\n\treturn @cast(tcphdr, \"tcphdr\", \"kernel<linux/tcp.h>\")->urg\n}\n\n/* returns TCP ACK flag for a given sk_buff structure */\nfunction __tcp_skb_ack:long (tcphdr:long)\n{\n\treturn @cast(tcphdr, \"tcphdr\", \"kernel<linux/tcp.h>\")->ack\n}\n\n/* returns TCP PSH flag for a given sk_buff structure */\nfunction __tcp_skb_psh:long (tcphdr:long)\n{\n\treturn @cast(tcphdr, \"tcphdr\", \"kernel<linux/tcp.h>\")->psh\n}\n\n/* returns TCP RST flag for a given sk_buff structure */\nfunction __tcp_skb_rst:long (tcphdr:long)\n{\n\treturn @cast(tcphdr, \"tcphdr\", \"kernel<linux/tcp.h>\")->rst\n}\n\n/* returns TCP SYN flag for a given sk_buff structure */\nfunction __tcp_skb_syn:long (tcphdr:long)\n{\n\treturn @cast(tcphdr, \"tcphdr\", \"kernel<linux/tcp.h>\")->syn\n}\n\n/* returns TCP FIN flag for a given sk_buff structure */\nfunction __tcp_skb_fin:long (tcphdr:long)\n{\n\treturn @cast(tcphdr, \"tcphdr\", \"kernel<linux/tcp.h>\")->fin\n}\n\n/* returns TCP source port for a given sk_buff structure */\nfunction __tcp_skb_sport:long (tcphdr:long)\n{\n\treturn ntohs(@cast(tcphdr, \"tcphdr\", \"kernel<linux/tcp.h>\")->source)\n}\n\n/* returns TCP destination port for a given sk_buff structure */\nfunction __tcp_skb_dport:long (tcphdr:long){\n\treturn ntohs(@cast(tcphdr, \"tcphdr\", \"kernel<linux/tcp.h>\")->dest)\n}\n\n/* return the TCP source port for a given sock */\nfunction __tcp_sock_sport:long (sock:long)\n{\n    port = @choose_defined(@inet_sock_cast(sock)->inet_sport, # kernel >= 2.6.33\n\t    @choose_defined(@inet_sock_cast(sock)->sport, # kernel >= 2.6.11\n\t\t@inet_sock_cast(sock)->inet->sport))\n    return ntohs(port)\n}\n\n@__private30 global sockstate[12]\nprobe init {\n\tsockstate[1] = \"TCP_ESTABLISHED\"\n\tsockstate[2] = \"TCP_SYN_SENT\"\n\tsockstate[3] = \"TCP_SYN_RECV\"\n\tsockstate[4] = \"TCP_FIN_WAIT1\"\n\tsockstate[5] = \"TCP_FIN_WAIT2\"\n\tsockstate[6] = \"TCP_TIME_WAIT\"\n\tsockstate[7] = \"TCP_CLOSE\"\n\tsockstate[8] = \"TCP_CLOSE_WAIT\"\n\tsockstate[9] = \"TCP_LAST_ACK\"\n\tsockstate[10] = \"TCP_LISTEN\"\n\tsockstate[11] = \"TCP_CLOSING\"\n\tsockstate[12] = \"TCP_MAX_STATES\"\n}\n\nfunction tcp_sockstate_str:string (state:long) {\n\treturn (state in sockstate ? sockstate[state] : \"UNDEF\")\n}\n\n// Get slow start threshold size.  If cwnd size is less than or equal to\n// threshold size, then TCP is in slow start; otherwise TCP is in congestion\n// avoidance.\nfunction tcp_ts_get_info_snd_ssthresh:long(sock:long)\n%{ /* pure */\n\tstruct sock *sk = (struct sock *)(uintptr_t) STAP_ARG_sock;\n#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)\n\tstruct tcp_opt *tp = tcp_sk(sk);\n#else\n\tstruct tcp_sock *tp = tcp_sk(sk);\n#endif\n\tSTAP_RETVALUE = (int64_t) kread(&(tp->snd_ssthresh));\n\tCATCH_DEREF_FAULT();\n%}\n\n// Get receiver's advertised segment size.  TCP typically never sends more\n// than what receiver can accept.\nfunction tcp_ts_get_info_rcv_mss:long(sock:long)\n%{ /* pure */\n\tstruct sock *sk = (struct sock *)(uintptr_t) STAP_ARG_sock;\n#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)\n\tstruct tcp_opt *tp = tcp_sk(sk);\n\tSTAP_RETVALUE = (int64_t) kread(&(tp->ack.rcv_mss));\n#else\n\tconst struct inet_connection_sock *icsk = inet_csk(sk);\n\tSTAP_RETVALUE = (int64_t) kread(&(icsk->icsk_ack.rcv_mss));\n#endif\n\tCATCH_DEREF_FAULT();\n%}\n\n%{\n// Define newer IPv4 sockopt constants for older kernels.\n#ifndef TCP_CONGESTION\n#define TCP_CONGESTION 0\n#endif\n#ifndef TCP_MD5SIG\n#define TCP_MD5SIG 0\n#endif\n#ifndef TCP_COOKIE_TRANSACTIONS\n#define TCP_COOKIE_TRANSACTIONS 0\n#endif\n#ifndef TCP_THIN_LINEAR_TIMEOUTS\n#define TCP_THIN_LINEAR_TIMEOUTS 0\n#endif\n#ifndef TCP_THIN_DUPACK\n#define TCP_THIN_DUPACK 0\n#endif\n#ifndef TCP_USER_TIMEOUT\n#define TCP_USER_TIMEOUT 0\n#endif\n%}\n\n@__private30 global __sockopt[18]\nprobe init {\n\t__sockopt[@const(\"TCP_NODELAY\")] = \"TCP_NODELAY\"\n\t__sockopt[@const(\"TCP_MAXSEG\")] = \"TCP_MAXSEG\"\n\t__sockopt[@const(\"TCP_CORK\")] = \"TCP_CORK\"\n\t__sockopt[@const(\"TCP_KEEPIDLE\")] = \"TCP_KEEPIDLE\"\n\t__sockopt[@const(\"TCP_KEEPINTVL\")] = \"TCP_KEEPINTVL\"\n\t__sockopt[@const(\"TCP_KEEPCNT\")] = \"TCP_KEEPCNT\"\n\t__sockopt[@const(\"TCP_SYNCNT\")] = \"TCP_SYNCNT\"\n\t__sockopt[@const(\"TCP_LINGER2\")] = \"TCP_LINGER2\"\n\t__sockopt[@const(\"TCP_DEFER_ACCEPT\")] = \"TCP_DEFER_ACCEPT\"\n\t__sockopt[@const(\"TCP_WINDOW_CLAMP\")] = \"TCP_WINDOW_CLAMP\"\n\t__sockopt[@const(\"TCP_INFO\")] = \"TCP_INFO\"\n\t__sockopt[@const(\"TCP_QUICKACK\")] = \"TCP_QUICKACK\"\n\tif (@const(\"TCP_CONGESTION\") > 0)\n\t\t__sockopt[@const(\"TCP_CONGESTION\")]\n\t\t\t= \"TCP_CONGESTION\"\n\tif (@const(\"TCP_MD5SIG\") > 0)\n\t\t__sockopt[@const(\"TCP_MD5SIG\")] = \"TCP_MD5SIG\"\n\tif (@const(\"TCP_COOKIE_TRANSACTIONS\") > 0)\n\t\t__sockopt[@const(\"TCP_COOKIE_TRANSACTIONS\")]\n\t\t\t= \"TCP_COOKIE_TRANSACTIONS\"\n\tif (@const(\"TCP_THIN_LINEAR_TIMEOUTS\") > 0)\n\t\t__sockopt[@const(\"TCP_THIN_LINEAR_TIMEOUTS\")]\n\t\t\t= \"TCP_THIN_LINEAR_TIMEOUTS\"\n\tif (@const(\"TCP_THIN_DUPACK\") > 0)\n\t\t__sockopt[@const(\"TCP_THIN_DUPACK\")]\n\t\t\t= \"TCP_THIN_DUPACK\"\n\tif (@const(\"TCP_USER_TIMEOUT\") > 0)\n\t\t__sockopt[@const(\"TCP_USER_TIMEOUT\")]\n\t\t\t= \"TCP_USER_TIMEOUT\"\n}\n\nfunction tcp_sockopt_str:string (optname:long)\n{\n\treturn (optname in __sockopt ? __sockopt[optname]\n\t\t: sprintf(\"UNDEF_SOCKOPT(%d)\", optname))\n}\n\n%{\n// Define newer IPv6 sockopt constants for older kernels.\n#include <linux/in6.h>\n#ifndef IPV6_2292PKTINFO\n#define IPV6_2292PKTINFO 0\n#endif\n#ifndef IPV6_2292HOPOPTS\n#define IPV6_2292HOPOPTS 0\n#endif\n#ifndef IPV6_2292DSTOPTS\n#define IPV6_2292DSTOPTS 0\n#endif\n#ifndef IPV6_2292RTHDR\n#define IPV6_2292RTHDR 0\n#endif\n#ifndef IPV6_2292PKTOPTIONS\n#define IPV6_2292PKTOPTIONS 0\n#endif\n#ifndef IPV6_2292HOPLIMIT\n#define IPV6_2292HOPLIMIT 0\n#endif\n#ifndef IPV6_RECVPKTINFO\n#define IPV6_RECVPKTINFO 0\n#endif\n#ifndef IPV6_RECVHOPLIMIT\n#define IPV6_RECVHOPLIMIT 0\n#endif\n#ifndef IPV6_RECVHOPOPTS\n#define IPV6_RECVHOPOPTS 0\n#endif\n#ifndef IPV6_RTHDRDSTOPTS\n#define IPV6_RTHDRDSTOPTS 0\n#endif\n#ifndef IPV6_RECVRTHDR\n#define IPV6_RECVRTHDR 0\n#endif\n#ifndef IPV6_RECVDSTOPTS\n#define IPV6_RECVDSTOPTS 0\n#endif\n#ifndef IPV6_RECVPATHMTU\n#define IPV6_RECVPATHMTU 0\n#endif\n#ifndef IPV6_PATHMTU\n#define IPV6_PATHMTU 0\n#endif\n#ifndef IPV6_DONTFRAG\n#define IPV6_DONTFRAG 0\n#endif\n#ifndef IPV6_ADDR_PREFERENCES\n#define IPV6_ADDR_PREFERENCES 0\n#endif\n#ifndef IPV6_MINHOPCOUNT\n#define IPV6_MINHOPCOUNT 0\n#endif\n#ifndef IPV6_RECVORIGDSTADDR\n#define IPV6_RECVORIGDSTADDR 0\n#endif\n#ifndef IPV6_TRANSPARENT\n#define IPV6_TRANSPARENT 0\n#endif\n%}\n\n@__private30 global __ipv6_sockopt[55]\nprobe init {\n\t__ipv6_sockopt[@const(\"IPV6_ADDRFORM\")] = \"IPV6_ADDRFORM\"\n\tif (@const(\"IPV6_2292PKTINFO\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_2292PKTINFO\")]\n\t\t\t= \"IPV6_2292PKTINFO\"\n\tif (@const(\"IPV6_2292HOPOPTS\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_2292HOPOPTS\")]\n\t\t\t= \"IPV6_2292HOPOPTS\"\n\tif (@const(\"IPV6_2292DSTOPTS\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_2292DSTOPTS\")]\n\t\t\t= \"IPV6_2292DSTOPTS\"\n\tif (@const(\"IPV6_2292RTHDR\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_2292RTHDR\")]\n\t\t\t= \"IPV6_2292RTHDR\"\n\tif (@const(\"IPV6_2292PKTOPTIONS\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_2292PKTOPTIONS\")]\n\t\t\t= \"IPV6_2292PKTOPTIONS\"\n\t__ipv6_sockopt[@const(\"IPV6_CHECKSUM\")] = \"IPV6_CHECKSUM\"\n\tif (@const(\"IPV6_2292HOPLIMIT\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_2292HOPLIMIT\")]\n\t\t\t= \"IPV6_2292HOPLIMIT\"\n\t__ipv6_sockopt[@const(\"IPV6_NEXTHOP\")] = \"IPV6_NEXTHOP\"\n\t__ipv6_sockopt[@const(\"IPV6_AUTHHDR\")] = \"IPV6_AUTHHDR\"\n\t__ipv6_sockopt[@const(\"IPV6_FLOWINFO\")] = \"IPV6_FLOWINFO\"\n\t__ipv6_sockopt[@const(\"IPV6_UNICAST_HOPS\")]\n\t\t= \"IPV6_UNICAST_HOPS\"\n\t__ipv6_sockopt[@const(\"IPV6_MULTICAST_IF\")]\n\t\t= \"IPV6_MULTICAST_IF\"\n\t__ipv6_sockopt[@const(\"IPV6_MULTICAST_HOPS\")]\n\t\t= \"IPV6_MULTICAST_HOPS\"\n\t__ipv6_sockopt[@const(\"IPV6_MULTICAST_LOOP\")]\n\t\t= \"IPV6_MULTICAST_LOOP\"\n\t__ipv6_sockopt[@const(\"IPV6_ADD_MEMBERSHIP\")]\n\t\t= \"IPV6_ADD_MEMBERSHIP\"\n\t__ipv6_sockopt[@const(\"IPV6_DROP_MEMBERSHIP\")]\n\t\t= \"IPV6_DROP_MEMBERSHIP\"\n\t__ipv6_sockopt[@const(\"IPV6_ROUTER_ALERT\")]\n\t\t= \"IPV6_ROUTER_ALERT\"\n\t__ipv6_sockopt[@const(\"IPV6_MTU_DISCOVER\")]\n\t\t= \"IPV6_MTU_DISCOVER\"\n\t__ipv6_sockopt[@const(\"IPV6_MTU\")] = \"IPV6_MTU\"\n\t__ipv6_sockopt[@const(\"IPV6_RECVERR\")] = \"IPV6_RECVERR\"\n\t__ipv6_sockopt[@const(\"IPV6_V6ONLY\")] = \"IPV6_V6ONLY\"\n\t__ipv6_sockopt[@const(\"IPV6_JOIN_ANYCAST\")]\n\t\t= \"IPV6_JOIN_ANYCAST\"\n\t__ipv6_sockopt[@const(\"IPV6_LEAVE_ANYCAST\")]\n\t\t= \"IPV6_LEAVE_ANYCAST\"\n\t__ipv6_sockopt[@const(\"IPV6_FLOWLABEL_MGR\")]\n\t\t= \"IPV6_FLOWLABEL_MGR\"\n\t__ipv6_sockopt[@const(\"IPV6_FLOWINFO_SEND\")]\n\t\t= \"IPV6_FLOWINFO_SEND\"\n\t__ipv6_sockopt[@const(\"IPV6_IPSEC_POLICY\")]\n\t\t= \"IPV6_IPSEC_POLICY\"\n\t__ipv6_sockopt[@const(\"IPV6_XFRM_POLICY\")]\n\t\t= \"IPV6_XFRM_POLICY\"\n\t__ipv6_sockopt[@const(\"MCAST_JOIN_GROUP\")]\n\t\t= \"MCAST_JOIN_GROUP\"\n\t__ipv6_sockopt[@const(\"MCAST_BLOCK_SOURCE\")]\n\t\t= \"MCAST_BLOCK_SOURCE\"\n\t__ipv6_sockopt[@const(\"MCAST_UNBLOCK_SOURCE\")]\n\t\t= \"MCAST_UNBLOCK_SOURCE\"\n\t__ipv6_sockopt[@const(\"MCAST_LEAVE_GROUP\")]\n\t\t= \"MCAST_LEAVE_GROUP\"\n\t__ipv6_sockopt[@const(\"MCAST_JOIN_SOURCE_GROUP\")]\n\t\t= \"MCAST_JOIN_SOURCE_GROUP\"\n\t__ipv6_sockopt[@const(\"MCAST_LEAVE_SOURCE_GROUP\")]\n\t\t= \"MCAST_LEAVE_SOURCE_GROUP\"\n\t__ipv6_sockopt[@const(\"MCAST_MSFILTER\")] = \"MCAST_MSFILTER\"\n\tif (@const(\"IPV6_RECVPKTINFO\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_RECVPKTINFO\")]\n\t\t\t= \"IPV6_RECVPKTINFO\"\n\t__ipv6_sockopt[@const(\"IPV6_PKTINFO\")] = \"IPV6_PKTINFO\"\n\tif (@const(\"IPV6_RECVHOPLIMIT\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_RECVHOPLIMIT\")]\n\t\t\t= \"IPV6_RECVHOPLIMIT\"\n\t__ipv6_sockopt[@const(\"IPV6_HOPLIMIT\")] = \"IPV6_HOPLIMIT\"\n\tif (@const(\"IPV6_RECVHOPOPTS\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_RECVHOPOPTS\")]\n\t\t\t= \"IPV6_RECVHOPOPTS\"\n\t__ipv6_sockopt[@const(\"IPV6_HOPOPTS\")] = \"IPV6_HOPOPTS\"\n\tif (@const(\"IPV6_RTHDRDSTOPTS\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_RTHDRDSTOPTS\")]\n\t\t\t= \"IPV6_RTHDRDSTOPTS\"\n\tif (@const(\"IPV6_RECVRTHDR\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_RECVRTHDR\")]\n\t\t\t= \"IPV6_RECVRTHDR\"\n\t__ipv6_sockopt[@const(\"IPV6_RTHDR\")] = \"IPV6_RTHDR\"\n\tif (@const(\"IPV6_RECVDSTOPTS\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_RECVDSTOPTS\")]\n\t\t\t= \"IPV6_RECVDSTOPTS\"\n\t__ipv6_sockopt[@const(\"IPV6_DSTOPTS\")] = \"IPV6_DSTOPTS\"\n\tif (@const(\"IPV6_RECVPATHMTU\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_RECVPATHMTU\")]\n\t\t\t= \"IPV6_RECVPATHMTU\"\n\tif (@const(\"IPV6_PATHMTU\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_PATHMTU\")]\n\t\t\t= \"IPV6_PATHMTU\"\n\tif (@const(\"IPV6_DONTFRAG\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_DONTFRAG\")]\n\t\t\t= \"IPV6_DONTFRAG\"\n\t__ipv6_sockopt[@const(\"IPV6_RECVTCLASS\")]\n\t\t= \"IPV6_RECVTCLASS\"\n\t__ipv6_sockopt[@const(\"IPV6_TCLASS\")] = \"IPV6_TCLASS\"\n\tif (@const(\"IPV6_ADDR_PREFERENCES\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_ADDR_PREFERENCES\")]\n\t\t\t= \"IPV6_ADDR_PREFERENCES\"\n\tif (@const(\"IPV6_MINHOPCOUNT\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_MINHOPCOUNT\")]\n\t\t\t= \"IPV6_MINHOPCOUNT\"\n\tif (@const(\"IPV6_RECVORIGDSTADDR\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_RECVORIGDSTADDR\")]\n\t\t\t= \"IPV6_RECVORIGDSTADDR\"\n\tif (@const(\"IPV6_TRANSPARENT\") > 0)\n\t\t__ipv6_sockopt[@const(\"IPV6_TRANSPARENT\")]\n\t\t\t= \"IPV6_TRANSPARENT\"\n}\n\nfunction tcp_ipv6_sockopt_str:string (optname:long)\n{\n\treturn (optname in __ipv6_sockopt ? __ipv6_sockopt[optname]\n\t\t: sprintf(\"UNDEF_SOCKOPT(%d)\", optname))\n}\n\n/**\n  * probe tcp.sendmsg - Sending a tcp message\n  * @name: Name of this probe\n  * @sock: Network socket \n  * @family: IP address family\n  * @size: Number of bytes to send  \n  *\n  * Context:\n  *  The process which sends a tcp message \n  */\nprobe tcp.sendmsg = kernel.function(\"tcp_sendmsg\") {\n\tname = \"tcp.sendmsg\"\n\tsock = (@defined($sock) ? $sock->sk : $sk)\n\tfamily  = __ip_sock_family(@defined($sock) ? $sock->sk : $sk)\n\tsize = $size\n}\n\n/**\n * probe tcp.sendmsg.return -  Sending TCP message is done\n * @name: Name of this probe\n * @size: Number of bytes sent or error code if an error occurred. \n *\n * Context:\n *  The process which sends a tcp message\n */\nprobe tcp.sendmsg.return = kernel.function(\"tcp_sendmsg\").return {\n\tname = \"tcp.sendmsg\"\n\tsize = $return \n}\n\n/**\n * probe tcp.recvmsg - Receiving TCP message\n * @name: Name of this probe\n * @sock: Network socket\n * @size: Number of bytes to be received  \n * @family: IP address family\n * @saddr: A string representing the source IP address\n * @daddr: A string representing the destination IP address\n * @sport: TCP source port \n * @dport: TCP destination port\n * Context:\n *  The process which receives a tcp message\n */\nprobe tcp.recvmsg = kernel.function(\"tcp_recvmsg\") {\n\tname = \"tcp.recvmsg\"\n\tsock    = $sk\n\tsize    = $len\n\tfamily  = __ip_sock_family($sk)\n\tsaddr   = format_ipaddr(__ip_sock_saddr($sk), __ip_sock_family($sk))\n\tdaddr   = format_ipaddr(__ip_sock_daddr($sk), __ip_sock_family($sk))\n\tsport   = __tcp_sock_sport($sk)\n\tdport   = __tcp_sock_dport($sk)\n}\n\n/**\n * probe tcp.recvmsg.return - Receiving TCP message complete\n * @name: Name of this probe\n * @size: Number of bytes received or error code if an error occurred.\n * @family: IP address family\n * @saddr: A string representing the source IP address\n * @daddr: A string representing the destination IP address\n * @sport: TCP source port \n * @dport: TCP destination port\n *\n * Context:\n *  The process which receives a tcp message\n */\nprobe tcp.recvmsg.return = kernel.function(\"tcp_recvmsg\").return {\n\tname = \"tcp.recvmsg\"\n\tsize = $return\n\tfamily  = __ip_sock_family(@entry($sk))\n\tsaddr   = format_ipaddr(__ip_sock_saddr(@entry($sk)), __ip_sock_family(@entry($sk)))\n\tdaddr   = format_ipaddr(__ip_sock_daddr(@entry($sk)), __ip_sock_family(@entry($sk)))\n\tsport = __tcp_sock_sport(@entry($sk))\n\tdport = __tcp_sock_dport(@entry($sk))\n}\n\n/**\n * probe tcp.disconnect - TCP socket disconnection\n * @name: Name of this probe\n * @sock: Network socket \n * @family: IP address family\n * @flags: TCP flags (e.g. FIN, etc)  \n * @saddr: A string representing the source IP address\n * @daddr: A string representing the destination IP address\n * @sport: TCP source port \n * @dport: TCP destination port\n *\n * Context:\n *  The process which disconnects tcp \n */\nprobe tcp.disconnect = kernel.function(\"tcp_disconnect\") {\n\tname = \"tcp.disconnect\"\n\tsock  = $sk\n\tfamily = __ip_sock_family($sk)\n\tflags = $flags\n\tsaddr   = format_ipaddr(__ip_sock_saddr($sk), __ip_sock_family($sk))\n\tdaddr   = format_ipaddr(__ip_sock_daddr($sk), __ip_sock_family($sk))\n\tsport = __tcp_sock_sport($sk)\n\tdport = __tcp_sock_dport($sk)\n}\n\n/**\n * probe tcp.disconnect.return - TCP socket disconnection complete\n * @name: Name of this probe\n * @ret: Error code (0: no error) \n *\n * Context:\n *  The process which disconnects tcp\n */\nprobe tcp.disconnect.return = kernel.function(\"tcp_disconnect\").return {\n\tname = \"tcp.disconnect\"\n\tret = $return \n}\n\n/**\n * probe tcp.setsockopt - Call to setsockopt()\n * @name: Name of this probe\n * @sock: Network socket\n * @family: IP address family\n * @level: The level at which the socket options will be manipulated\n * @optname: TCP socket options (e.g. TCP_NODELAY, TCP_MAXSEG, etc)\n * @optstr: Resolves optname to a human-readable format\n * @optlen: Used to access values for setsockopt()\n *\n * Context:\n *  The process which calls setsockopt\n */\nprobe tcp.setsockopt = tcp.ipv4.setsockopt, tcp.ipv6.setsockopt\n{\n}\nprobe tcp.ipv4.setsockopt = kernel.function(\"tcp_setsockopt\")\n{\n\tname = \"tcp.ipv4.setsockopt\"\n\tsock = $sk\n\tfamily  = __ip_sock_family($sk)\n\tlevel = $level\n\toptname = $optname\n\toptstr = tcp_sockopt_str($optname)\n\toptlen = $optlen\n}\nprobe tcp.ipv6.setsockopt = kernel.function(\"ipv6_setsockopt\")!,\n\tmodule(\"ipv6\").function(\"ipv6_setsockopt\")\n{\n\tname = \"tcp.ipv6.setsockopt\"\n\tsock = $sk\n\tfamily  = __ip_sock_family($sk)\n\tlevel = $level\n\toptname = $optname\n\toptstr = tcp_ipv6_sockopt_str($optname)\n\toptlen = $optlen\n}\n\n/**\n * probe tcp.setsockopt.return -  Return from setsockopt()\n * @name: Name of this probe\n * @ret: Error code (0: no error)\n *\n * Context:\n *  The process which calls setsockopt\n */\nprobe tcp.setsockopt.return = tcp.ipv4.setsockopt.return,\n\ttcp.ipv6.setsockopt.return\n{\n}\nprobe tcp.ipv4.setsockopt.return = kernel.function(\"tcp_setsockopt\").return\n{\n\tname = \"tcp.ipv4.setsockopt\"\n\tret = $return\n}\nprobe tcp.ipv6.setsockopt.return = kernel.function(\"ipv6_setsockopt\").return!,\n\tmodule(\"ipv6\").function(\"ipv6_setsockopt\").return\n{\n\tname = \"tcp.ipv6.setsockopt\"\n\tret = $return\n}\n\n/**\n * probe tcp.receive - Called when a TCP packet is received\n * @name: Name of the probe point\n * @iphdr: IP header address\n * @protocol: Packet protocol from driver\n * @family: IP address family\n * @saddr: A string representing the source IP address\n * @daddr: A string representing the destination IP address\n * @sport: TCP source port\n * @dport: TCP destination port\n * @urg: TCP URG flag\n * @ack: TCP ACK flag\n * @psh: TCP PSH flag\n * @rst: TCP RST flag\n * @syn: TCP SYN flag\n * @fin: TCP FIN flag\n */\nprobe tcp.receive = tcp.ipv4.receive, tcp.ipv6.receive\n{\n}\n\nprobe tcp.ipv4.receive = kernel.function(\"tcp_v4_rcv\")\n{\n\tname = \"tcp.ipv4.receive\"\n\t# If we're here, by definition we're doing AF_INET, not AF_INET6.\n\tfamily = @const(\"AF_INET\")\n\ttry {\n\t  iphdr = __get_skb_iphdr($skb)\n\t  saddr = format_ipaddr(__ip_skb_saddr(iphdr), @const(\"AF_INET\"))\n\t  daddr = format_ipaddr(__ip_skb_daddr(iphdr), @const(\"AF_INET\"))\n\t  protocol = __ip_skb_proto(iphdr)\n\t} catch { }\n\n\ttry {\n\t  tcphdr = __get_skb_tcphdr($skb)\n\t  dport = __tcp_skb_dport(tcphdr)\n\t  sport = __tcp_skb_sport(tcphdr)\n\t  urg = __tcp_skb_urg(tcphdr)\n\t  ack = __tcp_skb_ack(tcphdr)\n\t  psh = __tcp_skb_psh(tcphdr)\n\t  rst = __tcp_skb_rst(tcphdr)\n\t  syn = __tcp_skb_syn(tcphdr)\n\t  fin = __tcp_skb_fin(tcphdr)\n\t} catch { }\n}\n\nprobe tcp.ipv6.receive = kernel.function(\"tcp_v6_rcv\")!,\n\tmodule(\"ipv6\").function(\"tcp_v6_rcv\")\n{\n\tname = \"tcp.ipv6.receive\"\n\t# If we're here, by definition we're doing AF_INET6, not AF_INET.\n\tfamily = @const(\"AF_INET6\")\n\ttry {\n\t  iphdr = __get_skb_iphdr(@choose_defined($skb, kernel_pointer($pskb)))\n\t  saddr = format_ipaddr(&@cast(iphdr, \"ipv6hdr\",\n\t\t\t\t       \"kernel<linux/ipv6.h>\")->saddr,\n\t\t\t\t@const(\"AF_INET6\"))\n\t  daddr = format_ipaddr(&@cast(iphdr, \"ipv6hdr\",\n\t\t\t\t       \"kernel<linux/ipv6.h>\")->daddr,\n\t\t\t\t@const(\"AF_INET6\"))\n\t} catch { }\n\n\t# If we're here, by definition we're doing IPPROTO_TCP.  There\n\t# isn't a protocol field in 'struct ipv6hdr'.  There is one in\n\t# 'struct sk_buff', but that protocol field is an Ethernet\n\t# Procol ID (ETH_P_*), not an IP protocol ID (IPPROTO_*).\n\tprotocol = @const(\"IPPROTO_TCP\")\n\n\ttry {\n\t  tcphdr = __get_skb_tcphdr(@choose_defined($skb,\n\t\t\t\t    kernel_pointer($pskb)))\n\t  dport = __tcp_skb_dport(tcphdr)\n\t  sport = __tcp_skb_sport(tcphdr)\n\t  urg = __tcp_skb_urg(tcphdr)\n\t  ack = __tcp_skb_ack(tcphdr)\n\t  psh = __tcp_skb_psh(tcphdr)\n\t  rst = __tcp_skb_rst(tcphdr)\n\t  syn = __tcp_skb_syn(tcphdr)\n\t  fin = __tcp_skb_fin(tcphdr)\n\t} catch { }\n}\n"
  },
  {
    "path": "Units/parser-systemtap.r/vars.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-systemtap.r/vars.d/expected.tags",
    "content": "A\tinput.stp\t/^private global A$/;\"\tv\na\tinput.stp\t/^global a%[10], b[10], c%[10], d = \"[\", e = 3, f = \"]\"$/;\"\tv\nb\tinput.stp\t/^global a%[10], b[10], c%[10], d = \"[\", e = 3, f = \"]\"$/;\"\tv\nc\tinput.stp\t/^global a%[10], b[10], c%[10], d = \"[\", e = 3, f = \"]\"$/;\"\tv\nd\tinput.stp\t/^global a%[10], b[10], c%[10], d = \"[\", e = 3, f = \"]\"$/;\"\tv\ne\tinput.stp\t/^global a%[10], b[10], c%[10], d = \"[\", e = 3, f = \"]\"$/;\"\tv\nf\tinput.stp\t/^global a%[10], b[10], c%[10], d = \"[\", e = 3, f = \"]\"$/;\"\tv\nB\tinput.stp\t/^@__private30 global B$/;\"\tv\n"
  },
  {
    "path": "Units/parser-systemtap.r/vars.d/input.stp",
    "content": "private global A\nglobal a%[10], b[10], c%[10], d = \"[\", e = 3, f = \"]\"\n@__private30 global B\n"
  },
  {
    "path": "Units/parser-tcl.r/comments.tcl.d/args.ctags",
    "content": "--sort=no\n--fields=+neKl\n\n"
  },
  {
    "path": "Units/parser-tcl.r/comments.tcl.d/expected.tags",
    "content": "f1\tinput.tcl\t/^proc f1 {} {$/;\"\tprocedure\tline:1\tlanguage:Tcl\tend:3\nf2\tinput.tcl\t/^proc f2 {} {puts \"hello\"} ; # proc g3 {} {    puts \"hello\"}$/;\"\tprocedure\tline:7\tlanguage:Tcl\tend:7\nf3\tinput.tcl\t/^proc f3 {} {puts \"hello\"} proc g4 {} {    puts \"hello\"}$/;\"\tprocedure\tline:8\tlanguage:Tcl\tend:8\nf4\tinput.tcl\t/^proc f4 {} {puts \"hello\" # proc g5 {} {    puts \"hello\"}$/;\"\tprocedure\tline:9\tlanguage:Tcl\tend:11\nf5\tinput.tcl\t/^} proc g7 {} {    puts \"hello\"} { } # proc g8 {} {} ; proc f5 {} { puts \"hello\"\\\\$/;\"\tprocedure\tline:11\tlanguage:Tcl\tend:12\n"
  },
  {
    "path": "Units/parser-tcl.r/comments.tcl.d/input.tcl",
    "content": "proc f1 {} {\n    puts \"hello\"\n}\n# proc g0 {} {    puts \"hello\"}\n     # proc g1 {} {    puts \"hello\"}\n\nproc f2 {} {puts \"hello\"} ; # proc g3 {} {    puts \"hello\"}\nproc f3 {} {puts \"hello\"} proc g4 {} {    puts \"hello\"}\nproc f4 {} {puts \"hello\" # proc g5 {} {    puts \"hello\"}\n# proc g6 {} {    puts \"hello\"}\n} proc g7 {} {    puts \"hello\"} { } # proc g8 {} {} ; proc f5 {} { puts \"hello\"\\\n } # proc g9 {}\n"
  },
  {
    "path": "Units/parser-tcl.r/dollar-in-regex.d/expected.tags",
    "content": "proc1\tinput.tcl\t/^proc proc1 {} {$/;\"\tp\nproc2\tinput.tcl\t/^proc proc2 {} {}$/;\"\tp\nproc3\tinput.tcl\t/^proc proc3 {} {$/;\"\tp\nproc4\tinput.tcl\t/^proc proc4 {} {}$/;\"\tp\n"
  },
  {
    "path": "Units/parser-tcl.r/dollar-in-regex.d/input.tcl",
    "content": "# Taken from #2627 submitted by @surmish\nproc proc1 {} {\n  if {[regexp {[0-9]$} \"\"]} {\n    echo \"matched\"\n  }\n}\n\nproc proc2 {} {}\n\nproc proc3 {} {\n    set abc \"hello\"\n    puts ${abc}\n}\n\nproc proc4 {} {}\n\nproc3\n"
  },
  {
    "path": "Units/parser-tcl.r/duplication-tags-in-autofq.d/args.ctags",
    "content": "--extras=+q\n--sort=no\n--fields=+E\n--_scopesep-Tcl=/p:@\n--_scopesep-Tcl=/n:#\n--_scopesep-Tcl=n/p:+\n"
  },
  {
    "path": "Units/parser-tcl.r/duplication-tags-in-autofq.d/expected.tags",
    "content": "pr0\tinput.tcl\t/^proc ::pr0 {s} {$/;\"\tp\n@pr0\tinput.tcl\t/^proc ::pr0 {s} {$/;\"\tp\textras:qualified\nN\tinput.tcl\t/^namespace eval N {$/;\"\tn\n#N\tinput.tcl\t/^namespace eval N {$/;\"\tn\textras:qualified\npr1\tinput.tcl\t/^    proc pr1 {s} {$/;\"\tp\tnamespace:#N\n#N+pr1\tinput.tcl\t/^    proc pr1 {s} {$/;\"\tp\tnamespace:#N\textras:qualified\n"
  },
  {
    "path": "Units/parser-tcl.r/duplication-tags-in-autofq.d/input.tcl",
    "content": "proc ::pr0 {s} {\n    puts \"$s\"\n}\n\nnamespace eval N {\n    proc pr1 {s} {\n\tputs \"$s\"\n    }\n}\n"
  },
  {
    "path": "Units/parser-tcl.r/end-of-cmdline.d/expected.tags",
    "content": "a\tinput.tcl\t/^proc a {} {$/;\"\tp\nb\tinput.tcl\t/^proc b {} {}; proc c {} {$/;\"\tp\nc\tinput.tcl\t/^proc b {} {}; proc c {} {$/;\"\tp\nd\tinput.tcl\t/^}; proc d {} {$/;\"\tp\ne\tinput.tcl\t/^}; proc e {} {};;;$/;\"\tp\nf\tinput.tcl\t/^proc f {} {};;;;;;;; a \\\\$/;\"\tp\ng\tinput.tcl\t/^    ; proc g {}  {} ; \\\\$/;\"\tp\nh\tinput.tcl\t/^    proc h {} {}$/;\"\tp\n"
  },
  {
    "path": "Units/parser-tcl.r/end-of-cmdline.d/input.tcl",
    "content": "proc a {} {\n}\n\nproc b {} {}; proc c {} {\n}; proc d {} {\n\n\n\n}; proc e {} {};;;\nproc f {} {};;;;;;;; a \\\n    ; proc g {}  {} ; \\\n    proc h {} {}\n\n"
  },
  {
    "path": "Units/parser-tcl.r/escaping.d/expected.tags",
    "content": "a\tinput-0.tcl\t/^proc a {} {set quotedText a\\\\\"}$/;\"\tp\nb\tinput-0.tcl\t/^proc b {} {}$/;\"\tp\nproc1\tinput.tcl\t/^proc proc1 {} {$/;\"\tp\nproc2\tinput.tcl\t/^proc proc2  {} {}$/;\"\tp\n"
  },
  {
    "path": "Units/parser-tcl.r/escaping.d/input-0.tcl",
    "content": "proc a {} {set quotedText a\\\"}\nproc b {} {}\n# Taken from the issue #4283 submitted by @torstenberg.\n"
  },
  {
    "path": "Units/parser-tcl.r/escaping.d/input.tcl",
    "content": "# Taken from a comment in #2627 submitted by @surmish.\nproc proc1 {} {\n  expr {[string first \"\\\\\" $varName]==0}\n}\n\nproc proc2  {} {}\n"
  },
  {
    "path": "Units/parser-tcl.r/namespace-disabled.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--fields=+eE\n--kinds-Tcl=-n\n"
  },
  {
    "path": "Units/parser-tcl.r/namespace-disabled.d/expected.tags",
    "content": "pr1\tinput.tcl\t/^    proc pr1 {s} {$/;\"\tp\tnamespace:::A\tend:7\n::A::pr1\tinput.tcl\t/^    proc pr1 {s} {$/;\"\tp\tnamespace:::A\textras:qualified\tend:7\npr2\tinput.tcl\t/^    proc B::pr2 {s} {$/;\"\tp\tnamespace:B\tend:11\nB::pr2\tinput.tcl\t/^    proc B::pr2 {s} {$/;\"\tp\textras:qualified\tend:11\npr3\tinput.tcl\t/^\tproc pr3 {s} {$/;\"\tp\tnamespace:::A::C\tend:15\n::A::C::pr3\tinput.tcl\t/^\tproc pr3 {s} {$/;\"\tp\tnamespace:::A::C\textras:qualified\tend:15\npr4\tinput.tcl\t/^    proc ::pr4 {s} {$/;\"\tp\tend:19\n::pr4\tinput.tcl\t/^    proc ::pr4 {s} {$/;\"\tp\textras:qualified\tend:19\npr5\tinput.tcl\t/^proc ::pr5 {s} {$/;\"\tp\tend:25\n::pr5\tinput.tcl\t/^proc ::pr5 {s} {$/;\"\tp\textras:qualified\tend:25\npr6\tinput.tcl\t/^proc pr6 {s} {$/;\"\tp\tend:29\n::pr6\tinput.tcl\t/^proc pr6 {s} {$/;\"\tp\textras:qualified\tend:29\n"
  },
  {
    "path": "Units/parser-tcl.r/namespace-disabled.d/input.tcl",
    "content": "namespace eval A::B {\n}\n\nnamespace eval A {\n    proc pr1 {s} {\n\tputs $s\n    }\n    pr1 \"a\"\n    proc B::pr2 {s} {\n\tputs \"$s\"\n    }\n    namespace eval C {\n\tproc pr3 {s} {\n\t    puts $s\n\t}\n    }\n    proc ::pr4 {s} {\n\tputs \"$s\"\n    }\n\n}\n\nproc ::pr5 {s} {\n    puts \"$s\"\n}\n\nproc pr6 {s} {\n    puts \"$s\"\n}\n\nA::pr1 \"b\"\n\nA::B::pr2 \"c\"\n\nA::C::pr3 \"d\"\n\npr4 \"e\"\n\npr5 \"f\"\n\npr6 \"g\"\n"
  },
  {
    "path": "Units/parser-tcl.r/namespace.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n--fields=+eE\n"
  },
  {
    "path": "Units/parser-tcl.r/namespace.d/expected.tags",
    "content": "A::B\tinput.tcl\t/^namespace eval A::B {$/;\"\tn\tend:2\n::A::B\tinput.tcl\t/^namespace eval A::B {$/;\"\tn\textras:qualified\tend:2\nA\tinput.tcl\t/^namespace eval A {$/;\"\tn\tend:21\n::A\tinput.tcl\t/^namespace eval A {$/;\"\tn\textras:qualified\tend:21\npr1\tinput.tcl\t/^    proc pr1 {s} {$/;\"\tp\tnamespace:::A\tend:7\n::A::pr1\tinput.tcl\t/^    proc pr1 {s} {$/;\"\tp\tnamespace:::A\textras:qualified\tend:7\npr2\tinput.tcl\t/^    proc B::pr2 {s} {$/;\"\tp\tnamespace:B\tend:11\nB::pr2\tinput.tcl\t/^    proc B::pr2 {s} {$/;\"\tp\textras:qualified\tend:11\nC\tinput.tcl\t/^    namespace eval C {$/;\"\tn\tnamespace:::A\tend:16\n::A::C\tinput.tcl\t/^    namespace eval C {$/;\"\tn\tnamespace:::A\textras:qualified\tend:16\npr3\tinput.tcl\t/^\tproc pr3 {s} {$/;\"\tp\tnamespace:::A::C\tend:15\n::A::C::pr3\tinput.tcl\t/^\tproc pr3 {s} {$/;\"\tp\tnamespace:::A::C\textras:qualified\tend:15\npr4\tinput.tcl\t/^    proc ::pr4 {s} {$/;\"\tp\tend:19\n::pr4\tinput.tcl\t/^    proc ::pr4 {s} {$/;\"\tp\textras:qualified\tend:19\npr5\tinput.tcl\t/^proc ::pr5 {s} {$/;\"\tp\tend:25\n::pr5\tinput.tcl\t/^proc ::pr5 {s} {$/;\"\tp\textras:qualified\tend:25\npr6\tinput.tcl\t/^proc pr6 {s} {$/;\"\tp\tend:29\n::pr6\tinput.tcl\t/^proc pr6 {s} {$/;\"\tp\textras:qualified\tend:29\n"
  },
  {
    "path": "Units/parser-tcl.r/namespace.d/input.tcl",
    "content": "namespace eval A::B {\n}\n\nnamespace eval A {\n    proc pr1 {s} {\n\tputs $s\n    }\n    pr1 \"a\"\n    proc B::pr2 {s} {\n\tputs \"$s\"\n    }\n    namespace eval C {\n\tproc pr3 {s} {\n\t    puts $s\n\t}\n    }\n    proc ::pr4 {s} {\n\tputs \"$s\"\n    }\n\n}\n\nproc ::pr5 {s} {\n    puts \"$s\"\n}\n\nproc pr6 {s} {\n    puts \"$s\"\n}\n\nA::pr1 \"b\"\n\nA::B::pr2 \"c\"\n\nA::C::pr3 \"d\"\n\npr4 \"e\"\n\npr5 \"f\"\n\npr6 \"g\"\n"
  },
  {
    "path": "Units/parser-tcl.r/nulltags.d/args.ctags",
    "content": "--sort=no\n--extras=+{nulltag}\n--_xformat=%-16N %-10K %4n %-16F %C %{scopeKind}:%{scope}\n"
  },
  {
    "path": "Units/parser-tcl.r/nulltags.d/expected.tags-x",
    "content": "                 procedure     1 input.tcl proc {} {} {return Empty } :\naaa              procedure     2 input.tcl proc aaa {} {return Normal} :\na                procedure     4 input.tcl proc {a} {} {return Braced} :\nns1              namespace     6 input.tcl namespace eval ns1 { :\n                 procedure     7 input.tcl proc {} {} {return Empty } namespace:::ns1\nbbb              procedure     8 input.tcl proc bbb {} {return Normal} namespace:::ns1\nb                procedure     9 input.tcl proc {b} {} {return Braced} namespace:::ns1\nns2              namespace    12 input.tcl namespace eval ns2 :\n                 procedure    13 input.tcl proc ns2:: {} {return Empty } namespace:ns2\nccc              procedure    14 input.tcl proc ns2::ccc {} {return Normal} namespace:ns2\nc                procedure    15 input.tcl proc {ns2::c} {} {return Braced} namespace:ns2\n                 procedure    17 input.tcl proc :: {} {return \"Empty at Root NS\"} :\n"
  },
  {
    "path": "Units/parser-tcl.r/nulltags.d/input.tcl",
    "content": "proc {}  {} {return Empty }\nproc aaa {} {return Normal}\n\nproc {a} {} {return Braced}\n\nnamespace eval ns1 {\n\tproc {}  {} {return Empty }\n\tproc bbb {} {return Normal}\n\tproc {b} {} {return Braced}\n}\n\nnamespace eval ns2\nproc ns2::    {} {return Empty }\nproc ns2::ccc {} {return Normal}\nproc {ns2::c} {} {return Braced}\n\nproc :: {} {return \"Empty at Root NS\"}\n"
  },
  {
    "path": "Units/parser-tcl.r/prefixed-proc.d/args.ctags",
    "content": "--extras=+q\n"
  },
  {
    "path": "Units/parser-tcl.r/prefixed-proc.d/expected.tags",
    "content": "proc1\tinput.tcl\t/^proc sScope::proc1 {} {}$/;\"\tp\tnamespace:sScope\nsScope::proc1\tinput.tcl\t/^proc sScope::proc1 {} {}$/;\"\tp\n"
  },
  {
    "path": "Units/parser-tcl.r/prefixed-proc.d/input.tcl",
    "content": "# Taken from https://github.com/universal-ctags/ctags/issues/2624\n# submitted by @surmish\nproc sScope::proc1 {} {}\n"
  },
  {
    "path": "Units/parser-tcl.r/signature.d/args.ctags",
    "content": "--sort=no\n--kinds-Tcl=+z\n--fields=+So\n--extras=+q\n"
  },
  {
    "path": "Units/parser-tcl.r/signature.d/expected.tags",
    "content": "fn\tinput.tcl\t/^proc fn a {$/;\"\tp\tsignature:a\n::fn\tinput.tcl\t/^proc fn a {$/;\"\tp\tsignature:a\na\tinput.tcl\t/^proc fn a {$/;\"\tz\tprocedure:::fn\n::fn{a\tinput.tcl\t/^proc fn a {$/;\"\tz\tprocedure:::fn\nf11\tinput.tcl\t/^proc f11 {a} {$/;\"\tp\tsignature:{a}\n::f11\tinput.tcl\t/^proc f11 {a} {$/;\"\tp\tsignature:{a}\na\tinput.tcl\t/^proc f11 {a} {$/;\"\tz\tprocedure:::f11\tnth:0\n::f11{a\tinput.tcl\t/^proc f11 {a} {$/;\"\tz\tprocedure:::f11\tnth:0\nf10\tinput.tcl\t/^proc f10 {{a 0}} {$/;\"\tp\tsignature:{{a 0}}\n::f10\tinput.tcl\t/^proc f10 {{a 0}} {$/;\"\tp\tsignature:{{a 0}}\na\tinput.tcl\t/^proc f10 {{a 0}} {$/;\"\tz\tprocedure:::f10\tnth:0\n::f10{a\tinput.tcl\t/^proc f10 {{a 0}} {$/;\"\tz\tprocedure:::f10\tnth:0\ng1121\tinput.tcl\t/^proc g1121 {a b} {$/;\"\tp\tsignature:{a b}\n::g1121\tinput.tcl\t/^proc g1121 {a b} {$/;\"\tp\tsignature:{a b}\na\tinput.tcl\t/^proc g1121 {a b} {$/;\"\tz\tprocedure:::g1121\tnth:0\n::g1121{a\tinput.tcl\t/^proc g1121 {a b} {$/;\"\tz\tprocedure:::g1121\tnth:0\nb\tinput.tcl\t/^proc g1121 {a b} {$/;\"\tz\tprocedure:::g1121\tnth:1\n::g1121{b\tinput.tcl\t/^proc g1121 {a b} {$/;\"\tz\tprocedure:::g1121\tnth:1\ng1021\tinput.tcl\t/^proc g1021 {{a 0} b} {$/;\"\tp\tsignature:{{a 0} b}\n::g1021\tinput.tcl\t/^proc g1021 {{a 0} b} {$/;\"\tp\tsignature:{{a 0} b}\na\tinput.tcl\t/^proc g1021 {{a 0} b} {$/;\"\tz\tprocedure:::g1021\tnth:0\n::g1021{a\tinput.tcl\t/^proc g1021 {{a 0} b} {$/;\"\tz\tprocedure:::g1021\tnth:0\nb\tinput.tcl\t/^proc g1021 {{a 0} b} {$/;\"\tz\tprocedure:::g1021\tnth:1\n::g1021{b\tinput.tcl\t/^proc g1021 {{a 0} b} {$/;\"\tz\tprocedure:::g1021\tnth:1\ng1020\tinput.tcl\t/^proc g1020 {{a 0} {b 1}} {$/;\"\tp\tsignature:{{a 0} {b 1}}\n::g1020\tinput.tcl\t/^proc g1020 {{a 0} {b 1}} {$/;\"\tp\tsignature:{{a 0} {b 1}}\na\tinput.tcl\t/^proc g1020 {{a 0} {b 1}} {$/;\"\tz\tprocedure:::g1020\tnth:0\n::g1020{a\tinput.tcl\t/^proc g1020 {{a 0} {b 1}} {$/;\"\tz\tprocedure:::g1020\tnth:0\nb\tinput.tcl\t/^proc g1020 {{a 0} {b 1}} {$/;\"\tz\tprocedure:::g1020\tnth:1\n::g1020{b\tinput.tcl\t/^proc g1020 {{a 0} {b 1}} {$/;\"\tz\tprocedure:::g1020\tnth:1\ng1120\tinput.tcl\t/^proc g1120 {a {b 1}} {$/;\"\tp\tsignature:{a {b 1}}\n::g1120\tinput.tcl\t/^proc g1120 {a {b 1}} {$/;\"\tp\tsignature:{a {b 1}}\na\tinput.tcl\t/^proc g1120 {a {b 1}} {$/;\"\tz\tprocedure:::g1120\tnth:0\n::g1120{a\tinput.tcl\t/^proc g1120 {a {b 1}} {$/;\"\tz\tprocedure:::g1120\tnth:0\nb\tinput.tcl\t/^proc g1120 {a {b 1}} {$/;\"\tz\tprocedure:::g1120\tnth:1\n::g1120{b\tinput.tcl\t/^proc g1120 {a {b 1}} {$/;\"\tz\tprocedure:::g1120\tnth:1\nh112131\tinput.tcl\t/^proc h112131 {a b c} {$/;\"\tp\tsignature:{a b c}\n::h112131\tinput.tcl\t/^proc h112131 {a b c} {$/;\"\tp\tsignature:{a b c}\na\tinput.tcl\t/^proc h112131 {a b c} {$/;\"\tz\tprocedure:::h112131\tnth:0\n::h112131{a\tinput.tcl\t/^proc h112131 {a b c} {$/;\"\tz\tprocedure:::h112131\tnth:0\nb\tinput.tcl\t/^proc h112131 {a b c} {$/;\"\tz\tprocedure:::h112131\tnth:1\n::h112131{b\tinput.tcl\t/^proc h112131 {a b c} {$/;\"\tz\tprocedure:::h112131\tnth:1\nc\tinput.tcl\t/^proc h112131 {a b c} {$/;\"\tz\tprocedure:::h112131\tnth:2\n::h112131{c\tinput.tcl\t/^proc h112131 {a b c} {$/;\"\tz\tprocedure:::h112131\tnth:2\nh102131\tinput.tcl\t/^proc h102131 {{a 0} b c} {$/;\"\tp\tsignature:{{a 0} b c}\n::h102131\tinput.tcl\t/^proc h102131 {{a 0} b c} {$/;\"\tp\tsignature:{{a 0} b c}\na\tinput.tcl\t/^proc h102131 {{a 0} b c} {$/;\"\tz\tprocedure:::h102131\tnth:0\n::h102131{a\tinput.tcl\t/^proc h102131 {{a 0} b c} {$/;\"\tz\tprocedure:::h102131\tnth:0\nb\tinput.tcl\t/^proc h102131 {{a 0} b c} {$/;\"\tz\tprocedure:::h102131\tnth:1\n::h102131{b\tinput.tcl\t/^proc h102131 {{a 0} b c} {$/;\"\tz\tprocedure:::h102131\tnth:1\nc\tinput.tcl\t/^proc h102131 {{a 0} b c} {$/;\"\tz\tprocedure:::h102131\tnth:2\n::h102131{c\tinput.tcl\t/^proc h102131 {{a 0} b c} {$/;\"\tz\tprocedure:::h102131\tnth:2\nh112031\tinput.tcl\t/^proc h112031 {a {b 0} c} {$/;\"\tp\tsignature:{a {b 0} c}\n::h112031\tinput.tcl\t/^proc h112031 {a {b 0} c} {$/;\"\tp\tsignature:{a {b 0} c}\na\tinput.tcl\t/^proc h112031 {a {b 0} c} {$/;\"\tz\tprocedure:::h112031\tnth:0\n::h112031{a\tinput.tcl\t/^proc h112031 {a {b 0} c} {$/;\"\tz\tprocedure:::h112031\tnth:0\nb\tinput.tcl\t/^proc h112031 {a {b 0} c} {$/;\"\tz\tprocedure:::h112031\tnth:1\n::h112031{b\tinput.tcl\t/^proc h112031 {a {b 0} c} {$/;\"\tz\tprocedure:::h112031\tnth:1\nc\tinput.tcl\t/^proc h112031 {a {b 0} c} {$/;\"\tz\tprocedure:::h112031\tnth:2\n::h112031{c\tinput.tcl\t/^proc h112031 {a {b 0} c} {$/;\"\tz\tprocedure:::h112031\tnth:2\nh112130\tinput.tcl\t/^proc h112130 {a b {c 0}} {$/;\"\tp\tsignature:{a b {c 0}}\n::h112130\tinput.tcl\t/^proc h112130 {a b {c 0}} {$/;\"\tp\tsignature:{a b {c 0}}\na\tinput.tcl\t/^proc h112130 {a b {c 0}} {$/;\"\tz\tprocedure:::h112130\tnth:0\n::h112130{a\tinput.tcl\t/^proc h112130 {a b {c 0}} {$/;\"\tz\tprocedure:::h112130\tnth:0\nb\tinput.tcl\t/^proc h112130 {a b {c 0}} {$/;\"\tz\tprocedure:::h112130\tnth:1\n::h112130{b\tinput.tcl\t/^proc h112130 {a b {c 0}} {$/;\"\tz\tprocedure:::h112130\tnth:1\nc\tinput.tcl\t/^proc h112130 {a b {c 0}} {$/;\"\tz\tprocedure:::h112130\tnth:2\n::h112130{c\tinput.tcl\t/^proc h112130 {a b {c 0}} {$/;\"\tz\tprocedure:::h112130\tnth:2\nh102031\tinput.tcl\t/^proc h102031 {{a 0} {b 0} c} {$/;\"\tp\tsignature:{{a 0} {b 0} c}\n::h102031\tinput.tcl\t/^proc h102031 {{a 0} {b 0} c} {$/;\"\tp\tsignature:{{a 0} {b 0} c}\na\tinput.tcl\t/^proc h102031 {{a 0} {b 0} c} {$/;\"\tz\tprocedure:::h102031\tnth:0\n::h102031{a\tinput.tcl\t/^proc h102031 {{a 0} {b 0} c} {$/;\"\tz\tprocedure:::h102031\tnth:0\nb\tinput.tcl\t/^proc h102031 {{a 0} {b 0} c} {$/;\"\tz\tprocedure:::h102031\tnth:1\n::h102031{b\tinput.tcl\t/^proc h102031 {{a 0} {b 0} c} {$/;\"\tz\tprocedure:::h102031\tnth:1\nc\tinput.tcl\t/^proc h102031 {{a 0} {b 0} c} {$/;\"\tz\tprocedure:::h102031\tnth:2\n::h102031{c\tinput.tcl\t/^proc h102031 {{a 0} {b 0} c} {$/;\"\tz\tprocedure:::h102031\tnth:2\nh112030\tinput.tcl\t/^proc h112030 {a {b 0} {c 0}} {$/;\"\tp\tsignature:{a {b 0} {c 0}}\n::h112030\tinput.tcl\t/^proc h112030 {a {b 0} {c 0}} {$/;\"\tp\tsignature:{a {b 0} {c 0}}\na\tinput.tcl\t/^proc h112030 {a {b 0} {c 0}} {$/;\"\tz\tprocedure:::h112030\tnth:0\n::h112030{a\tinput.tcl\t/^proc h112030 {a {b 0} {c 0}} {$/;\"\tz\tprocedure:::h112030\tnth:0\nb\tinput.tcl\t/^proc h112030 {a {b 0} {c 0}} {$/;\"\tz\tprocedure:::h112030\tnth:1\n::h112030{b\tinput.tcl\t/^proc h112030 {a {b 0} {c 0}} {$/;\"\tz\tprocedure:::h112030\tnth:1\nc\tinput.tcl\t/^proc h112030 {a {b 0} {c 0}} {$/;\"\tz\tprocedure:::h112030\tnth:2\n::h112030{c\tinput.tcl\t/^proc h112030 {a {b 0} {c 0}} {$/;\"\tz\tprocedure:::h112030\tnth:2\nh102130\tinput.tcl\t/^proc h102130 {{a 0} b {c 0}} {$/;\"\tp\tsignature:{{a 0} b {c 0}}\n::h102130\tinput.tcl\t/^proc h102130 {{a 0} b {c 0}} {$/;\"\tp\tsignature:{{a 0} b {c 0}}\na\tinput.tcl\t/^proc h102130 {{a 0} b {c 0}} {$/;\"\tz\tprocedure:::h102130\tnth:0\n::h102130{a\tinput.tcl\t/^proc h102130 {{a 0} b {c 0}} {$/;\"\tz\tprocedure:::h102130\tnth:0\nb\tinput.tcl\t/^proc h102130 {{a 0} b {c 0}} {$/;\"\tz\tprocedure:::h102130\tnth:1\n::h102130{b\tinput.tcl\t/^proc h102130 {{a 0} b {c 0}} {$/;\"\tz\tprocedure:::h102130\tnth:1\nc\tinput.tcl\t/^proc h102130 {{a 0} b {c 0}} {$/;\"\tz\tprocedure:::h102130\tnth:2\n::h102130{c\tinput.tcl\t/^proc h102130 {{a 0} b {c 0}} {$/;\"\tz\tprocedure:::h102130\tnth:2\nh102030\tinput.tcl\t/^proc h102030 {{a 0} {b 0} {c 0}} {$/;\"\tp\tsignature:{{a 0} {b 0} {c 0}}\n::h102030\tinput.tcl\t/^proc h102030 {{a 0} {b 0} {c 0}} {$/;\"\tp\tsignature:{{a 0} {b 0} {c 0}}\na\tinput.tcl\t/^proc h102030 {{a 0} {b 0} {c 0}} {$/;\"\tz\tprocedure:::h102030\tnth:0\n::h102030{a\tinput.tcl\t/^proc h102030 {{a 0} {b 0} {c 0}} {$/;\"\tz\tprocedure:::h102030\tnth:0\nb\tinput.tcl\t/^proc h102030 {{a 0} {b 0} {c 0}} {$/;\"\tz\tprocedure:::h102030\tnth:1\n::h102030{b\tinput.tcl\t/^proc h102030 {{a 0} {b 0} {c 0}} {$/;\"\tz\tprocedure:::h102030\tnth:1\nc\tinput.tcl\t/^proc h102030 {{a 0} {b 0} {c 0}} {$/;\"\tz\tprocedure:::h102030\tnth:2\n::h102030{c\tinput.tcl\t/^proc h102030 {{a 0} {b 0} {c 0}} {$/;\"\tz\tprocedure:::h102030\tnth:2\ni10_0\tinput.tcl\t/^proc i10_0 {{a d}} {$/;\"\tp\tsignature:{{a d}}\n::i10_0\tinput.tcl\t/^proc i10_0 {{a d}} {$/;\"\tp\tsignature:{{a d}}\na\tinput.tcl\t/^proc i10_0 {{a d}} {$/;\"\tz\tprocedure:::i10_0\tnth:0\n::i10_0{a\tinput.tcl\t/^proc i10_0 {{a d}} {$/;\"\tz\tprocedure:::i10_0\tnth:0\ni10_1\tinput.tcl\t/^proc i10_1 {{a {d}}} {$/;\"\tp\tsignature:{{a {d}}}\n::i10_1\tinput.tcl\t/^proc i10_1 {{a {d}}} {$/;\"\tp\tsignature:{{a {d}}}\na\tinput.tcl\t/^proc i10_1 {{a {d}}} {$/;\"\tz\tprocedure:::i10_1\tnth:0\n::i10_1{a\tinput.tcl\t/^proc i10_1 {{a {d}}} {$/;\"\tz\tprocedure:::i10_1\tnth:0\ni10_2\tinput.tcl\t/^proc i10_2 {{a {[h102030]}}} {$/;\"\tp\tsignature:{{a {[h102030]}}}\n::i10_2\tinput.tcl\t/^proc i10_2 {{a {[h102030]}}} {$/;\"\tp\tsignature:{{a {[h102030]}}}\na\tinput.tcl\t/^proc i10_2 {{a {[h102030]}}} {$/;\"\tz\tprocedure:::i10_2\tnth:0\n::i10_2{a\tinput.tcl\t/^proc i10_2 {{a {[h102030]}}} {$/;\"\tz\tprocedure:::i10_2\tnth:0\n"
  },
  {
    "path": "Units/parser-tcl.r/signature.d/input.tcl",
    "content": "proc fn a {\n    return a\n}\n\nproc f11 {a} {\n    return a\n}\n\nproc f10 {{a 0}} {\n    return a\n}\n\nproc g1121 {a b} {\n    return a + b\n}\n\nproc g1021 {{a 0} b} {\n    return a + b\n}\n\nproc g1020 {{a 0} {b 1}} {\n    return a + b\n}\n\nproc g1120 {a {b 1}} {\n    return a + b\n}\n\nproc h112131 {a b c} {\n    return a + b + c\n}\n\nproc h102131 {{a 0} b c} {\n    return a + b + c\n}\n\nproc h112031 {a {b 0} c} {\n    return a + b + c\n}\n\nproc h112130 {a b {c 0}} {\n    return a + b + c\n}\n\nproc h102031 {{a 0} {b 0} c} {\n    return a + b + c\n}\n\nproc h112030 {a {b 0} {c 0}} {\n    return a + b + c\n}\n\nproc h102130 {{a 0} b {c 0}} {\n    return a + b + c\n}\n\nproc h102030 {{a 0} {b 0} {c 0}} {\n    return a + b + c\n}\n\nset d 1\n\nproc i10_0 {{a d}} {\n    return a\n}\n\nproc i10_1 {{a {d}}} {\n    return 0\n}\n\nproc i10_2 {{a {[h102030]}}} {\n    return 0\n}\n"
  },
  {
    "path": "Units/parser-tcl.r/simple.tcl.d/expected.tags",
    "content": "simple1\tinput.tcl\t/^proc simple1 {} {$/;\"\tp\n"
  },
  {
    "path": "Units/parser-tcl.r/simple.tcl.d/input.tcl",
    "content": "# proc comment\nproc simple1 {} {\n}\n"
  },
  {
    "path": "Units/parser-tcl.r/tcl-issue-1368.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-tcl.r/tcl-issue-1368.d/input.tcl",
    "content": "\"\n"
  },
  {
    "path": "Units/parser-tcl.r/tcl-issue-3638.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-tcl.r/tcl-issue-3638.d/input.tcl",
    "content": "# Taken from https://github.com/universal-ctags/ctags/issues/3638 submitted by @kenifanying\nproc test1 {a} {\n\tset i 1\n\tset PORT1 Gi0/1\n\tset PORT2 Te1/1\n\tputs \"[format \"%10s %10s %10s\" \"$i |\" $PORT1 $PORT2]\"\n}\nproc test2 {} {\n\tputs \"test2\"\n}\n"
  },
  {
    "path": "Units/parser-tcloo.r/force-use.d/args.ctags",
    "content": "--sort=no\n--param-TclOO.forceUse=1\n--fields=+{language}\n"
  },
  {
    "path": "Units/parser-tcloo.r/force-use.d/expected.tags",
    "content": "X\tinput.tcl\t/^class create X {$/;\"\tc\tlanguage:TclOO\nadd\tinput.tcl\t/^    method add v {$/;\"\tm\tlanguage:TclOO\tclass:X\ndoSomething\tinput.tcl\t/^    }; method doSomething {v} {$/;\"\tm\tlanguage:TclOO\tclass:X\n"
  },
  {
    "path": "Units/parser-tcloo.r/force-use.d/input.tcl",
    "content": "# Assume this source file is loaded from\n# another source file:\n# \n#   namespace import oo::*\n#   source input.tcl\n#\nclass create X {\n    method add v {\n    }; method doSomething {v} {\n    }\n}\n"
  },
  {
    "path": "Units/parser-tcloo.r/namespace-class.d/args.ctags",
    "content": "--fields=+l\n"
  },
  {
    "path": "Units/parser-tcloo.r/namespace-class.d/expected.tags",
    "content": "X\tinput.tcl\t/^oo::class create X {$/;\"\tc\tlanguage:TclOO\nY\tinput.tcl\t/^class create Y {$/;\"\tc\tlanguage:TclOO\n"
  },
  {
    "path": "Units/parser-tcloo.r/namespace-class.d/input.tcl",
    "content": "namespace import oo::class\n\noo::class create X {\n}\n\nclass create Y {\n}\n"
  },
  {
    "path": "Units/parser-tcloo.r/namespace-wildcard.d/args.ctags",
    "content": "--fields=+l\n"
  },
  {
    "path": "Units/parser-tcloo.r/namespace-wildcard.d/expected.tags",
    "content": "X\tinput.tcl\t/^oo::class create X {$/;\"\tc\tlanguage:TclOO\nY\tinput.tcl\t/^class create Y {$/;\"\tc\tlanguage:TclOO\n"
  },
  {
    "path": "Units/parser-tcloo.r/namespace-wildcard.d/input.tcl",
    "content": "namespace import oo::*\n\noo::class create X {\n}\n\nclass create Y {\n}\n"
  },
  {
    "path": "Units/parser-tcloo.r/no-class-in-create.d/input.tcl",
    "content": "oo::class create  {\n    superclass Y\n"
  },
  {
    "path": "Units/parser-tcloo.r/no-empty-line-between-classes.d/args.ctags",
    "content": "--sort=no\n--fields=+li\n"
  },
  {
    "path": "Units/parser-tcloo.r/no-empty-line-between-classes.d/expected.tags",
    "content": "S\tinput.tcl\t/^oo::class create S {$/;\"\tc\tlanguage:TclOO\nsx\tinput.tcl\t/^    method sx {} {$/;\"\tm\tlanguage:TclOO\tclass:S\nM\tinput.tcl\t/^oo::class create M {$/;\"\tc\tlanguage:TclOO\nmx\tinput.tcl\t/^    method mx {} {$/;\"\tm\tlanguage:TclOO\tclass:M\nC\tinput.tcl\t/^oo::class create C {$/;\"\tc\tlanguage:TclOO\tinherits:S\ncx\tinput.tcl\t/^    method cx {} {$/;\"\tm\tlanguage:TclOO\tclass:C\n"
  },
  {
    "path": "Units/parser-tcloo.r/no-empty-line-between-classes.d/input.tcl",
    "content": "oo::class create S {\n    variable x\n    method sx {} {\n        set x 0\n    }\n}\noo::class create M {\n    variable x\n    method mx {} {\n        incr x 3\n    }\n}\noo::class create C {\n    superclass S\n    mixin M\n    variable x\n    method cx {} {\n        incr x 5\n    }\n}\n# Taken from https://wiki.tcl-lang.org/page/Variables+in+TclOO\n"
  },
  {
    "path": "Units/parser-tcloo.r/simple-tcloo.d/args.ctags",
    "content": "--fields=+li\n--extras=+q\n"
  },
  {
    "path": "Units/parser-tcloo.r/simple-tcloo.d/expected.tags",
    "content": "X\tinput.tcl\t/^oo::class create X {$/;\"\tc\tlanguage:TclOO\tinherits:Y;\nX::add\tinput.tcl\t/^    method add v {$/;\"\tm\tlanguage:TclOO\tclass:X\nX::doSomething\tinput.tcl\t/^    }; method doSomething {v} {$/;\"\tm\tlanguage:TclOO\tclass:X\nadd\tinput.tcl\t/^    method add v {$/;\"\tm\tlanguage:TclOO\tclass:X\ndoSomething\tinput.tcl\t/^    }; method doSomething {v} {$/;\"\tm\tlanguage:TclOO\tclass:X\n"
  },
  {
    "path": "Units/parser-tcloo.r/simple-tcloo.d/input.tcl",
    "content": "oo::class create X {\n    superclass Y;\n\n    method add v {\n    }; method doSomething {v} {\n    }\n}\n\nclass create ShouldNotBeCaptured {\n}\n"
  },
  {
    "path": "Units/parser-terraform.r/data.d/expected.tags",
    "content": "example_database_password\tinput.tf\t/^data \"aws_ssm_parameter\" \"example_database_password\" {$/;\"\td\n"
  },
  {
    "path": "Units/parser-terraform.r/data.d/input.tf",
    "content": "data \"aws_ssm_parameter\" \"example_database_password\" {\n  name = \"example-database-password\"\n}\n"
  },
  {
    "path": "Units/parser-terraform.r/local.d/expected.tags",
    "content": "this_is_a_local_variable_1\tinput.tf\t/^  this_is_a_local_variable_1 = \"this is the value of local variable 1\"$/;\"\tl\n"
  },
  {
    "path": "Units/parser-terraform.r/local.d/input.tf",
    "content": "locals {\n  this_is_a_local_variable_1 = \"this is the value of local variable 1\"\n}\n"
  },
  {
    "path": "Units/parser-terraform.r/module.d/expected.tags",
    "content": "database\tinput.tf\t/^module \"database\" {$/;\"\tm\n"
  },
  {
    "path": "Units/parser-terraform.r/module.d/input.tf",
    "content": "module \"database\" {\n  source = \"../../modules/database\"\n}\n"
  },
  {
    "path": "Units/parser-terraform.r/output.d/expected.tags",
    "content": "password\tinput.tf\t/^output \"password\" {$/;\"\to\n"
  },
  {
    "path": "Units/parser-terraform.r/output.d/input.tf",
    "content": "output \"password\" {\n  value = data.aws_ssm_parameter.example_database_password.value\n}\n"
  },
  {
    "path": "Units/parser-terraform.r/provider.d/expected.tags",
    "content": "aws\tinput.tf\t/^provider \"aws\" {$/;\"\tp\n"
  },
  {
    "path": "Units/parser-terraform.r/provider.d/input.tf",
    "content": "provider \"aws\" {\n  region = \"us-east-1\"\n}\n"
  },
  {
    "path": "Units/parser-terraform.r/resource.d/expected.tags",
    "content": "example_events_bus\tinput.tf\t/^resource \"aws_cloudwatch_event_bus\" \"example_events_bus\" {$/;\"\tr\n"
  },
  {
    "path": "Units/parser-terraform.r/resource.d/input.tf",
    "content": "resource \"aws_cloudwatch_event_bus\" \"example_events_bus\" {\n  name = var.events_bus_name\n}\n"
  },
  {
    "path": "Units/parser-terraform.r/simple-terraform.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+rl\n"
  },
  {
    "path": "Units/parser-terraform.r/simple-terraform.d/expected.tags",
    "content": "aws\tinput.tf\t/^provider \"aws\" {$/;\"\tp\tlanguage:Terraform\troles:def\nevents_bus_name\tinput.tf\t/^variable \"events_bus_name\" {$/;\"\tv\tlanguage:Terraform\troles:def\nexample_events_bus\tinput.tf\t/^resource \"aws_cloudwatch_event_bus\" \"example_events_bus\" {$/;\"\tr\tlanguage:Terraform\troles:def\ndatabase\tinput.tf\t/^module \"database\" {$/;\"\tm\tlanguage:Terraform\troles:def\nexample_database_password\tinput.tf\t/^data \"aws_ssm_parameter\" \"example_database_password\" {$/;\"\td\tlanguage:Terraform\troles:def\npassword\tinput.tf\t/^output \"password\" {$/;\"\to\tlanguage:Terraform\troles:def\nthis_is_a_local_variable_1\tinput.tf\t/^  this_is_a_local_variable_1 = \"this is the value of local variable 1\"$/;\"\tl\tlanguage:Terraform\troles:def\nthis_is_a_local_variable_2\tinput.tf\t/^  this_is_a_local_variable_2 = var.events_bus_name == local.this_is_a_local_variable_1 ## var.ev/;\"\tl\tlanguage:Terraform\troles:def\nevents_bus_name\tinput-0.tfvars\t/^events_bus_name = \"hyper-connector\"$/;\"\tv\tlanguage:Terraform\troles:assigned\n"
  },
  {
    "path": "Units/parser-terraform.r/simple-terraform.d/input-0.tfvars",
    "content": "events_bus_name = \"hyper-connector\"\n"
  },
  {
    "path": "Units/parser-terraform.r/simple-terraform.d/input.tf",
    "content": "provider \"aws\" {\n  region = \"us-east-1\"\n}\n\nvariable \"events_bus_name\" {\n  type = string\n  default = \"hello-world\"\n}\n\n# variable \"dont_extract_me0\" {\n// variable \"dont_extract_me1\" {\n\nresource \"aws_cloudwatch_event_bus\" \"example_events_bus\" {\n  name = var.events_bus_name\n}\n\nmodule \"database\" {\n  source = \"../../modules/database\"\n}\n\ndata \"aws_ssm_parameter\" \"example_database_password\" {\n  name = \"example-database-password\"\n}\n\noutput \"password\" {\n  value = data.aws_ssm_parameter.example_database_password.value\n}\n\nlocals {\n  this_is_a_local_variable_1 = \"this is the value of local variable 1\"\n  this_is_a_local_variable_2 = var.events_bus_name == local.this_is_a_local_variable_1 ## var.events_bus_name == shouldn't be picked up as a local\n\n  /* THE DEFINITIONS IN THIS BLOCK SHOULDN'T BE PICKED UP\nvariable \"no_parse_super_aws_thing\" {\n  type = string\n  default = \"hello-world\"\n}\nresource \"aws_cloudwatch_event_bus\" \"no_parse_example_events_bus_1\" {\n  name = var.events_bus_name\n}\n\nmodule \"no_parse_database_1\" {\n  source = \"../../modules/database\"\n}\n\ndata \"aws_ssm_parameter\" \"no_parse_example_database_password_1\" {\n  name = \"example-database-password\"\n}\n\noutput \"no_parse_password_1\" {\n  value = data.aws_ssm_parameter.example_database_password.value\n}\n\nlocals {\n  no_parse_this_is_a_local_variable_1 = \"this is the value of local variable 1\"\n\n}\n*/\n}\n"
  },
  {
    "path": "Units/parser-terraform.r/variable.d/expected.tags",
    "content": "events_bus_name\tinput.tf\t/^variable \"events_bus_name\" {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-terraform.r/variable.d/input.tf",
    "content": "variable \"events_bus_name\" {\n  type = string\n  default = \"hello-world\"\n}\n"
  },
  {
    "path": "Units/parser-tex.r/bibitem.d/expected.tags",
    "content": "X\tinput.tex\t/^\\\\bibitem [A] {X} XXX$/;\"\tB\nY\tinput.tex\t/^\\\\bibitem {Y} YYY$/;\"\tB\n"
  },
  {
    "path": "Units/parser-tex.r/bibitem.d/input.tex",
    "content": "\\documentclass{article}\n\\begin{document}\n\\begin{thebibliography}{99}\n\n\\bibitem [A] {X} XXX\n\n\\bibitem {Y} YYY\n\n\\end{thebibliography}\n\\end{document}\n"
  },
  {
    "path": "Units/parser-tex.r/bug2886870.tex.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-tex.r/bug2886870.tex.d/expected.tags",
    "content": "Introduction\tinput.tex\t/^\\\\section{Introduction}$/;\"\ts\nEquations\tinput.tex\t/^\\\\section{Equations}$/;\"\ts\neq:ising\tinput.tex\t/^\\\\label{eq:ising}$/;\"\tl\n\\\\lb\tinput.tex\t/^ \\\\newcommand{\\\\lb}{{\\\\langle}}$/;\"\tC\n\\\\rb\tinput.tex\t/^ \\\\newcommand{\\\\rb}{{\\\\rangle}}$/;\"\tC\n\\\\lb\tinput.tex\t/^\\\\newcommand{\\\\lb}{{\\\\langle}}$/;\"\tC\n\\\\rb\tinput.tex\t/^\\\\newcommand{\\\\rb}{{\\\\rangle}}$/;\"\tC\neq:fine\tinput.tex\t/^I = \\\\! \\\\int_{-\\\\infty}^\\\\infty f(x)\\\\,dx \\\\label{eq:fine}.$/;\"\tl\neq:mdiv\tinput.tex\t/^\\\\label{eq:mdiv}$/;\"\tl\n\\\\rv\tinput.tex\t/^\\\\newcommand{\\\\rv}{\\\\textbf{r}}$/;\"\tC\nTables\tinput.tex\t/^\\\\section{Tables}$/;\"\ts\ntab:5/tc\tinput.tex\t/^\\\\caption{\\\\label{tab:5\\/tc}Comparison of the mean-field predictions$/;\"\tl\nLists\tinput.tex\t/^\\\\section{Lists}$/;\"\ts\nFigures\tinput.tex\t/^\\\\section{Figures}$/;\"\ts\nfig:typical\tinput.tex\t/^\\\\caption{\\\\label{fig:typical}Show me a sine.}$/;\"\tl\nfig:lj\tinput.tex\t/^\\\\caption{\\\\label{fig:lj}Plot of the$/;\"\tl\nLiteral text\tinput.tex\t/^\\\\section{Literal text}$/;\"\ts\nSpecial Symbols\tinput.tex\t/^\\\\section{Special Symbols}$/;\"\ts\nCommon Greek letters\tinput.tex\t/^\\\\subsection{Common Greek letters}$/;\"\tu\tsection:Special Symbols\nTest for ctags\tinput.tex\t/^\\\\subsubsection{Test for ctags}$/;\"\tb\tsubsection:Special Symbols\"\"Common Greek letters\nSpecial symbols\tinput.tex\t/^\\\\subsection{Special symbols}$/;\"\tu\tsection:Special Symbols\n\\\\color{red}Use of Color\tinput.tex\t/^\\\\section{\\\\color{red}Use of Color}$/;\"\ts\n\\\\label{morefig}Subfigures\tinput.tex\t/^\\\\section{\\\\label{morefig}Subfigures}$/;\"\ts\nfig:qm/complexfunctions\tinput.tex\t/^\\\\caption{\\\\label{fig:qm\\/complexfunctions} Two representations of complex$/;\"\tl\nlatex\tinput.tex\t/^\\\\bibitem{latex}Helmut Kopka and Patrick W. Daly, \\\\textsl{A Guide to$/;\"\tB\nwebsite\tinput.tex\t/^\\\\bibitem{website}Some useful links are$/;\"\tB\n"
  },
  {
    "path": "Units/parser-tex.r/bug2886870.tex.d/input.tex",
    "content": "% Derrived from % http://sip.clarku.edu/tutorials/TeX/intro.html\r\n% similar to intro_orig.tex.d/input.tex. Slightly different.\r\n% Sample LaTeX file\r\n% The name of this file is intro.tex.\r\n\r\n\\documentclass[12pt]{article}\r\n\r\n\\usepackage{amsmath}    % need for subequations\r\n\\usepackage{graphicx}   % need for figures\r\n\\usepackage{verbatim}   % useful for program listings\r\n\\usepackage{color}      % use if color is used in text\r\n\\usepackage{subfigure}  % use for side-by-side figures\r\n\\usepackage{hyperref}   % use for hypertext links, including those to external documents and URLs\r\n\r\n% don't need the following. simply use defaults\r\n\\setlength{\\baselineskip}{16.0pt}    % 16 pt usual spacing between lines\r\n\r\n\\setlength{\\parskip}{3pt plus 2pt}\r\n\\setlength{\\parindent}{20pt}\r\n\\setlength{\\oddsidemargin}{0.5cm}\r\n\\setlength{\\evensidemargin}{0.5cm}\r\n\\setlength{\\marginparsep}{0.75cm}\r\n\\setlength{\\marginparwidth}{2.5cm}\r\n\\setlength{\\marginparpush}{1.0cm}\r\n\\setlength{\\textwidth}{150mm}\r\n\r\n\\begin{comment}\r\n\\pagestyle{empty} % use if page numbers not wanted\r\n\\end{comment}\r\n\r\n% above is the preamble\r\n\r\n\\begin{document}\r\n\r\n\\begin{center}\r\n{\\large Introduction to \\LaTeX} \\\\ % \\\\ = new line\r\n\\copyright 2006 by Harvey Gould \\\\\r\nDecember 5, 2006\r\n\\end{center}\r\n\r\n\\section{Introduction}\r\n\\TeX\\ looks more difficult than it is. It is\r\nalmost as easy as $\\pi$. See how easy it is to make special\r\nsymbols such as $\\alpha$,\r\n$\\beta$, $\\gamma$,\r\n$\\delta$, $\\sin x$, $\\hbar$, $\\lambda$, $\\ldots$ We also can make\r\nsubscripts\r\n$A_{x}$, $A_{xy}$ and superscripts, $e^x$, $e^{x^2}$, and\r\n$e^{a^b}$. We will use \\LaTeX, which is based on \\TeX\\ and has\r\nmany higher-level commands (macros) for formatting, making\r\ntables, etc. More information can be found in Ref.~\\cite{latex}.\r\n\r\nWe just made a new paragraph. Extra lines and spaces make no\r\ndifference. Note that all formulas are enclosed by\r\n\\$ and occur in \\textit{math mode}.\r\n\r\nThe default font is Computer Modern. It includes \\textit{italics},\r\n\\textbf{boldface},\r\n\\textsl{slanted}, and \\texttt{monospaced} fonts.\r\n\r\n\\section{Equations}\r\nLet us see how easy it is to write equations.\r\n\\begin{equation}\r\n\\Delta =\\sum_{i=1}^N w_i (x_i - \\bar{x})^2 .\r\n\\end{equation}\r\nIt is a good idea to number equations, but we can have a\r\nequation without a number by writing\r\n\\begin{equation}\r\nP(x) = \\frac{x - a}{b - a} , \\nonumber\r\n\\end{equation}\r\nand\r\n\\begin{equation}\r\ng = \\frac{1}{2} \\sqrt{2\\pi} . \\nonumber\r\n\\end{equation}\r\n\r\nWe can give an equation a label so that we can refer to it later.\r\n\\begin{equation}\r\n\\label{eq:ising}\r\nE = -J \\sum_{i=1}^N s_i s_{i+1} ,\r\n\\end{equation}\r\nEquation~\\eqref{eq:ising} expresses the energy of a configuration\r\nof spins in the Ising model.\\footnote{It is necessary to process (typeset) a\r\nfile twice to get the counters correct.}\r\n\r\nWe can define our own macros to save typing. For example, suppose\r\nthat we introduce the macros:\r\n\\begin{verbatim}\r\n \\newcommand{\\lb}{{\\langle}}\r\n \\newcommand{\\rb}{{\\rangle}}\r\n\\end{verbatim}\r\n\\newcommand{\\lb}{{\\langle}}\r\n\\newcommand{\\rb}{{\\rangle}}\r\nThen we can write the average value of $x$ as\r\n\\begin{verbatim}\r\n\\begin{equation}\r\n\\lb x \\rb = 3\r\n\\end{equation}\r\n\\end{verbatim}\r\nThe result is\r\n\\begin{equation}\r\n\\lb x \\rb = 3 .\r\n\\end{equation}\r\n\r\nExamples of more complicated equations:\r\n\\begin{equation}\r\nI = \\! \\int_{-\\infty}^\\infty f(x)\\,dx \\label{eq:fine}.\r\n\\end{equation}\r\nWe can do some fine tuning by adding small amounts of horizontal\r\nspacing:\r\n\\begin{verbatim}\r\n \\, small space       \\! negative space\r\n\\end{verbatim}\r\nas is done in Eq.~\\eqref{eq:fine}.\r\n\r\nWe also can align several equations:\r\n\\begin{align}\r\na & = b \\\\\r\nc &= d ,\r\n\\end{align}\r\nor number them as subequations:\r\n\\begin{subequations}\r\n\\begin{align}\r\na & = b \\\\\r\nc &= d .\r\n\\end{align}\r\n\\end{subequations}\r\n\r\nWe can also have different cases:\r\n\\begin{equation}\r\n\\label{eq:mdiv}\r\nm(T) =\r\n\\begin{cases}\r\n0 & \\text{$T > T_c$} \\\\\r\n\\bigl(1 - [\\sinh 2 \\beta J]^{-4} \\bigr)^{\\! 1/8} & \\text{$T < T_c$}\r\n\\end{cases}\r\n\\end{equation}\r\nwrite matrices\r\n\\begin{align}\r\n\\textbf{T} &=\r\n\\begin{pmatrix}\r\nT_{++} \\hfill & T_{+-} \\\\\r\nT_{-+} & T_{--} \\hfill \r\n\\end{pmatrix} , \\nonumber \\\\\r\n& =\r\n\\begin{pmatrix}\r\ne^{\\beta (J + B)} \\hfill & e^{-\\beta J} \\hfill \\\\\r\ne^{-\\beta J} \\hfill & e^{\\beta (J - B)} \\hfill\r\n\\end{pmatrix}.\r\n\\end{align}\r\nand \r\n\\newcommand{\\rv}{\\textbf{r}}\r\n\\begin{equation}\r\n\\sum_i \\vec A \\cdot \\vec B = -P\\!\\int\\! \\rv \\cdot\r\n\\hat{\\mathbf{n}}\\, dA = P\\!\\int \\! {\\vec \\nabla} \\cdot \\rv\\, dV.\r\n\\end{equation}\r\n\r\n\\section{Tables}\r\nTables are a little more difficult. TeX\r\nautomatically calculates the width of the columns.\r\n\r\n\\begin{table}[h]\r\n\\begin{center}\r\n\\begin{tabular}{|l|l|r|l|}\r\n\\hline\r\nlattice & $d$ & $q$ & $T_{\\rm mf}/T_c$ \\\\\r\n\\hline\r\nsquare & 2 & 4 & 1.763 \\\\\r\n\\hline\r\ntriangular & 2 & 6 & 1.648 \\\\\r\n\\hline\r\ndiamond & 3 & 4 & 1.479 \\\\\r\n\\hline\r\nsimple cubic & 3 & 6 & 1.330 \\\\\r\n\\hline\r\nbcc & 3 & 8 & 1.260 \\\\\r\n\\hline\r\nfcc & 3 & 12 & 1.225 \\\\\r\n\\hline\r\n\\end{tabular}\r\n\\caption{\\label{tab:5/tc}Comparison of the mean-field predictions\r\nfor the critical temperature of the Ising model with exact results\r\nand the best known estimates for different spatial dimensions $d$\r\nand lattice symmetries.}\r\n\\end{center}\r\n\\end{table}\r\n\r\n\\section{Lists}\r\n\r\nSome example of formatted lists include the\r\nfollowing:\r\n\r\n\\begin{enumerate}\r\n\r\n\\item bread\r\n\r\n\\item cheese\r\n\r\n\\end{enumerate}\r\n\r\n\\begin{itemize}\r\n\r\n\\item Tom\r\n\r\n\\item Dick\r\n\r\n\\end{itemize}\r\n\r\n\\section{Figures}\r\n\r\nWe can make figures bigger or smaller by scaling them. Figure~\\ref{fig:lj}\r\nhas been scaled by 60\\%.\r\n\r\n\\begin{figure}[h]\r\n\\begin{center}\r\n\\includegraphics{figures/sine}\r\n\\caption{\\label{fig:typical}Show me a sine.}\r\n\\end{center}\r\n\\end{figure}\r\n\r\n\\begin{figure}[h]\r\n\\begin{center}\r\n\\scalebox{0.6}{\\includegraphics{figures/lj}}\r\n\\caption{\\label{fig:lj}Plot of the\r\nLennard-Jones potential\r\n$u(r)$. The potential is characterized by a length\r\n$\\sigma$ and an energy\r\n$\\epsilon$.}\r\n\\end{center}\r\n\\end{figure}\r\n\r\n\\section{Literal text}\r\nIt is desirable to print program code exactly as it is typed in a\r\nmonospaced font. Use \\verb \\begin{verbatim} and\r\n\\verb \\end{verbatim} as in the following example:\r\n\\begin{verbatim}\r\ndouble y0 = 10; // example of declaration and assignment statement\r\ndouble v0 = 0;  // initial velocity\r\ndouble t = 0;   // time\r\ndouble dt = 0.01; // time step\r\ndouble y = y0;\r\n\\end{verbatim}\r\nThe command \\verb \\verbatiminput{programs/Square.java}\\ allows\r\nyou to list the file \\texttt{Square.java} in the directory\r\nprograms.\r\n\r\n\\section{Special Symbols}\r\n\r\n\\subsection{Common Greek letters}\r\n\r\nThese commands may be used only in math mode. Only the most common\r\nletters are included here.\r\n\r\n$\\alpha, \r\n\\beta, \\gamma, \\Gamma,\r\n\\delta,\\Delta,\r\n\\epsilon, \\zeta, \\eta, \\theta, \\Theta, \\kappa,\r\n\\lambda, \\Lambda, \\mu, \\nu,\r\n\\xi, \\Xi,\r\n\\pi, \\Pi,\r\n\\rho,\r\n\\sigma, \r\n\\tau,\r\n\\phi, \\Phi,\r\n\\chi,\r\n\\psi, \\Psi,\r\n\\omega, \\Omega$\r\n\\subsubsection{Test for ctags}\r\n\\subsection{Special symbols}\r\n\r\nThe derivative is defined as\r\n\\begin{equation}\r\n\\frac{dy}{dx} = \\lim_{\\Delta x \\to 0} \\frac{\\Delta y}\r\n{\\Delta x}\r\n\\end{equation}\r\n\\begin{equation}\r\nf(x) \\to y \\quad \\mbox{as} \\quad x \\to\r\nx_{0}\r\n\\end{equation}\r\n\\begin{equation}\r\nf(x) \\mathop {\\longrightarrow}\r\n\\limits_{x \\to x_0} y\r\n\\end{equation}\r\n\r\n\\noindent Order of magnitude:\r\n\\begin{equation}\r\n\\log_{10}f \\simeq n\r\n\\end{equation}\r\n\\begin{equation}\r\nf(x)\\sim 10^{n}\r\n\\end{equation}\r\nApproximate equality:\r\n\\begin{equation}\r\nf(x)\\simeq g(x)\r\n\\end{equation}\r\n\\LaTeX\\ is simple if we keep everything in proportion:\r\n\\begin{equation}\r\nf(x) \\propto x^3 .\r\n\\end{equation}\r\n\r\nFinally we can skip some space by using commands such as\r\n\\begin{verbatim}\r\n\\bigskip    \\medskip    \\smallskip    \\vspace{1pc}\r\n\\end{verbatim}\r\nThe space can be negative.\r\n\r\n\\section{\\color{red}Use of Color}\r\n\r\n{\\color{blue}{We can change colors for emphasis}},\r\n{\\color{green}{but}} {\\color{cyan}{who is going pay for the ink?}}\r\n\r\n\\section{\\label{morefig}Subfigures}\r\n\r\nAs soon as many students start becoming comfortable using \\LaTeX, they want\r\nto use some of its advanced features. So we now show how to place two\r\nfigures side by side.\r\n\r\n\\begin{figure}[h!]\r\n\\begin{center}\r\n\\subfigure[Real and imaginary.]{\r\n\\includegraphics[scale=0.5]{figures/reim}}\r\n\\subfigure[Amplitude and phase.]{\r\n\\includegraphics[scale=0.5]{figures/phase}}\r\n\\caption{\\label{fig:qm/complexfunctions} Two representations of complex\r\nwave functions.}\r\n\\end{center}\r\n\\end{figure}\r\n\r\nWe first have to include the necessary package,\r\n\\verb+\\usepackage{subfigure}+, which has to go in the preamble (before\r\n\\verb+\\begin{document}+). It sometimes can be difficult to place a figure in\r\nthe desired place.\r\n\r\nYour LaTeX document can be easily modified to make a poster or a screen\r\npresentation similar to (and better than) PowerPoint. Conversion to HTML is\r\nstraightforward. Comments on this tutorial are appreciated.\r\n\r\n\\begin{thebibliography}{5}\r\n\r\n\\bibitem{latex}Helmut Kopka and Patrick W. Daly, \\textsl{A Guide to\r\n\\LaTeX: Document Preparation for Beginners and Advanced Users},\r\nfourth edition, Addison-Wesley (2004).\r\n\r\n\\bibitem{website}Some useful links are\r\ngiven at \\url{}.\r\n\r\n\\end{thebibliography}\r\n\r\n{\\small \\noindent Updated 5 December 2006.}\r\n\\end{document}\r\n\r\n% Updated 6 February 2006. \r\n\r\n\r\n"
  },
  {
    "path": "Units/parser-tex.r/cleveref-label.d/expected.tags",
    "content": "eqs:einstein\tinput.tex\t/^  \\\\label[pluralequation]{eqs:einstein}$/;\"\tl\neqs:einstein2\tinput.tex\t/^  \\\\label{eqs:einstein2}$/;\"\tl\n"
  },
  {
    "path": "Units/parser-tex.r/cleveref-label.d/input.tex",
    "content": "%% Taken from #1558\n\\documentclass{article}\n\\usepackage{cleveref}\n\\crefname{pluralequation}{eqs.}{eqs.}\n\\begin{document}\n\\begin{equation}\n  E = m c^2 \\qquad R_{\\mu\\nu} - \\frac{1}{2} R g_{\\mu\\nu} + \\Lambda g_{\\mu\\nu} = \\frac{8\\pi G}{c^4} T_{\\mu\\nu}\n  \\label[pluralequation]{eqs:einstein}\n  \\label{eqs:einstein2}\n\\end{equation}\n\\end{document}\n"
  },
  {
    "path": "Units/parser-tex.r/empty-arg.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-tex.r/empty-arg.d/expected.tags",
    "content": "z\tinput.tex\t/^\\\\subsection{z}$/;\"\tu\nA\tinput.tex\t/^\\\\section{A}$/;\"\ts\na\tinput.tex\t/^\\\\subsection{a}$/;\"\tu\tsection:A\nB\tinput.tex\t/^\\\\section{B}$/;\"\ts\nb\tinput.tex\t/^\\\\subsection{b}$/;\"\tu\tsection:B\n"
  },
  {
    "path": "Units/parser-tex.r/empty-arg.d/input.tex",
    "content": "\\documentclass{article}\n\\begin{document}\n\\section{}\n\\subsection{z}\n\\section{A}\n\\subsection{a}\n\\section{B}\n\\subsection{b}\n\\end{document}\n"
  },
  {
    "path": "Units/parser-tex.r/intro.tex.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+K\n--fields=+r\n"
  },
  {
    "path": "Units/parser-tex.r/intro.tex.d/expected.tags",
    "content": "chapter text\tinput.tex\t/^\\\\chapter{chapter text}$/;\"\tchapter\troles:def\nchapter1-intro.inc\tinput.tex\t/^\\\\include{chapter1-intro.inc}$/;\"\txinput\troles:included\nsection1 text\tinput.tex\t/^\\\\section{section1 text}$/;\"\tsection\tchapter:chapter text\troles:def\nIntroduction\tinput.tex\t/^\\\\section{Introduction}$/;\"\tsection\tchapter:chapter text\troles:def\nPart1\tinput.tex\t/^\\\\part{Part1}$/;\"\tpart\troles:def\nsubsection2\tinput.tex\t/^\\\\subsection{subsection2}$/;\"\tsubsection\tpart:Part1\troles:def\nsubsubsection3 with extra text\tinput.tex\t/^\\\\subsubsection{subsubsection3 with extra text}$/;\"\tsubsubsection\tsubsection:Part1\"\"subsection2\troles:def\nshort section4\tinput.tex\t/^\\\\section[short section4]{section4 text}$/;\"\tsection\tpart:Part1\troles:def\nshort para1\tinput.tex\t/^\\\\paragraph[short para1]{long paragraph1}$/;\"\tparagraph\tsection:Part1\"\"short section4\troles:def\nlong paragraph2\tinput.tex\t/^\\\\paragraph{long paragraph2}$/;\"\tparagraph\tsection:Part1\"\"short section4\troles:def\nPart2\tinput.tex\t/^\\\\part{Part2}$/;\"\tpart\troles:def\nshorter intro2\tinput.tex\t/^\\\\section[shorter intro2]*{Introduction2longtitle}$/;\"\tsection\tpart:Part2\troles:def\nsubsec5 text\tinput.tex\t/^\\\\subsection[subsec5 text]*{subsection5}$/;\"\tsubsection\tsection:Part2\"\"shorter intro2\troles:def\nshort subpara1\tinput.tex\t/^\\\\subparagraph[short subpara1]{long subparagraph1}$/;\"\tsubparagraph\tsubsection:Part2\"\"shorter intro2\"\"subsec5 text\troles:def\nlong subparagraph2\tinput.tex\t/^\\\\subparagraph{long subparagraph2}$/;\"\tsubparagraph\tsubsection:Part2\"\"shorter intro2\"\"subsec5 text\troles:def\nsubsubsection6 with extra text\tinput.tex\t/^\\\\subsubsection{subsubsection6 with extra text}$/;\"\tsubsubsection\tsubsection:Part2\"\"shorter intro2\"\"subsec5 text\troles:def\nchapter2\tinput.tex\t/^\\\\chapter{chapter2}$/;\"\tchapter\tpart:Part2\troles:def\nchapter2-intro.inc\tinput.tex\t/^\\\\include{chapter2-intro.inc}$/;\"\txinput\troles:included\n"
  },
  {
    "path": "Units/parser-tex.r/intro.tex.d/input.tex",
    "content": "% http://sip.clarku.edu/tutorials/TeX/intro.html\r\n\\documentclass[12pt]{article}\r\n\r\n\\usepackage{amsmath}    % need for subequations\r\n\\chapter{chapter text}\r\n\\include{chapter1-intro.inc}\r\n\\section{section1 text}\r\nIt is desirable to print program code exactly as it is typed in a\r\nmonospaced font. Use \\verb \\begin{verbatim} and\r\n\\section{Introduction}\r\n\\part{Part1}\r\nIt is desirable to print program code exactly as it is typed in a\r\nmonospaced font. Use \\verb \\begin{verbatim} and\r\n\\subsection{subsection2}\r\nIt is desirable to print program code exactly as it is typed in a\r\nmonospaced font. Use \\verb \\begin{verbatim} and\r\n\\subsubsection{subsubsection3 with extra text}\r\nIt is desirable to print program code exactly as it is typed in a\r\nmonospaced font. Use \\verb \\begin{verbatim} and\r\n\\section[short section4]{section4 text}\r\n\\paragraph[short para1]{long paragraph1}\r\n\\paragraph{long paragraph2}\r\nIt is desirable to print program code exactly as it is typed in a\r\nmonospaced font. Use \\verb \\begin{verbatim} and\r\n\\part{Part2}\r\n\\section[shorter intro2]*{Introduction2longtitle}\r\nIt is desirable to print program code exactly as it is typed in a\r\nmonospaced font. Use \\verb \\begin{verbatim} and\r\n\\subsection[subsec5 text]*{subsection5}\r\n\\subparagraph[short subpara1]{long subparagraph1}\r\n\\subparagraph{long subparagraph2}\r\nIt is desirable to print program code exactly as it is typed in a\r\nmonospaced font. Use \\verb \\begin{verbatim} and\r\n\\subsubsection{subsubsection6 with extra text}\r\nIt is desirable to print program code exactly as it is typed in a\r\nmonospaced font. Use \\verb \\begin{verbatim} and\r\n\\chapter{chapter2}\r\n\\include{chapter2-intro.inc}\r\n\\end{document}\r\n\r\n"
  },
  {
    "path": "Units/parser-tex.r/intro_orig.tex.d/README",
    "content": "* \\\\color{red}Use of Color\tinput.tex\t/^\\\\section{\\\\color{red}Use of Color}$/;\"\tsection\troles:def\n* \\\\label{morefig}Subfigures\tinput.tex\t/^\\\\section{\\\\label{morefig}Subfigures}$/;\"\tsection\troles:def\n\nThese two are questionable.\n\nIdeally the first one should be:\n\n* Use of Color\tinput.tex\t/^\\\\section{\\\\color{red}Use of Color}$/;\"\tsection\troles:def\n\nIf we should consider only \\color, skipping it is nor hard.\n\nThe second one sohuld be:\n\n* morefig\tinput.tex\t/^\\\\section{\\\\label{morefig}Subfigures}$/;\"\tlabel\troles;def\n* Subfigures\tinput.tex\t/^\\\\section{\\\\label{morefig}Subfigures}$/;\"\tsection\troles:def\n"
  },
  {
    "path": "Units/parser-tex.r/intro_orig.tex.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+K\n--fields=+r\n"
  },
  {
    "path": "Units/parser-tex.r/intro_orig.tex.d/expected.tags",
    "content": "Introduction\tinput.tex\t/^\\\\section{Introduction}$/;\"\tsection\troles:def\nEquations\tinput.tex\t/^\\\\section{Equations}$/;\"\tsection\troles:def\neq:ising\tinput.tex\t/^\\\\label{eq:ising}$/;\"\tlabel\troles:def\n\\\\lb\tinput.tex\t/^ \\\\newcommand{\\\\lb}{{\\\\langle}}$/;\"\tcommand\troles:def\n\\\\rb\tinput.tex\t/^ \\\\newcommand{\\\\rb}{{\\\\rangle}}$/;\"\tcommand\troles:def\n\\\\lb\tinput.tex\t/^\\\\newcommand{\\\\lb}{{\\\\langle}}$/;\"\tcommand\troles:def\n\\\\rb\tinput.tex\t/^\\\\newcommand{\\\\rb}{{\\\\rangle}}$/;\"\tcommand\troles:def\neq:fine\tinput.tex\t/^I = \\\\! \\\\int_{-\\\\infty}^\\\\infty f(x)\\\\,dx \\\\label{eq:fine}.$/;\"\tlabel\troles:def\neq:mdiv\tinput.tex\t/^\\\\label{eq:mdiv}$/;\"\tlabel\troles:def\n\\\\rv\tinput.tex\t/^\\\\newcommand{\\\\rv}{\\\\textbf{r}}$/;\"\tcommand\troles:def\nTables\tinput.tex\t/^\\\\section{Tables}$/;\"\tsection\troles:def\ntab:5/tc\tinput.tex\t/^\\\\caption{\\\\label{tab:5\\/tc}Comparison of the mean-field predictions$/;\"\tlabel\troles:def\nLists\tinput.tex\t/^\\\\section{Lists}$/;\"\tsection\troles:def\nFigures\tinput.tex\t/^\\\\section{Figures}$/;\"\tsection\troles:def\nfig:typical\tinput.tex\t/^\\\\caption{\\\\label{fig:typical}Show me a sine.}$/;\"\tlabel\troles:def\nfig:lj\tinput.tex\t/^\\\\caption{\\\\label{fig:lj}Plot of the$/;\"\tlabel\troles:def\nLiteral text\tinput.tex\t/^\\\\section{Literal text}$/;\"\tsection\troles:def\nSpecial Symbols\tinput.tex\t/^\\\\section{Special Symbols}$/;\"\tsection\troles:def\nCommon Greek letters\tinput.tex\t/^\\\\subsection{Common Greek letters}$/;\"\tsubsection\tsection:Special Symbols\troles:def\nSpecial symbols\tinput.tex\t/^\\\\subsection{Special symbols}$/;\"\tsubsection\tsection:Special Symbols\troles:def\n\\\\color{red}Use of Color\tinput.tex\t/^\\\\section{\\\\color{red}Use of Color}$/;\"\tsection\troles:def\n\\\\label{morefig}Subfigures\tinput.tex\t/^\\\\section{\\\\label{morefig}Subfigures}$/;\"\tsection\troles:def\nfig:qm/complexfunctions\tinput.tex\t/^\\\\caption{\\\\label{fig:qm\\/complexfunctions} Two representations of complex$/;\"\tlabel\troles:def\nlatex\tinput.tex\t/^\\\\bibitem{latex}Helmut Kopka and Patrick W. Daly, \\\\textsl{A Guide to$/;\"\tbibitem\troles:def\nwebsite\tinput.tex\t/^\\\\bibitem{website}Some useful links are$/;\"\tbibitem\troles:def\n"
  },
  {
    "path": "Units/parser-tex.r/intro_orig.tex.d/input.tex",
    "content": "% http://sip.clarku.edu/tutorials/TeX/intro.html\r\n\\documentclass[12pt]{article}\r\n\r\n\\usepackage{amsmath}    % need for subequations\r\n\\usepackage{graphicx}   % need for figures\r\n\\usepackage{verbatim}   % useful for program listings\r\n\\usepackage{color}      % use if color is used in text\r\n\\usepackage{subfigure}  % use for side-by-side figures\r\n\\usepackage{hyperref}   % use for hypertext links, including those to external documents and URLs\r\n\r\n% don't need the following. simply use defaults\r\n\\setlength{\\baselineskip}{16.0pt}    % 16 pt usual spacing between lines\r\n\r\n\\setlength{\\parskip}{3pt plus 2pt}\r\n\\setlength{\\parindent}{20pt}\r\n\\setlength{\\oddsidemargin}{0.5cm}\r\n\\setlength{\\evensidemargin}{0.5cm}\r\n\\setlength{\\marginparsep}{0.75cm}\r\n\\setlength{\\marginparwidth}{2.5cm}\r\n\\setlength{\\marginparpush}{1.0cm}\r\n\\setlength{\\textwidth}{150mm}\r\n\r\n\\begin{comment}\r\n\\pagestyle{empty} % use if page numbers not wanted\r\n\\end{comment}\r\n\r\n% above is the preamble\r\n\r\n\\begin{document}\r\n\r\n\\begin{center}\r\n{\\large Introduction to \\LaTeX} \\\\ % \\\\ = new line\r\n\\copyright 2006 by Harvey Gould \\\\\r\nDecember 5, 2006\r\n\\end{center}\r\n\r\n\\section{Introduction}\r\n\\TeX\\ looks more difficult than it is. It is\r\nalmost as easy as $\\pi$. See how easy it is to make special\r\nsymbols such as $\\alpha$,\r\n$\\beta$, $\\gamma$,\r\n$\\delta$, $\\sin x$, $\\hbar$, $\\lambda$, $\\ldots$ We also can make\r\nsubscripts\r\n$A_{x}$, $A_{xy}$ and superscripts, $e^x$, $e^{x^2}$, and\r\n$e^{a^b}$. We will use \\LaTeX, which is based on \\TeX\\ and has\r\nmany higher-level commands (macros) for formatting, making\r\ntables, etc. More information can be found in Ref.~\\cite{latex}.\r\n\r\nWe just made a new paragraph. Extra lines and spaces make no\r\ndifference. Note that all formulas are enclosed by\r\n\\$ and occur in \\textit{math mode}.\r\n\r\nThe default font is Computer Modern. It includes \\textit{italics},\r\n\\textbf{boldface},\r\n\\textsl{slanted}, and \\texttt{monospaced} fonts.\r\n\r\n\\section{Equations}\r\nLet us see how easy it is to write equations.\r\n\\begin{equation}\r\n\\Delta =\\sum_{i=1}^N w_i (x_i - \\bar{x})^2 .\r\n\\end{equation}\r\nIt is a good idea to number equations, but we can have a\r\nequation without a number by writing\r\n\\begin{equation}\r\nP(x) = \\frac{x - a}{b - a} , \\nonumber\r\n\\end{equation}\r\nand\r\n\\begin{equation}\r\ng = \\frac{1}{2} \\sqrt{2\\pi} . \\nonumber\r\n\\end{equation}\r\n\r\nWe can give an equation a label so that we can refer to it later.\r\n\\begin{equation}\r\n\\label{eq:ising}\r\nE = -J \\sum_{i=1}^N s_i s_{i+1} ,\r\n\\end{equation}\r\nEquation~\\eqref{eq:ising} expresses the energy of a configuration\r\nof spins in the Ising model.\\footnote{It is necessary to process (typeset) a\r\nfile twice to get the counters correct.}\r\n\r\nWe can define our own macros to save typing. For example, suppose\r\nthat we introduce the macros:\r\n\\begin{verbatim}\r\n \\newcommand{\\lb}{{\\langle}}\r\n \\newcommand{\\rb}{{\\rangle}}\r\n\\end{verbatim}\r\n\\newcommand{\\lb}{{\\langle}}\r\n\\newcommand{\\rb}{{\\rangle}}\r\nThen we can write the average value of $x$ as\r\n\\begin{verbatim}\r\n\\begin{equation}\r\n\\lb x \\rb = 3\r\n\\end{equation}\r\n\\end{verbatim}\r\nThe result is\r\n\\begin{equation}\r\n\\lb x \\rb = 3 .\r\n\\end{equation}\r\n\r\nExamples of more complicated equations:\r\n\\begin{equation}\r\nI = \\! \\int_{-\\infty}^\\infty f(x)\\,dx \\label{eq:fine}.\r\n\\end{equation}\r\nWe can do some fine tuning by adding small amounts of horizontal\r\nspacing:\r\n\\begin{verbatim}\r\n \\, small space       \\! negative space\r\n\\end{verbatim}\r\nas is done in Eq.~\\eqref{eq:fine}.\r\n\r\nWe also can align several equations:\r\n\\begin{align}\r\na & = b \\\\\r\nc &= d ,\r\n\\end{align}\r\nor number them as subequations:\r\n\\begin{subequations}\r\n\\begin{align}\r\na & = b \\\\\r\nc &= d .\r\n\\end{align}\r\n\\end{subequations}\r\n\r\nWe can also have different cases:\r\n\\begin{equation}\r\n\\label{eq:mdiv}\r\nm(T) =\r\n\\begin{cases}\r\n0 & \\text{$T > T_c$} \\\\\r\n\\bigl(1 - [\\sinh 2 \\beta J]^{-4} \\bigr)^{\\! 1/8} & \\text{$T < T_c$}\r\n\\end{cases}\r\n\\end{equation}\r\nwrite matrices\r\n\\begin{align}\r\n\\textbf{T} &=\r\n\\begin{pmatrix}\r\nT_{++} \\hfill & T_{+-} \\\\\r\nT_{-+} & T_{--} \\hfill \r\n\\end{pmatrix} , \\nonumber \\\\\r\n& =\r\n\\begin{pmatrix}\r\ne^{\\beta (J + B)} \\hfill & e^{-\\beta J} \\hfill \\\\\r\ne^{-\\beta J} \\hfill & e^{\\beta (J - B)} \\hfill\r\n\\end{pmatrix}.\r\n\\end{align}\r\nand \r\n\\newcommand{\\rv}{\\textbf{r}}\r\n\\begin{equation}\r\n\\sum_i \\vec A \\cdot \\vec B = -P\\!\\int\\! \\rv \\cdot\r\n\\hat{\\mathbf{n}}\\, dA = P\\!\\int \\! {\\vec \\nabla} \\cdot \\rv\\, dV.\r\n\\end{equation}\r\n\r\n\\section{Tables}\r\nTables are a little more difficult. TeX\r\nautomatically calculates the width of the columns.\r\n\r\n\\begin{table}[h]\r\n\\begin{center}\r\n\\begin{tabular}{|l|l|r|l|}\r\n\\hline\r\nlattice & $d$ & $q$ & $T_{\\rm mf}/T_c$ \\\\\r\n\\hline\r\nsquare & 2 & 4 & 1.763 \\\\\r\n\\hline\r\ntriangular & 2 & 6 & 1.648 \\\\\r\n\\hline\r\ndiamond & 3 & 4 & 1.479 \\\\\r\n\\hline\r\nsimple cubic & 3 & 6 & 1.330 \\\\\r\n\\hline\r\nbcc & 3 & 8 & 1.260 \\\\\r\n\\hline\r\nfcc & 3 & 12 & 1.225 \\\\\r\n\\hline\r\n\\end{tabular}\r\n\\caption{\\label{tab:5/tc}Comparison of the mean-field predictions\r\nfor the critical temperature of the Ising model with exact results\r\nand the best known estimates for different spatial dimensions $d$\r\nand lattice symmetries.}\r\n\\end{center}\r\n\\end{table}\r\n\r\n\\section{Lists}\r\n\r\nSome example of formatted lists include the\r\nfollowing:\r\n\r\n\\begin{enumerate}\r\n\r\n\\item bread\r\n\r\n\\item cheese\r\n\r\n\\end{enumerate}\r\n\r\n\\begin{itemize}\r\n\r\n\\item Tom\r\n\r\n\\item Dick\r\n\r\n\\end{itemize}\r\n\r\n\\section{Figures}\r\n\r\nWe can make figures bigger or smaller by scaling them. Figure~\\ref{fig:lj}\r\nhas been scaled by 60\\%.\r\n\r\n\\begin{figure}[h]\r\n\\begin{center}\r\n\\includegraphics{figures/sine}\r\n\\caption{\\label{fig:typical}Show me a sine.}\r\n\\end{center}\r\n\\end{figure}\r\n\r\n\\begin{figure}[h]\r\n\\begin{center}\r\n\\scalebox{0.6}{\\includegraphics{figures/lj}}\r\n\\caption{\\label{fig:lj}Plot of the\r\nLennard-Jones potential\r\n$u(r)$. The potential is characterized by a length\r\n$\\sigma$ and an energy\r\n$\\epsilon$.}\r\n\\end{center}\r\n\\end{figure}\r\n\r\n\\section{Literal text}\r\nIt is desirable to print program code exactly as it is typed in a\r\nmonospaced font. Use \\verb \\begin{verbatim} and\r\n\\verb \\end{verbatim} as in the following example:\r\n\\begin{verbatim}\r\ndouble y0 = 10; // example of declaration and assignment statement\r\ndouble v0 = 0;  // initial velocity\r\ndouble t = 0;   // time\r\ndouble dt = 0.01; // time step\r\ndouble y = y0;\r\n\\end{verbatim}\r\nThe command \\verb \\verbatiminput{programs/Square.java}\\ allows\r\nyou to list the file \\texttt{Square.java} in the directory\r\nprograms.\r\n\r\n\\section{Special Symbols}\r\n\r\n\\subsection{Common Greek letters}\r\n\r\nThese commands may be used only in math mode. Only the most common\r\nletters are included here.\r\n\r\n$\\alpha, \r\n\\beta, \\gamma, \\Gamma,\r\n\\delta,\\Delta,\r\n\\epsilon, \\zeta, \\eta, \\theta, \\Theta, \\kappa,\r\n\\lambda, \\Lambda, \\mu, \\nu,\r\n\\xi, \\Xi,\r\n\\pi, \\Pi,\r\n\\rho,\r\n\\sigma, \r\n\\tau,\r\n\\phi, \\Phi,\r\n\\chi,\r\n\\psi, \\Psi,\r\n\\omega, \\Omega$\r\n\r\n\\subsection{Special symbols}\r\n\r\nThe derivative is defined as\r\n\\begin{equation}\r\n\\frac{dy}{dx} = \\lim_{\\Delta x \\to 0} \\frac{\\Delta y}\r\n{\\Delta x}\r\n\\end{equation}\r\n\\begin{equation}\r\nf(x) \\to y \\quad \\mbox{as} \\quad x \\to\r\nx_{0}\r\n\\end{equation}\r\n\\begin{equation}\r\nf(x) \\mathop {\\longrightarrow}\r\n\\limits_{x \\to x_0} y\r\n\\end{equation}\r\n\r\n\\noindent Order of magnitude:\r\n\\begin{equation}\r\n\\log_{10}f \\simeq n\r\n\\end{equation}\r\n\\begin{equation}\r\nf(x)\\sim 10^{n}\r\n\\end{equation}\r\nApproximate equality:\r\n\\begin{equation}\r\nf(x)\\simeq g(x)\r\n\\end{equation}\r\n\\LaTeX\\ is simple if we keep everything in proportion:\r\n\\begin{equation}\r\nf(x) \\propto x^3 .\r\n\\end{equation}\r\n\r\nFinally we can skip some space by using commands such as\r\n\\begin{verbatim}\r\n\\bigskip    \\medskip    \\smallskip    \\vspace{1pc}\r\n\\end{verbatim}\r\nThe space can be negative.\r\n\r\n\\section{\\color{red}Use of Color}\r\n\r\n{\\color{blue}{We can change colors for emphasis}},\r\n{\\color{green}{but}} {\\color{cyan}{who is going pay for the ink?}}\r\n\r\n\\section{\\label{morefig}Subfigures}\r\n\r\nAs soon as many students start becoming comfortable using \\LaTeX, they want\r\nto use some of its advanced features. So we now show how to place two\r\nfigures side by side.\r\n\r\n\\begin{figure}[h!]\r\n\\begin{center}\r\n\\subfigure[Real and imaginary.]{\r\n\\includegraphics[scale=0.5]{figures/reim}}\r\n\\subfigure[Amplitude and phase.]{\r\n\\includegraphics[scale=0.5]{figures/phase}}\r\n\\caption{\\label{fig:qm/complexfunctions} Two representations of complex\r\nwave functions.}\r\n\\end{center}\r\n\\end{figure}\r\n\r\nWe first have to include the necessary package,\r\n\\verb+\\usepackage{subfigure}+, which has to go in the preamble (before\r\n\\verb+\\begin{document}+). It sometimes can be difficult to place a figure in\r\nthe desired place.\r\n\r\nYour LaTeX document can be easily modified to make a poster or a screen\r\npresentation similar to (and better than) PowerPoint. Conversion to HTML is\r\nstraightforward. Comments on this tutorial are appreciated.\r\n\r\n\\begin{thebibliography}{5}\r\n\r\n\\bibitem{latex}Helmut Kopka and Patrick W. Daly, \\textsl{A Guide to\r\n\\LaTeX: Document Preparation for Beginners and Advanced Users},\r\nfourth edition, Addison-Wesley (2004).\r\n\r\n\\bibitem{website}Some useful links are\r\ngiven at \\url{}.\r\n\r\n\\end{thebibliography}\r\n\r\n{\\small \\noindent Updated 5 December 2006.}\r\n\\end{document}\r\n\r\n"
  },
  {
    "path": "Units/parser-tex.r/newcommand.d/expected.tags",
    "content": "\\\\bar\tinput.tex\t/^\\\\providecommand{\\\\bar}{\\\\section{#1}}$/;\"\tC\n\\\\baz\tinput.tex\t/^\\\\def\\\\baz{\\\\section{#1}}$/;\"\tC\n\\\\foo\tinput.tex\t/^\\\\renewcommand{\\\\foo}{\\\\section{#1}}$/;\"\tC\n\\\\mysection0\tinput.tex\t/^\\\\newcommand{\\\\mysection0}{\\\\section{#1}}$/;\"\tC\n\\\\mysection1\tinput.tex\t/^\\\\newcommand{\\\\mysection1}[1]{\\\\section{#1}}$/;\"\tC\n\\\\mysection2\tinput.tex\t/^\\\\newcommand{\\\\mysection2}[1][1]{\\\\section{#1}}$/;\"\tC\n\\\\mysection3\tinput.tex\t/^\\\\newcommand\\\\mysection3[1][1]{\\\\section{#1}}$/;\"\tC\n\\\\op\tinput.tex\t/^\\\\DeclareMathOperator{\\\\op}{foo}$/;\"\to\n"
  },
  {
    "path": "Units/parser-tex.r/newcommand.d/input.tex",
    "content": "\\documentclass{article}\n\\newcommand{\\mysection0}{\\section{#1}}\n\\newcommand{\\mysection1}[1]{\\section{#1}}\n\\newcommand{\\mysection2}[1][1]{\\section{#1}}\n\\newcommand\\mysection3[1][1]{\\section{#1}}\n\\renewcommand{\\foo}{\\section{#1}}\n\\providecommand{\\bar}{\\section{#1}}\n\\def\\baz{\\section{#1}}\n\\DeclareMathOperator{\\op}{foo}\n\\begin{document}\n\\mysection0{ABC}\n\\mysection1{EFG}\n\\mysection2{HIJ}\n\\end{document}\n"
  },
  {
    "path": "Units/parser-tex.r/newcounter.d/expected.tags",
    "content": "m\tinput.tex\t/^\\\\newcounter{m}{n}$/;\"\tN\nn\tinput.tex\t/^\\\\newcounter{n}$/;\"\tN\n"
  },
  {
    "path": "Units/parser-tex.r/newcounter.d/input.tex",
    "content": "\\documentclass{article}\n\n\\begin{document}\n\n\\newcounter{n}\n\n\\newcounter{m}{n}\n\n\\end{document}\n"
  },
  {
    "path": "Units/parser-tex.r/newenvironment.d/expected.tags",
    "content": "boxed\tinput.tex\t/^\\\\newenvironment{boxed}$/;\"\te\nboxedA\tinput.tex\t/^\\\\renewenvironment{boxedA}$/;\"\te\ntheorem\tinput.tex\t/^\\\\newtheorem{theorem}{Theorem}$/;\"\tt\ntheoremA\tinput.tex\t/^\\\\newtheorem{theoremA}{Theorem A}$/;\"\tt\n"
  },
  {
    "path": "Units/parser-tex.r/newenvironment.d/input.tex",
    "content": "\\documentclass{article}\n\\newtheorem{theoremA}{Theorem A}\n\\newenvironment{boxed}\n    {\\begin{center}\n    \\begin{tabular}{|p{0.9\\textwidth}|}\n    \\hline\\\\\n    }\n    { \n    \\\\\\\\\\hline\n    \\end{tabular} \n    \\end{center}\n    }\n\\renewenvironment{boxedA}\n    {\\begin{center}\n    \\begin{tabular}{|p{0.9\\textwidth}|}\n    \\hline\\\\\n    }\n    { \n    \\\\\\\\\\hline\n    \\end{tabular} \n    \\end{center}\n    }\n\\newtheorem{theorem}{Theorem}\n\\begin{document}\n\\begin{boxed}\nfoo\n\\end{boxed}\n\\begin{boxedA}\nfoo\n\\end{boxedA}\n\\begin{theorem}\nbar\n\\end{theorem}\n\\end{document}"
  },
  {
    "path": "Units/parser-tex.r/state-cleanup.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-tex.r/state-cleanup.d/expected.tags",
    "content": "PartA\tinput.tex\t/^\\\\part{PartA}$/;\"\tp\nSectionA\tinput.tex\t/^\\\\section{SectionA}$/;\"\ts\tpart:PartA\nSubsectionA\tinput.tex\t/^\\\\subsection{SubsectionA}$/;\"\tu\tsection:PartA\"\"SectionA\nSectionB\tinput-0.tex\t/^\\\\section{SectionB}$/;\"\ts\nSubsectionB\tinput-0.tex\t/^\\\\subsection{SubsectionB}$/;\"\tu\tsection:SectionB\n"
  },
  {
    "path": "Units/parser-tex.r/state-cleanup.d/input-0.tex",
    "content": "\\section{SectionB}\n\\subsection{SubsectionB}\n"
  },
  {
    "path": "Units/parser-tex.r/state-cleanup.d/input.tex",
    "content": "\\part{PartA}\n\\section{SectionA}\n\\subsection{SubsectionA}\n"
  },
  {
    "path": "Units/parser-tex.r/unicode-sections.d/expected.tags",
    "content": "ABC\tinput.tex\t/^\\\\section{ABC}$/;\"\ts\nDEF\tinput.tex\t/^\\\\section{DEF}$/;\"\ts\nZÖZÜZÄZßZ\tinput.tex\t/^\\\\section{ZÖZÜZÄZßZ}$/;\"\ts\n"
  },
  {
    "path": "Units/parser-tex.r/unicode-sections.d/input.tex",
    "content": "% https://github.com/universal-ctags/ctags/issues/1846\n\n\\begin{document}\n\\section{ABC}\n\\section{ZÖZÜZÄZßZ}\n\\section{DEF}\n\\end{document}\n"
  },
  {
    "path": "Units/parser-tex.r/xinput.d/args.ctags",
    "content": "--extras=+r\n--fields=+r\n--sort=no\n--roles-all.*=*\n"
  },
  {
    "path": "Units/parser-tex.r/xinput.d/expected.tags",
    "content": "document\tinput.tex\t/^\\\\begin{document}$/;\"\te\troles:used\ninput-1\tinput.tex\t/^\\\\include{input-1}$/;\"\ti\troles:included\ninput-2\tinput.tex\t/^\\\\input{input-2}$/;\"\ti\troles:input\ninput-3\tinput.tex\t/^\\\\bibliography{input-3}$/;\"\ti\troles:bibliography\nThe first section\tinput-1.tex\t/^\\\\section {The first section}$/;\"\ts\troles:def\nThe second section\tinput-2.tex\t/^\\\\section {The second section}$/;\"\ts\troles:def\n1957-doe_loc_ident\tinput-3.bib\t/^@article{1957-doe_loc_ident,$/;\"\ta\troles:def\n"
  },
  {
    "path": "Units/parser-tex.r/xinput.d/input-1.tex",
    "content": "\\section {The first section}\n"
  },
  {
    "path": "Units/parser-tex.r/xinput.d/input-2.tex",
    "content": "\\section {The second section}\n"
  },
  {
    "path": "Units/parser-tex.r/xinput.d/input-3.bib",
    "content": "@article{1957-doe_loc_ident,\n author    = \"John Doe\",\n title     = \"Exploration of the Location-Identity Split\",\n journal   = \"Journal of Splits\",\n year      =  1957,\n volume    =  3\n}\n"
  },
  {
    "path": "Units/parser-tex.r/xinput.d/input.tex",
    "content": "\\documentclass{article}\n\\begin{document}\n\\include{input-1}\n\\input{input-2}\n\n\\cite{1957-doe_loc_ident}\n\n\\bibliographystyle{plain}\n\\bibliography{input-3}\n\n\\end{document}\n"
  },
  {
    "path": "Units/parser-thrift.r/cpp_include.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+rln\n"
  },
  {
    "path": "Units/parser-thrift.r/cpp_include.d/expected.tags",
    "content": "iostream\tinput.thrift\t/^cpp_include \"iostream\"$/;\"\th\tline:1\tlanguage:C++\troles:local\nvector\tinput.thrift\t/^cpp_include 'vector'$/;\"\th\tline:2\tlanguage:C++\troles:local\n"
  },
  {
    "path": "Units/parser-thrift.r/cpp_include.d/input.thrift",
    "content": "cpp_include \"iostream\"\ncpp_include 'vector'\n"
  },
  {
    "path": "Units/parser-thrift.r/exception.d/args.ctags",
    "content": "--sort=no\n--kinds-Thrift=+zZ\n--fields=+iS\n--fields-Thrift=+{throws}\n"
  },
  {
    "path": "Units/parser-thrift.r/exception.d/expected.tags",
    "content": "Calculator\tinput.thrift\t/^service Calculator extends shared.SharedService {$/;\"\tv\tinherits:shared.SharedService\nping\tinput.thrift\t/^   void ping(),$/;\"\tf\tservice:Calculator\ttyperef:typename:void\tsignature:()\nadd\tinput.thrift\t/^   i32 add(1:i32 num1, 2:i32 num2),$/;\"\tf\tservice:Calculator\ttyperef:typename:i32 \tsignature:(1:i32 num1, 2:i32 num2)\nnum1\tinput.thrift\t/^   i32 add(1:i32 num1, 2:i32 num2),$/;\"\tz\tfunction:Calculator.add\ttyperef:typename:i32 \nnum2\tinput.thrift\t/^   i32 add(1:i32 num1, 2:i32 num2),$/;\"\tz\tfunction:Calculator.add\ttyperef:typename:i32 \ncalculate\tinput.thrift\t/^   i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),$/;\"\tf\tservice:Calculator\ttyperef:typename:i32 \tsignature:(1:i32 logid, 2:Work w)\tthrows:(1:InvalidOperation ouch)\nlogid\tinput.thrift\t/^   i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),$/;\"\tz\tfunction:Calculator.calculate\ttyperef:typename:i32 \nw\tinput.thrift\t/^   i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),$/;\"\tz\tfunction:Calculator.calculate\ttyperef:typename:Work\nouch\tinput.thrift\t/^   i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),$/;\"\tZ\tfunction:Calculator.calculate\ttyperef:typename:InvalidOperation\nzip\tinput.thrift\t/^   oneway void zip()$/;\"\tf\tservice:Calculator\ttyperef:typename:void\tsignature:()\nBadFish\tinput-0.thrift\t/^exception BadFish {$/;\"\tx\nfish\tinput-0.thrift\t/^  1: string       fish,       \\/\\/The problem fish$/;\"\tm\texception:BadFish\ttyperef:typename:string       \nerror_code\tinput-0.thrift\t/^  2: i16          error_code, \\/\\/The service specific error code$/;\"\tm\texception:BadFish\ttyperef:typename:i16          \nTradeHistory\tinput-0.thrift\t/^service TradeHistory {$/;\"\tv\nGetLastSale\tinput-0.thrift\t/^  double GetLastSale(1: string fish)$/;\"\tf\tservice:TradeHistory\ttyperef:typename:double \tsignature:(1: string fish)\tthrows:(1: BadFish bf)\nfish\tinput-0.thrift\t/^  double GetLastSale(1: string fish)$/;\"\tz\tfunction:TradeHistory.GetLastSale\ttyperef:typename:string \nbf\tinput-0.thrift\t/^    throws (1: BadFish bf),$/;\"\tZ\tfunction:TradeHistory.GetLastSale\ttyperef:typename:BadFish\n"
  },
  {
    "path": "Units/parser-thrift.r/exception.d/input-0.thrift",
    "content": "// Taken from https://freecontent.manning.com/apache-thrift-handling-exceptions/\nexception BadFish {\n  1: string       fish,       //The problem fish\n  2: i16          error_code, //The service specific error code\n}\n  \nservice TradeHistory {\n  double GetLastSale(1: string fish)\n    throws (1: BadFish bf),\n}\n  \n"
  },
  {
    "path": "Units/parser-thrift.r/exception.d/input.thrift",
    "content": "// Taken from https://thrift.apache.org/\n/**\n * Ahh, now onto the cool part, defining a service. Services just need a name\n * and can optionally inherit from another service using the extends keyword.\n */\nservice Calculator extends shared.SharedService {\n\n  /**\n   * A method definition looks like C code. It has a return type, arguments,\n   * and optionally a list of exceptions that it may throw. Note that argument\n   * lists and exception lists are specified using the exact same syntax as\n   * field lists in struct or exception definitions.\n   */\n\n   void ping(),\n\n   i32 add(1:i32 num1, 2:i32 num2),\n\n   i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),\n\n   /**\n    * This method has a oneway modifier. That means the client only makes\n    * a request and does not listen for any response at all. Oneway methods\n    * must be void.\n    */\n   oneway void zip()\n\n}\n"
  },
  {
    "path": "Units/parser-thrift.r/include.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-thrift.r/include.d/expected.tags",
    "content": "a.thrift\tinput.thrift\t/^include \"a.thrift\"$/;\"\tT\troles:included\nA.thrift\tinput.thrift\t/^include 'A.thrift'$/;\"\tT\troles:included\nb\"c'd\\\\e\\\\n.thrift\tinput.thrift\t/^include \"b\\\\\"c\\\\'d\\\\\\\\e\\\\n.thrift\"$/;\"\tT\troles:included\nB'C\"D\\\\E\\\\N.thrift\tinput.thrift\t/^include 'B\\\\'C\\\\\"D\\\\\\\\E\\\\N.thrift'$/;\"\tT\troles:included\n"
  },
  {
    "path": "Units/parser-thrift.r/include.d/input.thrift",
    "content": "include \"a.thrift\"\ninclude 'A.thrift'\ninclude \"b\\\"c\\'d\\\\e\\n.thrift\"\ninclude 'B\\'C\\\"D\\\\E\\N.thrift'\ninclude ''\ninclude \"\"\ninclude \"\ninclude '\n"
  },
  {
    "path": "Units/parser-thrift.r/simple-thrift.d/args.ctags",
    "content": "--sort=no\n--kinds-Thrift=+zZ\n--fields=+iS\n--fields-Thrift=+{throws}\n"
  },
  {
    "path": "Units/parser-thrift.r/simple-thrift.d/expected.tags",
    "content": "org.apache.hive.service.rpc.thrift\tinput.thrift\t/^namespace java org.apache.hive.service.rpc.thrift$/;\"\tn\ttarget:java\napache.hive.service.rpc.thrift\tinput.thrift\t/^namespace cpp apache.hive.service.rpc.thrift$/;\"\tn\ttarget:cpp\nTProtocolVersion\tinput.thrift\t/^enum TProtocolVersion {$/;\"\tg\nHIVE_CLI_SERVICE_PROTOCOL_V1\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V1,$/;\"\te\tenum:TProtocolVersion\nHIVE_CLI_SERVICE_PROTOCOL_V2\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V2$/;\"\te\tenum:TProtocolVersion\nHIVE_CLI_SERVICE_PROTOCOL_V3\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V3$/;\"\te\tenum:TProtocolVersion\nHIVE_CLI_SERVICE_PROTOCOL_V4\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V4$/;\"\te\tenum:TProtocolVersion\nHIVE_CLI_SERVICE_PROTOCOL_V5\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V5$/;\"\te\tenum:TProtocolVersion\nHIVE_CLI_SERVICE_PROTOCOL_V6\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V6$/;\"\te\tenum:TProtocolVersion\nHIVE_CLI_SERVICE_PROTOCOL_V7\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V7$/;\"\te\tenum:TProtocolVersion\nHIVE_CLI_SERVICE_PROTOCOL_V8\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V8$/;\"\te\tenum:TProtocolVersion\nHIVE_CLI_SERVICE_PROTOCOL_V9\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V9$/;\"\te\tenum:TProtocolVersion\nHIVE_CLI_SERVICE_PROTOCOL_V10\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V10$/;\"\te\tenum:TProtocolVersion\nHIVE_CLI_SERVICE_PROTOCOL_V11\tinput.thrift\t/^  HIVE_CLI_SERVICE_PROTOCOL_V11$/;\"\te\tenum:TProtocolVersion\nTTypeId\tinput.thrift\t/^enum TTypeId {$/;\"\tg\nBOOLEAN_TYPE\tinput.thrift\t/^  BOOLEAN_TYPE,$/;\"\te\tenum:TTypeId\nTINYINT_TYPE\tinput.thrift\t/^  TINYINT_TYPE,$/;\"\te\tenum:TTypeId\nSMALLINT_TYPE\tinput.thrift\t/^  SMALLINT_TYPE,$/;\"\te\tenum:TTypeId\nINT_TYPE\tinput.thrift\t/^  INT_TYPE,$/;\"\te\tenum:TTypeId\nBIGINT_TYPE\tinput.thrift\t/^  BIGINT_TYPE,$/;\"\te\tenum:TTypeId\nFLOAT_TYPE\tinput.thrift\t/^  FLOAT_TYPE,$/;\"\te\tenum:TTypeId\nDOUBLE_TYPE\tinput.thrift\t/^  DOUBLE_TYPE,$/;\"\te\tenum:TTypeId\nSTRING_TYPE\tinput.thrift\t/^  STRING_TYPE,$/;\"\te\tenum:TTypeId\nTIMESTAMP_TYPE\tinput.thrift\t/^  TIMESTAMP_TYPE,$/;\"\te\tenum:TTypeId\nBINARY_TYPE\tinput.thrift\t/^  BINARY_TYPE,$/;\"\te\tenum:TTypeId\nARRAY_TYPE\tinput.thrift\t/^  ARRAY_TYPE,$/;\"\te\tenum:TTypeId\nMAP_TYPE\tinput.thrift\t/^  MAP_TYPE,$/;\"\te\tenum:TTypeId\nSTRUCT_TYPE\tinput.thrift\t/^  STRUCT_TYPE,$/;\"\te\tenum:TTypeId\nUNION_TYPE\tinput.thrift\t/^  UNION_TYPE,$/;\"\te\tenum:TTypeId\nUSER_DEFINED_TYPE\tinput.thrift\t/^  USER_DEFINED_TYPE,$/;\"\te\tenum:TTypeId\nDECIMAL_TYPE\tinput.thrift\t/^  DECIMAL_TYPE,$/;\"\te\tenum:TTypeId\nNULL_TYPE\tinput.thrift\t/^  NULL_TYPE,$/;\"\te\tenum:TTypeId\nDATE_TYPE\tinput.thrift\t/^  DATE_TYPE,$/;\"\te\tenum:TTypeId\nVARCHAR_TYPE\tinput.thrift\t/^  VARCHAR_TYPE,$/;\"\te\tenum:TTypeId\nCHAR_TYPE\tinput.thrift\t/^  CHAR_TYPE,$/;\"\te\tenum:TTypeId\nINTERVAL_YEAR_MONTH_TYPE\tinput.thrift\t/^  INTERVAL_YEAR_MONTH_TYPE,$/;\"\te\tenum:TTypeId\nINTERVAL_DAY_TIME_TYPE\tinput.thrift\t/^  INTERVAL_DAY_TIME_TYPE,$/;\"\te\tenum:TTypeId\nTIMESTAMPLOCALTZ_TYPE\tinput.thrift\t/^  TIMESTAMPLOCALTZ_TYPE$/;\"\te\tenum:TTypeId\nPRIMITIVE_TYPES\tinput.thrift\t/^const set<TTypeId> PRIMITIVE_TYPES = [$/;\"\tC\ttyperef:typename:set<TTypeId> \nCOMPLEX_TYPES\tinput.thrift\t/^const set<TTypeId> COMPLEX_TYPES = [$/;\"\tC\ttyperef:typename:set<TTypeId> \nCOLLECTION_TYPES\tinput.thrift\t/^const set<TTypeId> COLLECTION_TYPES = [$/;\"\tC\ttyperef:typename:set<TTypeId> \nTYPE_NAMES\tinput.thrift\t/^const map<TTypeId,string> TYPE_NAMES = {$/;\"\tC\ttyperef:typename:map<TTypeId,string> \nTTypeEntryPtr\tinput.thrift\t/^typedef i32 TTypeEntryPtr$/;\"\tt\ttyperef:typename:i32 \nCHARACTER_MAXIMUM_LENGTH\tinput.thrift\t/^const string CHARACTER_MAXIMUM_LENGTH = \"characterMaximumLength\"$/;\"\tC\ttyperef:typename:string \nPRECISION\tinput.thrift\t/^const string PRECISION = \"precision\"$/;\"\tC\ttyperef:typename:string \nSCALE\tinput.thrift\t/^const string SCALE = \"scale\"$/;\"\tC\ttyperef:typename:string \nTTypeQualifierValue\tinput.thrift\t/^union TTypeQualifierValue {$/;\"\tu\ni32Value\tinput.thrift\t/^  1: optional i32 i32Value$/;\"\tm\tunion:TTypeQualifierValue\ttyperef:typename:i32 \nstringValue\tinput.thrift\t/^  2: optional string stringValue$/;\"\tm\tunion:TTypeQualifierValue\ttyperef:typename:string \nTTypeQualifiers\tinput.thrift\t/^struct TTypeQualifiers {$/;\"\ts\nqualifiers\tinput.thrift\t/^  1: required map <string, TTypeQualifierValue> qualifiers$/;\"\tm\tstruct:TTypeQualifiers\ttyperef:typename:map <string, TTypeQualifierValue> \nTPrimitiveTypeEntry\tinput.thrift\t/^struct TPrimitiveTypeEntry {$/;\"\ts\ntype\tinput.thrift\t/^  1: required TTypeId type$/;\"\tm\tstruct:TPrimitiveTypeEntry\ttyperef:typename:TTypeId\ntypeQualifiers\tinput.thrift\t/^  2: optional TTypeQualifiers typeQualifiers$/;\"\tm\tstruct:TPrimitiveTypeEntry\ttyperef:typename:TTypeQualifiers\nTArrayTypeEntry\tinput.thrift\t/^struct TArrayTypeEntry {$/;\"\ts\nobjectTypePtr\tinput.thrift\t/^  1: required TTypeEntryPtr objectTypePtr$/;\"\tm\tstruct:TArrayTypeEntry\ttyperef:typename:TTypeEntryPtr\nTMapTypeEntry\tinput.thrift\t/^struct TMapTypeEntry {$/;\"\ts\nkeyTypePtr\tinput.thrift\t/^  1: required TTypeEntryPtr keyTypePtr$/;\"\tm\tstruct:TMapTypeEntry\ttyperef:typename:TTypeEntryPtr\nvalueTypePtr\tinput.thrift\t/^  2: required TTypeEntryPtr valueTypePtr$/;\"\tm\tstruct:TMapTypeEntry\ttyperef:typename:TTypeEntryPtr\nTStructTypeEntry\tinput.thrift\t/^struct TStructTypeEntry {$/;\"\ts\nnameToTypePtr\tinput.thrift\t/^  1: required map<string, TTypeEntryPtr> nameToTypePtr$/;\"\tm\tstruct:TStructTypeEntry\ttyperef:typename:map<string, TTypeEntryPtr> \nTUnionTypeEntry\tinput.thrift\t/^struct TUnionTypeEntry {$/;\"\ts\nnameToTypePtr\tinput.thrift\t/^  1: required map<string, TTypeEntryPtr> nameToTypePtr$/;\"\tm\tstruct:TUnionTypeEntry\ttyperef:typename:map<string, TTypeEntryPtr> \nTUserDefinedTypeEntry\tinput.thrift\t/^struct TUserDefinedTypeEntry {$/;\"\ts\ntypeClassName\tinput.thrift\t/^  1: required string typeClassName$/;\"\tm\tstruct:TUserDefinedTypeEntry\ttyperef:typename:string \nTTypeEntry\tinput.thrift\t/^union TTypeEntry {$/;\"\tu\nprimitiveEntry\tinput.thrift\t/^  1: TPrimitiveTypeEntry primitiveEntry$/;\"\tm\tunion:TTypeEntry\ttyperef:typename:TPrimitiveTypeEntry\narrayEntry\tinput.thrift\t/^  2: TArrayTypeEntry arrayEntry$/;\"\tm\tunion:TTypeEntry\ttyperef:typename:TArrayTypeEntry\nmapEntry\tinput.thrift\t/^  3: TMapTypeEntry mapEntry$/;\"\tm\tunion:TTypeEntry\ttyperef:typename:TMapTypeEntry\nstructEntry\tinput.thrift\t/^  4: TStructTypeEntry structEntry$/;\"\tm\tunion:TTypeEntry\ttyperef:typename:TStructTypeEntry\nunionEntry\tinput.thrift\t/^  5: TUnionTypeEntry unionEntry$/;\"\tm\tunion:TTypeEntry\ttyperef:typename:TUnionTypeEntry\nuserDefinedTypeEntry\tinput.thrift\t/^  6: TUserDefinedTypeEntry userDefinedTypeEntry$/;\"\tm\tunion:TTypeEntry\ttyperef:typename:TUserDefinedTypeEntry\nTTypeDesc\tinput.thrift\t/^struct TTypeDesc {$/;\"\ts\ntypes\tinput.thrift\t/^  1: required list<TTypeEntry> types$/;\"\tm\tstruct:TTypeDesc\ttyperef:typename:list<TTypeEntry> \nTColumnDesc\tinput.thrift\t/^struct TColumnDesc {$/;\"\ts\ncolumnName\tinput.thrift\t/^  1: required string columnName$/;\"\tm\tstruct:TColumnDesc\ttyperef:typename:string \ntypeDesc\tinput.thrift\t/^  2: required TTypeDesc typeDesc$/;\"\tm\tstruct:TColumnDesc\ttyperef:typename:TTypeDesc\nposition\tinput.thrift\t/^  3: required i32 position$/;\"\tm\tstruct:TColumnDesc\ttyperef:typename:i32 \ncomment\tinput.thrift\t/^  4: optional string comment$/;\"\tm\tstruct:TColumnDesc\ttyperef:typename:string \nTTableSchema\tinput.thrift\t/^struct TTableSchema {$/;\"\ts\ncolumns\tinput.thrift\t/^  1: required list<TColumnDesc> columns$/;\"\tm\tstruct:TTableSchema\ttyperef:typename:list<TColumnDesc> \nTBoolValue\tinput.thrift\t/^struct TBoolValue {$/;\"\ts\nvalue\tinput.thrift\t/^  1: optional bool value$/;\"\tm\tstruct:TBoolValue\ttyperef:typename:bool \nTByteValue\tinput.thrift\t/^struct TByteValue {$/;\"\ts\nvalue\tinput.thrift\t/^  1: optional byte value$/;\"\tm\tstruct:TByteValue\ttyperef:typename:byte \nTI16Value\tinput.thrift\t/^struct TI16Value {$/;\"\ts\nvalue\tinput.thrift\t/^  1: optional i16 value$/;\"\tm\tstruct:TI16Value\ttyperef:typename:i16 \nTI32Value\tinput.thrift\t/^struct TI32Value {$/;\"\ts\nvalue\tinput.thrift\t/^  1: optional i32 value$/;\"\tm\tstruct:TI32Value\ttyperef:typename:i32 \nTI64Value\tinput.thrift\t/^struct TI64Value {$/;\"\ts\nvalue\tinput.thrift\t/^  1: optional i64 value$/;\"\tm\tstruct:TI64Value\ttyperef:typename:i64 \nTDoubleValue\tinput.thrift\t/^struct TDoubleValue {$/;\"\ts\nvalue\tinput.thrift\t/^  1: optional double value$/;\"\tm\tstruct:TDoubleValue\ttyperef:typename:double \nTStringValue\tinput.thrift\t/^struct TStringValue {$/;\"\ts\nvalue\tinput.thrift\t/^  1: optional string value$/;\"\tm\tstruct:TStringValue\ttyperef:typename:string \nTColumnValue\tinput.thrift\t/^union TColumnValue {$/;\"\tu\nboolVal\tinput.thrift\t/^  1: TBoolValue   boolVal      \\/\\/ BOOLEAN$/;\"\tm\tunion:TColumnValue\ttyperef:typename:TBoolValue\nbyteVal\tinput.thrift\t/^  2: TByteValue   byteVal      \\/\\/ TINYINT$/;\"\tm\tunion:TColumnValue\ttyperef:typename:TByteValue\ni16Val\tinput.thrift\t/^  3: TI16Value    i16Val       \\/\\/ SMALLINT$/;\"\tm\tunion:TColumnValue\ttyperef:typename:TI16Value\ni32Val\tinput.thrift\t/^  4: TI32Value    i32Val       \\/\\/ INT$/;\"\tm\tunion:TColumnValue\ttyperef:typename:TI32Value\ni64Val\tinput.thrift\t/^  5: TI64Value    i64Val       \\/\\/ BIGINT, TIMESTAMP$/;\"\tm\tunion:TColumnValue\ttyperef:typename:TI64Value\ndoubleVal\tinput.thrift\t/^  6: TDoubleValue doubleVal    \\/\\/ FLOAT, DOUBLE$/;\"\tm\tunion:TColumnValue\ttyperef:typename:TDoubleValue\nstringVal\tinput.thrift\t/^  7: TStringValue stringVal    \\/\\/ STRING, LIST, MAP, STRUCT, UNIONTYPE, BINARY, DECIMAL, NULL,/;\"\tm\tunion:TColumnValue\ttyperef:typename:TStringValue\nTRow\tinput.thrift\t/^struct TRow {$/;\"\ts\ncolVals\tinput.thrift\t/^  1: required list<TColumnValue> colVals$/;\"\tm\tstruct:TRow\ttyperef:typename:list<TColumnValue> \nTBoolColumn\tinput.thrift\t/^struct TBoolColumn {$/;\"\ts\nvalues\tinput.thrift\t/^  1: required list<bool> values$/;\"\tm\tstruct:TBoolColumn\ttyperef:typename:list<bool> \nnulls\tinput.thrift\t/^  2: required binary nulls$/;\"\tm\tstruct:TBoolColumn\ttyperef:typename:binary \nTByteColumn\tinput.thrift\t/^struct TByteColumn {$/;\"\ts\nvalues\tinput.thrift\t/^  1: required list<byte> values$/;\"\tm\tstruct:TByteColumn\ttyperef:typename:list<byte> \nnulls\tinput.thrift\t/^  2: required binary nulls$/;\"\tm\tstruct:TByteColumn\ttyperef:typename:binary \nTI16Column\tinput.thrift\t/^struct TI16Column {$/;\"\ts\nvalues\tinput.thrift\t/^  1: required list<i16> values$/;\"\tm\tstruct:TI16Column\ttyperef:typename:list<i16> \nnulls\tinput.thrift\t/^  2: required binary nulls$/;\"\tm\tstruct:TI16Column\ttyperef:typename:binary \nTI32Column\tinput.thrift\t/^struct TI32Column {$/;\"\ts\nvalues\tinput.thrift\t/^  1: required list<i32> values$/;\"\tm\tstruct:TI32Column\ttyperef:typename:list<i32> \nnulls\tinput.thrift\t/^  2: required binary nulls$/;\"\tm\tstruct:TI32Column\ttyperef:typename:binary \nTI64Column\tinput.thrift\t/^struct TI64Column {$/;\"\ts\nvalues\tinput.thrift\t/^  1: required list<i64> values$/;\"\tm\tstruct:TI64Column\ttyperef:typename:list<i64> \nnulls\tinput.thrift\t/^  2: required binary nulls$/;\"\tm\tstruct:TI64Column\ttyperef:typename:binary \nTDoubleColumn\tinput.thrift\t/^struct TDoubleColumn {$/;\"\ts\nvalues\tinput.thrift\t/^  1: required list<double> values$/;\"\tm\tstruct:TDoubleColumn\ttyperef:typename:list<double> \nnulls\tinput.thrift\t/^  2: required binary nulls$/;\"\tm\tstruct:TDoubleColumn\ttyperef:typename:binary \nTStringColumn\tinput.thrift\t/^struct TStringColumn {$/;\"\ts\nvalues\tinput.thrift\t/^  1: required list<string> values$/;\"\tm\tstruct:TStringColumn\ttyperef:typename:list<string> \nnulls\tinput.thrift\t/^  2: required binary nulls$/;\"\tm\tstruct:TStringColumn\ttyperef:typename:binary \nTBinaryColumn\tinput.thrift\t/^struct TBinaryColumn {$/;\"\ts\nvalues\tinput.thrift\t/^  1: required list<binary> values$/;\"\tm\tstruct:TBinaryColumn\ttyperef:typename:list<binary> \nnulls\tinput.thrift\t/^  2: required binary nulls$/;\"\tm\tstruct:TBinaryColumn\ttyperef:typename:binary \nTColumn\tinput.thrift\t/^union TColumn {$/;\"\tu\nboolVal\tinput.thrift\t/^  1: TBoolColumn   boolVal      \\/\\/ BOOLEAN$/;\"\tm\tunion:TColumn\ttyperef:typename:TBoolColumn\nbyteVal\tinput.thrift\t/^  2: TByteColumn   byteVal      \\/\\/ TINYINT$/;\"\tm\tunion:TColumn\ttyperef:typename:TByteColumn\ni16Val\tinput.thrift\t/^  3: TI16Column    i16Val       \\/\\/ SMALLINT$/;\"\tm\tunion:TColumn\ttyperef:typename:TI16Column\ni32Val\tinput.thrift\t/^  4: TI32Column    i32Val       \\/\\/ INT$/;\"\tm\tunion:TColumn\ttyperef:typename:TI32Column\ni64Val\tinput.thrift\t/^  5: TI64Column    i64Val       \\/\\/ BIGINT, TIMESTAMP$/;\"\tm\tunion:TColumn\ttyperef:typename:TI64Column\ndoubleVal\tinput.thrift\t/^  6: TDoubleColumn doubleVal    \\/\\/ FLOAT, DOUBLE$/;\"\tm\tunion:TColumn\ttyperef:typename:TDoubleColumn\nstringVal\tinput.thrift\t/^  7: TStringColumn stringVal    \\/\\/ STRING, LIST, MAP, STRUCT, UNIONTYPE, DECIMAL, NULL$/;\"\tm\tunion:TColumn\ttyperef:typename:TStringColumn\nbinaryVal\tinput.thrift\t/^  8: TBinaryColumn binaryVal    \\/\\/ BINARY$/;\"\tm\tunion:TColumn\ttyperef:typename:TBinaryColumn\nTRowSet\tinput.thrift\t/^struct TRowSet {$/;\"\ts\nstartRowOffset\tinput.thrift\t/^  1: required i64 startRowOffset$/;\"\tm\tstruct:TRowSet\ttyperef:typename:i64 \nrows\tinput.thrift\t/^  2: required list<TRow> rows$/;\"\tm\tstruct:TRowSet\ttyperef:typename:list<TRow> \ncolumns\tinput.thrift\t/^  3: optional list<TColumn> columns$/;\"\tm\tstruct:TRowSet\ttyperef:typename:list<TColumn> \nbinaryColumns\tinput.thrift\t/^  4: optional binary binaryColumns$/;\"\tm\tstruct:TRowSet\ttyperef:typename:binary \ncolumnCount\tinput.thrift\t/^  5: optional i32 columnCount$/;\"\tm\tstruct:TRowSet\ttyperef:typename:i32 \nTStatusCode\tinput.thrift\t/^enum TStatusCode {$/;\"\tg\nSUCCESS_STATUS\tinput.thrift\t/^  SUCCESS_STATUS,$/;\"\te\tenum:TStatusCode\nSUCCESS_WITH_INFO_STATUS\tinput.thrift\t/^  SUCCESS_WITH_INFO_STATUS,$/;\"\te\tenum:TStatusCode\nSTILL_EXECUTING_STATUS\tinput.thrift\t/^  STILL_EXECUTING_STATUS,$/;\"\te\tenum:TStatusCode\nERROR_STATUS\tinput.thrift\t/^  ERROR_STATUS,$/;\"\te\tenum:TStatusCode\nINVALID_HANDLE_STATUS\tinput.thrift\t/^  INVALID_HANDLE_STATUS$/;\"\te\tenum:TStatusCode\nTStatus\tinput.thrift\t/^struct TStatus {$/;\"\ts\nstatusCode\tinput.thrift\t/^  1: required TStatusCode statusCode$/;\"\tm\tstruct:TStatus\ttyperef:typename:TStatusCode\ninfoMessages\tinput.thrift\t/^  2: optional list<string> infoMessages$/;\"\tm\tstruct:TStatus\ttyperef:typename:list<string> \nsqlState\tinput.thrift\t/^  3: optional string sqlState  \\/\\/ as defined in the ISO\\/IEF CLI specification$/;\"\tm\tstruct:TStatus\ttyperef:typename:string \nerrorCode\tinput.thrift\t/^  4: optional i32 errorCode    \\/\\/ internal error code$/;\"\tm\tstruct:TStatus\ttyperef:typename:i32 \nerrorMessage\tinput.thrift\t/^  5: optional string errorMessage$/;\"\tm\tstruct:TStatus\ttyperef:typename:string \nTOperationState\tinput.thrift\t/^enum TOperationState {$/;\"\tg\nINITIALIZED_STATE\tinput.thrift\t/^  INITIALIZED_STATE,$/;\"\te\tenum:TOperationState\nRUNNING_STATE\tinput.thrift\t/^  RUNNING_STATE,$/;\"\te\tenum:TOperationState\nFINISHED_STATE\tinput.thrift\t/^  FINISHED_STATE,$/;\"\te\tenum:TOperationState\nCANCELED_STATE\tinput.thrift\t/^  CANCELED_STATE,$/;\"\te\tenum:TOperationState\nCLOSED_STATE\tinput.thrift\t/^  CLOSED_STATE,$/;\"\te\tenum:TOperationState\nERROR_STATE\tinput.thrift\t/^  ERROR_STATE,$/;\"\te\tenum:TOperationState\nUKNOWN_STATE\tinput.thrift\t/^  UKNOWN_STATE,$/;\"\te\tenum:TOperationState\nPENDING_STATE\tinput.thrift\t/^  PENDING_STATE,$/;\"\te\tenum:TOperationState\nTIMEDOUT_STATE\tinput.thrift\t/^  TIMEDOUT_STATE,$/;\"\te\tenum:TOperationState\nTIdentifier\tinput.thrift\t/^typedef string TIdentifier$/;\"\tt\ttyperef:typename:string \nTPattern\tinput.thrift\t/^typedef string TPattern$/;\"\tt\ttyperef:typename:string \nTPatternOrIdentifier\tinput.thrift\t/^typedef string TPatternOrIdentifier$/;\"\tt\ttyperef:typename:string \nTHandleIdentifier\tinput.thrift\t/^struct THandleIdentifier {$/;\"\ts\nguid\tinput.thrift\t/^  1: required binary guid,$/;\"\tm\tstruct:THandleIdentifier\ttyperef:typename:binary \nsecret\tinput.thrift\t/^  2: required binary secret,$/;\"\tm\tstruct:THandleIdentifier\ttyperef:typename:binary \nTSessionHandle\tinput.thrift\t/^struct TSessionHandle {$/;\"\ts\nsessionId\tinput.thrift\t/^  1: required THandleIdentifier sessionId$/;\"\tm\tstruct:TSessionHandle\ttyperef:typename:THandleIdentifier\nTOperationType\tinput.thrift\t/^enum TOperationType {$/;\"\tg\nEXECUTE_STATEMENT\tinput.thrift\t/^  EXECUTE_STATEMENT,$/;\"\te\tenum:TOperationType\nGET_TYPE_INFO\tinput.thrift\t/^  GET_TYPE_INFO,$/;\"\te\tenum:TOperationType\nGET_CATALOGS\tinput.thrift\t/^  GET_CATALOGS,$/;\"\te\tenum:TOperationType\nGET_SCHEMAS\tinput.thrift\t/^  GET_SCHEMAS,$/;\"\te\tenum:TOperationType\nGET_TABLES\tinput.thrift\t/^  GET_TABLES,$/;\"\te\tenum:TOperationType\nGET_TABLE_TYPES\tinput.thrift\t/^  GET_TABLE_TYPES,$/;\"\te\tenum:TOperationType\nGET_COLUMNS\tinput.thrift\t/^  GET_COLUMNS,$/;\"\te\tenum:TOperationType\nGET_FUNCTIONS\tinput.thrift\t/^  GET_FUNCTIONS,$/;\"\te\tenum:TOperationType\nUNKNOWN\tinput.thrift\t/^  UNKNOWN,$/;\"\te\tenum:TOperationType\nPROCEDURAL_SQL\tinput.thrift\t/^  PROCEDURAL_SQL$/;\"\te\tenum:TOperationType\nTOperationHandle\tinput.thrift\t/^struct TOperationHandle {$/;\"\ts\noperationId\tinput.thrift\t/^  1: required THandleIdentifier operationId$/;\"\tm\tstruct:TOperationHandle\ttyperef:typename:THandleIdentifier\noperationType\tinput.thrift\t/^  2: required TOperationType operationType$/;\"\tm\tstruct:TOperationHandle\ttyperef:typename:TOperationType\nhasResultSet\tinput.thrift\t/^  3: required bool hasResultSet$/;\"\tm\tstruct:TOperationHandle\ttyperef:typename:bool \nmodifiedRowCount\tinput.thrift\t/^  4: optional double modifiedRowCount$/;\"\tm\tstruct:TOperationHandle\ttyperef:typename:double \nTOpenSessionReq\tinput.thrift\t/^struct TOpenSessionReq {$/;\"\ts\nclient_protocol\tinput.thrift\t/^  1: required TProtocolVersion client_protocol = TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V10$/;\"\tm\tstruct:TOpenSessionReq\ttyperef:typename:TProtocolVersion\nusername\tinput.thrift\t/^  2: optional string username$/;\"\tm\tstruct:TOpenSessionReq\ttyperef:typename:string \npassword\tinput.thrift\t/^  3: optional string password$/;\"\tm\tstruct:TOpenSessionReq\ttyperef:typename:string \nconfiguration\tinput.thrift\t/^  4: optional map<string, string> configuration$/;\"\tm\tstruct:TOpenSessionReq\ttyperef:typename:map<string, string> \nTOpenSessionResp\tinput.thrift\t/^struct TOpenSessionResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TOpenSessionResp\ttyperef:typename:TStatus\nserverProtocolVersion\tinput.thrift\t/^  2: required TProtocolVersion serverProtocolVersion = TProtocolVersion.HIVE_CLI_SERVICE_PROTOCO/;\"\tm\tstruct:TOpenSessionResp\ttyperef:typename:TProtocolVersion\nsessionHandle\tinput.thrift\t/^  3: optional TSessionHandle sessionHandle$/;\"\tm\tstruct:TOpenSessionResp\ttyperef:typename:TSessionHandle\nconfiguration\tinput.thrift\t/^  4: optional map<string, string> configuration$/;\"\tm\tstruct:TOpenSessionResp\ttyperef:typename:map<string, string> \nTSetClientInfoReq\tinput.thrift\t/^struct TSetClientInfoReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle,$/;\"\tm\tstruct:TSetClientInfoReq\ttyperef:typename:TSessionHandle\nconfiguration\tinput.thrift\t/^  2: optional map<string, string> configuration$/;\"\tm\tstruct:TSetClientInfoReq\ttyperef:typename:map<string, string> \nTSetClientInfoResp\tinput.thrift\t/^struct TSetClientInfoResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TSetClientInfoResp\ttyperef:typename:TStatus\nTCloseSessionReq\tinput.thrift\t/^struct TCloseSessionReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TCloseSessionReq\ttyperef:typename:TSessionHandle\nTCloseSessionResp\tinput.thrift\t/^struct TCloseSessionResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TCloseSessionResp\ttyperef:typename:TStatus\nTGetInfoType\tinput.thrift\t/^enum TGetInfoType {$/;\"\tg\nCLI_MAX_DRIVER_CONNECTIONS\tinput.thrift\t/^  CLI_MAX_DRIVER_CONNECTIONS =           0,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_CONCURRENT_ACTIVITIES\tinput.thrift\t/^  CLI_MAX_CONCURRENT_ACTIVITIES =        1,$/;\"\te\tenum:TGetInfoType\nCLI_DATA_SOURCE_NAME\tinput.thrift\t/^  CLI_DATA_SOURCE_NAME =                 2,$/;\"\te\tenum:TGetInfoType\nCLI_FETCH_DIRECTION\tinput.thrift\t/^  CLI_FETCH_DIRECTION =                  8,$/;\"\te\tenum:TGetInfoType\nCLI_SERVER_NAME\tinput.thrift\t/^  CLI_SERVER_NAME =                      13,$/;\"\te\tenum:TGetInfoType\nCLI_SEARCH_PATTERN_ESCAPE\tinput.thrift\t/^  CLI_SEARCH_PATTERN_ESCAPE =            14,$/;\"\te\tenum:TGetInfoType\nCLI_DBMS_NAME\tinput.thrift\t/^  CLI_DBMS_NAME =                        17,$/;\"\te\tenum:TGetInfoType\nCLI_DBMS_VER\tinput.thrift\t/^  CLI_DBMS_VER =                         18,$/;\"\te\tenum:TGetInfoType\nCLI_ACCESSIBLE_TABLES\tinput.thrift\t/^  CLI_ACCESSIBLE_TABLES =                19,$/;\"\te\tenum:TGetInfoType\nCLI_ACCESSIBLE_PROCEDURES\tinput.thrift\t/^  CLI_ACCESSIBLE_PROCEDURES =            20,$/;\"\te\tenum:TGetInfoType\nCLI_CURSOR_COMMIT_BEHAVIOR\tinput.thrift\t/^  CLI_CURSOR_COMMIT_BEHAVIOR =           23,$/;\"\te\tenum:TGetInfoType\nCLI_DATA_SOURCE_READ_ONLY\tinput.thrift\t/^  CLI_DATA_SOURCE_READ_ONLY =            25,$/;\"\te\tenum:TGetInfoType\nCLI_DEFAULT_TXN_ISOLATION\tinput.thrift\t/^  CLI_DEFAULT_TXN_ISOLATION =            26,$/;\"\te\tenum:TGetInfoType\nCLI_IDENTIFIER_CASE\tinput.thrift\t/^  CLI_IDENTIFIER_CASE =                  28,$/;\"\te\tenum:TGetInfoType\nCLI_IDENTIFIER_QUOTE_CHAR\tinput.thrift\t/^  CLI_IDENTIFIER_QUOTE_CHAR =            29,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_COLUMN_NAME_LEN\tinput.thrift\t/^  CLI_MAX_COLUMN_NAME_LEN =              30,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_CURSOR_NAME_LEN\tinput.thrift\t/^  CLI_MAX_CURSOR_NAME_LEN =              31,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_SCHEMA_NAME_LEN\tinput.thrift\t/^  CLI_MAX_SCHEMA_NAME_LEN =              32,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_CATALOG_NAME_LEN\tinput.thrift\t/^  CLI_MAX_CATALOG_NAME_LEN =             34,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_TABLE_NAME_LEN\tinput.thrift\t/^  CLI_MAX_TABLE_NAME_LEN =               35,$/;\"\te\tenum:TGetInfoType\nCLI_SCROLL_CONCURRENCY\tinput.thrift\t/^  CLI_SCROLL_CONCURRENCY =               43,$/;\"\te\tenum:TGetInfoType\nCLI_TXN_CAPABLE\tinput.thrift\t/^  CLI_TXN_CAPABLE =                      46,$/;\"\te\tenum:TGetInfoType\nCLI_USER_NAME\tinput.thrift\t/^  CLI_USER_NAME =                        47,$/;\"\te\tenum:TGetInfoType\nCLI_TXN_ISOLATION_OPTION\tinput.thrift\t/^  CLI_TXN_ISOLATION_OPTION =             72,$/;\"\te\tenum:TGetInfoType\nCLI_INTEGRITY\tinput.thrift\t/^  CLI_INTEGRITY =                        73,$/;\"\te\tenum:TGetInfoType\nCLI_GETDATA_EXTENSIONS\tinput.thrift\t/^  CLI_GETDATA_EXTENSIONS =               81,$/;\"\te\tenum:TGetInfoType\nCLI_NULL_COLLATION\tinput.thrift\t/^  CLI_NULL_COLLATION =                   85,$/;\"\te\tenum:TGetInfoType\nCLI_ALTER_TABLE\tinput.thrift\t/^  CLI_ALTER_TABLE =                      86,$/;\"\te\tenum:TGetInfoType\nCLI_ORDER_BY_COLUMNS_IN_SELECT\tinput.thrift\t/^  CLI_ORDER_BY_COLUMNS_IN_SELECT =       90,$/;\"\te\tenum:TGetInfoType\nCLI_SPECIAL_CHARACTERS\tinput.thrift\t/^  CLI_SPECIAL_CHARACTERS =               94,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_COLUMNS_IN_GROUP_BY\tinput.thrift\t/^  CLI_MAX_COLUMNS_IN_GROUP_BY =          97,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_COLUMNS_IN_INDEX\tinput.thrift\t/^  CLI_MAX_COLUMNS_IN_INDEX =             98,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_COLUMNS_IN_ORDER_BY\tinput.thrift\t/^  CLI_MAX_COLUMNS_IN_ORDER_BY =          99,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_COLUMNS_IN_SELECT\tinput.thrift\t/^  CLI_MAX_COLUMNS_IN_SELECT =            100,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_COLUMNS_IN_TABLE\tinput.thrift\t/^  CLI_MAX_COLUMNS_IN_TABLE =             101,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_INDEX_SIZE\tinput.thrift\t/^  CLI_MAX_INDEX_SIZE =                   102,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_ROW_SIZE\tinput.thrift\t/^  CLI_MAX_ROW_SIZE =                     104,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_STATEMENT_LEN\tinput.thrift\t/^  CLI_MAX_STATEMENT_LEN =                105,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_TABLES_IN_SELECT\tinput.thrift\t/^  CLI_MAX_TABLES_IN_SELECT =             106,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_USER_NAME_LEN\tinput.thrift\t/^  CLI_MAX_USER_NAME_LEN =                107,$/;\"\te\tenum:TGetInfoType\nCLI_OJ_CAPABILITIES\tinput.thrift\t/^  CLI_OJ_CAPABILITIES =                  115,$/;\"\te\tenum:TGetInfoType\nCLI_XOPEN_CLI_YEAR\tinput.thrift\t/^  CLI_XOPEN_CLI_YEAR =                   10000,$/;\"\te\tenum:TGetInfoType\nCLI_CURSOR_SENSITIVITY\tinput.thrift\t/^  CLI_CURSOR_SENSITIVITY =               10001,$/;\"\te\tenum:TGetInfoType\nCLI_DESCRIBE_PARAMETER\tinput.thrift\t/^  CLI_DESCRIBE_PARAMETER =               10002,$/;\"\te\tenum:TGetInfoType\nCLI_CATALOG_NAME\tinput.thrift\t/^  CLI_CATALOG_NAME =                     10003,$/;\"\te\tenum:TGetInfoType\nCLI_COLLATION_SEQ\tinput.thrift\t/^  CLI_COLLATION_SEQ =                    10004,$/;\"\te\tenum:TGetInfoType\nCLI_MAX_IDENTIFIER_LEN\tinput.thrift\t/^  CLI_MAX_IDENTIFIER_LEN =               10005,$/;\"\te\tenum:TGetInfoType\nCLI_ODBC_KEYWORDS\tinput.thrift\t/^  CLI_ODBC_KEYWORDS =                    10006$/;\"\te\tenum:TGetInfoType\nTGetInfoValue\tinput.thrift\t/^union TGetInfoValue {$/;\"\tu\nstringValue\tinput.thrift\t/^  1: string stringValue$/;\"\tm\tunion:TGetInfoValue\ttyperef:typename:string \nsmallIntValue\tinput.thrift\t/^  2: i16 smallIntValue$/;\"\tm\tunion:TGetInfoValue\ttyperef:typename:i16 \nintegerBitmask\tinput.thrift\t/^  3: i32 integerBitmask$/;\"\tm\tunion:TGetInfoValue\ttyperef:typename:i32 \nintegerFlag\tinput.thrift\t/^  4: i32 integerFlag$/;\"\tm\tunion:TGetInfoValue\ttyperef:typename:i32 \nbinaryValue\tinput.thrift\t/^  5: i32 binaryValue$/;\"\tm\tunion:TGetInfoValue\ttyperef:typename:i32 \nlenValue\tinput.thrift\t/^  6: i64 lenValue$/;\"\tm\tunion:TGetInfoValue\ttyperef:typename:i64 \nTGetInfoReq\tinput.thrift\t/^struct TGetInfoReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetInfoReq\ttyperef:typename:TSessionHandle\ninfoType\tinput.thrift\t/^  2: required TGetInfoType infoType$/;\"\tm\tstruct:TGetInfoReq\ttyperef:typename:TGetInfoType\nTGetInfoResp\tinput.thrift\t/^struct TGetInfoResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetInfoResp\ttyperef:typename:TStatus\ninfoValue\tinput.thrift\t/^  2: required TGetInfoValue infoValue$/;\"\tm\tstruct:TGetInfoResp\ttyperef:typename:TGetInfoValue\nTExecuteStatementReq\tinput.thrift\t/^struct TExecuteStatementReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TExecuteStatementReq\ttyperef:typename:TSessionHandle\nstatement\tinput.thrift\t/^  2: required string statement$/;\"\tm\tstruct:TExecuteStatementReq\ttyperef:typename:string \nconfOverlay\tinput.thrift\t/^  3: optional map<string, string> confOverlay$/;\"\tm\tstruct:TExecuteStatementReq\ttyperef:typename:map<string, string> \nrunAsync\tinput.thrift\t/^  4: optional bool runAsync = false$/;\"\tm\tstruct:TExecuteStatementReq\ttyperef:typename:bool \nqueryTimeout\tinput.thrift\t/^  5: optional i64 queryTimeout = 0$/;\"\tm\tstruct:TExecuteStatementReq\ttyperef:typename:i64 \nTExecuteStatementResp\tinput.thrift\t/^struct TExecuteStatementResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TExecuteStatementResp\ttyperef:typename:TStatus\noperationHandle\tinput.thrift\t/^  2: optional TOperationHandle operationHandle$/;\"\tm\tstruct:TExecuteStatementResp\ttyperef:typename:TOperationHandle\nTGetTypeInfoReq\tinput.thrift\t/^struct TGetTypeInfoReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetTypeInfoReq\ttyperef:typename:TSessionHandle\nTGetTypeInfoResp\tinput.thrift\t/^struct TGetTypeInfoResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetTypeInfoResp\ttyperef:typename:TStatus\noperationHandle\tinput.thrift\t/^  2: optional TOperationHandle operationHandle$/;\"\tm\tstruct:TGetTypeInfoResp\ttyperef:typename:TOperationHandle\nTGetCatalogsReq\tinput.thrift\t/^struct TGetCatalogsReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetCatalogsReq\ttyperef:typename:TSessionHandle\nTGetCatalogsResp\tinput.thrift\t/^struct TGetCatalogsResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetCatalogsResp\ttyperef:typename:TStatus\noperationHandle\tinput.thrift\t/^  2: optional TOperationHandle operationHandle$/;\"\tm\tstruct:TGetCatalogsResp\ttyperef:typename:TOperationHandle\nTGetSchemasReq\tinput.thrift\t/^struct TGetSchemasReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetSchemasReq\ttyperef:typename:TSessionHandle\ncatalogName\tinput.thrift\t/^  2: optional TIdentifier catalogName$/;\"\tm\tstruct:TGetSchemasReq\ttyperef:typename:TIdentifier\nschemaName\tinput.thrift\t/^  3: optional TPatternOrIdentifier schemaName$/;\"\tm\tstruct:TGetSchemasReq\ttyperef:typename:TPatternOrIdentifier\nTGetSchemasResp\tinput.thrift\t/^struct TGetSchemasResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetSchemasResp\ttyperef:typename:TStatus\noperationHandle\tinput.thrift\t/^  2: optional TOperationHandle operationHandle$/;\"\tm\tstruct:TGetSchemasResp\ttyperef:typename:TOperationHandle\nTGetTablesReq\tinput.thrift\t/^struct TGetTablesReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetTablesReq\ttyperef:typename:TSessionHandle\ncatalogName\tinput.thrift\t/^  2: optional TPatternOrIdentifier catalogName$/;\"\tm\tstruct:TGetTablesReq\ttyperef:typename:TPatternOrIdentifier\nschemaName\tinput.thrift\t/^  3: optional TPatternOrIdentifier schemaName$/;\"\tm\tstruct:TGetTablesReq\ttyperef:typename:TPatternOrIdentifier\ntableName\tinput.thrift\t/^  4: optional TPatternOrIdentifier tableName$/;\"\tm\tstruct:TGetTablesReq\ttyperef:typename:TPatternOrIdentifier\ntableTypes\tinput.thrift\t/^  5: optional list<string> tableTypes$/;\"\tm\tstruct:TGetTablesReq\ttyperef:typename:list<string> \nTGetTablesResp\tinput.thrift\t/^struct TGetTablesResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetTablesResp\ttyperef:typename:TStatus\noperationHandle\tinput.thrift\t/^  2: optional TOperationHandle operationHandle$/;\"\tm\tstruct:TGetTablesResp\ttyperef:typename:TOperationHandle\nTGetTableTypesReq\tinput.thrift\t/^struct TGetTableTypesReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetTableTypesReq\ttyperef:typename:TSessionHandle\nTGetTableTypesResp\tinput.thrift\t/^struct TGetTableTypesResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetTableTypesResp\ttyperef:typename:TStatus\noperationHandle\tinput.thrift\t/^  2: optional TOperationHandle operationHandle$/;\"\tm\tstruct:TGetTableTypesResp\ttyperef:typename:TOperationHandle\nTGetColumnsReq\tinput.thrift\t/^struct TGetColumnsReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetColumnsReq\ttyperef:typename:TSessionHandle\ncatalogName\tinput.thrift\t/^  2: optional TIdentifier catalogName$/;\"\tm\tstruct:TGetColumnsReq\ttyperef:typename:TIdentifier\nschemaName\tinput.thrift\t/^  3: optional TPatternOrIdentifier schemaName$/;\"\tm\tstruct:TGetColumnsReq\ttyperef:typename:TPatternOrIdentifier\ntableName\tinput.thrift\t/^  4: optional TPatternOrIdentifier tableName$/;\"\tm\tstruct:TGetColumnsReq\ttyperef:typename:TPatternOrIdentifier\ncolumnName\tinput.thrift\t/^  5: optional TPatternOrIdentifier columnName$/;\"\tm\tstruct:TGetColumnsReq\ttyperef:typename:TPatternOrIdentifier\nTGetColumnsResp\tinput.thrift\t/^struct TGetColumnsResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetColumnsResp\ttyperef:typename:TStatus\noperationHandle\tinput.thrift\t/^  2: optional TOperationHandle operationHandle$/;\"\tm\tstruct:TGetColumnsResp\ttyperef:typename:TOperationHandle\nTGetFunctionsReq\tinput.thrift\t/^struct TGetFunctionsReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetFunctionsReq\ttyperef:typename:TSessionHandle\ncatalogName\tinput.thrift\t/^  2: optional TIdentifier catalogName$/;\"\tm\tstruct:TGetFunctionsReq\ttyperef:typename:TIdentifier\nschemaName\tinput.thrift\t/^  3: optional TPatternOrIdentifier schemaName$/;\"\tm\tstruct:TGetFunctionsReq\ttyperef:typename:TPatternOrIdentifier\nfunctionName\tinput.thrift\t/^  4: required TPatternOrIdentifier functionName$/;\"\tm\tstruct:TGetFunctionsReq\ttyperef:typename:TPatternOrIdentifier\nTGetFunctionsResp\tinput.thrift\t/^struct TGetFunctionsResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetFunctionsResp\ttyperef:typename:TStatus\noperationHandle\tinput.thrift\t/^  2: optional TOperationHandle operationHandle$/;\"\tm\tstruct:TGetFunctionsResp\ttyperef:typename:TOperationHandle\nTGetPrimaryKeysReq\tinput.thrift\t/^struct TGetPrimaryKeysReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetPrimaryKeysReq\ttyperef:typename:TSessionHandle\ncatalogName\tinput.thrift\t/^  2: optional TIdentifier catalogName$/;\"\tm\tstruct:TGetPrimaryKeysReq\ttyperef:typename:TIdentifier\nschemaName\tinput.thrift\t/^  3: optional TIdentifier schemaName$/;\"\tm\tstruct:TGetPrimaryKeysReq\ttyperef:typename:TIdentifier\ntableName\tinput.thrift\t/^  4: optional TIdentifier tableName$/;\"\tm\tstruct:TGetPrimaryKeysReq\ttyperef:typename:TIdentifier\nTGetPrimaryKeysResp\tinput.thrift\t/^struct TGetPrimaryKeysResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetPrimaryKeysResp\ttyperef:typename:TStatus\noperationHandle\tinput.thrift\t/^  2: optional TOperationHandle operationHandle$/;\"\tm\tstruct:TGetPrimaryKeysResp\ttyperef:typename:TOperationHandle\nTGetCrossReferenceReq\tinput.thrift\t/^struct TGetCrossReferenceReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetCrossReferenceReq\ttyperef:typename:TSessionHandle\nparentCatalogName\tinput.thrift\t/^  2: optional TIdentifier parentCatalogName$/;\"\tm\tstruct:TGetCrossReferenceReq\ttyperef:typename:TIdentifier\nparentSchemaName\tinput.thrift\t/^  3: optional TIdentifier parentSchemaName$/;\"\tm\tstruct:TGetCrossReferenceReq\ttyperef:typename:TIdentifier\nparentTableName\tinput.thrift\t/^  4: optional TIdentifier parentTableName$/;\"\tm\tstruct:TGetCrossReferenceReq\ttyperef:typename:TIdentifier\nforeignCatalogName\tinput.thrift\t/^  5: optional TIdentifier foreignCatalogName$/;\"\tm\tstruct:TGetCrossReferenceReq\ttyperef:typename:TIdentifier\nforeignSchemaName\tinput.thrift\t/^  6: optional TIdentifier foreignSchemaName$/;\"\tm\tstruct:TGetCrossReferenceReq\ttyperef:typename:TIdentifier\nforeignTableName\tinput.thrift\t/^  7: optional TIdentifier foreignTableName$/;\"\tm\tstruct:TGetCrossReferenceReq\ttyperef:typename:TIdentifier\nTGetCrossReferenceResp\tinput.thrift\t/^struct TGetCrossReferenceResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetCrossReferenceResp\ttyperef:typename:TStatus\noperationHandle\tinput.thrift\t/^  2: optional TOperationHandle operationHandle$/;\"\tm\tstruct:TGetCrossReferenceResp\ttyperef:typename:TOperationHandle\nTGetOperationStatusReq\tinput.thrift\t/^struct TGetOperationStatusReq {$/;\"\ts\noperationHandle\tinput.thrift\t/^  1: required TOperationHandle operationHandle$/;\"\tm\tstruct:TGetOperationStatusReq\ttyperef:typename:TOperationHandle\ngetProgressUpdate\tinput.thrift\t/^  2: optional bool getProgressUpdate$/;\"\tm\tstruct:TGetOperationStatusReq\ttyperef:typename:bool \nTGetOperationStatusResp\tinput.thrift\t/^struct TGetOperationStatusResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:TStatus\noperationState\tinput.thrift\t/^  2: optional TOperationState operationState$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:TOperationState\nsqlState\tinput.thrift\t/^  3: optional string sqlState$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:string \nerrorCode\tinput.thrift\t/^  4: optional i32 errorCode$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:i32 \nerrorMessage\tinput.thrift\t/^  5: optional string errorMessage$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:string \ntaskStatus\tinput.thrift\t/^  6: optional string taskStatus$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:string \noperationStarted\tinput.thrift\t/^  7: optional i64 operationStarted$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:i64 \noperationCompleted\tinput.thrift\t/^  8: optional i64 operationCompleted$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:i64 \nhasResultSet\tinput.thrift\t/^  9: optional bool hasResultSet$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:bool \nprogressUpdateResponse\tinput.thrift\t/^  10: optional TProgressUpdateResp progressUpdateResponse$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:TProgressUpdateResp\nnumModifiedRows\tinput.thrift\t/^  11: optional i64 numModifiedRows$/;\"\tm\tstruct:TGetOperationStatusResp\ttyperef:typename:i64 \nTCancelOperationReq\tinput.thrift\t/^struct TCancelOperationReq {$/;\"\ts\noperationHandle\tinput.thrift\t/^  1: required TOperationHandle operationHandle$/;\"\tm\tstruct:TCancelOperationReq\ttyperef:typename:TOperationHandle\nTCancelOperationResp\tinput.thrift\t/^struct TCancelOperationResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TCancelOperationResp\ttyperef:typename:TStatus\nTCloseOperationReq\tinput.thrift\t/^struct TCloseOperationReq {$/;\"\ts\noperationHandle\tinput.thrift\t/^  1: required TOperationHandle operationHandle$/;\"\tm\tstruct:TCloseOperationReq\ttyperef:typename:TOperationHandle\nTCloseOperationResp\tinput.thrift\t/^struct TCloseOperationResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TCloseOperationResp\ttyperef:typename:TStatus\nTGetResultSetMetadataReq\tinput.thrift\t/^struct TGetResultSetMetadataReq {$/;\"\ts\noperationHandle\tinput.thrift\t/^  1: required TOperationHandle operationHandle$/;\"\tm\tstruct:TGetResultSetMetadataReq\ttyperef:typename:TOperationHandle\nTGetResultSetMetadataResp\tinput.thrift\t/^struct TGetResultSetMetadataResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetResultSetMetadataResp\ttyperef:typename:TStatus\nschema\tinput.thrift\t/^  2: optional TTableSchema schema$/;\"\tm\tstruct:TGetResultSetMetadataResp\ttyperef:typename:TTableSchema\nTFetchOrientation\tinput.thrift\t/^enum TFetchOrientation {$/;\"\tg\nFETCH_NEXT\tinput.thrift\t/^  FETCH_NEXT,$/;\"\te\tenum:TFetchOrientation\nFETCH_PRIOR\tinput.thrift\t/^  FETCH_PRIOR,$/;\"\te\tenum:TFetchOrientation\nFETCH_RELATIVE\tinput.thrift\t/^  FETCH_RELATIVE,$/;\"\te\tenum:TFetchOrientation\nFETCH_ABSOLUTE\tinput.thrift\t/^  FETCH_ABSOLUTE,$/;\"\te\tenum:TFetchOrientation\nFETCH_FIRST\tinput.thrift\t/^  FETCH_FIRST,$/;\"\te\tenum:TFetchOrientation\nFETCH_LAST\tinput.thrift\t/^  FETCH_LAST$/;\"\te\tenum:TFetchOrientation\nTFetchResultsReq\tinput.thrift\t/^struct TFetchResultsReq {$/;\"\ts\noperationHandle\tinput.thrift\t/^  1: required TOperationHandle operationHandle$/;\"\tm\tstruct:TFetchResultsReq\ttyperef:typename:TOperationHandle\norientation\tinput.thrift\t/^  2: required TFetchOrientation orientation = TFetchOrientation.FETCH_NEXT$/;\"\tm\tstruct:TFetchResultsReq\ttyperef:typename:TFetchOrientation\nmaxRows\tinput.thrift\t/^  3: required i64 maxRows$/;\"\tm\tstruct:TFetchResultsReq\ttyperef:typename:i64 \nfetchType\tinput.thrift\t/^  4: optional i16 fetchType = 0$/;\"\tm\tstruct:TFetchResultsReq\ttyperef:typename:i16 \nTFetchResultsResp\tinput.thrift\t/^struct TFetchResultsResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TFetchResultsResp\ttyperef:typename:TStatus\nhasMoreRows\tinput.thrift\t/^  2: optional bool hasMoreRows$/;\"\tm\tstruct:TFetchResultsResp\ttyperef:typename:bool \nresults\tinput.thrift\t/^  3: optional TRowSet results$/;\"\tm\tstruct:TFetchResultsResp\ttyperef:typename:TRowSet\nTGetDelegationTokenReq\tinput.thrift\t/^struct  TGetDelegationTokenReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TGetDelegationTokenReq\ttyperef:typename:TSessionHandle\nowner\tinput.thrift\t/^  2: required string owner$/;\"\tm\tstruct:TGetDelegationTokenReq\ttyperef:typename:string \nrenewer\tinput.thrift\t/^  3: required string renewer$/;\"\tm\tstruct:TGetDelegationTokenReq\ttyperef:typename:string \nTGetDelegationTokenResp\tinput.thrift\t/^struct TGetDelegationTokenResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TGetDelegationTokenResp\ttyperef:typename:TStatus\ndelegationToken\tinput.thrift\t/^  2: optional string delegationToken$/;\"\tm\tstruct:TGetDelegationTokenResp\ttyperef:typename:string \nTCancelDelegationTokenReq\tinput.thrift\t/^struct TCancelDelegationTokenReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TCancelDelegationTokenReq\ttyperef:typename:TSessionHandle\ndelegationToken\tinput.thrift\t/^  2: required string delegationToken$/;\"\tm\tstruct:TCancelDelegationTokenReq\ttyperef:typename:string \nTCancelDelegationTokenResp\tinput.thrift\t/^struct TCancelDelegationTokenResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TCancelDelegationTokenResp\ttyperef:typename:TStatus\nTRenewDelegationTokenReq\tinput.thrift\t/^struct TRenewDelegationTokenReq {$/;\"\ts\nsessionHandle\tinput.thrift\t/^  1: required TSessionHandle sessionHandle$/;\"\tm\tstruct:TRenewDelegationTokenReq\ttyperef:typename:TSessionHandle\ndelegationToken\tinput.thrift\t/^  2: required string delegationToken$/;\"\tm\tstruct:TRenewDelegationTokenReq\ttyperef:typename:string \nTRenewDelegationTokenResp\tinput.thrift\t/^struct TRenewDelegationTokenResp {$/;\"\ts\nstatus\tinput.thrift\t/^  1: required TStatus status$/;\"\tm\tstruct:TRenewDelegationTokenResp\ttyperef:typename:TStatus\nTJobExecutionStatus\tinput.thrift\t/^enum TJobExecutionStatus {$/;\"\tg\nIN_PROGRESS\tinput.thrift\t/^    IN_PROGRESS,$/;\"\te\tenum:TJobExecutionStatus\nCOMPLETE\tinput.thrift\t/^    COMPLETE,$/;\"\te\tenum:TJobExecutionStatus\nNOT_AVAILABLE\tinput.thrift\t/^    NOT_AVAILABLE$/;\"\te\tenum:TJobExecutionStatus\nTProgressUpdateResp\tinput.thrift\t/^struct TProgressUpdateResp {$/;\"\ts\nheaderNames\tinput.thrift\t/^  1: required list<string> headerNames$/;\"\tm\tstruct:TProgressUpdateResp\ttyperef:typename:list<string> \nrows\tinput.thrift\t/^  2: required list<list<string>> rows$/;\"\tm\tstruct:TProgressUpdateResp\ttyperef:typename:list<list<string>> \nprogressedPercentage\tinput.thrift\t/^  3: required double progressedPercentage$/;\"\tm\tstruct:TProgressUpdateResp\ttyperef:typename:double \nstatus\tinput.thrift\t/^  4: required TJobExecutionStatus status$/;\"\tm\tstruct:TProgressUpdateResp\ttyperef:typename:TJobExecutionStatus\nfooterSummary\tinput.thrift\t/^  5: required string footerSummary$/;\"\tm\tstruct:TProgressUpdateResp\ttyperef:typename:string \nstartTime\tinput.thrift\t/^  6: required i64 startTime$/;\"\tm\tstruct:TProgressUpdateResp\ttyperef:typename:i64 \nTGetQueryIdReq\tinput.thrift\t/^struct TGetQueryIdReq {$/;\"\ts\noperationHandle\tinput.thrift\t/^  1: required TOperationHandle operationHandle$/;\"\tm\tstruct:TGetQueryIdReq\ttyperef:typename:TOperationHandle\nTGetQueryIdResp\tinput.thrift\t/^struct TGetQueryIdResp {$/;\"\ts\nqueryId\tinput.thrift\t/^  1: required string queryId$/;\"\tm\tstruct:TGetQueryIdResp\ttyperef:typename:string \nTCLIService\tinput.thrift\t/^service TCLIService {$/;\"\tv\nOpenSession\tinput.thrift\t/^  TOpenSessionResp OpenSession(1:TOpenSessionReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TOpenSessionResp\tsignature:(1:TOpenSessionReq req)\nreq\tinput.thrift\t/^  TOpenSessionResp OpenSession(1:TOpenSessionReq req);$/;\"\tz\tfunction:TCLIService.OpenSession\ttyperef:typename:TOpenSessionReq\nCloseSession\tinput.thrift\t/^  TCloseSessionResp CloseSession(1:TCloseSessionReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TCloseSessionResp\tsignature:(1:TCloseSessionReq req)\nreq\tinput.thrift\t/^  TCloseSessionResp CloseSession(1:TCloseSessionReq req);$/;\"\tz\tfunction:TCLIService.CloseSession\ttyperef:typename:TCloseSessionReq\nGetInfo\tinput.thrift\t/^  TGetInfoResp GetInfo(1:TGetInfoReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetInfoResp\tsignature:(1:TGetInfoReq req)\nreq\tinput.thrift\t/^  TGetInfoResp GetInfo(1:TGetInfoReq req);$/;\"\tz\tfunction:TCLIService.GetInfo\ttyperef:typename:TGetInfoReq\nExecuteStatement\tinput.thrift\t/^  TExecuteStatementResp ExecuteStatement(1:TExecuteStatementReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TExecuteStatementResp\tsignature:(1:TExecuteStatementReq req)\nreq\tinput.thrift\t/^  TExecuteStatementResp ExecuteStatement(1:TExecuteStatementReq req);$/;\"\tz\tfunction:TCLIService.ExecuteStatement\ttyperef:typename:TExecuteStatementReq\nGetTypeInfo\tinput.thrift\t/^  TGetTypeInfoResp GetTypeInfo(1:TGetTypeInfoReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetTypeInfoResp\tsignature:(1:TGetTypeInfoReq req)\nreq\tinput.thrift\t/^  TGetTypeInfoResp GetTypeInfo(1:TGetTypeInfoReq req);$/;\"\tz\tfunction:TCLIService.GetTypeInfo\ttyperef:typename:TGetTypeInfoReq\nGetCatalogs\tinput.thrift\t/^  TGetCatalogsResp GetCatalogs(1:TGetCatalogsReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetCatalogsResp\tsignature:(1:TGetCatalogsReq req)\nreq\tinput.thrift\t/^  TGetCatalogsResp GetCatalogs(1:TGetCatalogsReq req);$/;\"\tz\tfunction:TCLIService.GetCatalogs\ttyperef:typename:TGetCatalogsReq\nGetSchemas\tinput.thrift\t/^  TGetSchemasResp GetSchemas(1:TGetSchemasReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetSchemasResp\tsignature:(1:TGetSchemasReq req)\nreq\tinput.thrift\t/^  TGetSchemasResp GetSchemas(1:TGetSchemasReq req);$/;\"\tz\tfunction:TCLIService.GetSchemas\ttyperef:typename:TGetSchemasReq\nGetTables\tinput.thrift\t/^  TGetTablesResp GetTables(1:TGetTablesReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetTablesResp\tsignature:(1:TGetTablesReq req)\nreq\tinput.thrift\t/^  TGetTablesResp GetTables(1:TGetTablesReq req);$/;\"\tz\tfunction:TCLIService.GetTables\ttyperef:typename:TGetTablesReq\nGetTableTypes\tinput.thrift\t/^  TGetTableTypesResp GetTableTypes(1:TGetTableTypesReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetTableTypesResp\tsignature:(1:TGetTableTypesReq req)\nreq\tinput.thrift\t/^  TGetTableTypesResp GetTableTypes(1:TGetTableTypesReq req);$/;\"\tz\tfunction:TCLIService.GetTableTypes\ttyperef:typename:TGetTableTypesReq\nGetColumns\tinput.thrift\t/^  TGetColumnsResp GetColumns(1:TGetColumnsReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetColumnsResp\tsignature:(1:TGetColumnsReq req)\nreq\tinput.thrift\t/^  TGetColumnsResp GetColumns(1:TGetColumnsReq req);$/;\"\tz\tfunction:TCLIService.GetColumns\ttyperef:typename:TGetColumnsReq\nGetFunctions\tinput.thrift\t/^  TGetFunctionsResp GetFunctions(1:TGetFunctionsReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetFunctionsResp\tsignature:(1:TGetFunctionsReq req)\nreq\tinput.thrift\t/^  TGetFunctionsResp GetFunctions(1:TGetFunctionsReq req);$/;\"\tz\tfunction:TCLIService.GetFunctions\ttyperef:typename:TGetFunctionsReq\nGetPrimaryKeys\tinput.thrift\t/^  TGetPrimaryKeysResp GetPrimaryKeys(1:TGetPrimaryKeysReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetPrimaryKeysResp\tsignature:(1:TGetPrimaryKeysReq req)\nreq\tinput.thrift\t/^  TGetPrimaryKeysResp GetPrimaryKeys(1:TGetPrimaryKeysReq req);$/;\"\tz\tfunction:TCLIService.GetPrimaryKeys\ttyperef:typename:TGetPrimaryKeysReq\nGetCrossReference\tinput.thrift\t/^  TGetCrossReferenceResp GetCrossReference(1:TGetCrossReferenceReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetCrossReferenceResp\tsignature:(1:TGetCrossReferenceReq req)\nreq\tinput.thrift\t/^  TGetCrossReferenceResp GetCrossReference(1:TGetCrossReferenceReq req);$/;\"\tz\tfunction:TCLIService.GetCrossReference\ttyperef:typename:TGetCrossReferenceReq\nGetOperationStatus\tinput.thrift\t/^  TGetOperationStatusResp GetOperationStatus(1:TGetOperationStatusReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetOperationStatusResp\tsignature:(1:TGetOperationStatusReq req)\nreq\tinput.thrift\t/^  TGetOperationStatusResp GetOperationStatus(1:TGetOperationStatusReq req);$/;\"\tz\tfunction:TCLIService.GetOperationStatus\ttyperef:typename:TGetOperationStatusReq\nCancelOperation\tinput.thrift\t/^  TCancelOperationResp CancelOperation(1:TCancelOperationReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TCancelOperationResp\tsignature:(1:TCancelOperationReq req)\nreq\tinput.thrift\t/^  TCancelOperationResp CancelOperation(1:TCancelOperationReq req);$/;\"\tz\tfunction:TCLIService.CancelOperation\ttyperef:typename:TCancelOperationReq\nCloseOperation\tinput.thrift\t/^  TCloseOperationResp CloseOperation(1:TCloseOperationReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TCloseOperationResp\tsignature:(1:TCloseOperationReq req)\nreq\tinput.thrift\t/^  TCloseOperationResp CloseOperation(1:TCloseOperationReq req);$/;\"\tz\tfunction:TCLIService.CloseOperation\ttyperef:typename:TCloseOperationReq\nGetResultSetMetadata\tinput.thrift\t/^  TGetResultSetMetadataResp GetResultSetMetadata(1:TGetResultSetMetadataReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetResultSetMetadataResp\tsignature:(1:TGetResultSetMetadataReq req)\nreq\tinput.thrift\t/^  TGetResultSetMetadataResp GetResultSetMetadata(1:TGetResultSetMetadataReq req);$/;\"\tz\tfunction:TCLIService.GetResultSetMetadata\ttyperef:typename:TGetResultSetMetadataReq\nFetchResults\tinput.thrift\t/^  TFetchResultsResp FetchResults(1:TFetchResultsReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TFetchResultsResp\tsignature:(1:TFetchResultsReq req)\nreq\tinput.thrift\t/^  TFetchResultsResp FetchResults(1:TFetchResultsReq req);$/;\"\tz\tfunction:TCLIService.FetchResults\ttyperef:typename:TFetchResultsReq\nGetDelegationToken\tinput.thrift\t/^  TGetDelegationTokenResp GetDelegationToken(1:TGetDelegationTokenReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetDelegationTokenResp\tsignature:(1:TGetDelegationTokenReq req)\nreq\tinput.thrift\t/^  TGetDelegationTokenResp GetDelegationToken(1:TGetDelegationTokenReq req);$/;\"\tz\tfunction:TCLIService.GetDelegationToken\ttyperef:typename:TGetDelegationTokenReq\nCancelDelegationToken\tinput.thrift\t/^  TCancelDelegationTokenResp CancelDelegationToken(1:TCancelDelegationTokenReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TCancelDelegationTokenResp\tsignature:(1:TCancelDelegationTokenReq req)\nreq\tinput.thrift\t/^  TCancelDelegationTokenResp CancelDelegationToken(1:TCancelDelegationTokenReq req);$/;\"\tz\tfunction:TCLIService.CancelDelegationToken\ttyperef:typename:TCancelDelegationTokenReq\nRenewDelegationToken\tinput.thrift\t/^  TRenewDelegationTokenResp RenewDelegationToken(1:TRenewDelegationTokenReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TRenewDelegationTokenResp\tsignature:(1:TRenewDelegationTokenReq req)\nreq\tinput.thrift\t/^  TRenewDelegationTokenResp RenewDelegationToken(1:TRenewDelegationTokenReq req);$/;\"\tz\tfunction:TCLIService.RenewDelegationToken\ttyperef:typename:TRenewDelegationTokenReq\nGetQueryId\tinput.thrift\t/^  TGetQueryIdResp GetQueryId(1:TGetQueryIdReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TGetQueryIdResp\tsignature:(1:TGetQueryIdReq req)\nreq\tinput.thrift\t/^  TGetQueryIdResp GetQueryId(1:TGetQueryIdReq req);$/;\"\tz\tfunction:TCLIService.GetQueryId\ttyperef:typename:TGetQueryIdReq\nSetClientInfo\tinput.thrift\t/^  TSetClientInfoResp SetClientInfo(1:TSetClientInfoReq req);$/;\"\tf\tservice:TCLIService\ttyperef:typename:TSetClientInfoResp\tsignature:(1:TSetClientInfoReq req)\nreq\tinput.thrift\t/^  TSetClientInfoResp SetClientInfo(1:TSetClientInfoReq req);$/;\"\tz\tfunction:TCLIService.SetClientInfo\ttyperef:typename:TSetClientInfoReq\n"
  },
  {
    "path": "Units/parser-thrift.r/simple-thrift.d/input.thrift",
    "content": "// Taken from https://github.com/apache/hive/blob/master/service-rpc/if/TCLIService.thrift\n// ----\n// Licensed to the Apache Software Foundation (ASF) under one\n// or more contributor license agreements.  See the NOTICE file\n// distributed with this work for additional information\n// regarding copyright ownership.  The ASF licenses this file\n// to you under the Apache License, Version 2.0 (the\n// \"License\"); you may not use this file except in compliance\n// with the License.  You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Coding Conventions for this file:\n//\n// Structs/Enums/Unions\n// * Struct, Enum, and Union names begin with a \"T\",\n//   and use a capital letter for each new word, with no underscores.\n// * All fields should be declared as either optional or required.\n//\n// Functions\n// * Function names start with a capital letter and have a capital letter for\n//   each new word, with no underscores.\n// * Each function should take exactly one parameter, named TFunctionNameReq,\n//   and should return either void or TFunctionNameResp. This convention allows\n//   incremental updates.\n//\n// Services\n// * Service names begin with the letter \"T\", use a capital letter for each\n//   new word (with no underscores), and end with the word \"Service\".\n\nnamespace java org.apache.hive.service.rpc.thrift\nnamespace cpp apache.hive.service.rpc.thrift\n\n// List of protocol versions. A new token should be\n// added to the end of this list every time a change is made.\nenum TProtocolVersion {\n  HIVE_CLI_SERVICE_PROTOCOL_V1,\n\n  // V2 adds support for asynchronous execution\n  HIVE_CLI_SERVICE_PROTOCOL_V2\n\n  // V3 add varchar type, primitive type qualifiers\n  HIVE_CLI_SERVICE_PROTOCOL_V3\n\n  // V4 add decimal precision/scale, char type\n  HIVE_CLI_SERVICE_PROTOCOL_V4\n\n  // V5 adds error details when GetOperationStatus returns in error state\n  HIVE_CLI_SERVICE_PROTOCOL_V5\n\n  // V6 uses binary type for binary payload (was string) and uses columnar result set\n  HIVE_CLI_SERVICE_PROTOCOL_V6\n\n  // V7 adds support for delegation token based connection\n  HIVE_CLI_SERVICE_PROTOCOL_V7\n\n  // V8 adds support for interval types\n  HIVE_CLI_SERVICE_PROTOCOL_V8\n\n  // V9 adds support for serializing ResultSets in SerDe\n  HIVE_CLI_SERVICE_PROTOCOL_V9\n\n  // V10 adds support for in place updates via GetOperationStatus\n  HIVE_CLI_SERVICE_PROTOCOL_V10\n\n  // V11 adds timestamp with local time zone type\n  HIVE_CLI_SERVICE_PROTOCOL_V11\n}\n\nenum TTypeId {\n  BOOLEAN_TYPE,\n  TINYINT_TYPE,\n  SMALLINT_TYPE,\n  INT_TYPE,\n  BIGINT_TYPE,\n  FLOAT_TYPE,\n  DOUBLE_TYPE,\n  STRING_TYPE,\n  TIMESTAMP_TYPE,\n  BINARY_TYPE,\n  ARRAY_TYPE,\n  MAP_TYPE,\n  STRUCT_TYPE,\n  UNION_TYPE,\n  USER_DEFINED_TYPE,\n  DECIMAL_TYPE,\n  NULL_TYPE,\n  DATE_TYPE,\n  VARCHAR_TYPE,\n  CHAR_TYPE,\n  INTERVAL_YEAR_MONTH_TYPE,\n  INTERVAL_DAY_TIME_TYPE,\n  TIMESTAMPLOCALTZ_TYPE\n}\n\nconst set<TTypeId> PRIMITIVE_TYPES = [\n  TTypeId.BOOLEAN_TYPE,\n  TTypeId.TINYINT_TYPE,\n  TTypeId.SMALLINT_TYPE,\n  TTypeId.INT_TYPE,\n  TTypeId.BIGINT_TYPE,\n  TTypeId.FLOAT_TYPE,\n  TTypeId.DOUBLE_TYPE,\n  TTypeId.STRING_TYPE,\n  TTypeId.TIMESTAMP_TYPE,\n  TTypeId.BINARY_TYPE,\n  TTypeId.DECIMAL_TYPE,\n  TTypeId.NULL_TYPE,\n  TTypeId.DATE_TYPE,\n  TTypeId.VARCHAR_TYPE,\n  TTypeId.CHAR_TYPE,\n  TTypeId.INTERVAL_YEAR_MONTH_TYPE,\n  TTypeId.INTERVAL_DAY_TIME_TYPE,\n  TTypeId.TIMESTAMPLOCALTZ_TYPE\n]\n\nconst set<TTypeId> COMPLEX_TYPES = [\n  TTypeId.ARRAY_TYPE\n  TTypeId.MAP_TYPE\n  TTypeId.STRUCT_TYPE\n  TTypeId.UNION_TYPE\n  TTypeId.USER_DEFINED_TYPE\n]\n\nconst set<TTypeId> COLLECTION_TYPES = [\n  TTypeId.ARRAY_TYPE\n  TTypeId.MAP_TYPE\n]\n\nconst map<TTypeId,string> TYPE_NAMES = {\n  TTypeId.BOOLEAN_TYPE: \"BOOLEAN\",\n  TTypeId.TINYINT_TYPE: \"TINYINT\",\n  TTypeId.SMALLINT_TYPE: \"SMALLINT\",\n  TTypeId.INT_TYPE: \"INT\",\n  TTypeId.BIGINT_TYPE: \"BIGINT\",\n  TTypeId.FLOAT_TYPE: \"FLOAT\",\n  TTypeId.DOUBLE_TYPE: \"DOUBLE\",\n  TTypeId.STRING_TYPE: \"STRING\",\n  TTypeId.TIMESTAMP_TYPE: \"TIMESTAMP\",\n  TTypeId.BINARY_TYPE: \"BINARY\",\n  TTypeId.ARRAY_TYPE: \"ARRAY\",\n  TTypeId.MAP_TYPE: \"MAP\",\n  TTypeId.STRUCT_TYPE: \"STRUCT\",\n  TTypeId.UNION_TYPE: \"UNIONTYPE\",\n  TTypeId.DECIMAL_TYPE: \"DECIMAL\",\n  TTypeId.NULL_TYPE: \"NULL\"\n  TTypeId.DATE_TYPE: \"DATE\"\n  TTypeId.VARCHAR_TYPE: \"VARCHAR\"\n  TTypeId.CHAR_TYPE: \"CHAR\"\n  TTypeId.INTERVAL_YEAR_MONTH_TYPE: \"INTERVAL_YEAR_MONTH\"\n  TTypeId.INTERVAL_DAY_TIME_TYPE: \"INTERVAL_DAY_TIME\"\n  TTypeId.TIMESTAMPLOCALTZ_TYPE: \"TIMESTAMP WITH LOCAL TIME ZONE\"\n}\n\n// Thrift does not support recursively defined types or forward declarations,\n// which makes it difficult to represent Hive's nested types.\n// To get around these limitations TTypeDesc employs a type list that maps\n// integer \"pointers\" to TTypeEntry objects. The following examples show\n// how different types are represented using this scheme:\n//\n// \"INT\":\n// TTypeDesc {\n//   types = [\n//     TTypeEntry.primitive_entry {\n//       type = INT_TYPE\n//     }\n//   ]\n// }\n//\n// \"ARRAY<INT>\":\n// TTypeDesc {\n//   types = [\n//     TTypeEntry.array_entry {\n//       object_type_ptr = 1\n//     },\n//     TTypeEntry.primitive_entry {\n//       type = INT_TYPE\n//     }\n//   ]\n// }\n//\n// \"MAP<INT,STRING>\":\n// TTypeDesc {\n//   types = [\n//     TTypeEntry.map_entry {\n//       key_type_ptr = 1\n//       value_type_ptr = 2\n//     },\n//     TTypeEntry.primitive_entry {\n//       type = INT_TYPE\n//     },\n//     TTypeEntry.primitive_entry {\n//       type = STRING_TYPE\n//     }\n//   ]\n// }\n\ntypedef i32 TTypeEntryPtr\n\n// Valid TTypeQualifiers key names\nconst string CHARACTER_MAXIMUM_LENGTH = \"characterMaximumLength\"\n\n// Type qualifier key name for decimal\nconst string PRECISION = \"precision\"\nconst string SCALE = \"scale\"\n\nunion TTypeQualifierValue {\n  1: optional i32 i32Value\n  2: optional string stringValue\n}\n\n// Type qualifiers for primitive type.\nstruct TTypeQualifiers {\n  1: required map <string, TTypeQualifierValue> qualifiers\n}\n\n// Type entry for a primitive type.\nstruct TPrimitiveTypeEntry {\n  // The primitive type token. This must satisfy the condition\n  // that type is in the PRIMITIVE_TYPES set.\n  1: required TTypeId type\n  2: optional TTypeQualifiers typeQualifiers\n}\n\n// Type entry for an ARRAY type.\nstruct TArrayTypeEntry {\n  1: required TTypeEntryPtr objectTypePtr\n}\n\n// Type entry for a MAP type.\nstruct TMapTypeEntry {\n  1: required TTypeEntryPtr keyTypePtr\n  2: required TTypeEntryPtr valueTypePtr\n}\n\n// Type entry for a STRUCT type.\nstruct TStructTypeEntry {\n  1: required map<string, TTypeEntryPtr> nameToTypePtr\n}\n\n// Type entry for a UNIONTYPE type.\nstruct TUnionTypeEntry {\n  1: required map<string, TTypeEntryPtr> nameToTypePtr\n}\n\nstruct TUserDefinedTypeEntry {\n  // The fully qualified name of the class implementing this type.\n  1: required string typeClassName\n}\n\n// We use a union here since Thrift does not support inheritance.\nunion TTypeEntry {\n  1: TPrimitiveTypeEntry primitiveEntry\n  2: TArrayTypeEntry arrayEntry\n  3: TMapTypeEntry mapEntry\n  4: TStructTypeEntry structEntry\n  5: TUnionTypeEntry unionEntry\n  6: TUserDefinedTypeEntry userDefinedTypeEntry\n}\n\n// Type descriptor for columns.\nstruct TTypeDesc {\n  // The \"top\" type is always the first element of the list.\n  // If the top type is an ARRAY, MAP, STRUCT, or UNIONTYPE\n  // type, then subsequent elements represent nested types.\n  1: required list<TTypeEntry> types\n}\n\n// A result set column descriptor.\nstruct TColumnDesc {\n  // The name of the column\n  1: required string columnName\n\n  // The type descriptor for this column\n  2: required TTypeDesc typeDesc\n\n  // The ordinal position of this column in the schema\n  3: required i32 position\n\n  4: optional string comment\n}\n\n// Metadata used to describe the schema (column names, types, comments)\n// of result sets.\nstruct TTableSchema {\n  1: required list<TColumnDesc> columns\n}\n\n// A Boolean column value.\nstruct TBoolValue {\n  // NULL if value is unset.\n  1: optional bool value\n}\n\n// A Byte column value.\nstruct TByteValue {\n  // NULL if value is unset.\n  1: optional byte value\n}\n\n// A signed, 16 bit column value.\nstruct TI16Value {\n  // NULL if value is unset\n  1: optional i16 value\n}\n\n// A signed, 32 bit column value\nstruct TI32Value {\n  // NULL if value is unset\n  1: optional i32 value\n}\n\n// A signed 64 bit column value\nstruct TI64Value {\n  // NULL if value is unset\n  1: optional i64 value\n}\n\n// A floating point 64 bit column value\nstruct TDoubleValue {\n  // NULL if value is unset\n  1: optional double value\n}\n\nstruct TStringValue {\n  // NULL if value is unset\n  1: optional string value\n}\n\n// A single column value in a result set.\n// Note that Hive's type system is richer than Thrift's,\n// so in some cases we have to map multiple Hive types\n// to the same Thrift type. On the client-side this is\n// disambiguated by looking at the Schema of the\n// result set.\nunion TColumnValue {\n  1: TBoolValue   boolVal      // BOOLEAN\n  2: TByteValue   byteVal      // TINYINT\n  3: TI16Value    i16Val       // SMALLINT\n  4: TI32Value    i32Val       // INT\n  5: TI64Value    i64Val       // BIGINT, TIMESTAMP\n  6: TDoubleValue doubleVal    // FLOAT, DOUBLE\n  7: TStringValue stringVal    // STRING, LIST, MAP, STRUCT, UNIONTYPE, BINARY, DECIMAL, NULL, INTERVAL_YEAR_MONTH, INTERVAL_DAY_TIME\n}\n\n// Represents a row in a rowset.\nstruct TRow {\n  1: required list<TColumnValue> colVals\n}\n\nstruct TBoolColumn {\n  1: required list<bool> values\n  2: required binary nulls\n}\n\nstruct TByteColumn {\n  1: required list<byte> values\n  2: required binary nulls\n}\n\nstruct TI16Column {\n  1: required list<i16> values\n  2: required binary nulls\n}\n\nstruct TI32Column {\n  1: required list<i32> values\n  2: required binary nulls\n}\n\nstruct TI64Column {\n  1: required list<i64> values\n  2: required binary nulls\n}\n\nstruct TDoubleColumn {\n  1: required list<double> values\n  2: required binary nulls\n}\n\nstruct TStringColumn {\n  1: required list<string> values\n  2: required binary nulls\n}\n\nstruct TBinaryColumn {\n  1: required list<binary> values\n  2: required binary nulls\n}\n\n// Note that Hive's type system is richer than Thrift's,\n// so in some cases we have to map multiple Hive types\n// to the same Thrift type. On the client-side this is\n// disambiguated by looking at the Schema of the\n// result set.\nunion TColumn {\n  1: TBoolColumn   boolVal      // BOOLEAN\n  2: TByteColumn   byteVal      // TINYINT\n  3: TI16Column    i16Val       // SMALLINT\n  4: TI32Column    i32Val       // INT\n  5: TI64Column    i64Val       // BIGINT, TIMESTAMP\n  6: TDoubleColumn doubleVal    // FLOAT, DOUBLE\n  7: TStringColumn stringVal    // STRING, LIST, MAP, STRUCT, UNIONTYPE, DECIMAL, NULL\n  8: TBinaryColumn binaryVal    // BINARY\n}\n\n// Represents a rowset\nstruct TRowSet {\n  // The starting row offset of this rowset.\n  1: required i64 startRowOffset\n  2: required list<TRow> rows\n  3: optional list<TColumn> columns\n  4: optional binary binaryColumns\n  5: optional i32 columnCount\n}\n\n// The return status code contained in each response.\nenum TStatusCode {\n  SUCCESS_STATUS,\n  SUCCESS_WITH_INFO_STATUS,\n  STILL_EXECUTING_STATUS,\n  ERROR_STATUS,\n  INVALID_HANDLE_STATUS\n}\n\n// The return status of a remote request\nstruct TStatus {\n  1: required TStatusCode statusCode\n\n  // If status is SUCCESS_WITH_INFO, info_msgs may be populated with\n  // additional diagnostic information.\n  2: optional list<string> infoMessages\n\n  // If status is ERROR, then the following fields may be set\n  3: optional string sqlState  // as defined in the ISO/IEF CLI specification\n  4: optional i32 errorCode    // internal error code\n  5: optional string errorMessage\n}\n\n// The state of an operation (i.e. a query or other\n// asynchronous operation that generates a result set)\n// on the server.\nenum TOperationState {\n  // The operation has been initialized\n  INITIALIZED_STATE,\n\n  // The operation is running. In this state the result\n  // set is not available.\n  RUNNING_STATE,\n\n  // The operation has completed. When an operation is in\n  // this state its result set may be fetched.\n  FINISHED_STATE,\n\n  // The operation was canceled by a client\n  CANCELED_STATE,\n\n  // The operation was closed by a client\n  CLOSED_STATE,\n\n  // The operation failed due to an error\n  ERROR_STATE,\n\n  // The operation is in an unrecognized state\n  UKNOWN_STATE,\n\n  // The operation is in an pending state\n  PENDING_STATE,\n\n  // The operation is in an timedout state\n  TIMEDOUT_STATE,\n}\n\n// A string identifier. This is interpreted literally.\ntypedef string TIdentifier\n\n// A search pattern.\n//\n// Valid search pattern characters:\n// '_': Any single character.\n// '%': Any sequence of zero or more characters.\n// '\\': Escape character used to include special characters,\n//      e.g. '_', '%', '\\'. If a '\\' precedes a non-special\n//      character it has no special meaning and is interpreted\n//      literally.\ntypedef string TPattern\n\n\n// A search pattern or identifier. Used as input\n// parameter for many of the catalog functions.\ntypedef string TPatternOrIdentifier\n\nstruct THandleIdentifier {\n  // 16 byte globally unique identifier\n  // This is the public ID of the handle and\n  // can be used for reporting.\n  1: required binary guid,\n\n  // 16 byte secret generated by the server\n  // and used to verify that the handle is not\n  // being hijacked by another user.\n  2: required binary secret,\n}\n\n// Client-side handle to persistent\n// session information on the server-side.\nstruct TSessionHandle {\n  1: required THandleIdentifier sessionId\n}\n\n// The subtype of an OperationHandle.\nenum TOperationType {\n  EXECUTE_STATEMENT,\n  GET_TYPE_INFO,\n  GET_CATALOGS,\n  GET_SCHEMAS,\n  GET_TABLES,\n  GET_TABLE_TYPES,\n  GET_COLUMNS,\n  GET_FUNCTIONS,\n  UNKNOWN,\n  PROCEDURAL_SQL\n}\n\n// Client-side reference to a task running\n// asynchronously on the server.\nstruct TOperationHandle {\n  1: required THandleIdentifier operationId\n  2: required TOperationType operationType\n\n  // If hasResultSet = TRUE, then this operation\n  // generates a result set that can be fetched.\n  // Note that the result set may be empty.\n  //\n  // If hasResultSet = FALSE, then this operation\n  // does not generate a result set, and calling\n  // GetResultSetMetadata or FetchResults against\n  // this OperationHandle will generate an error.\n  3: required bool hasResultSet\n\n  // For operations that don't generate result sets,\n  // modifiedRowCount is either:\n  //\n  // 1) The number of rows that were modified by\n  //    the DML operation (e.g. number of rows inserted,\n  //    number of rows deleted, etc).\n  //\n  // 2) 0 for operations that don't modify or add rows.\n  //\n  // 3) < 0 if the operation is capable of modifiying rows,\n  //    but Hive is unable to determine how many rows were\n  //    modified. For example, Hive's LOAD DATA command\n  //    doesn't generate row count information because\n  //    Hive doesn't inspect the data as it is loaded.\n  //\n  // modifiedRowCount is unset if the operation generates\n  // a result set.\n  4: optional double modifiedRowCount\n}\n\n\n// OpenSession()\n//\n// Open a session (connection) on the server against\n// which operations may be executed.\nstruct TOpenSessionReq {\n  // The version of the HiveServer2 protocol that the client is using.\n  1: required TProtocolVersion client_protocol = TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V10\n\n  // Username and password for authentication.\n  // Depending on the authentication scheme being used,\n  // this information may instead be provided by a lower\n  // protocol layer, in which case these fields may be\n  // left unset.\n  2: optional string username\n  3: optional string password\n\n  // Configuration overlay which is applied when the session is\n  // first created.\n  4: optional map<string, string> configuration\n}\n\nstruct TOpenSessionResp {\n  1: required TStatus status\n\n  // The protocol version that the server is using.\n  2: required TProtocolVersion serverProtocolVersion = TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V10\n\n  // Session Handle\n  3: optional TSessionHandle sessionHandle\n\n  // The configuration settings for this session.\n  4: optional map<string, string> configuration\n}\n\nstruct TSetClientInfoReq {\n  1: required TSessionHandle sessionHandle,\n  2: optional map<string, string> configuration\n}\n\nstruct TSetClientInfoResp {\n  1: required TStatus status\n}\n\n\n// CloseSession()\n//\n// Closes the specified session and frees any resources\n// currently allocated to that session. Any open\n// operations in that session will be canceled.\nstruct TCloseSessionReq {\n  1: required TSessionHandle sessionHandle\n}\n\nstruct TCloseSessionResp {\n  1: required TStatus status\n}\n\n\n\nenum TGetInfoType {\n  CLI_MAX_DRIVER_CONNECTIONS =           0,\n  CLI_MAX_CONCURRENT_ACTIVITIES =        1,\n  CLI_DATA_SOURCE_NAME =                 2,\n  CLI_FETCH_DIRECTION =                  8,\n  CLI_SERVER_NAME =                      13,\n  CLI_SEARCH_PATTERN_ESCAPE =            14,\n  CLI_DBMS_NAME =                        17,\n  CLI_DBMS_VER =                         18,\n  CLI_ACCESSIBLE_TABLES =                19,\n  CLI_ACCESSIBLE_PROCEDURES =            20,\n  CLI_CURSOR_COMMIT_BEHAVIOR =           23,\n  CLI_DATA_SOURCE_READ_ONLY =            25,\n  CLI_DEFAULT_TXN_ISOLATION =            26,\n  CLI_IDENTIFIER_CASE =                  28,\n  CLI_IDENTIFIER_QUOTE_CHAR =            29,\n  CLI_MAX_COLUMN_NAME_LEN =              30,\n  CLI_MAX_CURSOR_NAME_LEN =              31,\n  CLI_MAX_SCHEMA_NAME_LEN =              32,\n  CLI_MAX_CATALOG_NAME_LEN =             34,\n  CLI_MAX_TABLE_NAME_LEN =               35,\n  CLI_SCROLL_CONCURRENCY =               43,\n  CLI_TXN_CAPABLE =                      46,\n  CLI_USER_NAME =                        47,\n  CLI_TXN_ISOLATION_OPTION =             72,\n  CLI_INTEGRITY =                        73,\n  CLI_GETDATA_EXTENSIONS =               81,\n  CLI_NULL_COLLATION =                   85,\n  CLI_ALTER_TABLE =                      86,\n  CLI_ORDER_BY_COLUMNS_IN_SELECT =       90,\n  CLI_SPECIAL_CHARACTERS =               94,\n  CLI_MAX_COLUMNS_IN_GROUP_BY =          97,\n  CLI_MAX_COLUMNS_IN_INDEX =             98,\n  CLI_MAX_COLUMNS_IN_ORDER_BY =          99,\n  CLI_MAX_COLUMNS_IN_SELECT =            100,\n  CLI_MAX_COLUMNS_IN_TABLE =             101,\n  CLI_MAX_INDEX_SIZE =                   102,\n  CLI_MAX_ROW_SIZE =                     104,\n  CLI_MAX_STATEMENT_LEN =                105,\n  CLI_MAX_TABLES_IN_SELECT =             106,\n  CLI_MAX_USER_NAME_LEN =                107,\n  CLI_OJ_CAPABILITIES =                  115,\n\n  CLI_XOPEN_CLI_YEAR =                   10000,\n  CLI_CURSOR_SENSITIVITY =               10001,\n  CLI_DESCRIBE_PARAMETER =               10002,\n  CLI_CATALOG_NAME =                     10003,\n  CLI_COLLATION_SEQ =                    10004,\n  CLI_MAX_IDENTIFIER_LEN =               10005,\n  CLI_ODBC_KEYWORDS =                    10006\n}\n\nunion TGetInfoValue {\n  1: string stringValue\n  2: i16 smallIntValue\n  3: i32 integerBitmask\n  4: i32 integerFlag\n  5: i32 binaryValue\n  6: i64 lenValue\n}\n\n// GetInfo()\n//\n// This function is based on ODBC's CLIGetInfo() function.\n// The function returns general information about the data source\n// using the same keys as ODBC.\nstruct TGetInfoReq {\n  // The sesssion to run this request against\n  1: required TSessionHandle sessionHandle\n\n  2: required TGetInfoType infoType\n}\n\nstruct TGetInfoResp {\n  1: required TStatus status\n\n  2: required TGetInfoValue infoValue\n}\n\n\n// ExecuteStatement()\n//\n// Execute a statement.\n// The returned OperationHandle can be used to check on the\n// status of the statement, and to fetch results once the\n// statement has finished executing.\nstruct TExecuteStatementReq {\n  // The session to execute the statement against\n  1: required TSessionHandle sessionHandle\n\n  // The statement to be executed (DML, DDL, SET, etc)\n  2: required string statement\n\n  // Configuration properties that are overlayed on top of the\n  // the existing session configuration before this statement\n  // is executed. These properties apply to this statement\n  // only and will not affect the subsequent state of the Session.\n  3: optional map<string, string> confOverlay\n\n  // Execute asynchronously when runAsync is true\n  4: optional bool runAsync = false\n\n  // The number of seconds after which the query will timeout on the server\n  5: optional i64 queryTimeout = 0\n}\n\nstruct TExecuteStatementResp {\n  1: required TStatus status\n  2: optional TOperationHandle operationHandle\n}\n\n// GetTypeInfo()\n//\n// Get information about types supported by the HiveServer instance.\n// The information is returned as a result set which can be fetched\n// using the OperationHandle provided in the response.\n//\n// Refer to the documentation for ODBC's CLIGetTypeInfo function for\n// the format of the result set.\nstruct TGetTypeInfoReq {\n  // The session to run this request against.\n  1: required TSessionHandle sessionHandle\n}\n\nstruct TGetTypeInfoResp {\n  1: required TStatus status\n  2: optional TOperationHandle operationHandle\n}\n\n\n// GetCatalogs()\n//\n// Returns the list of catalogs (databases)\n// Results are ordered by TABLE_CATALOG\n//\n// Resultset columns :\n// col1\n// name: TABLE_CAT\n// type: STRING\n// desc: Catalog name. NULL if not applicable.\n//\nstruct TGetCatalogsReq {\n  // Session to run this request against\n  1: required TSessionHandle sessionHandle\n}\n\nstruct TGetCatalogsResp {\n  1: required TStatus status\n  2: optional TOperationHandle operationHandle\n}\n\n\n// GetSchemas()\n//\n// Retrieves the schema names available in this database. \n// The results are ordered by TABLE_CATALOG and TABLE_SCHEM.\n// col1\n// name: TABLE_SCHEM\n// type: STRING\n// desc: schema name\n// col2\n// name: TABLE_CATALOG\n// type: STRING\n// desc: catalog name\nstruct TGetSchemasReq {\n  // Session to run this request against\n  1: required TSessionHandle sessionHandle\n\n  // Name of the catalog. Must not contain a search pattern.\n  2: optional TIdentifier catalogName\n\n  // schema name or pattern\n  3: optional TPatternOrIdentifier schemaName\n}\n\nstruct TGetSchemasResp {\n  1: required TStatus status\n  2: optional TOperationHandle operationHandle\n}\n\n\n// GetTables()\n//\n// Returns a list of tables with catalog, schema, and table\n// type information. The information is returned as a result\n// set which can be fetched using the OperationHandle\n// provided in the response.\n// Results are ordered by TABLE_TYPE, TABLE_CAT, TABLE_SCHEM, and TABLE_NAME\n//\n// Result Set Columns:\n//\n// col1\n// name: TABLE_CAT\n// type: STRING\n// desc: Catalog name. NULL if not applicable.\n//\n// col2\n// name: TABLE_SCHEM\n// type: STRING\n// desc: Schema name.\n//\n// col3\n// name: TABLE_NAME\n// type: STRING\n// desc: Table name.\n//\n// col4\n// name: TABLE_TYPE\n// type: STRING\n// desc: The table type, e.g. \"TABLE\", \"VIEW\", etc.\n//\n// col5\n// name: REMARKS\n// type: STRING\n// desc: Comments about the table\n//\nstruct TGetTablesReq {\n  // Session to run this request against\n  1: required TSessionHandle sessionHandle\n\n  // Name of the catalog or a search pattern.\n  2: optional TPatternOrIdentifier catalogName\n\n  // Name of the schema or a search pattern.\n  3: optional TPatternOrIdentifier schemaName\n\n  // Name of the table or a search pattern.\n  4: optional TPatternOrIdentifier tableName\n\n  // List of table types to match\n  // e.g. \"TABLE\", \"VIEW\", \"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n  // \"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\", etc.\n  5: optional list<string> tableTypes\n}\n\nstruct TGetTablesResp {\n  1: required TStatus status\n  2: optional TOperationHandle operationHandle\n}\n\n\n// GetTableTypes()\n//\n// Returns the table types available in this database.\n// The results are ordered by table type.\n//\n// col1\n// name: TABLE_TYPE\n// type: STRING\n// desc: Table type name.\nstruct TGetTableTypesReq {\n  // Session to run this request against\n  1: required TSessionHandle sessionHandle\n}\n\nstruct TGetTableTypesResp {\n  1: required TStatus status\n  2: optional TOperationHandle operationHandle\n}\n\n\n// GetColumns()\n//\n// Returns a list of columns in the specified tables.\n// The information is returned as a result set which can be fetched\n// using the OperationHandle provided in the response.\n// Results are ordered by TABLE_CAT, TABLE_SCHEM, TABLE_NAME,\n// and ORDINAL_POSITION.\n//\n// Result Set Columns are the same as those for the ODBC CLIColumns\n// function.\n//\nstruct TGetColumnsReq {\n  // Session to run this request against\n  1: required TSessionHandle sessionHandle\n\n  // Name of the catalog. Must not contain a search pattern.\n  2: optional TIdentifier catalogName\n\n  // Schema name or search pattern\n  3: optional TPatternOrIdentifier schemaName\n\n  // Table name or search pattern\n  4: optional TPatternOrIdentifier tableName\n\n  // Column name or search pattern\n  5: optional TPatternOrIdentifier columnName\n}\n\nstruct TGetColumnsResp {\n  1: required TStatus status\n  2: optional TOperationHandle operationHandle\n}\n\n\n// GetFunctions()\n//\n// Returns a list of functions supported by the data source. The\n// behavior of this function matches\n// java.sql.DatabaseMetaData.getFunctions() both in terms of\n// inputs and outputs.\n//\n// Result Set Columns:\n//\n// col1\n// name: FUNCTION_CAT\n// type: STRING\n// desc: Function catalog (may be null)\n//\n// col2\n// name: FUNCTION_SCHEM\n// type: STRING\n// desc: Function schema (may be null)\n//\n// col3\n// name: FUNCTION_NAME\n// type: STRING\n// desc: Function name. This is the name used to invoke the function.\n//\n// col4\n// name: REMARKS\n// type: STRING\n// desc: Explanatory comment on the function.\n//\n// col5\n// name: FUNCTION_TYPE\n// type: SMALLINT\n// desc: Kind of function. One of:\n//       * functionResultUnknown - Cannot determine if a return value or a table\n//                                 will be returned.\n//       * functionNoTable       - Does not a return a table.\n//       * functionReturnsTable  - Returns a table.\n//\n// col6\n// name: SPECIFIC_NAME\n// type: STRING\n// desc: The name which uniquely identifies this function within its schema.\n//       In this case this is the fully qualified class name of the class\n//       that implements this function.\n//\nstruct TGetFunctionsReq {\n  // Session to run this request against\n  1: required TSessionHandle sessionHandle\n\n  // A catalog name; must match the catalog name as it is stored in the\n  // database; \"\" retrieves those without a catalog; null means\n  // that the catalog name should not be used to narrow the search.\n  2: optional TIdentifier catalogName\n\n  // A schema name pattern; must match the schema name as it is stored\n  // in the database; \"\" retrieves those without a schema; null means\n  // that the schema name should not be used to narrow the search.\n  3: optional TPatternOrIdentifier schemaName\n\n  // A function name pattern; must match the function name as it is stored\n  // in the database.\n  4: required TPatternOrIdentifier functionName\n}\n\nstruct TGetFunctionsResp {\n  1: required TStatus status\n  2: optional TOperationHandle operationHandle\n}\n\nstruct TGetPrimaryKeysReq {\n  // Session to run this request against\n  1: required TSessionHandle sessionHandle\n\n  // Name of the catalog.\n  2: optional TIdentifier catalogName\n\n  // Name of the schema.\n  3: optional TIdentifier schemaName\n\n  // Name of the table.\n  4: optional TIdentifier tableName\n}\n\nstruct TGetPrimaryKeysResp {\n  1: required TStatus status\n  2: optional TOperationHandle operationHandle\n}\n\nstruct TGetCrossReferenceReq {\n  // Session to run this request against\n  1: required TSessionHandle sessionHandle\n\n  // Name of the parent catalog.\n  2: optional TIdentifier parentCatalogName\n\n  // Name of the parent schema.\n  3: optional TIdentifier parentSchemaName\n\n  // Name of the parent table.\n  4: optional TIdentifier parentTableName\n\n  // Name of the foreign catalog.\n  5: optional TIdentifier foreignCatalogName\n\n  // Name of the foreign schema.\n  6: optional TIdentifier foreignSchemaName\n\n  // Name of the foreign table.\n  7: optional TIdentifier foreignTableName\n}\n\nstruct TGetCrossReferenceResp {\n  1: required TStatus status\n  2: optional TOperationHandle operationHandle\n}\n\n// GetOperationStatus()\n//\n// Get the status of an operation running on the server.\nstruct TGetOperationStatusReq {\n  // Session to run this request against\n  1: required TOperationHandle operationHandle\n  // optional arguments to get progress information\n  2: optional bool getProgressUpdate\n}\n\nstruct TGetOperationStatusResp {\n  1: required TStatus status\n  2: optional TOperationState operationState\n\n  // If operationState is ERROR_STATE, then the following fields may be set\n  // sqlState as defined in the ISO/IEF CLI specification\n  3: optional string sqlState\n\n  // Internal error code\n  4: optional i32 errorCode\n\n  // Error message\n  5: optional string errorMessage\n\n  // List of statuses of sub tasks\n  6: optional string taskStatus\n\n  // When was the operation started\n  7: optional i64 operationStarted\n\n  // When was the operation completed\n  8: optional i64 operationCompleted\n\n  // If the operation has the result\n  9: optional bool hasResultSet\n\n  10: optional TProgressUpdateResp progressUpdateResponse\n\n  11: optional i64 numModifiedRows\n}\n\n\n// CancelOperation()\n//\n// Cancels processing on the specified operation handle and\n// frees any resources which were allocated.\nstruct TCancelOperationReq {\n  // Operation to cancel\n  1: required TOperationHandle operationHandle\n}\n\nstruct TCancelOperationResp {\n  1: required TStatus status\n}\n\n\n// CloseOperation()\n//\n// Given an operation in the FINISHED, CANCELED,\n// or ERROR states, CloseOperation() will free\n// all of the resources which were allocated on\n// the server to service the operation.\nstruct TCloseOperationReq {\n  1: required TOperationHandle operationHandle\n}\n\nstruct TCloseOperationResp {\n  1: required TStatus status\n}\n\n\n// GetResultSetMetadata()\n//\n// Retrieves schema information for the specified operation\nstruct TGetResultSetMetadataReq {\n  // Operation for which to fetch result set schema information\n  1: required TOperationHandle operationHandle\n}\n\nstruct TGetResultSetMetadataResp {\n  1: required TStatus status\n  2: optional TTableSchema schema\n}\n\n\nenum TFetchOrientation {\n  // Get the next rowset. The fetch offset is ignored.\n  FETCH_NEXT,\n\n  // Get the previous rowset. The fetch offset is ignored.\n  // NOT SUPPORTED\n  FETCH_PRIOR,\n\n  // Return the rowset at the given fetch offset relative\n  // to the curren rowset.\n  // NOT SUPPORTED\n  FETCH_RELATIVE,\n\n  // Return the rowset at the specified fetch offset.\n  // NOT SUPPORTED\n  FETCH_ABSOLUTE,\n\n  // Get the first rowset in the result set.\n  FETCH_FIRST,\n\n  // Get the last rowset in the result set.\n  // NOT SUPPORTED\n  FETCH_LAST\n}\n\n// FetchResults()\n//\n// Fetch rows from the server corresponding to\n// a particular OperationHandle.\nstruct TFetchResultsReq {\n  // Operation from which to fetch results.\n  1: required TOperationHandle operationHandle\n\n  // The fetch orientation. For V1 this must be either\n  // FETCH_NEXT or FETCH_FIRST. Defaults to FETCH_NEXT.\n  2: required TFetchOrientation orientation = TFetchOrientation.FETCH_NEXT\n\n  // Max number of rows that should be returned in\n  // the rowset.\n  3: required i64 maxRows\n\n  // The type of a fetch results request. 0 represents Query output. 1 represents Log\n  4: optional i16 fetchType = 0\n}\n\nstruct TFetchResultsResp {\n  1: required TStatus status\n\n  // TRUE if there are more rows left to fetch from the server.\n  2: optional bool hasMoreRows\n\n  // The rowset. This is optional so that we have the\n  // option in the future of adding alternate formats for\n  // representing result set data, e.g. delimited strings,\n  // binary encoded, etc.\n  3: optional TRowSet results\n}\n\n// GetDelegationToken()\n// Retrieve delegation token for the current user\nstruct  TGetDelegationTokenReq {\n  // session handle\n  1: required TSessionHandle sessionHandle\n\n  // userid for the proxy user\n  2: required string owner\n\n  // designated renewer userid\n  3: required string renewer\n}\n\nstruct TGetDelegationTokenResp {\n  // status of the request\n  1: required TStatus status\n\n  // delegation token string\n  2: optional string delegationToken\n}\n\n// CancelDelegationToken()\n// Cancel the given delegation token\nstruct TCancelDelegationTokenReq {\n  // session handle\n  1: required TSessionHandle sessionHandle\n\n  // delegation token to cancel\n  2: required string delegationToken\n}\n\nstruct TCancelDelegationTokenResp {\n  // status of the request\n  1: required TStatus status\n}\n\n// RenewDelegationToken()\n// Renew the given delegation token\nstruct TRenewDelegationTokenReq {\n  // session handle\n  1: required TSessionHandle sessionHandle\n\n  // delegation token to renew\n  2: required string delegationToken\n}\n\nstruct TRenewDelegationTokenResp {\n  // status of the request\n  1: required TStatus status\n}\n\nenum TJobExecutionStatus {\n    IN_PROGRESS,\n    COMPLETE,\n    NOT_AVAILABLE\n}\n\nstruct TProgressUpdateResp {\n  1: required list<string> headerNames\n  2: required list<list<string>> rows\n  3: required double progressedPercentage\n  4: required TJobExecutionStatus status\n  5: required string footerSummary\n  6: required i64 startTime\n}\n\nstruct TGetQueryIdReq {\n  1: required TOperationHandle operationHandle\n}\n\nstruct TGetQueryIdResp {\n  1: required string queryId\n}\n\nservice TCLIService {\n\n  TOpenSessionResp OpenSession(1:TOpenSessionReq req);\n\n  TCloseSessionResp CloseSession(1:TCloseSessionReq req);\n\n  TGetInfoResp GetInfo(1:TGetInfoReq req);\n\n  TExecuteStatementResp ExecuteStatement(1:TExecuteStatementReq req);\n\n  TGetTypeInfoResp GetTypeInfo(1:TGetTypeInfoReq req);\n\n  TGetCatalogsResp GetCatalogs(1:TGetCatalogsReq req);\n\n  TGetSchemasResp GetSchemas(1:TGetSchemasReq req);\n\n  TGetTablesResp GetTables(1:TGetTablesReq req);\n\n  TGetTableTypesResp GetTableTypes(1:TGetTableTypesReq req);\n\n  TGetColumnsResp GetColumns(1:TGetColumnsReq req);\n\n  TGetFunctionsResp GetFunctions(1:TGetFunctionsReq req);\n\n  TGetPrimaryKeysResp GetPrimaryKeys(1:TGetPrimaryKeysReq req);\n\n  TGetCrossReferenceResp GetCrossReference(1:TGetCrossReferenceReq req);\n\n  TGetOperationStatusResp GetOperationStatus(1:TGetOperationStatusReq req);\n\n  TCancelOperationResp CancelOperation(1:TCancelOperationReq req);\n\n  TCloseOperationResp CloseOperation(1:TCloseOperationReq req);\n\n  TGetResultSetMetadataResp GetResultSetMetadata(1:TGetResultSetMetadataReq req);\n\n  TFetchResultsResp FetchResults(1:TFetchResultsReq req);\n\n  TGetDelegationTokenResp GetDelegationToken(1:TGetDelegationTokenReq req);\n\n  TCancelDelegationTokenResp CancelDelegationToken(1:TCancelDelegationTokenReq req);\n\n  TRenewDelegationTokenResp RenewDelegationToken(1:TRenewDelegationTokenReq req);\n\n  TGetQueryIdResp GetQueryId(1:TGetQueryIdReq req);\n\n  TSetClientInfoResp SetClientInfo(1:TSetClientInfoReq req);\n}\n"
  },
  {
    "path": "Units/parser-toml.r/garbage-at-eof.b/README",
    "content": "Taken from https://github.com/BurntSushi/toml/raw/refs/heads/master/internal/toml-test/tests/invalid/encoding/bad-utf8-at-end.toml\nWith this input, the TOML parser entered an infinite loop.\n"
  },
  {
    "path": "Units/parser-toml.r/garbage-at-eof.b/expected.tags",
    "content": "x\tinput.toml\t/^x = \"\"\"\"\"\"/;\"\tK\n"
  },
  {
    "path": "Units/parser-toml.r/garbage-at-eof.b/features",
    "content": "packcc\n"
  },
  {
    "path": "Units/parser-toml.r/garbage-at-eof.b/input.toml",
    "content": "# There is a 0xda at after the quotes, and no EOL at the end of the file.\n#\n# This is a bit of an edge case: This indicates there should be two bytes\n# (0b1101_1010) but there is no byte to follow because it's the end of the file.\nx = \"\"\"\"\"\""
  },
  {
    "path": "Units/parser-toml.r/run-as-guest-with-bom.d/args.ctags",
    "content": "--languages=+TOML\n\n--sort=no\n--fields=+ne\n--extras=+g\n"
  },
  {
    "path": "Units/parser-toml.r/run-as-guest-with-bom.d/expected.tags",
    "content": "g\tinput.md\t/^[g]$/;\"\tt\tline:2\tend:3\na\tinput.md\t/^  a = \"\\/\"$/;\"\tK\tline:3\ttable:g\nm\tinput.md\t/^[m]$/;\"\tt\tline:4\tend:5\nb\tinput.md\t/^  b = \"\"$/;\"\tK\tline:5\ttable:m\n"
  },
  {
    "path": "Units/parser-toml.r/run-as-guest-with-bom.d/input.md",
    "content": "﻿```toml\n[g]\n  a = \"/\"\n[m]\n  b = \"\"\n```\n"
  },
  {
    "path": "Units/parser-toml.r/run-as-guest.d/args.ctags",
    "content": "--languages=+TOML\n\n--sort=no\n--fields=+ne\n--extras=+g\n"
  },
  {
    "path": "Units/parser-toml.r/run-as-guest.d/expected.tags",
    "content": "g\tinput.md\t/^[g]$/;\"\tt\tline:2\tend:3\na\tinput.md\t/^  a = \"\\/\"$/;\"\tK\tline:3\ttable:g\nm\tinput.md\t/^[m]$/;\"\tt\tline:4\tend:5\nb\tinput.md\t/^  b = \"\"$/;\"\tK\tline:5\ttable:m\n"
  },
  {
    "path": "Units/parser-toml.r/run-as-guest.d/input.md",
    "content": "```toml\n[g]\n  a = \"/\"\n[m]\n  b = \"\"\n```\n"
  },
  {
    "path": "Units/parser-toml.r/simple.d/args.ctags",
    "content": "--languages=+TOML\n\n--sort=no\n--fields=+K{nth}{end}{line}\n"
  },
  {
    "path": "Units/parser-toml.r/simple.d/expected.tags",
    "content": "title\tinput.toml\t/^title = \"TOML Example\"$/;\"\tqkey\tline:5\ndog.\"tater.man\"\tinput.toml\t/^[dog.\"tater.man\"]$/;\"\ttable\tline:7\tend:10\ntype.name\tinput.toml\t/^type.name = \"pug\"$/;\"\tqkey\tline:8\ttable:dog.\"tater.man\"\nx\tinput.toml\t/^x = 1$/;\"\tqkey\tline:9\ttable:dog.\"tater.man\"\nowner\tinput.toml\t/^[owner]$/;\"\ttable\tline:11\tend:14\nname\tinput.toml\t/^name = \"Tom Preston-Werner\"$/;\"\tqkey\tline:12\ttable:owner\ndob\tinput.toml\t/^dob = 1979-05-27T07:32:00-08:00 # First class dates$/;\"\tqkey\tline:13\ttable:owner\ndatabase\tinput.toml\t/^[database]$/;\"\ttable\tline:15\tend:20\nserver\tinput.toml\t/^server = \"192.168.1.1\"$/;\"\tqkey\tline:16\ttable:database\nports\tinput.toml\t/^ports = [ 8001, 8001, 8002 ]$/;\"\tqkey\tline:17\ttable:database\nconnection_max\tinput.toml\t/^connection_max = 5000$/;\"\tqkey\tline:18\ttable:database\nenabled\tinput.toml\t/^enabled = true$/;\"\tqkey\tline:19\ttable:database\nservers\tinput.toml\t/^[servers]$/;\"\ttable\tline:21\tend:23\nservers.alpha\tinput.toml\t/^  [servers.alpha]$/;\"\ttable\tline:24\tend:27\nip\tinput.toml\t/^  ip = \"10.0.0.1\"$/;\"\tqkey\tline:25\ttable:servers.alpha\ndc\tinput.toml\t/^  dc = \"eqdc10\"$/;\"\tqkey\tline:26\ttable:servers.alpha\nservers.beta\tinput.toml\t/^  [servers.beta]$/;\"\ttable\tline:28\tend:31\nip\tinput.toml\t/^  ip = \"10.0.0.2\"$/;\"\tqkey\tline:29\ttable:servers.beta\ndc\tinput.toml\t/^  dc = \"eqdc10\"$/;\"\tqkey\tline:30\ttable:servers.beta\nclients\tinput.toml\t/^[clients]$/;\"\ttable\tline:32\tend:40\ndata\tinput.toml\t/^data = [ [\"gamma\", \"delta\"], [1, 2] ]$/;\"\tqkey\tline:33\ttable:clients\nhosts\tinput.toml\t/^hosts = [$/;\"\tqkey\tline:36\ttable:clients\nproducts\tinput.toml\t/^[[products]] # 0$/;\"\tarraytable\tline:41\tend:44\tnth:0\nname\tinput.toml\t/^name = \"Hammer\"$/;\"\tqkey\tline:42\tarraytable:products\nsku\tinput.toml\t/^sku = 738594937$/;\"\tqkey\tline:43\tarraytable:products\nproducts\tinput.toml\t/^[[products]] # 1$/;\"\tarraytable\tline:45\tend:46\tnth:1\nproducts\tinput.toml\t/^[[products]] # 2$/;\"\tarraytable\tline:47\tend:50\tnth:2\nname\tinput.toml\t/^name = \"Nail\"$/;\"\tqkey\tline:48\tarraytable:products\nsku\tinput.toml\t/^sku = 284758393$/;\"\tqkey\tline:49\tarraytable:products\ncolor\tinput.toml\t/^color = \"gray\"$/;\"\tqkey\tline:50\tarraytable:products\nx\tinput-0.toml\t/^[x]$/;\"\ttable\tline:1\tend:4\ny\tinput-0.toml\t/^y = 1$/;\"\tqkey\tline:2\ttable:x\n\"\"\tinput-0.toml\t/^\"\" = 2$/;\"\tqkey\tline:3\ttable:x\n''\tinput-0.toml\t/^'' = 3$/;\"\tqkey\tline:4\ttable:x\n"
  },
  {
    "path": "Units/parser-toml.r/simple.d/features",
    "content": "packcc\n"
  },
  {
    "path": "Units/parser-toml.r/simple.d/input-0.toml",
    "content": "[x]\ny = 1\n\"\" = 2\n'' = 3\n"
  },
  {
    "path": "Units/parser-toml.r/simple.d/input.toml",
    "content": "## Taken from https://toml.io/en/v0.5.0#example\n\n# This is a TOML document.\n\ntitle = \"TOML Example\"\n\n[dog.\"tater.man\"]\ntype.name = \"pug\"\nx = 1\n\n[owner]\nname = \"Tom Preston-Werner\"\ndob = 1979-05-27T07:32:00-08:00 # First class dates\n\n[database]\nserver = \"192.168.1.1\"\nports = [ 8001, 8001, 8002 ]\nconnection_max = 5000\nenabled = true\n\n[servers]\n\n  # Indentation (tabs and/or spaces) is allowed but not required\n  [servers.alpha]\n  ip = \"10.0.0.1\"\n  dc = \"eqdc10\"\n\n  [servers.beta]\n  ip = \"10.0.0.2\"\n  dc = \"eqdc10\"\n\n[clients]\ndata = [ [\"gamma\", \"delta\"], [1, 2] ]\n\n# Line breaks are OK when inside arrays\nhosts = [\n  \"alpha\",\n  \"omega\"\n]\n\n[[products]] # 0\nname = \"Hammer\"\nsku = 738594937\n\n[[products]] # 1\n\n[[products]] # 2\nname = \"Nail\"\nsku = 284758393\ncolor = \"gray\"\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-altstep.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-altstep.d/expected.tags",
    "content": "Altsteps\tinput.ttcn\t/^module Altsteps$/;\"\tM\nalt_guard\tinput.ttcn\t/^    altstep alt_guard () runs on CoffeeMachine$/;\"\ta\nalt_catchAnything\tinput.ttcn\t/^    altstep alt_catchAnything ()$/;\"\ta\nactivateAltsteps\tinput.ttcn\t/^    function activateAltsteps ()$/;\"\tf\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-altstep.d/input.ttcn",
    "content": "module Altsteps\n{\n\n    altstep alt_guard () runs on CoffeeMachine\n    {\n        [] guard.timeout { setverdict( fail ) }\n    }\n\n    altstep alt_catchAnything ()\n        runs on CoffeeMachine\n    {\n        [] CoffeePort.receive(?) { \n        setverdict( fail )\n        }\n    }\n\n    function activateAltsteps ()\n        runs on CoffeeMachine \n    {\n      activate(alt_guard())\n      activate(alt_catchAnything())\n    }\n\n}\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-comments.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-comments.d/expected.tags",
    "content": "f\tinput.ttcn\t/^var integer f := 64\\/2$/;\"\tv\ng\tinput.ttcn\t/^var integer g := 64 \\/ 2$/;\"\tv\nCoffee0\tinput-0.ttcn\t/^type record Coffee0$/;\"\tt\nid0\tinput-0.ttcn\t/^    integer id0,$/;\"\tm\ndescription0\tinput-0.ttcn\t/^    charstring description0$/;\"\tm\nCoffee1\tinput-1.ttcn\t/^type record Coffee1$/;\"\tt\nid1\tinput-1.ttcn\t/^    integer id1,$/;\"\tm\ndescription1\tinput-1.ttcn\t/^    charstring description1$/;\"\tm\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-comments.d/input-0.ttcn",
    "content": "type record Coffee0\n{\n    // whitespaces after comment\t\n    integer id0,\n    charstring description0\n}\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-comments.d/input-1.ttcn",
    "content": "type record Coffee1\n{\n    /* whitespaces after comment */\n    integer id1,\n    charstring description1\n}\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-comments.d/input.ttcn",
    "content": "\n\n// var integer a := 2 \n\n/* var integer b := 4 */\n\n/*\n   var integer c := 8\n*/\n\n/*\n * var indeger d := 16\n */\n\n/**\n* var integer e := 32\n*/\n\nvar integer f := 64/2\nvar integer g := 64 / 2\n\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-component.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-component.d/expected.tags",
    "content": "CoffeeMachine\tinput.ttcn\t/^module CoffeeMachine$/;\"\tM\nIntegerInputPortType\tinput.ttcn\t/^   type port IntegerInputPortType message { in integer }$/;\"\tt\nCharstringOutputPortType\tinput.ttcn\t/^   type port CharstringOutputPortType message { out charstring }$/;\"\tt\nCoffeeMachineComponentType\tinput.ttcn\t/^   type component CoffeeMachineComponentType$/;\"\tt\nInputPort\tinput.ttcn\t/^      port IntegerInputPortType InputPort;$/;\"\tp\nOutputPort\tinput.ttcn\t/^      port CharstringOutputPortType OutputPort;$/;\"\tp\nmachine\tinput.ttcn\t/^   var CoffeeMachineComponentType machine$/;\"\tv\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-component.d/input.ttcn",
    "content": "module CoffeeMachine\n{\n\n   type port IntegerInputPortType message { in integer }\n   type port CharstringOutputPortType message { out charstring }\n\n   type component CoffeeMachineComponentType\n   {\n      port IntegerInputPortType InputPort;\n      port CharstringOutputPortType OutputPort;\n   }\n\n   var CoffeeMachineComponentType machine\n   machine := CoffeeMachineComponentType.create()\n   machine := CoffeeMachineComponentType.create(\"start\")\n   machine := CoffeeMachineComponentType.create() alive\n   machine := CoffeeMachineComponentType.create(2) alive\n   machine.start(doSomeCoffee(\"late\")) \n   machine.done\n\n}\n\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-constants.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-constants.d/expected.tags",
    "content": "CoffeeConstants\tinput.ttcn\t/^module CoffeeConstants$/;\"\tM\nc_espressoId\tinput.ttcn\t/^const integer c_espressoId := 1$/;\"\tc\nc_espresso\tinput.ttcn\t/^const charstring c_espresso := \"small little one\"$/;\"\tc\nc_latteId\tinput.ttcn\t/^const integer c_latteId := 2$/;\"\tc\nc_latte\tinput.ttcn\t/^const charstring c_latte := \"big one with a lot of milk\"$/;\"\tc\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-constants.d/input.ttcn",
    "content": "module CoffeeConstants\n{\n\nconst integer c_espressoId := 1\nconst charstring c_espresso := \"small little one\"\nconst integer c_latteId := 2\nconst charstring c_latte := \"big one with a lot of milk\"\n\n}\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-enum.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-enum.d/expected.tags",
    "content": "CoffeeTemperature\tinput.ttcn\t/^type enumerated CoffeeTemperature $/;\"\tt\ne_cold\tinput.ttcn\t/^    e_cold, e_warm, e_hot$/;\"\te\ne_warm\tinput.ttcn\t/^    e_cold, e_warm, e_hot$/;\"\te\ne_hot\tinput.ttcn\t/^    e_cold, e_warm, e_hot$/;\"\te\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-enum.d/input.ttcn",
    "content": "\ntype enumerated CoffeeTemperature \n{\n    e_cold, e_warm, e_hot\n}\n\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-function.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-function.d/expected.tags",
    "content": "CoffeeMachine\tinput.ttcn\t/^module CoffeeMachine$/;\"\tM\nstartCoffeePrepration\tinput.ttcn\t/^    function startCoffeePrepration()$/;\"\tf\ndrinkCoffee\tinput.ttcn\t/^   function drinkCoffee(charstring coffeeType)$/;\"\tf\ngetCoffee\tinput.ttcn\t/^   function getCoffee() runs on CoffeeDrinkerComponentType$/;\"\tf\nboilWater\tinput.ttcn\t/^   function boilWater() return Water$/;\"\tf\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-function.d/input.ttcn",
    "content": "module CoffeeMachine\n{\n    function startCoffeePrepration()\n    {\n        //do nothing\n    }\n\n   function drinkCoffee(charstring coffeeType)\n       runs on CoffeeDrinkerComponentType\n   {\n      //drinking coffee\n   }\n\n   function getCoffee() runs on CoffeeDrinkerComponentType\n       return template Coffee\n   {\n       return coffee(\"espresso\")\n   }\n\n   function boilWater() return Water\n   {\n       return valueof(CleanWater{})\n   }\n}\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-group.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-group.d/expected.tags",
    "content": "dataBroadcast\tinput.ttcn\t/^group dataBroadcast$/;\"\tG\nDataReq\tinput.ttcn\t/^  type record DataReq {}$/;\"\tt\nDataRsp\tinput.ttcn\t/^  type record DataRsp {}$/;\"\tt\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-group.d/input.ttcn",
    "content": "group dataBroadcast\n{\n  type record DataReq {}\n  type record DataRsp {}\n}\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-module.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-module.d/expected.tags",
    "content": "Example\tinput.ttcn\t/^module Example$/;\"\tM\nPar_One\tinput.ttcn\t/^        integer Par_One, Par_Two;$/;\"\tP\nPar_Two\tinput.ttcn\t/^        integer Par_One, Par_Two;$/;\"\tP\nPar_Three\tinput.ttcn\t/^        boolean Par_Three := true$/;\"\tP\nExample2\tinput.ttcn\t/^module Example2$/;\"\tM\nmoduleName\tinput.ttcn\t/^    modulepar charstring moduleName := \"CoffeeMachine\"$/;\"\tP\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-module.d/input.ttcn",
    "content": "import from OtherModuleAll all\nimport from OtherModuleNotAll { onlySome }\n\nmodule Example\n{\n    modulepar \n    {\n        integer Par_One, Par_Two;\n        boolean Par_Three := true\n    }\n}\n\nmodule Example2\n{\n    modulepar charstring moduleName := \"CoffeeMachine\"\n}\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-numbers.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-numbers.d/expected.tags",
    "content": "emptyIntegerTemplate\tinput.ttcn\t/^template integer emptyIntegerTemplate := omit$/;\"\td\nmyPositiveInteger\tinput.ttcn\t/^var integer myPositiveInteger := 42$/;\"\tv\nmyNegativeInteger\tinput.ttcn\t/^var integer myNegativeInteger := -5$/;\"\tv\nmyPositiveFloat\tinput.ttcn\t/^var float myPositiveFloat := 3.14$/;\"\tv\nmyNegativeFloat\tinput.ttcn\t/^var float myNegativeFloat := -0.5$/;\"\tv\nmyBigExponentialNotation1\tinput.ttcn\t/^var integer myBigExponentialNotation1 := 6.022E23$/;\"\tv\nmyBigExponentialNotation2\tinput.ttcn\t/^var integer myBigExponentialNotation2 := 6.022E20.35$/;\"\tv\nmyBigExponentialNotation3\tinput.ttcn\t/^var integer myBigExponentialNotation3 := -6.022E23$/;\"\tv\nmyBigExponentialNotation4\tinput.ttcn\t/^var integer myBigExponentialNotation4 := 6.022E-23$/;\"\tv\nmyBigExponentialNotation5\tinput.ttcn\t/^var integer myBigExponentialNotation5 := 6.022E-20.35$/;\"\tv\nmyBigExponentialNotation6\tinput.ttcn\t/^var integer myBigExponentialNotation6 := -6.022E-23$/;\"\tv\nmySmallExponentialNotation\tinput.ttcn\t/^var integer mySmallExponentialNotation := 6.022e23$/;\"\tv\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-numbers.d/input.ttcn",
    "content": "template integer emptyIntegerTemplate := omit\nvar integer myPositiveInteger := 42\nvar integer myNegativeInteger := -5\nvar float myPositiveFloat := 3.14\nvar float myNegativeFloat := -0.5\nvar integer myBigExponentialNotation1 := 6.022E23\nvar integer myBigExponentialNotation2 := 6.022E20.35\nvar integer myBigExponentialNotation3 := -6.022E23\nvar integer myBigExponentialNotation4 := 6.022E-23\nvar integer myBigExponentialNotation5 := 6.022E-20.35\nvar integer myBigExponentialNotation6 := -6.022E-23\nvar integer mySmallExponentialNotation := 6.022e23\n\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-signature.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-signature.d/expected.tags",
    "content": "MySignature\tinput.ttcn\t/^signature MySignature(in integer par1, in integer par2)$/;\"\ts\nmySign\tinput.ttcn\t/^template MySignature mySign$/;\"\td\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-signature.d/input.ttcn",
    "content": "signature MySignature(in integer par1, in integer par2)\ntemplate MySignature mySign\n    := ({ par1 := 1, par2 := 2 }, { par1 := 2, par2 := 1 })\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-strings-with-quotes.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-strings-with-quotes.d/expected.tags",
    "content": "begin\tinput.ttcn\t/^var charstring begin := \"first\"$/;\"\tv\nemptyString\tinput.ttcn\t/^var charstring emptyString := \"\"$/;\"\tv\nsimpleString\tinput.ttcn\t/^var charstring simpleString := \"abcdef\"$/;\"\tv\nsingleQuote\tinput.ttcn\t/^var charstring singleQuote := \"'\"$/;\"\tv\ntwoSingleQuote\tinput.ttcn\t/^var charstring twoSingleQuote := \"''\"$/;\"\tv\nstringWithSingleQuote\tinput.ttcn\t/^var charstring stringWithSingleQuote := \"a'bc\"$/;\"\tv\nstringWithTwoSingleQuote\tinput.ttcn\t/^var charstring stringWithTwoSingleQuote := \"a'b'c\"$/;\"\tv\nescapedDoubleQuotes\tinput.ttcn\t/^var charstring escapedDoubleQuotes := \"\\\\\"\"$/;\"\tv\ntwoEscapedDoubleQuotes\tinput.ttcn\t/^var charstring twoEscapedDoubleQuotes := \"\\\\\"\\\\\"\"$/;\"\tv\nstringWithEscapedDoubleQuotes\tinput.ttcn\t/^var charstring stringWithEscapedDoubleQuotes := \"a\\\\\"bc\"$/;\"\tv\nstringWithTwoEscapedDoubleQuotes\tinput.ttcn\t/^var charstring stringWithTwoEscapedDoubleQuotes := \"a\\\\\"b\\\\\"c\"$/;\"\tv\ndoubleQuotes\tinput.ttcn\t/^var charstring doubleQuotes := \"\"\"\"$/;\"\tv\ntwoDoubleQuotes\tinput.ttcn\t/^var charstring twoDoubleQuotes := \"\"\"\"\"\"$/;\"\tv\nstringWithDoubleQuotes\tinput.ttcn\t/^var charstring stringWithDoubleQuotes := \"a\"\"bc\"$/;\"\tv\nstringWithTwoDoubleQuotes\tinput.ttcn\t/^var charstring stringWithTwoDoubleQuotes := \"a\"\"b\"\"c\"$/;\"\tv\nmixedQuotes1\tinput.ttcn\t/^var charstring mixedQuotes1 := \"\\\\\"\"\"\"$/;\"\tv\nmixedQuotes2\tinput.ttcn\t/^var charstring mixedQuotes2 := \"\"\"\\\\\"\"$/;\"\tv\nstringWithMixedQuotes1\tinput.ttcn\t/^var charstring stringWithMixedQuotes1 := \"a\\\\\"b\"\"c\"$/;\"\tv\nstringWithMixedQuotes2\tinput.ttcn\t/^var charstring stringWithMixedQuotes2 := \"a\"\"b\\\\\"c\"$/;\"\tv\nbackslash\tinput.ttcn\t/^var charstring backslash := \"\\\\\\\\\"$/;\"\tv\nstringWithBackslash\tinput.ttcn\t/^var charstring stringWithBackslash := \"a\\\\\\\\b\"$/;\"\tv\nbackslashAndEscapedDoubleQuotes\tinput.ttcn\t/^var charstring backslashAndEscapedDoubleQuotes := \"\\\\\\\\\\\\\"\"$/;\"\tv\nescapedDoubleQuotesAndBackslash\tinput.ttcn\t/^var charstring escapedDoubleQuotesAndBackslash := \"\\\\\"\\\\\\\\\"$/;\"\tv\nstringWithBackslashAndEscapedDoubleQuotes\tinput.ttcn\t/^var charstring stringWithBackslashAndEscapedDoubleQuotes := \"a\\\\\\\\\\\\\"b\"$/;\"\tv\nstringWithEscapedDoubleQuotesAndBackslash\tinput.ttcn\t/^var charstring stringWithEscapedDoubleQuotesAndBackslash := \"a\\\\\"\\\\\\\\b\"$/;\"\tv\nstringWithBackslashAndDoubleQuotes\tinput.ttcn\t/^var charstring stringWithBackslashAndDoubleQuotes := \"a\\\\\\\\\"\"b\"$/;\"\tv\nstringWithDoubleQuotesAndBackslash\tinput.ttcn\t/^var charstring stringWithDoubleQuotesAndBackslash := \"a\"\"\\\\\\\\b\"$/;\"\tv\nend\tinput.ttcn\t/^var charstring end := \"last\"$/;\"\tv\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-strings-with-quotes.d/input.ttcn",
    "content": "/* standard strings */\nvar charstring begin := \"first\"\nvar charstring emptyString := \"\"\nvar charstring simpleString := \"abcdef\"\n/* single quotes */\nvar charstring singleQuote := \"'\"\nvar charstring twoSingleQuote := \"''\"\nvar charstring stringWithSingleQuote := \"a'bc\"\nvar charstring stringWithTwoSingleQuote := \"a'b'c\"\n/* escaped double quotes with backslash */\nvar charstring escapedDoubleQuotes := \"\\\"\"\nvar charstring twoEscapedDoubleQuotes := \"\\\"\\\"\"\nvar charstring stringWithEscapedDoubleQuotes := \"a\\\"bc\"\nvar charstring stringWithTwoEscapedDoubleQuotes := \"a\\\"b\\\"c\"\n/* two double quotes in string are treated as escaped double quotes */\nvar charstring doubleQuotes := \"\"\"\"\nvar charstring twoDoubleQuotes := \"\"\"\"\"\"\nvar charstring stringWithDoubleQuotes := \"a\"\"bc\"\nvar charstring stringWithTwoDoubleQuotes := \"a\"\"b\"\"c\"\n/* mixed quotes */\nvar charstring mixedQuotes1 := \"\\\"\"\"\"\nvar charstring mixedQuotes2 := \"\"\"\\\"\"\nvar charstring stringWithMixedQuotes1 := \"a\\\"b\"\"c\"\nvar charstring stringWithMixedQuotes2 := \"a\"\"b\\\"c\"\n/* quotes and backslach interactions */\nvar charstring backslash := \"\\\\\"\nvar charstring stringWithBackslash := \"a\\\\b\"\nvar charstring backslashAndEscapedDoubleQuotes := \"\\\\\\\"\"\nvar charstring escapedDoubleQuotesAndBackslash := \"\\\"\\\\\"\nvar charstring stringWithBackslashAndEscapedDoubleQuotes := \"a\\\\\\\"b\"\nvar charstring stringWithEscapedDoubleQuotesAndBackslash := \"a\\\"\\\\b\"\nvar charstring stringWithBackslashAndDoubleQuotes := \"a\\\\\"\"b\"\nvar charstring stringWithDoubleQuotesAndBackslash := \"a\"\"\\\\b\"\n\nvar charstring end := \"last\"\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-strings.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-strings.d/expected.tags",
    "content": "myCharstring\tinput.ttcn\t/^var charstring myCharstring := \"qwerty\"$/;\"\tv\nmyCharstring\tinput.ttcn\t/^var universal charstring myCharstring := \"asdfgh\"$/;\"\tv\nmyCharstring2\tinput.ttcn\t/^var universal charstring myCharstring2 := \"a's'd\"$/;\"\tv\nmyCharstring3\tinput.ttcn\t/^var universal charstring myCharstring3 := \"a'sd\"$/;\"\tv\nmyCharstring5\tinput.ttcn\t/^var universal charstring myCharstring5 := \"\\\\\"asd\\\\\"\"$/;\"\tv\nmyCharstring6\tinput.ttcn\t/^var universal charstring myCharstring6 := \"a\\\\\"s\\\\\"d\"$/;\"\tv\nmyCharstring7\tinput.ttcn\t/^var universal charstring myCharstring7 := \"a\\\\\"s\\\\\"d\"$/;\"\tv\nmyCharstring8\tinput.ttcn\t/^var universal charstring myCharstring8 := \"\"\"asd\"\"\"$/;\"\tv\nmyIntAsCharstring1\tinput.ttcn\t/^var universal charstring myIntAsCharstring1 := \"156\"$/;\"\tv\nmyIntAsCharstring2\tinput.ttcn\t/^var universal charstring myIntAsCharstring2 := \"-156\"$/;\"\tv\nmyFloatAsCharstring1\tinput.ttcn\t/^var universal charstring myFloatAsCharstring1 := \"1.56\"$/;\"\tv\nmyFloatAsCharstring2\tinput.ttcn\t/^var universal charstring myFloatAsCharstring2 := \"-1.56\"$/;\"\tv\nmyBitstring\tinput.ttcn\t/^var bitstring myBitstring := '100100101101'B$/;\"\tv\nmyHexstring\tinput.ttcn\t/^var hexstring myHexstring := '09A8B'H$/;\"\tv\nmyOctetstring\tinput.ttcn\t/^var octetstring myOctetstring := '09A8B8'O$/;\"\tv\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-strings.d/input.ttcn",
    "content": "var charstring myCharstring := \"qwerty\"\nvar universal charstring myCharstring := \"asdfgh\"\nvar universal charstring myCharstring2 := \"a's'd\"\nvar universal charstring myCharstring3 := \"a'sd\"\nvar universal charstring myCharstring5 := \"\\\"asd\\\"\"\nvar universal charstring myCharstring6 := \"a\\\"s\\\"d\"\nvar universal charstring myCharstring7 := \"a\\\"s\\\"d\"\nvar universal charstring myCharstring8 := \"\"\"asd\"\"\"\nvar universal charstring myIntAsCharstring1 := \"156\"\nvar universal charstring myIntAsCharstring2 := \"-156\"\nvar universal charstring myFloatAsCharstring1 := \"1.56\"\nvar universal charstring myFloatAsCharstring2 := \"-1.56\"\nvar bitstring myBitstring := '100100101101'B\nvar hexstring myHexstring := '09A8B'H\nvar octetstring myOctetstring := '09A8B8'O\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-function.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-function.d/expected.tags",
    "content": "templateFunctionThatReturnTemplateType\tinput.ttcn\t/^function templateFunctionThatReturnTemplateType<type PARAM>(PARAM parameter)$/;\"\tf\ntemplateFunction\tinput.ttcn\t/^function templateFunction<type PARAM>(PARAM parameter)$/;\"\tf\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-function.d/input.ttcn",
    "content": "function templateFunctionThatReturnTemplateType<type PARAM>(PARAM parameter)\n    return list<PARAM>\n{\n}\n\nfunction templateFunction<type PARAM>(PARAM parameter)\n{\n}\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-restriction.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-restriction.d/expected.tags",
    "content": "CoffeeTemplates\tinput.ttcn\t/^module CoffeeTemplates$/;\"\tM\nAnyCoffee\tinput.ttcn\t/^template (present) Coffee AnyCoffee$/;\"\td\nSomeCoffee\tinput.ttcn\t/^template (value) Coffee SomeCoffee(integer id, charstring description := \"\")$/;\"\td\nEspresso\tinput.ttcn\t/^template (omit) Coffee Espresso()$/;\"\td\nLatte\tinput.ttcn\t/^template (TYPO IN RESTRICTION) Coffee Latte()$/;\"\td\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-restriction.d/input.ttcn",
    "content": "import from CoffeeTypes all\nimport from CoffeeConstants all\n\nmodule CoffeeTemplates\n{\n\ntemplate (present) Coffee AnyCoffee\n{\n    id := ?,\n    description := ?\n}\n\ntemplate (value) Coffee SomeCoffee(integer id, charstring description := \"\")\n{\n    id := id,\n   description := description\n}\n\ntemplate (omit) Coffee Espresso()\n{\n    id := c_espressoId,\n    description := c_espresso\n}\n\ntemplate (TYPO IN RESTRICTION) Coffee Latte()\n{\n    id := c_latteId,\n    description := c_latte\n}\n\n}\n\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-template.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-template.d/expected.tags",
    "content": "listOfType\tinput.ttcn\t/^template list<Type> listOfType := { }$/;\"\td\nlistOfTemplateType\tinput.ttcn\t/^template list<TemplateType<Type> > listOfTemplateType := { }$/;\"\td\nmatpWithKeyAndTemplateValue\tinput.ttcn\t/^template Map<Key, TemplateVal<Val> > matpWithKeyAndTemplateValue := { }$/;\"\td\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-template.d/input.ttcn",
    "content": "template list<Type> listOfType := { }\ntemplate list<TemplateType<Type> > listOfTemplateType := { }\ntemplate Map<Key, TemplateVal<Val> > matpWithKeyAndTemplateValue := { }\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-type.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-type.d/expected.tags",
    "content": "list\tinput.ttcn\t/^type record of T list<type T>$/;\"\tt\nRecordOfList\tinput.ttcn\t/^type record of list<T> RecordOfList<type T>$/;\"\tt\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-type.d/input.ttcn",
    "content": "type record of T list<type T>\ntype record of list<T> RecordOfList<type T>\n\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-variables-and-constants.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-variables-and-constants.d/expected.tags",
    "content": "variable\tinput.ttcn\t/^var TemplateType<Type> variable := { }$/;\"\tv\nconstant\tinput.ttcn\t/^const TemplateType<Type> constant := { }$/;\"\tc\ntemplateVariable\tinput.ttcn\t/^var template TemplateType<Type> templateVariable := { }$/;\"\tv\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template-variables-and-constants.d/input.ttcn",
    "content": "var TemplateType<Type> variable := { }\nconst TemplateType<Type> constant := { }\nvar template TemplateType<Type> templateVariable := { }\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template.d/expected.tags",
    "content": "CoffeeTemplates\tinput.ttcn\t/^module CoffeeTemplates$/;\"\tM\nAnyCoffee\tinput.ttcn\t/^template Coffee AnyCoffee$/;\"\td\nSomeCoffee\tinput.ttcn\t/^template Coffee SomeCoffee(integer id, charstring description := \"\")$/;\"\td\nEspresso\tinput.ttcn\t/^template Coffee Espresso()$/;\"\td\nLatte\tinput.ttcn\t/^template Coffee Latte()$/;\"\td\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-template.d/input.ttcn",
    "content": "import from CoffeeTypes all\nimport from CoffeeConstants all\n\nmodule CoffeeTemplates\n{\n\ntemplate Coffee AnyCoffee\n{\n    id := ?,\n    description := ?\n}\n\ntemplate Coffee SomeCoffee(integer id, charstring description := \"\")\n{\n    id := id,\n   description := description\n}\n\ntemplate Coffee Espresso()\n{\n    id := c_espressoId,\n    description := c_espresso\n}\n\ntemplate Coffee Latte()\n{\n    id := c_latteId,\n    description := c_latte\n}\n\n}\n\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-testcase.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-testcase.d/expected.tags",
    "content": "CoffeeSuite\tinput.ttcn\t/^module CoffeeSuite$/;\"\tM\nOneCoffeesPlease\tinput.ttcn\t/^    testcase OneCoffeesPlease () runs on EmptyComponentType$/;\"\tC\nTwoCoffeesPlease\tinput.ttcn\t/^    testcase TwoCoffeesPlease ()$/;\"\tC\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-testcase.d/input.ttcn",
    "content": "import from CoffeeMachine all;\n\nmodule CoffeeSuite\n{\n    testcase OneCoffeesPlease () runs on EmptyComponentType\n    {\n    }\n\n    testcase TwoCoffeesPlease ()\n        runs on EmptyComponentType\n    {\n    }\n}\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-timer.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-timer.d/expected.tags",
    "content": "guardTimer\tinput.ttcn\t/^timer guardTimer;$/;\"\tT\nmaxDuration\tinput.ttcn\t/^var float maxDuration;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-timer.d/input.ttcn",
    "content": "timer guardTimer;\nvar float maxDuration;\n\nguardTimer.start( maxDuration )\n\nalt\n{\n    [] myPort.receive( anyResp )\n    {\n    }\n    [] guardTimer.timeout \n    {\n        setverdict( fail )\n    }\n}\n\nguardTimer.stop;\n\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-types.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-types.d/expected.tags",
    "content": "CoffeeTypes\tinput.ttcn\t/^module CoffeeTypes$/;\"\tM\nCoffee\tinput.ttcn\t/^type record Coffee$/;\"\tt\nid\tinput.ttcn\t/^    integer id,$/;\"\tm\ndescription\tinput.ttcn\t/^    charstring description$/;\"\tm\nCoffeeList\tinput.ttcn\t/^type record of Coffee CoffeeList$/;\"\tt\nRangedCoffeeList\tinput.ttcn\t/^type record length (1..2) of Coffee RangedCoffeeList$/;\"\tt\nTee\tinput.ttcn\t/^type record Tee$/;\"\tt\nnestedIntegersRecord\tinput.ttcn\t/^    record of integer nestedIntegersRecord,$/;\"\tm\nnestedRangedIntegersRecord\tinput.ttcn\t/^    record length (0..5) of integer nestedRangedIntegersRecord,$/;\"\tm\nnestedIntegersSet\tinput.ttcn\t/^    set of integer nestedIntegersSet,$/;\"\tm\nnestedRangerdIntegersSet\tinput.ttcn\t/^    set length (2..4) of integer nestedRangerdIntegersSet,$/;\"\tm\ne_type1\tinput.ttcn\t/^    enumerated {e_type1, e_type2} nestedEnum,$/;\"\te\ne_type2\tinput.ttcn\t/^    enumerated {e_type1, e_type2} nestedEnum,$/;\"\te\nnestedEnum\tinput.ttcn\t/^    enumerated {e_type1, e_type2} nestedEnum,$/;\"\tm\nt1\tinput.ttcn\t/^    union {Type1 t1, Type2 t2} nestedUnion$/;\"\tm\nt2\tinput.ttcn\t/^    union {Type1 t1, Type2 t2} nestedUnion$/;\"\tm\nnestedUnion\tinput.ttcn\t/^    union {Type1 t1, Type2 t2} nestedUnion$/;\"\tm\nTeeSet\tinput.ttcn\t/^type set of Tee TeeSet$/;\"\tt\nRangedTeeSet\tinput.ttcn\t/^type set length (0 .. 2) of Tee RangedTeeSet$/;\"\tt\nDrink\tinput.ttcn\t/^type union Drink$/;\"\tt\ntee\tinput.ttcn\t/^    Tee tee,$/;\"\tm\ncoffee\tinput.ttcn\t/^    Coffee coffee,$/;\"\tm\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-types.d/input.ttcn",
    "content": "module CoffeeTypes\n{\n\ntype record Coffee\n{\n    integer id,\n    charstring description\n}\n\ntype record of Coffee CoffeeList\ntype record length (1..2) of Coffee RangedCoffeeList\n\ntype record Tee\n{\n    record of integer nestedIntegersRecord,\n    record length (0..5) of integer nestedRangedIntegersRecord,\n    /* a comment */\n    set of integer nestedIntegersSet,\n    // a comment\n    set length (2..4) of integer nestedRangerdIntegersSet,\n    enumerated {e_type1, e_type2} nestedEnum,\n    union {Type1 t1, Type2 t2} nestedUnion\n}\n\ntype set of Tee TeeSet\ntype set length (0 .. 2) of Tee RangedTeeSet\n\ntype union Drink\n{\n    Tee tee,\n    Coffee coffee,\n}\n\n}\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-variables.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-variables.d/expected.tags",
    "content": "cappuccino\tinput.ttcn\t/^var Coffee cappuccino := { id:= 5, description := \"with creme\" }$/;\"\tv\nlatte\tinput.ttcn\t/^var template Coffee latte := Latte()$/;\"\tv\nsomeCofee\tinput.ttcn\t/^var template Coffee someCofee := SomeCoffee(8,?)$/;\"\tv\nespresso\tinput.ttcn\t/^var template Coffee espresso := Espresso()$/;\"\tv\nlatte\tinput.ttcn\t/^var template Coffee latte := Latte$/;\"\tv\nespresso\tinput.ttcn\t/^var template Coffee espresso := Black(getBlackId(),*)$/;\"\tv\nlatteId\tinput.ttcn\t/^var Coffee.id latteId := 4$/;\"\tv\ncomplecCoffee1\tinput.ttcn\t/^var Coffee complecCoffee1 := { id:= {5}, description := omit }$/;\"\tv\ncomplecCoffee2\tinput.ttcn\t/^var Coffee complecCoffee2 := { { 5 }, omit }$/;\"\tv\ncomplecCoffee3\tinput.ttcn\t/^var Coffee complecCoffee3 := { { 5 }, {\"complex\"}}$/;\"\tv\ncomplecCoffee4\tinput.ttcn\t/^var Coffee complecCoffee4 := { { 5 }, getComplex() }$/;\"\tv\ncomplecCoffee5\tinput.ttcn\t/^var Coffee complecCoffee5 := { getComplex() }$/;\"\tv\ncomplecCoffee6\tinput.ttcn\t/^var Coffee complecCoffee6 := { getComplex(), {\"complex\"} }$/;\"\tv\n"
  },
  {
    "path": "Units/parser-ttcn.r/ttcn-variables.d/input.ttcn",
    "content": "import from CoffeTypes all\nimport from CoffeConstants all\nimport from CoffeTemplates all\nimport from CoffeFunctions { boilWatter }\n\nvar Coffee cappuccino := { id:= 5, description := \"with creme\" }\nvar template Coffee latte := Latte()\nvar template Coffee someCofee := SomeCoffee(8,?)\nvar template Coffee espresso := Espresso()\nvar template Coffee latte := Latte\nvar template Coffee espresso := Black(getBlackId(),*)\n//type reference\nvar Coffee.id latteId := 4\nvar Coffee complecCoffee1 := { id:= {5}, description := omit }\nvar Coffee complecCoffee2 := { { 5 }, omit }\nvar Coffee complecCoffee3 := { { 5 }, {\"complex\"}}\nvar Coffee complecCoffee4 := { { 5 }, getComplex() }\nvar Coffee complecCoffee5 := { getComplex() }\nvar Coffee complecCoffee6 := { getComplex(), {\"complex\"} }\n"
  },
  {
    "path": "Units/parser-typescript.r/README",
    "content": "Not whole input files but only some parts of them are taken from official docs[1]\n[1] https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.pdf\n"
  },
  {
    "path": "Units/parser-typescript.r/github-issue-4313.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-typescript.r/github-issue-4313.d/expected.tags",
    "content": "saveTemplate\tinput.ts\t/^function saveTemplate()$/;\"\tf\nfoobar\tinput.ts\t/^function foobar()$/;\"\tf\n"
  },
  {
    "path": "Units/parser-typescript.r/github-issue-4313.d/input.ts",
    "content": "function saveTemplate()\n{\n\t{ if (x < y) }\n\n\tif (x > y)\n}\n\nfunction foobar()\n{\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/skip-bang.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-typescript.r/skip-bang.d/expected.tags",
    "content": "SomeClass\tinput.ts\t/^class SomeClass {$/;\"\tc\nbrokenMethod\tinput.ts\t/^  brokenMethod() {$/;\"\tm\tclass:SomeClass\nx\tinput.ts\t/^    const x = {a: !true ? 1 : 2};$/;\"\tC\tmethod:SomeClass.brokenMethod\nmissingMethod\tinput.ts\t/^  missingMethod() {}$/;\"\tm\tclass:SomeClass\nC\tinput-0.ts\t/^class C {$/;\"\tc\nfoo\tinput-0.ts\t/^  foo!: string;$/;\"\tp\tclass:C\nbar\tinput-0.ts\t/^  public bar!: number;$/;\"\tp\tclass:C\nbaz\tinput-0.ts\t/^  readonly baz!: boolean;$/;\"\tp\tclass:C\nconstructor\tinput-0.ts\t/^  constructor() {}$/;\"\tm\tclass:C\nA\tinput-1.ts\t/^class A {$/;\"\tc\nf\tinput-1.ts\t/^  f() {$/;\"\tm\tclass:A\nd\tinput-1.ts\t/^    const d = {$/;\"\tC\tmethod:A.f\na\tinput-1.ts\t/^    const a = (b: unknown) => {$/;\"\tC\tmethod:A.f\n"
  },
  {
    "path": "Units/parser-typescript.r/skip-bang.d/input-0.ts",
    "content": "class C {\n  foo!: string;\n  public bar!: number;\n  readonly baz!: boolean;\n\n  constructor() {}\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/skip-bang.d/input-1.ts",
    "content": "/* Derived from https://github.com/universal-ctags/ctags/issues/4000#issuecomment-2116428681\n * submitted by @char01 */\nclass A {\n  f() {\n    let c = true;\n\n    const d = {\n      e() {},\n    };\n\n    const a = (b: unknown) => {\n      if (!c) {}\n    };\n\n    d.e();\n  }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/skip-bang.d/input.ts",
    "content": "/* Taken from #4384 submitted by @naktinis */\nclass SomeClass {\n  brokenMethod() {\n    const x = {a: !true ? 1 : 2};\n  }\n\n  missingMethod() {}\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/skip-bang.d/validator",
    "content": "tsc\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-fq-white.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n--extras=+q\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-fq-white.d/expected.tags",
    "content": "CPoint\tinput.ts\t/^class CPoint {$/;\"\tc\nx\tinput.ts\t/^  x: number$/;\"\tp\tclass:CPoint\nCPoint.x\tinput.ts\t/^  x: number$/;\"\tp\tclass:CPoint\ny\tinput.ts\t/^  y: number$/;\"\tp\tclass:CPoint\nCPoint.y\tinput.ts\t/^  y: number$/;\"\tp\tclass:CPoint\nconstructor\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tm\tclass:CPoint\nCPoint.constructor\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tm\tclass:CPoint\nx\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\nCPoint.constructor.x\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\ny\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\nCPoint.constructor.y\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\nBankAccount\tinput.ts\t/^class BankAccount {$/;\"\tc\nbalance\tinput.ts\t/^  balance = 0$/;\"\tp\tclass:BankAccount\nBankAccount.balance\tinput.ts\t/^  balance = 0$/;\"\tp\tclass:BankAccount\ndeposit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tm\tclass:BankAccount\nBankAccount.deposit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tm\tclass:BankAccount\ncredit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tz\tmethod:BankAccount.deposit\nBankAccount.deposit.credit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tz\tmethod:BankAccount.deposit\nCheckingAccount\tinput.ts\t/^class CheckingAccount extends BankAccount {$/;\"\tc\nconstructor\tinput.ts\t/^  constructor(balance: number) {$/;\"\tm\tclass:CheckingAccount\nCheckingAccount.constructor\tinput.ts\t/^  constructor(balance: number) {$/;\"\tm\tclass:CheckingAccount\nbalance\tinput.ts\t/^  constructor(balance: number) {$/;\"\tz\tmethod:CheckingAccount.constructor\nCheckingAccount.constructor.balance\tinput.ts\t/^  constructor(balance: number) {$/;\"\tz\tmethod:CheckingAccount.constructor\nwriteCheck\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tm\tclass:CheckingAccount\nCheckingAccount.writeCheck\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tm\tclass:CheckingAccount\ndebit\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tz\tmethod:CheckingAccount.writeCheck\nCheckingAccount.writeCheck.debit\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tz\tmethod:CheckingAccount.writeCheck\nList\tinput.ts\t/^class List<T extends NamedItem> {$/;\"\tc\nnext\tinput.ts\t/^  next: List<T> = null$/;\"\tp\tclass:List\nList.next\tinput.ts\t/^  next: List<T> = null$/;\"\tp\tclass:List\nconstructor\tinput.ts\t/^  constructor(public item: T) {$/;\"\tm\tclass:List\nList.constructor\tinput.ts\t/^  constructor(public item: T) {$/;\"\tm\tclass:List\nitem\tinput.ts\t/^  constructor(public item: T) {$/;\"\tp\tclass:List\nList.item\tinput.ts\t/^  constructor(public item: T) {$/;\"\tp\tclass:List\ninsertAfter\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tm\tclass:List\nList.insertAfter\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tm\tclass:List\nitem\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tz\tmethod:List.insertAfter\nList.insertAfter.item\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tz\tmethod:List.insertAfter\ntemp\tinput.ts\t/^    var temp = this.next$/;\"\tl\tmethod:List.insertAfter\nList.insertAfter.temp\tinput.ts\t/^    var temp = this.next$/;\"\tl\tmethod:List.insertAfter\nlog\tinput.ts\t/^  log() {$/;\"\tm\tclass:List\nList.log\tinput.ts\t/^  log() {$/;\"\tm\tclass:List\nC\tinput.ts\t/^class C {$/;\"\tc\nx\tinput.ts\t/^  x: number$/;\"\tp\tclass:C\nC.x\tinput.ts\t/^  x: number$/;\"\tp\tclass:C\nx\tinput.ts\t/^  static x: string$/;\"\tp\tclass:C\nC.x\tinput.ts\t/^  static x: string$/;\"\tp\tclass:C\nMessenger\tinput.ts\t/^class Messenger {$/;\"\tc\nmessage\tinput.ts\t/^  message = \"Hello World\"$/;\"\tp\tclass:Messenger\nMessenger.message\tinput.ts\t/^  message = \"Hello World\"$/;\"\tp\tclass:Messenger\nstart\tinput.ts\t/^  start() {$/;\"\tm\tclass:Messenger\nMessenger.start\tinput.ts\t/^  start() {$/;\"\tm\tclass:Messenger\n_this\tinput.ts\t/^    var _this = this$/;\"\tl\tmethod:Messenger.start\nMessenger.start._this\tinput.ts\t/^    var _this = this$/;\"\tl\tmethod:Messenger.start\nD\tinput.ts\t/^class D {$/;\"\tc\ndata\tinput.ts\t/^  data: string | string[]$/;\"\tp\tclass:D\nD.data\tinput.ts\t/^  data: string | string[]$/;\"\tp\tclass:D\ngetData\tinput.ts\t/^  getData() {$/;\"\tm\tclass:D\nD.getData\tinput.ts\t/^  getData() {$/;\"\tm\tclass:D\ndata\tinput.ts\t/^    var data = this.data$/;\"\tl\tmethod:D.getData\nD.getData.data\tinput.ts\t/^    var data = this.data$/;\"\tl\tmethod:D.getData\nPoint\tinput.ts\t/^class Point {$/;\"\tc\nfakePointBuilder\tinput.ts\t/^  protected fakePointBuilder: () => { x: number, y: number }$/;\"\tp\tclass:Point\nPoint.fakePointBuilder\tinput.ts\t/^  protected fakePointBuilder: () => { x: number, y: number }$/;\"\tp\tclass:Point\nconstructor\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tm\tclass:Point\nPoint.constructor\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tm\tclass:Point\nx\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\nPoint.x\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\ny\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\nPoint.y\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\nlength\tinput.ts\t/^  public length() { return Math.sqrt(this.x * this.x + this.y * this.y) }$/;\"\tm\tclass:Point\nPoint.length\tinput.ts\t/^  public length() { return Math.sqrt(this.x * this.x + this.y * this.y) }$/;\"\tm\tclass:Point\norigin\tinput.ts\t/^  static origin = new Point(0, 0)$/;\"\tp\tclass:Point\nPoint.origin\tinput.ts\t/^  static origin = new Point(0, 0)$/;\"\tp\tclass:Point\nA\tinput.ts\t/^class A {$/;\"\tc\nx\tinput.ts\t/^  private x: number$/;\"\tp\tclass:A\nA.x\tinput.ts\t/^  private x: number$/;\"\tp\tclass:A\ny\tinput.ts\t/^  protected y: number$/;\"\tp\tclass:A\nA.y\tinput.ts\t/^  protected y: number$/;\"\tp\tclass:A\nfun\tinput.ts\t/^  public fun: (a: 22 | 30, b: CPoint) => number | string$/;\"\tp\tclass:A\nA.fun\tinput.ts\t/^  public fun: (a: 22 | 30, b: CPoint) => number | string$/;\"\tp\tclass:A\nf\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tm\tclass:A\nA.f\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tm\tclass:A\na\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\nA.f.a\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\nb\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\nA.f.b\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\ngetXAsT\tinput.ts\t/^  getXAsT<T = any>(): T {$/;\"\tm\tclass:A\nA.getXAsT\tinput.ts\t/^  getXAsT<T = any>(): T {$/;\"\tm\tclass:A\nregister\tinput.ts\t/^  register(...args) {$/;\"\tm\tclass:A\nA.register\tinput.ts\t/^  register(...args) {$/;\"\tm\tclass:A\nargs\tinput.ts\t/^  register(...args) {$/;\"\tz\tmethod:A.register\nA.register.args\tinput.ts\t/^  register(...args) {$/;\"\tz\tmethod:A.register\nlongArgsFun\tinput.ts\t/^  longArgsFun(options: {$/;\"\tm\tclass:A\nA.longArgsFun\tinput.ts\t/^  longArgsFun(options: {$/;\"\tm\tclass:A\noptions\tinput.ts\t/^  longArgsFun(options: {$/;\"\tz\tmethod:A.longArgsFun\nA.longArgsFun.options\tinput.ts\t/^  longArgsFun(options: {$/;\"\tz\tmethod:A.longArgsFun\nclosure\tinput.ts\t/^  closure($/;\"\tm\tclass:A\nA.closure\tinput.ts\t/^  closure($/;\"\tm\tclass:A\nx\tinput.ts\t/^    x: number,$/;\"\tz\tmethod:A.closure\nA.closure.x\tinput.ts\t/^    x: number,$/;\"\tz\tmethod:A.closure\nnormalizedPath\tinput.ts\t/^    const normalizedPath = path === '\\/*' ? '' : path$/;\"\tC\tmethod:A.closure\nA.closure.normalizedPath\tinput.ts\t/^    const normalizedPath = path === '\\/*' ? '' : path$/;\"\tC\tmethod:A.closure\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-fq-white.d/input.ts",
    "content": "class CPoint {\n  x: number\n  y: number\n  constructor(x: number, y: number) {\n    this.x = x\n    this.y = y\n  }\n}\n\nclass BankAccount {\n  balance = 0\n  deposit(credit: number) {\n    this.balance += credit\n    return this.balance\n  }\n}\n\nclass CheckingAccount extends BankAccount {\n  constructor(balance: number) {\n    super(balance)\n  }\n  writeCheck(debit: number) {\n    this.balance -= debit\n  }\n}\n\nclass List<T extends NamedItem> {\n  next: List<T> = null\n  constructor(public item: T) {\n  }\n  insertAfter(item: T) {\n    var temp = this.next\n    this.next = new List(item)\n    this.next.next = temp\n  }\n  log() {\n    console.log(this.item.name)\n  }\n  // ...\n}\n\nclass C {\n  x: number\n  static x: string\n}\n\nclass Messenger {\n  message = \"Hello World\"\n  start() {\n    var _this = this\n    setTimeout(function() { alert(_this.message) }, 3000)\n  }\n}\n\nclass D {\n  data: string | string[]\n  getData() {\n    var data = this.data\n    return typeof data === \"string\" ? data : data.join(\" \")\n  }\n}\n\nclass Point {\n  protected fakePointBuilder: () => { x: number, y: number }\n  constructor(public x: number, public y: number) { }\n  public length() { return Math.sqrt(this.x * this.x + this.y * this.y) }\n  static origin = new Point(0, 0)\n}\n\nclass A {\n  private x: number\n  protected y: number\n  public fun: (a: 22 | 30, b: CPoint) => number | string\n\n  static f(a: A, b: B) {\n    a.x = 1 // Ok\n    b.x = 1 // Ok\n    a.y = 1 // Ok\n    b.y = 1 // Ok\n  }\n\n  getXAsT<T = any>(): T {\n    return this.x as T\n  }\n\n  register(...args) {\n    return this.f(...args)\n  }\n\n  longArgsFun(options: {\n    root: string\n    prefix?: string\n    setHeaders?: Function\n    send?: any\n  }) {\n    return this.f(options)\n  }\n\n  closure(\n    x: number,\n  ): (path: string, callback: Function) => any {\n    const normalizedPath = path === '/*' ? '' : path\n  }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-fq.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n--extras=+q\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-fq.d/expected.tags",
    "content": "CPoint\tinput.ts\t/^class CPoint {$/;\"\tc\nx\tinput.ts\t/^  x: number;$/;\"\tp\tclass:CPoint\nCPoint.x\tinput.ts\t/^  x: number;$/;\"\tp\tclass:CPoint\ny\tinput.ts\t/^  y: number;$/;\"\tp\tclass:CPoint\nCPoint.y\tinput.ts\t/^  y: number;$/;\"\tp\tclass:CPoint\nconstructor\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tm\tclass:CPoint\nCPoint.constructor\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tm\tclass:CPoint\nx\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\nCPoint.constructor.x\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\ny\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\nCPoint.constructor.y\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\nBankAccount\tinput.ts\t/^class BankAccount {$/;\"\tc\nbalance\tinput.ts\t/^  balance = 0;$/;\"\tp\tclass:BankAccount\nBankAccount.balance\tinput.ts\t/^  balance = 0;$/;\"\tp\tclass:BankAccount\ndeposit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tm\tclass:BankAccount\nBankAccount.deposit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tm\tclass:BankAccount\ncredit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tz\tmethod:BankAccount.deposit\nBankAccount.deposit.credit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tz\tmethod:BankAccount.deposit\nCheckingAccount\tinput.ts\t/^class CheckingAccount extends BankAccount {$/;\"\tc\nconstructor\tinput.ts\t/^  constructor(balance: number) {$/;\"\tm\tclass:CheckingAccount\nCheckingAccount.constructor\tinput.ts\t/^  constructor(balance: number) {$/;\"\tm\tclass:CheckingAccount\nbalance\tinput.ts\t/^  constructor(balance: number) {$/;\"\tz\tmethod:CheckingAccount.constructor\nCheckingAccount.constructor.balance\tinput.ts\t/^  constructor(balance: number) {$/;\"\tz\tmethod:CheckingAccount.constructor\nwriteCheck\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tm\tclass:CheckingAccount\nCheckingAccount.writeCheck\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tm\tclass:CheckingAccount\ndebit\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tz\tmethod:CheckingAccount.writeCheck\nCheckingAccount.writeCheck.debit\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tz\tmethod:CheckingAccount.writeCheck\nList\tinput.ts\t/^class List<T extends NamedItem> {$/;\"\tc\nnext\tinput.ts\t/^  next: List<T> = null;$/;\"\tp\tclass:List\nList.next\tinput.ts\t/^  next: List<T> = null;$/;\"\tp\tclass:List\nconstructor\tinput.ts\t/^  constructor(public item: T) {$/;\"\tm\tclass:List\nList.constructor\tinput.ts\t/^  constructor(public item: T) {$/;\"\tm\tclass:List\nitem\tinput.ts\t/^  constructor(public item: T) {$/;\"\tp\tclass:List\nList.item\tinput.ts\t/^  constructor(public item: T) {$/;\"\tp\tclass:List\ninsertAfter\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tm\tclass:List\nList.insertAfter\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tm\tclass:List\nitem\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tz\tmethod:List.insertAfter\nList.insertAfter.item\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tz\tmethod:List.insertAfter\ntemp\tinput.ts\t/^    var temp = this.next;$/;\"\tl\tmethod:List.insertAfter\nList.insertAfter.temp\tinput.ts\t/^    var temp = this.next;$/;\"\tl\tmethod:List.insertAfter\nlog\tinput.ts\t/^  log() {$/;\"\tm\tclass:List\nList.log\tinput.ts\t/^  log() {$/;\"\tm\tclass:List\nC\tinput.ts\t/^class C {$/;\"\tc\nx\tinput.ts\t/^  x: number;$/;\"\tp\tclass:C\nC.x\tinput.ts\t/^  x: number;$/;\"\tp\tclass:C\nx\tinput.ts\t/^  static x: string;$/;\"\tp\tclass:C\nC.x\tinput.ts\t/^  static x: string;$/;\"\tp\tclass:C\nMessenger\tinput.ts\t/^class Messenger {$/;\"\tc\nmessage\tinput.ts\t/^  message = \"Hello World\";$/;\"\tp\tclass:Messenger\nMessenger.message\tinput.ts\t/^  message = \"Hello World\";$/;\"\tp\tclass:Messenger\nstart\tinput.ts\t/^  start() {$/;\"\tm\tclass:Messenger\nMessenger.start\tinput.ts\t/^  start() {$/;\"\tm\tclass:Messenger\n_this\tinput.ts\t/^    var _this = this;$/;\"\tl\tmethod:Messenger.start\nMessenger.start._this\tinput.ts\t/^    var _this = this;$/;\"\tl\tmethod:Messenger.start\nD\tinput.ts\t/^class D {$/;\"\tc\ndata\tinput.ts\t/^  data: string | string[];$/;\"\tp\tclass:D\nD.data\tinput.ts\t/^  data: string | string[];$/;\"\tp\tclass:D\ngetData\tinput.ts\t/^  getData() {$/;\"\tm\tclass:D\nD.getData\tinput.ts\t/^  getData() {$/;\"\tm\tclass:D\ndata\tinput.ts\t/^    var data = this.data;$/;\"\tl\tmethod:D.getData\nD.getData.data\tinput.ts\t/^    var data = this.data;$/;\"\tl\tmethod:D.getData\nPoint\tinput.ts\t/^class Point {$/;\"\tc\nfakePointBuilder\tinput.ts\t/^  protected fakePointBuilder: () => { x: number, y: number };$/;\"\tp\tclass:Point\nPoint.fakePointBuilder\tinput.ts\t/^  protected fakePointBuilder: () => { x: number, y: number };$/;\"\tp\tclass:Point\nconstructor\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tm\tclass:Point\nPoint.constructor\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tm\tclass:Point\nx\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\nPoint.x\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\ny\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\nPoint.y\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\nlength\tinput.ts\t/^  public length() { return Math.sqrt(this.x * this.x + this.y * this.y); }$/;\"\tm\tclass:Point\nPoint.length\tinput.ts\t/^  public length() { return Math.sqrt(this.x * this.x + this.y * this.y); }$/;\"\tm\tclass:Point\norigin\tinput.ts\t/^  static origin = new Point(0, 0);$/;\"\tp\tclass:Point\nPoint.origin\tinput.ts\t/^  static origin = new Point(0, 0);$/;\"\tp\tclass:Point\nA\tinput.ts\t/^class A {$/;\"\tc\nx\tinput.ts\t/^  private x: number;$/;\"\tp\tclass:A\nA.x\tinput.ts\t/^  private x: number;$/;\"\tp\tclass:A\ny\tinput.ts\t/^  protected y: number;$/;\"\tp\tclass:A\nA.y\tinput.ts\t/^  protected y: number;$/;\"\tp\tclass:A\nfun\tinput.ts\t/^  public fun: (a: 22 | 30, b: CPoint) => number | string;$/;\"\tp\tclass:A\nA.fun\tinput.ts\t/^  public fun: (a: 22 | 30, b: CPoint) => number | string;$/;\"\tp\tclass:A\nf\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tm\tclass:A\nA.f\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tm\tclass:A\na\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\nA.f.a\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\nb\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\nA.f.b\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\ngetXAsT\tinput.ts\t/^  getXAsT<T = any>(): T {$/;\"\tm\tclass:A\nA.getXAsT\tinput.ts\t/^  getXAsT<T = any>(): T {$/;\"\tm\tclass:A\nregister\tinput.ts\t/^  register(...args) {$/;\"\tm\tclass:A\nA.register\tinput.ts\t/^  register(...args) {$/;\"\tm\tclass:A\nargs\tinput.ts\t/^  register(...args) {$/;\"\tz\tmethod:A.register\nA.register.args\tinput.ts\t/^  register(...args) {$/;\"\tz\tmethod:A.register\nlongArgsFun\tinput.ts\t/^  longArgsFun(options: {$/;\"\tm\tclass:A\nA.longArgsFun\tinput.ts\t/^  longArgsFun(options: {$/;\"\tm\tclass:A\noptions\tinput.ts\t/^  longArgsFun(options: {$/;\"\tz\tmethod:A.longArgsFun\nA.longArgsFun.options\tinput.ts\t/^  longArgsFun(options: {$/;\"\tz\tmethod:A.longArgsFun\nclosure\tinput.ts\t/^  closure($/;\"\tm\tclass:A\nA.closure\tinput.ts\t/^  closure($/;\"\tm\tclass:A\nx\tinput.ts\t/^    x: number,$/;\"\tz\tmethod:A.closure\nA.closure.x\tinput.ts\t/^    x: number,$/;\"\tz\tmethod:A.closure\nnormalizedPath\tinput.ts\t/^    const normalizedPath = path === '\\/*' ? '' : path;$/;\"\tC\tmethod:A.closure\nA.closure.normalizedPath\tinput.ts\t/^    const normalizedPath = path === '\\/*' ? '' : path;$/;\"\tC\tmethod:A.closure\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-fq.d/input.ts",
    "content": "class CPoint {\n  x: number;\n  y: number;\n  constructor(x: number, y: number) {\n    this.x = x;\n    this.y = y;\n  }\n}\n\nclass BankAccount {\n  balance = 0;\n  deposit(credit: number) {\n    this.balance += credit;\n    return this.balance;\n  }\n}\n\nclass CheckingAccount extends BankAccount {\n  constructor(balance: number) {\n    super(balance);\n  }\n  writeCheck(debit: number) {\n    this.balance -= debit;\n  }\n}\n\nclass List<T extends NamedItem> {\n  next: List<T> = null;\n  constructor(public item: T) {\n  }\n  insertAfter(item: T) {\n    var temp = this.next;\n    this.next = new List(item);\n    this.next.next = temp;\n  }\n  log() {\n    console.log(this.item.name);\n  }\n  // ...\n}\n\nclass C {\n  x: number;\n  static x: string;\n}\n\nclass Messenger {\n  message = \"Hello World\";\n  start() {\n    var _this = this;\n    setTimeout(function() { alert(_this.message); }, 3000);\n  }\n};\n\nclass D {\n  data: string | string[];\n  getData() {\n    var data = this.data;\n    return typeof data === \"string\" ? data : data.join(\" \");\n  }\n}\n\nclass Point {\n  protected fakePointBuilder: () => { x: number, y: number };\n  constructor(public x: number, public y: number) { }\n  public length() { return Math.sqrt(this.x * this.x + this.y * this.y); }\n  static origin = new Point(0, 0);\n}\n\nclass A {\n  private x: number;\n  protected y: number;\n  public fun: (a: 22 | 30, b: CPoint) => number | string;\n\n  static f(a: A, b: B) {\n    a.x = 1; // Ok\n    b.x = 1; // Ok\n    a.y = 1; // Ok\n    b.y = 1; // Ok\n  }\n\n  getXAsT<T = any>(): T {\n    return this.x as T;\n  }\n\n  register(...args) {\n    return this.f(...args);\n  }\n\n  longArgsFun(options: {\n    root: string;\n    prefix?: string;\n    setHeaders?: Function;\n    send?: any;\n  }) {\n    return this.f(options);\n  }\n\n  closure(\n    x: number,\n  ): (path: string, callback: Function) => any {\n    const normalizedPath = path === '/*' ? '' : path;\n  }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-member-init.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n--fields=+i\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-member-init.d/expected.tags",
    "content": "User\tinput.ts\t/^class User {$/;\"\tc\nsoundMan\tinput.ts\t/^\tprivate readonly soundMan = singletons.getSoundManager();$/;\"\tp\tclass:User\nlssMan\tinput.ts\t/^\tprivate readonly lssMan = singletons.getLoopedSoundSourceManager();$/;\"\tp\tclass:User\nminimapStyle\tinput.ts\t/^\toverride minimapStyle = Color.USER;$/;\"\tp\tclass:User\ndestroy\tinput.ts\t/^\toverride destroy(parent: any) {$/;\"\tm\tclass:User\nparent\tinput.ts\t/^\toverride destroy(parent: any) {$/;\"\tz\tmethod:User.destroy\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-member-init.d/input.ts",
    "content": "/* base on User.ts from Stendhal -- License: AGPL */\n/* https://github.com/arianne/stendhal/blob/master/srcjs/stendhal/entity/User.ts */\n\nclass User {\n\tprivate readonly soundMan = singletons.getSoundManager();\n\tprivate readonly lssMan = singletons.getLoopedSoundSourceManager();\n\n\toverride minimapStyle = Color.USER;\n\n\toverride destroy(parent: any) {\n\t\tthis.onExitZone();\n\t\tsuper.destroy(parent);\n\t}\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-member-with-props.d/args.ctags",
    "content": "--sort=no\n--fields-TypeScript=+{properties}\n--fields=+{access}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-member-with-props.d/expected.tags",
    "content": "C\tinput.ts\t/^class C {$/;\"\tc\na\tinput.ts\t/^      a$/;\"\tp\tclass:C\taccess:public\nb\tinput.ts\t/^      protected b;$/;\"\tp\tclass:C\taccess:protected\nc\tinput.ts\t/^      c$/;\"\tp\tclass:C\taccess:public\nd\tinput.ts\t/^      static d;$/;\"\tp\tclass:C\taccess:public\tproperties:static\ne\tinput.ts\t/^      e$/;\"\tp\tclass:C\taccess:public\nf\tinput.ts\t/^      protected static f;$/;\"\tp\tclass:C\taccess:protected\tproperties:static\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-member-with-props.d/input.ts",
    "content": "class C {\n      a\n      protected b;\n      c\n      static d;\n      e\n      protected static f;\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-member-with-props.d/validator",
    "content": "tsc\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-white.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=fcigemnzpvCgGal\n--fields=+i\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-white.d/expected.tags",
    "content": "CPoint\tinput.ts\t/^class CPoint {$/;\"\tc\nx\tinput.ts\t/^  x: number$/;\"\tp\tclass:CPoint\ny\tinput.ts\t/^  y: number$/;\"\tp\tclass:CPoint\nconstructor\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tm\tclass:CPoint\nx\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\ny\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\nBankAccount\tinput.ts\t/^class BankAccount {$/;\"\tc\nbalance\tinput.ts\t/^  balance = 0$/;\"\tp\tclass:BankAccount\ndeposit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tm\tclass:BankAccount\ncredit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tz\tmethod:BankAccount.deposit\nCheckingAccount\tinput.ts\t/^class CheckingAccount extends BankAccount {$/;\"\tc\tinherits:BankAccount\nconstructor\tinput.ts\t/^  constructor(balance: number) {$/;\"\tm\tclass:CheckingAccount\nbalance\tinput.ts\t/^  constructor(balance: number) {$/;\"\tz\tmethod:CheckingAccount.constructor\nwriteCheck\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tm\tclass:CheckingAccount\ndebit\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tz\tmethod:CheckingAccount.writeCheck\nList\tinput.ts\t/^class List<T extends NamedItem> {$/;\"\tc\nnext\tinput.ts\t/^  next: List<T> = null$/;\"\tp\tclass:List\nconstructor\tinput.ts\t/^  constructor(public item: T) {$/;\"\tm\tclass:List\nitem\tinput.ts\t/^  constructor(public item: T) {$/;\"\tp\tclass:List\ninsertAfter\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tm\tclass:List\nitem\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tz\tmethod:List.insertAfter\ntemp\tinput.ts\t/^    var temp = this.next$/;\"\tl\tmethod:List.insertAfter\nlog\tinput.ts\t/^  log() {$/;\"\tm\tclass:List\nC\tinput.ts\t/^class C {$/;\"\tc\nx\tinput.ts\t/^  x: number$/;\"\tp\tclass:C\nx\tinput.ts\t/^  static x: string$/;\"\tp\tclass:C\nMessenger\tinput.ts\t/^class Messenger {$/;\"\tc\nmessage\tinput.ts\t/^  message = \"Hello World\"$/;\"\tp\tclass:Messenger\nstart\tinput.ts\t/^  start() {$/;\"\tm\tclass:Messenger\n_this\tinput.ts\t/^    var _this = this$/;\"\tl\tmethod:Messenger.start\nD\tinput.ts\t/^class D {$/;\"\tc\ndata\tinput.ts\t/^  data: string | string[]$/;\"\tp\tclass:D\ngetData\tinput.ts\t/^  getData() {$/;\"\tm\tclass:D\ndata\tinput.ts\t/^    var data = this.data$/;\"\tl\tmethod:D.getData\nPoint\tinput.ts\t/^class Point {$/;\"\tc\nfakePointBuilder\tinput.ts\t/^  protected fakePointBuilder: () => { x: number, y: number }$/;\"\tp\tclass:Point\nconstructor\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tm\tclass:Point\nx\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\ny\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\nlength\tinput.ts\t/^  public length() { return Math.sqrt(this.x * this.x + this.y * this.y) }$/;\"\tm\tclass:Point\norigin\tinput.ts\t/^  static origin = new Point(0, 0)$/;\"\tp\tclass:Point\nA\tinput.ts\t/^class A {$/;\"\tc\nx\tinput.ts\t/^  private x: number$/;\"\tp\tclass:A\ny\tinput.ts\t/^  protected y: number$/;\"\tp\tclass:A\nfun\tinput.ts\t/^  public fun: (a: 22 | 30, b: CPoint) => number | string$/;\"\tp\tclass:A\nf\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tm\tclass:A\na\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\nb\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\ngetXAsT\tinput.ts\t/^  getXAsT<T = any>(): T {$/;\"\tm\tclass:A\nregister\tinput.ts\t/^  register(...args) {$/;\"\tm\tclass:A\nargs\tinput.ts\t/^  register(...args) {$/;\"\tz\tmethod:A.register\nlongArgsFun\tinput.ts\t/^  longArgsFun(options: {$/;\"\tm\tclass:A\noptions\tinput.ts\t/^  longArgsFun(options: {$/;\"\tz\tmethod:A.longArgsFun\nclosure\tinput.ts\t/^  closure($/;\"\tm\tclass:A\nx\tinput.ts\t/^    x: number,$/;\"\tz\tmethod:A.closure\nnormalizedPath\tinput.ts\t/^    const normalizedPath = path === '\\/*' ? '' : path$/;\"\tC\tmethod:A.closure\nX\tinput.ts\t/^class X {$/;\"\tc\nf\tinput.ts\t/^    public f(a: T): number {$/;\"\tm\tclass:X\na\tinput.ts\t/^    public f(a: T): number {$/;\"\tz\tmethod:X.f\ng\tinput.ts\t/^    public g(a: T): number {$/;\"\tm\tclass:X\na\tinput.ts\t/^    public g(a: T): number {$/;\"\tz\tmethod:X.g\nC\tinput.ts\t/^class C extends A implements B, D {$/;\"\tc\tinherits:A,B,D\nx\tinput.ts\t/^    x: number$/;\"\tp\tclass:C\nCt\tinput.ts\t/^class Ct<T> extends A<T> implements B<T>, D, E<T> {$/;\"\tc\tinherits:A,B,D,E\nx\tinput.ts\t/^    x: number$/;\"\tp\tclass:Ct\nA\tinput.ts\t/^class A<T> implements I<T>$/;\"\tc\tinherits:I\nTasksService\tinput.ts\t/^export class TasksService {$/;\"\tc\ntasks\tinput.ts\t/^  private tasks: string[] = []$/;\"\tp\tclass:TasksService\ntaskObj\tinput.ts\t/^  private taskObj: object = {}$/;\"\tp\tclass:TasksService\ngetAllTasks\tinput.ts\t/^  getAllTasks(): string[] {$/;\"\tm\tclass:TasksService\ngetTaskObj\tinput.ts\t/^  getTaskObj(): object {$/;\"\tm\tclass:TasksService\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class-white.d/input.ts",
    "content": "class CPoint {\n  x: number\n  y: number\n  constructor(x: number, y: number) {\n    this.x = x\n    this.y = y\n  }\n}\n\nclass BankAccount {\n  balance = 0\n  deposit(credit: number) {\n    this.balance += credit\n    return this.balance\n  }\n}\n\nclass CheckingAccount extends BankAccount {\n  constructor(balance: number) {\n    super(balance)\n  }\n  writeCheck(debit: number) {\n    this.balance -= debit\n  }\n}\n\nclass List<T extends NamedItem> {\n  next: List<T> = null\n  constructor(public item: T) {\n  }\n  insertAfter(item: T) {\n    var temp = this.next\n    this.next = new List(item)\n    this.next.next = temp\n  }\n  log() {\n    console.log(this.item.name)\n  }\n  // ...\n}\n\nclass C {\n  x: number\n  static x: string\n}\n\nclass Messenger {\n  message = \"Hello World\"\n  start() {\n    var _this = this\n    setTimeout(function() { alert(_this.message) }, 3000)\n  }\n}\n\nclass D {\n  data: string | string[]\n  getData() {\n    var data = this.data\n    return typeof data === \"string\" ? data : data.join(\" \")\n  }\n}\n\nclass Point {\n  protected fakePointBuilder: () => { x: number, y: number }\n  constructor(public x: number, public y: number) { }\n  public length() { return Math.sqrt(this.x * this.x + this.y * this.y) }\n  static origin = new Point(0, 0)\n}\n\nclass A {\n  private x: number\n  protected y: number\n  public fun: (a: 22 | 30, b: CPoint) => number | string\n\n  static f(a: A, b: B) {\n    a.x = 1 // Ok\n    b.x = 1 // Ok\n    a.y = 1 // Ok\n    b.y = 1 // Ok\n  }\n\n  getXAsT<T = any>(): T {\n    return this.x as T\n  }\n\n  register(...args) {\n    return this.f(...args)\n  }\n\n  longArgsFun(options: {\n    root: string\n    prefix?: string\n    setHeaders?: Function\n    send?: any\n  }) {\n    return this.f(options)\n  }\n\n  closure(\n    x: number,\n  ): (path: string, callback: Function) => any {\n    const normalizedPath = path === '/*' ? '' : path\n  }\n}\n\nclass X {\n    public f(a: T): number {\n        return g({ a: a})\n    }\n\n    public g(a: T): number {\n        return 1\n    }\n}\n\nclass C extends A implements B, D {\n    x: number\n}\n\nclass Ct<T> extends A<T> implements B<T>, D, E<T> {\n    x: number\n}\n\nclass A<T> implements I<T>\n{\n}\n\nexport class TasksService {\n  private tasks: string[] = []\n  private taskObj: object = {}\n\n  getAllTasks(): string[] {\n    return this.tasks\n  }\n\n  getTaskObj(): object {\n    return this.taskObj\n  }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n--fields=+i\n--fields-typescript=+{properties}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class.d/expected.tags",
    "content": "CPoint\tinput.ts\t/^class CPoint {$/;\"\tc\nx\tinput.ts\t/^  x: number;$/;\"\tp\tclass:CPoint\ny\tinput.ts\t/^  y: number;$/;\"\tp\tclass:CPoint\nconstructor\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tm\tclass:CPoint\nx\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\ny\tinput.ts\t/^  constructor(x: number, y: number) {$/;\"\tz\tmethod:CPoint.constructor\nBankAccount\tinput.ts\t/^class BankAccount {$/;\"\tc\nbalance\tinput.ts\t/^  balance = 0;$/;\"\tp\tclass:BankAccount\ndeposit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tm\tclass:BankAccount\ncredit\tinput.ts\t/^  deposit(credit: number) {$/;\"\tz\tmethod:BankAccount.deposit\nCheckingAccount\tinput.ts\t/^class CheckingAccount extends BankAccount {$/;\"\tc\tinherits:BankAccount\nconstructor\tinput.ts\t/^  constructor(balance: number) {$/;\"\tm\tclass:CheckingAccount\nbalance\tinput.ts\t/^  constructor(balance: number) {$/;\"\tz\tmethod:CheckingAccount.constructor\nwriteCheck\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tm\tclass:CheckingAccount\ndebit\tinput.ts\t/^  writeCheck(debit: number) {$/;\"\tz\tmethod:CheckingAccount.writeCheck\nList\tinput.ts\t/^class List<T extends NamedItem> {$/;\"\tc\nnext\tinput.ts\t/^  next: List<T> = null;$/;\"\tp\tclass:List\nconstructor\tinput.ts\t/^  constructor(public item: T) {$/;\"\tm\tclass:List\nitem\tinput.ts\t/^  constructor(public item: T) {$/;\"\tp\tclass:List\ninsertAfter\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tm\tclass:List\nitem\tinput.ts\t/^  insertAfter(item: T) {$/;\"\tz\tmethod:List.insertAfter\ntemp\tinput.ts\t/^    var temp = this.next;$/;\"\tl\tmethod:List.insertAfter\nlog\tinput.ts\t/^  log() {$/;\"\tm\tclass:List\nC\tinput.ts\t/^class C {$/;\"\tc\nx\tinput.ts\t/^  x: number;$/;\"\tp\tclass:C\nx\tinput.ts\t/^  static x: string;$/;\"\tp\tclass:C\tproperties:static\nMessenger\tinput.ts\t/^class Messenger {$/;\"\tc\nmessage\tinput.ts\t/^  message = \"Hello World\";$/;\"\tp\tclass:Messenger\nstart\tinput.ts\t/^  start() {$/;\"\tm\tclass:Messenger\n_this\tinput.ts\t/^    var _this = this;$/;\"\tl\tmethod:Messenger.start\nD\tinput.ts\t/^class D {$/;\"\tc\ndata\tinput.ts\t/^  data: string | string[];$/;\"\tp\tclass:D\ngetData\tinput.ts\t/^  getData() {$/;\"\tm\tclass:D\ndata\tinput.ts\t/^    var data = this.data;$/;\"\tl\tmethod:D.getData\nPoint\tinput.ts\t/^class Point {$/;\"\tc\nfakePointBuilder\tinput.ts\t/^  protected fakePointBuilder: () => { x: number, y: number };$/;\"\tp\tclass:Point\nconstructor\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tm\tclass:Point\nx\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\ny\tinput.ts\t/^  constructor(public x: number, public y: number) { }$/;\"\tp\tclass:Point\nlength\tinput.ts\t/^  public length() { return Math.sqrt(this.x * this.x + this.y * this.y); }$/;\"\tm\tclass:Point\norigin\tinput.ts\t/^  static origin = new Point(0, 0);$/;\"\tp\tclass:Point\tproperties:static\nA\tinput.ts\t/^class A {$/;\"\tc\nx\tinput.ts\t/^  private x: number;$/;\"\tp\tclass:A\ny\tinput.ts\t/^  protected y: number;$/;\"\tp\tclass:A\nfun\tinput.ts\t/^  public fun: (a: 22 | 30, b: CPoint) => number | string;$/;\"\tp\tclass:A\nf\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tm\tclass:A\tproperties:static\na\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\nb\tinput.ts\t/^  static f(a: A, b: B) {$/;\"\tz\tmethod:A.f\ngetXAsT\tinput.ts\t/^  getXAsT<T = any>(): T {$/;\"\tm\tclass:A\nregister\tinput.ts\t/^  register(...args) {$/;\"\tm\tclass:A\nargs\tinput.ts\t/^  register(...args) {$/;\"\tz\tmethod:A.register\nlongArgsFun\tinput.ts\t/^  longArgsFun(options: {$/;\"\tm\tclass:A\noptions\tinput.ts\t/^  longArgsFun(options: {$/;\"\tz\tmethod:A.longArgsFun\nclosure\tinput.ts\t/^  closure($/;\"\tm\tclass:A\nx\tinput.ts\t/^    x: number,$/;\"\tz\tmethod:A.closure\nnormalizedPath\tinput.ts\t/^    const normalizedPath = path === '\\/*' ? '' : path;$/;\"\tC\tmethod:A.closure\nX\tinput.ts\t/^class X {$/;\"\tc\nf\tinput.ts\t/^    public f(a: T): number {$/;\"\tm\tclass:X\na\tinput.ts\t/^    public f(a: T): number {$/;\"\tz\tmethod:X.f\ng\tinput.ts\t/^    public g(a: T): number {$/;\"\tm\tclass:X\na\tinput.ts\t/^    public g(a: T): number {$/;\"\tz\tmethod:X.g\nC\tinput.ts\t/^class C extends A implements B, D {$/;\"\tc\tinherits:A,B,D\nx\tinput.ts\t/^    x: number;$/;\"\tp\tclass:C\nCt\tinput.ts\t/^class Ct<T> extends A<T> implements B<T>, D, E<T> {$/;\"\tc\tinherits:A,B,D,E\nx\tinput.ts\t/^    x: number;$/;\"\tp\tclass:Ct\nA\tinput.ts\t/^class A<T> implements I<T>$/;\"\tc\tinherits:I\nTasksService\tinput.ts\t/^export class TasksService {$/;\"\tc\ntasks\tinput.ts\t/^  private tasks: string[] = [];$/;\"\tp\tclass:TasksService\ntaskObj\tinput.ts\t/^  private taskObj: object = {};$/;\"\tp\tclass:TasksService\ngetAllTasks\tinput.ts\t/^  getAllTasks(): string[] {$/;\"\tm\tclass:TasksService\ngetTaskObj\tinput.ts\t/^  getTaskObj(): object {$/;\"\tm\tclass:TasksService\nTest\tinput-0.ts\t/^export class Test {$/;\"\tc\nvar\tinput-0.ts\t/^    public var?: string;$/;\"\tp\tclass:Test\nfoo\tinput-0.ts\t/^    public foo() {$/;\"\tm\tclass:Test\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class.d/input-0.ts",
    "content": "// Taken from the #4336 reported by @zeerd\nexport class Test {\n    public var?: string;\n\n    public foo() {\n        return 'hello';\n    }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-class.d/input.ts",
    "content": "class CPoint {\n  x: number;\n  y: number;\n  constructor(x: number, y: number) {\n    this.x = x;\n    this.y = y;\n  }\n}\n\nclass BankAccount {\n  balance = 0;\n  deposit(credit: number) {\n    this.balance += credit;\n    return this.balance;\n  }\n}\n\nclass CheckingAccount extends BankAccount {\n  constructor(balance: number) {\n    super(balance);\n  }\n  writeCheck(debit: number) {\n    this.balance -= debit;\n  }\n}\n\nclass List<T extends NamedItem> {\n  next: List<T> = null;\n  constructor(public item: T) {\n  }\n  insertAfter(item: T) {\n    var temp = this.next;\n    this.next = new List(item);\n    this.next.next = temp;\n  }\n  log() {\n    console.log(this.item.name);\n  }\n  // ...\n}\n\nclass C {\n  x: number;\n  static x: string;\n}\n\nclass Messenger {\n  message = \"Hello World\";\n  start() {\n    var _this = this;\n    setTimeout(function() { alert(_this.message); }, 3000);\n  }\n};\n\nclass D {\n  data: string | string[];\n  getData() {\n    var data = this.data;\n    return typeof data === \"string\" ? data : data.join(\" \");\n  }\n}\n\nclass Point {\n  protected fakePointBuilder: () => { x: number, y: number };\n  constructor(public x: number, public y: number) { }\n  public length() { return Math.sqrt(this.x * this.x + this.y * this.y); }\n  static origin = new Point(0, 0);\n}\n\nclass A {\n  private x: number;\n  protected y: number;\n  public fun: (a: 22 | 30, b: CPoint) => number | string;\n\n  static f(a: A, b: B) {\n    a.x = 1; // Ok\n    b.x = 1; // Ok\n    a.y = 1; // Ok\n    b.y = 1; // Ok\n  }\n\n  getXAsT<T = any>(): T {\n    return this.x as T;\n  }\n\n  register(...args) {\n    return this.f(...args);\n  }\n\n  longArgsFun(options: {\n    root: string;\n    prefix?: string;\n    setHeaders?: Function;\n    send?: any;\n  }) {\n    return this.f(options);\n  }\n\n  closure(\n    x: number,\n  ): (path: string, callback: Function) => any {\n    const normalizedPath = path === '/*' ? '' : path;\n  }\n}\n\nclass X {\n    public f(a: T): number {\n        return g({ a: a});\n    }\n\n    public g(a: T): number {\n        return 1;\n    }\n}\n\nclass C extends A implements B, D {\n    x: number;\n}\n\nclass Ct<T> extends A<T> implements B<T>, D, E<T> {\n    x: number;\n}\n\nclass A<T> implements I<T>\n{\n}\n\nexport class TasksService {\n  private tasks: string[] = [];\n  private taskObj: object = {};\n\n  getAllTasks(): string[] {\n    return this.tasks;\n  }\n\n  getTaskObj(): object {\n    return this.taskObj;\n  }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-const.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-const.d/expected.tags",
    "content": "scene\tinput.ts\t/^let scene: three.Scene,$/;\"\tv\ncamera\tinput.ts\t/^  camera: three.PerspectiveCamera,$/;\"\tv\nrenderer\tinput.ts\t/^  renderer: three.WebGLRenderer;$/;\"\tv\ncubeArr\tinput.ts\t/^const cubeArr = new three.Group();$/;\"\tC\nsetupScene\tinput.ts\t/^const setupScene = (): void => {$/;\"\tC\ncreateCubeArr\tinput.ts\t/^const createCubeArr = (): void => {$/;\"\tC\ncreateWall\tinput.ts\t/^const createWall = (): void => {$/;\"\tC\ncreateCube\tinput.ts\t/^const createCube = (): three.Mesh => {$/;\"\tC\nanimate\tinput.ts\t/^const animate = (): void => {$/;\"\tC\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-const.d/input.ts",
    "content": "// Taken from issue #2488 submitted by @sparkcanon\nimport * as three from \"three\";\n\nlet scene: three.Scene,\n  camera: three.PerspectiveCamera,\n  renderer: three.WebGLRenderer;\nconst cubeArr = new three.Group();\n\n// TODO: Add lighting\nconst setupScene = (): void => {\n  scene = new three.Scene();\n  camera = new three.PerspectiveCamera(\n    75,\n    window.innerWidth / window.innerHeight,\n    0.1,\n    1000\n  );\n\n  renderer = new three.WebGLRenderer();\n  renderer.setSize(window.innerWidth, window.innerHeight);\n  document.body.appendChild(renderer.domElement);\n  camera.position.z = 20;\n};\n\n// TODO: Position the cubes in the center of the screen\nconst createCubeArr = (): void => {\n  let cubes;\n\n  for (let i = 0; i < 5; i++) {\n    for (let r = 1; r < 5; r++) {\n      cubes = createCube();\n      cubes.position.set(i * 3, r * 2, 0);\n      cubeArr.add(cubes);\n    }\n  }\n  cubeArr.position.set(-5, -5, 0);\n  scene.add(cubeArr);\n};\n\n// TODO: Receive shadow\nconst createWall = (): void => {\n  const geometry = new three.PlaneGeometry(20, 20, 20);\n  const material = new three.MeshBasicMaterial({\n    color: 0x0000ff,\n    side: three.DoubleSide,\n  });\n  const mesh = new three.Mesh(geometry, material);\n  scene.add(mesh);\n};\n\nconst createCube = (): three.Mesh => {\n  const geometry, material;\n  geometry = new three.BoxGeometry(1, 1, 1);\n  material = new three.MeshBasicMaterial({\n    color: 0x00ff00,\n    side: three.DoubleSide,\n  });\n  const cube = new three.Mesh(geometry, material);\n  return cube;\n};\n\nconst animate = (): void => {\n  requestAnimationFrame(animate);\n  renderer.render(scene, camera);\n};\n\nsetupScene();\ncreateCubeArr();\ncreateWall();\nanimate();\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-decorators-white.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-decorators-white.d/expected.tags",
    "content": "Greeter\tinput.ts\t/^class Greeter {$/;\"\tc\ngreeting\tinput.ts\t/^    greeting: string$/;\"\tp\tclass:Greeter\nconstructor\tinput.ts\t/^    constructor(message: string) {$/;\"\tm\tclass:Greeter\nmessage\tinput.ts\t/^    constructor(message: string) {$/;\"\tz\tmethod:Greeter.constructor\ngreet\tinput.ts\t/^    greet(@required name: string) {$/;\"\tm\tclass:Greeter\nname\tinput.ts\t/^    greet(@required name: string) {$/;\"\tz\tmethod:Greeter.greet\nPoint\tinput.ts\t/^class Point {$/;\"\tc\n_x\tinput.ts\t/^    private _x: number$/;\"\tp\tclass:Point\n_y\tinput.ts\t/^    private _y: number$/;\"\tp\tclass:Point\nconstructor\tinput.ts\t/^    constructor(@inject x: number, @inject('yNumber') y: number) {$/;\"\tm\tclass:Point\nx\tinput.ts\t/^    constructor(@inject x: number, @inject('yNumber') y: number) {$/;\"\tz\tmethod:Point.constructor\ny\tinput.ts\t/^    constructor(@inject x: number, @inject('yNumber') y: number) {$/;\"\tz\tmethod:Point.constructor\nx\tinput.ts\t/^    get x() { return this._x }$/;\"\tm\tclass:Point\ny\tinput.ts\t/^    get y() { return this._y }$/;\"\tm\tclass:Point\nLine\tinput.ts\t/^class Line {$/;\"\tc\n_p0\tinput.ts\t/^    private _p0: Point$/;\"\tp\tclass:Line\n_p1\tinput.ts\t/^    private _p1: Point$/;\"\tp\tclass:Line\np0\tinput.ts\t/^    set p0(value: Point) { this._p0 = value }$/;\"\tm\tclass:Line\nvalue\tinput.ts\t/^    set p0(value: Point) { this._p0 = value }$/;\"\tz\tmethod:Line.p0\np0\tinput.ts\t/^    get p0() { return this._p0 }$/;\"\tm\tclass:Line\np1\tinput.ts\t/^    set p1(value: Point) { this._p1 = value }$/;\"\tm\tclass:Line\nvalue\tinput.ts\t/^    set p1(value: Point) { this._p1 = value }$/;\"\tz\tmethod:Line.p1\np1\tinput.ts\t/^    get p1() { return this._p1 }$/;\"\tm\tclass:Line\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-decorators-white.d/input.ts",
    "content": "@sealed\n@classDecorator\nclass Greeter {\n    @format(\"Hello, %s\")\n    greeting: string\n\n    constructor(message: string) {\n        this.greeting = message\n    }\n\n    @validate\n    greet(@required name: string) {\n        return \"Hello \" + name + \", \" + this.greeting\n    }\n}\n\nclass Point {\n    private _x: number\n    private _y: number\n    constructor(@inject x: number, @inject('yNumber') y: number) {\n        this._x = x\n        this._y = y\n    }\n\n    @configurable(false)\n    get x() { return this._x }\n\n    @configurable(false)\n    get y() { return this._y }\n}\n\nclass Line {\n    private _p0: Point\n    private _p1: Point\n\n    @validate\n    @Reflect.metadata(\"design:type\", Point)\n    set p0(value: Point) { this._p0 = value }\n    get p0() { return this._p0 }\n\n    @validate\n    @Reflect.metadata(\"design:type\", Point)\n    set p1(value: Point) { this._p1 = value }\n    get p1() { return this._p1 }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-decorators.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-decorators.d/expected.tags",
    "content": "Greeter\tinput.ts\t/^class Greeter {$/;\"\tc\ngreeting\tinput.ts\t/^    greeting: string;$/;\"\tp\tclass:Greeter\nconstructor\tinput.ts\t/^    constructor(message: string) {$/;\"\tm\tclass:Greeter\nmessage\tinput.ts\t/^    constructor(message: string) {$/;\"\tz\tmethod:Greeter.constructor\ngreet\tinput.ts\t/^    greet(@required name: string) {$/;\"\tm\tclass:Greeter\nname\tinput.ts\t/^    greet(@required name: string) {$/;\"\tz\tmethod:Greeter.greet\nPoint\tinput.ts\t/^class Point {$/;\"\tc\n_x\tinput.ts\t/^    private _x: number;$/;\"\tp\tclass:Point\n_y\tinput.ts\t/^    private _y: number;$/;\"\tp\tclass:Point\nconstructor\tinput.ts\t/^    constructor(@inject x: number, @inject('yNumber') y: number) {$/;\"\tm\tclass:Point\nx\tinput.ts\t/^    constructor(@inject x: number, @inject('yNumber') y: number) {$/;\"\tz\tmethod:Point.constructor\ny\tinput.ts\t/^    constructor(@inject x: number, @inject('yNumber') y: number) {$/;\"\tz\tmethod:Point.constructor\nx\tinput.ts\t/^    get x() { return this._x; }$/;\"\tm\tclass:Point\ny\tinput.ts\t/^    get y() { return this._y; }$/;\"\tm\tclass:Point\nLine\tinput.ts\t/^class Line {$/;\"\tc\n_p0\tinput.ts\t/^    private _p0: Point;$/;\"\tp\tclass:Line\n_p1\tinput.ts\t/^    private _p1: Point;$/;\"\tp\tclass:Line\np0\tinput.ts\t/^    set p0(value: Point) { this._p0 = value; }$/;\"\tm\tclass:Line\nvalue\tinput.ts\t/^    set p0(value: Point) { this._p0 = value; }$/;\"\tz\tmethod:Line.p0\np0\tinput.ts\t/^    get p0() { return this._p0; }$/;\"\tm\tclass:Line\np1\tinput.ts\t/^    set p1(value: Point) { this._p1 = value; }$/;\"\tm\tclass:Line\nvalue\tinput.ts\t/^    set p1(value: Point) { this._p1 = value; }$/;\"\tz\tmethod:Line.p1\np1\tinput.ts\t/^    get p1() { return this._p1; }$/;\"\tm\tclass:Line\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-decorators.d/input.ts",
    "content": "@sealed\n@classDecorator\nclass Greeter {\n    @format(\"Hello, %s\")\n    greeting: string;\n\n    constructor(message: string) {\n        this.greeting = message;\n    }\n\n    @validate\n    greet(@required name: string) {\n        return \"Hello \" + name + \", \" + this.greeting;\n    }\n}\n\nclass Point {\n    private _x: number;\n    private _y: number;\n    constructor(@inject x: number, @inject('yNumber') y: number) {\n        this._x = x;\n        this._y = y;\n    }\n\n    @configurable(false)\n    get x() { return this._x; }\n\n    @configurable(false)\n    get y() { return this._y; }\n}\n\nclass Line {\n    private _p0: Point;\n    private _p1: Point;\n\n    @validate\n    @Reflect.metadata(\"design:type\", Point)\n    set p0(value: Point) { this._p0 = value; }\n    get p0() { return this._p0; }\n\n    @validate\n    @Reflect.metadata(\"design:type\", Point)\n    set p1(value: Point) { this._p1 = value; }\n    get p1() { return this._p1; }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-enum-white.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-enum-white.d/expected.tags",
    "content": "Color\tinput.ts\t/^enum Color { Red Green Blue }$/;\"\tg\nRed\tinput.ts\t/^enum Color { Red Green Blue }$/;\"\te\tenum:Color\nGreen\tinput.ts\t/^enum Color { Red Green Blue }$/;\"\te\tenum:Color\nBlue\tinput.ts\t/^enum Color { Red Green Blue }$/;\"\te\tenum:Color\nTest\tinput.ts\t/^enum Test {$/;\"\tg\nA\tinput.ts\t/^  A$/;\"\te\tenum:Test\nB\tinput.ts\t/^  B$/;\"\te\tenum:Test\nC\tinput.ts\t/^  C = Math.floor(Math.random() * 1000)$/;\"\te\tenum:Test\nD\tinput.ts\t/^  D = 10$/;\"\te\tenum:Test\nE\tinput.ts\t/^  E$/;\"\te\tenum:Test\nStyle\tinput.ts\t/^export enum Style {$/;\"\tg\nNone\tinput.ts\t/^  None = 0$/;\"\te\tenum:Style\nBold\tinput.ts\t/^  Bold = 1$/;\"\te\tenum:Style\nItalic\tinput.ts\t/^  Italic = 2$/;\"\te\tenum:Style\nUnderline\tinput.ts\t/^  Underline = 4$/;\"\te\tenum:Style\nEmphasis\tinput.ts\t/^  Emphasis = Bold | Italic$/;\"\te\tenum:Style\nHyperlink\tinput.ts\t/^  Hyperlink = Bold | Underline$/;\"\te\tenum:Style\nComparison\tinput.ts\t/^const enum Comparison {$/;\"\tg\nLessThan\tinput.ts\t/^  LessThan = -1$/;\"\te\tenum:Comparison\nEqualTo\tinput.ts\t/^  EqualTo = 0$/;\"\te\tenum:Comparison\nGreaterThan\tinput.ts\t/^  GreaterThan = 1$/;\"\te\tenum:Comparison\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-enum-white.d/input.ts",
    "content": "enum Color { Red Green Blue }\nenum Test {\n  A\n  B\n  C = Math.floor(Math.random() * 1000)\n  D = 10\n  E\n}\n\nexport enum Style {\n  None = 0\n  Bold = 1\n  Italic = 2\n  Underline = 4\n  Emphasis = Bold | Italic\n  Hyperlink = Bold | Underline\n}\n\nconst enum Comparison {\n  LessThan = -1\n  EqualTo = 0\n  GreaterThan = 1\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-enum.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-enum.d/expected.tags",
    "content": "Color\tinput.ts\t/^enum Color { Red, Green, Blue }$/;\"\tg\nRed\tinput.ts\t/^enum Color { Red, Green, Blue }$/;\"\te\tenum:Color\nGreen\tinput.ts\t/^enum Color { Red, Green, Blue }$/;\"\te\tenum:Color\nBlue\tinput.ts\t/^enum Color { Red, Green, Blue }$/;\"\te\tenum:Color\nTest\tinput.ts\t/^enum Test {$/;\"\tg\nA\tinput.ts\t/^  A,$/;\"\te\tenum:Test\nB\tinput.ts\t/^  B,$/;\"\te\tenum:Test\nC\tinput.ts\t/^  C = Math.floor(Math.random() * 1000),$/;\"\te\tenum:Test\nD\tinput.ts\t/^  D = 10,$/;\"\te\tenum:Test\nE\tinput.ts\t/^  E$/;\"\te\tenum:Test\nStyle\tinput.ts\t/^export enum Style {$/;\"\tg\nNone\tinput.ts\t/^  None = 0,$/;\"\te\tenum:Style\nBold\tinput.ts\t/^  Bold = 1,$/;\"\te\tenum:Style\nItalic\tinput.ts\t/^  Italic = 2,$/;\"\te\tenum:Style\nUnderline\tinput.ts\t/^  Underline = 4,$/;\"\te\tenum:Style\nEmphasis\tinput.ts\t/^  Emphasis = Bold | Italic,$/;\"\te\tenum:Style\nHyperlink\tinput.ts\t/^  Hyperlink = Bold | Underline$/;\"\te\tenum:Style\nComparison\tinput.ts\t/^const enum Comparison {$/;\"\tg\nLessThan\tinput.ts\t/^  LessThan = -1,$/;\"\te\tenum:Comparison\nEqualTo\tinput.ts\t/^  EqualTo = 0,$/;\"\te\tenum:Comparison\nGreaterThan\tinput.ts\t/^  GreaterThan = 1$/;\"\te\tenum:Comparison\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-enum.d/input.ts",
    "content": "enum Color { Red, Green, Blue }\nenum Test {\n  A,\n  B,\n  C = Math.floor(Math.random() * 1000),\n  D = 10,\n  E\n}\n\nexport enum Style {\n  None = 0,\n  Bold = 1,\n  Italic = 2,\n  Underline = 4,\n  Emphasis = Bold | Italic,\n  Hyperlink = Bold | Underline\n}\n\nconst enum Comparison {\n  LessThan = -1,\n  EqualTo = 0,\n  GreaterThan = 1\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function-variable-white.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function-variable-white.d/expected.tags",
    "content": "mul\tinput.ts\t/^function mul(a: number, b: number) {$/;\"\tf\na\tinput.ts\t/^function mul(a: number, b: number) {$/;\"\tz\tfunction:mul\nb\tinput.ts\t/^function mul(a: number, b: number) {$/;\"\tz\tfunction:mul\nnumberToString\tinput.ts\t/^function numberToString(a: number[]) {$/;\"\tf\na\tinput.ts\t/^function numberToString(a: number[]) {$/;\"\tz\tfunction:numberToString\nstringArray\tinput.ts\t/^  var stringArray = a.map(v => v.toString())$/;\"\tl\tfunction:numberToString\nmap\tinput.ts\t/^function map<T, U>(a: T[], f: (x: T) => U): U[] {$/;\"\tf\na\tinput.ts\t/^function map<T, U>(a: T[], f: (x: T) => U): U[] {$/;\"\tz\tfunction:map\nf\tinput.ts\t/^function map<T, U>(a: T[], f: (x: T) => U): U[] {$/;\"\tz\tfunction:map\nresult\tinput.ts\t/^  var result: U[] = []$/;\"\tl\tfunction:map\ni\tinput.ts\t/^  for (var i = 0; i < a.length; i++) result.push(f(a[i]))$/;\"\tl\tfunction:map\nzip\tinput.ts\t/^function zip<S, T, U>(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] {$/;\"\tf\nx\tinput.ts\t/^function zip<S, T, U>(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] {$/;\"\tz\tfunction:zip\ny\tinput.ts\t/^function zip<S, T, U>(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] {$/;\"\tz\tfunction:zip\ncombine\tinput.ts\t/^function zip<S, T, U>(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] {$/;\"\tz\tfunction:zip\nlen\tinput.ts\t/^  var len = Math.max(x.length, y.length)$/;\"\tl\tfunction:zip\nresult\tinput.ts\t/^  var result: U[] = []$/;\"\tl\tfunction:zip\ni\tinput.ts\t/^  for (var i = 0; i < len; i++) result.push(combine(x[i])(y[i]))$/;\"\tl\tfunction:zip\nf1\tinput.ts\t/^function f1(x: string | number | boolean) {$/;\"\tf\nx\tinput.ts\t/^function f1(x: string | number | boolean) {$/;\"\tz\tfunction:f1\ny\tinput.ts\t/^    var y = x \\/\\/ Type of y is string | number$/;\"\tl\tfunction:f1\nz\tinput.ts\t/^    var z = x \\/\\/ Type of z is boolean$/;\"\tl\tfunction:f1\nf2\tinput.ts\t/^function f2(input: boolean) {$/;\"\tf\ninput\tinput.ts\t/^function f2(input: boolean) {$/;\"\tz\tfunction:f2\na\tinput.ts\t/^    let a = 100$/;\"\tl\tfunction:f2\nb\tinput.ts\t/^        let b = a + 1$/;\"\tl\tfunction:f2\nf3\tinput.ts\t/^function f3(input: boolean) {$/;\"\tf\ninput\tinput.ts\t/^function f3(input: boolean) {$/;\"\tz\tfunction:f3\na\tinput.ts\t/^    const a = 100$/;\"\tC\tfunction:f3\nb\tinput.ts\t/^        let b = a + 1$/;\"\tl\tfunction:f3\nf4\tinput.ts\t/^function f4(input = [1, 2]) {$/;\"\tf\ninput\tinput.ts\t/^function f4(input = [1, 2]) {$/;\"\tz\tfunction:f4\nfirst\tinput.ts\t/^  let [first, second] = input$/;\"\tl\tfunction:f4\nsecond\tinput.ts\t/^  let [first, second] = input$/;\"\tl\tfunction:f4\nf5\tinput.ts\t/^function f5([first, second]: [number, number]) {$/;\"\tf\nfirst\tinput.ts\t/^function f5([first, second]: [number, number]) {$/;\"\tz\tfunction:f5\nsecond\tinput.ts\t/^function f5([first, second]: [number, number]) {$/;\"\tz\tfunction:f5\nd\tinput.ts\t/^function d(p: string): void {$/;\"\tf\np\tinput.ts\t/^function d(p: string): void {$/;\"\tz\tfunction:d\nview\tinput.ts\t/^    const view = p as BigTableView$/;\"\tC\tfunction:d\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function-variable-white.d/input.ts",
    "content": "function mul(a: number, b: number) {\n  return a * b\n}\n\nfunction numberToString(a: number[]) {\n  var stringArray = a.map(v => v.toString())\n  return stringArray\n}\n\nfunction map<T, U>(a: T[], f: (x: T) => U): U[] {\n  var result: U[] = []\n  for (var i = 0; i < a.length; i++) result.push(f(a[i]))\n  return result\n}\n\nfunction zip<S, T, U>(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] {\n  var len = Math.max(x.length, y.length)\n  var result: U[] = []\n  for (var i = 0; i < len; i++) result.push(combine(x[i])(y[i]))\n  return result\n}\n\nfunction f1(x: string | number | boolean) {\n  if (typeof x === \"string\" || typeof x === \"number\") {\n    var y = x // Type of y is string | number\n  }\n  else {\n    var z = x // Type of z is boolean\n  }\n}\n\nfunction f2(input: boolean) {\n    let a = 100\n\n    if (input) {\n        let b = a + 1\n        return b\n    }\n\n    return a\n}\n\nfunction f3(input: boolean) {\n    const a = 100\n\n    if (input) {\n        let b = a + 1\n        return b\n    }\n\n    return a\n}\n\nfunction f4(input = [1, 2]) {\n  let [first, second] = input\n}\n\nfunction f5([first, second]: [number, number]) {\n  console.log(first)\n  console.log(second)\n}\n\nfunction d(p: string): void {\n    const view = p as BigTableView\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function-variable.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function-variable.d/expected.tags",
    "content": "mul\tinput.ts\t/^function mul(a: number, b: number) {$/;\"\tf\na\tinput.ts\t/^function mul(a: number, b: number) {$/;\"\tz\tfunction:mul\nb\tinput.ts\t/^function mul(a: number, b: number) {$/;\"\tz\tfunction:mul\nnumberToString\tinput.ts\t/^function numberToString(a: number[]) {$/;\"\tf\na\tinput.ts\t/^function numberToString(a: number[]) {$/;\"\tz\tfunction:numberToString\nstringArray\tinput.ts\t/^  var stringArray = a.map(v => v.toString());$/;\"\tl\tfunction:numberToString\nmap\tinput.ts\t/^function map<T, U>(a: T[], f: (x: T) => U): U[] {$/;\"\tf\na\tinput.ts\t/^function map<T, U>(a: T[], f: (x: T) => U): U[] {$/;\"\tz\tfunction:map\nf\tinput.ts\t/^function map<T, U>(a: T[], f: (x: T) => U): U[] {$/;\"\tz\tfunction:map\nresult\tinput.ts\t/^  var result: U[] = [];$/;\"\tl\tfunction:map\ni\tinput.ts\t/^  for (var i = 0; i < a.length; i++) result.push(f(a[i]));$/;\"\tl\tfunction:map\nzip\tinput.ts\t/^function zip<S, T, U>(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] {$/;\"\tf\nx\tinput.ts\t/^function zip<S, T, U>(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] {$/;\"\tz\tfunction:zip\ny\tinput.ts\t/^function zip<S, T, U>(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] {$/;\"\tz\tfunction:zip\ncombine\tinput.ts\t/^function zip<S, T, U>(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] {$/;\"\tz\tfunction:zip\nlen\tinput.ts\t/^  var len = Math.max(x.length, y.length);$/;\"\tl\tfunction:zip\nresult\tinput.ts\t/^  var result: U[] = [];$/;\"\tl\tfunction:zip\ni\tinput.ts\t/^  for (var i = 0; i < len; i++) result.push(combine(x[i])(y[i]));$/;\"\tl\tfunction:zip\nf1\tinput.ts\t/^function f1(x: string | number | boolean) {$/;\"\tf\nx\tinput.ts\t/^function f1(x: string | number | boolean) {$/;\"\tz\tfunction:f1\ny\tinput.ts\t/^    var y = x; \\/\\/ Type of y is string | number$/;\"\tl\tfunction:f1\nz\tinput.ts\t/^    var z = x; \\/\\/ Type of z is boolean$/;\"\tl\tfunction:f1\nf2\tinput.ts\t/^function f2(input: boolean) {$/;\"\tf\ninput\tinput.ts\t/^function f2(input: boolean) {$/;\"\tz\tfunction:f2\na\tinput.ts\t/^    let a = 100;$/;\"\tl\tfunction:f2\nb\tinput.ts\t/^        let b = a + 1;$/;\"\tl\tfunction:f2\nf3\tinput.ts\t/^function f3(input: boolean) {$/;\"\tf\ninput\tinput.ts\t/^function f3(input: boolean) {$/;\"\tz\tfunction:f3\na\tinput.ts\t/^    const a = 100;$/;\"\tC\tfunction:f3\nb\tinput.ts\t/^        let b = a + 1;$/;\"\tl\tfunction:f3\nf4\tinput.ts\t/^function f4(input = [1, 2]) {$/;\"\tf\ninput\tinput.ts\t/^function f4(input = [1, 2]) {$/;\"\tz\tfunction:f4\nfirst\tinput.ts\t/^  let [first, second] = input;$/;\"\tl\tfunction:f4\nsecond\tinput.ts\t/^  let [first, second] = input;$/;\"\tl\tfunction:f4\nf5\tinput.ts\t/^function f5([first, second]: [number, number]) {$/;\"\tf\nfirst\tinput.ts\t/^function f5([first, second]: [number, number]) {$/;\"\tz\tfunction:f5\nsecond\tinput.ts\t/^function f5([first, second]: [number, number]) {$/;\"\tz\tfunction:f5\nd\tinput.ts\t/^function d(p: string): void {$/;\"\tf\np\tinput.ts\t/^function d(p: string): void {$/;\"\tz\tfunction:d\nview\tinput.ts\t/^    const view = p as BigTableView;$/;\"\tC\tfunction:d\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function-variable.d/input.ts",
    "content": "function mul(a: number, b: number) {\n  return a * b;\n}\n\nfunction numberToString(a: number[]) {\n  var stringArray = a.map(v => v.toString());\n  return stringArray;\n}\n\nfunction map<T, U>(a: T[], f: (x: T) => U): U[] {\n  var result: U[] = [];\n  for (var i = 0; i < a.length; i++) result.push(f(a[i]));\n  return result;\n}\n\nfunction zip<S, T, U>(x: S[], y: T[], combine: (x: S) => (y: T) => U): U[] {\n  var len = Math.max(x.length, y.length);\n  var result: U[] = [];\n  for (var i = 0; i < len; i++) result.push(combine(x[i])(y[i]));\n  return result;\n}\n\nfunction f1(x: string | number | boolean) {\n  if (typeof x === \"string\" || typeof x === \"number\") {\n    var y = x; // Type of y is string | number\n  }\n  else {\n    var z = x; // Type of z is boolean\n  }\n}\n\nfunction f2(input: boolean) {\n    let a = 100;\n\n    if (input) {\n        let b = a + 1;\n        return b;\n    }\n\n    return a;\n}\n\nfunction f3(input: boolean) {\n    const a = 100;\n\n    if (input) {\n        let b = a + 1;\n        return b;\n    }\n\n    return a;\n}\n\nfunction f4(input = [1, 2]) {\n  let [first, second] = input;\n}\n\nfunction f5([first, second]: [number, number]) {\n  console.log(first);\n  console.log(second);\n}\n\nfunction d(p: string): void {\n    const view = p as BigTableView;\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function-white.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function-white.d/expected.tags",
    "content": "point\tinput.ts\t/^function point(x: number, y: number): Point {$/;\"\tf\nx\tinput.ts\t/^function point(x: number, y: number): Point {$/;\"\tz\tfunction:point\ny\tinput.ts\t/^function point(x: number, y: number): Point {$/;\"\tz\tfunction:point\nequals\tinput.ts\t/^export function equals(p1: Point, p2: Point) {$/;\"\tf\np1\tinput.ts\t/^export function equals(p1: Point, p2: Point) {$/;\"\tz\tfunction:equals\np2\tinput.ts\t/^export function equals(p1: Point, p2: Point) {$/;\"\tz\tfunction:equals\nmessage\tinput.ts\t/^export function message(s: string) {$/;\"\tf\ns\tinput.ts\t/^export function message(s: string) {$/;\"\tz\tfunction:message\npoint\tinput.ts\t/^export default function point(x: number, y: number) {$/;\"\tf\nx\tinput.ts\t/^export default function point(x: number, y: number) {$/;\"\tz\tfunction:point\ny\tinput.ts\t/^export default function point(x: number, y: number) {$/;\"\tz\tfunction:point\nnumberToString\tinput.ts\t/^function numberToString(a: number[]) {$/;\"\tf\na\tinput.ts\t/^function numberToString(a: number[]) {$/;\"\tz\tfunction:numberToString\nstringArray\tinput.ts\t/^  var stringArray = a.map(v => v.toString())$/;\"\tl\tfunction:numberToString\ng\tinput.ts\t/^function *g(): Iterable<string> {$/;\"\tG\ni\tinput.ts\t/^  for (var i = 0; i < 100; i++) {$/;\"\tl\tgenerator:g\nh\tinput.ts\t/^function *h(limit) {$/;\"\tG\nlimit\tinput.ts\t/^function *h(limit) {$/;\"\tz\tgenerator:h\ni\tinput.ts\t/^  for (var i = 0; i < limit; i++) {$/;\"\tl\tgenerator:h\nfn\tinput.ts\t/^async function fn(): Promise<number> {  $/;\"\tf\ni\tinput.ts\t/^  var i = await p \\/\\/ suspend execution until 'p' is settled. 'i' has type \"number\"  $/;\"\tl\tfunction:fn\nisCat\tinput.ts\t/^function isCat(a: Animal): a is Cat {$/;\"\tf\na\tinput.ts\t/^function isCat(a: Animal): a is Cat {$/;\"\tz\tfunction:isCat\nfoo\tinput.ts\t/^var foo = function() {$/;\"\tv\nfoo2\tinput.ts\t/^var foo2 = () => {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function-white.d/input.ts",
    "content": "function point(x: number, y: number): Point {\n  return { x: x, y: y }\n}\n\nexport function equals(p1: Point, p2: Point) {\n  return p1.x == p2.x && p1.y == p2.y\n}\n\nexport function message(s: string) {\n  console.log(s)\n}\n\nexport default function point(x: number, y: number) {\n  return { x, y }\n}\n\nfunction numberToString(a: number[]) {\n  var stringArray = a.map(v => v.toString())\n  return stringArray\n}\n\nfunction *g(): Iterable<string> {\n  for (var i = 0; i < 100; i++) {\n    yield \"\" // string is assignable to string\n  }\n  yield * otherStringGenerator() // otherStringGenerator must be iterable and element type assignable to string\n}\n\nfunction *h(limit) {\n  for (var i = 0; i < limit; i++) {\n    yield i\n  }\n}\n\nasync function fn(): Promise<number> {  \n  var i = await p // suspend execution until 'p' is settled. 'i' has type \"number\"  \n  return 1 + i\n}\n\nfunction isCat(a: Animal): a is Cat {\n  return a.name === 'kitty'\n}\n\nvar foo = function() {\n  console.log()\n}\n\nvar foo2 = () => {\n  console.log()\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function.d/expected.tags",
    "content": "point\tinput.ts\t/^function point(x: number, y: number): Point {$/;\"\tf\nx\tinput.ts\t/^function point(x: number, y: number): Point {$/;\"\tz\tfunction:point\ny\tinput.ts\t/^function point(x: number, y: number): Point {$/;\"\tz\tfunction:point\nequals\tinput.ts\t/^export function equals(p1: Point, p2: Point) {$/;\"\tf\np1\tinput.ts\t/^export function equals(p1: Point, p2: Point) {$/;\"\tz\tfunction:equals\np2\tinput.ts\t/^export function equals(p1: Point, p2: Point) {$/;\"\tz\tfunction:equals\nmessage\tinput.ts\t/^export function message(s: string) {$/;\"\tf\ns\tinput.ts\t/^export function message(s: string) {$/;\"\tz\tfunction:message\npoint\tinput.ts\t/^export default function point(x: number, y: number) {$/;\"\tf\nx\tinput.ts\t/^export default function point(x: number, y: number) {$/;\"\tz\tfunction:point\ny\tinput.ts\t/^export default function point(x: number, y: number) {$/;\"\tz\tfunction:point\nnumberToString\tinput.ts\t/^function numberToString(a: number[]) {$/;\"\tf\na\tinput.ts\t/^function numberToString(a: number[]) {$/;\"\tz\tfunction:numberToString\nstringArray\tinput.ts\t/^  var stringArray = a.map(v => v.toString());$/;\"\tl\tfunction:numberToString\ng\tinput.ts\t/^function *g(): Iterable<string> {$/;\"\tG\ni\tinput.ts\t/^  for (var i = 0; i < 100; i++) {$/;\"\tl\tgenerator:g\nh\tinput.ts\t/^function *h(limit) {$/;\"\tG\nlimit\tinput.ts\t/^function *h(limit) {$/;\"\tz\tgenerator:h\ni\tinput.ts\t/^  for (var i = 0; i < limit; i++) {$/;\"\tl\tgenerator:h\nfn\tinput.ts\t/^async function fn(): Promise<number> {  $/;\"\tf\ni\tinput.ts\t/^  var i = await p; \\/\\/ suspend execution until 'p' is settled. 'i' has type \"number\"  $/;\"\tl\tfunction:fn\nisCat\tinput.ts\t/^function isCat(a: Animal): a is Cat {$/;\"\tf\na\tinput.ts\t/^function isCat(a: Animal): a is Cat {$/;\"\tz\tfunction:isCat\nfoo\tinput.ts\t/^var foo = function() {$/;\"\tv\nfoo2\tinput.ts\t/^var foo2 = () => {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-function.d/input.ts",
    "content": "function point(x: number, y: number): Point {\n  return { x: x, y: y };\n}\n\nexport function equals(p1: Point, p2: Point) {\n  return p1.x == p2.x && p1.y == p2.y;\n}\n\nexport function message(s: string) {\n  console.log(s);\n}\n\nexport default function point(x: number, y: number) {\n  return { x, y };\n}\n\nfunction numberToString(a: number[]) {\n  var stringArray = a.map(v => v.toString());\n  return stringArray;\n}\n\nfunction *g(): Iterable<string> {\n  for (var i = 0; i < 100; i++) {\n    yield \"\"; // string is assignable to string\n  }\n  yield * otherStringGenerator(); // otherStringGenerator must be iterable and element type assignable to string\n}\n\nfunction *h(limit) {\n  for (var i = 0; i < limit; i++) {\n    yield i;\n  }\n}\n\nasync function fn(): Promise<number> {  \n  var i = await p; // suspend execution until 'p' is settled. 'i' has type \"number\"  \n  return 1 + i;  \n}\n\nfunction isCat(a: Animal): a is Cat {\n  return a.name === 'kitty';\n}\n\nvar foo = function() {\n  console.log();\n};\n\nvar foo2 = () => {\n  console.log();\n};\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-generators.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-generators.d/expected.tags",
    "content": "Rectangle\tinput.ts\t/^class Rectangle {$/;\"\tc\nheight\tinput.ts\t/^  height: number;$/;\"\tp\tclass:Rectangle\nwidth\tinput.ts\t/^  width: number;$/;\"\tp\tclass:Rectangle\nconstructor\tinput.ts\t/^  constructor(height, width) {$/;\"\tm\tclass:Rectangle\narea\tinput.ts\t/^  get area() {$/;\"\tm\tclass:Rectangle\ncalcArea\tinput.ts\t/^  calcArea() {$/;\"\tm\tclass:Rectangle\ngetSides\tinput.ts\t/^  *getSides() {$/;\"\tG\tclass:Rectangle\nidMaker\tinput.ts\t/^function* idMaker() {$/;\"\tG\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-generators.d/input.ts",
    "content": "// Taken from MDN\n// ==> Rectangle.js <==\nclass Rectangle {\n  height: number;\n  width: number;\n  constructor(height, width) {\n    this.height = height;\n    this.width = width;\n  }\n  // Getter\n  get area() {\n    return this.calcArea();\n  }\n  // Method\n  calcArea() {\n    return this.height * this.width;\n  }\n  *getSides() {\n    yield this.height;\n    yield this.width;\n    yield this.height;\n    yield this.width;\n  }\n}\n\n// ==> idMaker.js <==\nfunction* idMaker() {\n  let index = 0;\n  while (true) {\n    yield index++;\n  }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-generators.d/validator",
    "content": "tsc-es2015\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-interface-white.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-interface-white.d/expected.tags",
    "content": "Mover\tinput.ts\t/^interface Mover {$/;\"\ti\nmove\tinput.ts\t/^  move(): void$/;\"\tm\tinterface:Mover\ngetStatus\tinput.ts\t/^  getStatus(): { speed: number }$/;\"\tm\tinterface:Mover\nShaker\tinput.ts\t/^interface Shaker {$/;\"\ti\nshake\tinput.ts\t/^  shake(): void$/;\"\tm\tinterface:Shaker\ngetStatus\tinput.ts\t/^  getStatus(): { frequency: number }$/;\"\tm\tinterface:Shaker\nMoverShaker\tinput.ts\t/^interface MoverShaker extends Mover, Shaker {$/;\"\ti\ngetStatus\tinput.ts\t/^  getStatus(\\/*)*\\/): { speed: number; frequency: number }$/;\"\tm\tinterface:MoverShaker\ngetSomething\tinput.ts\t/^  getSomething(): \\/* } *\\/ void$/;\"\tm\tinterface:MoverShaker\ngetSomethingSophisticated\tinput.ts\t/^  getSomethingSophisticated()\\/*$/;\"\tm\tinterface:MoverShaker\ngetTpl\tinput.ts\t/^  getTpl<T>(): Promise<T>$/;\"\tm\tinterface:MoverShaker\nSimpleRecord\tinput.ts\t/^interface SimpleRecord {$/;\"\ti\npropertyA\tinput.ts\t/^  propertyA: number$/;\"\tp\tinterface:SimpleRecord\npropertyB\tinput.ts\t/^  propertyB: string$/;\"\tp\tinterface:SimpleRecord\npropertyC\tinput.ts\t/^  readonly propertyC: []$/;\"\tp\tinterface:SimpleRecord\nwithoutType\tinput.ts\t/^  withoutType?$/;\"\tp\tinterface:SimpleRecord\nDocument\tinput.ts\t/^interface Document {$/;\"\ti\ncreateElement\tinput.ts\t/^  createElement(tagName: \"div\"): HTMLDivElement$/;\"\tm\tinterface:Document\ncreateElement\tinput.ts\t/^  createElement(tagName: \"span\"): HTMLSpanElement$/;\"\tm\tinterface:Document\ncreateElement\tinput.ts\t/^  createElement(tagName: \"canvas\"): HTMLCanvasElement$/;\"\tm\tinterface:Document\ncreateElement\tinput.ts\t/^  createElement(tagName: string): HTMLElement$/;\"\tm\tinterface:Document\nCompilerOptions\tinput.ts\t/^interface CompilerOptions {$/;\"\ti\nstrict\tinput.ts\t/^  strict?: boolean$/;\"\tp\tinterface:CompilerOptions\nsourcePath\tinput.ts\t/^  sourcePath?: string$/;\"\tp\tinterface:CompilerOptions\ntargetPath\tinput.ts\t/^  targetPath?: string$/;\"\tp\tinterface:CompilerOptions\nList\tinput.ts\t/^interface List<T> {$/;\"\ti\ndata\tinput.ts\t/^  data: T$/;\"\tp\tinterface:List\nnext\tinput.ts\t/^  next: List<T>$/;\"\tp\tinterface:List\nowner\tinput.ts\t/^  owner: List<List<T>>$/;\"\tp\tinterface:List\nJQuery\tinput.ts\t/^interface JQuery {$/;\"\ti\ntext\tinput.ts\t/^  text(content: string)$/;\"\tm\tinterface:JQuery\nJQueryStatic\tinput.ts\t/^interface JQueryStatic {$/;\"\ti\nget\tinput.ts\t/^  get(url: string, callback: (data: string) => any)$/;\"\tm\tinterface:JQueryStatic\nArray\tinput.ts\t/^interface Array<T> {$/;\"\ti\nlength\tinput.ts\t/^  length: number$/;\"\tp\tinterface:Array\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-interface-white.d/input.ts",
    "content": "interface Mover {\n  move(): void\n  getStatus(): { speed: number }\n}\n\ninterface Shaker {\n  shake(): void\n  getStatus(): { frequency: number }\n}\n\ninterface MoverShaker extends Mover, Shaker {\n  getStatus(/*)*/): { speed: number; frequency: number }\n  //somethingCommentedOut(): string\n  getSomething(): /* } */ void\n  getSomethingSophisticated()/*\n    comment\n    block\n    */: void\n\n  getTpl<T>(): Promise<T>\n}\n\ninterface SimpleRecord {\n  propertyA: number\n  propertyB: string\n  readonly propertyC: []\n  withoutType?\n}\n\ninterface Document {\n  createElement(tagName: \"div\"): HTMLDivElement\n  createElement(tagName: \"span\"): HTMLSpanElement\n  createElement(tagName: \"canvas\"): HTMLCanvasElement\n  createElement(tagName: string): HTMLElement\n}\n\ninterface CompilerOptions {\n  strict?: boolean\n  sourcePath?: string\n  targetPath?: string\n}\n\ninterface List<T> {\n  data: T\n  next: List<T>\n  owner: List<List<T>>\n}\n\ninterface JQuery {\n  text(content: string)\n}\n\ninterface JQueryStatic {\n  get(url: string, callback: (data: string) => any)\n  (query: string): JQuery\n}\n\ninterface Array<T> {\n  length: number\n  [x: number]: T\n  // Other members\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-interface.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-interface.d/expected.tags",
    "content": "Mover\tinput.ts\t/^interface Mover {$/;\"\ti\nmove\tinput.ts\t/^  move(): void;$/;\"\tm\tinterface:Mover\ngetStatus\tinput.ts\t/^  getStatus(): { speed: number; };$/;\"\tm\tinterface:Mover\nShaker\tinput.ts\t/^interface Shaker {$/;\"\ti\nshake\tinput.ts\t/^  shake(): void;$/;\"\tm\tinterface:Shaker\ngetStatus\tinput.ts\t/^  getStatus(): { frequency: number; };$/;\"\tm\tinterface:Shaker\nMoverShaker\tinput.ts\t/^interface MoverShaker extends Mover, Shaker {$/;\"\ti\ngetStatus\tinput.ts\t/^  getStatus(\\/*)*\\/): { speed: number; frequency: number; };$/;\"\tm\tinterface:MoverShaker\ngetSomething\tinput.ts\t/^  getSomething(): \\/* } *\\/ void;$/;\"\tm\tinterface:MoverShaker\ngetSomethingSophisticated\tinput.ts\t/^  getSomethingSophisticated()\\/*$/;\"\tm\tinterface:MoverShaker\ngetTpl\tinput.ts\t/^  getTpl<T>(): Promise<T>;$/;\"\tm\tinterface:MoverShaker\nSimpleRecord\tinput.ts\t/^interface SimpleRecord {$/;\"\ti\npropertyA\tinput.ts\t/^  propertyA: number;$/;\"\tp\tinterface:SimpleRecord\npropertyB\tinput.ts\t/^  propertyB: string;$/;\"\tp\tinterface:SimpleRecord\npropertyC\tinput.ts\t/^  readonly propertyC: [];$/;\"\tp\tinterface:SimpleRecord\nwithoutType\tinput.ts\t/^  withoutType?;$/;\"\tp\tinterface:SimpleRecord\nDocument\tinput.ts\t/^interface Document {$/;\"\ti\ncreateElement\tinput.ts\t/^  createElement(tagName: \"div\"): HTMLDivElement;$/;\"\tm\tinterface:Document\ncreateElement\tinput.ts\t/^  createElement(tagName: \"span\"): HTMLSpanElement;$/;\"\tm\tinterface:Document\ncreateElement\tinput.ts\t/^  createElement(tagName: \"canvas\"): HTMLCanvasElement;$/;\"\tm\tinterface:Document\ncreateElement\tinput.ts\t/^  createElement(tagName: string): HTMLElement;$/;\"\tm\tinterface:Document\nCompilerOptions\tinput.ts\t/^interface CompilerOptions {$/;\"\ti\nstrict\tinput.ts\t/^  strict?: boolean;$/;\"\tp\tinterface:CompilerOptions\nsourcePath\tinput.ts\t/^  sourcePath?: string;$/;\"\tp\tinterface:CompilerOptions\ntargetPath\tinput.ts\t/^  targetPath?: string;$/;\"\tp\tinterface:CompilerOptions\nList\tinput.ts\t/^interface List<T> {$/;\"\ti\ndata\tinput.ts\t/^  data: T;$/;\"\tp\tinterface:List\nnext\tinput.ts\t/^  next: List<T>;$/;\"\tp\tinterface:List\nowner\tinput.ts\t/^  owner: List<List<T>>;$/;\"\tp\tinterface:List\nJQuery\tinput.ts\t/^interface JQuery {$/;\"\ti\ntext\tinput.ts\t/^  text(content: string);$/;\"\tm\tinterface:JQuery\nJQueryStatic\tinput.ts\t/^interface JQueryStatic {$/;\"\ti\nget\tinput.ts\t/^  get(url: string, callback: (data: string) => any);$/;\"\tm\tinterface:JQueryStatic\nArray\tinput.ts\t/^interface Array<T> {$/;\"\ti\nlength\tinput.ts\t/^  length: number;$/;\"\tp\tinterface:Array\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-interface.d/input.ts",
    "content": "interface Mover {\n  move(): void;\n  getStatus(): { speed: number; };\n}\n\ninterface Shaker {\n  shake(): void;\n  getStatus(): { frequency: number; };\n}\n\ninterface MoverShaker extends Mover, Shaker {\n  getStatus(/*)*/): { speed: number; frequency: number; };\n  //somethingCommentedOut(): string;\n  getSomething(): /* } */ void;\n  getSomethingSophisticated()/*\n    comment\n    block\n    */: void;\n\n  getTpl<T>(): Promise<T>;\n}\n\ninterface SimpleRecord {\n  propertyA: number;\n  propertyB: string;\n  readonly propertyC: [];\n  withoutType?;\n}\n\ninterface Document {\n  createElement(tagName: \"div\"): HTMLDivElement;\n  createElement(tagName: \"span\"): HTMLSpanElement;\n  createElement(tagName: \"canvas\"): HTMLCanvasElement;\n  createElement(tagName: string): HTMLElement;\n}\n\ninterface CompilerOptions {\n  strict?: boolean;\n  sourcePath?: string;\n  targetPath?: string;\n}\n\ninterface List<T> {\n  data: T;\n  next: List<T>;\n  owner: List<List<T>>;\n}\n\ninterface JQuery {\n  text(content: string);\n}\n\ninterface JQueryStatic {\n  get(url: string, callback: (data: string) => any);\n  (query: string): JQuery;\n}\n\ninterface Array<T> {\n  length: number;\n  [x: number]: T;\n  // Other members\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespace-with-fq-name-white.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespace-with-fq-name-white.d/expected.tags",
    "content": "ctags.config\tinput.ts\t/^namespace ctags.config {$/;\"\tn\nversion\tinput.ts\t/^    export const version = \"6.0\"$/;\"\tC\tnamespace:ctags.config\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespace-with-fq-name-white.d/input.ts",
    "content": "namespace ctags.config {\n    export const version = \"6.0\"\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespace-with-fq-name.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespace-with-fq-name.d/expected.tags",
    "content": "ctags.config\tinput.ts\t/^namespace ctags.config {$/;\"\tn\nversion\tinput.ts\t/^    export const version = \"6.0\";$/;\"\tC\tnamespace:ctags.config\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespace-with-fq-name.d/input.ts",
    "content": "namespace ctags.config {\n    export const version = \"6.0\";\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespaces-white.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespaces-white.d/expected.tags",
    "content": "Validation\tinput.ts\t/^namespace Validation {$/;\"\tn\nStringValidator\tinput.ts\t/^    export interface StringValidator {$/;\"\ti\tnamespace:Validation\nisAcceptable\tinput.ts\t/^        isAcceptable(s: string): boolean$/;\"\tm\tinterface:Validation.StringValidator\nlettersRegexp\tinput.ts\t/^    const lettersRegexp = \\/^[A-Za-z]+$\\/$/;\"\tC\tnamespace:Validation\nnumberRegexp\tinput.ts\t/^    const numberRegexp = \\/^[0-9]+$\\/$/;\"\tC\tnamespace:Validation\nLettersOnlyValidator\tinput.ts\t/^    export class LettersOnlyValidator implements StringValidator {$/;\"\tc\tnamespace:Validation\nisAcceptable\tinput.ts\t/^        isAcceptable(s: string) {$/;\"\tm\tclass:Validation.LettersOnlyValidator\ns\tinput.ts\t/^        isAcceptable(s: string) {$/;\"\tz\tmethod:Validation.LettersOnlyValidator.isAcceptable\nZipCodeValidator\tinput.ts\t/^    export class ZipCodeValidator implements StringValidator {$/;\"\tc\tnamespace:Validation\nisAcceptable\tinput.ts\t/^        isAcceptable(s: string) {$/;\"\tm\tclass:Validation.ZipCodeValidator\ns\tinput.ts\t/^        isAcceptable(s: string) {$/;\"\tz\tmethod:Validation.ZipCodeValidator.isAcceptable\nstrings\tinput.ts\t/^let strings = [\"Hello\", \"98052\", \"101\"]$/;\"\tv\nvalidators\tinput.ts\t/^let validators: { [s: string]: Validation.StringValidator; } = {}$/;\"\tv\ns\tinput.ts\t/^for (let s of strings) {$/;\"\tv\nname\tinput.ts\t/^    for (let name in validators) {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespaces-white.d/input.ts",
    "content": "namespace Validation {\n    export interface StringValidator {\n        isAcceptable(s: string): boolean\n    }\n\n    const lettersRegexp = /^[A-Za-z]+$/\n    const numberRegexp = /^[0-9]+$/\n\n    export class LettersOnlyValidator implements StringValidator {\n        isAcceptable(s: string) {\n            return lettersRegexp.test(s)\n        }\n    }\n\n    export class ZipCodeValidator implements StringValidator {\n        isAcceptable(s: string) {\n            return s.length === 5 && numberRegexp.test(s)\n        }\n    }\n}\n\n// Some samples to try\nlet strings = [\"Hello\", \"98052\", \"101\"]\n\n// Validators to use\nlet validators: { [s: string]: Validation.StringValidator; } = {}\nvalidators[\"ZIP code\"] = new Validation.ZipCodeValidator()\nvalidators[\"Letters only\"] = new Validation.LettersOnlyValidator()\n\n// Show whether each string passed each validator\nfor (let s of strings) {\n    for (let name in validators) {\n        console.log(`\"${ s }\" - ${ validators[name].isAcceptable(s) ? \"matches\" : \"does not match\" } ${ name }`)\n    }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespaces.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespaces.d/expected.tags",
    "content": "Validation\tinput.ts\t/^namespace Validation {$/;\"\tn\nStringValidator\tinput.ts\t/^    export interface StringValidator {$/;\"\ti\tnamespace:Validation\nisAcceptable\tinput.ts\t/^        isAcceptable(s: string): boolean;$/;\"\tm\tinterface:Validation.StringValidator\nlettersRegexp\tinput.ts\t/^    const lettersRegexp = \\/^[A-Za-z]+$\\/;$/;\"\tC\tnamespace:Validation\nnumberRegexp\tinput.ts\t/^    const numberRegexp = \\/^[0-9]+$\\/;$/;\"\tC\tnamespace:Validation\nLettersOnlyValidator\tinput.ts\t/^    export class LettersOnlyValidator implements StringValidator {$/;\"\tc\tnamespace:Validation\nisAcceptable\tinput.ts\t/^        isAcceptable(s: string) {$/;\"\tm\tclass:Validation.LettersOnlyValidator\ns\tinput.ts\t/^        isAcceptable(s: string) {$/;\"\tz\tmethod:Validation.LettersOnlyValidator.isAcceptable\nZipCodeValidator\tinput.ts\t/^    export class ZipCodeValidator implements StringValidator {$/;\"\tc\tnamespace:Validation\nisAcceptable\tinput.ts\t/^        isAcceptable(s: string) {$/;\"\tm\tclass:Validation.ZipCodeValidator\ns\tinput.ts\t/^        isAcceptable(s: string) {$/;\"\tz\tmethod:Validation.ZipCodeValidator.isAcceptable\nstrings\tinput.ts\t/^let strings = [\"Hello\", \"98052\", \"101\"];$/;\"\tv\nvalidators\tinput.ts\t/^let validators: { [s: string]: Validation.StringValidator; } = {};$/;\"\tv\ns\tinput.ts\t/^for (let s of strings) {$/;\"\tv\nname\tinput.ts\t/^    for (let name in validators) {$/;\"\tv\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-namespaces.d/input.ts",
    "content": "namespace Validation {\n    export interface StringValidator {\n        isAcceptable(s: string): boolean;\n    }\n\n    const lettersRegexp = /^[A-Za-z]+$/;\n    const numberRegexp = /^[0-9]+$/;\n\n    export class LettersOnlyValidator implements StringValidator {\n        isAcceptable(s: string) {\n            return lettersRegexp.test(s);\n        }\n    }\n\n    export class ZipCodeValidator implements StringValidator {\n        isAcceptable(s: string) {\n            return s.length === 5 && numberRegexp.test(s);\n        }\n    }\n}\n\n// Some samples to try\nlet strings = [\"Hello\", \"98052\", \"101\"];\n\n// Validators to use\nlet validators: { [s: string]: Validation.StringValidator; } = {};\nvalidators[\"ZIP code\"] = new Validation.ZipCodeValidator();\nvalidators[\"Letters only\"] = new Validation.LettersOnlyValidator();\n\n// Show whether each string passed each validator\nfor (let s of strings) {\n    for (let name in validators) {\n        console.log(`\"${ s }\" - ${ validators[name].isAcceptable(s) ? \"matches\" : \"does not match\" } ${ name }`);\n    }\n}\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-type-white.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-type-white.d/expected.tags",
    "content": "MyString\tinput.ts\t/^type MyString = \"mystring\"$/;\"\ta\nMyUnion\tinput.ts\t/^type MyUnion = MyString | \"other\" | 99$/;\"\ta\nMyExportedUnion\tinput.ts\t/^export type MyExportedUnion = MyUnion | \"default\" \\/\\/$/;\"\ta\nStringOrNumber\tinput.ts\t/^type StringOrNumber = string | number$/;\"\ta\nText\tinput.ts\t/^type Text = string | { text: string }$/;\"\ta\nNameLookup\tinput.ts\t/^type NameLookup = Dictionary<string, Person>$/;\"\ta\nObjectStatics\tinput.ts\t/^type ObjectStatics = typeof Object$/;\"\ta\nCallback\tinput.ts\t/^type Callback<T> = (data: T) => void$/;\"\ta\nPair\tinput.ts\t/^type Pair<T> = [T, T]$/;\"\ta\nCoordinates\tinput.ts\t/^type Coordinates = Pair<number>$/;\"\ta\nTree\tinput.ts\t/^type Tree<T> = T | { left: Tree<T>, right: Tree<T> }$/;\"\ta\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-type-white.d/input.ts",
    "content": "type MyString = \"mystring\"\ntype MyUnion = MyString | \"other\" | 99\nexport type MyExportedUnion = MyUnion | \"default\" //\n\ntype StringOrNumber = string | number\ntype Text = string | { text: string }\ntype NameLookup = Dictionary<string, Person>\ntype ObjectStatics = typeof Object\ntype Callback<T> = (data: T) => void\ntype Pair<T> = [T, T]\ntype Coordinates = Pair<number>\ntype Tree<T> = T | { left: Tree<T>, right: Tree<T> }\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-type.d/args.ctags",
    "content": "--sort=no\n--kinds-typescript=*\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-type.d/expected.tags",
    "content": "MyString\tinput.ts\t/^type MyString = \"mystring\";$/;\"\ta\nMyUnion\tinput.ts\t/^type MyUnion = MyString | \"other\" | 99;$/;\"\ta\nMyExportedUnion\tinput.ts\t/^export type MyExportedUnion = MyUnion | \"default\" \\/\\/;$/;\"\ta\nStringOrNumber\tinput.ts\t/^type StringOrNumber = string | number;$/;\"\ta\nText\tinput.ts\t/^type Text = string | { text: string };$/;\"\ta\nNameLookup\tinput.ts\t/^type NameLookup = Dictionary<string, Person>;$/;\"\ta\nObjectStatics\tinput.ts\t/^type ObjectStatics = typeof Object;$/;\"\ta\nCallback\tinput.ts\t/^type Callback<T> = (data: T) => void;$/;\"\ta\nPair\tinput.ts\t/^type Pair<T> = [T, T];$/;\"\ta\nCoordinates\tinput.ts\t/^type Coordinates = Pair<number>;$/;\"\ta\nTree\tinput.ts\t/^type Tree<T> = T | { left: Tree<T>, right: Tree<T> };$/;\"\ta\n"
  },
  {
    "path": "Units/parser-typescript.r/ts-type.d/input.ts",
    "content": "type MyString = \"mystring\";\ntype MyUnion = MyString | \"other\" | 99;\nexport type MyExportedUnion = MyUnion | \"default\" //;\n;\ntype StringOrNumber = string | number;\ntype Text = string | { text: string };\ntype NameLookup = Dictionary<string, Person>;\ntype ObjectStatics = typeof Object;\ntype Callback<T> = (data: T) => void;\ntype Pair<T> = [T, T];\ntype Coordinates = Pair<number>;\ntype Tree<T> = T | { left: Tree<T>, right: Tree<T> };\n"
  },
  {
    "path": "Units/parser-typespec.r/simple-typespec.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-typespec.r/simple-typespec.d/expected.tags",
    "content": "Name.Space\tinput.tsp\t/^namespace Name.Space;$/;\"\tn\nInner\tinput.tsp\t/^namespace Inner {$/;\"\tn\tnamespace:Name.Space\nVersions\tinput.tsp\t/^  enum Versions {$/;\"\tg\tnamespace:Name.Space.Inner\nv2024_05_01_preview\tinput.tsp\t/^    v2024_05_01_preview: \"2024-05-01-preview\",$/;\"\te\tenum:Name.Space.Inner.Versions\nv2024_05_02_preview\tinput.tsp\t/^    v2024_05_02_preview,$/;\"\te\tenum:Name.Space.Inner.Versions\nOpA\tinput.tsp\t/^  op OpA<T extends TypeSpec.Reflection.Model> is OpB<$/;\"\to\tnamespace:Name.Space.Inner\nInterfaceA\tinput.tsp\t/^  interface InterfaceA extends InterfaceB {$/;\"\ti\tnamespace:Name.Space.Inner\nopA\tinput.tsp\t/^    opA is OpA<{$/;\"\tp\tinterface:Name.Space.Inner.InterfaceA\nopB\tinput.tsp\t/^    opB is OpB<$/;\"\tp\tinterface:Name.Space.Inner.InterfaceA\nUnionA\tinput.tsp\t/^  union UnionA {$/;\"\tu\tnamespace:Name.Space.Inner\nModelA\tinput.tsp\t/^model ModelA {$/;\"\tm\tnamespace:Name.Space\ncontentA\tinput.tsp\t/^  contentA: ModelB;$/;\"\tp\tmodel:Name.Space.ModelA\ncontentB\tinput.tsp\t/^  contentB?: boolean;$/;\"\tp\tmodel:Name.Space.ModelA\nModelB\tinput.tsp\t/^model ModelB extends ModelA {$/;\"\tm\tnamespace:Name.Space\nAliasA\tinput.tsp\t/^alias AliasA<$/;\"\ta\tnamespace:Name.Space\n"
  },
  {
    "path": "Units/parser-typespec.r/simple-typespec.d/input.tsp",
    "content": "import \"@typespec/http\";\nimport \"./common.tsp\";\n\nusing TypeSpec;\nusing TypeSpec.Rest;\n\n@armProviderNamespace\n@service(#{ title: \"Name.Space\" })\n@versioned(Versions)\n@armCommonTypesVersion(CommonTypes.Versions.v3)\nnamespace Name.Space;\n\nnamespace Inner {\n  @doc(\"API Versions\")\n  @added(a())\n  enum Versions {\n    @doc(\"May 01, 2024 Preview API Version\")\n    v2024_05_01_preview: \"2024-05-01-preview\",\n    v2024_05_02_preview,\n  }\n\n  @summary(\"Example operation summary for demonstration purposes.\")\n  @doc(\"\"\"\n    Example\n    multi-line\n    documentation.\n    \"\"\")\n  @returnsDoc(\"Example return documentation\")\n  @post\n  op OpA<T extends TypeSpec.Reflection.Model> is OpB<\n    T & ModelA,\n    ModelB<ModelA[]>\n  >;\n\n  // single line comment\n  interface InterfaceA extends InterfaceB {\n    opA is OpA<{\n      @doc(\"The format of the HTTP payload.\")\n      @header\n      contentType: \"application/json\";\n\n      @clientName(\"uri\", \"c\\\\sharp\")\n      @doc(\"Example URL parameter.\")\n      opB: url;\n    }>;\n\n    /**\n    * Example operation description\n    */\n    opB is OpB<\n      ModelA,\n      {\n        ...ModelB\n      }\n    >;\n  }\n\n  @doc(\"Example union type description.\")\n  union UnionA {\n    string,\n\n    @doc(\"Example option A description with some technical details that would be typical for this kind of documentation.\")\n    \"unionA\",\n\n    @doc(\"Example option B description with additional technical context that would be common in API documentation.\")\n    \"unionB\",\n  }\n}\n\n@doc(\"Example model description.\")\nmodel ModelA {\n  @doc(\"Example property description.\")\n  contentA: ModelB;\n\n  @removed(Versions.v1_2)\n  @doc(\"Example boolean property with typical documentation about its purpose and default behavior.\")\n  contentB?: boolean;\n\n  ...ModelX;\n}\n\n@doc(\"Example model description.\")\nmodel ModelB extends ModelA {\n  ...ModelX;\n}\n\n\nalias AliasA<\n  TParamA extends ModelX,\n  TParamB,\n  TParamC extends ModelX = {},\n  TError = Error\n> = ModelB<TParamA, TParamB, TParamC, TError>;\n"
  },
  {
    "path": "Units/parser-unknown.r/etags.d/expected.tags-e",
    "content": "\f\ninput.unknown,0\n"
  },
  {
    "path": "Units/parser-unknown.r/etags.d/input.unknown",
    "content": ""
  },
  {
    "path": "Units/parser-unknown.r/no-unknown-parser.d/args.ctags",
    "content": "--extras=+f\n--fields=+e\n"
  },
  {
    "path": "Units/parser-unknown.r/no-unknown-parser.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-unknown.r/no-unknown-parser.d/input.unknown",
    "content": ""
  },
  {
    "path": "Units/parser-unknown.r/unknown-parser-with-some-lines.d/args.ctags",
    "content": "--extras=+f\n--languages=+unknown\n--fields=+e\n\n"
  },
  {
    "path": "Units/parser-unknown.r/unknown-parser-with-some-lines.d/expected.tags",
    "content": "input.unknown\tinput.unknown\t1;\"\tF\tend:7\n"
  },
  {
    "path": "Units/parser-unknown.r/unknown-parser-with-some-lines.d/input.unknown",
    "content": "\n\n\n\n\n\n\n"
  },
  {
    "path": "Units/parser-unknown.r/unknown-parser.d/args.ctags",
    "content": "--extras=+f\n--languages=+unknown\n--fields=+e\n\n"
  },
  {
    "path": "Units/parser-unknown.r/unknown-parser.d/expected.tags",
    "content": "input.unknown\tinput.unknown\t1;\"\tF\n"
  },
  {
    "path": "Units/parser-unknown.r/unknown-parser.d/input.unknown",
    "content": ""
  },
  {
    "path": "Units/parser-v.r/helloworld.d/args.ctags",
    "content": "--fields=+ERSaenr\n"
  },
  {
    "path": "Units/parser-v.r/helloworld.d/expected.tags",
    "content": "main\tinput.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:3\n"
  },
  {
    "path": "Units/parser-v.r/helloworld.d/input.v",
    "content": "fn main() {\n    println(\"hello world\")\n}\n"
  },
  {
    "path": "Units/parser-v.r/torture.d/args.ctags",
    "content": "--fields=+ERSaenrl\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/torture.d/expected.tags",
    "content": "main\tinput.v\t/^fn main() {$/;\"\tf\tline:1\tlanguage:V\ttyperef:typename:\tsignature:()\troles:def\tend:17\na\tinput.v\t/^\ta := 1$/;\"\tv\tline:3\tlanguage:V\tfn:main\troles:def\nthismodule\tinput-1.v\t/^module thismodule$/;\"\tp\tline:1\tlanguage:V\troles:def\nthat\tinput-1.v\t/^import that.aaa$/;\"\tp\tline:3\tlanguage:V\troles:imported\textras:reference\naaa\tinput-1.v\t/^import that.aaa$/;\"\tp\tline:3\tlanguage:V\tmodule:that\troles:imported\textras:reference\nthat\tinput-1.v\t/^import that.bbb { Bbb }$/;\"\tp\tline:4\tlanguage:V\troles:imported\textras:reference\nbbb\tinput-1.v\t/^import that.bbb { Bbb }$/;\"\tp\tline:4\tlanguage:V\tmodule:that\troles:imported\textras:reference\nBbb\tinput-1.v\t/^import that.bbb { Bbb }$/;\"\tY\tline:4\tlanguage:V\tmodule:that.bbb\troles:imported\textras:reference\nFoo\tinput-1.v\t/^struct Foo {$/;\"\ts\tline:6\tlanguage:V\tmodule:thismodule\troles:def\tend:9\na\tinput-1.v\t/^\ta aaa.Aaa$/;\"\tm\tline:7\tlanguage:V\tstruct:thismodule.Foo\troles:def\nb\tinput-1.v\t/^\tb Bbb$/;\"\tm\tline:8\tlanguage:V\tstruct:thismodule.Foo\troles:def\nmain\tinput-1.v\t/^fn main() {$/;\"\tf\tline:11\tlanguage:V\tmodule:thismodule\ttyperef:typename:\tsignature:()\troles:def\tend:15\nfoo\tinput-1.v\t/^\tfoo := Foo{}$/;\"\tv\tline:12\tlanguage:V\tfn:thismodule.main\troles:def\n"
  },
  {
    "path": "Units/parser-v.r/torture.d/input-1.v",
    "content": "module thismodule\n\nimport that.aaa\nimport that.bbb { Bbb }\n\nstruct Foo {\n\ta aaa.Aaa\n\tb Bbb\n}\n\nfn main() {\n\tfoo := Foo{}\n\tfoo.a\n\tfoo.b\n}\n"
  },
  {
    "path": "Units/parser-v.r/torture.d/input.v",
    "content": "fn main() {\n\tassert sample_data['int'] or { 0 }.as_map()['0'] or { 0 }.int() == 1\n\ta := 1\n\tassert json.encode(StructType[string]{ val: '' }) == '{\"val\":\"\"}'\n\tassert json.map_from(StructType[StructType[string]]{StructType[string]{'3'}}).str() == '{\"val\":{\"val\":\"3\"}}'\n\tif include_newlines && s.text[s.pos] in json2.newlines {\n\t}\n\tif (s.pos - 1 >= 0 && s.text[s.pos - 1] != `\\\\`) && ch == `\"` {\n\t}\n\tif g.cur_fn != unsafe { nil } && g.cur_fn.generic_names.len > 0 {\n\t}\n\tfor (flags & ttf.tfkc_more_components) > 0 {\n\t\tres << 'foo' + foo.bar.map(it.str()).join('|')\n\t\tres << 'foo' + foo.bar.chan(it.str()).join('|')\n\t}\n    e.run_func(e.mods['main']['main'] or { ast.FnDecl{} } as ast.FnDecl, ...args)\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-const.d/args.ctags",
    "content": "--fields=+ERSaenr\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-const.d/expected.tags",
    "content": "a\tinput.v\t/^    a = 20$/;\"\tc\tline:3\troles:def\nb\tinput.v\t/^    b = 999999999$/;\"\tc\tline:4\troles:def\nc\tinput.v\t/^    c = 45.6$/;\"\tc\tline:5\troles:def\nd\tinput.v\t/^    d = 3.14$/;\"\tc\tline:6\troles:def\ne\tinput.v\t/^    e = 1_000_000$/;\"\tc\tline:7\troles:def\nf\tinput.v\t/^    f = 3_122.55$/;\"\tc\tline:8\troles:def\ng\tinput.v\t/^    g = \"hi\"$/;\"\tc\tline:10\troles:def\nh\tinput.v\t/^    h = \"hi \\\\\"tim\\\\\"\"$/;\"\tc\tline:11\troles:def\ni\tinput.v\t/^    i = '\\\\u2605'$/;\"\tc\tline:12\troles:def\nj\tinput.v\t/^    j = '\\\\xe2\\\\x98\\\\x85'$/;\"\tc\tline:13\troles:def\nk\tinput.v\t/^    k = `x`$/;\"\tc\tline:14\troles:def\nl\tinput.v\t/^    l = 0b1111_0000_1010$/;\"\tc\tline:16\troles:def\nm\tinput.v\t/^    m = -0b1111_0000_1010$/;\"\tc\tline:17\troles:def\nn\tinput.v\t/^    n = 0x00$/;\"\tc\tline:18\troles:def\no\tinput.v\t/^    o = 0xabcdef$/;\"\tc\tline:19\troles:def\np\tinput.v\t/^    p = 0xF_F$/;\"\tc\tline:20\troles:def\nq\tinput.v\t/^    q = 0o173$/;\"\tc\tline:21\troles:def\nr\tinput.v\t/^    r = 0o17_3$/;\"\tc\tline:22\troles:def\ns\tinput.v\t/^    s = 'Hello World 👋'$/;\"\tc\tline:24\troles:def\nt\tinput.v\t/^    t = 42e1$/;\"\tc\tline:26\troles:def\nu\tinput.v\t/^    u = 123e-2$/;\"\tc\tline:27\troles:def\nv\tinput.v\t/^    v = 456E+2$/;\"\tc\tline:28\troles:def\nx\tinput.v\t/^const x = 99$/;\"\tc\tline:31\troles:def\npi\tinput.v\t/^pub const pi = 3.14$/;\"\tc\tline:32\taccess:pub\troles:def\nnumbers\tinput.v\t/^    numbers = [1, 2, 3]$/;\"\tc\tline:35\troles:def\nred\tinput.v\t/^    red     = Color{$/;\"\tc\tline:36\troles:def\ngreen\tinput.v\t/^    green = &Colour{0, 255, 0}$/;\"\tc\tline:41\troles:def\nblue\tinput.v\t/^    blue = rgb(0, 0, 255)$/;\"\tc\tline:42\troles:def\ntest1\tinput.v\t/^    test1 = [$/;\"\tc\tline:43\troles:def\ntest2\tinput.v\t/^    test2 = test1 + 3$/;\"\tc\tline:47\troles:def\ntest3\tinput.v\t/^    test3 = 0$/;\"\tc\tline:48\troles:def\na\tinput.v\t/^    a = 9 + 3$/;\"\tc\tline:52\taccess:pub\troles:def\nb\tinput.v\t/^    b = a[3]$/;\"\tc\tline:53\taccess:pub\troles:def\nc\tinput.v\t/^    c = 0$/;\"\tc\tline:54\taccess:pub\troles:def\nd\tinput.v\t/^    d = r'hi'$/;\"\tc\tline:55\taccess:pub\troles:def\ne\tinput.v\t/^    e = r\"there\"$/;\"\tc\tline:56\taccess:pub\troles:def\nf\tinput.v\t/^    f = '\"'$/;\"\tc\tline:57\taccess:pub\troles:def\ng\tinput.v\t/^    g = \"'\"$/;\"\tc\tline:58\taccess:pub\troles:def\nh\tinput.v\t/^    h = '${\"'\"}'$/;\"\tc\tline:59\taccess:pub\troles:def\ni\tinput.v\t/^    i = '\\\\${'$/;\"\tc\tline:60\taccess:pub\troles:def\nj\tinput.v\t/^    j = '$'$/;\"\tc\tline:61\taccess:pub\troles:def\nz\tinput.v\t/^    z = 'done'$/;\"\tc\tline:62\taccess:pub\troles:def\na\tinput-1.v\t/^    a = x + -8$/;\"\tc\tline:2\troles:def\nb\tinput-1.v\t/^    b = x \\/ x$/;\"\tc\tline:3\troles:def\nc\tinput-1.v\t/^    c = x * x$/;\"\tc\tline:4\troles:def\nd\tinput-1.v\t/^    d = x - +8$/;\"\tc\tline:5\troles:def\ne\tinput-1.v\t/^    e = x | x & x && x || x$/;\"\tc\tline:6\troles:def\nf\tinput-1.v\t/^    f = !x | !!x$/;\"\tc\tline:7\troles:def\ng\tinput-1.v\t/^    g = ~x == ~~~~~~~~~~~~x != !!!!!!!x$/;\"\tc\tline:8\troles:def\nh\tinput-1.v\t/^    h = x ^ x ^ x$/;\"\tc\tline:9\troles:def\ni\tinput-1.v\t/^    i = x$/;\"\tc\tline:10\troles:def\n"
  },
  {
    "path": "Units/parser-v.r/v-const.d/input-1.v",
    "content": "const (\n    a = x + -8\n    b = x / x\n    c = x * x\n    d = x - +8\n    e = x | x & x && x || x\n    f = !x | !!x\n    g = ~x == ~~~~~~~~~~~~x != !!!!!!!x\n    h = x ^ x ^ x\n    i = x\n)\n"
  },
  {
    "path": "Units/parser-v.r/v-const.d/input.v",
    "content": "const (\n    // decimal\n    a = 20\n    b = 999999999\n    c = 45.6\n    d = 3.14\n    e = 1_000_000\n    f = 3_122.55\n    // strings\n    g = \"hi\"\n    h = \"hi \\\"tim\\\"\"\n    i = '\\u2605'\n    j = '\\xe2\\x98\\x85'\n    k = `x`\n    // other bases\n    l = 0b1111_0000_1010\n    m = -0b1111_0000_1010\n    n = 0x00\n    o = 0xabcdef\n    p = 0xF_F\n    q = 0o173\n    r = 0o17_3\n    // unicode\n    s = 'Hello World 👋'\n    // exp\n    t = 42e1\n    u = 123e-2\n    v = 456E+2\n)\n\nconst x = 99\npub const pi = 3.14\n\nconst (\n    numbers = [1, 2, 3]\n    red     = Color{\n        r: 255\n        g: 0\n        b: 0\n    }\n    green = &Colour{0, 255, 0}\n    blue = rgb(0, 0, 255)\n    test1 = [\n        Aaa{},\n        Bbb{3, 4},\n    ]\n    test2 = test1 + 3\n    test3 = 0\n)\n\npub const (\n    a = 9 + 3\n    b = a[3]\n    c = 0\n    d = r'hi'\n    e = r\"there\"\n    f = '\"'\n    g = \"'\"\n    h = '${\"'\"}'\n    i = '\\${'\n    j = '$'\n    z = 'done'\n)\n"
  },
  {
    "path": "Units/parser-v.r/v-enum.d/args.ctags",
    "content": "--fields=+ERSaenr\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-enum.d/expected.tags",
    "content": "Foo\tinput.v\t/^enum Foo {$/;\"\tg\tline:3\troles:def\tend:10\naaa\tinput.v\t/^    aaa = 5$/;\"\te\tline:4\tenum:Foo\troles:def\nbbb\tinput.v\t/^    bbb$/;\"\te\tline:5\tenum:Foo\troles:def\nccc\tinput.v\t/^    ccc$/;\"\te\tline:6\tenum:Foo\troles:def\n@fn\tinput.v\t/^    @fn$/;\"\te\tline:7\tenum:Foo\troles:def\n@struct\tinput.v\t/^    @struct$/;\"\te\tline:8\tenum:Foo\troles:def\nddd\tinput.v\t/^    ddd$/;\"\te\tline:9\tenum:Foo\troles:def\naaa\tinput-1.v\t/^module aaa$/;\"\tp\tline:1\troles:def\nFoo\tinput-1.v\t/^enum Foo {$/;\"\tg\tline:3\tmodule:aaa\troles:def\tend:10\naaa\tinput-1.v\t/^    aaa = 5$/;\"\te\tline:4\tenum:aaa.Foo\troles:def\nbbb\tinput-1.v\t/^    bbb$/;\"\te\tline:5\tenum:aaa.Foo\troles:def\nccc\tinput-1.v\t/^    ccc = C.foo$/;\"\te\tline:6\tenum:aaa.Foo\troles:def\n@fn\tinput-1.v\t/^    @fn$/;\"\te\tline:7\tenum:aaa.Foo\troles:def\n@struct\tinput-1.v\t/^    @struct [attr]$/;\"\te\tline:8\tenum:aaa.Foo\troles:def\nddd\tinput-1.v\t/^    ddd = 999  @[attr]$/;\"\te\tline:9\tenum:aaa.Foo\troles:def\n"
  },
  {
    "path": "Units/parser-v.r/v-enum.d/input-1.v",
    "content": "module aaa\n\nenum Foo {\n    aaa = 5\n    bbb\n    ccc = C.foo\n    @fn\n    @struct [attr]\n    ddd = 999  @[attr]\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-enum.d/input.v",
    "content": "//module aaa\n\nenum Foo {\n    aaa = 5\n    bbb\n    ccc\n    @fn\n    @struct\n    ddd\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-expr.d/args.ctags",
    "content": "--fields=+ERSaenr\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-expr.d/expected.tags",
    "content": "test_exprs\tinput.v\t/^fn test_exprs() {$/;\"\tf\tline:2\ttyperef:typename:\tsignature:()\troles:def\tend:89\na\tinput.v\t/^    a := 0$/;\"\tv\tline:3\tfn:test_exprs\troles:def\nb\tinput.v\t/^    b := 0$/;\"\tv\tline:5\tfn:test_exprs\troles:def\nc\tinput.v\t/^    c := 0$/;\"\tv\tline:7\tfn:test_exprs\troles:def\nd\tinput.v\t/^    d := 0$/;\"\tv\tline:9\tfn:test_exprs\troles:def\ne\tinput.v\t/^    e := 0$/;\"\tv\tline:11\tfn:test_exprs\troles:def\nf\tinput.v\t/^    f := 0$/;\"\tv\tline:13\tfn:test_exprs\troles:def\ng\tinput.v\t/^    g := 0$/;\"\tv\tline:15\tfn:test_exprs\troles:def\nh\tinput.v\t/^    h := 0$/;\"\tv\tline:18\tfn:test_exprs\troles:def\ni\tinput.v\t/^    i := 0$/;\"\tv\tline:20\tfn:test_exprs\troles:def\nj\tinput.v\t/^    j := 0$/;\"\tv\tline:22\tfn:test_exprs\troles:def\nk\tinput.v\t/^    k := 0$/;\"\tv\tline:24\tfn:test_exprs\troles:def\nl\tinput.v\t/^    l := 0$/;\"\tv\tline:26\tfn:test_exprs\troles:def\nm\tinput.v\t/^    m := 0$/;\"\tv\tline:28\tfn:test_exprs\troles:def\nn\tinput.v\t/^    n := 0$/;\"\tv\tline:30\tfn:test_exprs\troles:def\no\tinput.v\t/^    o := 0$/;\"\tv\tline:32\tfn:test_exprs\troles:def\np\tinput.v\t/^    p := 0$/;\"\tv\tline:34\tfn:test_exprs\troles:def\nq\tinput.v\t/^    q := 0$/;\"\tv\tline:36\tfn:test_exprs\troles:def\nr\tinput.v\t/^    r := 0$/;\"\tv\tline:38\tfn:test_exprs\troles:def\ns\tinput.v\t/^    s := 0$/;\"\tv\tline:40\tfn:test_exprs\troles:def\nt\tinput.v\t/^    t := 0$/;\"\tv\tline:43\tfn:test_exprs\troles:def\nu\tinput.v\t/^    u := 0$/;\"\tv\tline:45\tfn:test_exprs\troles:def\nv\tinput.v\t/^    v := 0$/;\"\tv\tline:47\tfn:test_exprs\troles:def\nw\tinput.v\t/^    w := 0$/;\"\tv\tline:49\tfn:test_exprs\troles:def\ny\tinput.v\t/^    y := 0$/;\"\tv\tline:51\tfn:test_exprs\troles:def\nz\tinput.v\t/^    z := 0$/;\"\tv\tline:53\tfn:test_exprs\troles:def\naa\tinput.v\t/^    aa := 0$/;\"\tv\tline:55\tfn:test_exprs\troles:def\nab\tinput.v\t/^    ab := 0$/;\"\tv\tline:58\tfn:test_exprs\troles:def\nac\tinput.v\t/^    ac := 0$/;\"\tv\tline:60\tfn:test_exprs\troles:def\nad\tinput.v\t/^    ad := 0$/;\"\tv\tline:62\tfn:test_exprs\troles:def\nae\tinput.v\t/^    ae := 0$/;\"\tv\tline:65\tfn:test_exprs\troles:def\naf\tinput.v\t/^    af := 0$/;\"\tv\tline:67\tfn:test_exprs\troles:def\nag\tinput.v\t/^    ag := 0$/;\"\tv\tline:69\tfn:test_exprs\troles:def\nah\tinput.v\t/^    ah := 0$/;\"\tv\tline:71\tfn:test_exprs\troles:def\nai\tinput.v\t/^    ai := 0$/;\"\tv\tline:73\tfn:test_exprs\troles:def\naj\tinput.v\t/^    aj := 0$/;\"\tv\tline:75\tfn:test_exprs\troles:def\nak\tinput.v\t/^    ak := 0$/;\"\tv\tline:78\tfn:test_exprs\troles:def\nal\tinput.v\t/^    al := 0$/;\"\tv\tline:80\tfn:test_exprs\troles:def\nam\tinput.v\t/^    am := 0$/;\"\tv\tline:82\tfn:test_exprs\troles:def\nan\tinput.v\t/^    an := 0$/;\"\tv\tline:84\tfn:test_exprs\troles:def\nao\tinput.v\t/^    ao := 0$/;\"\tv\tline:86\tfn:test_exprs\troles:def\nap\tinput.v\t/^    ap := 0$/;\"\tv\tline:88\tfn:test_exprs\troles:def\ntest_exprs\tinput-1.v\t/^fn test_exprs() {$/;\"\tf\tline:2\ttyperef:typename:\tsignature:()\troles:def\tend:44\na\tinput-1.v\t/^    a := x + x + x$/;\"\tv\tline:3\tfn:test_exprs\troles:def\nb\tinput-1.v\t/^    b := x - x - x$/;\"\tv\tline:4\tfn:test_exprs\troles:def\nc\tinput-1.v\t/^    c := x * x * x$/;\"\tv\tline:5\tfn:test_exprs\troles:def\nd\tinput-1.v\t/^    d := x \\/ x \\/ x$/;\"\tv\tline:6\tfn:test_exprs\troles:def\ne\tinput-1.v\t/^    e := x % x % x$/;\"\tv\tline:7\tfn:test_exprs\troles:def\nf\tinput-1.v\t/^    f := x ^ x$/;\"\tv\tline:8\tfn:test_exprs\troles:def\ng\tinput-1.v\t/^    g := x += x$/;\"\tv\tline:10\tfn:test_exprs\troles:def\nh\tinput-1.v\t/^    h := x -= x$/;\"\tv\tline:11\tfn:test_exprs\troles:def\ni\tinput-1.v\t/^    i := x \\/= x$/;\"\tv\tline:12\tfn:test_exprs\troles:def\nj\tinput-1.v\t/^    j := x *= x$/;\"\tv\tline:13\tfn:test_exprs\troles:def\nk\tinput-1.v\t/^    k := x %= x$/;\"\tv\tline:14\tfn:test_exprs\troles:def\nl\tinput-1.v\t/^    l := x <<= x$/;\"\tv\tline:15\tfn:test_exprs\troles:def\nm\tinput-1.v\t/^    m := x >>= x$/;\"\tv\tline:16\tfn:test_exprs\troles:def\nn\tinput-1.v\t/^    n := x >>>= x$/;\"\tv\tline:17\tfn:test_exprs\troles:def\no\tinput-1.v\t/^    o := x &= x$/;\"\tv\tline:18\tfn:test_exprs\troles:def\np\tinput-1.v\t/^    p := x |= x$/;\"\tv\tline:19\tfn:test_exprs\troles:def\nq\tinput-1.v\t/^    q := x ^= x$/;\"\tv\tline:20\tfn:test_exprs\troles:def\nr\tinput-1.v\t/^    r := 0$/;\"\tv\tline:21\tfn:test_exprs\troles:def\ns\tinput-1.v\t/^    s := ~x$/;\"\tv\tline:23\tfn:test_exprs\troles:def\nt\tinput-1.v\t/^    t := x & x$/;\"\tv\tline:24\tfn:test_exprs\troles:def\nu\tinput-1.v\t/^    u := x | x$/;\"\tv\tline:25\tfn:test_exprs\troles:def\nv\tinput-1.v\t/^    v := x ^ x$/;\"\tv\tline:26\tfn:test_exprs\troles:def\nw\tinput-1.v\t/^    w := x << x$/;\"\tv\tline:27\tfn:test_exprs\troles:def\ny\tinput-1.v\t/^    y := x >> x$/;\"\tv\tline:28\tfn:test_exprs\troles:def\nz\tinput-1.v\t/^    z := x >>> x$/;\"\tv\tline:29\tfn:test_exprs\troles:def\naa\tinput-1.v\t/^    aa := !x$/;\"\tv\tline:31\tfn:test_exprs\troles:def\nab\tinput-1.v\t/^    ab := x || x$/;\"\tv\tline:32\tfn:test_exprs\troles:def\nac\tinput-1.v\t/^    ac := x && x$/;\"\tv\tline:33\tfn:test_exprs\troles:def\nad\tinput-1.v\t/^    ad := x == x$/;\"\tv\tline:35\tfn:test_exprs\troles:def\nae\tinput-1.v\t/^    ae := x != x$/;\"\tv\tline:36\tfn:test_exprs\troles:def\naf\tinput-1.v\t/^    af := x < x$/;\"\tv\tline:37\tfn:test_exprs\troles:def\nag\tinput-1.v\t/^    ag := x > x$/;\"\tv\tline:38\tfn:test_exprs\troles:def\nah\tinput-1.v\t/^    ah := x <= x$/;\"\tv\tline:39\tfn:test_exprs\troles:def\nai\tinput-1.v\t/^    ai := x >= x$/;\"\tv\tline:40\tfn:test_exprs\troles:def\naj\tinput-1.v\t/^    aj := x++ - 3$/;\"\tv\tline:42\tfn:test_exprs\troles:def\nak\tinput-1.v\t/^    ak := x-- + 3$/;\"\tv\tline:43\tfn:test_exprs\troles:def\nmain\tinput-2.v\t/^fn main () {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:11\na\tinput-2.v\t/^    a := 0$/;\"\tv\tline:2\tfn:main\troles:def\nb\tinput-2.v\t/^    mut b := 0$/;\"\tv\tline:3\tfn:main\taccess:mut\troles:def\nc\tinput-2.v\t/^    mut c, d := foo()$/;\"\tv\tline:4\tfn:main\taccess:mut\troles:def\nd\tinput-2.v\t/^    mut c, d := foo()$/;\"\tv\tline:4\tfn:main\troles:def\ne\tinput-2.v\t/^    e, mut f := foo()$/;\"\tv\tline:5\tfn:main\troles:def\nf\tinput-2.v\t/^    e, mut f := foo()$/;\"\tv\tline:5\tfn:main\taccess:mut\troles:def\ng\tinput-2.v\t/^    g, h, i, mut j, k := x, x, x, x, x$/;\"\tv\tline:8\tfn:main\troles:def\nh\tinput-2.v\t/^    g, h, i, mut j, k := x, x, x, x, x$/;\"\tv\tline:8\tfn:main\troles:def\ni\tinput-2.v\t/^    g, h, i, mut j, k := x, x, x, x, x$/;\"\tv\tline:8\tfn:main\troles:def\nj\tinput-2.v\t/^    g, h, i, mut j, k := x, x, x, x, x$/;\"\tv\tline:8\tfn:main\taccess:mut\troles:def\nk\tinput-2.v\t/^    g, h, i, mut j, k := x, x, x, x, x$/;\"\tv\tline:8\tfn:main\troles:def\nm\tinput-2.v\t/^    m := chan int{cap: 1}$/;\"\tv\tline:10\tfn:main\troles:def\nfoo\tinput-2.v\t/^fn foo(ch chan int) {$/;\"\tf\tline:13\ttyperef:typename:\tsignature:(ch chan int)\troles:def\tend:18\nn\tinput-2.v\t/^    n := <-ch or {$/;\"\tv\tline:15\tfn:foo\troles:def\n"
  },
  {
    "path": "Units/parser-v.r/v-expr.d/input-1.v",
    "content": "// not even consts!\nfn test_exprs() {\n    a := x + x + x\n    b := x - x - x\n    c := x * x * x\n    d := x / x / x\n    e := x % x % x\n    f := x ^ x\n    // assignment\n    g := x += x\n    h := x -= x\n    i := x /= x\n    j := x *= x\n    k := x %= x\n    l := x <<= x\n    m := x >>= x\n    n := x >>>= x\n    o := x &= x\n    p := x |= x\n    q := x ^= x\n    r := 0\n    // bit\n    s := ~x\n    t := x & x\n    u := x | x\n    v := x ^ x\n    w := x << x\n    y := x >> x\n    z := x >>> x\n    // logic\n    aa := !x\n    ab := x || x\n    ac := x && x\n    // comparison\n    ad := x == x\n    ae := x != x\n    af := x < x\n    ag := x > x\n    ah := x <= x\n    ai := x >= x\n    // unary\n    aj := x++ - 3\n    ak := x-- + 3\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-expr.d/input-2.v",
    "content": "fn main () {\n    a := 0\n    mut b := 0\n    mut c, d := foo()\n    e, mut f := foo()\n    x, x = foo()\n    x, x, x = a, b, c\n    g, h, i, mut j, k := x, x, x, x, x\n    l = unsafe{ nil }\n    m := chan int{cap: 1}\n}\n\nfn foo(ch chan int) {\n    ch <- 123.456\n    n := <-ch or {\n        println('channel has been closed')\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-expr.d/input.v",
    "content": "// not even consts!\nfn test_exprs() {\n    a := 0\n    x = x + x + x\n    b := 0\n    x = x - x - x\n    c := 0\n    x = x * x * x\n    d := 0\n    x = x / x / x\n    e := 0\n    x = x % x % x\n    f := 0\n    x = x ^ x\n    g := 0\n    // assignment\n    x += x\n    h := 0\n    x -= x\n    i := 0\n    x /= x\n    j := 0\n    x *= x\n    k := 0\n    x %= x\n    l := 0\n    x <<= x\n    m := 0\n    x >>= x\n    n := 0\n    x >>>= x\n    o := 0\n    x &= x\n    p := 0\n    x |= x\n    q := 0\n    x ^= x\n    r := 0\n\n    s := 0\n    // bit\n    x = ~x\n    t := 0\n    x = x & x\n    u := 0\n    x = x | x\n    v := 0\n    x = x ^ x\n    w := 0\n    x = x << x\n    y := 0\n    x = x >> x\n    z := 0\n    x = x >>> x\n    aa := 0\n    // logic\n    x = !x\n    ab := 0\n    x = x || x\n    ac := 0\n    x = x && x\n    ad := 0\n    // comparison\n    x = x == x\n    ae := 0\n    x = x != x\n    af := 0\n    x = x < x\n    ag := 0\n    x = x > x\n    ah := 0\n    x = x <= x\n    ai := 0\n    x = x >= x\n    aj := 0\n    // unary\n    x = x++ - 3\n    ak := 0\n    x = x-- + 3\n    al := 0\n    x = x in x\n    am := 0\n    x = x !in x\n    an := 0\n    x = x is X\n    ao := 0\n    x = x !is X\n    ap := 0\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-extern.d/args.ctags",
    "content": "--fields=+ERSaenrl\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-extern.d/expected.tags",
    "content": "C\tinput.v\t/^struct C.SYSTEM_INFO {$/;\"\tp\tline:1\tlanguage:V\troles:foreignlang\textras:reference\nSYSTEM_INFO\tinput.v\t/^struct C.SYSTEM_INFO {$/;\"\ts\tline:1\tlanguage:V\tmodule:C\troles:def\tend:2\nSYSTEM_INFO\tinput.v\t/^struct C.SYSTEM_INFO {$/;\"\ts\tline:1\tlanguage:C\troles:foreigndecl\textras:reference\nC\tinput.v\t/^fn C.foo(bar string) i64$/;\"\tp\tline:3\tlanguage:V\troles:foreignlang\textras:reference\nfoo\tinput.v\t/^fn C.foo(bar string) i64$/;\"\tf\tline:3\tlanguage:V\tmodule:C\ttyperef:typename:i64\tsignature:(bar string)\troles:def\nfoo\tinput.v\t/^fn C.foo(bar string) i64$/;\"\tf\tline:3\tlanguage:C\troles:foreigndecl\textras:reference\nJS\tinput.v\t/^fn JS.bar(baz string) int$/;\"\tp\tline:4\tlanguage:V\troles:foreignlang\textras:reference\nbar\tinput.v\t/^fn JS.bar(baz string) int$/;\"\tf\tline:4\tlanguage:V\tmodule:JS\ttyperef:typename:int\tsignature:(baz string)\troles:def\nbar\tinput.v\t/^fn JS.bar(baz string) int$/;\"\tf\tline:4\tlanguage:JavaScript\troles:foreigndecl\textras:reference\n"
  },
  {
    "path": "Units/parser-v.r/v-extern.d/input.v",
    "content": "struct C.SYSTEM_INFO {\n}\nfn C.foo(bar string) i64\nfn JS.bar(baz string) int\n"
  },
  {
    "path": "Units/parser-v.r/v-fn.d/args.ctags",
    "content": "--fields=+ERSaenr\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-fn.d/expected.tags",
    "content": "fn1\tinput.v\t/^fn fn1() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:2\nfn2\tinput.v\t/^fn fn2(a int) {$/;\"\tf\tline:4\ttyperef:typename:\tsignature:(a int)\troles:def\tend:5\nfn3\tinput.v\t/^fn fn3(a int, b string, c Foo) os.Signal {$/;\"\tf\tline:7\ttyperef:typename:os.Signal\tsignature:(a int, b string, c Foo)\troles:def\tend:8\nfn4\tinput.v\t/^fn fn4() ! {$/;\"\tf\tline:10\ttyperef:typename:!\tsignature:()\troles:def\tend:11\nfn5\tinput.v\t/^fn fn5() ?Test {$/;\"\tf\tline:13\ttyperef:typename:?Test\tsignature:()\troles:def\tend:14\nfn6\tinput.v\t/^fn fn6() (int, int) {$/;\"\tf\tline:16\ttyperef:typename:(int, int)\tsignature:()\troles:def\tend:23\nfn7\tinput.v\t/^    fn fn7() {$/;\"\tf\tline:18\tfn:fn6\ttyperef:typename:\tsignature:()\troles:def\tend:22\nfn8\tinput.v\t/^        fn fn8(a int, b string, c Foo) (!Test, int, Foo) {$/;\"\tf\tline:20\tfn:fn6.fn7\ttyperef:typename:(!Test, int, Foo)\tsignature:(a int, b string, c Foo)\troles:def\tend:21\nfnR1\tinput.v\t/^fn (s Foo) fnR1(a int) {$/;\"\tf\tline:27\ttyperef:typename:\tsignature:(s Foo)(a int)\troles:def\tend:28\ns\tinput.v\t/^fn (s Foo) fnR1(a int) {$/;\"\tR\tline:27\tfn:fnR1\troles:def\nfnR2\tinput.v\t/^fn (s *Foo) fnR2(a int, b string, c Foo) ?Foo {$/;\"\tf\tline:30\ttyperef:typename:?Foo\tsignature:(s *Foo)(a int, b string, c Foo)\troles:def\tend:31\ns\tinput.v\t/^fn (s *Foo) fnR2(a int, b string, c Foo) ?Foo {$/;\"\tR\tline:30\tfn:fnR2\troles:def\nmain\tinput.v\t/^fn main () {$/;\"\tf\tline:33\ttyperef:typename:\tsignature:()\troles:def\tend:48\nx\tinput.v\t/^    x := fn(a int, b int) int { return a + b }$/;\"\tv\tline:36\tfn:main\troles:def\ny\tinput.v\t/^    y := x(0, 0)$/;\"\tv\tline:37\tfn:main\troles:def\nz\tinput.v\t/^    z := fn() {$/;\"\tv\tline:38\tfn:main\troles:def\na\tinput.v\t/^        a := 0$/;\"\tv\tline:41\troles:def\nb\tinput.v\t/^        b := 0$/;\"\tv\tline:42\troles:def\nadd\tinput.v\t/^        add :=$/;\"\tv\tline:43\troles:def\nxyz\tinput-1.v\t/^module xyz$/;\"\tp\tline:1\troles:def\nyesnow\tinput-1.v\t/^fn (mut s Foo) yesnow() ! {$/;\"\tf\tline:3\tmodule:xyz\ttyperef:typename:!\tsignature:(mut s Foo)()\troles:def\tend:4\ns\tinput-1.v\t/^fn (mut s Foo) yesnow() ! {$/;\"\tR\tline:3\tfn:xyz.yesnow\troles:def\nnew_repo\tinput-2.v\t/^fn new_repo[T](db DB) Repo[T] {$/;\"\tf\tline:3\ttyperef:typename:Repo[T]\tsignature:[T](db DB)\troles:def\tend:5\nfind_by_id\tinput-2.v\t/^pub fn (r Repo[T]) find_by_id(id int) ?T {$/;\"\tf\tline:7\ttyperef:typename:?T\taccess:pub\tsignature:(r Repo[T])(id int)\troles:def\tend:10\nr\tinput-2.v\t/^pub fn (r Repo[T]) find_by_id(id int) ?T {$/;\"\tR\tline:7\tfn:find_by_id\troles:def\ntable_name\tinput-2.v\t/^    table_name := T.name \\/\\/ in this example getting the name of the type gives us the table na/;\"\tv\tline:8\tfn:find_by_id\troles:def\nBosh\tinput-3.v\t/^enum Bosh {$/;\"\tg\tline:3\troles:def\tend:6\nbim\tinput-3.v\t/^    bim$/;\"\te\tline:4\tenum:Bosh\troles:def\nbam\tinput-3.v\t/^    bam$/;\"\te\tline:5\tenum:Bosh\troles:def\nfrom_string\tinput-3.v\t/^fn Bosh.from_string(s string) !Bosh {$/;\"\tf\tline:8\tenum:Bosh\ttyperef:typename:!Bosh\tsignature:(s string)\troles:def\tend:9\nnope\tinput-3.v\t/^fn Bogus.nope() {$/;\"\tf\tline:11\ttyperef:typename:\tsignature:()\troles:def\tend:12\nxyz\tinput-4.v\t/^module xyz$/;\"\tp\tline:1\troles:def\nBosh\tinput-4.v\t/^enum Bosh {$/;\"\tg\tline:5\tmodule:xyz\troles:def\tend:8\nbim\tinput-4.v\t/^    bim$/;\"\te\tline:6\tenum:xyz.Bosh\troles:def\nbam\tinput-4.v\t/^    bam$/;\"\te\tline:7\tenum:xyz.Bosh\troles:def\nfrom_string\tinput-4.v\t/^fn Bosh.from_string(s string) !Bosh {$/;\"\tf\tline:10\tenum:xyz.Bosh\ttyperef:typename:!Bosh\tsignature:(s string)\troles:def\tend:11\nnope\tinput-4.v\t/^fn Bogus.nope() {$/;\"\tf\tline:13\ttyperef:typename:\tsignature:()\troles:def\tend:14\nmain\tinput-5.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:4\na\tinput-5.v\t/^    a := foo().bar()$/;\"\tv\tline:2\tfn:main\troles:def\nb\tinput-5.v\t/^    b := Foo.bar().foo.bar()$/;\"\tv\tline:3\tfn:main\troles:def\na\tinput-6.v\t/^pub fn a() Test$/;\"\tf\tline:1\ttyperef:typename:Test\taccess:pub\tsignature:()\troles:def\nb\tinput-6.v\t/^pub fn b() !Test$/;\"\tf\tline:2\ttyperef:typename:!Test\taccess:pub\tsignature:()\troles:def\nc\tinput-6.v\t/^pub fn c() []Test$/;\"\tf\tline:3\ttyperef:typename:[]Test\taccess:pub\tsignature:()\troles:def\nd\tinput-6.v\t/^pub fn d() [][]Test$/;\"\tf\tline:4\ttyperef:typename:[][]Test\taccess:pub\tsignature:()\troles:def\ne\tinput-6.v\t/^pub fn e() a.b.C$/;\"\tf\tline:5\ttyperef:typename:a.b.C\taccess:pub\tsignature:()\troles:def\nf\tinput-6.v\t/^pub fn f() [][][]a.b.C$/;\"\tf\tline:6\ttyperef:typename:[][][]a.b.C\taccess:pub\tsignature:()\troles:def\n"
  },
  {
    "path": "Units/parser-v.r/v-fn.d/input-1.v",
    "content": "module xyz\n\nfn (mut s Foo) yesnow() ! {\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-fn.d/input-2.v",
    "content": "// generics\n\nfn new_repo[T](db DB) Repo[T] {\n    return Repo[T]{db: db}\n}\n\npub fn (r Repo[T]) find_by_id(id int) ?T {\n    table_name := T.name // in this example getting the name of the type gives us the table name\n    return r.db.query_one[T]('select * from ${table_name} where id = ?', id)\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-fn.d/input-3.v",
    "content": "// static methods\n\nenum Bosh {\n    bim\n    bam\n}\n\nfn Bosh.from_string(s string) !Bosh {\n}\n\nfn Bogus.nope() {\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-fn.d/input-4.v",
    "content": "module xyz\n\n// static methods\n\nenum Bosh {\n    bim\n    bam\n}\n\nfn Bosh.from_string(s string) !Bosh {\n}\n\nfn Bogus.nope() {\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-fn.d/input-5.v",
    "content": "fn main() {\n    a := foo().bar()\n    b := Foo.bar().foo.bar()\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-fn.d/input-6.v",
    "content": "pub fn a() Test\npub fn b() !Test\npub fn c() []Test\npub fn d() [][]Test\npub fn e() a.b.C\npub fn f() [][][]a.b.C\n"
  },
  {
    "path": "Units/parser-v.r/v-fn.d/input.v",
    "content": "fn fn1() {\n}\n\nfn fn2(a int) {\n}\n\nfn fn3(a int, b string, c Foo) os.Signal {\n}\n\nfn fn4() ! {\n}\n\nfn fn5() ?Test {\n}\n\nfn fn6() (int, int) {\n\n    fn fn7() {\n\n        fn fn8(a int, b string, c Foo) (!Test, int, Foo) {\n        }\n    }\n}\n\n// receivers\n\nfn (s Foo) fnR1(a int) {\n}\n\nfn (s *Foo) fnR2(a int, b string, c Foo) ?Foo {\n}\n\nfn main () {\n\n    // anon\n    x := fn(a int, b int) int { return a + b }\n    y := x(0, 0)\n    z := fn() {\n\n        // closures\n        a := 0\n        b := 0\n        add :=\n            fn        [a,   b\t]   (   c  int  , d  int )\tint  {\n            return a + b + c + d\n        }\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-import.d/args.ctags",
    "content": "--fields=+ERSaenr\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-import.d/expected.tags",
    "content": "main\tinput.v\t/^module main$/;\"\tp\tline:1\troles:def\nos\tinput.v\t/^import os$/;\"\tp\tline:2\troles:imported\textras:reference\na\tinput.v\t/^import a.b.cd$/;\"\tp\tline:3\troles:imported\textras:reference\nb\tinput.v\t/^import a.b.cd$/;\"\tp\tline:3\tmodule:a\troles:imported\textras:reference\ncd\tinput.v\t/^import a.b.cd$/;\"\tp\tline:3\tmodule:a.b\troles:imported\textras:reference\nos\tinput-1.v\t/^import os { abc, def }$/;\"\tp\tline:1\troles:imported\textras:reference\nabc\tinput-1.v\t/^import os { abc, def }$/;\"\tY\tline:1\tmodule:os\troles:imported\textras:reference\ndef\tinput-1.v\t/^import os { abc, def }$/;\"\tY\tline:1\tmodule:os\troles:imported\textras:reference\nxyz\tinput-2.v\t/^import mymod.sha256 as xyz$/;\"\tp\tline:1\troles:imported\textras:reference\nfoo\tinput-3.v\t/^import os as foo { a, b }$/;\"\tp\tline:1\troles:imported\textras:reference\na\tinput-3.v\t/^import os as foo { a, b }$/;\"\tY\tline:1\tmodule:foo\troles:imported\textras:reference\nb\tinput-3.v\t/^import os as foo { a, b }$/;\"\tY\tline:1\tmodule:foo\troles:imported\textras:reference\n"
  },
  {
    "path": "Units/parser-v.r/v-import.d/input-1.v",
    "content": "import os { abc, def }\n"
  },
  {
    "path": "Units/parser-v.r/v-import.d/input-2.v",
    "content": "import mymod.sha256 as xyz\n"
  },
  {
    "path": "Units/parser-v.r/v-import.d/input-3.v",
    "content": "import os as foo { a, b }\n"
  },
  {
    "path": "Units/parser-v.r/v-import.d/input.v",
    "content": "module main\nimport os\nimport a.b.cd\n"
  },
  {
    "path": "Units/parser-v.r/v-match.d/args.ctags",
    "content": "--fields=+ERSaenr\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-match.d/expected.tags",
    "content": "main\tinput.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:7\na\tinput.v\t/^    a := match os {$/;\"\tv\tline:2\tfn:main\troles:def\nmain\tinput-1.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:7\nkind\tinput-2.v\t/^fn (c Colour) kind() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:(c Colour)()\troles:def\tend:7\nc\tinput-2.v\t/^fn (c Colour) kind() {$/;\"\tR\tline:1\tfn:kind\troles:def\nmain\tinput-3.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:6\nmain\tinput-4.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:12\n"
  },
  {
    "path": "Units/parser-v.r/v-match.d/input-1.v",
    "content": "fn main() {\n    match true {\n        2 > 4 { foo() }\n        a == 7 { foo () }\n        else { foo() }\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-match.d/input-2.v",
    "content": "fn (c Colour) kind() {\n    return match c {\n        .red, .green, .blue { \"primary\" }\n        .yellow, .cyan, .magenta { \"secondary\" }\n        else { \"tertiary\" }\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-match.d/input-3.v",
    "content": "fn main() {\n    match c {\n\t    `0`...`9` { 'digit' }\n\t    `a`...`z` { 'character' }\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-match.d/input-4.v",
    "content": "fn main() {\n    return match mut x {\n        StructA { 0 }\n        StructB { 0 }\n        int, u16 { 0 }\n        &a.b.c.Foo { 0 }\n        ?map[string]f32 { 0 }\n        []string { 0 }\n        &a.b.c.Foo, ?map[string]f32, []string { 0 }\n        else { 0 }\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-match.d/input.v",
    "content": "fn main() {\n    a := match os {\n        'a' { 3 }\n        'b' { 4 }\n        else { 5 }\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-misc.d/args.ctags",
    "content": "--fields=+ERSaenr\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-misc.d/expected.tags",
    "content": "main\tinput.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:6\nb\tinput.v\t/^    b, c := 1, 2$/;\"\tv\tline:5\tfn:main\troles:def\nc\tinput.v\t/^    b, c := 1, 2$/;\"\tv\tline:5\tfn:main\troles:def\n"
  },
  {
    "path": "Units/parser-v.r/v-misc.d/input.v",
    "content": "fn main() {\n    a = [] // empty array or array of some type (w/ init)?\n    foo.bar = []foo.bar.Type{}\n    a = []\n    b, c := 1, 2\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-statements.d/args.ctags",
    "content": "--fields=+ERSaenr\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-statements.d/expected.tags",
    "content": "test_if\tinput.v\t/^fn test_if() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:40\na\tinput.v\t/^    a := 0 \\/\\/ test$/;\"\tv\tline:2\tfn:test_if\troles:def\nb\tinput.v\t/^        b := 0$/;\"\tv\tline:4\tfn:test_if\troles:def\nc\tinput.v\t/^        c := 0$/;\"\tv\tline:7\tfn:test_if\troles:def\nd\tinput.v\t/^        d := 0$/;\"\tv\tline:10\tfn:test_if\troles:def\ne\tinput.v\t/^        e := 0$/;\"\tv\tline:13\tfn:test_if\troles:def\nf\tinput.v\t/^        f := 0$/;\"\tv\tline:16\tfn:test_if\troles:def\ng\tinput.v\t/^        g := 0$/;\"\tv\tline:19\tfn:test_if\troles:def\nh\tinput.v\t/^            h := 0 \\/* test *\\/$/;\"\tv\tline:23\tfn:test_if\troles:def\ni\tinput.v\t/^            i := 0 \\/* test \\/* NESTED *\\/ test *\\/$/;\"\tv\tline:26\tfn:test_if\troles:def\nj\tinput.v\t/^            j := 0$/;\"\tv\tline:31\tfn:test_if\troles:def\nk\tinput.v\t/^            k := 0$/;\"\tv\tline:34\tfn:test_if\troles:def\nl\tinput.v\t/^        l := x$/;\"\tv\tline:38\tfn:test_if\troles:def\ntest_for\tinput-1.v\t/^fn test_for() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:39\na\tinput-1.v\t/^    for a in x {$/;\"\tv\tline:3\troles:def\nfoo\tinput-1.v\t/^foo:$/;\"\tl\tline:5\tfn:test_for\troles:def\ni\tinput-1.v\t/^    for mut i, b in x {$/;\"\tv\tline:6\taccess:mut\troles:def\nb\tinput-1.v\t/^    for mut i, b in x {$/;\"\tv\tline:6\troles:def\nc\tinput-1.v\t/^    for mut c in x {$/;\"\tv\tline:8\taccess:mut\troles:def\ni\tinput-1.v\t/^    for i, mut d in x {$/;\"\tv\tline:10\troles:def\nd\tinput-1.v\t/^    for i, mut d in x {$/;\"\tv\tline:10\taccess:mut\troles:def\nbar\tinput-1.v\t/^bar:$/;\"\tl\tline:12\tfn:test_for\troles:def\ne\tinput-1.v\t/^    for _, e in x {$/;\"\tv\tline:13\troles:def\nf\tinput-1.v\t/^    for f, _ in x {$/;\"\tv\tline:15\troles:def\ng\tinput-1.v\t/^    for g in 0..5 {$/;\"\tv\tline:19\troles:def\ni\tinput-1.v\t/^    for i := 0; i < 100; i++ {$/;\"\tv\tline:30\troles:def\np\tinput-1.v\t/^    for p, q := a.b.c, x.y.z; p < q; {$/;\"\tv\tline:37\troles:def\nq\tinput-1.v\t/^    for p, q := a.b.c, x.y.z; p < q; {$/;\"\tv\tline:37\troles:def\ntest_defer_return\tinput-2.v\t/^fn test_defer_return() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:6\nx\tinput-2.v\t/^    x := get_lock()$/;\"\tv\tline:2\tfn:test_defer_return\troles:def\ntest_return_with_expr\tinput-2.v\t/^fn test_return_with_expr() {$/;\"\tf\tline:8\ttyperef:typename:\tsignature:()\troles:def\tend:10\ntest_return_wo_expr\tinput-2.v\t/^fn test_return_wo_expr() {$/;\"\tf\tline:12\ttyperef:typename:\tsignature:()\troles:def\tend:14\ntest_assert\tinput-2.v\t/^fn test_assert() {$/;\"\tf\tline:16\ttyperef:typename:\tsignature:()\troles:def\tend:18\ntest_is_operator\tinput-2.v\t/^fn test_is_operator() {$/;\"\tf\tline:20\ttyperef:typename:\tsignature:()\troles:def\tend:24\nmain\tinput-3.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:5\na\tinput-3.v\t/^        a := 55$/;\"\tv\tline:3\tfn:main\troles:def\nmain\tinput-4.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:7\na\tinput-4.v\t/^    a := 1$/;\"\tv\tline:6\tfn:main\troles:def\nmain\tinput-5.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:8\na\tinput-5.v\t/^\t\ta := 5$/;\"\tv\tline:3\tfn:main\troles:def\na\tinput-5.v\t/^\t\ta := 5$/;\"\tv\tline:6\tfn:main\troles:def\nmain\tinput-6.v\t/^fn main() {$/;\"\tf\tline:1\ttyperef:typename:\tsignature:()\troles:def\tend:11\na\tinput-6.v\t/^\t\ta := 0$/;\"\tv\tline:3\tfn:main\troles:def\nb\tinput-6.v\t/^\t\tb := 0$/;\"\tv\tline:5\tfn:main\troles:def\nc\tinput-6.v\t/^\t\tc := 0$/;\"\tv\tline:7\tfn:main\troles:def\nd\tinput-6.v\t/^\t\td := 0$/;\"\tv\tline:9\tfn:main\troles:def\n"
  },
  {
    "path": "Units/parser-v.r/v-statements.d/input-1.v",
    "content": "fn test_for() {\n    // in\n    for a in x {\n    }\nfoo:\n    for mut i, b in x {\n    }\n    for mut c in x {\n    }\n    for i, mut d in x {\n    }\nbar:\n    for _, e in x {\n    }\n    for f, _ in x {\n        break\n    }\n    // range\n    for g in 0..5 {\n        break foo\n    }\n    // cond\n    for i <= 100 {\n        continue\n    }\n    // bare\n    for {\n        continue bar\n    }\n    for i := 0; i < 100; i++ {\n    }\n    // other expr\n    for (i & whatever) == true {\n    }\n    for if a { b } else { c } == 8 {\n    }\n    for p, q := a.b.c, x.y.z; p < q; {\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-statements.d/input-2.v",
    "content": "fn test_defer_return() {\n    x := get_lock()\n    defer {\n        x.unlock()\n    }\n}\n\nfn test_return_with_expr() {\n    return x.value()\n}\n\nfn test_return_wo_expr() {\n    return\n}\n\nfn test_assert() {\n    assert a == a\n}\n\nfn test_is_operator() {\n    if a is Cat {\n        a.meow()\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-statements.d/input-3.v",
    "content": "fn main() {\n    $if ident ? {\n        a := 55\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-statements.d/input-4.v",
    "content": "fn main() {\n    asm {\n        mov eax, a\n        add eax, b\n    }\n    a := 1\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-statements.d/input-5.v",
    "content": "fn main() {\n\trlock m {\n\t\ta := 5\n\t}\n\tlock s, r {\n\t\ta := 5\n\t}\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-statements.d/input-6.v",
    "content": "fn main() {\n\tif a is b {\n\t\ta := 0\n\t} else if a !is b {\n\t\tb := 0\n\t} else if a in b {\n\t\tc := 0\n\t} else if a !in b {\n\t\td := 0\n\t}\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-statements.d/input.v",
    "content": "fn test_if() {\n    a := 0 // test\n    if a {\n        b := 0\n    }\n    if a {\n        c := 0\n    }\n    else {\n        d := 0\n    }\n    if a {\n        e := 0\n    } // // test\n    else if b {\n        f := 0\n    } // test\n    else {\n        g := 0\n    }\n    if a {\n        if b {\n            h := 0 /* test */\n        }\n        else {\n            i := 0 /* test /* NESTED */ test */\n        }\n    }\n    else {\n        if c {\n            j := 0\n        }\n        else {\n            k := 0\n        }\n    }\n    if mut x is SomeStruct {\n        l := x\n    }\n}\n\n/*\nMULTILINE\n/*\nNESTED\n*/\nCOMMENT\n*/\n"
  },
  {
    "path": "Units/parser-v.r/v-struct.d/args.ctags",
    "content": "--fields=+ERSaenr\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-struct.d/expected.tags",
    "content": "x\tinput.v\t/^module x$/;\"\tp\tline:1\troles:def\nFoo\tinput.v\t/^struct Foo {$/;\"\ts\tline:3\tmodule:x\troles:def\tend:15\na\tinput.v\t/^    a int$/;\"\tm\tline:4\tstruct:x.Foo\troles:def\nb\tinput.v\t/^    b Foo$/;\"\tm\tline:5\tstruct:x.Foo\troles:def\nc\tinput.v\t/^    c map[int]Foo$/;\"\tm\tline:7\tstruct:x.Foo\taccess:mut\troles:def\nd\tinput.v\t/^    d []int$/;\"\tm\tline:9\tstruct:x.Foo\taccess:pub\troles:def\ne\tinput.v\t/^    e u8 [required]$/;\"\tm\tline:11\tstruct:x.Foo\taccess:pub mut\troles:def\nf\tinput.v\t/^    f ?[]Foo$/;\"\tm\tline:13\tstruct:x.Foo\taccess:__global\troles:def\ng\tinput.v\t/^    g []?Foo$/;\"\tm\tline:14\tstruct:x.Foo\taccess:__global\troles:def\nBar\tinput-1.v\t/^struct Bar {$/;\"\ts\tline:1\troles:def\tend:8\nf\tinput-1.v\t/^    f int = 99$/;\"\tm\tline:2\tstruct:Bar\troles:def\ng\tinput-1.v\t/^    g Foo = Foo{66}$/;\"\tm\tline:3\tstruct:Bar\troles:def\nh\tinput-1.v\t/^    h string = \"hi\"$/;\"\tm\tline:4\tstruct:Bar\troles:def\ni\tinput-1.v\t/^    i int @[required]$/;\"\tm\tline:5\tstruct:Bar\troles:def\nj\tinput-1.v\t/^    j int = 99 @[required]$/;\"\tm\tline:6\tstruct:Bar\troles:def\nk\tinput-1.v\t/^    k string = \"j\" @[json: 'k']$/;\"\tm\tline:7\tstruct:Bar\troles:def\nModel\tinput-2.v\t/^pub struct Model {$/;\"\ts\tline:2\taccess:pub\troles:def\tend:9\ngeometry\tinput-2.v\t/^    geometry &map[u64]Geom = &map[u64]Geom{}$/;\"\tm\tline:4\tstruct:Model\taccess:mut\troles:def\nlayers\tinput-2.v\t/^    layers [][]Id = [][]Id{ len: int( Layer.len ), init: []Id{} }$/;\"\tm\tline:5\tstruct:Model\taccess:mut\troles:def\nlast_id\tinput-2.v\t/^    last_id Id [required]$/;\"\tm\tline:6\tstruct:Model\taccess:mut\troles:def\nhighlighted\tinput-2.v\t/^    highlighted []Id = []Id{}$/;\"\tm\tline:7\tstruct:Model\taccess:mut\troles:def\nselected\tinput-2.v\t/^    selected []Id = []Id{}$/;\"\tm\tline:8\tstruct:Model\taccess:mut\troles:def\naaa\tinput-3.v\t/^module aaa$/;\"\tp\tline:1\troles:def\nFoo\tinput-3.v\t/^interface Foo {$/;\"\ti\tline:3\tmodule:aaa\troles:def\tend:11\nid\tinput-3.v\t/^    id string$/;\"\tm\tline:4\tinterface:aaa.Foo\troles:def\nfoo\tinput-3.v\t/^    foo &Foo$/;\"\tm\tline:5\tinterface:aaa.Foo\troles:def\nfn1\tinput-3.v\t/^    fn1()$/;\"\tn\tline:6\tinterface:aaa.Foo\ttyperef:typename:\tsignature:()\troles:def\nfn2\tinput-3.v\t/^    fn2() fn2.Test$/;\"\tn\tline:7\tinterface:aaa.Foo\ttyperef:typename:fn2.Test\tsignature:()\troles:def\nfn3\tinput-3.v\t/^    fn3(a int, b int, c int) !&Test$/;\"\tn\tline:8\tinterface:aaa.Foo\ttyperef:typename:!&Test\tsignature:(a int, b int, c int)\troles:def\nfn4\tinput-3.v\t/^    fn4() [][]a.b.c.D$/;\"\tn\tline:9\tinterface:aaa.Foo\ttyperef:typename:[][]a.b.c.D\tsignature:()\troles:def\nfn5\tinput-3.v\t/^    fn5()$/;\"\tn\tline:10\tinterface:aaa.Foo\ttyperef:typename:\tsignature:()\troles:def\nmain\tinput-4.v\t/^fn main() {$/;\"\tf\tline:2\ttyperef:typename:\tsignature:()\troles:def\tend:15\na\tinput-4.v\t/^    a := SomeStruct{$/;\"\tv\tline:3\tfn:main\troles:def\nFoo\tinput-5.v\t/^struct Foo {$/;\"\ts\tline:2\troles:def\tend:11\na\tinput-5.v\t/^    a string$/;\"\tm\tline:3\tstruct:Foo\troles:def\nBar\tinput-5.v\t/^    b struct Bar {$/;\"\ts\tline:4\tstruct:Foo\troles:def\nc\tinput-5.v\t/^        c string$/;\"\tm\tline:5\tstruct:Foo.Bar\troles:def\nb\tinput-5.v\t/^    b struct Bar {$/;\"\tm\tline:4\tstruct:Foo\troles:def\nd\tinput-5.v\t/^    d string$/;\"\tm\tline:7\tstruct:Foo\troles:def\nf\tinput-5.v\t/^        f string$/;\"\tm\tline:9\tstruct:Foo\troles:def\ne\tinput-5.v\t/^    e struct {$/;\"\tm\tline:8\tstruct:Foo\troles:def\nFoo\tinput-6.v\t/^struct Foo {$/;\"\ts\tline:2\troles:def\tend:7\na\tinput-6.v\t/^    a string$/;\"\tm\tline:4\tstruct:Foo\troles:def\nb\tinput-6.v\t/^\tb fn (mut a int) b.Foo$/;\"\tm\tline:5\tstruct:Foo\troles:def\nc\tinput-6.v\t/^    c string$/;\"\tm\tline:6\tstruct:Foo\troles:def\nFoo\tinput-7.v\t/^union Foo {$/;\"\tu\tline:1\troles:def\tend:8\nx\tinput-7.v\t/^    x int$/;\"\tm\tline:2\tunion:Foo\troles:def\ny\tinput-7.v\t/^    y string$/;\"\tm\tline:3\tunion:Foo\troles:def\nx\tinput-7.v\t/^        x string$/;\"\tm\tline:5\tunion:Foo\troles:def\ny\tinput-7.v\t/^        y int$/;\"\tm\tline:6\tunion:Foo\troles:def\nz\tinput-7.v\t/^    z struct {$/;\"\tm\tline:4\tunion:Foo\troles:def\n"
  },
  {
    "path": "Units/parser-v.r/v-struct.d/input-1.v",
    "content": "struct Bar {\n    f int = 99\n    g Foo = Foo{66}\n    h string = \"hi\"\n    i int @[required]\n    j int = 99 @[required]\n    k string = \"j\" @[json: 'k']\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-struct.d/input-2.v",
    "content": "[heap]\npub struct Model {\n    mut:\n    geometry &map[u64]Geom = &map[u64]Geom{}\n    layers [][]Id = [][]Id{ len: int( Layer.len ), init: []Id{} }\n    last_id Id [required]\n    highlighted []Id = []Id{}\n    selected []Id = []Id{}\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-struct.d/input-3.v",
    "content": "module aaa\n\ninterface Foo {\n    id string\n    foo &Foo\n    fn1()\n    fn2() fn2.Test\n    fn3(a int, b int, c int) !&Test\n    fn4() [][]a.b.c.D\n    fn5()\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-struct.d/input-4.v",
    "content": "// update sytax\nfn main() {\n    a := SomeStruct{\n        ...&foo(66)\n        b: \"55\".whatever().foo().bar\n        \"hi\": 55\n        .whatever: 99\n        \"hi\": .hi\n        .whatever: 99\n        c: fully.quallify\n        .notme: Foo{}\n        value()\n        \"yo\"\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-struct.d/input-5.v",
    "content": "// anon struct\nstruct Foo {\n    a string\n    b struct Bar {\n        c string\n    }\n    d string\n    e struct {\n        f string\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-struct.d/input-6.v",
    "content": "// embedded struct, fn prop\nstruct Foo {\n    Bar\n    a string\n\tb fn (mut a int) b.Foo\n    c string\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-struct.d/input-7.v",
    "content": "union Foo {\n    x int\n    y string\n    z struct {\n        x string\n        y int\n    }\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-struct.d/input.v",
    "content": "module x\n\nstruct Foo {\n    a int\n    b Foo\nmut:\n    c map[int]Foo\npub:\n    d []int\npub mut:\n    e u8 [required]\n__global:\n    f ?[]Foo\n    g []?Foo\n}\n"
  },
  {
    "path": "Units/parser-v.r/v-type.d/args.ctags",
    "content": "--fields=+ERSaenr\n--sort=no\n--extras=+r\n"
  },
  {
    "path": "Units/parser-v.r/v-type.d/expected.tags",
    "content": "Foo\tinput.v\t/^type Foo = int$/;\"\ta\tline:1\troles:def\nBar\tinput.v\t/^type Bar = []map[string]Foo$/;\"\ta\tline:3\troles:def\nWorld\tinput-1.v\t/^type World = Mars | Moon | Venus$/;\"\ta\tline:1\troles:def\n"
  },
  {
    "path": "Units/parser-v.r/v-type.d/input-1.v",
    "content": "type World = Mars | Moon | Venus\n"
  },
  {
    "path": "Units/parser-v.r/v-type.d/input.v",
    "content": "type Foo = int\n\ntype Bar = []map[string]Foo\n"
  },
  {
    "path": "Units/parser-varlink.r/varlink-enum.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-varlink.r/varlink-enum.d/expected.tags",
    "content": "org.example.complex\tinput.varlink\t/^interface org.example.complex$/;\"\ti\nEnum\tinput.varlink\t/^type Enum (enum, b, c)$/;\"\tg\tinterface:org.example.complex\nenum\tinput.varlink\t/^type Enum (enum, b, c)$/;\"\te\tenum:org.example.complex.Enum\nb\tinput.varlink\t/^type Enum (enum, b, c)$/;\"\te\tenum:org.example.complex.Enum\nc\tinput.varlink\t/^type Enum (enum, b, c)$/;\"\te\tenum:org.example.complex.Enum\nType\tinput.varlink\t/^type Type (type, b, c)$/;\"\tg\tinterface:org.example.complex\ntype\tinput.varlink\t/^type Type (type, b, c)$/;\"\te\tenum:org.example.complex.Type\nb\tinput.varlink\t/^type Type (type, b, c)$/;\"\te\tenum:org.example.complex.Type\nc\tinput.varlink\t/^type Type (type, b, c)$/;\"\te\tenum:org.example.complex.Type\nTypeEnum\tinput.varlink\t/^type TypeEnum (type, b, c)$/;\"\tg\tinterface:org.example.complex\ntype\tinput.varlink\t/^type TypeEnum (type, b, c)$/;\"\te\tenum:org.example.complex.TypeEnum\nb\tinput.varlink\t/^type TypeEnum (type, b, c)$/;\"\te\tenum:org.example.complex.TypeEnum\nc\tinput.varlink\t/^type TypeEnum (type, b, c)$/;\"\te\tenum:org.example.complex.TypeEnum\nInterface\tinput.varlink\t/^type Interface (interface, b, c)$/;\"\tg\tinterface:org.example.complex\ninterface\tinput.varlink\t/^type Interface (interface, b, c)$/;\"\te\tenum:org.example.complex.Interface\nb\tinput.varlink\t/^type Interface (interface, b, c)$/;\"\te\tenum:org.example.complex.Interface\nc\tinput.varlink\t/^type Interface (interface, b, c)$/;\"\te\tenum:org.example.complex.Interface\nTypeFoo\tinput.varlink\t/^type TypeFoo ($/;\"\ts\tinterface:org.example.complex\nbool\tinput.varlink\t/^  bool: bool,$/;\"\tf\tstruct:org.example.complex.TypeFoo\nint\tinput.varlink\t/^  int: int,$/;\"\tf\tstruct:org.example.complex.TypeFoo\nfloat\tinput.varlink\t/^  float: float,$/;\"\tf\tstruct:org.example.complex.TypeFoo\nstring\tinput.varlink\t/^  string: string,$/;\"\tf\tstruct:org.example.complex.TypeFoo\nenum\tinput.varlink\t/^  enum: ?[]?(foo, bar, baz),$/;\"\tf\tstruct:org.example.complex.TypeFoo\nfoo\tinput.varlink\t/^  enum: ?[]?(foo, bar, baz),$/;\"\te\tstruct:org.example.complex.TypeFoo\nbar\tinput.varlink\t/^  enum: ?[]?(foo, bar, baz),$/;\"\te\tstruct:org.example.complex.TypeFoo\nbaz\tinput.varlink\t/^  enum: ?[]?(foo, bar, baz),$/;\"\te\tstruct:org.example.complex.TypeFoo\ntype\tinput.varlink\t/^  type: ?TypeEnum,$/;\"\tf\tstruct:org.example.complex.TypeFoo\nanon\tinput.varlink\t/^  anon: (foo: bool, bar: int, baz: [](a: int, b: int))$/;\"\tf\tstruct:org.example.complex.TypeFoo\nfoo\tinput.varlink\t/^  anon: (foo: bool, bar: int, baz: [](a: int, b: int))$/;\"\tf\tstruct:org.example.complex.TypeFoo\nbar\tinput.varlink\t/^  anon: (foo: bool, bar: int, baz: [](a: int, b: int))$/;\"\tf\tstruct:org.example.complex.TypeFoo\nbaz\tinput.varlink\t/^  anon: (foo: bool, bar: int, baz: [](a: int, b: int))$/;\"\tf\tstruct:org.example.complex.TypeFoo\na\tinput.varlink\t/^  anon: (foo: bool, bar: int, baz: [](a: int, b: int))$/;\"\tf\tstruct:org.example.complex.TypeFoo\nb\tinput.varlink\t/^  anon: (foo: bool, bar: int, baz: [](a: int, b: int))$/;\"\tf\tstruct:org.example.complex.TypeFoo\nFoo\tinput.varlink\t/^method Foo(enum: (b: bool, c: int), foo: TypeFoo, interface: Interface) -> ($/;\"\tm\tinterface:org.example.complex\nenum\tinput.varlink\t/^method Foo(enum: (b: bool, c: int), foo: TypeFoo, interface: Interface) -> ($/;\"\tI\tmethod:org.example.complex.Foo\nb\tinput.varlink\t/^method Foo(enum: (b: bool, c: int), foo: TypeFoo, interface: Interface) -> ($/;\"\tI\tmethod:org.example.complex.Foo\nc\tinput.varlink\t/^method Foo(enum: (b: bool, c: int), foo: TypeFoo, interface: Interface) -> ($/;\"\tI\tmethod:org.example.complex.Foo\nfoo\tinput.varlink\t/^method Foo(enum: (b: bool, c: int), foo: TypeFoo, interface: Interface) -> ($/;\"\tI\tmethod:org.example.complex.Foo\ninterface\tinput.varlink\t/^method Foo(enum: (b: bool, c: int), foo: TypeFoo, interface: Interface) -> ($/;\"\tI\tmethod:org.example.complex.Foo\na\tinput.varlink\t/^  a: [](b: bool, c: int),$/;\"\tO\tmethod:org.example.complex.Foo\nb\tinput.varlink\t/^  a: [](b: bool, c: int),$/;\"\tO\tmethod:org.example.complex.Foo\nc\tinput.varlink\t/^  a: [](b: bool, c: int),$/;\"\tO\tmethod:org.example.complex.Foo\nfoo\tinput.varlink\t/^  foo: TypeFoo,$/;\"\tO\tmethod:org.example.complex.Foo\ninterface\tinput.varlink\t/^  interface: Interface$/;\"\tO\tmethod:org.example.complex.Foo\nBar\tinput.varlink\t/^method Bar() -> ()$/;\"\tm\tinterface:org.example.complex\nErrorFoo\tinput.varlink\t/^error ErrorFoo ($/;\"\tE\tinterface:org.example.complex\nenum\tinput.varlink\t/^  enum: (b: bool, c: int, interface: Interface),$/;\"\td\terror:org.example.complex.ErrorFoo\nb\tinput.varlink\t/^  enum: (b: bool, c: int, interface: Interface),$/;\"\td\terror:org.example.complex.ErrorFoo\nc\tinput.varlink\t/^  enum: (b: bool, c: int, interface: Interface),$/;\"\td\terror:org.example.complex.ErrorFoo\ninterface\tinput.varlink\t/^  enum: (b: bool, c: int, interface: Interface),$/;\"\td\terror:org.example.complex.ErrorFoo\nfoo\tinput.varlink\t/^  foo: TypeFoo,$/;\"\td\terror:org.example.complex.ErrorFoo\nbar\tinput.varlink\t/^  bar: (type, enum, int, bool, string, if, let),$/;\"\td\terror:org.example.complex.ErrorFoo\ntype\tinput.varlink\t/^  bar: (type, enum, int, bool, string, if, let),$/;\"\te\terror:org.example.complex.ErrorFoo\nenum\tinput.varlink\t/^  bar: (type, enum, int, bool, string, if, let),$/;\"\te\terror:org.example.complex.ErrorFoo\nint\tinput.varlink\t/^  bar: (type, enum, int, bool, string, if, let),$/;\"\te\terror:org.example.complex.ErrorFoo\nbool\tinput.varlink\t/^  bar: (type, enum, int, bool, string, if, let),$/;\"\te\terror:org.example.complex.ErrorFoo\nstring\tinput.varlink\t/^  bar: (type, enum, int, bool, string, if, let),$/;\"\te\terror:org.example.complex.ErrorFoo\nif\tinput.varlink\t/^  bar: (type, enum, int, bool, string, if, let),$/;\"\te\terror:org.example.complex.ErrorFoo\nlet\tinput.varlink\t/^  bar: (type, enum, int, bool, string, if, let),$/;\"\te\terror:org.example.complex.ErrorFoo\ninterface\tinput.varlink\t/^  interface: Interface$/;\"\td\terror:org.example.complex.ErrorFoo\nErrorBar\tinput.varlink\t/^error ErrorBar ()$/;\"\tE\tinterface:org.example.complex\n"
  },
  {
    "path": "Units/parser-varlink.r/varlink-enum.d/features",
    "content": "packcc\n"
  },
  {
    "path": "Units/parser-varlink.r/varlink-enum.d/input.varlink",
    "content": "# Taken from https://github.com/varlink/varlink.github.io/pull/12\n\ninterface org.example.complex\n\ntype Enum (enum, b, c)\n\ntype Type (type, b, c)\n\ntype TypeEnum (type, b, c)\n\ntype Interface (interface, b, c)\n\ntype TypeFoo (\n  bool: bool,\n  int: int,\n  float: float,\n  string: string,\n  enum: ?[]?(foo, bar, baz),\n  type: ?TypeEnum,\n  anon: (foo: bool, bar: int, baz: [](a: int, b: int))\n)\n\nmethod Foo(enum: (b: bool, c: int), foo: TypeFoo, interface: Interface) -> (\n  a: [](b: bool, c: int),\n  foo: TypeFoo,\n  interface: Interface\n)\n\nmethod Bar() -> ()\n\nerror ErrorFoo (\n  enum: (b: bool, c: int, interface: Interface),\n  foo: TypeFoo,\n  bar: (type, enum, int, bool, string, if, let),\n  interface: Interface\n)\n\nerror ErrorBar ()\n"
  },
  {
    "path": "Units/parser-varlink.r/varlink-type-method-error.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-varlink.r/varlink-type-method-error.d/expected.tags",
    "content": "org.example.more\tinput.varlink\t/^interface org.example.more$/;\"\ti\nState\tinput.varlink\t/^type State ($/;\"\ts\tinterface:org.example.more\nstart\tinput.varlink\t/^  start: ?bool,$/;\"\tf\tstruct:org.example.more.State\nprogress\tinput.varlink\t/^  progress: ?int,$/;\"\tf\tstruct:org.example.more.State\nend\tinput.varlink\t/^  end: ?bool$/;\"\tf\tstruct:org.example.more.State\nPing\tinput.varlink\t/^method Ping(ping: string) -> (pong: string)$/;\"\tm\tinterface:org.example.more\nping\tinput.varlink\t/^method Ping(ping: string) -> (pong: string)$/;\"\tI\tmethod:org.example.more.Ping\npong\tinput.varlink\t/^method Ping(ping: string) -> (pong: string)$/;\"\tO\tmethod:org.example.more.Ping\nTestMore\tinput.varlink\t/^method TestMore(n: int) -> (state: State)$/;\"\tm\tinterface:org.example.more\nn\tinput.varlink\t/^method TestMore(n: int) -> (state: State)$/;\"\tI\tmethod:org.example.more.TestMore\nstate\tinput.varlink\t/^method TestMore(n: int) -> (state: State)$/;\"\tO\tmethod:org.example.more.TestMore\nStopServing\tinput.varlink\t/^method StopServing() -> ()$/;\"\tm\tinterface:org.example.more\nTestMoreError\tinput.varlink\t/^error TestMoreError (reason: string)$/;\"\tE\tinterface:org.example.more\nreason\tinput.varlink\t/^error TestMoreError (reason: string)$/;\"\td\terror:org.example.more.TestMoreError\n"
  },
  {
    "path": "Units/parser-varlink.r/varlink-type-method-error.d/features",
    "content": "packcc\n"
  },
  {
    "path": "Units/parser-varlink.r/varlink-type-method-error.d/input.varlink",
    "content": "# Taken from https://github.com/varlink/rust/blob/master/examples/more/src/org.example.more.varlink\n\n# Example Varlink service\ninterface org.example.more\n\n# Enum, returning either start, progress or end\n# progress: [0-100]\ntype State (\n  start: ?bool,\n  progress: ?int,\n  end: ?bool\n)\n\n# Returns the same string\nmethod Ping(ping: string) -> (pong: string)\n\n# Dummy progress method\n# n: number of progress steps\nmethod TestMore(n: int) -> (state: State)\n\n# Stop serving\nmethod StopServing() -> ()\n\n# Something failed in TestMore\nerror TestMoreError (reason: string)\n"
  },
  {
    "path": "Units/parser-vera.r/vera-interface.d/args.ctags",
    "content": "--sort=no\n--fields=+eK\n"
  },
  {
    "path": "Units/parser-vera.r/vera-interface.d/expected.tags",
    "content": "sample_if\tinput.vr\t/^interface sample_if {$/;\"\tinterface\tend:14\nclock\tinput.vr\t/^  input clock          CLOCK;$/;\"\tsignal\tinterface:sample_if\tend:5\nreset\tinput.vr\t/^  output reset         PHOLD#1;$/;\"\tsignal\tinterface:sample_if\tend:6\nenable\tinput.vr\t/^  output enable        PHOLD#1;$/;\"\tsignal\tinterface:sample_if\tend:7\ncout\tinput.vr\t/^  input [7:0] cout     PSAMPLE #-1;$/;\"\tsignal\tinterface:sample_if\tend:8\ndata\tinput.vr\t/^  inout data           PSAMPLE PHOLD NSAMPLE#-1 NHOLD #1;$/;\"\tsignal\tinterface:sample_if\tend:9\nddr_data_in\tinput.vr\t/^  input ddr_data_in    PSAMPLE NSAMPLE;$/;\"\tsignal\tinterface:sample_if\tend:10\ndata_in\tinput.vr\t/^  input data_in        PSAMPLE #-1 hdl_node \"sample_if_verilog.data\";$/;\"\tsignal\tinterface:sample_if\tend:11\ncount\tinput.vr\t/^  input [7:0] count    PSAMPLE #-1 hdl_node \"sample_if_verilog.counter\";$/;\"\tsignal\tinterface:sample_if\tend:12\nnenable\tinput.vr\t/^  output  nenable      PHOLD   #1 hdl_node \"sample_if_verilog.counter_en\";$/;\"\tsignal\tinterface:sample_if\tend:13\n"
  },
  {
    "path": "Units/parser-vera.r/vera-interface.d/input.vr",
    "content": "// Taken from:\n// http://www.asic-world.com/vera/hdl1.html#Interface_Declaration\ninterface sample_if {\n  // Other signals are sampled with respect to this\n  input clock          CLOCK;\n  output reset         PHOLD#1;\n  output enable        PHOLD#1;\n  input [7:0] cout     PSAMPLE #-1;\n  inout data           PSAMPLE PHOLD NSAMPLE#-1 NHOLD #1;\n  input ddr_data_in    PSAMPLE NSAMPLE;\n  input data_in        PSAMPLE #-1 hdl_node \"sample_if_verilog.data\";\n  input [7:0] count    PSAMPLE #-1 hdl_node \"sample_if_verilog.counter\";\n  output  nenable      PHOLD   #1 hdl_node \"sample_if_verilog.counter_en\";\n}\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-2d-array.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-2d-array.d/expected.tags",
    "content": "my_pack\tinput.sv\t/^package my_pack;$/;\"\tK\nMY_WIDTH\tinput.sv\t/^    localparam int MY_WIDTH                  = 1;$/;\"\tc\tpackage:my_pack\nMY_DEPTH\tinput.sv\t/^    localparam int MY_DEPTH                  = 2;$/;\"\tc\tpackage:my_pack\nmy_t\tinput.sv\t/^    typedef logic [MY_DEPTH-1:0][MY_WIDTH-1:0]  my_t;$/;\"\tT\tpackage:my_pack\nmy_t2\tinput.sv\t/^    typedef logic   [MY_DEPTH-1:0] \t [MY_WIDTH-1:0] \t my_t2;$/;\"\tT\tpackage:my_pack\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-2d-array.d/input.sv",
    "content": "// Taken from the commet in #2489 submitted by @t0mj0nes.\npackage my_pack;\n    localparam int MY_WIDTH                  = 1;\n    localparam int MY_DEPTH                  = 2;\n    typedef logic [MY_DEPTH-1:0][MY_WIDTH-1:0]  my_t;\n   // Added by @masatake.\n    typedef logic   [MY_DEPTH-1:0] \t [MY_WIDTH-1:0] \t my_t2;\nendpackage // my_pack\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-assertion.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-assertion.d/expected.tags",
    "content": "deffered_assert\tinput.sv\t/^module deffered_assert;$/;\"\tm\nexpr\tinput.sv\t/^var expr;$/;\"\tr\tmodule:deffered_assert\ndeferred_immediate_assertions\tinput.sv\t/^initial begin : deferred_immediate_assertions$/;\"\tb\tmodule:deffered_assert\nimmediate_assertion\tinput.sv\t/^    immediate_assertion : assert (expr) myTask();$/;\"\tA\tblock:deffered_assert.deferred_immediate_assertions\nimmediate_cover\tinput.sv\t/^    immediate_cover     : cover (expr) myTask();$/;\"\tA\tblock:deffered_assert.deferred_immediate_assertions\nimmediate_assume\tinput.sv\t/^    immediate_assume    : assume (expr) myTask();$/;\"\tA\tblock:deffered_assert.deferred_immediate_assertions\ndeferred_assertion1\tinput.sv\t/^    deferred_assertion1 : assert #0 (expr) myTask();$/;\"\tA\tblock:deffered_assert.deferred_immediate_assertions\ndeferred_cover1\tinput.sv\t/^    deferred_cover1     : cover #0 (expr) myTask();$/;\"\tA\tblock:deffered_assert.deferred_immediate_assertions\ndeferred_assume1\tinput.sv\t/^    deferred_assume1    : assume #0 (expr) myTask();$/;\"\tA\tblock:deffered_assert.deferred_immediate_assertions\ndeferred_assertion2\tinput.sv\t/^    deferred_assertion2 : assert final (expr) myTask();$/;\"\tA\tblock:deffered_assert.deferred_immediate_assertions\ndeferred_cover2\tinput.sv\t/^    deferred_cover2     : cover final (expr) myTask();$/;\"\tA\tblock:deffered_assert.deferred_immediate_assertions\ndeferred_assume2\tinput.sv\t/^    deferred_assume2    : assume final (expr) myTask();$/;\"\tA\tblock:deffered_assert.deferred_immediate_assertions\nprop1\tinput.sv\t/^property prop1 ($/;\"\tR\tmodule:deffered_assert\nm\tinput.sv\t/^    local input int m,$/;\"\tp\tproperty:deffered_assert.prop1\nn\tinput.sv\t/^    logic [1:0] n,$/;\"\tp\tproperty:deffered_assert.prop1\no\tinput.sv\t/^    int o$/;\"\tp\tproperty:deffered_assert.prop1\nprop2\tinput.sv\t/^property prop2 (a, b);$/;\"\tR\tmodule:deffered_assert\na\tinput.sv\t/^property prop2 (a, b);$/;\"\tp\tproperty:deffered_assert.prop2\nb\tinput.sv\t/^property prop2 (a, b);$/;\"\tp\tproperty:deffered_assert.prop2\nconcurrent_assertion1\tinput.sv\t/^concurrent_assertion1   : assert property (prop2 (l, m));$/;\"\tA\tmodule:deffered_assert\nassert_test\tinput.sv\t/^module assert_test;$/;\"\tm\nassert_f\tinput.sv\t/^        assert_f: assert(f) $info(\"passed\"); else $error(\"failed\");$/;\"\tA\tmodule:assert_test\nassume_inputs\tinput.sv\t/^        assume_inputs: assume (in_a || in_b) $info(\"assumption holds\");$/;\"\tA\tmodule:assert_test\ncover_a_and_b\tinput.sv\t/^        cover_a_and_b: cover (in_a && in_b) $info(\"in_a && in_b == 1 covered\");$/;\"\tA\tmodule:assert_test\nt\tinput.sv\t/^    time t;$/;\"\tr\tmodule:assert_test\nb1\tinput.sv\t/^    always_comb begin : b1$/;\"\tb\tmodule:assert_test\na1\tinput.sv\t/^        a1: assert (not_a != a);$/;\"\tA\tblock:assert_test.b1\na2\tinput.sv\t/^        a2: assert #0 (not_a != a); \\/\\/ Should pass once values have settled$/;\"\tA\tblock:assert_test.b1\nb1\tinput.sv\t/^    always_comb begin : b1$/;\"\tb\tmodule:assert_test\nc1\tinput.sv\t/^        c1: cover (b != a);$/;\"\tA\tblock:assert_test.b1\nc2\tinput.sv\t/^        c2: cover #0 (b != a);$/;\"\tA\tblock:assert_test.b1\nerror_type\tinput.sv\t/^    function int error_type (int opcode);$/;\"\tf\tmodule:assert_test\nopcode\tinput.sv\t/^    function int error_type (int opcode);$/;\"\tp\tfunction:assert_test.error_type\nfunc_assert\tinput.sv\t/^        func_assert: assert (opcode < 64) else $display(\"Opcode error.\");$/;\"\tA\tfunction:assert_test.error_type\nb1\tinput.sv\t/^        always_comb begin : b1$/;\"\tb\tmodule:assert_test\na1\tinput.sv\t/^            a1: assert #0 (my_cond) else$/;\"\tA\tblock:assert_test.b1\na2\tinput.sv\t/^            a2: assert #0 (my_cond) else$/;\"\tA\tblock:assert_test.b1\ndut\tinput.sv\t/^module dut(input logic clk, input logic a, input logic b);$/;\"\tm\nclk\tinput.sv\t/^module dut(input logic clk, input logic a, input logic b);$/;\"\tp\tmodule:dut\na\tinput.sv\t/^module dut(input logic clk, input logic a, input logic b);$/;\"\tp\tmodule:dut\nb\tinput.sv\t/^module dut(input logic clk, input logic a, input logic b);$/;\"\tp\tmodule:dut\nc\tinput.sv\t/^    logic c;$/;\"\tr\tmodule:dut\na1\tinput.sv\t/^    a1: assert #0 (!(a & c)) $display(\"Pass\"); else $display(\"Fail\");$/;\"\tA\tmodule:dut\na2\tinput.sv\t/^    a2: assert final (!(a & c)) $display(\"Pass\"); else $display(\"Fail\");$/;\"\tA\tmodule:dut\ntb\tinput.sv\t/^program tb(input logic clk, output logic a, output logic b);$/;\"\tP\nclk\tinput.sv\t/^program tb(input logic clk, output logic a, output logic b);$/;\"\tp\tprogram:tb\na\tinput.sv\t/^program tb(input logic clk, output logic a, output logic b);$/;\"\tp\tprogram:tb\nb\tinput.sv\t/^program tb(input logic clk, output logic a, output logic b);$/;\"\tp\tprogram:tb\nm\tinput.sv\t/^    default clocking m @(posedge clk);$/;\"\tL\tprogram:tb\nsva_svtb\tinput.sv\t/^module sva_svtb;$/;\"\tm\nclk\tinput.sv\t/^    bit clk;$/;\"\tr\tmodule:sva_svtb\na\tinput.sv\t/^    logic a, b;$/;\"\tr\tmodule:sva_svtb\nb\tinput.sv\t/^    logic a, b;$/;\"\tr\tmodule:sva_svtb\ndut\tinput.sv\t/^    dut dut (.*);$/;\"\ti\tmodule:sva_svtb\ttyperef:module:dut\ntb\tinput.sv\t/^    tb tb (.*);$/;\"\ti\tmodule:sva_svtb\ttyperef:module:tb\nm\tinput.sv\t/^module m (input a, b);$/;\"\tm\na\tinput.sv\t/^module m (input a, b);$/;\"\tp\tmodule:m\nb\tinput.sv\t/^module m (input a, b);$/;\"\tp\tmodule:m\na1\tinput.sv\t/^    a1: assert #0 (a == b);$/;\"\tA\tmodule:m\nm\tinput.sv\t/^module m (input a, b);$/;\"\tm\na\tinput.sv\t/^module m (input a, b);$/;\"\tp\tmodule:m\nb\tinput.sv\t/^module m (input a, b);$/;\"\tp\tmodule:m\na1\tinput.sv\t/^        a1: assert #0 (a == b);$/;\"\tA\tmodule:m\nm\tinput.sv\t/^module m (input bad_val, bad_val_ok, a, b, c, clear_b2);$/;\"\tm\nbad_val\tinput.sv\t/^module m (input bad_val, bad_val_ok, a, b, c, clear_b2);$/;\"\tp\tmodule:m\nbad_val_ok\tinput.sv\t/^module m (input bad_val, bad_val_ok, a, b, c, clear_b2);$/;\"\tp\tmodule:m\na\tinput.sv\t/^module m (input bad_val, bad_val_ok, a, b, c, clear_b2);$/;\"\tp\tmodule:m\nb\tinput.sv\t/^module m (input bad_val, bad_val_ok, a, b, c, clear_b2);$/;\"\tp\tmodule:m\nc\tinput.sv\t/^module m (input bad_val, bad_val_ok, a, b, c, clear_b2);$/;\"\tp\tmodule:m\nclear_b2\tinput.sv\t/^module m (input bad_val, bad_val_ok, a, b, c, clear_b2);$/;\"\tp\tmodule:m\nb1\tinput.sv\t/^    always @(bad_val or bad_val_ok) begin : b1$/;\"\tb\tmodule:m\na1\tinput.sv\t/^        a1: assert #0 (bad_val) else $fatal(1, \"Sorry\");$/;\"\tA\tblock:m.b1\nb2\tinput.sv\t/^    always @(a or b or c) begin : b2$/;\"\tb\tmodule:m\na2\tinput.sv\t/^            a2: assert #0 (a && b);$/;\"\tA\tblock:m.b2\na3\tinput.sv\t/^         a3: assert #0 (a || b);$/;\"\tA\tblock:m.b2\nb3\tinput.sv\t/^    always @(clear_b2) begin : b3$/;\"\tb\tmodule:m\nm\tinput.sv\t/^module m;$/;\"\tm\na\tinput.sv\t/^    bit a;$/;\"\tr\tmodule:m\nb\tinput.sv\t/^    integer b;$/;\"\tr\tmodule:m\nq\tinput.sv\t/^    byte q[$];$/;\"\tr\tmodule:m\np1\tinput.sv\t/^    property p1;$/;\"\tR\tmodule:m\np2\tinput.sv\t/^    property p2;$/;\"\tR\tmodule:m\nl_b\tinput.sv\t/^        integer l_b;$/;\"\tr\tproperty:m.p2\ncount\tinput.sv\t/^    bit [2:0] count;$/;\"\tr\tmodule:m\nt\tinput.sv\t/^    realtime t;$/;\"\tr\tmodule:m\np1\tinput.sv\t/^    property p1;$/;\"\tR\tmodule:m\np2\tinput.sv\t/^    property p2;$/;\"\tR\tmodule:m\nl_t\tinput.sv\t/^        realtime l_t;$/;\"\tr\tproperty:m.p2\nm\tinput.sv\t/^module m;$/;\"\tm\ndelay_example\tinput.sv\t/^    sequence delay_example(x, y, min, max, delay1);$/;\"\tq\tmodule:m\nx\tinput.sv\t/^    sequence delay_example(x, y, min, max, delay1);$/;\"\tp\tsequence:m.delay_example\ny\tinput.sv\t/^    sequence delay_example(x, y, min, max, delay1);$/;\"\tp\tsequence:m.delay_example\nmin\tinput.sv\t/^    sequence delay_example(x, y, min, max, delay1);$/;\"\tp\tsequence:m.delay_example\nmax\tinput.sv\t/^    sequence delay_example(x, y, min, max, delay1);$/;\"\tp\tsequence:m.delay_example\ndelay1\tinput.sv\t/^    sequence delay_example(x, y, min, max, delay1);$/;\"\tp\tsequence:m.delay_example\na1\tinput.sv\t/^    a1: assert property (@(posedge clk) delay_example(x, y, 3, $, 2));$/;\"\tA\tmodule:m\nz\tinput.sv\t/^    int z, d;$/;\"\tr\tmodule:m\nd\tinput.sv\t/^    int z, d;$/;\"\tr\tmodule:m\ns1\tinput.sv\t/^    sequence s1;$/;\"\tq\tmodule:m\ns2\tinput.sv\t/^    sequence s2;$/;\"\tq\tmodule:m\ns3\tinput.sv\t/^    sequence s3;$/;\"\tq\tmodule:m\ns4\tinput.sv\t/^    sequence s4;$/;\"\tq\tmodule:m\ns20_1\tinput.sv\t/^    sequence s20_1(data,en);$/;\"\tq\tmodule:m\ndata\tinput.sv\t/^    sequence s20_1(data,en);$/;\"\tp\tsequence:m.s20_1\nen\tinput.sv\t/^    sequence s20_1(data,en);$/;\"\tp\tsequence:m.s20_1\ns\tinput.sv\t/^    sequence s;$/;\"\tq\tmodule:m\nrule\tinput.sv\t/^    sequence rule;$/;\"\tq\tmodule:m\nrule\tinput.sv\t/^    sequence rule;$/;\"\tq\tmodule:m\nm\tinput.sv\t/^module m;$/;\"\tm\ns1\tinput.sv\t/^    sequence s1(w, x, y);$/;\"\tq\tmodule:m\nw\tinput.sv\t/^    sequence s1(w, x, y);$/;\"\tp\tsequence:m.s1\nx\tinput.sv\t/^    sequence s1(w, x, y);$/;\"\tp\tsequence:m.s1\ny\tinput.sv\t/^    sequence s1(w, x, y);$/;\"\tp\tsequence:m.s1\ns2\tinput.sv\t/^    sequence s2(w, y, bit x);$/;\"\tq\tmodule:m\nw\tinput.sv\t/^    sequence s2(w, y, bit x);$/;\"\tp\tsequence:m.s2\ny\tinput.sv\t/^    sequence s2(w, y, bit x);$/;\"\tp\tsequence:m.s2\nx\tinput.sv\t/^    sequence s2(w, y, bit x);$/;\"\tp\tsequence:m.s2\ndelay_arg_example\tinput.sv\t/^    sequence delay_arg_example (max, shortint delay1, delay2, min);$/;\"\tq\tmodule:m\nmax\tinput.sv\t/^    sequence delay_arg_example (max, shortint delay1, delay2, min);$/;\"\tp\tsequence:m.delay_arg_example\ndelay1\tinput.sv\t/^    sequence delay_arg_example (max, shortint delay1, delay2, min);$/;\"\tp\tsequence:m.delay_arg_example\ndelay2\tinput.sv\t/^    sequence delay_arg_example (max, shortint delay1, delay2, min);$/;\"\tp\tsequence:m.delay_arg_example\nmin\tinput.sv\t/^    sequence delay_arg_example (max, shortint delay1, delay2, min);$/;\"\tp\tsequence:m.delay_arg_example\nmy_delay\tinput.sv\t/^    parameter my_delay=2;$/;\"\tc\tmodule:m\nevent_arg_example\tinput.sv\t/^    sequence event_arg_example (event ev);$/;\"\tq\tmodule:m\nev\tinput.sv\t/^    sequence event_arg_example (event ev);$/;\"\tp\tsequence:m.event_arg_example\nevent_arg_example2\tinput.sv\t/^    sequence event_arg_example2 (reg sig);$/;\"\tq\tmodule:m\nsig\tinput.sv\t/^    sequence event_arg_example2 (reg sig);$/;\"\tp\tsequence:m.event_arg_example2\ns\tinput.sv\t/^    sequence s(bit a, bit b);$/;\"\tq\tmodule:m\na\tinput.sv\t/^    sequence s(bit a, bit b);$/;\"\tp\tsequence:m.s\nb\tinput.sv\t/^    sequence s(bit a, bit b);$/;\"\tp\tsequence:m.s\nloc_a\tinput.sv\t/^        bit loc_a;$/;\"\tr\tsequence:m.s\nm\tinput.sv\t/^module m;$/;\"\tm\ns\tinput.sv\t/^    sequence s;$/;\"\tq\tmodule:m\nu\tinput.sv\t/^        logic u, v = a, w = v || b;$/;\"\tr\tsequence:m.s\nv\tinput.sv\t/^        logic u, v = a, w = v || b;$/;\"\tr\tsequence:m.s\nw\tinput.sv\t/^        logic u, v = a, w = v || b;$/;\"\tr\tsequence:m.s\ne\tinput.sv\t/^    property e;$/;\"\tR\tmodule:m\nx\tinput.sv\t/^        int x;$/;\"\tr\tproperty:m.e\nm\tinput.sv\t/^module m;$/;\"\tm\np3\tinput.sv\t/^    property p3;$/;\"\tR\tmodule:m\nc1\tinput.sv\t/^    c1: cover property (@(posedge clk) a #-# p3);$/;\"\tA\tmodule:m\na1\tinput.sv\t/^    a1: assert property (@(posedge clk) a |-> p3);$/;\"\tA\tmodule:m\nm\tinput.sv\t/^module m;$/;\"\tm\np\tinput.sv\t/^    property p;$/;\"\tR\tmodule:m\nv\tinput.sv\t/^        logic v = e;$/;\"\tr\tproperty:m.p\na1\tinput.sv\t/^    a1: assert property (@(posedge clk) f |=> p);$/;\"\tA\tmodule:m\np\tinput.sv\t/^    property p;$/;\"\tR\tmodule:m\nv\tinput.sv\t/^        logic v;$/;\"\tr\tproperty:m.p\nm\tinput.sv\t/^module m;$/;\"\tm\nabc\tinput.sv\t/^    property abc(a, b, c);$/;\"\tR\tmodule:m\na\tinput.sv\t/^    property abc(a, b, c);$/;\"\tp\tproperty:m.abc\nb\tinput.sv\t/^    property abc(a, b, c);$/;\"\tp\tproperty:m.abc\nc\tinput.sv\t/^    property abc(a, b, c);$/;\"\tp\tproperty:m.abc\nenv_prop\tinput.sv\t/^    env_prop: assert property (abc(rst, in1, in2))$/;\"\tA\tmodule:m\nabc\tinput.sv\t/^    property abc(a, b, c);$/;\"\tR\tmodule:m\na\tinput.sv\t/^    property abc(a, b, c);$/;\"\tp\tproperty:m.abc\nb\tinput.sv\t/^    property abc(a, b, c);$/;\"\tp\tproperty:m.abc\nc\tinput.sv\t/^    property abc(a, b, c);$/;\"\tp\tproperty:m.abc\nenv_prop\tinput.sv\t/^        assume property (abc(req, gnt, rst)) else $error(”Assumption failed.”);$/;\"\tA\tmodule:m\na1\tinput.sv\t/^    a1:assume property ( @(posedge clk) req dist {0:=40, 1:=60} ) ;$/;\"\tA\tmodule:m\nproto\tinput.sv\t/^    property proto ;$/;\"\tR\tmodule:m\na1_assertion\tinput.sv\t/^    a1_assertion:assert property ( @(posedge clk) req inside {0, 1} ) ;$/;\"\tA\tmodule:m\nproto_assertion\tinput.sv\t/^    property proto_assertion ;$/;\"\tR\tmodule:m\ntst\tinput.sv\t/^program tst;$/;\"\tP\ndata\tinput.sv\t/^    integer data;$/;\"\tr\tprogram:tst\nwait_for\tinput.sv\t/^    task automatic wait_for( integer value, output bit success );$/;\"\tt\tprogram:tst\nvalue\tinput.sv\t/^    task automatic wait_for( integer value, output bit success );$/;\"\tp\ttask:tst.wait_for\nsuccess\tinput.sv\t/^    task automatic wait_for( integer value, output bit success );$/;\"\tp\ttask:tst.wait_for\nok\tinput.sv\t/^        bit ok;$/;\"\tr\tprogram:tst\nA\tinput.sv\t/^module A;$/;\"\tm\na\tinput.sv\t/^    logic a, clk;$/;\"\tr\tmodule:A\nclk\tinput.sv\t/^    logic a, clk;$/;\"\tr\tmodule:A\ncb_with_input\tinput.sv\t/^    clocking cb_with_input @(posedge clk);$/;\"\tL\tmodule:A\np1\tinput.sv\t/^        property p1;$/;\"\tR\tclocking:A.cb_with_input\ncb_without_input\tinput.sv\t/^    clocking cb_without_input @(posedge clk);$/;\"\tL\tmodule:A\np1\tinput.sv\t/^        property p1;$/;\"\tR\tclocking:A.cb_without_input\np1\tinput.sv\t/^    property p1;$/;\"\tR\tmodule:A\np2\tinput.sv\t/^    property p2;$/;\"\tR\tmodule:A\na1\tinput.sv\t/^    a1: assert property (p1);$/;\"\tA\tmodule:A\na2\tinput.sv\t/^    a2: assert property (cb_with_input.p1);$/;\"\tA\tmodule:A\na3\tinput.sv\t/^    a3: assert property (p2);$/;\"\tA\tmodule:A\na4\tinput.sv\t/^    a4: assert property (cb_without_input.p1);$/;\"\tA\tmodule:A\nuvm_error\tinput.sv\t/^`define uvm_error(id, msg) $display(\"%0t: UVM_ERROR @ %m [%0s] %s\", $time, id, msg);$/;\"\td\nC\tinput.sv\t/^class C;$/;\"\tC\ncheck_transfer_size\tinput.sv\t/^  protected function void check_transfer_size();$/;\"\tf\tclass:C\nassert_transfer_size\tinput.sv\t/^    assert_transfer_size : assert(trans_collected.size == 1) else begin$/;\"\tA\tfunction:C.check_transfer_size\ncheck_transfer_data_size\tinput.sv\t/^  protected function void check_transfer_data_size();$/;\"\tf\tclass:C\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-assertion.d/input.sv",
    "content": "module deffered_assert;\n// LRM 16.3 Immediate assertions\n// LRM 16.4 Deferred assertions\nvar expr;\ninitial begin : deferred_immediate_assertions\n    immediate_assertion : assert (expr) myTask();\n    immediate_cover     : cover (expr) myTask();\n    immediate_assume    : assume (expr) myTask();\n    deferred_assertion1 : assert #0 (expr) myTask();\n    deferred_cover1     : cover #0 (expr) myTask();\n    deferred_assume1    : assume #0 (expr) myTask();\n    deferred_assertion2 : assert final (expr) myTask();\n    deferred_cover2     : cover final (expr) myTask();\n    deferred_assume2    : assume final (expr) myTask();\nend\n\nproperty prop1 (\n    local input int m,\n    logic [1:0] n,\n    int o\n);\n  m;\nendproperty :prop1\n\nproperty prop2 (a, b);\n  a ##1 b;\nendproperty : prop2\n\nconcurrent_assertion1   : assert property (prop2 (l, m));\n\nendmodule\n\nmodule assert_test;\n    // 16.3 Immediate assertions\n    always_comb begin\n        assert_f: assert(f) $info(\"passed\"); else $error(\"failed\");\n        assume_inputs: assume (in_a || in_b) $info(\"assumption holds\");\n        else $error(\"assumption does not hold\");\n        cover_a_and_b: cover (in_a && in_b) $info(\"in_a && in_b == 1 covered\");\n    end\n\n    time t;\n    always @(posedge clk)\n        if (state == REQ)\n            assert (req1 || req2)\n            else begin\n                t = $time;\n                #5 $error(\"assert failed at time %0t\",t);\n            end\n\n    always @(posedge clk) begin\n        assert (myfunc(a,b)) count1 = count + 1; else ->event1;\n        assert (y == 0) else flag = 1;\n    end\n\n    // 16.4.2 Deferred assertion flush points\n    assign not_a = !a;\n    always_comb begin : b1\n        a1: assert (not_a != a);\n        a2: assert #0 (not_a != a); // Should pass once values have settled\n    end\n\n    assign a = '0;\n    assign b = '1;\n    always_comb begin : b1\n        c1: cover (b != a);\n        c2: cover #0 (b != a);\n    end\n\n    function int error_type (int opcode);\n        func_assert: assert (opcode < 64) else $display(\"Opcode error.\");\n        if (opcode < 32)\n            return (0);\n        else\n            return (1);\n        endfunction\n\n        always_comb begin : b1\n            a1: assert #0 (my_cond) else\n            $error(\"Error on operation of type %d\\n\", error_type(opcode));\n            a2: assert #0 (my_cond) else\n            error_type(opcode);\n            //...\n        end\nendmodule\n\nmodule dut(input logic clk, input logic a, input logic b);\n    logic c;\n    always_ff @(posedge clk)\n        c <= b;\n    a1: assert #0 (!(a & c)) $display(\"Pass\"); else $display(\"Fail\");\n    a2: assert final (!(a & c)) $display(\"Pass\"); else $display(\"Fail\");\nendmodule\n\nprogram tb(input logic clk, output logic a, output logic b);\n    default clocking m @(posedge clk);\n        default input #0;\n        default output #0;\n        output a;\n        output b;\n    endclocking\n\n    initial begin\n        a = 1;\n        b = 0;\n        ##10;\n        b = 1;\n        ##1;\n        a = 0;\n    end\nendprogram\n\nmodule sva_svtb;\n    bit clk;\n    logic a, b;\n    // ...\n    dut dut (.*);\n    tb tb (.*);\nendmodule\n\n// 16.4.3 Deferred assertions outside procedural code\nmodule m (input a, b);\n    a1: assert #0 (a == b);\nendmodule\n\n// This is equivalent to the following:\nmodule m (input a, b);\n    always_comb begin\n        a1: assert #0 (a == b);\n    end\nendmodule\n\n// 16.4.4 Disabling deferred assertions\nmodule m (input bad_val, bad_val_ok, a, b, c, clear_b2);\n    always @(bad_val or bad_val_ok) begin : b1\n        a1: assert #0 (bad_val) else $fatal(1, \"Sorry\");\n        if (bad_val_ok) begin\n            disable a1;\n        end\n    end\n\n    always @(a or b or c) begin : b2\n        if (c == 8'hff) begin\n            a2: assert #0 (a && b);\n        end else begin\n         a3: assert #0 (a || b);\n        end\n    end\n\n    always @(clear_b2) begin : b3\n        disable b2;\n    end\nendmodule\n\n// 16.5 Concurrent assertions overview\n// 16.6 Boolean expressions\nmodule m;\n    bit a;\n    integer b;\n    byte q[$];\n    property p1;\n        $rose(a) |-> q[0];\n    endproperty\n    property p2;\n        integer l_b;\n        ($rose(a), l_b = b) |-> ##[3:10] q[l_b];\n    endproperty\n\n    bit [2:0] count;\n    realtime t;\n    initial count = 0;\n    always @(posedge clk) begin\n        if (count == 0) t = $realtime; //capture t in a procedural context\n        count++;\n    end\n\n    property p1;\n        @(posedge clk)\n        count == 7 |-> $realtime - t < 50.5;\n    endproperty\n\n    property p2;\n        realtime l_t;\n        @(posedge clk)\n        (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |->\n          $realtime - l_t < 50.5;\n    endproperty\nendmodule\n\n// 16.7 Sequences\nmodule m;\n    sequence delay_example(x, y, min, max, delay1);\n        x ##delay1 y[*min:max];\n    endsequence\n    // Legal\n    a1: assert property (@(posedge clk) delay_example(x, y, 3, $, 2));\n\n    int z, d;\n    // Illegal: z and d are not elaboration-time constants\n    // a2_illegal: assert property (@(posedge clk) delay_example(x, y, z, $, d));\n\n    sequence s1;\n        @(posedge clk) a ##1 b ##1 c;\n    endsequence\n    sequence s2;\n        @(posedge clk) d ##1 e ##1 f;\n    endsequence\n    sequence s3;\n        @(negedge clk) g ##1 h ##1 i;\n    endsequence\n    sequence s4;\n        @(edge clk) j ##1 k ##1 l;\n    endsequence\n\n    sequence s20_1(data,en);\n        (!frame && (data==data_bus)) ##1 (c_be[0:3] == en);\n    endsequence\n\n    sequence s;\n        a ##1 b ##1 c;\n    endsequence\n    sequence rule;\n        @(posedge sysclk)\n        trans ##1 start_trans ##1 s ##1 end_trans;\n    endsequence\n\n    sequence rule;\n        @(posedge sysclk)\n        trans ##1 start_trans ##1 (a ##1 b ##1 c) ##1 end_trans ;\n    endsequence\n    // sequence s1;\n    //     @(posedge sysclk) (x ##1 s2);\n    // endsequence\n    // sequence s2;\n    //     @(posedge sysclk) (y ##1 s1);\n    // endsequence\nendmodule\n\n// 16.8.1 Typed formal arguments in sequence declarations\nmodule m;\n    sequence s1(w, x, y);\n        w ##1 x ##[2:10] y;\n    endsequence\n    sequence s2(w, y, bit x);\n        w ##1 x ##[2:10] y;\n    endsequence\n\n    cover property (s1(.w(a), .x(bit'(b)), .y(c)));\n    cover property (s2(.w(a), .x(b), .y(c)));\n\n    sequence delay_arg_example (max, shortint delay1, delay2, min);\n        x ##delay1 y[*min:max] ##delay2 z;\n    endsequence\n\n    parameter my_delay=2;\n    cover property (delay_arg_example($, my_delay, my_delay-1, 3));\n\n    cover property (x ##2 y[*3:$] ##1 z);\n\n    sequence event_arg_example (event ev);\n        @(ev) x ##1 y;\n    endsequence\n    cover property (event_arg_example(posedge clk));\n\n    cover property (@(posedge clk) x ##1 y);\n\n    sequence event_arg_example2 (reg sig);\n        @(posedge sig) x ##1 y;\n    endsequence\n    cover property (event_arg_example2(clk));\n\n    cover property (@(posedge clk) x ##1 y);\n\n    sequence s(bit a, bit b);\n        bit loc_a;\n        (1'b1, loc_a = a) ##0\n        (t == loc_a) [*0:$] ##1 b;\n    endsequence\nendmodule\n\n// 16.10 Local variables\nmodule m;\n    sequence s;\n        logic u, v = a, w = v || b;\n        // ...\n        v ##1 w;\n    endsequence\n\n    property e;\n        int x;\n        (valid_in, x = pipe_in) |-> ##5 (pipe_out1 == (x+1));\n    endproperty\nendmodule\n\n// 16.12 Declaring properties\nmodule m;\n    // 16.12.2 Sequence property\n    property p3;\n        b ##1 c;\n    endproperty\n    c1: cover property (@(posedge clk) a #-# p3);\n    a1: assert property (@(posedge clk) a |-> p3);\nendmodule\n\n// 16.13.7 Local variable initialization assignments\nmodule m;\n    property p;\n        logic v = e;\n        (@(posedge clk1) (a == v)[*1:$] |-> b)\n        and\n        (@(posedge clk2) c[*1:$] |-> d == v)\n        ;\n    endproperty\n    a1: assert property (@(posedge clk) f |=> p);\n\n    property p;\n        logic v;\n        (@(posedge clk1) (1, v = e) ##0 (a == v)[*1:$] |-> b)\n        and\n        (@(posedge clk2) (1, v = e) ##0 c[*1:$] |-> d == v)\n        ;\n    endproperty\nendmodule\n\n// 16.14 Concurrent assertions\nmodule m;\n    // 16.14.1 Assert statement\n    property abc(a, b, c);\n        disable iff (a==2) @(posedge clk) not (b ##1 c);\n    endproperty\n    env_prop: assert property (abc(rst, in1, in2))\n    $display(\"env_prop passed.\"); else $display(\"env_prop failed.\");\n\n    // 16.14.2 Assume statement\n    property abc(a, b, c);\n        disable iff (c) @(posedge clk) a |=> b;\n    endproperty\n    env_prop:\n        assume property (abc(req, gnt, rst)) else $error(”Assumption failed.”);\n\n    a1:assume property ( @(posedge clk) req dist {0:=40, 1:=60} ) ;\n    property proto ;\n        @(posedge clk) req |-> req[*1:$] ##0 ack;\n    endproperty\n\n    a1_assertion:assert property ( @(posedge clk) req inside {0, 1} ) ;\n    property proto_assertion ;\n        @(posedge clk) req |-> req[*1:$] ##0 ack;\n    endproperty\n\n    // 16.14.3 Cover statement\n    // 16.14.4 Restrict statement\n    restrict property (@(posedge clk) ctr == '0);\nendmodule\n\n// 16.17 Expect statement\nprogram tst;\n    initial begin\n        # 200ms;\n        expect( @(posedge clk) a ##1 b ##1 c ) else $error( \"expect failed\" );\n        // ABC: d...\n    end\n\n    integer data;\n    //...\n    task automatic wait_for( integer value, output bit success );\n        expect( @(posedge clk) ##[1:10] data == value ) success = 1;\n        else success = 0;\n    endtask\n\n    initial begin\n        bit ok;\n        wait_for( 23, ok ); // wait for the value 23\n        // ...\n    end\nendprogram\n\n// 16.18 Clocking blocks and concurrent assertions\nmodule A;\n    logic a, clk;\n\n    clocking cb_with_input @(posedge clk);\n        input a;\n        property p1;\n            a;\n        endproperty\n    endclocking\n\n    clocking cb_without_input @(posedge clk);\n        property p1;\n            a;\n        endproperty\n    endclocking\n\n    property p1;\n        @(posedge clk) a;\n    endproperty\n\n    property p2;\n        @(posedge clk) cb_with_input.a;\n    endproperty\n\n    a1: assert property (p1);\n    a2: assert property (cb_with_input.p1);\n    a3: assert property (p2);\n    a4: assert property (cb_without_input.p1);\nendmodule\n\n// original test\n// excerpt from UVM 1.2:examples/integrated/ubus/sv/ubus_slave_monitor.sv\n`define uvm_error(id, msg) $display(\"%0t: UVM_ERROR @ %m [%0s] %s\", $time, id, msg);\nclass C;\n  protected function void check_transfer_size();\n    assert_transfer_size : assert(trans_collected.size == 1) else begin\n      `uvm_error(get_type_name(),\n        \"Invalid transfer size!\")\n    end\n  endfunction : check_transfer_size\n\n  // check_transfer_data_size\n  protected function void check_transfer_data_size();\n  endfunction : check_transfer_data_size\n\nendclass : C\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-assertion.d/validator",
    "content": "KNOWN-INVALIDATION\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-assignment.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-assignment.d/expected.tags",
    "content": "assignment\tinput.sv\t/^module assignment;$/;\"\tm\nbar\tinput.sv\t/^  function int bar();$/;\"\tf\tmodule:assignment\nmsg\tinput.sv\t/^  string msg = $sformatf(\"GP miscompare between '%s' and '%s':\\\\nlhs = %s\\\\nrhs = %s\",$/;\"\tr\tmodule:assignment\nunpackedbits\tinput.sv\t/^  bit unpackedbits [1:0] = '{1,1};$/;\"\tr\tmodule:assignment\nunpackedints\tinput.sv\t/^  int unpackedints [1:0] = '{1'b1, 1'b1};$/;\"\tr\tmodule:assignment\ny\tinput.sv\t/^  int y;$/;\"\tr\tmodule:assignment\nunpackedints2\tinput.sv\t/^  int unpackedints2 [1:0] = '{2 {y}};$/;\"\tr\tmodule:assignment\nn\tinput.sv\t/^  int n[1:2][1:3] = '{2{'{3{y}}}};$/;\"\tr\tmodule:assignment\nabkey\tinput.sv\t/^  struct {int a; time b;} abkey[1:0];$/;\"\tS\tmodule:assignment\na\tinput.sv\t/^  struct {int a; time b;} abkey[1:0];$/;\"\tw\tstruct:assignment.abkey\nb\tinput.sv\t/^  struct {int a; time b;} abkey[1:0];$/;\"\tw\tstruct:assignment.abkey\nabkey_fun\tinput.sv\t/^  struct {int a; time b;} abkey_fun[1:0] = '{'{a:bar(), b:2ns}, '{int:5, time:$time}};$/;\"\tS\tmodule:assignment\na\tinput.sv\t/^  struct {int a; time b;} abkey_fun[1:0] = '{'{a:bar(), b:2ns}, '{int:5, time:$time}};$/;\"\tw\tstruct:assignment.abkey_fun\nb\tinput.sv\t/^  struct {int a; time b;} abkey_fun[1:0] = '{'{a:bar(), b:2ns}, '{int:5, time:$time}};$/;\"\tw\tstruct:assignment.abkey_fun\nst\tinput.sv\t/^  } st;$/;\"\tT\tmodule:assignment\nx\tinput.sv\t/^    int x;$/;\"\tw\ttypedef:assignment.st\ny\tinput.sv\t/^    int y;$/;\"\tw\ttypedef:assignment.st\nk\tinput.sv\t/^  int k = 1;$/;\"\tr\tmodule:assignment\ns1\tinput.sv\t/^  st s1 = '{1, 2+k}; \\/\\/ by position;$/;\"\tr\tmodule:assignment\ns2\tinput.sv\t/^  st s2 = '{x:2, y:3+k}; \\/\\/ by name$/;\"\tr\tmodule:assignment\ns3\tinput.sv\t/^  struct { int x; int y; } s3 = '{1, 2+k};$/;\"\tS\tmodule:assignment\nx\tinput.sv\t/^  struct { int x; int y; } s3 = '{1, 2+k};$/;\"\tw\tstruct:assignment.s3\ny\tinput.sv\t/^  struct { int x; int y; } s3 = '{1, 2+k};$/;\"\tw\tstruct:assignment.s3\ns4\tinput.sv\t/^  struct { int x; int y; } s4 = '{x:2, y:3+k};$/;\"\tS\tmodule:assignment\nx\tinput.sv\t/^  struct { int x; int y; } s4 = '{x:2, y:3+k};$/;\"\tw\tstruct:assignment.s4\ny\tinput.sv\t/^  struct { int x; int y; } s4 = '{x:2, y:3+k};$/;\"\tw\tstruct:assignment.s4\ns5\tinput.sv\t/^  st s5 = '{default:2};$/;\"\tr\tmodule:assignment\nab\tinput.sv\t/^  typedef struct { int a; shortreal b; } ab;  \\/\\/ LRM 5.10$/;\"\tT\tmodule:assignment\na\tinput.sv\t/^  typedef struct { int a; shortreal b; } ab;  \\/\\/ LRM 5.10$/;\"\tw\ttypedef:assignment.ab\nb\tinput.sv\t/^  typedef struct { int a; shortreal b; } ab;  \\/\\/ LRM 5.10$/;\"\tw\ttypedef:assignment.ab\nabkey\tinput.sv\t/^  ab abkey[1:0] = '{'{a:1, b:1.0}, '{int:2, shortreal:2.0}};$/;\"\tr\tmodule:assignment\nABC\tinput.sv\t/^  } ABC, DEF;$/;\"\tS\tmodule:assignment\nA\tinput.sv\t/^    int A;$/;\"\tw\tstruct:assignment.ABC\nBC1\tinput.sv\t/^    } BC1, BC2;$/;\"\tw\tstruct:assignment.ABC\nBC2\tinput.sv\t/^    } BC1, BC2;$/;\"\tw\tstruct:assignment.ABC\nDEF\tinput.sv\t/^  } ABC, DEF;$/;\"\tS\tmodule:assignment\nA\tinput.sv\t/^    int A;$/;\"\tw\tstruct:assignment.DEF\nBC1\tinput.sv\t/^    } BC1, BC2;$/;\"\tw\tstruct:assignment.DEF\nBC2\tinput.sv\t/^    } BC1, BC2;$/;\"\tw\tstruct:assignment.DEF\nsa\tinput.sv\t/^  } sa;$/;\"\tT\tmodule:assignment\na\tinput.sv\t/^    logic [7:0] a;$/;\"\tw\ttypedef:assignment.sa\nb\tinput.sv\t/^    bit b;$/;\"\tw\ttypedef:assignment.sa\nc\tinput.sv\t/^    bit signed [31:0] c;$/;\"\tw\ttypedef:assignment.sa\ns\tinput.sv\t/^    string s;$/;\"\tw\ttypedef:assignment.sa\ns2\tinput.sv\t/^  sa s2 = '{int:1, default:0, string:\"\"};$/;\"\tr\tmodule:assignment\nA3\tinput.sv\t/^  int A3[1:3];$/;\"\tr\tmodule:assignment\nAI3\tinput.sv\t/^  typedef int AI3[1:3];$/;\"\tT\tmodule:assignment\nA3\tinput.sv\t/^  AI3 A3;$/;\"\tr\tmodule:assignment\nA9\tinput.sv\t/^  int A9[1:9];$/;\"\tr\tmodule:assignment\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-assignment.d/input.sv",
    "content": "module assignment;\n\n  function int bar();\n    return 0;\n  endfunction\n\n  // src/tlm2/uvm_tlm2_generic_payload.svh:494\n  string msg = $sformatf(\"GP miscompare between '%s' and '%s':\\nlhs = %s\\nrhs = %s\",\n                         bar(), 1, 2, 3);\n\n  // LRM 10.9.1 Array assignment patterns\n  bit unpackedbits [1:0] = '{1,1};\n  int unpackedints [1:0] = '{1'b1, 1'b1};\n  int y;\n  int unpackedints2 [1:0] = '{2 {y}};\n  int n[1:2][1:3] = '{2{'{3{y}}}};\n\n  struct {int a; time b;} abkey[1:0];\n  abkey = '{'{a:1, b:2ns}, '{int:5, time:$time}};\n\n  struct {int a; time b;} abkey_fun[1:0] = '{'{a:bar(), b:2ns}, '{int:5, time:$time}};\n\n  // LRM 10.9.2 Structure assignment patterns\n  typedef struct {\n    int x;\n    int y;\n  } st;\n  int k = 1;\n  st s1 = '{1, 2+k}; // by position;\n  st s2 = '{x:2, y:3+k}; // by name\n  struct { int x; int y; } s3 = '{1, 2+k};\n  struct { int x; int y; } s4 = '{x:2, y:3+k};\n\n  st s5 = '{default:2};\n\n  typedef struct { int a; shortreal b; } ab;  // LRM 5.10\n  ab abkey[1:0] = '{'{a:1, b:1.0}, '{int:2, shortreal:2.0}};\n\n  struct {\n    int A;\n    struct {\n      int B, C;\n    } BC1, BC2;\n  } ABC, DEF;\n  ABC = '{A:1, BC1:'{B:2, C:3}, BC2:'{B:4,C:5}};\n  DEF = '{default:10};\n\n  typedef struct {\n    logic [7:0] a;\n    bit b;\n    bit signed [31:0] c;\n    string s;\n  } sa;\n  sa s2 = '{int:1, default:0, string:\"\"};\n\n  // LRM 10.10 Unpacked array concatenation\n  int A3[1:3];\n  A3 = {1, 2, 3}; // unpacked array concatenation: A3[1]=1, A3[2]=2, A3[3]=3\n  A3 = '{1, 2, 3}; // array assignment pattern: A3[1]=1, A3[2]=2, A3[3]=3\n\n  typedef int AI3[1:3];\n  AI3 A3;\n  int A9[1:9];\n  A3 = '{1, 2, 3};\n  A9 = {A3, 4, 5, A3, 6}; // legal, gives A9='{1,2,3,4,5,1,2,3,6}\n  A9 = '{9{1}}; // legal, gives A9='{1,1,1,1,1,1,1,1,1}\n  // array concatenation\n  A9 = {A3, 4, AI3'{5, 6, 7}, 8, 9}; // legal, A9='{1,2,3,4,5,6,7,8,9}\n\nendmodule\n\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-assignment.d/validator",
    "content": "KNOWN-INVALIDATION\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-basic.d/args.ctags",
    "content": "--extras=+q\n--kinds-systemverilog=+Q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-basic.d/expected.tags",
    "content": "DEFINE\tinput.sv\t/^`define DEFINE$/;\"\td\nDEF_WITH_EQ\tinput.sv\t/^`define DEF_WITH_EQ = 1'd100$/;\"\td\nDEF_VALUE\tinput.sv\t/^`define DEF_VALUE   1'd100$/;\"\td\ntest\tinput.sv\t/^class test;$/;\"\tC\na\tinput.sv\t/^    reg a;$/;\"\tr\tclass:test\ntest.a\tinput.sv\t/^    reg a;$/;\"\tr\tclass:test\nb\tinput.sv\t/^    logic b;$/;\"\tr\tclass:test\ntest.b\tinput.sv\t/^    logic b;$/;\"\tr\tclass:test\nc\tinput.sv\t/^    bit [1:0] c[3] = '{0, 0, 0};$/;\"\tr\tclass:test\ntest.c\tinput.sv\t/^    bit [1:0] c[3] = '{0, 0, 0};$/;\"\tr\tclass:test\nmult\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tf\tclass:test\ntest.mult\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tf\tclass:test\na\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:test.mult\ntest.mult.a\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:test.mult\nb\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:test.mult\ntest.mult.b\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:test.mult\nextern_func\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tQ\tclass:test\ntest.extern_func\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tQ\tclass:test\na\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tp\tprototype:test.extern_func\ntest.extern_func.a\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tp\tprototype:test.extern_func\nb\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tp\tprototype:test.extern_func\ntest.extern_func.b\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tp\tprototype:test.extern_func\nmod\tinput.sv\t/^module mod#($/;\"\tm\nPARAM1\tinput.sv\t/^    parameter PARAM1 = 10,$/;\"\tc\tmodule:mod\nmod.PARAM1\tinput.sv\t/^    parameter PARAM1 = 10,$/;\"\tc\tmodule:mod\nPARAM2\tinput.sv\t/^    parameter PARAM2 = 2.0$/;\"\tc\tmodule:mod\nmod.PARAM2\tinput.sv\t/^    parameter PARAM2 = 2.0$/;\"\tc\tmodule:mod\na\tinput.sv\t/^    input wire a,$/;\"\tp\tmodule:mod\nmod.a\tinput.sv\t/^    input wire a,$/;\"\tp\tmodule:mod\nb\tinput.sv\t/^    b,c,$/;\"\tp\tmodule:mod\nmod.b\tinput.sv\t/^    b,c,$/;\"\tp\tmodule:mod\nc\tinput.sv\t/^    b,c,$/;\"\tp\tmodule:mod\nmod.c\tinput.sv\t/^    b,c,$/;\"\tp\tmodule:mod\nd\tinput.sv\t/^    d ,$/;\"\tp\tmodule:mod\nmod.d\tinput.sv\t/^    d ,$/;\"\tp\tmodule:mod\ne\tinput.sv\t/^    output wire e ,$/;\"\tp\tmodule:mod\nmod.e\tinput.sv\t/^    output wire e ,$/;\"\tp\tmodule:mod\nf\tinput.sv\t/^    output reg f,$/;\"\tp\tmodule:mod\nmod.f\tinput.sv\t/^    output reg f,$/;\"\tp\tmodule:mod\ng\tinput.sv\t/^    inout wire g$/;\"\tp\tmodule:mod\nmod.g\tinput.sv\t/^    inout wire g$/;\"\tp\tmodule:mod\nLOCALPARAM\tinput.sv\t/^localparam LOCALPARAM = 2**2;$/;\"\tc\tmodule:mod\nmod.LOCALPARAM\tinput.sv\t/^localparam LOCALPARAM = 2**2;$/;\"\tc\tmodule:mod\nSTATE1\tinput.sv\t/^localparam STATE1 = 4'h0,$/;\"\tc\tmodule:mod\nmod.STATE1\tinput.sv\t/^localparam STATE1 = 4'h0,$/;\"\tc\tmodule:mod\nSTATE2\tinput.sv\t/^           STATE2 = 4'h1,$/;\"\tc\tmodule:mod\nmod.STATE2\tinput.sv\t/^           STATE2 = 4'h1,$/;\"\tc\tmodule:mod\nSTATE3\tinput.sv\t/^           STATE3 = 4'h2,$/;\"\tc\tmodule:mod\nmod.STATE3\tinput.sv\t/^           STATE3 = 4'h2,$/;\"\tc\tmodule:mod\nSTATE4\tinput.sv\t/^           STATE4 = 4'h5    ,$/;\"\tc\tmodule:mod\nmod.STATE4\tinput.sv\t/^           STATE4 = 4'h5    ,$/;\"\tc\tmodule:mod\nSTATE5\tinput.sv\t/^           STATE5 = 4'h6    ,$/;\"\tc\tmodule:mod\nmod.STATE5\tinput.sv\t/^           STATE5 = 4'h6    ,$/;\"\tc\tmodule:mod\nSTATE6\tinput.sv\t/^           STATE6 = 4'h7    ,$/;\"\tc\tmodule:mod\nmod.STATE6\tinput.sv\t/^           STATE6 = 4'h7    ,$/;\"\tc\tmodule:mod\nSTATE7\tinput.sv\t/^           STATE7 = 4'h8;$/;\"\tc\tmodule:mod\nmod.STATE7\tinput.sv\t/^           STATE7 = 4'h8;$/;\"\tc\tmodule:mod\nk\tinput.sv\t/^real k;$/;\"\tr\tmodule:mod\nmod.k\tinput.sv\t/^real k;$/;\"\tr\tmodule:mod\nl\tinput.sv\t/^integer l;$/;\"\tr\tmodule:mod\nmod.l\tinput.sv\t/^integer l;$/;\"\tr\tmodule:mod\nt\tinput.sv\t/^test t;$/;\"\tr\tmodule:mod\nmod.t\tinput.sv\t/^test t;$/;\"\tr\tmodule:mod\nadd\tinput.sv\t/^task add ($/;\"\tt\tmodule:mod\nmod.add\tinput.sv\t/^task add ($/;\"\tt\tmodule:mod\nx\tinput.sv\t/^    input x, y$/;\"\tp\ttask:mod.add\nmod.add.x\tinput.sv\t/^    input x, y$/;\"\tp\ttask:mod.add\ny\tinput.sv\t/^    input x, y$/;\"\tp\ttask:mod.add\nmod.add.y\tinput.sv\t/^    input x, y$/;\"\tp\ttask:mod.add\nz\tinput.sv\t/^    ,output z$/;\"\tp\ttask:mod.add\nmod.add.z\tinput.sv\t/^    ,output z$/;\"\tp\ttask:mod.add\nmult\tinput.sv\t/^function mult ($/;\"\tf\tmodule:mod\nmod.mult\tinput.sv\t/^function mult ($/;\"\tf\tmodule:mod\nx\tinput.sv\t/^    input x,$/;\"\tp\tfunction:mod.mult\nmod.mult.x\tinput.sv\t/^    input x,$/;\"\tp\tfunction:mod.mult\ny\tinput.sv\t/^    input y);$/;\"\tp\tfunction:mod.mult\nmod.mult.y\tinput.sv\t/^    input y);$/;\"\tp\tfunction:mod.mult\ntemp\tinput.sv\t/^    reg temp;$/;\"\tr\tfunction:mod.mult\nmod.mult.temp\tinput.sv\t/^    reg temp;$/;\"\tr\tfunction:mod.mult\nref_test\tinput.sv\t/^function ref_test ($/;\"\tf\tmodule:mod\nmod.ref_test\tinput.sv\t/^function ref_test ($/;\"\tf\tmodule:mod\ntref1\tinput.sv\t/^    ref tref1,$/;\"\tp\tfunction:mod.ref_test\nmod.ref_test.tref1\tinput.sv\t/^    ref tref1,$/;\"\tp\tfunction:mod.ref_test\ntref2\tinput.sv\t/^    ref logic tref2$/;\"\tp\tfunction:mod.ref_test\nmod.ref_test.tref2\tinput.sv\t/^    ref logic tref2$/;\"\tp\tfunction:mod.ref_test\nmynet\tinput.sv\t/^wire [PARAM1-1:0] mynet;$/;\"\tn\tmodule:mod\nmod.mynet\tinput.sv\t/^wire [PARAM1-1:0] mynet;$/;\"\tn\tmodule:mod\ngencnt\tinput.sv\t/^genvar gencnt;$/;\"\tr\tmodule:mod\nmod.gencnt\tinput.sv\t/^genvar gencnt;$/;\"\tr\tmodule:mod\narray\tinput.sv\t/^    for (gencnt = 0; gencnt < PARAM1; gencnt = gencnt + 1) begin: array$/;\"\tb\tmodule:mod\nmod.array\tinput.sv\t/^    for (gencnt = 0; gencnt < PARAM1; gencnt = gencnt + 1) begin: array$/;\"\tb\tmodule:mod\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-basic.d/input.sv",
    "content": "// Include module declaration in a comment\n// module wrong;\n// endmodule\n`define DEFINE\n`define DEF_WITH_EQ = 1'd100\n`define DEF_VALUE   1'd100\n\nclass test;\n    reg a;\n    logic b;\n    bit [1:0] c[3] = '{0, 0, 0};\n\n    function mult (a, input b = 0);\n        return a * b;\n    endfunction : mult\n\n    extern virtual function void extern_func (input bit a, input b);\n\nendclass : test\n\nmodule mod#(\n    parameter PARAM1 = 10,\n    parameter PARAM2 = 2.0\n) (\n    input wire a,\n    b,c,\n    d ,\n    output wire e ,\n    `ifndef DEFINE\n    output reg f,\n    `endif\n    inout wire g\n);\n\nlocalparam LOCALPARAM = 2**2;\n\nlocalparam STATE1 = 4'h0,\n           STATE2 = 4'h1,\n           STATE3 = 4'h2,\n           STATE4 = 4'h5    ,\n           STATE5 = 4'h6    ,\n           STATE6 = 4'h7    ,\n           STATE7 = 4'h8;\n\nreal k;\ninteger l;\ntest t;\n\ntask add (\n    input x, y\n    `ifdef DEFINE\n    ,output z\n    `endif\n);\n    z = x + y;\nendtask\n\nfunction mult (\n    `ifdef DEFINE\n    input x,\n    `endif\n    input y);\n    reg temp;\n    temp = x * y;\n    return temp;\nendfunction\n\nfunction ref_test (\n    ref tref1,\n    // ref wire tref2  /* Nets shall not be passed by reference. */\n    ref logic tref2\n    );\nendfunction\n\nwire [PARAM1-1:0] mynet;\n\ngenvar gencnt;\ngenerate\n    for (gencnt = 0; gencnt < PARAM1; gencnt = gencnt + 1) begin: array\n        assign mynet[gencnt] = 1'b0;\n    end\nendgenerate\n\nendmodule // mod\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-block.d/args.ctags",
    "content": "--sort=no\n--fields-SystemVerilog=+{parameter}\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-block.d/expected.tags",
    "content": "test\tinput.sv\t/^module test;$/;\"\tm\nr\tinput.sv\t/^  logic r;$/;\"\tr\tmodule:test\nenable_a\tinput.sv\t/^  event enable_a, enable_b;$/;\"\te\tmodule:test\nenable_b\tinput.sv\t/^  event enable_a, enable_b;$/;\"\te\tmodule:test\nwa\tinput.sv\t/^  logic wa, wb;$/;\"\tr\tmodule:test\nwb\tinput.sv\t/^  logic wa, wb;$/;\"\tr\tmodule:test\nta\tinput.sv\t/^  time  ta, tb;$/;\"\tr\tmodule:test\ntb\tinput.sv\t/^  time  ta, tb;$/;\"\tr\tmodule:test\nfork_1\tinput.sv\t/^    fork: fork_1$/;\"\tb\tmodule:test\nblock1\tinput.sv\t/^module block1 #(N_IF = 8) ($/;\"\tm\nN_IF\tinput.sv\t/^module block1 #(N_IF = 8) ($/;\"\tc\tmodule:block1\tparameter:\nclk\tinput.sv\t/^  input logic clk, rst_n$/;\"\tp\tmodule:block1\nrst_n\tinput.sv\t/^  input logic clk, rst_n$/;\"\tp\tmodule:block1\nb_g1\tinput.sv\t/^  generate for (genvar gi = 0; gi < N_IF; ++gi) begin : b_g1$/;\"\tb\tmodule:block1\na\tinput.sv\t/^      logic a;$/;\"\tr\tblock:block1.b_g1\nvar_b_g\tinput.sv\t/^    logic var_b_g;$/;\"\tr\tblock:block1.b_g1\nb_g2\tinput.sv\t/^  for (genvar gi = 0; gi < N_IF; ++gi) begin : b_g2$/;\"\tb\tmodule:block1\nb1\tinput.sv\t/^    always_comb begin:b1$/;\"\tb\tblock:block1.b_g2\nlb1\tinput.sv\t/^        logic lb1;$/;\"\tr\tblock:block1.b_g2.b1\nb2_1\tinput.sv\t/^        begin :b2_1$/;\"\tb\tblock:block1.b_g2.b1\nlb2\tinput.sv\t/^          logic lb2;$/;\"\tr\tblock:block1.b_g2.b1.b2_1\nb2_2\tinput.sv\t/^        begin :b2_2$/;\"\tb\tblock:block1.b_g2.b1\nlb2\tinput.sv\t/^          logic lb2;$/;\"\tr\tblock:block1.b_g2.b1.b2_2\nvar_b_g\tinput.sv\t/^    logic var_b_g;$/;\"\tr\tblock:block1.b_g2\nnested_block\tinput.sv\t/^class nested_block;$/;\"\tC\nfunc\tinput.sv\t/^  function void func (input logic a, b);$/;\"\tf\tclass:nested_block\na\tinput.sv\t/^  function void func (input logic a, b);$/;\"\tp\tfunction:nested_block.func\nb\tinput.sv\t/^  function void func (input logic a, b);$/;\"\tp\tfunction:nested_block.func\nouter_block\tinput.sv\t/^    if (a) begin : outer_block$/;\"\tb\tfunction:nested_block.func\ninner_block\tinput.sv\t/^      if (b) begin : inner_block$/;\"\tb\tblock:nested_block.func.outer_block\np\tinput.sv\t/^  logic p; \\/\\/ class:nested_block$/;\"\tr\tclass:nested_block\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-block.d/input.sv",
    "content": "//\n// block test\n//\n\n// LRM 9.3.2 Parallel blocks\nmodule test;\n  logic r;\n  initial begin\n    fork\n      #50 r = 'h35;\n      #100 r = 'hE2;\n      #150 r = 'h00;\n      #200 r = 'hF7;\n    join\n  end\n\n  event enable_a, enable_b;\n  logic wa, wb;\n  time  ta, tb;\n  initial\n    fork: fork_1\n      @enable_a\n      begin\n        #ta wa = 0;\n        #ta wa = 1;\n        #ta wa = 0;\n      end\n      @enable_b\n      begin\n        #tb wb = 1;\n        #tb wb = 0;\n        #tb wb = 1;\n      end\n    join\nendmodule\n\n// LRM 9.3.4 Block names\n\n// orignal tests\nmodule block1 #(N_IF = 8) (\n  input logic clk, rst_n\n);\n  generate for (genvar gi = 0; gi < N_IF; ++gi) begin : b_g1\n\n    always_ff @(posedge clk, negedge rst_n) begin\n      logic a;\n      if (~rst_n) begin\n        ;\n      end\n    end\n    logic var_b_g;\n\n  end endgenerate\n\n  for (genvar gi = 0; gi < N_IF; ++gi) begin : b_g2\n\n    always_comb begin:b1\n        logic lb1;\n        begin :b2_1\n          logic lb2;\n        end:b2_1\n        begin :b2_2\n          logic lb2;\n        end:b2_2\n    end : b1\n    logic var_b_g;\n\n  end : b_g2\n\nendmodule : block1\n\n// fixed by sv-kind-fixes\nclass nested_block;\n  function void func (input logic a, b);\n    if (a) begin : outer_block\n      if (b) begin : inner_block\n        ;\n      end : inner_block\n    end // no block label\n  endfunction\n\n  logic p; // class:nested_block\nendclass : nested_block\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-checker.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-checker.d/expected.tags",
    "content": "my_check1\tinput.sv\t/^checker my_check1 (logic test_sig, event clock);$/;\"\tH\ntest_sig\tinput.sv\t/^checker my_check1 (logic test_sig, event clock);$/;\"\tp\tchecker:my_check1\nclock\tinput.sv\t/^checker my_check1 (logic test_sig, event clock);$/;\"\tp\tchecker:my_check1\np\tinput.sv\t/^    property p(logic sig);$/;\"\tR\tchecker:my_check1\nsig\tinput.sv\t/^    property p(logic sig);$/;\"\tp\tproperty:my_check1.p\na1\tinput.sv\t/^    a1: assert property (p (test_sig));$/;\"\tA\tchecker:my_check1\nc1\tinput.sv\t/^    c1: cover property (!test_sig ##1 test_sig);$/;\"\tA\tchecker:my_check1\nmy_check2\tinput.sv\t/^checker my_check2 (logic a, b);$/;\"\tH\na\tinput.sv\t/^checker my_check2 (logic a, b);$/;\"\tp\tchecker:my_check2\nb\tinput.sv\t/^checker my_check2 (logic a, b);$/;\"\tp\tchecker:my_check2\na1\tinput.sv\t/^    a1: assert #0 ($onehot0({a, b}));$/;\"\tA\tchecker:my_check2\nc1\tinput.sv\t/^    c1: cover #0 (a == 0 && b == 0);$/;\"\tA\tchecker:my_check2\nc2\tinput.sv\t/^    c2: cover #0 (a == 1);$/;\"\tA\tchecker:my_check2\nc3\tinput.sv\t/^    c3: cover #0 (b == 1);$/;\"\tA\tchecker:my_check2\nmy_check3\tinput.sv\t/^checker my_check3 (logic a, b, event clock, output bit failure, undef);$/;\"\tH\na\tinput.sv\t/^checker my_check3 (logic a, b, event clock, output bit failure, undef);$/;\"\tp\tchecker:my_check3\nb\tinput.sv\t/^checker my_check3 (logic a, b, event clock, output bit failure, undef);$/;\"\tp\tchecker:my_check3\nclock\tinput.sv\t/^checker my_check3 (logic a, b, event clock, output bit failure, undef);$/;\"\tp\tchecker:my_check3\nfailure\tinput.sv\t/^checker my_check3 (logic a, b, event clock, output bit failure, undef);$/;\"\tp\tchecker:my_check3\nundef\tinput.sv\t/^checker my_check3 (logic a, b, event clock, output bit failure, undef);$/;\"\tp\tchecker:my_check3\na1\tinput.sv\t/^    a1: assert property ($onehot0({a, b})) failure = 1'b0; else failure = 1'b1;$/;\"\tA\tchecker:my_check3\na2\tinput.sv\t/^    a2: assert property ($isunknown({a, b})) undef = 1'b0; else undef = 1'b1;$/;\"\tA\tchecker:my_check3\nmy_check4\tinput.sv\t/^checker my_check4 (input logic in,$/;\"\tH\nin\tinput.sv\t/^checker my_check4 (input logic in,$/;\"\tp\tchecker:my_check4\nen\tinput.sv\t/^                   en = 1'b1, \\/\\/ default value$/;\"\tp\tchecker:my_check4\nclock\tinput.sv\t/^                   event clock,$/;\"\tp\tchecker:my_check4\nctr\tinput.sv\t/^                   output int ctr = 0); \\/\\/ initial value$/;\"\tp\tchecker:my_check4\na1\tinput.sv\t/^    a1: assert property (ctr < 5);$/;\"\tA\tchecker:my_check4\nm\tinput.sv\t/^module m;$/;\"\tm\nc1\tinput.sv\t/^    checker c1;$/;\"\tH\tmodule:m\nc2\tinput.sv\t/^    checker c2;$/;\"\tH\tmodule:m\nmutex\tinput.sv\t/^checker mutex (logic [31:0] sig, event clock, output bit failure);$/;\"\tH\nsig\tinput.sv\t/^checker mutex (logic [31:0] sig, event clock, output bit failure);$/;\"\tp\tchecker:mutex\nclock\tinput.sv\t/^checker mutex (logic [31:0] sig, event clock, output bit failure);$/;\"\tp\tchecker:mutex\nfailure\tinput.sv\t/^checker mutex (logic [31:0] sig, event clock, output bit failure);$/;\"\tp\tchecker:mutex\nm\tinput.sv\t/^module m(wire [31:0] bus, logic clk);$/;\"\tm\nbus\tinput.sv\t/^module m(wire [31:0] bus, logic clk);$/;\"\tp\tmodule:m\nclk\tinput.sv\t/^module m(wire [31:0] bus, logic clk);$/;\"\tp\tmodule:m\nres\tinput.sv\t/^    logic res, scan;$/;\"\tr\tmodule:m\nscan\tinput.sv\t/^    logic res, scan;$/;\"\tr\tmodule:m\ncheck_bus\tinput.sv\t/^    mutex check_bus(bus, posedge clk, res);$/;\"\ti\tmodule:m\ttyperef:module:mutex\nc1\tinput.sv\t/^checker c1(event clk, logic[7:0] a, b);$/;\"\tH\nclk\tinput.sv\t/^checker c1(event clk, logic[7:0] a, b);$/;\"\tp\tchecker:c1\na\tinput.sv\t/^checker c1(event clk, logic[7:0] a, b);$/;\"\tp\tchecker:c1\nb\tinput.sv\t/^checker c1(event clk, logic[7:0] a, b);$/;\"\tp\tchecker:c1\nMAX_SUM\tinput.sv\t/^    `define MAX_SUM 8$/;\"\td\nsum\tinput.sv\t/^    logic [7:0] sum;$/;\"\tr\tchecker:c1\np0\tinput.sv\t/^        p0: assert property (sum < `MAX_SUM);$/;\"\tA\tchecker:c1\np1\tinput.sv\t/^    p1: assert property (@clk sum < `MAX_SUM);$/;\"\tA\tchecker:c1\np2\tinput.sv\t/^    p2: assert property (@clk a != b);$/;\"\tA\tchecker:c1\np3\tinput.sv\t/^    p3: assert #0 ($onehot(a));$/;\"\tA\tchecker:c1\nm\tinput.sv\t/^module m(input logic rst, clk, logic en, logic[7:0] in1, in2,$/;\"\tm\nrst\tinput.sv\t/^module m(input logic rst, clk, logic en, logic[7:0] in1, in2,$/;\"\tp\tmodule:m\nclk\tinput.sv\t/^module m(input logic rst, clk, logic en, logic[7:0] in1, in2,$/;\"\tp\tmodule:m\nen\tinput.sv\t/^module m(input logic rst, clk, logic en, logic[7:0] in1, in2,$/;\"\tp\tmodule:m\nin1\tinput.sv\t/^module m(input logic rst, clk, logic en, logic[7:0] in1, in2,$/;\"\tp\tmodule:m\nin2\tinput.sv\t/^module m(input logic rst, clk, logic en, logic[7:0] in1, in2,$/;\"\tp\tmodule:m\nin_array\tinput.sv\t/^         in_array [20:0]);$/;\"\tp\tmodule:m\ncheck_outside\tinput.sv\t/^    c1 check_outside(posedge clk, in1, in2);$/;\"\ti\tmodule:m\ttyperef:module:c1\nv1\tinput.sv\t/^        automatic logic [7:0] v1=0;$/;\"\tr\tmodule:m\ncheck_inside\tinput.sv\t/^            c1 check_inside(posedge clk, in1, v1);$/;\"\ti\tmodule:m\ttyperef:module:c1\ncheck_loop\tinput.sv\t/^                c1 check_loop(posedge clk, in1, in_array[v1]);$/;\"\ti\tmodule:m\ttyperef:module:c1\ncounter_model\tinput.sv\t/^checker counter_model(logic flag);$/;\"\tH\nflag\tinput.sv\t/^checker counter_model(logic flag);$/;\"\tp\tchecker:counter_model\ncounter\tinput.sv\t/^    bit [2:0] counter = '0;$/;\"\tr\tchecker:counter_model\nobserver_model\tinput.sv\t/^checker observer_model(bit valid, reset);$/;\"\tH\nvalid\tinput.sv\t/^checker observer_model(bit valid, reset);$/;\"\tp\tchecker:observer_model\nreset\tinput.sv\t/^checker observer_model(bit valid, reset);$/;\"\tp\tchecker:observer_model\nflag\tinput.sv\t/^    rand bit flag;$/;\"\tr\tchecker:observer_model\nm1\tinput.sv\t/^    m1: assume property (reset |=> !flag);$/;\"\tA\tchecker:observer_model\nm2\tinput.sv\t/^    m2: assume property (!reset && flag |=> flag);$/;\"\tA\tchecker:observer_model\nm3\tinput.sv\t/^    m3: assume property ($rising_gclk(flag) |-> valid);$/;\"\tA\tchecker:observer_model\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-checker.d/input.sv",
    "content": "//\n// Checker tests\n//\n\n// LRM 17 Checkers\n// 17.2 Checker declaration\n// Simple checker containing concurrent assertions\nchecker my_check1 (logic test_sig, event clock);\n    default clocking @clock; endclocking\n    property p(logic sig);\n        sig ##1 !sig; // ...\n    endproperty\n    a1: assert property (p (test_sig));\n    c1: cover property (!test_sig ##1 test_sig);\nendchecker : my_check1\n\n// Simple checker containing deferred assertions\nchecker my_check2 (logic a, b);\n    a1: assert #0 ($onehot0({a, b}));\n    c1: cover #0 (a == 0 && b == 0);\n    c2: cover #0 (a == 1);\n    c3: cover #0 (b == 1);\nendchecker : my_check2\n\n// Simple checker with output arguments\nchecker my_check3 (logic a, b, event clock, output bit failure, undef);\n    default clocking @clock; endclocking\n    a1: assert property ($onehot0({a, b})) failure = 1'b0; else failure = 1'b1;\n    a2: assert property ($isunknown({a, b})) undef = 1'b0; else undef = 1'b1;\nendchecker : my_check3\n\n// Checker with default input and initialized output arguments\nchecker my_check4 (input logic in,\n                   en = 1'b1, // default value\n                   event clock,\n                   output int ctr = 0); // initial value\n    default clocking @clock; endclocking\n    always_ff @clock\n        if (en && in) ctr <= ctr + 1;\n    a1: assert property (ctr < 5);\nendchecker : my_check4\n\nmodule m;\n    default clocking @clk1; endclocking\n    default disable iff rst1;\n    checker c1;\n        // Inherits @clk1 and rst1\n        // ...\n    endchecker : c1\n    checker c2;\n        // Explicitly redefines its default values\n        default clocking @clk2; endclocking\n        default disable iff rst2;\n        // ...\n    endchecker : c2\n    // ...\nendmodule : m\n\n// 17.3 Checker instantiation\nchecker mutex (logic [31:0] sig, event clock, output bit failure);\n    assert property (@clock $onehot0(sig))\n    failure = 1'b0; else failure = 1'b1;\nendchecker : mutex\n\nmodule m(wire [31:0] bus, logic clk);\n    logic res, scan;\n    // ...\n    mutex check_bus(bus, posedge clk, res);\n    always @(posedge clk) scan <= res;\nendmodule : m\n\n\nchecker c1(event clk, logic[7:0] a, b);\n    `define MAX_SUM 8\n    logic [7:0] sum;\n    always_ff @(clk) begin\n        sum <= a + 1'b1;\n        p0: assert property (sum < `MAX_SUM);\n    end\n    p1: assert property (@clk sum < `MAX_SUM);\n    p2: assert property (@clk a != b);\n    p3: assert #0 ($onehot(a));\nendchecker\n\nmodule m(input logic rst, clk, logic en, logic[7:0] in1, in2,\n         in_array [20:0]);\n    c1 check_outside(posedge clk, in1, in2);\n    always @(posedge clk) begin\n        automatic logic [7:0] v1=0;\n        if (en) begin\n            // v1 is automatic, so current procedural value is used\n            c1 check_inside(posedge clk, in1, v1);\n        end\n        for (int i = 0; i < 4; i++) begin\n            v1 = v1+5;\n            if (i != 2) begin\n                // v1 is automatic, so current procedural value is used\n                c1 check_loop(posedge clk, in1, in_array[v1]);\n            end\n        end\n    end\nendmodule : m\n\n// 17.7 Checker variables\nchecker counter_model(logic flag);\n    bit [2:0] counter = '0;\n    always_ff @$global_clock\n        counter <= counter + 1'b1;\n    assert property (@$global_clock counter == 0 |-> flag);\nendchecker : counter_model\n\nchecker observer_model(bit valid, reset);\n    default clocking @$global_clock; endclocking\n    rand bit flag;\n\n    m1: assume property (reset |=> !flag);\n    m2: assume property (!reset && flag |=> flag);\n    m3: assume property ($rising_gclk(flag) |-> valid);\nendchecker : observer_model\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-checker.d/validator",
    "content": "KNOWN-INVALIDATION\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-class.d/args.ctags",
    "content": "--extras=+q\n--kinds-systemverilog=+Q\n--fields=+i\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-class.d/expected.tags",
    "content": "DEFINE\tinput.sv\t/^`define DEFINE$/;\"\td\nDEF_WITH_EQ\tinput.sv\t/^`define DEF_WITH_EQ = 1'd100$/;\"\td\nDEF_VALUE\tinput.sv\t/^`define DEF_VALUE   1'd100$/;\"\td\ntest\tinput.sv\t/^class test;$/;\"\tC\na\tinput.sv\t/^    reg a;$/;\"\tr\tclass:test\ntest.a\tinput.sv\t/^    reg a;$/;\"\tr\tclass:test\nb\tinput.sv\t/^    logic b;$/;\"\tr\tclass:test\ntest.b\tinput.sv\t/^    logic b;$/;\"\tr\tclass:test\nenum_simple\tinput.sv\t/^    enum {enum_simple1, enum_simple2} enum_simple;$/;\"\tE\tclass:test\ntest.enum_simple\tinput.sv\t/^    enum {enum_simple1, enum_simple2} enum_simple;$/;\"\tE\tclass:test\nenum_simple1\tinput.sv\t/^    enum {enum_simple1, enum_simple2} enum_simple;$/;\"\tc\tenum:test.enum_simple\ntest.enum_simple.enum_simple1\tinput.sv\t/^    enum {enum_simple1, enum_simple2} enum_simple;$/;\"\tc\tenum:test.enum_simple\nenum_simple2\tinput.sv\t/^    enum {enum_simple1, enum_simple2} enum_simple;$/;\"\tc\tenum:test.enum_simple\ntest.enum_simple.enum_simple2\tinput.sv\t/^    enum {enum_simple1, enum_simple2} enum_simple;$/;\"\tc\tenum:test.enum_simple\nenum_var1\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tE\tclass:test\ntest.enum_var1\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tE\tclass:test\nenum_const1\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tc\tenum:test.enum_var1\ntest.enum_var1.enum_const1\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tc\tenum:test.enum_var1\nenum_const2\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tc\tenum:test.enum_var1\ntest.enum_var1.enum_const2\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tc\tenum:test.enum_var1\nenum_var2\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tE\tclass:test\ntest.enum_var2\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tE\tclass:test\nenum_const1\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tc\tenum:test.enum_var2\ntest.enum_var2.enum_const1\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tc\tenum:test.enum_var2\nenum_const2\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tc\tenum:test.enum_var2\ntest.enum_var2.enum_const2\tinput.sv\t/^    enum {enum_const1, enum_const2} enum_var1, enum_var2;$/;\"\tc\tenum:test.enum_var2\nenum_complex\tinput.sv\t/^    } enum_complex;$/;\"\tE\tclass:test\ntest.enum_complex\tinput.sv\t/^    } enum_complex;$/;\"\tE\tclass:test\nenum_bit1\tinput.sv\t/^      enum_bit1,$/;\"\tc\tenum:test.enum_complex\ntest.enum_complex.enum_bit1\tinput.sv\t/^      enum_bit1,$/;\"\tc\tenum:test.enum_complex\nenum_bit2\tinput.sv\t/^      enum_bit2='x,$/;\"\tc\tenum:test.enum_complex\ntest.enum_complex.enum_bit2\tinput.sv\t/^      enum_bit2='x,$/;\"\tc\tenum:test.enum_complex\nenum_bit3\tinput.sv\t/^      enum_bit3=2'b01,$/;\"\tc\tenum:test.enum_complex\ntest.enum_complex.enum_bit3\tinput.sv\t/^      enum_bit3=2'b01,$/;\"\tc\tenum:test.enum_complex\nenum_bit4\tinput.sv\t/^      enum_bit4[0:10]=2'b10,$/;\"\tc\tenum:test.enum_complex\ntest.enum_complex.enum_bit4\tinput.sv\t/^      enum_bit4[0:10]=2'b10,$/;\"\tc\tenum:test.enum_complex\nenum_bit5\tinput.sv\t/^      enum_bit5 [9:0] = 2'b10$/;\"\tc\tenum:test.enum_complex\ntest.enum_complex.enum_bit5\tinput.sv\t/^      enum_bit5 [9:0] = 2'b10$/;\"\tc\tenum:test.enum_complex\nmult\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tf\tclass:test\ntest.mult\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tf\tclass:test\na\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:test.mult\ntest.mult.a\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:test.mult\nb\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:test.mult\ntest.mult.b\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:test.mult\nextern_func\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tQ\tclass:test\ntest.extern_func\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tQ\tclass:test\na\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tp\tprototype:test.extern_func\ntest.extern_func.a\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tp\tprototype:test.extern_func\nb\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tp\tprototype:test.extern_func\ntest.extern_func.b\tinput.sv\t/^    extern virtual function void extern_func (input bit a, input b);$/;\"\tp\tprototype:test.extern_func\nsupertest\tinput.sv\t/^class supertest extends test;$/;\"\tC\tinherits:test\nc\tinput.sv\t/^    logic c;$/;\"\tr\tclass:supertest\nsupertest.c\tinput.sv\t/^    logic c;$/;\"\tr\tclass:supertest\nfwrd_ref\tinput.sv\t/^    extern virtual function bit fwrd_ref;$/;\"\tQ\tclass:supertest\nsupertest.fwrd_ref\tinput.sv\t/^    extern virtual function bit fwrd_ref;$/;\"\tQ\tclass:supertest\nmult\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tf\tclass:supertest\nsupertest.mult\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tf\tclass:supertest\na\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:supertest.mult\nsupertest.mult.a\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:supertest.mult\nb\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:supertest.mult\nsupertest.mult.b\tinput.sv\t/^    function mult (a, input b = 0);$/;\"\tp\tfunction:supertest.mult\nparamtest\tinput.sv\t/^class paramtest #(type BASE=supertest #(test)) extends BASE;$/;\"\tC\tinherits:BASE\nBASE\tinput.sv\t/^class paramtest #(type BASE=supertest #(test)) extends BASE;$/;\"\tc\tclass:paramtest\nparamtest.BASE\tinput.sv\t/^class paramtest #(type BASE=supertest #(test)) extends BASE;$/;\"\tc\tclass:paramtest\nparamtest2\tinput.sv\t/^class paramtest2 #($/;\"\tC\tinherits:BASE\nBASE\tinput.sv\t/^  type BASE=supertest #(test)$/;\"\tc\tclass:paramtest2\nparamtest2.BASE\tinput.sv\t/^  type BASE=supertest #(test)$/;\"\tc\tclass:paramtest2\nparamtest3\tinput.sv\t/^class paramtest3 #(type BASE=supertest, type BASE2=paramtest);$/;\"\tC\nBASE\tinput.sv\t/^class paramtest3 #(type BASE=supertest, type BASE2=paramtest);$/;\"\tc\tclass:paramtest3\nparamtest3.BASE\tinput.sv\t/^class paramtest3 #(type BASE=supertest, type BASE2=paramtest);$/;\"\tc\tclass:paramtest3\nBASE2\tinput.sv\t/^class paramtest3 #(type BASE=supertest, type BASE2=paramtest);$/;\"\tc\tclass:paramtest3\nparamtest3.BASE2\tinput.sv\t/^class paramtest3 #(type BASE=supertest, type BASE2=paramtest);$/;\"\tc\tclass:paramtest3\nmyfunc\tinput.sv\t/^virtual function myfunc (a, b);$/;\"\tf\tclass:paramtest3\nparamtest3.myfunc\tinput.sv\t/^virtual function myfunc (a, b);$/;\"\tf\tclass:paramtest3\na\tinput.sv\t/^virtual function myfunc (a, b);$/;\"\tp\tfunction:paramtest3.myfunc\nparamtest3.myfunc.a\tinput.sv\t/^virtual function myfunc (a, b);$/;\"\tp\tfunction:paramtest3.myfunc\nb\tinput.sv\t/^virtual function myfunc (a, b);$/;\"\tp\tfunction:paramtest3.myfunc\nparamtest3.myfunc.b\tinput.sv\t/^virtual function myfunc (a, b);$/;\"\tp\tfunction:paramtest3.myfunc\next_func\tinput.sv\t/^extern virtual function test ext_func (c, d);$/;\"\tQ\tclass:paramtest3\nparamtest3.ext_func\tinput.sv\t/^extern virtual function test ext_func (c, d);$/;\"\tQ\tclass:paramtest3\nc\tinput.sv\t/^extern virtual function test ext_func (c, d);$/;\"\tp\tprototype:paramtest3.ext_func\nparamtest3.ext_func.c\tinput.sv\t/^extern virtual function test ext_func (c, d);$/;\"\tp\tprototype:paramtest3.ext_func\nd\tinput.sv\t/^extern virtual function test ext_func (c, d);$/;\"\tp\tprototype:paramtest3.ext_func\nparamtest3.ext_func.d\tinput.sv\t/^extern virtual function test ext_func (c, d);$/;\"\tp\tprototype:paramtest3.ext_func\next_func\tinput.sv\t/^function test paramtest3::ext_func (c, d);$/;\"\tf\tclass:paramtest3\nparamtest3.ext_func\tinput.sv\t/^function test paramtest3::ext_func (c, d);$/;\"\tf\tclass:paramtest3\nc\tinput.sv\t/^function test paramtest3::ext_func (c, d);$/;\"\tp\tfunction:paramtest3.ext_func\nparamtest3.ext_func.c\tinput.sv\t/^function test paramtest3::ext_func (c, d);$/;\"\tp\tfunction:paramtest3.ext_func\nd\tinput.sv\t/^function test paramtest3::ext_func (c, d);$/;\"\tp\tfunction:paramtest3.ext_func\nparamtest3.ext_func.d\tinput.sv\t/^function test paramtest3::ext_func (c, d);$/;\"\tp\tfunction:paramtest3.ext_func\ntest_attributes\tinput.sv\t/^class test_attributes;$/;\"\tC\nstatic_logic\tinput.sv\t/^  static logic          static_logic;$/;\"\tr\tclass:test_attributes\ntest_attributes.static_logic\tinput.sv\t/^  static logic          static_logic;$/;\"\tr\tclass:test_attributes\nprotected_logic\tinput.sv\t/^  protected logic       protected_logic;$/;\"\tr\tclass:test_attributes\ntest_attributes.protected_logic\tinput.sv\t/^  protected logic       protected_logic;$/;\"\tr\tclass:test_attributes\nlocal_logic\tinput.sv\t/^  local logic           local_logic;$/;\"\tr\tclass:test_attributes\ntest_attributes.local_logic\tinput.sv\t/^  local logic           local_logic;$/;\"\tr\tclass:test_attributes\nconst_static_logic\tinput.sv\t/^  const static logic    const_static_logic;$/;\"\tr\tclass:test_attributes\ntest_attributes.const_static_logic\tinput.sv\t/^  const static logic    const_static_logic;$/;\"\tr\tclass:test_attributes\nconst_protected_logic\tinput.sv\t/^  const protected logic const_protected_logic;$/;\"\tr\tclass:test_attributes\ntest_attributes.const_protected_logic\tinput.sv\t/^  const protected logic const_protected_logic;$/;\"\tr\tclass:test_attributes\nconst_local_logic\tinput.sv\t/^  const local logic     const_local_logic;$/;\"\tr\tclass:test_attributes\ntest_attributes.const_local_logic\tinput.sv\t/^  const local logic     const_local_logic;$/;\"\tr\tclass:test_attributes\nrand_logic\tinput.sv\t/^  rand logic            rand_logic;$/;\"\tr\tclass:test_attributes\ntest_attributes.rand_logic\tinput.sv\t/^  rand logic            rand_logic;$/;\"\tr\tclass:test_attributes\nrandc_logic\tinput.sv\t/^  randc logic           randc_logic;$/;\"\tr\tclass:test_attributes\ntest_attributes.randc_logic\tinput.sv\t/^  randc logic           randc_logic;$/;\"\tr\tclass:test_attributes\nconst_logic\tinput.sv\t/^  const logic           const_logic;$/;\"\tr\tclass:test_attributes\ntest_attributes.const_logic\tinput.sv\t/^  const logic           const_logic;$/;\"\tr\tclass:test_attributes\nD\tinput.sv\t/^class D;$/;\"\tC\nm_cb_find\tinput.sv\t/^  static function int m_cb_find(foo#(bar) a, callback b);$/;\"\tf\tclass:D\nD.m_cb_find\tinput.sv\t/^  static function int m_cb_find(foo#(bar) a, callback b);$/;\"\tf\tclass:D\na\tinput.sv\t/^  static function int m_cb_find(foo#(bar) a, callback b);$/;\"\tp\tfunction:D.m_cb_find\nD.m_cb_find.a\tinput.sv\t/^  static function int m_cb_find(foo#(bar) a, callback b);$/;\"\tp\tfunction:D.m_cb_find\nb\tinput.sv\t/^  static function int m_cb_find(foo#(bar) a, callback b);$/;\"\tp\tfunction:D.m_cb_find\nD.m_cb_find.b\tinput.sv\t/^  static function int m_cb_find(foo#(bar) a, callback b);$/;\"\tp\tfunction:D.m_cb_find\nset_priority\tinput.sv\t/^  pure virtual function void set_priority (foo::bar x);$/;\"\tQ\tclass:D\nD.set_priority\tinput.sv\t/^  pure virtual function void set_priority (foo::bar x);$/;\"\tQ\tclass:D\nx\tinput.sv\t/^  pure virtual function void set_priority (foo::bar x);$/;\"\tp\tprototype:D.set_priority\nD.set_priority.x\tinput.sv\t/^  pure virtual function void set_priority (foo::bar x);$/;\"\tp\tprototype:D.set_priority\nBasePacket\tinput.sv\t/^virtual class BasePacket;$/;\"\tC\nsend\tinput.sv\t/^pure virtual function integer send(bit[31:0] data); \\/\\/ No implementation$/;\"\tQ\tclass:BasePacket\nBasePacket.send\tinput.sv\t/^pure virtual function integer send(bit[31:0] data); \\/\\/ No implementation$/;\"\tQ\tclass:BasePacket\ndata\tinput.sv\t/^pure virtual function integer send(bit[31:0] data); \\/\\/ No implementation$/;\"\tp\tprototype:BasePacket.send\nBasePacket.send.data\tinput.sv\t/^pure virtual function integer send(bit[31:0] data); \\/\\/ No implementation$/;\"\tp\tprototype:BasePacket.send\ncomplex_class\tinput.sv\t/^virtual class static complex_class #(type BASE1=foo, type BASE2=bar) extends base (a, b) impleme/;\"\tC\tinherits:base\nBASE1\tinput.sv\t/^virtual class static complex_class #(type BASE1=foo, type BASE2=bar) extends base (a, b) impleme/;\"\tc\tclass:complex_class\ncomplex_class.BASE1\tinput.sv\t/^virtual class static complex_class #(type BASE1=foo, type BASE2=bar) extends base (a, b) impleme/;\"\tc\tclass:complex_class\nBASE2\tinput.sv\t/^virtual class static complex_class #(type BASE1=foo, type BASE2=bar) extends base (a, b) impleme/;\"\tc\tclass:complex_class\ncomplex_class.BASE2\tinput.sv\t/^virtual class static complex_class #(type BASE1=foo, type BASE2=bar) extends base (a, b) impleme/;\"\tc\tclass:complex_class\npacket_c\tinput.sv\t/^  Packet packet_c;$/;\"\tr\tclass:complex_class\ncomplex_class.packet_c\tinput.sv\t/^  Packet packet_c;$/;\"\tr\tclass:complex_class\nnext\tinput.sv\t/^  LinkedPacket next;$/;\"\tr\tclass:complex_class\ncomplex_class.next\tinput.sv\t/^  LinkedPacket next;$/;\"\tr\tclass:complex_class\nget_next\tinput.sv\t/^  function LinkedPacket get_next();$/;\"\tf\tclass:complex_class\ncomplex_class.get_next\tinput.sv\t/^  function LinkedPacket get_next();$/;\"\tf\tclass:complex_class\nauto_class\tinput.sv\t/^class automatic auto_class;$/;\"\tC\na\tinput.sv\t/^  logic a;$/;\"\tr\tclass:auto_class\nauto_class.a\tinput.sv\t/^  logic a;$/;\"\tr\tclass:auto_class\ntest_final_specifier_A\tinput.sv\t/^class :final test_final_specifier_A;$/;\"\tC\ntest_class\tinput.sv\t/^class test_class;$/;\"\tC\ntest_final_specifier_B\tinput.sv\t/^virtual class :final test_final_specifier_B;$/;\"\tC\nTopPacket\tinput.sv\t/^class : final TopPacket extends LinkedPacket;$/;\"\tC\tinherits:LinkedPacket\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-class.d/input.sv",
    "content": "// Include module declaration in a comment\n// module wrong;\n// endmodule\n`define DEFINE\n`define DEF_WITH_EQ = 1'd100\n`define DEF_VALUE   1'd100\n\nclass test;\n    reg a;\n    logic b;\n    enum {enum_simple1, enum_simple2} enum_simple;\n    enum {enum_const1, enum_const2} enum_var1, enum_var2;\n    enum bit [1:0] {\n      enum_bit1,\n      enum_bit2='x,\n      enum_bit3=2'b01,\n      enum_bit4[0:10]=2'b10,\n      enum_bit5 [9:0] = 2'b10\n    } enum_complex;\n    function mult (a, input b = 0);\n        return a * b;\n    endfunction : mult\n\n    extern virtual function void extern_func (input bit a, input b);\n\nendclass : test\n\nclass supertest extends test;\n    logic c;\n    extern virtual function bit fwrd_ref;\n    function mult (a, input b = 0);\n        return a * b * 2;\n    endfunction : mult\nendclass : test\n\nclass paramtest #(type BASE=supertest #(test)) extends BASE;\nendclass : paramtest\n\nclass paramtest2 #(\n  type BASE=supertest #(test)\n) extends BASE;\nendclass : paramtest2\n\nclass paramtest3 #(type BASE=supertest, type BASE2=paramtest);\n\nvirtual function myfunc (a, b);\nendfunction\n\nextern virtual function test ext_func (c, d);\n\nendclass : paramtest3\n\nfunction test paramtest3::ext_func (c, d);\nendfunction\n\nclass test_attributes;\n  static logic          static_logic;\n  protected logic       protected_logic;\n  local logic           local_logic;\n  const static logic    const_static_logic;\n  const protected logic const_protected_logic;\n  const local logic     const_local_logic;\n  rand logic            rand_logic;\n  randc logic           randc_logic;\n  const logic           const_logic;\nendclass : test_attributes\n\nclass D;\n  // UVM-1.2: src/base/uvm_callback.svh\n  static function int m_cb_find(foo#(bar) a, callback b);\n    return -1;\n  endfunction\n  // UVM-1.2: src/base/uvm_callback.svh\n  pure virtual function void set_priority (foo::bar x);\nendclass\n\n// 8.21 Abstract classes and pure virtual methods\nvirtual class BasePacket;\npure virtual function integer send(bit[31:0] data); // No implementation\nendclass\n\n// original complex class\nvirtual class static complex_class #(type BASE1=foo, type BASE2=bar) extends base (a, b) implements xxx, yyy;\n  Packet packet_c;\n  LinkedPacket next;\n  function LinkedPacket get_next();\n    get_next = next;\n  endfunction\nendclass\n\nclass automatic auto_class;\n  logic a;\nendclass : auto_class\n\nclass :final test_final_specifier_A;\n  // The final specifier, preceded by a colon, when applied to classes:\n  // specifies that a class shall not be extended.\nendclass\n\nclass test_class;\nendclass\n\nvirtual class :final test_final_specifier_B;\n  // The final specifier, preceded by a colon, when applied to classes:\n  // specifies that a class shall not be extended.\nendclass\n\nclass : final TopPacket extends LinkedPacket;\n  // The final specifier, preceded by a colon, when applied to classes:\n  // specifies that a class shall not be extended.\nendclass\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-clocking.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-clocking.d/expected.tags",
    "content": "foo_bus\tinput.sv\t/^interface foo_bus;$/;\"\tI\nclock1\tinput.sv\t/^  logic clock1;$/;\"\tr\tinterface:foo_bus\ndata\tinput.sv\t/^  logic data, ready, enable, ack, addr;$/;\"\tr\tinterface:foo_bus\nready\tinput.sv\t/^  logic data, ready, enable, ack, addr;$/;\"\tr\tinterface:foo_bus\nenable\tinput.sv\t/^  logic data, ready, enable, ack, addr;$/;\"\tr\tinterface:foo_bus\nack\tinput.sv\t/^  logic data, ready, enable, ack, addr;$/;\"\tr\tinterface:foo_bus\naddr\tinput.sv\t/^  logic data, ready, enable, ack, addr;$/;\"\tr\tinterface:foo_bus\nbus\tinput.sv\t/^  clocking bus @(posedge clock1);$/;\"\tL\tinterface:foo_bus\nfoo_14_4\tinput.sv\t/^module foo_14_4;$/;\"\tm\nclk\tinput.sv\t/^  logic clk, address, data;$/;\"\tr\tmodule:foo_14_4\naddress\tinput.sv\t/^  logic clk, address, data;$/;\"\tr\tmodule:foo_14_4\ndata\tinput.sv\t/^  logic clk, address, data;$/;\"\tr\tmodule:foo_14_4\ndram\tinput.sv\t/^  clocking dram @(clk);$/;\"\tL\tmodule:foo_14_4\ntest\tinput.sv\t/^program test( input phi1, input [15:0] data, output logic write,$/;\"\tP\nphi1\tinput.sv\t/^program test( input phi1, input [15:0] data, output logic write,$/;\"\tp\tprogram:test\ndata\tinput.sv\t/^program test( input phi1, input [15:0] data, output logic write,$/;\"\tp\tprogram:test\nwrite\tinput.sv\t/^program test( input phi1, input [15:0] data, output logic write,$/;\"\tp\tprogram:test\nphi2\tinput.sv\t/^              input phi2, inout [8:1] cmd, input enable$/;\"\tp\tprogram:test\ncmd\tinput.sv\t/^              input phi2, inout [8:1] cmd, input enable$/;\"\tp\tprogram:test\nenable\tinput.sv\t/^              input phi2, inout [8:1] cmd, input enable$/;\"\tp\tprogram:test\ncmd_reg\tinput.sv\t/^  reg [8:1] cmd_reg;$/;\"\tr\tprogram:test\ncd1\tinput.sv\t/^  clocking cd1 @(posedge phi1);$/;\"\tL\tprogram:test\ncd2\tinput.sv\t/^  clocking cd2 @(posedge phi2);$/;\"\tL\tprogram:test\ntop\tinput.sv\t/^module top;$/;\"\tm\nclk1\tinput.sv\t/^logic clk1, clk2;$/;\"\tr\tmodule:top\nclk2\tinput.sv\t/^logic clk1, clk2;$/;\"\tr\tmodule:top\nsys\tinput.sv\t/^  global clocking sys @(clk1 or clk2); endclocking$/;\"\tL\tmodule:top\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-clocking.d/input.sv",
    "content": "//\n// Clocking blocks tests\n//\n\n// LRM 14.3 Clocking block declaration\ninterface foo_bus;\n  logic clock1;\n  logic data, ready, enable, ack, addr;\n\n  clocking bus @(posedge clock1);\n    default input #10ns output #2ns;\n    input data, ready, enable = top.mem1.enable;\n    output negedge ack;\n    input #1step addr;\n  endclocking\nendinterface\n\n// 14.4 Input and output skews\nmodule foo_14_4;\n  logic clk, address, data;\n  clocking dram @(clk);\n    input #1ps address;\n    input #5 output #6 data;\n  endclocking\nendmodule\n\n// 14.8 Multiple clocking blocks example\nprogram test( input phi1, input [15:0] data, output logic write,\n              input phi2, inout [8:1] cmd, input enable\n);\n  reg [8:1] cmd_reg;\n  clocking cd1 @(posedge phi1);\n    input data;\n    output write;\n    input state = top.cpu1.state;\n  endclocking\n\n  clocking cd2 @(posedge phi2);\n    input #2 output #4ps cmd;\n    input enable;\n  endclocking\n\n  initial begin\n    // program begins here\n    // ...\n    // user can access cd1.data , cd2.cmd , etc…\n  end\n\n  assign cmd = enable ? cmd_reg: 'x;\nendprogram\n\n// 14.14 Global clocking\nmodule top;\nlogic clk1, clk2;\n  global clocking sys @(clk1 or clk2); endclocking\n  // ...\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-constraint.d/args.ctags",
    "content": "--sort=no\n--kinds-systemverilog=+Q\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-constraint.d/expected.tags",
    "content": "Bus\tinput.sv\t/^class Bus;$/;\"\tC\naddr\tinput.sv\t/^  rand bit[15:0] addr;$/;\"\tr\tclass:Bus\ndata\tinput.sv\t/^  rand bit[31:0] data;$/;\"\tr\tclass:Bus\nword_align\tinput.sv\t/^  constraint word_align {addr[1:0] == 2'b0;}$/;\"\tO\tclass:Bus\nAddrType\tinput.sv\t/^typedef enum {low, mid, high} AddrType;$/;\"\tT\nlow\tinput.sv\t/^typedef enum {low, mid, high} AddrType;$/;\"\tc\ttypedef:AddrType\nmid\tinput.sv\t/^typedef enum {low, mid, high} AddrType;$/;\"\tc\ttypedef:AddrType\nhigh\tinput.sv\t/^typedef enum {low, mid, high} AddrType;$/;\"\tc\ttypedef:AddrType\nMyBus\tinput.sv\t/^class MyBus extends Bus;$/;\"\tC\natype\tinput.sv\t/^  rand AddrType atype;$/;\"\tr\tclass:MyBus\naddr_range\tinput.sv\t/^  constraint addr_range$/;\"\tO\tclass:MyBus\nexercise_bus\tinput.sv\t/^task exercise_bus (MyBus bus);$/;\"\tt\nbus\tinput.sv\t/^task exercise_bus (MyBus bus);$/;\"\tp\ttask:exercise_bus\nres\tinput.sv\t/^  int res;$/;\"\tr\ttask:exercise_bus\nC\tinput.sv\t/^class C;$/;\"\tC\nx\tinput.sv\t/^  rand int x;$/;\"\tr\tclass:C\nproto1\tinput.sv\t/^  constraint proto1;        \\/\\/ implicit form$/;\"\tQ\tclass:C\nproto2\tinput.sv\t/^  extern constraint proto2; \\/\\/ explicit form$/;\"\tQ\tclass:C\nD\tinput.sv\t/^virtual class D;$/;\"\tC\nTest\tinput.sv\t/^  pure constraint Test;$/;\"\tQ\tclass:D\nE\tinput.sv\t/^class E;$/;\"\tC\nc1\tinput.sv\t/^  constraint c1 {$/;\"\tO\tclass:E\na\tinput.sv\t/^  rand byte a[5];$/;\"\tr\tclass:E\nb\tinput.sv\t/^  rand byte b;$/;\"\tr\tclass:E\nexcluded\tinput.sv\t/^  rand byte excluded;$/;\"\tr\tclass:E\nu\tinput.sv\t/^  constraint u { unique {b, a[2:3], excluded}; }$/;\"\tO\tclass:E\nexclusion\tinput.sv\t/^  constraint exclusion { excluded == 5; }$/;\"\tO\tclass:E\nC\tinput.sv\t/^class C;$/;\"\tC\nA\tinput.sv\t/^  rand byte A[] ;$/;\"\tr\tclass:C\nC1\tinput.sv\t/^  constraint C1 { foreach ( A [ i ] ) A[i] inside {2,4,8,16}; }$/;\"\tO\tclass:C\nC2\tinput.sv\t/^  constraint C2 { foreach ( A [ j ] ) A[j] > 2 * j; }$/;\"\tO\tclass:C\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-constraint.d/input.sv",
    "content": "//\n// LRM 18. Constrained random value generation\n//\n\n// 18.3 Concepts and usage\nclass Bus;\n  rand bit[15:0] addr;\n  rand bit[31:0] data;\n  constraint word_align {addr[1:0] == 2'b0;}\nendclass\n\ntypedef enum {low, mid, high} AddrType;\nclass MyBus extends Bus;\n  rand AddrType atype;\n  constraint addr_range\n  {\n    (atype == low ) -> addr inside { [0 : 15] };\n    (atype == mid ) -> addr inside { [16 : 127]};\n    (atype == high) -> addr inside {[128 : 255]};\n  }\nendclass\n\ntask exercise_bus (MyBus bus);\n  int res;\n  // EXAMPLE 1: restrict to low addresses\n  res = bus.randomize() with {atype == low;};\n  // EXAMPLE 2: restrict to address between 10 and 20\n  res = bus.randomize() with {10 <= addr && addr <= 20;};\n  // EXAMPLE 3: restrict data values to powers-of-two\n  res = bus.randomize() with {(data & (data - 1)) == 0;};\nendtask\n\n// 18.5 Constraint blocks\n// 18.5.1 External constraint blocks\nclass C;\n  rand int x;\n  constraint proto1;        // implicit form\n  extern constraint proto2; // explicit form\nendclass\n\n// 18.5.2 Constraint inheritance\nvirtual class D;\n  pure constraint Test;\nendclass\n\nclass E;\n  // 18.5.4 Distribution\n  constraint c1 {\n    x != 200;\n    x dist {100 := 1, 200 := 2, 300 := 5};\n  }\n\n  // 18.5.5 Uniqueness constraints\n  rand byte a[5];\n  rand byte b;\n  rand byte excluded;\n  constraint u { unique {b, a[2:3], excluded}; }\n  constraint exclusion { excluded == 5; }\nendclass\n\n// 18.5.8 Iterative constraints\n// 18.5.8.1 foreach iterative constraints\nclass C;\n  rand byte A[] ;\n  constraint C1 { foreach ( A [ i ] ) A[i] inside {2,4,8,16}; }\n  constraint C2 { foreach ( A [ j ] ) A[j] > 2 * j; }\nendclass\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-covergroup.d/args.ctags",
    "content": "--sort=no\n--kinds-systemverilog=+Q\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-covergroup.d/expected.tags",
    "content": "C0\tinput.sv\t/^checker C0 (logic clk);$/;\"\tH\nclk\tinput.sv\t/^checker C0 (logic clk);$/;\"\tp\tchecker:C0\ncolor\tinput.sv\t/^    enum { red, green, blue } color;$/;\"\tE\tchecker:C0\nred\tinput.sv\t/^    enum { red, green, blue } color;$/;\"\tc\tenum:C0.color\ngreen\tinput.sv\t/^    enum { red, green, blue } color;$/;\"\tc\tenum:C0.color\nblue\tinput.sv\t/^    enum { red, green, blue } color;$/;\"\tc\tenum:C0.color\npixel_adr\tinput.sv\t/^    bit [3:0] pixel_adr, pixel_offset, pixel_hue;$/;\"\tr\tchecker:C0\npixel_offset\tinput.sv\t/^    bit [3:0] pixel_adr, pixel_offset, pixel_hue;$/;\"\tr\tchecker:C0\npixel_hue\tinput.sv\t/^    bit [3:0] pixel_adr, pixel_offset, pixel_hue;$/;\"\tr\tchecker:C0\ng2\tinput.sv\t/^    covergroup g2 @(posedge clk);$/;\"\tV\tchecker:C0\nxyz\tinput.sv\t/^class xyz;$/;\"\tC\nm_x\tinput.sv\t/^    bit [3:0] m_x;$/;\"\tr\tclass:xyz\nm_y\tinput.sv\t/^    int m_y;$/;\"\tr\tclass:xyz\nm_z\tinput.sv\t/^    bit m_z;$/;\"\tr\tclass:xyz\ncov1\tinput.sv\t/^    covergroup cov1 @m_z;   \\/\\/ embedded covergroup$/;\"\tV\tclass:xyz\nnew\tinput.sv\t/^    function new(); cov1 = new; endfunction$/;\"\tf\tclass:xyz\nC1\tinput.sv\t/^checker C1 (logic clk);$/;\"\tH\nclk\tinput.sv\t/^checker C1 (logic clk);$/;\"\tp\tchecker:C1\nv_a\tinput.sv\t/^    bit [9:0] v_a;$/;\"\tr\tchecker:C1\ncg\tinput.sv\t/^    covergroup cg @(posedge clk);$/;\"\tV\tchecker:C1\nC2\tinput.sv\t/^checker C2 (logic clk);$/;\"\tH\nclk\tinput.sv\t/^checker C2 (logic clk);$/;\"\tp\tchecker:C2\na\tinput.sv\t/^    bit [3:0] a, b, c;$/;\"\tr\tchecker:C2\nb\tinput.sv\t/^    bit [3:0] a, b, c;$/;\"\tr\tchecker:C2\nc\tinput.sv\t/^    bit [3:0] a, b, c;$/;\"\tr\tchecker:C2\ncov2\tinput.sv\t/^    covergroup cov2 @(posedge clk);$/;\"\tV\tchecker:C2\nC3\tinput.sv\t/^checker C3 (logic clk);$/;\"\tH\nclk\tinput.sv\t/^checker C3 (logic clk);$/;\"\tp\tchecker:C3\np_cg\tinput.sv\t/^    covergroup p_cg with function sample(bit a, int x);$/;\"\tV\tchecker:C3\nsample\tinput.sv\t/^    covergroup p_cg with function sample(bit a, int x);$/;\"\tQ\tcovergroup:C3.p_cg\na\tinput.sv\t/^    covergroup p_cg with function sample(bit a, int x);$/;\"\tp\tprototype:C3.p_cg.sample\nx\tinput.sv\t/^    covergroup p_cg with function sample(bit a, int x);$/;\"\tp\tprototype:C3.p_cg.sample\nC4\tinput.sv\t/^checker C4 (logic clk);$/;\"\tH\nclk\tinput.sv\t/^checker C4 (logic clk);$/;\"\tp\tchecker:C4\ncg\tinput.sv\t/^    covergroup cg @@ ( begin task_end );$/;\"\tV\tchecker:C4\nvar_to_check_context\tinput.sv\t/^    reg var_to_check_context;$/;\"\tr\tchecker:C4\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-covergroup.d/input.sv",
    "content": "//\n//  LRM: 19. Functional coverage\n//\n// covergroup is decleared in class, package, or checker\n\n// 19.3 Defining the coverage model: covergroup\nchecker C0 (logic clk);\n    enum { red, green, blue } color;\n    bit [3:0] pixel_adr, pixel_offset, pixel_hue;\n\n    covergroup g2 @(posedge clk);\n        Hue: coverpoint pixel_hue;\n        Offset: coverpoint pixel_offset;\n\n        AxC: cross color, pixel_adr;    // cross 2 variables (implicitly declared\n                                        // coverpoints)\n\n        all: cross color, Hue, Offset;  // cross 1 variable and 2 coverpoints\n    endgroup\nendchecker\n\n// 19.4 Using covergroup in classes\nclass xyz;\n    bit [3:0] m_x;\n    int m_y;\n    bit m_z;\n\n    covergroup cov1 @m_z;   // embedded covergroup\n        coverpoint m_x;\n        coverpoint m_y;\n    endgroup\n\n    function new(); cov1 = new; endfunction\nendclass\n\n// 19.5.1 Specifying bins for values\nchecker C1 (logic clk);\n    bit [9:0] v_a;\n\n    covergroup cg @(posedge clk);\n        coverpoint v_a\n        {\n            bins a = { [0:63],65 };\n            bins b[] = { [127:150],[148:191] }; // note overlapping values\n            bins c[] = { 200,201,202 };\n            bins d = { [1000:$] };\n            bins others[] = default;\n        }\n    endgroup\nendchecker\n\n// 19.6 Defining cross coverage\nchecker C2 (logic clk);\n    bit [3:0] a, b, c;\n    covergroup cov2 @(posedge clk);\n        BC: coverpoint b+c;\n        aXb : cross a, BC;\n    endgroup\nendchecker\n\n// 19.8.1 Overriding the built-in sample method\nchecker C3 (logic clk);\n    covergroup p_cg with function sample(bit a, int x);\n        coverpoint x;\n        cross x, a;\n    endgroup : p_cg\nendchecker\n\n// original\nchecker C4 (logic clk);\n    covergroup cg @@ ( begin task_end );\n    endgroup\n\n    reg var_to_check_context;\nendchecker\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-directive.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-directive.d/expected.tags",
    "content": "directive\tinput.sv\t/^module directive;$/;\"\tm\nD\tinput.sv\t/^`define D(x,y) initial $display(\"start\", x , y, \"end\");$/;\"\td\nMACRO1\tinput.sv\t/^`define MACRO1(a=5,b=\"B\",c) $display(a,,b,,c);$/;\"\td\nMACRO2\tinput.sv\t/^`define MACRO2(a=5, b, c=\"C\") $display(a,,b,,c);$/;\"\td\nMACRO3\tinput.sv\t/^`define MACRO3(a=5, b=0, c=\"C\") $display(a,,b,,c);$/;\"\td\nwordsize\tinput.sv\t/^`define wordsize 8$/;\"\td\ndata\tinput.sv\t/^logic [1:`wordsize] data;$/;\"\tr\tmodule:directive\nvar_nand\tinput.sv\t/^`define var_nand(dly) nand #dly$/;\"\td\nmax\tinput.sv\t/^`define max(a,b)((a) > (b) ? (a) : (b))$/;\"\td\nTOP\tinput.sv\t/^`define TOP(a,b) a + b$/;\"\td\nmain\tinput.sv\t/^module main;$/;\"\tm\nHI\tinput.sv\t/^`define HI Hello$/;\"\td\nLO\tinput.sv\t/^`define LO \"`HI, world\"$/;\"\td\nH\tinput.sv\t/^`define H(x) \"Hello, x\"$/;\"\td\ndirective2\tinput.sv\t/^module directive2;$/;\"\tm\nmsg\tinput.sv\t/^`define msg(x,y) `\"x: `\\\\`\"y`\\\\`\"`\"$/;\"\td\nappend\tinput.sv\t/^`define append(f) f``_master$/;\"\td\nhome\tinput.sv\t/^`define home(filename) `\"\\/home\\/mydir\\/filename`\"$/;\"\td\nand_op\tinput.sv\t/^module and_op (a, b, c);$/;\"\tm\na\tinput.sv\t/^    output a;$/;\"\tp\tmodule:and_op\nb\tinput.sv\t/^    input b, c;$/;\"\tp\tmodule:and_op\nc\tinput.sv\t/^    input b, c;$/;\"\tp\tmodule:and_op\na\tinput.sv\t/^        wire a = b & c;$/;\"\tn\tmodule:and_op\ntest\tinput.sv\t/^module test(out);$/;\"\tm\nout\tinput.sv\t/^    output out;$/;\"\tp\tmodule:test\nwow\tinput.sv\t/^    `define wow$/;\"\td\nnest_one\tinput.sv\t/^    `define nest_one$/;\"\td\nsecond_nest\tinput.sv\t/^    `define second_nest$/;\"\td\nnest_two\tinput.sv\t/^    `define nest_two$/;\"\td\ntest\tinput.sv\t/^module test;$/;\"\tm\nifdef_in_port\tinput.sv\t/^module ifdef_in_port ($/;\"\tm\na\tinput.sv\t/^    input logic a,$/;\"\tp\tmodule:ifdef_in_port\nb1\tinput.sv\t/^        input logic b1,$/;\"\tp\tmodule:ifdef_in_port\nb2\tinput.sv\t/^        input logic b2,$/;\"\tp\tmodule:ifdef_in_port\nb3\tinput.sv\t/^        input logic b3,$/;\"\tp\tmodule:ifdef_in_port\nc\tinput.sv\t/^    input logic c$/;\"\tp\tmodule:ifdef_in_port\nuser_t\tinput.sv\t/^typedef logic user_t;$/;\"\tT\ndefine_in_port\tinput.sv\t/^module define_in_port ($/;\"\tm\na\tinput.sv\t/^    input user_t a,$/;\"\tp\tmodule:define_in_port\nFOO\tinput.sv\t/^`define FOO$/;\"\td\nb\tinput.sv\t/^    input user_t b,$/;\"\tp\tmodule:define_in_port\nBAR\tinput.sv\t/^`define BAR$/;\"\td\nc1\tinput.sv\t/^        input user_t c1,$/;\"\tp\tmodule:define_in_port\nc2\tinput.sv\t/^        input user_t c2,$/;\"\tp\tmodule:define_in_port\nc3\tinput.sv\t/^        input user_t c3,c4,$/;\"\tp\tmodule:define_in_port\nc4\tinput.sv\t/^        input user_t c3,c4,$/;\"\tp\tmodule:define_in_port\nd1\tinput.sv\t/^        output user_t d1 ,$/;\"\tp\tmodule:define_in_port\nd2\tinput.sv\t/^        output user_t d2$/;\"\tp\tmodule:define_in_port\ndefine_in_port_messy\tinput.sv\t/^module define_in_port_messy ($/;\"\tm\nFOO\tinput.sv\t/^`define FOO$/;\"\td\na\tinput.sv\t/^    input user_t a$/;\"\tp\tmodule:define_in_port_messy\nBAR\tinput.sv\t/^`define BAR$/;\"\td\nb\tinput.sv\t/^    ,input user_t b$/;\"\tp\tmodule:define_in_port_messy\nc1\tinput.sv\t/^        ,input user_t c1$/;\"\tp\tmodule:define_in_port_messy\nc2\tinput.sv\t/^        ,input user_t c2$/;\"\tp\tmodule:define_in_port_messy\nc3\tinput.sv\t/^        ,input user_t c3 , c4$/;\"\tp\tmodule:define_in_port_messy\nc4\tinput.sv\t/^        ,input user_t c3 , c4$/;\"\tp\tmodule:define_in_port_messy\nd1\tinput.sv\t/^        , output user_t d1$/;\"\tp\tmodule:define_in_port_messy\nd2\tinput.sv\t/^        , output user_t d2$/;\"\tp\tmodule:define_in_port_messy\nMY_DEFINE\tinput.sv\t/^`define MY_DEFINE$/;\"\td\nassert_clk\tinput.sv\t/^`define assert_clk(arg, __clk=clk, __rst_n=rst_n) \\\\$/;\"\td\nforSkipMacro\tinput.sv\t/^module forSkipMacro;$/;\"\tm\nadd_t\tinput.sv\t/^`define add_t(f) f``_t$/;\"\td\n`add_t\tinput.sv\t/^    var `add_t(foo) = '0;$/;\"\tr\tmodule:forSkipMacro\nmacro\tinput.sv\t/^`define macro$/;\"\td\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-directive.d/input.sv",
    "content": "//\n// LRM 22. Compiler Directives\n//  `define should have its own kind other than constant (c)\n\n//\n// 22.4 `include\n//\n`include \"parts/count.v\"\n`include \"fileB\" // including fileB\n`include <List.vh>\n\n//\n// 22.5 `define, `undef, and `undefineall\n//\nmodule directive;\n`define D(x,y) initial $display(\"start\", x , y, \"end\");\n`D( \"msg1\" , \"msg2\" )\n// expands to 'initial $display(\"start\", \"msg1\" , \"msg2\", \"end\");'\n`D( \" msg1\", )\n// expands to 'initial $display(\"start\", \" msg1\" , , \"end\");'\n`D(, \"msg2 \")\n// expands to 'initial $display(\"start\", , \"msg2 \", \"end\");'\n`D(,)\n// expands to 'initial $display(\"start\", , , \"end\");'\n`D( , )\n// expands to 'initial $display(\"start\", , , \"end\");'\n//`D(\"msg1\")\n// illegal, only one argument\n//`D()\n// illegal, only one empty argument\n//`D(,,)\n// illegal, more actual than formal arguments\n\n`define MACRO1(a=5,b=\"B\",c) $display(a,,b,,c);\n`MACRO1 ( , 2, 3 ) // argument a omitted, replaced by default\n// expands to '$display(5,,2,,3);'\n`MACRO1 ( 1 , , 3 ) // argument b omitted, replaced by default\n// expands to '$display(1,,\"B\",,3);'\n`MACRO1 ( , 2, ) // argument c omitted, replaced by nothing\n// expands to '$display(5,,2,,);'\n//`MACRO1 ( 1 ) // ILLEGAL: b and c omitted, no default for c\n\n`define MACRO2(a=5, b, c=\"C\") $display(a,,b,,c);\n`MACRO2 (1, , 3) // argument b omitted, replaced by nothing\n// expands to '$display(1,,,,3);'\n`MACRO2 (, 2, ) // a and c omitted, replaced by defaults\n// expands to '$display(5,,2,,\"C\");'\n`MACRO2 (, 2) // a and c omitted, replaced by defaults\n// expands to '$display(5,,2,,\"C\");'\n\n`define MACRO3(a=5, b=0, c=\"C\") $display(a,,b,,c);\n`MACRO3 ( 1 ) // b and c omitted, replaced by defaults\n// expands to '$display(1,,0,,\"C\");'\n`MACRO3 ( ) // all arguments replaced by defaults\n// expands to '$display(5,,0,,\"C\");'\n//`MACRO3 // ILLEGAL: parentheses required\n\n`define wordsize 8\nlogic [1:`wordsize] data;\n\n//define a nand with variable delay\n`define var_nand(dly) nand #dly\n`var_nand(2) g121 (q21, n10, n11);\n`var_nand(5) g122 (q22, n10, n11);\n\n// illegal\n//`define first_half \"start of string\n//$display(`first_half end of string\");\n\n`define max(a,b)((a) > (b) ? (a) : (b))\nn = `max(p+q, r+s) ;\n\n`define TOP(a,b) a + b\n`TOP( `TOP(b,1), `TOP(42,a) )\n\nendmodule\n\nmodule main;\n`define HI Hello\n`define LO \"`HI, world\"\n`define H(x) \"Hello, x\"\n\n    initial begin\n        $display(\"`HI, world\");\n        $display(`LO);\n        $display(`H(world));\n    end\nendmodule\n\nmodule directive2;\n`define msg(x,y) `\"x: `\\`\"y`\\`\"`\"\n`define append(f) f``_master\n\n    initial begin\n        $display(`msg(left side,right side));\n        `append(clock) = 1'b0;\n    end\n\n`define home(filename) `\"/home/mydir/filename`\"\n`include `home(myfile)\n\nendmodule\n\n//\n// 22.6 `ifdef, `else, `elsif, `endif, `ifndef\n//\nmodule and_op (a, b, c);\n    output a;\n    input b, c;\n    `ifdef behavioral\n        wire a = b & c;\n    `else\n        and a1 (a,b,c);\n    `endif\nendmodule\n\nmodule test(out);\n    output out;\n    `define wow\n    `define nest_one\n    `define second_nest\n    `define nest_two\n    `ifdef wow\n        initial $display(\"wow is defined\");\n        `ifdef nest_one\n            initial $display(\"nest_one is defined\");\n            `ifdef nest_two\n                initial $display(\"nest_two is defined\");\n            `else\n                initial $display(\"nest_two is not defined\");\n            `endif\n        `else\n            initial $display(\"nest_one is not defined\");\n        `endif\n    `else\n        initial $display(\"wow is not defined\");\n        `ifdef second_nest\n            initial $display(\"second_nest is defined\");\n        `else\n            initial $display(\"second_nest is not defined\");\n        `endif\n    `endif\nendmodule\n\nmodule test;\n    `ifdef first_block\n        `ifndef second_nest\n            initial $display(\"first_block is defined\");\n        `else\n            initial $display(\"first_block and second_nest defined\");\n        `endif\n    `elsif second_block\n        initial $display(\"second_block defined, first_block is not\");\n    `else\n        `ifndef last_result\n            initial $display(\"first_block, second_block,\",\n                \" last_result not defined.\");\n        `elsif real_last\n            initial $display(\"first_block, second_block not defined,\",\n                \" last_result and real_last defined.\");\n        `else\n            initial $display(\"Only last_result defined!\");\n        `endif\n    `endif\nendmodule\n\n// orignal tests\nmodule ifdef_in_port (\n    input logic a,\n    `ifdef FOO// comment w/o white space\n        input logic b1,\n    `elsif BAR  // coment w/ white space\n        input logic b2,\n    `else/* old C comment */ // foo\n        input logic b3,\n    `endif /* old C comment */ // foo\n    input logic c\n);\n\nendmodule\n\ntypedef logic user_t;\nmodule define_in_port (\n    input user_t a,\n`define FOO\n    input user_t b,\n`define BAR\n`ifdef FOO\n        input user_t c1,\n`elsif BAZ\n        input user_t c2,\n`else\n        input user_t c3,c4,\n`endif\n`ifdef FOO\n        output user_t d1 ,\n`else\n        output user_t d2\n`endif\n);\n\nendmodule\n\nmodule define_in_port_messy (\n    input user_t a\n`define FOO\n    ,input user_t b\n`define BAR\n`ifdef FOO\n        ,input user_t c1\n`elsif BAZ\n        ,input user_t c2\n`else\n        ,input user_t c3 , c4\n`endif\n`ifdef FOO\n        , output user_t d1\n`else\n        , output user_t d2\n`endif\n);\n\nendmodule\n\n`undef  MY_UNDEF\n`define MY_DEFINE\n\n`define assert_clk(arg, __clk=clk, __rst_n=rst_n) \\\n assert property (@(posedge __clk) disable iff (!__rst_n) arg)\n\nmodule forSkipMacro;\n`define add_t(f) f``_t\n    var `add_t(foo) = '0;\n\n`define macro\n    `macro({e},FOO)\n    `macro(\"string\",FOO)\n    `macro(bar)\n    `macro(int)\n    `macro(int,bar)\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-directive.d/validator",
    "content": "KNOWN-INVALIDATION\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github2635.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github2635.d/expected.tags",
    "content": "ctags_uni_issues\tinput.sv\t/^module ctags_uni_issues ($/;\"\tm\ndata_in\tinput.sv\t/^  input var logic data_in$/;\"\tp\tmodule:ctags_uni_issues\nfoo\tinput.sv\t/^  const var foo;$/;\"\tr\tmodule:ctags_uni_issues\nbar\tinput.sv\t/^  var bar;$/;\"\tr\tmodule:ctags_uni_issues\nvariable_name\tinput.sv\t/^  chandle variable_name ;$/;\"\tr\tmodule:ctags_uni_issues\nx\tinput.sv\t/^class x;$/;\"\tC\nra\tinput.sv\t/^  rand var ra;$/;\"\tr\tclass:x\nrb\tinput.sv\t/^  randc var rb;$/;\"\tr\tclass:x\nfoo\tinput.sv\t/^package foo;$/;\"\tK\ndelay_example\tinput.sv\t/^  sequence delay_example(x, y, min, max, delay1);$/;\"\tq\tpackage:foo\nx\tinput.sv\t/^  sequence delay_example(x, y, min, max, delay1);$/;\"\tp\tsequence:foo.delay_example\ny\tinput.sv\t/^  sequence delay_example(x, y, min, max, delay1);$/;\"\tp\tsequence:foo.delay_example\nmin\tinput.sv\t/^  sequence delay_example(x, y, min, max, delay1);$/;\"\tp\tsequence:foo.delay_example\nmax\tinput.sv\t/^  sequence delay_example(x, y, min, max, delay1);$/;\"\tp\tsequence:foo.delay_example\ndelay1\tinput.sv\t/^  sequence delay_example(x, y, min, max, delay1);$/;\"\tp\tsequence:foo.delay_example\nmh1\tinput.sv\t/^module mh1 ($/;\"\tm\nin1\tinput.sv\t/^  input var int in1,$/;\"\tp\tmodule:mh1\nout2\tinput.sv\t/^  output var int out2$/;\"\tp\tmodule:mh1\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github2635.d/input.sv",
    "content": "//\n// from LRM-2017\n//\nmodule ctags_uni_issues (\n  // 6.8 Variable declarations\n  input var logic data_in\n);\n\n  const var foo;\n  var bar;\n\n  // 6.14 Chandle data type\n  chandle variable_name ;\nendmodule\n\n// 8. Classes\n// 8.3\nclass x;\n  rand var ra;\n  randc var rb;\nendclass\n\npackage foo;\n  // 16.8 Declaring sequences\n  // sequence is not supported\n  sequence delay_example(x, y, min, max, delay1);\n    x ##delay1 y[*min:max];\n  endsequence\nendpackage\n\n// 23.2 Module definitions\nmodule mh1 (\n  input var int in1,\n  output var int out2\n);\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github3457.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github3457.d/expected.tags",
    "content": "A\tinput.sv\t/^class A;$/;\"\tC\nA0\tinput.sv\t/^  covergroup A0;$/;\"\tV\tclass:A\nA1\tinput.sv\t/^  covergroup A1;$/;\"\tV\tclass:A\nA2\tinput.sv\t/^  covergroup A2;$/;\"\tV\tclass:A\nA3\tinput.sv\t/^  covergroup A3;$/;\"\tV\tclass:A\nA4\tinput.sv\t/^  covergroup A4;$/;\"\tV\tclass:A\nA5\tinput.sv\t/^  covergroup A5;$/;\"\tV\tclass:A\nB\tinput.sv\t/^class B;$/;\"\tC\none\tinput.sv\t/^  int one, two;$/;\"\tr\tclass:B\ntwo\tinput.sv\t/^  int one, two;$/;\"\tr\tclass:B\nnew\tinput.sv\t/^  function new();$/;\"\tf\tclass:B\nE\tinput.sv\t/^typedef enum { FOO, BAR } E;/;\"\tT\nFOO\tinput.sv\t/^typedef enum { FOO, BAR } E;/;\"\tc\ttypedef:E\nBAR\tinput.sv\t/^typedef enum { FOO, BAR } E;/;\"\tc\ttypedef:E\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github3457.d/input.sv",
    "content": "// https://github.com/universal-ctags/ctags/issues/3457\nclass A;\n  covergroup A0;\n    coverpoint intf.x {\n      bins foo = { 0 };\n      bins bar = { 1 };\n    }\n    coverpoint intf.y {\n      bins foo = { 0 };\n      bins bar = { 1 };\n    }\n    // empty bins definition, end of ';', everything is OK.\n    coverpoint intf.z;\n  endgroup\n\n  covergroup A1;\n    coverpoint intf.a;\n    coverpoint intf.b;\n    // bins definition with '{}', but not a variable by hierarchical index, OK.\n    coverpoint no_sro {\n      bins foo = { 0 };\n      bins bar = { 1 };\n    }\n  endgroup\n\n  covergroup A2;\n    coverpoint intf.m {\n      bins foo = { 0 };\n      bins bar = { 1 };\n    }\n    coverpoint intf.n {\n      bins foo = { 0 };\n      bins bar = { 1 };\n    }\n    // exceptional, index by 'this', OK.\n    coverpoint this.t {\n      bins foo = { 0 };\n      bins bar = { 1 };\n    }\n  endgroup\n\n  covergroup A3;\n    coverpoint intf.r {\n      bins foo = { 0 };\n      bins bar = { 1 };\n    }\n    coverpoint intf.s {\n      bins foo = { 0 };\n      bins bar = { 1 };\n    }\n    // contain multiple hierarchical variable, OK.\n    cross intf.u, intf.v {\n      bins foo = { 0 };\n      bins bar = { 1 };\n    }\n  endgroup\n\n  covergroup A4;\n    coverpoint intf.p;\n    // last definition, hierarchical variable, bins definition with '{}'\n    // meet at the same time, subsequent parsers will all go WRONG.\n    coverpoint intf.q {\n      bins foo = { 0 };\n      bins bar = { 1 };\n    }\n  endgroup\n\n  // Error Scope >> covergroup:A.A4\n  covergroup A5;\n    coverpoint foo;\n    coverpoint bar;\n  endgroup\nendclass\n\n// Error Scope >> covergroup:A.A4\nclass B;\n  int one, two;\n  function new();\n  endfunction\nendclass\n\n// Error Scope >> covergroup:A.A4\ntypedef enum { FOO, BAR } E;"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github3457.d/validator",
    "content": "KNOWN-INVALIDATION\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github3462.d/args.ctags",
    "content": "--sort=no\n--kinds-systemverilog=+Q\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github3462.d/expected.tags",
    "content": "foo\tinput.sv\t/^module foo;$/;\"\tm\nfoo\tinput.sv\t/^package foo;$/;\"\tK\nimport_func\tinput.sv\t/^  import \"DPI-C\" context function int import_func (string str);$/;\"\tQ\tpackage:foo\nstr\tinput.sv\t/^  import \"DPI-C\" context function int import_func (string str);$/;\"\tp\tprototype:foo.import_func\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github3462.d/input.sv",
    "content": "// SystemVerilog: \"assertions\" parsing error when encountered \"::\" #3462\n// https://github.com/universal-ctags/ctags/issues/3462\n\nmodule foo;\n  import uvm_pkg::*;\n  always_comb begin\n    // something\n    assert (foo) else $error(\"failed\");\n    // something\n    someclass::method();\n    // something\n    assert (bar) else $error(\"failed\");\n  end\nendmodule\n\npackage foo;\n  import \"DPI-C\" context function int import_func (string str);\nendpackage\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github3712.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github3712.d/expected.tags",
    "content": "XXX_TOP\tinput.sv\t/^`define XXX_TOP  foo_top$/;\"\td\nXXX\tinput.sv\t/^`define XXX          foo$/;\"\td\nxxx_begin\tinput.sv\t/^`define xxx_begin$/;\"\td\nxxx_end\tinput.sv\t/^`define xxx_end$/;\"\td\n`XXX\tinput.sv\t/^module `XXX ();$/;\"\tm\nadd_t\tinput.sv\t/^`define add_t(f) f``_t$/;\"\td\n`XXX_TOP\tinput.sv\t/^module `XXX_TOP();$/;\"\tm\nfoo\tinput.sv\t/^class foo;$/;\"\tC\nnew\tinput.sv\t/^  function new(string name=\"...\");$/;\"\tf\tclass:foo\nname\tinput.sv\t/^  function new(string name=\"...\");$/;\"\tp\tfunction:foo.new\n`add_t\tinput.sv\t/^  var `add_t(foo) = '0;$/;\"\tr\tclass:foo\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github3712.d/input.sv",
    "content": "// https://github.com/universal-ctags/ctags/issues/3712\n\n`define XXX_TOP  foo_top\n`define XXX          foo\n`define xxx_begin\n`define xxx_end\n\nmodule `XXX ();\n`define add_t(f) f``_t\nendmodule\n\nmodule `XXX_TOP();\n  `XXX U_XXX ();  // cannot be detected\nendmodule\n\nclass foo;\n  // from a design pattern in UVM\n  `xxx_begin(bar) // must be ignored\n  `xxx_end        // must be ignored\n\n  function new(string name=\"...\");\n    super.new(name);\n  endfunction : new\n\n  // from systemverilog-directive.d\n  var `add_t(foo) = '0;\nendclass : foo\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github4056.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github4056.d/expected.tags",
    "content": "my_enum\tinput.sv\t/^} my_enum;$/;\"\tT\nOTHER_VAL1\tinput.sv\t/^  OTHER_VAL1,$/;\"\tc\ttypedef:my_enum\nOTHER_VAL2\tinput.sv\t/^  OTHER_VAL2$/;\"\tc\ttypedef:my_enum\ne\tinput.sv\t/^my_enum e;$/;\"\tr\nO\tinput.sv\t/^class O;$/;\"\tC\ncomplex0_s\tinput.sv\t/^  } [1:0] complex0_s, complex1_s;$/;\"\tS\tclass:O\na\tinput.sv\t/^    logic a,b ;$/;\"\tw\tstruct:O.complex0_s\nb\tinput.sv\t/^    logic a,b ;$/;\"\tw\tstruct:O.complex0_s\ns0\tinput.sv\t/^    logic [15:0] [7:0] s0 , s1;$/;\"\tw\tstruct:O.complex0_s\ns1\tinput.sv\t/^    logic [15:0] [7:0] s0 , s1;$/;\"\tw\tstruct:O.complex0_s\nstruct0_s\tinput.sv\t/^    } [15:0] [7:0] struct0_s, struct1_s;$/;\"\tw\tstruct:O.complex0_s\nstruct1_s\tinput.sv\t/^    } [15:0] [7:0] struct0_s, struct1_s;$/;\"\tw\tstruct:O.complex0_s\nenum00_e\tinput.sv\t/^    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tw\tstruct:O.complex0_s\nenum01_e\tinput.sv\t/^    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tw\tstruct:O.complex0_s\nenum10_e\tinput.sv\t/^    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tw\tstruct:O.complex0_s\nenum11_e\tinput.sv\t/^    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tw\tstruct:O.complex0_s\nd\tinput.sv\t/^    bit[7:0][1:0]d,e;$/;\"\tw\tstruct:O.complex0_s\ne\tinput.sv\t/^    bit[7:0][1:0]d,e;$/;\"\tw\tstruct:O.complex0_s\ncomplex1_s\tinput.sv\t/^  } [1:0] complex0_s, complex1_s;$/;\"\tS\tclass:O\na\tinput.sv\t/^    logic a,b ;$/;\"\tw\tstruct:O.complex1_s\nb\tinput.sv\t/^    logic a,b ;$/;\"\tw\tstruct:O.complex1_s\ns0\tinput.sv\t/^    logic [15:0] [7:0] s0 , s1;$/;\"\tw\tstruct:O.complex1_s\ns1\tinput.sv\t/^    logic [15:0] [7:0] s0 , s1;$/;\"\tw\tstruct:O.complex1_s\nstruct0_s\tinput.sv\t/^    } [15:0] [7:0] struct0_s, struct1_s;$/;\"\tw\tstruct:O.complex1_s\nstruct1_s\tinput.sv\t/^    } [15:0] [7:0] struct0_s, struct1_s;$/;\"\tw\tstruct:O.complex1_s\nenum00_e\tinput.sv\t/^    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tw\tstruct:O.complex1_s\nenum01_e\tinput.sv\t/^    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tw\tstruct:O.complex1_s\nenum10_e\tinput.sv\t/^    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tw\tstruct:O.complex1_s\nenum11_e\tinput.sv\t/^    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tw\tstruct:O.complex1_s\nd\tinput.sv\t/^    bit[7:0][1:0]d,e;$/;\"\tw\tstruct:O.complex1_s\ne\tinput.sv\t/^    bit[7:0][1:0]d,e;$/;\"\tw\tstruct:O.complex1_s\nifdef1_e\tinput.sv\t/^} ifdef1_e;$/;\"\tT\nxxx\tinput.sv\t/^    xxx,$/;\"\tc\ttypedef:ifdef1_e\nyyy\tinput.sv\t/^    yyy$/;\"\tc\ttypedef:ifdef1_e\nzzz\tinput.sv\t/^    zzz = 'x$/;\"\tc\ttypedef:ifdef1_e\nifdef2_e\tinput.sv\t/^} ifdef2_e;$/;\"\tT\naaa\tinput.sv\t/^    aaa,$/;\"\tc\ttypedef:ifdef2_e\nbbb\tinput.sv\t/^    bbb$/;\"\tc\ttypedef:ifdef2_e\nccc\tinput.sv\t/^    ,ccc$/;\"\tc\ttypedef:ifdef2_e\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github4056.d/input.sv",
    "content": "// https://github.com/universal-ctags/ctags/issues/4056\n\ntypedef enum {\n  `include \"test1.txt\"\n  OTHER_VAL1,\n  `include \"test2.txt\"\n  OTHER_VAL2\n} my_enum;\n\nmy_enum e;\n\n// from Units/parser-verilog.r/systemverilog-struct.d/input.sv\nclass O;\n  // complex struct\n  struct packed signed {\n  `include \"test1.txt\"\n    logic a,b ;\n    logic [15:0] [7:0] s0 , s1;\n  `include \"test1.txt\"\n    struct {\n  `include \"test1.txt\"\n      logic x, y; // not emitted\n  `include \"test1.txt\"\n    } [15:0] [7:0] struct0_s, struct1_s;\n  `include \"test1.txt\"\n    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;\n  `include \"test1.txt\"\n    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;\n    bit[7:0][1:0]d,e;\n  `include \"test1.txt\"\n  } [1:0] complex0_s, complex1_s;\nendclass\n\n// https://github.com/universal-ctags/ctags/issues/\ntypedef enum logic {\n    xxx,\n    yyy\n`ifdef foo\n    ,\n    zzz = 'x\n`endif\n} ifdef1_e;\n\ntypedef enum logic {\n    aaa,\n    bbb\n`ifdef bar\n    ,ccc\n`endif\n} ifdef2_e;\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github4109.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github4109.d/expected.tags",
    "content": "new_test_case\tinput.sv\t/^package new_test_case; \\/\\/ for better readability$/;\"\tK\ntest_func_A\tinput.sv\t/^  function signed test_func_A();$/;\"\tf\tpackage:new_test_case\ntest_task_A\tinput.sv\t/^  task test_task_A; endtask$/;\"\tt\tpackage:new_test_case\ntest_func_B\tinput.sv\t/^  function not_care_class test_func_B();$/;\"\tf\tpackage:new_test_case\ntest_func_C\tinput.sv\t/^  function not_care_class#(int) test_func_C  ();$/;\"\tf\tpackage:new_test_case\ntest_func_D\tinput.sv\t/^  function not_care_class #(int) test_func_D (   );$/;\"\tf\tpackage:new_test_case\ntest_func_E\tinput.sv\t/^  function not_care_class #( .T(int) ) test_func_E();$/;\"\tf\tpackage:new_test_case\ntest_func_F\tinput.sv\t/^  function unsigned [7:0] class_scope::test_func_F();$/;\"\tf\tclass:new_test_case.class_scope\ntest_func_G\tinput.sv\t/^  function not_care_class class_scope::test_func_G();$/;\"\tf\tclass:new_test_case.class_scope\ntest_func_H\tinput.sv\t/^  function not_care_class#(IF) class_scope::test_func_H();$/;\"\tf\tclass:new_test_case.class_scope\ntest_func_I\tinput.sv\t/^  function not_care_class  #(IF)  class_scope::test_func_I;$/;\"\tf\tclass:new_test_case.class_scope\ntest_func_J\tinput.sv\t/^  function not_care_class#(.T(real), .size(4)) class_scope::test_func_J;$/;\"\tf\tclass:new_test_case.class_scope\nnew\tinput.sv\t/^  function class_scope::new;$/;\"\tf\tclass:new_test_case.class_scope\ntest_task_B\tinput.sv\t/^  task class_scope::test_task_B ()  ;$/;\"\tt\tclass:new_test_case.class_scope\ntest_func_K\tinput.sv\t/^  function not_care_class::TYPE test_func_K ();$/;\"\tf\tpackage:new_test_case\ntest_func_L\tinput.sv\t/^  function automatic bit signed [15:0] test_func_L();$/;\"\tf\tpackage:new_test_case\ntest_func_M\tinput.sv\t/^  function not_care_class#(bit [2:0]) :: TYPE test_func_M;$/;\"\tf\tpackage:new_test_case\ntest_func_N\tinput.sv\t/^  function not_care_class  #(.T(bit [2:0]))::TYPE test_func_N;$/;\"\tf\tpackage:new_test_case\ntest_func_O\tinput.sv\t/^  function not_care_class # (100)  ::TYPE test_func_O  ()  ;$/;\"\tf\tpackage:new_test_case\ntest_var_A\tinput.sv\t/^  int test_var_A = 100;$/;\"\tr\tpackage:new_test_case\ntest_func_P\tinput.sv\t/^  function static bit test_func_P; endfunction$/;\"\tf\tpackage:new_test_case\nnew\tinput.sv\t/^  function new; endfunction$/;\"\tf\tpackage:new_test_case\ntest_task_C\tinput.sv\t/^  task test_task_C; endtask$/;\"\tt\tpackage:new_test_case\ntest_func_Q\tinput.sv\t/^  function not_care_class :: TYPE scope::test_func_Q;$/;\"\tf\tclass:new_test_case.scope\ntest_func_R\tinput.sv\t/^  function void test_func_R ();$/;\"\tf\tpackage:new_test_case\ntest_func_S\tinput.sv\t/^  function not_care_class#(shortint)::TYPE scope::test_func_S (  );$/;\"\tf\tclass:new_test_case.scope\ntest_func_T\tinput.sv\t/^  function not_care_class # ( .IF( IF ) )::TYPE scope:: test_func_T;$/;\"\tf\tclass:new_test_case.scope\ntest_var_B\tinput.sv\t/^  longint test_var_B = 1024;$/;\"\tr\tpackage:new_test_case\ntest_task_D\tinput.sv\t/^  task test_task_D (  );$/;\"\tt\tpackage:new_test_case\ntest_func_U\tinput.sv\t/^  function void test_func_U; endfunction$/;\"\tf\tpackage:new_test_case\nnew\tinput.sv\t/^  function scope::new ();$/;\"\tf\tclass:new_test_case.scope\ntest_task_E\tinput.sv\t/^  task scope:: test_task_E;$/;\"\tt\tclass:new_test_case.scope\nLOW\tinput.sv\t/^  localparam LOW = 8;$/;\"\tc\tpackage:new_test_case\nHIGH\tinput.sv\t/^  localparam HIGH = 15;$/;\"\tc\tpackage:new_test_case\ntest_func_V\tinput.sv\t/^  function automatic logic [ LOW : HIGH ] test_func_V ();$/;\"\tf\tpackage:new_test_case\ntest_func_W\tinput.sv\t/^  function automatic int signed [LOW-1:HIGH-1] test_func_W;$/;\"\tf\tpackage:new_test_case\ntest_func_EA\tinput.sv\t/^  function automatic A:: B#(IF) ::TYPE test_func_EA ();$/;\"\tf\tpackage:new_test_case\ntest_func_EB\tinput.sv\t/^  function automatic unsigned [ LOW -1: HIGH -1] scope:: test_func_EB;$/;\"\tf\tclass:new_test_case.scope\ntest_wrong_task\tinput.sv\t/^  task static A :: B :: C # (.T (int)) :: test_wrong_task ();$/;\"\tt\tclass:new_test_case.A.B.C\ntest_wrong_function\tinput.sv\t/^  function static A::B::TYPE scope # ( .T (IF) ) :: test_wrong_function;$/;\"\tf\tclass:new_test_case.scope\ntest_specifier_A\tinput.sv\t/^  function :initial void test_specifier_A (); endfunction$/;\"\tf\tpackage:new_test_case\ntest_specifier_B\tinput.sv\t/^  function :extends void test_specifier_B (); endfunction$/;\"\tf\tpackage:new_test_case\ntest_specifier_C\tinput.sv\t/^  function :final   void test_specifier_C (); endfunction$/;\"\tf\tpackage:new_test_case\ntest_specifier_D\tinput.sv\t/^  function : initial : final void test_specifier_D (); endfunction$/;\"\tf\tpackage:new_test_case\ntest_specifier_E\tinput.sv\t/^  function : extends : final void test_specifier_E (); endfunction$/;\"\tf\tpackage:new_test_case\ntest_specifier_F\tinput.sv\t/^  function : final : initial void test_specifier_F (); endfunction$/;\"\tf\tpackage:new_test_case\ntest_specifier_G\tinput.sv\t/^  function : final : extends void test_specifier_G (); endfunction$/;\"\tf\tpackage:new_test_case\ntest_specifier_H\tinput.sv\t/^  virtual function : initial A :: B :: TYPE test_specifier_H ();$/;\"\tf\tpackage:new_test_case\ntest_specifier_I\tinput.sv\t/^  virtual function :extends :final A::B::C A::B::test_specifier_I;$/;\"\tf\tclass:new_test_case.A.B\ntest_specifier_J\tinput.sv\t/^  task :initial :final A :: B :: test_specifier_J ;$/;\"\tt\tclass:new_test_case.A.B\ntest_specifier_K\tinput.sv\t/^  task :final : extends A #(IF)::B ::test_specifier_K () ;$/;\"\tt\tclass:new_test_case.A.B\nnew\tinput.sv\t/^  function corner_A::corner_B :: new (  );$/;\"\tf\tclass:new_test_case.corner_A.corner_B\ntest_func_XA\tinput.sv\t/^  function A::B::C::D #(int) corner_A:: test_func_XA();$/;\"\tf\tclass:new_test_case.corner_A\ntest_func_XB\tinput.sv\t/^  function void corner_A # ( .T(real) ) :: test_func_XB;$/;\"\tf\tclass:new_test_case.corner_A\ntest_func_XC\tinput.sv\t/^  function A # ( IF ) :: B :: C corner_A :: test_func_XC ();$/;\"\tf\tclass:new_test_case.corner_A\ntest_func_XD\tinput.sv\t/^  function A :: B # ( 100 )::C::D#(int) test_func_XD;$/;\"\tf\tpackage:new_test_case\ntest_task_F\tinput.sv\t/^  task A::B::C::test_task_F ;$/;\"\tt\tclass:new_test_case.A.B.C\ntest_func_Y\tinput.sv\t/^  function void test_func_Y ( int Y_in_A, int Y_in_B );$/;\"\tf\tpackage:new_test_case\nY_in_A\tinput.sv\t/^  function void test_func_Y ( int Y_in_A, int Y_in_B );$/;\"\tp\tfunction:new_test_case.test_func_Y\nY_in_B\tinput.sv\t/^  function void test_func_Y ( int Y_in_A, int Y_in_B );$/;\"\tp\tfunction:new_test_case.test_func_Y\ntest_task_G\tinput.sv\t/^  task A #(real):: B#(IF)::C#( .size(64) ) :: D :: test_task_G ();$/;\"\tt\tclass:new_test_case.A.B.C.D\ntest_var_C\tinput.sv\t/^  int test_var_C = 1024;$/;\"\tr\tpackage:new_test_case\ntest_func_Z\tinput.sv\t/^  function logic [LOW:HIGH] test_func_Z ();$/;\"\tf\tpackage:new_test_case\ntest_class\tinput.sv\t/^  class test_class;$/;\"\tC\tpackage:new_test_case\ntest_func_EC\tinput.sv\t/^    static function A::B::C::D test_func_EC () ;$/;\"\tf\tclass:new_test_case.test_class\ntest_task_EB\tinput.sv\t/^  static task test_class::test_task_EB ; endtask$/;\"\tt\tclass:new_test_case.test_class\ntest_func_ED\tinput.sv\t/^  static function A:: B ::C::D  test_class :: test_func_ED;$/;\"\tf\tclass:new_test_case.test_class\nuvm_component\tinput.sv\t/^virtual class uvm_component extends uvm_report_object;$/;\"\tC\nconfig_mode_t\tinput.sv\t/^  typedef bit [1:0] config_mode_t;$/;\"\tT\tclass:uvm_component\ntest_ok\tinput.sv\t/^function void uvm_component::test_ok();$/;\"\tf\tclass:uvm_component\nreturn_scope_res\tinput.sv\t/^function uvm_component::config_mode_t uvm_component::return_scope_res();$/;\"\tf\tclass:uvm_component\ntest_scope_variable\tinput.sv\t/^int test_scope_variable;$/;\"\tr\nm_set_cl_msg_args\tinput.sv\t/^function void uvm_component::m_set_cl_msg_args();$/;\"\tf\tclass:uvm_component\nm_set_cl_verb\tinput.sv\t/^function void uvm_component::m_set_cl_verb; return; endfunction$/;\"\tf\tclass:uvm_component\nm_set_cl_action\tinput.sv\t/^function void uvm_component::m_set_cl_action; return; endfunction$/;\"\tf\tclass:uvm_component\nm_set_cl_sev\tinput.sv\t/^function void uvm_component::m_set_cl_sev; return; endfunction$/;\"\tf\tclass:uvm_component\ntest_case_A\tinput.sv\t/^package test_case_A;$/;\"\tK\ntest_ok\tinput.sv\t/^  function void test_ok;$/;\"\tf\tpackage:test_case_A\noops\tinput.sv\t/^  function extern_class::data_type oops();$/;\"\tf\tpackage:test_case_A\nOOPS\tinput.sv\t/^  function extern_class#(int)::data_type OOPS();$/;\"\tf\tpackage:test_case_A\nstill_ok\tinput.sv\t/^  function void still_ok();$/;\"\tf\tpackage:test_case_A\ntest_case_B\tinput.sv\t/^package test_case_B;$/;\"\tK\nfoo\tinput.sv\t/^  function void foo; \\/\\/ OK$/;\"\tf\tpackage:test_case_B\ntest_ok\tinput.sv\t/^  function uvm_queue#(uvm_callback) test_ok(uvm_object obj);$/;\"\tf\tpackage:test_case_B\nobj\tinput.sv\t/^  function uvm_queue#(uvm_callback) test_ok(uvm_object obj);$/;\"\tp\tfunction:test_case_B.test_ok\nTEST_OK\tinput.sv\t/^  function uvm_queue #(uvm_callback) TEST_OK(uvm_object obj);$/;\"\tf\tpackage:test_case_B\nobj\tinput.sv\t/^  function uvm_queue #(uvm_callback) TEST_OK(uvm_object obj);$/;\"\tp\tfunction:test_case_B.TEST_OK\nbar\tinput.sv\t/^  function void bar(); \\/\\/ OK$/;\"\tf\tpackage:test_case_B\noops\tinput.sv\t/^  function uvm_queue #(uvm_callback)::data_type oops(uvm_object obj);$/;\"\tf\tpackage:test_case_B\nobj\tinput.sv\t/^  function uvm_queue #(uvm_callback)::data_type oops(uvm_object obj);$/;\"\tp\tfunction:test_case_B.oops\ntest_scope_var\tinput.sv\t/^    int test_scope_var = 1;$/;\"\tr\tfunction:test_case_B.oops\nstill_ok\tinput.sv\t/^  function void still_ok();$/;\"\tf\tpackage:test_case_B\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github4109.d/input.sv",
    "content": "\n// ---------------------------------------------------------------------------\n// TEST CASE for `processFunction()` to parse `function` and `task` body\n// ---------------------------------------------------------------------------\n\npackage new_test_case; // for better readability\n\n  // 1. Normal function.\n  // -----------------------------------------------------------------\n  function signed test_func_A();\n  endfunction\n  task test_task_A; endtask\n\n  // 2. Normal function return class type.\n  // -----------------------------------------------------------------\n  // 2.1 return Normal class.\n  function not_care_class test_func_B();\n  endfunction\n  // 2.2 return parameterized class without space.\n  function not_care_class#(int) test_func_C  ();\n  endfunction\n  // 2.3 return parameterized class with space.\n  function not_care_class #(int) test_func_D (   );\n  endfunction\n  // 2.4 return parameterized class with parameter.\n  function not_care_class #( .T(int) ) test_func_E();\n  endfunction\n\n  // 3. The prototype of the class is declared in another file,\n  //    and the specific implementation is here.\n  // -----------------------------------------------------------------\n  // 3.1 Normal function.\n  function unsigned [7:0] class_scope::test_func_F();\n  endfunction\n  // 3.2 return Normal class.\n  function not_care_class class_scope::test_func_G();\n  endfunction\n  // 3.3 return parameterized class without space.\n  function not_care_class#(IF) class_scope::test_func_H();\n  endfunction\n  // 3.4 return parameterized class with space.\n  function not_care_class  #(IF)  class_scope::test_func_I;\n  endfunction\n  // 3.5 return parameterized class with parameter.\n  function not_care_class#(.T(real), .size(4)) class_scope::test_func_J;\n  endfunction\n  // 3.6 task or new function\n  function class_scope::new;\n  endfunction\n  task class_scope::test_task_B ()  ;\n  endtask\n\n  // 4. Normal function: return type from a class ( with `::` ).\n  // -----------------------------------------------------------------\n  // 4.1 from a Normal class\n  function not_care_class::TYPE test_func_K ();\n  endfunction\n  // Subsequent parsing is not affected.\n  function automatic bit signed [15:0] test_func_L();\n  endfunction\n  // 4.2 from a parameterized class\n  function not_care_class#(bit [2:0]) :: TYPE test_func_M;\n  endfunction\n  function not_care_class  #(.T(bit [2:0]))::TYPE test_func_N;\n  endfunction\n  function not_care_class # (100)  ::TYPE test_func_O  ()  ;\n  endfunction\n  // Subsequent parsing is not affected.\n  int test_var_A = 100;\n  function static bit test_func_P; endfunction\n  // 4.3 task or new function\n  function new; endfunction\n  task test_task_C; endtask\n\n  // 5. function with class_scope && return type with class_scope\n  // -----------------------------------------------------------------\n  // 5.1 from a Normal class\n  function not_care_class :: TYPE scope::test_func_Q;\n  endfunction\n  // Subsequent parsing is not affected\n  function void test_func_R ();\n  endfunction\n  // 5.2 from a parameterized class\n  function not_care_class#(shortint)::TYPE scope::test_func_S (  );\n  endfunction\n  function not_care_class # ( .IF( IF ) )::TYPE scope:: test_func_T;\n  endfunction\n  // Subsequent parsing is not affected\n  longint test_var_B = 1024;\n  task test_task_D (  );\n  endtask\n  function void test_func_U; endfunction\n  // 5.3 task or new function\n  function scope::new ();\n  endfunction\n  task scope:: test_task_E;\n  endtask\n\n  // 6. Corner TEST\n  // -----------------------------------------------------------------\n  localparam LOW = 8;\n  localparam HIGH = 15;\n  function automatic logic [ LOW : HIGH ] test_func_V ();\n  endfunction\n  function automatic int signed [LOW-1:HIGH-1] test_func_W;\n  endfunction\n  function automatic A:: B#(IF) ::TYPE test_func_EA ();\n  endfunction\n  function automatic unsigned [ LOW -1: HIGH -1] scope:: test_func_EB;\n  endfunction\n  task static A :: B :: C # (.T (int)) :: test_wrong_task ();\n  endtask\n  function static A::B::TYPE scope # ( .T (IF) ) :: test_wrong_function;\n  endfunction\n  function :initial void test_specifier_A (); endfunction\n  function :extends void test_specifier_B (); endfunction\n  function :final   void test_specifier_C (); endfunction\n  function : initial : final void test_specifier_D (); endfunction\n  function : extends : final void test_specifier_E (); endfunction\n  function : final : initial void test_specifier_F (); endfunction\n  function : final : extends void test_specifier_G (); endfunction\n  virtual function : initial A :: B :: TYPE test_specifier_H ();\n  endfunction\n  virtual function :extends :final A::B::C A::B::test_specifier_I;\n  endfunction\n  task :initial :final A :: B :: test_specifier_J ;\n  endtask\n  task :final : extends A #(IF)::B ::test_specifier_K () ;\n  endtask\n  function corner_A::corner_B :: new (  );\n  endfunction\n  function A::B::C::D #(int) corner_A:: test_func_XA();\n  endfunction\n  function void corner_A # ( .T(real) ) :: test_func_XB;\n  endfunction\n  function A # ( IF ) :: B :: C corner_A :: test_func_XC ();\n  endfunction\n  function A :: B # ( 100 )::C::D#(int) test_func_XD;\n  endfunction\n  task A::B::C::test_task_F ;\n  endtask\n  function void test_func_Y ( int Y_in_A, int Y_in_B );\n  endfunction\n  task A #(real):: B#(IF)::C#( .size(64) ) :: D :: test_task_G ();\n  endtask\n  int test_var_C = 1024;\n  function logic [LOW:HIGH] test_func_Z ();\n  endfunction\n  class test_class;\n    static function A::B::C::D test_func_EC () ;\n    endfunction\n    extern static task test_task_EB ();\n    extern static function A :: B :: C :: D test_func_ED ();\n  endclass\n  static task test_class::test_task_EB ; endtask\n  static function A:: B ::C::D  test_class :: test_func_ED;\n  endfunction\n\nendpackage : new_test_case\n\n// ---------------------------------------------------------------------------\n// REF : https://github.com/universal-ctags/ctags/issues/4109\n// ---------------------------------------------------------------------------\n\nvirtual class uvm_component extends uvm_report_object;\n  typedef bit [1:0] config_mode_t;\n  extern virtual function void test_ok();\n  // ------------------------------------------------------\n  extern virtual function config_mode_t return_scope_res();\n  // ------------------------------------------------------\n  extern function void m_set_cl_msg_args();\n  extern function void m_set_cl_verb;\n  extern function void m_set_cl_action;\n  extern function void m_set_cl_sev;\nendclass\n\nfunction void uvm_component::test_ok();\n  // function body, this function is parsed OK\nendfunction\n\n// ---------------------------------------------------------------------\nfunction uvm_component::config_mode_t uvm_component::return_scope_res();\n  return 2'b00;\nendfunction\n// ---------------------------------------------------------------------\n\nint test_scope_variable;\n\nfunction void uvm_component::m_set_cl_msg_args();\nendfunction\nfunction void uvm_component::m_set_cl_verb; return; endfunction\nfunction void uvm_component::m_set_cl_action; return; endfunction\nfunction void uvm_component::m_set_cl_sev; return; endfunction\n\npackage test_case_A;\n  typedef class extern_class;\n\n  function void test_ok;\n  endfunction\n\n  function extern_class::data_type oops();\n  endfunction\n\n  function extern_class#(int)::data_type OOPS();\n  endfunction\n\n  function void still_ok();\n  endfunction\nendpackage\n\npackage test_case_B;\n  function void foo; // OK\n    // something\n  endfunction\n\n  // return type is a parameterized class, OK\n  function uvm_queue#(uvm_callback) test_ok(uvm_object obj);\n    return null;\n  endfunction\n\n  // OK, even if there is a space between `uvm_queue` and `#(`\n  function uvm_queue #(uvm_callback) TEST_OK(uvm_object obj);\n    return null;\n  endfunction\n\n  // Subsequent parsing is not affected\n  function void bar(); // OK\n    // something\n  endfunction\n\n  // ----------------------------------------------------------------\n  function uvm_queue #(uvm_callback)::data_type oops(uvm_object obj);\n    int test_scope_var = 1;\n    return null;\n  endfunction\n  // ----------------------------------------------------------------\n\n  function void still_ok();\n    // function body\n  endfunction\nendpackage\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github646.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github646.d/expected.tags",
    "content": "function\tinput.sv\t/^function 0:/;\"\tf\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github646.d/input.sv",
    "content": "function 0:"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-github646.d/validator",
    "content": "NONE\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-illegal.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-illegal.d/input-0-2724.sv",
    "content": "module m2724;\n  struct\n  {\n    s* ; // pushMembers() caused infinite loop : #2724\n  }\n  logic foo;\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-illegal.d/input-1-2738.sv",
    "content": "// #2738: processDesignElementL() go into infinite loop\ninterface static 0\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-illegal.d/input.sv",
    "content": ""
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-interface.d/args.ctags",
    "content": "--extras=+q\n--kinds-systemverilog=+Q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-interface.d/expected.tags",
    "content": "intf\tinput.sv\t/^interface intf ($/;\"\tI\nin1\tinput.sv\t/^    input in1,$/;\"\tp\tinterface:intf\nintf.in1\tinput.sv\t/^    input in1,$/;\"\tp\tinterface:intf\nin2\tinput.sv\t/^    input [11:0] in2,$/;\"\tp\tinterface:intf\nintf.in2\tinput.sv\t/^    input [11:0] in2,$/;\"\tp\tinterface:intf\nout\tinput.sv\t/^    output out,$/;\"\tp\tinterface:intf\nintf.out\tinput.sv\t/^    output out,$/;\"\tp\tinterface:intf\niout\tinput.sv\t/^    inout iout$/;\"\tp\tinterface:intf\nintf.iout\tinput.sv\t/^    inout iout$/;\"\tp\tinterface:intf\na\tinput.sv\t/^logic a, b, c, d;$/;\"\tr\tinterface:intf\nintf.a\tinput.sv\t/^logic a, b, c, d;$/;\"\tr\tinterface:intf\nb\tinput.sv\t/^logic a, b, c, d;$/;\"\tr\tinterface:intf\nintf.b\tinput.sv\t/^logic a, b, c, d;$/;\"\tr\tinterface:intf\nc\tinput.sv\t/^logic a, b, c, d;$/;\"\tr\tinterface:intf\nintf.c\tinput.sv\t/^logic a, b, c, d;$/;\"\tr\tinterface:intf\nd\tinput.sv\t/^logic a, b, c, d;$/;\"\tr\tinterface:intf\nintf.d\tinput.sv\t/^logic a, b, c, d;$/;\"\tr\tinterface:intf\ne\tinput.sv\t/^logic [11:0] e;$/;\"\tr\tinterface:intf\nintf.e\tinput.sv\t/^logic [11:0] e;$/;\"\tr\tinterface:intf\nmaster\tinput.sv\t/^modport master (input a, b, output c, d, e);$/;\"\tM\tinterface:intf\nintf.master\tinput.sv\t/^modport master (input a, b, output c, d, e);$/;\"\tM\tinterface:intf\nslave\tinput.sv\t/^modport slave (output a, b, input c, d, e);$/;\"\tM\tinterface:intf\nintf.slave\tinput.sv\t/^modport slave (output a, b, input c, d, e);$/;\"\tM\tinterface:intf\nintf_static\tinput.sv\t/^interface static intf_static;$/;\"\tI\nlogic_static\tinput.sv\t/^    logic logic_static;$/;\"\tr\tinterface:intf_static\nintf_static.logic_static\tinput.sv\t/^    logic logic_static;$/;\"\tr\tinterface:intf_static\nintf_automatic\tinput.sv\t/^interface automatic intf_automatic;$/;\"\tI\nlogic_automatic\tinput.sv\t/^    logic logic_automatic;$/;\"\tr\tinterface:intf_automatic\nintf_automatic.logic_automatic\tinput.sv\t/^    logic logic_automatic;$/;\"\tr\tinterface:intf_automatic\nexternal_interface\tinput.sv\t/^extern interface external_interface;$/;\"\tQ\nubus_env\tinput.sv\t/^class ubus_env extends uvm_env;$/;\"\tC\nvif\tinput.sv\t/^  protected virtual interface ubus_if vif;$/;\"\tr\tclass:ubus_env\nubus_env.vif\tinput.sv\t/^  protected virtual interface ubus_if vif;$/;\"\tr\tclass:ubus_env\nhas_bus_monitor\tinput.sv\t/^  protected bit has_bus_monitor = 1;$/;\"\tr\tclass:ubus_env\nubus_env.has_bus_monitor\tinput.sv\t/^  protected bit has_bus_monitor = 1;$/;\"\tr\tclass:ubus_env\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-interface.d/input.sv",
    "content": "interface intf (\n    input in1,\n    input [11:0] in2,\n    output out,\n    inout iout\n);\n\nlogic a, b, c, d;\nlogic [11:0] e;\n\nmodport master (input a, b, output c, d, e);\nmodport slave (output a, b, input c, d, e);\n\nendinterface : intf\n\ninterface static intf_static;\n    logic logic_static;\nendinterface\n\ninterface automatic intf_automatic;\n    logic logic_automatic;\nendinterface\n\nextern interface external_interface;\n\n// from UVM-1.2\nclass ubus_env extends uvm_env;\n\n  // Virtual Interface variable\n  protected virtual interface ubus_if vif;\n\n  // Control properties\n  protected bit has_bus_monitor = 1;\nendclass : ubus_env\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-module.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-module.d/expected.tags",
    "content": "user_t\tinput.sv\t/^typedef logic user_t;$/;\"\tT\nblk_dut1\tinput.sv\t/^module blk_dut1 (input user_t apb, input logic rst); $/;\"\tm\napb\tinput.sv\t/^module blk_dut1 (input user_t apb, input logic rst); $/;\"\tp\tmodule:blk_dut1\nrst\tinput.sv\t/^module blk_dut1 (input user_t apb, input logic rst); $/;\"\tp\tmodule:blk_dut1\nblk_dut2\tinput.sv\t/^module blk_dut2 (user_t apb, input logic rst);$/;\"\tm\napb\tinput.sv\t/^module blk_dut2 (user_t apb, input logic rst);$/;\"\tp\tmodule:blk_dut2\nrst\tinput.sv\t/^module blk_dut2 (user_t apb, input logic rst);$/;\"\tp\tmodule:blk_dut2\nblk_dut3\tinput.sv\t/^module blk_dut3 (logic apb, input logic rst);$/;\"\tm\napb\tinput.sv\t/^module blk_dut3 (logic apb, input logic rst);$/;\"\tp\tmodule:blk_dut3\nrst\tinput.sv\t/^module blk_dut3 (logic apb, input logic rst);$/;\"\tp\tmodule:blk_dut3\nblk_dut4\tinput.sv\t/^module blk_dut4 #(int BASE_ADDR='h0) (user_t apb,$/;\"\tm\nBASE_ADDR\tinput.sv\t/^module blk_dut4 #(int BASE_ADDR='h0) (user_t apb,$/;\"\tc\tmodule:blk_dut4\napb\tinput.sv\t/^module blk_dut4 #(int BASE_ADDR='h0) (user_t apb,$/;\"\tp\tmodule:blk_dut4\nrst\tinput.sv\t/^                                     input logic rst);$/;\"\tp\tmodule:blk_dut4\nM1\tinput.sv\t/^module M1;$/;\"\tm\nM2\tinput.sv\t/^module M2 ();$/;\"\tm\nM3\tinput.sv\t/^module M3 (a);$/;\"\tm\na\tinput.sv\t/^  input a;$/;\"\tp\tmodule:M3\nM4\tinput.sv\t/^module M4 (a, b);$/;\"\tm\na\tinput.sv\t/^  input a, b;$/;\"\tp\tmodule:M4\nb\tinput.sv\t/^  input a, b;$/;\"\tp\tmodule:M4\nM5\tinput.sv\t/^module M5 (input user_t a, b);$/;\"\tm\na\tinput.sv\t/^module M5 (input user_t a, b);$/;\"\tp\tmodule:M5\nb\tinput.sv\t/^module M5 (input user_t a, b);$/;\"\tp\tmodule:M5\nM6\tinput.sv\t/^module M6 (logic a);$/;\"\tm\na\tinput.sv\t/^module M6 (logic a);$/;\"\tp\tmodule:M6\nM7\tinput.sv\t/^module M7 (logic a, output b);$/;\"\tm\na\tinput.sv\t/^module M7 (logic a, output b);$/;\"\tp\tmodule:M7\nb\tinput.sv\t/^module M7 (logic a, output b);$/;\"\tp\tmodule:M7\nM8\tinput.sv\t/^module M8 (user_t a, b);$/;\"\tm\na\tinput.sv\t/^module M8 (user_t a, b);$/;\"\tp\tmodule:M8\nb\tinput.sv\t/^module M8 (user_t a, b);$/;\"\tp\tmodule:M8\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-module.d/input.sv",
    "content": "// user defined type port\ntypedef logic user_t;\nmodule blk_dut1 (input user_t apb, input logic rst); \nendmodule\nmodule blk_dut2 (user_t apb, input logic rst);\nendmodule\nmodule blk_dut3 (logic apb, input logic rst);\nendmodule\nmodule blk_dut4 #(int BASE_ADDR='h0) (user_t apb,\n                                     input logic rst);\nendmodule\n\n// no port\nmodule M1;\nendmodule\n\n// no port\nmodule M2 ();\nendmodule\n\n// non-ANSI\nmodule M3 (a);\n  input a;\nendmodule\n\n// non-ANSI\nmodule M4 (a, b);\n  input a, b;\nendmodule\n\n// ANSI\nmodule M5 (input user_t a, b);\nendmodule\n\n// ANSI\nmodule M6 (logic a);\nendmodule\n\n// ANSI\nmodule M7 (logic a, output b);\nendmodule\n\n// ANSI\nmodule M8 (user_t a, b);\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-net-var.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-net-var.d/expected.tags",
    "content": "net_decl\tinput.sv\t/^module net_decl;$/;\"\tm\na\tinput.sv\t/^  trireg a;$/;\"\tn\tmodule:net_decl\ncap1\tinput.sv\t/^  trireg (large) #(0,0,50) cap1;$/;\"\tn\tmodule:net_decl\ncap2\tinput.sv\t/^  trireg (small) signed [3:0] cap2;$/;\"\tn\tmodule:net_decl\nw\tinput.sv\t/^  wire w = vara & varb; \\/\\/ net with a continuous assignment$/;\"\tn\tmodule:net_decl\nv\tinput.sv\t/^  logic v = consta & constb; \\/\\/ variable with initialization$/;\"\tr\tmodule:net_decl\nvw\tinput.sv\t/^  logic vw; \\/\\/ no initial assignment$/;\"\tr\tmodule:net_decl\ncirc\tinput.sv\t/^  real circ;$/;\"\tr\tmodule:net_decl\ntop\tinput.sv\t/^module top();$/;\"\tm\niBus\tinput.sv\t/^  interconnect [0:1] iBus;$/;\"\tn\tmodule:top\nl1\tinput.sv\t/^  lDriver l1(iBus[0]);$/;\"\ti\tmodule:top\ttyperef:module:lDriver\nr1\tinput.sv\t/^  rDriver r1(iBus[1]);$/;\"\ti\tmodule:top\ttyperef:module:rDriver\nm1\tinput.sv\t/^  rlMod m1(iBus);$/;\"\ti\tmodule:top\ttyperef:module:rlMod\nrlMod\tinput.sv\t/^module rlMod(input interconnect [0:1] iBus);$/;\"\tm\niBus\tinput.sv\t/^module rlMod(input interconnect [0:1] iBus);$/;\"\tp\tmodule:rlMod\nl1\tinput.sv\t/^  lMod l1(iBus[0]);$/;\"\ti\tmodule:rlMod\ttyperef:module:lMod\nr1\tinput.sv\t/^  rMod r1(iBus[1]);$/;\"\ti\tmodule:rlMod\ttyperef:module:rMod\nNet_declarations\tinput.sv\t/^module Net_declarations;$/;\"\tm\ncap1\tinput.sv\t/^  trireg (large) logic #(0,0,0) cap1;$/;\"\tn\tmodule:Net_declarations\naddressT\tinput.sv\t/^  typedef logic [31:0] addressT;$/;\"\tT\tmodule:Net_declarations\nw1\tinput.sv\t/^  wire addressT w1;$/;\"\tn\tmodule:Net_declarations\nmemsig\tinput.sv\t/^  wire struct packed { logic ecc; logic [7:0] data; } memsig;$/;\"\tn\tmodule:Net_declarations\nw\tinput.sv\t/^  wire w; \\/\\/ equivalent to \"wire logic w;\"$/;\"\tn\tmodule:Net_declarations\nw\tinput.sv\t/^  wire logic w;$/;\"\tn\tmodule:Net_declarations\nww\tinput.sv\t/^  wire [15:0] ww; \\/\\/ equivalent to \"wire logic [15:0] ww;\"$/;\"\tn\tmodule:Net_declarations\nww\tinput.sv\t/^  wire logic [15:0] ww;$/;\"\tn\tmodule:Net_declarations\nw1\tinput.sv\t/^  interconnect w1;              \\/\\/ legal$/;\"\tn\tmodule:Net_declarations\nw2\tinput.sv\t/^  interconnect [3:0] w2;        \\/\\/ legal$/;\"\tn\tmodule:Net_declarations\nw3\tinput.sv\t/^  interconnect [3:0] w3 [1:0];  \\/\\/ legal$/;\"\tn\tmodule:Net_declarations\nwT\tinput.sv\t/^  nettype T wT;$/;\"\tN\tmodule:Net_declarations\nwTsum\tinput.sv\t/^  nettype T wTsum with Tsum;$/;\"\tN\tmodule:Net_declarations\nw1\tinput.sv\t/^  wT w1;$/;\"\tr\tmodule:Net_declarations\nw2\tinput.sv\t/^  wT w2[8];$/;\"\tr\tmodule:Net_declarations\nw3\tinput.sv\t/^  wTsum w3;$/;\"\tr\tmodule:Net_declarations\nw4\tinput.sv\t/^  wTsum w4[8];$/;\"\tr\tmodule:Net_declarations\nTR\tinput.sv\t/^  typedef real TR[5];$/;\"\tT\tmodule:Net_declarations\nwTR\tinput.sv\t/^  nettype TR wTR;$/;\"\tN\tmodule:Net_declarations\nw5\tinput.sv\t/^  wTR w5;$/;\"\tr\tmodule:Net_declarations\nw6\tinput.sv\t/^  wTR w6[8];$/;\"\tr\tmodule:Net_declarations\nVariable_declarations\tinput.sv\t/^module Variable_declarations;$/;\"\tm\ns1\tinput.sv\t/^  shortint s1, s2[0:9];$/;\"\tr\tmodule:Variable_declarations\ns2\tinput.sv\t/^  shortint s1, s2[0:9];$/;\"\tr\tmodule:Variable_declarations\nv\tinput.sv\t/^  var v; \\/\\/ equivalent to \"var logic v;\"$/;\"\tr\tmodule:Variable_declarations\nvw\tinput.sv\t/^  var [15:0] vw; \\/\\/ equivalent to \"var logic [15:0] vw;\"$/;\"\tr\tmodule:Variable_declarations\nstatus\tinput.sv\t/^  var enum bit { clear, error } status;$/;\"\tr\tmodule:Variable_declarations\ndata_in\tinput.sv\t/^  input var logic data_in;$/;\"\tp\tmodule:Variable_declarations\nr\tinput.sv\t/^  var reg r;$/;\"\tr\tmodule:Variable_declarations\ni\tinput.sv\t/^  int i = 0;$/;\"\tr\tmodule:Variable_declarations\nVector_declarations\tinput.sv\t/^module Vector_declarations;$/;\"\tm\nw\tinput.sv\t/^  wand w; \\/\\/ a scalar \"wand\" net$/;\"\tn\tmodule:Vector_declarations\nbusa\tinput.sv\t/^  tri [15:0] busa; \\/\\/ a 16-bit bus$/;\"\tn\tmodule:Vector_declarations\nstoreit\tinput.sv\t/^  trireg (small) storeit; \\/\\/ a charge storage node of strength small$/;\"\tn\tmodule:Vector_declarations\na\tinput.sv\t/^  logic a; \\/\\/ a scalar variable$/;\"\tr\tmodule:Vector_declarations\nv\tinput.sv\t/^  logic[3:0] v; \\/\\/ a 4-bit vector made up of (from most to$/;\"\tr\tmodule:Vector_declarations\nsigned_reg\tinput.sv\t/^  logic signed [3:0] signed_reg; \\/\\/ a 4-bit vector in range -8 to 7$/;\"\tr\tmodule:Vector_declarations\nb\tinput.sv\t/^  logic [-1:4] b; \\/\\/ a 6-bit vector$/;\"\tr\tmodule:Vector_declarations\nw1\tinput.sv\t/^  wire w1, w2; \\/\\/ declares two nets$/;\"\tn\tmodule:Vector_declarations\nw2\tinput.sv\t/^  wire w1, w2; \\/\\/ declares two nets$/;\"\tn\tmodule:Vector_declarations\nx\tinput.sv\t/^  logic [4:0] x, y, z; \\/\\/ declares three 5-bit variables$/;\"\tr\tmodule:Vector_declarations\ny\tinput.sv\t/^  logic [4:0] x, y, z; \\/\\/ declares three 5-bit variables$/;\"\tr\tmodule:Vector_declarations\nz\tinput.sv\t/^  logic [4:0] x, y, z; \\/\\/ declares three 5-bit variables$/;\"\tr\tmodule:Vector_declarations\nbus64\tinput.sv\t/^  tri1 scalared [63:0] bus64; \\/\\/a bus that will be expanded$/;\"\tn\tmodule:Vector_declarations\ndata\tinput.sv\t/^  tri vectored [31:0] data; \\/\\/a bus that may or may not be expanded$/;\"\tn\tmodule:Vector_declarations\nString_data_type\tinput.sv\t/^module String_data_type;$/;\"\tm\ndefault_name\tinput.sv\t/^  parameter string default_name = \"John Smith\";$/;\"\tc\tmodule:String_data_type\nmyName\tinput.sv\t/^  string myName = default_name;$/;\"\tr\tmodule:String_data_type\nc\tinput.sv\t/^  byte c = \"A\"; \\/\\/ assigns to c \"A\"$/;\"\tr\tmodule:String_data_type\nb\tinput.sv\t/^  bit [10:0] b = \"\\\\x41\"; \\/\\/ assigns to b 'b000_0100_0001$/;\"\tr\tmodule:String_data_type\nh\tinput.sv\t/^  bit [1:4][7:0] h = \"hello\" ; \\/\\/ assigns to h \"ello\"$/;\"\tr\tmodule:String_data_type\ns0\tinput.sv\t/^  string s0 = \"String literal assign\";\\/\\/ sets s0 to \"String literal assign\"$/;\"\tr\tmodule:String_data_type\ns1\tinput.sv\t/^  string s1 = \"hello\\\\0world\"; \\/\\/ sets s1 to \"helloworld\"$/;\"\tr\tmodule:String_data_type\nb\tinput.sv\t/^  bit [11:0] b = 12'ha41;$/;\"\tr\tmodule:String_data_type\ns2\tinput.sv\t/^  string s2 = string'(b); \\/\\/ sets s2 to 16'h0a41$/;\"\tr\tmodule:String_data_type\nr_t\tinput.sv\t/^  typedef logic [15:0] r_t;$/;\"\tT\tmodule:String_data_type\nr\tinput.sv\t/^  r_t r;$/;\"\tr\tmodule:String_data_type\ni\tinput.sv\t/^  integer i = 1;$/;\"\tr\tmodule:String_data_type\nb\tinput.sv\t/^  string b = \"\";$/;\"\tr\tmodule:String_data_type\na\tinput.sv\t/^  string a = {\"Hi\", b};$/;\"\tr\tmodule:String_data_type\nevent_data_type\tinput.sv\t/^module event_data_type;$/;\"\tm\ndone\tinput.sv\t/^  event done; \\/\\/ declare a new event called done$/;\"\te\tmodule:event_data_type\ndone_too\tinput.sv\t/^  event done_too = done; \\/\\/ declare done_too as alias to done$/;\"\te\tmodule:event_data_type\nempty\tinput.sv\t/^  event empty = null; \\/\\/ event variable with no synchronization object$/;\"\te\tmodule:event_data_type\nuser_define_types_0\tinput.sv\t/^module user_define_types_0;$/;\"\tm\nintP\tinput.sv\t/^  typedef int intP;$/;\"\tT\tmodule:user_define_types_0\na\tinput.sv\t/^  intP a, b;$/;\"\tr\tmodule:user_define_types_0\nb\tinput.sv\t/^  intP a, b;$/;\"\tr\tmodule:user_define_types_0\nintf_i\tinput.sv\t/^interface intf_i;$/;\"\tI\ndata_t\tinput.sv\t/^  typedef int data_t;$/;\"\tT\tinterface:intf_i\nsub\tinput.sv\t/^module sub(intf_i p);$/;\"\tm\np\tinput.sv\t/^module sub(intf_i p);$/;\"\tp\tmodule:sub\nmy_data_t\tinput.sv\t/^  typedef p.data_t my_data_t;$/;\"\tT\tmodule:sub\ndata\tinput.sv\t/^  my_data_t data;$/;\"\tr\tmodule:sub\ncbs\tinput.sv\t/^module cbs;$/;\"\tm\ncbs_t\tinput.sv\t/^  typedef p[10].data_t cbs_t;$/;\"\tT\tmodule:cbs\nuser_define_types_1\tinput.sv\t/^module user_define_types_1;$/;\"\tm\nenum_test\tinput.sv\t/^module enum_test;$/;\"\tm\nlight1\tinput.sv\t/^  enum {red, yellow, green} light1, light2; \\/\\/ anonymous int type$/;\"\tE\tmodule:enum_test\nred\tinput.sv\t/^  enum {red, yellow, green} light1, light2; \\/\\/ anonymous int type$/;\"\tc\tenum:enum_test.light1\nyellow\tinput.sv\t/^  enum {red, yellow, green} light1, light2; \\/\\/ anonymous int type$/;\"\tc\tenum:enum_test.light1\ngreen\tinput.sv\t/^  enum {red, yellow, green} light1, light2; \\/\\/ anonymous int type$/;\"\tc\tenum:enum_test.light1\nlight2\tinput.sv\t/^  enum {red, yellow, green} light1, light2; \\/\\/ anonymous int type$/;\"\tE\tmodule:enum_test\nred\tinput.sv\t/^  enum {red, yellow, green} light1, light2; \\/\\/ anonymous int type$/;\"\tc\tenum:enum_test.light2\nyellow\tinput.sv\t/^  enum {red, yellow, green} light1, light2; \\/\\/ anonymous int type$/;\"\tc\tenum:enum_test.light2\ngreen\tinput.sv\t/^  enum {red, yellow, green} light1, light2; \\/\\/ anonymous int type$/;\"\tc\tenum:enum_test.light2\nstate\tinput.sv\t/^  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;$/;\"\tE\tmodule:enum_test\nIDLE\tinput.sv\t/^  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;$/;\"\tc\tenum:enum_test.state\nXX\tinput.sv\t/^  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;$/;\"\tc\tenum:enum_test.state\nS1\tinput.sv\t/^  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;$/;\"\tc\tenum:enum_test.state\nS2\tinput.sv\t/^  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;$/;\"\tc\tenum:enum_test.state\nnext\tinput.sv\t/^  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;$/;\"\tE\tmodule:enum_test\nIDLE\tinput.sv\t/^  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;$/;\"\tc\tenum:enum_test.next\nXX\tinput.sv\t/^  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;$/;\"\tc\tenum:enum_test.next\nS1\tinput.sv\t/^  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;$/;\"\tc\tenum:enum_test.next\nS2\tinput.sv\t/^  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;$/;\"\tc\tenum:enum_test.next\nmedal\tinput.sv\t/^  enum {bronze=3, silver, gold} medal; \\/\\/ silver=4, gold=5$/;\"\tE\tmodule:enum_test\nbronze\tinput.sv\t/^  enum {bronze=3, silver, gold} medal; \\/\\/ silver=4, gold=5$/;\"\tc\tenum:enum_test.medal\nsilver\tinput.sv\t/^  enum {bronze=3, silver, gold} medal; \\/\\/ silver=4, gold=5$/;\"\tc\tenum:enum_test.medal\ngold\tinput.sv\t/^  enum {bronze=3, silver, gold} medal; \\/\\/ silver=4, gold=5$/;\"\tc\tenum:enum_test.medal\nmedal2\tinput.sv\t/^  enum bit [3:0] {bronze='h3, silver, gold='h5} medal2;$/;\"\tE\tmodule:enum_test\nbronze\tinput.sv\t/^  enum bit [3:0] {bronze='h3, silver, gold='h5} medal2;$/;\"\tc\tenum:enum_test.medal2\nsilver\tinput.sv\t/^  enum bit [3:0] {bronze='h3, silver, gold='h5} medal2;$/;\"\tc\tenum:enum_test.medal2\ngold\tinput.sv\t/^  enum bit [3:0] {bronze='h3, silver, gold='h5} medal2;$/;\"\tc\tenum:enum_test.medal2\nmedal3\tinput.sv\t/^  enum bit [3:0] {bronze=4'h3, silver, gold=4'h5} medal3;$/;\"\tE\tmodule:enum_test\nbronze\tinput.sv\t/^  enum bit [3:0] {bronze=4'h3, silver, gold=4'h5} medal3;$/;\"\tc\tenum:enum_test.medal3\nsilver\tinput.sv\t/^  enum bit [3:0] {bronze=4'h3, silver, gold=4'h5} medal3;$/;\"\tc\tenum:enum_test.medal3\ngold\tinput.sv\t/^  enum bit [3:0] {bronze=4'h3, silver, gold=4'h5} medal3;$/;\"\tc\tenum:enum_test.medal3\nboolean\tinput.sv\t/^  typedef enum {NO, YES} boolean;$/;\"\tT\tmodule:enum_test\nNO\tinput.sv\t/^  typedef enum {NO, YES} boolean;$/;\"\tc\ttypedef:enum_test.boolean\nYES\tinput.sv\t/^  typedef enum {NO, YES} boolean;$/;\"\tc\ttypedef:enum_test.boolean\nmyvar\tinput.sv\t/^  boolean myvar; \\/\\/ named type$/;\"\tr\tmodule:enum_test\nE1\tinput.sv\t/^  typedef enum { add=10, sub[5], jmp[6:8] } E1; \\/\\/ FIXME$/;\"\tT\tmodule:enum_test\nadd\tinput.sv\t/^  typedef enum { add=10, sub[5], jmp[6:8] } E1; \\/\\/ FIXME$/;\"\tc\ttypedef:enum_test.E1\nsub\tinput.sv\t/^  typedef enum { add=10, sub[5], jmp[6:8] } E1; \\/\\/ FIXME$/;\"\tc\ttypedef:enum_test.E1\njmp\tinput.sv\t/^  typedef enum { add=10, sub[5], jmp[6:8] } E1; \\/\\/ FIXME$/;\"\tc\ttypedef:enum_test.E1\nvr\tinput.sv\t/^  enum { register[2] = 1, register[2:4] = 10 } vr; \\/\\/ FIXME$/;\"\tE\tmodule:enum_test\nregister\tinput.sv\t/^  enum { register[2] = 1, register[2:4] = 10 } vr; \\/\\/ FIXME$/;\"\tc\tenum:enum_test.vr\nregister\tinput.sv\t/^  enum { register[2] = 1, register[2:4] = 10 } vr; \\/\\/ FIXME$/;\"\tc\tenum:enum_test.vr\ncmplx_enum1\tinput.sv\t/^  enum logic signed [3:0] { foo, bar } [1:0] cmplx_enum1; $/;\"\tE\tmodule:enum_test\nfoo\tinput.sv\t/^  enum logic signed [3:0] { foo, bar } [1:0] cmplx_enum1; $/;\"\tc\tenum:enum_test.cmplx_enum1\nbar\tinput.sv\t/^  enum logic signed [3:0] { foo, bar } [1:0] cmplx_enum1; $/;\"\tc\tenum:enum_test.cmplx_enum1\ncmplx_enum2\tinput.sv\t/^  enum logic unsigned [3:0] { foo, bar } [] cmplx_enum2; $/;\"\tE\tmodule:enum_test\nfoo\tinput.sv\t/^  enum logic unsigned [3:0] { foo, bar } [] cmplx_enum2; $/;\"\tc\tenum:enum_test.cmplx_enum2\nbar\tinput.sv\t/^  enum logic unsigned [3:0] { foo, bar } [] cmplx_enum2; $/;\"\tc\tenum:enum_test.cmplx_enum2\ndelay_control\tinput.sv\t/^module delay_control #(d, e);$/;\"\tm\nd\tinput.sv\t/^module delay_control #(d, e);$/;\"\tc\tmodule:delay_control\ne\tinput.sv\t/^module delay_control #(d, e);$/;\"\tc\tmodule:delay_control\nrega\tinput.sv\t/^  int rega, regb, regr;$/;\"\tr\tmodule:delay_control\nregb\tinput.sv\t/^  int rega, regb, regr;$/;\"\tr\tmodule:delay_control\nregr\tinput.sv\t/^  int rega, regb, regr;$/;\"\tr\tmodule:delay_control\ncont_a\tinput.sv\t/^module cont_a;$/;\"\tm\nmynet\tinput.sv\t/^  wire (strong1, pull0) mynet = enable;$/;\"\tn\tmodule:cont_a\ncont_b\tinput.sv\t/^module cont_b;$/;\"\tm\nmynet\tinput.sv\t/^  wire mynet;$/;\"\tn\tmodule:cont_b\ndelay_control_wire\tinput.sv\t/^module delay_control_wire #(d, e);$/;\"\tm\nd\tinput.sv\t/^module delay_control_wire #(d, e);$/;\"\tc\tmodule:delay_control_wire\ne\tinput.sv\t/^module delay_control_wire #(d, e);$/;\"\tc\tmodule:delay_control_wire\nwireA\tinput.sv\t/^  wire #10 wireA;$/;\"\tn\tmodule:delay_control_wire\nwirea\tinput.sv\t/^  wire #10 wirea = wireb;$/;\"\tn\tmodule:delay_control_wire\nwireb\tinput.sv\t/^  wire #d wireb = wireb;$/;\"\tn\tmodule:delay_control_wire\nwirec\tinput.sv\t/^  wire #((d+e)\\/2) wirec = wireb;$/;\"\tn\tmodule:delay_control_wire\nwired\tinput.sv\t/^  wire #wirer wired = wirer + 1;$/;\"\tn\tmodule:delay_control_wire\nw$ire\tinput.sv\t/^  wire w$ire, wire$;  \\/\\/ '$' included$/;\"\tn\tmodule:delay_control_wire\nwire$\tinput.sv\t/^  wire w$ire, wire$;  \\/\\/ '$' included$/;\"\tn\tmodule:delay_control_wire\nrst\tinput.sv\t/^module rst;$/;\"\tm\ntrst_n\tinput.sv\t/^  logic trst_n;$/;\"\tr\tmodule:rst\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-net-var.d/input.sv",
    "content": "// LRM 6.3 Data types\nmodule net_decl;\n  // 6.3.2.1 Charge strength\n  trireg a;\n  trireg (large) #(0,0,50) cap1;\n  trireg (small) signed [3:0] cap2;\n\n  // 6.5 Nets and variables\n  wire w = vara & varb; // net with a continuous assignment\n  logic v = consta & constb; // variable with initialization\n  logic vw; // no initial assignment\n  assign vw = vara & varb; // continuous assignment to a variable\n  real circ;\n  assign circ = 2.0 * PI * R; // continuous assignment to a variable\n\n  // 6.6 Net types\n  // 6.6.7 User-defined nettypes\n  // add later !!!\nendmodule\n\n// 6.6.8 Generic interconnect\nmodule top();\n  interconnect [0:1] iBus;\n  lDriver l1(iBus[0]);\n  rDriver r1(iBus[1]);\n  rlMod m1(iBus);\nendmodule : top\n\nmodule rlMod(input interconnect [0:1] iBus);\n  lMod l1(iBus[0]);\n  rMod r1(iBus[1]);\nendmodule : rlMod\n\n// 6.7 Net declarations\nmodule Net_declarations;\n  // 6.7.1 Net declarations with built-in net types\n  trireg (large) logic #(0,0,0) cap1;\n  typedef logic [31:0] addressT;\n  wire addressT w1;\n  wire struct packed { logic ecc; logic [7:0] data; } memsig;\n\n  wire w; // equivalent to \"wire logic w;\"\n  wire logic w;\n  wire [15:0] ww; // equivalent to \"wire logic [15:0] ww;\"\n  wire logic [15:0] ww;\n\n  interconnect w1;              // legal\n  interconnect [3:0] w2;        // legal\n  interconnect [3:0] w3 [1:0];  // legal\n\n  // 6.7.2 Net declarations with user-defined nettypes\n  nettype T wT;\n  nettype T wTsum with Tsum;\n  wT w1;\n  wT w2[8];\n  wTsum w3;\n  wTsum w4[8];\n  typedef real TR[5];\n  nettype TR wTR;\n  wTR w5;\n  wTR w6[8];\nendmodule\n\n// 6.8 Variable declarations\nmodule Variable_declarations;\n  shortint s1, s2[0:9];\n\n  var v; // equivalent to \"var logic v;\"\n  var [15:0] vw; // equivalent to \"var logic [15:0] vw;\"\n  var enum bit { clear, error } status;\n  input var logic data_in;\n  var reg r;\n\n  int i = 0;\nendmodule\n\n// 6.9 Vector declarations\nmodule Vector_declarations;\n  // 6.9.1 Specifying vectors\n  wand w; // a scalar \"wand\" net\n  tri [15:0] busa; // a 16-bit bus\n  trireg (small) storeit; // a charge storage node of strength small\n  logic a; // a scalar variable\n  logic[3:0] v; // a 4-bit vector made up of (from most to\n  // least significant)v[3], v[2], v[1], and v[0]\n  logic signed [3:0] signed_reg; // a 4-bit vector in range -8 to 7\n  logic [-1:4] b; // a 6-bit vector\n  wire w1, w2; // declares two nets\n  logic [4:0] x, y, z; // declares three 5-bit variables\n\n  // 6.9.2 Vector net accessibility\n  tri1 scalared [63:0] bus64; //a bus that will be expanded\n  tri vectored [31:0] data; //a bus that may or may not be expanded\nendmodule\n\n// 6.16 String data type\nmodule String_data_type;\n  parameter string default_name = \"John Smith\";\n  string myName = default_name;\n\n  byte c = \"A\"; // assigns to c \"A\"\n  bit [10:0] b = \"\\x41\"; // assigns to b 'b000_0100_0001\n  bit [1:4][7:0] h = \"hello\" ; // assigns to h \"ello\"\n\n  string s0 = \"String literal assign\";// sets s0 to \"String literal assign\"\n  string s1 = \"hello\\0world\"; // sets s1 to \"helloworld\"\n  bit [11:0] b = 12'ha41;\n  string s2 = string'(b); // sets s2 to 16'h0a41\n\n  typedef logic [15:0] r_t;\n  r_t r;\n  integer i = 1;\n  string b = \"\";\n  string a = {\"Hi\", b};\n  r = r_t'(a); // OK\n  b = string'(r); // OK\n  b = \"Hi\"; // OK\n  b = {5{\"Hi\"}}; // OK\n  a = {i{\"Hi\"}}; // OK (non-constant replication)\n  //r = {i{\"Hi\"}}; // invalid (non-constant replication)\n  a = {i{b}}; // OK\n  a = {a,b}; // OK\n  a = {\"Hi\",b}; // OK\n  r = {\"H\",\"\"}; // yields \"H\\0\". \"\" is converted to 8'b0\n  b = {\"H\",\"\"}; // yields \"H\". \"\" is the empty string\n  a[0] = \"h\"; // OK, same as a[0] = \"cough\"\n  //a[0] = b; // invalid, requires a cast\n  a[1] = \"\\0\"; // ignored, a is unchanged\nendmodule\n\n// 6.17 Event data type\nmodule event_data_type;\n  event done; // declare a new event called done\n  event done_too = done; // declare done_too as alias to done\n  event empty = null; // event variable with no synchronization object\nendmodule\n\n// 6.18 User-defined types\nmodule user_define_types_0;\n  typedef int intP;\n  intP a, b;\nendmodule\n\ninterface intf_i;\n  typedef int data_t;\nendinterface\n\n// interface based typedef\nmodule sub(intf_i p);\n  typedef p.data_t my_data_t;\n  my_data_t data;\nendmodule\n\n// interface based typedef with constant bit select\nmodule cbs;\n  typedef p[10].data_t cbs_t;\nendmodule\n\nmodule user_define_types_1;\n  // forward typedef\n  typedef enum type_identifier;\n  typedef struct type_identifier;\n  typedef union type_identifier;\n  typedef class type_identifier;\n  typedef interface class type_identifier;\n  typedef type_identifier;\nendmodule\n\n// 6.19 Enumerations\nmodule enum_test;\n  enum {red, yellow, green} light1, light2; // anonymous int type\n  // Syntax error: IDLE=2'b00, XX=2'bx <ERROR>, S1=2'b01, S2=2'b10\n  //enum bit [1:0] {IDLE, XX='x, S1=2'b01, S2=2'b10} state, next;\n  // Correct: IDLE=0, XX='x, S1=1, S2=2\n  enum integer {IDLE, XX='x, S1='b01, S2='b10} state, next;\n  // Syntax error: IDLE=0, XX='x, S1=??, S2=??\n  //enum integer {IDLE, XX='x, S1, S2} state, next;\n  enum {bronze=3, silver, gold} medal; // silver=4, gold=5\n\n  // Correct declaration - bronze and gold are unsized\n  enum bit [3:0] {bronze='h3, silver, gold='h5} medal2;\n  // Correct declaration - bronze and gold sizes are redundant\n  enum bit [3:0] {bronze=4'h3, silver, gold=4'h5} medal3;\n\n  // 6.19.1 Defining new data types as enumerated types\n  typedef enum {NO, YES} boolean;\n  boolean myvar; // named type\n\n  // 6.19.2 Enumerated type ranges\n  typedef enum { add=10, sub[5], jmp[6:8] } E1; // FIXME\n  enum { register[2] = 1, register[2:4] = 10 } vr; // FIXME\n\n  // original\n  enum logic signed [3:0] { foo, bar } [1:0] cmplx_enum1; \n  enum logic unsigned [3:0] { foo, bar } [] cmplx_enum2; \n\nendmodule\n\n// 9.4.1 Delay control\nmodule delay_control #(d, e);\n  int rega, regb, regr;\n  initial begin\n    #10 rega = regb;\n    #d rega = regb; // d is defined as a parameter\n    #((d+e)/2) rega = regb; // delay is average of d and e\n    #regr regr = regr + 1; // delay is the value in regr\n  end\nendmodule\n\n// 10.3 Continuous assignments\nmodule cont_a;\n  wire (strong1, pull0) mynet = enable;\nendmodule\n\nmodule cont_b;\n  wire mynet;\n  assign (strong1, pull0) mynet = enable;\nendmodule\n\n// 10.3.3 Continuous assignment delays\nmodule delay_control_wire #(d, e);\n  wire #10 wireA;\n  assign wireA = wireB;\n  wire #10 wirea = wireb;\n  wire #d wireb = wireb;\n  wire #((d+e)/2) wirec = wireb;\n  wire #wirer wired = wirer + 1;\n  wire w$ire, wire$;  // '$' included\nendmodule\n\n// orignal : LRM 5.8 Time literals\nmodule rst;\n  logic trst_n;\n  initial begin\n    #10.5fs trst_n = 1'b0;\n    #10ps   trst_n = 1'b1;\n    #10ns   trst_n = 1'b0;\n    #10us   trst_n = 1'b1;\n    #10ms   trst_n = 1'b0;\n    #10s    trst_n = 1'b1;\n  end\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-net-var.d/validator",
    "content": "KNOWN-INVALIDATION\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-nocontext.d/args.ctags",
    "content": "--extras=+q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-nocontext.d/expected.tags",
    "content": "DEFINE\tinput.sv\t/^`define DEFINE$/;\"\td\nDEF_WITH_EQ\tinput.sv\t/^`define DEF_WITH_EQ = 1'd100$/;\"\td\nDEF_VALUE\tinput.sv\t/^`define DEF_VALUE   1'd100$/;\"\td\na\tinput.sv\t/^module a;$/;\"\tm\nPARAM\tinput.sv\t/^parameter PARAM = 1;$/;\"\tc\tmodule:a\na.PARAM\tinput.sv\t/^parameter PARAM = 1;$/;\"\tc\tmodule:a\nLOCALPARAM\tinput.sv\t/^localparam LOCALPARAM = 2**2;$/;\"\tc\tmodule:a\na.LOCALPARAM\tinput.sv\t/^localparam LOCALPARAM = 2**2;$/;\"\tc\tmodule:a\nSTATE1\tinput.sv\t/^localparam STATE1 = 4'h0,$/;\"\tc\tmodule:a\na.STATE1\tinput.sv\t/^localparam STATE1 = 4'h0,$/;\"\tc\tmodule:a\nSTATE2\tinput.sv\t/^           STATE2 = 4'h1,$/;\"\tc\tmodule:a\na.STATE2\tinput.sv\t/^           STATE2 = 4'h1,$/;\"\tc\tmodule:a\nSTATE3\tinput.sv\t/^           STATE3 = 4'h2,$/;\"\tc\tmodule:a\na.STATE3\tinput.sv\t/^           STATE3 = 4'h2,$/;\"\tc\tmodule:a\nSTATE4\tinput.sv\t/^           STATE4 = 4'h5    ,$/;\"\tc\tmodule:a\na.STATE4\tinput.sv\t/^           STATE4 = 4'h5    ,$/;\"\tc\tmodule:a\nSTATE5\tinput.sv\t/^           STATE5 = 4'h6    ,$/;\"\tc\tmodule:a\na.STATE5\tinput.sv\t/^           STATE5 = 4'h6    ,$/;\"\tc\tmodule:a\nSTATE6\tinput.sv\t/^           STATE6 = 4'h7    ,$/;\"\tc\tmodule:a\na.STATE6\tinput.sv\t/^           STATE6 = 4'h7    ,$/;\"\tc\tmodule:a\nSTATE7\tinput.sv\t/^           STATE7 = 4'h8;$/;\"\tc\tmodule:a\na.STATE7\tinput.sv\t/^           STATE7 = 4'h8;$/;\"\tc\tmodule:a\na\tinput.sv\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:a\na.a\tinput.sv\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:a\nb\tinput.sv\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:a\na.b\tinput.sv\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:a\nc\tinput.sv\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:a\na.c\tinput.sv\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:a\nd\tinput.sv\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:a\na.d\tinput.sv\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:a\ne\tinput.sv\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:a\na.e\tinput.sv\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:a\nf\tinput.sv\t/^reg f;$/;\"\tr\tmodule:a\na.f\tinput.sv\t/^reg f;$/;\"\tr\tmodule:a\ng\tinput.sv\t/^wire g;$/;\"\tn\tmodule:a\na.g\tinput.sv\t/^wire g;$/;\"\tn\tmodule:a\nk\tinput.sv\t/^real k;$/;\"\tr\tmodule:a\na.k\tinput.sv\t/^real k;$/;\"\tr\tmodule:a\nl\tinput.sv\t/^integer l;$/;\"\tr\tmodule:a\na.l\tinput.sv\t/^integer l;$/;\"\tr\tmodule:a\nm\tinput.sv\t/^byte m;$/;\"\tr\tmodule:a\na.m\tinput.sv\t/^byte m;$/;\"\tr\tmodule:a\nadd\tinput.sv\t/^task add ($/;\"\tt\tmodule:a\na.add\tinput.sv\t/^task add ($/;\"\tt\tmodule:a\nx\tinput.sv\t/^    input x, y,$/;\"\tp\ttask:a.add\na.add.x\tinput.sv\t/^    input x, y,$/;\"\tp\ttask:a.add\ny\tinput.sv\t/^    input x, y,$/;\"\tp\ttask:a.add\na.add.y\tinput.sv\t/^    input x, y,$/;\"\tp\ttask:a.add\nz\tinput.sv\t/^    output z$/;\"\tp\ttask:a.add\na.add.z\tinput.sv\t/^    output z$/;\"\tp\ttask:a.add\nmult\tinput.sv\t/^function mult ($/;\"\tf\tmodule:a\na.mult\tinput.sv\t/^function mult ($/;\"\tf\tmodule:a\nx\tinput.sv\t/^    input x,$/;\"\tp\tfunction:a.mult\na.mult.x\tinput.sv\t/^    input x,$/;\"\tp\tfunction:a.mult\ny\tinput.sv\t/^    input y);$/;\"\tp\tfunction:a.mult\na.mult.y\tinput.sv\t/^    input y);$/;\"\tp\tfunction:a.mult\ntemp\tinput.sv\t/^    reg temp;$/;\"\tr\tfunction:a.mult\na.mult.temp\tinput.sv\t/^    reg temp;$/;\"\tr\tfunction:a.mult\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-nocontext.d/input.sv",
    "content": "// Include module declaration in a comment\n// module wrong;\n// endmodule\n`define DEFINE\n\n`define DEF_WITH_EQ = 1'd100\n`define DEF_VALUE   1'd100\n\nmodule a;\nparameter PARAM = 1;\n\nlocalparam LOCALPARAM = 2**2;\n\nlocalparam STATE1 = 4'h0,\n           STATE2 = 4'h1,\n           STATE3 = 4'h2,\n           STATE4 = 4'h5    ,\n           STATE5 = 4'h6    ,\n           STATE6 = 4'h7    ,\n           STATE7 = 4'h8;\n\nwire a,b,c,d,e;\nreg f;\nwire g;\nreal k;\ninteger l;\n\nbyte m;\ninitial begin\n    add(a, b, f);\nend\n\ntask add (\n    input x, y,\n    output z\n);\nendtask : add\n\nfunction mult (\n    input x,\n    input y);\n    reg temp;\n    temp = x * y;\n    return temp;\nendfunction : mult\n\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-nulltags.d/args.ctags",
    "content": "--sort=no\n--extras=+{nulltag}\n--_xformat=%-16N %-10K %4n %-16F %C %{scopeKind}:%{scope}\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-nulltags.d/expected.tags-x",
    "content": "                 module        6 input.sv module \\ ; :\n                 struct       16 input.sv } \\ ; module:\n                 member       11 input.sv } \\ ; struct:.\neen              member       15 input.sv } \\een ; struct:.\nen               struct       26 input.sv } \\en ; module:\n                 member       21 input.sv } \\ ; struct:.en\nenn              member       25 input.sv } \\enn ; struct:.en\nn                module       29 input.sv module \\n ; :\n                 struct       39 input.sv } \\ ; module:n\n                 member       34 input.sv } \\ ; struct:n.\nnen              member       38 input.sv } \\nen ; struct:n.\nnn               struct       49 input.sv } \\nn ; module:n\n                 member       44 input.sv } \\ ; struct:n.nn\nnnn              member       48 input.sv } \\nnn ; struct:n.nn\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-nulltags.d/input.sv",
    "content": "/* Legend:\n * <e> = empty (null)\n * <n> = non-empty\n */\n\nmodule \\ ;\n\tstruct {\n\t\tstruct {\n\t\t\tlogic \\ ;\n\t\t\tlogic \\eeen ;\n\t\t} \\ ;\n\t\tstruct {\n\t\t\tlogic \\ ;\n\t\t\tlogic \\eenn ;\n\t\t} \\een ;\n\t} \\ ;\n\tstruct {\n\t\tstruct {\n\t\t\tlogic \\ ;\n\t\t\tlogic \\enen ;\n\t\t} \\ ;\n\t\tstruct {\n\t\t\tlogic \\ ;\n\t\t\tlogic \\ennn ;\n\t\t} \\enn ;\n\t} \\en ;\nendmodule\n\nmodule \\n ;\n\tstruct {\n\t\tstruct {\n\t\t\tlogic \\ ;\n\t\t\tlogic \\neen ;\n\t\t} \\ ;\n\t\tstruct {\n\t\t\tlogic \\ ;\n\t\t\tlogic \\nenn ;\n\t\t} \\nen ;\n\t} \\ ;\n\tstruct {\n\t\tstruct {\n\t\t\tlogic \\ ;\n\t\t\tlogic \\nnen ;\n\t\t} \\ ;\n\t\tstruct {\n\t\t\tlogic \\ ;\n\t\t\tlogic \\nnnn ;\n\t\t} \\nnn ;\n\t} \\nn ;\nendmodule\n\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-package.d/args.ctags",
    "content": "--kinds-systemverilog=+Q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-package.d/expected.tags",
    "content": "ComplexPkg\tinput.sv\t/^package ComplexPkg;$/;\"\tK\nComplex\tinput.sv\t/^    } Complex;$/;\"\tT\tpackage:ComplexPkg\ni\tinput.sv\t/^        shortreal i, r;$/;\"\tw\ttypedef:ComplexPkg.Complex\nr\tinput.sv\t/^        shortreal i, r;$/;\"\tw\ttypedef:ComplexPkg.Complex\nadd\tinput.sv\t/^    function Complex add(Complex a, b);$/;\"\tf\tpackage:ComplexPkg\na\tinput.sv\t/^    function Complex add(Complex a, b);$/;\"\tp\tfunction:ComplexPkg.add\nb\tinput.sv\t/^    function Complex add(Complex a, b);$/;\"\tp\tfunction:ComplexPkg.add\nmul\tinput.sv\t/^    function Complex mul(Complex a, b);$/;\"\tf\tpackage:ComplexPkg\na\tinput.sv\t/^    function Complex mul(Complex a, b);$/;\"\tp\tfunction:ComplexPkg.mul\nb\tinput.sv\t/^    function Complex mul(Complex a, b);$/;\"\tp\tfunction:ComplexPkg.mul\np\tinput.sv\t/^package p;$/;\"\tK\nbool_t\tinput.sv\t/^    typedef enum { FALSE, TRUE } bool_t;$/;\"\tT\tpackage:p\nFALSE\tinput.sv\t/^    typedef enum { FALSE, TRUE } bool_t;$/;\"\tc\ttypedef:p.bool_t\nTRUE\tinput.sv\t/^    typedef enum { FALSE, TRUE } bool_t;$/;\"\tc\ttypedef:p.bool_t\nq\tinput.sv\t/^package q;$/;\"\tK\nteeth_t\tinput.sv\t/^    typedef enum { ORIGINAL, FALSE } teeth_t;$/;\"\tT\tpackage:q\nORIGINAL\tinput.sv\t/^    typedef enum { ORIGINAL, FALSE } teeth_t;$/;\"\tc\ttypedef:q.teeth_t\nFALSE\tinput.sv\t/^    typedef enum { ORIGINAL, FALSE } teeth_t;$/;\"\tc\ttypedef:q.teeth_t\ntop1\tinput.sv\t/^module top1 ;$/;\"\tm\nmyteeth\tinput.sv\t/^    teeth_t myteeth;$/;\"\tr\tmodule:top1\ntop2\tinput.sv\t/^module top2 ;$/;\"\tm\nmyteeth\tinput.sv\t/^    teeth_t myteeth;$/;\"\tr\tmodule:top2\nA\tinput.sv\t/^package A;$/;\"\tK\ninstruction_t\tinput.sv\t/^    } instruction_t;$/;\"\tT\tpackage:A\nopcode\tinput.sv\t/^        bit [ 7:0] opcode;$/;\"\tw\ttypedef:A.instruction_t\naddr\tinput.sv\t/^        bit [23:0] addr;$/;\"\tw\ttypedef:A.instruction_t\nB\tinput.sv\t/^package B;$/;\"\tK\nboolean_t\tinput.sv\t/^    typedef enum bit {FALSE, TRUE} boolean_t;$/;\"\tT\tpackage:B\nFALSE\tinput.sv\t/^    typedef enum bit {FALSE, TRUE} boolean_t;$/;\"\tc\ttypedef:B.boolean_t\nTRUE\tinput.sv\t/^    typedef enum bit {FALSE, TRUE} boolean_t;$/;\"\tc\ttypedef:B.boolean_t\nM\tinput.sv\t/^module M import A::instruction_t, B::*;$/;\"\tm\nWIDTH\tinput.sv\t/^    #(WIDTH = 32)$/;\"\tc\tmodule:M\ndata\tinput.sv\t/^     (input [WIDTH-1:0] data,$/;\"\tp\tmodule:M\na\tinput.sv\t/^      input instruction_t a,$/;\"\tp\tmodule:M\nresult\tinput.sv\t/^      output [WIDTH-1:0] result,$/;\"\tp\tmodule:M\nOK\tinput.sv\t/^      output boolean_t OK$/;\"\tp\tmodule:M\nMyPackage\tinput.sv\t/^package MyPackage;$/;\"\tK\nMyData\tinput.sv\t/^    } MyData;$/;\"\tT\tpackage:MyPackage\na\tinput.sv\t/^        shortreal a;$/;\"\tw\ttypedef:MyPackage.MyData\nb\tinput.sv\t/^        real b;$/;\"\tw\ttypedef:MyPackage.MyData\nadd\tinput.sv\t/^    function MyData add(MyData x, y);$/;\"\tf\tpackage:MyPackage\nx\tinput.sv\t/^    function MyData add(MyData x, y);$/;\"\tp\tfunction:MyPackage.add\ny\tinput.sv\t/^    function MyData add(MyData x, y);$/;\"\tp\tfunction:MyPackage.add\nmul\tinput.sv\t/^    function MyData mul(MyData x, y);$/;\"\tf\tpackage:MyPackage\nx\tinput.sv\t/^    function MyData mul(MyData x, y);$/;\"\tp\tfunction:MyPackage.mul\ny\tinput.sv\t/^    function MyData mul(MyData x, y);$/;\"\tp\tfunction:MyPackage.mul\nvar_to_check_context\tinput.sv\t/^reg var_to_check_context;$/;\"\tr\nmod_a\tinput.sv\t/^module mod_a$/;\"\tm\nin_a\tinput.sv\t/^    input var logic in_a$/;\"\tp\tmodule:mod_a\nsig_a\tinput.sv\t/^    logic sig_a;$/;\"\tr\tmodule:mod_a\nmod_b\tinput.sv\t/^module mod_b$/;\"\tm\nin_b\tinput.sv\t/^    input var logic in_b$/;\"\tp\tmodule:mod_b\nsig_b\tinput.sv\t/^    logic sig_b;$/;\"\tr\tmodule:mod_b\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-package.d/input.sv",
    "content": "//\n// LRM: 26. Packages\n//\n// 26.2 Package declarations\npackage ComplexPkg;\n    typedef struct {\n        shortreal i, r;\n    } Complex;\n\n    function Complex add(Complex a, b);\n        add.r = a.r + b.r;\n        add.i = a.i + b.i;\n    endfunction\n\n    function Complex mul(Complex a, b);\n        mul.r = (a.r * b.r) - (a.i * b.i);\n        mul.i = (a.r * b.i) + (a.i * b.r);\n    endfunction\nendpackage : ComplexPkg\n\n// 26.3 Referencing data in packages\npackage p;\n    typedef enum { FALSE, TRUE } bool_t;\nendpackage\n\npackage q;\n    typedef enum { ORIGINAL, FALSE } teeth_t;\nendpackage\n\nmodule top1 ;\n    import p::*;\n    import q::teeth_t;\n\n    teeth_t myteeth;\n\n    initial begin\n        myteeth = q:: FALSE;    // OK:\n        //myteeth = FALSE;        // ERROR: Direct reference to FALSE refers to the\n    end // FALSE enumeration literal imported from p\nendmodule\n\nmodule top2 ;\n    import p::*;\n    import q::teeth_t, q::ORIGINAL, q::FALSE;\n\n    teeth_t myteeth;\n\n    initial begin\n        myteeth = FALSE; // OK: Direct reference to FALSE refers to the\n    end // FALSE enumeration literal imported from q\nendmodule\n\n// 26.4 Using packages in module headers\npackage A;\n    typedef struct {\n        bit [ 7:0] opcode;\n        bit [23:0] addr;\n    } instruction_t;\nendpackage: A\n\npackage B;\n    typedef enum bit {FALSE, TRUE} boolean_t;\nendpackage: B\n\nmodule M import A::instruction_t, B::*;\n    #(WIDTH = 32)\n     (input [WIDTH-1:0] data,\n      input instruction_t a,\n      output [WIDTH-1:0] result,\n      output boolean_t OK\n      );\n    // ...\nendmodule: M\n\n// original\npackage MyPackage;\n    typedef struct {\n        shortreal a;\n        real b;\n    } MyData;\n    function MyData add(MyData x, y);\n        add.a = x.a + y.a;\n    endfunction\n    function MyData mul(MyData x, y);\n        mul.b = x.b * y.b;\n    endfunction\nendpackage : MyPackage\n\nreg var_to_check_context;\n\n// multiple package import declarations, #3150\nmodule mod_a\n    import A::*, B::*;\n(\n    input var logic in_a\n);\n    logic sig_a;\nendmodule\n\nmodule mod_b\n    import A::*;\n    import B::*;\n(\n    input var logic in_b\n);\n    logic sig_b;\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-parameter.d/args.ctags",
    "content": "--sort=no\n--fields-SystemVerilog=+{parameter}\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-parameter.d/expected.tags",
    "content": "C\tinput.sv\t/^class C #($/;\"\tC\np\tinput.sv\t/^  int p = 1$/;\"\tc\tclass:C\tparameter:\nq\tinput.sv\t/^  parameter int q = 5;  \\/\\/ local parameter$/;\"\tc\tclass:C\nt\tinput.sv\t/^  static task t;$/;\"\tt\tclass:C\np\tinput.sv\t/^    int p;$/;\"\tr\ttask:C.t\nx\tinput.sv\t/^    int x = C::p;  \\/\\/ C::p disambiguates p$/;\"\tr\ttask:C.t\nC\tinput.sv\t/^class C #($/;\"\tC\np\tinput.sv\t/^    int p = 1,$/;\"\tc\tclass:C\tparameter:\nT\tinput.sv\t/^    type T = int$/;\"\tc\tclass:C\tparameter:\nf\tinput.sv\t/^function C::T C::f();$/;\"\tf\tclass:C\nC\tinput.sv\t/^virtual class C#(parameter DECODE_W, parameter ENCODE_W = $clog2(DECODE_W));$/;\"\tC\nDECODE_W\tinput.sv\t/^virtual class C#(parameter DECODE_W, parameter ENCODE_W = $clog2(DECODE_W));$/;\"\tc\tclass:C\tparameter:\nENCODE_W\tinput.sv\t/^virtual class C#(parameter DECODE_W, parameter ENCODE_W = $clog2(DECODE_W));$/;\"\tc\tclass:C\tparameter:\nENCODER_f\tinput.sv\t/^  static function logic [ENCODE_W-1:0] ENCODER_f$/;\"\tf\tclass:C\nDecodeIn\tinput.sv\t/^      (input logic [DECODE_W-1:0] DecodeIn);$/;\"\tp\tfunction:C.ENCODER_f\nDECODER_f\tinput.sv\t/^  static function logic [DECODE_W-1:0] DECODER_f$/;\"\tf\tclass:C\nEncodeIn\tinput.sv\t/^      (input logic [ENCODE_W-1:0] EncodeIn);$/;\"\tp\tfunction:C.DECODER_f\nPutImp\tinput.sv\t/^interface class PutImp #(type PUT_T = logic);$/;\"\tl\nPUT_T\tinput.sv\t/^interface class PutImp #(type PUT_T = logic);$/;\"\tc\tifclass:PutImp\tparameter:\nGetImp\tinput.sv\t/^interface class GetImp #(type GET_T = logic);$/;\"\tl\nGET_T\tinput.sv\t/^interface class GetImp #(type GET_T = logic);$/;\"\tc\tifclass:GetImp\tparameter:\nFifo\tinput.sv\t/^class Fifo #(type T = logic, int DEPTH = 1) implements PutImp#(T), GetImp#(T);$/;\"\tC\nT\tinput.sv\t/^class Fifo #(type T = logic, int DEPTH = 1) implements PutImp#(T), GetImp#(T);$/;\"\tc\tclass:Fifo\tparameter:\nDEPTH\tinput.sv\t/^class Fifo #(type T = logic, int DEPTH = 1) implements PutImp#(T), GetImp#(T);$/;\"\tc\tclass:Fifo\tparameter:\nmyFifo\tinput.sv\t/^  T myFifo[$:DEPTH-1];$/;\"\tr\tclass:Fifo\nput\tinput.sv\t/^  virtual function void put(T a);$/;\"\tf\tclass:Fifo\na\tinput.sv\t/^  virtual function void put(T a);$/;\"\tp\tfunction:Fifo.put\nget\tinput.sv\t/^  virtual function T get();$/;\"\tf\tclass:Fifo\nStack\tinput.sv\t/^class Stack #(type T = logic, int DEPTH = 1) implements PutImp#(T), GetImp#(T);$/;\"\tC\nT\tinput.sv\t/^class Stack #(type T = logic, int DEPTH = 1) implements PutImp#(T), GetImp#(T);$/;\"\tc\tclass:Stack\tparameter:\nDEPTH\tinput.sv\t/^class Stack #(type T = logic, int DEPTH = 1) implements PutImp#(T), GetImp#(T);$/;\"\tc\tclass:Stack\tparameter:\nmyFifo\tinput.sv\t/^  T myFifo[$:DEPTH-1];$/;\"\tr\tclass:Stack\nput\tinput.sv\t/^  virtual function void put(T a);$/;\"\tf\tclass:Stack\na\tinput.sv\t/^  virtual function void put(T a);$/;\"\tp\tfunction:Stack.put\nget\tinput.sv\t/^  virtual function T get();$/;\"\tf\tclass:Stack\nIntfA\tinput.sv\t/^interface class IntfA #(type T1 = logic);$/;\"\tl\nT1\tinput.sv\t/^interface class IntfA #(type T1 = logic);$/;\"\tc\tifclass:IntfA\tparameter:\nT2\tinput.sv\t/^  typedef T1[1:0] T2;$/;\"\tT\tifclass:IntfA\nIntfB\tinput.sv\t/^interface class IntfB #(type T = bit) extends IntfA #(T);$/;\"\tl\nT\tinput.sv\t/^interface class IntfB #(type T = bit) extends IntfA #(T);$/;\"\tc\tifclass:IntfB\tparameter:\ngeneric_fifo\tinput.sv\t/^module generic_fifo$/;\"\tm\nMSB\tinput.sv\t/^  #(parameter MSB=3, LSB=0, DEPTH=4) \\/\\/ these parameters can be redefined$/;\"\tc\tmodule:generic_fifo\tparameter:\nLSB\tinput.sv\t/^  #(parameter MSB=3, LSB=0, DEPTH=4) \\/\\/ these parameters can be redefined$/;\"\tc\tmodule:generic_fifo\tparameter:\nDEPTH\tinput.sv\t/^  #(parameter MSB=3, LSB=0, DEPTH=4) \\/\\/ these parameters can be redefined$/;\"\tc\tmodule:generic_fifo\tparameter:\nin\tinput.sv\t/^   (input  wire [MSB:LSB] in,$/;\"\tp\tmodule:generic_fifo\nclk\tinput.sv\t/^    input  wire clk, read, write, reset,$/;\"\tp\tmodule:generic_fifo\nread\tinput.sv\t/^    input  wire clk, read, write, reset,$/;\"\tp\tmodule:generic_fifo\nwrite\tinput.sv\t/^    input  wire clk, read, write, reset,$/;\"\tp\tmodule:generic_fifo\nreset\tinput.sv\t/^    input  wire clk, read, write, reset,$/;\"\tp\tmodule:generic_fifo\nout\tinput.sv\t/^    output logic [MSB:LSB] out,$/;\"\tp\tmodule:generic_fifo\nfull\tinput.sv\t/^    output logic full, empty );$/;\"\tp\tmodule:generic_fifo\nempty\tinput.sv\t/^    output logic full, empty );$/;\"\tp\tmodule:generic_fifo\ngeneric_decoder\tinput.sv\t/^module generic_decoder$/;\"\tm\nnum_code_bits\tinput.sv\t/^  #(num_code_bits = 3, localparam num_out_bits = 1 << num_code_bits)$/;\"\tc\tmodule:generic_decoder\tparameter:\nnum_out_bits\tinput.sv\t/^  #(num_code_bits = 3, localparam num_out_bits = 1 << num_code_bits)$/;\"\tc\tmodule:generic_decoder\nA\tinput.sv\t/^   (input [num_code_bits-1:0] A, output reg [num_out_bits-1:0] Y);$/;\"\tp\tmodule:generic_decoder\nY\tinput.sv\t/^   (input [num_code_bits-1:0] A, output reg [num_out_bits-1:0] Y);$/;\"\tp\tmodule:generic_decoder\nint_t\tinput.sv\t/^typedef int int_t;$/;\"\tT\nuser_defined_type_param\tinput.sv\t/^module user_defined_type_param$/;\"\tm\nnum_code_bits\tinput.sv\t/^  #(int_t num_code_bits = 3, localparam num_out_bits = 1 << num_code_bits)$/;\"\tc\tmodule:user_defined_type_param\tparameter:\nnum_out_bits\tinput.sv\t/^  #(int_t num_code_bits = 3, localparam num_out_bits = 1 << num_code_bits)$/;\"\tc\tmodule:user_defined_type_param\nA\tinput.sv\t/^   (input [num_code_bits-1:0] A, output reg [num_out_bits-1:0] Y);$/;\"\tp\tmodule:user_defined_type_param\nY\tinput.sv\t/^   (input [num_code_bits-1:0] A, output reg [num_out_bits-1:0] Y);$/;\"\tp\tmodule:user_defined_type_param\nL1\tinput.sv\t/^parameter L1 = 0;  \\/\\/  synonym for the localparam$/;\"\tc\tparameter:\nmodule_with_parameter_port_list\tinput.sv\t/^module module_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4/;\"\tm\nP1\tinput.sv\t/^module module_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4/;\"\tc\tmodule:module_with_parameter_port_list\tparameter:\nP2\tinput.sv\t/^module module_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4/;\"\tc\tmodule:module_with_parameter_port_list\tparameter:\nL2\tinput.sv\t/^module module_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4/;\"\tc\tmodule:module_with_parameter_port_list\nL3\tinput.sv\t/^module module_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4/;\"\tc\tmodule:module_with_parameter_port_list\nP3\tinput.sv\t/^module module_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4/;\"\tc\tmodule:module_with_parameter_port_list\tparameter:\nP4\tinput.sv\t/^module module_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4/;\"\tc\tmodule:module_with_parameter_port_list\tparameter:\nL4\tinput.sv\t/^  parameter  L4 = \"local parameter\";  \\/\\/ synonym for the localparam$/;\"\tc\tmodule:module_with_parameter_port_list\nL5\tinput.sv\t/^  localparam L5 = \"local parameter\";$/;\"\tc\tmodule:module_with_parameter_port_list\nmodule_with_empty_parameter_port_list\tinput.sv\t/^module module_with_empty_parameter_port_list #()$/;\"\tm\nL6\tinput.sv\t/^  parameter  L6 = \"local parameter\";  \\/\\/ synonym for the localparam$/;\"\tc\tmodule:module_with_empty_parameter_port_list\nL7\tinput.sv\t/^  localparam L7 = \"local parameter\";$/;\"\tc\tmodule:module_with_empty_parameter_port_list\nmodule_no_parameter_port_list\tinput.sv\t/^module module_no_parameter_port_list$/;\"\tm\nP5\tinput.sv\t/^  parameter  P5 = \"parameter\";$/;\"\tc\tmodule:module_no_parameter_port_list\tparameter:\nL8\tinput.sv\t/^  localparam L8 = \"local parameter\";$/;\"\tc\tmodule:module_no_parameter_port_list\nclass_with_parameter_port_list\tinput.sv\t/^class class_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4);$/;\"\tC\nP1\tinput.sv\t/^class class_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4);$/;\"\tc\tclass:class_with_parameter_port_list\tparameter:\nP2\tinput.sv\t/^class class_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4);$/;\"\tc\tclass:class_with_parameter_port_list\tparameter:\nL2\tinput.sv\t/^class class_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4);$/;\"\tc\tclass:class_with_parameter_port_list\nL3\tinput.sv\t/^class class_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4);$/;\"\tc\tclass:class_with_parameter_port_list\nP3\tinput.sv\t/^class class_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4);$/;\"\tc\tclass:class_with_parameter_port_list\tparameter:\nP4\tinput.sv\t/^class class_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4);$/;\"\tc\tclass:class_with_parameter_port_list\tparameter:\nL4\tinput.sv\t/^  parameter  L4 = \"local parameter\";  \\/\\/ synonym for the localparam$/;\"\tc\tclass:class_with_parameter_port_list\nL5\tinput.sv\t/^  localparam L5 = \"local parameter\";$/;\"\tc\tclass:class_with_parameter_port_list\nclass_with_empty_parameter_port_list\tinput.sv\t/^class class_with_empty_parameter_port_list #();$/;\"\tC\nL6\tinput.sv\t/^  parameter  L6 = \"local parameter\";  \\/\\/ synonym for the localparam$/;\"\tc\tclass:class_with_empty_parameter_port_list\nL7\tinput.sv\t/^  localparam L7 = \"local parameter\";$/;\"\tc\tclass:class_with_empty_parameter_port_list\nclass_no_parameter_port_list\tinput.sv\t/^class class_no_parameter_port_list;$/;\"\tC\nL8\tinput.sv\t/^  parameter  L8 = \"local parameter\";  \\/\\/ synonym for the localparam (class only)$/;\"\tc\tclass:class_no_parameter_port_list\nL9\tinput.sv\t/^  localparam L9 = \"local parameter\";$/;\"\tc\tclass:class_no_parameter_port_list\nprogram_with_parameter_port_list\tinput.sv\t/^program program_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, /;\"\tP\nP1\tinput.sv\t/^program program_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, /;\"\tc\tprogram:program_with_parameter_port_list\tparameter:\nP2\tinput.sv\t/^program program_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, /;\"\tc\tprogram:program_with_parameter_port_list\tparameter:\nL2\tinput.sv\t/^program program_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, /;\"\tc\tprogram:program_with_parameter_port_list\nL3\tinput.sv\t/^program program_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, /;\"\tc\tprogram:program_with_parameter_port_list\nP3\tinput.sv\t/^program program_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, /;\"\tc\tprogram:program_with_parameter_port_list\tparameter:\nP4\tinput.sv\t/^program program_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, /;\"\tc\tprogram:program_with_parameter_port_list\tparameter:\nL4\tinput.sv\t/^  parameter  L4 = \"local parameter\";  \\/\\/ synonym for the localparam$/;\"\tc\tprogram:program_with_parameter_port_list\nL5\tinput.sv\t/^  localparam L5 = \"local parameter\";$/;\"\tc\tprogram:program_with_parameter_port_list\nprogram_with_empty_parameter_port_list\tinput.sv\t/^program program_with_empty_parameter_port_list #()$/;\"\tP\nL6\tinput.sv\t/^  parameter  L6 = \"local parameter\";  \\/\\/ synonym for the localparam$/;\"\tc\tprogram:program_with_empty_parameter_port_list\nL7\tinput.sv\t/^  localparam L7 = \"local parameter\";$/;\"\tc\tprogram:program_with_empty_parameter_port_list\nprogram_no_parameter_port_list\tinput.sv\t/^program program_no_parameter_port_list$/;\"\tP\nP5\tinput.sv\t/^  parameter  P5 = \"parameter\";$/;\"\tc\tprogram:program_no_parameter_port_list\tparameter:\nL8\tinput.sv\t/^  localparam L8 = \"local parameter\";$/;\"\tc\tprogram:program_no_parameter_port_list\ninterface_with_parameter_port_list\tinput.sv\t/^interface interface_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter /;\"\tI\nP1\tinput.sv\t/^interface interface_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter /;\"\tc\tinterface:interface_with_parameter_port_list\tparameter:\nP2\tinput.sv\t/^interface interface_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter /;\"\tc\tinterface:interface_with_parameter_port_list\tparameter:\nL2\tinput.sv\t/^interface interface_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter /;\"\tc\tinterface:interface_with_parameter_port_list\nL3\tinput.sv\t/^interface interface_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter /;\"\tc\tinterface:interface_with_parameter_port_list\nP3\tinput.sv\t/^interface interface_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter /;\"\tc\tinterface:interface_with_parameter_port_list\tparameter:\nP4\tinput.sv\t/^interface interface_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter /;\"\tc\tinterface:interface_with_parameter_port_list\tparameter:\nL4\tinput.sv\t/^  parameter  L4 = \"local parameter\";  \\/\\/ synonym for the localparam$/;\"\tc\tinterface:interface_with_parameter_port_list\nL5\tinput.sv\t/^  localparam L5 = \"local parameter\";$/;\"\tc\tinterface:interface_with_parameter_port_list\ninterface_with_empty_parameter_port_list\tinput.sv\t/^interface interface_with_empty_parameter_port_list #()$/;\"\tI\nL6\tinput.sv\t/^  parameter  L6 = \"local parameter\";  \\/\\/ synonym for the localparam$/;\"\tc\tinterface:interface_with_empty_parameter_port_list\nL7\tinput.sv\t/^  localparam L7 = \"local parameter\";$/;\"\tc\tinterface:interface_with_empty_parameter_port_list\ninterface_no_parameter_port_list\tinput.sv\t/^interface interface_no_parameter_port_list$/;\"\tI\nP5\tinput.sv\t/^  parameter  P5 = \"parameter\";$/;\"\tc\tinterface:interface_no_parameter_port_list\tparameter:\nL8\tinput.sv\t/^  localparam L8 = \"local parameter\";$/;\"\tc\tinterface:interface_no_parameter_port_list\npackage_has_no_parameter_port_list\tinput.sv\t/^package package_has_no_parameter_port_list;$/;\"\tK\nL1\tinput.sv\t/^  parameter  L1 = \"local parameter\";$/;\"\tc\tpackage:package_has_no_parameter_port_list\nL2\tinput.sv\t/^  localparam L2 = \"local parameter\";$/;\"\tc\tpackage:package_has_no_parameter_port_list\ngenerate_constructs\tinput.sv\t/^module generate_constructs;$/;\"\tm\nL1\tinput.sv\t/^    parameter  L1 = \"local parameter\";  \\/\\/ FIXME$/;\"\tc\tmodule:generate_constructs\tparameter:\nL2\tinput.sv\t/^    localparam L2 = \"local parameter\";$/;\"\tc\tmodule:generate_constructs\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-parameter.d/input.sv",
    "content": "//\n// parameter defintion tests\n//\n\n// LRM 8.25.1 Class scope resolution operator for parameterized classes\nclass C #(\n  int p = 1\n);\n  parameter int q = 5;  // local parameter\n  static task t;\n    int p;\n    int x = C::p;  // C::p disambiguates p\n    // C::p is not p in the default specialization\n  endtask\nendclass\n\nclass C #(\n    int p = 1,\n    type T = int\n);\n  extern static function T f();\nendclass\n\nfunction C::T C::f();\n  return p + C::p;\nendfunction\n\n// LRM 13.8 Parameterized tasks and functions\nvirtual class C#(parameter DECODE_W, parameter ENCODE_W = $clog2(DECODE_W));\n  static function logic [ENCODE_W-1:0] ENCODER_f\n      (input logic [DECODE_W-1:0] DecodeIn);\n    ENCODER_f = '0;\n    for (int i = 0; i < DECODE_W; i++) begin\n      if (DecodeIn[i]) begin\n        ENCODER_f = i[ENCODE_W - 1:0];\n        break;\n      end\n    end\n  endfunction\n  static function logic [DECODE_W-1:0] DECODER_f\n      (input logic [ENCODE_W-1:0] EncodeIn);\n    DECODER_f = '0;\n    DECODER_f[EncodeIn] = 1'b1;\n  endfunction\nendclass\n\n// LRM 8.26 Interface classes\ninterface class PutImp #(type PUT_T = logic);\n  pure virtual function void put(PUT_T a);\nendclass\n\ninterface class GetImp #(type GET_T = logic);\n  pure virtual function GET_T get();\nendclass\n\nclass Fifo #(type T = logic, int DEPTH = 1) implements PutImp#(T), GetImp#(T);\n  T myFifo[$:DEPTH-1];\n  virtual function void put(T a);\n    myFifo.push_back(a);\n  endfunction\n  virtual function T get();\n    get = myFifo.pop_front();\n  endfunction\nendclass\n\nclass Stack #(type T = logic, int DEPTH = 1) implements PutImp#(T), GetImp#(T);\n  T myFifo[$:DEPTH-1];\n  virtual function void put(T a);\n    myFifo.push_front(a);\n  endfunction\n  virtual function T get();\n    get = myFifo.pop_front();\n  endfunction\nendclass\n\n// 8.26.3 Type access\ninterface class IntfA #(type T1 = logic);\n  typedef T1[1:0] T2;\n  pure virtual function T2 funcA();\nendclass : IntfA\n\ninterface class IntfB #(type T = bit) extends IntfA #(T);\n  pure virtual function T2 funcB(); // legal, type T2 is inherited\nendclass : IntfB\n\n// 23.2.3 Parameterized modules\nmodule generic_fifo\n  #(parameter MSB=3, LSB=0, DEPTH=4) // these parameters can be redefined\n   (input  wire [MSB:LSB] in,\n    input  wire clk, read, write, reset,\n    output logic [MSB:LSB] out,\n    output logic full, empty );\n    //...\nendmodule\n\nmodule generic_decoder\n  #(num_code_bits = 3, localparam num_out_bits = 1 << num_code_bits)\n   (input [num_code_bits-1:0] A, output reg [num_out_bits-1:0] Y);\nendmodule\n\n// additional test\ntypedef int int_t;\nmodule user_defined_type_param\n  #(int_t num_code_bits = 3, localparam num_out_bits = 1 << num_code_bits)\n   (input [num_code_bits-1:0] A, output reg [num_out_bits-1:0] Y);\nendmodule\n\n//\n// LRM 6.20.1 Parameter declaration syntax (#2537)\n//\n\n// compilation unit scope\nparameter L1 = 0;  //  synonym for the localparam\n\nmodule module_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4)\n( /*port list...*/ );\n  parameter  L4 = \"local parameter\";  // synonym for the localparam\n  localparam L5 = \"local parameter\";\n  // ...\nendmodule\n\nmodule module_with_empty_parameter_port_list #()\n( /*port list...*/ );\n  parameter  L6 = \"local parameter\";  // synonym for the localparam\n  localparam L7 = \"local parameter\";\n  // ...\nendmodule\n\nmodule module_no_parameter_port_list\n( /*port list...*/ );\n  parameter  P5 = \"parameter\";\n  localparam L8 = \"local parameter\";\n  // ...\nendmodule\n\nclass class_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4);\n  parameter  L4 = \"local parameter\";  // synonym for the localparam\n  localparam L5 = \"local parameter\";\n  // ...\nendclass\n\nclass class_with_empty_parameter_port_list #();\n  parameter  L6 = \"local parameter\";  // synonym for the localparam\n  localparam L7 = \"local parameter\";\n  // ...\nendclass\n\nclass class_no_parameter_port_list;\n  parameter  L8 = \"local parameter\";  // synonym for the localparam (class only)\n  localparam L9 = \"local parameter\";\n  // ...\nendclass\n\nprogram program_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4)\n( /*port list...*/ );\n  parameter  L4 = \"local parameter\";  // synonym for the localparam\n  localparam L5 = \"local parameter\";\n  // ...\nendprogram\n\nprogram program_with_empty_parameter_port_list #()\n( /*port list...*/ );\n  parameter  L6 = \"local parameter\";  // synonym for the localparam\n  localparam L7 = \"local parameter\";\n  // ...\nendprogram\n\nprogram program_no_parameter_port_list\n( /*port list...*/ );\n  parameter  P5 = \"parameter\";\n  localparam L8 = \"local parameter\";\n  // ...\nendprogram\n\ninterface interface_with_parameter_port_list #(P1, P2, localparam L2 = P1+1, L3=P2*2, parameter P3, P4)\n( /*port list...*/ );\n  parameter  L4 = \"local parameter\";  // synonym for the localparam\n  localparam L5 = \"local parameter\";\n  // ...\nendinterface\n\ninterface interface_with_empty_parameter_port_list #()\n( /*port list...*/ );\n  parameter  L6 = \"local parameter\";  // synonym for the localparam\n  localparam L7 = \"local parameter\";\n  // ...\nendinterface\n\ninterface interface_no_parameter_port_list\n( /*port list...*/ );\n  parameter  P5 = \"parameter\";\n  localparam L8 = \"local parameter\";\n  // ...\nendinterface\n\npackage package_has_no_parameter_port_list;\n  parameter  L1 = \"local parameter\";\n  localparam L2 = \"local parameter\";\nendpackage\n\nmodule generate_constructs;\n  generate\n    parameter  L1 = \"local parameter\";  // FIXME\n    localparam L2 = \"local parameter\";\n  endgenerate\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-procedural.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-procedural.d/expected.tags",
    "content": "procedural\tinput.sv\t/^module procedural;$/;\"\tm\nindex\tinput.sv\t/^  int index, rega, regb, result;$/;\"\tr\tmodule:procedural\nrega\tinput.sv\t/^  int index, rega, regb, result;$/;\"\tr\tmodule:procedural\nregb\tinput.sv\t/^  int index, rega, regb, result;$/;\"\tr\tmodule:procedural\nresult\tinput.sv\t/^  int index, rega, regb, result;$/;\"\tr\tmodule:procedural\nexpression\tinput.sv\t/^    logic expression, a, result, flaga, flagb;$/;\"\tr\tmodule:procedural\na\tinput.sv\t/^    logic expression, a, result, flaga, flagb;$/;\"\tr\tmodule:procedural\nresult\tinput.sv\t/^    logic expression, a, result, flaga, flagb;$/;\"\tr\tmodule:procedural\nflaga\tinput.sv\t/^    logic expression, a, result, flaga, flagb;$/;\"\tr\tmodule:procedural\nflagb\tinput.sv\t/^    logic expression, a, result, flaga, flagb;$/;\"\tr\tmodule:procedural\nb\tinput.sv\t/^    logic [2:1] b;$/;\"\tr\tmodule:procedural\nselect\tinput.sv\t/^    logic [1:2] select;$/;\"\tr\tmodule:procedural\nencode\tinput.sv\t/^    logic [2:0] encode ;$/;\"\tr\tmodule:procedural\ns\tinput.sv\t/^  string s;$/;\"\tr\tmodule:procedural\nvalue\tinput.sv\t/^  int value, a[3];$/;\"\tr\tmodule:procedural\na\tinput.sv\t/^  int value, a[3];$/;\"\tr\tmodule:procedural\noffset\tinput.sv\t/^  int offset = 10;$/;\"\tr\tmodule:procedural\nN\tinput.sv\t/^  parameter N = 8;$/;\"\tc\tmodule:procedural\nouter\tinput.sv\t/^    for (int i = 0; i < N; i++) begin:outer$/;\"\tb\tmodule:procedural\ninner\tinput.sv\t/^      for (int j = 0; j < N; j++) begin : inner$/;\"\tb\tblock:procedural.outer\nstate\tinput.sv\t/^    enum { FSM_IDLE, FSM_ITER } state;$/;\"\tE\tmodule:procedural\nFSM_IDLE\tinput.sv\t/^    enum { FSM_IDLE, FSM_ITER } state;$/;\"\tc\tenum:procedural.state\nFSM_ITER\tinput.sv\t/^    enum { FSM_IDLE, FSM_ITER } state;$/;\"\tc\tenum:procedural.state\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-procedural.d/input.sv",
    "content": "//\n// LRM 12. Procedural programming Statements\n//    These construct does not generate tags basically.\n//    But they must be ignored properly.\n//\n\nmodule procedural;\n\n  int index, rega, regb, result;\n\n  // 12.4 Conditional if–else statement\n  always_comb begin\n    if (index > 0)\n      if (rega > regb) result = rega;\n      else  // else applies to preceding if\n        result = regb;\n\n    if (index > 0)\n      begin\n        if (rega > regb)\n          result = rega;\n      end\n    else result = regb;\n  end\n\n  always_comb begin\n    logic expression, a, result, flaga, flagb;\n    logic [2:1] b;\n    logic [1:2] select;\n    logic [2:0] encode ;\n\n    // 12.4.1 if–else–if construct\n    if (expression) statement;\n    else if (expression) statement;\n    else if (expression) statement;\n    else statement;\n\n    // 12.4.2 unique-if, unique0-if, and priority-if\n    unique if ((a==0) || (a==1)) $display(\"0 or 1\");\n    else if (a == 2) $display(\"2\");\n    else if (a == 4) $display(\"4\"); // values 3,5,6,7 cause a violation report\n\n    priority if (b[2:1]==0) $display(\"0 or 1\");\n    else if (b[2] == 0) $display(\"2 or 3\");\n    else $display(\"4 to 7\");  // covers all other possible values,\n                              // so no violation report\n\n    unique0 if ((a==0) || (a==1)) $display(\"0 or 1\");\n    else if (a == 2) $display(\"2\");\n    else if (a == 4) $display(\"4\"); // values 3,5,6,7\n                                    // cause no violation report\n    // 12.5 Case statement\n    case (select[1:2])\n      2'b00: result = 0;\n      2'b01: result = flaga;\n      2'b0x,\n      2'b0z: result = flaga ? 'x : 0;\n      2'b10: result = flagb;\n      2'bx0,\n      2'bz0: result = flagb ? 'x : 0;\n      default result = 'x;\n    endcase\n\n    case (1)\n      encode[2] : $display(\"Select Line 2\") ;\n      encode[1] : $display(\"Select Line 1\") ;\n      encode[0] : $display(\"Select Line 0\") ;\n      default $display(\"Error: One of the bits expected ON\");\n    endcase\n  end\n\n  // original\n  string s;\n  always_comb begin\n    if (index > 0)\n      s = \"foo bar ) } \";\n  end\n\n  // \n  int value, a[3];\n  int offset = 10;\n  parameter N = 8;\n  always_comb begin\n    for ( int count = 0; count < 3; count++ )\n      value = value +((a[count]) * (count+1));\n\n    for ( int count = 0, done = 0, j = 0; j * count < 125; j++, count++)\n      $display(\"Value j = %d\\n\", j );\n\n    for (int i = 0, j = i+offset; i < N; i++,j++)\n      $display(\"i = %d, j = %d\\n\", i, j );\n  end\n\n  always_comb begin\n    for (int i = 0; i < N; i++) begin:outer\n      for (int j = 0; j < N; j++) begin : inner\n        // ...\n      end\n    end\n  end\n\n  always_comb begin\n    enum { FSM_IDLE, FSM_ITER } state;\n    case (state)\n      FSM_IDLE,\n      FSM_ITER : begin\n      end\n    endcase\n  end\n\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-program.d/args.ctags",
    "content": "--extras=+q\n--kinds-systemverilog=+Q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-program.d/expected.tags",
    "content": "prog\tinput.sv\t/^program prog ($/;\"\tP\nin1\tinput.sv\t/^    input in1,$/;\"\tp\tprogram:prog\nprog.in1\tinput.sv\t/^    input in1,$/;\"\tp\tprogram:prog\nin2\tinput.sv\t/^    input [11:0] in2,$/;\"\tp\tprogram:prog\nprog.in2\tinput.sv\t/^    input [11:0] in2,$/;\"\tp\tprogram:prog\nout\tinput.sv\t/^    output out,$/;\"\tp\tprogram:prog\nprog.out\tinput.sv\t/^    output out,$/;\"\tp\tprogram:prog\niout\tinput.sv\t/^    inout iout$/;\"\tp\tprogram:prog\nprog.iout\tinput.sv\t/^    inout iout$/;\"\tp\tprogram:prog\nstart\tinput.sv\t/^initial begin : start$/;\"\tb\tprogram:prog\nprog.start\tinput.sv\t/^initial begin : start$/;\"\tb\tprogram:prog\nok\tinput.sv\t/^    logic ok;$/;\"\tr\tblock:prog.start\nprog.start.ok\tinput.sv\t/^    logic ok;$/;\"\tr\tblock:prog.start\ni\tinput.sv\t/^    longint i;$/;\"\tr\tblock:prog.start\nprog.start.i\tinput.sv\t/^    longint i;$/;\"\tr\tblock:prog.start\nstop\tinput.sv\t/^final begin : stop$/;\"\tb\tprogram:prog\nprog.stop\tinput.sv\t/^final begin : stop$/;\"\tb\tprogram:prog\ncount\tinput.sv\t/^    byte count;$/;\"\tr\tblock:prog.stop\nprog.stop.count\tinput.sv\t/^    byte count;$/;\"\tr\tblock:prog.stop\ntopmod\tinput.sv\t/^module topmod;$/;\"\tm\nmod_prog1\tinput.sv\t/^program mod_prog1;$/;\"\tP\tmodule:topmod\ntopmod.mod_prog1\tinput.sv\t/^program mod_prog1;$/;\"\tP\tmodule:topmod\nmod_prog2\tinput.sv\t/^program mod_prog2;$/;\"\tP\tmodule:topmod\ntopmod.mod_prog2\tinput.sv\t/^program mod_prog2;$/;\"\tP\tmodule:topmod\nfunc_in_anon_prog\tinput.sv\t/^    function func_in_anon_prog;$/;\"\tf\nanon_pkg\tinput.sv\t/^package anon_pkg;$/;\"\tK\nfunc_in_anon_prog2\tinput.sv\t/^    function func_in_anon_prog2;$/;\"\tf\tpackage:anon_pkg\nanon_pkg.func_in_anon_prog2\tinput.sv\t/^    function func_in_anon_prog2;$/;\"\tf\tpackage:anon_pkg\nprog_static\tinput.sv\t/^program static prog_static;$/;\"\tP\nlogic_static\tinput.sv\t/^    logic logic_static;$/;\"\tr\tprogram:prog_static\nprog_static.logic_static\tinput.sv\t/^    logic logic_static;$/;\"\tr\tprogram:prog_static\nprog_automatic\tinput.sv\t/^program automatic prog_automatic;$/;\"\tP\nlogic_automatic\tinput.sv\t/^    logic logic_automatic;$/;\"\tr\tprogram:prog_automatic\nprog_automatic.logic_automatic\tinput.sv\t/^    logic logic_automatic;$/;\"\tr\tprogram:prog_automatic\nexternal_program\tinput.sv\t/^extern program external_program;$/;\"\tQ\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-program.d/input.sv",
    "content": "program prog (\n    input in1,\n    input [11:0] in2,\n    output out,\n    inout iout\n);\n\ninitial begin : start\n    logic ok;\n    longint i;\nend\n\nfinal begin : stop\n    byte count;\nend\n\nendprogram : prog\n\n\nmodule topmod;\n\nprogram mod_prog1;\nendprogram : mod_prog1\n\nprogram mod_prog2;\nendprogram : mod_prog2\n\nendmodule\n\n\nprogram;  // anounymous program inside compilation unit\n    // reg reg_in_anon_prog; /* a variable cannot be defined in anonymous program */\n    function func_in_anon_prog;\n    endfunction\nendprogram\n\npackage anon_pkg;\n\nprogram;  // anounymous program inside package\n    // reg reg_in_anon_prog2; /* a variable cannot be defined in anonymous program */\n    function func_in_anon_prog2;\n    endfunction\nendprogram\n\nendpackage\n\nprogram static prog_static;\n    logic logic_static;\nendprogram\n\nprogram automatic prog_automatic;\n    logic logic_automatic;\nendprogram\n\nextern program external_program;\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-prototype.d/args.ctags",
    "content": "--sort=no\n--kinds-systemverilog=+Q\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-prototype.d/expected.tags",
    "content": "C\tinput.sv\t/^class C;$/;\"\tC\next_func\tinput.sv\t/^  extern function void ext_func ();$/;\"\tQ\tclass:C\next_pure_virt_task\tinput.sv\t/^  pure virtual task ext_pure_virt_task (x);$/;\"\tQ\tclass:C\nx\tinput.sv\t/^  pure virtual task ext_pure_virt_task (x);$/;\"\tp\tprototype:C.ext_pure_virt_task\nfwd_type_class\tinput.sv\t/^  typedef class   fwd_type_class;$/;\"\tQ\tclass:C\nfoo\tinput.sv\t/^package foo;$/;\"\tK\nimport_func\tinput.sv\t/^  import \"DPI-C\" context function int import_func (string str);$/;\"\tQ\tpackage:foo\nstr\tinput.sv\t/^  import \"DPI-C\" context function int import_func (string str);$/;\"\tp\tprototype:foo.import_func\nuvm_object\tinput.sv\t/^  typedef logic uvm_object;$/;\"\tT\tpackage:foo\nbar\tinput.sv\t/^  function logic bar (uvm_object baz);$/;\"\tf\tpackage:foo\nbaz\tinput.sv\t/^  function logic bar (uvm_object baz);$/;\"\tp\tfunction:foo.bar\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-prototype.d/input.sv",
    "content": "// disabled K_PROTOTYPE: don't use \"--extras=+q\" for coverage\nclass C;\n  extern function void ext_func ();\n  pure virtual task ext_pure_virt_task (x);\n  typedef class   fwd_type_class;\nendclass\n\n// from UVM-1.2\npackage foo;\n  import \"DPI-C\" context function int import_func (string str);\n  typedef logic uvm_object;\n  function logic bar (uvm_object baz);\n    return 1'b1;\n  endfunction\nendpackage\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-qualifiers.d/args.ctags",
    "content": "--extras=+q\n--kinds-systemverilog=+Q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-qualifiers.d/expected.tags",
    "content": "foo\tinput.sv\t/^class foo;$/;\"\tC\next_func\tinput.sv\t/^extern function void ext_func (x, y);$/;\"\tQ\tclass:foo\nfoo.ext_func\tinput.sv\t/^extern function void ext_func (x, y);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^extern function void ext_func (x, y);$/;\"\tp\tprototype:foo.ext_func\nfoo.ext_func.x\tinput.sv\t/^extern function void ext_func (x, y);$/;\"\tp\tprototype:foo.ext_func\ny\tinput.sv\t/^extern function void ext_func (x, y);$/;\"\tp\tprototype:foo.ext_func\nfoo.ext_func.y\tinput.sv\t/^extern function void ext_func (x, y);$/;\"\tp\tprototype:foo.ext_func\next_static_func\tinput.sv\t/^extern static function void ext_static_func (x, y);$/;\"\tQ\tclass:foo\nfoo.ext_static_func\tinput.sv\t/^extern static function void ext_static_func (x, y);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^extern static function void ext_static_func (x, y);$/;\"\tp\tprototype:foo.ext_static_func\nfoo.ext_static_func.x\tinput.sv\t/^extern static function void ext_static_func (x, y);$/;\"\tp\tprototype:foo.ext_static_func\ny\tinput.sv\t/^extern static function void ext_static_func (x, y);$/;\"\tp\tprototype:foo.ext_static_func\nfoo.ext_static_func.y\tinput.sv\t/^extern static function void ext_static_func (x, y);$/;\"\tp\tprototype:foo.ext_static_func\next_protected_func\tinput.sv\t/^extern protected function void ext_protected_func (x, y);$/;\"\tQ\tclass:foo\nfoo.ext_protected_func\tinput.sv\t/^extern protected function void ext_protected_func (x, y);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^extern protected function void ext_protected_func (x, y);$/;\"\tp\tprototype:foo.ext_protected_func\nfoo.ext_protected_func.x\tinput.sv\t/^extern protected function void ext_protected_func (x, y);$/;\"\tp\tprototype:foo.ext_protected_func\ny\tinput.sv\t/^extern protected function void ext_protected_func (x, y);$/;\"\tp\tprototype:foo.ext_protected_func\nfoo.ext_protected_func.y\tinput.sv\t/^extern protected function void ext_protected_func (x, y);$/;\"\tp\tprototype:foo.ext_protected_func\next_local_func\tinput.sv\t/^extern local function void ext_local_func (x, y);$/;\"\tQ\tclass:foo\nfoo.ext_local_func\tinput.sv\t/^extern local function void ext_local_func (x, y);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^extern local function void ext_local_func (x, y);$/;\"\tp\tprototype:foo.ext_local_func\nfoo.ext_local_func.x\tinput.sv\t/^extern local function void ext_local_func (x, y);$/;\"\tp\tprototype:foo.ext_local_func\ny\tinput.sv\t/^extern local function void ext_local_func (x, y);$/;\"\tp\tprototype:foo.ext_local_func\nfoo.ext_local_func.y\tinput.sv\t/^extern local function void ext_local_func (x, y);$/;\"\tp\tprototype:foo.ext_local_func\next_pure_virt_func\tinput.sv\t/^extern pure virtual function void ext_pure_virt_func (x);$/;\"\tQ\tclass:foo\nfoo.ext_pure_virt_func\tinput.sv\t/^extern pure virtual function void ext_pure_virt_func (x);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^extern pure virtual function void ext_pure_virt_func (x);$/;\"\tp\tprototype:foo.ext_pure_virt_func\nfoo.ext_pure_virt_func.x\tinput.sv\t/^extern pure virtual function void ext_pure_virt_func (x);$/;\"\tp\tprototype:foo.ext_pure_virt_func\npure_virt_func\tinput.sv\t/^pure virtual function void pure_virt_func (x);$/;\"\tQ\tclass:foo\nfoo.pure_virt_func\tinput.sv\t/^pure virtual function void pure_virt_func (x);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^pure virtual function void pure_virt_func (x);$/;\"\tp\tprototype:foo.pure_virt_func\nfoo.pure_virt_func.x\tinput.sv\t/^pure virtual function void pure_virt_func (x);$/;\"\tp\tprototype:foo.pure_virt_func\npure_virt_static_func\tinput.sv\t/^pure virtual static function void pure_virt_static_func (x);$/;\"\tQ\tclass:foo\nfoo.pure_virt_static_func\tinput.sv\t/^pure virtual static function void pure_virt_static_func (x);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^pure virtual static function void pure_virt_static_func (x);$/;\"\tp\tprototype:foo.pure_virt_static_func\nfoo.pure_virt_static_func.x\tinput.sv\t/^pure virtual static function void pure_virt_static_func (x);$/;\"\tp\tprototype:foo.pure_virt_static_func\npure_virt_protected_func\tinput.sv\t/^pure virtual protected function void pure_virt_protected_func (x);$/;\"\tQ\tclass:foo\nfoo.pure_virt_protected_func\tinput.sv\t/^pure virtual protected function void pure_virt_protected_func (x);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^pure virtual protected function void pure_virt_protected_func (x);$/;\"\tp\tprototype:foo.pure_virt_protected_func\nfoo.pure_virt_protected_func.x\tinput.sv\t/^pure virtual protected function void pure_virt_protected_func (x);$/;\"\tp\tprototype:foo.pure_virt_protected_func\npure_virt_local_func\tinput.sv\t/^pure virtual local function void pure_virt_local_func (x);$/;\"\tQ\tclass:foo\nfoo.pure_virt_local_func\tinput.sv\t/^pure virtual local function void pure_virt_local_func (x);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^pure virtual local function void pure_virt_local_func (x);$/;\"\tp\tprototype:foo.pure_virt_local_func\nfoo.pure_virt_local_func.x\tinput.sv\t/^pure virtual local function void pure_virt_local_func (x);$/;\"\tp\tprototype:foo.pure_virt_local_func\next_task\tinput.sv\t/^extern task ext_task (x, y);$/;\"\tQ\tclass:foo\nfoo.ext_task\tinput.sv\t/^extern task ext_task (x, y);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^extern task ext_task (x, y);$/;\"\tp\tprototype:foo.ext_task\nfoo.ext_task.x\tinput.sv\t/^extern task ext_task (x, y);$/;\"\tp\tprototype:foo.ext_task\ny\tinput.sv\t/^extern task ext_task (x, y);$/;\"\tp\tprototype:foo.ext_task\nfoo.ext_task.y\tinput.sv\t/^extern task ext_task (x, y);$/;\"\tp\tprototype:foo.ext_task\next_static_task\tinput.sv\t/^extern static task ext_static_task (x, y);$/;\"\tQ\tclass:foo\nfoo.ext_static_task\tinput.sv\t/^extern static task ext_static_task (x, y);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^extern static task ext_static_task (x, y);$/;\"\tp\tprototype:foo.ext_static_task\nfoo.ext_static_task.x\tinput.sv\t/^extern static task ext_static_task (x, y);$/;\"\tp\tprototype:foo.ext_static_task\ny\tinput.sv\t/^extern static task ext_static_task (x, y);$/;\"\tp\tprototype:foo.ext_static_task\nfoo.ext_static_task.y\tinput.sv\t/^extern static task ext_static_task (x, y);$/;\"\tp\tprototype:foo.ext_static_task\next_protected_task\tinput.sv\t/^extern protected task ext_protected_task (x, y);$/;\"\tQ\tclass:foo\nfoo.ext_protected_task\tinput.sv\t/^extern protected task ext_protected_task (x, y);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^extern protected task ext_protected_task (x, y);$/;\"\tp\tprototype:foo.ext_protected_task\nfoo.ext_protected_task.x\tinput.sv\t/^extern protected task ext_protected_task (x, y);$/;\"\tp\tprototype:foo.ext_protected_task\ny\tinput.sv\t/^extern protected task ext_protected_task (x, y);$/;\"\tp\tprototype:foo.ext_protected_task\nfoo.ext_protected_task.y\tinput.sv\t/^extern protected task ext_protected_task (x, y);$/;\"\tp\tprototype:foo.ext_protected_task\next_local_task\tinput.sv\t/^extern local task ext_local_task (x, y);$/;\"\tQ\tclass:foo\nfoo.ext_local_task\tinput.sv\t/^extern local task ext_local_task (x, y);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^extern local task ext_local_task (x, y);$/;\"\tp\tprototype:foo.ext_local_task\nfoo.ext_local_task.x\tinput.sv\t/^extern local task ext_local_task (x, y);$/;\"\tp\tprototype:foo.ext_local_task\ny\tinput.sv\t/^extern local task ext_local_task (x, y);$/;\"\tp\tprototype:foo.ext_local_task\nfoo.ext_local_task.y\tinput.sv\t/^extern local task ext_local_task (x, y);$/;\"\tp\tprototype:foo.ext_local_task\next_pure_virt_task\tinput.sv\t/^extern pure virtual task ext_pure_virt_task (x);$/;\"\tQ\tclass:foo\nfoo.ext_pure_virt_task\tinput.sv\t/^extern pure virtual task ext_pure_virt_task (x);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^extern pure virtual task ext_pure_virt_task (x);$/;\"\tp\tprototype:foo.ext_pure_virt_task\nfoo.ext_pure_virt_task.x\tinput.sv\t/^extern pure virtual task ext_pure_virt_task (x);$/;\"\tp\tprototype:foo.ext_pure_virt_task\npure_virt_task\tinput.sv\t/^pure virtual task pure_virt_task (x);$/;\"\tQ\tclass:foo\nfoo.pure_virt_task\tinput.sv\t/^pure virtual task pure_virt_task (x);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^pure virtual task pure_virt_task (x);$/;\"\tp\tprototype:foo.pure_virt_task\nfoo.pure_virt_task.x\tinput.sv\t/^pure virtual task pure_virt_task (x);$/;\"\tp\tprototype:foo.pure_virt_task\npure_virt_static_task\tinput.sv\t/^pure virtual static task pure_virt_static_task (x);$/;\"\tQ\tclass:foo\nfoo.pure_virt_static_task\tinput.sv\t/^pure virtual static task pure_virt_static_task (x);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^pure virtual static task pure_virt_static_task (x);$/;\"\tp\tprototype:foo.pure_virt_static_task\nfoo.pure_virt_static_task.x\tinput.sv\t/^pure virtual static task pure_virt_static_task (x);$/;\"\tp\tprototype:foo.pure_virt_static_task\npure_virt_protected_task\tinput.sv\t/^pure virtual protected task pure_virt_protected_task (x);$/;\"\tQ\tclass:foo\nfoo.pure_virt_protected_task\tinput.sv\t/^pure virtual protected task pure_virt_protected_task (x);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^pure virtual protected task pure_virt_protected_task (x);$/;\"\tp\tprototype:foo.pure_virt_protected_task\nfoo.pure_virt_protected_task.x\tinput.sv\t/^pure virtual protected task pure_virt_protected_task (x);$/;\"\tp\tprototype:foo.pure_virt_protected_task\npure_virt_local_task\tinput.sv\t/^pure virtual local task pure_virt_local_task (x);$/;\"\tQ\tclass:foo\nfoo.pure_virt_local_task\tinput.sv\t/^pure virtual local task pure_virt_local_task (x);$/;\"\tQ\tclass:foo\nx\tinput.sv\t/^pure virtual local task pure_virt_local_task (x);$/;\"\tp\tprototype:foo.pure_virt_local_task\nfoo.pure_virt_local_task.x\tinput.sv\t/^pure virtual local task pure_virt_local_task (x);$/;\"\tp\tprototype:foo.pure_virt_local_task\nauto_function\tinput.sv\t/^function automatic auto_function (x);$/;\"\tf\tclass:foo\nfoo.auto_function\tinput.sv\t/^function automatic auto_function (x);$/;\"\tf\tclass:foo\nx\tinput.sv\t/^function automatic auto_function (x);$/;\"\tp\tfunction:foo.auto_function\nfoo.auto_function.x\tinput.sv\t/^function automatic auto_function (x);$/;\"\tp\tfunction:foo.auto_function\nauto_static\tinput.sv\t/^function static auto_static (x);$/;\"\tf\tclass:foo\nfoo.auto_static\tinput.sv\t/^function static auto_static (x);$/;\"\tf\tclass:foo\nx\tinput.sv\t/^function static auto_static (x);$/;\"\tp\tfunction:foo.auto_static\nfoo.auto_static.x\tinput.sv\t/^function static auto_static (x);$/;\"\tp\tfunction:foo.auto_static\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-qualifiers.d/input.sv",
    "content": "class foo;\nextern function void ext_func (x, y);\n\nextern static function void ext_static_func (x, y);\n\nextern protected function void ext_protected_func (x, y);\n\nextern local function void ext_local_func (x, y);\n\nextern pure virtual function void ext_pure_virt_func (x);\n\npure virtual function void pure_virt_func (x);\n\n// maybe illegal: static and/or virtual can appear only once.\npure virtual static function void pure_virt_static_func (x);\n\npure virtual protected function void pure_virt_protected_func (x);\n\npure virtual local function void pure_virt_local_func (x);\n\n\nextern task ext_task (x, y);\n\nextern static task ext_static_task (x, y);\n\nextern protected task ext_protected_task (x, y);\n\nextern local task ext_local_task (x, y);\n\nextern pure virtual task ext_pure_virt_task (x);\n\npure virtual task pure_virt_task (x);\n\n// maybe illegal: static and/or virtual can appear only once.\npure virtual static task pure_virt_static_task (x);\n\npure virtual protected task pure_virt_protected_task (x);\n\npure virtual local task pure_virt_local_task (x);\n\nfunction automatic auto_function (x);\nendfunction : auto_function\n\nfunction static auto_static (x);\nendfunction : auto_static\n\nendclass : foo\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-string.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-string.d/expected.tags",
    "content": "test_string\tinput.sv\t/^package test_string;$/;\"\tK\ntest_var_a\tinput.sv\t/^  int    test_var_a = 1'b1;$/;\"\tr\tpackage:test_string\ntest_str_a\tinput.sv\t/^  string test_str_a = \"Hello World!\\\\n\";$/;\"\tr\tpackage:test_string\ntest_var_b\tinput.sv\t/^  int    test_var_b = 100;$/;\"\tr\tpackage:test_string\ntest_str_b\tinput.sv\t/^  string test_str_b = \"\\\\\"\";$/;\"\tr\tpackage:test_string\ntest_var_c\tinput.sv\t/^  int    test_var_c = -1;$/;\"\tr\tpackage:test_string\ntest_str_c\tinput.sv\t/^  string test_str_c = \"\\\\b \\\\n \\\\t \\\\\\\\ \\\\\" \\\\v \\\\f \\\\a \\\\0 \\\\1 \\\\11 \\\\377 \\\\x0 \\\\x01 \\\\xff \\\\e\"/;\"\tr\tpackage:test_string\ntest_var_d\tinput.sv\t/^  int    test_var_d = 1024;$/;\"\tr\tpackage:test_string\ntest_str_d\tinput.sv\t/^  string test_str_d = \"\\\\\"\\\\\\\\\\\\\"\";$/;\"\tr\tpackage:test_string\ntest_var_e\tinput.sv\t/^  int    test_var_e = -1;$/;\"\tr\tpackage:test_string\ntest_str_e\tinput.sv\t/^  string test_str_e = \"\\\\\\\\\";$/;\"\tr\tpackage:test_string\ntest_str_f\tinput.sv\t/^  string test_str_f = \"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\";$/;\"\tr\tpackage:test_string\ntest_str_g\tinput.sv\t/^  string test_str_g = \"\\\\\"\\\\\"\\\\\"\";$/;\"\tr\tpackage:test_string\ntest_str_h\tinput.sv\t/^  string test_str_h = \"\\\\\"\\\\\"\\\\\"\\\\\"\";$/;\"\tr\tpackage:test_string\ntest_str_i\tinput.sv\t/^  string test_str_i = \"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\";$/;\"\tr\tpackage:test_string\ntest_str_j\tinput.sv\t/^  string test_str_j = \"\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\";$/;\"\tr\tpackage:test_string\ntest_str_k\tinput.sv\t/^  string test_str_k = \"\\\\0\\\\188\\\\xf\\\\\"\\\\\\\\\\\\\"\\\\\\\\\\\\\"\\\\\\\\\";$/;\"\tr\tpackage:test_string\ntest_str_l\tinput.sv\t/^  localparam byte test_str_l = \"\\\\\\\\\" ;$/;\"\tc\tpackage:test_string\ntest_str_m\tinput.sv\t/^  localparam byte test_str_m = \"\\\\\"\" ;$/;\"\tc\tpackage:test_string\ntest_str_n\tinput.sv\t/^  parameter string test_str_n = \"\\\\t\\\\n\\\\\\\\\\\\\"\\\\v\\\\f\";$/;\"\tc\tpackage:test_string\ntest_struct_str\tinput.sv\t/^  } test_struct_str;$/;\"\tS\tpackage:test_string\nname\tinput.sv\t/^    string name = \"Hello \\\\\" World!\";$/;\"\tw\tstruct:test_string.test_struct_str\naddr\tinput.sv\t/^    bit [23:0] addr;$/;\"\tw\tstruct:test_string.test_struct_str\ntest_typedef_str\tinput.sv\t/^  } test_typedef_str;$/;\"\tT\tpackage:test_string\nname\tinput.sv\t/^    string name = \"\\\\0\\\\\\\\\\\\\"\\\\\\\\\";$/;\"\tw\ttypedef:test_string.test_typedef_str\naddr\tinput.sv\t/^    bit [23:0] addr;$/;\"\tw\ttypedef:test_string.test_typedef_str\ntype_id\tinput.sv\t/^    string type_id = \"\\\\a\\\\t\\\\0\\\\xddVerilog\\\\\"\";$/;\"\tw\ttypedef:test_string.test_typedef_str\ntest_func_port\tinput.sv\t/^  function void test_func_port (string test_str_port = \"\\\\\\\\\\\\\"\", int test_var_port=1);$/;\"\tf\tpackage:test_string\ntest_str_port\tinput.sv\t/^  function void test_func_port (string test_str_port = \"\\\\\\\\\\\\\"\", int test_var_port=1);$/;\"\tp\tfunction:test_string.test_func_port\ntest_var_port\tinput.sv\t/^  function void test_func_port (string test_str_port = \"\\\\\\\\\\\\\"\", int test_var_port=1);$/;\"\tp\tfunction:test_string.test_func_port\ntest_task_port\tinput.sv\t/^  task test_task_port  (int test_int_port, string test_str_port=\"\\\\\"\\\\\\\\\", byte test_byte_port =/;\"\tt\tpackage:test_string\ntest_int_port\tinput.sv\t/^  task test_task_port  (int test_int_port, string test_str_port=\"\\\\\"\\\\\\\\\", byte test_byte_port =/;\"\tp\ttask:test_string.test_task_port\ntest_str_port\tinput.sv\t/^  task test_task_port  (int test_int_port, string test_str_port=\"\\\\\"\\\\\\\\\", byte test_byte_port =/;\"\tp\ttask:test_string.test_task_port\ntest_byte_port\tinput.sv\t/^  task test_task_port  (int test_int_port, string test_str_port=\"\\\\\"\\\\\\\\\", byte test_byte_port =/;\"\tp\ttask:test_string.test_task_port\ntest_ending_var\tinput.sv\t/^  bit [7:0] test_ending_var;$/;\"\tr\tpackage:test_string\ntest_ending_str\tinput.sv\t/^  string test_ending_str = \"'\\\\\"'END;'\";$/;\"\tr\tpackage:test_string\ntest_ending\tinput.sv\t/^  function void test_ending(); endfunction$/;\"\tf\tpackage:test_string\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-string.d/input.sv",
    "content": "package test_string;\n  int    test_var_a = 1'b1;\n  string test_str_a = \"Hello World!\\n\";\n  int    test_var_b = 100;\n  string test_str_b = \"\\\"\";\n  int    test_var_c = -1;\n\n  // LRM 5.9.1 Special characters in strings\n  // \\n \\t \\\\ \\\" \\v \\f \\a \\ddd \\xdd ( Others: such as \"\\b\" is treated the same as \"b\" )\n  string test_str_c = \"\\b \\n \\t \\\\ \\\" \\v \\f \\a \\0 \\1 \\11 \\377 \\x0 \\x01 \\xff \\e\";\n\n  int    test_var_d = 1024;\n  string test_str_d = \"\\\"\\\\\\\"\";\n  int    test_var_e = -1;\n  string test_str_e = \"\\\\\";\n  string test_str_f = \"\\\\\\\\\\\\\\\\\";\n  string test_str_g = \"\\\"\\\"\\\"\";\n  string test_str_h = \"\\\"\\\"\\\"\\\"\";\n  string test_str_i = \"\\\\\\\\\\\\\\\"\";\n  string test_str_j = \"\\\"\\\\\\\\\\\\\";\n  string test_str_k = \"\\0\\188\\xf\\\"\\\\\\\"\\\\\\\"\\\\\";\n\n  localparam byte test_str_l = \"\\\\\" ;\n  localparam byte test_str_m = \"\\\"\" ;\n  parameter string test_str_n = \"\\t\\n\\\\\\\"\\v\\f\";\n\n  struct {\n    string name = \"Hello \\\" World!\";\n    bit [23:0] addr;\n  } test_struct_str;\n\n  typedef struct {\n    string name = \"\\0\\\\\\\"\\\\\";\n    bit [23:0] addr;\n    string type_id = \"\\a\\t\\0\\xddVerilog\\\"\";\n  } test_typedef_str;\n\n  function void test_func_port (string test_str_port = \"\\\\\\\"\", int test_var_port=1);\n  endfunction\n  task test_task_port  (int test_int_port, string test_str_port=\"\\\"\\\\\", byte test_byte_port = \"\\\"\");\n  endtask\n\n  // All tags above should NOT be missed\n  bit [7:0] test_ending_var;\n  string test_ending_str = \"'\\\"'END;'\";\n  function void test_ending(); endfunction\nendpackage\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-struct.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-struct.d/expected.tags",
    "content": "S\tinput.sv\t/^class S;$/;\"\tC\nIR\tinput.sv\t/^  struct { bit [7:0] opcode; bit [23:0] addr; }IR;  \\/\\/ anonymous structure$/;\"\tS\tclass:S\nopcode\tinput.sv\t/^  struct { bit [7:0] opcode; bit [23:0] addr; }IR;  \\/\\/ anonymous structure$/;\"\tw\tstruct:S.IR\naddr\tinput.sv\t/^  struct { bit [7:0] opcode; bit [23:0] addr; }IR;  \\/\\/ anonymous structure$/;\"\tw\tstruct:S.IR\nfoo\tinput.sv\t/^  function foo;$/;\"\tf\tclass:S\ninstruction\tinput.sv\t/^  } instruction;      \\/\\/ named structure type$/;\"\tT\tclass:S\nopcode\tinput.sv\t/^    bit [7:0] opcode;$/;\"\tw\ttypedef:S.instruction\naddr\tinput.sv\t/^    bit [23:0] addr;$/;\"\tw\ttypedef:S.instruction\nIR1\tinput.sv\t/^  instruction IR1;    \\/\\/ define variable$/;\"\tr\tclass:S\npack1\tinput.sv\t/^  } pack1; \\/\\/ signed, 2-state$/;\"\tS\tclass:S\na\tinput.sv\t/^    int a;$/;\"\tw\tstruct:S.pack1\nb\tinput.sv\t/^    shortint b;$/;\"\tw\tstruct:S.pack1\nc\tinput.sv\t/^    byte c;$/;\"\tw\tstruct:S.pack1\nd\tinput.sv\t/^    bit [7:0] d;$/;\"\tw\tstruct:S.pack1\npack2\tinput.sv\t/^  } pack2; \\/\\/ unsigned, 4-state$/;\"\tS\tclass:S\na\tinput.sv\t/^    time a;$/;\"\tw\tstruct:S.pack2\nb\tinput.sv\t/^    integer b;$/;\"\tw\tstruct:S.pack2\nc\tinput.sv\t/^    logic [31:0] c;$/;\"\tw\tstruct:S.pack2\ns_atmcell\tinput.sv\t/^  } s_atmcell;$/;\"\tT\tclass:S\nGFC\tinput.sv\t/^    bit [3:0] GFC;$/;\"\tw\ttypedef:S.s_atmcell\nVPI\tinput.sv\t/^    bit [7:0] VPI;$/;\"\tw\ttypedef:S.s_atmcell\nVCI\tinput.sv\t/^    bit [11:0] VCI;$/;\"\tw\ttypedef:S.s_atmcell\nCLP\tinput.sv\t/^    bit CLP;$/;\"\tw\ttypedef:S.s_atmcell\nPT\tinput.sv\t/^    bit [3:0] PT ;$/;\"\tw\ttypedef:S.s_atmcell\nHEC\tinput.sv\t/^    bit [7:0] HEC;$/;\"\tw\ttypedef:S.s_atmcell\nPayload\tinput.sv\t/^    bit [47:0] [7:0] Payload;$/;\"\tw\ttypedef:S.s_atmcell\nfiller\tinput.sv\t/^    bit [2:0] filler;$/;\"\tw\ttypedef:S.s_atmcell\npacket1\tinput.sv\t/^  } packet1;$/;\"\tT\tclass:S\naddr\tinput.sv\t/^    int addr = 1 + constant;$/;\"\tw\ttypedef:S.packet1\ncrc\tinput.sv\t/^    int crc;$/;\"\tw\ttypedef:S.packet1\ndata\tinput.sv\t/^    byte data [4] = '{4{1}};$/;\"\tw\ttypedef:S.packet1\npi\tinput.sv\t/^  packet1 pi = '{1,2,'{2,3,4,5}}; \\/\\/suppresses the typedef initialization$/;\"\tr\tclass:S\nU\tinput.sv\t/^class U;$/;\"\tC\nnum\tinput.sv\t/^  typedef union { int i; shortreal f; } num;  \\/\\/ named union type$/;\"\tT\tclass:U\ni\tinput.sv\t/^  typedef union { int i; shortreal f; } num;  \\/\\/ named union type$/;\"\tw\ttypedef:U.num\nf\tinput.sv\t/^  typedef union { int i; shortreal f; } num;  \\/\\/ named union type$/;\"\tw\ttypedef:U.num\nn\tinput.sv\t/^  num n;$/;\"\tr\tclass:U\nnew\tinput.sv\t/^  function new;$/;\"\tf\tclass:U\ntagged_st\tinput.sv\t/^  } tagged_st;                        \\/\\/ named structure$/;\"\tT\tclass:U\nisfloat\tinput.sv\t/^    bit isfloat;$/;\"\tw\ttypedef:U.tagged_st\nn\tinput.sv\t/^    union { int i; shortreal f; } n;  \\/\\/ anonymous union type$/;\"\tw\ttypedef:U.tagged_st\nu_atmcell\tinput.sv\t/^  } u_atmcell;$/;\"\tT\tclass:U\nacell\tinput.sv\t/^    s_atmcell acell;$/;\"\tw\ttypedef:U.u_atmcell\nbit_slice\tinput.sv\t/^    bit [423:0] bit_slice;$/;\"\tw\ttypedef:U.u_atmcell\nbyte_slice\tinput.sv\t/^    bit [52:0][7:0] byte_slice;$/;\"\tw\ttypedef:U.u_atmcell\nu1\tinput.sv\t/^  u_atmcell u1;$/;\"\tr\tclass:U\nb\tinput.sv\t/^  byte b; bit [3:0] nib;$/;\"\tr\tclass:U\nnib\tinput.sv\t/^  byte b; bit [3:0] nib;$/;\"\tr\tclass:U\nO\tinput.sv\t/^class O;$/;\"\tC\nIR\tinput.sv\t/^  struct { bit [7:0] opcode; }IR;$/;\"\tS\tclass:O\nopcode\tinput.sv\t/^  struct { bit [7:0] opcode; }IR;$/;\"\tw\tstruct:O.IR\npack1\tinput.sv\t/^  struct packed signed { int a; } pack1;$/;\"\tS\tclass:O\na\tinput.sv\t/^  struct packed signed { int a; } pack1;$/;\"\tw\tstruct:O.pack1\npack2\tinput.sv\t/^  struct packed unsigned { int a;} pack2;$/;\"\tS\tclass:O\na\tinput.sv\t/^  struct packed unsigned { int a;} pack2;$/;\"\tw\tstruct:O.pack2\nunion1\tinput.sv\t/^  union packed unsigned { logic [7:0] a; } union1;$/;\"\tS\tclass:O\na\tinput.sv\t/^  union packed unsigned { logic [7:0] a; } union1;$/;\"\tw\tstruct:O.union1\npack3\tinput.sv\t/^  struct packed signed { int a; } [3:0] pack3, pack4;$/;\"\tS\tclass:O\na\tinput.sv\t/^  struct packed signed { int a; } [3:0] pack3, pack4;$/;\"\tw\tstruct:O.pack3\npack4\tinput.sv\t/^  struct packed signed { int a; } [3:0] pack3, pack4;$/;\"\tS\tclass:O\na\tinput.sv\t/^  struct packed signed { int a; } [3:0] pack3, pack4;$/;\"\tw\tstruct:O.pack4\nuser_t\tinput.sv\t/^  typedef logic user_t;$/;\"\tT\tclass:O\nenum00_e\tinput.sv\t/^  enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tE\tclass:O\nFOO\tinput.sv\t/^  enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tc\tenum:O.enum00_e\nBAR\tinput.sv\t/^  enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tc\tenum:O.enum00_e\nBAZ\tinput.sv\t/^  enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tc\tenum:O.enum00_e\nenum01_e\tinput.sv\t/^  enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tE\tclass:O\nFOO\tinput.sv\t/^  enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tc\tenum:O.enum01_e\nBAR\tinput.sv\t/^  enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tc\tenum:O.enum01_e\nBAZ\tinput.sv\t/^  enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tc\tenum:O.enum01_e\nenum10_e\tinput.sv\t/^  enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tE\tclass:O\nA\tinput.sv\t/^  enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tc\tenum:O.enum10_e\nB\tinput.sv\t/^  enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tc\tenum:O.enum10_e\nC\tinput.sv\t/^  enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tc\tenum:O.enum10_e\nenum11_e\tinput.sv\t/^  enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tE\tclass:O\nA\tinput.sv\t/^  enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tc\tenum:O.enum11_e\nB\tinput.sv\t/^  enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tc\tenum:O.enum11_e\nC\tinput.sv\t/^  enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tc\tenum:O.enum11_e\nenum0_t\tinput.sv\t/^  typedef enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum0_t ;$/;\"\tT\tclass:O\nFOO\tinput.sv\t/^  typedef enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum0_t ;$/;\"\tc\ttypedef:O.enum0_t\nBAR\tinput.sv\t/^  typedef enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum0_t ;$/;\"\tc\ttypedef:O.enum0_t\nBAZ\tinput.sv\t/^  typedef enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum0_t ;$/;\"\tc\ttypedef:O.enum0_t\nenum1_t\tinput.sv\t/^  typedef enum logic unsigned{A,B,C}[1:0]enum1_t;$/;\"\tT\tclass:O\nA\tinput.sv\t/^  typedef enum logic unsigned{A,B,C}[1:0]enum1_t;$/;\"\tc\ttypedef:O.enum1_t\nB\tinput.sv\t/^  typedef enum logic unsigned{A,B,C}[1:0]enum1_t;$/;\"\tc\ttypedef:O.enum1_t\nC\tinput.sv\t/^  typedef enum logic unsigned{A,B,C}[1:0]enum1_t;$/;\"\tc\ttypedef:O.enum1_t\ncomplex0_s\tinput.sv\t/^  } [1:0] complex0_s, complex1_s;$/;\"\tS\tclass:O\na\tinput.sv\t/^    logic a,b ;$/;\"\tw\tstruct:O.complex0_s\nb\tinput.sv\t/^    logic a,b ;$/;\"\tw\tstruct:O.complex0_s\ns0\tinput.sv\t/^    logic [15:0] [7:0] s0 , s1;$/;\"\tw\tstruct:O.complex0_s\ns1\tinput.sv\t/^    logic [15:0] [7:0] s0 , s1;$/;\"\tw\tstruct:O.complex0_s\nstruct0_s\tinput.sv\t/^    } [15:0] [7:0] struct0_s, struct1_s;$/;\"\tw\tstruct:O.complex0_s\nstruct1_s\tinput.sv\t/^    } [15:0] [7:0] struct0_s, struct1_s;$/;\"\tw\tstruct:O.complex0_s\nenum00_e\tinput.sv\t/^    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tw\tstruct:O.complex0_s\nenum01_e\tinput.sv\t/^    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tw\tstruct:O.complex0_s\nenum10_e\tinput.sv\t/^    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tw\tstruct:O.complex0_s\nenum11_e\tinput.sv\t/^    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tw\tstruct:O.complex0_s\nd\tinput.sv\t/^    bit[7:0][1:0]d,e;$/;\"\tw\tstruct:O.complex0_s\ne\tinput.sv\t/^    bit[7:0][1:0]d,e;$/;\"\tw\tstruct:O.complex0_s\ncomplex1_s\tinput.sv\t/^  } [1:0] complex0_s, complex1_s;$/;\"\tS\tclass:O\na\tinput.sv\t/^    logic a,b ;$/;\"\tw\tstruct:O.complex1_s\nb\tinput.sv\t/^    logic a,b ;$/;\"\tw\tstruct:O.complex1_s\ns0\tinput.sv\t/^    logic [15:0] [7:0] s0 , s1;$/;\"\tw\tstruct:O.complex1_s\ns1\tinput.sv\t/^    logic [15:0] [7:0] s0 , s1;$/;\"\tw\tstruct:O.complex1_s\nstruct0_s\tinput.sv\t/^    } [15:0] [7:0] struct0_s, struct1_s;$/;\"\tw\tstruct:O.complex1_s\nstruct1_s\tinput.sv\t/^    } [15:0] [7:0] struct0_s, struct1_s;$/;\"\tw\tstruct:O.complex1_s\nenum00_e\tinput.sv\t/^    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tw\tstruct:O.complex1_s\nenum01_e\tinput.sv\t/^    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tw\tstruct:O.complex1_s\nenum10_e\tinput.sv\t/^    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tw\tstruct:O.complex1_s\nenum11_e\tinput.sv\t/^    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tw\tstruct:O.complex1_s\nd\tinput.sv\t/^    bit[7:0][1:0]d,e;$/;\"\tw\tstruct:O.complex1_s\ne\tinput.sv\t/^    bit[7:0][1:0]d,e;$/;\"\tw\tstruct:O.complex1_s\ncomplex_t\tinput.sv\t/^  } [1:0] complex_t;$/;\"\tT\tclass:O\na\tinput.sv\t/^    logic a,b ;$/;\"\tw\ttypedef:O.complex_t\nb\tinput.sv\t/^    logic a,b ;$/;\"\tw\ttypedef:O.complex_t\ns0\tinput.sv\t/^    logic [15:0] [7:0] s0 , s1;$/;\"\tw\ttypedef:O.complex_t\ns1\tinput.sv\t/^    logic [15:0] [7:0] s0 , s1;$/;\"\tw\ttypedef:O.complex_t\nstruct0_s\tinput.sv\t/^    } [15:0] [7:0] struct0_s, struct1_s;$/;\"\tw\ttypedef:O.complex_t\nstruct1_s\tinput.sv\t/^    } [15:0] [7:0] struct0_s, struct1_s;$/;\"\tw\ttypedef:O.complex_t\nenum00_e\tinput.sv\t/^    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tw\ttypedef:O.complex_t\nenum01_e\tinput.sv\t/^    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;$/;\"\tw\ttypedef:O.complex_t\nenum10_e\tinput.sv\t/^    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tw\ttypedef:O.complex_t\nenum11_e\tinput.sv\t/^    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;$/;\"\tw\ttypedef:O.complex_t\nd\tinput.sv\t/^    bit[7:0][1:0]d,e;$/;\"\tw\ttypedef:O.complex_t\ne\tinput.sv\t/^    bit[7:0][1:0]d,e;$/;\"\tw\ttypedef:O.complex_t\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-struct.d/input.sv",
    "content": "//\n// LRM 7. Aggregate data types\n//\n\n// 7.2 Structures\nclass S;\n  struct { bit [7:0] opcode; bit [23:0] addr; }IR;  // anonymous structure\n                                                    // defines variable IR\n  function foo;\n    IR.opcode = 1;    // set field in IR.\n  endfunction\n  typedef struct {\n    bit [7:0] opcode;\n    bit [23:0] addr;\n  } instruction;      // named structure type\n  instruction IR1;    // define variable\n\n  // 7.2.1 Packed structures\n  struct packed signed {\n    int a;\n    shortint b;\n    byte c;\n    bit [7:0] d;\n  } pack1; // signed, 2-state\n\n  struct packed unsigned {\n    time a;\n    integer b;\n    logic [31:0] c;\n  } pack2; // unsigned, 4-state\n\n  typedef struct packed { // default unsigned\n    bit [3:0] GFC;\n    bit [7:0] VPI;\n    bit [11:0] VCI;\n    bit CLP;\n    bit [3:0] PT ;\n    bit [7:0] HEC;\n    bit [47:0] [7:0] Payload;\n    bit [2:0] filler;\n  } s_atmcell;\n\n  // 7.2.2 Assigning to structures\n  typedef struct {\n    int addr = 1 + constant;\n    int crc;\n    byte data [4] = '{4{1}};\n  } packet1;\n\n  packet1 pi = '{1,2,'{2,3,4,5}}; //suppresses the typedef initialization\nendclass\n\n// 7.3 Unions\nclass U;\n  typedef union { int i; shortreal f; } num;  // named union type\n  num n;\n  function new;\n    n.f = 0.0;  // set n in floating point format\n  endfunction\n\n  typedef struct {\n    bit isfloat;\n    union { int i; shortreal f; } n;  // anonymous union type\n  } tagged_st;                        // named structure\n\n  // 7.3.1 Packed unions\n  typedef union packed { // default unsigned\n    s_atmcell acell;\n    bit [423:0] bit_slice;\n    bit [52:0][7:0] byte_slice;\n  } u_atmcell;\n\n  u_atmcell u1;\n  byte b; bit [3:0] nib;\n  b = u1.bit_slice[415:408];    // same as b = u1.byte_slice[51];\n  nib = u1.bit_slice [423:420]; // same as nib = u1.acell.GFC;\n\n  // 7.3.2 Tagged unions\n  // FIXME: TBD\nendclass\n\n// orignal\nclass O;\n  struct { bit [7:0] opcode; }IR;\n  struct packed signed { int a; } pack1;\n  struct packed unsigned { int a;} pack2;\n  union packed unsigned { logic [7:0] a; } union1;\n  struct packed signed { int a; } [3:0] pack3, pack4;\n\n  // complex enum\n  typedef logic user_t;\n  enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;\n  enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;\n  typedef enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum0_t ;\n  typedef enum logic unsigned{A,B,C}[1:0]enum1_t;\n\n  // complex struct\n  struct packed signed {\n    logic a,b ;\n    logic [15:0] [7:0] s0 , s1;\n    struct {\n      logic x, y; // not emitted\n    } [15:0] [7:0] struct0_s, struct1_s;\n    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;\n    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;\n    bit[7:0][1:0]d,e;\n  } [1:0] complex0_s, complex1_s;\n\n  // complex typedef of struct\n  typedef struct packed signed {\n    logic a,b ;\n    logic [15:0] [7:0] s0 , s1;\n    struct {\n      logic x, y; // not emitted\n    } [15:0] [7:0] struct0_s, struct1_s;\n    enum user_t [1:0] { FOO, BAR, BAZ } [3:0] enum00_e, enum01_e ;\n    enum logic unsigned{A,B,C}[1:0]enum10_e,enum11_e;\n    bit[7:0][1:0]d,e;\n  } [1:0] complex_t;\nendclass\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-symtab.d/args.ctags",
    "content": "--sort=no\n--extras=+q\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-symtab.d/expected.tags",
    "content": "int32_t\tinput.sv\t/^typedef bit[31:0] int32_t;$/;\"\tT\nmod\tinput.sv\t/^module mod($/;\"\tm\nclk\tinput.sv\t/^  input bit clk,$/;\"\tp\tmodule:mod\nmod.clk\tinput.sv\t/^  input bit clk,$/;\"\tp\tmodule:mod\na\tinput.sv\t/^  input int32_t a$/;\"\tp\tmodule:mod\nmod.a\tinput.sv\t/^  input int32_t a$/;\"\tp\tmodule:mod\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-symtab.d/input.sv",
    "content": "// Takne from #2413 submitted by @antoinemadec\ntypedef bit[31:0] int32_t;\nmodule mod(\n  input bit clk,\n  input int32_t a\n);\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-task-function.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-task-function.d/expected.tags",
    "content": "task_func\tinput.sv\t/^module task_func;$/;\"\tm\ncrc\tinput.sv\t/^  function automatic int crc( ref byte packet [1000:1] );$/;\"\tf\tmodule:task_func\npacket\tinput.sv\t/^  function automatic int crc( ref byte packet [1000:1] );$/;\"\tp\tfunction:task_func.crc\nshow\tinput.sv\t/^  task automatic show ( const ref byte data [] );$/;\"\tt\tmodule:task_func\ndata\tinput.sv\t/^  task automatic show ( const ref byte data [] );$/;\"\tp\ttask:task_func.show\nattr\tinput.sv\t/^  task automatic attr ( (* my_attr *) const ref foo, enum { s0, s1 } sel_e );$/;\"\tt\tmodule:task_func\nfoo\tinput.sv\t/^  task automatic attr ( (* my_attr *) const ref foo, enum { s0, s1 } sel_e );$/;\"\tp\ttask:task_func.attr\nsel_e\tinput.sv\t/^  task automatic attr ( (* my_attr *) const ref foo, enum { s0, s1 } sel_e );$/;\"\tp\ttask:task_func.attr\nC\tinput.sv\t/^class C;$/;\"\tC\nM\tinput.sv\t/^module M (output a, input b, c, d);$/;\"\tm\na\tinput.sv\t/^module M (output a, input b, c, d);$/;\"\tp\tmodule:M\nb\tinput.sv\t/^module M (output a, input b, c, d);$/;\"\tp\tmodule:M\nc\tinput.sv\t/^module M (output a, input b, c, d);$/;\"\tp\tmodule:M\nd\tinput.sv\t/^module M (output a, input b, c, d);$/;\"\tp\tmodule:M\nmyprint\tinput.sv\t/^  function void myprint (int a);$/;\"\tf\tmodule:M\na\tinput.sv\t/^  function void myprint (int a);$/;\"\tp\tfunction:M.myprint\nx\tinput.sv\t/^    logic x;$/;\"\tr\tfunction:M.myprint\nN\tinput.sv\t/^module N;$/;\"\tm\narray_locator\tinput.sv\t/^  function array_locator();$/;\"\tf\tmodule:N\nSA\tinput.sv\t/^    string SA[10], qs[$];$/;\"\tr\tfunction:N.array_locator\nqs\tinput.sv\t/^    string SA[10], qs[$];$/;\"\tr\tfunction:N.array_locator\nIA\tinput.sv\t/^    int IA[int], qi[$];$/;\"\tr\tfunction:N.array_locator\nqi\tinput.sv\t/^    int IA[int], qi[$];$/;\"\tr\tfunction:N.array_locator\narray_ordering\tinput.sv\t/^  function array_ordering();$/;\"\tf\tmodule:N\nc\tinput.sv\t/^    struct { byte red, green, blue; } c [512];$/;\"\tS\tfunction:N.array_ordering\nred\tinput.sv\t/^    struct { byte red, green, blue; } c [512];$/;\"\tw\tstruct:N.array_ordering.c\ngreen\tinput.sv\t/^    struct { byte red, green, blue; } c [512];$/;\"\tw\tstruct:N.array_ordering.c\nblue\tinput.sv\t/^    struct { byte red, green, blue; } c [512];$/;\"\tw\tstruct:N.array_ordering.c\nfoo\tinput.sv\t/^package foo;$/;\"\tK\nuvm_object\tinput.sv\t/^  typedef logic uvm_object;$/;\"\tT\tpackage:foo\nbar\tinput.sv\t/^  function logic bar (uvm_object baz);$/;\"\tf\tpackage:foo\nbaz\tinput.sv\t/^  function logic bar (uvm_object baz);$/;\"\tp\tfunction:foo.bar\nfunc_test\tinput.sv\t/^class func_test;$/;\"\tC\nuvm_object\tinput.sv\t/^  typedef logic uvm_object;$/;\"\tT\tclass:func_test\nuvm_comparer\tinput.sv\t/^  typedef logic uvm_comparer;$/;\"\tT\tclass:func_test\nuvm_packer\tinput.sv\t/^  typedef logic uvm_packer;$/;\"\tT\tclass:func_test\nbar\tinput.sv\t/^  function void foo::bar(uvm_object element);\t\\/\\/ FIXME$/;\"\tf\tclass:func_test.foo\nelement\tinput.sv\t/^  function void foo::bar(uvm_object element);\t\\/\\/ FIXME$/;\"\tp\tfunction:func_test.foo.bar\ndo_compare\tinput.sv\t/^  function bit do_compare(uvm_object rhs, uvm_comparer comparer);$/;\"\tf\tclass:func_test\nrhs\tinput.sv\t/^  function bit do_compare(uvm_object rhs, uvm_comparer comparer);$/;\"\tp\tfunction:func_test.do_compare\ncomparer\tinput.sv\t/^  function bit do_compare(uvm_object rhs, uvm_comparer comparer);$/;\"\tp\tfunction:func_test.do_compare\ndo_pack\tinput.sv\t/^  function void do_pack(uvm_packer packer);$/;\"\tf\tclass:func_test\npacker\tinput.sv\t/^  function void do_pack(uvm_packer packer);$/;\"\tp\tfunction:func_test.do_pack\nget_if\tinput.sv\t/^  function uvm_port_base #(IF) get_if(int index=0);\t\\/\\/ FIXME$/;\"\tf\tclass:func_test\nindex\tinput.sv\t/^  function uvm_port_base #(IF) get_if(int index=0);\t\\/\\/ FIXME$/;\"\tp\tfunction:func_test.get_if\nbind_vitf\tinput.sv\t/^  function void bind_vitf(virtual wb_if.master sigs);$/;\"\tf\tclass:func_test\nsigs\tinput.sv\t/^  function void bind_vitf(virtual wb_if.master sigs);$/;\"\tp\tfunction:func_test.bind_vitf\nget\tinput.sv\t/^  function string get(string v);$/;\"\tf\tclass:func_test\nv\tinput.sv\t/^  function string get(string v);$/;\"\tp\tfunction:func_test.get\nget_arg\tinput.sv\t/^  function string get_arg();$/;\"\tf\tclass:func_test\nparameterized_task\tinput.sv\t/^  function parameterized_task;$/;\"\tf\tclass:func_test\nfoo\tinput.sv\t/^  function void foo (inout bar::type_t baz);$/;\"\tf\tclass:func_test\nbaz\tinput.sv\t/^  function void foo (inout bar::type_t baz);$/;\"\tp\tfunction:func_test.foo\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-task-function.d/input.sv",
    "content": "// LRM 13.5.2 Pass by Reference\nmodule task_func;\n\n  function automatic int crc( ref byte packet [1000:1] );\n    for( int j= 1; j <= 1000; j++ ) begin\n      crc ^= packet[j];\n    end\n  endfunction\n\n  task automatic show ( const ref byte data [] );\n    for ( int j = 0; j < data.size ; j++ )\n      $display( data[j] ); // data can be read but not written\n  endtask\n\n  task automatic attr ( (* my_attr *) const ref foo, enum { s0, s1 } sel_e );\n  endtask\n\nendmodule\n\n// disabled K_PROTOTYPE: don't use \"--extras=+q\" for coverage\nclass C;\n  extern function void ext_func ();\n  pure virtual task ext_pure_virt_task (x);\n  typedef class   fwd_type_class;\nendclass\n\n// LRM 13.4.1 Return values and void functions\nmodule M (output a, input b, c, d);\n  always_comb begin\n    a = b + myfunc1(c, d); // call myfunc1 (defined above) as an expression\n    myprint(a); // call myprint (defined below) as a statement\n  end\n\n  function void myprint (int a);\n    logic x;\n  endfunction\nendmodule\n\n// 7.12 Array manipulation methods\nmodule N;\n  // 7.12.1 Array locator methods\n  function array_locator();\n    string SA[10], qs[$];\n    int IA[int], qi[$];\n    // Find all items greater than 5\n    qi = IA.find( x ) with ( x > 5 );\n  endfunction\n\n  // 7.12.2 Array ordering methods\n  function array_ordering();\n    struct { byte red, green, blue; } c [512];\n    c.sort with ( item.red );               // sort c using the red field only\n    c.sort( x ) with ( {x.blue, x.green} ); // sort by blue then green\n  endfunction\nendmodule\n\n// from UVM-1.2\npackage foo;\n  import \"DPI-C\" context function int import_func (string str);\n  typedef logic uvm_object;\n  function logic bar (uvm_object baz);\n    return 1'b1;\n  endfunction\nendpackage\n\nclass func_test;\n  typedef logic uvm_object;\n  typedef logic uvm_comparer;\n  typedef logic uvm_packer;\n\n  function void foo::bar(uvm_object element);\t// FIXME\n  endfunction\n\n  function bit do_compare(uvm_object rhs, uvm_comparer comparer);\n    foo::bar(rhs);\n  endfunction\n\n  function void do_pack(uvm_packer packer);\n    for (int i = 0; i < 10; i++)\n      ;\n  endfunction\n\n  function uvm_port_base #(IF) get_if(int index=0);\t// FIXME\n  endfunction\n\n  function void bind_vitf(virtual wb_if.master sigs);\n    this.sigs = sigs;\n  endfunction\n\n  // paren\n  function string get(string v);\n      if (v[0] == \"(\")  // \"(\" in paired paren '( ... )'\n        ;\n  endfunction\n\n  function string get_arg();\n  endfunction\n\n  // cf. LRM 13.8 Parameterized tasks and functions\n  function parameterized_task;\n    // src/reg/uvm_reg_indirect.svh\n    uvm_resource_db#(bit)::set({\"REG::\", get_full_name()}, \"NO_REG_TESTS\", 1);\n  endfunction\n\n  function void foo (inout bar::type_t baz);\n  endfunction\nendclass\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-typed-parameter.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-typed-parameter.d/expected.tags",
    "content": "default_name\tinput.sv\t/^  parameter string default_name = \"John Smith\"; \\/\\/ default_name:register => default_name:const/;\"\tc\nflag\tinput.sv\t/^  parameter logic flag = 1 ; \\/\\/ flags:register => flags:constant$/;\"\tc\nr1\tinput.sv\t/^  parameter real r1 = 3.5e17; \\/\\/ r1:register => r1:constant$/;\"\tc\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-typed-parameter.d/input.sv",
    "content": "  // 6.16 String data type\n  parameter string default_name = \"John Smith\"; // default_name:register => default_name:constant\n\n  // 6.20 Constants\n  parameter logic flag = 1 ; // flags:register => flags:constant\n  parameter real r1 = 3.5e17; // r1:register => r1:constant\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-typedef.d/args.ctags",
    "content": "--extras=+q\n--kinds-systemverilog=+Q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-typedef.d/expected.tags",
    "content": "fwd_type_enum\tinput.sv\t/^typedef enum              fwd_type_enum;$/;\"\tQ\nfwd_type_struct\tinput.sv\t/^typedef struct            fwd_type_struct;$/;\"\tQ\nfwd_type_union\tinput.sv\t/^typedef union             fwd_type_union;$/;\"\tQ\nfwd_type_class\tinput.sv\t/^typedef class             fwd_type_class;$/;\"\tQ\nfwd_type_interface_class\tinput.sv\t/^typedef interface class   fwd_type_interface_class;$/;\"\tQ\nfwd_type\tinput.sv\t/^typedef                   fwd_type;$/;\"\tQ\ntype_enum\tinput.sv\t/^typedef enum           {no, yes} type_enum;$/;\"\tT\nno\tinput.sv\t/^typedef enum           {no, yes} type_enum;$/;\"\tc\ttypedef:type_enum\ntype_enum.no\tinput.sv\t/^typedef enum           {no, yes} type_enum;$/;\"\tc\ttypedef:type_enum\nyes\tinput.sv\t/^typedef enum           {no, yes} type_enum;$/;\"\tc\ttypedef:type_enum\ntype_enum.yes\tinput.sv\t/^typedef enum           {no, yes} type_enum;$/;\"\tc\ttypedef:type_enum\ntype_enum_bit\tinput.sv\t/^typedef enum bit       {W, X}    type_enum_bit;$/;\"\tT\nW\tinput.sv\t/^typedef enum bit       {W, X}    type_enum_bit;$/;\"\tc\ttypedef:type_enum_bit\ntype_enum_bit.W\tinput.sv\t/^typedef enum bit       {W, X}    type_enum_bit;$/;\"\tc\ttypedef:type_enum_bit\nX\tinput.sv\t/^typedef enum bit       {W, X}    type_enum_bit;$/;\"\tc\ttypedef:type_enum_bit\ntype_enum_bit.X\tinput.sv\t/^typedef enum bit       {W, X}    type_enum_bit;$/;\"\tc\ttypedef:type_enum_bit\ntype_enum_bit2\tinput.sv\t/^typedef enum bit [1:0] {Y, Z}    type_enum_bit2;$/;\"\tT\nY\tinput.sv\t/^typedef enum bit [1:0] {Y, Z}    type_enum_bit2;$/;\"\tc\ttypedef:type_enum_bit2\ntype_enum_bit2.Y\tinput.sv\t/^typedef enum bit [1:0] {Y, Z}    type_enum_bit2;$/;\"\tc\ttypedef:type_enum_bit2\nZ\tinput.sv\t/^typedef enum bit [1:0] {Y, Z}    type_enum_bit2;$/;\"\tc\ttypedef:type_enum_bit2\ntype_enum_bit2.Z\tinput.sv\t/^typedef enum bit [1:0] {Y, Z}    type_enum_bit2;$/;\"\tc\ttypedef:type_enum_bit2\ntype_struct\tinput.sv\t/^  } type_struct;$/;\"\tT\nstruct_real\tinput.sv\t/^  real       struct_real;$/;\"\tw\ttypedef:type_struct\ntype_struct.struct_real\tinput.sv\t/^  real       struct_real;$/;\"\tw\ttypedef:type_struct\nstruct_bit\tinput.sv\t/^  bit  [1:0] struct_bit;$/;\"\tw\ttypedef:type_struct\ntype_struct.struct_bit\tinput.sv\t/^  bit  [1:0] struct_bit;$/;\"\tw\ttypedef:type_struct\ntype_union\tinput.sv\t/^  } type_union;$/;\"\tT\nunion_real\tinput.sv\t/^  real       union_real;$/;\"\tw\ttypedef:type_union\ntype_union.union_real\tinput.sv\t/^  real       union_real;$/;\"\tw\ttypedef:type_union\nunion_bit\tinput.sv\t/^  bit  [1:0] union_bit;$/;\"\tw\ttypedef:type_union\ntype_union.union_bit\tinput.sv\t/^  bit  [1:0] union_bit;$/;\"\tw\ttypedef:type_union\ntype_union_packed\tinput.sv\t/^  } type_union_packed;$/;\"\tT\nunion_bit1\tinput.sv\t/^  bit  [1:0] union_bit1;$/;\"\tw\ttypedef:type_union_packed\ntype_union_packed.union_bit1\tinput.sv\t/^  bit  [1:0] union_bit1;$/;\"\tw\ttypedef:type_union_packed\nunion_bit2\tinput.sv\t/^  bit  [1:0] union_bit2;$/;\"\tw\ttypedef:type_union_packed\ntype_union_packed.union_bit2\tinput.sv\t/^  bit  [1:0] union_bit2;$/;\"\tw\ttypedef:type_union_packed\ntype_union_tagged\tinput.sv\t/^  } type_union_tagged;$/;\"\tT\nInvalid\tinput.sv\t/^  void Invalid;$/;\"\tw\ttypedef:type_union_tagged\ntype_union_tagged.Invalid\tinput.sv\t/^  void Invalid;$/;\"\tw\ttypedef:type_union_tagged\nValid\tinput.sv\t/^  int Valid;$/;\"\tw\ttypedef:type_union_tagged\ntype_union_tagged.Valid\tinput.sv\t/^  int Valid;$/;\"\tw\ttypedef:type_union_tagged\ntype_struct_union\tinput.sv\t/^  } type_struct_union;$/;\"\tT\nstruct_real\tinput.sv\t/^  real       struct_real;$/;\"\tw\ttypedef:type_struct_union\ntype_struct_union.struct_real\tinput.sv\t/^  real       struct_real;$/;\"\tw\ttypedef:type_struct_union\nstruct_union\tinput.sv\t/^    } struct_union;$/;\"\tw\ttypedef:type_struct_union\ntype_struct_union.struct_union\tinput.sv\t/^    } struct_union;$/;\"\tw\ttypedef:type_struct_union\ntype_strcut_packed_unsigned\tinput.sv\t/^} type_strcut_packed_unsigned;$/;\"\tT\nupper\tinput.sv\t/^  logic [7:0] upper;$/;\"\tw\ttypedef:type_strcut_packed_unsigned\ntype_strcut_packed_unsigned.upper\tinput.sv\t/^  logic [7:0] upper;$/;\"\tw\ttypedef:type_strcut_packed_unsigned\nlower\tinput.sv\t/^  logic [7:0] lower;$/;\"\tw\ttypedef:type_strcut_packed_unsigned\ntype_strcut_packed_unsigned.lower\tinput.sv\t/^  logic [7:0] lower;$/;\"\tw\ttypedef:type_strcut_packed_unsigned\ntype_bit\tinput.sv\t/^typedef      bit                 type_bit;$/;\"\tT\ntype_bit_bus\tinput.sv\t/^typedef      bit [1:0]           type_bit_bus;$/;\"\tT\ntype_bit_bus_array\tinput.sv\t/^typedef      bit [1:0]           type_bit_bus_array [2:0];$/;\"\tT\ntype_logic_signed_vec\tinput.sv\t/^typedef      logic signed [7:0]  type_logic_signed_vec;$/;\"\tT\ntype_bit_unsigned_vec\tinput.sv\t/^typedef      bit unsigned [7:0]  type_bit_unsigned_vec;$/;\"\tT\ntype_int_unsigned\tinput.sv\t/^    } type_int_unsigned;$/;\"\tT\ncond0\tinput.sv\t/^    cond0 = 0, cond1 = 1, cond2 = 2$/;\"\tc\ttypedef:type_int_unsigned\ntype_int_unsigned.cond0\tinput.sv\t/^    cond0 = 0, cond1 = 1, cond2 = 2$/;\"\tc\ttypedef:type_int_unsigned\ncond1\tinput.sv\t/^    cond0 = 0, cond1 = 1, cond2 = 2$/;\"\tc\ttypedef:type_int_unsigned\ntype_int_unsigned.cond1\tinput.sv\t/^    cond0 = 0, cond1 = 1, cond2 = 2$/;\"\tc\ttypedef:type_int_unsigned\ncond2\tinput.sv\t/^    cond0 = 0, cond1 = 1, cond2 = 2$/;\"\tc\ttypedef:type_int_unsigned\ntype_int_unsigned.cond2\tinput.sv\t/^    cond0 = 0, cond1 = 1, cond2 = 2$/;\"\tc\ttypedef:type_int_unsigned\ntype_enum_bit_bus_defined_values\tinput.sv\t/^} type_enum_bit_bus_defined_values;$/;\"\tT\nA\tinput.sv\t/^    A = 2'b00,$/;\"\tc\ttypedef:type_enum_bit_bus_defined_values\ntype_enum_bit_bus_defined_values.A\tinput.sv\t/^    A = 2'b00,$/;\"\tc\ttypedef:type_enum_bit_bus_defined_values\nB\tinput.sv\t/^    B = 2'b01,$/;\"\tc\ttypedef:type_enum_bit_bus_defined_values\ntype_enum_bit_bus_defined_values.B\tinput.sv\t/^    B = 2'b01,$/;\"\tc\ttypedef:type_enum_bit_bus_defined_values\nC\tinput.sv\t/^    C = 2'b10,$/;\"\tc\ttypedef:type_enum_bit_bus_defined_values\ntype_enum_bit_bus_defined_values.C\tinput.sv\t/^    C = 2'b10,$/;\"\tc\ttypedef:type_enum_bit_bus_defined_values\nD\tinput.sv\t/^    D = {1'b1, 1'b1}$/;\"\tc\ttypedef:type_enum_bit_bus_defined_values\ntype_enum_bit_bus_defined_values.D\tinput.sv\t/^    D = {1'b1, 1'b1}$/;\"\tc\ttypedef:type_enum_bit_bus_defined_values\nfoo_t\tinput.sv\t/^typedef  bit [7:0]  foo_t ;$/;\"\tT\nbar_e\tinput.sv\t/^} bar_e;$/;\"\tT\nX\tinput.sv\t/^    X = 'h0000,$/;\"\tc\ttypedef:bar_e\nbar_e.X\tinput.sv\t/^    X = 'h0000,$/;\"\tc\ttypedef:bar_e\nY\tinput.sv\t/^    Y = 'h0001,$/;\"\tc\ttypedef:bar_e\nbar_e.Y\tinput.sv\t/^    Y = 'h0001,$/;\"\tc\ttypedef:bar_e\nZ\tinput.sv\t/^    Z = -1$/;\"\tc\ttypedef:bar_e\nbar_e.Z\tinput.sv\t/^    Z = -1$/;\"\tc\ttypedef:bar_e\ntype_class\tinput.sv\t/^typedef classname#(paramvalue) type_class;$/;\"\tT\nUVM_CORESERVICE_TYPE\tinput.sv\t/^`define UVM_CORESERVICE_TYPE uvm_default_coreservice_t$/;\"\td\n`UVM_CORESERVICE_TYPE\tinput.sv\t/^typedef class `UVM_CORESERVICE_TYPE;$/;\"\tQ\n"
  },
  {
    "path": "Units/parser-verilog.r/systemverilog-typedef.d/input.sv",
    "content": "typedef enum              fwd_type_enum;\ntypedef struct            fwd_type_struct;\ntypedef union             fwd_type_union;\ntypedef class             fwd_type_class;\ntypedef interface class   fwd_type_interface_class;\ntypedef                   fwd_type;\n\ntypedef enum           {no, yes} type_enum;\ntypedef enum bit       {W, X}    type_enum_bit;\ntypedef enum bit [1:0] {Y, Z}    type_enum_bit2;\n\ntypedef struct {\n  real       struct_real;\n  bit  [1:0] struct_bit;\n  } type_struct;\n\ntypedef union {\n  real       union_real;\n  bit  [1:0] union_bit;\n  } type_union;\n\ntypedef union packed {\n  bit  [1:0] union_bit1;\n  bit  [1:0] union_bit2;\n  } type_union_packed;\n\ntypedef union tagged {\n  void Invalid;\n  int Valid;\n  } type_union_tagged;\n\ntypedef struct {\n  real       struct_real;\n  union {\n    int i;\n    bit b;\n    } struct_union;\n  } type_struct_union;\n\ntypedef struct packed unsigned {\n  logic [7:0] upper;\n  logic [7:0] lower;\n} type_strcut_packed_unsigned;\n\ntypedef      bit                 type_bit;\ntypedef      bit [1:0]           type_bit_bus;\ntypedef      bit [1:0]           type_bit_bus_array [2:0];\ntypedef      logic signed [7:0]  type_logic_signed_vec;\ntypedef      bit unsigned [7:0]  type_bit_unsigned_vec;\n\ntypedef enum int unsigned{\n    cond0 = 0, cond1 = 1, cond2 = 2\n    } type_int_unsigned;\n\ntypedef enum bit [1:0] {\n    A = 2'b00,\n    B = 2'b01,\n    C = 2'b10,\n    D = {1'b1, 1'b1}\n} type_enum_bit_bus_defined_values;\n\n// enum with user defined type\ntypedef  bit [7:0]  foo_t ;\ntypedef enum foo_t {\n    X = 'h0000,\n    Y = 'h0001,\n    Z = -1\n} bar_e;\n\ntypedef classname#(paramvalue) type_class;\n\n// from UVM-1.2\n`define UVM_CORESERVICE_TYPE uvm_default_coreservice_t\ntypedef class `UVM_CORESERVICE_TYPE;\n// typedef class `UVM_CORESERVICE_TYPE(arg);\n"
  },
  {
    "path": "Units/parser-verilog.r/validator",
    "content": "svlint\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-2001.d/args.ctags",
    "content": "--extras=+q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-2001.d/expected.tags",
    "content": "DEFINE\tinput.v\t/^`define DEFINE$/;\"\td\nDEF_WITH_EQ\tinput.v\t/^`define DEF_WITH_EQ = 1'd100$/;\"\td\nDEF_VALUE\tinput.v\t/^`define DEF_VALUE   1'd100$/;\"\td\nmod\tinput.v\t/^module mod#($/;\"\tm\nPARAM1\tinput.v\t/^    parameter PARAM1 = 10,$/;\"\tc\tmodule:mod\nmod.PARAM1\tinput.v\t/^    parameter PARAM1 = 10,$/;\"\tc\tmodule:mod\nPARAM2\tinput.v\t/^    parameter PARAM2 = 2.0$/;\"\tc\tmodule:mod\nmod.PARAM2\tinput.v\t/^    parameter PARAM2 = 2.0$/;\"\tc\tmodule:mod\na\tinput.v\t/^    input wire a,$/;\"\tp\tmodule:mod\nmod.a\tinput.v\t/^    input wire a,$/;\"\tp\tmodule:mod\nb\tinput.v\t/^    b,c,$/;\"\tp\tmodule:mod\nmod.b\tinput.v\t/^    b,c,$/;\"\tp\tmodule:mod\nc\tinput.v\t/^    b,c,$/;\"\tp\tmodule:mod\nmod.c\tinput.v\t/^    b,c,$/;\"\tp\tmodule:mod\nd\tinput.v\t/^    d ,$/;\"\tp\tmodule:mod\nmod.d\tinput.v\t/^    d ,$/;\"\tp\tmodule:mod\ne\tinput.v\t/^    output wire e ,$/;\"\tp\tmodule:mod\nmod.e\tinput.v\t/^    output wire e ,$/;\"\tp\tmodule:mod\nf\tinput.v\t/^    output reg f,$/;\"\tp\tmodule:mod\nmod.f\tinput.v\t/^    output reg f,$/;\"\tp\tmodule:mod\ng\tinput.v\t/^    inout wire g$/;\"\tp\tmodule:mod\nmod.g\tinput.v\t/^    inout wire g$/;\"\tp\tmodule:mod\nLOCALPARAM\tinput.v\t/^localparam LOCALPARAM = 2**2;$/;\"\tc\tmodule:mod\nmod.LOCALPARAM\tinput.v\t/^localparam LOCALPARAM = 2**2;$/;\"\tc\tmodule:mod\nSTATE1\tinput.v\t/^localparam STATE1 = 4'h0,$/;\"\tc\tmodule:mod\nmod.STATE1\tinput.v\t/^localparam STATE1 = 4'h0,$/;\"\tc\tmodule:mod\nSTATE2\tinput.v\t/^           STATE2 = 4'h1,$/;\"\tc\tmodule:mod\nmod.STATE2\tinput.v\t/^           STATE2 = 4'h1,$/;\"\tc\tmodule:mod\nSTATE3\tinput.v\t/^           STATE3 = 4'h2,$/;\"\tc\tmodule:mod\nmod.STATE3\tinput.v\t/^           STATE3 = 4'h2,$/;\"\tc\tmodule:mod\nSTATE4\tinput.v\t/^           STATE4 = 4'h5    ,$/;\"\tc\tmodule:mod\nmod.STATE4\tinput.v\t/^           STATE4 = 4'h5    ,$/;\"\tc\tmodule:mod\nSTATE5\tinput.v\t/^           STATE5 = 4'h6    ,$/;\"\tc\tmodule:mod\nmod.STATE5\tinput.v\t/^           STATE5 = 4'h6    ,$/;\"\tc\tmodule:mod\nSTATE6\tinput.v\t/^           STATE6 = 4'h7    ,$/;\"\tc\tmodule:mod\nmod.STATE6\tinput.v\t/^           STATE6 = 4'h7    ,$/;\"\tc\tmodule:mod\nSTATE7\tinput.v\t/^           STATE7 = 4'h8;$/;\"\tc\tmodule:mod\nmod.STATE7\tinput.v\t/^           STATE7 = 4'h8;$/;\"\tc\tmodule:mod\nk\tinput.v\t/^real k;$/;\"\tr\tmodule:mod\nmod.k\tinput.v\t/^real k;$/;\"\tr\tmodule:mod\nl\tinput.v\t/^integer l;$/;\"\tr\tmodule:mod\nmod.l\tinput.v\t/^integer l;$/;\"\tr\tmodule:mod\nscounter\tinput.v\t/^reg signed [3:0] scounter;$/;\"\tr\tmodule:mod\nmod.scounter\tinput.v\t/^reg signed [3:0] scounter;$/;\"\tr\tmodule:mod\nadd\tinput.v\t/^task add ($/;\"\tt\tmodule:mod\nmod.add\tinput.v\t/^task add ($/;\"\tt\tmodule:mod\nx\tinput.v\t/^    input x, y,$/;\"\tp\ttask:mod.add\nmod.add.x\tinput.v\t/^    input x, y,$/;\"\tp\ttask:mod.add\ny\tinput.v\t/^    input x, y,$/;\"\tp\ttask:mod.add\nmod.add.y\tinput.v\t/^    input x, y,$/;\"\tp\ttask:mod.add\nz\tinput.v\t/^    output z$/;\"\tp\ttask:mod.add\nmod.add.z\tinput.v\t/^    output z$/;\"\tp\ttask:mod.add\nmult\tinput.v\t/^function integer mult ($/;\"\tf\tmodule:mod\nmod.mult\tinput.v\t/^function integer mult ($/;\"\tf\tmodule:mod\nx\tinput.v\t/^    input x,$/;\"\tp\tfunction:mod.mult\nmod.mult.x\tinput.v\t/^    input x,$/;\"\tp\tfunction:mod.mult\ny\tinput.v\t/^    input y);$/;\"\tp\tfunction:mod.mult\nmod.mult.y\tinput.v\t/^    input y);$/;\"\tp\tfunction:mod.mult\nfunc_with_range\tinput.v\t/^function [1:0] func_with_range (k, l);$/;\"\tf\tmodule:mod\nmod.func_with_range\tinput.v\t/^function [1:0] func_with_range (k, l);$/;\"\tf\tmodule:mod\nk\tinput.v\t/^function [1:0] func_with_range (k, l);$/;\"\tp\tfunction:mod.func_with_range\nmod.func_with_range.k\tinput.v\t/^function [1:0] func_with_range (k, l);$/;\"\tp\tfunction:mod.func_with_range\nl\tinput.v\t/^function [1:0] func_with_range (k, l);$/;\"\tp\tfunction:mod.func_with_range\nmod.func_with_range.l\tinput.v\t/^function [1:0] func_with_range (k, l);$/;\"\tp\tfunction:mod.func_with_range\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-2001.d/input.v",
    "content": "// Include module declaration in a comment\n// module wrong;\n// endmodule\n`define DEFINE\n`define DEF_WITH_EQ = 1'd100\n`define DEF_VALUE   1'd100\n\nmodule mod#(\n    parameter PARAM1 = 10,\n    parameter PARAM2 = 2.0\n) (\n    input wire a,\n    b,c,\n    d ,\n    output wire e ,\n    output reg f,\n    inout wire g\n);\n\nlocalparam LOCALPARAM = 2**2;\n\nlocalparam STATE1 = 4'h0,\n           STATE2 = 4'h1,\n           STATE3 = 4'h2,\n           STATE4 = 4'h5    ,\n           STATE5 = 4'h6    ,\n           STATE6 = 4'h7    ,\n           STATE7 = 4'h8;\n\nreal k;\ninteger l;\nreg signed [3:0] scounter;\n\ntask add (\n    input x, y,\n    output z\n);\n    z = x + y;\nendtask\n\nfunction integer mult (\n    input x,\n    input y);\n    mult = x * y;\nendfunction\n\nfunction [1:0] func_with_range (k, l);\n    func_with_range = {k, l};\nendfunction\n\nendmodule // mod\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-basic.d/args.ctags",
    "content": "--extras=+q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-basic.d/expected.tags",
    "content": "DEFINE\tinput.v\t/^`define DEFINE$/;\"\td\nDEF_WITH_EQ\tinput.v\t/^`define DEF_WITH_EQ = 1'd100$/;\"\td\nDEF_VALUE\tinput.v\t/^`define DEF_VALUE   1'd100$/;\"\td\nmod\tinput.v\t/^module mod ($/;\"\tm\nPARAM\tinput.v\t/^parameter PARAM = 1;$/;\"\tc\tmodule:mod\nmod.PARAM\tinput.v\t/^parameter PARAM = 1;$/;\"\tc\tmodule:mod\nSTATE1\tinput.v\t/^parameter STATE1 = 4'h0,$/;\"\tc\tmodule:mod\nmod.STATE1\tinput.v\t/^parameter STATE1 = 4'h0,$/;\"\tc\tmodule:mod\nSTATE2\tinput.v\t/^          STATE2 = 4'h1,$/;\"\tc\tmodule:mod\nmod.STATE2\tinput.v\t/^          STATE2 = 4'h1,$/;\"\tc\tmodule:mod\nSTATE3\tinput.v\t/^          STATE3 = 4'h2,$/;\"\tc\tmodule:mod\nmod.STATE3\tinput.v\t/^          STATE3 = 4'h2,$/;\"\tc\tmodule:mod\nSTATE4\tinput.v\t/^          STATE4 = 4'h5    ,$/;\"\tc\tmodule:mod\nmod.STATE4\tinput.v\t/^          STATE4 = 4'h5    ,$/;\"\tc\tmodule:mod\nSTATE5\tinput.v\t/^          STATE5 = 4'h6    ,$/;\"\tc\tmodule:mod\nmod.STATE5\tinput.v\t/^          STATE5 = 4'h6    ,$/;\"\tc\tmodule:mod\nSTATE6\tinput.v\t/^          STATE6 = 4'h7    ,$/;\"\tc\tmodule:mod\nmod.STATE6\tinput.v\t/^          STATE6 = 4'h7    ,$/;\"\tc\tmodule:mod\nSTATE7\tinput.v\t/^          STATE7 = 4'h8;$/;\"\tc\tmodule:mod\nmod.STATE7\tinput.v\t/^          STATE7 = 4'h8;$/;\"\tc\tmodule:mod\na\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\nmod.a\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\nb\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\nmod.b\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\nc\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\nmod.c\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\nd\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\nmod.d\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\ne\tinput.v\t/^output e;$/;\"\tp\tmodule:mod\nmod.e\tinput.v\t/^output e;$/;\"\tp\tmodule:mod\nf\tinput.v\t/^output f;$/;\"\tp\tmodule:mod\nmod.f\tinput.v\t/^output f;$/;\"\tp\tmodule:mod\ng\tinput.v\t/^inout g;$/;\"\tp\tmodule:mod\nmod.g\tinput.v\t/^inout g;$/;\"\tp\tmodule:mod\na\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nmod.a\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nb\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nmod.b\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nc\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nmod.c\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nd\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nmod.d\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\ne\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nmod.e\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nf\tinput.v\t/^reg f;$/;\"\tr\tmodule:mod\nmod.f\tinput.v\t/^reg f;$/;\"\tr\tmodule:mod\ng\tinput.v\t/^wire g;$/;\"\tn\tmodule:mod\nmod.g\tinput.v\t/^wire g;$/;\"\tn\tmodule:mod\nk\tinput.v\t/^real k;$/;\"\tr\tmodule:mod\nmod.k\tinput.v\t/^real k;$/;\"\tr\tmodule:mod\nl\tinput.v\t/^integer l;$/;\"\tr\tmodule:mod\nmod.l\tinput.v\t/^integer l;$/;\"\tr\tmodule:mod\nadd\tinput.v\t/^task add;$/;\"\tt\tmodule:mod\nmod.add\tinput.v\t/^task add;$/;\"\tt\tmodule:mod\nx\tinput.v\t/^    input x, y;$/;\"\tp\ttask:mod.add\nmod.add.x\tinput.v\t/^    input x, y;$/;\"\tp\ttask:mod.add\ny\tinput.v\t/^    input x, y;$/;\"\tp\ttask:mod.add\nmod.add.y\tinput.v\t/^    input x, y;$/;\"\tp\ttask:mod.add\nz\tinput.v\t/^    output z;$/;\"\tp\ttask:mod.add\nmod.add.z\tinput.v\t/^    output z;$/;\"\tp\ttask:mod.add\nmult\tinput.v\t/^function mult;$/;\"\tf\tmodule:mod\nmod.mult\tinput.v\t/^function mult;$/;\"\tf\tmodule:mod\nx\tinput.v\t/^    input x;$/;\"\tp\tfunction:mod.mult\nmod.mult.x\tinput.v\t/^    input x;$/;\"\tp\tfunction:mod.mult\ny\tinput.v\t/^    input y;$/;\"\tp\tfunction:mod.mult\nmod.mult.y\tinput.v\t/^    input y;$/;\"\tp\tfunction:mod.mult\nmynet\tinput.v\t/^wire [PARAM1-1:0] mynet;$/;\"\tn\tmodule:mod\nmod.mynet\tinput.v\t/^wire [PARAM1-1:0] mynet;$/;\"\tn\tmodule:mod\ngencnt\tinput.v\t/^genvar gencnt;$/;\"\tr\tmodule:mod\nmod.gencnt\tinput.v\t/^genvar gencnt;$/;\"\tr\tmodule:mod\narray\tinput.v\t/^    for (gencnt = 0; gencnt < PARAM1; gencnt = gencnt + 1) begin: array$/;\"\tb\tmodule:mod\nmod.array\tinput.v\t/^    for (gencnt = 0; gencnt < PARAM1; gencnt = gencnt + 1) begin: array$/;\"\tb\tmodule:mod\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-basic.d/input.v",
    "content": "// Include module declaration in a comment\n// module wrong;\n// endmodule\n`define DEFINE\n`define DEF_WITH_EQ = 1'd100\n`define DEF_VALUE   1'd100\n\nmodule mod (\n    a,\n    b,c,\n    d , e ,\n    `ifdef DEFINE\n    f,\n    `endif\n    g\n);\n\nparameter PARAM = 1;\n\nparameter STATE1 = 4'h0,\n          STATE2 = 4'h1,\n          STATE3 = 4'h2,\n          STATE4 = 4'h5    ,\n          STATE5 = 4'h6    ,\n          STATE6 = 4'h7    ,\n          STATE7 = 4'h8;\n\ninput a,b, c, d ;\noutput e;\noutput f;\ninout g;\n\nwire a,b,c,d,e;\nreg f;\nwire g;\nreal k;\ninteger l;\n\ntask add;\n    input x, y;\n    output z;\nbegin\n    z = x + y;\nend\nendtask\n\nfunction mult;\n    input x;\n    input y;\nbegin\n    mult = x * y;\nend\nendfunction\n\nwire [PARAM1-1:0] mynet;\n\ngenvar gencnt;\ngenerate\n    for (gencnt = 0; gencnt < PARAM1; gencnt = gencnt + 1) begin: array\n        assign mynet[gencnt] = 1'b0;\n    end\nendgenerate\n\nendmodule // mod\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-escaped-id.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-escaped-id.d/expected.tags",
    "content": "themodule#(x=42)\tinput.v\t/^module \\\\themodule#(x=42) ($/;\"\tm\nclk,rst,\tinput.v\t/^    input wire \\\\clk,rst, , \\\\d ,$/;\"\tp\tmodule:themodule#(x=42)\nd\tinput.v\t/^    input wire \\\\clk,rst, , \\\\d ,$/;\"\tp\tmodule:themodule#(x=42)\n1+1=2\tinput.v\t/^    output reg \\\\1+1=2$/;\"\tp\tmodule:themodule#(x=42)\n\\\\\tinput.v\t/^localparam \\\\\\\\ = 1;$/;\"\tc\tmodule:themodule#(x=42)\n\\\\\\\\\tinput.v\t/^localparam \\\\\\\\\\\\ = \\\\\\\\ ;$/;\"\tc\tmodule:themodule#(x=42)\nr\\\\n\tinput.v\t/^localparam \\\\r\\\\n = \\\\\\\\\\\\ ;$/;\"\tc\tmodule:themodule#(x=42)\n\\\\r\\\\n\tinput.v\t/^localparam \\\\\\\\r\\\\n = \\\\r\\\\n ;$/;\"\tc\tmodule:themodule#(x=42)\n\\\\\\\\r\\\\n\tinput.v\t/^localparam \\\\\\\\\\\\r\\\\n = \\\\\\\\r\\\\n ;$/;\"\tc\tmodule:themodule#(x=42)\nend\tinput.v\t/^always @(posedge \\\\clk,rst, ) begin : \\\\end$/;\"\tb\tmodule:themodule#(x=42)\n\\\\end\tinput.v\t/^    if (\\\\\\\\\\\\r\\\\n ) begin : \\\\\\\\end$/;\"\tb\tblock:themodule#(x=42).end\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-escaped-id.d/input.v",
    "content": "module \\themodule#(x=42) (\n    input wire \\clk,rst, , \\d ,\n    output reg \\1+1=2\n);\n\n//localparam \\ = 1;  // null identifier\nlocalparam \\\\ = 1;\nlocalparam \\\\\\ = \\\\ ;\nlocalparam \\r\\n = \\\\\\ ;\nlocalparam \\\\r\\n = \\r\\n ;\nlocalparam \\\\\\r\\n = \\\\r\\n ;\n\nalways @(posedge \\clk,rst, ) begin : \\end\n    if (\\\\\\r\\n ) begin : \\\\end\n        \\1+1=2 <= d;\n    end\nend\n\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-github624.d/args.ctags",
    "content": "--sort=no\n# The input is too short. selectVorVerilogByKeywords() doesn't work well.\n--language-force=Verilog\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-github624.d/expected.tags",
    "content": "function\tinput.v\t/^function::0$/;\"\tf\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-github624.d/input.v",
    "content": "function::0\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-github624.d/validator",
    "content": "NONE\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-instance.d/args.ctags",
    "content": "--extras=+q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-instance.d/expected.tags",
    "content": "foo\tinput.v\t/^module foo # (parameter$/;\"\tm\nPAR_A\tinput.v\t/^              PAR_A = 1,$/;\"\tc\tmodule:foo\nfoo.PAR_A\tinput.v\t/^              PAR_A = 1,$/;\"\tc\tmodule:foo\nPAR_B\tinput.v\t/^              PAR_B = 2$/;\"\tc\tmodule:foo\nfoo.PAR_B\tinput.v\t/^              PAR_B = 2$/;\"\tc\tmodule:foo\na\tinput.v\t/^   input a, b;$/;\"\tp\tmodule:foo\nfoo.a\tinput.v\t/^   input a, b;$/;\"\tp\tmodule:foo\nb\tinput.v\t/^   input a, b;$/;\"\tp\tmodule:foo\nfoo.b\tinput.v\t/^   input a, b;$/;\"\tp\tmodule:foo\ntop\tinput.v\t/^module top (\\/*AUTOARG*\\/$/;\"\tm\na\tinput.v\t/^   input                a;                      \\/\\/ To uut3 of foo.v$/;\"\tp\tmodule:top\ntop.a\tinput.v\t/^   input                a;                      \\/\\/ To uut3 of foo.v$/;\"\tp\tmodule:top\nb\tinput.v\t/^   input                b;                      \\/\\/ To uut3 of foo.v$/;\"\tp\tmodule:top\ntop.b\tinput.v\t/^   input                b;                      \\/\\/ To uut3 of foo.v$/;\"\tp\tmodule:top\nunused_pin\tinput.v\t/^   wire unused_pin;$/;\"\tn\tmodule:top\ntop.unused_pin\tinput.v\t/^   wire unused_pin;$/;\"\tn\tmodule:top\nuut1\tinput.v\t/^   foo uut1 ($/;\"\ti\tmodule:top\ttyperef:module:foo\ntop.uut1\tinput.v\t/^   foo uut1 ($/;\"\ti\tmodule:top\ttyperef:module:foo\nuut2\tinput.v\t/^     uut2 ($/;\"\ti\tmodule:top\ttyperef:module:foo\ntop.uut2\tinput.v\t/^     uut2 ($/;\"\ti\tmodule:top\ttyperef:module:foo\nuut3\tinput.v\t/^   foo uut3 (\\/*AUTOINST*\\/$/;\"\ti\tmodule:top\ttyperef:module:foo\ntop.uut3\tinput.v\t/^   foo uut3 (\\/*AUTOINST*\\/$/;\"\ti\tmodule:top\ttyperef:module:foo\nuut4\tinput.v\t/^   uut4 (\\/*AUTOINST*\\/$/;\"\ti\tmodule:top\ttyperef:module:foo\ntop.uut4\tinput.v\t/^   uut4 (\\/*AUTOINST*\\/$/;\"\ti\tmodule:top\ttyperef:module:foo\nuut5\tinput.v\t/^   uut5 (\\/*AUTOINST*\\/$/;\"\ti\tmodule:top\ttyperef:module:foo\ntop.uut5\tinput.v\t/^   uut5 (\\/*AUTOINST*\\/$/;\"\ti\tmodule:top\ttyperef:module:foo\nuut6\tinput.v\t/^   foo uut6 [10:0]();$/;\"\ti\tmodule:top\ttyperef:module:foo\ntop.uut6\tinput.v\t/^   foo uut6 [10:0]();$/;\"\ti\tmodule:top\ttyperef:module:foo\nuut7\tinput.v\t/^   foo uut7 [1:0][10:0]();$/;\"\ti\tmodule:top\ttyperef:module:foo\ntop.uut7\tinput.v\t/^   foo uut7 [1:0][10:0]();$/;\"\ti\tmodule:top\ttyperef:module:foo\nuut8\tinput.v\t/^   foo uut8 () ;$/;\"\ti\tmodule:top\ttyperef:module:foo\ntop.uut8\tinput.v\t/^   foo uut8 () ;$/;\"\ti\tmodule:top\ttyperef:module:foo\nfunc_foo\tinput.v\t/^   function void func_foo(int a);$/;\"\tf\tmodule:top\ntop.func_foo\tinput.v\t/^   function void func_foo(int a);$/;\"\tf\tmodule:top\na\tinput.v\t/^   function void func_foo(int a);$/;\"\tp\tfunction:top.func_foo\ntop.func_foo.a\tinput.v\t/^   function void func_foo(int a);$/;\"\tp\tfunction:top.func_foo\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-instance.d/input.v",
    "content": "// Include module declaration in a comment\n\nmodule foo # (parameter\n              PAR_A = 1,\n              PAR_B = 2\n              )\n   (/*AUTOARG*/\n   // Inputs\n   a, b\n   );\n   input a, b;\n\nendmodule: foo\n\nmodule top (/*AUTOARG*/\n   // Inputs\n   a, b\n   );\n   //begin: AUTOOUTPUTS\n   /*AUTOOUTPUT*/\n\n   //begin: AUTOINPUTS\n   /*AUTOINPUT*/\n   // Beginning of automatic inputs (from unused autoinst inputs)\n   input                a;                      // To uut3 of foo.v\n   input                b;                      // To uut3 of foo.v\n   // End of automatics\n\n   //begin: AUTOWIREs\n   /*AUTOWIRE*/\n\n   //begin: AUTOREGINPUTs\n   /*AUTOREGINPUT*/\n\n   //begin: AUTOREGs\n   /*AUTOREGINPUT*/\n\n   //begin: AUTOUNUSEDs\n   wire unused_pin;\n   assign unused_pin = |{\n                         /*AUTOUNUSED*/\n                         1'b0} ;\n\n   //begin: AUTOTIEOFFs\n   /*AUTOTIEOFF*/\n   foo uut1 (\n             // Inputs\n             a,\n             b),\n     uut2 (\n           .a (a),\n           .b (b));\n   foo uut3 (/*AUTOINST*/\n             // Inputs\n             .a                         (a),\n             .b                         (b))  ;\n   foo #(3, 4)\n   uut4 (/*AUTOINST*/\n             // Inputs\n             .a                         (a),\n             .b                         (b));\n   foo #(.PAR_A (5),\n         .PAR_B (6))\n   uut5 (/*AUTOINST*/\n         // Inputs\n         .a                         (a),\n         .b                         (b));\n   foo uut6 [10:0]();\n   foo uut7 [1:0][10:0]();\n   foo uut8 () ;\n\n   /*! Function Description\n    *\n    *  \\param <name> <description>\n    *\n    *  \\return <return value description>\n    */\n\n   function void func_foo(int a);\n\n   endfunction : func_foo\n\n\n\n\nendmodule: top\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-memleak.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-memleak.d/expected.tags",
    "content": "DEFINE\tinput.v\t/^`define DEFINE$/;\"\td\nmod\tinput.v\t/^module mod ($/;\"\tm\nPARAM\tinput.v\t/^parameter PARAM = 1;$/;\"\tc\tmodule:mod\na\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\nb\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\nc\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\nd\tinput.v\t/^input a,b, c, d ;$/;\"\tp\tmodule:mod\ne\tinput.v\t/^output e;$/;\"\tp\tmodule:mod\nf\tinput.v\t/^output f;$/;\"\tp\tmodule:mod\ng\tinput.v\t/^inout g;$/;\"\tp\tmodule:mod\na\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nb\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nc\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nd\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\ne\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:mod\nf\tinput.v\t/^reg f;$/;\"\tr\tmodule:mod\ng\tinput.v\t/^wire g;$/;\"\tn\tmodule:mod\nk\tinput.v\t/^real k;$/;\"\tr\tmodule:mod\nl\tinput.v\t/^integer l;$/;\"\tr\tmodule:mod\nadd\tinput.v\t/^task add;$/;\"\tt\tmodule:mod\nx\tinput.v\t/^    input x, y;$/;\"\tp\ttask:mod.add\ny\tinput.v\t/^    input x, y;$/;\"\tp\ttask:mod.add\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-memleak.d/input.v",
    "content": "// Include module declaration in a comment\n// module wrong;\n// endmodule\n`define DEFINE\n\nmodule mod (\n    a,\n    b,c,\n    d , e ,\n    f,\n    g\n);\n\nparameter PARAM = 1;\n\ninput a,b, c, d ;\noutput e;\noutput f;\ninout g;\n\nwire a,b,c,d,e;\nreg f;\nwire g;\nreal k;\ninteger l;\n\ntask add;\n    input x, y;\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-memleak.d/validator",
    "content": "NONE\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-module-ref.d/args.ctags",
    "content": "--sort=no\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-module-ref.d/expected.tags",
    "content": "test\tinput.v\t/^module test (\\/*AUTOARG*\\/);$/;\"\tm\troles:def\ni_a\tinput.v\t/^   input i_a, i_b;$/;\"\tp\tmodule:test\troles:def\ni_b\tinput.v\t/^   input i_a, i_b;$/;\"\tp\tmodule:test\troles:def\no_c\tinput.v\t/^   output o_c;$/;\"\tp\tmodule:test\troles:def\nint1\tinput.v\t/^   ref1 int1 ();$/;\"\ti\tmodule:test\ttyperef:module:ref1\troles:def\nref1\tinput.v\t/^   ref1 int1 ();$/;\"\tm\tmodule:test\troles:decl\nint2\tinput.v\t/^   ref1 int2 ();$/;\"\ti\tmodule:test\ttyperef:module:ref1\troles:def\nref1\tinput.v\t/^   ref1 int2 ();$/;\"\tm\tmodule:test\troles:decl\nint3\tinput.v\t/^   int3 ();$/;\"\ti\tmodule:test\ttyperef:module:ref3\troles:def\nref3\tinput.v\t/^   ref3 # (.A (aaa),$/;\"\tm\tmodule:test\troles:decl\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-module-ref.d/input.v",
    "content": "// Taken from #3469 submitted by @my2817\nmodule test (/*AUTOARG*/);\n   input i_a, i_b;\n   output o_c;\n\n   ref1 int1 ();\n   ref1 int2 ();\n   ref3 # (.A (aaa),\n           .B (bbb))\n   int3 ();\n\nendmodule // test\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-multiline-macro.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-multiline-macro.d/expected.tags",
    "content": "defvar_with_comment\tinput.sv\t/^`define defvar_with_comment \\\\$/;\"\td\ndefvar_without_comment\tinput.sv\t/^`define defvar_without_comment \\\\$/;\"\td\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-multiline-macro.d/input.sv",
    "content": "// from UVM-1.2\n`define defvar_with_comment \\\n  // comment in multi-line macro \\\n  logic foo;\n\n`define defvar_without_comment \\\n  logic foo;\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-nocontext.d/args.ctags",
    "content": "--extras=+q\n--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-nocontext.d/expected.tags",
    "content": "DEFINE\tinput.v\t/^`define DEFINE$/;\"\td\nDEF_WITH_EQ\tinput.v\t/^`define DEF_WITH_EQ = 1'd100$/;\"\td\nDEF_VALUE\tinput.v\t/^`define DEF_VALUE   1'd100$/;\"\td\nfoo\tinput.v\t/^module foo;$/;\"\tm\nPARAM\tinput.v\t/^parameter PARAM = 1;$/;\"\tc\tmodule:foo\nfoo.PARAM\tinput.v\t/^parameter PARAM = 1;$/;\"\tc\tmodule:foo\nLOCALPARAM\tinput.v\t/^localparam LOCALPARAM = 2**2;$/;\"\tc\tmodule:foo\nfoo.LOCALPARAM\tinput.v\t/^localparam LOCALPARAM = 2**2;$/;\"\tc\tmodule:foo\nSTATE1\tinput.v\t/^localparam STATE1 = 4'h0,$/;\"\tc\tmodule:foo\nfoo.STATE1\tinput.v\t/^localparam STATE1 = 4'h0,$/;\"\tc\tmodule:foo\nSTATE2\tinput.v\t/^           STATE2 = 4'h1,$/;\"\tc\tmodule:foo\nfoo.STATE2\tinput.v\t/^           STATE2 = 4'h1,$/;\"\tc\tmodule:foo\nSTATE3\tinput.v\t/^           STATE3 = 4'h2,$/;\"\tc\tmodule:foo\nfoo.STATE3\tinput.v\t/^           STATE3 = 4'h2,$/;\"\tc\tmodule:foo\nSTATE4\tinput.v\t/^           STATE4 = 4'h5    ,$/;\"\tc\tmodule:foo\nfoo.STATE4\tinput.v\t/^           STATE4 = 4'h5    ,$/;\"\tc\tmodule:foo\nSTATE5\tinput.v\t/^           STATE5 = 4'h6    ,$/;\"\tc\tmodule:foo\nfoo.STATE5\tinput.v\t/^           STATE5 = 4'h6    ,$/;\"\tc\tmodule:foo\nSTATE6\tinput.v\t/^           STATE6 = 4'h7    ,$/;\"\tc\tmodule:foo\nfoo.STATE6\tinput.v\t/^           STATE6 = 4'h7    ,$/;\"\tc\tmodule:foo\nSTATE7\tinput.v\t/^           STATE7 = 4'h8;$/;\"\tc\tmodule:foo\nfoo.STATE7\tinput.v\t/^           STATE7 = 4'h8;$/;\"\tc\tmodule:foo\na\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:foo\nfoo.a\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:foo\nb\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:foo\nfoo.b\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:foo\nc\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:foo\nfoo.c\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:foo\nd\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:foo\nfoo.d\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:foo\ne\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:foo\nfoo.e\tinput.v\t/^wire a,b,c,d,e;$/;\"\tn\tmodule:foo\nf\tinput.v\t/^reg f;$/;\"\tr\tmodule:foo\nfoo.f\tinput.v\t/^reg f;$/;\"\tr\tmodule:foo\ng\tinput.v\t/^wire g;$/;\"\tn\tmodule:foo\nfoo.g\tinput.v\t/^wire g;$/;\"\tn\tmodule:foo\nk\tinput.v\t/^real k;$/;\"\tr\tmodule:foo\nfoo.k\tinput.v\t/^real k;$/;\"\tr\tmodule:foo\nl\tinput.v\t/^integer l;$/;\"\tr\tmodule:foo\nfoo.l\tinput.v\t/^integer l;$/;\"\tr\tmodule:foo\nadd\tinput.v\t/^task add;$/;\"\tt\tmodule:foo\nfoo.add\tinput.v\t/^task add;$/;\"\tt\tmodule:foo\nx\tinput.v\t/^    input x, y;$/;\"\tp\ttask:foo.add\nfoo.add.x\tinput.v\t/^    input x, y;$/;\"\tp\ttask:foo.add\ny\tinput.v\t/^    input x, y;$/;\"\tp\ttask:foo.add\nfoo.add.y\tinput.v\t/^    input x, y;$/;\"\tp\ttask:foo.add\nz\tinput.v\t/^    output z;$/;\"\tp\ttask:foo.add\nfoo.add.z\tinput.v\t/^    output z;$/;\"\tp\ttask:foo.add\nmult\tinput.v\t/^function mult;$/;\"\tf\tmodule:foo\nfoo.mult\tinput.v\t/^function mult;$/;\"\tf\tmodule:foo\nx\tinput.v\t/^    input x;$/;\"\tp\tfunction:foo.mult\nfoo.mult.x\tinput.v\t/^    input x;$/;\"\tp\tfunction:foo.mult\ny\tinput.v\t/^    input y;$/;\"\tp\tfunction:foo.mult\nfoo.mult.y\tinput.v\t/^    input y;$/;\"\tp\tfunction:foo.mult\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-nocontext.d/input.v",
    "content": "// Include module declaration in a comment\n// module wrong;\n// endmodule\n`define DEFINE\n\n`define DEF_WITH_EQ = 1'd100\n`define DEF_VALUE   1'd100\n\nmodule foo;\nparameter PARAM = 1;\n\nlocalparam LOCALPARAM = 2**2;\n\nlocalparam STATE1 = 4'h0,\n           STATE2 = 4'h1,\n           STATE3 = 4'h2,\n           STATE4 = 4'h5    ,\n           STATE5 = 4'h6    ,\n           STATE6 = 4'h7    ,\n           STATE7 = 4'h8;\n\nwire a,b,c,d,e;\nreg f;\nwire g;\nreal k;\ninteger l;\n\ninitial begin\n    add(a, b, f);\nend\n\ntask add;\n    input x, y;\n    output z;\nbegin\n    z = x + y;\nend\nendtask\n\nfunction mult;\n    input x;\n    input y;\nbegin\n    mult = x * y;\nend\nendfunction\n\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug108_1.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug108_1.d/expected.tags",
    "content": "wahoo\tinput.v\t/^module wahoo ()$/;\"\tm\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug108_1.d/input.v",
    "content": "// File example.v\n//\n// Below is an example of a comment that is mis-parsed by exuberant ctags.\n// It uses the multi-line comment format, i.e. /* ... */ except that in\n// this case, the character sequence immediately preceding the closing\n// delimiter is an asterisk. (Any even number of asterisks would have the\n// same problem.\n// The line immediately afterwards is used to demonstrate the problem.\n// the module name 'wahoo' isn't recognised, because the parser mistakenly\n// thinks we are still in a multi-line comment.\n/*\n * I am a multi-line comment\n * I happen to end in a strange\n * (but legal) way: **/\nmodule wahoo ()\n;\nendmodule\n\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug108_2.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug108_2.d/expected.tags",
    "content": "top\tinput.v\t/^module top(outsig, insig);$/;\"\tm\noutsig\tinput.v\t/^output outsig;$/;\"\tp\tmodule:top\ninsig\tinput.v\t/^input insig;$/;\"\tp\tmodule:top\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug108_2.d/input.v",
    "content": "/*\n*\n**/\nmodule top(outsig, insig);\noutput outsig;\ninput insig;\nassign outsig = insig;\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug174.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug174.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug174.d/input.v",
    "content": "// somewhat contrived, but i came across a real-life file that caused this\n// crash.\nvalue=\nhello/\nworld;\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug73_1.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug73_1.d/expected.tags",
    "content": "N_84\tinput.v\t/^     wire N_84, N_83;     \\/\\/ is ok.$/;\"\tn\nN_83\tinput.v\t/^     wire N_84, N_83;     \\/\\/ is ok.$/;\"\tn\nN_84\tinput.v\t/^     wire N_84,$/;\"\tn\nN_83\tinput.v\t/^          N_83;     \\/\\/ then N_83 will be missing in tags.$/;\"\tn\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug73_1.d/input.v",
    "content": "/*\nBugs item #762027, was opened at 2003-06-27 18:32\nMessage generated for change (Tracker Item Submitted) made by Item Submitter\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=762027&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: cdic (cdic)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: multi-line definition w/o back-slash will be missing\n\nInitial Comment:\nThere is a small bug (language verilog):\n*/\n     wire N_84, N_83;     // is ok.\n  \n     wire N_84,\n          N_83;     // then N_83 will be missing in tags.\n/*\nThanks for fixing it.\n\ncdic\n*/\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug73_2.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug73_2.d/expected.tags",
    "content": "foo\tinput.v\t/^module foo;$/;\"\tm\nS0\tinput.v\t/^  S0 = 2'h0,$/;\"\tc\tmodule:foo\nS1\tinput.v\t/^  S1 = 2'h1,$/;\"\tc\tmodule:foo\nS2\tinput.v\t/^  S2 = 2'h2,$/;\"\tc\tmodule:foo\nS3\tinput.v\t/^  S3 = 2'h3;$/;\"\tc\tmodule:foo\nstate\tinput.v\t/^reg [1:0] \\/* synopsys enum state_info *\\/ state;$/;\"\tr\tmodule:foo\nnext_state\tinput.v\t/^reg [1:0] \\/* synopsys enum state_info *\\/ next_state;$/;\"\tr\tmodule:foo\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug73_2.d/input.v",
    "content": "// Taken from http://www.europa.com/~celiac/fsm_samp.html\n\nmodule foo;\n// These are the symbolic names for states\nparameter  [1:0]       //synopsys enum state_info\n  S0 = 2'h0,\n  S1 = 2'h1,\n  S2 = 2'h2,\n  S3 = 2'h3;\n\n// These are the current state and next state variables\nreg [1:0] /* synopsys enum state_info */ state;\nreg [1:0] /* synopsys enum state_info */ next_state;\n \n \n// synopsys state_vector state\n\nalways @ (state or y or x)\nbegin \n  next_state = state;\n  case (state)                 // synopsys full_case parallel_case\n    S0: begin \n      if (x) begin \n        next_state = S1;\n      end\n      else begin \n\n        next_state = S2;\n      end\n    end\n    S1: begin \n      if (y) begin \n        next_state = S2;\n      end\n      else begin \n        next_state = S0;\n      end\n    end\n    S2: begin \n      if (x & y) begin \n        next_state = S3;\n      end\n      else begin \n        next_state = S0;\n      end\n    end\n    S3: begin \n      next_state = S0;\n    end\n  endcase\nend\n\n\nalways @ (posedge clk or posedge reset)\nbegin \n  if (reset) begin \n    state <= S0;\n  end\n  else begin \n    state <= next_state;\n  end\nend\n\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug73_3.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug73_3.d/expected.tags",
    "content": "traffic\tinput.v\t/^module traffic;$/;\"\tm\non\tinput.v\t/^parameter on = 1, off = 0, red_tics = 35, $/;\"\tc\tmodule:traffic\noff\tinput.v\t/^parameter on = 1, off = 0, red_tics = 35, $/;\"\tc\tmodule:traffic\nred_tics\tinput.v\t/^parameter on = 1, off = 0, red_tics = 35, $/;\"\tc\tmodule:traffic\namber_tics\tinput.v\t/^          amber_tics = 3, green_tics = 20;$/;\"\tc\tmodule:traffic\ngreen_tics\tinput.v\t/^          amber_tics = 3, green_tics = 20;$/;\"\tc\tmodule:traffic\nclock\tinput.v\t/^reg clock, red, amber, green;$/;\"\tr\tmodule:traffic\nred\tinput.v\t/^reg clock, red, amber, green;$/;\"\tr\tmodule:traffic\namber\tinput.v\t/^reg clock, red, amber, green;$/;\"\tr\tmodule:traffic\ngreen\tinput.v\t/^reg clock, red, amber, green;$/;\"\tr\tmodule:traffic\nstop_at\tinput.v\t/^initial begin: stop_at$/;\"\tb\tmodule:traffic\nInit\tinput.v\t/^initial begin: Init$/;\"\tb\tmodule:traffic\nlight\tinput.v\t/^task light;$/;\"\tt\tmodule:traffic\ncolor\tinput.v\t/^   output color;$/;\"\tp\ttask:traffic.light\ntics\tinput.v\t/^   input [31:0] tics;$/;\"\tp\ttask:traffic.light\nclock_wave\tinput.v\t/^always begin: clock_wave$/;\"\tb\tmodule:traffic\nmain_process\tinput.v\t/^always begin: main_process$/;\"\tb\tmodule:traffic\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug73_3.d/input.v",
    "content": "// http://www.eg.bucknell.edu/~cs320/1995-fall/verilog-manual.html#RTFToC33\n\n// Digital model of a traffic light\n// By Dan Hyde August 10, 1995\nmodule traffic;\nparameter on = 1, off = 0, red_tics = 35, \n          amber_tics = 3, green_tics = 20;\nreg clock, red, amber, green;\n\n// will stop the simulation after 1000 time units\ninitial begin: stop_at\n   #1000; $stop;    \nend\n\n// initialize the lights and set up monitoring of registers\ninitial begin: Init\n    red = off; amber = off; green = off;\n    $display(\"                 Time green amber red\");  \n    $monitor(\"%3d    %b     %b    %b\", $time, green, amber, red);\nend\n\n// task to wait for 'tics' positive edge clocks\n// before turning light off\ntask light;\n   output color;\n   input [31:0] tics;\n   begin\n      repeat(tics)  // wait to detect tics positive edges on clock\n         @(posedge clock);\n      color = off;\n   end\nendtask\n\n// waveform for clock period of 2 time units\nalways begin: clock_wave\n  #1 clock = 0;\n  #1 clock = 1;\nend\n\nalways begin: main_process\n   red = on;\n   light(red, red_tics);  // call task to wait \n   green = on;\n   light(green, green_tics);\n   amber = on;\n   light(amber, amber_tics);\nend\n\nendmodule\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug98.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug98.d/expected.tags",
    "content": "pass_task_1\tinput.v\t/^task pass_task_1;$/;\"\tt\nfail_task_2\tinput.v\t/^task fail_task_2;$/;\"\tt\npass_func_1\tinput.v\t/^function pass_func_1;$/;\"\tf\nfail_func_2\tinput.v\t/^function fail_func_2;$/;\"\tf\npass_define_1\tinput.v\t/^`define pass_define_1 1'b1;$/;\"\td\nfail_define_2\tinput.v\t/^`define fail_define_2 1'b1;$/;\"\td\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug98.d/input.v",
    "content": "/**************************************************************************\n****\n* test task one\n* the line below has 53 asteriks\n*****************************************************/\ntask pass_task_1;\nbegin\nend\nendtask\n\n/**************************************************************************\n****\n* test task one\n* the line below has 54 asteriks\n******************************************************/\ntask fail_task_2;\nbegin\nend\nendtask\n\n/**************************************************************************\n****\n* test function one\n* the line below has 53 asteriks\n*****************************************************/\nfunction pass_func_1;\nbegin\nend\nendfunction\n\n/**************************************************************************\n****\n* test function two\n* the line below has 54 asteriks\n******************************************************/\nfunction fail_func_2;\nbegin\nend\nendfunction\n\n/**************************************************************************\n****\n* test function one\n* the line below has 53 asteriks\n*****************************************************/\n`define pass_define_1 1'b1;\n\n/**************************************************************************\n****\n* test function two\n* the line below has 54 asteriks\n******************************************************/\n`define fail_define_2 1'b1;\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug99.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug99.d/expected.tags",
    "content": "HOSTA\tinput.v\t/^`define HOSTA$/;\"\td\nHOSTB\tinput.v\t/^`define HOSTB$/;\"\td\nHOSTC\tinput.v\t/^`define HOSTC$/;\"\td\nHOSTD\tinput.v\t/^`define HOSTD$/;\"\td\nGUESTA\tinput.v\t/^`define GUESTA 1$/;\"\td\nGUESTB\tinput.v\t/^`define GUESTB 2$/;\"\td\nGUESTC\tinput.v\t/^`define GUESTC 3$/;\"\td\nGUESTD\tinput.v\t/^`define GUESTD 4$/;\"\td\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_bug99.d/input.v",
    "content": "/*\n * In Verilog, the following two lines are both valid syntax:\n *\n * `define GUEST\n * `define GUEST <value>\n *\n * The first defines \"GUEST\" as existing, but with no assigned \n * value.  The second defines \"GUEST\" as existing with an \n * assigned value.  Ctags55 correctly handles both cases, but \n * Ctags551 - Ctags554 only handles the `define with value \n * correctly.  Here is some test code to demonstrate this:\n */\n`define HOSTA\n`define HOSTB\n`define HOSTC\n`define HOSTD\n\n`define GUESTA 1\n`define GUESTB 2\n`define GUESTC 3\n`define GUESTD 4\n/*\n * Ctags55 correctly generates a tag for all `defines in the \n * code, but Ctags554 does not generate tags for \"HOSTB\" \n * or \"HOSTD\".\n */\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_patch57.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_patch57.d/expected.tags",
    "content": "ramaddr_0\tinput.v\t/^parameter ramaddr_0 = {1'b1,9'd0};$/;\"\tc\n"
  },
  {
    "path": "Units/parser-verilog.r/verilog-sf_patch57.d/input.v",
    "content": "parameter ramaddr_0 = {1'b1,9'd0};\n"
  },
  {
    "path": "Units/parser-vhdl.r/bug2374109.vhd.d/README",
    "content": "This one is inherited from e-ctags source tree.\nThe input looks broken;\n\n- the \"end\" sohuld be \"end Pow2\", and\n- the code in loop \"Result * N\" should be \"Result * i\".\n\nThe test case is kept as is. However, if you will work on improving\nVHDL parser, you may update this test case as you need.\n"
  },
  {
    "path": "Units/parser-vhdl.r/bug2374109.vhd.d/expected.tags",
    "content": "Pow2\tinput.vhd\t/^function Pow2( N, Exp : integer )  return mylib.myinteger is$/;\"\tf\nResult\tinput.vhd\t/^  Variable Result   : integer := 1;$/;\"\tv\tfunction:Pow2\n"
  },
  {
    "path": "Units/parser-vhdl.r/bug2374109.vhd.d/input.vhd",
    "content": "function Pow2( N, Exp : integer )  return mylib.myinteger is\n  Variable Result   : integer := 1;\n\nbegin\n  for i in 1 to Exp loop\n    Result := Result * N;\n  end loop;\n  return( Result );\nend Pow;\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-component.d/args.ctags",
    "content": "--sort=no\n--kinds-VHDL=+{local}{prototype}{component}\n--fields=+Kpre\n--extras=+r\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-component.d/expected.tags",
    "content": "ENTITY_TOP\tinput.vhd\t/^entity ENTITY_TOP is$/;\"\tentity\troles:def\tend:13\nGEN\tinput.vhd\t/^    GEN : integer := 0$/;\"\tgeneric\tentity:ENTITY_TOP\troles:def\nINP\tinput.vhd\t/^    INP : in std_logic$/;\"\tport\tentity:ENTITY_TOP\troles:def\narch\tinput.vhd\t/^architecture arch of ENTITY_TOP is$/;\"\tarchitecture\tentity:ENTITY_TOP\troles:def\tend:54\nENTITY_TOP\tinput.vhd\t/^architecture arch of ENTITY_TOP is$/;\"\tentity\troles:desigend\tarchitecture:arch\nsig\tinput.vhd\t/^  signal sig : std_logic := '0';$/;\"\tsignal\tarchitecture:ENTITY_TOP.arch\troles:def\nENTITY_1\tinput.vhd\t/^  component ENTITY_1$/;\"\tcomponent\tarchitecture:ENTITY_TOP.arch\troles:def\tend:25\nGEN\tinput.vhd\t/^      GEN : integer := 0$/;\"\tgeneric\tcomponent:ENTITY_TOP.arch.ENTITY_1\troles:def\nINP\tinput.vhd\t/^      INP : in std_logic$/;\"\tport\tcomponent:ENTITY_TOP.arch.ENTITY_1\troles:def\nENTITY_2\tinput.vhd\t/^  component ENTITY_2$/;\"\tcomponent\tarchitecture:ENTITY_TOP.arch\troles:def\tend:34\nGEN\tinput.vhd\t/^      GEN : integer := 0$/;\"\tgeneric\tcomponent:ENTITY_TOP.arch.ENTITY_2\troles:def\nINP\tinput.vhd\t/^      INP : in std_logic$/;\"\tport\tcomponent:ENTITY_TOP.arch.ENTITY_2\troles:def\nENTITY_1\tinput-0.vhd\t/^entity ENTITY_1 is$/;\"\tentity\troles:def\tend:13\nGEN\tinput-0.vhd\t/^    GEN : integer := 0$/;\"\tgeneric\tentity:ENTITY_1\troles:def\nINP\tinput-0.vhd\t/^    INP : in std_logic$/;\"\tport\tentity:ENTITY_1\troles:def\narch\tinput-0.vhd\t/^architecture arch of ENTITY_1 is$/;\"\tarchitecture\tentity:ENTITY_1\troles:def\tend:20\nENTITY_1\tinput-0.vhd\t/^architecture arch of ENTITY_1 is$/;\"\tentity\troles:desigend\tarchitecture:arch\nsig\tinput-0.vhd\t/^  signal sig : std_logic := '0';$/;\"\tsignal\tarchitecture:ENTITY_1.arch\troles:def\nENTITY_2\tinput-1.vhd\t/^entity ENTITY_2 is$/;\"\tentity\troles:def\tend:13\nGEN\tinput-1.vhd\t/^    GEN : integer := 0$/;\"\tgeneric\tentity:ENTITY_2\troles:def\nINP\tinput-1.vhd\t/^    INP : in std_logic$/;\"\tport\tentity:ENTITY_2\troles:def\narch\tinput-1.vhd\t/^architecture arch of ENTITY_2 is$/;\"\tarchitecture\tentity:ENTITY_2\troles:def\tend:20\nENTITY_2\tinput-1.vhd\t/^architecture arch of ENTITY_2 is$/;\"\tentity\troles:desigend\tarchitecture:arch\nsig\tinput-1.vhd\t/^  signal sig : std_logic := '0';$/;\"\tsignal\tarchitecture:ENTITY_2.arch\troles:def\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-component.d/input-0.vhd",
    "content": "-- Taken from a comment https://github.com/universal-ctags/ctags/issues/2678\n-- submitted by @pidgeon777\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity ENTITY_1 is\n  generic (\n    GEN : integer := 0\n  );\n  port (\n    INP : in std_logic\n  );\nend entity;\n\narchitecture arch of ENTITY_1 is\n\n  signal sig : std_logic := '0';\n\nbegin\nend architecture;\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-component.d/input-1.vhd",
    "content": "-- Taken from a comment https://github.com/universal-ctags/ctags/issues/2678\n-- submitted by @pidgeon777\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity ENTITY_2 is\n  generic (\n    GEN : integer := 0\n  );\n  port (\n    INP : in std_logic\n  );\nend entity;\n\narchitecture arch of ENTITY_2 is\n\n  signal sig : std_logic := '0';\n\nbegin\nend architecture;\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-component.d/input.vhd",
    "content": "-- Taken from a comment https://github.com/universal-ctags/ctags/issues/2678\n-- submitted by @pidgeon777\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity ENTITY_TOP is\n  generic (\n    GEN : integer := 0\n  );\n  port (\n    INP : in std_logic\n  );\nend entity;\n\narchitecture arch of ENTITY_TOP is\n  signal sig : std_logic := '0';\n\n  component ENTITY_1\n    generic (\n      GEN : integer := 0\n    );\n    port (\n      INP : in std_logic\n    );\n  end component;\n\n  component ENTITY_2\n    generic (\n      GEN : integer := 0\n    );\n    port (\n      INP : in std_logic\n    );\n  end component;\n\nbegin\n\n  ENTITY_1_i : ENTITY_1\n  generic map(\n    GEN => 0\n  )\n  port map(\n    INP => '0'\n  );\n\n  ENTITY_2_i : ENTITY_2\n  generic map(\n    GEN => 0\n  )\n  port map(\n    INP => '0'\n  );\n\nend architecture;\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-crash.d/README",
    "content": "This includes input files that crashed ctags processes.\nThe validity of the input files is not considered well.\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-crash.d/input.vhd",
    "content": "package body\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-local.d/args.ctags",
    "content": "--sort=no\n--kinds-VHDL=+{local}{prototype}\n--fields=+Kpe\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-local.d/expected.tags",
    "content": "types_util\tinput.vhd\t/^package types_util is$/;\"\tpackage\tend:30\nstrlen\tinput.vhd\t/^function strlen(s: in string) return integer;$/;\"\tprototype\tpackage:types_util\nStringToUVector\tinput.vhd\t/^function StringToUVector(inStr: string) return std_ulogic_vector;$/;\"\tprototype\tpackage:types_util\nStringToSVector\tinput.vhd\t/^function StringToSVector(inStr: string) return std_logic_vector;$/;\"\tprototype\tpackage:types_util\nUnsignedToSigned\tinput.vhd\t/^function UnsignedToSigned(inUnsigned: std_ulogic_vector) return std_logic_vector;$/;\"\tprototype\tpackage:types_util\nSignalFromString\tinput.vhd\t/^function SignalFromString(inStr: string; ind : integer ) return std_logic;$/;\"\tprototype\tpackage:types_util\nSymbolToSVector\tinput.vhd\t/^function SymbolToSVector(inStr: string; idx: integer) return std_logic_vector;$/;\"\tprototype\tpackage:types_util\ntost\tinput.vhd\t/^function tost(v:std_logic_vector) return string;$/;\"\tprototype\tpackage:types_util\ntost\tinput.vhd\t/^function tost(v:std_logic) return string;$/;\"\tprototype\tpackage:types_util\ntost\tinput.vhd\t/^function tost(i : integer) return string;$/;\"\tprototype\tpackage:types_util\nprint\tinput.vhd\t/^procedure print(s : string);$/;\"\tprototype\tpackage:types_util\ntypes_util\tinput.vhd\t/^package body types_util is$/;\"\tpackage\tend:203\nstrlen\tinput.vhd\t/^  function strlen(s: in string) return integer is$/;\"\tfunction\tpackage:types_util\tend:44\nn\tinput.vhd\t/^    variable n: integer:=0; variable sj: integer:=s'left;$/;\"\tvariable\tfunction:types_util.strlen\nsj\tinput.vhd\t/^    variable n: integer:=0; variable sj: integer:=s'left;$/;\"\tvariable\tfunction:types_util.strlen\nSignalFromString\tinput.vhd\t/^  function SignalFromString(inStr: string; ind : integer ) return std_logic is$/;\"\tfunction\tpackage:types_util\tend:53\ntemp\tinput.vhd\t/^    variable temp: std_logic := 'X';$/;\"\tvariable\tfunction:types_util.SignalFromString\nStringToUVector\tinput.vhd\t/^  function StringToUVector(inStr: string) return std_ulogic_vector is$/;\"\tfunction\tpackage:types_util\tend:65\ntemp\tinput.vhd\t/^    variable temp: std_ulogic_vector(inStr'range) := (others => 'X');$/;\"\tvariable\tfunction:types_util.StringToUVector\nStringToSVector\tinput.vhd\t/^  function StringToSVector(inStr: string) return std_logic_vector is$/;\"\tfunction\tpackage:types_util\tend:77\ntemp\tinput.vhd\t/^    variable temp: std_logic_vector(inStr'range) := (others => 'X');$/;\"\tvariable\tfunction:types_util.StringToSVector\nSymbolToSVector\tinput.vhd\t/^  function SymbolToSVector(inStr: string; idx: integer) return std_logic_vector is$/;\"\tfunction\tpackage:types_util\tend:89\nss\tinput.vhd\t/^    constant ss: string(1 to inStr'length) := inStr;$/;\"\tlocal\tfunction:types_util.SymbolToSVector\nc\tinput.vhd\t/^    variable c : integer;$/;\"\tvariable\tfunction:types_util.SymbolToSVector\ntemp\tinput.vhd\t/^    variable temp: std_logic_vector(7 downto 0) := (others => 'X');$/;\"\tvariable\tfunction:types_util.SymbolToSVector\nUnsignedToSigned\tinput.vhd\t/^  function UnsignedToSigned(inUnsigned: std_ulogic_vector) $/;\"\tfunction\tpackage:types_util\tend:104\ntemp\tinput.vhd\t/^    variable temp: std_logic_vector(inUnsigned'length-1 downto 0) := (others => 'X');$/;\"\tvariable\tfunction:types_util.UnsignedToSigned\ni\tinput.vhd\t/^    variable i: integer:=0;$/;\"\tvariable\tfunction:types_util.UnsignedToSigned\nnibble\tinput.vhd\t/^  subtype nibble is std_logic_vector(3 downto 0);$/;\"\tsubtype\tpackage:types_util\ntodec\tinput.vhd\t/^  function todec(i:integer) return character is$/;\"\tfunction\tpackage:types_util\tend:124\ntohex\tinput.vhd\t/^  function tohex(n:nibble) return character is$/;\"\tfunction\tpackage:types_util\tend:148\ntost\tinput.vhd\t/^  function tost(v:std_logic_vector) return string is$/;\"\tfunction\tpackage:types_util\tend:170\nvlen\tinput.vhd\t/^    constant vlen : natural := v'length; --'$/;\"\tlocal\tfunction:types_util.tost\nslen\tinput.vhd\t/^    constant slen : natural := (vlen+3)\\/4;$/;\"\tlocal\tfunction:types_util.tost\nvv\tinput.vhd\t/^    variable vv : std_logic_vector(0 to slen*4-1) := (others => '0');$/;\"\tvariable\tfunction:types_util.tost\ns\tinput.vhd\t/^    variable s : string(1 to slen);$/;\"\tvariable\tfunction:types_util.tost\nnz\tinput.vhd\t/^    variable nz : boolean := false;$/;\"\tvariable\tfunction:types_util.tost\nindex\tinput.vhd\t/^    variable index : integer := -1;$/;\"\tvariable\tfunction:types_util.tost\ntost\tinput.vhd\t/^  function tost(v:std_logic) return string is$/;\"\tfunction\tpackage:types_util\tend:176\ntost\tinput.vhd\t/^  function tost(i : integer) return string is$/;\"\tfunction\tpackage:types_util\tend:195\nL\tinput.vhd\t/^    variable L : line;$/;\"\tvariable\tfunction:types_util.tost\ns\tinput.vhd\t/^    variable s, x : string(1 to 128);$/;\"\tvariable\tfunction:types_util.tost\nx\tinput.vhd\t/^    variable s, x : string(1 to 128);$/;\"\tvariable\tfunction:types_util.tost\nn\tinput.vhd\t/^    variable n, tmp : integer := 0;$/;\"\tvariable\tfunction:types_util.tost\ntmp\tinput.vhd\t/^    variable n, tmp : integer := 0;$/;\"\tvariable\tfunction:types_util.tost\nprint\tinput.vhd\t/^  procedure print(s : string) is$/;\"\tprocedure\tpackage:types_util\tend:201\nL\tinput.vhd\t/^    variable L : line;$/;\"\tvariable\tprocedure:types_util.print\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-local.d/input.vhd",
    "content": "--\n-- Taken from rtl/commonlib/types_util.vhd of https://github.com/sergeykhbr/riscv_vhdl\n--\n-----------------------------------------------------------------------------\n--! @file\n--! @copyright Copyright 2015 GNSS Sensor Ltd. All right reserved.\n--! @author    Sergey Khabarov - sergeykhbr@gmail.com\n--! @brief\t    Package for common testbenches implementation.\n------------------------------------------------------------------------------\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\nlibrary std;\nuse std.textio.all;\n\npackage types_util is\n\nfunction strlen(s: in string) return integer;\nfunction StringToUVector(inStr: string) return std_ulogic_vector;\nfunction StringToSVector(inStr: string) return std_logic_vector;\nfunction UnsignedToSigned(inUnsigned: std_ulogic_vector) return std_logic_vector;\nfunction SignalFromString(inStr: string; ind : integer ) return std_logic;\nfunction SymbolToSVector(inStr: string; idx: integer) return std_logic_vector;\n\nfunction tost(v:std_logic_vector) return string;\nfunction tost(v:std_logic) return string;\nfunction tost(i : integer) return string;\nprocedure print(s : string);\n\nend;\n\npackage body types_util is\n\n  function strlen(s: in string) return integer is\n    variable n: integer:=0; variable sj: integer:=s'left;\n  begin\n    loop\n      if    sj>s'right then exit;\n      elsif s(sj)=NUL  then exit; --sequential if protects sj > length\n      else                  sj:=sj+1; n:=n+1;\n      end if;\n    end loop;\n    return n;\n  end strlen;\n\n  function SignalFromString(inStr: string; ind : integer ) return std_logic is\n    variable temp: std_logic := 'X';\n  begin\n    if(inStr(inStr'high-ind)='1')    then temp := '1';\n    elsif(inStr(inStr'high-ind)='0') then temp := '0';\n    end if;\n    return temp;\n  end function SignalFromString;\n\n\n  function StringToUVector(inStr: string) return std_ulogic_vector is\n    variable temp: std_ulogic_vector(inStr'range) := (others => 'X');\n  begin\n    for i in inStr'range loop --\n      if(inStr(inStr'high-i+1)='1')    then temp(i) := '1';\n      elsif(inStr(inStr'high-i+1)='0') then temp(i) := '0';\n      end if;\n    end loop;\n    return temp(inStr'high downto 1);\n  end function StringToUVector;\n  -- conversion function\n  \n  function StringToSVector(inStr: string) return std_logic_vector is\n    variable temp: std_logic_vector(inStr'range) := (others => 'X');\n  begin\n    for i in inStr'range loop --\n      if(inStr(inStr'high-i+1)='1')    then temp(i) := '1';\n      elsif(inStr(inStr'high-i+1)='0') then temp(i) := '0';\n      end if;\n    end loop;\n    return temp(inStr'high downto 1);\n  end function StringToSVector;\n\n  function SymbolToSVector(inStr: string; idx: integer) return std_logic_vector is\n    constant ss: string(1 to inStr'length) := inStr;\n    variable c : integer;\n    variable temp: std_logic_vector(7 downto 0) := (others => 'X');\n  begin\n    c := character'pos(ss(idx+1));\n    for i in 0 to 7 loop --\n      temp(i) := to_unsigned(c,8)(i);\n    end loop;\n    return temp;\n  end function SymbolToSVector;\n  \n\n  function UnsignedToSigned(inUnsigned: std_ulogic_vector) \n    return std_logic_vector is\n    variable temp: std_logic_vector(inUnsigned'length-1 downto 0) := (others => 'X');\n    variable i: integer:=0;\n  begin\n    while i < inUnsigned'length loop\n      if(inUnsigned(i)='1')    then temp(i) := '1';\n      elsif(inUnsigned(i)='0') then temp(i) := '0';\n      end if;\n      i := i+1;\n    end loop;\n    return temp;\n  end function UnsignedToSigned;\n\n\n  subtype nibble is std_logic_vector(3 downto 0);\n\n  function todec(i:integer) return character is\n  begin\n    case i is\n    when 0 => return('0');\n    when 1 => return('1');\n    when 2 => return('2');\n    when 3 => return('3');\n    when 4 => return('4');\n    when 5 => return('5');\n    when 6 => return('6');\n    when 7 => return('7');\n    when 8 => return('8');\n    when 9 => return('9');\n    when others => return('0');\n    end case;\n  end;\n\n\n  function tohex(n:nibble) return character is\n  begin\n    case n is\n    when \"0000\" => return('0');\n    when \"0001\" => return('1');\n    when \"0010\" => return('2');\n    when \"0011\" => return('3');\n    when \"0100\" => return('4');\n    when \"0101\" => return('5');\n    when \"0110\" => return('6');\n    when \"0111\" => return('7');\n    when \"1000\" => return('8');\n    when \"1001\" => return('9');\n    when \"1010\" => return('a');\n    when \"1011\" => return('b');\n    when \"1100\" => return('c');\n    when \"1101\" => return('d');\n    when \"1110\" => return('e');\n    when \"1111\" => return('f');\n    when others => return('X');\n    end case;\n  end;\n\n\n  function tost(v:std_logic_vector) return string is\n    constant vlen : natural := v'length; --'\n    constant slen : natural := (vlen+3)/4;\n    variable vv : std_logic_vector(0 to slen*4-1) := (others => '0');\n    variable s : string(1 to slen);\n    variable nz : boolean := false;\n    variable index : integer := -1;\n  begin\n    vv(slen*4-vlen to slen*4-1) := v;\n    for i in 0 to slen-1 loop\n      if (vv(i*4 to i*4+3) = \"0000\") and nz and (i /= (slen-1)) then\n        index := i;\n      else\n        nz := false;\n        s(i+1) := tohex(vv(i*4 to i*4+3));\n      end if;\n    end loop;\n    if ((index +2) = slen) then return(s(slen to slen));\n    else return(string'(\"0x\") & s(index+2 to slen)); end if; --'\n  end;\n\n\n  function tost(v:std_logic) return string is\n  begin\n    if to_x01(v) = '1' then return(\"1\"); else return(\"0\"); end if;\n  end;\n\n\n  function tost(i : integer) return string is\n    variable L : line;\n    variable s, x : string(1 to 128);\n    variable n, tmp : integer := 0;\n  begin\n    tmp := i;\n    if i < 0 then tmp := -i; end if;\n    loop\n      s(128-n) := todec(tmp mod 10);\n      tmp := tmp / 10;\n      n := n+1;\n      if tmp = 0 then exit; end if;\n    end loop;\n    x(1 to n) := s(129-n to 128);\n    if i < 0 then return \"-\" & x(1 to n); end if;\n    return(x(1 to n));\n  end;\n\n  procedure print(s : string) is\n    variable L : line;\n  begin\n    L := new string'(s); writeline(output, L);\n  end;\n\nend;\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-port.d/args.ctags",
    "content": "--sort=no\n--kinds-VHDL=+{port}{component}\n--fields=+e\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-port.d/expected.tags",
    "content": "logical_ops_1\tinput.vhd\t/^entity logical_ops_1 is$/;\"\te\tend:5\na\tinput.vhd\t/^  port (a, b, c, d: in bit;$/;\"\tq\tentity:logical_ops_1\nb\tinput.vhd\t/^  port (a, b, c, d: in bit;$/;\"\tq\tentity:logical_ops_1\nc\tinput.vhd\t/^  port (a, b, c, d: in bit;$/;\"\tq\tentity:logical_ops_1\nd\tinput.vhd\t/^  port (a, b, c, d: in bit;$/;\"\tq\tentity:logical_ops_1\nm\tinput.vhd\t/^        m: out bit);$/;\"\tq\tentity:logical_ops_1\nENTITY_A\tinput-0.vhd\t/^entity ENTITY_A is$/;\"\te\tend:10\nGENERIC_C\tinput-0.vhd\t/^    GENERIC_C : integer := value;$/;\"\tg\tentity:ENTITY_A\nPORT_C\tinput-0.vhd\t/^    PORT_C : in std_logic$/;\"\tq\tentity:ENTITY_A\nENTITY_B\tinput-0.vhd\t/^entity ENTITY_B is$/;\"\te\tend:19\nGENERIC_C\tinput-0.vhd\t/^    GENERIC_C : integer := value;$/;\"\tg\tentity:ENTITY_B\nPORT_C\tinput-0.vhd\t/^    PORT_C : in std_logic$/;\"\tq\tentity:ENTITY_B\nCOMPONENT_A\tinput-1.vhd\t/^component COMPONENT_A is$/;\"\tC\tend:10\nGENERIC_C\tinput-1.vhd\t/^    GENERIC_C : integer := value;$/;\"\tg\tcomponent:COMPONENT_A\nPORT_C\tinput-1.vhd\t/^    PORT_C : in std_logic$/;\"\tq\tcomponent:COMPONENT_A\nCOMPONENT_B\tinput-1.vhd\t/^component COMPONENT_B is$/;\"\tC\tend:19\nGENERIC_C\tinput-1.vhd\t/^    GENERIC_C : integer := value;$/;\"\tg\tcomponent:COMPONENT_B\nPORT_C\tinput-1.vhd\t/^    PORT_C : in std_logic$/;\"\tq\tcomponent:COMPONENT_B\nCOMPONENT_C\tinput-1.vhd\t/^component COMPONENT_C is$/;\"\tC\tend:28\nGENERIC_C\tinput-1.vhd\t/^    GENERIC_C : integer := value;$/;\"\tg\tcomponent:COMPONENT_C\nPORT_C\tinput-1.vhd\t/^    PORT_C : in std_logic$/;\"\tq\tcomponent:COMPONENT_C\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-port.d/input-0.vhd",
    "content": "-- Taken from https://github.com/universal-ctags/ctags/issues/2678\n-- commented by @pidgeon777.\nentity ENTITY_A is\n  generic (\n    GENERIC_C : integer := value;\n  );\n  port (\n    PORT_C : in std_logic\n  );\nend entity;\n\nentity ENTITY_B is\n  generic (\n    GENERIC_C : integer := value;\n  );\n  port (\n    PORT_C : in std_logic\n  );\nend entity;\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-port.d/input-1.vhd",
    "content": "-- Taken from https://github.com/universal-ctags/ctags/issues/2678\n-- commented by @pidgeon777.\ncomponent COMPONENT_A is\n  generic (\n    GENERIC_C : integer := value;\n  );\n  port (\n    PORT_C : in std_logic\n  );\nend component;\n\ncomponent COMPONENT_B is\n  generic (\n    GENERIC_C : integer := value;\n  );\n  port (\n    PORT_C : in std_logic\n  );\nend component COMPONENT_B;\n\ncomponent COMPONENT_C is\n  generic (\n    GENERIC_C : integer := value;\n  );\n  port (\n    PORT_C : in std_logic\n  );\nend component;\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-port.d/input.vhd",
    "content": "-- https://www.ics.uci.edu/~jmoorkan/vhdlref/Synario%20VHDL%20Manual.pdf\nentity logical_ops_1 is\n  port (a, b, c, d: in bit;\n        m: out bit);\nend logical_ops_1;\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-process.d/args.ctags",
    "content": "--sort=no\n--fields=+E\n--fields=+Kpre\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-process.d/expected.tags",
    "content": "StackTraceBuffer\tinput.vhd\t/^entity StackTraceBuffer is $/;\"\tentity\troles:def\tend:29\nabits\tinput.vhd\t/^    abits : integer := 5;$/;\"\tgeneric\tentity:StackTraceBuffer\troles:def\ndbits\tinput.vhd\t/^    dbits : integer := 64$/;\"\tgeneric\tentity:StackTraceBuffer\troles:def\ni_clk\tinput.vhd\t/^    i_clk   : in std_logic;$/;\"\tport\tentity:StackTraceBuffer\troles:def\ni_raddr\tinput.vhd\t/^    i_raddr : in std_logic_vector(abits-1 downto 0);$/;\"\tport\tentity:StackTraceBuffer\troles:def\no_rdata\tinput.vhd\t/^    o_rdata : out std_logic_vector(dbits-1 downto 0);$/;\"\tport\tentity:StackTraceBuffer\troles:def\ni_we\tinput.vhd\t/^    i_we    : in std_logic;$/;\"\tport\tentity:StackTraceBuffer\troles:def\ni_waddr\tinput.vhd\t/^    i_waddr : in std_logic_vector(abits-1 downto 0);$/;\"\tport\tentity:StackTraceBuffer\troles:def\ni_wdata\tinput.vhd\t/^    i_wdata : in std_logic_vector(dbits-1 downto 0)$/;\"\tport\tentity:StackTraceBuffer\troles:def\narch_StackTraceBuffer\tinput.vhd\t/^architecture arch_StackTraceBuffer of StackTraceBuffer is$/;\"\tarchitecture\tentity:StackTraceBuffer\troles:def\tend:51\nram_type\tinput.vhd\t/^  type ram_type is array ((2**abits)-1 downto 0) of std_logic_vector (dbits-1 downto 0);$/;\"\ttype\tarchitecture:StackTraceBuffer.arch_StackTraceBuffer\troles:def\nstackbuf\tinput.vhd\t/^  signal stackbuf    : ram_type;$/;\"\tsignal\tarchitecture:StackTraceBuffer.arch_StackTraceBuffer\troles:def\nraddr\tinput.vhd\t/^  signal raddr       : std_logic_vector(abits-1 downto 0);$/;\"\tsignal\tarchitecture:StackTraceBuffer.arch_StackTraceBuffer\troles:def\nregs\tinput.vhd\t/^  regs : process(i_clk) begin $/;\"\tprocess\tarchitecture:StackTraceBuffer.arch_StackTraceBuffer\troles:def\tend:47\nStackTraceBuffer0\tinput-0.vhd\t/^entity StackTraceBuffer0 is $/;\"\tentity\troles:def\tend:30\nabits0\tinput-0.vhd\t/^    abits0 : integer := 5;$/;\"\tgeneric\tentity:StackTraceBuffer0\troles:def\ndbits0\tinput-0.vhd\t/^    dbits0 : integer := 64$/;\"\tgeneric\tentity:StackTraceBuffer0\troles:def\ni_clk0\tinput-0.vhd\t/^    i_clk0   : in std_logic;$/;\"\tport\tentity:StackTraceBuffer0\troles:def\ni_raddr0\tinput-0.vhd\t/^    i_raddr0 : in std_logic_vector(abits0-1 downto 0);$/;\"\tport\tentity:StackTraceBuffer0\troles:def\no_rdata0\tinput-0.vhd\t/^    o_rdata0 : out std_logic_vector(dbits0-1 downto 0);$/;\"\tport\tentity:StackTraceBuffer0\troles:def\ni_we0\tinput-0.vhd\t/^    i_we0    : in std_logic;$/;\"\tport\tentity:StackTraceBuffer0\troles:def\ni_waddr0\tinput-0.vhd\t/^    i_waddr0 : in std_logic_vector(abits0-1 downto 0);$/;\"\tport\tentity:StackTraceBuffer0\troles:def\ni_wdata0\tinput-0.vhd\t/^    i_wdata0 : in std_logic_vector(dbits0-1 downto 0)$/;\"\tport\tentity:StackTraceBuffer0\troles:def\narch_StackTraceBuffer0\tinput-0.vhd\t/^architecture arch_StackTraceBuffer0 of StackTraceBuffer0 is$/;\"\tarchitecture\tentity:StackTraceBuffer0\troles:def\tend:52\nram_type0\tinput-0.vhd\t/^  type ram_type0 is array ((2**abits0)-1 downto 0) of std_logic_vector (dbits0-1 downto 0);$/;\"\ttype\tarchitecture:StackTraceBuffer0.arch_StackTraceBuffer0\troles:def\nstackbuf0\tinput-0.vhd\t/^  signal stackbuf0    : ram_type0;$/;\"\tsignal\tarchitecture:StackTraceBuffer0.arch_StackTraceBuffer0\troles:def\nraddr0\tinput-0.vhd\t/^  signal raddr0       : std_logic_vector(abits0-1 downto 0);$/;\"\tsignal\tarchitecture:StackTraceBuffer0.arch_StackTraceBuffer0\troles:def\nanonProcess21a9f813010f\tinput-0.vhd\t/^  process(i_clk0) begin $/;\"\tprocess\tarchitecture:StackTraceBuffer0.arch_StackTraceBuffer0\troles:def\textras:anonymous\tend:48\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-process.d/input-0.vhd",
    "content": "--\n-- Taken from rtl/riverlib/core/stacktrbuf.vhd of https://github.com/sergeykhbr/riscv_vhdl\n-- with modifications.\n--\n-----------------------------------------------------------------------------\n--! @file\n--! @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved.\n--! @author    Sergey Khabarov - sergeykhbr@gmail.com\n--! @brief     Stack trace buffer on hardware level.\n------------------------------------------------------------------------------\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nlibrary commonlib;\nuse commonlib.types_common.all;\n\nentity StackTraceBuffer0 is \n  generic (\n    abits0 : integer := 5;\n    dbits0 : integer := 64\n  );\n  port (\n    i_clk0   : in std_logic;\n    i_raddr0 : in std_logic_vector(abits0-1 downto 0);\n    o_rdata0 : out std_logic_vector(dbits0-1 downto 0);\n    i_we0    : in std_logic;\n    i_waddr0 : in std_logic_vector(abits0-1 downto 0);\n    i_wdata0 : in std_logic_vector(dbits0-1 downto 0)\n  );\nend; \n \narchitecture arch_StackTraceBuffer0 of StackTraceBuffer0 is\n\n  type ram_type0 is array ((2**abits0)-1 downto 0) of std_logic_vector (dbits0-1 downto 0);\n  signal stackbuf0    : ram_type0;\n  signal raddr0       : std_logic_vector(abits0-1 downto 0);\n\nbegin\n\n  -- registers:\n  process(i_clk0) begin \n    if rising_edge(i_clk0) then \n      if i_we0 = '1' then\n        stackbuf0(conv_integer(i_waddr0)) <= i_wdata0; \n      end if;\n      raddr0 <= i_raddr0;\n    end if;\n  end process;\n  \n  o_rdata0 <= stackbuf0(conv_integer(raddr0));\n\nend;\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-process.d/input.vhd",
    "content": "--\n-- Taken from rtl/riverlib/core/stacktrbuf.vhd of https://github.com/sergeykhbr/riscv_vhdl\n--\n-----------------------------------------------------------------------------\n--! @file\n--! @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved.\n--! @author    Sergey Khabarov - sergeykhbr@gmail.com\n--! @brief     Stack trace buffer on hardware level.\n------------------------------------------------------------------------------\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nlibrary commonlib;\nuse commonlib.types_common.all;\n\nentity StackTraceBuffer is \n  generic (\n    abits : integer := 5;\n    dbits : integer := 64\n  );\n  port (\n    i_clk   : in std_logic;\n    i_raddr : in std_logic_vector(abits-1 downto 0);\n    o_rdata : out std_logic_vector(dbits-1 downto 0);\n    i_we    : in std_logic;\n    i_waddr : in std_logic_vector(abits-1 downto 0);\n    i_wdata : in std_logic_vector(dbits-1 downto 0)\n  );\nend; \n \narchitecture arch_StackTraceBuffer of StackTraceBuffer is\n\n  type ram_type is array ((2**abits)-1 downto 0) of std_logic_vector (dbits-1 downto 0);\n  signal stackbuf    : ram_type;\n  signal raddr       : std_logic_vector(abits-1 downto 0);\n\nbegin\n\n  -- registers:\n  regs : process(i_clk) begin \n    if rising_edge(i_clk) then \n      if i_we = '1' then\n        stackbuf(conv_integer(i_waddr)) <= i_wdata; \n      end if;\n      raddr <= i_raddr;\n    end if;\n  end process;\n  \n  o_rdata <= stackbuf(conv_integer(raddr));\n\nend;\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-type.d/args.ctags",
    "content": "--sort=no\n--kinds-VHDL=+{local}{prototype}{component}\n--fields=+Kpre\n--extras=+r\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-type.d/expected.tags",
    "content": "types_misc\tinput.vhd\t/^package types_misc is$/;\"\tpackage\troles:def\tend:325\nCFG_IRQ_UNUSED\tinput.vhd\t/^constant CFG_IRQ_UNUSED         : integer := 0;$/;\"\tconstant\tpackage:types_misc\troles:def\nCFG_IRQ_UART1\tinput.vhd\t/^constant CFG_IRQ_UART1          : integer := 1;$/;\"\tconstant\tpackage:types_misc\troles:def\nCFG_IRQ_ETHMAC\tinput.vhd\t/^constant CFG_IRQ_ETHMAC         : integer := 2;$/;\"\tconstant\tpackage:types_misc\troles:def\nCFG_IRQ_GPTIMERS\tinput.vhd\t/^constant CFG_IRQ_GPTIMERS       : integer := 3;$/;\"\tconstant\tpackage:types_misc\troles:def\nCFG_IRQ_GNSSENGINE\tinput.vhd\t/^constant CFG_IRQ_GNSSENGINE     : integer := 4;$/;\"\tconstant\tpackage:types_misc\troles:def\nCFG_IRQ_TOTAL\tinput.vhd\t/^constant CFG_IRQ_TOTAL          : integer := 5;$/;\"\tconstant\tpackage:types_misc\troles:def\nreset_global\tinput.vhd\t/^component reset_global$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:67\ninSysReset\tinput.vhd\t/^  inSysReset  : in std_ulogic;$/;\"\tport\tcomponent:types_misc.reset_global\troles:def\ninSysClk\tinput.vhd\t/^  inSysClk    : in std_ulogic;$/;\"\tport\tcomponent:types_misc.reset_global\troles:def\noutReset\tinput.vhd\t/^  outReset    : out std_ulogic );$/;\"\tport\tcomponent:types_misc.reset_global\troles:def\naxi4_rom\tinput.vhd\t/^component axi4_rom is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:86\nmemtech\tinput.vhd\t/^    memtech  : integer := inferred;$/;\"\tgeneric\tcomponent:types_misc.axi4_rom\troles:def\nasync_reset\tinput.vhd\t/^    async_reset : boolean := false;$/;\"\tgeneric\tcomponent:types_misc.axi4_rom\troles:def\nxaddr\tinput.vhd\t/^    xaddr    : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_rom\troles:def\nxmask\tinput.vhd\t/^    xmask    : integer := 16#fffff#;$/;\"\tgeneric\tcomponent:types_misc.axi4_rom\troles:def\nsim_hexfile\tinput.vhd\t/^    sim_hexfile : string$/;\"\tgeneric\tcomponent:types_misc.axi4_rom\troles:def\nclk\tinput.vhd\t/^    clk  : in std_logic;$/;\"\tport\tcomponent:types_misc.axi4_rom\troles:def\nnrst\tinput.vhd\t/^    nrst : in std_logic;$/;\"\tport\tcomponent:types_misc.axi4_rom\troles:def\ncfg\tinput.vhd\t/^    cfg  : out axi4_slave_config_type;$/;\"\tport\tcomponent:types_misc.axi4_rom\troles:def\ni\tinput.vhd\t/^    i    : in  axi4_slave_in_type;$/;\"\tport\tcomponent:types_misc.axi4_rom\troles:def\no\tinput.vhd\t/^    o    : out axi4_slave_out_type$/;\"\tport\tcomponent:types_misc.axi4_rom\troles:def\naxi4_sram\tinput.vhd\t/^component axi4_sram is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:105\nmemtech\tinput.vhd\t/^    memtech  : integer := inferred;$/;\"\tgeneric\tcomponent:types_misc.axi4_sram\troles:def\nasync_reset\tinput.vhd\t/^    async_reset : boolean := false;$/;\"\tgeneric\tcomponent:types_misc.axi4_sram\troles:def\nxaddr\tinput.vhd\t/^    xaddr    : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_sram\troles:def\nxmask\tinput.vhd\t/^    xmask    : integer := 16#fffff#;$/;\"\tgeneric\tcomponent:types_misc.axi4_sram\troles:def\nabits\tinput.vhd\t/^    abits    : integer := 17;$/;\"\tgeneric\tcomponent:types_misc.axi4_sram\troles:def\ninit_file\tinput.vhd\t/^    init_file : string := \"\" -- only for 'inferred'$/;\"\tgeneric\tcomponent:types_misc.axi4_sram\troles:def\nclk\tinput.vhd\t/^    clk  : in std_logic;$/;\"\tport\tcomponent:types_misc.axi4_sram\troles:def\nnrst\tinput.vhd\t/^    nrst : in std_logic;$/;\"\tport\tcomponent:types_misc.axi4_sram\troles:def\ncfg\tinput.vhd\t/^    cfg  : out axi4_slave_config_type;$/;\"\tport\tcomponent:types_misc.axi4_sram\troles:def\ni\tinput.vhd\t/^    i    : in  axi4_slave_in_type;$/;\"\tport\tcomponent:types_misc.axi4_sram\troles:def\no\tinput.vhd\t/^    o    : out axi4_slave_out_type$/;\"\tport\tcomponent:types_misc.axi4_sram\troles:def\nspi_in_type\tinput.vhd\t/^type spi_in_type is record$/;\"\ttype\tpackage:types_misc\troles:def\tend:110\nSDI\tinput.vhd\t/^    SDI : std_logic;$/;\"\trecord\ttype:types_misc.spi_in_type\troles:def\nspi_out_type\tinput.vhd\t/^type spi_out_type is record$/;\"\ttype\tpackage:types_misc\troles:def\tend:119\nSDO\tinput.vhd\t/^    SDO : std_logic;$/;\"\trecord\ttype:types_misc.spi_out_type\troles:def\nSCK\tinput.vhd\t/^    SCK : std_logic;$/;\"\trecord\ttype:types_misc.spi_out_type\troles:def\nnCS\tinput.vhd\t/^    nCS : std_logic;$/;\"\trecord\ttype:types_misc.spi_out_type\troles:def\nnWP\tinput.vhd\t/^    nWP : std_logic;$/;\"\trecord\ttype:types_misc.spi_out_type\troles:def\nnHOLD\tinput.vhd\t/^    nHOLD : std_logic;$/;\"\trecord\ttype:types_misc.spi_out_type\troles:def\nRESET\tinput.vhd\t/^    RESET : std_logic;$/;\"\trecord\ttype:types_misc.spi_out_type\troles:def\nspi_out_none\tinput.vhd\t/^constant spi_out_none : spi_out_type := ($/;\"\tconstant\tpackage:types_misc\troles:def\naxi4_flashspi\tinput.vhd\t/^component axi4_flashspi is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:140\nasync_reset\tinput.vhd\t/^    async_reset : boolean := false;$/;\"\tgeneric\tcomponent:types_misc.axi4_flashspi\troles:def\nxaddr\tinput.vhd\t/^    xaddr   : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_flashspi\troles:def\nxmask\tinput.vhd\t/^    xmask   : integer := 16#fffff#;$/;\"\tgeneric\tcomponent:types_misc.axi4_flashspi\troles:def\nwait_while_write\tinput.vhd\t/^    wait_while_write : boolean := true  -- hold AXI bus response until end of write cycle$/;\"\tgeneric\tcomponent:types_misc.axi4_flashspi\troles:def\nclk\tinput.vhd\t/^    clk    : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_flashspi\troles:def\nnrst\tinput.vhd\t/^    nrst   : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_flashspi\troles:def\ncfg\tinput.vhd\t/^    cfg    : out axi4_slave_config_type;$/;\"\tport\tcomponent:types_misc.axi4_flashspi\troles:def\ni_spi\tinput.vhd\t/^    i_spi  : in  spi_in_type;$/;\"\tport\tcomponent:types_misc.axi4_flashspi\troles:def\no_spi\tinput.vhd\t/^    o_spi  : out spi_out_type;$/;\"\tport\tcomponent:types_misc.axi4_flashspi\troles:def\ni_axi\tinput.vhd\t/^    i_axi  : in  axi4_slave_in_type;$/;\"\tport\tcomponent:types_misc.axi4_flashspi\troles:def\no_axi\tinput.vhd\t/^    o_axi  : out axi4_slave_out_type  );$/;\"\tport\tcomponent:types_misc.axi4_flashspi\troles:def\naxi4_gpio\tinput.vhd\t/^component axi4_gpio is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:161\nasync_reset\tinput.vhd\t/^    async_reset : boolean := false;$/;\"\tgeneric\tcomponent:types_misc.axi4_gpio\troles:def\nxaddr\tinput.vhd\t/^    xaddr    : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_gpio\troles:def\nxmask\tinput.vhd\t/^    xmask    : integer := 16#fffff#;$/;\"\tgeneric\tcomponent:types_misc.axi4_gpio\troles:def\nxirq\tinput.vhd\t/^    xirq     : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_gpio\troles:def\nwidth\tinput.vhd\t/^    width    : integer := 12$/;\"\tgeneric\tcomponent:types_misc.axi4_gpio\troles:def\nclk\tinput.vhd\t/^    clk  : in std_logic;$/;\"\tport\tcomponent:types_misc.axi4_gpio\troles:def\nnrst\tinput.vhd\t/^    nrst : in std_logic;$/;\"\tport\tcomponent:types_misc.axi4_gpio\troles:def\ncfg\tinput.vhd\t/^    cfg  : out axi4_slave_config_type;$/;\"\tport\tcomponent:types_misc.axi4_gpio\troles:def\ni\tinput.vhd\t/^    i    : in  axi4_slave_in_type;$/;\"\tport\tcomponent:types_misc.axi4_gpio\troles:def\no\tinput.vhd\t/^    o    : out axi4_slave_out_type;$/;\"\tport\tcomponent:types_misc.axi4_gpio\troles:def\ni_gpio\tinput.vhd\t/^    i_gpio : in std_logic_vector(width-1 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_gpio\troles:def\no_gpio\tinput.vhd\t/^    o_gpio : out std_logic_vector(width-1 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_gpio\troles:def\no_gpio_dir\tinput.vhd\t/^    o_gpio_dir : out std_logic_vector(width-1 downto 0)$/;\"\tport\tcomponent:types_misc.axi4_gpio\troles:def\nuart_in_type\tinput.vhd\t/^type uart_in_type is record$/;\"\ttype\tpackage:types_misc\troles:def\tend:166\nrd\tinput.vhd\t/^  rd   \t: std_ulogic;$/;\"\trecord\ttype:types_misc.uart_in_type\troles:def\ncts\tinput.vhd\t/^  cts   : std_ulogic;$/;\"\trecord\ttype:types_misc.uart_in_type\troles:def\nuart_out_type\tinput.vhd\t/^type uart_out_type is record$/;\"\ttype\tpackage:types_misc\troles:def\tend:171\ntd\tinput.vhd\t/^  td   \t: std_ulogic;$/;\"\trecord\ttype:types_misc.uart_out_type\troles:def\nrts\tinput.vhd\t/^  rts   : std_ulogic;$/;\"\trecord\ttype:types_misc.uart_out_type\troles:def\naxi4_uart\tinput.vhd\t/^component axi4_uart is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:191\nasync_reset\tinput.vhd\t/^    async_reset : boolean := false;$/;\"\tgeneric\tcomponent:types_misc.axi4_uart\troles:def\nxaddr\tinput.vhd\t/^    xaddr   : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_uart\troles:def\nxmask\tinput.vhd\t/^    xmask   : integer := 16#fffff#;$/;\"\tgeneric\tcomponent:types_misc.axi4_uart\troles:def\nxirq\tinput.vhd\t/^    xirq    : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_uart\troles:def\nfifosz\tinput.vhd\t/^    fifosz  : integer := 16$/;\"\tgeneric\tcomponent:types_misc.axi4_uart\troles:def\nclk\tinput.vhd\t/^    clk    : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_uart\troles:def\nnrst\tinput.vhd\t/^    nrst   : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_uart\troles:def\ncfg\tinput.vhd\t/^    cfg    : out axi4_slave_config_type;$/;\"\tport\tcomponent:types_misc.axi4_uart\troles:def\ni_uart\tinput.vhd\t/^    i_uart : in  uart_in_type;$/;\"\tport\tcomponent:types_misc.axi4_uart\troles:def\no_uart\tinput.vhd\t/^    o_uart : out uart_out_type;$/;\"\tport\tcomponent:types_misc.axi4_uart\troles:def\ni_axi\tinput.vhd\t/^    i_axi  : in  axi4_slave_in_type;$/;\"\tport\tcomponent:types_misc.axi4_uart\troles:def\no_axi\tinput.vhd\t/^    o_axi  : out axi4_slave_out_type;$/;\"\tport\tcomponent:types_misc.axi4_uart\troles:def\no_irq\tinput.vhd\t/^    o_irq  : out std_logic);$/;\"\tport\tcomponent:types_misc.axi4_uart\troles:def\nuart_tap\tinput.vhd\t/^component uart_tap is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:204\nnrst\tinput.vhd\t/^    nrst     : in std_logic;$/;\"\tport\tcomponent:types_misc.uart_tap\troles:def\nclk\tinput.vhd\t/^    clk      : in std_logic;$/;\"\tport\tcomponent:types_misc.uart_tap\troles:def\ni_uart\tinput.vhd\t/^    i_uart   : in  uart_in_type;$/;\"\tport\tcomponent:types_misc.uart_tap\troles:def\no_uart\tinput.vhd\t/^    o_uart   : out uart_out_type;$/;\"\tport\tcomponent:types_misc.uart_tap\troles:def\ni_msti\tinput.vhd\t/^    i_msti   : in axi4_master_in_type;$/;\"\tport\tcomponent:types_misc.uart_tap\troles:def\no_msto\tinput.vhd\t/^    o_msto   : out axi4_master_out_type;$/;\"\tport\tcomponent:types_misc.uart_tap\troles:def\no_mstcfg\tinput.vhd\t/^    o_mstcfg : out axi4_master_config_type$/;\"\tport\tcomponent:types_misc.uart_tap\troles:def\ntap_jtag\tinput.vhd\t/^component tap_jtag is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:224\nainst\tinput.vhd\t/^    ainst  : integer range 0 to 255 := 2;$/;\"\tgeneric\tcomponent:types_misc.tap_jtag\troles:def\ndinst\tinput.vhd\t/^    dinst  : integer range 0 to 255 := 3);$/;\"\tgeneric\tcomponent:types_misc.tap_jtag\troles:def\nnrst\tinput.vhd\t/^    nrst  : in std_logic;$/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\nclk\tinput.vhd\t/^    clk  : in std_logic;$/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\ni_tck\tinput.vhd\t/^    i_tck   : in std_logic;   -- in: Test Clock$/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\ni_ntrst\tinput.vhd\t/^    i_ntrst   : in std_logic;   -- in: $/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\ni_tms\tinput.vhd\t/^    i_tms   : in std_logic;   -- in: Test Mode State$/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\ni_tdi\tinput.vhd\t/^    i_tdi   : in std_logic;   -- in: Test Data Input$/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\no_tdo\tinput.vhd\t/^    o_tdo   : out std_logic;   -- out: Test Data Output$/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\no_jtag_vref\tinput.vhd\t/^    o_jtag_vref : out std_logic;$/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\ni_msti\tinput.vhd\t/^    i_msti   : in axi4_master_in_type;$/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\no_msto\tinput.vhd\t/^    o_msto   : out axi4_master_out_type;$/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\no_mstcfg\tinput.vhd\t/^    o_mstcfg : out axi4_master_config_type$/;\"\tport\tcomponent:types_misc.tap_jtag\troles:def\naxi4_irqctrl\tinput.vhd\t/^component axi4_irqctrl is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:245\nasync_reset\tinput.vhd\t/^    async_reset : boolean := false;$/;\"\tgeneric\tcomponent:types_misc.axi4_irqctrl\troles:def\nxaddr\tinput.vhd\t/^    xaddr    : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_irqctrl\troles:def\nxmask\tinput.vhd\t/^    xmask    : integer := 16#fffff#$/;\"\tgeneric\tcomponent:types_misc.axi4_irqctrl\troles:def\nclk\tinput.vhd\t/^    clk    : in std_logic;$/;\"\tport\tcomponent:types_misc.axi4_irqctrl\troles:def\nnrst\tinput.vhd\t/^    nrst   : in std_logic;$/;\"\tport\tcomponent:types_misc.axi4_irqctrl\troles:def\ni_irqs\tinput.vhd\t/^    i_irqs : in std_logic_vector(CFG_IRQ_TOTAL-1 downto 1);$/;\"\tport\tcomponent:types_misc.axi4_irqctrl\troles:def\no_cfg\tinput.vhd\t/^    o_cfg  : out axi4_slave_config_type;$/;\"\tport\tcomponent:types_misc.axi4_irqctrl\troles:def\ni_axi\tinput.vhd\t/^    i_axi  : in axi4_slave_in_type;$/;\"\tport\tcomponent:types_misc.axi4_irqctrl\troles:def\no_axi\tinput.vhd\t/^    o_axi  : out axi4_slave_out_type;$/;\"\tport\tcomponent:types_misc.axi4_irqctrl\troles:def\no_irq_meip\tinput.vhd\t/^    o_irq_meip : out std_logic$/;\"\tport\tcomponent:types_misc.axi4_irqctrl\troles:def\naxi4_gptimers\tinput.vhd\t/^  component axi4_gptimers is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:267\nasync_reset\tinput.vhd\t/^    async_reset : boolean := false;$/;\"\tgeneric\tcomponent:types_misc.axi4_gptimers\troles:def\nxaddr\tinput.vhd\t/^    xaddr   : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_gptimers\troles:def\nxmask\tinput.vhd\t/^    xmask   : integer := 16#fffff#;$/;\"\tgeneric\tcomponent:types_misc.axi4_gptimers\troles:def\nxirq\tinput.vhd\t/^    xirq    : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_gptimers\troles:def\ntmr_total\tinput.vhd\t/^    tmr_total  : integer := 2$/;\"\tgeneric\tcomponent:types_misc.axi4_gptimers\troles:def\nclk\tinput.vhd\t/^    clk    : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_gptimers\troles:def\nnrst\tinput.vhd\t/^    nrst   : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_gptimers\troles:def\ncfg\tinput.vhd\t/^    cfg    : out axi4_slave_config_type;$/;\"\tport\tcomponent:types_misc.axi4_gptimers\troles:def\ni_axi\tinput.vhd\t/^    i_axi  : in  axi4_slave_in_type;$/;\"\tport\tcomponent:types_misc.axi4_gptimers\troles:def\no_axi\tinput.vhd\t/^    o_axi  : out axi4_slave_out_type;$/;\"\tport\tcomponent:types_misc.axi4_gptimers\troles:def\no_pwm\tinput.vhd\t/^    o_pwm : out std_logic_vector(tmr_total-1 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_gptimers\troles:def\no_irq\tinput.vhd\t/^    o_irq  : out std_logic$/;\"\tport\tcomponent:types_misc.axi4_gptimers\troles:def\naxi4_pnp\tinput.vhd\t/^component axi4_pnp is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:298\nasync_reset\tinput.vhd\t/^    async_reset : boolean := false;$/;\"\tgeneric\tcomponent:types_misc.axi4_pnp\troles:def\nxaddr\tinput.vhd\t/^    xaddr   : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_pnp\troles:def\nxmask\tinput.vhd\t/^    xmask   : integer := 16#fffff#;$/;\"\tgeneric\tcomponent:types_misc.axi4_pnp\troles:def\ntech\tinput.vhd\t/^    tech    : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_pnp\troles:def\nhw_id\tinput.vhd\t/^    hw_id   : std_logic_vector(31 downto 0) := X\"20170101\"$/;\"\tgeneric\tcomponent:types_misc.axi4_pnp\troles:def\nsys_clk\tinput.vhd\t/^    sys_clk : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\nadc_clk\tinput.vhd\t/^    adc_clk : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\nnrst\tinput.vhd\t/^    nrst   : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\nmstcfg\tinput.vhd\t/^    mstcfg : in  bus0_xmst_cfg_vector;$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\nslvcfg\tinput.vhd\t/^    slvcfg : in  bus0_xslv_cfg_vector;$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\ncfg\tinput.vhd\t/^    cfg    : out  axi4_slave_config_type;$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\ni\tinput.vhd\t/^    i      : in  axi4_slave_in_type;$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\no\tinput.vhd\t/^    o      : out axi4_slave_out_type;$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\ni_otp_busy\tinput.vhd\t/^    i_otp_busy : in std_logic;$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\no_otp_cfg_rsetup\tinput.vhd\t/^    o_otp_cfg_rsetup : out std_logic_vector(3 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\no_otp_cfg_wadrsetup\tinput.vhd\t/^    o_otp_cfg_wadrsetup : out std_logic_vector(3 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\no_otp_cfg_wactive\tinput.vhd\t/^    o_otp_cfg_wactive : out std_logic_vector(31 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\no_otp_cfg_whold\tinput.vhd\t/^    o_otp_cfg_whold : out std_logic_vector(3 downto 0)$/;\"\tport\tcomponent:types_misc.axi4_pnp\troles:def\naxi4_otp\tinput.vhd\t/^component axi4_otp is$/;\"\tcomponent\tpackage:types_misc\troles:def\tend:323\nasync_reset\tinput.vhd\t/^    async_reset : boolean := false;$/;\"\tgeneric\tcomponent:types_misc.axi4_otp\troles:def\nxaddr\tinput.vhd\t/^    xaddr   : integer := 0;$/;\"\tgeneric\tcomponent:types_misc.axi4_otp\troles:def\nxmask\tinput.vhd\t/^    xmask   : integer := 16#ffffe#$/;\"\tgeneric\tcomponent:types_misc.axi4_otp\troles:def\nclk\tinput.vhd\t/^    clk    : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\nnrst\tinput.vhd\t/^    nrst   : in  std_logic;$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\ncfg\tinput.vhd\t/^    cfg    : out axi4_slave_config_type;$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\ni_axi\tinput.vhd\t/^    i_axi  : in  axi4_slave_in_type;$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\no_axi\tinput.vhd\t/^    o_axi  : out axi4_slave_out_type;$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\no_otp_we\tinput.vhd\t/^    o_otp_we     : out  std_ulogic;$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\no_otp_re\tinput.vhd\t/^    o_otp_re     : out  std_ulogic;$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\no_otp_addr\tinput.vhd\t/^    o_otp_addr   : out std_logic_vector(11 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\no_otp_wdata\tinput.vhd\t/^    o_otp_wdata  : out std_logic_vector(15 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\ni_otp_rdata\tinput.vhd\t/^    i_otp_rdata  : in std_logic_vector(15 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\ni_cfg_rsetup\tinput.vhd\t/^    i_cfg_rsetup : in std_logic_vector(3 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\ni_cfg_wadrsetup\tinput.vhd\t/^    i_cfg_wadrsetup : in std_logic_vector(3 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\ni_cfg_wactive\tinput.vhd\t/^    i_cfg_wactive : in std_logic_vector(31 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\ni_cfg_whold\tinput.vhd\t/^    i_cfg_whold : in std_logic_vector(3 downto 0);$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\no_busy\tinput.vhd\t/^    o_busy : out std_logic$/;\"\tport\tcomponent:types_misc.axi4_otp\troles:def\n"
  },
  {
    "path": "Units/parser-vhdl.r/vhdl-type.d/input.vhd",
    "content": "--\n-- Taken from rtl/misclib/types_misc.vhd of https://github.com/sergeykhbr/riscv_vhdl\n--\n--!\n--! Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com\n--!\n--! Licensed under the Apache License, Version 2.0 (the \"License\");\n--! you may not use this file except in compliance with the License.\n--! You may obtain a copy of the License at\n--!\n--!     http://www.apache.org/licenses/LICENSE-2.0\n--! Unless required by applicable law or agreed to in writing, software\n--! distributed under the License is distributed on an \"AS IS\" BASIS,\n--! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n--! See the License for the specific language governing permissions and\n--! limitations under the License.\n--!\n\n--! Standard library.\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\nlibrary commonlib;\nuse commonlib.types_common.all;\n--! Technology definition library.\nlibrary techmap;\nuse techmap.gencomp.all;\n--! CPU, System Bus and common peripheries library.\nlibrary ambalib;\nuse ambalib.types_amba4.all;\nuse ambalib.types_bus0.all;\n\n--! @brief   Declaration of components visible on SoC top level.\npackage types_misc is\n\n--! @defgroup irq_id_group AXI4 interrupt generic IDs.\n--! @ingroup axi4_config_generic_group\n--! @details Unique indentificator of the interrupt pin also used\n--!          as an index in the interrupts bus.\n--! @{\n\n--! Zero interrupt index must be unused.\nconstant CFG_IRQ_UNUSED         : integer := 0;\n--! UART_A interrupt pin.\nconstant CFG_IRQ_UART1          : integer := 1;\n--! Ethernet MAC interrupt pin.\nconstant CFG_IRQ_ETHMAC         : integer := 2;\n--! GP Timers interrupt pin\nconstant CFG_IRQ_GPTIMERS       : integer := 3;\n--! GNSS Engine IRQ pin that generates 1 msec pulses.\nconstant CFG_IRQ_GNSSENGINE     : integer := 4;\n--! Total number of used interrupts in a system\nconstant CFG_IRQ_TOTAL          : integer := 5;\n--! @}\n\n--! @brief SOC global reset former.\n--! @details This module produces output reset signal in a case if\n--!          button 'Reset' was pushed or PLL isn't a 'lock' state.\n--! param[in]  inSysReset Button generated signal\n--! param[in]  inSysClk Clock from the PLL. Bus clock.\n--! param[out] outReset Output reset signal with active 'High' (1 = reset).\ncomponent reset_global\nport (\n  inSysReset  : in std_ulogic;\n  inSysClk    : in std_ulogic;\n  outReset    : out std_ulogic );\nend component;\n\n\n--! Boot ROM with AXI4 interface declaration.\ncomponent axi4_rom is\ngeneric (\n    memtech  : integer := inferred;\n    async_reset : boolean := false;\n    xaddr    : integer := 0;\n    xmask    : integer := 16#fffff#;\n    sim_hexfile : string\n  );\nport (\n    clk  : in std_logic;\n    nrst : in std_logic;\n    cfg  : out axi4_slave_config_type;\n    i    : in  axi4_slave_in_type;\n    o    : out axi4_slave_out_type\n  );\nend component; \n\n--! Internal RAM with AXI4 interface declaration.\ncomponent axi4_sram is\n  generic (\n    memtech  : integer := inferred;\n    async_reset : boolean := false;\n    xaddr    : integer := 0;\n    xmask    : integer := 16#fffff#;\n    abits    : integer := 17;\n    init_file : string := \"\" -- only for 'inferred'\n  );\n  port (\n    clk  : in std_logic;\n    nrst : in std_logic;\n    cfg  : out axi4_slave_config_type;\n    i    : in  axi4_slave_in_type;\n    o    : out axi4_slave_out_type\n  );\nend component; \n\n--! AXI4 to SPI brdige for external Flash IC Micron M25AA1024\ntype spi_in_type is record\n    SDI : std_logic;\nend record;\n\ntype spi_out_type is record\n    SDO : std_logic;\n    SCK : std_logic;\n    nCS : std_logic;\n    nWP : std_logic;\n    nHOLD : std_logic;\n    RESET : std_logic;\nend record;\n\nconstant spi_out_none : spi_out_type := (\n  '0', '0', '1', '1', '1', '0'\n);\n\ncomponent axi4_flashspi is\n  generic (\n    async_reset : boolean := false;\n    xaddr   : integer := 0;\n    xmask   : integer := 16#fffff#;\n    wait_while_write : boolean := true  -- hold AXI bus response until end of write cycle\n  );\n  port (\n    clk    : in  std_logic;\n    nrst   : in  std_logic;\n    cfg    : out axi4_slave_config_type;\n    i_spi  : in  spi_in_type;\n    o_spi  : out spi_out_type;\n    i_axi  : in  axi4_slave_in_type;\n    o_axi  : out axi4_slave_out_type  );\nend component; \n\n--! @brief AXI4 GPIO controller\ncomponent axi4_gpio is\n  generic (\n    async_reset : boolean := false;\n    xaddr    : integer := 0;\n    xmask    : integer := 16#fffff#;\n    xirq     : integer := 0;\n    width    : integer := 12\n  );\n  port (\n    clk  : in std_logic;\n    nrst : in std_logic;\n    cfg  : out axi4_slave_config_type;\n    i    : in  axi4_slave_in_type;\n    o    : out axi4_slave_out_type;\n    i_gpio : in std_logic_vector(width-1 downto 0);\n    o_gpio : out std_logic_vector(width-1 downto 0);\n    o_gpio_dir : out std_logic_vector(width-1 downto 0)\n  );\nend component; \n\ntype uart_in_type is record\n  rd   \t: std_ulogic;\n  cts   : std_ulogic;\nend record;\n\ntype uart_out_type is record\n  td   \t: std_ulogic;\n  rts   : std_ulogic;\nend record;\n\n--! UART with the AXI4 interface declaration.\ncomponent axi4_uart is\n  generic (\n    async_reset : boolean := false;\n    xaddr   : integer := 0;\n    xmask   : integer := 16#fffff#;\n    xirq    : integer := 0;\n    fifosz  : integer := 16\n  );\n  port (\n    clk    : in  std_logic;\n    nrst   : in  std_logic;\n    cfg    : out axi4_slave_config_type;\n    i_uart : in  uart_in_type;\n    o_uart : out uart_out_type;\n    i_axi  : in  axi4_slave_in_type;\n    o_axi  : out axi4_slave_out_type;\n    o_irq  : out std_logic);\nend component;\n\n--! Test Access Point via UART (debug access)\ncomponent uart_tap is\n  port (\n    nrst     : in std_logic;\n    clk      : in std_logic;\n    i_uart   : in  uart_in_type;\n    o_uart   : out uart_out_type;\n    i_msti   : in axi4_master_in_type;\n    o_msto   : out axi4_master_out_type;\n    o_mstcfg : out axi4_master_config_type\n  );\nend component; \n\n-- JTAG TAP\ncomponent tap_jtag is\n  generic (\n    ainst  : integer range 0 to 255 := 2;\n    dinst  : integer range 0 to 255 := 3);\n  port (\n    nrst  : in std_logic;\n    clk  : in std_logic;\n    i_tck   : in std_logic;   -- in: Test Clock\n    i_ntrst   : in std_logic;   -- in: \n    i_tms   : in std_logic;   -- in: Test Mode State\n    i_tdi   : in std_logic;   -- in: Test Data Input\n    o_tdo   : out std_logic;   -- out: Test Data Output\n    o_jtag_vref : out std_logic;\n    i_msti   : in axi4_master_in_type;\n    o_msto   : out axi4_master_out_type;\n    o_mstcfg : out axi4_master_config_type\n    );\nend component;\n\n\n--! @brief   Interrupt controller with the AXI4 interface declaration.\n--! @details To rise interrupt on certain CPU HostIO interface is used.\ncomponent axi4_irqctrl is\n  generic (\n    async_reset : boolean := false;\n    xaddr    : integer := 0;\n    xmask    : integer := 16#fffff#\n  );\n  port \n (\n    clk    : in std_logic;\n    nrst   : in std_logic;\n    i_irqs : in std_logic_vector(CFG_IRQ_TOTAL-1 downto 1);\n    o_cfg  : out axi4_slave_config_type;\n    i_axi  : in axi4_slave_in_type;\n    o_axi  : out axi4_slave_out_type;\n    o_irq_meip : out std_logic\n  );\n  end component;\n\n  --! @brief   General Purpose Timers with the AXI interface.\n  --! @details This module provides high precision counter and\n  --!          generic number of GP timers.\n  component axi4_gptimers is\n  generic (\n    async_reset : boolean := false;\n    xaddr   : integer := 0;\n    xmask   : integer := 16#fffff#;\n    xirq    : integer := 0;\n    tmr_total  : integer := 2\n  );\n  port (\n    clk    : in  std_logic;\n    nrst   : in  std_logic;\n    cfg    : out axi4_slave_config_type;\n    i_axi  : in  axi4_slave_in_type;\n    o_axi  : out axi4_slave_out_type;\n    o_pwm : out std_logic_vector(tmr_total-1 downto 0);\n    o_irq  : out std_logic\n  );\n  end component; \n\n--! @brief   Plug-n-Play support module with AXI4 interface declaration.\n--! @details Each device in a system hase to implements sideband signal\n--!          structure 'nasti_slave_config_type' that allows FW to\n--!          detect Hardware configuration in a run-time.\n--! @todo Implements PnP signals for all Masters devices.\ncomponent axi4_pnp is\n  generic (\n    async_reset : boolean := false;\n    xaddr   : integer := 0;\n    xmask   : integer := 16#fffff#;\n    tech    : integer := 0;\n    hw_id   : std_logic_vector(31 downto 0) := X\"20170101\"\n  );\n  port (\n    sys_clk : in  std_logic;\n    adc_clk : in  std_logic;\n    nrst   : in  std_logic;\n    mstcfg : in  bus0_xmst_cfg_vector;\n    slvcfg : in  bus0_xslv_cfg_vector;\n    cfg    : out  axi4_slave_config_type;\n    i      : in  axi4_slave_in_type;\n    o      : out axi4_slave_out_type;\n    -- OTP Timing control\n    i_otp_busy : in std_logic;\n    o_otp_cfg_rsetup : out std_logic_vector(3 downto 0);\n    o_otp_cfg_wadrsetup : out std_logic_vector(3 downto 0);\n    o_otp_cfg_wactive : out std_logic_vector(31 downto 0);\n    o_otp_cfg_whold : out std_logic_vector(3 downto 0)\n  );\nend component; \n\ncomponent axi4_otp is\n  generic (\n    async_reset : boolean := false;\n    xaddr   : integer := 0;\n    xmask   : integer := 16#ffffe#\n  );\n  port (\n    clk    : in  std_logic;\n    nrst   : in  std_logic;\n    cfg    : out axi4_slave_config_type;\n    i_axi  : in  axi4_slave_in_type;\n    o_axi  : out axi4_slave_out_type;\n    o_otp_we     : out  std_ulogic;\n    o_otp_re     : out  std_ulogic;\n    o_otp_addr   : out std_logic_vector(11 downto 0);\n    o_otp_wdata  : out std_logic_vector(15 downto 0);\n    i_otp_rdata  : in std_logic_vector(15 downto 0);\n    i_cfg_rsetup : in std_logic_vector(3 downto 0);\n    i_cfg_wadrsetup : in std_logic_vector(3 downto 0);\n    i_cfg_wactive : in std_logic_vector(31 downto 0);\n    i_cfg_whold : in std_logic_vector(3 downto 0);\n    o_busy : out std_logic\n  );\nend component; \n\nend; -- package declaration\n"
  },
  {
    "path": "Units/parser-vim.r/3214129.vim.d/expected.tags",
    "content": "<Leader>hgG\tinput.vim\t/^  nmap <unique> <Leader>hgG <Plug>HGClearAndGotoOriginal$/;\"\tm\n<Leader>hga\tinput.vim\t/^  nmap <unique> <Leader>hga <Plug>HGAdd$/;\"\tm\n<Leader>hgc\tinput.vim\t/^  nmap <unique> <Leader>hgc <Plug>HGCommit$/;\"\tm\n<Leader>hgd\tinput.vim\t/^  nmap <unique> <Leader>hgd <Plug>HGDiff$/;\"\tm\n<Leader>hgg\tinput.vim\t/^  nmap <unique> <Leader>hgg <Plug>HGGotoOriginal$/;\"\tm\n<Leader>hgl\tinput.vim\t/^  nmap <unique> <Leader>hgl <Plug>HGLog$/;\"\tm\n<Leader>hgn\tinput.vim\t/^  nmap <unique> <Leader>hgn <Plug>HGAnnotate$/;\"\tm\n<Leader>hgq\tinput.vim\t/^  nmap <unique> <Leader>hgq <Plug>HGRevert$/;\"\tm\n<Leader>hgr\tinput.vim\t/^  nmap <unique> <Leader>hgr <Plug>HGReview$/;\"\tm\n<Leader>hgs\tinput.vim\t/^  nmap <unique> <Leader>hgs <Plug>HGStatus$/;\"\tm\n<Leader>hgu\tinput.vim\t/^  nmap <unique> <Leader>hgu <Plug>HGUpdate$/;\"\tm\n<Leader>hgv\tinput.vim\t/^  nmap <unique> <Leader>hgv <Plug>HGVimDiff$/;\"\tm\n<Plug>HGAdd\tinput.vim\t/^nnoremap <silent> <Plug>HGAdd :HGAdd<CR>$/;\"\tm\n<Plug>HGAnnotate\tinput.vim\t/^nnoremap <silent> <Plug>HGAnnotate :HGAnnotate<CR>$/;\"\tm\n<Plug>HGClearAndGotoOriginal\tinput.vim\t/^nnoremap <silent> <Plug>HGClearAndGotoOriginal :HGGotoOriginal!<CR>$/;\"\tm\n<Plug>HGCommit\tinput.vim\t/^nnoremap <silent> <Plug>HGCommit :HGCommit<CR>$/;\"\tm\n<Plug>HGDiff\tinput.vim\t/^nnoremap <silent> <Plug>HGDiff :HGDiff<CR>$/;\"\tm\n<Plug>HGGotoOriginal\tinput.vim\t/^nnoremap <silent> <Plug>HGGotoOriginal :HGGotoOriginal<CR>$/;\"\tm\n<Plug>HGLog\tinput.vim\t/^nnoremap <silent> <Plug>HGLog :HGLog<CR>$/;\"\tm\n<Plug>HGRevert\tinput.vim\t/^nnoremap <silent> <Plug>HGRevert :HGRevert<CR>$/;\"\tm\n<Plug>HGReview\tinput.vim\t/^nnoremap <silent> <Plug>HGReview :HGReview<CR>$/;\"\tm\n<Plug>HGStatus\tinput.vim\t/^nnoremap <silent> <Plug>HGStatus :HGStatus<CR>$/;\"\tm\n<Plug>HGUpdate\tinput.vim\t/^nnoremap <silent> <Plug>HGUpdate :HGUpdate<CR>$/;\"\tm\n<Plug>HGVimDiff\tinput.vim\t/^nnoremap <silent> <Plug>HGVimDiff :HGVimDiff<CR>$/;\"\tm\n<Plug>HGWatchAdd\tinput.vim\t/^nnoremap <silent> <Plug>HGWatchAdd :HGWatchAdd<CR>$/;\"\tm\n<Plug>HGWatchOff\tinput.vim\t/^nnoremap <silent> <Plug>HGWatchOff :HGWatchOff<CR>$/;\"\tm\n<Plug>HGWatchOn\tinput.vim\t/^nnoremap <silent> <Plug>HGWatchOn :HGWatchOn<CR>$/;\"\tm\n<Plug>HGWatchRemove\tinput.vim\t/^nnoremap <silent> <Plug>HGWatchRemove :HGWatchRemove<CR>$/;\"\tm\n<Plug>HGWatchers\tinput.vim\t/^nnoremap <silent> <Plug>HGWatchers :HGWatchers<CR>$/;\"\tm\nHGAdd\tinput.vim\t/^com! HGAdd call s:HGAdd()$/;\"\tc\nHGAnnotate\tinput.vim\t/^com! -nargs=? HGAnnotate call s:HGAnnotate(<f-args>)$/;\"\tc\nHGCommand\tinput.vim\t/^      augroup HGCommand$/;\"\ta\nHGCommand\tinput.vim\t/^augroup HGCommand$/;\"\ta\nHGCommandPlugin\tinput.vim\t/^  augroup HGCommandPlugin$/;\"\ta\nHGCommit\tinput.vim\t/^    augroup HGCommit$/;\"\ta\nHGCommit\tinput.vim\t/^com! -bang -nargs=? HGCommit call s:HGCommit(<q-bang>, <q-args>)$/;\"\tc\nHGDiff\tinput.vim\t/^com! -nargs=* HGDiff call s:HGDiff(<f-args>)$/;\"\tc\nHGDisableBufferSetup\tinput.vim\t/^com! HGDisableBufferSetup call HGDisableBufferSetup()$/;\"\tc\nHGDisableBufferSetup\tinput.vim\t/^function! HGDisableBufferSetup()$/;\"\tf\nHGEnableBufferSetup\tinput.vim\t/^com! HGEnableBufferSetup call HGEnableBufferSetup()$/;\"\tc\nHGEnableBufferSetup\tinput.vim\t/^function! HGEnableBufferSetup()$/;\"\tf\nHGGetRevision\tinput.vim\t/^function! HGGetRevision()$/;\"\tf\nHGGetStatusLine\tinput.vim\t/^function! HGGetStatusLine()$/;\"\tf\nHGGotoOriginal\tinput.vim\t/^com! -bang HGGotoOriginal call s:HGGotoOriginal(<q-bang>)$/;\"\tc\nHGLog\tinput.vim\t/^com! -nargs=? HGLog call s:HGLog(<f-args>)$/;\"\tc\nHGReload\tinput.vim\t/^com! HGReload unlet! loaded_hgcommand | runtime plugin\\/hgcommand.vim$/;\"\tc\nHGRevert\tinput.vim\t/^com! HGRevert call s:HGRevert()$/;\"\tc\nHGReview\tinput.vim\t/^com! -nargs=? HGReview call s:HGReview(<f-args>)$/;\"\tc\nHGStatus\tinput.vim\t/^com! HGStatus call s:HGStatus()$/;\"\tc\nHGUpdate\tinput.vim\t/^com! HGUpdate call s:HGUpdate()$/;\"\tc\nHGVimDiff\tinput.vim\t/^com! -nargs=* HGVimDiff call s:HGVimDiff(<f-args>)$/;\"\tc\nHGVimDiffRestore\tinput.vim\t/^augroup HGVimDiffRestore$/;\"\ta\n\\\\add\tinput.vim\t/^      nmap \\\\add <Plug>HGAdd$/;\"\tm\nbuffer\tinput.vim\t/^                        command buffer.  The HGCommand buffer variables may be $/;\"\tc\ng:HGCommandDeleteOnHide\tinput.vim\t/^    let g:HGCommandDeleteOnHide=1$/;\"\tv\ng:HGCommandEnableBufferSetup\tinput.vim\t/^  let g:HGCommandEnableBufferSetup=0$/;\"\tv\ng:HGCommandEnableBufferSetup\tinput.vim\t/^  let g:HGCommandEnableBufferSetup=1$/;\"\tv\nloaded_hgcommand\tinput.vim\t/^let loaded_hgcommand = 1$/;\"\tv\nloaded_hgcommand\tinput.vim\t/^let loaded_hgcommand=2$/;\"\tv\ns:HGAdd\tinput.vim\t/^function! s:HGAdd()$/;\"\tf\ns:HGAnnotate\tinput.vim\t/^function! s:HGAnnotate(...)$/;\"\tf\ns:HGBufferCheck\tinput.vim\t/^function! s:HGBufferCheck(hgBuffer)$/;\"\tf\ns:HGChangeToCurrentFileDir\tinput.vim\t/^function! s:HGChangeToCurrentFileDir(fileName)$/;\"\tf\ns:HGCommandEditFileRunning\tinput.vim\t/^let s:HGCommandEditFileRunning = 0$/;\"\tv\ns:HGCommit\tinput.vim\t/^function! s:HGCommit(...)$/;\"\tf\ns:HGCreateCommandBuffer\tinput.vim\t/^function! s:HGCreateCommandBuffer(cmd, cmdName, statusText, origBuffNR)$/;\"\tf\ns:HGCurrentBufferCheck\tinput.vim\t/^function! s:HGCurrentBufferCheck()$/;\"\tf\ns:HGDiff\tinput.vim\t/^function! s:HGDiff(...)$/;\"\tf\ns:HGDoCommand\tinput.vim\t/^function! s:HGDoCommand(cmd, cmdName, statusText)$/;\"\tf\ns:HGEditFile\tinput.vim\t/^function! s:HGEditFile(name, origBuffNR)$/;\"\tf\ns:HGFinishCommit\tinput.vim\t/^function! s:HGFinishCommit(messageFile, targetDir, targetFile, origBuffNR)$/;\"\tf\ns:HGGetOption\tinput.vim\t/^function! s:HGGetOption(name, default)$/;\"\tf\ns:HGGetStatusVars\tinput.vim\t/^function! s:HGGetStatusVars(revisionVar, branchVar, repositoryVar)$/;\"\tf\ns:HGGotoOriginal\tinput.vim\t/^function! s:HGGotoOriginal(...)$/;\"\tf\ns:HGInstallDocumentation\tinput.vim\t/^function! s:HGInstallDocumentation(full_name, revision)$/;\"\tf\ns:HGLog\tinput.vim\t/^function! s:HGLog(...)$/;\"\tf\ns:HGMarkOrigBufferForSetup\tinput.vim\t/^function! s:HGMarkOrigBufferForSetup(hgBuffer)$/;\"\tf\ns:HGOverrideOption\tinput.vim\t/^function! s:HGOverrideOption(option, ...)$/;\"\tf\ns:HGResolveLink\tinput.vim\t/^function! s:HGResolveLink(fileName)$/;\"\tf\ns:HGRevert\tinput.vim\t/^function! s:HGRevert()$/;\"\tf\ns:HGReview\tinput.vim\t/^function! s:HGReview(...)$/;\"\tf\ns:HGSetupBuffer\tinput.vim\t/^function! s:HGSetupBuffer()$/;\"\tf\ns:HGStatus\tinput.vim\t/^function! s:HGStatus()$/;\"\tf\ns:HGToggleDeleteOnHide\tinput.vim\t/^function! s:HGToggleDeleteOnHide()$/;\"\tf\ns:HGUpdate\tinput.vim\t/^function! s:HGUpdate()$/;\"\tf\ns:HGVimDiff\tinput.vim\t/^function! s:HGVimDiff(...)$/;\"\tf\ns:HGVimDiffRestore\tinput.vim\t/^function! s:HGVimDiffRestore(vimDiffBuff)$/;\"\tf\ns:HGWipeoutCommandBuffers\tinput.vim\t/^function! s:HGWipeoutCommandBuffers(originalBuffer, hgCommand)$/;\"\tf\ns:revision\tinput.vim\t/^  let s:revision=\"0.1\"$/;\"\tv\n"
  },
  {
    "path": "Units/parser-vim.r/3214129.vim.d/input.vim",
    "content": "\" vim600: set foldmethod=marker:\n\"\n\" Vim plugin to assist in working with HG-controlled files.\n\"\n\" Last Change:   2006/02/22\n\" Version:       1.76\n\" Maintainer:    Mathieu Clabaut <mathieu.clabaut@gmail.com>\n\" License:       This file is placed in the public domain.\n\" Credits:\n\"                Bob Hiestand <bob.hiestand@gmail.com> for the fabulous\n\"                cvscommand.vim from which this script was directly created by\n\"                means of sed commands and minor tweaks.\n\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\"\n\" Section: Documentation \n\"----------------------------\n\"\n\" Documentation should be available by \":help hgcommand\" command, once the\n\" script has been copied in you .vim/plugin directory.\n\"\n\" You still can read the documentation at the end of this file. Locate it by\n\" searching the \"hgcommand-contents\" string (and set ft=help to have\n\" appropriate syntaxic coloration). \n\n\" Section: Plugin header {{{1\n\n\" loaded_hgcommand is set to 1 when the initialization begins, and 2 when it\n\" completes.  This allows various actions to only be taken by functions after\n\" system initialization.\n\nif exists(\"loaded_hgcommand\")\n   finish\nendif\nlet loaded_hgcommand = 1\n\nif v:version < 602\n  echohl WarningMsg|echomsg \"HGCommand 1.69 or later requires VIM 6.2 or later\"|echohl None\n  finish\nendif\n\n\" Section: Event group setup {{{1\n\naugroup HGCommand\naugroup END\n\n\" Section: Plugin initialization {{{1\nsilent do HGCommand User HGPluginInit\n\n\" Section: Script variable initialization {{{1\n\nlet s:HGCommandEditFileRunning = 0\nunlet! s:vimDiffRestoreCmd\nunlet! s:vimDiffSourceBuffer\nunlet! s:vimDiffBufferCount\nunlet! s:vimDiffScratchList\n\n\" Section: Utility functions {{{1\n\n\" Function: s:HGResolveLink() {{{2\n\" Fully resolve the given file name to remove shortcuts or symbolic links.\n\nfunction! s:HGResolveLink(fileName)\n  let resolved = resolve(a:fileName)\n  if resolved != a:fileName\n    let resolved = s:HGResolveLink(resolved)\n  endif\n  return resolved\nendfunction\n\n\" Function: s:HGChangeToCurrentFileDir() {{{2\n\" Go to the directory in which the current HG-controlled file is located.\n\" If this is a HG command buffer, first switch to the original file.\n\nfunction! s:HGChangeToCurrentFileDir(fileName)\n  let oldCwd=getcwd()\n  let fileName=s:HGResolveLink(a:fileName)\n  let newCwd=fnamemodify(fileName, ':h')\n  if strlen(newCwd) > 0\n    execute 'cd' escape(newCwd, ' ')\n  endif\n  return oldCwd\nendfunction\n\n\" Function: s:HGGetOption(name, default) {{{2\n\" Grab a user-specified option to override the default provided.  Options are\n\" searched in the window, buffer, then global spaces.\n\nfunction! s:HGGetOption(name, default)\n  if exists(\"s:\" . a:name . \"Override\")\n    execute \"return s:\".a:name.\"Override\"\n  elseif exists(\"w:\" . a:name)\n    execute \"return w:\".a:name\n  elseif exists(\"b:\" . a:name)\n    execute \"return b:\".a:name\n  elseif exists(\"g:\" . a:name)\n    execute \"return g:\".a:name\n  else\n    return a:default\n  endif\nendfunction\n\n\" Function: s:HGEditFile(name, origBuffNR) {{{2\n\" Wrapper around the 'edit' command to provide some helpful error text if the\n\" current buffer can't be abandoned.  If name is provided, it is used;\n\" otherwise, a nameless scratch buffer is used.\n\" Returns: 0 if successful, -1 if an error occurs.\n\nfunction! s:HGEditFile(name, origBuffNR)\n  \"Name parameter will be pasted into expression.\n  let name = escape(a:name, ' *?\\')\n\n  let editCommand = s:HGGetOption('HGCommandEdit', 'edit')\n  if editCommand != 'edit'\n    if s:HGGetOption('HGCommandSplit', 'horizontal') == 'horizontal'\n      if name == \"\"\n        let editCommand = 'rightbelow new'\n      else\n        let editCommand = 'rightbelow split ' . name\n      endif\n    else\n      if name == \"\"\n        let editCommand = 'vert rightbelow new'\n      else\n        let editCommand = 'vert rightbelow split ' . name\n      endif\n    endif\n  else\n    if name == \"\"\n      let editCommand = 'enew'\n    else\n      let editCommand = 'edit ' . name\n    endif\n  endif\n\n  \" Protect against useless buffer set-up\n  let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1\n  try\n    execute editCommand\n  finally\n    let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1\n  endtry\n\n  let b:HGOrigBuffNR=a:origBuffNR\n  let b:HGCommandEdit='split'\nendfunction\n\n\" Function: s:HGCreateCommandBuffer(cmd, cmdName, statusText, filename) {{{2\n\" Creates a new scratch buffer and captures the output from execution of the\n\" given command.  The name of the scratch buffer is returned.\n\nfunction! s:HGCreateCommandBuffer(cmd, cmdName, statusText, origBuffNR)\n  let fileName=bufname(a:origBuffNR)\n\n  let resultBufferName=''\n\n  if s:HGGetOption(\"HGCommandNameResultBuffers\", 0)\n    let nameMarker = s:HGGetOption(\"HGCommandNameMarker\", '_')\n    if strlen(a:statusText) > 0\n      let bufName=a:cmdName . ' -- ' . a:statusText\n    else\n      let bufName=a:cmdName\n    endif\n    let bufName=fileName . ' ' . nameMarker . bufName . nameMarker\n    let counter=0\n    let resultBufferName = bufName\n    while buflisted(resultBufferName)\n      let counter=counter + 1\n      let resultBufferName=bufName . ' (' . counter . ')'\n    endwhile\n  endif\n\n  let hgCommand = s:HGGetOption(\"HGCommandHGExec\", \"hg\") . \" \" . a:cmd\n  echomsg \"DBG :\".hgCommand\n  let hgOut = system(hgCommand)\n  \" HACK:  diff command does not return proper error codes\n  if v:shell_error && a:cmdName != 'hgdiff'\n    if strlen(hgOut) == 0\n      echoerr \"HG command failed\"\n    else\n      echoerr \"HG command failed:  \" . hgOut\n    endif\n    return -1\n  endif\n  if strlen(hgOut) == 0\n    \" Handle case of no output.  In this case, it is important to check the\n    \" file status, especially since hg edit/unedit may change the attributes\n    \" of the file with no visible output.\n\n    echomsg \"No output from HG command\"\n    checktime\n    return -1\n  endif\n\n  if s:HGEditFile(resultBufferName, a:origBuffNR) == -1\n    return -1\n  endif\n\n  set buftype=nofile\n  set noswapfile\n  set filetype=\n\n  if s:HGGetOption(\"HGCommandDeleteOnHide\", 0)\n    set bufhidden=delete\n  endif\n\n  silent 0put=hgOut\n\n  \" The last command left a blank line at the end of the buffer.  If the\n  \" last line is folded (a side effect of the 'put') then the attempt to\n  \" remove the blank line will kill the last fold.\n  \"\n  \" This could be fixed by explicitly detecting whether the last line is\n  \" within a fold, but I prefer to simply unfold the result buffer altogether.\n\n  if has('folding')\n    normal zR\n  endif\n\n  $d\n  1\n\n  \" Define the environment and execute user-defined hooks.\n\n  let b:HGSourceFile=fileName\n  let b:HGCommand=a:cmdName\n  if a:statusText != \"\"\n    let b:HGStatusText=a:statusText\n  endif\n\n  silent do HGCommand User HGBufferCreated\n  return bufnr(\"%\")\nendfunction\n\n\" Function: s:HGBufferCheck(hgBuffer) {{{2\n\" Attempts to locate the original file to which HG operations were applied\n\" for a given buffer.\n\nfunction! s:HGBufferCheck(hgBuffer)\n  let origBuffer = getbufvar(a:hgBuffer, \"HGOrigBuffNR\")\n  if origBuffer\n    if bufexists(origBuffer)\n      return origBuffer\n    else\n      \" Original buffer no longer exists.\n      return -1 \n    endif\n  else\n    \" No original buffer\n    return a:hgBuffer\n  endif\nendfunction\n\n\" Function: s:HGCurrentBufferCheck() {{{2\n\" Attempts to locate the original file to which HG operations were applied\n\" for the current buffer.\n\nfunction! s:HGCurrentBufferCheck()\n  return s:HGBufferCheck(bufnr(\"%\"))\nendfunction\n\n\" Function: s:HGToggleDeleteOnHide() {{{2\n\" Toggles on and off the delete-on-hide behavior of HG buffers\n\nfunction! s:HGToggleDeleteOnHide()\n  if exists(\"g:HGCommandDeleteOnHide\")\n    unlet g:HGCommandDeleteOnHide\n  else\n    let g:HGCommandDeleteOnHide=1\n  endif\nendfunction\n\n\" Function: s:HGDoCommand(hgcmd, cmdName, statusText) {{{2\n\" General skeleton for HG function execution.\n\" Returns: name of the new command buffer containing the command results\n\nfunction! s:HGDoCommand(cmd, cmdName, statusText)\n  let hgBufferCheck=s:HGCurrentBufferCheck()\n  if hgBufferCheck == -1 \n    echo \"Original buffer no longer exists, aborting.\"\n    return -1\n  endif\n\n  let fileName=bufname(hgBufferCheck)\n  if isdirectory(fileName)\n    let fileName=fileName . \"/\" . getline(\".\")\n  endif\n  let realFileName = fnamemodify(s:HGResolveLink(fileName), ':t')\n  let oldCwd=s:HGChangeToCurrentFileDir(fileName)\n  try\n     \" TODO\n    \"if !filereadable('HG/Root')\n      \"throw fileName . ' is not a HG-controlled file.'\n    \"endif\n    let fullCmd = a:cmd . ' \"' . realFileName . '\"'\n    \"echomsg \"DEBUG\".fullCmd\n    let resultBuffer=s:HGCreateCommandBuffer(fullCmd, a:cmdName, a:statusText, hgBufferCheck)\n    return resultBuffer\n  catch\n    echoerr v:exception\n    return -1\n  finally\n    execute 'cd' escape(oldCwd, ' ')\n  endtry\nendfunction\n\n\n\" Function: s:HGGetStatusVars(revision, branch, repository) {{{2\n\"\n\" Obtains a HG revision number and branch name.  The 'revisionVar',\n\" 'branchVar'and 'repositoryVar' arguments, if non-empty, contain the names of variables to hold\n\" the corresponding results.\n\"\n\" Returns: string to be exec'd that sets the multiple return values.\n\nfunction! s:HGGetStatusVars(revisionVar, branchVar, repositoryVar)\n  let hgBufferCheck=s:HGCurrentBufferCheck()\n  if hgBufferCheck == -1 \n    return \"\"\n  endif\n  let fileName=bufname(hgBufferCheck)\n  let realFileName = fnamemodify(s:HGResolveLink(fileName), ':t')\n  let oldCwd=s:HGChangeToCurrentFileDir(fileName)\n  try\n     \"\"TODO\n    \"if !filereadable('HG/Root')\n      \"return \"\"\n    \"endif\n    let hgCommand = s:HGGetOption(\"HGCommandHGExec\", \"hg\") . \" status -mardui \" . fileName\n    let statustext=system(hgCommand)\n    if(v:shell_error)\n      return \"\"\n    endif\n    if match(statustext, '^[?I]') >= 0 \n      let revision=\"NEW\"\n    elseif match(statustext, '^[R]') >= 0 \n      let revision=\"REMOVED\"\n    elseif match(statustext, '^[D]') >= 0 \n      let revision=\"DELETED\"\n    elseif match(statustext, '^[A]') >= 0 \n      let revision=\"ADDED\"\n    endif\n\n    let hgCommand = s:HGGetOption(\"HGCommandHGExec\", \"hg\") . \" parents -b  \" \n    let statustext=system(hgCommand)\n    if(v:shell_error)\n        return \"\"\n    endif\n    if exists('revision')\n      let returnExpression = \"let \" . a:revisionVar . \"='\" . revision . \"'\"\n    else\n      let revision=substitute(statustext, '^changeset:\\s*\\(\\d\\+\\):.*\\_$\\_.*$', '\\1', \"\")\n      let returnExpression = \"let \" . a:revisionVar . \"='\" . revision . \"'\"\n    endif\n\n    if a:branchVar != \"\" && match(statustext, '^\\_.*\\_^branch:') >= 0\n      let branch=substitute(statustext, '^\\_.*\\_^branch:\\s*\\(\\S\\+\\)\\n\\_.*$', '\\1', \"\")\n      let returnExpression=returnExpression . \" | let \" . a:branchVar . \"='\" . branch . \"'\"\n    endif\n    if a:repositoryVar != \"\"\n      let hgCommand = s:HGGetOption(\"HGCommandHGExec\", \"hg\") . \" root  \" \n      let roottext=system(hgCommand)\n      let repository=substitute(roottext,'^.*/\\([^/\\n\\r]*\\)\\n\\_.*$','\\1','')\n      let returnExpression=returnExpression . \" | let \" . a:repositoryVar . \"='\" . repository . \"'\"\n    endif\n\n\n\n    return returnExpression\n  finally\n    execute 'cd' escape(oldCwd, ' ')\n  endtry\nendfunction\n\n\" Function: s:HGSetupBuffer() {{{2\n\" Attempts to set the b:HGBranch, b:HGRevision and b:HGRepository variables.\n\nfunction! s:HGSetupBuffer()\n  if (exists(\"b:HGBufferSetup\") && b:HGBufferSetup)\n    \" This buffer is already set up.\n    return\n  endif\n\n  if !s:HGGetOption(\"HGCommandEnableBufferSetup\", 0)\n        \\ || @% == \"\"\n        \\ || s:HGCommandEditFileRunning > 0\n        \\ || exists(\"b:HGOrigBuffNR\")\n    unlet! b:HGRevision\n    unlet! b:HGBranch\n    unlet! b:HGRepository\n    return\n  endif\n\n  if !filereadable(expand(\"%\"))\n    return -1\n  endif\n\n  let revision=\"\"\n  let branch=\"\"\n  let repository=\"\"\n\n  exec s:HGGetStatusVars('revision', 'branch', 'repository')\n  \"echomsg \"DBG \".revision.\"#\".branch.\"#\".repository\n  if revision != \"\"\n    let b:HGRevision=revision\n  else\n    unlet! b:HGRevision\n  endif\n  if branch != \"\"\n    let b:HGBranch=branch\n  else\n    unlet! b:HGBranch\n  endif\n  if repository != \"\"\n     let b:HGRepository=repository\n  else\n     unlet! b:HGRepository\n  endif\n  silent do HGCommand User HGBufferSetup\n  let b:HGBufferSetup=1\nendfunction\n\n\" Function: s:HGMarkOrigBufferForSetup(hgbuffer) {{{2\n\" Resets the buffer setup state of the original buffer for a given HG buffer.\n\" Returns:  The HG buffer number in a passthrough mode.\n\nfunction! s:HGMarkOrigBufferForSetup(hgBuffer)\n  checktime\n  if a:hgBuffer != -1\n    let origBuffer = s:HGBufferCheck(a:hgBuffer)\n    \"This should never not work, but I'm paranoid\n    if origBuffer != a:hgBuffer\n      call setbufvar(origBuffer, \"HGBufferSetup\", 0)\n    endif\n  endif\n  return a:hgBuffer\nendfunction\n\n\" Function: s:HGOverrideOption(option, [value]) {{{2\n\" Provides a temporary override for the given HG option.  If no value is\n\" passed, the override is disabled.\n\nfunction! s:HGOverrideOption(option, ...)\n  if a:0 == 0\n    unlet! s:{a:option}Override\n  else\n    let s:{a:option}Override = a:1\n  endif\nendfunction\n\n\" Function: s:HGWipeoutCommandBuffers() {{{2\n\" Clears all current HG buffers of the specified type for a given source.\n\nfunction! s:HGWipeoutCommandBuffers(originalBuffer, hgCommand)\n  let buffer = 1\n  while buffer <= bufnr('$')\n    if getbufvar(buffer, 'HGOrigBuffNR') == a:originalBuffer\n      if getbufvar(buffer, 'HGCommand') == a:hgCommand\n        execute 'bw' buffer\n      endif\n    endif\n    let buffer = buffer + 1\n  endwhile\nendfunction\n\n\" Function: s:HGInstallDocumentation(full_name, revision)              {{{2\n\"   Install help documentation.\n\" Arguments:\n\"   full_name: Full name of this vim plugin script, including path name.\n\"   revision:  Revision of the vim script. #version# mark in the document file\n\"              will be replaced with this string with 'v' prefix.\n\" Return:\n\"   1 if new document installed, 0 otherwise.\n\" Note: Cleaned and generalized by guo-peng Wen\n\"'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''\n\nfunction! s:HGInstallDocumentation(full_name, revision)\n    \" Name of the document path based on the system we use:\n    if (has(\"unix\"))\n        \" On UNIX like system, using forward slash:\n        let l:slash_char = '/'\n        let l:mkdir_cmd  = ':silent !mkdir -p '\n    else\n        \" On M$ system, use backslash. Also mkdir syntax is different.\n        \" This should only work on W2K and up.\n        let l:slash_char = '\\'\n        let l:mkdir_cmd  = ':silent !mkdir '\n    endif\n\n    let l:doc_path = l:slash_char . 'doc'\n    let l:doc_home = l:slash_char . '.vim' . l:slash_char . 'doc'\n\n    \" Figure out document path based on full name of this script:\n    let l:vim_plugin_path = fnamemodify(a:full_name, ':h')\n    let l:vim_doc_path    = fnamemodify(a:full_name, ':h:h') . l:doc_path\n    if (!(filewritable(l:vim_doc_path) == 2))\n        echomsg \"Doc path: \" . l:vim_doc_path\n        execute l:mkdir_cmd . '\"' . l:vim_doc_path . '\"'\n        if (!(filewritable(l:vim_doc_path) == 2))\n            \" Try a default configuration in user home:\n            let l:vim_doc_path = expand(\"~\") . l:doc_home\n            if (!(filewritable(l:vim_doc_path) == 2))\n                execute l:mkdir_cmd . '\"' . l:vim_doc_path . '\"'\n                if (!(filewritable(l:vim_doc_path) == 2))\n                    \" Put a warning:\n                    echomsg \"Unable to open documentation directory\"\n                    echomsg \" type :help add-local-help for more informations.\"\n                    return 0\n                endif\n            endif\n        endif\n    endif\n\n    \" Exit if we have problem to access the document directory:\n    if (!isdirectory(l:vim_plugin_path)\n        \\ || !isdirectory(l:vim_doc_path)\n        \\ || filewritable(l:vim_doc_path) != 2)\n        return 0\n    endif\n\n    \" Full name of script and documentation file:\n    let l:script_name = fnamemodify(a:full_name, ':t')\n    let l:doc_name    = fnamemodify(a:full_name, ':t:r') . '.txt'\n    let l:plugin_file = l:vim_plugin_path . l:slash_char . l:script_name\n    let l:doc_file    = l:vim_doc_path    . l:slash_char . l:doc_name\n\n    \" Bail out if document file is still up to date:\n    if (filereadable(l:doc_file)  &&\n        \\ getftime(l:plugin_file) < getftime(l:doc_file))\n        return 0\n    endif\n\n    \" Prepare window position restoring command:\n    if (strlen(@%))\n        let l:go_back = 'b ' . bufnr(\"%\")\n    else\n        let l:go_back = 'enew!'\n    endif\n\n    \" Create a new buffer & read in the plugin file (me):\n    setl nomodeline\n    exe 'enew!'\n    exe 'r ' . l:plugin_file\n\n    setl modeline\n    let l:buf = bufnr(\"%\")\n    setl noswapfile modifiable\n\n    norm zR\n    norm gg\n\n    \" Delete from first line to a line starts with\n    \" === START_DOC\n    1,/^=\\{3,}\\s\\+START_DOC\\C/ d\n\n    \" Delete from a line starts with\n    \" === END_DOC\n    \" to the end of the documents:\n    /^=\\{3,}\\s\\+END_DOC\\C/,$ d\n\n    \" Remove fold marks:\n    %s/{\\{3}[1-9]/    /\n\n    \" Add modeline for help doc: the modeline string is mangled intentionally\n    \" to avoid it be recognized by VIM:\n    call append(line('$'), '')\n    call append(line('$'), ' v' . 'im:tw=78:ts=8:ft=help:norl:')\n\n    \" Replace revision:\n    exe \"normal :1s/#version#/ v\" . a:revision . \"/\\<CR>\"\n\n    \" Save the help document:\n    exe 'w! ' . l:doc_file\n    exe l:go_back\n    exe 'bw ' . l:buf\n\n    \" Build help tags:\n    exe 'helptags ' . l:vim_doc_path\n\n    return 1\nendfunction\n\n\" Section: Public functions {{{1\n\n\" Function: HGGetRevision() {{{2\n\" Global function for retrieving the current buffer's HG revision number.\n\" Returns: Revision number or an empty string if an error occurs.\n\nfunction! HGGetRevision()\n  let revision=\"\"\n  exec s:HGGetStatusVars('revision', '', '')\n  return revision\nendfunction\n\n\" Function: HGDisableBufferSetup() {{{2\n\" Global function for deactivating the buffer autovariables.\n\nfunction! HGDisableBufferSetup()\n  let g:HGCommandEnableBufferSetup=0\n  silent! augroup! HGCommandPlugin\nendfunction\n\n\" Function: HGEnableBufferSetup() {{{2\n\" Global function for activating the buffer autovariables.\n\nfunction! HGEnableBufferSetup()\n  let g:HGCommandEnableBufferSetup=1\n  augroup HGCommandPlugin\n    au!\n    au BufEnter * call s:HGSetupBuffer()\n  augroup END\n\n  \" Only auto-load if the plugin is fully loaded.  This gives other plugins a\n  \" chance to run.\n  if g:loaded_hgcommand == 2\n    call s:HGSetupBuffer()\n  endif\nendfunction\n\n\" Function: HGGetStatusLine() {{{2\n\" Default (sample) status line entry for HG files.  This is only useful if\n\" HG-managed buffer mode is on (see the HGCommandEnableBufferSetup variable\n\" for how to do this).\n\nfunction! HGGetStatusLine()\n  if exists('b:HGSourceFile')\n    \" This is a result buffer\n    let value='[' . b:HGCommand . ' ' . b:HGSourceFile\n    if exists('b:HGStatusText')\n      let value=value . ' ' . b:HGStatusText\n    endif\n    let value = value . ']'\n    return value\n  endif\n\n  if exists('b:HGRevision')\n        \\ && b:HGRevision != ''\n        \\ && exists('b:HGBranch')\n        \\ && b:HGBranch != ''\n        \\ && exists('b:HGRepository')\n        \\ && b:HGRepository != ''\n        \\ && exists('g:HGCommandEnableBufferSetup')\n        \\ && g:HGCommandEnableBufferSetup\n   return '[HG ' . b:HGRepository . '/' . b:HGBranch .'/' . b:HGRevision . ']'\n  else\n    return ''\n  endif\nendfunction\n\n\" Section: HG command functions {{{1\n\n\" Function: s:HGAdd() {{{2\nfunction! s:HGAdd()\n  return s:HGMarkOrigBufferForSetup(s:HGDoCommand('add', 'hgadd', ''))\nendfunction\n\n\" Function: s:HGAnnotate(...) {{{2\nfunction! s:HGAnnotate(...)\n  if a:0 == 0\n    if &filetype == \"HGAnnotate\"\n      \" This is a HGAnnotate buffer.  Perform annotation of the version\n      \" indicated by the current line.\n      let revision = substitute(getline(\".\"),'\\(^[0-9]*\\):.*','\\1','')\n      if s:HGGetOption('HGCommandAnnotateParent', 0) != 0 && revision > 0\n        let revision = revision - 1\n      endif\n    else\n      let revision=HGGetRevision()\n      if revision == \"\"\n        echoerr \"Unable to obtain HG version information.\"\n        return -1\n      endif\n    endif\n  else\n    let revision=a:1\n  endif\n\n  if revision == \"NEW\"\n    echo \"No annotatation available for new file.\"\n    return -1\n  endif\n\n  let resultBuffer=s:HGDoCommand('annotate -ndu -r ' . revision, 'hgannotate', revision) \n  echomsg \"DBG: \".resultBuffer\n  if resultBuffer !=  -1\n    set filetype=HGAnnotate\n  endif\n\n  return resultBuffer\nendfunction\n\n\" Function: s:HGCommit() {{{2\nfunction! s:HGCommit(...)\n  \" Handle the commit message being specified.  If a message is supplied, it\n  \" is used; if bang is supplied, an empty message is used; otherwise, the\n  \" user is provided a buffer from which to edit the commit message.\n  if a:2 != \"\" || a:1 == \"!\"\n    return s:HGMarkOrigBufferForSetup(s:HGDoCommand('commit -m \"' . a:2 . '\"', 'hgcommit', ''))\n  endif\n\n  let hgBufferCheck=s:HGCurrentBufferCheck()\n  if hgBufferCheck ==  -1\n    echo \"Original buffer no longer exists, aborting.\"\n    return -1\n  endif\n\n  \" Protect against windows' backslashes in paths.  They confuse exec'd\n  \" commands.\n\n  let shellSlashBak = &shellslash\n  try\n    set shellslash\n\n    let messageFileName = tempname()\n\n    let fileName=bufname(hgBufferCheck)\n    let realFilePath=s:HGResolveLink(fileName)\n    let newCwd=fnamemodify(realFilePath, ':h')\n    if strlen(newCwd) == 0\n      \" Account for autochdir being in effect, which will make this blank, but\n      \" we know we'll be in the current directory for the original file.\n      let newCwd = getcwd()\n    endif\n\n    let realFileName=fnamemodify(realFilePath, ':t')\n\n    if s:HGEditFile(messageFileName, hgBufferCheck) == -1\n      return\n    endif\n\n    \" Protect against case and backslash issues in Windows.\n    let autoPattern = '\\c' . messageFileName\n\n    \" Ensure existence of group\n    augroup HGCommit\n    augroup END\n\n    execute 'au HGCommit BufDelete' autoPattern 'call delete(\"' . messageFileName . '\")'\n    execute 'au HGCommit BufDelete' autoPattern 'au! HGCommit * ' autoPattern\n\n    \" Create a commit mapping.  The mapping must clear all autocommands in case\n    \" it is invoked when HGCommandCommitOnWrite is active, as well as to not\n    \" invoke the buffer deletion autocommand.\n\n    execute 'nnoremap <silent> <buffer> <Plug>HGCommit '.\n          \\ ':au! HGCommit * ' . autoPattern . '<CR>'.\n          \\ ':g/^HG:/d<CR>'.\n          \\ ':update<CR>'.\n          \\ ':call <SID>HGFinishCommit(\"' . messageFileName . '\",' .\n          \\                             '\"' . newCwd . '\",' .\n          \\                             '\"' . realFileName . '\",' .\n          \\                             hgBufferCheck . ')<CR>'\n\n    silent 0put ='HG: ----------------------------------------------------------------------'\n    silent put =\\\"HG: Enter Log.  Lines beginning with `HG:' are removed automatically\\\"\n    silent put ='HG: Type <leader>cc (or your own <Plug>HGCommit mapping)'\n\n    if s:HGGetOption('HGCommandCommitOnWrite', 1) == 1\n      execute 'au HGCommit BufWritePre' autoPattern 'g/^HG:/d'\n      execute 'au HGCommit BufWritePost' autoPattern 'call s:HGFinishCommit(\"' . messageFileName . '\", \"' . newCwd . '\", \"' . realFileName . '\", ' . hgBufferCheck . ') | au! * ' autoPattern\n      silent put ='HG: or write this buffer'\n    endif\n\n    silent put ='HG: to finish this commit operation'\n    silent put ='HG: ----------------------------------------------------------------------'\n    $\n    let b:HGSourceFile=fileName\n    let b:HGCommand='HGCommit'\n    set filetype=hg\n  finally\n    let &shellslash = shellSlashBak\n  endtry\n\nendfunction\n\n\" Function: s:HGDiff(...) {{{2\nfunction! s:HGDiff(...)\n  if a:0 == 1\n    let revOptions = '-r' . a:1\n    let caption = a:1 . ' -> current'\n  elseif a:0 == 2\n    let revOptions = '-r' . a:1 . ' -r' . a:2\n    let caption = a:1 . ' -> ' . a:2\n  else\n    let revOptions = ''\n    let caption = ''\n  endif\n\n  let hgdiffopt=s:HGGetOption('HGCommandDiffOpt', 'w')\n\n  if hgdiffopt == \"\"\n    let diffoptionstring=\"\"\n  else\n    let diffoptionstring=\" -\" . hgdiffopt . \" \"\n  endif\n\n  let resultBuffer = s:HGDoCommand('diff ' . diffoptionstring . revOptions , 'hgdiff', caption)\n  if resultBuffer != -1 \n    set filetype=diff\n  endif\n  return resultBuffer\nendfunction\n\n\n\" Function: s:HGGotoOriginal([\"!]) {{{2\nfunction! s:HGGotoOriginal(...)\n  let origBuffNR = s:HGCurrentBufferCheck()\n  if origBuffNR > 0\n    let origWinNR = bufwinnr(origBuffNR)\n    if origWinNR == -1\n      execute 'buffer' origBuffNR\n    else\n      execute origWinNR . 'wincmd w'\n    endif\n    if a:0 == 1\n      if a:1 == \"!\"\n        let buffnr = 1\n        let buffmaxnr = bufnr(\"$\")\n        while buffnr <= buffmaxnr\n          if getbufvar(buffnr, \"HGOrigBuffNR\") == origBuffNR\n            execute \"bw\" buffnr\n          endif\n          let buffnr = buffnr + 1\n        endwhile\n      endif\n    endif\n  endif\nendfunction\n\n\" Function: s:HGFinishCommit(messageFile, targetDir, targetFile) {{{2\nfunction! s:HGFinishCommit(messageFile, targetDir, targetFile, origBuffNR)\n  if filereadable(a:messageFile)\n    let oldCwd=getcwd()\n    if strlen(a:targetDir) > 0\n      execute 'cd' escape(a:targetDir, ' ')\n    endif\n    let resultBuffer=s:HGCreateCommandBuffer('commit -F \"' . a:messageFile . '\" \"'. a:targetFile . '\"', 'hgcommit', '', a:origBuffNR)\n    execute 'cd' escape(oldCwd, ' ')\n    execute 'bw' escape(a:messageFile, ' *?\\')\n    silent execute 'call delete(\"' . a:messageFile . '\")'\n    return s:HGMarkOrigBufferForSetup(resultBuffer)\n  else\n    echoerr \"Can't read message file; no commit is possible.\"\n    return -1\n  endif\nendfunction\n\n\" Function: s:HGLog() {{{2\nfunction! s:HGLog(...)\n  if a:0 == 0\n    let versionOption = \"\"\n    let caption = ''\n  else\n    let versionOption=\" -r\" . a:1\n    let caption = a:1\n  endif\n\n  let resultBuffer=s:HGDoCommand('log' . versionOption, 'hglog', caption)\n  if resultBuffer != \"\"\n    set filetype=rcslog\n  endif\n  return resultBuffer\nendfunction\n\n\" Function: s:HGRevert() {{{2\nfunction! s:HGRevert()\n  return s:HGMarkOrigBufferForSetup(s:HGDoCommand('revert', 'hgrevert', ''))\nendfunction\n\n\" Function: s:HGReview(...) {{{2\nfunction! s:HGReview(...)\n  if a:0 == 0\n    let versiontag=\"\"\n    if s:HGGetOption('HGCommandInteractive', 0)\n      let versiontag=input('Revision:  ')\n    endif\n    if versiontag == \"\"\n      let versiontag=\"(current)\"\n      let versionOption=\"\"\n    else\n      let versionOption=\" -r \" . versiontag . \" \"\n    endif\n  else\n    let versiontag=a:1\n    let versionOption=\" -r \" . versiontag . \" \"\n  endif\n\n  let resultBuffer = s:HGDoCommand('cat' . versionOption, 'hgreview', versiontag)\n  if resultBuffer > 0\n    let &filetype=getbufvar(b:HGOrigBuffNR, '&filetype')\n  endif\n\n  return resultBuffer\nendfunction\n\n\" Function: s:HGStatus() {{{2\nfunction! s:HGStatus()\n  return s:HGDoCommand('status', 'hgstatus', '')\nendfunction\n\n\n\" Function: s:HGUpdate() {{{2\nfunction! s:HGUpdate()\n  return s:HGMarkOrigBufferForSetup(s:HGDoCommand('update', 'update', ''))\nendfunction\n\n\" Function: s:HGVimDiff(...) {{{2\nfunction! s:HGVimDiff(...)\n  let originalBuffer = s:HGCurrentBufferCheck()\n  let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1\n  try\n    \" If there's already a VimDiff'ed window, restore it.\n    \" There may only be one HGVimDiff original window at a time.\n\n    if exists(\"s:vimDiffSourceBuffer\") && s:vimDiffSourceBuffer != originalBuffer\n      \" Clear the existing vimdiff setup by removing the result buffers.\n      call s:HGWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff')\n    endif\n\n    \" Split and diff\n    if(a:0 == 2)\n      \" Reset the vimdiff system, as 2 explicit versions were provided.\n      if exists('s:vimDiffSourceBuffer')\n        call s:HGWipeoutCommandBuffers(s:vimDiffSourceBuffer, 'vimdiff')\n      endif\n      let resultBuffer = s:HGReview(a:1)\n      if resultBuffer < 0\n        echomsg \"Can't open HG revision \" . a:1\n        return resultBuffer\n      endif\n      let b:HGCommand = 'vimdiff'\n      diffthis\n      let s:vimDiffBufferCount = 1\n      let s:vimDiffScratchList = '{'. resultBuffer . '}'\n      \" If no split method is defined, cheat, and set it to vertical.\n      try\n        call s:HGOverrideOption('HGCommandSplit', s:HGGetOption('HGCommandDiffSplit', s:HGGetOption('HGCommandSplit', 'vertical')))\n        let resultBuffer=s:HGReview(a:2)\n      finally\n        call s:HGOverrideOption('HGCommandSplit')\n      endtry\n      if resultBuffer < 0\n        echomsg \"Can't open HG revision \" . a:1\n        return resultBuffer\n      endif\n      let b:HGCommand = 'vimdiff'\n      diffthis\n      let s:vimDiffBufferCount = 2\n      let s:vimDiffScratchList = s:vimDiffScratchList . '{'. resultBuffer . '}'\n    else\n      \" Add new buffer\n      try\n        \" Force splitting behavior, otherwise why use vimdiff?\n        call s:HGOverrideOption(\"HGCommandEdit\", \"split\")\n        call s:HGOverrideOption(\"HGCommandSplit\", s:HGGetOption('HGCommandDiffSplit', s:HGGetOption('HGCommandSplit', 'vertical')))\n        if(a:0 == 0)\n          let resultBuffer=s:HGReview()\n        else\n          let resultBuffer=s:HGReview(a:1)\n        endif\n      finally\n        call s:HGOverrideOption(\"HGCommandEdit\")\n        call s:HGOverrideOption(\"HGCommandSplit\")\n      endtry\n      if resultBuffer < 0\n        echomsg \"Can't open current HG revision\"\n        return resultBuffer\n      endif\n      let b:HGCommand = 'vimdiff'\n      diffthis\n\n      if !exists('s:vimDiffBufferCount')\n        \" New instance of vimdiff.\n        let s:vimDiffBufferCount = 2\n        let s:vimDiffScratchList = '{' . resultBuffer . '}'\n\n        \" This could have been invoked on a HG result buffer, not the\n        \" original buffer.\n        wincmd W\n        execute 'buffer' originalBuffer\n        \" Store info for later original buffer restore\n        let s:vimDiffRestoreCmd = \n              \\    \"call setbufvar(\".originalBuffer.\", \\\"&diff\\\", \".getbufvar(originalBuffer, '&diff').\")\"\n              \\ . \"|call setbufvar(\".originalBuffer.\", \\\"&foldcolumn\\\", \".getbufvar(originalBuffer, '&foldcolumn').\")\"\n              \\ . \"|call setbufvar(\".originalBuffer.\", \\\"&foldenable\\\", \".getbufvar(originalBuffer, '&foldenable').\")\"\n              \\ . \"|call setbufvar(\".originalBuffer.\", \\\"&foldmethod\\\", '\".getbufvar(originalBuffer, '&foldmethod').\"')\"\n              \\ . \"|call setbufvar(\".originalBuffer.\", \\\"&scrollbind\\\", \".getbufvar(originalBuffer, '&scrollbind').\")\"\n              \\ . \"|call setbufvar(\".originalBuffer.\", \\\"&wrap\\\", \".getbufvar(originalBuffer, '&wrap').\")\"\n              \\ . \"|if &foldmethod=='manual'|execute 'normal zE'|endif\"\n        diffthis\n        wincmd w\n      else\n        \" Adding a window to an existing vimdiff\n        let s:vimDiffBufferCount = s:vimDiffBufferCount + 1\n        let s:vimDiffScratchList = s:vimDiffScratchList . '{' . resultBuffer . '}'\n      endif\n    endif\n\n    let s:vimDiffSourceBuffer = originalBuffer\n\n    \" Avoid executing the modeline in the current buffer after the autocommand.\n\n    let currentBuffer = bufnr('%')\n    let saveModeline = getbufvar(currentBuffer, '&modeline')\n    try\n      call setbufvar(currentBuffer, '&modeline', 0)\n      silent do HGCommand User HGVimDiffFinish\n    finally\n      call setbufvar(currentBuffer, '&modeline', saveModeline)\n    endtry\n    return resultBuffer\n  finally\n    let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1\n  endtry\nendfunction\n\n\" Section: Command definitions {{{1\n\" Section: Primary commands {{{2\ncom! HGAdd call s:HGAdd()\ncom! -nargs=? HGAnnotate call s:HGAnnotate(<f-args>)\ncom! -bang -nargs=? HGCommit call s:HGCommit(<q-bang>, <q-args>)\ncom! -nargs=* HGDiff call s:HGDiff(<f-args>)\ncom! -bang HGGotoOriginal call s:HGGotoOriginal(<q-bang>)\ncom! -nargs=? HGLog call s:HGLog(<f-args>)\ncom! HGRevert call s:HGRevert()\ncom! -nargs=? HGReview call s:HGReview(<f-args>)\ncom! HGStatus call s:HGStatus()\ncom! HGUpdate call s:HGUpdate()\ncom! -nargs=* HGVimDiff call s:HGVimDiff(<f-args>)\n\n\" Section: HG buffer management commands {{{2\ncom! HGDisableBufferSetup call HGDisableBufferSetup()\ncom! HGEnableBufferSetup call HGEnableBufferSetup()\n\n\" Allow reloading hgcommand.vim\ncom! HGReload unlet! loaded_hgcommand | runtime plugin/hgcommand.vim\n\n\" Section: Plugin command mappings {{{1\nnnoremap <silent> <Plug>HGAdd :HGAdd<CR>\nnnoremap <silent> <Plug>HGAnnotate :HGAnnotate<CR>\nnnoremap <silent> <Plug>HGCommit :HGCommit<CR>\nnnoremap <silent> <Plug>HGDiff :HGDiff<CR>\nnnoremap <silent> <Plug>HGGotoOriginal :HGGotoOriginal<CR>\nnnoremap <silent> <Plug>HGClearAndGotoOriginal :HGGotoOriginal!<CR>\nnnoremap <silent> <Plug>HGLog :HGLog<CR>\nnnoremap <silent> <Plug>HGRevert :HGRevert<CR>\nnnoremap <silent> <Plug>HGReview :HGReview<CR>\nnnoremap <silent> <Plug>HGStatus :HGStatus<CR>\nnnoremap <silent> <Plug>HGUpdate :HGUpdate<CR>\nnnoremap <silent> <Plug>HGVimDiff :HGVimDiff<CR>\nnnoremap <silent> <Plug>HGWatchers :HGWatchers<CR>\nnnoremap <silent> <Plug>HGWatchAdd :HGWatchAdd<CR>\nnnoremap <silent> <Plug>HGWatchOn :HGWatchOn<CR>\nnnoremap <silent> <Plug>HGWatchOff :HGWatchOff<CR>\nnnoremap <silent> <Plug>HGWatchRemove :HGWatchRemove<CR>\n\n\" Section: Default mappings {{{1\nif !hasmapto('<Plug>HGAdd')\n  nmap <unique> <Leader>hga <Plug>HGAdd\nendif\nif !hasmapto('<Plug>HGAnnotate')\n  nmap <unique> <Leader>hgn <Plug>HGAnnotate\nendif\nif !hasmapto('<Plug>HGClearAndGotoOriginal')\n  nmap <unique> <Leader>hgG <Plug>HGClearAndGotoOriginal\nendif\nif !hasmapto('<Plug>HGCommit')\n  nmap <unique> <Leader>hgc <Plug>HGCommit\nendif\nif !hasmapto('<Plug>HGDiff')\n  nmap <unique> <Leader>hgd <Plug>HGDiff\nendif\nif !hasmapto('<Plug>HGGotoOriginal')\n  nmap <unique> <Leader>hgg <Plug>HGGotoOriginal\nendif\nif !hasmapto('<Plug>HGLog')\n  nmap <unique> <Leader>hgl <Plug>HGLog\nendif\nif !hasmapto('<Plug>HGRevert')\n  nmap <unique> <Leader>hgq <Plug>HGRevert\nendif\nif !hasmapto('<Plug>HGReview')\n  nmap <unique> <Leader>hgr <Plug>HGReview\nendif\nif !hasmapto('<Plug>HGStatus')\n  nmap <unique> <Leader>hgs <Plug>HGStatus\nendif\nif !hasmapto('<Plug>HGUpdate')\n  nmap <unique> <Leader>hgu <Plug>HGUpdate\nendif\nif !hasmapto('<Plug>HGVimDiff')\n  nmap <unique> <Leader>hgv <Plug>HGVimDiff\nendif\n\n\" Section: Menu items {{{1\nsilent! aunmenu Plugin.HG\namenu <silent> &Plugin.HG.&Add        <Plug>HGAdd\namenu <silent> &Plugin.HG.A&nnotate   <Plug>HGAnnotate\namenu <silent> &Plugin.HG.&Commit     <Plug>HGCommit\namenu <silent> &Plugin.HG.&Diff       <Plug>HGDiff\namenu <silent> &Plugin.HG.&Log        <Plug>HGLog\namenu <silent> &Plugin.HG.Revert      <Plug>HGRevert\namenu <silent> &Plugin.HG.&Review     <Plug>HGReview\namenu <silent> &Plugin.HG.&Status     <Plug>HGStatus\namenu <silent> &Plugin.HG.&Update     <Plug>HGUpdate\namenu <silent> &Plugin.HG.&VimDiff    <Plug>HGVimDiff\namenu <silent> &Plugin.HG.&Watchers   <Plug>HGWatchers\namenu <silent> &Plugin.HG.WatchAdd    <Plug>HGWatchAdd\namenu <silent> &Plugin.HG.WatchOn     <Plug>HGWatchOn\namenu <silent> &Plugin.HG.WatchOff    <Plug>HGWatchOff\namenu <silent> &Plugin.HG.WatchRemove <Plug>HGWatchRemove\n\n\" Section: Autocommands to restore vimdiff state {{{1\nfunction! s:HGVimDiffRestore(vimDiffBuff)\n  let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning + 1\n  try\n    if exists(\"s:vimDiffSourceBuffer\")\n      if a:vimDiffBuff == s:vimDiffSourceBuffer\n        \" Original file is being removed.\n        unlet! s:vimDiffSourceBuffer\n        unlet! s:vimDiffBufferCount\n        unlet! s:vimDiffRestoreCmd\n        unlet! s:vimDiffScratchList\n      elseif match(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}') >= 0\n        let s:vimDiffScratchList = substitute(s:vimDiffScratchList, '{' . a:vimDiffBuff . '}', '', '')\n        let s:vimDiffBufferCount = s:vimDiffBufferCount - 1\n        if s:vimDiffBufferCount == 1 && exists('s:vimDiffRestoreCmd')\n          \" All scratch buffers are gone, reset the original.\n          \" Only restore if the source buffer is still in Diff mode\n\n          let sourceWinNR=bufwinnr(s:vimDiffSourceBuffer)\n          if sourceWinNR != -1\n            \" The buffer is visible in at least one window\n            let currentWinNR = winnr()\n            while winbufnr(sourceWinNR) != -1\n              if winbufnr(sourceWinNR) == s:vimDiffSourceBuffer\n                execute sourceWinNR . 'wincmd w'\n                if getwinvar('', \"&diff\")\n                  execute s:vimDiffRestoreCmd\n                endif\n              endif\n              let sourceWinNR = sourceWinNR + 1\n            endwhile\n            execute currentWinNR . 'wincmd w'\n          else\n            \" The buffer is hidden.  It must be visible in order to set the\n            \" diff option.\n            let currentBufNR = bufnr('')\n            execute \"hide buffer\" s:vimDiffSourceBuffer\n            if getwinvar('', \"&diff\")\n              execute s:vimDiffRestoreCmd\n            endif\n            execute \"hide buffer\" currentBufNR\n          endif\n\n          unlet s:vimDiffRestoreCmd\n          unlet s:vimDiffSourceBuffer\n          unlet s:vimDiffBufferCount\n          unlet s:vimDiffScratchList\n        elseif s:vimDiffBufferCount == 0\n          \" All buffers are gone.\n          unlet s:vimDiffSourceBuffer\n          unlet s:vimDiffBufferCount\n          unlet s:vimDiffScratchList\n        endif\n      endif\n    endif\n  finally\n    let s:HGCommandEditFileRunning = s:HGCommandEditFileRunning - 1\n  endtry\nendfunction\n\naugroup HGVimDiffRestore\n  au!\n  au BufUnload * call s:HGVimDiffRestore(expand(\"<abuf>\"))\naugroup END\n\n\" Section: Optional activation of buffer management {{{1\n\nif s:HGGetOption('HGCommandEnableBufferSetup', 0)\n  call HGEnableBufferSetup()\nendif\n\n\" Section: Doc installation {{{1\n\"\n  let s:revision=\"0.1\"\n  silent! let s:install_status =\n      \\ s:HGInstallDocumentation(expand('<sfile>:p'), s:revision)\n  if (s:install_status == 1)\n      echom expand(\"<sfile>:t:r\") . ' v' . s:revision .\n\t\t\\ ': Help-documentation installed.'\n  endif\n\n\n\" Section: Plugin completion {{{1\n\nlet loaded_hgcommand=2\nsilent do HGCommand User HGPluginFinish\n\" vim:se expandtab sts=2 sw=2:\nfinish\n\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\" Section: Documentation content                                          {{{1\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n=== START_DOC\n*hgcommand.txt*\t  Mercurial vim integration\t\t             #version#\n\n\n\t\t\t HGCOMMAND REFERENCE MANUAL~\n\n\nAuthor:  Mathieu Clabaut <mathieu.clabaut@gmail.com>\nCredits:  Bob Hiestand <bob.hiestand@gmail.com>\nMercurial: http://www.selenic.com/mercurial\n   Mercurial (noted Hg) is a fast, lightweight Source Control Management\n   system designed for efficient handling of very large distributed projects.\n\n==============================================================================\n1. Contents\t\t\t\t\t\t  *hgcommand-contents*\n\n\tInstallation\t\t: |hgcommand-install|\n        HGCommand Intro\t        : |hgcommand|\n\tHGCommand Manual\t: |hgcommand-manual|\n\tCustomization\t\t: |hgcommand-customize|\n\tBugs\t\t\t: |hgcommand-bugs|\n\n==============================================================================\n2. HGCommand Installation\t\t\t\t   *hgcommand-install*\n\n   In order to install the plugin, place the hgcommand.vim file into a plugin' \n   directory in your runtime path (please see |add-global-plugin| and \n   |'runtimepath'|.\n\n   HGCommand may be customized by setting variables, creating maps, and \n   specifying event handlers.  Please see |hgcommand-customize| for more\n   details.\n\n                                                         *hgcommand-auto-help*\n   The help file is automagically generated when the |hgcommand| script is \n   loaded for the first time.\n\n==============================================================================\n\n3. HGCommand Intro\t\t\t\t\t           *hgcommand*\n                                                             *hgcommand-intro*\n\n   The HGCommand plugin provides global ex commands for manipulating \n   HG-controlled source files.  In general, each command operates on the \n   current buffer and accomplishes a separate hg function, such as update, \n   commit, log, and others (please see |hgcommand-commands| for a list of all\n   available commands).  The results of each operation are displayed in a \n   scratch buffer.  Several buffer variables are defined for those scratch \n   buffers (please see |hgcommand-buffer-variables|).\n\n   The notion of \"current file\" means either the current buffer, or, in the \n   case of a directory buffer, the file on the current line within the buffer.\n\n   For convenience, any HGCommand invoked on a HGCommand scratch buffer acts \n   as though it was invoked on the original file and splits the screen so that \n   the output appears in a new window.\n\n   Many of the commands accept revisions as arguments.  By default, most \n   operate on the most recent revision on the current branch if no revision is \n   specified (though see |HGCommandInteractive| to prompt instead).\n\n   Each HGCommand is mapped to a key sequence starting with the <Leader> \n   keystroke.  The default mappings may be overridden by supplying different \n   mappings before the plugin is loaded, such as in the vimrc, in the standard \n   fashion for plugin mappings.  For examples, please see \n   |hgcommand-mappings-override|.\n\n   The HGCommand plugin may be configured in several ways.  For more details, \n   please see |hgcommand-customize|.\n\n==============================================================================\n4. HGCommand Manual\t\t\t\t\t    *hgcommand-manual*\n\n4.1 HGCommand commands\t\t\t\t\t  *hgcommand-commands*\n\n   HGCommand defines the following commands:\n\n      |:HGAdd|\n      |:HGAnnotate|\n      |:HGCommit|\n      |:HGDiff|\n      |:HGGotoOriginal|\n      |:HGLog|\n      |:HGRevert|\n      |:HGReview|\n      |:HGStatus|\n      |:HGUpdate|\n      |:HGVimDiff|\n\n:HGAdd\t\t\t\t\t\t\t              *:HGAdd*\n\n   This command performs \"hg add\" on the current file.  Please note, this does \n   not commit the newly-added file.\n\n:HGAnnotate\t\t\t\t\t\t         *:HGAnnotate*\n\n   This command performs \"hg annotate\" on the current file.  If an argument is \n   given, the argument is used as a revision number to display.  If not given \n   an argument, it uses the most recent version of the file on the current \n   branch.  Additionally, if the current buffer is a HGAnnotate buffer \n   already, the version number on the current line is used.\n\n   If the |HGCommandAnnotateParent| variable is set to a non-zero value, the \n   version previous to the one on the current line is used instead.  This \n   allows one to navigate back to examine the previous version of a line.\n\n   The filetype of the HGCommand scratch buffer is set to 'HGAnnotate', to \n   take advantage of the bundled syntax file.\n\n\n:HGCommit[!]\t\t\t\t\t\t           *:HGCommit*\n\n   If called with arguments, this performs \"hg commit\" using the arguments as \n   the log message.\n\n   If '!' is used with no arguments, an empty log message is committed.\n\n   If called with no arguments, this is a two-step command.  The first step \n   opens a buffer to accept a log message.  When that buffer is written, it is \n   automatically closed and the file is committed using the information from \n   that log message.  The commit can be abandoned if the log message buffer is \n   deleted or wiped before being written.\n\n   Alternatively, the mapping that is used to invoke :HGCommit (by default \n   <Leader>hgc) can be used in the log message buffer to immediately commit.  \n   This is useful if the |HGCommandCommitOnWrite| variable is set to 0 to \n   disable the normal commit-on-write behavior.\n\n:HGDiff\t\t\t\t\t\t                     *:HGDiff*\n\n   With no arguments, this performs \"hg diff\" on the current file against the \n   current repository version.\n\n   With one argument, \"hg diff\" is performed on the current file against the \n   specified revision.\n\n   With two arguments, hg diff is performed between the specified revisions of \n   the current file.\n\n   This command uses the 'HGCommandDiffOpt' variable to specify diff options.  \n   If that variable does not exist, then 'wbBc' is assumed.  If you wish to \n   have no options, then set it to the empty string.\n\n\n:HGGotoOriginal\t\t\t\t\t             *:HGGotoOriginal*\n\n   This command returns the current window to the source buffer, if the \n   current buffer is a HG command output buffer.\n\n:HGGotoOriginal!\n\n   Like \":HGGotoOriginal\" but also executes :bufwipeout on all HG command \n   output buffers for the source buffer.\n\n:HGLog\t\t\t\t\t\t\t              *:HGLog*\n\n   Performs \"hg log\" on the current file.\n\n   If an argument is given, it is passed as an argument to the \"-r\" option of \n   \"hg log\".\n\n:HGRevert\t\t\t\t\t\t           *:HGRevert*\n\n   Replaces the current file with the most recent version from the repository \n   in order to wipe out any undesired changes.\n \n:HGReview\t\t\t\t\t\t           *:HGReview*\n\n   Retrieves a particular version of the current file.  If no argument is \n   given, the most recent version of the file on the current branch is \n   retrieved.  Otherwise, the specified version is retrieved.\n\n:HGStatus\t\t\t\t\t \t           *:HGStatus*\n\n   Performs \"hg status\" on the current file.\n\n:HGUpdate\t\t\t\t\t\t           *:HGUpdate*\n\n   Performs \"hg update\" on the current file.  This intentionally does not \n   automatically reload the current buffer, though vim should prompt the user \n   to do so if the underlying file is altered by this command.\n\n:HGVimDiff\t\t\t\t\t\t          *:HGVimDiff*\n\n   With no arguments, this prompts the user for a revision and then uses \n   vimdiff to display the differences between the current file and the \n   specified revision.  If no revision is specified, the most recent version \n   of the file on the current branch is used.\n\n   With one argument, that argument is used as the revision as above.  With \n   two arguments, the differences between the two revisions is displayed using \n   vimdiff.\n\n   With either zero or one argument, the original buffer is used to perform \n   the vimdiff.  When the other buffer is closed, the original buffer will be \n   returned to normal mode.\n\n   Once vimdiff mode is started using the above methods, additional vimdiff \n   buffers may be added by passing a single version argument to the command.  \n   There may be up to 4 vimdiff buffers total.\n\n   Using the 2-argument form of the command resets the vimdiff to only those 2 \n   versions.  Additionally, invoking the command on a different file will \n   close the previous vimdiff buffers.\n\n\n4.2 Mappings\t\t\t\t\t\t  *hgcommand-mappings*\n\n   By default, a mapping is defined for each command.  These mappings execute \n   the default (no-argument) form of each command.\n\n      <Leader>hga HGAdd\n      <Leader>hgn HGAnnotate\n      <Leader>hgc HGCommit\n      <Leader>hgd HGDiff\n      <Leader>hgg HGGotoOriginal\n      <Leader>hgG HGGotoOriginal!\n      <Leader>hgl HGLog\n      <Leader>hgr HGReview\n      <Leader>hgs HGStatus\n      <Leader>hgu HGUpdate\n      <Leader>hgv HGVimDiff\n\n                                                 *hgcommand-mappings-override*\n\n   The default mappings can be overriden by user-provided instead by mapping \n   to <Plug>CommandName.  This is especially useful when these mappings \n   collide with other existing mappings (vim will warn of this during plugin \n   initialization, but will not clobber the existing mappings).\n\n   For instance, to override the default mapping for :HGAdd to set it to \n   '\\add', add the following to the vimrc: >\n\n      nmap \\add <Plug>HGAdd\n<\n4.3 Automatic buffer variables\t\t\t  *hgcommand-buffer-variables*\n\n   Several buffer variables are defined in each HGCommand result buffer.\t\n   These may be useful for additional customization in callbacks defined in \n   the event handlers (please see |hgcommand-events|).\n\n   The following variables are automatically defined:\n\nb:hgOrigBuffNR\t\t\t\t\t\t      *b:hgOrigBuffNR*\n\n   This variable is set to the buffer number of the source file.\n\nb:hgcmd\t\t\t\t\t\t                     *b:hgcmd*\n\n   This variable is set to the name of the hg command that created the result \n   buffer.\n==============================================================================\n\n5. Configuration and customization\t\t\t *hgcommand-customize*\n                                                            *hgcommand-config*\n\n   The HGCommand plugin can be configured in two ways:  by setting \n   configuration variables (see |hgcommand-options|) or by defining HGCommand \n   event handlers (see |hgcommand-events|).  Additionally, the HGCommand \n   plugin provides several option for naming the HG result buffers (see \n   |hgcommand-naming|) and supported a customized status line (see \n   |hgcommand-statusline| and |hgcommand-buffer-management|).\n\n5.1 HGCommand configuration variables\t\t\t   *hgcommand-options*\n\n   Several variables affect the plugin's behavior.  These variables are \n   checked at time of execution, and may be defined at the window, buffer, or \n   global level and are checked in that order of precedence.\n\n\n   The following variables are available:\n\n      |HGCommandAnnotateParent|\n      |HGCommandCommitOnWrite|\n      |HGCommandHGExec|\n      |HGCommandDeleteOnHide|\n      |HGCommandDiffOpt|\n      |HGCommandDiffSplit|\n      |HGCommandEdit|\n      |HGCommandEnableBufferSetup|\n      |HGCommandInteractive|\n      |HGCommandNameMarker|\n      |HGCommandNameResultBuffers|\n      |HGCommandSplit|\n\nHGCommandAnnotateParent\t\t\t             *HGCommandAnnotateParent*\n\n   This variable, if set to a non-zero value, causes the zero-argument form of \n   HGAnnotate when invoked on a HGAnnotate buffer to go to the version \n   previous to that displayed on the current line. If not set, it defaults to \n   0.\n\nHGCommandCommitOnWrite\t\t\t\t      *HGCommandCommitOnWrite*\n\n   This variable, if set to a non-zero value, causes the pending hg commit to \n   take place immediately as soon as the log message buffer is written.  If \n   set to zero, only the HGCommit mapping will cause the pending commit to \n   occur.  If not set, it defaults to 1.\n\nHGCommandHGExec\t\t\t\t                     *HGCommandHGExec*\n\n   This variable controls the executable used for all HG commands.  If not \n   set, it defaults to \"hg\".\n\nHGCommandDeleteOnHide\t\t\t\t       *HGCommandDeleteOnHide*\n\n   This variable, if set to a non-zero value, causes the temporary HG result \n   buffers to automatically delete themselves when hidden.\n\nHGCommandDiffOpt\t\t\t\t            *HGCommandDiffOpt*\n\n   This variable, if set, determines the options passed to the diff command of \n   HG.  If not set, it defaults to 'w'.\n\nHGCommandDiffSplit\t\t\t\t          *HGCommandDiffSplit*\n\n   This variable overrides the |HGCommandSplit| variable, but only for buffers \n   created with |:HGVimDiff|.\n\nHGCommandEdit\t\t\t\t\t               *HGCommandEdit*\n\n   This variable controls whether the original buffer is replaced ('edit') or \n   split ('split').  If not set, it defaults to 'edit'.\n\nHGCommandEnableBufferSetup\t\t\t  *HGCommandEnableBufferSetup*\n\n   This variable, if set to a non-zero value, activates HG buffer management \n   mode see (|hgcommand-buffer-management|).  This mode means that three \n   buffer variables, 'HGRepository', 'HGRevision' and 'HGBranch', are set if \n   the file is HG-controlled.  This is useful for displaying version \n   information in the status bar.\n\nHGCommandInteractive\t\t\t\t        *HGCommandInteractive*\n\n   This variable, if set to a non-zero value, causes appropriate commands (for \n   the moment, only |:HGReview|) to query the user for a revision to use \n   instead of the current revision if none is specified.\n\nHGCommandNameMarker\t\t\t\t         *HGCommandNameMarker*\n\n   This variable, if set, configures the special attention-getting characters \n   that appear on either side of the hg buffer type in the buffer name.  This \n   has no effect unless |HGCommandNameResultBuffers| is set to a true value.  \n   If not set, it defaults to '_'.  \n\nHGCommandNameResultBuffers\t\t\t  *HGCommandNameResultBuffers*\n\n   This variable, if set to a true value, causes the hg result buffers to be \n   named in the old way ('<source file name> _<hg command>_').  If not set or \n   set to a false value, the result buffer is nameless.\n\nHGCommandSplit\t\t\t\t\t              *HGCommandSplit*\n\n   This variable controls the orientation of the various window splits that \n   may occur (such as with HGVimDiff, when using a HG command on a HG command \n   buffer, or when the |HGCommandEdit| variable is set to 'split'.  If set to \n   'horizontal', the resulting windows will be on stacked on top of one \n   another.  If set to 'vertical', the resulting windows will be side-by-side.  \n   If not set, it defaults to 'horizontal' for all but HGVimDiff windows.\n\n5.2 HGCommand events\t\t\t\t            *hgcommand-events*\n\n   For additional customization, HGCommand can trigger user-defined events.  \n   Event handlers are provided by defining User event autocommands (see \n   |autocommand|, |User|) in the HGCommand group with patterns matching the \n   event name.\n\n   For instance, the following could be added to the vimrc to provide a 'q' \n   mapping to quit a HGCommand scratch buffer: >\n\n      augroup HGCommand\n         au HGCommand User HGBufferCreated silent! nmap <unique> <buffer> q:\n         bwipeout<cr>\n      augroup END\n<\n\n   The following hooks are available:\n\nHGBufferCreated\t\tThis event is fired just after a hg command result\n                        buffer is created and filled with the result of a hg \n                        command.  It is executed within the context of the HG \n                        command buffer.  The HGCommand buffer variables may be \n                        useful for handlers of this event (please see \n                        |hgcommand-buffer-variables|).\n\nHGBufferSetup\t\tThis event is fired just after HG buffer setup occurs,\n                        if enabled.\n\nHGPluginInit\t\tThis event is fired when the HGCommand plugin first\n                        loads.\n\nHGPluginFinish\t\tThis event is fired just after the HGCommand plugin\n                        loads.\n\nHGVimDiffFinish\t\tThis event is fired just after the HGVimDiff command\n                        executes to allow customization of, for instance, \n                        window placement and focus.\n\n5.3 HGCommand buffer naming\t\t\t\t    *hgcommand-naming*\n\n   By default, the buffers containing the result of HG commands are nameless \n   scratch buffers.  It is intended that buffer variables of those buffers be \n   used to customize the statusline option so that the user may fully control \n   the display of result buffers.\n\n   If the old-style naming is desired, please enable the \n   |HGCommandNameResultBuffers| variable.  Then, each result buffer will \n   receive a unique name that includes the source file name, the HG command, \n   and any extra data (such as revision numbers) that were part of the \n   command.\n\n5.4 HGCommand status line support\t\t\t*hgcommand-statusline*\n\n   It is intended that the user will customize the |'statusline'| option to \n   include HG result buffer attributes.  A sample function that may be used in \n   the |'statusline'| option is provided by the plugin, HGGetStatusLine().  In \n   order to use that function in the status line, do something like the \n   following: >\n\n      set statusline=%<%f\\ %{HGGetStatusLine()}\\ %h%m%r%=%l,%c%V\\ %P\n<\n   of which %{HGGetStatusLine()} is the relevant portion.\n\n   The sample HGGetStatusLine() function handles both HG result buffers and \n   HG-managed files if HGCommand buffer management is enabled (please see \n   |hgcommand-buffer-management|).\n\n5.5 HGCommand buffer management\t\t         *hgcommand-buffer-management*\n\n   The HGCommand plugin can operate in buffer management mode, which means \n   that it attempts to set two buffer variables ('HGRevision' and 'HGBranch') \n   upon entry into a buffer.  This is rather slow because it means that 'hg \n   status' will be invoked at each entry into a buffer (during the |BufEnter| \n   autocommand).\n\n   This mode is disabled by default.  In order to enable it, set the \n   |HGCommandEnableBufferSetup| variable to a true (non-zero) value.  Enabling \n   this mode simply provides the buffer variables mentioned above.  The user \n   must explicitly include those in the |'statusline'| option if they are to \n   appear in the status line (but see |hgcommand-statusline| for a simple way\n   to do that).\n\n==============================================================================\n9. Tips\t\t\t\t\t\t\t      *hgcommand-tips*\n\n9.1 Split window annotation, by Michael Anderson >\n\n   :nmap <Leader>hgN :vs<CR><C-w>h<Leader>hgn:vertical res 40<CR>\n                 \\ggdddd:set scb<CR>:set nowrap<CR><C-w>lgg:set scb<CR>\n                 \\:set nowrap<CR>\n<\n\n   This splits the buffer vertically, puts an annotation on the left (minus \n   the header) with the width set to 40. An editable/normal copy is placed on \n   the right.  The two versions are scroll locked so they  move as one. and \n   wrapping is turned off so that the lines line up correctly. The advantages \n   are...\n\n   1) You get a versioning on the right.\n   2) You can still edit your own code.\n   3) Your own code still has syntax highlighting.\n\n==============================================================================\n\n8. Known bugs\t\t\t\t\t\t      *hgcommand-bugs*\n\n   Please let me know if you run across any.\n\n   HGVimDiff, when using the original (real) source buffer as one of the diff \n   buffers, uses some hacks to try to restore the state of the original buffer \n   when the scratch buffer containing the other version is destroyed.  There \n   may still be bugs in here, depending on many configuration details.\n\n==============================================================================\n=== END_DOC\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\" v im:tw=78:ts=8:ft=help:norl:\n\" vim600: set foldmethod=marker  tabstop=8 shiftwidth=2 softtabstop=2 smartindent smarttab  :\n\"fileencoding=iso-8859-15 \n"
  },
  {
    "path": "Units/parser-vim.r/3548393.vim.d/expected.tags",
    "content": "Gozilla\tinput.vim\t/^command! -nargs=0 Gozilla call s:Gozilla()$/;\"\tc\nGtags\tinput.vim\t/^command! -nargs=* -complete=custom,GtagsCandidate Gtags call s:RunGlobal(<q-args>)$/;\"\tc\nGtagsCandidate\tinput.vim\t/^function! GtagsCandidate(lead, line, pos)$/;\"\tf\nGtagsCandidateCore\tinput.vim\t/^function! GtagsCandidateCore(lead, line, pos)$/;\"\tf\nGtagsCursor\tinput.vim\t/^command! -nargs=0 GtagsCursor call s:GtagsCursor()$/;\"\tc\nGtagsUpdate\tinput.vim\t/^command! -nargs=0 GtagsUpdate call s:GtagsAutoUpdate()$/;\"\tc\nGtags_Auto_Map\tinput.vim\t/^    let Gtags_Auto_Map = 0$/;\"\tv\nGtags_Auto_Update\tinput.vim\t/^    let Gtags_Auto_Update = 0$/;\"\tv\ng:Gtags_Double_Quote_Char\tinput.vim\t/^        let g:Gtags_Double_Quote_Char = '\"'$/;\"\tv\ng:Gtags_Double_Quote_Char\tinput.vim\t/^        let g:Gtags_Double_Quote_Char = '\\\\\"'$/;\"\tv\ng:Gtags_Efm\tinput.vim\t/^    let g:Gtags_Efm = \"%f\\\\t%l\\\\t%m\"$/;\"\tv\ng:Gtags_Efm\tinput.vim\t/^    let g:Gtags_Efm = \"%m\\\\t%f\\\\t%l\"$/;\"\tv\ng:Gtags_OpenQuickfixWindow\tinput.vim\t/^    let g:Gtags_OpenQuickfixWindow = 1$/;\"\tv\ng:Gtags_Result\tinput.vim\t/^    let g:Gtags_Result = \"ctags\"$/;\"\tv\ng:Gtags_Result\tinput.vim\t/^    let g:Gtags_Result = \"ctags-mod\"$/;\"\tv\ng:Gtags_Shell_Quote_Char\tinput.vim\t/^        let g:Gtags_Shell_Quote_Char = \"'\"$/;\"\tv\ng:Gtags_Shell_Quote_Char\tinput.vim\t/^        let g:Gtags_Shell_Quote_Char = '\"'$/;\"\tv\ng:Gtags_Single_Quote_Char\tinput.vim\t/^        let g:Gtags_Single_Quote_Char = \"'\"$/;\"\tv\ng:Gtags_Single_Quote_Char\tinput.vim\t/^        let g:Gtags_Single_Quote_Char = s:sq . s:dq . s:sq . s:dq . s:sq$/;\"\tv\ng:Gtags_VerticalWindow\tinput.vim\t/^    let g:Gtags_VerticalWindow = 0$/;\"\tv\nloaded_gtags\tinput.vim\t/^let loaded_gtags = 1$/;\"\tv\ns:Error\tinput.vim\t/^function! s:Error(msg)$/;\"\tf\ns:ExecLoad\tinput.vim\t/^function! s:ExecLoad(option, long_option, pattern)$/;\"\tf\ns:Extract\tinput.vim\t/^function! s:Extract(line, target)$/;\"\tf\ns:Gozilla\tinput.vim\t/^function! s:Gozilla()$/;\"\tf\ns:GtagsAutoUpdate\tinput.vim\t/^function! s:GtagsAutoUpdate()$/;\"\tf\ns:GtagsCursor\tinput.vim\t/^function! s:GtagsCursor()$/;\"\tf\ns:RunGlobal\tinput.vim\t/^function! s:RunGlobal(line)$/;\"\tf\ns:TrimOption\tinput.vim\t/^function! s:TrimOption(option)$/;\"\tf\ns:dq\tinput.vim\t/^        let s:dq = '\"'$/;\"\tv\ns:global_command\tinput.vim\t/^        let s:global_command = \"global\"$/;\"\tv\ns:global_command\tinput.vim\t/^let s:global_command = $GTAGSGLOBAL$/;\"\tv\ns:sq\tinput.vim\t/^        let s:sq = \"'\"$/;\"\tv\n"
  },
  {
    "path": "Units/parser-vim.r/3548393.vim.d/input.vim",
    "content": "\" File: gtags.vim\n\" Author: Tama Communications Corporation\n\" Version: 0.6.2\n\" Last Modified: 2012 Oct 23\n\"\n\" Copyright and licence\n\" ---------------------\n\" Copyright (c) 2004, 2008, 2010, 2011 Tama Communications Corporation\n\"\n\" This file is part of GNU GLOBAL.\n\"\n\" This program is free software: you can redistribute it and/or modify\n\" it under the terms of the GNU General Public License as published by\n\" the Free Software Foundation, either version 3 of the License, or\n\" (at your option) any later version.\n\" \n\" This program is distributed in the hope that it will be useful,\n\" but WITHOUT ANY WARRANTY; without even the implied warranty of\n\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\" GNU General Public License for more details.\n\" \n\" You should have received a copy of the GNU General Public License\n\" along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\"\n\" Overview\n\" --------\n\" The gtags.vim plug-in script integrates the GNU GLOBAL source code tag system\n\" with Vim. About the details, see http://www.gnu.org/software/global/.\n\"\n\" Installation\n\" ------------\n\" Drop the file in your plug-in directory or source it from your vimrc.\n\" To use this script, you need the GNU GLOBAL-6.0 or later installed\n\" in your machine.\n\"\n\" Usage\n\" -----\n\" First of all, you must execute gtags(1) at the root of source directory\n\" to make tag files. Assuming that your source directory is '/var/src',\n\" it is necessary to execute the following commands.\n\"\n\"\t$ cd /var/src\n\"\t$ gtags\n\"\n\" And you will find four tag files in the directory.\n\"\n\" General form of Gtags command is as follows:\n\"\n\"\t:Gtags [option] pattern\n\"\n\" To go to func, you can say\n\"\n\"       :Gtags func\n\"\n\" Input completion is available. If you forgot function name but recall\n\" only some characters of the head, please input them and press <TAB> key.\n\"\n\"       :Gtags fu<TAB>\n\"       :Gtags func\t\t\t<- Vim will append 'nc'.\n\"\n\" If you omitted argument, vim ask it like this:\n\"\n\"       Gtags for pattern: <current token>\n\"\n\" Vim execute `global -x main', parse the output, list located\n\" objects in quickfix window and load the first entry.  The quickfix\n\" windows is like this:\n\"\n\"      gozilla/gozilla.c|200| main(int argc, char **argv)\n\"      gtags-cscope/gtags-cscope.c|124| main(int argc, char **argv)\n\"      gtags-parser/asm_scan.c|2056| int main()\n\"      gtags-parser/gctags.c|157| main(int argc, char **argv)\n\"      gtags-parser/php.c|2116| int main()\n\"      gtags/gtags.c|152| main(int argc, char **argv)\n\"      [Quickfix List]\n\"\n\" You can go to any entry using quickfix command.\n\"\n\" :cn'\n\"      go to the next entry.\n\"\n\" :cp'\n\"      go to the previous entry.\n\"\n\" :ccN'\n\"      go to the Nth entry.\n\"\n\" :cl'\n\"      list all entries.\n\"\n\" You can see the help of quickfix like this:\n\"\n\"          :h quickfix\n\"\n\" You can use POSIX regular expression too. It requires more execution time though.\n\"\n\"       :Gtags ^[sg]et_\n\"\n\" It will match to both of 'set_value' and 'get_value'.\n\"\n\" To go to the referenced point of func, add -r option.\n\"\n\"       :Gtags -r func\n\"\n\" To go to any symbols which are not defined in GTAGS, try this.\n\"\n\"       :Gtags -s func\n\"\n\" To go to any string other than symbol, try this.\n\"\n\"       :Gtags -g ^[sg]et_\n\"\n\" This command accomplishes the same function as grep(1) but is more convenient\n\" because it retrieves the entire directory structure.\n\"\n\" To get list of objects in a file 'main.c', use -f command.\n\"\n\"       :Gtags -f main.c\n\"\n\" If you are editing `main.c' itself, you can use '%' instead.\n\"\n\"       :Gtags -f %\n\"\n\" You can browse project files whose path includes specified pattern.\n\" For example:\n\"\n\"       :Gtags -P /vm/\t\t\t<- all files under 'vm' directory.\n\"       :Gtags -P \\.h$\t\t\t<- all include files.\n\"\t:Gtags -P init\t\t\t<- all paths includes 'init'\n\"\n\" If you omitted the argument and input only <ENTER> key to the prompt,\n\" vim shows list of all files in your project.\n\"\n\" You can use all options of global(1) except for the -c, -p, -u and\n\" all long name options. They are sent to global(1) as is.\n\" For example, if you want to ignore case distinctions in pattern.\n\"\n\"       :Gtags -gi paTtern\n\"\n\" It will match to both of 'PATTERN' and 'pattern'.\n\"\n\" If you want to search a pattern which starts with a hyphen like '-C'\n\" then you can use the -e option like grep(1).\n\"\n\"\t:Gtags -ge -C\n\"\n\" By default, Gtags command search only in source files. If you want to\n\" search in both source files and text files, or only in text files then\n\"\n\"\t:Gtags -go pattern\t\t# both source and text\n\"\t:Gtags -gO pattern\t\t# only text file\n\"\n\" See global(1) for other options.\n\"\n\" The GtagsCursor command brings you to the definition or reference of\n\" the current token.\n\"\n\"       :GtagsCursor\n\"\n\" If you have the hypertext generated by htags(1) then you can display\n\" the same place on mozilla browser. Let's load mozilla and try this:\n\"\n\"       :Gozilla\n\"\n\" If you want to load vim with all main()s then following command line is useful.\n\"\n\"\t% vim '+Gtags main'\n\"\n\" Also see the chapter of 'vim editor' of the on-line manual of GLOBAL.\n\"\n\"\t% info global\n\"\n\" You can use the suggested key mapping with the following code:\n\"\n\"\t[$HOME/.vimrc]\n\"\tlet Gtags_Auto_Map = 1\n\"\nif exists(\"loaded_gtags\")\n    finish\nendif\n\n\"\n\" global command name\n\"\nlet s:global_command = $GTAGSGLOBAL\nif s:global_command == ''\n        let s:global_command = \"global\"\nendif\n\" Open the Gtags output window.  Set this variable to zero, to not open\n\" the Gtags output window by default.  You can open it manually by using\n\" the :cwindow command.\n\" (This code was drived from 'grep.vim'.)\nif !exists(\"g:Gtags_OpenQuickfixWindow\")\n    let g:Gtags_OpenQuickfixWindow = 1\nendif\n\nif !exists(\"g:Gtags_VerticalWindow\")\n    let g:Gtags_VerticalWindow = 0\nendif\n\nif !exists(\"g:Gtags_Auto_Map\")\n    let Gtags_Auto_Map = 0\nendif\n\nif !exists(\"Gtags_Auto_Update\")\n    let Gtags_Auto_Update = 0\nendif\n\n\" -- ctags-x format \n\" let Gtags_Result = \"ctags-x\"\n\" let Gtags_Efm = \"%*\\\\S%*\\\\s%l%\\\\s%f%\\\\s%m\"\n\"\n\" -- ctags format \n\" let Gtags_Result = \"ctags\"\n\" let Gtags_Efm = \"%m\\t%f\\t%l\"\n\"\n\" Gtags_Use_Tags_Format is obsoleted.\nif exists(\"g:Gtags_Use_Tags_Format\")\n    let g:Gtags_Result = \"ctags\"\n    let g:Gtags_Efm = \"%m\\t%f\\t%l\"\nendif\nif !exists(\"g:Gtags_Result\")\n    let g:Gtags_Result = \"ctags-mod\"\nendif\nif !exists(\"g:Gtags_Efm\")\n    let g:Gtags_Efm = \"%f\\t%l\\t%m\"\nendif\n\" Character to use to quote patterns and file names before passing to global.\n\" (This code was drived from 'grep.vim'.)\nif !exists(\"g:Gtags_Shell_Quote_Char\")\n    if has(\"win32\") || has(\"win16\") || has(\"win95\")\n        let g:Gtags_Shell_Quote_Char = '\"'\n    else\n        let g:Gtags_Shell_Quote_Char = \"'\"\n    endif\nendif\nif !exists(\"g:Gtags_Single_Quote_Char\")\n    if has(\"win32\") || has(\"win16\") || has(\"win95\")\n        let g:Gtags_Single_Quote_Char = \"'\"\n        let g:Gtags_Double_Quote_Char = '\\\"'\n    else\n        let s:sq = \"'\"\n        let s:dq = '\"'\n        let g:Gtags_Single_Quote_Char = s:sq . s:dq . s:sq . s:dq . s:sq\n        let g:Gtags_Double_Quote_Char = '\"'\n    endif\nendif\n\n\"\n\" Display error message.\n\"\nfunction! s:Error(msg)\n    echohl WarningMsg |\n           \\ echomsg 'Error: ' . a:msg |\n           \\ echohl None\nendfunction\n\"\n\" Extract pattern or option string.\n\"\nfunction! s:Extract(line, target)\n    let l:option = ''\n    let l:pattern = ''\n    let l:force_pattern = 0\n    let l:length = strlen(a:line)\n    let l:i = 0\n\n    \" skip command name.\n    if a:line =~ '^Gtags'\n        let l:i = 5\n    endif\n    while l:i < l:length && a:line[l:i] == ' '\n       let l:i = l:i + 1\n    endwhile \n    while l:i < l:length\n        if a:line[l:i] == \"-\" && l:force_pattern == 0\n            let l:i = l:i + 1\n            \" Ignore long name option like --help.\n            if l:i < l:length && a:line[l:i] == '-'\n                while l:i < l:length && a:line[l:i] != ' '\n                   let l:i = l:i + 1\n                endwhile \n            else\n                while l:i < l:length && a:line[l:i] != ' '\n                    let l:c = a:line[l:i]\n                    let l:option = l:option . l:c\n                    let l:i = l:i + 1\n                endwhile \n                if l:c == 'e'\n                    let l:force_pattern = 1\n                endif\n            endif\n        else\n            let l:pattern = ''\n            \" allow pattern includes blanks.\n            while l:i < l:length\n                 if a:line[l:i] == \"'\"\n                     let l:pattern = l:pattern . g:Gtags_Single_Quote_Char\n                 elseif a:line[l:i] == '\"'\n                     let l:pattern = l:pattern . g:Gtags_Double_Quote_Char\n                 else\n                     let l:pattern = l:pattern . a:line[l:i]\n                 endif\n                let l:i = l:i + 1\n            endwhile \n            if a:target == 'pattern'\n                return l:pattern\n            endif\n        endif\n        \" Skip blanks.\n        while l:i < l:length && a:line[l:i] == ' '\n               let l:i = l:i + 1\n        endwhile \n    endwhile \n    if a:target == 'option'\n        return l:option\n    endif\n    return ''\nendfunction\n\n\"\n\" Trim options to avoid errors.\n\"\nfunction! s:TrimOption(option)\n    let l:option = ''\n    let l:length = strlen(a:option)\n    let l:i = 0\n\n    while l:i < l:length\n        let l:c = a:option[l:i]\n        if l:c !~ '[cenpquv]'\n            let l:option = l:option . l:c\n        endif\n        let l:i = l:i + 1\n    endwhile\n    return l:option\nendfunction\n\n\"\n\" Execute global and load the result into quickfix window.\n\"\nfunction! s:ExecLoad(option, long_option, pattern)\n    \" Execute global(1) command and write the result to a temporary file.\n    let l:isfile = 0\n    let l:option = ''\n    let l:result = ''\n\n    if a:option =~ 'f'\n        let l:isfile = 1\n        if filereadable(a:pattern) == 0\n            call s:Error('File ' . a:pattern . ' not found.')\n            return\n        endif\n    endif\n    if a:long_option != ''\n        let l:option = a:long_option . ' '\n    endif\n    let l:option = l:option . '--result=' . g:Gtags_Result . ' -q'\n    let l:option = l:option . s:TrimOption(a:option)\n    if l:isfile == 1\n        let l:cmd = s:global_command . ' ' . l:option . ' ' . g:Gtags_Shell_Quote_Char . a:pattern . g:Gtags_Shell_Quote_Char\n    else\n        let l:cmd = s:global_command . ' ' . l:option . 'e ' . g:Gtags_Shell_Quote_Char . a:pattern . g:Gtags_Shell_Quote_Char \n    endif\n\n    let l:result = system(l:cmd)\n    if v:shell_error != 0\n        if v:shell_error != 0\n            if v:shell_error == 2\n                call s:Error('invalid arguments. please use the latest GLOBAL.')\n            elseif v:shell_error == 3\n                call s:Error('GTAGS not found.')\n            else\n                call s:Error('global command failed. command line: ' . l:cmd)\n            endif\n        endif\n        return\n    endif\n    if l:result == '' \n        if l:option =~ 'f'\n            call s:Error('Tag not found in ' . a:pattern . '.')\n        elseif l:option =~ 'P'\n            call s:Error('Path which matches to ' . a:pattern . ' not found.')\n        elseif l:option =~ 'g'\n            call s:Error('Line which matches to ' . a:pattern . ' not found.')\n        else\n            call s:Error('Tag which matches to ' . g:Gtags_Shell_Quote_Char . a:pattern . g:Gtags_Shell_Quote_Char . ' not found.')\n        endif\n        return\n    endif\n\n    \" Open the quickfix window\n    if g:Gtags_OpenQuickfixWindow == 1\n        if g:Gtags_VerticalWindow == 1\n            topleft vertical copen\n        else\n            botright copen\n        endif\n    endif\n    \" Parse the output of 'global -x or -t' and show in the quickfix window.\n    let l:efm_org = &efm\n    let &efm = g:Gtags_Efm\n    cexpr! l:result\n    let &efm = l:efm_org\nendfunction\n\n\"\n\" RunGlobal()\n\"\nfunction! s:RunGlobal(line)\n    let l:pattern = s:Extract(a:line, 'pattern')\n\n    if l:pattern == '%'\n        let l:pattern = expand('%')\n    elseif l:pattern == '#'\n        let l:pattern = expand('#')\n    endif\n    let l:option = s:Extract(a:line, 'option')\n    \" If no pattern supplied then get it from user.\n    if l:pattern == ''\n        let s:option = l:option\n        if l:option =~ 'f'\n            let l:line = input(\"Gtags for file: \", expand('%'), 'file')\n        else\n            let l:line = input(\"Gtags for pattern: \", expand('<cword>'), 'custom,GtagsCandidateCore')\n        endif\n        let l:pattern = s:Extract(l:line, 'pattern')\n        if l:pattern == ''\n            call s:Error('Pattern not specified.')\n            return\n        endif\n    endif\n    call s:ExecLoad(l:option, '', l:pattern)\nendfunction\n\n\"\n\" Execute RunGlobal() depending on the current position.\n\"\nfunction! s:GtagsCursor()\n    let l:pattern = expand(\"<cword>\")\n    let l:option = \"--from-here=\\\"\" . line('.') . \":\" . expand(\"%\") . \"\\\"\"\n    call s:ExecLoad('', l:option, l:pattern)\nendfunction\n\n\"\n\" Show the current position on mozilla.\n\" (You need to execute htags(1) in your source directory.)\n\"\nfunction! s:Gozilla()\n    let l:lineno = line('.')\n    let l:filename = expand(\"%\")\n    let l:result = system('gozilla +' . l:lineno . ' ' . l:filename)\nendfunction\n\"\n\" Auto update of tag files using incremental update facility.\n\"\nfunction! s:GtagsAutoUpdate()\n    let l:result = system(s:global_command . \" -u --single-update=\\\"\" . expand(\"%\") . \"\\\"\")\nendfunction\n\n\"\n\" Custom completion.\n\"\nfunction! GtagsCandidate(lead, line, pos)\n    let s:option = s:Extract(a:line, 'option')\n    return GtagsCandidateCore(a:lead, a:line, a:pos)\nendfunction\n\nfunction! GtagsCandidateCore(lead, line, pos)\n    if s:option == 'g'\n        return ''\n    elseif s:option == 'f'\n        if isdirectory(a:lead)\n            if a:lead =~ '/$'\n                let l:pattern = a:lead . '*'\n            else\n                let l:pattern = a:lead . '/*'\n            endif\n        else\n            let l:pattern = a:lead . '*'\n        endif\n        return glob(l:pattern)\n    else \n        return system(s:global_command . ' ' . '-c' . s:option . ' ' . a:lead)\n    endif\nendfunction\n\n\" Define the set of Gtags commands\ncommand! -nargs=* -complete=custom,GtagsCandidate Gtags call s:RunGlobal(<q-args>)\ncommand! -nargs=0 GtagsCursor call s:GtagsCursor()\ncommand! -nargs=0 Gozilla call s:Gozilla()\ncommand! -nargs=0 GtagsUpdate call s:GtagsAutoUpdate()\nif g:Gtags_Auto_Update == 1\n\t:autocmd! BufWritePost * call s:GtagsAutoUpdate()\nendif\n\" Suggested map:\nif g:Gtags_Auto_Map == 1\n\t:nmap <F2> :copen<CR>\n\t:nmap <F4> :cclose<CR>\n\t:nmap <F5> :Gtags<SPACE>\n\t:nmap <F6> :Gtags -f %<CR>\n\t:nmap <F7> :GtagsCursor<CR>\n\t:nmap <F8> :Gozilla<CR>\n\t:nmap <C-n> :cn<CR>\n\t:nmap <C-p> :cp<CR>\n\t:nmap <C-\\><C-]> :GtagsCursor<CR>\nendif\nlet loaded_gtags = 1\n"
  },
  {
    "path": "Units/parser-vim.r/bug3032253.vim.d/expected.tags",
    "content": "ThisIsValid\tinput.vim\t/^   comma! ThisIsValid$/;\"\tc\n"
  },
  {
    "path": "Units/parser-vim.r/bug3032253.vim.d/input.vim",
    "content": "\" ctags will hang when it attempts to process this line\n   command.\n   command!.\n   comma!.\n   comma! ThisIsValid\n"
  },
  {
    "path": "Units/parser-vim.r/bug358.vim.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-vim.r/bug358.vim.d/input.vim",
    "content": ""
  },
  {
    "path": "Units/parser-vim.r/bug359.vim.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-vim.r/bug359.vim.d/input.vim",
    "content": "\" This is an invalid Vim command, but it crashes the Vim parser\r\ncommand 'endlessloop'\r\n"
  },
  {
    "path": "Units/parser-vim.r/end-field.vim.d/args.ctags",
    "content": "--fields=ne\n--sort=no\n"
  },
  {
    "path": "Units/parser-vim.r/end-field.vim.d/expected.tags",
    "content": "Test\tinput.vim\t/^function Test()$/;\"\tline:1\tend:3\ns:Test\tinput.vim\t/^function s:Test()$/;\"\tline:5\tend:6\n"
  },
  {
    "path": "Units/parser-vim.r/end-field.vim.d/input.vim",
    "content": "function Test()\n  call s:Test()\nendfunction\n\nfunction s:Test()\nendfunction"
  },
  {
    "path": "Units/parser-vim.r/simple.vim.d/expected.tags",
    "content": "$env_var\tinput.vim\t/^let $env_var = 'something'$/;\"\tv\n(\tinput.vim\t/^inoremap <buffer> ( <C-R>=PreviewFunctionSignature()<LF> $/;\"\tm\n,,,\tinput.vim\t/^inoremap ,,, <esc>diwi<<esc>pa><cr><\\/<esc>pa><esc>kA$/;\"\tm\n<F8>\tinput.vim\t/^nnoremap <silent> <F8> :Tlist<CR>$/;\"\tm\n<Leader>scdt\tinput.vim\t/^map! <unique> <Leader>scdt <Plug>GetColumnDataType$/;\"\tm\nBar\tinput.vim\t/^fu Bar(arg)$/;\"\tf\nDBSetOption\tinput.vim\t/^command! -nargs=* -complete=customlist,<SID>DB_settingsComplete DBSetOption :call s:DB_setMultip/;\"\tc\nE\tinput.vim\t/^function E$/;\"\tf\nExtraLines\tinput.vim\t/^            \\\\ ExtraLines edit<bang> <args>$/;\"\tc\nFoo\tinput.vim\t/^function! Foo(arg)$/;\"\tf\nFoo_SID\tinput.vim\t/^function! <SID>Foo_SID(arg)$/;\"\tf\nIndentedFunction\tinput.vim\t/^    fu IndentedFunction(arg)$/;\"\tf\nNoSpaceBeforeContinue\tinput.vim\t/^            \\\\NoSpaceBeforeContinue edit<bang> <args>$/;\"\tc\nSelectCmd\tinput.vim\t/^command! -nargs=+ SelectCmd         :call s:DB_execSql(\"select \" . <q-args>)$/;\"\tc\nSpaceBeforeContinue\tinput.vim\t/^            \\\\ SpaceBeforeContinue edit<bang> <args>$/;\"\tc\nautoloadFunc#subdirname#Funcname\tinput.vim\t/^function autoloadFunc#subdirname#Funcname()$/;\"\tf\nforms#FT_TEXTFIELD\tinput.vim\t/^let forms#FT_TEXTFIELD = 'textfield'$/;\"\tv\nforms#form\tinput.vim\t/^let forms#form = {$/;\"\tv\nforms#form.addTextField\tinput.vim\t/^function! forms#form.addTextField(fname, flabel, fvalue, hotkey)$/;\"\tf\ng:plugin#foo\tinput.vim\t/^let g:plugin#foo = {}$/;\"\tv\ng:var_global_scope\tinput.vim\t/^let g:var_global_scope = 1$/;\"\tv\nmydict\tinput.vim\t/^let mydict = {'data': [0, 1, 2, 3]}$/;\"\tv\nmydict.len\tinput.vim\t/^function mydict.len() dict$/;\"\tf\nplugin#foo\tinput.vim\t/^function! g:plugin#foo() abort dict$/;\"\tf\ns:Foo_scolon\tinput.vim\t/^function! s:Foo_scolon(arg)$/;\"\tf\ns:validFuncLowerCaseInitialLetter\tinput.vim\t/^function! s:validFuncLowerCaseInitialLetter(arg)$/;\"\tf\ns:var_script_scope\tinput.vim\t/^let s:var_script_scope = 1$/;\"\tv\nuncompress\tinput.vim\t/^augroup uncompress$/;\"\ta\nvar_script_default_scope\tinput.vim\t/^let var_script_default_scope = 1$/;\"\tv\n"
  },
  {
    "path": "Units/parser-vim.r/simple.vim.d/input.vim",
    "content": "\n\" These variables should be tagged\nlet g:var_global_scope = 1\nlet s:var_script_scope = 1\nlet var_script_default_scope = 1\nlet forms#FT_TEXTFIELD = 'textfield'\nlet forms#form = {\n      \\ 'title': 'Address Entry Form',\n      \\ 'fields': [],\n      \\ 'defaultbutton': 'ok',\n      \\ 'fieldMap': {},\n      \\ 'hotkeyMap': {},\n      \\ }\nlet $env_var = 'something'\n\n\n\" These lets should be ignored\nlet &errorformat = \"%A%.%#rror reported by parser: %m\" \nlet @a = 'set register a'\nlet [a, b; rest] = [\"aval\", \"bval\", 3, 4]\n\nlet \n\n\" These lets should be ignored Vim variables are readonly\nlet v:version = 'something'\n\n\" autogroups\naugroup uncompress\n  au!\n  au BufEnter *.gz\t%!gunzip\naugroup END\n\n\" This deletes the autogroup and should be ignored\naugroup! uncompress\n\n\" Ensure line is ignored\naugroup    \n\n\" commands\ncommand! -nargs=+ SelectCmd         :call s:DB_execSql(\"select \" . <q-args>)\ncommand! -nargs=* -complete=customlist,<SID>DB_settingsComplete DBSetOption :call s:DB_setMultipleOptions(<q-args>)\ncomma -bang \n            \\NoSpaceBeforeContinue edit<bang> <args>\ncom -nargs=1 -bang -complete=customlist,EditFileComplete\n            \\ SpaceBeforeContinue edit<bang> <args>\ncom -nargs=1 -bang \n            \\-complete=customlist,EditFileComplete\n            \\ -complete=file\n            \\ ExtraLines edit<bang> <args>\n\n\" functions\nfu Bar(arg)\n    let var_inside_func = []\nendf\n\nfu invalidFuncLowerCaseInitialLetter(arg)\nendf\n\nfunction! Foo(arg)\nendfunction\n\n    fu IndentedFunction(arg)\n    endf\n\nfunction! <SID>Foo_SID(arg)\nendfu\n\nfunction! s:Foo_scolon(arg)\nendfunction\n\nfunction! s:validFuncLowerCaseInitialLetter(arg)\nendfunction\n\n\" New to Vim7\nlet mydict = {'data': [0, 1, 2, 3]}\nfunction mydict.len() dict\n    let var_in_func = 2\n    let s:script_var_in_func = 2\n   return len(self.data)\nendfunction\necho mydict.len()\n\nfunction autoloadFunc#subdirname#Funcname()\n   echo \"Done!\"\nendfunction\n\n\" Dict function with g:prefix.\nlet g:plugin#foo = {}\nfunction! g:plugin#foo() abort dict\nendfunction\n\nfunction! forms#form.addTextField(fname, flabel, fvalue, hotkey)\n  let field = s:field.new(self, g:forms#FT_TEXTFIELD, a:fname, a:flabel,\n        \\ a:fvalue, a:hotkey)\n  return field\nendfunction\n\n\" Invalid function, must start with an UPPER case letter\nfunction e\nendfunction\n\n\" Shortest possible function name\nfunction E\nendfunction\n\n\" Ensure it ingores the invalid function declaration\nfunction s:\nendfunction\n\n\" Tags should be created for\n\" <F8>\n\" <Leader>scdt\n\" ,,,\n\" (\nnnoremap <silent> <F8> :Tlist<CR>\nmap! <unique> <Leader>scdt <Plug>GetColumnDataType\ninoremap ,,, <esc>diwi<<esc>pa><cr></<esc>pa><esc>kA\ninoremap <buffer> ( <C-R>=PreviewFunctionSignature()<LF> \n\n"
  },
  {
    "path": "Units/parser-vim.r/vim-class.d/args.ctags",
    "content": "--sort=no\n--fields=+tSen{access}{implementation}{inherits}\n"
  },
  {
    "path": "Units/parser-vim.r/vim-class.d/expected.tags",
    "content": "AsyncCmd\tinput.vim\t/^export class AsyncCmd$/;\"\tk\tline:5\tend:40\njob\tinput.vim\t/^    var job: job$/;\"\tv\tline:6\tclass:AsyncCmd\ttyperef:typename:job\nStop\tinput.vim\t/^    def Stop(how: string = '')$/;\"\tf\tline:8\tclass:AsyncCmd\tsignature:(how: string = '')\tend:12\nnew\tinput.vim\t/^    def new(cmd: any, CallbackFn: func(list<string>), env: dict<any> = null_dict)$/;\"\tf\tline:14\tclass:AsyncCmd\tsignature:(cmd: any,CallbackFn: func(list<string>)\tend:39\nOtherThing\tinput-0.vim\t/^class OtherThing$/;\"\tk\tline:4\tend:20\nsize\tinput-0.vim\t/^   var size: number$/;\"\tv\tline:5\tclass:OtherThing\ttyperef:typename:number\ntotalSize\tinput-0.vim\t/^   static var totalSize: number$/;\"\tv\tline:6\tclass:OtherThing\ttyperef:typename:number\nnew\tinput-0.vim\t/^   def new(this.size)$/;\"\tf\tline:8\tclass:OtherThing\tsignature:(this.size)\tend:10\n_sum\tinput-0.vim\t/^   static var _sum: number$/;\"\tv\tline:12\tclass:OtherThing\ttyperef:typename:number\nresult\tinput-0.vim\t/^   public static var result: number$/;\"\tv\tline:13\tclass:OtherThing\ttyperef:typename:number\taccess:public\nClearTotalSize\tinput-0.vim\t/^   static def ClearTotalSize(): number$/;\"\tf\tline:15\tclass:OtherThing\ttyperef:typename:number\tsignature:()\tend:19\nYetOtherThing\tinput-0.vim\t/^class YetOtherThing$/;\"\tk\tline:23\tend:30\n_Foo\tinput-0.vim\t/^   static def _Foo()$/;\"\tf\tline:24\tclass:YetOtherThing\tsignature:()\tend:26\nBar\tinput-0.vim\t/^   def Bar()$/;\"\tf\tline:27\tclass:YetOtherThing\tsignature:()\tend:29\nA\tinput-0.vim\t/^class A$/;\"\tk\tline:32\tend:37\nv1\tinput-0.vim\t/^   final v1 = [1, 2]               # final object variable$/;\"\tC\tline:33\tclass:A\nv2\tinput-0.vim\t/^   public final v2 = {x: 1}        # final object variable$/;\"\tC\tline:34\tclass:A\taccess:public\nv3\tinput-0.vim\t/^   static final v3 = 'abc'         # final class variable$/;\"\tC\tline:35\tclass:A\nv4\tinput-0.vim\t/^   public static final v4 = 0z10   # final class variable$/;\"\tC\tline:36\tclass:A\taccess:public\nShape\tinput-1.vim\t/^abstract class Shape$/;\"\tk\tline:4\timplementation:abstract\tend:7\ncolor\tinput-1.vim\t/^   var color = Color.Black$/;\"\tv\tline:5\tclass:Shape\nthickness\tinput-1.vim\t/^   var thickness = 10$/;\"\tv\tline:6\tclass:Shape\nSquare\tinput-1.vim\t/^class Square extends Shape$/;\"\tk\tline:9\tinherits:Shape\tend:14\nsize\tinput-1.vim\t/^   var size: number$/;\"\tv\tline:10\tclass:Square\ttyperef:typename:number\nnew\tinput-1.vim\t/^   def new(this.size)$/;\"\tf\tline:12\tclass:Square\tsignature:(this.size)\tend:13\nTriangle\tinput-1.vim\t/^class Triangle extends Shape$/;\"\tk\tline:16\tinherits:Shape\tend:22\nbase\tinput-1.vim\t/^   var base: number$/;\"\tv\tline:17\tclass:Triangle\ttyperef:typename:number\nheight\tinput-1.vim\t/^   var height: number$/;\"\tv\tline:18\tclass:Triangle\ttyperef:typename:number\nnew\tinput-1.vim\t/^   def new(this.base, this.height)$/;\"\tf\tline:20\tclass:Triangle\tsignature:(this.base,this.height)\tend:21\n"
  },
  {
    "path": "Units/parser-vim.r/vim-class.d/input-0.vim",
    "content": "vim9script\n# Taken from https://vim-jp.org/vimdoc-en/vim9class.html#Vim9-simple-class\n\nclass OtherThing\n   var size: number\n   static var totalSize: number\n\n   def new(this.size)\n      totalSize += this.size\n   enddef\n\n   static var _sum: number\n   public static var result: number\n\n   static def ClearTotalSize(): number\n      var prev = totalSize\n      totalSize = 0\n      return prev\n   enddef\nendclass\n\n\nclass YetOtherThing\n   static def _Foo()\n      echo \"Foo\"\n   enddef\n   def Bar()\n      _Foo()\n   enddef\nendclass\n\nclass A\n   final v1 = [1, 2]               # final object variable\n   public final v2 = {x: 1}        # final object variable\n   static final v3 = 'abc'         # final class variable\n   public static final v4 = 0z10   # final class variable\nendclass\n"
  },
  {
    "path": "Units/parser-vim.r/vim-class.d/input-1.vim",
    "content": "vim9script\n# Taken from https://vim-jp.org/vimdoc-en/vim9class.html#Vim9-simple-class\n\nabstract class Shape\n   var color = Color.Black\n   var thickness = 10\nendclass\n\nclass Square extends Shape\n   var size: number\n\n   def new(this.size)\n   enddef\nendclass\n\nclass Triangle extends Shape\n   var base: number\n   var height: number\n\n   def new(this.base, this.height)\n   enddef\nendclass\n"
  },
  {
    "path": "Units/parser-vim.r/vim-class.d/input.vim",
    "content": "vim9script\n# Derrived from\n# https://github.com/girishji/scope.vim/blob/271ad6d1b76e04cfacf5b30f80103654a2cfce73/autoload/scope/task.vim\n\nexport class AsyncCmd\n    var job: job\n\n    def Stop(how: string = '')\n        if this.job->job_status() ==# 'run'\n            how->empty() ? this.job->job_stop() : this.job->job_stop(how)\n        endif\n    enddef\n\n    def new(cmd: any, CallbackFn: func(list<string>), env: dict<any> = null_dict)\n        # ch_logfile('/tmp/channellog', 'w')\n        # ch_log('BuildItemsList call')\n        var items = []\n        this.Stop('kill')\n        if cmd->empty()\n            return\n        endif\n        var start = reltime()\n        this.job = job_start(cmd, {\n            out_cb: (ch, str) => {\n                # out_cb is invoked when channel reads 1 line; if you don't care\n                # about intermediate output use close_cb\n                items->add(str)\n                if start->reltime()->reltimefloat() * 1000 > 100 # update every 100ms\n                    CallbackFn(items)\n                    start = reltime()\n                endif\n            },\n            close_cb: (ch) =>  CallbackFn(items),\n            err_cb: (chan: channel, msg: string) => {\n                # ignore errors\n                # :echohl ErrorMsg | echoerr $'error: {msg} from {cmd}' | echohl None\n            },\n        }->extend(env != null_dict ? {env: env} : {}))\n    enddef\nendclass\n"
  },
  {
    "path": "Units/parser-vim.r/vim-command-in-function.d/expected.tags",
    "content": "MyCommand\tinput.vim\t/^  command! MyCommand echom \"foo\"$/;\"\tc\n"
  },
  {
    "path": "Units/parser-vim.r/vim-command-in-function.d/input.vim",
    "content": "fun! f()\n  command! MyCommand echom \"foo\"\nendfun\n"
  },
  {
    "path": "Units/parser-vim.r/vim-command-not-command.d/README",
    "content": "expected.tags must be empty. \nsinglequote after \"command\" is invalid syntax in vim.\n"
  },
  {
    "path": "Units/parser-vim.r/vim-command-not-command.d/expected.tags",
    "content": ""
  },
  {
    "path": "Units/parser-vim.r/vim-command-not-command.d/input.vim",
    "content": "command 'x'"
  },
  {
    "path": "Units/parser-vim.r/vim-command.d/expected.tags",
    "content": "Foo\tinput.vim\t/^com Foo call Foo()$/;\"\tc\n"
  },
  {
    "path": "Units/parser-vim.r/vim-command.d/input.vim",
    "content": "com Foo call Foo()\n\n\" No endless loop: https://github.com/fishman/ctags/issues/74.\n\" TODO\n\" com ''\n\n\" No sefault; https://github.com/fishman/ctags/issues/72.\ncom -complete=Foo\n"
  },
  {
    "path": "Units/parser-vim.r/vim-const.d/args.ctags",
    "content": "--sort=no\n--fields=+t\n"
  },
  {
    "path": "Units/parser-vim.r/vim-const.d/expected.tags",
    "content": "s:CONSTANT\tinput.vim\t/^const s:CONSTANT = 42$/;\"\tC\nmatches\tinput-0.vim\t/^final matches = []$/;\"\tC\nnames\tinput-0.vim\t/^const names = ['Betty', 'Peter']$/;\"\tC\nLINK\tinput-0.vim\t/^const LINK: string = '->'$/;\"\tC\ttyperef:typename:string\nmylist\tinput-0.vim\t/^final mylist: list<string> = ['foo']$/;\"\tC\ttyperef:typename:list<string>\n"
  },
  {
    "path": "Units/parser-vim.r/vim-const.d/input-0.vim",
    "content": "vim9script\n\n# Taken from https://vim-jp.org/vimdoc-ja/vim9.html#vim9-differences\nfinal matches = []\nconst names = ['Betty', 'Peter']\n\nconst LINK: string = '->'\n\n# Taken from ~/var/vim/runtime/doc/vim9.txt\nfinal mylist: list<string> = ['foo']\n"
  },
  {
    "path": "Units/parser-vim.r/vim-const.d/input.vim",
    "content": "const s:CONSTANT = 42\n"
  },
  {
    "path": "Units/parser-vim.r/vim-heredoc.d/args.ctags",
    "content": "--sort=no\n--kinds-vim=+h\n--extras=+r\n--fields=+re\n"
  },
  {
    "path": "Units/parser-vim.r/vim-heredoc.d/expected.tags",
    "content": "var1\tinput.vim\t/^let var1 =<< trim END$/;\"\tv\troles:def\nEND\tinput.vim\t/^let var1 =<< trim END$/;\"\th\troles:def\tend:4\nEND\tinput.vim\t/^END$/;\"\th\troles:endmarker\nvar2\tinput.vim\t/^let var2 =<< END$/;\"\tv\troles:def\nEND\tinput.vim\t/^let var2 =<< END$/;\"\th\troles:def\tend:9\nEND\tinput.vim\t/^END$/;\"\th\troles:endmarker\n"
  },
  {
    "path": "Units/parser-vim.r/vim-heredoc.d/input.vim",
    "content": "let var1 =<< trim END\n\tfunction! Foo(arg)\n\tendfunction\nEND\n\nlet var2 =<< END\nfunction! Bar(arg)\nendfunction\nEND\n"
  },
  {
    "path": "Units/parser-vim.r/vim-let-in-function.d/expected.tags",
    "content": "Func\tinput.vim\t/^function Func()$/;\"\tf\ng:global_var\tinput.vim\t/^  let g:global_var = 42$/;\"\tv\n"
  },
  {
    "path": "Units/parser-vim.r/vim-let-in-function.d/input.vim",
    "content": "function Func()\n  let g:global_var = 42\n  let g_local_var = 42\nendfunction\n"
  },
  {
    "path": "Units/parser-vim.r/vim-map-special-args.d/expected.tags",
    "content": "foo\tinput.vim\t/^map <buffer> <nowait> <silent> <special> <script> <expr> <unique> foo bar$/;\"\tm\n"
  },
  {
    "path": "Units/parser-vim.r/vim-map-special-args.d/input.vim",
    "content": "map <buffer> <nowait> <silent> <special> <script> <expr> <unique> foo bar\n"
  },
  {
    "path": "Units/parser-vim.r/vim-signature.d/args.ctags",
    "content": "--fields=+{signature}\n--sort=no\n"
  },
  {
    "path": "Units/parser-vim.r/vim-signature.d/expected.tags",
    "content": "s:ShellEscape\tinput.vim\t/^fun! s:ShellEscape(s, ...)$/;\"\tf\tsignature:(s,...)\ns:Foo\tinput.vim\t/^fun! s:Foo()$/;\"\tf\tsignature:()\ns:Broken\tinput.vim\t/^function! s:Broken (arg$/;\"\tf\ns:GetTokensFromLine\tinput.vim\t/^function! s:GetTokensFromLine(line, string_continuation, atom_continuation,$/;\"\tf\tsignature:(line,string_continuation,atom_continuation,tabstop)\n"
  },
  {
    "path": "Units/parser-vim.r/vim-signature.d/input.vim",
    "content": "\" Taken from vim82/autoload/netrw.vim\n\" ---------------------------------------------------------------------\n\" s:ShellEscape: shellescape(), or special windows handling {{{2\nfun! s:ShellEscape(s, ...)\n  if (has('win32') || has('win64')) && $SHELL == '' && &shellslash\n    return printf('\"%s\"', substitute(a:s, '\"', '\"\"', 'g'))\n  endif \n  let f = a:0 > 0 ? a:1 : 0\n  return shellescape(a:s, f)\nendfun\n\nfun! s:Foo()\n     return []\nendfun\n\nfunction! s:Broken (arg\n  return []\nendfun\n\n\" Taken from vim82/indent/erlang.vim\nfunction! s:GetTokensFromLine(line, string_continuation, atom_continuation,\n                             \\tabstop)\n\n  let linelen = strlen(a:line) \" The length of the line\n  let i = 0 \" The index of the current character in the line\n  let vcol = 0 \" The virtual column of the current character\n  let indtokens = []\n\n  if a:string_continuation\n    let i = matchend(a:line, '^\\%([^\"\\\\]\\|\\\\.\\)*\"', 0)\n    if i ==# -1\n      call s:Log('    Whole line is string continuation -> ignore')\n      return []\n    else\n      let vcol = s:CalcVCol(a:line, 0, i - 1, 0, a:tabstop)\n      call add(indtokens, ['<string_end>', vcol, i])\n    endif\n  elseif a:atom_continuation\n    let i = matchend(a:line, \"^\\\\%([^'\\\\\\\\]\\\\|\\\\\\\\.\\\\)*'\", 0)\n    if i ==# -1\n      call s:Log('    Whole line is quoted atom continuation -> ignore')\n      return []\n    else\n      let vcol = s:CalcVCol(a:line, 0, i - 1, 0, a:tabstop)\n      call add(indtokens, ['<quoted_atom_end>', vcol, i])\n    endif\n  endif\n\n  while 0 <= i && i < linelen\n\n    let next_vcol = ''\n\n    \" Spaces\n    if a:line[i] ==# ' '\n      let next_i = matchend(a:line, ' *', i + 1)\n\n    \" Tabs\n    elseif a:line[i] ==# \"\\t\"\n      let next_i = matchend(a:line, '\\t*', i + 1)\n\n      \" See example in s:CalcVCol\n      let next_vcol = (vcol / a:tabstop + (next_i - i)) * a:tabstop\n\n    \" Comment\n    elseif a:line[i] ==# '%'\n      let next_i = linelen\n\n    \" String token: \"...\"\n    elseif a:line[i] ==# '\"'\n      let next_i = matchend(a:line, '\\%([^\"\\\\]\\|\\\\.\\)*\"', i + 1)\n      if next_i ==# -1\n        call add(indtokens, ['<string_start>', vcol, i])\n      else\n        let next_vcol = s:CalcVCol(a:line, i, next_i - 1, vcol, a:tabstop)\n        call add(indtokens, ['<string>', vcol, i])\n      endif\n\n    \" Quoted atom token: '...'\n    elseif a:line[i] ==# \"'\"\n      let next_i = matchend(a:line, \"\\\\%([^'\\\\\\\\]\\\\|\\\\\\\\.\\\\)*'\", i + 1)\n      if next_i ==# -1\n        call add(indtokens, ['<quoted_atom_start>', vcol, i])\n      else\n        let next_vcol = s:CalcVCol(a:line, i, next_i - 1, vcol, a:tabstop)\n        call add(indtokens, ['<quoted_atom>', vcol, i])\n      endif\n\n    \" Keyword or atom or variable token or number\n    elseif a:line[i] =~# '[a-zA-Z_@0-9]'\n      let next_i = matchend(a:line,\n                           \\'[[:alnum:]_@:]*\\%(\\s*#\\s*[[:alnum:]_@:]*\\)\\=',\n                           \\i + 1)\n      call add(indtokens, [a:line[(i):(next_i - 1)], vcol, i])\n\n    \" Character token: $<char> (as in: $a)\n    elseif a:line[i] ==# '$'\n      call add(indtokens, ['$.', vcol, i])\n      let next_i = i + 2\n\n    \" Dot token: .\n    elseif a:line[i] ==# '.'\n\n      let next_i = i + 1\n\n      if i + 1 ==# linelen || a:line[i + 1] =~# '[[:blank:]%]'\n        \" End of clause token: . (as in: f() -> ok.)\n        call add(indtokens, ['<end_of_clause>', vcol, i])\n\n      else\n        \" Possibilities:\n        \" - Dot token in float: . (as in: 3.14)\n        \" - Dot token in record: . (as in: #myrec.myfield)\n        call add(indtokens, ['.', vcol, i])\n      endif\n\n    \" Equal sign\n    elseif a:line[i] ==# '='\n      \" This is handled separately so that \"=<<\" will be parsed as\n      \" ['=', '<<'] instead of ['=<', '<']. Although Erlang parses it\n      \" currently in the latter way, that may be fixed some day.\n      call add(indtokens, [a:line[i], vcol, i])\n      let next_i = i + 1\n\n    \" Three-character tokens\n    elseif i + 1 < linelen &&\n         \\ index(['=:=', '=/='], a:line[i : i + 1]) != -1\n      call add(indtokens, [a:line[i : i + 1], vcol, i])\n      let next_i = i + 2\n\n    \" Two-character tokens\n    elseif i + 1 < linelen &&\n         \\ index(['->', '<<', '>>', '||', '==', '/=', '=<', '>=', '++', '--',\n         \\        '::'],\n         \\       a:line[i : i + 1]) != -1\n      call add(indtokens, [a:line[i : i + 1], vcol, i])\n      let next_i = i + 2\n\n    \" Other character: , ; < > ( ) [ ] { } # + - * / : ? = ! |\n    else\n      call add(indtokens, [a:line[i], vcol, i])\n      let next_i = i + 1\n\n    endif\n\n    if next_vcol ==# ''\n      let vcol += next_i - i\n    else\n      let vcol = next_vcol\n    endif\n\n    let i = next_i\n\n  endwhile\n\n  return indtokens\n\nendfunction\n"
  },
  {
    "path": "Units/parser-vim.r/vim9-def-function.d/args.ctags",
    "content": "--sort=no\n--fields=+tS\n"
  },
  {
    "path": "Units/parser-vim.r/vim9-def-function.d/expected.tags",
    "content": "Func\tinput.vim\t/^def Func()$/;\"\tf\tsignature:()\nFunc2\tinput.vim\t/^def Func2(): number$/;\"\tf\ttyperef:typename:number\tsignature:()\n"
  },
  {
    "path": "Units/parser-vim.r/vim9-def-function.d/input.vim",
    "content": "def Func()\nenddef\n\nvim9script\ndef Func2(): number\n\treturn 0\nenddef\n"
  },
  {
    "path": "Units/parser-vim.r/vim9-export.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-vim.r/vim9-export.d/expected.tags",
    "content": "EXPORTED_CONST\tinput.vim\t/^export const EXPORTED_CONST = 1234$/;\"\tC\nv\tinput.vim\t/^export var v = 1$/;\"\tv\nf\tinput.vim\t/^export final f = 2$/;\"\tC\nc\tinput.vim\t/^export const c = 3$/;\"\tC\nMyFunc\tinput.vim\t/^export def MyFunc()$/;\"\tf\n"
  },
  {
    "path": "Units/parser-vim.r/vim9-export.d/input.vim",
    "content": "vim9script\n\nexport const EXPORTED_CONST = 1234\nexport var v = 1\nexport final f = 2\nexport const c = 3\nexport def MyFunc()\n       echo \"hello\"\nenddef\n\n# export class MyClass ...\n# export interface MyClass ...\n"
  },
  {
    "path": "Units/parser-vim.r/vim9-var.d/args.ctags",
    "content": "--sort=no\n--fields=+St\n"
  },
  {
    "path": "Units/parser-vim.r/vim9-var.d/expected.tags",
    "content": "cur_menu_name\tinput.vim\t/^var cur_menu_name = \"\"$/;\"\tv\ncur_menu_nr\tinput.vim\t/^var cur_menu_nr = 0$/;\"\tv\ncur_menu_item\tinput.vim\t/^var cur_menu_item: number = 0$/;\"\tv\ttyperef:typename:number\ncur_menu_char\tinput.vim\t/^var cur_menu_char = \"\"$/;\"\tv\nlanguage_section\tinput.vim\t/^var language_section: list<string> =<< trim END$/;\"\tv\ttyperef:typename:list<string>\n"
  },
  {
    "path": "Units/parser-vim.r/vim9-var.d/input.vim",
    "content": "vim9script\n\n# Taken from vim/runtime/makemenu.vim\n\nvar cur_menu_name = \"\"\nvar cur_menu_nr = 0\nvar cur_menu_item: number = 0\nvar cur_menu_char = \"\"\n\n# Taken from vim/runtime/import/dist/vimhighlight.vim\n\nvar language_section: list<string> =<< trim END\n\n    Highlighting groups for language syntaxes\n    -----------------------------------------\n\nEND\n"
  },
  {
    "path": "Units/parser-vim.r/vimball.vim.d/expected.tags",
    "content": "hello.vim\tinput.vba\t/^hello.vim\t[[[1$/;\"\tn\n"
  },
  {
    "path": "Units/parser-vim.r/vimball.vim.d/input.vba",
    "content": "\" Vimball Archiver by Charles E. Campbell\nUseVimball\nfinish\nhello.vim\t[[[1\n1\ncommand! HelloWorld :echo \"Hello World!\"\n"
  },
  {
    "path": "Units/parser-xml.r/doctype.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+l\n"
  },
  {
    "path": "Units/parser-xml.r/doctype.d/expected.tags",
    "content": "book\tinput.xml\t/^<!DOCTYPE book [$/;\"\tr\tlanguage:XML\nns8b4f64860101\tinput.xml\t/^<book xmlns=\"http:\\/\\/docbook.org\\/ns\\/docbook\" version=\"5.0\">$/;\"\tn\tlanguage:XML\turi:http://docbook.org/ns/docbook\nchap1\tinput.xml\t/^<!ENTITY chap1 SYSTEM \"chap1.xml\">$/;\"\tE\tlanguage:DTD\nchap2\tinput.xml\t/^<!ENTITY chap2 SYSTEM \"chap2.xml\">$/;\"\tE\tlanguage:DTD\nchap3\tinput.xml\t/^<!ENTITY chap3 SYSTEM \"chap3.xml\">$/;\"\tE\tlanguage:DTD\nappa\tinput.xml\t/^<!ENTITY appa SYSTEM \"appa.xml\">$/;\"\tE\tlanguage:DTD\nappb\tinput.xml\t/^<!ENTITY appb SYSTEM \"appb.xml\">$/;\"\tE\tlanguage:DTD\n"
  },
  {
    "path": "Units/parser-xml.r/doctype.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-xml.r/doctype.d/input.xml",
    "content": "<?xml version=\"1.0\" standalone=\"no\"?>\n<!DOCTYPE book [\n<!ENTITY chap1 SYSTEM \"chap1.xml\">\n<!ENTITY chap2 SYSTEM \"chap2.xml\">\n<!ENTITY chap3 SYSTEM \"chap3.xml\">\n<!ENTITY appa SYSTEM \"appa.xml\">\n<!ENTITY appb SYSTEM \"appb.xml\">\n]>\n<book xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\">\n<title>My First Book</title>\n&chap1;\n&chap2;\n&chap3;\n&appa;\n&appb;\n</book>\n"
  },
  {
    "path": "Units/parser-xml.r/dos-eol.d/.gitattributes",
    "content": "input.xml\ttext eol=crlf\ninput-0.xml\ttext eol=crlf\n"
  },
  {
    "path": "Units/parser-xml.r/dos-eol.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n"
  },
  {
    "path": "Units/parser-xml.r/dos-eol.d/expected.tags",
    "content": "root\tinput.xml\t/^<!DOCTYPE root [$/;\"\tr\ndeftest\tinput.xml\t/^<!ENTITY % deftest '&#60;!ELEMENT test (#PCDATA) >' >$/;\"\tp\ndefmiddle\tinput.xml\t/^<!ENTITY % defmiddle '&#60;!ELEMENT middle (test) >' >$/;\"\tp\ndefroot\tinput.xml\t/^<!ENTITY % defroot '&#60;!ELEMENT root (middle) >' >$/;\"\tp\nroot\tinput-0.xml\t/^<!DOCTYPE root [$/;\"\tr\ndeftest\tinput-0.xml\t/^<!ENTITY % deftest '&#60;!ELEMENT test (#PCDATA) >' >$/;\"\tp\ndefmiddle\tinput-0.xml\t/^<!ENTITY % defmiddle '&#60;!ELEMENT middle (test) >' >$/;\"\tp\ndefroot\tinput-0.xml\t/^<!ENTITY % defroot '&#60;!ELEMENT root (middle) >' >$/;\"\tp\n"
  },
  {
    "path": "Units/parser-xml.r/dos-eol.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-xml.r/dos-eol.d/input-0.xml",
    "content": "﻿<?xml version='1.0'?>\r\n<!DOCTYPE root [\r\n<!ENTITY % deftest '&#60;!ELEMENT test (#PCDATA) >' >\r\n<!ENTITY % defmiddle '&#60;!ELEMENT middle (test) >' >\r\n<!ENTITY % defroot '&#60;!ELEMENT root (middle) >' >\r\n%defroot;%defmiddle;%deftest;\r\n]>\r\n<root><middle><test>sample</test></middle></root>\r\n<!-- Derrived from test/valid/t9a.xml in\r\n     https://gitlab.gnome.org/GNOME/libxml2/-/releases/v2.9.13\r\n     UTF-8 BOM is prepended .-->\r\n"
  },
  {
    "path": "Units/parser-xml.r/dos-eol.d/input.xml",
    "content": "<?xml version='1.0'?>\r\n<!DOCTYPE root [\r\n<!ENTITY % deftest '&#60;!ELEMENT test (#PCDATA) >' >\r\n<!ENTITY % defmiddle '&#60;!ELEMENT middle (test) >' >\r\n<!ENTITY % defroot '&#60;!ELEMENT root (middle) >' >\r\n%defroot;%defmiddle;%deftest;\r\n]>\r\n<root><middle><test>sample</test></middle></root>\r\n<!-- Taken from test/valid/t9a.xml in\r\n     https://gitlab.gnome.org/GNOME/libxml2/-/releases/v2.9.13 -->\r\n"
  },
  {
    "path": "Units/parser-xml.r/ns-with-no-prefix.d/expected.tags",
    "content": "nscb9c983d0101\tinput.xml\t/^<input xmlns=\"https:\\/\\/ctags.io\\/root\">$/;\"\tn\turi:https://ctags.io/root\n"
  },
  {
    "path": "Units/parser-xml.r/ns-with-no-prefix.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-xml.r/ns-with-no-prefix.d/input.xml",
    "content": "<input xmlns=\"https://ctags.io/root\">\n  <foo/>\n</input>\n"
  },
  {
    "path": "Units/parser-xml.r/simple-xml.d/args.ctags",
    "content": "--sort=no\n--fields=+lxn\n"
  },
  {
    "path": "Units/parser-xml.r/simple-xml.d/expected.tags",
    "content": "nsa9858b760101\tinput.xml\t/^       >$/;\"\tn\tline:4\tlanguage:XML\turi:https://ctags.io/root\nabc\tinput.xml\t/^       >$/;\"\tn\tline:4\tlanguage:XML\turi:https://ctags.io/nosuchthing\nunused\tinput.xml\t/^       >$/;\"\tn\tline:4\tlanguage:XML\turi:https://ctags.io/unused\nefg\tinput.xml\t/^<abc:UnKnownTag id=\"a\" xmlns:efg=\"https:\\/\\/ctags.io\\/nosuchthing2\">$/;\"\tn\tline:5\tlanguage:XML\turi:https://ctags.io/nosuchthing2\na\tinput.xml\t/^<abc:UnKnownTag id=\"a\" xmlns:efg=\"https:\\/\\/ctags.io\\/nosuchthing2\">$/;\"\ti\tline:5\tlanguage:XML\txpath:/*/abc:UnKnownTag/@id\nb\tinput.xml\t/^  <efg:UnKnownTag2 id=\"b\"\\/>$/;\"\ti\tline:6\tlanguage:XML\txpath:/*/abc:UnKnownTag/efg:UnKnownTag2/@id\n"
  },
  {
    "path": "Units/parser-xml.r/simple-xml.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-xml.r/simple-xml.d/input.xml",
    "content": "<input xmlns=\"https://ctags.io/root\"\n       xmlns:abc=\"https://ctags.io/nosuchthing\"\n       xmlns:unused=\"https://ctags.io/unused\"\n       >\n<abc:UnKnownTag id=\"a\" xmlns:efg=\"https://ctags.io/nosuchthing2\">\n  <efg:UnKnownTag2 id=\"b\"/>\n</abc:UnKnownTag>\n</input>\n"
  },
  {
    "path": "Units/parser-xslt.r/xslt-simple.d/args.ctags",
    "content": "--sort=no\n--fields=+r\n--extras=+r\n"
  },
  {
    "path": "Units/parser-xslt.r/xslt-simple.d/expected.tags",
    "content": "xsl\tinput.xsl\t/^  xmlns=\"http:\\/\\/www.w3.org\\/TR\\/REC-html40\">$/;\"\tn\troles:def\turi:http://www.w3.org/1999/XSL/Transform\ngjdoc\tinput.xsl\t/^  xmlns=\"http:\\/\\/www.w3.org\\/TR\\/REC-html40\">$/;\"\tn\troles:def\turi:http://www.gnu.org/software/cp-tools/gjdocxml\nhtml\tinput.xsl\t/^  xmlns=\"http:\\/\\/www.w3.org\\/TR\\/REC-html40\">$/;\"\tn\troles:def\turi:http://www.w3.org/TR/REC-html40\nns9777d4f00101\tinput.xsl\t/^  xmlns=\"http:\\/\\/www.w3.org\\/TR\\/REC-html40\">$/;\"\tn\troles:def\turi:http://www.w3.org/TR/REC-html40\nhtml_common.xsl\tinput.xsl\t/^  <xsl:include href=\"html_common.xsl\"\\/>$/;\"\ts\troles:included\n/\tinput.xsl\t/^  <xsl:template match=\"\\/\">$/;\"\tm\troles:def\noutput_title\tinput.xsl\t/^        <xsl:call-template name=\"output_title\">$/;\"\tn\tmatchedTemplate:/\troles:called\np_pagetitle\tinput.xsl\t/^          <xsl:with-param name=\"p_pagetitle\" select=\"$gjdoc.outputfile.info\"\\/>$/;\"\tp\tnamedTemplate:/.output_title\troles:bound\ninclude_common\tinput.xsl\t/^        <xsl:call-template name=\"include_common\"\\/>$/;\"\tn\tmatchedTemplate:/\troles:called\noutput_navbar\tinput.xsl\t/^        <xsl:call-template name=\"output_navbar\">$/;\"\tn\tmatchedTemplate:/\troles:called\np_show_package\tinput.xsl\t/^          <xsl:with-param name=\"p_show_package\" select=\"0\"\\/>$/;\"\tp\tnamedTemplate:/.output_navbar\troles:bound\np_curr_package\tinput.xsl\t/^          <xsl:with-param name=\"p_curr_package\" select=\"1\"\\/>$/;\"\tp\tnamedTemplate:/.output_navbar\troles:bound\np_show_package_tree\tinput.xsl\t/^          <xsl:with-param name=\"p_show_package_tree\" select=\"1\"\\/>$/;\"\tp\tnamedTemplate:/.output_navbar\troles:bound\np_top\tinput.xsl\t/^          <xsl:with-param name=\"p_top\" select=\"1\"\\/> $/;\"\tp\tnamedTemplate:/.output_navbar\troles:bound\noutput_navbar\tinput.xsl\t/^        <xsl:call-template name=\"output_navbar\">$/;\"\tn\tmatchedTemplate:/\troles:called\np_show_package\tinput.xsl\t/^          <xsl:with-param name=\"p_show_package\" select=\"0\"\\/>$/;\"\tp\tnamedTemplate:/.output_navbar\troles:bound\np_curr_package\tinput.xsl\t/^          <xsl:with-param name=\"p_curr_package\" select=\"1\"\\/>$/;\"\tp\tnamedTemplate:/.output_navbar\troles:bound\np_show_package_tree\tinput.xsl\t/^          <xsl:with-param name=\"p_show_package_tree\" select=\"1\"\\/>$/;\"\tp\tnamedTemplate:/.output_navbar\troles:bound\np_top\tinput.xsl\t/^          <xsl:with-param name=\"p_top\" select=\"0\"\\/> $/;\"\tp\tnamedTemplate:/.output_navbar\troles:bound\n/gjdoc:rootdoc/gjdoc:packagedoc[@name=$gjdoc.outputfile.info]/gjdoc:firstSentenceTags/node()\tinput.xsl\t/^          <xsl:apply-templates select=\"\\/gjdoc:rootdoc\\/gjdoc:packagedoc[@name=$gjdoc.outputfile/;\"\tm\tmatchedTemplate:/\troles:applied\noutput-classes-summary\tinput.xsl\t/^              <xsl:call-template name=\"output-classes-summary\"\\/>$/;\"\tn\tmatchedTemplate:/\troles:called\noutput-classes-summary\tinput.xsl\t/^              <xsl:call-template name=\"output-classes-summary\"\\/>$/;\"\tn\tmatchedTemplate:/\troles:called\noutput-classes-summary\tinput.xsl\t/^              <xsl:call-template name=\"output-classes-summary\"\\/>$/;\"\tn\tmatchedTemplate:/\troles:called\noutput-classes-summary\tinput.xsl\t/^              <xsl:call-template name=\"output-classes-summary\"\\/>$/;\"\tn\tmatchedTemplate:/\troles:called\n/gjdoc:rootdoc/gjdoc:packagedoc[@name=$gjdoc.outputfile.info]/gjdoc:inlineTags/node()\tinput.xsl\t/^          <xsl:apply-templates select=\"\\/gjdoc:rootdoc\\/gjdoc:packagedoc[@name=$gjdoc.outputfile/;\"\tm\tmatchedTemplate:/\troles:applied\noutput-classes-summary\tinput.xsl\t/^  <xsl:template name=\"output-classes-summary\">$/;\"\tn\troles:def\nv_currentclass\tinput.xsl\t/^    <xsl:variable name=\"v_currentclass\" select=\"@qualifiedtypename\"\\/>$/;\"\tv\tnamedTemplate:output-classes-summary\troles:def\nv_sub_xml_filename\tinput.xsl\t/^    <xsl:variable name=\"v_sub_xml_filename\" select=\"concat(@qualifiedtypename,'.xml')\"\\/>$/;\"\tv\tnamedTemplate:output-classes-summary\troles:def\nv_docstring\tinput.xsl\t/^        <xsl:variable name=\"v_docstring\" select=\"document($v_sub_xml_filename,\\/gjdoc:rootdoc)\\//;\"\tv\tnamedTemplate:output-classes-summary\troles:def\n"
  },
  {
    "path": "Units/parser-xslt.r/xslt-simple.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/parser-xslt.r/xslt-simple.d/input.xsl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<!-- packagedoc.xsl\n     Copyright (C) 2003 Free Software Foundation, Inc.\n     \n     This file is part of GNU Classpath.\n     \n     GNU Classpath is free software; you can redistribute it and/or modify\n     it under the terms of the GNU General Public License as published by\n     the Free Software Foundation; either version 2, or (at your option)\n     any later version.\n      \n     GNU Classpath is distributed in the hope that it will be useful, but\n     WITHOUT ANY WARRANTY; without even the implied warranty of\n     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n     General Public License for more details.\n     \n     You should have received a copy of the GNU General Public License\n     along with GNU Classpath; see the file COPYING.  If not, write to the\n     Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\n     02111-1307 USA.\n     -->\n\n<!-- Creates the package descriptor files for HTML documentation. \n     -->\n\n<xsl:stylesheet version=\"1.0\"\n  xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n  xmlns:gjdoc=\"http://www.gnu.org/software/cp-tools/gjdocxml\"\n  xmlns:html=\"http://www.w3.org/TR/REC-html40\"\n  xmlns=\"http://www.w3.org/TR/REC-html40\">\n\n  <xsl:include href=\"html_common.xsl\"/>\n\n  <xsl:output method=\"xml\"\n    encoding=\"utf-8\"\n    indent=\"no\"/>\n\n  <xsl:strip-space elements=\"*\"/>\n\n  <xsl:template match=\"/\">\n\n    <html>\n      <head>\n        <xsl:call-template name=\"output_title\">\n          <xsl:with-param name=\"p_pagetitle\" select=\"$gjdoc.outputfile.info\"/>\n        </xsl:call-template>\n        <xsl:call-template name=\"include_common\"/>\n      </head>\n      <body class=\"classdoc\" onload=\"if(parent.contentPageLoaded)parent.contentPageLoaded(getTitle())\">\n\n        <!-- Top Navigation Bar -->\n        <xsl:call-template name=\"output_navbar\">\n          <xsl:with-param name=\"p_show_package\" select=\"0\"/>\n          <xsl:with-param name=\"p_curr_package\" select=\"1\"/>\n          <xsl:with-param name=\"p_show_package_tree\" select=\"1\"/>\n          <xsl:with-param name=\"p_top\" select=\"1\"/> \n        </xsl:call-template>\n\n        <div class=\"pagebody\">\n\n        <h1 class=\"classdoc-title\">Package <xsl:value-of select=\"$gjdoc.outputfile.info\"/></h1>\n\n        <div class=\"classdoc-package-comment-body\">\n          <xsl:apply-templates select=\"/gjdoc:rootdoc/gjdoc:packagedoc[@name=$gjdoc.outputfile.info]/gjdoc:firstSentenceTags/node()\"/>\n        </div>\n\n        <xsl:if test=\"/gjdoc:rootdoc/gjdoc:classdoc[gjdoc:containingPackage/@name=$gjdoc.outputfile.info][gjdoc:isInterface]\">\n          <table border=\"1\" cellspacing=\"0\" width=\"100%\" class=\"classdoc-table\">\n            <tr><td colspan=\"2\" class=\"section-header\"><div class=\"section-header\">Interface Summary</div></td></tr>\n            <xsl:for-each select=\"/gjdoc:rootdoc/gjdoc:classdoc[gjdoc:containingPackage/@name=$gjdoc.outputfile.info][gjdoc:isInterface]\">\n              <xsl:sort select=\"@name\" order=\"ascending\"/>\n              <xsl:call-template name=\"output-classes-summary\"/>\n            </xsl:for-each>\n          </table>          \n        </xsl:if>\n\n        <xsl:if test=\"/gjdoc:rootdoc/gjdoc:classdoc[gjdoc:containingPackage/@name=$gjdoc.outputfile.info][gjdoc:isOrdinaryClass]\">\n          <table border=\"1\" cellspacing=\"0\" width=\"100%\" class=\"classdoc-table\">\n            <tr><td colspan=\"2\" class=\"section-header\"><div class=\"section-header\">Class Summary</div></td></tr>\n            <xsl:for-each select=\"/gjdoc:rootdoc/gjdoc:classdoc[gjdoc:containingPackage/@name=$gjdoc.outputfile.info][gjdoc:isOrdinaryClass]\">\n              <xsl:sort select=\"@name\" order=\"ascending\"/>\n              <xsl:call-template name=\"output-classes-summary\"/>\n            </xsl:for-each>\n          </table>\n        </xsl:if>\n\n        <xsl:if test=\"/gjdoc:rootdoc/gjdoc:classdoc[gjdoc:containingPackage/@name=$gjdoc.outputfile.info][gjdoc:isException]\">\n          <table border=\"1\" cellspacing=\"0\" width=\"100%\" class=\"classdoc-table\">\n            <tr><td colspan=\"2\" class=\"section-header\"><div class=\"section-header\">Exception Summary</div></td></tr>\n            <xsl:for-each select=\"/gjdoc:rootdoc/gjdoc:classdoc[gjdoc:containingPackage/@name=$gjdoc.outputfile.info][gjdoc:isException]\">\n              <xsl:sort select=\"@name\" order=\"ascending\"/>\n              <xsl:call-template name=\"output-classes-summary\"/>\n            </xsl:for-each>\n          </table>\n        </xsl:if>\n\n        <xsl:if test=\"/gjdoc:rootdoc/gjdoc:classdoc[gjdoc:containingPackage/@name=$gjdoc.outputfile.info][gjdoc:isError]\">\n          <table border=\"1\" cellspacing=\"0\" width=\"100%\" class=\"classdoc-table\">\n            <tr><td colspan=\"2\" class=\"section-header\"><div class=\"section-header\">Error Summary</div></td></tr>\n            <xsl:for-each select=\"/gjdoc:rootdoc/gjdoc:classdoc[gjdoc:containingPackage/@name=$gjdoc.outputfile.info][gjdoc:isError]\">\n              <xsl:sort select=\"@name\" order=\"ascending\"/>\n              <xsl:call-template name=\"output-classes-summary\"/>\n            </xsl:for-each>\n          </table>\n        </xsl:if>\n\n        <a name=\"description\"><p> </p></a>\n        <h1 class=\"classdoc-sub-title package-description\">Package <xsl:value-of select=\"$gjdoc.outputfile.info\"/> Description</h1>\n\n        <div class=\"classdoc-package-comment-body\">\n          <xsl:apply-templates select=\"/gjdoc:rootdoc/gjdoc:packagedoc[@name=$gjdoc.outputfile.info]/gjdoc:inlineTags/node()\"/>\n        </div>\n\n      </div>\n\n        <!-- Bottom Navigation Bar -->\n        <xsl:call-template name=\"output_navbar\">\n          <xsl:with-param name=\"p_show_package\" select=\"0\"/>\n          <xsl:with-param name=\"p_curr_package\" select=\"1\"/>\n          <xsl:with-param name=\"p_show_package_tree\" select=\"1\"/>\n          <xsl:with-param name=\"p_top\" select=\"0\"/> \n        </xsl:call-template>\n      </body>\n    </html>\n\n  </xsl:template>\n\n  <xsl:template name=\"output-classes-summary\">\n    <xsl:variable name=\"v_currentclass\" select=\"@qualifiedtypename\"/>\n    <xsl:variable name=\"v_sub_xml_filename\" select=\"concat(@qualifiedtypename,'.xml')\"/>\n    <tr>\n      <td class=\"class-link\">\n        <a href=\"{concat(@name, '.html')}\" class=\"package-link\">\n          <xsl:value-of select=\"@name\"/>\n        </a>\n      </td>\n      <td class=\"class-summary-description\">\n        <xsl:variable name=\"v_docstring\" select=\"document($v_sub_xml_filename,/gjdoc:rootdoc)/gjdoc:classdoc[@qualifiedtypename=$v_currentclass]/gjdoc:firstSentenceTags/node()\"/>\n        <xsl:choose>\n          <xsl:when test=\"$v_docstring\">\n            <xsl:for-each select=\"$v_docstring\">\n              <xsl:value-of select=\".\" disable-output-escaping=\"yes\"/>\n            </xsl:for-each>\n          </xsl:when>\n          <xsl:otherwise>\n            <i>No description available.</i>\n          </xsl:otherwise>\n        </xsl:choose>\n      </td>\n    </tr>\n  </xsl:template>\n</xsl:stylesheet>\n"
  },
  {
    "path": "Units/parser-yacc.r/bom.d/args.ctags",
    "content": "--extras=+g\n--fields=+n\n"
  },
  {
    "path": "Units/parser-yacc.r/bom.d/expected.tags",
    "content": "x\tinput.y\t/^int x;$/;\"\tv\tline:2\ttyperef:typename:int\ny\tinput.y\t/^int y;$/;\"\tv\tline:8\ttyperef:typename:int\n"
  },
  {
    "path": "Units/parser-yacc.r/bom.d/input.y",
    "content": "﻿%{\nint x;\n%}\n\n%%\n\n%%\nint y;\n"
  },
  {
    "path": "Units/parser-yacc.r/c-anon-ids.d/README",
    "content": "This test case is for verifying that anonGenerate() works expectedly\nwhen a parser runs twice on different areas of the same input.\n\ninput.y has two C areas.\nAnonymous structs are defined in each area.\nFour different anonIds must be generateda.\n"
  },
  {
    "path": "Units/parser-yacc.r/c-anon-ids.d/args.ctags",
    "content": "--sort=no\n--extra=+g\n--fields=-t\n"
  },
  {
    "path": "Units/parser-yacc.r/c-anon-ids.d/expected.tags",
    "content": "__anon04bc23ae0108\tinput.y\t/^\tstruct {$/;\"\ts\tfile:\nx\tinput.y\t/^\t\tint x, y;$/;\"\tm\tstruct:__anon04bc23ae0108\tfile:\ny\tinput.y\t/^\t\tint x, y;$/;\"\tm\tstruct:__anon04bc23ae0108\tfile:\npoint\tinput.y\t/^\t} point;$/;\"\tv\n__anon04bc23ae0208\tinput.y\t/^\tstruct {$/;\"\ts\tfile:\nx\tinput.y\t/^\t\tint x, y;$/;\"\tm\tstruct:__anon04bc23ae0208\tfile:\ny\tinput.y\t/^\t\tint x, y;$/;\"\tm\tstruct:__anon04bc23ae0208\tfile:\nvector\tinput.y\t/^\t} vector;$/;\"\tv\n"
  },
  {
    "path": "Units/parser-yacc.r/c-anon-ids.d/input.y",
    "content": "%{\n\tstruct {\n\t\tint x, y;\n\t} point;\n%}\n\n%%\n\n%%\n\tstruct {\n\t\tint x, y;\n\t} vector;\n\n"
  },
  {
    "path": "Units/parser-yacc.r/code-directive.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--kinds-C=+p\n--extras=+r\n"
  },
  {
    "path": "Units/parser-yacc.r/code-directive.d/expected.tags",
    "content": "PHP_JSON_T_NUL\tinput.y\t/^%token <value> PHP_JSON_T_NUL$/;\"\tt\ttyperef:typename:value\nPHP_JSON_T_EOI\tinput.y\t/^%token PHP_JSON_T_EOI$/;\"\tt\nstart\tinput.y\t/^start:$/;\"\tl\nphp.h\tinput.y\t/^#include \"php.h\"/;\"\th\njson_yydebug\tinput.y\t/^int json_yydebug = 1;$/;\"\tv\ttyperef:typename:int\n__anon5ae0960c010a\tinput.y\t/union {$/;\"\tu\tfile:\nvalue\tinput.y\t/^\tzval value;$/;\"\tm\tunion:__anon5ae0960c010a\ttyperef:typename:zval\tfile:\nphp_json_yylex\tinput.y\t/^static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser);$/;\"\tp\ttyperef:typename:int\tfile:\nphp_json_yyerror\tinput.y\t/^static void php_json_yyerror(php_json_parser *parser, char const *msg);$/;\"\tp\ttyperef:typename:void\tfile:\nphp_json_parser_array_create\tinput.y\t/^static int php_json_parser_array_create(php_json_parser *parser, zval *array)$/;\"\tf\ttyperef:typename:int\tfile:\n"
  },
  {
    "path": "Units/parser-yacc.r/code-directive.d/input.y",
    "content": "/* Based on php-pear/ext/json/json_parser.y */\n%require \"3.0\"\n%code top {\n#include \"php.h\"\nint json_yydebug = 1;\n}\n\n%define api.prefix {php_json_yy}\n%define api.pure full\n%param  { php_json_parser *parser  }\n\n%union {\n\tzval value;\n}\n\n\n%token <value> PHP_JSON_T_NUL\n%token PHP_JSON_T_EOI\n\n%destructor { zval_ptr_dtor_nogc(&$$); } <value>\n\n%code {\nstatic int php_json_yylex(union YYSTYPE *value, php_json_parser *parser);\nstatic void php_json_yyerror(php_json_parser *parser, char const *msg);\n}\n\n%% /* Rules */\n\nstart:\n\t\tvalue PHP_JSON_T_EOI\n\t\t\t{\n\t\t\t\tZVAL_COPY_VALUE(&$$, &$1);\n\t\t\t\tZVAL_COPY_VALUE(parser->return_value, &$1);\n\t\t\t\t(void) php_json_yynerrs;\n\t\t\t\tYYACCEPT;\n\t\t\t}\n;\n\n\n%% /* Functions */\n\nstatic int php_json_parser_array_create(php_json_parser *parser, zval *array)\n{\n\tarray_init(array);\n\treturn SUCCESS;\n}\n\n"
  },
  {
    "path": "Units/parser-yacc.r/nested.d/args.ctags",
    "content": "--sort=no\n--extras=+gf\n--kinds-C=+px\n--fields=+lE\n"
  },
  {
    "path": "Units/parser-yacc.r/nested.d/expected.tags",
    "content": "END_OF_FILE\tinput.y\t/^\tEND_OF_FILE\t0$/;\"\tt\tlanguage:YACC\nERROR\tinput.y\t/^\tERROR\t\t255$/;\"\tt\tlanguage:YACC\nBELL\tinput.y\t/^\tBELL\t\t1$/;\"\tt\tlanguage:YACC\nACCESSX\tinput.y\t/^\tACCESSX\t\t2$/;\"\tt\tlanguage:YACC\nMESSAGE\tinput.y\t/^\tMESSAGE\t\t3$/;\"\tt\tlanguage:YACC\nNONE\tinput.y\t/^\tNONE\t\t20$/;\"\tt\tlanguage:YACC\nIGNORE\tinput.y\t/^\tIGNORE\t\t21$/;\"\tt\tlanguage:YACC\nECHO\tinput.y\t/^\tECHO\t\t22$/;\"\tt\tlanguage:YACC\nPRINT_EV\tinput.y\t/^\tPRINT_EV\t23$/;\"\tt\tlanguage:YACC\nSHELL\tinput.y\t/^\tSHELL\t\t24$/;\"\tt\tlanguage:YACC\nSOUND\tinput.y\t/^\tSOUND\t\t25$/;\"\tt\tlanguage:YACC\nEQUALS\tinput.y\t/^\tEQUALS\t\t40$/;\"\tt\tlanguage:YACC\nPLUS\tinput.y\t/^\tPLUS\t\t41$/;\"\tt\tlanguage:YACC\nMINUS\tinput.y\t/^\tMINUS\t\t42$/;\"\tt\tlanguage:YACC\nDIVIDE\tinput.y\t/^\tDIVIDE\t\t43$/;\"\tt\tlanguage:YACC\nTIMES\tinput.y\t/^\tTIMES\t\t44$/;\"\tt\tlanguage:YACC\nOBRACE\tinput.y\t/^\tOBRACE\t\t45$/;\"\tt\tlanguage:YACC\nCBRACE\tinput.y\t/^\tCBRACE\t\t46$/;\"\tt\tlanguage:YACC\nOPAREN\tinput.y\t/^\tOPAREN\t\t47$/;\"\tt\tlanguage:YACC\nCPAREN\tinput.y\t/^\tCPAREN\t\t48$/;\"\tt\tlanguage:YACC\nOBRACKET\tinput.y\t/^\tOBRACKET\t49$/;\"\tt\tlanguage:YACC\nCBRACKET\tinput.y\t/^\tCBRACKET\t50$/;\"\tt\tlanguage:YACC\nDOT\tinput.y\t/^\tDOT\t\t51$/;\"\tt\tlanguage:YACC\nCOMMA\tinput.y\t/^\tCOMMA\t\t52$/;\"\tt\tlanguage:YACC\nSEMI\tinput.y\t/^\tSEMI\t\t53$/;\"\tt\tlanguage:YACC\nEXCLAM\tinput.y\t/^\tEXCLAM\t\t54$/;\"\tt\tlanguage:YACC\nINVERT\tinput.y\t/^\tINVERT\t\t55$/;\"\tt\tlanguage:YACC\nSTRING\tinput.y\t/^\tSTRING\t\t60$/;\"\tt\tlanguage:YACC\nINTEGER\tinput.y\t/^\tINTEGER\t\t61$/;\"\tt\tlanguage:YACC\nFLOAT\tinput.y\t/^\tFLOAT\t\t62$/;\"\tt\tlanguage:YACC\nIDENT\tinput.y\t/^\tIDENT\t\t63$/;\"\tt\tlanguage:YACC\nKEYNAME\tinput.y\t/^\tKEYNAME\t\t64$/;\"\tt\tlanguage:YACC\nCfgFile\tinput.y\t/^CfgFile\t\t$/;\"\tl\tlanguage:YACC\ttyperef:typename:entry\nCfgEntryList\tinput.y\t/^CfgEntryList\t:\tCfgEntryList CfgEntry$/;\"\tl\tlanguage:YACC\ttyperef:typename:entry\nCfgEntry\tinput.y\t/^CfgEntry\t:\tEventDef ActionDef$/;\"\tl\tlanguage:YACC\ttyperef:typename:entry\nVarDef\tinput.y\t/^VarDef\t\t:\tIdent EQUALS NameSpec$/;\"\tl\tlanguage:YACC\ttyperef:typename:entry\nEventDef\tinput.y\t/^EventDef\t:\tEventType OPAREN OptNameSpec CPAREN$/;\"\tl\tlanguage:YACC\ttyperef:typename:entry\nEventType\tinput.y\t/^EventType\t:\tBELL\t\t{ $$= XkbBellNotify; }$/;\"\tl\tlanguage:YACC\ttyperef:typename:ival\nActionDef\tinput.y\t/^ActionDef\t:\tActionType OptString$/;\"\tl\tlanguage:YACC\ttyperef:typename:act\nActionType\tinput.y\t/^ActionType\t:\tNONE\t { $$ = NoAction; }$/;\"\tl\tlanguage:YACC\ttyperef:typename:ival\nOptNameSpec\tinput.y\t/^OptNameSpec\t:\tNameSpec { $$= $1; }$/;\"\tl\tlanguage:YACC\ttyperef:typename:str\nNameSpec\tinput.y\t/^NameSpec\t:\tIdent\t{ $$= $1; }$/;\"\tl\tlanguage:YACC\ttyperef:typename:str\nIdent\tinput.y\t/^Ident\t\t:\tIDENT\t{ $$= scanStr; scanStr= NULL; }$/;\"\tl\tlanguage:YACC\ttyperef:typename:str\nOptString\tinput.y\t/^OptString\t:\tString\t{ $$= $1; }$/;\"\tl\tlanguage:YACC\ttyperef:typename:str\nString\tinput.y\t/^String\t\t:\tSTRING\t{ $$= scanStr; scanStr= NULL; }$/;\"\tl\tlanguage:YACC\ttyperef:typename:str\nYYDEBUG\tinput.y\t/^#define\tYYDEBUG /;\"\td\tlanguage:C\tfile:\textras:fileScope,guest\nDEBUG_VAR\tinput.y\t/^#define\tDEBUG_VAR /;\"\td\tlanguage:C\tfile:\textras:fileScope,guest\n__anon5f5ae8c8010a\tinput.y\t/union\t{$/;\"\tu\tlanguage:C\tfile:\textras:fileScope,guest,anonymous\nstr\tinput.y\t/^\tchar *\t\tstr;$/;\"\tm\tlanguage:C\tunion:__anon5f5ae8c8010a\ttyperef:typename:char *\tfile:\textras:fileScope,guest\nival\tinput.y\t/^\tint\t\tival;$/;\"\tm\tlanguage:C\tunion:__anon5f5ae8c8010a\ttyperef:typename:int\tfile:\textras:fileScope,guest\nentry\tinput.y\t/^\tCfgEntryPtr\tentry;$/;\"\tm\tlanguage:C\tunion:__anon5f5ae8c8010a\ttyperef:typename:CfgEntryPtr\tfile:\textras:fileScope,guest\nact\tinput.y\t/^\tActDefPtr\tact;$/;\"\tm\tlanguage:C\tunion:__anon5f5ae8c8010a\ttyperef:typename:ActDefPtr\tfile:\textras:fileScope,guest\nyyerror\tinput.y\t/^yyerror(char *s)$/;\"\tf\tlanguage:C\ttyperef:typename:int\textras:guest\nyywrap\tinput.y\t/^yywrap(void)$/;\"\tf\tlanguage:C\ttyperef:typename:int\textras:guest\nCFGParseFile\tinput.y\t/^CFGParseFile(FILE *file)$/;\"\tf\tlanguage:C\ttyperef:typename:int\textras:guest\ninput.y\tinput.y\t1;\"\tF\tlanguage:YACC\textras:inputFile\n"
  },
  {
    "path": "Units/parser-yacc.r/nested.d/input.y",
    "content": "/* Taken from xorg-x11-xkb-utils-7.7/xkbevd-1.1.3/cfgparse.y */\n/************************************************************\n Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.\n\n Permission to use, copy, modify, and distribute this\n software and its documentation for any purpose and without\n fee is hereby granted, provided that the above copyright\n notice appear in all copies and that both that copyright\n notice and this permission notice appear in supporting\n documentation, and that the name of Silicon Graphics not be\n used in advertising or publicity pertaining to distribution\n of the software without specific prior written permission.\n Silicon Graphics makes no representation about the suitability\n of this software for any purpose. It is provided \"as is\"\n without any express or implied warranty.\n\n SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS\n SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON\n GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL\n DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,\n DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE\n OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH\n THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\n ********************************************************/\n\n%token\n\tEND_OF_FILE\t0\n\tERROR\t\t255\n\tBELL\t\t1\n\tACCESSX\t\t2\n\tMESSAGE\t\t3\n\n\tNONE\t\t20\n\tIGNORE\t\t21\n\tECHO\t\t22\n\tPRINT_EV\t23\n\tSHELL\t\t24\n\tSOUND\t\t25\n\n\tEQUALS\t\t40\n\tPLUS\t\t41\n\tMINUS\t\t42\n\tDIVIDE\t\t43\n\tTIMES\t\t44\n\tOBRACE\t\t45\n\tCBRACE\t\t46\n\tOPAREN\t\t47\n\tCPAREN\t\t48\n\tOBRACKET\t49\n\tCBRACKET\t50\n\tDOT\t\t51\n\tCOMMA\t\t52\n\tSEMI\t\t53\n\tEXCLAM\t\t54\n\tINVERT\t\t55\n\tSTRING\t\t60\n\tINTEGER\t\t61\n\tFLOAT\t\t62\n\tIDENT\t\t63\n\tKEYNAME\t\t64\n%{\n#ifdef DEBUG\n#define\tYYDEBUG 1\n#endif\n#define\tDEBUG_VAR parseDebug\n#include \"xkbevd.h\"\n#include <stdlib.h>\n%}\n%right\tEQUALS\n%left\tPLUS MINUS\n%left\tTIMES DIVIDE\n%left\tEXCLAM INVERT\n%left\tOPAREN\n%start\tCfgFile\n%union\t{\n\tchar *\t\tstr;\n\tint\t\tival;\n\tCfgEntryPtr\tentry;\n\tActDefPtr\tact;\n}\n%type <str>\tIdent String OptString NameSpec OptNameSpec\n%type <ival>\tActionType EventType\n%type <act>\tActionDef\n%type <entry>\tCfgFile CfgEntryList CfgEntry EventDef VarDef\n%%\nCfgFile\t\t\n\t\t:\tCfgEntryList\n\t\t\t{ InterpretConfigs($1); }\n\t\t;\n\nCfgEntryList\t:\tCfgEntryList CfgEntry\n\t\t\t{\n\t\t\t    CfgEntryPtr tmp;\n\t\t\t    if ($1!=NULL) {\n\t\t\t\tfor (tmp=$1;tmp->next!=NULL;tmp=tmp->next) {\n\t\t\t\t    /* conditional does the work */\n\t\t\t\t}\n\t\t\t\ttmp->next= $2;\n\t\t\t\t$$= $1;\n\t\t\t    }\n\t\t\t    else $$= $2;\n\t\t\t}\n\t\t|\tCfgEntry { $$= $1; }\n\t\t;\n\nCfgEntry\t:\tEventDef ActionDef\n\t\t\t{\n\t\t\t    if (($1)&&($2))\n\t\t\t\t$1->action= *($2);\n\t\t\t    if ($2)\n\t\t\t\tfree($2);\n\t\t\t    $$= $1;\n\t\t\t}\n\t\t|\tVarDef \t\t{ $$= $1; }\n\t\t;\n\nVarDef\t\t:\tIdent EQUALS NameSpec\n\t\t\t{\n\t\t\t    CfgEntryPtr cfg;\n\t\t\t    cfg= calloc(1,sizeof(CfgEntryRec));\n\t\t\t    if (cfg) {\n\t\t\t\tcfg->entry_type= VariableDef;\n\t\t\t\tcfg->event_type= 0;\n\t\t\t\tcfg->name.str= $1;\n\t\t\t\tcfg->action.type= UnknownAction;\n\t\t\t\tcfg->action.text= $3;\n\t\t\t\tcfg->action.priv= 0;\n\t\t\t\tcfg->next= NULL;\n\t\t\t    }\n\t\t\t    $$= cfg;\n\t\t\t}\n\t\t;\n\nEventDef\t:\tEventType OPAREN OptNameSpec CPAREN\n\t\t\t{\n\t\t\t    CfgEntryPtr cfg;\n\t\t\t    cfg= calloc(1,sizeof(CfgEntryRec));\n\t\t\t    if (cfg) {\n\t\t\t\tcfg->entry_type= EventDef;\n\t\t\t\tcfg->event_type= $1;\n\t\t\t\tcfg->name.str= $3;\n\t\t\t\tcfg->action.type= UnknownAction;\n\t\t\t\tcfg->action.text= NULL;\n\t\t\t\tcfg->action.priv= 0;\n\t\t\t\tcfg->next= NULL;\n\t\t\t    }\n\t\t\t    $$= cfg;\n\t\t\t}\n\t\t;\n\nEventType\t:\tBELL\t\t{ $$= XkbBellNotify; }\n\t\t|\tACCESSX\t\t{ $$= XkbAccessXNotify; }\n\t\t|\tMESSAGE\t\t{ $$= XkbActionMessage; }\n\t\t;\n\nActionDef\t:\tActionType OptString\n\t\t\t{\n\t\t\t    ActDefPtr act;\n\t\t\t    act= calloc(1,sizeof(ActDefRec));\n\t\t\t    if (act) {\n\t\t\t\tact->type= $1;\n\t\t\t\tact->text= $2;\n\t\t\t    }\n\t\t\t    $$= act;\n\t\t\t}\n\t\t;\n\nActionType\t:\tNONE\t { $$ = NoAction; }\n\t\t|\tIGNORE\t { $$ = NoAction; }\n\t\t|\tECHO\t { $$ = EchoAction; }\n\t\t|\tPRINT_EV { $$ = PrintEvAction; }\n\t\t|\tSHELL\t { $$ = ShellAction; }\n\t\t|\tSOUND\t { $$ = SoundAction; }\n\t\t|\t\t { $$ = UnknownAction; }\n\t\t;\n\nOptNameSpec\t:\tNameSpec { $$= $1; }\n\t\t|\t\t { $$= NULL; }\n\t\t;\n\nNameSpec\t:\tIdent\t{ $$= $1; }\n\t\t|\tString\t{ $$= $1; }\n\t\t;\n\nIdent\t\t:\tIDENT\t{ $$= scanStr; scanStr= NULL; }\n\t\t;\n\nOptString\t:\tString\t{ $$= $1; }\n\t\t|\t\t{ $$= NULL; }\n\t\t;\n\nString\t\t:\tSTRING\t{ $$= scanStr; scanStr= NULL; }\n\t\t;\n%%\nint\nyyerror(char *s)\n{\n    (void)fprintf(stderr,\"%s: line %d of %s\\n\",s,lineNum,\n\t\t\t\t\t(scanFile?scanFile:\"(unknown)\"));\n    if (scanStr)\n\t(void)fprintf(stderr,\"last scanned symbol is: %s\\n\",scanStr);\n    return 1;\n}\n\n\nint\nyywrap(void)\n{\n   return 1;\n}\n\nint\nCFGParseFile(FILE *file)\n{\n    if (file) {\n\tyyin= file;\n\tif (yyparse()==0) {\n\t    return 1;\n\t}\n\treturn 0;\n    }\n    return 1;\n}\n"
  },
  {
    "path": "Units/parser-yacc.r/not-union.d/README",
    "content": "The input is taken from iproute2-3.10.0/misc/ssfilter.y.\niproute2 is distributed under the terms of GPLv2.\n"
  },
  {
    "path": "Units/parser-yacc.r/not-union.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--kinds-C=+px\n--fields=+l\n"
  },
  {
    "path": "Units/parser-yacc.r/not-union.d/expected.tags",
    "content": "HOSTCOND\tinput.y\t/^%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND$/;\"\tt\tlanguage:YACC\nDCOND\tinput.y\t/^%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND$/;\"\tt\tlanguage:YACC\nSCOND\tinput.y\t/^%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND$/;\"\tt\tlanguage:YACC\nDPORT\tinput.y\t/^%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND$/;\"\tt\tlanguage:YACC\nSPORT\tinput.y\t/^%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND$/;\"\tt\tlanguage:YACC\nLEQ\tinput.y\t/^%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND$/;\"\tt\tlanguage:YACC\nGEQ\tinput.y\t/^%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND$/;\"\tt\tlanguage:YACC\nNEQ\tinput.y\t/^%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND$/;\"\tt\tlanguage:YACC\nAUTOBOUND\tinput.y\t/^%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND$/;\"\tt\tlanguage:YACC\napplet\tinput.y\t/^applet: null expr$/;\"\tl\tlanguage:YACC\nnull\tinput.y\t/^null:   \\/* NOTHING *\\/ { $$ = NULL; }$/;\"\tl\tlanguage:YACC\nexpr\tinput.y\t/^expr:\tDCOND HOSTCOND$/;\"\tl\tlanguage:YACC\nssfilter_t\tinput.y\t/^typedef struct ssfilter * ssfilter_t;$/;\"\tt\tlanguage:C\ttyperef:struct:ssfilter *\tfile:\nYYSTYPE\tinput.y\t/^#define YYSTYPE /;\"\td\tlanguage:C\tfile:\nalloc_node\tinput.y\t/^static struct ssfilter * alloc_node(int type, void *pred)$/;\"\tf\tlanguage:C\ttyperef:struct:ssfilter *\tfile:\nyy_argv\tinput.y\t/^static char\t\t**yy_argv;$/;\"\tv\tlanguage:C\ttyperef:typename:char **\tfile:\nyy_argc\tinput.y\t/^static int\t\tyy_argc;$/;\"\tv\tlanguage:C\ttyperef:typename:int\tfile:\nyy_fp\tinput.y\t/^static FILE\t\t*yy_fp;$/;\"\tv\tlanguage:C\ttyperef:typename:FILE *\tfile:\nyy_ret\tinput.y\t/^static ssfilter_t\t*yy_ret;$/;\"\tv\tlanguage:C\ttyperef:typename:ssfilter_t *\tfile:\ntok_type\tinput.y\t/^static int tok_type = -1;$/;\"\tv\tlanguage:C\ttyperef:typename:int\tfile:\nyylex\tinput.y\t/^static int yylex(void);$/;\"\tp\tlanguage:C\ttyperef:typename:int\tfile:\nyyerror\tinput.y\t/^static void yyerror(char *s)$/;\"\tf\tlanguage:C\ttyperef:typename:void\tfile:\nget_token_from_line\tinput.y\t/^static char *get_token_from_line(char **ptr)$/;\"\tf\tlanguage:C\ttyperef:typename:char *\tfile:\nyylex\tinput.y\t/^int yylex(void)$/;\"\tf\tlanguage:C\ttyperef:typename:int\nssfilter_parse\tinput.y\t/^int ssfilter_parse(struct ssfilter **f, int argc, char **argv, FILE *fp)$/;\"\tf\tlanguage:C\ttyperef:typename:int\nEND\tinput.y\t/^#define END /;\"\td\tlanguage:C\tfile:\n"
  },
  {
    "path": "Units/parser-yacc.r/not-union.d/input.y",
    "content": "%{\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <malloc.h>\n#include <string.h>\n#include \"ssfilter.h\"\n\ntypedef struct ssfilter * ssfilter_t;\n\n#define YYSTYPE ssfilter_t\n\nstatic struct ssfilter * alloc_node(int type, void *pred)\n{\n\tstruct ssfilter *n = malloc(sizeof(*n));\n\tif (n == NULL)\n\t\tabort();\n\tn->type = type;\n\tn->pred = pred;\n\tn->post = NULL;\n\treturn n;\n}\n\nstatic char\t\t**yy_argv;\nstatic int\t\tyy_argc;\nstatic FILE\t\t*yy_fp;\nstatic ssfilter_t\t*yy_ret;\nstatic int tok_type = -1;\n\nstatic int yylex(void);\n\nstatic void yyerror(char *s)\n{\n\tfprintf(stderr, \"ss: bison bellows (while parsing filter): \\\"%s!\\\"\", s);\n}\n\n%}\n\n%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND\n%left '|'\n%left '&'\n%nonassoc '!'\n\n%%\napplet: null expr\n        {\n                *yy_ret = $2;\n                $$ = $2;\n        }\n        | null\n        ;\nnull:   /* NOTHING */ { $$ = NULL; }\n        ;\nexpr:\tDCOND HOSTCOND\n        {\n\t\t$$ = alloc_node(SSF_DCOND, $2);\n        }\n        | SCOND HOSTCOND\n        {\n\t\t$$ = alloc_node(SSF_SCOND, $2);\n        }\n        | DPORT GEQ HOSTCOND\n        {\n                $$ = alloc_node(SSF_D_GE, $3);\n        }\n        | DPORT LEQ HOSTCOND\n        {\n                $$ = alloc_node(SSF_D_LE, $3);\n        }\n        | DPORT '>' HOSTCOND\n        {\n                $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_LE, $3));\n        }\n        | DPORT '<' HOSTCOND\n        {\n                $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_GE, $3));\n        }\n        | DPORT '=' HOSTCOND\n        {\n\t\t$$ = alloc_node(SSF_DCOND, $3);\n        }\n        | DPORT NEQ HOSTCOND\n        {\n\t\t$$ = alloc_node(SSF_NOT, alloc_node(SSF_DCOND, $3));\n        }\n\n        | SPORT GEQ HOSTCOND\n        {\n                $$ = alloc_node(SSF_S_GE, $3);\n        }\n        | SPORT LEQ HOSTCOND\n        {\n                $$ = alloc_node(SSF_S_LE, $3);\n        }\n        | SPORT '>' HOSTCOND\n        {\n                $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_LE, $3));\n        }\n        | SPORT '<' HOSTCOND\n        {\n                $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_GE, $3));\n        }\n        | SPORT '=' HOSTCOND\n        {\n\t\t$$ = alloc_node(SSF_SCOND, $3);\n        }\n        | SPORT NEQ HOSTCOND\n        {\n\t\t$$ = alloc_node(SSF_NOT, alloc_node(SSF_SCOND, $3));\n        }\n\n        | AUTOBOUND\n        {\n                $$ = alloc_node(SSF_S_AUTO, NULL);\n        }\n        | expr '|' expr\n        {\n                $$ = alloc_node(SSF_OR, $1);\n\t        $$->post = $3;\n        }\n        | expr expr\n        {\n                $$ = alloc_node(SSF_AND, $1);\n\t        $$->post = $2;\n        }\n        | expr '&' expr\n\n        {\n                $$ = alloc_node(SSF_AND, $1);\n\t        $$->post = $3;\n        }\n        | '!' expr\n        {\n                $$ = alloc_node(SSF_NOT, $2);\n        }\n        | '(' expr ')'\n        {\n                $$ = $2;\n        }\n;\n%%\n\nstatic char *get_token_from_line(char **ptr)\n{\n\tchar *tok, *cp = *ptr;\n\n\twhile (*cp == ' ' || *cp == '\\t') cp++;\n\n\tif (*cp == 0) {\n\t\t*ptr = cp;\n\t\treturn NULL;\n\t}\n\n\ttok = cp;\n\n\twhile (*cp != 0 && *cp != ' ' && *cp != '\\t') {\n\t\t/* Backslash escapes everything. */\n\t\tif (*cp == '\\\\') {\n\t\t\tchar *tp;\n\t\t\tfor (tp = cp; tp != tok; tp--)\n\t\t\t\t*tp = *(tp-1);\n\t\t\tcp++;\n\t\t\ttok++;\n\t\t\tif (*cp == 0)\n\t\t\t\tbreak;\n\t\t}\n\t\tcp++;\n\t}\n\tif (*cp)\n\t\t*cp++ = 0;\n\t*ptr = cp;\n\treturn tok;\n}\n\nint yylex(void)\n{\n\tstatic char argbuf[1024];\n\tstatic char *tokptr = argbuf;\n\tstatic int argc;\n\tchar *curtok;\n\n\tdo {\n\t\twhile (*tokptr == 0) {\n\t\t\ttokptr = NULL;\n\t\t\tif (argc < yy_argc) {\n\t\t\t\ttokptr = yy_argv[argc];\n\t\t\t\targc++;\n\t\t\t} else if (yy_fp) {\n\t\t\t\twhile (tokptr == NULL) {\n\t\t\t\t\tif (fgets(argbuf, sizeof(argbuf)-1, yy_fp) == NULL)\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\targbuf[sizeof(argbuf)-1] = 0;\n\t\t\t\t\tif (strlen(argbuf) == sizeof(argbuf) - 1) {\n\t\t\t\t\t\tfprintf(stderr, \"Too long line in filter\");\n\t\t\t\t\t\texit(-1);\n\t\t\t\t\t}\n\t\t\t\t\tif (argbuf[strlen(argbuf)-1] == '\\n')\n\t\t\t\t\t\targbuf[strlen(argbuf)-1] = 0;\n\t\t\t\t\tif (argbuf[0] == '#' || argbuf[0] == '0')\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\ttokptr = argbuf;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t} while ((curtok = get_token_from_line(&tokptr)) == NULL);\n\n\tif (strcmp(curtok, \"!\") == 0 ||\n\t    strcmp(curtok, \"not\") == 0)\n\t\treturn '!';\n\tif (strcmp(curtok, \"&\") == 0 ||\n\t    strcmp(curtok, \"&&\") == 0 ||\n\t    strcmp(curtok, \"and\") == 0)\n\t\treturn '&';\n\tif (strcmp(curtok, \"|\") == 0 ||\n\t    strcmp(curtok, \"||\") == 0 ||\n\t    strcmp(curtok, \"or\") == 0)\n\t\treturn '|';\n\tif (strcmp(curtok, \"(\") == 0)\n\t\treturn '(';\n\tif (strcmp(curtok, \")\") == 0)\n\t\treturn ')';\n\tif (strcmp(curtok, \"dst\") == 0) {\n\t\ttok_type = DCOND;\n\t\treturn DCOND;\n\t}\n\tif (strcmp(curtok, \"src\") == 0) {\n                tok_type = SCOND;\n\t\treturn SCOND;\n        }\n\tif (strcmp(curtok, \"dport\") == 0) {\n\t\ttok_type = DPORT;\n\t\treturn DPORT;\n\t}\n\tif (strcmp(curtok, \"sport\") == 0) {\n\t\ttok_type = SPORT;\n\t\treturn SPORT;\n\t}\n\tif (strcmp(curtok, \">=\") == 0 ||\n\t    strcmp(curtok, \"ge\") == 0 ||\n\t    strcmp(curtok, \"geq\") == 0)\n\t\treturn GEQ;\n\tif (strcmp(curtok, \"<=\") == 0 ||\n\t    strcmp(curtok, \"le\") == 0 ||\n\t    strcmp(curtok, \"leq\") == 0)\n\t\treturn LEQ;\n\tif (strcmp(curtok, \"!=\") == 0 ||\n\t    strcmp(curtok, \"ne\") == 0 ||\n\t    strcmp(curtok, \"neq\") == 0)\n\t\treturn NEQ;\n\tif (strcmp(curtok, \"=\") == 0 ||\n\t    strcmp(curtok, \"==\") == 0 ||\n\t    strcmp(curtok, \"eq\") == 0)\n\t\treturn '=';\n\tif (strcmp(curtok, \">\") == 0 ||\n\t    strcmp(curtok, \"gt\") == 0)\n\t\treturn '>';\n\tif (strcmp(curtok, \"<\") == 0 ||\n\t    strcmp(curtok, \"lt\") == 0)\n\t\treturn '<';\n\tif (strcmp(curtok, \"autobound\") == 0) {\n\t\ttok_type = AUTOBOUND;\n\t\treturn AUTOBOUND;\n\t}\n\tyylval = (void*)parse_hostcond(curtok, tok_type == SPORT || tok_type == DPORT);\n\tif (yylval == NULL) {\n\t\tfprintf(stderr, \"Cannot parse dst/src address.\\n\");\n\t\texit(1);\n\t}\n\treturn HOSTCOND;\n}\n\nint ssfilter_parse(struct ssfilter **f, int argc, char **argv, FILE *fp)\n{\n\tyy_argc = argc;\n\tyy_argv = argv;\n\tyy_fp   = fp;\n\tyy_ret  = f;\n\n\tif (yyparse()) {\n\t\tfprintf(stderr, \" Sorry.\\n\");\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n#define END 1\n\n"
  },
  {
    "path": "Units/parser-yacc.r/token-and-cstr.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/parser-yacc.r/token-and-cstr.d/expected.tags",
    "content": "IDENTIFIER\tinput.y\t/^%token <str> IDENTIFIER \"identifier\"$/;\"\tt\ttyperef:typename:str\nTYPEDEF_NAME\tinput.y\t/^%token <str> TYPEDEF_NAME \"typedef-name\"$/;\"\tt\ttyperef:typename:str\n"
  },
  {
    "path": "Units/parser-yacc.r/token-and-cstr.d/input.y",
    "content": "%{\n%}\n%token <str> IDENTIFIER \"identifier\"\n%token <str> TYPEDEF_NAME \"typedef-name\"\n%%\n%%\n"
  },
  {
    "path": "Units/parser-yaml.r/yaml-anchor.d/args.ctags",
    "content": "--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/parser-yaml.r/yaml-anchor.d/expected.tags",
    "content": "mark\tinput.yml\t/^- &mark foo$/;\"\ta\troles:def\nmark\tinput.yml\t/^- *mark$/;\"\ta\troles:alias\n"
  },
  {
    "path": "Units/parser-yaml.r/yaml-anchor.d/features",
    "content": "yaml\n"
  },
  {
    "path": "Units/parser-yaml.r/yaml-anchor.d/input.yml",
    "content": "- &mark foo\n- *mark\n"
  },
  {
    "path": "Units/parser-zephir.r/zephir-return-hint.d/args.ctags",
    "content": "--fields=afikmsS\n"
  },
  {
    "path": "Units/parser-zephir.r/zephir-return-hint.d/expected.tags",
    "content": "Test\tinput.zep\t/^class Test$/;\"\tc\nfirst\tinput.zep\t/^    public function first(string str) -> string$/;\"\tf\tclass:Test\taccess:public\tsignature:(string str)\nnested\tinput.zep\t/^        function nested() {$/;\"\tf\tfunction:Test::first\tsignature:()\nsecond\tinput.zep\t/^    public function second(int i) -> int$/;\"\tf\tclass:Test\taccess:public\tsignature:(int i)\n"
  },
  {
    "path": "Units/parser-zephir.r/zephir-return-hint.d/input.zep",
    "content": "class Test\n{\n    public function first(string str) -> string\n    {\n        function nested() {\n            \n        }\n    }\n    \n    public function second(int i) -> int\n    {\n        \n    }\n}\n"
  },
  {
    "path": "Units/parser-zephir.r/zephir-simple.d/args.ctags",
    "content": "--fields=afikmsS\n"
  },
  {
    "path": "Units/parser-zephir.r/zephir-simple.d/expected.tags",
    "content": "MyClass\tinput.zep\t/^class MyClass$/;\"\tc\tnamespace:Test\nTest\tinput.zep\t/^namespace Test;$/;\"\tn\nsomeMethod1\tinput.zep\t/^    public function someMethod1()$/;\"\tf\tclass:Test\\\\MyClass\taccess:public\tsignature:()\nsomeMethod2\tinput.zep\t/^    public function someMethod2()$/;\"\tf\tclass:Test\\\\MyClass\taccess:public\tsignature:()\n"
  },
  {
    "path": "Units/parser-zephir.r/zephir-simple.d/input.zep",
    "content": "/* from http://zephir-lang.com/language.html */\nnamespace Test;\n\nclass MyClass\n{\n\n    public function someMethod1()\n    {\n        int a = 1, b = 2;\n        return a + b;\n    }\n\n    public function someMethod2()\n    {\n        int a = 3, b = 4;\n        return a + b;\n    }\n\n}\n"
  },
  {
    "path": "Units/parser-zsh.r/autoload.d/args.ctags",
    "content": "--sort=no\n--fields=+rK\n--extras=+r\n"
  },
  {
    "path": "Units/parser-zsh.r/autoload.d/expected.tags",
    "content": "func\tinput.zsh\t/^autoload func$/;\"\tscript\troles:autoloaded\nfunc\tinput.zsh\t/^autoload func$/;\"\tfunction\troles:autoloaded\nkfun\tinput.zsh\t/^autoload -z kfun$/;\"\tscript\troles:autoloaded\nkfun\tinput.zsh\t/^autoload -z kfun$/;\"\tfunction\troles:autoloaded\nzfun\tinput.zsh\t/^autoload -k zfun$/;\"\tscript\troles:autoloaded\nzfun\tinput.zsh\t/^autoload -k zfun$/;\"\tfunction\troles:autoloaded\nf0\tinput.zsh\t/^autoload f0 f1 f2$/;\"\tscript\troles:autoloaded\nf0\tinput.zsh\t/^autoload f0 f1 f2$/;\"\tfunction\troles:autoloaded\nf1\tinput.zsh\t/^autoload f0 f1 f2$/;\"\tscript\troles:autoloaded\nf1\tinput.zsh\t/^autoload f0 f1 f2$/;\"\tfunction\troles:autoloaded\nf2\tinput.zsh\t/^autoload f0 f1 f2$/;\"\tscript\troles:autoloaded\nf2\tinput.zsh\t/^autoload f0 f1 f2$/;\"\tfunction\troles:autoloaded\n/path0/A/pf0\tinput.zsh\t/^autoload \\/path0\\/A\\/pf0 \\/path1\\/B\\/pf1$/;\"\tscript\troles:autoloaded\npf0\tinput.zsh\t/^autoload \\/path0\\/A\\/pf0 \\/path1\\/B\\/pf1$/;\"\tfunction\troles:autoloaded\n/path1/B/pf1\tinput.zsh\t/^autoload \\/path0\\/A\\/pf0 \\/path1\\/B\\/pf1$/;\"\tscript\troles:autoloaded\npf1\tinput.zsh\t/^autoload \\/path0\\/A\\/pf0 \\/path1\\/B\\/pf1$/;\"\tfunction\troles:autoloaded\n/path3/pf3\tinput.zsh\t/^autoload \\/path3\\/pf3 f3$/;\"\tscript\troles:autoloaded\npf3\tinput.zsh\t/^autoload \\/path3\\/pf3 f3$/;\"\tfunction\troles:autoloaded\nf3\tinput.zsh\t/^autoload \\/path3\\/pf3 f3$/;\"\tscript\troles:autoloaded\nf3\tinput.zsh\t/^autoload \\/path3\\/pf3 f3$/;\"\tfunction\troles:autoloaded\nfoo\tinput.zsh\t/^foo()$/;\"\tfunction\troles:def\ng0\tinput.zsh\t/^autoload +x g0 g1$/;\"\tscript\troles:autoloaded\ng0\tinput.zsh\t/^autoload +x g0 g1$/;\"\tfunction\troles:autoloaded\ng1\tinput.zsh\t/^autoload +x g0 g1$/;\"\tscript\troles:autoloaded\ng1\tinput.zsh\t/^autoload +x g0 g1$/;\"\tfunction\troles:autoloaded\n"
  },
  {
    "path": "Units/parser-zsh.r/autoload.d/input.zsh",
    "content": "autoload func\nautoload -z kfun\nautoload -k zfun\nautoload f0 f1 f2\nautoload /path0/A/pf0 /path1/B/pf1\nautoload /path3/pf3 f3\n\nfoo()\n{\n    autoload -X\n}\n\nautoload +x g0 g1\n"
  },
  {
    "path": "Units/pcre2-single-line.d/args.ctags",
    "content": "--langdef=Foo\n--map-Foo=.foo\n--kinddef-Foo=d,def,definitions\n--kinddef-Foo=v,var,variables\n--kinddef-Foo=f,func,functions\n--kinddef-Foo=m,macro,macros\n--kinddef-Foo=p,pkg,packages\n\n\n--regex-Foo=/def\\s+(\\W)(\\w+)\\1/\\2/d/p\n--regex-Foo=/var\\s+(\\W)(\\w+)\\1/\\2/v/{pcre2}\n--regex-Foo=/func\\s+[\"']?(.+?)['\"]?$/\\1/f/pi\n--regex-Foo=/macro\\s+[\"']?(.+?)['\"]?$/\\1/m/{pcre2}{icase}\n--regex-Foo=/package\\s+[\"']?(.+?)['\"]?$/\\1/p/i{pcre2}\n"
  },
  {
    "path": "Units/pcre2-single-line.d/expected.tags",
    "content": "P0\tinput.foo\t/^package P0$/;\"\tp\nabc\tinput.foo\t/^var \"abc\"$/;\"\tv\ncapture_me_in_bar\tinput.foo\t/^def |capture_me_in_bar|$/;\"\td\ncapture_me_in_slash\tinput.foo\t/^def \\/capture_me_in_slash\\/$/;\"\td\nf0\tinput.foo\t/^func 'f0'$/;\"\tf\nf1\tinput.foo\t/^func \"f1\"$/;\"\tf\nf2\tinput.foo\t/^func f2$/;\"\tf\nf3\tinput.foo\t/^FunC f3$/;\"\tf\nm0\tinput.foo\t/^macro m0$/;\"\tm\n"
  },
  {
    "path": "Units/pcre2-single-line.d/features",
    "content": "pcre2\n"
  },
  {
    "path": "Units/pcre2-single-line.d/input.foo",
    "content": "def |capture_me_in_bar|\ndef {dont_capture_me}\ndef /capture_me_in_slash/\nvar \"abc\"\nfunc 'f0'\nfunc \"f1\"\nfunc f2\nFunC f3\nmacro m0\npackage P0\n"
  },
  {
    "path": "Units/readtags.r/backslash-at-the-end-of-pattern.d/expected.tags",
    "content": "M\tinput.c\t/^#define M\\\\/;\"\td\tfile:\nmain\tinput.c\t/^int main() {$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "Units/readtags.r/backslash-at-the-end-of-pattern.d/input.c",
    "content": "/* TAKEN FROM https://raw.githubusercontent.com/notepad-plus-plus/notepad-plus-plus/master/scintilla/test/examples/x.cxx */\n/* https://github.com/notepad-plus-plus/notepad-plus-plus/blob/master/LICENSE */\n// A demonstration program\n#include <stdio.h>\n#if 0 /* */\n#define DUMMY() \\\n\tif (1);\n#endif\n\n#define M\\\n\n\\\n \nint main() {\n\tdouble x[] = {3.14159,6.02e23,1.6e-19,1.0+1};\n\tint y[] = {75,0113,0x4b};\n\tprintf(\"hello world %d %g\\n\", y[0], x[0]);\n}\n"
  },
  {
    "path": "Units/readtags.r/backslash-at-the-end-of-pattern.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/regex-flag-anonymous.d/args.ctags",
    "content": "--sort=no\n\n--langdef=foo\n--map-foo=.foo\n--kinddef-foo=m,module,modules\n--kinddef-foo=x,exception,exceptions\n\n--regex-foo=/^defmodule *([a-zA-Z0-9]+) *do/\\1/m/{scope=push}\n--regex-foo=/^end//{scope=pop}{placeholder}\n--regex-foo=/ +defexception( +.*)$//x/{_anonymous=exception}{scope=ref}\n"
  },
  {
    "path": "Units/regex-flag-anonymous.d/expected.tags",
    "content": "MyAppError1\tinput.foo\t/^defmodule MyAppError1 do$/;\"\tm\nexceptionf9e1959f0101\tinput.foo\t/^  defexception [:message]$/;\"\tx\tmodule:MyAppError1\nMyAppError2\tinput.foo\t/^defmodule MyAppError2 do$/;\"\tm\nexceptionf9e1959f0201\tinput.foo\t/^  defexception [:message]$/;\"\tx\tmodule:MyAppError2\n"
  },
  {
    "path": "Units/regex-flag-anonymous.d/input.foo",
    "content": "#\n# Taken from commit log subitted by @dreamtigers in #2024.\n#\ndefmodule MyAppError1 do\n  defexception [:message]\n  # code\nend\n\ndefmodule MyAppError2 do\n  defexception [:message]\n  # code\nend\n"
  },
  {
    "path": "Units/regex-flag-long.d/args.ctags",
    "content": "--langdef=dummy\n--langmap=dummy:.dummy\n--regex-dummy=/^define:(.*)$/\\1/d,definition/{icase}\n"
  },
  {
    "path": "Units/regex-flag-long.d/expected.tags",
    "content": "a\tinput.dummy\t/^define:a$/;\"\td\nb\tinput.dummy\t/^Define:b$/;\"\td\nc\tinput.dummy\t/^DEFINE:c$/;\"\td\nd\tinput.dummy\t/^definE:d$/;\"\td\n"
  },
  {
    "path": "Units/regex-flag-long.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/regex-flag-long.d/input.dummy",
    "content": "define:a\nDefine:b\nDEFINE:c\ndefinE:d\n\ndecl:f\nDecl:g\nDECL:h\ndecL:i\n\n\n"
  },
  {
    "path": "Units/regex-flag-postrun.d/args.ctags",
    "content": "--sort=no\n--fields=+ln\n\n--langdef=TESTC{base=C}\n--kinddef-TESTC=d,def,definitions\n--regex-TESTC=/.*def:([0-za-zA-Z]+).*/inline-\\1/d/\n--regex-TESTC=/.*def:([0-za-zA-Z]+).*/post-\\1/d/{postrun}\n"
  },
  {
    "path": "Units/regex-flag-postrun.d/expected.tags",
    "content": "inline-x\tinput.c\t/^\\/* def:x *\\/$/;\"\td\tline:1\tlanguage:TESTC\nf\tinput.c\t/^int f(void)$/;\"\tf\tline:2\tlanguage:C\ttyperef:typename:int\npost-x\tinput.c\t/^\\/* def:x *\\/$/;\"\td\tline:1\tlanguage:TESTC\n"
  },
  {
    "path": "Units/regex-flag-postrun.d/input.c",
    "content": "/* def:x */\nint f(void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Units/regex-flag-scope.r/intervaltab-case-label.d/args.ctags",
    "content": "--sort=no\n--kinddef-C=H,caseHandler,case handler\n--regex-C=/^[ \\t]*case[ \\t]*+([a-zA-Z0-9_]+):.*/\\1/H/{scope=intervaltab}{postrun}\n"
  },
  {
    "path": "Units/regex-flag-scope.r/intervaltab-case-label.d/expected.tags",
    "content": "empty0\tinput.c\t/^empty0(void)$/;\"\tf\ttyperef:typename:void\nfoo\tinput.c\t/^foo(void)$/;\"\tf\ttyperef:typename:int\nempty1\tinput.c\t/^empty1(void)$/;\"\tf\ttyperef:typename:void\nbar\tinput.c\t/^bar(void)$/;\"\tf\ttyperef:typename:int\nempty2\tinput.c\t/^empty2(void)$/;\"\tf\ttyperef:typename:void\nA\tinput.c\t/^\tcase A:$/;\"\tH\tfunction:foo\nB\tinput.c\t/^\tcase B:$/;\"\tH\tfunction:foo\nC\tinput.c\t/^\tcase C:$/;\"\tH\tfunction:bar\nD\tinput.c\t/^\tcase D:$/;\"\tH\tfunction:bar\n"
  },
  {
    "path": "Units/regex-flag-scope.r/intervaltab-case-label.d/input.c",
    "content": "void\nempty0(void)\n{\n\t/* NO switch/case here */\n}\n\nint\nfoo(void)\n{\n\tswitch (x)\n\t{\n\tcase A:\n\t\tbreak;\n\tcase B:\n\t\tbreak;\n\t}\n\treturn 0;\n}\n\nvoid\nempty1(void)\n{\n\t/* NO switch/case here */\n}\n\nint\nbar(void)\n{\n\tswitch (x)\n\t{\n\tcase C:\n\t\tbreak;\n\tcase D:\n\t\tbreak;\n\t}\n\treturn 0;\n}\n\nvoid\nempty2(void)\n{\n\t/* NO switch/case here */\n}\n"
  },
  {
    "path": "Units/regex-flag-scope.r/intervaltab-linux-cb.d/args.ctags",
    "content": "--sort=no\n\n--_roledef-C.f=callback,function used as callback function\n--_fielddef-C=method,method name used for calling the callback function\n\n--regex-C=/^[ \\t]*\\.([a-zA-Z_][a-zA-Z_0-9]*)[ \\t]*=[ \\t]*([a-zA-Z_][a-zA-Z_0-9]*)[ \\t]*,?/\\2/{scope=intervaltab}{postrun}{_field=method:\\1}\n\n--extras=+{reference}\n--fields=+{roles}{line}{end}\n--fields-C=+{method}\n"
  },
  {
    "path": "Units/regex-flag-scope.r/intervaltab-linux-cb.d/expected.tags",
    "content": "proc_pid_cmdline_ops\tinput.c\t/^static const struct file_operations proc_pid_cmdline_ops = {$/;\"\tv\tline:3\ttyperef:typename:const struct file_operations\tfile:\troles:def\tend:6\nproc_lstats_operations\tinput.c\t/^static const struct file_operations proc_lstats_operations = {$/;\"\tv\tline:8\ttyperef:typename:const struct file_operations\tfile:\troles:def\tend:14\nproc_single_file_operations\tinput.c\t/^static const struct file_operations proc_single_file_operations = {$/;\"\tv\tline:16\ttyperef:typename:const struct file_operations\tfile:\troles:def\tend:21\nproc_pid_cmdline_read\tinput.c\t/^\t.read\t= proc_pid_cmdline_read,$/;\"\tr\tline:4\tvariable:proc_pid_cmdline_ops\troles:def\tmethod:read\ngeneric_file_llseek\tinput.c\t/^\t.llseek\t= generic_file_llseek,$/;\"\tr\tline:5\tvariable:proc_pid_cmdline_ops\troles:def\tmethod:llseek\nlstats_open\tinput.c\t/^\t.open\t\t= lstats_open,$/;\"\tr\tline:9\tvariable:proc_lstats_operations\troles:def\tmethod:open\nseq_read\tinput.c\t/^\t.read\t\t= seq_read,$/;\"\tr\tline:10\tvariable:proc_lstats_operations\troles:def\tmethod:read\nlstats_write\tinput.c\t/^\t.write\t\t= lstats_write,$/;\"\tr\tline:11\tvariable:proc_lstats_operations\troles:def\tmethod:write\nseq_lseek\tinput.c\t/^\t.llseek\t\t= seq_lseek,$/;\"\tr\tline:12\tvariable:proc_lstats_operations\troles:def\tmethod:llseek\nsingle_release\tinput.c\t/^\t.release\t= single_release,$/;\"\tr\tline:13\tvariable:proc_lstats_operations\troles:def\tmethod:release\nproc_single_open\tinput.c\t/^\t.open\t\t= proc_single_open,$/;\"\tr\tline:17\tvariable:proc_single_file_operations\troles:def\tmethod:open\nseq_read\tinput.c\t/^\t.read\t\t= seq_read,$/;\"\tr\tline:18\tvariable:proc_single_file_operations\troles:def\tmethod:read\nseq_lseek\tinput.c\t/^\t.llseek\t\t= seq_lseek,$/;\"\tr\tline:19\tvariable:proc_single_file_operations\troles:def\tmethod:llseek\nsingle_release\tinput.c\t/^\t.release\t= single_release,$/;\"\tr\tline:20\tvariable:proc_single_file_operations\troles:def\tmethod:release\n"
  },
  {
    "path": "Units/regex-flag-scope.r/intervaltab-linux-cb.d/input.c",
    "content": "/* Taken from Linux (fs/proc/base.c) */\n\nstatic const struct file_operations proc_pid_cmdline_ops = {\n\t.read\t= proc_pid_cmdline_read,\n\t.llseek\t= generic_file_llseek,\n};\n\nstatic const struct file_operations proc_lstats_operations = {\n\t.open\t\t= lstats_open,\n\t.read\t\t= seq_read,\n\t.write\t\t= lstats_write,\n\t.llseek\t\t= seq_lseek,\n\t.release\t= single_release,\n};\n\nstatic const struct file_operations proc_single_file_operations = {\n\t.open\t\t= proc_single_open,\n\t.read\t\t= seq_read,\n\t.llseek\t\t= seq_lseek,\n\t.release\t= single_release,\n};\n"
  },
  {
    "path": "Units/regex-flag-scope.r/intervaltab-update-line.d/args.ctags",
    "content": "--sort=no\n--extras=+g\n--fields=+ln{scope}e\n\n--langdef=FOOX\n--map-FOOX=.foox\n\n--kinddef-FOOX=d,def,definitions\n--regex-FOOX=/define +([A-Z]):/\\1/d/{{\n\t.\n}}\n--regex-FOOX=/^(end0)$//{{\n\tdup @1 end:\n}}\n\n--regex-FOOX=/^(end)$//{{\n    dup dup :end {\n        line: dup\n        @1 end:\n    } if\n}}\n\n--langdef=MARK{base=FOOX}\n--kinddef-MARK=m,marker,markers\n--regex-MARK=/^# +MARK:([A-Z])/\\1/m/{scope=intervaltab}{postrun}\n"
  },
  {
    "path": "Units/regex-flag-scope.r/intervaltab-update-line.d/expected.tags",
    "content": "X\tinput.foox\t/^end0$/;\"\td\tline:3\tlanguage:FOOX\tend:5\nY\tinput.foox\t/^# MARK:Y$/;\"\tm\tline:2\tlanguage:MARK\nZ\tinput.foox\t/^# MARK:Z$/;\"\tm\tline:4\tlanguage:MARK\tscope:def:X\nA\tinput.foox\t/^# MARK:A$/;\"\tm\tline:6\tlanguage:MARK\n"
  },
  {
    "path": "Units/regex-flag-scope.r/intervaltab-update-line.d/input.foox",
    "content": "define X:\n# MARK:Y\nend0\n# MARK:Z\nend\n# MARK:A\n"
  },
  {
    "path": "Units/regex-flag-scope.r/regex-with-scope-autoFQTag.d/args.ctags",
    "content": "# To check the output easier\n--sort=no\n--fields=+e\n--extras=+q\n\n--langdef=foo{_autoFQTag}\n    --map-foo=+.foo\n    --regex-foo=/^#.*//{exclusive}\n    --regex-foo=/^[[:blank:]]*define[[:blank:]]+([[:alnum:]_]+)[[:blank:]]*\\{/\\1/d,definition/{scope=push}\n    --regex-foo=/^[[:blank:]]*\\{/_/d,definition/{scope=push}{placeholder}\n    --regex-foo=/^[[:blank:]]*package[[:blank:]]+([[:alnum:]_]+)/\\1/p,package/{scope=push}\n    --regex-foo=/^[[:blank:]]*end[[:blank:]]*$//{scope=pop}{exclusive}\n    --regex-foo=/^[[:blank:]]*\\}[[:blank:]]*$//{scope=pop}{exclusive}\n    --regex-foo=/^[[:blank:]]*ns[[:blank:]]+([[:alnum:]_]+)/\\1/n,namespace/{scope=set}\n    --regex-foo=/^[[:blank:]]*var[[:blank:]]+([[:alnum:]_]+)/\\1/v,var/{scope=ref}\n    --regex-foo=/^[[:blank:]]*global//{scope=clear}{exclusive}\n"
  },
  {
    "path": "Units/regex-flag-scope.r/regex-with-scope-autoFQTag.d/expected.tags",
    "content": "NS1\tinput.foo\t/^ns NS1$/;\"\tn\tend:15\nx\tinput.foo\t/^define x {$/;\"\td\tnamespace:NS1\tend:14\nNS1.x\tinput.foo\t/^define x {$/;\"\td\tnamespace:NS1\tend:14\ny\tinput.foo\t/^\tdefine y {$/;\"\td\tdefinition:NS1.x\tend:7\nNS1.x.y\tinput.foo\t/^\tdefine y {$/;\"\td\tdefinition:NS1.x\tend:7\nv_y_0\tinput.foo\t/^\t       var v_y_0$/;\"\tv\tdefinition:NS1.x.y\nNS1.x.y.v_y_0\tinput.foo\t/^\t       var v_y_0$/;\"\tv\tdefinition:NS1.x.y\nv_y_1\tinput.foo\t/^\t       var v_y_1$/;\"\tv\tdefinition:NS1.x.y\nNS1.x.y.v_y_1\tinput.foo\t/^\t       var v_y_1$/;\"\tv\tdefinition:NS1.x.y\nz\tinput.foo\t/^\tdefine z {$/;\"\td\tdefinition:NS1.x\tend:13\nNS1.x.z\tinput.foo\t/^\tdefine z {$/;\"\td\tdefinition:NS1.x\tend:13\nv_z_0\tinput.foo\t/^\t       var v_z_0$/;\"\tv\tdefinition:NS1.x.z\nNS1.x.z.v_z_0\tinput.foo\t/^\t       var v_z_0$/;\"\tv\tdefinition:NS1.x.z\nv_z_1\tinput.foo\t/^\t       var v_z_1$/;\"\tv\tdefinition:NS1.x.z\nNS1.x.z.v_z_1\tinput.foo\t/^\t       var v_z_1$/;\"\tv\tdefinition:NS1.x.z\na\tinput.foo\t/^\t       define a {$/;\"\td\tdefinition:NS1.x.z\tend:12\nNS1.x.z.a\tinput.foo\t/^\t       define a {$/;\"\td\tdefinition:NS1.x.z\tend:12\nNS2\tinput.foo\t/^ns NS2$/;\"\tn\tend:24\np\tinput.foo\t/^define p {$/;\"\td\tnamespace:NS2\tend:22\nNS2.p\tinput.foo\t/^define p {$/;\"\td\tnamespace:NS2\tend:22\nq\tinput.foo\t/^   define q {$/;\"\td\tdefinition:NS2.p\tend:21\nNS2.p.q\tinput.foo\t/^   define q {$/;\"\td\tdefinition:NS2.p\tend:21\nv_g1\tinput.foo\t/^var v_g1$/;\"\tv\nd_g\tinput.foo\t/^define d_g {$/;\"\td\tend:28\nv_l\tinput.foo\t/^       var v_l$/;\"\tv\tdefinition:d_g\nd_g.v_l\tinput.foo\t/^       var v_l$/;\"\tv\tdefinition:d_g\nNS3\tinput.foo\t/^ns NS3$/;\"\tn\tend:47\nPACKAGE\tinput.foo\t/^package PACKAGE$/;\"\tp\tnamespace:NS3\tend:44\nNS3.PACKAGE\tinput.foo\t/^package PACKAGE$/;\"\tp\tnamespace:NS3\tend:44\np\tinput.foo\t/^define p {$/;\"\td\tpackage:NS3.PACKAGE\tend:41\nNS3.PACKAGE.p\tinput.foo\t/^define p {$/;\"\td\tpackage:NS3.PACKAGE\tend:41\nq\tinput.foo\t/^   define q {$/;\"\td\tdefinition:NS3.PACKAGE.p\tend:38\nNS3.PACKAGE.p.q\tinput.foo\t/^   define q {$/;\"\td\tdefinition:NS3.PACKAGE.p\tend:38\nL\tinput.foo\t/^\t\tvar L$/;\"\tv\tdefinition:NS3.PACKAGE.p.q\nNS3.PACKAGE.p.q.L\tinput.foo\t/^\t\tvar L$/;\"\tv\tdefinition:NS3.PACKAGE.p.q\nv_g2\tinput.foo\t/^var v_g2$/;\"\tv\tnamespace:NS3\nNS3.v_g2\tinput.foo\t/^var v_g2$/;\"\tv\tnamespace:NS3\n"
  },
  {
    "path": "Units/regex-flag-scope.r/regex-with-scope-autoFQTag.d/input.foo",
    "content": "# open:X\nns NS1\ndefine x {\n\tdefine y {\n\t       var v_y_0\n\t       var v_y_1\n\t}\n\tdefine z {\n\t       var v_z_0\n\t       var v_z_1\n\t       define a {\n\t       }\n\t}\n}\n\nns NS2\ndefine p {\n# def:WRAPPER\n   define q {\n\t  print\n   }\n}\n\nglobal\nvar v_g1\ndefine d_g {\n       var v_l\n}\n\nns NS3\npackage PACKAGE\ndefine p {\n   define q {\n\t  print\n\t  {\n\t\tvar L\n\t  }\n   }\n\n# end of define\n}\n\n# end of package\nend\n\nvar v_g2\n# close\n"
  },
  {
    "path": "Units/regex-flag-scope.r/regex-with-scope-nested.d/args.ctags",
    "content": "# To check the output easier\n--sort=no\n--fields=+e\n\n--langdef=foo\n    --map-foo=+.foo\n    --regex-foo=/^#.*//{exclusive}\n    --regex-foo=/^[[:blank:]]*define[[:blank:]]+([[:alnum:]_]+)[[:blank:]]*\\{/\\1/d,definition/{scope=push}\n    --regex-foo=/^[[:blank:]]*\\{/_/d,definition/{scope=push}{placeholder}\n    --regex-foo=/^[[:blank:]]*package[[:blank:]]+([[:alnum:]_]+)/\\1/p,package/{scope=push}\n    --regex-foo=/^[[:blank:]]*end[[:blank:]]*$//{scope=pop}{exclusive}\n    --regex-foo=/^[[:blank:]]*\\}[[:blank:]]*$//{scope=pop}{exclusive}\n    --regex-foo=/^[[:blank:]]*ns[[:blank:]]+([[:alnum:]_]+)/\\1/n,namespace/{scope=set}\n    --regex-foo=/^[[:blank:]]*var[[:blank:]]+([[:alnum:]_]+)/\\1/v,var/{scope=ref}\n    --regex-foo=/^[[:blank:]]*global//{scope=clear}{exclusive}\n\n--langdef=bar{base=foo}\n   --kinddef-bar=s,scope,scopes\n   --kinddef-bar=d,definition,definitions\n   --regex-bar=/^# open:([[:alnum:]_]+)/\\1/s/{scope=push}\n   --regex-bar=/^# def:([[:alnum:]_]+)/\\1/d/{scope=ref}\n   --regex-bar=/^# close//{scope=pop}{exclusive}\n"
  },
  {
    "path": "Units/regex-flag-scope.r/regex-with-scope-nested.d/expected.tags",
    "content": "X\tinput.foo\t/^# open:X$/;\"\ts\tend:47\nNS1\tinput.foo\t/^ns NS1$/;\"\tn\tend:15\nx\tinput.foo\t/^define x {$/;\"\td\tnamespace:NS1\tend:14\ny\tinput.foo\t/^\tdefine y {$/;\"\td\tdefinition:NS1.x\tend:7\nv_y_0\tinput.foo\t/^\t       var v_y_0$/;\"\tv\tdefinition:NS1.x.y\nv_y_1\tinput.foo\t/^\t       var v_y_1$/;\"\tv\tdefinition:NS1.x.y\nz\tinput.foo\t/^\tdefine z {$/;\"\td\tdefinition:NS1.x\tend:13\nv_z_0\tinput.foo\t/^\t       var v_z_0$/;\"\tv\tdefinition:NS1.x.z\nv_z_1\tinput.foo\t/^\t       var v_z_1$/;\"\tv\tdefinition:NS1.x.z\na\tinput.foo\t/^\t       define a {$/;\"\td\tdefinition:NS1.x.z\tend:12\nNS2\tinput.foo\t/^ns NS2$/;\"\tn\tend:24\np\tinput.foo\t/^define p {$/;\"\td\tnamespace:NS2\tend:22\nWRAPPER\tinput.foo\t/^# def:WRAPPER$/;\"\td\tscope:X\nq\tinput.foo\t/^   define q {$/;\"\td\tdefinition:NS2.p\tend:21\nv_g1\tinput.foo\t/^var v_g1$/;\"\tv\nd_g\tinput.foo\t/^define d_g {$/;\"\td\tend:28\nv_l\tinput.foo\t/^       var v_l$/;\"\tv\tdefinition:d_g\nNS3\tinput.foo\t/^ns NS3$/;\"\tn\tend:47\nPACKAGE\tinput.foo\t/^package PACKAGE$/;\"\tp\tnamespace:NS3\tend:44\np\tinput.foo\t/^define p {$/;\"\td\tpackage:NS3.PACKAGE\tend:41\nq\tinput.foo\t/^   define q {$/;\"\td\tdefinition:NS3.PACKAGE.p\tend:38\nL\tinput.foo\t/^\t\tvar L$/;\"\tv\tdefinition:NS3.PACKAGE.p.q\nv_g2\tinput.foo\t/^var v_g2$/;\"\tv\tnamespace:NS3\n"
  },
  {
    "path": "Units/regex-flag-scope.r/regex-with-scope-nested.d/input.foo",
    "content": "# open:X\nns NS1\ndefine x {\n\tdefine y {\n\t       var v_y_0\n\t       var v_y_1\n\t}\n\tdefine z {\n\t       var v_z_0\n\t       var v_z_1\n\t       define a {\n\t       }\n\t}\n}\n\nns NS2\ndefine p {\n# def:WRAPPER\n   define q {\n\t  print\n   }\n}\n\nglobal\nvar v_g1\ndefine d_g {\n       var v_l\n}\n\nns NS3\npackage PACKAGE\ndefine p {\n   define q {\n\t  print\n\t  {\n\t\tvar L\n\t  }\n   }\n\n# end of define\n}\n\n# end of package\nend\n\nvar v_g2\n# close\n"
  },
  {
    "path": "Units/regex-flag-scope.r/regex-with-scope.d/args.ctags",
    "content": "# To check the output easier\n--sort=no\n\n--langdef=foo\n    --map-foo=+.foo\n    --regex-foo=/^#.*//{exclusive}\n    --regex-foo=/^[[:blank:]]*define[[:blank:]]+([[:alnum:]_]+)[[:blank:]]*\\{/\\1/d,definition/{scope=push}\n    --regex-foo=/^[[:blank:]]*\\{/_/d,definition/{scope=push}{placeholder}\n    --regex-foo=/^[[:blank:]]*package[[:blank:]]+([[:alnum:]_]+)/\\1/p,package/{scope=push}\n    --regex-foo=/^[[:blank:]]*end[[:blank:]]*$//{scope=pop}{exclusive}\n    --regex-foo=/^[[:blank:]]*\\}[[:blank:]]*$//{scope=pop}{exclusive}\n    --regex-foo=/^[[:blank:]]*ns[[:blank:]]+([[:alnum:]_]+)/\\1/n,namespace/{scope=set}\n    --regex-foo=/^[[:blank:]]*var[[:blank:]]+([[:alnum:]_]+)/\\1/v,var/{scope=ref}\n    --regex-foo=/^[[:blank:]]*global//{scope=clear}{exclusive}\n"
  },
  {
    "path": "Units/regex-flag-scope.r/regex-with-scope.d/expected.tags",
    "content": "NS1\tinput.foo\t/^ns NS1$/;\"\tn\nx\tinput.foo\t/^define x {$/;\"\td\tnamespace:NS1\ny\tinput.foo\t/^\tdefine y {$/;\"\td\tdefinition:NS1.x\nv_y_0\tinput.foo\t/^\t       var v_y_0$/;\"\tv\tdefinition:NS1.x.y\nv_y_1\tinput.foo\t/^\t       var v_y_1$/;\"\tv\tdefinition:NS1.x.y\nz\tinput.foo\t/^\tdefine z {$/;\"\td\tdefinition:NS1.x\nv_z_0\tinput.foo\t/^\t       var v_z_0$/;\"\tv\tdefinition:NS1.x.z\nv_z_1\tinput.foo\t/^\t       var v_z_1$/;\"\tv\tdefinition:NS1.x.z\na\tinput.foo\t/^\t       define a {$/;\"\td\tdefinition:NS1.x.z\nNS2\tinput.foo\t/^ns NS2$/;\"\tn\np\tinput.foo\t/^define p {$/;\"\td\tnamespace:NS2\nq\tinput.foo\t/^   define q {$/;\"\td\tdefinition:NS2.p\nv_g1\tinput.foo\t/^var v_g1$/;\"\tv\nd_g\tinput.foo\t/^define d_g {$/;\"\td\nv_l\tinput.foo\t/^       var v_l$/;\"\tv\tdefinition:d_g\nNS3\tinput.foo\t/^ns NS3$/;\"\tn\nPACKAGE\tinput.foo\t/^package PACKAGE$/;\"\tp\tnamespace:NS3\np\tinput.foo\t/^define p {$/;\"\td\tpackage:NS3.PACKAGE\nq\tinput.foo\t/^   define q {$/;\"\td\tdefinition:NS3.PACKAGE.p\nL\tinput.foo\t/^\t\tvar L$/;\"\tv\tdefinition:NS3.PACKAGE.p.q\nv_g2\tinput.foo\t/^var v_g2$/;\"\tv\tnamespace:NS3\n"
  },
  {
    "path": "Units/regex-flag-scope.r/regex-with-scope.d/input.foo",
    "content": "ns NS1\ndefine x {\n\tdefine y {\n\t       var v_y_0\n\t       var v_y_1\n\t}\n\tdefine z {\n\t       var v_z_0\n\t       var v_z_1\n\t       define a {\n\t       }\n\t}\n}\n\nns NS2\ndefine p {\n   define q {\n\t  print\n   }\n}\n\nglobal\nvar v_g1\ndefine d_g {\n       var v_l\n}\n\nns NS3\npackage PACKAGE\ndefine p {\n   define q {\n\t  print\n\t  {\n\t\tvar L\n\t  }\n   }\n\n# end of define\n}\n\n# end of package\nend\n\nvar v_g2\n"
  },
  {
    "path": "Units/regex-flag-simple.d/args.ctags",
    "content": "--langdef=dummy\n--langmap=dummy:.dummy\n--regex-dummy=/^define:(.*)$/\\1/d,definition/i\n--regex-dummy=/^decl:(.*)$/\\1/D,decl/\n"
  },
  {
    "path": "Units/regex-flag-simple.d/expected.tags",
    "content": "a\tinput.dummy\t/^define:a$/;\"\td\nb\tinput.dummy\t/^Define:b$/;\"\td\nc\tinput.dummy\t/^DEFINE:c$/;\"\td\nd\tinput.dummy\t/^definE:d$/;\"\td\nf\tinput.dummy\t/^decl:f$/;\"\tD\n"
  },
  {
    "path": "Units/regex-flag-simple.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/regex-flag-simple.d/input.dummy",
    "content": "define:a\nDefine:b\nDEFINE:c\ndefinE:d\n\ndecl:f\nDecl:g\nDECL:h\ndecL:i\n\n\n"
  },
  {
    "path": "Units/regex-multiline-flag-advnaceTo.d/args.ctags",
    "content": "--sort=no\n\n--langdef=foo\n--langmap=foo:.foo\n--kinddef-foo=a,something,something\n--mline-regex-foo=/def *([a-z]+)/\\1/a/{mgroup=1}\n\n--langdef=bar\n--langmap=bar:.bar\n--kinddef-bar=a,something,something\n--mline-regex-bar=/def *([a-z]+)/\\1/a/{mgroup=1}{_advanceTo=1start}\n\n--langdef=baz\n--langmap=baz:.baz\n--kinddef-baz=a,something,something\n--mline-regex-baz=/def *([a-z]+)/\\1/a/{mgroup=1}{_advanceTo=1end}\n"
  },
  {
    "path": "Units/regex-multiline-flag-advnaceTo.d/expected.tags",
    "content": "def\tinput.foo\t/^def def def abc$/;\"\ta\nabc\tinput.foo\t/^def def def abc$/;\"\ta\ndef\tinput-0.bar\t/^def def def abc$/;\"\ta\ndef\tinput-0.bar\t/^def def def abc$/;\"\ta\nabc\tinput-0.bar\t/^def def def abc$/;\"\ta\ndef\tinput-1.baz\t/^def def def abc$/;\"\ta\nabc\tinput-1.baz\t/^def def def abc$/;\"\ta\n"
  },
  {
    "path": "Units/regex-multiline-flag-advnaceTo.d/input-0.bar",
    "content": "def def def abc\n"
  },
  {
    "path": "Units/regex-multiline-flag-advnaceTo.d/input-1.baz",
    "content": "def def def abc\n"
  },
  {
    "path": "Units/regex-multiline-flag-advnaceTo.d/input.foo",
    "content": "def def def abc\n"
  },
  {
    "path": "Units/regex-multiline-flag-dos.d/args.ctags",
    "content": "# Taken from #1473 opened by WillDHB\n--langdef=mltest\n--mline-regex-mltest=/@subscribe([[:space:]])*([a-z ]+)[[:space:]]*([a-zA-Z]*)\\(([a-zA-Z]*)/\\3-\\4/s,subscription/{mgroup=3}\n--excmd=mixed\n--fields=+ln\n--language-force=mltest\n"
  },
  {
    "path": "Units/regex-multiline-flag-dos.d/expected.tags",
    "content": "A-SomeEvent\tinput.mlt\t/^public void catchA(SomeEvent e)$/;\"\ts\tline:3\tlanguage:mltest\nB-SomeEvent\tinput.mlt\t/^public void catchB(SomeEvent e)$/;\"\ts\tline:10\tlanguage:mltest\nC-SomeEvent\tinput.mlt\t/^public void catchC(SomeEvent e)$/;\"\ts\tline:17\tlanguage:mltest\nD-SomeEvent\tinput.mlt\t/^public void catchD(SomeEvent e)$/;\"\ts\tline:24\tlanguage:mltest\nE-SomeEvent\tinput.mlt\t/^public void catchE(SomeEvent e)$/;\"\ts\tline:33\tlanguage:mltest\nF-SomeEvent\tinput.mlt\t/^public void catchF(SomeEvent e)$/;\"\ts\tline:43\tlanguage:mltest\n"
  },
  {
    "path": "Units/regex-multiline-flag-dos.d/input.mlt",
    "content": "// Taken from #1473 opened by WillDHB\r\n@subscribe\r\npublic void catchA(SomeEvent e)\r\n{\r\nint x = 4 * 4;\r\nreturn;\r\n}\r\n\r\n@subscribe\r\npublic void catchB(SomeEvent e)\r\n{\r\nint x = 4 * 4;\r\nreturn;\r\n}\r\n\r\n@subscribe\r\npublic void catchC(SomeEvent e)\r\n{\r\nint x = 7 * 7 * 7;\r\nreturn;\r\n}\r\n\r\n@subscribe\r\npublic void catchD(SomeEvent e)\r\n{\r\nint x = 9;\r\n\r\nreturn;\r\n\r\n}\r\n\r\n@subscribe\r\npublic void catchE(SomeEvent e)\r\n{\r\n\r\nint x = 30;\r\n\r\nreturn;\r\n\r\n}\r\n\r\n@subscribe\r\npublic void catchF(SomeEvent e)\r\n{\r\nreturn;\r\n}\r\n"
  },
  {
    "path": "Units/regex-multiline-flag-hat-and-doller.d/args.ctags",
    "content": "--langdef=FOOBAR\n--langmap=FOOBAR:.foobar\n--kinddef-FOOBAR=d,def,definitions\n--kinddef-FOOBAR=D,Def,Definitions\n--mline-regex-foobar=/^def[\\n\\t ]+([a-z]+)$/\\1/d/{mgroup=1}\n--mline-regex-foobar=/[\\n]?def[\\n\\t ]+([a-z]+)\\n/\\1/D/{mgroup=1}\n--fields=+ln\n"
  },
  {
    "path": "Units/regex-multiline-flag-hat-and-doller.d/expected.tags",
    "content": "a\tinput.foobar\t/^\ta$/;\"\tD\tline:2\tlanguage:FOOBAR\na\tinput.foobar\t/^\ta$/;\"\td\tline:2\tlanguage:FOOBAR\nb\tinput.foobar\t/^\tb$/;\"\tD\tline:4\tlanguage:FOOBAR\nb\tinput.foobar\t/^\tb$/;\"\td\tline:4\tlanguage:FOOBAR\nc\tinput.foobar\t/^\tc$/;\"\tD\tline:6\tlanguage:FOOBAR\nc\tinput.foobar\t/^\tc$/;\"\td\tline:6\tlanguage:FOOBAR\nd\tinput.foobar\t/^  d$/;\"\tD\tline:8\tlanguage:FOOBAR\n"
  },
  {
    "path": "Units/regex-multiline-flag-hat-and-doller.d/input.foobar",
    "content": "def\n\ta\ndef\n\tb\ndef\n\tc\n# def\n  d\n\n"
  },
  {
    "path": "Units/regex-multiline-flag-newline.d/args.ctags",
    "content": "--langdef=FOOBAR\n--langmap=FOOBAR:.foobar\n--kinddef-FOOBAR=d,def,definitions\n--mline-regex-foobar=/^def((\\n[\\n\\t])|(: ))([a-z0-9-]+)/\\4/d/{mgroup=4}\n--fields=+ln\n"
  },
  {
    "path": "Units/regex-multiline-flag-newline.d/expected.tags",
    "content": "captureme0\tinput.foobar\t/^def: captureme0$/;\"\td\tline:4\tlanguage:FOOBAR\ncaptureme1\tinput.foobar\t/^captureme1$/;\"\td\tline:8\tlanguage:FOOBAR\ncaptureme2\tinput.foobar\t/^\tcaptureme2$/;\"\td\tline:15\tlanguage:FOOBAR\n"
  },
  {
    "path": "Units/regex-multiline-flag-newline.d/input.foobar",
    "content": "def\ndont-cptureme0\n\ndef: captureme0\n\ndef\n\ncaptureme1\n\ndef\n\n\ndont-captureme1\ndef\n\tcaptureme2\n\n\n"
  },
  {
    "path": "Units/regex-multiline-flag-scope.d/args.ctags",
    "content": "--sort=no\n\n--langdef=Foo{base=C}{dedicated}\n--map-Foo=.foo\n--kinddef-Foo=R,reader,read functions\n--mline-regex-Foo=/\\n[ \\t]+\\.read[ \\t]+=[ \\t]+([a-z_]+_read),\\n/\\1/R/{scope=intervaltab}{mgroup=1}\n"
  },
  {
    "path": "Units/regex-multiline-flag-scope.d/expected.tags",
    "content": "proc_pid_cmdline_ops\tinput.foo\t/^static const struct file_operations proc_pid_cmdline_ops = {$/;\"\tv\ttyperef:typename:const struct file_operations\tfile:\nproc_lstats_operations\tinput.foo\t/^static const struct file_operations proc_lstats_operations = {$/;\"\tv\ttyperef:typename:const struct file_operations\tfile:\nproc_single_file_operations\tinput.foo\t/^static const struct file_operations proc_single_file_operations = {$/;\"\tv\ttyperef:typename:const struct file_operations\tfile:\nproc_pid_cmdline_read\tinput.foo\t/^\t.read\t= proc_pid_cmdline_read,$/;\"\tR\tvariable:proc_pid_cmdline_ops\nseq_read\tinput.foo\t/^\t.read\t\t= seq_read,$/;\"\tR\tvariable:proc_lstats_operations\nseq_read\tinput.foo\t/^\t.read\t\t= seq_read,$/;\"\tR\tvariable:proc_single_file_operations\n"
  },
  {
    "path": "Units/regex-multiline-flag-scope.d/input.foo",
    "content": "/* Taken from Linux (fs/proc/base.c) */\n\nstatic const struct file_operations proc_pid_cmdline_ops = {\n\t.read\t= proc_pid_cmdline_read,\n\t.llseek\t= generic_file_llseek,\n};\n\nstatic const struct file_operations proc_lstats_operations = {\n\t.open\t\t= lstats_open,\n\t.read\t\t= seq_read,\n\t.write\t\t= lstats_write,\n\t.llseek\t\t= seq_lseek,\n\t.release\t= single_release,\n};\n\nstatic const struct file_operations proc_single_file_operations = {\n\t.open\t\t= proc_single_open,\n\t.read\t\t= seq_read,\n\t.llseek\t\t= seq_lseek,\n\t.release\t= single_release,\n};\n"
  },
  {
    "path": "Units/regex-multiline-flag.d/args.ctags",
    "content": "--langdef=javaspring\n--langmap=javaspring:.java\n--mline-regex-javaspring=/@Subscribe([[:space:]])*([a-z ]+)[[:space:]]*([a-zA-Z]*)\\(([a-zA-Z]*)/\\3-\\4/s,subscription/{mgroup=3}\n--excmd=mixed\n--fields=+ln\n"
  },
  {
    "path": "Units/regex-multiline-flag.d/expected.tags",
    "content": "Event-SomeEvent\tinput.java\t/^public void catchEvent(SomeEvent e)$/;\"\ts\tline:2\tlanguage:javaspring\nrecover-Exception\tinput.java\t/^    recover(Exception e)$/;\"\ts\tline:10\tlanguage:javaspring\n"
  },
  {
    "path": "Units/regex-multiline-flag.d/input.java",
    "content": "@Subscribe\npublic void catchEvent(SomeEvent e)\n{\n    return;\n}\n\n\n@Subscribe\npublic void\n    recover(Exception e)\n{\n    return;\n}\n"
  },
  {
    "path": "Units/review-needed.r/bug816636.sml.t/expected.tags",
    "content": "f\tinput.sml\t/^fun f x = 1 + g x$/;\"\tf\ng\tinput.sml\t/^and g x = 2 + f 0;$/;\"\tf\n"
  },
  {
    "path": "Units/review-needed.r/bug816636.sml.t/input.sml",
    "content": "(*\nBugs item #816636, was opened at 2003-10-02 11:01\nMessage generated for change (Tracker Item Submitted) made by Item Submitter\nYou can respond by visiting: \nhttps://sourceforge.net/tracker/?func=detail&atid=106556&aid=816636&group_id=6556\n\nCategory: None\nGroup: None\nStatus: Open\nResolution: None\nPriority: 5\nSubmitted By: Rahul Chaudhry (rahuldotc)\nAssigned to: Nobody/Anonymous (nobody)\nSummary: sml (standard ML) tag support\n\nInitial Comment:\nThe program does not handle the \"and\" keyword of ML.\n\ne.g. on the following code:\n*)\nfun f x = 1 + g x\n\nand g x = 2 + f 0;\n(*\nctags generates a tag for function \"f\" but not for function \"g\".\n*)\n"
  },
  {
    "path": "Units/review-needed.r/dosbatch_test.cmd.t/expected.tags",
    "content": "DONE\tinput.cmd\t/^:DONE$/;\"\tl\nEND\tinput.cmd\t/^:END$/;\"\tl\nERROR\tinput.cmd\t/^:ERROR$/;\"\tl\nERROR_OPTIONS\tinput.cmd\t/^:ERROR_OPTIONS$/;\"\tl\nOPTIONS\tinput.cmd\t/^@if \"%OPTIONS%.\" EQU \"1.\" set OPTIONS=$/;\"\tv\nPATH\tinput.cmd\t/^set PATH=%SQLANY11%\\\\bin32;%PATH%$/;\"\tv\nSAMPLE_DATA\tinput.cmd\t/^:SAMPLE_DATA$/;\"\tl\nUPDATE\tinput.cmd\t/^:UPDATE$/;\"\tl\n"
  },
  {
    "path": "Units/review-needed.r/dosbatch_test.cmd.t/features",
    "content": "regex\n"
  },
  {
    "path": "Units/review-needed.r/dosbatch_test.cmd.t/input.cmd",
    "content": "@SETLOCAL\r\n@echo off\r\n\r\nSET OPTIONS=%1\r\nSET SAMPLE_DATA=%1\r\nif NOT '%SAMPLE_DATA%' EQU '' SET SAMPLE_DATA=1\r\nif '%SAMPLE_DATA%' EQU '' SET SAMPLE_DATA=0\r\n@echo.\r\n@echo.\r\n@echo.Sample data:[%SAMPLE_DATA%]\r\n@echo.\r\n@echo.\r\n \r\n@IF NOT DEFINED SCRIPT_DIR FOR /f %%i IN ('cd') DO @SET SCRIPT_DIR=%%i\r\n\r\n\r\nCALL setenv.cmd \r\n@if NOT \"%errorlevel%\" EQU \"0\" goto ERROR\r\nIF DEFINED required_software_missing goto ERROR\r\n\r\nset PATH=%SQLANY11%\\bin32;%PATH%\r\n\r\n@if \"%OPTIONS%.\" EQU \"1.\" set OPTIONS=\r\n@rem Jump to label if specified\r\n@if NOT \"%OPTIONS%.\" EQU \".\" goto %OPTIONS%\r\n\r\nCALL cleanup11.cmd \r\n\r\n:UPDATE\r\n@echo.\r\n@echo.\r\n@echo Update objects (triggers, procedures, web services)\r\n@echo.\r\n:SAMPLE_DATA\r\n@echo.\r\n@echo.\r\n@echo Create report\r\n@echo.\r\ncd %SQL_DIR%\r\n@echo on\r\n%DBISQL% -c \"dsn=%CONS%;uid=dba;pwd=%CONS_PWD%;autostop=no\" read schema_logging.sql; \r\n@echo off\r\n@if NOT \"%errorlevel%\" EQU \"0\" goto ERROR\r\n@echo errorlevel [%errorlevel%]\r\n\r\n:DONE\r\n@echo.\r\n@echo.\r\n@echo.-------------------------------------------\r\n@echo  All Done!\r\n@echo.-------------------------------------------\r\n@echo.\r\n@echo.\r\ngoto END\r\n\r\n:ERROR\r\nFOR /f %%i IN ('cd') DO @SET CURR_DIR=%%i\r\n@echo.\r\n@echo.\r\n@echo.-------------------------------------------\r\n@echo.    ERROR!!\r\n@echo errorlevel = %errorlevel%\r\n@echo gendb11.cmd \r\n@echo.\r\n@echo.Working directory:\r\n@echo CURR_DIR=%CURR_DIR%\r\n@echo.-------------------------------------------\r\n@echo.\r\ngoto END\r\n\r\n:ERROR_OPTIONS\r\n@echo.\r\n@echo.\r\n@echo.\r\n@echo ********************************************************\r\n@echo * Please provide dev, qa, demo as a commandline option *\r\n@echo ********************************************************\r\n@echo.\r\n@echo.\r\n@echo.\r\nGOTO END\r\n\r\n\r\n:END\r\ncd %SCRIPT_DIR%\r\n@ENDLOCAL\r\n"
  },
  {
    "path": "Units/review-needed.r/flex_override.mxml.t/expected.tags",
    "content": "myGet\tinput.mxml\t/^\t\t\tpublic override function get myGet():MyClass$/;\"\tp\nmyOverride\tinput.mxml\t/^\t\t\tpublic override function myOverride():void$/;\"\tf\nsave\tinput.mxml\t/^\t\t\tprivate function save():void$/;\"\tf\n"
  },
  {
    "path": "Units/review-needed.r/flex_override.mxml.t/input.mxml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<ATag xmlns=\"http://www.adobe.com/2006/mxml\">\r\n\t<mx:Script>\r\n\t\t<![CDATA[\r\n\t\t\tpublic override function get myGet():MyClass\r\n\t\t\t{\r\n\t\t\t}\r\n\r\n\t\t\tprivate function save():void\r\n\t\t\t{\r\n\t\t\t}\r\n\r\n\t\t\t\r\n\t\t\tpublic override function myOverride():void\r\n\t\t\t{\r\n\t\t\t\tsuper.myOverride();\r\n\t\t\t}\r\n\t\t]]>\r\n\t</mx:Script>\r\n</ATag>\r\n"
  },
  {
    "path": "Units/review-needed.r/ingres_procedures.sql.t/README",
    "content": "I don't understand the original intent of this test case.\n\nFor db0002, x, n, err are tagged as a variable.\nFor db0003, they are not.\n\nThe difference between db0002 and db0003 is \"=\" and \"AS\".\nAbout \"=\" I cannot find good document.\n\nMasatake YAMATO\n\n"
  },
  {
    "path": "Units/review-needed.r/ingres_procedures.sql.t/args.ctags",
    "content": "--fields=+n\n--kinds-SQL=+l\n\n"
  },
  {
    "path": "Units/review-needed.r/ingres_procedures.sql.t/expected.tags",
    "content": "db0001\tinput.sql\t/^CREATE PROCEDURE db0001 (short_name varchar(12) not null)  $/;\"\tp\tline:1\ndb0002\tinput.sql\t/^PROCEDURE db0002 (short_name varchar(12) not null)  =$/;\"\tp\tline:5\ndb0003\tinput.sql\t/^PROCEDURE db0003 (short_name varchar(12) not null)  $/;\"\tp\tline:35\nerr\tinput.sql\t/^err = varchar(80) not null not default; $/;\"\tl\tline:40\tprocedure:db0003\nerr\tinput.sql\t/^err = varchar(80) not null not default; $/;\"\tv\tline:9\nn\tinput.sql\t/^n = i4 not null; $/;\"\tl\tline:39\tprocedure:db0003\nn\tinput.sql\t/^n = i4 not null; $/;\"\tv\tline:8\nx\tinput.sql\t/^x = varchar(12) not null; $/;\"\tl\tline:38\tprocedure:db0003\nx\tinput.sql\t/^x = varchar(12) not null; $/;\"\tv\tline:7\n"
  },
  {
    "path": "Units/review-needed.r/ingres_procedures.sql.t/input.sql",
    "content": "CREATE PROCEDURE db0001 (short_name varchar(12) not null)  \r\nBEGIN\r\nEND;\r\n\r\nPROCEDURE db0002 (short_name varchar(12) not null)  =\r\nDECLARE\r\nx = varchar(12) not null; \r\nn = i4 not null; \r\nerr = varchar(80) not null not default; \r\nBEGIN \r\n\r\n    if short_name = '' then \r\n        err := 'db0001: Pusty short_name!'; \r\n        raise error 8001 :err; \r\n        return -1; \r\n    endif; \r\n\r\n    select :x = bank_sh_name from \"cafa\". banks_directory_066 \r\n    where bank_sh_name = :short_name; \r\n    if iierrornumber != 0 THEN rollback; \r\n        err := 'db0001: Podczas sprawdzania unikalnosci short_name \r\n        banku wystapil blad!'; \r\n        raise error 8001 :err; \r\n        return -1; \r\n    endif; \r\n\r\n    n := iirowcount; \r\n    commit; \r\n    return n; \r\nEND;  \r\n\r\n-- OR with AS instead of =:\r\n\r\n\r\nPROCEDURE db0003 (short_name varchar(12) not null)  \r\nAS\r\nDECLARE\r\nx = varchar(12) not null; \r\nn = i4 not null; \r\nerr = varchar(80) not null not default; \r\nBEGIN \r\n\r\n    if short_name = '' then \r\n        err := 'db0001: Pusty short_name!'; \r\n        raise error 8001 :err; \r\n        return -1; \r\n    endif; \r\n\r\n    select :x = bank_sh_name from \"cafa\". banks_directory_066 \r\n    where bank_sh_name = :short_name; \r\n    if iierrornumber != 0 THEN rollback; \r\n        err := 'db0001: Podczas sprawdzania unikalnosci short_name \r\n        banku wystapil blad!'; \r\n        raise error 8001 :err; \r\n        return -1; \r\n    endif; \r\n\r\n    n := iirowcount; \r\n    commit; \r\n    return n; \r\nEND  \r\n\r\n\r\n"
  },
  {
    "path": "Units/review-needed.r/jbrown.vr.t/args.ctags",
    "content": "--fields=+r\n--extras=+r\n"
  },
  {
    "path": "Units/review-needed.r/jbrown.vr.t/expected.tags",
    "content": "Transaction\tinput.vr\t/^class Transaction {$/;\"\tc\troles:def\naddress\tinput.vr\t/^   rand bit[31:0] address;           \\/\\/ allow for address to be random$/;\"\tm\tclass:Transaction\tfile:\troles:def\ndata\tinput.vr\t/^   rand bit[31:0] data;              \\/\\/ allow for data to be random$/;\"\tm\tclass:Transaction\tfile:\troles:def\nmine.vrh\tinput.vr\t/^#include \"mine.vrh\"/;\"\th\troles:local\nmyProgram\tinput.vr\t/^program myProgram {$/;\"\tp\troles:def\nnew\tinput.vr\t/^   task new( (bit[31:0] address = -1), (bit[31:0] data = -1)) {$/;\"\tt\tclass:Transaction\tfile:\troles:def\nvera_defines.vrh\tinput.vr\t/^#include <vera_defines.vrh>/;\"\th\troles:system\nwriteBus\tinput.vr\t/^   task writeBus() {$/;\"\tt\tclass:Transaction\tfile:\troles:def\n"
  },
  {
    "path": "Units/review-needed.r/jbrown.vr.t/input.vr",
    "content": "// Sample taken from:\n// http://groups.google.com/groups?q=vera+group:comp.*&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=39BD28D2.40737022%40us.ibm.com.remove.this.spam.filter&rnum=6\n#include <vera_defines.vrh>\n#include \"mine.vrh\"\n\ntypedef class Transaction;\n\nprogram myProgram {\n\n   Transaction t;                    // t is of type Transaction\n\n   repeat(100) {                     // write 100 times to the bus\n      t = new();                     // random values to bus\n      t.writeBus();\n   }\n\n   t = new(32'h0000_0000, 32'h1111_afaf);  // write direct value to bus\n   t.writeBus();\n}\n\nclass Transaction {\n\n   rand bit[31:0] address;           // allow for address to be random\n   rand bit[31:0] data;              // allow for data to be random\n\n   constraint c1 {                   // rules for generating address\n      address >= 32'h0000_1000;\n      address <= 32'h0000_1fff;\n   }\n\n   // no rules for data: any value is valid\n\n   task new( (bit[31:0] address = -1), (bit[31:0] data = -1)) {\n      void = this.randomize();       // randomize address, data\n      if (address != -1) this.address = address;\n      if (data != -1) this.data = data;\n   }\n\n   task writeBus() {\n      printf(\"Writing Bus w/ Addr=%h_%h Data=%h_%h\\n\",\n          address[31:16], address[15:0], data[31:16], data[15:0]);\n\n      @1 bus.address = address;\n      bus.data = data;\n      @1 bus.addrress = 32'hzzzz_zzzz;\n      bus.data = 32'hzzzz_zzzz;\n   }\n} // end class Transaction\n"
  },
  {
    "path": "Units/review-needed.r/maze.erl.t/expected.tags",
    "content": "build\tinput.erl\t/^build() ->$/;\"\tf\tmodule:maze\ngenerate\tinput.erl\t/^generate(#maze{}=M) ->$/;\"\tf\tmodule:maze\ngenerate\tinput.erl\t/^generate(#maze{}=M, R, X, Y) ->$/;\"\tf\tmodule:maze\nmaze\tinput.erl\t/^-module(maze).$/;\"\tm\npick\tinput.erl\t/^pick(List) ->$/;\"\tf\tmodule:maze\npick\tinput.erl\t/^pick(Tuple) when tuple(Tuple) ->$/;\"\tf\tmodule:maze\nscramble\tinput.erl\t/^scramble(List) ->$/;\"\tf\tmodule:maze\nscramble\tinput.erl\t/^scramble(List, Acc) ->$/;\"\tf\tmodule:maze\nscramble\tinput.erl\t/^scramble(Tuple) when tuple(Tuple) ->$/;\"\tf\tmodule:maze\nscramble\tinput.erl\t/^scramble([], Acc) -> Acc;$/;\"\tf\tmodule:maze\nseed\tinput.erl\t/^seed() ->$/;\"\tf\tmodule:maze\ntot_get\tinput.erl\t/^tot_get(X, Y, Tot) ->$/;\"\tf\tmodule:maze\ntot_new\tinput.erl\t/^tot_new(W, H, Cell) ->$/;\"\tf\tmodule:maze\ntot_print\tinput.erl\t/^tot_print(ToT) ->$/;\"\tf\tmodule:maze\ntot_print\tinput.erl\t/^tot_print(Y, ToT) -> ok.$/;\"\tf\tmodule:maze\ntot_print\tinput.erl\t/^tot_print(Y, ToT) when Y =< size(ToT) ->$/;\"\tf\tmodule:maze\ntot_print_tuple\tinput.erl\t/^tot_print_tuple(T) ->$/;\"\tf\tmodule:maze\ntot_print_tuple\tinput.erl\t/^tot_print_tuple(X, T) -> ok.$/;\"\tf\tmodule:maze\ntot_print_tuple\tinput.erl\t/^tot_print_tuple(X, T) when X =< size(T) ->$/;\"\tf\tmodule:maze\ntot_put\tinput.erl\t/^tot_put(X, Y, Tot, V) ->$/;\"\tf\tmodule:maze\n"
  },
  {
    "path": "Units/review-needed.r/maze.erl.t/input.erl",
    "content": "-module(maze).\n-vsn('2002.0317').\n-author('cpressey@catseye.mb.ca').\n-copyright('Copyright (c)2002 Cat`s Eye Technologies. All rights reserved.').\n\n%%% Redistribution and use in source and binary forms, with or without\n%%% modification, are permitted provided that the following conditions\n%%% are met:\n%%%\n%%%   Redistributions of source code must retain the above copyright\n%%%   notice, this list of conditions and the following disclaimer.\n%%%\n%%%   Redistributions in binary form must reproduce the above copyright\n%%%   notice, this list of conditions and the following disclaimer in\n%%%   the documentation and/or other materials provided with the\n%%%   distribution.\n%%%\n%%%   Neither the name of Cat's Eye Technologies nor the names of its\n%%%   contributors may be used to endorse or promote products derived\n%%%   from this software without specific prior written permission.\n%%%\n%%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n%%% CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,\n%%% INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n%%% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n%%% DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE\n%%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n%%% OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n%%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n%%% OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n%%% ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n%%% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n%%% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n%%% POSSIBILITY OF SUCH DAMAGE. \n\n-include(\"maze.hrl\").\n\n-export([build/0, generate/1]).\n\n\n%%% BEGIN maze.erl %%%\n\n%%% A simple maze-drawing program.\n\n%% Driver function -----------------------------------------------------\n\nbuild() ->\n  Tot = generate(#maze{}),\n  tot_print(Tot).\n\n%% Maze generation function --------------------------------------------\n\ngenerate(#maze{}=M) ->\n  seed(),\n  {X, Y} = {random:uniform(M#maze.width div 2) * 2, random:uniform(M#maze.height div 2) * 2},\n  \n  R2 = tot_put(X, Y, tot_new(M#maze.width, M#maze.height, M#maze.wall), M#maze.space),\n  generate(M, R2, X, Y).\n  \ngenerate(#maze{}=M, R, X, Y) ->\n  lists:foldl(fun({DX, DY}, A) ->\n                NX = X + DX * 2, NY = Y + DY * 2,\n\t\tW = M#maze.wall,\n                case catch tot_get(NX, NY, A) of\n\t\t   W ->\n                    M1 = tot_put(X + DX, Y + DY, A, M#maze.space),\n                    M2 = tot_put(NX, NY, M1, M#maze.space),\n                    generate(M, M2, NX, NY);\n\t          _ -> A\n\t\tend \n\t      end, R, scramble([{-1,0}, {1,0}, {0,-1}, {0,1}])).\n\n%%% ToT (Tuple-of-Tuples) Utilities ------------------------------------\n\ntot_new(W, H, Cell) ->\n  erlang:make_tuple(H, erlang:make_tuple(W, Cell)).\n  \ntot_get(X, Y, Tot) ->\n  element(X, element(Y, Tot)).\n  \ntot_put(X, Y, Tot, V) ->\n  setelement(Y, Tot, setelement(X, element(Y, Tot), V)).\n\ntot_print(ToT) ->\n  tot_print(1, ToT).\ntot_print(Y, ToT) when Y =< size(ToT) ->\n  tot_print_tuple(element(Y, ToT)),\n  io:fwrite(\"~n\"),\n  tot_print(Y+1, ToT);\ntot_print(Y, ToT) -> ok.\ntot_print_tuple(T) ->\n  tot_print_tuple(1, T).\ntot_print_tuple(X, T) when X =< size(T) ->\n  io:fwrite(\"~s\", [[element(X, T)]]),\n  tot_print_tuple(X+1, T);\ntot_print_tuple(X, T) -> ok.\n  \n%%% Randomness Functions -----------------------------------------------\n\n%% Seed the random number generator so that it will produce unpredictable\n%% values.  Should be called once at startup, before using random numbers.\n\nseed() ->\n  {H,M,S} = time(),\n  random:seed(S,M,H),\n  random:uniform(23).  % prime the pump - first number can be iffy\n\n%% Pick a random element from a tuple or a list (equal chance for every\n%% element.)\n\npick(Tuple) when tuple(Tuple) ->\n  pick(tuple_to_list(Tuple));\npick(List) ->\n  lists:nth(random:uniform(length(List)), List).\n\n%% Mix up the order (shuffle or scramble) a tuple or list.\n\nscramble(Tuple) when tuple(Tuple) ->\n  list_to_tuple(scramble(tuple_to_list(Tuple)));\nscramble(List) ->\n  scramble(List, []).\nscramble([], Acc) -> Acc;\nscramble(List, Acc) ->\n  S = pick(List),\n  scramble(List -- [S], Acc ++ [S]).\n\n%%% END of maze.erl %%%   \n"
  },
  {
    "path": "Units/review-needed.r/maze.hrl.t/expected.tags",
    "content": "SPACE\tinput.hrl\t/^-define(SPACE, $ ).$/;\"\td\nWALL\tinput.hrl\t/^-define(WALL,  $#).$/;\"\td\nmaze\tinput.hrl\t/^-record(maze,{width = 40,height = 30, space = ?SPACE ,wall = ?WALL}).$/;\"\tr\n"
  },
  {
    "path": "Units/review-needed.r/maze.hrl.t/input.hrl",
    "content": "-vsn('2002.0317').\n-author('cpressey@catseye.mb.ca').\n-copyright('Copyright (c)2002 Cat`s Eye Technologies. All rights reserved.').\n\n%%% Redistribution and use in source and binary forms, with or without\n%%% modification, are permitted provided that the following conditions\n%%% are met:\n%%%\n%%%   Redistributions of source code must retain the above copyright\n%%%   notice, this list of conditions and the following disclaimer.\n%%%\n%%%   Redistributions in binary form must reproduce the above copyright\n%%%   notice, this list of conditions and the following disclaimer in\n%%%   the documentation and/or other materials provided with the\n%%%   distribution.\n%%%\n%%%   Neither the name of Cat's Eye Technologies nor the names of its\n%%%   contributors may be used to endorse or promote products derived\n%%%   from this software without specific prior written permission.\n%%%\n%%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n%%% CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,\n%%% INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n%%% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n%%% DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE\n%%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n%%% OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n%%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n%%% OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n%%% ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n%%% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n%%% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n%%% POSSIBILITY OF SUCH DAMAGE. \n\n%%% BEGIN maze.hrl %%%\n\n-define(SPACE, $ ).\n-define(WALL,  $#).\n\n-record(maze,{width = 40,height = 30, space = ?SPACE ,wall = ?WALL}).\n\n%%% END of maze.erl %%%   \n"
  },
  {
    "path": "Units/review-needed.r/simple.asp.t/expected.tags",
    "content": "HtmlCutout\tinput.asp\t/^function HtmlCutout(lang, str)   'dig-out a piece of text from a multilang. string str$/;\"\tf\nconstDecl\tinput.asp\t/^Const constDecl = 512$/;\"\td\nf_translate_9data\tinput.asp\t/^Function f_translate_9data(id,defaulttext,data)   'lookup lang_???(id) and insert data at $0,$1,/;\"\tf\njs_erroralert\tinput.asp\t/^sub js_erroralert(txt)           'print inline-script to generate popup-window with txt$/;\"\ts\nlang_length\tinput.asp\t/^DIM lang_length     '(htmlct.inc) num.chars to get, i.e. mid(str, lang_start, lang_length)$/;\"\tv\nlang_start\tinput.asp\t/^Dim lang_start      '(htmlct.inc) char-index, use for multilanguage-strings$/;\"\tv\nlang_swe\tinput.asp\t/^dim lang_swe(230)   'translation-table for pagetitles, buttons, etc.$/;\"\tv\n"
  },
  {
    "path": "Units/review-needed.r/simple.asp.t/input.asp",
    "content": "' \"_descriptions.asp\"\n' Documentation for my variables\n\nConst constDecl = 512\n\nDim lang_start      '(htmlct.inc) char-index, use for multilanguage-strings\nDIM lang_length     '(htmlct.inc) num.chars to get, i.e. mid(str, lang_start, lang_length)\nfunction HtmlCutout(lang, str)   'dig-out a piece of text from a multilang. string str\n\ndim lang_swe(230)   'translation-table for pagetitles, buttons, etc.\nFunction f_translate_9data(id,defaulttext,data)   'lookup lang_???(id) and insert data at $0,$1,...\n\nsub js_erroralert(txt)           'print inline-script to generate popup-window with txt\n\n"
  },
  {
    "path": "Units/review-needed.r/simple.fal.t/expected.tags",
    "content": "regex\tinput.fal\t/^load regex$/;\"\ti\nsocket\tinput.fal\t/^import from socket$/;\"\ti\ntest\tinput.fal\t/^function test_func( parameter )$/;\"\tf\n"
  },
  {
    "path": "Units/review-needed.r/simple.fal.t/input.fal",
    "content": "#!/usr/bin/env falcon\n\n/* \n * COMMENT\n */\n\nimport from socket\n\nconst CONSTANT = \"1\"\n\ntest = \"\nThis is a multi-line\\n\\n\nstring\"\n\n// If statement\nif test.len < 1 \n    > 'ERROR'\nend\n\n// Import statement\nload regex\n\n// Simple variables\nstring_var = \"falcon string\"\nnumber_var = 8192\n\n// Function\nfunction test_func( parameter )\n   printl( \"Hello \", parameter )\nend\n \n// Function call\ndo_something( \"world\" ) \n\n/* vim: set sw=4 sts=4 : */\n\n"
  },
  {
    "path": "Units/review-needed.r/simple.pb.t/expected.tags",
    "content": "a.l\tinput.pb\t/^Global a.l$/;\"\tv\nb.l\tinput.pb\t/^Dim b.l(100)$/;\"\tv\nf.l\tinput.pb\t/^Procedure f.l()$/;\"\tf\nstart\tinput.pb\t/^start:$/;\"\tl\ntest\tinput.pb\t/^Structure test$/;\"\tt\n"
  },
  {
    "path": "Units/review-needed.r/simple.pb.t/input.pb",
    "content": "Gosub start\n\nGlobal a.l\nDim b.l(100)\n\nStructure test\n    a.l\n    b.l\nEndStructure\n\nProcedure f.l()\n    a = 3\nEndProcedure\n\nstart:\n    f()\nReturn\n\n"
  },
  {
    "path": "Units/review-needed.r/simple.sml.t/expected.tags",
    "content": "'a\tinput.sml\t/^  type 'a susp = unit -> 'a$/;\"\tt\n'a\tinput.sml\t/^  type 'a susp$/;\"\tt\nChange\tinput.sml\t/^exception Change$/;\"\te\nCircular\tinput.sml\t/^\t  exception Circular$/;\"\te\nFactorial\tinput.sml\t/^exception Factorial$/;\"\te\nImpossible\tinput.sml\t/^          exception Impossible$/;\"\te\nMatcher\tinput.sml\t/^functor Matcher (structure RegExp : REGEXP) :> MATCHER = struct$/;\"\tc\nRegExp\tinput.sml\t/^    structure RegExp = RegExp$/;\"\tr\nRegExp\tinput.sml\t/^functor Matcher (structure RegExp : REGEXP) :> MATCHER = struct$/;\"\tr\nSUSP\tinput.sml\t/^signature SUSP = sig$/;\"\ts\nSusp\tinput.sml\t/^structure Susp :> SUSP = struct$/;\"\tr\nabstype_name\tinput.sml\t/^abstype abstype_name$/;\"\tt\nchecked_factorial\tinput.sml\t/^    fun checked_factorial n =$/;\"\tf\nchecked_factorial\tinput.sml\t/^fun checked_factorial n =$/;\"\tf\ndelay\tinput.sml\t/^  fun delay (t : 'a susp) =$/;\"\tf\ndelay\tinput.sml\t/^  val delay : (unit -> 'a) -> 'a susp$/;\"\tv\ndist\tinput.sml\t/^fun dist (x:real, y:real):real = sqrt (x*x + y*y)$/;\"\tf\ndist\tinput.sml\t/^val dist : real * real -> real = fn (x:real, y:real) => sqrt (x*x + y*y)$/;\"\tv\nfact\tinput.sml\t/^    fun fact 0 = 1$/;\"\tf\nforce\tinput.sml\t/^  fun force t = t ()$/;\"\tf\nforce\tinput.sml\t/^  val force : 'a susp -> 'a$/;\"\tv\nhyperlink\tinput.sml\t/^type hyperlink = { protocol : string, address : string, display : string }$/;\"\tt\nloopback\tinput.sml\t/^  fun loopback f =$/;\"\tf\nmatch\tinput.sml\t/^    fun match regexp string =$/;\"\tf\nmatch_is\tinput.sml\t/^    fun match_is Zero cs k = false$/;\"\tf\nmemo\tinput.sml\t/^          val memo : 'a susp ref = ref (fn () => raise Impossible)$/;\"\tv\nr\tinput.sml\t/^\t  val r = ref (fn () => raise Circular)$/;\"\tv\nr\tinput.sml\t/^              let val r = t () in memo := (fn () => r); r end$/;\"\tv\nsuit\tinput.sml\t/^datatype suit = Spades | Hearts | Diamonds | Clubs$/;\"\tt\nt\tinput.sml\t/^\t  fun t () = force (!r)$/;\"\tf\nt'\tinput.sml\t/^          fun t' () =$/;\"\tf\n"
  },
  {
    "path": "Units/review-needed.r/simple.sml.t/input.sml",
    "content": "(* This is a comment *)\n\nabstype abstype_name\n\ndatatype suit = Spades | Hearts | Diamonds | Clubs\n\nexception Change\n\nfun dist (x:real, y:real):real = sqrt (x*x + y*y)\n\nfun checked_factorial n =\n    if n < 0 then\n\traise Factorial\n    else if n=0 then\n\t1\n\t else\n\t     n * checked_factorial (n-1)\n\nexception Factorial\n\nlocal\n    fun fact 0 = 1\n      | fact n = n * fact (n-1)\nin\n    fun checked_factorial n =\n\tif n >= 0 then\n\t    fact n\n\telse\n\t    raise Factorial\nend \n\nfunctor Matcher (structure RegExp : REGEXP) :> MATCHER = struct\n\n    structure RegExp = RegExp\n\n    open RegExp\n\n    fun match_is Zero cs k = false\n      | match_is One cs k = k cs\n      | match_is (Char c) nil _ = false\n      | match_is (Char c) (c'::cs) k = (c=c') andalso (k cs)\n      | match_is (Plus (r1, r2)) cs k =\n\t(match_is r1 cs k) orelse (match_is r2 cs k)\n      | match_is (Times (r1, r2)) cs k =\n\tmatch_is r1 cs (fn cs' => match_is r2 cs' k)\n      | match_is (r as Star r1) cs k =\n\t(k cs) orelse match_is r1 cs (fn cs' => match_is r cs' k)\n\n    fun match regexp string =\n\tmatch_is regexp (String.explode string)\n\t(fn nil => true | _ => false)\n\nend\n\nsignature SUSP = sig\n  type 'a susp\n  val force : 'a susp -> 'a\n  val delay : (unit -> 'a) -> 'a susp\nend\n\nstructure Susp :> SUSP = struct\n  type 'a susp = unit -> 'a\n  fun force t = t ()\n  fun delay (t : 'a susp) =\n      let\n          exception Impossible\n          val memo : 'a susp ref = ref (fn () => raise Impossible)\n          fun t' () =\n              let val r = t () in memo := (fn () => r); r end\n      in\n          memo := t';\n          fn () => (!memo)()\n      end\n  fun loopback f =\n      let\n\t  exception Circular\n\t  val r = ref (fn () => raise Circular)\n\t  fun t () = force (!r)\n      in\n\t  r := f t ; t\n      end\nend\n\ntype hyperlink = { protocol : string, address : string, display : string }\n\nval dist : real * real -> real = fn (x:real, y:real) => sqrt (x*x + y*y)\n"
  },
  {
    "path": "Units/review-needed.r/simple.vr.t/args.ctags",
    "content": "--fields=+r\n--extras=+r\n"
  },
  {
    "path": "Units/review-needed.r/simple.vr.t/expected.tags",
    "content": "DEFAULT_BIT\tinput.vr\t/^#define DEFAULT_BIT /;\"\td\tfile:\troles:def\nDEFAULT_BIT\tinput.vr\t/^#undef DEFAULT_BIT$/;\"\td\tfile:\troles:undef\nDEFAULT_INT\tinput.vr\t/^#define DEFAULT_INT /;\"\td\tfile:\troles:def\nDEFAULT_INT\tinput.vr\t/^#undef DEFAULT_INT$/;\"\td\tfile:\troles:undef\nExampleClass\tinput.vr\t/^class ExampleClass {$/;\"\tc\troles:def\ngetBit\tinput.vr\t/^    public function bit getBit() {$/;\"\tf\tclass:ExampleClass\troles:def\ngetData\tinput.vr\t/^    public function bit[7:0] getData() {$/;\"\tf\tclass:ExampleClass\troles:def\ngetInt\tinput.vr\t/^    public function integer getInt() {$/;\"\tf\tclass:ExampleClass\troles:def\ngetName\tinput.vr\t/^    public function string getName() {$/;\"\tf\tclass:ExampleClass\troles:def\ngetTrigger\tinput.vr\t/^function event ExampleClass::getTrigger() {$/;\"\tf\tclass:ExampleClass\troles:def\nm_bit\tinput.vr\t/^    local bit       m_bit = DEFAULT_BIT;$/;\"\tm\tclass:ExampleClass\tfile:\troles:def\nm_data\tinput.vr\t/^    local bit [7:0] m_data = 8'hzz;$/;\"\tm\tclass:ExampleClass\tfile:\troles:def\nm_eTrigger\tinput.vr\t/^    local event     m_eTrigger;$/;\"\tm\tclass:ExampleClass\tfile:\troles:def\nm_int\tinput.vr\t/^    local integer   m_int = DEFAULT_INT;$/;\"\tm\tclass:ExampleClass\tfile:\troles:def\nm_sName\tinput.vr\t/^    local string    m_sName;$/;\"\tm\tclass:ExampleClass\tfile:\troles:def\nmain\tinput.vr\t/^program main {$/;\"\tp\troles:def\nnew\tinput.vr\t/^    public task new(string sInstName, integer index = DEFAULT_INT) {$/;\"\tt\tclass:ExampleClass\troles:def\nsetBit\tinput.vr\t/^    public task setBit(bit b) {$/;\"\tt\tclass:ExampleClass\troles:def\nsetData\tinput.vr\t/^    public task setData(bit[7:0] data) {$/;\"\tt\tclass:ExampleClass\troles:def\nsetInt\tinput.vr\t/^    public task setInt(integer i) {$/;\"\tt\tclass:ExampleClass\troles:def\nsetName\tinput.vr\t/^    public task setName(string name) {$/;\"\tt\tclass:ExampleClass\troles:def\nsetTrigger\tinput.vr\t/^task ExampleClass::setTrigger(event e) {$/;\"\tt\tclass:ExampleClass\troles:def\ntrigger\tinput.vr\t/^    public task trigger() {$/;\"\tt\tclass:ExampleClass\troles:def\nwait\tinput.vr\t/^    public task wait() {$/;\"\tt\tclass:ExampleClass\troles:def\n"
  },
  {
    "path": "Units/review-needed.r/simple.vr.t/input.vr",
    "content": "// Sample provide by Dave Eggum <deggum@synopsys.com> on 05 Sep 2002.\n#define DEFAULT_INT 0\n#define DEFAULT_BIT 1'bz\n\ntypedef class ExampleClass;\n\nprogram main {\n    ExampleClass oModel1, oModel2, oModel3;\n    integer i;\n    string s;\n\n    oModel1 = new(\"first\");\n    oModel2 = new(\"second\", 2);\n    oModel3 = new(\"third\", 3);\n\n    oModel1.setInt(5);\n    i = oModel1.getInt();\n\n    oModel2.m_bit; // BUG: this jump should fail... but doesn't\n\n    oModel2.setData(8'o272);\n    oModel2.setData(8'hbA);\n    oModel2.setData(8'b1011_1010);\n\n    s = oModel3.getName();\n\n    fork {\n        oModel3.wait();\n    } {\n        oModel3.trigger();\n    }\n    join all\n\n    wait_child();\n\n    oModel3.setTrigger(void);\n}\n\nclass ExampleClass {\n    local integer   m_int = DEFAULT_INT;\n    local bit       m_bit = DEFAULT_BIT;\n    local bit [7:0] m_data = 8'hzz;\n    local string    m_sName;\n    local event     m_eTrigger;\n\n    public task new(string sInstName, integer index = DEFAULT_INT) {\n        m_sName = sInstName;\n        m_int = index;\n    }\n\n    public task setInt(integer i) {\n        m_int = i;\n    }\n\n    public function integer getInt() {\n        getInt = m_int;\n    }\n\n    public task setBit(bit b) {\n        m_bit = b;\n    }\n\n    public function bit getBit() {\n        getBit = m_bit;\n    }\n\n    public task setData(bit[7:0] data) {\n        m_data = data;\n    }\n\n    public function bit[7:0] getData() {\n        getData = m_data;\n    }\n\n    public task setName(string name) {\n        m_sName = name;\n    }\n\n    public function string getName() {\n        getName = m_sName;\n    }\n\n    public task wait() {\n        sync(ALL,m_eTrigger);\n    }\n\n    public task trigger() {\n        trigger(m_eTrigger);\n    }\n\n    public task setTrigger(event e); // prototype\n    public function event getTrigger(); // prototype\n}\n\ntask ExampleClass::setTrigger(event e) {\n    m_eTrigger = e;\n}\n\nfunction event ExampleClass::getTrigger() {\n    getTrigger = m_eTrigger;\n}\n#undef DEFAULT_INT\n#undef DEFAULT_BIT\n// vim: sw=4:ts=4:expandtab\n"
  },
  {
    "path": "Units/review-needed.r/test.vhd.t/README",
    "content": "This one is inherited from e-ctags source tree.\n\nThe input looks too large. Therefore it is hard to evaluate the impact\nof code change; a small improvement on the parser needs huge updates\nof expected.tags.\n\nThe test case is kept as is. However, if you will work on improving\nVHDL parser, you may rearrange this test input as you need.\n"
  },
  {
    "path": "Units/review-needed.r/test.vhd.t/args.ctags",
    "content": "--sort=no\n--kinds-VHDL=+{port}{component}{generic}{local}\n"
  },
  {
    "path": "Units/review-needed.r/test.vhd.t/expected.tags",
    "content": "badger\tinput.vhd\t/^package body badger is$/;\"\tP\nbadger2\tinput.vhd\t/^package body badger2 is$/;\"\tP\naccumulator\tinput.vhd\t/^entity accumulator is port ($/;\"\te\na\tinput.vhd\t/^  a: in std_logic_vector(3 downto 0);$/;\"\tq\tentity:accumulator\nclk\tinput.vhd\t/^  clk, reset: in std_logic;$/;\"\tq\tentity:accumulator\nreset\tinput.vhd\t/^  clk, reset: in std_logic;$/;\"\tq\tentity:accumulator\naccum\tinput.vhd\t/^  accum: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:accumulator\nsimple\tinput.vhd\t/^architecture simple of accumulator is$/;\"\ta\tentity:accumulator\naccumL\tinput.vhd\t/^signal accumL: unsigned(3 downto 0);$/;\"\ts\tarchitecture:accumulator.simple\naccumulate\tinput.vhd\t/^  accumulate: process (clk, reset) begin$/;\"\tQ\tarchitecture:accumulator.simple\nadder\tinput.vhd\t/^entity adder is port ($/;\"\te\na\tinput.vhd\t/^  a,b : in std_logic_vector (15 downto 0);$/;\"\tq\tentity:adder\nb\tinput.vhd\t/^  a,b : in std_logic_vector (15 downto 0);$/;\"\tq\tentity:adder\nsum\tinput.vhd\t/^  sum: out std_logic_vector (15 downto 0)$/;\"\tq\tentity:adder\ndataflow\tinput.vhd\t/^architecture dataflow of adder is$/;\"\ta\tentity:adder\npAdderAttr\tinput.vhd\t/^entity pAdderAttr is$/;\"\te\nn\tinput.vhd\t/^  generic(n : integer := 8);$/;\"\tg\tentity:pAdderAttr\na\tinput.vhd\t/^  port (a    : in std_logic_vector(n - 1 downto 0);$/;\"\tq\tentity:pAdderAttr\nb\tinput.vhd\t/^        b    : in std_logic_vector(n - 1 downto 0);$/;\"\tq\tentity:pAdderAttr\ncin\tinput.vhd\t/^        cin  : in std_logic;$/;\"\tq\tentity:pAdderAttr\nsum\tinput.vhd\t/^        sum  : out std_logic_vector(n - 1 downto 0);$/;\"\tq\tentity:pAdderAttr\ncout\tinput.vhd\t/^        cout : out std_logic);$/;\"\tq\tentity:pAdderAttr\nloopDemo\tinput.vhd\t/^architecture loopDemo of pAdderAttr is$/;\"\ta\tentity:pAdderAttr\nanonProcesscfc8de98010f\tinput.vhd\t/^  process(a, b, cin)$/;\"\tQ\tarchitecture:pAdderAttr.loopDemo\ncarry\tinput.vhd\t/^    variable carry: std_logic_vector(sum'length downto 0);$/;\"\tv\tprocess:pAdderAttr.loopDemo.anonProcesscfc8de98010f\nlocalSum\tinput.vhd\t/^    variable localSum: std_logic_vector(sum'high downto 0);$/;\"\tv\tprocess:pAdderAttr.loopDemo.anonProcesscfc8de98010f\nadder\tinput.vhd\t/^entity adder is port ($/;\"\te\na\tinput.vhd\t/^  a,b: in unsigned(3 downto 0);$/;\"\tq\tentity:adder\nb\tinput.vhd\t/^  a,b: in unsigned(3 downto 0);$/;\"\tq\tentity:adder\nsum\tinput.vhd\t/^  sum: out unsigned(3 downto 0)$/;\"\tq\tentity:adder\nsimple\tinput.vhd\t/^architecture simple of adder is$/;\"\ta\tentity:adder\nAND2\tinput.vhd\t/^entity AND2 is port ($/;\"\te\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tentity:AND2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tentity:AND2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tentity:AND2\nrtl\tinput.vhd\t/^architecture rtl of AND2 is$/;\"\ta\tentity:AND2\nasyncLoad\tinput.vhd\t/^entity asyncLoad is port ($/;\"\te\nloadVal\tinput.vhd\t/^  loadVal, d: in std_logic_vector(3 downto 0);$/;\"\tq\tentity:asyncLoad\nd\tinput.vhd\t/^  loadVal, d: in std_logic_vector(3 downto 0);$/;\"\tq\tentity:asyncLoad\nclk\tinput.vhd\t/^  clk, load: in std_logic;$/;\"\tq\tentity:asyncLoad\nload\tinput.vhd\t/^  clk, load: in std_logic;$/;\"\tq\tentity:asyncLoad\nq\tinput.vhd\t/^  q: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:asyncLoad\nrtl\tinput.vhd\t/^architecture rtl of asyncLoad is$/;\"\ta\tentity:asyncLoad\nanonProcesscfc8de98020f\tinput.vhd\t/^  process (clk, load, loadVal) begin$/;\"\tQ\tarchitecture:asyncLoad.rtl\nBidirBuf\tinput.vhd\t/^entity BidirBuf is port ($/;\"\te\nOE\tinput.vhd\t/^  OE: in std_logic;$/;\"\tq\tentity:BidirBuf\ninput\tinput.vhd\t/^  input: in std_logic_vector;$/;\"\tq\tentity:BidirBuf\noutput\tinput.vhd\t/^  output: out std_logic_vector$/;\"\tq\tentity:BidirBuf\nbehavioral\tinput.vhd\t/^architecture behavioral of BidirBuf is$/;\"\ta\tentity:BidirBuf\nbidirBuf\tinput.vhd\t/^  bidirBuf: process (OE, input) begin$/;\"\tQ\tarchitecture:BidirBuf.behavioral\nBidirCnt\tinput.vhd\t/^entity BidirCnt is port ($/;\"\te\nOE\tinput.vhd\t/^  OE: in std_logic;$/;\"\tq\tentity:BidirCnt\nCntEnable\tinput.vhd\t/^  CntEnable: in std_logic;$/;\"\tq\tentity:BidirCnt\nLdCnt\tinput.vhd\t/^  LdCnt: in std_logic;$/;\"\tq\tentity:BidirCnt\nClk\tinput.vhd\t/^  Clk: in std_logic;$/;\"\tq\tentity:BidirCnt\nRst\tinput.vhd\t/^  Rst: in std_logic;$/;\"\tq\tentity:BidirCnt\nCnt\tinput.vhd\t/^  Cnt: inout std_logic_vector(3 downto 0)$/;\"\tq\tentity:BidirCnt\nbehavioral\tinput.vhd\t/^architecture behavioral of BidirCnt is$/;\"\ta\tentity:BidirCnt\nLoadCnt\tinput.vhd\t/^  component LoadCnt port ($/;\"\tC\tarchitecture:BidirCnt.behavioral\nCntEn\tinput.vhd\t/^    CntEn: in std_logic;$/;\"\tq\tcomponent:BidirCnt.behavioral.LoadCnt\nLdCnt\tinput.vhd\t/^    LdCnt: in std_logic;$/;\"\tq\tcomponent:BidirCnt.behavioral.LoadCnt\nLdData\tinput.vhd\t/^    LdData: in std_logic_vector(3 downto 0);$/;\"\tq\tcomponent:BidirCnt.behavioral.LoadCnt\nClk\tinput.vhd\t/^    Clk: in std_logic;$/;\"\tq\tcomponent:BidirCnt.behavioral.LoadCnt\nRst\tinput.vhd\t/^    Rst: in std_logic;$/;\"\tq\tcomponent:BidirCnt.behavioral.LoadCnt\nCntVal\tinput.vhd\t/^    CntVal: out std_logic_vector(3 downto 0)$/;\"\tq\tcomponent:BidirCnt.behavioral.LoadCnt\nBidirBuf\tinput.vhd\t/^  component BidirBuf port ($/;\"\tC\tarchitecture:BidirCnt.behavioral\nOE\tinput.vhd\t/^    OE: in std_logic;$/;\"\tq\tcomponent:BidirCnt.behavioral.BidirBuf\ninput\tinput.vhd\t/^    input: in std_logic_vector;$/;\"\tq\tcomponent:BidirCnt.behavioral.BidirBuf\noutput\tinput.vhd\t/^    output: inout std_logic_vector$/;\"\tq\tcomponent:BidirCnt.behavioral.BidirBuf\nCntVal\tinput.vhd\t/^signal CntVal: std_logic_vector(3 downto 0);$/;\"\ts\tarchitecture:BidirCnt.behavioral\nLoadVal\tinput.vhd\t/^signal LoadVal: std_logic_vector(3 downto 0);$/;\"\ts\tarchitecture:BidirCnt.behavioral\nBIDIR\tinput.vhd\t/^entity BIDIR is port ($/;\"\te\nip\tinput.vhd\t/^  ip: in std_logic;$/;\"\tq\tentity:BIDIR\noe\tinput.vhd\t/^  oe: in std_logic;$/;\"\tq\tentity:BIDIR\nop_fb\tinput.vhd\t/^  op_fb: out std_logic;$/;\"\tq\tentity:BIDIR\nop\tinput.vhd\t/^  op: inout std_logic$/;\"\tq\tentity:BIDIR\nrtl\tinput.vhd\t/^architecture rtl of BIDIR is$/;\"\ta\tentity:BIDIR\nbidirbuffer\tinput.vhd\t/^entity bidirbuffer is port ($/;\"\te\ninput\tinput.vhd\t/^  input: in std_logic;$/;\"\tq\tentity:bidirbuffer\nenable\tinput.vhd\t/^  enable: in std_logic;$/;\"\tq\tentity:bidirbuffer\nfeedback\tinput.vhd\t/^  feedback: out std_logic;$/;\"\tq\tentity:bidirbuffer\noutput\tinput.vhd\t/^  output: inout std_logic$/;\"\tq\tentity:bidirbuffer\nstructural\tinput.vhd\t/^architecture structural of bidirbuffer is$/;\"\ta\tentity:bidirbuffer\nclkGen\tinput.vhd\t/^entity clkGen is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:clkGen\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:clkGen\nClkDiv2\tinput.vhd\t/^  ClkDiv2, ClkDiv4,$/;\"\tq\tentity:clkGen\nClkDiv4\tinput.vhd\t/^  ClkDiv2, ClkDiv4,$/;\"\tq\tentity:clkGen\nClkDiv6\tinput.vhd\t/^  ClkDiv6,ClkDiv8: out std_logic$/;\"\tq\tentity:clkGen\nClkDiv8\tinput.vhd\t/^  ClkDiv6,ClkDiv8: out std_logic$/;\"\tq\tentity:clkGen\nbehav\tinput.vhd\t/^architecture behav of clkGen is$/;\"\ta\tentity:clkGen\nnumClks\tinput.vhd\t/^subtype numClks is std_logic_vector(1 to 4);$/;\"\tT\tarchitecture:clkGen.behav\nnumPatterns\tinput.vhd\t/^subtype numPatterns is integer range 0 to 11;$/;\"\tT\tarchitecture:clkGen.behav\nclkTableType\tinput.vhd\t/^type clkTableType is array (numpatterns'low to numPatterns'high) of numClks;$/;\"\tt\tarchitecture:clkGen.behav\nclkTable\tinput.vhd\t/^constant clkTable: clkTableType := clkTableType'($/;\"\tc\tarchitecture:clkGen.behav\nindex\tinput.vhd\t/^signal index: numPatterns;$/;\"\ts\tarchitecture:clkGen.behav\nlookupTable\tinput.vhd\t/^  lookupTable: process (clk, reset) begin$/;\"\tQ\tarchitecture:clkGen.behav\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\nenable\tinput.vhd\t/^  enable: in std_logic;$/;\"\tq\tentity:counter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: buffer unsigned(3 downto 0)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\nincrement\tinput.vhd\t/^  increment: process (clk, reset) begin$/;\"\tQ\tarchitecture:counter.simple\ncount8\tinput.vhd\t/^entity count8 is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:count8\nrst\tinput.vhd\t/^  rst: in std_logic;$/;\"\tq\tentity:count8\ncount\tinput.vhd\t/^  count: out std_logic_vector(7 downto 0)$/;\"\tq\tentity:count8\nstructural\tinput.vhd\t/^architecture structural of count8 is$/;\"\ta\tentity:count8\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: out std_logic_vector(0 to 9)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\ncountL\tinput.vhd\t/^signal countL: unsigned(0 to 9);$/;\"\ts\tarchitecture:counter.simple\nincrement\tinput.vhd\t/^  increment: process (clk, reset) begin$/;\"\tQ\tarchitecture:counter.simple\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: out std_logic_vector(9 downto 0)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\ncountL\tinput.vhd\t/^signal countL: unsigned(9 downto 0);$/;\"\ts\tarchitecture:counter.simple\nincrement\tinput.vhd\t/^  increment: process (clk, reset) begin$/;\"\tQ\tarchitecture:counter.simple\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:counter\nload\tinput.vhd\t/^  load: in std_logic;$/;\"\tq\tentity:counter\nenable\tinput.vhd\t/^  enable: in std_logic;$/;\"\tq\tentity:counter\ndata\tinput.vhd\t/^  data: in std_logic_vector(3 downto 0);$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\ncountL\tinput.vhd\t/^signal countL: unsigned(3 downto 0);$/;\"\ts\tarchitecture:counter.simple\nincrement\tinput.vhd\t/^  increment: process (clk, reset) begin$/;\"\tQ\tarchitecture:counter.simple\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:counter\nload\tinput.vhd\t/^  load: in std_logic;$/;\"\tq\tentity:counter\ndata\tinput.vhd\t/^  data: in std_logic_vector(3 downto 0);$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\ncountL\tinput.vhd\t/^signal countL: unsigned(3 downto 0);$/;\"\ts\tarchitecture:counter.simple\nincrement\tinput.vhd\t/^  increment: process (clk, reset) begin$/;\"\tQ\tarchitecture:counter.simple\nCnt4Term\tinput.vhd\t/^entity Cnt4Term is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:Cnt4Term\nCnt\tinput.vhd\t/^  Cnt: out std_logic_vector(3 downto 0);$/;\"\tq\tentity:Cnt4Term\nTermCnt\tinput.vhd\t/^  TermCnt: out std_logic$/;\"\tq\tentity:Cnt4Term\nbehavioral\tinput.vhd\t/^architecture behavioral of Cnt4Term is$/;\"\ta\tentity:Cnt4Term\nCntL\tinput.vhd\t/^signal CntL: unsigned(3 downto 0);$/;\"\ts\tarchitecture:Cnt4Term.behavioral\nincrement\tinput.vhd\t/^  increment: process begin$/;\"\tQ\tarchitecture:Cnt4Term.behavioral\nCounter\tinput.vhd\t/^entity Counter is port ($/;\"\te\nclock\tinput.vhd\t/^  clock: in std_logic;$/;\"\tq\tentity:Counter\nCount\tinput.vhd\t/^  Count: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:Counter\nstructural\tinput.vhd\t/^architecture structural of Counter is$/;\"\ta\tentity:Counter\nCnt4Term\tinput.vhd\t/^  component Cnt4Term port ($/;\"\tC\tarchitecture:Counter.structural\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tcomponent:Counter.structural.Cnt4Term\nCnt\tinput.vhd\t/^    Cnt: out std_logic_vector(3 downto 0);$/;\"\tq\tcomponent:Counter.structural.Cnt4Term\nTermCnt\tinput.vhd\t/^    TermCnt: out std_logic);$/;\"\tq\tcomponent:Counter.structural.Cnt4Term\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\ncountL\tinput.vhd\t/^signal countL: unsigned(3 downto 0);$/;\"\ts\tarchitecture:counter.simple\nincrement\tinput.vhd\t/^  increment: process (clk) begin$/;\"\tQ\tarchitecture:counter.simple\nconvertArith\tinput.vhd\t/^entity convertArith is port ($/;\"\te\ntruncate\tinput.vhd\t/^  truncate: out unsigned(3 downto 0);$/;\"\tq\tentity:convertArith\nextend\tinput.vhd\t/^  extend: out unsigned(15 downto 0);$/;\"\tq\tentity:convertArith\ndirection\tinput.vhd\t/^  direction: out unsigned(0 to 7)$/;\"\tq\tentity:convertArith\nsimple\tinput.vhd\t/^architecture simple of convertArith is$/;\"\ta\tentity:convertArith\nConst\tinput.vhd\t/^constant Const: unsigned(7 downto 0) := \"00111010\";$/;\"\tc\tarchitecture:convertArith.simple\nFEWGATES\tinput.vhd\t/^entity FEWGATES is port ($/;\"\te\na\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nb\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nc\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nd\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\ny\tinput.vhd\t/^  y: out std_logic$/;\"\tq\tentity:FEWGATES\nconcurrent\tinput.vhd\t/^architecture concurrent of FEWGATES is$/;\"\ta\tentity:FEWGATES\nTHREE\tinput.vhd\t/^constant THREE: std_logic_vector(1 downto 0) := \"11\";$/;\"\tc\tarchitecture:FEWGATES.concurrent\ntypeConvert\tinput.vhd\t/^entity typeConvert is port ($/;\"\te\na\tinput.vhd\t/^  a: out unsigned(7 downto 0)$/;\"\tq\tentity:typeConvert\nsimple\tinput.vhd\t/^architecture simple of typeConvert is$/;\"\ta\tentity:typeConvert\nConst\tinput.vhd\t/^constant Const: natural := 43;$/;\"\tc\tarchitecture:typeConvert.simple\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\ncountL\tinput.vhd\t/^signal countL: unsigned(3 downto 0);$/;\"\ts\tarchitecture:counter.simple\nincrement\tinput.vhd\t/^  increment: process (clk) begin$/;\"\tQ\tarchitecture:counter.simple\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: out std_logic_vector(0 to 3)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\ncountL\tinput.vhd\t/^signal countL: unsigned(0 to 3);$/;\"\ts\tarchitecture:counter.simple\nincrement\tinput.vhd\t/^  increment: process (clk, reset) begin$/;\"\tQ\tarchitecture:counter.simple\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\ncountL\tinput.vhd\t/^signal countL: unsigned(3 downto 0);$/;\"\ts\tarchitecture:counter.simple\nincrement\tinput.vhd\t/^  increment: process (clk, reset) begin$/;\"\tQ\tarchitecture:counter.simple\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\ncountL\tinput.vhd\t/^signal countL: unsigned(3 downto 0);$/;\"\ts\tarchitecture:counter.simple\nincrement\tinput.vhd\t/^  increment: process (clk, reset) begin$/;\"\tQ\tarchitecture:counter.simple\ncounter\tinput.vhd\t/^entity counter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:counter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:counter\ncount\tinput.vhd\t/^  count: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:counter\nsimple\tinput.vhd\t/^architecture simple of counter is$/;\"\ta\tentity:counter\ncountL\tinput.vhd\t/^signal countL: unsigned(3 downto 0);$/;\"\ts\tarchitecture:counter.simple\nincrement\tinput.vhd\t/^  increment: process (clk, reset) begin$/;\"\tQ\tarchitecture:counter.simple\ndecoder\tinput.vhd\t/^entity decoder is port ($/;\"\te\ndecIn\tinput.vhd\t/^  decIn: in std_logic_vector(1 downto 0);$/;\"\tq\tentity:decoder\ndecOut\tinput.vhd\t/^  decOut: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:decoder\nsimple\tinput.vhd\t/^architecture simple of decoder is$/;\"\ta\tentity:decoder\nisa_dec\tinput.vhd\t/^entity isa_dec is port$/;\"\te\ndev_adr\tinput.vhd\t/^  dev_adr:          in std_logic_vector(19 downto 0);$/;\"\tq\tentity:isa_dec\ndecOut_n\tinput.vhd\t/^  decOut_n:         out std_logic_vector(5 downto 0)$/;\"\tq\tentity:isa_dec\nsynthesis\tinput.vhd\t/^architecture synthesis of isa_dec is$/;\"\ta\tentity:isa_dec\nCtrlRegRange\tinput.vhd\t/^  constant  CtrlRegRange: std_logic_vector(2 downto 0)    := \"100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nSuperIoRange\tinput.vhd\t/^  constant  SuperIoRange: std_logic_vector(2 downto 0)    := \"010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIntCtrlReg\tinput.vhd\t/^  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIoIntStatReg\tinput.vhd\t/^  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nRstCtrlReg\tinput.vhd\t/^  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nAtcStatusReg\tinput.vhd\t/^  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nMgmtStatusReg\tinput.vhd\t/^  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nsio_dec_n\tinput.vhd\t/^  alias sio_dec_n: std_logic is        decOut_n(5);$/;\"\tA\tarchitecture:isa_dec.synthesis\nrst_ctrl_rd_n\tinput.vhd\t/^  alias rst_ctrl_rd_n: std_logic is    decOut_n(4);$/;\"\tA\tarchitecture:isa_dec.synthesis\natc_stat_rd_n\tinput.vhd\t/^  alias atc_stat_rd_n: std_logic is    decOut_n(3);$/;\"\tA\tarchitecture:isa_dec.synthesis\nmgmt_stat_rd_n\tinput.vhd\t/^  alias mgmt_stat_rd_n: std_logic is   decOut_n(2);$/;\"\tA\tarchitecture:isa_dec.synthesis\nio_int_stat_rd_n\tinput.vhd\t/^  alias io_int_stat_rd_n: std_logic is decOut_n(1);$/;\"\tA\tarchitecture:isa_dec.synthesis\nint_ctrl_rd_n\tinput.vhd\t/^  alias int_ctrl_rd_n: std_logic is    decOut_n(0);$/;\"\tA\tarchitecture:isa_dec.synthesis\nupper\tinput.vhd\t/^  alias upper: std_logic_vector(2 downto 0) is dev_adr(19 downto 17);$/;\"\tA\tarchitecture:isa_dec.synthesis\nCtrlBits\tinput.vhd\t/^  alias CtrlBits: std_logic_vector(16 downto 0) is dev_adr(16 downto 0);$/;\"\tA\tarchitecture:isa_dec.synthesis\ndecoder\tinput.vhd\t/^  decoder: process (upper, CtrlBits)$/;\"\tQ\tarchitecture:isa_dec.synthesis\nisa_dec\tinput.vhd\t/^entity isa_dec is port$/;\"\te\ndev_adr\tinput.vhd\t/^  dev_adr:          in std_logic_vector(19 downto 0);$/;\"\tq\tentity:isa_dec\nsio_dec_n\tinput.vhd\t/^  sio_dec_n:        out std_logic;$/;\"\tq\tentity:isa_dec\nrst_ctrl_rd_n\tinput.vhd\t/^  rst_ctrl_rd_n:    out std_logic;$/;\"\tq\tentity:isa_dec\natc_stat_rd_n\tinput.vhd\t/^  atc_stat_rd_n:    out std_logic;$/;\"\tq\tentity:isa_dec\nmgmt_stat_rd_n\tinput.vhd\t/^  mgmt_stat_rd_n:   out std_logic;$/;\"\tq\tentity:isa_dec\nio_int_stat_rd_n\tinput.vhd\t/^  io_int_stat_rd_n: out std_logic;$/;\"\tq\tentity:isa_dec\nint_ctrl_rd_n\tinput.vhd\t/^  int_ctrl_rd_n:    out std_logic$/;\"\tq\tentity:isa_dec\nsynthesis\tinput.vhd\t/^architecture synthesis of isa_dec is$/;\"\ta\tentity:isa_dec\nCtrlRegRange\tinput.vhd\t/^  constant  CtrlRegRange: std_logic_vector(2 downto 0)    := \"100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nSuperIoRange\tinput.vhd\t/^  constant  SuperIoRange: std_logic_vector(2 downto 0)    := \"010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIntCtrlReg\tinput.vhd\t/^  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIoIntStatReg\tinput.vhd\t/^  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nRstCtrlReg\tinput.vhd\t/^  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nAtcStatusReg\tinput.vhd\t/^  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nMgmtStatusReg\tinput.vhd\t/^  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\ndecoder\tinput.vhd\t/^  decoder: process (dev_adr)$/;\"\tQ\tarchitecture:isa_dec.synthesis\nisa_dec\tinput.vhd\t/^entity isa_dec is port$/;\"\te\ndev_adr\tinput.vhd\t/^  dev_adr:         in std_logic_vector(19 downto 0);$/;\"\tq\tentity:isa_dec\nsio_dec_n\tinput.vhd\t/^  sio_dec_n:       out std_logic;$/;\"\tq\tentity:isa_dec\nrst_ctrl_rd_n\tinput.vhd\t/^  rst_ctrl_rd_n:   out std_logic;$/;\"\tq\tentity:isa_dec\natc_stat_rd_n\tinput.vhd\t/^  atc_stat_rd_n:   out std_logic;$/;\"\tq\tentity:isa_dec\nmgmt_stat_rd_n\tinput.vhd\t/^  mgmt_stat_rd_n:  out std_logic;$/;\"\tq\tentity:isa_dec\nio_int_stat_rd_n\tinput.vhd\t/^  io_int_stat_rd_n:out std_logic;$/;\"\tq\tentity:isa_dec\nint_ctrl_rd_n\tinput.vhd\t/^  int_ctrl_rd_n:   out std_logic$/;\"\tq\tentity:isa_dec\nsynthesis\tinput.vhd\t/^architecture synthesis of isa_dec is$/;\"\ta\tentity:isa_dec\nCtrlRegRange\tinput.vhd\t/^  constant  CtrlRegRange: std_logic_vector(2 downto 0)  := \"100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nSuperIoRange\tinput.vhd\t/^  constant  SuperIoRange: std_logic_vector(2 downto 0)  := \"010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIntCtrlReg\tinput.vhd\t/^  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIoIntStatReg\tinput.vhd\t/^  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nRstCtrlReg\tinput.vhd\t/^  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nAtcStatusReg\tinput.vhd\t/^  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nMgmtStatusReg\tinput.vhd\t/^  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nisa_dec\tinput.vhd\t/^entity isa_dec is port$/;\"\te\ndev_adr\tinput.vhd\t/^  dev_adr:          in std_logic_vector(19 downto 0);$/;\"\tq\tentity:isa_dec\ncs0_n\tinput.vhd\t/^  cs0_n:            in std_logic;$/;\"\tq\tentity:isa_dec\nsio_dec_n\tinput.vhd\t/^  sio_dec_n:        out std_logic;$/;\"\tq\tentity:isa_dec\nrst_ctrl_rd_n\tinput.vhd\t/^  rst_ctrl_rd_n:    out std_logic;$/;\"\tq\tentity:isa_dec\natc_stat_rd_n\tinput.vhd\t/^  atc_stat_rd_n:    out std_logic;$/;\"\tq\tentity:isa_dec\nmgmt_stat_rd_n\tinput.vhd\t/^  mgmt_stat_rd_n:   out std_logic;$/;\"\tq\tentity:isa_dec\nio_int_stat_rd_n\tinput.vhd\t/^  io_int_stat_rd_n: out std_logic;$/;\"\tq\tentity:isa_dec\nint_ctrl_rd_n\tinput.vhd\t/^  int_ctrl_rd_n:    out std_logic$/;\"\tq\tentity:isa_dec\nsynthesis\tinput.vhd\t/^architecture synthesis of isa_dec is$/;\"\ta\tentity:isa_dec\nCtrlRegRange\tinput.vhd\t/^  constant  CtrlRegRange: std_logic_vector(2 downto 0)    := \"100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nSuperIoRange\tinput.vhd\t/^  constant  SuperIoRange: std_logic_vector(2 downto 0)    := \"010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIntCtrlReg\tinput.vhd\t/^  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIoIntStatReg\tinput.vhd\t/^  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nRstCtrlReg\tinput.vhd\t/^  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nAtcStatusReg\tinput.vhd\t/^  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nMgmtStatusReg\tinput.vhd\t/^  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\ndecoder\tinput.vhd\t/^  decoder: process (dev_adr, cs0_n)$/;\"\tQ\tarchitecture:isa_dec.synthesis\nisa_dec\tinput.vhd\t/^entity isa_dec is port$/;\"\te\ndev_adr\tinput.vhd\t/^  dev_adr:          in std_logic_vector(19 downto 0);$/;\"\tq\tentity:isa_dec\ncs0_n\tinput.vhd\t/^  cs0_n:            in std_logic;$/;\"\tq\tentity:isa_dec\nsio_dec_n\tinput.vhd\t/^  sio_dec_n:        out std_logic;$/;\"\tq\tentity:isa_dec\nrst_ctrl_rd_n\tinput.vhd\t/^  rst_ctrl_rd_n:    out std_logic;$/;\"\tq\tentity:isa_dec\natc_stat_rd_n\tinput.vhd\t/^  atc_stat_rd_n:    out std_logic;$/;\"\tq\tentity:isa_dec\nmgmt_stat_rd_n\tinput.vhd\t/^  mgmt_stat_rd_n:   out std_logic;$/;\"\tq\tentity:isa_dec\nio_int_stat_rd_n\tinput.vhd\t/^  io_int_stat_rd_n: out std_logic;$/;\"\tq\tentity:isa_dec\nint_ctrl_rd_n\tinput.vhd\t/^  int_ctrl_rd_n:    out std_logic$/;\"\tq\tentity:isa_dec\nsynthesis\tinput.vhd\t/^architecture synthesis of isa_dec is$/;\"\ta\tentity:isa_dec\nCtrlRegRange\tinput.vhd\t/^  constant  CtrlRegRange: std_logic_vector(2 downto 0)    := \"100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nSuperIoRange\tinput.vhd\t/^  constant  SuperIoRange: std_logic_vector(2 downto 0)    := \"010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIntCtrlReg\tinput.vhd\t/^  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIoIntStatReg\tinput.vhd\t/^  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nRstCtrlReg\tinput.vhd\t/^  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nAtcStatusReg\tinput.vhd\t/^  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nMgmtStatusReg\tinput.vhd\t/^  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nLsio_dec_n\tinput.vhd\t/^  signal Lsio_dec_n:        std_logic;$/;\"\ts\tarchitecture:isa_dec.synthesis\nLrst_ctrl_rd_n\tinput.vhd\t/^  signal Lrst_ctrl_rd_n:    std_logic;$/;\"\ts\tarchitecture:isa_dec.synthesis\nLatc_stat_rd_n\tinput.vhd\t/^  signal Latc_stat_rd_n:    std_logic;$/;\"\ts\tarchitecture:isa_dec.synthesis\nLmgmt_stat_rd_n\tinput.vhd\t/^  signal Lmgmt_stat_rd_n:   std_logic;$/;\"\ts\tarchitecture:isa_dec.synthesis\nLio_int_stat_rd_n\tinput.vhd\t/^  signal Lio_int_stat_rd_n: std_logic;$/;\"\ts\tarchitecture:isa_dec.synthesis\nLint_ctrl_rd_n\tinput.vhd\t/^  signal Lint_ctrl_rd_n:    std_logic;$/;\"\ts\tarchitecture:isa_dec.synthesis\ndecoder\tinput.vhd\t/^  decoder: process (dev_adr)$/;\"\tQ\tarchitecture:isa_dec.synthesis\nqualify\tinput.vhd\t/^  qualify: process (cs0_n) begin$/;\"\tQ\tarchitecture:isa_dec.synthesis\nisa_dec\tinput.vhd\t/^entity isa_dec is port$/;\"\te\ndev_adr\tinput.vhd\t/^  dev_adr:          in std_logic_vector(19 downto 0);$/;\"\tq\tentity:isa_dec\nsio_dec_n\tinput.vhd\t/^  sio_dec_n:        out std_logic;$/;\"\tq\tentity:isa_dec\nrst_ctrl_rd_n\tinput.vhd\t/^  rst_ctrl_rd_n:    out std_logic;$/;\"\tq\tentity:isa_dec\natc_stat_rd_n\tinput.vhd\t/^  atc_stat_rd_n:    out std_logic;$/;\"\tq\tentity:isa_dec\nmgmt_stat_rd_n\tinput.vhd\t/^  mgmt_stat_rd_n:   out std_logic;$/;\"\tq\tentity:isa_dec\nio_int_stat_rd_n\tinput.vhd\t/^  io_int_stat_rd_n: out std_logic;$/;\"\tq\tentity:isa_dec\nint_ctrl_rd_n\tinput.vhd\t/^  int_ctrl_rd_n:    out std_logic$/;\"\tq\tentity:isa_dec\nsynthesis\tinput.vhd\t/^architecture synthesis of isa_dec is$/;\"\ta\tentity:isa_dec\nCtrlRegRange\tinput.vhd\t/^  constant  CtrlRegRange: std_logic_vector(2 downto 0)    := \"100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nSuperIoRange\tinput.vhd\t/^  constant  SuperIoRange: std_logic_vector(2 downto 0)    := \"010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIntCtrlReg\tinput.vhd\t/^  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIoIntStatReg\tinput.vhd\t/^  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nRstCtrlReg\tinput.vhd\t/^  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nAtcStatusReg\tinput.vhd\t/^  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nMgmtStatusReg\tinput.vhd\t/^  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\ndecoder\tinput.vhd\t/^  decoder: process ( dev_adr)$/;\"\tQ\tarchitecture:isa_dec.synthesis\ndecProcs\tinput.vhd\t/^package decProcs is$/;\"\tP\ndecProcs\tinput.vhd\t/^package body decProcs is$/;\"\tP\nDEC2x4\tinput.vhd\t/^  procedure DEC2x4 (inputs : in std_logic_vector(1 downto 0);$/;\"\tp\tpackage:decProcs\nisa_dec\tinput.vhd\t/^entity isa_dec is port$/;\"\te\ndev_adr\tinput.vhd\t/^  dev_adr:         in std_logic_vector(19 downto 0);$/;\"\tq\tentity:isa_dec\nsio_dec_n\tinput.vhd\t/^  sio_dec_n:       out std_logic;$/;\"\tq\tentity:isa_dec\nrst_ctrl_rd_n\tinput.vhd\t/^  rst_ctrl_rd_n:   out std_logic;$/;\"\tq\tentity:isa_dec\natc_stat_rd_n\tinput.vhd\t/^  atc_stat_rd_n:   out std_logic;$/;\"\tq\tentity:isa_dec\nmgmt_stat_rd_n\tinput.vhd\t/^  mgmt_stat_rd_n:  out std_logic;$/;\"\tq\tentity:isa_dec\nio_int_stat_rd_n\tinput.vhd\t/^  io_int_stat_rd_n:out std_logic;$/;\"\tq\tentity:isa_dec\nint_ctrl_rd_n\tinput.vhd\t/^  int_ctrl_rd_n:   out std_logic$/;\"\tq\tentity:isa_dec\nsynthesis\tinput.vhd\t/^architecture synthesis of isa_dec is$/;\"\ta\tentity:isa_dec\nCtrlRegRange\tinput.vhd\t/^  constant  CtrlRegRange: std_logic_vector(2 downto 0)  := \"100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nSuperIoRange\tinput.vhd\t/^  constant  SuperIoRange: std_logic_vector(2 downto 0)  := \"010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIntCtrlReg\tinput.vhd\t/^  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nIoIntStatReg\tinput.vhd\t/^  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nRstCtrlReg\tinput.vhd\t/^  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nAtcStatusReg\tinput.vhd\t/^  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nMgmtStatusReg\tinput.vhd\t/^  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";$/;\"\tc\tarchitecture:isa_dec.synthesis\nprogPulse\tinput.vhd\t/^entity progPulse is port ($/;\"\te\nclk\tinput.vhd\t/^  clk, reset: in std_logic;$/;\"\tq\tentity:progPulse\nreset\tinput.vhd\t/^  clk, reset: in std_logic;$/;\"\tq\tentity:progPulse\nloadLength\tinput.vhd\t/^  loadLength,loadDelay: in std_logic;$/;\"\tq\tentity:progPulse\nloadDelay\tinput.vhd\t/^  loadLength,loadDelay: in std_logic;$/;\"\tq\tentity:progPulse\ndata\tinput.vhd\t/^  data: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulse\npulse\tinput.vhd\t/^  pulse: out std_logic$/;\"\tq\tentity:progPulse\nrtl\tinput.vhd\t/^architecture rtl of progPulse is$/;\"\ta\tentity:progPulse\ndelayCnt\tinput.vhd\t/^signal delayCnt, pulseCnt: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\npulseCnt\tinput.vhd\t/^signal delayCnt, pulseCnt: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\ndelayCntVal\tinput.vhd\t/^signal delayCntVal, pulseCntVal: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\npulseCntVal\tinput.vhd\t/^signal delayCntVal, pulseCntVal: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\nstartPulse\tinput.vhd\t/^signal startPulse, endPulse: std_logic;$/;\"\ts\tarchitecture:progPulse.rtl\nendPulse\tinput.vhd\t/^signal startPulse, endPulse: std_logic;$/;\"\ts\tarchitecture:progPulse.rtl\ndelayReg\tinput.vhd\t/^  delayReg: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\nlengthReg\tinput.vhd\t/^  lengthReg: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\npulseDelay\tinput.vhd\t/^  pulseDelay: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\npulseLength\tinput.vhd\t/^  pulseLength: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\npulseOutput\tinput.vhd\t/^  pulseOutput: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\narst\tinput.vhd\t/^    arst : in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic;$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98030f\tinput.vhd\t/^  process (clk) begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\na\tinput.vhd\t/^    a,b,c : in std_logic;$/;\"\tq\tentity:DFF\nb\tinput.vhd\t/^    a,b,c : in std_logic;$/;\"\tq\tentity:DFF\nc\tinput.vhd\t/^    a,b,c : in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98040f\tinput.vhd\t/^  process (clk, a,b,c) begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\na\tinput.vhd\t/^    a,b,c : in std_logic;$/;\"\tq\tentity:DFF\nb\tinput.vhd\t/^    a,b,c : in std_logic;$/;\"\tq\tentity:DFF\nc\tinput.vhd\t/^    a,b,c : in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nlocalRst\tinput.vhd\t/^signal localRst: std_logic;$/;\"\ts\tarchitecture:DFF.rtl\nanonProcesscfc8de98050f\tinput.vhd\t/^  process (clk, localRst) begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\narst\tinput.vhd\t/^    arst: in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98060f\tinput.vhd\t/^  process (clk, arst) begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\naset\tinput.vhd\t/^    aset : in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98070f\tinput.vhd\t/^  process (clk, aset) begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd1\tinput.vhd\t/^    d1, d2: in std_logic;$/;\"\tq\tentity:DFF\nd2\tinput.vhd\t/^    d1, d2: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\narst\tinput.vhd\t/^    arst : in std_logic;$/;\"\tq\tentity:DFF\nq1\tinput.vhd\t/^    q1, q2: out std_logic$/;\"\tq\tentity:DFF\nq2\tinput.vhd\t/^    q1, q2: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98080f\tinput.vhd\t/^  process (clk, arst) begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98090f\tinput.vhd\t/^  process begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFFE\tinput.vhd\t/^entity DFFE is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFFE\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DFFE\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFFE\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFFE\nrtl\tinput.vhd\t/^architecture rtl of DFFE is$/;\"\ta\tentity:DFFE\nanonProcesscfc8de980a0f\tinput.vhd\t/^  process begin$/;\"\tQ\tarchitecture:DFFE.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nenvector\tinput.vhd\t/^    envector: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de980b0f\tinput.vhd\t/^  process (clk) begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de980c0f\tinput.vhd\t/^  process (clk) begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFFE_SR\tinput.vhd\t/^entity DFFE_SR is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFFE_SR\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DFFE_SR\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFFE_SR\nrst\tinput.vhd\t/^    rst: in std_logic;$/;\"\tq\tentity:DFFE_SR\nprst\tinput.vhd\t/^    prst: in std_logic;$/;\"\tq\tentity:DFFE_SR\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFFE_SR\nrtl\tinput.vhd\t/^architecture rtl of DFFE_SR is$/;\"\ta\tentity:DFFE_SR\nanonProcesscfc8de980d0f\tinput.vhd\t/^  process (clk, rst, prst) begin$/;\"\tQ\tarchitecture:DFFE_SR.rtl\nflipFlop\tinput.vhd\t/^entity flipFlop is port ($/;\"\te\nclock\tinput.vhd\t/^  clock, input: in std_logic;$/;\"\tq\tentity:flipFlop\ninput\tinput.vhd\t/^  clock, input: in std_logic;$/;\"\tq\tentity:flipFlop\nffOut\tinput.vhd\t/^  ffOut: out std_logic$/;\"\tq\tentity:flipFlop\nsimple\tinput.vhd\t/^architecture simple of flipFlop is$/;\"\ta\tentity:flipFlop\ndff\tinput.vhd\t/^  procedure dff (signal clk: in std_logic;$/;\"\tp\tarchitecture:flipFlop.simple\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de980e0f\tinput.vhd\t/^  process begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd1\tinput.vhd\t/^    d1, d2: in std_logic;$/;\"\tq\tentity:DFF\nd2\tinput.vhd\t/^    d1, d2: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nsrst\tinput.vhd\t/^    srst : in std_logic;$/;\"\tq\tentity:DFF\nq1\tinput.vhd\t/^    q1, q2: out std_logic$/;\"\tq\tentity:DFF\nq2\tinput.vhd\t/^    q1, q2: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de980f0f\tinput.vhd\t/^  process (clk) begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFFE_SR\tinput.vhd\t/^entity DFFE_SR is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFFE_SR\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DFFE_SR\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFFE_SR\nrst\tinput.vhd\t/^    rst: in std_logic;$/;\"\tq\tentity:DFFE_SR\nprst\tinput.vhd\t/^    prst: in std_logic;$/;\"\tq\tentity:DFFE_SR\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFFE_SR\nrtl\tinput.vhd\t/^architecture rtl of DFFE_SR is$/;\"\ta\tentity:DFFE_SR\nanonProcesscfc8de98100f\tinput.vhd\t/^  process (clk, rst, prst) begin$/;\"\tQ\tarchitecture:DFFE_SR.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nsrst\tinput.vhd\t/^    srst : in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98110f\tinput.vhd\t/^  process begin$/;\"\tQ\tarchitecture:DFF.rtl\nstruct_dffe_sr\tinput.vhd\t/^entity struct_dffe_sr is port ($/;\"\te\nd\tinput.vhd\t/^  d: in std_logic;$/;\"\tq\tentity:struct_dffe_sr\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:struct_dffe_sr\nen\tinput.vhd\t/^  en: in std_logic;$/;\"\tq\tentity:struct_dffe_sr\nrst\tinput.vhd\t/^  rst,prst: in std_logic;$/;\"\tq\tentity:struct_dffe_sr\nprst\tinput.vhd\t/^  rst,prst: in std_logic;$/;\"\tq\tentity:struct_dffe_sr\nq\tinput.vhd\t/^  q: out std_logic$/;\"\tq\tentity:struct_dffe_sr\ninstance\tinput.vhd\t/^architecture instance of struct_dffe_sr is$/;\"\ta\tentity:struct_dffe_sr\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nsrst\tinput.vhd\t/^    srst : in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98120f\tinput.vhd\t/^  process (clk) begin$/;\"\tQ\tarchitecture:DFF.rtl\nstruct_dffe\tinput.vhd\t/^entity struct_dffe is port ($/;\"\te\nd\tinput.vhd\t/^  d: in std_logic;$/;\"\tq\tentity:struct_dffe\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:struct_dffe\nen\tinput.vhd\t/^  en: in std_logic;$/;\"\tq\tentity:struct_dffe\nq\tinput.vhd\t/^  q: out std_logic$/;\"\tq\tentity:struct_dffe\ninstance\tinput.vhd\t/^architecture instance of struct_dffe is$/;\"\ta\tentity:struct_dffe\ndffTri\tinput.vhd\t/^entity dffTri is$/;\"\te\nsize\tinput.vhd\t/^  generic (size: integer := 8);$/;\"\tg\tentity:dffTri\ndata\tinput.vhd\t/^  data: in std_logic_vector(size - 1 downto 0);$/;\"\tq\tentity:dffTri\nclock\tinput.vhd\t/^  clock: in std_logic;$/;\"\tq\tentity:dffTri\nff_enable\tinput.vhd\t/^  ff_enable: in std_logic;$/;\"\tq\tentity:dffTri\nop_enable\tinput.vhd\t/^  op_enable: in std_logic;$/;\"\tq\tentity:dffTri\nqout\tinput.vhd\t/^  qout: out std_logic_vector(size - 1 downto 0)$/;\"\tq\tentity:dffTri\nparameterize\tinput.vhd\t/^architecture parameterize of dffTri is$/;\"\ta\tentity:dffTri\ntribufType\tinput.vhd\t/^type tribufType is record$/;\"\tt\tarchitecture:dffTri.parameterize\nip\tinput.vhd\t/^  ip: std_logic;$/;\"\tr\ttype:dffTri.parameterize.tribufType\noe\tinput.vhd\t/^  oe: std_logic;$/;\"\tr\ttype:dffTri.parameterize.tribufType\nop\tinput.vhd\t/^  op: std_logic;$/;\"\tr\ttype:dffTri.parameterize.tribufType\ntribufArrayType\tinput.vhd\t/^type tribufArrayType is array (integer range <>) of tribufType;$/;\"\tt\tarchitecture:dffTri.parameterize\ntri\tinput.vhd\t/^signal tri: tribufArrayType(size - 1 downto 0);$/;\"\ts\tarchitecture:dffTri.parameterize\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98130f\tinput.vhd\t/^  process begin$/;\"\tQ\tarchitecture:DFF.rtl\nTRIBUF\tinput.vhd\t/^entity TRIBUF is port ($/;\"\te\nip\tinput.vhd\t/^  ip: in std_logic;$/;\"\tq\tentity:TRIBUF\noe\tinput.vhd\t/^  oe: in std_logic;$/;\"\tq\tentity:TRIBUF\nop\tinput.vhd\t/^  op: out std_logic bus$/;\"\tq\tentity:TRIBUF\nsequential\tinput.vhd\t/^architecture sequential of TRIBUF is$/;\"\ta\tentity:TRIBUF\nenable\tinput.vhd\t/^  enable: process (ip,oe) begin$/;\"\tQ\tarchitecture:TRIBUF.sequential\nDLATCHH\tinput.vhd\t/^entity DLATCHH is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DLATCHH\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DLATCHH\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DLATCHH\nrtl\tinput.vhd\t/^architecture rtl of DLATCHH is$/;\"\ta\tentity:DLATCHH\nqLocal\tinput.vhd\t/^signal qLocal: std_logic;$/;\"\ts\tarchitecture:DLATCHH.rtl\nDLATCHH\tinput.vhd\t/^entity DLATCHH is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DLATCHH\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DLATCHH\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DLATCHH\nrtl\tinput.vhd\t/^architecture rtl of DLATCHH is$/;\"\ta\tentity:DLATCHH\nanonProcesscfc8de98140f\tinput.vhd\t/^  process (en, d) begin$/;\"\tQ\tarchitecture:DLATCHH.rtl\nstruct_dlatch\tinput.vhd\t/^entity struct_dlatch is port ($/;\"\te\nd\tinput.vhd\t/^  d: in std_logic;$/;\"\tq\tentity:struct_dlatch\nen\tinput.vhd\t/^  en: in std_logic;$/;\"\tq\tentity:struct_dlatch\nq\tinput.vhd\t/^  q: out std_logic$/;\"\tq\tentity:struct_dlatch\ninstance\tinput.vhd\t/^architecture instance of struct_dlatch is$/;\"\ta\tentity:struct_dlatch\ndownCounter\tinput.vhd\t/^entity downCounter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:downCounter\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:downCounter\ncount\tinput.vhd\t/^  count: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:downCounter\nsimple\tinput.vhd\t/^architecture simple of downCounter is$/;\"\ta\tentity:downCounter\ncountL\tinput.vhd\t/^signal countL: unsigned(3 downto 0);$/;\"\ts\tarchitecture:downCounter.simple\ntermCnt\tinput.vhd\t/^signal termCnt: std_logic;$/;\"\ts\tarchitecture:downCounter.simple\ndecrement\tinput.vhd\t/^  decrement: process (clk, reset) begin$/;\"\tQ\tarchitecture:downCounter.simple\ncompareDC\tinput.vhd\t/^entity compareDC is port ($/;\"\te\naddressBus\tinput.vhd\t/^  addressBus: in std_logic_vector(31 downto 0);$/;\"\tq\tentity:compareDC\naddressHit\tinput.vhd\t/^  addressHit: out std_logic$/;\"\tq\tentity:compareDC\nwontWork\tinput.vhd\t/^architecture wontWork of compareDC is$/;\"\ta\tentity:compareDC\ncompare\tinput.vhd\t/^  compare: process(addressBus) begin$/;\"\tQ\tarchitecture:compareDC.wontWork\nencoder\tinput.vhd\t/^entity encoder is$/;\"\te\ninvec\tinput.vhd\t/^        port (invec: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:encoder\nenc_out\tinput.vhd\t/^              enc_out: out std_logic_vector(2 downto 0)$/;\"\tq\tentity:encoder\nrtl\tinput.vhd\t/^architecture rtl of encoder is$/;\"\ta\tentity:encoder\nencode\tinput.vhd\t/^  encode: process (invec) begin$/;\"\tQ\tarchitecture:encoder.rtl\nencoder\tinput.vhd\t/^entity encoder is$/;\"\te\ninvec\tinput.vhd\t/^  port (invec:in std_logic_vector(7 downto 0);$/;\"\tq\tentity:encoder\nenc_out\tinput.vhd\t/^        enc_out:out  std_logic_vector(2 downto 0)$/;\"\tq\tentity:encoder\nrtl\tinput.vhd\t/^architecture rtl of encoder is$/;\"\ta\tentity:encoder\nanonProcesscfc8de98150f\tinput.vhd\t/^  process (invec)$/;\"\tQ\tarchitecture:encoder.rtl\nencoder\tinput.vhd\t/^entity encoder is$/;\"\te\ninvec\tinput.vhd\t/^  port (invec: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:encoder\nenc_out\tinput.vhd\t/^        enc_out: out std_logic_vector(2 downto 0)$/;\"\tq\tentity:encoder\nrtl\tinput.vhd\t/^architecture rtl of encoder is$/;\"\ta\tentity:encoder\ncompare\tinput.vhd\t/^entity compare is port ($/;\"\te\nina\tinput.vhd\t/^  ina: in std_logic_vector (3 downto 0);$/;\"\tq\tentity:compare\ninb\tinput.vhd\t/^  inb: in std_logic_vector (2 downto 0);$/;\"\tq\tentity:compare\nequal\tinput.vhd\t/^  equal: out std_logic$/;\"\tq\tentity:compare\nsimple\tinput.vhd\t/^architecture simple of compare is$/;\"\ta\tentity:compare\nequalProc\tinput.vhd\t/^  equalProc: process (ina, inb) begin$/;\"\tQ\tarchitecture:compare.simple\nLogicFcn\tinput.vhd\t/^entity LogicFcn is port ($/;\"\te\nA\tinput.vhd\t/^  A: in std_logic;$/;\"\tq\tentity:LogicFcn\nB\tinput.vhd\t/^  B: in std_logic;$/;\"\tq\tentity:LogicFcn\nC\tinput.vhd\t/^  C: in std_logic;$/;\"\tq\tentity:LogicFcn\nY\tinput.vhd\t/^  Y: out std_logic$/;\"\tq\tentity:LogicFcn\nbehavioral\tinput.vhd\t/^architecture behavioral of LogicFcn is$/;\"\ta\tentity:LogicFcn\nfcn\tinput.vhd\t/^  fcn: process (A,B,C) begin$/;\"\tQ\tarchitecture:LogicFcn.behavioral\nLogicFcn\tinput.vhd\t/^entity LogicFcn is port ($/;\"\te\nA\tinput.vhd\t/^  A: in std_logic;$/;\"\tq\tentity:LogicFcn\nB\tinput.vhd\t/^  B: in std_logic;$/;\"\tq\tentity:LogicFcn\nC\tinput.vhd\t/^  C: in std_logic;$/;\"\tq\tentity:LogicFcn\nY\tinput.vhd\t/^  Y: out std_logic$/;\"\tq\tentity:LogicFcn\ndataflow\tinput.vhd\t/^architecture dataflow of LogicFcn is$/;\"\ta\tentity:LogicFcn\nLogicFcn\tinput.vhd\t/^entity LogicFcn is port ($/;\"\te\nA\tinput.vhd\t/^  A: in std_logic;$/;\"\tq\tentity:LogicFcn\nB\tinput.vhd\t/^  B: in std_logic;$/;\"\tq\tentity:LogicFcn\nC\tinput.vhd\t/^  C: in std_logic;$/;\"\tq\tentity:LogicFcn\nY\tinput.vhd\t/^  Y: out std_logic$/;\"\tq\tentity:LogicFcn\nstructural\tinput.vhd\t/^architecture structural of LogicFcn is$/;\"\ta\tentity:LogicFcn\nnotA\tinput.vhd\t/^signal notA, notB, andSignal: std_logic;$/;\"\ts\tarchitecture:LogicFcn.structural\nnotB\tinput.vhd\t/^signal notA, notB, andSignal: std_logic;$/;\"\ts\tarchitecture:LogicFcn.structural\nandSignal\tinput.vhd\t/^signal notA, notB, andSignal: std_logic;$/;\"\ts\tarchitecture:LogicFcn.structural\nSimDFF\tinput.vhd\t/^entity SimDFF is port ($/;\"\te\nD\tinput.vhd\t/^  D, Clk: in std_logic;$/;\"\tq\tentity:SimDFF\nClk\tinput.vhd\t/^  D, Clk: in std_logic;$/;\"\tq\tentity:SimDFF\nQ\tinput.vhd\t/^  Q: out std_logic$/;\"\tq\tentity:SimDFF\nSimModel\tinput.vhd\t/^architecture SimModel of SimDFF is$/;\"\ta\tentity:SimDFF\ntCQ\tinput.vhd\t/^constant tCQ: time := 8 ns;$/;\"\tc\tarchitecture:SimDFF.SimModel\ntS\tinput.vhd\t/^constant tS:  time := 4 ns;$/;\"\tc\tarchitecture:SimDFF.SimModel\ntH\tinput.vhd\t/^constant tH:  time := 3 ns;$/;\"\tc\tarchitecture:SimDFF.SimModel\nreg\tinput.vhd\t/^  reg: process (Clk, D) begin$/;\"\tQ\tarchitecture:SimDFF.SimModel\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98160f\tinput.vhd\t/^  process (clk) begin$/;\"\tQ\tarchitecture:DFF.rtl\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nanonProcesscfc8de98170f\tinput.vhd\t/^  process begin$/;\"\tQ\tarchitecture:DFF.rtl\nFEWGATES\tinput.vhd\t/^entity FEWGATES is port ($/;\"\te\na\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nb\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nc\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nd\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\ny\tinput.vhd\t/^  y: out std_logic$/;\"\tq\tentity:FEWGATES\nstructural\tinput.vhd\t/^architecture structural of FEWGATES is$/;\"\ta\tentity:FEWGATES\nAND2\tinput.vhd\t/^  component AND2 port ($/;\"\tC\tarchitecture:FEWGATES.structural\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.AND2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.AND2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tcomponent:FEWGATES.structural.AND2\nOR2\tinput.vhd\t/^  component OR2 port ($/;\"\tC\tarchitecture:FEWGATES.structural\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.OR2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.OR2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tcomponent:FEWGATES.structural.OR2\nINVERTER\tinput.vhd\t/^  component INVERTER port ($/;\"\tC\tarchitecture:FEWGATES.structural\ni\tinput.vhd\t/^    i: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.INVERTER\no\tinput.vhd\t/^    o: out std_logic$/;\"\tq\tcomponent:FEWGATES.structural.INVERTER\na_and_b\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nc_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nnot_c_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nFEWGATES\tinput.vhd\t/^entity FEWGATES is port ($/;\"\te\na\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nb\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nc\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nd\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\ny\tinput.vhd\t/^  y: out std_logic$/;\"\tq\tentity:FEWGATES\nstructural\tinput.vhd\t/^architecture structural of FEWGATES is$/;\"\ta\tentity:FEWGATES\nAND2\tinput.vhd\t/^  component AND2 port ($/;\"\tC\tarchitecture:FEWGATES.structural\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.AND2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.AND2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tcomponent:FEWGATES.structural.AND2\nOR2\tinput.vhd\t/^  component OR2 port ($/;\"\tC\tarchitecture:FEWGATES.structural\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.OR2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.OR2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tcomponent:FEWGATES.structural.OR2\nINVERTER\tinput.vhd\t/^  component INVERTER port ($/;\"\tC\tarchitecture:FEWGATES.structural\ni\tinput.vhd\t/^    i: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.INVERTER\no\tinput.vhd\t/^    o: out std_logic$/;\"\tq\tcomponent:FEWGATES.structural.INVERTER\na_and_b\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nc_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nnot_c_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nFEWGATES\tinput.vhd\t/^entity FEWGATES is port ($/;\"\te\na\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nb\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nc\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nd\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\ny\tinput.vhd\t/^  y: out std_logic$/;\"\tq\tentity:FEWGATES\nstructural\tinput.vhd\t/^architecture structural of FEWGATES is$/;\"\ta\tentity:FEWGATES\na_and_b\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nc_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nnot_c_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nFEWGATES\tinput.vhd\t/^entity FEWGATES is port ($/;\"\te\na\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nb\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nc\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nd\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\ny\tinput.vhd\t/^  y: out std_logic$/;\"\tq\tentity:FEWGATES\nconcurrent\tinput.vhd\t/^architecture concurrent of FEWGATES is$/;\"\ta\tentity:FEWGATES\na_and_b\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.concurrent\nc_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.concurrent\nnot_c_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.concurrent\nGatesPkg\tinput.vhd\t/^package GatesPkg is$/;\"\tP\nAND2\tinput.vhd\t/^  component AND2 port ($/;\"\tC\tpackage:GatesPkg\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tcomponent:GatesPkg.AND2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tcomponent:GatesPkg.AND2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tcomponent:GatesPkg.AND2\nOR2\tinput.vhd\t/^  component OR2 port ($/;\"\tC\tpackage:GatesPkg\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tcomponent:GatesPkg.OR2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tcomponent:GatesPkg.OR2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tcomponent:GatesPkg.OR2\nINVERTER\tinput.vhd\t/^  component INVERTER port ($/;\"\tC\tpackage:GatesPkg\ni\tinput.vhd\t/^    i: in std_logic;$/;\"\tq\tcomponent:GatesPkg.INVERTER\no\tinput.vhd\t/^    o: out std_logic$/;\"\tq\tcomponent:GatesPkg.INVERTER\nFEWGATES\tinput.vhd\t/^entity FEWGATES is port ($/;\"\te\na\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nb\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nc\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nd\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\ny\tinput.vhd\t/^  y: out std_logic$/;\"\tq\tentity:FEWGATES\nstructural\tinput.vhd\t/^architecture structural of FEWGATES is$/;\"\ta\tentity:FEWGATES\na_and_b\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nc_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nnot_c_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nAND2\tinput.vhd\t/^entity AND2 is port ($/;\"\te\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tentity:AND2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tentity:AND2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tentity:AND2\nrtl\tinput.vhd\t/^architecture rtl of AND2 is$/;\"\ta\tentity:AND2\nOR2\tinput.vhd\t/^entity OR2 is port ($/;\"\te\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tentity:OR2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tentity:OR2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tentity:OR2\nrtl\tinput.vhd\t/^architecture rtl of OR2 is$/;\"\ta\tentity:OR2\nINVERTER\tinput.vhd\t/^entity INVERTER is port ($/;\"\te\ni\tinput.vhd\t/^    i: in std_logic;$/;\"\tq\tentity:INVERTER\no\tinput.vhd\t/^    o: out std_logic$/;\"\tq\tentity:INVERTER\nrtl\tinput.vhd\t/^architecture rtl of INVERTER is$/;\"\ta\tentity:INVERTER\nFEWGATES\tinput.vhd\t/^entity FEWGATES is port ($/;\"\te\na\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nb\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nc\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\nd\tinput.vhd\t/^  a,b,c,d: in std_logic;$/;\"\tq\tentity:FEWGATES\ny\tinput.vhd\t/^  y: out std_logic$/;\"\tq\tentity:FEWGATES\nstructural\tinput.vhd\t/^architecture structural of FEWGATES is$/;\"\ta\tentity:FEWGATES\nAND2\tinput.vhd\t/^  component AND2 port ($/;\"\tC\tarchitecture:FEWGATES.structural\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.AND2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.AND2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tcomponent:FEWGATES.structural.AND2\nOR2\tinput.vhd\t/^  component OR2 port ($/;\"\tC\tarchitecture:FEWGATES.structural\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.OR2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.OR2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tcomponent:FEWGATES.structural.OR2\nINVERTER\tinput.vhd\t/^  component INVERTER port ($/;\"\tC\tarchitecture:FEWGATES.structural\ni\tinput.vhd\t/^    i: in std_logic;$/;\"\tq\tcomponent:FEWGATES.structural.INVERTER\no\tinput.vhd\t/^    o: out std_logic$/;\"\tq\tcomponent:FEWGATES.structural.INVERTER\na_and_b\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nc_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nnot_c_and_d\tinput.vhd\t/^signal a_and_b, c_and_d, not_c_and_d: std_logic;$/;\"\ts\tarchitecture:FEWGATES.structural\nsimHierarchy\tinput.vhd\t/^entity simHierarchy is port ($/;\"\te\nA\tinput.vhd\t/^  A, B, Clk: in std_logic;$/;\"\tq\tentity:simHierarchy\nB\tinput.vhd\t/^  A, B, Clk: in std_logic;$/;\"\tq\tentity:simHierarchy\nClk\tinput.vhd\t/^  A, B, Clk: in std_logic;$/;\"\tq\tentity:simHierarchy\nY\tinput.vhd\t/^  Y: out std_logic$/;\"\tq\tentity:simHierarchy\nhierarchical\tinput.vhd\t/^architecture hierarchical of simHierarchy is$/;\"\ta\tentity:simHierarchy\nADly\tinput.vhd\t/^signal ADly, BDly, OrGateDly, ClkDly: std_logic;$/;\"\ts\tarchitecture:simHierarchy.hierarchical\nBDly\tinput.vhd\t/^signal ADly, BDly, OrGateDly, ClkDly: std_logic;$/;\"\ts\tarchitecture:simHierarchy.hierarchical\nOrGateDly\tinput.vhd\t/^signal ADly, BDly, OrGateDly, ClkDly: std_logic;$/;\"\ts\tarchitecture:simHierarchy.hierarchical\nClkDly\tinput.vhd\t/^signal ADly, BDly, OrGateDly, ClkDly: std_logic;$/;\"\ts\tarchitecture:simHierarchy.hierarchical\nOrGate\tinput.vhd\t/^signal OrGate, FlopOut: std_logic;$/;\"\ts\tarchitecture:simHierarchy.hierarchical\nFlopOut\tinput.vhd\t/^signal OrGate, FlopOut: std_logic;$/;\"\ts\tarchitecture:simHierarchy.hierarchical\nINVERTER\tinput.vhd\t/^entity INVERTER is port ($/;\"\te\ni\tinput.vhd\t/^    i: in std_logic;$/;\"\tq\tentity:INVERTER\no\tinput.vhd\t/^    o: out std_logic$/;\"\tq\tentity:INVERTER\nrtl\tinput.vhd\t/^architecture rtl of INVERTER is$/;\"\ta\tentity:INVERTER\nio1164\tinput.vhd\t/^package io1164 is$/;\"\tP\nio1164\tinput.vhd\t/^package body io1164 is$/;\"\tP\nchar2char_t\tinput.vhd\t/^    type char2char_t is array (character'low to character'high) of character;$/;\"\tt\tpackage:io1164\nlowcase\tinput.vhd\t/^    constant lowcase: char2char_t := ($/;\"\tc\tpackage:io1164\nf_logic_to_character_t\tinput.vhd\t/^    type f_logic_to_character_t is $/;\"\tt\tpackage:io1164\nf_logic_to_character\tinput.vhd\t/^    constant f_logic_to_character : f_logic_to_character_t := $/;\"\tc\tpackage:io1164\nx_charcode\tinput.vhd\t/^    constant x_charcode     : integer := -1;$/;\"\tc\tpackage:io1164\nmaxoct_charcode\tinput.vhd\t/^    constant maxoct_charcode: integer := 7;$/;\"\tc\tpackage:io1164\nmaxhex_charcode\tinput.vhd\t/^    constant maxhex_charcode: integer := 15;$/;\"\tc\tpackage:io1164\nbad_charcode\tinput.vhd\t/^    constant bad_charcode   : integer := integer'left;$/;\"\tc\tpackage:io1164\ndigit2int_t\tinput.vhd\t/^    type digit2int_t is $/;\"\tt\tpackage:io1164\noctdigit2int\tinput.vhd\t/^    constant octdigit2int: digit2int_t := ($/;\"\tc\tpackage:io1164\nhexdigit2int\tinput.vhd\t/^    constant hexdigit2int: digit2int_t := ($/;\"\tc\tpackage:io1164\noct_bits_per_digit\tinput.vhd\t/^    constant oct_bits_per_digit: integer := 3;$/;\"\tc\tpackage:io1164\nhex_bits_per_digit\tinput.vhd\t/^    constant hex_bits_per_digit: integer := 4;$/;\"\tc\tpackage:io1164\nint2octdigit_t\tinput.vhd\t/^    type     int2octdigit_t is $/;\"\tt\tpackage:io1164\nint2octdigit\tinput.vhd\t/^    constant int2octdigit: int2octdigit_t :=$/;\"\tc\tpackage:io1164\nint2hexdigit_t\tinput.vhd\t/^    type     int2hexdigit_t is $/;\"\tt\tpackage:io1164\nint2hexdigit\tinput.vhd\t/^    constant int2hexdigit: int2hexdigit_t :=$/;\"\tc\tpackage:io1164\noct_logic_vector_t\tinput.vhd\t/^    type     oct_logic_vector_t is$/;\"\tt\tpackage:io1164\noctint2logic_t\tinput.vhd\t/^    type     octint2logic_t is $/;\"\tt\tpackage:io1164\noctint2logic\tinput.vhd\t/^    constant octint2logic  : octint2logic_t := ($/;\"\tc\tpackage:io1164\nhex_logic_vector_t\tinput.vhd\t/^    type     hex_logic_vector_t is$/;\"\tt\tpackage:io1164\nhexint2logic_t\tinput.vhd\t/^    type     hexint2logic_t is $/;\"\tt\tpackage:io1164\nhexint2logic\tinput.vhd\t/^    constant hexint2logic  : hexint2logic_t := ($/;\"\tc\tpackage:io1164\nread\tinput.vhd\t/^    procedure read( l: inout line; value: out std_ulogic; good : out boolean ) is$/;\"\tp\tpackage:io1164\nc\tinput.vhd\t/^        variable c      : character;        -- char read while looping$/;\"\tv\tprocedure:io1164.read\nm\tinput.vhd\t/^        variable m      : line;             -- safe copy of L$/;\"\tv\tprocedure:io1164.read\nsuccess\tinput.vhd\t/^        variable success: boolean := false; -- readable version of GOOD$/;\"\tv\tprocedure:io1164.read\ndone\tinput.vhd\t/^        variable done   : boolean := false; -- flag to say done reading chars$/;\"\tv\tprocedure:io1164.read\nread\tinput.vhd\t/^    procedure read( l: inout line; value: out std_ulogic ) is$/;\"\tp\tpackage:io1164\nsuccess\tinput.vhd\t/^        variable success: boolean;  -- internal good flag$/;\"\tv\tprocedure:io1164.read\nread\tinput.vhd\t/^    procedure read(l    : inout line           ; $/;\"\tp\tpackage:io1164\nm\tinput.vhd\t/^        variable m           : line           ; -- saved copy of L$/;\"\tv\tprocedure:io1164.read\nsuccess\tinput.vhd\t/^        variable success     : boolean := true; -- readable GOOD$/;\"\tv\tprocedure:io1164.read\nlogic_value\tinput.vhd\t/^        variable logic_value : std_logic      ; -- value for one array element$/;\"\tv\tprocedure:io1164.read\nc\tinput.vhd\t/^        variable c           : character      ; -- read a character$/;\"\tv\tprocedure:io1164.read\nread\tinput.vhd\t/^    procedure read(l: inout line; value: out std_logic_vector ) is$/;\"\tp\tpackage:io1164\nsuccess\tinput.vhd\t/^        variable success: boolean;$/;\"\tv\tprocedure:io1164.read\nwrite\tinput.vhd\t/^    procedure write(l        : inout line          ;$/;\"\tp\tpackage:io1164\nwrite\tinput.vhd\t/^    procedure write(l        : inout line                   ;$/;\"\tp\tpackage:io1164\nm\tinput.vhd\t/^        variable m: line; -- build up intermediate string$/;\"\tv\tprocedure:io1164.write\nread_oct\tinput.vhd\t/^    procedure read_oct(l         : inout line            ; $/;\"\tp\tpackage:io1164\nm\tinput.vhd\t/^        variable m               : line                      ; -- safe L$/;\"\tv\tprocedure:io1164.read_oct\nsuccess\tinput.vhd\t/^        variable success         : boolean            := true; -- readable GOOD$/;\"\tv\tprocedure:io1164.read_oct\nlogic_value\tinput.vhd\t/^        variable logic_value     : std_logic                 ; -- elem value$/;\"\tv\tprocedure:io1164.read_oct\nc\tinput.vhd\t/^        variable c               : character                 ; -- char read$/;\"\tv\tprocedure:io1164.read_oct\ncharcode\tinput.vhd\t/^        variable charcode        : integer                   ; -- char->int$/;\"\tv\tprocedure:io1164.read_oct\noct_logic_vector\tinput.vhd\t/^        variable oct_logic_vector: oct_logic_vector_t        ; -- for 1 digit$/;\"\tv\tprocedure:io1164.read_oct\nbitpos\tinput.vhd\t/^        variable bitpos          : integer                   ; -- in state vec.$/;\"\tv\tprocedure:io1164.read_oct\nread_oct\tinput.vhd\t/^    procedure read_oct(l         : inout line            ; $/;\"\tp\tpackage:io1164\nsuccess\tinput.vhd\t/^        variable success: boolean;                 -- internal good flag$/;\"\tv\tprocedure:io1164.read_oct\nwrite_oct\tinput.vhd\t/^    procedure write_oct(l        : inout line                   ;$/;\"\tp\tpackage:io1164\nm\tinput.vhd\t/^        variable m            : line     ; -- safe copy of L$/;\"\tv\tprocedure:io1164.write_oct\ngoodlength\tinput.vhd\t/^        variable goodlength   : boolean  ; -- array is ok len for this base$/;\"\tv\tprocedure:io1164.write_oct\nisx\tinput.vhd\t/^        variable isx          : boolean  ; -- an X in this digit$/;\"\tv\tprocedure:io1164.write_oct\ninteger_value\tinput.vhd\t/^        variable integer_value: integer  ; -- accumulate integer value$/;\"\tv\tprocedure:io1164.write_oct\nc\tinput.vhd\t/^        variable c            : character; -- character read$/;\"\tv\tprocedure:io1164.write_oct\ncharpos\tinput.vhd\t/^        variable charpos      : integer  ; -- index string being contructed$/;\"\tv\tprocedure:io1164.write_oct\nbitpos\tinput.vhd\t/^        variable bitpos       : integer  ; -- bit index inside digit$/;\"\tv\tprocedure:io1164.write_oct\nread_hex\tinput.vhd\t/^    procedure read_hex(l         : inout line            ; $/;\"\tp\tpackage:io1164\nm\tinput.vhd\t/^        variable m               : line                      ; -- safe L$/;\"\tv\tprocedure:io1164.read_hex\nsuccess\tinput.vhd\t/^        variable success         : boolean            := true; -- readable GOOD$/;\"\tv\tprocedure:io1164.read_hex\nlogic_value\tinput.vhd\t/^        variable logic_value     : std_logic                 ; -- elem value$/;\"\tv\tprocedure:io1164.read_hex\nc\tinput.vhd\t/^        variable c               : character                 ; -- char read$/;\"\tv\tprocedure:io1164.read_hex\ncharcode\tinput.vhd\t/^        variable charcode        : integer                   ; -- char->int$/;\"\tv\tprocedure:io1164.read_hex\nhex_logic_vector\tinput.vhd\t/^        variable hex_logic_vector: hex_logic_vector_t        ; -- for 1 digit$/;\"\tv\tprocedure:io1164.read_hex\nbitpos\tinput.vhd\t/^        variable bitpos          : integer                   ; -- in state vec.$/;\"\tv\tprocedure:io1164.read_hex\nread_hex\tinput.vhd\t/^    procedure read_hex(l         : inout line            ; $/;\"\tp\tpackage:io1164\nsuccess\tinput.vhd\t/^        variable success: boolean;                 -- internal good flag$/;\"\tv\tprocedure:io1164.read_hex\nwrite_hex\tinput.vhd\t/^    procedure write_hex(l        : inout line                   ;$/;\"\tp\tpackage:io1164\nm\tinput.vhd\t/^        variable m            : line     ; -- safe copy of L$/;\"\tv\tprocedure:io1164.write_hex\ngoodlength\tinput.vhd\t/^        variable goodlength   : boolean  ; -- array is ok len for this base$/;\"\tv\tprocedure:io1164.write_hex\nisx\tinput.vhd\t/^        variable isx          : boolean  ; -- an X in this digit$/;\"\tv\tprocedure:io1164.write_hex\ninteger_value\tinput.vhd\t/^        variable integer_value: integer  ; -- accumulate integer value$/;\"\tv\tprocedure:io1164.write_hex\nc\tinput.vhd\t/^        variable c            : character; -- character read$/;\"\tv\tprocedure:io1164.write_hex\ncharpos\tinput.vhd\t/^        variable charpos      : integer  ; -- index string being contructed$/;\"\tv\tprocedure:io1164.write_hex\nbitpos\tinput.vhd\t/^        variable bitpos       : integer  ; -- bit index inside digit$/;\"\tv\tprocedure:io1164.write_hex\nread_oct\tinput.vhd\t/^    procedure read_oct(l     : inout line;$/;\"\tp\tpackage:io1164\npos\tinput.vhd\t/^        variable pos     : integer;$/;\"\tv\tprocedure:io1164.read_oct\ndigit\tinput.vhd\t/^        variable digit   : integer;$/;\"\tv\tprocedure:io1164.read_oct\nresult\tinput.vhd\t/^        variable result  : integer := 0;$/;\"\tv\tprocedure:io1164.read_oct\nsuccess\tinput.vhd\t/^        variable success : boolean := true;$/;\"\tv\tprocedure:io1164.read_oct\nc\tinput.vhd\t/^        variable c       : character;$/;\"\tv\tprocedure:io1164.read_oct\nold_l\tinput.vhd\t/^        variable old_l   : line := l;$/;\"\tv\tprocedure:io1164.read_oct\nread_oct\tinput.vhd\t/^    procedure read_oct(l     : inout line;$/;\"\tp\tpackage:io1164\nsuccess\tinput.vhd\t/^        variable success: boolean;                 -- internal good flag$/;\"\tv\tprocedure:io1164.read_oct\nread_hex\tinput.vhd\t/^    procedure read_hex(l     : inout line;$/;\"\tp\tpackage:io1164\npos\tinput.vhd\t/^        variable pos     : integer;$/;\"\tv\tprocedure:io1164.read_hex\ndigit\tinput.vhd\t/^        variable digit   : integer;$/;\"\tv\tprocedure:io1164.read_hex\nresult\tinput.vhd\t/^        variable result  : integer := 0;$/;\"\tv\tprocedure:io1164.read_hex\nsuccess\tinput.vhd\t/^        variable success : boolean := true;$/;\"\tv\tprocedure:io1164.read_hex\nc\tinput.vhd\t/^        variable c       : character;$/;\"\tv\tprocedure:io1164.read_hex\nold_l\tinput.vhd\t/^        variable old_l   : line := l;$/;\"\tv\tprocedure:io1164.read_hex\nread_hex\tinput.vhd\t/^    procedure read_hex(l     : inout line;$/;\"\tp\tpackage:io1164\nsuccess\tinput.vhd\t/^        variable success: boolean;                 -- internal good flag$/;\"\tv\tprocedure:io1164.read_hex\nasyncLdCnt\tinput.vhd\t/^entity asyncLdCnt is port ($/;\"\te\nloadVal\tinput.vhd\t/^  loadVal: in std_logic_vector(3 downto 0);$/;\"\tq\tentity:asyncLdCnt\nclk\tinput.vhd\t/^  clk, load: in std_logic;$/;\"\tq\tentity:asyncLdCnt\nload\tinput.vhd\t/^  clk, load: in std_logic;$/;\"\tq\tentity:asyncLdCnt\nq\tinput.vhd\t/^  q: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:asyncLdCnt\nrtl\tinput.vhd\t/^architecture rtl of asyncLdCnt is$/;\"\ta\tentity:asyncLdCnt\nqLocal\tinput.vhd\t/^signal qLocal: unsigned(3 downto 0);$/;\"\ts\tarchitecture:asyncLdCnt.rtl\nanonProcesscfc8de98180f\tinput.vhd\t/^  process (clk, load, loadVal) begin$/;\"\tQ\tarchitecture:asyncLdCnt.rtl\nLoadCnt\tinput.vhd\t/^entity LoadCnt is port ($/;\"\te\nCntEn\tinput.vhd\t/^  CntEn: in std_logic;$/;\"\tq\tentity:LoadCnt\nLdCnt\tinput.vhd\t/^  LdCnt: in std_logic;$/;\"\tq\tentity:LoadCnt\nLdData\tinput.vhd\t/^  LdData: in std_logic_vector(3 downto 0);$/;\"\tq\tentity:LoadCnt\nClk\tinput.vhd\t/^  Clk: in std_logic;$/;\"\tq\tentity:LoadCnt\nRst\tinput.vhd\t/^  Rst: in std_logic;$/;\"\tq\tentity:LoadCnt\nCntVal\tinput.vhd\t/^  CntVal: out std_logic_vector(3 downto 0)$/;\"\tq\tentity:LoadCnt\nbehavioral\tinput.vhd\t/^architecture behavioral of LoadCnt is$/;\"\ta\tentity:LoadCnt\nCnt\tinput.vhd\t/^signal Cnt: std_logic_vector(3 downto 0);$/;\"\ts\tarchitecture:LoadCnt.behavioral\ncounter\tinput.vhd\t/^  counter: process (Clk, Rst) begin$/;\"\tQ\tarchitecture:LoadCnt.behavioral\nloadCntTB\tinput.vhd\t/^entity loadCntTB is$/;\"\te\ntestbench\tinput.vhd\t/^architecture testbench of loadCntTB is$/;\"\ta\tentity:loadCntTB\nloadCnt\tinput.vhd\t/^  component loadCnt port ($/;\"\tC\tarchitecture:loadCntTB.testbench\ndata\tinput.vhd\t/^    data: in std_logic_vector (7 downto 0);$/;\"\tq\tcomponent:loadCntTB.testbench.loadCnt\nload\tinput.vhd\t/^    load: in std_logic;$/;\"\tq\tcomponent:loadCntTB.testbench.loadCnt\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tcomponent:loadCntTB.testbench.loadCnt\nrst\tinput.vhd\t/^    rst: in std_logic;$/;\"\tq\tcomponent:loadCntTB.testbench.loadCnt\nq\tinput.vhd\t/^    q: out std_logic_vector (7 downto 0)$/;\"\tq\tcomponent:loadCntTB.testbench.loadCnt\nvectorType\tinput.vhd\t/^type vectorType is record$/;\"\tt\tarchitecture:loadCntTB.testbench\ndata\tinput.vhd\t/^  data: std_logic_vector(7 downto 0);$/;\"\tr\ttype:loadCntTB.testbench.vectorType\nload\tinput.vhd\t/^  load: std_logic;$/;\"\tr\ttype:loadCntTB.testbench.vectorType\nrst\tinput.vhd\t/^  rst: std_logic;$/;\"\tr\ttype:loadCntTB.testbench.vectorType\nq\tinput.vhd\t/^  q: std_logic_vector(7 downto 0);$/;\"\tr\ttype:loadCntTB.testbench.vectorType\ntestVector\tinput.vhd\t/^signal testVector: vectorType;$/;\"\ts\tarchitecture:loadCntTB.testbench\nTestClk\tinput.vhd\t/^signal TestClk: std_logic := '0';$/;\"\ts\tarchitecture:loadCntTB.testbench\nQout\tinput.vhd\t/^signal Qout: std_logic_vector(7 downto 0);$/;\"\ts\tarchitecture:loadCntTB.testbench\nClkPeriod\tinput.vhd\t/^constant ClkPeriod: time := 100 ns;$/;\"\tc\tarchitecture:loadCntTB.testbench\nreadVec\tinput.vhd\t/^  readVec: process$/;\"\tQ\tarchitecture:loadCntTB.testbench\nVectorLine\tinput.vhd\t/^    variable VectorLine: line;$/;\"\tv\tprocess:loadCntTB.testbench.readVec\nVectorValid\tinput.vhd\t/^    variable VectorValid: boolean;$/;\"\tv\tprocess:loadCntTB.testbench.readVec\nvRst\tinput.vhd\t/^    variable vRst: std_logic;$/;\"\tv\tprocess:loadCntTB.testbench.readVec\nvLoad\tinput.vhd\t/^    variable vLoad: std_logic;$/;\"\tv\tprocess:loadCntTB.testbench.readVec\nvData\tinput.vhd\t/^    variable vData: std_logic_vector(7 downto 0);$/;\"\tv\tprocess:loadCntTB.testbench.readVec\nvQ\tinput.vhd\t/^    variable vQ: std_logic_vector(7 downto 0);$/;\"\tv\tprocess:loadCntTB.testbench.readVec\nverify\tinput.vhd\t/^  verify: process (TestClk)$/;\"\tQ\tarchitecture:loadCntTB.testbench\nErrorMsg\tinput.vhd\t/^  variable ErrorMsg: line;$/;\"\tv\tprocess:loadCntTB.testbench.verify\nloadCnt\tinput.vhd\t/^entity loadCnt is port ($/;\"\te\ndata\tinput.vhd\t/^  data: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:loadCnt\nload\tinput.vhd\t/^  load: in std_logic;$/;\"\tq\tentity:loadCnt\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:loadCnt\nrst\tinput.vhd\t/^  rst: in std_logic;$/;\"\tq\tentity:loadCnt\nq\tinput.vhd\t/^  q: out std_logic_vector (7 downto 0)$/;\"\tq\tentity:loadCnt\nrtl\tinput.vhd\t/^architecture rtl of loadCnt is$/;\"\ta\tentity:loadCnt\ncnt\tinput.vhd\t/^signal cnt: std_logic_vector (7 downto 0);$/;\"\ts\tarchitecture:loadCnt.rtl\ncounter\tinput.vhd\t/^  counter: process (clk, rst) begin$/;\"\tQ\tarchitecture:loadCnt.rtl\nmultiplier\tinput.vhd\t/^entity multiplier is port ($/;\"\te\na\tinput.vhd\t/^  a,b : in std_logic_vector (15 downto 0);$/;\"\tq\tentity:multiplier\nb\tinput.vhd\t/^  a,b : in std_logic_vector (15 downto 0);$/;\"\tq\tentity:multiplier\nproduct\tinput.vhd\t/^  product: out std_logic_vector (31 downto 0)$/;\"\tq\tentity:multiplier\ndataflow\tinput.vhd\t/^architecture dataflow of multiplier is$/;\"\ta\tentity:multiplier\nmux\tinput.vhd\t/^entity mux is port ($/;\"\te\nA\tinput.vhd\t/^  A, B, Sel: in std_logic;$/;\"\tq\tentity:mux\nB\tinput.vhd\t/^  A, B, Sel: in std_logic;$/;\"\tq\tentity:mux\nSel\tinput.vhd\t/^  A, B, Sel: in std_logic;$/;\"\tq\tentity:mux\nY\tinput.vhd\t/^  Y: out std_logic$/;\"\tq\tentity:mux\nsimModel\tinput.vhd\t/^architecture simModel of mux is$/;\"\ta\tentity:mux\ntPD_A\tinput.vhd\t/^constant tPD_A:   time := 10 ns;$/;\"\tc\tarchitecture:mux.simModel\ntPD_B\tinput.vhd\t/^constant tPD_B:   time := 15 ns;$/;\"\tc\tarchitecture:mux.simModel\ntPD_Sel\tinput.vhd\t/^constant tPD_Sel: time := 5 ns;$/;\"\tc\tarchitecture:mux.simModel\nDelayMux\tinput.vhd\t/^  DelayMux: process (A, B, Sel)$/;\"\tQ\tarchitecture:mux.simModel\nlocalY\tinput.vhd\t/^  variable localY: std_logic; -- Zero delay place holder for Y$/;\"\tv\tprocess:mux.simModel.DelayMux\nForceShare\tinput.vhd\t/^entity ForceShare is port ($/;\"\te\na\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\nb\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\nc\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\nd\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\ne\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\nf\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\nresult\tinput.vhd\t/^  result: out std_logic_vector(7 downto 0)$/;\"\tq\tentity:ForceShare\nbehaviour\tinput.vhd\t/^architecture behaviour of ForceShare is$/;\"\ta\tentity:ForceShare\nsum\tinput.vhd\t/^  sum: process (a,c,b,d,e,f)$/;\"\tQ\tarchitecture:ForceShare.behaviour\nTRIBUF8\tinput.vhd\t/^entity TRIBUF8 is port ($/;\"\te\nip\tinput.vhd\t/^  ip: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:TRIBUF8\noe\tinput.vhd\t/^  oe: in std_logic;$/;\"\tq\tentity:TRIBUF8\nop\tinput.vhd\t/^  op: out std_logic_vector(7 downto 0)$/;\"\tq\tentity:TRIBUF8\nconcurrent\tinput.vhd\t/^architecture concurrent of TRIBUF8 is$/;\"\ta\tentity:TRIBUF8\nTRIBUF\tinput.vhd\t/^entity TRIBUF is port ($/;\"\te\nip\tinput.vhd\t/^  ip: in std_logic;$/;\"\tq\tentity:TRIBUF\noe\tinput.vhd\t/^  oe: in std_logic;$/;\"\tq\tentity:TRIBUF\nop\tinput.vhd\t/^  op: out std_logic$/;\"\tq\tentity:TRIBUF\nconcurrent\tinput.vhd\t/^architecture concurrent of TRIBUF is$/;\"\ta\tentity:TRIBUF\nTRIBUF8\tinput.vhd\t/^entity TRIBUF8 is port ($/;\"\te\nip\tinput.vhd\t/^  ip: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:TRIBUF8\noe\tinput.vhd\t/^  oe: in std_logic;$/;\"\tq\tentity:TRIBUF8\nop\tinput.vhd\t/^  op: out std_logic_vector(7 downto 0)$/;\"\tq\tentity:TRIBUF8\nsequential\tinput.vhd\t/^architecture sequential of TRIBUF8 is$/;\"\ta\tentity:TRIBUF8\nenable\tinput.vhd\t/^  enable: process (ip,oe) begin$/;\"\tQ\tarchitecture:TRIBUF8.sequential\nTRIBUF\tinput.vhd\t/^entity TRIBUF is port ($/;\"\te\nip\tinput.vhd\t/^  ip: in bit;$/;\"\tq\tentity:TRIBUF\noe\tinput.vhd\t/^  oe: in bit;$/;\"\tq\tentity:TRIBUF\nop\tinput.vhd\t/^  op: out bit$/;\"\tq\tentity:TRIBUF\nsequential\tinput.vhd\t/^architecture sequential of TRIBUF is$/;\"\ta\tentity:TRIBUF\nenable\tinput.vhd\t/^  enable: process (ip,oe) begin$/;\"\tQ\tarchitecture:TRIBUF.sequential\nTRIBUF\tinput.vhd\t/^entity TRIBUF is port ($/;\"\te\nip\tinput.vhd\t/^  ip: in std_logic;$/;\"\tq\tentity:TRIBUF\noe\tinput.vhd\t/^  oe: in std_logic;$/;\"\tq\tentity:TRIBUF\nop\tinput.vhd\t/^  op: out std_logic$/;\"\tq\tentity:TRIBUF\nsequential\tinput.vhd\t/^architecture sequential of TRIBUF is$/;\"\ta\tentity:TRIBUF\nenable\tinput.vhd\t/^  enable: process (ip,oe) begin$/;\"\tQ\tarchitecture:TRIBUF.sequential\ntribuffer\tinput.vhd\t/^entity tribuffer is port ($/;\"\te\ninput\tinput.vhd\t/^  input: in std_logic;$/;\"\tq\tentity:tribuffer\nenable\tinput.vhd\t/^  enable: in std_logic;$/;\"\tq\tentity:tribuffer\noutput\tinput.vhd\t/^  output: out std_logic$/;\"\tq\tentity:tribuffer\nstructural\tinput.vhd\t/^architecture structural of tribuffer is$/;\"\ta\tentity:tribuffer\noddParityGen\tinput.vhd\t/^entity oddParityGen is$/;\"\te\nwidth\tinput.vhd\t/^  generic ( width : integer := 8 );$/;\"\tg\tentity:oddParityGen\nad\tinput.vhd\t/^  port (ad: in std_logic_vector (width - 1 downto 0);$/;\"\tq\tentity:oddParityGen\noddParity\tinput.vhd\t/^        oddParity : out std_logic ) ;$/;\"\tq\tentity:oddParityGen\nscaleable\tinput.vhd\t/^architecture scaleable of oddParityGen is$/;\"\ta\tentity:oddParityGen\ngenXor\tinput.vhd\t/^signal genXor: std_logic_vector(ad'range);$/;\"\ts\tarchitecture:oddParityGen.scaleable\noddParityLoop\tinput.vhd\t/^entity oddParityLoop is$/;\"\te\nwidth\tinput.vhd\t/^  generic ( width : integer := 8 );$/;\"\tg\tentity:oddParityLoop\nad\tinput.vhd\t/^  port (ad: in std_logic_vector (width - 1 downto 0);$/;\"\tq\tentity:oddParityLoop\noddParity\tinput.vhd\t/^        oddParity : out std_logic ) ;$/;\"\tq\tentity:oddParityLoop\nscaleable\tinput.vhd\t/^architecture scaleable of oddParityLoop is$/;\"\ta\tentity:oddParityLoop\nanonProcesscfc8de98190f\tinput.vhd\t/^  process (ad) $/;\"\tQ\tarchitecture:oddParityLoop.scaleable\nloopXor\tinput.vhd\t/^    variable loopXor: std_logic;$/;\"\tv\tprocess:oddParityLoop.scaleable.anonProcesscfc8de98190f\nOR2\tinput.vhd\t/^entity OR2 is port ($/;\"\te\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tentity:OR2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tentity:OR2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tentity:OR2\nrtl\tinput.vhd\t/^architecture rtl of OR2 is$/;\"\ta\tentity:OR2\nOR2\tinput.vhd\t/^entity OR2 is port ($/;\"\te\nI1\tinput.vhd\t/^  I1, I2: in std_logic;$/;\"\tq\tentity:OR2\nI2\tinput.vhd\t/^  I1, I2: in std_logic;$/;\"\tq\tentity:OR2\nY\tinput.vhd\t/^  Y: out std_logic$/;\"\tq\tentity:OR2\nsimple\tinput.vhd\t/^architecture simple of OR2 is$/;\"\ta\tentity:OR2\nsimPrimitives\tinput.vhd\t/^package simPrimitives is$/;\"\tP\nOR2\tinput.vhd\t/^  component OR2$/;\"\tC\tpackage:simPrimitives\ntPD\tinput.vhd\t/^    generic (tPD: time := 1 ns);$/;\"\tg\tcomponent:simPrimitives.OR2\nI1\tinput.vhd\t/^    port (I1, I2: in std_logic;$/;\"\tq\tcomponent:simPrimitives.OR2\nI2\tinput.vhd\t/^    port (I1, I2: in std_logic;$/;\"\tq\tcomponent:simPrimitives.OR2\nY\tinput.vhd\t/^      Y: out std_logic$/;\"\tq\tcomponent:simPrimitives.OR2\nOR2\tinput.vhd\t/^entity OR2 is$/;\"\te\ntPD\tinput.vhd\t/^  generic (tPD: time := 1 ns);$/;\"\tg\tentity:OR2\nI1\tinput.vhd\t/^  port (I1, I2: in std_logic;$/;\"\tq\tentity:OR2\nI2\tinput.vhd\t/^  port (I1, I2: in std_logic;$/;\"\tq\tentity:OR2\nY\tinput.vhd\t/^    Y: out std_logic$/;\"\tq\tentity:OR2\nsimple\tinput.vhd\t/^architecture simple of OR2 is$/;\"\ta\tentity:OR2\nadder\tinput.vhd\t/^entity adder is port ($/;\"\te\na\tinput.vhd\t/^  a,b: in std_logic_vector(3 downto 0);$/;\"\tq\tentity:adder\nb\tinput.vhd\t/^  a,b: in std_logic_vector(3 downto 0);$/;\"\tq\tentity:adder\nsum\tinput.vhd\t/^  sum: out std_logic_vector(3 downto 0);$/;\"\tq\tentity:adder\noverflow\tinput.vhd\t/^  overflow: out std_logic$/;\"\tq\tentity:adder\nconcat\tinput.vhd\t/^architecture concat of adder is$/;\"\ta\tentity:adder\nlocalSum\tinput.vhd\t/^signal localSum: std_logic_vector(4 downto 0);$/;\"\ts\tarchitecture:adder.concat\nparamDFF\tinput.vhd\t/^entity paramDFF is$/;\"\te\nsize\tinput.vhd\t/^  generic (size: integer := 8);$/;\"\tg\tentity:paramDFF\ndata\tinput.vhd\t/^  data: in std_logic_vector(size - 1 downto 0);$/;\"\tq\tentity:paramDFF\nclock\tinput.vhd\t/^  clock: in std_logic;$/;\"\tq\tentity:paramDFF\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:paramDFF\nff_enable\tinput.vhd\t/^  ff_enable: in std_logic;$/;\"\tq\tentity:paramDFF\nop_enable\tinput.vhd\t/^  op_enable: in std_logic;$/;\"\tq\tentity:paramDFF\nqout\tinput.vhd\t/^  qout: out std_logic_vector(size - 1 downto 0)$/;\"\tq\tentity:paramDFF\nparameterize\tinput.vhd\t/^architecture parameterize of paramDFF is$/;\"\ta\tentity:paramDFF\nreg\tinput.vhd\t/^signal reg: std_logic_vector(size - 1 downto 0);$/;\"\ts\tarchitecture:paramDFF.parameterize\noddParityGen\tinput.vhd\t/^entity oddParityGen is$/;\"\te\nwidth\tinput.vhd\t/^  generic ( width : integer := 32 );$/;\"\tg\tentity:oddParityGen\nad\tinput.vhd\t/^  port (ad: in std_logic_vector (width - 1 downto 0);$/;\"\tq\tentity:oddParityGen\noddParity\tinput.vhd\t/^        oddParity : out std_logic ) ;$/;\"\tq\tentity:oddParityGen\nscaleable\tinput.vhd\t/^architecture scaleable of oddParityGen is$/;\"\ta\tentity:oddParityGen\ngenXor\tinput.vhd\t/^signal genXor: std_logic_vector(ad'range);$/;\"\ts\tarchitecture:oddParityGen.scaleable\none\tinput.vhd\t/^signal one: std_logic := '1';$/;\"\ts\tarchitecture:oddParityGen.scaleable\noddParityGen\tinput.vhd\t/^entity oddParityGen is$/;\"\te\nwidth\tinput.vhd\t/^  generic ( width : integer := 32 ); -- (2 <= width <= 32) and a power of 2$/;\"\tg\tentity:oddParityGen\nad\tinput.vhd\t/^  port (ad: in std_logic_vector (width - 1 downto 0);$/;\"\tq\tentity:oddParityGen\noddParity\tinput.vhd\t/^        oddParity : out std_logic ) ;$/;\"\tq\tentity:oddParityGen\nscaleable\tinput.vhd\t/^architecture scaleable of oddParityGen is$/;\"\ta\tentity:oddParityGen\nstage0\tinput.vhd\t/^signal stage0: std_logic_vector(31 downto 0);$/;\"\ts\tarchitecture:oddParityGen.scaleable\nstage1\tinput.vhd\t/^signal stage1: std_logic_vector(15 downto 0);$/;\"\ts\tarchitecture:oddParityGen.scaleable\nstage2\tinput.vhd\t/^signal stage2: std_logic_vector(7 downto 0);$/;\"\ts\tarchitecture:oddParityGen.scaleable\nstage3\tinput.vhd\t/^signal stage3: std_logic_vector(3 downto 0);$/;\"\ts\tarchitecture:oddParityGen.scaleable\nstage4\tinput.vhd\t/^signal stage4: std_logic_vector(1 downto 0);$/;\"\ts\tarchitecture:oddParityGen.scaleable\npowerOfFour\tinput.vhd\t/^entity powerOfFour is port($/;\"\te\nclk\tinput.vhd\t/^  clk      : in  std_logic; $/;\"\tq\tentity:powerOfFour\ninputVal\tinput.vhd\t/^  inputVal : in  unsigned(3 downto 0);$/;\"\tq\tentity:powerOfFour\npower\tinput.vhd\t/^  power    : out unsigned(15 downto 0)$/;\"\tq\tentity:powerOfFour\nbehavioral\tinput.vhd\t/^architecture behavioral of powerOfFour is$/;\"\ta\tentity:powerOfFour\nPow\tinput.vhd\t/^   function Pow( N, Exp : integer )  return integer is$/;\"\tf\tarchitecture:powerOfFour.behavioral\nResult\tinput.vhd\t/^      Variable Result   : integer := 1;$/;\"\tv\tfunction:powerOfFour.behavioral.Pow\ninputValInt\tinput.vhd\t/^signal inputValInt: integer range 0 to 15;$/;\"\ts\tarchitecture:powerOfFour.behavioral\npowerL\tinput.vhd\t/^signal powerL: integer range 0 to 65535;$/;\"\ts\tarchitecture:powerOfFour.behavioral\nanonProcesscfc8de981a0f\tinput.vhd\t/^   process begin$/;\"\tQ\tarchitecture:powerOfFour.behavioral\nPowerPkg\tinput.vhd\t/^package PowerPkg is  $/;\"\tP\nPower\tinput.vhd\t/^  component Power port($/;\"\tC\tpackage:PowerPkg\nClk\tinput.vhd\t/^      Clk                   : in  bit; $/;\"\tq\tcomponent:PowerPkg.Power\ninputVal\tinput.vhd\t/^      inputVal              : in  bit_vector(0 to 3);$/;\"\tq\tcomponent:PowerPkg.Power\npower\tinput.vhd\t/^      power                 : out bit_vector(0 to 15) );$/;\"\tq\tcomponent:PowerPkg.Power\nPower\tinput.vhd\t/^entity Power is port($/;\"\te\nClk\tinput.vhd\t/^   Clk                   : in  bit; $/;\"\tq\tentity:Power\ninputVal\tinput.vhd\t/^   inputVal              : in  bit_vector(0 to 3);$/;\"\tq\tentity:Power\npower\tinput.vhd\t/^   power                 : out bit_vector(0 to 15) );$/;\"\tq\tentity:Power\nfunky\tinput.vhd\t/^architecture funky of Power is$/;\"\ta\tentity:Power\nPow\tinput.vhd\t/^   function Pow( N, Exp : integer )  return integer is$/;\"\tf\tarchitecture:Power.funky\nResult\tinput.vhd\t/^      Variable Result   : integer := 1;$/;\"\tv\tfunction:Power.funky.Pow\ni\tinput.vhd\t/^      Variable i        : integer := 0;$/;\"\tv\tfunction:Power.funky.Pow\nRollVal\tinput.vhd\t/^   function RollVal(  CntlVal : integer )  return integer is$/;\"\tf\tarchitecture:Power.funky\nanonProcesscfc8de981b0f\tinput.vhd\t/^   process $/;\"\tQ\tarchitecture:Power.funky\npriority_encoder\tinput.vhd\t/^entity priority_encoder is port$/;\"\te\ninterrupts\tinput.vhd\t/^  (interrupts : in  std_logic_vector(7 downto 0);$/;\"\tq\tentity:priority_encoder\npriority\tinput.vhd\t/^   priority   : in  std_logic_vector(2 downto 0);$/;\"\tq\tentity:priority_encoder\nresult\tinput.vhd\t/^   result     : out std_logic_vector(2 downto 0)$/;\"\tq\tentity:priority_encoder\nbehave\tinput.vhd\t/^architecture behave of priority_encoder is$/;\"\ta\tentity:priority_encoder\nanonProcesscfc8de981c0f\tinput.vhd\t/^  process (interrupts)$/;\"\tQ\tarchitecture:priority_encoder.behave\nselectIn\tinput.vhd\t/^     variable selectIn  : integer;$/;\"\tv\tprocess:priority_encoder.behave.anonProcesscfc8de981c0f\nLoopCount\tinput.vhd\t/^     variable LoopCount : integer;$/;\"\tv\tprocess:priority_encoder.behave.anonProcesscfc8de981c0f\nprimitive\tinput.vhd\t/^package primitive is$/;\"\tP\nDFFE\tinput.vhd\t/^  component DFFE port ($/;\"\tC\tpackage:primitive\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tcomponent:primitive.DFFE\nq\tinput.vhd\t/^    q: out std_logic;$/;\"\tq\tcomponent:primitive.DFFE\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tcomponent:primitive.DFFE\nclk\tinput.vhd\t/^    clk: in std_logic$/;\"\tq\tcomponent:primitive.DFFE\nDFFE_SR\tinput.vhd\t/^  component DFFE_SR port ($/;\"\tC\tpackage:primitive\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tcomponent:primitive.DFFE_SR\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tcomponent:primitive.DFFE_SR\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tcomponent:primitive.DFFE_SR\nrst\tinput.vhd\t/^    rst: in std_logic;$/;\"\tq\tcomponent:primitive.DFFE_SR\nprst\tinput.vhd\t/^    prst: in std_logic;$/;\"\tq\tcomponent:primitive.DFFE_SR\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tcomponent:primitive.DFFE_SR\nDLATCHH\tinput.vhd\t/^  component DLATCHH port ($/;\"\tC\tpackage:primitive\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tcomponent:primitive.DLATCHH\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tcomponent:primitive.DLATCHH\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tcomponent:primitive.DLATCHH\nAND2\tinput.vhd\t/^  component AND2 port ($/;\"\tC\tpackage:primitive\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tcomponent:primitive.AND2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tcomponent:primitive.AND2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tcomponent:primitive.AND2\nOR2\tinput.vhd\t/^  component OR2 port ($/;\"\tC\tpackage:primitive\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tcomponent:primitive.OR2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tcomponent:primitive.OR2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tcomponent:primitive.OR2\nINVERTER\tinput.vhd\t/^  component INVERTER port ($/;\"\tC\tpackage:primitive\ni\tinput.vhd\t/^    i: in std_logic;$/;\"\tq\tcomponent:primitive.INVERTER\no\tinput.vhd\t/^    o: out std_logic$/;\"\tq\tcomponent:primitive.INVERTER\nTRIBUF\tinput.vhd\t/^  component TRIBUF port ($/;\"\tC\tpackage:primitive\nip\tinput.vhd\t/^    ip: in std_logic;$/;\"\tq\tcomponent:primitive.TRIBUF\noe\tinput.vhd\t/^    oe: in std_logic;$/;\"\tq\tcomponent:primitive.TRIBUF\nop\tinput.vhd\t/^    op: out std_logic$/;\"\tq\tcomponent:primitive.TRIBUF\nBIDIR\tinput.vhd\t/^  component BIDIR port ($/;\"\tC\tpackage:primitive\nip\tinput.vhd\t/^    ip: in std_logic;$/;\"\tq\tcomponent:primitive.BIDIR\noe\tinput.vhd\t/^    oe: in std_logic;$/;\"\tq\tcomponent:primitive.BIDIR\nop_fb\tinput.vhd\t/^    op_fb: out std_logic;$/;\"\tq\tcomponent:primitive.BIDIR\nop\tinput.vhd\t/^    op: inout std_logic$/;\"\tq\tcomponent:primitive.BIDIR\nDFFE\tinput.vhd\t/^entity DFFE is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFFE\nq\tinput.vhd\t/^    q: out std_logic;$/;\"\tq\tentity:DFFE\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DFFE\nclk\tinput.vhd\t/^    clk: in std_logic$/;\"\tq\tentity:DFFE\nrtl\tinput.vhd\t/^architecture rtl of DFFE is$/;\"\ta\tentity:DFFE\nanonProcesscfc8de981d0f\tinput.vhd\t/^  process begin$/;\"\tQ\tarchitecture:DFFE.rtl\nDFFE_SR\tinput.vhd\t/^entity DFFE_SR is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DFFE_SR\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DFFE_SR\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFFE_SR\nrst\tinput.vhd\t/^    rst: in std_logic;$/;\"\tq\tentity:DFFE_SR\nprst\tinput.vhd\t/^    prst: in std_logic;$/;\"\tq\tentity:DFFE_SR\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DFFE_SR\nrtl\tinput.vhd\t/^architecture rtl of DFFE_SR is$/;\"\ta\tentity:DFFE_SR\nanonProcesscfc8de981e0f\tinput.vhd\t/^  process (clk, rst, prst) begin$/;\"\tQ\tarchitecture:DFFE_SR.rtl\nDLATCHH\tinput.vhd\t/^entity DLATCHH is port ($/;\"\te\nd\tinput.vhd\t/^    d: in std_logic;$/;\"\tq\tentity:DLATCHH\nen\tinput.vhd\t/^    en: in std_logic;$/;\"\tq\tentity:DLATCHH\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:DLATCHH\nrtl\tinput.vhd\t/^architecture rtl of DLATCHH is$/;\"\ta\tentity:DLATCHH\nanonProcesscfc8de981f0f\tinput.vhd\t/^  process (en) begin$/;\"\tQ\tarchitecture:DLATCHH.rtl\nAND2\tinput.vhd\t/^entity AND2 is port ($/;\"\te\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tentity:AND2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tentity:AND2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tentity:AND2\nrtl\tinput.vhd\t/^architecture rtl of AND2 is$/;\"\ta\tentity:AND2\nOR2\tinput.vhd\t/^entity OR2 is port ($/;\"\te\ni1\tinput.vhd\t/^    i1: in std_logic;$/;\"\tq\tentity:OR2\ni2\tinput.vhd\t/^    i2: in std_logic;$/;\"\tq\tentity:OR2\ny\tinput.vhd\t/^    y: out std_logic$/;\"\tq\tentity:OR2\nrtl\tinput.vhd\t/^architecture rtl of OR2 is$/;\"\ta\tentity:OR2\nINVERTER\tinput.vhd\t/^entity INVERTER is port ($/;\"\te\ni\tinput.vhd\t/^    i: in std_logic;$/;\"\tq\tentity:INVERTER\no\tinput.vhd\t/^    o: out std_logic$/;\"\tq\tentity:INVERTER\nrtl\tinput.vhd\t/^architecture rtl of INVERTER is$/;\"\ta\tentity:INVERTER\nTRIBUF\tinput.vhd\t/^entity TRIBUF is port ($/;\"\te\nip\tinput.vhd\t/^  ip: in std_logic;$/;\"\tq\tentity:TRIBUF\noe\tinput.vhd\t/^  oe: in std_logic;$/;\"\tq\tentity:TRIBUF\nop\tinput.vhd\t/^  op: out std_logic$/;\"\tq\tentity:TRIBUF\nrtl\tinput.vhd\t/^architecture rtl of TRIBUF is$/;\"\ta\tentity:TRIBUF\nBIDIR\tinput.vhd\t/^entity BIDIR is port ($/;\"\te\nip\tinput.vhd\t/^  ip: in std_logic;$/;\"\tq\tentity:BIDIR\noe\tinput.vhd\t/^  oe: in std_logic;$/;\"\tq\tentity:BIDIR\nop_fb\tinput.vhd\t/^  op_fb: out std_logic;$/;\"\tq\tentity:BIDIR\nop\tinput.vhd\t/^  op: inout std_logic$/;\"\tq\tentity:BIDIR\nrtl\tinput.vhd\t/^architecture rtl of BIDIR is$/;\"\ta\tentity:BIDIR\nprogPulse\tinput.vhd\t/^entity progPulse is port ($/;\"\te\nclk\tinput.vhd\t/^  clk, reset: in std_logic;$/;\"\tq\tentity:progPulse\nreset\tinput.vhd\t/^  clk, reset: in std_logic;$/;\"\tq\tentity:progPulse\nloadLength\tinput.vhd\t/^  loadLength,loadDelay: in std_logic;$/;\"\tq\tentity:progPulse\nloadDelay\tinput.vhd\t/^  loadLength,loadDelay: in std_logic;$/;\"\tq\tentity:progPulse\ndata\tinput.vhd\t/^  data: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulse\npulse\tinput.vhd\t/^  pulse: out std_logic$/;\"\tq\tentity:progPulse\nrtl\tinput.vhd\t/^architecture rtl of progPulse is$/;\"\ta\tentity:progPulse\ndownCnt\tinput.vhd\t/^signal downCnt, downCntData: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\ndownCntData\tinput.vhd\t/^signal downCnt, downCntData: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\ndownCntLd\tinput.vhd\t/^signal downCntLd, downCntEn: std_logic;$/;\"\ts\tarchitecture:progPulse.rtl\ndownCntEn\tinput.vhd\t/^signal downCntLd, downCntEn: std_logic;$/;\"\ts\tarchitecture:progPulse.rtl\ndelayCntVal\tinput.vhd\t/^signal delayCntVal, pulseCntVal: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\npulseCntVal\tinput.vhd\t/^signal delayCntVal, pulseCntVal: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\nstartPulse\tinput.vhd\t/^signal startPulse, endPulse: std_logic;$/;\"\ts\tarchitecture:progPulse.rtl\nendPulse\tinput.vhd\t/^signal startPulse, endPulse: std_logic;$/;\"\ts\tarchitecture:progPulse.rtl\nfsmType\tinput.vhd\t/^subtype fsmType is std_logic_vector(1 downto 0);$/;\"\tT\tarchitecture:progPulse.rtl\nloadDelayCnt\tinput.vhd\t/^constant loadDelayCnt  : fsmType := \"00\";$/;\"\tc\tarchitecture:progPulse.rtl\nwaitDelayEnd\tinput.vhd\t/^constant waitDelayEnd  : fsmType := \"10\";$/;\"\tc\tarchitecture:progPulse.rtl\nloadLengthCnt\tinput.vhd\t/^constant loadLengthCnt : fsmType := \"11\";$/;\"\tc\tarchitecture:progPulse.rtl\nwaitLengthEnd\tinput.vhd\t/^constant waitLengthEnd : fsmType := \"01\";$/;\"\tc\tarchitecture:progPulse.rtl\ncurrState\tinput.vhd\t/^signal currState, nextState: fsmType;$/;\"\ts\tarchitecture:progPulse.rtl\nnextState\tinput.vhd\t/^signal currState, nextState: fsmType;$/;\"\ts\tarchitecture:progPulse.rtl\ndelayreg\tinput.vhd\t/^  delayreg: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\nlengthReg\tinput.vhd\t/^  lengthReg: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\nnextStProc\tinput.vhd\t/^  nextStProc: process (currState, downCnt, loadDelay, loadLength) begin$/;\"\tQ\tarchitecture:progPulse.rtl\ncurrStProc\tinput.vhd\t/^  currStProc: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\noutConProc\tinput.vhd\t/^  outConProc: process (currState, delayCntVal, pulseCntVal) begin$/;\"\tQ\tarchitecture:progPulse.rtl\ndownCntr\tinput.vhd\t/^  downCntr: process (clk,reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\npulseErr\tinput.vhd\t/^entity pulseErr is port$/;\"\te\na\tinput.vhd\t/^  (a: in std_logic;$/;\"\tq\tentity:pulseErr\nb\tinput.vhd\t/^   b: out std_logic$/;\"\tq\tentity:pulseErr\nbehavior\tinput.vhd\t/^architecture behavior of pulseErr is$/;\"\ta\tentity:pulseErr\nc\tinput.vhd\t/^signal c: std_logic;$/;\"\ts\tarchitecture:pulseErr.behavior\npulse\tinput.vhd\t/^  pulse: process (a,c) begin$/;\"\tQ\tarchitecture:pulseErr.behavior\nprogPulse\tinput.vhd\t/^entity progPulse is port ($/;\"\te\nclk\tinput.vhd\t/^  clk, reset: in std_logic;$/;\"\tq\tentity:progPulse\nreset\tinput.vhd\t/^  clk, reset: in std_logic;$/;\"\tq\tentity:progPulse\nloadLength\tinput.vhd\t/^  loadLength,loadDelay: in std_logic;$/;\"\tq\tentity:progPulse\nloadDelay\tinput.vhd\t/^  loadLength,loadDelay: in std_logic;$/;\"\tq\tentity:progPulse\ndata\tinput.vhd\t/^  data: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulse\npulse\tinput.vhd\t/^  pulse: out std_logic$/;\"\tq\tentity:progPulse\nrtl\tinput.vhd\t/^architecture rtl of progPulse is$/;\"\ta\tentity:progPulse\ndownCnt\tinput.vhd\t/^signal downCnt, downCntData: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\ndownCntData\tinput.vhd\t/^signal downCnt, downCntData: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\ndownCntLd\tinput.vhd\t/^signal downCntLd, downCntEn: std_logic;$/;\"\ts\tarchitecture:progPulse.rtl\ndownCntEn\tinput.vhd\t/^signal downCntLd, downCntEn: std_logic;$/;\"\ts\tarchitecture:progPulse.rtl\ndelayCntVal\tinput.vhd\t/^signal delayCntVal, pulseCntVal: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\npulseCntVal\tinput.vhd\t/^signal delayCntVal, pulseCntVal: unsigned(7 downto 0);$/;\"\ts\tarchitecture:progPulse.rtl\nstartPulse\tinput.vhd\t/^signal startPulse, endPulse: std_logic;$/;\"\ts\tarchitecture:progPulse.rtl\nendPulse\tinput.vhd\t/^signal startPulse, endPulse: std_logic;$/;\"\ts\tarchitecture:progPulse.rtl\nprogPulseFsmType\tinput.vhd\t/^type progPulseFsmType is (loadDelayCnt, waitDelayEnd, loadLengthCnt, waitLengthEnd);$/;\"\tt\tarchitecture:progPulse.rtl\ncurrState\tinput.vhd\t/^signal currState, nextState: progPulseFsmType;$/;\"\ts\tarchitecture:progPulse.rtl\nnextState\tinput.vhd\t/^signal currState, nextState: progPulseFsmType;$/;\"\ts\tarchitecture:progPulse.rtl\ndelayreg\tinput.vhd\t/^  delayreg: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\nlengthReg\tinput.vhd\t/^  lengthReg: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\nnextStProc\tinput.vhd\t/^  nextStProc: process (currState, downCnt, loadDelay, loadLength) begin$/;\"\tQ\tarchitecture:progPulse.rtl\ncurrStProc\tinput.vhd\t/^  currStProc: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\noutConProc\tinput.vhd\t/^  outConProc: process (currState, delayCntVal, pulseCntVal) begin$/;\"\tQ\tarchitecture:progPulse.rtl\ndownCntr\tinput.vhd\t/^  downCntr: process (clk,reset) begin$/;\"\tQ\tarchitecture:progPulse.rtl\nprogPulseFsm\tinput.vhd\t/^entity progPulseFsm is port ($/;\"\te\ndownCnt\tinput.vhd\t/^  downCnt: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulseFsm\ndelayCntVal\tinput.vhd\t/^  delayCntVal: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulseFsm\nlengthCntVal\tinput.vhd\t/^  lengthCntVal: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulseFsm\nloadLength\tinput.vhd\t/^  loadLength: in std_logic;$/;\"\tq\tentity:progPulseFsm\nloadDelay\tinput.vhd\t/^  loadDelay: in std_logic;$/;\"\tq\tentity:progPulseFsm\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:progPulseFsm\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:progPulseFsm\ndownCntEn\tinput.vhd\t/^  downCntEn: out std_logic;$/;\"\tq\tentity:progPulseFsm\ndownCntLd\tinput.vhd\t/^  downCntLd: out std_logic;$/;\"\tq\tentity:progPulseFsm\ndownCntData\tinput.vhd\t/^  downCntData: out std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulseFsm\npulse\tinput.vhd\t/^  pulse: out std_logic$/;\"\tq\tentity:progPulseFsm\nfsm\tinput.vhd\t/^architecture fsm of progPulseFsm is$/;\"\ta\tentity:progPulseFsm\nprogPulseFsmType\tinput.vhd\t/^type progPulseFsmType is (loadDelayCnt, waitDelayEnd, loadLengthCnt, waitLengthEnd);$/;\"\tt\tarchitecture:progPulseFsm.fsm\nstateVec\tinput.vhd\t/^type stateVec is array (3 downto 0) of std_logic;$/;\"\tt\tarchitecture:progPulseFsm.fsm\nstateBits\tinput.vhd\t/^type stateBits is array (progPulseFsmType) of stateVec;$/;\"\tt\tarchitecture:progPulseFsm.fsm\nloadVal\tinput.vhd\t/^signal loadVal: std_logic;$/;\"\ts\tarchitecture:progPulseFsm.fsm\nstateTable\tinput.vhd\t/^constant stateTable: stateBits := ($/;\"\tc\tarchitecture:progPulseFsm.fsm\ncurrState\tinput.vhd\t/^signal currState, nextState: progPulseFsmType;$/;\"\ts\tarchitecture:progPulseFsm.fsm\nnextState\tinput.vhd\t/^signal currState, nextState: progPulseFsmType;$/;\"\ts\tarchitecture:progPulseFsm.fsm\nnextStProc\tinput.vhd\t/^  nextStProc: process (currState, downCnt, loadDelay, loadLength) begin$/;\"\tQ\tarchitecture:progPulseFsm.fsm\ncurrStProc\tinput.vhd\t/^  currStProc: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulseFsm.fsm\nprogPulseFsm\tinput.vhd\t/^entity progPulseFsm is port ($/;\"\te\ndownCnt\tinput.vhd\t/^  downCnt: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulseFsm\ndelayCntVal\tinput.vhd\t/^  delayCntVal: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulseFsm\nlengthCntVal\tinput.vhd\t/^  lengthCntVal: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulseFsm\nloadLength\tinput.vhd\t/^  loadLength: in std_logic;$/;\"\tq\tentity:progPulseFsm\nloadDelay\tinput.vhd\t/^  loadDelay: in std_logic;$/;\"\tq\tentity:progPulseFsm\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:progPulseFsm\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:progPulseFsm\ndownCntEn\tinput.vhd\t/^  downCntEn: out std_logic;$/;\"\tq\tentity:progPulseFsm\ndownCntLd\tinput.vhd\t/^  downCntLd: out std_logic;$/;\"\tq\tentity:progPulseFsm\ndowntCntData\tinput.vhd\t/^  downtCntData: out std_logic_vector(7 downto 0);$/;\"\tq\tentity:progPulseFsm\npulse\tinput.vhd\t/^  pulse: out std_logic$/;\"\tq\tentity:progPulseFsm\nfsm\tinput.vhd\t/^architecture fsm of progPulseFsm is$/;\"\ta\tentity:progPulseFsm\nprogPulseFsmType\tinput.vhd\t/^type progPulseFsmType is (loadDelayCnt, waitDelayEnd, loadLengthCnt, waitLengthEnd);$/;\"\tt\tarchitecture:progPulseFsm.fsm\ncurrState\tinput.vhd\t/^signal currState, nextState: progPulseFsmType;$/;\"\ts\tarchitecture:progPulseFsm.fsm\nnextState\tinput.vhd\t/^signal currState, nextState: progPulseFsmType;$/;\"\ts\tarchitecture:progPulseFsm.fsm\ndownCntL\tinput.vhd\t/^signal downCntL: unsigned (7 downto 0);$/;\"\ts\tarchitecture:progPulseFsm.fsm\nnextStProc\tinput.vhd\t/^  nextStProc: process (currState, downCntL, loadDelay, loadLength) begin$/;\"\tQ\tarchitecture:progPulseFsm.fsm\ncurrStProc\tinput.vhd\t/^  currStProc: process (clk, reset) begin$/;\"\tQ\tarchitecture:progPulseFsm.fsm\noutConProc\tinput.vhd\t/^  outConProc: process (currState, delayCntVal, lengthCntVal) begin$/;\"\tQ\tarchitecture:progPulseFsm.fsm\npowerOfFour\tinput.vhd\t/^entity powerOfFour is port($/;\"\te\nclk\tinput.vhd\t/^  clk      : in  std_logic; $/;\"\tq\tentity:powerOfFour\ninputVal\tinput.vhd\t/^  inputVal : in  std_logic_vector(3 downto 0);$/;\"\tq\tentity:powerOfFour\npower\tinput.vhd\t/^  power    : out std_logic_vector(15 downto 0)$/;\"\tq\tentity:powerOfFour\nbehavioral\tinput.vhd\t/^architecture behavioral of powerOfFour is$/;\"\ta\tentity:powerOfFour\nanonProcesscfc8de98200f\tinput.vhd\t/^   process begin$/;\"\tQ\tarchitecture:powerOfFour.behavioral\npowerOfFour\tinput.vhd\t/^entity powerOfFour is port($/;\"\te\nclk\tinput.vhd\t/^  clk      : in  std_logic; $/;\"\tq\tentity:powerOfFour\ninputVal\tinput.vhd\t/^  inputVal : in  std_logic_vector(3 downto 0);$/;\"\tq\tentity:powerOfFour\npower\tinput.vhd\t/^  power    : out std_logic_vector(15 downto 0)$/;\"\tq\tentity:powerOfFour\nbehavioral\tinput.vhd\t/^architecture behavioral of powerOfFour is$/;\"\ta\tentity:powerOfFour\nPow\tinput.vhd\t/^   function Pow( N, Exp : integer )  return integer is$/;\"\tf\tarchitecture:powerOfFour.behavioral\nResult\tinput.vhd\t/^      Variable Result   : integer := 1;$/;\"\tv\tfunction:powerOfFour.behavioral.Pow\nanonProcesscfc8de98210f\tinput.vhd\t/^   process begin$/;\"\tQ\tarchitecture:powerOfFour.behavioral\npowerOfFour\tinput.vhd\t/^entity powerOfFour is port($/;\"\te\nclk\tinput.vhd\t/^  clk      : in  std_logic; $/;\"\tq\tentity:powerOfFour\ninputVal\tinput.vhd\t/^  inputVal : in  std_logic_vector(3 downto 0);$/;\"\tq\tentity:powerOfFour\npower\tinput.vhd\t/^  power    : out std_logic_vector(15 downto 0)$/;\"\tq\tentity:powerOfFour\nbehavioral\tinput.vhd\t/^architecture behavioral of powerOfFour is$/;\"\ta\tentity:powerOfFour\nPow\tinput.vhd\t/^   function Pow( N, Exp : integer )  return integer is$/;\"\tf\tarchitecture:powerOfFour.behavioral\nResult\tinput.vhd\t/^      Variable Result   : integer := 1;$/;\"\tv\tfunction:powerOfFour.behavioral.Pow\nanonProcesscfc8de98220f\tinput.vhd\t/^   process begin$/;\"\tQ\tarchitecture:powerOfFour.behavioral\nregFile\tinput.vhd\t/^entity regFile is port ($/;\"\te\nclk\tinput.vhd\t/^  clk, rst: in std_logic;$/;\"\tq\tentity:regFile\nrst\tinput.vhd\t/^  clk, rst: in std_logic;$/;\"\tq\tentity:regFile\ndata\tinput.vhd\t/^  data: in std_logic_vector(31 downto 0);$/;\"\tq\tentity:regFile\nregSel\tinput.vhd\t/^  regSel: in std_logic_vector(1 downto 0);$/;\"\tq\tentity:regFile\nwrEnable\tinput.vhd\t/^  wrEnable: in std_logic;$/;\"\tq\tentity:regFile\nregOut\tinput.vhd\t/^  regOut: out std_logic_vector(31 downto 0)$/;\"\tq\tentity:regFile\nbehavioral\tinput.vhd\t/^architecture behavioral of regFile is$/;\"\ta\tentity:regFile\nreg\tinput.vhd\t/^subtype reg is std_logic_vector(31 downto 0);$/;\"\tT\tarchitecture:regFile.behavioral\nregArray\tinput.vhd\t/^type regArray is array (integer range <>) of reg;$/;\"\tt\tarchitecture:regFile.behavioral\nregisterFile\tinput.vhd\t/^signal registerFile: regArray(0 to 3);$/;\"\ts\tarchitecture:regFile.behavioral\nregProc\tinput.vhd\t/^  regProc: process (clk, rst) $/;\"\tQ\tarchitecture:regFile.behavioral\ni\tinput.vhd\t/^  variable i: integer;$/;\"\tv\tprocess:regFile.behavioral.regProc\noutputs\tinput.vhd\t/^  outputs: process(regSel, registerFile) begin$/;\"\tQ\tarchitecture:regFile.behavioral\nDFF\tinput.vhd\t/^entity DFF is port ($/;\"\te\nd1\tinput.vhd\t/^    d1,d2: in std_logic;$/;\"\tq\tentity:DFF\nd2\tinput.vhd\t/^    d1,d2: in std_logic;$/;\"\tq\tentity:DFF\nq1\tinput.vhd\t/^    q1,q2: out std_logic;$/;\"\tq\tentity:DFF\nq2\tinput.vhd\t/^    q1,q2: out std_logic;$/;\"\tq\tentity:DFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:DFF\nrst\tinput.vhd\t/^    rst : in std_logic$/;\"\tq\tentity:DFF\nrtl\tinput.vhd\t/^architecture rtl of DFF is$/;\"\ta\tentity:DFF\nresetLatch\tinput.vhd\t/^  resetLatch: process (clk, rst) begin$/;\"\tQ\tarchitecture:DFF.rtl\nresFcnDemo\tinput.vhd\t/^entity resFcnDemo is port ($/;\"\te\na\tinput.vhd\t/^  a, b: in std_logic;$/;\"\tq\tentity:resFcnDemo\nb\tinput.vhd\t/^  a, b: in std_logic;$/;\"\tq\tentity:resFcnDemo\noeA\tinput.vhd\t/^  oeA,oeB: in std_logic;$/;\"\tq\tentity:resFcnDemo\noeB\tinput.vhd\t/^  oeA,oeB: in std_logic;$/;\"\tq\tentity:resFcnDemo\nresult\tinput.vhd\t/^  result: out std_logic$/;\"\tq\tentity:resFcnDemo\nmultiDriver\tinput.vhd\t/^architecture multiDriver of resFcnDemo is$/;\"\ta\tentity:resFcnDemo\nscaleDFF\tinput.vhd\t/^entity scaleDFF is port ($/;\"\te\ndata\tinput.vhd\t/^  data: in std_logic_vector(7 downto 0);$/;\"\tq\tentity:scaleDFF\nclock\tinput.vhd\t/^  clock: in std_logic;$/;\"\tq\tentity:scaleDFF\nenable\tinput.vhd\t/^  enable: in std_logic;$/;\"\tq\tentity:scaleDFF\nqout\tinput.vhd\t/^  qout: out std_logic_vector(7 downto 0)$/;\"\tq\tentity:scaleDFF\nscalable\tinput.vhd\t/^architecture scalable of scaleDFF is$/;\"\ta\tentity:scaleDFF\nsevenSegment\tinput.vhd\t/^entity sevenSegment is port ($/;\"\te\nbcdInputs\tinput.vhd\t/^  bcdInputs: in std_logic_vector (3 downto 0);$/;\"\tq\tentity:sevenSegment\na_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tentity:sevenSegment\nb_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tentity:sevenSegment\nc_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tentity:sevenSegment\nd_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tentity:sevenSegment\ne_n\tinput.vhd\t/^  e_n, f_n, g_n: out std_logic$/;\"\tq\tentity:sevenSegment\nf_n\tinput.vhd\t/^  e_n, f_n, g_n: out std_logic$/;\"\tq\tentity:sevenSegment\ng_n\tinput.vhd\t/^  e_n, f_n, g_n: out std_logic$/;\"\tq\tentity:sevenSegment\nbehavioral\tinput.vhd\t/^architecture behavioral of sevenSegment is$/;\"\ta\tentity:sevenSegment\nla_n\tinput.vhd\t/^signal la_n, lb_n, lc_n, ld_n, le_n, lf_n, lg_n: std_logic;$/;\"\ts\tarchitecture:sevenSegment.behavioral\nlb_n\tinput.vhd\t/^signal la_n, lb_n, lc_n, ld_n, le_n, lf_n, lg_n: std_logic;$/;\"\ts\tarchitecture:sevenSegment.behavioral\nlc_n\tinput.vhd\t/^signal la_n, lb_n, lc_n, ld_n, le_n, lf_n, lg_n: std_logic;$/;\"\ts\tarchitecture:sevenSegment.behavioral\nld_n\tinput.vhd\t/^signal la_n, lb_n, lc_n, ld_n, le_n, lf_n, lg_n: std_logic;$/;\"\ts\tarchitecture:sevenSegment.behavioral\nle_n\tinput.vhd\t/^signal la_n, lb_n, lc_n, ld_n, le_n, lf_n, lg_n: std_logic;$/;\"\ts\tarchitecture:sevenSegment.behavioral\nlf_n\tinput.vhd\t/^signal la_n, lb_n, lc_n, ld_n, le_n, lf_n, lg_n: std_logic;$/;\"\ts\tarchitecture:sevenSegment.behavioral\nlg_n\tinput.vhd\t/^signal la_n, lb_n, lc_n, ld_n, le_n, lf_n, lg_n: std_logic;$/;\"\ts\tarchitecture:sevenSegment.behavioral\noe\tinput.vhd\t/^signal oe: std_logic;$/;\"\ts\tarchitecture:sevenSegment.behavioral\nbcd2sevSeg\tinput.vhd\t/^  bcd2sevSeg: process (bcdInputs) begin$/;\"\tQ\tarchitecture:sevenSegment.behavioral\nsevenSegmentTB\tinput.vhd\t/^entity sevenSegmentTB is$/;\"\te\ntestbench\tinput.vhd\t/^architecture testbench of sevenSegmentTB is$/;\"\ta\tentity:sevenSegmentTB\nsevenSegment\tinput.vhd\t/^component sevenSegment port ($/;\"\tC\tarchitecture:sevenSegmentTB.testbench\nbcdInputs\tinput.vhd\t/^  bcdInputs: in std_logic_vector (3 downto 0);$/;\"\tq\tcomponent:sevenSegmentTB.testbench.sevenSegment\na_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tcomponent:sevenSegmentTB.testbench.sevenSegment\nb_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tcomponent:sevenSegmentTB.testbench.sevenSegment\nc_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tcomponent:sevenSegmentTB.testbench.sevenSegment\nd_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tcomponent:sevenSegmentTB.testbench.sevenSegment\ne_n\tinput.vhd\t/^  e_n, f_n, g_n: out std_logic$/;\"\tq\tcomponent:sevenSegmentTB.testbench.sevenSegment\nf_n\tinput.vhd\t/^  e_n, f_n, g_n: out std_logic$/;\"\tq\tcomponent:sevenSegmentTB.testbench.sevenSegment\ng_n\tinput.vhd\t/^  e_n, f_n, g_n: out std_logic$/;\"\tq\tcomponent:sevenSegmentTB.testbench.sevenSegment\nvector\tinput.vhd\t/^type vector is record$/;\"\tt\tarchitecture:sevenSegmentTB.testbench\nbcdStimulus\tinput.vhd\t/^  bcdStimulus: std_logic_vector(3 downto 0);$/;\"\tr\ttype:sevenSegmentTB.testbench.vector\nsevSegOut\tinput.vhd\t/^  sevSegOut: std_logic_vector(6 downto 0);$/;\"\tr\ttype:sevenSegmentTB.testbench.vector\nNumVectors\tinput.vhd\t/^constant NumVectors: integer:= 17;$/;\"\tc\tarchitecture:sevenSegmentTB.testbench\nPropDelay\tinput.vhd\t/^constant PropDelay: time := 40 ns;$/;\"\tc\tarchitecture:sevenSegmentTB.testbench\nSimLoopDelay\tinput.vhd\t/^constant SimLoopDelay: time := 10 ns;$/;\"\tc\tarchitecture:sevenSegmentTB.testbench\nvectorArray\tinput.vhd\t/^type vectorArray is array (0 to NumVectors - 1) of vector;$/;\"\tt\tarchitecture:sevenSegmentTB.testbench\nvectorTable\tinput.vhd\t/^constant vectorTable: vectorArray := ($/;\"\tc\tarchitecture:sevenSegmentTB.testbench\nStimInputs\tinput.vhd\t/^signal StimInputs: std_logic_vector(3 downto 0);$/;\"\ts\tarchitecture:sevenSegmentTB.testbench\nCaptureOutputs\tinput.vhd\t/^signal CaptureOutputs: std_logic_vector(6 downto 0);$/;\"\ts\tarchitecture:sevenSegmentTB.testbench\nLoopStim\tinput.vhd\t/^  LoopStim: process$/;\"\tQ\tarchitecture:sevenSegmentTB.testbench\nFoundError\tinput.vhd\t/^    variable FoundError: boolean := false;$/;\"\tv\tprocess:sevenSegmentTB.testbench.LoopStim\nTempVector\tinput.vhd\t/^    variable TempVector: vector;$/;\"\tv\tprocess:sevenSegmentTB.testbench.LoopStim\nErrorMsgLine\tinput.vhd\t/^    variable ErrorMsgLine: line;$/;\"\tv\tprocess:sevenSegmentTB.testbench.LoopStim\nsevenSegment\tinput.vhd\t/^entity sevenSegment is port ($/;\"\te\nbcdInputs\tinput.vhd\t/^  bcdInputs: in std_logic_vector (3 downto 0);$/;\"\tq\tentity:sevenSegment\na_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tentity:sevenSegment\nb_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tentity:sevenSegment\nc_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tentity:sevenSegment\nd_n\tinput.vhd\t/^  a_n, b_n, c_n, d_n,$/;\"\tq\tentity:sevenSegment\ne_n\tinput.vhd\t/^  e_n, f_n, g_n: out std_logic$/;\"\tq\tentity:sevenSegment\nf_n\tinput.vhd\t/^  e_n, f_n, g_n: out std_logic$/;\"\tq\tentity:sevenSegment\ng_n\tinput.vhd\t/^  e_n, f_n, g_n: out std_logic$/;\"\tq\tentity:sevenSegment\nbehavioral\tinput.vhd\t/^architecture behavioral of sevenSegment is$/;\"\ta\tentity:sevenSegment\nbcd2sevSeg\tinput.vhd\t/^  bcd2sevSeg: process (bcdInputs) begin$/;\"\tQ\tarchitecture:sevenSegment.behavioral\nForceShare\tinput.vhd\t/^entity ForceShare is port ($/;\"\te\na\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\nb\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\nc\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\nd\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\ne\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\nf\tinput.vhd\t/^  a,b,c,d,e,f: in std_logic_vector (7 downto 0);$/;\"\tq\tentity:ForceShare\nresult\tinput.vhd\t/^  result: out std_logic_vector(7 downto 0)$/;\"\tq\tentity:ForceShare\nbehaviour\tinput.vhd\t/^architecture behaviour of ForceShare is$/;\"\ta\tentity:ForceShare\nsum\tinput.vhd\t/^  sum: process (a,c,b,d,e,f)$/;\"\tQ\tarchitecture:ForceShare.behaviour\ntempSum\tinput.vhd\t/^  variable tempSum: std_logic_vector(7 downto 0);$/;\"\tv\tprocess:ForceShare.behaviour.sum\nshifter\tinput.vhd\t/^entity shifter is port ($/;\"\te\nclk\tinput.vhd\t/^  clk, rst: in std_logic;$/;\"\tq\tentity:shifter\nrst\tinput.vhd\t/^  clk, rst: in std_logic;$/;\"\tq\tentity:shifter\nshiftEn\tinput.vhd\t/^  shiftEn,shiftIn: std_logic;$/;\"\tq\tentity:shifter\nshiftIn\tinput.vhd\t/^  shiftEn,shiftIn: std_logic;$/;\"\tq\tentity:shifter\nq\tinput.vhd\t/^  q: out std_logic_vector (15 downto 0)$/;\"\tq\tentity:shifter\nbehav\tinput.vhd\t/^architecture behav of shifter is$/;\"\ta\tentity:shifter\nqLocal\tinput.vhd\t/^signal qLocal: std_logic_vector(15 downto 0);$/;\"\ts\tarchitecture:shifter.behav\nshift\tinput.vhd\t/^  shift: process (clk, rst) begin$/;\"\tQ\tarchitecture:shifter.behav\nlastAssignment\tinput.vhd\t/^entity lastAssignment is port$/;\"\te\na\tinput.vhd\t/^  (a, b: in std_logic;$/;\"\tq\tentity:lastAssignment\nb\tinput.vhd\t/^  (a, b: in std_logic;$/;\"\tq\tentity:lastAssignment\nselA\tinput.vhd\t/^   selA, selb: in std_logic;$/;\"\tq\tentity:lastAssignment\nselb\tinput.vhd\t/^   selA, selb: in std_logic;$/;\"\tq\tentity:lastAssignment\nresult\tinput.vhd\t/^   result: out std_logic$/;\"\tq\tentity:lastAssignment\nbehavioral\tinput.vhd\t/^architecture behavioral of lastAssignment is$/;\"\ta\tentity:lastAssignment\ndemo\tinput.vhd\t/^  demo: process (a,b,selA,selB) begin$/;\"\tQ\tarchitecture:lastAssignment.behavioral\nsignalDemo\tinput.vhd\t/^entity signalDemo is port ($/;\"\te\na\tinput.vhd\t/^  a: in std_logic;$/;\"\tq\tentity:signalDemo\nb\tinput.vhd\t/^  b: out std_logic$/;\"\tq\tentity:signalDemo\nbasic\tinput.vhd\t/^architecture basic of signalDemo is$/;\"\ta\tentity:signalDemo\nc\tinput.vhd\t/^signal c: std_logic;$/;\"\ts\tarchitecture:signalDemo.basic\ndemo\tinput.vhd\t/^  demo: process (a) begin$/;\"\tQ\tarchitecture:signalDemo.basic\nsignalDemo\tinput.vhd\t/^entity signalDemo is port ($/;\"\te\na\tinput.vhd\t/^  a: in std_logic;$/;\"\tq\tentity:signalDemo\nb\tinput.vhd\t/^  b: out std_logic$/;\"\tq\tentity:signalDemo\nbasic\tinput.vhd\t/^architecture basic of signalDemo is$/;\"\ta\tentity:signalDemo\nc\tinput.vhd\t/^signal c: std_logic;$/;\"\ts\tarchitecture:signalDemo.basic\ndemo\tinput.vhd\t/^  demo: process (a) begin$/;\"\tQ\tarchitecture:signalDemo.basic\nsimPrimitives\tinput.vhd\t/^package simPrimitives is$/;\"\tP\nOR2\tinput.vhd\t/^  component OR2$/;\"\tC\tpackage:simPrimitives\ntPD\tinput.vhd\t/^    generic (tPD: time := 1 ns);$/;\"\tg\tcomponent:simPrimitives.OR2\nI1\tinput.vhd\t/^    port (I1, I2: in std_logic;$/;\"\tq\tcomponent:simPrimitives.OR2\nI2\tinput.vhd\t/^    port (I1, I2: in std_logic;$/;\"\tq\tcomponent:simPrimitives.OR2\nY\tinput.vhd\t/^          Y: out std_logic$/;\"\tq\tcomponent:simPrimitives.OR2\nSimDFF\tinput.vhd\t/^  component SimDFF$/;\"\tC\tpackage:simPrimitives\ntCQ\tinput.vhd\t/^  generic(tCQ: time := 1 ns;$/;\"\tg\tcomponent:simPrimitives.SimDFF\ntS\tinput.vhd\t/^          tS : time := 1 ns;$/;\"\tg\tcomponent:simPrimitives.SimDFF\ntH\tinput.vhd\t/^          tH : time := 1 ns$/;\"\tg\tcomponent:simPrimitives.SimDFF\nD\tinput.vhd\t/^  port (D, Clk: in std_logic;$/;\"\tq\tcomponent:simPrimitives.SimDFF\nClk\tinput.vhd\t/^  port (D, Clk: in std_logic;$/;\"\tq\tcomponent:simPrimitives.SimDFF\nQ\tinput.vhd\t/^        Q: out std_logic$/;\"\tq\tcomponent:simPrimitives.SimDFF\nOR2\tinput.vhd\t/^entity OR2 is$/;\"\te\ntPD\tinput.vhd\t/^  generic (tPD: time := 1 ns);$/;\"\tg\tentity:OR2\nI1\tinput.vhd\t/^  port (I1, I2: in std_logic;$/;\"\tq\tentity:OR2\nI2\tinput.vhd\t/^  port (I1, I2: in std_logic;$/;\"\tq\tentity:OR2\nY\tinput.vhd\t/^    Y: out std_logic$/;\"\tq\tentity:OR2\nsimple\tinput.vhd\t/^architecture simple of OR2 is$/;\"\ta\tentity:OR2\nSimDFF\tinput.vhd\t/^entity SimDFF is$/;\"\te\ntCQ\tinput.vhd\t/^  generic(tCQ: time := 1 ns;$/;\"\tg\tentity:SimDFF\ntS\tinput.vhd\t/^          tS : time := 1 ns;$/;\"\tg\tentity:SimDFF\ntH\tinput.vhd\t/^          tH : time := 1 ns$/;\"\tg\tentity:SimDFF\nD\tinput.vhd\t/^  port (D, Clk: in std_logic;$/;\"\tq\tentity:SimDFF\nClk\tinput.vhd\t/^  port (D, Clk: in std_logic;$/;\"\tq\tentity:SimDFF\nQ\tinput.vhd\t/^  Q: out std_logic$/;\"\tq\tentity:SimDFF\nSimModel\tinput.vhd\t/^architecture SimModel of SimDFF is$/;\"\ta\tentity:SimDFF\nreg\tinput.vhd\t/^  reg: process (Clk, D) begin$/;\"\tQ\tarchitecture:SimDFF.SimModel\nSRFF\tinput.vhd\t/^entity SRFF is port ($/;\"\te\ns\tinput.vhd\t/^    s,r: in std_logic;$/;\"\tq\tentity:SRFF\nr\tinput.vhd\t/^    s,r: in std_logic;$/;\"\tq\tentity:SRFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:SRFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:SRFF\nrtl\tinput.vhd\t/^architecture rtl of SRFF is$/;\"\ta\tentity:SRFF\nanonProcesscfc8de98230f\tinput.vhd\t/^  process begin$/;\"\tQ\tarchitecture:SRFF.rtl\nSRFF\tinput.vhd\t/^entity SRFF is port ($/;\"\te\ns\tinput.vhd\t/^    s,r: in std_logic;$/;\"\tq\tentity:SRFF\nr\tinput.vhd\t/^    s,r: in std_logic;$/;\"\tq\tentity:SRFF\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tentity:SRFF\nq\tinput.vhd\t/^    q: out std_logic$/;\"\tq\tentity:SRFF\nrtl\tinput.vhd\t/^architecture rtl of SRFF is$/;\"\ta\tentity:SRFF\nanonProcesscfc8de98240f\tinput.vhd\t/^  process begin$/;\"\tQ\tarchitecture:SRFF.rtl\nscaleable\tinput.vhd\t/^package scaleable is$/;\"\tP\nscaleUpCnt\tinput.vhd\t/^  component scaleUpCnt port ($/;\"\tC\tpackage:scaleable\nclk\tinput.vhd\t/^    clk: in std_logic;$/;\"\tq\tcomponent:scaleable.scaleUpCnt\nreset\tinput.vhd\t/^    reset: in std_logic;$/;\"\tq\tcomponent:scaleable.scaleUpCnt\ncnt\tinput.vhd\t/^    cnt: in std_logic_vector$/;\"\tq\tcomponent:scaleable.scaleUpCnt\nscaleUpCnt\tinput.vhd\t/^entity scaleUpCnt is port ($/;\"\te\nclk\tinput.vhd\t/^  clk: in std_logic;$/;\"\tq\tentity:scaleUpCnt\nreset\tinput.vhd\t/^  reset: in std_logic;$/;\"\tq\tentity:scaleUpCnt\ncnt\tinput.vhd\t/^  cnt: out std_logic_vector$/;\"\tq\tentity:scaleUpCnt\nscaleable\tinput.vhd\t/^architecture scaleable of scaleUpCnt is$/;\"\ta\tentity:scaleUpCnt\none\tinput.vhd\t/^signal one: std_logic := '1';$/;\"\ts\tarchitecture:scaleUpCnt.scaleable\ncntL\tinput.vhd\t/^signal cntL: std_logic_vector(cnt'range);$/;\"\ts\tarchitecture:scaleUpCnt.scaleable\nandTerm\tinput.vhd\t/^signal andTerm: std_logic_vector(cnt'range);$/;\"\ts\tarchitecture:scaleUpCnt.scaleable\npci_target\tinput.vhd\t/^entity pci_target is port ($/;\"\te\nPCI_Frame_n\tinput.vhd\t/^  PCI_Frame_n: in std_logic;\t-- PCI Frame#$/;\"\tq\tentity:pci_target\nPCI_Irdy_n\tinput.vhd\t/^  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#$/;\"\tq\tentity:pci_target\nHit\tinput.vhd\t/^  Hit: in std_logic;\t\t\t-- Hit on address decode$/;\"\tq\tentity:pci_target\nD_Done\tinput.vhd\t/^  D_Done: in std_logic;\t\t\t-- Device decode complete$/;\"\tq\tentity:pci_target\nTerm\tinput.vhd\t/^  Term: in std_logic;\t\t\t-- Terminate transaction$/;\"\tq\tentity:pci_target\nReady\tinput.vhd\t/^  Ready: in std_logic;\t\t\t-- Ready to transfer data$/;\"\tq\tentity:pci_target\nCmd_Write\tinput.vhd\t/^  Cmd_Write: in std_logic;\t\t-- Command is Write$/;\"\tq\tentity:pci_target\nCmd_Read\tinput.vhd\t/^  Cmd_Read: in std_logic;\t\t-- Command is Read$/;\"\tq\tentity:pci_target\nT_Abort\tinput.vhd\t/^  T_Abort: in std_logic;\t\t-- Target error  - abort transaction$/;\"\tq\tentity:pci_target\nPCI_Clk\tinput.vhd\t/^  PCI_Clk: in std_logic;\t\t-- PCI Clock$/;\"\tq\tentity:pci_target\nPCI_Reset_n\tinput.vhd\t/^  PCI_Reset_n: in std_logic;\t-- PCI Reset#$/;\"\tq\tentity:pci_target\nPCI_Devsel_n\tinput.vhd\t/^  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#$/;\"\tq\tentity:pci_target\nPCI_Trdy_n\tinput.vhd\t/^  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#$/;\"\tq\tentity:pci_target\nPCI_Stop_n\tinput.vhd\t/^  PCI_Stop_n: out std_logic;\t-- PCI Stop#$/;\"\tq\tentity:pci_target\nOE_AD\tinput.vhd\t/^  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable$/;\"\tq\tentity:pci_target\nOE_Trdy_n\tinput.vhd\t/^  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable$/;\"\tq\tentity:pci_target\nOE_Stop_n\tinput.vhd\t/^  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable$/;\"\tq\tentity:pci_target\nOE_Devsel_n\tinput.vhd\t/^  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable$/;\"\tq\tentity:pci_target\nfsm\tinput.vhd\t/^architecture fsm of pci_target is$/;\"\ta\tentity:pci_target\nLPCI_Devsel_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Trdy_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Stop_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\ntargetFsmType\tinput.vhd\t/^subtype targetFsmType is std_logic_vector(2 downto 0);$/;\"\tT\tarchitecture:pci_target.fsm\nIdle\tinput.vhd\t/^constant Idle: \t\ttargetFsmType := \"000\";$/;\"\tc\tarchitecture:pci_target.fsm\nB_Busy\tinput.vhd\t/^constant B_Busy: \t\ttargetFsmType := \"101\";$/;\"\tc\tarchitecture:pci_target.fsm\nBackoff\tinput.vhd\t/^constant Backoff: \ttargetFsmType := \"010\";$/;\"\tc\tarchitecture:pci_target.fsm\nS_Data\tinput.vhd\t/^constant S_Data: \t\ttargetFsmType := \"011\";$/;\"\tc\tarchitecture:pci_target.fsm\nTurn_Ar\tinput.vhd\t/^constant Turn_Ar: \ttargetFsmType := \"110\";$/;\"\tc\tarchitecture:pci_target.fsm\ncurrState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnextState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnxtStProc\tinput.vhd\t/^ nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,$/;\"\tQ\tarchitecture:pci_target.fsm\ncurStProc\tinput.vhd\t/^  curStProc: process (PCI_Clk, PCI_Reset_n) begin$/;\"\tQ\tarchitecture:pci_target.fsm\noutConProc\tinput.vhd\t/^  outConProc: process (currState, Ready, T_Abort, Cmd_Write,$/;\"\tQ\tarchitecture:pci_target.fsm\npci_target\tinput.vhd\t/^entity pci_target is port ($/;\"\te\nPCI_Frame_n\tinput.vhd\t/^  PCI_Frame_n: in std_logic;\t-- PCI Frame#$/;\"\tq\tentity:pci_target\nPCI_Irdy_n\tinput.vhd\t/^  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#$/;\"\tq\tentity:pci_target\nHit\tinput.vhd\t/^  Hit: in std_logic;\t\t\t-- Hit on address decode$/;\"\tq\tentity:pci_target\nD_Done\tinput.vhd\t/^  D_Done: in std_logic;\t\t\t-- Device decode complete$/;\"\tq\tentity:pci_target\nTerm\tinput.vhd\t/^  Term: in std_logic;\t\t\t-- Terminate transaction$/;\"\tq\tentity:pci_target\nReady\tinput.vhd\t/^  Ready: in std_logic;\t\t\t-- Ready to transfer data$/;\"\tq\tentity:pci_target\nCmd_Write\tinput.vhd\t/^  Cmd_Write: in std_logic;\t\t-- Command is Write$/;\"\tq\tentity:pci_target\nCmd_Read\tinput.vhd\t/^  Cmd_Read: in std_logic;\t\t-- Command is Read$/;\"\tq\tentity:pci_target\nT_Abort\tinput.vhd\t/^  T_Abort: in std_logic;\t\t-- Target error  - abort transaction$/;\"\tq\tentity:pci_target\nPCI_Clk\tinput.vhd\t/^  PCI_Clk: in std_logic;\t\t-- PCI Clock$/;\"\tq\tentity:pci_target\nPCI_Reset_n\tinput.vhd\t/^  PCI_Reset_n: in std_logic;\t-- PCI Reset#$/;\"\tq\tentity:pci_target\nPCI_Devsel_n\tinput.vhd\t/^  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#$/;\"\tq\tentity:pci_target\nPCI_Trdy_n\tinput.vhd\t/^  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#$/;\"\tq\tentity:pci_target\nPCI_Stop_n\tinput.vhd\t/^  PCI_Stop_n: out std_logic;\t-- PCI Stop#$/;\"\tq\tentity:pci_target\nOE_AD\tinput.vhd\t/^  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable$/;\"\tq\tentity:pci_target\nOE_Trdy_n\tinput.vhd\t/^  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable$/;\"\tq\tentity:pci_target\nOE_Stop_n\tinput.vhd\t/^  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable$/;\"\tq\tentity:pci_target\nOE_Devsel_n\tinput.vhd\t/^  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable$/;\"\tq\tentity:pci_target\nfsm\tinput.vhd\t/^architecture fsm of pci_target is$/;\"\ta\tentity:pci_target\nLPCI_Devsel_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Trdy_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Stop_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\ntargetFsmType\tinput.vhd\t/^subtype targetFsmType is std_logic_vector(2 downto 0);$/;\"\tT\tarchitecture:pci_target.fsm\nIdle\tinput.vhd\t/^constant Idle: \t\ttargetFsmType := \"000\";$/;\"\tc\tarchitecture:pci_target.fsm\nB_Busy\tinput.vhd\t/^constant B_Busy: \t\ttargetFsmType := \"001\";$/;\"\tc\tarchitecture:pci_target.fsm\nBackoff\tinput.vhd\t/^constant Backoff: \ttargetFsmType := \"011\";$/;\"\tc\tarchitecture:pci_target.fsm\nS_Data\tinput.vhd\t/^constant S_Data: \t\ttargetFsmType := \"010\";$/;\"\tc\tarchitecture:pci_target.fsm\nTurn_Ar\tinput.vhd\t/^constant Turn_Ar: \ttargetFsmType := \"110\";$/;\"\tc\tarchitecture:pci_target.fsm\ncurrState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnextState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnxtStProc\tinput.vhd\t/^ nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,$/;\"\tQ\tarchitecture:pci_target.fsm\ncurStProc\tinput.vhd\t/^  curStProc: process (PCI_Clk, PCI_Reset_n) begin$/;\"\tQ\tarchitecture:pci_target.fsm\noutConProc\tinput.vhd\t/^  outConProc: process (currState, Ready, T_Abort, Cmd_Write,$/;\"\tQ\tarchitecture:pci_target.fsm\npci_target\tinput.vhd\t/^entity pci_target is port ($/;\"\te\nPCI_Frame_n\tinput.vhd\t/^  PCI_Frame_n: in std_logic;\t-- PCI Frame#$/;\"\tq\tentity:pci_target\nPCI_Irdy_n\tinput.vhd\t/^  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#$/;\"\tq\tentity:pci_target\nHit\tinput.vhd\t/^  Hit: in std_logic;\t\t\t-- Hit on address decode$/;\"\tq\tentity:pci_target\nD_Done\tinput.vhd\t/^  D_Done: in std_logic;\t\t\t-- Device decode complete$/;\"\tq\tentity:pci_target\nTerm\tinput.vhd\t/^  Term: in std_logic;\t\t\t-- Terminate transaction$/;\"\tq\tentity:pci_target\nReady\tinput.vhd\t/^  Ready: in std_logic;\t\t\t-- Ready to transfer data$/;\"\tq\tentity:pci_target\nCmd_Write\tinput.vhd\t/^  Cmd_Write: in std_logic;\t\t-- Command is Write$/;\"\tq\tentity:pci_target\nCmd_Read\tinput.vhd\t/^  Cmd_Read: in std_logic;\t\t-- Command is Read$/;\"\tq\tentity:pci_target\nT_Abort\tinput.vhd\t/^  T_Abort: in std_logic;\t\t-- Target error  - abort transaction$/;\"\tq\tentity:pci_target\nPCI_Clk\tinput.vhd\t/^  PCI_Clk: in std_logic;\t\t-- PCI Clock$/;\"\tq\tentity:pci_target\nPCI_Reset_n\tinput.vhd\t/^  PCI_Reset_n: in std_logic;\t-- PCI Reset#$/;\"\tq\tentity:pci_target\nPCI_Devsel_n\tinput.vhd\t/^  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#$/;\"\tq\tentity:pci_target\nPCI_Trdy_n\tinput.vhd\t/^  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#$/;\"\tq\tentity:pci_target\nPCI_Stop_n\tinput.vhd\t/^  PCI_Stop_n: out std_logic;\t-- PCI Stop#$/;\"\tq\tentity:pci_target\nOE_AD\tinput.vhd\t/^  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable$/;\"\tq\tentity:pci_target\nOE_Trdy_n\tinput.vhd\t/^  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable$/;\"\tq\tentity:pci_target\nOE_Stop_n\tinput.vhd\t/^  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable$/;\"\tq\tentity:pci_target\nOE_Devsel_n\tinput.vhd\t/^  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable$/;\"\tq\tentity:pci_target\nfsm\tinput.vhd\t/^architecture fsm of pci_target is$/;\"\ta\tentity:pci_target\nLPCI_Devsel_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Trdy_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Stop_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\ntargetFsmType\tinput.vhd\t/^subtype targetFsmType is std_logic_vector(2 downto 0);$/;\"\tT\tarchitecture:pci_target.fsm\nIdle\tinput.vhd\t/^constant Idle: \t\ttargetFsmType := \"000\";$/;\"\tc\tarchitecture:pci_target.fsm\nB_Busy\tinput.vhd\t/^constant B_Busy: \ttargetFsmType := \"001\";$/;\"\tc\tarchitecture:pci_target.fsm\nBackoff\tinput.vhd\t/^constant Backoff: \ttargetFsmType := \"010\";$/;\"\tc\tarchitecture:pci_target.fsm\nS_Data\tinput.vhd\t/^constant S_Data: \ttargetFsmType := \"011\";$/;\"\tc\tarchitecture:pci_target.fsm\nTurn_Ar\tinput.vhd\t/^constant Turn_Ar: \ttargetFsmType := \"100\";$/;\"\tc\tarchitecture:pci_target.fsm\ncurrState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnextState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnxtStProc\tinput.vhd\t/^ nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,$/;\"\tQ\tarchitecture:pci_target.fsm\ncurStProc\tinput.vhd\t/^  curStProc: process (PCI_Clk, PCI_Reset_n) begin$/;\"\tQ\tarchitecture:pci_target.fsm\noutConProc\tinput.vhd\t/^  outConProc: process (currState, Ready, T_Abort, Cmd_Write,$/;\"\tQ\tarchitecture:pci_target.fsm\npci_target\tinput.vhd\t/^entity pci_target is port ($/;\"\te\nPCI_Frame_n\tinput.vhd\t/^  PCI_Frame_n: in std_logic;\t-- PCI Frame#$/;\"\tq\tentity:pci_target\nPCI_Irdy_n\tinput.vhd\t/^  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#$/;\"\tq\tentity:pci_target\nHit\tinput.vhd\t/^  Hit: in std_logic;\t\t\t-- Hit on address decode$/;\"\tq\tentity:pci_target\nD_Done\tinput.vhd\t/^  D_Done: in std_logic;\t\t\t-- Device decode complete$/;\"\tq\tentity:pci_target\nTerm\tinput.vhd\t/^  Term: in std_logic;\t\t\t-- Terminate transaction$/;\"\tq\tentity:pci_target\nReady\tinput.vhd\t/^  Ready: in std_logic;\t\t\t-- Ready to transfer data$/;\"\tq\tentity:pci_target\nCmd_Write\tinput.vhd\t/^  Cmd_Write: in std_logic;\t\t-- Command is Write$/;\"\tq\tentity:pci_target\nCmd_Read\tinput.vhd\t/^  Cmd_Read: in std_logic;\t\t-- Command is Read$/;\"\tq\tentity:pci_target\nT_Abort\tinput.vhd\t/^  T_Abort: in std_logic;\t\t-- Target error  - abort transaction$/;\"\tq\tentity:pci_target\nPCI_Clk\tinput.vhd\t/^  PCI_Clk: in std_logic;\t\t-- PCI Clock$/;\"\tq\tentity:pci_target\nPCI_Reset_n\tinput.vhd\t/^  PCI_Reset_n: in std_logic;\t-- PCI Reset#$/;\"\tq\tentity:pci_target\nPCI_Devsel_n\tinput.vhd\t/^  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#$/;\"\tq\tentity:pci_target\nPCI_Trdy_n\tinput.vhd\t/^  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#$/;\"\tq\tentity:pci_target\nPCI_Stop_n\tinput.vhd\t/^  PCI_Stop_n: out std_logic;\t-- PCI Stop#$/;\"\tq\tentity:pci_target\nOE_AD\tinput.vhd\t/^  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable$/;\"\tq\tentity:pci_target\nOE_Trdy_n\tinput.vhd\t/^  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable$/;\"\tq\tentity:pci_target\nOE_Stop_n\tinput.vhd\t/^  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable$/;\"\tq\tentity:pci_target\nOE_Devsel_n\tinput.vhd\t/^  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable$/;\"\tq\tentity:pci_target\nfsm\tinput.vhd\t/^architecture fsm of pci_target is$/;\"\ta\tentity:pci_target\nLPCI_Devsel_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Trdy_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Stop_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\ntargetFsmType\tinput.vhd\t/^subtype targetFsmType is std_logic_vector(3 downto 0);$/;\"\tT\tarchitecture:pci_target.fsm\nIdle\tinput.vhd\t/^constant Idle: \t\ttargetFsmType := \"0000\";$/;\"\tc\tarchitecture:pci_target.fsm\nB_Busy\tinput.vhd\t/^constant B_Busy: \ttargetFsmType := \"0001\";$/;\"\tc\tarchitecture:pci_target.fsm\nBackoff\tinput.vhd\t/^constant Backoff: \ttargetFsmType := \"0011\";$/;\"\tc\tarchitecture:pci_target.fsm\nS_Data\tinput.vhd\t/^constant S_Data: \ttargetFsmType := \"1100\";$/;\"\tc\tarchitecture:pci_target.fsm\nTurn_Ar\tinput.vhd\t/^constant Turn_Ar: \ttargetFsmType := \"1101\";$/;\"\tc\tarchitecture:pci_target.fsm\ncurrState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnextState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnxtStProc\tinput.vhd\t/^ nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,$/;\"\tQ\tarchitecture:pci_target.fsm\ncurStProc\tinput.vhd\t/^  curStProc: process (PCI_Clk, PCI_Reset_n) begin$/;\"\tQ\tarchitecture:pci_target.fsm\noutConProc\tinput.vhd\t/^  outConProc: process (currState, Ready, T_Abort, Cmd_Write,$/;\"\tQ\tarchitecture:pci_target.fsm\npci_target\tinput.vhd\t/^entity pci_target is port ($/;\"\te\nPCI_Frame_n\tinput.vhd\t/^  PCI_Frame_n: in std_logic;\t-- PCI Frame#$/;\"\tq\tentity:pci_target\nPCI_Irdy_n\tinput.vhd\t/^  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#$/;\"\tq\tentity:pci_target\nHit\tinput.vhd\t/^  Hit: in std_logic;\t\t\t-- Hit on address decode$/;\"\tq\tentity:pci_target\nD_Done\tinput.vhd\t/^  D_Done: in std_logic;\t\t\t-- Device decode complete$/;\"\tq\tentity:pci_target\nTerm\tinput.vhd\t/^  Term: in std_logic;\t\t\t-- Terminate transaction$/;\"\tq\tentity:pci_target\nReady\tinput.vhd\t/^  Ready: in std_logic;\t\t\t-- Ready to transfer data$/;\"\tq\tentity:pci_target\nCmd_Write\tinput.vhd\t/^  Cmd_Write: in std_logic;\t\t-- Command is Write$/;\"\tq\tentity:pci_target\nCmd_Read\tinput.vhd\t/^  Cmd_Read: in std_logic;\t\t-- Command is Read$/;\"\tq\tentity:pci_target\nT_Abort\tinput.vhd\t/^  T_Abort: in std_logic;\t\t-- Target error  - abort transaction$/;\"\tq\tentity:pci_target\nPCI_Clk\tinput.vhd\t/^  PCI_Clk: in std_logic;\t\t-- PCI Clock$/;\"\tq\tentity:pci_target\nPCI_Reset_n\tinput.vhd\t/^  PCI_Reset_n: in std_logic;\t-- PCI Reset#$/;\"\tq\tentity:pci_target\nPCI_Devsel_n\tinput.vhd\t/^  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#$/;\"\tq\tentity:pci_target\nPCI_Trdy_n\tinput.vhd\t/^  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#$/;\"\tq\tentity:pci_target\nPCI_Stop_n\tinput.vhd\t/^  PCI_Stop_n: out std_logic;\t-- PCI Stop#$/;\"\tq\tentity:pci_target\nOE_AD\tinput.vhd\t/^  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable$/;\"\tq\tentity:pci_target\nOE_Trdy_n\tinput.vhd\t/^  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable$/;\"\tq\tentity:pci_target\nOE_Stop_n\tinput.vhd\t/^  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable$/;\"\tq\tentity:pci_target\nOE_Devsel_n\tinput.vhd\t/^  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable$/;\"\tq\tentity:pci_target\nfsm\tinput.vhd\t/^architecture fsm of pci_target is$/;\"\ta\tentity:pci_target\nLPCI_Devsel_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Trdy_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Stop_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\ntargetFsmType\tinput.vhd\t/^subtype targetFsmType is std_logic_vector(2 downto 0);$/;\"\tT\tarchitecture:pci_target.fsm\nIdle\tinput.vhd\t/^constant Idle: \t\ttargetFsmType := \"000\";$/;\"\tc\tarchitecture:pci_target.fsm\nB_Busy\tinput.vhd\t/^constant B_Busy: \t\ttargetFsmType := \"101\";$/;\"\tc\tarchitecture:pci_target.fsm\nBackoff\tinput.vhd\t/^constant Backoff: \ttargetFsmType := \"010\";$/;\"\tc\tarchitecture:pci_target.fsm\nS_Data\tinput.vhd\t/^constant S_Data: \t\ttargetFsmType := \"011\";$/;\"\tc\tarchitecture:pci_target.fsm\nTurn_Ar\tinput.vhd\t/^constant Turn_Ar: \ttargetFsmType := \"110\";$/;\"\tc\tarchitecture:pci_target.fsm\nDont_Care\tinput.vhd\t/^constant Dont_Care: targetFsmType := \"XXX\";$/;\"\tc\tarchitecture:pci_target.fsm\ncurrState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnextState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnxtStProc\tinput.vhd\t/^ nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,$/;\"\tQ\tarchitecture:pci_target.fsm\ncurStProc\tinput.vhd\t/^  curStProc: process (PCI_Clk, PCI_Reset_n) begin$/;\"\tQ\tarchitecture:pci_target.fsm\noutConProc\tinput.vhd\t/^  outConProc: process (currState, Ready, T_Abort, Cmd_Write,$/;\"\tQ\tarchitecture:pci_target.fsm\npci_target\tinput.vhd\t/^entity pci_target is port ($/;\"\te\nPCI_Frame_n\tinput.vhd\t/^  PCI_Frame_n: in std_logic;    -- PCI Frame#$/;\"\tq\tentity:pci_target\nPCI_Irdy_n\tinput.vhd\t/^  PCI_Irdy_n: in std_logic;     -- PCI Irdy#$/;\"\tq\tentity:pci_target\nHit\tinput.vhd\t/^  Hit: in std_logic;            -- Hit on address decode$/;\"\tq\tentity:pci_target\nD_Done\tinput.vhd\t/^  D_Done: in std_logic;         -- Device decode complete$/;\"\tq\tentity:pci_target\nTerm\tinput.vhd\t/^  Term: in std_logic;           -- Terminate transaction$/;\"\tq\tentity:pci_target\nReady\tinput.vhd\t/^  Ready: in std_logic;          -- Ready to transfer data$/;\"\tq\tentity:pci_target\nCmd_Write\tinput.vhd\t/^  Cmd_Write: in std_logic;      -- Command is Write$/;\"\tq\tentity:pci_target\nCmd_Read\tinput.vhd\t/^  Cmd_Read: in std_logic;       -- Command is Read$/;\"\tq\tentity:pci_target\nT_Abort\tinput.vhd\t/^  T_Abort: in std_logic;        -- Target error  - abort transaction$/;\"\tq\tentity:pci_target\nPCI_Clk\tinput.vhd\t/^  PCI_Clk: in std_logic;        -- PCI Clock$/;\"\tq\tentity:pci_target\nPCI_Reset_n\tinput.vhd\t/^  PCI_Reset_n: in std_logic;    -- PCI Reset#$/;\"\tq\tentity:pci_target\nPCI_Devsel_n\tinput.vhd\t/^  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#$/;\"\tq\tentity:pci_target\nPCI_Stop_n\tinput.vhd\t/^  PCI_Stop_n: out std_logic;    -- PCI Stop#$/;\"\tq\tentity:pci_target\nPCI_Trdy_n\tinput.vhd\t/^  PCI_Trdy_n: out std_logic;    -- PCI Trdy#$/;\"\tq\tentity:pci_target\nOE_AD\tinput.vhd\t/^  OE_AD: out std_logic;         -- PCI AD bus enable$/;\"\tq\tentity:pci_target\nOE_Trdy_n\tinput.vhd\t/^  OE_Trdy_n: out std_logic;     -- PCI Trdy# enable$/;\"\tq\tentity:pci_target\nOE_Stop_n\tinput.vhd\t/^  OE_Stop_n: out std_logic;     -- PCI Stop# enable$/;\"\tq\tentity:pci_target\nOE_Devsel_n\tinput.vhd\t/^  OE_Devsel_n: out std_logic    -- PCI Devsel# enable$/;\"\tq\tentity:pci_target\nfsm\tinput.vhd\t/^architecture fsm of pci_target is$/;\"\ta\tentity:pci_target\nLPCI_Devsel_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Trdy_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Stop_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\ntargetFsmType\tinput.vhd\t/^type targetFsmType is (Idle, B_Busy, Backoff, S_Data, Turn_Ar);$/;\"\tt\tarchitecture:pci_target.fsm\ncurrState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnextState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnxtStProc\tinput.vhd\t/^ nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,$/;\"\tQ\tarchitecture:pci_target.fsm\ncurStProc\tinput.vhd\t/^  curStProc: process (PCI_Clk, PCI_Reset_n) begin$/;\"\tQ\tarchitecture:pci_target.fsm\noutConProc\tinput.vhd\t/^  outConProc: process (currState, Ready, T_Abort, Cmd_Write,$/;\"\tQ\tarchitecture:pci_target.fsm\npci_target\tinput.vhd\t/^entity pci_target is port ($/;\"\te\nPCI_Frame_n\tinput.vhd\t/^  PCI_Frame_n: in std_logic;    -- PCI Frame#$/;\"\tq\tentity:pci_target\nPCI_Irdy_n\tinput.vhd\t/^  PCI_Irdy_n: in std_logic;     -- PCI Irdy#$/;\"\tq\tentity:pci_target\nHit\tinput.vhd\t/^  Hit: in std_logic;            -- Hit on address decode$/;\"\tq\tentity:pci_target\nD_Done\tinput.vhd\t/^  D_Done: in std_logic;         -- Device decode complete$/;\"\tq\tentity:pci_target\nTerm\tinput.vhd\t/^  Term: in std_logic;           -- Terminate transaction$/;\"\tq\tentity:pci_target\nReady\tinput.vhd\t/^  Ready: in std_logic;          -- Ready to transfer data$/;\"\tq\tentity:pci_target\nCmd_Write\tinput.vhd\t/^  Cmd_Write: in std_logic;      -- Command is Write$/;\"\tq\tentity:pci_target\nCmd_Read\tinput.vhd\t/^  Cmd_Read: in std_logic;       -- Command is Read$/;\"\tq\tentity:pci_target\nT_Abort\tinput.vhd\t/^  T_Abort: in std_logic;        -- Target error  - abort transaction$/;\"\tq\tentity:pci_target\nPCI_Clk\tinput.vhd\t/^  PCI_Clk: in std_logic;        -- PCI Clock$/;\"\tq\tentity:pci_target\nPCI_Reset_n\tinput.vhd\t/^  PCI_Reset_n: in std_logic;    -- PCI Reset#$/;\"\tq\tentity:pci_target\nPCI_Devsel_n\tinput.vhd\t/^  PCI_Devsel_n: out std_logic;  -- PCI Devsel#$/;\"\tq\tentity:pci_target\nPCI_Trdy_n\tinput.vhd\t/^  PCI_Trdy_n: out std_logic;    -- PCI Trdy#$/;\"\tq\tentity:pci_target\nPCI_Stop_n\tinput.vhd\t/^  PCI_Stop_n: out std_logic;    -- PCI Stop#$/;\"\tq\tentity:pci_target\nOE_AD\tinput.vhd\t/^  OE_AD: out std_logic;         -- PCI AD bus enable$/;\"\tq\tentity:pci_target\nOE_Trdy_n\tinput.vhd\t/^  OE_Trdy_n: out std_logic;     -- PCI Trdy# enable$/;\"\tq\tentity:pci_target\nOE_Stop_n\tinput.vhd\t/^  OE_Stop_n: out std_logic;     -- PCI Stop# enable$/;\"\tq\tentity:pci_target\nOE_Devsel_n\tinput.vhd\t/^  OE_Devsel_n: out std_logic    -- PCI Devsel# enable$/;\"\tq\tentity:pci_target\nfsm\tinput.vhd\t/^architecture fsm of pci_target is$/;\"\ta\tentity:pci_target\nLPCI_Devsel_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Trdy_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Stop_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\ntargetFsmType\tinput.vhd\t/^subtype targetFsmType is std_logic_vector(4 downto 0);$/;\"\tT\tarchitecture:pci_target.fsm\nIdle\tinput.vhd\t/^constant Idle:    integer := 0;$/;\"\tc\tarchitecture:pci_target.fsm\nB_Busy\tinput.vhd\t/^constant B_Busy:  integer := 1;$/;\"\tc\tarchitecture:pci_target.fsm\nBackoff\tinput.vhd\t/^constant Backoff: integer := 2;$/;\"\tc\tarchitecture:pci_target.fsm\nS_Data\tinput.vhd\t/^constant S_Data:  integer := 3;$/;\"\tc\tarchitecture:pci_target.fsm\nTurn_Ar\tinput.vhd\t/^constant Turn_Ar: integer := 4;$/;\"\tc\tarchitecture:pci_target.fsm\ncurrState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnextState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnxtStProc\tinput.vhd\t/^ nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,$/;\"\tQ\tarchitecture:pci_target.fsm\ncurStProc\tinput.vhd\t/^  curStProc: process (PCI_Clk, PCI_Reset_n) begin$/;\"\tQ\tarchitecture:pci_target.fsm\noutConProc\tinput.vhd\t/^  outConProc: process (currState, Ready, T_Abort, Cmd_Write,$/;\"\tQ\tarchitecture:pci_target.fsm\npci_target\tinput.vhd\t/^entity pci_target is port ($/;\"\te\nPCI_Frame_n\tinput.vhd\t/^  PCI_Frame_n: in std_logic;\t-- PCI Frame#$/;\"\tq\tentity:pci_target\nPCI_Irdy_n\tinput.vhd\t/^  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#$/;\"\tq\tentity:pci_target\nHit\tinput.vhd\t/^  Hit: in std_logic;\t\t\t-- Hit on address decode$/;\"\tq\tentity:pci_target\nD_Done\tinput.vhd\t/^  D_Done: in std_logic;\t\t\t-- Device decode complete$/;\"\tq\tentity:pci_target\nTerm\tinput.vhd\t/^  Term: in std_logic;\t\t\t-- Terminate transaction$/;\"\tq\tentity:pci_target\nReady\tinput.vhd\t/^  Ready: in std_logic;\t\t\t-- Ready to transfer data$/;\"\tq\tentity:pci_target\nCmd_Write\tinput.vhd\t/^  Cmd_Write: in std_logic;\t\t-- Command is Write$/;\"\tq\tentity:pci_target\nCmd_Read\tinput.vhd\t/^  Cmd_Read: in std_logic;\t\t-- Command is Read$/;\"\tq\tentity:pci_target\nT_Abort\tinput.vhd\t/^  T_Abort: in std_logic;\t\t-- Target error  - abort transaction$/;\"\tq\tentity:pci_target\nPCI_Clk\tinput.vhd\t/^  PCI_Clk: in std_logic;\t\t-- PCI Clock$/;\"\tq\tentity:pci_target\nPCI_Reset_n\tinput.vhd\t/^  PCI_Reset_n: in std_logic;\t-- PCI Reset#$/;\"\tq\tentity:pci_target\nPCI_Devsel_n\tinput.vhd\t/^  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#$/;\"\tq\tentity:pci_target\nPCI_Trdy_n\tinput.vhd\t/^  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#$/;\"\tq\tentity:pci_target\nPCI_Stop_n\tinput.vhd\t/^  PCI_Stop_n: out std_logic;\t-- PCI Stop#$/;\"\tq\tentity:pci_target\nOE_AD\tinput.vhd\t/^  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable$/;\"\tq\tentity:pci_target\nOE_Trdy_n\tinput.vhd\t/^  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable$/;\"\tq\tentity:pci_target\nOE_Stop_n\tinput.vhd\t/^  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable$/;\"\tq\tentity:pci_target\nOE_Devsel_n\tinput.vhd\t/^  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable$/;\"\tq\tentity:pci_target\nfsm\tinput.vhd\t/^architecture fsm of pci_target is$/;\"\ta\tentity:pci_target\nLPCI_Devsel_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Trdy_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Stop_n\tinput.vhd\t/^signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\ntargetFsmType\tinput.vhd\t/^subtype targetFsmType is std_logic_vector(2 downto 0);$/;\"\tT\tarchitecture:pci_target.fsm\nIdle\tinput.vhd\t/^constant Idle: \t\ttargetFsmType := \"000\";$/;\"\tc\tarchitecture:pci_target.fsm\nB_Busy\tinput.vhd\t/^constant B_Busy: \ttargetFsmType := \"001\";$/;\"\tc\tarchitecture:pci_target.fsm\nBackoff\tinput.vhd\t/^constant Backoff: \ttargetFsmType := \"011\";$/;\"\tc\tarchitecture:pci_target.fsm\nS_Data\tinput.vhd\t/^constant S_Data: \ttargetFsmType := \"110\";$/;\"\tc\tarchitecture:pci_target.fsm\nTurn_Ar\tinput.vhd\t/^constant Turn_Ar: \ttargetFsmType := \"100\";$/;\"\tc\tarchitecture:pci_target.fsm\ncurrState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnextState\tinput.vhd\t/^signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnxtStProc\tinput.vhd\t/^ nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,$/;\"\tQ\tarchitecture:pci_target.fsm\ncurStProc\tinput.vhd\t/^  curStProc: process (PCI_Clk, PCI_Reset_n) begin$/;\"\tQ\tarchitecture:pci_target.fsm\noutConProc\tinput.vhd\t/^  outConProc: process (currState, Ready, T_Abort, Cmd_Write,$/;\"\tQ\tarchitecture:pci_target.fsm\npci_target\tinput.vhd\t/^entity pci_target is port ($/;\"\te\nPCI_Frame_n\tinput.vhd\t/^  PCI_Frame_n: in std_logic;    -- PCI Frame#$/;\"\tq\tentity:pci_target\nPCI_Irdy_n\tinput.vhd\t/^  PCI_Irdy_n: in std_logic;     -- PCI Irdy#$/;\"\tq\tentity:pci_target\nHit\tinput.vhd\t/^  Hit: in std_logic;            -- Hit on address decode$/;\"\tq\tentity:pci_target\nD_Done\tinput.vhd\t/^  D_Done: in std_logic;         -- Device decode complete$/;\"\tq\tentity:pci_target\nTerm\tinput.vhd\t/^  Term: in std_logic;           -- Terminate transaction$/;\"\tq\tentity:pci_target\nReady\tinput.vhd\t/^  Ready: in std_logic;          -- Ready to transfer data$/;\"\tq\tentity:pci_target\nCmd_Write\tinput.vhd\t/^  Cmd_Write: in std_logic;      -- Command is Write$/;\"\tq\tentity:pci_target\nCmd_Read\tinput.vhd\t/^  Cmd_Read: in std_logic;       -- Command is Read$/;\"\tq\tentity:pci_target\nT_Abort\tinput.vhd\t/^  T_Abort: in std_logic;        -- Target error  - abort transaction$/;\"\tq\tentity:pci_target\nPCI_Clk\tinput.vhd\t/^  PCI_Clk: in std_logic;        -- PCI Clock$/;\"\tq\tentity:pci_target\nPCI_Reset_n\tinput.vhd\t/^  PCI_Reset_n: in std_logic;    -- PCI Reset#$/;\"\tq\tentity:pci_target\nPCI_Devsel_n\tinput.vhd\t/^  PCI_Devsel_n: out std_logic;  -- PCI Devsel#$/;\"\tq\tentity:pci_target\nPCI_Trdy_n\tinput.vhd\t/^  PCI_Trdy_n: out std_logic;    -- PCI Trdy#$/;\"\tq\tentity:pci_target\nPCI_Stop_n\tinput.vhd\t/^  PCI_Stop_n: out std_logic;    -- PCI Stop#$/;\"\tq\tentity:pci_target\nOE_AD\tinput.vhd\t/^  OE_AD: out std_logic;         -- PCI AD bus enable$/;\"\tq\tentity:pci_target\nOE_Trdy_n\tinput.vhd\t/^  OE_Trdy_n: out std_logic;     -- PCI Trdy# enable$/;\"\tq\tentity:pci_target\nOE_Stop_n\tinput.vhd\t/^  OE_Stop_n: out std_logic;     -- PCI Stop# enable$/;\"\tq\tentity:pci_target\nOE_Devsel_n\tinput.vhd\t/^  OE_Devsel_n: out std_logic    -- PCI Devsel# enable$/;\"\tq\tentity:pci_target\nfsm\tinput.vhd\t/^architecture fsm of pci_target is$/;\"\ta\tentity:pci_target\nLPCI_Devsel_n\tinput.vhd\t/^  signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Trdy_n\tinput.vhd\t/^  signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\nLPCI_Stop_n\tinput.vhd\t/^  signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;$/;\"\ts\tarchitecture:pci_target.fsm\ntargetFsmType\tinput.vhd\t/^  subtype targetFsmType is std_logic_vector(2 downto 0);$/;\"\tT\tarchitecture:pci_target.fsm\nIdle\tinput.vhd\t/^  constant Idle:    targetFsmType := \"000\";$/;\"\tc\tarchitecture:pci_target.fsm\nB_Busy\tinput.vhd\t/^  constant B_Busy:  targetFsmType := \"001\";$/;\"\tc\tarchitecture:pci_target.fsm\nBackoff\tinput.vhd\t/^  constant Backoff: targetFsmType := \"011\";$/;\"\tc\tarchitecture:pci_target.fsm\nS_Data\tinput.vhd\t/^  constant S_Data:  targetFsmType := \"110\";$/;\"\tc\tarchitecture:pci_target.fsm\nTurn_Ar\tinput.vhd\t/^  constant Turn_Ar: targetFsmType := \"100\";$/;\"\tc\tarchitecture:pci_target.fsm\ncurrState\tinput.vhd\t/^  signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnextState\tinput.vhd\t/^  signal currState, nextState: targetFsmType;$/;\"\ts\tarchitecture:pci_target.fsm\nnxtStProc\tinput.vhd\t/^ nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,$/;\"\tQ\tarchitecture:pci_target.fsm\ncurStProc\tinput.vhd\t/^  curStProc: process (PCI_Clk, PCI_Reset_n) begin$/;\"\tQ\tarchitecture:pci_target.fsm\noutConProc\tinput.vhd\t/^  outConProc: process (currState, Ready, T_Abort, Cmd_Write,$/;\"\tQ\tarchitecture:pci_target.fsm\ntest\tinput.vhd\t/^entity test is port ($/;\"\te\na\tinput.vhd\t/^  a: in std_logic;$/;\"\tq\tentity:test\nz\tinput.vhd\t/^  z: out std_logic;$/;\"\tq\tentity:test\nen\tinput.vhd\t/^  en: in std_logic$/;\"\tq\tentity:test\nsimple\tinput.vhd\t/^architecture simple of test is$/;\"\ta\tentity:test\n"
  },
  {
    "path": "Units/review-needed.r/test.vhd.t/input.vhd",
    "content": "package body badger is\nend package body;\n\npackage body badger2 is\nend package body badger2;\n\n-- Incorporates Errata 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity accumulator is port (\n  a: in std_logic_vector(3 downto 0);\n  clk, reset: in std_logic;\n  accum: out std_logic_vector(3 downto 0)\n  );\nend accumulator;\n\narchitecture simple of accumulator is\n\nsignal accumL: unsigned(3 downto 0);\n\nbegin\n\n  accumulate: process (clk, reset) begin\n    if (reset = '1') then\n      accumL <= \"0000\";\n    elsif (clk'event and clk= '1') then\n      accumL <= accumL + to_unsigned(a);\n    end if;\n  end process;\n\n  accum <= std_logic_vector(accumL);\n\nend simple;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.std_logic_unsigned.all;\n\nentity adder is port (\n  a,b : in std_logic_vector (15 downto 0);\n  sum: out std_logic_vector (15 downto 0)\n  );\nend adder;\n\narchitecture dataflow of adder is\n\nbegin\n\n  sum <= a + b;\n\nend dataflow;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity pAdderAttr is\n  generic(n : integer := 8);\n  port (a    : in std_logic_vector(n - 1 downto 0);\n        b    : in std_logic_vector(n - 1 downto 0);\n        cin  : in std_logic;\n        sum  : out std_logic_vector(n - 1 downto 0);\n        cout : out std_logic);\nend pAdderAttr;\n\n\narchitecture loopDemo of pAdderAttr is\n\nbegin\n\n  process(a, b, cin)\n    variable carry: std_logic_vector(sum'length downto 0);\n    variable localSum: std_logic_vector(sum'high downto 0);\n\n  begin\n\n    carry(0) := cin;\n\n    for i in sum'reverse_range loop\n      localSum(i)  := (a(i) xor b(i)) xor carry(i);\n      carry(i + 1) := (a(i) and b(i)) or (carry(i) and (a(i) or b(i)));\n    end loop;\n\n    sum <= localSum;\n    cout <= carry(carry'high - 1);\n\n  end process;\n\nend loopDemo;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity adder is port (\n  a,b: in unsigned(3 downto 0);\n  sum: out unsigned(3 downto 0)\n  );\nend adder;\n\narchitecture simple of adder is\n\nbegin\n\n  sum <= a + b;\n\nend simple;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity AND2 is port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\nend AND2;\n\narchitecture rtl of AND2 is\n\nbegin\n\n  y <= '1' when i1 = '1' and i2 = '1' else '0';\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity asyncLoad is port (\n  loadVal, d: in std_logic_vector(3 downto 0);\n  clk, load: in std_logic;\n  q: out std_logic_vector(3 downto 0)\n  );\nend asyncLoad;\n\narchitecture rtl of asyncLoad is\n\nbegin\n\n  process (clk, load, loadVal) begin\n    if (load = '1') then\n      q <= loadVal;\n    elsif (clk'event and clk = '1' ) then\n      q <= d;\n    end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.std_logic_unsigned.all;\n\nentity BidirBuf is port (\n  OE: in std_logic;\n  input: in std_logic_vector;\n  output: out std_logic_vector\n  );\nend BidirBuf;\n\narchitecture behavioral of BidirBuf is\n\nbegin\n\n  bidirBuf: process (OE, input) begin\n    if (OE = '1') then\n      output <= input;\n    else\n      output <= (others => 'Z');\n    end if;\n  end process;\n\nend behavioral;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity BidirCnt is port (\n  OE: in std_logic;\n  CntEnable: in std_logic;\n  LdCnt: in std_logic;\n  Clk: in std_logic;\n  Rst: in std_logic;\n  Cnt: inout std_logic_vector(3 downto 0)\n  );\nend BidirCnt;\n\narchitecture behavioral of BidirCnt is\n\n  component LoadCnt port (\n    CntEn: in std_logic;\n    LdCnt: in std_logic;\n    LdData: in std_logic_vector(3 downto 0);\n    Clk: in std_logic;\n    Rst: in std_logic;\n    CntVal: out std_logic_vector(3 downto 0)\n    );\n  end component;\n\n  component BidirBuf port (\n    OE: in std_logic;\n    input: in std_logic_vector;\n    output: inout std_logic_vector\n    );\n  end component;\n\nsignal CntVal: std_logic_vector(3 downto 0);\nsignal LoadVal: std_logic_vector(3 downto 0);\n\nbegin\n\n  u1: loadcnt port map (CntEn => CntEnable,\n                        LdCnt => LdCnt,\n                        LdData => LoadVal,\n                        Clk => Clk,\n                        Rst => Rst,\n                        CntVal => CntVal\n                        );\n\n  u2: bidirbuf port map (OE => oe,\n                         input => CntVal,\n                         output => Cnt\n                        );\n\n  LoadVal <= Cnt;\n\nend behavioral;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity BIDIR is port (\n  ip: in std_logic;\n  oe: in std_logic;\n  op_fb: out std_logic;\n  op: inout std_logic\n  );\nend BIDIR;\n\narchitecture rtl of BIDIR is\n\nbegin\n\n  op <= ip when oe = '1' else 'Z';\n  op_fb <= op;\n\nend rtl;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nuse work.primitive.all;\n\nentity bidirbuffer is port (\n  input: in std_logic;\n  enable: in std_logic;\n  feedback: out std_logic;\n  output: inout std_logic\n  );\nend bidirbuffer;\n\narchitecture structural of bidirbuffer is\n\nbegin\n\n  u1: bidir port map (ip => input,\n                      oe => enable,\n                      op_fb => feedback,\n                      op => output\n                      );\n\nend structural;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity clkGen is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  ClkDiv2, ClkDiv4,\n  ClkDiv6,ClkDiv8: out std_logic\n  );\nend clkGen;\n \narchitecture behav of clkGen is\n\nsubtype numClks is std_logic_vector(1 to 4);\nsubtype numPatterns is integer range 0 to 11;\n\ntype clkTableType is array (numpatterns'low to numPatterns'high) of numClks;\n\nconstant clkTable: clkTableType := clkTableType'(\n-- ClkDiv8______\n-- ClkDiv6_____ |\n-- ClkDiv4____ ||\n-- ClkDiv2 __ |||\n--           ||||\n            \"1111\",\n            \"0111\",\n            \"1011\",\n            \"0001\",\n            \"1100\",\n            \"0100\",\n            \"1010\",\n            \"0010\",\n            \"1111\",\n            \"0001\",\n            \"1001\",\n            \"0101\"); \n\nsignal index: numPatterns;\n \nbegin\n\n  lookupTable: process (clk, reset) begin\n    if reset = '1' then\n      index <= 0;\n    elsif (clk'event and clk = '1') then\n      if index = numPatterns'high then\n        index <= numPatterns'low;\n      else\n        index <= index + 1;\n      end if;\n    end if;\n  end process;\n\n  (ClkDiv2,ClkDiv4,ClkDiv6,ClkDiv8) <= clkTable(index);\n\nend behav;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  enable: in std_logic;\n  reset: in std_logic;\n  count: buffer unsigned(3 downto 0)\n  );\nend counter;\n\narchitecture simple of counter is\n\nbegin\n\n  increment: process (clk, reset) begin\n    if reset = '1' then\n      count <= \"0000\";\n    elsif(clk'event and clk = '1') then\n      if enable = '1' then\n        count <= count + 1;\n      else\n        count <= count;\n      end if;\n    end if;\n  end process;\n\nend simple;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nuse work.scaleable.all;\n\nentity count8 is port (\n  clk: in std_logic;\n  rst: in std_logic;\n  count: out std_logic_vector(7 downto 0)\n  );\nend count8;\n\narchitecture structural of count8 is\n\nbegin\n\n  u1: scaleUpCnt port map (clk => clk,\n                           reset => rst,\n                           cnt => count\n                          );\n\nend structural;\n-- Incorporates Errata 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  count: out std_logic_vector(0 to 9)\n  );\nend counter;\n\narchitecture simple of counter is\n\nsignal countL: unsigned(0 to 9);\n\nbegin\n\n  increment: process (clk, reset) begin\n    if reset = '1' then\n      countL <= to_unsigned(3,10);\n    elsif(clk'event and clk = '1') then\n      countL <= countL + 1;\n    end if;\n  end process;\n  \n  count <= std_logic_vector(countL);\n\nend simple;\n-- Incorporates Errata 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  count: out std_logic_vector(9 downto 0)\n  );\nend counter;\n\narchitecture simple of counter is\n\nsignal countL: unsigned(9 downto 0);\n\nbegin\n\n  increment: process (clk, reset) begin\n    if reset = '1' then\n      countL <= to_unsigned(0,10);\n    elsif(clk'event and clk = '1') then\n      countL <= countL + 1;\n    end if;\n  end process;\n  \n  count <= std_logic_vector(countL);\n\nend simple;\n-- Incorporates Errata 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  load: in std_logic;\n  enable: in std_logic;\n  data: in std_logic_vector(3 downto 0);\n  count: out std_logic_vector(3 downto 0)\n  );\nend counter;\n\narchitecture simple of counter is\n\nsignal countL: unsigned(3 downto 0);\n\nbegin\n\n  increment: process (clk, reset) begin\n    if (reset = '1') then\n      countL <= \"0000\";\n    elsif(clk'event and clk = '1') then\n      if (load = '1') then\n        countL <= to_unsigned(data);\n      elsif (enable = '1') then\n        countL <= countL + 1;\n      end if;\n    end if;\n  end process;\n  \n  count <= std_logic_vector(countL);\n\nend simple;\n-- Incorporates Errata 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  load: in std_logic;\n  data: in std_logic_vector(3 downto 0);\n  count: out std_logic_vector(3 downto 0)\n  );\nend counter;\n\narchitecture simple of counter is\n\nsignal countL: unsigned(3 downto 0);\n\nbegin\n\n  increment: process (clk, reset) begin\n    if (reset = '1') then\n      countL <= \"0000\";\n    elsif(clk'event and clk = '1') then\n      if (load = '1') then\n        countL <= to_unsigned(data);\n      else\n        countL <= countL + 1;\n      end if;\n    end if;\n  end process;\n  \n  count <= std_logic_vector(countL);\n\nend simple;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.numeric_std.all;\n\nentity Cnt4Term is port (\n  clk: in std_logic;\n  Cnt: out std_logic_vector(3 downto 0);\n  TermCnt: out std_logic\n  );\nend Cnt4Term;\n\narchitecture behavioral of Cnt4Term is\n\nsignal CntL: unsigned(3 downto 0);\n\nbegin\n\n  increment: process begin\n    wait until clk = '1';\n      CntL <= CntL + 1;\n  end process;\n\n  Cnt <= to_stdlogicvector(CntL);\n\n  TermCnt <= '1' when CntL = \"1111\" else '0';\n\nend behavioral;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity Counter is port (\n  clock: in std_logic;\n  Count: out std_logic_vector(3 downto 0)\n  );\nend Counter;\n\narchitecture structural of Counter is\n\n  component Cnt4Term port (\n    clk: in std_logic;\n    Cnt: out std_logic_vector(3 downto 0);\n    TermCnt: out std_logic);\n  end component;\n\nbegin\n\n  u1: Cnt4Term port map (clk => clock,\n                         Cnt => Count,\n                         TermCnt => open\n                    );\n\nend structural;\n-- Incorporates Errata 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  count: out std_logic_vector(3 downto 0)\n  );\nend counter;\n\narchitecture simple of counter is\n\nsignal countL: unsigned(3 downto 0);\n\nbegin\n\n  increment: process (clk) begin\n    if(clk'event and clk = '1') then\n      if (reset = '1') then\n        countL <= \"0000\";\n      else\n        countL <= countL + 1;\n      end if;\n    end if;\n  end process;\n  \n  count <= std_logic_vector(countL);\n\nend simple;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.numeric_std.all;\n\nentity convertArith is port (\n  truncate: out unsigned(3 downto 0);\n  extend: out unsigned(15 downto 0);\n  direction: out unsigned(0 to 7)\n  );\nend convertArith;\n\narchitecture simple of convertArith is\n\nconstant Const: unsigned(7 downto 0) := \"00111010\";\n\nbegin\n\n  truncate  <= resize(Const, truncate'length);\n  extend    <= resize(Const, extend'length);\n  direction <= resize(Const, direction'length);\n\nend simple;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.numeric_std.all;\n\nentity FEWGATES is port (\n  a,b,c,d: in std_logic;\n  y: out std_logic\n  );\nend FEWGATES;\n\narchitecture concurrent of FEWGATES is\n\nconstant THREE: std_logic_vector(1 downto 0) := \"11\";\n\nbegin\n\n  y <= '1' when (a & b = THREE) or (c & d /= THREE) else '0';\n\nend concurrent;\n-- incorporates Errata 12.1\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.numeric_std.all;\n\nentity typeConvert is port (\n  a: out unsigned(7 downto 0)\n  );\nend typeConvert;\n\narchitecture simple of typeConvert is\n\nconstant Const: natural := 43;\n\nbegin\n\n  a <= To_unsigned(Const,8);\n\nend simple;\n-- Incorporates Errata 5.4 \n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  count: out std_logic_vector(3 downto 0)\n  );\nend counter;\n\narchitecture simple of counter is\n\nsignal countL: unsigned(3 downto 0);\n\nbegin\n\n  increment: process (clk) begin\n    if (clk'event and clk = '1') then\n      countL <= countL + 1;\n    end if;\n  end process;\n\n  count <= std_logic_vector(countL);\n\nend simple;\n-- Incorporates Errata 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  count: out std_logic_vector(0 to 3)\n  );\nend counter;\n\narchitecture simple of counter is\n\nsignal countL: unsigned(0 to 3);\n\nbegin\n\n  increment: process (clk, reset) begin\n    if reset = '1' then\n      countL <= \"1001\";\n    elsif(clk'event and clk = '1') then\n      countL <= countL + 1;\n    end if;\n  end process;\n  \n  count <= std_logic_vector(countL);\n\nend simple;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  count: out std_logic_vector(3 downto 0)\n  );\nend counter;\n\narchitecture simple of counter is\n\nsignal countL: unsigned(3 downto 0);\n\nbegin\n\n  increment: process (clk, reset) begin\n    if (reset = '1') then\n      countL <= \"0000\";\n    elsif(clk'event and clk = '1') then\n      countL <= countL + \"001\";\n    end if;\n  end process;\n  \n  count <= std_logic_vector(countL);\n\nend simple;\n-- Incorporates Errata 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  count: out std_logic_vector(3 downto 0)\n  );\nend counter;\n\narchitecture simple of counter is\n\nsignal countL: unsigned(3 downto 0);\n\nbegin\n\n  increment: process (clk, reset) begin\n    if reset = '1' then\n      countL <= \"1001\";\n    elsif(clk'event and clk = '1') then\n      countL <= countL + 1;\n    end if;\n  end process;\n  \n  count <= std_logic_vector(countL);\n\nend simple;\n-- Incorporates Errata 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity counter is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  count: out std_logic_vector(3 downto 0)\n  );\nend counter;\n\narchitecture simple of counter is\n\nsignal countL: unsigned(3 downto 0);\n\nbegin\n\n  increment: process (clk, reset) begin\n    if (reset = '1') then\n      countL <= \"1001\";\n    elsif(clk'event and clk = '1') then\n      countL <= countL + \"0001\";\n    end if;\n  end process;\n  \n  count <= std_logic_vector(countL);\n\nend simple;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nuse work.decProcs.all;\n\nentity decoder is port (\n  decIn: in std_logic_vector(1 downto 0);\n  decOut: out std_logic_vector(3 downto 0)\n  );\nend decoder;\n\narchitecture simple of decoder is\n\nbegin\n\n  DEC2x4(decIn,decOut);\n\nend simple;\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity isa_dec is port\n(\n  dev_adr:          in std_logic_vector(19 downto 0);\n\n  decOut_n:         out std_logic_vector(5 downto 0)\n\n);\nend isa_dec;\n\n\narchitecture synthesis of isa_dec is\n\n  constant  CtrlRegRange: std_logic_vector(2 downto 0)    := \"100\";\n  constant  SuperIoRange: std_logic_vector(2 downto 0)    := \"010\";\n\n  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";\n  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";\n  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";\n  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";\n  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";\n\n  alias sio_dec_n: std_logic is        decOut_n(5);\n  alias rst_ctrl_rd_n: std_logic is    decOut_n(4);\n  alias atc_stat_rd_n: std_logic is    decOut_n(3);\n  alias mgmt_stat_rd_n: std_logic is   decOut_n(2);\n  alias io_int_stat_rd_n: std_logic is decOut_n(1);\n  alias int_ctrl_rd_n: std_logic is    decOut_n(0);\n\n  alias upper: std_logic_vector(2 downto 0) is dev_adr(19 downto 17);\n  alias CtrlBits: std_logic_vector(16 downto 0) is dev_adr(16 downto 0);\n\nbegin\n\n  decoder: process (upper, CtrlBits)\n    begin \n      -- Set defaults for outputs - for synthesis reasons.\n\n        sio_dec_n        <= '1';\n        int_ctrl_rd_n    <= '1';\n        io_int_stat_rd_n <= '1';\n        rst_ctrl_rd_n    <= '1';\n        atc_stat_rd_n    <= '1';\n        mgmt_stat_rd_n   <= '1';\n\n        case upper is \n\n        when SuperIoRange =>\n          sio_dec_n <= '0';\n\t\t\n        when CtrlRegRange =>\n\n          case CtrlBits is\n\t\t\t\n            when IntCtrlReg =>\n              int_ctrl_rd_n <= '0';\n\n            when IoIntStatReg =>\n              io_int_stat_rd_n <= '0';\n\n            when RstCtrlReg =>\n              rst_ctrl_rd_n <= '0';\n\n            when AtcStatusReg =>\n              atc_stat_rd_n <= '0';\n\n            when MgmtStatusReg =>\n              mgmt_stat_rd_n <= '0';\n\n            when others =>\n              null;\n\t\t\t\t\t\t\t\n            end case;\n\n          when others =>\n            null;                     \n\t\t\t\t\t\n        end case;\n\n  end process decoder;\n\nend synthesis;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity isa_dec is port\n(\n  dev_adr:          in std_logic_vector(19 downto 0);\n\n  sio_dec_n:        out std_logic;\n  rst_ctrl_rd_n:    out std_logic;\n  atc_stat_rd_n:    out std_logic;\n  mgmt_stat_rd_n:   out std_logic;\n  io_int_stat_rd_n: out std_logic;\n  int_ctrl_rd_n:    out std_logic\n);\nend isa_dec;\n\n\narchitecture synthesis of isa_dec is\n\n  constant  CtrlRegRange: std_logic_vector(2 downto 0)    := \"100\";\n  constant  SuperIoRange: std_logic_vector(2 downto 0)    := \"010\";\n\n  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";\n  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";\n  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";\n  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";\n  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";\n\nbegin\n\n  decoder: process (dev_adr)\n    begin \n      -- Set defaults for outputs\n\n        sio_dec_n        <= '1';\n        int_ctrl_rd_n    <= '1';\n        io_int_stat_rd_n <= '1';\n        rst_ctrl_rd_n    <= '1';\n        atc_stat_rd_n    <= '1';\n        mgmt_stat_rd_n   <= '1';\n\n        case dev_adr(19 downto 17) is \n\n        when SuperIoRange =>\n          sio_dec_n <= '0';\n\t\t\n        when CtrlRegRange =>\n\n          case dev_adr(16 downto 0) is\n\t\t\t\n            when IntCtrlReg =>\n              int_ctrl_rd_n <= '0';\n\n            when IoIntStatReg =>\n              io_int_stat_rd_n <= '0';\n\n            when RstCtrlReg =>\n              rst_ctrl_rd_n <= '0';\n\n            when AtcStatusReg =>\n              atc_stat_rd_n <= '0';\n\n            when MgmtStatusReg =>\n              mgmt_stat_rd_n <= '0';\n\n            when others =>\n              null;\n\t\t\t\t\t\t\t\n            end case;\n\n          when others =>\n            null;                     \n\t\t\t\t\t\n        end case;\n\n  end process decoder;\n\nend synthesis;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity isa_dec is port\n(\n  dev_adr:         in std_logic_vector(19 downto 0);\n\n  sio_dec_n:       out std_logic;\n  rst_ctrl_rd_n:   out std_logic;\n  atc_stat_rd_n:   out std_logic;\n  mgmt_stat_rd_n:  out std_logic;\n  io_int_stat_rd_n:out std_logic;\n  int_ctrl_rd_n:   out std_logic\n  );\nend isa_dec;\n\n\narchitecture synthesis of isa_dec is\n\n  constant  CtrlRegRange: std_logic_vector(2 downto 0)  := \"100\";\n  constant  SuperIoRange: std_logic_vector(2 downto 0)  := \"010\";\n\n  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";\n  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";\n  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";\n  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";\n  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";\n\nbegin\n  sio_dec_n <= '0' when dev_adr (19 downto 17) = SuperIORange else '1';\n\n  int_ctrl_rd_n <= '0' when (dev_adr (19 downto 17) = CtrlRegRange)\n                        and (dev_adr(16 downto 0) = IntCtrlReg) else '1';\n\n  io_int_stat_rd_n <= '0' when (dev_adr (19 downto 17) = CtrlRegRange)\n                           and (dev_adr(16 downto 0) = IoIntStatReg) else '1';\n\n  rst_ctrl_rd_n <= '0' when (dev_adr (19 downto 17) = CtrlRegRange)\n                        and (dev_adr(16 downto 0) = RstCtrlReg) else '1';\n\n  atc_stat_rd_n <= '0' when (dev_adr (19 downto 17) = CtrlRegRange)\n                        and (dev_adr(16 downto 0) = AtcStatusReg) else '1';\n\n  mgmt_stat_rd_n <= '0' when (dev_adr (19 downto 17) = CtrlRegRange)\n                         and (dev_adr(16 downto 0) = MgmtStatusReg) else '1';\n\n\nend synthesis;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity isa_dec is port\n(\n  dev_adr:          in std_logic_vector(19 downto 0);\n  cs0_n:            in std_logic;\n\n  sio_dec_n:        out std_logic;\n  rst_ctrl_rd_n:    out std_logic;\n  atc_stat_rd_n:    out std_logic;\n  mgmt_stat_rd_n:   out std_logic;\n  io_int_stat_rd_n: out std_logic;\n  int_ctrl_rd_n:    out std_logic\n);\nend isa_dec;\n\n\narchitecture synthesis of isa_dec is\n\n  constant  CtrlRegRange: std_logic_vector(2 downto 0)    := \"100\";\n  constant  SuperIoRange: std_logic_vector(2 downto 0)    := \"010\";\n\n  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";\n  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";\n  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";\n  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";\n  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";\n\nbegin\n\n  decoder: process (dev_adr, cs0_n)\n    begin \n      -- Set defaults for outputs - for synthesis reasons.\n\n        sio_dec_n        <= '1';\n        int_ctrl_rd_n    <= '1';\n        io_int_stat_rd_n <= '1';\n        rst_ctrl_rd_n    <= '1';\n        atc_stat_rd_n    <= '1';\n        mgmt_stat_rd_n   <= '1';\n\n        if (cs0_n = '0') then\n          case dev_adr(19 downto 17) is \n\n          when SuperIoRange =>\n            sio_dec_n <= '0';\n\t\t\n          when CtrlRegRange =>\n\n            case dev_adr(16 downto 0) is\n\t\t\t\n              when IntCtrlReg =>\n                int_ctrl_rd_n <= '0';\n\n              when IoIntStatReg =>\n                io_int_stat_rd_n <= '0';\n\n              when RstCtrlReg =>\n                rst_ctrl_rd_n <= '0';\n\n              when AtcStatusReg =>\n                atc_stat_rd_n <= '0';\n\n              when MgmtStatusReg =>\n                mgmt_stat_rd_n <= '0';\n\n              when others =>\n                null;\n\t\t\t\t\t\t\t\n              end case;\n\n            when others =>\n              null;                     \n                         \n          end case;\n        else\n          null;\n        end if;\n\n  end process decoder;\n\nend synthesis;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity isa_dec is port\n(\n  dev_adr:          in std_logic_vector(19 downto 0);\n  cs0_n:            in std_logic;\n\n  sio_dec_n:        out std_logic;\n  rst_ctrl_rd_n:    out std_logic;\n  atc_stat_rd_n:    out std_logic;\n  mgmt_stat_rd_n:   out std_logic;\n  io_int_stat_rd_n: out std_logic;\n  int_ctrl_rd_n:    out std_logic\n);\nend isa_dec;\n\n\narchitecture synthesis of isa_dec is\n\n  constant  CtrlRegRange: std_logic_vector(2 downto 0)    := \"100\";\n  constant  SuperIoRange: std_logic_vector(2 downto 0)    := \"010\";\n\n  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";\n  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";\n  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";\n  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";\n  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";\n\n  signal Lsio_dec_n:        std_logic;\n  signal Lrst_ctrl_rd_n:    std_logic;\n  signal Latc_stat_rd_n:    std_logic;\n  signal Lmgmt_stat_rd_n:   std_logic;\n  signal Lio_int_stat_rd_n: std_logic;\n  signal Lint_ctrl_rd_n:    std_logic;\n\nbegin\n\n  decoder: process (dev_adr)\n    begin \n      -- Set defaults for outputs - for synthesis reasons.\n\n        Lsio_dec_n        <= '1';\n        Lint_ctrl_rd_n    <= '1';\n        Lio_int_stat_rd_n <= '1';\n        Lrst_ctrl_rd_n    <= '1';\n        Latc_stat_rd_n    <= '1';\n        Lmgmt_stat_rd_n   <= '1';\n\n        case dev_adr(19 downto 17) is \n\n        when SuperIoRange =>\n          Lsio_dec_n <= '0';\n\t\t\n        when CtrlRegRange =>\n\n          case dev_adr(16 downto 0) is\n\t\t\t\n            when IntCtrlReg =>\n              Lint_ctrl_rd_n <= '0';\n\n            when IoIntStatReg =>\n              Lio_int_stat_rd_n <= '0';\n\n            when RstCtrlReg =>\n              Lrst_ctrl_rd_n <= '0';\n\n            when AtcStatusReg =>\n              Latc_stat_rd_n <= '0';\n\n            when MgmtStatusReg =>\n              Lmgmt_stat_rd_n <= '0';\n\n            when others =>\n              null;\n\t\t\t\t\t\t\t\n            end case;\n\n          when others =>\n            null;                     \n                         \n        end case;\n\n  end process decoder;\n\n  qualify: process (cs0_n) begin\n\n    sio_dec_n        <= '1';\n    int_ctrl_rd_n    <= '1';\n    io_int_stat_rd_n <= '1';\n    rst_ctrl_rd_n    <= '1';\n    atc_stat_rd_n    <= '1';\n    mgmt_stat_rd_n   <= '1';\n\n    if (cs0_n = '0') then\n      sio_dec_n        <= Lsio_dec_n;\n      int_ctrl_rd_n    <= Lint_ctrl_rd_n;\n      io_int_stat_rd_n <= Lio_int_stat_rd_n;\n      rst_ctrl_rd_n    <= Lrst_ctrl_rd_n;\n      atc_stat_rd_n    <= Latc_stat_rd_n;\n      mgmt_stat_rd_n   <= Lmgmt_stat_rd_n;\n    else\n      null;\n    end if;\n  end process qualify;\n\nend synthesis;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity isa_dec is port\n(\n  dev_adr:          in std_logic_vector(19 downto 0);\n\n  sio_dec_n:        out std_logic;\n  rst_ctrl_rd_n:    out std_logic;\n  atc_stat_rd_n:    out std_logic;\n  mgmt_stat_rd_n:   out std_logic;\n  io_int_stat_rd_n: out std_logic;\n  int_ctrl_rd_n:    out std_logic\n);\nend isa_dec;\n\n\narchitecture synthesis of isa_dec is\n\n  constant  CtrlRegRange: std_logic_vector(2 downto 0)    := \"100\";\n  constant  SuperIoRange: std_logic_vector(2 downto 0)    := \"010\";\n\n  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";\n  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";\n  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";\n  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";\n  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";\n\nbegin\n\n  decoder: process ( dev_adr)\n    begin \n      -- Set defaults for outputs - for synthesis reasons.\n\n        sio_dec_n        <= '1';\n        int_ctrl_rd_n    <= '1';\n        io_int_stat_rd_n <= '1';\n        rst_ctrl_rd_n    <= '1';\n        atc_stat_rd_n    <= '1';\n        mgmt_stat_rd_n   <= '1';\n\n        if dev_adr(19 downto 17) = SuperIOrange then\n\n          sio_dec_n <= '0';\n\n        elsif dev_adr(19 downto 17) = CtrlRegrange then\n\n          if dev_adr(16 downto 0) = IntCtrlReg then\n\n            int_ctrl_rd_n <= '0';\n\n          elsif dev_adr(16 downto 0)= IoIntStatReg then\n\n            io_int_stat_rd_n <= '0';\n\n          elsif dev_adr(16 downto 0) = RstCtrlReg then\n\n            rst_ctrl_rd_n <= '0';\n\n          elsif dev_adr(16 downto 0) = AtcStatusReg then\n\n            atc_stat_rd_n <= '0';\n\n          elsif dev_adr(16 downto 0) = MgmtStatusReg then\n\n            mgmt_stat_rd_n <= '0';\n\n          else\n\n            null;\n\t\t\t\t\t\t\t\n          end if;\n\n        else\n\n          null;\n\n        end if;\n\n  end process decoder;\n\nend synthesis;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\npackage decProcs is\n\n  procedure DEC2x4 (inputs : in std_logic_vector(1 downto 0);\n                    decode: out std_logic_vector(3 downto 0)\n                   );\nend decProcs;\n\npackage body decProcs is\n\n  procedure DEC2x4 (inputs : in std_logic_vector(1 downto 0);\n                    decode: out std_logic_vector(3 downto 0)\n                   ) is\n  begin\n    case inputs is\n      when \"11\" =>\n        decode := \"1000\";\n      when \"10\" =>\n        decode := \"0100\";\n      when \"01\" =>\n        decode := \"0010\";\n      when \"00\" =>\n        decode := \"0001\";\n      when others =>\n        decode := \"0001\";\n    end case;\n  end DEC2x4;\n\nend decProcs;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity isa_dec is port\n(\n  dev_adr:         in std_logic_vector(19 downto 0);\n\n  sio_dec_n:       out std_logic;\n  rst_ctrl_rd_n:   out std_logic;\n  atc_stat_rd_n:   out std_logic;\n  mgmt_stat_rd_n:  out std_logic;\n  io_int_stat_rd_n:out std_logic;\n  int_ctrl_rd_n:   out std_logic\n  );\nend isa_dec;\n\n\narchitecture synthesis of isa_dec is\n\n  constant  CtrlRegRange: std_logic_vector(2 downto 0)  := \"100\";\n  constant  SuperIoRange: std_logic_vector(2 downto 0)  := \"010\";\n\n  constant  IntCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000000\";\n  constant  IoIntStatReg: std_logic_vector(16 downto 0) := \"00000000000000001\";\n  constant  RstCtrlReg:   std_logic_vector(16 downto 0) := \"00000000000000010\";\n  constant  AtcStatusReg: std_logic_vector(16 downto 0) := \"00000000000000011\";\n  constant  MgmtStatusReg:std_logic_vector(16 downto 0) := \"00000000000000100\";\n\nbegin\n  with dev_adr(19 downto 17) select\n    sio_dec_n <= '0' when SuperIORange,\n                 '1' when others;\n\n  with dev_adr(19 downto 0) select\n    int_ctrl_rd_n <= '0' when CtrlRegRange & IntCtrlReg,\n                     '1' when others;\n\n  with dev_adr(19 downto 0) select\n    io_int_stat_rd_n <= '0' when CtrlRegRange & IoIntStatReg,\n                        '1' when others;\n\n  with dev_adr(19 downto 0) select\n    rst_ctrl_rd_n <= '0' when CtrlRegRange & RstCtrlReg,\n                     '1' when others;\n\n  with dev_adr(19 downto 0) select\n    atc_stat_rd_n <= '0' when CtrlRegRange & AtcStatusReg,\n                     '1' when others;\n\n  with dev_adr(19 downto 0) select\n    mgmt_stat_rd_n <= '0' when CtrlRegRange & MgmtStatusReg,\n                      '1' when others;\n\n\nend synthesis;\n-- Incorporates Errata 5.1 and 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity progPulse is port (\n  clk, reset: in std_logic;\n  loadLength,loadDelay: in std_logic;\n  data: in std_logic_vector(7 downto 0);\n  pulse: out std_logic\n  );\nend progPulse;\n\narchitecture rtl of progPulse is\n\nsignal delayCnt, pulseCnt: unsigned(7 downto 0);\nsignal delayCntVal, pulseCntVal: unsigned(7 downto 0);\nsignal startPulse, endPulse: std_logic;\n\nbegin\n\n  delayReg: process (clk, reset) begin\n    if reset = '1' then\n      delayCntVal <= \"11111111\";\n    elsif clk'event and clk = '1' then\n      if loadDelay = '1' then\n        delayCntVal <= unsigned(data);\n      end if;\n    end if;\n  end process;\n\n  lengthReg: process (clk, reset) begin\n    if reset = '1' then\n      pulseCntVal <= \"11111111\";\n    elsif clk'event and clk = '1' then\n      if loadLength = '1' then -- changed loadLength to loadDelay (Errata 5.1)\n        pulseCntVal <= unsigned(data);\n      end if;\n    end if;\n  end process;\n\n  pulseDelay: process (clk, reset) begin\n    if (reset = '1') then\n      delayCnt <= \"11111111\";\n    elsif(clk'event and clk = '1') then\n      if (loadDelay = '1' or loadLength = '1' or endPulse = '1') then -- changed startPulse to endPulse (Errata 5.1)\n        delayCnt <= delayCntVal;\n      elsif endPulse = '1' then\n        delayCnt <= delayCnt - 1;\n      end if;\n    end if;\n  end process;\n\n  startPulse <= '1' when delayCnt = \"00000000\" else '0';\n\n  pulseLength: process (clk, reset) begin\n    if (reset = '1') then\n      pulseCnt <= \"11111111\";\n    elsif (clk'event and clk = '1') then\n      if (loadLength = '1') then\n        pulseCnt <= pulseCntVal;\n      elsif (startPulse = '1' and endPulse = '1') then\n        pulseCnt <= pulseCntVal;\n      elsif (endPulse = '1') then\n        pulseCnt <= pulseCnt;\n      else\n        pulseCnt <= pulseCnt - 1;\n      end if;\n    end if;\n  end process;\n\n  endPulse <= '1' when pulseCnt = \"00000000\" else '0';\n\n  pulseOutput: process (clk, reset) begin\n    if (reset = '1') then\n      pulse <= '0';\n    elsif (clk'event and clk = '1') then\n      if (startPulse = '1') then\n        pulse <= '1';\n      elsif (endPulse = '1') then\n        pulse <= '0';\n      end if;\n    end if;\n  end process;\n        \n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    arst : in std_logic;\n    q: out std_logic;\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process (clk) begin\n    if arst = '1' then\n      q <= '0';\n    elsif clk'event and clk = '1' then\n        q <= d;\n    end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    a,b,c : in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process (clk, a,b,c) begin\n    if ((a = '1' and b = '1') or c = '1') then\n      q <= '0';\n    elsif clk'event and clk = '1' then\n        q <= d;\n    end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    a,b,c : in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nsignal localRst: std_logic;\n\nbegin\n\n  localRst <= '1' when (( a = '1' and b = '1') or c = '1') else '0';\n\n  process (clk, localRst) begin\n    if localRst = '1' then\n      q <= '0';\n    elsif clk'event and clk = '1' then\n        q <= d;\n    end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    arst: in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process (clk, arst) begin\n    if arst = '1' then\n      q <= '0';\n    elsif clk'event and clk = '1' then\n        q <= d;\n    end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    aset : in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process (clk, aset) begin\n    if aset = '1' then\n      q <= '1';\n    elsif clk'event and clk = '1' then\n        q <= d;\n    end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d1, d2: in std_logic;\n    clk: in std_logic;\n    arst : in std_logic;\n    q1, q2: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process (clk, arst) begin\n    if arst = '1' then\n      q1 <= '0';\n      q2 <= '1';\n    elsif clk'event and clk = '1' then\n      q1 <= d1;\n      q2 <= d2;\n    end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    en: in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process begin\n    if clk'event and clk = '1' then\n      if en = '1' then\n        q <= d;\n      end if;\n    end if;\n    wait on clk;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFFE is port (\n    d: in std_logic;\n    en: in std_logic;\n    clk: in std_logic;\n    q: out std_logic\n    );\nend DFFE;\n\narchitecture rtl of DFFE is\n\nbegin\n\n  process begin\n    wait until clk = '1';\n      if en = '1' then\n        q <= d;\n      end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    envector: in std_logic_vector(7 downto 0);\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process (clk) begin\n    if clk'event and clk = '1' then\n      if envector = \"10010111\" then\n        q <= d;\n      end if;\n    end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    en: in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process (clk) begin\n    if clk'event and clk = '1' then\n      if en = '1' then\n        q <= d;\n      end if;\n    end if;\n  end process;\n\nend rtl;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFFE_SR is port (\n    d: in std_logic;\n    en: in std_logic;\n    clk: in std_logic;\n    rst: in std_logic;\n    prst: in std_logic;\n    q: out std_logic\n    );\nend DFFE_SR;\n\narchitecture rtl of DFFE_SR is\n\nbegin\n\n  process (clk, rst, prst) begin\n    if (prst = '1') then\n      q <= '1';\n    elsif (rst = '1') then\n      q <= '0';\n    elsif (clk'event and clk = '1') then\n      if (en = '1') then\n        q <= d;\n      end if;\n    end if;\n  end process;\n\nend rtl;\n\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity flipFlop is port (\n  clock, input: in std_logic;\n  ffOut: out std_logic\n  );\nend flipFlop;\n\narchitecture simple of flipFlop is\n\n  procedure dff (signal clk: in std_logic;\n                 signal d: in std_logic;\n                 signal q: out std_logic\n                ) is\n  begin\n    if clk'event and clk = '1' then\n      q <= d;\n    end if;\n  end procedure dff;\n\nbegin\n\n  dff(clock, input, ffOut);\n\nend simple;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    end: in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process begin\n    wait until rising_edge(clk);\n      if en = '1' then\n        q <= d;\n      end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d1, d2: in std_logic;\n    clk: in std_logic;\n    srst : in std_logic;\n    q1, q2: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process (clk) begin\n    if clk'event and clk = '1' then\n      if srst = '1' then\n\tq1 <= '0';\n\tq2 <= '1';\n      else\n        q1 <= d1;\n        q2 <= d2;\n      end if;\n    end if;\n  end process;\n\nend rtl;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFFE_SR is port (\n    d: in std_logic;\n    en: in std_logic;\n    clk: in std_logic;\n    rst: in std_logic;\n    prst: in std_logic;\n    q: out std_logic\n    );\nend DFFE_SR;\n\narchitecture rtl of DFFE_SR is\n\nbegin\n\n  process (clk, rst, prst) begin\n    if (rst = '1') then\n      q <= '0';\n    elsif (prst = '1') then\n      q <= '1';\n    elsif (clk'event and clk = '1') then\n      if (en = '1') then\n        q <= d;\n      end if;\n    end if;\n  end process;\n\nend rtl;\n\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    srst : in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process begin\n    wait until clk = '1';\n      if srst = '1' then\n\tq <= '0';\n      else\n        q <= d;\n      end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity struct_dffe_sr is port (\n  d: in std_logic;\n  clk: in std_logic;\n  en: in std_logic;\n  rst,prst: in std_logic;\n  q: out std_logic\n  );\nend struct_dffe_sr;\n\nuse work.primitive.all;\n\narchitecture instance of struct_dffe_sr is\n\nbegin\n\n  ff: dffe_sr port map (\n\td => d,\n\tclk => clk,\n\ten => en,\n        rst => rst,\n        prst => prst,\n\tq => q\n    );\n\nend instance;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    srst : in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process (clk) begin\n    if clk'event and clk = '1' then\n      if srst = '1' then\n\tq <= '0';\n      else\n        q <= d;\n      end if;\n    end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity struct_dffe is port (\n  d: in std_logic;\n  clk: in std_logic;\n  en: in std_logic;\n  q: out std_logic\n  );\nend struct_dffe;\n\nuse work.primitive.all;\n\narchitecture instance of struct_dffe is\n\nbegin\n\n  ff: dffe port map (\n\td => d,\n\tclk => clk,\n\ten => en,\n\tq => q\n      );\n\nend instance;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nuse work.primitive.all;\n\nentity dffTri is\n  generic (size: integer := 8);\n  port (\n  data: in std_logic_vector(size - 1 downto 0);\n  clock: in std_logic;\n  ff_enable: in std_logic;\n  op_enable: in std_logic;\n  qout: out std_logic_vector(size - 1 downto 0)\n  );\nend dffTri;\n\narchitecture parameterize of dffTri is\n\ntype tribufType is record\n  ip: std_logic;\n  oe: std_logic;\n  op: std_logic;\nend record;\n\ntype tribufArrayType is array (integer range <>) of tribufType;\n\nsignal tri: tribufArrayType(size - 1 downto 0);\n\nbegin\n\n  g0: for i in 0 to size - 1 generate\n    u1: DFFE port map (data(i), tri(i).ip, ff_enable, clock);\n  end generate;\n\n  g1: for i in 0 to size - 1 generate\n    u2: TRIBUF port map (tri(i).ip, tri(i).oe, tri(i).op);\n    tri(i).oe <= op_enable;\n    qout(i) <= tri(i).op;\n  end generate;\n\nend parameterize;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    en: in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process begin\n    wait until clk = '1';\n      if en = '1' then\n        q <= d;\n      end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity TRIBUF is port (\n  ip: in std_logic;\n  oe: in std_logic;\n  op: out std_logic bus\n  );\nend TRIBUF;\n\narchitecture sequential of TRIBUF is\n\nbegin\n\n  enable: process (ip,oe) begin\n    if (oe = '1') then\n      op <= ip;\n    else\n      op <= null;\n    end if;\n  end process;\n\nend sequential;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DLATCHH is port (\n    d: in std_logic;\n    en: in std_logic;\n    q: out std_logic\n    );\nend DLATCHH;\n\narchitecture rtl of DLATCHH is\n\nsignal qLocal: std_logic;\n\nbegin\n\n  qLocal <= d when en = '1' else qLocal;\n\n  q <= qLocal;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DLATCHH is port (\n    d: in std_logic;\n    en: in std_logic;\n    q: out std_logic\n    );\nend DLATCHH;\n\narchitecture rtl of DLATCHH is\n\nbegin\n\n  process (en, d) begin\n    if en = '1' then\n      q <= d;\n    end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity struct_dlatch is port (\n  d: in std_logic;\n  en: in std_logic;\n  q: out std_logic\n  );\nend struct_dlatch;\n\nuse work.primitive.all;\n\narchitecture instance of struct_dlatch is\n\nbegin\n\n  latch: dlatchh port map (\n\td => d,\n\ten => en,\n\tq => q\n      );\n\nend instance;\n-- Incorporates Errata 5.4\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity downCounter is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  count: out std_logic_vector(3 downto 0)\n  );\nend downCounter;\n\narchitecture simple of downCounter is\n\nsignal countL: unsigned(3 downto 0);\nsignal termCnt: std_logic;\n\nbegin\n\n  decrement: process (clk, reset) begin\n    if (reset = '1') then\n      countL <= \"1011\";          -- Reset to 11\n      termCnt <= '1';\n    elsif(clk'event and clk = '1') then\n      if (termCnt = '1') then\n        countL <= \"1011\";        -- Count rolls over to 11\n      else\n        countL <= countL - 1;\n      end if;\n\n      if (countL = \"0001\") then  -- Terminal count decoded 1 cycle earlier\n        termCnt <= '1';\n      else\n        termCnt <= '0';\n      end if;\n    end if;\n  end process;\n  \n  count <= std_logic_vector(countL);\n\nend simple;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.std_logic_unsigned.all;\n\nentity compareDC is port (\n  addressBus: in std_logic_vector(31 downto 0);\n  addressHit: out std_logic\n  );\nend compareDC;\n\narchitecture wontWork of compareDC is\n\nbegin\n\n  compare: process(addressBus) begin\n    if (addressBus = \"011110101011--------------------\") then\n      addressHit <= '1';\n    else\n      addressHit <= '0';\n    end if;\n  end process compare;\n\nend wontWork;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nentity encoder is\n        port (invec: in std_logic_vector(7 downto 0);\n              enc_out: out std_logic_vector(2 downto 0)\n             );\nend encoder;\n\narchitecture rtl of encoder is\n\nbegin\n\n  encode: process (invec) begin\n    case invec is\n      when \"00000001\" =>\n        enc_out <= \"000\";\n\n      when \"00000010\" =>\n        enc_out <= \"001\";\n\n      when \"00000100\" =>\n        enc_out <= \"010\";\n\n      when \"00001000\" =>\n        enc_out <= \"011\";\n\n      when \"00010000\" =>\n        enc_out <= \"100\";\n\n      when \"00100000\" =>\n        enc_out <= \"101\";\n\n      when \"01000000\" =>\n        enc_out <= \"110\";\n\n      when \"10000000\" =>\n        enc_out <= \"111\";\n\n      when others =>\n        enc_out <= \"000\";\n\n      end case;\n    end process;\n\nend rtl;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity encoder is\n  port (invec:in std_logic_vector(7 downto 0);\n        enc_out:out  std_logic_vector(2 downto 0)\n       );\nend encoder;\n\narchitecture rtl of encoder is\nbegin\n  process (invec)\n    begin\n      if invec(7) = '1' then\n        enc_out <= \"111\";\n\n      elsif invec(6) = '1' then\n        enc_out <= \"110\";\n\n      elsif invec(5) = '1' then\n        enc_out <= \"101\";\n\n      elsif invec(4) = '1' then\n        enc_out <= \"100\";\n\n      elsif invec(3) = '1' then\n        enc_out <= \"011\";\n\n      elsif invec(2) = '1' then\n        enc_out <= \"010\";\n\n      elsif invec(1) = '1' then\n        enc_out <= \"001\";\n\n      elsif invec(0) = '1' then\n        enc_out <= \"000\";\n\n      else \n        enc_out <= \"000\";\n      end if; \n    end process;\nend rtl;\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nentity encoder is\n  port (invec: in std_logic_vector(7 downto 0);\n        enc_out: out std_logic_vector(2 downto 0)\n        );\nend encoder;\n\narchitecture rtl of encoder is\n\nbegin\n  enc_out <= \"111\" when invec(7) = '1' else\n             \"110\" when invec(6) = '1' else\n             \"101\" when invec(5) = '1' else\n             \"100\" when invec(4) = '1' else\n             \"011\" when invec(3) = '1' else\n             \"010\" when invec(2) = '1' else\n             \"001\" when invec(1) = '1' else\n             \"000\" when invec(0) = '1' else\n             \"000\";\n\nend rtl;\n-- includes Errata 5.2\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all; -- errata 5.2\n\nentity compare is port (\n  ina: in std_logic_vector (3 downto 0);\n  inb: in std_logic_vector (2 downto 0);\n  equal: out std_logic\n  );\nend compare;\n\narchitecture simple of compare is\n\nbegin\n\n  equalProc: process (ina, inb) begin\n    if (ina = inb ) then\n      equal <= '1';\n    else\n      equal <= '0';\n    end if;\n  end process;\n\nend simple;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity LogicFcn is port (\n  A: in std_logic;\n  B: in std_logic;\n  C: in std_logic;\n  Y: out std_logic\n  );\nend LogicFcn;\n\narchitecture behavioral of LogicFcn is\n\nbegin\n\n  fcn: process (A,B,C) begin\n\n    if (A = '0' and B = '0') then\n      Y <= '1';\n    elsif C = '1' then\n      Y <= '1';\n    else\n      Y <= '0';\n    end if;\n\n  end process;\n\nend behavioral;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity LogicFcn is port (\n  A: in std_logic;\n  B: in std_logic;\n  C: in std_logic;\n  Y: out std_logic\n  );\nend LogicFcn;\n\narchitecture dataflow of LogicFcn is\n\nbegin\n\n  Y <= '1' when (A = '0' AND B = '0') OR\n                (C = '1')\n           else '0';\n\nend dataflow;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse work.primitive.all;\n\nentity LogicFcn is port (\n  A: in std_logic;\n  B: in std_logic;\n  C: in std_logic;\n  Y: out std_logic\n  );\nend LogicFcn;\n\narchitecture structural of LogicFcn is\n\nsignal notA, notB, andSignal: std_logic;\n\nbegin\n\n  i1: inverter port map (i => A,\n                         o => notA);\n\n  i2: inverter port map (i => B,\n                         o => notB);\n\n  a1: and2 port map (i1 => notA,\n                     i2 => notB,\n                     y => andSignal);\n\n  o1: or2 port map (i1 => andSignal,\n                    i2 => C,\n                    y => Y);\n\nend structural;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity SimDFF is port (\n  D, Clk: in std_logic;\n  Q: out std_logic\n  );\nend SimDff;\n\narchitecture SimModel of SimDFF is\n\nconstant tCQ: time := 8 ns;\nconstant tS:  time := 4 ns;\nconstant tH:  time := 3 ns;\n\nbegin\n\n  reg: process (Clk, D) begin\n\n    -- Assign output tCQ after rising clock edge\n    if (Clk'event and Clk = '1') then\n      Q <= D after tCQ;\n    end if;\n\n    -- Check setup time\n    if (Clk'event and Clk = '1') then\n      assert (D'last_event >= tS)\n        report \"Setup time violation\"\n        severity Warning;\n    end if;\n\n    -- Check hold time\n    if (D'event and Clk'stable and Clk = '1') then\n      assert (D'last_event - Clk'last_event > tH)\n        report \"Hold Time Violation\"\n        severity Warning;\n    end if;\n\n  end process;\n\nend simModel;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process (clk) begin\n    wait until clk = '1';\n      q <= d;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d: in std_logic;\n    clk: in std_logic;\n    q: out std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  process begin\n    wait until clk = '1';\n      q <= d;\n\n    wait on clk;\n  end process;\n\nend rtl;\nconfiguration SimpleGatesCfg of FEWGATES is\n\n  for structural\n\n    for all: AND2\n      use entity work.and2(rtl);\n    end for;\n\n    for u3: inverter\n      use entity work.inverter(rtl);\n    end for;\n\n    for u4: or2\n      use entity work.or2(rtl);\n    end for;\n\n  end for;\n\nend SimpleGatesCfg;\nconfiguration SimpleGatesCfg of FEWGATES is\n\n  for structural\n\n    for u1: and2\n      use entity work.and2(rtl);\n    end for;\n\n    for u2: and2\n      use entity work.and2(rtl);\n    end for;\n\n    for u3: inverter\n      use entity work.inverter(rtl);\n    end for;\n\n    for u4: or2\n      use entity work.or2(rtl);\n    end for;\n\n  end for;\n\nend SimpleGatesCfg;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity FEWGATES is port (\n  a,b,c,d: in std_logic;\n  y: out std_logic\n  );\nend FEWGATES;\n\nuse work.and2;\nuse work.or2;\nuse work.inverter;\n\narchitecture structural of FEWGATES is\n\n  component AND2 port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\n  end component;\n\n  component OR2 port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\n  end component;\n\n  component INVERTER port (\n    i: in std_logic;\n    o: out std_logic\n    );\n  end component;\n\nsignal a_and_b, c_and_d, not_c_and_d: std_logic;\n\nbegin\n\n  u1: and2 port map (i1 => a ,\n                     i2 => b,\n                     y => a_and_b\n                     );\n\n  u2: and2 port map (i1 => c,\n                     i2 => d,\n                     y => c_and_d\n                     );\n\n  u3: inverter port map (i => c_and_d,\n                         o => not_c_and_d);\n\n  u4: or2 port map (i1 => a_and_b,\n                    i2 => not_c_and_d,\n                    y => y\n                    );\nend structural;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity FEWGATES is port (\n  a,b,c,d: in std_logic;\n  y: out std_logic\n  );\nend FEWGATES;\n\nuse work.and2;\nuse work.or2;\nuse work.inverter;\n\narchitecture structural of FEWGATES is\n\n  component AND2 port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\n  end component;\n\n  component OR2 port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\n  end component;\n\n  component INVERTER port (\n    i: in std_logic;\n    o: out std_logic\n    );\n  end component;\n\nsignal a_and_b, c_and_d, not_c_and_d: std_logic;\n\n-- Configution specifications\n\nfor all: and2 use entity work.and2(rtl);\nfor u3: inverter use entity work.inverter(rtl);\nfor u4: or2 use entity work.or2(rtl);\n\nbegin\n\n  u1: and2 port map (i1 => a, i2 => b,\n                     y => a_and_b\n                     );\n\n  u2: and2 port map (i1 => c, i2 => d,\n                     y => c_and_d\n                     );\n\n  u3: inverter port map (i => c_and_d,\n                         o => not_c_and_d);\n\n  u4: or2 port map (i1 => a_and_b, i2 => not_c_and_d,\n                    y => y\n                    );\nend structural;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity FEWGATES is port (\n  a,b,c,d: in std_logic;\n  y: out std_logic\n  );\nend FEWGATES;\n\nuse work.GatesPkg.all;\n\narchitecture structural of FEWGATES is\n\nsignal a_and_b, c_and_d, not_c_and_d: std_logic;\n\nbegin\n\n  u1: and2 port map (i1 => a ,\n                     i2 => b,\n                     y => a_and_b\n                     );\n\n  u2: and2 port map (i1 => c,\n                     i2 => d,\n                     y => c_and_d\n                     );\n\n  u3: inverter port map (i => c_and_d,\n                         o => not_c_and_d);\n\n  u4: or2 port map (i1 => a_and_b,\n                    i2 => not_c_and_d,\n                    y => y\n                    );\nend structural;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\n\nentity FEWGATES is port (\n  a,b,c,d: in std_logic;\n  y: out std_logic\n  );\nend FEWGATES;\n\narchitecture concurrent of FEWGATES is\n\nsignal a_and_b, c_and_d, not_c_and_d: std_logic;\n\nbegin\n\n  a_and_b <= '1' when a = '1' and b = '1' else '0';\n  c_and_d <= '1' when c = '1' and d = '1' else '0';\n\n  not_c_and_d <= not c_and_d;\n\n  y <= '1' when a_and_b = '1' or not_c_and_d = '1' else '0';\n\nend concurrent;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\npackage GatesPkg is\n\n  component AND2 port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\n  end component;\n\n  component OR2 port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\n  end component;\n\n  component INVERTER port (\n    i: in std_logic;\n    o: out std_logic\n    );\n  end component;\n\nend GatesPkg;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nuse work.primitive.all;\n\nentity FEWGATES is port (\n  a,b,c,d: in std_logic;\n  y: out std_logic\n  );\nend FEWGATES;\n\narchitecture structural of FEWGATES is\n\nsignal a_and_b, c_and_d, not_c_and_d: std_logic;\n\nbegin\n\n  u1: and2 port map (i1 => a ,\n                     i2 => b,\n                     y => a_and_b\n                     );\n\n  u2: and2 port map (i1 =>c,\n                     i2 => d,\n                     y => c_and_d\n                     );\n\n  u3: inverter port map (a => c_and_d,\n                         y => not_c_and_d);\n\n  u4: or2 port map (i1 => a_and_b,\n                    i2 => not_c_and_d,\n                    y => y\n                    );\n\nend structural;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity AND2 is port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\nend AND2;\n\narchitecture rtl of AND2 is\n\nbegin\n\n  y <= '1' when i1 = '1' and i2 = '1' else '0';\n\nend rtl;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity OR2 is port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\nend OR2;\n\narchitecture rtl of OR2 is\n\nbegin\n\n  y <= '1' when i1 = '1' or i2 = '1' else '0';\n\nend rtl;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity INVERTER is port (\n    i: in std_logic;\n    o: out std_logic\n    );\nend INVERTER;\n\narchitecture rtl of INVERTER is\n\nbegin\n\n  o <= not i;\n\nend rtl;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity FEWGATES is port (\n  a,b,c,d: in std_logic;\n  y: out std_logic\n  );\nend FEWGATES;\n\narchitecture structural of FEWGATES is\n\n  component AND2 port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\n  end component;\n\n  component OR2 port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\n  end component;\n\n  component INVERTER port (\n    i: in std_logic;\n    o: out std_logic\n    );\n  end component;\n\nsignal a_and_b, c_and_d, not_c_and_d: std_logic;\n\nbegin\n\n  u1: and2 port map (i1 => a ,\n                     i2 => b,\n                     y => a_and_b\n                     );\n\n  u2: and2 port map (i1 => c,\n                     i2 => d,\n                     y => c_and_d\n                     );\n\n  u3: inverter port map (i => c_and_d,\n                         o => not_c_and_d);\n\n  u4: or2 port map (i1 => a_and_b,\n                    i2 => not_c_and_d,\n                    y => y\n                    );\nend structural;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nuse work.simPrimitives.all;\n\nentity simHierarchy is port (\n  A, B, Clk: in std_logic;\n  Y: out std_logic\n  );\nend simHierarchy;\n\narchitecture hierarchical of simHierarchy is\n\nsignal ADly, BDly, OrGateDly, ClkDly: std_logic;\nsignal OrGate, FlopOut: std_logic;\n\nbegin\n\n  ADly <= transport A after 2 ns;\n  BDly <= transport B after 2 ns;\n  OrGateDly <= transport OrGate after 1.5 ns;\n  ClkDly <= transport Clk after 1 ns;\n\n  u1: OR2 generic map (tPD => 10 ns)\n          port map ( I1 => ADly,\n                     I2 => BDly,\n                     Y => OrGate\n                   );\n\n  u2: simDFF generic map ( tS => 4 ns,\n                           tH => 3 ns,\n                           tCQ => 8 ns\n                         )\n             port map ( D => OrGateDly,\n                        Clk => ClkDly,\n                        Q => FlopOut\n                      );\n\n  Y <= transport FlopOut after 2 ns;\n\nend hierarchical;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity INVERTER is port (\n    i: in std_logic;\n    o: out std_logic\n    );\nend INVERTER;\n\narchitecture rtl of INVERTER is\n\nbegin\n\n  o <= not i;\n\nend rtl;\n--------------------------------------------------------------------------------\n--| File name   : $RCSfile: io1164.vhd $\n--| Library     : SUPPORT\n--| Revision    : $Revision: 1.1 $\n--| Author(s)   : Vantage Analysis Systems, Inc; Des Young\n--| Integration : Des Young\n--| Creation    : Nov 1995\n--| Status      : $State: Exp $\n--|\n--| Purpose     : IO routines for std_logic_1164.\n--| Assumptions : Numbers use radixed character set with no prefix.\n--| Limitations : Does not read VHDL pound-radixed numbers.\n--| Known Errors: none\n--|\n--| Description:\n--| This is a modified library. The source is basically that donated by\n--| Vantage to libutil. Des Young removed std_ulogic_vector support (to\n--| conform to synthesizable libraries), and added read_oct/hex to integer.\n--|\n--| =======================================================================\n--| Copyright (c) 1992-1994 Vantage Analysis Systems, Inc., all rights\n--| reserved. This package is provided by Vantage Analysis Systems.\n--| The package may not be sold without the express written consent of\n--| Vantage Analysis Systems, Inc.\n--|\n--| The VHDL for this package may be copied and/or distributed as long as\n--| this copyright notice is retained in the source and any modifications\n--| are clearly marked in the History: list.\n--|\n--| Title       : IO1164 package VHDL source\n--| Package Name: somelib.IO1164\n--| File Name   : io1164.vhdl\n--| Author(s)   : dbb\n--| Purpose     : * Overloads procedures READ and WRITE for STD_LOGIC types\n--|                 in manner consistent with TEXTIO package.\n--|               * Provides procedures to read and write logic values as\n--|                 binary, octal, or hexadecimal values ('X' as appropriate).\n--|                 These should be particularly useful for models\n--|                 to read in stimulus as 0/1/x or octal or hex.\n--| Subprograms :\n--| Notes       : \n--| History     : 1. Donated to libutil by Dave Bernstein 15 Jun 94\n--|               2. Removed all std_ulogic_vector support, Des Young, 14 Nov 95\n--|                  (This is because that type is not supported for synthesis).\n--|               3. Added read_oct/hex to integer, Des Young, 20 Nov 95\n--|\n--| =======================================================================\n--| Extra routines by Des Young, des@alantec.com. 1995. GNU copyright.\n--| =======================================================================\n--|\n--------------------------------------------------------------------------------\n\nlibrary ieee;\npackage io1164 is\n\n    --$ !VANTAGE_METACOMMENTS_ON\n    --$ !VANTAGE_DNA_ON\n\n    -- import std_logic package\n    use ieee.std_logic_1164.all;\n\n    -- import textio package\n    use std.textio.all;\n\n    --\n    -- the READ and WRITE procedures act similarly to the procedures in the\n    -- STD.TEXTIO package.  for each type, there are two read procedures and\n    -- one write procedure for converting between character and internal\n    -- representations of values.  each value is represented as the string of\n    -- characters that you would use in VHDL code.  (remember that apostrophes\n    -- and quotation marks are not used.)  input is case-insensitive.  output\n    -- is in upper case.  see the following LRM sections for more information:\n    --\n    --      2.3   - Subprogram Overloading\n    --      3.3   - Access Types             (STD.TEXTIO.LINE is an access type)\n    --      7.3.6 - Allocators               (allocators create access values)\n    --     14.3   - Package TEXTIO\n    --\n\n    -- Note that the procedures for std_ulogic will match calls with the value\n    -- parameter of type std_logic.\n\n    --\n    -- declare READ procedures to overload like in TEXTIO\n    --\n    procedure read(l: inout line; value: out std_ulogic       ; good: out boolean);\n    procedure read(l: inout line; value: out std_ulogic                          );\n    procedure read(l: inout line; value: out std_logic_vector ; good: out boolean);\n    procedure read(l: inout line; value: out std_logic_vector                    );\n\n    --\n    -- declare WRITE procedures to overload like in TEXTIO\n    --\n    procedure write(l        : inout line                  ;\n                    value    : in    std_ulogic            ;\n                    justified: in    side          := right;\n                    field    : in    width         := 0   );\n    procedure write(l        : inout line                  ;\n                    value    : in    std_logic_vector      ;\n                    justified: in    side          := right;\n                    field    : in    width         := 0   );\n\n    --\n    -- declare procedures to convert between logic values and octal\n    -- or hexadecimal ('X' where appropriate).\n    --\n\n    -- octal / std_logic_vector\n    procedure read_oct (l         : inout line                    ;\n                        value     : out   std_logic_vector        ;\n                        good      : out   boolean                );\n    procedure read_oct (l         : inout line                    ;\n                        value     : out   std_logic_vector       );\n    procedure write_oct(l         : inout line                    ;\n                        value     : in    std_logic_vector        ;\n                        justified : in    side            := right;\n                        field     : in    width           := 0   );\n\n    -- hexadecimal / std_logic_vector\n    procedure read_hex (l         : inout line                    ;\n                        value     : out   std_logic_vector        ;\n                        good      : out   boolean                );\n    procedure read_hex (l         : inout line                    ;\n                        value     : out   std_logic_vector       );\n    procedure write_hex(l         : inout line                    ;\n                        value     : in    std_logic_vector        ;\n                        justified : in    side            := right;\n                        field     : in    width           := 0   );\n\n    -- read a number into an integer\n    procedure read_oct(l     : inout line;\n                       value : out   integer;\n                       good  : out   boolean);\n    procedure read_oct(l     : inout line;\n                       value : out   integer);\n    procedure read_hex(l     : inout line;\n                       value : out   integer;\n                       good  : out   boolean);\n    procedure read_hex(l     : inout line;\n                       value : out   integer);\n\nend io1164;\n\n--------------------------------------------------------------------------------\n--| Copyright (c) 1992-1994 Vantage Analysis Systems, Inc., all rights reserved\n--| This package is provided by Vantage Analysis Systems.\n--| The package may not be sold without the express written consent of\n--| Vantage Analysis Systems, Inc.\n--|\n--| The VHDL for this package may be copied and/or distributed as long as\n--| this copyright notice is retained in the source and any modifications\n--| are clearly marked in the History: list.\n--|\n--| Title       : IO1164 package body VHDL source\n--| Package Name: VANTAGE_LOGIC.IO1164\n--| File Name   : io1164.vhdl\n--| Author(s)   : dbb\n--| Purpose     : source for IO1164 package body\n--| Subprograms :\n--| Notes       : see package declaration\n--| History     : see package declaration\n--------------------------------------------------------------------------------\n\npackage body io1164 is\n\n\n    --$ !VANTAGE_METACOMMENTS_ON\n    --$ !VANTAGE_DNA_ON\n\n    -- define lowercase conversion of characters for canonical comparison\n    type char2char_t is array (character'low to character'high) of character;\n    constant lowcase: char2char_t := (\n        nul, soh, stx, etx, eot, enq, ack, bel,\n        bs,  ht,  lf,  vt,  ff,  cr,  so,  si,\n        dle, dc1, dc2, dc3, dc4, nak, syn, etb,\n        can, em,  sub, esc, fsp, gsp, rsp, usp, \n\n        ' ', '!', '\"', '#', '$', '%', '&', ''',\n        '(', ')', '*', '+', ',', '-', '.', '/',\n        '0', '1', '2', '3', '4', '5', '6', '7',\n        '8', '9', ':', ';', '<', '=', '>', '?',\n\n        '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',\n        'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',\n        'p', 'q', 'r', 's', 't', 'u', 'v', 'w',\n        'x', 'y', 'z', '[', '\\', ']', '^', '_',\n\n        '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',\n        'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',\n        'p', 'q', 'r', 's', 't', 'u', 'v', 'w',\n        'x', 'y', 'z', '{', '|', '}', '~', del);\n\n    -- define conversions between various types\n\n    -- logic    -> character\n    type f_logic_to_character_t is \n        array (std_ulogic'low to std_ulogic'high) of character;\n    constant f_logic_to_character : f_logic_to_character_t := \n        ( \n          'U' => 'U', \n          'X' => 'X',\n          '0' => '0',\n          '1' => '1',\n          'Z' => 'Z',\n          'W' => 'W',\n          'L' => 'L',\n          'H' => 'H',\n          '-' => '-'\n        );\n\n    -- character, integer, logic\n\n    constant x_charcode     : integer := -1;\n    constant maxoct_charcode: integer := 7;\n    constant maxhex_charcode: integer := 15;\n    constant bad_charcode   : integer := integer'left;\n\n    type digit2int_t is \n        array ( character'low to character'high ) of integer;\n    constant octdigit2int: digit2int_t := (\n          '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4,\n          '5' => 5, '6' => 6, '7' => 7,\n          'X' | 'x' => x_charcode, others => bad_charcode );\n    constant hexdigit2int: digit2int_t := (\n          '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4,\n          '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, \n          'A' | 'a' => 10, 'B' | 'b' => 11, 'C' | 'c' => 12,\n          'D' | 'd' => 13, 'E' | 'e' => 14, 'F' | 'f' => 15,\n          'X' | 'x' => x_charcode, others => bad_charcode  );\n\n    constant oct_bits_per_digit: integer := 3;\n    constant hex_bits_per_digit: integer := 4;\n\n    type     int2octdigit_t is \n        array ( 0 to maxoct_charcode ) of character;\n    constant int2octdigit: int2octdigit_t :=\n        (  0 => '0',  1 => '1',  2 => '2',  3 => '3',\n           4 => '4',  5 => '5',  6 => '6',  7 => '7' );\n\n    type     int2hexdigit_t is \n        array ( 0 to maxhex_charcode ) of character;\n    constant int2hexdigit: int2hexdigit_t :=\n        (  0 => '0',  1 => '1',  2 => '2',  3 => '3',\n           4 => '4',  5 => '5',  6 => '6',  7 => '7',\n           8 => '8',  9 => '9', 10 => 'A', 11 => 'B',\n          12 => 'C', 13 => 'D', 14 => 'E', 15 => 'F' );\n\n    type     oct_logic_vector_t is\n        array(1 to oct_bits_per_digit) of std_ulogic;\n    type     octint2logic_t is \n        array (x_charcode to maxoct_charcode) of oct_logic_vector_t;\n    constant octint2logic  : octint2logic_t := (\n        ( 'X', 'X', 'X' ),\n        ( '0', '0', '0' ),\n        ( '0', '0', '1' ),\n        ( '0', '1', '0' ),\n        ( '0', '1', '1' ),\n        ( '1', '0', '0' ),\n        ( '1', '0', '1' ),\n        ( '1', '1', '0' ),\n        ( '1', '1', '1' )\n    );\n\n    type     hex_logic_vector_t is\n        array(1 to hex_bits_per_digit) of std_ulogic;\n    type     hexint2logic_t is \n        array (x_charcode to maxhex_charcode) of hex_logic_vector_t;\n    constant hexint2logic  : hexint2logic_t := (\n        ( 'X', 'X', 'X', 'X' ),\n        ( '0', '0', '0', '0' ),\n        ( '0', '0', '0', '1' ),\n        ( '0', '0', '1', '0' ),\n        ( '0', '0', '1', '1' ),\n        ( '0', '1', '0', '0' ),\n        ( '0', '1', '0', '1' ),\n        ( '0', '1', '1', '0' ),\n        ( '0', '1', '1', '1' ),\n        ( '1', '0', '0', '0' ),\n        ( '1', '0', '0', '1' ),\n        ( '1', '0', '1', '0' ),\n        ( '1', '0', '1', '1' ),\n        ( '1', '1', '0', '0' ),\n        ( '1', '1', '0', '1' ),\n        ( '1', '1', '1', '0' ),\n        ( '1', '1', '1', '1' )\n    );\n\n    ----------------------------------------------------------------------------\n    -- READ procedure bodies\n    --\n    --     The strategy for duplicating TEXTIO's overloading of procedures\n    --     with and without GOOD parameters is to put all the logic in the\n    --     version with the GOOD parameter and to have the version without\n    --     GOOD approximate a runtime error by use of an assertion.\n    --\n    ----------------------------------------------------------------------------\n\n    --\n    -- std_ulogic\n    --     note: compatible with std_logic\n    --\n\n    procedure read( l: inout line; value: out std_ulogic; good : out boolean ) is\n\n        variable c      : character;        -- char read while looping\n        variable m      : line;             -- safe copy of L\n        variable success: boolean := false; -- readable version of GOOD\n        variable done   : boolean := false; -- flag to say done reading chars\n\n    begin\n\n        --\n        -- algorithm:\n        -- \n        --     if there are characters in the line\n        --         save a copy of the line\n        --         get the next character\n        --         if got one\n        --             set value\n        --         if all ok\n        --             free temp copy\n        --         else\n        --             free passed in line\n        --             assign copy back to line\n        --         set GOOD\n        --     \n\n        -- only operate on lines that contain characters\n        if ( ( l /= null ) and ( l.all'length /= 0 ) ) then\n\n            -- save a copy of string in case read fails\n            m := new string'( l.all );\n    \n            -- grab the next character\n            read( l, c, success );\n\n            -- if read ok    \n            if success then\n\n--\n-- an issue here is whether lower-case values should be accepted or not\n--\n\n                -- determine the value    \n                case c is\n                    when 'U' | 'u' => value := 'U';\n                    when 'X' | 'x' => value := 'X';\n                    when '0'       => value := '0';\n                    when '1'       => value := '1';\n                    when 'Z' | 'z' => value := 'Z';\n                    when 'W' | 'w' => value := 'W';\n                    when 'L' | 'l' => value := 'L';\n                    when 'H' | 'h' => value := 'H';\n                    when '-'       => value := '-';\n                    when others    => success := false;\n                end case;\n\n            end if;\n\n            -- free working storage\n            if success then\n                deallocate( m );\n            else\n                deallocate( l );\n                l := m;\n            end if;\n\n        end if; -- non null access, non empty string\n\n        -- set output parameter\n        good := success;\n\n    end read;\n\n    procedure read( l: inout line; value: out std_ulogic ) is\n        variable success: boolean;  -- internal good flag\n    begin\n        read( l, value, success );  -- use safe version\n        assert success \n            report \"IO1164.READ: Unable to read STD_ULOGIC value.\" \n            severity error;\n    end read;\n\n    --\n    -- std_logic_vector\n    --     note: NOT compatible with std_ulogic_vector\n    --\n\n    procedure read(l    : inout line           ; \n                   value: out   std_logic_vector;\n                   good : out   boolean        ) is\n\n        variable m           : line           ; -- saved copy of L\n        variable success     : boolean := true; -- readable GOOD\n        variable logic_value : std_logic      ; -- value for one array element\n        variable c           : character      ; -- read a character\n\n    begin\n\n        --\n        -- algorithm:\n        -- \n        --     this procedure strips off leading whitespace, and then calls the\n        --     READ procedure for each single logic value element in the output\n        --     array.\n        --     \n\n        -- only operate on lines that contain characters\n        if ( ( l /= null ) and ( l.all'length /= 0 ) ) then\n\n            -- save a copy of string in case read fails\n            m := new string'( l.all );\n\n            -- loop for each element in output array\n            for i in value'range loop\n\n                -- prohibit internal blanks\n                if i /= value'left then\n                    if l.all'length = 0 then\n                        success := false;\n                        exit;\n                    end if;\n                    c := l.all(l.all'left);\n                    if c = ' ' or c = ht then\n                        success := false;\n                        exit;\n                    end if;\n                end if;\n\n                -- read the next logic value\n                read( l, logic_value, success );\n\n                -- stuff the value in if ok, else bail out\n                if success then\n                    value( i ) := logic_value;\n                else\n                    exit;\n                end if;\n\n            end loop; -- each element in output array\n\n            -- free working storage\n            if success then\n                deallocate( m );\n            else\n                deallocate( l );\n                l := m;\n            end if;\n\n        elsif ( value'length /= 0 ) then\n            -- string is empty but the  return array has 1+ elements\n            success := false;\n        end if;\n\n        -- set output parameter\n        good := success;\n\n    end read;\n\n    procedure read(l: inout line; value: out std_logic_vector ) is\n        variable success: boolean;\n    begin\n        read( l, value, success );\n        assert success \n            report \"IO1164.READ: Unable to read T_WLOGIC_VECTOR value.\" \n            severity error;\n    end read;\n\n    ----------------------------------------------------------------------------\n    -- WRITE procedure bodies\n    ----------------------------------------------------------------------------\n\n    --\n    -- std_ulogic\n    --     note: compatible with std_logic\n    --\n\n    procedure write(l        : inout line          ;\n                    value    : in    std_ulogic    ;\n                    justified: in    side  := right;\n                    field    : in    width := 0    ) is\n    begin\n\n        --\n        -- algorithm:\n        -- \n        --     just write out the string associated with the enumerated\n        --     value.\n        --     \n\n        case value is\n            when 'U' => write( l, character'('U'), justified, field );\n            when 'X' => write( l, character'('X'), justified, field );\n            when '0' => write( l, character'('0'), justified, field );\n            when '1' => write( l, character'('1'), justified, field );\n            when 'Z' => write( l, character'('Z'), justified, field );\n            when 'W' => write( l, character'('W'), justified, field );\n            when 'L' => write( l, character'('L'), justified, field );\n            when 'H' => write( l, character'('H'), justified, field );\n            when '-' => write( l, character'('-'), justified, field );\n        end case;\n    end write;\n\n    --\n    -- std_logic_vector\n    --     note: NOT compatible with std_ulogic_vector\n    --\n\n    procedure write(l        : inout line                   ;\n                    value    : in    std_logic_vector       ;\n                    justified: in    side           := right;\n                    field    : in    width          := 0    ) is\n\n        variable m: line; -- build up intermediate string\n\n    begin\n\n        --\n        -- algorithm:\n        -- \n        --     for each value in array\n        --         add string representing value to intermediate string\n        --     write intermediate string to line parameter\n        --     free intermediate string\n        --     \n\n        -- for each value in array\n        for i in value'range loop\n\n            -- add string representing value to intermediate string\n            write( m, value( i ) );\n\n        end loop;\n\n        -- write intermediate string to line parameter\n        write( l, m.all, justified, field );\n\n        -- free intermediate string\n        deallocate( m );\n\n    end write;\n\n\n--------------------------------------------------------------------------------\n\n    ----------------------------------------------------------------------------\n    -- procedure bodies for octal and hexadecimal read and write\n    ----------------------------------------------------------------------------\n\n    --\n    -- std_logic_vector/octal\n    --     note: NOT compatible with std_ulogic_vector\n    --\n\n    procedure read_oct(l         : inout line            ; \n                       value     : out   std_logic_vector; \n                       good      : out   boolean         ) is\n\n        variable m               : line                      ; -- safe L\n        variable success         : boolean            := true; -- readable GOOD\n        variable logic_value     : std_logic                 ; -- elem value\n        variable c               : character                 ; -- char read\n        variable charcode        : integer                   ; -- char->int\n        variable oct_logic_vector: oct_logic_vector_t        ; -- for 1 digit\n        variable bitpos          : integer                   ; -- in state vec.\n    begin\n\n        --\n        -- algorithm:\n        -- \n        --     skip over leading blanks, then read a digit\n        --     and do a conversion into a logic value\n        --     for each element in array\n        --     \n\n        -- make sure logic array is right size to read this base\n        success := ( ( value'length rem oct_bits_per_digit ) = 0 );\n        if success then\n\n            -- only operate on non-empty strings\n            if ( ( l /= null ) and ( l.all'length /= 0 ) ) then\n\n                -- save old copy of string in case read fails\n                m := new string'( l.all );\n\n                -- pick off leading white space and get first significant char\n                c := ' ';\n                while success and ( l.all'length > 0 ) and ( ( c = ' ' ) or ( c = ht ) ) loop\n                    read( l, c, success );\n                end loop;\n\n                -- turn character into integer\n                charcode := octdigit2int( c );\n\n                -- not doing any bits yet\n                bitpos := 0;\n\n                -- check for bad first character\n                if charcode = bad_charcode then\n                    success := false;\n                else\n                    -- loop through each value in array\n                    oct_logic_vector := octint2logic( charcode );\n                    for i in value'range loop\n    \n                        -- doing the next bit\n                        bitpos := bitpos + 1;\n    \n                        -- stick the value in\n                        value( i ) := oct_logic_vector( bitpos );\n                        \n                        -- read the next character if we're not at array end\n                        if ( bitpos = oct_bits_per_digit ) and ( i /= value'right ) then\n                            read( l, c, success );\n                            if not success then\n                                exit;\n                            end if;\n                            -- turn character into integer\n                            charcode := octdigit2int( c );\n                            -- check for bad char\n                            if charcode = bad_charcode then\n                                success := false;\n                                exit;\n                            end if;\n                            -- reset bit position\n                            bitpos := 0;\n                            -- turn character code into state array \n                            oct_logic_vector := octint2logic( charcode );\n                        end if;\n                        \n                    end loop; -- each index in return array\n \n                end if; -- if bad first character\n\n                -- clean up working storage\n                if success then\n                    deallocate( m );\n                else\n                    deallocate( l );\n                    l := m;\n                end if;\n\n            -- no characters to read for return array that isn't null slice\n            elsif ( value'length /= 0 ) then\n                success := false;\n            end if; -- non null access, non empty string\n\n        end if;\n\n        -- set out parameter of success\n        good := success;\n\n    end read_oct;\n\n\n    procedure read_oct(l         : inout line            ; \n                       value     : out   std_logic_vector) is\n        variable success: boolean;                 -- internal good flag\n    begin                                                              \n        read_oct( l, value, success ); -- use safe version  \n        assert success \n            report \"IO1164.READ_OCT: Unable to read T_LOGIC_VECTOR value.\" \n            severity error;\n    end read_oct;\n\n    procedure write_oct(l        : inout line                   ;\n                        value    : in    std_logic_vector       ;\n                        justified: in    side           := right;\n                        field    : in    width          := 0    ) is\n\n        variable m            : line     ; -- safe copy of L\n        variable goodlength   : boolean  ; -- array is ok len for this base\n        variable isx          : boolean  ; -- an X in this digit\n        variable integer_value: integer  ; -- accumulate integer value\n        variable c            : character; -- character read\n        variable charpos      : integer  ; -- index string being contructed\n        variable bitpos       : integer  ; -- bit index inside digit\n\n    begin\n\n        --\n        -- algorithm:\n        -- \n        -- make sure this array can be written in this base\n        -- create a string to place intermediate results\n        -- initialize counters and flags to beginning of string\n        -- for each item in array\n        --     note unknown, else accumulate logic into integer\n        --         if at this digit's last bit\n        --             stuff digit just computed into intermediate result\n        --             reset flags and counters except for charpos\n        -- write intermediate result into line\n        -- free work storage\n        --     \n\n        -- make sure this array can be written in this base\n        goodlength := ( ( value'length rem oct_bits_per_digit ) = 0 );\n        assert goodlength\n            report \"IO1164.WRITE_OCT: VALUE'Length is not a multiple of 3.\"\n            severity error;\n        if goodlength then\n\n            -- create a string to place intermediate results\n            m := new string(1 to ( value'length / oct_bits_per_digit ) );\n\n            -- initialize counters and flags to beginning of string\n            charpos := 0;\n            bitpos := 0;\n            isx := false;\n            integer_value := 0;\n\n            -- for each item in array\n            for i in value'range loop\n\n                -- note unknown, else accumulate logic into integer\n                case value(i) is\n                    when '0' | 'L' =>\n                        integer_value := integer_value * 2;\n                    when '1' | 'H' =>\n                        integer_value := ( integer_value * 2 ) + 1;\n                    when others =>\n                        isx := true;\n                end case;\n\n                -- see if we've done this digit's last bit\n                bitpos := bitpos + 1;\n                if bitpos = oct_bits_per_digit then\n\n                    -- stuff the digit just computed into the intermediate result\n                    charpos := charpos + 1;\n                    if isx then\n                        m.all(charpos) := 'X';\n                    else\n                        m.all(charpos) := int2octdigit( integer_value );\n                    end if;\n\n                    -- reset flags and counters except for location in string being constructed\n                    bitpos := 0;\n                    isx := false;\n                    integer_value := 0;\n\n                end if;\n\n            end loop;\n\n            -- write intermediate result into line\n            write( l, m.all, justified, field );\n\n            -- free work storage\n            deallocate( m );\n\n        end if;\n\n    end write_oct;\n\n    --\n    -- std_logic_vector/hexadecimal\n    --     note: NOT compatible with std_ulogic_vector\n    --\n\n    procedure read_hex(l         : inout line            ; \n                       value     : out   std_logic_vector; \n                       good      : out   boolean         ) is\n\n        variable m               : line                      ; -- safe L\n        variable success         : boolean            := true; -- readable GOOD\n        variable logic_value     : std_logic                 ; -- elem value\n        variable c               : character                 ; -- char read\n        variable charcode        : integer                   ; -- char->int\n        variable hex_logic_vector: hex_logic_vector_t        ; -- for 1 digit\n        variable bitpos          : integer                   ; -- in state vec.\n    begin\n\n        --\n        -- algorithm:\n        -- \n        --     skip over leading blanks, then read a digit\n        --     and do a conversion into a logic value\n        --     for each element in array\n        --     \n\n        -- make sure logic array is right size to read this base\n        success := ( ( value'length rem hex_bits_per_digit ) = 0 );\n        if success then\n\n            -- only operate on non-empty strings\n            if ( ( l /= null ) and ( l.all'length /= 0 ) ) then\n\n                -- save old copy of string in case read fails\n                m := new string'( l.all );\n\n                -- pick off leading white space and get first significant char\n                c := ' ';\n                while success and ( l.all'length > 0 ) and ( ( c = ' ' ) or ( c = ht ) ) loop\n                    read( l, c, success );\n                end loop;\n\n                -- turn character into integer\n                charcode := hexdigit2int( c );\n\n                -- not doing any bits yet\n                bitpos := 0;\n\n                -- check for bad first character\n                if charcode = bad_charcode then\n                    success := false;\n                else\n                    -- loop through each value in array\n                    hex_logic_vector := hexint2logic( charcode );\n                    for i in value'range loop\n    \n                        -- doing the next bit\n                        bitpos := bitpos + 1;\n    \n                        -- stick the value in\n                        value( i ) := hex_logic_vector( bitpos );\n                        \n                        -- read the next character if we're not at array end\n                        if ( bitpos = hex_bits_per_digit ) and ( i /= value'right ) then\n                            read( l, c, success );\n                            if not success then\n                                exit;\n                            end if;\n                            -- turn character into integer\n                            charcode := hexdigit2int( c );\n                            -- check for bad char\n                            if charcode = bad_charcode then\n                                success := false;\n                                exit;\n                            end if;\n                            -- reset bit position\n                            bitpos := 0;\n                            -- turn character code into state array \n                            hex_logic_vector := hexint2logic( charcode );\n                        end if;\n                        \n                    end loop; -- each index in return array\n \n                end if; -- if bad first character\n\n                -- clean up working storage\n                if success then\n                    deallocate( m );\n                else\n                    deallocate( l );\n                    l := m;\n                end if;\n\n            -- no characters to read for return array that isn't null slice\n            elsif ( value'length /= 0 ) then\n                success := false;\n            end if; -- non null access, non empty string\n\n        end if;\n\n        -- set out parameter of success\n        good := success;\n\n    end read_hex;\n\n\n    procedure read_hex(l         : inout line            ; \n                       value     : out   std_logic_vector) is\n        variable success: boolean;                 -- internal good flag\n    begin                                                              \n        read_hex( l, value, success ); -- use safe version  \n        assert success \n            report \"IO1164.READ_HEX: Unable to read T_LOGIC_VECTOR value.\" \n            severity error;\n    end read_hex;\n\n    procedure write_hex(l        : inout line                   ;\n                        value    : in    std_logic_vector       ;\n                        justified: in    side           := right;\n                        field    : in    width          := 0    ) is\n\n        variable m            : line     ; -- safe copy of L\n        variable goodlength   : boolean  ; -- array is ok len for this base\n        variable isx          : boolean  ; -- an X in this digit\n        variable integer_value: integer  ; -- accumulate integer value\n        variable c            : character; -- character read\n        variable charpos      : integer  ; -- index string being contructed\n        variable bitpos       : integer  ; -- bit index inside digit\n\n    begin\n\n        --\n        -- algorithm:\n        -- \n        -- make sure this array can be written in this base\n        -- create a string to place intermediate results\n        -- initialize counters and flags to beginning of string\n        -- for each item in array\n        --     note unknown, else accumulate logic into integer\n        --         if at this digit's last bit\n        --             stuff digit just computed into intermediate result\n        --             reset flags and counters except for charpos\n        -- write intermediate result into line\n        -- free work storage\n        --     \n\n        -- make sure this array can be written in this base\n        goodlength := ( ( value'length rem hex_bits_per_digit ) = 0 );\n        assert goodlength\n            report \"IO1164.WRITE_HEX: VALUE'Length is not a multiple of 4.\"\n            severity error;\n        if goodlength then\n\n            -- create a string to place intermediate results\n            m := new string(1 to ( value'length / hex_bits_per_digit ) );\n\n            -- initialize counters and flags to beginning of string\n            charpos := 0;\n            bitpos := 0;\n            isx := false;\n            integer_value := 0;\n\n            -- for each item in array\n            for i in value'range loop\n\n                -- note unknown, else accumulate logic into integer\n                case value(i) is\n                    when '0' | 'L' =>\n                        integer_value := integer_value * 2;\n                    when '1' | 'H' =>\n                        integer_value := ( integer_value * 2 ) + 1;\n                    when others =>\n                        isx := true;\n                end case;\n\n                -- see if we've done this digit's last bit\n                bitpos := bitpos + 1;\n                if bitpos = hex_bits_per_digit then\n\n                    -- stuff the digit just computed into the intermediate result\n                    charpos := charpos + 1;\n                    if isx then\n                        m.all(charpos) := 'X';\n                    else\n                        m.all(charpos) := int2hexdigit( integer_value );\n                    end if;\n\n                    -- reset flags and counters except for location in string being constructed\n                    bitpos := 0;\n                    isx := false;\n                    integer_value := 0;\n\n                end if;\n\n            end loop;\n\n            -- write intermediate result into line\n            write( l, m.all, justified, field );\n\n            -- free work storage\n            deallocate( m );\n\n        end if;\n\n    end write_hex;\n\n------------------------------------------------------------------------------\n\n    ------------------------------------\n    -- Read octal/hex numbers to integer\n    ------------------------------------\n\n    --\n    -- Read octal to integer\n    --\n    \n    procedure read_oct(l     : inout line;\n                       value : out integer;\n                       good  : out boolean) is\n\n        variable pos     : integer;\n        variable digit   : integer;\n        variable result  : integer := 0;\n        variable success : boolean := true;\n        variable c       : character;\n        variable old_l   : line := l;\n\n    begin\n        -- algorithm:\n        --\n        --  skip leading white space, read digit, convert\n        --  into integer\n        --\n        if (l /= NULL) then\n            -- set pos to start of actual number by skipping white space\n            pos := l'LEFT;\n            c := l(pos);\n            while ( l.all'length > 0 ) and ( ( c = ' ' ) or ( c = HT ) ) loop\n                pos := pos + 1;\n                c := l(pos);\n            end loop;\n            \n            -- check for start of valid number\n            digit := octdigit2int(l(pos));\n\n            if ((digit = bad_charcode) or (digit = x_charcode)) then\n                good := FALSE;\n                return;\n            else\n                -- calculate integer value\n                for i in pos to l'RIGHT loop\n                    digit := octdigit2int(l(pos));\n                    exit when (digit = bad_charcode) or (digit = x_charcode);\n                    result := (result * 8) + digit;\n                    pos := pos + 1;\n                end loop;\n                value := result;\n                -- shrink line\n                if (pos > 1) then\n                    l := new string'(old_l(pos to old_l'HIGH));\n                    deallocate(old_l);\n                end if;\n                good := TRUE;\n                return;\n            end if;\n        else\n            good := FALSE;\n        end if;\n\n    end read_oct;\n\n    -- simple version\n    procedure read_oct(l     : inout line;\n                       value : out   integer) is\n\n        variable success: boolean;                 -- internal good flag\n\n    begin                                                              \n        read_oct( l, value, success ); -- use safe version  \n        assert success \n            report \"IO1164.READ_OCT: Unable to read octal integer value.\" \n            severity error;\n    end read_oct;\n\n\n    --\n    -- Read hex to integer\n    --\n    \n    procedure read_hex(l     : inout line;\n                       value : out integer;\n                       good  : out boolean) is\n\n        variable pos     : integer;\n        variable digit   : integer;\n        variable result  : integer := 0;\n        variable success : boolean := true;\n        variable c       : character;\n        variable old_l   : line := l;\n\n    begin\n        -- algorithm:\n        --\n        --  skip leading white space, read digit, convert\n        --  into integer\n        --\n        if (l /= NULL) then\n            -- set pos to start of actual number by skipping white space\n            pos := l'LEFT;\n            c := l(pos);\n            while ( l.all'length > 0 ) and ( ( c = ' ' ) or ( c = HT ) ) loop\n                pos := pos + 1;\n                c := l(pos);\n            end loop;\n            \n            -- check for start of valid number\n            digit := hexdigit2int(l(pos));\n\n            if ((digit = bad_charcode) or (digit = x_charcode)) then\n                good := FALSE;\n                return;\n            else\n                -- calculate integer value\n                for i in pos to l'RIGHT loop\n                    digit := hexdigit2int(l(pos));\n                    exit when (digit = bad_charcode) or (digit = x_charcode);\n                    result := (result * 16) + digit;\n                    pos := pos + 1;\n                end loop;\n                value := result;\n                -- shrink line\n                if (pos > 1) then\n                    l := new string'(old_l(pos to old_l'HIGH));\n                    deallocate(old_l);\n                end if;\n                good := TRUE;\n                return;\n            end if;\n        else\n            good := FALSE;\n        end if;\n\n    end read_hex;\n\n    -- simple version\n    procedure read_hex(l     : inout line;\n                       value : out   integer) is\n\n        variable success: boolean;                 -- internal good flag\n\n    begin                                                              \n        read_hex( l, value, success ); -- use safe version  \n        assert success \n            report \"IO1164.READ_HEX: Unable to read hex integer value.\" \n            severity error;\n    end read_hex;\n\nend io1164;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.numeric_std.all;\n\nentity asyncLdCnt is port (\n  loadVal: in std_logic_vector(3 downto 0);\n  clk, load: in std_logic;\n  q: out std_logic_vector(3 downto 0)\n  );\nend asyncLdCnt;\n\narchitecture rtl of asyncLdCnt is\n\nsignal qLocal: unsigned(3 downto 0);\n\nbegin\n\n  process (clk, load, loadVal) begin\n    if (load = '1') then\n      qLocal <= to_unsigned(loadVal);\n    elsif (clk'event and clk = '1' ) then\n      qLocal <= qLocal + 1;\n    end if;\n  end process;\n\n  q <= to_stdlogicvector(qLocal);\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.std_logic_unsigned.all;\n\nentity LoadCnt is port (\n  CntEn: in std_logic;\n  LdCnt: in std_logic;\n  LdData: in std_logic_vector(3 downto 0);\n  Clk: in std_logic;\n  Rst: in std_logic;\n  CntVal: out std_logic_vector(3 downto 0)\n  );\nend LoadCnt;\n\narchitecture behavioral of LoadCnt is\n\nsignal Cnt: std_logic_vector(3 downto 0);\n\nbegin\n\n  counter: process (Clk, Rst) begin\n    if Rst = '1' then\n      Cnt <= (others => '0');\n    elsif (Clk'event and Clk = '1') then\n      if (LdCnt = '1') then\n        Cnt <= LdData;\n      elsif (CntEn = '1') then\n        Cnt <= Cnt + 1;\n      else\n        Cnt <= Cnt;\n      end if;\n    end if;\n  end process;\n\n  CntVal <= Cnt;\n\nend behavioral;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nlibrary UTILS;\nuse UTILS.io1164.all;\nuse std.textio.all;\n\nentity loadCntTB is\nend loadCntTB;\n\narchitecture testbench of loadCntTB is\n\n  component loadCnt port (\n    data: in std_logic_vector (7 downto 0);\n    load: in std_logic;\n    clk: in std_logic;\n    rst: in std_logic;\n    q: out std_logic_vector (7 downto 0)\n    );\n  end component;\n\nfile vectorFile: text is in \"vectorfile\";\ntype vectorType is record\n  data: std_logic_vector(7 downto 0);\n  load: std_logic;\n  rst: std_logic;\n  q: std_logic_vector(7 downto 0);\nend record;\n\nsignal testVector: vectorType;\nsignal TestClk: std_logic := '0';\nsignal Qout: std_logic_vector(7 downto 0);\n\nconstant ClkPeriod: time := 100 ns;\n\nfor all: loadCnt use entity work.loadcnt(rtl);\n\nbegin\n\n-- File reading and stimulus application\n  readVec: process\n    variable VectorLine: line;\n    variable VectorValid: boolean;\n    variable vRst: std_logic;\n    variable vLoad: std_logic;\n    variable vData: std_logic_vector(7 downto 0);\n    variable vQ: std_logic_vector(7 downto 0);\n    \n  begin\n    while not endfile (vectorFile) loop\n      readline(vectorFile, VectorLine);\n\n      read(VectorLine, vRst, good => VectorValid);\n      next when not VectorValid;\n      read(VectorLine, vLoad);\n      read(VectorLine, vData);\n      read(VectorLine, vQ);\n\n      wait for ClkPeriod/4;\n\n      testVector.Rst <= vRst;\n      testVector.Load <= vLoad;\n      testVector.Data <= vData;\n      testVector.Q <= vQ;\n\n      wait for (ClkPeriod/4) * 3;\n\n    end loop;\n\n  assert false\n    report \"Simulation complete\"\n    severity note;\n\n  wait;\n\n  end process;\n\n-- Free running test clock\n  TestClk <= not TestClk after ClkPeriod/2;\n\n-- Instance of design being tested\n  u1: loadCnt port map (Data => testVector.Data,\n                        load => testVector.Load,\n                        clk => TestClk,\n                        rst => testVector.Rst,\n                        q => Qout\n                       );\n\n-- Process to verify outputs\n  verify: process (TestClk)\n  variable ErrorMsg: line;\n  begin\n    if (TestClk'event and TestClk = '0') then\n      if Qout /= testVector.Q then\n        write(ErrorMsg, string'(\"Vector failed \"));\n        write(ErrorMsg, now);\n        writeline(output, ErrorMsg);\n      end if;\n    end if;\n  end process;\n                        \n\nend testbench;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.std_logic_unsigned.all;\n\nentity loadCnt is port (\n  data: in std_logic_vector (7 downto 0);\n  load: in std_logic;\n  clk: in std_logic;\n  rst: in std_logic;\n  q: out std_logic_vector (7 downto 0)\n  );\nend loadCnt;\n\narchitecture rtl of loadCnt is\n\nsignal cnt: std_logic_vector (7 downto 0);\n\nbegin\n\n  counter: process (clk, rst) begin\n    if (rst = '1') then\n      cnt <= (others => '0');\n    elsif (clk'event and clk = '1') then\n      if (load = '1') then\n        cnt <= data;\n      else\n        cnt <= cnt + 1;\n      end if;\n    end if;\n  end process;\n\n  q <= cnt;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.std_logic_unsigned.all;\n\nentity multiplier is port (\n  a,b : in std_logic_vector (15 downto 0);\n  product: out std_logic_vector (31 downto 0)\n  );\nend multiplier;\n\narchitecture dataflow of multiplier is\n\nbegin\n\n  product <= a * b;\n\nend dataflow;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity mux is port (\n  A, B, Sel: in std_logic;\n  Y: out std_logic\n  );\nend mux;\n\narchitecture simModel of mux is\n\n-- Delay Constants\nconstant tPD_A:   time := 10 ns;\nconstant tPD_B:   time := 15 ns;\nconstant tPD_Sel: time := 5 ns;\n\nbegin\n\n  DelayMux: process (A, B, Sel)\n\n  variable localY: std_logic; -- Zero delay place holder for Y\n\n  begin\n\n  -- Zero delay model\n    case Sel is\n      when '0' =>\n        localY := A;\n      when others =>\n        localY := B;\n    end case;\n\n  -- Delay calculation\n    if (B'event) then\n      Y <= localY after tPD_B;\n    elsif (A'event) then\n      Y <= localY after tPD_A;\n    else\n      Y <= localY after tPD_Sel;\n    end if;\n\n  end process;\n\n\nend simModel;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.std_logic_unsigned.all;\n\nentity ForceShare is port (\n  a,b,c,d,e,f: in std_logic_vector (7 downto 0);\n  result: out std_logic_vector(7 downto 0)\n  );\nend ForceShare;\n\narchitecture behaviour of ForceShare is\n\nbegin\n\n  sum: process (a,c,b,d,e,f)\n  begin\n\n    if (a + b = \"10011010\") then\n      result <= c;\n    elsif (a + b = \"01011001\") then\n          result <= d;\n    elsif (a + b = \"10111011\") then\n      result <= e;\n    else\n      result <= f;\n    end if;\n  end process;\n\nend behaviour;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity TRIBUF8 is port (\n  ip: in std_logic_vector(7 downto 0);\n  oe: in std_logic;\n  op: out std_logic_vector(7 downto 0)\n  );\nend TRIBUF8;\n\narchitecture concurrent of TRIBUF8 is\n\nbegin\n\n  op <= ip when oe = '1' else (others => 'Z');\n\nend concurrent;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity TRIBUF is port (\n  ip: in std_logic;\n  oe: in std_logic;\n  op: out std_logic\n  );\nend TRIBUF;\n\narchitecture concurrent of TRIBUF is\n\nbegin\n\n  op <= ip when oe = '1' else 'Z';\n\nend concurrent;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity TRIBUF8 is port (\n  ip: in std_logic_vector(7 downto 0);\n  oe: in std_logic;\n  op: out std_logic_vector(7 downto 0)\n  );\nend TRIBUF8;\n\narchitecture sequential of TRIBUF8 is\n\nbegin\n\n  enable: process (ip,oe) begin\n    if (oe = '1') then\n      op <= ip;\n    else\n      op <= (others => 'Z');\n    end if;\n  end process;\n\nend sequential;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity TRIBUF is port (\n  ip: in bit;\n  oe: in bit;\n  op: out bit\n  );\nend TRIBUF;\n\narchitecture sequential of TRIBUF is\n\nbegin\n\n  enable: process (ip,oe) begin\n    if (oe = '1') then\n      op <= ip;\n    else\n      op <= null;\n    end if;\n  end process;\n\nend sequential;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity TRIBUF is port (\n  ip: in std_logic;\n  oe: in std_logic;\n  op: out std_logic\n  );\nend TRIBUF;\n\narchitecture sequential of TRIBUF is\n\nbegin\n\n  enable: process (ip,oe) begin\n    if (oe = '1') then\n      op <= ip;\n    else\n      op <= 'Z';\n    end if;\n  end process;\n\nend sequential;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nuse work.primitive.all;\n\nentity tribuffer is port (\n  input: in std_logic;\n  enable: in std_logic;\n  output: out std_logic\n  );\nend tribuffer;\n\narchitecture structural of tribuffer is\n\nbegin\n\n  u1: tribuf port map (ip => input,\n                       oe => enable,\n                       op => output\n                      );\n\nend structural;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nuse work.primitive.all;\n\nentity oddParityGen is\n  generic ( width : integer := 8 );\n  port (ad: in std_logic_vector (width - 1 downto 0);\n        oddParity : out std_logic ) ;\nend oddParityGen; \n\narchitecture scaleable of oddParityGen is\n\nsignal genXor: std_logic_vector(ad'range);\n\nbegin\n\n  genXOR(0) <= '0';\n\n  parTree: for i in 1 to ad'high generate\n    x1: xor2 port map (i1 => genXor(i - 1),\n                       i2 => ad(i - 1),\n                       y  => genXor(i)\n                      );\n  end generate;\n\n oddParity <= genXor(ad'high) ;\n\nend scaleable ;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity oddParityLoop is\n  generic ( width : integer := 8 );\n  port (ad: in std_logic_vector (width - 1 downto 0);\n        oddParity : out std_logic ) ;\nend oddParityLoop ; \n\narchitecture scaleable of oddParityLoop is\nbegin\n\n  process (ad) \n    variable loopXor: std_logic;\n  begin\n    loopXor := '0';\n\n    for i in 0 to width -1 loop\n        loopXor := loopXor xor ad( i ) ;\n    end loop ;\n\n    oddParity <= loopXor ;\n\n  end process;\n\nend scaleable ;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity OR2 is port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\nend OR2;\n\narchitecture rtl of OR2 is\n\nbegin\n\n  y <= '1' when i1 = '1' or i2 = '1' else '0';\n\nend rtl;\nlibrary IEEE;\nUSE IEEE.std_logic_1164.all;\n\n\nentity OR2 is port (\n  I1, I2: in std_logic;\n  Y: out std_logic\n  );\nend OR2;\n\narchitecture simple of OR2 is\n\nbegin\n\n  Y <= I1 OR I2 after 10 ns;\n\nend simple;\nlibrary IEEE;\nUSE IEEE.std_logic_1164.all;\n\npackage simPrimitives is\n\n  component OR2\n    generic (tPD: time := 1 ns);\n\n    port (I1, I2: in std_logic;\n      Y: out std_logic\n      );\n  end component;\n\nend simPrimitives;\n\n\nlibrary IEEE;\nUSE IEEE.std_logic_1164.all;\n\nentity OR2 is\n  generic (tPD: time := 1 ns);\n\n  port (I1, I2: in std_logic;\n    Y: out std_logic\n    );\nend OR2;\n\narchitecture simple of OR2 is\n\nbegin\n\n  Y <= I1 OR I2 after tPD;\n\nend simple;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity adder is port (\n  a,b: in std_logic_vector(3 downto 0);\n  sum: out std_logic_vector(3 downto 0);\n  overflow: out std_logic\n  );\nend adder;\n\narchitecture concat of adder is\n\nsignal localSum: std_logic_vector(4 downto 0);\n\nbegin\n\n  localSum <= std_logic_vector(unsigned('0' & a) + unsigned('0' & b));\n\n  sum <= localSum(3 downto 0);\n  overflow <= localSum(4);\n\nend concat;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nuse work.primitive.all;\n\nentity paramDFF is\n  generic (size: integer := 8);\n  port (\n  data: in std_logic_vector(size - 1 downto 0);\n  clock: in std_logic;\n  reset: in std_logic;\n  ff_enable: in std_logic;\n  op_enable: in std_logic;\n  qout: out std_logic_vector(size - 1 downto 0)\n  );\nend paramDFF;\n\narchitecture parameterize of paramDFF is\n\nsignal reg: std_logic_vector(size - 1 downto 0);\n\nbegin\n\n  u1: pDFFE generic map (n => size)\n            port map    (d => data,\n                         clk =>clock,\n                         rst => reset,\n                         en => ff_enable,\n                         q => reg\n                        );\n  u2: pTRIBUF generic map (n => size)\n              port map    (ip => reg,\n                           oe => op_enable,\n                           op => qout\n                          );\n\nend parameterize;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nuse work.primitive.all;\n\nentity oddParityGen is\n  generic ( width : integer := 32 );\n  port (ad: in std_logic_vector (width - 1 downto 0);\n        oddParity : out std_logic ) ;\nend oddParityGen; \n\narchitecture scaleable of oddParityGen is\n\nsignal genXor: std_logic_vector(ad'range);\n\nsignal one: std_logic := '1';\n\nbegin\n\n  parTree: for i in ad'range generate\n    g0: if i = 0 generate\n      x0: xor2 port map (i1 => one,\n                         i2 => one,\n                         y => genXor(0)\n                        );\n    end generate;\n\n    g1: if i > 0 and i <= ad'high generate\n      x1: xor2 port map (i1 => genXor(i - 1),\n                         i2 => ad(i - 1),\n                         y  => genXor(i)\n                        );\n    end generate;\n\n  end generate;\n\n oddParity <= genXor(ad'high) ;\n\nend scaleable ;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nuse work.primitive.all;\n\nentity oddParityGen is\n  generic ( width : integer := 32 ); -- (2 <= width <= 32) and a power of 2\n  port (ad: in std_logic_vector (width - 1 downto 0);\n        oddParity : out std_logic ) ;\nend oddParityGen; \n\narchitecture scaleable of oddParityGen is\n\nsignal stage0: std_logic_vector(31 downto 0);\nsignal stage1: std_logic_vector(15 downto 0);\nsignal stage2: std_logic_vector(7 downto 0);\nsignal stage3: std_logic_vector(3 downto 0);\nsignal stage4: std_logic_vector(1 downto 0);\n\nbegin\n\n  g4: for i in stage4'range generate\n    g41: if (ad'length > 2) generate\n         x4: xor2 port map (stage3(i), stage3(i + stage4'length), stage4(i));\n    end generate;\n  end generate;\n\n  g3: for i in stage3'range generate\n    g31: if (ad'length > 4) generate\n         x3: xor2 port map (stage2(i), stage2(i + stage3'length), stage3(i));\n    end generate;\n  end generate;\n\n  g2: for i in stage2'range generate\n    g21: if (ad'length > 8) generate\n         x2: xor2 port map (stage1(i), stage1(i + stage2'length), stage2(i));\n    end generate;\n  end generate;\n\n  g1: for i in stage1'range generate\n    g11: if (ad'length > 16) generate\n         x1: xor2 port map (stage0(i), stage0(i + stage1'length), stage1(i));\n    end generate;\n  end generate;\n\n\n  s1: for i in ad'range generate\n    s14: if (ad'length = 2) generate\n         stage4(i) <= ad(i);\n    end generate;\n\n    s13: if (ad'length = 4) generate\n         stage3(i) <= ad(i);\n    end generate;\n\n    s12: if (ad'length = 8) generate\n         stage2(i) <= ad(i);\n    end generate;\n\n    s11: if (ad'length = 16) generate\n         stage1(i) <= ad(i);\n    end generate;\n\n    s10: if (ad'length = 32) generate\n         stage0(i) <= ad(i);\n    end generate;\n\n  end generate;\n\n\n  genPar: xor2 port map (stage4(0), stage4(1), oddParity);\n\nend scaleable ;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.numeric_std.all;\n\nentity powerOfFour is port(\n  clk      : in  std_logic; \n  inputVal : in  unsigned(3 downto 0);\n  power    : out unsigned(15 downto 0)\n  );\nend powerOfFour;\n\narchitecture behavioral of powerOfFour is\n\n   function Pow( N, Exp : integer )  return integer is\n      Variable Result   : integer := 1;\n\n   begin\n      for i in 1 to Exp loop\n         Result := Result * N;\n      end loop;\n      return( Result );\n   end Pow;\n\nsignal inputValInt: integer range 0 to 15;\nsignal powerL: integer range 0 to 65535;\n   \nbegin\n\n   inputValInt <= to_integer(inputVal);\n   power <= to_unsigned(powerL,16);\n\n   process begin\n     wait until Clk = '1';\n\n       powerL <= Pow(inputValInt,4);\n   \n   end process;\n\nend behavioral;\npackage PowerPkg is  \n  component Power port(\n      Clk                   : in  bit; \n      inputVal              : in  bit_vector(0 to 3);\n      power                 : out bit_vector(0 to 15) );\n   end component;\nend          PowerPkg;\n\nuse work.bv_math.all;\nuse work.int_math.all;\nuse work.PowerPkg.all;\n\nentity Power is port(\n   Clk                   : in  bit; \n   inputVal              : in  bit_vector(0 to 3);\n   power                 : out bit_vector(0 to 15) );\nend    Power;\n\n\n\n\narchitecture funky of Power is\n   \n   function Pow( N, Exp : integer )  return integer is\n      Variable Result   : integer := 1;\n      Variable i        : integer := 0;\n   begin\n      while( i < Exp ) loop\n         Result := Result * N;\n         i      := i      + 1;\n      end loop;\n      return( Result );\n   end Pow;\n   \n   \n   function RollVal(  CntlVal : integer )  return integer is\n   begin\n      return( Pow( 2, CntlVal ) + 2 );\n   end RollVal;\n   \n   \nbegin\n   process \n   begin\n      wait until Clk = '1';\n         \n        power <= i2bv(Rollval(bv2I(inputVal)),16);\n   \n   end process;\nend funky;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity priority_encoder is port\n  (interrupts : in  std_logic_vector(7 downto 0);\n   priority   : in  std_logic_vector(2 downto 0);\n   result     : out std_logic_vector(2 downto 0)\n  );\nend priority_encoder;\n\narchitecture behave of priority_encoder is\nbegin\n\n  process (interrupts)\n     variable selectIn  : integer;\n     variable LoopCount : integer;\n  begin\n\n    LoopCount   := 1;\n    selectIn := to_integer(to_unsigned(priority));\n      \n      while (LoopCount <= 7) and (interrupts(selectIn) /= '0') loop\n\t\t\n        if (selectIn = 0) then\n          selectIn := 7;\n        else\n          selectIn := selectIn - 1;\n        end if;\n\t\t\t\n        LoopCount := LoopCount + 1;\n  \n      end loop;\n\t\t\n    result <= std_logic_vector(to_unsigned(selectIn,3));\n\n  end process;\n  \nend behave;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\npackage primitive is\n  component DFFE port (\n    d: in std_logic;\n    q: out std_logic;\n    en: in std_logic;\n    clk: in std_logic\n    );\n  end component;\n\n  component DFFE_SR port (\n    d: in std_logic;\n    en: in std_logic;\n    clk: in std_logic;\n    rst: in std_logic;\n    prst: in std_logic;\n    q: out std_logic\n    );\n  end component;\n\n  component DLATCHH port (\n    d: in std_logic;\n    en: in std_logic;\n    q: out std_logic\n    );\n  end component;\n\n  component AND2 port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\n  end component;\n\n  component OR2 port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\n  end component;\n\n  component INVERTER port (\n    i: in std_logic;\n    o: out std_logic\n    );\n  end component;\n\n  component TRIBUF port (\n    ip: in std_logic;\n    oe: in std_logic;\n    op: out std_logic\n    );\n  end component;\n\n  component BIDIR port (\n    ip: in std_logic;\n    oe: in std_logic;\n    op_fb: out std_logic;\n    op: inout std_logic\n    );\n  end component;\n\nend package;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFFE is port (\n    d: in std_logic;\n    q: out std_logic;\n    en: in std_logic;\n    clk: in std_logic\n    );\nend DFFE;\n\narchitecture rtl of DFFE is\n\nbegin\n\n  process begin\n    wait until clk = '1';\n      if (en = '1') then\n        q <= d;\n      end if;\n  end process;\n\nend rtl;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFFE_SR is port (\n    d: in std_logic;\n    en: in std_logic;\n    clk: in std_logic;\n    rst: in std_logic;\n    prst: in std_logic;\n    q: out std_logic\n    );\nend DFFE_SR;\n\narchitecture rtl of DFFE_SR is\n\nbegin\n\n  process (clk, rst, prst) begin\n    if (rst = '1') then\n      q <= '0';\n    elsif (prst = '1') then\n      q <= '1';\n    elsif (clk'event and clk = '1') then\n      if (en = '1') then\n        q <= d;\n      end if;\n    end if;\n  end process;\n\nend rtl;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DLATCHH is port (\n    d: in std_logic;\n    en: in std_logic;\n    q: out std_logic\n    );\nend DLATCHH;\n\narchitecture rtl of DLATCHH is\n\nbegin\n\n  process (en) begin\n    if (en = '1') then\n      q <= d;\n    end if;\n  end process;\n\nend rtl;\n\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity AND2 is port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\nend AND2;\n\narchitecture rtl of AND2 is\n\nbegin\n\n  y <= '1' when i1 = '1' and i2 = '1' else '0';\n\nend rtl;\n\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity OR2 is port (\n    i1: in std_logic;\n    i2: in std_logic;\n    y: out std_logic\n    );\nend OR2;\n\narchitecture rtl of OR2 is\n\nbegin\n\n  y <= '1' when i1 = '1' or i2 = '1' else '0';\n\nend rtl;\n\n\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity INVERTER is port (\n    i: in std_logic;\n    o: out std_logic\n    );\nend INVERTER;\n\narchitecture rtl of INVERTER is\n\nbegin\n\n  o <= not i;\n\nend rtl;\n\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity TRIBUF is port (\n  ip: in std_logic;\n  oe: in std_logic;\n  op: out std_logic\n  );\nend TRIBUF;\n\narchitecture rtl of TRIBUF is\n\nbegin\n\n  op <= ip when oe = '1' else 'Z';\n\nend rtl;\n\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity BIDIR is port (\n  ip: in std_logic;\n  oe: in std_logic;\n  op_fb: out std_logic;\n  op: inout std_logic\n  );\nend BIDIR;\n\narchitecture rtl of BIDIR is\n\nbegin\n\n  op <= ip when oe = '1' else 'Z';\n  op_fb <= op;\n\nend rtl;\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity progPulse is port (\n  clk, reset: in std_logic;\n  loadLength,loadDelay: in std_logic;\n  data: in std_logic_vector(7 downto 0);\n  pulse: out std_logic\n  );\nend progPulse;\n\narchitecture rtl of progPulse is\n\nsignal downCnt, downCntData: unsigned(7 downto 0);\nsignal downCntLd, downCntEn: std_logic;\nsignal delayCntVal, pulseCntVal: unsigned(7 downto 0);\nsignal startPulse, endPulse: std_logic;\n\nsubtype fsmType is std_logic_vector(1 downto 0);\nconstant loadDelayCnt  : fsmType := \"00\";\nconstant waitDelayEnd  : fsmType := \"10\";\nconstant loadLengthCnt : fsmType := \"11\";\nconstant waitLengthEnd : fsmType := \"01\";\n\nsignal currState, nextState: fsmType;\n\nbegin\n\n  delayreg: process (clk, reset) begin\n    if reset = '1' then\n      delayCntVal <= \"11111111\";\n    elsif clk'event and clk = '1' then\n      if loadDelay = '1' then\n        delayCntVal <= to_unsigned(data);\n      end if;\n    end if;\n  end process;\n\n  lengthReg: process (clk, reset) begin\n    if reset = '1' then\n      pulseCntVal <= \"11111111\";\n    elsif clk'event and clk = '1' then\n      if loadDelay = '1' then\n        pulseCntVal <= to_unsigned(data);\n      end if;\n    end if;\n  end process;\n\n  nextStProc: process (currState, downCnt, loadDelay, loadLength) begin\n    case currState is\n      when loadDelayCnt =>\n        nextState <= waitDelayEnd;\n\n      when waitDelayEnd =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        elsif (downCnt = 0) then\n          nextState <= loadLengthCnt;\n        else\n          nextState <= waitDelayEnd;\n        end if;\n\n      when loadLengthCnt =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        else\n          nextState <= waitLengthEnd;\n        end if;\n\n      when waitLengthEnd =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        elsif (downCnt = 0) then\n          nextState <= loadDelayCnt;\n        else\n          nextState <= waitDelayEnd;\n        end if;\n\n      when others =>\n        null;\n\n   end case;\n  end process nextStProc;\n\n  currStProc: process (clk, reset) begin\n    if (reset = '1') then\n      currState <= loadDelayCnt;\n    elsif (clk'event and clk = '1') then\n      currState <= nextState;\n    end if;\n  end process currStProc;\n\n  outConProc: process (currState, delayCntVal, pulseCntVal) begin\n    case currState is\n      when loadDelayCnt =>\n        downCntEn <= '0';\n        downCntLd <= '1';\n        downCntData <= delayCntVal;\n\n      when waitDelayEnd =>\n        downCntEn <= '1';\n        downCntLd <= '0';\n        downCntData <= delayCntVal;\n\n      when loadLengthCnt =>\n        downCntEn <= '0';\n        downCntLd <= '1';\n        downCntData <= pulseCntVal;\n\n      when waitLengthEnd =>\n        downCntEn <= '1';\n        downCntLd <= '0';\n        downCntData <= pulseCntVal;\n\n      when others =>\n        downCntEn <= '0';\n        downCntLd <= '1';\n        downCntData <= pulseCntVal;\n\n    end case;\n  end process outConProc;\n\n  downCntr: process (clk,reset) begin\n    if (reset = '1') then\n      downCnt <= \"00000000\";\n    elsif (clk'event and clk = '1') then\n      if (downCntLd = '1') then\n        downCnt <= downCntData;\n      elsif (downCntEn = '1') then\n        downCnt <= downCnt - 1;\n      else\n        downCnt <= downCnt;\n      end if;\n    end if;\n  end process;\n\n  -- Assign pulse output\n  pulse <= currState(0);\n        \n\nend rtl;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity pulseErr is port\n  (a: in std_logic;\n   b: out std_logic\n  );\nend pulseErr;\n\narchitecture behavior of pulseErr is\n\nsignal c: std_logic;\n\nbegin\n\n  pulse: process (a,c) begin\n    b <= c XOR a;\n\n    c <= a;\n  end process;\n\nend behavior;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity progPulse is port (\n  clk, reset: in std_logic;\n  loadLength,loadDelay: in std_logic;\n  data: in std_logic_vector(7 downto 0);\n  pulse: out std_logic\n  );\nend progPulse;\n\narchitecture rtl of progPulse is\n\nsignal downCnt, downCntData: unsigned(7 downto 0);\nsignal downCntLd, downCntEn: std_logic;\nsignal delayCntVal, pulseCntVal: unsigned(7 downto 0);\nsignal startPulse, endPulse: std_logic;\n\ntype progPulseFsmType is (loadDelayCnt, waitDelayEnd, loadLengthCnt, waitLengthEnd);\nsignal currState, nextState: progPulseFsmType;\n\nbegin\n\n  delayreg: process (clk, reset) begin\n    if reset = '1' then\n      delayCntVal <= \"11111111\";\n    elsif clk'event and clk = '1' then\n      if loadDelay = '1' then\n        delayCntVal <= to_unsigned(data);\n      end if;\n    end if;\n  end process;\n\n  lengthReg: process (clk, reset) begin\n    if reset = '1' then\n      pulseCntVal <= \"11111111\";\n    elsif clk'event and clk = '1' then\n      if loadDelay = '1' then\n        pulseCntVal <= to_unsigned(data);\n      end if;\n    end if;\n  end process;\n\n  nextStProc: process (currState, downCnt, loadDelay, loadLength) begin\n    case currState is\n      when loadDelayCnt =>\n        nextState <= waitDelayEnd;\n\n      when waitDelayEnd =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        elsif (downCnt = 0) then\n          nextState <= loadLengthCnt;\n        else\n          nextState <= waitDelayEnd;\n        end if;\n\n      when loadLengthCnt =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        else\n          nextState <= waitLengthEnd;\n        end if;\n\n      when waitLengthEnd =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        elsif (downCnt = 0) then\n          nextState <= loadDelayCnt;\n        else\n          nextState <= waitDelayEnd;\n        end if;\n\n      when others =>\n        null;\n\n   end case;\n  end process nextStProc;\n\n  currStProc: process (clk, reset) begin\n    if (reset = '1') then\n      currState <= loadDelayCnt;\n    elsif (clk'event and clk = '1') then\n      currState <= nextState;\n    end if;\n  end process currStProc;\n\n  outConProc: process (currState, delayCntVal, pulseCntVal) begin\n    case currState is\n      when loadDelayCnt =>\n        downCntEn <= '0';\n        downCntLd <= '1';\n        downCntData <= delayCntVal;\n        pulse <= '0';\n\n      when waitDelayEnd =>\n        downCntEn <= '1';\n        downCntLd <= '0';\n        downCntData <= delayCntVal;\n        pulse <= '0';\n\n      when loadLengthCnt =>\n        downCntEn <= '0';\n        downCntLd <= '1';\n        downCntData <= pulseCntVal;\n        pulse <= '1';\n\n      when waitLengthEnd =>\n        downCntEn <= '1';\n        downCntLd <= '0';\n        downCntData <= pulseCntVal;\n        pulse <= '1';\n\n      when others =>\n        downCntEn <= '0';\n        downCntLd <= '1';\n        downCntData <= pulseCntVal;\n        pulse <= '0';\n\n    end case;\n  end process outConProc;\n\n  downCntr: process (clk,reset) begin\n    if (reset = '1') then\n      downCnt <= \"00000000\";\n    elsif (clk'event and clk = '1') then\n      if (downCntLd = '1') then\n        downCnt <= downCntData;\n      elsif (downCntEn = '1') then\n        downCnt <= downCnt - 1;\n      else\n        downCnt <= downCnt;\n      end if;\n    end if;\n  end process;\n        \n\nend rtl;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity progPulseFsm is port (\n  downCnt: in std_logic_vector(7 downto 0);\n  delayCntVal: in std_logic_vector(7 downto 0);\n  lengthCntVal: in std_logic_vector(7 downto 0);\n  loadLength: in std_logic;\n  loadDelay: in std_logic;\n  clk: in std_logic;\n  reset: in std_logic;\n\n  downCntEn: out std_logic;\n  downCntLd: out std_logic;\n  downCntData: out std_logic_vector(7 downto 0);\n\n  pulse: out std_logic\n  );\nend progPulseFsm;\n\narchitecture fsm of progPulseFsm is\n\ntype progPulseFsmType is (loadDelayCnt, waitDelayEnd, loadLengthCnt, waitLengthEnd);\ntype stateVec is array (3 downto 0) of std_logic;\ntype stateBits is array (progPulseFsmType) of stateVec;\n\nsignal loadVal: std_logic;\n\nconstant stateTable: stateBits := (\n  loadDelayCnt =>  \"0010\",\n  waitDelayEnd =>  \"0100\",\n  loadLengthCnt => \"0011\",\n  waitLengthEnd => \"1101\" );\n--                  ^^^^\n--                  ||||__ loadVal   \n--                  |||___ downCntLd\n--                  ||____ downCntEn\n--                  |_____ pulse\n\nsignal currState, nextState: progPulseFsmType;\n\nbegin\n\n  nextStProc: process (currState, downCnt, loadDelay, loadLength) begin\n    case currState is\n      when loadDelayCnt =>\n        nextState <= waitDelayEnd;\n\n      when waitDelayEnd =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        elsif (to_unsigned(downCnt) = 0) then\n          nextState <= loadLengthCnt;\n        else\n          nextState <= waitDelayEnd;\n        end if;\n\n      when loadLengthCnt =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        else\n          nextState <= waitLengthEnd;\n        end if;\n\n      when waitLengthEnd =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        elsif (to_unsigned(downCnt) = 0) then\n          nextState <= loadDelayCnt;\n        else\n          nextState <= waitDelayEnd;\n        end if;\n\n      when others =>\n        null;\n\n   end case;\n\n  end process nextStProc;\n\n  currStProc: process (clk, reset) begin\n    if (reset = '1') then\n      currState <= loadDelayCnt;\n    elsif (clk'event and clk = '1') then\n      currState <= nextState;\n    end if;\n  end process currStProc;\n\n  pulse     <= stateTable(currState)(3);\n  downCntEn <= stateTable(currState)(2);\n  downCntLd <= stateTable(currState)(1);\n  loadVal   <= stateTable(currState)(0);\n  \n  downCntData <= delayCntVal when loadVal = '0' else lengthCntVal;\n\nend fsm;\n-- Incorporates Errata 6.1\n\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;\n\nentity progPulseFsm is port (\n  downCnt: in std_logic_vector(7 downto 0);\n  delayCntVal: in std_logic_vector(7 downto 0);\n  lengthCntVal: in std_logic_vector(7 downto 0);\n  loadLength: in std_logic;\n  loadDelay: in std_logic;\n  clk: in std_logic;\n  reset: in std_logic;\n\n  downCntEn: out std_logic;\n  downCntLd: out std_logic;\n  downtCntData: out std_logic_vector(7 downto 0);\n\n  pulse: out std_logic\n  );\nend progPulseFsm;\n\narchitecture fsm of progPulseFsm is\n\ntype progPulseFsmType is (loadDelayCnt, waitDelayEnd, loadLengthCnt, waitLengthEnd);\nsignal currState, nextState: progPulseFsmType;\nsignal downCntL: unsigned (7 downto 0);\n\nbegin\n\n  downCntL <= to_unsigned(downCnt); -- convert downCnt to unsigned\n\n  nextStProc: process (currState, downCntL, loadDelay, loadLength) begin\n    case currState is\n      when loadDelayCnt =>\n        nextState <= waitDelayEnd;\n\n      when waitDelayEnd =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        elsif (downCntL = 0) then\n          nextState <= loadLengthCnt;\n        else\n          nextState <= waitDelayEnd;\n        end if;\n\n      when loadLengthCnt =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        else\n          nextState <= waitLengthEnd;\n        end if;\n\n      when waitLengthEnd =>\n        if (loadDelay = '1' or loadLength = '1') then\n          nextState <= loadDelayCnt;\n        elsif (downCntL = 0) then\n          nextState <= loadDelayCnt;\n        else\n          nextState <= waitDelayEnd;\n        end if;\n\n      when others =>\n        null;\n\n   end case;\n\n  end process nextStProc;\n\n  currStProc: process (clk, reset) begin\n    if (reset = '1') then\n      currState <= loadDelayCnt;\n    elsif (clk'event and clk = '1') then\n      currState <= nextState;\n    end if;\n  end process currStProc;\n\n  outConProc: process (currState, delayCntVal, lengthCntVal) begin\n    case currState is\n      when loadDelayCnt =>\n        downCntEn <= '0';\n        downCntLd <= '1';\n        downtCntData <= delayCntVal;\n        pulse <= '0';\n\n      when waitDelayEnd =>\n        downCntEn <= '1';\n        downCntLd <= '0';\n        downtCntData <= delayCntVal;\n        pulse <= '0';\n\n      when loadLengthCnt =>\n        downCntEn <= '0';\n        downCntLd <= '1';\n        downtCntData <= lengthCntVal;\n        pulse <= '1';\n\n      when waitLengthEnd =>\n        downCntEn <= '1';\n        downCntLd <= '0';\n        downtCntData <= lengthCntVal;\n        pulse <= '1';\n\n      when others =>\n        downCntEn <= '0';\n        downCntLd <= '1';\n        downtCntData <= delayCntVal;\n        pulse <= '0';\n\n    end case;\n  end process outConProc;\n\nend fsm;\n-- Incorporates errata 5.4\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.numeric_std.all;\n\nuse work.specialFunctions.all;\n\nentity powerOfFour is port(\n  clk      : in  std_logic; \n  inputVal : in  std_logic_vector(3 downto 0);\n  power    : out std_logic_vector(15 downto 0)\n  );\nend powerOfFour;\n\narchitecture behavioral of powerOfFour is\n\nbegin\n\n   process begin\n     wait until Clk = '1';\n\n       power <= std_logic_vector(to_unsigned(Pow(to_integer(unsigned(inputVal)),4),16));\n   \n   end process;\n\nend behavioral;\n-- Incorporate errata 5.4\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.numeric_std.all;\n\nentity powerOfFour is port(\n  clk      : in  std_logic; \n  inputVal : in  std_logic_vector(3 downto 0);\n  power    : out std_logic_vector(15 downto 0)\n  );\nend powerOfFour;\n\narchitecture behavioral of powerOfFour is\n\n   function Pow( N, Exp : integer )  return integer is\n      Variable Result   : integer := 1;\n\n   begin\n      for i in 1 to Exp loop\n         Result := Result * N;\n      end loop;\n      return( Result );\n   end Pow;\n\nbegin\n\n   process begin\n     wait until Clk = '1';\n\n       power <= std_logic_vector(to_unsigned(Pow(to_integer(to_unsigned(inputVal)),4),16));\n   \n   end process;\n\nend behavioral;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.std_logic_arith.all;\nuse IEEE.std_logic_unsigned.all;\n\nentity powerOfFour is port(\n  clk      : in  std_logic; \n  inputVal : in  std_logic_vector(3 downto 0);\n  power    : out std_logic_vector(15 downto 0)\n  );\nend powerOfFour;\n\narchitecture behavioral of powerOfFour is\n\n   function Pow( N, Exp : integer )  return integer is\n      Variable Result   : integer := 1;\n\n   begin\n      for i in 1 to Exp loop\n         Result := Result * N;\n      end loop;\n      return( Result );\n   end Pow;\n\nbegin\n\n   process begin\n     wait until Clk = '1';\n\n       power <= conv_std_logic_vector(Pow(conv_integer(inputVal),4),16);\n   \n   end process;\n\nend behavioral;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity regFile is port (\n  clk, rst: in std_logic;\n  data: in std_logic_vector(31 downto 0);\n  regSel: in std_logic_vector(1 downto 0);\n  wrEnable: in std_logic;\n  regOut: out std_logic_vector(31 downto 0)\n  );\nend regFile;\n\narchitecture behavioral of regFile is\n\nsubtype reg is std_logic_vector(31 downto 0);\ntype regArray is array (integer range <>) of reg;\n\nsignal registerFile: regArray(0 to 3);\n\nbegin\n\n  regProc: process (clk, rst) \n  variable i: integer;\n\n  begin\n    i := 0;\n\n    if rst = '1' then\n      while i <= registerFile'high loop\n        registerFile(i) <= (others => '0');\n        i := i + 1;\n      end loop;\n\n    elsif clk'event and clk = '1' then\n      if (wrEnable = '1') then\n        case regSel is\n          when \"00\" =>\n            registerFile(0) <= data;\n          when \"01\" =>\n            registerFile(1) <= data;\n          when \"10\" =>\n            registerFile(2) <= data;\n          when \"11\" =>\n            registerFile(3) <= data;\n          when others =>\n            null;\n        end case;\n      end if;\n    end if;\n  end process;\n\n  outputs: process(regSel, registerFile) begin\n    case regSel is\n      when \"00\" =>\n        regOut <= registerFile(0);\n      when \"01\" =>\n        regOut <= registerFile(1);\n      when \"10\" =>\n        regOut <= registerFile(2);\n      when \"11\" =>\n        regOut <= registerFile(3);\n      when others =>\n        null;\n    end case;\n  end process;\n\nend behavioral;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity DFF is port (\n    d1,d2: in std_logic;\n    q1,q2: out std_logic;\n    clk: in std_logic;\n    rst : in std_logic\n    );\nend DFF;\n\narchitecture rtl of DFF is\n\nbegin\n\n  resetLatch: process (clk, rst) begin\n    if rst = '1' then\n      q1 <= '0';\n    elsif clk'event and clk = '1' then\n      q1 <= d1;\n      q2 <= d2;\n    end if;\n  end process;\n\nend rtl;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity resFcnDemo is port (\n  a, b: in std_logic;\n  oeA,oeB: in std_logic;\n  result: out std_logic\n  );\nend resFcnDemo;\n\narchitecture multiDriver of resFcnDemo is\n\nbegin\n\n  result <= a when oeA = '1' else 'Z';\n  result <= b when oeB = '1' else 'Z';\n\nend multiDriver;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nuse work.primitive.all;\n\nentity scaleDFF is port (\n  data: in std_logic_vector(7 downto 0);\n  clock: in std_logic;\n  enable: in std_logic;\n  qout: out std_logic_vector(7 downto 0)\n  );\nend scaleDFF;\n\narchitecture scalable of scaleDFF is\n\nbegin\n\n  u1: sDFFE port map (d => data,\n                      clk =>clock,\n                      en => enable,\n                      q => qout\n                     );\n\nend scalable;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.std_logic_unsigned.all;\n\nentity sevenSegment is port (\n  bcdInputs: in std_logic_vector (3 downto 0);\n  a_n, b_n, c_n, d_n,\n  e_n, f_n, g_n: out std_logic\n  );\nend sevenSegment;\n\narchitecture behavioral of sevenSegment is\n\nsignal la_n, lb_n, lc_n, ld_n, le_n, lf_n, lg_n: std_logic;\nsignal oe: std_logic;\n\nbegin\n\n  bcd2sevSeg: process (bcdInputs) begin\n\n  -- Assign default to \"off\"\n    la_n <= '1';    lb_n <= '1';\n    lc_n <= '1';    ld_n <= '1';\n    le_n <= '1';    lf_n <= '1';\n    lg_n <= '1';\n\n    case bcdInputs is\n      when \"0000\" => la_n <= '0';        lb_n <= '0';\n                     lc_n <= '0';        ld_n <= '0';\n                     le_n <= '0';        lf_n <= '0';\n\n      when \"0001\" => lb_n <= '0';        lc_n <= '0';\n\n      when \"0010\" => la_n <= '0';        lb_n <= '0';\n                     ld_n <= '0';        le_n <= '0';\n                     lg_n <= '0';\n\n      when \"0011\" => la_n <= '0';        lb_n <= '0';\n                     lc_n <= '0';        ld_n <= '0';\n                     lg_n <= '0';\n\n      when \"0100\" => lb_n <= '0';        lc_n <= '0';\n                     lf_n <= '0';        lg_n <= '0';\n\n      when \"0101\" => la_n <= '0';        lc_n <= '0';\n                     ld_n <= '0';        lf_n <= '0';\n                     lg_n <= '0';\n\n      when \"0110\" => la_n <= '0';        lc_n <= '0';\n                     ld_n <= '0';        le_n <= '0';\n                     lf_n <= '0';        lg_n <= '0';\n\n      when \"0111\" => la_n <= '0';        lb_n <= '0';\n                     lc_n <= '0';\n\n      when \"1000\" => la_n <= '0';        lb_n <= '0';\n                     lc_n <= '0';        ld_n <= '0';\n                     le_n <= '0';        lf_n <= '0';\n                     lg_n <= '0';\n\n      when \"1001\" => la_n <= '0';        lb_n <= '0';\n                     lc_n <= '0';        ld_n <= '0';\n                     lf_n <= '0';        lg_n <= '0';\n\n-- All other inputs possibilities are \"don't care\"\n\n      when others => la_n <= 'X';        lb_n <= 'X';\n                     lc_n <= 'X';        ld_n <= 'X';\n                     le_n <= 'X';        lf_n <= 'X';\n                     lg_n <= 'X';\n\n    end case;\n\n  end process bcd2sevSeg;\n\n  -- Disable outputs for all invalid input values\n\n  oe <= '1' when (bcdInputs < 10) else '0';\n\n  a_n <= la_n when oe = '1' else 'Z';\n  b_n <= lb_n when oe = '1' else 'Z';\n  c_n <= lc_n when oe = '1' else 'Z';\n  d_n <= ld_n when oe = '1' else 'Z';\n  e_n <= le_n when oe = '1' else 'Z';\n  f_n <= lf_n when oe = '1' else 'Z';\n  g_n <= lg_n when oe = '1' else 'Z';\n\n\nend behavioral;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nuse std.textio.all;\n\nentity sevenSegmentTB is\nend sevenSegmentTB;\n\narchitecture testbench of sevenSegmentTB is\n\ncomponent sevenSegment port (\n  bcdInputs: in std_logic_vector (3 downto 0);\n  a_n, b_n, c_n, d_n,\n  e_n, f_n, g_n: out std_logic\n  );\nend component;\n\ntype vector is record\n  bcdStimulus: std_logic_vector(3 downto 0);\n  sevSegOut: std_logic_vector(6 downto 0);\nend record;\n\nconstant NumVectors: integer:= 17;\nconstant PropDelay: time := 40 ns;\nconstant SimLoopDelay: time := 10 ns;\n\ntype vectorArray is array (0 to NumVectors - 1) of vector;\nconstant vectorTable: vectorArray := (\n  (bcdStimulus => \"0000\", sevSegOut => \"0000001\"),\n  (bcdStimulus => \"0001\", sevSegOut => \"1001111\"),\n  (bcdStimulus => \"0010\", sevSegOut => \"0010010\"),\n  (bcdStimulus => \"0011\", sevSegOut => \"0000110\"),\n  (bcdStimulus => \"0100\", sevSegOut => \"1001100\"),\n  (bcdStimulus => \"0101\", sevSegOut => \"0100100\"),\n  (bcdStimulus => \"0110\", sevSegOut => \"0100000\"),\n  (bcdStimulus => \"0111\", sevSegOut => \"0001111\"),\n  (bcdStimulus => \"1000\", sevSegOut => \"0000000\"),\n  (bcdStimulus => \"1001\", sevSegOut => \"0000100\"),\n  (bcdStimulus => \"1010\", sevSegOut => \"ZZZZZZZ\"),\n  (bcdStimulus => \"1011\", sevSegOut => \"ZZZZZZZ\"),\n  (bcdStimulus => \"1100\", sevSegOut => \"ZZZZZZZ\"),\n  (bcdStimulus => \"1101\", sevSegOut => \"ZZZZZZZ\"),\n  (bcdStimulus => \"1110\", sevSegOut => \"ZZZZZZZ\"),\n  (bcdStimulus => \"1111\", sevSegOut => \"ZZZZZZZ\"),\n  (bcdStimulus => \"0000\", sevSegOut => \"0110110\") -- this vector fails\n  );\n\nfor all : sevenSegment use entity work.sevenSegment(behavioral);\n\nsignal StimInputs: std_logic_vector(3 downto 0);\nsignal CaptureOutputs: std_logic_vector(6 downto 0);\n\nbegin\n\n  u1: sevenSegment port map (bcdInputs => StimInputs,\n                             a_n => CaptureOutputs(6),\n                             b_n => CaptureOutputs(5),\n                             c_n => CaptureOutputs(4),\n                             d_n => CaptureOutputs(3),\n                             e_n => CaptureOutputs(2),\n                             f_n => CaptureOutputs(1),\n                             g_n => CaptureOutputs(0));\n\n  LoopStim: process\n    variable FoundError: boolean := false;\n    variable TempVector: vector;\n    variable ErrorMsgLine: line;\n  begin\n\n    for i in vectorTable'range loop\n      TempVector := vectorTable(i);\n\n      StimInputs <= TempVector.bcdStimulus;\n\n      wait for PropDelay;\n\n      if CaptureOutputs /= TempVector.sevSegOut then\n          write (ErrorMsgLine, string'(\"Vector failed at \"));\n          write (ErrorMsgLine, now);\n          writeline (output, ErrorMsgLine);\n          FoundError := true;\n      end if;\n\n      wait for SimLoopDelay;\n\n    end loop;\n\n  assert FoundError\n    report \"No errors. All vectors passed.\"\n    severity note;\n\n  wait;\n\n  end process;\n\nend testbench;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity sevenSegment is port (\n  bcdInputs: in std_logic_vector (3 downto 0);\n  a_n, b_n, c_n, d_n,\n  e_n, f_n, g_n: out std_logic\n  );\nend sevenSegment;\n\narchitecture behavioral of sevenSegment is\n\nbegin\n\n  bcd2sevSeg: process (bcdInputs) begin\n\n  -- Assign default to \"off\"\n    a_n <= '1';    b_n <= '1';\n    c_n <= '1';    d_n <= '1';\n    e_n <= '1';    f_n <= '1';\n    g_n <= '1';\n\n    case bcdInputs is\n      when \"0000\" =>\n        a_n <= '0';        b_n <= '0';\n        c_n <= '0';        d_n <= '0';\n        e_n <= '0';        f_n <= '0';\n\n      when \"0001\" =>\n        b_n <= '0';        c_n <= '0';\n\n      when \"0010\" =>\n        a_n <= '0';        b_n <= '0';\n        d_n <= '0';        e_n <= '0';\n        g_n <= '0';\n\n      when \"0011\" =>\n        a_n <= '0';        b_n <= '0';\n        c_n <= '0';        d_n <= '0';\n        g_n <= '0';\n\n      when \"0100\" =>\n        b_n <= '0';        c_n <= '0';\n        f_n <= '0';        g_n <= '0';\n\n      when \"0101\" =>\n        a_n <= '0';        c_n <= '0';\n        d_n <= '0';        f_n <= '0';\n        g_n <= '0';\n\n      when \"0110\" =>\n        a_n <= '0';        c_n <= '0';\n        d_n <= '0';        e_n <= '0';\n        f_n <= '0';        g_n <= '0';\n\n      when \"0111\" =>\n        a_n <= '0';        b_n <= '0';\n        c_n <= '0';\n\n      when \"1000\" =>\n        a_n <= '0';        b_n <= '0';\n        c_n <= '0';        d_n <= '0';\n        e_n <= '0';        f_n <= '0';\n        g_n <= '0';\n\n      when \"1001\" =>\n        a_n <= '0';        b_n <= '0';\n        c_n <= '0';        d_n <= '0';\n        f_n <= '0';        g_n <= '0';\n\n      when others =>\n        null;\n\n    end case;\n\n  end process bcd2sevSeg;\n\nend behavioral;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\nuse IEEE.std_logic_unsigned.all;\n\nentity ForceShare is port (\n  a,b,c,d,e,f: in std_logic_vector (7 downto 0);\n  result: out std_logic_vector(7 downto 0)\n  );\nend ForceShare;\n\narchitecture behaviour of ForceShare is\n\nbegin\n\n  sum: process (a,c,b,d,e,f)\n  variable tempSum: std_logic_vector(7 downto 0);\n  begin\n\n    tempSum := a + b; -- temporary node for sum\n\n    if (tempSum = \"10011010\") then\n      result <= c;\n    elsif (tempSum = \"01011001\") then\n          result <= d;\n    elsif (tempSum = \"10111011\") then\n      result <= e;\n    else\n      result <= f;\n    end if;\n  end process;\n\nend behaviour;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity shifter is port (\n  clk, rst: in std_logic;\n  shiftEn,shiftIn: std_logic;\n  q: out std_logic_vector (15 downto 0)\n  );\nend shifter;\n\n\narchitecture behav of shifter is\n\nsignal qLocal: std_logic_vector(15 downto 0);\n\nbegin\n\n  shift: process (clk, rst) begin\n    if (rst = '1') then\n      qLocal <= (others => '0');\n    elsif (clk'event and clk = '1') then\n      if (shiftEn = '1') then\n        qLocal <= qLocal(14 downto 0) & shiftIn;\n      else\n        qLocal <= qLocal;\n      end if;\n    end if;\n\n    q <= qLocal;\n  end process;\n\nend behav;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity lastAssignment is port\n  (a, b: in std_logic;\n   selA, selb: in std_logic;\n   result: out std_logic\n  );\nend lastAssignment;\n\narchitecture behavioral of lastAssignment is\n\nbegin\n\n  demo: process (a,b,selA,selB) begin\n    if (selA = '1') then\n      result <= a;\n    else\n      result <= '0';\n    end if;\n\n    if (selB = '1') then\n      result <= b;\n    else\n      result <= '0';\n    end if;\n  end process demo;\n\nend behavioral;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity signalDemo is port (\n  a: in std_logic;\n  b: out std_logic\n  );\nend signalDemo;\n\narchitecture basic of signalDemo is\n\nsignal c: std_logic;\n\nbegin\n\n  demo: process (a) begin\n\n    c <= a;\n\n    if c = '0' then\n      b <= a;\n    else\n      b <= '0';\n    end if;\n\n  end process;\n\nend basic;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity signalDemo is port (\n  a: in std_logic;\n  b: out std_logic\n  );\nend signalDemo;\n\narchitecture basic of signalDemo is\n\nsignal c: std_logic;\n\nbegin\n\n  demo: process (a) begin\n\n    c <= a;\n\n    if c = '1' then\n      b <= a;\n    else\n      b <= '0';\n    end if;\n\n  end process;\n\nend basic;\nlibrary IEEE;\nUSE IEEE.std_logic_1164.all;\n\npackage simPrimitives is\n\n  component OR2\n    generic (tPD: time := 1 ns);\n\n    port (I1, I2: in std_logic;\n          Y: out std_logic\n         );\n  end component;\n\n  component SimDFF\n  generic(tCQ: time := 1 ns;\n          tS : time := 1 ns;\n          tH : time := 1 ns\n         );\n  port (D, Clk: in std_logic;\n        Q: out std_logic\n       );\n  end component;\n\n\nend simPrimitives;\n\n\nlibrary IEEE;\nUSE IEEE.std_logic_1164.all;\n\nentity OR2 is\n  generic (tPD: time := 1 ns);\n\n  port (I1, I2: in std_logic;\n    Y: out std_logic\n    );\nend OR2;\n\narchitecture simple of OR2 is\n\nbegin\n\n  Y <= I1 OR I2 after tPD;\n\nend simple;\n\n\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity SimDFF is\n  generic(tCQ: time := 1 ns;\n          tS : time := 1 ns;\n          tH : time := 1 ns\n         );\n  port (D, Clk: in std_logic;\n  Q: out std_logic\n  );\nend SimDff;\n\narchitecture SimModel of SimDFF is\n\nbegin\n\n  reg: process (Clk, D) begin\n\n    -- Assign output tCQ after rising clock edge\n    if (Clk'event and Clk = '1') then\n      Q <= D after tCQ;\n    end if;\n\n    -- Check setup time\n    if (Clk'event and Clk = '1') then\n      assert (D'last_event >= tS)\n        report \"Setup time violation\"\n        severity Warning;\n    end if;\n\n    -- Check hold time\n    if (D'event and Clk'stable and Clk = '1') then\n      assert (D'last_event - Clk'last_event > tH)\n        report \"Hold Time Violation\"\n        severity Warning;\n    end if;\n\n  end process;\n\nend simModel;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity SRFF is port (\n    s,r: in std_logic;\n    clk: in std_logic;\n    q: out std_logic\n    );\nend SRFF;\n\narchitecture rtl of SRFF is\n\nbegin\n\n  process begin\n    wait until rising_edge(clk);\n      if s = '0' and r = '1' then\n\tq <= '0';\n      elsif s = '1' and r = '0' then\n\tq <= '1';\n      end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity SRFF is port (\n    s,r: in std_logic;\n    clk: in std_logic;\n    q: out std_logic\n    );\nend SRFF;\n\narchitecture rtl of SRFF is\n\nbegin\n\n  process begin\n    wait until clk = '1';\n      if s = '0' and r = '1' then\n\tq <= '0';\n      elsif s = '1' and r = '0' then\n\tq <= '1';\n      end if;\n  end process;\n\nend rtl;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\npackage scaleable is\n  component scaleUpCnt port (\n    clk: in std_logic;\n    reset: in std_logic;\n    cnt: in std_logic_vector\n    );\n  end component;\nend scaleable;\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nuse work.primitive.all;\n\nentity scaleUpCnt is port (\n  clk: in std_logic;\n  reset: in std_logic;\n  cnt: out std_logic_vector\n  );\nend scaleUpCnt;\n\narchitecture scaleable of scaleUpCnt is\n\nsignal one: std_logic := '1';\nsignal cntL: std_logic_vector(cnt'range);\nsignal andTerm: std_logic_vector(cnt'range);\n\nbegin\n\n-- Special case is the least significant bit\n\n  lsb: tff port map (t => one,\n                     reset => reset,\n                     clk => clk,\n                     q => cntL(cntL'low)\n                    );\n\n  andTerm(0) <= cntL(cntL'low);\n\n\n-- General case for all other bits\n\n  genAnd: for i in 1 to cntL'high generate\n    andTerm(i) <= andTerm(i - 1) and cntL(i);\n  end generate;\n\n  genTFF: for i in 1 to cntL'high generate\n    t1: tff port map (t => andTerm(i),\n                      clk => clk,\n                      reset => reset,\n                      q => cntl(i)\n                     );\n  end generate;\n\n  cnt <= CntL;\n\nend scaleable;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity pci_target is port (\n  PCI_Frame_n: in std_logic;\t-- PCI Frame#\n  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#\n  Hit: in std_logic;\t\t\t-- Hit on address decode\n  D_Done: in std_logic;\t\t\t-- Device decode complete\n  Term: in std_logic;\t\t\t-- Terminate transaction\n  Ready: in std_logic;\t\t\t-- Ready to transfer data\n  Cmd_Write: in std_logic;\t\t-- Command is Write\n  Cmd_Read: in std_logic;\t\t-- Command is Read\n  T_Abort: in std_logic;\t\t-- Target error  - abort transaction\n  PCI_Clk: in std_logic;\t\t-- PCI Clock\n  PCI_Reset_n: in std_logic;\t-- PCI Reset#\n\n  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#\n  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#\n  PCI_Stop_n: out std_logic;\t-- PCI Stop#\n  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable\n  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable\n  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable\n  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable\n\n  );\nend pci_target;\n\narchitecture fsm of pci_target is\n\nsignal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;\n\nsubtype targetFsmType is std_logic_vector(2 downto 0);\n\nconstant Idle: \t\ttargetFsmType := \"000\";\nconstant B_Busy: \t\ttargetFsmType := \"101\";\nconstant Backoff: \ttargetFsmType := \"010\";\nconstant S_Data: \t\ttargetFsmType := \"011\";\nconstant Turn_Ar: \ttargetFsmType := \"110\";\n\nsignal currState, nextState: targetFsmType;\n\nbegin\n\n nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,\n\t\t\t         LPCI_Devsel_n, LPCI_Stop_n, Term, Ready) begin\n   case currState is\n     when IDLE  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n    when B_BUSY =>\n      if (PCI_Frame_n ='1' and D_Done = '1') or\n\t     (PCI_Frame_n = '1' and D_Done = '0' and LPCI_Devsel_n = '0') then\n        nextState <= IDLE;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '0' or (Term = '1' and Ready = '1') ) then\n        nextState <= S_Data;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '1' and Ready = '0') then\n        nextState <= BACKOFF;\n      else\n        nextState <= B_BUSY;\n      end if;\n\n    when S_DATA =>\n      if PCI_Frame_n = '0' and LPCI_Stop_n = '0' and (LPCI_Trdy_n = '1' or PCI_Irdy_n = '0') then\n        nextState <= BACKOFF;\n      elsif PCI_Frame_n = '1' and (LPCI_Trdy_n = '0' or LPCI_Stop_n = '0') then\n        nextState <= TURN_AR;\n      else\n        nextState <= S_DATA;\n      end if;\n\n\n    when BACKOFF =>\n      if PCI_Frame_n = '1' then\n        nextState <= TURN_AR;\n      else\n        nextState <= BACKOFF;\n      end if;\n\n    when TURN_AR  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n      when others =>\n\t    null;\n    end case;\n  end process nxtStProc;\n\n\n  curStProc: process (PCI_Clk, PCI_Reset_n) begin\n    if (PCI_Reset_n = '0') then\n      currState <= Idle;\n    elsif (PCI_Clk'event and PCI_Clk = '1') then\n      currState <= nextState;\n    end if;\n  end process curStProc;\n\n\n  outConProc: process (currState, Ready, T_Abort, Cmd_Write,\n                       Cmd_Read, T_Abort, Term) begin\n    case currState is\n      when S_Data =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        if (Ready = '1' and T_Abort = '0' and (Cmd_Write = '1' or Cmd_Read = '1')) then\n          LPCI_Trdy_n <= '0';\n        else\n          LPCI_Trdy_n <= '1';\n        end if;\n\n        if (T_Abort = '1' or Term = '1') and (Cmd_Write = '1' or Cmd_Read = '1')  then\n          LPCI_Stop_n <= '0';\n        else\n          LPCI_Stop_n <= '1';\n        end if;\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n      when Backoff =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        LPCI_Stop_n <= '0';\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n      when Turn_Ar =>\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n\t  when others =>\n\n        OE_Trdy_n <= '0';\n        OE_Stop_n <= '0';\n        OE_Devsel_n <= '0';\n\t\tOE_AD <= '0';\n        LPCI_Trdy_n <= '1';\n        LPCI_Stop_n <= '1';\n        LPCI_Devsel_n <= '1';\n\n    end case;\n\n  end process outConProc;\n\n  PCI_Devsel_n <= LPCI_Devsel_n;\n  PCI_Trdy_n <= LPCI_Trdy_n;\n  PCI_Stop_n <= LPCI_Stop_n;\n\nend fsm;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity pci_target is port (\n  PCI_Frame_n: in std_logic;\t-- PCI Frame#\n  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#\n  Hit: in std_logic;\t\t\t-- Hit on address decode\n  D_Done: in std_logic;\t\t\t-- Device decode complete\n  Term: in std_logic;\t\t\t-- Terminate transaction\n  Ready: in std_logic;\t\t\t-- Ready to transfer data\n  Cmd_Write: in std_logic;\t\t-- Command is Write\n  Cmd_Read: in std_logic;\t\t-- Command is Read\n  T_Abort: in std_logic;\t\t-- Target error  - abort transaction\n  PCI_Clk: in std_logic;\t\t-- PCI Clock\n  PCI_Reset_n: in std_logic;\t-- PCI Reset#\n\n  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#\n  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#\n  PCI_Stop_n: out std_logic;\t-- PCI Stop#\n  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable\n  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable\n  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable\n  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable\n\n  );\nend pci_target;\n\narchitecture fsm of pci_target is\n\nsignal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;\n\nsubtype targetFsmType is std_logic_vector(2 downto 0);\n\nconstant Idle: \t\ttargetFsmType := \"000\";\nconstant B_Busy: \t\ttargetFsmType := \"001\";\nconstant Backoff: \ttargetFsmType := \"011\";\nconstant S_Data: \t\ttargetFsmType := \"010\";\nconstant Turn_Ar: \ttargetFsmType := \"110\";\n\nsignal currState, nextState: targetFsmType;\n\nbegin\n\n nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,\n\t\t\t         LPCI_Devsel_n, LPCI_Stop_n, Term, Ready) begin\n   case currState is\n     when IDLE  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n    when B_BUSY =>\n      if (PCI_Frame_n ='1' and D_Done = '1') or\n\t     (PCI_Frame_n = '1' and D_Done = '0' and LPCI_Devsel_n = '0') then\n        nextState <= IDLE;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '0' or (Term = '1' and Ready = '1') ) then\n        nextState <= S_Data;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '1' and Ready = '0') then\n        nextState <= BACKOFF;\n      else\n        nextState <= B_BUSY;\n      end if;\n\n    when S_DATA =>\n      if PCI_Frame_n = '0' and LPCI_Stop_n = '0' and (LPCI_Trdy_n = '1' or PCI_Irdy_n = '0') then\n        nextState <= BACKOFF;\n      elsif PCI_Frame_n = '1' and (LPCI_Trdy_n = '0' or LPCI_Stop_n = '0') then\n        nextState <= TURN_AR;\n      else\n        nextState <= S_DATA;\n      end if;\n\n\n    when BACKOFF =>\n      if PCI_Frame_n = '1' then\n        nextState <= TURN_AR;\n      else\n        nextState <= BACKOFF;\n      end if;\n\n    when TURN_AR  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n      when others =>\n\t    null;\n    end case;\n  end process nxtStProc;\n\n\n  curStProc: process (PCI_Clk, PCI_Reset_n) begin\n    if (PCI_Reset_n = '0') then\n      currState <= Idle;\n    elsif (PCI_Clk'event and PCI_Clk = '1') then\n      currState <= nextState;\n    end if;\n  end process curStProc;\n\n\n  outConProc: process (currState, Ready, T_Abort, Cmd_Write,\n                       Cmd_Read, T_Abort, Term) begin\n    case currState is\n      when S_Data =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        if (Ready = '1' and T_Abort = '0' and (Cmd_Write = '1' or Cmd_Read = '1')) then\n          LPCI_Trdy_n <= '0';\n        else\n          LPCI_Trdy_n <= '1';\n        end if;\n\n        if (T_Abort = '1' or Term = '1') and (Cmd_Write = '1' or Cmd_Read = '1')  then\n          LPCI_Stop_n <= '0';\n        else\n          LPCI_Stop_n <= '1';\n        end if;\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n      when Backoff =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        LPCI_Stop_n <= '0';\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n      when Turn_Ar =>\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n\t  when others =>\n\n        OE_Trdy_n <= '0';\n        OE_Stop_n <= '0';\n        OE_Devsel_n <= '0';\n\t\tOE_AD <= '0';\n        LPCI_Trdy_n <= '1';\n        LPCI_Stop_n <= '1';\n        LPCI_Devsel_n <= '1';\n\n    end case;\n\n  end process outConProc;\n\n  PCI_Devsel_n <= LPCI_Devsel_n;\n  PCI_Trdy_n <= LPCI_Trdy_n;\n  PCI_Stop_n <= LPCI_Stop_n;\n\nend fsm;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity pci_target is port (\n  PCI_Frame_n: in std_logic;\t-- PCI Frame#\n  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#\n  Hit: in std_logic;\t\t\t-- Hit on address decode\n  D_Done: in std_logic;\t\t\t-- Device decode complete\n  Term: in std_logic;\t\t\t-- Terminate transaction\n  Ready: in std_logic;\t\t\t-- Ready to transfer data\n  Cmd_Write: in std_logic;\t\t-- Command is Write\n  Cmd_Read: in std_logic;\t\t-- Command is Read\n  T_Abort: in std_logic;\t\t-- Target error  - abort transaction\n  PCI_Clk: in std_logic;\t\t-- PCI Clock\n  PCI_Reset_n: in std_logic;\t-- PCI Reset#\n\n  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#\n  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#\n  PCI_Stop_n: out std_logic;\t-- PCI Stop#\n  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable\n  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable\n  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable\n  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable\n\n  );\nend pci_target;\n\narchitecture fsm of pci_target is\n\nsignal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;\n\nsubtype targetFsmType is std_logic_vector(2 downto 0);\n\nconstant Idle: \t\ttargetFsmType := \"000\";\nconstant B_Busy: \ttargetFsmType := \"001\";\nconstant Backoff: \ttargetFsmType := \"010\";\nconstant S_Data: \ttargetFsmType := \"011\";\nconstant Turn_Ar: \ttargetFsmType := \"100\";\n\nsignal currState, nextState: targetFsmType;\n\nbegin\n\n nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,\n\t\t\t         LPCI_Devsel_n, LPCI_Stop_n, Term, Ready) begin\n   case currState is\n     when IDLE  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n    when B_BUSY =>\n      if (PCI_Frame_n ='1' and D_Done = '1') or\n\t     (PCI_Frame_n = '1' and D_Done = '0' and LPCI_Devsel_n = '0') then\n        nextState <= IDLE;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '0' or (Term = '1' and Ready = '1') ) then\n        nextState <= S_Data;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '1' and Ready = '0') then\n        nextState <= BACKOFF;\n      else\n        nextState <= B_BUSY;\n      end if;\n\n    when S_DATA =>\n      if PCI_Frame_n = '0' and LPCI_Stop_n = '0' and (LPCI_Trdy_n = '1' or PCI_Irdy_n = '0') then\n        nextState <= BACKOFF;\n      elsif PCI_Frame_n = '1' and (LPCI_Trdy_n = '0' or LPCI_Stop_n = '0') then\n        nextState <= TURN_AR;\n      else\n        nextState <= S_DATA;\n      end if;\n\n\n    when BACKOFF =>\n      if PCI_Frame_n = '1' then\n        nextState <= TURN_AR;\n      else\n        nextState <= BACKOFF;\n      end if;\n\n    when TURN_AR  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n      when others =>\n\t    null;\n    end case;\n  end process nxtStProc;\n\n\n  curStProc: process (PCI_Clk, PCI_Reset_n) begin\n    if (PCI_Reset_n = '0') then\n      currState <= Idle;\n    elsif (PCI_Clk'event and PCI_Clk = '1') then\n      currState <= nextState;\n    end if;\n  end process curStProc;\n\n\n  outConProc: process (currState, Ready, T_Abort, Cmd_Write,\n                       Cmd_Read, T_Abort, Term) begin\n    case currState is\n      when S_Data =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        if (Ready = '1' and T_Abort = '0' and (Cmd_Write = '1' or Cmd_Read = '1')) then\n          LPCI_Trdy_n <= '0';\n        else\n          LPCI_Trdy_n <= '1';\n        end if;\n\n        if (T_Abort = '1' or Term = '1') and (Cmd_Write = '1' or Cmd_Read = '1')  then\n          LPCI_Stop_n <= '0';\n        else\n          LPCI_Stop_n <= '1';\n        end if;\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n      when Backoff =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        LPCI_Stop_n <= '0';\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n      when Turn_Ar =>\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n\t  when others =>\n\n        OE_Trdy_n <= '0';\n        OE_Stop_n <= '0';\n        OE_Devsel_n <= '0';\n\t\tOE_AD <= '0';\n        LPCI_Trdy_n <= '1';\n        LPCI_Stop_n <= '1';\n        LPCI_Devsel_n <= '1';\n\n    end case;\n\n  end process outConProc;\n\n  PCI_Devsel_n <= LPCI_Devsel_n;\n  PCI_Trdy_n <= LPCI_Trdy_n;\n  PCI_Stop_n <= LPCI_Stop_n;\n\nend fsm;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity pci_target is port (\n  PCI_Frame_n: in std_logic;\t-- PCI Frame#\n  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#\n  Hit: in std_logic;\t\t\t-- Hit on address decode\n  D_Done: in std_logic;\t\t\t-- Device decode complete\n  Term: in std_logic;\t\t\t-- Terminate transaction\n  Ready: in std_logic;\t\t\t-- Ready to transfer data\n  Cmd_Write: in std_logic;\t\t-- Command is Write\n  Cmd_Read: in std_logic;\t\t-- Command is Read\n  T_Abort: in std_logic;\t\t-- Target error  - abort transaction\n  PCI_Clk: in std_logic;\t\t-- PCI Clock\n  PCI_Reset_n: in std_logic;\t-- PCI Reset#\n\n  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#\n  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#\n  PCI_Stop_n: out std_logic;\t-- PCI Stop#\n  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable\n  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable\n  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable\n  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable\n\n  );\nend pci_target;\n\narchitecture fsm of pci_target is\n\nsignal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;\n\nsubtype targetFsmType is std_logic_vector(3 downto 0);\n\nconstant Idle: \t\ttargetFsmType := \"0000\";\nconstant B_Busy: \ttargetFsmType := \"0001\";\nconstant Backoff: \ttargetFsmType := \"0011\";\nconstant S_Data: \ttargetFsmType := \"1100\";\nconstant Turn_Ar: \ttargetFsmType := \"1101\";\n\nsignal currState, nextState: targetFsmType;\n\nbegin\n\n nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,\n\t\t\t         LPCI_Devsel_n, LPCI_Stop_n, Term, Ready) begin\n   case currState is\n     when IDLE  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n    when B_BUSY =>\n      if (PCI_Frame_n ='1' and D_Done = '1') or\n\t     (PCI_Frame_n = '1' and D_Done = '0' and LPCI_Devsel_n = '0') then\n        nextState <= IDLE;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '0' or (Term = '1' and Ready = '1') ) then\n        nextState <= S_Data;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '1' and Ready = '0') then\n        nextState <= BACKOFF;\n      else\n        nextState <= B_BUSY;\n      end if;\n\n    when S_DATA =>\n      if PCI_Frame_n = '0' and LPCI_Stop_n = '0' and (LPCI_Trdy_n = '1' or PCI_Irdy_n = '0') then\n        nextState <= BACKOFF;\n      elsif PCI_Frame_n = '1' and (LPCI_Trdy_n = '0' or LPCI_Stop_n = '0') then\n        nextState <= TURN_AR;\n      else\n        nextState <= S_DATA;\n      end if;\n\n\n    when BACKOFF =>\n      if PCI_Frame_n = '1' then\n        nextState <= TURN_AR;\n      else\n        nextState <= BACKOFF;\n      end if;\n\n    when TURN_AR  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n      when others =>\n\t    null;\n    end case;\n  end process nxtStProc;\n\n\n  curStProc: process (PCI_Clk, PCI_Reset_n) begin\n    if (PCI_Reset_n = '0') then\n      currState <= Idle;\n    elsif (PCI_Clk'event and PCI_Clk = '1') then\n      currState <= nextState;\n    end if;\n  end process curStProc;\n\n\n  outConProc: process (currState, Ready, T_Abort, Cmd_Write,\n                       Cmd_Read, T_Abort, Term) begin\n    case currState is\n      when S_Data =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        if (Ready = '1' and T_Abort = '0' and (Cmd_Write = '1' or Cmd_Read = '1')) then\n          LPCI_Trdy_n <= '0';\n        else\n          LPCI_Trdy_n <= '1';\n        end if;\n\n        if (T_Abort = '1' or Term = '1') and (Cmd_Write = '1' or Cmd_Read = '1')  then\n          LPCI_Stop_n <= '0';\n        else\n          LPCI_Stop_n <= '1';\n        end if;\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n      when Backoff =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        LPCI_Stop_n <= '0';\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n      when Turn_Ar =>\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n\t  when others =>\n\n        OE_Trdy_n <= '0';\n        OE_Stop_n <= '0';\n        OE_Devsel_n <= '0';\n\t\tOE_AD <= '0';\n        LPCI_Trdy_n <= '1';\n        LPCI_Stop_n <= '1';\n        LPCI_Devsel_n <= '1';\n\n    end case;\n\n  end process outConProc;\n\n  PCI_Devsel_n <= LPCI_Devsel_n;\n  PCI_Trdy_n <= LPCI_Trdy_n;\n  PCI_Stop_n <= LPCI_Stop_n;\n\nend fsm;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity pci_target is port (\n  PCI_Frame_n: in std_logic;\t-- PCI Frame#\n  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#\n  Hit: in std_logic;\t\t\t-- Hit on address decode\n  D_Done: in std_logic;\t\t\t-- Device decode complete\n  Term: in std_logic;\t\t\t-- Terminate transaction\n  Ready: in std_logic;\t\t\t-- Ready to transfer data\n  Cmd_Write: in std_logic;\t\t-- Command is Write\n  Cmd_Read: in std_logic;\t\t-- Command is Read\n  T_Abort: in std_logic;\t\t-- Target error  - abort transaction\n  PCI_Clk: in std_logic;\t\t-- PCI Clock\n  PCI_Reset_n: in std_logic;\t-- PCI Reset#\n\n  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#\n  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#\n  PCI_Stop_n: out std_logic;\t-- PCI Stop#\n  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable\n  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable\n  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable\n  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable\n\n  );\nend pci_target;\n\narchitecture fsm of pci_target is\n\nsignal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;\n\nsubtype targetFsmType is std_logic_vector(2 downto 0);\n\nconstant Idle: \t\ttargetFsmType := \"000\";\nconstant B_Busy: \t\ttargetFsmType := \"101\";\nconstant Backoff: \ttargetFsmType := \"010\";\nconstant S_Data: \t\ttargetFsmType := \"011\";\nconstant Turn_Ar: \ttargetFsmType := \"110\";\nconstant Dont_Care: targetFsmType := \"XXX\";\n\nsignal currState, nextState: targetFsmType;\n\nbegin\n\n nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,\n\t\t\t         LPCI_Devsel_n, LPCI_Stop_n, Term, Ready) begin\n   case currState is\n     when IDLE  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n    when B_BUSY =>\n      if (PCI_Frame_n ='1' and D_Done = '1') or\n\t     (PCI_Frame_n = '1' and D_Done = '0' and LPCI_Devsel_n = '0') then\n        nextState <= IDLE;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '0' or (Term = '1' and Ready = '1') ) then\n        nextState <= S_Data;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '1' and Ready = '0') then\n        nextState <= BACKOFF;\n      else\n        nextState <= B_BUSY;\n      end if;\n\n    when S_DATA =>\n      if PCI_Frame_n = '0' and LPCI_Stop_n = '0' and (LPCI_Trdy_n = '1' or PCI_Irdy_n = '0') then\n        nextState <= BACKOFF;\n      elsif PCI_Frame_n = '1' and (LPCI_Trdy_n = '0' or LPCI_Stop_n = '0') then\n        nextState <= TURN_AR;\n      else\n        nextState <= S_DATA;\n      end if;\n\n\n    when BACKOFF =>\n      if PCI_Frame_n = '1' then\n        nextState <= TURN_AR;\n      else\n        nextState <= BACKOFF;\n      end if;\n\n    when TURN_AR  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n      when others =>\n\t    nextState <= Dont_Care;\n    end case;\n  end process nxtStProc;\n\n\n  curStProc: process (PCI_Clk, PCI_Reset_n) begin\n    if (PCI_Reset_n = '0') then\n      currState <= Idle;\n    elsif (PCI_Clk'event and PCI_Clk = '1') then\n      currState <= nextState;\n    end if;\n  end process curStProc;\n\n\n  outConProc: process (currState, Ready, T_Abort, Cmd_Write,\n                       Cmd_Read, T_Abort, Term) begin\n\n  -- Set default output assignments\n  OE_Trdy_n <= '0';\n  OE_Stop_n <= '0';\n  OE_Devsel_n <= '0';\n  OE_AD <= '0';\n  LPCI_Trdy_n <= '1';\n  LPCI_Stop_n <= '1';\n  LPCI_Devsel_n <= '1';\n\n    case currState is\n      when S_Data =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        if (Ready = '1' and T_Abort = '0' and (Cmd_Write = '1' or Cmd_Read = '1')) then\n          LPCI_Trdy_n <= '0';\n        else\n          LPCI_Trdy_n <= '1';\n        end if;\n\n        if (T_Abort = '1' or Term = '1') and (Cmd_Write = '1' or Cmd_Read = '1')  then\n          LPCI_Stop_n <= '0';\n        else\n          LPCI_Stop_n <= '1';\n        end if;\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n      when Backoff =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        LPCI_Stop_n <= '0';\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n      when Turn_Ar =>\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n\t  when others =>\n\n        OE_Trdy_n <= '0';\n        OE_Stop_n <= '0';\n        OE_Devsel_n <= '0';\n\t\tOE_AD <= '0';\n        LPCI_Trdy_n <= '1';\n        LPCI_Stop_n <= '1';\n        LPCI_Devsel_n <= '1';\n\n    end case;\n\n  end process outConProc;\n\n  PCI_Devsel_n <= LPCI_Devsel_n;\n  PCI_Trdy_n <= LPCI_Trdy_n;\n  PCI_Stop_n <= LPCI_Stop_n;\n\nend fsm;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity pci_target is port (\n  PCI_Frame_n: in std_logic;    -- PCI Frame#\n  PCI_Irdy_n: in std_logic;     -- PCI Irdy#\n  Hit: in std_logic;            -- Hit on address decode\n  D_Done: in std_logic;         -- Device decode complete\n  Term: in std_logic;           -- Terminate transaction\n  Ready: in std_logic;          -- Ready to transfer data\n  Cmd_Write: in std_logic;      -- Command is Write\n  Cmd_Read: in std_logic;       -- Command is Read\n  T_Abort: in std_logic;        -- Target error  - abort transaction\n  PCI_Clk: in std_logic;        -- PCI Clock\n  PCI_Reset_n: in std_logic;    -- PCI Reset#\n\n  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#\n  PCI_Stop_n: out std_logic;    -- PCI Stop#\n  PCI_Trdy_n: out std_logic;    -- PCI Trdy#\n  OE_AD: out std_logic;         -- PCI AD bus enable\n  OE_Trdy_n: out std_logic;     -- PCI Trdy# enable\n  OE_Stop_n: out std_logic;     -- PCI Stop# enable\n  OE_Devsel_n: out std_logic    -- PCI Devsel# enable\n  );\nend pci_target;\n\narchitecture fsm of pci_target is\n\nsignal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;\n\ntype targetFsmType is (Idle, B_Busy, Backoff, S_Data, Turn_Ar);\n\nsignal currState, nextState: targetFsmType;\n\nbegin\n\n-- Process to generate next state logic\n\n nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,\n\t\t\t         LPCI_Devsel_n, LPCI_Stop_n, Term, Ready) begin\n   case currState is\n     when Idle  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_Busy;\n      else\n        nextState <= Idle;\n      end if;\n\n    when B_Busy =>\n      if (PCI_Frame_n ='1' and D_Done = '1') or\n\t     (PCI_Frame_n = '1' and D_Done = '0' and LPCI_Devsel_n = '0') then\n        nextState <= Idle;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '0' or (Term = '1' and Ready = '1') ) then\n        nextState <= S_Data;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '1' and Ready = '0') then\n        nextState <= Backoff;\n      else\n        nextState <= B_Busy;\n      end if;\n\n    when S_Data =>\n      if PCI_Frame_n = '0' and LPCI_Stop_n = '0' and (LPCI_Trdy_n = '1' or PCI_Irdy_n = '0') then\n        nextState <= Backoff;\n      elsif PCI_Frame_n = '1' and (LPCI_Trdy_n = '0' or LPCI_Stop_n = '0') then\n        nextState <= Turn_Ar;\n      else\n        nextState <= S_Data;\n      end if;\n\n\n    when Backoff =>\n      if PCI_Frame_n = '1' then\n        nextState <= Turn_Ar;\n      else\n        nextState <= Backoff;\n      end if;\n\n    when Turn_Ar  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_Busy;\n      else\n        nextState <= Idle;\n      end if;\n\n    when others =>\n      null;\n\n    end case;\n\n  end process nxtStProc;\n\n\n-- Process to register the current state\n\n  curStProc: process (PCI_Clk, PCI_Reset_n) begin\n    if (PCI_Reset_n = '0') then\n      currState <= Idle;\n    elsif (PCI_Clk'event and PCI_Clk = '1') then\n      currState <= nextState;\n    end if;\n  end process curStProc;\n\n\n-- Process to generate outputs\n\n  outConProc: process (currState, Ready, T_Abort, Cmd_Write,\n                       Cmd_Read, T_Abort, Term) begin\n    case currState is\n      when S_Data =>\n        if (Cmd_Read = '1') then \n          OE_AD <= '1';\n        else\n          OE_AD <= '0';\n        end if;\n\n        if (Ready = '1' and T_Abort = '0' and (Cmd_Write = '1' or Cmd_Read = '1')) then\n          LPCI_Trdy_n <= '0';\n        else\n          LPCI_Trdy_n <= '1';\n        end if;\n\n        if (T_Abort = '1' or Term = '1') and (Cmd_Write = '1' or Cmd_Read = '1')  then\n          LPCI_Stop_n <= '0';\n        else\n          LPCI_Stop_n <= '1';\n        end if;\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n      when Backoff =>\n        if (Cmd_Read = '1') then \n          OE_AD <= '1';\n        else\n          OE_AD <= '0';\n        end if;\n\n        LPCI_Stop_n <= '0';\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n      when Turn_Ar =>\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n      when others =>\n\n        OE_Trdy_n <= '0';\n        OE_Stop_n <= '0';\n        OE_Devsel_n <= '0';\n        OE_AD <= '0';\n        LPCI_Trdy_n <= '1';\n        LPCI_Stop_n <= '1';\n        LPCI_Devsel_n <= '1';\n\n    end case;\n\n  end process outConProc;\n\n-- Assign output ports\n\n  PCI_Devsel_n <= LPCI_Devsel_n;\n  PCI_Trdy_n <= LPCI_Trdy_n;\n  PCI_Stop_n <= LPCI_Stop_n;\n\nend fsm;\n-- Incorporates Errata 10.1 and 10.2\n\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity pci_target is port (\n  PCI_Frame_n: in std_logic;    -- PCI Frame#\n  PCI_Irdy_n: in std_logic;     -- PCI Irdy#\n  Hit: in std_logic;            -- Hit on address decode\n  D_Done: in std_logic;         -- Device decode complete\n  Term: in std_logic;           -- Terminate transaction\n  Ready: in std_logic;          -- Ready to transfer data\n  Cmd_Write: in std_logic;      -- Command is Write\n  Cmd_Read: in std_logic;       -- Command is Read\n  T_Abort: in std_logic;        -- Target error  - abort transaction\n  PCI_Clk: in std_logic;        -- PCI Clock\n  PCI_Reset_n: in std_logic;    -- PCI Reset#\n\n  PCI_Devsel_n: out std_logic;  -- PCI Devsel#\n  PCI_Trdy_n: out std_logic;    -- PCI Trdy#\n  PCI_Stop_n: out std_logic;    -- PCI Stop#\n  OE_AD: out std_logic;         -- PCI AD bus enable\n  OE_Trdy_n: out std_logic;     -- PCI Trdy# enable\n  OE_Stop_n: out std_logic;     -- PCI Stop# enable\n  OE_Devsel_n: out std_logic    -- PCI Devsel# enable\n  );\nend pci_target;\n\narchitecture fsm of pci_target is\n\nsignal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;\n\nsubtype targetFsmType is std_logic_vector(4 downto 0);\n\nconstant Idle:    integer := 0;\nconstant B_Busy:  integer := 1;\nconstant Backoff: integer := 2;\nconstant S_Data:  integer := 3;\nconstant Turn_Ar: integer := 4;\n\nsignal currState, nextState: targetFsmType;\n\nbegin\n\n nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,\n                     LPCI_Devsel_n, LPCI_Stop_n, Term, Ready) begin\n\n   nextState <= (others => '0');\n\n   if currState(Idle) = '1' then\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState(B_Busy) <= '1';\n      else\n        nextState(Idle) <= '1';\n      end if;\n   end if;\n\n   if currState(B_Busy) = '1' then\n      if (PCI_Frame_n ='1' and D_Done = '1') or\n\t     (PCI_Frame_n = '1' and D_Done = '0' and LPCI_Devsel_n = '0') then\n        nextState(Idle) <= '1';\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '0' or (Term = '1' and Ready = '1') ) then\n        nextState(S_Data) <= '1';\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '1' and Ready = '0') then\n        nextState(Backoff) <= '1';\n      else\n        nextState(B_Busy) <= '1';\n      end if;\n   end if;\n\n   if currState(S_Data) = '1' then\n      if PCI_Frame_n = '0' and LPCI_Stop_n = '0' and\n         (LPCI_Trdy_n = '1' or PCI_Irdy_n = '0') then\n        nextState(Backoff) <= '1';\n      elsif PCI_Frame_n = '1' and (LPCI_Trdy_n = '0' or LPCI_Stop_n = '0') then\n        nextState(Turn_Ar) <= '1';\n      else\n        nextState(S_Data) <= '1';\n      end if;\n   end if;\n\n\n   if currState(Backoff) = '1' then\n      if PCI_Frame_n = '1' then\n        nextState(Turn_Ar) <= '1';\n      else\n        nextState(Backoff) <= '1';\n      end if;\n   end if;\n\n   if currState(Turn_Ar) = '1' then\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState(B_Busy) <= '1';\n      else\n        nextState(Idle) <= '1';\n      end if;\n   end if;\n\n  end process nxtStProc;\n\n\n  curStProc: process (PCI_Clk, PCI_Reset_n) begin\n    if (PCI_Reset_n = '0') then\n\tcurrState <= (others => '0'); -- per Errata 10.2\n      currState(Idle) <= '1';\n    elsif (PCI_Clk'event and PCI_Clk = '1') then\n      currState <= nextState;\n    end if;\n  end process curStProc;\n\n\n  outConProc: process (currState, Ready, T_Abort, Cmd_Write,\n                       Cmd_Read, T_Abort, Term) begin\n      OE_Trdy_n <= '0';\tOE_Stop_n <= '0';\tOE_Devsel_n <= '0';\t-- defaults per errata 10.1\n      OE_AD <= '0';\t\tLPCI_Trdy_n <= '1';\tLPCI_Stop_n <= '1';\n\t  LPCI_Devsel_n <= '1';\n\n    if (currState(S_Data) = '1') then\n      if (Cmd_Read = '1') then \n        OE_AD <= '1';\n      else\n        OE_AD <= '0';\n      end if;\n\n      if (Ready = '1' and T_Abort = '0' and (Cmd_Write = '1' or Cmd_Read = '1')) then\n          LPCI_Trdy_n <= '0';\n      else\n        LPCI_Trdy_n <= '1';\n      end if;\n\n      if (T_Abort = '1' or Term = '1') and (Cmd_Write = '1' or Cmd_Read = '1')  then\n        LPCI_Stop_n <= '0';\n      else\n        LPCI_Stop_n <= '1';\n      end if;\n\n      if (T_Abort = '0') then\n        LPCI_Devsel_n <= '0';\n      else\n        LPCI_Devsel_n <= '1';\n      end if;\n\n      OE_Trdy_n <= '1';\n      OE_Stop_n <= '1';\n      OE_Devsel_n <= '1';\n    end if;\n\n\n    if (currState(Backoff) = '1') then\n      if (Cmd_Read = '1') then \n        OE_AD <= '1';\n      else\n        OE_AD <= '0';\n      end if;\n\n      LPCI_Stop_n <= '0';\n\n      OE_Trdy_n <= '1';\n      OE_Stop_n <= '1';\n      OE_Devsel_n <= '1';\n\n      if (T_Abort = '0') then\n        LPCI_Devsel_n <= '0';\n      else\n        LPCI_Devsel_n <= '1';\n      end if;\n    end if;\n\n\n    if (currState(Turn_Ar) = '1') then\n      OE_Trdy_n <= '1';\n      OE_Stop_n <= '1';\n      OE_Devsel_n <= '1';\n    end if;\n\n    if (currState(Idle) = '1' or currState(B_Busy) = '1') then\n      OE_Trdy_n <= '0';\n      OE_Stop_n <= '0';\n      OE_Devsel_n <= '0';\n      OE_AD <= '0';\n      LPCI_Trdy_n <= '1';\n      LPCI_Stop_n <= '1';\n      LPCI_Devsel_n <= '1';\n    end if;\n\n   end process outConProc;\n\n  PCI_Devsel_n <= LPCI_Devsel_n;\n  PCI_Trdy_n <= LPCI_Trdy_n;\n  PCI_Stop_n <= LPCI_Stop_n;\n\nend fsm;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity pci_target is port (\n  PCI_Frame_n: in std_logic;\t-- PCI Frame#\n  PCI_Irdy_n: in std_logic;\t\t-- PCI Irdy#\n  Hit: in std_logic;\t\t\t-- Hit on address decode\n  D_Done: in std_logic;\t\t\t-- Device decode complete\n  Term: in std_logic;\t\t\t-- Terminate transaction\n  Ready: in std_logic;\t\t\t-- Ready to transfer data\n  Cmd_Write: in std_logic;\t\t-- Command is Write\n  Cmd_Read: in std_logic;\t\t-- Command is Read\n  T_Abort: in std_logic;\t\t-- Target error  - abort transaction\n  PCI_Clk: in std_logic;\t\t-- PCI Clock\n  PCI_Reset_n: in std_logic;\t-- PCI Reset#\n\n  PCI_Devsel_n: out std_logic;\t-- PCI Devsel#\n  PCI_Trdy_n: out std_logic;\t-- PCI Trdy#\n  PCI_Stop_n: out std_logic;\t-- PCI Stop#\n  OE_AD: out std_logic;\t\t\t-- PCI AD bus enable\n  OE_Trdy_n: out std_logic;\t\t-- PCI Trdy# enable\n  OE_Stop_n: out std_logic;\t\t-- PCI Stop# enable\n  OE_Devsel_n: out std_logic\t-- PCI Devsel# enable\n\n  );\nend pci_target;\n\narchitecture fsm of pci_target is\n\nsignal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;\n\nsubtype targetFsmType is std_logic_vector(2 downto 0);\n\nconstant Idle: \t\ttargetFsmType := \"000\";\nconstant B_Busy: \ttargetFsmType := \"001\";\nconstant Backoff: \ttargetFsmType := \"011\";\nconstant S_Data: \ttargetFsmType := \"110\";\nconstant Turn_Ar: \ttargetFsmType := \"100\";\n\nsignal currState, nextState: targetFsmType;\n\nbegin\n\n nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,\n\t\t\t         LPCI_Devsel_n, LPCI_Stop_n, Term, Ready) begin\n   case currState is\n     when IDLE  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n    when B_BUSY =>\n      if (PCI_Frame_n ='1' and D_Done = '1') or\n\t     (PCI_Frame_n = '1' and D_Done = '0' and LPCI_Devsel_n = '0') then\n        nextState <= IDLE;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '0' or (Term = '1' and Ready = '1') ) then\n        nextState <= S_Data;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '1' and Ready = '0') then\n        nextState <= BACKOFF;\n      else\n        nextState <= B_BUSY;\n      end if;\n\n    when S_DATA =>\n      if PCI_Frame_n = '0' and LPCI_Stop_n = '0' and (LPCI_Trdy_n = '1' or PCI_Irdy_n = '0') then\n        nextState <= BACKOFF;\n      elsif PCI_Frame_n = '1' and (LPCI_Trdy_n = '0' or LPCI_Stop_n = '0') then\n        nextState <= TURN_AR;\n      else\n        nextState <= S_DATA;\n      end if;\n\n\n    when BACKOFF =>\n      if PCI_Frame_n = '1' then\n        nextState <= TURN_AR;\n      else\n        nextState <= BACKOFF;\n      end if;\n\n    when TURN_AR  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_BUSY;\n      else\n        nextState <= IDLE;\n      end if;\n\n      when others =>\n\t    nextState <= IDLE;\n    end case;\n  end process nxtStProc;\n\n\n  curStProc: process (PCI_Clk, PCI_Reset_n) begin\n    if (PCI_Reset_n = '0') then\n      currState <= Idle;\n    elsif (PCI_Clk'event and PCI_Clk = '1') then\n      currState <= nextState;\n    end if;\n  end process curStProc;\n\n\n  outConProc: process (currState, Ready, T_Abort, Cmd_Write,\n                       Cmd_Read, T_Abort, Term) begin\n\n  -- Set default output assignments\n  OE_Trdy_n <= '0';\n  OE_Stop_n <= '0';\n  OE_Devsel_n <= '0';\n  OE_AD <= '0';\n  LPCI_Trdy_n <= '1';\n  LPCI_Stop_n <= '1';\n  LPCI_Devsel_n <= '1';\n\n    case currState is\n      when S_Data =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        if (Ready = '1' and T_Abort = '0' and (Cmd_Write = '1' or Cmd_Read = '1')) then\n          LPCI_Trdy_n <= '0';\n        else\n          LPCI_Trdy_n <= '1';\n        end if;\n\n        if (T_Abort = '1' or Term = '1') and (Cmd_Write = '1' or Cmd_Read = '1')  then\n          LPCI_Stop_n <= '0';\n        else\n          LPCI_Stop_n <= '1';\n        end if;\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n      when Backoff =>\n        if (Cmd_Read = '1') then \n\t\t  OE_AD <= '1';\n\t    else\n\t\t  OE_AD <= '0';\n\t\tend if;\n\n        LPCI_Stop_n <= '0';\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n      when Turn_Ar =>\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n\t  when others =>\n\n        OE_Trdy_n <= '0';\n        OE_Stop_n <= '0';\n        OE_Devsel_n <= '0';\n\t\tOE_AD <= '0';\n        LPCI_Trdy_n <= '1';\n        LPCI_Stop_n <= '1';\n        LPCI_Devsel_n <= '1';\n\n    end case;\n\n  end process outConProc;\n\n  PCI_Devsel_n <= LPCI_Devsel_n;\n  PCI_Trdy_n <= LPCI_Trdy_n;\n  PCI_Stop_n <= LPCI_Stop_n;\n\nend fsm;\nlibrary IEEE;\nuse IEEE.std_logic_1164.all;\n\nentity pci_target is port (\n  PCI_Frame_n: in std_logic;    -- PCI Frame#\n  PCI_Irdy_n: in std_logic;     -- PCI Irdy#\n  Hit: in std_logic;            -- Hit on address decode\n  D_Done: in std_logic;         -- Device decode complete\n  Term: in std_logic;           -- Terminate transaction\n  Ready: in std_logic;          -- Ready to transfer data\n  Cmd_Write: in std_logic;      -- Command is Write\n  Cmd_Read: in std_logic;       -- Command is Read\n  T_Abort: in std_logic;        -- Target error  - abort transaction\n  PCI_Clk: in std_logic;        -- PCI Clock\n  PCI_Reset_n: in std_logic;    -- PCI Reset#\n\n  PCI_Devsel_n: out std_logic;  -- PCI Devsel#\n  PCI_Trdy_n: out std_logic;    -- PCI Trdy#\n  PCI_Stop_n: out std_logic;    -- PCI Stop#\n  OE_AD: out std_logic;         -- PCI AD bus enable\n  OE_Trdy_n: out std_logic;     -- PCI Trdy# enable\n  OE_Stop_n: out std_logic;     -- PCI Stop# enable\n  OE_Devsel_n: out std_logic    -- PCI Devsel# enable\n  );\nend pci_target;\n\narchitecture fsm of pci_target is\n\n  signal LPCI_Devsel_n, LPCI_Trdy_n, LPCI_Stop_n: std_logic;\n\n  subtype targetFsmType is std_logic_vector(2 downto 0);\n\n  constant Idle:    targetFsmType := \"000\";\n  constant B_Busy:  targetFsmType := \"001\";\n  constant Backoff: targetFsmType := \"011\";\n  constant S_Data:  targetFsmType := \"110\";\n  constant Turn_Ar: targetFsmType := \"100\";\n\n  signal currState, nextState: targetFsmType;\n\nbegin\n\n nxtStProc: process (currState, PCI_Frame_n, Hit, D_Done, PCI_Irdy_n, LPCI_Trdy_n,\n                     LPCI_Devsel_n, LPCI_Stop_n, Term, Ready) begin\n   case currState is\n     when Idle  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_Busy;\n      else\n        nextState <= Idle;\n      end if;\n\n    when B_Busy =>\n      if (PCI_Frame_n ='1' and D_Done = '1') or\n\t     (PCI_Frame_n = '1' and D_Done = '0' and LPCI_Devsel_n = '0') then\n        nextState <= Idle;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '0' or (Term = '1' and Ready = '1') ) then\n        nextState <= S_Data;\n      elsif (PCI_Frame_n = '0' or PCI_Irdy_n = '0') and Hit = '1' and\n\t\t    (Term = '1' and Ready = '0') then\n        nextState <= Backoff;\n      else\n        nextState <= B_Busy;\n      end if;\n\n    when S_Data =>\n      if PCI_Frame_n = '0' and LPCI_Stop_n = '0' and\n         (LPCI_Trdy_n = '1' or PCI_Irdy_n = '0') then\n        nextState <= Backoff;\n      elsif PCI_Frame_n = '1' and (LPCI_Trdy_n = '0' or LPCI_Stop_n = '0') then\n        nextState <= Turn_Ar;\n      else\n        nextState <= S_Data;\n      end if;\n\n\n    when Backoff =>\n      if PCI_Frame_n = '1' then\n        nextState <= Turn_Ar;\n      else\n        nextState <= Backoff;\n      end if;\n\n    when Turn_Ar  =>\n      if (PCI_Frame_n = '0' and Hit = '0') then\n        nextState <= B_Busy;\n      else\n        nextState <= Idle;\n      end if;\n\n      when others =>\n\t    null;\n    end case;\n  end process nxtStProc;\n\n\n  curStProc: process (PCI_Clk, PCI_Reset_n) begin\n    if (PCI_Reset_n = '0') then\n      currState <= Idle;\n    elsif (PCI_Clk'event and PCI_Clk = '1') then\n      currState <= nextState;\n    end if;\n  end process curStProc;\n\n\n  outConProc: process (currState, Ready, T_Abort, Cmd_Write,\n                       Cmd_Read, T_Abort, Term) begin\n    case currState is\n      when S_Data =>\n        if (Cmd_Read = '1') then \n          OE_AD <= '1';\n        else\n          OE_AD <= '0';\n        end if;\n\n        if (Ready = '1' and T_Abort = '0' and (Cmd_Write = '1' or Cmd_Read = '1')) then\n          LPCI_Trdy_n <= '0';\n        else\n          LPCI_Trdy_n <= '1';\n        end if;\n\n        if (T_Abort = '1' or Term = '1') and (Cmd_Write = '1' or Cmd_Read = '1')  then\n          LPCI_Stop_n <= '0';\n        else\n          LPCI_Stop_n <= '1';\n        end if;\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n      when Backoff =>\n        if (Cmd_Read = '1') then \n          OE_AD <= '1';\n        else\n          OE_AD <= '0';\n        end if;\n\n        LPCI_Stop_n <= '0';\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n        if (T_Abort = '0') then\n          LPCI_Devsel_n <= '0';\n        else\n          LPCI_Devsel_n <= '1';\n        end if;\n\n      when Turn_Ar =>\n\n        OE_Trdy_n <= '1';\n        OE_Stop_n <= '1';\n        OE_Devsel_n <= '1';\n\n      when others =>\n\n        OE_Trdy_n <= '0';\n        OE_Stop_n <= '0';\n        OE_Devsel_n <= '0';\n        OE_AD <= '0';\n        LPCI_Trdy_n <= '1';\n        LPCI_Stop_n <= '1';\n        LPCI_Devsel_n <= '1';\n\n    end case;\n\n  end process outConProc;\n\n  PCI_Devsel_n <= LPCI_Devsel_n;\n  PCI_Trdy_n <= LPCI_Trdy_n;\n  PCI_Stop_n <= LPCI_Stop_n;\n\nend fsm;\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n\nentity test is port (\n  a: in std_logic;\n  z: out std_logic;\n  en: in std_logic\n  );\nend test;\n\narchitecture simple of test is\n\nbegin\n\n  z <= a when en = '1' else 'z';\n\nend simple;\n"
  },
  {
    "path": "Units/review-needed.r/too-large-for-reviewing-3526726.tex.t/expected.tags",
    "content": "A Rule with PCRE causes a failure to load snort.conf. Why?\tinput.tex\t/^\\\\subsection{A Rule with PCRE causes a failure to load snort.conf.  Why?}$/;\"\tu\tsection:Problems\nAfter I add new rules or comment out rules how do I make Snort reload?\tinput.tex\t/^\\\\subsection{After I add new rules or comment out rules how do I make Snort reload?}$/;\"\tu\tsection:Rules and Alerts\nAre rule keywords ORed or ANDed together?\tinput.tex\t/^\\\\subsection{Are rule keywords ORed or ANDed together?}$/;\"\tu\tsection:Rules and Alerts\nAre there other output systems for Snort besides ``Barnyard''?\\\\label{spoolers}\tinput.tex\t/^\\\\subsection{Are there other output systems for Snort besides ``Barnyard''?\\\\label{spoolers}}$/;\"\tu\tsection:Getting Fancy\nBASE appears to be broken in Lynx\tinput.tex\t/^\\\\subsection{BASE appears to be broken in Lynx }$/;\"\tu\tsection:Problems\nBackground\tinput.tex\t/^\\\\section{Background}$/;\"\ts\nCan Snort be evaded by the use of polymorphic mutators on shellcode?\tinput.tex\t/^\\\\subsection{Can Snort be evaded by the use of polymorphic mutators on shellcode?}$/;\"\tu\tsection:Background\nCan Snort trigger a rule by MAC addresses?\tinput.tex\t/^\\\\subsection{Can Snort trigger a rule by MAC addresses?}$/;\"\tu\tsection:Rules and Alerts\nCan priorities be assigned to alerts using BASE?\tinput.tex\t/^\\\\subsection{Can priorities be assigned to alerts using BASE?  }$/;\"\tu\tsection:Rules and Alerts\nConfiguring Snort\tinput.tex\t/^\\\\section{Configuring Snort}$/;\"\ts\nDevelopment\tinput.tex\t/^\\\\section{Development}   $/;\"\ts\nDoes Snort handle IP defragmentation?\tinput.tex\t/^\\\\subsection{Does Snort handle IP defragmentation?}$/;\"\tu\tsection:Background\nDoes Snort log the full packets when it generates alerts?\tinput.tex\t/^\\\\subsection{Does Snort log the full packets when it generates alerts? }$/;\"\tu\tsection:Background\nDoes Snort perform TCP stream reassembly?\tinput.tex\t/^\\\\subsection{Does Snort perform TCP stream reassembly?}$/;\"\tu\tsection:Background\nDoes Snort perform stateful protocol analysis?\tinput.tex\t/^\\\\subsection{Does Snort perform stateful protocol analysis?}$/;\"\tu\tsection:Background\nDoes snort see packets filtered by IPTables/IPChains/IPF/PF?\tinput.tex\t/^\\\\subsection{Does snort see packets filtered by IPTables\\/IPChains\\/IPF\\/PF?}$/;\"\tu\tsection:Rules and Alerts\nErrors loading rules files\tinput.tex\t/^\\\\subsection{Errors loading rules files}$/;\"\tu\tsection:Rules and Alerts\nGetting Fancy\tinput.tex\t/^\\\\section{Getting Fancy}$/;\"\ts\nGetting Started\tinput.tex\t/^\\\\section{Getting Started}$/;\"\ts\nHow can I deactivate a rule?\tinput.tex\t/^\\\\subsection{How can I deactivate a rule?}$/;\"\tu\tsection:Rules and Alerts\nHow can I define an address to be anything except some hosts?\tinput.tex\t/^\\\\subsection{How can I define an address to be anything except some hosts?}$/;\"\tu\tsection:Rules and Alerts\nHow can I examine logged packets in more detail?\tinput.tex\t/^\\\\subsection{How can I examine logged packets in more detail?}$/;\"\tu\tsection:Getting Fancy\nHow can I protect web servers running on ports other than 80?\tinput.tex\t/^\\\\subsection{How can I protect web servers running on ports other than 80?}$/;\"\tu\tsection:Rules and Alerts\nHow can I run Snort on multiple interfaces simultaneously?\tinput.tex\t/^\\\\subsection{How can I run Snort on multiple interfaces simultaneously?}$/;\"\tu\tsection:Configuring Snort\nHow can I specify a list of ports in a rule?\tinput.tex\t/^\\\\subsection{How can I specify a list of ports in a rule?}$/;\"\tu\tsection:Rules and Alerts\nHow can I test Snort without having an Ethernet card or a connection to other computers?\tinput.tex\t/^\\\\subsection{How can I test Snort without having an Ethernet card or a connection to other compu/;\"\tu\tsection:Getting Fancy\nHow can I use Snort to log HTTP URLs or SMTP traffic?\tinput.tex\t/^\\\\subsection{How can I use Snort to log HTTP URLs or SMTP traffic?}$/;\"\tu\tsection:Getting Fancy\nHow do I build this BASE thing?\tinput.tex\t/^\\\\subsection{How do I build this BASE thing?}$/;\"\tu\tsection:Configuring Snort\nHow do I configure stream4?\tinput.tex\t/^\\\\subsection{How do I configure stream4?}$/;\"\tu\tsection:Configuring Snort\nHow do I get Snort and ACID working?\tinput.tex\t/^\\\\subsection{How do I get Snort and ACID working?}$/;\"\tu\tsection:Configuring Snort\nHow do I get Snort to e-mail me alerts?\tinput.tex\t/^\\\\subsection{How do I get Snort to e-mail me alerts?}$/;\"\tu\tsection:Getting Fancy\nHow do I get Snort to log the packet payload as well as the header?\tinput.tex\t/^\\\\subsection{How do I get Snort to log the packet payload as well as the header?}$/;\"\tu\tsection:Configuring Snort\nHow do I ignore traffic coming from a particular host or hosts?\tinput.tex\t/^\\\\subsection{How do I ignore traffic coming from a particular host or hosts?}$/;\"\tu\tsection:Configuring Snort\nHow do I log a specific type of traffic and send alerts to syslog?\tinput.tex\t/^\\\\subsection{How do I log a specific type of traffic and send alerts to syslog?}$/;\"\tu\tsection:Getting Fancy\nHow do I log to multiple databases or output plugins?\tinput.tex\t/^\\\\subsection{How do I log to multiple databases or output plugins?}$/;\"\tu\tsection:Getting Fancy\nHow do I process those Snort logs into reports?\tinput.tex\t/^\\\\subsection{How do I process those Snort logs into reports?}$/;\"\tu\tsection:Getting Fancy\nHow do I run Snort?\tinput.tex\t/^\\\\subsection{How do I run Snort?}$/;\"\tu\tsection:Getting Started\nHow do I set EXTERNAL\\\\_NET?\tinput.tex\t/^\\\\subsection{How do I set EXTERNAL\\\\_NET?}$/;\"\tu\tsection:Configuring Snort\nHow do I setup a receive-only ethernet cable?\tinput.tex\t/^\\\\subsection{How do I setup a receive-only ethernet cable?}$/;\"\tu\tsection:Configuring Snort\nHow do I setup snort on a `stealth' interface?\tinput.tex\t/^\\\\subsection{How do I setup snort on a `stealth' interface? }\\\\label{stealth}$/;\"\tu\tsection:Configuring Snort\nHow do I test Snort alerts and logging?\tinput.tex\t/^\\\\subsection{How do I test Snort alerts and logging?}$/;\"\tu\tsection:Rules and Alerts\nHow do I turn off ``spp:possible EVASIVE RST detection'' alerts?\tinput.tex\t/^\\\\subsection{How do I turn off ``spp:possible EVASIVE RST detection'' alerts?}$/;\"\tu\tsection:Rules and Alerts\nHow do I understand this traffic and do IDS alert analysis?\tinput.tex\t/^\\\\subsection{How do I understand this traffic and do IDS alert analysis?}$/;\"\tu\tsection:Getting Fancy\nHow do I use a remote syslog machine?\tinput.tex\t/^\\\\subsection{How do I use a remote syslog machine?}$/;\"\tu\tsection:Configuring Snort\nHow do you get Snort to ignore some traffic?\tinput.tex\t/^\\\\subsection{How do you get Snort to ignore some traffic?}$/;\"\tu\tsection:Configuring Snort\nHow do you pronounce the names of some of these guys who work on Snort?\tinput.tex\t/^\\\\subsection{How do you pronounce the names of some of these guys who work on Snort?}$/;\"\tu\tsection:Background\nHow do you put Snort in debug mode?\tinput.tex\t/^\\\\subsection{How do you put Snort in debug mode? }$/;\"\tu\tsection:Development\nHow does rule ordering work?\tinput.tex\t/^\\\\subsection{How does rule ordering work?}$/;\"\tu\tsection:Configuring Snort\nHow long can address lists, variables, or rules be?\tinput.tex\t/^\\\\subsection{How long can address lists, variables, or rules be?}$/;\"\tu\tsection:Rules and Alerts\nHow to start Snort as a win32 service?\tinput.tex\t/^\\\\subsection{How to start Snort as a win32 service? }$/;\"\tu\tsection:Getting Fancy\nI am getting `snort [pid] uses obsolete (PF\\\\_INET, SOCK\\\\_PACKET)' warnings. What's wrong?\tinput.tex\t/^\\\\subsection{I am getting `snort [pid] uses obsolete (PF\\\\_INET, SOCK\\\\_PACKET)' warnings. What'/;\"\tu\tsection:Problems\nI am getting too many ``IIS Unicode attack detected'' and/or ``CGI Null Byte attack detected'' false positives. How can I turn this detection off?\tinput.tex\t/^\\\\subsection{I am getting too many ``IIS Unicode attack detected'' and\\/or ``CGI Null Byte attac/;\"\tu\tsection:Rules and Alerts\nI am still getting bombarded with spp\\\\_portscan messages even though the IP that I am getting the portscan from is in my \\\\$DNS\\\\_SERVERs var\tinput.tex\t/^\\\\subsection{I am still getting bombarded with spp\\\\_portscan messages even though the IP that I/;\"\tu\tsection:Problems\nI am using Snort on Windows and receive an ``OpenPcap() error upon startup: ERROR: OpenPcap() device open: Error opening adapter'' message. What's wrong?\tinput.tex\t/^\\\\subsection{I am using Snort on Windows and receive an ``OpenPcap() error upon startup: ERROR: /;\"\tu\tsection:Problems\nI have one network card and two aliases, how can I force Snort to ``listen'' on both addresses?\tinput.tex\t/^\\\\subsection{I have one network card and two aliases, how can I force Snort to ``listen'' on bot/;\"\tu\tsection:Configuring Snort\nI hear people talking about ``Barnyard''. What's that?\\\\label{barnyard}\tinput.tex\t/^\\\\subsection{I hear people talking about ``Barnyard''. What's that?\\\\label{barnyard}}$/;\"\tu\tsection:Getting Fancy\nI just downloaded a new ruleset and now Snort fails, complaining about the rules.\tinput.tex\t/^\\\\subsection{I just downloaded a new ruleset and now Snort fails, complaining about the$/;\"\tu\tsection:Problems\nI think I found a bug in Snort. Now what?\tinput.tex\t/^\\\\subsection{ I think I found a bug in Snort. Now what?}$/;\"\tu\tsection:Problems\nI try to start Snort and it gives an error like ``ERROR: Unable to open rules file: /root/.snortrc or /root//root/.snortrc.'' What can I do to fix this?\tinput.tex\t/^\\\\subsection{I try to start Snort and it gives an error like ``ERROR: Unable to open$/;\"\tu\tsection:Problems\nI want to build a Snort box. Will this $<$Insert list of hardware$>$ handle $<$this much$>$ traffic?\tinput.tex\t/^\\\\subsection{I want to build a Snort box.  Will this $<$Insert list of hardware$>$ handle $<$thi/;\"\tu\tsection:Getting Started\nI'm getting large amounts of $<$some alerts type$>$. What should I do? Where can I go to find out more about it?\tinput.tex\t/^\\\\subsection{I'm getting large amounts of $<$some alerts type$>$. What should I do?  Where can I/;\"\tu\tsection:Rules and Alerts\nI'm getting lots of *ICMP Ping Speedera*, is this bad?\tinput.tex\t/^\\\\subsection{I'm getting lots of *ICMP Ping Speedera*, is this bad?}$/;\"\tu\tsection:Problems\nI'm not seeing any interfaces listed under Win32.\tinput.tex\t/^\\\\subsection{I'm not seeing any interfaces listed under Win32.}$/;\"\tu\tsection:Problems\nI'm on a switched network, can I still use Snort?\tinput.tex\t/^\\\\subsection{I'm on a switched network, can I still use Snort?}$/;\"\tu\tsection:Background\nI've got RedHat and ....\tinput.tex\t/^\\\\subsection{ I've got RedHat and ....}$/;\"\tu\tsection:Getting Started\nIDSCenter\tinput.tex\t/^      \\\\item IDS Center (Win32) \\\\label{IDSCenter}$/;\"\tl\nIs Fyodor Yarochkin the same Fyodor who wrote nmap?\tinput.tex\t/^\\\\subsection{Is Fyodor Yarochkin the same Fyodor who wrote nmap?}$/;\"\tu\tsection:Background\nIs Snort vulnerable to IDS noise generators like ``Stick'' and ``Snot''?\tinput.tex\t/^\\\\subsection{Is Snort vulnerable to IDS noise generators like ``Stick'' and ``Snot''?}$/;\"\tu\tsection:Background\nIs it possible to have Snort call an external program when an alert is raised?\tinput.tex\t/^\\\\subsection{Is it possible to have Snort call an external program when an alert is raised?}$/;\"\tu\tsection:Getting Fancy\nIs it possible with snort to add a ipfilter/ipfw rule to a firewall?\tinput.tex\t/^\\\\subsection{Is it possible with snort to add a ipfilter\\/ipfw rule to a firewall? }$/;\"\tu\tsection:Getting Fancy\nIs there a private SID number range so my rules don't conflict?\tinput.tex\t/^\\\\subsection{Is there a private SID number range so my rules don't conflict?}$/;\"\tu\tsection:Rules and Alerts\nIt's not working on Win32, how can I tell if my problem is Snort or WinPcap?\tinput.tex\t/^\\\\subsection{It's not working on Win32, how can I tell if my problem is Snort or$/;\"\tu\tsection:Problems\nLibpcap complains about permissions problems, what's going on?\tinput.tex\t/^\\\\subsection{Libpcap complains about permissions problems, what's going on?}$/;\"\tu\tsection:Getting Started\nMiscellaneous\tinput.tex\t/^\\\\section{Miscellaneous}$/;\"\ts\nMy /var/log/snort directory gets very large...\tinput.tex\t/^\\\\subsection{My \\/var\\/log\\/snort directory gets very large...}$/;\"\tu\tsection:Problems\nMy BASE db connection times-out when performing long operations (e.g. deleting a large number of alerts).\tinput.tex\t/^\\\\subsection{My BASE db connection times-out when performing long operations (e.g.$/;\"\tu\tsection:Problems\nMy IP address is assigned dynamically to my interface, can I use Snort with it?\tinput.tex\t/^\\\\subsection{My IP address is assigned dynamically to my interface, can I use Snort with it?}$/;\"\tu\tsection:Configuring Snort\nMy network spans multiple subnets. How do I define HOME\\\\_NET?\tinput.tex\t/^\\\\subsection{My network spans multiple subnets.  How do I define HOME\\\\_NET?}$/;\"\tu\tsection:Configuring Snort\nMy snort crashes, how do I restart it?\tinput.tex\t/^\\\\subsection{My snort crashes, how do I restart it?}$/;\"\tu\tsection:Problems\nOn HPUX I get device lan0 open: recv\\\\_ack: promisc\\\\_phys: Invalid argument\tinput.tex\t/^\\\\subsection{On HPUX I get device lan0 open: recv\\\\_ack: promisc\\\\_phys: Invalid argument}$/;\"\tu\tsection:Problems\nPortscans are not being logged to my database\tinput.tex\t/^\\\\subsection{Portscans are not being logged to my database }$/;\"\tu\tsection:Problems\nProblems\tinput.tex\t/^\\\\section{Problems}$/;\"\ts\nRules and Alerts\tinput.tex\t/^\\\\section{Rules and Alerts}$/;\"\ts\nSMB alerts aren't working, what's wrong?\tinput.tex\t/^\\\\subsection{SMB alerts aren't working, what's wrong? }$/;\"\tu\tsection:Problems\nSnort complains about the ``react'' keyword...\tinput.tex\t/^\\\\subsection{Snort complains about the ``react'' keyword...}$/;\"\tu\tsection:Getting Fancy\nSnort fails to respond to a kill signal on Linux. Why?\tinput.tex\t/^\\\\subsection{Snort fails to respond to a kill signal on Linux.  Why?}$/;\"\tu\tsection:Problems\nSnort is behind a firewall (ipf/pf/ipchains/ipfilter) and awfully quiet...\tinput.tex\t/^\\\\subsection{Snort is behind a firewall (ipf\\/pf\\/ipchains\\/ipfilter) and awfully quiet...}$/;\"\tu\tsection:Rules and Alerts\nSnort is dying with a `can not create file' error and I have plenty of diskspace. What's wrong?\tinput.tex\t/^\\\\subsection{Snort is dying with a `can not create file' error and I have plenty of diskspace. W/;\"\tu\tsection:Problems\nSnort is not logging to my database\tinput.tex\t/^\\\\subsection{Snort is not logging to my database}$/;\"\tu\tsection:Problems\nSnort is not logging to syslog\tinput.tex\t/^\\\\subsection{Snort is not logging to syslog}$/;\"\tu\tsection:Problems\nSnort says BACKDOOR SIGNATURE... does my machine have a Trojan?\tinput.tex\t/^\\\\subsection{Snort says BACKDOOR SIGNATURE... does my machine have a Trojan? }$/;\"\tu\tsection:Rules and Alerts\nSnort says ``Garbage Packet with Null Pointer discarded!'' Huh?\tinput.tex\t/^\\\\subsection{Snort says ``Garbage Packet with Null Pointer discarded!'' Huh?}$/;\"\tu\tsection:Problems\nSnort says ``Ran Out Of Space.'' Huh?\tinput.tex\t/^\\\\subsection{Snort says ``Ran Out Of Space.'' Huh?}$/;\"\tu\tsection:Problems\nSnort says ``Rule IP addr (``1.1.1.1'') didn't x-late, WTF?''\tinput.tex\t/^\\\\subsection{Snort says ``Rule IP addr (``1.1.1.1'') didn't x-late, WTF?''}$/;\"\tu\tsection:Rules and Alerts\nTrying to install snort it says: ``bad interpreter: No such file or directory''\tinput.tex\t/^\\\\subsection{Trying to install snort it says: ``bad interpreter: No such file or$/;\"\tu\tsection:Problems\nWhat about `SMB Name Wildcard' alerts?\tinput.tex\t/^\\\\subsection{What about `SMB Name Wildcard' alerts? }$/;\"\tu\tsection:Rules and Alerts\nWhat about ``CGI Null Byte attacks?''\tinput.tex\t/^\\\\subsection{What about ``CGI Null Byte attacks?'' }$/;\"\tu\tsection:Rules and Alerts\nWhat about all these false alarms?\tinput.tex\t/^\\\\subsection{What about all these false alarms? }$/;\"\tu\tsection:Rules and Alerts\nWhat are CIDR netmasks?\tinput.tex\t/^\\\\subsection{What are CIDR netmasks? }$/;\"\tu\tsection:Getting Started\nWhat are HOME\\\\_NET and EXTERNAL\\\\_NET?\tinput.tex\t/^\\\\subsection{What are HOME\\\\_NET and EXTERNAL\\\\_NET?}$/;\"\tu\tsection:Configuring Snort\nWhat are all these ICMP files in subdirectories under /var/log/snort?\tinput.tex\t/^\\\\subsection{What are all these ICMP files in subdirectories under \\/var\\/log\\/snort? }$/;\"\tu\tsection:Rules and Alerts\nWhat are all these ``ICMP destination unreachable'' alerts?\tinput.tex\t/^\\\\subsection{What are all these ``ICMP destination unreachable'' alerts? }$/;\"\tu\tsection:Rules and Alerts\nWhat are some resources that I can use to understand more about source addresses logged and where they are coming from?\tinput.tex\t/^\\\\subsection{What are some resources that I can use to understand more about source$/;\"\tu\tsection:Getting Fancy\nWhat are these IDS codes in the alert names?\tinput.tex\t/^\\\\subsection{What are these IDS codes in the alert names? }$/;\"\tu\tsection:Rules and Alerts\nWhat do the numbers (ie: [116:56:1]) in front of a Snort alert mean?\tinput.tex\t/^\\\\subsection{What do the numbers (ie: [116:56:1]) in front of a Snort alert mean?}$/;\"\tu\tsection:Rules and Alerts\nWhat is the best way to use Snort to block attack traffic?\tinput.tex\t/^\\\\subsection{What is the best way to use Snort to block attack traffic?}$/;\"\tu\tsection:Getting Fancy\nWhat is the difference between ``Alerting'' and ``Logging''?\tinput.tex\t/^\\\\subsection{What is the difference between ``Alerting'' and ``Logging''?}$/;\"\tu\tsection:Rules and Alerts\nWhat is the use of the ``-r'' switch to read tcpdump files?\tinput.tex\t/^\\\\subsection{What is the use of the ``-r'' switch to read tcpdump files?  }$/;\"\tu\tsection:Getting Started\nWhat the heck is a SYNFIN scan?\tinput.tex\t/^\\\\subsection{What the heck is a SYNFIN scan? }$/;\"\tu\tsection:Rules and Alerts\nWhat the heck is a SYNFIN scan?\tinput.tex\t/^\\\\subsection{What the heck is a SYNFIN scan?}$/;\"\tu\tsection:Configuring Snort\nWhat the heck is a ``Stealth scan''?\tinput.tex\t/^\\\\subsection{What the heck is a ``Stealth scan''?}$/;\"\tu\tsection:Configuring Snort\nWhat version of Winpcap do I need?\\\\label{winpcap}\tinput.tex\t/^\\\\subsection{What version of Winpcap do I need?\\\\label{winpcap}}$/;\"\tu\tsection:Getting Started\nWhat's this about a Snort drinking game?\tinput.tex\t/^\\\\subsection{What's this about a Snort drinking game?}$/;\"\tu\tsection:Miscellaneous\nWhere are my log files located? What are they named?\tinput.tex\t/^\\\\subsection{Where are my log files located?  What are they named?}$/;\"\tu\tsection:Getting Started\nWhere can I get more reading and courses about IDS?\\\\label{courses}\tinput.tex\t/^\\\\subsection{Where can I get more reading and courses about IDS?\\\\label{courses}}$/;\"\tu\tsection:Background\nWhere do I find binary packages for BlueHat BSD-Linux-RT?\tinput.tex\t/^\\\\subsection{Where do I find binary packages for BlueHat BSD-Linux-RT?}$/;\"\tu\tsection:Getting Started\nWhere do I get more help on Snort?\tinput.tex\t/^\\\\subsection{Where do I get more help on Snort?}$/;\"\tu\tsection:Background\nWhere do I get the latest version of Winpcap?\tinput.tex\t/^\\\\subsection{Where do I get the latest version of Winpcap?}$/;\"\tu\tsection:Getting Started\nWhere do I get the latest version of libpcap?\tinput.tex\t/^\\\\subsection{Where do I get the latest version of libpcap? }$/;\"\tu\tsection:Getting Started\nWhere do the distance and within keywords work from to modify content searches in rules?\tinput.tex\t/^\\\\subsection{Where do the distance and within keywords work from to modify content$/;\"\tu\tsection:Rules and Alerts\nWhere does one obtain new/modifed rules? How do you merge them in?\tinput.tex\t/^\\\\subsection{Where does one obtain new\\/modifed rules? How do you merge them in?}$/;\"\tu\tsection:Configuring Snort\nWhere's a good place to physically put a Snort sensor?\tinput.tex\t/^\\\\subsection{Where's a good place to physically put a Snort sensor?}$/;\"\tu\tsection:Getting Started\nWhich takes precedence, commandline or rule file ?\tinput.tex\t/^\\\\subsection{Which takes precedence, commandline or rule file ?}$/;\"\tu\tsection:Configuring Snort\nWhy am I seeing so many ``SMTP RCPT TO overflow'' alerts ?\tinput.tex\t/^\\\\subsection{Why am I seeing so many ``SMTP RCPT TO overflow'' alerts ?}$/;\"\tu\tsection:Problems\nWhy are my unified alert times off by +/- N hours?\tinput.tex\t/^\\\\subsection{Why are my unified alert times off by +\\/- N hours?}$/;\"\tu\tsection:Problems\nWhy are there no subdirectories under /var/log/snort for IP addresses?\tinput.tex\t/^\\\\subsection{Why are there no subdirectories under \\/var\\/log\\/snort for IP addresses?}$/;\"\tu\tsection:Configuring Snort\nWhy can't snort see one of the 10Mbps or 100Mbps traffic on my autoswitch hub?\tinput.tex\t/^\\\\subsection{Why can't snort see one of the 10Mbps or 100Mbps traffic on my autoswitch hub?}$/;\"\tu\tsection:Problems\nWhy do certain alerts seem to have `unknown' IPs in BASE?\tinput.tex\t/^\\\\subsection{Why do certain alerts seem to have `unknown' IPs in BASE?  }$/;\"\tu\tsection:Rules and Alerts\nWhy do many Snort rules have the flags P (TCP PuSH) and A (TCP ACK) set?\tinput.tex\t/^\\\\subsection{Why do many Snort rules have the flags P (TCP PuSH) and A (TCP ACK) set? }$/;\"\tu\tsection:Rules and Alerts\nWhy does Snort complain about /var/log/snort?\tinput.tex\t/^\\\\subsection{Why does Snort complain about \\/var\\/log\\/snort?}$/;\"\tu\tsection:Getting Started\nWhy does building Snort complain about missing references?\tinput.tex\t/^\\\\subsection{Why does building Snort complain about missing references? }$/;\"\tu\tsection:Getting Started\nWhy does building snort fail with errors about yylex and lex\\\\_init?\tinput.tex\t/^\\\\subsection{Why does building snort fail with errors about yylex and lex\\\\_init? }$/;\"\tu\tsection:Getting Started\nWhy does chrooted Snort die when I send it a SIGHUP? \\\\label{chroot}\tinput.tex\t/^\\\\subsection{Why does chrooted Snort die when I send it a SIGHUP? \\\\label{chroot}}$/;\"\tu\tsection:Problems\nWhy does snort report ``Packet loss statistics are unavailable under Linux?''\tinput.tex\t/^\\\\subsection{Why does snort report ``Packet loss statistics are unavailable under Linux?''}$/;\"\tu\tsection:Problems\nWhy does the `error deleting alert' message occur when attempting to delete an alert with BASE?\tinput.tex\t/^\\\\subsection{Why does the `error deleting alert' message occur when attempting to delete an aler/;\"\tu\tsection:Problems\nWhy does the portscan plugin log ``stealth'' packets even though the host is in the portscan-ignorehosts list?\tinput.tex\t/^\\\\subsection{Why does the portscan plugin log ``stealth'' packets even though the host is in the/;\"\tu\tsection:Configuring Snort\nWhy does the program generate alerts on packets that have pass rules?\tinput.tex\t/^\\\\subsection{Why does the program generate alerts on packets that have pass rules?  }$/;\"\tu\tsection:Rules and Alerts\n\\\\myquote\tinput.tex\t/^\\\\newcommand{\\\\myquote}[1]{\\\\begin{quote}#1\\\\end{quote}}$/;\"\tC\n\\\\myref\tinput.tex\t/^\\\\newcommand{\\\\myref}[1]{(see FAQ \\\\ref{#1})}$/;\"\tC\nstealth\tinput.tex\t/^\\\\subsection{How do I setup snort on a `stealth' interface? }\\\\label{stealth}$/;\"\tl\nstream4\tinput.tex\t/^\\\\label{stream4}$/;\"\tl\n"
  },
  {
    "path": "Units/review-needed.r/too-large-for-reviewing-3526726.tex.t/input.tex",
    "content": "%latex2html -info 0 -local_icons -show_section_numbers -link 2 -split +1 faq.tex\r\n\\documentclass{article}\r\n\\usepackage{html}\r\n\\usepackage{graphicx}\r\n\\usepackage{fancyhdr}\r\n\\usepackage{makeidx}\r\n\r\n%% Margins\r\n\\oddsidemargin 0in\r\n\\evensidemargin 0in\r\n\\textwidth 6.5in\r\n\\topmargin 0in\r\n\\textheight 8in\r\n\\setlength{\\parindent}{0in}\r\n\\setlength{\\parskip}{.5\\baselineskip}\r\n\r\n\\pagestyle{fancy}\r\n\r\n\\lhead{ {\\sc Snort FAQ} }\r\n\\cfoot{ {\\sc feed the pig}}\r\n\\rhead{Page \\thepage}\r\n\r\n\\newcommand{\\myref}[1]{(see FAQ \\ref{#1})}\r\n\\newcommand{\\myquote}[1]{\\begin{quote}#1\\end{quote}}\r\n\r\n%\\label{key} assign current counter value to key\r\n%\\myref{key}{print value assigned to key}\r\n\r\n% To emphasise\r\n% {\\em blah}\r\n\r\n% To bold\r\n% {\\bf bold face }\r\n\r\n% The following characters are special characters and need to be backslashed\r\n% before use:\r\n%    $ & % # _ { }\r\n%\r\n% To get a backslash, try $\\backslash$\r\n\r\n\\makeindex\r\n\r\n\\begin{document}\r\n\r\n\\title{ The Snort FAQ }\r\n\\author{ The Snort Core Team }\r\n\\date{ }\r\n\r\n% Title Page\r\n\r\n\\maketitle\r\n\r\n\\newpage\r\n\r\nSuggestions for enhancements of this document are always welcome.  Please email them to the \\htmladdnormallink{Snort-Users}{mailto:snort-users@lists.sourceforge.net} mailing list. \r\n\r\nMany people have contributed to this FAQ:\r\n\\begin{center}\r\n\\begin{tabular}{llll}\r\n Marty Roesch   &  Fyodor Yarochkin    &   Dragos Ruiu      &     Jed Pickel\\\\\r\n\r\n    Max Vision   &    Michael Davis     &   Joe McAlerney    &      Joe Stewart\\\\\r\n\r\n    Erek Adams    &   Roman Danyliw   &   Christopher Cramer  &    Frank Knobbe\\\\\r\n\r\n     Phil Wood     & Toby Kohlenberg   &   Ramin Alidousti     &    Jim Hankins\\\\\r\n\r\nDennis Hollingworth &  Paul Howell      &      Stef Mit         &   Ofir Arkin\\\\\r\n\r\n    Jason Haar       & Blake Frantz &  Lars Norman S?ndergaard  & Brent Erickson\\\\\r\n\r\n   Brian Caswell  &  Scot Wiedenfeld &       Chris Green        &   Jeff Wirth\\\\\r\n\r\n  Edin Dizdarevic  &  Detmar Liesen   &         Don Ng       &     Matt Kettler\\\\\r\n\r\n     Joe Lyman      &  Jim Burwell     &      Jed Haile      &   Andrew Hutchinson\\\\\r\n\r\n    Jeff Nathan   &  Alberto Gonzalez   &     Jason Haar    &    Jeremy Hewlett\r\n\\end{tabular}\r\n\\end{center}\r\n\r\n\r\n\r\n\r\n\r\nIf you do not see your name on this list and you have contributed to the faq,\r\nplease email \\htmladdnormallink{bugs@snort.org}{mailto:bugs@snort.org}.\r\n\r\n\r\nDragos Ruiu: This version of this guide has been brought to you by the kind\r\ngenerosity and sponsorship of Wiley and Sons publishers whose support let\r\nmyself, and other snort developers Jeff Nathan and Jed Haile take the time to\r\nwork on this document and other tutorials for Snort due out in our upcoming\r\nbook. (route++)\r\n\r\n\r\n\\newpage\r\n\r\n\\begin{latexonly}\r\n\\tableofcontents\r\n\r\n\\newpage\r\n\\end{latexonly}\r\n\r\n\\section{Background}\r\n\r\n\\subsection{How do you pronounce the names of some of these guys who work on Snort?}\r\n\r\nFor the record, `Roesch' is pronounced like `fresh' without the `f.'  \r\nAdditionally, `Ruiu' is pronounced like `screw you' without the `sc.'  \r\nJed's last name is like `pick-el,' not `pickle.' \r\n\r\n\\subsection{Is Fyodor Yarochkin the same Fyodor who wrote nmap?}\r\n\r\nNope. fyodor@insecure.org is the author of nmap, and he uses the same pseudonym as the other Snort Fyodor's real surname. Yeah, it messes up my mailbox too, but I think it's too late to change either of them.\r\n\r\n\\subsection{Where do I get more help on Snort?}\r\n\r\nCheck the website, \\htmladdnormallink{http://www.snort.org/}{http://www.snort.org/}.  Other good resources are available in the source distribution, including the \\htmladdnormallink{Snort Users Manual}{http://www.snort.org/docs} and the USAGE file. There is also a excellent mailing list, snort-users. You can find\r\ninfo on how to signup at \\htmladdnormallink{http://www.snort.org/community/mailing-lists/}{http://www.snort.org/community/mailing-lists}. You can also join \r\n\\#snort on irc.freenode.net.\r\n\r\n\\subsection{Where can I get more reading and courses about IDS?\\label{courses}}\r\n\r\nAll of the following offer courses on Intrusion Detection:\r\n\\begin{itemize}\r\n\\item \\htmladdnormallink{SANS (http://www.sans.org)}{http://www.sans.org} \r\n\\item \\htmladdnormallink{Usenix (http://www.usenix.org/event/)}{http://www.usenix.org/event/} \r\n\\item \\htmladdnormallink{Networld/Interop (http://www.key3media.com/interop/)}{http://www.key3media.com/interop/}\r\n\\item \\htmladdnormallink{CanSecWest (http://www.cansecwest.com)}{http://www.cansecwest.com} \r\n\\end{itemize}\r\n\r\nThere are many good books on Intrusion Detection. Here are just a few:\r\n\r\n\\begin{tabular}{|p{2in}|p{1.5in}|l|l|}\r\n\\hline\r\n{\\bf Title} & {\\bf Author(s)} & {\\bf Publisher} & {\\bf ISBN}\\\\\r\n\\hline\\hline\r\nSnort 2.1 Intrusion Detection, Second Edition & Brian Caswell, Jay Beale & 1931836043 \\\\\r\n\\hline\r\nTao of Network Security Monitoring, The: Beyond Intrusion Detection & Richard Bejtlich & 0321246772 \\\\\r\n\\hline\r\nIntrusion Detection with Snort: Advanced IDS Techniques & Rafeeq Rehman & Prentice Hall & I0131407333\\\\\r\n\\hline\r\nSnort Intrusion Detection        &       Ryan Russell        & Syngress Media &  1931836744 \\\\\r\n\\hline\r\nSnort Intrusion Detection        &        Jack Koziol        &   New Riders   &  157870281X\\\\\r\n\\hline\r\nNetwork Intrusion Detection: An Analyst's Handbook & Stephen Northcutt & New Riders & 0735708681 \\\\\r\n\\hline\r\nIntrusion Signatures and Analysis                 & Stephen Northcutt & New Riders & 0735710635 \\\\\r\n\\hline\r\nTCP/IP Illustrated, Volume 1 The Protocols        & W. Richard Stevens & Addison-Wesley & 0201633469 \\\\\r\n\\hline\r\nIntrusion Detection                               & Rebecca G. Bace    & MacMillan Technical Publishing & 1578701856 \\\\\r\n\\hline\r\nThe Tao of Network Security Monitoring: Beyond Intrusion Detection & Richard Bejtlich & Addison-Wesley & 0321246772 \\\\\r\n\\hline\r\nSnort 2.1 Intrusion Detection, Second Edition & Brian Caswell \\& Jay Beale & Syngress Publishing & 1931836043 \\\\\r\n\\hline\r\n\\end{tabular}\r\n\r\n\t\r\n\\subsection{Does Snort handle IP defragmentation?}\r\n\r\nYes, use {\\tt preprocessor frag3}.\r\n\r\n\\subsection{Does Snort perform TCP stream reassembly?}\r\n\r\nYes, check out the stream4 preprocessor \\myref{stream4} that does stateful \r\nanalysis session login, TCP reassembly and much, much more.\r\n\r\n\\subsection{Does Snort perform stateful protocol analysis?}\r\n\r\nYes. Stream4 does this as well. See \\myref{stream4}.\r\n\r\n\\subsection{I'm on a switched network, can I still use Snort?}\r\n\r\n{\\bf Short version:}\r\n\r\nBeing able to sniff on a switched network depends on what type of switch is\r\nbeing used. If the switch can mirror traffic, then set the switch to mirror all\r\ntraffic to the Snort machine's port.\r\n\r\n{\\bf Extended version:}\r\n\r\nThere are several ways of deploying NIDS in switched environments which all\r\nhave their pros and cons. Which method applies to your needs depends on what\r\nkind of segments you want to monitor and on your budget. Here are the most\r\ncommon methods:\r\n\r\n\\begin{enumerate}\r\n\\item  {\\bf Switch mirror:} If the switch can mirror traffic, then set the switch to\r\n    mirror all traffic to the Snort machine's port.\r\n   \\begin{itemize}\r\n   \t\\item Advantages:\r\n\t      \\begin{itemize}\r\n              \\item Simple method, works with most decent switches.\r\n\t      \\end{itemize}\r\n\t \\item Drawbacks:\r\n\t      \\begin{itemize}\r\n              \\item If the switch is a fast Ethernet switch, you can mirror 100Mbit/s\r\n\t      max. Since each switch port is capable of handling 100Mbit/s for each\r\n\t      direction, the bandwidth per port sums up to 200Mbit/s, so the switch\r\n\t      will not be able to mirror all packets at high network utilization.\r\n\r\n\t      \\item Some switches suffer from performance degradation through port\r\n\t      mirroring.\r\n\t      \\end{itemize}\r\n    \\end{itemize}\r\n\\item  {\\bf Hub:} Insert a hub in line, so you can simply tap all traffic. Works\r\n    fine for home networks, will lose data due to collisions at loads greater\r\n    than 50\\%---so a 10Mbps hub should be fine for T1/E1, DSL or cablemodem. If\r\n    you have a DS3 or greater, you should investigate taps.\r\n    \\begin{itemize}\r\n      \\item Advantages:\r\n      \t\t\\begin{itemize}\r\n\t\t\\item Simple method\r\n\t\t\\item No impact on switch performance and no config changes\r\n\t\t\\item Low cost\r\n\t\t\\end{itemize}\r\n      \\item Drawbacks:\r\n      \t\t\\begin{itemize}\r\n\t\t\\item Loss of full-duplex capabilities\r\n\t\t\\item Additional single point of failure\r\n\t\t\\item Collision loss at above 50\\% load levels\r\n\t\t\\end{itemize}\r\n    \\end{itemize}\r\n\\item  {\\bf Network taps:} Use network taps (e.g. Shomiti/Finisar [\\htmladdnormallink{http://www.shomiti.com}{http://www.shomiti.com}] and Netoptics [\\htmladdnormallink{http://www.netoptics.com}{http://www.netoptics.com}). You can find some rather good information in the papers by Jeff  Nathan. You can find the papers at \r\n    \\htmladdnormallink{http://www.snort.org/docs/\\#deploy}{http://www.snort.org/docs/\\#deploy}.\r\n      \\begin{itemize}\r\n      \\item Advantages:\r\n      \t\t\\begin{itemize}\r\n\t\t\\item No impact on switch performance and no special configuration\r\n\t\t\\item Stealth---i.e., sending data back to the switch is disabled\r\n\t\t\\item No single point of failure, ``fail-open'' if the tap power fails\r\n\t\t\\end{itemize}\r\n      \\item Drawbacks:\r\n\t\t\\begin{itemize}\r\n\t\t\\item The datastream is split into TX and RX, so you need two NICs\r\n\t\t\\item The two datastreams have to be recombined, i.e. merged, if you don't\r\n\t\twant to lose the capability of doing stateful analysis. This can be\r\n\t\tdone by using channel bonding. Information can be found at \r\n\t\t\\htmladdnormallink{http://sourceforge.net/projects/bonding}{http://sourceforge.net/projects/bonding}.\r\n\t\t\\item Cost\r\n\t\t\\end{itemize}\r\n      \\end{itemize}\r\n\t\r\n\\item  {\\bf Throw money at it:} Tap switch ports (using the forementioned\r\n    network taps) but only tap all incoming packets (RX lines of the switch\r\n    ports), connecting those tap ports to a dedicated gigabit switch, which is\r\n    capable of mirroring up to ten RX taplines to one single dedicated gigabit\r\n    port, which is connected to a gigabit IDS machine.\r\n    \\begin{itemize}\r\n      \\item Advantages:\r\n      \t\t\\begin{itemize}\r\n        \t\\item Maximum coverage (i.e. monitor all switchports)\r\n\t\t\\item No performance degradation or re-configuration of the switch\r\n\t\t\\end{itemize}\r\n      \\item Drawbacks:\r\n      \t\t\\begin{itemize}\r\n\t\t\\item Mucho \\$\\$\\$\r\n\t\t\\end{itemize}\r\n    \\end{itemize}\r\n\\end{enumerate}\r\n\r\n\\subsection{Is Snort vulnerable to IDS noise generators like ``Stick'' and ``Snot''?}\r\n\r\nIt is now possible to defeat these kinds of noise generators with\r\nthe stream4 preprocessor (see \\myref{stream4}).  Even without the stream4 preprocessor \r\nenabled, Snort will weather the alert storm without falling over \r\nor losing a lot of alerts due to its highly optimized nature.  \r\nUsing tools that generate huge amounts of alerts will warn a good \r\nanalyst that someone is trying to sneak by their defenses.  \r\n\r\n\\subsection{Can Snort be evaded by the use of polymorphic mutators on shellcode?}\r\n\r\nYes, and this could defeat some of the NOP sled detection signatures,\r\nbut the ordinary exploit rules should not be affected by this kind\r\nof obfuscation.  The fnord preprocessor attempts to detect polymorphic\r\nshellcode attempts.\r\n\r\n\\subsection{Does Snort log the full packets when it generates alerts? }\r\n\r\nYes, the packets should be in the directory that has the same IP address as the\r\nsource host of the packet which generated the alert. If you are using binary\r\nlogging, there will be a packet capture file (.pcap) in the logging directory\r\ninstead.\r\n  \r\n\\section{Getting Started}\r\n\r\n\\subsection{Where do I find binary packages for BlueHat BSD-Linux-RT?}\r\n\r\nRepeat after me:\r\n\r\n\\begin{verbatim}\r\n    Go to http://www.snort.org/snort-downloads\r\n    Click the link for the <release> tar.gz\r\n    tar zxvf snort-<release>.tar.gz\r\n    cd <release>\r\n    ./configure\r\n    make\r\n    su\r\n    make install\r\n    mkdir /var/log/snort\r\n    cd etc\r\n    vi snort.conf\r\n    snort -D -c snort.conf\r\n    exit\r\n\\end{verbatim}\r\n\r\n...and if you want to use our binary package uninstaller :-):\r\n\\begin{verbatim}\r\n    cd <release>; make uninstall\r\n\\end{verbatim}\r\n\r\nAnd if you must, you can find some binaries at \\htmladdnormallink{http://www.snort.org/snort-downloads}{http://www.snort.org/snort-downloads}. \r\nYou can also find Snort in most BSD ports' trees.\r\n\r\n\\subsection{How do I run Snort?}\r\n\r\nRun Snort in sniffer mode and make sure it can see the packets.  \r\n\r\n\\begin{verbatim}snort -dv\\end{verbatim}\r\n\r\nThen run it with the HOME\\_NET set appropriately for the network\r\nyou're defending in your rules file.  A default rules file comes with the\r\nsnort distribution and is called ``snort.conf'' You can run this basic ruleset\r\nwith the following command line:\r\n\r\n\\begin{verbatim}snort -A full -c snort.conf\\end{verbatim}\r\n\r\nIf it's all set right, make sure the interface is in promiscuous mode by running the \r\ncommand from another window:\r\n\r\n\\begin{verbatim}ifconfig -a\\end{verbatim}\r\n\r\nThe output from ifconfig should show if the interface is in promiscuous mode.  \r\nIf it's not, there should be a way to set it manually.\r\n\r\nNote that the default output mode (-A full) of Snort should not be\r\nused except in very controlled environments.  It is the slowest way\r\nto run Snort and presents several hard to recover from problems\r\nwith inode creation on filesystems.\r\n\r\nFor people doing real IDS work, use something like (-A fast -b) to\r\ncombine fast alert mode with tcpdump binary log files or use the\r\nunified format coupled with Barnyard.\r\n\r\n\\subsection{Where are my log files located?  What are they named?}\r\n\r\nThe default location for logs is /var/log/snort. If snort is started with ``-l\r\n$<$directory$>$'', then the logs will be located in the directory specified.\r\n\r\nIn the past, running Snort in daemon mode (-D) produced a file named\r\n``snort.alert.'' For consistency's sake, this has been changed. Running Snort in\r\nboth standard or daemon modes (-D) will produce a file named ``alert.''\r\n\r\nNote the log file naming convention changed between 1.8 and 1.9. That funny\r\nalphanumeric soup at the end of the new names is a UNIX timestamp. This helps\r\navoid file conflicts.\r\n\r\n\\subsection{Why does Snort complain about /var/log/snort?}\r\n\r\nIt requires this directory to log alerts to it. Try running the command:\r\n\\begin{verbatim}\r\n    mkdir -p /var/log/snort\r\n\\end{verbatim}\r\nMake sure the logging directory is owned by the user Snort is running as.\r\n\r\n\\subsection{Where's a good place to physically put a Snort sensor?}\r\n\r\nThis is going to be heavily influenced by your organizations policy, and\r\nwhat you want to detect.  One way of looking at it is determining if you\r\nwant to place it inside or outside your firewall.  Placing an IDS outside\r\nof your firewall will allow you monitor all attacks directed at your\r\nnetwork, regardless of whether or not they are stopped at the firewall.\r\nThis almost certainly means that the IDS will pick up on more events\r\nthan an IDS inside the firewall, and hence more logs will be generated.\r\nPlace an IDS inside your firewall if you are only interested in monitoring\r\ntraffic that your firewall let pass.  If resources permit, it may be best\r\nto place one IDS outside and one IDS inside of your firewall.  This way\r\nyou can watch for everything directed at your network, and anything that\r\nmade it's way in.\r\n\r\nADDENDA AD NAUSEUM\r\n\r\nNote: So this one still gets a lot of traffic even though it's in the FAQ. Erek\r\nAdams has noted this comprehensive and authoritative discussion of this\r\nperpetual discussion item---mildly edited, also see faq question about switches\r\nhubs and taps -dr\r\n\r\nIf your router/switch can do port mirroring, then just connecting a network IDS\r\nto it would be fine. Or else a hub could be another option. Most network IDSes\r\ncan have a NIC that acts as a passive sniffer anyway.\r\n\r\nAs to where to place the sensor. I would go for both, one to monitor the\r\nexternal, one for the internal. I work in a distributor for security products,\r\nso over instrumentation is fun :) And in any case, if the traffic does not pass\r\nby the Sensor it will not get monitored. So some people deploy IDS on their\r\ninternal segments too, I believe.\r\n\r\n{\\bf In ``front'' of the firewall(s):}\r\n\r\nPro: Higher state of alert you know what attacks you are facing.\r\n\r\nCon: Wall to Wall of data, boring? If your firewall has NAT turned on, tracking\r\nthe sources originating from your internal network is difficult.\r\n\r\n{\\bf ``Behind'' the firewall(s):}\r\n\r\nPro: Only what gets through the firewall gets monitored? Less load on the IDS\r\nanalyst. You get to see what hosts are sending traffic to the internet.\r\n\r\nCon: Less idea of the state of the environment, false sense of safety.\r\n\r\n{\\bf Where should IDS be placed relative to firewalls? Explore the pros and cons of\r\nplacing IDS inside or outside firewall. What are the drawbacks of each?}\r\n\r\n\\begin{itemize}\r\n  \\item {\\bf MARCUS RANUM from NFR Security:} \"I'd put mine inside. Why should I care if\r\n    someone is attacking the outside of my firewall? I care only if they\r\n    succeed, which my IDS on the inside would ideally detect. Placing the IDS\r\n    on the outside is going to quickly lull the administrator into complacency.\r\n    I used to have a highly instrumented firewall that alerted me whenever\r\n    someone attacked it. Two weeks later I was deleting its alert messages\r\n    without reading them. Another important factor arguing for putting it\r\n    inside is that not all intrusions come from the outside or the firewall. An\r\n    IDS on the inside might detect new network links appearing, or attackers\r\n    that got in via another avenue such as a dial-in bank.''\r\n    \r\n  \\item {\\bf CURRY from IBM:} ``The IDS should be placed where it will be able to see as\r\n    much of the network traffic you're concerned about as possible. For\r\n    example, if you're concerned about attacks from the Internet, it makes the\r\n    most sense to put the IDS outside the firewall. the most sense to put the\r\n    IDS outside the firewall. This gives it an ``unobstructed'' view of\r\n    everything that's coming in. If you put the IDS inside the firewall, then\r\n    you're not seeing all the traffic the bad guys are sending at you, and this\r\n    may impact your ability to detect intrusions.''\r\n    \r\n\\item {\\bf SUTTERFIELD from Wheel Group:} ``IDS ideally plays an important role both\r\n    inside and outside a firewall. Outside a firewall, IDS watches legitimate\r\n    traffic going to public machines such as e-mail and Web servers. More\r\n    importantly IDS outside a firewall will see traffic that would typically be\r\n    blocked by a firewall and would remain undetected by an internal system.\r\n    This is especially important in detecting network sweeping which can be a\r\n    first indication of attack. External systems will also give you the benefit\r\n    of monitoring those services that firewalls determine are legitimate.\r\n    Putting an IDS inside the firewall offers the added benefit of being able\r\n    to watch traffic internal to the protected network. This adds an important\r\n    element of protection against insider threats. The major drawback of IDS\r\n    inside a firewall is that it cannot see a good deal of important traffic\r\n    coming from untrusted networks and may fail to alert on obvious signals of\r\n    an impending attack.''\r\n    \r\n\\item {\\bf CHRIS KLAUS from ISS:} ``Outside the firewall is almost always a good\r\n    idea---it protects the DMZ devices from attack and dedicates an additional\r\n    processor to protecting the internal network. Just inside the firewall is\r\n    also useful-it detects attempts to exploit the tunnels that exist through\r\n    the firewall and provides an excellent source of data for how well your\r\n    firewall is working. Throughout your intranet may be the best place for IDS\r\n    deployment, however. Everyone agrees that attacks aren't the only things\r\n    we're worried about-there's internal mischief, fraud, espionage, theft, and\r\n    general network misuse. Intrusion detection systems are just as effective\r\n    inside the network as outside, especially if they're unobtrusive and easy\r\n    to deploy.''\r\n    \r\n\\item {\\bf GENE SPAFFORD:} ``The IDS must be inside any firewalls to be able to detect\r\n    insider abuse and certain kinds of attacks through the firewall. IDS\r\n    outside the firewall may be useful if you want to monitor attacks on the\r\n    firewall, and to sample traffic that the firewall doesn't let through.\r\n    However, a true IDS system is likely to be wasted there unless you have\r\n    some follow-through on what you see.''\r\n    \r\n    \\vspace{10pt}\r\n   Bottom Line:\r\n\r\n{\\bf DRAGOS RUIU:} ``Just pick a spot you're likely to look at the logs for. :-)''\r\n\r\n\\end{itemize}\r\n\\subsection{Libpcap complains about permissions problems, what's going on?}\r\n\r\nYou are not running Snort as root or your kernel is not configured \r\ncorrectly.\r\n\r\n\\subsection{ I've got RedHat and ....}\r\n\r\nCheck your version of libpcap.  If it's not $>=$ 0.5, you should update.\r\n\r\n\\subsection{Where do I get the latest version of libpcap? }\r\n\r\nYou can find the most current version at:\r\n\r\n\\htmladdnormallink{http://www.tcpdump.org}{http://www.tcpdump.org/}\r\n\r\nYou might also want to have a look at Phil Wood's patches to libpcap for Linux:\r\n\r\n    \\htmladdnormallink{http://public.lanl.gov/cpw/}{http://public.lanl.gov/cpw/}\r\n    \r\n\\subsection{Where do I get the latest version of Winpcap?}\r\n\r\n\t\\htmladdnormallink{http://winpcap.polito.it/}{http://winpcap.polito.it/}\r\n\r\n\\subsection{What version of Winpcap do I need?\\label{winpcap}}\r\n\r\nIt depends. If you only have one processor, you can use the most current\r\nversion (3.x). If you have a SMP box, you'll have to use either an older\r\nversion ($<$ 2.3) or the 3.x version plus a patch from \\htmladdnormallink{http://www.ntop.org/winpcap.html}{http://www.ntop.org/winpcap.html}.\r\n\r\n\\subsection{Why does building Snort complain about missing references? }\r\n\r\nYou must configure libpcap with the --install-incl option.  (On Red Hat, \r\ninstall the libpcap-devel rpm.)\r\n\r\n\\subsection{Why does building snort fail with errors about yylex and lex\\_init? }\r\n\r\nYou need the lex and yacc tools or their gnu equivalents flex and bison \r\ninstalled.\r\n\r\n\\subsection{I want to build a Snort box.  Will this $<$Insert list of hardware$>$ handle $<$this much$>$ traffic? }\r\n\r\nThat depends. Lower the number of rules is a standard performance increase.\r\nDisable rules that you don't need or care about. There have been many\r\ndiscussions on 'tweaking performance' with lots of 'I handle XX mb with a \\_\\_\\_\r\nmachine setup.' being said. Look at some of the discussions on the snort-users\r\nmailing lists.\r\n\r\nHere is an oft quoted bit on the subject from Marty:\r\n\r\n``Hardware/OS recommendations''\r\n\r\nOk, here are the guidelines and some parameters. Intrusion detection is turning\r\ninto one of the most high performance production computing fields that is in\r\nwide deployment today. If you think about the requirements of a NIDS sensor and\r\nthe constraints that they are required to operate within, you'll probably start\r\nto realize that it's not too hard to find the performance wall with a NIDS\r\nthese days.\r\n\r\nThe things a NIDS needs are:\r\n\\begin{enumerate}\r\n\\item  MIPS (Fast CPU)\r\n\\item  RAM (More is *always* better)\r\n\\item  I/O (Wide, fast busses and high performance NIC)\r\n\\item  AODS (Acres Of Disk Space)\r\n\\end{enumerate}\r\n\r\nA NIDS also needs to be pretty quick internally at doing its job. Snort's seen\r\nbetter days in that regard (when 1.5 came out the architecture was a lot\r\ncleaner) but it's still considered to be one of the performance leaders\r\navailable.\r\n\r\nAs for OS selection, use what you like. When we implement Data Acquisition\r\nPlugin's in Snort 2.0 this may become more of a factor, but for now I'm hearing\r\nabout a lot of people seeing a lot of success using Snort on Solaris, Linux,\r\n*BSD and Windows 2000. Personally, I develop Snort on FreeBSD and Sourcefire\r\nuses OpenBSD for our sensor appliance OS, but I've been hearing some good\r\nthings about the RedHat Turbo Packet interface (which would require mods for\r\nSnort to use, not to mention my general objection to RedHat's breaking stuff\r\nall the time). (ed note: take a drink, see FAQ 7.2 -dr)\r\n\r\n\\subsection{What are CIDR netmasks? }\r\n\r\n(Excerpt from url: \\htmladdnormallink{http://public.pacbell.net/dedicated/cidr.html}{http://public.pacbell.net/dedicated/cidr.html})\r\n\r\nCIDR is a new addressing scheme for the Internet which allows for more i\r\nefficient allocation of IP addresses than the old Class A, B, and C address \r\nscheme.\r\n\r\n\\begin{center}\r\n\\begin{tabular}{llr}\r\n{\\bf CIDR Block} & {\\bf Equivalent Class C} & {\\bf Addresses}\\\\\r\n/27 & 1/8th of a Class C & 32 hosts \\\\\r\n/26 & 1/4th of a Class C & 64 hosts\\\\\r\n/25 & 1/2 of a Class C & 128 hosts\\\\\r\n/24 & 1 Class C & 256 hosts\\\\\r\n/23 & 2 Class C & 512 hosts\\\\\r\n/22 & 4 Class C & 1,024 hosts\\\\\r\n/21 & 8 Class C & 2,048 hosts\\\\\r\n/20 & 16 Class C & 4,096 hosts\\\\\r\n/19 & 32 Class C & 8,192 hosts\\\\\r\n/18 & 64 Class C & 16,384 hosts\\\\\r\n/17 & 128 Class C & 32,768 hosts\\\\\r\n/16 & 256 Class C & 65,536 hosts \\\\ \r\n/15 & 512 Class C & 131,072 hosts\\\\\r\n/14 & 1,024 Class C & 262,144 hosts\\\\\r\n/13 & 2,048 Class C & 524,288 hosts\\\\\r\n\\end{tabular}\r\n\\end{center}\r\n\r\nFor more detailed technical information on CIDR, check out the following RFCs:\r\n\r\n\r\n\\begin{itemize}\r\n\\item RFC 1517: Applicability Statement for the Implementation of CIDR\r\n\\item RFC 1518: An Architecture for IP Address Allocation with CIDR\r\n\\item RFC 1519: CIDR: An Address Assignment and Aggregation Strategy\r\n\\item RFC 1520: Exchanging Routing Information Across Provider Boundaries in the CIDR Environment\r\n\\end{itemize}\r\n\r\nRFCs are available at \r\n\\htmladdnormallink{http://www.rfc-editor.org/rfcsearch.html}{http://www.rfc-editor.org/rfcsearch.html}\r\n\r\n\\subsection{What is the use of the ``-r'' switch to read tcpdump files?  }\r\n\r\nUsed in conjunction with a Snort rules file, the tcpdump data can be\r\nanalyzed for hostile content, port scans, or anything else Snort can be \r\nused to detect.  Snort can also display the packets in a decoded format, \r\nwhich many people find is easier to read than native tcpdump output. \r\n\r\n\r\n\\section{Configuring Snort}\r\n\r\n\\subsection{How do I setup snort on a `stealth' interface? }\\label{stealth}\r\n\r\nIn *BSD and Linux:\r\n\\begin{verbatim}ifconfig eth1 up\\end{verbatim}\r\n\r\nSolaris:\r\n\r\n\\begin{verbatim}ifconfig eth1 plumb\r\nifconfig eth1 up\\end{verbatim}\r\n\r\nFor NT/W2K/XP users, try the following:\r\n\r\nNOTE: You are at your own risk if you follow these instructions.  Editing\r\nyour registry is DANGEROUS and should be done with extreme caution.  Follow\r\nthese steps at your OWN risk.\r\n\r\n\\begin{enumerate}\r\n\\item Get your device's hex value.  ('snort -W' works for this)\r\n\\item open Regedt32\r\n\\item Navigate to: HKEY\\_LOCAL\\_MACHINE$\\backslash$SYSTEM$\\backslash$CurrentControlSet$\\backslash$Services$\\backslash$Tcpip$\\backslash$Parameters$\\backslash$\\linebreak Interfaces$\\backslash$\\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\\}\r\n\\item Select the network card you wish to setup as the monitoring interface (this will be the \\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\\} value).\r\n\\item Set IPAddress:REG\\_MULTI\\_SZ: to null (Double click on the string, delete data in the Multi-String Editor, then click OK)\r\n\\item Set SubnetMask:REG\\_MULTI\\_SZ: to null (Double click on the string, delete data in the Multi-String Editor, then click OK)\r\n\\item Set DefaultGateway:REG\\_MULTI\\_SZ: to null (Double click on the string, delete data in the Multi-String Editor, then click OK)\r\n\\item Close the Registry Editor, your changes will be saved automatically.\r\n\\item In a command prompt, run 'ipconfig' to verify the interface does not have an IP bound to it.\r\n\\end{enumerate}\r\n\r\nIf you do not receive an IP address listing from the interface you\r\nmodified, you are good to go.  To run snort with the specified interface,\r\nuse the -i flag such as 'snort -v -d -p -i1'\r\n \r\n\\subsection{How do I setup a receive-only ethernet cable?}\r\n\r\nUse an ethernet tap, or build your own 'receive-only' ethernet cable.\r\nAnyway, here is the cable I use: \r\n\r\n\\begin{verbatim}\r\n LAN         Sniffer \r\n 1 -----\\   /-- 1\r\n 2 ---\\ |   \\-- 2\r\n 3 ---+-*------ 3\r\n 4 -  |       - 4\r\n 5 -  |       - 5\r\n 6 ---*-------- 6\r\n 7 -          - 7\r\n 8 -          - 8\r\n\\end{verbatim}\r\n\r\nBasically, 1 and 2 on the sniffer side are connected, 3 and 6 \r\nstraight through to the LAN. 1 and 2 on the LAN side connect to 3 and \r\n6 respectively. This fakes a link on both ends but only allows \r\ntraffic from the LAN to the sniffer. It also causes the 'incoming' \r\ntraffic to be sent back to the LAN, so this cable only works well on \r\na hub. You can use it on a switch but you will get ...err... \r\ninteresting results. Since the switch receives the packets back in on \r\nthe port it sent them out, the MAC table gets confused and after a \r\nshort while devices start to drop off the switch. Works like a charm \r\non a hub though. \r\n\r\nAnother method which uses a capacitor and should work on 100mbs links:\r\n\r\n    \\htmladdnormallink{http://www.geocities.com/samngms/sniffing\\_cable}{http://www.geocities.com/samngms/sniffing_cable}\r\n\r\nAnd another:\r\n\r\n    The UTP Y-Cable specified by Joe Lyman:\r\n\r\nA less noisy option: it involves a couple of cat 5 cables and a single speed\r\nhub. The idea is to use the rcv cables for the wire going to the sniffer box\r\nand use the xmit cables from another hub port. This will give you a link light\r\nand allow your sniffer to rcv only. Cannot xmit because the xmit cables are not\r\nconnected. This has been successfully used on netgear single speed hubs. It\r\nwon't work on dual speed hubs due to the negotiation of speed.\r\n\r\nPin outs. They are reversed in the picture in order to prevent lines from\r\ncrossing, and I only included the pins used.\r\n\r\n\\begin{verbatim}\r\n  * []HUB PORT 1             HUB PORT 2\r\n\r\n       -----             -----\r\n\r\n       x x r r                r r x x\r\n\r\n       6 3 2 1                1 2 3 6\r\n\r\n       | | | |                    | |\r\n\r\n       | | | ----------- |\r\n\r\n       | | -------------\r\n\r\n       | |\r\n\r\n       | |\r\n\r\n       | |\r\n\r\n       | |\r\n\r\n       6 3 2 1\r\n\r\n       r r x x\r\n\r\n       ----\r\n\r\n       SNIFFER\r\n\r\n        x = xmit\r\n\r\n        r = rcv\r\n\\end{verbatim}\r\nYou could make it a single cable by adding a battery to simulate the voltage\r\nfrom the xmit cables on the nic, but batteries die.\r\n\r\nIt's not recommended to cut the transmit side, shunt it to ground (pin 2). Some\r\nOS's will disable the interface if PIN 1 does not indicate a completed circuit.\r\n\r\n\\subsection{What are HOME\\_NET and EXTERNAL\\_NET?}\r\n\r\nHOME\\_NET and EXTERNAL\\_NET are standard variable names that all of the Snort.org\r\nrules use. HOME\\_NET refers to the network(s) that you want to protect, where\r\nEXTERNAL\\_NET is the network(s) that you think attacks would come from.\r\n\r\n\\subsection{My network spans multiple subnets.  How do I define HOME\\_NET?}\r\n\r\nSnort 1.7 supports IP lists.  You can assign a number of addresses to\r\na single variable.  For example:\r\n\r\n\\begin{verbatim}var HOME_NET [10.1.1.0/24,192.168.1.0/24]\\end{verbatim}\r\n\r\nNOTE: Not all preprocessors support IP lists at this time.  Unless\r\notherwise stated, assume that any preprocessor using an IP list variable\r\nwill use the first value as the HOME\\_NET.  The portscan preprocessor\r\nis an example.  To catch all detectable portscans, pass 0.0.0.0/0 in\r\nas the first parameter.\r\n\r\n\\begin{verbatim}preprocessor portscan: 0.0.0.0/0 5 3 portscan.log\\end{verbatim}\r\n\r\nUse the portscan-ignorehosts preprocessor to fine tune and ignore\r\ntraffic from noisy, trusted machines.\r\n\r\n\\subsection{How do I set EXTERNAL\\_NET?}\r\n\r\nMany people set EXTERNAL\\_NET to ``any''.\r\n\\begin{verbatim}\r\n    var EXTERNAL_NET any\r\n\\end{verbatim}\r\nBy setting it to ``any'' Snort will alert you on any traffic matching a rule\r\ncoming into or leaving your network.\r\n\r\nTo cut down on the work that Snort has to do, many people set it to ``not\r\nHOME\\_NET.''\r\n\\begin{verbatim}\r\n    var EXTERNAL_NET !$HOME_NET\r\n\\end{verbatim}\r\nThis tells Snort to define EXTERNAL\\_NET as everything except HOME\\_NET. For most\r\npeople this is the best thing to set it to.\r\n\r\n\\subsection{How can I run Snort on multiple interfaces simultaneously?}\r\n\r\nLINUX: If you aren't running snort on linux 2.1.x/2.2.x kernel (with LPF\r\navailable) the only way is to run multiple instances of snort, one instance per\r\ninterface (with the -i option specifying the interface). However for linux\r\n2.1.x/2.2.x and higher you can use libpcap library with S. Krahmer's patch\r\nwhich allows you to specify 'any' as interface name. In this case snort will be\r\nable to process traffic coming to all interfaces.\r\n\r\n*BSD: Use the ``bridge'' interface to combine your nics into a logical\r\ninterface (bridge0).\r\n\r\n\\subsection{My IP address is assigned dynamically to my interface, can I use Snort with it?}\r\n\r\nYes.  With Snort 1.7 and later, $<$interface$>$\\_ADDRESS variable is available.\r\nThe value of this variable will be always set to IP address/Netmask of the\r\ninterface which you run snort at. if interface goes down and up again (and\r\nan IP address is reassigned) you will have to restart snort. For earlier\r\nversions of snort numerous scripts to achieve the same result are\r\navailable.\r\n\r\n\r\n\\subsection{I have one network card and two aliases, how can I force Snort to ``listen'' on both addresses?}\r\n\r\nIf you're using at least version 1.7, you can specify an IP list like\r\nthis:\r\n\r\n\\begin{verbatim}var HOME_NET [ 192.168.10.0/24, 10.1.1.1/16 ]\\end{verbatim}\r\n\r\nIf you're using something older (version 1.6.3-patch2 or whatever) you can\r\nre-specify the HOME\\_NET variable multiple times like this (for example):\r\n\r\n\\begin{verbatim}\r\nvar HOME_NET 10.1.1.0/24\r\ninclude misc.rules\r\nvar HOME_NET 192.168.1.0/24\r\ninclude misc.rules\r\n\\end{verbatim}\r\n\r\n\\subsection{How do I ignore traffic coming from a particular host or hosts?}\r\n\r\nThere are two basic ways to ignore traffic from a host:\r\n\\begin{itemize}\r\n  \\item Pass Rules\r\n  \\item BPF Filters\r\n\\end{itemize}\r\nDetails:\r\n\\begin{enumerate}\r\n\\item  Pass Rules:\r\n      \\begin{itemize}\r\n      \\item Advantages:\r\n      \t\\begin{itemize}\r\n         \\item Gives you rule based control over the packets.\r\n         \\item Puts all your changes into 'one place'-snort.conf.\r\n\t\\end{itemize}\r\n      \\item Disadvantages:\r\n      \t\\begin{itemize}\r\n        \\item Reverses the Rule order, can cause some headaches in tracking down\r\n        problems.\r\n        \\item One poorly written pass rule can 'blind' your whole network.\r\n        \\item The more specific the pass rule is, the more CPU snort needs to process\r\n        it which may be important on loaded nets.\r\n      \\end{itemize}\r\n      \\item Example:\r\n\r\n        For example to ignore ALL ICMP traffic from host <foo> using a pass\r\n        rule:\r\n\t\t\\begin{verbatim}\r\n            pass icmp <foo> any -> $HOME_NET any\r\n\t    \t\\end{verbatim}\r\n    \\end{itemize}\r\n\\item  BPF Filters:\r\n      \\begin{itemize}\r\n      \\item Advantages:\r\n      \t\\begin{itemize}\r\n        \\item Drops the packet at the BPF interface, which saves on processing.\r\n        \\item Speeds up Snort since it 'never sees' those packets.\r\n\t\\end{itemize}\r\n      \\item Disadvantages:\r\n      \t\\begin{itemize}\r\n        \\item Poorly constructed filters can 'blind-side' you.\r\n\t\\end{itemize}\r\n      \\item Example:\r\n      \\begin{itemize}\r\n       \\item To ignore all traffic from 192.168.0.1:\r\n\t\\begin{verbatim}\r\n   snort <commandline options> not host 192.168.0.1\r\n    \t\\end{verbatim}\r\n       \\item To ignore all ICMP ECHO-REQUESTS (pings) and ICMP-ECHO REPLY's (ping\r\n        reply) from host $<$foo$>$:\r\n\t\\begin{verbatim}\r\n   snort <options> ``not ( (icmp[0] = 8 or icmp[0] = 0) and host <foo> )''\r\n        \\end{verbatim}\r\n\t\\end{itemize}\r\n    \\end{itemize}\r\n\\end{enumerate}\r\n\r\n\\subsection{How do I get Snort to log the packet payload as well as the header?}\r\n\r\nIt depends on how your Snort configuration logs. If it logs in binary format,\r\nyou'll have to process the binary log in order to get cleartext. You also might\r\nhave ``-A $<$foo$>$'' on the command line. Command line options always take\r\noverride the .conf file.  \r\n\r\n\\subsection{Why are there no subdirectories under /var/log/snort for IP addresses?}\r\n\r\nIt depends on how your snort configuration logs. If it logs in binary\r\nformat, you'll have to process the binary log in order to get cleartext.\r\n\r\n\\subsection{How do you get Snort to ignore some traffic?}\r\n\r\nSnort can be made to ignore traffic in a number of different ways:\r\n\\begin{enumerate}\r\n\\item Specify bpf filters on the command line the tcpdump man page\r\n has a description of bpf filters.\r\n\\item Use a pass rule\r\n\\item The portscan preprocessor has it's own special exclusion list\r\n with the portscan-ignorehosts.rules file directive\r\n\\end{enumerate}\r\n\r\n\\subsection{Why does the portscan plugin log ``stealth'' packets even though the host is in the portscan-ignorehosts list? }\r\n\r\nThese types of tcp packets are inherently suspicious, no matter where\r\nthey are coming from.  The portscan detector was built with the assumption\r\nthat {\\em stealth} packets should be reported, even from hosts which are not\r\nmonitored for portscanning.  An option to ignore ``stealth'' packets may be\r\nadded in the future.\r\n\r\n\\subsection{What the heck is a ``Stealth scan''?}\r\n\r\nA Stealth scan can refer to more than one type of scan.\r\n\\begin{itemize}\r\n  \\item {\\bf Half-Open or SYN scan:} Instead of completing the full TCP\r\n    three-way-handshake a full connection is not made. A SYN packet is sent to\r\n    the system and if a SYN/ACK packet is received it is assumed that the port\r\n    on the system is active. In that case a RST/ACK will be sent which will\r\n    determined the listening state the system is in. If a RST/ACK packet is\r\n    received, it is assumed that the port on the system is not active.\r\n  \\item {\\bf FIN scan:} According to RFC 793 a system should send back an RST for all TCP\r\n    ports closed when they receive a FIN packet for a specific port.\r\n  \\item {\\bf XMAS tree scan:} According to RFC 793 a system should send back an RST for\r\n    all TCP ports closed when they receive a FIN/URG/PUSH packet for a specific\r\n    port.\r\n  \\item {\\bf NULL scan:} According to RFC 793 a system should send back an RST for all TCP\r\n    ports closed when they receive a packet without any specified IP flags for\r\n    a specific port.\r\n  \\item {\\bf Slow scan:} Any of the above scans could be used as a slow scan. A slow scan\r\n    is when the attacker sends packets at a {\\bf very} slow rate. Sometimes these\r\n    scans can be conducted over hours, days, or weeks. The idea is since they\r\n    are so slow, the victim's security measures won't ``notice'' the scan.\r\n\\end{itemize}\r\n\r\n\\subsection{What the heck is a SYNFIN scan?}\r\n\r\nSYNFIN scans got their name because there are both the SYN and FIN flags set.\r\n\r\n\\subsection{Which takes precedence, commandline or rule file ?}\r\n\r\nThe command line always gets precedence over the rules file.  If people\r\nwant to try stuff out quickly without having to manually edit the rules\r\nfile, they should be able to override many things from the command\r\nline.  \r\n\r\n\\subsection{How does rule ordering work?}\r\n\r\n{\\bf For $=>$ 2.0:}\r\n\r\nPlease see the documents on v2.0 at:\r\n\\htmladdnormallink{http://www.snort.org/docs/development-papers/}{http://www.snort.org/docs/development-papers/}.\r\n\r\n{\\bf For $<=$ 1.9.X:}\r\n\r\nMarty has answered this many times on the snort-users mailing list.  Here is\r\nan excerpt from a post on Thu, 22 Feb 2001 00:31:53 -0500, titled {\\em ``Re: \r\n[Snort-users] order of evaluation of rules.''}\r\n\r\nCurrently, the data structures that store Snort rule data are the\r\nRuleTreeNodes (RTN) and the OptTreeNodes (OTN).  These data structs are\r\nstored in a two dimensinal linked list structure with the RTNs forming\r\nthe top row of the ``Array'' and the OTNs forming the columns under the\r\nRTNs.  Here's an ASCII illustration from the infamous ``lisapaper'':\r\n\r\n\\begin{verbatim}\r\n  RTN                   RTN                    RTN           \r\n  --------------        --------------         -----\r\n | Chain Header |      | Chain Header |      | Chai\r\n |              |      |              |      |\r\n | Src IP       |      | Src IP       |      | Src\r\n | Dst IP       |----->| Dst IP       |----->| Dst   .....\r\n | Src Port     |      | Src Port     |      | Src\r\n | Dst Port     |      | Dst Port     |      | Dst\r\n |              |      |              |      |\r\n  --------------        --------------         -----\r\n         |                     |\r\n         |                     |\r\n         |                     |\r\n  OTN   \\|/            OTN    \\|/\r\n  -------V------       --------V-------\r\n | Chain Option  |    | Chain Option   |\r\n |               |    |        :       |\r\n | Content       |             :\r\n | TCP Flags     |             :\r\n | ICMP Data     |\r\n | Payload Size  |\r\n | etc.          |\r\n |               |\r\n  --------------- \r\n         |\r\n         |\r\n         |\r\n   OTN  \\|/\r\n  -------V------\r\n | Chain Option |\r\n |              |\r\n | Content      |\r\n | TCP Flags    |\r\n | ICMP data    |\r\n | Payload Size |\r\n | etc.         |\r\n |              |\r\n  -------------- \r\n         |\r\n         |\r\n \r\n\\end{verbatim}\r\n\r\nRules with similar rule headers (i.e. all the CGI rules, the old stealth\r\nport scan detection rules, most of the rules that focus on any single\r\nservice, etc) are grouped under a single RTN for the sake of efficiency\r\nand the applicable OTNs are hung below them.  For instance, if you have\r\nthree rules like this:\r\n\r\n\\begin{verbatim}\r\nalert tcp any any -> $HOME 80 (content: \"foo\"; msg: \"foo\";)\r\nalert tcp any any -> $HOME 80 (content: \"bar\"; msg: \"bar\";)\r\nalert tcp any any -> $HOME 80 (content: \"baz\"; msg: \"baz\";)\r\n\\end{verbatim}\r\n\r\nThey all get grouped under the same RTN and the OTNs are ``hung'' beneath\r\nthem like this:\r\n\r\n\\begin{verbatim}\r\n\r\n  RTN\r\n --------------------\r\n|  SIP: any          |\r\n|  SP: any           |\r\n|  DIP: $HOME        |\r\n|  DP: 80            |\r\n -------------------- \r\n          |\r\n          |\r\n  OTN    \\|/  \r\n ---------v----------\r\n| content: foo       |\r\n| msg: foo           |\r\n ---------------------\r\n          |\r\n          |\r\n  OTN    \\|/  \r\n ---------v----------\r\n| content: bar       |\r\n| msg: bar           |\r\n ---------------------\r\n          |\r\n          |\r\n  OTN    \\|/  \r\n ---------v----------\r\n| content: baz       |\r\n| msg: baz           |\r\n ---------------------\r\n\\end{verbatim}\r\n\r\nThis is an efficient way to do things because we only need to check the\r\ndata in the RTN once with this method.  There is actually another\r\ndimension to this array: the function pointer list.  Each node in the\r\n``array'' has a linked list of function pointers attached to it.  The\r\nfunctions in this list are the tests that need to be done to determine\r\nwhether the data in the current packet matches the current rule node's\r\ninformation.  Having this function pointer list gives us great\r\nefficiency and flexibility: we don't need to perform tests for things\r\nthe current rule doesn't contain (e.g., ``any'' ports/IPs, packet content\r\non non-content rules, etc).  It also allows us to analyze the packet\r\nwith any function without having to make major modifications to the\r\nwhole program (which was the case in versions prior to version 1.5).\r\n\r\nThere are a couple of implications of this architecture.  For the sake\r\nof this discussion on rules ordering, the one we're interested in is\r\nthat rule order is tricky to figure out.  For instance:\r\n\r\n\\begin{verbatim}\r\nalert tcp any any -> $HOME 80 (content: \"foo\"; msg: \"foo\";)\r\nalert tcp any any -> $HOME 1:1024 (flags: S; msg: \"example\";)\r\nalert tcp any any -> $HOME 80 (flags: S; msg: \"Port 80 SYN!\";)\r\nalert tcp any any -> $HOME 80 (content: \"baz\"; msg: \"baz\";)\r\n\\end{verbatim}\r\n\r\ngets built like this:\r\n\r\n\\begin{verbatim}\r\n        RTN                            RTN\r\n --------------------           --------------------\r\n|  SIP: any          |         |  SIP: any          |\r\n|  SP: any           |-------->|  SP: any           |\r\n|  DIP: \\$HOME        |         |  DIP: \\$HOME        |\r\n|  DP: 80            |         |  DP: 1-1024        |\r\n --------------------           --------------------\r\n       |                              |\r\n       |                              |\r\n  OTN    \\|/                            \\|/\r\n ---------v----------           ---------v----------  \r\n| content: foo       |         | flags: S           |\r\n| msg: foo           |         | msg: example       |\r\n --------------------           --------------------\r\n       |\r\n       |\r\n  OTN    \\|/  \r\n ---------v----------\r\n| flags: S           |\r\n| msg: Port 80 SYN!  |\r\n --------------------\r\n       |\r\n       |\r\n  OTN    \\|/  \r\n ---------v----------\r\n| content: baz       |\r\n| msg: baz           |\r\n --------------------\r\n\\end{verbatim}\r\n\r\nNote that all three of the port 80 rules will be checked before the\r\n``1:1024'' rule due to the order in which the applicable RTN has been\r\ncreated.  This is because the rules parser builds the first chain header\r\nfor port 80 traffic and sticks it on the rules list, then on the next\r\nrule it sees that a new chain header is required, so it gets built and\r\nput in place.  In this case you would intuitively expect to get the\r\n``example'' message and never see the ``Port 80 SYN!,'' but the opposite is\r\ntrue.\r\n\r\n\\subsection{How do I configure stream4?}\r\n\\label{stream4}\r\n\r\nStream4 is an entirely new preprocessor that preforms two functions:\r\n\r\n\\begin{itemize}\r\n\\item Stateful inspection of TCP sessions\r\n\\item TCP stream reassembly\r\n\\end{itemize}\r\n\r\nMarty implemented stream4 out of the desire to have more robust stream reassembly capabilities and the desire to defeat the latest ``stateless attacks'' that have been coming out against Snort (c.f. stick and snot).  Stream4 is written with the intent to let Snort be able to handle performing stream reassembly for ``enterprise class'' users, people who need to track and reassemble more than 256 streams simultaneously.  Marty optimized the code fairly extensively to be robust, stable, and fast.  The testing and calculations I've performed lead me to be fairly confident that stream4 can provide full stream reassembly for several thousand simultaneous connections and stateful inspection for upwards of 64,000 simultaneous sessions.\r\n\r\nStream4 is a large and complex piece of code (almost 2000 lines) and there are a lot of options associated with its runtime configuration, so I'll go over them here.\r\n\r\n\\begin{verbatim}\r\npreprocessor stream4: [noinspect], [keepstats], [timeout <seconds>], [memcap]\r\n\\end{verbatim}\r\n\r\nstream4\\_reassemble defaults: \r\n\\begin{verbatim}\r\nReassemble client: ACTIVE \r\nReassemble server: INACTIVE \r\nReassemble ports: 21 23 25 53 80 143 110 111 513 \r\nReassembly alerts: ACTIVE \r\n\\end{verbatim}\r\n\r\n\r\n\\subsection{Where does one obtain new/modifed rules? How do you merge them in?}\r\n\r\nNew rules can be downloaded via CVS \\myref{cvs} or, alternatively, may be \r\nfound at www.snort.org. There is a mailing list dedicated to Snort rules, \r\ncalled snort-sigs hosted at Sourceforge.\r\n\r\nThere are some scripts/programs to help you with rule management:\r\n\\begin{itemize}\r\n  \\item oinkmaster: A simple Perl script to update the ruleset for you.\r\n\r\n    \\htmladdnormallink{http://www.algonet.se/~nitzer/oinkmaster/}{http://www.algonet.se/~nitzer/oinkmaster/}\r\n\r\n  \\item IDS Policy Manager: A win32 application that updates the ruleset\r\n    using a GUI, then uploads your rulesets via scp.\r\n\r\n    \\htmladdnormallink{http://www.activeworx.com/idspm}{http://www.activeworx.com/idspm}\r\n\r\n  \\item snortpp: a program to merge multiple files into one master file sorted by\r\n    SID.\r\n\r\n    \\htmladdnormallink{http://dragos.com/snortpp.tgz}{http://dragos.com/snortpp.tgz}\r\n\\end{itemize}\r\n\r\nThere is also this script that might be useful:\r\n\\begin{verbatim}\r\n  * []#!/bin/sh\r\n    ###########################################################################\r\n    ####\r\n    #\r\n    # Das Skript zum Herunterladen und installieren neuer IDS-Signaturen.\r\n    #\r\n    ###########################################################################\r\n    ####\r\n    MAILTO=\"admin@mydomain.de\"\r\n    MACHINE=\"machine1\"\r\n    #set -x\r\n    SIGS_URL1=\"http://www.snort.org/dl/signatures/snortrules-stable.tar.gz\"\r\n    MD5_URL1=\"http://www.snort.org/dl/signatures/snortrules-stable.tar.gz.md5\"\r\n    WGET=\"/usr/bin/wget\"\r\n    #WGET_PARAMS=\"-N\"\r\n    WGET_PARAMS=\"-t 3 -T 5 -N -a /etc/snort/snort.log -P /etc/snort\"\r\n    # Wget parameters:\r\n    #\r\n    # -t            : Retries (here 3)\r\n    # -N            : Get the file only if newer\r\n    # -a            : Append the log messages to the specified file\r\n    # -P            : Save the file to the specified directory\r\n    # -T            : Timeout\r\n    ECHO=\"/bin/echo\"\r\n    TAR=\"/bin/tar\"\r\n    KILL=\"/bin/kill\"\r\n    PIDOF=\"/sbin/pidof\"\r\n    SNORT=\"/usr/local/bin/snort\"\r\n    SNORTUSER=\"snort\"\r\n    SNORTGROUP=\"snort\"\r\n    KILLSIG=\"SIGUSR1\"\r\n    SERVICE=\"/sbin/service\"\r\n\r\n    # Where is the Snort configuration dir:\r\n    RULESPATH=\"/etc/snort/snortrules\"\r\n    SNORTCFGPATH=\"/etc/snort\"\r\n    MD5SUM=\"/usr/bin/md5sum\"\r\n    MD5SUM_PARAMS=\"\"\r\n\r\n    # The list of sensor interfacec divided by blanks\r\n    IFACES=\"eth0\"\r\n\r\n    ###########################################################################\r\n    ####\r\n    #                           F U N C T I O N S \r\n    #\r\n    ###########################################################################\r\n    ####\r\n    ###########################################################################\r\n    ####\r\n    #    Die Funktion, die Snort fuer alle def. Interfaces auf dem System startet    \r\n    #\r\n    #\r\n    #\r\n    #     Um sie zu erweitern muss man zwei Dinge tun:                                \r\n    #\r\n    #     1. Die Parameterliste von Interfaces erweitern                              \r\n    #\r\n    # 2. Das Konfigurationsfile unter /etc/snort/snort.conf_ethX anlegen          #\r\n    #\r\n    #\r\n    ###########################################################################\r\n    ####\r\n    restartsnort() {\r\n\r\n    # Restarting Snort for all interfaces\r\n    for i in $IFACES; do\r\n             \"$ECHO\" \"Setting up Snort for interface \"$i\"\"\r\n             $ECHO \"Restarting Snort...\"\r\n             #/usr/bin/killall snort\r\n             if [ -f /var/run/snort_\"$i\".pid ]\r\n             then\r\n                     PID=$(\"$PIDOF\" \"$SNORT\")\r\n                     if [ -z \"$PID\" ]\r\n                     then\r\n                             \"$SERVICE\" snort restart\r\n                     else\r\n                             #`cat /var/run/snort_\"$i\".pid`\r\n                            \"$ECHO\" \"Restarting Snort running with PID \"$PID\" and reloading the rules...\"\r\n                            \"$KILL\" -s \"$KILLSIG\" \"$PID\"\r\n                     fi\r\n             else\r\n                     \"$ECHO\" \"No PID file for interface \"$i\" found under /var/\r\n    run\"\r\n             fi\r\n             \"$ECHO\" \"Starting Snort\"\r\n             \"$SNORT\" -a -b -c \"$SNORTCFGPATH\"\"/snort.conf_\"\"$i\" -I -D -v \r\n    -i $i -u \"$SNORTUSER\" -g \"$SNORTGROUP\"\r\n             PID=`cat /var/run/snort_\"$i\".pid`\r\n             \"$ECHO\" \"Snort running now with PID \"$PID\"\"\r\n    done\r\n    }\r\n    ###########################################################################\r\n    ####\r\n    #     Die Funktion zum ueberpruefen, ob und wie Snort auf dem System laeuft     \r\n    #\r\n    ###########################################################################\r\n    ####\r\n    checksnort() {\r\n    SNORTS=$(\"$PIDOF\" \"$SNORT\" | wc -w | awk '{print $1}')\r\n    SNORT_PIDS=$(/usr/bin/find /var/run -name snort\\_eth[0-9]\\.pid -ls | \r\n    wc -l | awk '{print $1}')\r\n    \"$ECHO\" \"Snort instances counted:  $SNORTS\"\r\n    \"$ECHO\" \"Snort PID files found:    $SNORT_PIDS\"\r\n    \r\n    # 1. Fall: Snort laeuft nicht oder PID-File nicht da:\r\n    if [ \"$SNORTS\" = \"0\" -o \"$SNORT_PIDS\" = \"0\" ]\r\n    then\r\n             \"$ECHO\" \"Snort seems to be down or no PID file there...\"\r\n             \"$ECHO\" \"Restarting Snort for all Interfaces...\"\r\n             \"$SERVICE\" snort restart\r\n    fi\r\n    # 2. Fall: Anzahl der Instanzen ungleich der Anzahl der PID-Files\r\n    if [ \"$SNORTS\" -gt \"$SNORT_PIDS\" ]\r\n    then\r\n             \"$ECHO\" \"More Snort instances than found PID files...\"\r\n             \"$ECHO\" \"Something is wrong outthere...\"\r\n             \"$ECHO\" \"Stopping all Snort processes...\"\r\n    #        /usr/bin/killall -9 snort\r\n            \"$SERVICE\" snort stop\r\n            \"$ECHO\" \"Hold on... Restarting Snort now...\"\r\n            \"$SERVICE\" snort restart\r\n    fi\r\n     \r\n    # 3. Fall: Anzahl der Instanzen stimmt mit der Anzahl der PID-files ueberein\r\n    }\r\n    ###########################################################################\r\n    ####\r\n    ###########################################################################\r\n    ####\r\n    getrules() {\r\n    # Get the rules, since we know that they are newer...\r\n    $WGET $WGET_PARAMS $SIGS_URL1\r\n    $WGET $WGET_PARAMS $MD5_URL1\r\n    \"$ECHO\" \"Readout the checksum...\"\r\n    # MD5-Summe auslesen\r\n    if [ -f /etc/snort/snortrules-stable.tar.gz.md5 ]\r\n    then\r\n             MD5SUM1=`grep MD5 \\\r\n                      /etc/snort/snortrules-stable.tar.gz.md5|awk \r\n    '{print $4}'`\r\n    else\r\n             \"$ECHO\" \"Error! No MD5-file found\"\r\n             exit 1\r\n    fi\r\n    \"$ECHO\" \"Generating our own checksum...\"\r\n    # MD5-Summe bilden\r\n    if [ -f /etc/snort/snortrules-stable.tar.gz ]\r\n    then\r\n        MD5SUM2=`md5sum /etc/snort/snortrules-stable.tar.gz|awk '{print $1}'`\r\n    else\r\n             \"$ECHO\" \"Error! No rules file found\"\r\n             exit 1\r\n    fi\r\n    if [ \"$MD5SUM1\" = \"$MD5SUM2\" ]\r\n    then\r\n             \"$ECHO\" \"The MD5-Checksum fits!\"\r\n             \"$ECHO\" \"$MD5SUM1\"\r\n             \"$ECHO\" \"$MD5SUM2\"\r\n             \"$ECHO\" \"$MD5SUM1\" >> /etc/snort/snort.log\r\n             \"$ECHO\" \"$MD5SUM2\" >> /etc/snort/snort.log\r\n             \"$ECHO\" \"Proceeding...\"\r\n    #        /bin/sleep 1\r\n    else\r\n             \"$ECHO\" \"Error! Wrong checksum! Aborting!\"\r\n             \"$ECHO\" \"Install rules manually!\"\r\n             \"$ECHO\" \"$MD5SUM1\" >> /etc/snort/snort.log\r\n             \"$ECHO\" \"$MD5SUM2\" >> /etc/snort/snort.log\r\n             exit 1\r\n    fi\r\n    # Extract the new rules\r\n    if [ -f \"/etc/snort/snortrules-stable.tar.gz\" ]\r\n    then\r\n             \"$ECHO\" \"Extracting Snort rules...\"\r\n             \"$TAR\" -xzvf /etc/snort/snortrules-stable.tar.gz -C /etc/snort\r\n    else\r\n             \"$ECHO\" \"Lost the file! Something is wrong!\"\r\n             \"$ECHO\" \"Aborting!!\"\r\n             exit 1\r\n    fi\r\n    # Deleting old rules\r\n    # Existiert das Verzeichnis ueberhaupt?\r\n    if [ -d \"$RULESPATH\" ]\r\n    then\r\n    #        /bin/rm \"$RULESPATH\"/*.rules\r\n             /bin/mv -f /etc/snort/rules/*.rules \"$RULESPATH\"\r\n             /bin/cp -f /etc/snort/rules/classification.config \"$SNORTCFGPATH\"\r\n    else\r\n             \"$ECHO\" \"Missing rules-directory!\"\r\n             \"$ECHO\" \"Aborting!\"\r\n             exit 1\r\n    fi\r\n     \r\n    # Cleaning up...\r\n    /bin/rm -rf /etc/snort/rules\r\n    # Give everything to root\r\n    /bin/chown root:root ${RULESPATH}/*\r\n    }\r\n    ###########################################################################\r\n    ####\r\n    #                                   M A I N                                      \r\n    #\r\n    ###########################################################################\r\n    ####\r\n    # Error handling first\r\n    FCHK=$(/usr/bin/wget -spider -N -t 3 -T 5 \"$SIGS_URL1\" -P /etc/snort 2>&1)\r\n    ERR_MSG=$(\"$ECHO\" \"$FCHK\" | egrep -oi \"failed error\")\r\n    # Log the error message explicitly\r\n    \"$ECHO\" \"$FCHK\" >> /etc/snort/snort.log\r\n    # If there is a word \"failed\" or \"error\" we break..\r\n    if [ \"$(\"$ECHO\" \"$FCHK\"| grep -i \"failed\")\" ] || \\\r\n       [ \"$(\"$ECHO\" \"$FCHK\"| grep -i \"error\")\" ]\r\n    then\r\n             \"$ECHO\" \"Error getting the files. The server seems to be not available.\"\r\n             \"$ECHO\" \"Error message:\"\r\n             \"$ECHO\" \"$FCHK\"\r\n             \"$ECHO\" \"Aborting!\"\r\n             exit 0\r\n    fi\r\n     \r\n    \"$ECHO\" \"Checking/getting files...\"\r\n    # First extract the wget message\r\n    FCHK=$(/usr/bin/wget -spider -N -t 3 -T 5 \"$SIGS_URL1\" \\\r\n                                  -P /etc/snort 2>&1 | grep \"not retrieving\")\r\n    /bin/date >> /etc/snort/snort.log\r\n    \"$ECHO\" \"Wget-output:\"\r\n    \"$ECHO\" $FCHK\r\n    # Logging what we've done and when\r\n    \"$ECHO\" \"$FCHK\" >> /etc/snort/snort.log\r\n    if [ -z \"$FCHK\"  ]\r\n    then\r\n             \"$ECHO\" \"The files on the server seem to be newer.\"\r\n             \"$ECHO\" \"We will get them now...\"\r\n             getrules\r\n             # Reload rules\r\n             \"$SERVICE\" snort reload\r\n    #        restartsnort\r\n    else\r\n    #\r\n            \"$ECHO\" \"The signature files on the server are older or not newer.\"\r\n             \"$ECHO\" \"Doing nothing for now...\"\r\n             \"$ECHO\" \"Checking if Snort is running....\"\r\n             checksnort\r\n             exit 0\r\n    fi\r\n    # Send Email\r\n    \"$ECHO\" -e \"`ls -lA \"$RULESPATH\"`\\n\\nSnort running with PID $(\"$PIDOF\"\\\r\n                \"$SNORT\")\" | mail -s \"Reloaded Snort signatures on $MACHINE\"\\\r\n                \"$MAILTO\"\r\n    ###########################################################################\r\n    ####\r\n    ###########################################################################\r\n    ####\r\n    exit 0\r\n    #EOF\r\n\\end{verbatim}\r\n\r\n\\subsection{How do I use a remote syslog machine?}\r\n\r\nAdd the syslog switch, -s, and put this statement syslog.conf:\r\n\\begin{verbatim}\r\n    auth.alert         @managmentserverIP\r\n\\end{verbatim}\r\n\r\nLook at your snort.conf file for more info on the facility and Priority\r\nsettings.\r\n\r\nMake sure you have syslogd on the management server configured to allow syslog over\r\nUDP. Under RedHat, you can do this by editing /etc/sysconfig/syslog and adding\r\nthe following line:\r\n\\begin{verbatim}\r\n    SYSLOGD_OPTIONS=\"-r -m 0\"\r\n\\end{verbatim}\r\nThis will start syslogd with the mark interval set to 0 (turning it off) and\r\nset it to receive network connections.\r\n\r\nThen restart syslog. ``man syslogd'' for more info. You might also want to\r\ninvestigate syslog-ng\\linebreak (\\htmladdnormallink{http://www.balabit.hu/en/downloads/syslog-ng/}{http://www.balabit.hu/en/downloads/syslog-ng/}).\r\n\r\nExample invocation of snort:\r\n\\begin{verbatim}\r\n    /usr/local/bin/snort -c /etc/snort/snort.conf -I -A full -s 192.168.0.2:514\r\n    -i rl0\r\n\\end{verbatim}\r\nNote for Win32 users:\r\n\r\nFrank Knobbe wrote a patch for Snort to allow you to use `-s $<$host$>$' on the\r\ncommand line under Windows without nullifying the snort.conf. In other words,\r\nSnort still uses all settings from snort.conf but in addition uses the host\r\nfrom `-s' to send syslog alerts to. You can find the patch at:\r\n\r\n    \\htmladdnormallink{http://www.snort.org/dl/contrib/patches/win32syslog/}{http://www.snort.org/dl/contrib/patches/win32syslog/}\r\n\r\n\\subsection{How do I get Snort and ACID working?}\r\n\r\nAcid has been unmaintained for quite some time. Use BASE instead (see below).\r\n\r\n\\subsection{How do I build this BASE thing?}\r\n\r\nRead carefully through all the docs for each package. Getting BASE to work is a\r\nlot of work, since it depends on many packages. You need a working Apache, a\r\nworking PHP, a working GD (and the many libraries GD depends on) and the ADODB\r\npackage. This is a lot of stuff to configure.\r\n\r\nA typical sequence to get this all working on Solaris 8: Use some binary\r\npackages from a trusted Sun freeware site (sunfreeware.com). The most problems\r\nwere with PHP and the GD library. GD itself needs a bunch of packages and\r\nlibraries to work also. It needs the libpng stuff, the libjpeg stuff (if you\r\nwant jpeg), etc, etc. Read through the readme for GD. So you either need to get\r\nthese and compile them also, or get some binary packages. PHP is the most\r\ndifficult thing to get compiled correctly. The PHP package needs to be compiled\r\nwith lots of ``-with'' flags for GD to work properly, otherwise it gets lots of\r\nrun-time unresolved reference errors. Just using a ``with'' for GD isn't\r\nsufficient. You also need to \"with\" each library which GD uses also, or PHP\r\ncan't find the functions it needs. Here's the ``configure'' line you can use to\r\nget PHP working:\r\n\\begin{verbatim}\r\n    ./configure --with-mysql --with-apxs=/usr/apache/bin/apxs --with-gd\r\n    --enable-sockets --with-jpeg-dir=/usr/local/lib --with-png-dir=/usr/local/\r\n    lib --with-zlib-dir=/usr/local/lib --with-xpm-dir=/usr/local/lib\r\n\\end{verbatim}\r\n These `with' statements basically have the effect of the Makefile including -L\r\nand -R statements for each library so that both the compile and run time\r\nlinkers can find all the functions needed to find in the Apache module\r\nenvironment. Apache doesn't seem to consult the LD\\_LIBRARY\\_PATH when running a\r\nmodule (or PHP doesn't, or there's some config item in the Apache conf files,\r\nbut you can just use the ``withs'').\r\n\r\nBasically, you need to work from the bottom up. So you need to obtain/compile\r\nany libraries that GD needs and install them, and any libraries/packages those\r\npackages need. Then once you get GD compiled properly and installed, compile\r\nPHP. Then make a PHP script that calls phpinfo() and carefully examine the page\r\nproduced. Once satisfied PHP is working, then the 'foundation' is ready for the\r\nother stuff. If they succeed, then install ADODB and BASE, tweak the config\r\nfiles, and it should all work. (heh, heh)\r\n\r\nBASE website: \\htmladdnormallink{http://base.secureideas.net/}{http://base.secureideas.net/}\r\n\r\n\\section{Rules and Alerts}\r\n\r\n\\subsection{Errors loading rules files}\r\n\r\nSome common ones:\r\n\r\n\\begin{itemize}\r\n\\item \\begin{verbatim}ERROR telnet.rules:YYY => Port value missing in rule!\\end{verbatim}\r\n\\item \\begin{verbatim}ERROR telnet.rules:YYY => Bad port number: \"(msg:\"blah\"\\end{verbatim}\r\n\\item \\begin{verbatim}ERROR telnet.rules:YYY => Couldn't resolve hostname blah\\end{verbatim}\r\n\\end{itemize}\r\n\r\nWhat's going on?\r\n\r\n``telnet.rules'' is the file where the syntax error occurred, and ``YYY'' is the \r\nline number it occurred on.  There are a couple of possibilities:\r\n\r\n\\begin{enumerate}\r\n\\item The rule is missing a port value, has an invalid port number, or a bad hostname - in which case the ruleset author/maintainer should be notified.\r\n\r\n\\item More often, the rule is just fine, but a variable in it was not declared.  Open the rules file, look at the rule on the line number provided, and confirm that the variables it uses have been declared.  You can read more about variables at \r\n\\htmladdnormallink{http://www.snort.org/docs/writing\\_rules/chap2.html\\#tth\\_sEc2.1.2}{http://www.snort.org/docs/writing\\_rules/chap2.html\\#tth\\_sEc2.1.2}\r\n\\end{enumerate}\r\n\r\n\\subsection{Snort says ``Rule IP addr (``1.1.1.1'') didn't x-late, WTF?''}\r\n\r\nGet rid of the quotes around the IP address and try again.\r\n\r\n\\subsection{Snort is behind a firewall (ipf/pf/ipchains/ipfilter) and awfully quiet...}\r\n\r\nYour firewall rules will also block traffic to the Snort processes.\r\n\r\nNote: This does not apply if Snort is installed {\\bf on} the firewall box.\r\n\r\n\\subsection{Does snort see packets filtered by IPTables/IPChains/IPF/PF?}\r\n\r\nSnort operates using libpcap. In general it sees everything the network adapter\r\ndriver sees before the network stack munges it. Linux IPTables, Linux IPChains,\r\nBSD PF and IPF and other packet filters do not prevent snort from seeing a\r\npacket that is present on the network wire. Even if an inbound packet is denied\r\nby the packet filter Snort will still see and analyze the packet if it is\r\nlistening to that interface. Snort/pcap sees whatever comes out of or goes into\r\nthe network adapter.\r\n\r\nNote however that Snort is affected to the extent that the stream of data on\r\nthe network wire is affected. Thus Snort will not see outbound packets which\r\nwere denied while being sent since they will never reach the network adapter.\r\n\r\nUnder OpenBSD you can snort just the PF rejects by using the /dev/pflogN\r\ninterface.\r\n\r\n\\subsection{I'm getting large amounts of $<$some alerts type$>$. What should I do?  Where can I go to find out more about it? }\r\n\r\nSome rules are more prone to producing false positives than others.     \r\nThis often varies between networks.  You first need to determine if it\r\nis indeed a false positive.  Some rules are referenced with ID numbers.\r\nThe following are some common identification systems, and where to go\r\nto find more information about a particular alert.\r\n\r\n\\begin{tabular}{|l|l|l|}\r\n\\hline\r\n{\\bf System} & {\\bf Example} & {\\bf URL} \\\\\r\n\\hline\\hline\r\nIDS & IDS182 & \\htmladdnormallink{http://www.whitehats.com/IDS/182}{http://www.whitehats.com/IDS/182} \\\\\r\n\\hline\r\nCVE & CVE-2000-0138 & \r\n\\htmladdnormallink{http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2000-0138}{http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2000-0138} \\\\\r\n\\hline\r\nBugtraq & BugtraqID 1 & \\htmladdnormallink{http://www.securityfocus.com/vdb/bottom.html?vid=1}{http://www.securityfocus.com/vdb/bottom.html?vid=1} \\\\\r\n\\hline\r\nMcAfee & Mcafee 10225 & \\htmladdnormallink{http://vil.nai.com/vil/dispVirus.asp?virus\\_k=10225}{http://vil.nai.com/vil/dispVirus.asp?virus\\_k=10225} \\\\\r\n\\hline\r\nNessus & Nessus 11073 & \r\n\\htmladdnormallink{http://cgi.nessus.org/plugins/dump.php3?id=11073}{http://cgi.nessus.org/plugins/dump.php3?id=11073}\\\\\r\n\\hline\r\n\\end{tabular}\r\n\r\nIt may be necessary to examine the packet payload to determine if the\r\nalert is a false positive.  The packet payload is logged using the -d\r\noption.  If you determine the alerts are false positives, you may want\r\nto write pass rules for machines that are producing a large number of them.\r\nIf the rule is producing an unmanageable amount of false positives from\r\na number of different machines, you could pass on the rule for all traffic.\r\nThis should be used as a last resort.\r\n\r\n\\subsection{What about all these false alarms? }\r\n\r\nMost think that a pile of false positives is infinitely preferable. Then\r\npeople can turn off what they don't want. The reverse, having a small rule\r\nset, can lure people into complacency thinking that Snort is doing ``its\r\nthing'' and there is nothing to worry about.\r\n \r\n\r\n\\subsection{What are all these ICMP files in subdirectories under /var/log/snort? }\r\n\r\nMost of them are likely destination unreachable and port unreachables that\r\nwere detected by snort when a communications session attempt fails.\r\n\r\n\r\n\\subsection{Why does the program generate alerts on packets that have pass rules?  }\r\n\r\nThe default order that the rules are applied in is alerts first, then pass\r\nrules, then log rules. This ordering ensures that you don't write 50 great\r\nalert rules and then disable them all accidentally with an errant pass rule. If\r\nyou really want to change this order so that the pass rules are applied first,\r\nuse the ``-o'' command line switch, or the ``order'' config directive.\r\n\r\nOne other thing to keep in mind is that the alert might be generated from a\r\npreprocessor. If that is the case, then no pass rule will help you minimize the\r\nfalse positives. You will need to use a BPF filter. \r\n\r\n\\subsection{What are all these ``ICMP destination unreachable'' alerts? }\r\n\r\nICMP is the acronym for Internet Control Message Protocol\r\nThey are failed connections ICMP unreach packet carries first 64\r\nbits(8bytes) or more of the original datagrami and the original IP header.\r\n\r\nThe ICMP Destination Unreachable (message type 3) is sent back to the\r\noriginator when an IP packet could not be delivered to the destination\r\naddress.  The ICMP Code indicates why the packet could not be delivered.\r\nThe original codes are:\r\n\r\n\\begin{itemize}\r\n\\item0 - net unreachable\r\n\\item1 - host unreachable\r\n\\item2 - protocol unreachable\r\n\\item3 - port unreachable\r\n\\item4 - fragmentation needed and DF bit set\r\n\\item5 - source route failed\r\n\\end{itemize}\r\n\r\nAs far as why... ``it all depends...''\r\n\r\nICMP Unreachable Error Messages are divided into two groups:\r\n\\begin{enumerate}\r\n\\item ICMP Unreachable Error Messages issued by routers (all 16 of them)\r\n\\item  ICMP Unreachable Error Messages issued by a Host (only 2)\r\n\\end{enumerate}\r\n\r\nWhat are the only 2 issued by a host?\r\nICMP Port Unreachable - the destination port on the targeted host is\r\n                        closed (a.k.a. not in a listening state).\r\nICMP Protocol Unreachable - the protocol we were trying to use is not\r\n                        being used on the targeted host.\r\n\r\n\r\nBoth ICMP Type field and Code field indicates why the packets could\r\nnot be delivered.  Some snort ICMP alerts\" are informational like the ICMP\r\nalerts found in icmp-info.rules.  At this time there are no references\r\nor even classtypes associated with these rules.\r\n\r\nOther rules are more likely to be associated with untoward activity.  For\r\nexample, in icmp.rules you will find:\r\n\r\n\\begin{verbatim}\r\nalert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:\"ICMP ISS Pinger\"; \r\ncontent:\"|495353504e475251|\";itype:8;depth:32; reference:arachnids,158; \r\nclasstype:attempted-recon; sid:465; rev:1;)\r\n\\end{verbatim}\r\n\r\nwhich has a reference where the importance might be determined by checking\r\nout the arachnids reference.  The classtype may indicate more or\r\nless the relative importance of the event.\r\n\r\nWhen a destination UDP port is closed on the targeted host, a.k.a. not\r\nin a listening state, the targeted host will issue an ICMP Port Unreachable\r\nerror message back to the offending packets source IP address, given in\r\nthe query.  Some programs use these messages, like traceroute with *nix\r\nbased machines. Windows based machines (tracert) will default to\r\nICMP Echo requests...\r\n\r\nFor further information about this, see:\r\n\\begin{itemize}\r\n\\item IP - ftp://ftp.isi.edu/in-notes/rfc791.txt\r\n\\item ICMP - ftp://ftp.isi.edu/in-notes/rfc792.txt\r\n\\item TCP - ftp://ftp.isi.edu/in-notes/rfc793.txt\r\n\\item UDP - ftp://ftp.isi.edu/in-notes/rfc768.txt\r\n\\end{itemize}\r\n\r\nand\r\n\r\n\\htmladdnormallink{http://www.iana.org/assignments/icmp-parameters}{http://www.iana.org/assignments/icmp-parameters}\r\n\r\nActually, putting this URL somewhere handy is a good idea:\r\n\r\n\\htmladdnormallink{http://www.iana.org/}{http://www.iana.org/}\r\n\r\nThere is also a good ICMP paper on \r\n\\htmladdnormallink{http://www.sys-security.com/}{http://www.sys-security.com/}\r\n\r\n\\subsection{Why do many Snort rules have the flags P (TCP PuSH) and A (TCP ACK) set? }\r\n\r\nOne of the reasons it alerts on a PA flags is to minimize the false\r\npositive. You will only get an alert upon successful connections. If you\r\nwant to see all the attempts, you either have to modify the signatures, add\r\nyou own signatures or use your firewall logs to see if an attempt to\r\nspecific a port occurred.\r\n\r\n\r\n\\subsection{What are these IDS codes in the alert names? }\r\n\r\nIDS means \"Intrusion Detection Signature\" and identifies a\r\nknown attack attempt. You can learn more about a specific IDS id\r\nat the arachNIDS search engine on \r\n\\htmladdnormallink{http://www.whitehats.com/}{http://www.whitehats.com/}.\r\nThe ``references'' keyword in rules can also be a good pointer \r\nfor further research.\r\n\r\n\r\n\\subsection{Snort says BACKDOOR SIGNATURE... does my machine have a Trojan? }\r\n\r\nIf you are dumping the data part of the packet, review it.\r\nThese rules are known to have high false rates as most of them\r\nare just based on numeric port numbers.\r\n\r\n\r\n\\subsection{What about ``CGI Null Byte attacks?'' }\r\n\r\nIt's a part of the http preprocessor. Basically, if the http decoding \r\nroutine finds a \\%00 in an http request, it will alert with this message. \r\nSometimes you may see false positives with sites that use cookies with\r\nurlencoded binary data, or if you're scanning port 443 and picking up \r\nSSLencrypted  traffic . If you're logging alerted packets you can  check\r\nthe  actual string that caused the alert.  Also, the unicode alert is\r\nsubject to  the same false positives with cookies and SSL. Having the packet\r\ndumps is the  only way to tell for sure if you have a real attack on your\r\nhands, but this  is true for any content-based alert.\r\n\r\n\\subsection{Why do certain alerts seem to have `unknown' IPs in BASE?  }\r\n\r\nSee the BASE FAQ at \\htmladdnormallink{http://base.secureideas.net/faq.php}{http://base.secureideas.net/faq.php}\r\n\r\n\\subsection{Can priorities be assigned to alerts using BASE?  }\r\n\r\nSee the BASE FAQ at \\htmladdnormallink{http://base.secureideas.net/faq.php}{http://base.secureideas.net/faq.php}\r\n\r\n\\subsection{What about `SMB Name Wildcard' alerts? }\r\n\r\nWhitehats IDS177\r\n\\htmladdnormallink{http://dev.whitehats.com/cgi/test/new.pl/Show?\\_id=netbios-name-query}{http://dev.whitehats.com/cgi/test/new.pl/Show?\\_id=netbios-name-query}\r\nspecifies traffic coming from {\\em outside} of your local network.  Allowing\r\nnetbios traffic over public networks is usually very insecure.\r\n\r\nIf the rule you are using also refers to ingres traffic only, then it\r\nwould explain why you don't see a lot of false positives.  For anyone\r\nreading that does see a lot of false postiives -  if you change your rule\r\nto reflect the source address as being !\\$HOME (or whatever variable you\r\nuse to represent your internal network), then you should see most of the\r\nfalse positives go away.\r\n\r\nThe value of this chack is that a default administrative share C\\$ ADMIN\\$ or\r\nsome such has been accessed.  This shouldn't happen in normal use - when\r\npeople want to share files they should be implicitely defining the shares\r\nand ACL.  \r\n\r\n\\subsection{What the heck is a SYNFIN scan? }\r\n\r\nSYNFIN scans got their name because there are both the SYN and FIN flags set. \r\n\r\n\\subsection{I am getting too many ``IIS Unicode attack detected'' and/or ``CGI Null Byte attack detected'' false positives.  How can I turn this detection off? }\r\n\r\nThese messages are produced by the http\\_decode preprocessor.  If you wish\r\nto turn these checks off, add -unicode or -cginull to your http\\_decode\r\npreprocessor line respectively.\r\n\r\n\\begin{verbatim}preprocessor http_decode: 80 8080 -unicode -cginull\\end{verbatim}\r\n\r\nYour own internal users normal surfing can trigger these alerts in the\r\npreprocessor. Netscape in particular has been known to trigger them.\r\n\r\nInstead of disabling them,try a BPF filter to ignore your outbound http\r\ntraffic such as:\r\n\r\n\\begin{verbatim}snort -d -A fast -c snort.conf not (src net xxx.xxx and dst port 80)\\end{verbatim}\r\n\r\nThis has worked very well for us over a period of 5-6 months and Snort is\r\nstill very able to decode actual and dangerous cgi null and unicode attacks\r\non our public web servers.\r\n\r\n\\subsection{How do I test Snort alerts and logging?}\r\n\r\nTry a rule that will fire off all the time like:\r\n\r\n\\begin{verbatim}alert tcp any any -> any any (msg:\"TCP traffic\";)\\end{verbatim}\r\n \r\nAlso take a look at sneeze at http://snort.sourceforge.net/sneeze-1.0.tar\r\nSneeze is a false positive generator that reads snort signatures and generates\r\npackets that will trigger the rules.\r\n\r\n\\subsection{What is the difference between ``Alerting'' and ``Logging''?}\r\n\r\nThere are two primary output facilities in Snort, logging and alerting. The\r\nalerting facility exists to let you know that something interesting has\r\nhappened. The logging facility exists to log full packet information to the\r\noutput format (pcap, ascii, database, etc).\r\n\r\nThe ``alert'' action in Snort is hard coded to do two things when an event is\r\ndetected by Snort, write an event to the alert facility and log as much as\r\npossible/desired to the output facility. The ``log'' action merely logs the\r\ncurrent packet to the logging facility without generating an alert. This is\r\ndone so you can log interesting things (telnet sessions, whatever) without\r\nhaving to generate an alert on every packet.\r\n\r\nThe database plugin is something of an anomaly because it doesn't separate the\r\ntwo functionalities very much. The ``log'' option attaches the log facility and\r\nthe ``alert'' option attaches it to the alert facility. What this means in\r\npractical terms is that if the db plugin is in alert mode, it will only receive\r\noutput from alert rules, whereas if it's in ``log'' mode it will receive output\r\nfrom both log and alert rules.\r\n\r\n\\subsection{Are rule keywords ORed or ANDed together?}\r\n\r\n>From Section 2.1 of the Snort Manual:\r\n\\myquote{\r\n    All of the elements in that make up a rule must be true for the indicated\r\n    rule action to be taken. When taken together, the elements can be\r\n    considered to form a logical AND statement. At the same time, the various\r\n    rules in a Snort rules library file can be considered to form a large\r\n    logical OR statement.\r\n }\r\n\\subsection{Can Snort trigger a rule by MAC addresses?}\r\n\r\nNot exactly. Snort logs MAC addresses and other L2 info within the packets. The\r\narpwatch pre-processor can watch for games with MAC address changes. But there\r\nis no facility for triggering Rules form the L2 information. The content search\r\nkeywords and depth and offset begin from the L3 payload, though we haven't\r\ntried playing with really big offsets yet :-).\r\n\r\n\\subsection{How can I deactivate a rule?}\r\n\r\nRules can be called from an included file in snort.conf, which tells Snort to\r\nfollow the path to the rules file specified, and load it at initialization.\r\nRules can also be included in snort.conf directly. If you want to deactivate a\r\nsingle rule within any list of rules, you can use one of these techniques:\r\n\r\n\\begin{enumerate}\r\n\\item  Delete the rule and re-initialize Snort\r\n\\item  Place a \\# in front of the rule, commenting it out, and re-initialize Snort\r\n\\item  Write a pass rule with the same properties in local.rules (or wherever you\r\n    prefer), and re-initialize Snort with the -o option.\r\n\\end{enumerate}\r\n\r\n\\subsection{How can I define an address to be anything except some hosts?}\r\n\r\nUse the ! operator. E.g.:\r\n\r\n\\begin{verbatim}\r\n    var EXTERNAL_NET !$HOME_NET\r\n\\end{verbatim}\r\nNote that the negation operator does not work inside a list so the following\r\nwill NOT work:\r\n\\begin{verbatim}\r\n    var EXTERNAL_NET [!192.168.40.0/24,!10.14.0.0/16]\r\n\\end{verbatim}\r\nbut this will work:\r\n\\begin{verbatim}\r\n    var EXTERNAL_NET ![192.168.40.0/24,10.14.0.0/16]\r\n\\end{verbatim}\r\n\\subsection{After I add new rules or comment out rules how do I make Snort reload?}\r\n\r\nUsually a kill -HUP will work just fine. But if you are running inside of a\r\nchroot setup, this will not work as expected \\myref{chroot}. If you're running\r\nlike inside of a chroot jail, your best bet would be to kill and restart the\r\nsnort process instead.\r\n\r\n\\subsection{Where do the distance and within keywords work from to modify content\r\nsearches in rules?}\r\n\r\nThe ``distance'' keyword gives you a relative offset from the end of the last\r\nmatch, so it basically acts as a wildcarding mechanism. You can also use the\r\nnew ``within'' keyword to limit how deep into the packet from the end of the\r\ndistance it'll search before it stops.\r\n\r\n\\subsection{How can I specify a list of ports in a rule?}\r\n\r\nYou can't yet. You can specify a range of ports between X and Y with the\r\nnotation X:Y. See the users manual (\\htmladdnormallink{http://www.snort.org/docs/writing\\_rules/chap2.html\\#tth\\_sEc2.2.4}{http://www.snort.org/docs/writing\\_rules/chap2.html\\#tth\\_sEc2.2.4}) for more info on port ranges.\r\n\r\n\\subsection{How can I protect web servers running on ports other than 80?}\r\n\r\nIt is possible... It's a kludge, but it can work. Since the newer rules use\r\nthe \\$HTTP\\_PORTS variable, you simply reset it and re-run the rules for the other\r\nports.\r\n\r\nFor example:\r\n\\begin{verbatim}\r\n    var HTTP_PORTS 80\r\n    include web.rules\r\n    var HTTP_PORTS 8080\r\n    include web.rules\r\n\\end{verbatim}\r\n\r\n\\subsection{How do I turn off ``spp:possible EVASIVE RST detection'' alerts?}\r\n\r\nYou want to pass the ``disable\\_evasion\\_alerts'' argument to stream4 in\r\nsnort.conf.\r\n\r\n\\subsection{Is there a private SID number range so my rules don't conflict?}\r\n\r\nYes. Private SIDs start at 1000000.\r\n\r\n\\subsection{How long can address lists, variables, or rules be?}\r\n\r\nThe Snort parser has an 8K limit on variables and rules {\\bf after} expansion. In\r\npractice, this is not a major limitation. :-)\r\n\r\n\\subsection{What do the numbers (ie: [116:56:1]) in front of a Snort alert mean?}\r\n\r\nFor this explanation, we'll use the following example:\r\n\\begin{verbatim}\r\n[**] [116:56:1] (snort_decoder): T/TCP Detected [**]\r\n\\end{verbatim}\r\nThe first number is the Generator ID, this tells the user what component\r\nof Snort generated this alert. For a list of GIDs, please read\r\netc/generators in the Snort source. In this case, we know that this event\r\ncame from the ``decode'' (116) component of Snort.\r\n\r\nThe second number is the Snort ID (sometimes referred to as Signature\r\nID). For a list of preprocessor SIDs, please see etc/gen-msg.map.\r\nRule-based SIDs are written directly into the rules with the ``sid''\r\noption. In this case, ``56'' represents a T/TCP event.\r\n\r\nThe third number is the revision ID. This number is primarily used when\r\nwriting signatures, as each rendition of the rule should increment this\r\nnumber with the ``rev'' option.\r\n\r\n\r\n\\section{Getting Fancy}\r\n\r\n\\subsection{I hear people talking about ``Barnyard''. What's that?\\label{barnyard}}\r\n\r\nBarnyard is a output system for Snort. Snort creates a special binary output\r\nformat called ``unified.'' Barnyard reads this file, and then resends the data\r\nto a database backend. Unlike the database output plugin, Barnyard is aware of\r\na failure to send the alert to the database, and it stops sending alerts. It is\r\nalso aware when the database can accept connections again and will start\r\nsending the alerts again.\r\n\r\n\\subsection{Are there other output systems for Snort besides ``Barnyard''?\\label{spoolers}}\r\n\r\nFLoP (Fast Logging Project) and Mudpit are two other programs that can be used.\r\n\r\nFLoP adds a patch to Snort that creates an output plugin that writes alerts to\r\na Unix domain socket instead of a file. These alerts (which are stored in memory)\r\nare then sent to a central server where they are then written to a database.\r\nAdvantages are that database requests are made locally rather than over\r\nthe wire and files don't need to be stored on the sensor. \r\n\r\n    \\htmladdnormallink{http://www.geschke-online.de/FLoP/}{http://www.geschke-online.de/FLoP/}\r\n\r\nMudpit is similar to Barnyard in that it uses Snort's unified output. It however \r\nhas the ability to process both alert and log files in parallel, choosing one\r\nthat contains more information on a particular event.\r\n\r\n    \\htmladdnormallink{http://farm9.org/Mudpit/}{http://farm9.org/Mudpit/}\r\n\r\n\\subsection{How do I process those Snort logs into reports?}\r\n\\begin{enumerate}\r\n\\item  Barnyard \\myref{barnyard} can be used to process unified output files into a number of\r\n    formats, including output to a database for further analysis.\r\n\\item  SnortSnarf, a tool for producing HTML out of snort alerts for navigating\r\n    through these alerts.\r\n\r\n%        \\htmladdnormallink{http://www.silicondefense.com/snortsnarf/}{http://www.silicondefense.com/snortsnarf/}\r\n\r\n\\item  If you want to set up logging to a database you could try BASE:\r\n\r\n        \\htmladdnormallink{http://base.secureideas.net/}{http://base.secureideas.net/}\r\n\r\n\\item  You can manipulate the unified output files directly without a separate\r\n    database and browse/correlate them with Cerebus:\r\n\r\n     \\htmladdnormallink{http://dragos.com/cerebus/}{http://dragos.com/cerebus/}\r\n\r\n\\item For GUI front ends with simple log browsing, look at:\r\n    \\begin{itemize}\r\n      \\item HenWen (OSX)\r\n\r\n            \\htmladdnormallink{http://homepage.mac.com/nickzman}{http://homepage.mac.com/nickzman}\r\n\r\n            \\htmladdnormallink{http://home.attbi.com/~rickzman/software/HenWen1.0.sit.bin}{http://home.attbi.com/~rickzman/software/HenWen1.0.sit.bin}\r\n\r\n      \\item IDS Center (Win32) \\label{IDSCenter}\r\n\r\n            \\htmladdnormallink{http://www.packx.net/}{http://www.packx.net/}\r\n\r\n     \\item Puresecure (UNIX and Win32) (Formerly known as Demarc.)\r\n\r\n            \\htmladdnormallink{http://www.demarc.com/downloads/puresecure/}{http://www.demarc.com/downloads/puresecure/}\r\n\r\n      \\item SnortCenter (UNIX and Win32)\r\n\r\n            \\htmladdnormallink{http://users.pandora.be/larc/}{http://users.pandora.be/larc/}\r\n\r\n      \\item IDS Policy Manager (Win32)\r\n\r\n            \\htmladdnormallink{http://www.activeworx.com/IDSPM/}{http://www.activeworx.com/IDSPM/}\r\n \\end{itemize}\r\n \\end{enumerate}\r\n\r\n\\subsection{How do I log to multiple databases or output plugins?}\r\n\r\nFeed the unified output files through Barnyard twice to separate databases,\r\nor...\r\n\r\nYou can build redundancy by using multiple output plugins. Here are some\r\nexamples.\r\n\r\nMultiple instantiations of the database plugin:\r\n\\begin{verbatim}\r\n    output log_database: mysql, dbname=snort host=localhost user=xyz\r\n    output log_database: mysql, dbname=snort host=remote.loghost.com user=xyz\r\n\\end{verbatim}\r\nRemote database and local tcpdump:\r\n\\begin{verbatim}\r\n    output log_database: mysql, dbname=snort host=remote.loghost.com user=xyz\r\n    output log_tcpdump: /var/log/snort.tcpdump\r\n\\end{verbatim}\r\nThen you can replay the tcpdump file through snort to recreate the database.\r\n\r\nCAVEAT: Just playing back the log packets might not trigger some of the state\r\ndependent pre-processors.\r\n\r\n\\subsection{How can I test Snort without having an Ethernet card or a connection to other computers?  }\r\n\r\nYou have to use routing between two dummy devices: \r\n\r\n\\begin{verbatim}\r\nmodprobe -a dummy # (The dummy device has to be build by the kernel) \r\nifconfig dummy0 192.168.0.1 \r\nifconfig dummy0:0 192.168.0.2  \r\ntelnet 192.168.0.3 12345 \r\n\\end{verbatim}\r\n\r\nIt's important that the second IP is on the same interface and not, e.g.\r\ndummy1 or dummy2 and that the IP you try to access is {\\em not} one of those you\r\nput on the interfaces. Use snort's ability to hear in promiscious mode on an\r\nIP address range. (HOME\\_NET=192.168.0.0/16)\r\n\r\n\\subsection{How to start Snort as a win32 service? }\r\n\r\n\\begin{enumerate}\r\n\\item You must use complete paths for everything. This means EVERYTHING: Command\r\n    line, configuration files, everything. \r\n    \r\n    Examples: All include statements must be full paths:\r\n\r\n        WRONG: include scan-lib\r\n\r\n        CORRECT: include C:\\( \\backslash \\)snort\\( \\backslash \\)scan-lib\r\n\r\n    All command line options must be full paths:\r\n\r\n        WRONG: snort.exe -l ./log\r\n\r\n        CORRECT: snort.exe -l C:\\( \\backslash \\)snort\\( \\backslash \\)log\r\n\r\n\\item  YOU MUST ALWAYS HAVE A LOGGING DIRECTORY SET VIA THE COMMAND LINE (-l\r\n    switch). If you do not set a logging directory the service will not start\r\n    and, on NT/Win2k, your bootup will hang for about 4 minutes.\r\n\\item  Make sure that snort runs correctly from the command line, without yet\r\n    worrying about any service related issues. Test that all of your desired\r\n    command line parameters are causing snort to function as you expect, such\r\n    as correctly generating logging and alert output. If you can't get this\r\n    part to work, then you don't have much hope of snort miraculously starting\r\n    to work as a service.\r\n\\item  Once you have step (3) running correctly, modify the command line\r\n    parameters you used in step (3) to include the additional parameters \r\n    ``/SERVICE /INSTALL.'' For example, if your command line in step (3) was:\r\n    \t\\begin{verbatim}\r\n       snort -i1 -lC:\\( \\backslash \\)snort\\( \\backslash \\)log -cC:\\( \\\r\n        backslash \\)snort\\( \\backslash \\)snort.conf\r\n\t\\end{verbatim}\r\n    then you should change it to be:\r\n    \t\\begin{verbatim}\r\n        snort /SERVICE /INSTALL -i1 -lC:\\( \\backslash \\)snort\\( \\backslash \\)\r\n        log -cC:\\( \\backslash \\)snort\\( \\backslash \\)snort.conf\r\n\t\\end{verbatim}\r\n    Verify that the command line parameters were received correctly by running\r\n    the command `snort /SERVICE /SHOW.'\r\n\\item  Start the service by running the command:\r\n\t\\begin{verbatim}\r\n        net start snortsvc\r\n\t\\end{verbatim}\r\n    Note that versions 1.9 (build 228), 2.0 (build 50), or any versions newer\r\n    than these, will add entries to the Win32 event Log if there is ever a\r\n    problem starting the service.\r\n    Stop the service by running the command:\r\n    \\begin{verbatim}\r\n        net stop snortsvc\r\n    \\end{verbatim}\r\n\\item  The service can be uninstalled by running the command:\r\n\t\\begin{verbatim}\r\n        snort /SERVICE /UNINSTALL\r\n\t\\end{verbatim}\r\n\\end{enumerate}\r\n\r\n\\subsection{Is it possible with snort to add a ipfilter/ipfw rule to a firewall? }\r\n\r\nYes.  Select the appropriate DAQ module for your system.  IPQ, NFQ, and IPFW\r\nDAQs are available, among others.  See README.daq for details.  Other\r\npossibilities are listed below.\r\n\r\n\\begin{itemize}\r\n\\item SnortSam\r\n\t\\htmladdnormallink{http://www.snortsam.net}{http://www.snortsam.net}\r\n\r\n\\item You also might wat to look at inline-snort at:\r\n\t\\htmladdnormallink{http://www.snort.org/dl/contrib/patches/snort-inline}{http://www.snort.org/dl/contrib/patches/snort-inline}\r\n\\item Guardian is available and is part of the contrib section at \\htmladdnormallink{http://www.snort.org}{http://www.snort.org}.\r\n\r\nGuardian is a perl script which uses Snort to detect attacks,\r\nand then uses IPchains to deny any further attacks. The Guardian webpage can be found at:\r\n\\htmladdnormallink{http://www.chaotic.org/~astevens/Guardian/index.html}{http://www.chaotic.org/~astevens/Guardian/index.html}\r\nor you can use the mirror,\r\n\\htmladdnormallink{http://www.cyberwizards.com/~midnite/Guardian/index.html}{http://www.cyberwizards.com/~midnite/Guardian/index.html}\r\n\r\n\\end{itemize}\r\nBut one caveat... running external binaries can also be a performance\r\nlimiter and your should read the caution below...\r\n\r\nCHRISTOPHER CRAMER wrote:\r\n\r\n\\myquote{\r\nI'm sure this has been mentioned before in similar discussions, but this\r\nfeels like a \\_really\\_ bad idea.  What if the bad guys realize what is\r\ngoing on and make use of your blocking method as a DoS attack.  All one\r\nwould have to do start sending a series of triggering packets with spoofed\r\nIP addresses.\r\n\r\nSince I am no longer interested in breaking into your site, but rather\r\nmaking your life hell, I don't worry about the resulting data getting back\r\nto me.  All I have to do is start proceeding up a list of IP addresses\r\nthat I think you should no longer be able to talk to.  When you come in\r\nthe next morning, you find that you can no longer access the world.\r\n\r\nJust my \\$0.02.\r\n}\r\n\r\nDanger Will Robinson: Conventional wisdom says that \r\nauto-blocking is inherently dangerous. \r\n\r\nHowever, for those that like to live at the \r\nbleeding edge of tech (and the separate\r\nprocess scanning logs and processing\r\nfirewall commands sounds like a good \r\nway to do this...):\r\n\r\nPlease remember to include an exclusion list and put \r\non them important sites such as root servers, other \r\nimportant dns servers (yours, and important sites for \r\nyour users), and in general any host you don't want \r\nto receive phone calls about being DoSed when\r\nthey are spoofed - usually inconveniently like that \r\nfirst time you actually manage to get on vacation....\r\n(i.e. imagine ``Crisis: the CEO can't reach his favorite \r\nredlite.org game.... you have to fly back from the \r\nCarribean ASAP....'')   \r\n\r\n\\subsection{What is the best way to use Snort to block attack traffic?}\r\n\r\n\\begin{verbatim}snort-inline > hogwash >> SnortSAM|Guardian >> flexresp\\end{verbatim}\r\n\r\n\r\n\\subsection{Snort complains about the ``react'' keyword...}\r\n\r\nRerun configure with the --enable-flexresp option and rebuild/reinstall.\r\n\r\n\\subsection{How do I get Snort to e-mail me alerts?}\r\n\r\nYou can't. Such a process would slow Snort down too much to make it of any use.\r\nInstead, log to syslog and use swatch or logcheck to parse over the plaintext\r\nlogfiles.\r\n\r\nWith the Logsurfer docs, this might get you on the road to doing something with\r\nSnort and Logsurfer:\r\n\\begin{itemize}\r\n  \\item\r\n    \\htmladdnormallink{http://www.obfuscation.org/emf/logsurfer/snort.txt}{http://www.obfuscation.org/emf/logsurfer/snort.txt}\r\n\\end{itemize}\r\nJASON HAAR provided an example Swatch (3.1beta) config that emails alerts:\r\n\r\n\\begin{itemize}\r\n  \\item    \\htmladdnormallink{http://www.theadamsfamily.net/~erek/snort/snort-swatch.conf.txt}{http://www.theadamsfamily.net/~erek/snort/snort-swatch.conf.txt}\r\n\\end{itemize}\r\nHere are some docs on swatch:\r\n\\begin{itemize}\r\n  \\item \\htmladdnormallink{http://www.oit.ucsb.edu/~eta/swatch/}{http://www.oit.ucsb.edu/~eta/swatch/}\r\n  \\item \\htmladdnormallink{http://www.stanford.edu/~atkins/swatch}{http://www.stanford.edu/~atkins/swatch}\r\n  \\item \\htmladdnormallink{http://rr.sans.org/sysadmin/swatch.php}{http://rr.sans.org/sysadmin/swatch.php}\r\n  \\item \\htmladdnormallink{http://www.enteract.com/~lspitz/swatch.html}{http://rr.sans.org/sysadmin/swatch.php}\r\n  \\item \\htmladdnormallink{http://www.cert.org/security-improvement/implementations/i042.01.html}{http://www.cert.org/security-improvement/implementations/i042.01.html}\r\n\\end{itemize}\r\n\r\nIDS Center \\myref{IDSCenter} on Win32 will also mail alerts.\r\n\r\n\\subsection{How do I log a specific type of traffic and send alerts to syslog?}\r\n\r\nAn example addition to snort.conf:\r\n\\begin{verbatim}\r\nruletype redalert {\r\n   type alert\r\n   output alert_syslog: LOG_LOCAL2\r\n    output database: alert, postgresql, user=user dbname=snort password=pwd\r\n}\r\n\\end{verbatim}\r\n\r\nGo into your local.rules and make sure you have something like:\r\n\r\n\\begin{verbatim}\r\nredalert tcp any any -> any any (msg:\"REDRUM REDRUM\"; content:\"redalerttest\")\r\n\\end{verbatim}\r\n\r\nThen just do a telnet and type `redalerttest.'  Presto, alerts to both.\r\n\r\n\\subsection{Is it possible to have Snort call an external program when an alert is raised?}\r\n\r\nCalling another program from within your main IDS loop is\r\ngenerally a bad idea.  Having your IDS block while waiting\r\nfor $<$something$>$ of dubious reliability and origin nevermind\r\ntiming while the packets are piling up is inviting packet loss.\r\nEspecially with the already oh-so-consistent ``Gee I think\r\nI'll go away for a minute'' rock steady even cpu slicing\r\nWindows gives you (that's sarcasm, sorry). Go  with the\r\nsecond approach.... process invokation is expensive on \r\nWindows.\r\n\r\nYou want to keep that IDS task humming and munching\r\npackets as efficiently as possible with as few interruptions\r\nas possible, imho, and not be invoking the penalty of\r\nprocess invocation.... particularly on Windows where\r\nprocess invocation is much much heavier task than *nix.\r\n\r\nEven in a secondary process... You'll probably find\r\nsomething that stays ``awake'' all the time will work out\r\nmuch more nicely than something that gets ``woken up''\r\non a per alert basis for the aforementioned reasons.\r\n  \r\nAs a better alternative go check out swatch or logwatch.\r\nAlso for those new to UNIX, logging alerts to syslog and then using \r\n``tail -f /var/log/messages'' might be what you are looking for.\r\n\r\n\\subsection{How can I use Snort to log HTTP URLs or SMTP traffic?}\r\n\r\nIt can be done with Snort, but you might find it faster to use mailsnarf and\r\nurlsnarf from Dug Song's dsniff package. Dsniff is available from:\r\n\r\n    \\htmladdnormallink{http://www.monkey.org/~dsong/dsniff/}{http://www.monkey.org/~dsong/dsniff/}\r\n\r\nYou can get a win32 port of dsniff at:\r\n\r\n    \\htmladdnormallink{http://www.datanerds.net/~mike/dsniff.html}{http://www.datanerds.net/~mike/dsniff.html}\r\n\r\n\\subsection{What are some resources that I can use to understand more about source\r\naddresses logged and where they are coming from?}\r\n\r\n\\begin{itemize}\r\n  \\item \\htmladdnormallink{http://www.arin.org/}{http://www.arin.org/}\r\n  \\item \\htmladdnormallink{http://www.caida.org/tools/utilities/netgeo/}{http://www.caida.org/tools/utilities/netgeo/}\r\n  \\item \\htmladdnormallink{http://netgeo.caida.org/perl/netgeo.cgi}{http://netgeo.caida.org/perl/netgeo.cgi}\r\n  \\item \\htmladdnormallink{http://standards.ieee.org/regauth/oui/oui.txt}{http://standards.ieee.org/regauth/oui/oui.txt}\r\n  \\item \\htmladdnormallink{http://www.codito.de/manufactor\\_hash}{http://www.codito.de/manufactor_hash}\r\n  \\item \\htmladdnormallink{http://coffer.com/mac\\_find/}{http://coffer.com/mac_find/}\r\n  \\item \\htmladdnormallink{http://www.idefense.com/Intell/CI022702.html}{http://www.idefense.com/Intell/CI022702.html}\r\n  \\item \\htmladdnormallink{http://www.idefense.com/excelfiles/All.zip}{http://www.idefense.com/excelfiles/All.zip}\r\n\\end{itemize}\r\n\r\nAlso, try ``dig.''\r\n\r\n\\subsection{How do I understand this traffic and do IDS alert analysis?}\r\n\r\n\\begin{enumerate}\r\n\\item  You'll need to understand some basics of IP, TCP, and UDP. Things like\r\n    destination addresses, source addresses, common ports, what TCP SYN, FIN\r\n    and RST mean, etc. The same kind of basic knowledge of the internet you\r\n    need to successfully configure a multi-interface router applies here,\r\n    although you don't need to know router syntax. Some useful online\r\n    references:\r\n    \\begin{itemize}\r\n      \\item A truly basic ``intro to TCP/IP'' \\htmladdnormallink{http://pclt.cis.yale.edu/pclt/COMM/TCPIP.HTM}{http://pclt.cis.yale.edu/pclt/COMM/TCPIP.HTM}\r\n      \\item A reasonable looking TCP/IP FAQ: \\htmladdnormallink{http://www.itprc.com/tcpipfaq/default.htm}{http://www.itprc.com/tcpipfaq/default.htm}\r\n      \\item A basics of firewalls, DMZ's, etc.\r\n     \r\n     \\htmladdnormallink{http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html\\_single/Firewall-HOWTO.html}{http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html_single/Firewall-HOWTO.html}\r\n      \\end{itemize}\r\n\\item  You'll need to understand some basics of how network attacks work. I'd\r\n    recommend skimming over ``Smashing the Stack for fun and profit'' by Aleph\r\n    one. A deep understanding isn't necessary, but a casual read of this will\r\n    give you some helpful basics in understanding the kinds of things that\r\n    happen in an attack, and give you a better understanding of what to look\r\n    for.\r\n\r\n        \\htmladdnormallink{http://www.insecure.org/stf/smashstack.txt}{http://www.insecure.org/stf/smashstack.txt}\r\n\r\n\\item  A good guide on securing systems is helpful, something like this one:\r\n\r\n        \\htmladdnormallink{http://www.openna.com/products/books/sol/solus.php}{http://www.openna.com/products/books/sol/solus.php}\r\n\r\n        \\htmladdnormallink{http://www.seifried.org/lasg/}{http://www.seifried.org/lasg/}\r\n\r\n\\item  You'll need to understand the basics of internet servers, ie: what DNS,\r\n    HTTP, FTP, SMTP, etc. are for. Most of that should be covered in the\r\n    various other references made here.\r\n\\item  An excellent reference on ``oddball'' traffic patterns commonly seen at\r\n    network borders, also very helpful:\r\n\r\n      \\htmladdnormallink{http://www.robertgraham.com/pubs/firewall-seen.html}{http://www.robertgraham.com/pubs/firewall-seen.html}\r\n\\item  Also take a look at the ``Recommended Reading'' section \\myref{courses}\r\n\\end{enumerate}\r\n\r\n\r\n\\subsection{How can I examine logged packets in more detail?}\r\n\r\nIf you are using unified logging, you can use Barnyard \\myref{barnyard} or the unified log to pcap converter written by Dragos:\r\n\r\n    \\htmladdnormallink{http://dragos.com/logtopcap.c}{http://dragos.com/logtopcap.c}\r\n\r\nYou can also use the \\texttt{getpacket} program from the FLoP project \\myref{spoolers}\r\n\r\nYou can then get additional decoding of the packet contents by analyzing these\r\npcap files with either:\r\n\\begin{itemize}\r\n  \\item Tcpdump - http://www.tcpdump.org\r\n  \\item Ethereal - http://www.ethereal.com\r\n\\end{itemize}\r\n\r\n\\section{Problems}\r\n\\subsection{ I think I found a bug in Snort. Now what?}\r\n\r\nGet some more diagnostic information and post it to ``snort-users'' at\r\n\\htmladdnormallink{http://www.sourceforge.net/lists/listinfo/snort-users}{http://www.sourceforge.net/lists/listinfo/snort-users}.\r\n\r\nTo get diagnostic information, compile snort as either:\r\n\r\n\\begin{verbatim}make clean; make CFLAGS=-ggdb\\end{verbatim}\r\n\r\nor\r\n\\begin{verbatim}make clean; make \"CFLAGS=-ggdb -DDEBUG\" \\end{verbatim}\r\n\r\ntrace coredump as:\r\n\r\n\\begin{verbatim}\r\ngdb /path/to/snort /path/to/snort/core\r\n\r\ngdb> where\r\ngdb> bt \r\ngdb> print $varname, varname, \\$\\$varname etc..\r\n\\end{verbatim}\r\n\r\nor if corefile isn't generated, Snort should be started as:\r\n\r\n\\begin{verbatim}\r\ngdb snort\r\n\r\ngdb> run snort\\_args\\_go\\_here\r\n\\end{verbatim}\r\n\r\nThen, when it crashes:\r\n\\begin{verbatim}\r\n  gdb> where\r\n  gdb> bt\r\n  gdb> print \\$varname, varname, \\$\\$varname etc..\r\n\\end{verbatim}\r\n\r\n\\subsection{SMB alerts aren't working, what's wrong? }\r\n\r\nThe SMB alerting output plugin was removed in Snort 2.1 due to security issues.\r\n \r\n\\subsection{Snort says ``Garbage Packet with Null Pointer discarded!'' Huh?}\r\n\r\n This was an internal diagnostic message triggered by an old bug\r\nin early versions of the defragmentation preprocessor.  Upgrade to \r\nto the latest version of Snort.\r\n\r\n\\subsection{Snort says ``Ran Out Of Space.'' Huh?}\r\n\r\nThis is an internal diagnostic message when the defragmentation\r\npreprocessor runs into its ~32MB hard allocation space limit.\r\nTell Dragos about it $<$dr@kyx.net$>$.\r\n\r\n\\subsection{My BASE db connection times-out when performing long operations (e.g.\r\ndeleting a large number of alerts).}\r\n\r\nPHP has an internal variable set to limit the length an script can execute. It\r\nis used to prevent poorly written code from executing indefinitely. In order to\r\nmodify the time-out value, examine the 'max\\_execution\\_time' variable found in\r\nthe 'php.ini' configuration file.\r\n\r\n\\subsection{Why does snort report ``Packet loss statistics are unavailable under Linux?''}\r\n\r\nThe Linux IP stack doesn't report lost packet stats. This also has been\r\nrecently fixed with the 2.4+ kernel in the new version of libpcap...upgrade\r\nkernels and libpcap and it should now work.\r\n\r\n\\subsection{My /var/log/snort directory gets very large...}\r\n\r\nTry this script to archive the files:\r\n\r\n\\begin{verbatim}\r\n  * []#!/bin/sh\r\n\r\n    # \r\n    # Logfile rotation script for snort written by jameso@elwood.net.\r\n    # \r\n    # This script is pretty basic. We start out by setting some vars.\r\n    # Its job is tho rotate the days logfiles, e-mail you with what \r\n    # it logged, keep one weeks worth of uncompressed logs, and also\r\n    # keep compressed tgz files of all the logs. It is made to be run\r\n    # at midnight everynight. This script expects you to have a base\r\n    # dir that you keep all of your logs, rule sets etc in. You can \r\n    # see what sub dirs it expects from looking at the var settings\r\n    # below.\r\n    # \r\n    # Things to note in this script is that we run this script at 12 \r\n    # every night, so we want to set the dirdate var the day the script\r\n    # runs minus a day so we label the files with the correct day. We\r\n    # Then create a dir for the days logs, move the log files into \r\n    # today's dir. As soon as that is done restart snort so we don't miss\r\n    # anything. Then delete any logs that are uncompressed and over a\r\n    # week old. Then compress out today's logs and archive them away, and\r\n    # end up by mailling out the logs to you.\r\n    #\r\n    # Define where you have the base of your snort install\r\n    snortbase=/usr/snort\r\n    # Define other vars\r\n    # logdir   - Where the logs are kept\r\n    # oldlogs  - Where you want the archived .tgz logs kept\r\n    # weeklogs - This is where you want to keep a weeks worth of log files uncompressed\r\n    # dirdate  - Todays Date in Month - Day - Year format\r\n    # olddirdate - Todays date in the same format as dirdate, minus a week\r\n    logdir=$snortbase/log\r\n    oldlogs=$snortbase/oldlogs\r\n    weeklogs=$snortbase/weeklogs\r\n    # When I first wrote this script, I only ran it on BSD systems. That was a\r\n    # mistake, as BSD systems have a date command that apperently lets you walk the\r\n    # date back pretty easily. Well, some systems don't have this feature, so I had\r\n    # to change the way that dates are done in here. I left in the old way, because\r\n    # it is cleaner, and I added in a new way that should be portable. If anyone\r\n    # has any problems, just let me know and I will try to fix it.\r\n    #\r\n    # You have to change the system var to either bsd or other. Set it to bsd if\r\n    # your system supports the \"-v\" flag. If you are not sure, set it to other.\r\n    system=bsd\r\n    if [ $system = bsd ]\r\n    then\r\n     dirdate=`date -v -1d \"+%m-%d-%y\"`\r\n     olddirdate=`date -v -8d \"+%m-%d-%y\"`\r\n    elif [ $system = other ]\r\n     month=`date \"+%m\"`\r\n     yesterday=`expr \\`date \"+%d\"\\` - 1`\r\n     eightday=`expr \\`date \"+%d\"\\` - 8`\r\n     year=`date \"+%y\"`\r\n     dirdate=$month-$yesterday-$year\r\n     olddirdate=$month-$eightday-$year\r\n    fi\r\n    \r\n    # Create the Dir for today's logs.\r\n    if [ ! -d $weeklogs/$dirdate ]\r\n    then\r\n     mkdir $weeklogs/$dirdate\r\n    fi\r\n    \r\n    # Move the log files into today's log dir. This is done with\r\n    # a for loop right now, because I am afraid that if alot is\r\n    # logged there may be to many items to move with a \"mv *\"\r\n    # type command. There may a better way to do this, but I don't\r\n    # know it yet.\r\n    for logitem in `ls $logdir` ; do\r\n     mv $logdir/$logitem $weeklogs/$dirdate\r\n    done\r\n    \r\n    # Kill and restart snort now that the log files are moved.\r\n \r\n    kill `cat /var/run/snort_fxp0.pid`\r\n    \r\n    # Restart snort in the correct way for you\r\n \r\n    /usr/local/bin/snort -i fxp0 -d -D -h homeiprange/28 -l /usr/snort/log \\\r\n    -c /usr/snort/etc/08292k.rules > /dev/null 2>&1\r\n\r\n    # Delete any uncompressed log files that over a week old.\r\n \r\n    if [ -d $weeklogs/$olddirdate ]\r\n    then\r\n     rm -r $weeklogs/$olddirdate\r\n    fi\r\n\r\n    # Compress and save the log files to save for as long as you want.\r\n    # This is done in a sub-shell because we change dirs, and I don't want \r\n    # to do that within the shell that the script runs in.\r\n\r\n    (cd $weeklogs; tar zcvf $oldlogs/$dirdate.tgz $dirdate > /dev/null 2>&1)\r\n\r\n    # Mail out the log files for today.\r\n\r\n    cat $weeklogs/$dirdate/snort.alert | mail -s \"Snort logs\" you@domain.com\r\n    cat $weeklogs/$dirdate/snort_portscan.log |\r\n     mail -s \"Snort portscan logs\" you@do\r\n    main.com\r\n    \\end{verbatim}\r\n\r\n\\subsection{Why does the `error deleting alert' message occur when attempting to delete an alert with BASE?  }\r\n\r\nMost likely the DB user configure in BASE does not have sufficient\r\nprivileges. In addition to those privileges granted to log the alerts into\r\nthe database (INSERT, SELECT), DELETE is also required. \r\n\r\nThis permission related issue can be confirmed by manually inserting a row\r\ninto the database, then trying to delete it. \r\n\r\n\\begin{enumerate}\r\n\\item Log into MySQL with the same credentials (i.e. username, password) as you use in BASE:\r\n\t\\begin{verbatim}\r\n\tmysql -u -p\r\n\t\\end{verbatim}\r\n\\item Insert a test row into the event table: \r\n\t\\begin{verbatim}\r\n\tmysql> INSERT INTO event (sid, cid, signature, timestamp) \r\n\tVALUES (1,1000000, \"test\", \"0\");\r\n\t\\end{verbatim}\r\n\t(this assumes that you don't already have a row with an event ID=1000000. If\r\n\tyou do just choose another event id \\#) \r\n\r\n\\item Now delete this newly inserted row:\r\n\r\n\\begin{verbatim}mysql> DELETE FROM event WHERE sid=1 AND cid=10000000; \\end{verbatim}\r\n\r\nIf you were not able to delete, this confirms that this is a permission\r\nproblem. Re-login to mysql as root, and issue a GRANT command (giving the\r\nDELETE permission) to the BASE DB user: \r\n\r\n\\begin{verbatim}GRANT DELETE on snort.* to base@localhost\\end{verbatim}\r\n\r\n(this assumes that my alert database is 'snort', username is 'base', and\r\nlogging from the 'localhost') \r\n\r\n\\end{enumerate}\r\n\\subsection{BASE appears to be broken in Lynx }\r\n\r\nSee the BASE FAQ at \\htmladdnormallink{http://base.secureideas.net/faq.php}{http://base.secureideas.net/faq.php}\r\n\r\n\\subsection{I am getting `snort [pid] uses obsolete (PF\\_INET, SOCK\\_PACKET)' warnings. What's wrong?}\r\n\r\nYou are using an older libpcap version with recent linux kernel. There should be\r\nno problem with it as long as your kernel supports SOCK\\_PACKET socket \r\ntype. To get rid off the warning message however, you'll have to upgrade \r\nto some recent version of libpcap (a copy from www.tcpdump.org is recommended).\r\n\r\n\\subsection{On HPUX I get device lan0 open: recv\\_ack: promisc\\_phys: Invalid argument}\r\n\r\nIt's because there's another program running using the DLPI service.\r\nThe HP-UX implementation doesn't allow more than one libpcap program\r\nat a time to run, unlike Linux (from snort.c).\r\n\r\n\\subsection{Snort is dying with a `can not create file' error and I have plenty of diskspace. What's wrong?}\r\n\r\nYou may run out of free inodes, which basically also means you can not create\r\nmore files on the partition. The obvious solution is to rm some. ;-)\r\n\r\n\\subsection{I am using Snort on Windows and receive an ``OpenPcap() error upon startup: ERROR: OpenPcap() device open: Error opening adapter'' message. What's wrong? }\r\n\r\nEither winpcap is not installed, or you are using an incompatible version.\r\nTry upgrading to the latest version (2.3 as of 01/17/03).  It is available \r\nfrom \\htmladdnormallink{http://netgroup-serv.polito.it/winpcap/}{http://netgroup-serv.polito.it/winpcap/}.\r\nIt might also be an issue with SMP machines \\myref{winpcap}.\r\n\r\n\\subsection{Snort is not logging to my database}\r\n\r\nThere are a number of problems that may be causing Snort to fail to log to a \r\ndatabase.  You should check these:\r\n\\begin{enumerate}\r\n\\item You did not set up the database plugin in your configuration file.\r\n\\item  You are using an older database schema, and should update it by running the create scripts from the ./schemas directory of the source tarball.\r\n\\item You are using a command line option that overrides what you have in your configuration file.  This is most often -A or -s.  NOTE: If you wish to log to syslog as well, specify so in your configuration file rather then the command line.\r\n\\item There is a problem with your database configuration itself.  Make sure the user you specify has the correct permissions, or that the database is even up and running.\r\n\\end{enumerate}\r\n\r\n\\subsection{Portscans are not being logged to my database }\r\n\r\nYou need to change the output facility to 'alert' rather then 'log'.  The \r\nportscan preprocessor calls output plugins registered as 'alert' plugins \r\nrather then 'log'.\r\n\r\n\\begin{verbatim}output database: alert, mysql, user=snort dbname=snort host=localhost\\end{verbatim}\r\n\r\n\\subsection{Snort is not logging to syslog}\r\n\r\nThere are a number of problems that may be causing snort to fail to log to syslog.  You should check these:\r\n\\begin{itemize}\r\n\\item You are using a command line option that overrides what you have in your configuration file.  This is most often -A.\r\n\\item It may be logging to the wrong place.  Make sure syslog is configured correctly.\r\n\\end{itemize}\r\n\r\n\r\n\\subsection{I am still getting bombarded with spp\\_portscan messages even though the IP that I am getting the portscan from is in my \\$DNS\\_SERVERs var }\r\n\r\nTry adding /32 netmasks to those addresses:\r\n\r\n\\begin{verbatim}var DNS_SERVERS \\[xxx.xx.0.3/32,xxx.xxx.0.2/32\\]\\end{verbatim}\r\n\r\nAnd make sure the \\$DNS\\_SERVERS variable is on the portscan-ignorehosts line:\r\n\r\n\\begin{verbatim}preprocessor portscan-ignorehosts: $DNS_SERVERS\\end{verbatim}\r\n\r\n\\subsection{Why does chrooted Snort die when I send it a SIGHUP? \\label{chroot}}\r\n\r\nIt's a known problem with permissions. Workaround, restart snort instead.\r\n\r\nBut the short answer is this:  Due to the way the execv(2) call works, it\r\n\"Restarts\" snort from scratch.  This has the odd side effect of making \r\nHUPS to a chrooted snort become recursive.  For example, chroot to /snort.\r\nIt now sees /snort as / .  Now HUP snort.  Snort now expects to have \r\n/snort/snort as /.  In other words, you have to re-create your directories \r\nfor your jail inside it.  4 HUPS and you will be in \r\n/snort/snort/snort/snort.  \r\n\r\n\\subsection{My snort crashes, how do I restart it?}\r\n\r\nTry one of these two shell scripts or daemontools (refer to website to\r\ndaemontools)\r\n\r\n\\begin{verbatim}\r\n  * []#!/bin/sh\r\n    #snorthup: Snort Restarter and Crash Logger \r\n    #(dr@kyx..net with help from kmaxwell@superpages.com)  \r\n\r\n    $conf = \"snort.conf\"\r\n    for $IFACE in fxp0 fxp1\r\n    do\r\n        if [ -f /var/run/snort_$IFACE.pid ]; then\r\n            if !  ps -p `cat /var/run/snort_$IFACE.pid` > /dev/null ; then\r\n                /usr/bin/logger -p user.notice snorthup: removing bogus pidfile\r\n                /usr/bin/\r\n    logger -p user.notice snorthup: restarting absentee snort o\r\n    n $IFACE with conf file $i\r\n                rm -f /var/run/snort_$IFACE.pid\r\n                /usr/local/bin/snort -D -c $conf -i $IFACE\r\n            fi;\r\n       else\r\n           /usr/bin/\r\n    logger -p user.notice snorthup: restarting snort on $IFACE with \r\n    conf file $conf\r\n           /usr/local/bin/snort -D -c $conf -i $IFACE \r\n       fi \r\n    done\r\n\\end{verbatim}\r\nAnother version:\r\n\\begin{verbatim}\r\n  * []#!/bin/ksh\r\n    # snortstartd: Snort (Re)Starter\r\n    # Dom De Vitto (dom@devitto..com)\r\n    # (original idea by dr@kyx..net & kmaxwell@superpages.com)\r\n    #\r\n    # Note: You'd better get CONF and INTERFACES right or\r\n    # this script will just keep trying to start snort.\r\n    # Path to echo, sed, test, ps, grep, logger, rm, and sleep.\r\n\r\n    PATH=$PATH:/usr/bin:/usr/local/bin ; export PATH\r\n    \r\n    # Point this to your conf file:\r\n    \r\n    CONF=\"/usr/local/share/examples/snort/snort.conf\"\r\n\r\n    # Which interfaces should Snort run on, e.g.:\r\n\r\n    INTERFACES=\"hme0 hme1\"\r\n\r\n    # Wait this many seconds between checks:\r\n\r\n    CHECKEVERY=5\r\n\r\n    # Full path to Snort:\r\n\r\n    SNORTBINARY=/usr/local/bin/snort\r\n\r\n    while :; do\r\n      for INT in $INTERFACES\r\n      do\r\n        GREPSTRING=\"`echo $SNORTBINARY -N -D -c $CONF -i $INT|sed\r\n    's?\\/?\\\\\\/?g'`\"\r\n        PSCMDLINES=`(ps augxww 2>/dev/null||ps -ef 2>/dev/null) | grep\r\n    \"$GREPSTRING\"|wc -l`\r\n        if [ $PSCMDLINES = 0 ]; then\r\n          logger -p user.notice -t \"$0\" \"Starting Snort on $INT.\"\r\n          $SNORTBINARY -N -D -c $CONF -i $INT 2>&1 > /dev/null\r\n        fi\r\n      done\r\n      sleep $CHECKEVERY\r\n    done\r\n\\end{verbatim}\r\n\r\n\\subsection{Why can't snort see one of the 10Mbps or 100Mbps traffic on my autoswitch hub?}\r\n\r\nBasically it's a function of the design and all autoswitching hubs will \r\nbehave in this way.  It's the result of just not being able to stuff all \r\nthe 100 Mbps traffic into the 10Mbps CSMA/CD.  One solution I use to the \r\nproblem is these new cheapie four port switches... put all the 10Mbps on \r\nit's own hub/switch/whatever and then route that to the 100Mbps hub I use \r\nfor monitoring but put a cheapie switch in between that works as an \r\nadapter basically mediating the 10 up to 100 and vice versa.\r\n\r\n\r\nThe bad thing about hubs that {\\em don't} have this ``feature,'' is that\r\nin order to support 10bt devices, they throttle the entire hub speed\r\ndown to 10bt if there is one or more 10bt only devices hooked up to it.\r\nI have seen this behavior (and did the bandwidth tests to prove it) on\r\nold 3com office connect 10/100 hubs (newer ones do the 2 hubs with a switch\r\nthing.)  So, the point of what I am saying is, since these old hubs have\r\nno switching capabilities, and they don't know which port the traffic is\r\nsupposed to go to (no switch=no arp table), they have to throttle bandwidth.\r\n\r\nNone of the hubs and switches have any significant amount of storage\r\non the ethernet chip sets, and therefore {\\em any} non-layer-three box that\r\nhas 100 $->$ 10 capability can only handle small amounts of traffic before\r\nthe chip set drops incoming packets on the floor. Guess one might call\r\nthat throttled bandwidth, but at the expense of retransmission timeouts\r\nand retransmissions at the end nodes.\r\n\r\nIf the box has a backplane, multiple cards and some network management\r\nfunctions, there is a higher {\\em probability} the manufacturer has some\r\nadditional buffering going on to keep dropped packets from happening\r\non at least small bursts of traffic.\r\n\r\nIn the most generic of terms, if a box supports 100 ``full-duplex,'' then\r\nits a switch (regardless of what the manufacturer calls it). If it\r\nsupports 100 $->$ 10, there is 50-50 chance the box has some MAC address\r\nawareness. If a box only supports 10 $->$ 10 or 100 $->$ 100, there is a\r\nhigh probability it is not MAC address aware and therefore functions\r\nlike a hub.\r\n\r\nMany hubs have different back planes, i.e., one for 10 and one for 100.\r\n\r\n>From a definition standpoint, a hub segment whether it be 10 or 100 is\r\na single broadcast/collision domain.  You will not see ANY traffic\r\nbetween segements without a bridge or layer3 route function between\r\nthem.\r\n  \r\nIn a switched environment, typically each port is a separate collision\r\ndomain but one big broadcast domain.  VLANs can be created in some to\r\nseparate into separate broadcast domains and some have built in layer\r\n3 functionality which basically connects a router into the backplane\r\nso that it can route between vlans at wire speed.\r\n  \r\nThink of a switch as a bridge with many ports.  (that's what it is).\r\nSome switches support port mirroring or span ports.  When you want to\r\n``sniff'' frames in a switched environment (beyond just\r\nbroadcast/multicast traffic) you need to be able to \"see\" the unicast\r\ntraffic (telnet,http for example).  You set up a port to mirror\r\ntraffic from the ports that have the devices your interested in to the\r\nport you have your analysis device plugged into.  Without doing so,\r\nyou don't see the unicast conversations because the traffic is getting\r\n\"switched\" across the backplane so pc on port 1 talks to server on\r\nport 2 and no other ports get this traffic. If server on port 2\r\nbroadcasts or multicasts, the information is flooded out all ports.\r\n(multicast can be controlled on some switches so only those ports that\r\nhave listening stations get the traffic.  Not all switches have these\r\ncapabilities.\r\n  \r\nAn excellent book on the topic is Interconnections by Radia Perlman.\r\n(Bridges and Routers).\r\n  \r\nAdditional caveat: if you deal with full duplex on a switched port,\r\nonly a tap would save you - users have successfully used Shomiti's\r\nones on 100MB FD ports, and used two Snort instances, capturing\r\ntraffic on both directions. Port mirroring didn't work in that case ...\r\n\r\n\\subsection{Trying to install snort it says: ``bad interpreter: No such file or\r\ndirectory''}\r\n\r\nUsually this error comes from editing files on Windows machines. Often it shows\r\nup on the ./configure step. The configure script should be looking for the /bin\r\n/sh shell as its interpreter. If /bin/sh doesn't exist then you'll get this\r\nerror. Check that whatever comes after the \\#! on the first line of configure is\r\nactually there.\r\n\r\nIf the file has been edited on a Windows machine it can sometimes Add CR/LF\r\n(VM) characters on the end of each line, so \\#!/bin/sh becomes \\#!/bin/shVM and\r\nas the ctrl-v/ctrl-m characters are special, and hidden by default on most\r\neditors, it can create a really hard to find problem. To remove the extra CR\r\ncharacters that UNIXish machines don't like, simply use the dos2unix command:\r\n\\begin{verbatim}\r\n  * []dos2unix <infile> <outfile>\r\n\\end{verbatim}\r\nIf your OS doesn't have dos2unix, then you can use:\r\n\\begin{verbatim}\r\n  * []cat <infile> | tr -d ``\\r'' > <outfile>\r\n\\end{verbatim}\r\n\r\n\\subsection{I'm not seeing any interfaces listed under Win32.}\r\n\r\nThe reason you're seeing nothing in the interface list is a WinPcap problem. In\r\nprevious versions of WinPcap there is a 1K buffer, which overflows if you have\r\nmany interfaces (i.e., 10+). This has been replaced with an 8K buffer in more\r\nrecent versions of WinPcap. The current snort distribution should already be\r\nlinking against the newer WinPcap libraries, which should resolve this problem.\r\nTry obtaining a more recent build of snort.\r\n\r\n\\subsection{It's not working on Win32, how can I tell if my problem is Snort or\r\nWinPcap?}\r\n\r\nSee if WinDump will work with WinPcap. This should help you isolate which\r\ncomponent is being bogus.\r\n\r\n\\subsection{I just downloaded a new ruleset and now Snort fails, complaining about the\r\nrules.}\r\n\r\nFirst, make sure you downloaded the right ruleset for your version of snort.\r\nSnort.org generally hosts a ruleset for the released version of Snort, as well\r\nas rules for the development branch and sometimes copies for older versions of\r\nsnort. This is generally the case for ``unknown keyword in rule'' type errors.\r\n\r\nIf you have the rules that are correct for your version of snort be aware that\r\nthe snort rules tarball contains a snort.conf file. From time to time the\r\nsnort.conf included with the rules gets changed as new .rules files are added,\r\nand new variables are added to support a better ruleset. When downloading new\r\nrulesets you should always give the included snort.conf a quick look-over to\r\nsee if new includes or vars have been added, or at least be aware you should\r\nconsult it if things do not work as expected. This is generally the case if you\r\nget messages indicating that something is undefined in a rule.\r\n\r\n\\subsection{Why am I seeing so many ``SMTP RCPT TO overflow'' alerts ?}\r\n\r\nThat rule looks for a TCP frame going to your SMTP server which contains more\r\nthan 800 bytes of data. Any email can easily set that off if pipelining is\r\nused. SMTP command pipelining allows several command lines lines to be sent as\r\na single packet without waiting for an OK response. Any good high-volume\r\nmailserver will try to pipeline where possible, resulting in a single TCP frame\r\ncontaining a series of command lines, each of which is not very long, but in\r\naggregate easily exceed the 800 byte threshold, particularly if there is a\r\nlarge recipient list.\r\n\r\nFor more info on pipelining:\r\n\r\n    \\htmladdnormallink{http://www.faqs.org/rfcs/rfc1854.html}{http://www.faqs.org/rfcs/rfc1854.html}\r\n\r\nIf your mailservers are not vulnerable to these overflows you can disable this\r\nrule and regain some peace...\r\n\r\n\\subsection{I'm getting lots of *ICMP Ping Speedera*, is this bad?}\r\n\r\nQuite ordinary. Windows update uses speedera based DNS, among other things. Of\r\ncourse, if the speedera traffic is coming from a Dialup account (as there have\r\nbeen reports of) it's likely a hacker tool. ;-)\r\n\r\n\\subsection{Why are my unified alert times off by +/- N hours?}\r\n\r\nUnified log and alert files are stored in UTC.\r\n\r\n\\subsection{I try to start Snort and it gives an error like ``ERROR: Unable to open\r\nrules file: /root/.snortrc or /root//root/.snortrc.'' What can I do to fix this?}\r\n\r\nWhen Snort starts, it looks at the command line and checks for ``-c /some/path/\r\nsnort.conf.'' If thats not there, then it will look for the one of the following\r\nfiles:\r\n\r\n\\begin{itemize}\r\n  \\item /etc/snort.conf\r\n  \\item ./snort.conf\r\n  \\item \\$HOMEDIR/snort.conf\r\n  \\item \\$HOMEDIR/.snortrc\r\n  \\item ./.snortrc\r\n\\end{itemize}\r\n\r\nMake sure your .conf is in one of those locations and then Snort will be able\r\nto find it or use the -c parameter to tell Snort the full pathname to the\r\nsnort.conf.\r\n\\begin{verbatim}\r\n    snort -c /usr/local/etc/snort.conf\r\n\\end{verbatim}\r\n\r\n\\subsection{Snort fails to respond to a kill signal on Linux.  Why?}\r\n\r\nIn Snort 2.6, a change was made to switch from performing the Snort\r\nshutdown function within the signal handlers.  This was done to remove\r\nreentrant code from the signal handlers, and the vulnerabilities that\r\nentailed.  The signal handler now simply sets a flag and returns.\r\n\r\nSnort now uses pcap\\_dispatch() with a read timeout value.  So, when a\r\nsignal is received when snort is waiting for packets, the signal handler\r\nsets the flag and goes back to waiting for a packet.  If the timeout\r\nis then reached, pcap\\_dispatch() returns and Snort sees it received a\r\nsignal to exit and exits cleanly.\r\n\r\nPer the pcap(3) man page, ``Not all platforms support a read timeout;\r\non platforms that don't, the read timeout is ignored.''  Linux is one\r\nof the systems where this is not currently supported.\r\n\r\nSnort does receive the signal, but until a packet arrives, it does\r\nnot get the chance to exit cleanly.  There have been a number of\r\npatches created to implement the timeout on linux, and one example\r\ncan be found here.\r\n\r\n\\htmladdnormallink{http://www.ethereal.com/lists/ethereal-dev/199812/msg00019.html}{http://www.ethereal.com/lists/ethereal-dev/199812/msg00019.html}\r\n\r\n\\subsection{A Rule with PCRE causes a failure to load snort.conf.  Why?}\r\n\r\nNewer Snort rules are using PCRE named expressions (also known as\r\nnamed captures).  PCRE only supports this with versions 4.0 and\r\nlater, and if an earlier version of libpcre is being used, Snort will\r\nprint the following error at startup.\r\n\r\n\\begin{verbatim}\r\nunrecognized character after (?\r\nFatal Error, Quitting..\r\n\\end{verbatim}\r\n\r\nA rule that may cause this problem is shown.\r\n\r\n\\begin{verbatim}\r\nalert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:\"WEB-CLIENT Microsoft\r\nAgent v1.5 ActiveX clsid access\"; flow:established,to_client;\r\ncontent:\"F5BE8BD2-7DE6-11D0-91FE-00C04FD701A5\"; nocase;\r\npcre:\"/<object\\s*[^>]*\\s*classid\\s*=\\s*(?P<q1>\\x22|\\x27|)\\s*clsid\\s*\\x3a\\s*\r\n{?\\s*F5BE8BD2-7DE6-11D0-91FE-00C04FD701A5\\s*}?\\s*(?P=q1)(\\s|>)/si\";\r\nreference:cve,2005-1214; reference:cve,2006-3445; reference:cve,2007-1205;\r\nreference:url,www.microsoft.com/technet/security/bulletin/MS05-032.mspx;\r\nreference:url,www.microsoft.com/technet/security/bulletin/MS06-068.mspx;\r\nreference:url,www.microsoft.com/technet/security/bulletin/MS07-020.mspx;\r\nclasstype:attempted-user; sid:4172; rev:3;)\r\n\\end{verbatim}\r\n\r\nAs of Snort 2.7.0, the minimum version of libpcre is 4.0.  Because of\r\nvarious performance improvements and bug fixes within libpcre, it is\r\nrecommended that Snort be compiled with libpcre version 7.0 or later.\r\nVisit \\htmladdnormallink{http://www.pcre.org}{http://www.pcre.org} for\r\ndetails.\r\n\r\n\\section{Development}   \r\n  \r\n\r\n\\subsection{How do you put Snort in debug mode? }\r\n\r\nIn Snort 1.9 or higher,\r\n\r\n\\begin{enumerate}\r\n\r\n\\item ./configure --enable-debug\r\n\r\n\\item Look up the sections of Snort you'd like to debug ( look at src/snort\\_debug.h )\r\nand bitwise-or the flags together to create a hex value. \r\n\r\nFor example, \r\n\\begin{verbatim}\r\n#define DEBUG_PARSER            0x00000002\r\n...\r\n#define DEBUG_PATTERN_MATCH     0x00001000\r\n\\end{verbatim}\r\n\r\nTo debug just the parser:\r\n\\begin{verbatim}\r\nexport SNORT_DEBUG=0x2\r\n\\end{verbatim}\r\n\r\nTo debug both the parser and pattern matcher:\r\n\\begin{verbatim}\r\nexport SNORT_DEBUG=0x1002\r\n\\end{verbatim}\r\n\r\nDebugging preprocessors is similar, eg to debug frag3:\r\n\\begin{verbatim}\r\nexport SNORT_PP_DEBUG=0x1\r\n\\end{verbatim}\r\n\r\n\\item Run snort as normal.  You will need to redirect output to a file\r\n   to cope with the large amounts of debug output.\r\n\\end{enumerate}\r\n\r\n\\section{Miscellaneous}\r\n\\subsection{What's this about a Snort drinking game?}\r\n\r\n:-) Check it out for yourself:\r\n  \\htmladdnormallink{http://www.theadamsfamily.net/~erek/snort/drinking\\_game.txt}{http://www.theadamsfamily.net/~erek/snort/drinking_game.txt}\r\n\r\n\r\n%\\begin{thebibliography}\r\n%\\bibitem[cite74]\r\n%\\end{thebibliography}\r\n\r\n\\end{document}\r\n\r\n\r\n"
  },
  {
    "path": "Units/roundtrip-escapes.d/expected.tags",
    "content": "_\\\\_\tinput\t//\n_\\a_\tinput\t//\n_\\b_\tinput\t//\n_\\f_\tinput\t//\n_\\n_\tinput\t//\n\\n\tinput\t//\n_\\r_\tinput\t//\n\\r\tinput\t//\n_\\t_\tinput\t//\n_\\v_\tinput\t//\n_\\x01_\tinput\t//\n_\\x02_\tinput\t//\n_\\x03_\tinput\t//\n_\\x04_\tinput\t//\n_\\x05_\tinput\t//\n_\\x06_\tinput\t//\n_\\x07_\tinput\t//\n_\\x08_\tinput\t//\n_\\x09_\tinput\t//\n_\\x0A_\tinput\t//\n_\\x0b_\tinput\t//\n_\\x0c_\tinput\t//\n_\\x0d_\tinput\t//\n_\\x0e_\tinput\t//\n_\\x0f_\tinput\t//\n_\\x10_\tinput\t//\n_\\x11_\tinput\t//\n_\\x12_\tinput\t//\n_\\x13_\tinput\t//\n_\\x14_\tinput\t//\n_\\x15_\tinput\t//\n_\\x16_\tinput\t//\n_\\x17_\tinput\t//\n_\\x18_\tinput\t//\n_\\x19_\tinput\t//\n_\\x1a_\tinput\t//\n_\\x1b_\tinput\t//\n_\\x1c_\tinput\t//\n_\\x1d_\tinput\t//\n_\\x1e_\tinput\t//\n_\\x1F_\tinput\t//\n_\\x20_\tinput\t//\n_\\x21_\tinput\t//\n"
  },
  {
    "path": "Units/roundtrip-escapes.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/simple-PythonEntryPoints.d/args.ctags",
    "content": "--sort=no\n--map-PythonEntryPoints=+.pythonentrypoints\n--fields=+lKzZr\n--extras=+{subparser}r\n"
  },
  {
    "path": "Units/simple-PythonEntryPoints.d/expected.tags",
    "content": "console_scripts\tinput.pythonentrypoints\t/^[console_scripts]$/;\"\tkind:section\tlanguage:Iniconf\troles:def\nhachoir-grep\tinput.pythonentrypoints\t/^hachoir-grep = hachoir.grep:main$/;\"\tkind:key\tlanguage:Iniconf\tscope:section:console_scripts\troles:def\nhachoir-grep\tinput.pythonentrypoints\t/^hachoir-grep = hachoir.grep:main$/;\"\tkind:console\tlanguage:PythonEntryPoints\troles:def\nhachoir.grep\tinput.pythonentrypoints\t/^hachoir-grep = hachoir.grep:main$/;\"\tkind:module\tlanguage:Python\troles:entryPoint\nmain\tinput.pythonentrypoints\t/^hachoir-grep = hachoir.grep:main$/;\"\tkind:function\tlanguage:Python\tscope:module:hachoir.grep\troles:entryPoint\nhachoir-metadata\tinput.pythonentrypoints\t/^hachoir-metadata = hachoir.metadata.main:main$/;\"\tkind:key\tlanguage:Iniconf\tscope:section:console_scripts\troles:def\nhachoir-metadata\tinput.pythonentrypoints\t/^hachoir-metadata = hachoir.metadata.main:main$/;\"\tkind:console\tlanguage:PythonEntryPoints\troles:def\nhachoir.metadata.main\tinput.pythonentrypoints\t/^hachoir-metadata = hachoir.metadata.main:main$/;\"\tkind:module\tlanguage:Python\troles:entryPoint\nmain\tinput.pythonentrypoints\t/^hachoir-metadata = hachoir.metadata.main:main$/;\"\tkind:function\tlanguage:Python\tscope:module:hachoir.metadata.main\troles:entryPoint\nhachoir-strip\tinput.pythonentrypoints\t/^hachoir-strip = hachoir.strip:main$/;\"\tkind:key\tlanguage:Iniconf\tscope:section:console_scripts\troles:def\nhachoir-strip\tinput.pythonentrypoints\t/^hachoir-strip = hachoir.strip:main$/;\"\tkind:console\tlanguage:PythonEntryPoints\troles:def\nhachoir.strip\tinput.pythonentrypoints\t/^hachoir-strip = hachoir.strip:main$/;\"\tkind:module\tlanguage:Python\troles:entryPoint\nmain\tinput.pythonentrypoints\t/^hachoir-strip = hachoir.strip:main$/;\"\tkind:function\tlanguage:Python\tscope:module:hachoir.strip\troles:entryPoint\nhachoir-urwid\tinput.pythonentrypoints\t/^hachoir-urwid = hachoir.urwid:main$/;\"\tkind:key\tlanguage:Iniconf\tscope:section:console_scripts\troles:def\nhachoir-urwid\tinput.pythonentrypoints\t/^hachoir-urwid = hachoir.urwid:main$/;\"\tkind:console\tlanguage:PythonEntryPoints\troles:def\nhachoir.urwid\tinput.pythonentrypoints\t/^hachoir-urwid = hachoir.urwid:main$/;\"\tkind:module\tlanguage:Python\troles:entryPoint\nmain\tinput.pythonentrypoints\t/^hachoir-urwid = hachoir.urwid:main$/;\"\tkind:function\tlanguage:Python\tscope:module:hachoir.urwid\troles:entryPoint\nextra0\tinput.pythonentrypoints\t/^extra0 = a.b.c$/;\"\tkind:key\tlanguage:Iniconf\tscope:section:console_scripts\troles:def\nextra0\tinput.pythonentrypoints\t/^extra0 = a.b.c$/;\"\tkind:console\tlanguage:PythonEntryPoints\troles:def\na.b.c\tinput.pythonentrypoints\t/^extra0 = a.b.c$/;\"\tkind:module\tlanguage:Python\troles:entryPoint\nbroken\tinput.pythonentrypoints\t/^broken =$/;\"\tkind:key\tlanguage:Iniconf\tscope:section:console_scripts\troles:def\nbroken\tinput.pythonentrypoints\t/^broken =$/;\"\tkind:console\tlanguage:PythonEntryPoints\troles:def\ngui_scripts\tinput.pythonentrypoints\t/^[gui_scripts]$/;\"\tkind:section\tlanguage:Iniconf\troles:def\nhachoir-wx\tinput.pythonentrypoints\t/^hachoir-wx = hachoir.wx.main:main$/;\"\tkind:key\tlanguage:Iniconf\tscope:section:gui_scripts\troles:def\nhachoir-wx\tinput.pythonentrypoints\t/^hachoir-wx = hachoir.wx.main:main$/;\"\tkind:gui\tlanguage:PythonEntryPoints\troles:def\nhachoir.wx.main\tinput.pythonentrypoints\t/^hachoir-wx = hachoir.wx.main:main$/;\"\tkind:module\tlanguage:Python\troles:entryPoint\nmain\tinput.pythonentrypoints\t/^hachoir-wx = hachoir.wx.main:main$/;\"\tkind:function\tlanguage:Python\tscope:module:hachoir.wx.main\troles:entryPoint\n"
  },
  {
    "path": "Units/simple-PythonEntryPoints.d/input.pythonentrypoints",
    "content": "# Taken from hachoir-3.3.0.dist-info/entry_points.txt\n[console_scripts]\nhachoir-grep = hachoir.grep:main\nhachoir-metadata = hachoir.metadata.main:main\nhachoir-strip = hachoir.strip:main\nhachoir-urwid = hachoir.urwid:main\n\nextra0 = a.b.c\nbroken =\n\n[gui_scripts]\nhachoir-wx = hachoir.wx.main:main\n"
  },
  {
    "path": "Units/simple-abaqus.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/simple-abaqus.d/expected.tags",
    "content": "Part-1\tinput.inp\t/^*Part, name=Part-1$/;\"\tp\nAssembly\tinput.inp\t/^*Assembly, name=Assembly$/;\"\ta\nStep-1\tinput.inp\t/^*Step, name=Step-1$/;\"\ts\n"
  },
  {
    "path": "Units/simple-abaqus.d/input.inp",
    "content": "**\n**    Simple input file demonstrating user material in ABAQUS\n**\n**    This input file was created with ABAQUS/CAE, and then edited\n**    to insert the additional commands associated with user material.\n**\n**    You can run the code with\n**     abaqus job=user_element, user=Usermat.for\n**\n*Heading\n** Job name: Job-1 Model name: Model-1\n*Preprint, echo=NO, model=NO, history=NO, contact=NO\n**\n** PARTS\n**\n*Part, name=Part-1\n*End Part\n**  \n**\n** ASSEMBLY\n**\n*Assembly, name=Assembly\n**  \n*Instance, name=Part-1-1, part=Part-1\n*Node\n      1,           0.,           0.\n      2,          2.5,           0.\n      3,           0.,          2.5\n      4,          2.5,          2.5\n**\n** NOTE - if you use reduced integration elements\n** with a UMAT, you have to define the hourglass\n** stiffness for the element\n**\n*Element, type=CPE4R\n1, 1, 2, 4, 3\n*Nset, nset=_PickedSet2, internal, generate\n 1,  4,  1\n*Elset, elset=_PickedSet2, internal\n 1,\n** Region: (Section-1:Picked)\n*Elset, elset=_PickedSet2, internal\n 1,\n** Section: Section-1\n** THE LINE BELOW WAS EDITED TO ASSIGN THE USER MATERIAL\n*Solid Section, elset=_PickedSet2, material=usermat_elastic\n1.,\n*hourglass stiffness\n0.1\n*End Instance\n**  \n*Nset, nset=_PickedSet4, internal, instance=Part-1-1\n 1, 2\n*Elset, elset=_PickedSet4, internal, instance=Part-1-1\n 1,\n*Nset, nset=_PickedSet5, internal, instance=Part-1-1\n 1, 3\n*Elset, elset=_PickedSet5, internal, instance=Part-1-1\n 1,\n*Nset, nset=_PickedSet6, internal, instance=Part-1-1\n 3, 4\n*Elset, elset=_PickedSet6, internal, instance=Part-1-1\n 1,\n*End Assembly\n** \n** MATERIALS\n**\n**  THE LINES BELOW WERE EDITED TO DEFINE THE USER MATERIAL \n*Material, name=usermat_elastic\n*user material, constants=2, type=mechanical\n 1000.0, 0.3\n** This defines the number of state variables (none in this case)\n*DEPVAR\n1\n** ----------------------------------------------------------------\n** \n** STEP: Step-1\n** \n*Step, name=Step-1\n*Static\n0.1, 1., 1e-05, 1.\n** \n** BOUNDARY CONDITIONS\n** \n** Name: BC-1 Type: Displacement/Rotation\n*Boundary\n_PickedSet4, 2, 2\n** Name: BC-2 Type: Displacement/Rotation\n*Boundary\n_PickedSet5, 1, 1\n** Name: BC-3 Type: Displacement/Rotation\n*Boundary\n_PickedSet6, 2, 2, 0.1\n** \n** OUTPUT REQUESTS\n** \n*Restart, write, frequency=0\n** \n** FIELD OUTPUT: F-Output-1\n** \n*Output, field, variable=PRESELECT\n** \n** HISTORY OUTPUT: H-Output-1\n** \n*Output, history, variable=PRESELECT\n*End Step"
  },
  {
    "path": "Units/simple-abc.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/simple-abc.d/expected.tags",
    "content": "X:0001 / T:The Ranting Highlandman.\tinput.abc\t/^T:The Ranting Highlandman.$/;\"\ts\nX:0001 / T:The Ranting Highlandman. / T:The White Cockade\tinput.abc\t/^T:The White Cockade$/;\"\ts\nX:0002 / T:Quick Step. 25th Regt.\tinput.abc\t/^T:Quick Step. 25th Regt.$/;\"\ts\nX:0003 / T:The Lads of the Village.\tinput.abc\t/^T:The Lads of the Village.$/;\"\ts\nX:0004 / T:I'll Touzle your Kurchy.\tinput.abc\t/^T:I'll Touzle your Kurchy.$/;\"\ts\nX:0005 / T:The Lady's play thing, or Gen Howe's March.\tinput.abc\t/^T:The Lady's play thing, or Gen Howe's March.$/;\"\ts\n"
  },
  {
    "path": "Units/simple-abc.d/input.abc",
    "content": "% A Selection of Scotch, English, Irish and Foreign\n% Airs adapted to the Fife, Violin, or German-Flute\n% Glasgow\n% Printed and Sold by James Aird\n% Volume First\n% 1778 (often cited as 1782)\n\nX:0001\nT:The Ranting Highlandman.\nT:The White Cockade\nM:C|\nL:1/8\nQ:1/2=112\nI: :: ::\n%% G A B c d e ^f g a\nZ:Jack Campin * www.campin.me.uk * 2009\nK:G\nAG|B2B2 B2AG|B2B2 B2g2|B2B2 B2AG|AGAB A2\nGA|B2B2 cBAG|A2B2 g2fg|a2gf g2fe|d2B2 B2::\nBc|d2B2 g2B2|d2d2 d2e2|d2cB g2fg|a2A2 A2\nGA|B2B2 cBAG|A2B2 g2fg|a2gf g2fe|d2B2 B2:|\n\nX:0002\nT:Quick Step. 25th Regt.\nN:bars of quavers are all beamed together in the original\nM:2/4\nL:1/16\nQ:1/4=89\nI: :: ::\n%% D ^F G A B c d e f ^f g a\nZ:Jack Campin * www.campin.me.uk * 2009\nK:G\ng2d2 d2c2|(BcdB) G2D2 |G2B2 (ABcd)| B2``G2  G2d2|\ne2c2 c2e2| d2B2  B2d2 |g2d2  c2B2 | B4      A4 :|\nF2A2 A2dc| B2G2  G4   |B2d2  d2=f2|(ed)(cB) c4  |\ne2a2 a2g2|(gfed) g2c2 |B2AG  A2D2 | G2``G2  G4 :|\n\nX:0003\nT:The Lads of the Village.\nM:2/4\nL:1/8\nQ:1/4=104\nI: :: ::\n%% D ^F G A B c d e ^f g a\nZ:Jack Campin * www.campin.me.uk * 2009\nK:G\nG2g>d|ecBG|a>cBG|FA`FD|G2 gd|ecBG|A>cBG|(D/G/``F/A/) G2:|\ng>fgd|ecBG|g>fge|a>gfd|g>fgd|ecBG|A>cBG|(D/G/)(F/A/) G2:|\n\nX:0004\nT:I'll Touzle your Kurchy.\nM:6/8\nL:1/8\nQ:3/8=120\nI: :: ::\n%% D  E  ^F  G  A  B  c  d  e  ^f  g\nZ:Jack Campin * www.campin.me.uk * 2009\nK:E Minor\nB   |E>GE GEG|B>AB e2f|g>fe dgB|A>GA BG\nE   |E>GE GEG|B>AB e2f|g>fe dcB|AGF  E2:|\nB   |E>GE B2B|GEG  B2B|E>GE A2G|FDF  A2\nG/F/|E>GE B2B|GEG  e2f|gfe  dcB|AGF  E2:|\n\nX:0005\nT:The Lady's play thing, or Gen Howe's March.\nM:6/8\nL:1/8\nQ:3/8=120\nI: :: ::\n%% D  G  A  B  c  d  e  g\nN:last note printed as G3\nZ:Jack Campin * www.campin.me.uk * 2009\nK:G\nd/c/|B2B Bcd|A2A A2d|G2G GAB|B3  A2\ne   |dgd BdB|GBG Ddc|BcB AGA|G2G G2:|\nd   |dBd dBd|e2e e2c|cAc cAc|d2d d2\nc   |BGB BGB|c2c cBA|Bcd dcB|B3  A2\ne   |dgd BdB|GBG Ddc|BcB AGA|G2G G2:|\n"
  },
  {
    "path": "Units/simple-ctags.d/expected.tags",
    "content": "class\tinput.ctags\t/^--regex-coffee=\\/^[ \\\\t]*class ([a-zA-Z_$][0-9a-zA-Z_.$]*).*$\\/\\\\1\\/c,class\\/$/;\"\tk\tlangdef:coffee\ncoffee\tinput.ctags\t/^--langdef=coffee$/;\"\tl\nfunction\tinput.ctags\t/^--regex-coffee=\\/^[ \\\\t]*([a-zA-Z_$@][0-9a-zA-Z_$\\\\.]*)[ \\\\t]*[:=].*[=-]>.*$\\/\\\\1\\/f,function\\/$/;\"\tk\tlangdef:coffee\nvariable\tinput.ctags\t/^--kinddef-coffee=v,variable,variables$/;\"\tk\tlangdef:coffee\n"
  },
  {
    "path": "Units/simple-ctags.d/features",
    "content": "regex\n"
  },
  {
    "path": "Units/simple-ctags.d/input.ctags",
    "content": "#\n# Taken from https://github.com/fishman/dot_files/blob/master/ctags/.ctags\n#\n--langdef=coffee\n--langmap=coffee:.coffee\n--kinddef-coffee=v,variable,variables\n--regex-coffee=/^[ \\t]*class ([a-zA-Z_$][0-9a-zA-Z_.$]*).*$/\\1/c,class/\n--regex-coffee=/^[ \\t]*([a-zA-Z_$@][0-9a-zA-Z_$\\.]*)[ \\t]*[:=].*[=-]>.*$/\\1/f,function/\n--regex-coffee=/^[ \\t]*([a-zA-Z_$@][0-9a-zA-Z_$\\.]*)[ \\t]*=[^->\\n]*$/\\1/v/\n"
  },
  {
    "path": "Units/simple-diff.d/expected.tags",
    "content": "-0,0 +1,134\tinput.diff\t/^@@ -0,0 +1,134 @@$/;\"\th\tnewFile:b/parsers/diff.c\n-1,2 +0,0\tinput.diff\t/^@@ -1,2 +0,0 @@$/;\"\th\tdeletedFile:a/Units/review-needed.r/simple.ksh.t/expected.tags\n-28,6 +28,7\tinput.diff\t/^@@ -28,6 +28,7 @@$/;\"\th\tmodifiedFile:a/main/parsers.h\n-44,6 +44,7\tinput.diff\t/^@@ -44,6 +44,7 @@ PARSER_SOURCES =\t\t\t\t\\\\$/;\"\th\tmodifiedFile:a/source.mak\na/Units/review-needed.r/simple.ksh.t/expected.tags\tinput.diff\t/^--- a\\/Units\\/review-needed.r\\/simple.ksh.t\\/expected.tags$/;\"\td\na/main/parsers.h\tinput.diff\t/^--- a\\/main\\/parsers.h$/;\"\tm\na/source.mak\tinput.diff\t/^--- a\\/source.mak$/;\"\tm\nb/parsers/diff.c\tinput.diff\t/^+++ b\\/parsers\\/diff.c$/;\"\tn\n"
  },
  {
    "path": "Units/simple-diff.d/input.diff",
    "content": "diff --git a/main/parsers.h b/main/parsers.h\nindex 8000fa0..5332052 100644\n--- a/main/parsers.h\n+++ b/main/parsers.h\n@@ -28,6 +28,7 @@\n \tCsharpParser, \\\n \tCobolParser, \\\n \tDParser, \\\n+\tDiffParser, \\\n \tDosBatchParser, \\\n \tEiffelParser, \\\n \tErlangParser, \\\ndiff --git a/parsers/diff.c b/parsers/diff.c\nnew file mode 100644\nindex 0000000..a1bf5f3\n--- /dev/null\n+++ b/parsers/diff.c\n@@ -0,0 +1,134 @@\n+/*\n+*\n+*   Copyright (c) 2000-2001, Darren Hiebert\n+*\n+*   This source code is released for free distribution under the terms of the\n+*   GNU General Public License.\n+*\n+*   This module contains functions for generating tags for diff files (based on Sh parser).\n+*/\n+\n+/*\n+*   INCLUDE FILES\n+*/\n+#include \"general.h\"\t/* must always come first */\n+\n+#include <ctype.h>\n+#include <string.h>\n+\n+#include \"parse.h\"\n+#include \"read.h\"\n+#include \"vstring.h\"\n+\n+/*\n+*   DATA DEFINITIONS\n+*/\n+typedef enum {\n+\tK_FUNCTION\n+} diffKind;\n+\n+static kindOption DiffKinds [] = {\n+\t{ TRUE, 'f', \"compared file\", \"compared files\"}\n+};\n+\n+enum {\n+\tDIFF_DELIM_MINUS = 0,\n+\tDIFF_DELIM_PLUS\n+};\n+\n+static const char *DiffDelims[2] = {\n+\t\"--- \",\n+\t\"+++ \"\n+};\n+\n+/*\n+*   FUNCTION DEFINITIONS\n+*/\n+\n+static const unsigned char *stripAbsolute (const unsigned char *filename)\n+{\n+\tconst unsigned char *tmp;\n+\n+\t/* strip any absolute path */\n+\tif (*filename == '/' || *filename == '\\\\')\n+\t{\n+\t\tboolean skipSlash = TRUE;\n+\n+\t\ttmp = (const unsigned char*) strrchr ((const char*) filename,  '/');\n+\t\tif (tmp == NULL)\n+\t\t{\t/* if no / is contained try \\ in case of a Windows filename */\n+\t\t\ttmp = (const unsigned char*) strrchr ((const char*) filename, '\\\\');\n+\t\t\tif (tmp == NULL)\n+\t\t\t{\t/* last fallback, probably the filename doesn't contain a path, so take it */\n+\t\t\t\ttmp = filename;\n+\t\t\t\tskipSlash = FALSE;\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* skip the leading slash or backslash */\n+\t\tif (skipSlash)\n+\t\t\ttmp++;\n+\t}\n+\telse\n+\t\ttmp = filename;\n+\n+\treturn tmp;\n+}\n+\n+static void findDiffTags (void)\n+{\n+\tvString *filename = vStringNew ();\n+\tconst unsigned char *line, *tmp;\n+\tint delim = DIFF_DELIM_MINUS;\n+\n+\twhile ((line = fileReadLine ()) != NULL)\n+\t{\n+\t\tconst unsigned char* cp = line;\n+\n+\t\tif (strncmp ((const char*) cp, DiffDelims[delim], 4u) == 0)\n+\t\t{\n+\t\t\tcp += 4;\n+\t\t\tif (isspace (*cp)) continue;\n+\t\t\t/* when original filename is /dev/null use the new one instead */\n+\t\t\tif (delim == DIFF_DELIM_MINUS &&\n+\t\t\t\tstrncmp ((const char*) cp, \"/dev/null\", 9u) == 0 &&\n+\t\t\t\t(cp[9] == 0 || isspace (cp[9])))\n+\t\t\t{\n+\t\t\t\tdelim = DIFF_DELIM_PLUS;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\ttmp = stripAbsolute (cp);\n+\n+\t\t\tif (tmp != NULL)\n+\t\t\t{\n+\t\t\t\twhile (! isspace(*tmp) && *tmp != '\\0')\n+\t\t\t\t{\n+\t\t\t\t\tvStringPut(filename, *tmp);\n+\t\t\t\t\ttmp++;\n+\t\t\t\t}\n+\n+\t\t\t\tvStringTerminate(filename);\n+\t\t\t\tmakeSimpleTag (filename, DiffKinds, K_FUNCTION);\n+\t\t\t\tvStringClear (filename);\n+\t\t\t}\n+\n+\t\t\t/* restore default delim */\n+\t\t\tdelim = DIFF_DELIM_MINUS;\n+\t\t}\n+\t}\n+\tvStringDelete (filename);\n+}\n+\n+extern parserDefinition* DiffParser (void)\n+{\n+\tstatic const char *const extensions [] = { \"diff\", \"patch\", NULL };\n+\tparserDefinition* const def = parserNew (\"Diff\");\n+\tdef->kinds      = DiffKinds;\n+\tdef->kindCount  = KIND_COUNT (DiffKinds);\n+\tdef->extensions = extensions;\n+\tdef->parser     = findDiffTags;\n+\treturn def;\n+}\n+\n+/* vi:set tabstop=8 shiftwidth=4: */\ndiff --git a/source.mak b/source.mak\nindex 2550028..eaa9154 100644\n--- a/source.mak\n+++ b/source.mak\n@@ -44,6 +44,7 @@ PARSER_SOURCES =\t\t\t\t\\\n \t$(PARSER_DIR)/clojure.c\t\t\t\\\n \t$(PARSER_DIR)/css.c\t\t\t\\\n \t$(PARSER_DIR)/cobol.c\t\t\t\\\n+\t$(PARSER_DIR)/diff.c\t\t\t\\\n \t$(PARSER_DIR)/dosbatch.c\t\t\\\n \t$(PARSER_DIR)/eiffel.c\t\t\t\\\n \t$(PARSER_DIR)/erlang.c\t\t\t\\\n\n--- a/Units/review-needed.r/simple.ksh.t/expected.tags\n+++ /dev/null\n@@ -1,2 +0,0 @@\n-f1     input.ksh       /^f1() {$/;\"    f\n-f2     input.ksh       /^function f2 {$/;\"     f\n"
  },
  {
    "path": "Units/simple-gdbinit.d/args.ctags",
    "content": "--kinds-gdbinit=*\n\n"
  },
  {
    "path": "Units/simple-gdbinit.d/expected.tags",
    "content": "ybuffer-contents\tinput.gdb\t/^define ybuffer-contents$/;\"\td\nybuffer-contents\tinput.gdb\t/^document ybuffer-contents$/;\"\tD\nyfile_buffers_only\tinput.gdb\t/^set $yfile_buffers_only = 0$/;\"\tt\nyverbose\tinput.gdb\t/^set $yverbose = 1$/;\"\tt\n"
  },
  {
    "path": "Units/simple-gdbinit.d/input.gdb",
    "content": "# Taken from /usr/share/emacs/24.5/etc/emacs-buffer.gdb\n\nset main\nset $yverbose = 1\nset $yfile_buffers_only = 0\n\ndefine ybuffer-contents\n  ydump-buffer $arg0 /dev/stdout\n  if $yverbose && $buf->z_byte <= 1\n    yget-current-buffer-name\n    printf \"[Buffer \\\"%s\\\" is empty.]\\n\", $ycurrent_buffer_name\n  else\n    if *($endptr-1) != '\\n'\n      echo \\n\n    end\n  end\nend\ndocument ybuffer-contents\n  Write contents of buffer N (numbered according to `ybuffer-list') to stdout.\nend\n"
  },
  {
    "path": "Units/simple-glade.d/args.ctags",
    "content": "--extras=+rf\n--fields=+rKnl\n--regex-Glade=/.*SYSTEM \"([^\"]*)\">/\\1/D,DOCTYPE/\n--sort=no\n--excmd=mixed\n"
  },
  {
    "path": "Units/simple-glade.d/expected.tags",
    "content": "http://glade.gnome.org/glade-2.0.dtd\tinput.glade\t/^<!DOCTYPE glade-interface SYSTEM \"http:\\/\\/glade.gnome.org\\/glade-2.0.dtd\">$/;\"\tDOCTYPE\tline:2\tlanguage:Glade\troles:def\nwindow1\tinput.glade\t/^<widget class=\"GtkWindow\" id=\"window1\">$/;\"\tid\tline:6\tlanguage:XML\troles:def\nbutton1\tinput.glade\t/^    <widget class=\"GtkButton\" id=\"button1\">$/;\"\tid\tline:23\tlanguage:XML\troles:def\nGtkWindow\tinput.glade\t/^<widget class=\"GtkWindow\" id=\"window1\">$/;\"\tclass\tline:6\tlanguage:Glade\troles:widget\nGtkButton\tinput.glade\t/^    <widget class=\"GtkButton\" id=\"button1\">$/;\"\tclass\tline:23\tlanguage:Glade\troles:widget\non_button1_clicked\tinput.glade\t/^      <signal name=\"clicked\" handler=\"on_button1_clicked\" last_modification_time=\"Sat, 26 Dec 20/;\"\thandler\tline:30\tlanguage:Glade\troles:handler\ninput.glade\tinput.glade\t1;\"\tfile\tline:1\tlanguage:Glade\troles:def\n"
  },
  {
    "path": "Units/simple-glade.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/simple-glade.d/input.glade",
    "content": "<?xml version=\"1.0\" standalone=\"no\"?> <!--*- mode: xml -*-->\n<!DOCTYPE glade-interface SYSTEM \"http://glade.gnome.org/glade-2.0.dtd\">\n\n<glade-interface>\n\n<widget class=\"GtkWindow\" id=\"window1\">\n  <property name=\"visible\">True</property>\n  <property name=\"title\" translatable=\"yes\">window1</property>\n  <property name=\"type\">GTK_WINDOW_TOPLEVEL</property>\n  <property name=\"window_position\">GTK_WIN_POS_NONE</property>\n  <property name=\"modal\">False</property>\n  <property name=\"resizable\">True</property>\n  <property name=\"destroy_with_parent\">False</property>\n  <property name=\"decorated\">True</property>\n  <property name=\"skip_taskbar_hint\">False</property>\n  <property name=\"skip_pager_hint\">False</property>\n  <property name=\"type_hint\">GDK_WINDOW_TYPE_HINT_NORMAL</property>\n  <property name=\"gravity\">GDK_GRAVITY_NORTH_WEST</property>\n  <property name=\"focus_on_map\">True</property>\n  <property name=\"urgency_hint\">False</property>\n\n  <child>\n    <widget class=\"GtkButton\" id=\"button1\">\n      <property name=\"visible\">True</property>\n      <property name=\"can_focus\">True</property>\n      <property name=\"label\" translatable=\"yes\">button1</property>\n      <property name=\"use_underline\">True</property>\n      <property name=\"relief\">GTK_RELIEF_NORMAL</property>\n      <property name=\"focus_on_click\">True</property>\n      <signal name=\"clicked\" handler=\"on_button1_clicked\" last_modification_time=\"Sat, 26 Dec 2015 09:22:46 GMT\"/>\n    </widget>\n  </child>\n</widget>\n\n</glade-interface>\n"
  },
  {
    "path": "Units/simple-gomod.d/README",
    "content": "The input.gomod is taken from https://github.com/netmute/ctags-lsp.git .\n"
  },
  {
    "path": "Units/simple-gomod.d/args.ctags",
    "content": "--sort=no\n--map-GoMod=+.gomod\n"
  },
  {
    "path": "Units/simple-gomod.d/expected.tags",
    "content": "github.com/netmute/ctags-lsp\tinput.gomod\t/^module github.com\\/netmute\\/ctags-lsp$/;\"\tm\n"
  },
  {
    "path": "Units/simple-gomod.d/input.gomod",
    "content": "module github.com/netmute/ctags-lsp\n\ngo 1.23.2\n"
  },
  {
    "path": "Units/simple-haxe.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/simple-haxe.d/expected.tags",
    "content": "Color\tinput.hx\t/^enum Color {$/;\"\te\nPrintable\tinput.hx\t/^interface Printable {$/;\"\ti\ntoString\tinput.hx\t/^    public function toString():String;$/;\"\tm\nUser\tinput.hx\t/^typedef User = {$/;\"\tt\nage\tinput.hx\t/^  var age : Int;$/;\"\tv\nname\tinput.hx\t/^  var name : String;$/;\"\tv\nMain\tinput.hx\t/^class Main {$/;\"\tc\nmember\tinput.hx\t/^  static var member:String = \"bar\";$/;\"\tv\nmain\tinput.hx\t/^  static public function main():Void {$/;\"\tm\n"
  },
  {
    "path": "Units/simple-haxe.d/input.hx",
    "content": "enum Color {\n  Red;\n  Green;\n  Blue;\n  Rgb(r:Int, g:Int, b:Int);\n}\n\ninterface Printable {\n    public function toString():String;\n}\n\ntypedef User = {\n  var age : Int;\n  var name : String;\n}\n\nclass Main {\n  static var member:String = \"bar\";\n\n  static public function main():Void {\n    trace(\"Hello World\");\n  }\n}"
  },
  {
    "path": "Units/simple-javaproperties.d/expected.tags",
    "content": "A\tinput.properties\t/^    A: B$/;\"\tk\nC\tinput.properties\t/^    C : D$/;\"\tk\nE\tinput.properties\t/^        E = F$/;\"\tk\nG\tinput.properties\t/^\tG H$/;\"\tk\nX\tinput.properties\t/^\tX$/;\"\tk\nY\tinput.properties\t/^Y/;\"\tk\nkey\\\\ with\\\\ spaces\tinput.properties\t/^key\\\\ with\\\\ spaces = This is the value that could be looked up with the key \"key with spaces\".$/;\"\tk\nlanguage\tinput.properties\t/^language = English$/;\"\tk\nmessage\tinput.properties\t/^message = Welcome to \\\\$/;\"\tk\ntab\tinput.properties\t/^tab : \\\\u0009$/;\"\tk\nwebsite\tinput.properties\t/^website = http\\\\:\\/\\/en.wikipedia.org\\/$/;\"\tk\n"
  },
  {
    "path": "Units/simple-javaproperties.d/input.properties",
    "content": "#\n# Based on the exaimple written in https://en.wikipedia.org/wiki/.properties\n#\n\n# You are reading the \".properties\" entry.\n! The exclamation mark can also mark text as comments.\n# The key and element characters #, !, =, and : are written with\n# a preceding backslash to ensure that they are properly loaded.\nwebsite = http\\://en.wikipedia.org/\nlanguage = English\n# The backslash below tells the application to continue reading\n# the value onto the next line.\nmessage = Welcome to \\\n          Wikipedia!\n# Add spaces to the key\nkey\\ with\\ spaces = This is the value that could be looked up with the key \"key with spaces\".\n# Unicode\ntab : \\u0009\n\n    A: B\n    C : D\n        E = F\n\tG H\n\tX\nY"
  },
  {
    "path": "Units/simple-maven2.d/args.ctags",
    "content": "--extras=+r\n--fields=+r\n--fields-all=+{version}\n"
  },
  {
    "path": "Units/simple-maven2.d/expected.tags",
    "content": "backend\tinput.xml\t/^  <artifactId>backend<\\/artifactId>$/;\"\ta\tgroupId:org.ovirt.engine.core\troles:def\ncentral\tinput.xml\t/^      <id>central<\\/id>$/;\"\tr\troles:def\ncommons-collections\tinput.xml\t/^      <artifactId>commons-collections<\\/artifactId>$/;\"\ta\tgroupId:commons-collections\troles:dependency\ncommons-collections\tinput.xml\t/^      <groupId>commons-collections<\\/groupId>$/;\"\tg\troles:dependency\nengine.groupId\tinput.xml\t/^    <engine.groupId>org.ovirt.engine.core<\\/engine.groupId>$/;\"\tp\troles:def\nns4b0d50740101\tinput.xml\t/^<project xmlns=\"http:\\/\\/maven.apache.org\\/POM\\/4.0.0\" xmlns:xsi=\"http:\\/\\/www.w3.org\\/2001\\/XML/;\"\tn\troles:def\turi:http://maven.apache.org/POM/4.0.0\norg.ovirt.engine\tinput.xml\t/^    <groupId>org.ovirt.engine<\\/groupId>$/;\"\tg\troles:parent\norg.ovirt.engine.api\tinput.xml\t/^      <groupId>org.ovirt.engine.api<\\/groupId>$/;\"\tg\troles:dependency\norg.ovirt.engine.core\tinput.xml\t/^  <groupId>org.ovirt.engine.core<\\/groupId>$/;\"\tg\troles:def\novirt-engine-extensions-api\tinput.xml\t/^      <artifactId>ovirt-engine-extensions-api<\\/artifactId>$/;\"\ta\tgroupId:org.ovirt.engine.api\troles:dependency\tversion:${org.ovirt.engine.api.ovirt-engine-extensions-api.version}\nroot\tinput.xml\t/^    <artifactId>root<\\/artifactId>$/;\"\ta\tgroupId:org.ovirt.engine\troles:parent\tversion:3.5.6.2\nxsi\tinput.xml\t/^<project xmlns=\"http:\\/\\/maven.apache.org\\/POM\\/4.0.0\" xmlns:xsi=\"http:\\/\\/www.w3.org\\/2001\\/XML/;\"\tn\troles:def\turi:http://www.w3.org/2001/XMLSchema-instance\n"
  },
  {
    "path": "Units/simple-maven2.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/simple-maven2.d/input.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n<!-- Taken from\n     rhevm-3.5.6.2-0.1.el6ev:ovirt-engine/backend/pom.xml -->\n  <modelVersion>4.0.0</modelVersion>\n\n  <parent>\n    <groupId>org.ovirt.engine</groupId>\n    <artifactId>root</artifactId>\n    <version>3.5.6.2</version>\n  </parent>\n\n  <artifactId>backend</artifactId>\n  <groupId>org.ovirt.engine.core</groupId>\n  <packaging>pom</packaging>\n\n  <name>oVirt Modules - backend</name>\n  <description>parent POM for all oVirt modules</description>\n\n  <modules>\n    <module>manager</module>\n  </modules>\n\n  <properties>\n    <engine.groupId>org.ovirt.engine.core</engine.groupId>\n  </properties>\n\n  <repositories>\n    <repository>\n      <id>central</id>\n      <name>maven repo1</name>\n      <layout>default</layout>\n      <url>http://repo1.maven.org/maven2</url>\n      <snapshots>\n        <enabled>false</enabled>\n      </snapshots>\n    </repository>\n  </repositories>\n\n  <dependencies>\n    <dependency>\n      <groupId>org.ovirt.engine.api</groupId>\n      <artifactId>ovirt-engine-extensions-api</artifactId>\n      <version>${org.ovirt.engine.api.ovirt-engine-extensions-api.version}</version>\n    </dependency>\n    <dependency>\n      <groupId>commons-collections</groupId>\n      <artifactId>commons-collections</artifactId>\n    </dependency>\n  </dependencies>\n</project>\n"
  },
  {
    "path": "Units/simple-meson-options.d/README",
    "content": "input.meson_options is taken from QEMU source tree.\n"
  },
  {
    "path": "Units/simple-meson-options.d/args.ctags",
    "content": "--sort=no\n--fields=+K\n--map-MesonOptions=+.meson_options\n\n"
  },
  {
    "path": "Units/simple-meson-options.d/expected.tags",
    "content": "qemu_suffix\tinput.meson_options\t/^option('qemu_suffix', type : 'string', value: 'qemu',$/;\"\tstring\ndocdir\tinput.meson_options\t/^option('docdir', type : 'string', value : 'doc',$/;\"\tstring\nqemu_firmwarepath\tinput.meson_options\t/^option('qemu_firmwarepath', type : 'string', value : '',$/;\"\tstring\nsphinx_build\tinput.meson_options\t/^option('sphinx_build', type : 'string', value : '',$/;\"\tstring\ndocs\tinput.meson_options\t/^option('docs', type : 'feature', value : 'auto',$/;\"\tfeature\ngettext\tinput.meson_options\t/^option('gettext', type : 'boolean', value : true,$/;\"\tboolean\ninstall_blobs\tinput.meson_options\t/^option('install_blobs', type : 'boolean', value : true,$/;\"\tboolean\nsparse\tinput.meson_options\t/^option('sparse', type : 'feature', value : 'auto',$/;\"\tfeature\nmalloc_trim\tinput.meson_options\t/^option('malloc_trim', type : 'feature', value : 'auto',$/;\"\tfeature\nmalloc\tinput.meson_options\t/^option('malloc', type : 'combo', choices : ['system', 'tcmalloc', 'jemalloc'],$/;\"\tcombo\nkvm\tinput.meson_options\t/^option('kvm', type: 'feature', value: 'auto',$/;\"\tfeature\nhax\tinput.meson_options\t/^option('hax', type: 'feature', value: 'auto',$/;\"\tfeature\nwhpx\tinput.meson_options\t/^option('whpx', type: 'feature', value: 'auto',$/;\"\tfeature\nhvf\tinput.meson_options\t/^option('hvf', type: 'feature', value: 'auto',$/;\"\tfeature\nxen\tinput.meson_options\t/^option('xen', type: 'feature', value: 'auto',$/;\"\tfeature\nxen_pci_passthrough\tinput.meson_options\t/^option('xen_pci_passthrough', type: 'feature', value: 'auto',$/;\"\tfeature\ntcg\tinput.meson_options\t/^option('tcg', type: 'feature', value: 'auto',$/;\"\tfeature\ncocoa\tinput.meson_options\t/^option('cocoa', type : 'feature', value : 'auto',$/;\"\tfeature\nmpath\tinput.meson_options\t/^option('mpath', type : 'feature', value : 'auto',$/;\"\tfeature\niconv\tinput.meson_options\t/^option('iconv', type : 'feature', value : 'auto',$/;\"\tfeature\ncurses\tinput.meson_options\t/^option('curses', type : 'feature', value : 'auto',$/;\"\tfeature\nlibudev\tinput.meson_options\t/^option('libudev', type : 'feature', value : 'auto',$/;\"\tfeature\nsdl\tinput.meson_options\t/^option('sdl', type : 'feature', value : 'auto',$/;\"\tfeature\nsdl_image\tinput.meson_options\t/^option('sdl_image', type : 'feature', value : 'auto',$/;\"\tfeature\nu2f\tinput.meson_options\t/^option('u2f', type : 'feature', value : 'auto',$/;\"\tfeature\nvnc\tinput.meson_options\t/^option('vnc', type : 'feature', value : 'enabled',$/;\"\tfeature\nvnc_jpeg\tinput.meson_options\t/^option('vnc_jpeg', type : 'feature', value : 'auto',$/;\"\tfeature\nvnc_png\tinput.meson_options\t/^option('vnc_png', type : 'feature', value : 'auto',$/;\"\tfeature\nvnc_sasl\tinput.meson_options\t/^option('vnc_sasl', type : 'feature', value : 'auto',$/;\"\tfeature\nxkbcommon\tinput.meson_options\t/^option('xkbcommon', type : 'feature', value : 'auto',$/;\"\tfeature\nvirtiofsd\tinput.meson_options\t/^option('virtiofsd', type: 'feature', value: 'auto',$/;\"\tfeature\nvhost_user_blk_server\tinput.meson_options\t/^option('vhost_user_blk_server', type: 'feature', value: 'auto',$/;\"\tfeature\nfuse\tinput.meson_options\t/^option('fuse', type: 'feature', value: 'auto',$/;\"\tfeature\nfuse_lseek\tinput.meson_options\t/^option('fuse_lseek', type : 'feature', value : 'auto',$/;\"\tfeature\ncapstone\tinput.meson_options\t/^option('capstone', type: 'combo', value: 'auto',$/;\"\tcombo\nslirp\tinput.meson_options\t/^option('slirp', type: 'combo', value: 'auto',$/;\"\tcombo\nfdt\tinput.meson_options\t/^option('fdt', type: 'combo', value: 'auto',$/;\"\tcombo\n"
  },
  {
    "path": "Units/simple-meson-options.d/input.meson_options",
    "content": "option('qemu_suffix', type : 'string', value: 'qemu',\n       description: 'Suffix for QEMU data/modules/config directories (can be empty)')\noption('docdir', type : 'string', value : 'doc',\n       description: 'Base directory for documentation installation (can be empty)')\noption('qemu_firmwarepath', type : 'string', value : '',\n       description: 'search PATH for firmware files')\noption('sphinx_build', type : 'string', value : '',\n       description: 'Use specified sphinx-build [$sphinx_build] for building document (default to be empty)')\n\noption('docs', type : 'feature', value : 'auto',\n       description: 'Documentations build support')\noption('gettext', type : 'boolean', value : true,\n       description: 'Localization of the GTK+ user interface')\noption('install_blobs', type : 'boolean', value : true,\n       description: 'install provided firmware blobs')\noption('sparse', type : 'feature', value : 'auto',\n       description: 'sparse checker')\n\noption('malloc_trim', type : 'feature', value : 'auto',\n       description: 'enable libc malloc_trim() for memory optimization')\noption('malloc', type : 'combo', choices : ['system', 'tcmalloc', 'jemalloc'],\n       value: 'system', description: 'choose memory allocator to use')\n\noption('kvm', type: 'feature', value: 'auto',\n       description: 'KVM acceleration support')\noption('hax', type: 'feature', value: 'auto',\n       description: 'HAX acceleration support')\noption('whpx', type: 'feature', value: 'auto',\n       description: 'WHPX acceleration support')\noption('hvf', type: 'feature', value: 'auto',\n       description: 'HVF acceleration support')\noption('xen', type: 'feature', value: 'auto',\n       description: 'Xen backend support')\noption('xen_pci_passthrough', type: 'feature', value: 'auto',\n       description: 'Xen PCI passthrough support')\noption('tcg', type: 'feature', value: 'auto',\n       description: 'TCG support')\n\noption('cocoa', type : 'feature', value : 'auto',\n       description: 'Cocoa user interface (macOS only)')\noption('mpath', type : 'feature', value : 'auto',\n       description: 'Multipath persistent reservation passthrough')\noption('iconv', type : 'feature', value : 'auto',\n       description: 'Font glyph conversion support')\noption('curses', type : 'feature', value : 'auto',\n       description: 'curses UI')\noption('libudev', type : 'feature', value : 'auto',\n       description: 'Use libudev to enumerate host devices')\noption('sdl', type : 'feature', value : 'auto',\n       description: 'SDL user interface')\noption('sdl_image', type : 'feature', value : 'auto',\n       description: 'SDL Image support for icons')\noption('u2f', type : 'feature', value : 'auto',\n       description: 'U2F emulation support')\noption('vnc', type : 'feature', value : 'enabled',\n       description: 'VNC server')\noption('vnc_jpeg', type : 'feature', value : 'auto',\n       description: 'JPEG lossy compression for VNC server')\noption('vnc_png', type : 'feature', value : 'auto',\n       description: 'PNG compression for VNC server')\noption('vnc_sasl', type : 'feature', value : 'auto',\n       description: 'SASL authentication for VNC server')\noption('xkbcommon', type : 'feature', value : 'auto',\n       description: 'xkbcommon support')\noption('virtiofsd', type: 'feature', value: 'auto',\n       description: 'build virtiofs daemon (virtiofsd)')\noption('vhost_user_blk_server', type: 'feature', value: 'auto',\n       description: 'build vhost-user-blk server')\noption('fuse', type: 'feature', value: 'auto',\n       description: 'FUSE block device export')\noption('fuse_lseek', type : 'feature', value : 'auto',\n       description: 'SEEK_HOLE/SEEK_DATA support for FUSE exports')\n\noption('capstone', type: 'combo', value: 'auto',\n       choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],\n       description: 'Whether and how to find the capstone library')\noption('slirp', type: 'combo', value: 'auto',\n       choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],\n       description: 'Whether and how to find the slirp library')\noption('fdt', type: 'combo', value: 'auto',\n       choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],\n       description: 'Whether and how to find the libfdt library')\n"
  },
  {
    "path": "Units/simple-passwd.d/args.ctags",
    "content": "--map-passwd=+.passwd\n"
  },
  {
    "path": "Units/simple-passwd.d/expected.tags",
    "content": "bin\tinput.passwd\t/^bin:x:1:1:bin:\\/bin:\\/sbin\\/nologin$/;\"\tu\thome:/bin\tshell:/sbin/nologin\nroot\tinput.passwd\t/^root:x:0:0:root:\\/root:\\/bin\\/bash$/;\"\tu\thome:/root\tshell:/bin/bash\n"
  },
  {
    "path": "Units/simple-passwd.d/input.passwd",
    "content": "root:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:/sbin/nologin\n"
  },
  {
    "path": "Units/simple-pkgconfig.d/args.ctags",
    "content": "--sort=no\n--fields=+{extras}lKr\n--extras=+r\n"
  },
  {
    "path": "Units/simple-pkgconfig.d/expected.tags",
    "content": "prefix\tinput.pc\t/^prefix=@CMAKE_INSTALL_PREFIX@$/;\"\tvar\tlanguage:PkgConfig\troles:def\nexec_prefix\tinput.pc\t/^exec_prefix=@CMAKE_INSTALL_PREFIX@$/;\"\tvar\tlanguage:PkgConfig\troles:def\nlibdir\tinput.pc\t/^libdir=@CMAKE_INSTALL_FULL_LIBDIR@$/;\"\tvar\tlanguage:PkgConfig\troles:def\nincludedir\tinput.pc\t/^includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@$/;\"\tvar\tlanguage:PkgConfig\troles:def\nrpmhome\tinput.pc\t/^rpmhome=@RPM_CONFIGDIR@$/;\"\tvar\tlanguage:PkgConfig\troles:def\n@CMAKE_PROJECT_NAME@\tinput.pc\t/^Name: @CMAKE_PROJECT_NAME@$/;\"\tname\tlanguage:PkgConfig\troles:def\ninput\tinput.pc\t/^Name: @CMAKE_PROJECT_NAME@$/;\"\tpkg\tlanguage:PkgConfig\troles:def\textras:guessedFromFileName\npopt\tinput.pc\t/^Requires: popt$/;\"\tpkg\tlanguage:PkgConfig\troles:required\textras:reference\n@ZSTD_REQUIRES@\tinput.pc\t/^Requires.private: @ZSTD_REQUIRES@$/;\"\tpkg\tlanguage:PkgConfig\troles:required\textras:reference\nxfunc\tinput.pc\t/^Provides: xfunc$/;\"\tpkg\tlanguage:PkgConfig\troles:provided\textras:reference\napt\tinput.pc\t/^Conflicts: apt$/;\"\tpkg\tlanguage:PkgConfig\troles:conflicted\textras:reference\n"
  },
  {
    "path": "Units/simple-pkgconfig.d/input.pc",
    "content": "#\n# Derrived from  rpm/rpm.pc.in\n#\nprefix=@CMAKE_INSTALL_PREFIX@\nexec_prefix=@CMAKE_INSTALL_PREFIX@\nlibdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@\nrpmhome=@RPM_CONFIGDIR@\n\nName: @CMAKE_PROJECT_NAME@\nDescription: @CMAKE_PROJECT_DESCRIPTION@\nVersion: @CMAKE_PROJECT_VERSION@\nURL: @CMAKE_PROJECT_HOMEPAGE_URL@\nRequires: popt\nRequires.private: @ZSTD_REQUIRES@\nProvides: xfunc\nConflicts: apt\n# Conflicts:\nCflags: -I${includedir} -D_FILE_OFFSET_BITS=64\nLibs: -L${libdir} -lrpm -lrpmio\nLibs.private: -lpopt -lrt -lpthread @WITH_LZMA_LIB@ @WITH_BZ2_LIB@ @WITH_ZLIB_LIB@ @LUA_LIBS@\n"
  },
  {
    "path": "Units/simple-plist.d/args.ctags",
    "content": "--fields=+x\n\n"
  },
  {
    "path": "Units/simple-plist.d/expected.tags",
    "content": "A\tinput.plist\t/^\t<key>A<\\/key>$/;\"\tk\txpath:/plist/dict/key[1]/text()\nB\tinput.plist\t/^\t<key>B<\\/key>$/;\"\tk\txpath:/plist/dict/key[2]/text()\nC\tinput.plist\t/^\t\t<key>C<\\/key>$/;\"\tk\tkey:B\txpath:/plist/dict/dict/key/text()\nD\tinput.plist\t/^\t<key>D<\\/key>$/;\"\tk\txpath:/plist/dict/key[3]/text()\nE\tinput.plist\t/^\t    <key>E<\\/key>$/;\"\tk\tkey:D\txpath:/plist/dict/array/dict/key[1]/text()\nF\tinput.plist\t/^\t    <key>F<\\/key>$/;\"\tk\tkey:D\txpath:/plist/dict/array/dict/key[2]/text()\nG\tinput.plist\t/^\t\t<key>G<\\/key>$/;\"\tk\tkey:D.F\txpath:/plist/dict/array/dict/array/dict/key/text()\nrootDict\tinput.plist\t/^<dict id=\"rootDict\">$/;\"\ti\txpath:/plist/dict/@id\n"
  },
  {
    "path": "Units/simple-plist.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/simple-plist.d/input.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">\n<plist version=\"0.9\">\n<dict id=\"rootDict\">\n\t<key>A</key>\n\t<string>v0</string>\n\t<key>B</key>\n\t<dict>\n\t\t<key>C</key>\n\t\t<string>v1</string>\n\t</dict>\n\t<key>D</key>\n\t<array>\n\t  <dict>\n\t    <key>E</key>\n\t    <string>v2</string>\n\t    <key>F</key>\n\t    <array>\n\t      <dict>\n\t\t<string>v3</string>\n\t\t<key>G</key>\n\t\t<string>v4</string>\n\t      </dict>\n\t    </array>\n\t  </dict>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "Units/simple-pythonLoggingConfig.d/args.ctags",
    "content": "--fields=+lK\n"
  },
  {
    "path": "Units/simple-pythonLoggingConfig.d/expected.tags",
    "content": "args\tinput.conf\t/^args=(sys.stdout,)$/;\"\tkey\tlanguage:Iniconf\tsection:handler_hand01\nclass\tinput.conf\t/^class=StreamHandler$/;\"\tkey\tlanguage:Iniconf\tsection:handler_hand01\nclass\tinput.conf\t/^class=logging.Formatter$/;\"\tkey\tlanguage:Iniconf\tsection:formatter_form01\ncompiler.parser\tinput.conf\t/^qualname=compiler.parser$/;\"\tqualname\tlanguage:PythonLoggingConfig\tloggerSection:parser\ndatefmt\tinput.conf\t/^datefmt=$/;\"\tkey\tlanguage:Iniconf\tsection:formatter_form01\nformat\tinput.conf\t/^format=F1 %(asctime)s %(levelname)s %(message)s$/;\"\tkey\tlanguage:Iniconf\tsection:formatter_form01\nformatter\tinput.conf\t/^formatter=form01$/;\"\tkey\tlanguage:Iniconf\tsection:handler_hand01\nformatter_form01\tinput.conf\t/^[formatter_form01]$/;\"\tsection\tlanguage:Iniconf\nformatters\tinput.conf\t/^[formatters]$/;\"\tsection\tlanguage:Iniconf\nhandler_hand01\tinput.conf\t/^[handler_hand01]$/;\"\tsection\tlanguage:Iniconf\nhandlers\tinput.conf\t/^[handlers]$/;\"\tsection\tlanguage:Iniconf\nhandlers\tinput.conf\t/^handlers=hand01$/;\"\tkey\tlanguage:Iniconf\tsection:logger_parser\nhandlers\tinput.conf\t/^handlers=hand01$/;\"\tkey\tlanguage:Iniconf\tsection:logger_root\nkey-with-dashes\tinput.conf\t/^key-with-dashes=value2$/;\"\tkey\tlanguage:Iniconf\tsection:section.with.dots\nkey.with.dots\tinput.conf\t/^key.with.dots=value1$/;\"\tkey\tlanguage:Iniconf\tsection:section.with.dots\nkeys\tinput.conf\t/^keys=form01$/;\"\tkey\tlanguage:Iniconf\tsection:formatters\nkeys\tinput.conf\t/^keys=hand01$/;\"\tkey\tlanguage:Iniconf\tsection:handlers\nkeys\tinput.conf\t/^keys=root,parser$/;\"\tkey\tlanguage:Iniconf\tsection:loggers\nlevel\tinput.conf\t/^level=DEBUG$/;\"\tkey\tlanguage:Iniconf\tsection:logger_parser\nlevel\tinput.conf\t/^level=NOTSET$/;\"\tkey\tlanguage:Iniconf\tsection:handler_hand01\nlevel\tinput.conf\t/^level=NOTSET$/;\"\tkey\tlanguage:Iniconf\tsection:logger_root\nlogger_parser\tinput.conf\t/^[logger_parser]$/;\"\tsection\tlanguage:Iniconf\nlogger_root\tinput.conf\t/^[logger_root]$/;\"\tsection\tlanguage:Iniconf\nloggers\tinput.conf\t/^[loggers]$/;\"\tsection\tlanguage:Iniconf\nparser\tinput.conf\t/^[logger_parser]$/;\"\tloggerSection\tlanguage:PythonLoggingConfig\npropagate\tinput.conf\t/^propagate=1$/;\"\tkey\tlanguage:Iniconf\tsection:logger_parser\nqualname\tinput.conf\t/^qualname=compiler.parser$/;\"\tkey\tlanguage:Iniconf\tsection:logger_parser\nroot\tinput.conf\t/^[logger_root]$/;\"\tloggerSection\tlanguage:PythonLoggingConfig\nsection.with.dots\tinput.conf\t/^[section.with.dots]$/;\"\tsection\tlanguage:Iniconf\n"
  },
  {
    "path": "Units/simple-pythonLoggingConfig.d/input.conf",
    "content": "#\n# TAKEN FROM https://docs.python.org/2/library/logging.config.html\n#\n\n[loggers]\nkeys=root,parser\n\n[handlers]\nkeys=hand01\n\n[formatters]\nkeys=form01\n\n[logger_root]\nlevel=NOTSET\nhandlers=hand01\n\n[logger_parser]\nlevel=DEBUG\nhandlers=hand01\npropagate=1\nqualname=compiler.parser\n\n[handler_hand01]\nclass=StreamHandler\nlevel=NOTSET\nformatter=form01\nargs=(sys.stdout,)\n\n[formatter_form01]\nformat=F1 %(asctime)s %(levelname)s %(message)s\ndatefmt=\nclass=logging.Formatter\n\n[section.with.dots]\nkey.with.dots=value1\nkey-with-dashes=value2\n"
  },
  {
    "path": "Units/simple-s4class.d/args.ctags",
    "content": "--kinds-R=*\n--fields-R=*\n--fields=+ElS\n--sort=no\n"
  },
  {
    "path": "Units/simple-s4class.d/expected.tags",
    "content": "C\tinput.r\t/^setClass(\"C\", representation(x=\"numeric\"))$/;\"\tc\tlanguage:S4Class\textras:subparser\nx\tinput.r\t/^setClass(\"C\", representation(x=\"numeric\"))$/;\"\tr\tlanguage:S4Class\tclass:C\ttyperef:typename:numeric\textras:subparser\nrun\tinput.r\t/^setGeneric(\"run\", function(object) 1)$/;\"\tg\tlanguage:S4Class\textras:subparser\nanonFuncc203d3890100\tinput.r\t/^setGeneric(\"run\", function(object) 1)$/;\"\tf\tlanguage:R\tgeneric:run\tsignature:(object)\textras:anonymous\nobject\tinput.r\t/^setGeneric(\"run\", function(object) 1)$/;\"\tz\tlanguage:R\tfunction:run.anonFuncc203d3890100\nrun\tinput.r\t/^setMethod(\"run\", c(\"C\"), definition = function (object) {$/;\"\tm\tlanguage:S4Class\tsignature:(\"C\")\textras:subparser\nanonFuncc203d3890200\tinput.r\t/^setMethod(\"run\", c(\"C\"), definition = function (object) {$/;\"\tf\tlanguage:R\tmethod:run\tsignature:(object)\textras:anonymous\nobject\tinput.r\t/^setMethod(\"run\", c(\"C\"), definition = function (object) {$/;\"\tz\tlanguage:R\tfunction:run.anonFuncc203d3890200\nrun2\tinput.r\t/^setGeneric(\"run2\", function(object) 1)$/;\"\tg\tlanguage:S4Class\textras:subparser\nanonFuncc203d3890300\tinput.r\t/^setGeneric(\"run2\", function(object) 1)$/;\"\tf\tlanguage:R\tgeneric:run2\tsignature:(object)\textras:anonymous\nobject\tinput.r\t/^setGeneric(\"run2\", function(object) 1)$/;\"\tz\tlanguage:R\tfunction:run2.anonFuncc203d3890300\nrun2\tinput.r\t/^setMethod(\"run2\", c(\"C\"), function (object) {$/;\"\tm\tlanguage:S4Class\tsignature:(\"C\")\textras:subparser\nanonFuncc203d3890400\tinput.r\t/^setMethod(\"run2\", c(\"C\"), function (object) {$/;\"\tf\tlanguage:R\tmethod:run2\tsignature:(object)\textras:anonymous\nobject\tinput.r\t/^setMethod(\"run2\", c(\"C\"), function (object) {$/;\"\tz\tlanguage:R\tfunction:run2.anonFuncc203d3890400\nD\tinput.r\t/^setClass (\"D\", contains = \"C\")$/;\"\tc\tlanguage:S4Class\textras:subparser\nrun3\tinput.r\t/^setGeneric(\"run3\", function(i, j) 1)$/;\"\tg\tlanguage:S4Class\textras:subparser\nanonFuncc203d3890500\tinput.r\t/^setGeneric(\"run3\", function(i, j) 1)$/;\"\tf\tlanguage:R\tgeneric:run3\tsignature:(i, j)\textras:anonymous\ni\tinput.r\t/^setGeneric(\"run3\", function(i, j) 1)$/;\"\tz\tlanguage:R\tfunction:run3.anonFuncc203d3890500\nj\tinput.r\t/^setGeneric(\"run3\", function(i, j) 1)$/;\"\tz\tlanguage:R\tfunction:run3.anonFuncc203d3890500\nrun3\tinput.r\t/^setMethod(\"run3\", signature(\"numeric\", \"numeric\"),$/;\"\tm\tlanguage:S4Class\tsignature:(\"numeric\", \"numeric\")\textras:subparser\nanonFuncc203d3890600\tinput.r\t/^\t\t  function (i, j) { i + j })$/;\"\tf\tlanguage:R\tmethod:run3\tsignature:(i, j)\textras:anonymous\ni\tinput.r\t/^\t\t  function (i, j) { i + j })$/;\"\tz\tlanguage:R\tfunction:run3.anonFuncc203d3890600\nj\tinput.r\t/^\t\t  function (i, j) { i + j })$/;\"\tz\tlanguage:R\tfunction:run3.anonFuncc203d3890600\nc\tinput.r\t/^c <- new (\"C\", x = 2)$/;\"\tg\tlanguage:R\tassignmentop:<-\n"
  },
  {
    "path": "Units/simple-s4class.d/input.r",
    "content": "setClass(\"C\", representation(x=\"numeric\"))\n\nsetGeneric(\"run\", function(object) 1)\n\nsetMethod(\"run\", c(\"C\"), definition = function (object) {\n\t\t object@x <- 4\n\t\t 3 + object@x\n})\n\nsetGeneric(\"run2\", function(object) 1)\nsetMethod(\"run2\", c(\"C\"), function (object) {\n\t\t object@x <- 4\n\t\t 3 + object@x\n})\n\nsetClass (\"D\", contains = \"C\")\nsetGeneric(\"run3\", function(i, j) 1)\nsetMethod(\"run3\", signature(\"numeric\", \"numeric\"),\n\t\t  function (i, j) { i + j })\n\nc <- new (\"C\", x = 2)\nprint(run(c))\nprint(run('a'))\n"
  },
  {
    "path": "Units/simple-texBeamer.d/args.ctags",
    "content": "--sort=no\n--fields=+K\n--roles-all.*=*\n--extras=+r\n--fields=+r\n"
  },
  {
    "path": "Units/simple-texBeamer.d/expected.tags",
    "content": "document\tinput.tex\t/^\\\\begin{document}$/;\"\tenvironment\troles:used\nframe\tinput.tex\t/^\\\\begin{frame}{Concept}$/;\"\tenvironment\troles:used\nConcept\tinput.tex\t/^\\\\begin{frame}{Concept}$/;\"\tframetitle\troles:def\nframe\tinput.tex\t/^\\\\begin{frame}{Concept}{kind}$/;\"\tenvironment\troles:used\nkind\tinput.tex\t/^\\\\begin{frame}{Concept}{kind}$/;\"\tframesubtitle\tframetitle:Concept\troles:def\nframe\tinput.tex\t/^\\\\begin{frame}\\\\frametitle{Concept}$/;\"\tenvironment\troles:used\nfield\tinput.tex\t/^  \\\\framesubtitle{field}$/;\"\tframesubtitle\tframetitle:Concept\troles:def\nframe\tinput.tex\t/^\\\\begin{frame}{Concept}$/;\"\tenvironment\troles:used\nextra\tinput.tex\t/^  \\\\framesubtitle{extra}$/;\"\tframesubtitle\tframetitle:Concept\troles:def\nframe\tinput.tex\t/^\\\\begin{frame}[fragile]{Concept}{pseudo tag}$/;\"\tenvironment\troles:used\npseudo tag\tinput.tex\t/^\\\\begin{frame}[fragile]{Concept}{pseudo tag}$/;\"\tframesubtitle\tframetitle:Concept\troles:def\nframe\tinput.tex\t/^\\\\begin{frame}<1-2>\\\\frametitle{Options}$/;\"\tenvironment\troles:used\nOptions\tinput.tex\t/^\\\\begin{frame}<1-2>\\\\frametitle{Options}$/;\"\tframetitle\troles:def\nitemize\tinput.tex\t/^  \\\\begin{itemize}$/;\"\tenvironment\troles:used\nitemize\tinput.tex\t/^  \\\\begin{itemize}$/;\"\tenvironment\troles:used\nframe\tinput.tex\t/^\\\\begin{frame}<1-2>[fragile]\\\\frametitle{Optlib}$/;\"\tenvironment\troles:used\nOptlib\tinput.tex\t/^\\\\begin{frame}<1-2>[fragile]\\\\frametitle{Optlib}$/;\"\tframetitle\troles:def\nitemize\tinput.tex\t/^  \\\\begin{itemize}$/;\"\tenvironment\troles:used\nitemize\tinput.tex\t/^  \\\\begin{itemize}$/;\"\tenvironment\troles:used\nframe\tinput.tex\t/^\\\\begin{frame}<1-2>[fragile]\\\\frametitle{Optlib}\\\\framesubtitle{Line oriented parser}$/;\"\tenvironment\troles:used\nLine oriented parser\tinput.tex\t/^\\\\begin{frame}<1-2>[fragile]\\\\frametitle{Optlib}\\\\framesubtitle{Line oriented parser}$/;\"\tframesubtitle\tframetitle:Optlib\troles:def\nitemize\tinput.tex\t/^  \\\\begin{itemize}$/;\"\tenvironment\troles:used\nframe\tinput.tex\t/^\\\\begin{frame}[<+->][plain]{Optlib}\\\\framesubtitle{Multiline parser}$/;\"\tenvironment\troles:used\nMultiline parser\tinput.tex\t/^\\\\begin{frame}[<+->][plain]{Optlib}\\\\framesubtitle{Multiline parser}$/;\"\tframesubtitle\tframetitle:Optlib\troles:def\nitemize\tinput.tex\t/^\\\\begin{itemize}$/;\"\tenvironment\troles:used\n"
  },
  {
    "path": "Units/simple-texBeamer.d/input.tex",
    "content": "\\documentclass{beamer}\n\n\\begin{document}\n\\begin{frame}{Concept}\n\\end{frame}\n\\begin{frame}{Concept}{kind}\n\\end{frame}\n\\begin{frame}\\frametitle{Concept}\n  \\framesubtitle{field}\n\\end{frame}\n\\begin{frame}{Concept}\n  \\framesubtitle{extra}\n\\end{frame}\n\n\\begin{frame}[fragile]{Concept}{pseudo tag}\n\\end{frame}\n\n\\begin{frame}<1-2>\\frametitle{Options}\n\\onslide*<1>{\n  \\begin{itemize}\n  \\item --kinds=\n  \\item --fields=\n  \\item --extras=\n  \\end{itemize}\n}\n\\onslide*<2>{\n  \\begin{itemize}\n  \\item --list-kinds-full=\n  \\item --list-fields=\n  \\item --list-extras=\n  \\end{itemize}\n}\n\\end{frame}\n\n\\begin{frame}<1-2>[fragile]\\frametitle{Optlib}\n\\onslide*<1>{\n  \\begin{itemize}\n  \\item --langdef=\n  \\item --map-LANG=\n  \\end{itemize}\n}\n\\onslide*<2>{\n  \\begin{itemize}\n  \\item --kinddef-LANG=\n  \\item --fielddef-LANG=\n  \\item --extradef-LANG=\n  \\end{itemize}\n}\n\\end{frame}\n\n\\begin{frame}<1-2>[fragile]\\frametitle{Optlib}\\framesubtitle{Line oriented parser}\n\\onslide*<1>{\n--regex-LANG=...\n}\n\\onslide*<2>{\n  \\begin{itemize}\n  \\item \\{scope\\}\n  \\item \\{exclusive\\}\n  \\item \\{placeholder\\}\n  \\end{itemize}\n}\n\\end{frame}\n\\begin{frame}[<+->][plain]{Optlib}\\framesubtitle{Multiline parser}\n--mline-regex-LANG=...\n\\begin{itemize}\n\\item \\{mgroup\\}\n\\item \\{\\_advanceTo\\}\n\\item \\{\\_guest\\}\n\\end{itemize}\n\\end{frame}\n\\end{document}\n"
  },
  {
    "path": "Units/simple-txt2tags.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/simple-txt2tags.d/expected.tags",
    "content": "Paragraph\tinput.t2t\t/^= Paragraph =[paragraph]$/;\"\ts\nComment\tinput.t2t\t/^= Comment =[comment]$/;\"\ts\nLine\tinput.t2t\t/^= Line =[line]$/;\"\ts\nInline\tinput.t2t\t/^= Inline =[inline]$/;\"\ts\nLink\tinput.t2t\t/^= Link =[link]$/;\"\ts\nImage\tinput.t2t\t/^= Image =[image]$/;\"\ts\nMacro\tinput.t2t\t/^= Macro =[macro]$/;\"\ts\nNumbered Title\tinput.t2t\t/^= Numbered Title =[numtitle]$/;\"\ts\nTitle\tinput.t2t\t/^= Title =[title]$/;\"\ts\nTitle Level 1\tinput.t2t\t/^= Title Level 1 =$/;\"\ts\nTitle Level 2\tinput.t2t\t/^== Title Level 2 ==$/;\"\ts\tsection:Title Level 1\nTitle Level 3\tinput.t2t\t/^=== Title Level 3 ===$/;\"\ts\tsection:Title Level 1\"\"Title Level 2\nTitle Level 4\tinput.t2t\t/^==== Title Level 4 ====$/;\"\ts\tsection:Title Level 1\"\"Title Level 2\"\"Title Level 3\nTitle Level 5\tinput.t2t\t/^===== Title Level 5 =====$/;\"\ts\tsection:Title Level 1\"\"Title Level 2\"\"Title Level 3\"\"Title Level 4\nTitle Level 1\tinput.t2t\t/^= Title Level 1 =[lab_el-1]$/;\"\ts\nTitle Level 2\tinput.t2t\t/^== Title Level 2 ==[lab_el-2]$/;\"\ts\tsection:Title Level 1\nTitle Level 3\tinput.t2t\t/^=== Title Level 3 ===[lab_el-3]$/;\"\ts\tsection:Title Level 1\"\"Title Level 2\nTitle Level 4\tinput.t2t\t/^==== Title Level 4 ====[lab_el-4]$/;\"\ts\tsection:Title Level 1\"\"Title Level 2\"\"Title Level 3\nTitle Level 5\tinput.t2t\t/^===== Title Level 5 =====[lab_el-5]$/;\"\ts\tsection:Title Level 1\"\"Title Level 2\"\"Title Level 3\"\"Title Level 4\nTitle Level 3\tinput.t2t\t/^     ===Title Level 3===    $/;\"\ts\tsection:Title Level 1\"\"Title Level 2\nTitle Level 3\tinput.t2t\t/^    === Title Level 3 ===    $/;\"\ts\tsection:Title Level 1\"\"Title Level 2\nTitle Level 3\tinput.t2t\t/^   ===  Title Level 3  ===   $/;\"\ts\tsection:Title Level 1\"\"Title Level 2\nTitle Level 3\tinput.t2t\t/^===     Title Level 3      ===$/;\"\ts\tsection:Title Level 1\"\"Title Level 2\nTitle Level 3\tinput.t2t\t/^===          Title Level 3 ===$/;\"\ts\tsection:Title Level 1\"\"Title Level 2\nTitle Level 3\tinput.t2t\t/^   ===  Title Level 3  ===[lab_el-9]   $/;\"\ts\tsection:Title Level 1\"\"Title Level 2\nQuote\tinput.t2t\t/^= Quote =[quote]$/;\"\ts\nRaw\tinput.t2t\t/^= Raw =[raw]$/;\"\ts\nVerbatim\tinput.t2t\t/^= Verbatim =[verbatim]$/;\"\ts\nDefinition List\tinput.t2t\t/^= Definition List =[deflist]$/;\"\ts\nNumbered List\tinput.t2t\t/^= Numbered List =[numlist]$/;\"\ts\nList\tinput.t2t\t/^= List =[list]$/;\"\ts\nTable\tinput.t2t\t/^= Table =[table]$/;\"\ts\n"
  },
  {
    "path": "Units/simple-txt2tags.d/input.t2t",
    "content": "Txt2tags Markup Rules\n\n\n%!includeconf: rules.conf\n\nThis document describes all the details about each txt2tags mark.\nThe target audience are **experienced** users. You may find it\nuseful if you want to master the marks or solve a specific problem\nabout a mark.\n\nIf you are new to txt2tags or just want to know which are the\navailable marks, please read the [Markup Demo MARKUPDEMO].\n\nNote 1: This document is generated directly from the txt2tags\ntest-suite. All the rules mentioned here are 100% in sync with the\ncurrent program code.\n\nNote 2: A good practice is to consult [the sources rules.t2t] when\nreading, to see how the texts were made.\n\nTable of Contents:\n\n%%TOC\n\n-------------------------------------------------------------\n\n= Paragraph =[paragraph]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/paragraph.t2t\nBODYINIT\n\n%%% Syntax: Lines grouped together\nA paragraph is composed by one or more lines.\nA blank line (or a table, or a list) ends the\ncurrent paragraph.\n\n%%% Syntax: Leading and trailing spaces are ignored\n   Leading and trailing spaces are ignored.   \n\n%%% Syntax: A comment don't close a paragraph\nA comment line can be placed inside a paragraph.\n% this comment will be ignored\nIt will not affect it.\n\n%%% Closing: EOF closes the open paragraph\nThe end of the file (EOF) closes the\ncurrently open paragraph.\n\n= Comment =[comment]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/comment.t2t\nBODYINIT\n\n%%% Syntax: The % character at the line beginning (column 1)\n%glued with the % mark\n% separated from the % mark\n%      very distant from the % mark\n%%%%%%% lots of % marks\n% a blank comment, used for vertical spacing:\n%\n% NOTE: what matters is the first % being at the line beginning,\n%       the rest of the line is just ignored.\n\n%%% Syntax: Area (block)\n%%%\nYou're not seeing this.\n%%%\n\n%%% Syntax: Area (block) with trailing spaces\n%%% \t \nYou're not seeing this.\n%%%\t \n\n%%% Invalid: The % in any other position\n % not on the line beginning (at column 2)\n\nsome text     % half line comments are not allowed\n\n\n= Line =[line]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/line.t2t\nBODYINIT\n\n%%% Syntax: At least 20 chars of - = _\n--------------------\n====================\n____________________\n%%% Syntax: Any kind of mixing is allowed\n%% Free mixing is allowed to make the line,\n%% but the first char is the identifier for\n%% the difference between separator ( - _ )\n%% and strong ( = ) lines.\n=========-----------\n-_-_-_-_-_-_-_-_-_-_\n=-=-=-=-=-=-=-=-=-=-\n=------------------=\n--------====--------\n%%% Syntax: Leading and/or trailing spaces are allowed\n   --------------------\n--------------------   \n   --------------------   \n%%% Invalid: Less than 20 chars (but strike matches)\n---------\n%%% Invalid: Strange chars (but strike matches)\n--------- ----------\n\n---------+----------\n\n( -------------------- )\n\n= Inline =[inline]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/inline.t2t\nBODYINIT\n\n%%% Syntax: Marks are greedy and must be \"glued\" with contents\n%% GLUED: The contents must be glued with the marks, no spaces\n%% between them. Right after the opening mark there must be a\n%% non-blank character, as well as right before the closing mark.\n%% \n%% GREEDY: If the contents boundary character is the same as\n%% the mark character, it is considered contents, not mark.\n%% So \"\"****bold****\"\" turns to \"\"<B>**bold**</B>\"\" in HTML.\n\ni) **b**         //i//         __u__         --s--         ``m``         \"\"r\"\"        ''t''\ni) **bo**        //it//        __un__        --st--        ``mo``        \"\"ra\"\"       ''tg''\ni) **bold**      //ital//      __undr__      --strk--      ``mono``      \"\"raw\"\"      ''tggd''\ni) **bo ld**     //it al//     __un dr__     --st rk--     ``mo no``     \"\"r aw\"\"     ''tg gd''\ni) **bo * ld**   //it / al//   __un _ dr__   --st - rk--   ``mo ` no``   \"\"r \" aw\"\"   ''tg ' gd''\ni) **bo **ld**   //it //al//   __un __dr__   --st --rk--   ``mo ``no``   \"\"r \"\"aw\"\"   ''tg ''gd''\ni) **bo ** ld**  //it // al//  __un __ dr__  --st -- rk--  ``mo `` no``  \"\"r \"\" aw\"\"  ''tg '' gd''\ni) ****bold****  ////ital////  ____undr____  ----strk----  ````mono````  \"\"\"\"raw\"\"\"\"  ''''tggd''''\ni) ***bold***    ///ital///    ___undr___    ---strk---    ```mono```    \"\"\"raw\"\"\"    '''tggd'''\n\n%%% Syntax: Repetition is greedy\n%% When the mark character is repeated many times,\n%% the contents are expanded to the largest possible.\n%% Thats why they are greedy, the outer marks are\n%% the ones used.\n\ni)  *****         /////         _____         -----         `````        \"\"\"\"\"        '''''\ni)  ******        //////        ______        ------        ``````       \"\"\"\"\"\"       ''''''\ni)  *******       ///////       _______       -------       ```````      \"\"\"\"\"\"\"      '''''''\ni)  ********      ////////      ________      --------      ````````     \"\"\"\"\"\"\"\"     ''''''''\ni)  *********     /////////     _________     ---------     `````````    \"\"\"\"\"\"\"\"\"    '''''''''\ni)  **********    //////////    __________    ----------    ``````````   \"\"\"\"\"\"\"\"\"\"   ''''''''''\n\n%%% Invalid: No contents\n\ni)     ****          ////          ____          ----          ````       \"\"\"\"       ''''\ni)     ** **         // //         __ __         -- --         `` ``      \"\" \"\"      '' ''\n\n%%% Invalid: Contents not \"glued\" with marks\n%% Spaces between the marks and the contents in any side\n%% invalidate the mark.\n\ni)  ** bold**     // ital//     __ undr__     -- strk--     `` mono``     \"\" raw\"\"     '' tggd''\ni)  **bold **     //ital //     __undr __     --strk --     ``mono ``     \"\"raw \"\"     ''tggd ''\ni)  ** bold **    // ital //    __ undr __    -- strk --    `` mono ``    \"\" raw \"\"    '' tggd ''\n\n= Link =[link]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/link.t2t\nBODYINIT\n\n%%% Syntax: E-mail\nuser@domain.com\nuser@domain.com.\nuser@domain.com. any text.\nany text: user@domain.com. any text.\n[label user@domain.com]\n%%% Syntax: E-mail with form data\nuser@domain.com?subject=bla\nuser@domain.com?subject=bla.\nuser@domain.com?subject=bla,\nuser@domain.com?subject=bla&cc=otheruser@domain.com\nuser@domain.com?subject=bla&cc=otheruser@domain.com.\nuser@domain.com?subject=bla&cc=otheruser@domain.com,\n[label user@domain.com?subject=bla&cc=otheruser@domain.com].\n[label user@domain.com?subject=bla&cc=otheruser@domain.com.].\n%%% Syntax: URL\nhttp://www.domain.com\nhttp://www.domain.com/dir/\nhttp://www.domain.com/dir///\nhttp://www.domain.com.\nhttp://www.domain.com,\nhttp://www.domain.com. any text.\nhttp://www.domain.com, any text.\nhttp://www.domain.com/dir/. any text.\nany text: http://www.domain.com. any text.\nany text: http://www.domain.com/dir/. any text.\nany text: http://www.domain.com/dir/index.html. any text.\nany text: http://www.domain.com/dir/index.html, any text.\n%%% Syntax: URL with anchor\nhttp://www.domain.com/dir/#anchor\nhttp://www.domain.com/dir/index.html#anchor\nhttp://www.domain.com/dir/index.html#anchor.\nhttp://www.domain.com/dir/#anchor. any text.\nhttp://www.domain.com/dir/index.html#anchor. any text.\nany text: http://www.domain.com/dir/#anchor. any text.\nany text: http://www.domain.com/dir/index.html#anchor. any text.\n%%% Syntax: URL with form data\nhttp://domain.com?a=a@a.a&b=a+b+c.\nhttp://domain.com?a=a@a.a&b=a+b+c,\nhttp://domain.com/bla.cgi?a=a@a.a&b=a+b+c.\nhttp://domain.com/bla.cgi?a=a@a.a&b=a+b+c@.\n%%% Syntax: URL with form data and anchor\nhttp://domain.com?a=a@a.a&b=a+b+c.#anchor\nhttp://domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor\nhttp://domain.com/bla.cgi?a=a@a.a&b=a+b+c@.#anchor\n%%% Syntax: URL with login data\nhttp://user:password@domain.com/bla.html.\nhttp://user:password@domain.com/dir/.\nhttp://user:password@domain.com.\nhttp://user:@domain.com.\nhttp://user@domain.com.\n%%% Syntax: URL with login, form and anchor\nhttp://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor\nhttp://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c@#anchor\n%%% Syntax: URL with label\n[label www.domain.com]\n%%% Syntax: URL with label (trailing spaces are discarded, leading are maintained)\n%TODO normalize this behavior\n[  label www.domain.com]\n[label   www.domain.com]\n%%% Syntax: URL with label, stressing\n[anchor        http://www.domain.com/dir/index.html#anchor.]\n[login         http://user:password@domain.com/bla.html]\n[form          http://www.domain.com/bla.cgi?a=a@a.a&b=a+b+c.]\n[form & anchor http://www.domain.com/bla.cgi?a=a@a.a&b=a+b+c.#anchor]\n[login & form  http://user:password@domain.com/bla.cgi?a=a@a.a&b=a+b+c.]\n%%% Syntax: Link with label for local files\n[local link up          ..]\n[local link file        bla.html]\n[local link anchor      #anchor]\n[local link file/anchor bla.html#anchor]\n[local link file/anchor bla.html#anchor.]\n[local link img         abc.gif]\n%%% Syntax: Another link as a label\n[www.fake.com www.domain.com]\n%%% Syntax: URL with funny chars\nhttp://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm\nhttp://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-\nhttp://domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-#anchor_-1%.\nhttp://foo._user-9:pass!#$%&*()+word@domain.com:8080/~user/_st-r@a=n$g,e/index%20new.htm?a=/%22&b=+.@*_-#anchor_-1%.\n%%% Test: Various per line\nhttp://L1.com ! L2@www.com ! [L3 www.com] ! [L4 w@ww.com] ! www.L5.com\n%%% Feature: Guessed link, adding protocol automatically\nwww.domain.com\nwww2.domain.com\nftp.domain.com\nWWW.DOMAIN.COM\nFTP.DOMAIN.COM\n[label www.domain.com]\n[label ftp.domain.com]\n[label WWW.DOMAIN.COM]\n[label FTP.DOMAIN.COM]\n%%% Invalid: Trailing space on link\n[label www.domain.com ]\n%%% Invalid: Label with ] char (use postproc)\n[label] www.domain.com]\n\n= Image =[image]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/image.t2t\nBODYINIT\n\n%%% Syntax: Image name inside brackets: [img]\n[img.png]\n\n%%% Syntax: Image pointing to a link: [[img] link]\n[[img.png] http://txt2tags.org]\n\n%%% Align: Image position is preserved when inside paragraph\n[img.png] Image at the line beginning.\n\nImage in the middle [img.png] of the line.\n\nImage at the line end. [img.png]\n\n%%% Align: Image alone with spaces around is aligned\n[img.png]   \n                [img.png]  \n                                    [img.png]\n\n%%% Test: Two glued images with no spaces (left & right)\n[img.png][img.png]\n\n%%% Test: Various per line\nImages [img.png] mixed [img.png] with [img.png] text.\n\nImages glued together: [img.png][img.png][img.png].\n\n%%% Invalid: Spaces inside are not allowed\n[img.png ]\n\n[ img.png]\n\n[ img.png ]\n\n= Macro =[macro]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/macro.t2t\nBODYINIT\n\n%%% Syntax: Macro without formatting string\nDate    : %%date - %%date()\nMtime   : %%mtime - %%mtime()\nInfile  : %%infile - %%infile()\nOutfile : %%outfile - %%outfile()\n\n%%% Syntax: Macro name is case insensitive\nDate    : %%dAtE\nMtime   : %%mTiMe\nInfile  : %%iNfIlE\nOutfile : %%oUtFiLe\n\n%%% Syntax: Macro with formatting string\nDate    : %%date(txt %C txt)\nMtime   : %%mtime(txt %C txt)\nInfile  : %%infile(txt %e txt)\nOutfile : %%outfile(txt %e txt)\n\n%%% Syntax: Leading and trailing spaces are preserved\nDate    : (%%date( txt )) - (%%date( %C ))\nMtime   : (%%mtime( txt )) - (%%mtime( %C ))\nInfile  : (%%infile( txt )) - (%%infile( %e ))\nOutfile : (%%outfile( txt )) - (%%outfile( %e ))\n\n%%% Test: Expansion of the percent char\nDate    : %%date(%) - %%date(%%) - %%date(%%%) - %%date(%%%)\nMtime   : %%mtime(%) - %%mtime(%%) - %%mtime(%%%) - %%mtime(%%%)\nInfile  : %%infile(%) - %%infile(%%) - %%infile(%%%) - %%infile(%%%)\nOutfile : %%outfile(%) - %%outfile(%%) - %%outfile(%%%) - %%outfile(%%%)\n\n%%% Test: Various per line, glued\nDate    : %%date(%C)%%date%%date\nMtime   : %%mtime(%C)%%mtime%%mtime\nInfile  : %%infile(%e)%%infile%%infile\nOutfile : %%outfile(%e)%%outfile%%outfile\n\n%%% Test: Path formatters\nPath    : %%infile(%p)\nPath    : %%outfile(%p)\nDirname : %%infile(%d, %D)\nDirname : %%outfile(%d, %D)\nFile    : %%infile(%F + %e = %f)\nFile    : %%outfile(%F + %e = %f)\n\n= Numbered Title =[numtitle]\n\nSee [Title #title], the same rules apply.\n\n= Title =[title]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/title.t2t\nBODYINIT\n\n%%% Syntax: Balanced equal signs (from 1 to 5)\n= Title Level 1 =\n== Title Level 2 ==\n=== Title Level 3 ===\n==== Title Level 4 ====\n===== Title Level 5 =====\n%%% Label: Between brackets, alphanumeric [A-Za-z0-9_-]\n= Title Level 1 =[lab_el-1]\n== Title Level 2 ==[lab_el-2]\n=== Title Level 3 ===[lab_el-3]\n==== Title Level 4 ====[lab_el-4]\n===== Title Level 5 =====[lab_el-5]\n%%% Syntax: Spaces around and/or inside are allowed (and ignored)\n     ===Title Level 3===    \n    === Title Level 3 ===    \n   ===  Title Level 3  ===   \n===     Title Level 3      ===\n===          Title Level 3 ===\n   ===  Title Level 3  ===[lab_el-9]   \n%%% Invalid: Unbalanced equal signs\n      =Not Title\n\n     ==Not Title=\n\n    ===Not Title====\n%%% Invalid: Level deeper than 5\n ======Not Title 6======\n\n=======Not Title 7=======\n%%% Invalid: Space between title and label\n=Not Title= [label1]\n%%% Invalid: Space inside label\n=Not Title=[ label ]\n%%% Invalid: Strange chars inside label\n=Not Title=[la/bel]\n\n= Quote =[quote]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/quote.t2t\nBODYINIT\n\n%%% Syntax: TAB defines quote\n\tTo quote a paragraph, just prefix it by a TAB\n\tcharacter. All the lines of the paragraph must\n\tbegin with a TAB.\nAny non-tabbed line closes the quote block.\n\n%%% Nesting: Creating deeper quotes\n\tThe number of leading TABs identifies the quote\n\tblock depth. This is quote level 1.\n\t\tWith two TABs, we are on the quote\n\t\tlevel 2.\n\t\t\tThe more TABs, more deep is\n\t\t\tthe quote level.\n\t\t\t\tThere isn't a limit.\n\n%%% Nesting: Reverse nesting works\n\t\t\t\tThis quote starts at\n\t\t\t\tlevel 4.\n\t\t\tThen its depth is decreased.\n\t\tCounting down, one by one.\n\tUntil the level 1.\n\n%%% Nesting: Random count\n\t\t\tUnlike lists, any quote block is\n\t\t\tindependent, not part of a tree.\n\tThe TAB count don't need to be incremental\n\tby one.\n\t\t\t\tThe nesting don't need\n\t\t\t\tto follow any rule.\n\t\tQuotes can be opened and closed\n\t\tin any way.\n\t\t\t\t\tYou choose.\n\n%%% Nesting: When not supported\n\tSome targets (as sgml) don't support the\n\tnesting of quotes. There is only one quote\n\tlevel.\n\t\tIn this case, no matter how much\n\t\tTABs are used to define the quote\n\t\tblock, it always will be level 1.\n\n%%% Syntax: Spaces after TAB\n\t  Spaces AFTER the TAB character are allowed.\n\t  But be careful, it can be confusing.\n\n%%% Invalid: Spaces before TAB\n  \tSpaces BEFORE the TAB character\n  \tinvalidate the mark. It's not quote.\n\n%%% Invalid: Paragraphs inside\n\tParagraph breaks inside a quote aren't\n\tpossible.\n\t\n\tThis sample are two separated quoted\n\tparagraphs, not a quote block with\n\ttwo paragraphs inside.\n\n%%% Closing: EOF closes the open block\n\tThe end of the file (EOF) closes the\n\tcurrently open quote block.\n\n= Raw =[raw]\n\nSee [Verbatim #verbatim], the same rules apply.\n\n= Verbatim =[verbatim]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/verbatim.t2t\nBODYINIT\n\n%%% Syntax: A single line \n``` A verbatim line.\n\n%%% Syntax: A single line with leading spaces\n```   Another verbatim line, with leading spaces.\n\n%%% Syntax: Area (block)\n```\nA verbatim area delimited\n       by lines with marks.\n```\n\n%%% Syntax: Area (block) with trailing spaces\n``` \t \nTrailing spaces and TABs after the area marks\nare allowed, but not encouraged nor documented.\n```\t \n\n%%% Invalid: No space between mark and contents\n```Not a verbatim line, need one space after mark.\n\n%%% Invalid: Leading spaces on block marks\n  ```\n  Not a verbatim area.\n  The marks must be at the line beginning,\n  no leading spaces.\n  ```\n\n%%% Closing: EOF closes the open block\n```\nThe end of the file (EOF) closes\nthe currently open verbatim area.\n```\n\n= Definition List =[deflist]\n\nSee [List #list], the same rules apply.\n\n= Numbered List =[numlist]\n\nSee [List #list], the same rules apply.\n\n= List =[list]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/list.t2t\nBODYINIT\n\n%%% Items: Prefixed by hyphen\n- Use the hyphen to prefix list items.\n- There must be one space after the hyphen.\n- The list is closed by two consecutive blank lines.\n\n\n%%% Items: Free leading spacing (indentation)\n     - The list can be indented on the source document.\n     - You can use any number of spaces.\n     - The result will be the same.\n\n\n%%% Items: Vertical spacing between items\n- Let one blank line between the list items.\n\n- It will be maintained on the conversion.\n\n- Some targets don't support this behavior.\n\t   \t  \n- This one was separated by a line with blanks.\n  You can also put a blank line inside\n\n  the item contents and it will be preserved.\n\n\n%%% Items: Exactly ONE space after the hyphen\n-This is not a list (no space)\n\n-    This is not a list (more than one space)\n\n-\tThis is not a list (a TAB instead the space)\n\n\n%%% Items: Catchy cases\n- - This is a list\n- + This is a list\n- : This is a list\n\n\n%%% Nesting: Creating sublists\n- This is the \"mother\" list first item.\n- Here is the second, but inside this item,\n  - there is a sublist, with its own items.\n  - Note that the items of the same sublist\n  - must have the same indentation.\n    - And this can go on, opening sublists.\n      - Just add leading spaces before the\n      - hyphen and sublists will be opened.\n      - The two blank lines closes them all.\n\n\n%%% Nesting: Free leading spacing (indentation)\n- When nesting lists, the additional spaces are free.\n - You can add just one,\n        - or many.\n          - What matters is to put more than the previous.\n          - But remember that the other items of the same list\n          - must use the same indentation.\n\n\n%%% Nesting: Maximum depth\n- There is not a depth limit,\n  - you can go deeper and deeper.\n    - But some targets may have restrictions.\n      - The LaTeX maximum is here, 4 levels.\n        - This one and the following sublists\n          - are moved up to the level 4\n            - when converting to LaTeX.\n              - On the other targets,\n                - it is just fine\n                  - to have a very deep list.\n\n\n%%% Nesting: Reverse doesn't work\n        - Reverse nesting doesn't work.\n      - Because a sublist *must* have a mother list.\n    - It's the list concept, not a txt2tags limitation.\n  - All this sublists will be bumped to mother lists.\n- At level 1, like this one.\n\n\n%%% Nesting: Going deeper and back\n\n%% When nesting back to an upper level, the previous sublist\n%% is automatically closed.\n- Level 1\n  - Level 2\n    - Level 3\n      - Level 4\n    - Level 3 -- (closed Level 4)\n  - Level 2 -- (closed Level 3)\n- Level 1 -- (closed Level 2)\n\n\n%% More than one list can be closed when nesting back.\n- Level 1\n  - Level 2\n    - Level 3\n      - Level 4\n- Level 1 -- (closed Level 4, Level 3 and Level 2)\n\n\n%%% Nesting: Vertical spacing between lists\n- Level 1\n\n  - Level 2 -- blank BEFORE and AFTER (in)\n\n    - Level 3\n% comment lines are NOT considered blank lines\n      - Level 4\n% comment lines are NOT considered blank lines\n    - Level 3\n\n  - Level 2 -- blank BEFORE and AFTER (out)\n\n- Level 1\n        \n  - Level 2 -- blank BEFORE (spaces) and AFTER (TAB)\n\t\n    - Level 3\n\n\n%%% Nesting: Messing up\n%% Be careful when going back on the nesting,\n%% it must be on a valid level! If not, it will\n%% be bumped up to the previous valid level.\n- Level 1\n    - Level 2\n        - Level 3\n            - Level 4\n          - Level 3.5 ???\n        - Level 3\n      - Level 2.5 ???\n    - Level 2\n  - Level 1.5 ???\n- Level 1\n\n\n%%% Closing: Two (not so) empty lines\n- This list is closed by a line with spaces and other with TABs\n        \n\t\n- This list is NOT closed by two comment lines\n% comment lines are NOT considered blank lines\n% comment lines are NOT considered blank lines\n- This list is closed by a line with spaces and TAB,\n- then a comment line, then an empty line.\n\t      \t\n% comment lines are NOT considered blank lines\n\n%%% Closing: Empty item closes current (sub)list\n\n%% The two blank lines closes ALL the lists.\n%% To close just the current, use an empty item.\n- Level 1\n  - Level 2\n    - Level 3\n    -\n    Level 2\n  -  \n  Level 1\n-\n\n%% The empty item can have trailing blanks.\n- Empty item with trailing spaces.\n-    \n\n- Empty item with trailing TAB.\n-\t\n\n%%% Closing: EOF closes the lists\n- If the end of the file (EOF) is hit,\n  - all the currently opened list are closed,\n    - just like when using the two blank lines.\n\n\n= Table =[table]\n\n%INCLUDED(t2t) starts here: ../../../test/marks/table.t2t\nBODYINIT\n\n%%% Syntax: Lines starting with a pipe |\n| Cell 1\n\n%%% Syntax: Extra pipes separate cells\n| Cell 1 | Cell 2 | Cell 3\n\n%%% Syntax: With a trailing pipe, make border\n| Cell 1 | Cell 2 | Cell 3 |\n\n%%% Syntax: Table lines starting with double pipe are heading\n|| Cell 1 | Cell 2 | Cell 3 |\n\n%%% Align: Spaces before the leading pipe centralize the table\n   | Cell 1 | Cell 2 | Cell 3 |\n\n%%% Align: Spaces inside the cell denote its alignment\n   || Heading | Heading | Heading |\n% comments don't close an opened table   \n   | <-     |   --   |     -> |\n   |   --   |   --   |   --   |\n   |     -> |   --   | <-     |\n\n%%% Span: Column span is defined by extra pipes at cell closing\n   || 1  |  2  |    3+4   ||\n   |  1  |  2  |  3  |  4  |\n   |      1+2+3    |||  4  |\n   |  1  |    2+3   ||  4  |\n   |        1+2+3+4     ||||\n\n%%% Test: Empty cells are placed as expected\n   | 0 | 1 | 2 |   |\n   | 4 | 5 |   | 7 |\n   | 8 |   | A | B |\n   |   | D | E | F |\n\n%%% Test: Lines with different number of cells\n   | 1 |\n   | 1 | 2 |\n   | 1 | 2 | 3 |\n   | 1 | 2 | 3 | 4 |\n   | 1 | 2 | 3 | 4 | 5 |\n\n%%% Test: Empty cells + Span + Messy cell number = Fun!\n   |   Jan |\n   |   Fev ||\n   |   Mar |||\n   |   Apr ||||\n   |   May |||||\n   |  20%  |  40%  |  60%  |  80%  |  100%  |\n\n   |   |     |  /  |     |    |\n   |   |   / / / / /     |||  |\n   |  / / / / / / / / /  |||||\n   |   |  o  |     |  o  |    |\n   |   |     |   . |     |    |\n   |   |    = = = =    |||    |\n\n   | 01 | 02 |    |    | 05 |    | 07 |    |\n   |    |    | 11 |    | 13 |    |    | 16 |\n   | 17 |    | 19 | 20 |    |    | 23 |    |\n   | 25 | 26 |    |    | 29 | 30 |    | 32 |\n   |    |    | 35 |    | 37 |    | 39 | 40 |\n\n%%% Test: Lots of cells at the same line\n| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |\n\n%%% Test: Empty lines\n|   |\n|  |\n| |\n\n%%% Invalid: There must be at least one space around the pipe\n|this|is|not|a|table|\n\n|this| is| not| a| table|\n\n|this |is |not |a |table |\n\n%%% Invalid: You must use spaces, not TABs\n|\tthis\t|\tis\t|\tnot\t|\ta\t|\ttable\t|\n\n------------------------------------------------------------\n\nThe End.\n"
  },
  {
    "path": "Units/simple-windres.d/expected.tags",
    "content": "IDB_JUMP_TO_TAG\tinput.rc\t/^IDB_JUMP_TO_TAG  \tBITMAP\tDISCARDABLE\t\t\"Res\\/MainToolbar_JumpToTag.bmp\"$/;\"\tb\nIDB_REFRESH_TAGS\tinput.rc\t/^IDB_REFRESH_TAGS  \tBITMAP\tDISCARDABLE\t\t\"Res\\/MainToolbar_RefreshTags.bmp\"$/;\"\tb\nIDB_SHOW_TAGS\tinput.rc\t/^IDB_SHOW_TAGS\t  \tBITMAP\tDISCARDABLE\t\t\"Res\\/MainToolbar_ShowTags.bmp\"$/;\"\tb\nIDCM_TAGS_TREE\tinput.rc\t/^IDCM_TAGS_TREE MENU PRELOAD DISCARDABLE$/;\"\tm\nIDC_LINK_CURSOR\tinput.rc\t/^IDC_LINK_CURSOR\t\tCURSOR  DISCARDABLE     \"res\\\\\\\\link_cur.cur\"$/;\"\tc\nIDD_ABOUTBOX\tinput.rc\t/^IDD_ABOUTBOX DIALOGEX 0, 0, 224, 187$/;\"\td\nIDD_SELECT_TAG\tinput.rc\t/^IDD_SELECT_TAG DIALOGEX 0, 0, 365, 143$/;\"\td\nIDD_TAGS_TREE\tinput.rc\t/^IDD_TAGS_TREE DIALOGEX 0, 0, 190, 90$/;\"\td\nIDF_CM_ROMAN\tinput.rc\t/^IDF_CM_ROMAN\t\tFONT\t\"cmroman.fnt\"$/;\"\tf\nIDI_TAGS\tinput.rc\t/^IDI_TAGS\t\t\tICON\tDISCARDABLE\t\t\"Res\\/NppTags.ico\"$/;\"\ti\nIDR_MAINFRAME\tinput.rc\t/^IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE $/;\"\ta\nVS_VERSION_INFO\tinput.rc\t/^VS_VERSION_INFO VERSIONINFO$/;\"\tv\n"
  },
  {
    "path": "Units/simple-windres.d/input.rc",
    "content": "/////////////////////////////////////////////////////////////////////////////\n//                                                                         //\n//  NppTags - CTags plugin for Notepad++                                   //\n//  Copyright (C) 2013 Frank Fesevur                                       //\n//                                                                         //\n//  This program is free software; you can redistribute it and/or modify   //\n//  it under the terms of the GNU General Public License as published by   //\n//  the Free Software Foundation; either version 2 of the License, or      //\n//  (at your option) any later version.                                    //\n//                                                                         //\n//  This program is distributed in the hope that it will be useful,        //\n//  but WITHOUT ANY WARRANTY; without even the implied warranty of         //\n//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the           //\n//  GNU General Public License for more details.                           //\n//                                                                         //\n//  You should have received a copy of the GNU General Public License      //\n//  along with this program; if not, write to the Free Software            //\n//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              //\n//                                                                         //\n/////////////////////////////////////////////////////////////////////////////\n\n#include <windows.h>\n#include <commctrl.h>\n#include \"Resource.h\"\n#include \"Version.h\"\n#include \"sqlite3.h\"\n\n/////////////////////////////////////////////////////////////////////////////\n// Version Information\n\nVS_VERSION_INFO VERSIONINFO\nFILEVERSION\tVERSION_NUMBER\nPRODUCTVERSION\tVERSION_NUMBER\nFILEFLAGSMASK\t0x3fL\nFILEFLAGS 0\nFILEOS VOS_NT_WINDOWS32\nFILETYPE VFT_APP\nFILESUBTYPE VFT2_UNKNOWN\n{\n\tBLOCK\t\"VarFileInfo\"\n\t{\n\t\tVALUE\t\"Translation\",\t0x409,\t1200\n\t}\n\tBLOCK\t\"StringFileInfo\"\n\t{\n\t\tBLOCK \"040904b0\"\n\t\t{\n\t\t\tVALUE\t\"CompanyName\",\t\t\t\"Frank Fesevur\"\n\t\t\tVALUE\t\"FileDescription\",\t\t\"CTags plug-in for Notepad++\"\n\t\t\tVALUE\t\"FileVersion\",\t\t\tVERSION_NUMBER_STR\n\t\t\tVALUE\t\"InternalName\",\t\t\t\"NppTags.dll\"\n\t\t\tVALUE\t\"LegalCopyright\",\t\tCOPYRIGHT_STR\n\t\t\tVALUE\t\"OriginalFilename\",\t\t\"NppTags.dll\"\n\t\t\tVALUE\t\"ProductName\",\t\t\t\"NppTags\"\n\t\t\tVALUE\t\"ProductVersion\",\t\tVERSION_NUMBER_STR\n\t\t}\n\t}\n}\n\n/////////////////////////////////////////////////////////////////////////////\n// Dialogs\n\nIDD_ABOUTBOX DIALOGEX 0, 0, 224, 187\nSTYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_BORDER | WS_SYSMENU\nFONT 8, \"MS Shell Dlg\", 0, 0, 0x1\n{\n\tGROUPBOX\t\t\"Exuberant CTags plug-in\",IDC_STATIC,10,9,201,154,BS_CENTER\n\tLTEXT\t\t\t\"Author:\",IDC_STATIC,30,23,35,8\n\tLTEXT\t\t\t\"Frank Fesevur\",IDC_STATIC,75,23,74,8\n\tLTEXT\t\t\t\"Version:\",IDC_STATIC,30,38,31,8\n\tLTEXT\t\t\tVERSION_NUMBER_STR,IDC_STATIC,75,38,19,8\n\tLTEXT\t\t\t\"Using SQLite:\",IDC_STATIC,30,52,43,8\n\tLTEXT\t\t\tSQLITE_VERSION,IDC_STATIC,75,52,43,8\n\tLTEXT\t\t\t\"Licence:\",IDC_STATIC,30,67,43,8\n\tLTEXT\t\t\t\"GPL-2\",IDC_STATIC,75,67,43,8\n\tLTEXT\t\t\t\"Site:\",IDC_STATIC,30,84,27,8\n\tCONTROL\t\t\t\"<a href=\"\"http://www.fesevur.com/nppsnippets\"\">http://www.fesevur.com/nppsnippets</a>\",IDC_SYSLINK,\"SysLink\",NOT WS_TABSTOP,75,84,130,8\n\tEDITTEXT\t\tIDC_CHANGELOG,29,97,175,61,ES_MULTILINE | ES_AUTOVSCROLL | NOT ES_AUTOHSCROLL | ES_READONLY | ES_WANTRETURN | WS_VSCROLL | NOT WS_TABSTOP\n\tPUSHBUTTON\t\t\"Close\",IDCANCEL,86,167,50,14\n}\n\nIDD_TAGS_TREE DIALOGEX 0, 0, 190, 90\nSTYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\nCAPTION \"Tags\"\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\n{\n\tCONTROL\t\t\t\"Tree1\",IDC_TREE,\"SysTreeView32\", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_INFOTIP | WS_BORDER | WS_TABSTOP, 0, 7, 186, 90\n}\n\nIDD_SELECT_TAG DIALOGEX 0, 0, 365, 143\nSTYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU\nCAPTION \"Select Tag\"\nFONT 8, \"MS Shell Dlg\", 0, 0, 0x1\n{\n\tCONTROL\t\t\t\"List1\", IDC_TAG_LIST, \"SysListView32\", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOLABELWRAP | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 7, 7, 351, 109\n\tDEFPUSHBUTTON\t\"&Goto\",IDOK,93,122,50,14\n\tPUSHBUTTON\t\t\"&Cancel\",IDCANCEL,153,122,50,14\n}\n\n/////////////////////////////////////////////////////////////////////////////\n// Context Menus\n\nIDCM_TAGS_TREE MENU PRELOAD DISCARDABLE\n{\n\tPOPUP \"_POPUP_\"\n\t{\n\t\tMENUITEM \"&Jump to Tag\",\t\t\t\tIDC_JUMP_TO_TAG\n\t\tMENUITEM SEPARATOR\n\t\tMENUITEM \"&Generate tags database\",\t\tIDC_REFRESH_TAGS\n\t\tMENUITEM SEPARATOR\n\t\tMENUITEM \"&Database options...\",\t\tIDC_DATABASE_OPTIONS\n\t\tMENUITEM SEPARATOR\n\t\tMENUITEM \"&Tag properties...\",\t\t\tIDC_TAG_PROPERTIES\n\t}\n}\n\n/////////////////////////////////////////////////////////////////////////////\n// Bitmaps\n\nIDB_SHOW_TAGS\t  \tBITMAP\tDISCARDABLE\t\t\"Res/MainToolbar_ShowTags.bmp\"\nIDB_REFRESH_TAGS  \tBITMAP\tDISCARDABLE\t\t\"Res/MainToolbar_RefreshTags.bmp\"\nIDB_JUMP_TO_TAG  \tBITMAP\tDISCARDABLE\t\t\"Res/MainToolbar_JumpToTag.bmp\"\n\n/////////////////////////////////////////////////////////////////////////////\n// Icons\n\nIDI_TAGS\t\t\tICON\tDISCARDABLE\t\t\"Res/NppTags.ico\"\n\n/* Testing an Accelerator and multi line comments */\n\nIDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE \nBEGIN\n    \"P\",            ID_FILE_PRINT,          VIRTKEY, CONTROL, NOINVERT\n    \"S\",            ID_FILE_SAVE_AS,        VIRTKEY, CONTROL, NOINVERT\n    \"U\",            ID_EDIT_COPYURL,        VIRTKEY, CONTROL, NOINVERT\n    \"V\",            ID_EDIT_PASTE,          VIRTKEY, CONTROL, NOINVERT\n    VK_F1,          ID_HELP,                VIRTKEY, NOINVERT\n    VK_F1,          ID_CONTEXT_HELP,        VIRTKEY, SHIFT, NOINVERT\n    VK_INSERT,      ID_EDIT_PASTE,          VIRTKEY, SHIFT, NOINVERT\n    VK_RETURN,      ID_FILE_PROPERTIES,     VIRTKEY, ALT, NOINVERT\nEND\n\n/////////////////////////////////////////////////////////////////////////////\n// And put a CURSOR in it as well\n\nIDC_LINK_CURSOR\t\tCURSOR  DISCARDABLE     \"res\\\\link_cur.cur\"\n\n/* And don't forget a font file */\n\nIDF_CM_ROMAN\t\tFONT\t\"cmroman.fnt\"\n"
  },
  {
    "path": "Units/simple-xrc.d/args.ctags",
    "content": "--sort=no\n"
  },
  {
    "path": "Units/simple-xrc.d/expected.tags",
    "content": "frame_view\tinput.xrc\t/^  <object class=\"wxFrame\" name=\"frame_view\" subclass=\"hachoir.wx.frame_view.frame_view_t\">$/;\"\to\nmain_menu_bar\tinput.xrc\t/^    <object class=\"wxMenuBar\" name=\"main_menu_bar\">$/;\"\to\nfile_menu\tinput.xrc\t/^      <object class=\"wxMenu\" name=\"file_menu\">$/;\"\to\nfile_menu_open_file\tinput.xrc\t/^        <object class=\"wxMenuItem\" name=\"file_menu_open_file\">$/;\"\to\nfile_menu_close_window\tinput.xrc\t/^        <object class=\"wxMenuItem\" name=\"file_menu_close_window\">$/;\"\to\ntree_view\tinput.xrc\t/^      <object class=\"wxTreeCtrl\" name=\"tree_view\" subclass=\"hachoir.wx.tree_view.tree_view_t\">$/;\"\to\nhex_view\tinput.xrc\t/^        <object class=\"wxScrolledWindow\" name=\"hex_view\" subclass=\"hachoir.wx.hex_view.hex_view_/;\"\to\nfield_view\tinput.xrc\t/^        <object class=\"wxListCtrl\" name=\"field_view\" subclass=\"hachoir.wx.field_view.field_view_/;\"\to\nfield_menu\tinput.xrc\t/^  <object class=\"wxMenu\" name=\"field_menu\">$/;\"\to\nfield_menu_split\tinput.xrc\t/^    <object class=\"wxMenu\" name=\"field_menu_split\">$/;\"\to\nfield_menu_split_bytes\tinput.xrc\t/^      <object class=\"wxMenuItem\" name=\"field_menu_split_bytes\">$/;\"\to\nfield_menu_split_bits\tinput.xrc\t/^      <object class=\"wxMenuItem\" name=\"field_menu_split_bits\">$/;\"\to\nfield_menu_convert_to_core_type\tinput.xrc\t/^    <object class=\"wxMenu\" name=\"field_menu_convert_to_core_type\">$/;\"\to\nfield_menu_dump_to_disk\tinput.xrc\t/^    <object class=\"wxMenuItem\" name=\"field_menu_dump_to_disk\">$/;\"\to\nfield_menu_parse_substream\tinput.xrc\t/^    <object class=\"wxMenuItem\" name=\"field_menu_parse_substream\">$/;\"\to\nfield_menu_open_window_here\tinput.xrc\t/^    <object class=\"wxMenuItem\" name=\"field_menu_open_window_here\">$/;\"\to\nfield_menu_address\tinput.xrc\t/^    <object class=\"wxMenu\" name=\"field_menu_address\">$/;\"\to\nfield_menu_address_absolute\tinput.xrc\t/^      <object class=\"wxMenuItem\" name=\"field_menu_address_absolute\">$/;\"\to\nfield_menu_address_relative\tinput.xrc\t/^      <object class=\"wxMenuItem\" name=\"field_menu_address_relative\">$/;\"\to\nfield_menu_address_base\tinput.xrc\t/^    <object class=\"wxMenu\" name=\"field_menu_address_base\">$/;\"\to\nfield_menu_address_base_hex\tinput.xrc\t/^      <object class=\"wxMenuItem\" name=\"field_menu_address_base_hex\">$/;\"\to\nfield_menu_address_base_dec\tinput.xrc\t/^      <object class=\"wxMenuItem\" name=\"field_menu_address_base_dec\">$/;\"\to\n"
  },
  {
    "path": "Units/simple-xrc.d/features",
    "content": "xpath\n"
  },
  {
    "path": "Units/simple-xrc.d/input.xrc",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Taken from hachoir/wx/resource/hachoir_wx.xrc -->\n<resource>\n  <object class=\"wxFrame\" name=\"frame_view\" subclass=\"hachoir.wx.frame_view.frame_view_t\">\n    <title></title>\n    <object class=\"wxMenuBar\" name=\"main_menu_bar\">\n      <object class=\"wxMenu\" name=\"file_menu\">\n        <label>File</label>\n        <object class=\"wxMenuItem\" name=\"file_menu_open_file\">\n          <label>Open File...</label>\n          <accel>Ctrl-O</accel>\n        </object>\n        <object class=\"wxMenuItem\" name=\"file_menu_close_window\">\n          <label>Close Window</label>\n          <accel>Ctrl-W</accel>\n        </object>\n      </object>\n    </object>\n    <size>800, 600</size>\n    <style>wxDEFAULT_FRAME_STYLE</style>\n    <object class=\"wxSplitterWindow\" name=\"\">\n      <orientation>vertical</orientation>\n      <sashpos>150</sashpos>\n      <style>wxSP_LIVE_UPDATE</style>\n      <object class=\"wxTreeCtrl\" name=\"tree_view\" subclass=\"hachoir.wx.tree_view.tree_view_t\">\n        <style>wxTR_TWIST_BUTTONS|wxTR_SINGLE|wxTR_DEFAULT_STYLE</style>\n      </object>\n      <object class=\"wxSplitterWindow\" name=\"\">\n        <orientation>horizontal</orientation>\n        <object class=\"wxScrolledWindow\" name=\"hex_view\" subclass=\"hachoir.wx.hex_view.hex_view_t\">\n          <style>wxVSCROLL</style>\n          <font>\n            <size>11</size>\n            <family>modern</family>\n            <style>normal</style>\n            <weight>normal</weight>\n            <underlined>0</underlined>\n            <face>Monaco</face>\n          </font>\n        </object>\n        <object class=\"wxListCtrl\" name=\"field_view\" subclass=\"hachoir.wx.field_view.field_view_t\">\n          <style>wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VIRTUAL|wxLC_HRULES|wxLC_VRULES</style>\n          <font>\n            <size>11</size>\n            <family>modern</family>\n            <style>normal</style>\n            <weight>normal</weight>\n            <underlined>0</underlined>\n            <face>Monaco</face>\n          </font>\n          <tooltip>Right-click for extra fun!</tooltip>\n        </object>\n        <sashpos>200</sashpos>\n        <style>wxSP_LIVE_UPDATE</style>\n      </object>\n    </object>\n  </object>\n  <object class=\"wxMenu\" name=\"field_menu\">\n    <label>Field</label>\n    <object class=\"wxMenu\" name=\"field_menu_split\">\n      <label>Split</label>\n      <object class=\"wxMenuItem\" name=\"field_menu_split_bytes\">\n        <label>Bytes...</label>\n      </object>\n      <object class=\"wxMenuItem\" name=\"field_menu_split_bits\">\n        <label>Bits...</label>\n      </object>\n    </object>\n    <object class=\"wxMenu\" name=\"field_menu_convert_to_core_type\">\n      <label>Convert to Core Type</label>\n    </object>\n    <object class=\"wxMenuItem\" name=\"field_menu_dump_to_disk\">\n      <label>Dump To Disk...</label>\n    </object>\n    <object class=\"wxMenuItem\" name=\"field_menu_parse_substream\">\n      <label>Parse Sub-Stream</label>\n    </object>\n    <object class=\"wxMenuItem\" name=\"field_menu_open_window_here\">\n      <label>Open New Window Here</label>\n    </object>\n    <object class=\"separator\"/>\n    <object class=\"wxMenu\" name=\"field_menu_address\">\n      <label>Address Offset</label>\n      <object class=\"wxMenuItem\" name=\"field_menu_address_absolute\">\n        <label>Absolute</label>\n        <radio>1</radio>\n        <checked>1</checked>\n      </object>\n      <object class=\"wxMenuItem\" name=\"field_menu_address_relative\">\n        <label>Relative</label>\n        <radio>1</radio>\n      </object>\n    </object>\n    <object class=\"wxMenu\" name=\"field_menu_address_base\">\n      <label>Address Base</label>\n      <object class=\"wxMenuItem\" name=\"field_menu_address_base_hex\">\n        <label>Hexadecimal</label>\n        <radio>1</radio>\n        <checked>1</checked>\n      </object>\n      <object class=\"wxMenuItem\" name=\"field_menu_address_base_dec\">\n        <label>Decimal</label>\n        <radio>1</radio>\n      </object>\n    </object>\n  </object>\n</resource>\n"
  },
  {
    "path": "Units/simple-xref.d/expected.tags-x",
    "content": "foo              function      2 input.c int foo (void) { return 0; }\nmain             function      1 input.c int main(void) { return 0; }\n"
  },
  {
    "path": "Units/simple-xref.d/input.c",
    "content": "int main(void) { return 0; }\nint foo (void) { return 0; }\n"
  },
  {
    "path": "Units/simple-yumrepo.d/args.ctags",
    "content": "--sort=no\n--fields=+lK\n--languages=-Iniconf\n"
  },
  {
    "path": "Units/simple-yumrepo.d/expected.tags",
    "content": "fedora\tinput.repo\t/^[fedora]$/;\"\trepoid\tlanguage:YumRepo\nfedora-debuginfo\tinput.repo\t/^[fedora-debuginfo]$/;\"\trepoid\tlanguage:YumRepo\nfedora-source\tinput.repo\t/^[fedora-source]$/;\"\trepoid\tlanguage:YumRepo\n"
  },
  {
    "path": "Units/simple-yumrepo.d/input.repo",
    "content": "[fedora]\nname=Fedora $releasever - $basearch\nfailovermethod=priority\n#baseurl=http://download.fedoraproject.org/pub/fedora/linux/releases/$releasever/Everything/$basearch/os/\nmetalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch\nenabled=1\n#metadata_expire=7d\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch\nskip_if_unavailable=False\n\n[fedora-debuginfo]\nname=Fedora $releasever - $basearch - Debug\nfailovermethod=priority\n#baseurl=http://download.fedoraproject.org/pub/fedora/linux/releases/$releasever/Everything/$basearch/debug/\nmetalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-debug-$releasever&arch=$basearch\nenabled=1\nmetadata_expire=7d\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch\nskip_if_unavailable=False\n\n[fedora-source]\nname=Fedora $releasever - Source\nfailovermethod=priority\n#baseurl=http://download.fedoraproject.org/pub/fedora/linux/releases/$releasever/Everything/source/SRPMS/\nmetalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-source-$releasever&arch=$basearch\nenabled=1\nmetadata_expire=7d\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch\nskip_if_unavailable=False\n"
  },
  {
    "path": "Units/unit-example-multi-inputs.d/args.ctags",
    "content": "--sort=no\n--fields=+l\n"
  },
  {
    "path": "Units/unit-example-multi-inputs.d/expected.tags",
    "content": "main\tinput.c\t/^main(void)$/;\"\tf\tlanguage:C\ttyperef:typename:int\npoint\tinput-0.h\t/^struct point {$/;\"\ts\tlanguage:C++\nx\tinput-0.h\t/^\tint x;$/;\"\tm\tlanguage:C++\tstruct:point\ttyperef:typename:int\ny\tinput-0.h\t/^\tint y;$/;\"\tm\tlanguage:C++\tstruct:point\ttyperef:typename:int\nshell_func\tinput-1.sh\t/^function shell_func$/;\"\tf\tlanguage:Sh\n__anon3cd860c60108\tinput-2.c\t/^struct {$/;\"\ts\tlanguage:C\tfile:\nname\tinput-2.c\t/^\tchar *name;$/;\"\tm\tlanguage:C\tstruct:__anon3cd860c60108\ttyperef:typename:char *\tfile:\nx\tinput-2.c\t/^} x;$/;\"\tv\tlanguage:C\ttyperef:struct:__anon3cd860c60108\n__anon3cd865070108\tinput-3.c\t/^struct {$/;\"\ts\tlanguage:C\tfile:\nage\tinput-3.c\t/^\tint age;$/;\"\tm\tlanguage:C\tstruct:__anon3cd865070108\ttyperef:typename:int\tfile:\ny\tinput-3.c\t/^} y;$/;\"\tv\tlanguage:C\ttyperef:struct:__anon3cd865070108\n"
  },
  {
    "path": "Units/unit-example-multi-inputs.d/input-0.h",
    "content": "struct point {\n\tint x;\n\tint y;\n};\n"
  },
  {
    "path": "Units/unit-example-multi-inputs.d/input-1.sh",
    "content": "function shell_func\n{\n\t:\n}\n"
  },
  {
    "path": "Units/unit-example-multi-inputs.d/input-2.c",
    "content": "struct {\n\tchar *name;\n} x;\n"
  },
  {
    "path": "Units/unit-example-multi-inputs.d/input-3.c",
    "content": "struct {\n\tint age;\n} y;\n"
  },
  {
    "path": "Units/unit-example-multi-inputs.d/input.c",
    "content": "#include \"input-0.h\"\n\nint\nmain(void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Units/writer-ctags.r/output-field-escaping.d/args.ctags",
    "content": "--sort=no\n--fields=+{scope}\n"
  },
  {
    "path": "Units/writer-ctags.r/output-field-escaping.d/expected.tags",
    "content": "\\x01level1\tinput.rst\t/^\u0001level1$/;\"\tc\nlevel2\tinput.rst\t/^level2$/;\"\ts\tscope:chapter:\\x01level1\n\\x21level3\\x03\tinput.rst\t/^!level3\u0003$/;\"\tS\tscope:section:level2\n\\x21level1+\tinput.rst\t/^!level1+$/;\"\tc\nlevel2+\tinput.rst\t/^level2+$/;\"\ts\tscope:chapter:!level1+\n\\x02level3+\\x04\tinput.rst\t/^\u0002level3+\u0004$/;\"\tS\tscope:section:level2+\n"
  },
  {
    "path": "Units/writer-ctags.r/output-field-escaping.d/input.rst",
    "content": "\u0001level1\n=================\n\nlevel2\n-----------------\n\n!level3\u0003\n.................\n\n!level1+\n=================\n\nlevel2+\n-----------------\n\n\u0002level3+\u0004\n.................\n"
  },
  {
    "path": "Units/writer-ctags.r/output-field-escaping.d/minitrip",
    "content": ""
  },
  {
    "path": "Units/writer-etags.r/cork-etags.d/expected.tags-e",
    "content": "\f\ninput.clj,125\n(ns app.controller)app.controller\u00011,0\n (defn empty-fn [])empty-fn\u00013,21\n(defn function-with-body []function-with-body\u00015,42\n"
  },
  {
    "path": "Units/writer-etags.r/cork-etags.d/input.clj",
    "content": "(ns app.controller)\n\n (defn empty-fn [])\n\n(defn function-with-body []\n    (println \"body\"))\n\n'(defn quoted-function [])\n(quote quoted-function2 [])\n"
  },
  {
    "path": "Units/writer-etags.r/simple-etags.d/expected.tags-e",
    "content": "\f\ninput.c,76\nint main(void) { return 0; }main\u00011,0\nint foo (void) { return 0; }foo\u00012,29\n"
  },
  {
    "path": "Units/writer-etags.r/simple-etags.d/input.c",
    "content": "int main(void) { return 0; }\nint foo (void) { return 0; }\n"
  },
  {
    "path": "Units/writer-json.r/fq-json.d/args.ctags",
    "content": "--fields=NFPE\n--extra=+q\n"
  },
  {
    "path": "Units/writer-json.r/fq-json.d/expected.tags-json",
    "content": "{\"_type\": \"tag\", \"name\": \"A\", \"path\": \"input.py\", \"pattern\": \"/^class A:$/\"}\n{\"_type\": \"tag\", \"name\": \"A.f\", \"path\": \"input.py\", \"pattern\": \"/^    def f():$/\", \"extras\": \"qualified\"}\n{\"_type\": \"tag\", \"name\": \"f\", \"path\": \"input.py\", \"pattern\": \"/^    def f():$/\"}\n"
  },
  {
    "path": "Units/writer-json.r/fq-json.d/input.py",
    "content": "class A:\n    def f():\n        pass\n"
  },
  {
    "path": "Units/writer-xref.r/cork-xref.d/expected.tags-x",
    "content": "app.controller   namespace     1 input.clj (ns app.controller)\nempty-fn         function      3 input.clj (defn empty-fn [])\nfunction-with-body function      5 input.clj (defn function-with-body []\n"
  },
  {
    "path": "Units/writer-xref.r/cork-xref.d/input.clj",
    "content": "(ns app.controller)\n\n (defn empty-fn [])\n\n(defn function-with-body []\n    (println \"body\"))\n\n'(defn quoted-function [])\n(quote quoted-function2 [])\n"
  },
  {
    "path": "Units/writer-xref.r/format-CfSt.d/args.ctags",
    "content": "--_xformat=%-10N%-10S %t,%5f => %10C\n"
  },
  {
    "path": "Units/writer-xref.r/format-CfSt.d/expected.tags-x",
    "content": "S         -          -, file =>  struct S{\nT         -          typename:S, file => typedef S T;\nfunc      (T x)      typename:int,    - => int func (T x)\ni         -          typename:int, file =>     int i;\nt0        -          struct:S, file => static struct S t0;\nt0        -          typename:T, file => static T t0;\n"
  },
  {
    "path": "Units/writer-xref.r/format-CfSt.d/input.c",
    "content": "struct S{\n  int i;\n};\n\ntypedef S T;\n\nstatic T t0;\nstatic struct S t0;\n\nint func (T x)\n{\n  return 0;\n}\n"
  },
  {
    "path": "Units/writer-xref.r/format-NlKkFnP.d/args.ctags",
    "content": "--sort=no\n--_xformat=%14N %l:%K(%k) %F %n - %C\n\n\n"
  },
  {
    "path": "Units/writer-xref.r/format-NlKkFnP.d/expected.tags-x",
    "content": "             X ObjectiveC:protocol(P) input.m 1 - @protocol X\n   doSomething ObjectiveC:method(m) input.m 2 - - doSomething;\n             A ObjectiveC:interface(i) input.m 5 - @interface A: NSObject\n       aMethod ObjectiveC:method(m) input.m 6 - - aMethod;\n             B ObjectiveC:interface(i) input.m 9 - @interface B: A <X>\n             i ObjectiveC:field(E) input.m 12 - int i;\n             j ObjectiveC:field(E) input.m 14 - int j;\n             x ObjectiveC:function(f) input.m 18 - static int x(void)\n             y ObjectiveC:function(f) input.m 23 - int y(void)\n             B ObjectiveC:implementation(I) input.m 28 - @implementation B\n       aMethod ObjectiveC:method(m) input.m 29 - - aMethod\n   doSomething ObjectiveC:method(m) input.m 33 - - doSomething\n"
  },
  {
    "path": "Units/writer-xref.r/format-NlKkFnP.d/filter",
    "content": "#!/bin/sh\nsed -e 's|\\.\\{1,\\}/.*/input.m|input.m|'\n"
  },
  {
    "path": "Units/writer-xref.r/format-NlKkFnP.d/input.m",
    "content": "@protocol X\n- doSomething;\n@end\n\n@interface A: NSObject\n- aMethod;\n@end\n\n@interface B: A <X>\n{\n@public\n  int i;\n@private\n  int j;\n}\n@end\n\nstatic int x(void)\n{\n  return 0;\n}\n\nint y(void)\n{\n  return 1;\n}\n\n@implementation B\n- aMethod\n{\n  return nil;\n}\n- doSomething\n{\n  return self;\n}\n@end\n"
  },
  {
    "path": "Units/writer-xref.r/format-aim.d/args.ctags",
    "content": "--_xformat=%-10N <access = %10a, parent = %10i, impl = %10m>\n"
  },
  {
    "path": "Units/writer-xref.r/format-aim.d/expected.tags-x",
    "content": "getTarget  <access =    private, parent =          -, impl =          ->\ninput      <access =          -, parent =     Object, impl =          ->\nlife       <access =  protected, parent =          -, impl =   abstract>\nmain       <access =     public, parent =          -, impl =          ->\n"
  },
  {
    "path": "Units/writer-xref.r/format-aim.d/input.java",
    "content": "public class input extends Object\n{\n    private static String getTarget ()\n    {\n\treturn \"world\";\n    }\n\n    abstract protected static int life ();\n\n    public static void main(String[] args)\n    {\n        System.out.println(\"Hello, \"+input.getTarget()+\".\");\n    }\n}\n"
  },
  {
    "path": "Units/writer-xref.r/fq-xref.d/args.ctags",
    "content": "--extra=+q\n"
  },
  {
    "path": "Units/writer-xref.r/fq-xref.d/expected.tags-x",
    "content": "A                class         1 input.py class A:\nA.f              member        2 input.py def f():\nf                member        2 input.py def f():\n"
  },
  {
    "path": "Units/writer-xref.r/fq-xref.d/input.py",
    "content": "class A:\n    def f():\n        pass\n"
  },
  {
    "path": "Units/writer-xref.r/ptag-xref.d/args.ctags",
    "content": "--extras=+p\n--pseudo-tags=-TAG_PROGRAM_VERSION\n"
  },
  {
    "path": "Units/writer-xref.r/ptag-xref.d/expected.tags-x",
    "content": "!_TAG_FILE_FORMAT ptag          0 2                extended format; --format=1 will not append ;\" to lines\n!_TAG_FILE_SORTED ptag          0 1                0=unsorted, 1=sorted, 2=foldcase\n!_TAG_OUTPUT_FILESEP ptag          0 slash            slash or backslash\n!_TAG_OUTPUT_MODE ptag          0                  u-ctags or e-ctags\n!_TAG_PROGRAM_AUTHOR ptag          0 Universal Ctags Team \n!_TAG_PROGRAM_NAME ptag          0 Universal Ctags  Derived from Exuberant Ctags\n!_TAG_PROGRAM_URL ptag          0 https://ctags.io/ official site\nmain             function      1 input.c int main (void)\n"
  },
  {
    "path": "Units/writer-xref.r/ptag-xref.d/input.c",
    "content": "int main (void)\n{\n\treturn 0;\n}\n"
  },
  {
    "path": "Units/writer-xref.r/truncation.d/args.ctags",
    "content": "--_xformat=%N %.32C %-.16C\n"
  },
  {
    "path": "Units/writer-xref.r/truncation.d/expected.tags-x",
    "content": "foo foo(int a, int b, int c, int d,  foo(int a, int b\n"
  },
  {
    "path": "Units/writer-xref.r/truncation.d/input.c",
    "content": "int\nfoo(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m)\n{\n}\n"
  },
  {
    "path": "appveyor.yml",
    "content": "version: 1.0.{build}\n\nenvironment:\n  matrix:\n    - compiler: msbuild\n      CONFIGURATION: Release\n    # - compiler: msys2\n    #   ARCH: x64\n    #   MSYS2_ARCH: x86_64\n    #   MSYS2_DIR: msys64\n    #   MSYSTEM: MINGW64\n    # - compiler: msys2\n    #   ARCH: x86\n    #   MSYS2_ARCH: i686\n    #   MSYS2_DIR: msys64\n    #   MSYSTEM: MINGW32\n    - compiler: msvc\n      ARCH: x64\n      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019\n    #- compiler: msvc\n    #  ARCH: x86\n    - compiler: mingw\n    #- compiler: cygwin\n\nbuild_script:\n  - '%APPVEYOR_BUILD_FOLDER%\\win32\\appveyor.bat build'\n\nafter_build:\n  - '%APPVEYOR_BUILD_FOLDER%\\win32\\appveyor.bat package'\n\ntest_script:\n  - '%APPVEYOR_BUILD_FOLDER%\\win32\\appveyor.bat test'\n\nartifacts:\n  - path: ctags-*.zip\n"
  },
  {
    "path": "autogen.sh",
    "content": "#!/bin/sh\n\n# Report the paths causing trouble frequently\necho '##################################################################'\necho '#                The paths and versions for tools                #'\necho '##################################################################'\nfor t in autoreconf aclocal pkg-config autoconf automake; do\n\tif type $t; then\n\t\techo '------------------------------------------------------------------'\n\t\t$t --version\n\tfi\n\techo '##################################################################'\ndone\n\nif [ -e ./aclocal.m4 ]; then\n\techo '#             Renaming aclocal.m4 to last-aclocal.m4             #'\n\tmv ./aclocal.m4 ./last-aclocal.m4\n\techo '##################################################################'\nfi\n\necho '#                        Generating files                        #'\necho '##################################################################'\n\nset -e\t# errexit (exit on error)\nif [ ! -z \"${CI}\" ]; then\n\tset -x\t# xtrace (execution trace)\nfi\n\ntype autoreconf > /dev/null 2>&1 || {\n\techo \"No autotools (autoconf and automake) found\" 1>&2\n\texit 1\n}\ntype pkg-config > /dev/null 2>&1 || {\n\techo \"No pkg-config found\" 1>&2\n\texit 1\n}\n\nautoreconf -vfi\n"
  },
  {
    "path": "circle.yml",
    "content": "version: 2\njobs:\n  #\n  # This is for the latest RELEASED Fedora.\n  # Update the version of Fedora when new version is released.\n  # We don't use rawhide, the development version of Fedora\n  # till the list of TODO items of u-ctags becomes nil.\n  #\n  # We assume GNU Make is available.\n  #\n   fedora43_gmake:\n     working_directory: ~/universal-ctags\n     docker:\n       - image: docker.io/fedora:43\n     steps:\n       - run:\n           name: Install Git, Gdb and Procps-NG\n           command: |\n             yum -y install git gdb procps-ng\n       - checkout\n       - run:\n           name: Install tools for building ctags and validating test input files\n           command: |\n             dnf -y install awk gcc automake autoconf pkgconfig make libseccomp-devel libxml2-devel jansson-devel libyaml-devel pcre2-devel findutils diffutils sudo\n             dnf -y install python3-sphinx\n             # These are for input-validation.\n             dnf -y install g++ jq puppet nodejs gcc-gfortran gcc-gnat typescript swi-prolog rubypick golang-bin\n             # nodejs requires libsqlite.so.0 with sqlite-session feature\n             # It was turned off in 3.46.1-1.\n             dnf -y update sqlite-libs\n       - run:\n           name: Build\n           command: |\n             bash ./autogen.sh\n             ./configure --enable-debugging\n             make -j 2\n       - run:\n           name: Test\n           command: |\n             make check validate-input\n       - run:\n           name: Make HTML documents\n           command: |\n             cd docs\n             make html\n\n   fedora43_gmake_roundtrip:\n     working_directory: ~/universal-ctags\n     docker:\n       - image: docker.io/fedora:43\n     steps:\n       - run:\n           name: Install Git and Gdb\n           command: |\n             yum -y install git gdb\n       - checkout\n       - run:\n           name: Install build tools\n           command: |\n             dnf -y install awk gcc automake autoconf pkgconfig make libseccomp-devel libxml2-devel jansson-devel libyaml-devel pcre2-devel findutils diffutils sudo\n             dnf -y install jq puppet\n       - run:\n           name: Build\n           command: |\n             bash ./autogen.sh\n             ./configure --enable-debugging\n             make -j 2\n       - run:\n           name: Test\n           command: |\n             make roundtrip\n\n  #\n  # We assume GNU make as the `make` command as we use GNU make extension\n  # aggressively in man/Makefile and win32/Makefile.\n  #\n  # man/Makefile is used to generate man files only when rst2man is installed.\n  # win32/Makefile is used only when either source.mk or win32/*.in is updated.\n  # In other cases we can still build ctags without GNU make.\n  #\n  # The following tests use bmake (NetBSD make) to check if GNU make extensions\n  # are not used unintentionally.\n  #\n  # On Fedora 31 bmake package cannot be installed because a package required by\n  # bmake is not available. More inspection is needed. Fedora 30 is the last\n  # version where bmake can be installed.\n  #\n   fedora30_bmake:\n     working_directory: ~/universal-ctags\n     docker:\n       - image: docker.io/fedora:30\n     steps:\n       - run:\n           name: Install Git and Gdb\n           command: |\n             dnf -y install git gdb\n       - checkout\n       - run:\n           name: Install packages for building ctags with bmake and checking code\n           command: |\n             dnf -y install gcc automake autoconf pkgconfig bmake libseccomp-devel libxml2-devel jansson-devel libyaml-devel pcre2-devel findutils sudo\n       - run:\n           name: Build\n           command: |\n             bash ./autogen.sh\n             MAKE=bmake ./configure --enable-debugging\n             bmake -j 2\n       - run:\n           name: Test\n           command: |\n             MAKE=bmake bmake check codecheck\n\n   fedora30_bmake_roundtrip:\n     working_directory: ~/universal-ctags\n     docker:\n       - image: docker.io/fedora:30\n     steps:\n       - run:\n           name: Install Git and Gdb\n           command: |\n             dnf -y install git gdb\n       - checkout\n       - run:\n           name: Install build tools\n           command: |\n             dnf -y install gcc automake autoconf pkgconfig bmake libseccomp-devel libxml2-devel jansson-devel libyaml-devel pcre2-devel findutils sudo\n             dnf -y install jq puppet\n       - run:\n           name: Build\n           command: |\n             bash ./autogen.sh\n             MAKE=bmake ./configure --enable-debugging\n             bmake -j 2\n       - run:\n           name: Test\n           command: |\n             MAKE=bmake bmake roundtrip\n\n   fedora43_distcheck:\n     working_directory: ~/universal-ctags\n     docker:\n       - image: docker.io/fedora:43\n     steps:\n       - run:\n           name: Install Git, Gdb and Procps-NG\n           command: |\n             dnf -y install git gdb procps-ng\n       - checkout\n       - run:\n           name: Install build tools\n           command: |\n             dnf -y install awk gcc automake autoconf pkgconfig make libseccomp-devel libxml2-devel jansson-devel libyaml-devel findutils diffutils sudo pcre2-devel\n             dnf -y install jq puppet python3-docutils\n       - run:\n           name: Run autogen.sh\n           command: |\n             bash ./autogen.sh\n       - run:\n           name: Run configure\n           command: |\n             ./configure\n       - run:\n           name: verify generated files (optlib, txt2cstr, etc.) are updated\n           command: |\n             make check-genfile\n       - run:\n           name: Test\n           command: |\n             ulimit -c 0\n             # Let's trick git.\n             #\n             # \"git\" running in \"make distcheck\" may refer $(pwd)/.git of THIS context.\n             # On the other hand, we want to run the test cases in an environment separated\n             # from our git repo.\n             #\n             mkdir __NO_GIT__\n             make distcheck GIT_DIR=__NO_GIT__\n             rmdir __NO_GIT__\n\n   stream10:\n     working_directory: ~/universal-ctags\n     docker:\n       - image: quay.io/centos/centos:stream10\n     steps:\n       - run:\n           name: Install Git\n           command: |\n             dnf -y --enablerepo=baseos --enablerepo=appstream --enablerepo=crb install git\n       - checkout\n       - run:\n           name: Install build tools\n           command: |\n              dnf -y --enablerepo=baseos --enablerepo=appstream --enablerepo=crb install python3 gcc automake autoconf pkgconfig make jansson-devel libxml2-devel libyaml-devel pcre2-devel findutils diffutils sudo\n       - run:\n           name: Build\n           command: |\n             bash ./autogen.sh\n             ./configure --enable-debugging\n             make -j 2\n       - run:\n           name: Test\n           command: |\n             make check roundtrip\n\n   stream9:\n     working_directory: ~/universal-ctags\n     docker:\n       - image: quay.io/centos/centos:stream9\n     steps:\n       - run:\n           name: Install Git\n           command: |\n             yum -y --enablerepo=baseos --enablerepo=appstream --enablerepo=crb install git\n       - checkout\n       - run:\n           name: Install build tools\n           command: |\n              yum -y --enablerepo=baseos --enablerepo=appstream --enablerepo=crb install python3 gcc automake autoconf pkgconfig make jansson-devel libxml2-devel libyaml-devel pcre2-devel findutils diffutils sudo\n       - run:\n           name: Build\n           command: |\n             bash ./autogen.sh\n             ./configure --enable-debugging\n             make -j 2\n       - run:\n           name: Test\n           command: |\n             make check roundtrip\n\n   ubuntu20_mingw:\n     working_directory: ~/universal-ctags\n     docker:\n       - image: docker.io/ubuntu:20.04\n     steps:\n       - run:\n           name: Install git\n           command: |\n             export DEBIAN_FRONTEND=noninteractive\n             apt-get -y update\n             apt-get -y install git\n       - checkout\n       - run:\n           name: Install build tools\n           command: |\n             export DEBIAN_FRONTEND=noninteractive\n             apt-get -o APT::Immediate-Configure=false -y install \\\n             binutils-mingw-w64-i686 gcc-mingw-w64-i686 make gcc\n       - run:\n           name: Build\n           command: |\n             make -j2 CC=i686-w64-mingw32-gcc WINDRES=i686-w64-mingw32-windres CC_FOR_PACKCC=gcc -f mk_mingw.mak\n   ubuntu20_32bit:\n     working_directory: ~/universal-ctags\n     docker:\n       - image: docker.io/ubuntu:20.04\n     steps:\n       - run:\n           name: Install git\n           command: |\n             export DEBIAN_FRONTEND=noninteractive\n             dpkg --add-architecture i386\n             apt-get -y update\n             apt-get -y install git\n       - checkout\n       - run:\n           name: Install build tools\n           # APT::Immediate-Configure=false is taken from\n           # https://superuser.com/questions/199582/apt-error-could-not-perform-immediate-configuration-on\n           # I don't understand why I need this.\n           # -- Masatake\n           command: |\n             export DEBIAN_FRONTEND=noninteractive\n             apt-get -o APT::Immediate-Configure=false -y install \\\n             pkg-config autoconf automake make gcc \\\n             libjansson-dev:i386 libyaml-dev:i386 libseccomp-dev:i386 libxml2-dev:i386 \\\n             gdb valgrind \\\n             python3-docutils \\\n             libc6-dev-i386 libc6-dbg:i386\n       - run:\n           name: Build\n           command: |\n             bash ./autogen.sh\n             CC='gcc -m32' ./configure --enable-debugging\n             make -j 2\n       - run:\n           name: Test\n           command: |\n             # make check roundtrip\n             make units CATEGORIES=parser-varlink\n\n   fedora43_cross_aarch64:\n     working_directory: ~/universal-ctags\n     docker:\n       - image: docker.io/library/fedora:43\n     steps:\n       - run:\n           name: Install tools\n           command: |\n             dnf -y install git gcc autoconf automake make file\n       - run:\n           name: Prepare repo file for install cross compiler\n           command: |\n             curl -o /etc/yum.repos.d/lantw44-aarch64-linux-gnu-toolchain-fedora-43.repo https://copr.fedorainfracloud.org/coprs/lantw44/aarch64-linux-gnu-toolchain/repo/fedora-43/lantw44-aarch64-linux-gnu-toolchain-fedora-43.repo\n       - run:\n           name: Install the cross compiler for aarch64\n           command: |\n             dnf -y install aarch64-linux-gnu-binutils aarch64-linux-gnu-gcc aarch64-linux-gnu-glibc\n       - checkout\n       - run:\n           name: Build ctags for aarch64\n           command: |\n             bash ./autogen.sh\n             mkdir out\n             ./configure --host=aarch64-linux-gnu \\\n             --prefix=`pwd`/out \\\n             --enable-static \\\n             --disable-seccomp \\\n             CC=/usr/bin/aarch64-linux-gnu-gcc \\\n             CPP=/usr/bin/aarch64-linux-gnu-cpp \\\n             AR=/usr/bin/aarch64-linux-gnu-gcc-ar \\\n             RANLIB=/usr/bin/aarch64-linux-gnu-gcc-ranlib \\\n             CC_FOR_BUILD=/usr/bin/gcc\n             make -j 2\n       - run:\n           name: Install locally\n           command: |\n             make install\n       - run:\n           name: Test\n           command: |\n             test -f out/bin/ctags && ( file out/bin/ctags | grep -q 'ARM aarch64' )\n\nworkflows:\n  version: 2\n  build_and_test:\n    jobs:\n      - ubuntu20_32bit\n      - fedora30_bmake\n      - fedora43_distcheck\n      - stream10\n      - stream9\n      - fedora43_gmake\n      - fedora43_cross_aarch64\n      - ubuntu20_mingw\n      - fedora30_bmake_roundtrip\n      - fedora43_gmake_roundtrip\n"
  },
  {
    "path": "configure.ac",
    "content": "#\tCopyright (c) 2009, Darren Hiebert\n#\n#\tThis source code is released for free distribution under the terms\n#\tof the GNU General Public License version 2 or (at your option) any\n#\tlater version.\n\n#\tProcess this file with autoconf to produce a configure script.\n\nAC_PREREQ([2.64])\n\ndnl You must update PROGRAM_VERSION in main/ctags.h, too.\ndnl --version option of readtags also prints this.\nAC_INIT([universal-ctags],[6.2.0])\n\nif ! test -e \"${srcdir}/config.h.in\"; then\n   echo \"---\"\n   echo \"--- ${srcdir}/config.h.in WAS NOT FOUND.\" 1>&2\n   echo \"--- YOU MIGHT HAVE RUN autoconf ONLY\" 1>&2\n   echo \"--- BUT YOU MAY HAVE TO RUN autogen.sh.\" 1>&2\n   echo \"---\"\n   exit 1\nfi\n\n# Report system info\n# ------------------\nprogram_name=[`grep 'PROGRAM_NAME  *\"' $srcdir/main/ctags.h | sed -e 's/.*\"\\([^\"]*\\)\".*/\\1/'`]\nprogram_version=[`grep 'PROGRAM_VERSION  *\"' $srcdir/main/ctags.h | sed -e 's/.*\"\\([^\"]*\\)\".*/\\1/'`]\necho \"$program_name, version $program_version\"\nuname -mrsv 2>/dev/null\n\nAM_INIT_AUTOMAKE([foreign subdir-objects tar-ustar])\nAM_SILENT_RULES([yes])\nAC_CONFIG_HEADERS([config.h])\n\nm4_ifndef([PKG_CHECK_EXISTS], [m4_fatal([must install pkg-config 0.18 or later before running ./autogen.sh])])\n\nAC_CANONICAL_BUILD\nAC_CANONICAL_HOST\n\ncase $host in\n    *darwin*)\n        if test \"${enable_static}\" = \"yes\"; then\n            printf \"\\n%s\\n\" \"macOS not support --enable-static.\" >&5\n            printf \"\\n%s\\n\" \"macOS not support --enable-static.\" >&6\n            exit 1\n        fi\n        ;;\n    *freebsd*|*openbsd*)\n        if test \"$cross_compiling\" = \"no\" ; then\n            # https://github.com/universal-ctags/ctags/issues/3338\n            export LDFLAGS=\"$LDFLAGS -L/usr/local/lib\"\n        fi\n        ;;\nesac\n\nAH_TEMPLATE([PACKAGE], [Package name.])\nAH_TEMPLATE([VERSION], [Package version.])\nAH_TEMPLATE([clock_t],\n\t[Define to the appropriate type if <time.h> does not define this.])\nAH_TEMPLATE([fpos_t],\n\t[Define to long if <stdio.h> does not define this.])\nAH_TEMPLATE([L_tmpnam],\n\t[Define to the appropriate size for tmpnam() if <stdio.h> does not define\n\tthis.])\nAH_TEMPLATE([HAVE_STAT_ST_INO],\n\t[Define this macro if the field \"st_ino\" exists in struct stat in\n\t<sys/stat.h>.])\nAH_TEMPLATE([HAVE_STATEMENT_EXPRESSION_EXT],\n\t[Define this macro if compiler supports statement expression non-standard\n\tC feature.])\nAH_TEMPLATE([remove],\n\t[Define remove to unlink if you have unlink(), but not remove().])\nAH_TEMPLATE([INT_MAX],\n\t[Define as the maximum integer on your system if not defined <limits.h>.])\nAH_TEMPLATE([CUSTOM_CONFIGURATION_FILE],\n\t[You can define this label to be a string containing the name of a\n\tsite-specific configuration file containing site-wide default options. The\n\tfiles /etc/ctags.conf and /usr/local/etc/ctags.conf are already checked,\n\tso only define one here if you need a file somewhere else.])\nAH_TEMPLATE([ETAGS],\n\t[Define the string to check (in executable name) for etags mode])\nAH_TEMPLATE([MACROS_USE_PATTERNS],\n\t[Define this label if you want macro tags (defined lables) to use patterns\n\tin the EX command by default (original ctags behavior is to use line\n\tnumbers).])\nAH_VERBATIM([DEFAULT_FILE_FORMAT], [\n/* Define this as desired.\n * 1:  Original ctags format\n * 2:  Extended ctags format with extension flags in EX-style comment.\n */\n#define DEFAULT_FILE_FORMAT\t2\n])\nAH_TEMPLATE([CASE_INSENSITIVE_FILENAMES],\n\t[Define this label if your system uses case-insensitive file names])\nAH_VERBATIM([EXTERNAL_SORT], [\n/* Define this label to use the system sort utility (which is probably more\n*  efficient) over the internal sorting algorithm.\n*/\n#ifndef INTERNAL_SORT\n# undef EXTERNAL_SORT\n#endif\n])\nAH_TEMPLATE([HAVE_ICONV],\n\t[Define this value if support multibyte character encoding.])\nAH_TEMPLATE([ICONV_USE_LIB_PREFIX],\n\t[Define this value if the platform uses \"lib\" as prefix for iconv functions.])\nAH_TEMPLATE([TMPDIR],\n\t[If you wish to change the directory in which temporary files are stored,\n\tdefine this label to the directory desired.])\nAH_TEMPLATE([NON_CONST_PUTENV_PROTOTYPE],\n\t[Define this is you have a prototype for putenv() in <stdlib.h>, but\n\tdoesn't declare its argument as \"const char *\".])\nAH_TEMPLATE([MSDOS_STYLE_PATH],\n\t[Define to 1 if your system uses MS-DOS style path.])\nAH_TEMPLATE([MANUAL_GLOBBING],\n\t[Define to 1 if your system doesn't expand wildcards.])\nAH_TEMPLATE([HAVE__FINDFIRST],\n\t[Define to 1 if your system have _findfirst().])\nAH_TEMPLATE([ENABLE_GCOV],\n\t[Define to 1 if gcov is instrumented.])\nAH_TEMPLATE([USE_GNULIB_FNMATCH],\n\t[Define to 1 when using fnmatch implementation in bundled gnulib.])\n\n# Define convenience macros\n# -------------------------\n# CHECK_HEADER_DEFINE(LABEL, HEADER [,ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ] ])\nAC_DEFUN([CHECK_HEADER_DEFINE], [\n\tAC_MSG_CHECKING([if $1 is defined in $2])\n\tAC_EGREP_CPP([$2:$1],\n[\n#include <$2>\n#ifdef $1\nconst char *result_yes = \"$2:$1\";\n#endif\n], [\n\tAC_MSG_RESULT(yes)\n\t[$3]\n], [\n\tAC_MSG_RESULT(no)\n\t[$4]\n]) ])\n\n# CHECK_PROTO(FUNCTION, HEADER-FILE)\nAC_DEFUN([CHECK_PROTO], [\n\tAC_EGREP_HEADER([[^A-Za-z0-9_]$1([ \t]+[A-Za-z0-9_]*)?[\t ]*\\(],\n\t[$2],\n\t[],\n\t[\n\t\tAC_MSG_NOTICE([adding prototype for $1])\n\t\tAH_TEMPLATE(AS_TR_CPP([NEED_PROTO_$1]),\n\t\t\t    [If you receive error or warning messages indicating that you are missing a prototype for, or a type mismatch using, the following function, define this label and remake.])\n\t\tAC_DEFINE(AS_TR_CPP([NEED_PROTO_$1]))\n\t])\n])\n\n# PRETTY_ARG_VAR(VARIABLE, DESCRIPTION, DEFAULT)\n# ----------------------------------------------\n# Call AC_ARG_VAR with DEFAULT value.\nAC_DEFUN([PRETTY_ARG_VAR], [\n\tAC_ARG_VAR([$1], [$2 [$3]])\n\n\tif test \"${ac_env_$1_set}\" = \"set\"; then\n\t\t$1=\"${ac_env_$1_value}\"\n\telse\n\t\t$1=\"$3\"\n\tfi\n])\n\n# Checks for configuration options\n# --------------------------------\n\nAC_ARG_WITH([sparse-cgcc],\n\t[AS_HELP_STRING([--with-sparse-cgcc],\n\t\t[use Sparse 'compiler wrapper' cgcc as C compiler [no]])])\n\nAC_ARG_ENABLE([coverage-gcov],\n\t[AS_HELP_STRING([--enable-coverage-gcov],\n\t\t[enable 'gcov' coverage testing tool [no]])])\n\nAC_ARG_ENABLE(readcmd,\n\t[AS_HELP_STRING([--disable-readcmd],\n\t\t[do not include readtags command during install])],\n\t[], [enable_readcmd=yes])\n\nAC_ARG_ENABLE(etags,\n\t[AS_HELP_STRING([--enable-etags],\n\t\t[enable the installation of links for etags])])\n\nAC_ARG_ENABLE(extended-format,\n\t[AS_HELP_STRING([--disable-extended-format],\n\t\t[disable extension flags; use original ctags file format only])],\n\tAC_DEFINE(DEFAULT_FILE_FORMAT, 1), AC_DEFINE(DEFAULT_FILE_FORMAT, 2))\n\nAC_ARG_ENABLE(external-sort,\n\t[AS_HELP_STRING([--disable-external-sort],\n\t\t[use internal sort algorithm instead of sort program])])\n\nAC_ARG_ENABLE(iconv,\n\t[AS_HELP_STRING([--disable-iconv],\n\t\t[disable multibyte character encoding support])])\n\nAC_ARG_ENABLE(custom-config,\n\t[AS_HELP_STRING([--enable-custom-config=FILE],\n\t\t[enable custom config file for site-wide defaults])])\n\nAC_ARG_ENABLE(macro-patterns,\n\t[AS_HELP_STRING([--enable-macro-patterns],\n\t\t[use patterns as default method to locate macros instead of line numbers])])\n\nAC_ARG_ENABLE(tmpdir,\n\t[AS_HELP_STRING([--enable-tmpdir=DIR],\n\t\t[default directory for temporary files [ARG=/tmp]])],\n\ttmpdir_specified=yes)\n\nAC_ARG_ENABLE([debugging],\n\t[AS_HELP_STRING([--enable-debugging],\n\t\t[enable debugging features])])\n\nAC_ARG_ENABLE([static],\n\t[AS_HELP_STRING([--enable-static],\n\t\t[enable static linking (mainly for MinGW)])])\n\nAC_ARG_ENABLE([lto],\n\t[AS_HELP_STRING([--enable-lto],\n\t\t[enable link time optimization])])\n\nAC_ARG_PROGRAM\n\n# Process configuration options\n# -----------------------------\n\nAM_CONDITIONAL(INSTALL_ETAGS, [test \"x$enable_etags\" = \"xyes\"])\nAM_CONDITIONAL(USE_READCMD, [test \"x$enable_readcmd\" = \"xyes\"])\n\ndnl AC_MSG_NOTICE(Change with $program_transform_name)\nCTAGS_NAME_EXECUTABLE=`echo ctags | sed \"$program_transform_name\"`\nAC_SUBST(CTAGS_NAME_EXECUTABLE)\nETAGS_NAME_EXECUTABLE=`echo etags | sed \"$program_transform_name\"`\nAC_SUBST(ETAGS_NAME_EXECUTABLE)\n\nAC_DEFINE_UNQUOTED(ETAGS, \"$ETAGS_NAME_EXECUTABLE\")\n\nif test \"$enable_custom_config\" = no -o \"$enable_custom_config\" = yes ; then\n\tAC_MSG_NOTICE(no name supplied for custom configuration file)\nelif test -n \"$enable_custom_config\" ; then\n\tAC_DEFINE_UNQUOTED(CUSTOM_CONFIGURATION_FILE, \"$enable_custom_config\")\n\tAC_MSG_NOTICE($enable_custom_config will be used as custom configuration file)\nfi\n\nif test \"$enable_macro_patterns\" = yes ; then\n\tAC_DEFINE(MACROS_USE_PATTERNS)\n\tAC_MSG_NOTICE(tag file will use patterns for macros by default)\nfi\n\nAM_CONDITIONAL(ENABLE_DEBUGGING, [test \"x$enable_debugging\" = \"xyes\"])\n\n\n# Checks for programs\n# -------------------\n\nAC_PROG_CC\nAC_PROG_CC_C99\nAC_C_INLINE\n# For gnulib.\n#  Typically, this is immediately after AC_PROG_CC, ...\ngl_EARLY\n\nAC_ARG_VAR(RANLIB,[ranlib command or path])\nAC_PROG_RANLIB\nPRETTY_ARG_VAR([AR], [ar command or path], [ar])\nAC_C_BIGENDIAN\n\nif test \"$cross_compiling\" = \"yes\"; then\n    # We need to compile and run a program on the build machine.\n    AC_MSG_CHECKING(for cc for build)\n    if test \"x${CC_FOR_BUILD}\" = \"x\" ; then\n        CC_FOR_BUILD=cc\n    fi\n    AC_MSG_RESULT($CC_FOR_BUILD)\n\n    AC_MSG_CHECKING(if $CC_FOR_BUILD works)\n\n    unset TEMP_DIR_FOR_CHECKING\n    TEMP_DIR_FOR_CHECKING=$(mktemp -d)\n\n    unset CC_FOR_BUILD_WORKS\n    CC_FOR_BUILD_WORKS=no\n\n    (\n        cd \"$TEMP_DIR_FOR_CHECKING\" || return 1\n\n        printf 'int main() { return 0;}' > test.c\n\n        $CC_FOR_BUILD $CPPFLAGS_FOR_BUILD $CFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD -o test test.c\n    ) && CC_FOR_BUILD_WORKS=yes\n\n    AC_MSG_RESULT($CC_FOR_BUILD_WORKS)\n\n    unset BUILD_EXEEXT\n    unset BUILD_OBJEXT\n\n    BUILD_OBJEXT='o'\n\n    if test -f \"$TEMP_DIR_FOR_CHECKING/test.exe\" ; then\n        BUILD_EXEEXT='.exe'\n    fi\nelse\n    CC_FOR_BUILD=\"$CC\"\n    CFLAGS_FOR_BUILD=\"$CFLAGS\"\n    CPPFLAGS_FOR_BUILD=\"$CPPFLAGS\"\n    LDFLAGS_FOR_BUILD=\"$LDFLAGS\"\n\n    BUILD_OBJEXT=\"$OBJEXT\"\n    BUILD_EXEEXT=\"$EXEEXT\"\nfi\n\nAC_ARG_VAR(CC_FOR_BUILD,[build system C compiler])\nAC_ARG_VAR(CFLAGS_FOR_BUILD,[CFLAGS for build system C compiler])\nAC_ARG_VAR(CPPFLAGS_FOR_BUILD,[CPPFLAGS for build system C compiler])\nAC_ARG_VAR(LDFLAGS_FOR_BUILD,[LDFLAGS for build system C compiler])\n\nAC_SUBST([CC_FOR_BUILD])\nAC_SUBST([CFLAGS_FOR_BUILD])\nAC_SUBST([CPPFLAGS_FOR_BUILD])\nAC_SUBST([LDFLAGS_FOR_BUILD])\n\nAC_SUBST([BUILD_OBJEXT])\nAC_SUBST([BUILD_EXEEXT])\n\nAC_ARG_VAR(WINDRES,[windres command or path, used with mingw-w64])\nAC_SUBST([WINDRES])\n\nif test \"x${WINDRES}\" = \"x\" ; then\n    WINDRES=windres\nfi\n\nif test \"${with_sparse_cgcc}\" = \"yes\"; then\n\tREAL_CC=\"${CC}\"\n\tCC=\"cgcc\"\n\tAC_SUBST([REAL_CC])\n\n\tPRETTY_ARG_VAR([CGCC_CFLAGS], [cgcc specific flags],\n\t\t       [-Wsparse-all])\nelse\n\tCGCC_CFLAGS=\"\"\nfi\n\nif test \"${enable_coverage_gcov}\" = \"yes\"; then\n\tCOVERAGE_CFLAGS=\"--coverage\"\n\tCOVERAGE_LDFLAGS=\"--coverage\"\n\tAC_DEFINE(ENABLE_GCOV)\nfi\nAC_SUBST([COVERAGE_CFLAGS])\nAC_SUBST([COVERAGE_LDFLAGS])\n\nAC_PROG_LN_S\nAC_CHECK_PROG(STRIP, strip, strip, :)\nAC_SYS_LARGEFILE\n\nAC_CHECK_PROG([perl_found], [perl], [yes], [no])\nAM_CONDITIONAL([RUN_OPTLIB2C], [test \"${perl_found}\" = \"yes\"])\nAM_CONDITIONAL([RUN_TXT2CSTR], [test \"${perl_found}\" = \"yes\"])\n\n# rst2man and rst2html are part of python-docutils, and if not found\n# \tcan be installed using pip (\"pip install docutils\"). On some\n#\tsystems, rst2man and rst2html are actually installed as rst2man.py\n#\tand rst2html.py - create a symlink of that's the case.\n#\tAlso, allow to define path as \"--with-rst2man\" and \"--with-rst2html\".\nAC_ARG_WITH([rst2man],\n  AS_HELP_STRING([--with-rst2man=PATH], [Location of rst2man (auto)]),\n  [RST2MAN=\"$withval\"],\n  [AC_PATH_PROGS(RST2MAN,\n    [rst2man rst2man.py rst2man-3 rst2man-3.6 rst2man-3.7 rst2man-3.8 rst2man-3.9, rst2man-3.10],\n    [no])])\nAM_CONDITIONAL([HAVE_RST2MAN], [test \"x$RST2MAN\" != \"xno\"])\nAC_ARG_WITH([rst2html],\n  AS_HELP_STRING([--with-rst2html=PATH], [Location of rst2html (auto)]),\n  [RST2HTML=\"$withval\"],\n  [AC_PATH_PROGS(RST2HTML,\n    [rst2html rst2html.py rst2html-3 rst2html-3.6 rst2html-3.7 rst2html-3.8 rst2html-3.9, rst2html-3.10],\n    [no])])\nAM_CONDITIONAL([HAVE_RST2HTML], [test \"x$RST2HTML\" != \"xno\"])\n\n# rst2pdf is a separate tool and can also be installed via pip (e.g.,\n# \t\"pip install rst2pdf\")\nAC_PATH_PROGS(RST2PDF, [rst2pdf], [no])\nAM_CONDITIONAL([HAVE_RST2PDF], [test \"x$RST2PDF\" != \"xno\"])\n\n# rst2man had a bug about code-block:: handling.\n# https://sourceforge.net/p/docutils/patches/141\nRST2MAN_OPTIONS=\nif ! test \"x$RST2MAN\" = \"xno\"; then\n   RST2MAN_SUPPORTING_SYNTAX_HIGHLIGHT_OPTION=no\n   AC_MSG_CHECKING(whether rst2mn has --syntax-highlight option)\n   if $RST2MAN --help | grep -q -e --syntax-highlight; then\n      RST2MAN_SUPPORTING_SYNTAX_HIGHLIGHT_OPTION=yes\n      dnl See man/Makefile about the option\n      RST2MAN_OPTIONS=--syntax-highlight=none\n   fi\n   AC_MSG_RESULT($RST2MAN_SUPPORTING_SYNTAX_HIGHLIGHT_OPTION)\nfi\nAC_SUBST(RST2MAN_OPTIONS)\nAM_CONDITIONAL([HAS_GNU_SED], [sed --version 2>/dev/null | grep -q GNU])\n\nAC_ARG_WITH([pegof],\n  AS_HELP_STRING([--with-pegof=PATH], [Location of pegof (auto)]),\n  [PEGOF=\"$withval\"],\n  [AC_PATH_PROGS(PEGOF,\n    [pegof],\n    [no])])\nAM_CONDITIONAL([HAVE_PEGOF], [test \"x$PEGOF\" != \"xno\"])\n\n# Checks for operating environment\n# --------------------------------\nin_git_repo=no\nAC_MSG_CHECKING(building in a git repository)\nif test -f \"${srcdir}/.git/HEAD\" || test -f \"${srcdir}/.git\"; then\n\tin_git_repo=yes\nfi\nAC_MSG_RESULT(${in_git_repo})\n\nAC_CHECK_PROGS([GIT], [git])\nif ! test \"${GIT:+set}\" = \"set\"; then\n\tin_git_repo=no\nfi\nAM_CONDITIONAL([BUILD_IN_GIT_REPO], [test \"x${in_git_repo}\" = \"xyes\"])\n\nhave_timeout=no\nAC_CHECK_PROGS([TESTING_TIMEOUT], [timeout])\nif test \"${TESTING_TIMEOUT:+set}\" = \"set\"; then\n\thave_timeout=yes\nfi\nAM_CONDITIONAL([HAVE_TIMEOUT], [test \"x${have_timeout}\" = \"xyes\"])\n\nAC_CHECK_PROGS([PYTHON],\n\t\t\t   [python3 python3.8 python3.7 python3.6 python3.5 python], [])\n\n\n# Check for temporary directory\nAC_MSG_CHECKING(directory to use for temporary files)\nif test -n \"$enable_tmpdir\"; then\n\ttmpdir=\"$enable_tmpdir\"\nelif test -n \"$TMPDIR\"; then\n\ttmpdir=\"$TMPDIR\"\nelif test -n \"$TMP\"; then\n\ttmpdir=\"$TMP\"\nelif test -n \"$TEMP\"; then\n\ttmpdir=\"$TEMP\"\nelif test -d \"c:/\"; then\n\ttmpdir=\"c:/\"\nelse\n\ttmpdir=\"/tmp\"\nfi\n\nif test \"$cross_compiling\" = yes ; then\n        AC_MSG_RESULT($tmpdir)\n        AC_DEFINE_UNQUOTED(TMPDIR, \"$tmpdir\")\nelse\n    if test -d $tmpdir ; then\n        AC_MSG_RESULT($tmpdir)\n        AC_DEFINE_UNQUOTED(TMPDIR, \"$tmpdir\")\n    else\n        AC_MSG_ERROR($tmpdir does not exist)\n    fi\nfi\n\n# Test for case-insensitive filenames\nAC_MSG_CHECKING(for case-insensitive filenames)\ntouch conftest.cif\nif test -f CONFTEST.CIF; then\n\tAC_MSG_RESULT(yes)\n\tAC_DEFINE(CASE_INSENSITIVE_FILENAMES)\nelse\n\tAC_MSG_RESULT(no)\nfi\nrm -f conftest.cif\n\nAC_MSG_CHECKING(selected sort method)\nif test no = \"$enable_external_sort\"; then\n\tAC_MSG_RESULT(simple internal algorithm)\nelse\n\tAC_MSG_RESULT(external sort utility)\n\tenable_external_sort=no\n    AC_CHECK_PROG(sort_found, sort, yes, no)\n\tif test \"$sort_found\" = yes ; then\n\t\tAC_MSG_CHECKING(if sort accepts our command line)\n\t\ttouch ${tmpdir}/sort.test\n\t\tsort -u -f -o ${tmpdir}/sort.test ${tmpdir}/sort.test 1>/dev/null 2>&1\n\t\tif test $? -ne 0 ; then\n\t\t\tAC_MSG_RESULT(no)\n\t\telse\n\t\t\tAC_MSG_RESULT(yes)\n\t\t\tAC_DEFINE(EXTERNAL_SORT)\n\t\t\tenable_external_sort=yes\n\t\tfi\n\t\trm -f ${tmpdir}/sort.test\n    fi\nfi\nif test \"$enable_external_sort\" != yes ; then\n\tAC_MSG_NOTICE(using internal sort algorithm as fallback)\nfi\n\n\n# Checks for header files\n# -----------------------\n\nAC_CHECK_HEADERS([direct.h dirent.h fcntl.h io.h stat.h types.h unistd.h])\nAC_CHECK_HEADERS([sys/dir.h sys/stat.h sys/types.h sys/wait.h])\n\n# Checks for header file macros\n# -----------------------------\n\nCHECK_HEADER_DEFINE(L_tmpnam, [stdio.h],, AC_DEFINE(L_tmpnam, 20))\n\n\n# Checks for typedefs and types\n# -----------------------------\n\nAC_TYPE_OFF_T\n\nAC_CHECK_HEADERS([stdbool.h])\n\n# Checks for compiler characteristics\n# -----------------------------------\n\nAC_C_CONST\nAC_OBJEXT\nAC_EXEEXT\nAC_C_TYPEOF\n\nif test \"${enable_static}\" = \"yes\"; then\n\tLDFLAGS=\"$LDFLAGS -static\"\nfi\n\n# Check for host type\ncase \"$host\" in\n  i?86-*-mingw* | x86_64-*-mingw*)\n\thost_mingw=yes\n\t# See https://github.com/universal-ctags/ctags/pull/3069\n\tgl_cv_have_weak=no\n\tAC_DEFINE(MSDOS_STYLE_PATH)\n\tAC_DEFINE(MANUAL_GLOBBING)\n\tAC_DEFINE(HAVE__FINDFIRST)\n\t;;\n  *-cygwin | *-msys)\n\tgl_cv_have_weak=no\n\t;;\nesac\nAM_CONDITIONAL([HOST_MINGW], [test \"x${host_mingw}\" = \"xyes\"])\n\nAC_MSG_CHECKING(if compiler supports statement expressions)\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[\nint main(int argc, char **argv) {return ({ int x = 1; x + argc;});}\n])],[have_statement_expression_ext=yes],[have_statement_expression_ext=no])\nAC_MSG_RESULT($have_statement_expression_ext)\nif test yes = \"$have_statement_expression_ext\"; then\n\tAC_DEFINE(HAVE_STATEMENT_EXPRESSION_EXT)\nfi\n\n\n# Check if struct stat contains st_ino.\n# MinGW has st_ino, but it doesn't work.\nif test yes != \"$host_mingw\"; then\n\tAC_MSG_CHECKING(if struct stat contains st_ino)\n\tAC_COMPILE_IFELSE([AC_LANG_PROGRAM([\n\t\t#include <sys/stat.h>\n\t\t#include <stdlib.h>\n\t\t], [\n\t\tstruct stat st;\n\t\tstat(\".\", &st);\n\t\tif (st.st_ino > 0)\n\t\t\texit(0);\n\t])],[have_st_ino=yes],[have_st_ino=no])\n\tAC_MSG_RESULT($have_st_ino)\n\tif test yes = \"$have_st_ino\"; then\n\t\tAC_DEFINE(HAVE_STAT_ST_INO)\n\tfi\nfi\n\nPRETTY_ARG_VAR([EXTRA_CPPFLAGS], [extra (Objective) C/C++ preprocessor flags],\n\t       [-D_GNU_SOURCE -D__USE_GNU])\nPRETTY_ARG_VAR([DEBUG_CPPFLAGS], [(Objective) C/C++ preprocessor debug flags],\n\t       [-DDEBUG])\n\nPRETTY_ARG_VAR([EXTRA_CFLAGS], [extra C compiler flags],\n\t       [-std=gnu99])\nPRETTY_ARG_VAR([WARNING_CFLAGS], [C compiler warning flags],\n\t       [-Wall])\n\nPRETTY_ARG_VAR([EXTRA_LDFLAGS], [extra linker flags],\n\t       [])\n\ndnl ref. https://stackoverflow.com/questions/40374061/autoconf-recipe-to-use-gcc-ar-and-gcc-ranlib\nuse_lto=no\n\nAS_IF([test \"x$cross_compiling\" != \"xyes\" -a \"x$enable_lto\" = \"xyes\"],[\n\t\tAX_CHECK_COMPILE_FLAG(-flto,[use_lto=yes])])\nAS_VAR_IF([use_lto], [yes], [\n\tAS_CASE($CC,\n\t\t[gcc|*/gcc],     [AC_CHECK_PROGS([LTO_AR], [gcc-ar ar],   [:])],\n\t\t[clang|*/clang], [AC_CHECK_PROGS([LTO_AR], [clang-ar ar], [:])],\n\t\t[use_lto=no])\n\tAC_MSG_CHECKING([the wrapper for ar working with $CC -flto])\n\tAS_VAR_IF([LTO_AR], [:], AC_MSG_ERROR([could not find AR tool working with -flto.]))\n\tAS_VAR_IF([use_lto], [yes],\n\t\t[AS_CASE($LTO_AR,\n\t\t\t[*-ar],[AC_MSG_RESULT([$LTO_AR])],\n\t\t\t[use_lto=no\n\t\t\t AC_MSG_RESULT([no suitable AR tool is found; truning off LTO])])],\n\t\t[AC_MSG_RESULT([no suitable AR tool is found; truning off LTO])])\n])\nAS_VAR_IF([use_lto], [yes], [\n\tAS_CASE($CC,\n\t\t[gcc|*/gcc],     [AC_CHECK_PROGS([LTO_RANLIB], [gcc-ranlib ranlib],  [:])],\n\t\t[clang|*/clang], [AC_CHECK_PROGS([LTO_RANLIB], [clang-ranlib ranlib], [:])],\n\t\t[use_lto=no])\n\tAC_MSG_CHECKING([the wrapper for ranlib working with $CC -flto])\n\tAS_VAR_IF([LTO_RANLIB], [:], AC_MSG_ERROR([could not find RANLIB tool working with -flto.]))\n\tAS_VAR_IF([use_lto], [yes],\n\t\t[AS_CASE($LTO_RANLIB,\n\t\t\t[*-ranlib],[AC_MSG_RESULT([$LTO_RANLIB])],\n\t\t\t[use_lto=no\n\t\t\t AC_MSG_RESULT([no suitable ranlib tool is found; truning off LTO])])],\n\t\t[AC_MSG_RESULT([no suitable ranlib is found; truning off LTO])])\n])\nAS_VAR_IF([use_lto], [yes], [\n\tAR=\"$LTO_AR\"\n\tRANLIB=\"$LTO_RANLIB\"\n\tEXTRA_CFLAGS=\"$EXTRA_CFLAGS -flto\"\n\tEXTRA_LDFLAGS=\"$EXTRA_LDFLAGS -flto\"\n],[\n\tAS_VAR_IF([enable_lto], [yes], [\n\t\tAC_MSG_ERROR([though --enable-lto is specified, the fto feature is not available nor usable.])\n\t])\n])\n\n# Checks for function availability\n# -----------------------------------\n\n# For gnulib.\n#   Place it further down in the file, typically where you normally check for\n#   header files or functions.\ngl_INIT\n\nif test \"$REPLACE_FNMATCH\" != 0; then\n\tAC_DEFINE([USE_GNULIB_FNMATCH])\nfi\n\nAC_CHECK_FUNCS(asprintf)\nAC_CHECK_FUNCS(strcasecmp stricmp, break)\nAC_CHECK_FUNCS(strncasecmp strnicmp, break)\n\nAC_CHECK_FUNCS(mkstemp, have_mkstemp=yes)\nif test \"$have_mkstemp\" != yes ; then\n\tAC_CHECK_FUNCS(tempnam, have_tempnam=yes)\nfi\nif test \"$have_mkstemp\" != yes -a \"$have_tempnam\" != yes; then\n\tAC_CHECK_FUNCS(chmod)\n\tif test \"$tmpdir_specified\" = yes ; then\n\t\tAC_MSG_NOTICE(use of tmpnam overrides temporary directory selection)\n\tfi\nfi\n\nAC_CHECK_FUNCS(opendir findfirst _findfirst, break)\nAC_CHECK_FUNCS(strerror strsignal)\n\nAC_CHECK_FUNCS(truncate, have_truncate=yes)\n# === Cannot nest AC_CHECK_FUNCS() calls\nif test \"$have_truncate\" != yes  ; then\n\tAC_CHECK_FUNCS(ftruncate, have_ftruncate=yes)\n\tif test \"$have_ftruncate\" != yes ; then\n\t\tAC_CHECK_FUNCS(chsize)\n\tfi\nfi\n\nAC_CHECK_FUNCS(setenv, have_setenv=yes)\n# === Cannot nest AC_CHECK_FUNCS() calls\nif test \"$have_setenv\" != yes ; then\n\tAC_CHECK_FUNCS(putenv, have_putenv=yes)\n\tif test \"$have_putenv\" = yes ; then\n\t\tAC_EGREP_HEADER(putenv, stdlib.h, have_putenv_prototype=yes)\n\t\tif test \"$have_putenv_prototype\" = yes ; then\n\t\t\tAC_MSG_CHECKING(putenv prototype)\n\t\t\tAC_EGREP_HEADER([[^A-Za-zo-9_]putenv[ \t]*\\(.*const.*\\)[ \t]*;],\n\t\t\t\tstdlib.h, AC_MSG_RESULT(correct),\n\t\t\t\t[\n\t\t\t\t\tAC_MSG_RESULT(no const)\n\t\t\t\t\tAC_DEFINE(NON_CONST_PUTENV_PROTOTYPE)\n\t\t\t\t])\n\t\tfi\n\tfi\nfi\n\nhave_scandir=no\nAC_CHECK_FUNCS(scandir,have_scandir=yes)\n\nhave_dirent_h=no\nAC_CHECK_HEADERS(dirent.h,have_dirent_h=yes)\n\ndnl Dummy check for setting $PKG_CONFIG.\nPKG_CHECK_EXISTS([dummy])\nif test \"${enable_static}\" = \"yes\"; then\n\tPKG_CONFIG=\"$PKG_CONFIG --static\"\nfi\n\nAC_ARG_ENABLE([xml],\n\t[AS_HELP_STRING([--disable-xml],\n\t\t[disable xml support])])\n\nAH_TEMPLATE([HAVE_LIBXML],\n\t[Define this value if libxml is available.])\ndnl About the condition of version\ndnl see https://mail.gnome.org/archives/xml/2010-February/msg00008.html\nAS_IF([test \"x$enable_xml\" != \"xno\"], [\n\tPKG_CHECK_MODULES(LIBXML, [libxml-2.0 >= 2.7.7],\n\t\t\t\t[AC_MSG_CHECKING([libxml-2.0 CRLF handling bug])\n\t\t\t\t ORIGINAL_CFLAGS=$CFLAGS\n\t\t\t\t ORIGINAL_LIBS=$LIBS\n\t\t\t\t CFLAGS=\"$CFLAGS $LIBXML_CFLAGS\"\n\t\t\t\t LIBS=\"$LIBS $LIBXML_LIBS\"\n\t\t\t\t AC_RUN_IFELSE([AC_LANG_SOURCE([[\n\t\t\t\t #include <libxml/parser.h>\n\t\t\t\t #include <libxml/tree.h>\n\t\t\t\t #include <string.h>\n\n\t\t\t\t #define CRLF \"\\r\\n\"\n\t\t\t\t #define __LF  \" \\n\"\n\n\t\t\t\t const char * crlf = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" ?><root><!---->\"CRLF CRLF\"<target/></root>\";\n\t\t\t\t const char * __lf = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" ?><root><!---->\"__LF __LF\"<target/></root>\";\n\n\t\t\t\t static int run(const char *input)\n\t\t\t\t {\n\t\t\t\t\txmlDocPtr doc = xmlParseMemory(input, strlen(input));\n\t\t\t\t\txmlNode *root = xmlDocGetRootElement(doc);\n\t\t\t\t\txmlNode *node = root->children->next->next;\n\t\t\t\t\treturn  node->line;\n\t\t\t\t }\n\n\t\t\t\t int main(void)\n\t\t\t\t {\n\t\t\t\t\txmlLineNumbersDefault (1);\n\t\t\t\t\treturn run(crlf) == run(__lf)? 0: 1;\n\t\t\t\t }]])],[AC_MSG_RESULT([good])\n\t\t\t\t\thave_libxml=yes\n\t\t\t\t\tCFLAGS=$ORIGINAL_CFLAGS\n\t\t\t\t\tLIBS=$ORIGINAL_LIBS\n\t\t\t\t\tAC_DEFINE(HAVE_LIBXML)],\n\t\t\t\t    [AC_MSG_RESULT([bad])\n\t\t\t\t    AC_MSG_WARN([Xpath feature is disabled because the way of handling CRLF in libxml2 is broken.\nSee https://gitlab.gnome.org/GNOME/libxml2/-/commit/43b511fa714df875dc4f40d108061eede0d4d76b])],\n\t\t\t\t    dnl In a context of cross-compiling: We can not do try-run.\n\t\t\t\t    dnl Instead, we check the version number only.\n\t\t\t\t    [PKG_CHECK_MODULES(LIBXML12d0, [libxml-2.0 = 2.12.0],\n\t\t\t\t\t\t\t\t   [AC_MSG_WARN([Xpath feature is disabled because the way of handling CRLF in libxml2 2.12.0 may be broken.\nSee https://gitlab.gnome.org/GNOME/libxml2/-/commit/43b511fa714df875dc4f40d108061eede0d4d76b])\n\t\t\t\t\t\t\t\t    have_libxml=no],[\n\t\t\t\t     PKG_CHECK_MODULES(LIBXML12d1, [libxml-2.0 = 2.12.1],\n\t\t\t\t\t\t\t\t   [AC_MSG_WARN([Xpath feature is disabled because the way of handling CRLF in libxml2 2.12.1 may be broken.\nSee https://gitlab.gnome.org/GNOME/libxml2/-/commit/43b511fa714df875dc4f40d108061eede0d4d76b])\n\t\t\t\t\t\t\t\t    have_libxml=no],\n\t\t\t\t     dnl The available libxml-2.0 is not 2.12.[01].\n\t\t\t\t\t\t\t\t   [have_libxml=yes\n\t\t\t\t\t\t\t\t    AC_DEFINE(HAVE_LIBXML)\n\t\t\t\t\t\t\t\t   ])])]\n\t\t\t\t)],\n\t\t\t\t[AS_IF([test \"x$enable_xml\" = \"xyes\"], [\n\t\t\t\t   AC_MSG_ERROR([libxml2 not found])])])\n])\n\nAM_CONDITIONAL(HAVE_LIBXML, test \"x$have_libxml\" = xyes)\n\nif test \"${enable_static}\" = \"yes\"; then\n\tif test \"${have_libxml}\" = \"yes\"; then\n\t\tif test \"${host_mingw}\" = \"yes\"; then\n\t\t\tdnl -DLIBXML_STATIC needs to be added manually.\n\t\t\tLIBXML_CFLAGS=\"$LIBXML_CFLAGS -DLIBXML_STATIC\"\n\t\tfi\n\tfi\nfi\n\ndnl https://stackoverflow.com/questions/40798571/autoconf-detect-deprecated-functions-in-glibc\nAH_TEMPLATE([IS_xmlLineNumbersDefault_DEPRECATED],\n\t[Define this value if xmlLineNumbersDefault is marked as a deprecated function.])\nAS_VAR_IF([have_libxml], [yes], [\n\tCC_CHECK_WERROR\n\tAS_VAR_IF([cc_cv_werror],[x],[],[\n\t\thave_deprecated_attr=\n\t\tCC_CHECK_CFLAGS_APPEND([-Wdeprecated-declarations], [have_deprecated_attr=yes])\n\t\tAS_VAR_IF([have_deprecated_attr], [yes], [\n\t\t\tSAVE_CFLAGS=$CFLAGS\n\t\t\tCFLAGS=\"$CFLAGS $LIBXML_CFLAGS $cc_cv_werror -Wdeprecated-declarations\"\n\t\t\tAC_MSG_CHECKING([whether xmlLineNumbersDefault is deprecated])\n\t\t\tAC_COMPILE_IFELSE([AC_LANG_PROGRAM([\n\t\t\t\t#include <libxml/parser.h>\n\t\t\t],[\n\t\t\t\tint main (void) {xmlLineNumbersDefault (1); return 0;}\n\t\t\t])],[is_xmlLineNumbersDefault_deprecated=no],[is_xmlLineNumbersDefault_deprecated=yes])\n\t\t\tCFLAGS=$SAVE_CFLAGS\n\t\t\tAC_MSG_RESULT($is_xmlLineNumbersDefault_deprecated)\n\t\t\tAS_VAR_IF([is_xmlLineNumbersDefault_deprecated],[yes],[\n\t\t\t\tAC_DEFINE(IS_xmlLineNumbersDefault_DEPRECATED)\n\t\t\t])\n\t\t])\n\t])\n])\n\nAC_ARG_ENABLE([json],\n\t[AS_HELP_STRING([--disable-json],\n\t\t[disable json support])])\n\nAH_TEMPLATE([HAVE_JANSSON],\n\t[Define this value if jansson is available.])\ndnl This enforces explicit feature usage regardless of the libraries\ndnl available on the build system. This avoids automagic dependencies which\ndnl can cause issues for source-based distros [1].\ndnl [1]: https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Automagic_dependencies\nAS_IF([test \"x$enable_json\" != \"xno\"], [\n\tPKG_CHECK_MODULES(JANSSON, jansson,\n\t\t\t       [have_jansson=yes\n\t\t\t       AC_DEFINE(HAVE_JANSSON)],\n\t\t\t       [AS_IF([test \"x$enable_json\" = \"xyes\"], [\n\t\t\t           AC_MSG_ERROR([jansson not found])])])\n])\nAM_CONDITIONAL(HAVE_JANSSON, test \"x$have_jansson\" = xyes)\n\nAH_TEMPLATE([HAVE_SECCOMP],\n\t[Define this value if libseccomp is available.])\nAC_ARG_ENABLE([seccomp],\n\t[AS_HELP_STRING([--disable-seccomp],\n\t\t[disable seccomp support])])\nAS_IF([test \"x$enable_seccomp\" != \"xno\"], [\n\tPKG_CHECK_MODULES(SECCOMP, libseccomp,\n\t\t\t       [have_seccomp=yes\n\t\t\t       AC_DEFINE(HAVE_SECCOMP)],\n\t\t\t       [AS_IF([test \"x$enable_seccomp\" = \"xyes\"], [\n\t\t\t           AC_MSG_ERROR([libseccomp not found])])])\n])\n\nAC_ARG_ENABLE([yaml],\n\t[AS_HELP_STRING([--disable-yaml],\n\t\t[disable yaml support])])\n\nAH_TEMPLATE([HAVE_LIBYAML],\n\t[Define this value if libyaml is available.])\nAS_IF([test \"x$enable_yaml\" != \"xno\"], [\n\tPKG_CHECK_MODULES(LIBYAML, yaml-0.1,\n\t\t\t       [have_libyaml=yes\n\t\t\t       AC_DEFINE(HAVE_LIBYAML)],\n\t\t\t       [AS_IF([test \"x$enable_yaml\" = \"xyes\"], [\n\t\t\t           AC_MSG_ERROR([libyaml not found])])])\n])\nAM_CONDITIONAL(HAVE_LIBYAML, test \"x$have_libyaml\" = xyes)\n\nAC_ARG_ENABLE([pcre2],\n\t[AS_HELP_STRING([--disable-pcre2],\n\t\t[disable pcre2 support])])\n\nAH_TEMPLATE([HAVE_PCRE2],\n\t[Define this value if pcre2 is available.])\nAS_IF([test \"x$enable_pcre2\" != \"xno\"], [\n\tPKG_CHECK_MODULES(PCRE2, libpcre2-8,\n\t\t\t       [have_libpcre2_8=yes\n\t\t\t       AC_DEFINE(HAVE_PCRE2)],\n\t\t\t       [AS_IF([test \"x$enable_pcre2\" = \"xyes\"], [\n\t\t\t           AC_MSG_ERROR([libpcre2-8 not found])])])\n])\nAM_CONDITIONAL(HAVE_PCRE2, test \"x$have_libpcre2_8\" = xyes)\n\nif test \"${enable_static}\" = \"yes\"; then\n\tif test \"${have_libpcre2_8}\" = \"yes\"; then\n\t\tif test \"${host_mingw}\" = \"yes\"; then\n\t\t\tdnl -DPCRE2_STATIC needs to be added manually.\n\t\t\tPCRE2_CFLAGS=\"$PCRE2_CFLAGS -DPCRE2_STATIC\"\n\t\tfi\n\tfi\nfi\n\n\n# Checks for missing prototypes\n# -----------------------------\nAC_MSG_NOTICE(checking for new missing prototypes)\n\nCHECK_PROTO(stat,\tsys/stat.h)\nCHECK_PROTO(lstat,\tsys/stat.h)\nif test \"$have_truncate\" = yes ; then\n\tCHECK_PROTO(truncate, unistd.h)\nfi\nif test \"$have_ftruncate\" = yes ; then\n\tCHECK_PROTO(ftruncate, unistd.h)\nfi\n\n# Process library configuration options\n# -------------------------------------\n\nICONV_LIBS=\nif test \"$enable_iconv\" != no ; then\n\tsave_LIBS=\"$LIBS\"\n\t#\n\t# Working around for issue #1620\n\t#\n\tLIBS=\"$LIBS $LIBXML_LIBS\"\n\tLIBS=\"$LIBS $JANSSON_LIBS\"\n\tLIBS=\"$LIBS $SECCOMP_LIBS\"\n\tLIBS=\"$LIBS $LIBYAML_LIBS\"\n\tLIBS=\"$LIBS $ASPELL_LIBS\"\n\tLIBS=\"$LIBS -liconv\"\n\t#\n\tAC_MSG_CHECKING(for iconv_open or libiconv_open with -liconv)\n\tAC_LINK_IFELSE([AC_LANG_PROGRAM([\n\t\t\t#include <iconv.h>\n\t\t], [iconv_open(\"fr\", \"to\")])], [\n\t\t#\n\t\t# iconv_open is available in libiconv.\n\t\t#\n\t\tLIBS=\"$save_LIBS\"\n\t\tICONV_LIBS=-liconv\n\t\tAC_MSG_RESULT([yes(iconv)])\n\t\tAC_DEFINE(HAVE_ICONV)\n\t\t], [AC_LINK_IFELSE([AC_LANG_PROGRAM([\n\t\t#include <iconv.h>\n\t\t], [libiconv_open(\"fr\", \"to\")])],[\n\t\t#\n\t\t# libiconv_open is available in libiconv\n\t\t#\n\t\tLIBS=\"$save_LIBS\"\n\t\tICONV_LIBS=-liconv\n\t\tAC_MSG_RESULT([yes(libiconv_open)])\n\t\tAC_DEFINE(HAVE_ICONV)\n\t\tAC_DEFINE(ICONV_USE_LIB_PREFIX)\n\t\t],[LIBS=\"$save_LIBS\"\n\t\tAC_MSG_RESULT(no)\n\t\tAC_CHECK_FUNC(iconv_open, [\n\t\t#\n\t\t# iconv_open is available in libc.\n\t\t# No extra -l flag is needed.\n\t\t#\n\t\tAC_DEFINE(HAVE_ICONV)\n\t\t], [\n\t\tAC_MSG_ERROR([Could not find libiconv. Please install libiconv and libiconv-devel.])])])\n\t\t])\n\tAC_SUBST([ICONV_LIBS])\nfi\n\n# Checks for declaration\n# ----------------------\nAC_CHECK_DECLS([__environ], [], [], [\n[#include <unistd.h>]\n])\nAC_CHECK_DECLS([_NSGetEnviron],[],[],[\n[#include <crt_externs.h>]\n])\nAC_CHECK_DECLS([strnlen],[have_strnlen=yes],[],[\n[#include <string.h>]\n])\nAM_CONDITIONAL(HAVE_STRNLEN, test \"x$have_strnlen\" = xyes)\n\nif test \"$cross_compiling\" = \"yes\"; then\n    AC_MSG_CHECKING(whether strnlen is declared for build)\n    TEMP_DIR_FOR_CHECKING=$(mktemp -d || exit 1)\n    cat > \"$TEMP_DIR_FOR_CHECKING/test.c\" <<EOF\n#include<string.h>\nint main() { strnlen(\"abcd\",1); return 0;}\nEOF\n\n    if $CC_FOR_BUILD $CPPFLAGS_FOR_BUILD $CFLAGS_FOR_BUILD -o \"$TEMP_DIR_FOR_CHECKING/test.o\" \"$TEMP_DIR_FOR_CHECKING/test.c\" > /dev/null 2>&1 ; then\n        have_strnlen_for_build=yes\n    else\n        have_strnlen_for_build=no\n    fi\n    AC_MSG_RESULT($have_strnlen_for_build)\n    AM_CONDITIONAL(HAVE_STRNLEN_FOR_BUILD, test \"x$have_strnlen_for_build\" = xyes)\nelse\n    AM_CONDITIONAL(HAVE_STRNLEN_FOR_BUILD, test \"x$have_strnlen\" = xyes)\nfi\n\nif test \"$CTAGS_NAME_EXECUTABLE\" != ctags ; then\n\tAC_MSG_NOTICE(Changing name of 'ctags' for $CTAGS_NAME_EXECUTABLE)\nfi\n\nif test \"$ETAGS_NAME_EXECUTABLE\" != etags ; then\n\tAC_MSG_NOTICE(Changing name of 'etags' for $ETAGS_NAME_EXECUTABLE)\nfi\n\n# Output files\n# ------------\n\nAC_CHECK_LIB([m], [isnan])\n\nAC_CHECK_FUNCS(mblen)\n\nAC_CONFIG_FILES([Makefile gnulib/Makefile man/GNUmakefile])\n\nAC_OUTPUT\n\nAC_MSG_RESULT([\n##############################################################################\nNow you can run make or gmake. When you run as make, make sure it is GNU make.\n##############################################################################\n])\n\n# vim:ts=4:sw=4:\n"
  },
  {
    "path": "docs/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\nBUILDDIR      = _build\nEXTDIR        = _ext\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n# the i18n builder cannot share the environment and doctrees with the others\nI18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n\n.PHONY: help clean check-if-sphinx-build-is-installed html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext\n\nhelp:\n\t@echo \"\\\n\tUsage: make <TARGET>\\n\\n\\\n\t<TARGET> is one of following:\\n\\\n\thelp       show help infomation\\n\\\n\tclean      detele cached files\\n\\\n\thtml       to make standalone HTML files\\n\\\n\tdirhtml    to make HTML files named index.html in directories\\n\\\n\tsinglehtml to make a single large HTML file\\n\\\n\tpickle     to make pickle files\\n\\\n\tjson       to make JSON files\\n\\\n\thtmlhelp   to make HTML files and a HTML help project\\n\\\n\tqthelp     to make HTML files and a qthelp project\\n\\\n\tdevhelp    to make HTML files and a Devhelp project\\n\\\n\tepub       to make an epub\\n\\\n\tlatex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\\n\\\n\tlatexpdf   to make LaTeX files and run them through pdflatex\\n\\\n\tlatexpdfja to make LaTeX files and run them through platex/dvipdfmx\\n\\\n\ttext       to make text files\\n\\\n\tman        to make manual pages\\n\\\n\ttexinfo    to make Texinfo files\\n\\\n\tinfo       to make Texinfo files and run them through makeinfo\\n\\\n\tgettext    to make PO message catalogs\\n\\\n\tchanges    to make an overview of all changed/added/deprecated items\\n\\\n\txml        to make Docutils-native XML files\\n\\\n\tpseudoxml  to make pseudoxml-XML files for display purposes\\n\\\n\tlinkcheck  to check all external links for integrity\\n\\\n\tdoctest    to run all doctests embedded in the documentation (if enabled)\"\n\nclean:\n\trm -rf $(BUILDDIR) $(EXTDIR)/__pycache__\n\ncheck-if-sphinx-build-is-installed:\n\t@if [ -z \"$(SPHINXBUILD)\" ] ; then \\\n\t\techo \"The SPHINXBUILD variable must not be empty.\" ;\\\n\t\texit 1 ;\\\n\tfi ; \\\n\tif ! command -v \"$(SPHINXBUILD)\" > /dev/null ; then \\\n\t\techo \"The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)\" ;\\\n\t\texit 1 ;\\\n\tfi\n\nhtml: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/html.\"\n\ndirhtml: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/dirhtml.\"\n\nsinglehtml: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml\n\t@echo\n\t@echo \"Build finished. The HTML page is in $(BUILDDIR)/singlehtml.\"\n\npickle: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\njson: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\nhtmlhelp: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in $(BUILDDIR)/htmlhelp.\"\n\nqthelp: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in $(BUILDDIR)/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator $(BUILDDIR)/qthelp/NppSnippets.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile $(BUILDDIR)/qthelp/NppSnippets.qhc\"\n\ndevhelp: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp\n\t@echo\n\t@echo \"Build finished.\"\n\t@echo \"To view the help file:\"\n\t@echo \"# mkdir -p $$HOME/.local/share/devhelp/NppSnippets\"\n\t@echo \"# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/NppSnippets\"\n\t@echo \"# devhelp\"\n\nepub: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub\n\t@echo\n\t@echo \"Build finished. The epub file is in $(BUILDDIR)/epub.\"\n\nlatex: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in $(BUILDDIR)/latex.\"\n\t@echo \"Run \\`make' in that directory to run these through (pdf)latex\" \\\n\t      \"(use \\`make latexpdf' here to do that automatically).\"\n\nlatexpdf: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through pdflatex...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\nlatexpdfja: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through platex and dvipdfmx...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\ntext: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text\n\t@echo\n\t@echo \"Build finished. The text files are in $(BUILDDIR)/text.\"\n\nman: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man\n\t@echo\n\t@echo \"Build finished. The manual pages are in $(BUILDDIR)/man.\"\n\ntexinfo: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo\n\t@echo \"Build finished. The Texinfo files are in $(BUILDDIR)/texinfo.\"\n\t@echo \"Run \\`make' in that directory to run these through makeinfo\" \\\n\t      \"(use \\`make info' here to do that automatically).\"\n\ninfo: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo \"Running Texinfo files through makeinfo...\"\n\tmake -C $(BUILDDIR)/texinfo info\n\t@echo \"makeinfo finished; the Info files are in $(BUILDDIR)/texinfo.\"\n\ngettext: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale\n\t@echo\n\t@echo \"Build finished. The message catalogs are in $(BUILDDIR)/locale.\"\n\nchanges: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes\n\t@echo\n\t@echo \"The overview file is in $(BUILDDIR)/changes.\"\n\nlinkcheck: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in $(BUILDDIR)/linkcheck/output.txt.\"\n\ndoctest: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/doctest/output.txt.\"\n\nxml: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml\n\t@echo\n\t@echo \"Build finished. The XML files are in $(BUILDDIR)/xml.\"\n\npseudoxml: check-if-sphinx-build-is-installed\n\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml\n\t@echo\n\t@echo \"Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml.\"\n"
  },
  {
    "path": "docs/README.md",
    "content": "# Universal Ctags Documentation #\n\nGo to https://docs.ctags.io to read formatted version of this documentation.\n\n## reStructuredText (Docutils and Sphinx) ##\n\n* [Docutils](https://docutils.sourceforge.io/docs/index.html) is used to format\n`man/*.rst.in` for man pages. Only reStructuredText syntaxes described\n[here](https://docutils.sourceforge.io/rst.html) can be used for the man pages.\n\n* [Sphinx Python Documentation Generator](https://www.sphinx-doc.org/en/master/index.html) is used to format `docs/*.rst`.\nSee [here](https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html) for more details of reStructuredText extended by Sphinx.\n\n## Rules for writing documents ##\n\nSee also [Writing Documents](https://docs.ctags.io/en/latest/contributions.html#writing-documents).\n\n### reStructuredText Markup Rules\n\n* put two grave accents around a single-word option, an option usage like\n  `--langdef=MyLang`, a file path, and so on, as \"``` ``--foo`` ```\".  For a\n  single character, add single quotes around it as \"``` '``-``' ```\".\n\n* put two grave accents and double quotes around a multi-word option and an\n  example of a command line, as  \" ``` \"``-f file_name``\" ``` \" or \" ```\n  \"``ctags --help``\" ``` \".\n\n* put double quotes around referring a section, e.g. \" `` See \"Writing\n  Documents\". `` \".\n\n* use one asterisk (emphasis) for a newly-introduced conceptual *word* as\n  \"`*word*`\".\n\n* use one asterisk and \"`<>`\" as \"`*<LANG>*`\" for an option parameter like\n  `<LANG>` in `--kind-<LANG>` option.\n\n* To represent a backslash, surround it with double backquote. i.e. \"``` ``\\`` ```\".\n  Escaping a backslash with another backslash doesn't work well depending\n  on the tools. When converting rst to man, two backslashes are converted\n  into one, however when converting to html, four backslashes are converted\n  into one.\n\n### Hyperlinks\n\n* \"`` `title`_ ``\"  and \"`` `string <title>`_ ``\" styles are valid only in the same page.\n  When this is used on `rst2man`, it is shown with underline.\n\n* \"`` :ref:`label` ``\" and \"`` :ref:`string <label>` ``\" style can jump across files.\n  `rst2html` (and sphinx) converts this to a hyperlink.\n  But this cause error on `rst2man` which is used to format man pages.\n  Don't use this style in man pages.\n\n* The titles of man pages (e.g. \"``ctags(1)``\", \"``ctags-optlib(7)``\", etc.) in\n  ``man/*.[1-9].rst.in`` are replaced to hyperlinks as \"`` :ref:`ctags(1)` ``\"\n  by \"``make update-docs``\".\n\n### Markers ###\n\n- \"`NOT REVIEWED YET`\" (or \"`BEGIN: NOT REVIEWED YET`\" ... \"`END: NOT REVIEWED YET`\") means the section or block is not reviewed yet.\n- \"`IN MAN PAGE`\" means the topic is also explained in the man page of ctags.\n- \"`.. TODO: ...`\": TODO comments for documents.\n- \"`.. TODO(code): ...`\": TODO comments for programming codes.\n- \"`.. TESTCASE: ...`\": A test case for the feature documented is at ....\n\n##  Generating man pages ###\n\nThe files in `docs/man/` directory are generated from the man pages in `man/`\ndirectory. **Do not edit the files in `docs/man/` directory directly.**\n\nExecute `make` in the top directory to update them. Or\n\n```sh\nmake -C man\n```\n\nwill build the man pages only.\n\nDuring this process, hyperlinks to man pages are added as described above, and\ndelete unnecessary section markups from `docs/man/*.rst`.  See `man/Makefile.am`\nfor more details.\n\nTo generate the man pages `rst2man` command is needed.\n`rst2man` is part of the `python-docutils` package on Ubuntu.\n"
  },
  {
    "path": "docs/_ext/ctags_optlib_highlighter.py",
    "content": "from pygments.lexer import RegexLexer, bygroups\nfrom pygments.token import *\n\n#\n# The choice of license is done for merging this to the upstream project\n# in the future.\n#\n\n# Copyright (c) 2021 by Masatake YAMATO.\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n#\n# * Redistributions of source code must retain the above copyright\n#   notice, this list of conditions and the following disclaimer.\n#\n# * Redistributions in binary form must reproduce the above copyright\n#   notice, this list of conditions and the following disclaimer in the\n#   documentation and/or other materials provided with the distribution.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#\n# References:\n# - https://pygments.org/docs/lexerdevelopment/\n# - https://pygments.org/docs/tokens/#module-pygments.token\n#\n# For testing:\n#   python -m pygments -x -l ctags_highlighter.py:CtagsOptlibLexer foo.ctags  | less -r\n#\n\nclass CtagsOptlibLexer(RegexLexer):\n    name = 'ctags'\n    aliases = ['ctags']\n    filenames = ['*.ctags']\n\n    tokens = {\n        'root': [\n            (r'#.*\\n', Comment.Single),\n            (r'^[ \\t]+', Whitespace),\n            (r'(--langdef)(=)([a-zA-Z0-9#+]+)(.*\\n)',\n             bygroups(Keyword.Namespace, Punctuation,\n                      Name.Namespace, Text\n                      )),\n            (r'(--map-)([a-zA-Z0-9#+]+)(=\\+?)(.*\\n)',\n             bygroups(Keyword.Declaration, Name.Namespace, Punctuation,\n                      Text\n                      )),\n            (r'(--langmap)(=\\+?)([a-zA-Z0-9#+]+)(:)(.*\\n)',\n             bygroups(Keyword.Declaration, Punctuation, Name.Namespace, Punctuation,\n                      Text\n                      )),\n            # kinds\n            (r'(--kinddef-)([a-zA-Z0-9#+]+)(=)(.)(,)([a-zA-Z0-9]+)(,)(.*\\n)',\n             bygroups(Keyword.Declaration, Name.Namespace, Punctuation,\n                      Name.Entity, Punctuation, Name.Entity, Punctuation, String.Doc)),\n            (r'(--kinds-)([a-zA-Z0-9#+]+)(=\\+?)(.*\\n)',\n             bygroups(Keyword, Punctuation,\n                      Text\n                      )),\n            # fields\n            (r'(--_fielddef-)([a-zA-Z0-9#+]+)(=)([a-zA-Z0-9]+)(,)(.*)(\\n)',\n             bygroups(Keyword.Declaration, Name.Namespace, Punctuation,\n                      Name.Type, Punctuation, String.Doc,\n                      Text\n                      )),\n            (r'(--fields)(=\\+?)(.*\\n)',\n             bygroups(Keyword, Punctuation,\n                      Text\n                      )),\n            (r'(--fields-)([a-zA-Z0-9#+]+)(=\\+?)(.*\\n)',\n             bygroups(Keyword, Name.Namespace, Punctuation,\n                      Text)),\n            # extras\n            (r'(--_extradef-)([a-zA-Z0-9#+]+)(=)([a-zA-Z0-9]+)(,)(.*)(\\n)',\n             bygroups(Keyword.Declaration, Name.Namespace, Punctuation,\n                      Name.Variable, Punctuation, String.Doc,\n                      Text\n                      )),\n            (r'(--extras?)(=\\+?)(.*\\n)',\n             bygroups(Keyword, Punctuation,\n                      Text)),\n            (r'(--extras?-)([a-zA-Z0-9#+]+)(=\\+?)(.*\\n)',\n             bygroups(Keyword, Name.Namespace, Punctuation,\n                      Text\n                      )),\n            # roles\n            (r'(--_roledef-)([a-zA-Z0-9#+]+)(\\.)([a-zA-Z])(=)([a-zA-Z0-9]+)(,)(.*)(\\n)',\n             bygroups(Keyword.Declaration, Name.Namespace, Punctuation, Name.Entity, Punctuation,\n                      Name.Decorator, Punctuation, String.Doc,\n                      Text\n                      )),\n            (r'(--roles-)([a-zA-Z0-9#+]+)(\\.)([a-zA-Z])(=\\+?)(.*\\n)',\n             bygroups(Keyword, Name.Namespace, Punctuation, Name.Entity, Punctuation,\n                      Text\n                      )),\n            # regex  and tables\n            (r'(--regex-|--mline-regex-)([a-zA-Z0-9#+]+)(=)(.*\\n)',\n             bygroups(Keyword.Declaration, Name.Namespace, Punctuation,\n                      # TODO\n                      Text\n                      )),\n            (r'(--_tabledef-)([a-zA-Z0-9#+]+)(=)([a-zA-Z0-9]*)(\\n)',\n             bygroups(Keyword.Declaration, Name.Namespace, Punctuation,\n                      Name.Function,\n                      Text\n                      )),\n            (r'(--_mtable-regex-)([a-zA-Z0-9#+]+)(=)([a-zA-Z0-9]*)(.*\\n)',\n             bygroups(Keyword.Declaration, Name.Namespace, Punctuation,\n                      Name.Function,\n                      Text\n                      )),\n            # TODO\n            (r'.*\\n', Text)\n        ]\n    }\n"
  },
  {
    "path": "docs/_ext/lexers.py",
    "content": "from ctags_optlib_highlighter import CtagsOptlibLexer\nfrom pygments.lexers.special import TextLexer\nimport sphinx\n\ndef install(app, h, name):\n    v = sphinx.__version__.split('.')\n    if int(v[0]) > 3:\n        c = h\n    elif (int(v[0]) == 3) and (int(v[1]) > 3):\n        c = h\n    else:\n        c = h()\n    app.add_lexer(name, c)\n\ndef setup(app):\n    install(app, CtagsOptlibLexer, 'ctags')\n    # Setup stubs\n    for h in ['git', 'yacc', 'EmacsLisp', 'tags', 'Autoconf', 'SystemTap', 'RMarkdown']:\n        install(app, TextLexer, h)\n"
  },
  {
    "path": "docs/autotools.rst",
    "content": "Building with configure (\\*nix including GNU/Linux)\n---------------------------------------------------------------------\n\nIf you are going to build Universal Ctags on a popular GNU/Linux\ndistribution, you can install the tools and libraries that Universal Ctags\nrequires (or may use) as packages. See `GNU/Linux distributions`_ about\nthe packages.\n\nLike most Autotools-based projects, you need to do:\n\n.. code-block:: console\n\n    $ git clone https://github.com/universal-ctags/ctags.git\n    $ cd ctags\n    $ ./autogen.sh\n    $ ./configure --prefix=/where/you/want # defaults to /usr/local\n    $ make\n    $ make install # may require extra privileges depending on where to install\n\nAfter installation the `ctags` executable will be in `$prefix/bin/`.\n\n`autogen.sh` runs `autoreconf` internally.\nIf you use a (binary oriented) GNU/Linux distribution, `autoreconf` may\nbe part of the `autoconf` package. In addition you may have to install\n`automake` and/or `pkg-config`, too.\n\nGNU/Linux distributions\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nBefore running ./autogen.sh, install some packages.\n\nOn Debian-based systems (including Ubuntu), do:\n\n.. code-block:: console\n\n    $ sudo apt install \\\n        gcc make \\\n        pkg-config autoconf automake \\\n        python3-docutils \\\n        libseccomp-dev \\\n        libjansson-dev \\\n        libyaml-dev \\\n        libxml2-dev\n\nOn Fedora systems, do:\n\n.. code-block:: console\n\n    $ sudo dnf install \\\n        gcc make \\\n        pkgconfig autoconf automake \\\n        python3-docutils \\\n        libseccomp-devel \\\n        jansson-devel \\\n        libyaml-devel \\\n        libxml2-devel\n\nChanging the executable's name\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nOn some systems, like certain BSDs, there is already a 'ctags' program in the base\nsystem, so it is somewhat inconvenient to have the same name for\nUniversal Ctags. During the ``configure`` stage you can now change\nthe name of the created executable.\n\nTo add a prefix 'ex' which will result in 'ctags' being renamed to 'exctags':\n\n.. code-block:: console\n\n\t$ ./configure --program-prefix=ex\n\nTo completely change the program's name run the following:\n\n.. code-block:: console\n\n\t$ ./configure --program-transform-name='s/ctags/my_ctags/; s/etags/myemacs_tags/'\n\nPlease remember there is also an 'etags' installed alongside 'ctags' which you may also want to rename as shown above.\n\nLink time optimization\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\nLink-time optimization (LTO) is an interprocedural optimization (IPO) across\ntranslation units (module files) for languages that compile on a file-by-file\nbasis. This optimization is supported by the compilers, like gcc and clang,\netc.\n\nLTO is usually beneficial to improving program performance (here refers to ctags).\nWe provide the `--enable-lto` option to enable it, as in the following example:\n\n.. code-block:: console\n\n\t$ ./configure --enable-lto\n\nBut note that we do not enable LTO by default (for stability reasons), and there\nare certain requirements for using LTO. First, the compiler itself must support\nLTO optimization, and second, it cannot be cross-compilation (like below). When\nthe above requirements are met, you need to actively use the `--enable-lto` option\nto truly enable LTO optimization for ctags.\n\nFor example:\n\n.. code-block:: console\n\n\t$ ./configure\n\nis equivalent to:\n\n.. code-block:: console\n\n\t$ ./configure --disable-lto\n\nCross-compilation\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nThe way of cross-compilation is a bit complicated because the\nbuild-system of ctags uses `packcc`, a code generator written in C\nlanguage. It means that two C compilers should be installed on you build machine;\none for compiling `packcc`, another for compiling `ctags`.\n\nWe provide two sets of configure variables to affect these two C compilers:\n`CC`, `CFLAGS`, `CPPFLAGS`, `LDFLAGS` variables affect the compiler who compiles `ctags`.\n`CC_FOR_BUILD`, `CPPFLAGS_FOR_BUILD`, `CPPFLAGS_FOR_BUILD`, `LDFLAGS_FOR_BUILD` variables\naffect the compiler who compiles `packcc`.\n\nWhen native-compiling, `FOO_FOR_BUILD` is the same as `FOO`.\n\nHere is an example show you how to use these configure variables:\n\n.. code-block:: console\n\n       $ mkdir ./out\n       $ configure \\\n               --host=armv7a-linux-androideabi \\\n               --prefix=`pwd`/out \\\n               --enable-static \\\n               --disable-seccomp \\\n               CC=/usr/local/opt/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi21-clang \\\n               CFLAGS='-v' \\\n               CPP='/usr/local/opt/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi21-clang -E' \\\n               CPPFLAGS='-I/Users/leleliu008/.ndk-pkg/pkg/jansson/armeabi-v7a/include -I/Users/leleliu008/.ndk-pkg/pkg/libyaml/armeabi-v7a/include -I/Users/leleliu008/.ndk-pkg/pkg/libxml2/armeabi-v7a/include -I/Users/leleliu008/.ndk-pkg/pkg/libiconv/armeabi-v7a/include --sysroot /usr/local/opt/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -Qunused-arguments -Dftello=ftell -Dfseeko=fseek' \\\n               LDFLAGS='-L/Users/leleliu008/.ndk-pkg/pkg/jansson/armeabi-v7a/lib -L/Users/leleliu008/.ndk-pkg/pkg/libyaml/armeabi-v7a/lib -L/Users/leleliu008/.ndk-pkg/pkg/libxml2/armeabi-v7a/lib -L/Users/leleliu008/.ndk-pkg/pkg/libiconv/armeabi-v7a/lib --sysroot /usr/local/opt/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot' \\\n               AR=/usr/local/opt/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ar \\\n               RANLIB=/usr/local/opt/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ranlib \\\n               CC_FOR_BUILD=/usr/bin/cc \\\n               CFLAGS_FOR_BUILD='-v' \\\n               PKG_CONFIG_PATH=/Users/leleliu008/.ndk-pkg/pkg/libiconv/armeabi-v7a/lib/pkgconfig:/Users/leleliu008/.ndk-pkg/pkg/libxml2/armeabi-v7a/lib/pkgconfig:/Users/leleliu008/.ndk-pkg/pkg/libyaml/armeabi-v7a/lib/pkgconfig:/Users/leleliu008/.ndk-pkg/pkg/jansson/armeabi-v7a/lib/pkgconfig \\\n               PKG_CONFIG_LIBDIR=/Users/leleliu008/.ndk-pkg/pkg\n       ...\n       $ make\n       ...\n       $ make install\n       ...\n       $ ls out/bin\n       ctags readtags\n\nSimpler example for `aarch64-linux-gnu` can be found in `circle.yml` in the source tree.\n\nPEG optimization\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\nSome parsers of Universal Ctags are written in PEG grammar.  The build\nsystem of Universal Ctags uses `packcc\n<https://github.com/arithy/packcc>`_ for translating the PEG source\nfiles to C source files. A snapshot version of `packcc` is in the\nsource tree of Universal Ctags. The in-tree `packcc` is used when\nbuilding `ctags`. So you don't have to install `packcc`.\n\n`pegof <https://github.com/dolik-rce/pegof>`_ is a PEG grammar\noptimizer (and formatter). You can use `pegof` to build `ctags` though the\ndeveloper says it is not yet stable enough (https://github.com/universal-ctags/ctags/pull/4023).\n\nYou may have to build `pegof` first.\nSee `Building <https://github.com/dolik-rce/pegof/blob/master/README.md#building>`_ about\nhow to build `pegof`. Following the instructions on the page, you may\nsee the executable is at `./build/pegof`.\n\nWhen building ctags, specify the executable to `--with-pegof` option of `./configure`\nscript:\n\n.. code-block:: console\n\n   $ ls -d ctags pegof\n   ctags  pegof\n   $ ls -l pegof/build/pegof\n   -rwxr-xr-x. 1 yamato yamato 1894560 Jun 30 03:01 pegof/build/pegof\n   $ cd ctags\n   $ ./configure --with-pegof=../pegof/build/pegof\n   ...\n   $ make\n   ...\n\nIf your `ctags` is built with `pegof`, you can verify it with `--list-features` option:\n\n.. code-block:: console\n\n   $ ./ctags --list-features | grep pegof\n   pegof             makes peg based parser(s) optimized (experimental)\n"
  },
  {
    "path": "docs/building.rst",
    "content": "=============================================================================\nBuilding ctags\n=============================================================================\n\n.. toctree::\n\t:maxdepth: 2\n\n\tautotools.rst\n\twindows.rst\n\tosx.rst\n"
  },
  {
    "path": "docs/conf.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# Universal Ctags documentation build configuration file\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this file.\n# See http://sphinx-doc.org/config.html for more information.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys\nimport os\n\n# Check if we run on RTD or locally\non_rtd = os.environ.get('READTHEDOCS', None) == 'True'\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#sys.path.insert(0, os.path.abspath('.'))\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nimport os, sys\nsys.path.append(os.path.abspath(\"./_ext\"))\n\nextensions = [\n        'lexers'\n]\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix of source filenames.\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = 'Universal Ctags'\ncopyright = '2015-2022, Universal Ctags Team'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = '0.3.0'\n# The full version, including alpha/beta/rc tags.\nrelease = '0.3.0'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#language = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\ntoday_fmt = '%d %B %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\nexclude_patterns = ['_build']\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n#keep_warnings = False\n\n# Customizes the Smart Quotes transform. The default 'qDe' educates normal\n# quote characters \", ', em- and en-Dashes ---, --, and ellipses ....\nsmartquotes_action = 'qe'  # Exclude dashes transform for cmdline options.\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\nhtml_theme = 'default'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#html_theme_options = {}\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# See if the RTD theme is installed locally\n# Based on RTD FAQ and the RTD-theme install instruction\n# http://read-the-docs.readthedocs.org/en/latest/faq.html\n# https://github.com/snide/sphinx_rtd_theme\n\nif not on_rtd:\n\tif os.path.exists('_themes/sphinx_rtd_theme'):\n\t\thtml_theme_path = [ '_themes', ]\n\t\thtml_theme = 'sphinx_rtd_theme'\n\n# The name for this set of Sphinx documents.  If None, it defaults to\n# \"<project> v<release> documentation\".\n#html_title = None\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n#html_logo = None\n\n# The name of an image file (within the static path) to use as favicon of the\n# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#html_favicon = None\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\n#html_static_path = ['_static']\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#html_extra_path = []\n\n# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,\n# using the given strftime format.\nhtml_last_updated_fmt = '%d %b %Y'\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_domain_indices = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\n#html_split_index = False\n\n# If true, links to the reST sources are added to the pages.\nhtml_show_sourcelink = False\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = None\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'UniversalCtagsdoc'\n\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n\t# The paper size ('letterpaper' or 'a4paper').\n\t'papersize': 'a4paper',\n\n\t# The font size ('10pt', '11pt' or '12pt').\n\t#'pointsize': '10pt',\n\n\t# Additional stuff for the LaTeX preamble.\n\t#'preamble': '',\n\n\t'classoptions': ',openany,oneside',\n\t'babel': '\\\\usepackage[english]{babel}'\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n  ('index', 'UniversalCtags.tex', 'Universal Ctags Documentation',\n   'Universal Ctags Team', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# If true, show page references after internal links.\n#latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    ('index', 'Universal Ctags', 'Universal Ctags Documentation',\n     ['Universal Ctags Team'], 1)\n]\n\n# If true, show URL addresses after external links.\n#man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n  ('index', 'Universal Ctags', 'Universal Ctags Documentation',\n   'Universal Ctags Team', 'Universal Ctags', 'Universal Ctags',\n   'Miscellaneous'),\n]\n\n# Documents to append as an appendix to all manuals.\n#texinfo_appendices = []\n\n# If false, no module index is generated.\n#texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#texinfo_no_detailmenu = False\n"
  },
  {
    "path": "docs/contributions.rst",
    "content": ".. _contributions:\n\n======================================================================\nContributions\n======================================================================\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\n.. contents:: `Table of contents`\n\t:depth: 3\n\t:local:\n\n----\n\nYou are welcome.\n\nSupporting many parsers with few developers is impossible.  We invite\nthe person who contributes a parser to u-ctags team, especially if the\ntarget language is updated frequently. TypeScript is a typical\nfrequently updated language.\n\nThis is what we would like potential contributors to know. In this\nsection \"you\" means a contributor, and \"we\" means reviewers. \"I\" means\nMasatake YAMATO, the author of this section.\n\nThis page gathers random notes for newly joined members.\n\nBasic rules\n---------------------------------------------------------------------\n\nYou are the maintainer of your parser, of course.\n\nYou may update your parser as you want under the rules described\nlater.\n\nYou may review pull requests changing your parser.\n\nA parser exists and is maintained independently form other\nparsers. However, considering the consistency between parsers are not\nbad.\n\nYou can put your name to docs/developers.rst.\n\nRead docs.ctags.io.\n\nBefore You Start\n---------------------------------------------------------------------\n\n .. Specific to add new parser and/or new kind/role\n\nWhen working on ctags I take into account the following uses for\ntags:\n\n1. inserting the name with completion,\n2. jumping to the definition of the name (in an editor or similar tool),\n3. navigating the source code tree,\n4. summarizing the source code tree, and\n5. answering a query about the source code tree.\n\nWhen I review new parser code, I expect the parser to contribute to\nthese purposes.\n\nWhat should be tagged?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere are two classes of tags. The primary class is a *definition tag*.\nIf a name is defined in a file, the name and the line and the file\nwhere the name is defined should be tagged (recorded). However, in\nsome languages answering, \"What is a definition?\" is not so obvious.\nYou may have to decide what is tagged in your parser thoughtfully.\nThe purposes listed at the top of this subsection should help you\ndecide.\n\nThe secondary class is a *reference tag*. This is newly introduced in\nUniversal Ctags and is not available in Exuberant Ctags. If a name is\nused (or referenced) in a file, it can be tagged as a reference tag.\n\nDon't be confused by the two tag classes.\n\nDefining kinds and roles\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDefining kinds is the most important task in writing a new parser.\nOnce a kind is introduced, we cannot change it because it breaks\ntags file compatibility.\n\nSee :ref:`tag_entries` in :ref:`ctags(1) <ctags(1)>` for more details of kinds\nand roles.\n\nScope information and full qualified tags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nOptional.\nTBW.\n\nDeveloping a parser\n---------------------------------------------------------------------\n\nOrigin of changes and license\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nMake clear where the patches come from and who wrote them.\n\nIf you backport patches from Geany or some other project, their\ncommit IDs should be logged, too.\n\nInclude a copyright notice when adding a new\n``{parsers,main}/*.[ch]`` file.\nA new file also requires a license notice at the head of the file.\n\nWe expect your change (or new code) to be provided under the terms of\nthe General Public License version 2 or any later version. We would\nlike you to express \"version 2 or any later version\".\n\nReference\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIn the comment at the head of your source file, include a URL for a\nweb page that explains the language your parser deals with.\nEspecially if the language is not well known.\n\nHere is an example.\n\n.. code-block:: C\n\n    /*\n    *\n    *   Copyright (c) 2016, Masatake YAMATO\n    *   Copyright (c) 2016, Red Hat, K.K.\n    *\n    *   This source code is released for free distribution under the terms of the\n    *   GNU General Public License version 2 or (at your option) any later version.\n    *\n    *   This module contains functions for generating tags for property list defined\n    *   in http://www.apple.com/DTDs/PropertyList-1.0.dtd.\n    */\n\nC language\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDon't forget to use `static` modifiers. Don't introduce unnecessary\nglobal variables.\n\nRemove unused variables and types. If you want to keep them in your\nsource code, include a descriptive comment.\n\nUse the available facilities provided by the ctags core. If the\nfacilities are not enough for writing a parser, consider extending\nthe core first.\n\nUse underscores in names only in file scope objects.\nDon't use them in function declarations, variable declarations or\nmacro names in header files.\n\nBasic whitespace settings are specified in the `EditorConfig\n<https://editorconfig.org/>`_ configuration file (`.editorconfig`).\nThere are `plugins <https://editorconfig.org/#download>`_ available\nfor most popular editors to automatically configure these settings.\n\nStyle guidelines are largely captured in the `Uncrustify\n<http://uncrustify.sourceforge.net/>`_ configuration file\n(`.uncrustify.cfg`). Formatting can be checked with:\n\n.. code-block:: console\n\n    $ uncrustify -c .uncrustify.cfg -f parsers/awk.c | diff -u parsers/awk.c -\n\nDon't mix `whitespace cleanup` fixes and other improvements in one\ncommit when changing the existing code. Style fixes, including\n`whitespace cleanup`, should be in a separate commit. Mixing\nfunctional changes with style fixes makes reviewing harder.\n\nIf possible, don't use file static variables. Find an alternative way\nthat uses parameters.\n\n\n.. NOT REVIEWED YET\n\nNotes for GNU emacs users\n.........................................................................\n\nIf you use GNU emacs, utilize the `.editorconfig` configuration based\non non-GNU C style. Here non-GNU C style means\n\"align a keyword for control flow and `{` of the block start\".\n\nGNU style:\n\n.. code-block:: C\n\n\tif (...)\n\t    {\n\t\t...\n\nnon-GNU style:\n\n.. code-block:: C\n\n\tif (...)\n\t{\n\t\t...\n\nFor combining the style and `.editorconfig` configuration, put\nfollowing code snippet to your .emacs:\n\n.. code-block:: emacs\n\n\t(add-hook 'hack-local-variables-hook\n\t\t(lambda () (editorconfig-apply)))\n\n`.dir-locals.el` in ctags source tree applies \"linux\" style of `cc-mode`.\nAbove code snippet applies the `.editorconfig` configuration AFTER\ninstalling the \"linux\" style to the current buffer.\n\nI like GNU style, but for keeping consistency in existing code of\nExuberant Ctags, the origin of Universal Ctags, I introduced the style\nand configuration to my .emacs.  Please, do the same.\n\nCompatibility\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWe are trying to maintain compatibility with Exuberant-ctags in the\nfollowing two areas.\n\n* Command line option\n* Tag file compatibility\n\nCommand line options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDon't introduce `--<LANG>-foo=...` style options. They are less\nsuitable for command-line completion by the zsh/bash completion\nengines. Instead, introduce `--foo-<LANG>=...` style options.\n\nAdd an entry to docs/news.rst if you change the behavior of an option\nor introduce a new option. If you think the option is stable enough,\nadd it to ctags.1.in, too.\n\nUse underscore as a prefix for experimental options. Once an option\nis introduced, it must be maintained. We don't want to remove it\nlater. If you are not sure of the usefulness of the option, use an\nunderscore at the start of a long option name like: `--_echo`.\n\nWrite a test case for Tmain or Units.\n\nDon't remove an option, especially if it exists in Exuberant Ctags.\n\nWriting parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThere are two ways to write a parser, writing in C and using *optlib parser*.\n\nUniversal Ctags extends the *optlib parser* feature so extensively that it can\nimplement most of functions of a parser.\n*optlib parser* is also suitable for prototyping.\n\nSee :ref:`ctags-optlib(7) <ctags-optlib(7)>` and :ref:`optlib` for details.\nSee :ref:`optlib2c` how to add a optlib parser on ``ctags``.\n\nFor writing a parser in C see :ref:`writing_parser_in_c`.\n\nBuild script\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nTo add your optlib parser, ``foo.ctags``, into ``ctags`` do the following steps;\n\n* put ``foo.ctags`` file on ``optlib/`` directory\n* add ``foo.ctags`` on ``OPTLIB2C_INPUT`` variable in ``source.mak``\n* add ``fooParser`` on ``PARSER_LIST`` macro variable in ``main/parser_p.h``\n* add ``foo`` on the list in the section \"New parsers\" in ``docs/news.rst``\n* add ``\"..\\optlib\\foo.c\"`` in ``win32/ctags_vs2013.vcxproj``\n* add ``\"..\\optlib\\foo.c\"`` in  ``win32/ctags_vs2013.vcxproj.filters``\n\nTranslated C code is also committed to our git repository. The translated code\nis useful for building ctags on the platforms where optlib2c doesn't run.\n\nTo add your parser file, ``foo.c``, into ``ctags`` do the following steps;\n\n* put ``foo.c`` file on ``parsers/`` directory\n* add ``foo.c`` on ``PARSER_SRCS`` variable in ``sources.mak``\n* add ``foo`` on the list in the section \"New parsers\" in ``docs/news.rst``\n* add ``\"..\\parsers\\foo.c\"`` in ``win32/ctags_vs2013.vcxproj``\n* add ``\"..\\parsers\\foo.c\"`` in  ``win32/ctags_vs2013.vcxproj.filters``\n\nIf you have GNU make, ``make -C win32`` updates the win32 files described above\nfrom ``makefile.mak``.\nWithout updating win32 files our CI process run on\nAppveyor will fail.\n\nSee `this pull request <https://github.com/universal-ctags/ctags/pull/2765>`_\nfor the `Meson` parser as an example of optlib parser.\n\nTesting\n---------------------------------------------------------------------\n\nAdd test cases, and run both existing cases and your new cases.\n\nIf you add a new parser or modify an existing parser, add new test\ncases to \"Units\". If you modify the core, add new test cases to\n\"Tmain\". The way to write and run test cases is described in\n:ref:`testing_ctags` and :ref:`testing_parser` section of this guide.\n\nWith the exception of the tmain test harness, you can specify VG=1\nfor running test cases under the Valgrind memory debugger.\n\nA parse should not enter an infinite loop for bad input.\nA parse should not crash for bad input.\nA parse should return control to its caller for bad input.\n\nDescribe what kind of tests are passed in the commit message.\ne.g. ::\n\n  make units LANGUAGES=TTCN VG=1 is passed.\n  make fuzz LANGUAGES=TTCN VG=1  is passed.\n  make chop LANGUAGES=TTCN VG=1  is passed.\n\nTest cases\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAdd a test case to Unit when creating or modifying a parser.\n\nAdd a test case to Tmain when modifying the core.\n\nAdd a test case to Tinst when modifying the install target in the\nMakefile.\n\nTesting your parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf possible, prepare a simple test and a complex one. The simple one\nfor helping us, the maintainers, understand the intent of the\nmodification.\n\nIf there are more than 3 test cases for a parser, a parser specific\ntest case directory should be prepared like `Units/parser-c.r`.\n\nAdd realistic examples for you parser to *codebase*\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAt `codebase <https://github.com/universal-ctags/codebase>`_, we\ncollect realistic examples that can be used for evaluating your parser\nespecially about its performance aspect. Consider contributing to the\nrepository when adding a new parser to Universal Ctags.\n\nWriting Documents\n---------------------------------------------------------------------\n\n* ``man/*.rst`` files are the source files of our man pages.\n  The man pages are for users. See \"`How to add a new man page for your parser`_\".\n\n* ``docs/*.rst`` files explain experimental\n  new features. The files are for developers. The parts of contents\n  of ``docs/*.rst`` should be moved to ``man/*.rst`` in the future.\n\n* Update ``docs/news.rst`` especially if you add a new parser.\n\n* Write ``docs/parser-<NAME-OF-YOUR-PARSER>.rst`` as you want.\n  A FAQ and the design or your parser are common topics.\n  Consider the maintenance of your parser after you left the\n  project for some reason.\n\nHow to add a new man page for your parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n1. write what the users of your parser may want to (or should) know to ``man/ctags-lang-LANGUAGE.7.rst.in``\n2. add ``man/ctags-lang-LANGUAGE.7`` to ``GEN_IN_MAN_FILES`` of ``man/Makefile.am``.\n3. run ``make -C man update-docs``. This step generates the rst file at ``docs/man/ctags-lang-LANGUAGE.7.rst``.\n4. add ``ctags-lang-LANGUAGE(7)`` to (toctree of) ``docs/man-pages.rst``.\n5. do ``git add`` for\n    * ``man/ctags-lang-LANGUAGE.7.rst.in``\n    * ``docs/man/ctags-lang-LANGUAGE.7.rst``\n6. git commit with a log header: \"``docs(man): add a man page for LANGUAGE``\".\n7. make a pull request\n\n.. TODO: Why do we have to git add ``docs/man/ctags-lang-LANGUAGE.7.rst``?\n\tA system which uses it has Sphinx. It should be able to generate\n\t``docs/man/ctags-lang-LANGUAGE.7.rst``.\n\nCommitting and submitting a pull request\n---------------------------------------------------------------------\n\n* Make a pull request even if the change is small enough.\n\n* Wait for one day till merging even if the change is small enough.\n\n* Wait for 3 days at least for non-small change to your parser.\n\n* Wait for 7 days at least and get an LGTM (Looks Good To Me) comment from a\n  member of the team if your commit changes the other parts than your parser and\n  the changes are not obvious.\n\n* Add a test case to your pull request. To make git-bisect happy,\n  don't add a test case for a feature or a bugfix before adding the\n  code for the feature or the bugfix.\n\n* Even if a pull request includes multiple commits, each commit must\n  be semantically well separated. Sometimes you may want to adjust\n  whitespaces in the code. Adjusting whitespaces is o.k., but don't\n  mix the other change with it. Make a commit just for the whitespaces\n  adjustment.\n\nTitle of commit log and pull request\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* \"Misc Fixes\" is allowed as far as each commit in a pull request is\n  semantically well separated. Sometimes, you may fix various minor\n  things randomly. Making pull requests for each of them is\n  boring. You may want to make \"mix fixes\" pull request especially if\n  your code is young.\n\n* Use [WIP] (Work In Progress) prefix as the title of your pull request, if you don't\n  want people to take time for reviewing your code. Removing [WIP]\n  implies \"ready to be reviewed.\"\n\n* Use [FYI] (For Your Information) prefix as the title to show your idea or sketch represented\n  in C language.\n\n* Use the name of your parser as the prefix of a commit log.\n\n  .. code-block:: git\n\n        C++: record template type parameters to detect the end of template prefix\n\n        If we know Foo is a name of type, it becomes easier to detect whether\n        \">>\" in \"Foo>>\" is a shift operator or the end marker of the template\n        prefix.\n\n  In the above example, \"C++: \" is the prefix.\n\n* Use the name of your parser as the prefix of a pull request if your\n  change is about a parser.\n\n* Use following prefixes for the changes other than parsers.\n\n  main\n    Changes for files under ``main/`` directory\n\n  Units\n    Changes for the test cases under ``Units/`` directory\n\n  Tmain\n    Changes for the test cases under ``Tmain/`` directory\n\n  units\n    Changes for the test harness (misc/units.py) itself\n\n  docs(web)\n    Changes for the ``docs/*.rst``\n\n  docs(man)\n    Changes for the ``man/*.rst``\n\n  dsl\n    Changes operators that can be used in optscript command\n\n  operators\n    Changes operators that can be used in optlib `{{` ... `}}` blocks\n\n  prelude\n    Changes optlib procedures defined in main/CommonPrelude.ps\n\n  CXX (or Cxx)\n    Changes affecting all parsers defined in parsers/cxx\n\n  See also the output of ``git log`` command.\n\n* Combine prefixes with a comma if a change modifies multiple parts of our source tree\n\n  Here is an example.\n\n  .. code-block:: git\n\n\n        commit 64a05963c108af4b7832a2215006ff5cafcaaebb\n        Author: Masatake YAMATO <yamato@redhat.com>\n        Date:   Tue Mar 19 12:19:37 2019 +0900\n\n        main,Flex,JavaScript,SQL,refactor: introduce a helper function to skip two character sequence\n\n        ...\n\n* Use following prefixes if the change as no run-time impact.\n\n  cosmetic\n    - Remove whitespaces at the end of lines\n    - Adjust indentation\n    - Remove an empty line\n    - ...\n\n  style\n    - Rename symbol names\n    - ...\n\n  refactor\n    - Code transformation that doesn't intent changing run-time behavior\n\n  These prefixes reduce the load of reviewers.\n\n* Use [INCOMPATIBLE] as a prefix for both pull request and commit log\n  if the change breaks the compatibility with Exuberant Ctags. Write\n  an explanation in ``man/ctags-incompatibilities.7.rst.in`` about the\n  detail of breakage.\n\n* Use [SELF-INCOMPATIBLE] as a prefix for both pull request and commit\n  log if the change breaks the compatibility with Universal Ctags\n  itself.\n\nCommit log\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n(For new parsers the following criteria is not applicable.)\n\nMake clear the original motivation for the change and/or the impact\non the tags file.\n\nIf you fix a bug reported somewhere on the web, its URL should be\nlogged, too.\n\nIf the bug is reported in the Exuberant Ctags tracker on the\nSourceForge web site, log it as ``sf-bugs:N``, ``sf-patches:N``,\n``sf-support-requests:N``, or ``sf-feature-requests:N``.\n``docs/tracking.rst`` also should be updated.\n\nSquashing commits\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWhen you submit a pull request you might receive some comments from a\nreviewer and, in response, update your patches. After updating, we\nwould like you to squash your patches into logical units of work\nbefore we merge them to keep the repository history as simple as\npossible.\n\n* Use ``git rebase -i`` and ``git push --force`` to refine your change in\n  the meaning of \"semantically well separated.\"  \"semantically well\n  separated\" is important than \"recording the history of your try and\n  error.\"\n\nQuoted from @steveno in `#393\n<https://github.com/universal-ctags/ctags/issues/393>`_ :\n\n    You can check out this page for a good example of how to squash\n    commits\n    http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html\n\n    Once you've squashed all your commits, simply do a git push -f to\n    your fork, and GitHub will update the pull request for you\n    automatically.\n\nRules for reviewing a pull request\n---------------------------------------------------------------------\n\n* Put your rough schedule as a comment if you don't have time, but you\n  want to review.\n\nTesting a PR locally before being merged\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou may want to test a PR locally before it is merged into the master\nrepository.\n\nIf you want to test a PR #2234 on a repository `upstream` as branch name\n`BRANCHNAME`;::\n\n  $ git fetch upstream pull/2234/head:BRANCHNAME\n  $ git checkout BRANCHNAME\n\nThis creates a branch `BRANCHNAME`, and pulls the PR into the branch, and\nswitches to the branch. The branch name `BRANCHNAME` does not have to be the\nsame as the branch name of the PR.\n\nAlternatively suppose you want to test ``USERNAME``'s PR with branch\nname ``main-fix-foo``;::\n\n  git checkout -b tmp-main-fix-foo master\n  git pull https://github.com/USERNAME/ctags.git main-fix-foo\n\nThis creates a branch ``tmp-main-fix-fix-foo`` from a branch ``master`` and\nswitches to it, then pulls the branch ``main-fix-foo`` from\n``https://github.com/USERNAME/ctags.git``.\n"
  },
  {
    "path": "docs/developers.rst",
    "content": "============================================================\nWho we are\n============================================================\n\nPlease, add your name, background and interests here If you are\ninterested in contributing to Universal Ctags steadily. So we can\ndispatch a task and/or an issue to the right person!\n\n(Keep the list in alphabetical order.)\n\n\nCameron Eagans <me@cweagans.net>\n\n\tI've been a PHP developer for almost 10 years, and have been using Vim\n\talmost as long. My goal is to help guide the direction of the PHP\n\tparser, as well as maintain the ctags website and help guide new\n\tcontributors to tasks that they may be able to help with. With time,\n\tI may end up contributing directly to ctags development, but my C skills\n\tare not so great at the moment.\n\nColomban Wendling <colomban@geany.org>\n\n\tI am a developer of Geany, a lightweight IDE/editor that uses CTags\n\tparsers to provide various code insights for a large variety of\n\tlanguages. I don't use CTags directly but through a (currently)\n\tinternal library. Hence, my fields of interest are the quality of the\n\tparsers (good and comprehensive results) and their code (speed, proof\n\tagainst any inputs, absence of memory leaks, regression tests), and a\n\tCTags library applications could use more readily. I am mostly a C\n\tdeveloper, but as the maintainer of the CTags parsers in Geany I work\n\ton all parsers.\n\nFrank Fesevur <ffes@users.sourceforge.net>\n\n\tMy current use of ctags is for a Notepad++ plug-in I'm writing.\n\tThe plug-in is not yet released because of problems with the\n\tWindows version of ctags. Those problems are fixed by now.\n\tI am a Windows developer, but also an occasional Ubuntu and\n\tRaspbian user at home. I wrote the windres parser.\n\nKarol Samborski <edv.karol@gmail.com>\n\n\tI like programming in multiple languages such as Haskell, C/C++,\n\tTypeScript, PHP to name a few. Ctags are useful for me as I code mostly in\n\tVim. My goal here is to take care of the TypeScript parser.\n\nKen Takata <kentkt@csc.jp>\n\n\tI use ctags with Vim mainly on Windows and Cygwin.\n\tI'm the one of the heaviest contributors of Vim.\n\tI set up the AppVeyor environment and I'm also maintaining the\n\t`ctags-win32 <https://github.com/universal-ctags/ctags-win32>`_ project.\n\nMasatake YAMATO <yamato@redhat.com>\n\n\tI'm using ctags in batch jobs running on my source code base\n\twhere most of all source code in Fedora are deployed.  I'm an\n\tEmacs user, so generally I don't use ctags interactively\n\texcept when hacking Universal Ctags. Therefore my primary goal\n\tis to improve the robustness of parsers: I introduced Units\n\ttest facility and badinput command for achieving the goal.\n\tThe secondary goal is to support more languages and formats: I\n\tintroduced optlib. I'm working on Fedora. I don't\n\thave access to the other platforms.\n\nQingming He <906459647@qq.com>\n\n\tI'm mainly a Fortran developer and I use ctags combined with Emacs to\n\thandle my projects. My goal is to improve the Fortran parser to make\n\tit support Fortran standards from 77 to 2008 and maybe 2015 to be\n\treleased in the near future. I'm also interested in improving the lisp\n\tparsers (elisp and scheme).\n\nSzymon Tomasz Stefanek <s.stefanek@gmail.com>\n\n\tI'm a multilanguage developer and I use ctags with my own text editor\n\twhich has some IDE capabilities. I'm the maintainer of the new C/C++ parser.\n\nVitor Antunes <vitor.hda@gmail.com>\n\n\tI've been working with Verilog for most of the last 10\n\tyears and am an avid Vim user. My goal is to improve the\n\tVerilog parser such that Vim can get the most out of it\n\tin plugins like Tagbar and to support the Omni\n\tcompletion plugin I am writing.\n"
  },
  {
    "path": "docs/extending.rst",
    "content": ".. _extending_ctags_in_c:\n\n=============================================================================\nExtending ctags with a parser written in C\n=============================================================================\n\nThis chapter describes how to add a parser in C and the internal API of\nUniversal Ctags.\n\nBefore you start writing a parser in C, consider using *optlib parser*.\nUniversal Ctags extends the functionality so extensively that it can implement\nmost of functionality for the parser.\nSee :ref:`ctags-optlib(7) <ctags-optlib(7)>` and :ref:`optlib` for details.\n\n*optlib parser* is also suitable for prototyping of a parser in C.\n\n.. toctree::\n\t:maxdepth: 4\n\n\tparser-in-c.rst\n\tinternal.rst\n"
  },
  {
    "path": "docs/index.rst",
    "content": ".. Universal Ctags documentation master file\n\n#####################################################################\nUniversal Ctags Hacking Guide\n#####################################################################\n\n:Version: Draft\n:Authors: Universal Ctags developers\n:Web Page: https://ctags.io/\n\n`Universal Ctags`_ (abbreviated as u-ctags) is a *maintained* implementation of\n``ctags``.\n``ctags`` generates an index (or tag) file of language objects found in source\nfiles for programming languages.\nThis index makes it easy for text editors and other tools to locate the indexed\nitems.\n\n`Exuberant Ctags`_ (e-ctags) maintained by Darren Hiebert, the ancestor of\n`Universal Ctags`_, improved traditional ctags with multi-language support, the\nability for the user to define new languages searched by regular expressions\n(called optlib in Universal Ctags), and the ability to generate emacs-style TAGS\nfiles.\nBut the activity of the project unfortunately stalled.\n\n`Universal Ctags`_ has the objective of continuing the development of `Exuberant\nCtags`_.\nReza Jelveh <reza.jelveh@gmail.com> initially created a personal fork of\n`Exuberant Ctags`_ on GitHub.\nAs interest and participation grew, it was decided to move development to a\ndedicated project as `Universal Ctags`_.\nThe goal of this project is to maintain a common/unified working space where\npeople interested in making ctags better can work together.\n\nSome of the major features of `Universal Ctags`_ are:\n\n* greater number of supported languages\n* better language support\n    * new extended C/C++ language parser, etc.\n* fully extended optlib (a feature to define a new language parser from a\n  command line)\n* interactive mode (experimental)\n\nThe primary documents of `Universal Ctags`_ are man pages. Users should first\nconsult the :ref:`ctags(1) <ctags(1)>`, and :ref:`other man pages <man-pages>` if\nnecessary.\n\nThis guide, which also includes the man pages, is primarily for developers and\nprovides additional information to the man pages, including experimental\nfeatures.\n\nThis is a draft document. Proofreading and pull-requests are welcome!\n\n\n.. _Exuberant Ctags: http://ctags.sourceforge.net/\n.. _Universal Ctags: https://ctags.io/\n\n\n.. toctree::\n\t:maxdepth: 2\n\n\tbuilding.rst\n\tman-pages.rst\n\tparsers.rst\n\toption-file.rst\n\toutput-format.rst\n\trunning-multi-parsers.rst\n\tinteractive-mode.rst\n\tnews.rst\n\toptlib.rst\n\toptscript.rst\n\textending.rst\n\ttesting-ctags.rst\n\ttesting-parser.rst\n\ttesting-readtags.rst\n\treporting.rst\n\tcontributions.rst\n\treleasing.rst\n\tother-projects.rst\n\tdevelopers.rst\n"
  },
  {
    "path": "docs/interactive-mode.rst",
    "content": ".. _interactive-mode:\n\n======================================================================\nInteractive mode\n======================================================================\n\nUniversal Ctags can be run with ``--_interactive``, which enters a REPL that\ncan be used programmatically to control ctags generation. In this mode, json\ncommands are received over stdin, and corresponding responses are emitted over\nstdout.\n\nThis feature needs ctags to be built with json support and this requires libjansson to be installed\nat build-time. If it's supported it will be listed in the output of ``--list-features``:\n\n.. code-block:: console\n\n\t$ ctags --list-features | grep json\n\tjson\n\nCommunication with Universal Ctags over stdio uses the `json lines`_ format, where each\njson object appears on a single line and is terminated with a newline.\n\nWhen ``ctags --_interactive`` is invoked, it will emit a single json object to stdout announcing\nits name and version. This signals the start of the interactive loop, and the user can begin sending\ncommands over stdin.\n\n.. code-block:: console\n\n    $ ctags --_interactive\n    {\"_type\": \"program\", \"name\": \"Universal Ctags\", \"version\": \"0.0.0\"}\n\nThe following commands are currently supported in interactive mode:\n\n- generate-tags_\n\ngenerate-tags\n-------------\n\nThe ``generate-tags`` command takes two arguments:\n\n- ``filename``: name of the file to generate tags for (required)\n- ``size``: size in bytes of the file, if the contents will be received over stdin (optional)\n\nThe simplest way to generate tags for a file is by passing its path on filesystem(``file request``). The response will include\none json object per line representing each tag, followed by a single json object with the ``completed``\nfield emitted once the file has been fully processed.\n\n.. code-block:: console\n\n    $ echo '{\"command\":\"generate-tags\", \"filename\":\"test.rb\"}' | ctags --_interactive\n    {\"_type\": \"program\", \"name\": \"Universal Ctags\", \"version\": \"0.0.0\"}\n    {\"_type\": \"tag\", \"name\": \"foobar\", \"path\": \"test.rb\", \"pattern\": \"/^  def foobar$/\", \"kind\": \"method\", \"scope\": \"Test\", \"scopeKind\": \"class\"}\n    {\"_type\":\"completed\", \"command\": \"generate-tags\"}\n\nThe ``generate-tags`` command can also be used to generate tags for code which is not present on filesystem(``inline request``). For example,\nan IDE might want to generate ctags for an unsaved buffer while the user is editing code. When ``size`` is specified,\nthe corresponding number of bytes are read over stdin after the json object and newline.\n\n.. code-block:: console\n\n    $ (\n      echo '{\"command\":\"generate-tags\", \"filename\":\"test.rb\", \"size\": 17}'\n      echo 'def foobaz() end'\n    ) | ctags --_interactive\n    {\"_type\": \"program\", \"name\": \"Universal Ctags\", \"version\": \"0.0.0\"}\n    {\"_type\": \"tag\", \"name\": \"foobaz\", \"path\": \"test.rb\", \"pattern\": \"/^def foobaz() end$/\", \"kind\": \"method\"}\n    {\"_type\": \"completed\", \"command\": \"generate-tags\"}\n\n.. _json lines: http://jsonlines.org/\n\n.. _sandbox-submode:\n\nsandbox submode\n--------------------------\n\n``sandbox`` submode can be used with ``--_interactive=sandbox``.  This\nsubmode will activate a sandbox, to this limits the damage that the\ncan be achieved when exploiting a buffer overflow in Universal Ctags.\n\nIn the sandbox submode ctags can generate tags only for inline\nrequests because ctags has to use open system call to handle file\nrequests. The open system call is not allowed in the sandbox.\n\nThis feature uses `Seccomp BPF (SECure COMPuting with filters)\n<https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html>`_,\nand is only supported on Linux. To use the sandbox submode `libseccomp\n<https://github.com/seccomp/libseccomp>`_ is needed at build-time. If ctags was\nbuilt with seccomp support, ``sandbox`` is listed in the output of\n``--list-features`` option.\n\n.. code-block:: console\n\n\t$ ctags --list-features | grep sandbox\n\tsandbox\n\n.. code-block:: console\n\n    $ (\n      echo '{\"command\":\"generate-tags\", \"filename\":\"test.rb\", \"size\": 17}'\n      echo 'def foobaz() end'\n    ) | ctags --_interactive=sandbox\n    {\"_type\": \"program\", \"name\": \"Universal Ctags\", \"version\": \"0.0.0\"}\n    {\"_type\": \"tag\", \"name\": \"foobaz\", \"path\": \"test.rb\", \"pattern\": \"/^def foobaz() end$/\", \"kind\": \"method\"}\n    {\"_type\": \"completed\", \"command\": \"generate-tags\"}\n"
  },
  {
    "path": "docs/internal.rst",
    "content": ".. ctags Internal API\n.. ---------------------------------------------------------------------\n\n.. _input-text-stream:\n\nInput text stream\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. figure:: input-text-stream.svg\n\t    :scale: 80%\n\nFunction prototypes for handling input text stream are declared in\n``main/read.h``. The file exists in Exuberant Ctags, too.  However, the\nnames functions are changed when overhauling ``--line-directive``\noption. (In addition macros were converted to functions for making\ndata structures for the input text stream opaque.)\n\nCtags has 3 groups of functions for handling input: *input*, *bypass*, and\n*raw*. Parser developers should use input group. The rest of two\nare for ctags main part.\n\n\n.. _inputFile:\n\n`inputFile` type and the functions of input group\n......................................................................\n\n.. note:: The original version of this section was written\n\tbefore ``inputFile`` type and ``File`` variable are made private.\n\n``inputFile`` is the type for representing the input file and stream for\na parser. It was declared in ``main/read.h`` but now it is defined in\n``main/read.c``.\n\nCtags uses a file static variable ``File`` having type ``inputFile`` for\nmaintaining the input file and stream. ``File`` is also defined in\nmain/read.c as ``inputFile`` is.\n\n``fp`` and ``line`` are the essential fields of ``File``. ``fp`` having type\nwell known ``MIO`` declared in ``main/mio.h``. By calling functions of input group\n(``getcFromInputFile`` and ``readLineFromInputFile``), a parser gets input\ntext from ``fp``.\n\nThe functions of input group updates fields ``input`` and ``source`` of ``File`` variable.\nThese two fields has type ``inputFileInfo``. These two fields are for mainly\ntracking the name of file and the current line number. Usually ctags uses\nonly ``input`` field. ``source`` field is used only when ``#line`` directive is found\nin the current input text stream.\n\nA case when a tool generates the input file from another file, a tool\ncan record the original source file to the generated file with using\nthe ``#line`` directive. ``source`` field is used for tracking/recording the\ninformation appeared on ``#line`` directives.\n\nRegex pattern matching are also done behind calling the functions of\nthis group.\n\n\nThe functions of bypass group\n......................................................................\nThe functions of bypass group (``readLineFromBypass`` and\n``readLineFromBypassSlow``) are used for reading text from ``fp`` field of\n``File`` static variable without updating ``input`` and ``source`` fields of\n``File`` variable.\n\n\nParsers may not need the functions of this group.  The functions are\nused in ctags main part. The functions are used to make pattern\nfields of tags file, for example.\n\n\nThe functions of raw group\n......................................................................\nThe functions of this group (``readLineRaw`` and ``readLineRawWithNoSeek``)\ntake a parameter having type ``MIO``; and don't touch ``File`` static\nvariable.\n\nParsers may not need the functions of this group.  The functions are\nused in ctags main part. The functions are used to load option files,\nfor example.\n\n\nEscaping and unescaping input fields\n......................................................................\n\n.. figure:: input-escaping.svg\n\t    :scale: 80%\n\n.. figure:: input-unescaping.svg\n\t    :scale: 80%\n\n.. NOT REVIEWED YET\n\n.. _output-tag-stream:\n\nOutput tag stream\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. figure:: output-tag-stream.svg\n\t    :scale: 80%\n\nCtags provides ``makeTagEntry`` to parsers as an entry point for writing\ntag information to MIO. ``makeTagEntry`` calls ``writeTagEntry`` if the\nparser does not set ``CORK_QUEUE`` to ``useCork`` field. ``writeTagEntry`` calls ``writerWriteTag``.\n``writerWriteTag`` just calls ``writeEntry`` of writer backends.\n``writerTable`` variable holds the four backends: ctagsWriter, etagsWriter,\nxrefWriter, and jsonWriter.\nOne of them is chosen depending on the arguments passed to ctags.\n\nIf ``CORK_QUEUE`` is set to ``useCork``, the tag information goes to a queue on memory.\nThe queue is flushed when ``useCork`` in unset. See \"`cork API`_\" for more\ndetails.\n\ncork API\n......................................................................\n\nBackground and Idea\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n*cork API* is introduced for recording scope information easier.\n\nBefore introducing cork API, a scope information must be recorded as\nstrings. It is flexible but memory management is required.\nFollowing code is taken from ``clojure.c`` (with some modifications).\n\n.. code-block:: c\n\n\t\tif (vStringLength (parent) > 0)\n\t\t{\n\t\t\tcurrent.extensionFields.scopeKind = ClojureKinds[K_NAMESPACE].name;\n\t\t\tcurrent.extensionFields.scopeName = vStringValue (parent);\n\t\t}\n\n\t\tmakeTagEntry (&current);\n\n``parent``, ``scopeKind`` and ``scopeName`` are vStrings. The parser must manage\ntheir life cycles; the parser cannot free them till the tag referring them via\nits scope fields are emitted, and must free them after emitting.\n\ncork API provides more solid way to hold scope information. cork API\nexpects ``parent``, which represents scope of a tag(``current``)\ncurrently parser dealing, is recorded to a *tags* file before recording\nthe ``current`` tag via ``makeTagEntry`` function.\n\nFor passing the information about ``parent`` to ``makeTagEntry``,\n``tagEntryInfo`` object was created. It was used just for recording; and\nfreed after recording.  In cork API, it is not freed after recording;\na parser can reused it as scope information.\n\nHow to use\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nSee a commit titled with \"`clojure: use cork <https://github.com/universal-ctags/ctags/commit/ef181e6>`_\".\nI applied cork API to the clojure parser.\n\nCork API can be enabled and disabled per parser,\nand is disabled by default. So there is no impact till you\nenables it in your parser.\n\n``useCork`` field is introduced in ``parserDefinition`` type:\n\n.. code-block:: c\n\n\t\ttypedef struct {\n\t\t...\n\t\t\t\tunsigned int useCork;\n\t\t...\n\t\t} parserDefinition;\n\nSet ``CORK_QUEUE`` to ``useCork`` like:\n\n.. code-block:: c\n\n    extern parserDefinition *ClojureParser (void)\n    {\n\t    ...\n\t    parserDefinition *def = parserNew (\"Clojure\");\n\t    ...\n\t    def->useCork = CORK_QUEUE;\n\t    return def;\n    }\n\nWhen ctags running a parser with ``useCork`` being ``CORK_QUEUE``, all output\nrequested via ``makeTagEntry`` function calling is stored to an internal\nqueue, not to ``tags`` file.  When parsing an input file is done, the\ntag information stored automatically to the queue are flushed to\n``tags`` file in batch.\n\nWhen calling ``makeTagEntry`` with a ``tagEntryInfo`` object (``parent``),\nit returns an integer. The integer can be used as handle for referring\nthe object after calling.\n\n\n.. code-block:: c\n\n\t\tint parent = CORK_NIL;\n\t\t...\n\t\tparent = makeTagEntry (&e);\n\nThe handle can be used by setting to a ``scopeIndex``\nfield of ``current`` tag, which is in the scope of ``parent``.\n\n.. code-block:: c\n\n\t\tcurrent.extensionFields.scopeIndex = parent;\n\nWhen passing ``current`` to ``makeTagEntry``, the ``scopeIndex`` is\nreferred for emitting the scope information of ``current``.\n\n``scopeIndex`` must be set to ``CORK_NIL`` if a tag is not in any scope.\nWhen using ``scopeIndex`` of ``current``, ``KIND_GHOST_INDEX`` must be assigned\nto ``current.extensionFields.scopeKindIndex`` and  ``NULL`` must be assigned to\n``current.extensionFields.scopeName``.  ``initTagEntry`` function does this\ninitialization internally, so you generally you don't have to write\nthe initialization explicitly.\n\nAutomatic full qualified tag generation\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIf a parser uses the cork API for recording and emitting scope\ninformation, ctags can reuse it for generating *full qualified (FQ)\ntags*. Set ``requestAutomaticFQTag`` field of ``parserDefinition`` to\n``TRUE`` then the main part of ctags emits FQ tags on behalf of the parser\nif ``--extras=+q`` is given.\n\nAn example can be found in DTS parser:\n\n.. code-block:: c\n\n    extern parserDefinition* DTSParser (void)\n    {\n\t    static const char *const extensions [] = { \"dts\", \"dtsi\", NULL };\n\t    parserDefinition* const def = parserNew (\"DTS\");\n\t    ...\n\t    def->requestAutomaticFQTag = TRUE;\n\t    return def;\n    }\n\nSetting ``requestAutomaticFQTag`` to ``TRUE`` implies setting\n``useCork`` to ``CORK_QUEUE``.\n\n.. NOT REVIEWED YET\n\n.. _symtabAPI:\n\nsymbol table API\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n*symbol table* API is an extension to the cork API. The cork API was\nintroduced to provide the simple way to represent mapping (*forward\nmapping*) from a language object (*child object*) to its upper scope\n(*parent object*). *symbol table* API is for representing the mapping\n(*reverse mapping*) opposite direction; you can look up (or traverse)\nchild tags defined (or used) in a given tag.\n\nTo use this API, a parser must set ``CORK_SYMTAB`` to ``useCork`` member\nof ``parserDefinition`` in addition to setting ``CORK_QUEUE`` as preparation.\n\nAn example taken from R parser:\n\n.. code-block:: c\n\n\textern parserDefinition *RParser (void)\n\t{\n\t\tstatic const char *const extensions[] = { \"r\", \"R\", \"s\", \"q\", NULL };\n\t\tparserDefinition *const def = parserNew (\"R\");\n\n\t\t...\n\n\t\tdef->useCork = CORK_QUEUE | CORK_SYMTAB;\n\n\t\t...\n\n\t\treturn def;\n\t}\n\n\nTo install a reverse mapping between a parent and its child tags,\ncall ``registerEntry`` with the cork index for a child after making\nthe child tag filling ``scopeIndex``:\n\n.. code-block:: c\n\n\tint parent = CORK_NIL;\n\t...\n\tparent = makeTagEntry (&e_parent);\n\n\t...\n\n\ttagEntryInfo e_child;\n\t...\n\tinitTagEntry (&e_child, ...);\n\te_child.extensionFields.scopeIndex = parent;    /* setting up forward mapping */\n\t...\n\tint child = makeTagEntry (&e_child);\n\n\tregisterEntry (child);                          /* setting up reverse mapping */\n\n``registerEntry`` stores ``child`` to the symbol table of ``parent``.\nIf ``scopeIndex`` of ``child`` is ``CORK_NIL``, the ``child`` is stores\nto the *toplevel scope*.\n\n``unregisterEntry`` is for clearing (and updating) the reverse mapping\nof a child. Consider the case you want to change the scope of ``child``\nfrom ``newParent``.\n\n.. code-block:: c\n\n\tunregisterEntry (child);                         /* delete the reverse mapping. */\n\ttagEntryInfo *e_child = getEntryInCorkQueue (child);\n\te_child->extensionFields.scopeIndex = newParent; /* update the forward mapping. */\n\tregisterEntry (child);                           /* set the new reverse mapping. */\n\n``foreachEntriesInScope`` is the function for traversing all child\ntags stored to the parent tag specified with ``corkIndex``.\nIf the ``corkIndex`` is ``CORK_NIL``, the children defined (and/or\nused) in *toplevel scope*  are traversed.\n\n.. code-block:: c\n\n\ttypedef bool (* entryForeachFunc) (int corkIndex,\n\t\t\t\t\t\t\t\t\t   tagEntryInfo * entry,\n\t\t\t\t\t\t\t\t\t   void * data);\n\tbool          foreachEntriesInScope (int corkIndex,\n\t\t\t\t\t\t\t\t\t\t const char *name, /* or NULL */\n\t\t\t\t\t\t\t\t\t\t entryForeachFunc func,\n\t\t\t\t\t\t\t\t\t\t void *data);\n\n``foreachEntriesInScope``  takes a ``foreachEntriesInScope`` typed\ncallback function.  ``foreachEntriesInScope`` passes the cork\nindex and a pointer for ``tagEntryInfo`` object of children.\n\n`anyEntryInScope` is a function for finding a child tag stored\nto the parent tag specified with ``corkIndex``. It returns\nthe cork index for the child tag. If ``corkIndex`` is ``CORK_NIL``,\n`anyEntryInScope` finds a tag stored to the toplevel scope.\nThe returned child tag has ``name`` as its name as far as ``name``\nis not ``NULL``.\n\n.. code-block:: c\n\n\tint           anyEntryInScope       (int corkIndex,\n\t\t\t\t\t\t\t\t\t\t const char *name,\n\t\t\t\t\t\t\t\t\t\t bool onlyDefinitionTag);\n\n\n.. _tokeninfo:\n\ntokenInfo API\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIn Exuberant Ctags, a developer can write a parser anyway; only input\nstream and tagEntryInfo data structure is given.\n\nHowever, while maintaining Universal Ctags I (Masatake YAMATO) think\nwe should have a framework for writing parser. Of course the framework\nis optional; you can still write a parser without the framework.\n\nTo design a framework, I have studied how @b4n (Colomban Wendling)\nwrites parsers. tokenInfo API is the first fruit of my study.\n\nTBW\n\nMultiple parsers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. _promiseAPI:\n\nGuest parser (promise API)\n......................................................................\n\nSee \":ref:`host-guest-parsers`\" about the concept of guest parsers.\n\nBackground and Idea\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nMore than one programming languages can be used in one input text stream.\n*promise API* allows a host parser running a :ref:`guest parser\n<host-guest-parsers>` in the specified area of input text stream.\n\ne.g. Code written in c language (C code) is embedded\nin code written in Yacc language (Yacc code). Let's think about this\ninput stream.\n\n.. code-block:: yacc\n\n   /* foo.y */\n    %token\n\t    END_OF_FILE\t0\n\t    ERROR\t\t255\n\t    BELL\t\t1\n\n    %{\n    /* C language */\n    int counter;\n    %}\n    %right\tEQUALS\n    %left\tPLUS MINUS\n    ...\n    %%\n    CfgFile\t\t:\tCfgEntryList\n\t\t\t    { InterpretConfigs($1); }\n\t\t    ;\n\n    ...\n    %%\n    int\n    yyerror(char *s)\n    {\n\t(void)fprintf(stderr,\"%s: line %d of %s\\n\",s,lineNum,\n\t\t\t\t\t    (scanFile?scanFile:\"(unknown)\"));\n\tif (scanStr)\n\t    (void)fprintf(stderr,\"last scanned symbol is: %s\\n\",scanStr);\n\treturn 1;\n    }\n\nIn the input the area started from ``%{`` to ``%}`` and the area started from\nthe second ``%%`` to the end of file are written in C. Yacc can be called\n*host language*, and C can be called *guest language*.\n\nCtags may choose the Yacc parser for the input. However, the parser\ndoesn't know about C syntax. Implementing C parser in the Yacc parser\nis one of approach. However, ctags has already C parser.  The Yacc\nparser should utilize the existing C parser. The promise API allows this.\n\nSee also \":ref:`host-guest-parsers`\" about more concept and examples of the\nguest parser.\n\nUsage\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nSee a commit titled with \"`Yacc: run C parser in the areas where code\nis written in C <https://github.com/universal-ctags/ctags/commit/757673f>`_\".\nI applied promise API to the Yacc parser.\n\nThe parser for host language must track and record the ``start`` and the\n``end`` of a guest language. Pairs of ``line number`` and ``byte offset``\nrepresents the ``start`` and ``end``. When the ``start`` and ``end`` are\nfixed, call ``makePromise`` with (1) the guest parser name, (2) ``start``,\nand (3) ``end``. (This description is a bit simplified the real usage.)\n\n\nLet's see the actual code from \"`parsers/yacc.c\n<https://github.com/universal-ctags/ctags/blob/29f3d603a3884fb5b9834402a20c9589e694b819/parsers/yacc.c>`_\".\n\n.. code-block:: c\n\n\tstruct cStart {\n\t\tunsigned long input;\n\t\tunsigned long source;\n\t};\n\nBoth fields are for recording ``start``. ``input`` field\nis for recording the value returned from ``getInputLineNumber``.\n``source`` is for ``getSourceLineNumber``. See \"`inputFile`_\" for the\ndifference of the two.\n\n``enter_c_prologue`` shown in the next is a function called when ``%{`` is\nfound in the current input text stream. Remember, in yacc syntax, ``%{``\nis a marker of C code area.\n\n.. code-block:: c\n\n    static void enter_c_prologue (const char *line CTAGS_ATTR_UNUSED,\n\t\t\t\t const regexMatch *matches CTAGS_ATTR_UNUSED,\n\t\t\t\t unsigned int count CTAGS_ATTR_UNUSED,\n\t\t\t\t void *data)\n    {\n\t   struct cStart *cstart = data;\n\n\n\t   readLineFromInputFile ();\n\t   cstart->input  = getInputLineNumber ();\n\t   cstart->source = getSourceLineNumber ();\n    }\n\n\nThe function just records the start line.  It calls\n``readLineFromInputFile`` because the C code may start the next line of\nthe line where the marker is.\n\n``leave_c_prologue`` shown in the next is a function called when ``%}``,\nthe end marker of C code area, is found in the current input text stream.\n\n.. code-block:: c\n\n    static void leave_c_prologue (const char *line CTAGS_ATTR_UNUSED,\n\t\t\t\t const regexMatch *matches CTAGS_ATTR_UNUSED,\n\t\t\t\t unsigned int count CTAGS_ATTR_UNUSED,\n\t\t\t\t void *data)\n    {\n\t   struct cStart *cstart = data;\n\t   unsigned long c_end;\n\n\t   c_end = getInputLineNumber ();\n\t   makePromise (\"C\", cstart->input, 0, c_end, 0, cstart->source);\n    }\n\nAfter recording the line number of the end of the C code area,\n``leave_c_prologue`` calls ``makePromise``.\n\nOf course ``\"C\"`` stands for C language, the name of guest parser.\nAvailable parser names can be listed by running ctags with\n``--list-languages`` option. In this example two ``0`` characters are provided as\nthe 3rd and 5th argument. They are byte offsets of the start and the end of the\nC language area from the beginning of the line which is 0 in this case. In\ngeneral, the guest language's section does not have to start at the beginning of\nthe line in which case the two offsets have to be provided. Parsers reading\nthe input character by character can obtain the current offset by calling\n``getInputLineOffset()``.\n\nIn some cases, you may want to specifying the offset of the end of\nline (EOL).  A macro ``EOL_CHAR_OFFSET`` defined in ``main/promise.h``\ncan be used for specifying EOL in abstracted way; you don't have to find\nthe real offset for the EOL.\n\nInternal design\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. figure:: promise.svg\n\t    :scale: 80%\n\nA host parser cannot run a guest parser directly. What the host parser\ncan do is just asking the ctags main part scheduling of running the\nguest parser for specified area which defined with the ``start`` and\n``end``. These scheduling requests are called *promises*.\n\nAfter running the host parser, before closing the input stream, the\nctags main part checks the existence of promise(s). If there is, the\nmain part makes a sub input stream and run the guest parser specified\nin the promise. The sub input stream is made from the original input\nstream by narrowing as requested in the promise. The main part\niterates the above process till there is no promise.\n\nTheoretically a guest parser can be nested; it can make a promise.\nThe level 2 guest is also just scheduled. (However, I have never\ntested such a nested guest parser).\n\nWhy not running the guest parser directly from the context of the host\nparser? Remember many parsers have their own file static variables. If\na parser is called from the parser, the variables may be crashed.\n\nAPI for subparser\n......................................................................\n\nSee \":ref:`base-sub-parsers`\" about the concept of subparser.\n\n.. note:: Consider using optlib when implementing a subparser. It is much more\n\teasy and simple. See \":ref:`defining-subparsers`\" for details.\n\nOutline\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nYou have to work on both sides: a base parser and subparsers.\n\nA base parser must define a data structure type (``baseMethodTable``) for\nits subparsers by extending ``struct subparser`` defined in\n``main/subparser.h``.  A subparser defines a variable (``subparser var``)\nhaving type ``baseMethodTable`` by filling its fields and registers\n``subparser var`` to the base parser using dependency API.\n\nThe base parser calls functions pointed by ``baseMethodTable`` of\nsubparsers during parsing. A function for probing a higher level\nlanguage may be included in ``baseMethodTable``.  What kind of fields\nshould be included in ``baseMethodTable`` is up to the design of a base\nparser and the requirements of its subparsers. A method for\nprobing is one of them.\n\nRegistering a ``subparser var`` to a base parser is enough for the\nbottom up choice. For handling the top down choice (e.g. specifying\n``--language-force=<subparser>`` in a command line), more code is needed.\n\nIn the top down choice, the subparser must call ``scheduleRunningBasepaser``,\ndeclared in ``main/subparser.h``, in its ``parser`` method.\nHere, ``parser`` method means a function assigned to the ``parser`` member of\nthe ``parserDefinition`` of the subparser.\n``scheduleRunningBaseparser`` takes an integer argument\nthat specifies the dependency used for registering the ``subparser var``.\n\nBy extending ``struct subparser`` you can define a type for\nyour subparser. Then make a variable for the type and\ndeclare a dependency on the base parser.\n\nFields of ``subparser`` type\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nHere the source code of Autoconf/m4 parsers is referred as an example.\n\n``main/types.h``:\n\n.. code-block:: C\n\n    struct sSubparser;\n    typedef struct sSubparser subparser;\n\n\n``main/subparser.h``:\n\n.. code-block:: C\n\n    typedef enum eSubparserRunDirection {\n\t    SUBPARSER_BASE_RUNS_SUB = 1 << 0,\n\t    SUBPARSER_SUB_RUNS_BASE = 1 << 1,\n\t    SUBPARSER_BI_DIRECTION  = SUBPARSER_BASE_RUNS_SUB|SUBPARSER_SUB_RUNS_BASE,\n    } subparserRunDirection;\n\n    struct sSubparser {\n\t    ...\n\n\t    /* public to the parser */\n\t    subparserRunDirection direction;\n\n\t    void (* inputStart) (subparser *s);\n\t    void (* inputEnd) (subparser *s);\n\t    void (* exclusiveSubparserChosenNotify) (subparser *s, void *data);\n    };\n\nA subparser must fill the fields of ``subparser``.\n\n``direction`` field specifies how the subparser is called. See\n\":ref:`multiple_parsers_directions`\" in \":ref:`multiple_parsers`\" about\n*direction flags*, and see \":ref:`optlib_directions`\" in \":ref:`optlib`\" for\nexamples of using the direction flags.\n\n===========================  ======================\n``direction`` field          Direction Flag\n===========================  ======================\n``SUBPARSER_BASE_RUNS_SUB``  ``shared`` (default)\n``SUBPARSER_SUB_RUNS_BASE``  ``dedicated``\n``SUBPARSER_BI_DIRECTION``   ``bidirectional``\n===========================  ======================\n\nIf a subparser runs exclusively and is chosen in top down way, set\n``SUBPARSER_SUB_RUNS_BASE`` flag. If a subparser runs coexisting way and\nis chosen in bottom up way, set ``SUBPARSER_BASE_RUNS_SUB``.  Use\n``SUBPARSER_BI_DIRECTION`` if both cases can be considered.\n\nSystemdUnit parser runs as a subparser of iniconf base parser.\nSystemdUnit parser specifies ``SUBPARSER_SUB_RUNS_BASE`` because\nunit files of systemd have very specific file extensions though\nthey are written in iniconf syntax. Therefore we expect SystemdUnit\nparser is chosen in top down way. The same logic is applicable to\nYumRepo parser.\n\nAutoconf parser specifies ``SUBPARSER_BI_DIRECTION``. For input\nfile having name ``configure.ac``, by pattern matching, Autoconf parser\nis chosen in top down way. In other hand, for file name ``foo.m4``,\nAutoconf parser can be chosen in bottom up way.\n\n.. TODO: Write about SUBPARSER_BASE_RUNS_SUB after implementing python-celery.\n\n``inputStart`` is called before the base parser starting parsing a new input file.\n``inputEnd`` is called after the base parser finishing parsing the input file.\nUniversal Ctags main part calls these methods. Therefore, a base parser doesn't\nhave to call them.\n\n``exclusiveSubparserChosenNotify`` is called when a parser is chosen\nas an exclusive parser. Calling this method is a job of a base parser.\n\n\nExtending ``subparser`` type\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe m4 parser extends ``subparser`` type like following:\n\n``parsers/m4.h``:\n\n.. code-block:: C\n\n    typedef struct sM4Subparser m4Subparser;\n    struct sM4Subparser {\n\t    subparser subparser;\n\n\t    bool (* probeLanguage) (m4Subparser *m4, const char* token);\n\n\t    /* return value: Cork index */\n\t    int  (* newMacroNotify) (m4Subparser *m4, const char* token);\n\n\t    bool (* doesLineCommentStart)   (m4Subparser *m4, int c, const char *token);\n\t    bool (* doesStringLiteralStart) (m4Subparser *m4, int c);\n    };\n\n\nPut ``subparser`` as the first member of the extended struct (here sM4Subparser).\nIn addition the first field, 4 methods are defined in the extended struct.\n\nTill choosing a subparser for the current input file, the m4 parser calls\n``probeLanguage`` method of its subparsers each time when find a token\nin the input file. A subparser returns ``true`` if it recognizes the\ninput file is for the itself by analyzing tokens passed from the\nbase parser.\n\n``parsers/autoconf.c``:\n\n.. code-block:: C\n\n    extern parserDefinition* AutoconfParser (void)\n    {\n\t    static const char *const patterns [] = { \"configure.in\", NULL };\n\t    static const char *const extensions [] = { \"ac\", NULL };\n\t    parserDefinition* const def = parserNew(\"Autoconf\");\n\n\t    static m4Subparser autoconfSubparser = {\n\t\t    .subparser = {\n\t\t\t    .direction = SUBPARSER_BI_DIRECTION,\n\t\t\t    .exclusiveSubparserChosenNotify = exclusiveSubparserChosenCallback,\n\t\t    },\n\t\t    .probeLanguage  = probeLanguage,\n\t\t    .newMacroNotify = newMacroCallback,\n\t\t    .doesLineCommentStart = doesLineCommentStart,\n\t\t    .doesStringLiteralStart = doesStringLiteralStart,\n\t    };\n\n``probeLanguage`` function defined in ``autoconf.c`` is connected to\nthe ``probeLanguage`` member of ``autoconfSubparser``. The ``probeLanguage`` function\nof Autoconf is very simple:\n\n``parsers/autoconf.c``:\n\n.. code-block:: C\n\n    static bool probeLanguage (m4Subparser *m4, const char* token)\n    {\n\t    return strncmp (token, \"m4_\", 3) == 0\n\t\t    || strncmp (token, \"AC_\", 3) == 0\n\t\t    || strncmp (token, \"AM_\", 3) == 0\n\t\t    || strncmp (token, \"AS_\", 3) == 0\n\t\t    || strncmp (token, \"AH_\", 3) == 0\n\t\t    ;\n    }\n\nThis function checks the prefix of passed tokens. If known\nprefix is found, Autoconf assumes this is an Autoconf input\nand returns ``true``.\n\n``parsers/m4.c``:\n\n.. code-block:: C\n\n\t\tif (m4tmp->probeLanguage\n\t\t\t&& m4tmp->probeLanguage (m4tmp, token))\n\t\t{\n\t\t\tchooseExclusiveSubparser ((m4Subparser *)tmp, NULL);\n\t\t\tm4found = m4tmp;\n\t\t}\n\nThe m4 parsers calls ``probeLanguage`` function of a subparser. If ``true``\nis returned ``chooseExclusiveSubparser`` function which is defined\nin the main part. ``chooseExclusiveSubparser`` calls\n``exclusiveSubparserChosenNotify`` method of the chosen subparser.\n\nThe method is implemented in Autoconf subparser like following:\n\n``parsers/autoconf.c``:\n\n.. code-block:: C\n\n    static void exclusiveSubparserChosenCallback (subparser *s, void *data)\n    {\n\t    setM4Quotes ('[', ']');\n    }\n\nIt changes quote characters of the m4 parser.\n\n\nMaking a tag in a subparser\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nVia calling callback functions defined in subparsers, their base parser\ngives chance to them making tag entries.\n\nThe m4 parser calls ``newMacroNotify`` method when it finds an m4 macro is used.\nThe Autoconf parser connects ``newMacroCallback`` function defined in ``parser/autoconf.c``.\n\n\n``parsers/autoconf.c``:\n\n\n.. code-block:: C\n\n    static int newMacroCallback (m4Subparser *m4, const char* token)\n    {\n\t    int keyword;\n\t    int index = CORK_NIL;\n\n\t    keyword = lookupKeyword (token, getInputLanguage ());\n\n\t    /* TODO:\n\t       AH_VERBATIM\n\t     */\n\t    switch (keyword)\n\t    {\n\t    case KEYWORD_NONE:\n\t\t    break;\n\t    case KEYWORD_init:\n\t\t    index = makeAutoconfTag (PACKAGE_KIND);\n\t\t    break;\n\n    ...\n\n    extern parserDefinition* AutoconfParser (void)\n    {\n\t    ...\n\t    static m4Subparser autoconfSubparser = {\n\t\t    .subparser = {\n\t\t\t    .direction = SUBPARSER_BI_DIRECTION,\n\t\t\t    .exclusiveSubparserChosenNotify = exclusiveSubparserChosenCallback,\n\t\t    },\n\t\t    .probeLanguage  = probeLanguage,\n\t\t    .newMacroNotify = newMacroCallback,\n\nIn ``newMacroCallback`` function, the Autoconf parser receives the name of macro\nfound by the base parser and analysis whether the macro is interesting\nin the context of Autoconf language or not. If it is interesting name,\nthe Autoconf parser makes a tag for it.\n\n\nCalling methods of subparsers from a base parser\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nA base parser can use ``foreachSubparser`` macro for accessing its\nsubparsers. A base should call ``enterSubparser`` before calling a\nmethod of a subparser, and call ``leaveSubparser`` after calling the\nmethod. The macro and functions are declare in ``main/subparser.h`` .\n\n\n``parsers/m4.c``:\n\n.. code-block:: C\n\n    static m4Subparser * maySwitchLanguage (const char* token)\n    {\n\t    subparser *tmp;\n\t    m4Subparser *m4found = NULL;\n\n\t    foreachSubparser (tmp, false)\n\t    {\n\t\t    m4Subparser *m4tmp = (m4Subparser *)tmp;\n\n\t\t    enterSubparser(tmp);\n\t\t    if (m4tmp->probeLanguage\n\t\t\t    && m4tmp->probeLanguage (m4tmp, token))\n\t\t    {\n\t\t\t    chooseExclusiveSubparser (tmp, NULL);\n\t\t\t    m4found = m4tmp;\n\t\t    }\n\t\t    leaveSubparser();\n\n\t\t    if (m4found)\n\t\t\t    break;\n\t    }\n\n\t    return m4found;\n    }\n\n``foreachSubparser`` takes a variable having type ``subparser``.\nFor each iteration, the value for the variable is updated.\n\n``enterSubparser`` takes a variable having type ``subparser``.  With the\ncalling ``enterSubparser``, the current language (the value returned from\n``getInputLanguage``) can be temporary switched to the language specified\nwith the variable. One of the effect of switching is that ``language``\nfield of tags made in the callback function called between\n``enterSubparser`` and ``leaveSubparser`` is adjusted.\n\nRegistering a subparser to its base parser\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nUse ``DEPTYPE_SUBPARSER`` dependency in a subparser for registration.\n\n``parsers/autoconf.c``:\n\n.. code-block:: C\n\n    extern parserDefinition* AutoconfParser (void)\n    {\n\t    parserDefinition* const def = parserNew(\"Autoconf\");\n\n\t    static m4Subparser autoconfSubparser = {\n\t\t    .subparser = {\n\t\t\t    .direction = SUBPARSER_BI_DIRECTION,\n\t\t\t    .exclusiveSubparserChosenNotify = exclusiveSubparserChosenCallback,\n\t\t    },\n\t\t    .probeLanguage  = probeLanguage,\n\t\t    .newMacroNotify = newMacroCallback,\n\t\t    .doesLineCommentStart = doesLineCommentStart,\n\t\t    .doesStringLiteralStart = doesStringLiteralStart,\n\t    };\n\t    static parserDependency dependencies [] = {\n\t\t    [0] = { DEPTYPE_SUBPARSER, \"M4\", &autoconfSubparser },\n\t    };\n\n\t    def->dependencies = dependencies;\n\t    def->dependencyCount = ARRAY_SIZE (dependencies);\n\n\n``DEPTYPE_SUBPARSER`` is specified in the 0th element of ``dependencies``\nfunction static variable. In the next a literal string \"M4\" is\nspecified and ``autoconfSubparser`` follows. The intent of the code is\nregistering ``autoconfSubparser`` subparser definition to a base parser\nnamed \"M4\".\n\n``dependencies`` function static variable must be assigned to\n``dependencies`` fields of a variable of ``parserDefinition``.\nThe main part of Universal Ctags refers the field when\ninitializing parsers.\n\n``[0]`` emphasizes this is \"the 0th element\". The subparser may refer\nthe index of the array when the subparser calls\n``scheduleRunningBaseparser``.\n\n\nScheduling running the base parser\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nFor the case that a subparser is chosen in top down, the subparser\nmust call ``scheduleRunningBaseparser`` in the main ``parser`` method.\n\n``parsers/autoconf.c``:\n\n.. code-block:: C\n\n    static void findAutoconfTags(void)\n    {\n\t    scheduleRunningBaseparser (0);\n    }\n\n    extern parserDefinition* AutoconfParser (void)\n    {\n\t    ...\n\t    parserDefinition* const def = parserNew(\"Autoconf\");\n\t    ...\n\t    static parserDependency dependencies [] = {\n\t\t    [0] = { DEPTYPE_SUBPARSER, \"M4\", &autoconfSubparser },\n\t    };\n\n\t    def->dependencies = dependencies;\n\t    ...\n\t    def->parser = findAutoconfTags;\n\t    ...\n\t    return def;\n    }\n\nA subparser can do nothing actively. A base parser makes its subparser\nwork by calling methods of the subparser.  Therefore a subparser must\nrun its base parser when the subparser is chosen in a top down way,\nThe main part prepares ``scheduleRunningBaseparser`` function for the purpose.\n\nA subparser should call the function from ``parser`` method of ``parserDefinition``\nof the subparser. ``scheduleRunningBaseparser`` takes an integer. It specifies\nan index of the dependency which is used for registering the subparser.\n\n\nPackCC compiler-compiler\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nPackCC is a compiler-compiler; it translates ``.peg`` grammar file to ``.c``\nfile.  PackCC was originally written by Arihiro Yoshida. Its source\nrepository is at https://github.com/arithy/packcc.\n\nThe source tree of PackCC is grafted at ``misc/packcc`` directory.\nBuilding PackCC and ctags are integrated in the build-scripts of\nUniversal Ctags.\n\nRefer `peg/valink.peg\n<https://github.com/universal-ctags/ctags/blob/master/peg/varlink.peg>`_ as a\nsample of a parser using PackCC.\n\nNull tags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n*Null tag* is a tag having an empty string as its name.\n\nUniversal Ctags supports null tags cautiously.\nSee the description for ``nulltag``/``z`` extra in :ref:`ctags(1) <ctags(1)>`.\n\nIf you want to make a null tag, set 1 to ``allowNullTag`` of\n``tagEtnryInfo`` before calling ``makeTagEntry``.  ``makeTagEntry``\nevaluates the member. The following pseudo code doesn't work:\n\n.. code-block:: C\n\n   tagEntryInfo e;\n   /* ... */\n   int corkIndex = makeTagEntry (&e);\n   /* ... */\n   tagEntryInfo *p = getEntryInCorkQueue (corkIndex);\n   p->allowNullTag = 1;\n\nAutomatic parser guessing (TBW)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nManaging regular expression parsers (TBW)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nGhost kind in regex parser (TBW)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. TODO: Q: what is the point of documenting this?\n\tfrom comment on #2916: I (@masatake) must explain the ghost kind.\n\tfrom comment on #2916:\n\t\tI (@masatake) found I must explain \"placeholder tag\". The ghost kind is\n\t\tuseful for fill the find field of the placeholder tag. I will write about\n\t\tthe Ghost kind when I write about the placeholder tag. I will write about\n\t\tthe placeholder tag when I write about Optscript.\n\n\tIf a whitespace is used as a kind letter, it is never printed when\n\tctags is called with ``--list-kinds`` option.  This kind is\n\tautomatically assigned to an empty name pattern.\n\n\tNormally you don't need to know this.\n"
  },
  {
    "path": "docs/man/ctags-client-tools.7.rst",
    "content": ".. _ctags-client-tools(7):\n\n==============================================================\nctags-client-tools\n==============================================================\n\nHints for developing a tool using ctags command and tags output\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** [options] [file(s)]\n|\t**etags** [options] [file(s)]\n\n\nDESCRIPTION\n-----------\n**Client tool** means a tool running the ctags command\nand/or reading a tags file generated by ctags command.\nThis man page gathers hints for people who develop client tools.\n\n\nPSEUDO-TAGS\n-----------\n**Pseudo-tags**, stored in a tag file, indicate how\nctags generated the tags file: whether the\ntags file is sorted or not, which version of tags file format is used,\nthe name of tags generator, and so on. The opposite term for\npseudo-tags is **regular-tags**. A regular-tag is for a language\nobject in an input file. A pseudo-tag is for the tags file\nitself. Client tools may use pseudo-tags as reference for processing\nregular-tags.\n\nA pseudo-tag is stored in a tags file in the same format as\nregular-tags as described in :ref:`tags(5) <tags(5)>`, except that pseudo-tag names\nare prefixed with \"!_\". For the general information about\npseudo-tags, see \"TAG FILE INFORMATION\" in :ref:`tags(5) <tags(5)>`.\n\nAn example of a pseudo tag::\n\n\t!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n\nThe value, \"Universal Ctags\", associated with the pseudo tag ``TAG_PROGRAM_NAME``, is\nused in the field for input file. The description, \"Derived from\nExuberant Ctags\", is used in the field for pattern.\n\nUniversal Ctags extends the naming scheme of the classical pseudo-tags\navailable in Exuberant Ctags for emitting language specific\ninformation as pseudo tags::\n\n\t!_{pseudo-tag-name}!{language-name}\t{associated-value}\t/{description}/\n\nThe language-name is appended to the pseudo-tag name with a separator, \"!\".\n\nAn example of pseudo tag with a language suffix::\n\n\t!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n\nThis pseudo-tag says \"the function kind of C language is enabled\nwhen generating this tags file.\" ``--pseudo-tags`` is the option for\nenabling/disabling individual pseudo-tags. When enabling/disabling a\npseudo tag with the option, specify the tag name only\n``TAG_KIND_DESCRIPTION``, without the prefix (\"!_\") or the suffix (\"!C\").\n\n\nOptions for Pseudo-tags\n~~~~~~~~~~~~~~~~~~~~~~~\n``--extras=+p`` (or ``--extras=+{pseudo}``)\n\tForces writing pseudo-tags.\n\n\tctags emits pseudo-tags by default when writing tags\n\tto a regular file (e.g. \"tags'.) However, when specifying ``-o -``\n\tor ``-f -`` for writing tags to standard output,\n\tctags doesn't emit pseudo-tags. ``--extras=+p`` or\n\t``--extras=+{pseudo}`` will force pseudo-tags to be written.\n\n``--list-pseudo-tags``\n\tLists available types of pseudo-tags and shows whether they are enabled or disabled.\n\n\tRunning ctags with ``--list-pseudo-tags`` option\n\tlists available pseudo-tags. Some of pseudo-tags newly introduced\n\tin Universal Ctags project are disabled by default. Use\n\t``--pseudo-tags=...`` to enable them.\n\n``--pseudo-tags=[+|-]names|*``\n\tSpecifies a list of pseudo-tag types to include in the output.\n\n\tThe parameters are a set of pseudo tag names. Valid pseudo tag names\n\tcan be listed with ``--list-pseudo-tags``. Surround each name in the set\n\twith braces, like \"{TAG_PROGRAM_AUTHOR}\". You don't have to include the \"!_\"\n\tpseudo tag prefix when specifying a name in the option argument for ``--pseudo-tags=``\n\toption.\n\n\tpseudo-tags don't have a notation using one-letter flags.\n\n\tIf a name is preceded by either the '+' or '-' characters, that\n\ttags's effect has been added or removed. Otherwise the names replace\n\tany current settings. All entries are included if '*' is given.\n\tAll entries are removed if nothing ('') is given.\n\n``--fields=+E`` (or ``--fields=+{extras}``)\n\tAttach \"extras:pseudo\" field to pseudo-tags.\n\n\tAn example of pseudo tags with the field::\n\n\t\t!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\textras:pseudo\n\n\tIf the name of a regular tag in a tag file starts with \"!_\", a\n\tclient tool cannot distinguish whether the tag is a regular-tag or\n\tpseudo-tag.  The fields attached with this option help the tool\n\tdistinguish them.\n\n\nList of notable pseudo-tags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nRunning ctags with ``--list-pseudo-tags`` option lists available types\nof pseudo-tags with short descriptions. This subsection shows hints\nfor using notable ones.\n\n``TAG_EXTRA_DESCRIPTION``  (new in Universal Ctags)\n\tIndicates the names and descriptions of enabled extras::\n\n\t  !_TAG_EXTRA_DESCRIPTION\t{extra-name}\t/description/\n\t  !_TAG_EXTRA_DESCRIPTION!{language-name}\t{extra-name}\t/description/\n\n\tIf your tool relies on some extra tags (extras), refer to\n\tthe pseudo-tags of this type. A tool can reject the tags file that\n\tdoesn't include expected extras, and raise an error in an early\n\tstage of processing.\n\n\tAn example of the pseudo-tags::\n\n\t  $ ctags --extras=+p --pseudo-tags='{TAG_EXTRA_DESCRIPTION}' -o - input.c\n\t  !_TAG_EXTRA_DESCRIPTION\tanonymous\t/Include tags for non-named objects like lambda/\n\t  !_TAG_EXTRA_DESCRIPTION\tfileScope\t/Include tags of file scope/\n\t  !_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n\t  !_TAG_EXTRA_DESCRIPTION\tsubparser\t/Include tags generated by subparsers/\n\t  ...\n\n\tA client tool can know \"{anonymous}\", \"{fileScope}\", \"{pseudo}\",\n\tand \"{subparser}\" extras are enabled from the output.\n\n\tUniversal Ctags version 6.0 will turn on this pseudo tag by default.\n\n``TAG_FIELD_DESCRIPTION``  (new in Universal Ctags)\n\tIndicates the names and descriptions of enabled fields::\n\n\t  !_TAG_FIELD_DESCRIPTION\t{field-name}\t/description/\n\t  !_TAG_FIELD_DESCRIPTION!{language-name}\t{field-name}\t/description/\n\n\tIf your tool relies on some fields, refer to the pseudo-tags of\n\tthis type.  A tool can reject a tags file that doesn't include\n\texpected fields, and raise an error in an early stage of\n\tprocessing.\n\n\tAn example of the pseudo-tags::\n\n\t  $ ctags --fields-C=+'{macrodef}' --extras=+p --pseudo-tags='{TAG_FIELD_DESCRIPTION}' -o - input.c\n\t  !_TAG_FIELD_DESCRIPTION\tfile\t/File-restricted scoping/\n\t  !_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n\t  !_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n\t  !_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n\t  !_TAG_FIELD_DESCRIPTION\ttyperef\t/Type and name of a variable or typedef/\n\t  !_TAG_FIELD_DESCRIPTION!C\tmacrodef\t/macro definition/\n\t  ...\n\n\tA client tool can know \"{file}\", \"{input}\", \"{name}\", \"{pattern}\",\n\tand \"{typeref}\" fields are enabled from the output.\n\tThe fields are common in languages. In addition to the common fields,\n\tthe tool can known \"{macrodef}\" field of C language is also enabled.\n\n\tUniversal Ctags version 6.0 will turn on this pseudo tag by default.\n\n``TAG_FILE_ENCODING``  (new in Universal Ctags)\n\tTBW\n\n``TAG_FILE_FORMAT``\n\tSee also :ref:`tags(5) <tags(5)>`.\n\n``TAG_FILE_SORTED``\n\tSee also :ref:`tags(5) <tags(5)>`.\n\n``TAG_KIND_DESCRIPTION`` (new in Universal Ctags)\n\tIndicates the names and descriptions of enabled kinds::\n\n\t  !_TAG_KIND_DESCRIPTION!{language-name}\t{kind-letter},{kind-name}\t/description/\n\n\tIf your tool relies on some kinds, refer to the pseudo-tags of\n\tthis type.  A tool can reject the tags file that doesn't include\n\texpected kinds, and raise an error in an early stage of\n\tprocessing.\n\n\tKinds are language specific, so a language name is  always\n\tappended to the tag name as suffix.\n\n\tAn example of the pseudo-tags::\n\n\t  $ ctags --extras=+p --kinds-C=vfm --pseudo-tags='{TAG_KIND_DESCRIPTION}' -o - input.c\n\t  !_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n\t  !_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n\t  !_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n\t  ...\n\n\tA client tool can know \"{function}\", \"{member}\", and \"{variable}\"\n\tkinds of C language are enabled from the output.\n\n\tUniversal Ctags version 6.0 will turn on this pseudo tag by default.\n\n``TAG_KIND_SEPARATOR`` (new in Universal Ctags)\n\tTBW\n\n``TAG_OUTPUT_EXCMD`` (new in Universal Ctags)\n\tIndicates the specified type of EX command with ``--excmd`` option.\n\n``TAG_OUTPUT_FILESEP`` (new in Universal Ctags)\n\tIndicates filename separators (\"slash\" or \"backslsh\") used in input fields.\n\n\tUniversal Ctags running on MS Windows replaces backslashes with slashes\n\twhen emitting input fields by default. This pseudo tag is for\n\tnotifying this replacement to client tools.\n\n\tSee also the description for ``--use-slash-as-filename-separator``\n\toption in :ref:`ctags(1) <ctags(1)>`.\n\n``TAG_OUTPUT_MODE`` (new in Universal Ctags)\n\tIndicates whether using Universal Ctags extended escape sequences (\"u-ctags\") or not (\"e-ctags\").\n\n\tTo reduce illegal characters like <Tab> in tags files, Universal\n\tCtags extends the escape sequences originally used in Exuberant\n\tCtags, and applies the escaping rules to more fields.\n\n\tSee :ref:`tags(5) <tags(5)>` about the escaping rules.\n\n\t``--output-format`` option is for choosing the output mode within\n\tthe tags output format. See :ref:`ctags(1) <ctags(1)>` about the option.\n\n\tIn \"e-ctags\" mode, for not violating the tags file format\n\tdescribed in :ref:`tags(5) <tags(5)>`, Universal Ctags skips emitting tag entries\n\tincluding illegal characters like <Tab>.\n\n\tIn input fields ({tagfile} in :ref:`tags(5) <tags(5)>`), we have one more\n\tcondition for applying the escaping rules: ``\\`` characters\n\tare not used as filename separators. UNIX-like systems use ``/``\n\tfor the purpose. On MS Windows, Universal Ctags converts ``\\``\n\tin filenames to ``/`` by default. So, generally this condition is\n\tsatisfied. The condition is not satisfied only when you specify\n\t``--use-slash-as-filename-separator=no`` on MS Windows.\n\n``TAG_OUTPUT_VERSION`` (new in Universal Ctags 6.0)\n\tIndicates the language-common interface version of the output::\n\n\t  !_TAG_OUTPUT_VERSION\t{current}.{age}\t/.../\n\n\tThe public interface includes common fields, common extras,\n\tpseudo tags.\n\n\tThe maintainer of Universal Ctags may update the numbers,\n\t\"{current}\" and \"{age}\" in the same manner as explained\n\tin ``TAG_PARSER_VERSION``.\n\n``TAG_PARSER_VERSION`` (new in Universal Ctags 6.0)\n\tIndicates the interface version of the parser::\n\n\t  !_TAG_PARSER_VERSION!{language-name}\t{current}.{age}\t/.../\n\n\tThe public interfaces include kinds, roles, language specific fields,\n\tand language specific extras.\n\n\tThe maintainer of the parser for \"${language-name}\" may update\n\tthe numbers, \"{current}\" and \"{age}\" in the following rules:\n\n\t* If kinds, roles, language specific fields, and/or language\n\t  specific extras have been added, removed or changed since last\n\t  release, increment \"{current}\".\n\t* If they have been added since last release, increment \"{age}\".\n\t* If they have been removed since last release, set \"{age}\" to 0.\n\n\tThis concept is based on the versioning in **libtool**\n\t(`7.2 Libtool’s versioning system <https://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning>`_.)\n\tIn Universal Ctags, we simplified the concept with removing\n\t\"revision\" in the versioning in libtool.\n\n\tManual pages for languages may document changes that increase\n\tthe number of \"{current}\".\n\n``TAG_PATTERN_LENGTH_LIMIT`` (new in Universal Ctags)\n\tTBW\n\n``TAG_PROC_CWD`` (new in Universal Ctags)\n\tIndicates the working directory of ctags during processing.\n\n\tThis pseudo-tag helps a client tool solve the absolute paths for\n\tthe input files for tag entries even when they are tagged with\n\trelative paths.\n\n\tAn example of the pseudo-tags::\n\n\t  $ cat tags\n\t  !_TAG_PROC_CWD\t/tmp/\t//\n\t  main\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n\t  ...\n\n\tFrom the regular tag for \"main\", the client tool can know the\n\t\"main\" is at \"input.c\".  However, it is a relative path. So if the\n\tdirectory where ctags run and the directory\n\twhere the client tool runs are different, the client tool cannot\n\tfind \"input.c\" from the file system. In that case,\n\t``TAG_PROC_CWD`` gives the tool a hint; \"input.c\" may be at \"/tmp\".\n\n``TAG_PROGRAM_NAME``\n\tIndicates the name of program generating this tags file.\n\n``TAG_PROGRAM_VERSION``\n\tIndicates the version of program generating this tags file.\n\n``TAG_ROLE_DESCRIPTION`` (new in Universal Ctags)\n\tIndicates the names and descriptions of enabled roles::\n\n\t  !_TAG_ROLE_DESCRIPTION!{language-name}!{kind-name}\t{role-name}\t/description/\n\n\tIf your tool relies on some roles, refer to the pseudo-tags of\n\tthis type. Note that a role owned by a disabled kind is not listed\n\teven if the role itself is enabled.\n\nREDUNDANT-KINDS\n---------------\nTBW (Write about --fields=+kKzZ)\n\nMULTIPLE-LANGUAGES FOR AN INPUT FILE\n------------------------------------\nUniversal ctags can run multiple parsers.\nThat means a parser, which supports multiple parsers (**guest parsers** or **sub-parsers**), may output tags for\ndifferent languages.\n\nGuest parsers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nA parser can run guest pursers on the areas in a source file.\n\nConsider the following text as a source file (\"input.html\"):\n\n.. code-block:: html\n\n\t<html><head>\n\t\t<script>class MyObject {}</script>\n\t\t<style type=\"text/css\">h1.heading { color: red; }</style>\n\t</htad>\n\t<h1 class='heading'>title</h1>\n\t</html>\n\nIf a user doesn't specify any extras, Universal ctags emits:\n\n.. code-block:: console\n\n\t$ ctags -o - input.html\n\ttitle\tinput.html\t/^<h1 class='heading'>title<\\/h1>$/;\"\th\n\nThese is no issue here.\n``running guest pursers`` extra is disabled by default.\n\nIf a user enables the ``running guest parsers`` extra with specifying\n``--extras=+{guest}`` or ``--extras=+g``, Universal ctags emits:\n\n.. code-block:: console\n\n\t$ ctags -o - --extras='{guest}' input.html\n\tMyObject\tinput.html\t/class MyObject {}/;\"\tc\n\th1.heading\tinput.html\t/h1.heading { color: red; }/;\"\tc\n\ttitle\tinput.html\t/^<h1 class='heading'>title<\\/h1>$/;\"\th\n\nUniversal ctags extracts the language objects for CSS and JavaScript; the HTML\nparser runs JavaScript parser on the area \"``<script>...</script>``\" area\nand CSS parser on the area \"``<style ...> ...</style>``\" area.\n\nIf a client tool assumes that ctags runs one parser for an input file,\nthe tool may tell \"MyObject is a class of HTML\" and/or \"h1.heading is\na class of HTML\" to its users. ``c`` is too few information to\ntell what is \"MyObject\" and what is \"h1.heading\" correctly. The\nclient tool needs more information.\n\n``language``/``l`` field can be used to show the language\nfor each tag.\n\n.. code-block:: console\n\n\t$ ctags -o - --extras='{guest}' --fields=+'{language}' input.html\n\tMyObject\tinput.html\t/class MyObject {}/;\"\tc\tlanguage:JavaScript\n\th1.heading\tinput.html\t/h1.heading { color: red; }/;\"\tc\tlanguage:CSS\n\ttitle\tinput.html\t/^<h1 class='heading'>title<\\/h1>$/;\"\th\tlanguage:HTML\n\nFor some class tools, the ``language:`` field provides enough information.\nUniversal ctags can emits more self-descriptive tag file.\n\n\nEnabling ``K`` field with ``--fields=+K`` option, Universal ctags uses\nlong-names instead of single-letter to represent kind fields:\n\n.. code-block:: console\n\n\t$ ctags -o - --extras='{guest}' --fields=+'{language}K' input.html\n\tMyObject\t/tmp/input.html\t/class MyObject {}/;\"\tclass\tlanguage:JavaScript\n\th1.heading\t/tmp/input.html\t/h1.heading { color: red; }/;\"\tclass\tlanguage:CSS\n\ttitle\t/tmp/input.html\t/^<h1 class='heading'>title<\\/h1>$/;\"\theading1\tlanguage:HTML\n\nThe long-name representation makes tag files larger.\nIf you want to keep a tag file small, you can make your tool utilize pseudo-tags\ninstead of enabling ``K`` field. Universal ctags emits the following line at the\nbeginning of a tags file by default:\n\n.. code-block:: console\n\n\t$ cat ./tags\n\t...\n\t!_TAG_KIND_DESCRIPTION!CSS\tc,class\t/classes/\n\t...\n\t!_TAG_KIND_DESCRIPTION!HTML\tc,class\t/classes/\n\t!_TAG_KIND_DESCRIPTION!HTML\th,heading1\t/H1 headings/\n\t...\n\t!_TAG_KIND_DESCRIPTION!JavaScript\tc,class\t/classes/\n\t...\n\nFrom the second field of the output, a tool can know the mapping\nbetween a single-letter for a kind and a long-name for the kind.\n\nUniversal ctags emits pseudo-tags to tag files by default. However, if\nyou make ctags emit to standard output with ``-o -`` or ``-f -``\noption, ctags doesn't print pseudo-tags.  ``pseudo``/``p`` extra\nforces emitting.\n\n.. code-block:: console\n\n\t$ ctags -o - --extras='{guest}{pseudo}' --fields=+'{language}' input.html\n\t...\n\t!_TAG_KIND_DESCRIPTION!CSS\tc,class\t/classes/\n\t...\n\t!_TAG_KIND_DESCRIPTION!HTML\tc,class\t/classes/\n\t!_TAG_KIND_DESCRIPTION!HTML\th,heading1\t/H1 headings/\n\t...\n\t!_TAG_KIND_DESCRIPTION!JavaScript\tc,class\t/classes/\n\t...\n\nSub-parsers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nTBW\n\nUTILIZING READTAGS\n-----------------------------------\nSee :ref:`readtags(1) <readtags(1)>` to know how to use readtags. This section is for discussing\nsome notable topics for client tools.\n\nBuild Filter/Sorter Expressions\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nCertain escape sequences in expressions are recognized by readtags. For\nexample, when searching for a tag that matches ``a\\?b``, if using a filter\nexpression like ``'(eq? $name \"a\\?b\")'``, since ``\\?`` is translated into a\nsingle ``?`` by readtags, it actually searches for ``a?b``.\n\nAnother problem is: If the client tools talks to readtags not by subprocess\ndirectly, but through a shell, then if a single quote appear in filter\nexpressions (which is also wrapped by single quotes), it terminates the\nexpression, producing broken expressions, and may even cause unintended shell\ninjection. Single quotes can be escaped using ``'\"'\"'``.\n\nSo, client tools need to:\n\n* Replace ``\\`` by ``\\\\``\n* Replace ``'`` by ``'\"'\"'``, if it talks to readtags through a shell.\n\ninside the expressions. If the expression also contains strings, ``\"`` in the\nstrings needs to be replaced by ``\\\"``.\n\nAnother thing to notice is that missing fields are represented by ``#f``, and\napplying string operators to them will produce an error. You should always\ncheck if a field is missing before applying string operators. See the\n\"Filtering\" section in :ref:`readtags(1) <readtags(1)>` to know how to do this. Run \"readtags -H\nfilter\" to see which operators take string arguments.\n\nBuild Filter/Sorter Expressions using Lisp Languages\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nClient tools written in Lisp could build the expression using lists. ``prin1``\n(in Common Lisp style Lisps) and ``write`` (in Scheme style Lisps) can\ntranslate the list into a string that can be directly used. For example, in\nEmacsLisp:\n\n.. code-block:: EmacsLisp\n\n   (let ((name \"hi\"))\n     (prin1 `(eq? $name ,name)))\n   => \"(eq\\\\? $name \"hi\")\"\n\nThe \"?\" is escaped, and readtags can handle it.\n\nEscape sequences produced by ``write`` in Scheme style Lisps are exactly those\nsupported by readtags, so any legal readtags expressions can be used. Common\nLisp style Lisps may produce escape sequences that are unrecgonized by\nreadtags, like ``\\#``, so symbols that contain \"#\" can't be used. Readtags\nprovides some aliases for these Lisps, so they should:\n\n* Use ``true`` for ``#t``.\n* Use ``false`` for ``#f``.\n* Use ``nil`` or ``()`` for ``()``.\n* Use ``(string->regexp \"PATTERN\")`` for ``#/PATTERN/``. Use\n  ``(string->regexp \"PATTERN\" :case-fold true)`` for ``#/PATTERN/i``. Notice\n  that ``string->regexp`` doesn't require escaping \"/\" in the pattern.\n\nNotice that if the client tool talks to readtags through a shell, then in the\nproduced string, ``'`` still needs to be replaced by ``'\"'\"'`` to prevent\nbroken expressions and shell injection.\n\nParse Readtags Output\n~~~~~~~~~~~~~~~~~~~~~\nIn the output of readtags, tabs can appear in all field values (e.g., the tag\nname itself could contain tabs), which makes it hard to split the line into\nfields. Client tools should use the ``-E`` option, which keeps the escape\nsequences in the tags file, so the only field that could contain tabs is the\npattern field.\n\nThe pattern field could:\n\n- Use a line number. It will look like ``number;\"`` (e.g. ``10;\"``).\n- Use a search pattern. It will look like ``/pattern/;\"`` or ``?pattern?;\"``.\n  Notice that the search pattern could contain tabs.\n- Combine these two, like ``number;/pattern/;\"`` or ``number;?pattern?;\"``.\n\nThese are true for tags files using extended format, which is the default one.\nThe legacy format (i.e. ``--format=1``) doesn't include the semicolons. It's\nold and barely used, so we won't discuss it here.\n\nClient tools could split the line using the following steps:\n\n* Find the first 2 tabs in the line, so we get the name and input field.\n* From the 2nd tab:\n\n  * If a ``/`` follows, then the pattern delimiter is ``/``.\n  * If a ``?`` follows, then the pattern delimiter is ``?``.\n  * If a number follows, then:\n\n\t* If a ``;/`` follows the number, then the delimiter is ``/``.\n\t* If a ``;?`` follows the number, then the delimiter is ``?``.\n\t* If a ``;\"`` follows the number, then the field uses only line number, and\n\t  there's no pattern delimiter (since there's no regex pattern). In this\n\t  case the pattern field ends at the 3rd tab.\n\n* After the opening delimiter, find the next unescaped pattern delimiter, and\n  that's the closing delimiter. It will be followed by ``;\"`` and then a tab.\n  That's the end of the pattern field. By \"unescaped pattern delimiter\", we\n  mean there's an even number (including 0) of backslashes before it.\n* From here, split the rest of the line into fields by tabs.\n\nThen, the escape sequences in fields other than the pattern field should be\ntranslated. See \"Proposal\" in :ref:`tags(5) <tags(5)>` to know about all the escape sequences.\n\nMake Use of the Pattern Field\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe pattern field specifies how to find a tag in its source file. The code\ngenerating this field seems to have a long history, so there are some pitfalls\nand it's a bit hard to handle. A client tool could simply require the ``line:``\nfield and jump to the line it specifies, to avoid using the pattern field. But\nanyway, we'll discuss how to make the best use of it here.\n\nYou should take the words here merely as suggestions, and not standards. A\nclient tool could definitely develop better (or simpler) ways to use the\npattern field.\n\nFrom the last section, we know the pattern field could contain a line number\nand a search pattern. When it only contains the line number, handling it is\neasy: you simply go to that line.\n\nThe search pattern resembles an EX command, but as we'll see later, it's\nactually not a valid one, so some manual work are required to process it.\n\nThe search pattern could look like ``/pat/``, called \"forward search pattern\",\nor ``?pat?``, called \"backward search pattern\". Using a search pattern means\neven if the source file is updated, as long as the part containing the tag\ndoesn't change, we could still locate the tag correctly by searching.\n\nWhen the pattern field only contains the search pattern, you just search for\nit. The search direction (forward/backward) doesn't matter, as it's decided\nsolely by whether the ``-B`` option is enabled, and not the actual context. You\ncould always start the search from say the beginning of the file.\n\nWhen both the search pattern and the line number are presented, you could make\ngood use of the line number, by going to the line first, then searching for the\nnearest occurrence of the pattern. A way to do this is to search both forward\nand backward for the pattern, and when there is a occurrence on both sides, go\nto the nearer one.\n\nWhat's good about this is when there are multiple identical lines in the source\nfile (e.g. the COMMON block in Fortran), this could help us find the correct\none, even after the source file is updated and the tag position is shifted by a\nfew lines.\n\nNow let's discuss how to search for the pattern. After you trim the ``/`` or\n``?`` around it, the pattern resembles a regex pattern. It should be a regex\npattern, as required by being a valid EX command, but it's actually not, as\nyou'll see below.\n\nIt could begin with a ``^``, which means the pattern starts from the beginning\nof a line. It could also end with an *unescaped* ``$`` which means the pattern\nends at the end of a line. Let's keep this information, and trim them too.\n\nNow the remaining part is the actual string containing the tag. Some characters\nare escaped:\n\n* ``\\``.\n* ``$``, but only at the end of the string.\n* ``/``, but only in forward search patterns.\n* ``?``, but only in backward search patterns.\n\nYou need to unescape these to get the literal string. Now you could convert\nthis literal string to a regexp that matches it (by escaping, like\n``re.escape`` in Python or ``regexp-quote`` in Elisp), and assemble it with\n``^`` or ``$`` if the pattern originally has it, and finally search for the tag\nusing this regexp.\n\nRemark: About a Previous Format of the Pattern Field\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIn some earlier versions of Universal Ctags, the line number in the pattern\nfield is the actual line number minus one, for forward search patterns; or plus\none, for backward search patterns. The idea is to resemble an EX command: you\ngo to the line, then search forward/backward for the pattern, and you can\nalways find the correct one. But this denies the purpose of using a search\npattern: to tolerate file updates. For example, the tag is at line 50,\naccording to this scheme, the pattern field should be::\n\n\t49;/pat/;\"\n\nThen let's assume that some code above are removed, and the tag is now at\nline 45. Now you can't find it if you search forward from line 49.\n\nDue to this reason, Universal Ctags turns to use the actual line number. A\nclient tool could distinguish them by the ``TAG_OUTPUT_EXCMD`` pseudo tag, it's\n\"combine\" for the old scheme, and \"combineV2\" for the present scheme. But\nprobably there's no need to treat them differently, since \"search for the\nnearest occurrence from the line\" gives good result on both schemes.\n\nJSON OUTPUT\n-----------\nSee :ref:`ctags-json-output(5) <ctags-json-output(5)>`.\n\nCHANGES\n-----------\n\nVersion 6.0\n~~~~~~~~~~~\n* ctags enables ``TAG_KIND_DESCRIPTION``, ``TAG_ROLE_DESCRIPTION``,\n  ``TAG_FIELD_DESCRIPTION``, and ``TAG_EXTRA_DESCRIPTION`` pseudo tags by default.\n* ``TAG_PARSER_VERSION`` is introduced.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-lang-python(7) <ctags-lang-python(7)>`, :ref:`ctags-incompatibilities(7) <ctags-incompatibilities(7)>`, :ref:`tags(5) <tags(5)>`, :ref:`ctags-json-output(5) <ctags-json-output(5)>`, :ref:`readtags(1) <readtags(1)>`,\n`7.2 Libtool’s versioning system <https://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning>`\n"
  },
  {
    "path": "docs/man/ctags-faq.7.rst",
    "content": ".. _ctags-faq(7):\n\n==============================================================\nctags-faq\n==============================================================\n\nUniversal Ctags FAQ\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nThis is the Universal Ctags FAQ (Frequently-Asked Questions).\nIt is based on `Exuberant Ctags FAQ <http://ctags.sourceforge.net/faq.html>`_\n\n.. contents::\n\nDESCRIPTION\n-----------\n\n.. TODO: https://github.com/universal-ctags/ctags/issues/2312\n\t#1421: feature: clean up stale tags when appending (`-a`)\n\t#2356: can't pre-process the macro but it works with Exuberant Ctags 5.8\n\t#2540: C/C++：conditional compilation like #ifdef will cause parse errror\n\nWhat is the difference between Universal Ctags and Exuberant Ctags?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUniversal Ctags is an unofficial fork of Exuberant Ctags.\nThe differences are summarized in :ref:`ctags-incompatibilities(7) <ctags-incompatibilities(7)>` man page.\n\nThe most notable one is that Universal Ctags doesn't read ``~/.ctags`` file.\nInstead, it reads ``*.ctags`` under ``~/.ctags.d`` directory.\n\nHow can I avoid having to specify my favorite option every time?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nEither by setting the environment variable ``CTAGS`` to your custom\noptions, or putting them into a ``~/.ctags.d/anyname.ctags`` file in your home\ndirectory.\n\nWhat are these strange bits of text beginning with ``;\"`` which follow many of the lines in the tag file?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThese are *extension flags*. They are added in order to provide extra\ninformation about the tag that may be utilized by the editor in order to\nmore intelligently handle tags. They are appended to the EX command part of\nthe tag line in a manner that provides backwards compatibility with existing\nimplementations of the Vi editor. The semicolon is an EX command separator\nand the double quote begins an EX comment. Thus, the extension flags appear\nas an EX comment and should be ignored by the editor when it processes the\nEX command.\n\nSome non-vi editors, however, implement only the bare minimum of EX commands\nin order to process the search command or line number in the third field of\nthe tag file. If you encounter this problem, use the option ``--format=1`` to\ngenerate a tag file without these extensions (remember that you can set the\nCTAGS environment variable to any default arguments you wish to supply). Then\nask the supplier of your editor to implement handling of this feature of EX\ncommands.\n\nWhy can't I jump to ``class::member``?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBecause, by default, ctags only generates tags for the separate identifiers\nfound in the source files. If you specify the ``--extra=+q`` option, then\nctags will also generate a second, class-qualified tag for each class member\n(data and function/method) in the form ``class::member`` for C++, and in the form\n``class.method`` for Eiffel and Java.\n\nWhy do I end up on the wrong line when I jump to a tag?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBy default, ctags encodes the line number in the file where macro (``#define``)\ntags are found. This was done to remain compatible with the original UNIX\nversion of ctags. If you change the file containing the tag without\nrebuilding the tag file, the location of tag in the tag file may no longer\nmatch the current location.\n\nIn order to avoid this problem, you can specify the option ``--excmd=p``,\nwhich causes ctags to use a search pattern to locate macro tags. I have\nnever uncovered the reason why the original UNIX ctags used line numbers\nexclusively for macro tags, but have so far resisted changing the default\nbehavior of Exuberant (and Universal) Ctags to behave differently.\n\nHow do I jump to the tag I want instead of the wrong one by the same name?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA tag file is simple a list of tag names and where to find them. If there\nare duplicate entries, you often end up going to the wrong one because the\ntag file is sorted and your editor locates the first one in the tag file.\n\nStandard Vi provides no facilities to alter this behavior. However, Vim\nhas some nice features to minimize this problem, primarily by examining all\nmatches and choosing the best one under the circumstances. Vim also provides\ncommands which allow for selection of the desired matching tag.\n\nHow can I locate all references to a specific function or variable?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere are several packages already available which provide this capability.\nNamely, these are: GLOBAL source code tag system, GNU id-utils, cscope,\nand cflow. As of this writing, they can be found in the following locations:\n\n- GLOBAL:    http://www.gnu.org/software/global\n- id-utils:  http://www.gnu.org/software/idutils/idutils.html\n- cscope:    http://cscope.sourceforge.net\n- cflow:     ftp://www.ibiblio.org/pub/Linux/devel/lang/c\n\nWhy does appending tags to a tag file tag so long?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSometimes, in an attempt to build a global tag file for all source files in\na large source tree of many directories, someone will make an attempt to run\nctags in append (``-a``) mode on every directory in the hierarchy. Each time\nctags is invoked, its default behavior is to sort the tag file once the tags\nfor that execution have been added. As the cumulative tag file grows, the sort\ntime increases arithmetically.\n\nThe best way to avoid this problem (and the most efficient) is to make\nuse of the ``--recurse`` (or ``-R``) option of ctags by executing the following\ncommand in the root of the directory hierarchy (thus running ctags only once):\n\n\t.. code-block:: sh\n\n\t\tctags -R\n\nIf you really insist on running ctags separately on each directory, you can\navoid the sort pass each time by specifying the option ``--sort=no``. Once the\ntag file is completely built, use the sort command to manually sort the\nfinal tag file, or let the final invocation of ctags sort the file.\n\nHow should I set up tag files for a multi-level directory hierarchy?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere are a few ways of approaching this:\n\n1.  A local tag file in each directory containing only the tags for source\n    files in that directory.\n\n2.  One single big, global tag file present in the root directory of your\n    hierarchy, containing all tags present in all source files in the\n    hierarchy.\n\n3.  A local tag file in each directory containing only the tags for source\n    files in that directory, in addition to one single global tag file\n    present in the root directory of your hierarchy, containing all\n    non-static tags present in all source files in the hierarchy.\n\n4.  A local tag file in each directory of the hierarchy, each one\n    containing all tags present in source files in that directory and all\n    non-static tags in every directory below it (note that this implies\n    also having one big tag file in the root directory of the hierarchy).\n\nEach of these approaches has its own set of advantages and disadvantages,\ndepending upon your particular conditions. Which approach is deemed best\ndepends upon the following factors:\n\nA.  The ability of your editor to use multiple tag files.\n\n    If your editor cannot make use of multiple tag files (original vi\n    implementations could not), then one large tag file is the only way to\n    go if you ever desire to jump to tags located in other directories. If\n    you never need to jump to tags in another directory (i.e. the source\n    in each directory is entirely self-contained), then a local tag file\n    in each directory will fit your needs.\n\nB.  The time is takes for your editor to look up a tag in the tag file.\n\n    The significance of this factor depends upon the size of your source\n    tree and on whether the source files are located on a local or remote\n    file system. For source and tag files located on a local file system,\n    looking up a tag is not as big a hit as one might first imagine, since\n    vi implementations typically perform a binary search on a sorted tag\n    file. This may or may not be true for the editor you use. For files\n    located on a remote file system, reading a large file is an expensive\n    operation.\n\nC.  Whether or not you expect the source code to change and the time it\n    takes to rebuild a tag file to account for changes to the source code.\n\n    While Universal Ctags is particularly fast in scanning source code\n    (around 1-2 MB/sec), a large project may still result in objectionable\n    delays if one wishes to keep their tag file(s) up to date on a\n    frequent basis, or if the files are located on a remote file system.\n\nD.  The presence of duplicate tags in the source code and the ability to\n    handle them.\n\n    The impact of this factor is influenced by the following three issues:\n\n    1.  How common are duplicate tags in your project?\n\n    2.  Does your editor provide any facilities for dealing with duplicate\n        tags?\n\n        While standard vi does not, many modern vi implementations, such\n        as Vim have good facilities for selecting the desired match from\n        the list of duplicates. If your editor does not support duplicate\n        tags, then it will typically send you to only one of them, whether\n        or not that is the one you wanted (and not even notifying you that\n        there are other potential matches).\n\n    3.  What is the significance of duplicate tags?\n\n        For example, if you have two tags of the same name from entirely\n        isolated software components, jumping first to the match found\n        in component B while working in component A may be entirely\n        misleading, distracting or inconvenient (to keep having to choose\n        which one if your editor provides you with a list of matches).\n        However, if you have two tags of the same name for parallel builds\n        (say two initialization routines for different hosts), you may\n        always want to specify which one you want.\n\nOf the approaches listed above, I tend to favor Approach 3. My editor of\nchoice is Vim, which provides a rich set of features for handling multiple\ntag files, which partly influences my choice. If you are working with\nsource files on a remote file system, then I would recommend either\nApproach 3 or Approach 4, depending upon the hit when reading the global\ntag file.\n\nThe advantages of Approach 3 are many (assuming that your editor has\nthe ability to support both multiple tag files and duplicate tags). All\nlookups of tag located in the current directory are fast and the local\ntag file can be quickly and easily regenerated in one second or less\n(I have even mapped a keystroke to do this easily). A lookup of a\n(necessarily non-static) tag found in another directory fails a lookup in\nthe local tag file, but is found in the global tag file, which satisfies\nall cross-directory lookups. The global tag file can be automatically\nregenerated periodically with a cron job (and perhaps the local tag files\nalso).\n\nNow I give an example of how you would implement Approach 3. Means of\nimplementing the other approaches can be performed in a similar manner.\n\nHere is a visual representation of an example directory hierarchy:\n\n::\n\n\tproject\n\t`-----misccomp\n\t|       `...\n\t`-----sysint\n\t        `-----client\n\t        |       `-----hdrs\n\t        |       `-----lib\n\t        |       `-----src\n\t        |       `-----test\n\t        `-----common\n\t        |       `-----hdrs\n\t        |       `-----lib\n\t        |       `-----src\n\t        |       `-----test\n\t        `-----server\n\t                `-----hdrs\n\t                `-----lib\n\t                `-----src\n\t                `-----test\n\nHere is a recommended solution (conceptually) to build the tag files:\n\n1.  Within each of the leaf nodes (i.e. ``hdrs``, ``lib``, ``src``, ``test``) build a tag\n    file using \"``ctags *.[ch]``\". This can be easily be done for the whole\n    hierarchy by making a shell script, call it ``dirtags``, containing the\n    following lines:\n\n\t.. code-block:: sh\n\n\t\t#!/bin/sh\n\t\tcd $1\n\t\tctags *\n\n    Now execute the following command:\n\n\t.. code-block:: sh\n\n\t\tfind * -type d -exec dirtags {} \\;\n\n    These tag files are trivial (and extremely quick) to rebuild while\n    making changes within a directory. The following Vim key mapping is\n    quite useful to rebuild the tag file in the directory of the current\n    source file:\n\n\t.. code-block:: text\n\n\t\t:nmap ,t :!(cd %:p:h;ctags *.[ch])&<CR><CR>\n\n2.  Build the global tag file:\n\n\t.. code-block:: sh\n\n\t\tcd ~/project\n\t\tctags --file-scope=no -R\n\n    thus constructing a tag file containing only non-static tags for all\n    source files in all descendent directories.\n\n3.  Configure your editor to read the local tag file first, then consult\n    the global tag file when not found in the local tag file. In Vim,\n    this is done as follows:\n\n\t.. code-block:: text\n\n\t\t:set tags=./tags,tags,~/project/tags\n\nIf you wish to implement Approach 4, you would need to replace the\n``dirtags`` script of step 1 with the following:\n\n\t.. code-block:: sh\n\n\t\t#!/bin/sh\n\t\tcd $1\n\t\tctags *\n\t\t# Now append the non-static tags from descendent directories\n\t\tfind * -type d -prune -print | ctags -aR --file-scope=no -L-\n\nAnd replace the configuration of step 3 with this:\n\n\t.. code-block:: text\n\n\t\t:set tags=./tags;$HOME,tags\n\nAs a caveat, it should be noted that step 2 builds a global tag file whose\nfile names will be relative to the directory in which the global tag file\nis being built. This takes advantage of the Vim ``tagrelative`` option,\nwhich causes the path to be interpreted a relative to the location of the\ntag file instead of the current directory. For standard vi, which always\ninterprets the paths as relative to the current directory, we need to\nbuild the global tag file with absolute path names. This can be\naccomplished by replacing step 2 with the following:\n\n\t.. code-block:: sh\n\n\t\tcd ~/project\n\t\tctags --file-scope=no -R `pwd`\n\nDoes Universal Ctags support Unicode file names?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. MEMO: from https://github.com/universal-ctags/ctags/issues/1837\n\nYes, Unicode file names are supported on unix-like platforms (Linux, macOS,\nCygwin, etc.).\n\nHowever, on MS Windows, you need to use Windows 10 version 1903 or later to use\nUnicode file names. (This is an experimental feature, though.) On older versions\non Windows, Universal Ctags only support file names represented in the current\ncode page. If you still want to use Unicode file names on them, use Cygwin or\nMSYS2 version of Universal Ctags as a workaround.\n\nWhy does zsh cause \"zsh: no matches found\" error?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. MEMO: from https://github.com/universal-ctags/ctags/issues/2842\n\nzsh causes error on the following cases;\n\n\t.. code-block:: sh\n\n\t\tctags --extra=+* ...\n\t\tctags --exclude=foo/* ...\n\nThis is the 2nd most significant incompatibility *feature* of zsh.\n\nCited from \"Z-Shell Frequently-Asked Questions\", \"`2.1: Differences from sh and\nksh <http://zsh.sourceforge.net/FAQ/zshfaq02.html>`_\";\n\n\t... The next most classic difference is that unmatched glob patterns cause\n\tthe command to abort; set ``NO_NOMATCH`` for those.\n\nYou may add \"``setopt nonomatch``\" on your ``~/.zshrc``. Or you can escape glob\npatterns with backslash;\n\n\t.. code-block:: sh\n\n\t\tctags --extra=+\\* ...\n\t\tctags --exclude=foo/\\* ...\n\nOr quote them;\n\n\t.. code-block:: sh\n\n\t\tctags '--extra=+*' ...\n\t\tctags '--exclude=foo/*' ...\n\nSEE ALSO\n--------\n\nThe official Universal Ctags web site at:\n\nhttps://ctags.io/\n\n:ref:`ctags(1) <ctags(1)>`, :ref:`tags(5) <tags(5)>`\n\nAUTHOR\n------\n\nThis FAQ is based on `Exuberant Ctags FAQ <http://ctags.sourceforge.net/faq.html>`_ by\nDarren Hiebert and vberthoux@users.sourceforge.net\n\nUniversal Ctags project: https://ctags.io/\n"
  },
  {
    "path": "docs/man/ctags-incompatibilities.7.rst",
    "content": ".. _ctags-incompatibilities(7):\n\n==============================================================\nctags-incompatibilities\n==============================================================\n\nIncompatibilities between Universal Ctags and Exuberant Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** [options] [file(s)]\n|\t**etags** [options] [file(s)]\n\nDESCRIPTION\n-----------\n\nThis page describes major incompatible changes introduced to\nUniversal Ctags forked from Exuberant Ctags.\n\nOption files loading at starting up time (preload files)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUniversal Ctags doesn't load ``~/.ctags`` at starting up time.\nFile paths for preload files are changed.\nSee \"FILES\" section of :ref:`ctags(1) <ctags(1)>`.\n\nEnvironment variables for arranging command lines\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUniversal Ctags doesn't read ``CTAGS`` and/or ``ETAGS`` environment\nvariables.\n\nBehavior when ``--excmd=mixed`` is given\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nExuberant Ctags uses line numbers as addresses for C preprocessor\nmacro definition tags. Universal Ctags uses patterns for the tags.\n\nIncompatibilities in command line interface\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nOrdering in a command line\n....................................................................................\n\n.. NOTE: #1889\n\nThe command line format of Universal Ctags is \"``ctags [options]\n[source_file(s)]``\" following the standard POSIX convention.\n\nExuberant Ctags accepts a option following a source file.\n\n.. code-block:: console\n\n\t$ ctags -o - foo.c --list-kinds=Sh\n\tf  functions\n\nUniversal Ctags warns and ignores the option ``--list-kinds=Sh`` as follows.\n\n.. code-block:: console\n\n\t$ ctags -o - foo.c --list-kinds=Sh\n\tctags: Warning: cannot open input file \"--list-kinds=Sh\" : No such file or directory\n\ta\tfoo.c\t/^void a () {}$/;\"\tf\ttyperef:typename:void\n\tb\tfoo.c\t/^void b () {}$/;\"\tf\ttyperef:typename:void\n\nThe order of application of patterns and extensions in ``--langmap``\n....................................................................................\n\nWhen applying mappings for a name of given source file,\nExuberant Ctags tests file name patterns *AFTER* file extensions\n(*e-map-order*). Universal Ctags does this differently; it tests file\nname patterns *BEFORE* file extensions (*u-map-order*).\n\nThis incompatible change is introduced to deal with the following\nsituation:\n\n\t* ``build.xml`` as a source file,\n\t* The Ant parser declares it handles a file name pattern ``build.xml``, and\n\t* The XML parser declares it handles a file extension ``.xml``.\n\nWhich parser should be used for parsing ``build.xml``?  The assumption\nof Universal Ctags is the user may want to use the Ant parser; the\nfile name pattern it declares is more specific than the file extension\nthat the XML parser declares. However, e-map-order chooses the XML\nparser.\n\nSo Universal Ctags uses the u-map-order even though it introduces an\nincompatibility.\n\n``--list-map-extensions=<language>`` and ``--list-map-patterns=<language>``\noptions are helpful to verify and the file extensions and the file\nname patterns of given *<language>*.\n\nRemove ``--file-tags`` and ``--file-scope`` options\n....................................................................................\n\nEven in Exuberant Ctags, ``--file-tags`` is not documented in its man page.\nInstead of specifying ``--file-tags`` or ``--file-tags=yes``, use\n``--extras=+f`` or ``--extras=+{inputFile}``.\n\nInstead of specifying ``--file-tags=no``, use\n``--extras=-f`` or ``--extras=-{inputFile}``.\n\nUniversal Ctags introduces ``F/fileScope`` extra as the replacement for\n``--file-scope`` option.\n\nInstead of specifying ``--file-tags`` or ``--file-tags=yes``, use\n``--extras=+F`` or ``--extras=+{fileScope}``.\n\nInstead of specifying ``--file-tags=no``, use\n``--extras=-F`` or ``--extras=-{fileScope}``.\n\nIncompatibilities in language and kind definitions\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nLanguage name defined with ``--langdef=name`` option\n....................................................................................\n\nThe characters you can use are more restricted than Exuberant Ctags.\nFor more details, see the description of ``--langdef=name`` in :ref:`ctags-optlib(7) <ctags-optlib(7)>`.\n\nObsoleting ``--<LANG>-kinds`` option\n....................................................................................\n\nSome options have *<LANG>* as parameterized parts in their name like\n``--foo-<LANG>=...`` or ``--<LANG>-foo=...``. The most of all such\noptions in Exuberant Ctags have the former form, ``--foo-<LANG>=...``.\nThe exception is ``--<LANG>-kinds``.\n\nUniversal Ctags uses the former form for all *<LANG>* parameterized\noption. Use ``--kinds-<LANG>`` instead of ``--<LANG>-kinds`` in\nUniversal Ctags. ``--<LANG>-kinds`` still works but it will be\nremoved in the future.\n\nThe former form may be friendly to shell completion engines.\n\nDisallowing to define a kind with ``file`` as name\n....................................................................................\n\nThe kind name ``file`` is reserved.  Using it as part of kind spec in\n``--regex-<LANG>`` option is now disallowed.\n\nDisallowing to define a kind with '``F``' as letter\n....................................................................................\n\nThe kind letter '``F``' is reserved.  Using it as part of a kind spec in\n``--regex-<LANG>`` option is now disallowed.\n\nDisallowing to use other than alphabetical character as kind letter\n....................................................................................\n\nExuberant Ctags accepts a character other than alphabetical character\nas kind letter in ``--regex-<LANG>=...`` option.  Universal Ctags\naccepts only an alphabetical character.\n\nAcceptable characters as parts of a kind name\n....................................................................................\n\nExuberant Ctags accepts any character as a part of a kind name\ndefined with ``--regex-<LANG>=/regex/replacement/kind-spec/``.\n\nUniversal Ctags accepts only an alphabetical character as\nthe initial letter of a kind name.\nUniversal Ctags accepts only an alphabetical character or\nnumerical character as the rest letters.\n\nAn example::\n\n  --regex-Foo=/abstract +class +([a-z]+)/\\1/a,abstract class/i\n\nUniversal Ctags rejects this because the kind name, ``abstract class``,\nincludes a whitespace character.\n\nThis requirement is for making the output of Universal Ctags follow\nthe tags file format.\n\nA combination of a kind letter and a kind name\n....................................................................................\n\nIn Universal Ctags, the combination of\na kind letter and a kind name must be unique in a language.\n\nYou cannot define more than one kind reusing a kind letter with\ndifferent kind names. You cannot define more than one kind reusing a\nkind name with different kind letters.\n\nAn example::\n\n  --regex-Foo=/abstract +class +([a-z]+)/\\1/a,abstractClass/i\n  --regex-Foo=/attribute +([a-z]+)/\\1/a,attribute/i\n\nUniversal Ctags rejects this because the kind letter, '``a``', used twice\nfor defining a kind ``abstractClass`` and ``attribute``.\n\n\nIncompatibilities in tags file format\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUsing numerical character in the name part of tag tagfield\n....................................................................................\n\nThe version 2 tags file format, the default output format of\nExuberant Ctags, accepts only alphabetical characters in the name part\nof tag tagfield.\n\nUniversal Ctags introduces an exception to this specification; it may\nuse numerical characters in addition to alphabetical characters as the\nletters other than initial letter of the name part.\n\nThe kinds ``heading1``, ``heading2``, and ``heading3`` in the HTML parser\nare the examples.\n\nTruncating the pattern for long input lines\n....................................................................................\n\nTo prevent generating overly large tags files, a pattern field is\ntruncated, by default, when its size exceeds 96 bytes. A different\nlimit can be specified with ``--pattern-length-limit=N``. Specifying\n0 as *N* results no truncation as Exuberant Ctags does not.\n\nKind letters and names\n....................................................................................\n\nA kind letter '``F``' and a kind name ``file`` are reserved in the\nmain part. A parser cannot have a kind conflicting with\nthese reserved ones. Some incompatible changes are introduced\nto follow the above rule.\n\n* Cobol's ``file`` kind is renamed to ``fileDesc`` because the\n  kind name ``file`` is reserved.\n\n* Ruby's '``F``' (singletonMethod) is changed to '``S``'.\n\n* SQL's '``F``' (field) is changed to '``E``'.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-optlib(7) <ctags-optlib(7)>`, and :ref:`tags(5) <tags(5)>`.\n"
  },
  {
    "path": "docs/man/ctags-json-output.5.rst",
    "content": ".. _ctags-json-output(5):\n\n==============================================================\nctags-json-output\n==============================================================\n\nJSON based ctags output\n\n:Version: 1.0\n:Manual group: Universal Ctags\n:Manual section: 5\n\nSYNOPSIS\n--------\n|\t**ctags** --output-format=json ...\n\nDESCRIPTION\n-----------\nUniversal Ctags supports `JSON <https://www.json.org/>`_ (strictly\nspeaking `JSON Lines <https://jsonlines.org/>`_) output format if the\nctags executable is built with ``libjansson``.  JSON output goes to\nstandard output by default.\n\nFORMAT\n------\nEach JSON line represents a tag.\n\n.. code-block:: console\n\n\t$ ctags --extras=+p --output-format=json --fields=-s input.py\n\t{\"_type\": \"ptag\", \"name\": \"JSON_OUTPUT_VERSION\", \"path\": \"1.0\", \"pattern\": \"in development\"}\n\t{\"_type\": \"ptag\", \"name\": \"TAG_FILE_SORTED\", \"path\": \"1\", \"pattern\": \"0=unsorted, 1=sorted, 2=foldcase\"}\n\t...\n\t{\"_type\": \"tag\", \"name\": \"Klass\", \"path\": \"/tmp/input.py\", \"pattern\": \"/^class Klass:$/\", \"language\": \"Python\", \"kind\": \"class\"}\n\t{\"_type\": \"tag\", \"name\": \"method\", \"path\": \"/tmp/input.py\", \"pattern\": \"/^    def method(self):$/\", \"language\": \"Python\", \"kind\": \"member\", \"scope\": \"Klass\", \"scopeKind\": \"class\"}\n\t...\n\nA key not starting with ``_`` is mapped to a field of ctags.\n\"``--output-format=json --list-fields``\" options list the fields.\n\nA key starting with ``_`` represents meta information of the JSON\nline.  Currently only ``_type`` key is used. If the value for the key\nis ``tag``, the JSON line represents a regular tag. If the value is\n``ptag``, the line represents a pseudo-tag.\n\nThe output format can be changed in the\nfuture. ``JSON_OUTPUT_VERSION`` pseudo-tag provides a change\nclient-tools to handle the changes.  Current version is \"1.0\". A\nclient-tool can extract the version with ``path`` key from the\npseudo-tag.\n\nThe JSON output format is newly designed and has no limitation found\nin the default tags file format.\n\n* The values for ``kind`` key are represented in long-name flags.\n  No one-letter is here.\n\n* Scope names and scope kinds have distinguished keys: ``scope`` and ``scopeKind``.\n  They are combined in the default tags file format.\n\nDATA TYPE USED IN A FIELD\n-------------------------\nValues for the most of all keys are represented in JSON string type.\nHowever, some of them are represented in string, integer, and/or boolean type.\n\n\"``--output-format=json --list-fields``\" options show What kind of data type\nused in a field of JSON.\n\n.. code-block:: console\n\n\t$ ctags --output-format=json --list-fields\n\t#LETTER NAME           ENABLED LANGUAGE         JSTYPE FIXED DESCRIPTION\n\tF       input          yes     NONE             s--    no    input file\n\t...\n\tP       pattern        yes     NONE             s-b    no    pattern\n\t...\n\tf       file           yes     NONE             --b    no    File-restricted scoping\n\t...\n\te       end            no      NONE             -i-    no    end lines of various items\n\t...\n\n``JSTYPE`` column shows the data types.\n\n'``s``'\n\tstring\n\n'``i``'\n\tinteger\n\n'``b``'\n\tboolean (true or false)\n\nFor an example, the value for ``pattern`` field of ctags takes a string or a boolean value.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New key ``kindName`` for ``TAG_ROLE_DESCRIPTION`` pseudo tag\n\n  ``kindName`` is added to store the name of the kind in ``TAG_ROLE_DESCRIPTION``\n  pseudo tags.\n\n  In 0.0, a \"TAG_ROLE_DESCRIPTION\" pseudo tag was printed like:\n\n  .. code-block:: JSON\n\n      {\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\",\n                        \"parserName\": \"LANG!KIND\", }\n\n  In 1.0, it is printed like:\n\n  .. code-block:: JSON\n\n      {\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\",\n                        \"parserName\": \"LANG\",\n                        \"kindName\": \"KIND\",  }\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`tags(5) <tags(5)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-asm.7.rst",
    "content": ".. _ctags-lang-asm(7):\n\n==============================================================\nctags-lang-asm\n==============================================================\n\nRandom notes about tagging Assembly language source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Asm ...\n|\t**ctags** ... --language-force=Asm ...\n|\t**ctags** ... --map-Asm=+.asm ...\n|\t**ctags** ... --map-Asm=+.ASM ...\n|\t**ctags** ... --map-Asm=+.s ...\n|\t**ctags** ... --map-Asm=+.S ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging assembly language\nsource code.\n\nThe parser of Universal Ctags has been extended to support the source\ncode to be processed with *GNU assembler* (*Gas*).\n\nPARAMETERS\n----------\nThe Asm parser has some parameters for adapting it to different\nassembler implementations.\n\nWriting a parser for assembly language source code is not easy because\nthe syntax for the language differ depending on the implementations of\nassemblers and target CPU architectures. For example, in *NASM*, `;`\nis a starter of a line comment. On the other hand, in Gas for i386,\n`;` is a line separator. The parameters explained this man page are\nfor mitigating the gaps of syntax.\n\nUse ``--param-Asm.{parameter}={value}`` option for adjusting the value\nfor a parameter. For example:\n\n.. code-block:: console\n\n\t$ ctags ... --param-Asm.runCPreProcessor=false ...\n\nThis command line sets ``false`` to ``runCPreProcessor`` parameter.\n\n``--list-params=Asm`` lists available parameters available in the\nAsm parser.\n\n``runCPreProcessor``: running C preprocessor\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBy default, the CPreProcessor parser processes the assembly language\nsource code before the Asm parser does.\n\nThe main effects of running the CPreProcessor parser;\n\n* lines started from `//` are stripped as comments,\n* areas surrounded by the pair of `/*` and `*/` are\n  stripped as comments, and\n* macros defined with `#define` are extracted as tags.\n\nSet ``runCPreProcessor`` to ``false`` for disabling the CPreProcessor\nparser running before the Asm parser.\n\n``commentCharsAtBOL``: adjusting line comment starter at the beginning of line\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBy default, the Asm parser ignores lines starting from `;`, `*`, or\n`@` as comments. `//` is also ignored if `runCPreProcessor` is `true`.\n\n``commentCharsAtBOL`` is for changing the characters for line comments.\n`BOL` is acronym standing for \"the beginning of line.\" The characters\nact as comment starters only if they are at the beginning\nof lines.\n\nThe next example if for assembler input using `!` and `>` as the comment starter:\n\n.. code-block:: console\n\n\t$ ctags ... --param-Asm.commentCharsAtBOL='!>' ...\n\n``commentCharsInMOL``: adjusting line comment starter in the middle of line\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSome dialects of assemblers support comments starting from the middle of line.\nA `;` character starts a comment anywhere on the line in Gas for CRIS for example.\n\n``commentCharsInMOL`` is for specifying the character for line comments.\n`MOL` is acronym standing for \"the middle of line.\" Unlike characters\nspecified with ``commentCharsAtBOL``, the characters specified with\n``commentCharsInMOL`` act as comment starts even if they are in the\nmiddle of lines.\n\nBy default, the Asm parser has no ``commentCharsInMOL`` characters.\n\n``extraLinesepChars``: adding line separators\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe Asm parser processes its input line-oriented way.  By default, the\nparser recognizes `\\n` as a line separator.  ``extraLinesepChars`` is\nfor adding more line separators.\n\nIn Gas for AArch64, the `;` character can be used as line separators.\nThe next example for adjusting the Asm parser to the extra line\nseparator:\n\n.. code-block:: console\n\n\t$ ctags ... --param-Asm.extraLinesepChars=';' ...\n\nEXPANDING C PREPROCESSOR MACROS\n-------------------------------\nThe Asm parser has the ability to expand **C preprocessor macros**\nbefore parsing.\n\n.. note::\n\n   Don't confuse C preprocessor macros and assembler implementation\n   specific macros. The Asm parser expands only C preprocessor macros.\n\nSpecifying following options are must for expansion::\n\n  --param-Asm.runCPreProcessor=true\n  --fields=+{signature}\n  --fields-CPreProcessor=+{macrodef}\n\nWith the above options, the parser expands macros defined in command\nline with ``-D`` option. See :ref:`ctags(1) <ctags(1)>` about the way to define a macro\nwith the ``-D`` option.\n\nWith ``--param-CPreProcessor._expand=1`` option, the parser expands\nmacros defined in the current input file in addition to macros defined\nwith the ``-D`` option.\n\nThough the parser expands macros, the parser doesn't extract language\nobjects like labels as you expect. You must adjust the parser specific\nparameters to utilize the macro expansion feature effectively. See\n\nAn example of macro expansion\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\"input.S\"\n\n.. code-block::\n\n\t#define ENTRY(LABEL) .global LABEL\t;\\\n\tLABEL\n\n\tENTRY(main):\n\t\tnop\n\n\"output.tags\"\nwith \"--options=NONE -o - --param-Asm.useCPreProcessor=1 --param-CPreProcessor._expand=1 --fields=+{signature} --fields-CPreProcessor=+{macrodef} --param-Asm.extraLinesepChars=; --fields-CPreProcessor=+{macrodef} input.S\"\n\n.. code-block:: tags\n\n\tENTRY\tinput.S\t/^#define ENTRY(/;\"\td\tfile:\tsignature:(LABEL)\tmacrodef:.global LABEL ;LABEL\n\tmain\tinput.S\t/^ENTRY(main):$/;\"\tl\n\tmain\tinput.S\t/^ENTRY(main):$/;\"\ts\n\nThe definition of `ENTRY` assumes `;` is a line separator in the host assembly language.\n``--param-Asm.extraLinesepChars=;`` is for satisfying the assumption in ctags side.\n\nKnown limitations\n~~~~~~~~~~~~~~~~~\nThe parser has no ability to expand the macros defined outside of the\ncurrent input file. The parser doesn't consider `#undef` when\nexpanding.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* The kind ``section`` is deleted.\n  The section specified with `.section` directive as tagged as\n  ``placement`` role of ``section`` kind of ``Asm`` language.\n  These kind and role are deleted.\n\n  Instead, it is tagged as ``destination`` role of ``inputSection``\n  kind of ``LdScript`` language.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`,\n:ref:`ctags-lang-asm(7) <ctags-lang-asm(7)>`,\nInfo entries for GNU assembler\n"
  },
  {
    "path": "docs/man/ctags-lang-autoit.7.rst",
    "content": ".. _ctags-lang-autoit(7):\n\n==============================================================\nctags-lang-autoit\n==============================================================\n\nRandom notes about tagging AutoIt source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+AutoIt ...\n|\t**ctags** ... --language-force=AutoIt ...\n|\t**ctags** ... --map-AutoIt=+.au3 ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging AutoIt source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* Drop ``$`` from tags for variables names.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-automake.7.rst",
    "content": ".. _ctags-lang-automake(7):\n\n==============================================================\nctags-lang-automake\n==============================================================\n\nRandom notes about tagging Automake source code (Makefile.am) with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Automake ...\n|\t**ctags** ... --language-force=Automake ...\n|\t**ctags** ... --map-Automake=+.am ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Automake source code (Makefile.am).\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* Add ``canonicalizedName`` extra.\n* Add ``pseudodir`` kind.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-c++.7.rst",
    "content": ".. _ctags-lang-c++(7):\n\n==============================================================\nctags-lang-c++\n==============================================================\n\nRandom notes about tagging C++ source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+C++ ...\n|\t**ctags** ... --language-force=C++ ...\n|\t**ctags** ... --map-C++=+.c++  ...\n|\t**ctags** ... --map-C++=+.cc  ...\n|\t**ctags** ... --map-C++=+.cpp  ...\n|\t**ctags** ... --map-C++=+.h  ...\n|   ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging C++ source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New field ``section``\n\n* New field ``alias``\n\nChange since \"1.1\"\n~~~~~~~~~~~~~~~~~~\n\n* New kinds ``module`` and ``partition``\n\n* New roles ``imported`` and ``exported`` for ``header`` kind\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`,\n:ref:`ctags-lang-ldscript(7) <ctags-lang-ldscript(7)>`,\n`The new C/C++ parser <https://docs.ctags.io/en/latest/parser-cxx.html>`_ (https://docs.ctags.io/en/latest/parser-cxx.html)\n"
  },
  {
    "path": "docs/man/ctags-lang-c.7.rst",
    "content": ".. _ctags-lang-c(7):\n\n==============================================================\nctags-lang-c\n==============================================================\n\nRandom notes about tagging C source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+C ...\n|\t**ctags** ... --language-force=C ...\n|\t**ctags** ... --map-C=+.c ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging C source code.\n\nVERSIONS\n--------\n\nSee the output of\n\n| **ctags** --describe-language=C\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`,\n:ref:`ctags-lang-ldscript(7) <ctags-lang-ldscript(7)>`,\n`The new C/C++ parser <https://docs.ctags.io/en/latest/parser-cxx.html>`_ (https://docs.ctags.io/en/latest/parser-cxx.html)\n"
  },
  {
    "path": "docs/man/ctags-lang-cuda.7.rst",
    "content": ".. _ctags-lang-cuda(7):\n\n==============================================================\nctags-lang-cuda\n==============================================================\n\nRandom notes about tagging CUDA source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+CUDA ...\n|\t**ctags** ... --language-force=CUDA ...\n|\t**ctags** ... --map-CUDA=+.cu  ...\n|\t**ctags** ... --map-CUDA=+.cuh  ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging CUDA source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New field ``section``\n\n* New field ``alias``\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`,\n:ref:`ctags-lang-ldscript(7) <ctags-lang-ldscript(7)>`,\n`The new C/C++ parser <https://docs.ctags.io/en/latest/parser-cxx.html>`_ (https://docs.ctags.io/en/latest/parser-cxx.html)\n"
  },
  {
    "path": "docs/man/ctags-lang-elm.7.rst",
    "content": ".. _ctags-lang-elm(7):\n\n==============================================================\nctags-lang-elm\n==============================================================\n\nRandom notes about tagging Elm source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Elm ...\n|\t**ctags** ... --language-force=Elm ...\n|\t**ctags** ... --map-Elm=+.elm ...\n\nDESCRIPTION\n-----------\nThe Elm parser is a PEG parser using PackCC, which is part of the\nctags infrastructure. It should correctly process all top level\nstatements, however there is a limitation with functions embedded\nin let/in blocks. They will mostly be fine, but sometimes a\nfunction in a let/in block will be omitted.\n\nEXAMPLES\n--------\n\nImports\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nImported modules are tagged, and their role is \"imported\", not \"def\".\nTypes, functions, etc which are exposed via imported module have their\nrole as \"exposed\".\n\nExposed items are marked as being in the scope of their own module,\nnot the module that's doing the importing.\n\n\"input.elm\"\n\n.. code-block:: Elm\n\n\tmodule SomeMod exposing (..)\n\n\timport MyMod exposing\n\t  ( map\n\t  , Maybe\n\t  , Result(..)\n\t  , MyList(Empty)\n\t  )\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+r --fields=+r input.elm\"\n\n.. code-block:: tags\n\n\tSomeMod\tinput.elm\t/^module SomeMod exposing (..)$/;\"\tm\troles:def\n\tMyMod\tinput.elm\t/^import MyMod exposing$/;\"\tm\troles:imported\n\tmap\tinput.elm\t/^  ( map$/;\"\tf\tmodule:MyMod\troles:exposed\n\tMaybe\tinput.elm\t/^  , Maybe$/;\"\tt\tmodule:MyMod\troles:exposed\n\tResult\tinput.elm\t/^  , Result(..)$/;\"\tt\tmodule:MyMod\troles:exposed\n\tMyList\tinput.elm\t/^  , MyList(Empty)$/;\"\tt\tmodule:MyMod\troles:exposed\n\tEmpty\tinput.elm\t/^  , MyList(Empty)$/;\"\tc\ttype:MyMod.MyList\troles:exposed\n\nNamespaces\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nNamespaces are tagged and their role is \"def\".\n\n\"input.elm\"\n\n.. code-block:: Elm\n\n\tmodule AMod exposing (..)\n\n\timport MyImport as NSpace exposing (impFunc)\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+r --fields=+r input.elm\"\n\n.. code-block:: tags\n\n\tAMod\tinput.elm\t/^module AMod exposing (..)$/;\"\tm\troles:def\n\tNSpace\tinput.elm\t/^import MyImport as NSpace exposing (impFunc)$/;\"\tn\tmodule:AMod\troles:def\tmoduleName:MyImport\n\tMyImport\tinput.elm\t/^import MyImport as NSpace exposing (impFunc)$/;\"\tm\troles:imported\n\timpFunc\tinput.elm\t/^import MyImport as NSpace exposing (impFunc)$/;\"\tf\tmodule:MyImport\troles:exposed\n\nType names\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nConstructors top level functions will have type names.\n\n\"input.elm\"\n\n.. code-block:: Elm\n\n\tfuncA : Int -> Int\n\tfuncA a = a + 1\n\n\ttype B\n\t    = B1Cons\n\t      { x : Float\n\t      , y : Float\n\t      }\n\t    | B2Cons String Integer\n\t    | B3Cons\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+r --fields=+r input.elm\"\n\n.. code-block:: tags\n\n\tfuncA\tinput.elm\t/^funcA a = a + 1$/;\"\tf\ttyperef:typename:Int -> Int\troles:def\n\tB\tinput.elm\t/^type B$/;\"\tt\troles:def\n\tB1Cons\tinput.elm\t/^    = B1Cons$/;\"\tc\ttype:B\ttyperef:typename:{ x : Float , y : Float } -> B\troles:def\n\tB2Cons\tinput.elm\t/^    | B2Cons String Integer$/;\"\tc\ttype:B\ttyperef:typename:String -> Integer -> B\troles:def\n\tB3Cons\tinput.elm\t/^    | B3Cons$/;\"\tc\ttype:B\ttyperef:typename:B\troles:def\n\nFunction parameter lists\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFunction parameter lists can be extracted into the tags file\nsignature field. They are not really function signatures, but\nit's the closest concept available in ctags.\nUse \"--fields=+S\".\n\n.. code-block:: Elm\n\n    funcA a1 a2 =\n        a1 + a2\n\n\"output.tags\"\nwith \"--sort=no --extras=+r --fields=+rS\"\n\n.. code-block:: tags\n\n    funcA\tinput.elm\t/^funcA a1 a2 =$/;\"\tf\tsignature:a1 a2\troles:def\n\nKNOWN LIMITATIONS\n-----------------\nThe ctags signature field is used for function parameter lists, even\nthough it's not an idea field. See above.\n\nElm requires all statements at the same logical level to have the\nsame indentation. If there is additional indentation that line is part\nof the previous one. Therefore without over-complicating the\nPEG parser we have the following limitations...\n\nSometimes functions in let/in blocks will be omitted.\n\nFunctions in let/in blocks will be marked as being in the scope of their\nouter function, regardless of how deeply nested the let/in block is.\n\nFunctions in let/in blocks won't have type names.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-emacslisp.7.rst",
    "content": ".. _ctags-lang-emacslisp(7):\n\n==============================================================\nctags-lang-emacslisp\n==============================================================\n\nRandom notes about tagging EmacsLisp source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+EmacsLisp ...\n|\t**ctags** ... --language-force=EmacsLisp ...\n|\t**ctags** ... --map-Lisp=+.el ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging EmacsLisp source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* Add ``definer`` field.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-fortran.7.rst",
    "content": ".. _ctags-lang-fortran(7):\n\n==============================================================\nctags-lang-fortran\n==============================================================\n\nRandom notes about tagging Fortran source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Fortran ...\n|\t**ctags** ... --language-force=Fortran ...\n|\t**ctags** ... --map-Fortran=+.f ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging FORTRAN source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New extra ``linkName``.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-gdscript.7.rst",
    "content": ".. _ctags-lang-gdscript(7):\n\n==============================================================\nctags-lang-gdscript\n==============================================================\n\nRandom notes about tagging GDScript source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+GDScript ...\n|\t**ctags** ... --language-force=GDScript ...\n|\t**ctags** ... --map-GDScript=+.gd ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging GDScript source code\nwith Universal Ctags.\n\nStoring Annotations\n-------------------\nLike the Python parser storing decorations to ``decorations`` field,\nthe GDScript parser stores annotations\nstarting from `@` to the language specific field, ``annotations``.\nThough the field is enabled explicitly in following examples, the\nfield is enabled by default.\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\t@export\n\tvar s = \"Hello\"\n\n\t@master\n\tfunc f(msg):\n\t\tprint(msg)\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --fields-GDScript=+{annotations} -o - input.gd\"\n\n.. code-block:: tags\n\n\ts\tinput.gd\t/^var s = \"Hello\"$/;\"\tv\tannotations:export\n\tf\tinput.gd\t/^func f(msg):$/;\"\tm\tannotations:master\n\nExtracting `func`\n-----------------\nA language object defined with `func` keyword is tagged with ``method`` kind.\nLike annotations, the parser stores keywords modifying `func` like `static` to\nthe ``annotations`` field.\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\tfunc f(x):\n\t\treturn x\n\n\tstatic func f_s(x):\n\t\treutrn x\n\n\tremote func f_r(x):\n\t\treturn x\n\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --fields=+K --fields-GDScript=+{annotations} -o - input.gd\"\n\n.. code-block:: tags\n\n\tf\tinput.gd\t/^func f(x):$/;\"\tmethod\n\tf_s\tinput.gd\t/^static func f_s(x):$/;\"\tmethod\tannotations:static\n\tf_r\tinput.gd\t/^remote func f_r(x):$/;\"\tmethod\tannotations:remote\n\nTagging implicitly defined classes\n----------------------------------\n\"A file is a class!\" in GDScript.  A class is implicitly\ndefined. Functions, variables, constants, and signals are parts of the\nclass though the class is unnamed by default.\n\nIf the language specific extra, ``implicitClass``, is enabled, the\nparser makes a anonymous tag for the class. The parser fills the scope\nfields of the tags for all language objects defined in the file with\nthe anonymous tag.\n\nLet's see an example demonstrating the effect of the extra.\n\nTurning off the extra:\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\tfunc f(x):\n\t\treturn x\n\n\"output.tags\"\nwith \"--options=NONE --fields=+KZ --extras-GDScript=-{implicitClass} -o - input.gd\"\n\n.. code-block:: tags\n\n\tf\tinput.gd\t/^func f(x):$/;\"\tmethod\n\nTurning on the extra:\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\tfunc g(x):\n\t\treturn x\n\n\"output.tags\"\nwith \"--options=NONE --fields=+KZ --extras-GDScript=+{implicitClass} -o - input.gd\"\n\n.. code-block:: tags\n\n\tanon_class_84011bee0100\tinput.gd\t/^func g(x):$/;\"\tclass\n\tg\tinput.gd\t/^func g(x):$/;\"\tmethod\tscope:class:anon_class_84011bee0100\n\nTagging the name specified with `class_name`\n---------------------------------------------\n`class_name` is a keyword for giving a name to the implicitly defined\nclass.  If ``implicitClass`` is turned off, the parser just extract\nthe name coming after the keyword with ``class`` kind. If\n``implicitClass`` is turned on, the parser converts the anonymous tag\nto a non-anonymous tag with the specified name.  When converting,\nthe parser also updates scope fields of the other tags in the file.\n\nTurning off the extra:\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\tclass_name c\n\n\tfunc f(x):\n\t\treturn x\n\n\"output.tags\"\nwith \"--options=NONE --fields=+KZ --extras-GDScript=-{implicitClass} -o - input.gd\"\n\n.. code-block:: tags\n\n\tc\tinput.gd\t/^class_name c$/;\"\tclass\n\tf\tinput.gd\t/^func f(x):$/;\"\tmethod\n\nTurning on the extra:\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\tclass_name C\n\tfunc g(x):\n\t\treturn x\n\n\"output.tags\"\nwith \"--options=NONE --fields=+KZ --extras-GDScript=+{implicitClass} -o - input.gd\"\n\n.. code-block:: tags\n\n\tC\tinput.gd\t/^class_name C$/;\"\tclass\n\tg\tinput.gd\t/^func g(x):$/;\"\tmethod\tscope:class:C\n\nFilling ``inherits`` field\n--------------------------\n`extends` keyword specifies the super class for the implicitly defined class.\nIf `implicitClass` extra is turned on, the parser fills ``inherits`` field\nof the tag for the implicitly defined class with the name of super class.\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\textends B\n\tclass_name C\n\n\"output.tags\"\nwith \"--options=NONE --fields=+Ki --extras-GDScript=+{implicitClass} -o - input.gd\"\n\n.. code-block:: tags\n\n\tC\tinput.gd\t/^class_name C$/;\"\tclass\tinherits:B\n\nWhen `--extras=+r` is given, the parser extracts the class specified with the\n`extends` keyword as a reference tag of ``class`` kind with ``extended`` role.\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\textends B\n\n\"output.tags\"\nwith \"--options=NONE --fields=+rEK --extras=+r -o - input.gd\"\n\n.. code-block:: tags\n\n\tB\tinput.gd\t/^extends B$/;\"\tclass\troles:extended\textras:reference\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-i18nrubygem.7.rst",
    "content": ".. _ctags-lang-i18nrubgem(7):\n\n==============================================================\nctags-lang-i18nrubgem\n==============================================================\n\nRandom notes about tagging input for I18n Ruby Gem with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n:Expected feature: yaml\n\nSYNOPSIS\n--------\n|\t**ctags** ... --extras=+s --languages=+I18nRubyGem ...\n|\t**ctags** ... --extras=+s --language-force=I18nRubyGem ...\n|\t**ctags** ... --extras=+s --map-I18nRubyGem=+.yaml ...\n|\t**ctags** ... --extras=+s --map-I18nRubyGem=+.yml ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging input for I18n Ruby\nGem [RUBYI18N]_. I18nRubyGem is a subparser running on Yaml parser. If a\ntop-level scalar token of a given Yaml source input is a local name [ISOCODES]_,\nI18nRubyGem activates itself. If not, I18nRubyGem does nothing.\n\n\"input.yaml\"\n\n.. code-block:: YAML\n\n\t---\n\tja:\n\t  msg:\n\t    error: エラー\n\t    function: 関数\n\n\"output.tags\"\nwith \"--options=NONE -o - --fields=+E input.yaml\"\n\n.. code-block:: tags\n\n\terror\tinput.yaml\t/^    error: エラー$/;\"\tk\tkeyInMiddle:ja.msg\textras:subparser\n\tfunction\tinput.yaml\t/^    function: 関数$/;\"\tk\tkeyInMiddle:ja.msg\textras:subparser\n\tja.msg.error\tinput.yaml\t/^    error: エラー$/;\"\tk\tkeyInMiddle:ja.msg\textras:subparser,localeful\n\tja.msg.function\tinput.yaml\t/^    function: 関数$/;\"\tk\tkeyInMiddle:ja.msg\textras:subparser,localeful\n\tmsg.error\tinput.yaml\t/^    error: エラー$/;\"\tk\tlocale:ja\textras:subparser,localeless\n\tmsg.function\tinput.yaml\t/^    function: 関数$/;\"\tk\tlocale:ja\textras:subparser,localeless\n\n\nWith the options, the parser emits three tag entries for a key:\n\"error\", \"js.msg.error\", and \"msg.error\" for the key \"error\", The\nparser emits \"error\" at the first line always.\n\nTo emit \"ja.msg.error\", a ``localeful`` extra tag, at the fifth line\nalways. If you specify ``--extra=+q`` or ``--extra=+{qualified}``,\nctags emits the same tag twice: a ``localeful`` tag, and a ``qualified`` tag.\nYou can suppress the ``localeful`` extra tags., specify\n``--extras-I18nRubyGem=-{localeful}``.\n\nTo emit \"msg.error\", a ``localeless`` extra tag, at the fifth line\nalways. The parser creates a ``localeless`` extra tag by truncating\nthe first component (e.g. \"ja.\") from the associated full qualified\nextra tag (e.g. \"ja.msg.error\").  ``localeless`` extra is enabled by\ndefault. If you don't need ``localeless`` extra tags, specify\n``--extras-I18nRubyGem=-{localeless}``.\n\nThe parser doesn't make tag entries for top-level and mid-level components like\n``ja`` and ``msg`` by default. If you need them, specify\n``--kinds-I18nRubyGem=+{locale}`` and/or\n``--kinds-I18nRubyGem=+{keyInMiddle}``.\n\nKNOWN BUGS\n----------\nThe mechanism activating I18nRubyGem subparser doesn't work well for YAML\nsource input containing multiple documents.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n\nREFERENCES\n----------\n.. [RUBYI18N] Ruby I18n, https://github.com/ruby-i18n/i18n\n.. [ISOCODES] iso-codes, https://salsa.debian.org/iso-codes-team/iso-codes\n"
  },
  {
    "path": "docs/man/ctags-lang-iPythonCell.7.rst",
    "content": ".. _ctags-lang-iPythonCell(7):\n\n==============================================================\nctags-lang-iPythonCell\n==============================================================\n\nThe man page of the iPythonCell parser for Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --extras=+{subparser} --languages=+iPythonCell,Python \\\\\n|                     [--extras-IPythonCell=+{doubleSharps}] \\\\\n|                     [--regex-IPythonCell=/<PATTERN>/\\\\n/c/] ...\n\nDESCRIPTION\n-----------\niPythonCell parser is a subparser stacked on top of the Python parser.\nIt works when:\n\n* the Python parser is enabled,\n* the ``subparser`` extra is enabled, and\n* the iPythonCell parser itself is enabled.\n\nThe iPythonCell parser extracts cells explained as in vim-ipython-cell\n(https://github.com/hanschen/vim-ipython-cell/blob/master/README.md).\n\nKIND(S)\n-------\nThe iPythonCell parser defines only a ``cell`` kind.\n\nEXTRA(S)\n--------\n\nTagging cells staring with ``##...`` is disabled by default because\nthe pattern is too generic; with that pattern unwanted tags can be extracted.\n\nEnable ``doubleSharps`` language specific extra for tagging cells\nstaring with ``##...``.\n\nCUSTOMIZING\n-----------\nIf your favorite cell pattern is not supported in the parser, you can\ndefine the pattern in your ``.ctagd.d/your.ctags`` or command lines.\nHere is an example how to support \"``# CTAGS: ...``\":\n\n\"input.py\"\n\n.. code-block:: Python\n\n\tx=1\n\t# CTAGS: DEFINE F\n\tdef F():\n\t\t# CTAGS: DO NOTING\n\t\tpass\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --extras=+{subparser} --regex-IPythonCell=/[ \\t]*# CTAGS:[ ]?(.*)$/\\1/c/ -o - input.py\"\n\n.. code-block:: tags\n\n   x\tinput.py\t/^x=1$/;\"\tv\n   DEFINE F\tinput.py\t/^# CTAGS: DEFINE F$/;\"\tc\n   F\tinput.py\t/^def F():$/;\"\tf\n   DO NOTING\tinput.py\t/^\t# CTAGS: DO NOTING$/;\"\tc\n\nYou can put \"``--regex-IPythonCell=/[ \\t]*# CTAGS:[ ]?(.*)$/\\1/c/``\" in ``your.ctags``\nto avoid specifying the pattern repeatedly.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`, :ref:`ctags-lang-python(7) <ctags-lang-python(7)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-inko.7.rst",
    "content": ".. _ctags_lang-inko(7):\n\n======================================================================\nctags-lang-inko\n======================================================================\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Inko ...\n|\t**ctags** ... --language-force=Inko ...\n|\t**ctags** ... --map-Inko=+.inko ...\n\nDESCRIPTION\n-----------\nThis man page describes the Inko parser for Universal Ctags.\n\nThe input file is expected to be valid Inko source code, otherwise the output of\nctags is undefined.\n\nTags are generated for objects, traits, methods, attributes, and constants.\nString literals are ignored.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-javascript.7.rst",
    "content": ".. _ctags-lang-javascript(7):\n\n==============================================================\nctags-lang-javascript\n==============================================================\n\nRandom notes about tagging JavaScript source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+JavaScript ...\n|\t**ctags** ... --language-force=JavaScript ...\n|\t**ctags** ... --map-JavaScript=+.js ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging JavaScript source code.\n\nCLASSES\n-------\n\nES6 introduced the ``class`` keyword, but there is still the original method of defining a function and attaching a ``prototype``.  ctags follows the convention that function names that start with a capital letter are class constructors.\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New role ``foreigndecl`` for ``function`` kind\n\nChange since \"1.1\"\n~~~~~~~~~~~~~~~~~~\n\n* New field ``properties``\n\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-julia.7.rst",
    "content": ".. _ctags-lang-julia(7):\n\n==============================================================\nctags-lang-julia\n==============================================================\n\nRandom notes about tagging Julia source code with Universal-ctags\n\n:Version: 6.2.0\n:Manual group: Universal-ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Julia ...\n|\t**ctags** ... --language-force=Julia ...\n|\t**ctags** ... --map-Julia=+.jl ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Julia source code.\n\nTAGGING ``import`` AND ``using`` EXPRESSIONS\n--------------------------------------------\n\nSummary\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n`using X`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     used               N/A\n\t==== ========== ================== ===================\n\n`using X: a, b`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     namespace          N/A\n\ta, b unknown    used               scope:module:X\n\t==== ========== ================== ===================\n\n`import X`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     imported           N/A\n\t==== ========== ================== ===================\n\n`import X.a, Y.b`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX, Y module     namespace          N/A\n\ta    unknown    imported           scope:module:X\n\tb    unknown    imported           scope:module:Y\n\t==== ========== ================== ===================\n\n`import X: a, b`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     namespace          N/A\n\ta,b  unknown    imported           scope:module:X\n\t==== ========== ================== ===================\n\nExamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\"input.jl\"\n\n.. code-block:: Julia\n\n\tusing X0\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzK input.jl\"\n\n.. code-block:: tags\n\n\tX0\tinput.jl\t/^using X0$/;\"\tkind:module\troles:used\n\n``--extras=+r`` (or ``--extras=+{reference}``) option is needed for this tag,\nsince it's a reference tag. This is because module ``X`` is not defined here.\nIt is defined in another file. Enable ``roles:`` field with ``--fields=+r`` is\nfor recording that the module is \"used\", i.e., loaded by ``using``.\n\n\"input.jl\"\n\n.. code-block:: Julia\n\n\timport X1.a, X2.b, X3\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzKZ input.jl\"\n\n.. code-block:: tags\n\n\tX1\tinput.jl\t/^import X1.a, X2.b, X3$/;\"\tkind:module\troles:namespace\n\tX2\tinput.jl\t/^import X1.a, X2.b, X3$/;\"\tkind:module\troles:namespace\n\tX3\tinput.jl\t/^import X1.a, X2.b, X3$/;\"\tkind:module\troles:imported\n\ta\tinput.jl\t/^import X1.a, X2.b, X3$/;\"\tkind:unknown\tscope:module:X1\troles:imported\n\tb\tinput.jl\t/^import X1.a, X2.b, X3$/;\"\tkind:unknown\tscope:module:X2\troles:imported\n\nWhy ``X1`` and ``X2`` have role \"namespace\", while ``X3`` have role \"imported\"?\nIt's because the symbol ``a`` in module ``X1``, and ``b`` in module ``X2`` are\nbrought to the current scope, but ``X1`` and ``X2`` themselves are not. We use\n\"namespace\" role for such modules.\n\n``X3`` is different. The symbol ``X3``, together with all exported symbols in\n``X3``, is brought to current scope. For such modules, we use \"imported\" or\n\"used\" role depending whether they are loaded by ``import`` or ``using``.\n\nAlso, notice that ``a`` and ``b`` have the \"unknown\" kind. This is because we\ncannot know whether it's a function, constant, or macro, etc.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-kconfig.7.rst",
    "content": ".. _ctags-lang-kconfig(7):\n\n==============================================================\nctags-lang-kconfig\n==============================================================\n\nRandom notes about tagging Kconfig source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Kconfig ...\n|\t**ctags** ... --language-force=Kconfig ...\n|\t**ctags** ... --map-Kconfig=+(Kconfig*) ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Kconfig scripts.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``variable``\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`,\n`Kconfig Language <https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html>`_ (https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html),\n`Kconfig macro language <https://www.kernel.org/doc/html/latest/kbuild/kconfig-macro-language.html>`_ (https://www.kernel.org/doc/html/latest/kbuild/kconfig-macro-language.html),\n"
  },
  {
    "path": "docs/man/ctags-lang-ldscript.7.rst",
    "content": ".. _ctags-lang-ldscript(7):\n\n==============================================================\nctags-lang-ldscript\n==============================================================\n\nRandom notes about tagging LdScript source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+LdScript ...\n|\t**ctags** ... --language-force=LdScript ...\n|\t**ctags** ... --map-LdScript=+.lds ...\n|\t**ctags** ... --map-LdScript=+.lds.S ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging LdScript source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New role ``destination`` for ``inputSection`` kind\n\n* New role ``aliased`` for  ``symbol`` kind\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`,\n:ref:`ctags-lang-asm(7) <ctags-lang-asm(7)>`,\n:ref:`ctags-lang-c(7) <ctags-lang-c(7)>`,\n:ref:`ctags-lang-c++(7) <ctags-lang-c++(7)>`,\n:ref:`ctags-lang-cuda(7) <ctags-lang-cuda(7)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-lex.7.rst",
    "content": ".. _ctags-lang-lex(7):\n\n==============================================================\nctags-lang-lex\n==============================================================\n\nRandom notes about tagging Lex source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+LEX ...\n|\t**ctags** ... --language-force=LEX ...\n|\t**ctags** ... --map-Lex=+.l ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging LEX source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New role ``grouping`` for ``cond`` kind\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-lisp.7.rst",
    "content": ".. _ctags-lang-lisp(7):\n\n==============================================================\nctags-lang-lisp\n==============================================================\n\nRandom notes about tagging Lisp source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Lisp ...\n|\t**ctags** ... --language-force=Lisp ...\n|\t**ctags** ... --map-Lisp=+.cl ...\n|\t**ctags** ... --map-Lisp=+.clisp ...\n|\t**ctags** ... --map-Lisp=+.l ...\n|\t**ctags** ... --map-Lisp=+.lisp ...\n|\t**ctags** ... --map-Lisp=+.lsp ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Lisp source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* Add kinds:\n\n  + ``class``,\n  + ``generic``,\n  + ``method``,\n  + ``parameter``,\n  + ``struct``, and\n  + ``type``.\n\n* Add ``definer`` field.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-make.7.rst",
    "content": ".. _ctags-lang-make(7):\n\n==============================================================\nctags-lang-make\n==============================================================\n\nRandom notes about tagging Make source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Make ...\n|\t**ctags** ... --language-force=Make ...\n|\t**ctags** ... --map-Make=+([Mm]akefile) --map-Make=+(GNUmakefile) ...\n|\t**ctags** ... --map-Make=+.mak --map-Make=+.mk ...\n\nDESCRIPTION\n-----------\nThis parser extracts macro and target definitions. It also extracts included files as references.\n\nExamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\"input.mak\"\n\n.. code-block:: Makefile\n\n   -include base.mak\n\n   SRC = hello.c\n\n   all: hello\n   hello: hello.o\n   hello.o: hello.c\n   $(CC) -c $(CFLAGS) $(CPPFLAGS) $<\n\n\"output.tags\"\nwith \"--options=NONE --extras=+r --fields=+KlrE -o - input.mak\"\n\n.. code-block:: tags\n\n   SRC\tinput.mak\t/^SRC = hello.c$/;\"\tmacro\tlanguage:Make\troles:def\n   all\tinput.mak\t/^all: hello$/;\"\ttarget\tlanguage:Make\troles:def\n   base.mak\tinput.mak\t/^-include base.mak$/;\"\tmakefile\tlanguage:Make\troles:optional\textras:reference\n   hello\tinput.mak\t/^hello: hello.o$/;\"\ttarget\tlanguage:Make\troles:def\n   hello.o\tinput.mak\t/^hello.o: hello.c$/;\"\ttarget\tlanguage:Make\troles:def\n\n\nEXTRACTING CPP MACRO DEFINTIONS DEFINED WITH -DFOO\n---------------------------------------------------\nWith ``-D`` option in a C compiler like gcc, a programmer can define a\nmacro outside C source files. The options appears on a Makefile\nfrequently. For an example:\n\n.. code-block:: Makefile\n\n   CPPFLAGS = -DDEBUG\n\nThe Make parser has heuristics [DINMAKE]_ for extracting the macros defined with\nthe option. With enabling ``CppDef`` extra, you can turn on the heuristics.\n\nExamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\"input.mak\"\n\n.. code-block:: Makefile\n\n   -include base.mak\n\n   CFLAGS = -g -O2\n   CPPFLAGS = -DOUTPUT=stdout\n   SRC = hello.c\n\n   all: hello\n   hello: hello.o\n   hello.o: hello.c\n   $(CC) -c $(CFLAGS) $(CPPFLAGS) $<\n\n\"output.tags\"\nwith \"--options=NONE --extras-Make=+{CppDef} --fields=+KlE -o - input.mak\"\n\n.. code-block:: tags\n\n   CFLAGS\tinput.mak\t/^CFLAGS = -g -O2$/;\"\tmacro\tlanguage:Make\n   CPPFLAGS\tinput.mak\t/^CPPFLAGS = -DOUTPUT=stdout$/;\"\tmacro\tlanguage:Make\n   OUTPUT\tinput.mak\t/^CPPFLAGS = -DOUTPUT=stdout$/;\"\tmacro\tlanguage:CPreProcessor\textras:CppDef\n   SRC\tinput.mak\t/^SRC = hello.c$/;\"\tmacro\tlanguage:Make\n   all\tinput.mak\t/^all: hello$/;\"\ttarget\tlanguage:Make\n   hello\tinput.mak\t/^hello: hello.o$/;\"\ttarget\tlanguage:Make\n   hello.o\tinput.mak\t/^hello.o: hello.c$/;\"\ttarget\tlanguage:Make\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New extra ``CppDef`` [DINMAKE]_\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n\n.. [DINMAKE] `CONFIG_X86_X32_ABI is not visible (defined in Makefile, not C or Kconfig) <https://github.com/bootlin/elixir/issues/221>`_ (https://github.com/bootlin/elixir/issues/221)\n"
  },
  {
    "path": "docs/man/ctags-lang-markdown.7.rst",
    "content": ".. _ctags-lang-markdown(7):\n\n==============================================================\nctags-lang-markdown\n==============================================================\n\nRandom notes about tagging Markdown source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Markdown ...\n|\t**ctags** ... --language-force=Markdown ...\n|\t**ctags** ... --map-Markdown=+.md ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Markdown documents [XSYNTAX]_.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``hashtag`` [HASHTAG]_\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n\n.. [XSYNTAX] `Extend Syntax <https://www.markdownguide.org/extended-syntax/>`_ (https://www.markdownguide.org/extended-syntax/) in Markdown Guide\n.. [HASHTAG] `Hashtags in Markdown notes for VSCode <https://github.com/vanadium23/markdown-hashtags#hashtags-in-markdown-notes-for-vscode>`_ (https://github.com/vanadium23/markdown-hashtags#hashtags-in-markdown-notes-for-vscode)\n"
  },
  {
    "path": "docs/man/ctags-lang-meson.7.rst",
    "content": ".. _ctags-lang-meson(7):\n\n==============================================================\nctags-lang-meson\n==============================================================\n\nRandom notes about tagging Meson build scripts with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Meson ...\n|\t**ctags** ... --language-force=Meson ...\n|\t**ctags** ... --map-Meson=+(meson.build) ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Meson build scripts.\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kinds ``cfgdata`` and ``cfgvar``\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-odin.7.rst",
    "content": ".. _ctags-lang-odin(7):\n\n==============================================================\nctags-lang-odin\n==============================================================\n\nNotes about tagging Odin source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Odin ...\n|\t**ctags** ... --language-force=Odin ...\n|\t**ctags** ... --map-Odin=+.odin ...\n\nDESCRIPTION\n-----------\nThis man page gathers notes about tagging Odin source code\nwith Universal Ctags.\n\nThe Odin parser tags packages, procedures, constants, variables,\nstructs, enums, unions, struct members, enum values, type aliases,\nand foreign imports.\n\nDistinguishing types from constants\n------------------------------------\nIn Odin, the syntax for a type alias and a constant binding are\nidentical::\n\n\tMy_Type :: Other_Type\n\tMY_CONST :: OTHER_CONST\n\nWhen the right-hand side of a ``::`` binding is a plain identifier,\nthe parser cannot syntactically determine whether it is a type alias\nor a constant. In this case, the parser uses a naming-convention\nheuristic: if the name on the left-hand side contains any lowercase\nletter, it is tagged as a ``type`` (kind ``t``); if the name is\nentirely uppercase (and underscores/digits), it is tagged as a\n``const`` (kind ``c``).\n\nThis follows the strong Odin convention that type names use\n``Ada_Case`` and constants use ``SCREAMING_SNAKE_CASE``.\n\n\"input.odin\"\n\n.. code-block:: Odin\n\n\tpackage example\n\n\tHandle :: distinct rawptr\n\tVector2 :: [2]f32\n\tCallback :: proc(x: int) -> bool\n\tMy_Alias :: Some_Type\n\tMAX_SIZE :: SOME_VALUE\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --fields=+K -o - input.odin\"\n\n.. code-block:: tags\n\n\texample\tinput.odin\t/^package example$/;\"\tpackage\n\tHandle\tinput.odin\t/^Handle :: distinct rawptr$/;\"\ttype\tpackage:example\n\tVector2\tinput.odin\t/^Vector2 :: [2]f32$/;\"\ttype\tpackage:example\n\tCallback\tinput.odin\t/^Callback :: proc(x: int) -> bool$/;\"\ttype\tpackage:example\n\tMy_Alias\tinput.odin\t/^My_Alias :: Some_Type$/;\"\ttype\tpackage:example\n\tMAX_SIZE\tinput.odin\t/^MAX_SIZE :: SOME_VALUE$/;\"\tconst\tpackage:example\n\nNote that when the right-hand side is a keyword such as ``struct``,\n``enum``, ``union``, ``distinct``, ``proc``, ``map``, or a syntactic\nform such as ``^Type``, ``[N]Type``, or ``#type``, the parser\nidentifies the kind unambiguously without relying on the heuristic.\n\nThe heuristic will misclassify names that break the convention, such\nas an all-uppercase type alias (``HANDLE :: Some_Type`` would be\ntagged as ``const``) or a lowercase-containing constant\n(``kMaxSize :: SOME_VALUE`` would be tagged as ``type``).\nIn practice, these cases are rare in idiomatic Odin code.\n\nForeign blocks\n--------------\nThe parser extracts procedure and variable declarations from\n``foreign`` blocks.\n\n\"input.odin\"\n\n.. code-block:: Odin\n\n\tpackage ffi\n\n\tforeign import libc \"system:libc.so\"\n\n\tforeign libc {\n\t    puts :: proc \"c\" (s: cstring) -> i32 ---\n\t    errno: i32\n\t}\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --fields=+K -o - input.odin\"\n\n.. code-block:: tags\n\n\tffi\tinput.odin\t/^package ffi$/;\"\tpackage\n\tlibc\tinput.odin\t/^foreign import libc \"system:libc.so\"$/;\"\tforeign\tpackage:ffi\n\tputs\tinput.odin\t/^    puts :: proc \"c\" (s: cstring) -> i32 ---$/;\"\tproc\tpackage:ffi\n\terrno\tinput.odin\t/^    errno: i32$/;\"\tvar\tpackage:ffi\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-powershell.7.rst",
    "content": ".. _ctags-lang-powershell(7):\n\n==============================================================\nctags-lang-powershell\n==============================================================\n\nRandom notes about tagging PowerShell source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|  **ctags** ... --languages=+PowerShell ...\n|  **ctags** ... --language-force=PowerShell ...\n|  **ctags** ... --map-powershell=+.ps1 ...\n|  **ctags** ... --map-powershell=+.psm1 ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging PowerShell source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``enumlabel``\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-python.7.rst",
    "content": ".. _ctags-lang-python(7):\n\n==============================================================\nctags-lang-python\n==============================================================\n\nRandom notes about tagging python source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Python ...\n|\t**ctags** ... --language-force=Python ...\n|\t**ctags** ... --map-Python=+.py ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging python source code.\n\nTAGGING ``import`` STATEMENTS\n-----------------------------\n\nSummary\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n`import X`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     imported           N/A\n\t==== ========== ================== ===================\n\n`import X as Y`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     indirectlyImported N/A\n\tY    namespace  definition         nameref:module:X\n\t==== ========== ================== ===================\n\n`from X import *`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\t`X`  module     namespace          N/A\n\t==== ========== ================== ===================\n\n`from X import Y`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\t`X`  module     namespace          N/A\n\t`Y`  unknown    imported           scope:module:`X`\n\t==== ========== ================== ===================\n\n`from X import Y as Z`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\t`X`  module     namespace          N/A\n\t`Y`  unknown    indirectlyImported scope:module:`X`\n\t`Z`  unknown    definition         nameref:unknown:`Y`\n\t==== ========== ================== ===================\n\n..\n\t===================== ==== ========== ================== ===================\n\tinput code            name kind       role               other noticeable fields\n\t===================== ==== ========== ================== ===================\n\timport X              X    module     imported\n\timport X as Y         X    module     indirectlyImported\n\timport X as Y         Y    namespace  definition         nameref:module:X\n\tfrom X import *       X    module     namespace\n\tfrom X import Y       X    module     namespace\n\tfrom X import Y       Y    unknown    imported           scope:module:X\n\tfrom X import Y as Z  X    module     namespace\n\tfrom X import Y as Z  Y    unknown    indirectlyImported scope:module:X\n\tfrom X import Y as Z  Z    unknown    definition         nameref:unknown:Y\n\t===================== ==== ========== ================== ===================\n\n..  a table having merged cells cannot be converted to man page\n..\n\t+--------------------+------------------------------------------------------+\n\t|input code          |output tags                                           |\n\t|                    +----+----------+------------------+-------------------+\n\t|                    |name| kind     |role              |other noticeable fields  |\n\t+====================+====+==========+==================+===================+\n\t|import X            |X   | module   |imported          |                   |\n\t+--------------------+----+----------+------------------+-------------------+\n\t|import X as Y       |X   | module   |indirectlyImported|                   |\n\t|                    +----+----------+------------------+-------------------+\n\t|                    |Y   | namespace|definition        |nameref:module:X   |\n\t+--------------------+----+----------+------------------+-------------------+\n\t|from X import *     |X   | module   |namespace         |                   |\n\t+--------------------+----+----------+------------------+-------------------+\n\t|from X import Y     |X   | module   |namespace         |                   |\n\t|                    +----+----------+------------------+-------------------+\n\t|                    |Y   | unknown  |imported          |scope:module:X     |\n\t+--------------------+----+----------+------------------+-------------------+\n\t|from X import Y as Z|X   | module   |namespace         |                   |\n\t|                    +----+----------+------------------+-------------------+\n\t|                    |Y   | unknown  |indirectlyImported|scope:module:X     |\n\t|                    +----+----------+------------------+-------------------+\n\t|                    |Z   | unknown  |definition        |nameref:unknown:Y  |\n\t+--------------------+----+----------+------------------+-------------------+\n\nExamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\"input.py\"\n\n.. code-block:: Python\n\n   import X0\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzK input.py\"\n\n.. code-block:: tags\n\n\tX0\tinput.py\t/^import X0$/;\"\tkind:module\troles:imported\n\nA tag for an imported module has ``module`` kind with ``imported`` role.  The\nmodule is not defined here; it is defined in another file. So the tag for the\nimported module is a reference tag; specify ``--extras=+r`` (or\n``--extras=+{reference}``) option for tagging it.  \"roles:\" field enabled with\n``--fields=+r`` is for recording the module is \"imported\" to the tag file.\n\n\"input.py\"\n\n.. code-block:: Python\n\n\timport X1 as Y1\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzK --fields-Python=+{nameref} input.py\"\n\n.. code-block:: tags\n\n\tX1\tinput.py\t/^import X1 as Y1$/;\"\tkind:module\troles:indirectlyImported\n\tY1\tinput.py\t/^import X1 as Y1$/;\"\tkind:namespace\troles:def\tnameref:module:X1\n\n\"Y1\" introduces a new name and is defined here. So \"Y1\" is tagged as a\ndefinition tag.  \"X1\" is imported in a way that its name cannot be used\nin this source file. For letting client tools know that the name cannot be used,\n``indirectlyImported`` role is assigned for \"X1\".  \"Y1\" is the name for\naccessing objects defined in the module imported via \"X1\".  For recording this\nrelationship, ``nameref:`` field is attached to the tag of \"Y1\".  Instead of\n``module`` kind, ``namespace`` kind is assigned to \"Y1\" because \"Y1\" itself\nisn't a module.\n\n\"input.py\"\n\n.. code-block:: Python\n\n\tfrom X2 import *\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzK input.py\"\n\n.. code-block:: tags\n\n\tX2\tinput.py\t/^from X2 import *$/;\"\tkind:module\troles:namespace\n\nThe module is not defined here; it is defined in another file. So the tag for\nthe imported module is a reference tag. Unlike \"X0\" in \"import X0\", \"X2\" may not\nbe used because the names defined in \"X2\" can be used in this source file. To represent\nthe difference ``namespace`` role is attached to \"X2\" instead of ``imported``.\n\n\"input.py\"\n\n.. code-block:: Python\n\n\tfrom X3 import Y3\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzKZ input.py\"\n\n.. code-block:: tags\n\n\tX3\tinput.py\t/^from X3 import Y3$/;\"\tkind:module\troles:namespace\n\tY3\tinput.py\t/^from X3 import Y3$/;\"\tkind:unknown\tscope:module:X3\troles:imported\n\n\"Y3\" is a name for a language object defined in \"X3\" module. \"scope:module:X3\"\nattached to \"Y3\" represents this relation between \"Y3\" and \"X3\". ctags\nassigns ``unknown`` kind to \"Y3\" because ctags cannot know whether \"Y3\" is a\nclass, a variable, or a function from the input file.\n\n\"input.py\"\n\n.. code-block:: Python\n\n\tfrom X4 import Y4 as Z4\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzKZ input.py\"\n\n.. code-block:: tags\n\n\tX4\tinput.py\t/^from X4 import Y4 as Z4$/;\"\tkind:module\troles:namespace\n\tY4\tinput.py\t/^from X4 import Y4 as Z4$/;\"\tkind:unknown\tscope:module:X4\troles:indirectlyImported\n\tZ4\tinput.py\t/^from X4 import Y4 as Z4$/;\"\tkind:unknown\troles:def\tnameref:unknown:Y4\n\n\"Y4\" is similar to \"Y3\" of \"from X3 import Y3\" but the name cannot be used here.\n``indirectlyImported`` role assigned to \"Y4\" representing this. \"Z4\" is the name for\naccessing the language object named in \"Y4\" in \"X4\" module. \"nameref:unknown:Y4\"\nattached to \"Z4\" and \"scope:module:X4\" attached to \"Y4\" represent the relations.\n\nLAMBDA EXPRESSION AND TYPE HINT\n-------------------------------\n\nSummary\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n`id = lambda var0: var0`\n\n\t=========== ========== ================== ===================\n\tname        kind       role               other noticeable fields\n\t=========== ========== ================== ===================\n\t`id`        function   definition         signature:(`var0`)\n\t=========== ========== ================== ===================\n\n`id_t: Callable[[int], int] = lambda var1: var1`\n\n\t=========== ========== ================== ===================\n\tname        kind       role               other noticeable fields\n\t=========== ========== ================== ===================\n\t`id_t`      variable   definition         typeref:typename:`Callable[[int], int]` nameref:function:anonFuncN\n\tanonFuncN   function   definition         signature:(`var1`)\n\t=========== ========== ================== ===================\n\nExamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\"input.py\"\n\n.. code-block:: Python\n\n\tfrom typing import Callable\n\tid = lambda var0: var0\n\tid_t: Callable[[int], int] = lambda var1: var1\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --fields=+KS --fields-Python=+{nameref} --extras=+{anonymous} input.py\"\n\n.. code-block:: tags\n\n\tid\tinput.py\t/^id = lambda var0: var0$/;\"\tfunction\tsignature:(var0)\n\tid_t\tinput.py\t/^id_t: Callable[[int], int] = lambda var1: var1$/;\"\\\n\t\tvariable\ttyperef:typename:Callable[[int], int]\tnameref:function:anonFunc84011d2c0101\n\tanonFunc84011d2c0101\tinput.py\t/^id_t: Callable[[int], int] = lambda var1: var1$/;\"\\\n\t\tfunction\tsignature:(var1)\n\nIf a variable (\"id\") with no type hint is initialized with a lambda expression,\nctags assigns ``function`` kind for the tag of \"id\".\n\nIf a variable (\"id_t\") with a type hint is initialized with a lambda expression,\nctags assigns ``variable`` kind for the tag of \"id_t\" with ``typeref:`` and\n``nameref:`` fields. ctags fills ``typeref:`` field with the value of the type\nhint. The way of filling ``nameref:`` is a bit complicated.\n\nFor the lambda expression used in initializing the type-hint'ed variable, ctags\ncreates ``anonymous`` extra tag (\"anonFunc84011d2c0101\"). ctags fills the\n``nameref:`` field of \"id_t\" with the name of ``anonymous`` extra tag:\n\"nameref:function:anonFunc84011d2c0101\".\n\nYou may think why ctags does so complicated, and why ctags doesn't emit\nfollowing tags output for the input::\n\n\tid\tinput.py\t/^id = \\\\$/;\"\tfunction\tsignature:(var0)\n\tid_t\tinput.py\t/^id_t: \\\\$/;\"\tfunction\ttyperef:typename:Callable[[int], int]\tsignature:(var1)\n\nThere is a reason. The other languages of ctags obey the following rule: ctags fills\n``typeref:`` field for a tag of a callable object (like function) with the type\nof its return value. If we consider \"id_t\" is a function, its ``typeref:`` field\nshould have \"typename:int\". However, for filling ``typeref:`` with \"typename:int\",\nctags has to analyze \"Callable[[int], int]\" deeper. We don't want to do so.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New role ``entryPoint`` for ``module`` kind\n\n  PythonEntryPoints parser emits tag entries having this role.\n\n* New role ``entryPoint`` for  ``function`` kind\n\n  PythonEntryPoints parser emits tag entries having this role.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`, :ref:`ctags-lang-iPythonCell(7) <ctags-lang-iPythonCell(7)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-r.7.rst",
    "content": ".. _ctags-lang-r(7):\n\n==============================================================\nctags-lang-r\n==============================================================\n\nRandom notes about tagging R source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+R ...\n|\t**ctags** ... --language-force=R ...\n|\t**ctags** ... --map-R=+.r ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging R source code\nwith Universal Ctags.\n\nKinds\n-----------\nIf a variable gets a value returned from a *well-known constructor*\nand the variable appears for the first time in the current input file,\nthe R parser makes a tag for the variable and attaches a kind\nassociated with the constructor to the tag regardless of whether\nthe variable appears in the top-level context or a function.\n\nWell-known constructor and kind mapping\n\n\t============  ==================\n\tConstructor   kind\n\t============  ==================\n\tfunction()    function\n\tc()           vector\n\tlist()        list\n\tdata.frame()  dataframe\n\t============  ==================\n\nIf a variable doesn't get a value returned from one of well-known\nconstructors, the R parser attaches ``globalVar`` or ``functionVar`` kind\nto the tag for the variable depending on the context.\n\nHere is an example demonstrating the usage of the kinds:\n\n\"input.r\"\n\n.. code-block:: R\n\n\tG <- 1\n\tv <- c(1, 2)\n\tl <- list(3, 4)\n\td <- data.frame(n = v)\n\tf <- function(a) {\n\t\tg <- function (b) a + b\n\t\tw <- c(1, 2)\n\t\tm <- list (3, 4)\n\t\te <- data.frame(n = w)\n\t\tL <- 2\n\t}\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --fields=+KZ -o - input.r\"\n\n.. code-block:: tags\n\n\tG\tinput.r\t/^G <- 1$/;\"\tglobalVar\n\tv\tinput.r\t/^v <- c(1, 2)$/;\"\tvector\n\tl\tinput.r\t/^l <- list(3, 4)$/;\"\tlist\n\td\tinput.r\t/^d <- data.frame(n = v)$/;\"\tdataframe\n\tn\tinput.r\t/^d <- data.frame(n = v)$/;\"\tnameattr\tscope:dataframe:d\n\tf\tinput.r\t/^f <- function(a) {$/;\"\tfunction\n\tg\tinput.r\t/^\tg <- function (b) a + b$/;\"\tfunction\tscope:function:f\n\tw\tinput.r\t/^\tw <- c(1, 2)$/;\"\tvector\tscope:function:f\n\tm\tinput.r\t/^\tm <- list (3, 4)$/;\"\tlist\tscope:function:f\n\te\tinput.r\t/^\te <- data.frame(n = w)$/;\"\tdataframe\tscope:function:f\n\tn\tinput.r\t/^\te <- data.frame(n = w)$/;\"\tnameattr\tscope:dataframe:f.e\n\tL\tinput.r\t/^\tL <- 2$/;\"\tfunctionVar\tscope:function:f\n\n.. TODO:\n\n   - other kinds\n   - operators for assignment, <-, <<-, ->>, ->, =\n   - illuminating duplicated tags\n   - fields (constructor, assignmentop)\n   - sub parsers\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-rmarkdown.7.rst",
    "content": ".. _ctags_lang-rmarkdown(7):\n\n======================================================================\nctags-lang-rmarkdown\n======================================================================\n\nRandom notes about tagging R Markdown source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ...--extras=+{subparser}{guest} --languages=+RMarkdown ...\n|\t**ctags** ...--extras=+{subparser}{guest} --language-force=RMarkdown ...\n|\t**ctags** ...--extras=+{subparser}{guest} --map-RMarkdown=+.rmd ...\n\nDESCRIPTION\n-----------\nRMarkdown parser is an exclusive subparser stacked on top of the Markdown parser.\nIt works when:\n\n* the Markdown parser is enabled,\n* the ``subparser`` extra is enabled, and\n* the RMarkdown parser itself is enabled.\n\nThe RMarkdown parser extends the way of detecting **codeblocks** from the\nMarkdown parser. This extension is for running guest parsers on **code chunks**.\n\nThe Markdown parser expects the following syntax represents codeblocks:\n\n.. code-block::\n\n\t```language-name\n\t\t...\n\t```\n\nFor an example\n\n.. code-block::\n\n\t```r\n\t\t...\n\t```\n\nThe RMarkdown parser accepts the following syntax for code chunks:\n\n.. code-block::\n\n\t```{language-name chunk-label, ...}\n\t\t...\n\t```\n\nFor an example\n\n.. code-block::\n\n\t```{r precalc fig.height=4}\n\t\t...\n\t```\n\nGive `--extras=+{guest}` for enabling ``guest`` to command line if you\nwant to run proper parsers on lines inside code chunks.\n\nThe parser extracts chunk labels coming after `language-name` as\n`chunklabel` kind objects. In the example, the RMarkdown parser\nextracts `precalc` as a `chunklabel` kind object.\nThe `chunklabel` kind is enabled by default.\n\nEXAMPLES\n--------\n\"input.rmd\"\n\n.. code-block:: RMarkdown\n\n\t# Section 1\n\n\t```{r myblock}\n\t\tzero_fun <- function () {\n\t\t\treturn 0\n\t\t}\n\t```\n\n\t# Section 2\n\n\"output.tags\"\nwith \"--options=NONE --extras=+{guest} --fields=+KZln -o - input.rmd\"\n\n.. code-block:: tags\n\n\tSection 1\tinput.rmd\t/^# Section 1$/;\"\tchapter\tline:1\tlanguage:Markdown\n\tSection 2\tinput.rmd\t/^# Section 2$/;\"\tchapter\tline:9\tlanguage:Markdown\n\tmyblock\tinput.rmd\t/^```{r myblock}$/;\"\tchunklabel\tline:3\tlanguage:RMarkdown\n\tzero_fun\tinput.rmd\t/^\tzero_fun <- function () {$/;\"\tfunction\tline:4\tlanguage:R\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`, :ref:`ctags-lang-r(7) <ctags-lang-r(7)>`,\n`R Markdown: The Definitive Guide <https://bookdown.org/yihui/rmarkdown/>`_\n"
  },
  {
    "path": "docs/man/ctags-lang-scheme.7.rst",
    "content": ".. _ctags-lang-scheme(7):\n\n==============================================================\nctags-lang-scheme\n==============================================================\n\nRandom notes about tagging Scheme source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Scheme ...\n|\t**ctags** ... --language-force=Scheme ...\n|\t**ctags** ... --map-Scheme=+.SCM ...\n|\t**ctags** ... --map-Scheme=+.SM ...\n|\t**ctags** ... --map-Scheme=+.sch ...\n|\t**ctags** ... --map-Scheme=+.scheme ...\n|\t**ctags** ... --map-Scheme=+.scm ...\n|\t**ctags** ... --map-Scheme=+.sm ...\n|\t**ctags** ... --map-Scheme=+.rkt ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Scheme source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* Add ``unknown`` kind.\n\n* Add ``definer`` field.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-scss.7.rst",
    "content": ".. _ctags-lang-scss(7):\n\n==============================================================\nctags-lang-scss\n==============================================================\n\nRandom notes about tagging SCSS source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+SCSS ...\n|\t**ctags** ... --language-force=SCSS ...\n|\t**ctags** ... --map-Scss=+.scss ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging SCSS input.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``module`` and new role ``used`` of the ``module`` kind\n* New kind ``namespace``\n* New field ``module``\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-sql.7.rst",
    "content": ".. _ctags-lang-sql(7):\n\n==============================================================\nctags-lang-sql\n==============================================================\n\nThe man page of the SQL parser for Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... [--extras={guest}] --languages=+SQL ...\n\n\nDESCRIPTION\n-----------\nThe SQL parser supports various SQL dialects. PostgreSQL is one of them.\n\nPostgreSQL allows user-defined functions to be written in other\nlanguages (*procedural languages*) besides SQL and C [PL]_.\n\nThe SQL parser makes tags for language objects in the user-defined\nfunctions written in the procedural languages if the ``guest`` extra\nis enabled.\n\nThe SQL parser looks for a token coming after ``LANGUAGE`` keyword in\nthe source code to choose a proper guest parser.\n\n.. code-block:: psql\n\n   ... LANGUAGE plpythonu AS '... user-defined function ' ...\n   ... AS $$ user-defined function $$ LANGUAGE plv8 ...\n\nIn the above examples, ``plpythonu`` and ``plv8`` are the names of\nprocedural languages. The SQL parser trims `pl` at the start and `u`\nat the end of the name before finding a ctags parser.  For\n``plpythonu`` and ``plv8``, the SQL parser extracts ``python`` and\n``v8`` as the candidates of guest parsers.\n\nFor ``plpythonu``, ctags can run its Python parser.  ctags doesn't\nhave a parser named ``v8``. However, the JavaScript parser in ctags has\n``v8`` as an alias. So ctags can run the JavaScript parser as the\nguest parser for ``plv8``.\n\nEXAMPLES\n--------\ntagging code including a user-defined function in a string literal [GH3006]_:\n\n\"input.sql\"\n\n.. code-block:: psql\n\n\tCREATE OR REPLACE FUNCTION fun1() RETURNS VARCHAR AS '\n\tDECLARE\n\t\ttest1_var1 VARCHAR(64) := $$ABC$$;\n\t\ttest1_var2 VARCHAR(64) := $xyz$XYZ$xyz$;\n\t\ttest1_var3     INTEGER := 1;\n\tBEGIN\n\t\tRETURN  TO_CHAR(test_var3, ''000'') || test1_var1 || test1_var2;\n\tEND;\n\t' LANGUAGE plpgsql;\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+{guest} input.sql\"\n\n.. code-block:: tags\n\n\tfun1\tinput.sql\t/^CREATE OR REPLACE FUNCTION fun1() RETURNS VARCHAR AS '$/;\"\tf\ttyperef:typename:VARCHAR\n\ttest1_var1\tinput.sql\t/^\ttest1_var1 VARCHAR(64) := $$ABC$$;$/;\"\tv\n\ttest1_var2\tinput.sql\t/^\ttest1_var2 VARCHAR(64) := $xyz$XYZ$xyz$;$/;\"\tv\n\ttest1_var3\tinput.sql\t/^\ttest1_var3     INTEGER := 1;$/;\"\tv\n\ntagging code including a user-defined function in a dollar quote [GH3006]_:\n\n\"input.sql\"\n\n.. code-block:: psql\n\n\tCREATE OR REPLACE FUNCTION fun2() RETURNS VARCHAR LANGUAGE plpgsql AS $$\n\tDECLARE\n\t\ttest2_var1 VARCHAR(64) := 'ABC2';\n\t\ttest2_var2 VARCHAR(64) := 'XYZ2';\n\t\ttest2_var3        INTEGER := 2;\n\tBEGIN\n\t\tRETURN  TO_CHAR(test2_var3, '000') || test2_var1 || test2_var2;\n\tEND;\n\t$$;\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+{guest} input.sql\"\n\n.. code-block:: tags\n\n\tfun2\tinput.sql\t/^CREATE OR REPLACE FUNCTION fun2() RETURNS VARCHAR LANGUAGE plpgsql AS $\\$$/;\"\tf\ttyperef:typename:VARCHAR\n\ttest2_var1\tinput.sql\t/^\ttest2_var1 VARCHAR(64) := 'ABC2';$/;\"\tv\n\ttest2_var2\tinput.sql\t/^\ttest2_var2 VARCHAR(64) := 'XYZ2';$/;\"\tv\n\ttest2_var3\tinput.sql\t/^\ttest2_var3        INTEGER := 2;$/;\"\tv\n\ntagging code including a user-defined written in JavaScript:\n\n.. code-block:: psql\n\n\t-- Derived from https://github.com/plv8/plv8/blob/r3.0alpha/sql/plv8.sql\n\tCREATE FUNCTION test(keys text[], vals text[]) RETURNS text AS\n\t$$\n\t\tvar o = {};\n\t\tfor (var i = 0; i < keys.length; i++)\n\t\t\to[keys[i]] = vals[i];\n\t\treturn JSON.stringify(o);\n\t$$\n\tLANGUAGE plv8 IMMUTABLE STRICT;\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+{guest} input.sql\"\n\n.. code-block:: tags\n\n\ttest\tinput.sql\t/^CREATE FUNCTION test(keys text[], vals text[]) RETURNS text AS$/;\"\tf\n\to\tinput.sql\t/^\tvar o = {};$/;\"\tv\n\nKNOWN BUGS\n----------\nEscape sequences (`''`) in a string literal may make a guest parser confused.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`\n\nREFERENCES\n----------\n\n.. [PL] PostgreSQL 9.5.25 Documentation, \"Chapter 39. Procedural Languages\", https://www.postgresql.org/docs/9.5/xplang.html\n\n.. [GH3006] @bagl's comment submitted to https://github.com/universal-ctags/ctags/issues/3006\n"
  },
  {
    "path": "docs/man/ctags-lang-systemtap.7.rst",
    "content": ".. _ctags-lang-systemtap(7):\n\n==============================================================\nctags-lang-systemtap\n==============================================================\n\nRandom notes about tagging SystemTap source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+SystemTap ...\n|\t**ctags** ... --language-force=SystemTap ...\n|\t**ctags** ... --map-SystemTap=+.stp ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging SystemTap scripts.\n\nGuests\n~~~~~~~~~~~\nThe SystemTap parser runs CPreProcessor as a guest parser on the areas\nsurrounded by `%{` and `%}`.\n\n\"input.stp\"\n\n.. code-block:: SystemTap\n\n\t%{\n\t#define X 1\n\t%}\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+{guest} input.stp\"\n\n.. code-block:: tags\n\n\tX\tinput.stp\t/^#define X /;\"\td\tfile:\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New role ``attached`` for ``probe`` kind\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, `SystemTap Language Reference <https://sourceware.org/systemtap/langref>`_ (https://sourceware.org/systemtap/langref/)\n"
  },
  {
    "path": "docs/man/ctags-lang-tcl.7.rst",
    "content": ".. _ctags-lang-tcl(7):\n\n==============================================================\nctags-lang-tcl\n==============================================================\n\nRandom notes about tagging tcl source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Tcl ...\n|\t**ctags** ... --language-force=Tcl ...\n|\t**ctags** ... --map-Tcl=+.tcl ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging tcl source code.\n\nTAGGING language objects of OO Extensions\n-----------------------------------------\n\nTclOO parser and ITcl parser are subparsers running on the Tcl parser.\nAs the names of parsers show, they are for tagging language objects of\nobject oriented programming extensions for the Tcl language.\n\nA pattern, \"namespace import oo\" in an input file activates the TclOO\nparser. A pattern, \"namespace import itcl\" in an input file activates\nthe ITcl parser.\n\nThere are cases that one of the OO extensions is used though neither\npattern are appeared in an input file.\n\nConsider the following input files:\n\n\"main.tcl\"\n\n.. code-block:: Tcl\n\n\tpackage require Itcl\n\tnamespace import itcl::*\n\tsource input.tcl\n\n\"input.tcl\"\n\n.. code-block:: Tcl\n\n\tclass MyClass {\n\t\tpublic method foo {} {\n\t\t}\n\t}\n\nThe pattern for activating the ITcl parser is not appeared\nin \"input.tcl\" though \"class\" command is used. As a result,\nctags cannot extract \"MyClass\".\n\nThe parameters `TclOO.forceUse=true|[false]` and\n`ITcl.forceuse=true|[false]` for handling this situation. With the\nparameter, you can force ctags to activate one of the subparsers.\n\nYou can use the parameters like ``--param-ITcl.forceuse=true``\nin a command-line.\n\nNote that you can enable only one of ITcl parser or TclOO parser.\nEnabling both parsers with specifying the parameters can cause\nunexpected results.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-lang-terraform.7.rst",
    "content": ".. _ctags-lang-terraform(7):\n\n==============================================================\nctags-lang-terraform\n==============================================================\n\nRandom notes about tagging Terraform files with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Terraform ...\n|\t**ctags** ... --language-force=Terraform ...\n|\t**ctags** ... --map-Terraform=+.tf ...\n|\n|\t**ctags** ... --extras=+{reference} --languages=+TerraformVariables ...\n|\t**ctags** ... --extras=+{reference} --language-force=TerraformVariables ...\n|\t**ctags** ... --extras=+{reference} --map-Terraform=+.tfvars ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Terraform files.\n\nTIPS\n-----------\n\nExtracting variables assigned in Variable definitions\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSpecify ``--extras=+{reference}`` and ``--languages=+TerraformVariables``\nto extract variables assigned in variables definitions (`*.tfvars`).\nThe TerraformVariables parser extracts variables in `*.tfvars` files\nwith ``variable`` kind with ``assigned`` role of ``Terraform`` language.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``local``\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`,\n`Configuration Syntax <https://developer.hashicorp.com/terraform/language/syntax/configuration>`_ (https://developer.hashicorp.com/terraform/language/syntax/configuration),\n`Variable Definitions (.tfvars) Files <https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files>`_ (https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files)\n"
  },
  {
    "path": "docs/man/ctags-lang-verilog.7.rst",
    "content": ".. _ctags_lang-verilog(7):\n\n======================================================================\nctags-lang-verilog\n======================================================================\n\nThe man page about SystemVerilog/Verilog parser for Universal Ctags\n\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... [--kinds-systemverilog=+Q] [--fields-SystemVerilog=+{parameter}] ...\n|\t**ctags** ... [--fields-Verilog=+{parameter}] ...\n\n    +---------------+---------------+-------------------+\n    | Language      | Language ID   | File Mapping      |\n    +===============+===============+===================+\n    | SystemVerilog | SystemVerilog | .sv, .svh, svi    |\n    +---------------+---------------+-------------------+\n    | Verilog       | Verilog       | .v, .vh           |\n    +---------------+---------------+-------------------+\n\nDESCRIPTION\n-----------\nThis man page describes about the SystemVerilog/Verilog parser for Universal Ctags.\nSystemVerilog parser supports IEEE Std 1800-2017 keywords.\nVerilog parser supports IEEE Std 1364-2005 keywords.\n\nSupported Kinds\n~~~~~~~~~~~~~~~\n\n.. code-block:: console\n\n\t$ ctags --list-kinds-full=SystemVerilog\n\t#LETTER NAME       ENABLED REFONLY NROLES MASTER DESCRIPTION\n\tA       assert     yes     no      0      NONE   assertions (assert, assume, cover, restrict)\n\tC       class      yes     no      0      NONE   classes\n\tE       enum       yes     no      0      NONE   enumerators\n\tH       checker    yes     no      0      NONE   checkers\n\tI       interface  yes     no      0      NONE   interfaces\n\tK       package    yes     no      0      NONE   packages\n\tL       clocking   yes     no      0      NONE   clocking\n\tM       modport    yes     no      0      NONE   modports\n\tN       nettype    yes     no      0      NONE   nettype declarations\n\tO       constraint yes     no      0      NONE   constraints\n\tP       program    yes     no      0      NONE   programs\n\tQ       prototype  no      no      0      NONE   prototypes (extern, pure)\n\tR       property   yes     no      0      NONE   properties\n\tS       struct     yes     no      0      NONE   structs and unions\n\tT       typedef    yes     no      0      NONE   type declarations\n\tV       covergroup yes     no      0      NONE   covergroups\n\tb       block      yes     no      0      NONE   blocks (begin, fork)\n\tc       constant   yes     no      0      NONE   constants (parameter, specparam, enum values)\n\td       define     yes     no      0      NONE   text macros\n\te       event      yes     no      0      NONE   events\n\tf       function   yes     no      0      NONE   functions\n\ti       instance   yes     no      0      NONE   instances of module or interface\n\tl       ifclass    yes     no      0      NONE   interface class\n\tm       module     yes     no      0      NONE   modules\n\tn       net        yes     no      0      NONE   net data types\n\tp       port       yes     no      0      NONE   ports\n\tq       sequence   yes     no      0      NONE   sequences\n\tr       register   yes     no      0      NONE   variable data types\n\tt       task       yes     no      0      NONE   tasks\n\tw       member     yes     no      0      NONE   struct and union members\n\nNote that ``prototype`` (``Q``) is disabled by default.\n\n.. code-block:: console\n\n\t$ ctags --list-kinds-full=Verilog\n\t#LETTER NAME     ENABLED REFONLY NROLES MASTER DESCRIPTION\n\tb       block    yes     no      0      NONE   blocks (begin, fork)\n\tc       constant yes     no      0      NONE   constants (parameter, specparam)\n\td       define   yes     no      0      NONE   text macros\n\te       event    yes     no      0      NONE   events\n\tf       function yes     no      0      NONE   functions\n\ti       instance yes     no      0      NONE   instances of module\n\tm       module   yes     no      0      NONE   modules\n\tn       net      yes     no      0      NONE   net data types\n\tp       port     yes     no      0      NONE   ports\n\tr       register yes     no      0      NONE   variable data types\n\tt       task     yes     no      0      NONE   tasks\n\nSupported Language Specific Fields\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block:: console\n\n\t$ ctags --list-fields=Verilog\n\t#LETTER NAME      ENABLED LANGUAGE JSTYPE FIXED DESCRIPTION\n\t-       parameter no      Verilog  --b    no    parameter whose value can be overridden.\n\t$ ctags --list-fields=SystemVerilog\n\t#LETTER NAME      ENABLED LANGUAGE      JSTYPE FIXED DESCRIPTION\n\t-       parameter no      SystemVerilog --b    no    parameter whose value can be overridden.\n\n``parameter`` field\n....................\n\nIf the field ``parameter`` is enabled, a field ``parameter:`` is added on a parameter whose\nvalue can be overridden on an instantiated module, interface, or program.\nThis is useful for a editor plugin or extension to enable auto-instantiation of modules with\nparameters which can be overridden.\n\n.. code-block:: console\n\n    $ ctags ... --fields-Verilog=+{parameter} ...\n    $ ctags ... --fields-SystemVerilog=+{parameter} ...\n\nOn the following source code fields ``parameter:`` are added on\nparameters ``P*``, not on ones ``L*``.  Note that ``L4`` and ``L6`` is declared by\n``parameter`` statement, but fields ``parameter:`` are not added,\nbecause they cannot be overridden.\n\n\"input.sv\"\n\n.. code-block:: systemverilog\n\n\t// compilation unit scope\n\tparameter L1 = \"synonym for the localparam\";\n\n\tmodule with_parameter_port_list #(\n\t\tP1,\n\t\tlocalparam L2 = P1+1,\n\t\tparameter P2)\n\t\t( /*port list...*/ );\n\t\tparameter  L3 = \"synonym for the localparam\";\n\t\tlocalparam L4 = \"localparam\";\n\t\t// ...\n\tendmodule\n\n\tmodule with_empty_parameter_port_list #()\n\t\t( /*port list...*/ );\n\t\tparameter  L5 = \"synonym for the localparam\";\n\t\tlocalparam L6 = \"localparam\";\n\t\t// ...\n\tendmodule\n\n\tmodule no_parameter_port_list\n\t\t( /*port list...*/ );\n\t\tparameter  P3 = \"parameter\";\n\t\tlocalparam L7 = \"localparam\";\n\t\t// ...\n\tendmodule\n\n.. code-block:: console\n\n\t$ ctags -uo - --fields-SystemVerilog=+{parameter} input.sv\n\tL1\tinput.sv\t/^parameter L1 = \"synonym for the localparam\";$/;\"\tc\tparameter:\n\twith_parameter_port_list\tinput.sv\t/^module with_parameter_port_list #($/;\"\tm\n\tP1\tinput.sv\t/^\tP1,$/;\"\tc\tmodule:with_parameter_port_list\tparameter:\n\tL2\tinput.sv\t/^\tlocalparam L2 = P1+1,$/;\"\tc\tmodule:with_parameter_port_list\n\tP2\tinput.sv\t/^\tparameter P2)$/;\"\tc\tmodule:with_parameter_port_list\tparameter:\n\tL3\tinput.sv\t/^\tparameter  L3 = \"synonym for the localparam\";$/;\"\tc\tmodule:with_parameter_port_list\n\tL4\tinput.sv\t/^\tlocalparam L4 = \"localparam\";$/;\"\tc\tmodule:with_parameter_port_list\n\twith_empty_parameter_port_list\tinput.sv\t/^module with_empty_parameter_port_list #()$/;\"\tm\n\tL5\tinput.sv\t/^\tparameter  L5 = \"synonym for the localparam\";$/;\"\tc\tmodule:with_empty_parameter_port_list\n\tL6\tinput.sv\t/^\tlocalparam L6 = \"localparam\";$/;\"\tc\tmodule:with_empty_parameter_port_list\n\tno_parameter_port_list\tinput.sv\t/^module no_parameter_port_list$/;\"\tm\n\tP3\tinput.sv\t/^\tparameter  P3 = \"parameter\";$/;\"\tc\tmodule:no_parameter_port_list\tparameter:\n\tL7\tinput.sv\t/^\tlocalparam L7 = \"localparam\";$/;\"\tc\tmodule:no_parameter_port_list\n\nSupported Roles\n~~~~~~~~~~~~~~~\n\n.. code-block:: console\n\n\t$ ./ctags --list-roles=SystemVerilog\n\t#KIND(L/N) NAME ENABLED DESCRIPTION\n\tm/module   decl on      declaring instances\n\n\t$ ./ctags --list-roles=Verilog\n\t#KIND(L/N) NAME ENABLED DESCRIPTION\n\tm/module   decl on      declaring instances\n\nThe parser extracts names of modules used in instance declarations as\nreference tags. ``decl`` is the role for the tags. See \"TAG ENTRIES\"\nsection of :ref:`ctags(1) <ctags(1)>` about reference tags and roles.\n\n.. warning::\n\n   The support for references in Universal Ctags is still\n   experimental; the names of the roles may be changed in the future.\n\nTIPS\n~~~~\n\nIf you want to map files ``*.v`` to SystemVerilog, add\n``--map-SystemVerilog=+.v`` option.\n\nKNOWN ISSUES\n---------------------------------------------------------------------\n\nSee https://github.com/universal-ctags/ctags/issues/2674 for more information.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``define``\n* map ``.vh`` to Verilog\n\nSEE ALSO\n--------\n\n- :ref:`ctags(1) <ctags(1)>`\n- :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`\n- Language Reference Manuals (LRM)\n\n   - IEEE Standard for SystemVerilog — Unified Hardware Design, Specification, and\n     Verification Language, IEEE Std 1800-2017,\n     https://ieeexplore.ieee.org/document/8299595\n   - IEEE Standard for Verilog Hardware Description Language, IEEE Std 1364-2005,\n     https://ieeexplore.ieee.org/document/1620780\n"
  },
  {
    "path": "docs/man/ctags-lang-vim.7.rst",
    "content": ".. _ctags-lang-vim(7):\n\n==============================================================\nctags-lang-vim\n==============================================================\n\nRandom notes about tagging Vim source code with Universal Ctags\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** ... --languages=+Vim ...\n|\t**ctags** ... --language-force=Vim ...\n|\t**ctags** ... --map-Vim=+.vim ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging VIM source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kinds ``heredoc`` and ``class``\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`\n"
  },
  {
    "path": "docs/man/ctags-optlib.7.rst",
    "content": ".. _ctags-optlib(7):\n\n==============================================================\nctags-optlib\n==============================================================\n\nUniversal Ctags parser definition language\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**ctags** [options] [file(s)]\n|\t**etags** [options] [file(s)]\n\nDESCRIPTION\n-----------\n\n*Exuberant Ctags*, the ancestor of *Universal Ctags*, has provided\nthe way to define a new parser from command line.  Universal Ctags\nextends and refines this feature. *optlib parser* is the name for such\nparser in Universal Ctags. \"opt\" intends a parser is defined with\ncombination of command line options. \"lib\" intends an optlib parser\ncan be more than ad-hoc personal configuration.\n\nThis man page is for people who want to define an optlib parser. The\nreaders should read :ref:`ctags(1) <ctags(1)>` of Universal Ctags first.\n\nFollowing options are for defining (or customizing) a parser:\n\n* ``--langdef=<name>``\n* ``--map-<LANG>=[+|-]<extension>|<pattern>|<rexpr>``\n* ``--kinddef-<LANG>=<letter>,<name>,<description>``\n* ``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``\n* ``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``\n\nFollowing options are for controlling loading parser definition:\n\n* ``--options=<pathname>``\n* ``--options-maybe=<pathname>``\n* ``--optlib-dir=[+]<directory>``\n\nThe design of options and notations for defining a parser in\nExuberant Ctags may focus on reducing the number of typing by user.\nReducing the number of typing is important for users who want to\ndefine (or customize) a parser quickly.\n\nOn the other hand, the design in Universal Ctags focuses on\nmaintainability. The notation of Universal Ctags is redundant than\nthat of Exuberant Ctags; the newly introduced kind should be declared\nexplicitly, (long) names are approved than one-letter flags\nspecifying kinds, and naming rules are stricter.\n\nThis man page explains only stable options and flags.  Universal Ctags\nalso introduces experimental options and flags which have names starting\nwith ``_``. For documentation on these options and flags, visit\nUniversal Ctags web site at https://ctags.io/.\n\n\nStoring a parser definition to a file\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThough it is possible to define a parser from command line, you don't\nwant to type the same command line each time when you need the parser.\nYou can store options for defining a parser into a file.\n\nctags loads files (preload files) listed in \"FILES\"\nsection of :ref:`ctags(1) <ctags(1)>` at program starting up. You can put your parser\ndefinition needed usually to the files.\n\n``--options=<pathname>``, ``--options-maybe=<pathname>``, and\n``--optlib-dir=[+]<directory>`` are for loading optlib files you need\noccasionally. See \"Option File Options\" section of :ref:`ctags(1) <ctags(1)>` for\nthese options.\n\nAs explained in \"FILES\" section of :ref:`ctags(1) <ctags(1)>`, options for defining a\nparser listed line by line in an optlib file. Prefixed white spaces are\nignored. A line starting with '#' is treated as a comment.  Escaping\nshell meta character is not needed.\n\nUse ``.ctags`` as file extension for optlib file. You can define\nmultiple parsers in an optlib file but it is better to make a file for\neach parser definition.\n\n``--_echo=<msg>`` and ``--_force-quit=<num>`` options are for debugging\noptlib parser.\n\n\nOverview for defining a parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n1. Design the parser\n\n   You need know both the target language and the ctags'\n   concepts (definition, reference, kind, role, field, extra). About\n   the concepts, :ref:`ctags(1) <ctags(1)>` of Universal Ctags may help you.\n\n2. Give a name to the parser\n\n   Use ``--langdef=<name>`` option. *<name>* is referred as *<LANG>* in\n   the later steps.\n\n3. Give a file pattern or file extension for activating the parser\n\n   Use ``--map-<LANG>=[+|-]<extension>|<pattern>|<rexpr>``.\n\n4. Define kinds\n\n   Use ``--kinddef-<LANG>=<letter>,<name>,<description>`` option.\n   Universal Ctags introduces this option.  Exuberant Ctags doesn't\n   have. In Exuberant Ctags, a kind is defined as a side effect of\n   specifying ``--regex-<LANG>=`` option. So user doesn't have a\n   chance to recognize how important the definition of kind.\n\n5. Define patterns\n\n   Use ``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``\n   option for a single-line regular expression. You can also use\n   ``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``\n   option for a multi-line regular expression.\n\n   As *<kind-spec>*, you can use the one-letter flag defined with\n   ``--kinddef-<LANG>=<letter>,<name>,<description>`` option.\n\nOPTIONS\n------------\n\n``--langdef=<name>``\n\tDefines a new user-defined language, *<name>*, to be parsed with regular\n\texpressions. Once defined, *<name>* may be used in other options taking\n\tlanguage names.\n\n\t*<name>* must consist of alphanumeric characters, '``#``', or '``+``'\n\t('[a-zA-Z0-9#+]+'). The graph characters other than '``#``' and\n\t'``+``' are disallowed (or reserved). Some of them (``[-=:{.]``) are\n\tdisallowed because they can make the command line parser of\n\tctags confused. The rest of them are just\n\treserved for future extending ctags.\n\n\t``all`` is an exception.  ``all`` as *<name>* is not acceptable. It is\n\ta reserved word. See the description of\n\t``--kinds-(<LANG>|all)=[+|-](<kinds>|*)`` option in :ref:`ctags(1) <ctags(1)>` about how the\n\treserved word is used.\n\n\t``NONE`` is another exception. ``NONE`` as *<name>* is not acceptable.\n\n\tThe names of built-in parsers are capitalized. When\n\tctags evaluates an option in a command line, and\n\tchooses a parser, ctags uses the names of\n\tparsers in a case-insensitive way. Therefore, giving a name\n\tstarted from a lowercase character doesn't help you to avoid the\n\tparser name confliction. However, in a tags file,\n\tctags prints parser names in a case-sensitive\n\tway; it prints a parser name as specified in ``--langdef=<name>``\n\toption.  Therefore, we recommend you to give a name started from a\n\tlowercase character to your private optlib parser. With this\n\tconvention, people can know where a tag entry in a tag file comes\n\tfrom a built-in parser or a private optlib parser.\n\n``--kinddef-<LANG>=<letter>,<name>,<description>``\n\tDefine a kind for *<LANG>*.\n\tBe not confused this with ``--kinds-<LANG>``.\n\n\t*<letter>* must be an alphabetical character ('[a-zA-EG-Z]')\n\tother than \"F\". \"F\" has been reserved for representing a file\n\tsince Exuberant Ctags.\n\n\t*<name>* must start with an alphabetic character, and the rest\n\tmust  be alphanumeric ('[a-zA-Z][a-zA-Z0-9]*'). Do not use\n\t\"file\" as *<name>*. It has been reserved for representing a file\n\tsince Exuberant Ctags.\n\n\tNote that using a number character in a *<name>* violates the\n\tversion 2 of tags file format though ctags\n\taccepts it. For more detail, see :ref:`tags(5) <tags(5)>`.\n\n\t*<description>* comes from any printable ASCII characters. The\n\texception is ``{`` and ``\\``. ``{`` is reserved for adding flags\n\tthis option in the future. So put ``\\`` before ``{`` to include\n\t``{`` to a description. To include ``\\`` itself to a description,\n\tput ``\\`` before ``\\``.\n\n\tBoth *<letter>*, *<name>* and their combination must be unique in\n\ta *<LANG>*.\n\n\tThis option is newly introduced in Universal Ctags.  This option\n\treduces the typing defining a regex pattern with\n\t``--regex-<LANG>=``, and keeps the consistency of kind\n\tdefinitions in a language.\n\n\tThe *<letter>* can be used as an argument for ``--kinds-<LANG>``\n\toption to enable or disable the kind. Unless ``K`` field is\n\tenabled, the *<letter>* is used as value in the \"kind\" extension\n\tfield in tags output.\n\n\tThe *<name>* surrounded by braces can be used as an argument for\n\t``--kind-<LANG>`` option. If ``K`` field is enabled, the *<name>*\n\tis used as value in the \"kind\" extension field in tags output.\n\n\tThe *<description>* and *<letter>* are listed in ``--list-kinds``\n\toutput. All three elements of the kind-spec are listed in\n\t``--list-kinds-full`` output. Don't use braces in the\n\t*<description>*. They will be used meta characters in the future.\n\n``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``\n\tDefine a single-line regular expression.\n\n\tThe */<line_pattern>/<name_pattern>/* pair defines a regular expression\n\treplacement pattern, similar in style to ``sed`` substitution\n\tcommands, ``s/regexp/replacement/``, with which to generate tags from source files mapped to\n\tthe named language, *<LANG>*, (case-insensitive; either a built-in\n\tor user-defined language).\n\n\tThe regular expression, *<line_pattern>*, defines\n\tan extended regular expression (roughly that used by egrep(1)),\n\twhich is used to locate a single source line containing a tag and\n\tmay specify tab characters using ``\\t``.\n\n\tWhen a matching line is\n\tfound, a tag will be generated for the name defined by\n\t*<name_pattern>*, which generally will contain the special\n\tback-references ``\\1`` through ``\\9`` to refer to matching sub-expression\n\tgroups within *<line_pattern>*.\n\n\tThe '``/``' separator characters shown in the\n\tparameter to the option can actually be replaced by any\n\tcharacter. Note that whichever separator character is used will\n\thave to be escaped with a backslash ('``\\``') character wherever it is\n\tused in the parameter as something other than a separator. The\n\tregular expression defined by this option is added to the current\n\tlist of regular expressions for the specified language unless the\n\tparameter is omitted, in which case the current list is cleared.\n\n\tUnless modified by *<flags>*, *<line_pattern>* is interpreted as a POSIX\n\textended regular expression. The *<name_pattern>* should expand for all\n\tmatching lines to a non-empty string of characters, or a warning\n\tmessage will be reported unless ``{placeholder}`` regex flag is\n\tspecified.\n\n\tA kind specifier (*<kind-spec>*) for tags matching regexp may\n\tfollow *<name_pattern>*, which will determine what kind of tag is\n\treported in the ``kind`` extension field (see :ref:`tags(5) <tags(5)>`).\n\n\t*<kind-spec>* has two forms: *one-letter form* and *full form*.\n\n\tThe\tone-letter form in the form of ``<letter>``. It just refers a kind\n\t*<letter>* defined with ``--kinddef-<LANG>``. This form is recommended in\n\tUniversal Ctags.\n\n\tThe full form of *<kind-spec>* is in the form of\n\t``<letter>,<name>,<description>``. Either the kind *<name>* and/or the\n\t*<description>* can be omitted. See the description of\n\t``--kinddef-<LANG>=<letter>,<name>,<description>`` option about the\n\telements.\n\n\tThe full form is supported only for keeping the compatibility with Exuberant\n\tCtags which does not have ``--kinddef-<LANG>`` option. Supporting the\n\tform will be removed from Universal Ctags in the future.\n\n\t.. MEMO: the following line is commented out\n\t\tIf *<kind-spec>* is omitted, it defaults to ``r,regex``.\n\n\tAbout *<flags>*, see \"FLAGS FOR ``--regex-<LANG>`` OPTION\".\n\n\tFor more information on the regular expressions used by\n\tctags, see either the regex(5,7) man page, or\n\tthe GNU info documentation for regex (e.g. \"``info regex``\").\n\n``--list-regex-flags``\n\tLists the flags that can be used in ``--regex-<LANG>`` option.\n\n``--list-mline-regex-flags``\n\tLists the flags that can be used in ``--mline-regex-<LANG>`` option.\n\n``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``\n\tDefine a multi-line regular expression.\n\n\tThis option is similar to ``--regex-<LANG>`` option except the pattern is\n\tapplied to the whole file’s contents, not line by line.\n\n\tSee \"`FLAGS FOR --mline-regex-<LANG> OPTION`_\" about ``{mgroup=<N>}``.\n\t``{mgroup=<N>}`` flag is a must.\n\n``--_echo=<message>``\n\tPrint *<message>* to the standard error stream.  This is helpful to\n\tunderstand (and debug) optlib loading feature of Universal Ctags.\n\n``--_force-quit[=<num>]``\n\tExits immediately when this option is processed.  If *<num>* is used\n\tas exit status. The default is 0.  This is helpful to debug optlib\n\tloading feature of Universal Ctags.\n\n\nFLAGS FOR ``--regex-<LANG>`` OPTION\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can specify more than one flag, ``<letter>|{<name>}``, at the end of ``--regex-<LANG>`` to\ncontrol how Universal Ctags uses the pattern.\n\nExuberant Ctags uses a *<letter>* to represent a flag. In\nUniversal Ctags, a *<name>* surrounded by braces (name form) can be used\nin addition to *<letter>*. The name form makes a user reading an optlib\nfile easier.\n\nThe most of all flags newly added in Universal Ctags\ndon't have the one-letter representation. All of them have only the name\nrepresentation. ``--list-regex-flags`` lists all the flags.\n\n``basic`` (one-letter form ``b``)\n\tThe pattern is interpreted as a POSIX basic regular expression.\n\n``exclusive`` (one-letter form ``x``)\n\tSkip testing the other patterns if a line is matched to this\n\tpattern. This is useful to avoid using CPU to parse line comments.\n\n``extend`` (one-letter form ``e``)\n\tThe pattern is interpreted as a POSIX extended regular\n\texpression (default).\n\n``pcre2`` (one-letter form ``p``, experimental)\n\tThe pattern is interpreted as a PCRE2 regular expression explained\n\tin pcre2syntax(3).  This flag is available only if the ctags is\n\tbuilt with ``pcre2`` library. See the output of\n\t``--list-features`` option to know whether your ctags is\n\tbuilt-with ``pcre2`` or not.\n\n``icase`` (one-letter form ``i``)\n\tThe regular expression is to be applied in a case-insensitive\n\tmanner.\n\n``placeholder``\n\tDon't emit a tag captured with a regex pattern.  The replacement\n\tcan be an empty string.  See the following description of\n\t``scope=...`` flag about how this is useful.\n\n``postrun``\n\tMatch the pattern at the end of all the parsing processes, including:\n\n\t* running the built-in code for ``<LANG>``,\n\t* applying ``--mline-regex-<LANG>`` patterns,\n\t* applying ``--_mtable-regex-<LANG>`` patterns, and\n\t* applying non-``postrun`` ``--regex-<LANG>=`` patterns.\n\n\tThis flag is helpful when combined with ``scope=intervaltab``.\n\n\tThe built-in code processes source files line-by-line delivered by\n\tthe main part of ctags.  The main part applies\n\tnon-``postrun`` ``--regex-<LANG>=`` patterns to a line just after\n\tdelivering the line to the code of built-in code. Thus,\n\tnon-``postrun`` ``--regex-<LANG>=`` patterns cannot refer to the tags\n\tinformation finally extracted by the built-in code.\n\n\tThis is where the ``postrun`` comes into play. The main part never\n\tapplies ``postrun`` ``--regex-<LANG>=`` patterns when delivering\n\tlines to the code of built-in code. Instead, it applies the\n\t``postrun`` patterns in batch after delivering all lines to the\n\tbuilt-in code. The ``postrun`` patterns can refer to the tags\n\tinformation extracted by the built-in code.\n\n\t``--mline-regex-<LANG>`` and ``--_mtable-regex-<LANG>`` have no\n\t``{postrun}`` flag because the main part always applies the\n\tpatterns specified with the options after running the built-in\n\tcode for ``<LANG>``.\n\n\tSee also the description of ``scope=intervaltab`` flag.\n\n``scope=intervaltab``\n\tUse the interval table maintained by the main part of\n\tctags to fill in the ``scope:`` field.\n\tThis flag is useful for extending a built-in parser with the\n\t``--regex-<LANG>=`` option with ``postrun`` flag.\n\n\tThe interval table holds tag entries having both ``line:`` and\n\t``end:`` fields. These tag entries are stored in a table keyed by\n\ttheir ``line:`` and ``end:`` field pairs. Therefore, the table can\n\tanswer queries like, \"Is there a tag entry that includes\n\tthis line?\" or \"Which tag entry contains this line?\"\n\n\tThe source line, where ``postrun`` ``--regex-<LANG>`` pattern finds\n\ta language object, can be a key for such queries. The tag\n\tentry returned by the table is set in the ``scope:`` field of the\n\tnewly created tag entry for the language object.\n\n\t``postrun`` flag is needed for running the built-in parser that\n\tstores tag entries before applying patterns specified with\n\t``--regex-<LANG>``.\n\n\tSee also the example in \"`Using the interval table`_\".\n\n``scope=(ref|push|pop|clear|set|replace)``\n\tSpecify what to do with the internal scope stack.\n\n\tA parser programmed with ``--regex-<LANG>`` has a stack (scope\n\tstack) internally. You can use it for tracking scope\n\tinformation. The ``scope=...`` flag is for manipulating and\n\tutilizing the scope stack.\n\n\tIf ``{scope=push}`` is specified, a tag captured with\n\t``--regex-<LANG>`` is pushed to the stack. ``{scope=push}``\n\timplies ``{scope=ref}``.\n\n\tYou can fill the scope field (``scope:``) of captured tag with\n\t``{scope=ref}``. If ``{scope=ref}`` flag is given,\n\tctags attaches the tag at the top to the tag\n\tcaptured with ``--regex-<LANG>`` as the value for the ``scope:``\n\tfield.\n\n\tctags pops the tag at the top of the stack when\n\t``--regex-<LANG>`` with ``{scope=pop}`` is matched to the input\n\tline.\n\n\tSpecifying ``{scope=clear}`` removes all the tags in the scope.\n\tSpecifying ``{scope=set}`` removes all the tags in the scope, and\n\tthen pushes the captured tag as ``{scope=push}`` does.\n\n\t``{scope=replace}`` does the three things sequentially. First it\n\tdoes the same as ``{scope=pop}``, then fills the ``scope:`` field\n\tof the tag captured with ``--regex-<LANG>``, and pushes the tag to\n\tthe scope stack as if ``{scope=push}`` was given finally.\n\tYou cannot specify another scope action together with\n\t``{scope=replace}``.\n\n\tYou don't want to specify ``{scope=pop}{scope=push}`` as an\n\talternative to ``{scope=replace}``; ``{scope=pop}{scope=push}``\n\tfills the ``scope:`` field of the tag captured with ``--regex-<LANG>``\n\tfirst, then pops the tag at the top of the stack, and pushes\n\tthe captured tag to the scope stack finally. The timing when\n\tfilling the end field is different between ``{scope=replace}`` and\n\t``{scope=pop}{scope=push}``.\n\n\tIn some cases, you may want to use ``--regex-<LANG>`` only for its\n\tside effects: using it only to manipulate the stack but not for\n\tcapturing a tag. In such a case, make *<name_pattern>* component of\n\t``--regex-<LANG>`` option empty while specifying ``{placeholder}``\n\tas a regex flag. For example, a non-named tag can be put on\n\tthe stack by giving a regex flag \"``{scope=push}{placeholder}``\".\n\n\tYou may wonder what happens if a regex pattern with\n\t``{scope=ref}`` flag matches an input line but the stack is empty,\n\tor a non-named tag is at the top. If the regex pattern contains a\n\t``{scope=ref}`` flag and the stack is empty, the ``{scope=ref}``\n\tflag is ignored and nothing is attached to the ``scope:`` field.\n\n\tIf the top of the stack contains an unnamed tag,\n\tctags searches deeper into the stack to find the\n\ttop-most named tag. If it reaches the bottom of the stack without\n\tfinding a named tag, the ``{scope=ref}`` flag is ignored and\n\tnothing is attached to the ``scope:`` field.\n\n\tWhen a named tag on the stack is popped or cleared as the side\n\teffect of a pattern matching, ctags attaches the\n\tline number of the match to the ``end:`` field of\n\tthe named tag.\n\n\tctags clears all of the tags on the stack when it\n\treaches the end of the input source file. The line number of the\n\tend is attached to the ``end:`` field of the cleared tags.\n\n``warning=<message>``\n\tprint the given *<message>* at WARNING level\n\n``fatal=<message>``\n\tprint the given *<message>* and exit\n\nFLAGS FOR ``--mline-regex-<LANG>`` OPTION\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``mgroup=<N>``\n\tdecide the location of the tag extracted with\n\t``--mline-regex-<LANG>`` option.\n\n\t*<N>* is the number of a capture group in the pattern, which is\n\tused to record the line number location of the tag. ``mgroup=<N>``\n\tflag is not an optional. You **must** add an ``mgroup=<N>`` flag,\n\teven if the *<N>* is ``0`` (meaning the start position of the\n\twhole regex pattern).\n\n``scope=intervaltab``\n   See the description for the flag in\n   \"`FLAGS FOR --regex-<LANG> OPTION`_\".\n\n   Unlike ``--regex-<LANG>`` option, you don't have to specify\n   ``postrun`` flag.\n\nEXAMPLES\n-------------\n\nPerl Pod\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis is the definition (pod.ctags) used in ctags for parsing Pod\n(https://perldoc.perl.org/perlpod.html) file.\n\n.. code-block:: ctags\n\n   --langdef=pod\n   --map-pod=+.pod\n\n   --kinddef-pod=c,chapter,chapters\n   --kinddef-pod=s,section,sections\n   --kinddef-pod=S,subsection,subsections\n   --kinddef-pod=t,subsubsection,subsubsections\n\n   --regex-pod=/^=head1[ \\t]+(.+)/\\1/c/\n   --regex-pod=/^=head2[ \\t]+(.+)/\\1/s/\n   --regex-pod=/^=head3[ \\t]+(.+)/\\1/S/\n   --regex-pod=/^=head4[ \\t]+(.+)/\\1/t/\n\nUsing scope regex flags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nLet's think about writing a parser for a very small subset of the Ruby\nlanguage.\n\ninput source file (``input.srb``)::\n\n\tclass Example\n\t  def methodA\n\t\tputs \"in class_method\"\n\t  end\n\t  def methodB\n\t\tputs \"in class_method\"\n\t  end\n\tend\n\nThe parser for the input should capture ``Example`` with ``class`` kind,\n``methodA``, and ``methodB`` with ``method`` kind. ``methodA`` and ``methodB``\nshould have ``Example`` as their scope. ``end:`` fields of each tag\nshould have proper values.\n\noptlib file (``sub-ruby.ctags``):\n\n.. code-block:: ctags\n\n\t--langdef=subRuby\n\t--map-subRuby=.srb\n\t--kinddef-subRuby=c,class,classes\n\t--kinddef-subRuby=m,method,methods\n\t--regex-subRuby=/^class[ \\t]+([a-zA-Z][a-zA-Z0-9]+)/\\1/c/{scope=push}\n\t--regex-subRuby=/^end///{scope=pop}{placeholder}\n\t--regex-subRuby=/^[ \\t]+def[ \\t]+([a-zA-Z][a-zA-Z0-9_]+)/\\1/m/{scope=push}\n\t--regex-subRuby=/^[ \\t]+end///{scope=pop}{placeholder}\n\ncommand line and output::\n\n\t$ ctags --quiet --fields=+eK \\\n\t--options=./sub-ruby.ctags -o - input.srb\n\tExample\tinput.srb\t/^class Example$/;\"\tclass\tend:8\n\tmethodA\tinput.srb\t/^  def methodA$/;\"\tmethod\tclass:Example\tend:4\n\tmethodB\tinput.srb\t/^  def methodB$/;\"\tmethod\tclass:Example\tend:7\n\nUsing the interval table\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nLet's try to extract kernel threads defined in Linux kernel.\n\n``kthread_run`` is the function for creating and starting a\nkernel thread. For example, ``kswapd`` kernel thread is created\nwith the function like (quoted from linux/mm/vmscan.c):\n\n.. code-block:: C\n\n\tvoid kswapd_run(int nid)\n\t{\n\t\t\t/* ... */\n\t\t\tpgdat->kswapd = kthread_run(kswapd, pgdat, \"kswapd%d\", nid);\n\t\t\t/* ... */\n\n``kthread-v1.ctags`` illustrates the way to extract the name of kernel threads\nappeared at the third argument of ``kthread_run``.\n\n``kthread-v1.ctags``:\n\n.. code-block:: ctags\n\n\t--kinddef-C=K,kernelThread,the name of kernel thread in Linux kernel\n\t--regex-C=/kthread_run\\([^\"]+\"([^\"]+)\"/\\1/K/\n\nWith ``kthread-v1.ctags``, ctags emits the following tags:\n\n.. code-block:: console\n\n\t$ ctags --options=linux/kthread-v1.ctags  -o - vmscan.c\n\t...\n\tkswapd%d\tvmscan.c\t/^... = kthread_run(kswapd, pgdat, \"kswapd%d\"...$/;\"\tK\n\t...\n\nUsing the interval table, you can attach the name of the function\nwhere the kernel thread is defined.\n\n``kthread-v2.ctags``:\n\n.. code-block:: ctags\n\n\t--kinddef-C=K,kernelThread,the name of kernel thread in Linux kernel\n\t--regex-C=/kthread_run\\([^\"]+\"([^\"]+)\"/\\1/K/{postrun}{scope=intervaltab}\n\nWith ``kthread-v2.ctags``, ctags emits the following tags:\n\n.. code-block:: console\n\n\t$ ctags --options=linux/kthread-v2.ctags  -o - vmscan.c\n\t...\n\tkswapd%d\tvmscan.c\t/^... = kthread_run(kswapd, pgdat, \"kswapd%d\"...$/;\"\tK\tfunction:kswapd_run\n\t...\n\nWith the new .ctags file, ``function:kswapd_run`` is attach to\nthe tag entry as its scope field.\n\nSEE ALSO\n--------\n\nThe official Universal Ctags web site at:\n\nhttps://ctags.io/\n\n:ref:`ctags(1) <ctags(1)>`, :ref:`tags(5) <tags(5)>`, regex(3), regex(7), egrep(1), pcre2syntax(3)\n\nAUTHOR\n------\n\nUniversal Ctags project\nhttps://ctags.io/\n(This man page partially derived from :ref:`ctags(1) <ctags(1)>` of\nExecutable-ctags)\n\nDarren Hiebert <dhiebert@users.sourceforge.net>\nhttp://DarrenHiebert.com/\n"
  },
  {
    "path": "docs/man/ctags.1.rst",
    "content": ".. _ctags(1):\n\n==============================================================\nctags\n==============================================================\n\nGenerate tag files for source code\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 1\n\nSYNOPSIS\n--------\n|\t**ctags** [<options>] [<source_file(s)>]\n|\t**etags** [<options>] [<source_file(s)>]\n\n\nDESCRIPTION\n-----------\n\nThe *ctags* and *etags* (see ``-e`` option) programs\n(hereinafter collectively referred to as ctags,\nexcept where distinguished) generate an index (or \"tag\") file for a\nvariety of *language objects* found in *source file(s)*. This tag file allows\nthese items to be quickly and easily located by a text editor or other\nutilities (*client tools*). A *tag* signifies a language object for which an index entry is\navailable (or, alternatively, the index entry created for that object).\n\nAlternatively, ctags can generate a cross reference\nfile which lists, in human readable form, information about the various\nlanguage objects found in a set of source files.\n\nTag index files are supported by numerous editors, which allow the user to\nlocate the object associated with a name appearing in a source file and\njump to the file and line which defines the name. See the manual of your\nfavorite editor about utilizing ctags command and\nthe tag index files in the editor.\n\nctags is capable of generating different *kinds* of tags\nfor each of many different *languages*. For a complete list of supported\nlanguages, the names by which they are recognized, and the kinds of tags\nwhich are generated for each, see the ``--list-languages`` and ``--list-kinds-full``\noptions.\n\nThis man page describes *Universal Ctags*, an implementation of ctags\nderived from *Exuberant Ctags*. The major incompatible changes between\nUniversal Ctags and Exuberant Ctags are enumerated in\n:ref:`ctags-incompatibilities(7) <ctags-incompatibilities(7)>`.\n\nOne of the advantages of Exuberant Ctags is that it allows a user to\ndefine a new parser from the command line. Extending this capability is one\nof the major features of Universal Ctags. :ref:`ctags-optlib(7) <ctags-optlib(7)>`\ndescribes how the capability is extended.\n\nNewly introduced experimental features are not explained here. If you\nare interested in such features and ctags internals,\nvisit https://docs.ctags.io/.\n\n\nCOMMAND LINE INTERFACE\n----------------------\n\nDespite the wealth of available options, defaults are set so that\nctags is most commonly executed without any options (e.g.\n\"``ctags *``\", or \"``ctags -R``\"), which will\ncreate a tag file in the current directory for all recognized source\nfiles. The options described below are provided merely to allow custom\ntailoring to meet special needs.\n\nNote that spaces separating the single-letter options from their parameters\nare optional.\n\nNote also that the boolean parameters to the long form options (those\nbeginning with ``--`` and that take a ``[=(yes|no)]`` parameter) may be omitted,\nin which case ``=yes`` is implied. (e.g. ``--sort`` is equivalent to ``--sort=yes``).\nNote further that ``=1``, ``=on``, and ``=true`` are considered synonyms for ``=yes``,\nand that ``=0``, ``=off``, and ``=false`` are considered synonyms for ``=no``.\n\nSome options are either ignored or useful only when used while running in\netags mode (see ``-e`` option). Such options will be noted.\n\n*<options>* must precede the *<source_file(s)>* following the standard POSIX\nconvention.\n\nOptions taking language names will accept those names in either upper or\nlower case. See the ``--list-languages`` option for a complete list of the\nbuilt-in language names.\n\n\nLetters and names\n~~~~~~~~~~~~~~~~~\n\nSome options take one-letter flags as parameters (e.g. ``--kinds-<LANG>`` option).\nSpecifying just letters help a user create a complicated command line\nquickly.  However, a command line including sequences of one-letter flags\nbecomes difficult to understand.\n\nUniversal Ctags accepts long-name flags in\naddition to such one-letter flags. The long-name and one-letter flags can be mixed in an\noption parameter by surrounding each long-name by braces. Thus, for an\nexample, the following three notations for ``--kinds-C`` option have\nthe same meaning::\n\n\t--kinds-C=+pLl\n\t--kinds-C=+{prototype}{label}{local}\n\t--kinds-C=+{prototype}L{local}\n\nNote that braces may be meta characters in your shell. Put\nsingle quotes in such case.\n\n``--list-...`` options shows one-letter flags and associated long-name flags.\n\n\nList options\n~~~~~~~~~~~~\n\nUniversal Ctags introduces many ``--list-...`` options that provide\nthe internal data of Universal Ctags (See \"`Listing Options`_\"). Both users and client tools may\nuse the data. ``--with-list-header`` and ``--machinable`` options\nadjust the output of the most of ``--list-...`` options.\n\nThe default setting (``--with-list-header=yes`` and ``--machinable=no``)\nis for using interactively from a terminal. The header that explains\nthe meaning of columns is simply added to the output, and each column is\naligned in all lines. The header line starts with a hash ('``#``') character.\n\nFor scripting in a client tool, ``--with-list-header=no`` and\n``--machinable=yes`` may be useful. The header is not added to the\noutput, and each column is separated by tab characters.\n\nNote the order of columns will change in the future release.\nHowever, labels in the header will not change. So by scanning\nthe header, a client tool can find the index for the target\ncolumn.\n\n.. options that should be explained and revised here\n   ``--list-features``    (done)\n   ``--machinable``       (done)\n   ``--with-list-header`` (done)\n\n\nOPTIONS\n------------\nctags has more options than listed here.\nOptions starting with an underscore character, such as ``--_echo=<msg>``,\nare not listed here. They are experimental or for debugging purpose.\n\nNotation: ``<foo>`` is for a variable string ``foo``, ``[ ... ]`` for optional,\n``|`` for selection, and ``( ... )`` for grouping.  For example\n``--foo[=(yes|no)]`` means ``--foo``, ``--foo=yes``, or ``--foo=no``.\n\n.. _option_input_output_file:\n\nInput/Output File Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--exclude=<pattern>``\n\tAdd *<pattern>* to a list of excluded files and directories. This option may\n\tbe specified as many times as desired. For each file name considered\n\tby ctags, each pattern specified using this option\n\twill be compared against both the complete path (e.g.\n\t``some/path/base.ext``) and the base name (e.g. ``base.ext``) of the file, thus\n\tallowing patterns which match a given file name irrespective of its\n\tpath, or match only a specific path.\n\n\tIf appropriate support is available\n\tfrom the runtime library of your C compiler, then pattern may\n\tcontain the usual shell wildcards (not regular expressions) common on\n\tUnix (be sure to quote the option parameter to protect the wildcards from\n\tbeing expanded by the shell before being passed to ctags;\n\talso be aware that wildcards can match the slash character, '``/``').\n\tYou can determine if shell wildcards are available on your platform by\n\texamining the output of the ``--list-features`` option, which will include\n\t``wildcards`` in the compiled feature list; otherwise, pattern is matched\n\tagainst file names using a simple textual comparison.\n\n\tIf *<pattern>* begins with the character '``@``', then the rest of the string\n\tis interpreted as a file name from which to read exclusion patterns,\n\tone per line. If pattern is empty, the list of excluded patterns is\n\tcleared.\n\n\tNote that at program startup, the default exclude list contains names of\n\tcommon hidden and system files, patterns for binary files, and directories\n\tfor which it is generally not desirable to descend while processing the\n\t``--recurse`` option. To see the list of built-in exclude patterns, use\n\t``--list-excludes``.\n\n\tSee also the description for ``--exclude-exception=`` option.\n\n``--exclude-exception=<pattern>``\n\tAdd *<pattern>* to a list of included files and directories. The pattern\n\taffects the files and directories that are excluded by the pattern\n\tspecified with ``--exclude=`` option.\n\n\tFor an example, you want ctags to ignore all files\n\tunder ``foo`` directory except ``foo/main.c``, use the following command\n\tline: ``--exclude=foo/* --exclude-exception=foo/main.c``.\n\n``--filter[=(yes|no)]``\n\tMakes ctags behave as a filter, reading source\n\tfile names from standard input and printing their tags to standard\n\toutput on a file-by-file basis. If ``--sort`` is enabled, tags are sorted\n\tonly within the source file in which they are defined. File names are\n\tread from standard input in line-oriented input mode (see note for ``-L``\n\toption) and only after file names listed on the command line or from\n\tany file supplied using the ``-L`` option. When this option is enabled,\n\tthe options ``-f``, ``-o``, and ``--totals`` are ignored. This option is quite\n\tesoteric and is disabled by default.\n\n``--filter-terminator=<string>``\n\tSpecifies a *<string>* to print to standard output following the tags for\n\teach file name parsed when the ``--filter`` option is enabled. This may\n\tpermit an application reading the output of ctags\n\tto determine when the output for each file is finished.\n\n\tNote that if the\n\tfile name read is a directory and ``--recurse`` is enabled, this string will\n\tbe printed only once at the end of all tags found for by descending\n\tthe directory. This string will always be separated from the last tag\n\tline for the file by its terminating newline.\n\n\tThis option is quite esoteric and is empty by default.\n\n``--links[=(yes|no)]``\n\tIndicates whether symbolic links (if supported) should be followed.\n\tWhen disabled, symbolic links are ignored. This option is on by default.\n\n``--maxdepth=<N>``\n\tLimits the depth of directory recursion enabled with the ``--recurse``\n\t(``-R``) option.\n\n``--recurse[=(yes|no)]``\n\tRecurse into directories encountered in the list of supplied files.\n\n\tIf the list of supplied files is empty and no file list is specified with\n\tthe ``-L`` option, then the current directory (i.e. '``.``') is assumed.\n\tSymbolic links are followed by default (See ``--links`` option). If you don't like these behaviors, either\n\texplicitly specify the files or pipe the output of ``find(1)`` into\n\t\"``ctags -L -``\" instead. See, also, the ``--exclude`` and\n\t``--maxdepth`` to limit recursion.\n\n\tNote: This option is not supported on\n\tall platforms at present. It is available if the output of the ``--help``\n\toption includes this option.\n\n.. TODO(code): --list-features option should support this.\n\n``-R``\n\tEquivalent to ``--recurse``.\n\n``-L <file>``\n\tRead from *<file>* a list of file names for which tags should be generated.\n\n\tIf file is specified as '``-``', then file names are read from standard\n\tinput. File names read using this option are processed following file\n\tnames appearing on the command line. Options are also accepted in this\n\tinput. If this option is specified more than once, only the last will\n\tapply.\n\n\tNote: file is read in line-oriented mode, where a new line is\n\tthe only delimiter and non-trailing white space is considered significant,\n\tin order that file names containing spaces may be supplied\n\t(however, trailing white space is stripped from lines); this can affect\n\thow options are parsed if included in the input.\n\n``--append[=(yes|no)]``\n\tIndicates whether tags generated from the specified files should be\n\tappended to those already present in the tag file or should replace them.\n\tThis option is ``no`` by default.\n\n``-a``\n\tEquivalent to ``--append``.\n\n``-f <tagfile>``\n\tUse the name specified by *<tagfile>* for the tag file (default is \"``tags``\",\n\tor \"``TAGS``\" when running in etags mode). If *<tagfile>* is specified as '``-``',\n\tthen the tags are written to standard output instead.\n\n\tctags\n\twill stubbornly refuse to take orders if tagfile exists and\n\tits first line contains something other than a valid tags line. This\n\twill save your neck if you mistakenly type \"``ctags -f\n\t*.c``\", which would otherwise overwrite your first C file with the tags\n\tgenerated by the rest! It will also refuse to accept a multi-character\n\tfile name which begins with a '``-``' (dash) character, since this most\n\tlikely means that you left out the tag file name and this option tried to\n\tgrab the next option as the file name. If you really want to name your\n\toutput tag file ``-ugly``, specify it as \"``-f ./-ugly``\".\n\n\tThis option must\n\tappear before the first file name. If this option is specified more\n\tthan once, only the last will apply.\n\n``-o <tagfile>``\n\tEquivalent to \"``-f tagfile``\".\n\n.. _option_output_format:\n\nOutput Format Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--format=(1|2)``\n\tChange the format of the output tag file. Currently the only valid\n\tvalues for level are 1 or 2. Level 1 specifies the original tag file\n\tformat and level 2 specifies a new extended format containing extension\n\tfields (but in a manner which retains backward-compatibility with\n\toriginal ``vi(1)`` implementations). The default level is 2.\n\t[Ignored in etags mode]\n\n``--output-format=(u-ctags|e-ctags|etags|xref|json)``\n\tSpecify the output format. The default is ``u-ctags``.\n\tSee :ref:`tags(5) <tags(5)>` for ``u-ctags`` and ``e-ctags``.\n\t``TAG_OUTPUT_MODE`` pseudo tag indicates the choice,\n\t``u-ctags`` or ``e-ctags``. See :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`\n\tfor more about the pseudo tag.\n\n\tSee ``-e`` for ``etags``, and ``-x`` for ``xref``.\n\t``json`` format is available only if\n\tthe ctags executable is built with ``libjansson``.\n\tSee :ref:`ctags-json-output(5) <ctags-json-output(5)>` for more about ``json`` format.\n\n\tSee also ``--list-output-formats``.\n\n``-e``\n\tSame as ``--output-format=etags``.\n\tEnable etags mode, which will create a tag file for use with the Emacs\n\teditor. Alternatively, if ctags is invoked by a\n\tname containing the string \"etags\" (either by renaming,\n\tor creating a link to, the executable), etags mode will be enabled.\n\n``-x``\n\tSame as ``--output-format=xref``.\n\tPrint a tabular, human-readable cross reference (xref) file to standard\n\toutput instead of generating a tag file. The information contained in\n\tthe output includes: the tag name; the kind of tag; the line number,\n\tfile name, and source line (with extra white space condensed) of the\n\tfile which defines the tag. No tag file is written and all options\n\taffecting tag file output will be ignored.\n\n\tExample applications for this\n\tfeature are generating a listing of all functions located in a source\n\tfile (e.g. \"``ctags -x --kinds-c=f file``\"), or generating\n\ta list of all externally visible global variables located in a source\n\tfile (e.g. \"``ctags -x --kinds-c=v --extras=-F file``\").\n\n``--sort=(yes|no|foldcase)``\n\tIndicates whether the tag file should be sorted on the tag name\n\t(default is ``yes``). Note that the original ``vi(1)`` required sorted tags.\n\tThe ``foldcase`` value specifies case insensitive (or case-folded) sorting.\n\tFast binary searches of tag files sorted with case-folding will require\n\tspecial support from tools using tag files, such as that found in the\n\tctags readtags library, or Vim version 6.2 or higher\n\t(using \"``set ignorecase``\").\n\t[Ignored in etags mode]\n\n``-u``\n\tEquivalent to ``--sort=no`` (i.e. \"unsorted\").\n\n``--etags-include=<file>``\n\tInclude a reference to *<file>* in the tag file. This option may be specified\n\tas many times as desired. This supports Emacs' capability to use a\n\ttag file which *includes* other tag files. [Available only in etags mode]\n\n``--input-encoding=<encoding>``\n\tSpecifies the *<encoding>* of the input files.\n\tIf this option is specified, Universal Ctags converts the input from this\n\tencoding to the encoding specified by ``--output-encoding=encoding``.\n\n``--input-encoding-<LANG>=<encoding>``\n\tSpecifies a specific input *<encoding>* for *<LANG>*. It overrides the global\n\tdefault value given with ``--input-encoding``.\n\n``--output-encoding=<encoding>``\n\tSpecifies the *<encoding>* of the tags file.\n\tUniversal Ctags converts the encoding of input files from the encoding\n\tspecified by ``--input-encoding=<encoding>`` to this encoding.\n\n\tIn addition *<encoding>* is specified at the top the tags file as the\n\tvalue for the ``TAG_FILE_ENCODING`` pseudo-tag. The default value of\n\t*<encoding>* is ``UTF-8``.\n\n.. _option_lang_mapping:\n\nLanguage Selection and Mapping Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--language-force=(<language>|auto)``\n\tBy default, ctags automatically selects the language\n\tof a source file, ignoring those files whose language cannot be\n\tdetermined (see \"`Determining file language`_\"). This option forces the specified\n\t*language* (case-insensitive; either built-in or user-defined) to be used\n\tfor every supplied file instead of automatically selecting the language\n\tbased upon its extension.\n\n\tIn addition, the special value ``auto`` indicates\n\tthat the language should be automatically selected (which effectively\n\tdisables this option).\n\n``--languages=[+|-](<list>|all)``\n\tSpecifies the languages for which tag generation is enabled, with *<list>*\n\tcontaining a comma-separated list of language names (case-insensitive;\n\teither built-in or user-defined).\n\n\tIf the first language of *<list>* is not\n\tpreceded by either a '``+``' or '``-``', the current list (the current settings\n\tof enabled/disabled languages managed in ctags internally)\n\twill be cleared before adding or removing the languages in *<list>*. Until a '``-``' is\n\tencountered, each language in the *<list>* will be added to the current list.\n\n\tAs either the '``+``' or '``-``' is encountered in the *<list>*, the languages\n\tfollowing it are added or removed from the current list, respectively.\n\tThus, it becomes simple to replace the current list with a new one, or\n\tto add or remove languages from the current list.\n\n\tThe actual list of\n\tfiles for which tags will be generated depends upon the language\n\textension mapping in effect (see the ``--langmap`` option). Note that the most of\n\tlanguages, including user-defined languages, are enabled unless explicitly\n\tdisabled using this option. Language names included in list may be any\n\tbuilt-in language or one previously defined with ``--langdef``.\n\n\tThe default\n\tis ``all``, which is also accepted as a valid argument. See the\n\t``--list-languages`` option for a list of the all (built-in and user-defined)\n\tlanguage names.\n\n\tNote ``--languages=`` option works cumulative way; the option can be\n\tspecified with different arguments multiple times in a command line.\n\n``--alias-<LANG>=[+|-](<pattern>|default)``\n\tAdds ('``+``') or removes ('``-``') an alias *<pattern>* to a language specified\n\twith *<LANG>*. ctags refers to the alias pattern in\n\t\"`Determining file language`_\" stage.\n\n\tThe parameter *<pattern>* is not a list. Use this option multiple\n\ttimes in a command line to add or remove multiple alias\n\tpatterns.\n\n\tTo restore the default language aliases, specify ``default``.\n\n\tUsing ``all`` for *<LANG>* has meaning in following two cases:\n\n\t``--alias-all=``\n\t\tThis clears aliases setting of all languages.\n\n\t``--alias-all=default``\n\t\tThis restores the default languages aliases for all languages.\n\n``--guess-language-eagerly``\n\tLooks into the file contents for heuristically guessing the proper language parser.\n\tSee \"`Determining file language`_\".\n\n``-G``\n\tEquivalent to ``--guess-language-eagerly``.\n\n``--langmap=<map>[,<map>[...]]``\n\tControls how file names are mapped to languages (see the ``--list-maps``\n\toption). Each comma-separated *<map>* consists of the language name (either\n\ta built-in or user-defined language), a colon, and a list of *file\n\textensions* and/or *file name patterns*. A file extension is specified by\n\tpreceding the extension with a period (e.g. ``.c``). A file name pattern\n\tis specified by enclosing the pattern in parentheses (e.g.\n\t``([Mm]akefile)``).\n\n\tIf appropriate support is available from the runtime\n\tlibrary of your C compiler, then the file name pattern may contain the usual\n\tshell wildcards common on Unix (be sure to quote the option parameter to\n\tprotect the wildcards from being expanded by the shell before being\n\tpassed to ctags). You can determine if shell wildcards\n\tare available on your platform by examining the output of the\n\t``--list-features`` option, which will include ``wildcards`` in the compiled\n\tfeature list; otherwise, the file name patterns are matched against\n\tfile names using a simple textual comparison.\n\n\tWhen mapping a file extension or a file name pattern with\n\t``--langmap`` option, it will first be unmapped from any other\n\tlanguages. (``--map-<LANG>`` option provides more fine-grained\n\tcontrol.)\n\n\tIf the first character in a *<map>* is a plus sign ('``+``'), then the extensions and\n\tfile name patterns in that map will be appended to the current map\n\tfor that language; otherwise, the map will replace the current map.\n\tFor example, to specify that only files with extensions of ``.c`` and ``.x`` are\n\tto be treated as C language files, use ``--langmap=c:.c.x``; to also add\n\tfiles with extensions of ``.j`` as Java language files, specify\n\t``--langmap=c:.c.x,java:+.j``. To map makefiles (e.g. files named either\n\t``Makefile``, ``makefile``, or having the extension ``.mak``) to a language\n\tcalled ``make``, specify ``--langmap=make:([Mm]akefile).mak``. To map files\n\thaving no extension, specify a period not followed by a non-period\n\tcharacter (e.g. '``.``', ``..x``, ``.x.``).\n\n\tTo clear the mapping for a\n\tparticular language (thus inhibiting automatic generation of tags for\n\tthat language), specify an empty extension list (e.g. ``--langmap=fortran:``).\n\tTo restore the default language mappings for a particular language,\n\tsupply the keyword ``default`` for the mapping. To specify restore the\n\tdefault language mappings for all languages, specify ``--langmap=default``.\n\n\tNote that file name patterns are tested before file extensions when inferring\n\tthe language of a file. This order of Universal Ctags is different from\n\tExuberant Ctags. See :ref:`ctags-incompatibilities(7) <ctags-incompatibilities(7)>` for the background of\n\tthis incompatible change.\n\n\tUnlike ``--map-<LANG>`` option, you cannot specify relative-path regular\n\t expressions to ``--langmap`` option.\n\n``--map-<LANG>=[+|-]<extension>|<pattern>|<rexpr>``\n\tThis option provides the way to control mapping(s) of file names to\n\tlanguages in a more fine-grained way than ``--langmap`` option.\n\n\tIn ctags, more than one language can map to a\n\trelative-path regular expression (*<rexpr>*), file name *<pattern>*, or\n\tfile *<extension>* (*N:1 map*). Alternatively, ``--langmap``\n\toption handle only *1:1 map*, only one language mapping to one\n\tfile name *<pattern>* or file *<extension>*.  A typical N:1 map is\n\tseen in C++ and ObjectiveC language; both languages have a map to\n\t``.h`` as a file extension.\n\n\tA file extension is specified by preceding the extension with a period\n\t(e.g. ``.c``).  A file name pattern is specified by enclosing the pattern in\n\tparentheses (e.g.  ``([Mm]akefile)``). A relative-path regular expression is\n\tspecified by enclosing the expressions in percent signs '``%``'\n\t(e.g. ``%include/.*\\.h%``). To include a literal percent sign\n\tinside the regular expression, escape it as ``\\%``.\n\n\tA prefixed plus ('``+``') sign is for adding, and\n\tminus ('``-``') is for removing. No prefix means replacing the map of *<LANG>*.\n\n\tUnlike ``--langmap``, ``--map-<LANG>`` does not take a list; ``--map-<LANG>``\n\ttakes one extension, one pattern, or one regular expression. However, the\n\toption can be specified with different arguments multiple times in a command\n\tline.\n\n\tFor file extensions and file name patterns, the match is performed\n\twith a base file name, a file without any directory components.\n\tFor relative-path regular expressions, the match is performed with\n\ta relative-path incorporating the directory components. A\n\trelative-path is relative to the directory where ctags launches.\n\n\tAssume your shell is in ``/project/x`` directory and you have the following\n\tsource tree under the directory.\n\n\t.. code-block::\n\n\t\tsrc\n\t\t└── lib\n\t\t    ├── data.c\n\t\t    └── logic.c\n\n\tIf you run ctags with ``ctags -R src``,\n\tthe match is performed with ``src/lib/data.c`` and ``src/lib/logic.c`` If you\n\tgive ``--map-YourParser='%src/lib/.*\\.c%'``, ctags\n\tchooses ``YourParser`` parser for processing ``data.c`` and ``logic.c`` in the\n\ttree.\n\n\tIf your shell is in ``/project/x/src`` and you run\n\t``ctags -R lib``, ctags may not choose\n\t``YourParser`` because the match is performed with ``lib/data.c`` and\n\t``lib/logic.c``.\n\n\tA relative-path regular expression can take a flag controlling its testing.\n\tThe flag comes after the last percent sign. Currently only one available flag:\n\n\t``{icase}`` (one-letter form '``i``')\n\t\tThe regular expression is to be applied in a case-insensitive\n\t\tmanner. (e.g. ``%include/.*\\.h%i`` or ``%include/.*\\.h%{icase}``\n\n\tThe relative-path regular expression is available since version 6.3.0.\n\n.. _option_tags_file_contents:\n\nTags File Contents Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSee \"`TAG ENTRIES`_\" about fields, kinds, roles, and extras.\n\n``--excmd=(number|pattern|mix|combine)``\n\tDetermines the type of ``EX`` command used to locate tags in the source\n\tfile. [Ignored in etags mode]\n\n\tThe valid values for type (either the entire word or the first letter\n\tis accepted) are:\n\n\t``number``\n\t\tUse only line numbers in the tag file for locating tags. This has\n\t\tfour advantages:\n\n\t\t1.\tSignificantly reduces the size of the resulting tag file.\n\t\t2.\tEliminates failures to find tags because the line defining the\n\t\t\ttag has changed, causing the pattern match to fail (note that\n\t\t\tsome editors, such as ``vim``, are able to recover in many such\n\t\t\tinstances).\n\t\t3.\tEliminates finding identical matching, but incorrect, source\n\t\t\tlines (see \"`BUGS`_\").\n\t\t4.\tRetains separate entries in the tag file for lines which are\n\t\t\tidentical in content. In pattern mode, duplicate entries are\n\t\t\tdropped because the search patterns they generate are identical,\n\t\t\tmaking the duplicate entries useless.\n\n\t\tHowever, this option has one significant drawback: changes to the\n\t\tsource files can cause the line numbers recorded in the tag file\n\t\tto no longer correspond to the lines in the source file, causing\n\t\tjumps to some tags to miss the target definition by one or more\n\t\tlines. Basically, this option is best used when the source code\n\t\tto which it is applied is not subject to change. Selecting this\n\t\toption type causes the following options to be ignored: ``-B``, ``-F``.\n\n\t\t``number`` type is ignored in Xref and JSON output formats. Use\n\t\t``--_xformat=\"...%n\"`` for Xref output format, or ``--fields=+n-P`` for\n\t\tJSON output format.\n\n\t\t.. NOTE: #2792\n\n\t``pattern``\n\t\tUse only search patterns for all tags, rather than the line numbers\n\t\tusually used for macro definitions. This has the advantage of\n\t\tnot referencing obsolete line numbers when lines have been added or\n\t\tremoved since the tag file was generated.\n\n\t``mixed``\n\t\tIn this mode, patterns are generally used with an exceptions.\n\t\tFor Fortran, line numbers\n\t\tare used for common blocks because their corresponding source lines\n\t\tare generally identical, making pattern searches useless\n\t\tfor finding all matches.\n\n\t\tExuberant Ctags has one more exception; for C, line numbers are used\n\t\tfor macro definition tags. Universal Ctags doesn't have this exception\n\t\tfor C.\n\n\t\tThis was the default format generated by the original ctags and is,\n\t\ttherefore, retained as the default for this option.\n\n\t``combine``\n\t\tConcatenate the line number and pattern with a semicolon in between.\n\n``-n``\n\tEquivalent to ``--excmd=number``.\n\n``-N``\n\tEquivalent to ``--excmd=pattern``.\n\n``--extras=[+|-][<flags>|*]``\n\tSpecifies whether to include extra tag entries for certain kinds of\n\tinformation. See also \"`Extras`_\" subsection to know what are extras.\n\n\tThe parameter *<flags>* is a set of one-letter flags (and/or long-name flags), each\n\trepresenting one kind of extra tag entry to include in the tag file.\n\tIf flags is preceded by either the '``+``' or '``-``' character, the effect of\n\teach flag is added to, or removed from, those currently enabled;\n\totherwise the flags replace any current settings. All entries are\n\tincluded  if '``*``' is given.\n\n\tThis ``--extras=`` option is for controlling extras common in all\n\tlanguages (or language-independent extras).  Universal Ctags also\n\tsupports language-specific extras. (See \"`Language-specific fields and\n\textras`_\" about the concept). Use ``--extras-<LANG>=`` option for\n\tcontrolling them.\n\n``--extras-(<LANG>|all)=[+|-][<flags>|*]``\n\tSpecifies whether to include extra tag entries for certain kinds of\n\tinformation for language *<LANG>*. Universal Ctags\n\tintroduces language-specific extras. See \"`Language-specific fields and\n\textras`_\" about the concept. This option is for controlling them.\n\n\tSpecifies ``all`` as *<LANG>* to apply the parameter *<flags>* to all\n\tlanguages; all extras are enabled with specifying '``*``' as the\n\tparameter flags. If specifying nothing as the parameter flags\n\t(``--extras-all=``), all extras are disabled. These two combinations\n\tare useful for testing.\n\n\tCheck the output of the ``--list-extras=<LANG>`` option for the\n\textras of specific language *<LANG>*.\n\n``--fields=[+|-][<flags>|*]``\n\tSpecifies which language-independent fields are to be included in the tag\n\tentries. Language-independent fields are extension fields which are common\n\tin all languages. See \"`TAG FILE FORMAT`_\" section, and \"`Extension fields`_\"\n\tsubsection, for details of extension fields.\n\n\tThe parameter *<flags>* is a set of one-letter or long-name flags,\n\teach representing one type of extension field to include.\n\tEach flag or group of flags may be preceded by either '``+``' to add it\n\tto the default set, or '``-``' to exclude it. In the absence of any\n\tpreceding '``+``' or '``-``' sign, only those fields explicitly listed in flags\n\twill be included in the output (i.e. overriding the default set). All\n\tfields are included if '``*``' is given.\n\n\tThis option is ignored if the\n\toption ``--format=1`` (legacy tag file format) has been specified.\n\n\tUse ``--fields-<LANG>=`` option for controlling language-specific fields.\n\n``--fields-(<LANG>|all)=[+|-][<flags>|*]``\n\tSpecifies which language-specific fields are to be included in\n\tthe tag entries. Universal Ctags\n\tsupports language-specific fields. (See \"`Language-specific fields and\n\textras`_\" about the concept).\n\n\tSpecify ``all`` as *<LANG>* to apply the parameter *<flags>* to all\n\tlanguages; all fields are enabled with specifying '``*``' as the\n\tparameter flags. If specifying nothing as the parameter *<flags>*\n\t(i.e. ``--fields-all=``), all fields are disabled. These two combinations\n\tare useful for testing.\n\n\tSee the description of ``--fields=[+|-][<flags>|*]`` about *<flags>*.\n\n\tUse ``--fields=`` option for controlling language-independent fields.\n\n\n``--kinds-(<LANG>|all)=[+|-](<kinds>|*)``\n\tSpecifies a list of language-specific *<kinds>* of tags (or kinds) to\n\tinclude in the output file for a particular language, where *<LANG>* is\n\tcase-insensitive and is one of the built-in language names (see the\n\t``--list-languages`` option for a complete list).\n\n\tThe parameter *<kinds>* is a group\n\tof one-letter or long-name flags designating kinds of tags (particular to the language)\n\tto either include or exclude from the output. The specific sets of\n\tflags recognized for each language, their meanings and defaults may be\n\tlist using the ``--list-kinds-full`` option.\n\n\tEach letter or group of letters\n\tmay be preceded by either '``+``' to add it to, or '``-``' to remove it from,\n\tthe default set. In the absence of any preceding '``+``' or '``-``' sign, only\n\tthose kinds explicitly listed in kinds will be included in the output\n\t(i.e. overriding the default for the specified language).\n\n\tSpecify '``*``' as the parameter to include all kinds implemented\n\tin *<LANG>* in the output. Furthermore if ``all`` is given as *<LANG>*,\n\tspecification of the parameter ``kinds`` affects all languages defined\n\tin ctags. Giving ``all`` makes sense only when '``*``' or\n\t'``F``' is given as the parameter ``kinds``.\n\n\tAs an example for the C language, in order to add prototypes and\n\texternal variable declarations to the default set of tag kinds,\n\tbut exclude macros, use ``--kinds-c=+px-d``; to include only tags for\n\tfunctions, use ``--kinds-c=f``.\n\n\tSome kinds of C and C++ languages are synchronized; enabling\n\t(or disabling) a kind in one language enables the kind having\n\tthe same one-letter and long-name in the other language. See also the\n\tdescription of ``MASTER`` column of ``--list-kinds-full``.\n\n..\tCOMMENT:\n\t``--param-<LANG>.name=argument`` is moved to \"Language Specific Options\"\n\n``--pattern-length-limit=<N>``\n\tTruncate patterns of tag entries after *<N>* characters. Disable by setting to 0\n\t(default is 96).\n\n\tAn input source file with long lines and multiple tag matches per\n\tline can generate an excessively large tags file with an\n\tunconstrained pattern length. For example, running ctags on a\n\tminified JavaScript source file often exhibits this behavior.\n\n\tThe truncation avoids cutting in the middle of a UTF-8 code point\n\tspanning multiple bytes to prevent writing invalid byte sequences from\n\tvalid input files. This handling allows for an extra 3 bytes above the\n\tconfigured limit in the worse case of a 4 byte code point starting\n\tright before the limit. Please also note that this handling is fairly\n\tnaive and fast, and although it is resistant against any input, it\n\trequires a valid input to work properly; it is not guaranteed to work\n\tas the user expects when dealing with partially invalid UTF-8 input.\n\tThis also partially affect non-UTF-8 input, if the byte sequence at\n\tthe truncation length looks like a multibyte UTF-8 sequence. This\n\tshould however be rare, and in the worse case will lead to including\n\tup to an extra 3 bytes above the limit.\n\n``--pseudo-tags=[+|-](<pseudo-tag>|*)``\n\tEnable/disable emitting pseudo-tag named *<pseudo-tag>*.\n\tIf '``*``' is given, enable/disable emitting all pseudo-tags.\n\n``--put-field-prefix``\n\tPut ``UCTAGS`` as prefix for the name of fields newly introduced in\n\tUniversal Ctags.\n\n\tSome fields are newly introduced in Universal Ctags and more will\n\tbe introduced in the future. Other tags generators may also\n\tintroduce their specific fields.\n\n\tIn such a situation, there is a concern about conflicting field\n\tnames; mixing tags files generated by multiple tags generators\n\tincluding Universal Ctags is difficult. This option provides a\n\tworkaround for such station.\n\n\t.. code-block:: console\n\n\t\t$ ctags --fields='{line}{end}' -o - hello.c\n\t\tmain\thello.c\t/^main(int argc, char **argv)$/;\"\tf\tline:3\tend:6\n\t\t$ ctags --put-field-prefix --fields='{line}{end}' -o - hello.c\n\t\tmain\thello.c\t/^main(int argc, char **argv)$/;\"\tf\tline:3\tUCTAGSend:6\n\n\tIn the above example, the prefix is put to ``end`` field which is\n\tnewly introduced in Universal Ctags.\n\n``--roles-(<LANG>|all).(<kind>|*)=[+|-][<roles>|*]``\n\tSpecifies a list of kind-specific roles of tags to include in the\n\toutput file for a particular language.\n\t*<kind>* specifies the kind where the *<roles>* are defined.\n\t*<LANG>* specifies the language where the kind is defined.\n\tEach role in *<roles>* must be surrounded by braces (e.g. ``{system}``\n\tfor a role named \"system\").\n\n\tLike ``--kinds-<LANG>`` option, '``+``' is for adding the role to the\n\tlist, and '``-``' is for removing from the list. '``*``' is for including\n\tall roles of the kind to the list. \tThe option with no argument\n\tmakes the list empty.\n\n\tBoth a one-letter flag or a long name flag surrounded by braces are\n\tacceptable for specifying a kind (e.g. ``--roles-C.h=+{system}{local}``\n\tor ``--roles-C.{header}=+{system}{local}``).  '``*``' can be used for *<KIND>*\n\tonly for adding/removing all roles of all kinds in a language to/from\n\tthe list (e.g.  ``--roles-C.*=*`` or ``--roles-C.*=``).\n\n\t``all`` can be used for *<LANG>* only for adding/removing all roles of\n\tall kinds in all languages to/from the list\n\t(e.g.  ``--roles-all.*=*`` or ``--roles-all.*=``).\n\n``--tag-relative=(yes|no|always|never)``\n\tSpecifies how the file paths recorded in the tag file.\n\tThe default is ``yes`` when running in etags mode (see\n\tthe ``-e`` option), ``no`` otherwise.\n\n\t``yes``\n\t\tindicates that the file paths recorded in the tag file should be\n\t\t*relative to the directory containing the tag file*\n\t\tunless the files supplied on the command line\n\t\tare specified with absolute paths.\n\n\t``no``\n\t\tindicates that the file paths recorded in the tag file should be\n\t\t*relative to the current directory*\n\t\tunless the files supplied on the command line\n\t\tare specified with absolute paths.\n\n\t``always``\n\t\tindicates the recorded file paths should be relative\n\t\teven if source file names are passed in with absolute paths.\n\n\t``never``\n\t\tindicates the recorded file paths should be absolute\n\t\teven if source file names are passed in with relative paths.\n\n``--use-slash-as-filename-separator[=(yes|no)]``\n\tUses slash ('``/``') character as filename separators instead of backslash\n\t('``\\``') character when printing ``input:`` field.\n\tThe default is ``yes`` for the default \"u-ctags\" output format, and\n\t``no`` for the other formats.\n\n\t``TAG_OUTPUT_FILESEP`` pseudo tag is for representing  the choice of\n\tfilename separators with this option. See also :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`.\n\n\tThis option is available on MS Windows only.\n\n``-B``\n\tUse backward searching patterns (e.g. ``?pattern?``). [Ignored in etags mode]\n\n``-F``\n\tUse forward searching patterns (e.g. ``/pattern/``) (default). [Ignored\n\tin etags mode]\n\nOption File Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n.. TODO: merge some of description in option-file.rst into FILE or a dedicated\n\tsection\n\n``--options=<pathname>``\n\tRead additional options from file or directory.\n\n\tctags searches *<pathname>* in the optlib path list\n\tfirst. If ctags cannot find a file or directory\n\tin the list, ctags reads a file or directory\n\tat the specified *<pathname>*.\n\n\tIf a file is specified, it should contain one option per line. If\n\ta directory is specified, files suffixed with ``.ctags`` under it\n\tare read in alphabetical order.\n\n\tAs a special case, if ``--options=NONE`` is specified as the first\n\toption on the command line, preloading is disabled; the option\n\twill disable the automatic reading of any configuration options\n\tfrom a file (see \"`FILES`_\").\n\n``--options-maybe=<pathname>``\n\tSame as ``--options`` but doesn't cause an error if file\n\t(or directory) specified with *<pathname>* doesn't exist.\n\n``--optlib-dir=[+]<directory>``\n\tAdd an optlib *<directory>* to or reset the optlib path list.\n\tSee \"`Default optlib path list`_\" about the default elements for optlib path list.\n\noptlib Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSee :ref:`ctags-optlib(7) <ctags-optlib(7)>` for details of each option.\n\n``--kinddef-<LANG>=<letter>,<name>,<description>``\n\tDefine a kind for *<LANG>*.\n\tDon't be confused this with ``--kinds-<LANG>``.\n\n``--langdef=<name>``\n\tDefines a new user-defined language, *<name>*, to be parsed with regular\n\texpressions.\n\n``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``\n\tDefine multi-line regular expression for locating tags in specific language.\n\n``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``\n\tDefine single-line regular expression for locating tags in specific language.\n\n.. _option_lang_specific:\n\nLanguage Specific Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--if0[=(yes|no)]``\n\tIndicates a preference as to whether code within an \"``#if 0``\" branch of a\n\tpreprocessor conditional should be examined for non-macro tags (macro\n\ttags are always included). Because the intent of this construct is to\n\tdisable code, the default value of this option is ``no`` (disabled).\n\n\tNote that this\n\tindicates a preference only and does not guarantee skipping code within\n\tan \"``#if 0``\" branch, since the fall-back algorithm used to generate\n\ttags when preprocessor conditionals are too complex follows all branches\n\tof a conditional.\n\n``--line-directives[=(yes|no)]``\n\tSpecifies whether ``#line`` directives should be recognized. These are\n\tpresent in the output of a preprocessor and contain the line number, and\n\tpossibly the file name, of the original source file(s) from which the\n\tpreprocessor output file was generated. This option is off by default.\n\n\tWhen enabled, this option will\n\tcause ctags to generate tag entries marked with the\n\tfile names and line numbers of their locations original source file(s),\n\tinstead of their actual locations in the preprocessor output. The actual\n\tfile names placed into the tag file will have the same leading path\n\tcomponents as the preprocessor output file, since it is assumed that\n\tthe original source files are located relative to the preprocessor\n\toutput file (unless, of course, the ``#line`` directive specifies an\n\tabsolute path).\n\n\tNote: This option is generally\n\tonly useful when used together with the ``--excmd=number`` (``-n``) option.\n\tAlso, you may have to use either the ``--langmap`` or ``--language-force`` option\n\tif the extension of the preprocessor output file is not known to\n\tctags.\n\n``-D <macro>=<definition>``\n\tDefines a C preprocessor *<macro>*. This emulates the behavior of the\n\tcorresponding gcc option. All types of macros are supported,\n\tincluding the ones with parameters and variable arguments.\n\tStringification, token pasting and recursive macro expansion are also\n\tsupported.\n\tThis extends the function provided by ``-I`` option.\n\n``-h (<list>|default)``\n\tSpecifies a *<list>* of file extensions, separated by periods, which are\n\tto be interpreted as include (or header) files. To indicate files having\n\tno extension, use a period not followed by a non-period character\n\t(e.g. '``.``', ``..x``, ``.x.``).\n\n\tThis option only affects how the scoping of\n\tparticular kinds of tags are interpreted (i.e. whether or not they are\n\tconsidered as globally visible or visible only within the file in which\n\tthey are defined); it does not map the extension to any particular\n\tlanguage. Any tag which is located in a non-include file and cannot be\n\tseen (e.g. linked to) from another file is considered to have file-limited\n\t(e.g. static) scope. No kind of tag appearing in an include file\n\twill be considered to have file-limited scope.\n\n\tIf the first character in the list is '``+``', then the extensions in the list will be\n\tappended to the current list; otherwise, the list will replace the\n\tcurrent list. See, also, the ``fileScope``/``F`` flag of ``--extras`` option.\n\n\tThe default list is\n\t``.h.H.hh.hpp.hxx.h++.inc.def``. To restore the default list, specify \"``-h\n\tdefault``\".\n\n\tNote that if an extension supplied to this option is not\n\talready mapped to a particular language (see \"`Determining file language`_\", above),\n\tyou will also need to use either the ``--map-<LANG>``, ``--langmap`` or\n\t``--language-force`` option.\n\n``-I <identifier-list>``\n\tSpecifies a *<identifier-list>* of identifiers which are to be specially handled while\n\tparsing C and C++ source files. This option is specifically provided\n\tto handle special cases arising through the use of preprocessor macros.\n\tWhen the identifiers listed are simple identifiers, these identifiers\n\twill be ignored during parsing of the source files.\n\n\tIf an identifier is\n\tsuffixed with a '``+``' character (i.e. \"``-I FOO+``\"), ctags will also\n\tignore any parenthesis-enclosed argument list which may immediately\n\tfollow the identifier in the source files. See the example of \"``-I\n\tMODULE_VERSION+``\" below.\n\n\tIf two identifiers are\n\tseparated with the '``=``' character (i.e. ``-I FOO=BAR``), the first identifiers is replaced by\n\tthe second identifiers for parsing purposes. The list of identifiers may\n\tbe supplied directly on the command line or read in from a separate file.\n\tSee the example of \"``-I CLASS=class``\" below.\n\n\tIf the first character of *<identifier-list>* is '``@``', '``.``' or a pathname\n\tseparator ('``/``' or '``\\``'), or the first two characters specify a drive\n\tletter (e.g. ``C:``), the parameter *<identifier-list>* will be interpreted as\n\ta filename from which to read a list of identifiers, one per input line.\n\n\tOtherwise, *<identifier-list>* is a list of identifiers (or identifier\n\tpairs) to be specially handled, each delimited by either a comma or\n\tby white space (in which case the list should be quoted to keep the\n\tentire list as one command line argument).\n\n\tMultiple ``-I`` options may be\n\tsupplied. To clear the list of ignore identifiers, supply a single\n\tdash ('``-``') for *<identifier-list>*.\n\n\tThis feature is useful when preprocessor macros are used in such a way\n\tthat they cause syntactic confusion due to their presence. Indeed,\n\tthis is the best way of working around a number of problems caused by\n\tthe presence of syntax-busting macros in source files (see \"`CAVEATS`_\").\n\tSome examples will illustrate this point.\n\n\t.. code-block:: C\n\n\t\tint foo ARGDECL4(void *, ptr, long int, nbytes)\n\n\tIn the above example, the macro ``ARGDECL4`` would be mistakenly\n\tinterpreted to be the name of the function instead of the correct name\n\tof ``foo``. Specifying \"``-I ARGDECL4``\" results in the correct behavior.\n\n\t.. code-block:: C\n\n\t\t/* creates an RCS version string in module */\n\t\tMODULE_VERSION(\"$Revision$\")\n\n\tIn the above example the macro invocation looks too much like a function\n\tdefinition because it is not followed by a semicolon (indeed, it\n\tcould even be followed by a global variable definition that would look\n\tmuch like a K&R style function parameter declaration). In fact, this\n\tseeming function definition could possibly even cause the rest of the\n\tfile to be skipped over while trying to complete the definition.\n\tSpecifying \"``-I MODULE_VERSION+``\" would avoid such a problem.\n\n\t.. code-block:: C\n\n\t\tCLASS Example {\n\t\t\t// your content here\n\t\t};\n\n\tThe example above uses ``CLASS`` as a preprocessor macro which expands to\n\tsomething different for each platform. For instance ``CLASS`` may be\n\tdefined as ``class __declspec(dllexport)`` on Win32 platforms and simply\n\t``class`` on UNIX. Normally, the absence of the C++ keyword ``class``\n\twould cause the source file to be incorrectly parsed. Correct behavior\n\tcan be restored by specifying \"``-I CLASS=class``\".\n\n``--param-<LANG>.<name>=<argument>``\n\tSet a *<LANG>* specific parameter, a parameter specific to the *<LANG>*.\n\n\tAvailable parameters can be listed with ``--list-params``.\n\n.. _option_listing:\n\nListing Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--list-aliases[=(<language>|all)]``\n\tLists the aliases for either the specified *<language>* or ``all``\n\tlanguages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\tThe aliases are used when heuristically testing a language parser for a\n\tsource file.\n\n``--list-excludes``\n\tLists the current exclusion patterns used to exclude files.\n\n``--list-extras[=(<language>|NONE|all)]``\n\tLists the extras recognized for either the specified *<language>* or\n\t``all`` languages. If ``NONE`` is specified, it lists only extras\n\tcommon in all languages.\n\tSee \"`Extras`_\" subsection to know what are extras.\n\t``all`` is used as default value if the option argument is omitted.\n\n\tAn extra can be enabled or disabled with ``--extras=`` for common\n\textras in all languages, or ``--extras-<LANG>=`` for the specified\n\tlanguage.  These option takes one-letter flag or long-name flag as a parameter\n\tfor specifying an extra.\n\n\tThe meaning of columns in output are as follows:\n\n\tLETTER\n\t\tOne-letter flag. '``-``' means the extra does not have one-letter flag.\n\n\tNAME\n\t\tLong-name flag. The long-name is used in ``extras`` field.\n\n\tENABLED\n\t\tWhether the extra is enabled or not. It takes ``yes`` or ``no``.\n\n\tLANGUAGE\n\t\tThe name of language if the extra is owned by a parser.\n\t\t``NONE`` means the extra is common in parsers.\n\n\tVER\n\t\tThe ctags output version introducing the extra for a language-independent\n\t\textra, or the parser version introducing the extra for a\n\t\tlanguage-specified extra. See the ``--version`` option and\n\t\t``TAG_OUTPUT_VERSION`` in :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` about the ctags output\n\t\tversion.\n\n\t\t(since version 6.3.0)\n\n\tDESCRIPTION\n\t\tHuman readable description for the extra.\n\n``--list-features``\n\tLists the compiled features.\n\n``--list-fields[=(<language>|NONE|all)]``\n\tLists the fields recognized for either the specified *<language>* or\n\t``all`` languages. If ``NONE`` is specified, it lists only fields\n\tcommon in all languages.\n\tSee \"`Extension fields`_\" subsection to know what are fields.\n\t``all`` is used as default value if the option argument is omitted.\n\n\tThe meaning of columns are as follows:\n\n\tLETTER\n\t\tOne-letter flag. '``-``' means the field does not have one-letter flag.\n\n\tNAME\n\t\tLong-name of field.\n\n\tENABLED\n\t\tWhether the field is enabled or not. It takes ``yes`` or ``no``.\n\n\tLANGUAGE\n\t\tThe name of language if the field is owned by a parser.\n\t\t``NONE`` means that the field is a language-independent field which is\n\t\tcommon in all languages.\n\n\tJSTYPE\n\t\tJSON type used in printing the value of field when ``--output-format=json``\n\t\tis specified. See :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`.\n\n\tFIXED\n\t\tWhether this field can be disabled or not in tags output.\n\n\t\tSome fields are printed always in tags output.\n\t\tThey have ``yes`` as the value for this column.\n\n\t\tUnlike the tag output mode, JSON output mode allows disabling\n\t\tany fields.\n\n\tOP\n\t\tHow this field can be accessed from optscript code.\n\t\tThis field is for Universal Ctags developers.\n\n\tVER\n\t\tThe ctags output version introducing the field for a language-independent\n\t\tfield, or the parser version introducing the field for a\n\t\tlanguage-specified field. See the ``--version`` option and\n\t\t``TAG_OUTPUT_VERSION`` in :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` about the ctags output\n\t\tversion.\n\n\t\t(since version 6.3.0)\n\n\tDESCRIPTION\n\t\tHuman readable description for the field.\n\n``--list-kinds[=(<language>|all)]``\n\tSubset of ``--list-kinds-full``. This option is kept for\n\tbackward-compatibility with Exuberant Ctags.\n\n\tThis option prints only LETTER, DESCRIPTION, and ENABLED fields\n\tof ``--list-kinds-full`` output. However, the presentation of\n\tENABLED column is different from that of ``--list-kinds-full``\n\toption; ``[off]`` follows after description if the kind is disabled,\n\tand nothing follows\tif enabled. The most of all kinds are enabled\n\tby default.\n\n\tThe critical weakness of this option is that this option does not\n\tprint the name of kind. Universal Ctags introduces\n\t``--list-kinds-full`` because it considers that names are\n\timportant.\n\n\tThis option does not work with ``--machinable`` nor\n\t``--with-list-header``.\n\n``--list-kinds-full[=(<language>|all)]``\n\tLists the tag kinds recognized for either the specified *<language>*\n\tor ``all`` languages, and then exits. See \"`Kinds`_\" subsection to\n\tlearn what kinds are.\n\t``all`` is used as default value if the option argument is omitted.\n\n\tEach kind of tag recorded in the tag file is represented by a\n\tone-letter flag, or a long-name flag. They are also used to filter the tags\n\tplaced into the output through use of the ``--kinds-<LANG>``\n\toption.\n\n\tThe meaning of columns are as follows:\n\n\tLANGUAGE\n\t\tThe name of language having the kind.\n\n\tLETTER\n\t\tOne-letter flag. This must be unique in a language.\n\n\tNAME\n\t\tThe long-name flag of the kind. This can be used as the alternative\n\t\tto the one-letter flag described above. If enabling ``K`` field with\n\t\t``--fields=+K``, ctags uses long-names instead of\n\t\tone-letters in tags output. To enable/disable a kind with\n\t\t``--kinds-<LANG>`` option, long-name surrounded by braces instead\n\t\tof one-letter. See \"`Letters and names`_\" for details. This must be\n\t\tunique in a language.\n\n\tENABLED\n\t\tWhether the kind is enabled or not. It takes ``yes`` or ``no``.\n\n\tREFONLY\n\t\tWhether the kind is specialized for reference tagging or not.\n\t\tIf the column is ``yes``, the kind is for reference tagging, and\n\t\tit is never used for definition tagging. See also \"`TAG ENTRIES`_\".\n\n\tNROLES\n\t\tThe number of roles this kind has. See also \"`Roles`_\".\n\n\tMASTER\n\t\tThe master parser controlling enablement of the kind.\n\t\tA kind belongs to a language (owner) in Universal Ctags;\n\t\tenabling and disabling a kind in a language has no effect on\n\t\ta kind in another language even if both kinds has the\n\t\tsame one-letter flag and/or the same long-name flag. In other words,\n\t\tthe namespace of kinds are separated by language.\n\n\t\tHowever, Exuberant Ctags does not separate the kinds of C and\n\t\tC++. Enabling/disabling kindX in C language enables/disables a\n\t\tkind in C++ language having the same long-name flag with kindX. To\n\t\temulate this behavior in Universal Ctags, a concept named\n\t\t*master parser* is introduced. Enabling/disabling some kinds\n\t\tare synchronized under the control of a master language.\n\n\t\t.. code-block:: console\n\n\t\t\t$ ctags --kinds-C=+'{local}' --list-kinds-full \\\n\t\t\t  | grep -E '^(#|C\\+\\+ .* local)'\n\t\t\t#LANGUAGE  LETTER NAME   ENABLED REFONLY NROLES MASTER DESCRIPTION\n\t\t\tC++        l      local  yes     no      0      C      local variables\n\t\t\t$ ctags --kinds-C=-'{local}' --list-kinds-full \\\n\t\t\t  | grep -E '^(#|C\\+\\+ .* local)'\n\t\t\t#LANGUAGE  LETTER NAME   ENABLED REFONLY NROLES MASTER DESCRIPTION\n\t\t\tC++        l      local  no      no      0      C      local variables\n\n\t\tYou see ``ENABLED`` field of ``local`` kind of C++ language is changed\n\t\tThough ``local`` kind of C language is enabled/disabled. If you swap the languages, you\n\t\tsee the same result.\n\n\t\t.. TODO: need a reference to \"master parser\"\n\n\tVER\n\t\tThe parser version introducing the kind.\n\n\t\t(since version 6.3.0)\n\n\tDESCRIPTION\n\t\tHuman readable description for the kind.\n\n``--list-languages``\n\tLists the names of the languages understood by ctags,\n\tand then exits. These language names are case insensitive and may be\n\tused in many other options like ``--language-force``,\n\t``--languages``, ``--kinds-<LANG>``, ``--regex-<LANG>``, and so on.\n\n\tEach language listed is disabled if followed by ``[disabled]``.\n\tTo use the parser for such a language, specify the language as an\n\targument of ``--languages=+`` option.\n\n\t``--machinable`` and ``--with-list-header`` options are ignored if they are\n\tspecified with this option.\n\n``--list-map-extensions[=(<language>|all)]``\n\tLists the file extensions which associate a file\n\tname with a language for either the specified *<language>* or ``all``\n\tlanguages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n``--list-map-patterns[=(<language>|all)]``\n\tLists the file name patterns which associate a file\n\tname with a language for either the specified *<language>* or ``all``\n\tlanguages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n``--list-map-rexprs[=(<language>|all)]``\n\tLists the relative-path regular expressions which associate a file\n\tname with a language for either the specified *<language>* or ``all``\n\tlanguages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n\t(since version 6.3.0)\n\n``--list-maps[=(<language>|all)]``\n\tLists the file name patterns, the file extensions, and the relative-path\n\tregular expressions which associate a file name with a language for either\n\tthe specified *<language>* or ``all`` languages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n\tTo list the file extensions, file name patterns, or relative-path regular\n\texpressions individually, use ``--list-map-extensions``,\n\t``--list-map-patterns``, or ``--list-map-rexprs`` option.\n\n\tSee the ``--langmap`` option, and \"`Determining file language`_\", above.\n\n\tThis option does not work with ``--machinable`` nor\n\t``--with-list-header``.\n\n``--list-mline-regex-flags``\n\tOutput list of flags which can be used in a multiline regex parser\n\tdefinition.\n\tSee :ref:`ctags-optlib(7) <ctags-optlib(7)>`.\n\n``--list-output-formats``\n\tLists the output formats that can be used in ``--output-format`` option.\n\n\t``NULLTAG`` column represetns whether the format supports *null tags* or\n\tnot. See ``nulltag``/``z`` in \"`Extras`_\" about the null tags.\n\n\t(since version 6.2.0)\n\n``--list-params[=(<language>|all)]``\n\tLists the parameters for either the specified *<language>* or ``all``\n\tlanguages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n``--list-pseudo-tags``\n\tOutput list of pseudo-tags.\n\n``--list-regex-flags``\n\tLists the flags that can be used in ``--regex-<LANG>`` option.\n\tSee :ref:`ctags-optlib(7) <ctags-optlib(7)>`.\n\n``--list-roles[=(<language>|all)[.(<kind-specs>|*)]]``\n\tList the roles for either the specified *<language>* or ``all`` languages.\n\t``all`` is used as default value if the option argument is omitted.\n\n\tIf the parameter *<kindspecs>* is given after the parameter\n\t*<language>* or ``all`` with concatenating with '``.``', list only roles\n\tdefined in the kinds. Both one-letter flags and long name flags surrounded\n\tby braces are acceptable as the parameter *<kindspecs>*.\n\n\tThe meaning of columns are as follows:\n\n\tLANGUAGE\n\t\tThe name of language having the role.\n\n\tKIND(L/N)\n\t\tThe one-letter flag and the long-name flag of kind having the role.\n\n\tNAME\n\t\tThe long-name flag of the role.\n\n\tENABLED\n\t\tWhether the kind is enabled or not. It takes ``yes`` or ``no``.\n\n\tVER\n\t\tThe parser version introducing the role.\n\n\t\t(since version 6.3.0)\n\n\tDESCRIPTION\n\t\tHuman readable description for the role.\n\n``--list-subparsers[=(<baselang>|all)]``\n\tLists the subparsers for a base language for either the specified\n\t*<baselang>* or ``all`` languages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n``--machinable[=(yes|no)]``\n\tUse tab character as separators for ``--list-`` option output.  It\n\tmay be suitable for scripting. See \"`List options`_\" for considered\n\tuse cases. Disabled by default.\n\n``--with-list-header[=(yes|no)]``\n\tPrint headers describing columns in ``--list-`` option output.\n\tSee also \"`List options`_\".\n\n.. _option_misc:\n\nMiscellaneous Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``--describe-language=<language>``\n\tPrints the various aspects of the parser implementing the language.\n\n\t(since version 6.3.0)\n\n``--help``\n\tPrints to standard output a detailed usage description, and then exits.\n\n``-?``\n\tEquivalent to ``--help``.\n\n``--help-full``\n\tPrints to standard output a detailed usage description including experimental\n\tfeatures, and then exits. Visit https://docs.ctags.io/ for information\n\tabout the latest exciting experimental features.\n\n``--license``\n\tPrints a summary of the software license to standard output, and then exits.\n\n``--print-language``\n\tJust prints the language parsers for specified source files, and then exits.\n\n``--quiet[=(yes|no)]``\n\tWrite fewer messages (default is ``no``).\n\n``--totals[=(yes|no|extra)]``\n\tPrints statistics about the source files read and the tag file written\n\tduring the current invocation of ctags. This option\n\tis ``no`` by default.\n\n\tThe ``extra`` value prints parser specific statistics for parsers\n\tgathering such information.\n\n``--verbose[=(yes|no)]``\n\tEnable verbose mode. This prints out information on option processing\n\tand a brief message describing what action is being taken for each file\n\tconsidered by ctags. Normally, ctags\n\tdoes not read command line arguments until after options are read\n\tfrom the configuration files (see \"`FILES`_\", below).\n\tHowever, if this option is the first argument on\n\tthe command line, it will take effect before any options are read from\n\tthese sources. The default is ``no``.\n\n``-V``\n\tEquivalent to ``--verbose``.\n\n``--version[=<language>|NONE]``\n\tPrints a version identifier for ctags to standard\n\toutput, and then exits. This is guaranteed to always contain the string\n\t\"Universal Ctags\". See also the description for ``TAG_PROGRAM_VERSION``\n\tand ``TAG_OUTPUT_VERSION`` in :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`.\n\n\tIf ``NONE`` is given, prints the version identifier in a simplified way.\n\n\tIf *<language>* is given, print the version identifier for the parser\n\tfor *<language>*. See also the description for ``TAG_PARSER_VERSION`` in\n\t:ref:`ctags-client-tools(7) <ctags-client-tools(7)>`.\n\nObsoleted Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThese options are kept for backward-compatibility with Exuberant Ctags.\n\n``-w``\n\tThis option is silently ignored for backward-compatibility with the\n\tctags of SVR4 Unix.\n\n``--file-scope[=(yes|no)]``\n\tThis options is removed. Use ``--extras=[+|-]F`` or\n\t``--extras=[+|-]{fileScope}`` instead.\n\n``--extra=[+|-][<flags>|*]``\n\tEquivalent to ``--extras=[+|-][<flags>|*]``, which was introduced to make\n\tthe option naming convention align to the other options like\n\t``--kinds-<LANG>=`` and ``--fields=``.\n\n``--<LANG>-kinds=[+|-](<kinds>|*)``\n\tThis option is obsolete. Use ``--kinds-<LANG>=...`` instead.\n\nOPERATIONAL DETAILS\n-------------------\nAs ctags considers each source file name in turn, it tries to\ndetermine the language of the file by applying tests described in\n\"`Determining file language`_\".\n\nIf a language was identified, the file is opened and then the appropriate\nlanguage parser is called to operate on the currently open file. The parser\nparses through the file and adds an entry to the tag file for each\nlanguage object it is written to handle. See \"`TAG FILE FORMAT`_\", below,\nfor details on these entries.\n\nNotes for C/C++ Parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. TODO: move the following description to parser-cxx.rst.\n\nThis implementation of ctags imposes no formatting\nrequirements on C code as do legacy implementations. Older implementations\nof ctags tended to rely upon certain formatting assumptions in order to\nhelp it resolve coding dilemmas caused by preprocessor conditionals.\n\nIn general, ctags tries to be smart about conditional\npreprocessor directives. If a preprocessor conditional is encountered\nwithin a statement which defines a tag, ctags follows\nonly the first branch of that conditional (except in the special case of\n``#if 0``, in which case it follows only the last branch). The reason for\nthis is that failing to pursue only one branch can result in ambiguous\nsyntax, as in the following example:\n\n.. code-block:: C\n\n\t#ifdef TWO_ALTERNATIVES\n\tstruct {\n\t#else\n\tunion {\n\t#endif\n\t\tshort a;\n\t\tlong b;\n\t}\n\nBoth branches cannot be followed, or braces become unbalanced and\nctags would be unable to make sense of the syntax.\n\nIf the application of this heuristic fails to properly parse a file,\ngenerally due to complicated and inconsistent pairing within the\nconditionals, ctags will retry the file using a\ndifferent heuristic which does not selectively follow conditional\npreprocessor branches, but instead falls back to relying upon a closing\nbrace ('``}``') in column 1 as indicating the end of a block once any brace\nimbalance results from following a ``#if`` conditional branch.\n\nctags will also try to specially handle arguments lists\nenclosed in double sets of parentheses in order to accept the following\nconditional construct::\n\n\textern void foo __ARGS((int one, char two));\n\nAny name immediately preceding the '``((``' will be automatically ignored and\nthe previous name will be used.\n\nC++ operator definitions are specially handled. In order for consistency\nwith all types of operators (overloaded and conversion), the operator\nname in the tag file will always be preceded by the string \"operator \"\n(i.e. even if the actual operator definition was written as \"operator<<\").\n\nAfter creating or appending to the tag file, it is sorted by the tag name,\nremoving identical tag lines.\n\n.. _guessing:\n\nDetermining file language\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFile name mapping\n..........................\n\nUnless the ``--language-force`` option is specified, the language of each source\nfile is automatically selected based upon a *mapping* of file names to\nlanguages. The mappings in effect for each language may be displayed using\nthe ``--list-maps`` option and may be changed using the ``--langmap`` or\n``--map-<LANG>`` options.\n\nIf the name of a file is not mapped to a language, ctags tries\nto heuristically guess the language for the file by inspecting its content.\n\nAll files that have no file name mapping and no guessed parser are\nignored. This permits running ctags on all files in\neither a single directory (e.g.  \"``ctags *``\"), or on\nall files in an entire source directory tree\n(e.g. \"``ctags -R``\"), since only those files whose\nnames are mapped to languages will be scanned.\n\nAn extension may be mapped to multiple parsers. For example, ``.h``\nare mapped to C++, C and ObjectiveC. These mappings can cause\nissues. ctags tries to select the proper parser\nfor the source file by applying heuristics to its content, however\nit is not perfect.  In case of issues one can use ``--language-force=<language>``,\n``--langmap=<map>[,<map>[...]]``, or the ``--map-<LANG>=[+|-]<extension>|<pattern>|<rexpr>``\noptions. (Some of the heuristics are applied whether ``--guess-language-eagerly``\nis given or not.)\n\nThe order of testing is relative-path regular expressions (specified with\n``--map-<LANG>=<rexpr>``), file name patterns, then file extensions.\n\n.. TODO: all heuristics??? To be confirmed.\n\nHeuristically guessing\n..........................\n\nIf ctags cannot select a parser from the mapping of file names,\nvarious heuristic tests are conducted to determine the language:\n\ntemplate file name testing\n\tIf the file name has an ``.in`` extension, ctags applies\n\tthe mapping to the file name without the extension. For example,\n\t``config.h`` is tested for a file named ``config.h.in``.\n\n\"interpreter\" testing\n\tThe first line of the file is checked to see if the file is a ``#!``\n\tscript for a recognized language. ctags looks for\n\ta parser having the same name.\n\n\tIf ctags finds no such parser,\n\tctags looks for the name in alias lists. For\n\texample, consider if the first line is ``#!/bin/sh``.  Though\n\tctags has a \"shell\" parser, it doesn't have a \"sh\"\n\tparser. However, ``sh`` is listed as an alias for ``shell``, therefore\n\tctags selects the \"shell\" parser for the file.\n\n\tAn exception is ``env``. If ``env`` is specified (for example\n\t\"``#!/usr/bin/env python``\"), ctags\n\treads more lines to find real interpreter specification.\n\n\tTo display the list of aliases, use ``--list-aliases`` option.\n\tTo add an item to the list or to remove an item from the list, use the\n\t``--alias-<LANG>=+<pattern>`` or ``--alias-<LANG>=-<pattern>`` option\n\trespectively.\n\n\"zsh autoload tag\" testing\n\tIf the first line starts with ``#compdef`` or ``#autoload``,\n\tctags regards the line as \"zsh\".\n\n\"emacs mode at the first line\" testing\n\tThe Emacs editor has multiple editing modes specialized for programming\n\tlanguages. Emacs can recognize a marker called modeline in a file\n\tand utilize the marker for the mode selection. This heuristic test does\n\tthe same as what Emacs does.\n\n\tctags treats ``MODE`` as a name of interpreter and applies the same\n\trule of \"interpreter\" testing if the first line has one of\n\tthe following patterns::\n\n\t\t-*- mode: MODE -*-\n\n\tor\n\n\t::\n\n\t\t-*- MODE -*-\n\n\"emacs mode at the EOF\" testing\n\tEmacs editor recognizes another marker at the end of file as a\n\tmode specifier. This heuristic test does the same as what Emacs does.\n\n\tctags treats ``MODE`` as a name of an interpreter and applies the same\n\trule of \"interpreter\" heuristic testing, if the lines at the tail of the file\n\thave the following pattern::\n\n\t\tLocal Variables:\n\t\t...\n\t\tmode: MODE\n\t\t...\n\t\tEnd:\n\n\t3000 characters are sought from the end of file to find the pattern.\n\n\"vim modeline\" testing\n\tLike the modeline of the Emacs editor, Vim editor has the same concept.\n\tctags treats ``TYPE`` as a name of interpreter and applies the same\n\trule of \"interpreter\" heuristic testing if the first or last 5 lines of the file\n\thave one of the following patterns::\n\n\t\tfiletype=TYPE\n\n\tor\n\n\t::\n\n\t\tft=TYPE\n\n\"PHP marker\" testing\n\tIf the first line is started with ``<?php``,\n\tctags regards the line as \"php\".\n\nLooking into the file contents is a more expensive operation than file\nname matching. So ctags runs the testings in limited\nconditions.  \"interpreter\" testing is enabled only when a file is an\nexecutable or the ``--guess-language-eagerly`` (``-G`` in short) option is\ngiven. The other heuristic tests are enabled only when ``-G`` option is\ngiven.\n\nThe ``--print-language`` option can be used just to print the results of\nparser selections for given files instead of generating a tags file.\n\nExamples:\n\n.. code-block:: console\n\n\t$ ctags --print-language config.h.in input.m input.unknown\n\tconfig.h.in: C++\n\tinput.m: MatLab\n\tinput.unknown: NONE\n\n``NONE`` means that ctags does not select any parser for the file.\n\nTAG FILE FORMAT\n---------------\n\nThis section describes the tag file format briefly.  See :ref:`tags(5) <tags(5)>` and\n:ref:`ctags-client-tools(7) <ctags-client-tools(7)>` for more details.\n\nWhen not running in etags mode, each entry in the tag file consists of a\nseparate line, each looking like this, called *regular tags*, in the most general case:\n\n::\n\n\t<tag_name><TAB><file_name><TAB><ex_cmd>;\"<TAB><extension_fields>\n\nThe fields and separators of these lines are specified as follows:\n\n\t1.\t``<tag_name>``: tag name\n\t2.\t``<TAB>``: single tab character\n\t3.\t``<file_name>``: name of the file in which the object associated with the tag is located\n\t4.\t``<TAB>``: single tab character\n\t5.\t``<ex_cmd>``: EX command used to locate the tag within the file; generally a\n\t\tsearch pattern (either ``/pattern/`` or ``?pattern?``) or line number (see\n\t\t``--excmd=<type>`` option).\n\t6.\t``;\"<TAB><extension_fields>``: a set of extension fields. See\n\t\t\"`Extension fields`_\" for more details.\n\n\t\tTag file format 2 (see ``--format``) extends the EX command\n\t\tto include the extension fields embedded in an EX comment immediately appended\n\t\tto the EX command, which leaves it backward-compatible with original\n\t\t``vi(1)`` implementations.\n\nA few special tags, called *pseudo tags*, are written into the tag file for internal purposes.\n\n::\n\n\t!_TAG_FILE_FORMAT       2       /extended format; --format=1 will not append ;\" to lines/\n\t!_TAG_FILE_SORTED       1       /0=unsorted, 1=sorted, 2=foldcase/\n\t...\n\n``--pseudo-tags=[+|-](<pseudo-tag>|*)`` option enables or disables emitting pseudo-tags.\n\nSee the output of \"``ctags --list-pseudo-tags``\" for the list of\nthe kinds.\nSee also :ref:`tags(5) <tags(5)>` and :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` for more details of the pseudo tags.\n\nThese tags are composed in such a way that they always sort to the top of\nthe file. Therefore, the first two characters of these tags are used a magic\nnumber to detect a tag file for purposes of determining whether a\nvalid tag file is being overwritten rather than a source file.\n\nNote that the name of each source file will be recorded in the tag file\nexactly as it appears on the command line. Therefore, if the path you\nspecified on the command line was relative to the current directory, then\nit will be recorded in that same manner in the tag file. See, however,\nthe ``--tag-relative=(yes|no|always|never)`` option for how this behavior can be\nmodified.\n\n.. _tag_entries:\n\nTAG ENTRIES\n-----------\n\nA tag is an index for a language object. The concept of a tag and related\nitems in Exuberant Ctags are refined and extended in Universal Ctags.\n\nA tag is categorized into *definition tags* or *reference tags*.\nIn general, Exuberant Ctags only tags *definitions* of\nlanguage objects: places where newly named language objects *are introduced*.\nUniversal Ctags, on the other hand, can also tag *references* of language\nobjects: places where named language objects *are used*. However, support\nfor generating reference tags is new and limited to specific areas of\nspecific languages in the current version.\n\nExtension fields\n~~~~~~~~~~~~~~~~\n\nA tag can record various information, called *extension fields*.\n\nExtension fields are tab-separated key-value pairs appended to the end of\nthe EX command as a comment, as described above. These key value pairs\nappear in the general form ``key:value``.\n\nIn addition, information on the scope of the tag definition may be\navailable, with the key portion equal to some language-dependent construct\nname and its value the name declared for that construct in the program.\nThis scope entry indicates the scope in which the tag was found.\nFor example, a tag generated for a C structure member would have a scope\nlooking like ``struct:myStruct``.\n\n``--fields=[+|-][<flags>|*]`` and ``--fields-(<LANG>|all)=[+|-][<flags>|*]`` options specifies\nwhich available extension fields are to be included in the tag entries.\n\nSee the output of \"``ctags --list-fields``\" for the list of\nextension fields.\nThe essential fields are ``name``, ``input``, ``pattern``, and ``line``.\nThe meaning of major fields is as follows (long-name flag/one-letter flag):\n\n``access``/``a``\n\tIndicates the visibility of this class member, where value is specific\n\tto the language.\n\n``end``/``e``\n\tIndicates the line number of the end lines of the language object.\n\n``extras``/``E``\n\tExtra tag type information. See \"`Extras`_\" for details.\n\n``file``/``f``\n\tIndicates that the tag has file-limited visibility. This key has no\n\tcorresponding value. Enabled by default.\n\n``implementation``/``m``\n\tWhen present, this indicates a limited implementation (abstract vs.\n\tconcrete) of a routine or class, where value is specific to the\n\tlanguage (``virtual`` or ``pure virtual`` for C++; ``abstract`` for Java).\n\n``inherits``/``i``\n\tWhen present, value is a comma-separated list of classes from which\n\tthis class is derived (i.e. inherits from).\n\n``input``/``F``\n\tThe name of source file where ``name`` is defined or referenced.\n\n``k``\n\t`Kind <Kinds>`_ of tag as one-letter. Enabled by default.\n\tThis field has no long-name.\n\tSee also ``kind``/``z`` flag.\n\n``K``\n\t`Kind <Kinds>`_ of tag as long-name.\n\tThis field has no long-name.\n\tSee also ``kind``/``z`` flag.\n\n``kind``/``z``\n\tInclude the ``kind:`` key in `kind field <Kinds>`_.  See also ``k`` and ``K`` flags.\n\n``language``/``l``\n\tLanguage of source file containing tag\n\n``line``/``n``\n\tThe line number where ``name`` is defined or referenced in ``input``.\n\n``name``/``N``\n\tThe name of language objects.\n\n``nth``/``o``\n\tThe order in the parent scope.\n\t(i.e. 4th parameter in the function).\n\n``pattern``/``P``\n\tCan be used to search the ``name`` in ``input``\n\n``roles``/``r``\n\tRoles assigned to the tag. See \"`Roles`_\" for more details.\n\n``s``\n\tScope of tag definition. Enabled by default.\n\tThis field has no long-name.\n\tSee also ``scope``/``Z`` flag.\n\n``scope``/``Z``\n\tPrepend the ``scope:`` key to scope (``s``) field.\n\tSee also ``s`` flag.\n\n``scopeKind``/``p``\n\tKind of scope as long-name\n\n``signature``/``S``\n\tWhen present, value is a language-dependent representation of the\n\tsignature of a routine (e.g. prototype or parameter list). A routine signature in its complete form\n\tspecifies the return type of a routine and its formal argument list.\n\tThis extension field is presently supported only for C-based\n\tlanguages and does not include the return type.\n\n``typeref``/``t``\n\tType and name of a variable, typedef, or return type of\n\tcallable like function as ``typeref:`` field.\n\tEnabled by default.\n\nKinds\n......\n\n``kind`` is a field which represents the *kind* of language object\nspecified by a tag. Kinds used and defined are very different between\nparsers. For example, C language defines ``macro``, ``function``,\n``variable``, ``typedef``, etc.\n\n``--kinds-(<LANG>|all)=[+|-](<kinds>|*)`` option specifies a list of language-specific\nkinds of tags (or kinds) to include in the output file for a particular\nlanguage.\n\nSee the output of \"``ctags --list-kinds-full``\" for the complete\nlist of the kinds.\n\nIts value is either one of the\ncorresponding one-letter flags or a long-name flag. It is permitted\n(and is, in fact, the default) for the key portion of this field to be\nomitted. The optional behaviors are controlled with the ``--fields`` option as follows.\n\n.. code-block:: console\n\n\t$ ctags -o - kinds.c\n\tfoo     kinds.c /^int foo() {$/;\"       f       typeref:typename:int\n\t$ ctags --fields=+k -o - kinds.c\n\tfoo     kinds.c /^int foo() {$/;\"       f       typeref:typename:int\n\t$ ctags --fields=+K -o - kinds.c\n\tfoo     kinds.c /^int foo() {$/;\"       function        typeref:typename:int\n\t$ ctags --fields=+z -o - kinds.c\n\tfoo     kinds.c /^int foo() {$/;\"       kind:f  typeref:typename:int\n\t$ ctags --fields=+zK -o - kinds.c\n\tfoo     kinds.c /^int foo() {$/;\"       kind:function   typeref:typename:int\n\nRoles\n......\n\n*Role* is a newly introduced concept in Universal Ctags. Role is a\nconcept associated with reference tags, and is not implemented widely yet.\n\nAs described previously in \"`Kinds`_\", the ``kind`` field represents the type\nof language object specified with a tag, such as a function vs. a variable.\nSpecific kinds are defined for reference tags, such as the C++ kind ``header`` for\nheader file, or Java kind ``package`` for package statements. For such reference\nkinds, a ``roles`` field can be added to distinguish the role of the reference\nkind. In other words, the ``kind`` field identifies the *what* of the language\nobject, whereas the ``roles`` field identifies the *how* of a referenced language\nobject. Roles are only used with specific kinds.\n\nFor a definition tag, this field takes ``def`` as a value.\n\nFor example, ``Baz`` is tagged as a reference tag with kind ``package`` and with\nrole ``imported`` with the following code.\n\n.. code-block:: java\n\n\tpackage Bar;\n\timport Baz;\n\n\tclass Foo {\n\t\t\t// ...\n\t}\n\n.. code-block:: console\n\n\t$ ctags --fields=+KEr -uo - roles.java\n\tBar     roles.java     /^package Bar;$/;\"      package roles:def\n\tFoo     roles.java     /^class Foo {$/;\"       class   roles:def\n\t$ ctags --fields=+EKr --extras=+r -uo - roles.java\n\tBar     roles.java     /^package Bar;$/;\"      package roles:def\n\tBaz     roles.java     /^import Baz;$/;\"       package roles:imported  extras:reference\n\tFoo     roles.java     /^class Foo {$/;\"       class   roles:def\n\n``--roles-(<LANG>|all).(<kind>|all)=[+|-][<roles>|*]`` option specifies a list of kind-specific\nroles of tags to include in the output file for a particular language.\n\nInquire the output of \"``ctags --list-roles``\" for the list of\nroles.\n\n.. _extras:\n\nExtras\n~~~~~~\n\nGenerally, ctags tags only language objects appearing\nin source files, as is. In other words, a value for a ``name:`` field\nshould be found on the source file associated with the ``name:``. An\n``extra`` type tag (*extra*) is for tagging a language object with a processed\nname, or for tagging something not associated with a language object. A typical\nextra tag is ``qualified``, which tags a language object with a\nclass-qualified or scope-qualified name.\n\n``--extras-(<LANG>|all)=[+|-][<flags>|*]`` option specifies\nwhether to include extra tag entries for certain kinds of information.\n\nInquire the output of ``ctags --list-extras`` for the list of extras.\nThe meaning of major extras is as follows (long-name flag/one-letter flag):\n\n``anonymous``/none\n\tInclude an entry for the language object that has no name like lambda\n\tfunction. This extra has no one-letter flag and is enabled by\n\tdefault.\n\n\tThe extra tag is useful as a placeholder to fill scope fields\n\tfor language objects defined in a language object with no name.\n\n\t.. code-block:: C\n\n\t\tstruct {\n\t\t\tdouble x, y;\n\t\t} p = { .x = 0.0, .y = 0.0 };\n\n\t'``x``' and '``y``' are the members of a structure. When filling the scope\n\tfields for them, ctags has trouble because the struct\n\twhere '``x``' and '``y``' belong to has no name. For overcoming the trouble,\n\tctags generates an anonymous extra tag for the struct\n\tand fills the scope fields with the name of the extra tag.\n\n\t.. code-block:: console\n\n\t\t$ ctags --fields=-f -uo - input.c\n\t\t__anon9f26d2460108\tinput.c\t/^struct {$/;\"\ts\n\t\tx\tinput.c\t/^\tdouble x, y;$/;\"\tm\tstruct:__anon9f26d2460108\n\t\ty\tinput.c\t/^\tdouble x, y;$/;\"\tm\tstruct:__anon9f26d2460108\n\t\tp\tinput.c\t/^} p = { .x = 0.0, .y = 0.0 };$/;\"\tv\ttyperef:struct:__anon9f26d2460108\n\n\tThe above tag output has ``__anon9f26d2460108`` as an anonymous extra tag.\n\tThe typeref field of '``p``' also receives the benefit of it.\n\n``fileScope``/``F``\n\tIndicates whether tags scoped only for a single file (i.e. tags which\n\tcannot be seen outside of the file in which they are defined, such as\n\tlanguage objects with ``static`` modifier of C language) should be included\n\tin the output. See also the ``-h`` option.\n\n\tThis extra tag is enabled by default. Add ``--extras=-F`` option not to\n\toutput tags scoped only for a single-file. This is the replacement for\n\t``--file-scope`` option of Exuberant Ctags.\n\n\t.. code-block:: c\n\n\t\tstatic int f() {\n\t\t\treturn 0;\n\t\t}\n\t\tint g() {\n\t\t\treturn 0;\n\t\t}\n\n\t.. code-block:: console\n\n\t\t$ ctags -uo - filescope.c\n\t\tf       filescope.c     /^static int f() {$/;\"  f       typeref:typename:int    file:\n\t\tg       filescope.c     /^int g() {$/;\" f       typeref:typename:int\n\t\t$ ctags --extras=-F -uo - filescope.c\n\t\tg       filescope.c     /^int g() {$/;\" f       typeref:typename:int\n\n``inputFile``/``f``\n\tInclude an entry for the base file name of every source file\n\t(e.g. ``example.c``), which addresses the first line of the file.\n\tThis flag is the replacement for ``--file-tags`` hidden option of\n\tExuberant Ctags.\n\n\tIf the ``end:`` field is enabled, the end line number of the file can be\n\tattached to the tag. (However, ctags omits the ``end:`` field\n\tif no newline is in the file like an empty file.)\n\n\tBy default, ctags doesn't create the ``inputFile``/``f`` extra\n\ttag for the source file when ctags doesn't find a parser\n\tfor it. Enabling ``Unknown`` parser with ``--languages=+Unknown`` forces\n\tctags to create the extra tags for any source files.\n\n\tThe etags mode enables the ``Unknown`` parser implicitly.\n\n``nulltag``/``z``\n\tInclude tags (*null tags*) having empty strings as their names.\n\tGenerally speaking, trying to make a null tag is a sign of a parser bug\n\tor broken input. ctags warns such trying or throws the\n\tnull tag away. To suppress the warnings, use ``--quiet`` option.\n\n\tOn the other hand, null tags are valid in some languages.\n\tConsider ``{\"\":  val}`` in a JavaScript sourece code. The empty string is\n\tvalid as a key. If a parser intentionally makes a null tag (a valid null tag),\n\tctags doesn't warn but discard it by default.\n\n\tThe discards are due because some output formats may not consider null tags.\n\n\tWith ``nulltag``/``z`` extra, you can force ctags to emit the nulltags. This extra\n\tis effective only if the output format supports null tags. ``--list-output-formats``\n\toption tells you which output formats support null tags.\n\n\t(since version 6.2.0)\n\n``pseudo``/``p``\n\tInclude pseudo-tags. Enabled by default unless the tag file is\n\twritten to standard output. See :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` about\n\tthe detail of pseudo-tags.\n\n``qualified``/``q``\n\tInclude an extra class-qualified or namespace-qualified tag entry\n\tfor each tag which is a member of a class or a namespace.\n\n\tThis may allow easier location of a specific tags when\n\tmultiple occurrences of a tag name occur in the tag file.\n\tNote, however, that this could potentially more than double\n\tthe size of the tag file.\n\n\tThe actual form of the qualified tag depends upon the language\n\tfrom which the tag was derived (using a form that is most\n\tnatural for how qualified calls are specified in the\n\tlanguage). For C++ and Perl, it is in the form\n\t``class::member``; for Eiffel and Java, it is in the form\n\t``class.member``.\n\n\tNote: Using backslash characters as separators forming\n\tqualified name in PHP. However, in tags output of\n\tUniversal Ctags, a backslash character in a name is escaped\n\twith a backslash character. See :ref:`tags(5) <tags(5)>` about the escaping.\n\n\tThe following example demonstrates the ``qualified`` extra tag.\n\n\t.. code-block:: Java\n\n\t\tclass point {\n\t\t\tdouble x;\n\t\t};\n\n\tFor the above source file, ctags tags ``point`` and ``x`` by\n\tdefault.  If the ``qualified`` extra is enabled from the command line\n\t(``--extras=+q``), then ``point.x`` is also tagged even though the string\n\t\"``point.x``\" is not in the source code.\n\n\t.. code-block:: console\n\n\t\t$ ctags --fields=+K -uo - qualified.java\n\t\tpoint   qualified.java  /^class point {$/;\"     class\n\t\tx       qualified.java  /^      double x;$/;\"   field   class:point\n\t\t$ ctags --fields=+K --extras=+q -uo - qualified.java\n\t\tpoint   qualified.java  /^class point {$/;\"     class\n\t\tx       qualified.java  /^      double x;$/;\"   field   class:point\n\t\tpoint.x qualified.java  /^      double x;$/;\"   field   class:point\n\n``reference``/``r``\n\tInclude reference tags. See \"`TAG ENTRIES`_\" about reference tags.\n\n\tThe following example demonstrates the ``reference`` extra tag.\n\n\t.. code-block:: c\n\n\t\t#include <stdio.h>\n\t\t#include \"utils.h\"\n\t\t#define X\n\t\t#undef X\n\n\tThe ``roles:system`` or ``roles:local`` fields will be\n\tadded depending on whether the include file name begins with '``<``' or not.\n\n\t\"``#define X``\" emits a definition tag. On the other hand \"``#undef X``\" emits a\n\treference tag.\n\n\t.. code-block:: console\n\n\t\t$ ctags --fields=+EKr -uo - inc.c\n\t\tX       inc.c   /^#define X$/;\" macro   file:   roles:def       extras:fileScope\n\t\t$ ctags --fields=+EKr --extras=+r -uo - inc.c\n\t\tstdio.h inc.c   /^#include <stdio.h>/;\" header  roles:system    extras:reference\n\t\tutils.h inc.c   /^#include \"utils.h\"/;\" header  roles:local     extras:reference\n\t\tX       inc.c   /^#define X$/;\" macro   file:   roles:def       extras:fileScope\n\t\tX       inc.c   /^#undef X$/;\"  macro   file:   roles:undef     extras:fileScope,reference\n\nLanguage-specific fields and extras\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nExuberant Ctags has the concept of *fields* and *extras*. They are common\nbetween parsers of different languages. Universal Ctags extends this concept\nby providing language-specific fields and extras.\n\n.. Note: kinds are language-specific since e-ctags. roles are new to u-ctags.\n\n.. TODO: move the following \"Hot to ...\" sections to FAQ man page when available\n\nHOW TO USE WITH VI\n------------------\n\n``vi(1)`` will, by default, expect a tag file by the name ``tags`` in the current\ndirectory. Once the tag file is built, the following commands exercise\nthe tag indexing feature:\n\n``vi -t tag``\n\tStart vi and position the cursor at the file and line where ``tag``\n\tis defined.\n\n``:ta tag``\n\tFind a tag.\n\n``Ctrl-]``\n\tFind the tag under the cursor.\n\n``Ctrl-T``\n\tReturn to previous location before jump to tag (not widely implemented).\n\n\nHOW TO USE WITH GNU EMACS\n-------------------------\n\n``emacs(1)`` will, by default, expect a tag file by the name ``TAGS`` in the\ncurrent directory. Once the tag file is built, the following commands\nexercise the tag indexing feature:\n\n``M-x visit-tags-table <RET> FILE <RET>``\n\tSelect the tag file, ``FILE``, to use.\n\n``M-. [TAG] <RET>``\n\tFind the first definition of TAG. The default tag is the identifier\n\tunder the cursor.\n\n``M-*``\n\tPop back to where you previously invoked ``M-.``.\n\n``C-u M-.``\n\tFind the next definition for the last tag.\n\nFor more commands, see the Tags topic in the Emacs info document.\n\n\nHOW TO USE WITH NEDIT\n---------------------\n\nNEdit version 5.1 and later can handle the new extended tag file format\n(see ``--format``).\n\n* To make NEdit use the tag file, select \"File->Load Tags File\".\n* To jump to the definition for a tag, highlight the word, then press ``Ctrl-D``.\n\nNEdit 5.1 can read multiple tag files from different\ndirectories. Setting the X resource ``nedit.tagFile`` to the name of a tag\nfile instructs NEdit to automatically load that tag file at startup time.\n\n\nCAVEATS\n-------\n\nBecause ctags is neither a preprocessor nor a compiler,\nuse of preprocessor macros can fool ctags into either\nmissing tags or improperly generating inappropriate tags. Although\nctags has been designed to handle certain common cases,\nthis is the single biggest cause of reported problems. In particular,\nthe use of preprocessor constructs which alter the textual syntax of C\ncan fool ctags. You can work around many such problems\nby using the ``-I`` option.\n\nNote that since ctags generates patterns for locating\ntags (see the ``--excmd`` option), it is entirely possible that the wrong line\nmay be found by your editor if there exists another source line which is\nidentical to the line containing the tag. The following example\ndemonstrates this condition:\n\n.. code-block:: C\n\n\tint variable;\n\n\t/* ... */\n\tvoid foo(variable)\n\tint variable;\n\t{\n\t\t/* ... */\n\t}\n\nDepending upon which editor you use and where in the code you happen to be,\nit is possible that the search pattern may locate the local parameter\ndeclaration before it finds the actual global variable definition,\nsince the lines (and therefore their search patterns) are\nidentical.\n\nThis can be avoided by use of the ``--excmd=n`` option.\n\nINCOMPATIBLE CHANGES\n--------------------\nSee :ref:`ctags-incompatibilities(7) <ctags-incompatibilities(7)>` about incompatibilities between Universal\nCtags and Exuberant Ctags.\n\nThis section describes major incompatibilities within versions of Universal\nCtags.\n\nUnifying the kind Letter for ``unknown`` kinds\n\tSome parsers used different kind letters for ``unknown`` kinds.\n\tEmacsLisp used ``u``. Go used ``u``. Julian used ``x``. Lisp used ``u``.\n\tLua used ``X``. and Python used ``x``. They were unified to ``Y`` in\n\tthe during development of version 5.9.x.\n\nBUGS\n----\n\nctags has more options than ``ls(1)``.\n\nctags assumes the input file is written in the correct\ngrammar.  Otherwise output of ctags is undefined. In other words it has garbage\nin, garbage out (GIGO) feature.\n\n.. TODO: move the following paragraph to parser-cxx.rst.\n\nWhen parsing a C++ member function definition (e.g. ``className::function``),\nctags cannot determine whether the scope specifier\nis a class name or a namespace specifier and always lists it as a class name\nin the scope portion of the extension fields. Also, if a C++ function\nis defined outside of the class declaration (the usual case), the access\nspecification (i.e. public, protected, or private) and implementation\ninformation (e.g. virtual, pure virtual) contained in the function\ndeclaration are not known when the tag is generated for the function\ndefinition. It will, however be available for prototypes (e.g. ``--kinds-c++=+p``).\n\nNo qualified tags are generated for language objects inherited into a class.\n\nENVIRONMENT VARIABLES\n---------------------\n``TMPDIR``\n\tOn Unix-like hosts where ``mkstemp(3)`` is available, the value of this\n\tvariable specifies the directory in which to place temporary files.\n\tThis can be useful if the size of a temporary file becomes too large\n\tto fit on the partition holding the default temporary directory\n\tdefined at compilation time.\n\n\tctags creates temporary\n\tfiles only if either (1) an emacs-style tag file is being\n\tgenerated, (2) the tag file is being sent to standard output, or\n\t(3) the program was compiled to use an internal sort algorithm to sort\n\tthe tag files instead of the ``sort(1)`` utility of the operating system.\n\tIf the ``sort(1)`` utility of the operating system is being used, it will\n\tgenerally observe this variable also.\n\n\tNote that if ctags\n\tis setuid, the value of ``TMPDIR`` will be ignored.\n\n\nFILES\n-----\n\nOutput files\n~~~~~~~~~~~~\n\n``tags``\n\tThe default tag file created by ctags.\n\n``TAGS``\n\tThe default tag file created by etags.\n\nPreloading option files\n~~~~~~~~~~~~~~~~~~~~~~~\n\n``$XDG_CONFIG_HOME/ctags/*.ctags``, or ``$HOME/.config/ctags/*.ctags`` if\n``$XDG_CONFIG_HOME`` is not defined\n\n``$HOME/.ctags.d/*.ctags``\n\n``$HOMEDRIVE$HOMEPATH/ctags.d/*.ctags`` (on MS Windows only)\n\n``.ctags.d/*.ctags``\n\n``ctags.d/*.ctags``\n\n\tIf any of these configuration files exist, each will be expected to\n\tcontain a set of default options which are read in the order listed\n\twhen ctags starts, but before any command line options\n\tare read. This makes it possible to set up personal or project-level defaults.\n\n\tIt\n\tis possible to compile ctags to read an additional\n\tconfiguration file before any of those shown above, which will be\n\tindicated if the output produced by the ``--version`` option lists the\n\t``custom-conf`` feature.\n\n\tOptions appearing on the command line will override options\n\tspecified in these files. Only options will be read from these\n\tfiles.\n\n\tNote that the option\n\tfiles are read in line-oriented mode in which spaces are significant\n\t(since shell quoting is not possible) but spaces at the beginning\n\tof a line are ignored. Each line of the file is read as\n\tone command line parameter (as if it were quoted with single quotes).\n\tTherefore, use new lines to indicate separate command-line arguments.\n\n\tA line starting with '``#``' is treated as a comment.\n\n\t``*.ctags`` files in a directory are loaded in alphabetical order.\n\nDefault optlib path list\n~~~~~~~~~~~~~~~~~~~~~~~~\n\n``$XDG_CONFIG_HOME/ctags``, or ``$HOME/.config/ctags`` if\n``$XDG_CONFIG_HOME`` is not defined\n\n``$HOME/.ctags.d``\n\n``$HOMEDRIVE$HOMEPATH/ctags.d`` (on MS Windows only)\n\n\tThese directories are parts of the optlib path list by default.\n\tSee \"`Option File Options`_\" about the optlib path list.\n\n\tIf you have a set of options that you want to enable\n\tconditionally, make a directory in the path in the optlib path\n\tlist, and put the options to the files having .ctags as extensions\n\tunder the directory. ``--options=<the-directory-name>`` is for\n\tenabling the options.\n\n\tFor example, consider you have some options you want to enable\n\tonly when tagging the Linux kernel source tree.  In that case,\n\tmake ``$HOME/.ctags.d/linux`` directory, put the options to\n\t``$HOME/.ctags.d/linux/my.ctags``. If you have many options, you\n\tcan split them into multiple files like\n\t``$HOME/.ctags.d/linux/device-driver.ctags`` and\n\t``$HOME/.ctags.d/linux/network-stack.ctags``. Either way, you can\n\tenable the options in the .ctags file(s) under the directory by\n\tadding ``--options=linux`` to your ctags command line.\n\nSEE ALSO\n--------\n\nSee :ref:`ctags-optlib(7) <ctags-optlib(7)>` for defining (or extending) a parser\nin a configuration file.\n\nSee :ref:`tags(5) <tags(5)>` for the format of tag files.\n\nSee :ref:`ctags-incompatibilities(7) <ctags-incompatibilities(7)>` about known incompatible changes\nwith Exuberant Ctags.\n\nSee :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` if you are interested in writing\na tool for processing tags files.\n\nSee :ref:`ctags-lang-python(7) <ctags-lang-python(7)>` about python input specific notes.\n\nSee :ref:`readtags(1) <readtags(1)>` about a client tool for binary searching a\nname in a sorted tags file.\n\nThe official Universal Ctags web site at: https://ctags.io/\n\nAlso ``ex(1)``, ``vi(1)``, ``elvis(1)``, or, better yet, ``vim(1)``, the official editor of ctags.\nFor more information on ``vim(1)``, see the Vim web site at: https://www.vim.org/\n\nAbout the file format for ``TAGS``, see `emacs git\n<https://git.savannah.gnu.org/cgit/emacs.git/tree/etc/ETAGS.EBNF>`_.\n\nAUTHOR\n------\n\nUniversal Ctags project\nhttps://ctags.io/\n\nDarren Hiebert <dhiebert@users.sourceforge.net>\nhttp://DarrenHiebert.com/\n\n\nMOTIVATION\n----------\n\n\"Think ye at all times of rendering some service to every member of the\nhuman race.\"\n\n\"All effort and exertion put forth by man from the fullness of his heart is\nworship, if it is prompted by the highest motives and the will to do\nservice to humanity.\"\n\n-- From the Baha'i Writings\n\nCREDITS\n-------\nThis version of ctags (Universal Ctags) derived from\nthe repository, known as fishman-ctags, started by Reza Jelveh.\n\nThe fishman-ctags was derived from Exuberant Ctags.\n\nSome parsers are taken from ``tagmanager`` of the Geany (https://www.geany.org/)\nproject.\n\nExuberant Ctags was originally derived from and\ninspired by the ctags program by Steve Kirkendall <kirkenda@cs.pdx.edu>\nthat comes with the Elvis vi clone (though virtually none of the original\ncode remains).\n\nCredit is also due Bram Moolenaar <Bram@vim.org>, the author of vim,\nwho has devoted so much of his time and energy both to developing the editor\nas a service to others, and to helping the orphans of Uganda.\n\nThe section entitled \"`HOW TO USE WITH GNU EMACS`_\" was shamelessly stolen\nfrom the info page for GNU etags.\n"
  },
  {
    "path": "docs/man/readtags.1.rst",
    "content": ".. _readtags(1):\n\n==============================================================\nreadtags\n==============================================================\n\nFind tag file entries matching specified names\n\n:Version: 6.2.0\n:Manual group: Universal Ctags\n:Manual section: 1\n\nSYNOPSIS\n--------\n|\t**readtags** -h | --help\n|\t**readtags** (-H | --help-expression) (filter|sorter|formatter)\n|\t**readtags** -v | --version\n|\t**readtags** [OPTION]... ACTION\n\nDESCRIPTION\n-----------\nThe **readtags** program filters, sorts and prints tag entries in a tags file.\nThe basic filtering is done using **actions**, by which you can list all\nregular tags, pseudo tags or regular tags matching specific name. Then, further\nfiltering, sorting, and formatting can be done using **post processors**, namely\n**filter expressions**, **sorter expressions**, and **formatter expressions**.\n\nACTIONS\n-------\n``-l``, ``--list``\n\tList regular tags.\n\n``[-] NAME``\n\tList regular tags matching NAME.\n\t\"-\" as NAME indicates arguments after this as NAME even if they start with -.\n\n``-D``, ``--list-pseudo-tags``\n\tList pseudo tags.\n\tYou can use this option with ``-Q`` option to extract specified pseudo tags.\n\nOPTIONS\n-------\n\nControlling the Tags Reading Behavior\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe behavior of reading tags can be controlled using these options:\n\n``-t TAGFILE``, ``--tag-file TAGFILE``\n\tUse specified tag file (default: \"tags\").\n\tGiving \"-\" as TAGFILE indicates reading the tags file content from the\n\tstandard input. \"-\" can make the command line simpler. However,\n\tit doesn't mean efficient; readtags stores the data to a temporary\n\tfile and reads that file for taking the ACTION.\n\n``-s[0|1|2]``, ``--override-sort-detection METHOD``\n\tOverride sort detection of tag file.\n\tMETHOD: unsorted|sorted|foldcase\n\nThe NAME action will perform binary search on sorted (including \"foldcase\")\ntags files, which is much faster then on unsorted tags files.\n\nControlling the NAME Action Behavior\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe behavior of the NAME action can be controlled using these options:\n\n``-i``, ``--icase-match``\n\tPerform case-insensitive matching in the NAME action.\n\n``-p``, ``--prefix-match``\n\tPerform prefix matching in the NAME action.\n\nControlling the Output\n~~~~~~~~~~~~~~~~~~~~~~\nBy default, the output of readtags contains only the name, input and pattern\nfield. The Output can be tweaked using these options:\n\n``-A``, ``--absolute-input``\n\tDo the same as ``-C`` option but use only absolute path form.\n\n``-C``, ``--canonicalize-input``\n\tResolve '..' and '.' in input fields of regular tags.\n\tThis produces a unique representation of the input path.\n\tThis option works only with tags files having ``!_TAG_PROC_CWD`` pseudo\n\ttag.\n\n\tNOTE: The current implementation accepts only ``!_TAG_PROC_CWD``\n\tstarting with ``/``; a Windows directory name starting with a\n\tdrive letter like ``C:\\Somewhere`` is not acceptable.\n\n``-d``, ``--debug``\n\tTurn on debugging output.\n\n``-E``, ``--escape-output``\n\tEscape characters like tabs in output as described in :ref:`tags(5) <tags(5)>`.\n\n``-e``, ``--extension-fields``\n\tInclude extension fields in output.\n\n``-n``, ``--line-number``\n\tAlso include the line number field when ``-e`` option is give.\n\n``-P``, ``--with-pseudo-tags``\n\tList pseudo tags as if ``-D`` option is specified but continues processing without exiting.\n\tEven if you specify the ``-Q`` and ``-P`` options together, ``-Q``  affects only\n\tregular tags; it doesn't affect pseudo tags.\n\nAbout the ``-E`` option: certain characters are escaped in a tags file, to make\nit machine-readable. e.g., ensuring no tabs character appear in fields other\nthan the pattern field. By default, readtags translates them to make it\nhuman-readable, but when utilizing readtags output in a script or a client\ntool, ``-E`` option should be used. See :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` for more\ndiscussion on this.\n\nAbout printing input fields ({tagfile} in :ref:`tags(5) <tags(5)>`) with ``-E`` option: readtags\nalways prints the input field literally (as it is in the tags file), and when\nctags writes the tags file, the escaping rules are applied only when\n``TAG_OUTPUT_MODE`` pseudo tag has \"u-ctags\" and ``TAG_OUTPUT_FILESEP`` has\n\"slash\" as values for their input fields, as explained in\n:ref:`ctags-client-tools(7) <ctags-client-tools(7)>`.\n\nFiltering, Sorting, and Formatting\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nFurther filtering, sorting, and formatting on the tags listed by actions\nare performed using:\n\n``-Q EXP``, ``--filter EXP``\n\tFilter the tags listed by ACTION with EXP before printing.\n\n``-S EXP``, ``--sorter EXP``\n\tSort the tags listed by ACTION with EXP before printing.\n\n``-F EXP``, ``--formatter EXP``\n\tFormat the tags listed by ACTION with EXP when printing.\n\nThese are discussed in the `EXPRESSION`_ section.\n\nExamples\n~~~~~~~~\n* List all tags in \"/path/to/tags\":\n\n  .. code-block:: console\n\n     $ readtags -t /path/to/tags -l\n\n* List all tags in \"tags\" that start with \"mymethod\":\n\n  .. code-block:: console\n\n     $ readtags -p - mymethod\n\n* List all tags matching \"mymethod\", case insensitively:\n\n  .. code-block:: console\n\n     $ readtags -i - mymethod\n\n* List all tags start with \"myvar\", and printing all fields (i.e., the whole line):\n\n  .. code-block:: console\n\n     $ readtags -p -ne - myvar\n\nEXPRESSION\n----------\nScheme-style expressions are used for the ``-Q``, ``-S``, and ``-F`` options.\nFor those who doesn't know Scheme or Lisp, just remember:\n\n* A function call is wrapped in a pair of parenthesis. The first item in it is\n  the function/operator name, the others are arguments.\n* Function calls can be nested.\n* Missing values and boolean false are represented by ``#f``. ``#t`` and all\n  other values are considered to be true.\n\nSo, ``(+ 1 (+ 2 3))`` means add 2 and 3 first, then add the result with 1.\n``(and \"string\" 1 #t)`` means logical AND on ``\"string\"``, ``1`` and ``#t``,\nand the result is true since there is no ``#f``.\n\nFiltering\n~~~~~~~~~\nThe tag entries that make the filter expression produces true value are printed\nby readtags.\n\nThe basic operators for filtering are ``eq?``, ``prefix?``, ``suffix?``,\n``substr?``, and ``#/PATTERN/``. Language common fields can be accessed using\nvariables starting with ``$``, e.g., ``$language`` represents the language field.\nFor example:\n\n* List all tags start with \"myfunc\" in Python code files:\n\n  .. code-block:: console\n\n     $ readtags -p -Q '(eq? $language \"Python\")' - myfunc\n\n``downcase`` or ``upcase`` operators can be used to perform case-insensitive\nmatching:\n\n* List all tags containing \"my\", case insensitively:\n\n    .. code-block:: console\n\n     $ readtags -Q '(substr? (downcase $name) \"my\")' -l\n\nWe have logical operators like ``and``, ``or`` and ``not``. The value of a\nmissing field is #f, so we could deal with missing fields:\n\n* List all tags containing \"impl\" in Python code files, but allow the\n  ``language:`` field to be missing:\n\n  .. code-block:: console\n\n     $ readtags -Q '(and (substr? $name \"impl\")\\\n                         (or (not $language)\\\n                             (eq? $language \"Python\")))' -l\n\n``#/PATTERN/`` is for the case when string predicates (``prefix?``, ``suffix?``,\nand ``substr?``) are not enough. You can use \"Posix extended regular expression\"\nas PATTERN.\n\n* List all tags inherits from the class \"A\":\n\n  .. code-block:: console\n\n     $ readtags -Q '(#/(^|,) ?A(,|$)/ $inherits)' -l\n\nHere ``$inherits`` is a comma-separated class list like \"A,B,C\", \"P, A, Q\", or\njust \"A\". Notice that this filter works on both situations where there's a\nspace after each comma or there's not.\n\nCase-insensitive matching can be performed by ``#/PATTERN/i``:\n\n* List all tags inherits from the class \"A\" or \"a\":\n\n  .. code-block:: console\n\n     $ readtags -Q '(#/(^|,) ?A(,|$)/i $inherits)' -l\n\nTo include \"/\" in a pattern, prefix ``\\`` to the \"/\".\n\nNOTE: The above regular expression pattern for inspecting inheritances is just\nan example to show how to use ``#/PATTERN/`` expression. Tags file generators\nhave no consensus about the format of ``inherits:``, e.g., whether there should\nbe a space after a comma. Even parsers in ctags have no consensus. Noticing the\nformat of the ``inherits:`` field of specific languages is needed for such\nqueries.\n\nThe expressions ``#/PATTERN/`` and ``#/PATTERN/i`` are for interactive use.\nReadtags also offers an alias ``string->regexp``, so ``#/PATTERN/`` is equal to\n``(string->regexp \"PATTERN\")``, and ``#/PATTERN/i`` is equal to\n``(string->regexp \"PATTERN\" :case-fold #t)``. ``string->regexp`` doesn't need\nto prefix ``\\`` for including \"/\" in a pattern. ``string->regexp`` may simplify\na client tool building an expression. See also :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` for\nbuilding expressions in your tool.\n\nLet's now consider missing fields. The tags file may have tag entries that has\nno ``inherits:`` field. In that case ``$inherits`` is #f, and the regular\nexpression matching raises an error, since string operators only work for\nstrings. To avoid this problem:\n\n* Safely list all tags inherits from the class \"A\":\n\n  .. code-block:: console\n\n     $ readtags -Q '(and $inherits (#/(^|,) ?A(,|$)/ $inherits))' -l\n\nThis makes sure ``$inherits`` is not missing first, then match it by regexp.\n\nSometimes you want to keep tags where the field *is* missing. For example, your\nwant to exclude reference tags, which is marked by the ``extras:`` field, then\nyou want to keep tags who doesn't have ``extras:`` field since they are also\nnot reference tags. Here's how to do it:\n\n* List all tags but the reference tags:\n\n  .. code-block:: console\n\n     $ readtags -Q '(or (not $extras) (#/(^|,) ?reference(,|$)/ $extras))' -l\n\nNotice that ``(not $extras)`` produces ``#t`` when ``$extras`` is missing, so\nthe whole ``or`` expression produces ``#t``.\n\n\nThe combination of ``ctags -o -`` and ``readtags -t -`` is handy for inspecting\na source file as far as the source file is enough short.\n\n* List all the large (> 100 lines) functions in a file:\n\n  .. code-block:: console\n\n     $ ctags -o - --fields=+neKz input.c \\\n       | ./readtags -t - -en \\\n                    -Q '(and (eq? $kind \"function\") $end $line (> (- $end $line) 100))' \\\n                    -l\n\n* List all the tags including line 80 in a file:\n\n  .. code-block:: console\n\n     $ ctags -o - --fields=+neKz input.c \\\n       | readtags -t - -ne \\\n                  -Q '(and $line\n                           (or (eq? $line 80)\n                               (and $end (< $line 80) (< 80 $end))))' \\\n         -l\n\nRun \"readtags -H filter\" to know about all valid functions and variables.\n\nSorting\n~~~~~~~\nWhen sorting, the sorter expression is evaluated on two tag entries to decide\nwhich should sort before the other one, until the order of all tag entries is\ndecided.\n\nIn a sorter expression, ``$`` and ``&`` are used to access the fields in the\ntwo tag entries, and let's call them $-entry and &-entry. The sorter expression\nshould have a value of -1, 0 or 1. The value -1 means the $-entry should be put\nabove the &-entry, 1 means the contrary, and 0 makes their order in the output\nuncertain.\n\nThe core operator of sorting is ``<>``. It's used to compare two strings or two\nnumbers (numbers are for the ``line:`` or ``end:`` fields). In ``(<> a b)``, if\n``a`` < ``b``, the result is -1; ``a`` > ``b`` produces 1, and ``a`` = ``b``\nproduces 0. Strings are compared using the ``strcmp`` function, see strcmp(3).\n\nFor example, sort by names, and make those shorter or alphabetically smaller\nones appear before the others:\n\n.. code-block:: console\n\n   $ readtags -S '(<> $name &name)' -l\n\nThis reads \"If the tag name in the $-entry is smaller, it goes before the\n&-entry\".\n\nThe ``<or>`` operator is used to chain multiple expressions until one returns\n-1 or 1. For example, sort by input file names, then line numbers if in the\nsame file:\n\n.. code-block:: console\n\n   $ readtags -S '(<or> (<> $input &input) (<> $line &line))' -l\n\nThe ``*-`` operator is used to flip the compare result. i.e., ``(*- (<> a b))``\nis the same as ``(<> b a)``.\n\nFilter expressions can be used in sorter expressions. The technique is use\n``if`` to produce integers that can be compared based on the filter, like:\n\n.. code-block:: lisp\n\n   (<> (if filter-expr-on-$-entry -1 1)\n       (if filter-expr-on-&-entry -1 1))\n\nSo if $-entry satisfies the filter, while &-entry doesn't, it's the same as\n``(<> -1 1)``, which produces ``-1``.\n\nFor example, we want to put tags with \"file\" kind below other tags, then the\nsorter would look like:\n\n.. code-block:: lisp\n\n   (<> (if (eq? $kind \"file\") 1 -1)\n       (if (eq? &kind \"file\") 1 -1))\n\nA quick read tells us: If $-entry has \"file\" kind, and &-entry doesn't, the\nsorter becomes ``(<> 1 -1)``, which produces ``1``, so the $-entry is put below\nthe &-entry, exactly what we want.\n\nFormatting\n~~~~~~~~~~\nA formatter expression defines how readtags prints tag entries.\n\nA formatter expression may produce a string, a boolean, an integer,\nor a list. Readtags prints the produced string, and integer as is.\nReadtags prints nothing for ``#f``, and a newline for ``#t``.\n\nA list could contain any number of strings, booleans,\nintegers, and/or lists. Readtags prints the elements of a list\nsequentially and recursively.\n\nAll the operators for filtering are also available in formatter\nexpressions. In addition to the operators, ``list`` is available\nin formatter expressions. As the name shows, ``list`` is for\nmaking a list. ``list`` makes a list containing arguments passed to\nthe operator. e.g., the following expression makes a list contains\n``1``, ``#f``, and ``\"hello\"``:\n\n.. code-block:: lisp\n\n   (list 1 #f \"hello\")\n\nNOTE: Unlike real-Lisp, backquote constructs are not available.\n\nTo show some examples, the following tags file (``output.tags``) is assumed\nas input for readtags:\n\n.. code-block:: tags\n\n   M\tinput.c\t4;\"\tmacro\tfile:\n   N\tinput.c\t3;\"\tmacro\tfile:\n   bar\tinput.c\t11;\"\tf\ttyperef:typename:void\tfile:\tsignature:(char ** argv,int * r)\n   foo\tinput.c\t6;\"\tf\ttyperef:typename:int\tfile:\tsignature:(int v)\n   main\tinput.c\t16;\"\tf\ttyperef:typename:int\tsignature:(int argc,char ** argv)\n\nAn example for printing only function names:\n\n.. code-block:: console\n\n   $ readtags -t output.tags -Q '(eq? $kind \"function\")' -F '(list $name #t)' -l\n   bar\n   foo\n   main\n\nDoing the same only with a formatter expression:\n\n.. code-block:: console\n\n   $ readtags -t output.tags -F '(if (eq? $kind \"function\") (list $name #t) #f)' -l\n   bar\n   foo\n   main\n\nGenerating declarations for the functions:\n\n.. code-block:: console\n\n   $ readtags -t output.tags -F \\\n     '(if (eq? $kind \"function\")\n         (list (if $file \"static \" #f) $typeref-name \" \" $name $signature \";\" #t)\n        #f)' -l\n   static void bar(char ** argv,int * r);\n   static int foo(int v);\n   int main(int argc,char ** argv);\n\nInspecting the Behavior of Expressions\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe `print` operator can be used to print the value of an expression. For\nexample:\n\n.. code-block:: console\n\n   $ readtags -Q '(print $name)' -l\n\nprints the name of each tag entry before it. Since the return value of\n``print`` is not #f, all the tag entries are printed. We could control this\nusing the ``begin`` or ``begin0`` operator. ``begin`` returns the value of its\nlast argument, and ``begin0`` returns the value of its first argument. For\nexample:\n\n.. code-block:: console\n\n   $ readtags -Q '(begin0 #f (print (prefix? \"ctags\" \"ct\")))' -l\n\nprints a bunch of \"#t\" (depending on how many lines are in the tags file), and\nthe actual tag entries are not printed.\n\nSEE ALSO\n--------\nSee :ref:`tags(5) <tags(5)>` for the details of tags file format.\n\nSee :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` for the tips writing a\ntool utilizing tags file.\n\nThe official Universal Ctags web site at:\n\nhttps://ctags.io/\n\nThe git repository for the library used in readtags command:\n\nhttps://github.com/universal-ctags/libreadtags\n\nCREDITS\n-------\nUniversal Ctags project\nhttps://ctags.io/\n\nDarren Hiebert <dhiebert@users.sourceforge.net>\nhttp://DarrenHiebert.com/\n\nThe readtags command and libreadtags maintained at Universal Ctags\nare derived from readtags.c and readtags.h developed at\nhttp://ctags.sourceforge.net.\n"
  },
  {
    "path": "docs/man/tags.5.rst",
    "content": ".. _tags(5):\n\n==============================================================\ntags\n==============================================================\n\nVi tags file format extended in ctags projects\n\n:Version: 2+\n:Manual group: Universal Ctags\n:Manual section: 5\n\nDESCRIPTION\n-----------\n\nThe contents of next section is a copy of FORMAT file in Exuberant\nCtags source code in its subversion repository at sourceforge.net.\n\nExceptions introduced in Universal Ctags are explained inline with\n\"EXCEPTION\" marker. Statements that are made further clear in Universal\nCtags are explained inline with \"COMMENT\" marker.\n\n----\n\nProposal for extended Vi tags file format\n-----------------------------------------\n\n| Version: 0.06 DRAFT\n| Date: 1998 Feb 8\n| Author: Bram Moolenaar <Bram at vim.org> and Darren Hiebert <dhiebert at users.sourceforge.net>\n\nIntroduction\n~~~~~~~~~~~~\n\nThe file format for the \"tags\" file, as used by Vi and many of its\ndescendants, has limited capabilities.\n\nThis additional functionality is desired:\n\n1. Static or local tags.\n   The scope of these tags is the file where they are defined.  The same tag\n   can appear in several files, without really being a duplicate.\n2. Duplicate tags.\n   Allow the same tag to occur more then once.  They can be located in\n   a different file and/or have a different command.\n3. Support for C++.\n   A tag is not only specified by its name, but also by the context (the\n   class name).\n4. Future extension.\n   When even more additional functionality is desired, it must be possible to\n   add this later, without breaking programs that don't support it.\n\n\nFrom proposal to standard\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo make this proposal into a standard for tags files, it needs to be supported\nby most people working on versions of Vi, ctags, etc..  Currently this\nstandard is supported by:\n\nDarren Hiebert <dhiebert at users.sourceforge.net>\n\tExuberant Ctags\n\nBram Moolenaar <Bram at vim.org>\n\tVim (Vi IMproved)\n\nThese have been or will be asked to support this standard:\n\nNvi\n\t\tKeith Bostic <bostic at bsdi.com>\n\nVile\n\t\tTom E. Dickey <dickey at clark.net>\n\nNEdit\n\t\tMark Edel <edel at ltx.com>\n\nCRiSP\n\t\tPaul Fox <fox at crisp.demon.co.uk>\n\nLemmy\n\t\tJames Iuliano <jai at accessone.com>\n\nZeus\n\t\tJussi Jumppanen <jussij at ca.com.au>\n\nElvis\n\t\tSteve Kirkendall <kirkenda at cs.pdx.edu>\n\nFTE\n\t\tMarko Macek <Marko.Macek at snet.fri.uni-lj.si>\n\n\nBackwards compatibility\n~~~~~~~~~~~~~~~~~~~~~~~\n\nA tags file that is generated in the new format should still be usable by Vi.\nThis makes it possible to distribute tags files that are usable by all\nversions and descendants of Vi.\n\nThis restricts the format to what Vi can handle.  The format is:\n\n1. The tags file is a list of lines, each line in the format::\n\n\t{tagname}<Tab>{tagfile}<Tab>{tagaddress}\n\n\n   {tagname}\n\tAny identifier, not containing white space..\n\n\tEXCEPTION: Universal Ctags violates this item of the proposal;\n\ttagname may contain spaces. However, tabs are not allowed.\n\n   <Tab>\n\tExactly one TAB character (although many versions of Vi can\n\thandle any amount of white space).\n\n   {tagfile}\n\tThe name of the file where {tagname} is defined, relative to\n\tthe current directory (or location of the tags file?).\n\n   {tagaddress}\n\tAny Ex command.  When executed, it behaves like 'magic' was\n\tnot set.\n\n2. The tags file is sorted on {tagname}.  This allows for a binary search in\n   the file.\n\n3. Duplicate tags are allowed, but which one is actually used is\n   unpredictable (because of the binary search).\n\nThe best way to add extra text to the line for the new functionality, without\nbreaking it for Vi, is to put a comment in the {tagaddress}.  This gives the\nfreedom to use any text, and should work in any traditional Vi implementation.\n\nFor example, when the old tags file contains::\n\n\tmain\tmain.c\t/^main(argc, argv)$/\n\tDEBUG\tdefines.c\t89\n\nThe new lines can be::\n\n\tmain\tmain.c\t/^main(argc, argv)$/;\"any additional text\n\tDEBUG\tdefines.c\t89;\"any additional text\n\nNote that the ';' is required to put the cursor in the right line, and then\nthe '\"' is recognized as the start of a comment.\n\nFor Posix compliant Vi versions this will NOT work, since only a line number\nor a search command is recognized.  I hope Posix can be adjusted.  Nvi suffers\nfrom this.\n\n\nSecurity\n~~~~~~~~\n\nVi allows the use of any Ex command in a tags file.  This has the potential of\na trojan horse security leak.\n\nThe proposal is to allow only Ex commands that position the cursor in a single\nfile.  Other commands, like editing another file, quitting the editor,\nchanging a file or writing a file, are not allowed.  It is therefore logical\nto call the command a tagaddress.\n\nSpecifically, these two Ex commands are allowed:\n\n* A decimal line number::\n\n\t89\n\n* A search command.  It is a regular expression pattern, as used by Vi,\n  enclosed in // or ??::\n\n\t/^int c;$/\n\t?main()?\n\nThere are two combinations possible:\n\n* Concatenation of the above, with ';' in between.  The meaning is that the\n  first line number or search command is used, the cursor is positioned in\n  that line, and then the second search command is used (a line number would\n  not be useful).  This can be done multiple times.  This is useful when the\n  information in a single line is not unique, and the search needs to start\n  in a specified line.\n  ::\n\n\t/struct xyz {/;/int count;/\n\t389;/struct foo/;/char *s;/\n\n* A trailing comment can be added, starting with ';\"' (two characters:\n  semi-colon and double-quote).  This is used below.\n  ::\n\n\t89;\" foo bar\n\nThis might be extended in the future.  What is currently missing is a way to\nposition the cursor in a certain column.\n\n\nGoals\n~~~~~\n\nNow the usage of the comment text has to be defined.  The following is aimed\nat:\n\n1. Keep the text short, because:\n\n   * The line length that Vi can handle is limited to 512 characters.\n   * Tags files can contain thousands of tags.  I have seen tags files of\n     several Mbytes.\n   * More text makes searching slower.\n\n2. Keep the text readable, because:\n\n   * It is often necessary to check the output of a new ctags program.\n   * Be able to edit the file by hand.\n   * Make it easier to write a program to produce or parse the file.\n\n3. Don't use special characters, because:\n\n   * It should be possible to treat a tags file like any normal text file.\n\nProposal\n~~~~~~~~\n\nUse a comment after the {tagaddress} field.  The format would be::\n\n\t{tagname}<Tab>{tagfile}<Tab>{tagaddress}[;\"<Tab>{tagfield}..]\n\n\n{tagname}\n\tAny identifier, not containing white space..\n\n\tEXCEPTION: Universal Ctags violates this item of the proposal;\n\tname may contain spaces. However, tabs are not allowed.\n\tConversion, for some characters including <Tab> in the \"value\",\n\texplained in the last of this section is applied.\n\n<Tab>\n\tExactly one TAB character (although many versions of Vi can\n\thandle any amount of white space).\n\n{tagfile}\n\tThe name of the file where {tagname} is defined, relative to\n\tthe current directory (or location of the tags file?).\n\n{tagaddress}\n\tAny Ex command.  When executed, it behaves like 'magic' was\n\tnot set.  It may be restricted to a line number or a search\n\tpattern (Posix).\n\n\tCOMMENT: {tagaddress} could contain tab characters. See\n\t:ref:`ctags-client-tools(7) <ctags-client-tools(7)>` to know how to programmatically extract {tagaddress}\n\t(called \"pattern field\" there) and parse it.\n\nOptionally:\n\n;\"\n\t\tsemicolon + doublequote: Ends the tagaddress in way that looks\n\t\tlike the start of a comment to Vi.\n\n{tagfield}\n\t\tSee below.\n\nA tagfield has a name, a colon, and a value: \"name:value\".\n\n* The name consist only out of alphabetical characters.  Upper and lower case\n  are allowed.  Lower case is recommended.  Case matters (\"kind:\" and \"Kind:\n  are different tagfields).\n\n  EXCEPTION: Universal Ctags allows users to use a numerical character\n  in the name other than its initial letter.\n\n* The value may be empty.\n  It cannot contain a <Tab>.\n\n  - When a value contains a ``\\t``, this stands for a <Tab>.\n  - When a value contains a ``\\r``, this stands for a <CR>.\n  - When a value contains a ``\\n``, this stands for a <NL>.\n  - When a value contains a ``\\\\``, this stands for a single ``\\`` character.\n\n  Other use of the backslash character is reserved for future expansion.\n  Warning: When a tagfield value holds an MS-DOS file name, the backslashes\n  must be doubled!\n\n  EXCEPTION: Universal Ctags introduces more conversion rules.\n\n  - When a value contains a ``\\a``, this stands for a <BEL> (0x07).\n  - When a value contains a ``\\b``, this stands for a <BS> (0x08).\n  - When a value contains a ``\\v``, this stands for a <VT> (0x0b).\n  - When a value contains a ``\\f``, this stands for a <FF> (0x0c).\n  - The characters in range 0x01 to 0x1F included, and 0x7F are\n    converted to ``\\x`` prefixed hexadecimal number if the characters are\n    not handled in the above \"value\" rules.\n\n  EXCEPTION: Universal Ctags allows all these escape sequences in {tagname}\n  and {tagfile} also. However, about {tagfile}, a condition must be\n  satisfied. See \"`Exceptions in Universal Ctags`_\" about the condition.\n\n  - The leading space (0x20) and ``!`` (0x21) in {tagname} are converted\n    to ``\\x`` prefixed hexadecimal number (``\\x20`` and ``\\x21``) if the\n    tag is not a pseudo-tag. As described later, a pseudo-tag starts with\n    ``!``. These rules are for distinguishing pseudo-tags and non pseudo-tags\n    (regular tags) when tags lines in a tag file are sorted.\n\nProposed tagfield names:\n\n=============== =============================================================================\nFIELD-NAME\tDESCRIPTION\n=============== =============================================================================\narity\t\tNumber of arguments for a function tag.\n\nclass\t\tName of the class for which this tag is a member or method.\n\nenum\t\tName of the enumeration in which this tag is an enumerator.\n\nfile\t\tStatic (local) tag, with a scope of the specified file.  When\n\t\tthe value is empty, {tagfile} is used.\n\nfunction\tFunction in which this tag is defined.  Useful for local\n\t\tvariables (and functions).  When functions nest (e.g., in\n\t\tPascal), the function names are concatenated, separated with\n\t\t'/', so it looks like a path.\n\nkind\t\tKind of tag.  The value depends on the language.  For C and\n\t\tC++ these kinds are recommended:\n\n\t\tc\n\t\t\tclass name\n\n\t\td\n\t\t\tdefine (from #define XXX)\n\n\t\te\n\t\t\tenumerator\n\n\t\tf\n\t\t\tfunction or method name\n\n\t\tF\n\t\t\tfile name\n\n\t\tg\n\t\t\tenumeration name\n\n\t\tm\n\t\t\tmember (of structure or class data)\n\n\t\tp\n\t\t\tfunction prototype\n\n\t\ts\n\t\t\tstructure name\n\n\t\tt\n\t\t\ttypedef\n\n\t\tu\n\t\t\tunion name\n\n\t\tv\n\t\t\tvariable\n\n\t\tWhen this field is omitted, the kind of tag is undefined.\n\nstruct\t\tName of the struct in which this tag is a member.\n\nunion\t\tName of the union in which this tag is a member.\n=============== =============================================================================\n\n\nNote that these are mostly for C and C++.  When tags programs are written for\nother languages, this list should be extended to include the used field names.\nThis will help users to be independent of the tags program used.\n\nExamples::\n\n\tasdf\tsub.cc\t/^asdf()$/;\"\tnew_field:some\\svalue\tfile:\n\tfoo_t\tsub.h\t/^typedef foo_t$/;\"\tkind:t\n\tfunc3\tsub.p\t/^func3()$/;\"\tfunction:/func1/func2\tfile:\n\tgetflag\tsub.c\t/^getflag(arg)$/;\"\tkind:f\tfile:\n\tinc\tsub.cc\t/^inc()$/;\"\tfile: class:PipeBuf\n\n\nThe name of the \"kind:\" field can be omitted.  This is to reduce the size of\nthe tags file by about 15%.  A program reading the tags file can recognize the\n\"kind:\" field by the missing ':'.  Examples::\n\n\tfoo_t\tsub.h\t/^typedef foo_t$/;\"\tt\n\tgetflag\tsub.c\t/^getflag(arg)$/;\"\tf\tfile:\n\n\nAdditional remarks:\n\n* When a tagfield appears twice in a tag line, only the last one is used.\n\n\nNote about line separators:\n\nVi traditionally runs on Unix systems, where the line separator is a single\nlinefeed character <NL>.  On MS-DOS and compatible systems <CR><NL> is the\nstandard line separator.  To increase portability, this line separator is also\nsupported.\n\nOn the Macintosh a single <CR> is used for line separator.  Supporting this on\nUnix systems causes problems, because most fgets() implementation don't see\nthe <CR> as a line separator.  Therefore the support for a <CR> as line\nseparator is limited to the Macintosh.\n\nSummary:\n\n==============  ======================  =========================\nline separator\tgenerated on\t\taccepted on\n==============  ======================  =========================\n<LF>\t\tUnix\t\t\tUnix, MS-DOS, Macintosh\n<CR>\t\tMacintosh\t\tMacintosh\n<CR><LF>\tMS-DOS\t\t\tUnix, MS-DOS, Macintosh\n==============  ======================  =========================\n\nThe characters <CR> and <LF> cannot be used inside a tag line.  This is not\nmentioned elsewhere (because it's obvious).\n\n\nNote about white space:\n\nVi allowed any white space to separate the tagname from the tagfile, and the\nfilename from the tagaddress.  This would need to be allowed for backwards\ncompatibility.  However, all known programs that generate tags use a single\n<Tab> to separate fields.\n\nThere is a problem for using file names with embedded white space in the\ntagfile field.  To work around this, the same special characters could be used\nas in the new fields, for example ``\\s``.  But, unfortunately, in MS-DOS the\nbackslash character is used to separate file names.  The file name\n``c:\\vim\\sap`` contains ``\\s``, but this is not a <Space>.  The number of\nbackslashes could be doubled, but that will add a lot of characters, and make\nparsing the tags file slower and clumsy.\n\nTo avoid these problems, we will only allow a <Tab> to separate fields, and\nnot support a file name or tagname that contains a <Tab> character.  This\nmeans that we are not 100% Vi compatible.  However, there is no known tags\nprogram that uses something else than a <Tab> to separate the fields.  Only\nwhen a user typed the tags file himself, or made his own program to generate a\ntags file, we could run into problems.  To solve this, the tags file should be\nfiltered, to replace the arbitrary white space with a single <Tab>.  This Vi\ncommand can be used::\n\n\t:%s/^\\([^ ^I]*\\)[ ^I]*\\([^ ^I]*\\)[ ^I]*/\\1^I\\2^I/\n\n(replace ^I with a real <Tab>).\n\nCOMMENT: Universal Ctags running on MS Windows converts the ``\\`` separator\nto ``/`` by default, and allows the escape sequences even in {tagfile}\nif a condition is satisfied. See \"`Exceptions in Universal Ctags`_\" about\nthe condition.\n\nTAG FILE INFORMATION:\n\nPseudo-tag lines can be used to encode information into the tag file regarding\ndetails about its content (e.g. have the tags been sorted?, are the optional\ntagfields present?), and regarding the program used to generate the tag file.\nThis information can be used both to optimize use of the tag file (e.g.\nenable/disable binary searching) and provide general information (what version\nof the generator was used).\n\nThe names of the tags used in these lines may be suitably chosen to ensure\nthat when sorted, they will always be located near the first lines of the tag\nfile.  The use of \"!_TAG_\" is recommended.  Note that a rare tag like \"!\"\ncan sort to before these lines.  The program reading the tags file should be\nsmart enough to skip over these tags.\n\nThe lines described below have been chosen to convey a select set of\ninformation.\n\nTag lines providing information about the content of the tag file::\n\n    !_TAG_FILE_FORMAT\t{version-number}\t/optional comment/\n    !_TAG_FILE_SORTED\t{0|1}\t\t\t/0=unsorted, 1=sorted/\n\nThe {version-number} used in the tag file format line reserves the value of\n\"1\" for tag files complying with the original UNIX vi/ctags format, and\nreserves the value \"2\" for tag files complying with this proposal. This value\nmay be used to determine if the extended features described in this proposal\nare present.\n\nTag lines providing information about the program used to generate the tag\nfile, and provided solely for documentation purposes::\n\n    !_TAG_PROGRAM_AUTHOR\t{author-name}\t/{email-address}/\n    !_TAG_PROGRAM_NAME\t{program-name}\t/optional comment/\n    !_TAG_PROGRAM_URL\t{URL}\t/optional comment/\n    !_TAG_PROGRAM_VERSION\t{version-id}\t/optional comment/\n\nEXCEPTION: Universal Ctags introduces more kinds of pseudo-tags.\nSee :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` about them.\n\nCOMMENT: Though pseudo-tags are semantically different from regular tags, They\nuse the same format, which is::\n\n\t{tagname}<Tab>{tagfile}<Tab>{tagaddress}\n\n, and the escape sequences and illegal characters explained in \"Proposal\"\nsection also applies to pseudo-tags.\n\n----\n\n\nExceptions in Universal Ctags\n--------------------------------------------\n\nUniversal Ctags supports this proposal with some\nexceptions.\n\n\nExceptions\n~~~~~~~~~~~\n\n#. {tagname} in tags file generated by Universal Ctags may contain\n   spaces and several escape sequences. Parsers for documents like Tex and\n   reStructuredText, or liberal languages such as JavaScript need these\n   exceptions. See {tagname} of Proposal section for more detail about the\n   conversion.\n\n#. {tagfile} in tags file generated by Universal Ctags may contain\n   spaces and several escape sequences if ``\\`` characters are not used as\n   filename separators. UNIX-like systems use ``/`` for the\n   purpose. On MS Windows, Universal Ctags converts ``\\`` in filenames\n   to ``/`` by default. So, generally this condition is satisfied.\n   Universal Ctags emits several pseudo tags telling whether the condition\n   is satisfied or not. See :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` about these pseudo tags.\n\n#. \"name\" part of {tagfield} in a tag generated by Universal Ctags may\n   contain numeric characters, but the first character of the \"name\"\n   must be alphabetic.\n\n   .. NOT REVIEWED YET (above item)\n\n.. _compat-output:\n\nCompatible output and weakness\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. NOT REVIEWED YET\n\nDefault behavior (``--output-format=u-ctags`` option) has the\nexceptions.  On the other hand, with ``--output-format=e-ctags`` option\nctags has no exception; Universal Ctags command may use the same file\nformat as Exuberant Ctags. However, ``--output-format=e-ctags`` throws\naway a tag entry which name includes a space or a tab\ncharacter. ``TAG_OUTPUT_MODE`` pseudo-tag tells which format is\nused when ctags generating tags file.\n\nSEE ALSO\n--------\n:ref:`ctags(1) <ctags(1)>`, :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`, :ref:`ctags-incompatibilities(7) <ctags-incompatibilities(7)>`, :ref:`readtags(1) <readtags(1)>`\n"
  },
  {
    "path": "docs/man-pages.rst",
    "content": ".. _man-pages:\n\n======================================================================\nMan pages\n======================================================================\n\n.. toctree::\n\t:maxdepth: 3\n\n\tctags(1) <man/ctags.1.rst>\n\tctags-json-output(5) <man/ctags-json-output.5.rst>\n\ttags(5) <man/tags.5.rst>\n\n\tctags-optlib(7) <man/ctags-optlib.7.rst>\n\tctags-client-tools(7) <man/ctags-client-tools.7.rst>\n\tctags-incompatibilities(7) <man/ctags-incompatibilities.7.rst>\n\tctags-faq(7) <man/ctags-faq.7.rst>\n\n\tctags-lang-asm(7) <man/ctags-lang-asm.7.rst>\n\tctags-lang-autoit(7) <man/ctags-lang-autoit.7.rst>\n\tctags-lang-automake(7) <man/ctags-lang-automake.7.rst>\n\tctags-lang-c(7) <man/ctags-lang-c.7.rst>\n\tctags-lang-c++(7) <man/ctags-lang-c++.7.rst>\n\tctags-lang-cuda(7) <man/ctags-lang-cuda.7.rst>\n\tctags-lang-elm(7) <man/ctags-lang-elm.7.rst>\n\tctags-lang-emacslisp(7) <man/ctags-lang-emacslisp.7.rst>\n\tctags-lang-fortran(7) <man/ctags-lang-fortran.7.rst>\n\tctags-lang-gdscript(7) <man/ctags-lang-gdscript.7.rst>\n\tctags-lang-i18nrubygem(7) <man/ctags-lang-i18nrubygem.7.rst>\n\tctags-lang-iPythonCell(7) <man/ctags-lang-iPythonCell.7.rst>\n\tctags-lang-inko(7) <man/ctags-lang-inko.7.rst>\n\tctags-lang-javascript(7) <man/ctags-lang-javascript.7.rst>\n\tctags-lang-julia(7) <man/ctags-lang-julia.7.rst>\n\tctags-lang-kconfig(7) <man/ctags-lang-kconfig.7.rst>\n\tctags-lang-ldscript(7) <man/ctags-lang-ldscript.7.rst>\n\tctags-lang-lex(7) <man/ctags-lang-lex.7.rst>\n\tctags-lang-lisp(7) <man/ctags-lang-lisp.7.rst>\n\tctags-lang-make(7) <man/ctags-lang-make.7.rst>\n\tctags-lang-markdown(7) <man/ctags-lang-markdown.7.rst>\n\tctags-lang-meson(7) <man/ctags-lang-meson.7.rst>\n\tctags-lang-odin(7) <man/ctags-lang-odin.7.rst>\n\tctags-lang-powershell(7) <man/ctags-lang-powershell.7.rst>\n\tctags-lang-python(7) <man/ctags-lang-python.7.rst>\n\tctags-lang-r(7) <man/ctags-lang-r.7.rst>\n\tctags-lang-rmarkdown(7) <man/ctags-lang-rmarkdown.7.rst>\n\tctags-lang-scheme(7) <man/ctags-lang-scheme.7.rst>\n\tctags-lang-scss(7) <man/ctags-lang-scss.7.rst>\n\tctags-lang-sql(7) <man/ctags-lang-sql.7.rst>\n\tctags-lang-systemtap(7) <man/ctags-lang-systemtap.7.rst>\n\tctags-lang-tcl(7) <man/ctags-lang-tcl.7.rst>\n\tctags-lang-terraform(7) <man/ctags-lang-terraform.7.rst>\n\tctags-lang-verilog(7) <man/ctags-lang-verilog.7.rst>\n\tctags-lang-vim(7) <man/ctags-lang-vim.7.rst>\n\n\treadtags(1) <man/readtags.1.rst>\n"
  },
  {
    "path": "docs/news/6-0-0.rst",
    "content": "======================================================================\nChanges in 6.0.0\n======================================================================\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\n.. contents:: `Table of contents`\n\t:depth: 3\n\t:local:\n\n----\n\nMany changes have been introduced in Universal Ctags. Use git-log to\nreview changes not enumerated here, especially in language parsers.\n\nNew and extended options\n---------------------------------------------------------------------\n\n``--exclude-exception``, an option complementing ``--exclude``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSee :ref:`option_input_output_file` in :ref:`ctags(1) <ctags(1)>`.\n\n``--maxdepth`` option\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSee :ref:`option_input_output_file` in :ref:`ctags(1) <ctags(1)>`.\n\n``--input-encoding=ENCODING`` and ``--output-encoding=ENCODING``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. TODO: Review...\n\nPeople may use their own native language in source code comments (or\nsometimes in identifiers) and in such cases encoding may become an issue.\nNowadays UTF-8 is the most widely used encoding, but some source codes\nstill use legacy encodings like latin1, cp932 and so on. These options\nare useful for such files.\n\nctags doesn't consider the input encoding; it just reads input as a\nsequence of bytes and uses them as is when writing tags entries.\n\nOn the other hand Vim does consider input encoding. When loading a\nfile, Vim converts the file contents into an internal format with one\nof the encodings specified in its `fileencodings` option.\n\nAs a result of this difference, Vim cannot always move the cursor to\nthe definition of a tag as users expect when attempting to match the\npatterns in a tags file.\n\nThe good news is that there is a way to notify Vim of the encoding\nused in a tags file with the ``TAG_FILE_ENCODING`` pseudo-tag.\n\nTwo new options have been introduced (``--input-encoding=IN`` and\n``--output-encoding=OUT``).\n\nUsing the encoding specified with these options ctags converts input\nfrom ``IN`` to ``OUT``. ctags uses the converted strings when writing\nthe pattern parts of each tag line. As a result the tags output is\nencoded in ``OUT`` encoding.\n\nIn addition ``OUT`` is specified at the top the tags file as the\nvalue for the ``TAG_FILE_ENCODING`` pseudo-tag. The default value of\n``OUT`` is UTF-8.\n\nNOTE: Converted input is NOT passed to language parsers.\nThe parsers still deal with input as a byte sequence.\n\nWith ``--input-encoding-<LANG>=IN``, you can specify a specific input\nencoding for ``LANG``. It overrides the global default value given\nwith ``--input-encoding``.\n\nThe example usage can be found in *Tmain/{input,output}-encoding-option.d*.\n\nAcceptable ``IN`` and ``OUT`` values can be listed with *iconv -l* or\n*iconv --list*. It is platform dependant.\n\nTo enable the option, libiconv is needed on your platform.\nOn Windows mingw (without msys2), you must specify ``WITH_ICONV=yes``\nlike this::\n\n\tC:\\dev\\ctags>mingw32-make -f mk_mingw.mak WITH_ICONV=yes\n\n``--list-features`` helps you to know whether your ctags executable\nlinks to libiconv or not. You will find ``iconv`` in the output if it\nlinks to.\n\nSee also :ref:`option_output_format` in :ref:`ctags(1) <ctags(1)>`.\n\n``--map-<LANG>`` option\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. IN MAN PAGE\n\n``--map-<LANG>`` is newly introduced to control the file name\nto language mappings (langmap) with finer granularity than\n``--langmap`` allows.\n\nA langmap entry is defined as a pair; the name of the language and a\nfile name extension (or pattern).\n\nHere we use \"spec\" as a generic term representing both file name\nextensions and patterns.\n\n``--langmap`` maps specs to languages exclusively::\n\n  $ ctags --langdef=FOO --langmap=FOO:+.ABC \\\n\t    --langdef=BAR --langmap=BAR:+.ABC  \\\n\t    --list-maps | grep '\\*.ABC$'\n  BAR      *.ABC\n\nThough language `FOO` is added before `BAR`, only `BAR` is set as a\nhandler for the spec `*.ABC`.\n\nUniversal Ctags enables multiple parsers to be configured for a spec.\nThe appropriate parser for a given input file can then be chosen by a\nvariety of internal guessing strategies (see :ref:`Determining file language\n<guessing>`).\n\nLet's see how specs can be mapped non-exclusively with\n``--map-<LANG>``::\n\n    $ ctags --langdef=FOO --map-FOO=+.ABC \\\n\t      --langdef=BAR --map-BAR=+.ABC \\\n\t      --list-maps | grep '\\*.ABC$'\n    FOO      *.ABC\n    BAR      *.ABC\n\nBoth `FOO` and `BAR` are registered as handlers for the spec `*.ABC`.\n\n``--map-<LANG>`` can also be used for removing a langmap entry.::\n\n    $ ctags --langdef=FOO --map-FOO=+.ABC \\\n\t      --langdef=BAR --map-BAR=+.ABC \\\n\t      --map-FOO=-.ABC --list-maps | grep '\\*.ABC$'\n    BAR      *.ABC\n\n    $ ctags --langdef=FOO --map-FOO=+.ABC \\\n\t      --langdef=BAR --map-BAR=+.ABC \\\n\t      --map-BAR=-.ABC --list-maps | grep '\\*.ABC$'\n    FOO      *.ABC\n\n    $ ctags --langdef=FOO --map-FOO=+.ABC \\\n\t     --langdef=BAR --map-BAR=+.ABC \\\n\t     --map-BAR=-.ABC --map-FOO=-.ABC  --list-maps | grep '\\*.ABC$'\n    (NOTHING)\n\n``--langmap`` provides a way to manipulate the langmap in a\nspec-centric manner and ``--map-<LANG>`` provides a way to manipulate\nthe langmap in a parser-centric manner.\n\nSee also :ref:`option_lang_mapping` in :ref:`ctags(1) <ctags(1)>`.\n\nGuessing parser from file contents (``-G`` option)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSee :ref:`guessing` in :ref:`ctags(1) <ctags(1)>`.\n\nIncluding line number to pattern field\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUse ``--excmd=number``.\nSee :ref:`option_tags_file_contents` in :ref:`ctags(1) <ctags(1)>`.\n\nLong names in kinds, fields, and extra options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA letter is used for specifying a kind, a field, or an extra entry.\nIn Universal Ctags a name can also be used.\n\nSurround the name with braces (`{` and `}`) in values assigned to the\noptions, ``--kind-<LANG>=``, ``--fields=``, or ``--extras=``.\n\n.. code-block:: console\n\n\t$ ctags --kinds-C=+L-d ...\n\nThis command line uses the letters, `L` for enabling the label kind\nand `d` for disabling the macro kind of C. The command line can be\nrewritten with the associated names.\n\n.. code-block:: console\n\n\t$ ctags --kinds-C='+{label}-{macro}' ...\n\nThe quotes are needed because braces are interpreted as meta\ncharacters by the shell.\n\nThe available names can be listed with ``--list-kinds-full``,\n``--list-fields``, or ``--list-extras``.\n\nSee also :ref:`option_tags_file_contents` in :ref:`ctags(1) <ctags(1)>`.\n\nWildcard in options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFor the purpose of gathering as much as information as possible from\nsource code the \"wildcard\"(``*``) option value has been introduced.\n\n``--extras=*``\n\tEnables all extra tags.\n\n``--fields=*``\n\tEnables all available fields.\n\n``--kinds-<LANG>=*``\n\tEnables all available kinds for ``LANG``.\n\n``--kinds-all=*``\n\tEnables all available kinds for all available language parsers.\n\nSee also :ref:`option_tags_file_contents` in :ref:`ctags(1) <ctags(1)>`.\n\nExtra tag entries (``--extras``)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--extra`` option in Exuberant Ctags is renamed to ``--extras`` (plural) in\nUniversal Ctags for making consistent with ``--kinds-<LANG>`` and ``--fields``.\n\nThese extra tag entries are newly introduced.\n\n``F``\n\tReplacement for --file-scope.\n\n``p``\n\tInclude pseudo-tags.\n\n..\n\tNOT REVIEWED YET\n\nSee also :ref:`option_tags_file_contents` in :ref:`ctags(1) <ctags(1)>`.\n\nKinds synchronization\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSee the description about ``--kinds-<LANG>`` and ``--list-kinds-full``\noption on :ref:`option_tags_file_contents` in :ref:`ctags(1) <ctags(1)>`.\n\nEnabling/disabling pseudo-tags (``--pseudo-tags`` option)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. IN MAN PAGE\n\nSee :ref:`option_tags_file_contents` in :ref:`ctags(1) <ctags(1)>` and\n:ref:`ctags-client-tools(7) <ctags-client-tools(7)>` about the option.\n\n``--put-field-prefix`` options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSee :ref:`option_tags_file_contents` in :ref:`ctags(1) <ctags(1)>`.\n\n\"always\" and \"never\" as an argument for ``--tag-relative``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``--tag-relative`` option is extend.\nSee :ref:`option_tags_file_contents` in :ref:`ctags(1) <ctags(1)>`.\n\nDefining a parser specific extra\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA new ``--_extradef-<LANG>=name,description`` option allows you to\ndefining a parser specific extra which turning on and off can be\nreferred from a regex based parser for ``<LANG>``.\n\nSee :ref:`Conditional tagging with extras <extras>` for more details.\n\nDefining a CPreProcessor macro from command line\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nNewly introduced ``-D`` option extends the function provided by\n``-I`` option.\n\n``-D`` emulates the behaviour of the corresponding gcc option:\nit defines a C preprocessor macro.\n\nSee :ref:`option_tags_file_contents` in :ref:`ctags(1) <ctags(1)>` and\n:ref:`cxx` for more details.\n\nOptions for inspecting ctags internals\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nExuberant Ctags provides a way to inspect its internals via\n``--list-kinds``, ``--list-languages``, and ``--list-maps``.\n\nThis idea has been expanded in Universal Ctags with\n``--list-kinds-full``, ``--list-map-extensions``,  ``--list-extras``,\n``--list-features``, ``--list-fields``, ``--list-map-patterns``, and\n``--list-pseudo-tags`` being added.\n\nThe original three ``--list-`` options are not changed for\ncompatibility reasons, however, the newly introduced options are\nrecommended for all future use.\n\nBy default, interactive use is assumed and ctags tries aligning the\nlist output in columns for easier reading.\n\nWhen ``--machinable`` is given before a ``--list-`` option, ctags\noutputs the list in a format more suitable for processing by scripts.\nTab characters are used as separators between columns. The alignment\nof columns is never considered when ``--machinable`` is given.\n\nCurrently only ``--list-extras``, ``--list-fields`` and\n``--list-kinds-full`` support ``--machinable`` output.\n\nThese new ``--list-`` options also print a column header, a line\nrepresenting the name of each column. The header may help users and\nscripts to understand and recognize the columns. Ignoring the column\nheader is easy because it starts with a `#` character.\n\n``--with-list-header=no`` suppresses output of the column header.\n\nSee also :ref:`option_listing` in :ref:`ctags(1) <ctags(1)>`.\n\nNotice messages and ``--quiet``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThere were 3 classes of message in Exuberant Ctags.\nIn addition to them Universal Ctags introduced a new class of message, *notice*.\n\n*fatal*\n\tA critical error has occurred and ctags aborts the execution.\n\n*warning*\n\tAn error has occurred but ctags continues the execution.\n\n*notice* (new)\n    It is less important than *warning* but more important for users than *verbose*.\n\n*verbose*\n\tMainly used for debugging purposes.\n\nGenerally the user can ignore *notice* class messages and ``--quiet``\ncan be used to disable them.\n\n*verbose* class messages are disabled by default, and ``--verbose`` or ``-V``\ncan be used to enable them.\n\nSee also :ref:`option_misc` in :ref:`ctags(1) <ctags(1)>`.\n\nSkipping utf-8 BOM\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe three bytes sequence(``\\xEF\\xBB\\xBF``) at the head of an input\nfile is skipped when parsing.\n\nTODO:\n\n* Do the same in guessing and selecting parser stage.\n* Refect the BOM detection to encoding option\n\nInteractive mode\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA new ``--_interactive`` option launches a JSON based command REPL which\ncan be used to control ctags generation programmatically.\n\nSee :ref:`interactive-mode` for more details.\n\nPCRE2 regular expression\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWith ``{pcre2}`` (or ``p``) flag, PCRE2 expressions can be used in\n``--regex-<LANG>=``, ``--mline-regex-<LANG>=``, and\n``--_mtable-regex-<LANG>=`` if the ctags is built with ``pcre2`` library.\n\n\nIncompatible changes in command line\n---------------------------------------------------------------------\n\n.. NOT REVIEWED YET\n\n``-D`` option\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFor a ctags binary that had debugging output enabled in the build config\nstage, ``-D`` was used for specifying the level of debugging\noutput. It is changed to ``-d``. This change is not critical because\n``-D`` option was not described in ctags.1 man page.\n\nInstead ``-D`` is used for defining a macro in CPreProcessor parser.\n\nChanges imported from Exuberant Ctags\n---------------------------------------------------------------------\nSee \"Exuberant Ctags\" in \"Tracking other projects\" for detailed\ninformation regarding imported changes.\n\nSome changes have also been imported from Fedora and Debian.\n\nParser related changes\n---------------------------------------------------------------------\n\nNew parsers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe following parsers have been added:\n\n* Abaqus\n* Abc\n* Ada\n* AnsiblePlaybook *libyaml*\n* Asciidoc\n* Autoconf\n* Automake\n* AutoIt\n* BibTeX\n* Clojure\n* CMake *optlib*\n* CSS\n* Ctags option library *optlib*\n* CUDA\n* D\n* DBusIntrospect *libxml*\n* Diff\n* Dots *Sh based subparser*\n* DTD\n* DTS\n* Elixir *optlib*\n* Elm *peg/packcc*\n* Falcon\n* FrontMatter *only YAML syntax, running as a guest on R?Markdown*\n* FunctionParameters *Perl based subparser*\n* Gdbinit script *optlib*\n* GemSpec *Ruby based subparser*\n* GDScript\n* Glade *libxml*\n* Go\n* GPerf *optlib*\n* Haskell\n* Haxe\n* iPythonCell *optlib*, *Python based subparser*\n* Inko *optlib*\n* JavaProperties\n* JSON\n* Julia\n* Kconfig *optlib*\n* Kotlin *peg/packcc*\n* GNU linker script(LdScript)\n* LEX *optlib*\n* Man page *optlib*\n* Markdown\n* Maven2 *libxml*\n* MesonBuild (Meson) *optlib*\n* MesonOptions *optlib+script*\n* Moose *Perl based subparser*\n* Myrddin\n* M4\n* NSIS\n* ObjectiveC\n* Org *optlib*\n* OpenAPI (3.x.x / Swagger 2.0) *Yaml based subparser*\n* Passwd *optlib*\n* PuppetManifest *optlib*\n* Perl6 *Another name for Raku*\n* Pod *optlib*\n* PowerShell\n* PropertyList(plist) *libxml*\n* Protobuf\n* PythonLoggingConfig\n* QemuHX *optlib*\n* QtMoc\n* R\n* R6Class *R based subparser*\n* Rake *Ruby based subparser*\n* Raku *formerly Perl6*\n* RDoc *optlib pcre2*\n* RelaxNG *libxml*\n* ReStructuredText\n* RMarkdown *Markdown based subparser*\n* Robot\n* RpmMacros *optlib*\n* RpmSpec\n* RSpec *Ruby based subparser*\n* Rust\n* S4Class *R based subparser*\n* SCSS *optlib*\n* SystemdUnit\n* SystemTap *optlib*\n* SystemVerilog\n* SVG *libxml*\n* TclOO (see :ref:`The new Tcl parser <tcl>`)\n* Thrift *peg/packcc*\n* TTCN\n* Txt2tags\n* TypeScript\n* Varlink *peg/packcc*\n* WindRes\n* XSLT v1.0 *libxml*\n* Yacc\n* Yaml *libyaml*\n* YumRepo\n* Zephir\n* Zsh\n\nSee :ref:`optlib` for details on *optlib*.\nLibxml2 is required to use the parser(s) marked with *libxml*.\nLibyaml is required to use the parser(s) marked with *libyaml*.\npcre2 is required to use the parser(s) marked with *pcre2*.\n\nTIPS: you can list newly introduced parsers if you also have\nExuberant Ctags installed with following command line:\n\n.. code-block:: console\n\n\t\t$ diff -ruN <(universal-ctags --list-languages) <(exuberant-ctags --list-languages)  | grep '^[-+]'\n\nFully improved parsers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n* C (see :ref:`The new C/C++ parser <cxx>`)\n* C++ (see :ref:`The new C/C++ parser <cxx>`)\n* Python (see :ref:`The new Python parser <python>`)\n* HTML (see :ref:`The new HTML parser <html>`)\n* Tcl (see :ref:`The new Tcl parser <tcl>`)\n* ITcl (see :ref:`The new Tcl parser <tcl>`)\n* Ant (rewritten with *libxml*)\n* PHP\n* Verilog/SystemVerilog\n\nAutomatically expanding CPreProcessor macros defined in the same input file (HIGHLY EXPERIMENTAL)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSee :ref:`The new C/C++ parser <cxx>` for more details.\n\nReadtags\n---------------------------------------------------------------------\n\nPrinting line numbers with ``-n``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSee :ref:`readtags(1) <readtags(1)>`.\n\nFiltering in readtags command\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSee :ref:`readtags(1) <readtags(1)>`.\n\nreadtags has ability to find tag entries by name.\n\nThe concept of filtering is inspired by the display filter of\nWireshark. You can specify more complex conditions for searching.\n\nAll symbols starting with `$` represent a field of a tag entry which\nis being tested against the S expression. Most will evaluate as a\nstring or `#f`. It evaluates to `#f` when the field doesn't exist.\n\nThe `scope` field holds structured data: the kind and name of the\nupper scope combined with `:`. The hold the value is stored to\n`$scope`. The kind part is mapped to `$scope-kind`, and the name part\nto `$scope-name`.\n\n`$scope-kind` and `$scope-name` can only be used if the input tags\nfile is generated by ctags with ``--fields=+Z``.\n\n`$` is a generic accessor for accessing extension fields.\n`$` takes one argument: the name of an extension field.\nIt returns the value of the field as a string if a value\nis given, or `#f`.\n\nFollowing examples shows how `prefix?`, `suffix?`, and\n`substr?` work.\n::\n\n\t(prefix? \"TARGET\" \"TA\")\n\t=> #t\n\n\t(prefix? \"TARGET\" \"RGET\")\n\t=> #f\n\n\t(prefix? \"TARGET\" \"RGE\")\n\t=> #f\n\n\t(suffix? \"TARGET\" \"TA\")\n\t=> #f\n\n\t(suffix? \"TARGET\" \"RGET\")\n\t=> #t\n\n\t(suffix? \"TARGET\" \"RGE\")\n\t=> #f\n\n\t(substr? \"TARGET\" \"TA\")\n\t=> #t\n\n\t(suffix? \"TARGET\" \"RGET\")\n\t=> #t\n\n\t(suffix? \"TARGET\" \"RGE\")\n\t=> #t\n\n\t(and (suffix? \"TARGET\" \"TARGET\")\n\t     (prefix? \"TARGET\" \"TARGET\")\n\t     (substr? \"TARGET\" \"TARGET\")\n\t=> #t\n\n\nSorting in readtags command\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nreadtags can sort the tag entries before printing.\nYou can specify the way to sort with -S option. Like ``-Q`` option, ``-S``\nalso takes an S expression.\n\nSee :ref:`readtags(1) <readtags(1)>`.\n\n\nListing pseudo tags with ``-D``\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSee :ref:`readtags(1) <readtags(1)>`.\n"
  },
  {
    "path": "docs/news/6-1-0.rst",
    "content": "======================================================================\nChanges in 6.1.0\n======================================================================\n\nThis page lists only the most significant changes as remembered.  Use\ngit-log to review changes not enumerated here, especially in language\nparsers.\n\nNew and extended options and their flags\n---------------------------------------------------------------------\n\n``--regex-<LANG>`` option\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* ``{postrun}`` and ``{intervaltab}`` flags are added.\n  See :ref:`ctags-optlib(7) <ctags-optlib(7)>`.\n\nIncompatible changes\n---------------------------------------------------------------------\n\n* `section` kind is deleted from Asm parser.\n\nParser related changes\n---------------------------------------------------------------------\n\nNew parsers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe following parsers have been added:\n\n* BibLaTeX *BibTeX based subparser* by masatake · Pull Request #3822\n* Forth *optlib* by farvardin · Pull Request #3812\n* Quarto: new parser by masatake · Pull Request #3677\n\n  +  Quarto by Anish Shah · Pull Request #3643\n\n* V: new parser by Tim Marston · Pull Request #3871, #3870\n* Terraform: new parser by masatake · Pull Request #3684\n\n  + Terraform (HCL) (\\*.tf): new parser by  Matt Mrowiec · Pull Request #3683\n  + Terraform (HCL) (\\*.tf): new parser by Antony Southworth · Pull Request #2952\n\n* TerraformVariables *optlib* by masatake · Pull Request #3684\n\n* PkgConfig *optlib*: new parser · Pull Request #3891\n* I18nRubyGem *YAML based subparser* · Close #3533\n\n* XRC *libxml*: new parser · Pull Request #3897\n\nChanges about parser specific kinds, roles, fields, and extras\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. See the output of ./misc/news.bash man [v6.0.0]\n\n* Asm\n\n  + `section` kind is deleted.\n\n* AutoIt\n\n  + Drop `$` from tags for variables names.\n\n* Automake\n\n  + New extra `canonicalizedName`\n  + New kind `pseudodir`\n\n* C\n\n  + New role `foreigndecl` for `function` kind\n  + New role `foreigndecl` for `struct` kind\n\n\n  + New filed `section`\n\n  + New field `alias`\n\n* C++\n\n  + New filed `section`\n\n  + New field `alias`\n\n* CUDA\n\n  + New field `section`\n\n  + New field `alias`\n\n* Fortran\n\n  + New extra `linkName`.\n\n* JavaScript\n\n  + New role `foreigndecl` for `function` kind\n\n* Kconfig\n\n  + New kind `variable`\n\n* LdScript\n\n  + New role `destination` for `inputSection` kind\n\n  + New role `aliased` for `symbol` kind\n\n* Markdown\n\n  + New kind  `hashtag`\n\n* SystemTap\n\n  + New role `attached` for `probe` kind\n\n* SystemVerilog\n\n  + New kind `define`\n\nReadtags\n---------------------------------------------------------------------\n* Enhancement: add `-P, --with-psuedo-tags` option.\n* Enhancement: add `-A, --absolute-input` and `-C, --canonicalize-input` options.\n  See :ref:`readtags(1) <readtags(1)>`. for more details.\n* Enhancement: add `-d, --debug`  option for debugging purpose.\n* Bugfix: make `--formatter` options works.\n\n\nMerged pull requests\n---------------------------------------------------------------------\n\n.. note::\n\n   This list is imperfect. masatake cleaned up some pull requests before\n   merging. Though his names is used in \"... by ...\", his is not the\n   primary contributor of the pull requests. See git log for more\n   defatils.\n\n.. generated by ./misc/news.bash pr [v6.0.0...]\n\n* Pull in the latest subtrees by masatake · Pull Request #3902\n* readtags: add --with-psuedo-tags option by masatake · Pull Request #3901\n* I18nRubyGem: add a new kind, \"locale\" by masatake · Pull Request #3899\n* Ruby: improve the way of parsing `Class.new(SuperClass)` by masatake · Pull Request #3898\n* XML Based Resource System (XRC): new parser by masatake · Pull Request #3897\n* I18nRubyGem: new parser by masatake · Pull Request #3895\n* docs(man): write about guest parsers by masatake · Pull Request #3892\n* Revise the release process by masatake · Pull Request #3894\n* PkgConfig: new parser by masatake · Pull Request #3891\n* rpmMacros: process areas surrounded by pairs of curly bracket by masatake · Pull Request #3890\n* Vera: revise the dataflow of cppGetc -> vStringPut by masatake · Pull Request #3886\n* nestlevel: Fix user data alignment by b4n · Pull Request #3883\n* Cxx: extract section information from __attribute__((section(\"SECTION\"))) by masatake · Pull Request #3614\n* NEWS: merge README.rst and README.md by masatake · Pull Request #3875\n* builds-sys/test: enhance  check-genfile target by masatake · Pull Request #3882\n* various minor fixes by masatake · Pull Request #3880\n* GitHub Actions: disable BSD workflows again by masatake · Pull Request #3879\n* circleci: use fedora39 by masatake · Pull Request #3878\n* misc/news.bash: generalize the script by masatake · Pull Request #3877\n* docs(web): manage versions of NEWS by masatake · Pull Request #3872\n* main: use the interval tree for filling scope field by masatake · Pull Request #3678\n* V for merging by masatake · Pull Request #3871\n* YACC: fix a typo in the pattern for skipping C strings by masatake · Pull Request #3869\n* Revise: the way of accessing the optVm's appData by masatake · Pull Request #3868\n* dsl: extend #/../ operator to be able to extract a matched group in the pattern by masatake · Pull Request #3768\n* Docs: minor fixes by masatake · Pull Request #3867\n* misc/units.py: fix invalid escape sequences in regex patterns by masatake · Pull Request #3866\n* build-sys: don't use libxml-2 if its CRLF handling is broken by masatake · Pull Request #3858\n* SQL: extract views in \"create view if not exists VIEW ...\" by masatake · Pull Request #3850\n* JavaScript: handle spread syntax by masatake · Pull Request #3846\n* GitHub Actions: temporarily disable BSD workflows by leleliu008 · Pull Request #3848\n* README.md: update the URL for the badge of CircleCI Build Status by masatake · Pull Request #3844\n* Yaml: revise Ypath API by masatake · Pull Request #3842\n* docs(web): add .readthedocs.yaml file by masatake · Pull Request #3843\n* Update kotlin parser by dolik-rce · Pull Request #3841\n* Various warnings fixes by b4n · Pull Request #3840\n* main,tlib: fix wording by masatake · Pull Request #3838\n* ReStructuredText: run guest parsers on code blocks by masatake · Pull Request #3839\n* README.md: adjust wording of the configure command by rhythm16 · Pull Request #3835\n* Revert \"main,tlib: fix wording\" by masatake · Pull Request #3837\n* M4,Autoconf: allow to run a subparser inside quoted area by masatake · Pull Request #3833\n* main,tlib: fix wording by masatake · Pull Request #3834\n* Automake:  various updates by masatake · Pull Request #3828\n* Doc: update docs/windows.rst by leleliu008 · Pull Request #3825\n* AppVeyor: use Visual Studio 2019 image by leleliu008 · Pull Request #3815\n* BibTeX: accept \".\" and \"/\" as parts of a bib entry by masatake · Pull Request #3824\n* BibLaTeX: new subparser based on BibTeX by masatake · Pull Request #3822\n* using %zu for printing size_t values by leleliu008 · Pull Request #3821\n* Forth: new parser by farvardin · Pull Request #3812\n* build(deps): bump actions/checkout from 3 to 4 by dependabot[bot] · Pull Request #3814\n* GitHub Actions: Create dependabot.yml by k-takata · Pull Request #3813\n* c-based: fix to handle edge case by jafl · Pull Request #3796\n* C-based:  put markers to signature by masatake · Pull Request #3804\n* Appveyor: run nmake with defining DEBUG by masatake · Pull Request #3801\n* main,debug: don't use __func__ directly by masatake · Pull Request #3800\n* input-validate: add CATEGORIES make variable by hirooih · Pull Request #3793\n* Verilog validator by hirooih · Pull Request #3791\n* update Mac installation instructions by euclio · Pull Request #3790\n* CircleCI: run validate-input target on Fedora 38 instead of Fedora 30 by masatake · Pull Request #3792\n* ReStructuredText: skip prefixed whitespaces when parsing markup lines by masatake · Pull Request #3789\n* main: report the guessed reason if system(\"sort\") is failed by masatake · Pull Request #3788\n* Verilog,unit: lint-check unit tests by hirooih · Pull Request #3787\n* Verilog: fix for continuous assignment delays by hirooih · Pull Request #3786\n* RpmSpec: added references by masatake · Pull Request #3784\n* Protobuf: reduce calling cppGetLastCharOrStringContents by masatake · Pull Request #3783\n* LdScript: reject \" and ' as a part of an identifier by masatake · Pull Request #3782\n* Cxx: ignore alignas by masatake · Pull Request #3781\n* main: reserve errno in external sorting by masatake · Pull Request #3779\n* Tmain: add a case for testing the Perl/Perl6 selector by masatake · Pull Request #3778\n* MatLab: return appropriate tags for set get methods + unit  by portalgun · Pull Request #3773\n* build-sys: release note for 6.1 by masatake · Pull Request #3774\n* Ruby: don't make a scope for \"Class.new...\"  with no block by masatake · Pull Request #3733\n* Fix typo in asm.c by eltociear · Pull Request #3757\n* Javascript: multiple prototype assignments by jafl · Pull Request #3770\n* dsl: use strtol instead of es_read_from_string by masatake · Pull Request #3769\n* JavaScript: additional fix for get & set, when specified in prototype by jafl · Pull Request #3765\n* Fix compiler warnings by jafl · Pull Request #3764\n* JavaScript: treat \"get\" and \"set\" as function names… by jafl · Pull Request #3761\n* JavaScript: allow array index after 'this' keyword by jafl · Pull Request #3762\n* JavaScript: report object fields specified via shortcut syntax by jafl · Pull Request #3763\n* JavaScript: move unit test from review-needed to parser-javascript by jafl · Pull Request #3760\n* main: make --version and --help options work even if a broken .ctags is given by masatake · Pull Request #3756\n* docs(web),cosmetic: update optlib.rst typo removed by artemnovichenko · Pull Request #3753\n* Markdown: set the parser-version 1.1 by masatake · Pull Request #3752\n* Misc fix by masatake · Pull Request #3751\n* Markdown: add hashtags functionality by jiangyinzuo · Pull Request #3747\n* Markdown: accept sections in the line started from spaces by masatake · Pull Request #3750\n* Various minor fixes by masatake · Pull Request #3742\n* LdScript: support SORT keyword by masatake · Pull Request #3743\n* libreadtags: pull the latest version by masatake · Pull Request #3735\n* Fix many calls to ctype functions by b4n · Pull Request #3734\n* vstring: Avoid int -> char truncation warnings by b4n · Pull Request #3690\n* lregex: optimize substitute() by masatake · Pull Request #3728\n* Misc fix by masatake · Pull Request #3731\n* erlang: Fix crash parsing directives longer than 31 characters by b4n · Pull Request #3726\n* Misc fix by masatake · Pull Request #3724\n* verilog: treat a text-macro as an identifier by hirooih · Pull Request #3722\n* readtags: fix a bug compiling a formatter wrongly if giving --formatter long option by masatake · Pull Request #3723\n* Verilog: support virtual interface variables by hirooih · Pull Request #3720\n* units.py: don't use color if NO_COLOR is specified by masatake · Pull Request #3721\n* Suppress warning by masatake · Pull Request #3714\n* GDScript : mark xtag bit for implicitClass xtags by masatake · Pull Request #3717\n* Fortran: fix wrongly specified xtag type by masatake · Pull Request #3718\n* docs(web): sphinx minor fixes by masatake · Pull Request #3719\n* D: parse template instance types by ntrel · Pull Request #3716\n* D: fix parsing parameter with pointer by ntrel · Pull Request #3715\n* Misc fix by masatake · Pull Request #3713\n* D: set template members parent name by ntrel · Pull Request #3707\n* D: remove `overload`, not a keyword by ntrel · Pull Request #3710\n* D: parse contract expressions by ntrel · Pull Request #3708\n* D: parse const(T), immutable, inout and shared type qualifiers by ntrel · Pull Request #3709\n* readtags: canonicalize the input file name based on CWD ptag by masatake · Pull Request #3304\n* C-based parsers,style: adjust placements of \"{\" after if by masatake · Pull Request #3706\n* D: parse user-defined attributes by ntrel · Pull Request #3701\n* Circleci: add  fedora 38 by masatake · Pull Request #3705\n* main: add missing const modifiers by masatake · Pull Request #3699\n* autoit: Drop $ from variable names by techee · Pull Request #3697\n* C++: accept prototypes starting from :: operator by masatake · Pull Request #3694\n* main: revise bit fields in tagEntryInfo by masatake · Pull Request #3695\n* Misc fix by masatake · Pull Request #3691\n* AutoIt: Slightly optimize parsing #region by b4n · Pull Request #3689\n* main,refactor: delete 'inCorkQueue' parameter from attachParserField() by masatake · Pull Request #3687\n* Optscript: add _foreignreftag operator by masatake · Pull Request #3686\n* Misc fix by masatake · Pull Request #3685\n* Terraform: new parser by masatake · Pull Request #3684\n* main: Don't strdup the inputFileName when storing a tag to the corkQueue by masatake · Pull Request #3682\n* Misc fix by masatake · Pull Request #3681\n* Quarto: new parser by masatake · Pull Request #3677\n* Misc fix by masatake · Pull Request #3679\n* Ruby: skip if __DATA__ is found by masatake · Pull Request #3676\n* SQL: handle \"DATABASE\" and \"SCHEMA\" keywords specially only when they come after \"CREATE\" by masatake · Pull Request #3674\n* docs(web): add ctags-lang-kconfig.7.rst by masatake · Pull Request #3673\n* SQL: Skip PL/SQL selection directives and add sanity check for inquiry directive size by techee · Pull Request #3654\n* misc/review: add \"accept\" command to the Tmain inspector by masatake · Pull Request #3672\n* Fortran: add \"linkName\" extra by masatake · Pull Request #3671\n* Cxx: scan the cork queue instead of the symtab to fill nth fields by masatake · Pull Request #3642\n* main: add quick path for looking up too long strings in the keyword table by techee · Pull Request #3664\n* main,cosmetic: fix misspelling by jafl · Pull Request #3667\n* Powershell: fix string escape issue by iaalm · Pull Request #3661\n* Verilog: all text macro map to new kindDefinition:define  by my2817 · Pull Request #3653\n* Fix typo in conditional in C++ parser by al42and · Pull Request #3646\n* Tcl: don't include '\"' char as a part of identifiers by masatake · Pull Request #3639\n* GitHubActions: fix testing-openbsd.yml automake version broken issue by leleliu008 · Pull Request #3640\n* Ruby:  handle curly bracket by masatake · Pull Request #3633\n* Kconfig: support the  macro language by masatake · Pull Request #3632\n* Ldscript:  improve tagging versions in VERSION commands by masatake · Pull Request #3631\n* CPreProcessor:  don't include the newline after a backslash in string or char literals by masatake · Pull Request #3629\n* C,Asm,LdScript: minor fixes by masatake · Pull Request #3623\n* Markdown: fix the condition to detect code blocks by masatake · Pull Request #3626\n* C++,ObjectiveC,C,main: fix  the broken selector for .h by masatake · Pull Request #3622\n* Cxx: support typeof and __typeof__ keywords of the gcc extension by masatake · Pull Request #3621\n* Various preparations by masatake · Pull Request #3617\n* readtags: unescape input field (a.k.a {tagfile}) only if TAG_OUTPUT_MODE is u-ctags and TAG_OUTPUT_FILESEP is slash by masatake · Pull Request #3599\n* main: introduce --_paramdef-<LANG>=<NAME>,<DESCRIPTION> option by masatake · Pull Request #3613\n* Perl: skip string literals when collecting heredoc markers by masatake · Pull Request #3592\n* Org:  optimize by masatake · Pull Request #3611\n* GitHub Actions: fix testing-mac.yml Homebrew upgrade python@3.10 and python@3.11 failed problem by leleliu008 · Pull Request #3610\n* Systemtap: add new role \"attached\" for \"probe\" kind , and run CPreProcessor as a guest parser  by masatake · Pull Request #3607\n* C++,C: record consteval, constinit, thread_local, and __thread to properties: field by masatake · Pull Request #3602\n* HTML: introduce a specialized tokenizer for script areas by masatake · Pull Request #3598\n\n\nIssues close or partially closed via above pull requests\n---------------------------------------------------------------------\n\n.. generated by misc/news.bash issue [v6.0.0...]\n\n* YAML: extract keys (with scope) for I18n Ruby Gem · Issue #3523\n* docs(man): write about using multiple parsers for single input file · Issue #3888\n* Write about kind collisions to ctags-faq(7) · Issue #3007\n* create annotation tags instead of lightweight tag · Issue #3767\n* CPreProcessor: Assertion `'c >= 0 && c <= 0xff'` failed · Issue #3771\n* Convert NEWS.md to NEWS.rst · Issue #3874\n* [Question] Defining new regex-based tags with scope defined by built-in `ctags` kinds · Issue #3637\n* Warning reported when running make units · Issue #3865\n* Wording · Issue #3830\n* BibTeX: \".\" in label · Issue #3823\n* Bibtex - include types defined on biblatex package · Issue #3802\n* AIX compiling from source is failing · Issue #3807\n* LdScript: using cppGetc() in wrong ways · Issue #3449\n* Cxx: the way of handling alignas · Issue #3780\n* main: ctags option processing fails if \"Language already defined\", including ctags --help · Issue #2935\n* Markdown: tagging a chapter unexpectedly · Issue #3748\n* units.py: support NO_COLOR (https://no-color.org/) · Issue #3688\n* Request: filename related functions in readtags expressions · Issue #3168\n* C++: fully qualified return type breaks parsing prototypes · Issue #3693\n* SQL:  Warning: ignoring null tag in ... /src/test/regress/sql/collate.icu.utf8.sql(line: 412) · Issue #3636\n* Fortran: Improve handling of case insensitivity · Issue #3668\n* C/C++: Endless parse large file · Issue #3634\n* Tcl parser - Ctags can not generating tags for some proc · Issue #3638\n* Markdown: comments within shell code of markdown files are recognized as chapters · Issue #3625\n* C: support typeof gcc extension · Issue #3620\n* main: use escape sequences when printing pseudo tags as explained in tags(5) · Issue #3577\n* readtags: improper handling of escape sequences in input field · Issue #3559\n* Perl: Incorrectly sees << inside a string as start of a heredoc · Issue #3588\n* C++: Output information on `constexpr` and `consteval` functions · Issue #3539\n* html: apostrophe in JavaScript comment breaks guest parser · Issue #3581\n* HTML: HTML comment starter in JavaScript area · Issue #3597\n* html: apostrophe in JavaScript comment breaks guest parser · Issue #3581\n* HTML: HTML comment starter in JavaScript area · Issue #3597\n"
  },
  {
    "path": "docs/news/6-2-0.rst",
    "content": "======================================================================\nChanges in 6.2.0\n======================================================================\n\nThis page lists only the most significant changes as remembered.  Use\ngit-log to review changes not enumerated here, especially in language\nparsers.\n\nNew and extended options and their flags\n---------------------------------------------------------------------\n\n``--list-output-formats`` option\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSee :ref:`option_listing` in :ref:`ctags(1) <ctags(1)>`.\n\n``nulltag``/``z`` extra\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nUniversal Ctags now supports tags (*null tags*) having empty strings as their names.\nSee :ref:`extras` in :ref:`ctags(1) <ctags(1)>`.\n\n.. note::\n\n   * ``libreadtags`` and ``readtags`` do not support the null tags yet.\n   * Only ``json`` and ``xref`` output formats support the null tags.\n\nIncompatible changes\n---------------------------------------------------------------------\n\n* [readtags] make -Q,--filter not work on ptags when -P,--with-pseudo-tags is specified together\n\n  With this version, ``-Q,--filter`` option doesn't affect the pseudo tags listed\n  with ``-P,--with-pseudo-tags`` option.  ``-Q,--filter`` option specified wth\n  ``-P,--with-pseudo-tags`` option affect only regular tags.\n\n  To extract speicifed pseudo tags, use ``-Q,--filter`` option with\n  ``-D,--list-pseudo`` action.\n\nParser related changes\n---------------------------------------------------------------------\n\n#4026\n   Integrate `pegof <https://github.com/dolik-rce/pegof>`_ to our build process.\n\nNew parsers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe following parsers have been added:\n\n* SELinuxIntefae *M4 based subparser*\n* SELinuxTypeEnforcement *optlib*\n* PythonEntryPoints *subparser*\n* Scdoc *optlib*\n* JNI *subparser*\n* TypeSpec *parser*\n\n  + TypeSpec by Kaisheng Xu · Pull Request #4243\n\n.. note:: We added a TOML as a new parser in this version. However,\n\t\t  after adding it, we learned its implementation didn't work\n\t\t  entirely. So we deleted the TOML parser, and Cargo subparser\n\t\t  runs on the TOML parser from this \"New parsers\" list.\n\t\t  See `TOML: infinite loop <https://github.com/universal-ctags/ctags/issues/4096>`__\n\t\t  about how it doesn't work.\n\nChanges about parser specific kinds, roles, fields, and extras\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. See the output of ./misc/news.bash man [v6.1.0]\n\n* C++\n\n  + New kinds `module` and `partition`\n  + New roles `imported` and `exported` for `header` kind\n\n* Clojure\n\n  + New kind `unknown`\n  + New field `definer`\n\n* EmacsLisp\n\n  + New field `definer`\n\n* LEX\n\n  + New role `grouping` for `cond` kind\n\n* Lisp\n\n  + New kinds `class`, `generic`, `method`, `parameter`, `struct`, and `type`\n\n* Make\n\n  + New extra `CppDef`\n\n* Meson\n\n  + New kinds `cfgdata` and `cfgvar`\n\n* PowerShell\n\n  + New kind `enumlabel`\n\n* Python\n\n  + New role `entryPoint` for `module` and `function` kinds\n\n\tPythonEntryPoints parser emits tag entries having this role.\n\n* Scheme\n\n  + New kind `unknown`\n  + New field `definer`\n\n* SCSS\n\n  + New kind `module`\n  + New role `used` for the `module` kind\n  + New kind `namespace`\n  + New field `module`\n\n* SQL\n\n  + New kind `local`\n\n* Vim\n\n  + New kind `heredoc`\n  + New kind `class`\n\nReadtags\n---------------------------------------------------------------------\n\n* make formatter work with -D,--list-pseudo-tags option\n\n  An example extracting the value of ``!_TAG_PROC_CWD``:\n\n  .. code-block:: console\n\n\t $ ./readtags -t podman.tags -Q '(#/.*CWD.*/ $name)' -F '(list $input #t)' -D\n\t /home/yamato/var/ctags-github/\n\n* make -Q,--filter not work on ptags when -P,--with-pseudo-tags is specified together\n\nMerged pull requests\n---------------------------------------------------------------------\n\n.. note::\n\n   This list is imperfect. masatake cleaned up some pull requests before\n   merging. Though his names is used in \"... by ...\", his is not the\n   primary contributor of the pull requests. See git log for more\n   defatils.\n\n.. generated by ./misc/news.bash pr [v6.1.0...]\n\n* SystemVerilog,Verilog: accept empty names for any kind of language objects by masatake · Pull Request #4257\n* Units(JSON): add a test case for extracting null tags by masatake · Pull Request #4256\n* Misc fix by masatake · Pull Request #4258\n* build(deps): bump cross-platform-actions/action from 0.27.0 to 0.28.0 by dependabot[bot] · Pull Request #4250\n* Kconfig: don't leave without any items on the stack by masatake · Pull Request #4255\n* TypeSpec: new parser by iaalm · Pull Request #4243\n*  JNI: new subparser by masatake · Pull Request #4252\n* operator: add a getter for the language field by masatake · Pull Request #4251\n* Tests for more Clojure tags by aartaka · Pull Request #4126\n* optlib: allow users to set fields and check extras defined in a foreign language by masatake · Pull Request #3960\n* TOML,Cargo: disable the parsers temporarily by masatake · Pull Request #4248\n* Scdoc: new parser by masatake · Pull Request #4244\n* Some minor fixes by masatake · Pull Request #4245\n* circleci: switch to use Fedoa42 by masatake · Pull Request #4246\n* GitHub Actions: set timeout to tests on Qemu by masatake · Pull Request #4247\n* main/read:  revise the offset calculation on nested input stream by masatake · Pull Request #4212\n* Fix wrong parser versions by masatake · Pull Request #4242\n* Miscellaneous minor fixes by masatake · Pull Request #4241\n* SQL: fill signature and typeref fields for functions and procedures by masatake · Pull Request #4238\n* V: don't use multi-bytes chars in debug print by masatake · Pull Request #4236\n* CPreProcessor: (bugfix) don't return negative value other than EOF from unget-buffer by masatake · Pull Request #4234\n* RpmSpec: don't make a FQ tag for sub-packages if -n option is specified on %package line by masatake · Pull Request #4233\n* main: (bugfix) don't reset lineFposMap even in the 2nd pass when the parser runs as a guest by masatake · Pull Request #4231\n* main: fix typos in a parameter name by masatake · Pull Request #4230\n* SQL: extract trigger of Postgresql dialect by masatake · Pull Request #4229\n* JavaScript: (bugfix) consider << operator when detecting JSX area by masatake · Pull Request #4228\n* CPreProcessor,LdScript,Asm: (bugfix) don't expand macros defined with -I by masatake · Pull Request #4226\n* main/read: refactor step1 by masatake · Pull Request #4223\n* C++: skip broken C++11 attributes by masatake · Pull Request #4221\n* PythonEntryPoints: new subparser based on Iniconf parser by masatake · Pull Request #4219\n* lregex: avoid crashes when regex pattern compilation fails by masatake · Pull Request #4220\n* Moose: stop parsing when the base parser stops parsing by masatake · Pull Request #4218\n* units,tmain: add a variable to control the number of threads running test cases by masatake · Pull Request #4215\n* Ada: print debug messages only if --_trace=Ada is given by masatake · Pull Request #4213\n* main: various minor improvements, especially about mio by masatake · Pull Request #4214\n* readtags:  revise feature listing ptags (including an incompatible change) by masatake · Pull Request #4095\n* GitHub Actions: install pkg-config to the msys2 environment by masatake · Pull Request #4211\n* Ada: accept 'end;' as the end of function by masatake · Pull Request #4206\n* Circleci:  (fedora41) update libsqlite.so explicitly by masatake · Pull Request #4209\n* buildsys: (msvc) avoid \"multiply defined symbols\" errors by masatake · Pull Request #4208\n* JavaScript,HTML: skip JSX elements by masatake · Pull Request #4191\n* CPreProcessor: adjust line numbers when reading characters from unget-chars-buffer by masatake · Pull Request #4198\n* JavaScript: don't extract local constants and variables defined in arrow functions by masatake · Pull Request #4197\n* Asm: support Cpp macro arguments spanning multiple lines by masatake · Pull Request #4201\n* JavaScript: Fix held tokens breaking implicit semicolon insertion by b4n · Pull Request #4193\n* Ruby  minor improvements by masatake · Pull Request #4190\n* Units(Meson): add a case testing extracting config variables by masatake · Pull Request #4189\n* Meson: extract config variables by masatake · Pull Request #4186\n* CUDA: support function parameters with default values by masatake · Pull Request #4188\n* build(deps): bump cross-platform-actions/action from 0.25.0 to 0.27.0 by dependabot[bot] · Pull Request #4183\n* CPreProcessor: support variadic macros with GNU cpp extension syntax  by masatake · Pull Request #4184\n* SELinuxTypeEnforcement: fill typeref: field for alias kind objects by masatake · Pull Request #4180\n* optlib2c: make the error message more specific when a wrong datatype is given by masatake · Pull Request #4179\n* main:  provide the way to specify data taype in --_fielddef option by masatake · Pull Request #4178\n* main: support integer field in the writers by masatake · Pull Request #4177\n* Kotlin: fix annotation parsing by dolik-rce · Pull Request #4176\n* main: FIX the way to print boolean typed parser specific fields correctly in {xref,ctags} output by masatake · Pull Request #4174\n* Lisp: introduce version 0.0 of lisp meta parser by masatake · Pull Request #4130\n* Parsers for files defining SELinux policy by masatake · Pull Request #4173\n* various minor fixes by masatake · Pull Request #4172\n* optscropt: fix _scopedepth operator by masatake · Pull Request #4170\n* SCSS: support modules specified with single-quote chars like @use 'foo'  by masatake · Pull Request #4169\n* SCSS: extract modules and namespaces from @use \"...\" by masatake · Pull Request #4168\n* Tcl: extract null tags by masatake · Pull Request #4167\n* JavaScript: destructuring binding by masatake · Pull Request #3435\n* JSON: emit full qualified tags by masatake · Pull Request #4165\n* main: add nulltag/z, a new extra by masatake · Pull Request #4152\n* ObjectiveC: (bugfix) extract the line numbers for methods correctly by masatake · Pull Request #4162\n* (System)Verilog: escaped identifiers (LRM 5.6.1) by cousteaulecommandant · Pull Request #4129\n* PowerShell: recognize herestrings by masatake · Pull Request #4145\n* Introducing Universal Ctags Guru on Gurubase.io by kursataktas · Pull Request #4124\n* delete an accidentally commited file by masatake · Pull Request #4143\n* Revise the files for CI (ubi8, fedora, stream10) by masatake · Pull Request #4131\n* units.py: Fix format-NlKkFnP on Windows by k-takata · Pull Request #4137\n* verilog: support ifdef in enum by hirooih · Pull Request #4140\n* verilog: do not add scope to define (#4127) by hirooih · Pull Request #4139\n* Lisp: add def{struct,type,method,class,generic,parameter} kinds and definer field by masatake · Pull Request #4121\n* Verilog: Add final_specifier support for class parse by roccomao · Pull Request #4116\n* Verilog: Fix function parse when return type contains `::` by roccomao · Pull Request #4111\n* Verilog: Skip the escaped characters in string by roccomao · Pull Request #4115\n* verilog.c: keyword \"unsigned1\" should be \"unsigned\", without the 1 by cousteaulecommandant · Pull Request #4110\n* units.py: pass `count' as a keyword argument by masatake · Pull Request #4112\n* iniconf: some more adjustments for parsing TOML by techee · Pull Request #4099\n* treewide: delete more unwated files by masatake · Pull Request #4108\n* Remove unwanted files by k-takata · Pull Request #4107\n* readtags: add tr operator by masatake · Pull Request #4106\n* Meson: handle backshash chars in strings and == operator correctly by masatake · Pull Request #4104\n* Meson: extract benchmark langage objects correctly by masatake · Pull Request #4101\n* readtags:  refactoring for support multiple tag files by masatake · Pull Request #4079\n* Rust: don't put EOF to a vString by masatake · Pull Request #4093\n* GPerf: skip comment lines started from '#' by masatake · Pull Request #4092\n* main: error with more friendly and understandable message when \"tags\" directory exists by masatake · Pull Request #4085\n* Suppress warnings by masatake · Pull Request #4086\n* JavaScript: (bug fix) don't append EOF token to a repr by masatake · Pull Request #4087\n* Make: don't track EOF as a part of value by masatake · Pull Request #4088\n* Update libreadtags by masatake · Pull Request #4080\n* SystemTap: fill the typeref field for functions by masatake · Pull Request #4084\n*  build-sys: eliminate READTAGS_DSL condition  by masatake · Pull Request #4078\n* readtags: refactor for searching multiple tag files by masatake · Pull Request #4074\n* GemSpec: parse %q string by masatake · Pull Request #4077\n* Tmain: run Tmain/readtags-canonicalize-input-names.d only if DSL is enabled in readtags by masatake · Pull Request #4072\n* readtags:  minor fixes by masatake · Pull Request #4071\n* Fix build for Haiku by Begasus · Pull Request #4069\n* dsl: fix the function for hashing integer object by masatake · Pull Request #4067\n* Optscript:  fix bugs in foreigntag proc by masatake · Pull Request #4064\n* Main:  use extras and fields in the foreign language specified in {_language=...} flag by masatake · Pull Request #4059\n* verilog: skip compiler directives in enum definition (#4056) by hirooih · Pull Request #4058\n* Kconfig: fill names of anonymous choices with the values of their prompts by masatake · Pull Request #4057\n* Cargo: new subparser based on TOML parser by masatake · Pull Request #4048\n* iniconf: Allow dot and dash for ini keys by techee · Pull Request #4052\n* Kconfig: avoid stack underflow when filling typeref filed by masatake · Pull Request #4051\n* Kconfig: fill typeref: field by masatake · Pull Request #4050\n* main: make the implementation of --list-languages=_CATEGORY efficient by masatake · Pull Request #4047\n* main: extend --list-languages option to list only parsers using packcc by masatake · Pull Request #4046\n* TOML: new PEG based parser by masatake · Pull Request #3509\n* Fix quotes & option syntax in manpage by JaSpa · Pull Request #4045\n* build-sys,mvc: generate rules for running packcc from source.mak by masatake · Pull Request #4036\n* Fortran: accept $ as parts of names by masatake · Pull Request #4034\n*  Make: add CppDef extra for extracting FOO in -DFOO as a macro of CPreProcessor by masatake · Pull Request #4024\n* Make:  refactor and add comments by masatake · Pull Request #4031\n* build-sys: utilize pegof by masatake · Pull Request #4026\n* Make: minor changes by masatake · Pull Request #4028\n* Circleci:  update images by masatake · Pull Request #4029\n* Make: parse inside define/endef by masatake · Pull Request #4025\n* Haskell: skip multi-line type signature by masatake · Pull Request #4019\n* readtags: mark <or> as a special form by masatake · Pull Request #4022\n* main: fix a typo in an error message by masatake · Pull Request #4014\n* main: report errors when calling ftell(3) fails by masatake · Pull Request #4012\n* Cxx:  fix file field for exported objects by masatake · Pull Request #4010\n* jscript: Fix representation of held tokens by b4n · Pull Request #4008\n* php: Skip class and trait use not to confuse typerefs by b4n · Pull Request #4009\n* C++: record \"export\" in the property field if the keyword is put at a \"using\" declaration by masatake · Pull Request #4006\n* powershell: Parse enum labels by b4n · Pull Request #3998\n* matlab: A couple fixes for corner cases by b4n · Pull Request #3999\n* Pascal: support for inline or one line comments added by masatake · Pull Request #3997\n* JavaScript: Improve support for contextual keywords as identifiers by b4n · Pull Request #3993\n* vera: Explicit fallthrough by b4n · Pull Request #3992\n* docs,man: Fix typos by k-takata · Pull Request #3987\n* dsl: allow to specify a default value in $ and & operators by masatake · Pull Request #3984\n* CI: use codecov/codecov-action by k-takata · Pull Request #3986\n* Update  packcc by masatake · Pull Request #3983\n* C++: extract operators specified in using declarations by masatake · Pull Request #3982\n* main: don't allocate a buffer for tagEntryInfoX::sourceFileName if possible by masatake · Pull Request #3980\n* build-sys: make lto optional by iLeeWell · Pull Request #3978\n* build-sys: fix checking Windows platform with _WIN32 macro by Biswa96 · Pull Request #3977\n* configure.ac: fix result message grammar by glibg10b · Pull Request #3976\n* Automake: add \"makefile-automake\", the name of an emacs mode, as an alias by masatake · Pull Request #3975\n* optscript: add _anongen operator by masatake · Pull Request #3973\n* C++: recognize definitions of variable templates by masatake · Pull Request #3966\n* Asm: relax the condition for accepting characters within a section name by masatake · Pull Request #3964\n* optscript: make the help messages for @[0-9] and [0-9]@ operators easier to understand by masatake · Pull Request #3965\n* FrontMatter: fix the crash for an empty input by masatake · Pull Request #3961\n* add support for loongarch by wuruilong01 · Pull Request #3958\n* main: reset file-position map when input stream is reset by masatake · Pull Request #3953\n* Vim: extract classes by masatake · Pull Request #3951\n* main: fix typos in a variable name by masatake · Pull Request #3957\n* JavaScript: skip static blocks by masatake · Pull Request #3949\n* C++ : support C++20 modules by masatake · Pull Request #3941\n* Terraform: fix two known bugs by ponchoalv · Pull Request #3945\n* C,C++: fix properties field for object defined or declared with structure definitions by masatake · Pull Request #3944\n* LEX: make reference tags for the conditions used for making groups by masatake · Pull Request #3939\n* Docs(web): wrtite about foreign tags by masatake · Pull Request #3934\n* main: count the added tags after emitting parser-specific ptags by masatake · Pull Request #3936\n*  Make: fix wrong end fields for targets having macros on the same line  by masatake · Pull Request #3931\n* Vim:  support vim9script by masatake · Pull Request #3930\n* docs(man),man-test: require \"yaml\" feature in the man-test of I18nRubyGem by masatake · Pull Request #3929\n* Vim: skip heredoc regions  by masatake · Pull Request #3925\n* Fix typo by pepsiman · Pull Request #3926\n* build-sys: enable LTO by masatake · Pull Request #3922\n* build(deps): bump actions/cache from 3 to 4 by dependabot[bot] · Pull Request #3923\n* I18nRubyGem: trim leading colon inside of tag name by masatake · Pull Request #3921\n* Rake: extract m in \"task (:m)\" as a task by masatake · Pull Request #3919\n* Markdown,FrontMatter,YamlFrontMatter: recognize \"...\" as the end of YAML documents by masatake · Pull Request #3918\n* Ruby:  optimize the parser by reducing the numbers of calling strlen by masatake · Pull Request #3916\n* Python: extract n in \"n = SimpleNamespace(\" as namespace/I kind by masatake · Pull Request #3917\n* Ruby: extract m in \"define_method(:m\" as a method by masatake · Pull Request #3908\n* Sh,Zsh: handle options for alias and function built-in commands by masatake · Pull Request #3909\n* docs(web): add the news entry for 6.1.0 by masatake · Pull Request #3910\n* GitHub Actions: add CODECOV_TOKEN to env by masatake · Pull Request #3911\n* Ruby: extract m in \"m = Module.new()\" as a tag with module kind by masatake · Pull Request #3907\n* Post-release administrivia by masatake · Pull Request #3904\n\nIssues close or partially closed via above pull requests\n---------------------------------------------------------------------\n\n.. generated by ./misc/news.bash issue [v6.1.0...]\n\n* TOML: reporting wrong patterns when the parser runs as a sub parser · Issue #4114\n* Just another crash · Issue #4181\n* Java: crash with a multi-byte character · Issue #4222\n* JavaScript: Segfault on jQuery v1.11.0 · Issue #4227\n* ctags  crashes  with memory access violation  while tagging Linux source code · Issue #4225\n* C++: bug in code detecting attributes · Issue #4089\n* Perl: Segfault on Throwable::Error · Issue #4217\n* CPreprocessor,C: macro expands multiple lines · Issue #4018\n* JavaScript:  extract local vars unexpectedly · Issue #4194\n* Issues in CUDA parsing · Issue #4187\n* JavaScript: destructural binding · Issue #1112\n* JSON full attributes path · Issue #4164\n* Support Null Tag · Issue #4151\n* Objective-C method linenumber is the first block (not the function name like in C) · Issue #4161\n* Powershell: (bug) herestr breaks ctags functions list. · Issue #4141\n*  `parsers/args.ctags` was also committed accidentally. · Issue #4135\n* Unwanted files accidentally committed · Issue #4098\n* meson: use benchmark() instead of bench_mark() · Issue #4100\n* \"ctags: Failure on attempt to read file : Is a directory\" · Issue #4081\n* Fortran: How to include \"$\" in variable and function names · Issue #4033\n* Haskell: reference to too generic part of the type signature emitted when tagging Haskell source with multi-line type signature · Issue #4013\n* C++ modules: \"export\" declaration wrongly marked as file-local (static) · Issue #4003\n* tagging pascal language does not recognize one-line-comments '//' · Issue #3988\n* C++: null tag for the code specfying operator in unsing statement · Issue #3981\n* Support XDG specification on Windows · Issue #3969\n* C++:  crash when a variable template is given · Issue #3963\n* C++: variable template · Issue #3962\n* JavaScript static initialization blocks break the tagging of the rest of the class · Issue #3948\n* C++: disappearing pseudo tags · Issue #3935\n* ctags-lang-i18nrubygem test fails without yaml support · Issue #3928\n* Enabling LTO (Was: p5.9.20210221.0: build fails) · Issue #2885\n* I18nRubyGem leading colon inside of tag name · Issue #3920\n* Python: extract SimpleNamespace · Issue #3912\n"
  },
  {
    "path": "docs/news/HEAD.rst",
    "content": "======================================================================\nChanges in 6.?.?\n======================================================================\n\nThis page lists only the most significant changes as remembered.  Use\ngit-log to review changes not enumerated here, especially in language\nparsers.\n\nNew and extended options and their flags\n---------------------------------------------------------------------\n\nNew option: ``--describe-language=<language>``\n\n    Prints the various aspects of the parser implementing the language.\n\nNew column, VER in the output of ``--list-{kinds-full,roles,fields,extras,pseudo-tags}`` options\n\n    Indicates the versions of ctags output (or the parser) introducing the\n    item in the list.\n\nExtend ``--map-<LANG>=`` and ``--langmap=`` options to choose a parser using regular expressions\n\n\t``--map-<LANG>=[+]%REXPR%`` (or ``--langmap=<LANG>:[+]%REXPR%``) maps relative-paths\n\tthat match the regular expression to the given language.\n\n\tThe new ``--list-map-rexprs`` lists all regular-expression-based mappings.\n\n\t``--list-maps`` has also been extended to include regular-expression-based mappings.\n\nIncompatible changes\n---------------------------------------------------------------------\nMessages for broken symlinks are now emitted at NOTICE level instead of\nWARNING.  They are shown by default, but can be suppressed with the\n``--quiet`` option.\n\nParser related changes\n---------------------------------------------------------------------\nJavaScript:\n\n    * A new field \"properties\" was added to indicate that a field or\n      member of a class is static.\n    * Class member names prefixed with # are recognized as private.\n\nC#:\n\n    * Fix a bug that prevents the parser from extracting methods\n\t  if the method has nullable parameters.\n\nMeson:\n\n    * Extract config vars defined inside configuration_data({...}).\n\nPython:\n\n    * Support type statements.\n\nClojure:\n\n    * Verify namespace when extracting tag.\n\n      The older version doesn't consider NAMESPACE when processing\n      input like (NAMESPACE/defn foo ...).\n\n      With this change, the parser emits ``functions`` and/or\n      ``namespaces`` kind tags only if NAMESPACES is\n      \"``clojure.core``\".  For the other namespaces, the parser emits\n      \"``unknown``\" kind tags.\n\nSQL:\n\n    * Add ``type`` kind to extract ``t`` in \"``CREATE TYPE t ...``\".\n\nQemuHX:\n\n    * Extract command in ``{ \"command\", ...``.\n    * Implement a selector arbitrating Haxe and QemuHX parsers, both handling\n\t  ``.hx`` file extension.\n\nGo:\n\n    * Add ``receiver`` field to ``func`` kind tags.\n\nRust:\n\n    * Add ``macro`` field.\n      The Rust parser now extracts definition-like constructs found\n      in macro arguments as tags. For such tags, the parser records\n      the name of the enclosing macro invocation in the ``macro`` field.\n\nNew parsers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe following parsers have been added:\n\n* SINEX: to handle SINEX (Solution INdependent EXchange) files\n* Netfilter: to handle the output of \"nft list ...\" command\n* Prolog\n* DBusService\n* GoMod\n* Odin\n\nChanges about parser specific kinds, roles, fields, and extras\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. See the output of ./misc/news.bash man [v6.2.0]\n\nReadtags\n---------------------------------------------------------------------\n\n* Add ``list`` operator to the filter and sorter engines.\n  The operator was available only in the formatter expression.\n\n  You can use ``member`` and ``list`` together.\n\n  e.g. With the following command line, you can list only tag entries\n  having ``z`` or ``p`` as their kind.\n\n  .. code-block:: console\n\n\t $ readtags -et tags -Q '(member $kind (list \"z\" \"p\" ))' -l\n\nMerged pull requests\n---------------------------------------------------------------------\n\n.. note::\n\n   This list is imperfect. masatake cleaned up some pull requests before\n   merging. Though his names is used in \"... by ...\", his is not the\n   primary contributor of the pull requests. See git log for more\n   defatils.\n\n.. generated by ./misc/news.bash pr [v6.2.0...]\n\nIssues close or partially closed via above pull requests\n---------------------------------------------------------------------\n\n.. generated by ./misc/news.bash issue [v6.1.0...]\n"
  },
  {
    "path": "docs/news.rst",
    "content": "======================================================================\nNEWS\n======================================================================\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\n.. contents:: `Table of contents`\n\t:depth: 3\n\t:local:\n\n----\n\n.. toctree::\n\t:maxdepth: 1\n\n\tversion ?.?.? <news/HEAD.rst>\n\tversion 6.2.0 <news/6-2-0.rst>\n\tversion 6.1.0 <news/6-1-0.rst>\n\tversion 6.0.0 <news/6-0-0.rst>\n"
  },
  {
    "path": "docs/option-file.rst",
    "content": ".. _option_files:\n\nOption files\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n.. Q: shouldn't the section about option files (preload especially) go in\n\ttheir own section somewhere else in the docs? They're not specifically\n\tfor \"Extending ctags\" - they can be used for any command options that\n\tyou want to use permanently. It's really the new language parsers using\n\t--regex-<LANG> and such that are about \"Extending ctags\", no?\n\nAn \"option file\" is a file in which command line options are written line\nby line. ``ctags`` loads it and runs as if the options in the file were\npassed through command line.\n\nThe following file is an example of an option file:\n\n.. code-block:: ctags\n\n\t# Exclude directories that don't contain real code\n\t--exclude=Units\n\t\t# indentation is ignored\n\t\t--exclude=tinst-root\n\t--exclude=Tmain\n\nThe character `#` can be used as a start marker of a line comment.\nWhitespaces at the start of lines are ignored during loading.\n\nAnd it works exactly as if we had called:\n\n.. code-block:: sh\n\n\tctags --exclude=Units --exclude=tinst-root --exclude=Tmain\n\nOrder of loading option files\n......................................................................\n\nOption files are loaded by ``ctags`` automatically at start-up time.\n\nWhich files are loaded at start-up time are very different from Exuberant Ctags.\nSee :ref:`option-file_difference` for the differences and their intentions.\n\nAt start-up time, ``ctags`` loads files having :file:`.ctags` as a\nfile extension under the following statically defined directories:\n\n#. :file:`$XDG_CONFIG_HOME/ctags/`, or :file:`$HOME/.config/ctags/` if :file:`$XDG_CONFIG_HOME` is not defined\n#. :file:`$HOME/.ctags.d/`\n#. :file:`$HOMEDRIVE$HOMEPATH/ctags.d/` (on Windows)\n#. :file:`./.ctags.d/`\n#. :file:`./ctags.d/`\n\n``ctags`` visits the directories in the order listed above for preloading files.\n``ctags`` loads files having :file:`.ctags` as file extension in alphabetical\norder (``strcmp(3)`` is used for comparing, so for example\n:file:`.ctags.d/ZZZ.ctags` will be loaded *before* :file:`.ctags.d/aaa.ctags` in an ordinary locale).\n\nIf a option file includes ``--options=PATHNAME`` option, specified files are\nloaded immediately as described in the next section. ``ctags`` load a option\nfile only once if it is specified multiple times.\n\nFinally if ``--options=PATHNAME`` option is specified on ``ctags`` command line,\noption files specified are load.\n\n``--options=PATHNAME`` option\n......................................................................\nExuberant Ctags also has the ``--options`` option, but you can only specify a\nsingle file to load. Universal Ctags extends the option in two aspects:\n\n- You can specify a directory, to load all the files in that directory.\n- You can specify a PATH list to look in. See next section for details.\n\nSpecifying a directory\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nIf you specify a directory instead of a file as the argument for the\n``--options=PATHNAME``, ``ctags`` will load all files having a\n:file:`.ctags` extension under said directory in alphabetical order.\n\nSpecifying an optlib PATH list\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nMuch like a command line shell, ``ctags`` has an *optlib PATH list* in which it\ncan look for a file (or directory) to load.\n\nWhen loading a file (or directory) specified with ``--options=PATHNAME``,\nctags first checks if ``PATHNAME`` is an absolute path or a relative path.\nAn absolute path starts with '``/``' or '``.``'.\nIf ``PATHNAME`` is an absolute path, ctags tries to load it immediately.\n\nIf, on the contrary, is a relative path, ``ctags`` does two things: First,\nlooks for the file (or directory) in *optlib PATH list* and tries to load it.\n\nIf the file doesn't exist in the PATH list, ``ctags``  treats ``PATHNAME`` as a\npath relative to the working directory and loads the file.\n\nBy default, *optlib PATH list* is empty. To set or add a directory\npath to the list, use ``--optlib-dir=PATH``.\n\nFor setting (adding one after clearing)::\n\n\t--optlib-dir=PATH\n\nFor adding on the beginning of the PATH list::\n\n\t--optlib-dir=+PATH\n\nTips for writing an option file\n......................................................................\n\n* Use ``--quiet --options=NONE`` to disable preloading.\n\n* ``--_echo=MSG`` and  ``--_force-quit=[NUM]`` options are introduced for\n  debugging the process of loading option files. See \"OPTIONS\"\n  section of :ref:`ctags-optlib(7) <ctags-optlib(7)>`.\n\n* Universal Ctags has an ``optlib2c`` script that translates an option file\n  into C source code. Your optlib parser can thus easily become a built-in parser.\n  See :ref:`optlib2c` for details.\n\n.. _option-file_difference:\n\nDifference from Exuberant Ctags\n......................................................................\nQuoted from man page of Exuberant Ctags:\n\n\tFILES\n\t\t- /ctags.cnf (on MSDOS, MSWindows only)\n\t\t- /etc/ctags.conf\n\t\t- /usr/local/etc/ctags.conf\n\t\t- $HOME/.ctags\n\t\t- $HOME/ctags.cnf (on MSDOS, MSWindows only)\n\t\t- .ctags\n\t\t- ctags.cnf (on MSDOS, MSWindows only)\n\n\tIf any of these configuration files exist, each will\n\tbe expected to contain a set of default options\n\twhich are read in the order listed when ctags\n\tstarts, but before the CTAGS environment variable is\n\tread or any command line options are read.  This\n\tmakes it possible to set up site-wide, personal or\n\tproject-level defaults. It is possible to compile\n\tctags to read an additional configuration file\n\tbefore any of those shown above, which will be\n\tindicated if the output produced by the --version\n\toption lists the \"custom-conf\" feature. Options\n\tappearing in the CTAGS environment variable or on\n\tthe command line will override options specified in\n\tthese files. Only options will be read from these\n\tfiles.  Note that the option files are read in\n\tline-oriented mode in which spaces are significant\n\t(since shell quoting is not possible). Each line of\n\tthe file is read as one command line parameter (as\n\tif it were quoted with single quotes). Therefore,\n\tuse new lines to indicate separate command-line\n\targuments.\n\nWhat follows explains the differences and their intentions...\n\n\nDirectory oriented configuration management\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nExuberant Ctags provides a way to customize ctags with options like\n``--langdef=<LANG>`` and ``--regex-<LANG>``. These options are\npowerful and make ctags popular for programmers.\n\nUniversal Ctags extends this idea; we have added new options for\ndefining a parser, and have extended existing options. Defining\na new parser with the options is more than \"customizing\" in\nUniversal Ctags.\n\nTo make easier the maintenance a parser defined using the options, you can put\neach language parser in a different options file. Universal Ctags doesn't\npreload a single file. Instead, Universal Ctags loads all the files having the\n:file:`.ctags` extension under the previously specified directories. If you\nhave multiple parser definitions, put them in different files.\n\nAvoiding option incompatibility issues\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nThe Universal Ctags options are different from those of Exuberant Ctags,\ntherefore Universal Ctags doesn't load any of the files Exuberant Ctags loads at\nstart-up. Otherwise there would be incompatibility issues if Exuberant Ctags\nloaded an option file that used a newly introduced option in Universal Ctags,\nand vice versa.\n\nNo system wide configuration\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nTo make the preload path list short and because it was rarely ever used,\nUniversal Ctags does not load any option files for system wide configuration.\n(i.e., no :file:`/etc/ctags.d`)\n\nUsing :file:`.ctags` for the file extension\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nExtensions :file:`.cnf` and :file:`.conf` are obsolete.\nUse the unified extension :file:`.ctags` only.\n"
  },
  {
    "path": "docs/optlib.rst",
    "content": ".. _optlib:\n\nExtending ctags with Regex parser (*optlib*)\n---------------------------------------------------------------------\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\n.. contents:: `Table of contents`\n\t:depth: 3\n\t:local:\n\n.. TODO:\n\tadd a section on debugging\n\nExuberant Ctags allows a user to add a new parser to ctags with ``--langdef=<LANG>``\nand ``--regex-<LANG>=...`` options.\nUniversal Ctags follows and extends the design of Exuberant Ctags in more\npowerful ways and call the feature as *optlib parser*, which is described in\n:ref:`ctags-optlib(7) <ctags-optlib(7)>` and the following sections.\n\n:ref:`ctags-optlib(7) <ctags-optlib(7)>` is the primary document of the optlib\nparser feature. The following sections provide additional information and more\nadvanced features. Note that some of the features are experimental, and will be\nmarked as such in the documentation.\n\nLots of optlib parsers are included in Universal Ctags,\n`optlib/*.ctags <https://github.com/universal-ctags/ctags/tree/master/optlib>`_.\nThey will be good examples when you develop your own parsers.\n\nA optlib parser can be translated into C source code. Your optlib parser can\nthus easily become a built-in parser. See \":ref:`optlib2c`\" for details.\n\n.. BEGIN: NOT REVIEWED YET\n\nLanguage definition flags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--langdef=<LANG>`` option support additional arguments in the form\nof long flags. Long flags are specified with surrounding '``{``' and\n'``}``'.\n\n``base=LANG``\n\n\tSee \":ref:`defining-subparsers`\".\n\n``bidirectional``, ``dedicated``, and ``shared``\n\n\tSee \":ref:`optlib_directions`\".\n\n``version=CURRENT.AGE``\n\n\tDefine the generation of the interface of the optlib parser. This flag is\n\tmeaningful once the optlib parser becomes a part of Universal Ctags.\n\tSee also the description of ``--version=<language>`` option in\n\t:ref:`ctags(1) <ctags(1)>` and ``TAG_PARSER_VERSION`` pseudo tag\n\tin :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`.\n\n``_autoFQTag``\n\n\tSee \":ref:`autofqtag`\".\n\n``_foreignLanguage=LANG``\n\n\tSee \":ref:`foreigntag`\". Introduced in version 6.1.0.\n\n``--_list-langdef-flags`` lists the flags that can be used in\n``--langdef=<LANG>`` option.\n\n.. END: NOT REVIEWED YET\n\nRegular expression (regex) engine\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUniversal Ctags uses `the POSIX Extended Regular Expressions (ERE)\n<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_\nsyntax as same as Exuberant Ctags by default.\n\nDuring building Universal Ctags the ``configure`` script runs compatibility\ntests of the regex engine in the system library.  If tests pass the engine is\nused, otherwise the regex engine imported from `the GNU Gnulib library\n<https://www.gnu.org/software/gnulib/manual/gnulib.html#Regular-expressions>`_\nis used. In the latter case, ``ctags --list-features`` will contain\n``gnulib_regex``.\n\nSee ``regex(7)`` or `the GNU Gnulib Manual\n<https://www.gnu.org/software/gnulib/manual/gnulib.html#Regular-expressions>`_\nfor the details of the regular expression syntax.\n\n.. note::\n\n\tThe GNU regex engine supports some GNU extensions described `here\n\t<https://www.gnu.org/software/gnulib/manual/gnulib.html#posix_002dextended-regular-expression-syntax>`_.\n\tNote that an optlib parser using the extensions may not work with Universal\n\tCtags on some other systems.\n\nThe POSIX Extended Regular Expressions (ERE) does\n*not* support many of the \"modern\" extensions such as lazy captures,\nnon-capturing grouping, atomic grouping, possessive quantifiers, look-ahead/behind,\netc. It may be notoriously slow when backtracking.\n\nA common error is forgetting that a\nPOSIX ERE engine is always *greedy*; the '``*``' and '``+``' quantifiers match\nas much as possible, before backtracking from the end of their match.\n\nFor example this pattern::\n\n\tfoo.*bar\n\nWill match this entire string, not just the first part::\n\n\tfoobar, bar, and even more bar\n\nAnother detail to keep in mind is how the regex engine treats newlines.\nUniversal Ctags compiles the regular expressions in the ``--regex-<LANG>`` and\n``--mline-regex-<LANG>`` options with ``REG_NEWLINE`` set. What that means is documented\nin the\n`POSIX specification <https://pubs.opengroup.org/onlinepubs/9699919799/functions/regcomp.html>`_.\nOne obvious effect is that the regex special dot any-character '``.``' does not match\nnewline characters, the '``^``' anchor *does* match right after a newline, and\nthe '``$``' anchor matches right before a newline. A more subtle issue is this text from the\nchapter \"`Regular Expressions <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_\";\n\"the use of literal <newline>s or any escape sequence equivalent produces undefined\nresults\". What that means is using a regex pattern with ``[^\\n]+`` is invalid,\nand indeed in glibc produces very odd results. **Never use** '``\\n``' in patterns\nfor ``--regex-<LANG>``, and **never use them** in non-matching bracket expressions\nfor ``--mline-regex-<LANG>`` patterns. For the experimental ``--_mtable-regex-<LANG>``\nyou can safely use '``\\n``' because that regex is not compiled with ``REG_NEWLINE``.\n\nAnd it may also have some known \"quirks\"\nwith respect to escaping special characters in bracket expressions.\nFor example, a pattern of ``[^\\]]+`` is invalid in POSIX ERE, because the '``]``' is\n*not* special inside a bracket expression, and thus should **not** be escaped.\nMost regex engines ignore this subtle detail in POSIX ERE, and instead allow\nescaping it with '``\\]``' inside the bracket expression and treat it as the\nliteral character '``]``'. GNU glibc, however, does not generate an error but\ninstead considers it undefined behavior, and in fact it will match very odd\nthings. Instead you **must** use the more unintuitive ``[^]]+`` syntax. The same\nis technically true of other special characters inside a bracket expression,\nsuch as ``[^\\)]+``, which should instead be ``[^)]+``. The ``[^\\)]+`` will\nappear to work usually, but only because what it is really doing is matching any\ncharacter but '``\\``' *or* '``)``'. The only exceptions for using '``\\``' inside a\nbracket expression are for '``\\t``' and '``\\n``', which ctags converts to their\nsingle literal character control codes before passing the pattern to glibc.\n\nYou should always test your regex patterns against test files with strings that\ndo and do not match. Pay particular emphasis to when it should *not* match, and\nhow *much* it matches when it should.\n\nPerl-compatible regular expressions (PCRE2) engine\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUniversal Ctags optionally supports `Perl-Compatible Regular Expressions (PCRE2)\n<https://www.pcre.org/current/doc/html/pcre2syntax.html>`_ syntax\nonly if the Universal Ctags is built with ``pcre2`` library.\nSee the output of ``--list-features`` option to know whether your Universal\nCtags is built-with ``pcre2`` or not.\n\nPCRE2 *does* support many \"modern\" extensions.\nFor example this pattern::\n\n\tfoo.*?bar\n\nWill match just the first part, ``foobar``, not this entire string,::\n\n\tfoobar, bar, and even more bar\n\nRegex option argument flags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nMany regex-based options described in this document support additional arguments\nin the form of long flags. Long flags are specified with surrounding '``{``' and\n'``}``'.\n\nThe general format and placement is as follows:\n\n.. code-block:: ctags\n\n\t--regex-<LANG>=<PATTERN>/<NAME>/[<KIND>/]LONGFLAGS\n\nSome examples:\n\n.. code-block:: ctags\n\n\t--regex-Pod=/^=head1[ \\t]+(.+)/\\1/c/\n\t--regex-Foo=/set=[^;]+/\\1/v/{icase}\n\t--regex-Man=/^\\.TH[[:space:]]{1,}\"([^\"]{1,})\".*/\\1/t/{exclusive}{icase}{scope=push}\n\t--regex-Gdbinit=/^#//{exclusive}\n\nNote that the last example only has two '``/``' forward-slashes following\nthe regex pattern, as a shortened form when no kind-spec exists.\n\nThe ``--mline-regex-<LANG>`` option also follows the above format. The\nexperimental ``--_mtable-regex-<LANG>`` option follows a slightly\nmodified version as well.\n\nRegex control flags\n......................................................................\n\n.. Q: why even discuss the single-character version of the flags? Just\n\tmake everyone use the long form.\n\nThe regex matching can be controlled by adding flags to the ``--regex-<LANG>``,\n``--mline-regex-<LANG>``, and experimental ``--_mtable-regex-<LANG>`` options.\nThis is done by either using the single character short flags ``b``, ``e`` and\n``i`` flags as explained in the *ctags.1* man page, or by using long flags\ndescribed earlier. The long flags require more typing but are much more\nreadable.\n\nThe mapping between the older short flag names and long flag names is:\n\n=========== =========== ===========\nshort flag  long flag   description\n=========== =========== ===========\nb           basic       Posix basic regular expression syntax.\ne           extend      Posix extended regular expression syntax (default).\ni           icase       Case-insensitive matching.\n=========== =========== ===========\n\n\nSo the following ``--regex-<LANG>`` expression:\n\n.. code-block:: ctags\n\n   --kinddef-m4=d,definition,definitions\n   --regex-m4=/^m4_define\\(\\[([^]$\\(]+).+$/\\1/d/x\n\nis the same as:\n\n.. code-block:: ctags\n\n   --kinddef-m4=d,definition,definitions\n   --regex-m4=/^m4_define\\(\\[([^]$\\(]+).+$/\\1/d/{extend}\n\nThe characters '``{``' and '``}``' may not be suitable for command line\nuse, but long flags are mostly intended for option files.\n\nExclusive flag in regex\n......................................................................\n\nBy default, lines read from the input files will be matched against all the\nregular expressions defined with ``--regex-<LANG>``. Each successfully matched\nregular expression will emit a tag.\n\nIn some cases another policy, exclusive-matching, is preferable to the\nall-matching policy. Exclusive-matching means the rest of regular\nexpressions are not tried if one of regular expressions is matched\nsuccessfully, for that input line.\n\nFor specifying exclusive-matching the flags ``exclusive`` (long) and ``x``\n(short) were introduced. For example, this is used in\n:file:`optlib/gdbinit.ctags` for ignoring comment lines in gdb files,\nas follows:\n\n.. code-block:: ctags\n\n\t--regex-Gdbinit=/^#//{exclusive}\n\nComments in gdb files start with '``#``' so the above line is the first regex\nmatch line in :file:`gdbinit.ctags`, so that subsequent regex matches are\nnot tried for the input line.\n\nIf an empty name pattern (``//``) is used for the ``--regex-<LANG>`` option,\nctags warns it as a wrong usage of the option. However, if the flags\n``exclusive`` or ``x`` is specified, the warning is suppressed.\nThis is useful to ignore matched patterns as above.\n\nNOTE: This flag does not make sense in the multi-line ``--mline-regex-<LANG>``\noption nor the multi-table ``--_mtable-regex-<LANG>`` option.\n\n\nExperimental flags\n......................................................................\n\n.. note:: These flags are experimental. They apply to all regex option\n\ttypes: basic ``--regex-<LANG>``, multi-line ``--mline-regex-<LANG>``,\n\tand the experimental multi-table ``--_mtable-regex-<LANG>`` option.\n\n.. BEGIN: NOT REVIEWED YET\n\n``_anonymous=PREFIX``\n\n\tThis flag allows a regex match to generate an anonymous tag entry.\n\tctags gives a name starting with ``PREFIX`` and emits it.\n\tThis flag is useful to record the position for a language object\n\thaving no name. A lambda function in a functional programming\n\tlanguage is a typical example of a language object having no name.\n\n\tConsider following input (``input.foo``):\n\n\t.. code-block:: lisp\n\n\t\t(let ((f (lambda (x) (+ 1 x))))\n\t\t\t...\n\t\t\t)\n\n\tConsider following optlib file (``foo.ctags``):\n\n\t.. code-block:: ctags\n\t\t:emphasize-lines: 4\n\n\t\t--langdef=Foo\n\t\t--map-Foo=+.foo\n\t\t--kinddef-Foo=l,lambda,lambda functions\n\t\t--regex-Foo=/.*\\(lambda .*//l/{_anonymous=L}\n\n\tYou can get following tags file:\n\n\t.. code-block:: console\n\n\t\t$ u-ctags  --options=foo.ctags -o - /tmp/input.foo\n\t\tLe4679d360100\t/tmp/input.foo\t/^(let ((f (lambda (x) (+ 1 x))))$/;\"\tl\n\n.. END: NOT REVIEWED YET\n\n``_extra``\n\n\tThis flag indicates the tag should only be generated if the given\n\t``extra`` type is enabled, as explained in \":ref:`extra-regex-flag`\".\n\n``_field``\n\n\tThis flag allows a regex match to add additional custom fields to the\n\tgenerated tag entry, as explained in \":ref:`field-regex-flag`\".\n\n``_guest``\n\n\tThis flag is for specifying the area on which a guest parser runs,\n\tas explained in \":ref:`guest-regex-flag`\".\n\n``_language=<LANG>``\n\n\tThis flag is for emitting a foreign tag. See \":ref:`foreigntag`\".\n\tIntroduced in version 6.1.0.\n\n``_role``\n\n\tThis flag allows a regex match to generate a reference tag entry and\n\tspecify the role of the reference, as explained in \":ref:`role-regex-flag`\".\n\n.. _extra-regex-flag:\n\nConditional tagging with extras\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. NEEDS MORE REVIEWS\n\nIf a matched pattern should only be tagged when an ``extra`` flag is enabled,\nmark the pattern with ``{_extra=XNAME}`` where ``XNAME`` is the name of the\nextra. You must define a ``XNAME`` with the\n``--_extradef-<LANG>=XNAME,DESCRIPTION`` option before defining a regex flag\nmarked ``{_extra=XNAME}``.\n\n.. code-block:: python\n\n\tif __name__ == '__main__':\n\t\tdo_something()\n\nTo capture the lines above in a python program (``input.py``), an ``extra`` flag can\nbe used.\n\n.. code-block:: ctags\n\t:emphasize-lines: 1-2\n\n\t--_extradef-Python=main,__main__ entry points\n\t--regex-Python=/^if __name__ == '__main__':/__main__/f/{_extra=main}\n\nThe above optlib (``python-main.ctags``) introduces ``main`` extra to the Python parser.\nThe pattern matching is done only when the ``main`` is enabled.\n\n.. code-block:: console\n\n\t$ ctags --options=python-main.ctags -o - --extras-Python='+{main}' input.py\n\t__main__\tinput.py\t/^if __name__ == '__main__':$/;\"\tf\n\nBy default, ctags assumes the extra is a part of the language specified\nwith `<LANG>` in ``--regex-<LANG>``. Together with ``{_language=<LANG>}``\nflag, you can switch the language of the extra. See \":ref:`foreigntag`\".\nThe combination of these flags is new in version 6.2.0.\n\n.. TODO: this \"fields\" section should probably be moved up this document, as a\n\tsubsection in the \"Regex option argument flags\" section\n\n.. _field-regex-flag:\n\nAdding custom fields to the tag output\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. NEEDS MORE REVIEWS\n\nExuberant Ctags allows just one of the specified groups in a regex pattern to\nbe used as a part of the name of a tag entry.\n\nUniversal Ctags allows using the other groups in the regex pattern.\nAn optlib parser can have its specific fields. The groups can be used as a\nvalue of the fields of a tag entry.\n\nLet's think about `Unknown`, an imaginary language.\nHere is a source file (``input.unknown``) written in `Unknown`:\n\n.. code-block:: java\n\n\tpublic func foo(n, m);\n\tprotected func bar(n);\n\tprivate func baz(n,...);\n\nWith ``--regex-Unknown=...`` Exuberant Ctags can capture ``foo``, ``bar``, and ``baz``\nas names. Universal Ctags can attach extra context information to the\nnames as values for fields. Let's focus on ``bar``. ``protected`` is a\nkeyword to control how widely the identifier ``bar`` can be accessed.\n``(n)`` is the parameter list of ``bar``. ``protected`` and ``(n)`` are\nextra context information of ``bar``.\n\nWith the following optlib file (``unknown.ctags``), ctags can attach\n``protected`` to the field protection and ``(n)`` to the field signature.\n\n.. code-block:: ctags\n\t:emphasize-lines: 5-9\n\n\t--langdef=unknown\n\t--kinddef-unknown=f,func,functions\n\t--map-unknown=+.unknown\n\n\t--_fielddef-unknown=protection,access scope\n\t--_fielddef-unknown=signature,signatures\n\n\t--regex-unknown=/^((public|protected|private) +)?func ([^\\(]+)\\((.*)\\)/\\3/f/{_field=protection:\\1}{_field=signature:(\\4)}\n\t--fields-unknown=+'{protection}{signature}'\n\nFor the line ``protected func bar(n);`` you will get following tags output::\n\n\tbar\tinput.unknown\t/^protected func bar(n);$/;\"\tf\tprotection:protected\tsignature:(n)\n\nLet's see the detail of ``unknown.ctags``.\n\n.. code-block:: ctags\n\n\t--_fielddef-unknown=protection,access scope\n\n``--_fielddef-<LANG>=name,description`` defines a new field for a parser\nspecified by *<LANG>*.  Before defining a new field for the parser,\nthe parser must be defined with ``--langdef=<LANG>``. ``protection`` is\nthe field name used in tags output. ``access scope`` is the description\nused in the output of ``--list-fields`` and ``--list-fields=Unknown``.\n\n.. code-block:: ctags\n\n\t--_fielddef-unknown=signature,signatures\n\nThis defines a field named ``signature``.\n\n.. code-block:: ctags\n\n\t--regex-unknown=/^((public|protected|private) +)?func ([^\\(]+)\\((.*)\\)/\\3/f/{_field=protection:\\1}{_field=signature:(\\4)}\n\nThis option requests making a tag for the name that is specified with the group 3 of the\npattern, attaching the group 1 as a value for ``protection`` field to the tag, and attaching\nthe group 4 as a value for ``signature`` field to the tag. You can use the long regex flag\n``_field`` for attaching fields to a tag with the following notation rule::\n\n\t{_field=FIELDNAME:GROUP}\n\n\n``--fields-<LANG>=[+|-]{FIELDNAME}`` can be used to enable or disable specified field.\n\nWhen defining a new parser specific field, it is disabled by default. Enable the\nfield explicitly to use the field. See \":ref:`Parser specific fields <parser-specific-fields>`\"\nabout ``--fields-<LANG>`` option.\n\n`Passwd` parser is a simple example that uses ``--fields-<LANG>`` option.\n\nBy default, ctags assumes the field is a part of the language specified\nwith `<LANG>` in ``--regex-<LANG>``. Together with ``{_language=<LANG>}``\nflag, you can switch the language of the field. See \":ref:`foreigntag`\".\nThe combination of these flags is new in version 6.2.0.\n\n.. _role-regex-flag:\n\nCapturing reference tags\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. NOT REVIEWED YET\n\nTo make a reference tag with an optlib parser, specify a role with\n``_role`` long regex flag. Let's see an example:\n\n.. code-block:: ctags\n\t:emphasize-lines: 3-6\n\n\t--langdef=FOO\n\t--kinddef-FOO=m,module,modules\n\t--_roledef-FOO.m=imported,imported module\n\t--regex-FOO=/import[ \\t]+([a-z]+)/\\1/m/{_role=imported}\n\t--extras=+r\n\t--fields=+r\n\nA role must be defined before specifying it as value for ``_role`` flag.\n``--_roledef-<LANG>.<KIND>=<ROLE>,<ROLEDESC>`` option is for defining a role.\nSee the line, ``--regex-FOO=...``.  In this parser `FOO`, the name of an\nimported module is captured as a reference tag with role ``imported``.\n\nFor specifying *<KIND>* where the role is defined, you can use either a\nkind letter or a kind name surrounded by '``{``' and '``}``'.\n\nThe option has two parameters separated by a comma:\n\n*<ROLE>*\n\n\tthe role name, and\n\n*<ROLEDESC>*\n\n\tthe description of the role.\n\nThe first parameter is the name of the role. The role is defined in\nthe kind *<KIND>* of the language *<LANG>*. In the example,\n``imported`` role is defined in the ``module`` kind, which is specified\nwith ``m``. You can use ``{module}``, the name of the kind instead.\n\nThe kind specified in ``--_roledef-<LANG>.<KIND>`` option must be\ndefined *before* using the option. See the description of\n``--kinddef-<LANG>`` for defining a kind.\n\nThe roles are listed with ``--list-roles=<LANG>``. The name and description\npassed to ``--_roledef-<LANG>.<KIND>`` option are used in the output like::\n\n\t$ ctags --langdef=FOO --kinddef-FOO=m,module,modules \\\n\t\t\t\t--_roledef-FOO.m='imported,imported module' --list-roles=FOO\n\t#KIND(L/N) NAME     ENABLED DESCRIPTION\n\tm/module   imported on      imported module\n\n\nIf specifying ``_role`` regex flag multiple times with different roles, you can\nassign multiple roles to a reference tag.  See following input of C language\n\n.. code-block:: C\n\n\tx  = 0;\n\ti += 1;\n\nAn ultra fine grained C parser may capture the variable ``x`` with\n``lvalue`` role and the variable ``i`` with ``lvalue`` and ``incremented``\nroles.\n\nYou can implement such roles by extending the built-in C parser:\n\n.. code-block:: ctags\n\t:emphasize-lines: 2-5\n\n\t# c-extra.ctags\n\t--_roledef-C.v=lvalue,locator values\n\t--_roledef-C.v=incremented,incremented with ++ operator\n\t--regex-C=/([a-zA-Z_][a-zA-Z_0-9]*) *=/\\1/v/{_role=lvalue}\n\t--regex-C=/([a-zA-Z_][a-zA-Z_0-9]*) *\\+=/\\1/v/{_role=lvalue}{_role=incremented}\n\n.. code-block:: console\n\n\t$ ctags with --options=c-extra.ctags --extras=+r --fields=+r\n\ti\tinput.c\t/^i += 1;$/;\"\tv\troles:lvalue,incremented\n\tx\tinput.c\t/^x = 0;$/;\"\tv\troles:lvalue\n\n\nScope tracking in a regex parser\n......................................................................\n\nAbout the ``{scope=..}`` flag itself for scope tracking, see \"FLAGS FOR\n--regex-<LANG> OPTION\" section of :ref:`ctags-optlib(7) <ctags-optlib(7)>`.\n\nExample 1:\n\n.. code-block:: python\n\n\t# in /tmp/input.foo\n\tclass foo:\n\tdef bar(baz):\n\t\tprint(baz)\n\tclass goo:\n\tdef gar(gaz):\n\t\tprint(gaz)\n\n.. code-block:: ctags\n\t:emphasize-lines: 7,8\n\n\t# in /tmp/foo.ctags:\n\t--langdef=Foo\n\t--map-Foo=+.foo\n\t--kinddef-Foo=c,class,classes\n\t--kinddef-Foo=d,definition,definitions\n\n\t--regex-Foo=/^class[[:blank:]]+([[:alpha:]]+):/\\1/c/{scope=set}\n\t--regex-Foo=/^[[:blank:]]+def[[:blank:]]+([[:alpha:]]+).*:/\\1/d/{scope=ref}\n\n.. code-block:: console\n\n\t$ ctags --options=/tmp/foo.ctags -o - /tmp/input.foo\n\tbar\t/tmp/input.foo\t/^    def bar(baz):$/;\"\td\tclass:foo\n\tfoo\t/tmp/input.foo\t/^class foo:$/;\"\tc\n\tgar\t/tmp/input.foo\t/^    def gar(gaz):$/;\"\td\tclass:goo\n\tgoo\t/tmp/input.foo\t/^class goo:$/;\"\tc\n\n\nExample 2:\n\n.. code-block:: c\n\n\t// in /tmp/input.pp\n\tclass foo {\n\t\tint bar;\n\t}\n\n.. code-block:: ctags\n\t:emphasize-lines: 7-9\n\n\t# in /tmp/pp.ctags:\n\t--langdef=pp\n\t--map-pp=+.pp\n\t--kinddef-pp=c,class,classes\n\t--kinddef-pp=v,variable,variables\n\n\t--regex-pp=/^[[:blank:]]*\\}//{scope=pop}{exclusive}\n\t--regex-pp=/^class[[:blank:]]*([[:alnum:]]+)[[[:blank:]]]*\\{/\\1/c/{scope=push}\n\t--regex-pp=/^[[:blank:]]*int[[:blank:]]*([[:alnum:]]+)/\\1/v/{scope=ref}\n\n.. code-block:: console\n\n\t$ ctags --options=/tmp/pp.ctags -o - /tmp/input.pp\n\tbar\t/tmp/input.pp\t/^    int bar$/;\"\tv\tclass:foo\n\tfoo\t/tmp/input.pp\t/^class foo {$/;\"\tc\n\n\nExample 3:\n\n.. code-block::\n\n\t# in /tmp/input.docdoc\n\ttitle T\n\t...\n\tsection S0\n\t...\n\tsection S1\n\t...\n\n.. code-block:: ctags\n\t:emphasize-lines: 15,21\n\n\t# in /tmp/doc.ctags:\n\t--langdef=doc\n\t--map-doc=+.docdoc\n\t--kinddef-doc=s,section,sections\n\t--kinddef-doc=S,subsection,subsections\n\n\t--_tabledef-doc=main\n\t--_tabledef-doc=section\n\t--_tabledef-doc=subsection\n\n\t--_mtable-regex-doc=main/section +([^\\n]+)\\n/\\1/s/{scope=push}{tenter=section}\n\t--_mtable-regex-doc=main/[^\\n]+\\n|[^\\n]+|\\n//\n\t--_mtable-regex-doc=main///{scope=clear}{tquit}\n\n\t--_mtable-regex-doc=section/section +([^\\n]+)\\n/\\1/s/{scope=replace}\n\t--_mtable-regex-doc=section/subsection +([^\\n]+)\\n/\\1/S/{scope=push}{tenter=subsection}\n\t--_mtable-regex-doc=section/[^\\n]+\\n|[^\\n]+|\\n//\n\t--_mtable-regex-doc=section///{scope=clear}{tquit}\n\n\t--_mtable-regex-doc=subsection/(section )//{_advanceTo=0start}{tleave}{scope=pop}\n\t--_mtable-regex-doc=subsection/subsection +([^\\n]+)\\n/\\1/S/{scope=replace}\n\t--_mtable-regex-doc=subsection/[^\\n]+\\n|[^\\n]+|\\n//\n\t--_mtable-regex-doc=subsection///{scope=clear}{tquit}\n\n.. code-block:: console\n\n\t% ctags --sort=no --fields=+nl --options=/tmp/doc.ctags -o - /tmp/input.docdoc\n\tSEC0\t/tmp/input.docdoc\t/^section SEC0$/;\"\ts\tline:1\tlanguage:doc\n\tSUB0-1\t/tmp/input.docdoc\t/^subsection SUB0-1$/;\"\tS\tline:3\tlanguage:doc\tsection:SEC0\n\tSUB0-2\t/tmp/input.docdoc\t/^subsection SUB0-2$/;\"\tS\tline:5\tlanguage:doc\tsection:SEC0\n\tSEC1\t/tmp/input.docdoc\t/^section SEC1$/;\"\ts\tline:7\tlanguage:doc\n\tSUB1-1\t/tmp/input.docdoc\t/^subsection SUB1-1$/;\"\tS\tline:9\tlanguage:doc\tsection:SEC1\n\tSUB1-2\t/tmp/input.docdoc\t/^subsection SUB1-2$/;\"\tS\tline:11\tlanguage:doc\tsection:SEC1\n\n\nNOTE: This flag doesn't work well with ``--mline-regex-<LANG>=``.\n\nOverriding the letter for file kind\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. Q: this was fixed in https://github.com/universal-ctags/ctags/pull/331\n\tso can we remove this section?\n\nOne of the built-in tag kinds in Universal Ctags is the ``F`` file kind.\nOverriding the letter for file kind is not allowed in Universal Ctags.\n\n.. warning::\n\n\tDon't use ``F`` as a kind letter in your parser. (See issue `#317\n\t<https://github.com/universal-ctags/ctags/issues/317>`_ on github)\n\n.. _autofqtag:\n\nGenerating fully qualified tags automatically from scope information\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf scope fields are filled properly with ``{scope=...}`` regex flags,\nyou can use the field values for generating fully qualified tags.\nAbout the ``{scope=..}`` flag itself, see \"FLAGS FOR --regex-<LANG>\nOPTION\" section of :ref:`ctags-optlib(7) <ctags-optlib(7)>`.\n\nSpecify ``{_autoFQTag}`` to the end of ``--langdef=<LANG>`` option like\n``--langdef=Foo{_autoFQTag}`` to make ctags generate fully qualified\ntags automatically.\n\n'``.``' is the (ctags global) default separator combining names into a\nfully qualified tag. You can customize separators with\n``--_scopesep-<LANG>=...`` option.\n\ninput.foo::\n\n\tclass X\n\t\tvar y\n\tend\n\nfoo.ctags:\n\n.. code-block:: ctags\n\t:emphasize-lines: 1\n\n\t--langdef=foo{_autoFQTag}\n\t--map-foo=+.foo\n\t--kinddef-foo=c,class,classes\n\t--kinddef-foo=v,var,variables\n\t--regex-foo=/class ([A-Z]*)/\\1/c/{scope=push}\n\t--regex-foo=/end///{placeholder}{scope=pop}\n\t--regex-foo=/[ \\t]*var ([a-z]*)/\\1/v/{scope=ref}\n\nOutput::\n\n\t$ u-ctags --quiet --options=./foo.ctags -o - input.foo\n\tX\tinput.foo\t/^class X$/;\"\tc\n\ty\tinput.foo\t/^\tvar y$/;\"\tv\tclass:X\n\n\t$ u-ctags --quiet --options=./foo.ctags --extras=+q -o - input.foo\n\tX\tinput.foo\t/^class X$/;\"\tc\n\tX.y\tinput.foo\t/^\tvar y$/;\"\tv\tclass:X\n\ty\tinput.foo\t/^\tvar y$/;\"\tv\tclass:X\n\n\n``X.y`` is printed as a fully qualified tag when ``--extras=+q`` is given.\n\n.. NOT REVIEWED YET (--_scopesep)\n\nCustomizing scope separators\n......................................................................\nUse ``--_scopesep-<LANG>=[<parent-kindLetter>]/<child-kindLetter>:<sep>``\noption for customizing if the language uses ``{_autoFQTag}``.\n\n``parent-kindLetter``\n\n\tThe kind letter for a tag of outer-scope.\n\n\tYou can use '``*``' for specifying as wildcards that means\n\t*any kinds* for a tag of outer-scope.\n\n\tIf you omit ``parent-kindLetter``, the separator is used as\n\ta prefix for tags having the kind specified with ``child-kindLetter``.\n\tThis prefix can be used to refer to global namespace or similar concepts if the\n\tlanguage has one.\n\n``child-kindLetter``\n\n\tThe kind letter for a tag of inner-scope.\n\n\tYou can use '``*``' for specifying as wildcards that means\n\t*any kinds* for a tag of inner-scope.\n\n``sep``\n\n\tIn a qualified tag, if the outer-scope has kind and ``parent-kindLetter``\n\tthe inner-scope has ``child-kindLetter``, then ``sep`` is instead in\n\tbetween the scope names in the generated tags file.\n\nspecifying '``*``' as both  ``parent-kindLetter`` and ``child-kindLetter``\nsets ``sep`` as the language default separator. It is used as fallback.\n\nSpecifying '``*``' as ``child-kindLetter`` and omitting ``parent-kindLetter``\nsets ``sep`` as the language default prefix. It is used as fallback.\n\n\nNOTE: There is no ctags global default prefix.\n\nNOTE: ``_scopesep-<LANG>=...`` option affects only a parser that\nenables ``_autoFQTag``. A parser building full qualified tags\nmanually ignores the option.\n\nLet's see an example.\nThe input file is written in Tcl.  Tcl parser is not an optlib\nparser. However, it uses the ``_autoFQTag`` feature internally.\nTherefore, ``_scopesep-Tcl=`` option works well. Tcl parser\ndefines two kinds ``n`` (``namespace``) and ``p`` (``procedure``).\n\nBy default, Tcl parser uses ``::`` as scope separator. The parser also\nuses ``::`` as root prefix.\n\n.. code-block:: tcl\n\n\tnamespace eval N {\n\t\tnamespace eval M {\n\t\t\tproc pr0 {s} {\n\t\t\t\tputs $s\n\t\t\t}\n\t\t}\n\t}\n\n\tproc pr1 {s} {\n\t\tputs $s\n\t}\n\n``M`` is defined under the scope of ``N``. ``pr0`` is defined\tunder the scope\nof ``M``. ``N`` and ``pr1`` are at top level (so they are candidates to be added\nprefixes). ``M`` and ``N`` are language objects with ``n`` (``namespace``) kind.\n``pr0`` and ``pr1`` are language objects with ``p`` (``procedure``) kind.\n\n.. code-block:: console\n\n\t$ ctags -o - --extras=+q input.tcl\n\t::N\tinput.tcl\t/^namespace eval N {$/;\"\tn\n\t::N::M\tinput.tcl\t/^\tnamespace eval M {$/;\"\tn\tnamespace:::N\n\t::N::M::pr0\tinput.tcl\t/^\t\tproc pr0 {s} {$/;\"\tp\tnamespace:::N::M\n\t::pr1\tinput.tcl\t/^proc pr1 {s} {$/;\"\tp\n\tM\tinput.tcl\t/^\tnamespace eval M {$/;\"\tn\tnamespace:::N\n\tN\tinput.tcl\t/^namespace eval N {$/;\"\tn\n\tpr0\tinput.tcl\t/^\t\tproc pr0 {s} {$/;\"\tp\tnamespace:::N::M\n\tpr1\tinput.tcl\t/^proc pr1 {s} {$/;\"\tp\n\nLet's change the default separator to ``->``:\n\n.. code-block:: console\n\t:emphasize-lines: 1\n\n\t$ ctags -o - --extras=+q --_scopesep-Tcl='*/*:->' input.tcl\n\t::N\tinput.tcl\t/^namespace eval N {$/;\"\tn\n\t::N->M\tinput.tcl\t/^\tnamespace eval M {$/;\"\tn\tnamespace:::N\n\t::N->M->pr0\tinput.tcl\t/^\t\tproc pr0 {s} {$/;\"\tp\tnamespace:::N->M\n\t::pr1\tinput.tcl\t/^proc pr1 {s} {$/;\"\tp\n\tM\tinput.tcl\t/^\tnamespace eval M {$/;\"\tn\tnamespace:::N\n\tN\tinput.tcl\t/^namespace eval N {$/;\"\tn\n\tpr0\tinput.tcl\t/^\t\tproc pr0 {s} {$/;\"\tp\tnamespace:::N->M\n\tpr1\tinput.tcl\t/^proc pr1 {s} {$/;\"\tp\n\nLet's define '``^``' as default prefix:\n\n.. code-block:: console\n\t:emphasize-lines: 1\n\n\t$ ctags -o - --extras=+q --_scopesep-Tcl='*/*:->' --_scopesep-Tcl='/*:^' input.tcl\n\tM\tinput.tcl\t/^\tnamespace eval M {$/;\"\tn\tnamespace:^N\n\tN\tinput.tcl\t/^namespace eval N {$/;\"\tn\n\t^N\tinput.tcl\t/^namespace eval N {$/;\"\tn\n\t^N->M\tinput.tcl\t/^\tnamespace eval M {$/;\"\tn\tnamespace:^N\n\t^N->M->pr0\tinput.tcl\t/^\t\tproc pr0 {s} {$/;\"\tp\tnamespace:^N->M\n\t^pr1\tinput.tcl\t/^proc pr1 {s} {$/;\"\tp\n\tpr0\tinput.tcl\t/^\t\tproc pr0 {s} {$/;\"\tp\tnamespace:^N->M\n\tpr1\tinput.tcl\t/^proc pr1 {s} {$/;\"\tp\n\nLet's override the specification of separator for combining a\nnamespace and a procedure with '``+``': (About the separator for\ncombining a namespace and another namespace, ctags uses the default separator.)\n\n.. code-block:: console\n\t:emphasize-lines: 1\n\n\t$ ctags -o - --extras=+q --_scopesep-Tcl='*/*:->' --_scopesep-Tcl='/*:^' --_scopesep-Tcl='n/p:+' input.tcl\n\tM\tinput.tcl\t/^\tnamespace eval M {$/;\"\tn\tnamespace:^N\n\tN\tinput.tcl\t/^namespace eval N {$/;\"\tn\n\t^N\tinput.tcl\t/^namespace eval N {$/;\"\tn\n\t^N->M\tinput.tcl\t/^\tnamespace eval M {$/;\"\tn\tnamespace:^N\n\t^N->M+pr0\tinput.tcl\t/^\t\tproc pr0 {s} {$/;\"\tp\tnamespace:^N->M\n\t^pr1\tinput.tcl\t/^proc pr1 {s} {$/;\"\tp\n\tpr0\tinput.tcl\t/^\t\tproc pr0 {s} {$/;\"\tp\tnamespace:^N->M\n\tpr1\tinput.tcl\t/^proc pr1 {s} {$/;\"\tp\n\nLet's override the definition of prefix for a namespace with '``@``':\n(About the prefix for procedures, ctags uses the default prefix.)\n\n.. code-block:: console\n\t:emphasize-lines: 1\n\n\t$ ctags -o - --extras=+q --_scopesep-Tcl='*/*:->' --_scopesep-Tcl='/*:^' --_scopesep-Tcl='n/p:+' --_scopesep-Tcl='/n:@' input.tcl\n\t@N\tinput.tcl\t/^namespace eval N {$/;\"\tn\n\t@N->M\tinput.tcl\t/^\tnamespace eval M {$/;\"\tn\tnamespace:@N\n\t@N->M+pr0\tinput.tcl\t/^\t\tproc pr0 {s} {$/;\"\tp\tnamespace:@N->M\n\tM\tinput.tcl\t/^\tnamespace eval M {$/;\"\tn\tnamespace:@N\n\tN\tinput.tcl\t/^namespace eval N {$/;\"\tn\n\t^pr1\tinput.tcl\t/^proc pr1 {s} {$/;\"\tp\n\tpr0\tinput.tcl\t/^\t\tproc pr0 {s} {$/;\"\tp\tnamespace:@N->M\n\tpr1\tinput.tcl\t/^proc pr1 {s} {$/;\"\tp\n\n\nMulti-line pattern match\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWe often need to scan multiple lines to generate a tag, whether due to\nneeding contextual information to decide whether to tag or not, or to\nconstrain generating tags to only certain cases, or to grab multiple\nsubstrings to generate the tag name.\n\nUniversal Ctags has two ways to accomplish this: *multi-line regex options*,\nand an experimental *multi-table regex options* described later.\n\nThe newly introduced ``--mline-regex-<LANG>`` is similar to ``--regex-<LANG>``\nexcept the pattern is applied to the whole file's contents, not line by line.\n\nThis example is based on an issue `#219\n<https://github.com/universal-ctags/ctags/issues/219>`_ posted by\n@andreicristianpetcu:\n\n.. code-block:: java\n\n\t// in input.java:\n\n\t@Subscribe\n\tpublic void catchEvent(SomeEvent e)\n\t{\n\t\treturn;\n\t}\n\n\t@Subscribe\n\tpublic void\n\trecover(Exception e)\n\t{\n\t\treturn;\n\t}\n\nThe above java code is similar to the Java `Spring <https://spring.io>`_\nframework. The ``@Subscribe`` annotation is a keyword for the framework, and the\ndeveloper would like to have a tag generated for each method annotated with\n``@Subscribe``, using the name of the method followed by a dash followed by the\ntype of the argument. For example the developer wants the tag name\n``Event-SomeEvent`` generated for the first method shown above.\n\nTo accomplish this, the developer creates a :file:`spring.ctags` file with\nthe following:\n\n.. code-block:: ctags\n\t:emphasize-lines: 4\n\n\t# in spring.ctags:\n\t--langdef=javaspring\n\t--map-javaspring=+.java\n\t--mline-regex-javaspring=/@Subscribe([[:space:]])*([a-z ]+)[[:space:]]*([a-zA-Z]*)\\(([a-zA-Z]*)/\\3-\\4/s,subscription/{mgroup=3}\n\t--fields=+ln\n\nAnd now using :file:`spring.ctags` the tag file has this:\n\n.. code-block:: console\n\n\t$ ctags -o - --options=./spring.ctags input.java\n\tEvent-SomeEvent\tinput.java\t/^public void catchEvent(SomeEvent e)$/;\"\ts\tline:2\tlanguage:javaspring\n\trecover-Exception\tinput.java\t/^    recover(Exception e)$/;\"\ts\tline:10\tlanguage:javaspring\n\nMultiline pattern flags\n......................................................................\n\n.. note:: These flags also apply to the experimental ``--_mtable-regex-<LANG>``\n\toption described later.\n\n``{mgroup=N}``\n\n\tThis flag indicates the pattern should be applied to the whole file\n\tcontents, not line by line. ``N`` is the number of a capture group in the\n\tpattern, which is used to record the line number location of the tag. In the\n\tabove example ``3`` is specified. The start position of the regex capture\n\tgroup 3, relative to the whole file is used.\n\n.. warning:: You **must** add an ``{mgroup=N}`` flag to the multi-line\n\t``--mline-regex-<LANG>`` option, even if the ``N`` is ``0`` (meaning the\n\tstart position of the whole regex pattern). You do not need to add it for\n\tthe multi-table ``--_mtable-regex-<LANG>``.\n\n.. TODO: Q: isn't the above restriction really a bug? I think it is. I should fix it.\n   Q to @masatake-san: Do you mean that {mgroup=0} can be omitted? -> #2918 is opened\n   A. as proposed in #3514, I made {mgroup=N} be a must flag.\n\n``{_advanceTo=N[start|end]}``\n\n\tA regex pattern is applied to whole file's contents iteratively. This long\n\tflag specifies from where the pattern should be applied in the next\n\titeration for regex matching. When a pattern matches, the next pattern\n\tmatching starts from the start or end of capture group ``N``. By default it\n\tadvances to the end of the whole match (i.e., ``{_advanceTo=0end}`` is\n\tthe default).\n\n\n\tLet's think about following input\n\t::\n\n\t   def def abc\n\n\tConsider two sets of options, ``foo.ctags`` and ``bar.ctags``.\n\n\t.. code-block:: ctags\n\t\t:emphasize-lines: 5\n\n\t\t# foo.ctags:\n\t\t--langdef=foo\n\t\t--langmap=foo:.foo\n\t\t--kinddef-foo=a,something,something\n\t\t--mline-regex-foo=/def *([a-z]+)/\\1/a/{mgroup=1}\n\n\n\t.. code-block:: ctags\n\t\t:emphasize-lines: 5\n\n\t\t# bar.ctags:\n\t\t--langdef=bar\n\t\t--langmap=bar:.bar\n\t\t--kinddef-bar=a,something,something\n\t\t--mline-regex-bar=/def *([a-z]+)/\\1/a/{mgroup=1}{_advanceTo=1start}\n\n\t``foo.ctags`` emits following tags output::\n\n\t   def\tinput.foo\t/^def def abc$/;\"\ta\n\n\t``bar.ctags`` emits following tags output::\n\n\t   def\tinput-0.bar\t/^def def abc$/;\"\ta\n\t   abc\tinput-0.bar\t/^def def abc$/;\"\ta\n\n\t``_advanceTo=1start`` is specified in ``bar.ctags``.\n\tThis allows ctags to capture ``abc``.\n\n\tAt the first iteration, the patterns of both\n\t``foo.ctags`` and ``bar.ctags`` match as follows\n\t::\n\n\t\t0   1       (start)\n\t\tv   v\n\t\tdef def abc\n\t\t       ^\n\t\t       0,1  (end)\n\n\t``def`` at the group 1 is captured as a tag in\n\tboth languages. At the next iteration, the positions\n\twhere the pattern matching is applied to are not the\n\tsame in the languages.\n\n\t``foo.ctags``\n\t::\n\n\t\t       0end (default)\n\t\t       v\n\t\tdef def abc\n\n\n\t``bar.ctags``\n\t::\n\n\t\t    1start (as specified in _advanceTo long flag)\n\t\t    v\n\t\tdef def abc\n\n\tThis difference of positions makes the difference of tags output.\n\n\tA more relevant use-case is when ``{_advanceTo=N[start|end]}`` is used in\n\tthe experimental ``--_mtable-regex-<LANG>``, to \"advance\" back to the\n\tbeginning of a match, so that one can generate multiple tags for the same\n\tinput line(s).\n\n.. note:: This flag doesn't work well with scope related flags and ``exclusive`` flags.\n\n\n.. Q: this was previously titled \"Byte oriented pattern matching...\", presumably\n\tbecause it \"matched against the input at the current byte position, not line\".\n\tBut that's also true for --mline-regex-<LANG>, as far as I can tell.\n\nAdvanced pattern matching with multiple regex tables\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. note:: This is a highly experimental feature. This will not go into\n\tthe man page of 6.0. But let's be honest, it's the most exciting feature!\n\nIn some cases, the ``--regex-<LANG>`` and ``--mline-regex-<LANG>`` options are not\nsufficient to generate the tags for a particular language. Some of the common\nreasons for this are:\n\n* To ignore commented lines or sections for the language file, so that\n  tags aren't generated for symbols that are within the comments.\n* To enter and exit scope, and use it for tagging based on contextual\n  state or with end-scope markers that are difficult to match to their\n  associated scope entry point.\n* To support nested scopes.\n* To change the pattern searched for, or the resultant tag for the same\n  pattern, based on scoping or contextual location.\n* To break up an overly complicated ``--mline-regex-<LANG>`` pattern into\n  separate regex patterns, for performance or readability reasons.\n\nTo help handle such things, Universal Ctags has been enhanced with multi-table\nregex matching. The feature is inspired by `lex`, the fast lexical analyzer\ngenerator, which is a popular tool on Unix environments for writing parsers, and\n`RegexLexer <http://pygments.org/docs/lexerdevelopment/>`_ of Pygments.\nKnowledge about them will help you understand the new options.\n\nThe new options are:\n\n``--_tabledef-<LANG>``\n\tDeclares a new regex matching table of a given name for the language,\n\tas described in \":ref:`tabledef`\".\n\n``--_mtable-regex-<LANG>``\n\tAdds a regex pattern and associated tag generation information and flags, to\n\tthe given table, as described in \":ref:`mtable_regex`\".\n\n``--_mtable-extend-<LANG>``\n\tIncludes a previously-defined regex table to the named one.\n\nThe above will be discussed in more detail shortly.\n\nFirst, let's explain the feature with an example. Consider an\nimaginary language `X` has a similar syntax as JavaScript: ``var`` is\nused as defining variable(s), and \"``/* ... */``\" is used for block\ncomments.\n\nHere is our input, :file:`input.x`:\n\n.. code-block:: java\n\n   /* BLOCK COMMENT\n   var dont_capture_me;\n   */\n   var a /* ANOTHER BLOCK COMMENT */, b;\n\nWe want ctags to capture ``a`` and ``b`` - but it is difficult to write a parser\nthat will ignore ``dont_capture_me`` in the comment with a classical regex\nparser defined with ``--regex-<LANG>`` or ``--mline-regex-<LANG>``, because of\nthe block comments.\n\nThe ``--regex-<LANG>`` option only works on one line at a time, so can not know\n``dont_capture_me`` is within comments. The ``--mline-regex-<LANG>`` could\ndo it in theory, but due to the greedy nature of the regex engine it is\nimpractical and potentially inefficient to do so, given that there could be\nmultiple block comments in the file, with '``*``' inside them, etc.\n\nA parser written with multi-table regex, on the other hand, can capture only\n``a`` and ``b`` safely. But it is more complicated to understand.\n\nHere is the 1st version of :file:`X.ctags`:\n\n.. code-block:: ctags\n\n   --langdef=X\n   --map-X=.x\n   --kinddef-X=v,var,variables\n\nNot so interesting. It doesn't really *do* anything yet. It just creates a new\nlanguage named ``X``, for files ending with a :file:`.x` suffix, and defines a\nnew tag for variable kinds.\n\nWhen writing a multi-table parser, you have to think about the necessary states\nof parsing. For the parser of language `X`, we need the following states:\n\n* `toplevel` (initial state)\n* `comment` (inside comment)\n* `vars` (var statements)\n\n.. _tabledef:\n\nDeclaring a new regex table\n......................................................................\n\nBefore adding regular expressions, you have to declare tables for each state\nwith the ``--_tabledef-<LANG>=<TABLE>`` option.\n\nHere is the 2nd version of :file:`X.ctags` doing so:\n\n.. code-block:: ctags\n\t:emphasize-lines: 5-7\n\n\t--langdef=X\n\t--map-X=.x\n\t--kinddef-X=v,var,variables\n\n\t--_tabledef-X=toplevel\n\t--_tabledef-X=comment\n\t--_tabledef-X=vars\n\nFor table names, only characters in the range ``[0-9a-zA-Z_]`` are acceptable.\n\nFor a given language, for each file's input the ctags multi-table parser begins\nwith the first declared table. For :file:`X.ctags`, ``toplevel`` is the one.\nThe other tables are only ever entered/checked if another table specified to do\nso, starting with the first table. In other words, if the first declared table\ndoes not find a match for the current input, and does not specify to go to\nanother table, the other tables for that language won't be used. The flags to go\nto another table are ``{tenter}``, ``{tleave}``, and ``{tjump}``, as described\nlater.\n\n.. _mtable_regex:\n\nAdding a regex to a regex table\n......................................................................\n\nThe new option to add a regex to a declared table is ``--_mtable-regex-<LANG>``,\nand it follows this form:\n\n.. code-block:: ctags\n\n\t--_mtable-regex-<LANG>=<TABLE>/<PATTERN>/<NAME>/[<KIND>]/LONGFLAGS\n\nThe parameters for ``--_mtable-regex-<LANG>`` look complicated. However,\n``<PATTERN>``, ``<NAME>``, and ``<KIND>`` are the same as the parameters of the\n``--regex-<LANG>`` and ``--mline-regex-<LANG>`` options. ``<TABLE>`` is simply\nthe name of a table previously declared with the ``--_tabledef-<LANG>`` option.\n\nA regex pattern added to a parser with ``--_mtable-regex-<LANG>`` is matched\nagainst the input at the current byte position, not line. Even if you do not\nspecify the '``^``' anchor at the start of the pattern, ctags adds '``^``' to\nthe pattern automatically. Unlike the ``--regex-<LANG>`` and\n``--mline-regex-<LANG>`` options, a '``^``' anchor does not mean \"beginning of\nline\" in ``--_mtable-regex-<LANG>``; instead it means the beginning of the\ninput string (i.e., the current byte position).\n\nThe ``LONGFLAGS`` include the already discussed flags for ``--regex-<LANG>`` and\n``--mline-regex-<LANG>``: ``{scope=...}``, ``{mgroup=N}``, ``{_advanceTo=N}``,\n``{basic}``, ``{extend}``, and ``{icase}``. The ``{exclusive}`` flag does not\nmake sense for multi-table regex.\n\nIn addition, several new flags are introduced exclusively for multi-table\nregex use:\n\n``{tenter}``\n\tPush the current table on the stack, and enter another table.\n\n``{tleave}``\n\tLeave the current table, pop the stack, and go to the table that was\n\tjust popped from the stack.\n\n``{tjump}``\n\tJump to another table, without affecting the stack.\n\n``{treset}``\n\tClear the stack, and go to another table.\n\n``{tquit}``\n\tClear the stack, and stop processing the current input file for this\n\tlanguage.\n\nTo explain the above new flags, we'll continue using our example in the\nnext section.\n\n``--_list-mtable-regex-flags`` lists the flags that can be used in\n``--_mtable-regex-<LANG>`` option.\n\nSkipping block comments\n......................................................................\n\nLet's continue with our example. Here is the 3rd version of :file:`X.ctags`:\n\n.. code-block:: ctags\n\t:emphasize-lines: 9-13\n\t:linenos:\n\n\t--langdef=X\n\t--map-X=.x\n\t--kinddef-X=v,var,variables\n\n\t--_tabledef-X=toplevel\n\t--_tabledef-X=comment\n\t--_tabledef-X=vars\n\n\t--_mtable-regex-X=toplevel/\\/\\*//{tenter=comment}\n\t--_mtable-regex-X=toplevel/.//\n\n\t--_mtable-regex-X=comment/\\*\\///{tleave}\n\t--_mtable-regex-X=comment/.//\n\nFour ``--_mtable-regex-X`` lines are added for skipping the block comments. Let's\ndiscuss them one by one.\n\nFor each new file it scans, ctags always chooses the first pattern of the\nfirst table of the parser. Even if it's an empty table, ctags will only try\nthe first declared table. (in such a case it would immediately fail to match\nanything, and thus stop processing the input file and effectively do nothing)\n\nThe first declared table (``toplevel``) has the following regex added to\nit first:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 9\n\n\t--_mtable-regex-X=toplevel/\\/\\*//{tenter=comment}\n\nA pattern of ``\\/\\*`` is added to the ``toplevel`` table, to match the\nbeginning of a block comment. A backslash character is used in front of the\nleading '``/``' to escape the separation character '``/``' that separates the fields\nof ``--_mtable-regex-<LANG>``. Another backslash inside the pattern is used\nbefore the asterisk '``*``', to make it a literal asterisk character in regex.\n\nThe last ``//`` means ctags should not tag something matching this pattern.\nIn ``--regex-<LANG>`` you never use ``//`` because it would be pointless to\nmatch something and not tag it using and single-line ``--regex-<LANG>``; in\nmulti-line ``--mline-regex-<LANG>`` you rarely see it, because it would rarely\nbe useful. But in multi-table regex it's quite common, since you frequently\nwant to transition from one state to another (i.e., ``tenter`` or ``tjump``\nfrom one table to another).\n\nThe long flag added to our first regex of our first table is ``tenter``, which\nis a long flag for switching the table and pushing on the stack. ``{tenter=comment}``\nmeans \"switch the table from toplevel to comment\".\n\nSo given the input file :file:`input.x` shown earlier, ctags will begin at\nthe ``toplevel`` table and try to match the first regex. It will succeed, and\nthus push on the stack and go to the ``comment`` table.\n\nIt will begin at the top of the ``comment`` table (it always begins at the top\nof a given table), and try each regex line in sequence until it finds a match.\nIf it fails to find a match, it will pop the stack and go to the table that was\njust popped from the stack, and begin trying to match at the top of *that* table.\nIf it continues failing to find a match, and ultimately reaches the end of the\nstack, it will stop processing for this file. For the next input file, it will\nbegin again from the top of the first declared table.\n\nGetting back to our example, the top of the ``comment`` table has this regex:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 12\n\n\t--_mtable-regex-X=comment/\\*\\///{tleave}\n\nSimilar to the previous ``toplevel`` table pattern, this one for ``\\*\\/`` uses\na backslash to escape the separator '``/``', as well as one before the '``*``' to\nmake it a literal asterisk in regex. So what it's looking for, from a simple\nstring perspective, is the sequence ``*/``. Note that this means even though\nyou see three backslashes ``///`` at the end, the first one is escaped and used\nfor the pattern itself, and the ``--_mtable-regex-X`` only has ``//`` to\nseparate the regex pattern from the long flags, instead of the usual ``///``.\nThus it's using the shorthand form of the ``--_mtable-regex-X`` option.\nIt could instead have been:\n\n.. code-block:: ctags\n\n\t--_mtable-regex-X=comment/\\*\\////{tleave}\n\nThe above would have worked exactly the same.\n\nGetting back to our example, remember we're looking at the :file:`input.x`\nfile, currently using the ``comment`` table, and trying to match the first\nregex of that table, shown above, at the following location::\n\n\t   ,ctags is trying to match starting here\n\t  v\n\t/* BLOCK COMMENT\n\tvar dont_capture_me;\n\t*/\n\tvar a /* ANOTHER BLOCK COMMENT */, b;\n\nThe pattern doesn't match for the position just after ``/*``, because that\nposition is a space character. So ctags tries the next pattern in the same\ntable:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 13\n\n\t--_mtable-regex-X=comment/.//\n\nThis pattern matches any any one character including newline; the current\nposition moves one character forward. Now the character at the current position is\n'``B``'. The first pattern of the table ``*/`` still does not match with the input. So\nctags uses next pattern again. When the current position moves to the ``*/``\nof the 3rd line of :file:`input.x`, it will finally match this:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 12\n\n\t--_mtable-regex-X=comment/\\*\\///{tleave}\n\nIn this pattern, the long flag ``{tleave}`` is specified. This triggers table\nswitching again. ``{tleave}`` makes ctags switch the table back to the last\ntable used before doing ``{tenter}``. In this case, ``toplevel`` is the table.\nctags manages a stack where references to tables are put. ``{tenter}`` pushes\nthe current table to the stack. ``{tleave}`` pops the table at the top of the\nstack and chooses it.\n\nSo now ctags is back to the ``toplevel`` table, and tries the first regex\nof that table, which was this:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 9\n\n\t--_mtable-regex-X=toplevel/\\/\\*//{tenter=comment}\n\nIt tries to match that against its current position, which is now the\nnewline on line 3, between the ``*/`` and the word ``var``::\n\n\t/* BLOCK COMMENT\n\tvar dont_capture_me;\n\t*/ <--- ctags is now at this newline (/n) character\n\tvar a /* ANOTHER BLOCK COMMENT */, b;\n\nThe first regex of the ``toplevel`` table does not match a newline, so it tries\nthe second regex:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 13\n\n\t--_mtable-regex-X=toplevel/.//\n\nThis matches a newline successfully, but has no actions to perform. So ctags\nmoves one character forward (the newline it just matched), and goes back to the\ntop of the ``toplevel`` table, and tries the first regex again. Eventually we'll\nreach the beginning of the second block comment, and do the same things as before.\n\nWhen ctags finally reaches the end of the file (the position after ``b;``),\nit will not be able to match either the first or second regex of the\n``toplevel`` table, and quit processing the input file.\n\nSo far, we've successfully skipped over block comments for our new ``X``\nlanguage, but haven't generated any tags. The point of ctags is to generate\ntags, not just keep your computer warm. So now let's move onto actually tagging\nvariables...\n\n\nCapturing variables in a sequence\n......................................................................\n\nHere is the 4th version of :file:`X.ctags`:\n\n.. code-block:: ctags\n\t:emphasize-lines: 10,16-19\n\t:linenos:\n\n\t--langdef=X\n\t--map-X=.x\n\t--kinddef-X=v,var,variables\n\n\t--_tabledef-X=toplevel\n\t--_tabledef-X=comment\n\t--_tabledef-X=vars\n\n\t--_mtable-regex-X=toplevel/\\/\\*//{tenter=comment}\n\t--_mtable-regex-X=toplevel/var[ \\n\\t]//{tenter=vars}\n\t--_mtable-regex-X=toplevel/.//\n\n\t--_mtable-regex-X=comment/\\*\\///{tleave}\n\t--_mtable-regex-X=comment/.//\n\n\t--_mtable-regex-X=vars/;//{tleave}\n\t--_mtable-regex-X=vars/\\/\\*//{tenter=comment}\n\t--_mtable-regex-X=vars/([a-zA-Z][a-zA-Z0-9]*)/\\1/v/\n\t--_mtable-regex-X=vars/.//\n\nOne pattern in ``toplevel`` was added, and a new table ``vars`` with four\npatterns was also added.\n\nThe new regex in ``toplevel`` is this:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 10\n\n\t--_mtable-regex-X=toplevel/var[ \\n\\t]//{tenter=vars}\n\nThe purpose of this being in `toplevel` is to switch to the `vars` table when\nthe keyword ``var`` is found in the input stream. We need to switch states\n(i.e., tables) because we can't simply capture the variables ``a`` and ``b``\nwith a single regex pattern in the ``toplevel`` table, because there might be\nblock comments inside the ``var`` statement (as there are in our\n:file:`input.x`), and we also need to create *two* tags: one for ``a`` and one\nfor ``b``, even though the word ``var`` only appears once. In other words, we\nneed to \"remember\" that we saw the keyword ``var``, when we later encounter the\nnames ``a`` and ``b``, so that we know to tag each of them; and saving that\n\"in-variable-statement\" state is accomplished by switching tables to the\n``vars`` table.\n\nThe first regex in our new ``vars`` table is:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 16\n\n\t--_mtable-regex-X=vars/;//{tleave}\n\nThis pattern is used to match a single semi-colon '``;``', and if it matches\npop back to the ``toplevel`` table using the ``{tleave}`` long flag. We\ndidn't have to make this the first regex pattern, because it doesn't overlap\nwith any of the other ones other than the ``/.//`` last one (which must be\nlast for this example to work).\n\nThe second regex in our ``vars`` table is:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 17\n\n\t--_mtable-regex-X=vars/\\/\\*//{tenter=comment}\n\nWe need this because block comments can be in variable definitions::\n\n   var a /* ANOTHER BLOCK COMMENT */, b;\n\nSo to skip block comments in such a position, the pattern ``\\/\\*`` is used just\nlike it was used in the ``toplevel`` table: to find the literal ``/*`` beginning\nof the block comment and enter the ``comment`` table. Because we're using\n``{tenter}`` and ``{tleave}`` to push/pop from a stack of tables, we can\nuse the same ``comment`` table for both ``toplevel`` and ``vars`` to go to,\nbecause ctags will *remember* the previous table and ``{tleave}`` will\npop back to the right one.\n\nThe third regex in our ``vars`` table is:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 18\n\n\t--_mtable-regex-X=vars/([a-zA-Z][a-zA-Z0-9]*)/\\1/v/\n\nThis is nothing special, but is the one that actually tags something: it\ncaptures the variable name and uses it for generating a ``variable`` (shorthand\n``v``) tag kind.\n\nThe last regex in the ``vars`` table we've seen before:\n\n.. code-block:: ctags\n\t:linenos:\n\t:lineno-start: 19\n\n\t--_mtable-regex-X=vars/.//\n\nThis makes ctags ignore any other characters, such as whitespace or the\ncomma '``,``'.\n\n\nRunning our example\n......................................................................\n\n.. code-block:: console\n\n\t$ cat input.x\n\t/* BLOCK COMMENT\n\tvar dont_capture_me;\n\t*/\n\tvar a /* ANOTHER BLOCK COMMENT */, b;\n\n\t$ u-ctags -o - --fields=+n --options=X.ctags input.x\n\tu-ctags -o - --fields=+n --options=X.ctags input.x\n\ta\tinput.x\t/^var a \\/* ANOTHER BLOCK COMMENT *\\/, b;$/;\"\tv\tline:4\n\tb\tinput.x\t/^var a \\/* ANOTHER BLOCK COMMENT *\\/, b;$/;\"\tv\tline:4\n\nIt works!\n\nYou can find additional examples of multi-table regex in our github repo, under\nthe ``optlib`` directory. For example ``puppetManifest.ctags`` is a serious\nexample. It is the primary parser for testing multi-table regex parsers, and\nused in the actual ctags program for parsing puppet manifest files.\n\n\n.. _guest-regex-flag:\n\nScheduling a guest parser with ``_guest`` regex flag\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n.. NOT REVIEWED YET\n\nWith ``_guest`` regex flag, you can run a parser (a guest parser) on an\narea of the current input file.\nSee \":ref:`host-guest-parsers`\" about the concept of the guest parser.\n\nThe ``_guest`` regex flag specifies a *guest spec*, and attaches it to\nthe associated regex pattern.\n\nA guest spec has three fields: *<PARSER>*, *<START>* of area, and *<END>* of area.\nThe ``_guest`` regex flag has following forms::\n\n  {_guest=<PARSER>,<START>,<END>}\n\nctags maintains a data called *guest request* during parsing.  A\nguest request also has three fields: `parser`, `start of area`, and\n`end of area`.\n\nYou, a parser developer, have to fill the fields of guest specs.\nctags inquiries the guest spec when matching the regex pattern\nassociated with it, tries to fill the fields of the guest request,\nand runs a guest parser when all the fields of the guest request are\nfilled.\n\nIf you use `Multi-line pattern match`_ to define a host parser,\nyou must specify all the fields of `guest request`.\n\nOn the other hand if you don't use `Multi-line pattern match`_ to define a host parser,\nctags can fill fields of `guest request` incrementally; more than\none guest specs are used to fill the fields. In other words, you can\nmake some of the fields of a guest spec empty.\n\nThe *<PARSER>* field of ``_guest`` regex flag\n......................................................................\nFor *<PARSER>*, you can specify one of the following items:\n\na name of a parser\n\n\tIf you know the guest parser you want to run before parsing\n\tthe input file, specify the name of the parser. Aliases of parsers\n\tare also considered when finding a parser for the name.\n\n\tAn example of running C parser as a guest parser::\n\n\t\t{_guest=C,...\n\nthe group number of a regex pattern started from '``\\``' (backslash)\n\n\tIf a parser name appears in an input file, write a regex pattern\n\tto capture the name.  Specify the group number where the name is\n\tstored to the parser.  In such case, use '``\\``' as the prefix for\n\tthe number. Aliases of parsers are also considered when finding\n\ta parser for the name.\n\n\tLet's see an example. Git Flavor Markdown (GFM) is a language for\n\tdocumentation. It provides a notation for quoting a snippet of\n\tprogram code; the language treats the area started from ``~~~`` to\n\t``~~~`` as a snippet. You can specify a programming language of\n\tthe snippet with starting the area with\n\t``~~~<THE_NAME_OF_LANGUAGE>``, like ``~~~C`` or ``~~~Java``.\n\n\tTo run a guest parser on the area, you have to capture the\n\t*<THE_NAME_OF_LANGUAGE>* with a regex pattern:\n\n\t.. code-block:: ctags\n\n\t\t--_mtable-regex-Markdown=main/~~~([a-zA-Z0-9][-#+a-zA-Z0-9]*)[\\n]//{_guest=\\1,0end,}\n\n\tThe pattern captures the language name in the input file with the\n\tregex group 1, and specify it to *<PARSER>*::\n\n\t\t{guest=\\1,...\n\nthe group number of a regex pattern started from '``*``' (asterisk)\n\n\tIf a file name implying a programming language appears in an input\n\tfile, capture the file name with the regex pattern where the guest\n\tspec attaches to. ctags tries to find a proper parser for the\n\tfile name by inquiring the langmap.\n\n\tUse '``*``' as the prefix to the number for specifying the group of\n\tthe regex pattern that captures the file name.\n\n\tLet's see an example. Consider you have a shell script that emits\n\ta program code instantiated from one of the templates. Here documents\n\tare used to represent the templates like:\n\n\t.. code-block:: sh\n\n\t\ti=...\n\t\tcat > foo.c <<EOF\n\t\t\tint main (void) { return $i; }\n\t\tEOF\n\n\t\tcat > foo.el <<EOF\n\t\t\t(defun foo () (1+ $i))\n\t\tEOF\n\n\tTo run guest parsers for the here document areas, the shell\n\tscript parser of ctags must choose the parsers from the file\n\tnames (``foo.c`` and ``foo.el``):\n\n\t.. code-block:: ctags\n\n\t\t--regex-sh=/cat > ([a-z.]+) <<EOF//{_guest=*1,0end,}\n\n\tThe pattern captures the file name in the input file with the\n\tregex group 1, and specify it to *<PARSER>*::\n\n\t   {_guest=*1,...\n\nThe *<START>* and *<END>* fields of `_guest` regex flag\n......................................................................\n\nThe *<START>* and *<END>* fields specify the area the *<PARSER>* parses.  *<START>*\nspecifies the start of the area. *<END>* specifies the end of the area.\n\nThe forms of the two fields are the same: a regex group number\nfollowed by ``start`` or ``end``. e.g. ``3start``, ``0end``.  The suffixes,\n``start`` and ``end``, represents one of two boundaries of the group.\n\nLet's see an example::\n\n\t{_guest=C,2end,3start}\n\nThis guest regex flag means running C parser on the area between\n``2end`` and ``3start``. ``2end`` means the area starts from the end of\nmatching of the 2nd regex group associated with the flag. ``3start``\nmeans the area ends at the beginning of matching of the 3rd regex\ngroup associated with the flag.\n\nLet's more realistic example.\nHere is an optlib file for an imaginary language `single`:\n\n.. code-block:: ctags\n\t:emphasize-lines: 3\n\n\t--langdef=single\n\t--map-single=.single\n\t--regex-single=/^(BEGIN_C<).*(>END_C)$//{_guest=C,1end,2start}\n\nThis parser can run C parser and extract ``main`` function from the\nfollowing input file::\n\n\tBEGIN_C<int main (int argc, char **argv) { return 0; }>END_C\n\t        ^                                             ^\n\t         `- \"1end\" points here.                       |\n\t                               \"2start\" points here. -+\n\n.. NOT REVIEWED YET\n\n.. _defining-subparsers:\n\nDefining a subparser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBasic\n.........................................................................\n\nAbout the concept of subparser, see \":ref:`base-sub-parsers`\".\n\n``--langdef=<LANG>`` option is extended as\n``--langdef=<LANG>[{base=<LANG>}[{shared|dedicated|bidirectional}]][{_autoFQTag}]`` to define\na subparser for a specified base parser. Combining with ``--kinddef-<LANG>``\nand ``--regex-<KIND>`` options, you can extend an existing parser\nwithout risk of kind confliction.\n\nLet's see an example.\n\ninput.c\n\n.. code-block:: C\n\n\tstatic int set_one_prio(struct task_struct *p, int niceval, int error)\n\t{\n\t}\n\n\tSYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)\n\t{\n\t\t/* ...*/;\n\t}\n\n.. code-block:: console\n\n\t$ ctags  -x --_xformat=\"%20N %10K %10l\"  -o - input.c\n\t    set_one_prio   function          C\n\t SYSCALL_DEFINE3   function          C\n\nC parser doesn't understand that ``SYSCALL_DEFINE3`` is a macro for defining an\nentry point for a system.\n\nLet's define `linux` subparser which using C parser as a base parser (``linux.ctags``):\n\n.. code-block:: ctags\n\t:emphasize-lines: 1,3\n\n\t--langdef=linux{base=C}\n\t--kinddef-linux=s,syscall,system calls\n\t--regex-linux=/SYSCALL_DEFINE[0-9]\\(([^, )]+)[\\),]*/\\1/s/\n\nThe output is change as follows with `linux` parser:\n\n.. code-block:: console\n\t:emphasize-lines: 2\n\n\t$ ctags --options=./linux.ctags -x --_xformat=\"%20N %10K %10l\"  -o - input.c\n\t\t setpriority    syscall      linux\n\t\tset_one_prio   function          C\n\t     SYSCALL_DEFINE3   function          C\n\n``setpriority`` is recognized as a ``syscall`` of `linux`.\n\nUsing only ``--regex-C=...`` you can capture ``setpriority``.\nHowever, there were concerns about kind confliction; when introducing\na new kind with ``--regex-C=...``, you cannot use a letter and name already\nused in C parser and ``--regex-C=...`` options specified in the other places.\n\nYou can use a newly defined subparser as a new namespace of kinds.\nIn addition you can enable/disable with the subparser usable\n``--languages=[+|-]`` option:\n\n.. code-block::console\n\n\t$ ctags --options=./linux.ctags --languages=-linux -x --_xformat=\"%20N %10K %10l\"  -o - input.c\n\t    set_one_prio   function          C\n\t SYSCALL_DEFINE3   function          C\n\n.. _optlib_directions:\n\nDirection flags\n.........................................................................\n\n.. TESTCASE: Units/flags-langdef-directions.r\n\nAs explained in \":ref:`multiple_parsers_directions`\" in\n\":ref:`multiple_parsers`\", you can choose direction(s) how a base parser and a\nguest parser work together with direction flags.\n\nThe following examples are taken from `#1409\n<https://github.com/universal-ctags/ctags/issues/1409>`_ submitted by @sgraham on\ngithub Universal Ctags repository.\n\n``input.cc`` and ``input.mojom`` are input files, and have the same\ncontents::\n\n\tABC();\n\tint main(void)\n\t{\n\t}\n\nC++ parser can capture ``main`` as a function. `Mojom` subparser defined in the\nlater runs on C++ parser and is for capturing ``ABC``.\n\nshared combination\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n``{shared}`` is specified, for ``input.cc``, both tags capture by C++ parser\nand mojom parser are recorded to tags file. For ``input.mojom``, only\ntags captured by mojom parser are recorded to tags file.\n\nmojom-shared.ctags:\n\n.. code-block:: ctags\n\t:emphasize-lines: 1\n\n\t--langdef=mojom{base=C++}{shared}\n\t--map-mojom=+.mojom\n\t--kinddef-mojom=f,function,functions\n\t--regex-mojom=/^[ ]+([a-zA-Z]+)\\(/\\1/f/\n\n.. code-block:: console\n\t:emphasize-lines: 2\n\n\t$ ctags --options=mojom-shared.ctags --fields=+l -o - input.cc\n\tABC\tinput.cc\t/^ ABC();$/;\"\tf\tlanguage:mojom\n\tmain\tinput.cc\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n\n.. code-block:: console\n\t:emphasize-lines: 2\n\n\t$ ctags --options=mojom-shared.ctags --fields=+l -o - input.mojom\n\tABC\tinput.mojom\t/^ ABC();$/;\"\tf\tlanguage:mojom\n\nMojom parser uses C++ parser internally but tags captured by C++ parser are\ndropped in the output.\n\ndedicated combination\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n``{dedicated}`` is specified, for ``input.cc``, only tags capture by C++\nparser are recorded to tags file. For ``input.mojom``, both tags capture\nby C++ parser and mojom parser are recorded to tags file.\n\nmojom-dedicated.ctags:\n\n.. code-block:: ctags\n\t:emphasize-lines: 1\n\n\t--langdef=mojom{base=C++}{dedicated}\n\t--map-mojom=+.mojom\n\t--kinddef-mojom=f,function,functions\n\t--regex-mojom=/^[ ]+([a-zA-Z]+)\\(/\\1/f/\n\n.. code-block:: console\n\n\t$ ctags --options=mojom-dedicated.ctags --fields=+l -o - input.cc\n\tmain\tinput.cc\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n\n.. code-block:: console\n\t:emphasize-lines: 2-3\n\n\t$ ctags --options=mojom-dedicated.ctags --fields=+l -o - input.mojom\n\tABC\tinput.mojom\t/^ ABC();$/;\"\tf\tlanguage:mojom\n\tmain\tinput.mojom\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n\nMojom parser works only when ``.mojom`` file is given as input.\n\nbidirectional combination\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n``{bidirectional}`` is specified, both tags capture by C++ parser and\nmojom parser are recorded to tags file for either input ``input.cc`` and\n``input.mojom``.\n\nmojom-bidirectional.ctags:\n\n.. code-block:: ctags\n\t:emphasize-lines: 1\n\n\t--langdef=mojom{base=C++}{bidirectional}\n\t--map-mojom=+.mojom\n\t--kinddef-mojom=f,function,functions\n\t--regex-mojom=/^[ ]+([a-zA-Z]+)\\(/\\1/f/\n\n.. code-block:: console\n\t:emphasize-lines: 2\n\n\t$ ctags --options=mojom-bidirectional.ctags --fields=+l -o - input.cc\n\tABC\tinput.cc\t/^ ABC();$/;\"\tf\tlanguage:mojom\n\tmain\tinput.cc\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n\n.. code-block:: console\n\t:emphasize-lines: 2-3\n\n\t$ ctags --options=mojom-bidirectional.ctags --fields=+l -o - input.mojom\n\tABC\tinput.cc\t/^ ABC();$/;\"\tf\tlanguage:mojom\n\tmain\tinput.cc\t/^int main(void)$/;\"\tf\tlanguage:C++\ttyperef:typename:int\n\n\n.. BEGIN: NOT REVIEWED YET\n\n.. _foreigntag:\n\nMaking tags of foreign languages\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. TESTCASE: Units/foreign-tags.d\n\nIn some cases, an object for language X is appears in an input of language Y\nfor that you are developing a parser (parser Y). You may want to make a\ntag for the object as a tag for language X, not Y in the parser Y.\n\nFrom the point of view of the parser Y, the tag is called *foreign tag*.\n\nConsider an imaginary language DocC that is for documenting API of libraries\nwritten in C language. You are developing an optlib parser for DocC.\n\ninput.docC:\n\n.. code-block::\n\n\t- function: compress(const char *plain_text, enum algorithm alg) => char *\n\t  Compress a C string PLAING_TEXT with the algorithm specified with ALG.\n\n\t- function: decompress(const char *compressed_byteseq) => char *\n\t  Decompress a byte sequence compressed by compress().\n\nMaking tags for ``compress`` and ``decompress`` as language objects of\nDocC is a standard way. Making them as ``function`` kind reference\ntags with ``documented`` role of C language is the way of foreign\ntagging.\n\n.. note:: Foreign tag is rather newer concept in Universal Ctags. It is\n\t\t  not explored well yet.\n\ndocc.ctags:\n\n.. code-block:: ctags\n\t:linenos:\n\n\t--_roledef-C.f=documented,documented in a API document\n\n\t--langdef=DocC{_foreignLanguage=C}\n\t--map-DocC=.docc\n\t--regex-DocC=/^- +function: *([a-zA-Z_][a-zA-Z_0-9]+)\\(/\\1/f/{_language=C}{_role=documented}\n\nTo make foreign tags for C language, we extend the C parser at line 1: adding\n``documented`` role to ``function/f`` kind.\n\nThe foreign language must be declared with ``_foreignLanguage`` when\ndefining a parser (line 3). When tagging a foreign language object,\nuse ``{_language=<LANG>}`` flag (line 4); ctags looks up the\ndefinitions of the kind for ``f`` and for the role ``documented`` from\nthe C parser instead of ``DocD``.\n\nthe output for input.docc:\n\n.. code-block:: console\n\n\t$ ctags --options=docc.ctags --sort=no--extras=+r --fields=+rlK  -o - input.docc\n\tcompress\tinput.docc\t/^- function: compress(const char *plain_text, enum algorithm alg) => char *$/;\"\tfunction\tlanguage:C\troles:documented\n\tdecompress\tinput.docc\t/^- function: decompress(const char *compressed_byteseq) => char *$/;\"\tfunction\tlanguage:C\troles:documented\n\n\n.. TESTCASE: Tmain/parser-specific-fields-for-foreign-lang.d\n\n``{_language=<LANG>}`` flag affects ``{_field=FIELDNAME:GROUP}`` flag; ctags looks up\nthe field defintion in `<LANG>`.\n\n``{_language=<LANG>}`` flag affects ``{_extra=XNAME}`` flag; ctags looks up\nthe extra defintion in `<LANG>`.\n\n.. END: NOT REVIEWED YET\n\n.. _optlib2c:\n\nTranslating an option file into C source code (optlib2c)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nUniversal Ctags has an ``optlib2c`` script that translates an option file into C\nsource code. Your optlib parser can thus easily become a built-in parser.\n\nTo add your optlib file, ``foo.ctags``, into ctags do the following steps;\n\n* copy ``foo.ctags`` file on ``optlib/`` directory\n* add ``foo.ctags`` on ``OPTLIB2C_INPUT`` variable in ``source.mak``\n* add ``fooParser`` on ``PARSER_LIST`` macro variable in ``main/parser_p.h``\n\nYou are encouraged to submit your :file:`.ctags` file to our repository on\ngithub through a pull request. See \":ref:`contributions`\" for more details.\n"
  },
  {
    "path": "docs/optscript.rst",
    "content": ".. _optscript:\n\nOptscript, a programming language for extending optlib parsers\n--------------------------------------------------------------\n\n.. contents:: `Table of contents`\n\t:depth: 3\n\t:local:\n\nPreparation for learning\n~~~~~~~~~~~~~~~~~~~~~~~~\n**Optscript** is an implementation of PostScript(tm) alike stack\noriented general purpose programming language.  Developers of optlib\nparsers can utilize the language for extending their parsers.\n\nYou may not be familiar with a stack oriented programming language.\nThough there are some differences, the syntax and core non-graphical\noperators of Optscript and PostScript are the same. You can get the\nbasic knowledge for using Optscript from the materials for learning\nPostScript.\n\n\"PostScript Language Tutorial & Cookbook\" published by Adobe Systems\nInc. The book is known as \"blue book\". This is the best place to\nstart.  PostScript is a language for controlling printers. So it has\nmany graphical operators. Optscript is for tagging, and doesn't have\nsuch graphical operators. So you can skip the sections about graphics\n(but you may want to read them because the book is written well).\n\nGhostscript (``gs`` or ``gsnd``) is an interpreter for the PostScript\nlanguage and PDF files. Unlike Optscript, it implements the full-set of\nPostScript features including graphical operators. It is available\nunder either the GNU GPL Affero license. You can Ghostscript while\nreading the blue book. Do web searching to know about Ghostscript.\n\n``optscript`` is an command that source files are included in\nUniversal Ctags source tree. You can use it as the replacement of\n``gs``. However, I recommend you to have ``gs`` at hand because\n``optscript`` may have bugs. ``gs`` is much mature than ``optscript``.\nHaving two interpreters helps you to know correct behavior.\n\nThough ``gs`` has much higher qualities than ``optscript``, eventually\nyou may have to build the ``optscript`` command to learn Optscript\nspecific operators. You can built the command with \"``make\noptscript``\".\n\n* red book\n\n  TBW\n\nSyntax extension\n~~~~~~~~~~~~~~~~~~~~~~~~\n\n``?`` is a prefix for representing a character literal.\n\nFor an example, ``?x`` represents 120. This is a short cut for ``(x) 0\nget``.\n\nSome characters has special notation using ``\\``.\n\n``?\\t``\n\n\ttab\n\n``?\\n``\n\n\tnewline\n\n``?\\_``\n\n\tspace\n\n\nThe ``optscript`` command\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can run optscript with no argument:\n\n.. code-block:: console\n\n\t$ ./optsript\n\tOPT>\n\n``OPT>`` is the prompt of the interpreter.\nYou can stop it with ``quit`` operator:\n\n.. code-block:: console\n\n\t$ ./optsript\n\tOPT> quit\n\t$\n\n\nLet's see some example sessions.  To help you understand the session\neasily, Python sessions doing the same as Optscript are also written.\n\n* hello world\n\n  Optscript:\n\n  .. code-block:: console\n\n\tOPT> (hello, world) =\n\thello, world\n\n  Python:\n\n  .. code-block:: console\n\n\t>>> print ('hello, world')\n\thello, world\n\n* Adding\n\n  Optscript:\n\n  .. code-block:: console\n\n\tOPT> 2 3 add =\n\t5\n\n  Python:\n\n  .. code-block:: console\n\n\t>>> print (2 + 3)\n\t5\n\n* Variables\n\n  Optscript:\n\n  .. code-block:: console\n\n\tOPT> /x 2 def\n\tOPT> /y 3 def\n\tOPT> x y add =\n\t5\n\n  Python:\n\n  .. code-block:: console\n\n\t>>> x = 2\n\t>>> y = 3\n\t>>> print (x + y)\n\t5\n\n* Procedures\n\n  Optscript:\n\n  .. code-block:: console\n\n\tOPT> /add5_and_print { 5 add = } def\n\tOPT> 4 add5_and_print\n\t9\n\n  Python:\n\n  .. code-block:: console\n\n\t>>> def add5_and_print(x):\n\t...    print(x + 5);\n\t>>> add5_and_print(4)\n\t9\n\n* string manipulation\n\n  TBW\n\n* array manipulation\n\n  TBW\n\n* dict manipulation\n\n  TBW\n\n* control flow\n\n  TBW\n\n* operators for printing\n\n  TBW\n\n* reading script from file\n\n  TBW\n\nOptscript in ctags\n~~~~~~~~~~~~~~~~~~\n\nRelated options\n...............\n\n.. code-block:: ctags\n\n\t--_prelude-<LANG>={{\n\t\tOPTSCRIPT CODE FRAGMENTS\n\t}}\n\n\t--_sequel-<LANG>={{\n\t\tOPTSCRIPT CODE FRAGMENTS\n\t}}\n\n\t--regex-<LANG>=<PATTERN>/<NAME>/[<KIND>/]LONGFLAGS...{{\n\t\tOPTSCRIPT CODE FRAGMENTS\n\t}}\n\n\t--regex-<LANG>=<PATTERN>//LONGFLAGS...{{\n\t\tOPTSCRIPT CODE FRAGMENTS\n\t}}\n\n\t--mline-regex-<LANG>=<PATTERN>/<NAME>/[<KIND>/]LONGFLAGS...{{\n\t\tOPTSCRIPT CODE FRAGMENTS\n\t}}\n\n\t--mline-regex-<LANG>=<PATTERN>//LONGFLAGS...{{\n\t\tOPTSCRIPT CODE FRAGMENTS\n\t}}\n\n\t--_mtable-regex-<LANG>=<TABLE>/<PATTERN>/<NAME>/[<KIND>/]LONGFLAGS...{{\n\t\tOPTSCRIPT CODE FRAGMENTS\n\t}}\n\n\t--_mtable-regex-<LANG>=<TABLE>/<PATTERN>//LONGFLAGS...{{\n\t\tOPTSCRIPT CODE FRAGMENTS\n\t}}\n\n\t--_list-operators\n\n\t--list-fields\n\n\t--_paramdef-<LANG>=<NAME>,<DESCRIPTION>\n\nYou can run optscript code fragments when pattern specified with\noptions matches successfully. The options are ``--regex-<LANG>``,\n``--mline-regex-<LANG>``, and ``--_mtable-regex-<LANG>`` as you\nexpect. In addition, ``--_prelude-<LANG>`` and ``--_sequel-<LANG>``\noptions also take code fragments.\n\nTBW: two timings of evaluation\n\nPut code fragments at the end of options with surrounding \"``{{``\" and\n\"``}}``\". Though it is not impossible, a command line is not suitable\nplace to put code fragments because the code fragments may be long.\nInstead, you should write them to a .ctags file.\n\n.. warning::  An important rule in writing Optscript code in a file is\n  the start marker, ``{{`` must be at the end of line, and the end\n  marker ``}}`` must be at the beginning of line. If you break the\n  rule, the optlib loader of ctags fails to read your file.\n\n``--_prelude-<LANG>`` is for specified code fragments running at the\nbeginning of parsing a source file. You can use this option for\ndefining the common code used in the parser.\n\n``--_sequel-<LANG>`` is for for specified code fragments running at the end\nof parser a source file. Other than clean-up operations, the typical\nuse case of this option is for filling ``end:`` field of the tags\nctags found at the end of the input file.\n\nConsider the following input, written in a Python-like pseudocode:\n.. code-blcok::\n\n\t...\n\tdef fun(args)\n\t\t...\n\tEOF\n\nYou can make a tag with ``--regex-PseudoLang=/^def[ \\t]+([a-f]+)/\\1/d/``.\nHowever, there was no way to fill the ``end:`` field of ``f``.\nHere ``--_sequel-<LANG>`` option comes in. ctas runs the code fragment\nspecified with the option after reaching the end of input.\n\n.. code-block:: ctags\n\t--langdef=PseudoLang\n\t--map-PseudoLang=.ppp\n\t--kinddef-PseudoLang=d,def,definitions\n\t--regex-PseudoLang=/^def[ \\t]+([a-f]+)/\\1/d/{{\n\t\t% New definition\n\t\t% Let's fill end: field of the tags on the stack\n\t\tcount 0 gt {\n\t\t\t% Push the the line number (currentLine) of the tag (currentTag)\n\t\t\t% just extracted.\n\t\t\t. :line\n\t\t\t% The last tag extracted before extracting currentTag ends\n\t\t\t% at currentLine - 1.  (lastLine)\n\t\t\t1 sub\n\t\t\t% Fill the end: field with the lastLine.\n\t\t\tend:\n\t\t} if\n\t\t% push the currentTag\n\t\t.\n\t\t% Unless more `def` is found, we have no chance to fill\n\t\t% the end: field of the currentTag. but ...\n\t}}\n\t--_sequel-PseudoLang={{\n\t\t% this option gives the chance to fill the field.\n\t\tcount 0 gt {\n\t\t\t. :line end:\n\t\t} if\n\t}}\n\n``.`` in ``--_sequel-<LANG>`` code fragment is a placeholder tag.\nctags makes the placeholder tag when executing the code fragment\nimplicitly. The placeholder tag is only for providing the line number\nof the end of input file. You can get the line number with\n``. :line``.\n\nYou can also use this option for debug-printing the final state of\nparsing the source file.  e.g. ``--_sequel-Foo={{ _traced { pstack }\nif }}``.\n\n``--_list-operators`` lists all operators (and built-in procedures)\nand exits. In additions to operators defined in  ``optscript``,\n``ctags`` provides operators for tagging.\n\n``OP`` column of ``--list-fields`` represents the availability of\noperators for accessing the field specified in the line.  ``r``\nrepresents the field has an operator for reading\n(``:fieldname``). ``w`` represents the field has an operator for\nwriting (``fieldname:``).\n\n``--_paramdef-<LANG>=<NAME>,<DESCRIPTION>`` defines a language specific\nparameter named  ``<NAME>``. ``--param-<LANG>.<NAME>=<VALUE>`` assigns\na value ``<VALUE>`` to the parameter. You can access the value from\nOptscript code with ``_param`` operator. Don't use ``{`` character\nin the description. The character is reserved for future extension.\n\nOperators\n............................\n\n**.** -> ``-`` **.** ``corkIndex:int``\n\n    Push the cork index for the tag.\n\n**\\\\n** -> ``-`` **\\\\n** ``matchedString:string``\n\n\t``n`` is an integer (0...9) representing a group in a pattern.\n\tPush the matched string for the group.\n\n``_matchloc``\n\n    TBW\n\n``:field`` (See the output of ``--_list-operators``)\n\n    Get the value for the specified field from a tag\n\tand put it.\n\n``field:`` (See the output of ``--_list-operators``)\n\n    Set a value at the stack to the specified field of a tag.\n\n``_tag``\n\n    TBW\n\n``_COMMIT``\n\n    TBW\n\n``_traced``\n\n    TBW\n\nData types\n..........\n\n``MATCHLOC``\n\n    TBW\n\n``index:int``\n\n    TBW\n\n``TAG``\n\n    TBW\n\nRecipes\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nParameters\n...........................................\nWith ``--_paramdef-<LANG>=<param>,<description>`` option, you can\ndefine a parser-specific parameter to your optlib parser.\n\nIn the following example, we define a parser, ``Foo`` with a\nparser-specific parameter ``VAR``. If the parser sees \"x\" in the\ncurrent input stream, a code fragment attached to the pattern \"/(x)/\"\nruns. The code fragment does (1) check whether a value for ``VAR`` is\ngiven, (2) emit a tag with the value given to parameter ``VAR`` as\nname and with ``xval`` kind, and (3) remove the cork index from the\noperand stack.\n\nfoo.ctags:\n.. code-block::\n\n\t--langdef=Foo\n\t--map-Foo=.foo\n\t--kinddef-Foo=v,xval,externally defined values\n\t--_paramdef-Foo=VAR,desc\n\t--regex-Foo=/(x)//{{\n\t\t/VAR _param { % if VAR is defined ....\n\t\t\t/xval _tag _commit pop\n\t\t} if\n\t\t% if VAR is not defined, we do nothing.\n\t}}\n\ninput.foo:\n.. code-block::\n\n\tx\n\nWhen running the parser, we can give a value (\"hereiam\" in the following example)\nfor the parameter ``VAR`` from the command line:\n\n.. code-block:: console\n\n\t$ ./ctags --options=args.ctags --param-Foo.VAR=hereiam -o - input.foo\n\thereiam\tinput.foo\t/^x$/;\"\tv\n\nDifference between Optscript and PostScript\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* Memory management\n\n* Dynamically extendable data type\n\n  - string\n\n  - array\n"
  },
  {
    "path": "docs/osx.rst",
    "content": "Building on Mac OS\n-----------------------------------------------------------------------------\n\n:Maintainer: Cameron Eagans <me@cweagans.net>\n\n----\n\nThis part of the documentation is written by Cameron Eagans, a co-maintainer of Universal Ctags and the maintainer of\nthe OSX packaging of this project.\n\n\nBuild Prerequisites\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBuilding ctags on OSX should be no different than building on GNU/Linux. The same toolchains are used, and the Mac OS\npackaging scripts use autotools and make (as you'd expect).\n\nYou may need to install the xcode command line tools. You can install the entire xcode distribution from the App Store,\nor for a lighter install, you can simply run ``xcode-select --install`` to *only* install the compilers and such. See\nhttps://stackoverflow.com/a/9329325 for more information. Once your build toolchain is installed, proceed to the next\nsection.\n\nAt this point, if you'd like to build from an IDE, you'll have to figure it out. Building ctags is a pretty straightforward\nprocess that matches many other projects and most decent IDEs should be able to handle it.\n\nBuilding Manually (i.e. for development)\n.............................................................................\n\nYou can simply run the build instructions in README.md.\n\nBuilding with Homebrew\n.............................................................................\n\nHomebrew (https://brew.sh/) is the preferred method for installing Universal Ctags for end users. Currently, the process\nfor installing with Homebrew looks like this::\n\n        brew tap universal-ctags/universal-ctags\n        brew install --HEAD universal-ctags\n\nEventually, we hope to move the Universal-ctags formula to the main Homebrew repository, but since we don't have any\ntagged releases at this point, it's a head-only formula and wouldn't be accepted. When we have a tagged release, we'll\nsubmit a PR to Homebrew.\n\nIf you'd like to help with the Homebrew formula, you can find the repository here:\nhttps://github.com/universal-ctags/homebrew-universal-ctags\n\n\nDifferences between OSX and GNU/Linux\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere other things where building ctags on OSX differs from building on GNU/Linux.\n\n- Filenames on HFS+ (the Mac OS filesystem) are case-preserving, but not case-sensitive in 99% of configurations. If a\n  user manually formats their disk with a case sensitive version of HFS+, then the filesystem will behave like normal\n  GNU/Linux systems. Depending on users doing this is not a good thing.\n\nContributing\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis documentation is very much a work in progress. If you'd like to contribute, submit a PR and mention @cweagans for\nreview.\n\n"
  },
  {
    "path": "docs/other-projects.rst",
    "content": "======================================================================\nRelationship between other projects\n======================================================================\n\n.. contents:: `Table of contents`\n\t:depth: 3\n\t:local:\n\nOther tagging engines\n----------------------------------------------------------------------\n\n`Exuberant Ctags <http://ctags.sourceforge.net/>`_\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe origin of Universal Ctags.\n\n`Geany <https://github.com/geany/geany>`_\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nGeany is a small and lightweight IDE.\nGeany maintains their own tagging engine derived from ctags.\nWe are looking for the way to merge or share the source code each\nother.\n\nRepo\n\n\thttps://github.com/geany/geany/tree/master/ctags\n\nGeany has created a library out of ctags\n\n  \thttps://github.com/universal-ctags/ctags/issues/63\n\nTheir language parsers have many improvements to various parsers.\nChanges known by devs worth backporting:\n\n* Various fixes for D parser (c.c), but currently the code diverges\n  from ours to some extent.\n\n\nThey have these additional language parsers:\n\n* `DocBook <https://en.wikipedia.org/wiki/DocBook>`_\n* `Vala (c.c) <https://en.wikipedia.org/wiki/Vala_%28programming_language%29>`_\n\nSoftware using ctags\n----------------------------------------------------------------------\n\n`Pygments <https://pygments.org/>`_\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\t.. TODO: Is Pygments using ctags? To be move moved to other section?\n\n\tPygments is a generic syntax highlighter.\n\n\tIt can utilize tags file\n\tas input for making hyperlinks. However, Pygments just looks\n\tat names and lines in tags file. scopes and kinds are not\n\tused.  See `here\n\t<https://pygments-doc.readthedocs.io/en/latest/formatters/html.html>`_ for\n\tdetails.\n\n\tAs far as I (Masatake YAMATO) tried, using Pygments from ctags\n\tis not so useful. There are critical gap between ctags and Pygments.\n\tctags focuses on identifiers. Pygments focuses on keywords.\n\n`GNU global <https://www.gnu.org/software/global/>`_\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n \tGNU global is a source code tagging system.\n\n\tI (Masatake YAMATO) don't inspect this much but GNU global uses\n\tctags internally.\n\n\tA person at GNU global project proposed an extension for the tags file\n\tformat: See `this ticket\n\t<https://sourceforge.net/p/ctags/mailman/message/30020186/>`_ for details.\n\n\tSee also `'Source code reading' related sites\n\t<https://www.gnu.org/software/global/links.html>`_.\n\n`GNU Source-highlight <https://www.gnu.org/software/src-highlite/>`_\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\tGNU Source-highlight produces a document with syntax highlighting.\n\n\tIt can utilize tags file\n\tas input for making hyperlinks.\n\tSee `Generating References\n\t<https://www.gnu.org/software/src-highlite/source-highlight.html#Generating-References>`_\n\tsection for details.\n\n\tI (Masatake YAMATO) have not tried the feature yet.\n\n`OpenGrok <https://oracle.github.io/opengrok/>`_\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\tOpenGrok is a fast and usable source\n\tcode search and cross reference engine.\n\n\tI (Masatake YAMATO) don't inspect this much but OpenGrok uses\n\tctags internally.\n\nLinux kernel\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\tSee `linux/scripts/tags.sh <https://elixir.bootlin.com/linux/v5.10.2/source/scripts/tags.sh>`_\n\tof Linux kernel source tree.\n\tIt utilizes c parser to the utmost limit.\n\nOther interesting ctags repositories\n----------------------------------------------------------------------\nThere are several interesting repo's with ctags around. These are\ninteresting to integrate in the future.\n\n`VIM-Japan <https://github.com/vim-jp/ctags/>`_\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nVIM-Japan have some interesting things, especially regarding encoding.\n\n`Anjuta <https://gitlab.gnome.org/GNOME/anjuta>`_\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAnjuta DevStudio is a versatile Integrated Development Environment (IDE)\non GNOME Desktop Environment and features a number of advanced\nprogramming facilities.\n\nThey did not fork Exuberant Ctags, but they did\nnatively `include it in Anjuta <https://git.gnome.org/browse/anjuta/tree/plugins/symbol-db/anjuta-tags>`_.\nThey have made several additions to\ntheir version of it including fairly extensive Vala language support.\n\n`Tagbar <https://github.com/majutsushi/tagbar/>`_\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTagbar is a Vim plugin that provides an easy way to browse the tags of the\ncurrent file and get an overview of its structure.\n\nThis is `a gold mine of optlibs <https://github.com/majutsushi/tagbar/wiki>`_.\n\n.. include:: tracking.rst\n"
  },
  {
    "path": "docs/output-format.rst",
    "content": ".. _output-format:\n\n=============================================================================\nOutput formats\n=============================================================================\n\nThis section deals with individual output-format topics.\n\nThe command line option ``--output-format=``\\ *format* chooses an output format.\nSupported *format* are ``u-ctags``, ``e-ctags``, ``etags``, ``xref``, and ``json``.\n\n``u-ctags``, ``e-ctags``\n\t``u-ctags`` is the default output format extending the Exuberant Ctags\n\toutput format (``e-ctags``).\n\n\t``--format=1`` and ``--format=2`` are same as ``--output-format=e-ctags``\n\tand ``--output-format=u-ctags`` respectively.\n\n\tSee man page :ref:`tags (5) <tags(5)>` for details. The difference between\n\t``u-ctags`` and ``e-ctags`` are marked as \"EXCEPTION\".\n\tAdditional changes in Universal Ctags are described in\n\t:ref:`changes_tags_file`.\n\n``etags``\n\tOutput format for Emacs etags.\n\n\tSee the description of ``-e`` option in :ref:`ctags(1) <ctags(1)>`.\n\n``xref``\n\tA tabular, human-readable cross reference (xref) format.\n\t``--output-format=xref`` can be abbreviated as ``-x``.\n\n\tSee section :ref:`output-xref` for details.\n\n``json``\n\tJSON format.\n\n\tSee :ref:`ctags-client-tools(7) <ctags-client-tools(7)>`.\n\n*********\n\n.. toctree::\n\t:maxdepth: 2\n\n\toutput-tags.rst\n\toutput-xref.rst\n"
  },
  {
    "path": "docs/output-tags.rst",
    "content": ".. _changes_tags_file:\n\nChanges to the tags file format\n---------------------------------------------------------------------\n\n``F`` kind usage\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou cannot use ``F`` (``file``) kind in your .ctags because Universal Ctags\nreserves it. See :ref:`ctags-incompatibilities(7) <ctags-incompatibilities(7)>`.\n\nReference tags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTraditionally ctags collects the information for locating where a\nlanguage object is DEFINED.\n\nIn addition Universal Ctags supports reference tags. If the extra-tag\n``r`` is enabled, Universal Ctags also collects the information for\nlocating where a language object is REFERENCED. This feature was\nproposed by @shigio in `#569\n<https://github.com/universal-ctags/ctags/issues/569>`_ for GNU GLOBAL.\n\nHere are some examples. Here is the target input file named reftag.c.\n\n.. code-block:: c\n\n    #include <stdio.h>\n    #include \"foo.h\"\n    #define TYPE point\n    struct TYPE { int x, y; };\n    TYPE p;\n    #undef TYPE\n\n\nTraditional output:\n\n.. code-block:: console\n\n    $ ctags -o - reftag.c\n    TYPE\treftag.c\t/^#define TYPE /;\"\td\tfile:\n    TYPE\treftag.c\t/^struct TYPE { int x, y; };$/;\"\ts\tfile:\n    p\treftag.c\t/^TYPE p;$/;\"\tv\ttyperef:typename:TYPE\n    x\treftag.c\t/^struct TYPE { int x, y; };$/;\"\tm\tstruct:TYPE\ttyperef:typename:int\tfile:\n    y\treftag.c\t/^struct TYPE { int x, y; };$/;\"\tm\tstruct:TYPE\ttyperef:typename:int\tfile:\n\nOutput with the extra-tag ``r`` enabled:\n\n.. code-block:: console\n\n    $ ctags --list-extras | grep ^r\n    r\tInclude reference tags\toff\n    $ ctags -o - --extras=+r reftag.c\n    TYPE\treftag.c\t/^#define TYPE /;\"\td\tfile:\n    TYPE\treftag.c\t/^#undef TYPE$/;\"\td\tfile:\n    TYPE\treftag.c\t/^struct TYPE { int x, y; };$/;\"\ts\tfile:\n    foo.h\treftag.c\t/^#include \"foo.h\"/;\"\th\n    p\treftag.c\t/^TYPE p;$/;\"\tv\ttyperef:typename:TYPE\n    stdio.h\treftag.c\t/^#include <stdio.h>/;\"\th\n    x\treftag.c\t/^struct TYPE { int x, y; };$/;\"\tm\tstruct:TYPE\ttyperef:typename:int\tfile:\n    y\treftag.c\t/^struct TYPE { int x, y; };$/;\"\tm\tstruct:TYPE\ttyperef:typename:int\tfile:\n\n`#undef X` and two `#include` are newly collected.\n\n\"roles\" is a newly introduced field in Universal Ctags. The field\nnamed is for recording how a tag is referenced. If a tag is definition\ntag, the roles field has \"def\" as its value.\n\nUniversal Ctags prints the role information when the `r`\nfield is enabled with ``--fields=+r``.\n\n.. code-block:: console\n\n    $ ctags -o - --extras=+r --fields=+r reftag.c\n    TYPE\treftag.c\t/^#define TYPE /;\"\td\tfile:\n    TYPE\treftag.c\t/^#undef TYPE$/;\"\td\tfile:\troles:undef\n    TYPE\treftag.c\t/^struct TYPE { int x, y; };$/;\"\ts\tfile:\troles:def\n    foo.h\treftag.c\t/^#include \"foo.h\"/;\"\th\troles:local\n    p\treftag.c\t/^TYPE p;$/;\"\tv\ttyperef:typename:TYPE\troles:def\n    stdio.h\treftag.c\t/^#include <stdio.h>/;\"\th\troles:system\n    x\treftag.c\t/^struct TYPE { int x, y; };$/;\"\tm\tstruct:TYPE\ttyperef:typename:int\tfile:\troles:def\n    y\treftag.c\t/^struct TYPE { int x, y; };$/;\"\tm\tstruct:TYPE\ttyperef:typename:int\tfile:\troles:def\n\nThe `Reference tag marker` field, ``R``, is a specialized GNU global\nrequirement; D is used for the traditional definition tags, and R is\nused for the new reference tags. The field can be used only with\n``--_xformat``.\n\n.. code-block:: console\n\n    $ ctags -x --_xformat=\"%R %-16N %4n %-16F %C\" --extras=+r reftag.c\n    D TYPE                3 reftag.c         #define TYPE point\n    D TYPE                4 reftag.c         struct TYPE { int x, y; };\n    D p                   5 reftag.c         TYPE p;\n    D x                   4 reftag.c         struct TYPE { int x, y; };\n    D y                   4 reftag.c         struct TYPE { int x, y; };\n    R TYPE                6 reftag.c         #undef TYPE\n    R foo.h               2 reftag.c         #include \"foo.h\"\n    R stdio.h             1 reftag.c         #include <stdio.h>\n\nSee :ref:`Customizing xref output <xformat>` for more details about\n``--_xformat``.\n\nAlthough the facility for collecting reference tags is implemented,\nonly a few parsers currently utilize it. All available roles can be\nlisted with ``--list-roles``:\n\n.. code-block:: console\n\n    $ ctags --list-roles\n    #LANGUAGE      KIND(L/N)         NAME                ENABLED DESCRIPTION\n    SystemdUnit    u/unit            Requires            on      referred in Requires key\n    SystemdUnit    u/unit            Wants               on      referred in Wants key\n    SystemdUnit    u/unit            After               on      referred in After key\n    SystemdUnit    u/unit            Before              on      referred in Before key\n    SystemdUnit    u/unit            RequiredBy          on      referred in RequiredBy key\n    SystemdUnit    u/unit            WantedBy            on      referred in WantedBy key\n    Yaml           a/anchor          alias               on      alias\n    DTD            e/element         attOwner            on      attributes owner\n    Automake       c/condition       branched            on      used for branching\n    Cobol          S/sourcefile      copied              on      copied in source file\n    Maven2         g/groupId         dependency          on      dependency\n    DTD            p/parameterEntity elementName         on      element names\n    DTD            p/parameterEntity condition           on      conditions\n    LdScript       s/symbol          entrypoint          on      entry points\n    LdScript       i/inputSection    discarded           on      discarded when linking\n    ...\n\n.. NOTE: --xformat is the only way to extract referenced tag\n\nThe first column shows the name of the parser.\nThe second column shows the letter/name of the kind.\nThe third column shows the name of the role.\nThe fourth column shows whether the role is enabled or not.\nThe fifth column shows the description of the role.\n\nYou can define a role in an optlib parser for capturing reference\ntags. See :ref:`Capturing reference tags <role-regex-flag>` for more\ndetails.\n\n``--roles-<LANG>.<KIND>`` is the option for enabling/disabling\nspecified roles.\n\nPseudo-tags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. IN MAN PAGE\n\nSee :ref:`ctags-client-tools(7) <ctags-client-tools(7)>` about the\nconcept of the pseudo-tags.\n\n.. TODO move the following contents to ctags-client-tools(7).\n\n``TAG_KIND_DESCRIPTION``\n.........................................................................\n\nThis is a newly introduced pseudo-tag. It is not emitted by default.\nIt is emitted only when ``--pseudo-tags=+TAG_KIND_DESCRIPTION`` is\ngiven.\n\nThis is for describing kinds; their letter, name, and description are\nenumerated in the tag.\n\nctags emits ``TAG_KIND_DESCRIPTION`` with following format::\n\n\t!_TAG_KIND_SEPARATOR!{parser}\t{letter},{name}\t/{description}/\n\nA backslash and a slash in {description} is escaped with a backslash.\n\n\n``TAG_KIND_SEPARATOR``\n.........................................................................\n\nThis is a newly introduced pseudo-tag. It is not emitted by default.\nIt is emitted only when ``--pseudo-tags=+TAG_KIND_SEPARATOR`` is\ngiven.\n\nThis is for describing separators placed between two kinds in a\nlanguage.\n\nTag entries including the separators are emitted when ``--extras=+q``\nis given; fully qualified tags contain the separators. The separators\nare used in scope information, too.\n\nctags emits ``TAG_KIND_SEPARATOR`` with following format::\n\n\t!_TAG_KIND_SEPARATOR!{parser}\t{sep}\t/{upper}{lower}/\n\nor ::\n\n\t!_TAG_KIND_SEPARATOR!{parser}\t{sep}\t/{lower}/\n\nHere {parser} is the name of language. e.g. PHP.\n{lower} is the letter representing the kind of the lower item.\n{upper} is the letter representing the kind of the upper item.\n{sep} is the separator placed between the upper item and the lower\nitem.\n\nThe format without {upper} is for representing a root separator. The\nroot separator is used as prefix for an item which has no upper scope.\n\n`*` given as {upper} is a fallback wild card; if it is given, the\n{sep} is used in combination with any upper item and the item\nspecified with {lower}.\n\nEach backslash character used in {sep} is escaped with an extra\nbackslash character.\n\nExample output:\n\n.. code-block:: console\n\n    $ ctags -o - --extras=+p --pseudo-tags=  --pseudo-tags=+TAG_KIND_SEPARATOR input.php\n    !_TAG_KIND_SEPARATOR!PHP\t::\t/*c/\n    ...\n    !_TAG_KIND_SEPARATOR!PHP\t\\\\\t/c/\n    ...\n    !_TAG_KIND_SEPARATOR!PHP\t\\\\\t/nc/\n    ...\n\nThe first line means ``::`` is used when combining something with an\nitem of the class kind.\n\nThe second line means ``\\\\`` is used when a class item is at the top\nlevel; no upper item is specified.\n\nThe third line means ``\\\\`` is used when for combining a namespace item\n(upper) and a class item (lower).\n\nOf course, ctags uses the more specific line when choosing a\nseparator; the third line has higher priority than the first.\n\n``TAG_OUTPUT_FILESEP``\n.........................................................................\n\nThis pseudo-tag represents the separator used in file name: slash or\nbackslash.  This is always 'slash' on Unix-like environments.\nThis is also 'slash' by default on Windows, however when\n``--output-format=e-tags`` or ``--use-slash-as-filename-separator=no``\nis specified, it becomes 'backslash'.\n\n\n``TAG_OUTPUT_MODE``\n.........................................................................\n\n.. NOT REVIEWED YET\n\nThis pseudo-tag represents output mode: u-ctags or e-ctags.\nThis is controlled by ``--output-format`` option.\n\nSee also :ref:`Compatible output and weakness <compat-output>`.\n\nTruncating the pattern for long input lines\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSee ``--pattern-length-limit=N`` option in :ref:`ctags(1) <ctags(1)>`.\n\n.. _parser-specific-fields:\n\nParser specific fields\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA tag has a `name`, an `input` file name, and a `pattern` as basic\ninformation. Some fields like `language:`, `signature:`, etc are\nattached to the tag as optional information.\n\nIn Exuberant Ctags, fields are common to all languages.\nUniversal Ctags extends the concept of fields; a parser can define\nits specific field. This extension was proposed by @pragmaware in\n`#857 <https://github.com/universal-ctags/ctags/issues/857>`_.\n\nFor implementing the parser specific fields, the options for listing and\nenabling/disabling fields are also extended.\n\nIn the output of ``--list-fields``, the owner of the field is printed\nin the `LANGUAGE` column:\n\n.. code-block:: console\n\n\t$ ctags --list-fields\n\t#LETTER NAME            ENABLED LANGUAGE         XFMT  DESCRIPTION\n\t...\n\t-       end             off     C                TRUE   end lines of various constructs\n\t-       properties      off     C                TRUE   properties (static, inline, mutable,...)\n\t-       end             off     C++              TRUE   end lines of various constructs\n\t-       template        off     C++              TRUE   template parameters\n\t-       captures        off     C++              TRUE   lambda capture list\n\t-       properties      off     C++              TRUE   properties (static, virtual, inline, mutable,...)\n\t-       sectionMarker   off     reStructuredText TRUE   character used for declaring section\n\t-       version         off     Maven2           TRUE   version of artifact\n\ne.g. reStructuredText is the owner of the sectionMarker field and\nboth C and C++ own the end field.\n\n``--list-fields`` takes one optional argument, `LANGUAGE`. If it is\ngiven, ``--list-fields`` prints only the fields for that parser:\n\n.. code-block:: console\n\n\t$ ctags --list-fields=Maven2\n\t#LETTER NAME            ENABLED LANGUAGE        XFMT  DESCRIPTION\n\t-       version         off     Maven2          TRUE  version of artifact\n\nA parser specific field only has a long name, no letter. For\nenabling/disabling such fields, the name must be passed to\n``--fields-<LANG>``.\n\ne.g. for enabling the `sectionMarker` field owned by the\n`reStructuredText` parser, use the following command line:\n\n.. code-block:: console\n\n\t$ ctags --fields-reStructuredText=+{sectionMarker} ...\n\nThe wild card notation can be used for enabling/disabling parser specific\nfields, too. The following example enables all fields owned by the\n`C++` parser.\n\n.. code-block:: console\n\n\t$ ctags --fields-C++='*' ...\n\n`*` can also be used for specifying languages.\n\nThe next example is for enabling `end` fields for all languages which\nhave such a field.\n\n.. code-block:: console\n\n\t$ ctags --fields-'*'=+'{end}' ...\n\t...\n\nIn this case, using wild card notation to specify the language, not\nonly fields owned by parsers but also common fields having the name\nspecified (`end` in this example) are enabled/disabled.\n\nUsing the wild card notation to specify the language is helpful to\navoid incompatibilities between versions of Universal Ctags itself\n(SELF INCOMPATIBLY).\n\nIn Universal Ctags development, a parser developer may add a new\nparser specific field for a certain language.  Sometimes other developers\nthen recognize it is meaningful not only for the original language\nbut also other languages. In this case the field may be promoted to a\ncommon field. Such a promotion will break the command line\ncompatibility for ``--fields-<LANG>`` usage. The wild card for\n`<LANG>` will help in avoiding this unwanted effect of the promotion.\n\nWith respect to the tags file format, nothing is changed when\nintroducing parser specific fields; `<fieldname>`:`<value>` is used as\nbefore and the name of field owner is never prefixed. The `language:`\nfield of the tag identifies the owner.\n\n\nParser specific extras\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. NOT REVIEWED YET\n\nAs man page of Exuberant Ctags says, ``--extras`` option specifies\nwhether to include extra tag entries for certain kinds of information.\nThis option is available in Universal Ctags, too.\n\nIn Universal Ctags it is extended; a parser can define its specific\nextra flags. They can be controlled with ``--extras-<LANG>=[+|-]{...}``.\n\nSee some examples:\n\n.. code-block:: console\n\n\t$ ctags --list-extras\n\t#LETTER NAME                   ENABLED LANGUAGE         DESCRIPTION\n\tF       fileScope              TRUE    NONE             Include tags ...\n\tf       inputFile              FALSE   NONE             Include an entry ...\n\tp       pseudo                 FALSE   NONE             Include pseudo tags\n\tq       qualified              FALSE   NONE             Include an extra ...\n\tr       reference              FALSE   NONE             Include reference tags\n\tg       guest                  FALSE   NONE             Include tags ...\n\t-       whitespaceSwapped      TRUE    Robot            Include tags swapping ...\n\nSee the `LANGUAGE` column. NONE means the extra flags are language\nindependent (common). They can be enabled or disabled with `--extras=` as before.\n\nLook at `whitespaceSwapped`. Its language is `Robot`. This flag is enabled\nby default but can be disabled with `--extras-Robot=-{whitespaceSwapped}`.\n\n.. code-block:: console\n\n    $ cat input.robot\n    *** Keywords ***\n    it's ok to be correct\n\tPython_keyword_2\n\n    $ ctags -o - input.robot\n    it's ok to be correct\tinput.robot\t/^it's ok to be correct$/;\"\tk\n    it's_ok_to_be_correct\tinput.robot\t/^it's ok to be correct$/;\"\tk\n\n    $ ctags -o - --extras-Robot=-'{whitespaceSwapped}' input.robot\n    it's ok to be correct\tinput.robot\t/^it's ok to be correct$/;\"\tk\n\nWhen disabled the name `it's_ok_to_be_correct` is not included in the\ntags output.  In other words, the name `it's_ok_to_be_correct` is\nderived from the name `it's ok to be correct` when the extra flag is\nenabled.\n\nDiscussion\n.........................................................................\n\n.. NOT REVIEWED YET\n\n(This subsection should move to somewhere for developers.)\n\nThe question is what are extra tag entries. As far as I know none has\nanswered explicitly. I have two ideas in Universal Ctags. I\nwrite \"ideas\", not \"definitions\" here because existing parsers don't\nfollow the ideas. They are kept as is in variety reasons but the\nideas may be good guide for people who wants to write a new parser\nor extend an exiting parser.\n\nThe first idea is that a tag entry whose name is appeared in the input\nfile as is, the entry is NOT an extra. (If you want to control the\ninclusion of such entries, the classical ``--kind-<LANG>=[+|-]...`` is\nwhat you want.)\n\nQualified tags, whose inclusion is controlled by ``--extras=+q``, is\nexplained well with this idea.\nLet's see an example:\n\n.. code-block:: console\n\n    $ cat input.py\n    class Foo:\n\tdef func (self):\n\t    pass\n\n    $ ctags -o - --extras=+q --fields=+E input.py\n    Foo\tinput.py\t/^class Foo:$/;\"\tc\n    Foo.func\tinput.py\t/^    def func (self):$/;\"\tm\tclass:Foo\textra:qualified\n    func\tinput.py\t/^    def func (self):$/;\"\tm\tclass:Foo\n\n`Foo` and `func` are in `input.py`. So they are no extra tags.  In\nother hand, `Foo.func` is not in `input.py` as is. The name is\ngenerated by ctags as a qualified extra tag entry.\n`whitespaceSwapped` extra flag of  `Robot` parser is also aligned well\non the idea.\n\nI don't say all parsers follows this idea.\n\n.. code-block:: console\n\n    $ cat input.cc\n    class A\n    {\n      A operator+ (int);\n    };\n\n    $ ctags --kinds-all='*' --fields= -o - input.cc\n    A\tinput.cc\t/^class A$/\n    operator +\tinput.cc\t/^  A operator+ (int);$/\n\nIn this example `operator+` is in `input.cc`.\nIn other hand, `operator +`  is in the ctags output as non extra tag entry.\nSee a whitespace between the keyword `operator` and `+` operator.\nThis is an exception of the first idea.\n\nThe second idea is that if the *inclusion* of a tag cannot be\ncontrolled well with ``--kind-<LANG>=[+|-]...``, the tag may be an\nextra.\n\n.. code-block:: console\n\n    $ cat input.c\n    static int foo (void)\n    {\n\t    return 0;\n    }\n    int bar (void)\n    {\n\t    return 1;\n    }\n\n    $ ctags --sort=no -o - --extras=+F input.c\n    foo\tinput.c\t/^static int foo (void)$/;\"\tf\ttyperef:typename:int\tfile:\n    bar\tinput.c\t/^int bar (void)$/;\"\tf\ttyperef:typename:int\n\n    $ ctags -o - --extras=-F input.c\n    foo\tinput.c\t/^static int foo (void)$/;\"\tf\ttyperef:typename:int\tfile:\n\n    $\n\nFunction `foo` of C language is included only when `F` extra flag\nis enabled. Both `foo` and `bar` are functions. Their inclusions\ncan be controlled with `f` kind of C language: ``--kind-C=[+|-]f``.\n\nThe difference between static modifier or implicit extern modifier in\na function definition is handled by `F` extra flag.\n\nBasically the concept kind is for handling the kinds of language\nobjects: functions, variables, macros, types, etc. The concept extra\ncan handle the other aspects like scope (static or extern).\n\nHowever, a parser developer can take another approach instead of\nintroducing parser specific extra; one can prepare `staticFunction` and\n`exportedFunction` as kinds of one's parser.  The second idea is a\njust guide; the parser developer must decide suitable approach for the\ntarget language.\n\nAnyway, in the second idea, ``--extras`` is for controlling inclusion\nof tags. If what you want is not about inclusion, ``--param-<LANG>``\ncan be used as the last resort.\n\n\nParser specific parameter\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. NOT REVIEWED YET\n\nTo control the detail of a parser, ``--param-<LANG>`` option is introduced.\n``--kinds-<LANG>``, ``--fields-<LANG>``, ``--extras-<LANG>``\ncan be used for customizing the behavior of a parser specified with ``<LANG>``.\n\n``--param-<LANG>`` should be used for aspects of the parser that\nthe options(kinds, fields, extras) cannot handle well.\n\nA parser defines a set of parameters. Each parameter has name and\ntakes an argument. A user can set a parameter with following notation\n::\n\n   --param-<LANG>.name=arg\n\nAn example of specifying a parameter\n::\n\n   --param-CPreProcessor.if0=true\n\nHere `if0` is a name of parameter of CPreProcessor parser and\n`true` is the value of it.\n\nAll available parameters can be listed with ``--list-params`` option.\n\n.. code-block:: console\n\n    $ ctags --list-params\n    #PARSER         NAME     DESCRIPTION\n    CPreProcessor   if0      examine code within \"#if 0\" branch (true or [false])\n    CPreProcessor   ignore   a token to be specially handled\n\n(At this time only CPreProcessor parser has parameters.)\n"
  },
  {
    "path": "docs/output-xref.rst",
    "content": ".. NOT REVIEWED YET\n\n.. _output-xref:\n\n======================================================================\nXref output\n======================================================================\n\nXref output is a tabular, human-readable cross reference (xref) format.\n\nThe default information contained in the output includes:\n\n* the tag name\n* the kind of tag\n* the line number\n* file name\n* source line (with extra white space condensed) of the file\n\n``--_xformat`` option allows a user to customize the output information.  See\n:ref:`Customizing xref output <xformat>` for more details.\n\nXref output goes to standard output by default.\n\nNotes:\n\n    * Printing `z`{kind} field in xref format doesn't include `kind:` prefix.\n    * Printing `Z`{scope} field in xref format doesn't include `scope:` prefix.\n\n.. _xformat:\n\nCustomizing xref output\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``--_xformat`` option allows a user to customize the cross reference\n(xref) output enabled with ``-x``.\n::\n\n   --_xformat=FORMAT\n\n\nThe notation for FORMAT is similar to that employed by `printf(3)` in\nthe C language; `%` represents a slot which is substituted with a\nfield value when printing. You can specify multiple slots in FORMAT.\nHere field means an item listed with ``--list-fields`` option.\n\nThe notation of a slot::\n\n   %[-][.][WIDTH-AND-ADJUSTMENT]FIELD-SPECIFIER\n\n``FIELD-SPECIFIER`` specifies a field whose value is printed.\nShort notation and long notation are available. They can be mixed\nin a FORMAT. Specifying a field with either notation, one or more\nfields are activated internally.\n\nThe short notation is just a letter listed in the LETTER column of\nthe ``--list-fields`` output.\n\nThe long notation is a name string surrounded by braces(`{` and\n`}`). The name string is listed in the NAME column of the output of\nthe same option. To specify a field owned by a parser, prepend\nthe parser name to the name string with `.` as a separator.\n\nWild card (`*`) can be used where a parser name is specified. In this\ncase both common and parser specific fields are activated and printed.\nIf a common field and a parser specific field have the same name,\nthe common field has higher priority.\n\n`WIDTH-AND-ADJUSTMENT` is a positive number.\nThe value of the number is used as the width of\nthe column where a field is printed. The printing is\nright adjusted by default, and left\nadjusted when `-` is given as prefix.\nThe output is not truncated by default even if its field width is\nspecified and smaller than width of output value. For truncating\nthe output to the specified width, use `.` as prefix.\n\nAn example of specifying common fields:\n\n.. code-block:: console\n\n    $  ctags -x --_xformat=\"%-20N %4n %-16{input}|\" main/main.c | head\n    CLOCKS_PER_SEC        360 main/main.c     |\n    CLOCKS_PER_SEC        364 main/main.c     |\n    CLOCK_AVAILABLE       358 main/main.c     |\n    CLOCK_AVAILABLE       363 main/main.c     |\n    Totals                 87 main/main.c     |\n    __anonae81ef0f0108     87 main/main.c     |\n    addTotals             100 main/main.c     |\n    batchMakeTags         436 main/main.c     |\n    bytes                  87 main/main.c     |\n    clock                 365 main/main.c     |\n\nHere `%-20N %4n %-16{input}|` is a format string. Let's look at the\nelements of the format.\n\n`%-20N`\n\n\tThe short notation is used here.\n\tThe element means filling the slot with the name of the tag.\n\tThe width of the column is 20 characters and left adjusted.\n\n`%4n`\n\n\tThe short notation is used here.\n\tThe element means filling the slot with the line number of\n\tthe tag. The width of the column is 4 characters and right\n        adjusted.\n\n`%-16{input}`\n\n\tThe long notation is used here.\n\tThe element means filling the slot with the input file name\n\twhere the tag is defined. The width of column is 16\n        characters and left adjusted.\n\n`|`\n\n\tPrinted as is.\n\nAnother example of specifying parser specific fields:\n\n.. code-block:: console\n\n\t$  ctags -x --_xformat=\"%-20N [%10{C.properties}]\" main/main.c\n\tCLOCKS_PER_SEC       [          ]\n\tCLOCK_AVAILABLE      [          ]\n\tTotals               [          ]\n\t__anonae81ef0f0108   [          ]\n\taddTotals            [    extern]\n\tbatchMakeTags        [    static]\n\tbytes                [          ]\n\tclock                [          ]\n\tclock                [    static]\n\t...\n\nHere `\"%-20N [%10{C.properties}]\"` is a format string. Let's look at\nthe elements of the format.\n\n`%-20N`\n\n\tAlready explained in the first example.\n\n`[` and `]`\n\n\tPrinted as is.\n\n`%10{C.properties}`\n\n\tThe long notation is used here.\n\tThe element means filling the slot with the value\n\tof the properties field of the C parser.\n\tThe width of the column is 10 characters and right adjusted.\n\n\n.. TODO: An example of using WILDCARD\n"
  },
  {
    "path": "docs/parser-asm.rst",
    "content": ".. _asm:\n\n======================================================================\nAsm parser\n======================================================================\n\n.. NOT REVIEWED YET\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\nThe original (Exuberant Ctags) parser handles #define C preprocessor directive and C\nstyle comments by itself. In Universal Ctags Asm parser utilizes CPreProcessor meta\nparser for handling them. So a language object defined with #define is tagged as\n\"defines\" of CPreProcessor language, not Asm language.\n\n.. code-block:: console\n\n   $ cat input.S\n   #define S 1\n\n   $ e-ctags --fields=+l  -o - input.S\n   S\tinput.S\t/^#define S 1$/;\"\td\tlanguage:Asm\n\n   $ u-ctags --fields=+l  -o - input.S\n   S\tinput.S\t/^#define S /;\"\td\tlanguage:CPreProcessor\tfile:\n\n"
  },
  {
    "path": "docs/parser-cmake.rst",
    "content": ".. _cmake:\n\n======================================================================\nCMake parser\n======================================================================\n\nThe CMake parser is used for ``.cmake`` and ``CMakeLists.txt`` files.\nIt generates tags for the following items:\n\n- User-defined functions\n- User-defined macros\n- User-defined options created by ``option()``\n- Variables defined by ``set()``\n- Targets created by ``add_custom_target()``, ``add_executable()`` and ``add_library()``\n\nThe parser uses the experimental multi-table regex ``ctags`` options to\nperform the parsing and tag generation.\n\nCaveats:\n\n\tNames that are ``${}`` references to variables are not tagged.\n\n\tFor example, given the following::\n\n\t    set(PROJECT_NAME_STR ${PROJECT_NAME})\n\t    add_executable( ${PROJECT_NAME_STR} ... )\n\t    add_custom_target( ${PROJECT_NAME_STR}_tests ... )\n\t    add_library( sharedlib ... )\n\n\t...the variable ``PROJECT_NAME_STR`` and target ``sharedlib`` will both be tagged,\n\tbut the other targets will not be.\n\n\nReferences:\n\n\thttps://cmake.org/cmake/help/latest/manual/cmake-language.7.html\n"
  },
  {
    "path": "docs/parser-cxx.rst",
    "content": ".. _cxx:\n\n======================================================================\nThe new C/C++ parser\n======================================================================\n\n:Maintainer: Szymon Tomasz Stefanek <s.stefanek@gmail.com>\n\nIntroduction\n---------------------------------------------------------------------\n\nThe C++ language has strongly evolved since the old C/C++ parser was\nwritten. The old parser was struggling with some of the new features\nof the language and has shown signs of reaching its limits. For this\nreason in February/March 2016 the C/C++ parser was rewritten from\nscratch.\n\nIn the first release several outstanding bugs were fixed and some new\nfeatures were added. Among them:\n\n- Tagging of \"using namespace\" declarations\n- Tagging of function parameters\n- Extraction of function parameter types\n- Tagging of anonymous structures/unions/classes/enums\n- Support for C++11 lambdas (as anonymous functions)\n- Support for function-level scopes (for local variables and parameters)\n- Extraction of local variables which include calls to constructors\n- Extraction of local variables from within the for(), while(), if()\n  and switch() parentheses.\n- Support for function prototypes/declarations with trailing return type\n\nAt the time of writing (March 2016) more features are planned.\n\nNotable New Features\n---------------------------------------------------------------------\n\nSome of the notable new features are described below.\n\nProperties\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nSeveral properties of functions and variables can be extracted\nand placed in a new field called ``properties``.\nThe syntax to enable it is:\n\n.. code-block:: console\n\n\t$ ctags ... --fields-c++=+{properties} ...\n\nAt the time of writing the following properties are reported:\n\n- ``virtual``: a function is marked as virtual\n- ``static``: a function/variable is marked as static\n- ``inline``: a function implementation is marked as inline\n- ``explicit``: a function is marked as explicit\n- ``extern``: a function/variable is marked as extern\n- ``const``: a function is marked as const\n- ``pure``: a virtual function is pure (i.e = 0)\n- ``override``: a function is marked as override\n- ``default``: a function is marked as default\n- ``final``: a function is marked as final\n- ``delete``: a function is marked as delete\n- ``mutable``: a variable is marked as mutable\n- ``volatile``: a function is marked as volatile\n- ``specialization``: a function is a template specialization\n- ``scopespecialization``: template specialization of scope ``a<x>::b()``\n- ``deprecated``: a function is marked as deprecated via ``__attribute__``\n- ``scopedenum``: a scoped enumeration (C++11)\n\nPreprocessor macros\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nDefining a macro from command line\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe new parser supports the definition of real preprocessor macros\nvia the ``-D`` option. All types of macros are supported,\nincluding the ones with parameters and variable arguments.\nStringification, token pasting and recursive macro expansion are also supported.\n\nOption ``-I`` is now simply a backward-compatible syntax to define a\nmacro with no replacement.\n\nThe syntax is similar to the corresponding gcc ``-D`` option.\n\nSome examples follow.\n\n.. code-block:: console\n\n\t$ ctags ... -D IGNORE_THIS ...\n\nWith this commandline the following C/C++ input\n\n.. code-block:: C\n\n\tint IGNORE_THIS a;\n\nwill be processed as if it was\n\n.. code-block:: C\n\n\tint a;\n\nDefining a macro with parameters uses the following syntax:\n\n.. code-block:: console\n\n\t$ ctags ... -D \"foreach(arg)=for(arg;;)\" ...\n\nThis example defines ``for(arg;;)`` as the replacement ``foreach(arg)``.\nSo the following C/C++ input\n\n.. code-block:: C\n\n\tforeach(char * p,pointers)\n\t{\n\n\t}\n\nis processed in new C/C++ parser as:\n\n.. code-block:: C\n\n\tfor(char * p;;)\n\t{\n\n\t}\n\nand the p local variable can be extracted.\n\nThe previous commandline includes quotes since the macros generally contain\ncharacters that are treated specially by the shells. You may need some escaping.\n\nToken pasting is performed by the ``##`` operator, just like in the normal\nC preprocessor.\n\n.. code-block:: console\n\n\t$ ctags ... -D \"DECLARE_FUNCTION(prefix)=int prefix ## Call();\"\n\nSo the following code\n\n.. code-block:: C\n\n\tDECLARE_FUNCTION(a)\n\tDECLARE_FUNCTION(b)\n\nwill be processed as\n\n.. code-block:: C\n\n\tint aCall();\n\tint bCall();\n\nMacros with variable arguments use the gcc ``__VA_ARGS__`` syntax.\n\n.. code-block:: console\n\n\t$ ctags ... -D \"DECLARE_FUNCTION(name,...)=int name(__VA_ARGS__);\"\n\nSo the following code\n\n.. code-block:: C\n\n\tDECLARE_FUNCTION(x,int a,int b)\n\nwill be processed as\n\n.. code-block:: C\n\n\tint x(int a,int b);\n\nAutomatically expanding macros defined in the same input file (HIGHLY EXPERIMENTAL)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf a CPreProcessor macro defined in a C/C++/CUDA file, the macro invocation in the\nSAME file can be expanded with following options:\n\n.. code-block:: text\n\n   --param-CPreProcessor._expand=1\n   --fields-C=+{macrodef}\n   --fields-C++=+{macrodef}\n   --fields-CUDA=+{macrodef}\n   --fields=+{signature}\n\nLet's see an example.\n\ninput.c:\n.. code-block:: C\n\n\t#define DEFUN(NAME) int NAME (int x, int y)\n\t#define BEGIN {\n\t#define END }\n\n\tDEFUN(myfunc)\n\t  BEGIN\n\t  return -1\n\t  END\n\nThe output without options:\n.. code-block::\n\n   $ ctags -o - input.c\n   BEGIN\tinput.c\t/^#define BEGIN /;\"\td\tlanguage:C\tfile:\n   DEFUN\tinput.c\t/^#define DEFUN(/;\"\td\tlanguage:C\tfile:\n   END\tinput.c\t/^#define END /;\"\td\tlanguage:C\tfile:\n\nThe output with options:\n.. code-block::\n\n   $ ctags --param-CPreProcessor._expand=1 --fields-C=+'{macrodef}' --fields=+'{signature}' -o - input.c\n   BEGIN\tinput.c\t/^#define BEGIN /;\"\td\tlanguage:C\tfile:\tmacrodef:{\n   DEFUN\tinput.c\t/^#define DEFUN(/;\"\td\tlanguage:C\tfile:\tsignature:(NAME)\tmacrodef:int NAME (int x, int y)\n   END\tinput.c\t/^#define END /;\"\td\tlanguage:C\tfile:\tmacrodef:}\n   myfunc\tinput.c\t/^DEFUN(myfunc)$/;\"\tf\tlanguage:C\ttyperef:typename:int\tsignature:(int x,int y)\n\n``myfunc`` coded by ``DEFUN`` macro is captured well.\n\n\nThis feature is highly experimental. At least three limitations are known.\n\n* This feature doesn't understand ``#undef`` yet.\n  Once a macro is defined, its invocation is always expanded even\n  after the parser sees ``#undef`` for the macro in the same input\n  file.\n\n* Macros are expanded incorrectly if the result of macro expansion\n  includes the macro invocation again.\n\n* Currently, ctags can expand a macro invocation only if its\n  definitions are in the same input file. ctags cannot expand a macro\n  defined in the header file included from the current input file.\n\nEnabling this macro expansion feature makes the parsing speed about\ntwo times slower.\n\n\nIncompatible Changes\n---------------------------------------------------------------------\n\nThe parser is mostly compatible with the old one. There are some minor\nincompatible changes which are described below.\n\n\nAnonymous structure names\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe old parser produced structure names in the form ``__anonN`` where N\nwas a number starting at 1 in each file and increasing at each new\nstructure. This caused collisions in symbol names when ctags was run\non multiple files.\n\nIn the new parser the anonymous structure names depend on the file name\nbeing processed and on the type of the structure itself. Collisions are\nfar less likely (though not impossible as hash functions are unavoidably\nimperfect).\n\nPitfall: the file name used for hashing includes the path as passed to the\nctags executable. So the same file \"seen\" from different paths will produce\ndifferent structure names. This is unavoidable and is up to the user to\nensure that multiple ctags runs are started from a common directory root.\n\nFile scope\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe file scope information is not 100% reliable. It never was.\nThere are several cases in that compiler, linker or even source code\ntricks can \"unhide\" file scope symbols (for instance \\*.c files can be\nincluded into each other) and several other cases in that the limitation\nof the scope of a symbol to a single file simply cannot be determined\nwith a single pass or without looking at a program as a whole.\n\nThe new parser defines a simple policy for file scope association\nthat tries to be as compatible as possible with the old parser and\nshould reflect the most common usages. The policy is the following:\n\n- Namespaces are in file scope if declared inside a .c or .cpp file\n\n- Function prototypes are in file scope if declared inside a .c or .cpp file\n\n- K&R style function definitions are in file scope if declared static\n  inside a .c file.\n\n- Function definitions appearing inside a namespace are in file scope only\n  if declared static inside a .c or .cpp file.\n  Note that this rule includes both global functions (global namespace)\n  and class/struct/union members defined outside of the class/struct/union\n  declaration.\n\n- Function definitions appearing inside a class/struct/union declaration\n  are in file scope only if declared static inside a .cpp file\n\n- Function parameters are always in file scope\n\n- Local variables are always in file scope\n\n- Variables appearing inside a namespace are in file scope only if\n  they are declared static inside a .c or .cpp file\n\n- Variables that are members of a class/struct/union are in file scope\n  only if declared in a .c or .cpp file\n\n- Typedefs are in file scope if appearing inside a .c or .cpp file\n\nMost of these rules are debatable in one way or the other. Just keep in mind\nthat this is not 100% reliable.\n\nInheritance information\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe new parser does not strip template names from base classes.\nFor a declaration like\n\n.. code-block:: C\n\n\ttemplate<typename A> class B : public C<A>\n\nthe old parser reported ``C`` as base class while the new one reports\n``C<A>``.\n\nTyperef\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe syntax of the typeref field (``typeref:A:B``) was designed with only\nstruct/class/union/enum types in mind. Generic types don't have ``A``\ninformation and the keywords became entirely optional in C++:\nyou just can't tell. Furthermore, struct/class/union/enum types\nshare the same namespace and their names can't collide, so the ``A``\ninformation is redundant for most purposes.\n\nTo accommodate generic types and preserve some degree of backward\ncompatibility the new parser uses struct/class/union/enum in place\nof ``A`` where such keyword can be inferred. Where the information is\nnot available it uses the 'typename' keyword.\n\nGenerally, you should ignore the information in field ``A`` and use\nonly information in field ``B``.\n"
  },
  {
    "path": "docs/parser-gdscript.rst",
    "content": ".. _gdscript:\r\n\r\n======================================================================\r\nThe new GDScript parser\r\n======================================================================\r\n\r\nThe GDScript parser is written using the token based Python parser as a base\r\ndue to similarities with the Python language. Some adjustments have been made\r\nfor the differences between GDScript and Python. A short list of major\r\ndifferences:\r\n\r\n- Files are classes. All symbols are attributes of the class defined by the\r\n  file.\r\n- There are no functions because all symbols are class attributes, so all\r\n  \"functions\" are methods.\r\n- Variables are explicitly declared with the `var` keyword.\r\n- Enum, signal and const keywords are added.\r\n"
  },
  {
    "path": "docs/parser-html.rst",
    "content": ".. _html:\n\n======================================================================\nThe new HTML parser\n======================================================================\n\n:Maintainer: Jiri Techet <techet@gmail.com>\n\nIntroduction\n---------------------------------------------------------------------\n\nThe old HTML parser was line-oriented based on regular expression matching. This\nbrought several limitations like the inability of the parser to deal with tags\nspanning multiple lines and not respecting HTML comments. In addition, the speed\nof the parser depended on the number of regular expressions - the more tag types\nwere extracted, the more regular expressions were needed and the slower the\nparser became. Finally, parsing of embedded JavaScript was very limited, based\non regular expressions and detecting only function declarations.\n\nThe new parser is hand-written, using separated lexical analysis (dividing\nthe input into tokens) and syntax analysis. The parser has been profiled and\noptimized for speed so it is one of the fastest parsers in Universal Ctags.\nIt handles HTML comments correctly and in addition to existing tags it extracts\nalso <h1>, <h2> and <h3> headings. It should be reasonably simple to add new\ntag types.\n\nFinally, the parser uses the new functionality of Universal Ctags to use another\nparser for parsing other languages within a host language. This is used for\nparsing JavaScript within <script> tags and CSS within <style> tags. This\nsimplifies the parser and generates much better results than having a simplified\nJavaScript or CSS parser within the HTML parser. To run JavaScript and CSS parsers\nfrom HTML parser, use `--extras=+g` option.\n"
  },
  {
    "path": "docs/parser-in-c.rst",
    "content": ".. _writing_parser_in_c:\n\n=============================================================================\nWriting a parser in C\n=============================================================================\n\nThe section is based on the section \"Integrating a new language parser\" in \"`How\nto Add Support for a New Language to Exuberant Ctags (EXTENDING)\n<http://ctags.sourceforge.net/EXTENDING.html>`_\" of Exuberant Ctags documents.\n\nNow suppose that I want to truly integrate compiled-in support for Swine into\nctags.\n\nRegistering a parser\n-------------------------------------------------\nFirst, I create a new module, ``swine.c``, and add one externally visible function\nto it, ``extern parserDefinition *SwineParser(void)``, and add its name to the\ntable in ``parsers.h``. The job of this parser definition function is to create\nan instance of the ``parserDefinition`` structure (using ``parserNew()``) and\npopulate it with information defining how files of this language are recognized,\nwhat kinds of tags it can locate, and the function used to invoke the parser on\nthe currently open file.\n\nThe structure ``parserDefinition`` allows assignment of the following fields:\n\n.. code-block:: c\n\n\tstruct sParserDefinition {\n\t\t/* defined by parser */\n\t\tchar* name;                    /* name of language */\n\t\tkindDefinition* kindTable;\t   /* tag kinds handled by parser */\n\t\tunsigned int kindCount;        /* size of 'kinds' list */\n\t\tconst char *const *extensions; /* list of default extensions */\n\t\tconst char *const *patterns;   /* list of default file name patterns */\n\t\tconst char *const *aliases;    /* list of default aliases (alternative names) */\n\t\tparserInitialize initialize;   /* initialization routine, if needed */\n\t\tparserFinalize finalize;       /* finalize routine, if needed */\n\t\tsimpleParser parser;           /* simple parser (common case) */\n\t\trescanParser parser2;          /* rescanning parser (unusual case) */\n\t\tselectLanguage* selectLanguage; /* may be used to resolve conflicts */\n\t\tunsigned int method;           /* See METHOD_ definitions above */\n\t\tunsigned int useCork;\t\t   /* bit fields of corkUsage */\n\t\t...\n\t};\n\nThe ``name`` field must be set to a non-empty string. Also either ``parser`` or\n``parser2`` must set to point to a parsing routine which will generate the tag\nentries. All other fields are optional.\n\nReading input file stream\n-------------------------------------------------\nNow all that is left is to implement the parser. In order to do its job, the\nparser should read the file stream using using one of the two I/O interfaces:\neither the character-oriented ``getcFromInputFile()``, or the line-oriented\n``readLineFromInputFile()``.\n\nSee \":ref:`input-text-stream`\" for more details.\n\nParsing\n-------------------------------------------------\nHow our Swine parser actually parses the contents of the file is entirely up to\nthe writer of the parser--it can be as crude or elegant as desired. You will\nnote a variety of examples from the most complex (``parsers/cxx/*.[hc]``) to the\nsimplest (``parsers/make.[ch]``).\n\nAdding a tag to the tag file\n-------------------------------------------------\nWhen the Swine parser identifies an interesting token for which it wants to add\na tag to the tag file, it should create a ``tagEntryInfo`` structure and\ninitialize it by calling ``initTagEntry()``, which initializes defaults and\nfills information about the current line number and the file position of the\nbeginning of the line. After filling in information defining the current entry\n(and possibly overriding the file position or other defaults), the parser passes\nthis structure to ``makeTagEntry()``.\n\nSee \":ref:`output-tag-stream`\" for more details.\n\nAdding the parser to ``ctags``\n-------------------------------------------------\nLastly, be sure to add your the name of the file containing your parser (e.g.\n``parsers/swine.c``) to the macro ``PARSER_SRCS`` in the file ``source.mak``, so\nthat your new module will be compiled into the program.\n\nMisc.\n-------------------------------------------------\nThis is all there is to it. All other details are specific to the parser and how\nit wants to do its job.\n\nThere are some support functions which can take care of some commonly needed\nparsing tasks, such as *keyword table lookups* (see ``main/keyword.c``), which you\ncan make use of if desired (examples of its use can be found in ``parsers/c.c``,\n``parsers/eiffel.c``, and ``parsers/fortran.c``).\n\nSupport functions can be found in ``main/*.h`` excluding ``main/*_p.h``.\n\nAlmost everything is already taken care of automatically for you by the\ninfrastructure. Writing the actual parsing algorithm is the hardest part, but is\nnot constrained by any need to conform to anything in ctags other than that\nmentioned above.\n\nThere are several different approaches used in the parsers inside Universal\nCtags and you can browse through these as examples of how to go about creating\nyour own.\n"
  },
  {
    "path": "docs/parser-puppetManifest.rst",
    "content": ".. _puppetManifest:\n\n======================================================================\npuppetManifest parser\n======================================================================\n\n.. NOT REVIEWED YET\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\npuppetManifest is an experimental parser for testing multi tables\nregex meta parser defined with ``--_mtable-<LANG>`` option.\n\nThe parser has some bugs derived from the limit of the multi tables\nregex meta parser.\n\n\nHere document\n\n\tThe parser cannot ignore the contents inside the area of\n\there document. The end marker of here document is defined\n\tin the source code. Currently, ctags has no way to add a\n\tregex pattern for detecting the end maker.\n"
  },
  {
    "path": "docs/parser-python.rst",
    "content": ".. _python:\n\n======================================================================\nThe new Python parser\n======================================================================\n\n:Maintainer: Colomban Wendling <ban@herbesfolles.org>\n\nIntroduction\n---------------------------------------------------------------------\n\nThe old Python parser was a line-oriented parser that grew way beyond\nits capabilities, and ended up riddled with hacks and easily fooled by\nperfectly valid input.   By design, it especially had problems dealing\nwith constructs spanning multiple lines, like triple-quoted strings\nor implicitly continued lines; but several less tricky constructs were\nalso mishandled, and handling of lexical constructs was duplicated and\neach clone evolved in its own direction, supporting different features\nand having different bugs depending on the location.\n\nAll this made it very hard to fix some existing bugs, or add new\nfeatures.  To fix this regrettable state of things, the parser has been\nrewritten from scratch separating lexical analysis (generating tokens)\nfrom syntactical analysis (understanding what the lexemes mean).\nThis moves understanding lexemes to a single location, making it\nconsistent and easier to extend with new lexemes, and lightens the\nburden on the parsing code making it more concise, robust and clear.\n\nThis rewrite allowed to quite easily fix all known bugs of the old\nparser, and add many new features, including:\n\n- Tagging function parameters\n- Extraction of decorators\n- Proper handling of semicolons\n- Extracting multiple variables in a combined declaration\n- More accurate support of mixed indentation\n- Tagging local variables\n\n\nThe parser should be compatible with the old one.\n"
  },
  {
    "path": "docs/parser-tcl.rst",
    "content": ".. _tcl:\n\n======================================================================\nThe new Tcl parser\n======================================================================\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\nTcl parser is rewritten as a token oriented parser to support\nnamespace.  It was line oriented parser. Some incompatibility between\nExuberant Ctags is introduced in the rewriting.\n\nThe line oriented parser captures `class`, `public|protected|private\nmethod`.  They are definitions in ITcl and TclOO. The new token oriented Tcl\nparser ignores them.  Instead ITcl and TclOO subparser running on Tcl base\nparser capture them.\n\nKnown bugs\n----------------------------------------------------------------------\n\nFull qualified tags\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe separator used in full qualified tags should be `::` but `.` is\nused.\n\nA ITcl or TclOO class `C` can be defined in a Tcl namespace `N`:\n\n.. code-block:: Tcl\n\n    namespace eval N {\n\too::class create C {\n\t}\n    }\n\nWhen ``--extras=+q`` is given, currently ctags reports::\n\n\tN.C ...\n\nThis should be::\n\n\tN::C ...\n\nMuch work is needed to fix this.\n\nNested procs\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n`proc` defined in a `proc` cannot be captured well.\nThis is a regression.\n"
  },
  {
    "path": "docs/parser-v.rst",
    "content": ".. _v:\n\n======================================================================\nThe V parser\n======================================================================\n\n:Maintainer: Tim Marston <tim@ed.am>\n\nDevelopment\n---------------------------------------------------------------------\n\nThe V parser can emit warnings when it encounters code which does not parse.\nNormally, this would indicate a problem with the code being parsed.  But for\ndevelopment, it is useful to run the parser against a ton of known-good code\n(e.g., the V sources) to check the parser.  To emit unexpected token warnings,\nrun ctags with `-d 16`.  (Note: this requires ctags to have been built with\n`--enable-debugging`).\n\nA useful terminal command to run the V parser against the whole V source code\nand list the names of any files that fail to parser is:\n\n.. code-block:: console\n\n    $ cd vlib\n    $ find . -name '*test*' -prune -o -name '*.v' -print0 | \\\n        xargs -0 ctags -d 16 2>&1 | \\\n        sed -n 's/^UNEXPECTED.*at \\([^:]*\\):.*$/\\1/p' | \\\n        sort | uniq\n\nDebugging\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe V parser can also emit a dump of its operation by running ctags with `-d 8`.\n(Note: like the parser warnings, this also requires ctags to have been built\nwith `--enable-debugging`.)\n\nThe dump is extremely useful for debugging the parser and shows:\n\n- individual grammar parsers starting ({foo:) and ending (:foo})\n- lexer reading tokens (UPPERCASE)\n  - tokens read in non-primary token buffer appear in square brackets\n- tokens being \"unread\" (˄)\n- unread tokens being replayed (˅)\n- emitted tags (#)\n\nShortcomings\n---------------------------------------------------------------------\n\nThe V parser currently has no support for\n\n- cross references (except modules)\n- function arguments\n- closure arguments\n- variable types\n\nDesign\n---------------------------------------------------------------------\n\nThe V Parser reads tokens and parses V grammar in parallel (i.e., it does not\nbuild an AST).\n\nThe individual grammar parsers all follow these simple rules:\n\n- when called, `token` argument already holds the first token which an\n  individual grammar parser should recognise\n- on return, individual parser functions read only the tokens they recognises\n  and no additional tokens are read (i.e., they do not \"over read\")\n- these rules are enforced by `Assert` statements at the start of each parser\n  function\n\nThe lexer allows you to \"unread\" up to `MAX_REPLAYS` tokens.  But unreading a\ntoken only stores it (to be replayed when `getToken()` is next called) and it\ndoes not reset the `token` to hold its previous value.  Where it is necessary to\nread ahead and retain the value of a tokens, additional token buffers can be\nused (`newToken()`) or the primary token buffer can be duplicated (`dupToken()`)\nso that it can continue to be used for reading.  Generally, the primary token\nbuffer is used where it can be, so that the debug dump accurately shows where\nadditional buffers are used.  This helps to diagnose situations where unreading\na token does not reset its previous value.\n\nUse of `expectToken()`, rather than `isToken()`, is encouraged where applicable\nso that the parser can be run against as much known-good V code as possible and\nchecked to ensure that is not caught out by uncommon grammar.\n\nFully-qualified Identifiers and External Symbols\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe following tokens represent identifiers:\n- `IDENT` is a V variable/function/field name (e.g., `foo`)\n- `TYPE` is a V struct/interface/alias/union name (e.g., `Foo`)\n- `EXTERN` is never emitted by the lexer and represents an external symbol\n\nWhen the lexer returns an `IDENT` or `TYPE` and `parseFullyQualified()` is\nsubsequently called to consume any additional tokens which may make-up a\nfully-qualified identifier, the provided `token` is also updated to reflect the\nfinal, fully-qualified identifier, so that:\n\n- token->string is the whole, fully-qualified name of the identifier (e.g.,\n  `user.id`)\n- token->type is updated to `IDENT` or `TYPE` to reflect the last part of the\n  fully-qualified identifier (e.g., `Foo.bar` is an `IDENT` and `foo.Bar` is a\n  `TYPE`), or to `EXTERN` where the fully-qualified identifier is an external\n  symbol (e.g., `C.foo` or `JS.Foo`) and the type can not be determined further\n- the token is also marked as being fully-qualified, so that subsequent attempts\n  to fully-qualify it (e.g., after it is unread and replayed) have no effect\n"
  },
  {
    "path": "docs/parser-vim.rst",
    "content": ".. _vim:\n\n======================================================================\nThe Vim parser\n======================================================================\n\nIncompatible change\n---------------------------------------------------------------------\n\nQuoted from ``:help script-variable`` in the Vim documentation::\n\n\t\t\t    *script-variable* *s:var*\n    In a Vim script variables starting with \"s:\" can be used. They\n    cannot be accessed from outside of the scripts, thus are local to\n    the script.\n\nExuberant Ctags records the prefix `s:` as part of a script-local\nvariable's name. However, it is omitted from function names. As\nrequested in issue #852 on GitHub, Universal Ctags now also includes\nthe prefix in script-local function names.\n"
  },
  {
    "path": "docs/parser-xslt.rst",
    "content": ".. _xslt:\n\n======================================================================\nXSLT parser\n======================================================================\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\nThis parser only supports XSLT 1.0.\nIf a newer version (2.0 and 3.0) is specified in an input file, ctags\njust skips the input. With ``--verbose``, ctags prints the detected\nversion of the input file.\n\nScope information generated by the XSLT parser is a bit broken.\nCurrently a period (`.`) is used as the separator in nested scopes.\nThis is the default separator value in ctags.\n\nWhen the XSLT parser captures a node `<xsl:template match=\"...\">` the\nvalue of the `match` attribute is tagged with kind `matchedTemplate`.\nWhen a `matchedTemplate` name is stored as part of the scope information,\nclient tools may be confused because `.` is used both as the scope separator\nand in the XPath match expression.\n"
  },
  {
    "path": "docs/parsers.rst",
    "content": "=============================================================================\nParsers\n=============================================================================\n\n\n.. contents:: `Table of contents`\n\t:depth: 3\n\t:local:\n\nThis section deals with individual parser topics.\n\n.. toctree::\n\t:maxdepth: 2\n\n\tparser-asm.rst\n\tparser-cmake.rst\n\tparser-cxx.rst\n\tparser-gdscript.rst\n\tparser-html.rst\n\tparser-puppetManifest.rst\n\tparser-python.rst\n\tparser-tcl.rst\n\tparser-v.rst\n\tparser-vim.rst\n\tparser-xslt.rst\n"
  },
  {
    "path": "docs/releasing.rst",
    "content": ".. _releasing:\n\n======================================================================\nHow to release a new version\n======================================================================\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\n.. contents:: `Table of contents`\n\t:depth: 3\n\t:local:\n\n----\n\n#. Update parsers' ``versionCurrent`` and ``versionAge`` members\n\n#. Revise misc/visit-version-info.bash, run it, verify the output\n\n#. Update NEWS.rst\n\n   + New parsers\n   + Changes about ctags' CLI and OUTPUT\n   + Changes about parsers' kinds, roles, fields, extras, and parameters\n\n#. Update the version numbers (e.g. \"5.9.0\", \"5,9,0\") embedded in the following files:\n\n   + ``configure.ac``\n\n\t - AC_INIT\n\n   + ``main/ctags.h``\n\n\t - PROGRAM_VERSION\n\t - PROGRAM_COPYRIGHT\n\t - OUTPUT_VERSION_CURRENT\n\t - OUTPUT_VERSION_AGE\n\n   + ``win32/ctags.rc``\n\n\t - FILEVERSION\n\t - PRODUCTVERSION\n\t - VALUE \"FileVersion\"\n\t - VALUE \"LegalCopyright\"\n\t - VALUE \"ProductVersion\"\n\n   + ``win32/ctags.exe.manifest``\n\n\t - assemblyIdentity\n\n   + ``win32/config_mvc.h``\n\n\t - PACKAGE_STRING\n\t - PACKAGE_VERSION\n\n   + ``win32/config_mingw.h``\n\n\t - PACKAGE_STRING\n\t - PACKAGE_VERSION\n\t - VERSION\n\n   + ``misc/git-tag-maybe.sh``\n\n\t - BASE\n\n   + ``NEWS.rst``\n\n\t - Changes in ...\n\n#. Revise the version numbers in each parsers and their man pages\n\n#. Revise the version number in writer-json.c\n\n#. Regenerate rst files under ``docs/man``.\n\n#. Add a entry for the new version to ``docs/news.rst``.\n\n#. Put an annotation tag for the version and push it to ``github.com/universal-ctags/ctags``\n\n   .. code-block:: console\n\n\t\t\t\t   $ git tag -a v5.9.0 -m 'Version 5.9.0'\n\t\t\t\t   $ git push upstream --tags\n\n#. Make tarball in a freshly cloned directory\n\n   .. code-block:: console\n\n\t\t\t\t   $ ./configure\n\t\t\t\t   $ make distcheck\n\t\t\t\t   $ make clean\n\t\t\t\t   $ make dist\n\n   You will get a file like universal-ctags-5.9.0.tar.gz.\n\n#. Make a release on the GitHub page\n\n   Don't forget to upload the tar.gz file.\n"
  },
  {
    "path": "docs/reporting.rst",
    "content": "..\n    NOT REVIEWED YET\n\n======================================================================\nRequest for extending a parser (or Reporting a bug of parser)\n======================================================================\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\n.. contents:: `Table of contents`\n    :depth: 3\n    :local:\n\n----\n\nSometimes you will find u-ctags doesn't make a tag for a language\nobject unexpectedly. Writing a patch for making the tag is\nappreciate. However, you may not have time to do so. In that case, you\ncan open an issue on the GitHub page of u-ctags.\n\nThis section tells you how to drive u-ctags developers effectively.\n\nBefore reporting\n---------------------------------------------------------------------\n\nU-Ctags just captures the definitions of language objects.  U-ctags\nhas an infrastructure for capturing references for language objects.\nHowever, we implement reference tagging limited area.  We will not\nwork on writing new code for capturing references for your favorite\nlanguage.  About requests for capturing reference tags, we will say\n\"patches are welcome.\".\n\nWhat kind of language objects u-ctags captures is controlled by\n`--kind-<LANG>` option. Some kinds are disabled by default because we\nassume people don't want too large `tags` file. When you cannot find a\nlanguage object you want in a tags file, it is worth for checking the\nstatus of kinds. `--list-kinds=<LANG>` or (`--list-kinds-full=<LANG>`)\noption lists the status of the given language.\n\nLet's see an example.\n\nConsider following input (foo.h):\n\n.. code-block:: C\n\n    struct point {\n      int x, y;\n    };\n\n    struct point *make_point(int x0, int y0);\n\ntags output generated with `u-ctags -o - /tmp/foo.h` is as following.\n::\n\n    point    foo.h    /^struct point {$/;\"    s\n    x    foo.h    /^  int x, y;$/;\"    m    struct:point    typeref:typename:int\n    y    foo.h    /^  int x, y;$/;\"    m    struct:point    typeref:typename:int\n\nThough `point`, `x` and `y` are tagged, the declaration `make_point`\nis not tagged because `prototype` kind of C++ is disabled by default.\nYou can know it from the output of `ctags --list-kinds-full=C++`.\n::\n\n    #LETTER NAME       ENABLED REFONLY NROLES MASTER DESCRIPTION\n    A       alias      no      no      0      NONE   namespace aliases\n    L       label      no      no      0      C      goto labels\n    N       name       no      no      0      NONE   names imported via using scope::symbol\n    ...\n    p       prototype  no      no      0      C      function prototypes\n\nBy turning on the kind with `--kinds-C++=+p`, u-ctags tags\n`make_point`::\n\n    make_point    foo.h    /^struct point *make_point(int x0, int y0);$/;\"    p    typeref:struct:point *\n    point    foo.h    /^struct point {$/;\"    s\n    x    foo.h    /^  int x, y;$/;\"    m    struct:point    typeref:typename:int\n    y    foo.h    /^  int x, y;$/;\"    m    struct:point    typeref:typename:int\n\nWildcard `*` is for enabling all kinds of a language at once.\n`--kinds-C++=*` option enables all kinds of C++ parser. If you specify `all`\nas the name of `<LANG>`, you can enable all kinds of all languages at once.\n\nThe content of report\n---------------------------------------------------------------------\n\nDon't assume following three things.\n\nU-ctags developers know vi.\n\n    If you explain the expectation about how tags related functions of vi\n    and its plugins, U-ctags developers don't understand it.\n    The answer from them can be \"it can be a bug of vi.\"\n\nU-ctags developers know the programming language that you are talking.\n\n    U-ctags developers need your help to understand the meaning of\n    language object you asked tagging especially about kind.  A person\n    extending a parser have to decide a kind of newly tagging language\n    object: reusing an existing kind or introducing a new kind.\n    U-ctags developers expect a report know the concept kind, field,\n    and extra. ctags.1 man page of u-ctags explains them.\n\nEnglish is the native language of the head maintainer.\n\n    I don't want to write this but I have to write this.\n    Following are my private request for reporters.\n\n    Instead of long explanation, showing code or output\n    examples make me understand what you want.\n\n    Don't omit sentences. Please, write your sentence\n    in full.\n\n    Use pronounce fewer.\n\nU-ctags can generate something meaningful from a broken input.\n\n    From garbage, u-ctags generates garbage.\n    For a syntactically broken input source file, U-ctags\n    does not work well. U-ctags developers will not work\n    on improving u-ctags for handing such input.\n    The exception is that macro related input. Well known\n    one is C and C++.\n\nFollowing a tuple with three items helps us to understand what you want.\n\n1. Input file\n\n    A shorter input file is better. However, it must be syntactically\n    valid.  Show the URL (or something) where you get the input\n    file. It is needed to incorporate the input file to the u-ctags\n    source tree as a test case.\n\n2. Command line running u-ctags\n\n3. Expected output\n\nThese three items should be rendered preformatted form on an issue\npage of GitHub. Use triple backquotes notation of GitHub's\nmarkdown notation. I will close an issue with a bad notation\nlike this `issue <https://github.com/universal-ctags/ctags/issues/1547>`_.\n\nAn example of good report\n---------------------------------------------------------------------\n\nFor the following input file(input.f90), u-ctags reports incomplete pattern\nfor function `f` at the line 23.\n\n::\n\n   ! input.f90, taken from https://github.com/universal-ctags/ctags/issues/1616\n   module example_mod\n\n    ! This module contains two interfaces:\n    !   1. f_interface, which is an interface to the local f function\n    !   2. g, which is implemented in the example_smod submodule\n\n       interface f_interface\n          ! The function `f` is defined below, within the `contains` statement\n           module function f(x) result(y)\n              integer :: x, y\n           end function f\n        end interface f_interface\n\n       interface\n          ! The function `g` is implemented in example_smod.f90\n           module function g(x) result(y)\n              integer :: x,y\n           end function g\n       end interface\n\n       contains\n        function f(x) result(y)\n           integer :: x, y\n\n           y = x * 2\n        end function f\n   end module example_mod\n\nI run ctags with following command line::\n\n  u-ctags --fields=+n -o - /tmp/input.f90\n\nWhat I got::\n\n\texample_mod\t/tmp/input.f90\t/^module example_mod$/;\"\tm\tline:2\n\tf\t/tmp/input.f90\t/^     fu/;\"\tf\tline:23\n\tf_interface\t/tmp/input.f90\t/^    interface f_interface$/;\"\ti\tline:8\tmodule:example_mod\n\nI think this should be::\n\n\texample_mod\t/tmp/input.f90\t/^module example_mod$/;\"\tm\tline:2\n\tf\t/tmp/input.f90\t/^     function f/;\"\tf\tline:23\n\tf_interface\t/tmp/input.f90\t/^    interface f_interface$/;\"\ti\tline:8\tmodule:example_mod\n\nor::\n\n\texample_mod\t/tmp/input.f90\t/^module example_mod$/;\"\tm\tline:2\n\tf\t/tmp/input.f90\t/^     function f(x) result(y)/;\"\tf\tline:23\n\tf_interface\t/tmp/input.f90\t/^    interface f_interface$/;\"\ti\tline:8\tmodule:example_mod\n\n\nEither way, `/^     fu/` is too short as a pattern.\n\nThe version of u-ctags is `83b0d1f6`::\n\n\t$ u-ctags --version\n\tUniversal Ctags 0.0.0(83b0d1f6), Copyright (C) 2015 Universal Ctags Team\n\tUniversal Ctags is derived from Exuberant Ctags.\n\tExuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert\n\t  Compiled: Dec 15 2017, 08:07:36\n\t  URL: https://ctags.io/\n\t  Optional compiled features: +wildcards, +regex, +multibyte, +debug, +option-directory, +xpath, +json, +interactive, +sandbox, +yaml\n"
  },
  {
    "path": "docs/running-multi-parsers.rst",
    "content": ".. NOT REVIEWED YET\n\n.. _multiple_parsers:\n\nRunning multiple parsers on an input file\n---------------------------------------------------------------------\n\nUniversal Ctags provides parser developers two ways, *guest parser* (guest/host)\nand *subparser* (sub/base), to run multiple parsers for an input file.\n\nThis section shows concepts behind the running multiple parsers and real\nexamples.\n\n.. _host-guest-parsers:\n\nGuest parser: Applying a parser to specified areas of input file\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n*Guest parser* (guest/host) considers the case that an input file has areas\nwritten in languages different from the language for the input file.\n\nA *host parser* parses the input file and detects the areas.\nThe host parser schedules *guest parsers* parsing the areas.\nThe guest parsers parse the areas.\n\n.. figure:: area-and-parsers.svg\n\t    :scale: 80%\n\n.. NOTE: We don't have --list-guest-parser option as --list-subparser for\n\ta subparser, because a guest parser does not define a new parser and it just\n\tuses parsers which are already defined.\n\nCommand line interface\n.........................................................................\n\nRunning guest parser can be controlled with guest (``g``) extras flag.\nBy default it is disabled. To turning on the feature running\nguest parser, specify ``--extras=+g``.\n\nIf ``--fields=+E`` is given, all tags generated by a guest parser is marked\n``guest`` in their ``extras:`` fields.\n\nExamples of guest parser\n......................................................................\n\n{CSS,JavaScript}/HTML parser combination\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nFor an HTML file, you may want to run HTML parser, of course. The\nHTML file may have CSS areas and JavaScript areas. In other hand\nUniversal Ctags has both CSS and JavaScript parsers. Don't you\nthink it is useful if you can apply these parsers to the areas?\n\nIn this case, HTML has responsible to detect the CSS and\nJavaScript areas and record the positions of the areas.\nThe HTML parser schedules delayed invocations of CSS and\nJavaScript parsers on the area with promise API.\n\nHere HTML parser is a *host parser*. CSS and JavaScript parsers\nare *guest parsers*.\n\nSee \":ref:`The new HTML parser <html>`\" and \"`parsers/html.c\n<https://github.com/universal-ctags/ctags/blob/master/parsers/html.c>`_\".\n\n\nC/Yacc parser combination\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nA yacc file has some areas written in C. Universal Ctags has both YACC\nand C parsers. You may want to run C parser for the areas from YACC\nparser.\n\nHere YACC parser is a host parser. C parser is a guest parser.\nSee \"`optlib/yacc.ctags\n<https://github.com/universal-ctags/ctags/blob/master/optlib/yacc.ctags>`_\".\n\n\nPod/Perl parser combination\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nPod (Plain Old Documentation) is a language for documentation.  The language\ncan be used not only in a stand alone file but also it can be\nused inside a Perl script.\n\nUniversal Ctags has both parsers for Perl and Pod.\nThe Perl parser recognizes the area where Pod document is\nembedded in a Perl script and schedules applying pod parser\nas a guest parser on the area.\n\n.. _base-sub-parsers:\n\nSubparser: Tagging definitions of higher (upper) level language\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBackground\n......................................................................\n\nConsider an application written in language X.  The application has\nits domain own concepts. Developers of the application may try to\nexpress the concepts in the syntax of language X.\n\nIn language X level, the developer can define functions, variables, types, and\nso on. Further more, if the syntax of X allows, the developers want to\ndefine higher level (= application level) things for implementing the\ndomain own concepts.\n\nLet me show the part of source code of SPY-WARS, an imaginary game application.\nIt is written in scheme language, a dialect of lisp.\n(Here `gauche <https://practical-scheme.net/gauche/index.html>`_ is considered\nas the implementation of scheme interpreter).\n\n.. code-block:: scheme\n\n    (define agent-tables (make-hash-table))\n    (define-class <agent> ()\n      ((rights :init-keyword :rights)\n       (responsibilities :init-keyword :responsibilities)))\n\n    (define-macro (define-agent name rights responsibilities)\n      `(hash-table-put! agent-tables ',name\n\t\t\t(make <agent>\n\t\t\t  :rights ',rights\n\t\t\t  :responsibilities ',responsibilities)))\n\n    (define-agent Bond (kill ...) ...)\n    (define-agent Bourne ...)\n\n    ...\n\n``define``, ``define-class``, and ``define-macro`` are keywords of scheme\nfor defining a variable, class and macro. Therefore scheme parser of\nctags should make tags for ``agent-tables`` with variable kind,\n``<agent>`` with class kind, and ``define-agent`` with macro kind.\nThere is no discussion here.\n\n    NOTE: To be exactly ``define-class`` and ``define-macro`` are not the part\n    of scheme language. They are part of gauche. That means three parsers\n    are stacked: scheme, gosh, and SPY-WARS.\n\nThe interesting things here are ``Bond`` and ``Bourne``.\n\n.. code-block:: scheme\n\n    (define-agent Bond (kill ...) ...)\n    (define-agent Bourne ...)\n\nIn scheme parser level, the two expressions define nothing; the two\nexpressions are just macro (``define-agent``) expansions.\n\nHowever, in the application level, they define agents as the\nmacro name shown. In this level Universal Ctags should capture\n``Bond`` and ``Bourne``. The question is which parser should\ncapture them?  scheme parser should not; define-agent is not part of\nscheme language. Newly defined SPY-WARS parser is the answer.\n\nThough ``define-agent`` is just a macro in scheme parser level,\nit is keyword in SPY-WARS parser. SPY-WARS parser makes a\ntag for a token next to ``define-agent``.\n\nThe above example illustrates levels of language in an input\nfile. scheme is used as the base language. With the base language we\ncan assume an imaginary higher level language named SPY-WARS is used\nto write the application. To parse the source code of the application\nwritten in two stacked language, ctags uses the two stacked parsers.\n\nMaking higher level language is very popular technique in the\nlanguages of lisp family (see \"`On Lisp\n<http://www.paulgraham.com/onlisp.html>`_\" for more details).\nHowever, it is not special to lisp.\n\nFollowing code is taken from linux kernel written in C:\n\n.. code-block:: C\n\n    DEFINE_EVENT(mac80211_msg_event, mac80211_info,\n\t    TP_PROTO(struct va_format *vaf),\n\t    TP_ARGS(vaf)\n    );\n\nThere is no concept EVENT in C language, however it make sense in the\nsource tree of linux kernel. So we can consider linux parser, based on\nC parser, which tags ``mac80211_msg_event`` as ``event`` kind.\n\n\nTerms\n......................................................................\n\nBase parser and subparser\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\nIn the context of the SPY-WARS example, scheme parser is called a *base\nparser*. The SPY-WARS is called a *subparser*. A base parser tags\ndefinitions found in lower level view. A subparser on the base parser tags\ndefinitions found in higher level view. This relationship can be nested.\nA subparser can be a base parser for another subparser.\n\n.. figure:: stack-and-parsers.svg\n\t    :scale: 80%\n\nAt a glance the relationship between two parsers are similar to the\nrelationship guest parser and host parser description in\n\":ref:`host-guest-parsers`\".\nHowever, they are different. Though a guest\nparser can run stand-alone, a subparser cannot; a subparser needs help\nfrom base parser to work.\n\nTop down parser choice and bottom up parser choice\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nThere are two ways to run a subparser: *top down* or *bottom up* parser\nchoices.\n\nUniversal Ctags can chose a subparser :ref:`automatically <guessing>`.\nMatching file name patterns and extensions are the typical ways for\nchoosing. A user can choose a subparser with ``--language-force=`` option.\nChoosing a parser in these deterministic way is called *top down*.\nWhen a parser is chosen as a subparser in the top down way, the\nsubparser must call its base parser. The base parser may call methods\ndefined in the subparser.\n\nUniversal Ctags uses *bottom up* choice when the top down way\ndoesn't work; a given file name doesn't match any patterns and\nextensions of subparsers and the user doesn't specify\n``--language-force=`` explicitly. In choosing a subparser bottom up way\nit is assumed that a base parser for the subparser can be chosen\nby top down way. During a base parser running, the base parser tries\nto detect use of higher level languages in the input file. As shown\nlater in this section, the base parser utilizes methods defined in its\nsubparsers for the detection. If the base parser detects the use of a\nhigher level language, a subparser for the higher level language is\nchosen.  Choosing a parser in this non-deterministic way (dynamic way)\nis called *bottom up*.\n\n============================== =================\ninput file                     subparser choices\n============================== =================\n*<SUB_LANG>*  (``input.sub``)  top down\n*<BASE_LANG>* (``input.base``) bottom up\n============================== =================\n\nHere is an example. Universal Ctags has both m4 parser and Autoconf\nparser.  The m4 parser is a base parser. The Autoconf parser is a\nsubparser based on the m4 parser. If ``configure.ac`` is given as an\ninput file, Autoconf parser is chosen automatically because the\nAutoconf parser has ``configure.ac`` in its patterns list. Based on the\npattern matching, Universal Ctags chooses the Autoconf parser\nautomatically (top down choice).\n\nIf ``input.m4`` is given as an input file, the Autoconf parser is\nnot chosen. Instead the m4 parser is chosen automatically because\nthe m4 parser has ``.m4`` in its extension list. The m4 parser passes\nevery token finding in the input file to the\nAutoconf parser. The Autoconf parser gets the chance to probe\nwhether the Autoconf parser itself can handle the input or not; if\na token name is started with ``AC_``, the Autoconf parser\nreports \"this is Autoconf input though its file extension\nis ``.m4``\" to the m4 parser. As the result the Autoconf parser is\nchosen (bottom up choice).\n\nSome subparsers can be chosen both top down and bottom up ways. Some\nsubparser can be chosen only top down way or bottom up ways.\n\n.. _multiple_parsers_directions:\n\nDirection flags\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\n.. TESTCASE: Units/flags-langdef-directions.r\n\n*Direction flags* specify how a base parser and a subparser work together. You\ncan choose directions by putting a long flag after\n``--langdef=<SUB_LANG>{base=<BASE_LANG>}``.\n\nThe following three direction flags are available;\n\n``shared`` (default):\n\tFor an input file of *<BASE_LANG>* (ex. ``input.base``), tags captured by\n\tboth *<BASE_LANG>* and *<SUB_LANG>* parser are recorded to tags file.\n\n\tFor an input file of *<SUB_LANG>* (ex. ``input.sub``), tags captured by only\n\t*<SUB_LANG>* parser are recorded to tags file.\n\n\t=============== ===================== ======================\n\tinput file      tags of *<BASE_LANG>* tags of *<SUB_LANG>*\n\t=============== ===================== ======================\n\t``input.base``  recorded              recorded\n\t``input.sub``   ---                   recorded\n\t=============== ===================== ======================\n\n``dedicated``:\n\tFor an input file of *<BASE_LANG>* (ex. ``input.base``), tags captured by\n\tonly *<BASE_LANG>* parser are recorded to tags file.\n\n\tFor an input file of *<SUB_LANG>* (ex. ``input.sub``), tags captured by both\n\t*<BASE_LANG>* and *<SUB_LANG>* parser are recorded to tags file.\n\n\t=============== ===================== ======================\n\tinput file      tags of *<BASE_LANG>* tags of *<SUB_LANG>*\n\t=============== ===================== ======================\n\t``input.base``  recorded              ---\n\t``input.sub``   recorded              recorded\n\t=============== ===================== ======================\n\n``bidirectional``:\n\tFor an input file of both *<BASE_LANG>* (ex. ``input.base``) and\n\t*<SUB_LANG>* (ex. ``input.sub``), tags captured by both *<BASE_LANG>* and\n\t<SUB_LANG> parser are recorded to tags file.\n\n\t=============== ===================== ======================\n\tinput file      tags of *<BASE_LANG>* tags of *<SUB_LANG>*\n\t=============== ===================== ======================\n\t``input.base``  recorded              recorded\n\t``input.sub``   recorded              recorded\n\t=============== ===================== ======================\n\nIf no direction flag is specified, it implies ``{shared}``.\n\nSee \":ref:`optlib_directions`\" in \":ref:`optlib`\" for examples of using the\ndirection flags.\n\nListing subparsers\n.........................................................................\nSubparsers can be listed with ``--list-subparser``:\n\n.. code-block:: console\n\n    $ ctags --options=./linux.ctags --list-subparsers=C\n    #NAME                          BASEPARSER           DIRECTION\n    linux                          C                    base => sub {shared}\n\nCommand line interface\n.........................................................................\n\nRunning subparser can be controlled with subparser (``s``) extras flag.\nBy default it is enabled. To turning off the feature running\nsubparser, specify ``--extras=-s``.\n\n\nExamples of subparser\n......................................................................\n\nAutomake/Make parser combination\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nSimply to say the syntax of Automake is the subset of Make.  However,\nthe Automake parser has interests in Make macros having special\nsuffixes: ``_PROGRAMS``, ``_LTLIBRARIES``, and ``_SCRIPTS`` so on.\n\nHere is an example of input for Automake:\n\n.. code-block:: Make\n\n    bin_PROGRAMS = ctags\n    ctags_CPPFLAGS =    \\\n\t    -I.         \\\n\t    -I$(srcdir) \\\n\t    -I$(srcdir)/main\n\nFrom the point of the view of the Make parser, ``bin_PROGRAMS`` is a just\na macro; the Make parser tags ``bin_PROGRAMS`` as a macro. The Make parser\ndoesn't tag ``ctags`` being right side of '``=``' because it is not a new\nname: just a value assigned to bin_PROGRAMS. However, for the Automake\nparser ``ctags`` is a new name; the Automake parser tags ``ctags`` with\nkind ``Program``. The Automake parser can tag it with getting help from\nthe Make parser.\n\nThe Automake parser is an exclusive subparser. It is chosen in top\ndown way; an input file name ``Makefile.am`` gives enough information for\nchoosing the Automake parser.\n\nTo give chances to the Automake parser to capture Automake own\ndefinitions, The Make parser provides following interface in\n``parsers/make.h``:\n\n.. code-block:: C\n\n    struct sMakeSubparser {\n\t    subparser subparser;\n\n\t    void (* valueNotify) (makeSubparser *s, char* name);\n\t    void (* directiveNotify) (makeSubparser *s, char* name);\n\t    void (* newMacroNotify) (makeSubparser *s,\n\t\t\t\t     char* name,\n\t\t\t\t     bool withDefineDirective,\n\t\t\t\t     bool appending);\n    };\n\nThe Automake parser defines methods for tagging Automake own definitions\nin a ``struct sMakeSubparser`` type variable, and runs the Make parser by\ncalling ``scheduleRunningBaseparser`` function.\n\nThe Make parser tags Make own definitions in an input file.  In\naddition Make parser calls the methods during parsing the input file.\n\n.. code-block:: console\n\n   $ ctags --fields=+lK  --extras=+r -o - Makefile.am\n   bin\tMakefile.am\t/^bin_PROGRAMS = ctags$/;\"\tdirectory\tlanguage:Automake\n   bin_PROGRAMS\tMakefile.am\t/^bin_PROGRAMS = ctags$/;\"\tmacro\tlanguage:Make\n   ctags\tMakefile.am\t/^bin_PROGRAMS = ctags$/;\"\tprogram\tlanguage:Automake\tdirectory:bin\n   ctags_CPPFLAGS\tMakefile.am\t/^ctags_CPPFLAGS =    \\\\$/;\"\tmacro\tlanguage:Make\n\n``bin_PROGRAMS`` and ``ctags_CPPFLAGS`` are tagged as macros of Make.\nIn addition ``bin`` is tagged as directory, and ``ctags`` as program of Automake.\n\n``bin`` is tagged in a callback function assigned to ``newMacroFound`` method.\n``ctags`` is tagged in a callback function assigned to ``valuesFound`` method.\n\n``--extras=+r`` is used in the example. Reference (``r``) extra is needed to\ntag ``bin``. ``bin`` is not defined in the line, ``bin_PROGRAMS =``.\n``bin`` is referenced as a name of directory where programs are\nstored. Therefore ``r`` is needed.\n\nFor tagging ``ctags``, the Automake parser must recognize\n``bin`` in ``bin_PROGRAMS`` first. ``ctags`` is tagged\nbecause it is specified as a value for ``bin_PROGRAMS``.\nAs the result ``r`` is also needed to tag ``ctags``.\n\nOnly Automake related tags are emitted if Make parser is\ndisabled.\n\n.. code-block:: console\n\n\t$ ctags --languages=-Make --fields=+lKr --extras=+r -o - Makefile.am\n\tbin\tMakefile.am\t/^bin_PROGRAMS = ctags$/;\"\tdirectory\tlanguage:Automake\troles:program\n\tctags\tMakefile.am\t/^bin_PROGRAMS = ctags$/;\"\tprogram\tlanguage:Automake\tdirectory:bin\n\nAutoconf/M4 parser combination\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n\nUniversal Ctags uses m4 parser as a base parser and Autoconf parse as\na subparser for ``configure.ac`` input file.\n\n.. code-block:: Autoconf\n\n   AC_DEFUN([PRETTY_VAR_EXPAND],\n\t     [$(eval \"$as_echo_n\" $(eval \"$as_echo_n\" \"${$1}\"))])\n\nThe m4 parser finds no definition here.  However, Autoconf parser finds\n``PRETTY_VAR_EXPAND`` as a macro definition. Syntax like ``(...)`` is part\nof M4 language. So Autoconf parser is implemented as a subparser of\nm4 parser. The most parts of tokens in input files are handled by\nM4. Autoconf parser gives hints for parsing ``configure.ac`` and\nregisters callback functions to\nAutoconf parser.\n"
  },
  {
    "path": "docs/testing-ctags.rst",
    "content": ".. _testing_ctags:\n\n=============================================================================\nTesting ctags\n=============================================================================\n\n.. contents:: `Table of contents`\n\t:depth: 1\n\t:local:\n\n..\ttmain.rst\n\n*Tmain*: a facility for testing main part\n------------------------------------------------------------\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\n----\n\n*Tmain* is introduced to test the area where *Units*\ndoes not cover well.\n\n*Units* works fine for testing parsers. However, it\nassumes something input is given to ctags command,\nand a `tags` file is generated from ctags command.\n\nOther aspects cannot be tested. Such areas are files\nand directories layout after installation, standard\nerror output, exit status, etc.\n\nYou can run test cases with following command line:\n\n::\n\n\t$ make tmain\n\n*Tmain* is still under development so I will not write\nthe details here.\n\n\nTo write a test case, see files under `Tmain/tmain-example.d`.\nIn the example, *Tmain* does:\n\n1. runs new subshell and change the working directory to `Tmain/tmain-example.d`,\n2. runs `run.sh` with `bash`,\n3. captures stdout, stderr and exit status, and\n4. compares them with `stdout-expected.txt`, `stderr-expected.txt`,\n   and `exit-expected.txt`.\n5. compares it with `tags-expected.txt` if run.sh generates `tags` file.\n\n`run.sh` is run with following 3 arguments:\n\n1. the path for the target ctags\n2. the path for `builddir` directory\n3. the path for the target readtags\n\nThe path for readtags is not reliable; readtags command is not\navailable if --disable-readcmd was given in configure time.  A case,\ntesting the behavior of readtags, must verify the command existence\nwith `test -x $3` before going into the main part of the test.\n\nWhen comparing `tags` file with `tags-expected.txt`, you\nmust specify the path of `tags` explicitly with -o option\nin ctags command line like::\n\n\tCTAGS=$1\n\tBUILDDIR=$2\n\t${CTAGS} ... -o $BUILDDIR/tags ...\n\nThis makes it possible to keep the original source directory clean.\n\nSee also `tmain_run` and `tmain_compare` functions in `misc/units`.\n\nIf run.sh exits with code 77, the test case is skipped.\nThe output to stdout is captured and printed as the reason\nof skipping.\n\nTODO\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* Run under valgrind\n\n..\ttinst.rst\n\n*Tinst*: installation test\n---------------------------------------------------------------------\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\n-----\n\ntinst target is for testing the result of ``make install``.\n\n::\n\n   $ make tinst\n\nFussy syntax checking\n------------------------------------------------------------\nIf ``-Wall`` of gcc is not enough, you may be interested in this.\n\nYou can change C compiler warning options with 'WARNING_CFLAGS'\nconfigure arg-var option.\n\n::\n\n   $ ./configure WARNING_CFLAGS='-Wall -Wextra'\n\n\nIf configure option '--with-sparse-cgcc' is specified,\ncgcc is used as CC. cgcc is part of `Sparse, Semantic Parser for C\n<https://sparse.docs.kernel.org/en/latest/>`_.\nIt is used in development of Linux kernel for finding programming error.\ncgcc acts as a c compiler but more fussy. '-Wsparse-all' is used as\ndefault option passed to cgcc but you can change with 'CGCC_CFLAGS'\nconfigure arg-var option.\n\n::\n\n   $ ./configure --with-sparse-cgcc [CGCC_CFLAGS='-Wsparse-all']\n\n\nFinding performance bottleneck\n------------------------------------------------------------\n\nSee `Profiling with gperftools\n<https://wiki.geany.org/howtos/profiling/gperftools>`_ and `#383\n<https://github.com/universal-ctags/ctags/issues/383>`_.\n\nSee also `codebase <https://github.com/universal-ctags/codebase>`_.\n\nChecking coverage\n------------------------------------------------------------\nBefore starting coverage measuring, you need to specify\n'--enable-coverage-gcov' configure option.\n\n::\n\n   $ ./configure --enable-coverage-gcov\n\n\nAfter doing ``make clean``, you can build coverage measuring ready\nctags by ``make``. At this time *\\*.gcno* files are generated\nby the compiler. *\\*.gcno* files can be removed with ``make clean``.\n\nAfter building ctags, you can run run-gcov target.  When running\n*\\*.gcda* files.  The target runs ctags with all input files under\n*Units/\\*\\*/input.\\**; and call ``gcov``. Human readable result is\nprinted. The detail can be shown in *\\*.gcov* files. *\\*.gcda* files\nand *\\*.gcov* files can be removed with ``make clean-gcov``.\n\nRunning cppcheck\n------------------------------------------------------------\n\n.. NOT REVIEWED YET\n\n`cppcheck <http://cppcheck.sourceforge.net/>`_ is a tool for static C/C++ code\nanalysis.\n\nTo run it do as following after install cppcheck::\n\n   $ make cppcheck\n"
  },
  {
    "path": "docs/testing-parser.rst",
    "content": ".. _testing_parser:\n\n=============================================================================\nTesting a parser\n=============================================================================\n\n\n.. contents:: `Table of contents`\n\t:depth: 3\n\t:local:\n\nIt is difficult for us to know syntax of all languages supported in ctags. Test\nfacility and test cases are quite important for maintaining ctags with limited\nresources.\n\n..\t_units:\n\n*Units* test facility\n---------------------------------------------------------------------\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\n----\n\n**Test facility**\n\nExuberant Ctags has a test facility. The test case were *Test*\ndirectory. So Here I call it *Test*.\n\nMain aim of the facility is detecting regression. All files under Test\ndirectory are given as input for old and new version of ctags\ncommands.  The output tags files of both versions are compared. If any\ndifference is found the check fails. *Test* expects the older ctags\nbinary to be correct.\n\nThis expectation is not always met. Consider that a parser for a new\nlanguage is added. You may want to add a sample source code for that\nlanguage to *Test*. An older ctags version is unable to generate a\ntags file for that sample code, but the newer ctags version does. At\nthis point a difference is found and *Test* reports failure.\n\n**Units facility**\n\nThe units test facility (*Units*) I describe here takes a different\napproach. An input file and an expected output file are given by a\ncontributor of a language parser. The units test facility runs ctags\ncommand with the input file and compares its output and the expected\noutput file. The expected output doesn't depend on ctags.\n\nIf a contributor sends a patch which may improve a language parser,\nand if a reviewer is not familiar with that language, s/he cannot\nevaluate it.\n\n*Unit* test files, the pair of input file and expected output file may\nbe able to explain the intent of patch well; and may help the\nreviewer.\n\nHow to write a test case\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe test facility recognizes an input file and an expected\noutput file by patterns of file name. Each test case should\nhave its own directory under Units directory.\n\n*Units/TEST/input.\\** **requisite**\n\n\tInput file name must have a *input* as basename. *TEST*\n\tpart should explain the test case well.\n\n*Units/TEST/input[-_][0-9].\\** *Units/TEST/input[-_][0-9][-_]\\*.\\** **optional**\n\n\tOptional input file names. They are put next to *input.\\** in\n\ttesting command line.\n\n*Units/TEST/expected.tags* **optional**\n\n\tExpected output file must have a name *expected.tags*. It\n\tshould be the same directory of the input file.\n\n\tIf this file is not given, the exit status of ctags process\n\tis just checked; the output is ignored.\n\n\tIf you want to test etags output (specified with ``-e`` ),\n\tUse **.tags-e** as suffix instead of **.tags**.\n\tIn such a case you don't have to write ``-e`` to ``args.ctags``.\n\tThe test facility sets ``-e`` automatically.\n\n\tIf you want to test cross reference output (specified with ``-x`` ),\n\tUse **.tags-x** as suffix instead of **.tags**.\n\tIn such a case you don't have to write ``-x`` to ``args.ctags``.\n\tThe test facility sets ``-x`` automatically.\n\n\tIf you want to test json output (specified with ``--output-format=json`` ),\n\tUse **.tags-json** as suffix instead of **.tags**.\n\tIn such a case you don't have to write ``--output-format=json`` to ``args.ctags``,\n\tand add ``json`` to ``features`` as described below.\n\tThe test facility sets the option and the feature automatically.\n\n*Units/TEST/args.ctags* **optional**\n\n\t``-o -`` is used as default optional argument when running a\n\tunit test ctags. If you want to add more options, enumerate\n\toptions in **args.ctags** file.\n\n\tRemember you have to put one option in one line; don't\n\tput multiple options to one line. Multiple options in\n\tone line doesn't work.\n\n*Units/TEST/filter* **optional**\n\n\tYou can rearrange the output of ctags with this command\n\tbefore comparing with *executed.tags*.\n\tThis command is invoked with no argument. The output\n\tctags is given via stdin. Rearrange data should be\n\twritten to stdout.\n\n*Units/TEST/features* **optional**\n\n\tIf a unit test case requires special features of ctags,\n\tenumerate them in this file line by line. If a target ctags\n\tdoesn't have one of the features, the test is skipped.\n\n\tIf a file line is started with ``!``, the effect is inverted;\n\tif a target ctags has the feature specified with ``!``, the\n\ttest is skipped.\n\n\tAll features built-in can be listed with passing\n\t``--list-features`` to ctags.\n\n*Units/TEST/languages* **optional**\n\n\tIf a unit test case requires that language parsers are enabled/available,\n\tenumerate them in this file line by line. If one of them is\n\tdisabled/unavailable, the test is skipped.\n\n\tlanguage parsers enabled/available can be checked with passing\n\t``--list-languages`` to ctags.\n\nNote for importing a test case from Test directory\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nI think all test cases under Test directory should be converted to\nUnits.\n\nIf you convert use following TEST name convention.\n\n* use *.t* instead of *.d* as suffix for the name\n\nHere is an example::\n\n\tTest/simple.sh\n\nThis should be::\n\n\tUnits/simple.sh.t\n\nWith this name convention we can track which test case is converted or\nnot.\n\nExample of files\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSee `Units/parser-c.r/c-sample.d\n<https://github.com/universal-ctags/ctags/tree/master/Units/parser-c.r/c-sample.d>`_.\n\nHow to run unit tests\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n*test* make target::\n\n\t $ make units\n\nThe result of unit tests is reported by lines. You can specify\ntest cases with ``UNITS=``.\n\nAn example to run *vim-command.d* only::\n\n\t$ make units UNITS=vim-command\n\nAnother example to run *vim-command.d* and *parser-python.r/bug1856363.py.d*::\n\n\t$ make units UNITS=vim-command,bug1856363.py\n\nDuring testing *OUTPUT.tmp*, *EXPECTED.tmp* and *DIFF.tmp* files are\ngenerated for each test case directory. These are removed when the\nunit test is **passed**.  If the result is **FAILED**, it is kept for\ndebugging. Following command line can clean up these generated files\nat once::\n\n\t$ make clean-units\n\nOther than **FAILED** and **passed** two types of result are\ndefined.\n\n\n**skipped**\n\n\tmeans running the test case is skipped in some reason.\n\n**failed (KNOWN bug)**\n\n\tmeans the result was failed but the failure is expected.\n\tSee \":ref:`gathering_test`\".\n\nExample of running\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n\t$ make units\n\tCategory: ROOT\n\t-------------------------------------------------------------------------\n\tTesting 1795612.js as JavaScript                            passed\n\tTesting 1850914.js as JavaScript                            passed\n\tTesting 1878155.js as JavaScript                            passed\n\tTesting 1880687.js as JavaScript                            passed\n\tTesting 2023624.js as JavaScript                            passed\n\tTesting 3184782.sql as SQL                                  passed\n\t...\n\nRunning unit tests for specific languages\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can run only the tests for specific languages by setting\n``LANGUAGES`` to parsers as reported by\n``ctags --list-languages``::\n\n\tmake units LANGUAGES=PHP,C\n\nMultiple languages can be selected using a comma separated list.\n\n.. _gathering_test:\n\nGathering test cases for known bugs\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWhen we meet a bug, it is an important development activity to make a small test\ncase that triggers the bug.\nEven the bug cannot be fixed in soon,\nthe test case is an important result of work. Such result should\nbe merged to the source tree. However, we don't love **FAILED**\nmessage, too. What we should do?\n\nIn such a case, merge as usually but use *.b* as suffix for\nthe directory of test case instead of *.d*.\n\n``parser-autoconf.r/nested-block.ac.b/`` is an example\nof ``.b``*`` suffix usage.\n\nWhen you run test.units target, you will see::\n\n    Testing c-sample as C                                 passed\n    Testing css-singlequote-in-comment as CSS             failed (KNOWN bug)\n    Testing ctags-simple as ctags                         passed\n\nSuffix *.i* is a variant of *.b*. *.i* is for merging/gathering input\nwhich lets ctags process enter an infinite loop. Different from *.b*,\ntest cases marked as *.i* are never executed. They are just skipped\nbut reported the skips::\n\n    Testing ada-ads as Ada                                passed\n    Testing ada-function as Ada                           skipped (may cause an infinite loop)\n    Testing ada-protected as Ada                          passed\n    ...\n\n    Summary (see CMDLINE.tmp to reproduce without test harness)\n    ------------------------------------------------------------\n      #passed:                                347\n      #FIXED:                                 0\n      #FAILED (unexpected-exit-status):       0\n      #FAILED (unexpected-output):            0\n      #skipped (features):                    0\n      #skipped (languages):                   0\n      #skipped (infinite-loop):               1\n        ada-protected\n      ...\n\nRunning under valgrind and timeout\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nIf ``VG=1`` is given, each test cases are run under valgrind.\nIf valgrind detects an error, it is reported as::\n\n    $ make units VG=1\n    Testing css-singlequote-in-comment as CSS             failed (valgrind-error)\n    ...\n    Summary (see CMDLINE.tmp to reproduce without test harness)\n    ------------------------------------------------------------\n    ...\n    #valgrind-error:                        1\n      css-singlequote-in-comment\n    ...\n\nIn this case the report of valgrind is recorded to\n``Units/css-singlequote-in-comment/VALGRIND-CSS.tmp``.\n\nNOTE: ``/bin/bash`` is needed to report the result. You can specify a shell\nrunning test with SHELL macro like::\n\n    $ make units VG=1 SHELL=/bin/bash\n\n\nIf ``TIMEOUT=N`` is given, each test cases are run under timeout\ncommand. If ctags doesn't stop in ``N`` second, it is stopped\nby timeout command and reported as::\n\n    $ make units TIMEOUT=1\n    Testing css-singlequote-in-comment as CSS             failed (TIMED OUT)\n    ...\n    Summary (see CMDLINE.tmp to reproduce without test harness)\n    ------------------------------------------------------------\n    ...\n    #TIMED-OUT:                             1\n      css-singlequote-in-comment\n    ...\n\nIf ``TIMEOUT=N`` is given, *.i* test cases are run. They will be\nreported as *TIMED-OUT*.\n\nCategories\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. NOT REVIEWED\n\nWith *.r* suffix, you can put test cases under a sub directory\nof *Units*. ``Units/parser-ada.r`` is an example. If *misc/units*\ntest harness, the sub directory is called a category. ``parser-ada.r``\nis the name category in the above example.\n\n*CATEGORIES* macro of make is for running units in specified categories.\nFollowing command line is for running units in\n``Units/parser-sh.r`` and ``Units/parser-ada.r``::\n\n  $ make units CATEGORIES='parser-sh,parser-ada'\n\n\nFinding minimal bad input\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWhen a test case is failed, the input causing ``FAILED`` result is\npassed to *misc/units shrink*.  *misc/units shrink* tries to make the\nshortest input which makes ctags exits with non-zero status.  The\nresult is reported to ``Units/\\*/SHRINK-${language}.tmp``.  Maybe\nuseful to debug.\n\nAcknowledgments\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe file name rule is suggested by Maxime Coste <frrrwww@gmail.com>.\n\nReviewing the result of Units test\n------------------------------------------------------------\n\nTry misc/review.\n\n.. code-block:: console\n\n    $ misc/review --help\n    Usage:\n            misc/review          help|--help|-h                 show this message\n            misc/review          [list] [-b]                    list failed Units and Tmain\n                                 -b                             list .b (known bug) marked cases\n            misc/review          inspect [-b]                   inspect difference interactively\n                                 -b                             inspect .b (known bug) marked cases\n    $\n\nSemi-fuzz(*Fuzz*) testing\n---------------------------------------------------------------------\n\nUnexpected input can lead ctags to enter an infinite loop. The fuzz\ntarget tries to identify these conditions by passing\nsemi-random (semi-broken) input to ctags.\n\n::\n\n\t$ make fuzz LANGUAGES=LANG1[,LANG2,...]\n\nWith this command line, ctags is run for random variations of all test\ninputs under *Units/\\*/input.\\** of languages defined by ``LANGUAGES``\nmacro variable. In this target, the output of ctags is ignored and\nonly the exit status is analyzed. The ctags binary is also run under\ntimeout command, such that if an infinite loop is found it will exit\nwith a non-zero status. The timeout will be reported as following::\n\n\t[timeout C]                Units/test.vhd.t/input.vhd\n\nThis means that if C parser doesn't stop within N seconds when\n*Units/test.vhd.t/input.vhd* is given as an input, timeout will\ninterrupt ctags. The default duration can be changed using\n``TIMEOUT=N`` argument in *make* command. If there is no timeout but\nthe exit status is non-zero, the target reports it as following::\n\n\t[unexpected-status(N) C]                Units/test.vhd.t/input.vhd\n\nThe list of parsers which can be used as a value for ``LANGUAGES`` can\nbe obtained with following command line\n\n::\n\n\t$ ctags --list-languages\n\nBesides ``LANGUAGES`` and ``TIMEOUT``, fuzz target also takes the\nfollowing parameters:\n\n\t``VG=1``\n\n\t\tRun ctags under valgrind. If valgrind finds a memory\n\t\terror it is reported as::\n\n\t\t\t[valgrind-error Verilog]                Units/array_spec.f90.t/input.f90\n\n\t\tThe valgrind report is recorded at\n\t\t``Units/\\*/VALGRIND-${language}.tmp``.\n\nAs the same as units target, this semi-fuzz test target also calls\n*misc/units shrink* when a test case is failed. See \"*Units* test facility\"\nabout the shrunk result.\n\n*Noise* testing\n---------------------------------------------------------------------\n\nAfter enjoying developing Semi-fuzz testing, I'm looking for a more unfair\napproach. Run\n\n::\n\n\t$ make noise LANGUAGES=LANG1[,LANG2,...]\n\nThe noise target generates test cases by inserting or deleting one\ncharacter to the test cases of *Units*.\n\nIt takes a long time, even without ``VG=1``, so this cannot be run\nunder Travis CI. However, it is a good idea to run it locally.\n\n*Chop* and *slap* testing\n---------------------------------------------------------------------\n\nAfter reviving many bug reports, we recognized some of them spot\nunexpected EOF. The chop target was developed based on this recognition.\n\nThe chop target generates many input files from an existing input file\nunder *Units* by truncating the existing input file at variety file\npositions.\n\n::\n\n   $ make chop  LANGUAGES=LANG1[,LANG2,...]\n\nIt takes a long time, especially with ``VG=1``, so this cannot be run\nunder Travis CI. However, it is a good idea to run it locally.\n\nslap target is derived from chop target. While chop target truncates\nthe existing input files from tail, the slap target does the same\nfrom head.\n\n..\t_input-validation:\n\nInput validation for *Units*\n---------------------------------------------------------------------\n\nWe have to maintain parsers for languages that we don't know well.  We\ndon't have enough time to learn the languages.\n\n*Units* test cases help us not introduce wrong changes to a parser.\n\nHowever, there is still an issue; a developer who doesn't know a\ntarget language well may write a broken test input file for the\nlanguage.  Here comes \"Input validation.\"\n\nHow to run an example session of input validation\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can validate the test input files of *Units* with *validate-input*\nmake target if a validator or a language is defined.\n\nHere is an example validating an input file for JSON.\n\n.. code-block:: console\n\n  $ make validate-input VALIDATORS=jq\n  ...\n  Category: parser-json.r\n  ------------------------------------------------------------\n  simple-json.d/input.json with jq                                 valid\n\n  Summary\n  ------------------------------------------------------------\n    #valid:                                 1\n    #invalid:                               0\n    #skipped (known invalidation)           0\n    #skipped (validator unavailable)        0\n\n\nThis example shows validating *simple-json.d/input.json* as an input\nfile with *jq* validator. With VALIDATORS variable passed via\ncommand-line, you can specify validators to run. Multiple validators\ncan be specified using a comma-separated list.  If you don't give\nVALIDATORS, the make target tries to use all available validators.\n\nThe meanings of \"valid\" and \"invalid\" in \"Summary\" are apparent.  In\ntwo cases, the target skips validating input files:\n\n#skipped (known invalidation)\n\n    A test case specifies KNOWN-INVALIDATION in its *validator* file.\n\n#skipped (validator unavailable)\n\n    A command for a validator is not available.\n\n*validate-input* make target supports the CATEGORIES variable as *units* make target does.\n\n.. code-block:: console\n\n  $ make validate-input units CATEGORIES=parser-json.r\n  ...\n\nThis example shows validating input files and running units test on *parser-json.r* category.\n\n*validator* file\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n*validator* file in a *Units* test directory specifies which\nvalidator the make target should use.\n\n.. code-block:: console\n\n  $ cat Units/simple-json.d/validator\n  jq\n\nIf you put *validator* file to a category directory (a directory\nhaving *.r* suffix), the make target uses the validator specified in\nthe file as default.  The default validator can be overridden with a\n*validator* file in a subdirectory.\n\n.. code-block:: console\n\n  $ cat Units/parser-puppetManifest.r/validator\n  puppet\n  # cat Units/parser-puppetManifest.r/puppet-append.d/validator\n  KNOWN-INVALIDATION\n\nIn the example, the make target uses *puppet* validator for validating\nthe most of all input files under *Units/parser-puppetManifest.r*\ndirectory. An exception is an input file under\n*Units/parser-puppetManifest.r/puppet-append.d* directory.  The\ndirectory has its specific *validator* file.\n\nIf a *Unit* test case doesn't have *expected.tags* file, the make\ntarget doesn't run the validator on the file even if a default\nvalidator is given in its category directory.\n\nIf a *Unit* test case specifies NONE in its *validator* file,\nthe make target doesn't run the validator, either.\n\nIf a *Unit* test case specifies KNOWN-INVALIDATION in its *validator*\nfile, the make target just increments \"#skipped (known invalidation)\"\ncounter. The target reports the counter at the end of execution.\n\nvalidator command\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA validator specified in a *validator* file is a command file put\nunder *misc/validators* directory.  The command must have \"validator-\"\nas prefix in its file name. For an example,\n*misc/validators/validator-jq* is the command for \"jq\".\n\nThe command file must be an executable. *validate-input* make target\nruns the command in two ways.\n\n*is_runnable* method\n\n    Before running the command as a validator, the target runs\n    the command with \"is_runnable\" as the first argument.\n    A validator command can let the target know whether the\n    validator command is runnable or not with exit status.\n    0 means ready to run. Non-zero means not ready to run.\n\n    The make target never runs the validator command for\n    validation purpose if the exit status is non-zero.\n\n    For an example, *misc/validators/validator-jq* command uses *jq*\n    command as its backend. If *jq* command is not available on a\n    system, *validator-jq* can do nothing.  If such case,\n    *is_runnable* method of *validator-jq* command should exit with\n    non-zero value.\n\n    The second argument is dummy. Don't use it. The third argument\n    is the directory (*misc/validators*) where the command is.\n\n*validate* method\n\n    The make target runs the command with \"validate\", an input\n    file name for validating the input file, and the directory\n    (*misc/validators*) where the command is. The command exits\n    non-zero if the input file contains invalid syntax. This method\n    will never run if *is_runnable* method of the command exits with\n    non-zero.\n\n\n..\t_man_test:\n\nTesting examples in language specific man pages\n---------------------------------------------------------------------\n\n:Maintainer: Masatake YAMATO <yamato@redhat.com>\n\n----\n\n`man-test` is a target for testing the examples in the language\nspecific man pages (``man/ctags-lang-<LANG>.7.rst.in``). The command\nline for running the target is:\n\n.. code-block:: console\n\n   $ make man-test\n\nAn example for testing must have following form:\n\n.. code-block:: ReStructuredText\n\n  \"input.<EXT>\"\n\n  .. code-block:: <LANG>\n\n    <INPUT LINES>\n\n  \"output.tags\"\n  with \"<OPTIONS FOR CTAGS>\"\n\n  .. code-block:: tags\n\n    <TAGS OUTPUT LINES>\n\n\nThe man-test target recognizes the form and does the same as\nthe following shell code for each example in the man page:\n\n.. code-block:: console\n\n  $ echo <INPUT LINES> > input.<EXT>\n  $ echo <TAGS OUTPUT LINES> > output.tags\n  $ ctags <OPTIONS FOR CTAGS> > actual.tags\n  $ diff output.tags actual.tags\n\nA backslash character at the end of ``<INPUT LINES>`` or\n``<TAGS OUTPUT LINES>`` represents the continuation of lines;\na subsequent newline is ignored.\n\n.. code-block:: ReStructuredText\n\n    .. code-block:: tags\n\n       very long\\\n            line\n\nis read as:\n\n.. code-block:: ReStructuredText\n\n    .. code-block:: tags\n\n       very long     line\n\nHere is an example of a test case taken from\n``ctags-lang-python.7.rst.in``:\n\n.. code-block:: ReStructuredText\n\n\t\"input.py\"\n\n\t.. code-block:: Python\n\n\t   import X0\n\n\t\"output.tags\"\n\twith \"--options=NONE -o - --extras=+r --fields=+rzK input.py\"\n\n\t.. code-block:: tags\n\n\t\tX0\tinput.py\t/^import X0$/;\"\tkind:module\troles:imported\n\n``make man-test`` returns 0 if the all test cases in the all language\nspecific man pages are passed.\n\nHere is an example output of the man-test target.\n\n.. code-block:: console\n\n\t$ make man-test\n\t  RUN      man-test\n\t# Run test cases in ./man/ctags-lang-julia.7.rst.in\n\t```\n\t./man/ctags-lang-julia.7.rst.in[0]:75...passed\n\t./man/ctags-lang-julia.7.rst.in[1]:93...passed\n\t```\n\t# Run test cases in ./man/ctags-lang-python.7.rst.in\n\t```\n\t./man/ctags-lang-python.7.rst.in[0]:116...passed\n\t./man/ctags-lang-python.7.rst.in[1]:133...passed\n\t./man/ctags-lang-python.7.rst.in[2]:154...passed\n\t./man/ctags-lang-python.7.rst.in[3]:170...passed\n\t./man/ctags-lang-python.7.rst.in[4]:187...passed\n\t./man/ctags-lang-python.7.rst.in[5]:230...passed\n\t```\n\t# Run test cases in ./man/ctags-lang-verilog.7.rst.in\n\t```\n\t./man/ctags-lang-verilog.7.rst.in[0]:51...passed\n\t```\n\tOK\n\nNOTE: keep examples in the man pages simple. If you want to test ctags\ncomplicated (and or subtle) input, use the units target. The main\npurpose of the examples is for explaining the parser.\n\nIf your parser depends on a feature, listed in ``\"ctags\n--list-features\"``, and the ctags executable at the platform doesn't\nhave the feature, the man-test for the parser should be skipped.\n\n``:Expected feature: FEAT`` is the notation for declaring a feature\nthat needs to run the man-test for the parser. Here is an example:\n\n.. code-block:: ReStructuredText\n\n\t.. _ctags-lang-i18nrubgem(7):\n\n\t==============================================================\n\tctags-lang-i18nrubgem\n\t==============================================================\n\t------------------------------------------------------------------------\n\tRandom notes about tagging input for I18n Ruby Gem with Universal Ctags\n\t------------------------------------------------------------------------\n\t:Version: @VERSION@\n\t:Manual group: Universal Ctags\n\t:Manual section: 7\n\t:Expected feature: yaml\n\nAt the last line, ``yaml`` feature is declared.\n"
  },
  {
    "path": "docs/testing-readtags.rst",
    "content": ".. _testing_readtags:\n\n=============================================================================\nTesting readtags\n=============================================================================\n\n*roundtrip* target verifies the behavior of readtags command.  It\nreuses `expected.tags` files under Units as input files for readtags.\nAll tags in all `expected.tags` files are searched with readtags.  If a\ntag cannot be found with readtags, the roundtrip target reports the readtags\ncommand line that specifies the tag and the path for `expected.tags` file.\n\nExample of running the target\n\n.. code-block:: console\n\n    $ make roundtrip\n    FAILED: ./readtags -t Units/sh-statements.d/expected.tags -starting-with-dash\n    FAILED: ./readtags -t Units/sh-statements.d/expected.tags -starting-with-dash_2\n    FAILED: ./readtags -t Units/sh-statements.d/expected.tags -starting-with-dash_inner\n    FAILED: ./readtags -t Units/parser-c.r/backslash-at-the-end-of-pattern.d/expected.tags M\n    FAILED: ./readtags -t Units/simple-diff.d/expected.tags -0,0\n    FAILED: ./readtags -t Units/simple-diff.d/expected.tags -1,2\n    FAILED: ./readtags -t Units/simple-diff.d/expected.tags -28,6\n    FAILED: ./readtags -t Units/simple-diff.d/expected.tags -44,6\n    FAILED: ./readtags -t Units/review-needed.r/3526726.tex.t/expected.tags -r\n\t...\n    Makefile:498: recipe for target 'roundtrip' failed\n    make: *** [roundtrip] Error 1\n\n\nOn CI/CD environments, the target uses only marked `expected.tags`\nfiles instead of using all the `expected.tags` files because the\nroundtrip target took too long time.\n\nAn empty file named `minitrip` acts as the marker. Before processing\nan `expected.tags`, the target looks for `minitrip` file at the\ndirectory where `expected.tags` is. If it finds `minitrip` file, the\ntarget processes the `expected.tags`. If not, the target ignores the\n`expected.tags`.\n"
  },
  {
    "path": "docs/tracking.rst",
    "content": ":orphan:\n\nTracking other projects\n----------------------------------------------------------------------\n\nThis is working note for tracking activities other projects,\nespecially activity at Exuberant Ctags.\n\nI(Masatake YAMATO) consider tracking activities as the first class\nfruits of this project.\n\n\nExuberant Ctags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nsubversion\n......................................................................\n\n* status\n\n  Revisions up to <r815> are merged except:\n\n\tNOTHING HERE NOW\n\n  (Mon Sep 22 12:41:32 2014 by yamato)\n\n* howto\n\n  ::\n\n      <svn>\n      => <git: local Universal Ctags repo>\n      => <git: local Universal Ctags repo>\n\n\n  1. prepare your own Universal Ctags repo: a local git repo cloned from github.\n     You may know how to do it :)\n\n     ::\n\n\t$ git clone https://github.com/universal-ctags/ctags.git\n\n  2. prepare Exuberant Ctags SVN repo: a local git repo clone from Exuberant Ctags svn tree.\n\n    The original clone is already part of Exuberant Ctags tree.\n\n    To initialize your git repository with the required subversion information do ::\n\n\t$ git svn init https://svn.code.sf.net/p/ctags/code/trunk\n\t$ git update-ref refs/remotes/git-svn refs/remotes/origin/sourceforge\n\n    and then ::\n\n\t$ git svn fetch\n\t$ git svn rebase\n\n    to get the latest changes and reflect it to the local copy.\n\n  3. merge\n\n    TODO\n\n  4. cherry-pick\n\n     4.1. Make a branch at local Universal Ctags repo and switch to it.\n\n     4.2. Do cherry-pick like::\n\n\t \t$ git cherry-pick -s -x c81a8ce\n\n     You can find commit id on the another terminal\n     <git: local Universal Ctags repo>::\n\n\t \t$ git log\n\n     or ::\n\n\t \t$ git log --oneline\n\n     If conflicts are occurred in cherry-picking, you can\n     abort/reset cherry-picking with::\n\n\t $ git reset --hard\n\n     <git: local Universal Ctags repo>\n      at the branch for picking.\n\nbugs\n......................................................................\n   <367>  C++11 override makes a C++ member function declaration ignored\n\n\t * fixed in::\n\n\t        d4fcbdd\n\t\t#413\n\t\t#405\n\n   <366>  --options=.ctags doesn't work under Windows\n\n\t * fixed in::\n\n\t        15cedc6c94e95110cc319b5cdad7807caf3db1f4\n\n   <365>  Selecting Python kinds is broken\n\n\t* fixed in::\n\n\t         4a95e4a55f67230fc4eee91ffb31c18c422df6d3\n\n\t* discussed at #324.\n\n   <364>  Ruby method on self is missing the trailing ? in the generated tag name\n\n\t * fixed in::\n\n\t        d9ba5df9f4d54ddaa511bd5440a1a3decaa2dc28\n\n   <363> Invalid C input file causes invalid read / heap overflow\n\n\t* it is not reproduced.\n\n\t* the test case is imported as parser-c.r/c-heapoverflow-sh-bug-363.d::\n\n   \t\t$ make units UNITS=c-heapoverflow-sh-bug-363 VG=1\n\n   <361> Invalid C input file causes invalid read / heap overflow\n\n\t* it is not reproduced.\n\n   <360> Fails to parse annotation's fields with default value\n\n\t* fixed in::\n\n\t\t682a7f3b180c27c1196f8a1ae662d6e8ad142939\n\n   <358>  Vim parser: Segmentation fault when reading empty vim file\n\n\t * directly contributed by the original author of bug report and patch::\n\n\t   \te0f854f0100e7a3cb8b959a23d6036e43f6b6c85\n\n\t * it is fixed in sf, too::\n\n\t   \t5d774f6022a1af71fa5866994699aafce0253085\n\n   <356> [python] mistakes module level attribute for class level attribute in module level if\n\n\t * fixed in::\n\n\t        ab91e6e1ae84b80870a1e8712fc7f3133e4b5542\n\n   <355> Error when parsing empty file (OCaml)\n\n\t * fixed in::\n\n\t   \t02ec2066b5be6b129eba49685bd0b17fef4acfa\n\n   <341> Lua: \"function f ()\" whitespace\n\n\t * fixed in::\n\n\t   \t8590bbef5fcf70f6747d509808c29bf84342cd0d\n\n   <341> Introducing ctags.conf.d\n\n\t * merged the improved version::\n\n\t   \t216880c5287e0421d9c49898d983144db61c83aa\n\n   <271> regex callback is broken; <320> [PATCH] fix regex callback match count\n\n\t * merged patch (with updated bug number)::\n\n\t\ta12b3a24b62d6535a968e076675f68bac9ad32ba\n\n   <177> Lua: \"function\" results in function tag (includes patch)\n\n\t * fixed in::\n\n\t   \t5606f3f711afeac74587a249650a5f7b416f19be\n\n`patches <https://sourceforge.net/p/ctags/patches/%d>`_\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTracking the tickets in patch tracker is quite fruitful.\nPatches are always there. So it is easy to evaluate the value:)\n\n   [(<]TICKET#[>)] TITLE\n\n\t* STATUS\n\n\t  + MORE STATUS\n\n   <TICKET#>\n\n   \tmeans the ticket is closed from the view of Exuberant Ctags tree\n   \tdevelopers.  We don't have to take time for this ticket.\n\n   (TICKET#)\n\n   \tmeans the ticket is still opened from the view of Exuberant Ctags\n\ttree developers.  We don't have to take time for this ticket.\n\n----\n\n   <85> Add --encoding option to make utf-8 encoded tags file\n\n\t* contributed by the original author::\n\n\t      b3f670c7c4a3c3570b8d2d82756735586aafc0cb\n\n   <84> C++11 new using semantics\n\n\t* solved by another implementation::\n\n\t      c93e3bfa05b70d7fbc2539454c957eb2169e16b3\n\t      502355489b1ba748b1a235641bbd512ba6da315e\n\n   <83> New full non-regex PHP parser\n\n\t* contributed by the original author\n\n   <82> Support for comments in .ctags files\n\n\t* contributed by the original author::\n\n\t  \tcab4735e4f99ce23c52b78dc879bc06af66796fd\n\n   <81> ocaml parser segfaults on invalid files\n\n\t* the bug is not reproduced\n\n   <80> Add support for falcon pl\n\n\t* contributed by the original author\n\n   <74> protobuf parser\n\n\t* Merged after getting approval from the original author\n\n   <67> Objective C language parser\n\n\t* This is the implementation we have in Universal Ctags tree.\n\n   <65> absoluteFilename uses strcpy on overlapping strings\n\n\t* Fixed in Universal Ctags tree, however the ticket is still open::\n\n   \t\td2bdf505abb7569deae2b50305ea1edce6208557\n\n   <64> Fix strcpy() misuse\n\n\t* Fixed in Universal Ctags tree, however the ticket is still open::\n\n\t\td2bdf505abb7569deae2b50305ea1edce6208557\n\n   <55> TTCN-3 support\n\n\t* contributed by the original author\n\n   <51> Ada support\n\n\t* Ada support is now available in Universal Ctags tree::\n\n\t\t4b6b4a72f3d2d4ef969d7c650de1829d79f0ea7c\n\n   <38> Ada support\n\n\t* Ada support is now available in Universal Ctags tree::\n\n\t\t4b6b4a72f3d2d4ef969d7c650de1829d79f0ea7c\n\n   <33> Add basic ObjC support\n\n\t* This one is written in regexp.\n\t* we have better objc parser.\n\n   \\(1\\) bibtex parser\n\n\t* Reject because...\n\n\t  + the owner of the ticket is anonymous.\n\n\t  + the name of patch author is not written explicitly at\n\t    the header of patch.\n\n\t* Alternative\n\n\t  https://gist.github.com/ptrv/4576213\n\n\ndevel mailing list (ctags-devel@sourceforge)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n    <[Ctags] Shebang with python3 instead of python>\n    From: Martin Ueding <dev@ma...> - 2013-01-26 18:36:32\n\n\tAdded python, python2 and python3 as extensions of\n\tpython parser::\n\n\t\tbb81485205c67617f1b34f61341e60b9e8030502\n\n\n    <[Ctags-devel] Lack of fnmatch(3) in Windows>\n    From: Frank Fesevur <ffes@us...> - 2013-08-24 20:25:47\n\n\tThere is no fnmatch() in the Windows C library. Therefore\n\ta string comparison is done in fileNameMatched() in\n\tstrlist.c and patterns are not recognized::\n\n\t\t698bf2f3db692946d2358892d228a864014abc4b\n\n\n    <Re: [Ctags-devel] WindRes parser>\n    From: Frank Fesevur <ffes@unns...> - 2013-08-30 21:23:50\n\n\tA parser for Windows Resource files.\n\thttps://en.wikipedia.org/wiki/Resource_%28Windows%29\n\n\t::\n\n\t \t95b4806ba6c006e4b7e72a006700e33c720ab9e7\n\n\n    ([Ctags-devel] Skip repeat PATH_SEPARATORs in relativeFilename())\n    From: Seth Dickson <whefxlr@gm...> - 2013-12-24 04:51:01\n\n\tLooks interesting.\n\n\nFedora\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSome patches are maintained in ctags package of Fedora.\nInventory of patches are\nhttp://pkgs.fedoraproject.org/cgit/ctags.git/tree/ctags.spec\n\n<ctags-5.7-destdir.patch>\n\n\tThis patch was merged in Universal Ctags git tree::\n\n\t\td4b5972427a46cbdcbfb050a944cf62b300676be\n\n<ctags-5.7-segment-fault.patch>\n\n\tThis patch was merged in Universal Ctags git tree::\n\n\t\t8cc2b482f6c7257c5151893a6d02b8c79851fedd\n\n(ctags-5.8-cssparse.patch)\n\n\tNot in Universal Ctags tree.\n\n\tThe reproducer is attached to the following page:\n\thttps://bugzilla.redhat.com/show_bug.cgi?id=852101\n\n\tHowever, Universal Ctags doesn't reproduce with it.\n\n\tI, Masatake YAMATO, read the patch.  However, I don't\n\tunderstand the patch.\n\n<ctags-5.8-css.patch>\n\n\tThis patch was merged in Universal Ctags git tree::\n\n\t\t80c1522a36df3ba52b8b7cd7f5c79d5c30437a63\n\n<ctags-5.8-memmove.patch>\n\n\tThis patch was merged in Exuberant Ctags svn tree.\n\tAs the result this patch is in Universal Ctags tree::\n\n\t\td2bdf505abb7569deae2b50305ea1edce6208557\n\n<ctags-5.8-ocaml-crash.patch>\n\n\tThis patch was merged in Exuberant Ctags svn tree.\n\tAs the result this patch is in Universal Ctags tree::\n\n\t\tddb29762b37d60a875252dcc401de0b7479527b1\n\n<ctags-5.8-format-security.patch>\n\n\tThis patch was merged in Exuberant Ctags svn tree.\n\tAs the result this patch is in Universal Ctags tree::\n\n\t\t2f7a78ce21e4156ec3e63c821827cf1d5680ace8\n\nDebian\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSome patches are maintained in ctags package of Debian.\nInventory of patches are\nhttp://anonscm.debian.org/cgit/users/cjwatson/exuberant-ctags.git/tree/debian/patches/series\n\n<python-disable-imports.patch>\n\n\tUniversal Ctags tags Y in `import X as Y` and Z in `from X import Y as Z`\n\tas definition tags. They are turned on by default.\n\tThe others are tagged as reference tags. reference tags are recorded only\n\twhen \"r\" extra tags are enabled. e.g. `--extras=+r`.\n\n<vim-command-loop.patch>\n\n\tThis patch was merged as an alternative for\n\t7fb36a2f4690374526e9e7ef4f1e24800b6914ec\n\n\tDiscussed on https://github.com/fishman/ctags/issues/74\n\n\t::\n\n\t   \te59325a576e38bc63b91abb05a5a22d2cef25ab7\n"
  },
  {
    "path": "docs/windows.rst",
    "content": "Building/hacking/using on MS-Windows\n-----------------------------------------------------------------------------\n\n:Maintainer: Frank Fesevur <ffes@users.sourceforge.net>\n\n----\n\nThis part of the documentation is written by Frank Fesevur, co-maintainer of Universal Ctags and the maintainer of the Windows port of this project. It is still very much a work in progress. Things still need to be written down, tested or even investigated. When building for Windows you should be aware that there are many compilers and build environments available. This is a summary of available options and things that have been tested so far.\n\n\nCompilers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere are many compilers for Windows. Compilers not mentioned here may work but are not tested.\n\n\nMicrosoft Visual Studio\n.............................................................................\nhttps://www.visualstudio.com/\n\nMany professional developers targeting Windows use Visual Studio. Visual Studio comes in a couple of different editions. Their Express and Community editions are free to use, but a Microsoft-account is required to download the .iso and when you want to continue using it after a 30-days trial period. Other editions of Visual Studio must be purchased.\n\nInstalling Visual Studio will give you the IDE, the command line compilers and the MS-version of make named nmake.\n\nNote that ctags cannot be built with Visual Studio older than 2013 anymore. There is C99 (or C11) coding used that generates syntax errors with VS2012 and older. This could affect compilers from other vendors as well.\n\n\nGCC\n.............................................................................\n\nYou can use `MinGW-w64 <https://www.mingw-w64.org/>`_ to build ctags. There are several ways to install MinGW-w64 in Windows.\n\n- MSYS2 https://www.msys2.org/\n- MinGW-w64 - for 32 and 64 bit Windows https://sourceforge.net/projects/mingw-w64/\n- TDM-GCC https://jmeubank.github.io/tdm-gcc/\n\nIf you want to build a full-featured version, use MSYS2 (with Autotools). Otherwise, you can also use the other two distributions.\n\n**History**\n\nMinGW started it all, but development stalled for a while and no x64 was available. Then the MinGW-w64 fork emerged. It started as a 64-bit compiler, but soon they included both a 32-bit and a 64-bit compiler. But the name remained, a bit confusing. MinGW-w64 appears to be the most used flavor of MinGW at this moment. Many well known programs that originate from GNU/Linux use MinGW-w64 to compile their Windows port.\n\nBuilding ctags from the command line\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nMicrosoft Visual Studio\n.............................................................................\n\nMicrosoft Visual Studio provides ``Visual Studio Developer Command Prompt`` for command-line enthusiasts.\n\nThere are two ways to setup ``Visual Studio Developer Command Prompt``.\n\nThe first way to setup ``Visual Studio Developer Command Prompt`` is by clicking the ``Windows Start Menu``, details please refer to https://learn.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2019\n\nThe second way to setup ``Visual Studio Developer Command Prompt`` is opening ``Command Prompt`` Application and calling ``vcvarsall.bat`` in current ``Command Prompt``.\n\nThe location of ``vcvarsall.bat`` is various for different Microsoft Visual Studio versions and editions.\n\nFor Microsoft Visual Studio 2022 Enterprise::\n\n        C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Auxiliary\\Build\\vcvarsall.bat\n\nFor Microsoft Visual Studio 2022 Community::\n\n        C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat\n\nFor Microsoft Visual Studio 2019 Enterprise::\n\n        C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC\\Auxiliary\\Build\\vcvarsall.bat\n\nFor Microsoft Visual Studio 2019 Community::\n\n        C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat\n\nFollowing is an example shows you how to use ``vcvarsall.bat`` to setup ``Visual Studio Developer Command Prompt``::\n\n        call \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC\\Auxiliary\\Build\\vcvarsall.bat\" x64\n\nFor more details about ``vcvarsall.bat`` please refer to https://learn.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-160\n\nOnce ``Visual Studio Developer Command Prompt`` is setup, you can build ctags with ``NMake`` or ``MSBuild``.\n\nBuilding ctags with NMake\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThis requires Microsoft Visual Studio 2019 or later.\n\nThe simplest build instructions like below::\n\n        nmake -f mk_mvc.mak\n\nIf you want to build an iconv enabled version, you must specify ``WITH_ICONV=yes`` and ``ICONV_DIR`` like below::\n\n        nmake -f mk_mvc.mak WITH_ICONV=yes ICONV_DIR=path/to/iconvlib\n\nIf you want to build a debug version using ``mk_mvc.mak``, you must specify ``DEBUG=1`` like below::\n\n        nmake -f mk_mvc.mak DEBUG=1\n\nIf you want to create PDB files for debugging even for a release version, you must specify ``PDB=1`` like below::\n\n        nmake -f mk_mvc.mak PDB=1\n\nBuilding ctags with MSBuild\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThis supports only Microsoft Visual Studio 2013.\n\nBefore starting to build, you need to copy some files to proper location::\n\n        copy win32\\config_mvc.h config.h\n        copy win32\\gnulib_h\\langinfo.h gnulib\n        copy win32\\gnulib_h\\fnmatch.h gnulib\n\nThe simplest build instruction like below::\n\n        msbuild win32\\ctags_vs2013.sln\n\nIf you want to build a release version, run command like below::\n\n        msbuild win32\\ctags_vs2013.sln /p:Configuration=Release\n\nMSBuild is what the IDE uses internally and therefore will produce the same files as the IDE.\n\nFor more information about MSBuild, please refer to https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild?view=vs-2019\n\nGCC\n.............................................................................\n\n**General**\n\nAll the GCC's come with installers or with zipped archives. Install or extract them in a directory without spaces.\n\nGNU Make builds for Win32 are available as well, and sometimes are included with the compilers. Make sure it is in your path, for instance by copying the make.exe in the bin directory of your compiler.\n\nNative win32 versions of the GNU/Linux commands cp, rm and mv can be useful. rm is almost always used in by the ``clean`` target of a makefile.\n\n**MSYS2**\n\nFrom mingw.org: MSYS is a collection of GNU utilities such as bash, make, gawk and grep to allow building of applications and programs which depend on traditional UNIX tools to be present. It is intended to supplement MinGW and the deficiencies of the cmd shell.\n\nMSYS2 is a more maintained version of MSYS, but specially geared towards MinGW-w64. You can also use Autotools to build ctags.\nIf you use Autotools you can enable parsers which require jansson, libxml2 or libyaml, and can also do the Units testing with ``make units``.\nIf you don't need such features, you can still build ctags without using Autotools: ``make -f mk_mingw.mak``.\n\nThe following packages are needed to build a full-featured version:\n\n- base-devel (make, autoconf)\n- mingw-w64-{i686,x86_64}-toolchain (mingw-w64-{i686,x86_64}-gcc, mingw-w64-{i686,x86_64}-pkg-config)\n- mingw-w64-{i686,x86_64}-jansson\n- mingw-w64-{i686,x86_64}-libxml2\n- mingw-w64-{i686,x86_64}-libyaml\n- mingw-w64-{i686,x86_64}-xz\n\nIf you want to build a single static-linked binary, you can use the following command:\n\n.. code-block:: bash\n\n        ./autogen.sh\n        ./configure --disable-external-sort --enable-static\n        make\n\n``--disable-external-sort`` is a recommended option for Windows builds.\n\n**Cygwin**\n\nCygwin provides ports of many GNU/Linux tools and a POSIX API layer. This is the most complete way to get the GNU/Linux terminal feel under Windows. Cygwin has a setup that helps you install all the tools you need. One drawback of Cygwin is that it has poor performance.\n\nIt is easy to build a Cygwin version of ctags using the normal GNU/Linux build steps. This ctags.exe will depend on cygwin1.dll and should only be used within the Cygwin ecosystem.\n\nThe following packages are needed to build a full-featured version:\n\n- libiconv-devel\n- libjansson-devel\n- libxml2-devel\n- libyaml-devel\n\nCygwin has packages with a recent version of MinGW-w64 as well. This way it is easy to cross-compile a native Windows application with ``make -f mk_mingw.mak  CC=i686-w64-mingw32-gcc``.\n\nYou can also build a native Windows version using Autotools.\n\n.. code-block:: bash\n\n\t./autogen.sh\n\t./configure --host=i686-w64-mingw32 --disable-external-sort\n\tmake\n\nIf you use Autotools you can also do the Units testing with ``make units``.\n\nSome anti-virus software slows down the build and test process significantly, especially when ``./configure`` is running and during the Units tests. In that case it could help to temporarily disable them. But be aware of the risks when you disable your anti-virus software.\n\n**Cross-compile from GNU/Linux**\n\nAll major distributions have both MinGW and MinGW-w64 packages. Cross-compiling works the same way as with Cygwin. You cannot do the Windows based Units tests on GNU/Linux.\n\n\nBuilding ctags with IDEs\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nI have no idea how things work for the most GNU/Linux developers, but most of Windows developers prefer to use IDE over command prompt, running the debugger from the command line is not a thing a Windows developers would normally do. Many IDEs exist for Windows, I use the two below.\n\nMicrosoft Visual Studio\n.............................................................................\n\nAs already mentioned Microsoft Visual Studio 2013 has the free Express and Community editions. For ctags the Windows Desktop Express Edition is enough to get the job done. The IDE has a proper debugger. Project files for VS2013 can be found in the win32 directory.\n\nPlease know that when files are added to the sources.mak, these files need to be added to the .vcxproj and .vcxproj.filters files as well. The XML of these files should not be a problem.\n\nCode::Blocks\n.............................................................................\nhttp://www.codeblocks.org/\n\nCode::Blocks is a decent GPL-licensed IDE that has good gcc and gdb integration. The TDM-GCC that can be installed together with Code::Blocks works fine and I can provide a project file. This is an easy way to have a free - free as in beer as well as in speech - solution and to have the debugger within the GUI as well.\n\n\nOther differences between Microsoft Windows and GNU/Linux\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere other things where building ctags on Microsoft Windows differs from building on GNU/Linux.\n\n- Filenames on Windows file systems are case-preserving, but not case-sensitive.\n- Windows file systems use backslashes ``\"\\\"`` as path separators, but paths with forward slashes ``\"/\"`` are no problem for a Windows program to recognize, even when a full path (include drive letter) is used.\n- The default line-ending on Windows is CRLF. A tags file generated by the Windows build of ctags will contain CRLF.\n- The tools used to build ctags do understand Unix-line endings without problems. There is no need to convert the line-ending of existing files in the repository.\n- Due to the differences between the GNU/Linux and Windows C runtime library there are some things that need to be added to ctags to make the program as powerful as it is on GNU/Linux. At this moment regex and fnmatch are borrowed from glibc. mkstemp() is taken from MinGW-w64's runtime library. scandir() is taken from `Pacemaker <https://github.com/ClusterLabs/pacemaker/blob/master/replace/scandir.c>`_.\n- Units testing needs a decent ``bash`` shell, some unix-like tools (e.g. ``diff``, ``sed``) and Python 3.5 or later. It is only tested using Cygwin or MSYS2.\n"
  },
  {
    "path": "dsl/dsl.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n/*\n * INCLUDES\n */\n#include \"dsl.h\"\n#include <assert.h>\n#include <errno.h>\n#include <stdlib.h>\n#include <limits.h>\n#include <string.h>\n#include <ctype.h>\n\n/*\n * TYPES\n */\nstruct sDSLCode\n{\n\tEsObject *expr;\n};\n\nstruct sDSLEngine\n{\n\tDSLProcBind *pbinds;\n\tint pbinds_count;\n};\ntypedef struct sDSLEngine DSLEngine;\n\n/*\n * MACROS\n */\n\n/* dummy definition to allow/require an extra semicolon */\n#define END_DEF(sfx) typedef int ctags_dummy_int_type_ignore_me_##sfx\n\n#define DECLARE_VALUE_FN(N)\t\t\t\t\t\t\t\t\t\\\nstatic EsObject* value_##N (EsObject *args, DSLEnv *env)\n\n#define DEFINE_VALUE_FN(N)\t\t\t\t\t\t\t\t\t\\\nstatic EsObject* value_##N (EsObject *args, DSLEnv *env)\t\\\n{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\treturn dsl_entry_##N (env->entry);\t\t\t\t\t\t\\\n} END_DEF(value_##N)\n\n/*\n * FUNCTION DECLARATIONS\n */\n\nstatic EsObject *dsl_eval0 (EsObject *object, DSLEnv *env);\nstatic EsObject *dsl_define (DSLEngineType engine, DSLProcBind *pbind);\n\nstatic EsObject* builtin_null  (EsObject *args, DSLEnv *env);\nstatic EsObject* sform_begin (EsObject *args, DSLEnv *env);\nstatic EsObject* sform_begin0 (EsObject *args, DSLEnv *env);\nstatic EsObject* sfrom_and  (EsObject *args, DSLEnv *env);\nstatic EsObject* sform_or  (EsObject *args, DSLEnv *env);\nstatic EsObject* sform_if  (EsObject *args, DSLEnv *env);\nstatic EsObject* sform_cond  (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_not  (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_eq  (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_lt  (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_gt  (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_le  (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_ge  (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_prefix (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_suffix (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_substr (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_member (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_list (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_downcase (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_upcase (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_tr (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_length (EsObject *args, DSLEnv *env);\nstatic EsObject* bulitin_debug_print (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_entry_ref (EsObject *args, DSLEnv *env);\n\nstatic EsObject* builtin_string_append (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_string2regexp (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_regexp_quote (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_add  (EsObject *args, DSLEnv *env);\nstatic EsObject* builtin_sub  (EsObject *args, DSLEnv *env);\n\nstatic EsObject* value_true (EsObject *args, DSLEnv *env);\nstatic EsObject* value_false (EsObject *args, DSLEnv *env);\nstatic EsObject* value_nil (EsObject *args, DSLEnv *env);\n\nDECLARE_VALUE_FN(name);\nDECLARE_VALUE_FN(input);\nDECLARE_VALUE_FN(pattern);\nDECLARE_VALUE_FN(line);\n\nDECLARE_VALUE_FN(access);\nDECLARE_VALUE_FN(end);\nDECLARE_VALUE_FN(extras);\nDECLARE_VALUE_FN(file);\nDECLARE_VALUE_FN(inherits);\nDECLARE_VALUE_FN(implementation);\nDECLARE_VALUE_FN(kind);\nDECLARE_VALUE_FN(language);\nDECLARE_VALUE_FN(nth);\nDECLARE_VALUE_FN(scope);\nDECLARE_VALUE_FN(scope_kind);\nDECLARE_VALUE_FN(scope_name);\nDECLARE_VALUE_FN(signature);\nDECLARE_VALUE_FN(typeref);\nDECLARE_VALUE_FN(typeref_kind);\nDECLARE_VALUE_FN(typeref_name);\nDECLARE_VALUE_FN(roles);\nDECLARE_VALUE_FN(xpath);\n\nstatic EsObject* macro_string_append (EsObject *args);\nstatic EsObject* macro_string2regexp (EsObject *args);\nstatic EsObject* macro_regexp_quote (EsObject *args);\nstatic EsObject* macro_debug_printX (EsObject *args);\n\n/*\n * DATA DEFINITIONS\n */\nstatic DSLEngine engines [DSL_ENGINE_COUNT];\n\nstatic DSLProcBind pbinds_interanl_pseudo [] = {\n\t{ \"#/PATTERN/\", NULL, NULL, 0, 0,\n\t  .helpstr = \"(#/patter/ <string>) -> <boolean>; regular expression matching\\n\"\n\t  \"(#/patter/ <string> <integer>) -> <string>|\\\"\\\"; extact a group matching to the pattern\\n\"\n\t  \"(#/patter/ <string> <integer> <any:default>) -> <string>|default; ...returning DEFAULT in case of no match\"},\n\t{ \"#/PATTERN/i\", NULL, NULL, 0, 0,\n\t  .helpstr = \"(#/patter/i <string>) -> <boolean>; in case insensitive way\\n\"\n\t  \"(#/patter/i <string> <integer>) -> <string>|\\\"\\\"; extact a group matching to the pattern\\n\"\n\t  \"(#/patter/i <string> <integer> <any:default>) -> <string>|default; ...returning DEFAULT in case of no match\"},\n};\n\nstatic DSLProcBind pbinds [] = {\n\t{ \"null?\",   builtin_null,   NULL, DSL_PATTR_CHECK_ARITY, 1,\n\t  .helpstr = \"(null? <any>) -> <boolean>\" },\n\t{ \"begin\",   sform_begin,  NULL, DSL_PATTR_SELF_EVAL,  0UL,\n\t  .helpstr = \"(begin <any:0> ... <any:n>) -> <any:n>\" },\n\t{ \"begin0\",  sform_begin0, NULL, DSL_PATTR_SELF_EVAL,  0UL,\n\t  .helpstr = \"(begin0 <any:0> ... <any:n>) -> <any:0>\" },\n\t{ \"and\",     sfrom_and,    NULL, DSL_PATTR_SELF_EVAL,\n\t  .helpstr = \"(and <any> ...) -> <boolean>\" },\n\t{ \"or\",      sform_or,     NULL, DSL_PATTR_SELF_EVAL,\n\t  .helpstr = \"(or <any> ...) -> <boolean>\" },\n\t{ \"if\",      sform_if,       NULL, DSL_PATTR_SELF_EVAL|DSL_PATTR_CHECK_ARITY, 3,\n\t  .helpstr = \"(if <any:cond> <any:true> <any:false>) -> <any:true>|<any:false>\" },\n\t{ \"cond\",    sform_cond,     NULL, DSL_PATTR_SELF_EVAL, 0,\n\t  .helpstr = \"(cond (<any:cond0> ... <any:expr0>) ... (<any:condN> ... <any:exprN>)) -> <any:exprI>|false\" } ,\n\t{ \"not\",     builtin_not,    NULL, DSL_PATTR_CHECK_ARITY, 1,\n\t  .helpstr = \"(not <any>) -> <boolean>\" },\n\t{ \"eq?\",     builtin_eq,     NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(eq? <any> <any>) -> <boolean>\" },\n\t{ \"<\",       builtin_lt,     NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(< <integer> <integer>) -> <boolean>\" },\n\t{ \">\",       builtin_gt,     NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(> <integer> <integer>) -> <boolean>\" },\n\t{ \"<=\",      builtin_le,     NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(<= <integer> <integer>) -> <boolean>\" },\n\t{ \">=\",      builtin_ge,     NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(>= <integer> <integer>) -> <boolean>\" },\n\t{ \"prefix?\", builtin_prefix, NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(prefix? <string:target> <string:prefix>) -> <boolean>\" },\n\t{ \"suffix?\", builtin_suffix, NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(suffix? <string:target> <string:suffix>) -> <boolean>\" },\n\t{ \"substr?\", builtin_substr, NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(substr? <string:target> <string:substr>) -> <boolean>\" },\n\t{ \"member\",  builtin_member, NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(member <any> <list>) -> #f|<list>\" },\n\t{ \"list\",    builtin_list, NULL, 0, 0UL,\n\t  .helpstr = \"(list <any> ...) -> (<any> ...)\" },\n\t{ \"downcase\", builtin_downcase, NULL, DSL_PATTR_CHECK_ARITY, 1,\n\t  .helpstr = \"(downcase <string>|<list>) -> <string>|<list>\" },\n\t{ \"upcase\", builtin_upcase, NULL, DSL_PATTR_CHECK_ARITY, 1,\n\t  .helpstr = \"(upcase <string>|<list>) -> <string>|<list>\" },\n\t{ \"tr\",      builtin_tr,     NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(tr <string:target> <string:c0c1>) -> <string>\" },\n\t{ \"length\",  builtin_length, NULL, DSL_PATTR_CHECK_ARITY, 1,\n\t  .helpstr = \"(length <string>) -> <integer>\" },\n\t{ \"+\",               builtin_add,          NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(+ <integer> <integer>) -> <integer>\", },\n\t{ \"-\",               builtin_sub,          NULL, DSL_PATTR_CHECK_ARITY, 2,\n\t  .helpstr = \"(- <integer> <integer>) -> <integer>\", },\n\t{ \"concat\",   builtin_string_append,NULL, 0, 0,\n\t  .helpstr = \"(concat <string> ...) -> <string>; an alias for string-append\",\n\t  .macro = macro_string_append },\n\t{ \"string-append\",   builtin_string_append,NULL, 0, 0,\n\t  .helpstr = \"(string-append <string> ...) -> <string>\",\n\t  .macro = macro_string_append },\n\t{ \"string->regexp\",  builtin_string2regexp,NULL, 0, 0,\n\t  .helpstr = \"((string->regexp <string:pattern>) <string:target>) -> <boolean>\",\n\t  .macro = macro_string2regexp },\n\t{ \"regexp-quote\",    builtin_regexp_quote, NULL, DSL_PATTR_CHECK_ARITY, 1,\n\t  .helpstr = \"(regexp-quote <string>) -> <string>\",\n\t  .macro = macro_regexp_quote },\n\t{ \"print\",   bulitin_debug_print, NULL, DSL_PATTR_CHECK_ARITY, 1,\n\t  .helpstr = \"(print OBJ) -> OBJ\" },\n\t{ \"printX\", NULL, 0, 0,\n\t  .helpstr = \"(printX EXPR) -> EXPR; do the same as `print' but this works before evaluating\",\n\t  .macro = macro_debug_printX },\n\t{ \"true\",    value_true, NULL, 0, 0UL,\n\t  .helpstr = \"-> #t\" },\n\t{ \"false\",    value_false, NULL, 0, 0UL,\n\t  .helpstr = \"-> #f\" },\n\t{ \"nil\",    value_nil, NULL, 0, 0UL,\n\t  .helpstr = \"-> ()\" },\n\t{ \"$\",       builtin_entry_ref, NULL, DSL_PATTR_CHECK_ARITY_OPT, 1,\n\t  .helpstr = \"($ <string:field>) -> <string>|#f\\n\"\n\t  \"($ <string:field> <any:default>) -> <string>|<any:default>\"},\n\t{ \"$name\",           value_name,           NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> <string>\"},\n\t{ \"$input\",          value_input,          NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> <string>; input file name\" },\n\t{ \"$pattern\",        value_pattern,        NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"$line\",           value_line,           NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<integer>\" },\n\t{ \"$access\",         value_access,         NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\" },\n\t{ \"$end\",            value_end,            NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<integer>\"},\n\t{ \"$extras\",         value_extras,         NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"$file\",           value_file,           NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> <boolean>; whether the scope is limited in the file or not.\" },\n\t{ \"$inherits\",       value_inherits,       NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> <list>\" },\n\t{ \"$implementation\", value_implementation, NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\" },\n\t{ \"$nth\",            value_nth,            NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<integer>\"},\n\t{ \"$kind\",           value_kind,           NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"$language\",       value_language,       NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\" },\n\t{ \"$scope\",          value_scope,          NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>; $scope-kind:$scope-name\"},\n\t{ \"$scope-kind\",     value_scope_kind,     NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"$scope-name\",     value_scope_name,     NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"$signature\",      value_signature,      NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\" },\n\t{ \"$typeref\",        value_typeref,        NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"$typeref-kind\",   value_typeref_kind,   NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"$typeref-name\",   value_typeref_name,   NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"$roles\",          value_roles,          NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> <list>\" },\n\t{ \"$xpath\",         value_xpath,           NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n};\n\n\n/*\n * FUNCTION DEFINITIONS\n */\nstatic EsObject * dsl_define (DSLEngineType engine, DSLProcBind *pbind)\n{\n\tEsObject *name = es_symbol_intern (pbind->name);\n\tif (name == es_nil)\n\t\treturn es_nil;\n\n\tDSLProcBind **pbs = es_symbol_get_data (name);\n\tif (!pbs)\n\t{\n\t\tpbs = calloc (DSL_ENGINE_COUNT, sizeof (pbinds[0]));\n\t\tif (!pbs)\n\t\t\treturn es_nil;\n\t\tes_symbol_set_data (name, pbs);\n\t}\n\n\tpbs [engine] = pbind;\n\n\treturn name;\n}\n\nint dsl_init (DSLEngineType engine, DSLProcBind *engine_pbinds, int count)\n{\n\tstatic int initialized = 0;\n\n\tif (!initialized)\n\t{\n\t\tengines [DSL_INTERNAL_PSEUDO].pbinds = pbinds_interanl_pseudo;\n\t\tengines [DSL_INTERNAL_PSEUDO].pbinds_count\n\t\t\t= sizeof(pbinds_interanl_pseudo)/sizeof(pbinds_interanl_pseudo [0]);\n\n\t\tfor (int i = 0; i < sizeof(pbinds)/sizeof(pbinds [0]); i++)\n\t\t{\n\t\t\tif (dsl_define (DSL_COMMON, pbinds + i) == NULL)\n\t\t\t\treturn 0;\n\t\t}\n\t\tengines [DSL_COMMON].pbinds = pbinds;\n\t\tengines [DSL_COMMON].pbinds_count = sizeof(pbinds)/sizeof(pbinds [0]);\n\n\t\tinitialized = 1;\n\t}\n\n\tfor (int i = 0; i < count; i++)\n\t{\n\t\tif (dsl_define (engine, engine_pbinds + i) == NULL)\n\t\t\treturn 0;\n\t}\n\n\tengines [engine].pbinds = engine_pbinds;\n\tengines [engine].pbinds_count = count;\n\n\treturn 1;\n}\n\nDSLProcBind *dsl_lookup (DSLEngineType engine, EsObject *name)\n{\n\tDSLProcBind **pbs = es_symbol_get_data (name);\n\tif (!pbs)\n\t\treturn NULL;\n\treturn pbs [engine]? pbs [engine]: pbs [DSL_COMMON];\n}\n\nstatic void dsl_help0 (DSLEngineType engine, FILE *fp)\n{\n\tDSLEngine *e = engines + engine;\n\n\tfor (int i = 0; i < e->pbinds_count; i++)\n\t{\n\t\tconst char* hs = e->pbinds [i].helpstr;\n\n\t\tif (!hs)\n\t\t{\n\t\t\tfprintf(fp, \"%15s: \\n\", e->pbinds [i].name);\n\t\t\tcontinue;\n\t\t}\n\n\t\twhile (hs)\n\t\t{\n\t\t\tconst char *hs0 = strchr (hs, '\\n');\n\n\t\t\tfprintf(fp, \"%15s: \", (e->pbinds [i].helpstr == hs\n\t\t\t\t\t\t\t\t   ? e->pbinds [i].name\n\t\t\t\t\t\t\t\t   : \"\"));\n\n\t\t\tif (hs0)\n\t\t\t{\n\t\t\t\ths0++;\n\t\t\t\tfwrite(hs, 1, hs0 - hs, fp);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfputs(hs, fp);\n\t\t\t\tfputc('\\n', fp);\n\t\t\t}\n\t\t\ths = hs0;\n\t\t}\n\t}\n}\n\nvoid dsl_help (DSLEngineType engine, FILE *fp)\n{\n\tdsl_help0 (DSL_INTERNAL_PSEUDO, fp);\n\tdsl_help0 (DSL_COMMON, fp);\n\tdsl_help0 (engine, fp);\n}\n\nstatic void dsl_cache_reset0 (DSLProcBind *pb)\n{\n\tif (pb->flags & DSL_PATTR_MEMORABLE)\n\t\tpb->cache = NULL;\n}\n\nvoid dsl_cache_reset (DSLEngineType engine)\n{\n\tfor (int i = 0; i < sizeof(pbinds)/sizeof(pbinds [0]); i++)\n\t\tdsl_cache_reset0 (pbinds + i);\n\n\tDSLEngine *e = engines + engine;\n\tfor (int i = 0; i < e->pbinds_count; i++)\n\t\tdsl_cache_reset0( e->pbinds + i);\n}\n\nstatic int length (EsObject *object)\n{\n\tint i;\n\tfor (i = 0; !es_null (object); i++)\n\t\tobject = es_cdr (object);\n\treturn i;\n}\n\nstatic EsObject *error_included (EsObject *object)\n{\n\twhile (!es_null (object))\n\t{\n\t\tif (es_error_p (es_car (object)))\n\t\t\treturn es_car (object);\n\t\tobject = es_cdr (object);\n\t}\n\treturn es_false;\n}\n\nstatic EsObject *eval0 (EsObject *object, DSLEnv *env)\n{\n\tif (es_null (object))\n\t\treturn es_nil;\n\telse\n\t\treturn es_object_autounref (\n\t\t\tes_cons(dsl_eval0 (es_car (object), env),\n\t\t\t\teval0 (es_cdr (object), env))\n\t\t\t);\n}\n\nstatic EsObject *dsl_eval0 (EsObject *object, DSLEnv *env)\n{\n\tEsObject *r;\n\tDSLProcBind *pb;\n\tEsObject *car;\n\n\tif (es_null (object))\n\t\treturn es_nil;\n\telse if (es_symbol_p (object))\n\t{\n\t\tpb = dsl_lookup (env->engine, object);\n\n\t\tif (pb)\n\t\t{\n\t\t\tif (pb->cache)\n\t\t\t\treturn pb->cache;\n\n\t\t\tr = pb->proc (es_nil, env);\n\t\t\tif (pb->flags & DSL_PATTR_MEMORABLE)\n\t\t\t\tpb->cache = r;\n\t\t\treturn r;\n\t\t}\n\t\telse\n\t\t\tdsl_throw (UNBOUND_VARIABLE, object);\n\t}\n\telse if (es_atom (object))\n\t\treturn object;\n\n\tcar = es_car (object);\n\tif (es_regex_p(car))\n\t{\n\t\tEsObject *cdr = es_cdr (object);\n\t\tint l = length (cdr);\n\n\t\tif (l < 1)\n\t\t\tdsl_throw (TOO_FEW_ARGUMENTS, car);\n\n\t\tif (l > 3)\n\t\t\tdsl_throw (TOO_MANY_ARGUMENTS, car);\n\n\t\tcdr = eval0(cdr, env);\n\t\tEsObject *err;\n\n\t\terr = error_included (cdr);\n\t\tif (!es_object_equal (err, es_false))\n\t\t\treturn err;\n\n\t\tEsObject *cadr = es_car (cdr);\n\t\tif (!es_string_p (cadr))\n\t\t\tdsl_throw (WRONG_TYPE_ARGUMENT, object);\n\n\t\tif (l == 1)\n\t\t\treturn es_regex_exec (car, cadr);\n\n\t\tEsObject *cddr = es_cdr (cdr);\n\t\tEsObject *caddr = es_car (cddr);\n\t\tif (!es_number_p (caddr))\n\t\t\tdsl_throw (WRONG_TYPE_ARGUMENT, object);\n\t\tint group = es_integer_get(caddr);\n\t\tif (group < 1)\n\t\t\tdsl_throw (WRONG_REGEX_GROUP, object);\n\t\tEsObject *matched = es_regex_exec_extract_match_new (car, cadr, group);\n\n\t\tif (es_string_p(matched))\n\t\t\treturn es_object_autounref(matched);\n\t\telse if (es_null(matched))\n\t\t\tdsl_throw (WRONG_REGEX_GROUP, object);\n\n\t\tif (l == 3)\n\t\t{\n\t\t\tEsObject *cdddr = es_cdr (cddr);\n\t\t\treturn es_car (cdddr);\n\t\t}\n\n\t\treturn es_object_autounref(es_string_new(\"\"));\n\t}\n\telse if (es_error_p(car))\n\t\treturn car;\n\telse if (es_cons_p (car))\n\t{\n\t\tcar = dsl_eval0 (car, env);\n\t\tif (es_error_p(car))\n\t\t\treturn car;\n\n\t\tobject = es_object_autounref (es_cons (car, es_cdr (object)));\n\t\treturn dsl_eval0 (object, env);\n\t}\n\telse if (es_symbol_p(car))\n\t{\n\t\tEsObject *cdr = es_cdr (object);\n\t\tint l;\n\n\t\tpb = dsl_lookup (env->engine, car);\n\n\t\tif (!pb)\n\t\t\tdsl_throw (UNBOUND_VARIABLE, car);\n\n\t\tif (pb->cache)\n\t\t\treturn pb->cache;\n\n\t\tif (pb->flags & DSL_PATTR_CHECK_ARITY)\n\t\t{\n\t\t\tl = length (cdr);\n\t\t\tif (l < pb->arity)\n\t\t\t\tdsl_throw (TOO_FEW_ARGUMENTS, car);\n\t\t\telse if (l > pb->arity &&\n\t\t\t\t\t !(pb->flags & DSL_PATTR_CHECK_ARITY_OPT))\n\t\t\t\tdsl_throw (TOO_MANY_ARGUMENTS, car);\n\t\t}\n\n\t\tif (! (pb->flags & DSL_PATTR_SELF_EVAL))\n\t\t{\n\t\t\tEsObject *err;\n\n\t\t\tcdr = eval0(cdr, env);\n\n\t\t\terr = error_included (cdr);\n\t\t\tif (!es_object_equal (err, es_false))\n\t\t\t\treturn err;\n\t\t}\n\n\t\tr = pb->proc (cdr, env);\n\t\tif (pb->flags & DSL_PATTR_MEMORABLE)\n\t\t\tpb->cache = r;\n\t\treturn r;\n\t}\n\telse\n\t\tdsl_throw (CALLABLE_REQUIRED, car);\n}\n\nEsObject *dsl_eval (DSLCode *code, DSLEnv *env)\n{\n\treturn dsl_eval0 (code->expr, env);\n}\n\nEsObject *dsl_compile_and_eval (EsObject *expr, DSLEnv *env)\n{\n\treturn dsl_eval0 (expr, env);\n}\n\nstatic EsObject *compile (EsObject *expr, void *engine)\n{\n\tif (!es_cons_p (expr))\n\t\treturn es_object_ref (expr);\n\n\tEsObject *head = es_car (expr);\n\tif (es_symbol_p (head))\n\t{\n\t\tDSLProcBind *pb = dsl_lookup (*((DSLEngineType *)engine),\n\t\t\t\t\t\t\t\t\t  head);\n\t\tif (!pb)\n\t\t\tdsl_throw (UNBOUND_VARIABLE, head);\n\t\tif (pb->macro)\n\t\t{\n\t\t\tEsObject *tail = compile (es_cdr (expr), engine);\n\t\t\tif (es_error_p (tail))\n\t\t\t\treturn tail;\n\t\t\texpr = es_cons (head, tail);\n\t\t\tEsObject *r = pb->macro (expr);\n\t\t\tes_object_unref (expr);\n\t\t\tes_object_unref (tail);\n\t\t\treturn r;\n\t\t}\n\t}\n\treturn es_map (compile, expr, engine);\n}\n\nDSLCode *dsl_compile (DSLEngineType engine, EsObject *expr)\n{\n\tDSLCode *code = malloc (sizeof (DSLCode));\n\tif (code == NULL)\n\t\treturn NULL;\n\n\tcode->expr = compile (expr, &engine);\n\tif (es_null (code->expr))\n\t{\n\t\tfree (code);\n\t\treturn NULL;\n\t}\n\telse if (es_error_p (code->expr))\n\t{\n\t\tdsl_report_error (\"COMPILE ERROR\", code->expr);\n\t\tfree (code);\n\t\treturn NULL;\n\t}\n\treturn code;\n}\n\nvoid dsl_release (DSLEngineType engine, DSLCode *code)\n{\n\tes_object_unref (code->expr);\n\tfree (code);\n}\n\n/*\n * Built-ins\n */\nstatic EsObject* builtin_null  (EsObject *args, DSLEnv *env)\n{\n\treturn es_null(es_car (args))? es_true: es_false;\n}\n\nstatic EsObject* sform_begin_common  (const char *fn, EsObject *args, DSLEnv *env)\n{\n\tif (es_null (args))\n\t\tdsl_throw (TOO_FEW_ARGUMENTS,\n\t\t\t\t   es_symbol_intern (fn));\n\n\tEsObject *o = es_false;\n\twhile (! es_null (args))\n\t{\n\t\to = es_car (args);\n\t\to = dsl_eval0 (o, env);\n\t\tif (es_error_p (o))\n\t\t\treturn o;\n\t\targs = es_cdr (args);\n\t}\n\treturn o;\n}\n\nstatic EsObject* sform_begin  (EsObject *args, DSLEnv *env)\n{\n\treturn sform_begin_common (\"begin\", args, env);\n}\n\nstatic EsObject* sform_begin0  (EsObject *args, DSLEnv *env)\n{\n\tif (es_null (args))\n\t\tdsl_throw (TOO_FEW_ARGUMENTS, es_symbol_intern (\"begin0\"));\n\n\tint count = 0;\n\tEsObject *o, *o0 = es_false;\n\twhile (! es_null (args))\n\t{\n\t\to = es_car (args);\n\t\to = dsl_eval0 (o, env);\n\t\tif (!count++)\n\t\t\to0 = o;\n\n\t\tif (es_error_p (o))\n\t\t\treturn o;\n\t\targs = es_cdr (args);\n\t}\n\treturn o0;\n}\n\nstatic EsObject* sfrom_and  (EsObject *args, DSLEnv *env)\n{\n\tEsObject *o = es_true;\n\n\twhile (! es_null (args))\n\t{\n\t\to = es_car (args);\n\t\to = dsl_eval0 (o, env);\n\t\tif (es_object_equal (o, es_false))\n\t\t\treturn es_false;\n\t\telse if (es_error_p (o))\n\t\t\treturn o;\n\t\targs = es_cdr (args);\n\t}\n\n\treturn o;\n}\n\nstatic EsObject* sform_or  (EsObject *args, DSLEnv *env)\n{\n\tEsObject *o;\n\n\twhile (! es_null (args))\n\t{\n\t\to = es_car (args);\n\t\to = dsl_eval0 (o, env);\n\t\tif (! es_object_equal (o, es_false))\n\t\t\treturn o;\n\t\telse if (es_error_p (o))\n\t\t\treturn o;\n\t\targs = es_cdr (args);\n\t}\n\n\treturn es_false;\n}\n\nstatic EsObject* sform_if (EsObject *args, DSLEnv *env)\n{\n\tEsObject *o;\n\n\to = es_car (args);\n\to = dsl_eval0 (o, env);\n\tif (!es_object_equal (o, es_false))\n\t\treturn dsl_eval0 (es_car (es_cdr (args)), env);\n\telse if (es_error_p (o))\n\t\treturn o;\n\telse\n\t\treturn dsl_eval0 (es_car (es_cdr (es_cdr (args))), env);\n\n\treturn es_false;\n}\n\nstatic EsObject* sform_cond (EsObject *args, DSLEnv *env)\n{\n\n\twhile (!es_null(args))\n\t{\n\t\tEsObject *o = es_car (args);\n\t\targs = es_cdr (args);\n\n\t\tif (!es_cons_p (o))\n\t\t\tdsl_throw (WRONG_TYPE_ARGUMENT, o);\n\n\t\tEsObject *condition = es_car(o);\n\t\tEsObject *actions   = es_cdr(o);\n\n\t\tEsObject *result = dsl_eval0 (condition, env);\n\t\tif (es_error_p (result))\n\t\t\treturn result;\n\n\t\tif (!es_object_equal (result, es_false))\n\t\t{\n\t\t\tif (es_null (actions))\n\t\t\t\treturn result;\n\t\t\treturn sform_begin_common(\"cond\", actions, env);\n\t\t}\n\t}\n\n\treturn es_false;\n}\n\nstatic EsObject* builtin_not  (EsObject *args, DSLEnv *env)\n{\n\tif (es_object_equal (es_car(args), es_false))\n\t\treturn es_true;\n\telse if (es_error_p (es_car(args)))\n\t\treturn es_car(args);\n\telse\n\t\treturn es_false;\n}\n\n#define DEFINE_OP_WITH_CHECK(N, X, C, E, O)\t\t\t\t\\\n\tstatic EsObject* builtin_##N  (EsObject *args, DSLEnv *env)\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tEsObject *a, *b;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\ta = es_car (args);\t\t\t\t\t\\\n\t\tb = es_car (es_cdr (args));\t\t\t\t\\\n\t\tif (!C (a)) dsl_throw(E, O);\t\t\t\\\n\t\tif (!C (b)) dsl_throw(E, O);\t\t\t\\\n\t\tif (X)\t\t\t\t\t\t\t\\\n\t\t\treturn es_true;\t\t\t\t\t\\\n\t\telse\t\t\t\t\t\t\t\\\n\t\t\treturn es_false;\t\t\t\t\\\n\t} END_DEF(builtin_##N)\n\nstatic EsObject* builtin_eq  (EsObject *args, DSLEnv *env)\n{\n\tEsObject *a, *b;\n\ta = es_car (args);\n\tb = es_car (es_cdr (args));\n\n\tif (es_object_equal(a, b))\n\t\treturn es_true;\n\telse\n\t\treturn es_false;\n}\n\nDEFINE_OP_WITH_CHECK(lt, es_number_get (a) < es_number_get (b), es_number_p,  NUMBER_REQUIRED, es_symbol_intern (\"<\"));\nDEFINE_OP_WITH_CHECK(gt, es_number_get (a) > es_number_get (b), es_number_p,  NUMBER_REQUIRED, es_symbol_intern (\">\"));\nDEFINE_OP_WITH_CHECK(le, es_number_get (a) <= es_number_get (b), es_number_p, NUMBER_REQUIRED, es_symbol_intern (\"<=\"));\nDEFINE_OP_WITH_CHECK(ge, es_number_get (a) >= es_number_get (b), es_number_p, NUMBER_REQUIRED, es_symbol_intern (\">=\"));\n\nstatic EsObject* builtin_prefix (EsObject* args, DSLEnv *env)\n{\n\tEsObject *target = es_car (args);\n\tEsObject *prefix = es_car (es_cdr (args));\n\tconst char *ts;\n\tconst char *ps;\n\tsize_t tl;\n\tsize_t pl;\n\n\tif ((! es_string_p (target))\n\t    || (! es_string_p (prefix)))\n\t\tdsl_throw (WRONG_TYPE_ARGUMENT, es_symbol_intern (\"prefix?\"));\n\n\tts = es_string_get (target);\n\tps = es_string_get (prefix);\n\ttl = strlen (ts);\n\tpl = strlen (ps);\n\tif (tl < pl)\n\t\treturn es_false;\n\treturn (strncmp (ts, ps, pl) == 0)? es_true: es_false;\n}\n\nstatic EsObject* builtin_suffix (EsObject* args, DSLEnv *env)\n{\n\tEsObject *target = es_car (args);\n\tEsObject *suffix = es_car (es_cdr (args));\n\tconst char *ts;\n\tconst char *ss;\n\tsize_t tl;\n\tsize_t sl;\n\tunsigned int d;\n\n\tif ((! es_string_p (target))\n\t    || (! es_string_p (suffix)))\n\t\tdsl_throw (WRONG_TYPE_ARGUMENT, es_symbol_intern (\"suffix?\"));\n\n\tts = es_string_get (target);\n\tss = es_string_get (suffix);\n\ttl = strlen (ts);\n\tsl = strlen (ss);\n\tif (tl < sl)\n\t\treturn es_false;\n\td = tl - sl;\n\treturn (strcmp (ts + d, ss) == 0)? es_true: es_false;\n}\n\nstatic EsObject* builtin_substr (EsObject* args, DSLEnv *env)\n{\n\tEsObject *target = es_car (args);\n\tEsObject *substr = es_car (es_cdr (args));\n\tconst char *ts;\n\tconst char *ss;\n\n\tif ((! es_string_p (target))\n\t    || (! es_string_p (substr)))\n\t\tdsl_throw (WRONG_TYPE_ARGUMENT, es_symbol_intern(\"substr?\"));\n\tts = es_string_get (target);\n\tss = es_string_get (substr);\n\n\treturn strstr(ts, ss) == NULL? es_false: es_true;\n}\n\nstatic EsObject* builtin_member (EsObject *args, DSLEnv *env)\n{\n\tEsObject *elt  = es_car (args);\n\tEsObject *lst = es_car (es_cdr (args));\n\n\tif (! es_list_p (lst))\n\t\tdsl_throw (WRONG_TYPE_ARGUMENT, es_symbol_intern (\"member\"));\n\n\twhile (!es_null (lst))\n\t{\n\t\tif (es_object_equal (elt, es_car (lst)))\n\t\t\treturn lst;\n\t\tlst = es_cdr (lst);\n\t}\n\n\treturn es_false;\n}\n\nstatic EsObject* builtin_list (EsObject* args, DSLEnv *env)\n{\n\treturn args;\n}\n\nstatic EsObject* caseop (EsObject *o, int (*op)(int))\n{\n\tif (es_string_p (o))\n\t{\n\t\tconst char *s = es_string_get (o);\n\t\tchar *r = strdup (s);\n\t\tif (r == NULL)\n\t\t\treturn ES_ERROR_MEMORY;\n\n\t\tfor (char *tmp = r; *tmp != '\\0'; tmp++)\n\t\t\t*tmp = op ((unsigned char) *tmp);\n\n\t\tEsObject *q = es_object_autounref (es_string_new (r));\n\t\tfree (r);\n\t\treturn q;\n\t}\n\telse\n\t\treturn o;\n}\n\nstatic EsObject* downcase (EsObject *o)\n{\n\treturn caseop (o, tolower);\n}\n\nstatic EsObject* upcase (EsObject *o)\n{\n\treturn caseop (o, toupper);\n}\n\nstatic EsObject* builtin_caseop0 (EsObject *o,\n\t\t\t\t\t\t\t\t  EsObject *(* op) (EsObject*))\n{\n\tif (es_null (o)\n\t\t|| es_error_p (o))\n\t\treturn o;\n\telse if (es_list_p (o))\n\t{\n\t\tEsObject *oa = es_car (o);\n\t\tEsObject *od = es_cdr (o);\n\t\tEsObject *da, *dd;\n\n\t\tda = op (oa);\n\t\tif (es_error_p (da))\n\t\t\treturn da;\n\t\tdd = builtin_caseop0 (od, op);\n\t\tif (es_error_p (dd))\n\t\t\treturn dd;\n\n\t\treturn es_object_autounref (es_cons (da, dd));\n\t}\n\telse\n\t\treturn op (o);\n}\n\nstatic EsObject* builtin_downcase (EsObject *args, DSLEnv *env)\n{\n\tEsObject *o = es_car(args);\n\treturn builtin_caseop0 (o, downcase);\n}\n\nstatic EsObject* builtin_upcase (EsObject *args, DSLEnv *env)\n{\n\tEsObject *o = es_car(args);\n\treturn builtin_caseop0 (o, upcase);\n}\n\nstatic EsObject* tr(const char *target, char from, char to)\n{\n\tchar *r = strdup(target);\n\tif (r == NULL)\n\t\treturn ES_ERROR_MEMORY;\n\n\tfor (char *tmp = r; *tmp != '\\0'; tmp++)\n\t{\n\t\tif (*tmp == from)\n\t\t\t*tmp = to;\n\t}\n\n\tEsObject *q = es_object_autounref (es_string_new (r));\n\tfree (r);\n\treturn q;\n}\n\nstatic EsObject* builtin_tr (EsObject *args, DSLEnv *env)\n{\n\tEsObject *o_target = es_car(args);\n\tEsObject *o_c0c1 = es_car(es_cdr(args));\n\n\tif (!es_string_p (o_target))\n\t\treturn o_target;\n\n\tif (!es_string_p (o_c0c1))\n\t\tdsl_throw (STRING_REQUIRED, es_symbol_intern (\"tr\"));\n\n\tconst char *cstr_target = es_string_get (o_target);\n\tconst char *cstr_c0c1 = es_string_get (o_c0c1);\n\n\tif (cstr_target[0] == '\\0')\n\t\treturn o_target;\n\n\tsize_t len_c0c1 = strlen (cstr_c0c1);\n\tif (len_c0c1 != 2)\n\t\tdsl_throw (UNEXPECTED_STRING_LENGTH, es_symbol_intern (\"tr\"));\n\n\treturn tr (cstr_target, cstr_c0c1[0], cstr_c0c1[1]);\n}\n\n\nstatic EsObject* builtin_length (EsObject *args, DSLEnv *env)\n{\n\tEsObject *o = es_car(args);\n\tif (es_error_p (o))\n\t\treturn o;\n\tif (!es_string_p (o))\n\t\tdsl_throw (WRONG_TYPE_ARGUMENT, es_symbol_intern (\"length\"));\n\n\tconst char *cstr = es_string_get (o);\n\tsize_t len = strlen (cstr);\n\treturn es_object_autounref (es_integer_new ((int)len));\n}\n\nstatic MIO *miodebug;\nstatic EsObject* bulitin_debug_print (EsObject *args, DSLEnv *env)\n{\n\tif (miodebug == NULL)\n\t\tmiodebug = mio_new_fp (stderr, NULL);\n\n\tEsObject *o = es_car(args);\n\tes_print(o, miodebug);\n\tputc('\\n', stderr);\n\n\treturn o;\n}\n\n/*\n * Accessesors for tagEntry\n */\n\n/*\n * Value functions\n */\nDEFINE_VALUE_FN(name);\nDEFINE_VALUE_FN(input);\nDEFINE_VALUE_FN(pattern);\nDEFINE_VALUE_FN(line);\n\nDEFINE_VALUE_FN(access);\nDEFINE_VALUE_FN(end);\nDEFINE_VALUE_FN(extras);\nDEFINE_VALUE_FN(file);\nDEFINE_VALUE_FN(inherits);\nDEFINE_VALUE_FN(implementation);\nDEFINE_VALUE_FN(kind);\nDEFINE_VALUE_FN(language);\nDEFINE_VALUE_FN(nth);\nDEFINE_VALUE_FN(scope);\nDEFINE_VALUE_FN(scope_kind);\nDEFINE_VALUE_FN(scope_name);\nDEFINE_VALUE_FN(signature);\nDEFINE_VALUE_FN(typeref);\nDEFINE_VALUE_FN(typeref_kind);\nDEFINE_VALUE_FN(typeref_name);\nDEFINE_VALUE_FN(roles);\nDEFINE_VALUE_FN(xpath);\n\nstatic const char*entry_xget (const tagEntry *entry, const char* name)\n{\n\tunsigned int i;\n\tunsigned short count = entry->fields.count;\n\ttagExtensionField *list = entry->fields.list;\n\n\tfor (i = 0; i < count; ++i)\n\t{\n\t\tif (strcmp (list [i].key, name) == 0)\n\t\t\treturn list [i].value;\n\t}\n\treturn NULL;\n\n}\n\nEsObject* dsl_entry_xget_string (const tagEntry *entry, const char* name)\n{\n\tconst char* value = entry_xget (entry, name);\n\tif (value)\n\t\treturn es_object_autounref (es_string_new (value));\n\telse\n\t\treturn es_false;\n}\n\nEsObject* dsl_entry_xget_integer (const tagEntry *entry, const char* name)\n{\n\tconst char *str = entry_xget(entry, name);\n\tEsObject *o;\n\n\tif (str)\n\t{\n\t\tlong value;\n\t\tchar *endstr;\n\n\t\terrno = 0;\n\t\tvalue = strtol (str, &endstr, 10);\n\t\tif (*endstr == '\\0' && str != endstr && errno == 0 &&\n\t\t\tvalue <= INT_MAX  && value >= INT_MIN)\n\t\t{\n\t\t\to = es_integer_new ((int)value);\n\t\t\treturn es_object_autounref (o);\n\t\t}\n\t\telse\n\t\t\treturn es_false;\n\t}\n\telse\n\t\treturn es_false;\n}\n\n/*\n * Accessesors for tagEntry\n */\n\nstatic EsObject* builtin_entry_ref (EsObject *args, DSLEnv *env)\n{\n\tEsObject *key = es_car(args);\n\n\tif (es_error_p (key))\n\t\treturn key;\n\telse if (! es_string_p (key))\n\t\tdsl_throw (WRONG_TYPE_ARGUMENT, es_symbol_intern (\"$\"));\n\telse\n\t{\n\t\tEsObject *r = dsl_entry_xget_string (env->entry, es_string_get (key));\n\t\tif (es_object_equal (r, es_false))\n\t\t{\n\t\t\tEsObject *defaultv = es_car(es_cdr(args));\n\t\t\tif (es_null (defaultv))\n\t\t\t\treturn r;\n\t\t\treturn defaultv;\n\t\t}\n\t\treturn r;\n\t}\n}\n\nEsObject* dsl_entry_name (const tagEntry *entry)\n{\n\treturn es_object_autounref (es_string_new (entry->name));\n}\n\nEsObject* dsl_entry_input (const tagEntry *entry)\n{\n\treturn es_object_autounref (es_string_new (entry->file));\n}\n\nEsObject* dsl_entry_access (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_string (entry, \"access\");\n}\n\nEsObject* dsl_entry_file (const tagEntry *entry)\n{\n\treturn entry->fileScope? es_true: es_false;\n}\n\nEsObject* dsl_entry_language (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_string (entry, \"language\");\n}\n\nEsObject* dsl_entry_nth (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_integer(entry, \"nth\");\n}\n\nEsObject* dsl_entry_implementation (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_string (entry, \"implementation\");\n}\n\nEsObject* dsl_entry_signature (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_string (entry, \"signature\");\n}\n\nEsObject* dsl_entry_line (const tagEntry *entry)\n{\n\tunsigned long ln = entry->address.lineNumber;\n\n\tif (ln == 0)\n\t\treturn es_false;\n\telse\n\t\treturn es_object_autounref (es_integer_new (ln));\n}\n\nEsObject* dsl_entry_extras (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_string (entry, \"extras\");\n}\n\nEsObject* dsl_entry_end (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_integer(entry, \"end\");\n}\n\nEsObject* dsl_entry_kind (const tagEntry *entry)\n{\n\tconst char* kind;\n\tkind = entry->kind;\n\n\tif (kind)\n\t\treturn es_object_autounref (es_string_new (entry->kind));\n\telse\n\t\treturn es_false;\n}\n\nEsObject* dsl_entry_roles (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_string(entry, \"roles\");\n}\n\nEsObject* dsl_entry_pattern (const tagEntry *entry)\n{\n\tconst char *pattern = entry->address.pattern;\n\n\tif (pattern == NULL)\n\t\treturn es_false;\n\telse\n\t\treturn es_object_autounref (es_string_new (pattern));\n}\n\nEsObject* dsl_entry_inherits (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_string (entry, \"inherits\");\n}\n\nEsObject* dsl_entry_scope (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_string (entry, \"scope\");\n}\n\nEsObject* dsl_entry_typeref (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_string (entry, \"typeref\");\n}\n\nEsObject* dsl_entry_xpath (const tagEntry *entry)\n{\n\treturn dsl_entry_xget_string (entry, \"xpath\");\n}\n\nEsObject* dsl_entry_scope_kind (const tagEntry *entry)\n{\n\tconst char* scope = entry_xget (entry, \"scope\");\n\tconst char* kind;\n\tEsObject *r;\n\n\tif (scope == NULL)\n\t\treturn es_false;\n\n\tkind = strchr (scope, ':');\n\tif (kind == NULL)\n\t\treturn es_false;\n\n\tr = es_object_autounref (es_string_newL (scope,\n\t\t\t\t\t\t\t\t\t\t\t kind - scope));\n\treturn r;\n}\n\nEsObject* dsl_entry_scope_name (const tagEntry *entry)\n{\n\tconst char* scope = entry_xget (entry, \"scope\");\n\tconst char* kind;\n\tEsObject *r;\n\n\tif (scope == NULL)\n\t\treturn es_false;\n\n\tkind = strchr (scope, ':');\n\tif (kind == NULL)\n\t\treturn es_false;\n\n\tif (*(kind + 1) == '\\0')\n\t\treturn es_false;\n\n\tr = es_object_autounref (es_string_new (kind + 1));\n\n\treturn r;\n}\n\nEsObject* dsl_entry_typeref_kind (const tagEntry *entry)\n{\n\tconst char* typeref = entry_xget (entry, \"typeref\");\n\tconst char* kind;\n\tEsObject *r;\n\n\tif (typeref == NULL)\n\t\treturn es_false;\n\n\tkind = strchr (typeref, ':');\n\tif (kind == NULL)\n\t\treturn es_false;\n\n\tr = es_object_autounref (es_string_newL (typeref,\n\t\t\t\t\t\t\t\t\t\t\t kind - typeref));\n\treturn r;\n}\n\nEsObject* dsl_entry_typeref_name (const tagEntry *entry)\n{\n\tconst char* typeref = entry_xget (entry, \"typeref\");\n\tconst char* kind;\n\tEsObject *r;\n\n\tif (typeref == NULL)\n\t\treturn es_false;\n\n\tkind = strchr (typeref, ':');\n\tif (kind == NULL)\n\t\treturn es_false;\n\n\tif (*(kind + 1) == '\\0')\n\t\treturn es_false;\n\n\tr = es_object_autounref (es_string_new (kind + 1));\n\n\treturn r;\n}\n\nstatic EsObject* accumulate_length (EsObject *elt, void *data)\n{\n\tsize_t *len = data;\n\tif (!es_string_p (elt))\n\t\tdsl_throw (STRING_REQUIRED, elt);\n\n\tconst char *s = es_string_get (elt);\n\t*len += strlen (s);\n\n\treturn es_false;\n}\n\nstatic EsObject* string_accumulate (EsObject *elt, void *data)\n{\n\tchar **cursor = data;\n\tconst char *s;\n\tchar *t;\n\n\tfor (s = es_string_get(elt), t = *cursor;\n\t\t *s != '\\0';\n\t\t s++, t++)\n\t\t*t = *s;\n\t*cursor = t;\n\treturn es_false;\n}\n\nstatic EsObject* builtin_string_append  (EsObject *args, DSLEnv *env)\n{\n\tsize_t len = 0;\n\n\tEsObject *r = es_foreach (accumulate_length, args, &len);\n\tif (!es_object_equal (r, es_false))\n\t\treturn r;\n\n\tchar *buf = malloc (len + 1);\n\tif (buf == NULL)\n\t\treturn ES_ERROR_MEMORY;\n\n\tchar *cursor = buf;\n\tr = es_foreach (string_accumulate, args, &cursor);\n\tif (!es_object_equal (r, es_false))\n\t\tgoto out;\n\t*cursor = '\\0';\n\n\tr = es_string_new (buf);\n\n out:\n\tfree (buf);\n\treturn es_object_autounref (r);\n}\n\nstatic EsObject* optimize_strings (EsObject *kar, EsObject *kdr, void *user_data)\n{\n\tEsObject *r;\n\tif (!es_string_p (kar))\n\t{\n\t\tr = es_cons (kar, kdr);\n\t\treturn r;\n\t}\n\n\tEsObject *kadr = es_car (kdr);\n\tif (!es_string_p (kadr))\n\t{\n\t\tr = es_cons (kar, kdr);\n\t\treturn r;\n\t}\n\n\tconst char *kar_str = es_string_get (kar);\n\tconst char *kadr_str = es_string_get (kadr);\n\tsize_t kar_len = strlen (kar_str);\n\tsize_t kadr_len = strlen (kadr_str);\n\tchar *buf = malloc (kar_len + kadr_len + 1);\n\tif (buf == NULL)\n\t\treturn ES_ERROR_MEMORY;\n\n\tmemcpy (buf, kadr_str, kadr_len);\n\tmemcpy (buf + kadr_len, kar_str, kar_len);\n\tbuf [kadr_len + kar_len] = '\\0';\n\n\tEsObject *elt = es_object_autounref (es_string_new (buf));\n\tfree (buf);\n\n\tif (es_error_p (elt))\n\t\treturn ES_ERROR_MEMORY;\n\n\tr = es_cons (elt, es_cdr (kdr));\n\n\treturn r;\n}\n\nstatic EsObject* macro_string_append (EsObject *expr)\n{\n\tEsObject *new_expr;\n\tEsObject *list = es_cdr (expr);\n\tEsObject *r = es_fold (optimize_strings,\n\t\t\t\t\t\t   es_nil, list, NULL);\n\n\tif (es_error_p (r))\n\t\treturn es_error_set_object (r, expr);\n\n\tEsObject *str = es_car (r);\n\tif (es_string_p (str) && es_null (es_cdr (r)))\n\t\tnew_expr = es_object_ref (str);\n\telse\n\t{\n\t\tEsObject *kar = es_car (expr);\n\t\tEsObject* rr  = es_reverse (r);\n\t\tnew_expr = es_cons (kar, rr);\n\t\tes_object_unref (rr);\n\t}\n\tes_object_unref (r);\n\treturn new_expr;\n}\n\nstatic EsObject* builtin_add  (EsObject *args, DSLEnv *env)\n{\n\tEsObject *a = es_car (args);\n\tif (!es_integer_p (a))\n\t\tdsl_throw (INTEGER_REQUIRED,\n\t\t\t\t   es_symbol_intern (\"+\"));\n\n\tEsObject *b = es_car (es_cdr (args));\n\tif (!es_integer_p (b))\n\t\tdsl_throw (INTEGER_REQUIRED,\n\t\t\t\t   es_symbol_intern (\"+\"));\n\n\tint ai = es_integer_get (a);\n\tint bi = es_integer_get (b);\n\n\treturn es_object_autounref (es_integer_new (ai + bi));\n}\n\nstatic EsObject* builtin_sub  (EsObject *args, DSLEnv *env)\n{\n\tEsObject *a = es_car (args);\n\tif (!es_integer_p (a))\n\t\tdsl_throw (INTEGER_REQUIRED,\n\t\t\t\t   es_symbol_intern (\"-\"));\n\n\tEsObject *b = es_car (es_cdr (args));\n\tif (!es_integer_p (b))\n\t\tdsl_throw (INTEGER_REQUIRED,\n\t\t\t\t   es_symbol_intern (\"-\"));\n\n\tint ai = es_integer_get (a);\n\tint bi = es_integer_get (b);\n\n\treturn es_object_autounref (es_integer_new (ai - bi));\n}\n\nstatic EsObject* value_true (EsObject *args, DSLEnv *env)\n{\n\treturn es_true;\n}\n\nstatic EsObject* value_false (EsObject *args, DSLEnv *env)\n{\n\treturn es_false;\n}\n\nstatic EsObject* value_nil (EsObject *args, DSLEnv *env)\n{\n\treturn es_nil;\n}\n\nstatic EsObject* common_string2regexp (EsObject *args, DSLEnv *env,\n\t\t\t\t\t\t\t\t\t   EsObject *original_expr)\n{\n\tstatic EsObject *self = es_nil;\n\tif (self == es_nil)\n\t\tself = es_symbol_intern (\"string->regexp\");\n\n\tif (!es_cons_p (args))\n\t\tdsl_throw(TOO_FEW_ARGUMENTS,\n\t\t\t\t  (original_expr == es_nil)\n\t\t\t\t  ? self\n\t\t\t\t  : es_car (original_expr));\n\telse if (!es_string_p (es_car (args)))\n\t{\n\t\tif (original_expr == es_nil)\n\t\t\tdsl_throw(STRING_REQUIRED, self);\n\t\telse\n\t\t\treturn es_object_ref (original_expr);\n\t}\n\telse\n\t{\n\t\tstatic EsObject *case_fold_key = es_nil;\n\t\tif (case_fold_key == es_nil)\n\t\t\tcase_fold_key = es_symbol_intern (\":case-fold\");\n\t\tstatic EsObject *false_val = es_nil;\n\t\tif (false_val == es_nil)\n\t\t\tfalse_val = es_symbol_intern (\"false\");\n\n\t\tEsObject *case_fold = es_car (es_cdr (args));\n\t\tEsObject *pattern = es_car (args);\n\t\tint icase = 0;\n\n\t\tif (!es_null (case_fold))\n\t\t{\n\t\t\tif (!es_object_equal (case_fold, case_fold_key))\n\t\t\t\tdsl_throw (WRONG_TYPE_ARGUMENT,\n\t\t\t\t\t\t   (original_expr == es_nil)? self: original_expr);\n\n\t\t\tcase_fold = es_car (es_cdr (es_cdr (args)));\n\t\t\tif (es_null (case_fold))\n\t\t\t\tdsl_throw (TOO_FEW_ARGUMENTS,\n\t\t\t\t\t\t   (original_expr == es_nil)? self: original_expr);\n\n\t\t\ticase = ! (es_object_equal(case_fold, es_false)\n\t\t\t\t\t   /* TODO: remove the next condition. */\n\t\t\t\t\t   || es_object_equal(case_fold, false_val));\n\t\t}\n\n\t\tEsObject *r = es_regex_compile (es_string_get (pattern), icase);\n\t\treturn (original_expr == es_nil)? es_object_autounref (r): r;\n\t}\n}\n\nstatic EsObject* builtin_string2regexp (EsObject *args, DSLEnv *env)\n{\n\treturn common_string2regexp (args, env, es_nil);\n}\n\nstatic EsObject* macro_string2regexp (EsObject *expr)\n{\n\treturn common_string2regexp (es_cdr (expr), NULL, expr);\n}\n\nstatic EsObject* common_regexp_quote (EsObject *args, DSLEnv *env,\n\t\t\t\t\t\t\t\t\t  EsObject *original_expr)\n{\n\tstatic EsObject *self = es_nil;\n\tif (self == es_nil)\n\t\tself = es_symbol_intern (\"regexp-quote\");\n\n\tif (original_expr != es_nil && !es_cons_p (args))\n\t\tdsl_throw(TOO_FEW_ARGUMENTS,\n\t\t\t\t  es_car (original_expr));\n\n\tEsObject *unquoted_str = es_car (args);\n\tif (!es_string_p (unquoted_str))\n\t{\n\t\tif (original_expr  == es_nil)\n\t\t\tdsl_throw(STRING_REQUIRED, self);\n\t\telse\n\t\t\treturn es_object_ref (original_expr);\n\t}\n\n\tconst char *src = es_string_get (unquoted_str);\n\tif (src[0] == '\\0')\n\t\treturn (original_expr  == es_nil)\n\t\t\t? unquoted_str\n\t\t\t: es_object_ref (unquoted_str);\n\n\tsize_t len = strlen (src);\n\tchar *buf = malloc (len * 2 + 1);\n\tif (!buf)\n\t\treturn ES_ERROR_MEMORY;\n\n\tchar *dst = buf;\n\tfor (size_t i = 0; i < len; i++)\n\t{\n\t\tif (strchr (\"[{.*+]}^$()|?\\\\\", src [i]))\n\t\t\t*dst++ = '\\\\';\n\t\t*dst++ = src[i];\n\t}\n\t*dst = '\\0';\n\tEsObject *r = es_string_new (buf);\n\tfree (buf);\n\treturn (original_expr  == es_nil)? es_object_autounref (r): r;\n}\n\nstatic EsObject* builtin_regexp_quote (EsObject *args, DSLEnv *env)\n{\n\treturn common_regexp_quote (args, env, es_nil);\n}\n\nstatic EsObject* macro_regexp_quote (EsObject *expr)\n{\n\treturn common_regexp_quote (es_cdr (expr), NULL, expr);\n}\n\nstatic EsObject* macro_debug_printX (EsObject *expr)\n{\n\tEsObject *code = es_cdr (expr);\n\tbulitin_debug_print (code, NULL);\n\treturn es_object_ref(es_car (code));\n}\n\nvoid dsl_report_error (const char *msg, EsObject *obj)\n{\n\tMIO *mioerr = mio_new_fp (stderr, NULL);\n\n\tif (es_error_p (obj))\n\t{\n\t\tfprintf(stderr, \"%s: %s: \", msg, es_error_name (obj));\n\t\tes_print(es_error_get_object(obj), mioerr);\n\t}\n\telse\n\t{\n\t\tfprintf(stderr, \"%s: \", msg);\n\t\tes_print(obj, mioerr);\n\t}\n\tputc('\\n', stderr);\n\tmio_unref(mioerr);\n}\n"
  },
  {
    "path": "dsl/dsl.h",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef DSL_H\n#define DSL_H\n\n/*\n * INCLUDES\n */\n#include \"es.h\"\n#include \"readtags.h\"\n\n\n/*\n * TYPES\n */\nenum eDSLEngineType {\n\tDSL_INTERNAL_PSEUDO,\n\tDSL_COMMON,\n\tDSL_QUALIFIER,\n\tDSL_SORTER,\n\tDSL_FORMATTER,\n\tDSL_ENGINE_COUNT\n};\ntypedef enum eDSLEngineType DSLEngineType;\n\nstruct sDSLEnv {\n\tenum eDSLEngineType engine;\n\tconst tagEntry *entry;\n\tconst tagEntry *alt_entry;\n};\ntypedef struct sDSLEnv DSLEnv;\n\ntypedef EsObject* (* DSLProc)  (EsObject *args, DSLEnv *env);\ntypedef EsObject* (* DSLMacro)  (EsObject *expr);\n\n\nenum eDSLPAttr {\n\tDSL_PATTR_MEMORABLE   = 1UL << 0,\n\tDSL_PATTR_SELF_EVAL   = 1UL << 1,\n\tDSL_PATTR_CHECK_ARITY = 1UL << 2,\n\tDSL_PATTR_CHECK_ARITY_OPT = 1UL << 3 | DSL_PATTR_CHECK_ARITY,\n};\ntypedef enum eDSLPAttr DSLPAttr;\n\ntypedef struct sDSLProcBind DSLProcBind;\nstruct sDSLProcBind {\n\tconst char *name;\n\tDSLProc proc;\n\tEsObject* cache;\n\tDSLPAttr flags;\n\tint arity;\n\tconst char* helpstr;\n\tDSLMacro macro;\n};\n\ntypedef struct sDSLCode DSLCode;\n\n#define DSL_ERR_UNBOUND_VARIABLE    (es_error_intern(\"unbound-variable\"))\n#define DSL_ERR_TOO_FEW_ARGUMENTS   (es_error_intern(\"too-few-arguments\"))\n#define DSL_ERR_TOO_MANY_ARGUMENTS  (es_error_intern(\"too-many-arguments\"))\n#define DSL_ERR_STRING_REQUIRED     (es_error_intern(\"string-required\"))\n#define DSL_ERR_BOOLEAN_REQUIRED    (es_error_intern(\"boolean-required\"))\n#define DSL_ERR_INTEGER_REQUIRED    (es_error_intern(\"integer-required\"))\n#define DSL_ERR_NUMBER_REQUIRED     (es_error_intern(\"number-required\"))\n#define DSL_ERR_CALLABLE_REQUIRED   (es_error_intern(\"callable-required\"))\n#define DSL_ERR_WRONG_TYPE_ARGUMENT (es_error_intern(\"wrong-type-argument\"))\n#define DSL_ERR_NO_ALT_ENTRY        (es_error_intern(\"the-alternative-entry-unavailable\"))\n#define DSL_ERR_WRONG_REGEX_GROUP   (es_error_intern(\"wrong-regex-group\"))\n#define DSL_ERR_UNEXPECTED_STRING_LENGTH (es_error_intern(\"unexpected-string-length\"))\n\n/*\n * MACROS\n */\n#define dsl_throw(e,o)               return es_error_set_object(DSL_ERR_##e, o)\n\n\n/*\n * Function declarations\n */\n\n/* Return 1 if no error. */\nint            dsl_init        (DSLEngineType engine, DSLProcBind *engine_pbinds, int count);\nDSLProcBind   *dsl_lookup      (DSLEngineType engine, EsObject *name);\nvoid           dsl_help        (DSLEngineType engine, FILE *fp);\nvoid           dsl_cache_reset (DSLEngineType engine);\nDSLCode       *dsl_compile     (DSLEngineType engine, EsObject *expr);\nEsObject      *dsl_eval        (DSLCode *code, DSLEnv *env);\nvoid           dsl_release     (DSLEngineType engine, DSLCode *code);\n\n/* This should be remove when we have a real compiler. */\nEsObject *dsl_compile_and_eval (EsObject *expr, DSLEnv *env);\n\n\nEsObject* dsl_entry_xget_string (const tagEntry *entry, const char* name);\nEsObject* dsl_entry_xget_integer (const tagEntry *entry, const char* name);\n\nEsObject* dsl_entry_name (const tagEntry *entry);\nEsObject* dsl_entry_input (const tagEntry *entry);\nEsObject* dsl_entry_pattern (const tagEntry *entry);\nEsObject* dsl_entry_line (const tagEntry *entry);\n\nEsObject* dsl_entry_access (const tagEntry *entry);\nEsObject* dsl_entry_end (const tagEntry *entry);\nEsObject* dsl_entry_extras (const tagEntry *entry);\nEsObject* dsl_entry_file (const tagEntry *entry);\nEsObject* dsl_entry_inherits (const tagEntry *entry);\nEsObject* dsl_entry_implementation (const tagEntry *entry);\nEsObject* dsl_entry_kind (const tagEntry *entry);\nEsObject* dsl_entry_language (const tagEntry *entry);\nEsObject* dsl_entry_nth (const tagEntry *entry);\nEsObject* dsl_entry_scope (const tagEntry *entry);\nEsObject* dsl_entry_scope_kind (const tagEntry *entry);\nEsObject* dsl_entry_scope_name (const tagEntry *entry);\nEsObject* dsl_entry_signature (const tagEntry *entry);\nEsObject* dsl_entry_typeref (const tagEntry *entry);\nEsObject* dsl_entry_typeref_kind (const tagEntry *entry);\nEsObject* dsl_entry_typeref_name (const tagEntry *entry);\nEsObject* dsl_entry_roles (const tagEntry *entry);\nEsObject* dsl_entry_xpath (const tagEntry *entry);\n\nvoid dsl_report_error (const char *msg, EsObject *obj);\n\n#endif\n"
  },
  {
    "path": "dsl/es.c",
    "content": "/*\n  Copyright (c) 2009 Masatake YAMATO\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE. */\n\n#if defined (HAVE_CONFIG_H)\n# include <config.h>\n#endif\n\n#include \"es.h\"\n\n\n#include <stdlib.h>\n#include <string.h>\n#include <errno.h>\n#include <limits.h>\n#include <math.h>\n\n#include <regex.h>\n\nstatic int es_debug = 0;\n\ntypedef struct _EsInteger EsInteger;\ntypedef struct _EsReal EsReal;\ntypedef struct _EsBoolean EsBoolean;\ntypedef struct _EsString EsString;\ntypedef struct _EsSingleton EsSingleton;\ntypedef struct _EsSymbol EsSymbol;\ntypedef struct _EsError EsError;\ntypedef struct _EsCons EsCons;\ntypedef struct _EsRegex EsRegex;\ntypedef struct _EsPointer EsPointer;\n\nstruct _EsObject\n{\n\tEsType  type;\n\tunion\n\t{\n\t\tint     ref_count;\n\t\tEsSingleton* next;\n\t};\n};\n\nstruct _EsInteger\n{\n\tEsObject base;\n\tint      value;\n};\n\nstruct _EsReal\n{\n\tEsObject base;\n\tdouble   value;\n};\n\nstruct _EsBoolean\n{\n\tEsObject base;\n\tint      value;\n};\n\nstruct _EsString\n{\n\tEsObject    base;\n\tchar*       value;\n};\n\nstruct _EsSingleton\n{\n\tEsObject     base;\n\tchar*        quark;\n};\n\nstruct _EsSymbol\n{\n\tEsSingleton base;\n\tvoid       *data;\n};\n\nstruct _EsError\n{\n\tEsSingleton base;\n\tEsObject   *object;\n};\n\nstruct _EsCons\n{\n\tEsObject base;\n\tEsObject* car;\n\tEsObject* cdr;\n};\n\nstruct _EsRegex\n{\n\tEsObject base;\n\tregex_t *code;\n\tchar* literal;\n\tint   case_insensitive;\n};\n\nstruct _EsPointer\n{\n\tEsObject base;\n\tvoid *ptr;\n\tchar  fat [];\n};\n\nenum EsObjectFlag\n{\n\tES_OBJECT_FLAG_ATOM = 1 << 0,\n};\n\ntypedef struct _EsObjectClass EsObjectClass;\nstruct _EsObjectClass\n{\n\tsize_t         size;\n\tvoid           (* free)  (EsObject* object);\n\tint            (* equal) (const EsObject* self, const EsObject* other);\n\tvoid           (* print) (const EsObject* object, MIO* fp);\n\tunsigned       flags;\n\tEsSingleton  **obarray;\n\tconst char*    name;\n};\n\n\nstatic void es_nil_free(EsObject* object);\nstatic int  es_nil_equal(const EsObject* self, const EsObject* other);\nstatic void es_nil_print(const EsObject* object, MIO* fp);\n\nstatic void es_integer_free(EsObject* object);\nstatic int  es_integer_equal(const EsObject* self, const EsObject* other);\nstatic void es_integer_print(const EsObject* object, MIO* fp);\n\nstatic void es_real_free(EsObject* object);\nstatic int  es_real_equal(const EsObject* self, const EsObject* other);\nstatic void es_real_print(const EsObject* object, MIO* fp);\n\nstatic void es_boolean_free(EsObject* object);\nstatic int  es_boolean_equal(const EsObject* self, const EsObject* other);\nstatic void es_boolean_print(const EsObject* object, MIO* fp);\n\nstatic void es_string_free(EsObject* object);\nstatic int  es_string_equal(const EsObject* self, const EsObject* other);\nstatic void es_string_print(const EsObject* self, MIO* fp);\n\nstatic void es_symbol_free(EsObject* object);\nstatic int  es_symbol_equal(const EsObject* self, const EsObject* other);\nstatic void es_symbol_print(const EsObject* object, MIO* fp);\n\nstatic void es_cons_free(EsObject* object);\nstatic int  es_cons_equal(const EsObject* self, const EsObject* other);\nstatic void es_cons_print(const EsObject* object, MIO* fp);\n\nstatic void es_regex_free(EsObject* object);\nstatic int  es_regex_equal(const EsObject* self, const EsObject* other);\nstatic void es_regex_print(const EsObject* object, MIO* fp);\n\nstatic void es_error_free(EsObject* object);\nstatic int  es_error_equal(const EsObject* self, const EsObject* other);\nstatic void es_error_print(const EsObject* object, MIO* fp);\n\nstatic void es_pointer_free(EsObject* object);\nstatic int  es_pointer_equal(const EsObject* self, const EsObject* other);\nstatic void es_pointer_print(const EsObject* object, MIO* fp);\n\nstatic EsSingleton* es_obarray_intern(EsType type, const char* name);\nstatic const char*  es_singleton_get   (EsSingleton *singleton);\nstatic unsigned int hash(const char* keyarg);\n#define OBARRAY_SIZE    83\nstatic EsSingleton *symbol_obarray[OBARRAY_SIZE];\nstatic EsSingleton *error_obarray [OBARRAY_SIZE];\n\nstatic EsObjectClass es_nil_class = {\n\t.size    = 0,\n\t.free    = es_nil_free,\n\t.equal   = es_nil_equal,\n\t.print   = es_nil_print,\n\t.flags   = ES_OBJECT_FLAG_ATOM,\n\t.obarray = NULL,\n\t.name    = \"nil\",\n};\n\nstatic EsObjectClass es_integer_class = {\n\t.size    = sizeof(EsInteger),\n\t.free    = es_integer_free,\n\t.equal   = es_integer_equal,\n\t.print   = es_integer_print,\n\t.flags   = ES_OBJECT_FLAG_ATOM,\n\t.obarray = NULL,\n\t.name    = \"integer\",\n};\n\nstatic EsObjectClass es_real_class = {\n\t.size    = sizeof(EsReal),\n\t.free    = es_real_free,\n\t.equal   = es_real_equal,\n\t.print   = es_real_print,\n\t.flags   = ES_OBJECT_FLAG_ATOM,\n\t.obarray = NULL,\n\t.name    = \"real\",\n};\n\nstatic EsObjectClass es_boolean_class = {\n\t.size    = sizeof(EsBoolean),\n\t.free    = es_boolean_free,\n\t.equal   = es_boolean_equal,\n\t.print   = es_boolean_print,\n\t.flags   = ES_OBJECT_FLAG_ATOM,\n\t.obarray = (void*)1,\n\t.name    = \"boolean\",\n};\n\nstatic EsObjectClass es_symbol_class = {\n\t.size    = sizeof(EsSymbol),\n\t.free    = es_symbol_free,\n\t.equal   = es_symbol_equal,\n\t.print   = es_symbol_print,\n\t.flags   = ES_OBJECT_FLAG_ATOM,\n\t.obarray = symbol_obarray,\n\t.name    = \"symbol\",\n};\n\nstatic EsObjectClass es_string_class = {\n\t.size    = sizeof(EsString),\n\t.free    = es_string_free,\n\t.equal   = es_string_equal,\n\t.print   = es_string_print,\n\t.flags   = ES_OBJECT_FLAG_ATOM,\n\t.obarray = NULL,\n\t.name    = \"string\",\n};\n\nstatic EsObjectClass es_cons_class = {\n\t.size    = sizeof(EsCons),\n\t.free    = es_cons_free,\n\t.equal   = es_cons_equal,\n\t.print   = es_cons_print,\n\t.flags   = 0,\n\t.obarray = NULL,\n\t.name    = \"cons\",\n};\n\nstatic EsObjectClass es_regex_class = {\n\t.size    = sizeof(EsRegex),\n\t.free    = es_regex_free,\n\t.equal   = es_regex_equal,\n\t.print   = es_regex_print,\n\t.flags   = ES_OBJECT_FLAG_ATOM,\n\t.obarray = NULL,\n\t.name    = \"regex\",\n};\n\nstatic EsObjectClass es_error_class = {\n\t.size    = sizeof(EsError),\n\t.free    = es_error_free,\n\t.equal   = es_error_equal,\n\t.print   = es_error_print,\n\t.flags   = ES_OBJECT_FLAG_ATOM,\n\t.obarray = error_obarray,\n\t.name    = \"error\",\n};\n\n\n#define ES_TYPE_CLASS_MAX 32\nstatic int classes_count = ES_TYPE_FOREIGNER_START;\nstatic EsObjectClass *classes[ES_TYPE_CLASS_MAX] = {\n\t[ES_TYPE_NIL]     = &es_nil_class,\n\t[ES_TYPE_INTEGER] = &es_integer_class,\n\t[ES_TYPE_REAL]    = &es_real_class,\n\t[ES_TYPE_BOOLEAN] = &es_boolean_class,\n\t[ES_TYPE_SYMBOL]  = &es_symbol_class,\n\t[ES_TYPE_STRING]  = &es_string_class,\n\t[ES_TYPE_CONS]    = &es_cons_class,\n\t[ES_TYPE_REGEX]   = &es_regex_class,\n\t[ES_TYPE_ERROR]   = &es_error_class,\n};\n\n\f\n\nstatic MIO *mio_stdout (void)\n{\n\tstatic MIO *out;\n\n\tif (out == NULL)\n\t\tout = mio_new_fp (stdout, NULL);\n\n\treturn out;\n}\n\nstatic MIO *mio_stdin (void)\n{\n\tstatic MIO *out;\n\n\tif (out == NULL)\n\t\tout = mio_new_fp (stdin, NULL);\n\n\treturn out;\n}\n\nstatic MIO *mio_stderr (void)\n{\n\tstatic MIO *out;\n\n\tif (out == NULL)\n\t\tout = mio_new_fp (stderr, NULL);\n\n\treturn out;\n}\n\n\f\n\nstatic EsObjectClass*\nclass_of(const EsObject* object)\n{\n\treturn (classes[es_object_get_type(object)]);\n}\n\nstatic EsObject*\nes_object_new(EsType type)\n{\n\tEsObject* r;\n\n\n\tr = calloc(1, (classes[type])->size);\n\tif (r == NULL)\n\t\treturn ES_ERROR_MEMORY;\n\tr->type = type;\n\tr->ref_count = 1;\n\n\tif (es_debug)\n\t\tmio_printf(mio_stderr(), \";; new{%s}: 0x%p\\n\",\n\t\t\t\t   (classes[type])->name,\n\t\t\t\t   r);\n\n\treturn r;\n}\n\nstatic void\nes_object_free(EsObject* object)\n{\n\tmemset(object, 0, class_of(object)->size);\n\tfree(object);\n}\n\nstatic int\nes_object_type_p(const EsObject* object, EsType type)\n{\n\treturn es_object_get_type(object) == type;\n}\n\nconst char* es_type_get_name        (int t)\n{\n\treturn (classes[t]->name);\n}\n\nEsType\nes_object_get_type      (const EsObject*      object)\n{\n\treturn object? object->type: ES_TYPE_NIL;\n}\n\nEsObject*\nes_object_ref           (EsObject*       object)\n{\n\tif (object)\n    {\n\t\tif (class_of(object)->obarray)\n\t\t\treturn object;\n\n\t\tif (es_debug)\n\t\t\tmio_printf(mio_stderr(), \";; ref{%s}: [%d]0x%p\\n\",\n\t\t\t\t\t   class_of(object)->name,\n\t\t\t\t\t   object->ref_count,\n\t\t\t\t\t   object);\n\t\tobject->ref_count++;\n    }\n\treturn object;\n}\n\nvoid\nes_object_unref         (EsObject*       object)\n{\n\n\tif (object)\n    {\n\t\tif (class_of(object)->obarray)\n\t\t\treturn;\n\n\t\tif (object->ref_count == 0)\n\t\t\tif ((1 || es_debug))\n\t\t\t{\n\t\t\t\tmio_printf(mio_stderr(), \"*** ref_count < 0: 0x%p ***\\n\", object);\n\t\t\t\tmio_printf(mio_stderr(), \"*** BOOSTING while(1). ***\\n\");\n\t\t\t\twhile (1);\n\t\t\t}\n\n\t\tobject->ref_count--;\n\t\tif (es_debug)\n\t\t\tmio_printf(mio_stderr(), \";; unref{%s}: [%d]0x%p\\n\",\n\t\t\t\t\t   class_of(object)->name,\n\t\t\t\t\t   object->ref_count, object);\n\t\tif (object->ref_count == 0)\n\t\t{\n\t\t\tif (es_debug)\n\t\t\t\tmio_printf(mio_stderr(), \";; free{%s}: 0x%p\\n\",\n\t\t\t\t\t\t   class_of(object)->name,\n\t\t\t\t\t\t   object);\n\t\t\tclass_of(object)->free(object);\n\t\t}\n    }\n}\n\nvoid\nes_object_unref_batch (EsObject*       array[],\n\t\t\t\t\t   unsigned int    count)\n{\n\tunsigned int i;\n\n\tfor (i = 0; i < count; i++)\n    {\n\t\tes_object_unref(array[i]);\n\t\tarray[i] = es_nil;\n    }\n}\n\nint\nes_object_equal         (const EsObject* self,\n\t\t\t\t\t\t const EsObject* other)\n{\n\tif (self == other)\n\t\treturn 1;\n\n\treturn class_of(self)->equal(self, other);\n}\n\n\nint\nes_atom         (const EsObject* object)\n{\n\treturn class_of(object)->flags  & ES_OBJECT_FLAG_ATOM;\n}\n\n\n/*\n * Nil\n */\nint\nes_null(const EsObject* object)\n{\n\treturn (object == es_nil)? 1: 0;\n}\n\nstatic void\nes_nil_free(EsObject* object)\n{\n\t/* DO NOTHING */\n}\n\nstatic int\nes_nil_equal(const EsObject* self, const EsObject* other)\n{\n\treturn es_null(other);\n}\n\nstatic void\nes_nil_print(const EsObject* object, MIO* fp)\n{\n\tmio_puts(fp, \"()\");\n}\n\n/*\n * Integer\n */\nEsObject*\nes_integer_new (int                value)\n{\n\tEsObject* r;\n\n\tr = es_object_new(ES_TYPE_INTEGER);\n\t((EsInteger*)r)->value = value;\n\treturn r;\n}\n\nint\nes_integer_p   (const EsObject*   object)\n{\n\treturn es_object_type_p(object, ES_TYPE_INTEGER);\n}\n\nint\nes_integer_get (const EsObject*   object)\n{\n\tif (es_integer_p(object))\n\t\treturn ((EsInteger *)object)->value;\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; es_integer_get, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\treturn -1;\n    }\n}\n\nstatic void\nes_integer_free(EsObject* object)\n{\n\tes_object_free(object);\n}\n\nstatic int\nes_integer_equal(const EsObject* self, const EsObject* other)\n{\n\treturn ((es_integer_p(other))\n\t\t\t&& (es_integer_get(self) == es_integer_get(other)))? 1: 0;\n}\n\nstatic void\nes_integer_print(const EsObject* object, MIO* fp)\n{\n\tmio_printf(fp, \"%d\", es_integer_get(object));\n}\n\n\n/*\n * Real\n */\nEsObject*\nes_real_new (double                value)\n{\n\tEsObject* r;\n\n\tr = es_object_new(ES_TYPE_REAL);\n\t((EsReal*)r)->value = value;\n\treturn r;\n}\n\nint\nes_real_p   (const EsObject*   object)\n{\n\treturn es_object_type_p(object, ES_TYPE_REAL);\n}\n\ndouble\nes_real_get (const EsObject*   object)\n{\n\tif (es_real_p(object))\n\t\treturn ((EsReal *)object)->value;\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; es_real_get, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\treturn -1;\n    }\n}\n\nstatic void\nes_real_free(EsObject* object)\n{\n\tes_object_free(object);\n}\n\nstatic int\nes_real_equal(const EsObject* self, const EsObject* other)\n{\n\treturn ((es_real_p(other))\n\t\t\t/* TODO: Too restricted? */\n\t\t\t&& (es_real_get(self) == es_real_get(other)))? 1: 0;\n}\n\nstatic void\nes_real_print(const EsObject* object, MIO* fp)\n{\n\tmio_printf(fp, \"%f\", es_real_get(object));\n}\n\n/*\n * Use Integer as Real\n */\nint\nes_number_p    (const EsObject*   object)\n{\n\treturn (es_integer_p(object) || es_real_p(object))? 1: 0;\n}\n\ndouble\nes_number_get  (const EsObject*   object)\n{\n\tdouble r;\n\n\tswitch(es_object_get_type(object))\n    {\n    case ES_TYPE_INTEGER:\n\t\tr = (double)es_integer_get(object);\n\t\tbreak;\n    case ES_TYPE_REAL:\n\t\tr = es_real_get(object);\n\t\tbreak;\n    default:\n\t\tmio_printf(mio_stderr(), \";; es_number_get, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\tr = -1.0;\n\t\tbreak;\n    }\n\treturn r;\n}\n\n\n/*\n * Boolean\n */\nEsObject*\nes_boolean_new (int                value)\n{\n\tstatic EsObject* T;\n\tstatic EsObject* F;\n\n\tif (!T)\n    {\n\t\tT = es_object_new(ES_TYPE_BOOLEAN);\n\t\t((EsBoolean*)T)->value = 1;\n    }\n\tif (!F)\n    {\n\t\tF = es_object_new(ES_TYPE_BOOLEAN);\n\t\t((EsBoolean*)F)->value = 0;\n    }\n\n\treturn value? T: F;\n}\n\nint\nes_boolean_p   (const EsObject*   object)\n{\n\treturn es_object_type_p(object, ES_TYPE_BOOLEAN);\n}\n\nint\nes_boolean_get (const EsObject*   object)\n{\n\tif (es_boolean_p(object))\n\t\treturn ((EsBoolean *)object)->value;\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; es_boolean_get, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\treturn -1;\n    }\n}\n\nstatic void\nes_boolean_free(EsObject* object)\n{\n\t/* Do nothing */\n}\n\nstatic int\nes_boolean_equal(const EsObject* self, const EsObject* other)\n{\n\treturn (self == other)? 1: 0;\n}\n\nstatic void\nes_boolean_print(const EsObject* object, MIO* fp)\n{\n\tmio_printf(fp, \"#%c\", (es_boolean_get(object)? 't': 'f'));\n}\n\n/*\n * Singleton\n */\nstatic EsSingleton*\nes_obarray_intern(EsType type, const char* name)\n{\n\tunsigned int hv;\n\tEsSingleton** obarray;\n\tEsSingleton* s;\n\tEsSingleton* tmp;\n\n\n\tobarray = (classes[type])->obarray;\n\tif (!obarray)\n\t\treturn NULL;\n\n\thv = hash(name);\n\ttmp = obarray[hv];\n\n\ts = NULL;\n\twhile (tmp)\n    {\n\t\tif (!strcmp(tmp->quark, name))\n\t\t{\n\t\t\ts = tmp;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\ttmp = ((EsObject *)tmp)->next;\n    }\n\n\tif (!s)\n    {\n\t\ts = (EsSingleton*) es_object_new(type);\n\t\ts->quark = strdup(name);\n\t\ttmp = obarray[hv];\n\t\tobarray[hv] = s;\n\t\t((EsObject *)s)->next = tmp;\n    }\n\n\treturn s;\n\n}\n\nstatic const char*\nes_singleton_get   (EsSingleton *singleton)\n{\n\treturn singleton->quark;\n}\n\n\n/*\n * Symbol\n */\nstatic unsigned char get_char_class(int c);\n\n\nEsObject*\nes_symbol_intern  (const char*       name)\n{\n\tEsSingleton* r;\n\n\tr = es_obarray_intern(ES_TYPE_SYMBOL, name);\n\treturn (EsObject*)r;\n}\n\nint\nes_symbol_p    (const EsObject*   object)\n{\n\treturn es_object_type_p(object, ES_TYPE_SYMBOL);\n}\n\nconst char*\nes_symbol_get  (const EsObject*   object)\n{\n\tif (es_symbol_p(object))\n\t\treturn es_singleton_get((EsSingleton*)object);\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; es_symbol_get, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\treturn NULL;\n    }\n}\n\nvoid*        es_symbol_set_data (const EsObject*   object, void *data)\n{\n\tif (es_symbol_p(object))\n    {\n\t\tvoid* old_data;\n\n\t\told_data = ((EsSymbol*)object)->data;\n\t\t((EsSymbol*)object)->data = data;\n\t\treturn  old_data;\n    }\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; es_symbol_set_data, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\treturn NULL;\n    }\n}\n\nvoid*        es_symbol_get_data (const EsObject*   object)\n{\n\tif (es_symbol_p(object))\n\t\treturn ((EsSymbol*)object)->data;\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; es_symbol_get_data, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\treturn NULL;\n    }\n}\n\nstatic void\nes_symbol_free(EsObject* object)\n{\n\t/* DO NOTHING */\n}\n\nstatic int\nes_symbol_equal(const EsObject* self, const EsObject* other)\n{\n\treturn (self == other)? 1: 0;\n}\n\nstatic void\nes_symbol_print(const EsObject* object, MIO* fp)\n{\n\tconst char* string;\n\tsize_t len;\n\tchar c;\n\tunsigned char cc;\n\tunsigned char mask;\n\tint needs_bar;\n\n\tstring = es_symbol_get(object);\n\tif (!string)\n\t\treturn;\n\n\tlen = strlen(string);\n\tif (len == 0)\n\t\tneeds_bar = 1;\n\n\tc = string[0];\n\tcc = get_char_class(c);\n\tmask = 0x1;\n\tneeds_bar = (cc & mask)? 1: 0;\n\tif (!needs_bar)\n    {\n\t\t/* 0 => 1? */\n\t\tmask = 0x2;\n\t\tfor (size_t i = 0; i< len; i++)\n\t\t{\n\t\t\tc = string[i];\n\t\t\tcc = get_char_class(c);\n\t\t\tneeds_bar = (cc & mask)? 1: 0;\n\t\t\tif (needs_bar)\n\t\t\t\tbreak;\n\t\t}\n\n    }\n\n\tif (needs_bar)\n\t\tmio_printf(fp, \"|\");\n\n\tfor (size_t i = 0; i < len; i++)\n    {\n\t\tc = string[i];\n\t\tif (c == '\\\\' || c == '|')\n\t\t\tmio_printf(fp, \"\\\\\");\n\t\tmio_printf(fp, \"%c\", c);\n    }\n\n\tif (needs_bar)\n\t\tmio_printf(fp, \"|\");\n}\n\n\n/*\n * symbol.c - symbol implementation\n *\n *   Copyright (c) 2000-2007  Shiro Kawai  <shiro@acm.org>\n *\n *   Redistribution and use in source and binary forms, with or without\n *   modification, are permitted provided that the following conditions\n *   are met:\n *\n *   1. Redistributions of source code must retain the above copyright\n *      notice, this list of conditions and the following disclaimer.\n *\n *   2. Redistributions in binary form must reproduce the above copyright\n *      notice, this list of conditions and the following disclaimer in the\n *      documentation and/or other materials provided with the distribution.\n *\n *   3. Neither the name of the authors nor the names of its contributors\n *      may be used to endorse or promote products derived from this\n *      software without specific prior written permission.\n *\n *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n *  $Id: symbol.c,v 1.40 2007/09/13 12:30:28 shirok Exp $\n */\n/* table of special chars.\n   bit 0: bad char for symbol to begin with\n   bit 1: bad char for symbol to contain\n   bit 2: bad char for symbol, and should be written as \\nnn\n   bit 3: bad char for symbol, and should be written as \\c\n   bit 4: may be escaped when case fold mode\n*/\nstatic char symbol_special[] = {\n\t/* NUL .... */\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t/* .... */\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t/*    !  \"  #  $  %  &  '  (  )  *  +  ,  -  .  /  */\n\t3, 0, 3, 3, 0, 0, 0, 3, 3, 3, 0, 1, 3, 1, 1, 0,\n\t/* 0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?  */\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, 0, 0, 0, 0,\n\t/* @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  */\n\t1, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n\t/* P  Q  R  S  T  U  V  W  X  Y  Z  [  \\  ]  ^  _  */\n\t16,16,16,16,16,16,16,16,16,16,16,3, 11,3, 0, 0,\n\t/* `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  */\n\t3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t/* p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~  ^? */\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 11,3, 0, 7\n};\n\n/* symbol_special[':'] was 1 in the symbol.c of Gauche.\n   However I modified it to 0.\n   Because a keyword is a just a symbol started from `:'\n   in Es. */\nstatic unsigned char\nget_char_class(int c)\n{\n\treturn (c < 0)? 0xff: symbol_special[c];\n}\n\n/*\n * String\n */\nEsObject*\nes_string_new  (const char*        value)\n{\n\tEsObject* r;\n\n\tr = es_object_new(ES_TYPE_STRING);\n\t((EsString*)r)->value = strdup(value);\n\treturn r;\n}\n\nEsObject*\nes_string_newL (const char* value, size_t len)\n{\n\tEsObject* r;\n\n\tr = es_object_new(ES_TYPE_STRING);\n\tif (es_error_p (r))\n\t\treturn r;\n\n\tvoid * v = malloc (len + 1);\n\tif (v == NULL)\n\t{\n\t\t((EsString*)r)->value = NULL;\n\t\tes_object_free (r);\n\t\treturn ES_ERROR_MEMORY;\n\t}\n\tmemcpy (v, value, len);\n\t((char *)v)[len] = '\\0';\n\t((EsString*)r)->value = v;\n\treturn r;\n}\n\nint\nes_string_p    (const EsObject*   object)\n{\n\treturn es_object_type_p(object, ES_TYPE_STRING);\n}\n\nconst char*\nes_string_get  (const EsObject*   object)\n{\n\tif (es_string_p(object))\n\t\treturn ((EsString *)object)->value;\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; es_string_get, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\treturn NULL;\n    }\n}\n\nstatic void\nes_string_free(EsObject* object)\n{\n\tif (es_string_p(object))\n    {\n\t\tfree(((EsString*) object)->value);\n\t\t((EsString*) object)->value = NULL;\n\t\tes_object_free(object);\n    }\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; Internal error: \\n\");\n\t\tmio_printf(mio_stderr(), \";;es_string_free, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n    }\n}\n\n\nstatic int\nes_string_equal(const EsObject* self, const EsObject* other)\n{\n\tif (es_string_p(other))\n    {\n\t\treturn (!strcmp(es_string_get(self), es_string_get(other)));\n    }\n\telse\n\t\treturn 0;\n}\n\nstatic void\nes_string_print(const EsObject* object, MIO* fp)\n{\n\tconst char* string;\n\tchar  c;\n\tsize_t len;\n\tsize_t   i;\n\n\n\tstring = es_string_get(object);\n\tlen    = strlen(string);\n\n\tmio_printf(fp, \"\\\"\");\n\n\tfor (i = 0; i < len; i++)\n    {\n\t\tchar cc;\n\n\t\tc = string[i];\n\t\tswitch (c)\n\t\t{\n\t\tcase '\\n':\n\t\t\tcc = 'n';\n\t\t\tbreak;\n\t\tcase '\\t':\n\t\t\tcc = 't';\n\t\t\tbreak;\n\t\tcase '\\r':\n\t\t\tcc = 'r';\n\t\t\tbreak;\n\t\tcase '\\f':\n\t\t\tcc = 'f';\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tcc = 0;\n\t\t\tbreak;\n\t\t}\n\t\tif (cc)\n\t\t{\n\t\t\tmio_printf(fp, \"\\\\\");\n\t\t\tmio_printf(fp, \"%c\", cc);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (c == '\\\\' || c == '\"')\n\t\t\tmio_printf(fp, \"\\\\\");\n\t\tmio_printf(fp, \"%c\", c);\n    }\n\n\tmio_printf(fp, \"\\\"\");\n}\n\n/*\n * Cons\n */\nEsObject*\nes_cons        (EsObject* car, EsObject* cdr)\n{\n\tEsObject* r;\n\n\tif (!es_list_p(cdr))\n    {\n\t\t/* This library doesn't permit to dotted list. */\n\t\treturn es_nil;\n    }\n\n\n\tr = es_object_new(ES_TYPE_CONS);\n\tif (es_error_p (r))\n\t\treturn r;\n\tif (es_debug)\n    {\n\t\tmio_printf(mio_stderr(), \";; cons[0x%p] = (0x%p . 0x%p)\\n\", r, car, cdr);\n\t\t/* es_print(car, mio_stderr());\n\t\t   mio_putc('\\n', mio_stderr());\n\t\t   es_print(cdr, mio_stderr());\n\t\t   mio_putc('\\n', mio_stderr()); */\n    }\n\t((EsCons*)r)->car = es_object_ref(car);\n\t((EsCons*)r)->cdr = es_object_ref(cdr);\n\n\treturn r;\n}\n\nint\nes_cons_p      (const EsObject* object)\n{\n\treturn es_object_type_p(object, ES_TYPE_CONS);\n}\n\nint\nes_list_p      (const EsObject* object)\n{\n\tEsType t;\n\n\tt = es_object_get_type(object);\n\treturn (t == ES_TYPE_NIL || t == ES_TYPE_CONS);\n}\n\nEsObject*\nes_car         (const EsObject* object)\n{\n\tif (es_cons_p(object))\n\t\treturn ((EsCons*)object)->car;\n\telse if (es_null(object))\n\t\treturn es_nil;\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; es_car, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\treturn es_nil;\n    }\n}\n\nEsObject*\nes_cdr         (const EsObject* object)\n{\n\tif (es_cons_p(object))\n\t\treturn ((EsCons*)object)->cdr;\n\telse if (es_null(object))\n\t\treturn es_nil;\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; es_cdr, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\treturn es_nil;\n    }\n}\n\nstatic void\nes_cons_free(EsObject* object)\n{\n\tEsCons* cons;\n\n\tif (es_cons_p(object))\n    {\n\t\tcons = ((EsCons*)object);\n\n\t\tes_object_unref(cons->car);\n\t\tcons->car = NULL;\n\n\t\tes_object_unref(cons->cdr);\n\t\tcons->cdr = NULL;\n\t\tes_object_free(object);\n    }\n\telse if (es_null(object))\n\t\t;\t\t\t\t/* DO NOTHING */\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; Internal error: \\n\");\n\t\tmio_printf(mio_stderr(), \";; es_cons_free, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n    }\n}\n\nstatic int\nes_cons_equal(const EsObject* self, const EsObject* other)\n{\n\treturn (es_null(other)\n\t\t\t|| (!es_cons_p(other))\n\t\t\t|| (!es_object_equal(es_car(self), es_car(other)))\n\t\t\t|| (!es_object_equal(es_cdr(self), es_cdr(other))))\n\t\t? 0\n\t\t: 1;\n}\n\nstatic void\nes_cons_print(const EsObject* object, MIO* fp)\n{\n\tEsObject* car;\n\tEsObject* cdr;\n\n\tmio_printf(fp, \"(\");\n\twhile(!es_null(object))\n    {\n\t\tcar = es_car(object);\n\t\tcdr = es_cdr(object);\n\n\t\tes_print(car, fp);\n\t\tif (es_cons_p(cdr))\n\t\t\tmio_putc(fp, ' ');\n\t\telse if (!es_null(cdr))\n\t\t{\n\t\t\tmio_printf(mio_stderr(), \";; es_cons_print, dotted list given: \");\n\t\t\tmio_putc(mio_stderr(), '\\n');\n\t\t}\n\t\tobject = cdr;\n    }\n\tmio_printf(fp, \")\");\n}\n\nstatic EsObject* es_cons_reverse_rec(EsObject* cdr,\n\t\t\t\t\t\t\t\t\t EsObject* car,\n\t\t\t\t\t\t\t\t\t EsObject* gathered);\n\nstatic EsObject*\nes_cons_reverse  (EsObject*        cons)\n{\n\t/* g_return_val_if_fail (es_null(cons) || es_cons_p(cons), es_nil);\n\t   g_return_val_if_fail (!es_cproc_dotted_p(cons), es_nil); */\n\n\tif (es_null(cons))\n\t\treturn es_nil;\n\telse\n\t\treturn es_cons_reverse_rec(es_cdr(cons),\n\t\t\t\t\t\t\t\t   es_car(cons),\n\t\t\t\t\t\t\t\t   es_nil);\n}\n\nEsObject*\nes_reverse  (EsObject* cons)\n{\n\treturn es_cons_reverse(cons);\n}\n\nstatic EsObject*\nes_cons_reverse_rec(EsObject* cdr,\n\t\t\t\t\tEsObject* car,\n\t\t\t\t\tEsObject* gathered)\n{\n\tEsObject* cons;\n\tEsObject* o;\n\n\tcons = es_cons(car, o = gathered);\n\tes_object_unref(o);\n\n\tif (es_null(cdr))\n\t\treturn cons;\n\telse\n\t\treturn es_cons_reverse_rec(es_cdr(cdr),\n\t\t\t\t\t\t\t\t   es_car(cdr),\n\t\t\t\t\t\t\t\t   cons);\n}\n\n/*\n * Regex\n */\nEsObject*\nes_regex_compile   (const char* pattern_literal, int case_insensitive)\n{\n\tEsObject* r;\n\tregex_t *code;\n\tint err;\n\tint flag = REG_EXTENDED | REG_NEWLINE\n\t\t| (case_insensitive? REG_ICASE: 0);\n\n\tcode = malloc(sizeof(regex_t));\n\tif (!code)\n\t\treturn ES_ERROR_MEMORY;\n\n\terr = regcomp(code, pattern_literal,\n\t\t\t\t  flag);\n\tif (err)\n\t{\n#if 0\n/* TODO: This should be reported to caller. */\n\t\tchar errmsg [256];\n\t\tregerror (err, code, errmsg, 256);\n#endif\n\t\tregfree (code);\n\t\tfree (code);\n\t\treturn ES_ERROR_REGEX;\n\t}\n\n\tr = es_object_new(ES_TYPE_REGEX);\n\t((EsRegex*)r)->code = code;\n\t((EsRegex*)r)->literal = strdup(pattern_literal);\n\tif (!((EsRegex*)r)->literal)\n\t{\n\t\tregfree(((EsRegex*)r)->code);\n\t\tfree(((EsRegex*)r)->code);\n\t\tes_object_free(r);\n\t\treturn ES_ERROR_MEMORY;\n\t}\n\t((EsRegex*)r)->case_insensitive = case_insensitive;\n\treturn r;\n}\n\nint\nes_regex_p   (const EsObject*   object)\n{\n\treturn es_object_type_p(object, ES_TYPE_REGEX);\n}\n\nstatic void es_regex_free(EsObject* object)\n{\n\tfree(((EsRegex*)object)->literal);\n\tregfree(((EsRegex*)object)->code);\n\tfree(((EsRegex*)object)->code);\n\tes_object_free(object);\n}\n\nstatic int\nes_regex_equal(const EsObject* self, const EsObject* other)\n{\n\treturn (es_regex_p (other)\n\t\t\t&& (strcmp (((EsRegex*)self)->literal,\n\t\t\t\t\t\t((EsRegex*)other)->literal) == 0)\n\t\t\t&& (((EsRegex*)self)->case_insensitive ==\n\t\t\t\t((EsRegex*)other)->case_insensitive));\n}\n\nstatic void\nes_regex_print(const EsObject* object, MIO* fp)\n{\n\tmio_puts(fp, \"#/\");\n\tconst char *s = ((EsRegex*)object)->literal;\n\twhile (*s)\n\t{\n\t\tif (*s == '/')\n\t\t\tmio_putc(fp, '\\\\');\n\t\tmio_putc(fp, *s);\n\t\ts++;\n\t}\n\tmio_putc(fp, '/');\n\tif (((EsRegex*)object)->case_insensitive)\n\t\tmio_putc(fp, 'i');\n}\n\nEsObject*\nes_regex_exec    (const EsObject* regex,\n\t\t\t\t  const EsObject* str)\n{\n\treturn regexec (((EsRegex*)regex)->code, es_string_get (str),\n\t\t\t\t\t0, NULL, 0)? es_false: es_true;\n}\n\nEsObject*\nes_regex_exec_extract_match_new (const EsObject* regex,\n\t\t\t\t\t\t\t\t const EsObject* str,\n\t\t\t\t\t\t\t\t unsigned int group)\n{\n\tEsObject *r;\n\tregmatch_t *pmatch = calloc(group + 1, sizeof(regmatch_t));\n\tif (!pmatch)\n\t\treturn ES_ERROR_MEMORY;\n\n\tconst char *s = es_string_get (str);\n\tif (regexec(((EsRegex*)regex)->code, s, group + 1, pmatch, 0))\n\t\tr = es_false;\n\telse\n\t\tr = pmatch[group].rm_so == -1\n\t\t\t? es_nil:\n\t\t\tes_string_newL(s + pmatch[group].rm_so,\n\t\t\t\t\t\t   pmatch[group].rm_eo - pmatch[group].rm_so);\n\n\tfree (pmatch);\n\treturn r;\n}\n\n/*\n * Error\n */\nEsObject*\nes_error_intern  (const char*       name)\n{\n\tEsSingleton* r;\n\n\tr = es_obarray_intern(ES_TYPE_ERROR, name);\n\treturn (EsObject*)r;\n}\n\nint\nes_error_p    (const EsObject*   object)\n{\n\treturn es_object_type_p(object, ES_TYPE_ERROR);\n}\n\nconst char*\nes_error_name  (const EsObject*   object)\n{\n\tif (es_error_p(object))\n\t\treturn es_singleton_get((EsSingleton *)object);\n\telse\n    {\n\t\tmio_printf(mio_stderr(), \";; es_error_name, Wrong type argument: \");\n\t\tes_print(object, mio_stderr());\n\t\tmio_putc(mio_stderr(), '\\n');\n\t\treturn NULL;\n    }\n}\n\nEsObject*\nes_error_set_object (EsObject*   error, EsObject*   object)\n{\n\tEsError *e = (EsError *)error;\n\tif (e->object)\n\t\tes_object_unref (e->object);\n\n\te->object = es_object_ref (object);\n\treturn error;\n}\n\nEsObject*\nes_error_get_object (const EsObject*   error)\n{\n\tEsError *e = (EsError *)error;\n\treturn e->object;\n}\n\nstatic void\nes_error_free(EsObject* object)\n{\n\t/* DO NOTHING */\n}\n\nstatic int\nes_error_equal(const EsObject* self, const EsObject* other)\n{\n\treturn (self == other)? 1: 0;\n}\n\nstatic void\nes_error_print(const EsObject* object, MIO* fp)\n{\n\tconst char* string;\n\tEsError *e = (EsError *)object;\n\n\tstring = es_error_name(object);\n\tmio_printf(fp, \"#%s:\", string);\n\tes_print (e->object, fp);\n}\n\n/*\n * Foreigner\n */\ntypedef struct _EsPointerClass EsPointerClass;\nstruct _EsPointerClass\n{\n\tEsObjectClass base;\n\n\tsize_t fat_size;\n\tEsObject *(* init_fat) (void *fat, void * ptr, void *extra);\n\n\tvoid (* free_ptr) (void *);\n\tint  (* equal_ptr) (const void*, const void*);\n\tvoid (* print_ptr) (const void*, MIO *);\n\n\n\tvoid (* free_fatptr) (void *, void *);\n\tint  (* equal_fatptr) (const void*, const void*,\n\t\t\t\t\t\t   const void*, const void*);\n\tvoid (* print_fatptr) (const void*, const void*, MIO *);\n};\n\nstatic EsType\nes_type_define_pointer_full(const char *name,\n\t\t\t\t\t\t\tsize_t fat_size,\n\t\t\t\t\t\t\tEsObject *(* initfat_fn) (void *fat, void * ptr, void *extra),\n\t\t\t\t\t\t\tvoid (* freefn) (void *),\n\t\t\t\t\t\t\tint  (* equalfn) (const void*, const void*),\n\t\t\t\t\t\t\tvoid (* printfn) (const void*, MIO *),\n\t\t\t\t\t\t\tvoid (* freefn_fat)  (void * ptr, void *fat),\n\t\t\t\t\t\t\tint  (* equalfn_fat) (const void* ptr_a, const void* fat_a,\n\t\t\t\t\t\t\t\t\t\t\t\t  const void* ptr_b, const void* fat_b),\n\t\t\t\t\t\t\tvoid (* printfn_fat) (const void* ptr, const void *fat, MIO *))\n{\n\tEsType t = ES_TYPE_NIL;\n\tif (classes_count >= ES_TYPE_CLASS_MAX)\n\t\treturn t;\n\n\tEsPointerClass *c = calloc (1, sizeof (EsPointerClass));\n\tif (c == NULL)\n\t\treturn t;\n\n\tc->fat_size  = fat_size;\n\tc->init_fat = initfat_fn;\n\tc->free_ptr  = freefn;\n\tc->equal_ptr = equalfn;\n\tc->print_ptr = printfn;\n\tc->free_fatptr  = freefn_fat;\n\tc->equal_fatptr = equalfn_fat;\n\tc->print_fatptr = printfn_fat;\n\n\tc->base.size  = sizeof (EsPointer) + c->fat_size;\n\tc->base.free  = es_pointer_free;\n\tc->base.equal = es_pointer_equal;\n\tc->base.print = es_pointer_print;\n\tc->base.flags = ES_OBJECT_FLAG_ATOM;\n\tc->base.name  = strdup (name);\n\tif (c->base.name == NULL)\n\t{\n\t\tfree (c);\n\t\treturn t;\n\t}\n\n\tt = classes_count++;\n\tclasses [t] = (EsObjectClass *)c;\n\n\treturn t;\n}\n\nEsType\nes_type_define_pointer(const char *name,\n\t\t\t\t\t   void (* freefn) (void *),\n\t\t\t\t\t   int  (* equalfn) (const void*, const void*),\n\t\t\t\t\t   void (* printfn) (const void*, MIO *))\n{\n\n\treturn es_type_define_pointer_full (name, 0, NULL,\n\t\t\t\t\t\t\t\t\t\tfreefn, equalfn, printfn,\n\t\t\t\t\t\t\t\t\t\tNULL, NULL, NULL);\n}\n\nEsType\nes_type_define_fatptr    (const char *name,\n\t\t\t\t\t\t  size_t fat_size,\n\t\t\t\t\t\t  EsObject *(* initfat_fn) (void *fat, void * ptr, void *extra),\n\t\t\t\t\t\t  void (* freefn) (void * ptr, void *fat),\n\t\t\t\t\t\t  int  (* equalfn) (const void* ptr_a, const void* fat_a,\n\t\t\t\t\t\t\t\t\t\t\tconst void* ptr_b, const void* fat_b),\n\t\t\t\t\t\t  void (* printfn) (const void* ptr, const void *fat, MIO *))\n{\n\treturn es_type_define_pointer_full (name, fat_size, initfat_fn,\n\t\t\t\t\t\t\t\t\t\tNULL, NULL, NULL,\n\t\t\t\t\t\t\t\t\t\tfreefn, equalfn, printfn);\n}\n\nstatic void es_pointer_free(EsObject* object)\n{\n\tEsObjectClass *c = class_of(object);\n\tif (((EsPointer*)object)->ptr)\n\t{\n\t\tif (((EsPointerClass *)c)->free_fatptr)\n\t\t\t((EsPointerClass *)c)->free_fatptr (((EsPointer*)object)->ptr,\n\t\t\t\t\t\t\t\t\t\t\t\t((EsPointer*)object)->fat);\n\t\telse if (((EsPointerClass *)c)->free_ptr)\n\t\t\t((EsPointerClass *)c)->free_ptr (((EsPointer*)object)->ptr);\n\t}\n\tes_object_free (object);\n}\n\nstatic int  es_pointer_equal(const EsObject* self, const EsObject* other)\n{\n\tif (es_object_get_type (self) != es_object_get_type (other))\n\t\treturn 0;\n\n\tEsPointerClass *c = (EsPointerClass *)class_of(self);\n\tvoid *self_ptr  = ((EsPointer *)self)->ptr;\n\tvoid *other_ptr = ((EsPointer *)other)->ptr;\n\n\tif (c->fat_size == 0 && self_ptr == other_ptr)\n\t\treturn 1;\n\n\tif (self_ptr == NULL)\n\t\treturn 0;\n\n\tif (c->equal_fatptr)\n\t\treturn c->equal_fatptr (self_ptr, ((EsPointer*)self)->fat,\n\t\t\t\t\t\t\t\tother_ptr, ((EsPointer*)other)->fat);\n\telse if (c->equal_ptr)\n\t\treturn c->equal_ptr (self_ptr, other_ptr);\n\treturn 0;\n}\n\nstatic void es_pointer_print(const EsObject* object, MIO* fp)\n{\n\tEsObjectClass *c = class_of(object);\n\tif (((EsPointerClass *)c)->print_fatptr)\n\t{\n\t\t((EsPointerClass *)c)->print_fatptr (((EsPointer *)object)->ptr,\n\t\t\t\t\t\t\t\t\t\t\t ((EsPointer *)object)->fat,\n\t\t\t\t\t\t\t\t\t\t\t fp);\n\t}\n\telse if (((EsPointerClass *)c)->print_ptr)\n\t{\n\t\t((EsPointerClass *)c)->print_ptr (((EsPointer *)object)->ptr, fp);\n\t}\n\telse\n\t{\n\t\tmio_puts(fp, \"#<\");\n\t\tmio_puts(fp, c->name);\n\t\tmio_putc(fp, ' ');\n\t\tmio_printf(fp, \"(%p, %p)\", object, ((EsPointer *)object)->ptr);\n\t\tmio_putc(fp, '>');\n\t}\n}\n\nstatic EsObject*\nes_pointer_new_common (EsType type, void *ptr)\n{\n\tEsObject *r;\n\n\tr = es_object_new (type);\n\tif (es_error_p (r))\n\t\treturn r;\n\n\t((EsPointer *)r)->ptr = ptr;\n\treturn r;\n}\n\n/*\n * Pointer\n */\nEsObject*\nes_pointer_new (EsType type, void *ptr)\n{\n\tEsObject *r = es_pointer_new_common (type, ptr);\n\tif (es_error_p (r))\n\t\treturn r;\n\n\tif (((EsPointerClass *) (classes [type]))->fat_size > 0)\n\t\tmemset(((EsPointer *)r)->fat, 0,\n\t\t\t   ((EsPointerClass *) (classes [type]))->fat_size);\n\treturn r;\n}\n\nvoid*\nes_pointer_get    (const EsObject *object)\n{\n\treturn ((EsPointer *)object)->ptr;\n}\n\nvoid*\nes_pointer_take    (EsObject *object)\n{\n\tvoid *r = ((EsPointer *)object)->ptr;\n\t((EsPointer *)object)->ptr = NULL;\n\treturn r;\n}\n\n/*\n * Fat pointer\n */\nEsObject*\nes_fatptr_new (EsType type, void *ptr, void *extra)\n{\n\tEsObject *r = es_pointer_new_common (type, ptr);\n\tif (es_error_p (r))\n\t\treturn r;\n\n\tif (((EsPointerClass *) (classes [type]))->fat_size > 0)\n\t{\n\t\tif (((EsPointerClass *) (classes [type]))->init_fat)\n\t\t{\n\t\t\tEsObject *f = (* ((EsPointerClass *) (classes [type]))->init_fat)\n\t\t\t\t(((EsPointer *)r)->fat, ptr, extra);\n\t\t\tif (es_error_p (f))\n\t\t\t{\n\t\t\t\tes_object_free (r);\n\t\t\t\treturn f;\n\t\t\t}\n\t\t}\n\t\telse if (extra)\n\t\t\tmemcpy (((EsPointer *)r)->fat, extra,\n\t\t\t\t\t((EsPointerClass *) (classes [type]))->fat_size);\n\t\telse\n\t\t\tmemset(((EsPointer *)r)->fat, 0,\n\t\t\t\t   ((EsPointerClass *) (classes [type]))->fat_size);\n\t}\n\treturn r;\n}\n\nvoid*\nes_fatptr_get     (const EsObject *object)\n{\n\tEsObjectClass *c = class_of(object);\n\tif (((EsPointerClass *)c)->fat_size == 0)\n\t\treturn NULL;\n\n\treturn ((EsPointer *)object)->fat;\n}\n\n\f\n\n/* http://www.cse.yorku.ca/~oz/hash.html */\nstatic unsigned long\ndjb2(unsigned char *str)\n{\n\tunsigned long hash = 5381;\n\tint c;\n\n\twhile ((c = *str++))\n\t\thash = ((hash << 5) + hash) + c; /* hash * 33 + c */\n\n\treturn hash;\n}\n\nstatic unsigned int hash(const char* keyarg)\n{\n\treturn ((unsigned int)djb2((unsigned char *)keyarg)) % OBARRAY_SIZE;\n}\n\f\n/*\n * Print\n */\nvoid\nes_print           (const EsObject* object,\n\t\t\t\t\tMIO*           out)\n{\n\tclass_of(object)->print(object, out? out: mio_stdout());\n}\n\n\nchar*\nes_print_to_string (EsObject*        object)\n{\n\tchar *bp;\n\tsize_t size;\n\tMIO* out;\n\n\n\tout = mio_new_memory (NULL, 0, realloc, NULL);\n\tif (!out)\n    {\n\t\t/* TODO: Report error */\n\t\treturn NULL;\n    }\n\n\tes_print(object, out);\n\tbp = (char *)mio_memory_get_data (out, &size);\n\tmio_unref(out);\n\n\treturn bp;\n}\n\nstatic const char* comment_prefix = \";; \";\nvoid\nes_comment (const char* comment, MIO* out)\n{\n\tconst char* p;\n\tconst char* c;\n\n\tp = comment_prefix? comment_prefix: \";; \";\n\tc = comment? comment: \"\";\n\tout = out? out: mio_stdout();\n\n\t/* \"\"\n\t   => ;;\n\n\t   \"a\"\n\t   => ;; a\n\n\t   \"a\\n\"\n\t   => ;; a\n\n\n\t   \"a\\nb\"\n\t   => ;; a\n\t   ;; b\n\n\t   \"a\\nb\\n\"\n\t   => ;; a\n\t   ;;b\n\n\n\t*/\n\twhile (1)\n    {\n\t\tmio_puts(out, p);\n\n\t\twhile(1)\n\t\t{\n\t\t\tif (*c == '\\0')\n\t\t\t{\n\t\t\t\tmio_putc(out, '\\n');\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmio_putc(out, *c++);\n\t\t\t\tif (*(c - 1) == '\\n')\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n    }\n}\n\nchar*\nes_comment_to_string (const char* comment)\n{\n\tchar *bp;\n\tsize_t size;\n\tMIO* out;\n\n\tout = mio_new_memory (NULL, 0, realloc, NULL);\n\tif (!out)\n    {\n\t\t/* TODO: Report error */\n\t\treturn NULL;\n    }\n\n\tes_comment(comment, out);\n\tbp = (char *)mio_memory_get_data (out, &size);\n\tmio_unref(out);\n\n\treturn bp;\n}\n\n\n\n\f\n/*\n * Read\n */\ntypedef struct _Token Token;\nstruct _Token\n{\n\tchar*  buffer;\n\tsize_t filled;\n\tsize_t allocated;\n};\nstatic Token* token_new   (char seed);\nstatic void   token_free  (Token* token);\nstatic Token* token_append(Token* token, char c);\n\nstatic Token  eof_token;\n#define EOF_TOKEN         (&eof_token)\nstatic Token  open_paren_token;\n#define OPEN_PAREN_TOKEN  (&open_paren_token)\nstatic Token  close_paren_token;\n#define CLOSE_PAREN_TOKEN (&close_paren_token)\n\nstatic Token*   get_token      (MIO* in);\nstatic void     skip_to_newline(MIO* in);\nstatic int      is_whitespace    (char c);\nstatic int      is_paren_open    (char c);\nstatic int      is_paren_close   (char c);\nstatic int      is_comment_start (char c);\nstatic int      is_string_start  (char c);\nstatic int      is_fence_start   (char c);\nstatic int      is_reader_macro_prefix(char c);\n\ntypedef\nint (*TerminalDetector) (int c);\n\nstatic int is_string_end       (int c);\nstatic int is_fence_end        (int c);\nstatic int is_separator        (int c);\n\nstatic Token* get_sequence      (MIO* fp,\n\t\t\t\t\t\t\t\t Token* seed,\n\t\t\t\t\t\t\t\t TerminalDetector is_terminator,\n\t\t\t\t\t\t\t\t int              include_terminator);\nstatic Token* get_string        (MIO* fp, char seed);\nstatic Token* get_escaped_symbol(MIO* fp, char seed);\nstatic Token* get_symbol        (MIO* fp, char seed);\nstatic Token* get_regex         (MIO* fp);\nstatic void   inject_regex_flag (Token* t, char c);\n\nstatic EsObject* fill_list    (MIO*  fp);\nstatic EsObject* make_atom    (Token* token);\nstatic EsObject* make_string  (char* t);\nstatic EsObject* make_symbol  (char* t,\n\t\t\t\t\t\t\t   int is_wrapped);\nstatic EsObject* make_boolean (int b);\nstatic int  is_integer   (const char* t,\n\t\t\t\t\t\t  int* i);\nstatic EsObject* make_integer (int  i);\nstatic int  is_real      (const char* t,\n\t\t\t\t\t\t  double* d);\nstatic EsObject* make_real    (double d);\nstatic EsObject* make_regex (const char *pat,\n\t\t\t\t\t\t\t int case_insensitive);\n\n\nEsObject*\nes_read            (MIO* in)\n{\n\tToken* t;\n\tEsObject* r;\n\n\n\tin = in? in: mio_stdin();\n\n\tt = get_token(in);\n\n\tif (t == NULL)\n\t\treturn ES_READER_ERROR;\n\telse if (t == EOF_TOKEN)\n\t\treturn ES_READER_EOF;\n\telse if (t == OPEN_PAREN_TOKEN)\n\t\tr = fill_list(in);\n\telse if (t == CLOSE_PAREN_TOKEN)\n\t\treturn ES_READER_ERROR;\n\telse\n\t\tr = make_atom(t);\n\n\ttoken_free(t);\n\n\treturn r;\n}\n\n\nstatic Token*\nget_token(MIO* in)\n{\n\tToken* t;\n\n\tint c;\n\twhile (1)\n    {\n\t\tc = mio_getc(in);\n\n\t\tif (c == EOF)\n\t\t{\n\t\t\tt = EOF_TOKEN;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tchar c0;\n\n\t\t\tc0 = (char)c;\n\n\t\t\tif (is_whitespace(c0))\n\t\t\t\tcontinue;\n\t\t\telse if (is_comment_start(c0))\n\t\t\t{\n\t\t\t\tskip_to_newline(in);\n\t\t\t\t/* TODO */\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (is_paren_open(c0))\n\t\t\t{\n\t\t\t\tt = OPEN_PAREN_TOKEN;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (is_paren_close(c0))\n\t\t\t{\n\t\t\t\tt = CLOSE_PAREN_TOKEN;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (is_string_start(c0))\n\t\t\t{\n\t\t\t\tt = get_string(in, c0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (is_fence_start(c0))\n\t\t\t{\n\t\t\t\tt = get_escaped_symbol(in, c0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (is_reader_macro_prefix(c0))\n\t\t\t{\n\t\t\t\tc = mio_getc(in);\n\t\t\t\tif (c == EOF)\n\t\t\t\t{\n\t\t\t\t\tt = get_symbol(in, c0);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if (c == '/')\n\t\t\t\t{\n\t\t\t\t\tt = get_regex(in);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmio_ungetc (in, c);\n\t\t\t\t\tt = get_symbol(in, c0);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tt = get_symbol(in, c0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n    }\n\n\treturn t;\n}\n\nstatic int\nis_whitespace    (char c)\n{\n\tstatic const char* const whitespace_chars = \" \\t\\n\\r\\f\";\n\n\treturn strchr(whitespace_chars, c)? 1: 0;\n}\n\nstatic int\nis_paren_open    (char c)\n{\n\treturn (c == '(')? 1: 0;\n}\n\nstatic int\nis_paren_close   (char c)\n{\n\treturn (c == ')')? 1: 0;\n}\n\nstatic int\nis_comment_start (char c)\n{\n\treturn (c == ';')? 1: 0;\n}\n\nstatic int\nis_string_start  (char c)\n{\n\treturn (c == '\"')? 1: 0;\n}\n\nstatic int\nis_fence_start  (char c)\n{\n\treturn (c == '|')? 1: 0;\n}\n\nstatic int\nis_reader_macro_prefix(char c)\n{\n\treturn (c == '#')? 1: 0;\n}\n\nstatic void\nskip_to_newline  (MIO* fp)\n{\n\tint c;\n\n\n\twhile (1)\n    {\n\t\tchar c0;\n\n\n\t\tc = mio_getc(fp);\n\t\tif (c == EOF)\n\t\t\tbreak;\n\n\t\tc0 = (char)c;\n\t\tif (c0 == '\\n')\n\t\t\tbreak;\n    }\n}\n\nstatic int\nis_string_end    (int c)\n{\n\treturn ((char)(c) == '\"')? 1: 0;\n}\n\nstatic int\nis_fence_end     (int c)\n{\n\treturn ((char)(c) == '|')? 1: 0;\n}\n\nstatic int\nis_separator     (int c)\n{\n\tif (c == EOF)\n\t\treturn 1;\n\telse\n    {\n\t\tchar c0;\n\n\n\t\tc0 = (char)(c);\n\t\tif (is_whitespace(c0)\n\t\t\t|| is_comment_start(c0)\n\t\t\t|| is_paren_open(c0)\n\t\t\t|| is_paren_close(c0)\n\t\t\t|| is_string_start(c0)\n\t\t\t|| is_fence_start(c0))\n\t\t\treturn 1;\n    }\n\n\treturn 0;\n}\n\nstatic Token*\nget_string         (MIO* fp,\n\t\t\t\t\tchar seed)\n{\n\tToken* t;\n\n\tt = token_new(seed);\n\treturn get_sequence(fp, t, is_string_end, 1);\n}\n\nstatic Token*\nget_escaped_symbol (MIO* fp,\n\t\t\t\t\tchar seed)\n{\n\tToken* t;\n\n\tt = token_new(seed);\n\treturn get_sequence(fp, t, is_fence_end, 1);\n}\n\nstatic Token*\nget_symbol         (MIO* fp,\n\t\t\t\t\tchar seed)\n{\n\tToken* t;\n\n\tt = token_new(seed);\n\treturn get_sequence(fp, t, is_separator, 0);\n}\n\nstatic Token*\nget_regex (MIO* fp)\n{\n\tToken *t;\n\tt = token_new('#');\n\tif (!t)\n\t\treturn NULL;\n\n\tif (!token_append(t, '/'))\n\t\treturn NULL;\n\n\t/* Inject a placeholder representing\n\t * case-{in}sesitive. */\n\tif (!token_append(t, ' '))\n\t\treturn NULL;\n\n\tint c;\n\tint in_escape = 0;\n\twhile (1)\n\t{\n\t\tc = mio_getc(fp);\n\t\tif (EOF == c)\n\t\t{\n\t\t\t/* TODO: Propagate the error to upper layer. */\n\t\t\tmio_printf(mio_stderr(),\n\t\t\t\t\t   \";; unexpected termination during parsing regex pattern\\n\");\n\t\t\ttoken_free (t);\n\t\t\treturn NULL;\n\t\t}\n\n\t\tchar c0 = c;\n\t\tif (in_escape)\n\t\t{\n\t\t\tin_escape = 0;\n\n\t\t\tif (c0 == 'n')\n\t\t\t\tc0 = '\\n';\n\t\t\telse if (c0 == 't')\n\t\t\t\tc0 = '\\t';\n\t\t\telse if (c0 != '/')\n\t\t\t{\n\t\t\t\tif (!token_append(t, '\\\\'))\n\t\t\t\t\treturn NULL;\n\t\t\t}\n\n\t\t\tif (!token_append(t, c0))\n\t\t\t\treturn NULL;\n\t\t}\n\t\telse if (c0 == '\\\\')\n\t\t\tin_escape = 1;\n\t\telse if (c0 == '/')\n\t\t{\n\t\t\tc = mio_getc(fp);\n\t\t\tif (c == 'i')\n\t\t\t\t/* Refill the placeholder. */\n\t\t\t\tinject_regex_flag (t, 'i');\n\t\t\telse if (c != EOF)\n\t\t\t\tmio_ungetc (fp, c);\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tif (!token_append(t, c0))\n\t\t\t\treturn NULL;\n\t}\n\treturn t;\n}\n\nstatic void\ndump_token (MIO* stream, const char* prefix, Token* seed)\n{\n\tconst char* buf;\n\tsize_t i;\n\tchar  c;\n\n\n\tbuf = seed->buffer;\n\tmio_printf(stream, \"%s\", prefix);\n\tfor (i = 0; i < ( seed->filled - 1 ); i++)\n    {\n\t\tc = buf[i];\n\t\tmio_putc(stream, c);\n\t\tif (buf[i] == '\\n')\n\t\t\tmio_printf(stream, \"%s\", prefix);\n    }\n\tmio_putc(mio_stderr(), '\\n');\n}\n\nstatic Token*\nget_sequence       (MIO* fp,\n\t\t\t\t\tToken* seed,\n\t\t\t\t\tTerminalDetector     is_terminator,\n\t\t\t\t\tint             include_terminator)\n{\n\tint c;\n\tint in_escape;\n\n\tin_escape = 0;\n\twhile (1)\n    {\n\t\tc = mio_getc(fp);\n\t\tif (EOF == c)\n\t\t{\n\t\t\tif (in_escape)\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t  throw ReadError(\"no character after escape character: \" + seed);\n\t\t\t\t*/\n\t\t\t\tmio_printf(mio_stderr(), \";; no character after escape character:\\n\");\n\t\t\t\t{\n\t\t\t\t\tseed = token_append(seed, '\\\\');\n\t\t\t\t\tdump_token(mio_stderr(), \"; \", seed);\n\t\t\t\t}\n\t\t\t\ttoken_free(seed);\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\telse if (is_terminator(c))\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t  throw ReadError(\"got EOF during reading a sequence: \" + seed);\n\t\t\t\t*/\n\t\t\t\tmio_printf(mio_stderr(), \";; got EOF during reading a sequence: \\n\");\n\t\t\t\tdump_token(mio_stderr(), \"; \", seed);\n\t\t\t\ttoken_free(seed);\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tchar c0;\n\n\n\t\t\tc0 = (char)(c);\n\t\t\tif (in_escape)\n\t\t\t{\n\t\t\t\tswitch (c0)\n\t\t\t\t{\n\t\t\t\tcase 'n': c0 = '\\n'; break;\n\t\t\t\tcase 't': c0 = '\\t'; break;\n\t\t\t\tcase 'r': c0 = '\\r'; break;\n\t\t\t\tcase 'f': c0 = '\\f'; break;\n\t\t\t\tdefault:  break;\n\t\t\t\t}\n\t\t\t\tseed = token_append(seed, c0);\n\t\t\t\tin_escape = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (c0 == '\\\\')\n\t\t\t{\n\t\t\t\tin_escape = 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (is_terminator(c))\n\t\t\t{\n\t\t\t\tif (include_terminator)\n\t\t\t\t\tseed = token_append(seed, c0);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (mio_ungetc(fp, c) == EOF)\n\t\t\t\t\t{\n\t\t\t\t\t\ttoken_free(seed);\n\t\t\t\t\t\treturn NULL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tseed = token_append(seed, c0);\n\t\t\t\tin_escape = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n    }\n\treturn seed;\n}\n\n\n/*\n  (let ((total-length 0)\n  (count-symbol 0))\n  (mapatoms (lambda (s) (setq total-length (+ total-length (length (symbol-name s)))\n  count-symbol (+ 1 count-symbol)\n  )))\n  (/ total-length count-symbol)) => 15\n*/\n#define DEFAULT_TOKEN_LENGHT 16\nstatic Token*\ntoken_new   (char seed)\n{\n\tToken *t;\n\n\n\tt = malloc(sizeof(Token));\n\tif (!t)\n\t\treturn NULL;\n\n\tt->buffer = calloc(1, sizeof(char) * DEFAULT_TOKEN_LENGHT);\n\tif (!t->buffer)\n    {\n\t\tfree(t);\n\t\treturn NULL;\n    }\n\n\tt->filled = 0;\n\tt->buffer[t->filled++] = seed;\n\tt->buffer[t->filled++]   = '\\0';\n\tt->allocated = DEFAULT_TOKEN_LENGHT;\n\n\treturn t;\n}\n\nstatic void\ntoken_free  (Token* token)\n{\n\tif ((token == NULL)\n\t\t|| (token == EOF_TOKEN)\n\t\t|| (token == OPEN_PAREN_TOKEN)\n\t\t|| (token == CLOSE_PAREN_TOKEN))\n\t\treturn;\n\n\n\tfree(token->buffer);\n\ttoken->buffer = NULL;\n\tfree(token);\n}\n\nstatic Token*\ntoken_append(Token* t, char c)\n{\n\tsize_t d;\n\n\n\td = t->allocated - t->filled;\n\tif (d < 1)\n    {\n\t\tchar* tmp;\n\n\t\ttmp = t->buffer;\n\t\tt->buffer = realloc(t->buffer, t->allocated *= 2);\n\t\tif (!t->buffer)\n\t\t{\n\t\t\tt->buffer = tmp;\n\t\t\ttoken_free(t);\n\t\t\treturn NULL;\n\t\t}\n    }\n\n\tt->buffer[t->filled - 1] = c;\n\tt->buffer[t->filled++]   = '\\0';\n\n\treturn t;\n}\n\n/* We use the third character of buffer\n * as a flag representing an option for\n * regex pattern.\n *\n * 'i': case_insensitive\n */\nstatic void\ninject_regex_flag(Token* t, char c)\n{\n\tt->buffer [2] = c;\n}\n\nstatic EsObject*\nfill_list (MIO* fp)\n{\n\tEsObject* r;\n\tToken*    t;\n\n\tr = es_nil;\n\twhile(1)\n    {\n\t\tt = get_token(fp);\n\t\tif (t == NULL)\n\t\t{\n\t\t\tes_object_unref(r);\n\t\t\treturn ES_READER_ERROR;\n\t\t}\n\t\telse if (t == EOF_TOKEN)\n\t\t{\n\t\t\tes_object_unref(r);\n\t\t\treturn ES_READER_ERROR;\n\t\t}\n\t\telse if (t == CLOSE_PAREN_TOKEN)\n\t\t{\n\t\t\tEsObject* tmp;\n\n\t\t\ttmp = es_cons_reverse(r);\n\t\t\tes_object_unref(r);\n\t\t\tr = tmp;\n\t\t\tbreak;\n\t\t}\n\t\telse if (t == OPEN_PAREN_TOKEN)\n\t\t{\n\t\t\tEsObject* car;\n\t\t\tEsObject* cdr;\n\n\t\t\tcar = fill_list(fp);\n\t\t\tif (es_error_p(car))\n\t\t\t{\n\t\t\t\tes_object_unref(r);\n\t\t\t\tr = car;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcdr = r;\n\t\t\tr = es_cons(car, cdr);\n\t\t\tes_object_unref(car);\n\t\t\tes_object_unref(cdr);\n\n\t\t\tcontinue;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tEsObject* car;\n\t\t\tEsObject* cdr;\n\n\t\t\tcar = make_atom(t);\n\t\t\ttoken_free(t);\n\n\t\t\tif (es_error_p (car))\n\t\t\t{\n\t\t\t\tes_object_unref(r);\n\t\t\t\tr = car;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcdr = r;\n\t\t\tr = es_cons(car, cdr);\n\t\t\tes_object_unref(car);\n\t\t\tes_object_unref(cdr);\n\n\t\t\tcontinue;\n\t\t}\n    }\n\n\treturn r;\n}\n\n\nstatic EsObject*\nmake_atom          (Token*   token)\n{\n\tEsObject* r;\n\tchar* t;\n\n\tint i;\n\tdouble d;\n\n\n\tt = token->buffer;\n\n\tif (t[0] == '\"')\n\t\tr = make_string(t);\n\telse if (t[0] == '|')\n\t\tr = make_symbol(t, 1);\n\telse if (strcmp(t, \"#t\") == 0)\n\t\tr = make_boolean(1);\n\telse if (strcmp(t, \"#f\") == 0)\n\t\tr = make_boolean(0);\n\telse if ((strncmp(t, \"#/\", 2) == 0)\n\t\t\t && t[2] != '\\0')\n\t\tr = make_regex (t + 3, (t[2] == 'i'));\n\telse if (is_integer(t, &i))\n    {\n\t\tr = make_integer(i);\n    }\n\telse if (is_real(t, &d))\n    {\n\t\tr = make_real(d);\n    }\n\telse\n\t\tr = make_symbol(t, 0);\n\n\treturn r;\n}\n\nstatic EsObject*\nmake_string  (char* t)\n{\n\tsize_t len;\n\n\n\tlen = strlen(t);\n\tt[(len - 1)] = '\\0';\n\treturn es_string_new(t + 1);\n}\n\nstatic EsObject*\nmake_symbol  (char* t,\n\t\t\t  int is_wrapped)\n{\n\tif (is_wrapped)\n    {\n\t\tsize_t len;\n\n\t\tlen = strlen(t);\n\t\tt[(len - 1)] = '\\0';\n\t\tt = t + 1;\n    }\n\n\treturn es_symbol_intern(t);\n}\n\n\nstatic EsObject*\nmake_boolean (int b)\n{\n\treturn es_boolean_new(b);\n}\n\nstatic int\nis_integer   (const char* cstr,\n\t\t\t  int* i)\n{\n\tchar* endptr;\n\tlong  r;\n\n\tendptr = NULL;\n\terrno = 0;\n\tr = strtol(cstr, &endptr, 10);\n\n\tif (errno || (endptr == cstr))\n\t\treturn 0;\n\telse if (*endptr != '\\0')\n\t\treturn 0;\n\n\tif ((r > INT_MAX) || r < INT_MIN)\n    {\n\t\t/* TODO: What I should do?\n\t\t   TODO: Set error */\n\t\t/*\n\t\t  throw ReadError(\"Too large integer for `int': \" + r);\n\t\t*/\n\t\tmio_printf(mio_stderr(), \";; is_integer, Integer out of range: %s\\n\", cstr);\n\t\treturn 0;\n    }\n\n\t*i = r;\n\treturn 1;\n}\n\nstatic EsObject*\nmake_integer (int  i)\n{\n\treturn es_integer_new(i);\n}\n\nstatic int\nis_real      (const char* cstr,\n\t\t\t  double* d)\n{\n\tchar* endptr;\n\n\tendptr = NULL;\n\terrno = 0;\n\t*d = strtod(cstr, &endptr);\n\n\tif (errno || (endptr == cstr))\n\t\treturn 0;\n\telse if (*endptr != '\\0')\n\t\treturn 0;\n\telse if (isinf(*d) || isnan(*d))\n\t\treturn 0;\n\treturn 1;\n}\n\nstatic EsObject*\nmake_real (double d)\n{\n\treturn es_real_new(d);\n}\n\nstatic EsObject*\nmake_regex (const char *pat,\n\t\t\tint case_insensitive)\n{\n\treturn es_regex_compile(pat, case_insensitive);\n}\n\nEsObject*\nes_read_from_string(const char* buf,\n\t\t\t\t\tconst char** saveptr)\n{\n\tMIO* in;\n\tEsObject* o;\n\n\n\t/* IN is opend in \"r\" mode and the stream pointed by\n\t   IN is short-lived here. */\n\tin = mio_new_memory((void *)buf, strlen(buf), NULL, NULL);\n\to = es_read(in);\n\tif (saveptr)\n\t\t*saveptr = buf + mio_tell(in);\n\tmio_unref(in);\n\n\treturn o;\n}\n\n\n\f\ntypedef struct _EsAutounrefPool EsAutounrefPool;\ntypedef struct _EsChain EsChain;\n\nstruct _EsChain\n{\n\tEsObject* object;\n\tEsChain*  next;\n};\n\nstruct _EsAutounrefPool\n{\n\tEsAutounrefPool * parent_pool;\n\tEsChain*          chain;\n};\n\nstatic EsAutounrefPool * currrent_pool;\n\nstatic EsAutounrefPool* es_autounref_pool_new(void);\nstatic void             es_autounref_pool_free(EsAutounrefPool* pool);\nstatic EsChain*         es_chain_new(EsObject* object);\nstatic void             es_chain_free(EsChain* chain);\n\n\nvoid\nes_autounref_pool_push(void)\n{\n\tEsAutounrefPool* r;\n\n\tr = es_autounref_pool_new();\n\tr->parent_pool = currrent_pool;\n\tcurrrent_pool = r;\n}\n\nvoid\nes_autounref_pool_pop (void)\n{\n\tEsAutounrefPool *tmp;\n\n\ttmp = currrent_pool;\n\tcurrrent_pool = tmp->parent_pool;\n\n\tes_autounref_pool_free(tmp);\n}\n\nstatic void\nes_autounref_pool_free(EsAutounrefPool* pool)\n{\n\tpool->parent_pool = NULL;\n\tes_chain_free(pool->chain);\n\tpool->chain = NULL;\n\n\tfree(pool);\n}\n\nEsObject*\nes_object_autounref   (EsObject* object)\n{\n\tEsChain* r;\n\n\tr = es_chain_new(object);\n\tr->next = currrent_pool->chain;\n\tcurrrent_pool->chain = r;\n\n\treturn object;\n}\n\nstatic EsAutounrefPool*\nes_autounref_pool_new(void)\n{\n\tEsAutounrefPool* r;\n\n\tr = calloc(1, sizeof(EsAutounrefPool));\n\treturn r;\n}\n\nstatic EsChain*\nes_chain_new(EsObject *object)\n{\n\tEsChain* r;\n\n\tr = calloc(1, sizeof(EsChain));\n\tr->object = object;\n\treturn r;\n}\n\nstatic void\nes_chain_free(EsChain *chain)\n{\n\tEsChain *tmp;\n\n\twhile(chain)\n    {\n\t\ttmp = chain;\n\t\tchain = chain->next;\n\n\t\tes_object_unref(tmp->object);\n\t\ttmp->object = NULL;\n\t\ttmp->next = NULL;\n\t\tfree(tmp);\n    }\n}\n\n\n#include <stdarg.h>\nstatic EsObject* es_list_va(EsObject* object, va_list *ap);\n\nEsObject*\nes_list(EsObject* object,...)\n{\n\tEsObject* r;\n\tva_list ap;\n\n\tva_start(ap, object);\n\tr = es_list_va(object, &ap);\n\tva_end(ap);\n\n\treturn r;\n}\n\nstatic EsObject*\nes_list_va(EsObject* object, va_list *ap)\n{\n\tEsObject* r;\n\tEsObject* p;\n\tEsObject* tmp;\n\n\tr = es_nil;\n\tp = object;\n\tes_autounref_pool_push();\n\tdo {\n\t\tif (p == ES_READER_EOF)\n\t\t\tbreak;\n\n\t\tr = es_cons((p), es_object_autounref(r));\n\t\tp = va_arg(*ap, EsObject *);\n\t} while(1);\n\tes_autounref_pool_pop();\n\n\ttmp = r;\n\tr = es_cons_reverse(r);\n\tes_object_unref(tmp);\n\n\treturn r;\n}\n\n\nstatic EsObject* es_append0(EsObject* tail, EsObject* body);\nstatic EsObject* es_append1(EsObject* tail, EsObject* body0);\n\nEsObject*\nes_append(EsObject* list,...)\n{\n\tEsObject *r;\n\tEsObject *tmp;\n\tEsObject *tail;\n\tEsObject *body;\n\tva_list ap;\n\n\n\tva_start(ap, list);\n\tr = es_list_va(list, &ap);\n\tva_end(ap);\n\n\ttmp = r;\n\tr = es_cons_reverse(r);\n\tes_object_unref(tmp);\n\n\t/* r */\n\ttail = es_car(r);\n\tbody = es_cdr(r);\n\ttmp  = r;\n\tr = es_append0(tail, body);\n\tes_object_unref(tmp);\n\n\treturn r;\n}\n\nstatic EsObject*\nes_append0(EsObject* tail, EsObject* body)\n{\n\tif (es_null(body))\n\t\treturn tail;\n\telse\n    {\n\t\tEsObject* car;\n\n\t\tcar = es_cons_reverse(es_car(body));\n\t\ttail = es_append1(tail, car);\n\t\tes_object_unref(car);\n\t\tbody = es_cdr(body);\n\t\treturn es_append0(tail, body);\n    }\n}\n\nstatic EsObject*\nes_append1(EsObject* tail, EsObject* body0)\n{\n\tif (es_null(body0))\n\t\treturn es_object_ref(tail);\n\telse\n    {\n\t\tEsObject* car;\n\t\tEsObject* r;\n\n\t\tcar  = es_car(body0);\n\t\ttail = es_cons(car, tail);\n\n\t\tr = es_append1(tail, es_cdr(body0));\n\t\tes_object_unref(tail);\n\t\treturn r;\n    }\n}\n\n\n\f\nstatic EsObject* pattern_d         = NULL;\nstatic EsObject* pattern_f         = NULL;\nstatic EsObject* pattern_F         = NULL;\nstatic EsObject* pattern_s         = NULL;\nstatic EsObject* pattern_S         = NULL;\nstatic EsObject* pattern_b         = NULL;\nstatic EsObject* pattern_rest      = NULL;\nstatic EsObject* pattern_unquote   = NULL;\nstatic EsObject* pattern_splice    = NULL;\n\nstatic EsObject* pattern_i_d       = NULL;\nstatic EsObject* pattern_i_f       = NULL;\nstatic EsObject* pattern_i_F       = NULL;\nstatic EsObject* pattern_i_s       = NULL;\nstatic EsObject* pattern_i_S       = NULL;\nstatic EsObject* pattern_i_b       = NULL;\nstatic EsObject* pattern_i_rest    = NULL;\nstatic EsObject* pattern_i_unquote = NULL;\n\nstatic void\npattern_init(void)\n{\n\tif (!pattern_d) (pattern_d = es_symbol_intern(\"%d\"));\n\tif (!pattern_f) (pattern_f = es_symbol_intern(\"%f\"));\n\tif (!pattern_F) (pattern_F = es_symbol_intern(\"%F\"));\n\tif (!pattern_s) (pattern_s = es_symbol_intern(\"%s\"));\n\tif (!pattern_S) (pattern_S = es_symbol_intern(\"%S\"));\n\tif (!pattern_b) (pattern_b = es_symbol_intern(\"%b\"));\n\tif (!pattern_rest) (pattern_rest = es_symbol_intern(\"%@\"));\n\tif (!pattern_unquote) (pattern_unquote = es_symbol_intern(\"%,\"));\n\tif (!pattern_splice) (pattern_splice = es_symbol_intern(\"%,@\"));\n\n\tif (!pattern_i_d) (pattern_i_d = es_symbol_intern(\"%_d\"));\n\tif (!pattern_i_f) (pattern_i_f = es_symbol_intern(\"%_f\"));\n\tif (!pattern_i_F) (pattern_i_F = es_symbol_intern(\"%_F\"));\n\tif (!pattern_i_s) (pattern_i_s = es_symbol_intern(\"%_s\"));\n\tif (!pattern_i_S) (pattern_i_S = es_symbol_intern(\"%_S\"));\n\tif (!pattern_i_b) (pattern_i_b = es_symbol_intern(\"%_b\"));\n\tif (!pattern_i_rest) (pattern_i_rest = es_symbol_intern(\"%_@\"));\n\tif (!pattern_i_unquote) (pattern_i_unquote = es_symbol_intern(\"%_,\"));\n}\n\nstatic EsObject*\nes_vrealize_atom(EsObject* fmt_object, va_list *ap)\n{\n\tif (fmt_object == pattern_d)\n\t\treturn es_integer_new(va_arg(*ap, int));\n\telse if (fmt_object == pattern_f)\n    {\n\t\tdouble x = va_arg(*ap, double);\n\t\tmio_printf(mio_stderr(), \"=>%f\\n\", x);\n\t\treturn es_real_new(x);\n    }\n\telse if (fmt_object == pattern_s)\n\t\treturn es_string_new(va_arg(*ap, char *));\n\telse if (fmt_object == pattern_S)\n\t\treturn es_symbol_intern(va_arg(*ap, char *));\n\telse if (fmt_object == pattern_b)\n\t\treturn es_boolean_new(va_arg(*ap, int));\n\telse if ((fmt_object == pattern_unquote)\n\t\t\t || (fmt_object == pattern_splice))\n\t\treturn es_object_ref(va_arg(*ap, EsObject*));\n\telse\n\t\treturn es_object_ref(fmt_object);\n}\n\nstatic EsObject*\nes_vrealize(EsObject* fmt_object, va_list *ap)\n{\n\tpattern_init();\n\n\tif (es_cons_p(fmt_object))\n    {\n\t\tEsObject* car;\n\t\tEsObject* cdr;\n\t\tEsObject* kar;\n\t\tEsObject* kdr;\n\t\tEsObject* r;\n\n\t\tcar = es_car(fmt_object);\n\n\t\tif (car == pattern_rest)\n\t\t\tr = es_object_ref(va_arg(*ap, EsObject*));\n\t\telse\n\t\t{\n\t\t\tcdr = es_cdr(fmt_object);\n\n\t\t\tkar = es_vrealize(car, ap);\n\t\t\tkdr = es_vrealize(cdr, ap);\n\n\t\t\tif (car == pattern_splice)\n\t\t\t{\n\t\t\t\tif (es_cons_p(kar))\n\t\t\t\t\tr = es_append(kar, kdr, ES_READER_EOF);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* TODO: error */\n\t\t\t\t\tchar *fmt;\n\n\t\t\t\t\tmio_printf(mio_stderr(),\n\t\t\t\t\t\t\t   \";; an atom is passed for splice format:\\n\");\n\t\t\t\t\tfmt = es_print_to_string(fmt_object);\n\t\t\t\t\tmio_printf(mio_stderr(), \";; => %s\\n\", fmt);\n\t\t\t\t\tfree(fmt);\n\t\t\t\t\tr = es_nil;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tr = es_cons(kar, kdr);\n\n\t\t\tes_object_unref(kar);\n\t\t\tes_object_unref(kdr);\n\t\t}\n\t\treturn r;\n    }\n\telse\n\t\treturn es_vrealize_atom(fmt_object, ap);\n}\n\nEsObject*\nes_realize   (EsObject* fmt_object,...)\n{\n\tEsObject* object;\n\tva_list ap;\n\n\tif (es_error_p(fmt_object))\n\t\treturn es_object_ref(fmt_object);\n\n\tva_start(ap, fmt_object);\n\tobject = es_vrealize(fmt_object, &ap);\n\tva_end(ap);\n\n\treturn object;\n}\n\nEsObject*\nes_srealize  (const char* fmt,...)\n{\n\tEsObject* fmt_object;\n\tEsObject* object;\n\tva_list ap;\n\n\tfmt_object = es_read_from_string(fmt, NULL);\n\tif (es_error_p(fmt_object))\n\t\treturn fmt_object;\n\n\tva_start(ap, fmt);\n\tobject = es_vrealize(fmt_object, &ap);\n\tva_end(ap);\n\n\tes_object_unref(fmt_object);\n\n\treturn object;\n}\n\nEsObject* es_map   (EsObject * (*fn) (EsObject *, void *),\n\t\t\t\t\tEsObject *list, void *user_data)\n{\n\tif (es_null (list))\n\t\treturn list;\n\n\tEsObject *c = es_car (list);\n\tc = fn (c, user_data);\n\tif (es_error_p (c))\n\t\treturn c;\n\n\tEsObject *r = es_map (fn, es_cdr (list), user_data);\n\tif (es_error_p (r))\n\t{\n\t\tes_object_unref (c);\n\t\treturn r;\n\t}\n\n\tEsObject *o = es_cons (c, r);\n\tes_object_unref (r);\n\tes_object_unref (c);\n\n\treturn o;\n}\n\nEsObject* es_foreach (EsObject * (*fn) (EsObject *, void *),\n\t\t\t\t\t  EsObject *list, void *user_data)\n{\n\tif (es_null (list))\n\t\treturn es_false;\n\n\tfor (EsObject *c = list; !es_null (c); c = es_cdr (c))\n\t{\n\t\tEsObject *r = fn (es_car (c), user_data);\n\t\tif (!es_object_equal (r, es_false))\n\t\t\treturn r;\n\t}\n\n\treturn es_false;\n}\n\nEsObject* es_fold (EsObject * (*kons) (EsObject *, EsObject *, void *),\n\t\t\t\t   EsObject * knil, EsObject * list, void *user_data)\n{\n\tEsObject *r = knil;\n\n\tes_autounref_pool_push();\n\twhile (!es_null (list))\n\t{\n\t\tEsObject *e = es_car (list);\n\t\tlist = es_cdr (list);\n\n\t\tr = (* kons) (e, (r == knil) ? r : es_object_autounref (r),\n\t\t\t\t\t  user_data);\n\t\tif (es_error_p (r))\n\t\t\tbreak;\n\t}\n\tes_autounref_pool_pop();\n\n\treturn r;\n}\n\nstatic EsObject*\nes_vmatch_atom_input(EsObject* input, EsObject* fmt_object, va_list *ap)\n{\n\treturn ES_READER_ERROR;\n}\n\nstatic EsObject*\nes_vmatch_atom_fmt(EsObject* input, EsObject* fmt_object, va_list *ap)\n{\n\tif (fmt_object == pattern_unquote)\n\t\t*(va_arg(*ap, EsObject**)) = /* es_object_ref */(input);\n\telse if (fmt_object == pattern_i_unquote)\n\t\t;\n\telse\n\t\treturn ES_READER_ERROR;\n\n\treturn fmt_object;\n}\n\nstatic EsObject*\nes_vmatch_atom(EsObject* input, EsObject* fmt_object, va_list *ap)\n{\n\tif (fmt_object == pattern_d)\n    {\n\t\tif (es_integer_p(input))\n\t\t\t*(va_arg(*ap, int*)) = es_integer_get(input);\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_i_d)\n    {\n\t\tif (es_integer_p(input))\n\t\t\t;\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_f)\n    {\n\t\tif (es_real_p(input))\n\t\t\t*(va_arg(*ap, double*)) = es_real_get(input);\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_i_f)\n    {\n\t\tif (es_real_p(input))\n\t\t\t;\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_F)\n    {\n\t\tif (es_integer_p(input))\n\t\t{\n\t\t\tint i;\n\n\t\t\ti = es_integer_get(input);\n\t\t\t*(va_arg(*ap, double*)) = (double)i;\n\t\t}\n\t\telse if (es_real_p(input))\n\t\t{\n\t\t\t*(va_arg(*ap, double*)) = es_real_get(input);\n\t\t}\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_i_F)\n    {\n\t\tif (es_integer_p(input) || es_real_p(input))\n\t\t\t;\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_s)\n    {\n\t\tif (es_string_p(input))\n\t\t\t*(va_arg(*ap, const char**)) = /* strdup */(es_string_get(input));\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_i_s)\n    {\n\t\tif (es_string_p(input))\n\t\t\t;\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_S)\n    {\n\t\tif (es_symbol_p(input))\n\t\t\t*(va_arg(*ap, const char**)) = /* strdup */(es_symbol_get(input));\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_i_S)\n    {\n\t\tif (es_symbol_p(input))\n\t\t\t;\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_b)\n    {\n\t\tif (es_boolean_p(input))\n\t\t\t*(va_arg(*ap, int*)) = es_boolean_get(input);\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_i_b)\n    {\n\t\tif (es_boolean_p(input))\n\t\t\t;\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse if (fmt_object == pattern_unquote)\n\t\t*(va_arg(*ap, EsObject**)) = /* es_object_ref */(input);\n\telse if (fmt_object == pattern_i_unquote)\n\t\t;\n\telse if (es_object_equal(fmt_object, input))\n\t\t;\n\telse\n\t\treturn ES_READER_ERROR;\n\n\treturn fmt_object;\n}\n\nstatic void\nrecover(EsObject* fmt_object, va_list *aq)\n{\n\tif (es_cons_p(fmt_object))\n    {\n\t\trecover(es_car(fmt_object), aq);\n\t\trecover(es_cdr(fmt_object), aq);\n    }\n\telse\n    {\n\t\tif (fmt_object == pattern_s\n\t\t\t|| fmt_object == pattern_S)\n\t\t{\n\t\t\tchar **s;\n\n\t\t\ts = va_arg(*aq, char **);\n\t\t\t(void)/* free */(*s);\n\n\t\t\t*s = NULL;\n\t\t}\n\t\telse if (fmt_object == pattern_rest\n\t\t\t\t || fmt_object == pattern_unquote)\n\t\t{\n\t\t\tEsObject** o;\n\n\t\t\to = va_arg(*aq, EsObject**);\n\t\t\t(void)/* es_object_unref */(*o);\n\t\t\t*o = NULL;\n\t\t}\n    }\n}\n\nstatic EsObject*\nes_vmatch(EsObject* input, EsObject* fmt_object, va_list *ap)\n{\n\tpattern_init();\n\n\tif (es_cons_p(fmt_object) && es_cons_p(input))\n    {\n\t\tEsObject* fmt_car;\n\t\tEsObject* fmt_cdr;\n\t\tEsObject* i_car;\n\t\tEsObject* i_cdr;\n\n\t\tEsObject* r_car;\n\t\tEsObject* r_cdr;\n\n\t\tva_list   aq;\n\n\t\tfmt_car = es_car(fmt_object);\n\n\t\tif (fmt_car == pattern_rest)\n\t\t{\n\t\t\t*(va_arg(*ap, EsObject**)) = /* es_object_ref */(input);\n\t\t\treturn fmt_car;\n\t\t}\n\t\telse if (fmt_car == pattern_i_rest)\n\t\t{\n\t\t\treturn fmt_car;\n\t\t}\n\n\t\tfmt_cdr = es_cdr(fmt_object);\n\n\t\ti_car   = es_car(input);\n\t\ti_cdr   = es_cdr(input);\n\n\t\tva_copy(aq, *ap);\n\t\tr_car = es_vmatch(i_car, fmt_car, ap);\n\t\tif (es_error_p(r_car))\n\t\t{\n\t\t\tva_end(aq);\n\t\t\treturn r_car;\n\t\t}\n\n\t\tr_cdr = es_vmatch(i_cdr, fmt_cdr, ap);\n\t\tif (es_error_p(r_cdr))\n\t\t{\n\t\t\trecover(fmt_car, &aq);\n\t\t\tva_end(aq);\n\t\t\treturn r_cdr;\n\t\t}\n\t\tva_end(aq);\n\t\treturn r_cdr;\n    }\n\telse if (es_cons_p(fmt_object))\n    {\n\t\treturn es_vmatch_atom_input(input, fmt_object, ap);\n    }\n\telse if (es_cons_p(input))\n    {\n\t\tif (fmt_object == pattern_rest)\n\t\t{\n\t\t\t*(va_arg(*ap, EsObject**)) = /* es_object_ref */(input);\n\t\t\treturn fmt_object;\n\t\t}\n\t\telse if (fmt_object == pattern_i_rest)\n\t\t\treturn fmt_object;\n\t\telse\n\t\t\treturn es_vmatch_atom_fmt(input, fmt_object, ap);\n    }\n\telse\n    {\n\t\treturn es_vmatch_atom(input, fmt_object, ap);\n    }\n}\n\nint\nes_match(EsObject* input, EsObject* fmt_object,...)\n{\n\tEsObject* object;\n\tva_list ap;\n\n\tva_start(ap, fmt_object);\n\tobject = es_vmatch(input, fmt_object, &ap);\n\tva_end(ap);\n\n\treturn !(es_error_p(object));\n}\n\nint\nes_smatch   (EsObject* input, const char* fmt,...)\n{\n\tint r;\n\tEsObject* object;\n\tEsObject* fmt_object;\n\tva_list ap;\n\n\tfmt_object = es_read_from_string(fmt, NULL);\n\tif (es_error_p(fmt_object))\n\t\treturn 0;\n\n\tva_start(ap, fmt);\n\tobject = es_vmatch(input, fmt_object, &ap);\n\tva_end(ap);\n\n\tr = !(es_error_p(object));\n\tes_object_unref(fmt_object);\n\n\treturn r;\n}\n\nEsObject*\nes_pget (EsObject* plist, EsObject* key, EsObject* default_value)\n{\n\tif (es_cons_p(plist))\n    {\n\t\tEsObject* car;\n\t\tEsObject* cdr;\n\t\tEsObject* cadr;\n\t\tEsObject* cddr;\n\n\t\tcar = es_car(plist);\n\t\tcdr = es_cdr(plist);\n\n\t\tif (es_cons_p(cdr))\n\t\t{\n\t\t\tcadr = es_car(cdr);\n\t\t\tcddr = es_cdr(cdr);\n\n\t\t\tif (es_object_equal(car, key))\n\t\t\t\treturn cadr;\n\t\t\telse\n\t\t\t\treturn es_pget(cddr, key, default_value);\n\t\t}\n\t\telse\n\t\t\treturn ES_READER_ERROR;\n    }\n\telse\n\t\treturn default_value;\n}\n"
  },
  {
    "path": "dsl/es.h",
    "content": "/*\n  Copyright (c) 2009 Masatake YAMATO\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE. */\n\n#ifndef __ES_LANG_C_STDC99_H__\n#define __ES_LANG_C_STDC99_H__\n\n#ifndef _GNU_SOURCE\n#define _GNU_SOURCE\n#endif\n#include <stdio.h>\n\n#include \"mio.h\"\n\n#ifdef  __cplusplus\nextern \"C\" {\n#endif\n\nenum _EsType {\n  ES_TYPE_NIL,\n  ES_TYPE_INTEGER,\n  ES_TYPE_REAL,\n  ES_TYPE_BOOLEAN,\n  ES_TYPE_SYMBOL,\n  ES_TYPE_STRING,\n  ES_TYPE_CONS,\n  ES_TYPE_REGEX,\n  /* ... */\n  ES_TYPE_ERROR,\n  /* ... */\n  ES_TYPE_BUILTIN_LAST = ES_TYPE_ERROR,\n  ES_TYPE_FOREIGNER_START,\n};\ntypedef enum _EsType EsType;\n\nstruct _EsObject;\ntypedef struct _EsObject EsObject;\n\nconst char* es_type_get_name        (int t);\n\nEsType      es_object_get_type      (const EsObject*      object);\n\n\nEsObject*   es_object_ref           (EsObject*       object);\nvoid        es_object_unref         (EsObject*       object);\nvoid        es_object_unref_batch   (EsObject*       array[],\n\t\t\t\t\t\t\t\t\t unsigned int    count);\nEsObject*   es_object_autounref     (EsObject*      object);\n\nint         es_object_equal         (const EsObject* self,\n\t\t\t\t\t\t\t\t\t const EsObject* other);\n\nint         es_atom                 (const EsObject* object);\n\n#define     ES_ERROR_MEMORY   es_error_intern(\"MEMORY-EXHAUSTED\")\n#define     ES_ERROR_REGEX    es_error_intern(\"WRONG-REGEX-SYNTAX\")\n\n/*\n * Nil\n */\n#define es_nil ((EsObject*)0)\nint         es_null                 (const EsObject* object);\n\n/*\n * Integer\n */\nEsObject*    es_integer_new (int                value);\nint          es_integer_p   (const EsObject*   object);\nint          es_integer_get (const EsObject*   object);\n\n\n/*\n * Real\n */\nEsObject*    es_real_new    (double             value);\nint          es_real_p      (const EsObject*   object);\ndouble       es_real_get    (const EsObject*   object);\n\n\n/*\n * Use Integer as Real\n */\nint          es_number_p    (const EsObject*   object);\ndouble       es_number_get  (const EsObject*   object);\n\n\n/*\n * Boolean\n */\n#define es_true             (es_boolean_new(1))\n#define es_false            (es_boolean_new(0))\nEsObject*    es_boolean_new (int                value);\nint          es_boolean_p   (const EsObject*   object);\nint          es_boolean_get (const EsObject*   object);\n\n/*\n * String\n */\nEsObject*    es_string_new  (const char*        value);\nEsObject*    es_string_newL (const char*        value, size_t length);\nint          es_string_p    (const EsObject*   object);\nconst char*  es_string_get  (const EsObject*   object);\n\n\n/*\n * Symbol\n */\nEsObject*    es_symbol_intern  (const char*       name);\nint          es_symbol_p    (const EsObject*   object);\nconst char*  es_symbol_get  (const EsObject*   object);\n\nvoid*        es_symbol_set_data (const EsObject*   object, void *data);\nvoid*        es_symbol_get_data (const EsObject*   object);\n\n/*\n * Error\n */\n\nEsObject*    es_error_intern (const char*        name);\nint          es_error_p      (const EsObject*   object);\nconst char*  es_error_name   (const EsObject*   object);\nEsObject*    es_error_set_object (EsObject*   error, EsObject*   object);\nEsObject*    es_error_get_object (const EsObject*   error);\n\n\n/*\n * Cons\n */\nEsObject*    es_cons        (EsObject* car, EsObject* cdr);\nint          es_cons_p      (const EsObject* object);\nint          es_list_p      (const EsObject* object);\nEsObject*    es_car         (const EsObject* object);\nEsObject*    es_cdr         (const EsObject* object);\n\n\n/*\n * Regex\n */\nEsObject*    es_regex_compile (const char* pat,\n\t\t\t\t\t\t\t   int case_insensitive);\nint          es_regex_p       (const EsObject* object);\nEsObject*    es_regex_exec    (const EsObject* regex,\n\t\t\t\t\t\t\t   const EsObject* str);\n\n/* Return #f if unmatched.\n * Retrun NIL is the associate group is not in REGEX. */\nEsObject*    es_regex_exec_extract_match_new (const EsObject* regex,\n\t\t\t\t\t\t\t\t\t\t\t  const EsObject* str,\n\t\t\t\t\t\t\t\t\t\t\t  unsigned int group);\n\n/*\n * Foreign pointer\n */\nEsType       es_type_define_pointer   (const char *name,\n\t\t\t\t\t\t\t\t\t   void (* freefn) (void *),\n\t\t\t\t\t\t\t\t\t   int  (* equalfn) (const void*, const void*),\n\t\t\t\t\t\t\t\t\t   void (* printfn) (const void*, MIO *));\n\n/* If the type has sized fat area, the area is filled with zero. */\nEsObject*    es_pointer_new    (EsType type, void *ptr);\nvoid*        es_pointer_get    (const EsObject *object);\nvoid*        es_pointer_take   (EsObject *object);\n\n/*\n * Fatptr: Foreign pointer with extra data\n *\n * init_fat () returns es_true if the initialization ends successfully.\n * In failure case, init_fat () returns an error object.\n */\nEsType       es_type_define_fatptr    (const char *name,\n\t\t\t\t\t\t\t\t\t   size_t fat_size,\n\t\t\t\t\t\t\t\t\t   EsObject *(* initfat_fn) (void *fat, void * ptr, void *extra),\n\t\t\t\t\t\t\t\t\t   void (* freefn) (void * ptr, void *fat),\n\t\t\t\t\t\t\t\t\t   int  (* equalfn) (const void* ptr_a, const void* fat_a,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t const void* ptr_b, const void* fat_b),\n\t\t\t\t\t\t\t\t\t   void (* printfn) (const void* ptr, const void *fat, MIO *));\n/* If initfat_fn is given in the type, the new fat area will is\n * initialized with the method.\n * If initfat_fn is not given, and extra is not NULL, the contents\n * pointed by extra is copied to the fat area.\n * If initfat_fn is not given, and extra is NULL, the fat area\n * is filled with zero as es_pointer_new does. */\nEsObject*    es_fatptr_new     (EsType type, void *ptr, void *extra);\n/* Access to the fat area. Use es_pointer_get to access the pointer. */\nvoid*        es_fatptr_get     (const EsObject *object);\n\n/*\n * Print\n */\nvoid         es_print           (const EsObject* object,\n\t\t\t\t\t\t\t\t MIO*           out);\nchar*        es_print_to_string (EsObject*        object);\n\n/*\n * Read\n */\nEsObject*    es_read            (MIO* in);\nEsObject*    es_read_from_string(const char* in,\n\t\t\t\t\t\t\t\t const char** saveptr);\n\n#define      ES_READER_ERROR es_error_intern(\"READ-ERROR\")\n#define      ES_READER_EOF   es_error_intern(\"EOF\")\n\n/*\n * Comment\n */\nvoid         es_comment           (const char* comment,\n\t\t\t\t\t\t\t\t   MIO*       out);\nchar*        es_comment_to_string (const char* comment);\n\n/*\n * Autounref pool\n */\nvoid es_autounref_pool_push(void);\nvoid es_autounref_pool_pop (void);\n\n\n\n/*\n * List builders\n */\nEsObject* es_list     (EsObject* object,...);\nEsObject* es_append   (EsObject* list,...);\nEsObject* es_reverse  (EsObject* cons);\n\n#define      ES_PROC_UNIMPLEMENTED es_error_intern(\"PROC-UNIMPLEMENTED\")\nEsObject* es_realize   (EsObject* fmt_object,...);\nEsObject* es_srealize  (const char* fmt,...);\n\n/* The value returned from FN treated as if it is returned from\n * a *_new function. es_map may call es_object_unref() for the value.\n * The value returned from es_map should be treated as if it is\n * returned from a *_new function. The caller must free the returned\n * value.\n */\nEsObject* es_map   (EsObject * (*fn) (EsObject *, void *),\n\t\t\t\t\tEsObject *list, void *user_data);\n\n/* Unlike es_map, the value returnd from FN is not accumulated.\n * If FN returns a value other than #f, es_foreach stops the\n * iteration immediately and returns the value.\n */\nEsObject* es_foreach (EsObject * (*fn) (EsObject *, void *),\n\t\t\t\t\t  EsObject *list, void *user_data);\n\n/* The memory management of es_map is also applicable to es_fold. */\nEsObject* es_fold (EsObject * (*kons) (EsObject *, EsObject *, void *),\n\t\t\t\t   EsObject * knil, EsObject * list, void *user_data);\n\n/*\n * Rich element accessors\n */\nint        es_match        (EsObject* input, EsObject* fmt_object,...);\nint        es_smatch       (EsObject* input, const char* fmt,...);\n\n\nEsObject*  es_pget         (EsObject* plist, EsObject* key, EsObject* default_value);\n\n#ifdef  __cplusplus\n}\n#endif\n\n#endif /* Not def: __ES_LANG_C_STDC_H__ */\n"
  },
  {
    "path": "dsl/formatter.c",
    "content": "/*\n*   Copyright (c) 2021, Masatake YAMATO\n*   Copyright (c) 2021, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n/*\n * INCLUDES\n */\n\n#include \"formatter.h\"\n#include \"dsl.h\"\n#include \"es.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\n/*\n * DATA DEFINITIONS\n */\n#if 0\nstatic DSLProcBind pbinds [] = {\n};\n#endif\n\n/*\n * Procs\n */\nstatic int initialize (void)\n{\n\tstatic int initialized;\n\n\tif (initialized)\n\t\treturn 1;\n\n\tif (!dsl_init (DSL_FORMATTER, NULL, 0))\n\t{\n\t\tfprintf(stderr, \"MEMORY EXHAUSTED\\n\");\n\t\treturn 0;\n\t}\n\n\tinitialized = 1;\n\treturn 1;\n}\n\n/*\n * FCode\n */\nstruct sFCode\n{\n\tDSLCode *dsl;\n};\n\nFCode *f_compile (EsObject *exp)\n{\n\tFCode *code;\n\n\tif (!initialize ())\n\t\texit (1);\n\n\tcode = malloc (sizeof (FCode));\n\tif (code == NULL)\n\t{\n\t\tfprintf(stderr, \"MEMORY EXHAUSTED\\n\");\n\t\treturn NULL;\n\t}\n\n\tcode->dsl = dsl_compile (DSL_FORMATTER, exp);\n\tif (code->dsl == NULL)\n\t{\n\t\tfprintf(stderr, \"MEMORY EXHAUSTED or SYNTAX ERROR\\n\");\n\t\tfree (code);\n\t\treturn NULL;\n\t}\n\n\treturn code;\n}\n\nstatic int f_print0(EsObject *r, FILE *out)\n{\n\tif (es_error_p (r))\n\t{\n\t\tdsl_report_error (\"GOT ERROR in FORMATTING\", r);\n\t\treturn 1;\n\t}\n\telse if (es_string_p (r))\n\t{\n\t\tfputs (es_string_get(r), out);\n\t\treturn 0;\n\t}\n\telse if (es_integer_p (r))\n\t{\n\t\tfprintf(out, \"%d\", es_integer_get(r));\n\t\treturn 0;\n\t}\n\telse if (es_object_equal(r, es_false))\n\t{\n\t\treturn 0;\n\t}\n\telse if (es_object_equal(r, es_true))\n\t{\n\t\tputc ('\\n', out);\n\t\treturn 0;\n\t}\n\telse if (es_cons_p (r))\n\t{\n\t\tEsObject *car = es_car (r);\n\t\tEsObject *cdr = es_cdr(r);\n\n\t\tfor (; !es_null (car);\n\t\t\t car = es_car (cdr), cdr = es_cdr (cdr))\n\t\t{\n\t\t\tif (f_print0 (car, out))\n\t\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n\telse\n\t{\n\t\tdsl_report_error (\"UNEXPECTED VALUE IN FORMATTING\", r);\n\t\treturn 1;\n\t}\n}\n\nint f_print (const tagEntry * entry, FCode *code, FILE *out)\n{\n\tEsObject *r;\n\tint exit_code = 0;\n\n\tDSLEnv env = {\n\t\t.engine = DSL_FORMATTER,\n\t\t.entry = entry,\n\t};\n\n\tes_autounref_pool_push ();\n\tr = dsl_eval (code->dsl, &env);\n\texit_code = f_print0 (r, out);\n\tes_autounref_pool_pop ();\n\n\tdsl_cache_reset (DSL_FORMATTER);\n\n\tif (exit_code)\n\t\texit (exit_code);\n\n\treturn 0;\n}\n\nvoid f_destroy        (FCode *code)\n{\n\tdsl_release (DSL_FORMATTER, code->dsl);\n\tfree (code);\n}\n\nvoid f_help           (FILE *fp)\n{\n\tif (!initialize ())\n\t\texit (1);\n\tdsl_help (DSL_FORMATTER, fp);\n}\n"
  },
  {
    "path": "dsl/formatter.h",
    "content": "/*\n*   Copyright (c) 2021, Masatake YAMATO\n*   Copyright (c) 2021, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef FORMATTER_H\n#define FORMATTER_H\n\n/*\n * Includes\n */\n\n#include \"es.h\"\n#include \"readtags.h\"\n\n#include <stdio.h>\n\n/*\n * Type declarations\n */\n\ntypedef struct sFCode FCode;\n\n\n/*\n * function declarations\n */\n\nFCode       *f_compile        (EsObject *exp);\nint          f_print          (const tagEntry * entry, FCode *code, FILE *out);\nvoid         f_destroy        (FCode *code);\nvoid         f_help           (FILE *fp);\n\n#endif\n"
  },
  {
    "path": "dsl/optscript.c",
    "content": "// for x in $(grep ^declop ~/var/ctags/dsl/optscript.c | sed -e 's/declop(\\([^)]*\\));/\\1/'); do grep -q $x Tmain/optscript.d/*.ps || echo $x; done\n/*\n *   Copyright (c) 2020, Masatake YAMATO\n *   Copyright (c) 2020, Red Hat, Inc.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n */\n\n\n#include \"general.h\"\n\n#include \"debug.h\"\n#include \"es.h\"\n#include \"htable.h\"\n#include \"optscript.h\"\n#include \"ptrarray.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n#include <ctype.h>\n#include <string.h>\n\n\nstruct sOptVM\n{\n\tptrArray *ostack;\n\tptrArray *dstack;\n\tptrArray *estack;\n\n\tint        dstack_protection;\n\tMIO       *in;\n\tMIO       *out;\n\tMIO       *err;\n\n\tEsObject  *error;\n\n\tint        print_depth;\n\tint        read_depth;\n\tchar      *prompt;\n\tvoid      *app_data;\n};\n\ntypedef struct sOperatorFat\n{\n\tEsObject *name;\n\tint arity;\n\tconst char *help_str;\n} OperatorFat;\n\ntypedef struct sOperatorExtra\n{\n\tconst char *name;\n\tint arity;\n\tconst char *help_str;\n} OperatorExtra;\n\ntypedef OptOperatorFn Operator;\n\ntypedef enum eAttr {\n\tATTR_READABLE   = 1 << 0,\n\tATTR_WRITABLE   = 1 << 1,\n\tATTR_EXECUTABLE = 1 << 2,\n} Attr;\n\ntypedef struct sDictFat\n{\n\tunsigned int attr;\n} DictFat;\n\ntypedef struct sArrayFat\n{\n\tunsigned int attr;\n} ArrayFat;\n\ntypedef struct sStringFat\n{\n\tunsigned int attr;\n} StringFat;\n\ntypedef struct sNameFat\n{\n\tunsigned int attr;\n} NameFat;\n\nstatic EsObject* opt_system_dict;\n\nint OPT_TYPE_ARRAY;\nint OPT_TYPE_DICT;\nint OPT_TYPE_OPERATOR;\nint OPT_TYPE_STRING;\nint OPT_TYPE_NAME;\nint OPT_TYPE_MARK;\n\nstatic EsObject *OPT_ERR_UNDEFINED;\nstatic EsObject *OPT_ERR_SYNTAX;\nEsObject *OPT_ERR_UNDERFLOW;\nEsObject *OPT_ERR_TYPECHECK;\nEsObject *OPT_ERR_RANGECHECK;\nstatic EsObject *OPT_ERR_DICTSTACKUNDERFLOW;\nstatic EsObject *OPT_ERR_UNMATCHEDMARK;\nstatic EsObject *OPT_ERR_INTERNALERROR;\nstatic EsObject *OPT_ERR_END_PROC;\nstatic EsObject *OPT_ERR_INVALIDEXIT;\nstatic EsObject *OPT_ERR_STOPPED;\nEsObject *OPT_ERR_QUIT;\nstatic EsObject *OPT_ERR_INVALIDACCESS;\nstatic EsObject *OPT_ERR_INTOVERFLOW;\n\nstatic EsObject* OPT_MARK_ARRAY;\nstatic EsObject* OPT_MARK_DICT;\nstatic EsObject* OPT_MARK_MARK;\n\nstatic EsObject* OPT_KEY_newerror;\nstatic EsObject* OPT_KEY_errorname;\nstatic EsObject* OPT_KEY_command;\nstatic EsObject* OPT_KEY_ostack;\nstatic EsObject* OPT_KEY_estack;\nstatic EsObject* OPT_KEY_dstack;\n\n/* Naming conversions\n *\n * Opt|OPT\n * =====================================================================\n * exported as part of the library API\n *\n * optscript and ctags may refer these names.\n *\n *\n * <datatype>_...\n * =====================================================================\n * functions released to PS datatypes\n * PS datatypes are array, dict, operator, ...\n *\n * <datatype>_es_...\n * ---------------------------------------------------------------------\n * functions for representing the PS datatype object as EsObject object\n *\n * <datatype>_op_...\n * ---------------------------------------------------------------------\n * functions for accessing the datatype object from vm internal purpose\n *\n *\n * op_...<operator>\n * =====================================================================\n * functions implementing operators\n *\n *\n * vm_...\n * =====================================================================\n * the rest VM related functions\n *\n */\n\nstatic EsObject* array_new (unsigned int attr);\nstatic EsObject* array_shared_new (EsObject* original, unsigned int attr);\n\nstatic EsObject*    array_es_init_fat (void *fat, void *ptr, void *extra);\nstatic void         array_es_free  (void *ptr, void *fat);\nstatic int          array_es_equal (const void *a,\n\t\t\t\t\t\t\t\t\tconst void *afat,\n\t\t\t\t\t\t\t\t\tconst void *b,\n\t\t\t\t\t\t\t\t\tconst void *bfat);\nstatic void         array_es_print (const void *ptr, const void *fat, MIO *out);\n\nstatic void         array_op_add    (EsObject* array, EsObject* elt);\nstatic unsigned int array_op_length (const EsObject* array);\nstatic EsObject*    array_op_get    (const EsObject* array, unsigned int n);\nstatic void         array_op_put    (EsObject* array, unsigned int n, EsObject *obj);\n\n\nstatic EsObject* dict_new (unsigned int size, unsigned int attr);\n\nstatic EsObject* dict_es_init_fat (void *fat, void *ptr, void *extra);\nstatic void      dict_es_free  (void *ptr, void *fat);\nstatic int       dict_es_equal (const void *a,\n\t\t\t\t\t\t\t\tconst void *afat,\n\t\t\t\t\t\t\t\tconst void *b,\n\t\t\t\t\t\t\t\tconst void *bfat);\nstatic void      dict_es_print (const void *ptr, const void *fat, MIO *out);\n\n\nstatic void      dict_op_def           (EsObject* dict, EsObject *key, EsObject *val);\nstatic bool      dict_op_undef         (EsObject* dict, EsObject *key);\nstatic bool      dict_op_known_and_get (EsObject* dict, EsObject *key, EsObject **val);\nstatic void      dict_op_clear         (EsObject* dict);\n\n\nstatic EsObject* operator_new (Operator op, const char *name, int arity, const char *help_str);\n\nstatic EsObject* operator_es_init_fat (void *fat, void *ptr, void *extra);\nstatic void      operator_es_print (const void *ptr, const void *fat, MIO *out);\nstatic void      operator_es_free  (void *ptr, void *fat);\n\n\nstatic EsObject* string_new   (vString *vstr);\n\nstatic EsObject* string_es_init_fat (void *fat, void *ptr, void *extra);\nstatic void      string_es_free  (void *ptr, void *fat);\nstatic int       string_es_equal (const void *a,\n\t\t\t\t\t\t\t\t  const void *afat,\n\t\t\t\t\t\t\t\t  const void *b,\n\t\t\t\t\t\t\t\t  const void *bfat);\nstatic void      string_es_print (const void *ptr, const void *fat, MIO *out);\n\n\nstatic EsObject* name_new     (EsObject* symbol, unsigned int attr);\nstatic EsObject* name_newS    (const char*s, unsigned int attr);\nstatic EsObject* name_newS_cb (const char*s, void *attr);\n\nstatic EsObject* name_es_init_fat (void *fat, void *ptr, void *extra);\nstatic void      name_es_print (const void *ptr, const void *fat, MIO *out);\nstatic void      name_es_free  (void *ptr, void *fat);\nstatic int       name_es_equal (const void *a,\n\t\t\t\t\t\t\t\tconst void *afat,\n\t\t\t\t\t\t\t\tconst void *b,\n\t\t\t\t\t\t\t\tconst void *bfat);\n\n\nstatic EsObject* mark_new      (const char* mark);\n\nstatic void      mark_es_print (const void *ptr, MIO *out);\nstatic void      mark_es_free  (void *ptr);\nstatic int       mark_es_equal (const void *a, const void *b);\n\nstatic EsObject* vm_read          (OptVM *vm);\nstatic EsObject* vm_call_operator (OptVM *vm, EsObject *op);\nstatic EsObject* vm_call_proc     (OptVM *vm, EsObject *proc);\nstatic void      vm_print         (OptVM *vm, EsObject *o);\nstatic void      vm_print_full    (OptVM *vm, EsObject *o, bool string_as_is, int dict_recursion);\nstatic void      vm_help          (OptVM *vm, MIO *out, struct OptHelpExtender *extop, void *data);\nstatic void      vm_record_stop   (OptVM *vm, EsObject *cmd);\nstatic void      vm_record_error  (OptVM *vm, EsObject *e, EsObject *cmd);\nstatic void      vm_report_error  (OptVM *vm, EsObject *e);\nstatic void      vm_bind_proc     (OptVM *vm, ptrArray *proc);\n\nstatic void         vm_ostack_push        (OptVM *vm, EsObject *o);\nstatic EsObject*    vm_ostack_pop         (OptVM *vm);\nstatic unsigned int vm_ostack_count       (OptVM *vm);\nstatic EsObject*    vm_ostack_top         (OptVM *vm);\nstatic EsObject*    vm_ostack_peek        (OptVM *vm, int index_from_top);\nstatic int          vm_ostack_counttomark (OptVM *vm);\n\nstatic void         vm_dict_def           (OptVM *vm, EsObject *key, EsObject *val);\n\n/* Returns the dictionary where the value for the key is found.\n * val can be NULL. */\nstatic EsObject*    vm_dstack_known_and_get (OptVM *vm, EsObject *key, EsObject **val);\nstatic void         vm_dstack_push          (OptVM *vm, EsObject *o);\n/* FIXME: return type */\nstatic int          vm_dstack_count         (OptVM *vm);\nstatic EsObject*    vm_dstack_pop           (OptVM *vm);\nstatic void         vm_dstack_clear         (OptVM *vm);\n\nstatic EsObject*    vm_estack_push          (OptVM *vm, EsObject *p);\nstatic EsObject*    vm_estack_pop           (OptVM *vm);\n\n#define declop(OP)\t\t\t\t\t\t\t\t\t\t\\\n\tstatic EsObject* op_##OP(OptVM *vm, EsObject *name)\n\n\n#define defOP(DICT, FN, NAME, ARITY, HELP)\t\t\t\t\t\t\t\t\\\n\tdict_op_def (DICT,\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t es_object_autounref(es_symbol_intern (NAME)),\t\t\t\\\n\t\t\t\t es_object_autounref(operator_new (FN, NAME, ARITY, HELP)))\n\n#define defop(DICT, NAME, ARITY, HELP)\t\t\t\\\n\tdefOP (DICT, op_##NAME, #NAME, ARITY, HELP)\n\nstatic EsObject* op__print_objdict_rec (OptVM *vm, EsObject *name);\nstatic EsObject* op__print_objdict     (OptVM *vm, EsObject *name);\nstatic EsObject* op__print_object      (OptVM *vm, EsObject *name);\nstatic EsObject* op__print             (OptVM *vm, EsObject *name);\nstatic EsObject* op__print_object_nonl (OptVM *vm, EsObject *name);\nstatic EsObject* op__print_nonl        (OptVM *vm, EsObject *name);\nstatic EsObject* op__make_array        (OptVM *vm, EsObject *name);\nstatic EsObject* op__make_dict         (OptVM *vm, EsObject *name);\n\n/* non-standard operator */\ndeclop(_help);\n\n/* tested in pstack.ps */\ndeclop(pstack);\n\n/* error related non-standard operators */\ndeclop(_newerror);\ndeclop(_errorname);\n\n/* Operators for operand stack manipulation\n * tested in stack.ps */\ndeclop(pop);\ndeclop(exch);\ndeclop(dup);\ndeclop(index);\ndeclop(roll);\ndeclop(clear);\ndeclop(count);\ndeclop(mark);\ndeclop(cleartomark);\ndeclop(counttomark);\n\n/* Arithmetic Operators\n   tested in arithmetic.ps */\ndeclop(add);\ndeclop(idiv);\ndeclop(mod);\ndeclop(mul);\ndeclop(sub);\ndeclop(abs);\ndeclop(neg);\n\n/* Operators for array manipulation\n   tested in array.ps */\ndeclop(array);\ndeclop(astore);\ndeclop(aload);\n\n/* Operators for dictionary manipulation\n * tested in dict.ps */\ndeclop(dict);\ndeclop(begin);\ndeclop(end);\ndeclop(def);\ndeclop(load);\ndeclop(undef);\ndeclop(known);\ndeclop(where);\ndeclop(currentdict);\ndeclop(countdictstack);\ndeclop(store);\ndeclop(dictstack);\ndeclop(cleardictstack);\n\n/* Operators for string manipulation\n   tested in string.ps */\n/* -anchorsearch, -search, -token */\ndeclop(string);\ndeclop(_strstr);\ndeclop(_strrstr);\ndeclop(_strchr);\ndeclop(_strrchr);\ndeclop(_strpbrk);\n\n/* Relation, logical, and bit operators\n   tested in relalogbit.ps */\ndeclop(eq);\ndeclop(ne);\ndeclop(true);\ndeclop(false);\ndeclop(and);\ndeclop(or);\ndeclop(xor);\ndeclop(not);\ndeclop(bitshift);\ndeclop(ge);\ndeclop(gt);\ndeclop(le);\ndeclop(lt);\n\n/* Operators for control flow\n * tested in control.ps */\ndeclop(exec);\ndeclop(if);\ndeclop(ifelse);\ndeclop(repeat);\ndeclop(loop);\ndeclop(exit);\ndeclop(stop);\ndeclop(stopped);\ndeclop(for);\ndeclop(quit);\ndeclop(countexecstack);\ndeclop(execstack);\n/* ?start */\n\n/* Operators for type, attribute and their conversion\n * tested in typeattrconv.ps */\ndeclop(type);\ndeclop(cvn);\ndeclop(cvs);\ndeclop(cvx);\n/* cvlit, xcheck, executeonly, noacess, readonly,\n   rcheck, wcheck, cvi, cvr, cvrs, cvs,... */\n\n/* Operators for Virtual Memory Operators  */\n/* ?save, ?restore */\n\n/* Misc operators\n * tested in misc.ps */\ndeclop(null);\ndeclop(bind);\n\n/* Methods for compound objects\n   tested in compound.ps */\ndeclop(length);\ndeclop(copy);\ndeclop(get);\ndeclop(put);\ndeclop(forall);\ndeclop(putinterval);\ndeclop(_copyinterval);\n/* -getinterval .... */\n\n\f\n/*\n * Public functions\n */\n\nint\nopt_init (void)\n{\n\tOPT_TYPE_ARRAY    = es_type_define_fatptr (\"arraytype\",\n\t\t\t\t\t\t\t\t\t\t\t   sizeof (ArrayFat),\n\t\t\t\t\t\t\t\t\t\t\t   array_es_init_fat,\n\t\t\t\t\t\t\t\t\t\t\t   array_es_free,\n\t\t\t\t\t\t\t\t\t\t\t   array_es_equal,\n\t\t\t\t\t\t\t\t\t\t\t   array_es_print);\n\tOPT_TYPE_DICT     = es_type_define_fatptr (\"dicttype\",\n\t\t\t\t\t\t\t\t\t\t\t   sizeof (DictFat),\n\t\t\t\t\t\t\t\t\t\t\t   dict_es_init_fat,\n\t\t\t\t\t\t\t\t\t\t\t   dict_es_free,\n\t\t\t\t\t\t\t\t\t\t\t   dict_es_equal,\n\t\t\t\t\t\t\t\t\t\t\t   dict_es_print);\n\tOPT_TYPE_OPERATOR = es_type_define_fatptr (\"operatortype\",\n\t\t\t\t\t\t\t\t\t\t\t   sizeof (OperatorFat),\n\t\t\t\t\t\t\t\t\t\t\t   operator_es_init_fat,\n\t\t\t\t\t\t\t\t\t\t\t   operator_es_free,\n\t\t\t\t\t\t\t\t\t\t\t   NULL,\n\t\t\t\t\t\t\t\t\t\t\t   operator_es_print);\n\tOPT_TYPE_STRING   = es_type_define_fatptr (\"stringtype\",\n\t\t\t\t\t\t\t\t\t\t\t   sizeof (StringFat),\n\t\t\t\t\t\t\t\t\t\t\t   string_es_init_fat,\n\t\t\t\t\t\t\t\t\t\t\t   string_es_free,\n\t\t\t\t\t\t\t\t\t\t\t   string_es_equal,\n\t\t\t\t\t\t\t\t\t\t\t   string_es_print);\n\tOPT_TYPE_NAME     = es_type_define_fatptr (\"nametype\",\n\t\t\t\t\t\t\t\t\t\t\t   sizeof (NameFat),\n\t\t\t\t\t\t\t\t\t\t\t   name_es_init_fat,\n\t\t\t\t\t\t\t\t\t\t\t   name_es_free,\n\t\t\t\t\t\t\t\t\t\t\t   name_es_equal,\n\t\t\t\t\t\t\t\t\t\t\t   name_es_print);\n\tOPT_TYPE_MARK   = es_type_define_pointer (\"marktype\",\n\t\t\t\t\t\t\t\t\t\t\t  mark_es_free,\n\t\t\t\t\t\t\t\t\t\t\t  mark_es_equal,\n\t\t\t\t\t\t\t\t\t\t\t  mark_es_print);\n\n\tOPT_ERR_UNDEFINED          = es_error_intern (\"undefined\");\n\tOPT_ERR_SYNTAX             = es_error_intern (\"syntaxerror\");\n\tOPT_ERR_UNDERFLOW          = es_error_intern (\"stackunderflow\");\n\tOPT_ERR_TYPECHECK          = es_error_intern (\"typecheck\");\n\tOPT_ERR_RANGECHECK         = es_error_intern (\"rangecheck\");\n\tOPT_ERR_DICTSTACKUNDERFLOW = es_error_intern (\"dictstackunderflow\");\n\tOPT_ERR_UNMATCHEDMARK      = es_error_intern (\"unmatchedmark\");\n\tOPT_ERR_INTERNALERROR      = es_error_intern (\"internalerror\");\n\tOPT_ERR_END_PROC           = es_error_intern (\"}\");\n\tOPT_ERR_INVALIDEXIT        = es_error_intern (\"invalidexit\");\n\tOPT_ERR_STOPPED            = es_error_intern (\"stopped\");\n\tOPT_ERR_QUIT               = es_error_intern (\"quit\");\n\tOPT_ERR_INVALIDACCESS      = es_error_intern (\"invalidaccess\");\n\tOPT_ERR_INTOVERFLOW        = es_error_intern (\"intoverflow\");\n\n\tes_symbol_intern (\"true\");\n\tes_symbol_intern (\"false\");\n\tes_symbol_intern (\"null\");\n\n\tOPT_MARK_ARRAY = mark_new (\"[\");\n\tOPT_MARK_DICT  = mark_new (\"<<\");\n\tOPT_MARK_MARK  = mark_new (\"mark\");\n\n\topt_system_dict = dict_new (101, ATTR_READABLE);\n\n\tes_autounref_pool_push ();\n\n\tdefOP (opt_system_dict, op__print_objdict_rec,\"====\", 1,  \"any === -\");\n\tdefOP (opt_system_dict, op__print_objdict,    \"===\",  1,  \"any === -\");\n\tdefOP (opt_system_dict, op__print_object,     \"==\",   1,  \"any == -\");\n\tdefOP (opt_system_dict, op__print,            \"=\",    1,  \"any = -\");\n\n\tdefOP (opt_system_dict, op__print_object_nonl,\"==+\",  1,  \"any ==+ -\");\n\tdefOP (opt_system_dict, op__print_nonl,       \"=+\",   1,  \"any =+ -\");\n\n\tdefOP (opt_system_dict, op_mark,           \"<<\",  0,  \"- << mark\");\n\tdefOP (opt_system_dict, op_mark,           \"[\",   0,  \"- [ mark\");\n\tdefOP (opt_system_dict, op__make_array,    \"]\",   0,  \"[ any1 ... anyn ] array\");\n\tdefOP (opt_system_dict, op__make_dict ,    \">>\",  0, \"<< key1 value1 ... keyn valuen >> dict\");\n\n\tdefop (opt_system_dict, _help,  0, \"- _HELP -\");\n\tdefop (opt_system_dict, pstack, 0, \"|- any1 ... anyn PSTACK |- any1 ... anyn\");\n\n\tdefop (opt_system_dict, _newerror,  0, \"- _NEWERROR bool\");\n\tdefop (opt_system_dict, _errorname, 0, \"- _ERRORNAME error:name|null\");\n\n\tdefop (opt_system_dict, pop,    1, \"any POP -\");\n\tdefop (opt_system_dict, exch,   2, \"any1 any2 EXCH any2 any1\");\n\tdefop (opt_system_dict, dup,    1, \"any DUP any any\");\n\tdefop (opt_system_dict, index,  1, \"anyn ... any0 n INDEX anyn ... any0 anyn\");\n\tdefop (opt_system_dict, roll,   2, \"any_n-1 ... any0 n j ROLL any_(j-1)_mod_n ... any_n-1 ... any_j_mod_n\");\n\tdefop (opt_system_dict, clear,  0, \"|- any1 ... anyn CLEAR |-\");\n\tdefop (opt_system_dict, count,  0, \"|- any1 ... anyn COUNT any1 ... anyn n\");\n\tdefop (opt_system_dict, mark,   0, \"- MARK mark\");\n\tdefop (opt_system_dict, cleartomark, 1, \"mark any1 ... anyn CLEARTOMARK -\");\n\tdefop (opt_system_dict, counttomark, 1, \"mark any1 ... anyn COUNTTOMARK mark any1 ... anyn n\");\n\n\tdefop (opt_system_dict, add,  2, \"int1 int2 ADD int\");\n\tdefop (opt_system_dict, idiv, 2, \"int1 int2 IDIV int\");\n\tdefop (opt_system_dict, mod,  2, \"int1 int1 MOD int\");\n\tdefop (opt_system_dict, mul,  2, \"int1 int2 MUL int\");\n\tdefop (opt_system_dict, sub,  2, \"int1 int2 SUB int\");\n\tdefop (opt_system_dict, abs,  1, \"int1 ABS int2\");\n\tdefop (opt_system_dict, neg,  1, \"int1 NEG int2\");\n\n\tdefop (opt_system_dict, array,  1, \"int ARRAY array\");\n\tdefop (opt_system_dict, astore, 1, \"any0 ... any_n_1 array ASTORE array\");\n\tdefop (opt_system_dict, aload,  1, \"array ALOAD any0 ... any_n-1 array\");\n\n\tdefop (opt_system_dict, eq,       2, \"any1 any2 EQ bool\");\n\tdefop (opt_system_dict, ne,       2, \"any1 any2 NE bool\");\n\tdefop (opt_system_dict, true,     0, \"- TRUE true\");\n\tdefop (opt_system_dict, false,    0, \"- FALSE false\");\n\tdefop (opt_system_dict, ge,       2, \"int1 int2 GE bool%\"\n\t\t   \"string1 string2 GE bool\");\n\tdefop (opt_system_dict, gt,       2, \"int1 int2 GT bool%\"\n\t\t   \"string1 string2 GT bool\");\n\tdefop (opt_system_dict, le,       2, \"int1 int2 LE bool%\"\n\t\t   \"string1 string2 LE bool\");\n\tdefop (opt_system_dict, lt,       2, \"int1 int2 LT bool%\"\n\t\t   \"string1 string2 LT bool\");\n\tdefop (opt_system_dict, and,      2, \"bool1 bool2 AND bool3%\"\n\t\t   \"int1 int2 AND int3\");\n\tdefop (opt_system_dict, or,       2, \"bool1 bool2 OR bool3%\"\n\t\t   \"int1 int2 OR int3\");\n\tdefop (opt_system_dict, xor,      2, \"bool1 bool2 XOR bool3%\"\n\t\t   \"int1 int2 XOR int3\");\n\tdefop (opt_system_dict, not,      1, \"bool1|int1 NOT bool2|int2\");\n\tdefop (opt_system_dict, bitshift, 2, \"int1 shift BITSHIFT int2\");\n\n\tdefop (opt_system_dict, dict,           1, \"int DICT dict\");\n\tdefop (opt_system_dict, begin,          1, \"dict BEGIN -\");\n\tdefop (opt_system_dict, end,            0, \"- END -\");\n\tdefop (opt_system_dict, def,            2, \"key value DEF -\");\n\tdefop (opt_system_dict, load,           1, \"key LOAD value\");\n\tdefop (opt_system_dict, undef,          2, \"dict key UNDEF -\");\n\tdefop (opt_system_dict, known,          2, \"dict key KNOWN bool\");\n\tdefop (opt_system_dict, where,          1, \"key WHERE dict true%key WHERE false\");\n\tdefop (opt_system_dict, store,          2, \"key value STORE -\");\n\tdefop (opt_system_dict, currentdict,    0, \"- CURRENTDICT dict\");\n\tdefop (opt_system_dict, countdictstack, 0, \"- COUNTDICTSTACK int\");\n\tdefop (opt_system_dict, dictstack,      1, \"array DICTSTACK array\");\n\tdefop (opt_system_dict, cleardictstack, 0, \"- CLEARDICTSTACK -\");\n\n\tdefop (opt_system_dict, string,   1, \"int STRING -\");\n\tdefop (opt_system_dict, _strstr,  2, \"string seek _STRSTR string offset true%\"\n\t\t   \"string seek _STRSTR string false\");\n\tdefop (opt_system_dict, _strrstr, 2, \"string seek _STRRSTR string offset true%\"\n\t\t   \"string seek _STRRSTR string false\");\n\tdefop (opt_system_dict, _strchr,  2, \"string chr _STRCHR string offset true%\"\n\t\t   \"string chr _STRCHR string false\");\n\tdefop (opt_system_dict, _strrchr, 2, \"string chr _STRRCHR string offset true%\"\n\t\t   \"string chr _STRRCHR string false\");\n\tdefop (opt_system_dict, _strpbrk, 2, \"string accept _STRPBRK string offset true%\"\n\t\t   \"string accept _STRPBRK string false\");\n\n\tdefop (opt_system_dict, exec,           1, \"any EXEC -\");\n\tdefop (opt_system_dict, if,             2, \"bool proc IF -\");\n\tdefop (opt_system_dict, ifelse,         3, \"bool proc_t proc_f IFELSE -\");\n\tdefop (opt_system_dict, repeat,         2, \"int proc REPEAT -\");\n\tdefop (opt_system_dict, loop,           1, \"proc LOOP -\");\n\tdefop (opt_system_dict, exit,           0, \"- EXIT -\");\n\tdefop (opt_system_dict, stop,           0, \"- STOP -\");\n\tdefop (opt_system_dict, stopped,        1, \"any STOPPED bool\");\n\tdefop (opt_system_dict, for,            4, \"initial increment limit proc FOR -\");\n\tdefop (opt_system_dict, quit,           0, \"- quit -\");\n\tdefop (opt_system_dict, countexecstack, 0, \"- countexecstack int\");\n\tdefop (opt_system_dict, execstack,      1, \"array EXECSTACK array\");\n\n\tdefop (opt_system_dict, type,   1, \"any TYPE name\");\n\tdefop (opt_system_dict, cvn,    1, \"string CVN name\");\n\tdefop (opt_system_dict, cvs,    2, \"any string CVS string\");\n\tdefop (opt_system_dict, cvx,    1, \"any CVX any\");\n\n\tdefop (opt_system_dict, null,   0, \"- NULL null\");\n\tdefop (opt_system_dict, bind,   1, \"proc BIND proc\");\n\n\tdefop (opt_system_dict, copy,   1, \"any1 ... anyn n COPY any1 ... anyn any1 ... anyn%\"\n\t\t   \"array1 array2 COPY array2%\"\n\t\t   \"dict1 dict2 COPY dict2%\"\n\t\t   \"string1 string2 COPY string2\");\n\tdefop (opt_system_dict, length, 1, \"array LENGTH int%\"\n\t\t   \"dict LENGTH int%\"\n\t\t   \"string LENGTH int\");\n\tdefop (opt_system_dict, get,    2, \"array index GET any%\"\n\t\t   \"dict key GET any%\"\n\t\t   \"string int GET int\");\n\tdefop (opt_system_dict, put,    3, \"array index any PUT -%\"\n\t\t   \"dict key any PUT -%\"\n\t\t   \"string index int PUT -\");\n\tdefop (opt_system_dict, forall, 2, \"array proc FORALL -%\"\n\t\t   \"dict proc FORALL -%\"\n\t\t   \"string proc FORALL -\");\n\tdefop (opt_system_dict, putinterval, 3, \"array1 index array2 PUTINTERVAL -%\"\n\t\t   \"string1 index string2 PUTINTERVAL -\");\n\tdefop (opt_system_dict, _copyinterval, 4, \"array1 index count array2 _COPYINTERVAL array2%\"\n\t\t   \"string1 index count string2 _COPYINTERVAL string2\");\n\n#define defKey(S) OPT_KEY_##S = es_symbol_intern(#S)\n\tdefKey(newerror);\n\tdefKey(errorname);\n\tdefKey(command);\n\tdefKey(ostack);\n\tdefKey(estack);\n\tdefKey(dstack);\n\n\tes_autounref_pool_pop ();\n\n\treturn 0;\n}\n\nOptVM *\nopt_vm_new (MIO *in, MIO *out, MIO *err)\n{\n\tOptVM *vm = xCalloc (1, OptVM);\n\n\tvm->in    = mio_ref (in);\n\tvm->out   = mio_ref (out);\n\tvm->err   = mio_ref (err);\n\n\tEsObject *tmp;\n\n\ttmp = array_new (0);\n\tvm->ostack = (ptrArray *)es_pointer_take (tmp);\n\tes_object_unref (tmp);\n\n\ttmp = array_new (0);\n\tvm->dstack = (ptrArray *)es_pointer_take (tmp);\n\tes_object_unref (tmp);\n\n\ttmp = array_new (0);\n\tvm->estack = (ptrArray *)es_pointer_take (tmp);\n\tes_object_unref (tmp);\n\n\tvm->dstack_protection = 0;\n\tvm_dstack_push (vm, opt_system_dict);\n\tvm->dstack_protection++;\n\n\tvm->error = dict_new (6, ATTR_READABLE|ATTR_WRITABLE);\n\n\tvm->print_depth = 0;\n\tvm->read_depth = 0;\n\tvm->prompt = NULL;\n\n\treturn vm;\n}\n\nvoid\nopt_vm_clear (OptVM *vm, bool clear_app_data)\n{\n\tptrArrayClear  (vm->estack);\n\tptrArrayClear  (vm->ostack);\n\tvm_dstack_clear (vm);\n\tif (clear_app_data)\n\t\tvm->app_data = NULL;\n\tdict_op_clear (vm->error);\n}\n\nvoid\nopt_vm_delete (OptVM *vm)\n{\n\tptrArrayDelete  (vm->estack);\n\tptrArrayDelete (vm->dstack);\n\tptrArrayDelete  (vm->ostack);\n\tes_object_unref (vm->error);\n\n\tmio_unref (vm->err);\n\tmio_unref (vm->out);\n\tmio_unref (vm->in);\n\teFree (vm);\n}\n\nEsObject *\nopt_dict_new (unsigned int size)\n{\n\treturn dict_new (size, ATTR_READABLE|ATTR_WRITABLE);\n}\n\nbool\nopt_dict_known_and_get_cstr (EsObject *dict, const char* name, EsObject **val)\n{\n\tif (es_object_get_type (dict) != OPT_TYPE_DICT)\n\t\treturn false;\n\n\tEsObject *sym = es_symbol_intern (name);\n\treturn dict_op_known_and_get (dict, sym, val);\n}\n\nbool\nopt_dict_foreach (EsObject *dict, bool (* fn) (EsObject *, EsObject *, void*), void *data)\n{\n\tif (es_object_get_type (dict) != OPT_TYPE_DICT)\n\t\treturn false;\n\n\thashTable *htable = es_pointer_get (dict);\n\treturn hashTableForeachItem (htable, (hashTableForeachFunc) fn, data);\n}\n\nvoid\nopt_dict_def (EsObject *dict, EsObject *sym, EsObject *val)\n{\n\tAssert (!es_null(sym));\n\tdict_op_def (dict, sym, val);\n}\n\nbool\nopt_dict_undef (EsObject *dict, EsObject *sym)\n{\n\tAssert (!es_null(sym));\n\treturn dict_op_undef (dict, sym);\n}\n\nvoid\nopt_dict_clear (EsObject *dict)\n{\n\tAssert (es_object_get_type (dict) == OPT_TYPE_DICT);\n\tdict_op_clear (dict);\n}\n\nEsObject *\nopt_array_new (void)\n{\n\treturn array_new (ATTR_READABLE | ATTR_WRITABLE);\n}\n\nEsObject *\nopt_array_get (const EsObject *array, unsigned int index)\n{\n\treturn array_op_get (array, index);\n}\n\nvoid\nopt_array_put (EsObject *array, unsigned int index, EsObject *obj)\n{\n\tarray_op_put (array, index, obj);\n}\n\nvoid\nopt_array_add (EsObject *array, EsObject* elt)\n{\n\tarray_op_add (array, elt);\n}\n\nunsigned int\nopt_array_length(const EsObject *array)\n{\n\treturn array_op_length (array);\n}\n\nvoid\nopt_vm_dstack_push  (OptVM *vm, EsObject *dict)\n{\n\tvm_dstack_push (vm, dict);\n\tvm->dstack_protection++;\n}\n\nvoid\nopt_vm_dstack_pop  (OptVM *vm)\n{\n\tvm->dstack_protection--;\n\tvm_dstack_pop (vm);\n}\n\nEsObject*\nopt_vm_ostack_top (OptVM *vm)\n{\n\treturn vm_ostack_top (vm);\n}\n\nEsObject*\nopt_vm_ostack_peek (OptVM *vm, int index_from_top)\n{\n\treturn vm_ostack_peek (vm, index_from_top);\n}\n\nEsObject*\nopt_vm_ostack_pop (OptVM *vm)\n{\n\treturn vm_ostack_pop (vm);\n}\n\nvoid\nopt_vm_ostack_push        (OptVM *vm, EsObject *obj)\n{\n\tvm_ostack_push (vm, obj);\n}\n\nunsigned int\nopt_vm_ostack_count (OptVM *vm)\n{\n\treturn vm_ostack_count (vm);\n}\n\nstatic EsObject*\nvm_eval (OptVM *vm, EsObject * o)\n{\n\tEsObject *r = es_false;\n\n\tif (es_error_p (o))\n\t{\n\t\tr = o;\n\t\tgoto out;\n\t}\n\telse if (es_object_get_type (o) == OPT_TYPE_NAME)\n\t{\n\t\tunsigned int attr = ((NameFat *)es_fatptr_get (o))->attr;\n\t\tif (attr & ATTR_EXECUTABLE)\n\t\t{\n\t\t\tEsObject *sym = es_pointer_get (o);\n\t\t\tEsObject *val  = es_nil;\n\t\t\tEsObject *dict = vm_dstack_known_and_get (vm, sym, &val);\n\n\t\t\tif (es_object_get_type (dict) == OPT_TYPE_DICT)\n\t\t\t{\n\t\t\t\tint t = es_object_get_type (val);\n\t\t\t\tif (t == OPT_TYPE_OPERATOR)\n\t\t\t\t\tr = vm_call_operator (vm, val);\n\t\t\t\telse if (t == OPT_TYPE_ARRAY\n\t\t\t\t\t\t && (((ArrayFat *)es_fatptr_get (val))->attr & ATTR_EXECUTABLE))\n\t\t\t\t\tr = vm_call_proc (vm, val);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvm_ostack_push (vm, val);\n\t\t\t\t\tr = es_false;\n\t\t\t\t}\n\n\t\t\t\tif (es_error_p (r))\n\t\t\t\t\tgoto out;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tr = es_error_set_object (OPT_ERR_UNDEFINED, o);\n\t\t\t\tvm_record_error (vm, r, o); /* TODO */\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tvm_ostack_push (vm, o);\n\t}\n\telse if (es_object_get_type (o) == OPT_TYPE_OPERATOR)\n\t{\n\t\tr = vm_call_operator (vm, o);\n\t\tgoto out;\n\t}\n\telse\n\t\tvm_ostack_push (vm, o);\n out:\n\treturn r;\n}\n\nEsObject*\nopt_vm_read (OptVM *vm, MIO *in)\n{\n\tEsObject *e;\n\tMIO *tmp;\n\tif (in)\n\t{\n\t\ttmp = vm->in;\n\t\tvm->in = in;\n\t}\n\te = vm_read (vm);\n\tif (in)\n\t\tvm->in = tmp;\n\treturn e;\n}\n\nEsObject *\nopt_vm_eval (OptVM *vm, EsObject *obj)\n{\n\treturn vm_eval (vm, obj);\n}\n\nvoid\nopt_vm_report_error (OptVM *vm, EsObject *eobj, MIO *err)\n{\n\tMIO *tmp;\n\n\tif (err)\n\t{\n\t\ttmp = vm->err;\n\t\tvm->err = err;\n\t}\n\tvm_report_error\t(vm, eobj);\n\tif (err)\n\t\tvm->err = tmp;\n}\n\nchar*\nopt_vm_set_prompt (OptVM *vm, char *prompt)\n{\n\tchar *tmp = vm->prompt;\n\tvm->prompt = prompt;\n\treturn tmp;\n}\n\nvoid\nopt_vm_print_prompt   (OptVM *vm)\n{\n\tif (vm->prompt && vm->read_depth == 0)\n\t{\n\t\tmio_puts (vm->err, vm->prompt);\n\t\tunsigned int c = ptrArrayCount (vm->ostack);\n\n\t\tif (c > 0)\n\t\t\tmio_printf (vm->err, \"<%u> \", c);\n\t\telse\n\t\t\tmio_printf (vm->err, \"> \");\n\t}\n}\n\nvoid*\nopt_vm_get_app_data (OptVM *vm)\n{\n\treturn vm->app_data;\n}\n\nvoid*\nopt_vm_set_app_data (OptVM *vm, void *app_data)\n{\n\tvoid *tmp = vm->app_data;\n\tvm->app_data = app_data;\n\treturn tmp;\n}\n\nint\nopt_vm_help    (OptVM *vm, MIO *out, struct OptHelpExtender *extop, void *data)\n{\n\tvm_help (vm, out? out: vm->out, extop, data);\n\treturn 0;\n}\n\nEsObject *\nopt_operator_new (OptOperatorFn op, const char *name, int arity, const char *help_str)\n{\n\treturn operator_new (op, name, arity, help_str);\n}\n\nEsObject *opt_string_new_from_cstr     (const char *cstr)\n{\n\tvString *vstr = vStringNewInit (cstr? cstr: \"\");\n\treturn string_new (vstr);\n}\n\nconst char* opt_string_get_cstr (const EsObject *str)\n{\n\tvString *vstr = es_pointer_get (str);\n\treturn vStringValue (vstr);\n}\n\nEsObject *opt_name_new_from_cstr (const char *cstr)\n{\n\treturn name_newS (cstr, ATTR_READABLE);\n}\n\nconst char* opt_name_get_cstr (const EsObject *name)\n{\n\tif (es_object_get_type (name) == OPT_TYPE_NAME)\n\t\tname = es_pointer_get (name);\n\tif (!es_symbol_p (name))\n\t\treturn NULL;\n\treturn es_symbol_get (name);\n}\n\n\f\n/*\n * VM\n */\nstatic void\nvm_read_skip_comment(OptVM *vm)\n{\n\twhile (true)\n\t{\n\t\tint c = mio_getc (vm->in);\n\t\tif (c == EOF || c == '\\n' || c == '\\r')\n\t\t{\n\t\t\tif (c != EOF)\n\t\t\t\topt_vm_print_prompt (vm);\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n#define is_meta_char(c) ((c) == '%'\t\t\t\t\\\n\t\t\t\t\t\t || (c) == '/'\t\t\t\\\n\t\t\t\t\t\t || (c) == '('\t\t\t\\\n\t\t\t\t\t\t || (c) == '{'\t\t\t\\\n\t\t\t\t\t\t || (c) == '}'\t\t\t\\\n\t\t\t\t\t\t || (c) == '['\t\t\t\\\n\t\t\t\t\t\t || (c) == ']'\t\t\t\\\n\t\t\t\t\t\t || (c) == '<'\t\t\t\\\n\t\t\t\t\t\t || (c) == '>')\n\nstatic EsObject*\nvm_read_char (OptVM *vm)\n{\n\tint c = mio_getc (vm->in);\n\tint i;\n\n\tif (c == EOF)\n\t\treturn OPT_ERR_SYNTAX;\n\telse if (c == '\\\\')\n\t{\n\t\tc = mio_getc (vm->in);\n\t\tint i;\n\t\tswitch (c)\n\t\t{\n\t\tcase 't':\n\t\t\ti = '\\t';\n\t\t\tbreak;\n\t\tcase 'n':\n\t\t\ti = '\\n';\n\t\t\tbreak;\n\t\tcase 'f':\n\t\t\ti = '\\f';\n\t\t\tbreak;\n\t\tcase 'r':\n\t\t\ti = '\\r';\n\t\t\tbreak;\n\t\tcase 'v':\n\t\t\ti = '\\v';\n\t\t\tbreak;\n\t\tcase ' ':\n\t\tcase '_':\n\t\t\ti = ' ';\n\t\t\tbreak;\n\t\tcase '\\\\':\n\t\t\ti = '\\\\';\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn OPT_ERR_SYNTAX;\n\t\t}\n\t\tc = mio_getc (vm->in);\n\t\tif (!(c == EOF || isspace (c) || is_meta_char (c)))\n\t\t\treturn OPT_ERR_SYNTAX;\n\t\tmio_ungetc (vm->in, c);\n\t\treturn es_integer_new (i);\n\t}\n\telse if (isgraph(c))\n\t{\n\t\ti = c;\n\n\t\tc = mio_getc (vm->in);\n\t\tif (!(c == EOF || isspace (c) || is_meta_char (c)))\n\t\t\treturn OPT_ERR_SYNTAX;\n\t\tmio_ungetc (vm->in, c);\n\n\t\treturn es_integer_new (i);\n\t}\n\telse\n\t\treturn OPT_ERR_SYNTAX;\n}\n\nstatic EsObject*\nvm_read_string (OptVM *vm)\n{\n\tint depth = 0;\n\tvString *s = vStringNew ();\n\twhile (true)\n\t{\n\t\tint c = mio_getc (vm->in);\n\t\tif (c == ')')\n\t\t{\n\t\t\tif (depth == 0)\n\t\t\t\treturn string_new (s);\n\t\t\tvStringPut (s, c);\n\t\t\tdepth--;\n\t\t}\n\t\telse if (c == '(')\n\t\t{\n\t\t\tvStringPut (s, c);\n\t\t\tdepth++;\n\t\t}\n\t\telse if (c == '\\\\')\n\t\t{\n\t\t\tc = mio_getc (vm->in);\n\t\t\tswitch (c)\n\t\t\t{\n\t\t\tcase EOF:\n\t\t\t\tvStringDelete (s);\n\t\t\t\treturn OPT_ERR_SYNTAX;\n\t\t\tcase 'n':\n\t\t\t\tvStringPut (s, '\\n');\n\t\t\t\tbreak;\n\t\t\tcase 't':\n\t\t\t\tvStringPut (s, '\\t');\n\t\t\t\tbreak;\n\t\t\tcase 'r':\n\t\t\t\tvStringPut (s, '\\r');\n\t\t\t\tbreak;\n\t\t\tcase 'f':\n\t\t\t\tvStringPut (s, '\\f');\n\t\t\t\tbreak;\n\t\t\tcase 'v':\n\t\t\t\tvStringPut (s, '\\v');\n\t\t\t\tbreak;\n\t\t\tcase '\\\\':\n\t\t\tcase '(':\n\t\t\tcase ')':\n\t\t\t\tvStringPut (s, c);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tvStringPut (s, c);\n\t\t\t\tbreak;\n\t\t\t\t;\n\t\t\t}\n\t\t}\n\t\telse if (c == EOF)\n\t\t{\n\t\t\tvStringDelete (s);\n\t\t\treturn OPT_ERR_SYNTAX;\n\t\t}\n\t\telse\n\t\t\tvStringPut (s, c);\n\t}\n}\n\nstatic EsObject*\nvm_read_generic(OptVM *vm, int c,\n\t\t\t\tEsObject * (* make_object) (const char *, void *),\n\t\t\t\tvoid *data)\n{\n\tvString *name = vStringNew ();\n\tvStringPut (name, c);\n\n\twhile (1)\n\t{\n\t\tc = mio_getc (vm->in);\n\t\tif (c == EOF)\n\t\t\tbreak;\n\t\telse if (isspace (c) || is_meta_char (c))\n\t\t{\n\t\t\tmio_ungetc (vm->in, c);\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tvStringPut (name, c);\n\t}\n\tEsObject *n = make_object (vStringValue (name), data);\n\tvStringDelete (name);\n\treturn n;\n}\n\nstatic EsObject*\nvm_read_name (OptVM *vm, int c, unsigned int attr)\n{\n\treturn vm_read_generic (vm, c, name_newS_cb, &attr);\n}\n\nstruct name_or_number_data {\n\tunsigned int attr;\n\tbool negative;\n};\n\nstatic EsObject*\nname_or_number_new (const char* s, void *data)\n{\n\tstruct name_or_number_data *d = data;\n\n\tbool number = true;\n\tconst char *t = s;\n\twhile (*t)\n\t{\n\t\tif (!isdigit ((unsigned char) *t))\n\t\t{\n\t\t\tnumber = false;\n\t\t\tbreak;\n\t\t}\n\t\tt++;\n\t}\n\tif (number)\n\t{\n\t\tint n;\n\t\tif (strToInt (s, 10, &n))\n\t\t\treturn es_integer_new (n * ((d->negative)? -1: 1));\n\t\telse\n\t\t\treturn OPT_ERR_INTOVERFLOW;\n\t}\n\telse\n\t\treturn name_newS_cb (s, &d->attr);\n}\n\nstatic EsObject*\nvm_read_name_or_number (OptVM *vm, int c, unsigned int attr, bool negative)\n{\n\tstruct name_or_number_data data = {\n\t\t.attr     = attr,\n\t\t.negative = negative,\n\t};\n\n\treturn vm_read_generic (vm, c, name_or_number_new, &data);\n}\n\nstatic EsObject*\nvm_read_quoted (OptVM *vm)\n{\n\tbool immediate = false;\n\n\tint c = mio_getc (vm->in);\n\tswitch (c)\n\t{\n\tcase '/':\n\t\timmediate = true;\n\t\tc = mio_getc (vm->in);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tEsObject *s = vm_read_name (vm, c, ATTR_READABLE);\n\tif (immediate)\n\t{\n\t\tEsObject *q;\n\n\t\tEsObject *val  = es_nil;\n\t\tEsObject *dict = vm_dstack_known_and_get (vm, s, &val);\n\t\tif (es_object_get_type (dict) == OPT_TYPE_DICT)\n\t\t\tq = es_object_ref (val);\n\t\telse\n\t\t{\n\t\t\tq = es_error_set_object (OPT_ERR_UNDEFINED, s);\n\t\t\tvm_record_error (vm, q, s); /* TODO */\n\t\t}\n\t\tes_object_unref (s);\n\t\treturn q;\n\t}\n\telse\n\t\treturn s;\n}\n\nstatic EsObject*\nvm_read_proc (OptVM *vm)\n{\n\tEsObject *proc = array_new (ATTR_EXECUTABLE|ATTR_READABLE);\n\n\tvm->read_depth++;\n\twhile (true)\n\t{\n\t\tEsObject *o = vm_read (vm);\n\t\tif (es_object_equal (o, OPT_ERR_END_PROC))\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\telse if (es_error_p (o))\n\t\t{\n\t\t\tes_object_unref (proc);\n\t\t\tproc = o;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tarray_op_add (proc, o);\n\t\t\tes_object_unref (o);\n\t\t}\n\t}\n\tvm->read_depth--;\n\treturn proc;\n}\n\nstatic EsObject*\nvm_read (OptVM *vm)\n{\n\twhile (true)\n\t{\n\t\tint c = mio_getc (vm->in);\n\t\tif (c == EOF)\n\t\t\treturn es_object_ref (ES_READER_EOF);\n\t\telse if (c == '\\n' || c == '\\r')\n\t\t{\n\t\t\topt_vm_print_prompt (vm);\n\t\t\tcontinue;\n\t\t}\n\t\telse if (isspace (c))\n\t\t\tcontinue;\n\t\telse if (c == '%')\n\t\t{\n\t\t\tvm_read_skip_comment (vm);\n\t\t\tcontinue;\n\t\t}\n\t\telse if (isdigit (c))\n\t\t{\n\t\t\treturn vm_read_name_or_number (vm, c, ATTR_EXECUTABLE|ATTR_READABLE,\n\t\t\t\t\t\t\t\t\t\t   false);\n\t\t}\n\t\telse if (c == '-' || c == '+')\n\t\t{\n\t\t\tbool negative = (c == '-');\n\t\t\tc = mio_getc (vm->in);\n\t\t\tif (isdigit (c))\n\t\t\t\treturn vm_read_name_or_number (vm, c, ATTR_EXECUTABLE|ATTR_READABLE,\n\t\t\t\t\t\t\t\t\t\t\t   negative);\n\t\t\telse\n\t\t\t{\n\t\t\t\tmio_ungetc (vm->in, c);\n\t\t\t\treturn vm_read_name_or_number (vm, '-', ATTR_EXECUTABLE|ATTR_READABLE,\n\t\t\t\t\t\t\t\t\t\t\t   false);\n\t\t\t}\n\t\t}\n\t\telse if (c == '/')\n\t\t\treturn vm_read_quoted (vm);\n\t\telse if (c == '(')\n\t\t\treturn vm_read_string (vm);\n\t\telse if (c == '{')\n\t\t\treturn vm_read_proc (vm);\n\t\telse if (c == '}')\n\t\t{\n\t\t\tif (vm->read_depth)\n\t\t\t\treturn OPT_ERR_END_PROC;\n\t\t\telse\n\t\t\t\treturn OPT_ERR_SYNTAX;\n\t\t}\n\t\telse if (c == '[' || c == ']')\n\t\t{\n\t\t\tconst char name[2] = { [0] = c, [1] = '\\0' };\n\t\t\tEsObject *s = es_symbol_intern (name);\n\t\t\tEsObject *n = name_new (s, ATTR_EXECUTABLE|ATTR_READABLE);\n\t\t\treturn n;\n\t\t}\n\t\telse if (c == '<' || c == '>')\n\t\t{\n\t\t\tint c0 = mio_getc (vm->in);\n\t\t\tif (c != c0)\n\t\t\t\treturn OPT_ERR_SYNTAX;\n\n\t\t\tconst char name [3] = { [0] = c, [1] = c, [2] = '\\0' };\n\t\t\tEsObject *s = es_symbol_intern (name);\n\t\t\tEsObject *n = name_new (s, ATTR_EXECUTABLE|ATTR_READABLE);\n\t\t\treturn n;\n\t\t}\n\t\telse if (c == '?')\n\t\t\treturn vm_read_char (vm);\n\t\telse\n\t\t\treturn vm_read_name (vm, c, ATTR_EXECUTABLE|ATTR_READABLE);\n\t}\n}\n\nstatic void\nvm_ostack_push (OptVM *vm, EsObject *o)\n{\n\tptrArrayAdd (vm->ostack, es_object_ref (o));\n}\n\nstatic EsObject*\nvm_ostack_pop (OptVM *vm)\n{\n\tunsigned int c = vm_ostack_count (vm);\n\n\tif (c > 0)\n\t{\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\treturn es_false;\n\t}\n\n\treturn OPT_ERR_UNDERFLOW;\n}\n\nstatic unsigned int\nvm_ostack_count (OptVM *vm)\n{\n\treturn ptrArrayCount (vm->ostack);\n}\n\nstatic int\nvm_ostack_counttomark (OptVM *vm)\n{\n\tunsigned int c = ptrArrayCount (vm->ostack);\n\tunsigned int i;\n\n\tif  (c == 0)\n\t\treturn -1;\n\n\tfor (i = c; i > 0; i--)\n\t{\n\t\tEsObject *elt = ptrArrayItem (vm->ostack, i - 1);\n\t\tif (es_object_get_type (elt) == OPT_TYPE_MARK)\n\t\t\tbreak;\n\t}\n\n\tif (i == 0)\n\t\treturn -1;\n\n\tint r = (c - i);\n\tif (r < 0)\t\t\t\t\t/* FIXME */\n\t\tr = -1;\n\treturn r;\n}\n\nstatic EsObject*\nvm_ostack_top (OptVM *vm)\n{\n\tif (ptrArrayCount (vm->ostack) > 0)\n\t\treturn ptrArrayLast (vm->ostack);\n\treturn OPT_ERR_UNDERFLOW;\n}\n\nstatic EsObject*\nvm_ostack_peek (OptVM *vm, int index_from_top)\n{\n\tunsigned int c = ptrArrayCount (vm->ostack);\n\tif (c > (unsigned int)index_from_top)\n\t{\n\t\tunsigned int i = (c - ((unsigned int)index_from_top)) - 1;\n\t\tAssert (i < c);\n\t\treturn ptrArrayItem (vm->ostack, i);\n\t}\n\treturn OPT_ERR_UNDERFLOW;\n}\n\nstatic EsObject*\nvm_dstack_known_and_get (OptVM *vm, EsObject *key, EsObject **val)\n{\n\tif (es_object_get_type (key) == OPT_TYPE_NAME)\n\t\tkey = es_pointer_get (key);\n\n\tint c = ptrArrayCount (vm->dstack);\n\n\tfor (int i = c - 1; i >= 0; i--)\n\t{\n\t\tEsObject *d = ptrArrayItem (vm->dstack, i);\n\t\tif (dict_op_known_and_get (d, key, val))\n\t\t\treturn d;\n\t}\n\treturn es_false;\n}\n\nstatic void\nvm_dict_def (OptVM *vm, EsObject *key, EsObject *val)\n{\n\tAssert (!es_null(key));\n\tdict_op_def (ptrArrayLast(vm->dstack), key, val);\n}\n\nstatic void\nvm_dstack_push  (OptVM *vm, EsObject *o)\n{\n\tptrArrayAdd (vm->dstack, es_object_ref (o));\n}\n\nstatic int\nvm_dstack_count (OptVM *vm)\n{\n\treturn ptrArrayCount (vm->dstack);\n}\n\nstatic EsObject*\nvm_dstack_pop (OptVM *vm)\n{\n\tif (vm_dstack_count (vm) <= vm->dstack_protection)\n\t\treturn OPT_ERR_DICTSTACKUNDERFLOW;\n\tptrArrayDeleteLast (vm->dstack);\n\treturn es_false;\n}\n\nstatic void\nvm_dstack_clear         (OptVM *vm)\n{\n\twhile (ptrArrayCount (vm->dstack) > 1)\n\t\tptrArrayDeleteLast (vm->dstack);\n\n\tvm->dstack_protection = 1;\n}\n\nstatic EsObject*\nvm_call_operator (OptVM *vm, EsObject *op)\n{\n\tEsObject *r;\n\n\tOperator operator = es_pointer_get (op);\n\tOperatorFat *ofat = es_fatptr_get (op);\n\n\tvm_estack_push (vm, op);\n\n\tif (ofat->arity > 0)\n\t{\n\t\tunsigned int c = ptrArrayCount (vm->ostack);\n\t\tif (c < (unsigned int)ofat->arity)\n\t\t{\n\t\t\tvm_estack_pop (vm);\n\t\t\tvm_record_error (vm, OPT_ERR_UNDERFLOW, op);\n\t\t\treturn OPT_ERR_UNDERFLOW;\n\t\t}\n\t}\n\n\tr = (* operator) (vm, ofat->name);\n\tif (es_error_p (r))\n\t{\n\t\tvm_estack_pop (vm);\n\t\tif (es_object_equal (OPT_ERR_STOPPED, r))\n\t\t\tvm_record_stop (vm, op);\n\t\telse\n\t\t\tvm_record_error (vm, r, op);\n\t\treturn r;\n\t}\n\n\tvm_estack_pop (vm);\n\treturn es_false;\n}\n\nstatic EsObject*\nvm_call_proc     (OptVM *vm, EsObject *proc)\n{\n\tptrArray *a = es_pointer_get (proc);\n\tunsigned int c = ptrArrayCount (a);\n\n\tvm_estack_push (vm, proc);\n\tfor (unsigned int i = 0; i < c; i++)\n\t{\n\t\tEsObject *o = ptrArrayItem (a, i);\n\t\tEsObject* e = vm_eval (vm, o);\n\t\tif (es_error_p (e))\n\t\t{\n\t\t\tvm_estack_pop (vm);\t/* ??? */\n\t\t\treturn e;\n\t\t}\n\t}\n\tvm_estack_pop (vm);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nvm_estack_push (OptVM *vm, EsObject *p)\n{\n\tptrArrayAdd (vm->estack, es_object_ref (p));\n\treturn es_false;\n}\n\nstatic EsObject*\nvm_estack_pop (OptVM *vm)\n{\n\tif (ptrArrayCount (vm->estack) < 1)\n\t\treturn OPT_ERR_INTERNALERROR;\n\tptrArrayDeleteLast (vm->estack);\n\treturn es_false;\n}\n\nstatic void\ninsert_spaces (MIO *mio, int n)\n{\n\twhile (n-- > 0)\n\t\tmio_putc(mio, ' ');\n}\n\nstruct htable_print_data {\n\tOptVM *vm;\n\tint dict_recursion;\n};\n\nstatic bool\nhtable_print_entry (const void *key, void *val, void *user_data)\n{\n\tstruct htable_print_data *data = user_data;\n\n\tvm_print_full (data->vm, (EsObject *)key, false, data->dict_recursion);\n\tmio_putc (data->vm->out, ' ');\n\tvm_print_full (data->vm, (EsObject *)val, false, data->dict_recursion);\n\n\treturn true;\n}\n\nstatic bool\nhtable_print_entries (const void *key, void *val, void *user_data)\n{\n\tstruct htable_print_data *data = user_data;\n\n\tinsert_spaces (data->vm->out, data->vm->print_depth * 2);\n\thtable_print_entry (key, val, user_data);\n\tmio_putc (data->vm->out, '\\n');\n\n\treturn true;\n}\n\nstatic void\nvm_print (OptVM *vm, EsObject *elt)\n{\n\tvm_print_full (vm, elt, false, 0);\n}\n\nstatic void\nvm_print_full(OptVM *vm, EsObject *elt, bool string_as_is, int dict_recursion)\n{\n\tif (es_object_equal (elt, es_true))\n\t\tmio_puts (vm->out, \"true\");\n\telse if (es_object_equal (elt, es_false))\n\t\tmio_puts (vm->out, \"false\");\n\telse if (es_object_equal (elt, es_nil))\n\t\tmio_puts (vm->out, \"null\");\n\telse if (es_error_p (elt))\n\t{\n\t\tmio_putc (vm->out, '/');\n\t\tmio_puts (vm->out, es_error_name (elt));\n\t}\n\telse if (es_object_get_type (elt) == OPT_TYPE_DICT)\n\t{\n\t\thashTable *d = es_pointer_get (elt);\n\n\t\tstruct htable_print_data data = {\n\t\t\t.vm = vm,\n\t\t\t.dict_recursion = dict_recursion - 1,\n\t\t};\n\n\t\tif (dict_recursion)\n\t\t{\n\t\t\tswitch (hashTableCountItem (d))\n\t\t\t{\n\t\t\tcase 0:\n\t\t\t\tmio_puts(vm->out, \"<<>> \");\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tmio_puts(vm->out, \"<<\");\n\t\t\t\thashTableForeachItem (d, htable_print_entry, &data);\n\t\t\t\tmio_puts(vm->out, \">> \");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tmio_puts(vm->out, \"<<\\n\");\n\t\t\t\tvm->print_depth++;\n\t\t\t\thashTableForeachItem (d, htable_print_entries, &data);\n\t\t\t\tvm->print_depth--;\n\t\t\t\tinsert_spaces (vm->out, vm->print_depth*2);\n\t\t\t\tmio_puts(vm->out, \">> \");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmio_printf (vm->out, \"-dict:%u-\",\n\t\t\t\t\t\thashTableCountItem (d));\n\t\t}\n\t}\n\telse if (es_object_get_type (elt) == OPT_TYPE_ARRAY)\n\t{\n\t\tArrayFat *afat = (ArrayFat *)es_fatptr_get (elt);\n\t\tptrArray *a    = (ptrArray *)es_pointer_get (elt);\n\t\tunsigned int c = ptrArrayCount (a);\n\t\tint is_proc = (afat->attr & ATTR_EXECUTABLE)? 1: 0;\n\n\t\tmio_putc (vm->out, is_proc? '{': '[');\n\t\tvm->print_depth += is_proc;\n\t\tfor (unsigned int i = 0; i < c; i++)\n\t\t{\n\t\t\tvm_print_full (vm, (EsObject *)ptrArrayItem (a, i), false, dict_recursion);\n\t\t\tif (i != c - 1)\n\t\t\t\tmio_putc (vm->out, ' ');\n\t\t}\n\t\tvm->print_depth -= is_proc;\n\t\tmio_putc (vm->out, is_proc? '}': ']');\n\t}\n\telse if (es_object_get_type (elt) == OPT_TYPE_STRING && string_as_is)\n\t{\n\t\tconst char *cstr = opt_string_get_cstr (elt);\n\t\tmio_puts (vm->out, cstr);\n\t}\n\telse if ((es_object_get_type (elt) == OPT_TYPE_NAME || es_symbol_p (elt))\n\t\t\t && string_as_is)\n\t{\n\t\tconst char *cstr = opt_name_get_cstr (elt);\n\t\tmio_puts (vm->out, cstr);\n\t}\n\telse if (es_symbol_p (elt) && (! string_as_is))\n\t{\n\t\tmio_putc (vm->out, '/');\n\t\tes_print (elt, vm->out);\n\t}\n\telse\n\t\tes_print (elt, vm->out);\n}\n\nstatic bool\ncollect_operators (const void *key, void *value, void *user_data)\n{\n\tptrArray *a = user_data;\n\tEsObject *op   = value;\n\n\tif (es_object_get_type (op) == OPT_TYPE_OPERATOR)\n\t{\n\t\tOperatorFat *ofat = es_fatptr_get (op);\n\t\tif (ofat->help_str)\n\t\t\tptrArrayAdd (a, op);\n\t}\n\treturn true;\n}\n\nstatic const char*\ncallable_get_name (const EsObject *callable)\n{\n\tif (es_object_get_type (callable) == OPT_TYPE_OPERATOR)\n\t{\n\t\tconst OperatorFat *ofat_callable = es_fatptr_get (callable);\n\t\treturn es_symbol_get (ofat_callable->name);\n\t}\n\telse\n\t\treturn opt_name_get_cstr(callable);\n}\n\nstatic int\ncompare_callable_by_name (const void *a, const void *b)\n{\n\tconst char *str_a = callable_get_name (a);\n\tconst char *str_b = callable_get_name (b);\n\n\treturn strcmp (str_a, str_b);\n}\n\nstatic void\nvm_help (OptVM *vm, MIO *out, struct OptHelpExtender *extop, void *data)\n{\n\tunsigned int c = ptrArrayCount (vm->dstack);\n\n\tptrArray *a = ptrArrayNew (NULL);\n\tfor (unsigned int i = 0; i < c; i++)\n\t{\n\t\thashTable *t = es_pointer_get (ptrArrayItem (vm->dstack, i));\n\t\thashTableForeachItem (t, collect_operators, a);\n\t}\n\tif (extop)\n\t\textop->add (a, data);\n\n\tptrArraySort (a, compare_callable_by_name);\n\n\tunsigned int ca = ptrArrayCount (a);\n\tsize_t maxlen = 0;\n\tfor (unsigned int i = 0; i < ca; i++)\n\t{\n\t\tEsObject* obj = ptrArrayItem (a, i);\n\t\tconst char *name = callable_get_name (obj);\n\n\t\tsize_t l = strlen (name);\n\t\tif (l > maxlen)\n\t\t\tmaxlen = l;\n\t}\n\n\tfor (unsigned int i = 0; i < ca; i++)\n\t{\n\t\tEsObject* obj = ptrArrayItem (a, i);\n\t\tconst char *name = NULL;\n\t\tconst char *help_str_head = NULL;\n\t\tconst char *help_str_original = NULL;\n\n\t\tif (es_object_get_type (obj) == OPT_TYPE_OPERATOR)\n\t\t{\n\t\t\tOperatorFat *ofat = es_fatptr_get (obj);\n\t\t\tname = es_symbol_get (ofat->name);\n\t\t\thelp_str_head = ofat->help_str;\n\t\t}\n\t\telse if (extop)\n\t\t{\n\t\t\tname = opt_name_get_cstr (obj);\n\t\t\thelp_str_head = extop->get_help_str (obj, data);\n\t\t}\n\t\thelp_str_original = help_str_head;\n\n\t\tif (name == NULL || help_str_head == NULL)\n\t\t\tcontinue;\n\n\t\twhile (help_str_head)\n\t\t{\n\t\t\tconst char *next = strpbrk (help_str_head, \"%\\n\");\n\t\t\tconst char *label = (help_str_head == help_str_original)? name: NULL;\n\t\t\tif (next)\n\t\t\t{\n\t\t\t\tchar *tmp = eStrndup (help_str_head, next - help_str_head);\n\t\t\t\tbool desc = (tmp[0] == ':');\n\t\t\t\tmio_printf (out, \"%*s%s%s\\n\",\n\t\t\t\t\t\t\t(int)maxlen, label? label: \"\",\n\t\t\t\t\t\t\t((desc || (label == NULL))? \"\t\t\": \"\t->\t\"),\n\t\t\t\t\t\t\t(desc? tmp + 1: tmp));\n\t\t\t\teFree ((char *)tmp);\n\t\t\t\thelp_str_head = next + 1;\n\t\t\t\twhile (*help_str_head && isspace ((unsigned char)*help_str_head))\n\t\t\t\t\thelp_str_head++;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (*help_str_head != '\\0')\n\t\t\t\t{\n\t\t\t\t\tbool desc = (help_str_head[0] == ':');\n\t\t\t\t\tmio_printf (out, \"%*s%s%s\\n\",\n\t\t\t\t\t\t\t\t(int)maxlen, label? label: \"\",\n\t\t\t\t\t\t\t\t((desc || (label == NULL))? \"\t\t\": \"\t->\t\"),\n\t\t\t\t\t\t\t\t(desc? help_str_head + 1: help_str_head));\n\t\t\t\t}\n\t\t\t\thelp_str_head = NULL;\n\t\t\t}\n\t\t}\n\t}\n\n\tptrArrayDelete (a);\n}\n\nstatic EsObject *\narray_new_from_stack (ptrArray *src)\n{\n\tEsObject *dst = array_new (0);\n\tptrArray *a = (ptrArray *)es_pointer_get (dst);\n\tfor (unsigned int i = 0; i < ptrArrayCount(src); i++)\n\t\tptrArrayAdd (a, es_object_ref (ptrArrayItem (src, i)));\n\treturn dst;\n}\n\nstatic void\nvm_record_stop   (OptVM *vm, EsObject *cmd)\n{\n\tdict_op_def (vm->error, OPT_KEY_command, cmd);\n\tdict_op_def (vm->error, OPT_KEY_errorname, es_nil);\n\tdict_op_def (vm->error, OPT_KEY_newerror, es_false);\n\t/* OPT_KEY_{o,e,o}stack are kept as is. */\n}\n\nstatic void\nvm_record_error  (OptVM *vm, EsObject *e, EsObject *cmd)\n{\n\tEsObject *newerror = es_nil;\n\tif (dict_op_known_and_get (vm->error, OPT_KEY_newerror, &newerror)\n\t\t&& es_object_equal (newerror, es_true))\n\t\treturn;\n\n\tdict_op_def (vm->error, OPT_KEY_newerror, es_true);\n\tdict_op_def (vm->error, OPT_KEY_errorname, e);\n\tdict_op_def (vm->error, OPT_KEY_command, cmd);\n\n\tEsObject *a;\n\n\ta = array_new_from_stack (vm->ostack);\n\tdict_op_def (vm->error, OPT_KEY_ostack, a);\n\tes_object_unref (a);\n\n\ta = array_new_from_stack (vm->estack);\n\tdict_op_def (vm->error, OPT_KEY_estack, a);\n\tes_object_unref (a);\n\n\ta = array_new_from_stack (vm->dstack);\n\tdict_op_def (vm->error, OPT_KEY_dstack, a);\n\tes_object_unref (a);\n}\n\nstatic void\nvm_report_error (OptVM *vm, EsObject *e)\n{\n\tMIO *out = vm->out;\n\tvm->out = vm->err;\n\tmio_puts (vm->err, \"Error: \");\n\n\tEsObject *newerror = es_nil;\n\tif (!dict_op_known_and_get (vm->error, OPT_KEY_newerror, &newerror))\n\t{\n\t\tvm_print (vm, e);\n\t\tmio_putc (vm->err, '\\n');\n\t\tgoto out;\n\t}\n\n\tif (es_object_equal (newerror, es_false))\n\t{\n\t\tvm_print (vm, e);\n\t\tmio_putc (vm->err, '\\n');\n\t\tgoto out;\n\t}\n\n\tif (!dict_op_known_and_get (vm->error, OPT_KEY_errorname, &e))\n\t{\n\t\tvm_print (vm, OPT_ERR_INTERNALERROR);\n\t\tmio_putc (vm->err, '\\n');\n\t\tgoto out;\n\t}\n\n\tvm_print (vm, e);\n\n\tEsObject *command = es_nil;\n\tdict_op_known_and_get (vm->error, OPT_KEY_command, &command);\n\tEsObject *attached_object = es_error_get_object (e);\n\n\tif (!es_null (attached_object))\n\t{\n\t\tmio_puts (vm->err, \" in \");\n\t\tvm_print (vm, attached_object);\n\t}\n\telse if (!es_null (command))\n\t{\n\t\tmio_puts (vm->err, \" in \");\n\t\tvm_print (vm, command);\n\t\tcommand = es_nil;\n\t}\n\tmio_putc (vm->err, '\\n');\n\n\tEsObject *ostack = es_nil;\n\tif (dict_op_known_and_get (vm->error, OPT_KEY_ostack, &ostack))\n\t{\n\t\tmio_puts (vm->err, \"Operand stack:\\n\");\n\t\tmio_puts (vm->err, \"top|\");\n\t\tptrArray *a = es_pointer_get (ostack);\n\t\tfor (unsigned int i = ptrArrayCount (a); i > 0; i--)\n\t\t{\n\t\t\tEsObject *o = ptrArrayItem (a, i - 1);\n\t\t\tmio_puts (vm->err, \"   \");\n\t\t\tvm_print (vm, o);\n\t\t}\n\t}\n\tmio_puts (vm->err, \"   |bottom\\n\");\n\n\tEsObject *estack = es_nil;\n\tif (dict_op_known_and_get (vm->error, OPT_KEY_estack, &estack))\n\t{\n\t\tmio_puts (vm->err, \"Execution stack:\\n\");\n\t\tmio_puts (vm->err, \"top|\");\n\n\t\tif (!es_null (command))\n\t\t{\n\t\t\tmio_puts (vm->err, \"   \");\n\t\t\tvm_print (vm, command);\n\t\t}\n\n\t\tptrArray *a = es_pointer_get (estack);\n\t\tfor (unsigned int i = ptrArrayCount (a); i > 0; i--)\n\t\t{\n\t\t\tEsObject *o = ptrArrayItem (a, i - 1);\n\t\t\tmio_puts (vm->err, \"   \");\n\t\t\tvm_print (vm, o);\n\t\t}\n\t}\n\tmio_puts (vm->err, \"   |bottom\\n\");\n\n\tEsObject *dstack = es_nil;\n\tif (dict_op_known_and_get (vm->error, OPT_KEY_dstack, &dstack))\n\t{\n\t\tmio_puts (vm->err, \"Dictionary stack:\\n\");\n\t\tmio_puts (vm->err, \"top|\");\n\t\tptrArray *a = es_pointer_get (dstack);\n\t\tfor (unsigned int i = ptrArrayCount (a); i > 0; i--)\n\t\t{\n\t\t\tEsObject *o = ptrArrayItem (a, i - 1);\n\t\t\tmio_puts (vm->err, \"   \");\n\t\t\tvm_print (vm, o);\n\t\t}\n\t}\n\tmio_puts (vm->err, \"   |bottom\\n\");\n\n out:\n\tdict_op_def (vm->error, OPT_KEY_newerror, es_false);\n\tvm->out = out;\n}\n\nstatic void\nvm_bind_proc (OptVM *vm, ptrArray *proc)\n{\n\tunsigned int c = ptrArrayCount (proc);\n\tfor (unsigned int i = 0; i < c; i++)\n\t{\n\t\tEsObject *x = ptrArrayItem (proc, i);\n\n\t\tif (es_object_get_type (x) == OPT_TYPE_ARRAY)\n\t\t\tvm_bind_proc (vm, es_pointer_get (x));\n\t\telse if (es_object_get_type (x) == OPT_TYPE_NAME)\n\t\t{\n\t\t\tif (!(((NameFat *)es_fatptr_get (x))->attr\n\t\t\t\t  & ATTR_EXECUTABLE))\n\t\t\t\tcontinue;\n\n\t\t\tEsObject* val = NULL;\n\t\t\tEsObject *r = vm_dstack_known_and_get (vm, x, &val);\n\t\t\tif (es_object_get_type (r) == OPT_TYPE_DICT)\n\t\t\t{\n\t\t\t\tif (es_object_get_type (val) == OPT_TYPE_OPERATOR)\n\t\t\t\t\tptrArrayUpdate (proc, i, es_object_ref (val), es_nil);\n\t\t\t}\n\t\t}\n\t}\n}\n\n\f\n/*\n * Array\n */\nstatic EsObject*\narray_new (unsigned int attr)\n{\n\tptrArray *a = ptrArrayNew ((ptrArrayDeleteFunc)es_object_unref);\n\treturn es_fatptr_new  (OPT_TYPE_ARRAY, a, &attr);\n}\n\nstatic EsObject*\narray_shared_new (EsObject* original, unsigned int attr)\n{\n\tptrArray *a = es_pointer_get (original);\n\tptrArrayRef (a);\n\treturn es_fatptr_new (OPT_TYPE_ARRAY, a, &attr);\n}\n\nstatic EsObject*\narray_es_init_fat (void *fat, void *ptr, void *extra)\n{\n\tArrayFat *a = fat;\n\ta->attr = *((unsigned int *)extra);\n\treturn es_false;\n}\n\nstatic void\narray_es_free (void *ptr, void *fat)\n{\n\tif (ptr)\n\t\tptrArrayDelete ((ptrArray *)ptr);\n}\n\nstatic int\narray_es_equal (const void *a, const void *afat, const void *b, const void *bfat)\n{\n\tif (ptrArrayIsEmpty ((ptrArray *)a) && ptrArrayIsEmpty ((ptrArray*)b))\n\t\treturn 1;\n\telse if (a == b)\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nstatic void\narray_es_print (const void *ptr, const void *fat, MIO *out)\n{\n\tunsigned int c = ptrArrayCount ((ptrArray *)ptr);\n\tArrayFat *a = (ArrayFat *)fat;\n\tmio_printf (out, \"%c%c%c count: %u\",\n\t\t\t\t(a->attr & ATTR_READABLE)  ? 'r': '-',\n\t\t\t\t(a->attr & ATTR_WRITABLE)  ? 'w': '-',\n\t\t\t\t(a->attr & ATTR_EXECUTABLE)? 'x': '-',\n\t\t\t\tc);\n}\n\nstatic void\narray_op_add (EsObject* array, EsObject* elt)\n{\n\tptrArray *a = es_pointer_get (array);\n\tptrArrayAdd (a, es_object_ref (elt));\n}\n\nstatic unsigned int\narray_op_length (const EsObject* array)\n{\n\tptrArray *a = es_pointer_get (array);\n\treturn ptrArrayCount (a);\n}\n\nstatic EsObject*\narray_op_get (const EsObject* array, unsigned int n)\n{\n\tptrArray *a = es_pointer_get (array);\n\tunsigned int len = ptrArrayCount (a);\n\tif (n >= len)\n\t\treturn OPT_ERR_RANGECHECK;\n\treturn ptrArrayItem (a, n);\n}\n\nstatic void\narray_op_put (EsObject* array, unsigned int n, EsObject *obj)\n{\n\tptrArray *a = es_pointer_get (array);\n\tptrArrayUpdate (a, n,\n\t\t\t\t\tes_object_ref (obj), es_nil);\n}\n\n\f\n/*\n * Dictionary\n */\nstatic unsigned int\nopt_es_hash (const void * const key)\n{\n\tconst EsObject *k = key;\n\n\tif (es_integer_p (key))\n\t\treturn es_integer_get (key);\n\telse if (es_boolean_p (key))\n\t\treturn es_object_equal (key, es_true)? 1: 0;\n\n\treturn hashPtrhash (k);\n}\n\nstatic bool\nopt_es_eq (const void* a, const void* b)\n{\n\treturn es_object_equal (a, b);\n}\n\nstatic EsObject*\ndict_new (unsigned int size, unsigned int attr)\n{\n\thashTable *t = hashTableNew (size,\n\t\t\t\t\t\t\t\t opt_es_hash,\n\t\t\t\t\t\t\t\t opt_es_eq,\n\t\t\t\t\t\t\t\t (hashTableDeleteFunc)es_object_unref,\n\t\t\t\t\t\t\t\t (hashTableDeleteFunc)es_object_unref);\n\thashTableSetValueForUnknownKey (t, t, NULL);\n\treturn es_fatptr_new  (OPT_TYPE_DICT, t, &attr);\n}\n\nstatic EsObject*\ndict_es_init_fat (void *fat, void *ptr, void *extra)\n{\n\tDictFat *a = fat;\n\ta->attr = *((unsigned int *)extra);\n\treturn es_false;\n}\n\nstatic void\ndict_es_free (void *ptr, void *fat)\n{\n\tif (ptr)\n\t\thashTableDelete ((hashTable *)ptr);\n}\n\nstatic int\ndict_es_equal (const void *a, const void *afat, const void *b, const void *bfat)\n{\n\tif (a == b)\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic void\ndict_es_print (const void *ptr, const void *fat, MIO *out)\n{\n\tunsigned int c = hashTableCountItem ((hashTable *)ptr);\n\tDictFat *a = (DictFat *)fat;\n\tmio_printf (out, \"%c%c%c count: %u\",\n\t\t\t\t(a->attr & ATTR_READABLE)  ? 'r': '-',\n\t\t\t\t(a->attr & ATTR_WRITABLE)  ? 'w': '-',\n\t\t\t\t(a->attr & ATTR_EXECUTABLE)? 'x': '-',\n\t\t\t\tc);\n}\n\nstatic void\ndict_op_def (EsObject* dict, EsObject *key, EsObject *val)\n{\n\thashTable *t = es_pointer_get (dict);\n\tAssert (t);\n\tAssert (!es_null (key));\n\n\tif (es_object_get_type (key) == OPT_TYPE_NAME)\n\t\tkey = es_pointer_get (key);\n\n\tkey = es_object_ref (key);\n\tval = es_object_ref (val);\n\n\tif (hashTableUpdateOrPutItem (t, key, val))\n\t{\n\t\t/* A key in the hashtable is reused. */\n\t\tes_object_unref (key);\n\t}\n}\n\nstatic bool\ndict_op_undef (EsObject *dict, EsObject *key)\n{\n\thashTable *t = es_pointer_get (dict);\n\tAssert (t);\n\n\tif (es_object_get_type (key) == OPT_TYPE_NAME)\n\t\tkey = es_pointer_get (key);\n\n\t/* TODO: handle the case key == NULL */\n\treturn hashTableDeleteItem (t, key);\n}\n\nstatic bool\ndict_op_known_and_get(EsObject* dict, EsObject *key, EsObject **val)\n{\n\thashTable *t = es_pointer_get (dict);\n\tAssert (t);\n\n\tif (es_object_get_type (key) == OPT_TYPE_STRING)\n\t{\n\t\tconst char * cstr = opt_string_get_cstr (key);\n\t\tkey = es_symbol_intern (cstr);\n\t}\n\n\tif (es_object_get_type (key) == OPT_TYPE_NAME)\n\t\tkey = es_pointer_get (key);\n\n\tvoid *tmp = hashTableGetItem (t, key);\n\tif (tmp == t)\n\t\treturn false;\n\n\tif (val)\n\t\t*val = tmp;\n\treturn true;\n}\n\nstatic void\ndict_op_clear (EsObject* dict)\n{\n\thashTable *h = es_pointer_get (dict);\n\tAssert (h);\n\n\thashTableClear (h);\n}\n\n\f\n/*\n * Operator\n */\nstatic EsObject*\noperator_new (Operator op, const char *name, int arity, const char *help_str)\n{\n\tOperatorExtra extra = { .name = name, .arity = arity, .help_str = help_str };\n\treturn es_fatptr_new (OPT_TYPE_OPERATOR, op, &extra);\n}\n\nstatic EsObject*\noperator_es_init_fat (void *fat, void *ptr, void *extra)\n{\n\tOperatorFat *ofat = fat;\n\n\tif (!extra)\n\t{\n\t\tofat->name = NULL;\n\t\treturn es_true;\n\t}\n\n\tOperatorExtra *oextra = extra;\n\tconst char *name = oextra->name;\n\tEsObject *o = es_symbol_intern (name);\n\n\tif (es_error_p (o))\n\t\treturn o;\n\tofat->name = o;\n\tofat->arity = oextra->arity;\n\tofat->help_str = oextra->help_str? eStrdup (oextra->help_str): NULL;\n\treturn es_true;\n}\n\nstatic void\noperator_es_free  (void *ptr, void *fat)\n{\n\tOperatorFat *ofat = fat;\n\tif (ofat->help_str)\n\t\teFree ((char *)ofat->help_str);\n}\n\nstatic void\noperator_es_print (const void *ptr, const void *fat, MIO *out)\n{\n\tOperatorFat *ofat = (OperatorFat *)fat;\n\tmio_printf (out, \"--%s--\", es_symbol_get (ofat->name));\n}\n\n/*\n * String\n */\nstatic EsObject*\nstring_new   (vString *vstr)\n{\n\tunsigned int attr = ATTR_READABLE|ATTR_WRITABLE;\n\n\tif (vstr == NULL)\n\t\tvstr = vStringNew ();\n\n\treturn es_fatptr_new  (OPT_TYPE_STRING, vstr, &attr);\n}\n\nstatic EsObject*\nstring_es_init_fat (void *fat, void *ptr, void *extra)\n{\n\tStringFat *s = fat;\n\ts->attr = *((unsigned int *)extra);\n\treturn es_false;\n}\n\nstatic void\nstring_es_free  (void *ptr, void *fat)\n{\n\tif (ptr)\n\t\tvStringDelete (ptr);\n}\n\nstatic int\nstring_es_equal (const void *a,\n\t\t\t\t const void *afat,\n\t\t\t\t const void *b,\n\t\t\t\t const void *bfat)\n{\n\tif (!strcmp (vStringValue ((vString *)a),\n\t\t\t\t vStringValue ((vString *)b)))\n\t\treturn 1;\n\treturn 0;\n}\n\n\nstatic void\nstring_es_print (const void *ptr, const void *fat, MIO *out)\n{\n\tchar *v = vStringValue ((vString *)ptr);\n\n\tmio_putc (out, '(');\n\twhile (*v != '\\0')\n\t{\n\t\tswitch (*v)\n\t\t{\n\t\tcase '(':\n\t\tcase ')':\n\t\tcase '\\\\':\n\t\t\tmio_putc (out, '\\\\');\n\t\t\tmio_putc (out, *v);\n\t\t\tbreak;\n\t\tcase '\\n':\n\t\t\tmio_putc (out, '\\\\');\n\t\t\tmio_putc (out, 'n');\n\t\t\tbreak;\n\t\tcase '\\r':\n\t\t\tmio_putc (out, '\\\\');\n\t\t\tmio_putc (out, 'r');\n\t\t\tbreak;\n\t\tcase '\\t':\n\t\t\tmio_putc (out, '\\\\');\n\t\t\tmio_putc (out, 't');\n\t\t\tbreak;\n\t\tcase '\\f':\n\t\t\tmio_putc (out, '\\\\');\n\t\t\tmio_putc (out, 'f');\n\t\t\tbreak;\n\t\tcase '\\v':\n\t\t\tmio_putc (out, '\\\\');\n\t\t\tmio_putc (out, 'v');\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tmio_putc (out, *v);\n\t\t}\n\t\tv++;\n\t}\n\tmio_putc (out, ')');\n}\n\n\f\n/*\n * Name\n */\nstatic EsObject*\nname_new     (EsObject* symbol, unsigned int attr)\n{\n\treturn es_fatptr_new (OPT_TYPE_NAME,\n\t\t\t\t\t\t  es_object_ref (symbol), &attr);\n}\n\nstatic EsObject*\nname_newS    (const char*s, unsigned int attr)\n{\n\tEsObject *sym = es_symbol_intern (s);\n\treturn name_new (sym, attr);\n}\n\nstatic EsObject* name_newS_cb (const char*s, void *attr)\n{\n\treturn name_newS (s, *((unsigned int *)attr));\n}\n\nstatic EsObject*\nname_es_init_fat (void *fat, void *ptr, void *extra)\n{\n\tArrayFat *a = fat;\n\ta->attr = *((unsigned int *)extra);\n\treturn es_false;\n}\n\nstatic void\nname_es_print (const void *ptr, const void *fat, MIO *out)\n{\n\tconst EsObject *symbol = ptr;\n\tconst NameFat *qfat = fat;\n\tif (!(qfat->attr & ATTR_EXECUTABLE))\n\t\tmio_putc (out, '/');\n\tconst char *name = es_symbol_get (symbol);\n\tmio_puts (out, name);\n}\n\nstatic void\nname_es_free  (void *ptr, void *fat)\n{\n\tif (ptr)\n\t\tes_object_unref (ptr);\n}\n\nstatic int\nname_es_equal (const void *a, const void *afat,\n\t\t\t   const void *b, const void *bfat)\n{\n\tconst EsObject * asym = a;\n\tconst EsObject * bsym = b;\n\treturn es_object_equal (asym, bsym);\n}\n\n/*\n * Mark\n */\nstatic EsObject*\nmark_new (const char* mark)\n{\n\treturn es_pointer_new (OPT_TYPE_MARK,\n\t\t\t\t\t\t   eStrdup (mark));\n}\n\nstatic void\nmark_es_print (const void *ptr, MIO *out)\n{\n\tif (ptr == NULL || (strcmp (ptr, \"mark\") == 0))\n\t\tmio_printf (out, \"-mark-\");\n\telse\n\t\tmio_printf (out, \"-mark:%s-\", (char *)ptr);\n}\n\nstatic void\nmark_es_free (void *ptr)\n{\n\tif (ptr)\n\t\teFree (ptr);\n}\n\nstatic int\nmark_es_equal (const void *a, const void *b)\n{\n\treturn 1;\n}\n\n\f\n/*\n * Operator implementations\n */\n#define GEN_PRINTER(NAME, BODY,NL)\t\t\t\t\t\t\t\\\n\tstatic EsObject*\t\t\t\t\t\t\t\t\t\t\\\n\tNAME(OptVM *vm, EsObject *name)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tEsObject * elt = ptrArrayRemoveLast (vm->ostack);\t\\\n\t\tBODY;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (NL) mio_putc (vm->out, '\\n');\t\t\t\t\t\\\n\t\tes_object_unref (elt);\t\t\t\t\t\t\t\t\\\n\t\treturn es_false;\t\t\t\t\t\t\t\t\t\\\n\t}\n\nGEN_PRINTER(op__print_objdict_rec, vm_print_full (vm, elt, false, 10), true)\nGEN_PRINTER(op__print_objdict,     vm_print_full (vm, elt, false, 1),  true)\nGEN_PRINTER(op__print_object,      vm_print_full (vm, elt, false, 0),  true)\nGEN_PRINTER(op__print,             vm_print_full (vm, elt, true,  0),  true)\nGEN_PRINTER(op__print_object_nonl, vm_print_full (vm, elt, false, 0),  false)\nGEN_PRINTER(op__print_nonl,        vm_print_full (vm, elt, true,  0),  false)\n\nstatic EsObject*\nop__make_array (OptVM *vm, EsObject *name)\n{\n\tint n0 = vm_ostack_counttomark (vm);\n\tif (n0 < 0)\n\t\treturn OPT_ERR_UNMATCHEDMARK;\n\tunsigned int n = (unsigned int)n0;\n\n\tunsigned int count = vm_ostack_count (vm);\n\tAssert(count > n);\n\n\tEsObject *a = array_new (ATTR_READABLE | ATTR_WRITABLE);\n\tfor (unsigned int i = count - n; i < count; i++)\n\t{\n\t\tEsObject *elt = ptrArrayItem (vm->ostack, i);\n\t\tarray_op_add (a, elt);\n\t}\n\n\tptrArrayDeleteLastInBatch (vm->ostack, n + 1);\n\tvm_ostack_push (vm, a);\n\tes_object_unref (a);\n\treturn es_false;\n}\n\nstatic EsObject*\nop__make_dict (OptVM *vm, EsObject *name)\n{\n\tint n = vm_ostack_counttomark (vm);\n\tif (n < 0)\n\t\treturn OPT_ERR_UNMATCHEDMARK;\n\n\tif (n % 2)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tfor (int i = 0; i < (n / 2); i++)\n\t{\n\t\tEsObject *key = ptrArrayItemFromLast (vm->ostack, 2 * i + 1);\n\n\t\tif (es_object_get_type (key) != OPT_TYPE_NAME\n\t\t\t&& es_object_get_type (key) != OPT_TYPE_STRING\n\t\t\t&& !es_integer_p (key) && !es_boolean_p (key))\n\t\t\treturn OPT_ERR_TYPECHECK;\n\t}\n\n\t/* A hashtable grows automatically when its filling rate is\n\t * grater than 80%. If we put elements between `<<' and `>>' to a dictionary\n\t * initialized with the size equal to the number of elements, the dictionary\n\t * grows once during putting them. Making a 1/0.8 times larger dictionary can\n\t * avoid the predictable growing. */\n\tint size = (10 * (n > 0? (n / 2): 1)) / 8;\n\n\tEsObject *d = dict_new (size, ATTR_READABLE|ATTR_WRITABLE);\n\tfor (int i = 0; i < (n / 2); i++)\n\t{\n\t\tEsObject *val = ptrArrayLast (vm->ostack);\n\t\tEsObject *key = ptrArrayItemFromLast (vm->ostack, 1);\n\t\tbool converted = false;\n\n\t\tif (es_object_get_type (key) == OPT_TYPE_STRING)\n\t\t{\n\t\t\tconst char *cstr = opt_string_get_cstr (key);\n\t\t\tkey = opt_name_new_from_cstr (cstr);\n\t\t\tconverted = true;\n\t\t}\n\t\tdict_op_def (d, key, val);\n\t\tif (converted)\n\t\t\tes_object_unref (key);\n\n\t\tptrArrayDeleteLastInBatch (vm->ostack, 2);\n\t}\n\tptrArrayDeleteLast (vm->ostack); /* Remove the mark */\n\tvm_ostack_push (vm, d);\n\tes_object_unref (d);\n\treturn es_false;\n}\n\nstatic EsObject*\nop__help (OptVM *vm, EsObject *name)\n{\n\tvm_help (vm, vm->out, NULL, NULL);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_pstack (OptVM *vm, EsObject *name)\n{\n\tunsigned int c = vm_ostack_count (vm);\n\n\tfor (unsigned int i = c; i > 0; i--)\n\t{\n\t\tEsObject * elt = ptrArrayItem (vm->ostack, i - 1);\n\t\tvm_print (vm, elt);\n\t\tmio_putc (vm->out, '\\n');\n\t}\n\treturn es_false;\n}\n\nstatic EsObject*\nop__newerror (OptVM *vm, EsObject *name)\n{\n\tEsObject *newerror;\n\tif (dict_op_known_and_get (vm->error, OPT_KEY_newerror, &newerror))\n\t\tvm_ostack_push (vm, newerror);\n\telse\n\t\tvm_ostack_push (vm, es_false);\n\treturn es_false;\n}\n\nstatic EsObject*\nop__errorname (OptVM *vm, EsObject *name)\n{\n\tEsObject *errorname;\n\tif (dict_op_known_and_get (vm->error, OPT_KEY_errorname, &errorname))\n\t{\n\t\tEsObject *sym = es_nil;\n\t\tif (!es_null (errorname))\n\t\t{\n\t\t\tconst char *cstr = es_error_name(errorname);\n\t\t\tsym = opt_name_new_from_cstr (cstr);\n\t\t}\n\t\tvm_ostack_push (vm, sym);\n\t\tif (!es_null (errorname))\n\t\t\tes_object_unref (sym);\n\t}\n\telse\n\t\tvm_ostack_push (vm, es_nil);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_quit (OptVM *vm, EsObject *name)\n{\n\tint c = mio_getc (vm->in);\n\tif (!(c == '\\n' || c == '\\r' || c == EOF))\n\t\tmio_ungetc (vm->in, c);\n\treturn OPT_ERR_QUIT;\n}\n\nstatic EsObject*\nop_countexecstack (OptVM *vm, EsObject *name)\n{\n\tunsigned int c = ptrArrayCount (vm->estack);\n\tint n = c;\n\n\tif (n < 0)\n\t\treturn OPT_ERR_INTERNALERROR; /* TODO: integer overflow */\n\n\tEsObject *nobj = es_integer_new (n);\n\tvm_ostack_push (vm, nobj);\n\tes_object_unref (nobj);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop__stack_common (OptVM *vm, EsObject *name, ptrArray *stack, EsObject *dstarrayobj,\n\t\t\t\t  bool ignoreLast)\n{\n\tunsigned int c = ptrArrayCount (stack);\n\tptrArray *a = es_pointer_get (dstarrayobj);\n\n\tif (ignoreLast && c == 0)\n\t\treturn OPT_ERR_INTERNALERROR; /* TODO: integer overflow */\n\n\tptrArrayClear (a);\n\tfor (unsigned int i = 0; i < c - (ignoreLast? 1: 0); i++)\n\t{\n\t\tEsObject *d = ptrArrayItem (stack, i);\n\t\tptrArrayAdd (a, es_object_ref (d));\n\t}\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_execstack (OptVM *vm, EsObject *name)\n{\n\tEsObject *obj = ptrArrayLast (vm->ostack);\n\tif (es_object_get_type (obj) != OPT_TYPE_ARRAY)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\treturn op__stack_common (vm, name, vm->estack, obj, true);\n}\n\n\f\n/*\n * Operators for operand stack manipulation\n */\nstatic EsObject*\nop_pop (OptVM *vm, EsObject *name)\n{\n\tptrArrayDeleteLast (vm->ostack);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_exch (OptVM *vm, EsObject *name)\n{\n\tEsObject * top = ptrArrayRemoveLast (vm->ostack);\n\tEsObject * next = ptrArrayRemoveLast (vm->ostack);\n\tptrArrayAdd (vm->ostack, top);\n\tptrArrayAdd (vm->ostack, next);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_dup (OptVM *vm, EsObject *name)\n{\n\tEsObject * top = vm_ostack_top (vm);\n\tif (es_error_p (top))\n\t\treturn top;\n\tvm_ostack_push (vm, top);\n\treturn es_false;\n}\n\nstatic bool\ndict_copy_cb (const void *key, void *value, void *user_data)\n{\n\thashTable *dst = user_data;\n\thashTablePutItem (dst, es_object_ref ((void *)key), es_object_ref (value));\n\treturn true;\n}\n\nstatic EsObject*\nop__copy_compound (OptVM *vm, EsObject *name, unsigned int c, EsObject *obj2)\n{\n\tint t = es_object_get_type (obj2);\n\tif (!(t == OPT_TYPE_ARRAY || t == OPT_TYPE_DICT || t == OPT_TYPE_STRING))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tif (c < 2)\n\t\treturn OPT_ERR_UNDERFLOW;\n\n\tEsObject *obj1 = ptrArrayItemFromLast (vm->ostack, 1);\n\tif (es_object_get_type (obj1) != t)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tif (t == OPT_TYPE_ARRAY)\n\t{\n\t\tptrArray *a1 = es_pointer_get (obj1);\n\t\tptrArray *a2 = es_pointer_get (obj2);\n\t\tptrArrayClear (a2);\n\t\tunsigned int len = ptrArrayCount (a1);\n\t\tfor (unsigned int i = 0; i < len; i++)\n\t\t{\n\t\t\tEsObject *o = ptrArrayItem (a1, i);\n\t\t\tptrArrayAdd (a2, es_object_ref (o));\n\t\t}\n\t}\n\telse if (t == OPT_TYPE_DICT)\n\t{\n\t\thashTable *ht1 = es_pointer_get (obj1);\n\t\thashTable *ht2 = es_pointer_get (obj2);\n\t\thashTableClear (ht2);\n\t\thashTableForeachItem (ht1, dict_copy_cb, ht2);\n\t}\n\telse\n\t{\n\t\tvString *str1 = es_pointer_get (obj1);\n\t\tvString *str2 = es_pointer_get (obj2);\n\t\tvStringCopy (str2, str1);\n\t}\n\n\tptrArrayRemoveLast (vm->ostack);\n\tptrArrayDeleteLast (vm->ostack);\n\tptrArrayAdd (vm->ostack, obj2);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_copy (OptVM *vm, EsObject *name)\n{\n\tunsigned int c = vm_ostack_count (vm);\n\n\tif (c > 0)\n\t{\n\t\tEsObject * nobj = ptrArrayLast(vm->ostack);\n\n\n\t\tif (!es_integer_p (nobj))\n\t\t\treturn op__copy_compound (vm, name, c, nobj);\n\n\t\tint n0 = es_integer_get (nobj);\n\t\tif (n0 < 0)\n\t\t\treturn OPT_ERR_RANGECHECK;\n\t\tunsigned int n = (unsigned int)n0;\n\n\t\tc--;\n\n\t\tif (c < n)\n\t\t\treturn OPT_ERR_UNDERFLOW;\n\n\t\tptrArrayDeleteLast(vm->ostack);\n\n\t\tfor (unsigned int i = c - n; i < c; i++)\n\t\t{\n\t\t\tEsObject * elt = ptrArrayItem (vm->ostack, i);\n\t\t\tvm_ostack_push (vm, elt);\n\t\t}\n\t\treturn es_false;\n\t}\n\treturn OPT_ERR_UNDERFLOW;\n}\n\nstatic EsObject*\nop_index (OptVM *vm, EsObject *name)\n{\n\tunsigned int c = vm_ostack_count (vm);\n\n\tEsObject * nobj = ptrArrayLast(vm->ostack);\n\tif (!es_integer_p (nobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n = es_integer_get (nobj);\n\tif (n < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\tif (c < (unsigned int)(n + 2))\n\t\treturn OPT_ERR_UNDERFLOW;\n\n\tptrArrayDeleteLast (vm->ostack);\n\n\tEsObject * elt = ptrArrayItem (vm->ostack, c - n - 2);\n\tvm_ostack_push (vm, elt);\n\treturn es_false;\n\n\treturn OPT_ERR_UNDERFLOW;\n}\n\nstatic EsObject*\nop_roll (OptVM *vm, EsObject *name)\n{\n\tunsigned int c = vm_ostack_count (vm);\n\n\tEsObject *jobj = ptrArrayLast (vm->ostack);\n\tif (!es_integer_p (jobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint j = es_integer_get (jobj);\n\n\tEsObject *nobj = ptrArrayItemFromLast (vm->ostack, 1);\n\tif (!es_integer_p (nobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint n = es_integer_get (nobj);\n\tif (n < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tif ((((int)c) - 2) < n)\n\t\treturn OPT_ERR_UNDERFLOW;\n\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\n\tif (j == 0)\n\t\treturn es_false;\n\n\tunsigned int indx = c - 2 - n;\n\tEsObject *p;\n\tif (j > 0)\n\t{\n\t\twhile (j-- != 0)\n\t\t{\n\t\t\tp = ptrArrayRemoveLast (vm->ostack);\n\t\t\tptrArrayInsertItem (vm->ostack, indx, p);\n\t\t}\n\t}\n\telse\n\t{\n\t\twhile (j++ != 0)\n\t\t{\n\t\t\tp = ptrArrayRemoveItem(vm->ostack, indx);\n\t\t\tptrArrayAdd (vm->ostack, p);\n\t\t}\n\n\t}\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_clear (OptVM *vm, EsObject *name)\n{\n\tptrArrayClear (vm->ostack);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_count (OptVM *vm, EsObject *name)\n{\n\tunsigned int c = ptrArrayCount (vm->ostack);\n\n\tEsObject *n = es_integer_new ((int)c);\n\tptrArrayAdd (vm->ostack, n);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_mark (OptVM *vm, EsObject *name)\n{\n\tEsObject *mark;\n\tif (es_object_equal (name, es_symbol_intern (\"[\")))\n\t\tmark = OPT_MARK_ARRAY;\n\telse if (es_object_equal (name, es_symbol_intern (\"<<\")))\n\t\tmark = OPT_MARK_DICT;\n\telse\n\t\tmark = OPT_MARK_MARK;\n\tvm_ostack_push (vm, mark);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_cleartomark (OptVM *vm, EsObject *name)\n{\n\tint r = vm_ostack_counttomark (vm);\n\n\tif (r < 0)\n\t\treturn OPT_ERR_UNMATCHEDMARK;\n\n\tif (r < 0)\n\t\treturn OPT_ERR_UNMATCHEDMARK;\n\n\tfor (int i = 0; i <= r; i++)\n\t\tptrArrayDeleteLast (vm->ostack);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_counttomark (OptVM *vm, EsObject *name)\n{\n\tint r = vm_ostack_counttomark (vm);\n\n\tif (r < 0)\n\t\treturn OPT_ERR_UNMATCHEDMARK;\n\n\tptrArrayAdd (vm->ostack, es_integer_new (r));\n\treturn es_false;\n}\n\n\f\n/*\n * Arithmetic Operators\n */\n#define INTEGER_BINOP(OP)\t\t\t\t\t\t\t\t\t\\\n\tEsObject *n0obj = ptrArrayLast (vm->ostack);\t\t\t\\\n\tif (!es_integer_p (n0obj))\t\t\t\t\t\t\t\t\\\n\t\treturn OPT_ERR_TYPECHECK;\t\t\t\t\t\t\t\\\n\tint n0 = es_integer_get (n0obj);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tEsObject *n1obj = ptrArrayItemFromLast (vm->ostack, 1);\t\\\n\tif (!es_integer_p (n1obj))\t\t\t\t\t\t\t\t\\\n\t\treturn OPT_ERR_TYPECHECK;\t\t\t\t\t\t\t\\\n\tint n1 = es_integer_get (n1obj);\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tEsObject *r = es_integer_new (n1 OP n0);\t\t\t\t\\\n\tif (es_error_p (r))\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn r;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\t\t\t\t\\\n\tptrArrayAdd (vm->ostack, r);\t\t\t\t\t\t\t\\\n\treturn es_false\n\nstatic EsObject*\nop_add (OptVM *vm, EsObject *name)\n{\n\tINTEGER_BINOP(+);\n}\n\nstatic EsObject*\nop_idiv (OptVM *vm, EsObject *name)\n{\n\tINTEGER_BINOP(/);\n}\n\nstatic EsObject*\nop_mod (OptVM *vm, EsObject *name)\n{\n\tINTEGER_BINOP(%);\n}\n\nstatic EsObject*\nop_mul (OptVM *vm, EsObject *name)\n{\n\tINTEGER_BINOP(*);\n}\n\nstatic EsObject*\nop_sub (OptVM *vm, EsObject *name)\n{\n\tINTEGER_BINOP(-);\n}\n\nstatic EsObject*\nop_abs (OptVM *vm, EsObject *name)\n{\n\tEsObject *nobj = ptrArrayLast (vm->ostack);\n\tif (!es_integer_p (nobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n = es_integer_get(nobj);\n\tif (n >= 0)\n\t\treturn es_false;\n\n\tEsObject *r = es_integer_new (-n);\n\tif (es_error_p (r))\n\t\treturn r;\n\tptrArrayDeleteLast (vm->ostack);\n\tptrArrayAdd (vm->ostack, r);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_neg (OptVM *vm, EsObject *name)\n{\n\tEsObject *nobj = ptrArrayLast (vm->ostack);\n\tif (!es_integer_p (nobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint n = es_integer_get(nobj);\n\tEsObject *r = es_integer_new (-n);\n\tif (es_error_p (r))\n\t\treturn r;\n\tptrArrayDeleteLast (vm->ostack);\n\tptrArrayAdd (vm->ostack, r);\n\treturn es_false;\n}\n\n\f\n/*\n * Operators for array manipulation\n */\nstatic EsObject*\nop_array (OptVM *vm, EsObject *name)\n{\n\tEsObject *nobj = ptrArrayLast (vm->ostack);\n\tif (!es_integer_p (nobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n = es_integer_get (nobj);\n\tif (n < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tptrArrayDeleteLast (vm->ostack);\n\n\tEsObject *array = array_new (ATTR_WRITABLE|ATTR_READABLE);\n\tptrArray *a = es_pointer_get (array);\n\tfor (int i = 0; i < n; i++)\n\t\tptrArrayAdd (a, es_nil);\n\tvm_ostack_push (vm, array);\n\tes_object_unref (array);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_astore (OptVM *vm, EsObject *name)\n{\n\tEsObject *array = ptrArrayLast (vm->ostack);\n\tif (es_object_get_type (array) != OPT_TYPE_ARRAY)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tunsigned int c = ptrArrayCount (vm->ostack);\n\tptrArray *a = es_pointer_get (array);\n\tunsigned int l = ptrArrayCount (a);\n\n\tif (l == 0)\n\t\treturn es_false;\n\n\t/* +1 is for the array itself. */\n\tif (c < (l + 1))\n\t\treturn OPT_ERR_UNDERFLOW;\n\n\tptrArrayClear (a);\n\tptrArrayRemoveLast (vm->ostack);\n\n\tint i = l - 1;\n\tif (i < 0)\n\t\treturn OPT_ERR_INTERNALERROR; /* TODO: integer overflow */\n\tfor (; i >= 0; i--)\n\t{\n\t\tEsObject * o = ptrArrayItemFromLast (vm->ostack, i);\n\t\tptrArrayAdd (a, es_object_ref (o));\n\t}\n\n\tptrArrayDeleteLastInBatch (vm->ostack, l);\n\tvm_ostack_push (vm, array);\n\tes_object_unref (array);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_aload (OptVM *vm, EsObject *name)\n{\n\tEsObject *array = ptrArrayLast (vm->ostack);\n\tif (es_object_get_type (array) != OPT_TYPE_ARRAY)\n\t\treturn OPT_ERR_TYPECHECK;\n\tptrArray *a = es_pointer_get (array);\n\n\tptrArrayRemoveLast (vm->ostack);\n\tunsigned int c =  ptrArrayCount (a);\n\tfor (unsigned int i = 0; i < c; i++)\n\t{\n\t\tEsObject *o = ptrArrayItem (a, i);\n\t\tvm_ostack_push (vm, o);\n\t}\n\tvm_ostack_push (vm, array);\n\tes_object_unref (array);\n\treturn es_false;\n}\n\n\f\n/*\n * Operators for dictionary manipulation\n */\nstatic EsObject*\nop_dict (OptVM *vm, EsObject *name)\n{\n\tEsObject *nobj = ptrArrayLast (vm->ostack);\n\tif (!es_integer_p (nobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n = es_integer_get (nobj);\n\tif (n < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\telse if (n == 0)\n\t\tn = 1;\n\n\tptrArrayDeleteLast (vm->ostack);\n\n\tEsObject *dict = dict_new (n, ATTR_READABLE|ATTR_WRITABLE);\n\tvm_ostack_push (vm, dict);\n\tes_object_unref (dict);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_def (OptVM *vm, EsObject *name)\n{\n\tEsObject *val = ptrArrayLast (vm->ostack);\n\tEsObject *key = ptrArrayItemFromLast (vm->ostack, 1);\n\t/* TODO */\n\tif (es_object_get_type (key) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tvm_dict_def (vm, key, val);\n\n\tptrArrayDeleteLastInBatch(vm->ostack, 2);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_undef (OptVM *vm, EsObject *name)\n{\n\tEsObject *key = ptrArrayLast (vm->ostack);\n\tEsObject *dict = ptrArrayItemFromLast (vm->ostack, 1);\n\n\tif (es_object_get_type (key) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tif (es_object_get_type (dict) != OPT_TYPE_DICT)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tunsigned int attr = ((DictFat *)es_fatptr_get (dict))->attr;\n\tif (!(attr & ATTR_WRITABLE))\n\t\treturn OPT_ERR_INVALIDACCESS;\n\n\tif (!dict_op_undef (dict, key))\n\t\treturn es_error_set_object (OPT_ERR_UNDEFINED, key);\n\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_begin (OptVM *vm, EsObject *name)\n{\n\tEsObject *d = ptrArrayLast (vm->ostack);\n\tif (es_object_get_type (d) != OPT_TYPE_DICT)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tvm_dstack_push (vm, d);\n\tptrArrayDeleteLast (vm->ostack);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_end (OptVM *vm, EsObject *name)\n{\n\treturn vm_dstack_pop (vm);\n}\n\nstatic EsObject*\nop_currentdict (OptVM *vm, EsObject *name)\n{\n\tEsObject *dict = ptrArrayLast (vm->dstack);\n\n\tvm_ostack_push (vm, dict);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_countdictstack (OptVM *vm, EsObject *name)\n{\n\tunsigned int c = ptrArrayCount (vm->dstack);\n\tint n = c;\n\n\tif (n < 0)\n\t\treturn OPT_ERR_INTERNALERROR; /* TODO: integer overflow */\n\n\tEsObject *nobj = es_integer_new (n);\n\tvm_ostack_push (vm, nobj);\n\tes_object_unref (nobj);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_dictstack (OptVM *vm, EsObject *name)\n{\n\tEsObject *obj = ptrArrayLast (vm->ostack);\n\tif (es_object_get_type (obj) != OPT_TYPE_ARRAY)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\treturn op__stack_common (vm, name, vm->dstack, obj, false);\n}\n\nstatic EsObject*\nop_cleardictstack (OptVM *vm, EsObject *name)\n{\n\tunsigned int d = ptrArrayCount (vm->dstack) - vm->dstack_protection;\n\tptrArrayDeleteLastInBatch (vm->dstack, d);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_where (OptVM *vm, EsObject *name)\n{\n\tEsObject *key = ptrArrayLast (vm->ostack);\n\tif (es_object_get_type (key) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *dict = vm_dstack_known_and_get (vm, key, NULL);\n\tptrArrayDeleteLast (vm->ostack);\n\n\tif (es_object_get_type (dict) != OPT_TYPE_DICT)\n\t{\n\t\tvm_ostack_push (vm, es_false);\n\t\treturn es_false;\n\t}\n\telse\n\t{\n\t\tvm_ostack_push (vm, dict);\n\t\tvm_ostack_push (vm, es_true);\n\t\treturn es_false;\n\t}\n}\n\nstatic EsObject*\nop_known (OptVM *vm, EsObject *name)\n{\n\tEsObject *key  = ptrArrayLast (vm->ostack);\n\tEsObject *dict = ptrArrayItemFromLast (vm->ostack, 1);\n\n\tif (es_object_get_type (dict) != OPT_TYPE_DICT)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *b =  dict_op_known_and_get (dict, key, NULL)\n\t\t? es_true\n\t\t: es_false;\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\n\tvm_ostack_push (vm, b);\n\n\treturn false;\n}\n\nstatic EsObject*\nop_store (OptVM *vm, EsObject *name)\n{\n\tEsObject *val = ptrArrayLast (vm->ostack);\n\tEsObject *key = ptrArrayItemFromLast (vm->ostack, 1);\n\n\tif (es_null (key))\n\t\treturn OPT_ERR_TYPECHECK;\n\tif (es_object_get_type (key) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *dict = vm_dstack_known_and_get (vm, key, NULL);\n\tif (es_object_get_type (dict) != OPT_TYPE_DICT)\n\t\tvm_dict_def (vm, key, val);\n\telse if (!(((DictFat *)es_fatptr_get (dict))->attr & ATTR_WRITABLE))\n\t\treturn OPT_ERR_INVALIDACCESS;\n\telse\n\t\tdict_op_def (dict, key, val);\n\n\tptrArrayDeleteLastInBatch(vm->ostack, 2);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_load (OptVM *vm, EsObject *name)\n{\n\tEsObject *key = ptrArrayLast (vm->ostack);\n\tEsObject *val = NULL;\n\tEsObject *dict = vm_dstack_known_and_get (vm, key, &val);\n\n\tif (es_object_get_type (dict) != OPT_TYPE_DICT)\n\t\treturn es_error_set_object (OPT_ERR_UNDEFINED, key);\n\telse\n\t{\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\tvm_ostack_push (vm, val);\n\t\treturn es_false;\n\t}\n}\n\n\f\n/*\n * Operators for string manipulation\n */\nstatic EsObject*\nop_string (OptVM *vm, EsObject *name)\n{\n\tEsObject *nobj = ptrArrayLast (vm->ostack);\n\tif (!es_integer_p (nobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint n = es_integer_get (nobj);\n\tif (n < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tvString *s = vStringNew ();\n\n\twhile (n-- > 0)\n\t\tvStringPut (s, ' ');\n\n\tEsObject *sobj = string_new (s);\n\tptrArrayDeleteLast (vm->ostack);\n\tvm_ostack_push (vm, sobj);\n\tes_object_unref (sobj);\n\treturn es_false;\n}\n\nstatic EsObject*\nop__strstr_common (OptVM *vm, EsObject *name, bool fromTail)\n{\n\tEsObject *seekobj = ptrArrayLast (vm->ostack);\n\tEsObject *strobj = ptrArrayItemFromLast (vm->ostack, 1);\n\n\tif (es_object_get_type (strobj) != OPT_TYPE_STRING)\n\t\treturn OPT_ERR_TYPECHECK;\n\tif (es_object_get_type (seekobj) != OPT_TYPE_STRING)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tvString *stringv = es_pointer_get (strobj);\n\tvString *seekv = es_pointer_get (seekobj);\n\n\tif (vStringLength (stringv) < vStringLength (seekv))\n\t{\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\tvm_ostack_push (vm, es_false);\n\t\treturn es_false;\n\t}\n\n\tconst char *stringc = vStringValue (stringv);\n\tconst char *seekc = vStringValue (seekv);\n\tchar *tmp = (fromTail? strrstr: strstr) (stringc, seekc);\n\n\tif (tmp == NULL)\n\t{\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\tvm_ostack_push (vm, es_false);\n\t\treturn es_false;\n\t}\n\n\tunsigned int ud = tmp - stringc;\n\tint d = (int)ud;\n\tif (d < 0)\n\t\treturn OPT_ERR_INTERNALERROR; /* TODO: integer overflow */\n\n\tptrArrayDeleteLast (vm->ostack);\n\tEsObject* dobj = es_integer_new (d);\n\tvm_ostack_push (vm, dobj);\n\tes_object_unref (dobj);\n\tvm_ostack_push (vm, es_true);\n\treturn es_false;\n}\n\nstatic EsObject*\nop__strstr (OptVM *vm, EsObject *name)\n{\n\treturn op__strstr_common (vm, name, false);\n}\n\nstatic EsObject*\nop__strrstr (OptVM *vm, EsObject *name)\n{\n\treturn op__strstr_common (vm, name, true);\n}\n\nstatic EsObject*\nop__strchr_common (OptVM *vm, EsObject *name, bool fromTail)\n{\n\tEsObject *chrobj = ptrArrayLast (vm->ostack);\n\tEsObject *strobj = ptrArrayItemFromLast (vm->ostack, 1);\n\n\tif (! es_integer_p (chrobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tunsigned int chr = (unsigned int)es_integer_get (chrobj);\n\t/* 0 is unacceptable. */\n\tif (! (0 < chr && chr < 256))\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tif (es_object_get_type (strobj) != OPT_TYPE_STRING)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tvString *strv = es_pointer_get (strobj);\n\tconst char *str = vStringValue (strv);\n\n\tchar * p = (fromTail? strrchr: strchr) (str, (int)chr);\n\tif (p)\n\t{\n\t\tint d = p - str;\n\t\tif (d < 0)\n\t\t\treturn OPT_ERR_INTERNALERROR; /* TODO: integer overflow */\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\tEsObject *dobj = es_integer_new (d);\n\t\tvm_ostack_push (vm, dobj);\n\t\tes_object_unref (dobj);\n\t\tvm_ostack_push (vm, es_true);\n\t\treturn es_false;\n\t}\n\telse\n\t{\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\tvm_ostack_push (vm, es_false);\n\t\treturn es_false;\n\t}\n}\n\nstatic EsObject*\nop__strchr (OptVM *vm, EsObject *name)\n{\n\treturn op__strchr_common (vm, name, false);\n}\n\nstatic EsObject*\nop__strrchr (OptVM *vm, EsObject *name)\n{\n\treturn op__strchr_common (vm, name, true);\n}\n\nstatic EsObject*\nop__strpbrk (OptVM *vm, EsObject *name)\n{\n\tEsObject *acceptobj = ptrArrayLast (vm->ostack);\n\tEsObject *strobj = ptrArrayItemFromLast (vm->ostack, 1);\n\n\tif (es_object_get_type (strobj) != OPT_TYPE_STRING)\n\t\treturn OPT_ERR_TYPECHECK;\n\tif (es_object_get_type (acceptobj) != OPT_TYPE_STRING)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tvString *strv = es_pointer_get (strobj);\n\tvString *acceptv = es_pointer_get (acceptobj);\n\n\tconst char *str = vStringValue (strv);\n\tchar *p = strpbrk (str, vStringValue (acceptv));\n\tif (p)\n\t{\n\t\tint d = p - str;\n\t\tif (d < 0)\n\t\t\treturn OPT_ERR_INTERNALERROR; /* TODO: integer overflow */\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\tEsObject *dobj = es_integer_new (d);\n\t\tvm_ostack_push (vm, dobj);\n\t\tes_object_unref (dobj);\n\t\tvm_ostack_push (vm, es_true);\n\t\treturn es_false;\n\t}\n\telse\n\t{\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\tvm_ostack_push (vm, es_false);\n\t\treturn es_false;\n\t}\n}\n\n\f\n/*\n * Relation, logical, and bit operators\n */\nstatic EsObject*\nop__eq_full (OptVM *vm, EsObject *name, bool inversion)\n{\n\tEsObject *a = ptrArrayItemFromLast (vm->ostack, 0);\n\tEsObject *b = ptrArrayItemFromLast (vm->ostack, 1);\n\n\tbool eq = opt_es_eq (a, b);\n\tEsObject *r = (inversion? (!eq): eq)? es_true: es_false;\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\n\tvm_ostack_push (vm, r);\n\treturn es_false;\n}\n\n\f\n/*\n * Relation, logical, and bit operators\n */\nstatic EsObject*\nop_eq (OptVM *vm, EsObject *name)\n{\n\top__eq_full (vm, name, false);\n\treturn es_false;\n\n}\n\nstatic EsObject*\nop_ne (OptVM *vm, EsObject *name)\n{\n\top__eq_full (vm, name, true);\n\treturn es_false;\n\n}\n\nstatic EsObject*\nop_true (OptVM *vm, EsObject *name)\n{\n\tvm_ostack_push (vm, es_true);\n\treturn es_false;\n\n}\n\nstatic EsObject*\nop_false (OptVM *vm, EsObject *name)\n{\n\tvm_ostack_push (vm, es_false);\n\treturn es_false;\n}\n\n#define CMP_OP(OP)\t\t\t\t\t\t\t\t\t\t\t\\\n\tEsObject *o0 = ptrArrayLast (vm->ostack);\t\t\t\t\\\n\tEsObject *o1 = ptrArrayItemFromLast (vm->ostack, 1);\t\\\n\tEsObject *r;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tif (es_integer_p (o0))\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (!es_integer_p (o1))\t\t\t\t\t\t\t\t\\\n\t\t\treturn OPT_ERR_TYPECHECK;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tint i0 = es_integer_get (o0);\t\t\t\t\t\t\\\n\t\tint i1 = es_integer_get (o1);\t\t\t\t\t\t\\\n\t\tr = es_boolean_new (i1 OP i0);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\telse if (es_object_get_type (o0) == OPT_TYPE_STRING)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (es_object_get_type (o1) != OPT_TYPE_STRING)\t\t\\\n\t\t\treturn OPT_ERR_TYPECHECK;\t\t\t\t\t\t\\\n\t\tvString *vs0 = es_pointer_get (o0);\t\t\t\t\t\\\n\t\tvString *vs1 = es_pointer_get (o1);\t\t\t\t\t\\\n\t\tconst char *s0 = vStringValue (vs0);\t\t\t\t\\\n\t\tconst char *s1 = vStringValue (vs1);\t\t\t\t\\\n\t\tint d = strcmp (s1, s0);\t\t\t\t\t\t\t\\\n\t\tr = es_boolean_new (d OP 0);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn OPT_ERR_TYPECHECK;\t\t\t\t\t\t\t\\\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\t\t\t\t\\\n\tvm_ostack_push (vm, r);\t\t\t\t\t\t\t\t\t\\\n\tes_object_unref (r);\t\t\t\t\t\t\t\t\t\\\n\treturn es_false\n\nstatic EsObject*\nop_ge (OptVM *vm, EsObject *name)\n{\n\tCMP_OP (>=);\n}\n\nstatic EsObject*\nop_gt (OptVM *vm, EsObject *name)\n{\n\tCMP_OP (>);\n}\n\nstatic EsObject*\nop_le (OptVM *vm, EsObject *name)\n{\n\tCMP_OP (<=);\n}\n\nstatic EsObject*\nop_lt (OptVM *vm, EsObject *name)\n{\n\tCMP_OP (<);\n}\n\n#define LOGBIT_OP(LOGOP, BITOP)\t\t\t\t\t\t\t\t\t\\\n\tEsObject *o0 = ptrArrayLast (vm->ostack);\t\t\t\t\t\\\n\tEsObject *o1 = ptrArrayItemFromLast (vm->ostack, 1);\t\t\\\n\tEsObject *r;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tif (es_boolean_p (o0))\t\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (!es_boolean_p (o1))\t\t\t\t\t\t\t\t\t\\\n\t\t\treturn OPT_ERR_TYPECHECK;\t\t\t\t\t\t\t\\\n\t\tbool b0 = es_boolean_get (o0);\t\t\t\t\t\t\t\\\n\t\tbool b1 = es_boolean_get (o1);\t\t\t\t\t\t\t\\\n\t\tbool b  = b0 LOGOP b1;\t\t\t\t\t\t\t\t\t\\\n\t\tr = es_boolean_new (b);\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\telse if (es_integer_p (o0))\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (!es_integer_p (o1))\t\t\t\t\t\t\t\t\t\\\n\t\t\treturn OPT_ERR_TYPECHECK;\t\t\t\t\t\t\t\\\n\t\tint i0 = es_integer_get (o0);\t\t\t\t\t\t\t\\\n\t\tint i1 = es_integer_get (o1);\t\t\t\t\t\t\t\\\n\t\tint i  = i0 BITOP i1;\t\t\t\t\t\t\t\t\t\\\n\t\tr = es_integer_new (i);\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn OPT_ERR_TYPECHECK;\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\t\t\t\t\t\\\n\tvm_ostack_push (vm, r);\t\t\t\t\t\t\t\t\t\t\\\n\tes_object_unref (r);\t\t\t\t\t\t\t\t\t\t\\\n\treturn es_false;\n\nstatic EsObject*\nop_and (OptVM *vm, EsObject *name)\n{\n\tLOGBIT_OP (&&, &);\n}\n\nstatic EsObject*\nop_or (OptVM *vm, EsObject *name)\n{\n\tLOGBIT_OP (||, |);\n}\n\nstatic EsObject*\nop_xor (OptVM *vm, EsObject *name)\n{\n\tLOGBIT_OP (!=, ^);\n}\n\nstatic EsObject*\nop_not (OptVM *vm, EsObject *name)\n{\n\tEsObject *o = ptrArrayLast (vm->ostack);\n\tEsObject *r;\n\n\tif (es_boolean_p (o))\n\t\tr = es_boolean_new (!es_boolean_get (o));\n\telse if (es_integer_p (o))\n\t\tr = es_integer_new (~ es_integer_get (o));\n\telse\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tptrArrayDeleteLast (vm->ostack);\n\tvm_ostack_push (vm, r);\n\tes_object_unref (r);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_bitshift (OptVM *vm, EsObject *name)\n{\n\tEsObject *shiftobj = ptrArrayLast (vm->ostack);\n\tif (!es_integer_p (shiftobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *iobj = ptrArrayItemFromLast (vm->ostack, 1);\n\tif (!es_integer_p (iobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint shift = es_integer_get (shiftobj);\n\tint i = es_integer_get (iobj);\n\n\tEsObject *r;\n\tif (i == 0 || shift == 0)\n\t\tr = es_object_ref (iobj);\n\telse if (shift > 0)\n\t\tr = es_integer_new (i << shift);\n\telse\n\t\tr = es_integer_new (i >> -shift);\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\n\tvm_ostack_push (vm, r);\n\tes_object_unref (r);\n\n\treturn es_false;\n}\n\n\f\n/*\n * Operators for control flow\n */\nstatic EsObject*\nop_exec (OptVM *vm, EsObject *name)\n{\n\tEsObject *x = ptrArrayRemoveLast (vm->ostack);\n\n\tEsObject *e;\n\tif (es_object_get_type (x) == OPT_TYPE_ARRAY\n\t\t&& (((ArrayFat *)es_fatptr_get (x))->attr & ATTR_EXECUTABLE))\n\t\te = vm_call_proc (vm, x);\n\telse\n\t\te = vm_eval (vm, x);\n\n\tes_object_unref (x);\n\treturn e;\n}\n\nstatic EsObject*\nop_if (OptVM *vm, EsObject *name)\n{\n\tEsObject *proc = ptrArrayLast (vm->ostack);\n\tif (!((es_object_get_type (proc) == OPT_TYPE_ARRAY)\n\t\t  && (((ArrayFat *)es_fatptr_get (proc))->attr & ATTR_EXECUTABLE)))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *b = ptrArrayItemFromLast\t(vm->ostack, 1);\n\tif (!es_boolean_p (b))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tif (es_object_equal (b, es_false))\n\t{\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\treturn es_false;\n\t}\n\n\tes_object_ref (proc);\n\tptrArrayDeleteLast (vm->ostack);\n\tptrArrayDeleteLast (vm->ostack);\n\tEsObject *e = vm_call_proc (vm, proc);\n\tes_object_unref (proc);\n\n\treturn e;\n}\n\nstatic EsObject*\nop_ifelse (OptVM *vm, EsObject *name)\n{\n\tEsObject *procf = ptrArrayLast (vm->ostack);\n\tif (!((es_object_get_type (procf) == OPT_TYPE_ARRAY)\n\t\t  && (((ArrayFat *)es_fatptr_get (procf))->attr & ATTR_EXECUTABLE)))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *proct = ptrArrayItemFromLast\t(vm->ostack, 1);\n\tif (!((es_object_get_type (proct) == OPT_TYPE_ARRAY)\n\t\t  && (((ArrayFat *)es_fatptr_get (proct))->attr & ATTR_EXECUTABLE)))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *b = ptrArrayItemFromLast\t(vm->ostack, 2);\n\tif (!es_boolean_p (b))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *p = (es_object_equal (b, es_false))? procf: proct;\n\n\tes_object_ref (p);\n\tptrArrayDeleteLast (vm->ostack);\n\tptrArrayDeleteLast (vm->ostack);\n\tptrArrayDeleteLast (vm->ostack);\n\tEsObject *e = vm_call_proc (vm, p);\n\tes_object_unref (p);\n\n\treturn e;\n}\n\nstatic EsObject*\nop_loop (OptVM *vm, EsObject *name)\n{\n\tEsObject *proc = ptrArrayLast (vm->ostack);\n\tif (!((es_object_get_type (proc) == OPT_TYPE_ARRAY)\n\t\t  && (((ArrayFat *)es_fatptr_get (proc))->attr & ATTR_EXECUTABLE)))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tes_object_ref (proc);\n\tptrArrayDeleteLast (vm->ostack);\n\n\tEsObject *e;\n\twhile (true)\n\t{\n\t\te = vm_call_proc (vm, proc);\n\t\tif (es_object_equal (e, OPT_ERR_INVALIDEXIT))\n\t\t{\n\t\t\tdict_op_def (vm->error, OPT_KEY_newerror, es_false);\n\t\t\te = es_false;\n\t\t\tbreak;\n\t\t}\n\t\telse if (es_error_p (e))\n\t\t\tbreak;\n\t}\n\tes_object_unref (proc);\n\treturn e;\n}\n\nstatic EsObject*\nop_exit (OptVM *vm, EsObject *name)\n{\n\treturn OPT_ERR_INVALIDEXIT;\n}\n\nstatic EsObject*\nop_repeat (OptVM *vm, EsObject *name)\n{\n\tEsObject *proc = ptrArrayLast (vm->ostack);\n\tif (!((es_object_get_type (proc) == OPT_TYPE_ARRAY)\n\t\t  && (((ArrayFat *)es_fatptr_get (proc))->attr & ATTR_EXECUTABLE)))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *nobj = ptrArrayItemFromLast (vm->ostack, 1);\n\tif (!es_integer_p (nobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n = es_integer_get (nobj);\n\tif (n < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tes_object_ref (proc);\n\tptrArrayDeleteLast (vm->ostack);\n\tptrArrayDeleteLast (vm->ostack);\n\n\tEsObject *e = es_false;\n\tfor (int i = 0; i < n; i++)\n\t{\n\t\te = vm_call_proc (vm, proc);\n\t\tif (es_object_equal (e, OPT_ERR_INVALIDEXIT))\n\t\t{\n\t\t\tdict_op_def (vm->error, OPT_KEY_newerror, es_false);\n\t\t\te = es_false;\n\t\t\tbreak;\n\t\t}\n\t\telse if (es_error_p (e))\n\t\t\tbreak;\n\t}\n\tes_object_unref (proc);\n\treturn e;\n}\n\nstatic EsObject*\nop_stop (OptVM *vm, EsObject *name)\n{\n\treturn OPT_ERR_STOPPED;\n}\n\nstatic EsObject*\nop_stopped (OptVM *vm, EsObject *name)\n{\n\tEsObject *e = op_exec (vm, name);\n\tvm_ostack_push (vm, es_error_p (e)? es_true: es_false);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_for (OptVM *vm, EsObject *name)\n{\n\tEsObject *proc = ptrArrayLast (vm->ostack);\n\tif (!((es_object_get_type (proc) == OPT_TYPE_ARRAY)\n\t\t  && (((ArrayFat *)es_fatptr_get (proc))->attr & ATTR_EXECUTABLE)))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *limitobj = ptrArrayItemFromLast (vm->ostack, 1);\n\tif (! es_integer_p (limitobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint limit = es_integer_get (limitobj);\n\n\tEsObject *incrementobj = ptrArrayItemFromLast (vm->ostack, 2);\n\tif (! es_integer_p (incrementobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint increment = es_integer_get (incrementobj);\n\n\tEsObject *initialobj = ptrArrayItemFromLast (vm->ostack, 3);\n\tif (! es_integer_p (initialobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint initial = es_integer_get (initialobj);\n\n\tptrArrayRemoveLast (vm->ostack);\n\tptrArrayDeleteLastInBatch (vm->ostack, 3);\n\n\tEsObject *r = es_false;\n\tfor (int i = initial;\n\t\t (increment >= 0) ? (i <= limit) : (i >= limit);\n\t\t i += increment)\n\t{\n\t\tEsObject *iobj = es_integer_new (i);\n\t\tvm_ostack_push (vm, iobj);\n\t\tr = vm_call_proc (vm, proc);\n\t\tes_object_unref (iobj);\n\n\t\tif (es_object_equal (r, OPT_ERR_INVALIDEXIT))\n\t\t{\n\t\t\tdict_op_def (vm->error, OPT_KEY_newerror, es_false);\n\t\t\tr = es_false;\n\t\t\tbreak;\n\t\t}\n\t\tif (es_error_p (r))\n\t\t\tbreak;\n\t}\n\tes_object_unref (proc);\n\treturn r;\n}\n\n\f\n/*\n * Operators for type, attribute and their conversion\n */\nstatic const char*\nget_type_name (EsObject *o)\n{\n\tconst char *n;\n\n\tif (o == es_nil)\n\t\tn = \"nulltype\";\n\telse if (es_boolean_p (o))\n\t\tn = \"booleantype\";\n\telse if (es_integer_p (o))\n\t\tn = \"integertype\";\n\telse\n\t{\n\t\tint t = es_object_get_type (o);\n\t\tn = es_type_get_name (t);\n\t}\n\n\treturn n;\n}\n\nstatic EsObject*\nop_type (OptVM *vm, EsObject *name)\n{\n\tEsObject *o = ptrArrayRemoveLast (vm->ostack);\n\tconst char *n;\n\n\tn = get_type_name (o);\n\n\tEsObject *p = name_newS (n, ATTR_EXECUTABLE|ATTR_READABLE);\n\tvm_ostack_push (vm, p);\n\tes_object_unref (p);\n\tes_object_unref (o);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_cvn (OptVM *vm, EsObject *name)\n{\n\tEsObject *o = ptrArrayLast (vm->ostack);\n\tif (es_object_get_type (o) != OPT_TYPE_STRING)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tvString *vstr = es_pointer_get (o);\n\tconst char *cstr = vStringValue (vstr);\n\tStringFat *sfat = es_fatptr_get (o);\n\tEsObject *n = name_newS (cstr, sfat->attr);\n\tptrArrayDeleteLast (vm->ostack);\n\tvm_ostack_push (vm, n);\n\tes_object_unref (n);\n\treturn es_false;\n}\n\nstatic EsObject *\nop_cvs (OptVM *vm, EsObject *name)\n{\n\tEsObject *o = ptrArrayLast (vm->ostack);\n\tif (es_object_get_type (o) != OPT_TYPE_STRING)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *any = ptrArrayItemFromLast (vm->ostack, 1);\n\tvString *vstr = es_pointer_get (o);\n\tint t = es_object_get_type (any);\n\n\tif (t == OPT_TYPE_STRING)\n\t{\n\t\tvString *vany = es_pointer_get (any);\n\t\tvStringCopy (vstr, vany);\n\t}\n\telse if (t == OPT_TYPE_NAME || t == ES_TYPE_SYMBOL)\n\t{\n\t\tif (t == OPT_TYPE_NAME)\n\t\t\tany = es_pointer_get (any);\n\n\t\tconst char *cany = es_symbol_get (any);\n\t\tvStringCopyS (vstr, cany);\n\t}\n\telse if (t == ES_TYPE_INTEGER)\n\t{\n\t\tint iany = es_integer_get (any);\n#define buf_len 13\n\t\tchar buf[buf_len];\n\t\tif (!(snprintf (buf, buf_len, \"%d\", iany) > 0))\n\t\t\tbuf [0] = '\\0';\n\t\tvStringCopyS (vstr, buf);\n\t}\n\telse if (t == ES_TYPE_BOOLEAN)\n\t\tvStringCopyS (vstr, any == es_true? \"true\": \"false\");\n\telse\n\t{\n\t\tconst char *type_name = get_type_name (any);\n\t\tvStringCopyS (vstr, \"--\");\n\t\tvStringCatS (vstr, type_name);\n\t\tvStringCatS (vstr, \"--\");\n\t}\n\n\tes_object_ref (o);\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\n\tvm_ostack_push (vm, o);\n\tes_object_unref (o);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop_cvx (OptVM *vm, EsObject *name)\n{\n\tEsObject *o = ptrArrayLast (vm->ostack);\n\n\tif (es_object_get_type (o) == OPT_TYPE_ARRAY\n\t\t&& (! (((ArrayFat *)es_fatptr_get (o))->attr & ATTR_EXECUTABLE)))\n\t{\n\t\tEsObject *xarray = array_shared_new (o,\n\t\t\t\t\t\t\t\t\t\t\t ((ArrayFat *)es_fatptr_get (o))->attr | ATTR_EXECUTABLE);\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\tvm_ostack_push (vm, xarray);\n\t\tes_object_unref(xarray);\n\n\t}\n\telse if (es_object_get_type (o) == OPT_TYPE_NAME\n\t\t\t && (! (((NameFat *)es_fatptr_get (o))->attr & ATTR_EXECUTABLE)))\n\t{\n\t\tEsObject *symbol = es_pointer_get (o);\n\t\tEsObject *xname = name_new (symbol, ((NameFat *)es_fatptr_get (o))->attr | ATTR_EXECUTABLE);\n\t\tptrArrayDeleteLast (vm->ostack);\n\t\tvm_ostack_push (vm, xname);\n\t\tes_object_unref(xname);\n\t}\n\n\treturn es_false;\n}\n\n\f\n/*\n * Misc operators\n */\nstatic EsObject*\nop_null (OptVM *vm, EsObject *name)\n{\n\tvm_ostack_push (vm, es_nil);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_bind (OptVM *vm, EsObject *name)\n{\n\tEsObject *proc = ptrArrayLast (vm->ostack);\n\tif (!((es_object_get_type (proc) == OPT_TYPE_ARRAY)\n\t\t  && (((ArrayFat *)es_fatptr_get (proc))->attr & ATTR_EXECUTABLE)))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tvm_bind_proc (vm, es_pointer_get (proc));\n\treturn es_false;\n}\n\n\f\n/*\n * Methods for compound objects\n */\nstatic EsObject*\nop_length (OptVM *vm, EsObject *name)\n{\n\tEsObject *o = ptrArrayLast (vm->ostack);\n\tunsigned int c;\n\n\tint t = es_object_get_type (o);\n\tif (t == OPT_TYPE_ARRAY)\n\t{\n\t\tptrArray *a = es_pointer_get (o);\n\t\tc = ptrArrayCount (a);\n\t}\n\telse if (t == OPT_TYPE_DICT)\n\t{\n\t\thashTable *h = es_pointer_get (o);\n\t\tc = hashTableCountItem (h);\n\t}\n\telse if (t == OPT_TYPE_STRING)\n\t{\n\t\tvString *s = es_pointer_get (o);\n\t\tc = (unsigned int)vStringLength (s);\n\t}\n\telse if (t == OPT_TYPE_NAME)\n\t{\n\t\tEsObject *sym = es_pointer_get (o);\n\t\tconst char* cstr = es_symbol_get (sym);\n\t\tc = (unsigned int) strlen (cstr);\n\t}\n\telse\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n = c;\n\tif (n < 0)\n\t\treturn OPT_ERR_INTERNALERROR; /* TODO: integer overflow */\n\n\tptrArrayDeleteLast (vm->ostack);\n\tEsObject *nobj = es_integer_new (n);\n\tvm_ostack_push (vm, nobj);\n\tes_object_unref (nobj);\n\n\treturn es_false;\n}\n\nstatic EsObject*\nop__get_array (OptVM *vm, EsObject *name,\n\t\t\t   EsObject *k, EsObject *obj)\n{\n\tif (!es_integer_p (k))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint n = es_integer_get (k);\n\tif (n < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\tEsObject *r = array_op_get (obj, (unsigned int)n);\n\tif (es_error_p (r))\n\t\treturn r;\n\tes_object_ref (r);\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\n\tvm_ostack_push (vm, r);\n\tes_object_unref (r);\n\treturn es_false;\n}\n\nstatic EsObject*\nop__get_dict (OptVM *vm, EsObject *name,\n\t\t\t  EsObject *k, EsObject *obj)\n{\n\tEsObject *v = NULL;\n\tif (!dict_op_known_and_get (obj, k, &v))\n\t\treturn es_error_set_object (OPT_ERR_UNDEFINED, k);\n\tes_object_ref (v);\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\n\tvm_ostack_push (vm, v);\n\tes_object_unref (v);\n\treturn es_false;\n}\n\nstatic EsObject*\nop__get_str (OptVM *vm, EsObject *name,\n\t\t\t EsObject *k, EsObject *obj)\n{\n\tif (!es_integer_p (k))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint n = es_integer_get (k);\n\tif (n < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\tvString *s = es_pointer_get (obj);\n\tunsigned int len = vStringLength (s);\n\tif ((unsigned int)n >= len)\n\t\treturn OPT_ERR_RANGECHECK;\n\tunsigned char chr = vStringChar (s, n);\n\tptrArrayDeleteLastInBatch (vm->ostack, 2);\n\tEsObject *chrobj = es_integer_new (chr);\n\tvm_ostack_push (vm, chrobj);\n\tes_object_unref (chrobj);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_get (OptVM *vm, EsObject *name)\n{\n\tEsObject *k = ptrArrayLast (vm->ostack);\n\tEsObject *obj = ptrArrayItemFromLast (vm->ostack, 1);\n\n\tint t = es_object_get_type (obj);\n\tif (t == OPT_TYPE_ARRAY)\n\t\treturn op__get_array (vm, name, k, obj);\n\telse if (t == OPT_TYPE_DICT)\n\t\treturn op__get_dict (vm, name, k, obj);\n\telse if (t == OPT_TYPE_STRING)\n\t\treturn op__get_str (vm, name, k, obj);\n\n\treturn OPT_ERR_TYPECHECK;\n}\n\nstatic EsObject*\nop__put_array (OptVM *vm, EsObject *name,\n\t\t\t   EsObject *v, EsObject *k, EsObject *array)\n{\n\tif (!es_integer_p (k))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint index = es_integer_get (k);\n\tif (index < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tarray_op_put (array, (unsigned int)index, v);\n\tptrArrayDeleteLastInBatch (vm->ostack, 3);\n\treturn es_false;\n}\n\nstatic EsObject*\nop__put_dict (OptVM *vm, EsObject *name,\n\t\t\t  EsObject *v, EsObject *k, EsObject *dict)\n{\n\tEsObject *key = k;\n\n\tif (es_null (key))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tif (es_object_get_type (key) == OPT_TYPE_STRING)\n\t{\n\t\tconst char *cstr = opt_string_get_cstr (key);\n\t\tkey = opt_name_new_from_cstr (cstr);\n\t}\n\n\tif (es_object_get_type (key) != OPT_TYPE_NAME\n\t\t&& !es_integer_p (key) && !es_boolean_p (key))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tdict_op_def (dict, key, v);\n\tif (key != k)\n\t\tes_object_unref (key);\n\tptrArrayDeleteLastInBatch (vm->ostack, 3);\n\treturn es_false;\n}\n\nstatic EsObject*\nop__put_str (OptVM *vm, EsObject *name,\n\t\t\t EsObject *v, EsObject *k, EsObject *str)\n{\n\tif (!es_integer_p (v))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint c = es_integer_get (v);\n\tif (!(c >= 0 && c < 256))\n\t\treturn OPT_ERR_RANGECHECK;\n\tif (!es_integer_p (k))\n\t\treturn OPT_ERR_TYPECHECK;\n\tint index = es_integer_get (k);\n\tif (index < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tvString *vstr = es_pointer_get (str);\n\tsize_t len    = vStringLength (vstr);\n\tif (len > (size_t)index)\n\t{\n\t\tif (c == 0)\n\t\t\tvStringTruncate (vstr, (size_t)index);\n\t\telse\n\t\t\tvStringChar(vstr, index) = (char)c;\n\t}\n\telse\n\t{\n\t\tsize_t d = index - len;\n\t\tfor (size_t i = 0; i < d; i++)\n\t\t\tvStringPut (vstr, ' ');\n\t\tif (c != 0)\n\t\t\tvStringPut (vstr, c);\n\t}\n\n\tptrArrayDeleteLastInBatch (vm->ostack, 3);\n\treturn es_false;\n}\n\nstatic EsObject*\nop_put (OptVM *vm, EsObject *name)\n{\n\tEsObject *v = ptrArrayLast (vm->ostack);\n\tEsObject *k = ptrArrayItemFromLast (vm->ostack, 1);\n\tEsObject *obj = ptrArrayItemFromLast (vm->ostack, 2);\n\n\tint t = es_object_get_type (obj);\n\tif (t == OPT_TYPE_ARRAY)\n\t\treturn op__put_array (vm, name, v, k, obj);\n\telse if (t == OPT_TYPE_DICT)\n\t\treturn op__put_dict (vm, name, v, k, obj);\n\telse if (t == OPT_TYPE_STRING)\n\t\treturn op__put_str (vm, name, v, k, obj);\n\n\treturn OPT_ERR_TYPECHECK;\n}\n\nstatic EsObject*\nop__forall_array (OptVM *vm, EsObject *name,\n\t\t\t\t  EsObject *proc, EsObject *obj)\n{\n\tptrArray *a = es_pointer_get (obj);\n\tunsigned int c = ptrArrayCount (a);\n\n\tEsObject *e = es_false;\n\tfor (unsigned int i = 0; i < c; i++)\n\t{\n\t\tEsObject *o = ptrArrayItem (a, i);\n\t\tes_object_ref (o);\n\t\tvm_ostack_push (vm, o);\n\t\te = vm_call_proc (vm, proc);\n\t\tes_object_unref (o);\n\t\tif (es_error_p (e))\n\t\t\tbreak;\n\t}\n\n\treturn e;\n}\n\nstruct dictForallData {\n\tOptVM *vm;\n\tEsObject *proc;\n\tEsObject *err;\n};\n\nstatic bool\ndict_forall_cb (const void *key, void *value, void *user_data)\n{\n\tbool r = true;\n\tEsObject *k = (EsObject *)key;\n\tEsObject *v = value;\n\tstruct dictForallData *d = user_data;\n\n\t/* TODO */\n\tif (es_symbol_p (k))\n\t\tk = name_new (k, ATTR_READABLE);\n\telse\n\t\tes_object_ref ((EsObject *)k);\n\tes_object_ref (v);\n\n\tvm_ostack_push (d->vm, (EsObject *)k);\n\tvm_ostack_push (d->vm, v);\n\tEsObject *e = vm_call_proc (d->vm, d->proc);\n\tif (es_error_p (e))\n\t{\n\t\td->err = e;\n\t\tr = false;\n\t}\n\tes_object_unref ((EsObject *)k);\n\tes_object_unref (v);\n\n\treturn r;\n}\n\nstatic EsObject*\nop__forall_dict (OptVM *vm, EsObject *name,\n\t\t\t\t EsObject *proc, EsObject *obj)\n{\n\tEsObject *r = es_false;\n\thashTable *ht = es_pointer_get (obj);\n\tstruct dictForallData data = {\n\t\t.vm   = vm,\n\t\t.proc = proc\n\t};\n\n\tif (!hashTableForeachItem (ht, dict_forall_cb, &data))\n\t\tr = data.err;\n\n\treturn r;\n}\n\nstatic EsObject*\nop__forall_string (OptVM *vm, EsObject *name,\n\t\t\t\t   EsObject *proc, EsObject *obj)\n{\n\tvString *s = es_pointer_get (obj);\n\tunsigned int c = vStringLength (s);\n\n\tEsObject *e = es_false;\n\tfor (unsigned int i = 0; i < c; i++)\n\t{\n\t\tunsigned char chr = vStringChar (s, i);\n\t\tEsObject *o = es_integer_new (chr);\n\t\tvm_ostack_push (vm, o);\n\t\tes_object_unref (o);\n\t\te = vm_call_proc (vm, proc);\n\t\tif (es_error_p (e))\n\t\t\tbreak;\n\t}\n\n\treturn e;\n}\n\nstatic EsObject*\nop_forall (OptVM *vm, EsObject *name)\n{\n\tEsObject *proc = ptrArrayLast (vm->ostack);\n\tif (!(es_object_get_type (proc) == OPT_TYPE_ARRAY\n\t\t  && (((ArrayFat *)es_fatptr_get (proc))->attr & ATTR_EXECUTABLE)))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *obj = ptrArrayItemFromLast (vm->ostack, 1);\n\n\tint t = es_object_get_type (obj);\n\tEsObject * (* proc_driver) (OptVM *, EsObject *,\n\t\t\t\t\t\t\t\tEsObject *, EsObject *) = NULL;\n\tif (t == OPT_TYPE_ARRAY)\n\t\tproc_driver = op__forall_array;\n\telse if (t == OPT_TYPE_DICT)\n\t\tproc_driver = op__forall_dict;\n\telse if (t == OPT_TYPE_STRING)\n\t\tproc_driver = op__forall_string;\n\telse\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tptrArrayRemoveLast (vm->ostack);\n\tptrArrayRemoveLast (vm->ostack);\n\tEsObject *e = (*proc_driver) (vm, name, proc, obj);\n\tes_object_unref (proc);\n\tes_object_unref (obj);\n\n\tif (es_object_equal (e, OPT_ERR_INVALIDEXIT))\n\t{\n\t\tdict_op_def (vm->error, OPT_KEY_newerror, es_false);\n\t\te = es_false;\n\t}\n\treturn e;\n}\n\nstatic EsObject*\nop__putinterval_array (OptVM *vm, EsObject *name,\n\t\t\t\t\t   ptrArray *srca, unsigned int index, ptrArray *dsta)\n{\n\tunsigned int dlen = ptrArrayCount (dsta);\n\tunsigned int slen = ptrArrayCount (srca);\n\tif (dlen > index)\n\t{\n\t\tunsigned d = dlen - index;\n\t\tif (d <= slen)\n\t\t{\n\t\t\tptrArrayDeleteLastInBatch (dsta, d);\n\t\t\tfor (unsigned int i = 0; i < slen; i++)\n\t\t\t\tptrArrayAdd (dsta, es_object_ref (ptrArrayItem (srca, i)));\n\t\t\treturn es_false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (unsigned int i = 0; i < slen; i++)\n\t\t\t\tptrArrayUpdate (dsta, index + i,\n\t\t\t\t\t\t\t\tes_object_ref (ptrArrayItem (srca, i)),\n\t\t\t\t\t\t\t\tes_nil);\n\t\t\treturn es_false;\n\t\t}\n\t}\n\telse if (dlen == index)\n\t{\n\t\tfor (unsigned int i = 0; i < slen; i++)\n\t\t\tptrArrayAdd (dsta, es_object_ref (ptrArrayItem (srca, i)));\n\t\treturn es_false;\n\t}\n\telse\n\t\treturn OPT_ERR_RANGECHECK;\n}\n\nstatic EsObject*\nop__putinterval_string (OptVM *vm, EsObject *name,\n\t\t\t\t\t\tvString *srcv, unsigned int index, vString *dstv)\n{\n\tunsigned int dlen = vStringLength (dstv);\n\tif (dlen > index)\n\t{\n\t\tunsigned int d = dlen - index;\n\t\tunsigned int slen = vStringLength (srcv);\n\t\tif (d <= slen)\n\t\t{\n\t\t\tvStringTruncate (dstv, index);\n\t\t\tvStringCat (dstv, srcv);\n\t\t\treturn es_false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (unsigned int i = 0; i < slen; i++)\n\t\t\t\tvStringChar (dstv, index + i) = vStringChar (srcv, i);\n\t\t\treturn es_false;\n\t\t}\n\t}\n\telse if (dlen == index)\n\t{\n\t\tvStringCat (dstv, srcv);\n\t\treturn es_false;\n\t}\n\telse\n\t\treturn OPT_ERR_RANGECHECK;\n}\n\nstatic EsObject*\nop_putinterval (OptVM *vm, EsObject *name)\n{\n\tEsObject *src = ptrArrayLast (vm->ostack);\n\tEsObject *indexobj = ptrArrayItemFromLast (vm->ostack, 1);\n\tEsObject *dst = ptrArrayItemFromLast (vm->ostack, 2);\n\n\tint t = es_object_get_type (src);\n\tif (t == OPT_TYPE_ARRAY || t == OPT_TYPE_STRING)\n\t{\n\t\tif (!es_integer_p (indexobj))\n\t\t\treturn OPT_ERR_TYPECHECK;\n\t\tif (es_object_get_type (dst) != t)\n\t\t\treturn OPT_ERR_TYPECHECK;\n\t}\n\telse\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint index0 = es_integer_get (indexobj);\n\tif (index0 < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\tunsigned int index = (size_t)index0;\n\n\tEsObject *r;\n\tif (t == OPT_TYPE_ARRAY)\n\t\tr = op__putinterval_array (vm, name,\n\t\t\t\t\t\t\t\t   es_pointer_get (src),\n\t\t\t\t\t\t\t\t   index,\n\t\t\t\t\t\t\t\t   es_pointer_get (dst));\n\telse\n\t\tr = op__putinterval_string (vm, name,\n\t\t\t\t\t\t\t\t\tes_pointer_get (src),\n\t\t\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\t\t\tes_pointer_get (dst));\n\n\tif (!es_error_p (r))\n\t\tptrArrayDeleteLastInBatch (vm->ostack, 3);\n\n\treturn r;\n}\n\nstatic EsObject*\nop__copyinterval_array (OptVM *vm, EsObject *name,\n\t\t\t\t\t\tptrArray *dsta,\n\t\t\t\t\t\tunsigned int count,\n\t\t\t\t\t\tunsigned int index,\n\t\t\t\t\t\tptrArray *srca)\n{\n\tunsigned int srcl = ptrArrayCount (srca);\n\n\tif (index > srcl)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tif ((index + count) > srcl)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tfor (unsigned int i = index; i < index + count; i++)\n\t\tptrArrayAdd (dsta, es_object_ref (ptrArrayItem (srca, i)));\n\treturn es_false;\n}\n\nstatic EsObject*\nop__copyinterval_string (OptVM *vm, EsObject *name,\n\t\t\t\t\t\t vString *dsts,\n\t\t\t\t\t\t unsigned int count,\n\t\t\t\t\t\t unsigned int index,\n\t\t\t\t\t\t vString *srcs)\n{\n\tunsigned int srcl = vStringLength (srcs);\n\n\tif (index > srcl)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tif ((index + count) > srcl)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tvStringNCatSUnsafe (dsts, vStringValue (srcs) + index, count);\n\treturn es_false;\n}\n\nstatic EsObject*\nop__copyinterval (OptVM *vm, EsObject *name)\n{\n\tEsObject *dstobj = ptrArrayLast (vm->ostack);\n\tEsObject *countobj = ptrArrayItemFromLast (vm->ostack, 1);\n\tEsObject *indexobj = ptrArrayItemFromLast (vm->ostack, 2);\n\tEsObject *srcobj = ptrArrayItemFromLast (vm->ostack, 3);\n\n\tint t = es_object_get_type (dstobj);\n\tif (! (t == OPT_TYPE_ARRAY || t == OPT_TYPE_STRING))\n\t\treturn OPT_ERR_TYPECHECK;\n\tif (t != es_object_get_type (srcobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tif (!es_integer_p (countobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\tif (!es_integer_p (indexobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint count0 = es_integer_get (countobj);\n\tif (count0 < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\tunsigned int count = (unsigned int)count0;\n\n\tint index0 = es_integer_get (indexobj);\n\tif (index0 < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\tunsigned int index = (size_t)index0;\n\n\tEsObject* r;\n\tif (t == OPT_TYPE_ARRAY)\n\t\tr = op__copyinterval_array (vm, name,\n\t\t\t\t\t\t\t\t\tes_pointer_get (dstobj),\n\t\t\t\t\t\t\t\t\tcount,\n\t\t\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\t\t\tes_pointer_get (srcobj));\n\telse\n\t\tr = op__copyinterval_string (vm, name,\n\t\t\t\t\t\t\t\t\t es_pointer_get (dstobj),\n\t\t\t\t\t\t\t\t\t count,\n\t\t\t\t\t\t\t\t\t index,\n\t\t\t\t\t\t\t\t\t es_pointer_get (srcobj));\n\n\tif (es_error_p (r))\n\t\treturn r;\n\n\tes_object_ref (dstobj);\n\tptrArrayDeleteLastInBatch (vm->ostack, 4);\n\tvm_ostack_push (vm, dstobj);\n\tes_object_unref (dstobj);\n\treturn r;\n}\n"
  },
  {
    "path": "dsl/optscript.h",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef OPTSCRIPT_H\n#define OPTSCRIPT_H\n\n#include \"general.h\"\n\n#include \"es.h\"\n#include \"mio.h\"\n#include \"ptrarray.h\"\n\ntypedef struct sOptVM OptVM;\ntypedef EsObject* (* OptOperatorFn) (OptVM *, EsObject *);\n\nstruct OptHelpExtender {\n\tvoid        (* add)          (ptrArray *, void *);\n\tconst char* (* get_help_str) (EsObject *, void *);\n};\n\nint       opt_init (void);\n\nOptVM    *opt_vm_new          (MIO *in, MIO *out, MIO *err);\nvoid      opt_vm_delete       (OptVM *vm);\n\nEsObject *opt_vm_read         (OptVM *vm, MIO *in);\nEsObject *opt_vm_eval         (OptVM *vm, EsObject *obj);\nvoid      opt_vm_report_error (OptVM *vm, EsObject *eobj, MIO *err);\n\nvoid     *opt_vm_set_app_data (OptVM *vm, void *app_data);\nvoid     *opt_vm_get_app_data (OptVM *vm);\n\nchar     *opt_vm_set_prompt   (OptVM *vm, char *prompt);\nvoid      opt_vm_print_prompt (OptVM *vm);\n\nint       opt_vm_help         (OptVM *vm, MIO *out,\n\t\t\t\t\t\t\t   struct OptHelpExtender *extop, void *data);\n\nvoid      opt_vm_clear       (OptVM *vm, bool clear_app_data);\nvoid      opt_vm_dstack_push (OptVM *vm, EsObject *dict);\nvoid      opt_vm_dstack_pop  (OptVM *vm);\n\nEsObject*  opt_vm_ostack_top  (OptVM *vm);\nEsObject*  opt_vm_ostack_peek  (OptVM *vm, int index_from_top);\nEsObject*  opt_vm_ostack_pop  (OptVM *vm);\nvoid       opt_vm_ostack_push (OptVM *vm, EsObject *obj);\nunsigned int opt_vm_ostack_count (OptVM *vm);\n\nEsObject *opt_dict_new       (unsigned int size);\nbool      opt_dict_known_and_get_cstr (EsObject *dict, const char* name, EsObject **val);\nbool      opt_dict_foreach   (EsObject *dict, bool (* fn) (EsObject *, EsObject *, void*), void *data);\nvoid      opt_dict_def       (EsObject *dict, EsObject *sym, EsObject *val);\nbool      opt_dict_undef     (EsObject *dict, EsObject *sym);\nvoid      opt_dict_clear     (EsObject *dict);\n\nEsObject *opt_array_new      (void);\nEsObject *opt_array_get      (const EsObject *array, unsigned int index);\nvoid      opt_array_put      (EsObject *array, unsigned int index, EsObject *obj);\nvoid      opt_array_add      (EsObject *array, EsObject *elt);\n\nunsigned int opt_array_length(const EsObject *array);\n\nEsObject *opt_operator_new   (OptOperatorFn op, const char *name, int arity, const char *help_str);\n\nEsObject *opt_string_new_from_cstr (const char *cstr);\nconst char* opt_string_get_cstr (const EsObject *str);\n\nEsObject *opt_name_new_from_cstr (const char *cstr);\nconst char* opt_name_get_cstr (const EsObject *name);\n\nextern EsObject *OPT_ERR_TYPECHECK;\nextern EsObject *OPT_ERR_QUIT;\nextern EsObject *OPT_ERR_RANGECHECK;\nextern EsObject *OPT_ERR_UNDERFLOW;\n\nextern int OPT_TYPE_ARRAY;\nextern int OPT_TYPE_DICT;\nextern int OPT_TYPE_OPERATOR;\nextern int OPT_TYPE_STRING;\nextern int OPT_TYPE_NAME;\nextern int OPT_TYPE_MARK;\n\n#endif\n"
  },
  {
    "path": "dsl/qualifier.c",
    "content": "/*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n/*\n * INCLUDES\n */\n#include \"qualifier.h\"\n#include \"dsl.h\"\n#include \"es.h\"\n\n#include <stdlib.h>\n\n/*\n * TYPES\n */\nstruct sQCode\n{\n\tDSLCode *dsl;\n};\n\n\n/*\n * DATA DEFINITIONS\n */\n\n\n/*\n * FUNCTION DEFINITIONS\n */\nstatic int initialize (void)\n{\n\tstatic int initialized;\n\n\tif (initialized)\n\t\treturn 1;\n\n\tif (!dsl_init (DSL_QUALIFIER, NULL, 0))\n\t{\n\t\tfprintf(stderr, \"MEMORY EXHAUSTED\\n\");\n\t\treturn 0;\n\t}\n\n\tinitialized = 1;\n\treturn 1;\n}\n\nQCode *q_compile (EsObject *exp)\n{\n\tQCode *code;\n\n\tif (!initialize ())\n\t\texit (1);\n\n\tcode = malloc (sizeof (QCode));\n\tif (code == NULL)\n\t{\n\t\tfprintf(stderr, \"MEMORY EXHAUSTED\\n\");\n\t\treturn NULL;\n\t}\n\n\tcode->dsl = dsl_compile (DSL_QUALIFIER, exp);\n\tif (code->dsl == NULL)\n\t{\n\t\tfprintf(stderr, \"MEMORY EXHAUSTED or SYNTAX ERROR\\n\");\n\t\tfree (code);\n\t\treturn NULL;\n\t}\n\treturn code;\n}\n\nenum QRESULT q_is_acceptable  (QCode *code, tagEntry *entry)\n{\n\tEsObject *r;\n\tint i;\n\n\tDSLEnv env = {\n\t\t.engine = DSL_QUALIFIER,\n\t\t.entry  = entry,\n\t};\n\tes_autounref_pool_push ();\n\tr = dsl_eval (code->dsl, &env);\n\tif (es_object_equal (r, es_false))\n\t\ti = Q_REJECT;\n\telse if (es_error_p (r))\n\t{\n\t\tdsl_report_error (\"GOT ERROR in QUALIFYING\", r);\n\t\ti = Q_ERROR;\n\t}\n\telse\n\t\ti = Q_ACCEPT;\n\tes_autounref_pool_pop ();\n\n\tdsl_cache_reset (DSL_QUALIFIER);\n\n\treturn i;\n}\n\nvoid q_destroy (QCode *code)\n{\n\tdsl_release (DSL_QUALIFIER, code->dsl);\n\tfree (code);\n}\n\nvoid q_help (FILE *fp)\n{\n\tif (!initialize ())\n\t\texit (1);\n\tdsl_help (DSL_QUALIFIER, fp);\n}\n"
  },
  {
    "path": "dsl/qualifier.h",
    "content": "/*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef QUALIFIER_H\n#define QUALIFIER_H\n\n#include \"es.h\"\n#include \"readtags.h\"\n\n#include <stdio.h>\n\ntypedef struct sQCode QCode;\n\nenum QRESULT {\n\tQ_REJECT,\n\tQ_ACCEPT,\n\tQ_ERROR,\n};\n\nQCode       *q_compile        (EsObject *exp);\nenum QRESULT q_is_acceptable  (QCode *code, tagEntry *entry);\nvoid         q_destroy        (QCode *code);\nvoid         q_help           (FILE *fp);\n\n#endif\n"
  },
  {
    "path": "dsl/sorter.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n/*\n * INCLUDES\n */\n\n#include \"sorter.h\"\n#include \"dsl.h\"\n#include \"es.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\n\n/*\n * MACROS\n */\n\n/* dummy definition to allow/require an extra semicolon */\n#define END_DEF(sfx) typedef int ctags_dummy_int_type_ignore_me_##sfx\n\n#define DECLARE_ALT_VALUE_FN(N)\t\t\t\t\t\t\t\t\t\\\nstatic EsObject* alt_value_##N (EsObject *args, DSLEnv *env)\n\n#define DEFINE_ALT_VALUE_FN(N)\t\t\t\t\t\t\t\t\t\t\t\\\nstatic EsObject* alt_value_##N (EsObject *args, DSLEnv *env)\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tif (!env->alt_entry)\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tdsl_throw (NO_ALT_ENTRY, es_symbol_intern (\"&\" #N)); \t\t\t\\\n\treturn dsl_entry_##N (env->alt_entry);\t\t\t\t\t\t\t\t\\\n} END_DEF(alt_value_##N)\n\n\n/*\n * CONSTANTS\n */\nstatic EsObject *LTN;\nstatic EsObject *EQN;\nstatic EsObject *GTN;\n\n/*\n * FUNCTION DECLARATIONS\n */\nstatic EsObject* sorter_alt_entry_ref (EsObject *args, DSLEnv *env);\n\nDECLARE_ALT_VALUE_FN(name);\nDECLARE_ALT_VALUE_FN(input);\nDECLARE_ALT_VALUE_FN(pattern);\nDECLARE_ALT_VALUE_FN(line);\n\nDECLARE_ALT_VALUE_FN(access);\nDECLARE_ALT_VALUE_FN(end);\nDECLARE_ALT_VALUE_FN(extras);\nDECLARE_ALT_VALUE_FN(file);\nDECLARE_ALT_VALUE_FN(inherits);\nDECLARE_ALT_VALUE_FN(implementation);\nDECLARE_ALT_VALUE_FN(kind);\nDECLARE_ALT_VALUE_FN(language);\nDECLARE_ALT_VALUE_FN(nth);\nDECLARE_ALT_VALUE_FN(scope);\nDECLARE_ALT_VALUE_FN(scope_kind);\nDECLARE_ALT_VALUE_FN(scope_name);\nDECLARE_ALT_VALUE_FN(signature);\nDECLARE_ALT_VALUE_FN(typeref);\nDECLARE_ALT_VALUE_FN(typeref_kind);\nDECLARE_ALT_VALUE_FN(typeref_name);\nDECLARE_ALT_VALUE_FN(roles);\nDECLARE_ALT_VALUE_FN(xpath);\n\n\nstatic EsObject* sorter_proc_cmp (EsObject* args, DSLEnv *env);\nstatic EsObject* sorter_proc_flip (EsObject* args, DSLEnv *env);\nstatic EsObject* sorter_sform_cmp_or (EsObject* args, DSLEnv *env);\n\n/*\n * DATA DEFINITIONS\n */\n\n#define DSL_ERR_NO_ALT_ENTRY    (es_error_intern(\"the-alternative-entry-unavailable\"))\n\nstatic DSLProcBind pbinds [] = {\n\t{ \"<>\",              sorter_proc_cmp,          NULL, DSL_PATTR_CHECK_ARITY,     2,\n\t  .helpstr = \"(<> <any:a> <any:b>) -> -1|0|1; compare a b. The types of a and b must be the same.\" },\n\t{ \"*-\",              sorter_proc_flip,         NULL, DSL_PATTR_CHECK_ARITY,     1,\n\t  .helpstr = \"(*- <interger:n>) -> -<integer:n>; filp the result of comparison.\" },\n\t{ \"<or>\",            sorter_sform_cmp_or,      NULL, DSL_PATTR_SELF_EVAL|DSL_PATTR_CHECK_ARITY_OPT, 1,\n\t  .helpstr = \"(<or> <any> ...) -> -1|0|1; evaluate arguments left to right till one of them returns -1 or 1.\" },\n\n\t{ \"&\",               sorter_alt_entry_ref, NULL, DSL_PATTR_CHECK_ARITY_OPT,  1,\n\t  .helpstr = \"(& <string:field>) -> <string>|#f\\n\"\n\t  \"(& <string:field> <any:default>) -> <string>|<any:default>\"},\n\t{ \"&name\",           alt_value_name,           NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> <string>\"},\n\t{ \"&input\",          alt_value_input,          NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> <string>\"},\n\t{ \"&pattern\",        alt_value_pattern,        NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"&line\",           alt_value_line,           NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<integer>\" },\n\n\t{ \"&access\",         alt_value_access,         NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\" },\n\t{ \"&end\",            alt_value_end,            NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<integer>\"},\n\t{ \"&extras\",         alt_value_extras,         NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"&file\",           alt_value_file,           NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> <boolean>; whether the scope is limited in the file or not.\" },\n\t{ \"&inherits\",       alt_value_inherits,       NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> <list>\" },\n\t{ \"&implementation\", alt_value_implementation, NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\" },\n\t{ \"&kind\",           alt_value_kind,           NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"&language\",       alt_value_language,       NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\" },\n\t{ \"&nth\",            alt_value_nth,            NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<integer>\"},\n\t{ \"&scope\",          alt_value_scope,          NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>; $scope-kind:$scope-name\"},\n\t{ \"&scope-kind\",     alt_value_scope_kind,     NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"&scope-name\",     alt_value_scope_name,     NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"&signature\",      alt_value_signature,      NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\" },\n\t{ \"&typeref\",        alt_value_typeref,        NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"&typeref-kind\",   alt_value_typeref_kind,   NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"&typeref-name\",   alt_value_typeref_name,   NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n\t{ \"&roles\",          alt_value_roles,          NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> <list>\" },\n\t{ \"&xpath\",         alt_value_xpath,           NULL, DSL_PATTR_MEMORABLE, 0UL,\n\t  .helpstr = \"-> #f|<string>\"},\n};\n\n/*\n * FUNCTION DEFINITIONS\n */\n\n/*\n * Value functions\n */\nDEFINE_ALT_VALUE_FN(name);\nDEFINE_ALT_VALUE_FN(input);\nDEFINE_ALT_VALUE_FN(pattern);\nDEFINE_ALT_VALUE_FN(line);\n\nDEFINE_ALT_VALUE_FN(access);\nDEFINE_ALT_VALUE_FN(end);\nDEFINE_ALT_VALUE_FN(extras);\nDEFINE_ALT_VALUE_FN(file);\nDEFINE_ALT_VALUE_FN(inherits);\nDEFINE_ALT_VALUE_FN(implementation);\nDEFINE_ALT_VALUE_FN(kind);\nDEFINE_ALT_VALUE_FN(language);\nDEFINE_ALT_VALUE_FN(nth);\nDEFINE_ALT_VALUE_FN(scope);\nDEFINE_ALT_VALUE_FN(scope_kind);\nDEFINE_ALT_VALUE_FN(scope_name);\nDEFINE_ALT_VALUE_FN(signature);\nDEFINE_ALT_VALUE_FN(typeref);\nDEFINE_ALT_VALUE_FN(typeref_kind);\nDEFINE_ALT_VALUE_FN(typeref_name);\nDEFINE_ALT_VALUE_FN(roles);\nDEFINE_ALT_VALUE_FN(xpath);\n\n/*\n * Special form(s)\n */\nstatic EsObject* sorter_sform_cmp_or (EsObject* args, DSLEnv *env)\n{\n\tEsObject *o = EQN;\n\n\twhile (! es_null (args))\n\t{\n\t\to = es_car (args);\n\t\to = dsl_compile_and_eval (o, env);\n\n\t\tif (es_object_equal (o, LTN))\n\t\t\treturn LTN;\n\t\telse if (es_object_equal (o, GTN))\n\t\t\treturn GTN;\n\t\telse if (es_error_p (o))\n\t\t\treturn o;\n\n\t\targs = es_cdr (args);\n\t}\n\n\treturn o;\n}\n\n\n/*\n * Procs\n */\nstatic EsObject* sorter_alt_entry_ref (EsObject *args, DSLEnv *env)\n{\n\tEsObject *key = es_car(args);\n\n\tif (es_error_p (key))\n\t\treturn key;\n\telse if (! es_string_p (key))\n\t\tdsl_throw (WRONG_TYPE_ARGUMENT,\n\t\t\t\t   es_symbol_intern (\"&\"));\n\telse\n\t{\n\t\tEsObject *r = dsl_entry_xget_string (env->alt_entry, es_string_get (key));\n\t\tif (es_object_equal (r, es_false))\n\t\t{\n\t\t\tEsObject *defaultv = es_car(es_cdr(args));\n\t\t\tif (es_null (defaultv))\n\t\t\t\treturn r;\n\t\t\treturn defaultv;\n\t\t}\n\t\treturn r;\n\t}\n}\n\nstatic EsObject* sorter_proc_cmp (EsObject* args, DSLEnv *env)\n{\n\tEsObject *a, *b;\n\n\ta = es_car (args);\n\tb = es_car (es_cdr (args));\n\n\tif (es_number_p (a))\n\t{\n\t\tif (!es_number_p (b))\n\t\t\tdsl_throw (NUMBER_REQUIRED, es_symbol_intern (\"<>\"));\n\n\t\tdouble ad = es_number_get (a);\n\t\tdouble bd = es_number_get (b);\n\n\t\tif (ad < bd)\n\t\t\treturn LTN;\n\t\telse if (ad == bd)\n\t\t\treturn EQN;\n\t\telse\n\t\t\treturn GTN;\n\t}\n\telse if (es_string_p (a))\n\t{\n\t\tif (!es_string_p (b))\n\t\t\tdsl_throw (STRING_REQUIRED, es_symbol_intern (\"<>\"));\n\n\t\tconst char *as = es_string_get (a);\n\t\tconst char *bs = es_string_get (b);\n\n\t\tint tmp = strcmp (as, bs);\n\t\tif (tmp < 0)\n\t\t\treturn LTN;\n\t\telse if (tmp > 0)\n\t\t\treturn GTN;\n\t\telse\n\t\t\treturn EQN;\n\t}\n\telse if (es_boolean_p (a))\n\t{\n\t\tif (!es_boolean_p (b))\n\t\t\tdsl_throw (BOOLEAN_REQUIRED, es_symbol_intern (\"<>\"));\n\n\t\tbool ab = es_boolean_get (a);\n\t\tbool bb = es_boolean_get (a);\n\n\t\tif (ab == bb)\n\t\t\treturn EQN;\n\t\telse if ((int)ab < (int)bb)\n\t\t\treturn LTN;\n\t\telse\n\t\t\treturn GTN;\n\t}\n\telse\n\t\tdsl_throw (WRONG_TYPE_ARGUMENT, es_symbol_intern (\"<>\"));\n}\n\nstatic EsObject* sorter_proc_flip (EsObject* args, DSLEnv *env)\n{\n\tEsObject *o;\n\n\to = es_car (args);\n\n\tif (!es_integer_p (o))\n\t\tdsl_throw (INTEGER_REQUIRED, es_symbol_intern (\"-*\"));\n\n\tint i = es_integer_get (o);\n\tif (i < 0)\n\t\treturn GTN;\n\telse if (i == 0)\n\t\treturn EQN;\n\telse\n\t\treturn LTN;\n}\n\nstatic int initialize (void)\n{\n\tstatic int initialized;\n\n\tif (initialized)\n\t\treturn 1;\n\n\tif (!dsl_init (DSL_SORTER, pbinds, sizeof(pbinds)/sizeof(pbinds [0])))\n\t{\n\t\tfprintf(stderr, \"MEMORY EXHAUSTED\\n\");\n\t\treturn 0;\n\t}\n\n\tLTN = es_integer_new (-1);\n\tEQN = es_integer_new (0);\n\tGTN = es_integer_new (1);\n\n\tinitialized = 1;\n\treturn 1;\n}\n\n\n/*\n * SCode\n */\nstruct sSCode\n{\n\tDSLCode *dsl;\n};\n\nSCode *s_compile (EsObject *exp)\n{\n\tSCode *code;\n\n\tif (!initialize ())\n\t\texit (1);\n\n\tcode = malloc (sizeof (SCode));\n\tif (code == NULL)\n\t{\n\t\tfprintf(stderr, \"MEMORY EXHAUSTED\\n\");\n\t\treturn NULL;\n\t}\n\n\tcode->dsl = dsl_compile (DSL_SORTER, exp);\n\tif (code->dsl == NULL)\n\t{\n\t\tfprintf(stderr, \"MEMORY EXHAUSTED or SYNTAX ERROR\\n\");\n\t\tfree (code);\n\t\treturn NULL;\n\t}\n\treturn code;\n}\n\nint s_compare        (const tagEntry * a, const tagEntry * b, SCode *code)\n{\n\tEsObject *r;\n\tint i;\n\tint exit_code = 0;\n\n\tDSLEnv env = {\n\t\t.engine = DSL_SORTER,\n\t\t.entry = a,\n\t\t.alt_entry = b,\n\t};\n\tes_autounref_pool_push ();\n\tr = dsl_eval (code->dsl, &env);\n\n\tif (es_integer_p (r))\n\t{\n\t\tint n = es_integer_get(r);\n\n\t\tif (n < 0)\n\t\t\ti = -1;\n\t\telse if (n == 0)\n\t\t\ti = 0;\n\t\telse\n\t\t\ti = 1;\n\t\tgoto out;\n\t}\n\telse if (es_error_p (r))\n\t{\n\t\tdsl_report_error (\"GOT ERROR in SORTING\", r);\n\t\texit_code = 1;\n\t\tgoto out;\n\t}\n\telse\n\t{\n\t\tdsl_report_error (\"Get unexpected value as the result of sorting\",\n\t\t\t\t\t\t  r);\n\t\texit_code = 1;\n\t\tgoto out;\n\t}\n\n out:\n\tes_autounref_pool_pop ();\n\n\tdsl_cache_reset (DSL_SORTER);\n\n\tif (exit_code)\n\t{\n\t\ti = 0;\t\t\t\t\t/* For suppress the warning. */\n\t\texit (exit_code);\n\t}\n\n\treturn i;\n}\n\nvoid s_destroy        (SCode *code)\n{\n\tdsl_release (DSL_SORTER, code->dsl);\n\tfree (code);\n}\n\nvoid s_help           (FILE *fp)\n{\n\tif (!initialize ())\n\t\texit (1);\n\tdsl_help (DSL_SORTER, fp);\n}\n"
  },
  {
    "path": "dsl/sorter.h",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef SORTER_H\n#define SORTER_H\n\n/*\n * Includes\n */\n\n#include \"es.h\"\n#include \"readtags.h\"\n\n#include <stdio.h>\n\n\n/*\n * Type declarations\n */\n\ntypedef struct sSCode SCode;\n\n\n/*\n * function declarations\n */\n\nSCode       *s_compile        (EsObject *exp);\nint          s_compare        (const tagEntry * a, const tagEntry * b, SCode *code);\nvoid         s_destroy        (SCode *code);\nvoid         s_help           (FILE *fp);\n\n#endif\n"
  },
  {
    "path": "extra-cmds/Makefile",
    "content": "all:\n.SUFFIXES:\n.SUFFIXES: .c .o\n\n.c.o:\n\t$(MAKE) -C .. extra-cmds/$@\n%:\n\t$(MAKE) -C .. $@\n"
  },
  {
    "path": "extra-cmds/acutest.h",
    "content": "/* https://github.com/mity/acutest/blob/master/include/acutest.h\n   cce300734bfe5c3879b0449ac283a872633e615c */\n/*\n * Acutest -- Another C/C++ Unit Test facility\n * <https://github.com/mity/acutest>\n *\n * Copyright 2013-2020 Martin Mitas\n * Copyright 2019 Garrett D'Amore\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n#ifndef ACUTEST_H\n#define ACUTEST_H\n\n\n/************************\n *** Public interface ***\n ************************/\n\n/* By default, \"acutest.h\" provides the main program entry point (function\n * main()). However, if the test suite is composed of multiple source files\n * which include \"acutest.h\", then this causes a problem of multiple main()\n * definitions. To avoid this problem, #define macro TEST_NO_MAIN in all\n * compilation units but one.\n */\n\n/* Macro to specify list of unit tests in the suite.\n * The unit test implementation MUST provide list of unit tests it implements\n * with this macro:\n *\n *   TEST_LIST = {\n *       { \"test1_name\", test1_func_ptr },\n *       { \"test2_name\", test2_func_ptr },\n *       ...\n *       { NULL, NULL }     // zeroed record marking the end of the list\n *   };\n *\n * The list specifies names of each test (must be unique) and pointer to\n * a function implementing it. The function does not take any arguments\n * and has no return values, i.e. every test function has to be compatible\n * with this prototype:\n *\n *   void test_func(void);\n *\n * Note the list has to be ended with a zeroed record.\n */\n#define TEST_LIST               const struct acutest_test_ acutest_list_[]\n\n\n/* Macros for testing whether an unit test succeeds or fails. These macros\n * can be used arbitrarily in functions implementing the unit tests.\n *\n * If any condition fails throughout execution of a test, the test fails.\n *\n * TEST_CHECK takes only one argument (the condition), TEST_CHECK_ allows\n * also to specify an error message to print out if the condition fails.\n * (It expects printf-like format string and its parameters). The macros\n * return non-zero (condition passes) or 0 (condition fails).\n *\n * That can be useful when more conditions should be checked only if some\n * preceding condition passes, as illustrated in this code snippet:\n *\n *   SomeStruct* ptr = allocate_some_struct();\n *   if(TEST_CHECK(ptr != NULL)) {\n *       TEST_CHECK(ptr->member1 < 100);\n *       TEST_CHECK(ptr->member2 > 200);\n *   }\n */\n#define TEST_CHECK_(cond,...)   acutest_check_((cond), __FILE__, __LINE__, __VA_ARGS__)\n#define TEST_CHECK(cond)        acutest_check_((cond), __FILE__, __LINE__, \"%s\", #cond)\n\n\n/* These macros are the same as TEST_CHECK_ and TEST_CHECK except that if the\n * condition fails, the currently executed unit test is immediately aborted.\n *\n * That is done either by calling abort() if the unit test is executed as a\n * child process; or via longjmp() if the unit test is executed within the\n * main Acutest process.\n *\n * As a side effect of such abortion, your unit tests may cause memory leaks,\n * unflushed file descriptors, and other phenomena caused by the abortion.\n *\n * Therefore you should not use these as a general replacement for TEST_CHECK.\n * Use it with some caution, especially if your test causes some other side\n * effects to the outside world (e.g. communicating with some server, inserting\n * into a database etc.).\n */\n#define TEST_ASSERT_(cond,...)                                                 \\\n    do {                                                                       \\\n        if(!acutest_check_((cond), __FILE__, __LINE__, __VA_ARGS__))           \\\n            acutest_abort_();                                                  \\\n    } while(0)\n#define TEST_ASSERT(cond)                                                      \\\n    do {                                                                       \\\n        if(!acutest_check_((cond), __FILE__, __LINE__, \"%s\", #cond))           \\\n            acutest_abort_();                                                  \\\n    } while(0)\n\n\n#ifdef __cplusplus\n/* Macros to verify that the code (the 1st argument) throws exception of given\n * type (the 2nd argument). (Note these macros are only available in C++.)\n *\n * TEST_EXCEPTION_ is like TEST_EXCEPTION but accepts custom printf-like\n * message.\n *\n * For example:\n *\n *   TEST_EXCEPTION(function_that_throw(), ExpectedExceptionType);\n *\n * If the function_that_throw() throws ExpectedExceptionType, the check passes.\n * If the function throws anything incompatible with ExpectedExceptionType\n * (or if it does not thrown an exception at all), the check fails.\n */\n#define TEST_EXCEPTION(code, exctype)                                          \\\n    do {                                                                       \\\n        bool exc_ok_ = false;                                                  \\\n        const char *msg_ = NULL;                                               \\\n        try {                                                                  \\\n            code;                                                              \\\n            msg_ = \"No exception thrown.\";                                     \\\n        } catch(exctype const&) {                                              \\\n            exc_ok_= true;                                                     \\\n        } catch(...) {                                                         \\\n            msg_ = \"Unexpected exception thrown.\";                             \\\n        }                                                                      \\\n        acutest_check_(exc_ok_, __FILE__, __LINE__, #code \" throws \" #exctype);\\\n        if(msg_ != NULL)                                                       \\\n            acutest_message_(\"%s\", msg_);                                      \\\n    } while(0)\n#define TEST_EXCEPTION_(code, exctype, ...)                                    \\\n    do {                                                                       \\\n        bool exc_ok_ = false;                                                  \\\n        const char *msg_ = NULL;                                               \\\n        try {                                                                  \\\n            code;                                                              \\\n            msg_ = \"No exception thrown.\";                                     \\\n        } catch(exctype const&) {                                              \\\n            exc_ok_= true;                                                     \\\n        } catch(...) {                                                         \\\n            msg_ = \"Unexpected exception thrown.\";                             \\\n        }                                                                      \\\n        acutest_check_(exc_ok_, __FILE__, __LINE__, __VA_ARGS__);              \\\n        if(msg_ != NULL)                                                       \\\n            acutest_message_(\"%s\", msg_);                                      \\\n    } while(0)\n#endif  /* #ifdef __cplusplus */\n\n\n/* Sometimes it is useful to split execution of more complex unit tests to some\n * smaller parts and associate those parts with some names.\n *\n * This is especially handy if the given unit test is implemented as a loop\n * over some vector of multiple testing inputs. Using these macros allow to use\n * sort of subtitle for each iteration of the loop (e.g. outputting the input\n * itself or a name associated to it), so that if any TEST_CHECK condition\n * fails in the loop, it can be easily seen which iteration triggers the\n * failure, without the need to manually output the iteration-specific data in\n * every single TEST_CHECK inside the loop body.\n *\n * TEST_CASE allows to specify only single string as the name of the case,\n * TEST_CASE_ provides all the power of printf-like string formatting.\n *\n * Note that the test cases cannot be nested. Starting a new test case ends\n * implicitly the previous one. To end the test case explicitly (e.g. to end\n * the last test case after exiting the loop), you may use TEST_CASE(NULL).\n */\n#define TEST_CASE_(...)         acutest_case_(__VA_ARGS__)\n#define TEST_CASE(name)         acutest_case_(\"%s\", name)\n\n\n/* Maximal output per TEST_CASE call. Longer messages are cut.\n * You may define another limit prior including \"acutest.h\"\n */\n#ifndef TEST_CASE_MAXSIZE\n    #define TEST_CASE_MAXSIZE    64\n#endif\n\n\n/* printf-like macro for outputting an extra information about a failure.\n *\n * Intended use is to output some computed output versus the expected value,\n * e.g. like this:\n *\n *   if(!TEST_CHECK(produced == expected)) {\n *       TEST_MSG(\"Expected: %d\", expected);\n *       TEST_MSG(\"Produced: %d\", produced);\n *   }\n *\n * Note the message is only written down if the most recent use of any checking\n * macro (like e.g. TEST_CHECK or TEST_EXCEPTION) in the current test failed.\n * This means the above is equivalent to just this:\n *\n *   TEST_CHECK(produced == expected);\n *   TEST_MSG(\"Expected: %d\", expected);\n *   TEST_MSG(\"Produced: %d\", produced);\n *\n * The macro can deal with multi-line output fairly well. It also automatically\n * adds a final new-line if there is none present.\n */\n#define TEST_MSG(...)           acutest_message_(__VA_ARGS__)\n\n\n/* Maximal output per TEST_MSG call. Longer messages are cut.\n * You may define another limit prior including \"acutest.h\"\n */\n#ifndef TEST_MSG_MAXSIZE\n    #define TEST_MSG_MAXSIZE    1024\n#endif\n\n\n/* Macro for dumping a block of memory.\n *\n * Its intended use is very similar to what TEST_MSG is for, but instead of\n * generating any printf-like message, this is for dumping raw block of a\n * memory in a hexadecimal form:\n *\n *   TEST_CHECK(size_produced == size_expected &&\n *              memcmp(addr_produced, addr_expected, size_produced) == 0);\n *   TEST_DUMP(\"Expected:\", addr_expected, size_expected);\n *   TEST_DUMP(\"Produced:\", addr_produced, size_produced);\n */\n#define TEST_DUMP(title, addr, size)    acutest_dump_(title, addr, size)\n\n/* Maximal output per TEST_DUMP call (in bytes to dump). Longer blocks are cut.\n * You may define another limit prior including \"acutest.h\"\n */\n#ifndef TEST_DUMP_MAXSIZE\n    #define TEST_DUMP_MAXSIZE   1024\n#endif\n\n\n/* Common test initialiation/clean-up\n *\n * In some test suites, it may be needed to perform some sort of the same\n * initialization and/or clean-up in all the tests.\n *\n * Such test suites may use macros TEST_INIT and/or TEST_FINI prior including\n * this header. The expansion of the macro is then used as a body of helper\n * function called just before executing every single (TEST_INIT) or just after\n * it ends (TEST_FINI).\n *\n * Examples of various ways how to use the macro TEST_INIT:\n *\n *   #define TEST_INIT      my_init_func();\n *   #define TEST_INIT      my_init_func()      // Works even without the semicolon\n *   #define TEST_INIT      setlocale(LC_ALL, NULL);\n *   #define TEST_INIT      { setlocale(LC_ALL, NULL); my_init_func(); }\n *\n * TEST_FINI is to be used in the same way.\n */\n\n\n/**********************\n *** Implementation ***\n **********************/\n\n/* The unit test files should not rely on anything below. */\n\n#include <ctype.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <setjmp.h>\n\n#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__) || defined(__HAIKU__)\n    #define ACUTEST_UNIX_       1\n    #include <errno.h>\n    #include <libgen.h>\n    #include <unistd.h>\n    #include <sys/types.h>\n    #include <sys/wait.h>\n    #include <signal.h>\n    #include <time.h>\n\n    #if defined CLOCK_PROCESS_CPUTIME_ID  &&  defined CLOCK_MONOTONIC\n        #define ACUTEST_HAS_POSIX_TIMER_    1\n    #endif\n#endif\n\n#if defined(_gnu_linux_) || defined(__linux__)\n    #define ACUTEST_LINUX_      1\n    #include <fcntl.h>\n    #include <sys/stat.h>\n#endif\n\n#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)\n    #define ACUTEST_WIN_        1\n    #include <windows.h>\n    #include <io.h>\n#endif\n\n#if defined(__APPLE__)\n    #define ACUTEST_MACOS_\n    #include <assert.h>\n    #include <stdbool.h>\n    #include <sys/types.h>\n    #include <unistd.h>\n    #include <sys/sysctl.h>\n#endif\n\n#ifdef __cplusplus\n    #include <exception>\n#endif\n\n#ifdef __has_include\n    #if __has_include(<valgrind.h>)\n        #include <valgrind.h>\n    #endif\n#endif\n\n/* Enable the use of the non-standard keyword __attribute__ to silence warnings under some compilers */\n#if defined(__GNUC__) || defined(__clang__)\n    #define ACUTEST_ATTRIBUTE_(attr)    __attribute__((attr))\n#else\n    #define ACUTEST_ATTRIBUTE_(attr)\n#endif\n\n/* Note our global private identifiers end with '_' to mitigate risk of clash\n * with the unit tests implementation. */\n\n#ifdef __cplusplus\n    extern \"C\" {\n#endif\n\n#ifdef _MSC_VER\n    /* In the multi-platform code like ours, we cannot use the non-standard\n     * \"safe\" functions from Microsoft C lib like e.g. sprintf_s() instead of\n     * standard sprintf(). Hence, lets disable the warning C4996. */\n    #pragma warning(push)\n    #pragma warning(disable: 4996)\n#endif\n\n\nstruct acutest_test_ {\n    const char* name;\n    void (*func)(void);\n};\n\nstruct acutest_test_data_ {\n    unsigned char flags;\n    double duration;\n};\n\nenum {\n    ACUTEST_FLAG_RUN_ = 1 << 0,\n    ACUTEST_FLAG_SUCCESS_ = 1 << 1,\n    ACUTEST_FLAG_FAILURE_ = 1 << 2,\n};\n\nextern const struct acutest_test_ acutest_list_[];\n\nint acutest_check_(int cond, const char* file, int line, const char* fmt, ...);\nvoid acutest_case_(const char* fmt, ...);\nvoid acutest_message_(const char* fmt, ...);\nvoid acutest_dump_(const char* title, const void* addr, size_t size);\nvoid acutest_abort_(void) ACUTEST_ATTRIBUTE_(noreturn);\n\n\n#ifndef TEST_NO_MAIN\n\nstatic char* acutest_argv0_ = NULL;\nstatic size_t acutest_list_size_ = 0;\nstatic struct acutest_test_data_* acutest_test_data_ = NULL;\nstatic size_t acutest_count_ = 0;\nstatic int acutest_no_exec_ = -1;\nstatic int acutest_no_summary_ = 0;\nstatic int acutest_tap_ = 0;\nstatic int acutest_skip_mode_ = 0;\nstatic int acutest_worker_ = 0;\nstatic int acutest_worker_index_ = 0;\nstatic int acutest_cond_failed_ = 0;\nstatic int acutest_was_aborted_ = 0;\nstatic FILE *acutest_xml_output_ = NULL;\n\nstatic int acutest_stat_failed_units_ = 0;\nstatic int acutest_stat_run_units_ = 0;\n\nstatic const struct acutest_test_* acutest_current_test_ = NULL;\nstatic int acutest_current_index_ = 0;\nstatic char acutest_case_name_[TEST_CASE_MAXSIZE] = \"\";\nstatic int acutest_test_already_logged_ = 0;\nstatic int acutest_case_already_logged_ = 0;\nstatic int acutest_verbose_level_ = 2;\nstatic int acutest_test_failures_ = 0;\nstatic int acutest_colorize_ = 0;\nstatic int acutest_timer_ = 0;\n\nstatic int acutest_abort_has_jmp_buf_ = 0;\nstatic jmp_buf acutest_abort_jmp_buf_;\n\n\nstatic void\nacutest_cleanup_(void)\n{\n    free((void*) acutest_test_data_);\n}\n\nstatic void ACUTEST_ATTRIBUTE_(noreturn)\nacutest_exit_(int exit_code)\n{\n    acutest_cleanup_();\n    exit(exit_code);\n}\n\n#if defined ACUTEST_WIN_\n    typedef LARGE_INTEGER acutest_timer_type_;\n    static LARGE_INTEGER acutest_timer_freq_;\n    static acutest_timer_type_ acutest_timer_start_;\n    static acutest_timer_type_ acutest_timer_end_;\n\n    static void\n    acutest_timer_init_(void)\n    {\n        QueryPerformanceFrequency(&acutest_timer_freq_);\n    }\n\n    static void\n    acutest_timer_get_time_(LARGE_INTEGER* ts)\n    {\n        QueryPerformanceCounter(ts);\n    }\n\n    static double\n    acutest_timer_diff_(LARGE_INTEGER start, LARGE_INTEGER end)\n    {\n        double duration = (double)(end.QuadPart - start.QuadPart);\n        duration /= (double)acutest_timer_freq_.QuadPart;\n        return duration;\n    }\n\n    static void\n    acutest_timer_print_diff_(void)\n    {\n        printf(\"%.6lf secs\", acutest_timer_diff_(acutest_timer_start_, acutest_timer_end_));\n    }\n#elif defined ACUTEST_HAS_POSIX_TIMER_\n    static clockid_t acutest_timer_id_;\n    typedef struct timespec acutest_timer_type_;\n    static acutest_timer_type_ acutest_timer_start_;\n    static acutest_timer_type_ acutest_timer_end_;\n\n    static void\n    acutest_timer_init_(void)\n    {\n        if(acutest_timer_ == 1)\n            acutest_timer_id_ = CLOCK_MONOTONIC;\n        else if(acutest_timer_ == 2)\n            acutest_timer_id_ = CLOCK_PROCESS_CPUTIME_ID;\n    }\n\n    static void\n    acutest_timer_get_time_(struct timespec* ts)\n    {\n        clock_gettime(acutest_timer_id_, ts);\n    }\n\n    static double\n    acutest_timer_diff_(struct timespec start, struct timespec end)\n    {\n        double endns;\n        double startns;\n\n        endns = end.tv_sec;\n        endns *= 1e9;\n        endns += end.tv_nsec;\n\n        startns = start.tv_sec;\n        startns *= 1e9;\n        startns += start.tv_nsec;\n\n        return ((endns - startns)/ 1e9);\n    }\n\n    static void\n    acutest_timer_print_diff_(void)\n    {\n        printf(\"%.6lf secs\",\n            acutest_timer_diff_(acutest_timer_start_, acutest_timer_end_));\n    }\n#else\n    typedef int acutest_timer_type_;\n    static acutest_timer_type_ acutest_timer_start_;\n    static acutest_timer_type_ acutest_timer_end_;\n\n    void\n    acutest_timer_init_(void)\n    {}\n\n    static void\n    acutest_timer_get_time_(int* ts)\n    {\n        (void) ts;\n    }\n\n    static double\n    acutest_timer_diff_(int start, int end)\n    {\n        (void) start;\n        (void) end;\n        return 0.0;\n    }\n\n    static void\n    acutest_timer_print_diff_(void)\n    {}\n#endif\n\n#define ACUTEST_COLOR_DEFAULT_              0\n#define ACUTEST_COLOR_GREEN_                1\n#define ACUTEST_COLOR_RED_                  2\n#define ACUTEST_COLOR_DEFAULT_INTENSIVE_    3\n#define ACUTEST_COLOR_GREEN_INTENSIVE_      4\n#define ACUTEST_COLOR_RED_INTENSIVE_        5\n\nstatic int ACUTEST_ATTRIBUTE_(format (printf, 2, 3))\nacutest_colored_printf_(int color, const char* fmt, ...)\n{\n    va_list args;\n    char buffer[256];\n    int n;\n\n    va_start(args, fmt);\n    vsnprintf(buffer, sizeof(buffer), fmt, args);\n    va_end(args);\n    buffer[sizeof(buffer)-1] = '\\0';\n\n    if(!acutest_colorize_) {\n        return printf(\"%s\", buffer);\n    }\n\n#if defined ACUTEST_UNIX_\n    {\n        const char* col_str;\n        switch(color) {\n            case ACUTEST_COLOR_GREEN_:              col_str = \"\\033[0;32m\"; break;\n            case ACUTEST_COLOR_RED_:                col_str = \"\\033[0;31m\"; break;\n            case ACUTEST_COLOR_GREEN_INTENSIVE_:    col_str = \"\\033[1;32m\"; break;\n            case ACUTEST_COLOR_RED_INTENSIVE_:      col_str = \"\\033[1;31m\"; break;\n            case ACUTEST_COLOR_DEFAULT_INTENSIVE_:  col_str = \"\\033[1m\"; break;\n            default:                                col_str = \"\\033[0m\"; break;\n        }\n        printf(\"%s\", col_str);\n        n = printf(\"%s\", buffer);\n        printf(\"\\033[0m\");\n        return n;\n    }\n#elif defined ACUTEST_WIN_\n    {\n        HANDLE h;\n        CONSOLE_SCREEN_BUFFER_INFO info;\n        WORD attr;\n\n        h = GetStdHandle(STD_OUTPUT_HANDLE);\n        GetConsoleScreenBufferInfo(h, &info);\n\n        switch(color) {\n            case ACUTEST_COLOR_GREEN_:              attr = FOREGROUND_GREEN; break;\n            case ACUTEST_COLOR_RED_:                attr = FOREGROUND_RED; break;\n            case ACUTEST_COLOR_GREEN_INTENSIVE_:    attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY; break;\n            case ACUTEST_COLOR_RED_INTENSIVE_:      attr = FOREGROUND_RED | FOREGROUND_INTENSITY; break;\n            case ACUTEST_COLOR_DEFAULT_INTENSIVE_:  attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; break;\n            default:                                attr = 0; break;\n        }\n        if(attr != 0)\n            SetConsoleTextAttribute(h, attr);\n        n = printf(\"%s\", buffer);\n        SetConsoleTextAttribute(h, info.wAttributes);\n        return n;\n    }\n#else\n    n = printf(\"%s\", buffer);\n    return n;\n#endif\n}\n\nstatic void\nacutest_begin_test_line_(const struct acutest_test_* test)\n{\n    if(!acutest_tap_) {\n        if(acutest_verbose_level_ >= 3) {\n            acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, \"Test %s:\\n\", test->name);\n            acutest_test_already_logged_++;\n        } else if(acutest_verbose_level_ >= 1) {\n            int n;\n            char spaces[48];\n\n            n = acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, \"Test %s... \", test->name);\n            memset(spaces, ' ', sizeof(spaces));\n            if(n < (int) sizeof(spaces))\n                printf(\"%.*s\", (int) sizeof(spaces) - n, spaces);\n        } else {\n            acutest_test_already_logged_ = 1;\n        }\n    }\n}\n\nstatic void\nacutest_finish_test_line_(int result)\n{\n    if(acutest_tap_) {\n        const char* str = (result == 0) ? \"ok\" : \"not ok\";\n\n        printf(\"%s %d - %s\\n\", str, acutest_current_index_ + 1, acutest_current_test_->name);\n\n        if(result == 0  &&  acutest_timer_) {\n            printf(\"# Duration: \");\n            acutest_timer_print_diff_();\n            printf(\"\\n\");\n        }\n    } else {\n        int color = (result == 0) ? ACUTEST_COLOR_GREEN_INTENSIVE_ : ACUTEST_COLOR_RED_INTENSIVE_;\n        const char* str = (result == 0) ? \"OK\" : \"FAILED\";\n        printf(\"[ \");\n        acutest_colored_printf_(color, \"%s\", str);\n        printf(\" ]\");\n\n        if(result == 0  &&  acutest_timer_) {\n            printf(\"  \");\n            acutest_timer_print_diff_();\n        }\n\n        printf(\"\\n\");\n    }\n}\n\nstatic void\nacutest_line_indent_(int level)\n{\n    static const char spaces[] = \"                \";\n    int n = level * 2;\n\n    if(acutest_tap_  &&  n > 0) {\n        n--;\n        printf(\"#\");\n    }\n\n    while(n > 16) {\n        printf(\"%s\", spaces);\n        n -= 16;\n    }\n    printf(\"%.*s\", n, spaces);\n}\n\nint ACUTEST_ATTRIBUTE_(format (printf, 4, 5))\nacutest_check_(int cond, const char* file, int line, const char* fmt, ...)\n{\n    const char *result_str;\n    int result_color;\n    int verbose_level;\n\n    if(cond) {\n        result_str = \"ok\";\n        result_color = ACUTEST_COLOR_GREEN_;\n        verbose_level = 3;\n    } else {\n        if(!acutest_test_already_logged_  &&  acutest_current_test_ != NULL)\n            acutest_finish_test_line_(-1);\n\n        result_str = \"failed\";\n        result_color = ACUTEST_COLOR_RED_;\n        verbose_level = 2;\n        acutest_test_failures_++;\n        acutest_test_already_logged_++;\n    }\n\n    if(acutest_verbose_level_ >= verbose_level) {\n        va_list args;\n\n        if(!acutest_case_already_logged_  &&  acutest_case_name_[0]) {\n            acutest_line_indent_(1);\n            acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, \"Case %s:\\n\", acutest_case_name_);\n            acutest_test_already_logged_++;\n            acutest_case_already_logged_++;\n        }\n\n        acutest_line_indent_(acutest_case_name_[0] ? 2 : 1);\n        if(file != NULL) {\n#ifdef ACUTEST_WIN_\n            const char* lastsep1 = strrchr(file, '\\\\');\n            const char* lastsep2 = strrchr(file, '/');\n            if(lastsep1 == NULL)\n                lastsep1 = file-1;\n            if(lastsep2 == NULL)\n                lastsep2 = file-1;\n            file = (lastsep1 > lastsep2 ? lastsep1 : lastsep2) + 1;\n#else\n            const char* lastsep = strrchr(file, '/');\n            if(lastsep != NULL)\n                file = lastsep+1;\n#endif\n            printf(\"%s:%d: Check \", file, line);\n        }\n\n        va_start(args, fmt);\n        vprintf(fmt, args);\n        va_end(args);\n\n        printf(\"... \");\n        acutest_colored_printf_(result_color, \"%s\", result_str);\n        printf(\"\\n\");\n        acutest_test_already_logged_++;\n    }\n\n    acutest_cond_failed_ = (cond == 0);\n    return !acutest_cond_failed_;\n}\n\nvoid ACUTEST_ATTRIBUTE_(format (printf, 1, 2))\nacutest_case_(const char* fmt, ...)\n{\n    va_list args;\n\n    if(acutest_verbose_level_ < 2)\n        return;\n\n    if(acutest_case_name_[0]) {\n        acutest_case_already_logged_ = 0;\n        acutest_case_name_[0] = '\\0';\n    }\n\n    if(fmt == NULL)\n        return;\n\n    va_start(args, fmt);\n    vsnprintf(acutest_case_name_, sizeof(acutest_case_name_) - 1, fmt, args);\n    va_end(args);\n    acutest_case_name_[sizeof(acutest_case_name_) - 1] = '\\0';\n\n    if(acutest_verbose_level_ >= 3) {\n        acutest_line_indent_(1);\n        acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, \"Case %s:\\n\", acutest_case_name_);\n        acutest_test_already_logged_++;\n        acutest_case_already_logged_++;\n    }\n}\n\nvoid ACUTEST_ATTRIBUTE_(format (printf, 1, 2))\nacutest_message_(const char* fmt, ...)\n{\n    char buffer[TEST_MSG_MAXSIZE];\n    char* line_beg;\n    char* line_end;\n    va_list args;\n\n    if(acutest_verbose_level_ < 2)\n        return;\n\n    /* We allow extra message only when something is already wrong in the\n     * current test. */\n    if(acutest_current_test_ == NULL  ||  !acutest_cond_failed_)\n        return;\n\n    va_start(args, fmt);\n    vsnprintf(buffer, TEST_MSG_MAXSIZE, fmt, args);\n    va_end(args);\n    buffer[TEST_MSG_MAXSIZE-1] = '\\0';\n\n    line_beg = buffer;\n    while(1) {\n        line_end = strchr(line_beg, '\\n');\n        if(line_end == NULL)\n            break;\n        acutest_line_indent_(acutest_case_name_[0] ? 3 : 2);\n        printf(\"%.*s\\n\", (int)(line_end - line_beg), line_beg);\n        line_beg = line_end + 1;\n    }\n    if(line_beg[0] != '\\0') {\n        acutest_line_indent_(acutest_case_name_[0] ? 3 : 2);\n        printf(\"%s\\n\", line_beg);\n    }\n}\n\nvoid\nacutest_dump_(const char* title, const void* addr, size_t size)\n{\n    static const size_t BYTES_PER_LINE = 16;\n    size_t line_beg;\n    size_t truncate = 0;\n\n    if(acutest_verbose_level_ < 2)\n        return;\n\n    /* We allow extra message only when something is already wrong in the\n     * current test. */\n    if(acutest_current_test_ == NULL  ||  !acutest_cond_failed_)\n        return;\n\n    if(size > TEST_DUMP_MAXSIZE) {\n        truncate = size - TEST_DUMP_MAXSIZE;\n        size = TEST_DUMP_MAXSIZE;\n    }\n\n    acutest_line_indent_(acutest_case_name_[0] ? 3 : 2);\n    printf((title[strlen(title)-1] == ':') ? \"%s\\n\" : \"%s:\\n\", title);\n\n    for(line_beg = 0; line_beg < size; line_beg += BYTES_PER_LINE) {\n        size_t line_end = line_beg + BYTES_PER_LINE;\n        size_t off;\n\n        acutest_line_indent_(acutest_case_name_[0] ? 4 : 3);\n        printf(\"%08lx: \", (unsigned long)line_beg);\n        for(off = line_beg; off < line_end; off++) {\n            if(off < size)\n                printf(\" %02x\", ((const unsigned char*)addr)[off]);\n            else\n                printf(\"   \");\n        }\n\n        printf(\"  \");\n        for(off = line_beg; off < line_end; off++) {\n            unsigned char byte = ((const unsigned char*)addr)[off];\n            if(off < size)\n                printf(\"%c\", (iscntrl(byte) ? '.' : byte));\n            else\n                break;\n        }\n\n        printf(\"\\n\");\n    }\n\n    if(truncate > 0) {\n        acutest_line_indent_(acutest_case_name_[0] ? 4 : 3);\n        printf(\"           ... (and more %u bytes)\\n\", (unsigned) truncate);\n    }\n}\n\n/* This is called just before each test */\nstatic void\nacutest_init_(const char *test_name)\n{\n#ifdef TEST_INIT\n    TEST_INIT\n    ; /* Allow for a single unterminated function call */\n#endif\n\n    /* Suppress any warnings about unused variable. */\n    (void) test_name;\n}\n\n/* This is called after each test */\nstatic void\nacutest_fini_(const char *test_name)\n{\n#ifdef TEST_FINI\n    TEST_FINI\n    ; /* Allow for a single unterminated function call */\n#endif\n\n    /* Suppress any warnings about unused variable. */\n    (void) test_name;\n}\n\nvoid\nacutest_abort_(void)\n{\n    if(acutest_abort_has_jmp_buf_) {\n        longjmp(acutest_abort_jmp_buf_, 1);\n    } else {\n        if(acutest_current_test_ != NULL)\n            acutest_fini_(acutest_current_test_->name);\n        abort();\n    }\n}\n\nstatic void\nacutest_list_names_(void)\n{\n    const struct acutest_test_* test;\n\n    printf(\"Unit tests:\\n\");\n    for(test = &acutest_list_[0]; test->func != NULL; test++)\n        printf(\"  %s\\n\", test->name);\n}\n\nstatic void\nacutest_remember_(int i)\n{\n    if(acutest_test_data_[i].flags & ACUTEST_FLAG_RUN_)\n        return;\n\n    acutest_test_data_[i].flags |= ACUTEST_FLAG_RUN_;\n    acutest_count_++;\n}\n\nstatic void\nacutest_set_success_(int i, int success)\n{\n    acutest_test_data_[i].flags |= success ? ACUTEST_FLAG_SUCCESS_ : ACUTEST_FLAG_FAILURE_;\n}\n\nstatic void\nacutest_set_duration_(int i, double duration)\n{\n    acutest_test_data_[i].duration = duration;\n}\n\nstatic int\nacutest_name_contains_word_(const char* name, const char* pattern)\n{\n    static const char word_delim[] = \" \\t-_/.,:;\";\n    const char* substr;\n    size_t pattern_len;\n\n    pattern_len = strlen(pattern);\n\n    substr = strstr(name, pattern);\n    while(substr != NULL) {\n        int starts_on_word_boundary = (substr == name || strchr(word_delim, substr[-1]) != NULL);\n        int ends_on_word_boundary = (substr[pattern_len] == '\\0' || strchr(word_delim, substr[pattern_len]) != NULL);\n\n        if(starts_on_word_boundary && ends_on_word_boundary)\n            return 1;\n\n        substr = strstr(substr+1, pattern);\n    }\n\n    return 0;\n}\n\nstatic int\nacutest_lookup_(const char* pattern)\n{\n    int i;\n    int n = 0;\n\n    /* Try exact match. */\n    for(i = 0; i < (int) acutest_list_size_; i++) {\n        if(strcmp(acutest_list_[i].name, pattern) == 0) {\n            acutest_remember_(i);\n            n++;\n            break;\n        }\n    }\n    if(n > 0)\n        return n;\n\n    /* Try word match. */\n    for(i = 0; i < (int) acutest_list_size_; i++) {\n        if(acutest_name_contains_word_(acutest_list_[i].name, pattern)) {\n            acutest_remember_(i);\n            n++;\n        }\n    }\n    if(n > 0)\n        return n;\n\n    /* Try relaxed match. */\n    for(i = 0; i < (int) acutest_list_size_; i++) {\n        if(strstr(acutest_list_[i].name, pattern) != NULL) {\n            acutest_remember_(i);\n            n++;\n        }\n    }\n\n    return n;\n}\n\n\n/* Called if anything goes bad in Acutest, or if the unit test ends in other\n * way then by normal returning from its function (e.g. exception or some\n * abnormal child process termination). */\nstatic void ACUTEST_ATTRIBUTE_(format (printf, 1, 2))\nacutest_error_(const char* fmt, ...)\n{\n    if(acutest_verbose_level_ == 0)\n        return;\n\n    if(acutest_verbose_level_ >= 2) {\n        va_list args;\n\n        acutest_line_indent_(1);\n        if(acutest_verbose_level_ >= 3)\n            acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, \"ERROR: \");\n        va_start(args, fmt);\n        vprintf(fmt, args);\n        va_end(args);\n        printf(\"\\n\");\n    }\n\n    if(acutest_verbose_level_ >= 3) {\n        printf(\"\\n\");\n    }\n}\n\n/* Call directly the given test unit function. */\nstatic int\nacutest_do_run_(const struct acutest_test_* test, int index)\n{\n    int status = -1;\n\n    acutest_was_aborted_ = 0;\n    acutest_current_test_ = test;\n    acutest_current_index_ = index;\n    acutest_test_failures_ = 0;\n    acutest_test_already_logged_ = 0;\n    acutest_cond_failed_ = 0;\n\n#ifdef __cplusplus\n    try {\n#endif\n        acutest_init_(test->name);\n        acutest_begin_test_line_(test);\n\n        /* This is good to do in case the test unit crashes. */\n        fflush(stdout);\n        fflush(stderr);\n\n        if(!acutest_worker_) {\n            acutest_abort_has_jmp_buf_ = 1;\n            if(setjmp(acutest_abort_jmp_buf_) != 0) {\n                acutest_was_aborted_ = 1;\n                goto aborted;\n            }\n        }\n\n        acutest_timer_get_time_(&acutest_timer_start_);\n        test->func();\naborted:\n        acutest_abort_has_jmp_buf_ = 0;\n        acutest_timer_get_time_(&acutest_timer_end_);\n\n        if(acutest_verbose_level_ >= 3) {\n            acutest_line_indent_(1);\n            if(acutest_test_failures_ == 0) {\n                acutest_colored_printf_(ACUTEST_COLOR_GREEN_INTENSIVE_, \"SUCCESS: \");\n                printf(\"All conditions have passed.\\n\");\n\n                if(acutest_timer_) {\n                    acutest_line_indent_(1);\n                    printf(\"Duration: \");\n                    acutest_timer_print_diff_();\n                    printf(\"\\n\");\n                }\n            } else {\n                acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, \"FAILED: \");\n                if(!acutest_was_aborted_) {\n                    printf(\"%d condition%s %s failed.\\n\",\n                            acutest_test_failures_,\n                            (acutest_test_failures_ == 1) ? \"\" : \"s\",\n                            (acutest_test_failures_ == 1) ? \"has\" : \"have\");\n                } else {\n                    printf(\"Aborted.\\n\");\n                }\n            }\n            printf(\"\\n\");\n        } else if(acutest_verbose_level_ >= 1 && acutest_test_failures_ == 0) {\n            acutest_finish_test_line_(0);\n        }\n\n        status = (acutest_test_failures_ == 0) ? 0 : -1;\n\n#ifdef __cplusplus\n    } catch(std::exception& e) {\n        const char* what = e.what();\n        acutest_check_(0, NULL, 0, \"Threw std::exception\");\n        if(what != NULL)\n            acutest_message_(\"std::exception::what(): %s\", what);\n\n        if(acutest_verbose_level_ >= 3) {\n            acutest_line_indent_(1);\n            acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, \"FAILED: \");\n            printf(\"C++ exception.\\n\\n\");\n        }\n    } catch(...) {\n        acutest_check_(0, NULL, 0, \"Threw an exception\");\n\n        if(acutest_verbose_level_ >= 3) {\n            acutest_line_indent_(1);\n            acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, \"FAILED: \");\n            printf(\"C++ exception.\\n\\n\");\n        }\n    }\n#endif\n\n    acutest_fini_(test->name);\n    acutest_case_(NULL);\n    acutest_current_test_ = NULL;\n\n    return status;\n}\n\n/* Trigger the unit test. If possible (and not suppressed) it starts a child\n * process who calls acutest_do_run_(), otherwise it calls acutest_do_run_()\n * directly. */\nstatic void\nacutest_run_(const struct acutest_test_* test, int index, int master_index)\n{\n    int failed = 1;\n    acutest_timer_type_ start, end;\n\n    acutest_current_test_ = test;\n    acutest_test_already_logged_ = 0;\n    acutest_timer_get_time_(&start);\n\n    if(!acutest_no_exec_) {\n\n#if defined(ACUTEST_UNIX_)\n\n        pid_t pid;\n        int exit_code;\n\n        /* Make sure the child starts with empty I/O buffers. */\n        fflush(stdout);\n        fflush(stderr);\n\n        pid = fork();\n        if(pid == (pid_t)-1) {\n            acutest_error_(\"Cannot fork. %s [%d]\", strerror(errno), errno);\n            failed = 1;\n        } else if(pid == 0) {\n            /* Child: Do the test. */\n            acutest_worker_ = 1;\n            failed = (acutest_do_run_(test, index) != 0);\n            acutest_exit_(failed ? 1 : 0);\n        } else {\n            /* Parent: Wait until child terminates and analyze its exit code. */\n            waitpid(pid, &exit_code, 0);\n            if(WIFEXITED(exit_code)) {\n                switch(WEXITSTATUS(exit_code)) {\n                    case 0:   failed = 0; break;   /* test has passed. */\n                    case 1:   /* noop */ break;    /* \"normal\" failure. */\n                    default:  acutest_error_(\"Unexpected exit code [%d]\", WEXITSTATUS(exit_code));\n                }\n            } else if(WIFSIGNALED(exit_code)) {\n                char tmp[32];\n                const char* signame;\n                switch(WTERMSIG(exit_code)) {\n                    case SIGINT:  signame = \"SIGINT\"; break;\n                    case SIGHUP:  signame = \"SIGHUP\"; break;\n                    case SIGQUIT: signame = \"SIGQUIT\"; break;\n                    case SIGABRT: signame = \"SIGABRT\"; break;\n                    case SIGKILL: signame = \"SIGKILL\"; break;\n                    case SIGSEGV: signame = \"SIGSEGV\"; break;\n                    case SIGILL:  signame = \"SIGILL\"; break;\n                    case SIGTERM: signame = \"SIGTERM\"; break;\n                    default:      sprintf(tmp, \"signal %d\", WTERMSIG(exit_code)); signame = tmp; break;\n                }\n                acutest_error_(\"Test interrupted by %s.\", signame);\n            } else {\n                acutest_error_(\"Test ended in an unexpected way [%d].\", exit_code);\n            }\n        }\n\n#elif defined(ACUTEST_WIN_)\n\n        char buffer[512] = {0};\n        STARTUPINFOA startupInfo;\n        PROCESS_INFORMATION processInfo;\n        DWORD exitCode;\n\n        /* Windows has no fork(). So we propagate all info into the child\n         * through a command line arguments. */\n        _snprintf(buffer, sizeof(buffer)-1,\n                 \"%s --worker=%d %s --no-exec --no-summary %s --verbose=%d --color=%s -- \\\"%s\\\"\",\n                 acutest_argv0_, index, acutest_timer_ ? \"--time\" : \"\",\n                 acutest_tap_ ? \"--tap\" : \"\", acutest_verbose_level_,\n                 acutest_colorize_ ? \"always\" : \"never\",\n                 test->name);\n        memset(&startupInfo, 0, sizeof(startupInfo));\n        startupInfo.cb = sizeof(STARTUPINFO);\n        if(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo)) {\n            WaitForSingleObject(processInfo.hProcess, INFINITE);\n            GetExitCodeProcess(processInfo.hProcess, &exitCode);\n            CloseHandle(processInfo.hThread);\n            CloseHandle(processInfo.hProcess);\n            failed = (exitCode != 0);\n            if(exitCode > 1) {\n                switch(exitCode) {\n                    case 3:             acutest_error_(\"Aborted.\"); break;\n                    case 0xC0000005:    acutest_error_(\"Access violation.\"); break;\n                    default:            acutest_error_(\"Test ended in an unexpected way [%lu].\", exitCode); break;\n                }\n            }\n        } else {\n            acutest_error_(\"Cannot create unit test subprocess [%ld].\", GetLastError());\n            failed = 1;\n        }\n\n#else\n\n        /* A platform where we don't know how to run child process. */\n        failed = (acutest_do_run_(test, index) != 0);\n\n#endif\n\n    } else {\n        /* Child processes suppressed through --no-exec. */\n        failed = (acutest_do_run_(test, index) != 0);\n    }\n    acutest_timer_get_time_(&end);\n\n    acutest_current_test_ = NULL;\n\n    acutest_stat_run_units_++;\n    if(failed)\n        acutest_stat_failed_units_++;\n\n    acutest_set_success_(master_index, !failed);\n    acutest_set_duration_(master_index, acutest_timer_diff_(start, end));\n}\n\n#if defined(ACUTEST_WIN_)\n/* Callback for SEH events. */\nstatic LONG CALLBACK\nacutest_seh_exception_filter_(EXCEPTION_POINTERS *ptrs)\n{\n    acutest_check_(0, NULL, 0, \"Unhandled SEH exception\");\n    acutest_message_(\"Exception code:    0x%08lx\", ptrs->ExceptionRecord->ExceptionCode);\n    acutest_message_(\"Exception address: 0x%p\", ptrs->ExceptionRecord->ExceptionAddress);\n\n    fflush(stdout);\n    fflush(stderr);\n\n    return EXCEPTION_EXECUTE_HANDLER;\n}\n#endif\n\n\n#define ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_    0x0001\n#define ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_    0x0002\n\n#define ACUTEST_CMDLINE_OPTID_NONE_             0\n#define ACUTEST_CMDLINE_OPTID_UNKNOWN_          (-0x7fffffff + 0)\n#define ACUTEST_CMDLINE_OPTID_MISSINGARG_       (-0x7fffffff + 1)\n#define ACUTEST_CMDLINE_OPTID_BOGUSARG_         (-0x7fffffff + 2)\n\ntypedef struct acutest_test_CMDLINE_OPTION_ {\n    char shortname;\n    const char* longname;\n    int id;\n    unsigned flags;\n} ACUTEST_CMDLINE_OPTION_;\n\nstatic int\nacutest_cmdline_handle_short_opt_group_(const ACUTEST_CMDLINE_OPTION_* options,\n                    const char* arggroup,\n                    int (*callback)(int /*optval*/, const char* /*arg*/))\n{\n    const ACUTEST_CMDLINE_OPTION_* opt;\n    int i;\n    int ret = 0;\n\n    for(i = 0; arggroup[i] != '\\0'; i++) {\n        for(opt = options; opt->id != 0; opt++) {\n            if(arggroup[i] == opt->shortname)\n                break;\n        }\n\n        if(opt->id != 0  &&  !(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) {\n            ret = callback(opt->id, NULL);\n        } else {\n            /* Unknown option. */\n            char badoptname[3];\n            badoptname[0] = '-';\n            badoptname[1] = arggroup[i];\n            badoptname[2] = '\\0';\n            ret = callback((opt->id != 0 ? ACUTEST_CMDLINE_OPTID_MISSINGARG_ : ACUTEST_CMDLINE_OPTID_UNKNOWN_),\n                            badoptname);\n        }\n\n        if(ret != 0)\n            break;\n    }\n\n    return ret;\n}\n\n#define ACUTEST_CMDLINE_AUXBUF_SIZE_  32\n\nstatic int\nacutest_cmdline_read_(const ACUTEST_CMDLINE_OPTION_* options, int argc, char** argv,\n                      int (*callback)(int /*optval*/, const char* /*arg*/))\n{\n\n    const ACUTEST_CMDLINE_OPTION_* opt;\n    char auxbuf[ACUTEST_CMDLINE_AUXBUF_SIZE_+1];\n    int after_doubledash = 0;\n    int i = 1;\n    int ret = 0;\n\n    auxbuf[ACUTEST_CMDLINE_AUXBUF_SIZE_] = '\\0';\n\n    while(i < argc) {\n        if(after_doubledash  ||  strcmp(argv[i], \"-\") == 0) {\n            /* Non-option argument. */\n            ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]);\n        } else if(strcmp(argv[i], \"--\") == 0) {\n            /* End of options. All the remaining members are non-option arguments. */\n            after_doubledash = 1;\n        } else if(argv[i][0] != '-') {\n            /* Non-option argument. */\n            ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]);\n        } else {\n            for(opt = options; opt->id != 0; opt++) {\n                if(opt->longname != NULL  &&  strncmp(argv[i], \"--\", 2) == 0) {\n                    size_t len = strlen(opt->longname);\n                    if(strncmp(argv[i]+2, opt->longname, len) == 0) {\n                        /* Regular long option. */\n                        if(argv[i][2+len] == '\\0') {\n                            /* with no argument provided. */\n                            if(!(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_))\n                                ret = callback(opt->id, NULL);\n                            else\n                                ret = callback(ACUTEST_CMDLINE_OPTID_MISSINGARG_, argv[i]);\n                            break;\n                        } else if(argv[i][2+len] == '=') {\n                            /* with an argument provided. */\n                            if(opt->flags & (ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ | ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_)) {\n                                ret = callback(opt->id, argv[i]+2+len+1);\n                            } else {\n                                sprintf(auxbuf, \"--%s\", opt->longname);\n                                ret = callback(ACUTEST_CMDLINE_OPTID_BOGUSARG_, auxbuf);\n                            }\n                            break;\n                        } else {\n                            continue;\n                        }\n                    }\n                } else if(opt->shortname != '\\0'  &&  argv[i][0] == '-') {\n                    if(argv[i][1] == opt->shortname) {\n                        /* Regular short option. */\n                        if(opt->flags & ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_) {\n                            if(argv[i][2] != '\\0')\n                                ret = callback(opt->id, argv[i]+2);\n                            else if(i+1 < argc)\n                                ret = callback(opt->id, argv[++i]);\n                            else\n                                ret = callback(ACUTEST_CMDLINE_OPTID_MISSINGARG_, argv[i]);\n                            break;\n                        } else {\n                            ret = callback(opt->id, NULL);\n\n                            /* There might be more (argument-less) short options\n                             * grouped together. */\n                            if(ret == 0  &&  argv[i][2] != '\\0')\n                                ret = acutest_cmdline_handle_short_opt_group_(options, argv[i]+2, callback);\n                            break;\n                        }\n                    }\n                }\n            }\n\n            if(opt->id == 0) {  /* still not handled? */\n                if(argv[i][0] != '-') {\n                    /* Non-option argument. */\n                    ret = callback(ACUTEST_CMDLINE_OPTID_NONE_, argv[i]);\n                } else {\n                    /* Unknown option. */\n                    char* badoptname = argv[i];\n\n                    if(strncmp(badoptname, \"--\", 2) == 0) {\n                        /* Strip any argument from the long option. */\n                        char* assignment = strchr(badoptname, '=');\n                        if(assignment != NULL) {\n                            size_t len = assignment - badoptname;\n                            if(len > ACUTEST_CMDLINE_AUXBUF_SIZE_)\n                                len = ACUTEST_CMDLINE_AUXBUF_SIZE_;\n                            strncpy(auxbuf, badoptname, len);\n                            auxbuf[len] = '\\0';\n                            badoptname = auxbuf;\n                        }\n                    }\n\n                    ret = callback(ACUTEST_CMDLINE_OPTID_UNKNOWN_, badoptname);\n                }\n            }\n        }\n\n        if(ret != 0)\n            return ret;\n        i++;\n    }\n\n    return ret;\n}\n\nstatic void\nacutest_help_(void)\n{\n    printf(\"Usage: %s [options] [test...]\\n\", acutest_argv0_);\n    printf(\"\\n\");\n    printf(\"Run the specified unit tests; or if the option '--skip' is used, run all\\n\");\n    printf(\"tests in the suite but those listed.  By default, if no tests are specified\\n\");\n    printf(\"on the command line, all unit tests in the suite are run.\\n\");\n    printf(\"\\n\");\n    printf(\"Options:\\n\");\n    printf(\"  -s, --skip            Execute all unit tests but the listed ones\\n\");\n    printf(\"      --exec[=WHEN]     If supported, execute unit tests as child processes\\n\");\n    printf(\"                          (WHEN is one of 'auto', 'always', 'never')\\n\");\n    printf(\"  -E, --no-exec         Same as --exec=never\\n\");\n#if defined ACUTEST_WIN_\n    printf(\"  -t, --time            Measure test duration\\n\");\n#elif defined ACUTEST_HAS_POSIX_TIMER_\n    printf(\"  -t, --time            Measure test duration (real time)\\n\");\n    printf(\"      --time=TIMER      Measure test duration, using given timer\\n\");\n    printf(\"                          (TIMER is one of 'real', 'cpu')\\n\");\n#endif\n    printf(\"      --no-summary      Suppress printing of test results summary\\n\");\n    printf(\"      --tap             Produce TAP-compliant output\\n\");\n    printf(\"                          (See https://testanything.org/)\\n\");\n    printf(\"  -x, --xml-output=FILE Enable XUnit output to the given file\\n\");\n    printf(\"  -l, --list            List unit tests in the suite and exit\\n\");\n    printf(\"  -v, --verbose         Make output more verbose\\n\");\n    printf(\"      --verbose=LEVEL   Set verbose level to LEVEL:\\n\");\n    printf(\"                          0 ... Be silent\\n\");\n    printf(\"                          1 ... Output one line per test (and summary)\\n\");\n    printf(\"                          2 ... As 1 and failed conditions (this is default)\\n\");\n    printf(\"                          3 ... As 1 and all conditions (and extended summary)\\n\");\n    printf(\"  -q, --quiet           Same as --verbose=0\\n\");\n    printf(\"      --color[=WHEN]    Enable colorized output\\n\");\n    printf(\"                          (WHEN is one of 'auto', 'always', 'never')\\n\");\n    printf(\"      --no-color        Same as --color=never\\n\");\n    printf(\"  -h, --help            Display this help and exit\\n\");\n\n    if(acutest_list_size_ < 16) {\n        printf(\"\\n\");\n        acutest_list_names_();\n    }\n}\n\nstatic const ACUTEST_CMDLINE_OPTION_ acutest_cmdline_options_[] = {\n    { 's',  \"skip\",         's', 0 },\n    {  0,   \"exec\",         'e', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ },\n    { 'E',  \"no-exec\",      'E', 0 },\n#if defined ACUTEST_WIN_\n    { 't',  \"time\",         't', 0 },\n    {  0,   \"timer\",        't', 0 },   /* kept for compatibility */\n#elif defined ACUTEST_HAS_POSIX_TIMER_\n    { 't',  \"time\",         't', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ },\n    {  0,   \"timer\",        't', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ },  /* kept for compatibility */\n#endif\n    {  0,   \"no-summary\",   'S', 0 },\n    {  0,   \"tap\",          'T', 0 },\n    { 'l',  \"list\",         'l', 0 },\n    { 'v',  \"verbose\",      'v', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ },\n    { 'q',  \"quiet\",        'q', 0 },\n    {  0,   \"color\",        'c', ACUTEST_CMDLINE_OPTFLAG_OPTIONALARG_ },\n    {  0,   \"no-color\",     'C', 0 },\n    { 'h',  \"help\",         'h', 0 },\n    {  0,   \"worker\",       'w', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ },  /* internal */\n    { 'x',  \"xml-output\",   'x', ACUTEST_CMDLINE_OPTFLAG_REQUIREDARG_ },\n    {  0,   NULL,            0,  0 }\n};\n\nstatic int\nacutest_cmdline_callback_(int id, const char* arg)\n{\n    switch(id) {\n        case 's':\n            acutest_skip_mode_ = 1;\n            break;\n\n        case 'e':\n            if(arg == NULL || strcmp(arg, \"always\") == 0) {\n                acutest_no_exec_ = 0;\n            } else if(strcmp(arg, \"never\") == 0) {\n                acutest_no_exec_ = 1;\n            } else if(strcmp(arg, \"auto\") == 0) {\n                /*noop*/\n            } else {\n                fprintf(stderr, \"%s: Unrecognized argument '%s' for option --exec.\\n\", acutest_argv0_, arg);\n                fprintf(stderr, \"Try '%s --help' for more information.\\n\", acutest_argv0_);\n                acutest_exit_(2);\n            }\n            break;\n\n        case 'E':\n            acutest_no_exec_ = 1;\n            break;\n\n        case 't':\n#if defined ACUTEST_WIN_  ||  defined ACUTEST_HAS_POSIX_TIMER_\n            if(arg == NULL || strcmp(arg, \"real\") == 0) {\n                acutest_timer_ = 1;\n    #ifndef ACUTEST_WIN_\n            } else if(strcmp(arg, \"cpu\") == 0) {\n                acutest_timer_ = 2;\n    #endif\n            } else {\n                fprintf(stderr, \"%s: Unrecognized argument '%s' for option --time.\\n\", acutest_argv0_, arg);\n                fprintf(stderr, \"Try '%s --help' for more information.\\n\", acutest_argv0_);\n                acutest_exit_(2);\n            }\n#endif\n            break;\n\n        case 'S':\n            acutest_no_summary_ = 1;\n            break;\n\n        case 'T':\n            acutest_tap_ = 1;\n            break;\n\n        case 'l':\n            acutest_list_names_();\n            acutest_exit_(0);\n            break;\n\n        case 'v':\n            acutest_verbose_level_ = (arg != NULL ? atoi(arg) : acutest_verbose_level_+1);\n            break;\n\n        case 'q':\n            acutest_verbose_level_ = 0;\n            break;\n\n        case 'c':\n            if(arg == NULL || strcmp(arg, \"always\") == 0) {\n                acutest_colorize_ = 1;\n            } else if(strcmp(arg, \"never\") == 0) {\n                acutest_colorize_ = 0;\n            } else if(strcmp(arg, \"auto\") == 0) {\n                /*noop*/\n            } else {\n                fprintf(stderr, \"%s: Unrecognized argument '%s' for option --color.\\n\", acutest_argv0_, arg);\n                fprintf(stderr, \"Try '%s --help' for more information.\\n\", acutest_argv0_);\n                acutest_exit_(2);\n            }\n            break;\n\n        case 'C':\n            acutest_colorize_ = 0;\n            break;\n\n        case 'h':\n            acutest_help_();\n            acutest_exit_(0);\n            break;\n\n        case 'w':\n            acutest_worker_ = 1;\n            acutest_worker_index_ = atoi(arg);\n            break;\n        case 'x':\n            acutest_xml_output_ = fopen(arg, \"w\");\n            if (!acutest_xml_output_) {\n                fprintf(stderr, \"Unable to open '%s': %s\\n\", arg, strerror(errno));\n                acutest_exit_(2);\n            }\n            break;\n\n        case 0:\n            if(acutest_lookup_(arg) == 0) {\n                fprintf(stderr, \"%s: Unrecognized unit test '%s'\\n\", acutest_argv0_, arg);\n                fprintf(stderr, \"Try '%s --list' for list of unit tests.\\n\", acutest_argv0_);\n                acutest_exit_(2);\n            }\n            break;\n\n        case ACUTEST_CMDLINE_OPTID_UNKNOWN_:\n            fprintf(stderr, \"Unrecognized command line option '%s'.\\n\", arg);\n            fprintf(stderr, \"Try '%s --help' for more information.\\n\", acutest_argv0_);\n            acutest_exit_(2);\n            break;\n\n        case ACUTEST_CMDLINE_OPTID_MISSINGARG_:\n            fprintf(stderr, \"The command line option '%s' requires an argument.\\n\", arg);\n            fprintf(stderr, \"Try '%s --help' for more information.\\n\", acutest_argv0_);\n            acutest_exit_(2);\n            break;\n\n        case ACUTEST_CMDLINE_OPTID_BOGUSARG_:\n            fprintf(stderr, \"The command line option '%s' does not expect an argument.\\n\", arg);\n            fprintf(stderr, \"Try '%s --help' for more information.\\n\", acutest_argv0_);\n            acutest_exit_(2);\n            break;\n    }\n\n    return 0;\n}\n\n\n#ifdef ACUTEST_LINUX_\nstatic int\nacutest_is_tracer_present_(void)\n{\n    /* Must be large enough so the line 'TracerPid: ${PID}' can fit in. */\n    static const int OVERLAP = 32;\n\n    char buf[512];\n    int tracer_present = 0;\n    int fd;\n    size_t n_read = 0;\n\n    fd = open(\"/proc/self/status\", O_RDONLY);\n    if(fd == -1)\n        return 0;\n\n    while(1) {\n        static const char pattern[] = \"TracerPid:\";\n        const char* field;\n\n        while(n_read < sizeof(buf) - 1) {\n            ssize_t n;\n\n            n = read(fd, buf + n_read, sizeof(buf) - 1 - n_read);\n            if(n <= 0)\n                break;\n            n_read += n;\n        }\n        buf[n_read] = '\\0';\n\n        field = strstr(buf, pattern);\n        if(field != NULL  &&  field < buf + sizeof(buf) - OVERLAP) {\n            pid_t tracer_pid = (pid_t) atoi(field + sizeof(pattern) - 1);\n            tracer_present = (tracer_pid != 0);\n            break;\n        }\n\n        if(n_read == sizeof(buf) - 1) {\n            /* Move the tail with the potentially incomplete line we're looking\n             * for to the beginning of the buffer. */\n            memmove(buf, buf + sizeof(buf) - 1 - OVERLAP, OVERLAP);\n            n_read = OVERLAP;\n        } else {\n            break;\n        }\n    }\n\n    close(fd);\n    return tracer_present;\n}\n#endif\n\n#ifdef ACUTEST_MACOS_\nstatic bool\nacutest_AmIBeingDebugged(void)\n{\n    int junk;\n    int mib[4];\n    struct kinfo_proc info;\n    size_t size;\n\n    // Initialize the flags so that, if sysctl fails for some bizarre\n    // reason, we get a predictable result.\n    info.kp_proc.p_flag = 0;\n\n    // Initialize mib, which tells sysctl the info we want, in this case\n    // we're looking for information about a specific process ID.\n    mib[0] = CTL_KERN;\n    mib[1] = KERN_PROC;\n    mib[2] = KERN_PROC_PID;\n    mib[3] = getpid();\n\n    // Call sysctl.\n    size = sizeof(info);\n    junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);\n    assert(junk == 0);\n\n    // We're being debugged if the P_TRACED flag is set.\n    return ( (info.kp_proc.p_flag & P_TRACED) != 0 );\n}\n#endif\n\nint\nmain(int argc, char** argv)\n{\n    int i;\n\n    acutest_argv0_ = argv[0];\n\n#if defined ACUTEST_UNIX_\n    acutest_colorize_ = isatty(STDOUT_FILENO);\n#elif defined ACUTEST_WIN_\n #if defined _BORLANDC_\n    acutest_colorize_ = isatty(_fileno(stdout));\n #else\n    acutest_colorize_ = _isatty(_fileno(stdout));\n #endif\n#else\n    acutest_colorize_ = 0;\n#endif\n\n    /* Count all test units */\n    acutest_list_size_ = 0;\n    for(i = 0; acutest_list_[i].func != NULL; i++)\n        acutest_list_size_++;\n\n    acutest_test_data_ = (struct acutest_test_data_*)calloc(acutest_list_size_, sizeof(struct acutest_test_data_));\n    if(acutest_test_data_ == NULL) {\n        fprintf(stderr, \"Out of memory.\\n\");\n        acutest_exit_(2);\n    }\n\n    /* Parse options */\n    acutest_cmdline_read_(acutest_cmdline_options_, argc, argv, acutest_cmdline_callback_);\n\n    /* Initialize the proper timer. */\n    acutest_timer_init_();\n\n#if defined(ACUTEST_WIN_)\n    SetUnhandledExceptionFilter(acutest_seh_exception_filter_);\n#ifdef _MSC_VER\n    _set_abort_behavior(0, _WRITE_ABORT_MSG);\n#endif\n#endif\n\n    /* By default, we want to run all tests. */\n    if(acutest_count_ == 0) {\n        for(i = 0; acutest_list_[i].func != NULL; i++)\n            acutest_remember_(i);\n    }\n\n    /* Guess whether we want to run unit tests as child processes. */\n    if(acutest_no_exec_ < 0) {\n        acutest_no_exec_ = 0;\n\n        if(acutest_count_ <= 1) {\n            acutest_no_exec_ = 1;\n        } else {\n#ifdef ACUTEST_WIN_\n            if(IsDebuggerPresent())\n                acutest_no_exec_ = 1;\n#endif\n#ifdef ACUTEST_LINUX_\n            if(acutest_is_tracer_present_())\n                acutest_no_exec_ = 1;\n#endif\n#ifdef ACUTEST_MACOS_\n            if(acutest_AmIBeingDebugged())\n                acutest_no_exec_ = 1;\n#endif\n#ifdef RUNNING_ON_VALGRIND\n            /* RUNNING_ON_VALGRIND is provided by optionally included <valgrind.h> */\n            if(RUNNING_ON_VALGRIND)\n                acutest_no_exec_ = 1;\n#endif\n        }\n    }\n\n    if(acutest_tap_) {\n        /* TAP requires we know test result (\"ok\", \"not ok\") before we output\n         * anything about the test, and this gets problematic for larger verbose\n         * levels. */\n        if(acutest_verbose_level_ > 2)\n            acutest_verbose_level_ = 2;\n\n        /* TAP harness should provide some summary. */\n        acutest_no_summary_ = 1;\n\n        if(!acutest_worker_)\n            printf(\"1..%d\\n\", (int) acutest_count_);\n    }\n\n    int index = acutest_worker_index_;\n    for(i = 0; acutest_list_[i].func != NULL; i++) {\n        int run = (acutest_test_data_[i].flags & ACUTEST_FLAG_RUN_);\n        if (acutest_skip_mode_) /* Run all tests except those listed. */\n            run = !run;\n        if(run)\n            acutest_run_(&acutest_list_[i], index++, i);\n    }\n\n    /* Write a summary */\n    if(!acutest_no_summary_ && acutest_verbose_level_ >= 1) {\n        if(acutest_verbose_level_ >= 3) {\n            acutest_colored_printf_(ACUTEST_COLOR_DEFAULT_INTENSIVE_, \"Summary:\\n\");\n\n            printf(\"  Count of all unit tests:     %4d\\n\", (int) acutest_list_size_);\n            printf(\"  Count of run unit tests:     %4d\\n\", acutest_stat_run_units_);\n            printf(\"  Count of failed unit tests:  %4d\\n\", acutest_stat_failed_units_);\n            printf(\"  Count of skipped unit tests: %4d\\n\", (int) acutest_list_size_ - acutest_stat_run_units_);\n        }\n\n        if(acutest_stat_failed_units_ == 0) {\n            acutest_colored_printf_(ACUTEST_COLOR_GREEN_INTENSIVE_, \"SUCCESS:\");\n            printf(\" All unit tests have passed.\\n\");\n        } else {\n            acutest_colored_printf_(ACUTEST_COLOR_RED_INTENSIVE_, \"FAILED:\");\n            printf(\" %d of %d unit tests %s failed.\\n\",\n                    acutest_stat_failed_units_, acutest_stat_run_units_,\n                    (acutest_stat_failed_units_ == 1) ? \"has\" : \"have\");\n        }\n\n        if(acutest_verbose_level_ >= 3)\n            printf(\"\\n\");\n    }\n\n    if (acutest_xml_output_) {\n#if defined ACUTEST_UNIX_\n        char *suite_name = basename(argv[0]);\n#elif defined ACUTEST_WIN_\n        char suite_name[_MAX_FNAME];\n        _splitpath(argv[0], NULL, NULL, suite_name, NULL);\n#else\n        const char *suite_name = argv[0];\n#endif\n        fprintf(acutest_xml_output_, \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\");\n        fprintf(acutest_xml_output_, \"<testsuite name=\\\"%s\\\" tests=\\\"%d\\\" errors=\\\"%d\\\" failures=\\\"%d\\\" skip=\\\"%d\\\">\\n\",\n            suite_name, (int)acutest_list_size_, acutest_stat_failed_units_, acutest_stat_failed_units_,\n            (int)acutest_list_size_ - acutest_stat_run_units_);\n        for(i = 0; acutest_list_[i].func != NULL; i++) {\n            struct acutest_test_data_ *details = &acutest_test_data_[i];\n            fprintf(acutest_xml_output_, \"  <testcase name=\\\"%s\\\" time=\\\"%.2f\\\">\\n\", acutest_list_[i].name, details->duration);\n            if (details->flags & ACUTEST_FLAG_FAILURE_)\n                fprintf(acutest_xml_output_, \"    <failure />\\n\");\n            if (!(details->flags & ACUTEST_FLAG_FAILURE_) && !(details->flags & ACUTEST_FLAG_SUCCESS_))\n                fprintf(acutest_xml_output_, \"    <skipped />\\n\");\n            fprintf(acutest_xml_output_, \"  </testcase>\\n\");\n        }\n        fprintf(acutest_xml_output_, \"</testsuite>\\n\");\n        fclose(acutest_xml_output_);\n    }\n\n    acutest_cleanup_();\n\n    return (acutest_stat_failed_units_ == 0) ? 0 : 1;\n}\n\n\n#endif  /* #ifndef TEST_NO_MAIN */\n\n#ifdef _MSC_VER\n    #pragma warning(pop)\n#endif\n\n#ifdef __cplusplus\n    }  /* extern \"C\" */\n#endif\n\n#endif  /* #ifndef ACUTEST_H */\n"
  },
  {
    "path": "extra-cmds/optscript-repl.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#include \"general.h\"\n\n#include \"optscript.h\"\n#include \"mio.h\"\n#include \"routines.h\"\n\n#include <string.h>\n#include <stdlib.h>\n\nstatic void\nhelp (const char* progname, int exit_status)\n{\n\tFILE *out = stderr;\n\tif (exit_status == 0)\n\t\tout = stdout;\n\n\tfprintf (out, \"Usage: %s [options] [file|-]\\n\\n\", progname);\n\tfputs   (     \"  -h|--help             Print this option summary\\n\", out);\n\tfputs   (     \"  -l|--list-operators   List built-in operators\\n\", out);\n\tfputs   (     \"  -e|--eval CODE        Evaluate the CODE\\n\", out);\n\tfputc   ('\\n', out);\n\texit (exit_status);\n}\n\nstatic EsObject*\nop_renew (OptVM *vm, EsObject *name)\n{\n\tbool *app_data = opt_vm_get_app_data (vm);\n\t*app_data = true;\n\treturn OPT_ERR_QUIT;\n}\n\nstatic int\noptscript_run (OptVM *vm, char *prompt, void *app_data)\n{\n\tint r = 0;\n\tvoid *old_app_data = opt_vm_set_app_data (vm, app_data);\n\tchar *old_prompt = opt_vm_set_prompt (vm, prompt);\n\n\topt_vm_print_prompt (vm);\n\n\twhile (true)\n\t{\n\t\tEsObject *o = opt_vm_read (vm, NULL);\n\t\tif (es_object_equal (o, ES_READER_EOF))\n\t\t{\n\t\t\tes_object_unref (o);\n\t\t\tbreak;\n\t\t}\n\t\tEsObject *e = opt_vm_eval (vm, o);\n\t\tes_object_unref (o);\n\n\t\tif (es_error_p (e))\n\t\t{\n\t\t\tif (!es_object_equal (e, OPT_ERR_QUIT))\n\t\t\t{\n\t\t\t\topt_vm_report_error (vm, e, NULL);\n\t\t\t\tr = 1;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\topt_vm_set_prompt (vm, old_prompt);\n\topt_vm_set_app_data (vm, old_app_data);\n\treturn r;\n}\n\nint\nmain(int argc, char **argv)\n{\n\tMIO *in = NULL;\n\tconst char *file = NULL;\n\tbool help_ops = false;\n\n\tfor (int i = 1; i < argc; i++)\n\t{\n\t\tif (strcmp (argv[i], \"-h\") == 0\n\t\t\t|| strcmp (argv[i], \"--help\") == 0)\n\t\t\thelp (argv[0], 0);\n\t\telse if (strcmp (argv[i], \"-l\") == 0\n\t\t\t\t || strcmp (argv[i], \"--list-operators\") == 0)\n\t\t\thelp_ops = true;\n\t\telse if (strcmp (argv[i], \"-e\") == 0\n\t\t\t\t || strcmp (argv[i], \"--eval\") == 0)\n\t\t{\n\t\t\tif (file)\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"Don't specify multiple input: %s, %s\\n\",\n\t\t\t\t\t\t file, argv[i]);\n\t\t\t\texit (2);\n\t\t\t}\n\n\t\t\tif (i == argc -1)\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"no code for %s\\n\", argv[i]);\n\t\t\t\texit (2);\n\t\t\t}\n\t\t\tfile = \"<cmdline>\";\n\t\t\ti++;\n\t\t\tin = mio_new_memory ((unsigned char *)eStrdup(argv[i]), strlen (argv[i]), eRealloc, eFree);\n\t\t\tif (!in)\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"failed to create mio from memory\\n\");\n\t\t\t\texit (1);\n\t\t\t}\n\t\t}\n\t\telse if (argv[i][0] == '-' && argv[i][1] == '\\0')\n\t\t{\n\t\t\tif (file)\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"Don't specify multiple input: %s, %s\\n\",\n\t\t\t\t\t\t file, argv[i]);\n\t\t\t\texit (2);\n\t\t\t}\n\n\t\t\tfile = \"<stdin>\";\n\t\t\tin = mio_new_fp (stdin, NULL);\n\t\t\tif (!in)\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"failed to use <stdin>\\n\");\n\t\t\t\texit (1);\n\t\t\t}\n\t\t}\n\t\telse if (argv[i][0] == '-')\n\t\t{\n\t\t\tfprintf (stderr, \"unknown option: %s\\n\", argv[i]);\n\t\t\texit (2);\n\t\t}\n\t\telse if (in)\n\t\t{\n\t\t\tfprintf (stderr, \"too many arugments\\n\");\n\t\t\tmio_unref (in);\n\t\t\texit (2);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (file)\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"Don't specify multiple input: %s, %s\\n\",\n\t\t\t\t\t\t file, argv[i]);\n\t\t\t\texit (2);\n\t\t\t}\n\n\t\t\tfile = argv[i];\n\t\t\tin = mio_new_file (file, \"r\");\n\t\t\tif (!in)\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"failed to open: %s\\n\", file);\n\t\t\t\texit (1);\n\t\t\t}\n\t\t}\n\t}\n\n\topt_init ();\n\n\tif (!in)\n\t\tin = mio_new_fp (stdin, NULL);\n\tif (in == NULL)\n\t{\n\t\tfprintf (stderr, \"failed to open input stream\\n\");\n\t\texit (1);\n\t}\n\n\tMIO *out = mio_new_fp (stdout, NULL);\n\tif (!out)\n\t{\n\t\tmio_unref (in);\n\t\tfprintf (stderr, \"failed to open output stream\\n\");\n\t\texit (1);\n\t}\n\tMIO *err = mio_new_fp (stderr, NULL);\n\tif (!err)\n\t{\n\t\tmio_unref (out);\n\t\tmio_unref (in);\n\t\tfprintf (stderr, \"failed to open error stream\\n\");\n\t\texit (1);\n\t}\n\n\tOptVM *vm = opt_vm_new (in, out, err);\n\n\tint r;\n\n\tEsObject *dict = opt_dict_new (47);\n\t{\n\t\tEsObject *op;\n\t\tEsObject *sym;\n\n\t\top = opt_operator_new (op_renew, \"_renew\", 0, \":clear the state of vm%- _RENEW -\");\n\t\tsym = es_symbol_intern (\"_renew\");\n\t\topt_dict_def (dict, sym, op);\n\t\tes_object_unref (op);\n\t}\n\n\topt_vm_dstack_push (vm, dict);\n\tif (help_ops)\n\t\tr = opt_vm_help (vm, NULL, NULL, NULL);\n\telse\n\t{\n\t\tbool renew = false;\n\trenew:\n\t\tr = optscript_run (vm, file? NULL: \"OPT\", &renew);\n\t\tif (renew)\n\t\t{\n\t\t\topt_vm_clear (vm, true);\n\t\t\topt_vm_dstack_push (vm, dict);\n\t\t\trenew = false;\n\t\t\tgoto renew;\n\t\t}\n\t}\n\tes_object_unref (dict);\n\n\topt_vm_delete (vm);\n\n\tmio_unref (err);\n\tmio_unref (out);\n\tmio_unref (in);\n\n\treturn r;\n}\n"
  },
  {
    "path": "extra-cmds/printtags.c",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   This source code is released into the public domain.\n*\n*   This module contains functions for reading tag files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"printtags.h\"\n\n#include <stdbool.h>\n#include <stdio.h>\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic tagPrintProcs printFILEProcs = {\n\t.printStr = (int  (*) (const char *, void *))fputs,\n\t.printChar = (int  (*) (int, void *))fputc,\n};\n\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void ultostr (char dst [21], unsigned long d)\n{\n\tint o [20];\n\tint i;\n\n\tif (d == 0)\n\t{\n\t\tdst [0] = '0';\n\t\tdst [1] = '\\0';\n\t\treturn;\n\t}\n\n\tfor (i = 0; d != 0; i++, d = d/10)\n\t\to [i] = d % 10;\n\n\tfor (int j = i - 1; j >= 0; j--)\n\t\tdst [i - j - 1] = o[j] + '0';\n\tdst [i] = '\\0';\n}\n\nstatic void printValue (const char *val, bool printingWithEscaping,\n\t\t\t\t\t\tint  (* print_str) (const char *, void *),\n\t\t\t\t\t\tint  (* print_char) (int, void *),\n\t\t\t\t\t\tvoid *outfp)\n{\n\tif (printingWithEscaping)\n\t{\n\t\tfor(; *val != '\\0'; val++)\n\t\t{\n\t\t\tswitch (*val)\n\t\t\t{\n\t\t\t\tcase '\\t': print_str (\"\\\\t\",  outfp); break;\n\t\t\t\tcase '\\r': print_str (\"\\\\r\",  outfp); break;\n\t\t\t\tcase '\\n': print_str (\"\\\\n\",  outfp); break;\n\t\t\t\tcase '\\\\': print_str (\"\\\\\\\\\", outfp); break;\n\t\t\t\t\t/* Universal-CTags extensions */\n\t\t\t\tcase '\\a': print_str (\"\\\\a\", outfp); break;\n\t\t\t\tcase '\\b': print_str (\"\\\\b\", outfp); break;\n\t\t\t\tcase '\\v': print_str (\"\\\\v\", outfp); break;\n\t\t\t\tcase '\\f': print_str (\"\\\\f\", outfp); break;\n\t\t\t\tdefault:\n\t\t\t\t\tif ((0x01 <= *val && *val <= 0x1F) || *val == 0x7F)\n\t\t\t\t\t{\n\t\t\t\t\t\tchar c[5] = {\n\t\t\t\t\t\t\t[0] = '\\\\',\n\t\t\t\t\t\t\t[1] = 'x',\n\t\t\t\t\t\t};\n\t\t\t\t\t\tc [2] = (*val / 16) % 16;\n#if 0\n\t\t\t\t\t\tif (c [2] == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tc [2] = *val % 16;\n\t\t\t\t\t\t\tc [2] += ( c [2] < 10 )? '0': 'A' - 9;\n\t\t\t\t\t\t\tc [3] = '\\0';\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n#endif\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tc [2] += ( c [2] < 10 )? '0': 'A' - 9;\n\t\t\t\t\t\t\tc [3] = *val % 16;\n\t\t\t\t\t\t\tc [3] += ( c [3] < 10 )? '0': 'A' - 9;\n\t\t\t\t\t\t\tc [4] = '\\0';\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprint_str (c, outfp);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tprint_char (*val, outfp);\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t\tprint_str (val, outfp);\n}\n\nextern int tagsPrintValue (const char *val,\n\t\t\t\t\t\t   bool escaping,\n\t\t\t\t\t\t   tagPrintProcs *procs,\n\t\t\t\t\t\t   void *outfp)\n{\n\tif (!procs)\n\t\tprocs = &printFILEProcs;\n\n\tprintValue (val, escaping,\n\t\t\t\tprocs->printStr, procs->printChar,\n\t\t\t\toutfp);\n\treturn 1;\n}\n\nstatic void tagsPrintTag (const tagEntry *entry,\n\t\t\t\t\t\t  bool printingExtensionFields,\n\t\t\t\t\t\t  bool printingLineNumber,\n\t\t\t\t\t\t  bool printingWithEscaping,\n\t\t\t\t\t\t  bool printInputFieldWithEscaping,\n\t\t\t\t\t\t  bool pseudoTag,\n\t\t\t\t\t\t  int  (* print_str) (const char *, void *),\n\t\t\t\t\t\t  int  (* print_char) (int, void *),\n\t\t\t\t\t\t  void *outfp)\n{\n\tint i;\n\tint first = 1;\n\tconst char* separator = \";\\\"\";\n\tconst char* const empty = \"\";\n/* \"sep\" returns a value only the first time it is evaluated */\n#define sep (first ? (first = 0, separator) : empty)\n\n\tif (entry->name == NULL\n\t\t|| entry->file == NULL\n\t\t|| entry->address.pattern == NULL)\n\t\treturn;\n\tif (pseudoTag)\n\t\tprintValue (entry->name, printingWithEscaping,\n\t\t\t\t\tprint_str, print_char, outfp);\n\telse if (*entry->name == '!' && printingWithEscaping)\n\t{\n\t\tprint_str (\"\\\\x21\", outfp);\n\t\tprintValue (entry->name + 1, printingWithEscaping,\n\t\t\t\t\tprint_str, print_char, outfp);\n\t}\n\telse if (*entry->name == ' ' && printingWithEscaping)\n\t{\n\t\tprint_str (\"\\\\x20\", outfp);\n\t\tprintValue (entry->name + 1, printingWithEscaping,\n\t\t\t\t\tprint_str, print_char, outfp);\n\t}\n\telse\n\t\tprintValue (entry->name, printingWithEscaping,\n\t\t\t\t\tprint_str, print_char, outfp);\n\n\tprint_char ('\\t', outfp);\n\tprintValue  (entry->file, printInputFieldWithEscaping,\n\t\t\t\t print_str, print_char, outfp);\n\tprint_char ('\\t', outfp);\n\tprint_str (entry->address.pattern, outfp);\n\n\tif (printingExtensionFields)\n\t{\n\t\tif (entry->kind != NULL  &&  entry->kind [0] != '\\0')\n\t\t{\n\t\t\tprint_str (sep, outfp);\n\t\t\tprint_str (\"\\tkind:\", outfp);\n\t\t\tprintValue (entry->kind, printingWithEscaping,\n\t\t\t\t\t\tprint_str, print_char, outfp);\n\t\t\tfirst = 0;\n\t\t}\n\t\tif (entry->fileScope)\n\t\t{\n\t\t\tprint_str (sep, outfp);\n\t\t\tprint_str (\"\\tfile:\", outfp);\n\t\t\tfirst = 0;\n\t\t}\n\t\tif (printingLineNumber && entry->address.lineNumber > 0)\n\t\t{\n\t\t\tprint_str (sep, outfp);\n\t\t\tprint_str (\"\\tline:\", outfp);\n\t\t\tchar buf [20 + 1];\t/* 20 comes from UINNT64_MAX, 1 is for \\0. */\n\t\t\tultostr (buf, entry->address.lineNumber);\n\t\t\tprint_str (buf, outfp);\n\t\t\tfirst = 0;\n\t\t}\n\t\tfor (i = 0  ;  i < entry->fields.count  ;  ++i)\n\t\t{\n\t\t\tif (entry->fields.list [i].key)\n\t\t\t{\n\t\t\t\tprint_str (sep, outfp);\n\t\t\t\tprint_char ('\\t', outfp);\n\t\t\t\tprint_str (entry->fields.list [i].key, outfp);\n\t\t\t\tprint_char (':', outfp);\n\t\t\t\tif (entry->fields.list  [i].value)\n\t\t\t\t\tprintValue (entry->fields.list [i].value,\n\t\t\t\t\t\t\t\tprintingWithEscaping, print_str, print_char, outfp);\n\t\t\t\tfirst = 0;\n\t\t\t}\n\t\t}\n\t}\n\tprint_char ('\\n', outfp);\n#undef sep\n}\n\nextern int tagsPrint (const tagEntry *entry,\n\t\t\t\t\t  tagPrintOptions *opt, tagPrintProcs *procs, void *outfp)\n{\n\tif (!procs)\n\t\tprocs = &printFILEProcs;\n\n\ttagsPrintTag (entry,\n\t\t\t\t  opt->extensionFields,\n\t\t\t\t  opt->lineNumber,\n\t\t\t\t  opt->escaping,\n\t\t\t\t  opt->escapingInputField,\n\t\t\t\t  false,\n\t\t\t\t  procs->printStr,\n\t\t\t\t  procs->printChar,\n\t\t\t\t  outfp);\n\treturn 1;\t\t\t\t\t/* TODO */\n}\n\nextern int tagsPrintPseudoTag (const tagEntry *entry,\n\t\t\t\t\t\t\t   tagPrintOptions *opt, tagPrintProcs *procs, void *outfp)\n{\n\tif (!procs)\n\t\tprocs = &printFILEProcs;\n\n\ttagsPrintTag (entry,\n\t\t\t\t  opt->extensionFields,\n\t\t\t\t  opt->lineNumber,\n\t\t\t\t  opt->escaping,\n\t\t\t\t  opt->escapingInputField,\n\t\t\t\t  true,\n\t\t\t\t  procs->printStr,\n\t\t\t\t  procs->printChar,\n\t\t\t\t  outfp);\n\treturn 1;\t\t\t\t\t/* TODO */\n}\n"
  },
  {
    "path": "extra-cmds/printtags.h",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   This source code is released for the public domain.\n*\n*   This file defines the public interface for looking up tag entries in tag\n*   files.\n*/\n#ifndef PRINTTAGS_H\n#define PRINTTAGS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n*   INCLUDE FILES\n*/\n#include \"readtags.h\"\n#include <stdbool.h>\n\n/*\n*  DATA DECLARATIONS\n*/\n\ntypedef struct {\n\tint  (* printStr) (const char *, void *);\n\tint  (* printChar) (int, void *);\n} tagPrintProcs;\n\ntypedef struct {\n\tbool extensionFields;\n\tbool lineNumber;\n\tbool escaping;\n\tbool escapingInputField;\n} tagPrintOptions;\n\n/*\n*  FUNCTION PROTOTYPES\n*/\n\n/*\n* Print a tag to the file stream.\n*/\nextern int tagsPrint (const tagEntry *entry,\n\t\t\t\t\t  tagPrintOptions *opts, tagPrintProcs *procs, void *outfp);\nextern int tagsPrintPseudoTag (const tagEntry *entry,\n\t\t\t\t\t\t\t   tagPrintOptions *opts, tagPrintProcs *procs, void *outfp);\n\nextern int tagsPrintValue (const char *val, bool escaping, tagPrintProcs *procs, void *outfp);\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif\t/* PRINTTAGS_H */\n"
  },
  {
    "path": "extra-cmds/readtags-cmd.c",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   This source code is released into the public domain.\n*\n*   This module contains functions for reading tag files.\n*/\n\n#include \"general.h\"\n\n#include \"ctags.h\"\n#include \"readtags.h\"\n#include \"printtags.h\"\n#include \"routines.h\"\n#include \"routines_p.h\"\n\n#include \"vstring.h\"\n#include \"htable.h\"\n#include \"intern.h\"\n#include \"ptrarray.h\"\n#include \"fname.h\"\n\n#include \"dsl/qualifier.h\"\n#include \"dsl/sorter.h\"\n#include \"dsl/formatter.h\"\n\n#include <string.h>\t\t/* strerror */\n#include <stdlib.h>\t\t/* exit */\n#include <stdio.h>\t\t/* stderr */\n#include <stdbool.h>\n\ntypedef struct sReadOption {\n\tbool sortOverride;\n\tsortType sortMethod;\n\t/* options passed to libreadtags API functions.*/\n\tint matchOpts;\n} readOptions;\n\nstruct canonWorkArea {\n\tstruct canonFnameCacheTable *cacheTable;\n};\n\ntypedef struct tagFileX {\n\tconst char *fileName;\n\ttagFile *tagFile;\n\ttagFileInfo info;\n\tstruct canonWorkArea *canon;\n} tagFileX;\n\nstruct inputSpec {\n\tconst char *tagFileName;\n\tchar *tempFileName;\n\tstruct canonWorkArea canon;\n\ttagFileX *fileX;\n};\n\nenum actionType {\n\t\tACTION_NONE,\n\t\tACTION_FIND = 1 << 0,\n\t\tACTION_LIST = 1 << 1,\n\t\tACTION_LIST_PTAGS = 1 << 2,\n\t\tACTION_LIST_PTAGS_WITH_FILTER = 1 << 3,\n};\n\nstruct actionSpec {\n\tunsigned int action;\t\t/* bitset of actionType items */\n\tconst char *name;\t\t\t/* for ACTION_FIND */\n\tbool canonicalizing;\n\tbool absoluteOnly;\n\tptrArray *tagEntryArray;\n\tvoid (* walkerfn) (const tagEntry *, void *);\n\tvoid *dataForWalkerFn;\n\tQCode *qualifier;\n\tSCode *sorter;\n\tFCode *formatter;\n};\n\nstatic const char *ProgramName;\nstatic int debugMode;\n\nstatic const char* tagsStrerror (int err)\n{\n\tif (err > 0)\n\t\treturn strerror (err);\n\telse if (err < 0)\n\t{\n\t\tswitch (err)\n\t\t{\n\t\tcase TagErrnoUnexpectedSortedMethod:\n\t\t\treturn \"Unexpected sorted method\";\n\t\tcase TagErrnoUnexpectedFormat:\n\t\t\treturn \"Unexpected format number\";\n\t\tcase TagErrnoUnexpectedLineno:\n\t\t\treturn \"Unexpected value for line: field\";\n\t\tcase TagErrnoInvalidArgument:\n\t\t\treturn \"Unexpected argument passed to the API function\";\n\t\tdefault:\n\t\t\treturn \"Unknown error\";\n\t\t}\n\t}\n\telse\n\t\treturn \"no error\";\n}\n\nstatic void printTag (const tagEntry *entry, void *data)\n{\n\ttagsPrint (entry, (tagPrintOptions *)data, NULL, stdout);\n}\n\nstatic void printTagWithFormatter (const tagEntry *entry, void *data)\n{\n\tstruct actionSpec *actionSpec = data;\n\tf_print (entry, actionSpec->formatter, stdout);\n}\n\nstatic void printPseudoTag (const tagEntry *entry, void *data)\n{\n\ttagsPrintPseudoTag (entry, (tagPrintOptions *)data, NULL, stdout);\n}\n\nstatic void freeCopiedTag (tagEntry *e)\n{\n\tfree ((void *)e->name);\n\t/* Don't free. The value is interned. */\n\te->file = NULL;\n\tif (e->address.pattern)\n\t\tfree ((void *)e->address.pattern);\n\t/* Don't free. The value is interned. */\n\te->kind = NULL;\n\tfor (unsigned short c = 0; c < e->fields.count; c++)\n\t{\n\t\t/* Don't free. The value is interned. */\n\t\te->fields.list[c].key = NULL;\n\t\tfree ((void *)e->fields.list[c].value);\n\t}\n\tif (e->fields.count)\n\t\tfree ((void *)e->fields.list);\n\tfree ((void *)e);\n}\n\nstatic tagEntry *copyTag (tagEntry *o)\n{\n\ttagEntry *n;\n\n\tn = eCalloc (1, sizeof  (*o));\n\n\tn->name = eStrdup (o->name);\n\n\tif (o->file)\n\t\tn->file = intern (o->file);\n\n\tif (o->address.pattern)\n\t\tn->address.pattern = eStrdup (o->address.pattern);\n\n\tn->address.lineNumber = o->address.lineNumber;\n\n\tif (o->kind)\n\t\tn->kind = intern (o->kind);\n\n\tn->fileScope = o->fileScope;\n\tn->fields.count = o->fields.count;\n\n\tif (o->fields.count == 0)\n\t\treturn n;\n\n\tn->fields.list = eMalloc (o->fields.count * sizeof (*o->fields.list));\n\n\tfor (unsigned short c = 0; c < o->fields.count; c++)\n\t{\n\t\tn->fields.list[c].key = intern (o->fields.list[c].key);\n\t\tn->fields.list[c].value = eStrdup (o->fields.list[c].value);\n\t}\n\n\treturn n;\n}\n\nstatic int compareTagEntry (const void *a, const void *b, void *sorter)\n{\n\treturn s_compare (a, b, sorter);\n}\n\nstatic const char *canonicalizeFileNameX(tagFileX *const filex, const char *input)\n{\n\treturn canonicalizeFileName (filex->canon->cacheTable, input);\n}\n\nstatic void walkTags (tagFileX *const filex, tagEntry *first_entry, bool on_ptags,\n\t\t\t\t\t  tagResult (* nextfn) (tagFile *const, tagEntry *),\n\t\t\t\t\t  void (* actionfn) (const tagEntry *, void *), void *data,\n\t\t\t\t\t  struct actionSpec *actionSpec)\n{\n\ttagFile *const file = filex->tagFile;\n\tptrArray *a = actionSpec->tagEntryArray;\n\n\tdo\n\t{\n\t\ttagEntry *shadow = first_entry;\n\t\ttagEntry  shadowRec;\n\t\tif (actionSpec->canonicalizing\n\t\t\t&& (on_ptags == false\n\t\t\t\t|| strcmp (first_entry->name, \"!_TAG_PROC_CWD\") == 0))\n\t\t{\n\t\t\tshadowRec = *first_entry;\n\t\t\tshadow = &shadowRec;\n\t\t\tshadow->file = canonicalizeFileNameX (filex, first_entry->file);\n\t\t}\n\n\t\tif (actionSpec->qualifier)\n\t\t{\n\t\t\tint i = q_is_acceptable (actionSpec->qualifier, shadow);\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\tcase Q_REJECT:\n\t\t\t\tcontinue;\n\t\t\tcase Q_ERROR:\n\t\t\t\texit (1);\n\t\t\t}\n\t\t}\n\n\t\tif (a)\n\t\t{\n\t\t\ttagEntry *e = copyTag (shadow);\n\t\t\tptrArrayAdd (a, e);\n\t\t}\n\t\telse\n\t\t\t(* actionfn) (shadow, data);\n\t} while ( (*nextfn) (file, first_entry) == TagSuccess);\n\n\tint err = tagsGetErrno (file);\n\tif (err != 0)\n\t{\n\t\tfprintf (stderr, \"%s: error in walkTags(): %s\\n\",\n\t\t\t\t ProgramName,\n\t\t\t\t tagsStrerror (err));\n\t\texit (1);\n\t}\n\n\tif (a)\n\t{\n\t\tactionSpec->walkerfn = actionfn;\n\t\tactionSpec->dataForWalkerFn = data;\n\t}\n}\n\nstatic int copyFile (FILE *in, FILE *out)\n{\n#define BUFSIZE (4096 * 10)\n\tstatic unsigned char buffer [BUFSIZE];\n\n\twhile (1)\n\t{\n\t\tsize_t r, t;\n\n\t\tr = fread (buffer, 1, BUFSIZE, in);\n\t\tif (!r)\n\t\t{\n\t\t\tif (ferror(in))\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"%s: error in reading from stdin\\n\", ProgramName);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\t/* EOF */\n\t\t\tbreak;\n\t\t}\n\t\tt = fwrite (buffer, 1, r, out);\n\t\tif (r != t)\n\t\t{\n\t\t\tfprintf (stderr, \"%s error in writing to the temporarily file\", ProgramName);\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nstatic const char *loadCtagsCWD (tagFileX *const fileX, tagEntry *pentry)\n{\n\tif (tagsFindPseudoTag (fileX->tagFile, pentry, \"!_TAG_PROC_CWD\",\n\t\t\t\t\t\t   TAG_FULLMATCH) != TagSuccess)\n\t{\n\t\tint err = tagsGetErrno (fileX->tagFile);\n\t\tif (!err)\n\t\t{\n\t\t\tfprintf (stderr, \"%s: no !_TAG_PROC_CWD in %s\\n\",\n\t\t\t\t\t ProgramName, fileX->fileName);\n\t\t\texit (1);\n\t\t}\n\n\t\tfprintf (stderr, \"%s: cannot find !_TAG_PROC_CWD in %s: %s\\n\",\n\t\t\t\t ProgramName, fileX->fileName, tagsStrerror (err));\n\t\texit (1);\n\t}\n\n\tif (pentry->file[0] != '/')\n\t{\n\t\tfputs (\"!_TAG_PROC_CWD must start with '/': \", stderr);\n\t\ttagsPrintValue (pentry->file, true, NULL, stderr);\n\t\tfputc ('\\n', stderr);\n\t\texit (1);\n\t}\n\n\treturn pentry->file;\n}\n\nstatic struct canonFnameCacheTable *makeCanonFnameCacheTable (tagFileX *const fileX,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  bool absoluteOnly)\n{\n\ttagEntry pentry;\n\tconst char *cwd = loadCtagsCWD (fileX, &pentry);\n\treturn canonFnameCacheTableNew (cwd, absoluteOnly);\n}\n\nstatic tagFileX *makeTagFileX (const char *const filePath)\n{\n\ttagFileX *fileX = eMalloc (sizeof (*fileX));\n\tfileX->fileName = eStrdup(filePath);\n\tfileX->tagFile = NULL;\n\tfileX->info = (tagFileInfo){0};\n\tfileX->canon = NULL;\n\treturn fileX;\n}\n\nstatic void deleteTagFileX (tagFileX *fileX)\n{\n\teFree ((void *)fileX->fileName);\n\tif (fileX->tagFile)\n\t\ttagsClose (fileX->tagFile);\n\teFree (fileX);\n\n}\n\nstatic tagFileX *openTagFileX  (tagFileX *fileX)\n{\n\tfileX->tagFile = tagsOpen (fileX->fileName, &fileX->info);\n\treturn fileX;\n}\n\nstatic tagFileX *openTags (struct inputSpec *inputSpec)\n{\n\ttagFileX *fileX;\n\n\tif (inputSpec->tempFileName)\n\t\tfileX = makeTagFileX(inputSpec->tempFileName);\n\telse if (strcmp (inputSpec->tagFileName, \"-\") == 0)\n\t{\n\t\tchar *tempName = NULL;\n\t\tFILE *tempFP = tempFileFP (\"w\", &tempName);\n\n\t\tif (tempFP == NULL)\n\t\t{\n\t\t\tfprintf (stderr, \"%s: failed to make a temporarily file for storing data from stdin\\n\",\n\t\t\t\t\t ProgramName);\n\t\t\texit (1);\n\t\t}\n\n\t\tfileX = makeTagFileX(tempName);\n\t\tinputSpec->tempFileName = tempName; /* Move the ownership. */\n\t\ttempName = NULL;\t\t\t\t\t/* Don't touch this anymore. */\n\n\t\tif (copyFile (stdin, tempFP) < 0)\n\t\t{\n\t\t\tdeleteTagFileX (fileX);\n\t\t\tfclose (tempFP);\n\t\t\texit (1);\n\t\t}\n\n\t\tif (fflush (tempFP) < 0)\n\t\t{\n\t\t\tfprintf (stderr, \"%s: failed to flush a temporarily file for storing data from stdin\\n\",\n\t\t\t\t\t ProgramName);\n\t\t\tdeleteTagFileX (fileX);\n\t\t\tfclose (tempFP);\n\t\t\texit (1);\n\t\t}\n\n\t\tfclose (tempFP);\n\t}\n\telse\n\t\tfileX = makeTagFileX(inputSpec->tagFileName);\n\n\treturn openTagFileX (fileX);\n}\n\nstatic int hasPsuedoTag (tagFile *const file,\n\t\t\t\t\t\t const char *const ptag, const char *const exepectedValueAsInputField)\n{\n\ttagEntry entry;\n\n\treturn ((tagsFindPseudoTag (file, &entry,\n\t\t\t\t\t\t\t\tptag, TAG_FULLMATCH) == TagSuccess)\n\t\t\t&& (strcmp(entry.file, exepectedValueAsInputField) == 0));\n}\n\nstruct canonWorkArea *prepareCanonFnameCacheTable (struct canonWorkArea *canon,\n\t\t\t\t\t\t\t\t\t\t\t\t   tagFileX *const fileX,\n\t\t\t\t\t\t\t\t\t\t\t\t   bool absoluteOnly)\n{\n\tif (canon->cacheTable == NULL)\n\t\tcanon->cacheTable = makeCanonFnameCacheTable (fileX, absoluteOnly);\n\n\treturn canon;\n}\n\nstatic void dropCanonFnameCacheTableMaybe (struct canonWorkArea *canon)\n{\n\tif (canon->cacheTable)\n\t{\n\t\tcanonFnameCacheTableDelete (canon->cacheTable);\n\t\tcanon->cacheTable = NULL;\n\t}\n}\n\nstatic void findTag (struct inputSpec *inputSpec,\n\t\t\t\t\t const char *const name, readOptions *readOpts,\n\t\t\t\t\t tagPrintOptions *printOpts, struct actionSpec *actionSpec)\n{\n\ttagEntry entry;\n\tint err = 0;\n\ttagFileX *const fileX = inputSpec->fileX;\n\n\tif (actionSpec->canonicalizing)\n\t\tfileX->canon = prepareCanonFnameCacheTable (&inputSpec->canon,\n\t\t\t\t\t\t\t\t\t\t\t\t\tfileX, actionSpec->absoluteOnly);\n\n\tif (printOpts->escaping)\n\t{\n\t\tprintOpts->escapingInputField = false;\n\t\tif (hasPsuedoTag (fileX->tagFile, \"!_TAG_OUTPUT_MODE\", \"u-ctags\")\n\t\t\t&& hasPsuedoTag (fileX->tagFile, \"!_TAG_OUTPUT_FILESEP\", \"slash\"))\n\t\t\tprintOpts->escapingInputField = true;\n\t}\n\n\tif (readOpts->sortOverride)\n\t{\n\t\tif (tagsSetSortType (fileX->tagFile, readOpts->sortMethod) != TagSuccess)\n\t\t{\n\t\t\terr = tagsGetErrno (fileX->tagFile);\n\t\t\tfprintf (stderr, \"%s: cannot set sort type to %d: %s\\n\",\n\t\t\t\t\t ProgramName,\n\t\t\t\t\t readOpts->sortMethod,\n\t\t\t\t\t tagsStrerror (err));\n\t\t\texit (1);\n\t\t}\n\t}\n\tif (debugMode)\n\t\tfprintf (stderr, \"%s: searching for \\\"%s\\\" in \\\"%s\\\"\\n\",\n\t\t\t\t\t ProgramName, name, fileX->fileName);\n\tif (tagsFind (fileX->tagFile, &entry, name, readOpts->matchOpts) == TagSuccess)\n\t\twalkTags (fileX, &entry, false, tagsFindNext,\n\t\t\t\t  actionSpec->formatter? printTagWithFormatter: printTag,\n\t\t\t\t  actionSpec->formatter? (void *)actionSpec: (void *)printOpts,\n\t\t\t\t  actionSpec);\n\telse if ((err = tagsGetErrno (fileX->tagFile)) != 0)\n\t{\n\t\tfprintf (stderr, \"%s: error in tagsFind(): %s\\n\",\n\t\t\t\t ProgramName,\n\t\t\t\t tagsStrerror (err));\n\t\texit (1);\n\t}\n}\n\nstatic void listTags (struct inputSpec* inputSpec, bool pseudoTags, tagPrintOptions *printOpts,\n\t\t\t\t\t  struct actionSpec *actionSpec)\n{\n\ttagEntry entry;\n\tint err = 0;\n\ttagFileX *const fileX = inputSpec->fileX;\n\n\tif (actionSpec->canonicalizing)\n\t\tfileX->canon = prepareCanonFnameCacheTable (&inputSpec->canon,\n\t\t\t\t\t\t\t\t\t\t\t\t\tfileX, actionSpec->absoluteOnly);\n\n\tif (printOpts->escaping)\n\t{\n\t\tprintOpts->escapingInputField = false;\n\t\tif (hasPsuedoTag (fileX->tagFile, \"!_TAG_OUTPUT_MODE\", \"u-ctags\")\n\t\t\t&& hasPsuedoTag (fileX->tagFile, \"!_TAG_OUTPUT_FILESEP\", \"slash\"))\n\t\t\tprintOpts->escapingInputField = true;\n\t}\n\n\tif (pseudoTags)\n\t{\n\t\tQCode *qualifier = actionSpec->qualifier;\n\t\tif (!(actionSpec->action & ACTION_LIST_PTAGS_WITH_FILTER))\n\t\t\tactionSpec->qualifier = NULL;\n\n\t\tif (tagsFirstPseudoTag (fileX->tagFile, &entry) == TagSuccess)\n\t\t\twalkTags (fileX, &entry, true, tagsNextPseudoTag,\n\t\t\t\t\t  actionSpec->formatter? printTagWithFormatter: printPseudoTag,\n\t\t\t\t\t  actionSpec->formatter? (void *)actionSpec: (void *)printOpts,\n\t\t\t\t\t  actionSpec);\n\t\telse if ((err = tagsGetErrno (fileX->tagFile)) != 0)\n\t\t{\n\t\t\tfprintf (stderr, \"%s: error in tagsFirstPseudoTag(): %s\\n\",\n\t\t\t\t\t ProgramName,\n\t\t\t\t\t tagsStrerror (err));\n\t\t\texit (1);\n\t\t}\n\n\t\tif (!(actionSpec->action & ACTION_LIST_PTAGS_WITH_FILTER))\n\t\t\tactionSpec->qualifier = qualifier;\n\t}\n\telse\n\t{\n\t\tif (tagsFirst (fileX->tagFile, &entry) == TagSuccess)\n\t\t\twalkTags (fileX, &entry, false, tagsNext,\n\t\t\t\t\t  actionSpec->formatter? printTagWithFormatter: printTag,\n\t\t\t\t\t  actionSpec->formatter? (void *)actionSpec: (void *)printOpts,\n\t\t\t\t\t  actionSpec);\n\t\telse if ((err = tagsGetErrno (fileX->tagFile)) != 0)\n\t\t{\n\t\t\tfprintf (stderr, \"%s: error in tagsFirst(): %s\\n\",\n\t\t\t\t\t ProgramName,\n\t\t\t\t\t tagsStrerror (err));\n\t\t\texit (1);\n\t\t}\n\t}\n}\n\nstatic const char *const Usage =\n\t\"Find tag file entries matching specified names.\\n\\n\"\n\t\"Usage: \\n\"\n\t\"    %s -h | --help\\n\"\n\t\"        Print this help message.\\n\"\n\t\"    %s -H POSTPROCESSOR | --help-expression POSTPROCESSOR\\n\"\n\t\"        Print available terms that can be used in POSTPROCESSOR expression.\\n\"\n\t\"        POSTPROCESSOR: filter sorter formatter\\n\"\n\t\"    %s -v | --version\\n\"\n\t\"        Print the version identifier.\\n\"\n\t\"    %s [OPTIONS] ACTION\\n\"\n\t\"        Do the specified action.\\n\"\n\t\"Actions:\\n\"\n\t\"    -l | --list\\n\"\n\t\"        List regular tags.\\n\"\n\t\"    [-] NAME...\\n\"\n\t\"        List regular tags matching NAME(s).\\n\"\n\t\"        \\\"-\\\" indicates arguments after this as NAME(s) even if they start with -.\\n\"\n\t\"    -D | --list-pseudo-tags\\n\"\n\t\"        List pseudo tags.\\n\"\n\t\"Options:\\n\"\n\t\"    -d | --debug\\n\"\n\t\"        Turn on debugging output.\\n\"\n\t\"    -E | --escape-output\\n\"\n\t\"        Escape characters like tabs in output as described in tags(5).\\n\"\n\t\"    -e | --extension-fields\\n\"\n\t\"        Include extension fields in output.\\n\"\n\t\"    -i | --icase-match\\n\"\n\t\"        Perform case-insensitive matching in the NAME action.\\n\"\n\t\"    -n | --line-number\\n\"\n\t\"        Also include the line number field when -e option is given.\\n\"\n\t\"    -p | --prefix-match\\n\"\n\t\"        Perform prefix matching in the NAME action.\\n\"\n\t\"    -P | --with-pseudo-tags\\n\"\n\t\"        List pseudo tags as if -D option is specified but continues processing without exiting.\\n\"\n\t\"    -t TAGFILE | --tag-file TAGFILE\\n\"\n\t\"        Use specified tag file (default: \\\"tags\\\").\\n\"\n\t\"        \\\"-\\\" indicates taking tag file data from standard input.\\n\"\n\t\"    -s[0|1|2] | --override-sort-detection METHOD\\n\"\n\t\"        Override sort detection of tag file.\\n\"\n\t\"        METHOD: unsorted|sorted|foldcase\\n\"\n\t\"    -C | --canonicalize-input\\n\"\n\t\"        Reduct '..' and '.' in input fields.\\n\"\n\t\"    -A | --absolute-input\\n\"\n\t\"        Do the same as -C but use absolute path form\\n\"\n\t\"    -F EXP | --formatter EXP\\n\"\n\t\"        Format the tags listed by ACTION with EXP when printing.\\n\"\n\t\"    -Q EXP | --filter EXP\\n\"\n\t\"        Filter the tags listed by ACTION with EXP before printing.\\n\"\n\t\"    -S EXP | --sorter EXP\\n\"\n\t\"        Sort the tags listed by ACTION with EXP before printing.\\n\"\n\t;\n\nstatic void printUsage(FILE* stream, int exitCode)\n{\n\tfprintf (stream, Usage, ProgramName,\n\t\t\t ProgramName,\n\t\t\t ProgramName,\n\t\t\t ProgramName);\n\texit (exitCode);\n}\n\nstatic void printFilterExpression (FILE *stream, int exitCode)\n{\n\tfprintf (stream, \"Filter expression: \\n\");\n\tq_help (stream);\n\texit (exitCode);\n}\n\nstatic void printSorterExpression (FILE *stream, int exitCode)\n{\n\tfprintf (stream, \"Sorter expression: \\n\");\n\ts_help (stream);\n\texit (exitCode);\n}\n\nstatic void printFormatterExpression (FILE *stream, int exitCode)\n{\n\tfprintf (stream, \"Formatter expression: \\n\");\n\tf_help (stream);\n\texit (exitCode);\n}\n\nstatic void *compileExpression(const char* exp, void * (*compiler) (EsObject *),\n\t\t\t\t\t\t\t   const char *compiler_name)\n{\n\tconst char *rest = NULL;\n\tEsObject *sexp = es_read_from_string (exp, &rest);\n\tvoid *code;\n\n\tif (es_error_p (sexp))\n\t{\n\t\tfprintf (stderr,\n\t\t\t\t \"Failed to read the expression for %s: %s\\n\", compiler_name, exp);\n\t\tfprintf (stderr,\n\t\t\t\t \"Reason: %s\\n\", es_error_name (sexp));\n\t\texit (1);\n\t}\n\n\tif (rest && *rest != '\\0')\n\t{\n\t\tEsObject *tmp = es_read_from_string (rest, NULL);\n\t\tif (!es_object_equal (tmp, ES_READER_EOF))\n\t\t{\n\t\t\tfprintf (stderr,\n\t\t\t\t\t \"Garbage at the end of the %s expression: %s\\n\",\n\t\t\t\t\t compiler_name, rest);\n\t\t\texit (1);\n\t\t}\n\t\tes_object_unref (tmp);\n\t}\n\n\tcode = compiler (sexp);\n\tif (code == NULL)\n\t{\n\t\tfprintf (stderr,\n\t\t\t\t \"Failed to compile the expression of %s: %s\\n\", compiler_name, exp);\n\t\texit (1);\n\t}\n\tes_object_unref (sexp);\n\treturn code;\n}\n\nstatic tagFileX *openTagsX (struct inputSpec *inputSpec)\n{\n\ttagFileX *const fileX = openTags (inputSpec);\n\n\tif (fileX->tagFile == NULL || !fileX->info.status.opened)\n\t{\n\t\tfprintf (stderr, \"%s: cannot open tag file: %s: %s\\n\",\n\t\t\t\t ProgramName, tagsStrerror (fileX->info.status.error_number),\n\t\t\t\t fileX->fileName);\n\t\tdeleteTagFileX (fileX);\n\t\texit (1);\n\t}\n\treturn fileX;\n}\n\nstatic void run (struct actionSpec *actionSpec, struct inputSpec *inputSpec,\n\t\t\t\t readOptions *readOpts, tagPrintOptions *printOpts)\n{\n\tif (actionSpec->sorter)\n\t\tactionSpec->tagEntryArray = ptrArrayNew ((ptrArrayDeleteFunc)freeCopiedTag);\n\n\tinputSpec->fileX = openTagsX (inputSpec);\n\tif (actionSpec->action & ACTION_LIST_PTAGS)\n\t\tlistTags (inputSpec, true, printOpts, actionSpec);\n\n\tif (actionSpec->action & ACTION_FIND)\n\t\tfindTag (inputSpec, actionSpec->name, readOpts, printOpts, actionSpec);\n\telse if (actionSpec->action & ACTION_LIST)\n\t\tlistTags (inputSpec, false, printOpts, actionSpec);\n\n\tif (actionSpec->tagEntryArray)\n\t{\n\t\tif (actionSpec->sorter)\n\t\t\tptrArraySortR (actionSpec->tagEntryArray, compareTagEntry, actionSpec->sorter);\n\n\t\tconst size_t entry_count = ptrArrayCount(actionSpec->tagEntryArray);\n\t\tfor (unsigned int i = 0; i < entry_count; i++)\n\t\t{\n\t\t\ttagEntry *e = ptrArrayItem (actionSpec->tagEntryArray, i);\n\t\t\tactionSpec->walkerfn (e, actionSpec->dataForWalkerFn);\n\t\t}\n\t\tptrArrayDelete (actionSpec->tagEntryArray);\n\t}\n}\n\nstatic void initActionSpec (struct actionSpec *actionSpec)\n{\n\t*actionSpec = (struct actionSpec) {\n\t\t.action  = ACTION_NONE,\n\t\t.name = NULL,\n\t\t.canonicalizing = false,\n\t\t.tagEntryArray = NULL,\n\t\t.walkerfn = NULL,\n\t\t.dataForWalkerFn = NULL,\n\t\t.qualifier = NULL,\n\t\t.sorter = NULL,\n\t\t.formatter = NULL,\n\t};\n}\n\nstatic void finiActionSpec (struct actionSpec *actionSpec)\n{\n\tif (actionSpec->qualifier)\n\t\tq_destroy (actionSpec->qualifier);\n\tif (actionSpec->sorter)\n\t\ts_destroy (actionSpec->sorter);\n\tif (actionSpec->formatter)\n\t\tf_destroy (actionSpec->formatter);\n}\n\nstatic void initCanonWorkArea (struct canonWorkArea *canon)\n{\n\tcanon->cacheTable = NULL;\n}\n\nstatic void initInputSpec (struct inputSpec *inputSpec)\n{\n\t*inputSpec = (struct inputSpec) {\n\t\t.tagFileName = \"tags\",\n\t\t.tempFileName = NULL,\n\t\t.fileX = NULL,\n\t};\n\tinitCanonWorkArea (&inputSpec->canon);\n}\n\nstatic void finiInputSpec (struct inputSpec *inputSpec)\n{\n\tif (inputSpec->fileX)\n\t\tdeleteTagFileX (inputSpec->fileX);\n\n\tif (inputSpec->tempFileName)\n\t{\n\t\tremove (inputSpec->tempFileName);\n\t\teFree (inputSpec->tempFileName);\n\t}\n\n\tdropCanonFnameCacheTableMaybe (&inputSpec->canon);\n}\n\nstatic void printVersion(void)\n{\n\t/* readtags uses code of ctags via libutil.\n\t * So we here use the versoin of ctags as the version of readtags. */\n\tputs(PROGRAM_VERSION);\n\texit (0);\n}\n\nstatic void parseOptions (int argc, char **argv,\n\t\t\t\t\t\t  struct actionSpec *actionSpec, struct inputSpec *inputSpec,\n\t\t\t\t\t\t  readOptions *readOpts, tagPrintOptions *printOpts)\n{\n\tbool ignore_prefix = false;\n\n\tfor (int i = 1  ;  i < argc  ;  ++i)\n\t{\n\t\tconst char *const arg = argv [i];\n\t\tif (ignore_prefix || arg [0] != '-')\n\t\t{\n\t\t\tactionSpec->action |= ACTION_FIND;\n\t\t\tactionSpec->name = arg;\n\t\t}\n\t\telse if (arg [0] == '-' && arg [1] == '\\0')\n\t\t\tignore_prefix = true;\n\t\telse if (arg [0] == '-' && arg [1] == '-')\n\t\t{\n\t\t\tconst char *optname = arg + 2;\n\t\t\tif (strcmp (optname, \"debug\") == 0)\n\t\t\t\tdebugMode++;\n\t\t\telse if (strcmp (optname, \"list-pseudo-tags\") == 0\n\t\t\t\t\t || strcmp (optname, \"with-pseudo-tags\") == 0)\n\t\t\t{\n\t\t\t\tactionSpec->action |= ACTION_LIST_PTAGS;\n\t\t\t\tif (optname[0] == 'l')\n\t\t\t\t\tactionSpec->action |= ACTION_LIST_PTAGS_WITH_FILTER;\n\t\t\t}\n\t\t\telse if (strcmp (optname, \"help\") == 0)\n\t\t\t\tprintUsage (stdout, 0);\n\t\t\telse if (strcmp (optname, \"help-expression\") == 0)\n\t\t\t{\n\t\t\t\tif (i + 1 < argc)\n\t\t\t\t{\n\t\t\t\t\tconst char *exp_klass = argv [++i];\n\t\t\t\t\tif (strcmp (exp_klass, \"filter\") == 0)\n\t\t\t\t\t\tprintFilterExpression (stdout, 0);\n\t\t\t\t\tif (strcmp (exp_klass, \"sorter\") == 0)\n\t\t\t\t\t\tprintSorterExpression (stdout, 0);\n\t\t\t\t\tif (strcmp (exp_klass, \"formatter\") == 0)\n\t\t\t\t\t\tprintFormatterExpression (stdout, 0);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfprintf (stderr, \"%s: unknown expression class for --%s option\\n\",\n\t\t\t\t\t\t\t\t ProgramName, optname);\n\t\t\t\t\t\texit (1);\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfprintf (stderr, \"%s: missing expression class for --%s option\\n\",\n\t\t\t\t\t\t\t ProgramName, optname);\n\t\t\t\t\texit (1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (strcmp (optname, \"version\") == 0)\n\t\t\t\tprintVersion ();\n\t\t\telse if (strcmp (optname, \"escape-output\") == 0)\n\t\t\t\tprintOpts->escaping = true;\n\t\t\telse if (strcmp (optname, \"extension-fields\") == 0)\n\t\t\t\tprintOpts->extensionFields = true;\n\t\t\telse if (strcmp (optname, \"icase-match\") == 0)\n\t\t\t\treadOpts->matchOpts |= TAG_IGNORECASE;\n\t\t\telse if (strcmp (optname, \"prefix-match\") == 0)\n\t\t\t\treadOpts->matchOpts |= TAG_PARTIALMATCH;\n\t\t\telse if (strcmp (optname, \"list\") == 0)\n\t\t\t\tactionSpec->action |= ACTION_LIST;\n\t\t\telse if (strcmp (optname, \"line-number\") == 0)\n\t\t\t\tprintOpts->lineNumber = true;\n\t\t\telse if (strcmp (optname, \"tag-file\") == 0)\n\t\t\t{\n\t\t\t\tif (i + 1 < argc)\n\t\t\t\t\tinputSpec->tagFileName = argv [++i];\n\t\t\t\telse\n\t\t\t\t\tprintUsage (stderr, 1);\n\t\t\t}\n\t\t\telse if (strcmp (optname, \"override-sort-detection\") == 0)\n\t\t\t{\n\t\t\t\tif (i + 1 < argc)\n\t\t\t\t{\n\t\t\t\t\tconst char *sort_spec = argv [++i];\n\t\t\t\t\tif (strcmp (sort_spec, \"0\") == 0\n\t\t\t\t\t\t|| strcmp (sort_spec, \"unsorted\") == 0)\n\t\t\t\t\t\treadOpts->sortMethod = TAG_UNSORTED;\n\t\t\t\t\telse if (strcmp (sort_spec, \"1\") == 0\n\t\t\t\t\t\t\t || strcmp (sort_spec, \"sorted\") == 0)\n\t\t\t\t\t\treadOpts->sortMethod = TAG_SORTED;\n\t\t\t\t\telse if (strcmp (sort_spec, \"2\") == 0\n\t\t\t\t\t\t\t || strcmp (sort_spec, \"foldcase\") == 0)\n\t\t\t\t\t\treadOpts->sortMethod = TAG_FOLDSORTED;\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfprintf (stderr, \"%s: unknown sort method for --%s option\\n\",\n\t\t\t\t\t\t\t\t ProgramName, optname);\n\t\t\t\t\t\texit (1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfprintf (stderr, \"%s: missing sort method for --%s option\\n\",\n\t\t\t\t\t\t\t ProgramName, optname);\n\t\t\t\t\texit (1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (strcmp (optname, \"absolute-input\") == 0)\n\t\t\t{\n\t\t\t\tactionSpec->canonicalizing = true;\n\t\t\t\tactionSpec->absoluteOnly = true;\n\t\t\t}\n\t\t\telse if (strcmp (optname, \"canonicalize-input\") == 0)\n\t\t\t{\n\t\t\t\tactionSpec->canonicalizing = true;\n\t\t\t\tactionSpec->absoluteOnly = false;\n\t\t\t}\n\t\t\telse if (strcmp (optname, \"filter\") == 0)\n\t\t\t{\n\t\t\t\tif (i + 1 < argc)\n\t\t\t\t\tactionSpec->qualifier = compileExpression (argv[++i],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   (void * (*)(EsObject *))q_compile,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   optname);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfprintf (stderr, \"%s: missing filter expression for --%s option\\n\",\n\t\t\t\t\t\t\t ProgramName, optname);\n\t\t\t\t\texit (1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (strcmp (optname, \"sorter\") == 0)\n\t\t\t{\n\t\t\t\tif (i + 1 < argc)\n\t\t\t\t\tactionSpec->sorter = compileExpression (argv[++i],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(void * (*)(EsObject *))s_compile,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\toptname);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfprintf (stderr, \"%s: missing sorter expression for --%s option\\n\",\n\t\t\t\t\t\t\t ProgramName, optname);\n\t\t\t\t\texit (1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (strcmp (optname, \"formatter\") == 0)\n\t\t\t{\n\t\t\t\tif (i + 1 < argc)\n\t\t\t\t\tactionSpec->formatter = compileExpression (argv[++i],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   (void * (*)(EsObject *))f_compile,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   optname);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfprintf (stderr, \"%s: missing formatter expression for --%s option\\n\",\n\t\t\t\t\t\t\t ProgramName, optname);\n\t\t\t\t\texit (1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"%s: unknown long options: --%s\\n\",\n\t\t\t\t\t\t ProgramName, optname);\n\t\t\t\texit (1);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsize_t j;\n\t\t\tfor (j = 1  ;  arg [j] != '\\0'  ;  ++j)\n\t\t\t{\n\t\t\t\tswitch (arg [j])\n\t\t\t\t{\n\t\t\t\tcase 'd': debugMode++; break;\n\t\t\t\tcase 'D':\n\t\t\t\t\tactionSpec->action |= ACTION_LIST_PTAGS_WITH_FILTER;\n\t\t\t\t\t/* fall through */\n\t\t\t\tcase 'P':\n\t\t\t\t\tactionSpec->action |= ACTION_LIST_PTAGS;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'h': printUsage (stdout, 0); break;\n\t\t\t\tcase 'H':\n\t\t\t\t\tif (i + 1 < argc)\n\t\t\t\t\t{\n\t\t\t\t\t\tconst char *exp_klass = argv [++i];\n\t\t\t\t\t\tif (strcmp (exp_klass, \"filter\") == 0)\n\t\t\t\t\t\t\tprintFilterExpression (stdout, 0);\n\t\t\t\t\t\telse if (strcmp (exp_klass, \"sorter\") == 0)\n\t\t\t\t\t\t\tprintSorterExpression (stdout, 0);\n\t\t\t\t\t\telse if (strcmp (exp_klass, \"formatter\") == 0)\n\t\t\t\t\t\t\tprintFormatterExpression (stdout, 0);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tprintUsage(stderr, 1);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tprintUsage(stderr, 1);\n\t\t\t\tcase 'v': printVersion ();\n\t\t\t\tcase 'E': printOpts->escaping = true; break;\n\t\t\t\tcase 'e': printOpts->extensionFields = true; break;\n\t\t\t\tcase 'i': readOpts->matchOpts |= TAG_IGNORECASE;   break;\n\t\t\t\tcase 'p': readOpts->matchOpts |= TAG_PARTIALMATCH; break;\n\t\t\t\tcase 'l':\n\t\t\t\t\tactionSpec->action |= ACTION_LIST;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'n': printOpts->lineNumber = true; break;\n\t\t\t\tcase 't':\n\t\t\t\t\tif (arg [j+1] != '\\0')\n\t\t\t\t\t{\n\t\t\t\t\t\tinputSpec->tagFileName = arg + j + 1;\n\t\t\t\t\t\tj += strlen (inputSpec->tagFileName);\n\t\t\t\t\t}\n\t\t\t\t\telse if (i + 1 < argc)\n\t\t\t\t\t\tinputSpec->tagFileName = argv [++i];\n\t\t\t\t\telse\n\t\t\t\t\t\tprintUsage(stderr, 1);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 's':\n\t\t\t\t\treadOpts->sortOverride = true;\n\t\t\t\t\t++j;\n\t\t\t\t\tif (arg [j] == '\\0')\n\t\t\t\t\t\treadOpts->sortMethod = TAG_SORTED;\n\t\t\t\t\telse if (strchr (\"012\", arg[j]) != NULL)\n\t\t\t\t\t\treadOpts->sortMethod = (sortType) (arg[j] - '0');\n\t\t\t\t\telse\n\t\t\t\t\t\tprintUsage(stderr, 1);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'A':\n\t\t\t\t\tactionSpec->canonicalizing = true;\n\t\t\t\t\tactionSpec->absoluteOnly = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'C':\n\t\t\t\t\tactionSpec->canonicalizing = true;\n\t\t\t\t\tactionSpec->absoluteOnly = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'Q':\n\t\t\t\t\tif (i + 1 == argc)\n\t\t\t\t\t\tprintUsage(stderr, 1);\n\t\t\t\t\tactionSpec->qualifier = compileExpression (argv[++i],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   (void * (*)(EsObject *))q_compile,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   \"filter\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'S':\n\t\t\t\t\tif (i + 1 == argc)\n\t\t\t\t\t\tprintUsage(stderr, 1);\n\t\t\t\t\tactionSpec->sorter = compileExpression (argv[++i],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(void * (*)(EsObject *))s_compile,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"sorter\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'F':\n\t\t\t\t\tif (i + 1 == argc)\n\t\t\t\t\t\tprintUsage(stderr, 1);\n\t\t\t\t\tactionSpec->formatter = compileExpression (argv[++i],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   (void * (*)(EsObject *))f_compile,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   \"formatter\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tfprintf (stderr, \"%s: unknown option: %c\\n\",\n\t\t\t\t\t\t\t ProgramName, arg[j]);\n\t\t\t\t\texit (1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nextern int main (int argc, char **argv)\n{\n\ttagPrintOptions printOpts = {0};\n\treadOptions readOpts = {0};\n\tstruct inputSpec inputSpec;\n\tstruct actionSpec actionSpec;\n\n\tinitActionSpec (&actionSpec);\n\tinitInputSpec (&inputSpec);\n\n\tProgramName = argv [0];\n\tsetExecutableName (ProgramName);\n\tif (argc == 1)\n\t\tprintUsage(stderr, 1);\n\n\tparseOptions (argc, argv, &actionSpec, &inputSpec, &readOpts, &printOpts);\n\n\tif (actionSpec.action == ACTION_NONE)\n\t{\n\t\tfprintf (stderr,\n\t\t\t\"%s: no action specified: specify one of NAME, -l or -D\\n\",\n\t\t\tProgramName);\n\t\texit (1);\n\t}\n\n\tif ((actionSpec.action & ACTION_FIND) && (actionSpec.action & ACTION_LIST))\n\t{\n\t\tfprintf (stderr,\n\t\t\t\t \"%s: choose either an action: finding a tag or listing all\\n\",\n\t\t\t\t ProgramName);\n\t\texit (1);\n\t}\n\n\trun (&actionSpec, &inputSpec, &readOpts, &printOpts);\n\n\tfiniActionSpec(&actionSpec);\n\tfiniInputSpec(&inputSpec);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "extra-cmds/readtags-stub.c",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This code is derived from the main part of ctags.\n*   This source code is NOT released for the public domain.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"\n#include \"readtags-stub.h\"\n#include \"routines.h\"\n#include \"routines_p.h\"\n\n#include <errno.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef DEBUG\n\nextern void debugAssert (const char *assertion, const char *file, unsigned int line, const char *function)\n{\n\tfprintf(stderr, \"readtags: %s:%u: %s%sAssertion `%s' failed.\\n\",\n\t        file, line,\n\t        function ? function : \"\", function ? \": \" : \"\",\n\t        assertion);\n\tfflush(stderr);\n\tabort();\n}\n\n#endif\n\n#define selected(var,feature)\t(((int)(var) & (int)(feature)) == (int)feature)\n\nCTAGS_ATTR_PRINTF (2, 0)\nstatic bool stderrDefaultErrorPrinter (const errorSelection selection,\n\t\t\t\t       const char *const format,\n\t\t\t\t       va_list ap, void *data CTAGS_ATTR_UNUSED)\n{\n\tfprintf (stderr, \"%s: %s\", getExecutableName (),\n\t\t selected (selection, WARNING) ? \"Warning: \" :\n\t\t selected (selection, NOTICE) ? \"Notice: \" : \"\");\n\tvfprintf (stderr, format, ap);\n\tif (selected (selection, PERROR))\n\t{\n#ifdef HAVE_STRERROR\n\t\tfprintf (stderr, \" : %s\", strerror (errno));\n#else\n\t\tperror (\" \");\n#endif\n\t}\n\tfputs (\"\\n\", stderr);\n\n\treturn (selected (selection, FATAL))? true: false;\n}\n\nextern void error (const errorSelection selection,\n\t\t   const char *const format, ...)\n{\n\tva_list ap;\n\tbool shouldExit;\n\n\tif (selected (selection, NOTICE))\n\t\treturn;\n\n\tva_start (ap, format);\n\tshouldExit = stderrDefaultErrorPrinter (selection, format, ap, NULL);\n\tva_end (ap);\n\n\tif (shouldExit)\n\t\texit (1);\n}\n"
  },
  {
    "path": "extra-cmds/readtags-stub.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This code is derived from the main part of ctags.\n*   This source code is NOT released for the public domain.\n*/\n#ifndef READTAGS_STUB_H\n#define READTAGS_STUB_H\n\n#include \"general.h\"\n\n#ifdef DEBUG\n# include <assert.h>\n#endif\n\nenum eDebugLevels {\n\tDEBUG_READ   = 0x01,  /* echo raw (filtered) characters */\n\tDEBUG_PARSE  = 0x02,  /* echo parsing results */\n\tDEBUG_STATUS = 0x04,  /* echo file status information */\n\tDEBUG_OPTION = 0x08,  /* echo option parsing */\n\tDEBUG_CPP    = 0x10,  /* echo characters out of pre-processor */\n\tDEBUG_RAW    = 0x20   /* echo raw (filtered) characters */\n};\n\nextern void debugAssert (const char *assertion, const char *file, unsigned int line, const char *function) attr__noreturn;\nextern void debugPrintf (const enum eDebugLevels level, const char *const format, ...) CTAGS_ATTR_PRINTF (2, 3);\n\n#endif\t/* READTAGS_STUB_H */\n"
  },
  {
    "path": "extra-cmds/utiltest.c",
    "content": "/*\n*   Copyright (c) 2022 Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#include \"general.h\"\n\n#include \"acutest.h\"\n#include \"fname.h\"\n#include \"htable.h\"\n#include \"intern.h\"\n#include \"numarray.h\"\n#include \"routines.h\"\n#include \"routines_p.h\"\n#include \"vstring.h\"\n#include <string.h>\n\nstatic void test_fname_absolute(void)\n{\n\tchar *str;\n\tchar *in;\n\n#define T(INPUT,OUTPUT) \\\n\tTEST_CHECK((in = eStrdup (INPUT), \\\n\t\t\t\tstrcmp((str = canonicalizeAbsoluteFileName (in)), OUTPUT) == 0)); \\\n\teFree (in); \\\n\teFree (str)\n\n\tT(\"/abc/efg/..\", \"/abc\");\n\tT(\"/abc/efg/hij/..\", \"/abc/efg\");\n\tT(\"/abc/efg/../\", \"/abc\");\n\tT(\"/abc/efg/./\", \"/abc/efg\");\n\tT(\"/abc/efg/./../.\", \"/abc\");\n\tT(\"/abc/..\", \"/\");\n\n\tT(\"..\", \"/\");\n\tT(\".\", \"/\");\n\tT(\"a\", \"/a\");\n\tT(\"abc\", \"/abc\");\n\tT(\"\", \"/\");\n\n\tT(\"../a\", \"/a\");\n\tT(\"../abc\", \"/abc\");\n\tT(\"./a\", \"/a\");\n\tT(\"./abc\", \"/abc\");\n\tT(\"a/../b\", \"/b\");\n\tT(\"abc/../efg\", \"/efg\");\n\n\tT(\"..//////a\", \"/a\");\n\tT(\"..//..//..//a\", \"/a\");\n#undef T\n}\n\nstatic void test_fname_absolute_with_cache(void)\n{\n\tstruct canonFnameCacheTable *ct;\n\tbool absoluteOnly;\n#define T(INPUT,OUTPUT) \\\n\tif (!TEST_CHECK(strcmp(canonicalizeFileName (ct, INPUT), \\\n\t\t\t       OUTPUT) == 0))\t\t\t\t\\\n\t\tfprintf(stderr, \"\tACTUAL: %s (%s)\\n\", canonicalizeFileName (ct, INPUT), absoluteOnly? \"absOnly\": \"relaOK\")\n\n\tabsoluteOnly = true;\n\tct = canonFnameCacheTableNew (\"/abc\", absoluteOnly);\n\tT(\"/abc/input\", \"/abc/input\");\n\tT(\"/abc/../input\", \"/input\");\n\tT(\"/abc/../../input\", \"/input\");\n\tT(\"/abc/.././../input\", \"/input\");\n\tT(\"/abc/./input\", \"/abc/input\");\n\tT(\"/abc/.//input\", \"/abc/input\");\n\tT(\"/abc/.//.//input\", \"/abc/input\");\n\tT(\"/input\", \"/input\");\n\tT(\"/./input\", \"/input\");\n\tT(\"/../z/../input\", \"/input\");\n\tT(\"/../z/../..input\", \"/..input\");\n\n\tT(\"input\", \"/abc/input\");\n\tT(\"./input\", \"/abc/input\");\n\tT(\"../input\", \"/input\");\n\tT(\"..//input\", \"/input\");\n\tT(\".././input\", \"/input\");\n\tT(\"..//.//input\", \"/input\");\n\tT(\"../d/input\", \"/d/input\");\n\tT(\"../d/../input\", \"/input\");\n\tT(\"../d/..//input\", \"/input\");\n\tT(\"../d/..///./input\", \"/input\");\n\tcanonFnameCacheTableDelete (ct);\n\n\tabsoluteOnly = true;\n\tct = canonFnameCacheTableNew (\"/abc/efg\", absoluteOnly);\n\tT(\"input\", \"/abc/efg/input\");\n\tT(\"../input\", \"/abc/input\");\n\tT(\"..//input\", \"/abc/input\");\n\tT(\".././input\", \"/abc/input\");\n\tT(\"..//.//input\", \"/abc/input\");\n\tT(\"../d/input\", \"/abc/d/input\");\n\tT(\"../d/../input\", \"/abc/input\");\n\tT(\"../d/..//input\", \"/abc/input\");\n\tT(\"../d/..///./input\", \"/abc/input\");\n\tT(\"../d/..///./input/.././input\", \"/abc/input\");\n\tT(\"\", \"/abc/efg\");\n\tT(\".\", \"/abc/efg\");\n\tT(\"./\", \"/abc/efg\");\n\tT(\"./..\", \"/abc\");\n\tT(\"./.\", \"/abc/efg\");\n\tT(\"././//\", \"/abc/efg\");\n\tT(\"././//.\", \"/abc/efg\");\n\tT(\"././../efg/.\", \"/abc/efg\");\n\tT(\"..\", \"/abc\");\n\tT(\"../..\", \"/\");\n\tT(\"../../\", \"/\");\n\tT(\"../..\", \"/\");\n\tT(\"../../..\", \"/\");\n\tT(\"../../../..\", \"/\");\n\tT(\"../././..\", \"/\");\n\tT(\"./././..\", \"/abc\");\n\tT(\"...\", \"/abc/efg/...\");\n\tT(\".../\", \"/abc/efg/...\");\n\tT(\"...//\", \"/abc/efg/...\");\n\tT(\"..././\", \"/abc/efg/...\");\n\tT(\"...//./\", \"/abc/efg/...\");\n\tT(\"...//.//\", \"/abc/efg/...\");\n\tT(\"..././/\", \"/abc/efg/...\");\n\tT(\"..././.../\", \"/abc/efg/.../...\");\n\tcanonFnameCacheTableDelete (ct);\n#undef T\n}\n\nstatic void test_fname_relative(void)\n{\n\tstruct canonFnameCacheTable *ct;\n\tbool absoluteOnly;\n#define T(INPUT,OUTPUT) \\\n\tif (!TEST_CHECK(strcmp(canonicalizeFileName (ct, INPUT), \\\n\t\t\t       OUTPUT) == 0))\t\t\t\t\\\n\t\tfprintf(stderr, \"\tACTUAL: %s (%s)\\n\", canonicalizeFileName (ct, INPUT), absoluteOnly? \"absOnly\": \"relaOK\")\n\n\tabsoluteOnly = false;\n\tct = canonFnameCacheTableNew (\"/abc\", absoluteOnly);\n\tT(\"/abc/input\", \"/abc/input\");\n\tT(\"/abc/../input\", \"/input\");\n\tT(\"/abc/../../input\", \"/input\");\n\tT(\"/abc/.././../input\", \"/input\");\n\tT(\"/abc/./input\", \"/abc/input\");\n\tT(\"/abc/.//input\", \"/abc/input\");\n\tT(\"/abc/.//.//input\", \"/abc/input\");\n\tT(\"/input\", \"/input\");\n\tT(\"/./input\", \"/input\");\n\tT(\"/../z/../input\", \"/input\");\n\tT(\"/../z/../..input\", \"/..input\");\n\n\tT(\"input\", \"input\");\n\tT(\"./input\", \"input\");\n\tT(\"../input\", \"/input\");\n\tT(\"..//input\", \"/input\");\n\tT(\".././input\", \"/input\");\n\tT(\"..//.//input\", \"/input\");\n\tT(\"../d/input\", \"/d/input\");\n\tT(\"../d/../input\", \"/input\");\n\tT(\"../d/..//input\", \"/input\");\n\tT(\"../d/..///./input\", \"/input\");\n\tcanonFnameCacheTableDelete (ct);\n\n\tabsoluteOnly = false;\n\tct = canonFnameCacheTableNew (\"/abc/efg\", absoluteOnly);\n\tT(\"input\", \"input\");\n\tT(\"../input\", \"/abc/input\");\n\tT(\"..//input\", \"/abc/input\");\n\tT(\".././input\", \"/abc/input\");\n\tT(\"..//.//input\", \"/abc/input\");\n\tT(\"../d/input\", \"/abc/d/input\");\n\tT(\"../d/../input\", \"/abc/input\");\n\tT(\"../d/..//input\", \"/abc/input\");\n\tT(\"../d/..///./input\", \"/abc/input\");\n\tT(\"../d/..///./input/.././input\", \"/abc/input\");\n\tT(\"\", \".\");\n\tT(\".\", \".\");\n\tT(\"./\", \".\");\n\tT(\"./..\", \"/abc\");\n\tT(\"./.\", \".\");\n\tT(\"././//\", \".\");\n\tT(\"././//.\", \".\");\n\tT(\"././../efg/.\", \".\");\n\tT(\"..\", \"/abc\");\n\tT(\"../..\", \"/\");\n\tT(\"../../\", \"/\");\n\tT(\"../..\", \"/\");\n\tT(\"../../..\", \"/\");\n\tT(\"../../../..\", \"/\");\n\tT(\"../././..\", \"/\");\n\tT(\"./././..\", \"/abc\");\n\tT(\"...\", \"...\");\n\tT(\".../\", \"...\");\n\tT(\"...//\", \"...\");\n\tT(\"..././\", \"...\");\n\tT(\"...//./\", \"...\");\n\tT(\"...//.//\", \"...\");\n\tT(\"..././/\", \"...\");\n\tT(\"..././.../\", \".../...\");\n\tcanonFnameCacheTableDelete (ct);\n#undef T\n}\n\nstatic void test_htable_update(void)\n{\n\thashTable *htable = hashTableNew (3, hashCstrhash, hashCstreq,\n\t\t\t\t\t\t\t\t\t  eFree, NULL);\n\tTEST_CHECK(htable != NULL);\n\n\thashTablePutItem (htable, strdup(\"a\"), \"A\");\n\tTEST_CHECK (hashTableUpdateItem (htable,  \"a\", \"B\") == true);\n\tTEST_CHECK (hashTableUpdateItem (htable,  \"b\", \"B\") == false);\n\tTEST_CHECK (strcmp (hashTableGetItem (htable, \"a\"), \"B\") == 0);\n\tTEST_CHECK (hashTableUpdateOrPutItem (htable,  \"a\", \"C\") == true);\n\tTEST_CHECK (hashTableUpdateOrPutItem (htable,  strdup(\"x\"), \"X\") == false);\n\tTEST_CHECK (strcmp (hashTableGetItem (htable, \"x\"), \"X\") == 0);\n\thashTableDelete(htable);\n}\n\nstatic void test_htable_grow(void)\n{\n\thashTable *htable;\n\tint i;\n\tchar keyBuf[20];\n\n\thtable = hashTableNew (3, hashCstrhash, hashCstreq, eFree, NULL);\n\n\tfor (i = 0; i < 1000; ++i)\n\t{\n\t\tsnprintf(keyBuf, sizeof(keyBuf), \"str_%d\", i);\n\t\thashTablePutItem (htable, strdup(keyBuf), strdup(keyBuf));\n\t}\n\n\tTEST_CHECK (strcmp (hashTableGetItem (htable, \"str_123\"), \"str_123\") == 0);\n\thashTableDelete(htable);\n}\n\nstatic void test_intern(void)\n{\n\tconst char *str = \"asdfasfaskeopsdfksd\";\n\tconst char *symbol0 = intern(str);\n\tconst char *symbol1, *symbol2, *symbol3;\n\n\tchar *tmp = strdup (str);\n\tsymbol1 = intern (tmp);\n\tfree (tmp);\n\tsymbol2 = intern (symbol0);\n\tsymbol3 = intern (symbol1);\n\n\tTEST_CHECK (symbol0 == symbol1);\n\tTEST_CHECK (symbol1 == symbol2);\n\tTEST_CHECK (symbol2 == symbol3);\n}\n\nstatic void test_numarray(void)\n{\n\tintArray *a = intArrayNew ();\n\n\tintArrayAdd(a, 0);\n\tintArrayAdd(a, 1);\n\tintArrayAdd(a, 2);\n\n\tTEST_CHECK (intArrayCount(a) == 3);\n\tTEST_CHECK (intArrayItem(a, 0) == 0);\n\tTEST_CHECK (intArrayItem(a, 1) == 1);\n\tTEST_CHECK (intArrayItem(a, 2) == 2);\n\tTEST_CHECK (intArrayLast(a) == 2);\n\tTEST_CHECK (intArrayRemoveLast(a) == 2);\n\tTEST_CHECK (intArrayLast(a) == 1);\n\n\tintArrayDelete(a);\n}\n\nstatic void test_routines_strrstr(void)\n{\n\tTEST_CHECK(strcmp(strrstr(\"abcdcdb\", \"cd\"), \"cdb\") == 0);\n}\n\nstatic void test_routines_filenameSansExtensionNew(void)\n{\n\tchar *bs;\n\n\tTEST_CHECK ((bs = filenameSansExtensionNew (\"a.in\", \".in\"))\n\t\t\t\t&& strcmp(bs, \"a\") == 0);\n\tif (bs)\n\t\teFree (bs);\n\n\tTEST_CHECK ((bs = filenameSansExtensionNew (\"x/b.in\", \".in\"))\n\t\t\t\t&& strcmp(bs, \"x/b\") == 0);\n\tif (bs)\n\t\teFree (bs);\n\n\tTEST_CHECK ((bs = filenameSansExtensionNew (\"c.in.in\", \".in.in\"))\n\t\t\t\t&& strcmp(bs, \"c\") == 0);\n\tif (bs)\n\t\teFree (bs);\n\n\tTEST_CHECK ((bs = filenameSansExtensionNew (\"/y/d.in.in\", \".in.in\"))\n\t\t\t\t&& strcmp(bs, \"/y/d\") == 0);\n\tif (bs)\n\t\teFree (bs);\n}\n\nstatic void test_vstring_ncats(void)\n{\n\tvString *vstr = vStringNew ();\n\n\tvStringCatS (vstr, \"abc\");\n\tvStringNCatS (vstr, \"def\", 0);\n\tTEST_CHECK(strcmp (vStringValue (vstr), \"abc\") == 0);\n\tvStringClear (vstr);\n\n\tvStringCatS (vstr, \"abc\");\n\tvStringNCatS (vstr, \"def\", 1);\n\tTEST_CHECK(strcmp (vStringValue (vstr), \"abcd\") == 0);\n\tvStringClear (vstr);\n\n\tvStringCatS (vstr, \"abc\");\n\tvStringNCatS (vstr, \"def\", 2);\n\tTEST_CHECK(strcmp (vStringValue (vstr), \"abcde\") == 0);\n\tvStringClear (vstr);\n\n\tvStringCatS (vstr, \"abc\");\n\tvStringNCatS (vstr, \"def\", 3);\n\tTEST_CHECK(strcmp (vStringValue (vstr), \"abcdef\") == 0);\n\tvStringClear (vstr);\n\n\tvStringCatS (vstr, \"abc\");\n\tvStringNCatS (vstr, \"def\", 4);\n\tTEST_CHECK(strcmp (vStringValue (vstr), \"abcdef\") == 0);\n\tvStringClear (vstr);\n\n\tvStringDelete (vstr);\n}\n\nstatic void test_vstring_truncate_leading(void)\n{\n\tvString *vstr = vStringNewInit (\"   abcdefg\");\n\tTEST_CHECK(vstr != NULL);\n\n\tvStringStripLeading (vstr);\n\tTEST_CHECK(strcmp(vStringValue(vstr), \"abcdefg\") == 0);\n\n\tvStringTruncateLeading (vstr, 3);\n\tTEST_CHECK(strcmp(vStringValue(vstr), \"defg\") == 0);\n\n\tvStringTruncateLeading (vstr, 0);\n\tTEST_CHECK(strcmp(vStringValue(vstr), \"defg\") == 0);\n\n\tvStringTruncateLeading (vstr, 100);\n\tTEST_CHECK(strcmp(vStringValue(vstr), \"\") == 0);\n\n\tvStringDelete (vstr);\n}\n\nstatic void test_vstring_eqc(void)\n{\n\tvString *vstr = vStringNewInit (\"abcdefg\");\n\tTEST_CHECK(vstr != NULL);\n\n\tTEST_CHECK(vStringEqC(vstr, \"abcdefg\"));\n\tTEST_CHECK(!vStringEqC(vstr, \"abcdefgz\"));\n\tTEST_CHECK(!vStringEqC(vstr, \"abcdef\"));\n\tTEST_CHECK(!vStringEqC(vstr, \"\"));\n\n\tvStringDelete (vstr);\n}\n\nTEST_LIST = {\n   { \"fname/absolute\",   test_fname_absolute   },\n   { \"fname/absolute+cache\", test_fname_absolute_with_cache },\n   { \"fname/relative\",   test_fname_relative   },\n   { \"htable/update\",    test_htable_update    },\n   { \"htable/grow\",      test_htable_grow      },\n   { \"intern\",           test_intern           },\n   { \"numarray\",         test_numarray         },\n   { \"routines/strrstr\", test_routines_strrstr },\n   { \"routines/filenameSansExtensionNew\", test_routines_filenameSansExtensionNew },\n   { \"vstring/ncats\",    test_vstring_ncats    },\n   { \"vstring/truncate_leading\", test_vstring_truncate_leading },\n   { \"vstring/EqC\",      test_vstring_eqc },\n   { NULL, NULL }     /* zeroed record marking the end of the list */\n};\n"
  },
  {
    "path": "gnulib/.gitignore",
    "content": "fnmatch.h\nstdint.h\n"
  },
  {
    "path": "gnulib/Makefile.am",
    "content": "## DO NOT EDIT! GENERATED AUTOMATICALLY!\n## Process this file with automake to produce Makefile.in.\n# Copyright (C) 2002-2021 Free Software Foundation, Inc.\n#\n# This file is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This file is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this file.  If not, see <https://www.gnu.org/licenses/>.\n#\n# As a special exception to the GNU General Public License,\n# this file may be distributed as part of a program that\n# contains a configuration script generated by Autoconf, under\n# the same distribution terms as the rest of that program.\n#\n# Generated by gnulib-tool.\n# Reproduce by:\n# gnulib-tool --import \\\n#  --lib=libgnu \\\n#  --source-base=gnulib \\\n#  --m4-base=m4 \\\n#  --doc-base=doc \\\n#  --tests-base=tests \\\n#  --aux-dir=. \\\n#  --no-conditional-dependencies \\\n#  --no-libtool \\\n#  --macro-prefix=gl \\\n#  --no-vc-files \\\n#  fnmatch \\\n#  regex\n\nAUTOMAKE_OPTIONS = 1.11 gnits subdir-objects\n\nSUBDIRS =\nnoinst_HEADERS =\nnoinst_LIBRARIES =\nnoinst_LTLIBRARIES =\nEXTRA_DIST =\nBUILT_SOURCES =\nSUFFIXES =\nMOSTLYCLEANFILES = core *.stackdump\nMOSTLYCLEANDIRS =\nCLEANFILES =\nDISTCLEANFILES =\nMAINTAINERCLEANFILES =\n# No GNU Make output.\n\nAM_CPPFLAGS =\nAM_CFLAGS =\n\nnoinst_LIBRARIES += libgnu.a\n\nlibgnu_a_SOURCES =\nlibgnu_a_LIBADD = $(gl_LIBOBJS)\nlibgnu_a_DEPENDENCIES = $(gl_LIBOBJS)\nEXTRA_libgnu_a_SOURCES =\n\n## begin gnulib module absolute-header\n\n# Use this preprocessor expression to decide whether #include_next works.\n# Do not rely on a 'configure'-time test for this, since the expression\n# might appear in an installed header, which is used by some other compiler.\nHAVE_INCLUDE_NEXT = (__GNUC__ || __clang__ || 60000000 <= __DECC_VER)\n\n## end   gnulib module absolute-header\n\n## begin gnulib module alloca-opt\n\nBUILT_SOURCES += $(ALLOCA_H)\n\n# We need the following in order to create <alloca.h> when the system\n# doesn't have one that works with the given compiler.\nif GL_GENERATE_ALLOCA_H\nalloca.h: alloca.in.h $(top_builddir)/config.status\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's|@''HAVE_ALLOCA_H''@|$(HAVE_ALLOCA_H)|g' < $(srcdir)/alloca.in.h; \\\n\t} > $@-t && \\\n\tmv -f $@-t $@\nelse\nalloca.h: $(top_builddir)/config.status\n\trm -f $@\nendif\nMOSTLYCLEANFILES += alloca.h alloca.h-t\n\nEXTRA_DIST += alloca.in.h\n\n## end   gnulib module alloca-opt\n\n## begin gnulib module attribute\n\n\nEXTRA_DIST += attribute.h\n\n## end   gnulib module attribute\n\n## begin gnulib module btowc\n\n\nEXTRA_DIST += btowc.c\n\nEXTRA_libgnu_a_SOURCES += btowc.c\n\n## end   gnulib module btowc\n\n## begin gnulib module ctype\n\nBUILT_SOURCES += ctype.h\n\n# We need the following in order to create <ctype.h> when the system\n# doesn't have one that works with the given compiler.\nctype.h: ctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_CTYPE_H''@|$(NEXT_CTYPE_H)|g' \\\n\t      -e 's/@''GNULIB_ISBLANK''@/$(GL_GNULIB_ISBLANK)/g' \\\n\t      -e 's/@''HAVE_ISBLANK''@/$(HAVE_ISBLANK)/g' \\\n\t      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \\\n\t      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \\\n\t      < $(srcdir)/ctype.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += ctype.h ctype.h-t\n\nEXTRA_DIST += ctype.in.h\n\n## end   gnulib module ctype\n\n## begin gnulib module dynarray\n\nBUILT_SOURCES += malloc/dynarray.gl.h malloc/dynarray-skeleton.gl.h\n\nmalloc/dynarray.gl.h: malloc/dynarray.h\n\t$(AM_V_at)$(MKDIR_P) malloc\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e '/libc_hidden_proto/d' < $(srcdir)/malloc/dynarray.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += malloc/dynarray.gl.h malloc/dynarray.gl.h-t\n\nmalloc/dynarray-skeleton.gl.h: malloc/dynarray-skeleton.c\n\t$(AM_V_at)$(MKDIR_P) malloc\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's|<malloc/dynarray\\.h>|<malloc/dynarray.gl.h>|g' \\\n\t      -e 's|__attribute_maybe_unused__|_GL_ATTRIBUTE_MAYBE_UNUSED|g' \\\n\t      -e 's|__attribute_nonnull__|_GL_ATTRIBUTE_NONNULL|g' \\\n\t      -e 's|__attribute_warn_unused_result__|_GL_ATTRIBUTE_NODISCARD|g' \\\n\t      -e 's|__glibc_likely|_GL_LIKELY|g' \\\n\t      -e 's|__glibc_unlikely|_GL_UNLIKELY|g' \\\n\t      < $(srcdir)/malloc/dynarray-skeleton.c; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += malloc/dynarray-skeleton.gl.h malloc/dynarray-skeleton.gl.h-t\n\nlibgnu_a_SOURCES += malloc/dynarray_at_failure.c                 malloc/dynarray_emplace_enlarge.c                 malloc/dynarray_finalize.c                 malloc/dynarray_resize.c                 malloc/dynarray_resize_clear.c\n\nEXTRA_DIST += dynarray.h malloc/dynarray-skeleton.c malloc/dynarray.h\n\nEXTRA_libgnu_a_SOURCES += malloc/dynarray-skeleton.c\n\n## end   gnulib module dynarray\n\n## begin gnulib module flexmember\n\n\nEXTRA_DIST += flexmember.h\n\n## end   gnulib module flexmember\n\n## begin gnulib module fnmatch\n\n\nEXTRA_DIST += fnmatch.c fnmatch_loop.c\n\nEXTRA_libgnu_a_SOURCES += fnmatch.c fnmatch_loop.c\n\n## end   gnulib module fnmatch\n\n## begin gnulib module fnmatch-h\n\nBUILT_SOURCES += $(FNMATCH_H)\n\n# We need the following in order to create <fnmatch.h>.\nif GL_GENERATE_FNMATCH_H\nfnmatch.h: fnmatch.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''HAVE_FNMATCH_H''@|$(HAVE_FNMATCH_H)|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_FNMATCH_H''@|$(NEXT_FNMATCH_H)|g' \\\n\t      -e 's/@''GNULIB_FNMATCH''@/$(GL_GNULIB_FNMATCH)/g' \\\n\t      -e 's|@''HAVE_FNMATCH''@|$(HAVE_FNMATCH)|g' \\\n\t      -e 's|@''REPLACE_FNMATCH''@|$(REPLACE_FNMATCH)|g' \\\n\t      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \\\n\t      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \\\n\t      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \\\n\t      < $(srcdir)/fnmatch.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nelse\nfnmatch.h: $(top_builddir)/config.status\n\trm -f $@\nendif\nMOSTLYCLEANFILES += fnmatch.h fnmatch.h-t\n\nEXTRA_DIST += fnmatch.in.h\n\n## end   gnulib module fnmatch-h\n\n## begin gnulib module hard-locale\n\nlibgnu_a_SOURCES += hard-locale.c\n\nEXTRA_DIST += hard-locale.h\n\n## end   gnulib module hard-locale\n\n## begin gnulib module idx\n\nlibgnu_a_SOURCES += idx.h\n\n## end   gnulib module idx\n\n## begin gnulib module intprops\n\n\nEXTRA_DIST += intprops.h\n\n## end   gnulib module intprops\n\n## begin gnulib module inttypes-incomplete\n\nBUILT_SOURCES += inttypes.h\n\n# We need the following in order to create <inttypes.h> when the system\n# doesn't have one that works with the given compiler.\ninttypes.h: inttypes.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_INTTYPES_H''@|$(NEXT_INTTYPES_H)|g' \\\n\t      -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \\\n\t      -e 's/@''PRIPTR_PREFIX''@/$(PRIPTR_PREFIX)/g' \\\n\t      -e 's/@''GNULIB_IMAXABS''@/$(GL_GNULIB_IMAXABS)/g' \\\n\t      -e 's/@''GNULIB_IMAXDIV''@/$(GL_GNULIB_IMAXDIV)/g' \\\n\t      -e 's/@''GNULIB_STRTOIMAX''@/$(GL_GNULIB_STRTOIMAX)/g' \\\n\t      -e 's/@''GNULIB_STRTOUMAX''@/$(GL_GNULIB_STRTOUMAX)/g' \\\n\t      -e 's/@''HAVE_DECL_IMAXABS''@/$(HAVE_DECL_IMAXABS)/g' \\\n\t      -e 's/@''HAVE_DECL_IMAXDIV''@/$(HAVE_DECL_IMAXDIV)/g' \\\n\t      -e 's/@''HAVE_DECL_STRTOIMAX''@/$(HAVE_DECL_STRTOIMAX)/g' \\\n\t      -e 's/@''HAVE_DECL_STRTOUMAX''@/$(HAVE_DECL_STRTOUMAX)/g' \\\n\t      -e 's/@''HAVE_IMAXDIV_T''@/$(HAVE_IMAXDIV_T)/g' \\\n\t      -e 's/@''REPLACE_STRTOIMAX''@/$(REPLACE_STRTOIMAX)/g' \\\n\t      -e 's/@''REPLACE_STRTOUMAX''@/$(REPLACE_STRTOUMAX)/g' \\\n\t      -e 's/@''INT32_MAX_LT_INTMAX_MAX''@/$(INT32_MAX_LT_INTMAX_MAX)/g' \\\n\t      -e 's/@''INT64_MAX_EQ_LONG_MAX''@/$(INT64_MAX_EQ_LONG_MAX)/g' \\\n\t      -e 's/@''UINT32_MAX_LT_UINTMAX_MAX''@/$(UINT32_MAX_LT_UINTMAX_MAX)/g' \\\n\t      -e 's/@''UINT64_MAX_EQ_ULONG_MAX''@/$(UINT64_MAX_EQ_ULONG_MAX)/g' \\\n\t      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \\\n\t      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \\\n\t      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \\\n\t      < $(srcdir)/inttypes.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += inttypes.h inttypes.h-t\n\nEXTRA_DIST += inttypes.in.h\n\n## end   gnulib module inttypes-incomplete\n\n## begin gnulib module isblank\n\n\nEXTRA_DIST += isblank.c\n\nEXTRA_libgnu_a_SOURCES += isblank.c\n\n## end   gnulib module isblank\n\n## begin gnulib module langinfo\n\nBUILT_SOURCES += langinfo.h\n\n# We need the following in order to create an empty placeholder for\n# <langinfo.h> when the system doesn't have one.\nlanginfo.h: langinfo.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_LANGINFO_H''@|$(NEXT_LANGINFO_H)|g' \\\n\t      -e 's/@''GNULIB_NL_LANGINFO''@/$(GL_GNULIB_NL_LANGINFO)/g' \\\n\t      -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \\\n\t      -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \\\n\t      -e 's|@''HAVE_LANGINFO_ALTMON''@|$(HAVE_LANGINFO_ALTMON)|g' \\\n\t      -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \\\n\t      -e 's|@''HAVE_LANGINFO_YESEXPR''@|$(HAVE_LANGINFO_YESEXPR)|g' \\\n\t      -e 's|@''HAVE_NL_LANGINFO''@|$(HAVE_NL_LANGINFO)|g' \\\n\t      -e 's|@''REPLACE_NL_LANGINFO''@|$(REPLACE_NL_LANGINFO)|g' \\\n\t      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \\\n\t      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \\\n\t      < $(srcdir)/langinfo.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += langinfo.h langinfo.h-t\n\nEXTRA_DIST += langinfo.in.h\n\n## end   gnulib module langinfo\n\n## begin gnulib module libc-config\n\n\nEXTRA_DIST += cdefs.h libc-config.h\n\n## end   gnulib module libc-config\n\n## begin gnulib module limits-h\n\nBUILT_SOURCES += $(LIMITS_H)\n\n# We need the following in order to create <limits.h> when the system\n# doesn't have one that is compatible with GNU.\nif GL_GENERATE_LIMITS_H\nlimits.h: limits.in.h $(top_builddir)/config.status\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_LIMITS_H''@|$(NEXT_LIMITS_H)|g' \\\n\t      < $(srcdir)/limits.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nelse\nlimits.h: $(top_builddir)/config.status\n\trm -f $@\nendif\nMOSTLYCLEANFILES += limits.h limits.h-t\n\nEXTRA_DIST += limits.in.h\n\n## end   gnulib module limits-h\n\n## begin gnulib module localcharset\n\nlibgnu_a_SOURCES += localcharset.c\n\nEXTRA_DIST += localcharset.h\n\n## end   gnulib module localcharset\n\n## begin gnulib module locale\n\nBUILT_SOURCES += locale.h\n\n# We need the following in order to create <locale.h> when the system\n# doesn't have one that provides all definitions.\nlocale.h: locale.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_LOCALE_H''@|$(NEXT_LOCALE_H)|g' \\\n\t      -e 's/@''GNULIB_LOCALECONV''@/$(GL_GNULIB_LOCALECONV)/g' \\\n\t      -e 's/@''GNULIB_SETLOCALE''@/$(GL_GNULIB_SETLOCALE)/g' \\\n\t      -e 's/@''GNULIB_SETLOCALE_NULL''@/$(GL_GNULIB_SETLOCALE_NULL)/g' \\\n\t      -e 's/@''GNULIB_DUPLOCALE''@/$(GL_GNULIB_DUPLOCALE)/g' \\\n\t      -e 's/@''GNULIB_LOCALENAME''@/$(GL_GNULIB_LOCALENAME)/g' \\\n\t      -e 's|@''HAVE_NEWLOCALE''@|$(HAVE_NEWLOCALE)|g' \\\n\t      -e 's|@''HAVE_DUPLOCALE''@|$(HAVE_DUPLOCALE)|g' \\\n\t      -e 's|@''HAVE_FREELOCALE''@|$(HAVE_FREELOCALE)|g' \\\n\t      -e 's|@''HAVE_XLOCALE_H''@|$(HAVE_XLOCALE_H)|g' \\\n\t      -e 's|@''REPLACE_LOCALECONV''@|$(REPLACE_LOCALECONV)|g' \\\n\t      -e 's|@''REPLACE_SETLOCALE''@|$(REPLACE_SETLOCALE)|g' \\\n\t      -e 's|@''REPLACE_NEWLOCALE''@|$(REPLACE_NEWLOCALE)|g' \\\n\t      -e 's|@''REPLACE_DUPLOCALE''@|$(REPLACE_DUPLOCALE)|g' \\\n\t      -e 's|@''REPLACE_FREELOCALE''@|$(REPLACE_FREELOCALE)|g' \\\n\t      -e 's|@''REPLACE_STRUCT_LCONV''@|$(REPLACE_STRUCT_LCONV)|g' \\\n\t      -e 's|@''LOCALENAME_ENHANCE_LOCALE_FUNCS''@|$(LOCALENAME_ENHANCE_LOCALE_FUNCS)|g' \\\n\t      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \\\n\t      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \\\n\t      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \\\n\t      < $(srcdir)/locale.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += locale.h locale.h-t\n\nEXTRA_DIST += locale.in.h\n\n## end   gnulib module locale\n\n## begin gnulib module localeconv\n\n\nEXTRA_DIST += localeconv.c\n\nEXTRA_libgnu_a_SOURCES += localeconv.c\n\n## end   gnulib module localeconv\n\n## begin gnulib module lock\n\nlibgnu_a_SOURCES += glthread/lock.h glthread/lock.c\n\n## end   gnulib module lock\n\n## begin gnulib module mbrtowc\n\n\nEXTRA_DIST += lc-charset-dispatch.c lc-charset-dispatch.h mbrtowc-impl-utf8.h mbrtowc-impl.h mbrtowc.c mbtowc-lock.c mbtowc-lock.h windows-initguard.h\n\nEXTRA_libgnu_a_SOURCES += lc-charset-dispatch.c mbrtowc.c mbtowc-lock.c\n\n## end   gnulib module mbrtowc\n\n## begin gnulib module mbsinit\n\n\nEXTRA_DIST += mbsinit.c\n\nEXTRA_libgnu_a_SOURCES += mbsinit.c\n\n## end   gnulib module mbsinit\n\n## begin gnulib module mbsrtowcs\n\n\nEXTRA_DIST += mbsrtowcs-impl.h mbsrtowcs-state.c mbsrtowcs.c\n\nEXTRA_libgnu_a_SOURCES += mbsrtowcs-state.c mbsrtowcs.c\n\n## end   gnulib module mbsrtowcs\n\n## begin gnulib module mbtowc\n\n\nEXTRA_DIST += mbtowc-impl.h mbtowc.c\n\nEXTRA_libgnu_a_SOURCES += mbtowc.c\n\n## end   gnulib module mbtowc\n\n## begin gnulib module memchr\n\n\nEXTRA_DIST += memchr.c memchr.valgrind\n\nEXTRA_libgnu_a_SOURCES += memchr.c\n\n## end   gnulib module memchr\n\n## begin gnulib module mempcpy\n\n\nEXTRA_DIST += mempcpy.c\n\nEXTRA_libgnu_a_SOURCES += mempcpy.c\n\n## end   gnulib module mempcpy\n\n## begin gnulib module nl_langinfo\n\n\nEXTRA_DIST += nl_langinfo-lock.c nl_langinfo.c windows-initguard.h\n\nEXTRA_libgnu_a_SOURCES += nl_langinfo-lock.c nl_langinfo.c\n\n## end   gnulib module nl_langinfo\n\n## begin gnulib module regex\n\n\nEXTRA_DIST += regcomp.c regex.c regex.h regex_internal.c regex_internal.h regexec.c\n\nEXTRA_libgnu_a_SOURCES += regcomp.c regex.c regex_internal.c regexec.c\n\n## end   gnulib module regex\n\n## begin gnulib module setlocale-null\n\nlibgnu_a_SOURCES += setlocale_null.c\n\nEXTRA_DIST += setlocale-lock.c setlocale_null.h windows-initguard.h\n\nEXTRA_libgnu_a_SOURCES += setlocale-lock.c\n\n## end   gnulib module setlocale-null\n\n## begin gnulib module snippet/_Noreturn\n\n# Because this Makefile snippet defines a variable used by other\n# gnulib Makefile snippets, it must be present in all makefiles that\n# need it. This is ensured by the applicability 'all' defined above.\n\n_NORETURN_H=$(srcdir)/_Noreturn.h\n\nEXTRA_DIST += _Noreturn.h\n\n## end   gnulib module snippet/_Noreturn\n\n## begin gnulib module snippet/arg-nonnull\n\n# Because this Makefile snippet defines a variable used by other\n# gnulib Makefile snippets, it must be present in all makefiles that\n# need it. This is ensured by the applicability 'all' defined above.\n\nARG_NONNULL_H=$(srcdir)/arg-nonnull.h\n\nEXTRA_DIST += arg-nonnull.h\n\n## end   gnulib module snippet/arg-nonnull\n\n## begin gnulib module snippet/c++defs\n\n# Because this Makefile snippet defines a variable used by other\n# gnulib Makefile snippets, it must be present in all makefiles that\n# need it. This is ensured by the applicability 'all' defined above.\n\nCXXDEFS_H=$(srcdir)/c++defs.h\n\nEXTRA_DIST += c++defs.h\n\n## end   gnulib module snippet/c++defs\n\n## begin gnulib module snippet/warn-on-use\n\n# Because this Makefile snippet defines a variable used by other\n# gnulib Makefile snippets, it must be present in all makefiles that\n# need it. This is ensured by the applicability 'all' defined above.\n\nWARN_ON_USE_H=$(srcdir)/warn-on-use.h\n\nEXTRA_DIST += warn-on-use.h\n\n## end   gnulib module snippet/warn-on-use\n\n## begin gnulib module stdbool\n\nBUILT_SOURCES += $(STDBOOL_H)\n\n# We need the following in order to create <stdbool.h> when the system\n# doesn't have one that works.\nif GL_GENERATE_STDBOOL_H\nstdbool.h: stdbool.in.h $(top_builddir)/config.status\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nelse\nstdbool.h: $(top_builddir)/config.status\n\trm -f $@\nendif\nMOSTLYCLEANFILES += stdbool.h stdbool.h-t\n\nEXTRA_DIST += stdbool.in.h\n\n## end   gnulib module stdbool\n\n## begin gnulib module stddef\n\nBUILT_SOURCES += $(STDDEF_H)\n\n# We need the following in order to create <stddef.h> when the system\n# doesn't have one that works with the given compiler.\nif GL_GENERATE_STDDEF_H\nstddef.h: stddef.in.h $(top_builddir)/config.status\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \\\n\t      -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \\\n\t      -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \\\n\t      -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \\\n\t      < $(srcdir)/stddef.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nelse\nstddef.h: $(top_builddir)/config.status\n\trm -f $@\nendif\nMOSTLYCLEANFILES += stddef.h stddef.h-t\n\nEXTRA_DIST += stddef.in.h\n\n## end   gnulib module stddef\n\n## begin gnulib module stdint\n\nBUILT_SOURCES += $(STDINT_H)\n\n# We need the following in order to create <stdint.h> when the system\n# doesn't have one that works with the given compiler.\nif GL_GENERATE_STDINT_H\nstdint.h: stdint.in.h $(top_builddir)/config.status\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \\\n\t      -e 's/@''HAVE_C99_STDINT_H''@/$(HAVE_C99_STDINT_H)/g' \\\n\t      -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \\\n\t      -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \\\n\t      -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \\\n\t      -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \\\n\t      -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \\\n\t      -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \\\n\t      -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \\\n\t      -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \\\n\t      -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \\\n\t      -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \\\n\t      -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \\\n\t      -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \\\n\t      -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \\\n\t      -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \\\n\t      -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \\\n\t      -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \\\n\t      -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \\\n\t      -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \\\n\t      -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \\\n\t      -e 's/@''GNULIBHEADERS_OVERRIDE_WINT_T''@/$(GNULIBHEADERS_OVERRIDE_WINT_T)/g' \\\n\t      < $(srcdir)/stdint.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nelse\nstdint.h: $(top_builddir)/config.status\n\trm -f $@\nendif\nMOSTLYCLEANFILES += stdint.h stdint.h-t\n\nEXTRA_DIST += stdint.in.h\n\n## end   gnulib module stdint\n\n## begin gnulib module stdlib\n\nBUILT_SOURCES += stdlib.h\n\n# We need the following in order to create <stdlib.h> when the system\n# doesn't have one that works with the given compiler.\nstdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \\\n  $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \\\n\t      -e 's/@''GNULIB__EXIT''@/$(GL_GNULIB__EXIT)/g' \\\n\t      -e 's/@''GNULIB_ALIGNED_ALLOC''@/$(GL_GNULIB_ALIGNED_ALLOC)/g' \\\n\t      -e 's/@''GNULIB_ATOLL''@/$(GL_GNULIB_ATOLL)/g' \\\n\t      -e 's/@''GNULIB_CALLOC_POSIX''@/$(GL_GNULIB_CALLOC_POSIX)/g' \\\n\t      -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GL_GNULIB_CANONICALIZE_FILE_NAME)/g' \\\n\t      -e 's/@''GNULIB_FREE_POSIX''@/$(GL_GNULIB_FREE_POSIX)/g' \\\n\t      -e 's/@''GNULIB_GETLOADAVG''@/$(GL_GNULIB_GETLOADAVG)/g' \\\n\t      -e 's/@''GNULIB_GETSUBOPT''@/$(GL_GNULIB_GETSUBOPT)/g' \\\n\t      -e 's/@''GNULIB_GRANTPT''@/$(GL_GNULIB_GRANTPT)/g' \\\n\t      -e 's/@''GNULIB_MALLOC_POSIX''@/$(GL_GNULIB_MALLOC_POSIX)/g' \\\n\t      -e 's/@''GNULIB_MBTOWC''@/$(GL_GNULIB_MBTOWC)/g' \\\n\t      -e 's/@''GNULIB_MKDTEMP''@/$(GL_GNULIB_MKDTEMP)/g' \\\n\t      -e 's/@''GNULIB_MKOSTEMP''@/$(GL_GNULIB_MKOSTEMP)/g' \\\n\t      -e 's/@''GNULIB_MKOSTEMPS''@/$(GL_GNULIB_MKOSTEMPS)/g' \\\n\t      -e 's/@''GNULIB_MKSTEMP''@/$(GL_GNULIB_MKSTEMP)/g' \\\n\t      -e 's/@''GNULIB_MKSTEMPS''@/$(GL_GNULIB_MKSTEMPS)/g' \\\n\t      -e 's/@''GNULIB_POSIX_MEMALIGN''@/$(GL_GNULIB_POSIX_MEMALIGN)/g' \\\n\t      -e 's/@''GNULIB_POSIX_OPENPT''@/$(GL_GNULIB_POSIX_OPENPT)/g' \\\n\t      -e 's/@''GNULIB_PTSNAME''@/$(GL_GNULIB_PTSNAME)/g' \\\n\t      -e 's/@''GNULIB_PTSNAME_R''@/$(GL_GNULIB_PTSNAME_R)/g' \\\n\t      -e 's/@''GNULIB_PUTENV''@/$(GL_GNULIB_PUTENV)/g' \\\n\t      -e 's/@''GNULIB_QSORT_R''@/$(GL_GNULIB_QSORT_R)/g' \\\n\t      -e 's/@''GNULIB_RANDOM''@/$(GL_GNULIB_RANDOM)/g' \\\n\t      -e 's/@''GNULIB_RANDOM_R''@/$(GL_GNULIB_RANDOM_R)/g' \\\n\t      -e 's/@''GNULIB_REALLOC_POSIX''@/$(GL_GNULIB_REALLOC_POSIX)/g' \\\n\t      -e 's/@''GNULIB_REALLOCARRAY''@/$(GL_GNULIB_REALLOCARRAY)/g' \\\n\t      -e 's/@''GNULIB_REALPATH''@/$(GL_GNULIB_REALPATH)/g' \\\n\t      -e 's/@''GNULIB_RPMATCH''@/$(GL_GNULIB_RPMATCH)/g' \\\n\t      -e 's/@''GNULIB_SECURE_GETENV''@/$(GL_GNULIB_SECURE_GETENV)/g' \\\n\t      -e 's/@''GNULIB_SETENV''@/$(GL_GNULIB_SETENV)/g' \\\n\t      -e 's/@''GNULIB_STRTOD''@/$(GL_GNULIB_STRTOD)/g' \\\n\t      -e 's/@''GNULIB_STRTOL''@/$(GL_GNULIB_STRTOL)/g' \\\n\t      -e 's/@''GNULIB_STRTOLD''@/$(GL_GNULIB_STRTOLD)/g' \\\n\t      -e 's/@''GNULIB_STRTOLL''@/$(GL_GNULIB_STRTOLL)/g' \\\n\t      -e 's/@''GNULIB_STRTOUL''@/$(GL_GNULIB_STRTOUL)/g' \\\n\t      -e 's/@''GNULIB_STRTOULL''@/$(GL_GNULIB_STRTOULL)/g' \\\n\t      -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GL_GNULIB_SYSTEM_POSIX)/g' \\\n\t      -e 's/@''GNULIB_UNLOCKPT''@/$(GL_GNULIB_UNLOCKPT)/g' \\\n\t      -e 's/@''GNULIB_UNSETENV''@/$(GL_GNULIB_UNSETENV)/g' \\\n\t      -e 's/@''GNULIB_WCTOMB''@/$(GL_GNULIB_WCTOMB)/g' \\\n\t      -e 's/@''GNULIB_MDA_ECVT''@/$(GL_GNULIB_MDA_ECVT)/g' \\\n\t      -e 's/@''GNULIB_MDA_FCVT''@/$(GL_GNULIB_MDA_FCVT)/g' \\\n\t      -e 's/@''GNULIB_MDA_GCVT''@/$(GL_GNULIB_MDA_GCVT)/g' \\\n\t      -e 's/@''GNULIB_MDA_MKTEMP''@/$(GL_GNULIB_MDA_MKTEMP)/g' \\\n\t      -e 's/@''GNULIB_MDA_PUTENV''@/$(GL_GNULIB_MDA_PUTENV)/g' \\\n\t      < $(srcdir)/stdlib.in.h | \\\n\t  sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \\\n\t      -e 's|@''HAVE_ALIGNED_ALLOC''@|$(HAVE_ALIGNED_ALLOC)|g' \\\n\t      -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \\\n\t      -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \\\n\t      -e 's|@''HAVE_DECL_ECVT''@|$(HAVE_DECL_ECVT)|g' \\\n\t      -e 's|@''HAVE_DECL_FCVT''@|$(HAVE_DECL_FCVT)|g' \\\n\t      -e 's|@''HAVE_DECL_GCVT''@|$(HAVE_DECL_GCVT)|g' \\\n\t      -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \\\n\t      -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \\\n\t      -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \\\n\t      -e 's|@''HAVE_INITSTATE''@|$(HAVE_INITSTATE)|g' \\\n\t      -e 's|@''HAVE_DECL_INITSTATE''@|$(HAVE_DECL_INITSTATE)|g' \\\n\t      -e 's|@''HAVE_MBTOWC''@|$(HAVE_MBTOWC)|g' \\\n\t      -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \\\n\t      -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \\\n\t      -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \\\n\t      -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \\\n\t      -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \\\n\t      -e 's|@''HAVE_POSIX_MEMALIGN''@|$(HAVE_POSIX_MEMALIGN)|g' \\\n\t      -e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \\\n\t      -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \\\n\t      -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \\\n\t      -e 's|@''HAVE_QSORT_R''@|$(HAVE_QSORT_R)|g' \\\n\t      -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \\\n\t      -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \\\n\t      -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \\\n\t      -e 's|@''HAVE_REALLOCARRAY''@|$(HAVE_REALLOCARRAY)|g' \\\n\t      -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \\\n\t      -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \\\n\t      -e 's|@''HAVE_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \\\n\t      -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \\\n\t      -e 's|@''HAVE_SETSTATE''@|$(HAVE_SETSTATE)|g' \\\n\t      -e 's|@''HAVE_DECL_SETSTATE''@|$(HAVE_DECL_SETSTATE)|g' \\\n\t      -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \\\n\t      -e 's|@''HAVE_STRTOL''@|$(HAVE_STRTOL)|g' \\\n\t      -e 's|@''HAVE_STRTOLD''@|$(HAVE_STRTOLD)|g' \\\n\t      -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \\\n\t      -e 's|@''HAVE_STRTOUL''@|$(HAVE_STRTOUL)|g' \\\n\t      -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \\\n\t      -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \\\n\t      -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \\\n\t      -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \\\n\t      -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \\\n\t      -e 's|@''REPLACE_ALIGNED_ALLOC''@|$(REPLACE_ALIGNED_ALLOC)|g' \\\n\t      -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \\\n\t      -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \\\n\t      -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \\\n\t      -e 's|@''REPLACE_INITSTATE''@|$(REPLACE_INITSTATE)|g' \\\n\t      -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \\\n\t      -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \\\n\t      -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \\\n\t      -e 's|@''REPLACE_POSIX_MEMALIGN''@|$(REPLACE_POSIX_MEMALIGN)|g' \\\n\t      -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \\\n\t      -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \\\n\t      -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \\\n\t      -e 's|@''REPLACE_QSORT_R''@|$(REPLACE_QSORT_R)|g' \\\n\t      -e 's|@''REPLACE_RANDOM''@|$(REPLACE_RANDOM)|g' \\\n\t      -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \\\n\t      -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \\\n\t      -e 's|@''REPLACE_REALLOCARRAY''@|$(REPLACE_REALLOCARRAY)|g' \\\n\t      -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \\\n\t      -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \\\n\t      -e 's|@''REPLACE_SETSTATE''@|$(REPLACE_SETSTATE)|g' \\\n\t      -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \\\n\t      -e 's|@''REPLACE_STRTOL''@|$(REPLACE_STRTOL)|g' \\\n\t      -e 's|@''REPLACE_STRTOLD''@|$(REPLACE_STRTOLD)|g' \\\n\t      -e 's|@''REPLACE_STRTOLL''@|$(REPLACE_STRTOLL)|g' \\\n\t      -e 's|@''REPLACE_STRTOUL''@|$(REPLACE_STRTOUL)|g' \\\n\t      -e 's|@''REPLACE_STRTOULL''@|$(REPLACE_STRTOULL)|g' \\\n\t      -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \\\n\t      -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \\\n\t      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \\\n\t      -e '/definition of _Noreturn/r $(_NORETURN_H)' \\\n\t      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \\\n\t      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += stdlib.h stdlib.h-t\n\nEXTRA_DIST += stdlib.in.h\n\n## end   gnulib module stdlib\n\n## begin gnulib module streq\n\n\nEXTRA_DIST += streq.h\n\n## end   gnulib module streq\n\n## begin gnulib module string\n\nBUILT_SOURCES += string.h\n\n# We need the following in order to create <string.h> when the system\n# doesn't have one that works with the given compiler.\nstring.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \\\n\t      -e 's/@''GNULIB_EXPLICIT_BZERO''@/$(GL_GNULIB_EXPLICIT_BZERO)/g' \\\n\t      -e 's/@''GNULIB_FFSL''@/$(GL_GNULIB_FFSL)/g' \\\n\t      -e 's/@''GNULIB_FFSLL''@/$(GL_GNULIB_FFSLL)/g' \\\n\t      -e 's/@''GNULIB_MBSLEN''@/$(GL_GNULIB_MBSLEN)/g' \\\n\t      -e 's/@''GNULIB_MBSNLEN''@/$(GL_GNULIB_MBSNLEN)/g' \\\n\t      -e 's/@''GNULIB_MBSCHR''@/$(GL_GNULIB_MBSCHR)/g' \\\n\t      -e 's/@''GNULIB_MBSRCHR''@/$(GL_GNULIB_MBSRCHR)/g' \\\n\t      -e 's/@''GNULIB_MBSSTR''@/$(GL_GNULIB_MBSSTR)/g' \\\n\t      -e 's/@''GNULIB_MBSCASECMP''@/$(GL_GNULIB_MBSCASECMP)/g' \\\n\t      -e 's/@''GNULIB_MBSNCASECMP''@/$(GL_GNULIB_MBSNCASECMP)/g' \\\n\t      -e 's/@''GNULIB_MBSPCASECMP''@/$(GL_GNULIB_MBSPCASECMP)/g' \\\n\t      -e 's/@''GNULIB_MBSCASESTR''@/$(GL_GNULIB_MBSCASESTR)/g' \\\n\t      -e 's/@''GNULIB_MBSCSPN''@/$(GL_GNULIB_MBSCSPN)/g' \\\n\t      -e 's/@''GNULIB_MBSPBRK''@/$(GL_GNULIB_MBSPBRK)/g' \\\n\t      -e 's/@''GNULIB_MBSSPN''@/$(GL_GNULIB_MBSSPN)/g' \\\n\t      -e 's/@''GNULIB_MBSSEP''@/$(GL_GNULIB_MBSSEP)/g' \\\n\t      -e 's/@''GNULIB_MBSTOK_R''@/$(GL_GNULIB_MBSTOK_R)/g' \\\n\t      -e 's/@''GNULIB_MEMCHR''@/$(GL_GNULIB_MEMCHR)/g' \\\n\t      -e 's/@''GNULIB_MEMMEM''@/$(GL_GNULIB_MEMMEM)/g' \\\n\t      -e 's/@''GNULIB_MEMPCPY''@/$(GL_GNULIB_MEMPCPY)/g' \\\n\t      -e 's/@''GNULIB_MEMRCHR''@/$(GL_GNULIB_MEMRCHR)/g' \\\n\t      -e 's/@''GNULIB_RAWMEMCHR''@/$(GL_GNULIB_RAWMEMCHR)/g' \\\n\t      -e 's/@''GNULIB_STPCPY''@/$(GL_GNULIB_STPCPY)/g' \\\n\t      -e 's/@''GNULIB_STPNCPY''@/$(GL_GNULIB_STPNCPY)/g' \\\n\t      -e 's/@''GNULIB_STRCHRNUL''@/$(GL_GNULIB_STRCHRNUL)/g' \\\n\t      -e 's/@''GNULIB_STRDUP''@/$(GL_GNULIB_STRDUP)/g' \\\n\t      -e 's/@''GNULIB_STRNCAT''@/$(GL_GNULIB_STRNCAT)/g' \\\n\t      -e 's/@''GNULIB_STRNDUP''@/$(GL_GNULIB_STRNDUP)/g' \\\n\t      -e 's/@''GNULIB_STRNLEN''@/$(GL_GNULIB_STRNLEN)/g' \\\n\t      -e 's/@''GNULIB_STRPBRK''@/$(GL_GNULIB_STRPBRK)/g' \\\n\t      -e 's/@''GNULIB_STRSEP''@/$(GL_GNULIB_STRSEP)/g' \\\n\t      -e 's/@''GNULIB_STRSTR''@/$(GL_GNULIB_STRSTR)/g' \\\n\t      -e 's/@''GNULIB_STRCASESTR''@/$(GL_GNULIB_STRCASESTR)/g' \\\n\t      -e 's/@''GNULIB_STRTOK_R''@/$(GL_GNULIB_STRTOK_R)/g' \\\n\t      -e 's/@''GNULIB_STRERROR''@/$(GL_GNULIB_STRERROR)/g' \\\n\t      -e 's/@''GNULIB_STRERROR_R''@/$(GL_GNULIB_STRERROR_R)/g' \\\n\t      -e 's/@''GNULIB_STRERRORNAME_NP''@/$(GL_GNULIB_STRERRORNAME_NP)/g' \\\n\t      -e 's/@''GNULIB_SIGABBREV_NP''@/$(GL_GNULIB_SIGABBREV_NP)/g' \\\n\t      -e 's/@''GNULIB_SIGDESCR_NP''@/$(GL_GNULIB_SIGDESCR_NP)/g' \\\n\t      -e 's/@''GNULIB_STRSIGNAL''@/$(GL_GNULIB_STRSIGNAL)/g' \\\n\t      -e 's/@''GNULIB_STRVERSCMP''@/$(GL_GNULIB_STRVERSCMP)/g' \\\n\t      -e 's/@''GNULIB_MDA_MEMCCPY''@/$(GL_GNULIB_MDA_MEMCCPY)/g' \\\n\t      -e 's/@''GNULIB_MDA_STRDUP''@/$(GL_GNULIB_MDA_STRDUP)/g' \\\n\t      < $(srcdir)/string.in.h | \\\n\t  sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \\\n\t      -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \\\n\t      -e 's|@''HAVE_FFSLL''@|$(HAVE_FFSLL)|g' \\\n\t      -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \\\n\t      -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \\\n\t      -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \\\n\t      -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \\\n\t      -e 's|@''HAVE_RAWMEMCHR''@|$(HAVE_RAWMEMCHR)|g' \\\n\t      -e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \\\n\t      -e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \\\n\t      -e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \\\n\t      -e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \\\n\t      -e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \\\n\t      -e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \\\n\t      -e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \\\n\t      -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \\\n\t      -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \\\n\t      -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \\\n\t      -e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \\\n\t      -e 's|@''HAVE_STRERRORNAME_NP''@|$(HAVE_STRERRORNAME_NP)|g' \\\n\t      -e 's|@''HAVE_SIGABBREV_NP''@|$(HAVE_SIGABBREV_NP)|g' \\\n\t      -e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \\\n\t      -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \\\n\t      -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \\\n\t      -e 's|@''REPLACE_FFSLL''@|$(REPLACE_FFSLL)|g' \\\n\t      -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \\\n\t      -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \\\n\t      -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \\\n\t      -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \\\n\t      -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \\\n\t      -e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \\\n\t      -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \\\n\t      -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \\\n\t      -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \\\n\t      -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \\\n\t      -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \\\n\t      -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \\\n\t      -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \\\n\t      -e 's|@''REPLACE_STRERRORNAME_NP''@|$(REPLACE_STRERRORNAME_NP)|g' \\\n\t      -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \\\n\t      -e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \\\n\t      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \\\n\t      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \\\n\t      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \\\n\t      < $(srcdir)/string.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += string.h string.h-t\n\nEXTRA_DIST += string.in.h\n\n## end   gnulib module string\n\n## begin gnulib module strnlen\n\n\nEXTRA_DIST += strnlen.c\n\nEXTRA_libgnu_a_SOURCES += strnlen.c\n\n## end   gnulib module strnlen\n\n## begin gnulib module strnlen1\n\nlibgnu_a_SOURCES += strnlen1.h strnlen1.c\n\n## end   gnulib module strnlen1\n\n## begin gnulib module sys_types\n\nBUILT_SOURCES += sys/types.h\n\n# We need the following in order to create <sys/types.h> when the system\n# doesn't have one that works with the given compiler.\nsys/types.h: sys_types.in.h $(top_builddir)/config.status\n\t$(AM_V_at)$(MKDIR_P) sys\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_SYS_TYPES_H''@|$(NEXT_SYS_TYPES_H)|g' \\\n\t      -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \\\n\t      -e 's|@''WINDOWS_STAT_INODES''@|$(WINDOWS_STAT_INODES)|g' \\\n\t      < $(srcdir)/sys_types.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += sys/types.h sys/types.h-t\n\nEXTRA_DIST += sys_types.in.h\n\n## end   gnulib module sys_types\n\n## begin gnulib module threadlib\n\nlibgnu_a_SOURCES += glthread/threadlib.c\n\n## end   gnulib module threadlib\n\n## begin gnulib module unistd\n\nBUILT_SOURCES += unistd.h\nlibgnu_a_SOURCES += unistd.c\n\n# We need the following in order to create an empty placeholder for\n# <unistd.h> when the system doesn't have one.\nunistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \\\n\t      -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \\\n\t      -e 's/@''GNULIB_ACCESS''@/$(GL_GNULIB_ACCESS)/g' \\\n\t      -e 's/@''GNULIB_CHDIR''@/$(GL_GNULIB_CHDIR)/g' \\\n\t      -e 's/@''GNULIB_CHOWN''@/$(GL_GNULIB_CHOWN)/g' \\\n\t      -e 's/@''GNULIB_CLOSE''@/$(GL_GNULIB_CLOSE)/g' \\\n\t      -e 's/@''GNULIB_COPY_FILE_RANGE''@/$(GL_GNULIB_COPY_FILE_RANGE)/g' \\\n\t      -e 's/@''GNULIB_DUP''@/$(GL_GNULIB_DUP)/g' \\\n\t      -e 's/@''GNULIB_DUP2''@/$(GL_GNULIB_DUP2)/g' \\\n\t      -e 's/@''GNULIB_DUP3''@/$(GL_GNULIB_DUP3)/g' \\\n\t      -e 's/@''GNULIB_ENVIRON''@/$(GL_GNULIB_ENVIRON)/g' \\\n\t      -e 's/@''GNULIB_EUIDACCESS''@/$(GL_GNULIB_EUIDACCESS)/g' \\\n\t      -e 's/@''GNULIB_EXECL''@/$(GL_GNULIB_EXECL)/g' \\\n\t      -e 's/@''GNULIB_EXECLE''@/$(GL_GNULIB_EXECLE)/g' \\\n\t      -e 's/@''GNULIB_EXECLP''@/$(GL_GNULIB_EXECLP)/g' \\\n\t      -e 's/@''GNULIB_EXECV''@/$(GL_GNULIB_EXECV)/g' \\\n\t      -e 's/@''GNULIB_EXECVE''@/$(GL_GNULIB_EXECVE)/g' \\\n\t      -e 's/@''GNULIB_EXECVP''@/$(GL_GNULIB_EXECVP)/g' \\\n\t      -e 's/@''GNULIB_EXECVPE''@/$(GL_GNULIB_EXECVPE)/g' \\\n\t      -e 's/@''GNULIB_FACCESSAT''@/$(GL_GNULIB_FACCESSAT)/g' \\\n\t      -e 's/@''GNULIB_FCHDIR''@/$(GL_GNULIB_FCHDIR)/g' \\\n\t      -e 's/@''GNULIB_FCHOWNAT''@/$(GL_GNULIB_FCHOWNAT)/g' \\\n\t      -e 's/@''GNULIB_FDATASYNC''@/$(GL_GNULIB_FDATASYNC)/g' \\\n\t      -e 's/@''GNULIB_FSYNC''@/$(GL_GNULIB_FSYNC)/g' \\\n\t      -e 's/@''GNULIB_FTRUNCATE''@/$(GL_GNULIB_FTRUNCATE)/g' \\\n\t      -e 's/@''GNULIB_GETCWD''@/$(GL_GNULIB_GETCWD)/g' \\\n\t      -e 's/@''GNULIB_GETDOMAINNAME''@/$(GL_GNULIB_GETDOMAINNAME)/g' \\\n\t      -e 's/@''GNULIB_GETDTABLESIZE''@/$(GL_GNULIB_GETDTABLESIZE)/g' \\\n\t      -e 's/@''GNULIB_GETENTROPY''@/$(GL_GNULIB_GETENTROPY)/g' \\\n\t      -e 's/@''GNULIB_GETGROUPS''@/$(GL_GNULIB_GETGROUPS)/g' \\\n\t      -e 's/@''GNULIB_GETHOSTNAME''@/$(GL_GNULIB_GETHOSTNAME)/g' \\\n\t      -e 's/@''GNULIB_GETLOGIN''@/$(GL_GNULIB_GETLOGIN)/g' \\\n\t      -e 's/@''GNULIB_GETLOGIN_R''@/$(GL_GNULIB_GETLOGIN_R)/g' \\\n\t      -e 's/@''GNULIB_GETOPT_POSIX''@/$(GL_GNULIB_GETOPT_POSIX)/g' \\\n\t      -e 's/@''GNULIB_GETPAGESIZE''@/$(GL_GNULIB_GETPAGESIZE)/g' \\\n\t      -e 's/@''GNULIB_GETPASS''@/$(GL_GNULIB_GETPASS)/g' \\\n\t      -e 's/@''GNULIB_GETUSERSHELL''@/$(GL_GNULIB_GETUSERSHELL)/g' \\\n\t      -e 's/@''GNULIB_GROUP_MEMBER''@/$(GL_GNULIB_GROUP_MEMBER)/g' \\\n\t      -e 's/@''GNULIB_ISATTY''@/$(GL_GNULIB_ISATTY)/g' \\\n\t      -e 's/@''GNULIB_LCHOWN''@/$(GL_GNULIB_LCHOWN)/g' \\\n\t      -e 's/@''GNULIB_LINK''@/$(GL_GNULIB_LINK)/g' \\\n\t      -e 's/@''GNULIB_LINKAT''@/$(GL_GNULIB_LINKAT)/g' \\\n\t      -e 's/@''GNULIB_LSEEK''@/$(GL_GNULIB_LSEEK)/g' \\\n\t      -e 's/@''GNULIB_PIPE''@/$(GL_GNULIB_PIPE)/g' \\\n\t      -e 's/@''GNULIB_PIPE2''@/$(GL_GNULIB_PIPE2)/g' \\\n\t      -e 's/@''GNULIB_PREAD''@/$(GL_GNULIB_PREAD)/g' \\\n\t      -e 's/@''GNULIB_PWRITE''@/$(GL_GNULIB_PWRITE)/g' \\\n\t      -e 's/@''GNULIB_READ''@/$(GL_GNULIB_READ)/g' \\\n\t      -e 's/@''GNULIB_READLINK''@/$(GL_GNULIB_READLINK)/g' \\\n\t      -e 's/@''GNULIB_READLINKAT''@/$(GL_GNULIB_READLINKAT)/g' \\\n\t      -e 's/@''GNULIB_RMDIR''@/$(GL_GNULIB_RMDIR)/g' \\\n\t      -e 's/@''GNULIB_SETHOSTNAME''@/$(GL_GNULIB_SETHOSTNAME)/g' \\\n\t      -e 's/@''GNULIB_SLEEP''@/$(GL_GNULIB_SLEEP)/g' \\\n\t      -e 's/@''GNULIB_SYMLINK''@/$(GL_GNULIB_SYMLINK)/g' \\\n\t      -e 's/@''GNULIB_SYMLINKAT''@/$(GL_GNULIB_SYMLINKAT)/g' \\\n\t      -e 's/@''GNULIB_TRUNCATE''@/$(GL_GNULIB_TRUNCATE)/g' \\\n\t      -e 's/@''GNULIB_TTYNAME_R''@/$(GL_GNULIB_TTYNAME_R)/g' \\\n\t      -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GL_GNULIB_UNISTD_H_GETOPT)/g' \\\n\t      -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GL_GNULIB_UNISTD_H_NONBLOCKING)/g' \\\n\t      -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GL_GNULIB_UNISTD_H_SIGPIPE)/g' \\\n\t      -e 's/@''GNULIB_UNLINK''@/$(GL_GNULIB_UNLINK)/g' \\\n\t      -e 's/@''GNULIB_UNLINKAT''@/$(GL_GNULIB_UNLINKAT)/g' \\\n\t      -e 's/@''GNULIB_USLEEP''@/$(GL_GNULIB_USLEEP)/g' \\\n\t      -e 's/@''GNULIB_WRITE''@/$(GL_GNULIB_WRITE)/g' \\\n\t      -e 's/@''GNULIB_MDA_ACCESS''@/$(GL_GNULIB_MDA_ACCESS)/g' \\\n\t      -e 's/@''GNULIB_MDA_CHDIR''@/$(GL_GNULIB_MDA_CHDIR)/g' \\\n\t      -e 's/@''GNULIB_MDA_CLOSE''@/$(GL_GNULIB_MDA_CLOSE)/g' \\\n\t      -e 's/@''GNULIB_MDA_DUP''@/$(GL_GNULIB_MDA_DUP)/g' \\\n\t      -e 's/@''GNULIB_MDA_DUP2''@/$(GL_GNULIB_MDA_DUP2)/g' \\\n\t      -e 's/@''GNULIB_MDA_EXECL''@/$(GL_GNULIB_MDA_EXECL)/g' \\\n\t      -e 's/@''GNULIB_MDA_EXECLE''@/$(GL_GNULIB_MDA_EXECLE)/g' \\\n\t      -e 's/@''GNULIB_MDA_EXECLP''@/$(GL_GNULIB_MDA_EXECLP)/g' \\\n\t      -e 's/@''GNULIB_MDA_EXECV''@/$(GL_GNULIB_MDA_EXECV)/g' \\\n\t      -e 's/@''GNULIB_MDA_EXECVE''@/$(GL_GNULIB_MDA_EXECVE)/g' \\\n\t      -e 's/@''GNULIB_MDA_EXECVP''@/$(GL_GNULIB_MDA_EXECVP)/g' \\\n\t      -e 's/@''GNULIB_MDA_EXECVPE''@/$(GL_GNULIB_MDA_EXECVPE)/g' \\\n\t      -e 's/@''GNULIB_MDA_GETCWD''@/$(GL_GNULIB_MDA_GETCWD)/g' \\\n\t      -e 's/@''GNULIB_MDA_GETPID''@/$(GL_GNULIB_MDA_GETPID)/g' \\\n\t      -e 's/@''GNULIB_MDA_ISATTY''@/$(GL_GNULIB_MDA_ISATTY)/g' \\\n\t      -e 's/@''GNULIB_MDA_LSEEK''@/$(GL_GNULIB_MDA_LSEEK)/g' \\\n\t      -e 's/@''GNULIB_MDA_READ''@/$(GL_GNULIB_MDA_READ)/g' \\\n\t      -e 's/@''GNULIB_MDA_RMDIR''@/$(GL_GNULIB_MDA_RMDIR)/g' \\\n\t      -e 's/@''GNULIB_MDA_SWAB''@/$(GL_GNULIB_MDA_SWAB)/g' \\\n\t      -e 's/@''GNULIB_MDA_UNLINK''@/$(GL_GNULIB_MDA_UNLINK)/g' \\\n\t      -e 's/@''GNULIB_MDA_WRITE''@/$(GL_GNULIB_MDA_WRITE)/g' \\\n\t      < $(srcdir)/unistd.in.h | \\\n\t  sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \\\n\t      -e 's|@''HAVE_COPY_FILE_RANGE''@|$(HAVE_COPY_FILE_RANGE)|g' \\\n\t      -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \\\n\t      -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|g' \\\n\t      -e 's|@''HAVE_EXECVPE''@|$(HAVE_EXECVPE)|g' \\\n\t      -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \\\n\t      -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \\\n\t      -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \\\n\t      -e 's|@''HAVE_FDATASYNC''@|$(HAVE_FDATASYNC)|g' \\\n\t      -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \\\n\t      -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \\\n\t      -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \\\n\t      -e 's|@''HAVE_GETENTROPY''@|$(HAVE_GETENTROPY)|g' \\\n\t      -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \\\n\t      -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \\\n\t      -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \\\n\t      -e 's|@''HAVE_GETPASS''@|$(HAVE_GETPASS)|g' \\\n\t      -e 's|@''HAVE_GROUP_MEMBER''@|$(HAVE_GROUP_MEMBER)|g' \\\n\t      -e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \\\n\t      -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \\\n\t      -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \\\n\t      -e 's|@''HAVE_PIPE''@|$(HAVE_PIPE)|g' \\\n\t      -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \\\n\t      -e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \\\n\t      -e 's|@''HAVE_PWRITE''@|$(HAVE_PWRITE)|g' \\\n\t      -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \\\n\t      -e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \\\n\t      -e 's|@''HAVE_SETHOSTNAME''@|$(HAVE_SETHOSTNAME)|g' \\\n\t      -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \\\n\t      -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \\\n\t      -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \\\n\t      -e 's|@''HAVE_UNLINKAT''@|$(HAVE_UNLINKAT)|g' \\\n\t      -e 's|@''HAVE_USLEEP''@|$(HAVE_USLEEP)|g' \\\n\t      -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \\\n\t      -e 's|@''HAVE_DECL_EXECVPE''@|$(HAVE_DECL_EXECVPE)|g' \\\n\t      -e 's|@''HAVE_DECL_FCHDIR''@|$(HAVE_DECL_FCHDIR)|g' \\\n\t      -e 's|@''HAVE_DECL_FDATASYNC''@|$(HAVE_DECL_FDATASYNC)|g' \\\n\t      -e 's|@''HAVE_DECL_GETDOMAINNAME''@|$(HAVE_DECL_GETDOMAINNAME)|g' \\\n\t      -e 's|@''HAVE_DECL_GETLOGIN''@|$(HAVE_DECL_GETLOGIN)|g' \\\n\t      -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \\\n\t      -e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \\\n\t      -e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|g' \\\n\t      -e 's|@''HAVE_DECL_SETHOSTNAME''@|$(HAVE_DECL_SETHOSTNAME)|g' \\\n\t      -e 's|@''HAVE_DECL_TRUNCATE''@|$(HAVE_DECL_TRUNCATE)|g' \\\n\t      -e 's|@''HAVE_DECL_TTYNAME_R''@|$(HAVE_DECL_TTYNAME_R)|g' \\\n\t      -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \\\n\t      -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \\\n\t  | \\\n\t  sed -e 's|@''REPLACE_ACCESS''@|$(REPLACE_ACCESS)|g' \\\n\t      -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \\\n\t      -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \\\n\t      -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \\\n\t      -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \\\n\t      -e 's|@''REPLACE_EXECL''@|$(REPLACE_EXECL)|g' \\\n\t      -e 's|@''REPLACE_EXECLE''@|$(REPLACE_EXECLE)|g' \\\n\t      -e 's|@''REPLACE_EXECLP''@|$(REPLACE_EXECLP)|g' \\\n\t      -e 's|@''REPLACE_EXECV''@|$(REPLACE_EXECV)|g' \\\n\t      -e 's|@''REPLACE_EXECVE''@|$(REPLACE_EXECVE)|g' \\\n\t      -e 's|@''REPLACE_EXECVP''@|$(REPLACE_EXECVP)|g' \\\n\t      -e 's|@''REPLACE_EXECVPE''@|$(REPLACE_EXECVPE)|g' \\\n\t      -e 's|@''REPLACE_FACCESSAT''@|$(REPLACE_FACCESSAT)|g' \\\n\t      -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \\\n\t      -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \\\n\t      -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \\\n\t      -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \\\n\t      -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \\\n\t      -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \\\n\t      -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \\\n\t      -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \\\n\t      -e 's|@''REPLACE_GETPASS''@|$(REPLACE_GETPASS)|g' \\\n\t      -e 's|@''REPLACE_ISATTY''@|$(REPLACE_ISATTY)|g' \\\n\t      -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \\\n\t      -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \\\n\t      -e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \\\n\t      -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \\\n\t      -e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \\\n\t      -e 's|@''REPLACE_PWRITE''@|$(REPLACE_PWRITE)|g' \\\n\t      -e 's|@''REPLACE_READ''@|$(REPLACE_READ)|g' \\\n\t      -e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \\\n\t      -e 's|@''REPLACE_READLINKAT''@|$(REPLACE_READLINKAT)|g' \\\n\t      -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \\\n\t      -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \\\n\t      -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \\\n\t      -e 's|@''REPLACE_SYMLINKAT''@|$(REPLACE_SYMLINKAT)|g' \\\n\t      -e 's|@''REPLACE_TRUNCATE''@|$(REPLACE_TRUNCATE)|g' \\\n\t      -e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \\\n\t      -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \\\n\t      -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \\\n\t      -e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \\\n\t      -e 's|@''REPLACE_WRITE''@|$(REPLACE_WRITE)|g' \\\n\t      -e 's|@''UNISTD_H_HAVE_SYS_RANDOM_H''@|$(UNISTD_H_HAVE_SYS_RANDOM_H)|g' \\\n\t      -e 's|@''UNISTD_H_HAVE_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \\\n\t      -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \\\n\t      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \\\n\t      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \\\n\t      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += unistd.h unistd.h-t\n\nEXTRA_DIST += unistd.in.h\n\n## end   gnulib module unistd\n\n## begin gnulib module verify\n\n\nEXTRA_DIST += verify.h\n\n## end   gnulib module verify\n\n## begin gnulib module wchar\n\nBUILT_SOURCES += wchar.h\n\n# We need the following in order to create <wchar.h> when the system\n# version does not work standalone.\nwchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \\\n\t      -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \\\n\t      -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \\\n\t      -e 's/@''HAVE_CRTDEFS_H''@/$(HAVE_CRTDEFS_H)/g' \\\n\t      -e 's/@''GNULIBHEADERS_OVERRIDE_WINT_T''@/$(GNULIBHEADERS_OVERRIDE_WINT_T)/g' \\\n\t      -e 's/@''GNULIB_BTOWC''@/$(GL_GNULIB_BTOWC)/g' \\\n\t      -e 's/@''GNULIB_WCTOB''@/$(GL_GNULIB_WCTOB)/g' \\\n\t      -e 's/@''GNULIB_MBSINIT''@/$(GL_GNULIB_MBSINIT)/g' \\\n\t      -e 's/@''GNULIB_MBRTOWC''@/$(GL_GNULIB_MBRTOWC)/g' \\\n\t      -e 's/@''GNULIB_MBRLEN''@/$(GL_GNULIB_MBRLEN)/g' \\\n\t      -e 's/@''GNULIB_MBSRTOWCS''@/$(GL_GNULIB_MBSRTOWCS)/g' \\\n\t      -e 's/@''GNULIB_MBSNRTOWCS''@/$(GL_GNULIB_MBSNRTOWCS)/g' \\\n\t      -e 's/@''GNULIB_WCRTOMB''@/$(GL_GNULIB_WCRTOMB)/g' \\\n\t      -e 's/@''GNULIB_WCSRTOMBS''@/$(GL_GNULIB_WCSRTOMBS)/g' \\\n\t      -e 's/@''GNULIB_WCSNRTOMBS''@/$(GL_GNULIB_WCSNRTOMBS)/g' \\\n\t      -e 's/@''GNULIB_WCWIDTH''@/$(GL_GNULIB_WCWIDTH)/g' \\\n\t      -e 's/@''GNULIB_WMEMCHR''@/$(GL_GNULIB_WMEMCHR)/g' \\\n\t      -e 's/@''GNULIB_WMEMCMP''@/$(GL_GNULIB_WMEMCMP)/g' \\\n\t      -e 's/@''GNULIB_WMEMCPY''@/$(GL_GNULIB_WMEMCPY)/g' \\\n\t      -e 's/@''GNULIB_WMEMMOVE''@/$(GL_GNULIB_WMEMMOVE)/g' \\\n\t      -e 's/@''GNULIB_WMEMPCPY''@/$(GL_GNULIB_WMEMPCPY)/g' \\\n\t      -e 's/@''GNULIB_WMEMSET''@/$(GL_GNULIB_WMEMSET)/g' \\\n\t      -e 's/@''GNULIB_WCSLEN''@/$(GL_GNULIB_WCSLEN)/g' \\\n\t      -e 's/@''GNULIB_WCSNLEN''@/$(GL_GNULIB_WCSNLEN)/g' \\\n\t      -e 's/@''GNULIB_WCSCPY''@/$(GL_GNULIB_WCSCPY)/g' \\\n\t      -e 's/@''GNULIB_WCPCPY''@/$(GL_GNULIB_WCPCPY)/g' \\\n\t      -e 's/@''GNULIB_WCSNCPY''@/$(GL_GNULIB_WCSNCPY)/g' \\\n\t      -e 's/@''GNULIB_WCPNCPY''@/$(GL_GNULIB_WCPNCPY)/g' \\\n\t      -e 's/@''GNULIB_WCSCAT''@/$(GL_GNULIB_WCSCAT)/g' \\\n\t      -e 's/@''GNULIB_WCSNCAT''@/$(GL_GNULIB_WCSNCAT)/g' \\\n\t      -e 's/@''GNULIB_WCSCMP''@/$(GL_GNULIB_WCSCMP)/g' \\\n\t      -e 's/@''GNULIB_WCSNCMP''@/$(GL_GNULIB_WCSNCMP)/g' \\\n\t      -e 's/@''GNULIB_WCSCASECMP''@/$(GL_GNULIB_WCSCASECMP)/g' \\\n\t      -e 's/@''GNULIB_WCSNCASECMP''@/$(GL_GNULIB_WCSNCASECMP)/g' \\\n\t      -e 's/@''GNULIB_WCSCOLL''@/$(GL_GNULIB_WCSCOLL)/g' \\\n\t      -e 's/@''GNULIB_WCSXFRM''@/$(GL_GNULIB_WCSXFRM)/g' \\\n\t      -e 's/@''GNULIB_WCSDUP''@/$(GL_GNULIB_WCSDUP)/g' \\\n\t      -e 's/@''GNULIB_WCSCHR''@/$(GL_GNULIB_WCSCHR)/g' \\\n\t      -e 's/@''GNULIB_WCSRCHR''@/$(GL_GNULIB_WCSRCHR)/g' \\\n\t      -e 's/@''GNULIB_WCSCSPN''@/$(GL_GNULIB_WCSCSPN)/g' \\\n\t      -e 's/@''GNULIB_WCSSPN''@/$(GL_GNULIB_WCSSPN)/g' \\\n\t      -e 's/@''GNULIB_WCSPBRK''@/$(GL_GNULIB_WCSPBRK)/g' \\\n\t      -e 's/@''GNULIB_WCSSTR''@/$(GL_GNULIB_WCSSTR)/g' \\\n\t      -e 's/@''GNULIB_WCSTOK''@/$(GL_GNULIB_WCSTOK)/g' \\\n\t      -e 's/@''GNULIB_WCSWIDTH''@/$(GL_GNULIB_WCSWIDTH)/g' \\\n\t      -e 's/@''GNULIB_WCSFTIME''@/$(GL_GNULIB_WCSFTIME)/g' \\\n\t      -e 's/@''GNULIB_MDA_WCSDUP''@/$(GL_GNULIB_MDA_WCSDUP)/g' \\\n\t      < $(srcdir)/wchar.in.h | \\\n\t  sed -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \\\n\t      -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \\\n\t      -e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \\\n\t      -e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \\\n\t      -e 's|@''HAVE_MBRLEN''@|$(HAVE_MBRLEN)|g' \\\n\t      -e 's|@''HAVE_MBSRTOWCS''@|$(HAVE_MBSRTOWCS)|g' \\\n\t      -e 's|@''HAVE_MBSNRTOWCS''@|$(HAVE_MBSNRTOWCS)|g' \\\n\t      -e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \\\n\t      -e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \\\n\t      -e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \\\n\t      -e 's|@''HAVE_WMEMCHR''@|$(HAVE_WMEMCHR)|g' \\\n\t      -e 's|@''HAVE_WMEMCMP''@|$(HAVE_WMEMCMP)|g' \\\n\t      -e 's|@''HAVE_WMEMCPY''@|$(HAVE_WMEMCPY)|g' \\\n\t      -e 's|@''HAVE_WMEMMOVE''@|$(HAVE_WMEMMOVE)|g' \\\n\t      -e 's|@''HAVE_WMEMPCPY''@|$(HAVE_WMEMPCPY)|g' \\\n\t      -e 's|@''HAVE_WMEMSET''@|$(HAVE_WMEMSET)|g' \\\n\t      -e 's|@''HAVE_WCSLEN''@|$(HAVE_WCSLEN)|g' \\\n\t      -e 's|@''HAVE_WCSNLEN''@|$(HAVE_WCSNLEN)|g' \\\n\t      -e 's|@''HAVE_WCSCPY''@|$(HAVE_WCSCPY)|g' \\\n\t      -e 's|@''HAVE_WCPCPY''@|$(HAVE_WCPCPY)|g' \\\n\t      -e 's|@''HAVE_WCSNCPY''@|$(HAVE_WCSNCPY)|g' \\\n\t      -e 's|@''HAVE_WCPNCPY''@|$(HAVE_WCPNCPY)|g' \\\n\t      -e 's|@''HAVE_WCSCAT''@|$(HAVE_WCSCAT)|g' \\\n\t      -e 's|@''HAVE_WCSNCAT''@|$(HAVE_WCSNCAT)|g' \\\n\t      -e 's|@''HAVE_WCSCMP''@|$(HAVE_WCSCMP)|g' \\\n\t      -e 's|@''HAVE_WCSNCMP''@|$(HAVE_WCSNCMP)|g' \\\n\t      -e 's|@''HAVE_WCSCASECMP''@|$(HAVE_WCSCASECMP)|g' \\\n\t      -e 's|@''HAVE_WCSNCASECMP''@|$(HAVE_WCSNCASECMP)|g' \\\n\t      -e 's|@''HAVE_WCSCOLL''@|$(HAVE_WCSCOLL)|g' \\\n\t      -e 's|@''HAVE_WCSXFRM''@|$(HAVE_WCSXFRM)|g' \\\n\t      -e 's|@''HAVE_WCSDUP''@|$(HAVE_WCSDUP)|g' \\\n\t      -e 's|@''HAVE_WCSCHR''@|$(HAVE_WCSCHR)|g' \\\n\t      -e 's|@''HAVE_WCSRCHR''@|$(HAVE_WCSRCHR)|g' \\\n\t      -e 's|@''HAVE_WCSCSPN''@|$(HAVE_WCSCSPN)|g' \\\n\t      -e 's|@''HAVE_WCSSPN''@|$(HAVE_WCSSPN)|g' \\\n\t      -e 's|@''HAVE_WCSPBRK''@|$(HAVE_WCSPBRK)|g' \\\n\t      -e 's|@''HAVE_WCSSTR''@|$(HAVE_WCSSTR)|g' \\\n\t      -e 's|@''HAVE_WCSTOK''@|$(HAVE_WCSTOK)|g' \\\n\t      -e 's|@''HAVE_WCSWIDTH''@|$(HAVE_WCSWIDTH)|g' \\\n\t      -e 's|@''HAVE_WCSFTIME''@|$(HAVE_WCSFTIME)|g' \\\n\t      -e 's|@''HAVE_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \\\n\t      -e 's|@''HAVE_DECL_WCSDUP''@|$(HAVE_DECL_WCSDUP)|g' \\\n\t      -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \\\n\t  | \\\n\t  sed -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \\\n\t      -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \\\n\t      -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \\\n\t      -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \\\n\t      -e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \\\n\t      -e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \\\n\t      -e 's|@''REPLACE_MBSRTOWCS''@|$(REPLACE_MBSRTOWCS)|g' \\\n\t      -e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \\\n\t      -e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \\\n\t      -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \\\n\t      -e 's|@''REPLACE_WCSNRTOMBS''@|$(REPLACE_WCSNRTOMBS)|g' \\\n\t      -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \\\n\t      -e 's|@''REPLACE_WCSWIDTH''@|$(REPLACE_WCSWIDTH)|g' \\\n\t      -e 's|@''REPLACE_WCSFTIME''@|$(REPLACE_WCSFTIME)|g' \\\n\t      -e 's|@''REPLACE_WCSTOK''@|$(REPLACE_WCSTOK)|g' \\\n\t      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \\\n\t      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \\\n\t      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += wchar.h wchar.h-t\n\nEXTRA_DIST += wchar.in.h\n\n## end   gnulib module wchar\n\n## begin gnulib module wcrtomb\n\n\nEXTRA_DIST += wcrtomb.c\n\nEXTRA_libgnu_a_SOURCES += wcrtomb.c\n\n## end   gnulib module wcrtomb\n\n## begin gnulib module wctype-h\n\nBUILT_SOURCES += wctype.h\nlibgnu_a_SOURCES += wctype-h.c\n\n# We need the following in order to create <wctype.h> when the system\n# doesn't have one that works with the given compiler.\nwctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)\n\t$(AM_V_GEN)rm -f $@-t $@ && \\\n\t{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \\\n\t  sed -e 's|@''GUARD_PREFIX''@|GL|g' \\\n\t      -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \\\n\t      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \\\n\t      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \\\n\t      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \\\n\t      -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \\\n\t      -e 's/@''HAVE_CRTDEFS_H''@/$(HAVE_CRTDEFS_H)/g' \\\n\t      -e 's/@''GNULIBHEADERS_OVERRIDE_WINT_T''@/$(GNULIBHEADERS_OVERRIDE_WINT_T)/g' \\\n\t      -e 's/@''GNULIB_ISWBLANK''@/$(GL_GNULIB_ISWBLANK)/g' \\\n\t      -e 's/@''GNULIB_ISWDIGIT''@/$(GL_GNULIB_ISWDIGIT)/g' \\\n\t      -e 's/@''GNULIB_ISWXDIGIT''@/$(GL_GNULIB_ISWXDIGIT)/g' \\\n\t      -e 's/@''GNULIB_WCTYPE''@/$(GL_GNULIB_WCTYPE)/g' \\\n\t      -e 's/@''GNULIB_ISWCTYPE''@/$(GL_GNULIB_ISWCTYPE)/g' \\\n\t      -e 's/@''GNULIB_WCTRANS''@/$(GL_GNULIB_WCTRANS)/g' \\\n\t      -e 's/@''GNULIB_TOWCTRANS''@/$(GL_GNULIB_TOWCTRANS)/g' \\\n\t      -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \\\n\t      -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \\\n\t      -e 's/@''HAVE_WCTYPE_T''@/$(HAVE_WCTYPE_T)/g' \\\n\t      -e 's/@''HAVE_WCTRANS_T''@/$(HAVE_WCTRANS_T)/g' \\\n\t      -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \\\n\t      -e 's/@''REPLACE_ISWBLANK''@/$(REPLACE_ISWBLANK)/g' \\\n\t      -e 's/@''REPLACE_ISWDIGIT''@/$(REPLACE_ISWDIGIT)/g' \\\n\t      -e 's/@''REPLACE_ISWXDIGIT''@/$(REPLACE_ISWXDIGIT)/g' \\\n\t      -e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \\\n\t      -e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \\\n\t      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \\\n\t      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \\\n\t      < $(srcdir)/wctype.in.h; \\\n\t} > $@-t && \\\n\tmv $@-t $@\nMOSTLYCLEANFILES += wctype.h wctype.h-t\n\nEXTRA_DIST += wctype.in.h\n\n## end   gnulib module wctype-h\n\n## begin gnulib module windows-mutex\n\n\nEXTRA_DIST += windows-initguard.h windows-mutex.c windows-mutex.h\n\nEXTRA_libgnu_a_SOURCES += windows-mutex.c\n\n## end   gnulib module windows-mutex\n\n## begin gnulib module windows-once\n\n\nEXTRA_DIST += windows-once.c windows-once.h\n\nEXTRA_libgnu_a_SOURCES += windows-once.c\n\n## end   gnulib module windows-once\n\n## begin gnulib module windows-recmutex\n\n\nEXTRA_DIST += windows-initguard.h windows-recmutex.c windows-recmutex.h\n\nEXTRA_libgnu_a_SOURCES += windows-recmutex.c\n\n## end   gnulib module windows-recmutex\n\n## begin gnulib module windows-rwlock\n\n\nEXTRA_DIST += windows-initguard.h windows-rwlock.c windows-rwlock.h\n\nEXTRA_libgnu_a_SOURCES += windows-rwlock.c\n\n## end   gnulib module windows-rwlock\n\n## begin gnulib module wmemchr\n\n\nEXTRA_DIST += wmemchr-impl.h wmemchr.c\n\nEXTRA_libgnu_a_SOURCES += wmemchr.c\n\n## end   gnulib module wmemchr\n\n## begin gnulib module wmempcpy\n\n\nEXTRA_DIST += wmempcpy.c\n\nEXTRA_libgnu_a_SOURCES += wmempcpy.c\n\n## end   gnulib module wmempcpy\n\n\nmostlyclean-local: mostlyclean-generic\n\t@for dir in '' $(MOSTLYCLEANDIRS); do \\\n\t  if test -n \"$$dir\" && test -d $$dir; then \\\n\t    echo \"rmdir $$dir\"; rmdir $$dir; \\\n\t  fi; \\\n\tdone; \\\n\t:\n"
  },
  {
    "path": "gnulib/README.md",
    "content": "# README for `gnulib/` directory\n\nThe files in this directory were taken from [the GNU Portability Library\n(Gnulib)](https://www.gnu.org/software/gnulib/).\n\nSee \"1. Bread Overview\" and \"3. Invoking gnulib-tool\" in [the GNU Gnulib\ndocuments](https://www.gnu.org/software/gnulib/manual/gnulib.html) for more details.\n\n## Checking out Gnulib\n\n```\n$ git clone git://git.sv.gnu.org/gnulib.git\n```\n\nIn the following description, the directory where Gnulib is checked out is\ncalled `$GNULIB_DIR`. And the root directory of the Universal Ctags is called\n`$CTAGS_DIR`.\n\n## Importing the first module\n\nThe first module (`regex`) was imported by the following command into the\ndirectory `gnulib/` without modifying `.gitignore`.\n\n```\n$ cd $CTAGS_DIR\n$ gnulib-tool --source-base=gnulib --no-vc-files --import regex\n```\n\nThe options used are saved in `m4/gnulib-cache.m4`.\n\n## Updating the modules\n\n`-add-import` without module names updates imported modules.\n\n```\n$ cd $GNULIB_DIR\n$ git pull\n$ cd $CTAGS_DIR\n$ gnulib-tool --add-import\n```\n\n## Importing additional modules\n\n```\n$ gnulib-tool --add-import foo bar ...\n```\n"
  },
  {
    "path": "gnulib/_Noreturn.h",
    "content": "/* A C macro for declaring that a function does not return.\n   Copyright (C) 2011-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _Noreturn\n# if (defined __cplusplus \\\n      && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \\\n          || (defined _MSC_VER && 1900 <= _MSC_VER)) \\\n      && 0)\n    /* [[noreturn]] is not practically usable, because with it the syntax\n         extern _Noreturn void func (...);\n       would not be valid; such a declaration would only be valid with 'extern'\n       and '_Noreturn' swapped, or without the 'extern' keyword.  However, some\n       AIX system header files and several gnulib header files use precisely\n       this syntax with 'extern'.  */\n#  define _Noreturn [[noreturn]]\n# elif ((!defined __cplusplus || defined __clang__) \\\n        && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \\\n            || (!defined __STRICT_ANSI__ \\\n                && (__4 < __GNUC__ + (7 <= __GNUC_MINOR__) \\\n                    || (defined __apple_build_version__ \\\n                        ? 6000000 <= __apple_build_version__ \\\n                        : 3 < __clang_major__ + (5 <= __clang_minor__))))))\n   /* _Noreturn works as-is.  */\n# elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \\\n        || 0x5110 <= __SUNPRO_C)\n#  define _Noreturn __attribute__ ((__noreturn__))\n# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)\n#  define _Noreturn __declspec (noreturn)\n# else\n#  define _Noreturn\n# endif\n#endif\n"
  },
  {
    "path": "gnulib/alloca.in.h",
    "content": "/* Memory allocation on the stack.\n\n   Copyright (C) 1995, 1999, 2001-2004, 2006-2021 Free Software Foundation,\n   Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H\n   means there is a real alloca function.  */\n#ifndef _GL_ALLOCA_H\n#define _GL_ALLOCA_H\n\n/* alloca (N) returns a pointer to N bytes of memory\n   allocated on the stack, which will last until the function returns.\n   Use of alloca should be avoided:\n     - inside arguments of function calls - undefined behaviour,\n     - in inline functions - the allocation may actually last until the\n       calling function returns,\n     - for huge N (say, N >= 65536) - you never know how large (or small)\n       the stack is, and when the stack cannot fulfill the memory allocation\n       request, the program just crashes.\n */\n\n#ifndef alloca\n  /* Some version of mingw have an <alloca.h> that causes trouble when\n     included after 'alloca' gets defined as a macro.  As a workaround,\n     include this <alloca.h> first and define 'alloca' as a macro afterwards\n     if needed.  */\n# if defined __GNUC__ && (defined _WIN32 && ! defined __CYGWIN__) && @HAVE_ALLOCA_H@\n#  include_next <alloca.h>\n# endif\n#endif\n#ifndef alloca\n# if defined __GNUC__ || (__clang_major__ >= 4)\n#  define alloca __builtin_alloca\n# elif defined _AIX\n#  define alloca __alloca\n# elif defined _MSC_VER\n#  include <malloc.h>\n#  define alloca _alloca\n# elif defined __DECC && defined __VMS\n#  define alloca __ALLOCA\n# elif defined __TANDEM && defined _TNS_E_TARGET\n#  ifdef  __cplusplus\nextern \"C\"\n#  endif\nvoid *_alloca (unsigned short);\n#  pragma intrinsic (_alloca)\n#  define alloca _alloca\n# elif defined __MVS__\n#  include <stdlib.h>\n# else\n#  include <stddef.h>\n#  ifdef  __cplusplus\nextern \"C\"\n#  endif\nvoid *alloca (size_t);\n# endif\n#endif\n\n#endif /* _GL_ALLOCA_H */\n"
  },
  {
    "path": "gnulib/arg-nonnull.h",
    "content": "/* A C macro for declaring that specific arguments must not be NULL.\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools\n   that the values passed as arguments n, ..., m must be non-NULL pointers.\n   n = 1 stands for the first argument, n = 2 for the second argument etc.  */\n#ifndef _GL_ARG_NONNULL\n# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__\n#  define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))\n# else\n#  define _GL_ARG_NONNULL(params)\n# endif\n#endif\n"
  },
  {
    "path": "gnulib/attribute.h",
    "content": "/* ATTRIBUTE_* macros for using attributes in GCC and similar compilers\n\n   Copyright 2020-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Paul Eggert.  */\n\n/* Provide public ATTRIBUTE_* names for the private _GL_ATTRIBUTE_*\n   macros used within Gnulib.  */\n\n/* These attributes can be placed in two ways:\n     - At the start of a declaration (i.e. even before storage-class\n       specifiers!); then they apply to all entities that are declared\n       by the declaration.\n     - Immediately after the name of an entity being declared by the\n       declaration; then they apply to that entity only.  */\n\n#ifndef _GL_ATTRIBUTE_H\n#define _GL_ATTRIBUTE_H\n\n\n/* This file defines two types of attributes:\n   * C2X standard attributes.  These have macro names that do not begin with\n     'ATTRIBUTE_'.\n   * Selected GCC attributes; see:\n     https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html\n     https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html\n     https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html\n     These names begin with 'ATTRIBUTE_' to avoid name clashes.  */\n\n\n/* =============== Attributes for specific kinds of functions =============== */\n\n/* Attributes for functions that should not be used.  */\n\n/* Warn if the entity is used.  */\n/* Applies to:\n     - function, variable,\n     - struct, union, struct/union member,\n     - enumeration, enumeration item,\n     - typedef,\n   in C++ also: namespace, class, template specialization.  */\n#define DEPRECATED _GL_ATTRIBUTE_DEPRECATED\n\n/* If a function call is not optimized way, warn with MSG.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_WARNING(msg) _GL_ATTRIBUTE_WARNING (msg)\n\n/* If a function call is not optimized way, report an error with MSG.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_ERROR(msg) _GL_ATTRIBUTE_ERROR (msg)\n\n\n/* Attributes for memory-allocating functions.  */\n\n/* The function returns a pointer to freshly allocated memory.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_MALLOC _GL_ATTRIBUTE_MALLOC\n\n/* ATTRIBUTE_ALLOC_SIZE ((N)) - The Nth argument of the function\n   is the size of the returned memory block.\n   ATTRIBUTE_ALLOC_SIZE ((M, N)) - Multiply the Mth and Nth arguments\n   to determine the size of the returned memory block.  */\n/* Applies to: function, pointer to function, function types.  */\n#define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE (args)\n\n\n/* Attributes for variadic functions.  */\n\n/* The variadic function expects a trailing NULL argument.\n   ATTRIBUTE_SENTINEL () - The last argument is NULL (requires C99).\n   ATTRIBUTE_SENTINEL ((N)) - The (N+1)st argument from the end is NULL.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_SENTINEL(pos) _GL_ATTRIBUTE_SENTINEL (pos)\n\n\n/* ================== Attributes for compiler diagnostics ================== */\n\n/* Attributes that help the compiler diagnose programmer mistakes.\n   Some of them may also help for some compiler optimizations.  */\n\n/* ATTRIBUTE_FORMAT ((ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK)) -\n   The STRING-INDEXth function argument is a format string of style\n   ARCHETYPE, which is one of:\n     printf, gnu_printf\n     scanf, gnu_scanf,\n     strftime, gnu_strftime,\n     strfmon,\n   or the same thing prefixed and suffixed with '__'.\n   If FIRST-TO-CHECK is not 0, arguments starting at FIRST-TO_CHECK\n   are suitable for the format string.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_FORMAT(spec) _GL_ATTRIBUTE_FORMAT (spec)\n\n/* ATTRIBUTE_NONNULL ((N1, N2,...)) - Arguments N1, N2,... must not be NULL.\n   ATTRIBUTE_NONNULL () - All pointer arguments must not be null.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_NONNULL(args) _GL_ATTRIBUTE_NONNULL (args)\n\n/* The function's return value is a non-NULL pointer.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_RETURNS_NONNULL _GL_ATTRIBUTE_RETURNS_NONNULL\n\n/* Warn if the caller does not use the return value,\n   unless the caller uses something like ignore_value.  */\n/* Applies to: function, enumeration, class.  */\n#define NODISCARD _GL_ATTRIBUTE_NODISCARD\n\n\n/* Attributes that disable false alarms when the compiler diagnoses\n   programmer \"mistakes\".  */\n\n/* Do not warn if the entity is not used.  */\n/* Applies to:\n     - function, variable,\n     - struct, union, struct/union member,\n     - enumeration, enumeration item,\n     - typedef,\n   in C++ also: class.  */\n#define MAYBE_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED\n\n/* The contents of a character array is not meant to be NUL-terminated.  */\n/* Applies to: struct/union members and variables that are arrays of element\n   type '[[un]signed] char'.  */\n#define ATTRIBUTE_NONSTRING _GL_ATTRIBUTE_NONSTRING\n\n/* Do not warn if control flow falls through to the immediately\n   following 'case' or 'default' label.  */\n/* Applies to: Empty statement (;), inside a 'switch' statement.  */\n#define FALLTHROUGH _GL_ATTRIBUTE_FALLTHROUGH\n\n\n/* ================== Attributes for debugging information ================== */\n\n/* Attributes regarding debugging information emitted by the compiler.  */\n\n/* Omit the function from stack traces when debugging.  */\n/* Applies to: function.  */\n#define ATTRIBUTE_ARTIFICIAL _GL_ATTRIBUTE_ARTIFICIAL\n\n/* Make the entity visible to debuggers etc., even with '-fwhole-program'.  */\n/* Applies to: functions, variables.  */\n#define ATTRIBUTE_EXTERNALLY_VISIBLE _GL_ATTRIBUTE_EXTERNALLY_VISIBLE\n\n\n/* ========== Attributes that mainly direct compiler optimizations ========== */\n\n/* The function does not throw exceptions.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_NOTHROW _GL_ATTRIBUTE_NOTHROW\n\n/* Do not inline the function.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_NOINLINE _GL_ATTRIBUTE_NOINLINE\n\n/* Always inline the function, and report an error if the compiler\n   cannot inline.  */\n/* Applies to: function.  */\n#define ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_ALWAYS_INLINE\n\n/* It is OK for a compiler to omit duplicate calls with the same arguments.\n   This attribute is safe for a function that neither depends on\n   nor affects observable state, and always returns exactly once -\n   e.g., does not loop forever, and does not call longjmp.\n   (This attribute is stricter than ATTRIBUTE_PURE.)  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST\n\n/* It is OK for a compiler to omit duplicate calls with the same\n   arguments if observable state is not changed between calls.\n   This attribute is safe for a function that does not affect\n   observable state, and always returns exactly once.\n   (This attribute is looser than ATTRIBUTE_CONST.)  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE\n\n/* The function is rarely executed.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_COLD _GL_ATTRIBUTE_COLD\n\n/* If called from some other compilation unit, the function executes\n   code from that unit only by return or by exception handling,\n   letting the compiler optimize that unit more aggressively.  */\n/* Applies to: functions.  */\n#define ATTRIBUTE_LEAF _GL_ATTRIBUTE_LEAF\n\n/* For struct members: The member has the smallest possible alignment.\n   For struct, union, class: All members have the smallest possible alignment,\n   minimizing the memory required.  */\n/* Applies to: struct members, struct, union,\n   in C++ also: class.  */\n#define ATTRIBUTE_PACKED _GL_ATTRIBUTE_PACKED\n\n\n/* ================ Attributes that make invalid code valid ================ */\n\n/* Attributes that prevent fatal compiler optimizations for code that is not\n   fully ISO C compliant.  */\n\n/* Pointers to the type may point to the same storage as pointers to\n   other types, thus disabling strict aliasing optimization.  */\n/* Applies to: types.  */\n#define ATTRIBUTE_MAY_ALIAS _GL_ATTRIBUTE_MAY_ALIAS\n\n\n#endif /* _GL_ATTRIBUTE_H */\n"
  },
  {
    "path": "gnulib/btowc.c",
    "content": "/* Convert unibyte character to wide character.\n   Copyright (C) 2008, 2010-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 2008.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <wchar.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n\nwint_t\nbtowc (int c)\n{\n  if (c != EOF)\n    {\n      char buf[1];\n      wchar_t wc;\n\n      buf[0] = c;\n      if (mbtowc (&wc, buf, 1) >= 0)\n        return wc;\n    }\n  return WEOF;\n}\n"
  },
  {
    "path": "gnulib/c++defs.h",
    "content": "/* C++ compatible function declaration macros.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _GL_CXXDEFS_H\n#define _GL_CXXDEFS_H\n\n/* Begin/end the GNULIB_NAMESPACE namespace.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {\n# define _GL_END_NAMESPACE }\n#else\n# define _GL_BEGIN_NAMESPACE\n# define _GL_END_NAMESPACE\n#endif\n\n/* The three most frequent use cases of these macros are:\n\n   * For providing a substitute for a function that is missing on some\n     platforms, but is declared and works fine on the platforms on which\n     it exists:\n\n       #if @GNULIB_FOO@\n       # if !@HAVE_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       # endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on all platforms,\n     but is broken/insufficient and needs to be replaced on some platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on some platforms\n     but is broken/insufficient and needs to be replaced on some of them and\n     is additionally either missing or undeclared on some other platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       #  endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n*/\n\n/* _GL_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#if defined __cplusplus\n# define _GL_EXTERN_C extern \"C\"\n#else\n# define _GL_EXTERN_C extern\n#endif\n\n/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);\n   declares a replacement function, named rpl_func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \\\n  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)\n#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype rpl_func parameters_and_attributes\n\n/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);\n   declares the system function, named func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype func parameters_and_attributes\n\n/* _GL_CXXALIAS_RPL (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));\n\n   Wrapping rpl_func in an object with an inline conversion operator\n   avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#define _GL_CXXALIAS_RPL(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::rpl_func;                                  \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA (func, rettype, parameters);\n   is to be used when func is a Microsoft deprecated alias, on native Windows.\n   It declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to _func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));\n */\n#define _GL_CXXALIAS_MDA(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);\n   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);\n   except that the C function rpl_func may have a slightly different\n   declaration.  A cast is used to silence the \"invalid conversion\" error\n   that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                     \\\n    {                                                              \\\n      static const struct _gl_ ## func ## _wrapper                 \\\n      {                                                            \\\n        typedef rettype (*type) parameters;                        \\\n                                                                   \\\n        inline operator type () const                              \\\n        {                                                          \\\n          return reinterpret_cast<type>(::rpl_func);               \\\n        }                                                          \\\n      } func = {};                                                 \\\n    }                                                              \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_MDA (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_SYS (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to the system provided function func, if GNULIB_NAMESPACE\n   is defined.\n   Example:\n     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));\n\n   Wrapping func in an object with an inline conversion operator\n   avoids a reference to func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS(func,rettype,parameters)            \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::func;                                      \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                          \\\n    {                                                   \\\n      static const struct _gl_ ## func ## _wrapper      \\\n      {                                                 \\\n        typedef rettype (*type) parameters;             \\\n                                                        \\\n        inline operator type () const                   \\\n        {                                               \\\n          return reinterpret_cast<type>(::func);        \\\n        }                                               \\\n      } func = {};                                      \\\n    }                                                   \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function is picked among a set of overloaded functions,\n   namely the one with rettype2 and parameters2.  Two consecutive casts\n   are used to silence the \"cannot find a match\" and \"invalid conversion\"\n   errors that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n  /* The outer cast must be a reinterpret_cast.\n     The inner cast: When the function is defined as a set of overloaded\n     functions, it works as a static_cast<>, choosing the designated variant.\n     When the function is defined as a single variant, it works as a\n     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    namespace GNULIB_NAMESPACE                                                \\\n    {                                                                         \\\n      static const struct _gl_ ## func ## _wrapper                            \\\n      {                                                                       \\\n        typedef rettype (*type) parameters;                                   \\\n                                                                              \\\n        inline operator type () const                                         \\\n        {                                                                     \\\n          return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \\\n        }                                                                     \\\n      } func = {};                                                            \\\n    }                                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN (func);\n   causes a warning to be emitted when ::func is used but not when\n   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded\n   variants.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN(func) \\\n   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN_1(func,namespace) \\\n   _GL_CXXALIASWARN_2 (func, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n    _GL_WARN_ON_USE (func, \\\n                     \"The symbol ::\" #func \" refers to the system function. \" \\\n                     \"Use \" #namespace \"::\" #func \" instead.\")\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     extern __typeof__ (func) func\n# else\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN(func) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);\n   causes a warning to be emitted when the given overloaded variant of ::func\n   is used but not when GNULIB_NAMESPACE::func is used.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \\\n                        GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \\\n   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n    _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \\\n                         \"The symbol ::\" #func \" refers to the system function. \" \\\n                         \"Use \" #namespace \"::\" #func \" instead.\")\n# else\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n#endif /* _GL_CXXDEFS_H */\n"
  },
  {
    "path": "gnulib/cdefs.h",
    "content": "/* Copyright (C) 1992-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifndef\t_SYS_CDEFS_H\n#define\t_SYS_CDEFS_H\t1\n\n/* We are almost always included from features.h. */\n#ifndef _FEATURES_H\n# include <features.h>\n#endif\n\n/* The GNU libc does not support any K&R compilers or the traditional mode\n   of ISO C compilers anymore.  Check for some of the combinations not\n   supported anymore.  */\n#if defined __GNUC__ && !defined __STDC__\n# error \"You need a ISO C conforming compiler to use the glibc headers\"\n#endif\n\n/* Some user header file might have defined this before.  */\n#undef\t__P\n#undef\t__PMT\n\n/* Compilers that lack __has_attribute may object to\n       #if defined __has_attribute && __has_attribute (...)\n   even though they do not need to evaluate the right-hand side of the &&.\n   Similarly for __has_builtin, etc.  */\n#if (defined __has_attribute \\\n     && (!defined __clang_minor__ \\\n         || 3 < __clang_major__ + (5 <= __clang_minor__)))\n# define __glibc_has_attribute(attr) __has_attribute (attr)\n#else\n# define __glibc_has_attribute(attr) 0\n#endif\n#ifdef __has_builtin\n# define __glibc_has_builtin(name) __has_builtin (name)\n#else\n# define __glibc_has_builtin(name) 0\n#endif\n#ifdef __has_extension\n# define __glibc_has_extension(ext) __has_extension (ext)\n#else\n# define __glibc_has_extension(ext) 0\n#endif\n\n#if defined __GNUC__ || defined __clang__\n\n/* All functions, except those with callbacks or those that\n   synchronize memory, are leaf functions.  */\n# if __GNUC_PREREQ (4, 6) && !defined _LIBC\n#  define __LEAF , __leaf__\n#  define __LEAF_ATTR __attribute__ ((__leaf__))\n# else\n#  define __LEAF\n#  define __LEAF_ATTR\n# endif\n\n/* GCC can always grok prototypes.  For C++ programs we add throw()\n   to help it optimize the function calls.  But this only works with\n   gcc 2.8.x and egcs.  For gcc 3.4 and up we even mark C functions\n   as non-throwing using a function attribute since programs can use\n   the -fexceptions options for C code as well.  */\n# if !defined __cplusplus \\\n     && (__GNUC_PREREQ (3, 4) || __glibc_has_attribute (__nothrow__))\n#  define __THROW\t__attribute__ ((__nothrow__ __LEAF))\n#  define __THROWNL\t__attribute__ ((__nothrow__))\n#  define __NTH(fct)\t__attribute__ ((__nothrow__ __LEAF)) fct\n#  define __NTHNL(fct)  __attribute__ ((__nothrow__)) fct\n# else\n#  if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4)\n#   if __cplusplus >= 201103L\n#    define __THROW\tnoexcept (true)\n#   else\n#    define __THROW\tthrow ()\n#   endif\n#   define __THROWNL\t__THROW\n#   define __NTH(fct)\t__LEAF_ATTR fct __THROW\n#   define __NTHNL(fct) fct __THROW\n#  else\n#   define __THROW\n#   define __THROWNL\n#   define __NTH(fct)\tfct\n#   define __NTHNL(fct) fct\n#  endif\n# endif\n\n#else\t/* Not GCC or clang.  */\n\n# if (defined __cplusplus\t\t\t\t\t\t\\\n      || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))\n#  define __inline\tinline\n# else\n#  define __inline\t\t/* No inline functions.  */\n# endif\n\n# define __THROW\n# define __THROWNL\n# define __NTH(fct)\tfct\n\n#endif\t/* GCC || clang.  */\n\n/* These two macros are not used in glibc anymore.  They are kept here\n   only because some other projects expect the macros to be defined.  */\n#define __P(args)\targs\n#define __PMT(args)\targs\n\n/* For these things, GCC behaves the ANSI way normally,\n   and the non-ANSI way under -traditional.  */\n\n#define __CONCAT(x,y)\tx ## y\n#define __STRING(x)\t#x\n\n/* This is not a typedef so `const __ptr_t' does the right thing.  */\n#define __ptr_t void *\n\n\n/* C++ needs to know that types and declarations are C, not C++.  */\n#ifdef\t__cplusplus\n# define __BEGIN_DECLS\textern \"C\" {\n# define __END_DECLS\t}\n#else\n# define __BEGIN_DECLS\n# define __END_DECLS\n#endif\n\n\n/* Fortify support.  */\n#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)\n#define __bos0(ptr) __builtin_object_size (ptr, 0)\n\n/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available.  */\n#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0)\n# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)\n# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)\n#else\n# define __glibc_objsize0(__o) __bos0 (__o)\n# define __glibc_objsize(__o) __bos (__o)\n#endif\n\n#if __GNUC_PREREQ (4,3)\n# define __warnattr(msg) __attribute__((__warning__ (msg)))\n# define __errordecl(name, msg) \\\n  extern void name (void) __attribute__((__error__ (msg)))\n#else\n# define __warnattr(msg)\n# define __errordecl(name, msg) extern void name (void)\n#endif\n\n/* Support for flexible arrays.\n   Headers that should use flexible arrays only if they're \"real\"\n   (e.g. only if they won't affect sizeof()) should test\n   #if __glibc_c99_flexarr_available.  */\n#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __HP_cc\n# define __flexarr\t[]\n# define __glibc_c99_flexarr_available 1\n#elif __GNUC_PREREQ (2,97) || defined __clang__\n/* GCC 2.97 and clang support C99 flexible array members as an extension,\n   even when in C89 mode or compiling C++ (any version).  */\n# define __flexarr\t[]\n# define __glibc_c99_flexarr_available 1\n#elif defined __GNUC__\n/* Pre-2.97 GCC did not support C99 flexible arrays but did have\n   an equivalent extension with slightly different notation.  */\n# define __flexarr\t[0]\n# define __glibc_c99_flexarr_available 1\n#else\n/* Some other non-C99 compiler.  Approximate with [1].  */\n# define __flexarr\t[1]\n# define __glibc_c99_flexarr_available 0\n#endif\n\n\n/* __asm__ (\"xyz\") is used throughout the headers to rename functions\n   at the assembly language level.  This is wrapped by the __REDIRECT\n   macro, in order to support compilers that can do this some other\n   way.  When compilers don't support asm-names at all, we have to do\n   preprocessor tricks instead (which don't have exactly the right\n   semantics, but it's the best we can do).\n\n   Example:\n   int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */\n\n#if (defined __GNUC__ && __GNUC__ >= 2) || (__clang_major__ >= 4)\n\n# define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias))\n# ifdef __cplusplus\n#  define __REDIRECT_NTH(name, proto, alias) \\\n     name proto __THROW __asm__ (__ASMNAME (#alias))\n#  define __REDIRECT_NTHNL(name, proto, alias) \\\n     name proto __THROWNL __asm__ (__ASMNAME (#alias))\n# else\n#  define __REDIRECT_NTH(name, proto, alias) \\\n     name proto __asm__ (__ASMNAME (#alias)) __THROW\n#  define __REDIRECT_NTHNL(name, proto, alias) \\\n     name proto __asm__ (__ASMNAME (#alias)) __THROWNL\n# endif\n# define __ASMNAME(cname)  __ASMNAME2 (__USER_LABEL_PREFIX__, cname)\n# define __ASMNAME2(prefix, cname) __STRING (prefix) cname\n\n/*\n#elif __SOME_OTHER_COMPILER__\n\n# define __REDIRECT(name, proto, alias) name proto; \\\n\t_Pragma(\"let \" #name \" = \" #alias)\n*/\n#endif\n\n/* GCC and clang have various useful declarations that can be made with\n   the '__attribute__' syntax.  All of the ways we use this do fine if\n   they are omitted for compilers that don't understand it.  */\n#if !(defined __GNUC__ || defined __clang__)\n# define __attribute__(xyz)\t/* Ignore */\n#endif\n\n/* At some point during the gcc 2.96 development the `malloc' attribute\n   for functions was introduced.  We don't want to use it unconditionally\n   (although this would be possible) since it generates warnings.  */\n#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__malloc__)\n# define __attribute_malloc__ __attribute__ ((__malloc__))\n#else\n# define __attribute_malloc__ /* Ignore */\n#endif\n\n/* Tell the compiler which arguments to an allocation function\n   indicate the size of the allocation.  */\n#if __GNUC_PREREQ (4, 3)\n# define __attribute_alloc_size__(params) \\\n  __attribute__ ((__alloc_size__ params))\n#else\n# define __attribute_alloc_size__(params) /* Ignore.  */\n#endif\n\n/* At some point during the gcc 2.96 development the `pure' attribute\n   for functions was introduced.  We don't want to use it unconditionally\n   (although this would be possible) since it generates warnings.  */\n#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__pure__)\n# define __attribute_pure__ __attribute__ ((__pure__))\n#else\n# define __attribute_pure__ /* Ignore */\n#endif\n\n/* This declaration tells the compiler that the value is constant.  */\n#if __GNUC_PREREQ (2,5) || __glibc_has_attribute (__const__)\n# define __attribute_const__ __attribute__ ((__const__))\n#else\n# define __attribute_const__ /* Ignore */\n#endif\n\n#if __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__)\n# define __attribute_maybe_unused__ __attribute__ ((__unused__))\n/* Once the next version of the C standard comes out, we can\n   do something like the following here:\n   #elif defined __STDC_VERSION__ && 202???L <= __STDC_VERSION__\n   # define __attribute_maybe_unused__ [[__maybe_unused__]]   */\n#else\n# define __attribute_maybe_unused__ /* Ignore */\n#endif\n\n/* At some point during the gcc 3.1 development the `used' attribute\n   for functions was introduced.  We don't want to use it unconditionally\n   (although this would be possible) since it generates warnings.  */\n#if __GNUC_PREREQ (3,1) || __glibc_has_attribute (__used__)\n# define __attribute_used__ __attribute__ ((__used__))\n# define __attribute_noinline__ __attribute__ ((__noinline__))\n#else\n# define __attribute_used__ __attribute__ ((__unused__))\n# define __attribute_noinline__ /* Ignore */\n#endif\n\n/* Since version 3.2, gcc allows marking deprecated functions.  */\n#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__deprecated__)\n# define __attribute_deprecated__ __attribute__ ((__deprecated__))\n#else\n# define __attribute_deprecated__ /* Ignore */\n#endif\n\n/* Since version 4.5, gcc also allows one to specify the message printed\n   when a deprecated function is used.  clang claims to be gcc 4.2, but\n   may also support this feature.  */\n#if __GNUC_PREREQ (4,5) \\\n    || __glibc_has_extension (__attribute_deprecated_with_message__)\n# define __attribute_deprecated_msg__(msg) \\\n\t __attribute__ ((__deprecated__ (msg)))\n#else\n# define __attribute_deprecated_msg__(msg) __attribute_deprecated__\n#endif\n\n/* At some point during the gcc 2.8 development the `format_arg' attribute\n   for functions was introduced.  We don't want to use it unconditionally\n   (although this would be possible) since it generates warnings.\n   If several `format_arg' attributes are given for the same function, in\n   gcc-3.0 and older, all but the last one are ignored.  In newer gccs,\n   all designated arguments are considered.  */\n#if __GNUC_PREREQ (2,8) || __glibc_has_attribute (__format_arg__)\n# define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))\n#else\n# define __attribute_format_arg__(x) /* Ignore */\n#endif\n\n/* At some point during the gcc 2.97 development the `strfmon' format\n   attribute for functions was introduced.  We don't want to use it\n   unconditionally (although this would be possible) since it\n   generates warnings.  */\n#if __GNUC_PREREQ (2,97) || __glibc_has_attribute (__format__)\n# define __attribute_format_strfmon__(a,b) \\\n  __attribute__ ((__format__ (__strfmon__, a, b)))\n#else\n# define __attribute_format_strfmon__(a,b) /* Ignore */\n#endif\n\n/* The nonnull function attribute marks pointer parameters that\n   must not be NULL.  This has the name __nonnull in glibc,\n   and __attribute_nonnull__ in files shared with Gnulib to avoid\n   collision with a different __nonnull in DragonFlyBSD 5.9.  */\n#ifndef __attribute_nonnull__\n# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__)\n#  define __attribute_nonnull__(params) __attribute__ ((__nonnull__ params))\n# else\n#  define __attribute_nonnull__(params)\n# endif\n#endif\n#ifndef __nonnull\n# define __nonnull(params) __attribute_nonnull__ (params)\n#endif\n\n/* If fortification mode, we warn about unused results of certain\n   function calls which can lead to problems.  */\n#if __GNUC_PREREQ (3,4) || __glibc_has_attribute (__warn_unused_result__)\n# define __attribute_warn_unused_result__ \\\n   __attribute__ ((__warn_unused_result__))\n# if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0\n#  define __wur __attribute_warn_unused_result__\n# endif\n#else\n# define __attribute_warn_unused_result__ /* empty */\n#endif\n#ifndef __wur\n# define __wur /* Ignore */\n#endif\n\n/* Forces a function to be always inlined.  */\n#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__always_inline__)\n/* The Linux kernel defines __always_inline in stddef.h (283d7573), and\n   it conflicts with this definition.  Therefore undefine it first to\n   allow either header to be included first.  */\n# undef __always_inline\n# define __always_inline __inline __attribute__ ((__always_inline__))\n#else\n# undef __always_inline\n# define __always_inline __inline\n#endif\n\n/* Associate error messages with the source location of the call site rather\n   than with the source location inside the function.  */\n#if __GNUC_PREREQ (4,3) || __glibc_has_attribute (__artificial__)\n# define __attribute_artificial__ __attribute__ ((__artificial__))\n#else\n# define __attribute_artificial__ /* Ignore */\n#endif\n\n/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99\n   inline semantics, unless -fgnu89-inline is used.  Using __GNUC_STDC_INLINE__\n   or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions\n   older than 4.3 may define these macros and still not guarantee GNU inlining\n   semantics.\n\n   clang++ identifies itself as gcc-4.2, but has support for GNU inlining\n   semantics, that can be checked for by using the __GNUC_STDC_INLINE_ and\n   __GNUC_GNU_INLINE__ macro definitions.  */\n#if (!defined __cplusplus || __GNUC_PREREQ (4,3) \\\n     || (defined __clang__ && (defined __GNUC_STDC_INLINE__ \\\n\t\t\t       || defined __GNUC_GNU_INLINE__)))\n# if defined __GNUC_STDC_INLINE__ || defined __cplusplus\n#  define __extern_inline extern __inline __attribute__ ((__gnu_inline__))\n#  define __extern_always_inline \\\n  extern __always_inline __attribute__ ((__gnu_inline__))\n# else\n#  define __extern_inline extern __inline\n#  define __extern_always_inline extern __always_inline\n# endif\n#endif\n\n#ifdef __extern_always_inline\n# define __fortify_function __extern_always_inline __attribute_artificial__\n#endif\n\n/* GCC 4.3 and above allow passing all anonymous arguments of an\n   __extern_always_inline function to some other vararg function.  */\n#if __GNUC_PREREQ (4,3)\n# define __va_arg_pack() __builtin_va_arg_pack ()\n# define __va_arg_pack_len() __builtin_va_arg_pack_len ()\n#endif\n\n/* It is possible to compile containing GCC extensions even if GCC is\n   run in pedantic mode if the uses are carefully marked using the\n   `__extension__' keyword.  But this is not generally available before\n   version 2.8.  */\n#if !(__GNUC_PREREQ (2,8) || defined __clang__)\n# define __extension__\t\t/* Ignore */\n#endif\n\n/* __restrict is known in EGCS 1.2 and above, and in clang.\n   It works also in C++ mode (outside of arrays), but only when spelled\n   as '__restrict', not 'restrict'.  */\n#if !(__GNUC_PREREQ (2,92) || __clang_major__ >= 3)\n# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L\n#  define __restrict\trestrict\n# else\n#  define __restrict\t/* Ignore */\n# endif\n#endif\n\n/* ISO C99 also allows to declare arrays as non-overlapping.  The syntax is\n     array_name[restrict]\n   GCC 3.1 and clang support this.\n   This syntax is not usable in C++ mode.  */\n#if (__GNUC_PREREQ (3,1) || __clang_major__ >= 3) && !defined __cplusplus\n# define __restrict_arr\t__restrict\n#else\n# ifdef __GNUC__\n#  define __restrict_arr\t/* Not supported in old GCC.  */\n# else\n#  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L\n#   define __restrict_arr\trestrict\n#  else\n/* Some other non-C99 compiler.  */\n#   define __restrict_arr\t/* Not supported.  */\n#  endif\n# endif\n#endif\n\n#if (__GNUC__ >= 3) || __glibc_has_builtin (__builtin_expect)\n# define __glibc_unlikely(cond)\t__builtin_expect ((cond), 0)\n# define __glibc_likely(cond)\t__builtin_expect ((cond), 1)\n#else\n# define __glibc_unlikely(cond)\t(cond)\n# define __glibc_likely(cond)\t(cond)\n#endif\n\n#if (!defined _Noreturn \\\n     && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \\\n     &&  !(__GNUC_PREREQ (4,7) \\\n           || (3 < __clang_major__ + (5 <= __clang_minor__))))\n# if __GNUC_PREREQ (2,8)\n#  define _Noreturn __attribute__ ((__noreturn__))\n# else\n#  define _Noreturn\n# endif\n#endif\n\n#if __GNUC_PREREQ (8, 0)\n/* Describes a char array whose address can safely be passed as the first\n   argument to strncpy and strncat, as the char array is not necessarily\n   a NUL-terminated string.  */\n# define __attribute_nonstring__ __attribute__ ((__nonstring__))\n#else\n# define __attribute_nonstring__\n#endif\n\n/* Undefine (also defined in libc-symbols.h).  */\n#undef __attribute_copy__\n#if __GNUC_PREREQ (9, 0)\n/* Copies attributes from the declaration or type referenced by\n   the argument.  */\n# define __attribute_copy__(arg) __attribute__ ((__copy__ (arg)))\n#else\n# define __attribute_copy__(arg)\n#endif\n\n#if (!defined _Static_assert && !defined __cplusplus \\\n     && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \\\n     && (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \\\n         || defined __STRICT_ANSI__))\n# define _Static_assert(expr, diagnostic) \\\n    extern int (*__Static_assert_function (void)) \\\n      [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]\n#endif\n\n/* Gnulib avoids including these, as they don't work on non-glibc or\n   older glibc platforms.  */\n#ifndef __GNULIB_CDEFS\n# include <bits/wordsize.h>\n# include <bits/long-double.h>\n#endif\n\n#if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1\n# ifdef __REDIRECT\n\n/* Alias name defined automatically.  */\n#  define __LDBL_REDIR(name, proto) ... unused__ldbl_redir\n#  define __LDBL_REDIR_DECL(name) \\\n  extern __typeof (name) name __asm (__ASMNAME (\"__\" #name \"ieee128\"));\n\n/* Alias name defined automatically, with leading underscores.  */\n#  define __LDBL_REDIR2_DECL(name) \\\n  extern __typeof (__##name) __##name \\\n    __asm (__ASMNAME (\"__\" #name \"ieee128\"));\n\n/* Alias name defined manually.  */\n#  define __LDBL_REDIR1(name, proto, alias) ... unused__ldbl_redir1\n#  define __LDBL_REDIR1_DECL(name, alias) \\\n  extern __typeof (name) name __asm (__ASMNAME (#alias));\n\n#  define __LDBL_REDIR1_NTH(name, proto, alias) \\\n  __REDIRECT_NTH (name, proto, alias)\n#  define __REDIRECT_NTH_LDBL(name, proto, alias) \\\n  __LDBL_REDIR1_NTH (name, proto, __##alias##ieee128)\n\n/* Unused.  */\n#  define __REDIRECT_LDBL(name, proto, alias) ... unused__redirect_ldbl\n#  define __LDBL_REDIR_NTH(name, proto) ... unused__ldbl_redir_nth\n\n# else\n_Static_assert (0, \"IEEE 128-bits long double requires redirection on this platform\");\n# endif\n#elif defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH\n# define __LDBL_COMPAT 1\n# ifdef __REDIRECT\n#  define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias)\n#  define __LDBL_REDIR(name, proto) \\\n  __LDBL_REDIR1 (name, proto, __nldbl_##name)\n#  define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias)\n#  define __LDBL_REDIR_NTH(name, proto) \\\n  __LDBL_REDIR1_NTH (name, proto, __nldbl_##name)\n#  define __LDBL_REDIR2_DECL(name) \\\n  extern __typeof (__##name) __##name __asm (__ASMNAME (\"__nldbl___\" #name));\n#  define __LDBL_REDIR1_DECL(name, alias) \\\n  extern __typeof (name) name __asm (__ASMNAME (#alias));\n#  define __LDBL_REDIR_DECL(name) \\\n  extern __typeof (name) name __asm (__ASMNAME (\"__nldbl_\" #name));\n#  define __REDIRECT_LDBL(name, proto, alias) \\\n  __LDBL_REDIR1 (name, proto, __nldbl_##alias)\n#  define __REDIRECT_NTH_LDBL(name, proto, alias) \\\n  __LDBL_REDIR1_NTH (name, proto, __nldbl_##alias)\n# endif\n#endif\n#if (!defined __LDBL_COMPAT && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0) \\\n    || !defined __REDIRECT\n# define __LDBL_REDIR1(name, proto, alias) name proto\n# define __LDBL_REDIR(name, proto) name proto\n# define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW\n# define __LDBL_REDIR_NTH(name, proto) name proto __THROW\n# define __LDBL_REDIR2_DECL(name)\n# define __LDBL_REDIR_DECL(name)\n# ifdef __REDIRECT\n#  define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias)\n#  define __REDIRECT_NTH_LDBL(name, proto, alias) \\\n  __REDIRECT_NTH (name, proto, alias)\n# endif\n#endif\n\n/* __glibc_macro_warning (MESSAGE) issues warning MESSAGE.  This is\n   intended for use in preprocessor macros.\n\n   Note: MESSAGE must be a _single_ string; concatenation of string\n   literals is not supported.  */\n#if __GNUC_PREREQ (4,8) || __glibc_clang_prereq (3,5)\n# define __glibc_macro_warning1(message) _Pragma (#message)\n# define __glibc_macro_warning(message) \\\n  __glibc_macro_warning1 (GCC warning message)\n#else\n# define __glibc_macro_warning(msg)\n#endif\n\n/* Generic selection (ISO C11) is a C-only feature, available in GCC\n   since version 4.9.  Previous versions do not provide generic\n   selection, even though they might set __STDC_VERSION__ to 201112L,\n   when in -std=c11 mode.  Thus, we must check for !defined __GNUC__\n   when testing __STDC_VERSION__ for generic selection support.\n   On the other hand, Clang also defines __GNUC__, so a clang-specific\n   check is required to enable the use of generic selection.  */\n#if !defined __cplusplus \\\n    && (__GNUC_PREREQ (4, 9) \\\n\t|| __glibc_has_extension (c_generic_selections) \\\n\t|| (!defined __GNUC__ && defined __STDC_VERSION__ \\\n\t    && __STDC_VERSION__ >= 201112L))\n# define __HAVE_GENERIC_SELECTION 1\n#else\n# define __HAVE_GENERIC_SELECTION 0\n#endif\n\n#if __GNUC_PREREQ (10, 0)\n/* Designates a 1-based positional argument ref-index of pointer type\n   that can be used to access size-index elements of the pointed-to\n   array according to access mode, or at least one element when\n   size-index is not provided:\n     access (access-mode, <ref-index> [, <size-index>])  */\n#define __attr_access(x) __attribute__ ((__access__ x))\n#else\n#  define __attr_access(x)\n#endif\n\n/* Specify that a function such as setjmp or vfork may return\n   twice.  */\n#if __GNUC_PREREQ (4, 1)\n# define __attribute_returns_twice__ __attribute__ ((__returns_twice__))\n#else\n# define __attribute_returns_twice__ /* Ignore.  */\n#endif\n\n#endif\t /* sys/cdefs.h */\n"
  },
  {
    "path": "gnulib/ctype.in.h",
    "content": "/* A substitute for ISO C99 <ctype.h>, for platforms on which it is incomplete.\n\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible.  */\n\n/*\n * ISO C 99 <ctype.h> for platforms on which it is incomplete.\n * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/ctype.h.html>\n */\n\n#ifndef _@GUARD_PREFIX@_CTYPE_H\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n/* Include the original <ctype.h>.  */\n/* The include_next requires a split double-inclusion guard.  */\n#@INCLUDE_NEXT@ @NEXT_CTYPE_H@\n\n#ifndef _@GUARD_PREFIX@_CTYPE_H\n#define _@GUARD_PREFIX@_CTYPE_H\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n\n/* Return non-zero if c is a blank, i.e. a space or tab character.  */\n#if @GNULIB_ISBLANK@\n# if !@HAVE_ISBLANK@\n_GL_EXTERN_C int isblank (int c);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef isblank\n# if HAVE_RAW_DECL_ISBLANK\n_GL_WARN_ON_USE (isblank, \"isblank is unportable - \"\n                 \"use gnulib module isblank for portability\");\n# endif\n#endif\n\n#endif /* _@GUARD_PREFIX@_CTYPE_H */\n#endif /* _@GUARD_PREFIX@_CTYPE_H */\n"
  },
  {
    "path": "gnulib/dynarray.h",
    "content": "/* Type-safe arrays which grow dynamically.\n   Copyright 2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Paul Eggert and Bruno Haible, 2021.  */\n\n#ifndef _GL_DYNARRAY_H\n#define _GL_DYNARRAY_H\n\n/* Before including this file, you need to define:\n\n   DYNARRAY_STRUCT\n      The struct tag of dynamic array to be defined.\n\n   DYNARRAY_ELEMENT\n      The type name of the element type.  Elements are copied\n      as if by memcpy, and can change address as the dynamic\n      array grows.\n\n   DYNARRAY_PREFIX\n      The prefix of the functions which are defined.\n\n   The following parameters are optional:\n\n   DYNARRAY_ELEMENT_FREE\n      DYNARRAY_ELEMENT_FREE (E) is evaluated to deallocate the\n      contents of elements. E is of type  DYNARRAY_ELEMENT *.\n\n   DYNARRAY_ELEMENT_INIT\n      DYNARRAY_ELEMENT_INIT (E) is evaluated to initialize a new\n      element.  E is of type  DYNARRAY_ELEMENT *.\n      If DYNARRAY_ELEMENT_FREE but not DYNARRAY_ELEMENT_INIT is\n      defined, new elements are automatically zero-initialized.\n      Otherwise, new elements have undefined contents.\n\n   DYNARRAY_INITIAL_SIZE\n      The size of the statically allocated array (default:\n      at least 2, more elements if they fit into 128 bytes).\n      Must be a preprocessor constant.  If DYNARRAY_INITIAL_SIZE is 0,\n      there is no statically allocated array at, and all non-empty\n      arrays are heap-allocated.\n\n   DYNARRAY_FINAL_TYPE\n      The name of the type which holds the final array.  If not\n      defined, is PREFIX##finalize not provided.  DYNARRAY_FINAL_TYPE\n      must be a struct type, with members of type DYNARRAY_ELEMENT and\n      size_t at the start (in this order).\n\n   These macros are undefined after this header file has been\n   included.\n\n   The following types are provided (their members are private to the\n   dynarray implementation):\n\n     struct DYNARRAY_STRUCT\n\n   The following functions are provided:\n */\n\n/* Initialize a dynamic array object.  This must be called before any\n   use of the object.  */\n#if 0\nstatic void\n       DYNARRAY_PREFIX##init (struct DYNARRAY_STRUCT *list);\n#endif\n\n/* Deallocate the dynamic array and its elements.  */\n#if 0\nstatic void\n       DYNARRAY_PREFIX##free (struct DYNARRAY_STRUCT *list);\n#endif\n\n/* Return true if the dynamic array is in an error state.  */\n#if 0\nstatic bool\n       DYNARRAY_PREFIX##has_failed (const struct DYNARRAY_STRUCT *list);\n#endif\n\n/* Mark the dynamic array as failed.  All elements are deallocated as\n   a side effect.  */\n#if 0\nstatic void\n       DYNARRAY_PREFIX##mark_failed (struct DYNARRAY_STRUCT *list);\n#endif\n\n/* Return the number of elements which have been added to the dynamic\n   array.  */\n#if 0\nstatic size_t\n       DYNARRAY_PREFIX##size (const struct DYNARRAY_STRUCT *list);\n#endif\n\n/* Return a pointer to the first array element, if any.  For a\n   zero-length array, the pointer can be NULL even though the dynamic\n   array has not entered the failure state.  */\n#if 0\nstatic DYNARRAY_ELEMENT *\n       DYNARRAY_PREFIX##begin (const struct DYNARRAY_STRUCT *list);\n#endif\n\n/* Return a pointer one element past the last array element.  For a\n   zero-length array, the pointer can be NULL even though the dynamic\n   array has not entered the failure state.  */\n#if 0\nstatic DYNARRAY_ELEMENT *\n       DYNARRAY_PREFIX##end (const struct DYNARRAY_STRUCT *list);\n#endif\n\n/* Return a pointer to the array element at INDEX.  Terminate the\n   process if INDEX is out of bounds.  */\n#if 0\nstatic DYNARRAY_ELEMENT *\n       DYNARRAY_PREFIX##at (struct DYNARRAY_STRUCT *list, size_t index);\n#endif\n\n/* Add ITEM at the end of the array, enlarging it by one element.\n   Mark *LIST as failed if the dynamic array allocation size cannot be\n   increased.  */\n#if 0\nstatic void\n       DYNARRAY_PREFIX##add (struct DYNARRAY_STRUCT *list,\n                             DYNARRAY_ELEMENT item);\n#endif\n\n/* Allocate a place for a new element in *LIST and return a pointer to\n   it.  The pointer can be NULL if the dynamic array cannot be\n   enlarged due to a memory allocation failure.  */\n#if 0\nstatic DYNARRAY_ELEMENT *\n       DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *list);\n#endif\n\n/* Change the size of *LIST to SIZE.  If SIZE is larger than the\n   existing size, new elements are added (which can be initialized).\n   Otherwise, the list is truncated, and elements are freed.  Return\n   false on memory allocation failure (and mark *LIST as failed).  */\n#if 0\nstatic bool\n       DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *list, size_t size);\n#endif\n\n/* Remove the last element of LIST if it is present.  */\n#if 0\nstatic void\n       DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *list);\n#endif\n\n/* Remove all elements from the list.  The elements are freed, but the\n   list itself is not.  */\n#if 0\nstatic void\n       DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *list);\n#endif\n\n#if defined DYNARRAY_FINAL_TYPE\n/* Transfer the dynamic array to a permanent location at *RESULT.\n   Returns true on success on false on allocation failure.  In either\n   case, *LIST is re-initialized and can be reused.  A NULL pointer is\n   stored in *RESULT if LIST refers to an empty list.  On success, the\n   pointer in *RESULT is heap-allocated and must be deallocated using\n   free.  */\n#if 0\nstatic bool\n       DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *list,\n                                  DYNARRAY_FINAL_TYPE *result);\n#endif\n#else /* !defined DYNARRAY_FINAL_TYPE */\n/* Transfer the dynamic array to a heap-allocated array and return a\n   pointer to it.  The pointer is NULL if memory allocation fails, or\n   if the array is empty, so this function should be used only for\n   arrays which are known not be empty (usually because they always\n   have a sentinel at the end).  If LENGTHP is not NULL, the array\n   length is written to *LENGTHP.  *LIST is re-initialized and can be\n   reused.  */\n#if 0\nstatic DYNARRAY_ELEMENT *\n       DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *list,\n                                  size_t *lengthp);\n#endif\n#endif\n\n/* A minimal example which provides a growing list of integers can be\n   defined like this:\n\n     struct int_array\n     {\n       // Pointer to result array followed by its length,\n       // as required by DYNARRAY_FINAL_TYPE.\n       int *array;\n       size_t length;\n     };\n\n     #define DYNARRAY_STRUCT dynarray_int\n     #define DYNARRAY_ELEMENT int\n     #define DYNARRAY_PREFIX dynarray_int_\n     #define DYNARRAY_FINAL_TYPE struct int_array\n     #include <malloc/dynarray-skeleton.c>\n\n   To create a three-element array with elements 1, 2, 3, use this\n   code:\n\n     struct dynarray_int dyn;\n     dynarray_int_init (&dyn);\n     for (int i = 1; i <= 3; ++i)\n       {\n         int *place = dynarray_int_emplace (&dyn);\n         assert (place != NULL);\n         *place = i;\n       }\n     struct int_array result;\n     bool ok = dynarray_int_finalize (&dyn, &result);\n     assert (ok);\n     assert (result.length == 3);\n     assert (result.array[0] == 1);\n     assert (result.array[1] == 2);\n     assert (result.array[2] == 3);\n     free (result.array);\n\n   If the elements contain resources which must be freed, define\n   DYNARRAY_ELEMENT_FREE appropriately, like this:\n\n     struct str_array\n     {\n       char **array;\n       size_t length;\n     };\n\n     #define DYNARRAY_STRUCT dynarray_str\n     #define DYNARRAY_ELEMENT char *\n     #define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr)\n     #define DYNARRAY_PREFIX dynarray_str_\n     #define DYNARRAY_FINAL_TYPE struct str_array\n     #include <malloc/dynarray-skeleton.c>\n */\n\n\n/* The implementation is imported from glibc.  */\n\n/* Avoid possible conflicts with symbols exported by the GNU libc.  */\n#define __libc_dynarray_at_failure gl_dynarray_at_failure\n#define __libc_dynarray_emplace_enlarge gl_dynarray_emplace_enlarge\n#define __libc_dynarray_finalize gl_dynarray_finalize\n#define __libc_dynarray_resize_clear gl_dynarray_resize_clear\n#define __libc_dynarray_resize gl_dynarray_resize\n\n#if defined DYNARRAY_STRUCT || defined DYNARRAY_ELEMENT || defined DYNARRAY_PREFIX\n\n# ifndef _GL_LIKELY\n/* Rely on __builtin_expect, as provided by the module 'builtin-expect'.  */\n#  define _GL_LIKELY(cond) __builtin_expect ((cond), 1)\n#  define _GL_UNLIKELY(cond) __builtin_expect ((cond), 0)\n# endif\n\n/* Define auxiliary structs and declare auxiliary functions, common to all\n   instantiations of dynarray.  */\n# include <malloc/dynarray.gl.h>\n\n/* Define the instantiation, specified through\n     DYNARRAY_STRUCT\n     DYNARRAY_ELEMENT\n     DYNARRAY_PREFIX\n   etc.  */\n# include <malloc/dynarray-skeleton.gl.h>\n\n#else\n\n/* This file is being included from one of the malloc/dynarray_*.c files.  */\n# include <malloc/dynarray.h>\n\n#endif\n\n#endif /* _GL_DYNARRAY_H */\n"
  },
  {
    "path": "gnulib/flexmember.h",
    "content": "/* Sizes of structs with flexible array members.\n\n   Copyright 2016-2021 Free Software Foundation, Inc.\n\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.\n\n   Written by Paul Eggert.  */\n\n#include <stddef.h>\n\n/* Nonzero multiple of alignment of TYPE, suitable for FLEXSIZEOF below.\n   On older platforms without _Alignof, use a pessimistic bound that is\n   safe in practice even if FLEXIBLE_ARRAY_MEMBER is 1.\n   On newer platforms, use _Alignof to get a tighter bound.  */\n\n#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112\n# define FLEXALIGNOF(type) (sizeof (type) & ~ (sizeof (type) - 1))\n#else\n# define FLEXALIGNOF(type) _Alignof (type)\n#endif\n\n/* Yield a properly aligned upper bound on the size of a struct of\n   type TYPE with a flexible array member named MEMBER that is\n   followed by N bytes of other data.  The result is suitable as an\n   argument to malloc.  For example:\n\n     struct s { int n; char d[FLEXIBLE_ARRAY_MEMBER]; };\n     struct s *p = malloc (FLEXSIZEOF (struct s, d, n * sizeof (char)));\n\n   FLEXSIZEOF (TYPE, MEMBER, N) is not simply (sizeof (TYPE) + N),\n   since FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms.  Nor is\n   it simply (offsetof (TYPE, MEMBER) + N), as that might yield a size\n   that causes malloc to yield a pointer that is not properly aligned\n   for TYPE; for example, if sizeof (int) == alignof (int) == 4,\n   malloc (offsetof (struct s, d) + 3 * sizeof (char)) is equivalent\n   to malloc (7) and might yield a pointer that is not a multiple of 4\n   (which means the pointer is not properly aligned for struct s),\n   whereas malloc (FLEXSIZEOF (struct s, d, 3 * sizeof (char))) is\n   equivalent to malloc (8) and must yield a pointer that is a\n   multiple of 4.\n\n   Yield a value less than N if and only if arithmetic overflow occurs.  */\n\n#define FLEXSIZEOF(type, member, n) \\\n   ((offsetof (type, member) + FLEXALIGNOF (type) - 1 + (n)) \\\n    & ~ (FLEXALIGNOF (type) - 1))\n"
  },
  {
    "path": "gnulib/fnmatch.c",
    "content": "/* Copyright (C) 1991-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifndef _LIBC\n# include <libc-config.h>\n#endif\n\n/* Enable GNU extensions in fnmatch.h.  */\n#ifndef _GNU_SOURCE\n# define _GNU_SOURCE    1\n#endif\n\n#include <fnmatch.h>\n\n#include <assert.h>\n#include <errno.h>\n#include <ctype.h>\n#include <string.h>\n#include <stdlib.h>\n#if defined _LIBC || HAVE_ALLOCA\n# include <alloca.h>\n#endif\n#include <wchar.h>\n#include <wctype.h>\n#include <stddef.h>\n#include <stdbool.h>\n\n/* We need some of the locale data (the collation sequence information)\n   but there is no interface to get this information in general.  Therefore\n   we support a correct implementation only in glibc.  */\n#ifdef _LIBC\n# include \"../locale/localeinfo.h\"\n# include \"../locale/coll-lookup.h\"\n# include <shlib-compat.h>\n\n# define CONCAT(a,b) __CONCAT(a,b)\n# define btowc __btowc\n# define iswctype __iswctype\n# define mbsrtowcs __mbsrtowcs\n# define mempcpy __mempcpy\n# define strnlen __strnlen\n# define towlower __towlower\n# define wcscat __wcscat\n# define wcslen __wcslen\n# define wctype __wctype\n# define wmemchr __wmemchr\n# define wmempcpy __wmempcpy\n# define fnmatch __fnmatch\nextern int fnmatch (const char *pattern, const char *string, int flags);\n#endif\n\n#ifdef _LIBC\n# if __GNUC__ >= 7\n#  define FALLTHROUGH __attribute__ ((__fallthrough__))\n# else\n#  define FALLTHROUGH ((void) 0)\n# endif\n#else\n# include \"attribute.h\"\n#endif\n\n#include <intprops.h>\n#include <flexmember.h>\n\n#ifdef _LIBC\ntypedef ptrdiff_t idx_t;\n#else\n# include \"idx.h\"\n#endif\n\n/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set.  */\n#define NO_LEADING_PERIOD(flags) \\\n  ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))\n\n#ifndef _LIBC\n# if HAVE_ALLOCA\n/* The OS usually guarantees only one guard page at the bottom of the stack,\n   and a page size can be as small as 4096 bytes.  So we cannot safely\n   allocate anything larger than 4096 bytes.  Also care for the possibility\n   of a few compiler-allocated temporary stack slots.  */\n#  define __libc_use_alloca(n) ((n) < 4032)\n# else\n/* Just use malloc.  */\n#  define __libc_use_alloca(n) false\n#  undef alloca\n#  define alloca(n) malloc (n)\n# endif\n# define alloca_account(size, avar) ((avar) += (size), alloca (size))\n#endif\n\n/* Provide support for user-defined character classes, based on the functions\n   from ISO C 90 amendment 1.  */\n#ifdef CHARCLASS_NAME_MAX\n# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX\n#else\n/* This shouldn't happen but some implementation might still have this\n   problem.  Use a reasonable default value.  */\n# define CHAR_CLASS_MAX_LENGTH 256\n#endif\n\n#define IS_CHAR_CLASS(string) wctype (string)\n\n/* Avoid depending on library functions or files\n   whose names are inconsistent.  */\n\n/* Global variable.  */\nstatic int posixly_correct;\n\n/* Note that this evaluates C many times.  */\n#define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))\n#define CHAR    char\n#define UCHAR   unsigned char\n#define INT     int\n#define FCT     internal_fnmatch\n#define EXT     ext_match\n#define END     end_pattern\n#define STRUCT  fnmatch_struct\n#define L_(CS)  CS\n#define BTOWC(C) btowc (C)\n#define STRLEN(S) strlen (S)\n#define STRCAT(D, S) strcat (D, S)\n#define MEMPCPY(D, S, N) mempcpy (D, S, N)\n#define MEMCHR(S, C, N) memchr (S, C, N)\n#define WIDE_CHAR_VERSION 0\n#ifdef _LIBC\n# include <locale/weight.h>\n# define FINDIDX findidx\n#endif\n#include \"fnmatch_loop.c\"\n\n\n#define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))\n#define CHAR    wchar_t\n#define UCHAR   wint_t\n#define INT     wint_t\n#define FCT     internal_fnwmatch\n#define EXT     ext_wmatch\n#define END     end_wpattern\n#define L_(CS)  L##CS\n#define BTOWC(C) (C)\n#define STRLEN(S) wcslen (S)\n#define STRCAT(D, S) wcscat (D, S)\n#define MEMPCPY(D, S, N) wmempcpy (D, S, N)\n#define MEMCHR(S, C, N) wmemchr (S, C, N)\n#define WIDE_CHAR_VERSION 1\n#ifdef _LIBC\n/* Change the name the header defines so it doesn't conflict with\n   the <locale/weight.h> version included above.  */\n# define findidx findidxwc\n# include <locale/weightwc.h>\n# undef findidx\n# define FINDIDX findidxwc\n#endif\n\n#undef IS_CHAR_CLASS\n/* We have to convert the wide character string in a multibyte string.  But\n   we know that the character class names consist of alphanumeric characters\n   from the portable character set, and since the wide character encoding\n   for a member of the portable character set is the same code point as\n   its single-byte encoding, we can use a simplified method to convert the\n   string to a multibyte character string.  */\nstatic wctype_t\nis_char_class (const wchar_t *wcs)\n{\n  char s[CHAR_CLASS_MAX_LENGTH + 1];\n  char *cp = s;\n\n  do\n    {\n      /* Test for a printable character from the portable character set.  */\n#ifdef _LIBC\n      if (*wcs < 0x20 || *wcs > 0x7e\n          || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)\n        return (wctype_t) 0;\n#else\n      switch (*wcs)\n        {\n        case L' ': case L'!': case L'\"': case L'#': case L'%':\n        case L'&': case L'\\'': case L'(': case L')': case L'*':\n        case L'+': case L',': case L'-': case L'.': case L'/':\n        case L'0': case L'1': case L'2': case L'3': case L'4':\n        case L'5': case L'6': case L'7': case L'8': case L'9':\n        case L':': case L';': case L'<': case L'=': case L'>':\n        case L'?':\n        case L'A': case L'B': case L'C': case L'D': case L'E':\n        case L'F': case L'G': case L'H': case L'I': case L'J':\n        case L'K': case L'L': case L'M': case L'N': case L'O':\n        case L'P': case L'Q': case L'R': case L'S': case L'T':\n        case L'U': case L'V': case L'W': case L'X': case L'Y':\n        case L'Z':\n        case L'[': case L'\\\\': case L']': case L'^': case L'_':\n        case L'a': case L'b': case L'c': case L'd': case L'e':\n        case L'f': case L'g': case L'h': case L'i': case L'j':\n        case L'k': case L'l': case L'm': case L'n': case L'o':\n        case L'p': case L'q': case L'r': case L's': case L't':\n        case L'u': case L'v': case L'w': case L'x': case L'y':\n        case L'z': case L'{': case L'|': case L'}': case L'~':\n          break;\n        default:\n          return (wctype_t) 0;\n        }\n#endif\n\n      /* Avoid overrunning the buffer.  */\n      if (cp == s + CHAR_CLASS_MAX_LENGTH)\n        return (wctype_t) 0;\n\n      *cp++ = (char) *wcs++;\n    }\n  while (*wcs != L'\\0');\n\n  *cp = '\\0';\n\n  return wctype (s);\n}\n#define IS_CHAR_CLASS(string) is_char_class (string)\n\n#include \"fnmatch_loop.c\"\n\n\nint\nfnmatch (const char *pattern, const char *string, int flags)\n{\n  if (__glibc_unlikely (MB_CUR_MAX != 1))\n    {\n      mbstate_t ps;\n      size_t n;\n      const char *p;\n      wchar_t *wpattern_malloc = NULL;\n      wchar_t *wpattern;\n      wchar_t *wstring_malloc = NULL;\n      wchar_t *wstring;\n      size_t alloca_used = 0;\n\n      /* Convert the strings into wide characters.  */\n      memset (&ps, '\\0', sizeof (ps));\n      p = pattern;\n      n = strnlen (pattern, 1024);\n      if (__glibc_likely (n < 1024))\n        {\n          wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),\n                                                 alloca_used);\n          n = mbsrtowcs (wpattern, &p, n + 1, &ps);\n          if (__glibc_unlikely (n == (size_t) -1))\n            /* Something wrong.\n               XXX Do we have to set 'errno' to something which mbsrtows hasn't\n               already done?  */\n            return -1;\n          if (p)\n            {\n              memset (&ps, '\\0', sizeof (ps));\n              goto prepare_wpattern;\n            }\n        }\n      else\n        {\n        prepare_wpattern:\n          n = mbsrtowcs (NULL, &pattern, 0, &ps);\n          if (__glibc_unlikely (n == (size_t) -1))\n            /* Something wrong.\n               XXX Do we have to set 'errno' to something which mbsrtows hasn't\n               already done?  */\n            return -1;\n          if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))\n            {\n              __set_errno (ENOMEM);\n              return -2;\n            }\n          wpattern_malloc = wpattern\n            = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));\n          assert (mbsinit (&ps));\n          if (wpattern == NULL)\n            return -2;\n          (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);\n        }\n\n      assert (mbsinit (&ps));\n      n = strnlen (string, 1024);\n      p = string;\n      if (__glibc_likely (n < 1024))\n        {\n          wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),\n                                                alloca_used);\n          n = mbsrtowcs (wstring, &p, n + 1, &ps);\n          if (__glibc_unlikely (n == (size_t) -1))\n            {\n              /* Something wrong.\n                 XXX Do we have to set 'errno' to something which\n                 mbsrtows hasn't already done?  */\n            free_return:\n              free (wpattern_malloc);\n              return -1;\n            }\n          if (p)\n            {\n              memset (&ps, '\\0', sizeof (ps));\n              goto prepare_wstring;\n            }\n        }\n      else\n        {\n        prepare_wstring:\n          n = mbsrtowcs (NULL, &string, 0, &ps);\n          if (__glibc_unlikely (n == (size_t) -1))\n            /* Something wrong.\n               XXX Do we have to set 'errno' to something which mbsrtows hasn't\n               already done?  */\n            goto free_return;\n          if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))\n            {\n              free (wpattern_malloc);\n              __set_errno (ENOMEM);\n              return -2;\n            }\n\n          wstring_malloc = wstring\n            = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));\n          if (wstring == NULL)\n            {\n              free (wpattern_malloc);\n              return -2;\n            }\n          assert (mbsinit (&ps));\n          (void) mbsrtowcs (wstring, &string, n + 1, &ps);\n        }\n\n      int res = internal_fnwmatch (wpattern, wstring, wstring + n,\n                                   flags & FNM_PERIOD, flags, NULL,\n                                   alloca_used);\n\n      free (wstring_malloc);\n      free (wpattern_malloc);\n\n      return res;\n    }\n\n  return internal_fnmatch (pattern, string, string + strlen (string),\n                           flags & FNM_PERIOD, flags, NULL, 0);\n}\n\n#undef fnmatch\nversioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);\n#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)\nstrong_alias (__fnmatch, __fnmatch_old)\ncompat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);\n#endif\nlibc_hidden_ver (__fnmatch, fnmatch)\n"
  },
  {
    "path": "gnulib/fnmatch.in.h",
    "content": "/* Substitute for and wrapper around <fnmatch.h>.\n   Copyright (C) 1991-1993, 1996-1999, 2001-2003, 2005, 2007, 2009-2021 Free\n   Software Foundation, Inc.\n\n   This file is part of the GNU C Library.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _@GUARD_PREFIX@_FNMATCH_H\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n/* The include_next requires a split double-inclusion guard.  */\n#if @HAVE_FNMATCH_H@ && !@REPLACE_FNMATCH@\n# @INCLUDE_NEXT@ @NEXT_FNMATCH_H@\n#endif\n\n#ifndef _@GUARD_PREFIX@_FNMATCH_H\n#define _@GUARD_PREFIX@_FNMATCH_H\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n\n#if !@HAVE_FNMATCH_H@ || @REPLACE_FNMATCH@\n\n/* We #undef these before defining them because some losing systems\n   (HP-UX A.08.07 for example) define these in <unistd.h>.  */\n#undef  FNM_PATHNAME\n#undef  FNM_NOESCAPE\n#undef  FNM_PERIOD\n\n/* Bits set in the FLAGS argument to 'fnmatch'.  */\n#define FNM_PATHNAME    (1 << 0) /* No wildcard can ever match '/'.  */\n#define FNM_NOESCAPE    (1 << 1) /* Backslashes don't quote special chars.  */\n#define FNM_PERIOD      (1 << 2) /* Leading '.' is matched only explicitly.  */\n\n#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE\n# define FNM_FILE_NAME   FNM_PATHNAME   /* Preferred GNU name.  */\n# define FNM_LEADING_DIR (1 << 3)       /* Ignore '/...' after a match.  */\n# define FNM_CASEFOLD    (1 << 4)       /* Compare without regard to case.  */\n# define FNM_EXTMATCH    (1 << 5)       /* Use ksh-like extended matching. */\n#endif\n\n/* Value returned by 'fnmatch' if STRING does not match PATTERN.  */\n#define FNM_NOMATCH     1\n\n/* This value is returned if the implementation does not support\n   'fnmatch'.  Since this is not the case here it will never be\n   returned but the conformance test suites still require the symbol\n   to be defined.  */\n#ifdef _XOPEN_SOURCE\n# define FNM_NOSYS      (-1)\n#endif\n\n#endif\n\n\n#if @GNULIB_FNMATCH@\n/* Match NAME against the file name pattern PATTERN,\n   returning zero if it matches, FNM_NOMATCH if not.  */\n# if @REPLACE_FNMATCH@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define fnmatch rpl_fnmatch\n#  endif\n_GL_FUNCDECL_RPL (fnmatch, int,\n                  (const char *pattern, const char *name, int flags)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (fnmatch, int,\n                  (const char *pattern, const char *name, int flags));\n# else\n#  if !@HAVE_FNMATCH@\n_GL_FUNCDECL_SYS (fnmatch, int,\n                  (const char *pattern, const char *name, int flags)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (fnmatch, int,\n                  (const char *pattern, const char *name, int flags));\n# endif\n# if !GNULIB_FNMATCH_GNU && __GLIBC__ >= 2\n_GL_CXXALIASWARN (fnmatch);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef fnmatch\n# if HAVE_RAW_DECL_FNMATCH\n_GL_WARN_ON_USE (fnmatch,\n                 \"fnmatch does not portably work - \"\n                 \"use gnulib module fnmatch for portability or gnulib module fnmatch-gnu for a glibc compatible implementation\");\n# endif\n#endif\n\n\n#endif /* _@GUARD_PREFIX@_FNMATCH_H */\n#endif /* _@GUARD_PREFIX@_FNMATCH_H */\n"
  },
  {
    "path": "gnulib/fnmatch_loop.c",
    "content": "/* Copyright (C) 1991-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifdef _LIBC\n# include <stdint.h>\n#endif\n\nstruct STRUCT\n{\n  const CHAR *pattern;\n  const CHAR *string;\n  bool no_leading_period;\n};\n\n/* Match STRING against the file name pattern PATTERN, returning zero if\n   it matches, nonzero if not.  */\nstatic int FCT (const CHAR *pattern, const CHAR *string,\n                const CHAR *string_end, bool no_leading_period, int flags,\n                struct STRUCT *ends, size_t alloca_used);\nstatic int EXT (INT opt, const CHAR *pattern, const CHAR *string,\n                const CHAR *string_end, bool no_leading_period, int flags,\n                size_t alloca_used);\nstatic const CHAR *END (const CHAR *patternp);\n\nstatic int\nFCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,\n     bool no_leading_period, int flags, struct STRUCT *ends, size_t alloca_used)\n{\n  const CHAR *p = pattern, *n = string;\n  UCHAR c;\n#ifdef _LIBC\n# if WIDE_CHAR_VERSION\n  const char *collseq = (const char *)\n    _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);\n# else\n  const UCHAR *collseq = (const UCHAR *)\n    _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);\n# endif\n#endif\n\n  while ((c = *p++) != L_('\\0'))\n    {\n      bool new_no_leading_period = false;\n      c = FOLD (c);\n\n      switch (c)\n        {\n        case L_('?'):\n          if (__glibc_unlikely (flags & FNM_EXTMATCH) && *p == '(')\n            {\n              int res = EXT (c, p, n, string_end, no_leading_period,\n                             flags, alloca_used);\n              if (res != -1)\n                return res;\n            }\n\n          if (n == string_end)\n            return FNM_NOMATCH;\n          else if (*n == L_('/') && (flags & FNM_FILE_NAME))\n            return FNM_NOMATCH;\n          else if (*n == L_('.') && no_leading_period)\n            return FNM_NOMATCH;\n          break;\n\n        case L_('\\\\'):\n          if (!(flags & FNM_NOESCAPE))\n            {\n              c = *p++;\n              if (c == L_('\\0'))\n                /* Trailing \\ loses.  */\n                return FNM_NOMATCH;\n              c = FOLD (c);\n            }\n          if (n == string_end || FOLD ((UCHAR) *n) != c)\n            return FNM_NOMATCH;\n          break;\n\n        case L_('*'):\n          if (__glibc_unlikely (flags & FNM_EXTMATCH) && *p == '(')\n            {\n              int res = EXT (c, p, n, string_end, no_leading_period,\n                             flags, alloca_used);\n              if (res != -1)\n                return res;\n            }\n          else if (ends != NULL)\n            {\n              ends->pattern = p - 1;\n              ends->string = n;\n              ends->no_leading_period = no_leading_period;\n              return 0;\n            }\n\n          if (n != string_end && *n == L_('.') && no_leading_period)\n            return FNM_NOMATCH;\n\n          for (c = *p++; c == L_('?') || c == L_('*'); c = *p++)\n            {\n              if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0)\n                {\n                  const CHAR *endp = END (p);\n                  if (endp != p)\n                    {\n                      /* This is a pattern.  Skip over it.  */\n                      p = endp;\n                      continue;\n                    }\n                }\n\n              if (c == L_('?'))\n                {\n                  /* A ? needs to match one character.  */\n                  if (n == string_end)\n                    /* There isn't another character; no match.  */\n                    return FNM_NOMATCH;\n                  else if (*n == L_('/')\n                           && __glibc_unlikely (flags & FNM_FILE_NAME))\n                    /* A slash does not match a wildcard under\n                       FNM_FILE_NAME.  */\n                    return FNM_NOMATCH;\n                  else\n                    /* One character of the string is consumed in matching\n                       this ? wildcard, so *??? won't match if there are\n                       less than three characters.  */\n                    ++n;\n                }\n            }\n\n          if (c == L_('\\0'))\n            /* The wildcard(s) is/are the last element of the pattern.\n               If the name is a file name and contains another slash\n               this means it cannot match, unless the FNM_LEADING_DIR\n               flag is set.  */\n            {\n              int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;\n\n              if (flags & FNM_FILE_NAME)\n                {\n                  if (flags & FNM_LEADING_DIR)\n                    result = 0;\n                  else\n                    {\n                      if (MEMCHR (n, L_('/'), string_end - n) == NULL)\n                        result = 0;\n                    }\n                }\n\n              return result;\n            }\n          else\n            {\n              const CHAR *endp;\n              struct STRUCT end;\n\n              end.pattern = NULL;\n              endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\\0'),\n                             string_end - n);\n              if (endp == NULL)\n                endp = string_end;\n\n              if (c == L_('[')\n                  || (__glibc_unlikely (flags & FNM_EXTMATCH)\n                      && (c == L_('@') || c == L_('+') || c == L_('!'))\n                      && *p == L_('(')))\n                {\n                  int flags2 = ((flags & FNM_FILE_NAME)\n                                ? flags : (flags & ~FNM_PERIOD));\n\n                  for (--p; n < endp; ++n, no_leading_period = false)\n                    if (FCT (p, n, string_end, no_leading_period, flags2,\n                             &end, alloca_used) == 0)\n                      goto found;\n                }\n              else if (c == L_('/') && (flags & FNM_FILE_NAME))\n                {\n                  while (n < string_end && *n != L_('/'))\n                    ++n;\n                  if (n < string_end && *n == L_('/')\n                      && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags,\n                               NULL, alloca_used) == 0))\n                    return 0;\n                }\n              else\n                {\n                  int flags2 = ((flags & FNM_FILE_NAME)\n                                ? flags : (flags & ~FNM_PERIOD));\n\n                  if (c == L_('\\\\') && !(flags & FNM_NOESCAPE))\n                    c = *p;\n                  c = FOLD (c);\n                  for (--p; n < endp; ++n, no_leading_period = false)\n                    if (FOLD ((UCHAR) *n) == c\n                        && (FCT (p, n, string_end, no_leading_period, flags2,\n                                 &end, alloca_used) == 0))\n                      {\n                      found:\n                        if (end.pattern == NULL)\n                          return 0;\n                        break;\n                      }\n                  if (end.pattern != NULL)\n                    {\n                      p = end.pattern;\n                      n = end.string;\n                      no_leading_period = end.no_leading_period;\n                      continue;\n                    }\n                }\n            }\n\n          /* If we come here no match is possible with the wildcard.  */\n          return FNM_NOMATCH;\n\n        case L_('['):\n          {\n            /* Nonzero if the sense of the character class is inverted.  */\n            const CHAR *p_init = p;\n            const CHAR *n_init = n;\n            bool not;\n            CHAR cold;\n            UCHAR fn;\n\n            if (posixly_correct == 0)\n              posixly_correct = getenv (\"POSIXLY_CORRECT\") != NULL ? 1 : -1;\n\n            if (n == string_end)\n              return FNM_NOMATCH;\n\n            if (*n == L_('.') && no_leading_period)\n              return FNM_NOMATCH;\n\n            if (*n == L_('/') && (flags & FNM_FILE_NAME))\n              /* '/' cannot be matched.  */\n              return FNM_NOMATCH;\n\n            not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^')));\n            if (not)\n              ++p;\n\n            fn = FOLD ((UCHAR) *n);\n\n            c = *p++;\n            for (;;)\n              {\n                if (!(flags & FNM_NOESCAPE) && c == L_('\\\\'))\n                  {\n                    if (*p == L_('\\0'))\n                      return FNM_NOMATCH;\n                    c = FOLD ((UCHAR) *p);\n                    ++p;\n\n                    goto normal_bracket;\n                  }\n                else if (c == L_('[') && *p == L_(':'))\n                  {\n                    /* Leave room for the null.  */\n                    CHAR str[CHAR_CLASS_MAX_LENGTH + 1];\n                    size_t c1 = 0;\n                    wctype_t wt;\n                    const CHAR *startp = p;\n\n                    for (;;)\n                      {\n                        if (c1 == CHAR_CLASS_MAX_LENGTH)\n                          /* The name is too long and therefore the pattern\n                             is ill-formed.  */\n                          return FNM_NOMATCH;\n\n                        c = *++p;\n                        if (c == L_(':') && p[1] == L_(']'))\n                          {\n                            p += 2;\n                            break;\n                          }\n                        if (c < L_('a') || c >= L_('z'))\n                          {\n                            /* This cannot possibly be a character class name.\n                               Match it as a normal range.  */\n                            p = startp;\n                            c = L_('[');\n                            goto normal_bracket;\n                          }\n                        str[c1++] = c;\n                      }\n                    str[c1] = L_('\\0');\n\n                    wt = IS_CHAR_CLASS (str);\n                    if (wt == 0)\n                      /* Invalid character class name.  */\n                      return FNM_NOMATCH;\n\n#if defined _LIBC && ! WIDE_CHAR_VERSION\n                    /* The following code is glibc specific but does\n                       there a good job in speeding up the code since\n                       we can avoid the btowc() call.  */\n                    if (_ISCTYPE ((UCHAR) *n, wt))\n                      goto matched;\n#else\n                    if (iswctype (BTOWC ((UCHAR) *n), wt))\n                      goto matched;\n#endif\n                    c = *p++;\n                  }\n#ifdef _LIBC\n                else if (c == L_('[') && *p == L_('='))\n                  {\n                    /* It's important that STR be a scalar variable rather\n                       than a one-element array, because GCC (at least 4.9.2\n                       -O2 on x86-64) can be confused by the array and\n                       diagnose a \"used initialized\" in a dead branch in the\n                       findidx function.  */\n                    UCHAR str;\n                    uint32_t nrules =\n                      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);\n                    const CHAR *startp = p;\n\n                    c = *++p;\n                    if (c == L_('\\0'))\n                      {\n                        p = startp;\n                        c = L_('[');\n                        goto normal_bracket;\n                      }\n                    str = c;\n\n                    c = *++p;\n                    if (c != L_('=') || p[1] != L_(']'))\n                      {\n                        p = startp;\n                        c = L_('[');\n                        goto normal_bracket;\n                      }\n                    p += 2;\n\n                    if (nrules == 0)\n                      {\n                        if ((UCHAR) *n == str)\n                          goto matched;\n                      }\n                    else\n                      {\n                        const int32_t *table;\n# if WIDE_CHAR_VERSION\n                        const int32_t *weights;\n                        const wint_t *extra;\n# else\n                        const unsigned char *weights;\n                        const unsigned char *extra;\n# endif\n                        const int32_t *indirect;\n                        int32_t idx;\n                        const UCHAR *cp = (const UCHAR *) &str;\n\n# if WIDE_CHAR_VERSION\n                        table = (const int32_t *)\n                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);\n                        weights = (const int32_t *)\n                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);\n                        extra = (const wint_t *)\n                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);\n                        indirect = (const int32_t *)\n                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);\n# else\n                        table = (const int32_t *)\n                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);\n                        weights = (const unsigned char *)\n                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);\n                        extra = (const unsigned char *)\n                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);\n                        indirect = (const int32_t *)\n                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);\n# endif\n\n                        idx = FINDIDX (table, indirect, extra, &cp, 1);\n                        if (idx != 0)\n                          {\n                            /* We found a table entry.  Now see whether the\n                               character we are currently at has the same\n                               equivalence class value.  */\n                            int len = weights[idx & 0xffffff];\n                            int32_t idx2;\n                            const UCHAR *np = (const UCHAR *) n;\n\n                            idx2 = FINDIDX (table, indirect, extra,\n                                            &np, string_end - n);\n                            if (idx2 != 0\n                                && (idx >> 24) == (idx2 >> 24)\n                                && len == weights[idx2 & 0xffffff])\n                              {\n                                int cnt = 0;\n\n                                idx &= 0xffffff;\n                                idx2 &= 0xffffff;\n\n                                while (cnt < len\n                                       && (weights[idx + 1 + cnt]\n                                           == weights[idx2 + 1 + cnt]))\n                                  ++cnt;\n\n                                if (cnt == len)\n                                  goto matched;\n                              }\n                          }\n                      }\n\n                    c = *p++;\n                  }\n#endif\n                else if (c == L_('\\0'))\n                  {\n                    /* [ unterminated, treat as normal character.  */\n                    p = p_init;\n                    n = n_init;\n                    c = L_('[');\n                    goto normal_match;\n                  }\n                else\n                  {\n                    bool is_range = false;\n\n#ifdef _LIBC\n                    bool is_seqval = false;\n\n                    if (c == L_('[') && *p == L_('.'))\n                      {\n                        uint32_t nrules =\n                          _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);\n                        const CHAR *startp = p;\n                        size_t c1 = 0;\n\n                        while (1)\n                          {\n                            c = *++p;\n                            if (c == L_('.') && p[1] == L_(']'))\n                              {\n                                p += 2;\n                                break;\n                              }\n                            if (c == '\\0')\n                              return FNM_NOMATCH;\n                            ++c1;\n                          }\n\n                        /* We have to handling the symbols differently in\n                           ranges since then the collation sequence is\n                           important.  */\n                        is_range = *p == L_('-') && p[1] != L_('\\0');\n\n                        if (nrules == 0)\n                          {\n                            /* There are no names defined in the collation\n                               data.  Therefore we only accept the trivial\n                               names consisting of the character itself.  */\n                            if (c1 != 1)\n                              return FNM_NOMATCH;\n\n                            if (!is_range && *n == startp[1])\n                              goto matched;\n\n                            cold = startp[1];\n                            c = *p++;\n                          }\n                        else\n                          {\n                            int32_t table_size;\n                            const int32_t *symb_table;\n                            const unsigned char *extra;\n                            int32_t idx;\n                            int32_t elem;\n# if WIDE_CHAR_VERSION\n                            CHAR *wextra;\n# endif\n\n                            table_size =\n                              _NL_CURRENT_WORD (LC_COLLATE,\n                                                _NL_COLLATE_SYMB_HASH_SIZEMB);\n                            symb_table = (const int32_t *)\n                              _NL_CURRENT (LC_COLLATE,\n                                           _NL_COLLATE_SYMB_TABLEMB);\n                            extra = (const unsigned char *)\n                              _NL_CURRENT (LC_COLLATE,\n                                           _NL_COLLATE_SYMB_EXTRAMB);\n\n                            for (elem = 0; elem < table_size; elem++)\n                              if (symb_table[2 * elem] != 0)\n                                {\n                                  idx = symb_table[2 * elem + 1];\n                                  /* Skip the name of collating element.  */\n                                  idx += 1 + extra[idx];\n# if WIDE_CHAR_VERSION\n                                  /* Skip the byte sequence of the\n                                     collating element.  */\n                                  idx += 1 + extra[idx];\n                                  /* Adjust for the alignment.  */\n                                  idx = (idx + 3) & ~3;\n\n                                  wextra = (CHAR *) &extra[idx + 4];\n\n                                  if (/* Compare the length of the sequence.  */\n                                      c1 == wextra[0]\n                                      /* Compare the wide char sequence.  */\n                                      && (__wmemcmp (startp + 1, &wextra[1],\n                                                     c1)\n                                          == 0))\n                                    /* Yep, this is the entry.  */\n                                    break;\n# else\n                                  if (/* Compare the length of the sequence.  */\n                                      c1 == extra[idx]\n                                      /* Compare the byte sequence.  */\n                                      && memcmp (startp + 1,\n                                                 &extra[idx + 1], c1) == 0)\n                                    /* Yep, this is the entry.  */\n                                    break;\n# endif\n                                }\n\n                            if (elem < table_size)\n                              {\n                                /* Compare the byte sequence but only if\n                                   this is not part of a range.  */\n                                if (! is_range\n\n# if WIDE_CHAR_VERSION\n                                    && __wmemcmp (n, &wextra[1], c1) == 0\n# else\n                                    && memcmp (n, &extra[idx + 1], c1) == 0\n# endif\n                                    )\n                                  {\n                                    n += c1 - 1;\n                                    goto matched;\n                                  }\n\n                                /* Get the collation sequence value.  */\n                                is_seqval = true;\n# if WIDE_CHAR_VERSION\n                                cold = wextra[1 + wextra[0]];\n# else\n                                idx += 1 + extra[idx];\n                                /* Adjust for the alignment.  */\n                                idx = (idx + 3) & ~3;\n                                cold = *((int32_t *) &extra[idx]);\n# endif\n\n                                c = *p++;\n                              }\n                            else if (c1 == 1)\n                              {\n                                /* No valid character.  Match it as a\n                                   single byte.  */\n                                if (!is_range && *n == startp[1])\n                                  goto matched;\n\n                                cold = startp[1];\n                                c = *p++;\n                              }\n                            else\n                              return FNM_NOMATCH;\n                          }\n                      }\n                    else\n#endif\n                      {\n                        c = FOLD (c);\n                      normal_bracket:\n\n                        /* We have to handling the symbols differently in\n                           ranges since then the collation sequence is\n                           important.  */\n                        is_range = (*p == L_('-') && p[1] != L_('\\0')\n                                    && p[1] != L_(']'));\n\n                        if (!is_range && c == fn)\n                          goto matched;\n\n#if _LIBC\n                        /* This is needed if we goto normal_bracket; from\n                           outside of is_seqval's scope.  */\n                        is_seqval = false;\n#endif\n                        cold = c;\n                        c = *p++;\n                      }\n\n                    if (c == L_('-') && *p != L_(']'))\n                      {\n#if _LIBC\n                        /* We have to find the collation sequence\n                           value for C.  Collation sequence is nothing\n                           we can regularly access.  The sequence\n                           value is defined by the order in which the\n                           definitions of the collation values for the\n                           various characters appear in the source\n                           file.  A strange concept, nowhere\n                           documented.  */\n                        uint32_t fcollseq;\n                        uint32_t lcollseq;\n                        UCHAR cend = *p++;\n\n# if WIDE_CHAR_VERSION\n                        /* Search in the 'names' array for the characters.  */\n                        fcollseq = __collseq_table_lookup (collseq, fn);\n                        if (fcollseq == ~((uint32_t) 0))\n                          /* XXX We don't know anything about the character\n                             we are supposed to match.  This means we are\n                             failing.  */\n                          goto range_not_matched;\n\n                        if (is_seqval)\n                          lcollseq = cold;\n                        else\n                          lcollseq = __collseq_table_lookup (collseq, cold);\n# else\n                        fcollseq = collseq[fn];\n                        lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];\n# endif\n\n                        is_seqval = false;\n                        if (cend == L_('[') && *p == L_('.'))\n                          {\n                            uint32_t nrules =\n                              _NL_CURRENT_WORD (LC_COLLATE,\n                                                _NL_COLLATE_NRULES);\n                            const CHAR *startp = p;\n                            size_t c1 = 0;\n\n                            while (1)\n                              {\n                                c = *++p;\n                                if (c == L_('.') && p[1] == L_(']'))\n                                  {\n                                    p += 2;\n                                    break;\n                                  }\n                                if (c == '\\0')\n                                  return FNM_NOMATCH;\n                                ++c1;\n                              }\n\n                            if (nrules == 0)\n                              {\n                                /* There are no names defined in the\n                                   collation data.  Therefore we only\n                                   accept the trivial names consisting\n                                   of the character itself.  */\n                                if (c1 != 1)\n                                  return FNM_NOMATCH;\n\n                                cend = startp[1];\n                              }\n                            else\n                              {\n                                int32_t table_size;\n                                const int32_t *symb_table;\n                                const unsigned char *extra;\n                                int32_t idx;\n                                int32_t elem;\n# if WIDE_CHAR_VERSION\n                                CHAR *wextra;\n# endif\n\n                                table_size =\n                                  _NL_CURRENT_WORD (LC_COLLATE,\n                                                    _NL_COLLATE_SYMB_HASH_SIZEMB);\n                                symb_table = (const int32_t *)\n                                  _NL_CURRENT (LC_COLLATE,\n                                               _NL_COLLATE_SYMB_TABLEMB);\n                                extra = (const unsigned char *)\n                                  _NL_CURRENT (LC_COLLATE,\n                                               _NL_COLLATE_SYMB_EXTRAMB);\n\n                                for (elem = 0; elem < table_size; elem++)\n                                  if (symb_table[2 * elem] != 0)\n                                    {\n                                      idx = symb_table[2 * elem + 1];\n                                      /* Skip the name of collating\n                                         element.  */\n                                      idx += 1 + extra[idx];\n# if WIDE_CHAR_VERSION\n                                      /* Skip the byte sequence of the\n                                         collating element.  */\n                                      idx += 1 + extra[idx];\n                                      /* Adjust for the alignment.  */\n                                      idx = (idx + 3) & ~3;\n\n                                      wextra = (CHAR *) &extra[idx + 4];\n\n                                      if (/* Compare the length of the\n                                             sequence.  */\n                                          c1 == wextra[0]\n                                          /* Compare the wide char sequence.  */\n                                          && (__wmemcmp (startp + 1,\n                                                         &wextra[1], c1)\n                                              == 0))\n                                        /* Yep, this is the entry.  */\n                                        break;\n# else\n                                      if (/* Compare the length of the\n                                             sequence.  */\n                                          c1 == extra[idx]\n                                          /* Compare the byte sequence.  */\n                                          && memcmp (startp + 1,\n                                                     &extra[idx + 1], c1) == 0)\n                                        /* Yep, this is the entry.  */\n                                        break;\n# endif\n                                    }\n\n                                if (elem < table_size)\n                                  {\n                                    /* Get the collation sequence value.  */\n                                    is_seqval = true;\n# if WIDE_CHAR_VERSION\n                                    cend = wextra[1 + wextra[0]];\n# else\n                                    idx += 1 + extra[idx];\n                                    /* Adjust for the alignment.  */\n                                    idx = (idx + 3) & ~3;\n                                    cend = *((int32_t *) &extra[idx]);\n# endif\n                                  }\n                                else if (c1 == 1)\n                                  {\n                                    cend = startp[1];\n                                    c = *p++;\n                                  }\n                                else\n                                  return FNM_NOMATCH;\n                              }\n                          }\n                        else\n                          {\n                            if (!(flags & FNM_NOESCAPE) && cend == L_('\\\\'))\n                              cend = *p++;\n                            if (cend == L_('\\0'))\n                              return FNM_NOMATCH;\n                            cend = FOLD (cend);\n                          }\n\n                        /* XXX It is not entirely clear to me how to handle\n                           characters which are not mentioned in the\n                           collation specification.  */\n                        if (\n# if WIDE_CHAR_VERSION\n                            lcollseq == 0xffffffff ||\n# endif\n                            lcollseq <= fcollseq)\n                          {\n                            /* We have to look at the upper bound.  */\n                            uint32_t hcollseq;\n\n                            if (is_seqval)\n                              hcollseq = cend;\n                            else\n                              {\n# if WIDE_CHAR_VERSION\n                                hcollseq =\n                                  __collseq_table_lookup (collseq, cend);\n                                if (hcollseq == ~((uint32_t) 0))\n                                  {\n                                    /* Hum, no information about the upper\n                                       bound.  The matching succeeds if the\n                                       lower bound is matched exactly.  */\n                                    if (lcollseq != fcollseq)\n                                      goto range_not_matched;\n\n                                    goto matched;\n                                  }\n# else\n                                hcollseq = collseq[cend];\n# endif\n                              }\n\n                            if (lcollseq <= hcollseq && fcollseq <= hcollseq)\n                              goto matched;\n                          }\n# if WIDE_CHAR_VERSION\n                      range_not_matched:\n# endif\n#else\n                        /* We use a boring value comparison of the character\n                           values.  This is better than comparing using\n                           'strcoll' since the latter would have surprising\n                           and sometimes fatal consequences.  */\n                        UCHAR cend = *p++;\n\n                        if (!(flags & FNM_NOESCAPE) && cend == L_('\\\\'))\n                          cend = *p++;\n                        if (cend == L_('\\0'))\n                          return FNM_NOMATCH;\n\n                        /* It is a range.  */\n                        if ((UCHAR) cold <= fn && fn <= cend)\n                          goto matched;\n#endif\n\n                        c = *p++;\n                      }\n                  }\n\n                if (c == L_(']'))\n                  break;\n              }\n\n            if (!not)\n              return FNM_NOMATCH;\n            break;\n\n          matched:\n            /* Skip the rest of the [...] that already matched.  */\n            while ((c = *p++) != L_(']'))\n              {\n                if (c == L_('\\0'))\n                  /* [... (unterminated) loses.  */\n                  return FNM_NOMATCH;\n\n                if (!(flags & FNM_NOESCAPE) && c == L_('\\\\'))\n                  {\n                    if (*p == L_('\\0'))\n                      return FNM_NOMATCH;\n                    /* XXX 1003.2d11 is unclear if this is right.  */\n                    ++p;\n                  }\n                else if (c == L_('[') && *p == L_(':'))\n                  {\n                    int c1 = 0;\n                    const CHAR *startp = p;\n\n                    while (1)\n                      {\n                        c = *++p;\n                        if (++c1 == CHAR_CLASS_MAX_LENGTH)\n                          return FNM_NOMATCH;\n\n                        if (*p == L_(':') && p[1] == L_(']'))\n                          break;\n\n                        if (c < L_('a') || c >= L_('z'))\n                          {\n                            p = startp - 2;\n                            break;\n                          }\n                      }\n                    p += 2;\n                  }\n                else if (c == L_('[') && *p == L_('='))\n                  {\n                    c = *++p;\n                    if (c == L_('\\0'))\n                      return FNM_NOMATCH;\n                    c = *++p;\n                    if (c != L_('=') || p[1] != L_(']'))\n                      return FNM_NOMATCH;\n                    p += 2;\n                  }\n                else if (c == L_('[') && *p == L_('.'))\n                  {\n                    while (1)\n                      {\n                        c = *++p;\n                        if (c == L_('\\0'))\n                          return FNM_NOMATCH;\n\n                        if (c == L_('.') && p[1] == L_(']'))\n                          break;\n                      }\n                    p += 2;\n                  }\n              }\n            if (not)\n              return FNM_NOMATCH;\n          }\n          break;\n\n        case L_('+'):\n        case L_('@'):\n        case L_('!'):\n          if (__glibc_unlikely (flags & FNM_EXTMATCH) && *p == '(')\n            {\n              int res = EXT (c, p, n, string_end, no_leading_period, flags,\n                             alloca_used);\n              if (res != -1)\n                return res;\n            }\n          goto normal_match;\n\n        case L_('/'):\n          if (NO_LEADING_PERIOD (flags))\n            {\n              if (n == string_end || c != (UCHAR) *n)\n                return FNM_NOMATCH;\n\n              new_no_leading_period = true;\n              break;\n            }\n          FALLTHROUGH;\n        default:\n        normal_match:\n          if (n == string_end || c != FOLD ((UCHAR) *n))\n            return FNM_NOMATCH;\n        }\n\n      no_leading_period = new_no_leading_period;\n      ++n;\n    }\n\n  if (n == string_end)\n    return 0;\n\n  if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/'))\n    /* The FNM_LEADING_DIR flag says that \"foo*\" matches \"foobar/frobozz\".  */\n    return 0;\n\n  return FNM_NOMATCH;\n}\n\n\nstatic const CHAR *\nEND (const CHAR *pattern)\n{\n  const CHAR *p = pattern;\n\n  while (1)\n    if (*++p == L_('\\0'))\n      /* This is an invalid pattern.  */\n      return pattern;\n    else if (*p == L_('['))\n      {\n        /* Handle brackets special.  */\n        if (posixly_correct == 0)\n          posixly_correct = getenv (\"POSIXLY_CORRECT\") != NULL ? 1 : -1;\n\n        /* Skip the not sign.  We have to recognize it because of a possibly\n           following ']'.  */\n        if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))\n          ++p;\n        /* A leading ']' is recognized as such.  */\n        if (*p == L_(']'))\n          ++p;\n        /* Skip over all characters of the list.  */\n        while (*p != L_(']'))\n          if (*p++ == L_('\\0'))\n            /* This is no valid pattern.  */\n            return pattern;\n      }\n    else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')\n              || *p == L_('!')) && p[1] == L_('('))\n      {\n        p = END (p + 1);\n        if (*p == L_('\\0'))\n          /* This is an invalid pattern.  */\n          return pattern;\n      }\n    else if (*p == L_(')'))\n      break;\n\n  return p + 1;\n}\n\n\nstatic int\nEXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,\n     bool no_leading_period, int flags, size_t alloca_used)\n{\n  const CHAR *startp;\n  ptrdiff_t level;\n  struct patternlist\n  {\n    struct patternlist *next;\n    CHAR malloced;\n    CHAR str __flexarr;\n  } *list = NULL;\n  struct patternlist **lastp = &list;\n  size_t pattern_len = STRLEN (pattern);\n  bool any_malloced = false;\n  const CHAR *p;\n  const CHAR *rs;\n  int retval = 0;\n\n  /* Parse the pattern.  Store the individual parts in the list.  */\n  level = 0;\n  for (startp = p = pattern + 1; level >= 0; ++p)\n    if (*p == L_('\\0'))\n      {\n        /* This is an invalid pattern.  */\n        retval = -1;\n        goto out;\n      }\n    else if (*p == L_('['))\n      {\n        /* Handle brackets special.  */\n        if (posixly_correct == 0)\n          posixly_correct = getenv (\"POSIXLY_CORRECT\") != NULL ? 1 : -1;\n\n        /* Skip the not sign.  We have to recognize it because of a possibly\n           following ']'.  */\n        if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))\n          ++p;\n        /* A leading ']' is recognized as such.  */\n        if (*p == L_(']'))\n          ++p;\n        /* Skip over all characters of the list.  */\n        while (*p != L_(']'))\n          if (*p++ == L_('\\0'))\n            {\n              /* This is no valid pattern.  */\n              retval = -1;\n              goto out;\n            }\n      }\n    else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')\n              || *p == L_('!')) && p[1] == L_('('))\n      /* Remember the nesting level.  */\n      ++level;\n    else if (*p == L_(')'))\n      {\n        if (level-- == 0)\n          {\n            /* This means we found the end of the pattern.  */\n#define NEW_PATTERN \\\n            struct patternlist *newp;                                         \\\n            size_t plen = (opt == L_('?') || opt == L_('@')                   \\\n                           ? pattern_len : (p - startp + 1UL));               \\\n            idx_t slen = FLEXSIZEOF (struct patternlist, str, 0);             \\\n            idx_t new_used = alloca_used + slen;                              \\\n            idx_t plensize;                                                   \\\n            if (INT_MULTIPLY_WRAPV (plen, sizeof (CHAR), &plensize)           \\\n                || INT_ADD_WRAPV (new_used, plensize, &new_used))             \\\n              {                                                               \\\n                retval = -2;                                                  \\\n                goto out;                                                     \\\n              }                                                               \\\n            slen += plensize;                                                 \\\n            bool malloced = ! __libc_use_alloca (new_used);                   \\\n            if (__glibc_unlikely (malloced))                                  \\\n              {                                                               \\\n                newp = malloc (slen);                                         \\\n                if (newp == NULL)                                             \\\n                  {                                                           \\\n                    retval = -2;                                              \\\n                    goto out;                                                 \\\n                  }                                                           \\\n                any_malloced = true;                                          \\\n              }                                                               \\\n            else                                                              \\\n              newp = alloca_account (slen, alloca_used);                      \\\n            newp->next = NULL;                                                \\\n            newp->malloced = malloced;                                        \\\n            *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\\0');   \\\n            *lastp = newp;                                                    \\\n            lastp = &newp->next\n            NEW_PATTERN;\n          }\n      }\n    else if (*p == L_('|'))\n      {\n        if (level == 0)\n          {\n            NEW_PATTERN;\n            startp = p + 1;\n          }\n      }\n  assert (list != NULL);\n  assert (p[-1] == L_(')'));\n#undef NEW_PATTERN\n\n  switch (opt)\n    {\n    case L_('*'):\n      if (FCT (p, string, string_end, no_leading_period, flags, NULL,\n               alloca_used) == 0)\n        goto success;\n      FALLTHROUGH;\n    case L_('+'):\n      do\n        {\n          for (rs = string; rs <= string_end; ++rs)\n            /* First match the prefix with the current pattern with the\n               current pattern.  */\n            if (FCT (list->str, string, rs, no_leading_period,\n                     flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,\n                     NULL, alloca_used) == 0\n                /* This was successful.  Now match the rest with the rest\n                   of the pattern.  */\n                && (FCT (p, rs, string_end,\n                         rs == string\n                         ? no_leading_period\n                         : rs[-1] == '/' && NO_LEADING_PERIOD (flags),\n                         flags & FNM_FILE_NAME\n                         ? flags : flags & ~FNM_PERIOD, NULL, alloca_used) == 0\n                    /* This didn't work.  Try the whole pattern.  */\n                    || (rs != string\n                        && FCT (pattern - 1, rs, string_end,\n                                rs == string\n                                ? no_leading_period\n                                : rs[-1] == '/' && NO_LEADING_PERIOD (flags),\n                                flags & FNM_FILE_NAME\n                                ? flags : flags & ~FNM_PERIOD, NULL,\n                                alloca_used) == 0)))\n              /* It worked.  Signal success.  */\n              goto success;\n        }\n      while ((list = list->next) != NULL);\n\n      /* None of the patterns lead to a match.  */\n      retval = FNM_NOMATCH;\n      break;\n\n    case L_('?'):\n      if (FCT (p, string, string_end, no_leading_period, flags, NULL,\n               alloca_used) == 0)\n        goto success;\n      FALLTHROUGH;\n    case L_('@'):\n      do\n        /* I cannot believe it but 'strcat' is actually acceptable\n           here.  Match the entire string with the prefix from the\n           pattern list and the rest of the pattern following the\n           pattern list.  */\n        if (FCT (STRCAT (list->str, p), string, string_end,\n                 no_leading_period,\n                 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,\n                 NULL, alloca_used) == 0)\n          /* It worked.  Signal success.  */\n          goto success;\n      while ((list = list->next) != NULL);\n\n      /* None of the patterns lead to a match.  */\n      retval = FNM_NOMATCH;\n      break;\n\n    case L_('!'):\n      for (rs = string; rs <= string_end; ++rs)\n        {\n          struct patternlist *runp;\n\n          for (runp = list; runp != NULL; runp = runp->next)\n            if (FCT (runp->str, string, rs,  no_leading_period,\n                     flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,\n                     NULL, alloca_used) == 0)\n              break;\n\n          /* If none of the patterns matched see whether the rest does.  */\n          if (runp == NULL\n              && (FCT (p, rs, string_end,\n                       rs == string\n                       ? no_leading_period\n                       : rs[-1] == '/' && NO_LEADING_PERIOD (flags),\n                       flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,\n                       NULL, alloca_used) == 0))\n            /* This is successful.  */\n            goto success;\n        }\n\n      /* None of the patterns together with the rest of the pattern\n         lead to a match.  */\n      retval = FNM_NOMATCH;\n      break;\n\n    default:\n      assert (! \"Invalid extended matching operator\");\n      retval = -1;\n      break;\n    }\n\n success:\n out:\n  if (any_malloced)\n    while (list != NULL)\n      {\n        struct patternlist *old = list;\n        list = list->next;\n        if (old->malloced)\n          free (old);\n      }\n\n  return retval;\n}\n\n\n#undef FOLD\n#undef CHAR\n#undef UCHAR\n#undef INT\n#undef FCT\n#undef EXT\n#undef END\n#undef STRUCT\n#undef MEMPCPY\n#undef MEMCHR\n#undef STRLEN\n#undef STRCAT\n#undef L_\n#undef BTOWC\n#undef WIDE_CHAR_VERSION\n#undef FINDIDX\n"
  },
  {
    "path": "gnulib/glthread/lock.c",
    "content": "/* Locking in multithreaded situations.\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-posix.h, gthr-posix95.h.  */\n\n#include <config.h>\n\n#include \"glthread/lock.h\"\n\n/* ========================================================================= */\n\n#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS\n\n/* -------------------------- gl_lock_t datatype -------------------------- */\n\nint\nglthread_lock_init (gl_lock_t *lock)\n{\n  if (mtx_init (&lock->mutex, mtx_plain) != thrd_success)\n    return ENOMEM;\n  lock->init_needed = 0;\n  return 0;\n}\n\nint\nglthread_lock_lock (gl_lock_t *lock)\n{\n  if (lock->init_needed)\n    call_once (&lock->init_once, lock->init_func);\n  if (mtx_lock (&lock->mutex) != thrd_success)\n    return EAGAIN;\n  return 0;\n}\n\nint\nglthread_lock_unlock (gl_lock_t *lock)\n{\n  if (lock->init_needed)\n    call_once (&lock->init_once, lock->init_func);\n  if (mtx_unlock (&lock->mutex) != thrd_success)\n    return EINVAL;\n  return 0;\n}\n\nint\nglthread_lock_destroy (gl_lock_t *lock)\n{\n  if (lock->init_needed)\n    call_once (&lock->init_once, lock->init_func);\n  mtx_destroy (&lock->mutex);\n  return 0;\n}\n\n/* ------------------------- gl_rwlock_t datatype ------------------------- */\n\nint\nglthread_rwlock_init (gl_rwlock_t *lock)\n{\n  if (mtx_init (&lock->lock, mtx_plain) != thrd_success\n      || cnd_init (&lock->waiting_readers) != thrd_success\n      || cnd_init (&lock->waiting_writers) != thrd_success)\n    return ENOMEM;\n  lock->waiting_writers_count = 0;\n  lock->runcount = 0;\n  lock->init_needed = 0;\n  return 0;\n}\n\nint\nglthread_rwlock_rdlock (gl_rwlock_t *lock)\n{\n  if (lock->init_needed)\n    call_once (&lock->init_once, lock->init_func);\n  if (mtx_lock (&lock->lock) != thrd_success)\n    return EAGAIN;\n  /* Test whether only readers are currently running, and whether the runcount\n     field will not overflow, and whether no writer is waiting.  The latter\n     condition is because POSIX recommends that \"write locks shall take\n     precedence over read locks\", to avoid \"writer starvation\".  */\n  while (!(lock->runcount + 1 > 0 && lock->waiting_writers_count == 0))\n    {\n      /* This thread has to wait for a while.  Enqueue it among the\n         waiting_readers.  */\n      if (cnd_wait (&lock->waiting_readers, &lock->lock) != thrd_success)\n        {\n          mtx_unlock (&lock->lock);\n          return EINVAL;\n        }\n    }\n  lock->runcount++;\n  if (mtx_unlock (&lock->lock) != thrd_success)\n    return EINVAL;\n  return 0;\n}\n\nint\nglthread_rwlock_wrlock (gl_rwlock_t *lock)\n{\n  if (lock->init_needed)\n    call_once (&lock->init_once, lock->init_func);\n  if (mtx_lock (&lock->lock) != thrd_success)\n    return EAGAIN;\n  /* Test whether no readers or writers are currently running.  */\n  while (!(lock->runcount == 0))\n    {\n      /* This thread has to wait for a while.  Enqueue it among the\n         waiting_writers.  */\n      lock->waiting_writers_count++;\n      if (cnd_wait (&lock->waiting_writers, &lock->lock) != thrd_success)\n        {\n          lock->waiting_writers_count--;\n          mtx_unlock (&lock->lock);\n          return EINVAL;\n        }\n      lock->waiting_writers_count--;\n    }\n  lock->runcount--; /* runcount becomes -1 */\n  if (mtx_unlock (&lock->lock) != thrd_success)\n    return EINVAL;\n  return 0;\n}\n\nint\nglthread_rwlock_unlock (gl_rwlock_t *lock)\n{\n  if (lock->init_needed)\n    call_once (&lock->init_once, lock->init_func);\n  if (mtx_lock (&lock->lock) != thrd_success)\n    return EAGAIN;\n  if (lock->runcount < 0)\n    {\n      /* Drop a writer lock.  */\n      if (!(lock->runcount == -1))\n        {\n          mtx_unlock (&lock->lock);\n          return EINVAL;\n        }\n      lock->runcount = 0;\n    }\n  else\n    {\n      /* Drop a reader lock.  */\n      if (!(lock->runcount > 0))\n        {\n          mtx_unlock (&lock->lock);\n          return EINVAL;\n        }\n      lock->runcount--;\n    }\n  if (lock->runcount == 0)\n    {\n      /* POSIX recommends that \"write locks shall take precedence over read\n         locks\", to avoid \"writer starvation\".  */\n      if (lock->waiting_writers_count > 0)\n        {\n          /* Wake up one of the waiting writers.  */\n          if (cnd_signal (&lock->waiting_writers) != thrd_success)\n            {\n              mtx_unlock (&lock->lock);\n              return EINVAL;\n            }\n        }\n      else\n        {\n          /* Wake up all waiting readers.  */\n          if (cnd_broadcast (&lock->waiting_readers) != thrd_success)\n            {\n              mtx_unlock (&lock->lock);\n              return EINVAL;\n            }\n        }\n    }\n  if (mtx_unlock (&lock->lock) != thrd_success)\n    return EINVAL;\n  return 0;\n}\n\nint\nglthread_rwlock_destroy (gl_rwlock_t *lock)\n{\n  if (lock->init_needed)\n    call_once (&lock->init_once, lock->init_func);\n  mtx_destroy (&lock->lock);\n  cnd_destroy (&lock->waiting_readers);\n  cnd_destroy (&lock->waiting_writers);\n  return 0;\n}\n\n/* --------------------- gl_recursive_lock_t datatype --------------------- */\n\nint\nglthread_recursive_lock_init (gl_recursive_lock_t *lock)\n{\n  if (mtx_init (&lock->mutex, mtx_plain | mtx_recursive) != thrd_success)\n    return ENOMEM;\n  lock->init_needed = 0;\n  return 0;\n}\n\nint\nglthread_recursive_lock_lock (gl_recursive_lock_t *lock)\n{\n  if (lock->init_needed)\n    call_once (&lock->init_once, lock->init_func);\n  if (mtx_lock (&lock->mutex) != thrd_success)\n    return EAGAIN;\n  return 0;\n}\n\nint\nglthread_recursive_lock_unlock (gl_recursive_lock_t *lock)\n{\n  if (lock->init_needed)\n    call_once (&lock->init_once, lock->init_func);\n  if (mtx_unlock (&lock->mutex) != thrd_success)\n    return EINVAL;\n  return 0;\n}\n\nint\nglthread_recursive_lock_destroy (gl_recursive_lock_t *lock)\n{\n  if (lock->init_needed)\n    call_once (&lock->init_once, lock->init_func);\n  mtx_destroy (&lock->mutex);\n  return 0;\n}\n\n/* -------------------------- gl_once_t datatype -------------------------- */\n\n#endif\n\n/* ========================================================================= */\n\n#if USE_POSIX_THREADS\n\n/* -------------------------- gl_lock_t datatype -------------------------- */\n\n/* ------------------------- gl_rwlock_t datatype ------------------------- */\n\n# if HAVE_PTHREAD_RWLOCK && (HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER || (defined PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP && (__GNU_LIBRARY__ > 1)))\n\n#  if defined PTHREAD_RWLOCK_INITIALIZER || defined PTHREAD_RWLOCK_INITIALIZER_NP\n\n#   if !HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER\n     /* glibc with bug https://sourceware.org/bugzilla/show_bug.cgi?id=13701 */\n\nint\nglthread_rwlock_init_for_glibc (pthread_rwlock_t *lock)\n{\n  pthread_rwlockattr_t attributes;\n  int err;\n\n  err = pthread_rwlockattr_init (&attributes);\n  if (err != 0)\n    return err;\n  /* Note: PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP is the only value that\n     causes the writer to be preferred. PTHREAD_RWLOCK_PREFER_WRITER_NP does not\n     do this; see\n     http://man7.org/linux/man-pages/man3/pthread_rwlockattr_setkind_np.3.html */\n  err = pthread_rwlockattr_setkind_np (&attributes,\n                                       PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);\n  if (err == 0)\n    err = pthread_rwlock_init(lock, &attributes);\n  /* pthread_rwlockattr_destroy always returns 0.  It cannot influence the\n     return value.  */\n  pthread_rwlockattr_destroy (&attributes);\n  return err;\n}\n\n#   endif\n#  else\n\nint\nglthread_rwlock_init_multithreaded (gl_rwlock_t *lock)\n{\n  int err;\n\n  err = pthread_rwlock_init (&lock->rwlock, NULL);\n  if (err != 0)\n    return err;\n  lock->initialized = 1;\n  return 0;\n}\n\nint\nglthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)\n{\n  if (!lock->initialized)\n    {\n      int err;\n\n      err = pthread_mutex_lock (&lock->guard);\n      if (err != 0)\n        return err;\n      if (!lock->initialized)\n        {\n          err = glthread_rwlock_init_multithreaded (lock);\n          if (err != 0)\n            {\n              pthread_mutex_unlock (&lock->guard);\n              return err;\n            }\n        }\n      err = pthread_mutex_unlock (&lock->guard);\n      if (err != 0)\n        return err;\n    }\n  return pthread_rwlock_rdlock (&lock->rwlock);\n}\n\nint\nglthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)\n{\n  if (!lock->initialized)\n    {\n      int err;\n\n      err = pthread_mutex_lock (&lock->guard);\n      if (err != 0)\n        return err;\n      if (!lock->initialized)\n        {\n          err = glthread_rwlock_init_multithreaded (lock);\n          if (err != 0)\n            {\n              pthread_mutex_unlock (&lock->guard);\n              return err;\n            }\n        }\n      err = pthread_mutex_unlock (&lock->guard);\n      if (err != 0)\n        return err;\n    }\n  return pthread_rwlock_wrlock (&lock->rwlock);\n}\n\nint\nglthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)\n{\n  if (!lock->initialized)\n    return EINVAL;\n  return pthread_rwlock_unlock (&lock->rwlock);\n}\n\nint\nglthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)\n{\n  int err;\n\n  if (!lock->initialized)\n    return EINVAL;\n  err = pthread_rwlock_destroy (&lock->rwlock);\n  if (err != 0)\n    return err;\n  lock->initialized = 0;\n  return 0;\n}\n\n#  endif\n\n# else\n\nint\nglthread_rwlock_init_multithreaded (gl_rwlock_t *lock)\n{\n  int err;\n\n  err = pthread_mutex_init (&lock->lock, NULL);\n  if (err != 0)\n    return err;\n  err = pthread_cond_init (&lock->waiting_readers, NULL);\n  if (err != 0)\n    return err;\n  err = pthread_cond_init (&lock->waiting_writers, NULL);\n  if (err != 0)\n    return err;\n  lock->waiting_writers_count = 0;\n  lock->runcount = 0;\n  return 0;\n}\n\nint\nglthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)\n{\n  int err;\n\n  err = pthread_mutex_lock (&lock->lock);\n  if (err != 0)\n    return err;\n  /* Test whether only readers are currently running, and whether the runcount\n     field will not overflow, and whether no writer is waiting.  The latter\n     condition is because POSIX recommends that \"write locks shall take\n     precedence over read locks\", to avoid \"writer starvation\".  */\n  while (!(lock->runcount + 1 > 0 && lock->waiting_writers_count == 0))\n    {\n      /* This thread has to wait for a while.  Enqueue it among the\n         waiting_readers.  */\n      err = pthread_cond_wait (&lock->waiting_readers, &lock->lock);\n      if (err != 0)\n        {\n          pthread_mutex_unlock (&lock->lock);\n          return err;\n        }\n    }\n  lock->runcount++;\n  return pthread_mutex_unlock (&lock->lock);\n}\n\nint\nglthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)\n{\n  int err;\n\n  err = pthread_mutex_lock (&lock->lock);\n  if (err != 0)\n    return err;\n  /* Test whether no readers or writers are currently running.  */\n  while (!(lock->runcount == 0))\n    {\n      /* This thread has to wait for a while.  Enqueue it among the\n         waiting_writers.  */\n      lock->waiting_writers_count++;\n      err = pthread_cond_wait (&lock->waiting_writers, &lock->lock);\n      if (err != 0)\n        {\n          lock->waiting_writers_count--;\n          pthread_mutex_unlock (&lock->lock);\n          return err;\n        }\n      lock->waiting_writers_count--;\n    }\n  lock->runcount--; /* runcount becomes -1 */\n  return pthread_mutex_unlock (&lock->lock);\n}\n\nint\nglthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)\n{\n  int err;\n\n  err = pthread_mutex_lock (&lock->lock);\n  if (err != 0)\n    return err;\n  if (lock->runcount < 0)\n    {\n      /* Drop a writer lock.  */\n      if (!(lock->runcount == -1))\n        {\n          pthread_mutex_unlock (&lock->lock);\n          return EINVAL;\n        }\n      lock->runcount = 0;\n    }\n  else\n    {\n      /* Drop a reader lock.  */\n      if (!(lock->runcount > 0))\n        {\n          pthread_mutex_unlock (&lock->lock);\n          return EINVAL;\n        }\n      lock->runcount--;\n    }\n  if (lock->runcount == 0)\n    {\n      /* POSIX recommends that \"write locks shall take precedence over read\n         locks\", to avoid \"writer starvation\".  */\n      if (lock->waiting_writers_count > 0)\n        {\n          /* Wake up one of the waiting writers.  */\n          err = pthread_cond_signal (&lock->waiting_writers);\n          if (err != 0)\n            {\n              pthread_mutex_unlock (&lock->lock);\n              return err;\n            }\n        }\n      else\n        {\n          /* Wake up all waiting readers.  */\n          err = pthread_cond_broadcast (&lock->waiting_readers);\n          if (err != 0)\n            {\n              pthread_mutex_unlock (&lock->lock);\n              return err;\n            }\n        }\n    }\n  return pthread_mutex_unlock (&lock->lock);\n}\n\nint\nglthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)\n{\n  int err;\n\n  err = pthread_mutex_destroy (&lock->lock);\n  if (err != 0)\n    return err;\n  err = pthread_cond_destroy (&lock->waiting_readers);\n  if (err != 0)\n    return err;\n  err = pthread_cond_destroy (&lock->waiting_writers);\n  if (err != 0)\n    return err;\n  return 0;\n}\n\n# endif\n\n/* --------------------- gl_recursive_lock_t datatype --------------------- */\n\n# if HAVE_PTHREAD_MUTEX_RECURSIVE\n\n#  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP\n\nint\nglthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)\n{\n  pthread_mutexattr_t attributes;\n  int err;\n\n  err = pthread_mutexattr_init (&attributes);\n  if (err != 0)\n    return err;\n  err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);\n  if (err != 0)\n    {\n      pthread_mutexattr_destroy (&attributes);\n      return err;\n    }\n  err = pthread_mutex_init (lock, &attributes);\n  if (err != 0)\n    {\n      pthread_mutexattr_destroy (&attributes);\n      return err;\n    }\n  err = pthread_mutexattr_destroy (&attributes);\n  if (err != 0)\n    return err;\n  return 0;\n}\n\n#  else\n\nint\nglthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)\n{\n  pthread_mutexattr_t attributes;\n  int err;\n\n  err = pthread_mutexattr_init (&attributes);\n  if (err != 0)\n    return err;\n  err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);\n  if (err != 0)\n    {\n      pthread_mutexattr_destroy (&attributes);\n      return err;\n    }\n  err = pthread_mutex_init (&lock->recmutex, &attributes);\n  if (err != 0)\n    {\n      pthread_mutexattr_destroy (&attributes);\n      return err;\n    }\n  err = pthread_mutexattr_destroy (&attributes);\n  if (err != 0)\n    return err;\n  lock->initialized = 1;\n  return 0;\n}\n\nint\nglthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)\n{\n  if (!lock->initialized)\n    {\n      int err;\n\n      err = pthread_mutex_lock (&lock->guard);\n      if (err != 0)\n        return err;\n      if (!lock->initialized)\n        {\n          err = glthread_recursive_lock_init_multithreaded (lock);\n          if (err != 0)\n            {\n              pthread_mutex_unlock (&lock->guard);\n              return err;\n            }\n        }\n      err = pthread_mutex_unlock (&lock->guard);\n      if (err != 0)\n        return err;\n    }\n  return pthread_mutex_lock (&lock->recmutex);\n}\n\nint\nglthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)\n{\n  if (!lock->initialized)\n    return EINVAL;\n  return pthread_mutex_unlock (&lock->recmutex);\n}\n\nint\nglthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)\n{\n  int err;\n\n  if (!lock->initialized)\n    return EINVAL;\n  err = pthread_mutex_destroy (&lock->recmutex);\n  if (err != 0)\n    return err;\n  lock->initialized = 0;\n  return 0;\n}\n\n#  endif\n\n# else\n\nint\nglthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)\n{\n  int err;\n\n  err = pthread_mutex_init (&lock->mutex, NULL);\n  if (err != 0)\n    return err;\n  lock->owner = (pthread_t) 0;\n  lock->depth = 0;\n  return 0;\n}\n\nint\nglthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)\n{\n  pthread_t self = pthread_self ();\n  if (lock->owner != self)\n    {\n      int err;\n\n      err = pthread_mutex_lock (&lock->mutex);\n      if (err != 0)\n        return err;\n      lock->owner = self;\n    }\n  if (++(lock->depth) == 0) /* wraparound? */\n    {\n      lock->depth--;\n      return EAGAIN;\n    }\n  return 0;\n}\n\nint\nglthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)\n{\n  if (lock->owner != pthread_self ())\n    return EPERM;\n  if (lock->depth == 0)\n    return EINVAL;\n  if (--(lock->depth) == 0)\n    {\n      lock->owner = (pthread_t) 0;\n      return pthread_mutex_unlock (&lock->mutex);\n    }\n  else\n    return 0;\n}\n\nint\nglthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)\n{\n  if (lock->owner != (pthread_t) 0)\n    return EBUSY;\n  return pthread_mutex_destroy (&lock->mutex);\n}\n\n# endif\n\n/* -------------------------- gl_once_t datatype -------------------------- */\n\nstatic const pthread_once_t fresh_once = PTHREAD_ONCE_INIT;\n\nint\nglthread_once_singlethreaded (pthread_once_t *once_control)\n{\n  /* We don't know whether pthread_once_t is an integer type, a floating-point\n     type, a pointer type, or a structure type.  */\n  char *firstbyte = (char *)once_control;\n  if (*firstbyte == *(const char *)&fresh_once)\n    {\n      /* First time use of once_control.  Invert the first byte.  */\n      *firstbyte = ~ *(const char *)&fresh_once;\n      return 1;\n    }\n  else\n    return 0;\n}\n\n# if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK)\n\nint\nglthread_once_multithreaded (pthread_once_t *once_control,\n                             void (*init_function) (void))\n{\n  int err = pthread_once (once_control, init_function);\n  if (err == ENOSYS)\n    {\n      /* This happens on FreeBSD 11: The pthread_once function in libc returns\n         ENOSYS.  */\n      if (glthread_once_singlethreaded (once_control))\n        init_function ();\n      return 0;\n    }\n  return err;\n}\n\n# endif\n\n#endif\n\n/* ========================================================================= */\n\n#if USE_WINDOWS_THREADS\n\n#endif\n\n/* ========================================================================= */\n"
  },
  {
    "path": "gnulib/glthread/lock.h",
    "content": "/* Locking in multithreaded situations.\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h.  */\n\n/* This file contains locking primitives for use with a given thread library.\n   It does not contain primitives for creating threads or for other\n   synchronization primitives.\n\n   Normal (non-recursive) locks:\n     Type:                gl_lock_t\n     Declaration:         gl_lock_define(extern, name)\n     Initializer:         gl_lock_define_initialized(, name)\n     Initialization:      gl_lock_init (name);\n     Taking the lock:     gl_lock_lock (name);\n     Releasing the lock:  gl_lock_unlock (name);\n     De-initialization:   gl_lock_destroy (name);\n   Equivalent functions with control of error handling:\n     Initialization:      err = glthread_lock_init (&name);\n     Taking the lock:     err = glthread_lock_lock (&name);\n     Releasing the lock:  err = glthread_lock_unlock (&name);\n     De-initialization:   err = glthread_lock_destroy (&name);\n\n   Read-Write (non-recursive) locks:\n     Type:                gl_rwlock_t\n     Declaration:         gl_rwlock_define(extern, name)\n     Initializer:         gl_rwlock_define_initialized(, name)\n     Initialization:      gl_rwlock_init (name);\n     Taking the lock:     gl_rwlock_rdlock (name);\n                          gl_rwlock_wrlock (name);\n     Releasing the lock:  gl_rwlock_unlock (name);\n     De-initialization:   gl_rwlock_destroy (name);\n   Equivalent functions with control of error handling:\n     Initialization:      err = glthread_rwlock_init (&name);\n     Taking the lock:     err = glthread_rwlock_rdlock (&name);\n                          err = glthread_rwlock_wrlock (&name);\n     Releasing the lock:  err = glthread_rwlock_unlock (&name);\n     De-initialization:   err = glthread_rwlock_destroy (&name);\n\n   Recursive locks:\n     Type:                gl_recursive_lock_t\n     Declaration:         gl_recursive_lock_define(extern, name)\n     Initializer:         gl_recursive_lock_define_initialized(, name)\n     Initialization:      gl_recursive_lock_init (name);\n     Taking the lock:     gl_recursive_lock_lock (name);\n     Releasing the lock:  gl_recursive_lock_unlock (name);\n     De-initialization:   gl_recursive_lock_destroy (name);\n   Equivalent functions with control of error handling:\n     Initialization:      err = glthread_recursive_lock_init (&name);\n     Taking the lock:     err = glthread_recursive_lock_lock (&name);\n     Releasing the lock:  err = glthread_recursive_lock_unlock (&name);\n     De-initialization:   err = glthread_recursive_lock_destroy (&name);\n\n  Once-only execution:\n     Type:                gl_once_t\n     Initializer:         gl_once_define(extern, name)\n     Execution:           gl_once (name, initfunction);\n   Equivalent functions with control of error handling:\n     Execution:           err = glthread_once (&name, initfunction);\n*/\n\n\n#ifndef _LOCK_H\n#define _LOCK_H\n\n#include <errno.h>\n#include <stdlib.h>\n\n#if !defined c11_threads_in_use\n# if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC\n#  define c11_threads_in_use() 1\n# elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK\n#  include <threads.h>\n#  pragma weak thrd_exit\n#  define c11_threads_in_use() (thrd_exit != NULL)\n# else\n#  define c11_threads_in_use() 0\n# endif\n#endif\n\n/* ========================================================================= */\n\n#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS\n\n/* Use the ISO C threads library.  */\n\n# include <threads.h>\n\n# ifdef __cplusplus\nextern \"C\" {\n# endif\n\n/* -------------------------- gl_lock_t datatype -------------------------- */\n\ntypedef struct\n        {\n          int volatile init_needed;\n          once_flag init_once;\n          void (*init_func) (void);\n          mtx_t mutex;\n        }\n        gl_lock_t;\n# define gl_lock_define(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_lock_t NAME;\n# define gl_lock_define_initialized(STORAGECLASS, NAME) \\\n    static void _atomic_init_##NAME (void);       \\\n    STORAGECLASS gl_lock_t NAME =                 \\\n      { 1, ONCE_FLAG_INIT, _atomic_init_##NAME }; \\\n    static void _atomic_init_##NAME (void)        \\\n    {                                             \\\n      if (glthread_lock_init (&(NAME)))           \\\n        abort ();                                 \\\n    }\nextern int glthread_lock_init (gl_lock_t *lock);\nextern int glthread_lock_lock (gl_lock_t *lock);\nextern int glthread_lock_unlock (gl_lock_t *lock);\nextern int glthread_lock_destroy (gl_lock_t *lock);\n\n/* ------------------------- gl_rwlock_t datatype ------------------------- */\n\ntypedef struct\n        {\n          int volatile init_needed;\n          once_flag init_once;\n          void (*init_func) (void);\n          mtx_t lock; /* protects the remaining fields */\n          cnd_t waiting_readers; /* waiting readers */\n          cnd_t waiting_writers; /* waiting writers */\n          unsigned int waiting_writers_count; /* number of waiting writers */\n          int runcount; /* number of readers running, or -1 when a writer runs */\n        }\n        gl_rwlock_t;\n# define gl_rwlock_define(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_rwlock_t NAME;\n# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \\\n    static void _atomic_init_##NAME (void);       \\\n    STORAGECLASS gl_rwlock_t NAME =               \\\n      { 1, ONCE_FLAG_INIT, _atomic_init_##NAME }; \\\n    static void _atomic_init_##NAME (void)        \\\n    {                                             \\\n      if (glthread_rwlock_init (&(NAME)))         \\\n        abort ();                                 \\\n    }\nextern int glthread_rwlock_init (gl_rwlock_t *lock);\nextern int glthread_rwlock_rdlock (gl_rwlock_t *lock);\nextern int glthread_rwlock_wrlock (gl_rwlock_t *lock);\nextern int glthread_rwlock_unlock (gl_rwlock_t *lock);\nextern int glthread_rwlock_destroy (gl_rwlock_t *lock);\n\n/* --------------------- gl_recursive_lock_t datatype --------------------- */\n\ntypedef struct\n        {\n          int volatile init_needed;\n          once_flag init_once;\n          void (*init_func) (void);\n          mtx_t mutex;\n        }\n        gl_recursive_lock_t;\n# define gl_recursive_lock_define(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_recursive_lock_t NAME;\n# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \\\n    static void _atomic_init_##NAME (void);       \\\n    STORAGECLASS gl_recursive_lock_t NAME =       \\\n      { 1, ONCE_FLAG_INIT, _atomic_init_##NAME }; \\\n    static void _atomic_init_##NAME (void)        \\\n    {                                             \\\n      if (glthread_recursive_lock_init (&(NAME))) \\\n        abort ();                                 \\\n    }\nextern int glthread_recursive_lock_init (gl_recursive_lock_t *lock);\nextern int glthread_recursive_lock_lock (gl_recursive_lock_t *lock);\nextern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);\nextern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);\n\n/* -------------------------- gl_once_t datatype -------------------------- */\n\ntypedef once_flag gl_once_t;\n# define gl_once_define(STORAGECLASS, NAME) \\\n    STORAGECLASS once_flag NAME = ONCE_FLAG_INIT;\n# define glthread_once(ONCE_CONTROL, INITFUNCTION) \\\n    (call_once (ONCE_CONTROL, INITFUNCTION), 0)\n\n# ifdef __cplusplus\n}\n# endif\n\n#endif\n\n/* ========================================================================= */\n\n#if USE_POSIX_THREADS\n\n/* Use the POSIX threads library.  */\n\n# include <pthread.h>\n\n# ifdef __cplusplus\nextern \"C\" {\n# endif\n\n# if PTHREAD_IN_USE_DETECTION_HARD\n\n/* The pthread_in_use() detection needs to be done at runtime.  */\n#  define pthread_in_use() \\\n     glthread_in_use ()\nextern int glthread_in_use (void);\n\n# endif\n\n# if USE_POSIX_THREADS_WEAK\n\n/* Use weak references to the POSIX threads library.  */\n\n/* Weak references avoid dragging in external libraries if the other parts\n   of the program don't use them.  Here we use them, because we don't want\n   every program that uses libintl to depend on libpthread.  This assumes\n   that libpthread would not be loaded after libintl; i.e. if libintl is\n   loaded first, by an executable that does not depend on libpthread, and\n   then a module is dynamically loaded that depends on libpthread, libintl\n   will not be multithread-safe.  */\n\n/* The way to test at runtime whether libpthread is present is to test\n   whether a function pointer's value, such as &pthread_mutex_init, is\n   non-NULL.  However, some versions of GCC have a bug through which, in\n   PIC mode, &foo != NULL always evaluates to true if there is a direct\n   call to foo(...) in the same function.  To avoid this, we test the\n   address of a function in libpthread that we don't use.  */\n\n#  pragma weak pthread_mutex_init\n#  pragma weak pthread_mutex_lock\n#  pragma weak pthread_mutex_unlock\n#  pragma weak pthread_mutex_destroy\n#  pragma weak pthread_rwlock_init\n#  pragma weak pthread_rwlock_rdlock\n#  pragma weak pthread_rwlock_wrlock\n#  pragma weak pthread_rwlock_unlock\n#  pragma weak pthread_rwlock_destroy\n#  pragma weak pthread_once\n#  pragma weak pthread_cond_init\n#  pragma weak pthread_cond_wait\n#  pragma weak pthread_cond_signal\n#  pragma weak pthread_cond_broadcast\n#  pragma weak pthread_cond_destroy\n#  pragma weak pthread_mutexattr_init\n#  pragma weak pthread_mutexattr_settype\n#  pragma weak pthread_mutexattr_destroy\n#  pragma weak pthread_rwlockattr_init\n#  if __GNU_LIBRARY__ > 1\n#   pragma weak pthread_rwlockattr_setkind_np\n#  endif\n#  pragma weak pthread_rwlockattr_destroy\n#  ifndef pthread_self\n#   pragma weak pthread_self\n#  endif\n\n#  if !PTHREAD_IN_USE_DETECTION_HARD\n    /* Considering all platforms with USE_POSIX_THREADS_WEAK, only few symbols\n       can be used to determine whether libpthread is in use.  These are:\n         pthread_mutexattr_gettype\n         pthread_rwlockattr_destroy\n         pthread_rwlockattr_init\n     */\n#   pragma weak pthread_mutexattr_gettype\n#   define pthread_in_use() \\\n      (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())\n#  endif\n\n# else\n\n#  if !PTHREAD_IN_USE_DETECTION_HARD\n#   define pthread_in_use() 1\n#  endif\n\n# endif\n\n/* -------------------------- gl_lock_t datatype -------------------------- */\n\ntypedef pthread_mutex_t gl_lock_t;\n# define gl_lock_define(STORAGECLASS, NAME) \\\n    STORAGECLASS pthread_mutex_t NAME;\n# define gl_lock_define_initialized(STORAGECLASS, NAME) \\\n    STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer;\n# define gl_lock_initializer \\\n    PTHREAD_MUTEX_INITIALIZER\n# define glthread_lock_init(LOCK) \\\n    (pthread_in_use () ? pthread_mutex_init (LOCK, NULL) : 0)\n# define glthread_lock_lock(LOCK) \\\n    (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)\n# define glthread_lock_unlock(LOCK) \\\n    (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)\n# define glthread_lock_destroy(LOCK) \\\n    (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)\n\n/* ------------------------- gl_rwlock_t datatype ------------------------- */\n\n# if HAVE_PTHREAD_RWLOCK && (HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER || (defined PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP && (__GNU_LIBRARY__ > 1)))\n\n#  if defined PTHREAD_RWLOCK_INITIALIZER || defined PTHREAD_RWLOCK_INITIALIZER_NP\n\ntypedef pthread_rwlock_t gl_rwlock_t;\n#   define gl_rwlock_define(STORAGECLASS, NAME) \\\n      STORAGECLASS pthread_rwlock_t NAME;\n#   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \\\n      STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;\n#   if HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER\n#    if defined PTHREAD_RWLOCK_INITIALIZER\n#     define gl_rwlock_initializer \\\n        PTHREAD_RWLOCK_INITIALIZER\n#    else\n#     define gl_rwlock_initializer \\\n        PTHREAD_RWLOCK_INITIALIZER_NP\n#    endif\n#    define glthread_rwlock_init(LOCK) \\\n       (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0)\n#   else /* glibc with bug https://sourceware.org/bugzilla/show_bug.cgi?id=13701 */\n#    define gl_rwlock_initializer \\\n       PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP\n#    define glthread_rwlock_init(LOCK) \\\n       (pthread_in_use () ? glthread_rwlock_init_for_glibc (LOCK) : 0)\nextern int glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock);\n#   endif\n#   define glthread_rwlock_rdlock(LOCK) \\\n      (pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0)\n#   define glthread_rwlock_wrlock(LOCK) \\\n      (pthread_in_use () ? pthread_rwlock_wrlock (LOCK) : 0)\n#   define glthread_rwlock_unlock(LOCK) \\\n      (pthread_in_use () ? pthread_rwlock_unlock (LOCK) : 0)\n#   define glthread_rwlock_destroy(LOCK) \\\n      (pthread_in_use () ? pthread_rwlock_destroy (LOCK) : 0)\n\n#  else\n\ntypedef struct\n        {\n          int initialized;\n          pthread_mutex_t guard;   /* protects the initialization */\n          pthread_rwlock_t rwlock; /* read-write lock */\n        }\n        gl_rwlock_t;\n#   define gl_rwlock_define(STORAGECLASS, NAME) \\\n      STORAGECLASS gl_rwlock_t NAME;\n#   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \\\n      STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;\n#   define gl_rwlock_initializer \\\n      { 0, PTHREAD_MUTEX_INITIALIZER }\n#   define glthread_rwlock_init(LOCK) \\\n      (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)\n#   define glthread_rwlock_rdlock(LOCK) \\\n      (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)\n#   define glthread_rwlock_wrlock(LOCK) \\\n      (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)\n#   define glthread_rwlock_unlock(LOCK) \\\n      (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)\n#   define glthread_rwlock_destroy(LOCK) \\\n      (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)\nextern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);\nextern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);\nextern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);\nextern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);\nextern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);\n\n#  endif\n\n# else\n\ntypedef struct\n        {\n          pthread_mutex_t lock; /* protects the remaining fields */\n          pthread_cond_t waiting_readers; /* waiting readers */\n          pthread_cond_t waiting_writers; /* waiting writers */\n          unsigned int waiting_writers_count; /* number of waiting writers */\n          int runcount; /* number of readers running, or -1 when a writer runs */\n        }\n        gl_rwlock_t;\n# define gl_rwlock_define(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_rwlock_t NAME;\n# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;\n# define gl_rwlock_initializer \\\n    { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }\n# define glthread_rwlock_init(LOCK) \\\n    (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)\n# define glthread_rwlock_rdlock(LOCK) \\\n    (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)\n# define glthread_rwlock_wrlock(LOCK) \\\n    (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)\n# define glthread_rwlock_unlock(LOCK) \\\n    (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)\n# define glthread_rwlock_destroy(LOCK) \\\n    (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)\nextern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);\nextern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);\nextern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);\nextern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);\nextern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);\n\n# endif\n\n/* --------------------- gl_recursive_lock_t datatype --------------------- */\n\n# if HAVE_PTHREAD_MUTEX_RECURSIVE\n\n#  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP\n\ntypedef pthread_mutex_t gl_recursive_lock_t;\n#   define gl_recursive_lock_define(STORAGECLASS, NAME) \\\n      STORAGECLASS pthread_mutex_t NAME;\n#   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \\\n      STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer;\n#   ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER\n#    define gl_recursive_lock_initializer \\\n       PTHREAD_RECURSIVE_MUTEX_INITIALIZER\n#   else\n#    define gl_recursive_lock_initializer \\\n       PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP\n#   endif\n#   define glthread_recursive_lock_init(LOCK) \\\n      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)\n#   define glthread_recursive_lock_lock(LOCK) \\\n      (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)\n#   define glthread_recursive_lock_unlock(LOCK) \\\n      (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)\n#   define glthread_recursive_lock_destroy(LOCK) \\\n      (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)\nextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);\n\n#  else\n\ntypedef struct\n        {\n          pthread_mutex_t recmutex; /* recursive mutex */\n          pthread_mutex_t guard;    /* protects the initialization */\n          int initialized;\n        }\n        gl_recursive_lock_t;\n#   define gl_recursive_lock_define(STORAGECLASS, NAME) \\\n      STORAGECLASS gl_recursive_lock_t NAME;\n#   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \\\n      STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;\n#   define gl_recursive_lock_initializer \\\n      { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }\n#   define glthread_recursive_lock_init(LOCK) \\\n      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)\n#   define glthread_recursive_lock_lock(LOCK) \\\n      (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)\n#   define glthread_recursive_lock_unlock(LOCK) \\\n      (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)\n#   define glthread_recursive_lock_destroy(LOCK) \\\n      (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)\nextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);\nextern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);\nextern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);\nextern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);\n\n#  endif\n\n# else\n\n/* Old versions of POSIX threads on Solaris did not have recursive locks.\n   We have to implement them ourselves.  */\n\ntypedef struct\n        {\n          pthread_mutex_t mutex;\n          pthread_t owner;\n          unsigned long depth;\n        }\n        gl_recursive_lock_t;\n#  define gl_recursive_lock_define(STORAGECLASS, NAME) \\\n     STORAGECLASS gl_recursive_lock_t NAME;\n#  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \\\n     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;\n#  define gl_recursive_lock_initializer \\\n     { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }\n#  define glthread_recursive_lock_init(LOCK) \\\n     (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)\n#  define glthread_recursive_lock_lock(LOCK) \\\n     (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)\n#  define glthread_recursive_lock_unlock(LOCK) \\\n     (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)\n#  define glthread_recursive_lock_destroy(LOCK) \\\n     (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)\nextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);\nextern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);\nextern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);\nextern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);\n\n# endif\n\n/* -------------------------- gl_once_t datatype -------------------------- */\n\ntypedef pthread_once_t gl_once_t;\n# define gl_once_define(STORAGECLASS, NAME) \\\n    STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;\n# if PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK\n#  define glthread_once(ONCE_CONTROL, INITFUNCTION) \\\n     (pthread_in_use ()                                                        \\\n      ? pthread_once (ONCE_CONTROL, INITFUNCTION)                              \\\n      : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))\n# else\n#  define glthread_once(ONCE_CONTROL, INITFUNCTION) \\\n     (pthread_in_use ()                                                        \\\n      ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)               \\\n      : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))\nextern int glthread_once_multithreaded (pthread_once_t *once_control,\n                                        void (*init_function) (void));\n# endif\nextern int glthread_once_singlethreaded (pthread_once_t *once_control);\n\n# ifdef __cplusplus\n}\n# endif\n\n#endif\n\n/* ========================================================================= */\n\n#if USE_WINDOWS_THREADS\n\n# define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n# include <windows.h>\n\n# include \"windows-mutex.h\"\n# include \"windows-rwlock.h\"\n# include \"windows-recmutex.h\"\n# include \"windows-once.h\"\n\n# ifdef __cplusplus\nextern \"C\" {\n# endif\n\n/* We can use CRITICAL_SECTION directly, rather than the native Windows Event,\n   Mutex, Semaphore types, because\n     - we need only to synchronize inside a single process (address space),\n       not inter-process locking,\n     - we don't need to support trylock operations.  (TryEnterCriticalSection\n       does not work on Windows 95/98/ME.  Packages that need trylock usually\n       define their own mutex type.)  */\n\n/* There is no way to statically initialize a CRITICAL_SECTION.  It needs\n   to be done lazily, once only.  For this we need spinlocks.  */\n\n/* -------------------------- gl_lock_t datatype -------------------------- */\n\ntypedef glwthread_mutex_t gl_lock_t;\n# define gl_lock_define(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_lock_t NAME;\n# define gl_lock_define_initialized(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_lock_t NAME = gl_lock_initializer;\n# define gl_lock_initializer \\\n    GLWTHREAD_MUTEX_INIT\n# define glthread_lock_init(LOCK) \\\n    (glwthread_mutex_init (LOCK), 0)\n# define glthread_lock_lock(LOCK) \\\n    glwthread_mutex_lock (LOCK)\n# define glthread_lock_unlock(LOCK) \\\n    glwthread_mutex_unlock (LOCK)\n# define glthread_lock_destroy(LOCK) \\\n    glwthread_mutex_destroy (LOCK)\n\n/* ------------------------- gl_rwlock_t datatype ------------------------- */\n\ntypedef glwthread_rwlock_t gl_rwlock_t;\n# define gl_rwlock_define(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_rwlock_t NAME;\n# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;\n# define gl_rwlock_initializer \\\n    GLWTHREAD_RWLOCK_INIT\n# define glthread_rwlock_init(LOCK) \\\n    (glwthread_rwlock_init (LOCK), 0)\n# define glthread_rwlock_rdlock(LOCK) \\\n    glwthread_rwlock_rdlock (LOCK)\n# define glthread_rwlock_wrlock(LOCK) \\\n    glwthread_rwlock_wrlock (LOCK)\n# define glthread_rwlock_unlock(LOCK) \\\n    glwthread_rwlock_unlock (LOCK)\n# define glthread_rwlock_destroy(LOCK) \\\n    glwthread_rwlock_destroy (LOCK)\n\n/* --------------------- gl_recursive_lock_t datatype --------------------- */\n\ntypedef glwthread_recmutex_t gl_recursive_lock_t;\n# define gl_recursive_lock_define(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_recursive_lock_t NAME;\n# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;\n# define gl_recursive_lock_initializer \\\n    GLWTHREAD_RECMUTEX_INIT\n# define glthread_recursive_lock_init(LOCK) \\\n    (glwthread_recmutex_init (LOCK), 0)\n# define glthread_recursive_lock_lock(LOCK) \\\n    glwthread_recmutex_lock (LOCK)\n# define glthread_recursive_lock_unlock(LOCK) \\\n    glwthread_recmutex_unlock (LOCK)\n# define glthread_recursive_lock_destroy(LOCK) \\\n    glwthread_recmutex_destroy (LOCK)\n\n/* -------------------------- gl_once_t datatype -------------------------- */\n\ntypedef glwthread_once_t gl_once_t;\n# define gl_once_define(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT;\n# define glthread_once(ONCE_CONTROL, INITFUNCTION) \\\n    (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0)\n\n# ifdef __cplusplus\n}\n# endif\n\n#endif\n\n/* ========================================================================= */\n\n#if !(USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS)\n\n/* Provide dummy implementation if threads are not supported.  */\n\n/* -------------------------- gl_lock_t datatype -------------------------- */\n\ntypedef int gl_lock_t;\n# define gl_lock_define(STORAGECLASS, NAME)\n# define gl_lock_define_initialized(STORAGECLASS, NAME)\n# define glthread_lock_init(NAME) 0\n# define glthread_lock_lock(NAME) 0\n# define glthread_lock_unlock(NAME) 0\n# define glthread_lock_destroy(NAME) 0\n\n/* ------------------------- gl_rwlock_t datatype ------------------------- */\n\ntypedef int gl_rwlock_t;\n# define gl_rwlock_define(STORAGECLASS, NAME)\n# define gl_rwlock_define_initialized(STORAGECLASS, NAME)\n# define glthread_rwlock_init(NAME) 0\n# define glthread_rwlock_rdlock(NAME) 0\n# define glthread_rwlock_wrlock(NAME) 0\n# define glthread_rwlock_unlock(NAME) 0\n# define glthread_rwlock_destroy(NAME) 0\n\n/* --------------------- gl_recursive_lock_t datatype --------------------- */\n\ntypedef int gl_recursive_lock_t;\n# define gl_recursive_lock_define(STORAGECLASS, NAME)\n# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME)\n# define glthread_recursive_lock_init(NAME) 0\n# define glthread_recursive_lock_lock(NAME) 0\n# define glthread_recursive_lock_unlock(NAME) 0\n# define glthread_recursive_lock_destroy(NAME) 0\n\n/* -------------------------- gl_once_t datatype -------------------------- */\n\ntypedef int gl_once_t;\n# define gl_once_define(STORAGECLASS, NAME) \\\n    STORAGECLASS gl_once_t NAME = 0;\n# define glthread_once(ONCE_CONTROL, INITFUNCTION) \\\n    (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0)\n\n#endif\n\n/* ========================================================================= */\n\n/* Macros with built-in error handling.  */\n\n/* -------------------------- gl_lock_t datatype -------------------------- */\n\n#define gl_lock_init(NAME) \\\n   do                                  \\\n     {                                 \\\n       if (glthread_lock_init (&NAME)) \\\n         abort ();                     \\\n     }                                 \\\n   while (0)\n#define gl_lock_lock(NAME) \\\n   do                                  \\\n     {                                 \\\n       if (glthread_lock_lock (&NAME)) \\\n         abort ();                     \\\n     }                                 \\\n   while (0)\n#define gl_lock_unlock(NAME) \\\n   do                                    \\\n     {                                   \\\n       if (glthread_lock_unlock (&NAME)) \\\n         abort ();                       \\\n     }                                   \\\n   while (0)\n#define gl_lock_destroy(NAME) \\\n   do                                     \\\n     {                                    \\\n       if (glthread_lock_destroy (&NAME)) \\\n         abort ();                        \\\n     }                                    \\\n   while (0)\n\n/* ------------------------- gl_rwlock_t datatype ------------------------- */\n\n#define gl_rwlock_init(NAME) \\\n   do                                    \\\n     {                                   \\\n       if (glthread_rwlock_init (&NAME)) \\\n         abort ();                       \\\n     }                                   \\\n   while (0)\n#define gl_rwlock_rdlock(NAME) \\\n   do                                      \\\n     {                                     \\\n       if (glthread_rwlock_rdlock (&NAME)) \\\n         abort ();                         \\\n     }                                     \\\n   while (0)\n#define gl_rwlock_wrlock(NAME) \\\n   do                                      \\\n     {                                     \\\n       if (glthread_rwlock_wrlock (&NAME)) \\\n         abort ();                         \\\n     }                                     \\\n   while (0)\n#define gl_rwlock_unlock(NAME) \\\n   do                                      \\\n     {                                     \\\n       if (glthread_rwlock_unlock (&NAME)) \\\n         abort ();                         \\\n     }                                     \\\n   while (0)\n#define gl_rwlock_destroy(NAME) \\\n   do                                       \\\n     {                                      \\\n       if (glthread_rwlock_destroy (&NAME)) \\\n         abort ();                          \\\n     }                                      \\\n   while (0)\n\n/* --------------------- gl_recursive_lock_t datatype --------------------- */\n\n#define gl_recursive_lock_init(NAME) \\\n   do                                            \\\n     {                                           \\\n       if (glthread_recursive_lock_init (&NAME)) \\\n         abort ();                               \\\n     }                                           \\\n   while (0)\n#define gl_recursive_lock_lock(NAME) \\\n   do                                            \\\n     {                                           \\\n       if (glthread_recursive_lock_lock (&NAME)) \\\n         abort ();                               \\\n     }                                           \\\n   while (0)\n#define gl_recursive_lock_unlock(NAME) \\\n   do                                              \\\n     {                                             \\\n       if (glthread_recursive_lock_unlock (&NAME)) \\\n         abort ();                                 \\\n     }                                             \\\n   while (0)\n#define gl_recursive_lock_destroy(NAME) \\\n   do                                               \\\n     {                                              \\\n       if (glthread_recursive_lock_destroy (&NAME)) \\\n         abort ();                                  \\\n     }                                              \\\n   while (0)\n\n/* -------------------------- gl_once_t datatype -------------------------- */\n\n#define gl_once(NAME, INITFUNCTION) \\\n   do                                           \\\n     {                                          \\\n       if (glthread_once (&NAME, INITFUNCTION)) \\\n         abort ();                              \\\n     }                                          \\\n   while (0)\n\n/* ========================================================================= */\n\n#endif /* _LOCK_H */\n"
  },
  {
    "path": "gnulib/glthread/threadlib.c",
    "content": "/* Multithreading primitives.\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.  */\n\n#include <config.h>\n\n/* ========================================================================= */\n\n#if USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS\n\n/* Use the POSIX threads library.  */\n\n# include <errno.h>\n# include <pthread.h>\n# include <stdlib.h>\n\n# if PTHREAD_IN_USE_DETECTION_HARD\n\n#  if defined __FreeBSD__ || defined __DragonFly__                 /* FreeBSD */\n\n/* Test using pthread_key_create.  */\n\nint\nglthread_in_use (void)\n{\n  static int tested;\n  static int result; /* 1: linked with -lpthread, 0: only with libc */\n\n  if (!tested)\n    {\n      pthread_key_t key;\n      int err = pthread_key_create (&key, NULL);\n\n      if (err == ENOSYS)\n        result = 0;\n      else\n        {\n          result = 1;\n          if (err == 0)\n            pthread_key_delete (key);\n        }\n      tested = 1;\n    }\n  return result;\n}\n\n#  else                                                     /* Solaris, HP-UX */\n\n/* Test using pthread_create.  */\n\n/* The function to be executed by a dummy thread.  */\nstatic void *\ndummy_thread_func (void *arg)\n{\n  return arg;\n}\n\nint\nglthread_in_use (void)\n{\n  static int tested;\n  static int result; /* 1: linked with -lpthread, 0: only with libc */\n\n  if (!tested)\n    {\n      pthread_t thread;\n\n      if (pthread_create (&thread, NULL, dummy_thread_func, NULL) != 0)\n        /* Thread creation failed.  */\n        result = 0;\n      else\n        {\n          /* Thread creation works.  */\n          void *retval;\n          if (pthread_join (thread, &retval) != 0)\n            abort ();\n          result = 1;\n        }\n      tested = 1;\n    }\n  return result;\n}\n\n#  endif\n\n# endif\n\n#endif\n\n/* ========================================================================= */\n\n/* This declaration is solely to ensure that after preprocessing\n   this file is never empty.  */\ntypedef int dummy;\n"
  },
  {
    "path": "gnulib/hard-locale.c",
    "content": "/* hard-locale.c -- Determine whether a locale is hard.\n\n   Copyright (C) 1997-1999, 2002-2004, 2006-2007, 2009-2021 Free Software\n   Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n#include \"hard-locale.h\"\n\n#include <locale.h>\n#include <string.h>\n\nbool\nhard_locale (int category)\n{\n  char locale[SETLOCALE_NULL_MAX];\n\n  if (setlocale_null_r (category, locale, sizeof (locale)))\n    return false;\n\n  return !(strcmp (locale, \"C\") == 0 || strcmp (locale, \"POSIX\") == 0);\n}\n"
  },
  {
    "path": "gnulib/hard-locale.h",
    "content": "/* Determine whether a locale is hard.\n\n   Copyright (C) 1999, 2003-2004, 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef HARD_LOCALE_H_\n# define HARD_LOCALE_H_ 1\n\n# include <stdbool.h>\n\n/* Return true if the specified CATEGORY of the current locale is hard, i.e.\n   different from the C or POSIX locale that has a fixed behavior.\n   CATEGORY must be one of the LC_* values, but not LC_ALL.  */\nextern bool hard_locale (int category);\n\n#endif /* HARD_LOCALE_H_ */\n"
  },
  {
    "path": "gnulib/idx.h",
    "content": "/* A type for indices and sizes.\n   Copyright (C) 2020-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifndef _IDX_H\n#define _IDX_H\n\n/* Get ptrdiff_t.  */\n#include <stddef.h>\n\n/* Get PTRDIFF_MAX.  */\n#include <stdint.h>\n\n/* The type 'idx_t' holds an (array) index or an (object) size.\n   Its implementation promotes to a signed integer type,\n   which can hold the values\n     0..2^63-1 (on 64-bit platforms) or\n     0..2^31-1 (on 32-bit platforms).\n\n   Why a signed integer type?\n\n     * Security: Signed types can be checked for overflow via\n       '-fsanitize=undefined', but unsigned types cannot.\n\n     * Comparisons without surprises: ISO C99 § 6.3.1.8 specifies a few\n       surprising results for comparisons, such as\n\n           (int) -3 < (unsigned long) 7  =>  false\n           (int) -3 < (unsigned int) 7   =>  false\n       and on 32-bit machines:\n           (long) -3 < (unsigned int) 7  =>  false\n\n       This is surprising because the natural comparison order is by\n       value in the realm of infinite-precision signed integers (ℤ).\n\n       The best way to get rid of such surprises is to use signed types\n       for numerical integer values, and use unsigned types only for\n       bit masks and enums.\n\n   Why not use 'size_t' directly?\n\n     * Because 'size_t' is an unsigned type, and a signed type is better.\n       See above.\n\n   Why not use 'ptrdiff_t' directly?\n\n     * Maintainability: When reading and modifying code, it helps to know that\n       a certain variable cannot have negative values.  For example, when you\n       have a loop\n\n         int n = ...;\n         for (int i = 0; i < n; i++) ...\n\n       or\n\n         ptrdiff_t n = ...;\n         for (ptrdiff_t i = 0; i < n; i++) ...\n\n       you have to ask yourself \"what if n < 0?\".  Whereas in\n\n         idx_t n = ...;\n         for (idx_t i = 0; i < n; i++) ...\n\n       you know that this case cannot happen.\n\n       Similarly, when a programmer writes\n\n         idx_t = ptr2 - ptr1;\n\n       there is an implied assertion that ptr1 and ptr2 point into the same\n       object and that ptr1 <= ptr2.\n\n     * Being future-proof: In the future, range types (integers which are\n       constrained to a certain range of values) may be added to C compilers\n       or to the C standard.  Several programming languages (Ada, Haskell,\n       Common Lisp, Pascal) already have range types.  Such range types may\n       help producing good code and good warnings.  The type 'idx_t' could\n       then be typedef'ed to a range type that is signed after promotion.  */\n\n/* In the future, idx_t could be typedef'ed to a signed range type.\n   The clang \"extended integer types\", supported in Clang 11 or newer\n   <https://clang.llvm.org/docs/LanguageExtensions.html#extended-integer-types>,\n   are a special case of range types.  However, these types don't support binary\n   operators with plain integer types (e.g. expressions such as x > 1).\n   Therefore, they don't behave like signed types (and not like unsigned types\n   either).  So, we cannot use them here.  */\n\n/* Use the signed type 'ptrdiff_t'.  */\n/* Note: ISO C does not mandate that 'size_t' and 'ptrdiff_t' have the same\n   size, but it is so on all platforms we have seen since 1990.  */\ntypedef ptrdiff_t idx_t;\n\n/* IDX_MAX is the maximum value of an idx_t.  */\n#define IDX_MAX PTRDIFF_MAX\n\n/* So far no need has been found for an IDX_WIDTH macro.\n   Perhaps there should be another macro IDX_VALUE_BITS that does not\n   count the sign bit and is therefore one less than PTRDIFF_WIDTH.  */\n\n#endif /* _IDX_H */\n"
  },
  {
    "path": "gnulib/intprops.h",
    "content": "/* intprops.h -- properties of integer types\n\n   Copyright (C) 2001-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2.1 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Paul Eggert.  */\n\n#ifndef _GL_INTPROPS_H\n#define _GL_INTPROPS_H\n\n#include <limits.h>\n\n/* Return a value with the common real type of E and V and the value of V.\n   Do not evaluate E.  */\n#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))\n\n/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see\n   <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00406.html>.  */\n#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))\n\n/* The extra casts in the following macros work around compiler bugs,\n   e.g., in Cray C 5.0.3.0.  */\n\n/* True if the arithmetic type T is an integer type.  bool counts as\n   an integer.  */\n#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)\n\n/* True if the real type T is signed.  */\n#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))\n\n/* Return 1 if the real expression E, after promotion, has a\n   signed or floating type.  Do not evaluate E.  */\n#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)\n\n\n/* Minimum and maximum values for integer types and expressions.  */\n\n/* The width in bits of the integer type or expression T.\n   Do not evaluate T.  T must not be a bit-field expression.\n   Padding bits are not supported; this is checked at compile-time below.  */\n#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)\n\n/* The maximum and minimum values for the integer type T.  */\n#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t))\n#define TYPE_MAXIMUM(t)                                                 \\\n  ((t) (! TYPE_SIGNED (t)                                               \\\n        ? (t) -1                                                        \\\n        : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1)))\n\n/* The maximum and minimum values for the type of the expression E,\n   after integer promotion.  E is not evaluated.  */\n#define _GL_INT_MINIMUM(e)                                              \\\n  (EXPR_SIGNED (e)                                                      \\\n   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \\\n   : _GL_INT_CONVERT (e, 0))\n#define _GL_INT_MAXIMUM(e)                                              \\\n  (EXPR_SIGNED (e)                                                      \\\n   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \\\n   : _GL_INT_NEGATE_CONVERT (e, 1))\n#define _GL_SIGNED_INT_MAXIMUM(e)                                       \\\n  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)\n\n/* Work around OpenVMS incompatibility with C99.  */\n#if !defined LLONG_MAX && defined __INT64_MAX\n# define LLONG_MAX __INT64_MAX\n# define LLONG_MIN __INT64_MIN\n#endif\n\n/* This include file assumes that signed types are two's complement without\n   padding bits; the above macros have undefined behavior otherwise.\n   If this is a problem for you, please let us know how to fix it for your host.\n   This assumption is tested by the intprops-tests module.  */\n\n/* Does the __typeof__ keyword work?  This could be done by\n   'configure', but for now it's easier to do it by hand.  */\n#if (2 <= __GNUC__ \\\n     || (4 <= __clang_major__) \\\n     || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \\\n     || (0x5110 <= __SUNPRO_C && !__STDC__))\n# define _GL_HAVE___TYPEOF__ 1\n#else\n# define _GL_HAVE___TYPEOF__ 0\n#endif\n\n/* Return 1 if the integer type or expression T might be signed.  Return 0\n   if it is definitely unsigned.  T must not be a bit-field expression.\n   This macro does not evaluate its argument, and expands to an\n   integer constant expression.  */\n#if _GL_HAVE___TYPEOF__\n# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t))\n#else\n# define _GL_SIGNED_TYPE_OR_EXPR(t) 1\n#endif\n\n/* Bound on length of the string representing an unsigned integer\n   value representable in B bits.  log10 (2.0) < 146/485.  The\n   smallest value of B where this bound is not tight is 2621.  */\n#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)\n\n/* Bound on length of the string representing an integer type or expression T.\n   T must not be a bit-field expression.\n\n   Subtract 1 for the sign bit if T is signed, and then add 1 more for\n   a minus sign if needed.\n\n   Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 1 when its argument is\n   unsigned, this macro may overestimate the true bound by one byte when\n   applied to unsigned types of size 2, 4, 16, ... bytes.  */\n#define INT_STRLEN_BOUND(t)                                     \\\n  (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - _GL_SIGNED_TYPE_OR_EXPR (t)) \\\n   + _GL_SIGNED_TYPE_OR_EXPR (t))\n\n/* Bound on buffer size needed to represent an integer type or expression T,\n   including the terminating null.  T must not be a bit-field expression.  */\n#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)\n\n\n/* Range overflow checks.\n\n   The INT_<op>_RANGE_OVERFLOW macros return 1 if the corresponding C\n   operators might not yield numerically correct answers due to\n   arithmetic overflow.  They do not rely on undefined or\n   implementation-defined behavior.  Their implementations are simple\n   and straightforward, but they are harder to use and may be less\n   efficient than the INT_<op>_WRAPV, INT_<op>_OK, and\n   INT_<op>_OVERFLOW macros described below.\n\n   Example usage:\n\n     long int i = ...;\n     long int j = ...;\n     if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX))\n       printf (\"multiply would overflow\");\n     else\n       printf (\"product is %ld\", i * j);\n\n   Restrictions on *_RANGE_OVERFLOW macros:\n\n   These macros do not check for all possible numerical problems or\n   undefined or unspecified behavior: they do not check for division\n   by zero, for bad shift counts, or for shifting negative numbers.\n\n   These macros may evaluate their arguments zero or multiple times,\n   so the arguments should not have side effects.  The arithmetic\n   arguments (including the MIN and MAX arguments) must be of the same\n   integer type after the usual arithmetic conversions, and the type\n   must have minimum value MIN and maximum MAX.  Unsigned types should\n   use a zero MIN of the proper type.\n\n   Because all arguments are subject to integer promotions, these\n   macros typically do not work on types narrower than 'int'.\n\n   These macros are tuned for constant MIN and MAX.  For commutative\n   operations such as A + B, they are also tuned for constant B.  */\n\n/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic.\n   See above for restrictions.  */\n#define INT_ADD_RANGE_OVERFLOW(a, b, min, max)          \\\n  ((b) < 0                                              \\\n   ? (a) < (min) - (b)                                  \\\n   : (max) - (b) < (a))\n\n/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic.\n   See above for restrictions.  */\n#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max)     \\\n  ((b) < 0                                              \\\n   ? (max) + (b) < (a)                                  \\\n   : (a) < (min) + (b))\n\n/* Return 1 if - A would overflow in [MIN,MAX] arithmetic.\n   See above for restrictions.  */\n#define INT_NEGATE_RANGE_OVERFLOW(a, min, max)          \\\n  ((min) < 0                                            \\\n   ? (a) < - (max)                                      \\\n   : 0 < (a))\n\n/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic.\n   See above for restrictions.  Avoid && and || as they tickle\n   bugs in Sun C 5.11 2010/08/13 and other compilers; see\n   <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00401.html>.  */\n#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max)     \\\n  ((b) < 0                                              \\\n   ? ((a) < 0                                           \\\n      ? (a) < (max) / (b)                               \\\n      : (b) == -1                                       \\\n      ? 0                                               \\\n      : (min) / (b) < (a))                              \\\n   : (b) == 0                                           \\\n   ? 0                                                  \\\n   : ((a) < 0                                           \\\n      ? (a) < (min) / (b)                               \\\n      : (max) / (b) < (a)))\n\n/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic.\n   See above for restrictions.  Do not check for division by zero.  */\n#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max)       \\\n  ((min) < 0 && (b) == -1 && (a) < - (max))\n\n/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic.\n   See above for restrictions.  Do not check for division by zero.\n   Mathematically, % should never overflow, but on x86-like hosts\n   INT_MIN % -1 traps, and the C standard permits this, so treat this\n   as an overflow too.  */\n#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max)    \\\n  INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max)\n\n/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic.\n   See above for restrictions.  Here, MIN and MAX are for A only, and B need\n   not be of the same type as the other arguments.  The C standard says that\n   behavior is undefined for shifts unless 0 <= B < wordwidth, and that when\n   A is negative then A << B has undefined behavior and A >> B has\n   implementation-defined behavior, but do not check these other\n   restrictions.  */\n#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max)   \\\n  ((a) < 0                                              \\\n   ? (a) < (min) >> (b)                                 \\\n   : (max) >> (b) < (a))\n\n/* True if __builtin_add_overflow (A, B, P) and __builtin_sub_overflow\n   (A, B, P) work when P is non-null.  */\n/* __builtin_{add,sub}_overflow exists but is not reliable in GCC 5.x and 6.x,\n   see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98269>.  */\n#if 7 <= __GNUC__ && !defined __ICC\n# define _GL_HAS_BUILTIN_ADD_OVERFLOW 1\n#elif defined __has_builtin\n# define _GL_HAS_BUILTIN_ADD_OVERFLOW __has_builtin (__builtin_add_overflow)\n#else\n# define _GL_HAS_BUILTIN_ADD_OVERFLOW 0\n#endif\n\n/* True if __builtin_mul_overflow (A, B, P) works when P is non-null.  */\n#ifdef __clang__\n/* Work around Clang bug <https://bugs.llvm.org/show_bug.cgi?id=16404>.  */\n# define _GL_HAS_BUILTIN_MUL_OVERFLOW 0\n#else\n# define _GL_HAS_BUILTIN_MUL_OVERFLOW _GL_HAS_BUILTIN_ADD_OVERFLOW\n#endif\n\n/* True if __builtin_add_overflow_p (A, B, C) works, and similarly for\n   __builtin_sub_overflow_p and __builtin_mul_overflow_p.  */\n#if defined __clang__ || defined __ICC\n/* Clang 11 lacks __builtin_mul_overflow_p, and even if it did it\n   would presumably run afoul of Clang bug 16404.  ICC 2021.1's\n   __builtin_add_overflow_p etc. are not treated as integral constant\n   expressions even when all arguments are.  */\n# define _GL_HAS_BUILTIN_OVERFLOW_P 0\n#elif defined __has_builtin\n# define _GL_HAS_BUILTIN_OVERFLOW_P __has_builtin (__builtin_mul_overflow_p)\n#else\n# define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__)\n#endif\n\n/* The _GL*_OVERFLOW macros have the same restrictions as the\n   *_RANGE_OVERFLOW macros, except that they do not assume that operands\n   (e.g., A and B) have the same type as MIN and MAX.  Instead, they assume\n   that the result (e.g., A + B) has that type.  */\n#if _GL_HAS_BUILTIN_OVERFLOW_P\n# define _GL_ADD_OVERFLOW(a, b, min, max)                               \\\n   __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0)\n# define _GL_SUBTRACT_OVERFLOW(a, b, min, max)                          \\\n   __builtin_sub_overflow_p (a, b, (__typeof__ ((a) - (b))) 0)\n# define _GL_MULTIPLY_OVERFLOW(a, b, min, max)                          \\\n   __builtin_mul_overflow_p (a, b, (__typeof__ ((a) * (b))) 0)\n#else\n# define _GL_ADD_OVERFLOW(a, b, min, max)                                \\\n   ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max)                  \\\n    : (a) < 0 ? (b) <= (a) + (b)                                         \\\n    : (b) < 0 ? (a) <= (a) + (b)                                         \\\n    : (a) + (b) < (b))\n# define _GL_SUBTRACT_OVERFLOW(a, b, min, max)                           \\\n   ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max)             \\\n    : (a) < 0 ? 1                                                        \\\n    : (b) < 0 ? (a) - (b) <= (a)                                         \\\n    : (a) < (b))\n# define _GL_MULTIPLY_OVERFLOW(a, b, min, max)                           \\\n   (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a))))       \\\n    || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max))\n#endif\n#define _GL_DIVIDE_OVERFLOW(a, b, min, max)                             \\\n  ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max)  \\\n   : (a) < 0 ? (b) <= (a) + (b) - 1                                     \\\n   : (b) < 0 && (a) + (b) <= (a))\n#define _GL_REMAINDER_OVERFLOW(a, b, min, max)                          \\\n  ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max)  \\\n   : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b)                     \\\n   : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max))\n\n/* Return a nonzero value if A is a mathematical multiple of B, where\n   A is unsigned, B is negative, and MAX is the maximum value of A's\n   type.  A's type must be the same as (A % B)'s type.  Normally (A %\n   -B == 0) suffices, but things get tricky if -B would overflow.  */\n#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max)                            \\\n  (((b) < -_GL_SIGNED_INT_MAXIMUM (b)                                   \\\n    ? (_GL_SIGNED_INT_MAXIMUM (b) == (max)                              \\\n       ? (a)                                                            \\\n       : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1))   \\\n    : (a) % - (b))                                                      \\\n   == 0)\n\n/* Check for integer overflow, and report low order bits of answer.\n\n   The INT_<op>_OVERFLOW macros return 1 if the corresponding C operators\n   might not yield numerically correct answers due to arithmetic overflow.\n   The INT_<op>_WRAPV macros compute the low-order bits of the sum,\n   difference, and product of two C integers, and return 1 if these\n   low-order bits are not numerically correct.\n   These macros work correctly on all known practical hosts, and do not rely\n   on undefined behavior due to signed arithmetic overflow.\n\n   Example usage, assuming A and B are long int:\n\n     if (INT_MULTIPLY_OVERFLOW (a, b))\n       printf (\"result would overflow\\n\");\n     else\n       printf (\"result is %ld (no overflow)\\n\", a * b);\n\n   Example usage with WRAPV flavor:\n\n     long int result;\n     bool overflow = INT_MULTIPLY_WRAPV (a, b, &result);\n     printf (\"result is %ld (%s)\\n\", result,\n             overflow ? \"after overflow\" : \"no overflow\");\n\n   Restrictions on these macros:\n\n   These macros do not check for all possible numerical problems or\n   undefined or unspecified behavior: they do not check for division\n   by zero, for bad shift counts, or for shifting negative numbers.\n\n   These macros may evaluate their arguments zero or multiple times, so the\n   arguments should not have side effects.\n\n   The WRAPV macros are not constant expressions.  They support only\n   +, binary -, and *.\n\n   Because the WRAPV macros convert the result, they report overflow\n   in different circumstances than the OVERFLOW macros do.  For\n   example, in the typical case with 16-bit 'short' and 32-bit 'int',\n   if A, B and R are all of type 'short' then INT_ADD_OVERFLOW (A, B)\n   returns false because the addition cannot overflow after A and B\n   are converted to 'int', whereas INT_ADD_WRAPV (A, B, &R) returns\n   true or false depending on whether the sum fits into 'short'.\n\n   These macros are tuned for their last input argument being a constant.\n\n   Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B,\n   A % B, and A << B would overflow, respectively.  */\n\n#define INT_ADD_OVERFLOW(a, b) \\\n  _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW)\n#define INT_SUBTRACT_OVERFLOW(a, b) \\\n  _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW)\n#if _GL_HAS_BUILTIN_OVERFLOW_P\n# define INT_NEGATE_OVERFLOW(a) INT_SUBTRACT_OVERFLOW (0, a)\n#else\n# define INT_NEGATE_OVERFLOW(a) \\\n   INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))\n#endif\n#define INT_MULTIPLY_OVERFLOW(a, b) \\\n  _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)\n#define INT_DIVIDE_OVERFLOW(a, b) \\\n  _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW)\n#define INT_REMAINDER_OVERFLOW(a, b) \\\n  _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW)\n#define INT_LEFT_SHIFT_OVERFLOW(a, b) \\\n  INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \\\n                                 _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))\n\n/* Return 1 if the expression A <op> B would overflow,\n   where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test,\n   assuming MIN and MAX are the minimum and maximum for the result type.\n   Arguments should be free of side effects.  */\n#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow)        \\\n  op_result_overflow (a, b,                                     \\\n                      _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \\\n                      _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b)))\n\n/* Store the low-order bits of A + B, A - B, A * B, respectively, into *R.\n   Return 1 if the result overflows.  See above for restrictions.  */\n#if _GL_HAS_BUILTIN_ADD_OVERFLOW\n# define INT_ADD_WRAPV(a, b, r) __builtin_add_overflow (a, b, r)\n# define INT_SUBTRACT_WRAPV(a, b, r) __builtin_sub_overflow (a, b, r)\n#else\n# define INT_ADD_WRAPV(a, b, r) \\\n   _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW)\n# define INT_SUBTRACT_WRAPV(a, b, r) \\\n   _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW)\n#endif\n#if _GL_HAS_BUILTIN_MUL_OVERFLOW\n# if ((9 < __GNUC__ + (3 <= __GNUC_MINOR__) \\\n       || (__GNUC__ == 8 && 4 <= __GNUC_MINOR__)) \\\n      && !defined __ICC)\n#  define INT_MULTIPLY_WRAPV(a, b, r) __builtin_mul_overflow (a, b, r)\n# else\n   /* Work around GCC bug 91450.  */\n#  define INT_MULTIPLY_WRAPV(a, b, r) \\\n    ((!_GL_SIGNED_TYPE_OR_EXPR (*(r)) && EXPR_SIGNED (a) && EXPR_SIGNED (b) \\\n      && _GL_INT_MULTIPLY_RANGE_OVERFLOW (a, b, 0, (__typeof__ (*(r))) -1)) \\\n     ? ((void) __builtin_mul_overflow (a, b, r), 1) \\\n     : __builtin_mul_overflow (a, b, r))\n# endif\n#else\n# define INT_MULTIPLY_WRAPV(a, b, r) \\\n   _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW)\n#endif\n\n/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390.  See:\n   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193\n   https://llvm.org/bugs/show_bug.cgi?id=25390\n   For now, assume all versions of GCC-like compilers generate bogus\n   warnings for _Generic.  This matters only for compilers that\n   lack relevant builtins.  */\n#if __GNUC__ || defined __clang__\n# define _GL__GENERIC_BOGUS 1\n#else\n# define _GL__GENERIC_BOGUS 0\n#endif\n\n/* Store the low-order bits of A <op> B into *R, where OP specifies\n   the operation and OVERFLOW the overflow predicate.  Return 1 if the\n   result overflows.  See above for restrictions.  */\n#if 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS\n# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \\\n   (_Generic \\\n    (*(r), \\\n     signed char: \\\n       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \\\n                        signed char, SCHAR_MIN, SCHAR_MAX), \\\n     unsigned char: \\\n       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \\\n                        unsigned char, 0, UCHAR_MAX), \\\n     short int: \\\n       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \\\n                        short int, SHRT_MIN, SHRT_MAX), \\\n     unsigned short int: \\\n       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \\\n                        unsigned short int, 0, USHRT_MAX), \\\n     int: \\\n       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \\\n                        int, INT_MIN, INT_MAX), \\\n     unsigned int: \\\n       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \\\n                        unsigned int, 0, UINT_MAX), \\\n     long int: \\\n       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \\\n                        long int, LONG_MIN, LONG_MAX), \\\n     unsigned long int: \\\n       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \\\n                        unsigned long int, 0, ULONG_MAX), \\\n     long long int: \\\n       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \\\n                        long long int, LLONG_MIN, LLONG_MAX), \\\n     unsigned long long int: \\\n       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \\\n                        unsigned long long int, 0, ULLONG_MAX)))\n#else\n/* Store the low-order bits of A <op> B into *R, where OP specifies\n   the operation and OVERFLOW the overflow predicate.  If *R is\n   signed, its type is ST with bounds SMIN..SMAX; otherwise its type\n   is UT with bounds U..UMAX.  ST and UT are narrower than int.\n   Return 1 if the result overflows.  See above for restrictions.  */\n# if _GL_HAVE___TYPEOF__\n#  define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \\\n    (TYPE_SIGNED (__typeof__ (*(r))) \\\n     ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, st, smin, smax) \\\n     : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, ut, 0, umax))\n# else\n#  define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \\\n    (overflow (a, b, smin, smax) \\\n     ? (overflow (a, b, 0, umax) \\\n        ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 1) \\\n        : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st)) < 0) \\\n     : (overflow (a, b, 0, umax) \\\n        ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st)) >= 0 \\\n        : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 0)))\n# endif\n\n# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \\\n   (sizeof *(r) == sizeof (signed char) \\\n    ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \\\n                                 signed char, SCHAR_MIN, SCHAR_MAX, \\\n                                 unsigned char, UCHAR_MAX) \\\n    : sizeof *(r) == sizeof (short int) \\\n    ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \\\n                                 short int, SHRT_MIN, SHRT_MAX, \\\n                                 unsigned short int, USHRT_MAX) \\\n    : sizeof *(r) == sizeof (int) \\\n    ? (EXPR_SIGNED (*(r)) \\\n       ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \\\n                          int, INT_MIN, INT_MAX) \\\n       : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \\\n                          unsigned int, 0, UINT_MAX)) \\\n    : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow))\n# ifdef LLONG_MAX\n#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \\\n    (sizeof *(r) == sizeof (long int) \\\n     ? (EXPR_SIGNED (*(r)) \\\n        ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \\\n                           long int, LONG_MIN, LONG_MAX) \\\n        : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \\\n                           unsigned long int, 0, ULONG_MAX)) \\\n     : (EXPR_SIGNED (*(r)) \\\n        ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \\\n                           long long int, LLONG_MIN, LLONG_MAX) \\\n        : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \\\n                           unsigned long long int, 0, ULLONG_MAX)))\n# else\n#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \\\n    (EXPR_SIGNED (*(r)) \\\n     ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \\\n                        long int, LONG_MIN, LONG_MAX) \\\n     : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \\\n                        unsigned long int, 0, ULONG_MAX))\n# endif\n#endif\n\n/* Store the low-order bits of A <op> B into *R, where the operation\n   is given by OP.  Use the unsigned type UT for calculation to avoid\n   overflow problems.  *R's type is T, with extrema TMIN and TMAX.\n   T must be a signed integer type.  Return 1 if the result overflows.  */\n#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \\\n  (overflow (a, b, tmin, tmax) \\\n   ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \\\n   : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))\n\n/* Return the low-order bits of A <op> B, where the operation is given\n   by OP.  Use the unsigned type UT for calculation to avoid undefined\n   behavior on signed integer overflow, and convert the result to type T.\n   UT is at least as wide as T and is no narrower than unsigned int,\n   T is two's complement, and there is no padding or trap representations.\n   Assume that converting UT to T yields the low-order bits, as is\n   done in all known two's-complement C compilers.  E.g., see:\n   https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html\n\n   According to the C standard, converting UT to T yields an\n   implementation-defined result or signal for values outside T's\n   range.  However, code that works around this theoretical problem\n   runs afoul of a compiler bug in Oracle Studio 12.3 x86.  See:\n   https://lists.gnu.org/r/bug-gnulib/2017-04/msg00049.html\n   As the compiler bug is real, don't try to work around the\n   theoretical problem.  */\n\n#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \\\n  ((t) ((ut) (a) op (ut) (b)))\n\n/* Return true if the numeric values A + B, A - B, A * B fall outside\n   the range TMIN..TMAX.  Arguments should be integer expressions\n   without side effects.  TMIN should be signed and nonpositive.\n   TMAX should be positive, and should be signed unless TMIN is zero.  */\n#define _GL_INT_ADD_RANGE_OVERFLOW(a, b, tmin, tmax) \\\n  ((b) < 0 \\\n   ? (((tmin) \\\n       ? ((EXPR_SIGNED (_GL_INT_CONVERT (a, (tmin) - (b))) || (b) < (tmin)) \\\n          && (a) < (tmin) - (b)) \\\n       : (a) <= -1 - (b)) \\\n      || ((EXPR_SIGNED (a) ? 0 <= (a) : (tmax) < (a)) && (tmax) < (a) + (b))) \\\n   : (a) < 0 \\\n   ? (((tmin) \\\n       ? ((EXPR_SIGNED (_GL_INT_CONVERT (b, (tmin) - (a))) || (a) < (tmin)) \\\n          && (b) < (tmin) - (a)) \\\n       : (b) <= -1 - (a)) \\\n      || ((EXPR_SIGNED (_GL_INT_CONVERT (a, b)) || (tmax) < (b)) \\\n          && (tmax) < (a) + (b))) \\\n   : (tmax) < (b) || (tmax) - (b) < (a))\n#define _GL_INT_SUBTRACT_RANGE_OVERFLOW(a, b, tmin, tmax) \\\n  (((a) < 0) == ((b) < 0) \\\n   ? ((a) < (b) \\\n      ? !(tmin) || -1 - (tmin) < (b) - (a) - 1 \\\n      : (tmax) < (a) - (b)) \\\n   : (a) < 0 \\\n   ? ((!EXPR_SIGNED (_GL_INT_CONVERT ((a) - (tmin), b)) && (a) - (tmin) < 0) \\\n      || (a) - (tmin) < (b)) \\\n   : ((! (EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \\\n          && EXPR_SIGNED (_GL_INT_CONVERT ((tmax) + (b), a))) \\\n       && (tmax) <= -1 - (b)) \\\n      || (tmax) + (b) < (a)))\n#define _GL_INT_MULTIPLY_RANGE_OVERFLOW(a, b, tmin, tmax) \\\n  ((b) < 0 \\\n   ? ((a) < 0 \\\n      ? (EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \\\n         ? (a) < (tmax) / (b) \\\n         : ((INT_NEGATE_OVERFLOW (b) \\\n             ? _GL_INT_CONVERT (b, tmax) >> (TYPE_WIDTH (+ (b)) - 1) \\\n             : (tmax) / -(b)) \\\n            <= -1 - (a))) \\\n      : INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (b, tmin)) && (b) == -1 \\\n      ? (EXPR_SIGNED (a) \\\n         ? 0 < (a) + (tmin) \\\n         : 0 < (a) && -1 - (tmin) < (a) - 1) \\\n      : (tmin) / (b) < (a)) \\\n   : (b) == 0 \\\n   ? 0 \\\n   : ((a) < 0 \\\n      ? (INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (a, tmin)) && (a) == -1 \\\n         ? (EXPR_SIGNED (b) ? 0 < (b) + (tmin) : -1 - (tmin) < (b) - 1) \\\n         : (tmin) / (a) < (b)) \\\n      : (tmax) / (b) < (a)))\n\n/* The following macros compute A + B, A - B, and A * B, respectively.\n   If no overflow occurs, they set *R to the result and return 1;\n   otherwise, they return 0 and may modify *R.\n\n   Example usage:\n\n     long int result;\n     if (INT_ADD_OK (a, b, &result))\n       printf (\"result is %ld\\n\", result);\n     else\n       printf (\"overflow\\n\");\n\n   A, B, and *R should be integers; they need not be the same type,\n   and they need not be all signed or all unsigned.\n\n   These macros work correctly on all known practical hosts, and do not rely\n   on undefined behavior due to signed arithmetic overflow.\n\n   These macros are not constant expressions.\n\n   These macros may evaluate their arguments zero or multiple times, so the\n   arguments should not have side effects.\n\n   These macros are tuned for B being a constant.  */\n\n#define INT_ADD_OK(a, b, r) ! INT_ADD_WRAPV (a, b, r)\n#define INT_SUBTRACT_OK(a, b, r) ! INT_SUBTRACT_WRAPV (a, b, r)\n#define INT_MULTIPLY_OK(a, b, r) ! INT_MULTIPLY_WRAPV (a, b, r)\n\n#endif /* _GL_INTPROPS_H */\n"
  },
  {
    "path": "gnulib/inttypes.in.h",
    "content": "/* Copyright (C) 2006-2021 Free Software Foundation, Inc.\n   Written by Paul Eggert, Bruno Haible, Derek Price.\n   This file is part of gnulib.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/*\n * ISO C 99 <inttypes.h> for platforms that lack it.\n * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/inttypes.h.html>\n */\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n/* Include the original <inttypes.h> if it exists, and if this file\n   has not been included yet or if this file includes gnulib stdint.h\n   which in turn includes this file.\n   The include_next requires a split double-inclusion guard.  */\n#if ! defined INTTYPES_H || defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H\n# if @HAVE_INTTYPES_H@\n\n   /* Some pre-C++11 <stdint.h> implementations need this.  */\n#  if defined __cplusplus && ! defined __STDC_FORMAT_MACROS\n#   define __STDC_FORMAT_MACROS 1\n#  endif\n\n#  @INCLUDE_NEXT@ @NEXT_INTTYPES_H@\n\n#  define _GL_FINISHED_INCLUDING_SYSTEM_INTTYPES_H\n# endif\n#endif\n\n#if ! defined INTTYPES_H && ! defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H\n#define INTTYPES_H\n\n/* Include <stdint.h> or the gnulib replacement.\n   But avoid namespace pollution on glibc systems.  */\n#ifndef __GLIBC__\n# include <stdint.h>\n#endif\n/* Get CHAR_BIT, INT_MAX, LONG_MAX, etc.  */\n#include <limits.h>\n/* On mingw, __USE_MINGW_ANSI_STDIO only works if <stdio.h> is also included */\n#if defined _WIN32 && ! defined __CYGWIN__\n# include <stdio.h>\n#endif\n\n#if !(INT_MAX == 0x7fffffff && INT_MIN + INT_MAX == -1)\n# error \"This file assumes that 'int' is 32-bit two's complement. Please report your platform and compiler to <bug-gnulib@gnu.org>.\"\n#endif\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n\n/* 7.8.1 Macros for format specifiers */\n\n#if defined _TNS_R_TARGET\n   /* Tandem NonStop R series and compatible platforms released before\n      July 2005 support %Ld but not %lld.  */\n# define _LONG_LONG_FORMAT_PREFIX \"L\"\n#else\n# define _LONG_LONG_FORMAT_PREFIX \"ll\"\n#endif\n\n#if !defined PRId8\n# ifdef INT8_MAX\n#  define PRId8 \"d\"\n# endif\n#endif\n#if !defined PRIi8\n# ifdef INT8_MAX\n#  define PRIi8 \"i\"\n# endif\n#endif\n#if !defined PRIo8\n# ifdef UINT8_MAX\n#  define PRIo8 \"o\"\n# endif\n#endif\n#if !defined PRIu8\n# ifdef UINT8_MAX\n#  define PRIu8 \"u\"\n# endif\n#endif\n#if !defined PRIx8\n# ifdef UINT8_MAX\n#  define PRIx8 \"x\"\n# endif\n#endif\n#if !defined PRIX8\n# ifdef UINT8_MAX\n#  define PRIX8 \"X\"\n# endif\n#endif\n#if !defined PRId16\n# ifdef INT16_MAX\n#  define PRId16 \"d\"\n# endif\n#endif\n#if !defined PRIi16\n# ifdef INT16_MAX\n#  define PRIi16 \"i\"\n# endif\n#endif\n#if !defined PRIo16\n# ifdef UINT16_MAX\n#  define PRIo16 \"o\"\n# endif\n#endif\n#if !defined PRIu16\n# ifdef UINT16_MAX\n#  define PRIu16 \"u\"\n# endif\n#endif\n#if !defined PRIx16\n# ifdef UINT16_MAX\n#  define PRIx16 \"x\"\n# endif\n#endif\n#if !defined PRIX16\n# ifdef UINT16_MAX\n#  define PRIX16 \"X\"\n# endif\n#endif\n#if !defined PRId32\n# ifdef INT32_MAX\n#  define PRId32 \"d\"\n# endif\n#endif\n#if !defined PRIi32\n# ifdef INT32_MAX\n#  define PRIi32 \"i\"\n# endif\n#endif\n#if !defined PRIo32\n# ifdef UINT32_MAX\n#  define PRIo32 \"o\"\n# endif\n#endif\n#if !defined PRIu32\n# ifdef UINT32_MAX\n#  define PRIu32 \"u\"\n# endif\n#endif\n#if !defined PRIx32\n# ifdef UINT32_MAX\n#  define PRIx32 \"x\"\n# endif\n#endif\n#if !defined PRIX32\n# ifdef UINT32_MAX\n#  define PRIX32 \"X\"\n# endif\n#endif\n#ifdef INT64_MAX\n# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @INT64_MAX_EQ_LONG_MAX@)\n#  define _PRI64_PREFIX \"l\"\n# elif defined _MSC_VER || defined __MINGW32__\n#  define _PRI64_PREFIX \"I64\"\n# elif LONG_MAX >> 30 == 1\n#  define _PRI64_PREFIX _LONG_LONG_FORMAT_PREFIX\n# endif\n# if !defined PRId64\n#  define PRId64 _PRI64_PREFIX \"d\"\n# endif\n# if !defined PRIi64\n#  define PRIi64 _PRI64_PREFIX \"i\"\n# endif\n#endif\n#ifdef UINT64_MAX\n# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @UINT64_MAX_EQ_ULONG_MAX@)\n#  define _PRIu64_PREFIX \"l\"\n# elif defined _MSC_VER || defined __MINGW32__\n#  define _PRIu64_PREFIX \"I64\"\n# elif ULONG_MAX >> 31 == 1\n#  define _PRIu64_PREFIX _LONG_LONG_FORMAT_PREFIX\n# endif\n# if !defined PRIo64\n#  define PRIo64 _PRIu64_PREFIX \"o\"\n# endif\n# if !defined PRIu64\n#  define PRIu64 _PRIu64_PREFIX \"u\"\n# endif\n# if !defined PRIx64\n#  define PRIx64 _PRIu64_PREFIX \"x\"\n# endif\n# if !defined PRIX64\n#  define PRIX64 _PRIu64_PREFIX \"X\"\n# endif\n#endif\n\n#if !defined PRIdLEAST8\n# define PRIdLEAST8 \"d\"\n#endif\n#if !defined PRIiLEAST8\n# define PRIiLEAST8 \"i\"\n#endif\n#if !defined PRIoLEAST8\n# define PRIoLEAST8 \"o\"\n#endif\n#if !defined PRIuLEAST8\n# define PRIuLEAST8 \"u\"\n#endif\n#if !defined PRIxLEAST8\n# define PRIxLEAST8 \"x\"\n#endif\n#if !defined PRIXLEAST8\n# define PRIXLEAST8 \"X\"\n#endif\n#if !defined PRIdLEAST16\n# define PRIdLEAST16 \"d\"\n#endif\n#if !defined PRIiLEAST16\n# define PRIiLEAST16 \"i\"\n#endif\n#if !defined PRIoLEAST16\n# define PRIoLEAST16 \"o\"\n#endif\n#if !defined PRIuLEAST16\n# define PRIuLEAST16 \"u\"\n#endif\n#if !defined PRIxLEAST16\n# define PRIxLEAST16 \"x\"\n#endif\n#if !defined PRIXLEAST16\n# define PRIXLEAST16 \"X\"\n#endif\n#if !defined PRIdLEAST32\n# define PRIdLEAST32 \"d\"\n#endif\n#if !defined PRIiLEAST32\n# define PRIiLEAST32 \"i\"\n#endif\n#if !defined PRIoLEAST32\n# define PRIoLEAST32 \"o\"\n#endif\n#if !defined PRIuLEAST32\n# define PRIuLEAST32 \"u\"\n#endif\n#if !defined PRIxLEAST32\n# define PRIxLEAST32 \"x\"\n#endif\n#if !defined PRIXLEAST32\n# define PRIXLEAST32 \"X\"\n#endif\n#ifdef INT64_MAX\n# if !defined PRIdLEAST64\n#  define PRIdLEAST64 PRId64\n# endif\n# if !defined PRIiLEAST64\n#  define PRIiLEAST64 PRIi64\n# endif\n#endif\n#ifdef UINT64_MAX\n# if !defined PRIoLEAST64\n#  define PRIoLEAST64 PRIo64\n# endif\n# if !defined PRIuLEAST64\n#  define PRIuLEAST64 PRIu64\n# endif\n# if !defined PRIxLEAST64\n#  define PRIxLEAST64 PRIx64\n# endif\n# if !defined PRIXLEAST64\n#  define PRIXLEAST64 PRIX64\n# endif\n#endif\n\n#if !defined PRIdFAST8\n# if INT_FAST8_MAX > INT32_MAX\n#  define PRIdFAST8 PRId64\n# else\n#  define PRIdFAST8 \"d\"\n# endif\n#endif\n#if !defined PRIiFAST8\n# if INT_FAST8_MAX > INT32_MAX\n#  define PRIiFAST8 PRIi64\n# else\n#  define PRIiFAST8 \"i\"\n# endif\n#endif\n#if !defined PRIoFAST8\n# if UINT_FAST8_MAX > UINT32_MAX\n#  define PRIoFAST8 PRIo64\n# else\n#  define PRIoFAST8 \"o\"\n# endif\n#endif\n#if !defined PRIuFAST8\n# if UINT_FAST8_MAX > UINT32_MAX\n#  define PRIuFAST8 PRIu64\n# else\n#  define PRIuFAST8 \"u\"\n# endif\n#endif\n#if !defined PRIxFAST8\n# if UINT_FAST8_MAX > UINT32_MAX\n#  define PRIxFAST8 PRIx64\n# else\n#  define PRIxFAST8 \"x\"\n# endif\n#endif\n#if !defined PRIXFAST8\n# if UINT_FAST8_MAX > UINT32_MAX\n#  define PRIXFAST8 PRIX64\n# else\n#  define PRIXFAST8 \"X\"\n# endif\n#endif\n#if !defined PRIdFAST16\n# if INT_FAST16_MAX > INT32_MAX\n#  define PRIdFAST16 PRId64\n# else\n#  define PRIdFAST16 \"d\"\n# endif\n#endif\n#if !defined PRIiFAST16\n# if INT_FAST16_MAX > INT32_MAX\n#  define PRIiFAST16 PRIi64\n# else\n#  define PRIiFAST16 \"i\"\n# endif\n#endif\n#if !defined PRIoFAST16\n# if UINT_FAST16_MAX > UINT32_MAX\n#  define PRIoFAST16 PRIo64\n# else\n#  define PRIoFAST16 \"o\"\n# endif\n#endif\n#if !defined PRIuFAST16\n# if UINT_FAST16_MAX > UINT32_MAX\n#  define PRIuFAST16 PRIu64\n# else\n#  define PRIuFAST16 \"u\"\n# endif\n#endif\n#if !defined PRIxFAST16\n# if UINT_FAST16_MAX > UINT32_MAX\n#  define PRIxFAST16 PRIx64\n# else\n#  define PRIxFAST16 \"x\"\n# endif\n#endif\n#if !defined PRIXFAST16\n# if UINT_FAST16_MAX > UINT32_MAX\n#  define PRIXFAST16 PRIX64\n# else\n#  define PRIXFAST16 \"X\"\n# endif\n#endif\n#if !defined PRIdFAST32\n# if INT_FAST32_MAX > INT32_MAX\n#  define PRIdFAST32 PRId64\n# else\n#  define PRIdFAST32 \"d\"\n# endif\n#endif\n#if !defined PRIiFAST32\n# if INT_FAST32_MAX > INT32_MAX\n#  define PRIiFAST32 PRIi64\n# else\n#  define PRIiFAST32 \"i\"\n# endif\n#endif\n#if !defined PRIoFAST32\n# if UINT_FAST32_MAX > UINT32_MAX\n#  define PRIoFAST32 PRIo64\n# else\n#  define PRIoFAST32 \"o\"\n# endif\n#endif\n#if !defined PRIuFAST32\n# if UINT_FAST32_MAX > UINT32_MAX\n#  define PRIuFAST32 PRIu64\n# else\n#  define PRIuFAST32 \"u\"\n# endif\n#endif\n#if !defined PRIxFAST32\n# if UINT_FAST32_MAX > UINT32_MAX\n#  define PRIxFAST32 PRIx64\n# else\n#  define PRIxFAST32 \"x\"\n# endif\n#endif\n#if !defined PRIXFAST32\n# if UINT_FAST32_MAX > UINT32_MAX\n#  define PRIXFAST32 PRIX64\n# else\n#  define PRIXFAST32 \"X\"\n# endif\n#endif\n#ifdef INT64_MAX\n# if !defined PRIdFAST64\n#  define PRIdFAST64 PRId64\n# endif\n# if !defined PRIiFAST64\n#  define PRIiFAST64 PRIi64\n# endif\n#endif\n#ifdef UINT64_MAX\n# if !defined PRIoFAST64\n#  define PRIoFAST64 PRIo64\n# endif\n# if !defined PRIuFAST64\n#  define PRIuFAST64 PRIu64\n# endif\n# if !defined PRIxFAST64\n#  define PRIxFAST64 PRIx64\n# endif\n# if !defined PRIXFAST64\n#  define PRIXFAST64 PRIX64\n# endif\n#endif\n\n#if !defined PRIdMAX\n# if @INT32_MAX_LT_INTMAX_MAX@\n#  define PRIdMAX PRId64\n# else\n#  define PRIdMAX \"ld\"\n# endif\n#endif\n#if !defined PRIiMAX\n# if @INT32_MAX_LT_INTMAX_MAX@\n#  define PRIiMAX PRIi64\n# else\n#  define PRIiMAX \"li\"\n# endif\n#endif\n#if !defined PRIoMAX\n# if @UINT32_MAX_LT_UINTMAX_MAX@\n#  define PRIoMAX PRIo64\n# else\n#  define PRIoMAX \"lo\"\n# endif\n#endif\n#if !defined PRIuMAX\n# if @UINT32_MAX_LT_UINTMAX_MAX@\n#  define PRIuMAX PRIu64\n# else\n#  define PRIuMAX \"lu\"\n# endif\n#endif\n#if !defined PRIxMAX\n# if @UINT32_MAX_LT_UINTMAX_MAX@\n#  define PRIxMAX PRIx64\n# else\n#  define PRIxMAX \"lx\"\n# endif\n#endif\n#if !defined PRIXMAX\n# if @UINT32_MAX_LT_UINTMAX_MAX@\n#  define PRIXMAX PRIX64\n# else\n#  define PRIXMAX \"lX\"\n# endif\n#endif\n\n#if !defined PRIdPTR\n# ifdef INTPTR_MAX\n#  define PRIdPTR @PRIPTR_PREFIX@ \"d\"\n# endif\n#endif\n#if !defined PRIiPTR\n# ifdef INTPTR_MAX\n#  define PRIiPTR @PRIPTR_PREFIX@ \"i\"\n# endif\n#endif\n#if !defined PRIoPTR\n# ifdef UINTPTR_MAX\n#  define PRIoPTR @PRIPTR_PREFIX@ \"o\"\n# endif\n#endif\n#if !defined PRIuPTR\n# ifdef UINTPTR_MAX\n#  define PRIuPTR @PRIPTR_PREFIX@ \"u\"\n# endif\n#endif\n#if !defined PRIxPTR\n# ifdef UINTPTR_MAX\n#  define PRIxPTR @PRIPTR_PREFIX@ \"x\"\n# endif\n#endif\n#if !defined PRIXPTR\n# ifdef UINTPTR_MAX\n#  define PRIXPTR @PRIPTR_PREFIX@ \"X\"\n# endif\n#endif\n\n#if !defined SCNd8\n# ifdef INT8_MAX\n#  define SCNd8 \"hhd\"\n# endif\n#endif\n#if !defined SCNi8\n# ifdef INT8_MAX\n#  define SCNi8 \"hhi\"\n# endif\n#endif\n#if !defined SCNo8\n# ifdef UINT8_MAX\n#  define SCNo8 \"hho\"\n# endif\n#endif\n#if !defined SCNu8\n# ifdef UINT8_MAX\n#  define SCNu8 \"hhu\"\n# endif\n#endif\n#if !defined SCNx8\n# ifdef UINT8_MAX\n#  define SCNx8 \"hhx\"\n# endif\n#endif\n#if !defined SCNd16\n# ifdef INT16_MAX\n#  define SCNd16 \"hd\"\n# endif\n#endif\n#if !defined SCNi16\n# ifdef INT16_MAX\n#  define SCNi16 \"hi\"\n# endif\n#endif\n#if !defined SCNo16\n# ifdef UINT16_MAX\n#  define SCNo16 \"ho\"\n# endif\n#endif\n#if !defined SCNu16\n# ifdef UINT16_MAX\n#  define SCNu16 \"hu\"\n# endif\n#endif\n#if !defined SCNx16\n# ifdef UINT16_MAX\n#  define SCNx16 \"hx\"\n# endif\n#endif\n#if !defined SCNd32\n# ifdef INT32_MAX\n#  define SCNd32 \"d\"\n# endif\n#endif\n#if !defined SCNi32\n# ifdef INT32_MAX\n#  define SCNi32 \"i\"\n# endif\n#endif\n#if !defined SCNo32\n# ifdef UINT32_MAX\n#  define SCNo32 \"o\"\n# endif\n#endif\n#if !defined SCNu32\n# ifdef UINT32_MAX\n#  define SCNu32 \"u\"\n# endif\n#endif\n#if !defined SCNx32\n# ifdef UINT32_MAX\n#  define SCNx32 \"x\"\n# endif\n#endif\n#ifdef INT64_MAX\n# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @INT64_MAX_EQ_LONG_MAX@)\n#  define _SCN64_PREFIX \"l\"\n# elif defined _MSC_VER || defined __MINGW32__\n#  define _SCN64_PREFIX \"I64\"\n# elif LONG_MAX >> 30 == 1\n#  define _SCN64_PREFIX _LONG_LONG_FORMAT_PREFIX\n# endif\n# if !defined SCNd64\n#  define SCNd64 _SCN64_PREFIX \"d\"\n# endif\n# if !defined SCNi64\n#  define SCNi64 _SCN64_PREFIX \"i\"\n# endif\n#endif\n#ifdef UINT64_MAX\n# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @UINT64_MAX_EQ_ULONG_MAX@)\n#  define _SCNu64_PREFIX \"l\"\n# elif defined _MSC_VER || defined __MINGW32__\n#  define _SCNu64_PREFIX \"I64\"\n# elif ULONG_MAX >> 31 == 1\n#  define _SCNu64_PREFIX _LONG_LONG_FORMAT_PREFIX\n# endif\n# if !defined SCNo64\n#  define SCNo64 _SCNu64_PREFIX \"o\"\n# endif\n# if !defined SCNu64\n#  define SCNu64 _SCNu64_PREFIX \"u\"\n# endif\n# if !defined SCNx64\n#  define SCNx64 _SCNu64_PREFIX \"x\"\n# endif\n#endif\n\n#if !defined SCNdLEAST8\n# define SCNdLEAST8 \"hhd\"\n#endif\n#if !defined SCNiLEAST8\n# define SCNiLEAST8 \"hhi\"\n#endif\n#if !defined SCNoLEAST8\n# define SCNoLEAST8 \"hho\"\n#endif\n#if !defined SCNuLEAST8\n# define SCNuLEAST8 \"hhu\"\n#endif\n#if !defined SCNxLEAST8\n# define SCNxLEAST8 \"hhx\"\n#endif\n#if !defined SCNdLEAST16\n# define SCNdLEAST16 \"hd\"\n#endif\n#if !defined SCNiLEAST16\n# define SCNiLEAST16 \"hi\"\n#endif\n#if !defined SCNoLEAST16\n# define SCNoLEAST16 \"ho\"\n#endif\n#if !defined SCNuLEAST16\n# define SCNuLEAST16 \"hu\"\n#endif\n#if !defined SCNxLEAST16\n# define SCNxLEAST16 \"hx\"\n#endif\n#if !defined SCNdLEAST32\n# define SCNdLEAST32 \"d\"\n#endif\n#if !defined SCNiLEAST32\n# define SCNiLEAST32 \"i\"\n#endif\n#if !defined SCNoLEAST32\n# define SCNoLEAST32 \"o\"\n#endif\n#if !defined SCNuLEAST32\n# define SCNuLEAST32 \"u\"\n#endif\n#if !defined SCNxLEAST32\n# define SCNxLEAST32 \"x\"\n#endif\n#ifdef INT64_MAX\n# if !defined SCNdLEAST64\n#  define SCNdLEAST64 SCNd64\n# endif\n# if !defined SCNiLEAST64\n#  define SCNiLEAST64 SCNi64\n# endif\n#endif\n#ifdef UINT64_MAX\n# if !defined SCNoLEAST64\n#  define SCNoLEAST64 SCNo64\n# endif\n# if !defined SCNuLEAST64\n#  define SCNuLEAST64 SCNu64\n# endif\n# if !defined SCNxLEAST64\n#  define SCNxLEAST64 SCNx64\n# endif\n#endif\n\n#if !defined SCNdFAST8\n# if INT_FAST8_MAX > INT32_MAX\n#  define SCNdFAST8 SCNd64\n# elif INT_FAST8_MAX == 0x7fff\n#  define SCNdFAST8 \"hd\"\n# elif INT_FAST8_MAX == 0x7f\n#  define SCNdFAST8 \"hhd\"\n# else\n#  define SCNdFAST8 \"d\"\n# endif\n#endif\n#if !defined SCNiFAST8\n# if INT_FAST8_MAX > INT32_MAX\n#  define SCNiFAST8 SCNi64\n# elif INT_FAST8_MAX == 0x7fff\n#  define SCNiFAST8 \"hi\"\n# elif INT_FAST8_MAX == 0x7f\n#  define SCNiFAST8 \"hhi\"\n# else\n#  define SCNiFAST8 \"i\"\n# endif\n#endif\n#if !defined SCNoFAST8\n# if UINT_FAST8_MAX > UINT32_MAX\n#  define SCNoFAST8 SCNo64\n# elif UINT_FAST8_MAX == 0xffff\n#  define SCNoFAST8 \"ho\"\n# elif UINT_FAST8_MAX == 0xff\n#  define SCNoFAST8 \"hho\"\n# else\n#  define SCNoFAST8 \"o\"\n# endif\n#endif\n#if !defined SCNuFAST8\n# if UINT_FAST8_MAX > UINT32_MAX\n#  define SCNuFAST8 SCNu64\n# elif UINT_FAST8_MAX == 0xffff\n#  define SCNuFAST8 \"hu\"\n# elif UINT_FAST8_MAX == 0xff\n#  define SCNuFAST8 \"hhu\"\n# else\n#  define SCNuFAST8 \"u\"\n# endif\n#endif\n#if !defined SCNxFAST8\n# if UINT_FAST8_MAX > UINT32_MAX\n#  define SCNxFAST8 SCNx64\n# elif UINT_FAST8_MAX == 0xffff\n#  define SCNxFAST8 \"hx\"\n# elif UINT_FAST8_MAX == 0xff\n#  define SCNxFAST8 \"hhx\"\n# else\n#  define SCNxFAST8 \"x\"\n# endif\n#endif\n#if !defined SCNdFAST16\n# if INT_FAST16_MAX > INT32_MAX\n#  define SCNdFAST16 SCNd64\n# elif INT_FAST16_MAX == 0x7fff\n#  define SCNdFAST16 \"hd\"\n# else\n#  define SCNdFAST16 \"d\"\n# endif\n#endif\n#if !defined SCNiFAST16\n# if INT_FAST16_MAX > INT32_MAX\n#  define SCNiFAST16 SCNi64\n# elif INT_FAST16_MAX == 0x7fff\n#  define SCNiFAST16 \"hi\"\n# else\n#  define SCNiFAST16 \"i\"\n# endif\n#endif\n#if !defined SCNoFAST16\n# if UINT_FAST16_MAX > UINT32_MAX\n#  define SCNoFAST16 SCNo64\n# elif UINT_FAST16_MAX == 0xffff\n#  define SCNoFAST16 \"ho\"\n# else\n#  define SCNoFAST16 \"o\"\n# endif\n#endif\n#if !defined SCNuFAST16\n# if UINT_FAST16_MAX > UINT32_MAX\n#  define SCNuFAST16 SCNu64\n# elif UINT_FAST16_MAX == 0xffff\n#  define SCNuFAST16 \"hu\"\n# else\n#  define SCNuFAST16 \"u\"\n# endif\n#endif\n#if !defined SCNxFAST16\n# if UINT_FAST16_MAX > UINT32_MAX\n#  define SCNxFAST16 SCNx64\n# elif UINT_FAST16_MAX == 0xffff\n#  define SCNxFAST16 \"hx\"\n# else\n#  define SCNxFAST16 \"x\"\n# endif\n#endif\n#if !defined SCNdFAST32\n# if INT_FAST32_MAX > INT32_MAX\n#  define SCNdFAST32 SCNd64\n# else\n#  define SCNdFAST32 \"d\"\n# endif\n#endif\n#if !defined SCNiFAST32\n# if INT_FAST32_MAX > INT32_MAX\n#  define SCNiFAST32 SCNi64\n# else\n#  define SCNiFAST32 \"i\"\n# endif\n#endif\n#if !defined SCNoFAST32\n# if UINT_FAST32_MAX > UINT32_MAX\n#  define SCNoFAST32 SCNo64\n# else\n#  define SCNoFAST32 \"o\"\n# endif\n#endif\n#if !defined SCNuFAST32\n# if UINT_FAST32_MAX > UINT32_MAX\n#  define SCNuFAST32 SCNu64\n# else\n#  define SCNuFAST32 \"u\"\n# endif\n#endif\n#if !defined SCNxFAST32\n# if UINT_FAST32_MAX > UINT32_MAX\n#  define SCNxFAST32 SCNx64\n# else\n#  define SCNxFAST32 \"x\"\n# endif\n#endif\n#ifdef INT64_MAX\n# if !defined SCNdFAST64\n#  define SCNdFAST64 SCNd64\n# endif\n# if !defined SCNiFAST64\n#  define SCNiFAST64 SCNi64\n# endif\n#endif\n#ifdef UINT64_MAX\n# if !defined SCNoFAST64\n#  define SCNoFAST64 SCNo64\n# endif\n# if !defined SCNuFAST64\n#  define SCNuFAST64 SCNu64\n# endif\n# if !defined SCNxFAST64\n#  define SCNxFAST64 SCNx64\n# endif\n#endif\n\n#if !defined SCNdMAX\n# if @INT32_MAX_LT_INTMAX_MAX@\n#  define SCNdMAX SCNd64\n# else\n#  define SCNdMAX \"ld\"\n# endif\n#endif\n#if !defined SCNiMAX\n# if @INT32_MAX_LT_INTMAX_MAX@\n#  define SCNiMAX SCNi64\n# else\n#  define SCNiMAX \"li\"\n# endif\n#endif\n#if !defined SCNoMAX\n# if @UINT32_MAX_LT_UINTMAX_MAX@\n#  define SCNoMAX SCNo64\n# else\n#  define SCNoMAX \"lo\"\n# endif\n#endif\n#if !defined SCNuMAX\n# if @UINT32_MAX_LT_UINTMAX_MAX@\n#  define SCNuMAX SCNu64\n# else\n#  define SCNuMAX \"lu\"\n# endif\n#endif\n#if !defined SCNxMAX\n# if @UINT32_MAX_LT_UINTMAX_MAX@\n#  define SCNxMAX SCNx64\n# else\n#  define SCNxMAX \"lx\"\n# endif\n#endif\n\n#if !defined SCNdPTR\n# ifdef INTPTR_MAX\n#  define SCNdPTR @PRIPTR_PREFIX@ \"d\"\n# endif\n#endif\n#if !defined SCNiPTR\n# ifdef INTPTR_MAX\n#  define SCNiPTR @PRIPTR_PREFIX@ \"i\"\n# endif\n#endif\n#if !defined SCNoPTR\n# ifdef UINTPTR_MAX\n#  define SCNoPTR @PRIPTR_PREFIX@ \"o\"\n# endif\n#endif\n#if !defined SCNuPTR\n# ifdef UINTPTR_MAX\n#  define SCNuPTR @PRIPTR_PREFIX@ \"u\"\n# endif\n#endif\n#if !defined SCNxPTR\n# ifdef UINTPTR_MAX\n#  define SCNxPTR @PRIPTR_PREFIX@ \"x\"\n# endif\n#endif\n\n/* 7.8.2 Functions for greatest-width integer types */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if @GNULIB_IMAXABS@\n# if !@HAVE_DECL_IMAXABS@\nextern intmax_t imaxabs (intmax_t);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef imaxabs\n# if HAVE_RAW_DECL_IMAXABS\n_GL_WARN_ON_USE (imaxabs, \"imaxabs is unportable - \"\n                 \"use gnulib module imaxabs for portability\");\n# endif\n#endif\n\n#if @GNULIB_IMAXDIV@\n# if !@HAVE_IMAXDIV_T@\n#  if !GNULIB_defined_imaxdiv_t\ntypedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t;\n#   define GNULIB_defined_imaxdiv_t 1\n#  endif\n# endif\n# if !@HAVE_DECL_IMAXDIV@\nextern imaxdiv_t imaxdiv (intmax_t, intmax_t);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef imaxdiv\n# if HAVE_RAW_DECL_IMAXDIV\n_GL_WARN_ON_USE (imaxdiv, \"imaxdiv is unportable - \"\n                 \"use gnulib module imaxdiv for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRTOIMAX@\n# if @REPLACE_STRTOIMAX@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strtoimax\n#   define strtoimax rpl_strtoimax\n#  endif\n_GL_FUNCDECL_RPL (strtoimax, intmax_t,\n                  (const char *restrict, char **restrict, int)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strtoimax, intmax_t,\n                  (const char *restrict, char **restrict, int));\n# else\n#  if !@HAVE_DECL_STRTOIMAX@\n#   undef strtoimax\n_GL_FUNCDECL_SYS (strtoimax, intmax_t,\n                  (const char *restrict, char **restrict, int)\n                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strtoimax, intmax_t,\n                  (const char *restrict, char **restrict, int));\n# endif\n_GL_CXXALIASWARN (strtoimax);\n#elif defined GNULIB_POSIXCHECK\n# undef strtoimax\n# if HAVE_RAW_DECL_STRTOIMAX\n_GL_WARN_ON_USE (strtoimax, \"strtoimax is unportable - \"\n                 \"use gnulib module strtoimax for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRTOUMAX@\n# if @REPLACE_STRTOUMAX@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strtoumax\n#   define strtoumax rpl_strtoumax\n#  endif\n_GL_FUNCDECL_RPL (strtoumax, uintmax_t,\n                  (const char *restrict, char **restrict, int)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strtoumax, uintmax_t,\n                  (const char *restrict, char **restrict, int));\n# else\n#  if !@HAVE_DECL_STRTOUMAX@\n#   undef strtoumax\n_GL_FUNCDECL_SYS (strtoumax, uintmax_t,\n                  (const char *restrict, char **restrict, int)\n                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strtoumax, uintmax_t,\n                  (const char *restrict, char **restrict, int));\n# endif\n_GL_CXXALIASWARN (strtoumax);\n#elif defined GNULIB_POSIXCHECK\n# undef strtoumax\n# if HAVE_RAW_DECL_STRTOUMAX\n_GL_WARN_ON_USE (strtoumax, \"strtoumax is unportable - \"\n                 \"use gnulib module strtoumax for portability\");\n# endif\n#endif\n\n/* Don't bother defining or declaring wcstoimax and wcstoumax, since\n   wide-character functions like this are hardly ever useful.  */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* !defined INTTYPES_H && !defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H */\n"
  },
  {
    "path": "gnulib/isblank.c",
    "content": "/* Test whether a character is a blank.\n\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <ctype.h>\n\nint\nisblank (int c)\n{\n  /* On all known platforms, in all predefined locales, isblank(c) is likely\n     equivalent with  (c == ' ' || c == '\\t').  Look at the glibc definition\n     (in glibc/localedata/locales/i18n): The \"blank\" characters are '\\t', ' ',\n     U+1680, U+180E, U+2000..U+2006, U+2008..U+200A, U+205F, U+3000, and none\n     except the first two is present in a common 8-bit encoding.  Therefore\n     the substitute for other platforms is not more complicated than this.  */\n  return (c == ' ' || c == '\\t');\n}\n"
  },
  {
    "path": "gnulib/langinfo.in.h",
    "content": "/* Substitute for and wrapper around <langinfo.h>.\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/*\n * POSIX <langinfo.h> for platforms that lack it or have an incomplete one.\n * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/langinfo.h.html>\n */\n\n#ifndef _@GUARD_PREFIX@_LANGINFO_H\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n/* The include_next requires a split double-inclusion guard.  */\n#if @HAVE_LANGINFO_H@\n# @INCLUDE_NEXT@ @NEXT_LANGINFO_H@\n#endif\n\n#ifndef _@GUARD_PREFIX@_LANGINFO_H\n#define _@GUARD_PREFIX@_LANGINFO_H\n\n\n#if !@HAVE_LANGINFO_H@\n\n/* A platform that lacks <langinfo.h>.  */\n\n/* Assume that it also lacks <nl_types.h> and the nl_item type.  */\n# if !GNULIB_defined_nl_item\ntypedef int nl_item;\n#  define GNULIB_defined_nl_item 1\n# endif\n\n/* nl_langinfo items of the LC_CTYPE category */\n# define CODESET     10000\n/* nl_langinfo items of the LC_NUMERIC category */\n# define RADIXCHAR   10001\n# define DECIMAL_POINT RADIXCHAR\n# define THOUSEP     10002\n# define THOUSANDS_SEP THOUSEP\n# define GROUPING    10114\n/* nl_langinfo items of the LC_TIME category */\n# define D_T_FMT     10003\n# define D_FMT       10004\n# define T_FMT       10005\n# define T_FMT_AMPM  10006\n# define AM_STR      10007\n# define PM_STR      10008\n# define DAY_1       10009\n# define DAY_2       (DAY_1 + 1)\n# define DAY_3       (DAY_1 + 2)\n# define DAY_4       (DAY_1 + 3)\n# define DAY_5       (DAY_1 + 4)\n# define DAY_6       (DAY_1 + 5)\n# define DAY_7       (DAY_1 + 6)\n# define ABDAY_1     10016\n# define ABDAY_2     (ABDAY_1 + 1)\n# define ABDAY_3     (ABDAY_1 + 2)\n# define ABDAY_4     (ABDAY_1 + 3)\n# define ABDAY_5     (ABDAY_1 + 4)\n# define ABDAY_6     (ABDAY_1 + 5)\n# define ABDAY_7     (ABDAY_1 + 6)\n# define MON_1       10023\n# define MON_2       (MON_1 + 1)\n# define MON_3       (MON_1 + 2)\n# define MON_4       (MON_1 + 3)\n# define MON_5       (MON_1 + 4)\n# define MON_6       (MON_1 + 5)\n# define MON_7       (MON_1 + 6)\n# define MON_8       (MON_1 + 7)\n# define MON_9       (MON_1 + 8)\n# define MON_10      (MON_1 + 9)\n# define MON_11      (MON_1 + 10)\n# define MON_12      (MON_1 + 11)\n# define ALTMON_1    10200\n# define ALTMON_2    (ALTMON_1 + 1)\n# define ALTMON_3    (ALTMON_1 + 2)\n# define ALTMON_4    (ALTMON_1 + 3)\n# define ALTMON_5    (ALTMON_1 + 4)\n# define ALTMON_6    (ALTMON_1 + 5)\n# define ALTMON_7    (ALTMON_1 + 6)\n# define ALTMON_8    (ALTMON_1 + 7)\n# define ALTMON_9    (ALTMON_1 + 8)\n# define ALTMON_10   (ALTMON_1 + 9)\n# define ALTMON_11   (ALTMON_1 + 10)\n# define ALTMON_12   (ALTMON_1 + 11)\n# define ABMON_1     10035\n# define ABMON_2     (ABMON_1 + 1)\n# define ABMON_3     (ABMON_1 + 2)\n# define ABMON_4     (ABMON_1 + 3)\n# define ABMON_5     (ABMON_1 + 4)\n# define ABMON_6     (ABMON_1 + 5)\n# define ABMON_7     (ABMON_1 + 6)\n# define ABMON_8     (ABMON_1 + 7)\n# define ABMON_9     (ABMON_1 + 8)\n# define ABMON_10    (ABMON_1 + 9)\n# define ABMON_11    (ABMON_1 + 10)\n# define ABMON_12    (ABMON_1 + 11)\n# define ERA         10047\n# define ERA_D_FMT   10048\n# define ERA_D_T_FMT 10049\n# define ERA_T_FMT   10050\n# define ALT_DIGITS  10051\n/* nl_langinfo items of the LC_MONETARY category */\n# define CRNCYSTR    10052\n# define CURRENCY_SYMBOL   CRNCYSTR\n# define INT_CURR_SYMBOL   10100\n# define MON_DECIMAL_POINT 10101\n# define MON_THOUSANDS_SEP 10102\n# define MON_GROUPING      10103\n# define POSITIVE_SIGN     10104\n# define NEGATIVE_SIGN     10105\n# define FRAC_DIGITS       10106\n# define INT_FRAC_DIGITS   10107\n# define P_CS_PRECEDES     10108\n# define N_CS_PRECEDES     10109\n# define P_SEP_BY_SPACE    10110\n# define N_SEP_BY_SPACE    10111\n# define P_SIGN_POSN       10112\n# define N_SIGN_POSN       10113\n/* nl_langinfo items of the LC_MESSAGES category */\n# define YESEXPR     10053\n# define NOEXPR      10054\n\n#else\n\n/* A platform that has <langinfo.h>.  */\n\n# if !@HAVE_LANGINFO_CODESET@\n#  define CODESET     10000\n#  define GNULIB_defined_CODESET 1\n# endif\n\n# if !@HAVE_LANGINFO_T_FMT_AMPM@\n#  define T_FMT_AMPM  10006\n#  define GNULIB_defined_T_FMT_AMPM 1\n# endif\n\n# if !@HAVE_LANGINFO_ALTMON@\n#  define ALTMON_1    10200\n#  define ALTMON_2    (ALTMON_1 + 1)\n#  define ALTMON_3    (ALTMON_1 + 2)\n#  define ALTMON_4    (ALTMON_1 + 3)\n#  define ALTMON_5    (ALTMON_1 + 4)\n#  define ALTMON_6    (ALTMON_1 + 5)\n#  define ALTMON_7    (ALTMON_1 + 6)\n#  define ALTMON_8    (ALTMON_1 + 7)\n#  define ALTMON_9    (ALTMON_1 + 8)\n#  define ALTMON_10   (ALTMON_1 + 9)\n#  define ALTMON_11   (ALTMON_1 + 10)\n#  define ALTMON_12   (ALTMON_1 + 11)\n#  define GNULIB_defined_ALTMON 1\n# endif\n\n# if !@HAVE_LANGINFO_ERA@\n#  define ERA         10047\n#  define ERA_D_FMT   10048\n#  define ERA_D_T_FMT 10049\n#  define ERA_T_FMT   10050\n#  define ALT_DIGITS  10051\n#  define GNULIB_defined_ERA 1\n# endif\n\n# if !@HAVE_LANGINFO_YESEXPR@\n#  define YESEXPR     10053\n#  define NOEXPR      10054\n#  define GNULIB_defined_YESEXPR 1\n# endif\n\n#endif\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n\n/* Declare overridden functions.  */\n\n\n/* Return a piece of locale dependent information.\n   Note: The difference between nl_langinfo (CODESET) and locale_charset ()\n   is that the latter normalizes the encoding names to GNU conventions.  */\n\n#if @GNULIB_NL_LANGINFO@\n# if @REPLACE_NL_LANGINFO@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef nl_langinfo\n#   define nl_langinfo rpl_nl_langinfo\n#  endif\n_GL_FUNCDECL_RPL (nl_langinfo, char *, (nl_item item));\n_GL_CXXALIAS_RPL (nl_langinfo, char *, (nl_item item));\n# else\n#  if !@HAVE_NL_LANGINFO@\n_GL_FUNCDECL_SYS (nl_langinfo, char *, (nl_item item));\n#  endif\n_GL_CXXALIAS_SYS (nl_langinfo, char *, (nl_item item));\n# endif\n_GL_CXXALIASWARN (nl_langinfo);\n#elif defined GNULIB_POSIXCHECK\n# undef nl_langinfo\n# if HAVE_RAW_DECL_NL_LANGINFO\n_GL_WARN_ON_USE (nl_langinfo, \"nl_langinfo is not portable - \"\n                 \"use gnulib module nl_langinfo for portability\");\n# endif\n#endif\n\n\n#endif /* _@GUARD_PREFIX@_LANGINFO_H */\n#endif /* _@GUARD_PREFIX@_LANGINFO_H */\n"
  },
  {
    "path": "gnulib/lc-charset-dispatch.c",
    "content": "/* Dispatching based on the current locale's character encoding.\n   Copyright (C) 2018-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2018.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include \"lc-charset-dispatch.h\"\n\n#if GNULIB_defined_mbstate_t\n\n# include \"localcharset.h\"\n# include \"streq.h\"\n\n# if GNULIB_WCHAR_SINGLE_LOCALE\n/* When we know that the locale does not change, provide a speedup by\n   caching the value of locale_encoding_classification.  */\n#  define locale_encoding_classification_cached locale_encoding_classification\n# else\n/* By default, don't make assumptions, hence no caching.  */\n#  define locale_encoding_classification_uncached locale_encoding_classification\n# endif\n\n# if GNULIB_WCHAR_SINGLE_LOCALE\nstatic inline\n# endif\nenc_t\nlocale_encoding_classification_uncached (void)\n{\n  const char *encoding = locale_charset ();\n  if (STREQ_OPT (encoding, \"UTF-8\", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0))\n    return enc_utf8;\n  if (STREQ_OPT (encoding, \"EUC-JP\", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0))\n    return enc_eucjp;\n  if (STREQ_OPT (encoding, \"EUC-KR\", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0)\n      || STREQ_OPT (encoding, \"GB2312\", 'G', 'B', '2', '3', '1', '2', 0, 0, 0)\n      || STREQ_OPT (encoding, \"BIG5\", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0))\n    return enc_94;\n  if (STREQ_OPT (encoding, \"EUC-TW\", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0))\n    return enc_euctw;\n  if (STREQ_OPT (encoding, \"GB18030\", 'G', 'B', '1', '8', '0', '3', '0', 0, 0))\n    return enc_gb18030;\n  if (STREQ_OPT (encoding, \"SJIS\", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0))\n    return enc_sjis;\n  return enc_other;\n}\n\n# if GNULIB_WCHAR_SINGLE_LOCALE\n\nstatic int cached_locale_enc = -1;\n\nenc_t\nlocale_encoding_classification_cached (void)\n{\n  if (cached_locale_enc < 0)\n    cached_locale_enc = locale_encoding_classification_uncached ();\n  return cached_locale_enc;\n}\n\n# endif\n\n#else\n\n/* This declaration is solely to ensure that after preprocessing\n   this file is never empty.  */\ntypedef int dummy;\n\n#endif\n"
  },
  {
    "path": "gnulib/lc-charset-dispatch.h",
    "content": "/* Dispatching based on the current locale's character encoding.\n   Copyright (C) 2018-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2018.  */\n\n#include <wchar.h>\n\n#if GNULIB_defined_mbstate_t\n\n/* A classification of special values of the encoding of the current locale.  */\ntypedef enum\n  {\n    enc_other,      /* other */\n    enc_utf8,       /* UTF-8 */\n    enc_eucjp,      /* EUC-JP */\n    enc_94,         /* EUC-KR, GB2312, BIG5 */\n    enc_euctw,      /* EUC-TW */\n    enc_gb18030,    /* GB18030 */\n    enc_sjis        /* SJIS */\n  }\n  enc_t;\n\n/* Returns a classification of special values of the encoding of the current\n   locale.  */\nextern enc_t locale_encoding_classification (void);\n\n#endif\n"
  },
  {
    "path": "gnulib/libc-config.h",
    "content": "/* System definitions for code taken from the GNU C Library\n\n   Copyright 2017-2021 Free Software Foundation, Inc.\n\n   This program is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with this program; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n/* Written by Paul Eggert.  */\n\n/* This is intended to be a good-enough substitute for glibc system\n   macros like those defined in <sys/cdefs.h>, so that Gnulib code\n   shared with glibc can do this as the first #include:\n\n     #ifndef _LIBC\n     # include <libc-config.h>\n     #endif\n\n   When compiled as part of glibc this is a no-op; when compiled as\n   part of Gnulib this includes Gnulib's <config.h> and defines macros\n   that glibc library code would normally assume.\n\n   Note: This header file MUST NOT be included by public header files\n   of Gnulib.  */\n\n#include <config.h>\n\n/* On glibc this includes <features.h> and <sys/cdefs.h> and #defines\n   _FEATURES_H, __WORDSIZE, and __set_errno.  On FreeBSD 11 and\n   DragonFlyBSD 5.9 it includes <sys/cdefs.h> which defines __nonnull.\n   Elsewhere it is harmless.  */\n#include <errno.h>\n\n/* From glibc <errno.h>.  */\n#ifndef __set_errno\n# define __set_errno(val) (errno = (val))\n#endif\n\n/* From glibc <features.h>.  */\n\n#ifndef __GNUC_PREREQ\n# if defined __GNUC__ && defined __GNUC_MINOR__\n#  define __GNUC_PREREQ(maj, min) ((maj) < __GNUC__ + ((min) <= __GNUC_MINOR__))\n# else\n#  define __GNUC_PREREQ(maj, min) 0\n# endif\n#endif\n\n#ifndef __glibc_clang_prereq\n# if defined __clang_major__ && defined __clang_minor__\n#  ifdef __apple_build_version__\n/* Apple for some reason renumbers __clang_major__ and __clang_minor__.\n   Gnulib code uses only __glibc_clang_prereq (3, 5); map it to\n   6000000 <= __apple_build_version__.  Support for other calls to\n   __glibc_clang_prereq can be added here as needed.  */\n#   define __glibc_clang_prereq(maj, min) \\\n      ((maj) == 3 && (min) == 5 ? 6000000 <= __apple_build_version__ : 0)\n#  else\n#   define __glibc_clang_prereq(maj, min) \\\n      ((maj) < __clang_major__ + ((min) <= __clang_minor__))\n#  endif\n# else\n#  define __glibc_clang_prereq(maj, min) 0\n# endif\n#endif\n\n#ifndef __attribute_nonnull__\n/* <sys/cdefs.h> either does not exist, or is too old for Gnulib.\n   Prepare to include <cdefs.h>, which is Gnulib's version of a\n   more-recent glibc <sys/cdefs.h>.  */\n\n/* Define _FEATURES_H so that <cdefs.h> does not include <features.h>.  */\n# ifndef _FEATURES_H\n#  define _FEATURES_H 1\n# endif\n/* Define __GNULIB_CDEFS so that <cdefs.h> does not attempt to include\n   nonexistent files.  */\n# define __GNULIB_CDEFS\n/* Undef the macros unconditionally defined by our copy of glibc\n   <sys/cdefs.h>, so that they do not clash with any system-defined\n   versions.  */\n# undef _SYS_CDEFS_H\n# undef __ASMNAME\n# undef __ASMNAME2\n# undef __BEGIN_DECLS\n# undef __CONCAT\n# undef __END_DECLS\n# undef __HAVE_GENERIC_SELECTION\n# undef __LDBL_COMPAT\n# undef __LDBL_REDIR\n# undef __LDBL_REDIR1\n# undef __LDBL_REDIR1_DECL\n# undef __LDBL_REDIR1_NTH\n# undef __LDBL_REDIR2_DECL\n# undef __LDBL_REDIR_DECL\n# undef __LDBL_REDIR_NTH\n# undef __LEAF\n# undef __LEAF_ATTR\n# undef __NTH\n# undef __NTHNL\n# undef __REDIRECT\n# undef __REDIRECT_LDBL\n# undef __REDIRECT_NTH\n# undef __REDIRECT_NTHNL\n# undef __REDIRECT_NTH_LDBL\n# undef __STRING\n# undef __THROW\n# undef __THROWNL\n# undef __attr_access\n# undef __attribute__\n# undef __attribute_alloc_size__\n# undef __attribute_artificial__\n# undef __attribute_const__\n# undef __attribute_deprecated__\n# undef __attribute_deprecated_msg__\n# undef __attribute_format_arg__\n# undef __attribute_format_strfmon__\n# undef __attribute_malloc__\n# undef __attribute_noinline__\n# undef __attribute_nonstring__\n# undef __attribute_pure__\n# undef __attribute_returns_twice__\n# undef __attribute_used__\n# undef __attribute_warn_unused_result__\n# undef __bos\n# undef __bos0\n# undef __errordecl\n# undef __extension__\n# undef __extern_always_inline\n# undef __extern_inline\n# undef __flexarr\n# undef __fortify_function\n# undef __glibc_c99_flexarr_available\n# undef __glibc_has_attribute\n# undef __glibc_has_builtin\n# undef __glibc_has_extension\n# undef __glibc_macro_warning\n# undef __glibc_macro_warning1\n# undef __glibc_objsize\n# undef __glibc_objsize0\n# undef __glibc_unlikely\n# undef __inline\n# undef __ptr_t\n# undef __restrict\n# undef __restrict_arr\n# undef __va_arg_pack\n# undef __va_arg_pack_len\n# undef __warnattr\n\n/* Include our copy of glibc <sys/cdefs.h>.  */\n# include <cdefs.h>\n\n/* <cdefs.h> __inline is too pessimistic for non-GCC.  */\n# undef __inline\n# ifndef HAVE___INLINE\n#  if 199901 <= __STDC_VERSION__ || defined inline\n#   define __inline inline\n#  else\n#   define __inline\n#  endif\n# endif\n\n#endif /* defined __glibc_likely */\n\n\n/* A substitute for glibc <libc-symbols.h>, good enough for Gnulib.  */\n#define attribute_hidden\n#define libc_hidden_proto(name)\n#define libc_hidden_def(name)\n#define libc_hidden_weak(name)\n#define libc_hidden_ver(local, name)\n#define strong_alias(name, aliasname)\n#define weak_alias(name, aliasname)\n\n/* A substitute for glibc <shlib-compat.h>, good enough for Gnulib.  */\n#define SHLIB_COMPAT(lib, introduced, obsoleted) 0\n#define compat_symbol(lib, local, symbol, version) extern int dummy\n#define versioned_symbol(lib, local, symbol, version) extern int dummy\n"
  },
  {
    "path": "gnulib/limits.in.h",
    "content": "/* A GNU-like <limits.h>.\n\n   Copyright 2016-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n#if defined _GL_ALREADY_INCLUDING_LIMITS_H\n/* Special invocation convention:\n   On Haiku/x86_64, we have a sequence of nested includes\n   <limits.h> -> <syslimits.h> -> <limits.h>.\n   In this situation, LONG_MAX and INT_MAX are not yet defined,\n   therefore we should not attempt to define LONG_BIT.  */\n\n#@INCLUDE_NEXT@ @NEXT_LIMITS_H@\n\n#else\n/* Normal invocation convention.  */\n\n#ifndef _@GUARD_PREFIX@_LIMITS_H\n\n# define _GL_ALREADY_INCLUDING_LIMITS_H\n\n/* The include_next requires a split double-inclusion guard.  */\n# @INCLUDE_NEXT@ @NEXT_LIMITS_H@\n\n# undef _GL_ALREADY_INCLUDING_LIMITS_H\n\n#ifndef _@GUARD_PREFIX@_LIMITS_H\n#define _@GUARD_PREFIX@_LIMITS_H\n\n#ifndef LLONG_MIN\n# if defined LONG_LONG_MIN /* HP-UX 11.31 */\n#  define LLONG_MIN LONG_LONG_MIN\n# elif defined LONGLONG_MIN /* IRIX 6.5 */\n#  define LLONG_MIN LONGLONG_MIN\n# elif defined __GNUC__\n#  define LLONG_MIN (- __LONG_LONG_MAX__ - 1LL)\n# endif\n#endif\n#ifndef LLONG_MAX\n# if defined LONG_LONG_MAX /* HP-UX 11.31 */\n#  define LLONG_MAX LONG_LONG_MAX\n# elif defined LONGLONG_MAX /* IRIX 6.5 */\n#  define LLONG_MAX LONGLONG_MAX\n# elif defined __GNUC__\n#  define LLONG_MAX __LONG_LONG_MAX__\n# endif\n#endif\n#ifndef ULLONG_MAX\n# if defined ULONG_LONG_MAX /* HP-UX 11.31 */\n#  define ULLONG_MAX ULONG_LONG_MAX\n# elif defined ULONGLONG_MAX /* IRIX 6.5 */\n#  define ULLONG_MAX ULONGLONG_MAX\n# elif defined __GNUC__\n#  define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL)\n# endif\n#endif\n\n/* The number of usable bits in an unsigned or signed integer type\n   with minimum value MIN and maximum value MAX, as an int expression\n   suitable in #if.  Cover all known practical hosts.  This\n   implementation exploits the fact that MAX is 1 less than a power of\n   2, and merely counts the number of 1 bits in MAX; \"COBn\" means\n   \"count the number of 1 bits in the low-order n bits\").  */\n#define _GL_INTEGER_WIDTH(min, max) (((min) < 0) + _GL_COB128 (max))\n#define _GL_COB128(n) (_GL_COB64 ((n) >> 31 >> 31 >> 2) + _GL_COB64 (n))\n#define _GL_COB64(n) (_GL_COB32 ((n) >> 31 >> 1) + _GL_COB32 (n))\n#define _GL_COB32(n) (_GL_COB16 ((n) >> 16) + _GL_COB16 (n))\n#define _GL_COB16(n) (_GL_COB8 ((n) >> 8) + _GL_COB8 (n))\n#define _GL_COB8(n) (_GL_COB4 ((n) >> 4) + _GL_COB4 (n))\n#define _GL_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + !!((n) & 1))\n\n#ifndef WORD_BIT\n/* Assume 'int' is 32 bits wide.  */\n# define WORD_BIT 32\n#endif\n#ifndef LONG_BIT\n/* Assume 'long' is 32 or 64 bits wide.  */\n# if LONG_MAX == INT_MAX\n#  define LONG_BIT 32\n# else\n#  define LONG_BIT 64\n# endif\n#endif\n\n/* Macros specified by ISO/IEC TS 18661-1:2014.  */\n\n#if (! defined ULLONG_WIDTH                                             \\\n     && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__))\n# define CHAR_WIDTH _GL_INTEGER_WIDTH (CHAR_MIN, CHAR_MAX)\n# define SCHAR_WIDTH _GL_INTEGER_WIDTH (SCHAR_MIN, SCHAR_MAX)\n# define UCHAR_WIDTH _GL_INTEGER_WIDTH (0, UCHAR_MAX)\n# define SHRT_WIDTH _GL_INTEGER_WIDTH (SHRT_MIN, SHRT_MAX)\n# define USHRT_WIDTH _GL_INTEGER_WIDTH (0, USHRT_MAX)\n# define INT_WIDTH _GL_INTEGER_WIDTH (INT_MIN, INT_MAX)\n# define UINT_WIDTH _GL_INTEGER_WIDTH (0, UINT_MAX)\n# define LONG_WIDTH _GL_INTEGER_WIDTH (LONG_MIN, LONG_MAX)\n# define ULONG_WIDTH _GL_INTEGER_WIDTH (0, ULONG_MAX)\n# define LLONG_WIDTH _GL_INTEGER_WIDTH (LLONG_MIN, LLONG_MAX)\n# define ULLONG_WIDTH _GL_INTEGER_WIDTH (0, ULLONG_MAX)\n#endif /* !ULLONG_WIDTH && (_GNU_SOURCE || __STDC_WANT_IEC_60559_BFP_EXT__) */\n\n#endif /* _@GUARD_PREFIX@_LIMITS_H */\n#endif /* _@GUARD_PREFIX@_LIMITS_H */\n#endif\n"
  },
  {
    "path": "gnulib/localcharset.c",
    "content": "/* Determine a canonical name for the current locale's character encoding.\n\n   Copyright (C) 2000-2006, 2008-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include \"localcharset.h\"\n\n#include <stddef.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n\n#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET\n# define DARWIN7 /* Darwin 7 or newer, i.e. Mac OS X 10.3 or newer */\n#endif\n\n#if defined _WIN32 && !defined __CYGWIN__\n# define WINDOWS_NATIVE\n# include <locale.h>\n#endif\n\n#if defined __EMX__\n/* Assume EMX program runs on OS/2, even if compiled under DOS.  */\n# ifndef OS2\n#  define OS2\n# endif\n#endif\n\n#if !defined WINDOWS_NATIVE\n# if HAVE_LANGINFO_CODESET\n#  include <langinfo.h>\n# else\n#  if 0 /* see comment regarding use of setlocale(), below */\n#   include <locale.h>\n#  endif\n# endif\n# ifdef __CYGWIN__\n#  define WIN32_LEAN_AND_MEAN\n#  include <windows.h>\n# endif\n#elif defined WINDOWS_NATIVE\n# define WIN32_LEAN_AND_MEAN\n# include <windows.h>\n  /* For the use of setlocale() below, the Gnulib override in setlocale.c is\n     not needed; see the platform lists in setlocale_null.m4.  */\n# undef setlocale\n#endif\n#if defined OS2\n# define INCL_DOS\n# include <os2.h>\n#endif\n\n/* For MB_CUR_MAX_L */\n#if defined DARWIN7\n# include <xlocale.h>\n#endif\n\n\n#if HAVE_LANGINFO_CODESET || defined WINDOWS_NATIVE || defined OS2\n\n/* On these platforms, we use a mapping from non-canonical encoding name\n   to GNU canonical encoding name.  */\n\n/* With glibc-2.1 or newer, we don't need any canonicalization,\n   because glibc has iconv and both glibc and libiconv support all\n   GNU canonical names directly.  */\n# if !((defined __GNU_LIBRARY__ && __GLIBC__ >= 2) || defined __UCLIBC__)\n\nstruct table_entry\n{\n  const char alias[11+1];\n  const char canonical[11+1];\n};\n\n/* Table of platform-dependent mappings, sorted in ascending order.  */\nstatic const struct table_entry alias_table[] =\n  {\n#  if defined __FreeBSD__                                   /* FreeBSD */\n  /*{ \"ARMSCII-8\",  \"ARMSCII-8\" },*/\n    { \"Big5\",       \"BIG5\" },\n    { \"C\",          \"ASCII\" },\n  /*{ \"CP1131\",     \"CP1131\" },*/\n  /*{ \"CP1251\",     \"CP1251\" },*/\n  /*{ \"CP866\",      \"CP866\" },*/\n  /*{ \"GB18030\",    \"GB18030\" },*/\n  /*{ \"GB2312\",     \"GB2312\" },*/\n  /*{ \"GBK\",        \"GBK\" },*/\n  /*{ \"ISCII-DEV\",  \"?\" },*/\n    { \"ISO8859-1\",  \"ISO-8859-1\" },\n    { \"ISO8859-13\", \"ISO-8859-13\" },\n    { \"ISO8859-15\", \"ISO-8859-15\" },\n    { \"ISO8859-2\",  \"ISO-8859-2\" },\n    { \"ISO8859-5\",  \"ISO-8859-5\" },\n    { \"ISO8859-7\",  \"ISO-8859-7\" },\n    { \"ISO8859-9\",  \"ISO-8859-9\" },\n  /*{ \"KOI8-R\",     \"KOI8-R\" },*/\n  /*{ \"KOI8-U\",     \"KOI8-U\" },*/\n    { \"SJIS\",       \"SHIFT_JIS\" },\n    { \"US-ASCII\",   \"ASCII\" },\n    { \"eucCN\",      \"GB2312\" },\n    { \"eucJP\",      \"EUC-JP\" },\n    { \"eucKR\",      \"EUC-KR\" }\n#   define alias_table_defined\n#  endif\n#  if defined __NetBSD__                                    /* NetBSD */\n    { \"646\",        \"ASCII\" },\n  /*{ \"ARMSCII-8\",  \"ARMSCII-8\" },*/\n  /*{ \"BIG5\",       \"BIG5\" },*/\n    { \"Big5-HKSCS\", \"BIG5-HKSCS\" },\n  /*{ \"CP1251\",     \"CP1251\" },*/\n  /*{ \"CP866\",      \"CP866\" },*/\n  /*{ \"GB18030\",    \"GB18030\" },*/\n  /*{ \"GB2312\",     \"GB2312\" },*/\n    { \"ISO8859-1\",  \"ISO-8859-1\" },\n    { \"ISO8859-13\", \"ISO-8859-13\" },\n    { \"ISO8859-15\", \"ISO-8859-15\" },\n    { \"ISO8859-2\",  \"ISO-8859-2\" },\n    { \"ISO8859-4\",  \"ISO-8859-4\" },\n    { \"ISO8859-5\",  \"ISO-8859-5\" },\n    { \"ISO8859-7\",  \"ISO-8859-7\" },\n  /*{ \"KOI8-R\",     \"KOI8-R\" },*/\n  /*{ \"KOI8-U\",     \"KOI8-U\" },*/\n  /*{ \"PT154\",      \"PT154\" },*/\n    { \"SJIS\",       \"SHIFT_JIS\" },\n    { \"eucCN\",      \"GB2312\" },\n    { \"eucJP\",      \"EUC-JP\" },\n    { \"eucKR\",      \"EUC-KR\" },\n    { \"eucTW\",      \"EUC-TW\" }\n#   define alias_table_defined\n#  endif\n#  if defined __OpenBSD__                                   /* OpenBSD */\n    { \"646\",        \"ASCII\" },\n    { \"ISO8859-1\",  \"ISO-8859-1\" },\n    { \"ISO8859-13\", \"ISO-8859-13\" },\n    { \"ISO8859-15\", \"ISO-8859-15\" },\n    { \"ISO8859-2\",  \"ISO-8859-2\" },\n    { \"ISO8859-4\",  \"ISO-8859-4\" },\n    { \"ISO8859-5\",  \"ISO-8859-5\" },\n    { \"ISO8859-7\",  \"ISO-8859-7\" },\n    { \"US-ASCII\",   \"ASCII\" }\n#   define alias_table_defined\n#  endif\n#  if defined __APPLE__ && defined __MACH__                 /* Mac OS X */\n    /* Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is\n       useless:\n       - It returns the empty string when LANG is set to a locale of the\n         form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8\n         LC_CTYPE file.\n       - The environment variables LANG, LC_CTYPE, LC_ALL are not set by\n         the system; nl_langinfo(CODESET) returns \"US-ASCII\" in this case.\n       - The documentation says:\n           \"... all code that calls BSD system routines should ensure\n            that the const *char parameters of these routines are in UTF-8\n            encoding. All BSD system functions expect their string\n            parameters to be in UTF-8 encoding and nothing else.\"\n         It also says\n           \"An additional caveat is that string parameters for files,\n            paths, and other file-system entities must be in canonical\n            UTF-8. In a canonical UTF-8 Unicode string, all decomposable\n            characters are decomposed ...\"\n         but this is not true: You can pass non-decomposed UTF-8 strings\n         to file system functions, and it is the OS which will convert\n         them to decomposed UTF-8 before accessing the file system.\n       - The Apple Terminal application displays UTF-8 by default.\n       - However, other applications are free to use different encodings:\n         - xterm uses ISO-8859-1 by default.\n         - TextEdit uses MacRoman by default.\n       We prefer UTF-8 over decomposed UTF-8-MAC because one should\n       minimize the use of decomposed Unicode. Unfortunately, through the\n       Darwin file system, decomposed UTF-8 strings are leaked into user\n       space nevertheless.\n       Then there are also the locales with encodings other than US-ASCII\n       and UTF-8. These locales can be occasionally useful to users (e.g.\n       when grepping through ISO-8859-1 encoded text files), when all their\n       file names are in US-ASCII.\n     */\n    { \"ARMSCII-8\",  \"ARMSCII-8\" },\n    { \"Big5\",       \"BIG5\" },\n    { \"Big5HKSCS\",  \"BIG5-HKSCS\" },\n    { \"CP1131\",     \"CP1131\" },\n    { \"CP1251\",     \"CP1251\" },\n    { \"CP866\",      \"CP866\" },\n    { \"CP949\",      \"CP949\" },\n    { \"GB18030\",    \"GB18030\" },\n    { \"GB2312\",     \"GB2312\" },\n    { \"GBK\",        \"GBK\" },\n  /*{ \"ISCII-DEV\",  \"?\" },*/\n    { \"ISO8859-1\",  \"ISO-8859-1\" },\n    { \"ISO8859-13\", \"ISO-8859-13\" },\n    { \"ISO8859-15\", \"ISO-8859-15\" },\n    { \"ISO8859-2\",  \"ISO-8859-2\" },\n    { \"ISO8859-4\",  \"ISO-8859-4\" },\n    { \"ISO8859-5\",  \"ISO-8859-5\" },\n    { \"ISO8859-7\",  \"ISO-8859-7\" },\n    { \"ISO8859-9\",  \"ISO-8859-9\" },\n    { \"KOI8-R\",     \"KOI8-R\" },\n    { \"KOI8-U\",     \"KOI8-U\" },\n    { \"PT154\",      \"PT154\" },\n    { \"SJIS\",       \"SHIFT_JIS\" },\n    { \"eucCN\",      \"GB2312\" },\n    { \"eucJP\",      \"EUC-JP\" },\n    { \"eucKR\",      \"EUC-KR\" }\n#   define alias_table_defined\n#  endif\n#  if defined _AIX                                          /* AIX */\n  /*{ \"GBK\",        \"GBK\" },*/\n    { \"IBM-1046\",   \"CP1046\" },\n    { \"IBM-1124\",   \"CP1124\" },\n    { \"IBM-1129\",   \"CP1129\" },\n    { \"IBM-1252\",   \"CP1252\" },\n    { \"IBM-850\",    \"CP850\" },\n    { \"IBM-856\",    \"CP856\" },\n    { \"IBM-921\",    \"ISO-8859-13\" },\n    { \"IBM-922\",    \"CP922\" },\n    { \"IBM-932\",    \"CP932\" },\n    { \"IBM-943\",    \"CP943\" },\n    { \"IBM-eucCN\",  \"GB2312\" },\n    { \"IBM-eucJP\",  \"EUC-JP\" },\n    { \"IBM-eucKR\",  \"EUC-KR\" },\n    { \"IBM-eucTW\",  \"EUC-TW\" },\n    { \"ISO8859-1\",  \"ISO-8859-1\" },\n    { \"ISO8859-15\", \"ISO-8859-15\" },\n    { \"ISO8859-2\",  \"ISO-8859-2\" },\n    { \"ISO8859-5\",  \"ISO-8859-5\" },\n    { \"ISO8859-6\",  \"ISO-8859-6\" },\n    { \"ISO8859-7\",  \"ISO-8859-7\" },\n    { \"ISO8859-8\",  \"ISO-8859-8\" },\n    { \"ISO8859-9\",  \"ISO-8859-9\" },\n    { \"TIS-620\",    \"TIS-620\" },\n  /*{ \"UTF-8\",      \"UTF-8\" },*/\n    { \"big5\",       \"BIG5\" }\n#   define alias_table_defined\n#  endif\n#  if defined __hpux                                        /* HP-UX */\n    { \"SJIS\",      \"SHIFT_JIS\" },\n    { \"arabic8\",   \"HP-ARABIC8\" },\n    { \"big5\",      \"BIG5\" },\n    { \"cp1251\",    \"CP1251\" },\n    { \"eucJP\",     \"EUC-JP\" },\n    { \"eucKR\",     \"EUC-KR\" },\n    { \"eucTW\",     \"EUC-TW\" },\n    { \"gb18030\",   \"GB18030\" },\n    { \"greek8\",    \"HP-GREEK8\" },\n    { \"hebrew8\",   \"HP-HEBREW8\" },\n    { \"hkbig5\",    \"BIG5-HKSCS\" },\n    { \"hp15CN\",    \"GB2312\" },\n    { \"iso88591\",  \"ISO-8859-1\" },\n    { \"iso885913\", \"ISO-8859-13\" },\n    { \"iso885915\", \"ISO-8859-15\" },\n    { \"iso88592\",  \"ISO-8859-2\" },\n    { \"iso88594\",  \"ISO-8859-4\" },\n    { \"iso88595\",  \"ISO-8859-5\" },\n    { \"iso88596\",  \"ISO-8859-6\" },\n    { \"iso88597\",  \"ISO-8859-7\" },\n    { \"iso88598\",  \"ISO-8859-8\" },\n    { \"iso88599\",  \"ISO-8859-9\" },\n    { \"kana8\",     \"HP-KANA8\" },\n    { \"koi8r\",     \"KOI8-R\" },\n    { \"roman8\",    \"HP-ROMAN8\" },\n    { \"tis620\",    \"TIS-620\" },\n    { \"turkish8\",  \"HP-TURKISH8\" },\n    { \"utf8\",      \"UTF-8\" }\n#   define alias_table_defined\n#  endif\n#  if defined __sgi                                         /* IRIX */\n    { \"ISO8859-1\",  \"ISO-8859-1\" },\n    { \"ISO8859-15\", \"ISO-8859-15\" },\n    { \"ISO8859-2\",  \"ISO-8859-2\" },\n    { \"ISO8859-5\",  \"ISO-8859-5\" },\n    { \"ISO8859-7\",  \"ISO-8859-7\" },\n    { \"ISO8859-9\",  \"ISO-8859-9\" },\n    { \"eucCN\",      \"GB2312\" },\n    { \"eucJP\",      \"EUC-JP\" },\n    { \"eucKR\",      \"EUC-KR\" },\n    { \"eucTW\",      \"EUC-TW\" }\n#   define alias_table_defined\n#  endif\n#  if defined __osf__                                       /* OSF/1 */\n  /*{ \"GBK\",        \"GBK\" },*/\n    { \"ISO8859-1\",  \"ISO-8859-1\" },\n    { \"ISO8859-15\", \"ISO-8859-15\" },\n    { \"ISO8859-2\",  \"ISO-8859-2\" },\n    { \"ISO8859-4\",  \"ISO-8859-4\" },\n    { \"ISO8859-5\",  \"ISO-8859-5\" },\n    { \"ISO8859-7\",  \"ISO-8859-7\" },\n    { \"ISO8859-8\",  \"ISO-8859-8\" },\n    { \"ISO8859-9\",  \"ISO-8859-9\" },\n    { \"KSC5601\",    \"CP949\" },\n    { \"SJIS\",       \"SHIFT_JIS\" },\n    { \"TACTIS\",     \"TIS-620\" },\n  /*{ \"UTF-8\",      \"UTF-8\" },*/\n    { \"big5\",       \"BIG5\" },\n    { \"cp850\",      \"CP850\" },\n    { \"dechanyu\",   \"DEC-HANYU\" },\n    { \"dechanzi\",   \"GB2312\" },\n    { \"deckanji\",   \"DEC-KANJI\" },\n    { \"deckorean\",  \"EUC-KR\" },\n    { \"eucJP\",      \"EUC-JP\" },\n    { \"eucKR\",      \"EUC-KR\" },\n    { \"eucTW\",      \"EUC-TW\" },\n    { \"sdeckanji\",  \"EUC-JP\" }\n#   define alias_table_defined\n#  endif\n#  if defined __sun                                         /* Solaris */\n    { \"5601\",        \"EUC-KR\" },\n    { \"646\",         \"ASCII\" },\n  /*{ \"BIG5\",        \"BIG5\" },*/\n    { \"Big5-HKSCS\",  \"BIG5-HKSCS\" },\n    { \"GB18030\",     \"GB18030\" },\n  /*{ \"GBK\",         \"GBK\" },*/\n    { \"ISO8859-1\",   \"ISO-8859-1\" },\n    { \"ISO8859-11\",  \"TIS-620\" },\n    { \"ISO8859-13\",  \"ISO-8859-13\" },\n    { \"ISO8859-15\",  \"ISO-8859-15\" },\n    { \"ISO8859-2\",   \"ISO-8859-2\" },\n    { \"ISO8859-3\",   \"ISO-8859-3\" },\n    { \"ISO8859-4\",   \"ISO-8859-4\" },\n    { \"ISO8859-5\",   \"ISO-8859-5\" },\n    { \"ISO8859-6\",   \"ISO-8859-6\" },\n    { \"ISO8859-7\",   \"ISO-8859-7\" },\n    { \"ISO8859-8\",   \"ISO-8859-8\" },\n    { \"ISO8859-9\",   \"ISO-8859-9\" },\n    { \"PCK\",         \"SHIFT_JIS\" },\n    { \"TIS620.2533\", \"TIS-620\" },\n  /*{ \"UTF-8\",       \"UTF-8\" },*/\n    { \"ansi-1251\",   \"CP1251\" },\n    { \"cns11643\",    \"EUC-TW\" },\n    { \"eucJP\",       \"EUC-JP\" },\n    { \"gb2312\",      \"GB2312\" },\n    { \"koi8-r\",      \"KOI8-R\" }\n#   define alias_table_defined\n#  endif\n#  if defined __minix                                       /* Minix */\n    { \"646\", \"ASCII\" }\n#   define alias_table_defined\n#  endif\n#  if defined WINDOWS_NATIVE || defined __CYGWIN__          /* Windows */\n    { \"CP1361\",  \"JOHAB\" },\n    { \"CP20127\", \"ASCII\" },\n    { \"CP20866\", \"KOI8-R\" },\n    { \"CP20936\", \"GB2312\" },\n    { \"CP21866\", \"KOI8-RU\" },\n    { \"CP28591\", \"ISO-8859-1\" },\n    { \"CP28592\", \"ISO-8859-2\" },\n    { \"CP28593\", \"ISO-8859-3\" },\n    { \"CP28594\", \"ISO-8859-4\" },\n    { \"CP28595\", \"ISO-8859-5\" },\n    { \"CP28596\", \"ISO-8859-6\" },\n    { \"CP28597\", \"ISO-8859-7\" },\n    { \"CP28598\", \"ISO-8859-8\" },\n    { \"CP28599\", \"ISO-8859-9\" },\n    { \"CP28605\", \"ISO-8859-15\" },\n    { \"CP38598\", \"ISO-8859-8\" },\n    { \"CP51932\", \"EUC-JP\" },\n    { \"CP51936\", \"GB2312\" },\n    { \"CP51949\", \"EUC-KR\" },\n    { \"CP51950\", \"EUC-TW\" },\n    { \"CP54936\", \"GB18030\" },\n    { \"CP65001\", \"UTF-8\" },\n    { \"CP936\",   \"GBK\" }\n#   define alias_table_defined\n#  endif\n#  if defined OS2                                           /* OS/2 */\n    /* The list of encodings is taken from \"List of OS/2 Codepages\"\n       by Alex Taylor:\n       <http://altsan.org/os2/toolkits/uls/index.html#codepages>.\n       See also \"__convcp() of kLIBC\":\n       <https://github.com/bitwiseworks/libc/blob/master/src/emx/src/lib/locale/__convcp.c>.  */\n    { \"CP1004\",        \"CP1252\" },\n  /*{ \"CP1041\",        \"CP943\" },*/\n  /*{ \"CP1088\",        \"CP949\" },*/\n    { \"CP1089\",        \"ISO-8859-6\" },\n  /*{ \"CP1114\",        \"CP950\" },*/\n  /*{ \"CP1115\",        \"GB2312\" },*/\n    { \"CP1208\",        \"UTF-8\" },\n  /*{ \"CP1380\",        \"GB2312\" },*/\n    { \"CP1381\",        \"GB2312\" },\n    { \"CP1383\",        \"GB2312\" },\n    { \"CP1386\",        \"GBK\" },\n  /*{ \"CP301\",         \"CP943\" },*/\n    { \"CP3372\",        \"EUC-JP\" },\n    { \"CP4946\",        \"CP850\" },\n  /*{ \"CP5048\",        \"JIS_X0208-1990\" },*/\n  /*{ \"CP5049\",        \"JIS_X0212-1990\" },*/\n  /*{ \"CP5067\",        \"KS_C_5601-1987\" },*/\n    { \"CP813\",         \"ISO-8859-7\" },\n    { \"CP819\",         \"ISO-8859-1\" },\n    { \"CP878\",         \"KOI8-R\" },\n  /*{ \"CP897\",         \"CP943\" },*/\n    { \"CP912\",         \"ISO-8859-2\" },\n    { \"CP913\",         \"ISO-8859-3\" },\n    { \"CP914\",         \"ISO-8859-4\" },\n    { \"CP915\",         \"ISO-8859-5\" },\n    { \"CP916\",         \"ISO-8859-8\" },\n    { \"CP920\",         \"ISO-8859-9\" },\n    { \"CP921\",         \"ISO-8859-13\" },\n    { \"CP923\",         \"ISO-8859-15\" },\n  /*{ \"CP941\",         \"CP943\" },*/\n  /*{ \"CP947\",         \"CP950\" },*/\n  /*{ \"CP951\",         \"CP949\" },*/\n  /*{ \"CP952\",         \"JIS_X0208-1990\" },*/\n  /*{ \"CP953\",         \"JIS_X0212-1990\" },*/\n    { \"CP954\",         \"EUC-JP\" },\n    { \"CP964\",         \"EUC-TW\" },\n    { \"CP970\",         \"EUC-KR\" },\n  /*{ \"CP971\",         \"KS_C_5601-1987\" },*/\n    { \"IBM-1004\",      \"CP1252\" },\n  /*{ \"IBM-1006\",      \"?\" },*/\n  /*{ \"IBM-1008\",      \"?\" },*/\n  /*{ \"IBM-1041\",      \"CP943\" },*/\n  /*{ \"IBM-1051\",      \"?\" },*/\n  /*{ \"IBM-1088\",      \"CP949\" },*/\n    { \"IBM-1089\",      \"ISO-8859-6\" },\n  /*{ \"IBM-1098\",      \"?\" },*/\n  /*{ \"IBM-1114\",      \"CP950\" },*/\n  /*{ \"IBM-1115\",      \"GB2312\" },*/\n  /*{ \"IBM-1116\",      \"?\" },*/\n  /*{ \"IBM-1117\",      \"?\" },*/\n  /*{ \"IBM-1118\",      \"?\" },*/\n  /*{ \"IBM-1119\",      \"?\" },*/\n    { \"IBM-1124\",      \"CP1124\" },\n    { \"IBM-1125\",      \"CP1125\" },\n    { \"IBM-1131\",      \"CP1131\" },\n    { \"IBM-1208\",      \"UTF-8\" },\n    { \"IBM-1250\",      \"CP1250\" },\n    { \"IBM-1251\",      \"CP1251\" },\n    { \"IBM-1252\",      \"CP1252\" },\n    { \"IBM-1253\",      \"CP1253\" },\n    { \"IBM-1254\",      \"CP1254\" },\n    { \"IBM-1255\",      \"CP1255\" },\n    { \"IBM-1256\",      \"CP1256\" },\n    { \"IBM-1257\",      \"CP1257\" },\n  /*{ \"IBM-1275\",      \"?\" },*/\n  /*{ \"IBM-1276\",      \"?\" },*/\n  /*{ \"IBM-1277\",      \"?\" },*/\n  /*{ \"IBM-1280\",      \"?\" },*/\n  /*{ \"IBM-1281\",      \"?\" },*/\n  /*{ \"IBM-1282\",      \"?\" },*/\n  /*{ \"IBM-1283\",      \"?\" },*/\n  /*{ \"IBM-1380\",      \"GB2312\" },*/\n    { \"IBM-1381\",      \"GB2312\" },\n    { \"IBM-1383\",      \"GB2312\" },\n    { \"IBM-1386\",      \"GBK\" },\n  /*{ \"IBM-301\",       \"CP943\" },*/\n    { \"IBM-3372\",      \"EUC-JP\" },\n    { \"IBM-367\",       \"ASCII\" },\n    { \"IBM-437\",       \"CP437\" },\n    { \"IBM-4946\",      \"CP850\" },\n  /*{ \"IBM-5048\",      \"JIS_X0208-1990\" },*/\n  /*{ \"IBM-5049\",      \"JIS_X0212-1990\" },*/\n  /*{ \"IBM-5067\",      \"KS_C_5601-1987\" },*/\n    { \"IBM-813\",       \"ISO-8859-7\" },\n    { \"IBM-819\",       \"ISO-8859-1\" },\n    { \"IBM-850\",       \"CP850\" },\n  /*{ \"IBM-851\",       \"?\" },*/\n    { \"IBM-852\",       \"CP852\" },\n    { \"IBM-855\",       \"CP855\" },\n    { \"IBM-856\",       \"CP856\" },\n    { \"IBM-857\",       \"CP857\" },\n  /*{ \"IBM-859\",       \"?\" },*/\n    { \"IBM-860\",       \"CP860\" },\n    { \"IBM-861\",       \"CP861\" },\n    { \"IBM-862\",       \"CP862\" },\n    { \"IBM-863\",       \"CP863\" },\n    { \"IBM-864\",       \"CP864\" },\n    { \"IBM-865\",       \"CP865\" },\n    { \"IBM-866\",       \"CP866\" },\n  /*{ \"IBM-868\",       \"?\" },*/\n    { \"IBM-869\",       \"CP869\" },\n    { \"IBM-874\",       \"CP874\" },\n    { \"IBM-878\",       \"KOI8-R\" },\n  /*{ \"IBM-895\",       \"?\" },*/\n  /*{ \"IBM-897\",       \"CP943\" },*/\n  /*{ \"IBM-907\",       \"?\" },*/\n  /*{ \"IBM-909\",       \"?\" },*/\n    { \"IBM-912\",       \"ISO-8859-2\" },\n    { \"IBM-913\",       \"ISO-8859-3\" },\n    { \"IBM-914\",       \"ISO-8859-4\" },\n    { \"IBM-915\",       \"ISO-8859-5\" },\n    { \"IBM-916\",       \"ISO-8859-8\" },\n    { \"IBM-920\",       \"ISO-8859-9\" },\n    { \"IBM-921\",       \"ISO-8859-13\" },\n    { \"IBM-922\",       \"CP922\" },\n    { \"IBM-923\",       \"ISO-8859-15\" },\n    { \"IBM-932\",       \"CP932\" },\n  /*{ \"IBM-941\",       \"CP943\" },*/\n  /*{ \"IBM-942\",       \"?\" },*/\n    { \"IBM-943\",       \"CP943\" },\n  /*{ \"IBM-947\",       \"CP950\" },*/\n    { \"IBM-949\",       \"CP949\" },\n    { \"IBM-950\",       \"CP950\" },\n  /*{ \"IBM-951\",       \"CP949\" },*/\n  /*{ \"IBM-952\",       \"JIS_X0208-1990\" },*/\n  /*{ \"IBM-953\",       \"JIS_X0212-1990\" },*/\n    { \"IBM-954\",       \"EUC-JP\" },\n  /*{ \"IBM-955\",       \"?\" },*/\n    { \"IBM-964\",       \"EUC-TW\" },\n    { \"IBM-970\",       \"EUC-KR\" },\n  /*{ \"IBM-971\",       \"KS_C_5601-1987\" },*/\n    { \"IBM-eucCN\",     \"GB2312\" },\n    { \"IBM-eucJP\",     \"EUC-JP\" },\n    { \"IBM-eucKR\",     \"EUC-KR\" },\n    { \"IBM-eucTW\",     \"EUC-TW\" },\n    { \"IBM33722\",      \"EUC-JP\" },\n    { \"ISO8859-1\",     \"ISO-8859-1\" },\n    { \"ISO8859-2\",     \"ISO-8859-2\" },\n    { \"ISO8859-3\",     \"ISO-8859-3\" },\n    { \"ISO8859-4\",     \"ISO-8859-4\" },\n    { \"ISO8859-5\",     \"ISO-8859-5\" },\n    { \"ISO8859-6\",     \"ISO-8859-6\" },\n    { \"ISO8859-7\",     \"ISO-8859-7\" },\n    { \"ISO8859-8\",     \"ISO-8859-8\" },\n    { \"ISO8859-9\",     \"ISO-8859-9\" },\n  /*{ \"JISX0201-1976\", \"JISX0201-1976\" },*/\n  /*{ \"JISX0208-1978\", \"?\" },*/\n  /*{ \"JISX0208-1983\", \"JIS_X0208-1983\" },*/\n  /*{ \"JISX0208-1990\", \"JIS_X0208-1990\" },*/\n  /*{ \"JISX0212-1990\", \"JIS_X0212-1990\" },*/\n  /*{ \"KSC5601-1987\",  \"KS_C_5601-1987\" },*/\n    { \"SJIS-1\",        \"CP943\" },\n    { \"SJIS-2\",        \"CP943\" },\n    { \"eucJP\",         \"EUC-JP\" },\n    { \"eucKR\",         \"EUC-KR\" },\n    { \"eucTW-1993\",    \"EUC-TW\" }\n#   define alias_table_defined\n#  endif\n#  if defined VMS                                           /* OpenVMS */\n    /* The list of encodings is taken from the OpenVMS 7.3-1 documentation\n       \"Compaq C Run-Time Library Reference Manual for OpenVMS systems\"\n       section 10.7 \"Handling Different Character Sets\".  */\n    { \"DECHANYU\",  \"DEC-HANYU\" },\n    { \"DECHANZI\",  \"GB2312\" },\n    { \"DECKANJI\",  \"DEC-KANJI\" },\n    { \"DECKOREAN\", \"EUC-KR\" },\n    { \"ISO8859-1\", \"ISO-8859-1\" },\n    { \"ISO8859-2\", \"ISO-8859-2\" },\n    { \"ISO8859-5\", \"ISO-8859-5\" },\n    { \"ISO8859-7\", \"ISO-8859-7\" },\n    { \"ISO8859-8\", \"ISO-8859-8\" },\n    { \"ISO8859-9\", \"ISO-8859-9\" },\n    { \"SDECKANJI\", \"EUC-JP\" },\n    { \"SJIS\",      \"SHIFT_JIS\" },\n    { \"eucJP\",     \"EUC-JP\" },\n    { \"eucTW\",     \"EUC-TW\" }\n#   define alias_table_defined\n#  endif\n#  ifndef alias_table_defined\n    /* Just a dummy entry, to avoid a C syntax error.  */\n    { \"\", \"\" }\n#  endif\n  };\n\n# endif\n\n#else\n\n/* On these platforms, we use a mapping from locale name to GNU canonical\n   encoding name.  */\n\nstruct table_entry\n{\n  const char locale[17+1];\n  const char canonical[11+1];\n};\n\n/* Table of platform-dependent mappings, sorted in ascending order.  */\nstatic const struct table_entry locale_table[] =\n  {\n# if defined __FreeBSD__                                    /* FreeBSD 4.2 */\n    { \"cs_CZ.ISO_8859-2\",  \"ISO-8859-2\" },\n    { \"da_DK.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"da_DK.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"de_AT.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"de_AT.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"de_CH.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"de_CH.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"de_DE.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"de_DE.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"en_AU.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"en_AU.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"en_CA.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"en_CA.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"en_GB.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"en_GB.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"en_US.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"en_US.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"es_ES.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"es_ES.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"fi_FI.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"fi_FI.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"fr_BE.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"fr_BE.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"fr_CA.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"fr_CA.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"fr_CH.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"fr_CH.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"fr_FR.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"fr_FR.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"hr_HR.ISO_8859-2\",  \"ISO-8859-2\" },\n    { \"hu_HU.ISO_8859-2\",  \"ISO-8859-2\" },\n    { \"is_IS.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"is_IS.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"it_CH.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"it_CH.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"it_IT.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"it_IT.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"ja_JP.EUC\",         \"EUC-JP\" },\n    { \"ja_JP.SJIS\",        \"SHIFT_JIS\" },\n    { \"ja_JP.Shift_JIS\",   \"SHIFT_JIS\" },\n    { \"ko_KR.EUC\",         \"EUC-KR\" },\n    { \"la_LN.ASCII\",       \"ASCII\" },\n    { \"la_LN.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"la_LN.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"la_LN.ISO_8859-2\",  \"ISO-8859-2\" },\n    { \"la_LN.ISO_8859-4\",  \"ISO-8859-4\" },\n    { \"lt_LN.ASCII\",       \"ASCII\" },\n    { \"lt_LN.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"lt_LN.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"lt_LN.ISO_8859-2\",  \"ISO-8859-2\" },\n    { \"lt_LT.ISO_8859-4\",  \"ISO-8859-4\" },\n    { \"nl_BE.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"nl_BE.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"nl_NL.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"nl_NL.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"no_NO.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"no_NO.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"pl_PL.ISO_8859-2\",  \"ISO-8859-2\" },\n    { \"pt_PT.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"pt_PT.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"ru_RU.CP866\",       \"CP866\" },\n    { \"ru_RU.ISO_8859-5\",  \"ISO-8859-5\" },\n    { \"ru_RU.KOI8-R\",      \"KOI8-R\" },\n    { \"ru_SU.CP866\",       \"CP866\" },\n    { \"ru_SU.ISO_8859-5\",  \"ISO-8859-5\" },\n    { \"ru_SU.KOI8-R\",      \"KOI8-R\" },\n    { \"sl_SI.ISO_8859-2\",  \"ISO-8859-2\" },\n    { \"sv_SE.DIS_8859-15\", \"ISO-8859-15\" },\n    { \"sv_SE.ISO_8859-1\",  \"ISO-8859-1\" },\n    { \"uk_UA.KOI8-U\",      \"KOI8-U\" },\n    { \"zh_CN.EUC\",         \"GB2312\" },\n    { \"zh_TW.BIG5\",        \"BIG5\" },\n    { \"zh_TW.Big5\",        \"BIG5\" }\n#  define locale_table_defined\n# endif\n# if defined __DJGPP__                                      /* DOS / DJGPP 2.03 */\n    /* The encodings given here may not all be correct.\n       If you find that the encoding given for your language and\n       country is not the one your DOS machine actually uses, just\n       correct it in this file, and send a mail to\n       Juan Manuel Guerrero <juan.guerrero@gmx.de>\n       and <bug-gnulib@gnu.org>.  */\n    { \"C\",     \"ASCII\" },\n    { \"ar\",    \"CP864\" },\n    { \"ar_AE\", \"CP864\" },\n    { \"ar_DZ\", \"CP864\" },\n    { \"ar_EG\", \"CP864\" },\n    { \"ar_IQ\", \"CP864\" },\n    { \"ar_IR\", \"CP864\" },\n    { \"ar_JO\", \"CP864\" },\n    { \"ar_KW\", \"CP864\" },\n    { \"ar_MA\", \"CP864\" },\n    { \"ar_OM\", \"CP864\" },\n    { \"ar_QA\", \"CP864\" },\n    { \"ar_SA\", \"CP864\" },\n    { \"ar_SY\", \"CP864\" },\n    { \"be\",    \"CP866\" },\n    { \"be_BE\", \"CP866\" },\n    { \"bg\",    \"CP866\" }, /* not CP855 ?? */\n    { \"bg_BG\", \"CP866\" }, /* not CP855 ?? */\n    { \"ca\",    \"CP850\" },\n    { \"ca_ES\", \"CP850\" },\n    { \"cs\",    \"CP852\" },\n    { \"cs_CZ\", \"CP852\" },\n    { \"da\",    \"CP865\" }, /* not CP850 ?? */\n    { \"da_DK\", \"CP865\" }, /* not CP850 ?? */\n    { \"de\",    \"CP850\" },\n    { \"de_AT\", \"CP850\" },\n    { \"de_CH\", \"CP850\" },\n    { \"de_DE\", \"CP850\" },\n    { \"el\",    \"CP869\" },\n    { \"el_GR\", \"CP869\" },\n    { \"en\",    \"CP850\" },\n    { \"en_AU\", \"CP850\" }, /* not CP437 ?? */\n    { \"en_CA\", \"CP850\" },\n    { \"en_GB\", \"CP850\" },\n    { \"en_NZ\", \"CP437\" },\n    { \"en_US\", \"CP437\" },\n    { \"en_ZA\", \"CP850\" }, /* not CP437 ?? */\n    { \"eo\",    \"CP850\" },\n    { \"eo_EO\", \"CP850\" },\n    { \"es\",    \"CP850\" },\n    { \"es_AR\", \"CP850\" },\n    { \"es_BO\", \"CP850\" },\n    { \"es_CL\", \"CP850\" },\n    { \"es_CO\", \"CP850\" },\n    { \"es_CR\", \"CP850\" },\n    { \"es_CU\", \"CP850\" },\n    { \"es_DO\", \"CP850\" },\n    { \"es_EC\", \"CP850\" },\n    { \"es_ES\", \"CP850\" },\n    { \"es_GT\", \"CP850\" },\n    { \"es_HN\", \"CP850\" },\n    { \"es_MX\", \"CP850\" },\n    { \"es_NI\", \"CP850\" },\n    { \"es_PA\", \"CP850\" },\n    { \"es_PE\", \"CP850\" },\n    { \"es_PY\", \"CP850\" },\n    { \"es_SV\", \"CP850\" },\n    { \"es_UY\", \"CP850\" },\n    { \"es_VE\", \"CP850\" },\n    { \"et\",    \"CP850\" },\n    { \"et_EE\", \"CP850\" },\n    { \"eu\",    \"CP850\" },\n    { \"eu_ES\", \"CP850\" },\n    { \"fi\",    \"CP850\" },\n    { \"fi_FI\", \"CP850\" },\n    { \"fr\",    \"CP850\" },\n    { \"fr_BE\", \"CP850\" },\n    { \"fr_CA\", \"CP850\" },\n    { \"fr_CH\", \"CP850\" },\n    { \"fr_FR\", \"CP850\" },\n    { \"ga\",    \"CP850\" },\n    { \"ga_IE\", \"CP850\" },\n    { \"gd\",    \"CP850\" },\n    { \"gd_GB\", \"CP850\" },\n    { \"gl\",    \"CP850\" },\n    { \"gl_ES\", \"CP850\" },\n    { \"he\",    \"CP862\" },\n    { \"he_IL\", \"CP862\" },\n    { \"hr\",    \"CP852\" },\n    { \"hr_HR\", \"CP852\" },\n    { \"hu\",    \"CP852\" },\n    { \"hu_HU\", \"CP852\" },\n    { \"id\",    \"CP850\" }, /* not CP437 ?? */\n    { \"id_ID\", \"CP850\" }, /* not CP437 ?? */\n    { \"is\",    \"CP861\" }, /* not CP850 ?? */\n    { \"is_IS\", \"CP861\" }, /* not CP850 ?? */\n    { \"it\",    \"CP850\" },\n    { \"it_CH\", \"CP850\" },\n    { \"it_IT\", \"CP850\" },\n    { \"ja\",    \"CP932\" },\n    { \"ja_JP\", \"CP932\" },\n    { \"kr\",    \"CP949\" }, /* not CP934 ?? */\n    { \"kr_KR\", \"CP949\" }, /* not CP934 ?? */\n    { \"lt\",    \"CP775\" },\n    { \"lt_LT\", \"CP775\" },\n    { \"lv\",    \"CP775\" },\n    { \"lv_LV\", \"CP775\" },\n    { \"mk\",    \"CP866\" }, /* not CP855 ?? */\n    { \"mk_MK\", \"CP866\" }, /* not CP855 ?? */\n    { \"mt\",    \"CP850\" },\n    { \"mt_MT\", \"CP850\" },\n    { \"nb\",    \"CP865\" }, /* not CP850 ?? */\n    { \"nb_NO\", \"CP865\" }, /* not CP850 ?? */\n    { \"nl\",    \"CP850\" },\n    { \"nl_BE\", \"CP850\" },\n    { \"nl_NL\", \"CP850\" },\n    { \"nn\",    \"CP865\" }, /* not CP850 ?? */\n    { \"nn_NO\", \"CP865\" }, /* not CP850 ?? */\n    { \"no\",    \"CP865\" }, /* not CP850 ?? */\n    { \"no_NO\", \"CP865\" }, /* not CP850 ?? */\n    { \"pl\",    \"CP852\" },\n    { \"pl_PL\", \"CP852\" },\n    { \"pt\",    \"CP850\" },\n    { \"pt_BR\", \"CP850\" },\n    { \"pt_PT\", \"CP850\" },\n    { \"ro\",    \"CP852\" },\n    { \"ro_RO\", \"CP852\" },\n    { \"ru\",    \"CP866\" },\n    { \"ru_RU\", \"CP866\" },\n    { \"sk\",    \"CP852\" },\n    { \"sk_SK\", \"CP852\" },\n    { \"sl\",    \"CP852\" },\n    { \"sl_SI\", \"CP852\" },\n    { \"sq\",    \"CP852\" },\n    { \"sq_AL\", \"CP852\" },\n    { \"sr\",    \"CP852\" }, /* CP852 or CP866 or CP855 ?? */\n    { \"sr_CS\", \"CP852\" }, /* CP852 or CP866 or CP855 ?? */\n    { \"sr_YU\", \"CP852\" }, /* CP852 or CP866 or CP855 ?? */\n    { \"sv\",    \"CP850\" },\n    { \"sv_SE\", \"CP850\" },\n    { \"th\",    \"CP874\" },\n    { \"th_TH\", \"CP874\" },\n    { \"tr\",    \"CP857\" },\n    { \"tr_TR\", \"CP857\" },\n    { \"uk\",    \"CP1125\" },\n    { \"uk_UA\", \"CP1125\" },\n    { \"zh_CN\", \"GBK\" },\n    { \"zh_TW\", \"CP950\" } /* not CP938 ?? */\n#  define locale_table_defined\n# endif\n# ifndef locale_table_defined\n    /* Just a dummy entry, to avoid a C syntax error.  */\n    { \"\", \"\" }\n# endif\n  };\n\n#endif\n\n\n/* Determine the current locale's character encoding, and canonicalize it\n   into one of the canonical names listed below.\n   The result must not be freed; it is statically allocated.  The result\n   becomes invalid when setlocale() is used to change the global locale, or\n   when the value of one of the environment variables LC_ALL, LC_CTYPE, LANG\n   is changed; threads in multithreaded programs should not do this.\n   If the canonical name cannot be determined, the result is a non-canonical\n   name.  */\n\n#ifdef STATIC\nSTATIC\n#endif\nconst char *\nlocale_charset (void)\n{\n  const char *codeset;\n\n  /* This function must be multithread-safe.  To achieve this without using\n     thread-local storage, we use a simple strcpy or memcpy to fill this static\n     buffer.  Filling it through, for example, strcpy + strcat would not be\n     guaranteed to leave the buffer's contents intact if another thread is\n     currently accessing it.  If necessary, the contents is first assembled in\n     a stack-allocated buffer.  */\n\n#if HAVE_LANGINFO_CODESET || defined WINDOWS_NATIVE || defined OS2\n\n# if HAVE_LANGINFO_CODESET\n\n  /* Most systems support nl_langinfo (CODESET) nowadays.  */\n  codeset = nl_langinfo (CODESET);\n\n#  ifdef __CYGWIN__\n  /* Cygwin < 1.7 does not have locales.  nl_langinfo (CODESET) always\n     returns \"US-ASCII\".  Return the suffix of the locale name from the\n     environment variables (if present) or the codepage as a number.  */\n  if (codeset != NULL && strcmp (codeset, \"US-ASCII\") == 0)\n    {\n      const char *locale;\n      static char resultbuf[2 + 10 + 1];\n\n      locale = getenv (\"LC_ALL\");\n      if (locale == NULL || locale[0] == '\\0')\n        {\n          locale = getenv (\"LC_CTYPE\");\n          if (locale == NULL || locale[0] == '\\0')\n            locale = getenv (\"LANG\");\n        }\n      if (locale != NULL && locale[0] != '\\0')\n        {\n          /* If the locale name contains an encoding after the dot, return\n             it.  */\n          const char *dot = strchr (locale, '.');\n\n          if (dot != NULL)\n            {\n              const char *modifier;\n\n              dot++;\n              /* Look for the possible @... trailer and remove it, if any.  */\n              modifier = strchr (dot, '@');\n              if (modifier == NULL)\n                return dot;\n              if (modifier - dot < sizeof (resultbuf))\n                {\n                  /* This way of filling resultbuf is multithread-safe.  */\n                  memcpy (resultbuf, dot, modifier - dot);\n                  resultbuf [modifier - dot] = '\\0';\n                  return resultbuf;\n                }\n            }\n        }\n\n      /* The Windows API has a function returning the locale's codepage as a\n         number: GetACP().  This encoding is used by Cygwin, unless the user\n         has set the environment variable CYGWIN=codepage:oem (which very few\n         people do).\n         Output directed to console windows needs to be converted (to\n         GetOEMCP() if the console is using a raster font, or to\n         GetConsoleOutputCP() if it is using a TrueType font).  Cygwin does\n         this conversion transparently (see winsup/cygwin/fhandler_console.cc),\n         converting to GetConsoleOutputCP().  This leads to correct results,\n         except when SetConsoleOutputCP has been called and a raster font is\n         in use.  */\n      {\n        char buf[2 + 10 + 1];\n\n        sprintf (buf, \"CP%u\", GetACP ());\n        strcpy (resultbuf, buf);\n        codeset = resultbuf;\n      }\n    }\n#  endif\n\n  if (codeset == NULL)\n    /* The canonical name cannot be determined.  */\n    codeset = \"\";\n\n# elif defined WINDOWS_NATIVE\n\n  char buf[2 + 10 + 1];\n  static char resultbuf[2 + 10 + 1];\n\n  /* The Windows API has a function returning the locale's codepage as\n     a number, but the value doesn't change according to what the\n     'setlocale' call specified.  So we use it as a last resort, in\n     case the string returned by 'setlocale' doesn't specify the\n     codepage.  */\n  char *current_locale = setlocale (LC_CTYPE, NULL);\n  char *pdot = strrchr (current_locale, '.');\n\n  if (pdot && 2 + strlen (pdot + 1) + 1 <= sizeof (buf))\n    sprintf (buf, \"CP%s\", pdot + 1);\n  else\n    {\n      /* The Windows API has a function returning the locale's codepage as a\n         number: GetACP().\n         When the output goes to a console window, it needs to be provided in\n         GetOEMCP() encoding if the console is using a raster font, or in\n         GetConsoleOutputCP() encoding if it is using a TrueType font.\n         But in GUI programs and for output sent to files and pipes, GetACP()\n         encoding is the best bet.  */\n      sprintf (buf, \"CP%u\", GetACP ());\n    }\n  /* For a locale name such as \"French_France.65001\", in Windows 10,\n     setlocale now returns \"French_France.utf8\" instead.  */\n  if (strcmp (buf + 2, \"65001\") == 0 || strcmp (buf + 2, \"utf8\") == 0)\n    codeset = \"UTF-8\";\n  else\n    {\n      strcpy (resultbuf, buf);\n      codeset = resultbuf;\n    }\n\n# elif defined OS2\n\n  const char *locale;\n  static char resultbuf[2 + 10 + 1];\n  ULONG cp[3];\n  ULONG cplen;\n\n  codeset = NULL;\n\n  /* Allow user to override the codeset, as set in the operating system,\n     with standard language environment variables.  */\n  locale = getenv (\"LC_ALL\");\n  if (locale == NULL || locale[0] == '\\0')\n    {\n      locale = getenv (\"LC_CTYPE\");\n      if (locale == NULL || locale[0] == '\\0')\n        locale = getenv (\"LANG\");\n    }\n  if (locale != NULL && locale[0] != '\\0')\n    {\n      /* If the locale name contains an encoding after the dot, return it.  */\n      const char *dot = strchr (locale, '.');\n\n      if (dot != NULL)\n        {\n          const char *modifier;\n\n          dot++;\n          /* Look for the possible @... trailer and remove it, if any.  */\n          modifier = strchr (dot, '@');\n          if (modifier == NULL)\n            return dot;\n          if (modifier - dot < sizeof (resultbuf))\n            {\n              /* This way of filling resultbuf is multithread-safe.  */\n              memcpy (resultbuf, dot, modifier - dot);\n              resultbuf [modifier - dot] = '\\0';\n              return resultbuf;\n            }\n        }\n\n      /* For the POSIX locale, don't use the system's codepage.  */\n      if (strcmp (locale, \"C\") == 0 || strcmp (locale, \"POSIX\") == 0)\n        codeset = \"\";\n    }\n\n  if (codeset == NULL)\n    {\n      /* OS/2 has a function returning the locale's codepage as a number.  */\n      if (DosQueryCp (sizeof (cp), cp, &cplen))\n        codeset = \"\";\n      else\n        {\n          char buf[2 + 10 + 1];\n\n          sprintf (buf, \"CP%u\", cp[0]);\n          strcpy (resultbuf, buf);\n          codeset = resultbuf;\n        }\n    }\n\n# else\n\n#  error \"Add code for other platforms here.\"\n\n# endif\n\n  /* Resolve alias.  */\n  {\n# ifdef alias_table_defined\n    /* On some platforms, UTF-8 locales are the most frequently used ones.\n       Speed up the common case and slow down the less common cases by\n       testing for this case first.  */\n#  if defined __OpenBSD__ || (defined __APPLE__ && defined __MACH__) || defined __sun || defined __CYGWIN__\n    if (strcmp (codeset, \"UTF-8\") == 0)\n      goto done_table_lookup;\n    else\n#  endif\n      {\n        const struct table_entry * const table = alias_table;\n        size_t const table_size =\n          sizeof (alias_table) / sizeof (struct table_entry);\n        /* The table is sorted.  Perform a binary search.  */\n        size_t hi = table_size;\n        size_t lo = 0;\n        while (lo < hi)\n          {\n            /* Invariant:\n               for i < lo, strcmp (table[i].alias, codeset) < 0,\n               for i >= hi, strcmp (table[i].alias, codeset) > 0.  */\n            size_t mid = (hi + lo) >> 1; /* >= lo, < hi */\n            int cmp = strcmp (table[mid].alias, codeset);\n            if (cmp < 0)\n              lo = mid + 1;\n            else if (cmp > 0)\n              hi = mid;\n            else\n              {\n                /* Found an i with\n                     strcmp (table[i].alias, codeset) == 0.  */\n                codeset = table[mid].canonical;\n                goto done_table_lookup;\n              }\n          }\n      }\n    if (0)\n      done_table_lookup: ;\n    else\n# endif\n      {\n        /* Did not find it in the table.  */\n        /* On Mac OS X, all modern locales use the UTF-8 encoding.\n           BeOS and Haiku have a single locale, and it has UTF-8 encoding.  */\n# if (defined __APPLE__ && defined __MACH__) || defined __BEOS__ || defined __HAIKU__\n        codeset = \"UTF-8\";\n# else\n        /* Don't return an empty string.  GNU libc and GNU libiconv interpret\n           the empty string as denoting \"the locale's character encoding\",\n           thus GNU libiconv would call this function a second time.  */\n        if (codeset[0] == '\\0')\n          codeset = \"ASCII\";\n# endif\n      }\n  }\n\n#else\n\n  /* On old systems which lack it, use setlocale or getenv.  */\n  const char *locale = NULL;\n\n  /* But most old systems don't have a complete set of locales.  Some\n     (like DJGPP) have only the C locale.  Therefore we don't use setlocale\n     here; it would return \"C\" when it doesn't support the locale name the\n     user has set.  */\n# if 0\n  locale = setlocale (LC_CTYPE, NULL);\n# endif\n  if (locale == NULL || locale[0] == '\\0')\n    {\n      locale = getenv (\"LC_ALL\");\n      if (locale == NULL || locale[0] == '\\0')\n        {\n          locale = getenv (\"LC_CTYPE\");\n          if (locale == NULL || locale[0] == '\\0')\n            locale = getenv (\"LANG\");\n            if (locale == NULL)\n              locale = \"\";\n        }\n    }\n\n  /* Map locale name to canonical encoding name.  */\n  {\n# ifdef locale_table_defined\n    const struct table_entry * const table = locale_table;\n    size_t const table_size =\n      sizeof (locale_table) / sizeof (struct table_entry);\n    /* The table is sorted.  Perform a binary search.  */\n    size_t hi = table_size;\n    size_t lo = 0;\n    while (lo < hi)\n      {\n        /* Invariant:\n           for i < lo, strcmp (table[i].locale, locale) < 0,\n           for i >= hi, strcmp (table[i].locale, locale) > 0.  */\n        size_t mid = (hi + lo) >> 1; /* >= lo, < hi */\n        int cmp = strcmp (table[mid].locale, locale);\n        if (cmp < 0)\n          lo = mid + 1;\n        else if (cmp > 0)\n          hi = mid;\n        else\n          {\n            /* Found an i with\n                 strcmp (table[i].locale, locale) == 0.  */\n            codeset = table[mid].canonical;\n            goto done_table_lookup;\n          }\n      }\n    if (0)\n      done_table_lookup: ;\n    else\n# endif\n      {\n        /* Did not find it in the table.  */\n        /* On Mac OS X, all modern locales use the UTF-8 encoding.\n           BeOS and Haiku have a single locale, and it has UTF-8 encoding.  */\n# if (defined __APPLE__ && defined __MACH__) || defined __BEOS__ || defined __HAIKU__\n        codeset = \"UTF-8\";\n# else\n        /* The canonical name cannot be determined.  */\n        /* Don't return an empty string.  GNU libc and GNU libiconv interpret\n           the empty string as denoting \"the locale's character encoding\",\n           thus GNU libiconv would call this function a second time.  */\n        codeset = \"ASCII\";\n# endif\n      }\n  }\n\n#endif\n\n#ifdef DARWIN7\n  /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and \"UTF-8\"\n     (the default codeset) does not work when MB_CUR_MAX is 1.  */\n  if (strcmp (codeset, \"UTF-8\") == 0 && MB_CUR_MAX_L (uselocale (NULL)) <= 1)\n    codeset = \"ASCII\";\n#endif\n\n  return codeset;\n}\n"
  },
  {
    "path": "gnulib/localcharset.h",
    "content": "/* Determine a canonical name for the current locale's character encoding.\n   Copyright (C) 2000-2003, 2009-2021 Free Software Foundation, Inc.\n   This file is part of the GNU CHARSET Library.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _LOCALCHARSET_H\n#define _LOCALCHARSET_H\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/* Determine the current locale's character encoding, and canonicalize it\n   into one of the canonical names listed below.\n   The result must not be freed; it is statically allocated.  The result\n   becomes invalid when setlocale() is used to change the global locale, or\n   when the value of one of the environment variables LC_ALL, LC_CTYPE, LANG\n   is changed; threads in multithreaded programs should not do this.\n   If the canonical name cannot be determined, the result is a non-canonical\n   name.  */\nextern const char * locale_charset (void);\n\n/* About GNU canonical names for character encodings:\n\n   Every canonical name must be supported by GNU libiconv.  Support by GNU libc\n   is also desirable.\n\n   The name is case insensitive.  Usually an upper case MIME charset name is\n   preferred.\n\n   The current list of these GNU canonical names is:\n\n       name              MIME?             used by which systems\n                                    (darwin = Mac OS X, windows = native Windows)\n\n   ASCII, ANSI_X3.4-1968       glibc solaris freebsd netbsd darwin minix cygwin\n   ISO-8859-1              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos\n   ISO-8859-2              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos\n   ISO-8859-3              Y   glibc solaris cygwin\n   ISO-8859-4              Y   hpux osf solaris freebsd netbsd openbsd darwin\n   ISO-8859-5              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos\n   ISO-8859-6              Y   glibc aix hpux solaris cygwin\n   ISO-8859-7              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos\n   ISO-8859-8              Y   glibc aix hpux osf solaris cygwin zos\n   ISO-8859-9              Y   glibc aix hpux irix osf solaris freebsd darwin cygwin zos\n   ISO-8859-13                 glibc hpux solaris freebsd netbsd openbsd darwin cygwin\n   ISO-8859-14                 glibc cygwin\n   ISO-8859-15                 glibc aix irix osf solaris freebsd netbsd openbsd darwin cygwin\n   KOI8-R                  Y   glibc hpux solaris freebsd netbsd openbsd darwin\n   KOI8-U                  Y   glibc freebsd netbsd openbsd darwin cygwin\n   KOI8-T                      glibc\n   CP437                       dos\n   CP775                       dos\n   CP850                       aix osf dos\n   CP852                       dos\n   CP855                       dos\n   CP856                       aix\n   CP857                       dos\n   CP861                       dos\n   CP862                       dos\n   CP864                       dos\n   CP865                       dos\n   CP866                       freebsd netbsd openbsd darwin dos\n   CP869                       dos\n   CP874                       windows dos\n   CP922                       aix\n   CP932                       aix cygwin windows dos\n   CP943                       aix zos\n   CP949                       osf darwin windows dos\n   CP950                       windows dos\n   CP1046                      aix\n   CP1124                      aix\n   CP1125                      dos\n   CP1129                      aix\n   CP1131                      freebsd darwin\n   CP1250                      windows\n   CP1251                      glibc hpux solaris freebsd netbsd openbsd darwin cygwin windows\n   CP1252                      aix windows\n   CP1253                      windows\n   CP1254                      windows\n   CP1255                      glibc windows\n   CP1256                      windows\n   CP1257                      windows\n   GB2312                  Y   glibc aix hpux irix solaris freebsd netbsd darwin cygwin zos\n   EUC-JP                  Y   glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin\n   EUC-KR                  Y   glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin zos\n   EUC-TW                      glibc aix hpux irix osf solaris netbsd\n   BIG5                    Y   glibc aix hpux osf solaris freebsd netbsd darwin cygwin zos\n   BIG5-HKSCS                  glibc hpux solaris netbsd darwin\n   GBK                         glibc aix osf solaris freebsd darwin cygwin windows dos\n   GB18030                     glibc hpux solaris freebsd netbsd darwin\n   SHIFT_JIS               Y   hpux osf solaris freebsd netbsd darwin\n   JOHAB                       glibc solaris windows\n   TIS-620                     glibc aix hpux osf solaris cygwin zos\n   VISCII                  Y   glibc\n   TCVN5712-1                  glibc\n   ARMSCII-8                   glibc freebsd netbsd darwin\n   GEORGIAN-PS                 glibc cygwin\n   PT154                       glibc netbsd cygwin\n   HP-ROMAN8                   hpux\n   HP-ARABIC8                  hpux\n   HP-GREEK8                   hpux\n   HP-HEBREW8                  hpux\n   HP-TURKISH8                 hpux\n   HP-KANA8                    hpux\n   DEC-KANJI                   osf\n   DEC-HANYU                   osf\n   UTF-8                   Y   glibc aix hpux osf solaris netbsd darwin cygwin zos\n\n   Note: Names which are not marked as being a MIME name should not be used in\n   Internet protocols for information interchange (mail, news, etc.).\n\n   Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names.  Applications\n   must understand both names and treat them as equivalent.\n */\n\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif /* _LOCALCHARSET_H */\n"
  },
  {
    "path": "gnulib/locale.in.h",
    "content": "/* A POSIX <locale.h>.\n   Copyright (C) 2007-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n#if (defined _WIN32 && !defined __CYGWIN__ && defined __need_locale_t) \\\n    || defined _GL_ALREADY_INCLUDING_LOCALE_H\n\n/* Special invocation convention:\n   - Inside mingw header files,\n   - To handle Solaris header files (through Solaris 10) when combined\n     with gettext's libintl.h.  */\n\n#@INCLUDE_NEXT@ @NEXT_LOCALE_H@\n\n#else\n/* Normal invocation convention.  */\n\n#ifndef _@GUARD_PREFIX@_LOCALE_H\n\n#define _GL_ALREADY_INCLUDING_LOCALE_H\n\n/* The include_next requires a split double-inclusion guard.  */\n#@INCLUDE_NEXT@ @NEXT_LOCALE_H@\n\n#undef _GL_ALREADY_INCLUDING_LOCALE_H\n\n#ifndef _@GUARD_PREFIX@_LOCALE_H\n#define _@GUARD_PREFIX@_LOCALE_H\n\n/* NetBSD 5.0 mis-defines NULL.  */\n#include <stddef.h>\n\n/* Mac OS X 10.5 defines the locale_t type in <xlocale.h>.  */\n#if @HAVE_XLOCALE_H@\n# include <xlocale.h>\n#endif\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n\n/* The LC_MESSAGES locale category is specified in POSIX, but not in ISO C.\n   On systems that don't define it, use the same value as GNU libintl.  */\n#if !defined LC_MESSAGES\n# define LC_MESSAGES 1729\n#endif\n\n/* On native Windows with MSVC, 'struct lconv' lacks the members int_p_* and\n   int_n_*.  Instead of overriding 'struct lconv', merely define these member\n   names as macros.  This avoids trouble in C++ mode.  */\n#if defined _MSC_VER\n# define int_p_cs_precedes   p_cs_precedes\n# define int_p_sign_posn     p_sign_posn\n# define int_p_sep_by_space  p_sep_by_space\n# define int_n_cs_precedes   n_cs_precedes\n# define int_n_sign_posn     n_sign_posn\n# define int_n_sep_by_space  n_sep_by_space\n#endif\n\n/* Bionic libc's 'struct lconv' is just a dummy.  */\n#if @REPLACE_STRUCT_LCONV@\n# define lconv rpl_lconv\nstruct lconv\n{\n  /* All 'char *' are actually 'const char *'.  */\n\n  /* Members that depend on the LC_NUMERIC category of the locale.  See\n     <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_04> */\n\n  /* Symbol used as decimal point.  */\n  char *decimal_point;\n  /* Symbol used to separate groups of digits to the left of the decimal\n     point.  */\n  char *thousands_sep;\n  /* Definition of the size of groups of digits to the left of the decimal\n     point.  */\n  char *grouping;\n\n  /* Members that depend on the LC_MONETARY category of the locale.  See\n     <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_03> */\n\n  /* Symbol used as decimal point.  */\n  char *mon_decimal_point;\n  /* Symbol used to separate groups of digits to the left of the decimal\n     point.  */\n  char *mon_thousands_sep;\n  /* Definition of the size of groups of digits to the left of the decimal\n     point.  */\n  char *mon_grouping;\n  /* Sign used to indicate a value >= 0.  */\n  char *positive_sign;\n  /* Sign used to indicate a value < 0.  */\n  char *negative_sign;\n\n  /* For formatting local currency.  */\n  /* Currency symbol (3 characters) followed by separator (1 character).  */\n  char *currency_symbol;\n  /* Number of digits after the decimal point.  */\n  char frac_digits;\n  /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it\n     comes after the number.  */\n  char p_cs_precedes;\n  /* For values >= 0: Position of the sign.  */\n  char p_sign_posn;\n  /* For values >= 0: Placement of spaces between currency symbol, sign, and\n     number.  */\n  char p_sep_by_space;\n  /* For values < 0: 1 if the currency symbol precedes the number, 0 if it\n     comes after the number.  */\n  char n_cs_precedes;\n  /* For values < 0: Position of the sign.  */\n  char n_sign_posn;\n  /* For values < 0: Placement of spaces between currency symbol, sign, and\n     number.  */\n  char n_sep_by_space;\n\n  /* For formatting international currency.  */\n  /* Currency symbol (3 characters) followed by separator (1 character).  */\n  char *int_curr_symbol;\n  /* Number of digits after the decimal point.  */\n  char int_frac_digits;\n  /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it\n     comes after the number.  */\n  char int_p_cs_precedes;\n  /* For values >= 0: Position of the sign.  */\n  char int_p_sign_posn;\n  /* For values >= 0: Placement of spaces between currency symbol, sign, and\n     number.  */\n  char int_p_sep_by_space;\n  /* For values < 0: 1 if the currency symbol precedes the number, 0 if it\n     comes after the number.  */\n  char int_n_cs_precedes;\n  /* For values < 0: Position of the sign.  */\n  char int_n_sign_posn;\n  /* For values < 0: Placement of spaces between currency symbol, sign, and\n     number.  */\n  char int_n_sep_by_space;\n};\n#endif\n\n#if @GNULIB_LOCALECONV@\n# if @REPLACE_LOCALECONV@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef localeconv\n#   define localeconv rpl_localeconv\n#  endif\n_GL_FUNCDECL_RPL (localeconv, struct lconv *, (void));\n_GL_CXXALIAS_RPL (localeconv, struct lconv *, (void));\n# else\n_GL_CXXALIAS_SYS (localeconv, struct lconv *, (void));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (localeconv);\n# endif\n#elif @REPLACE_STRUCT_LCONV@\n# undef localeconv\n# define localeconv localeconv_used_without_requesting_gnulib_module_localeconv\n#elif defined GNULIB_POSIXCHECK\n# undef localeconv\n# if HAVE_RAW_DECL_LOCALECONV\n_GL_WARN_ON_USE (localeconv,\n                 \"localeconv returns too few information on some platforms - \"\n                 \"use gnulib module localeconv for portability\");\n# endif\n#endif\n\n#if @GNULIB_SETLOCALE@\n# if @REPLACE_SETLOCALE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef setlocale\n#   define setlocale rpl_setlocale\n#   define GNULIB_defined_setlocale 1\n#  endif\n_GL_FUNCDECL_RPL (setlocale, char *, (int category, const char *locale));\n_GL_CXXALIAS_RPL (setlocale, char *, (int category, const char *locale));\n# else\n_GL_CXXALIAS_SYS (setlocale, char *, (int category, const char *locale));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (setlocale);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef setlocale\n# if HAVE_RAW_DECL_SETLOCALE\n_GL_WARN_ON_USE (setlocale, \"setlocale works differently on native Windows - \"\n                 \"use gnulib module setlocale for portability\");\n# endif\n#endif\n\n#if @GNULIB_SETLOCALE_NULL@\n/* Included here for convenience.  */\n# include \"setlocale_null.h\"\n#endif\n\n#if /*@GNULIB_NEWLOCALE@ ||*/ (@GNULIB_LOCALENAME@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_NEWLOCALE@)\n# if @REPLACE_NEWLOCALE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef newlocale\n#   define newlocale rpl_newlocale\n#   define GNULIB_defined_newlocale 1\n#  endif\n_GL_FUNCDECL_RPL (newlocale, locale_t,\n                  (int category_mask, const char *name, locale_t base)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (newlocale, locale_t,\n                  (int category_mask, const char *name, locale_t base));\n# else\n#  if @HAVE_NEWLOCALE@\n_GL_CXXALIAS_SYS (newlocale, locale_t,\n                  (int category_mask, const char *name, locale_t base));\n#  endif\n# endif\n# if @HAVE_NEWLOCALE@\n_GL_CXXALIASWARN (newlocale);\n# endif\n# if @HAVE_NEWLOCALE@ || @REPLACE_NEWLOCALE@\n#  ifndef HAVE_WORKING_NEWLOCALE\n#   define HAVE_WORKING_NEWLOCALE 1\n#  endif\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef newlocale\n# if HAVE_RAW_DECL_NEWLOCALE\n_GL_WARN_ON_USE (newlocale, \"newlocale is not portable\");\n# endif\n#endif\n\n#if @GNULIB_DUPLOCALE@ || (@GNULIB_LOCALENAME@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_DUPLOCALE@)\n# if @REPLACE_DUPLOCALE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef duplocale\n#   define duplocale rpl_duplocale\n#   define GNULIB_defined_duplocale 1\n#  endif\n_GL_FUNCDECL_RPL (duplocale, locale_t, (locale_t locale) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (duplocale, locale_t, (locale_t locale));\n# else\n#  if @HAVE_DUPLOCALE@\n_GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale));\n#  endif\n# endif\n# if @HAVE_DUPLOCALE@\n_GL_CXXALIASWARN (duplocale);\n# endif\n# if @HAVE_DUPLOCALE@ || @REPLACE_DUPLOCALE@\n#  ifndef HAVE_WORKING_DUPLOCALE\n#   define HAVE_WORKING_DUPLOCALE 1\n#  endif\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef duplocale\n# if HAVE_RAW_DECL_DUPLOCALE\n_GL_WARN_ON_USE (duplocale, \"duplocale is buggy on some glibc systems - \"\n                 \"use gnulib module duplocale for portability\");\n# endif\n#endif\n\n#if /*@GNULIB_FREELOCALE@ ||*/ (@GNULIB_LOCALENAME@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_FREELOCALE@)\n# if @REPLACE_FREELOCALE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef freelocale\n#   define freelocale rpl_freelocale\n#   define GNULIB_defined_freelocale 1\n#  endif\n_GL_FUNCDECL_RPL (freelocale, void, (locale_t locale) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (freelocale, void, (locale_t locale));\n# else\n#  if @HAVE_FREELOCALE@\n/* Need to cast, because on FreeBSD and Mac OS X 10.13, the return type is\n                                   int.  */\n_GL_CXXALIAS_SYS_CAST (freelocale, void, (locale_t locale));\n#  endif\n# endif\n# if @HAVE_FREELOCALE@\n_GL_CXXALIASWARN (freelocale);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef freelocale\n# if HAVE_RAW_DECL_FREELOCALE\n_GL_WARN_ON_USE (freelocale, \"freelocale is not portable\");\n# endif\n#endif\n\n#endif /* _@GUARD_PREFIX@_LOCALE_H */\n#endif /* _@GUARD_PREFIX@_LOCALE_H */\n#endif /* !(__need_locale_t || _GL_ALREADY_INCLUDING_LOCALE_H) */\n"
  },
  {
    "path": "gnulib/localeconv.c",
    "content": "/* Query locale dependent information for formatting numbers.\n   Copyright (C) 2012-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <locale.h>\n\n#if HAVE_STRUCT_LCONV_DECIMAL_POINT\n\n/* Override for platforms where 'struct lconv' lacks the int_p_*, int_n_*\n   members.  */\n\nstruct lconv *\nlocaleconv (void)\n{\n  static struct lconv result;\n# undef lconv\n# undef localeconv\n  struct lconv *sys_result = localeconv ();\n\n  result.decimal_point = sys_result->decimal_point;\n  result.thousands_sep = sys_result->thousands_sep;\n  result.grouping = sys_result->grouping;\n  result.mon_decimal_point = sys_result->mon_decimal_point;\n  result.mon_thousands_sep = sys_result->mon_thousands_sep;\n  result.mon_grouping = sys_result->mon_grouping;\n  result.positive_sign = sys_result->positive_sign;\n  result.negative_sign = sys_result->negative_sign;\n  result.currency_symbol = sys_result->currency_symbol;\n  result.frac_digits = sys_result->frac_digits;\n  result.p_cs_precedes = sys_result->p_cs_precedes;\n  result.p_sign_posn = sys_result->p_sign_posn;\n  result.p_sep_by_space = sys_result->p_sep_by_space;\n  result.n_cs_precedes = sys_result->n_cs_precedes;\n  result.n_sign_posn = sys_result->n_sign_posn;\n  result.n_sep_by_space = sys_result->n_sep_by_space;\n  result.int_curr_symbol = sys_result->int_curr_symbol;\n  result.int_frac_digits = sys_result->int_frac_digits;\n  result.int_p_cs_precedes = sys_result->p_cs_precedes;\n  result.int_p_sign_posn = sys_result->p_sign_posn;\n  result.int_p_sep_by_space = sys_result->p_sep_by_space;\n  result.int_n_cs_precedes = sys_result->n_cs_precedes;\n  result.int_n_sign_posn = sys_result->n_sign_posn;\n  result.int_n_sep_by_space = sys_result->n_sep_by_space;\n\n  return &result;\n}\n\n#else\n\n/* Override for platforms where 'struct lconv' is a dummy.  */\n\n# include <limits.h>\n\nstruct lconv *\nlocaleconv (void)\n{\n  static /*const*/ struct lconv result =\n    {\n      /* decimal_point */ \".\",\n      /* thousands_sep */ \"\",\n      /* grouping */ \"\",\n      /* mon_decimal_point */ \"\",\n      /* mon_thousands_sep */ \"\",\n      /* mon_grouping */ \"\",\n      /* positive_sign */ \"\",\n      /* negative_sign */ \"\",\n      /* currency_symbol */ \"\",\n      /* frac_digits */ CHAR_MAX,\n      /* p_cs_precedes */ CHAR_MAX,\n      /* p_sign_posn */ CHAR_MAX,\n      /* p_sep_by_space */ CHAR_MAX,\n      /* n_cs_precedes */ CHAR_MAX,\n      /* n_sign_posn */ CHAR_MAX,\n      /* n_sep_by_space */ CHAR_MAX,\n      /* int_curr_symbol */ \"\",\n      /* int_frac_digits */ CHAR_MAX,\n      /* int_p_cs_precedes */ CHAR_MAX,\n      /* int_p_sign_posn */ CHAR_MAX,\n      /* int_p_sep_by_space */ CHAR_MAX,\n      /* int_n_cs_precedes */ CHAR_MAX,\n      /* int_n_sign_posn */ CHAR_MAX,\n      /* int_n_sep_by_space */ CHAR_MAX\n    };\n\n  return &result;\n}\n\n#endif\n"
  },
  {
    "path": "gnulib/malloc/dynarray-skeleton.c",
    "content": "/* Type-safe arrays which grow dynamically.\n   Copyright (C) 2017-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n/* Pre-processor macros which act as parameters:\n\n   DYNARRAY_STRUCT\n      The struct tag of dynamic array to be defined.\n   DYNARRAY_ELEMENT\n      The type name of the element type.  Elements are copied\n      as if by memcpy, and can change address as the dynamic\n      array grows.\n   DYNARRAY_PREFIX\n      The prefix of the functions which are defined.\n\n   The following parameters are optional:\n\n   DYNARRAY_ELEMENT_FREE\n      DYNARRAY_ELEMENT_FREE (E) is evaluated to deallocate the\n      contents of elements. E is of type  DYNARRAY_ELEMENT *.\n   DYNARRAY_ELEMENT_INIT\n      DYNARRAY_ELEMENT_INIT (E) is evaluated to initialize a new\n      element.  E is of type  DYNARRAY_ELEMENT *.\n      If DYNARRAY_ELEMENT_FREE but not DYNARRAY_ELEMENT_INIT is\n      defined, new elements are automatically zero-initialized.\n      Otherwise, new elements have undefined contents.\n   DYNARRAY_INITIAL_SIZE\n      The size of the statically allocated array (default:\n      at least 2, more elements if they fit into 128 bytes).\n      Must be a preprocessor constant.  If DYNARRAY_INITIAL_SIZE is 0,\n      there is no statically allocated array at, and all non-empty\n      arrays are heap-allocated.\n   DYNARRAY_FINAL_TYPE\n      The name of the type which holds the final array.  If not\n      defined, is PREFIX##finalize not provided.  DYNARRAY_FINAL_TYPE\n      must be a struct type, with members of type DYNARRAY_ELEMENT and\n      size_t at the start (in this order).\n\n   These macros are undefined after this header file has been\n   included.\n\n   The following types are provided (their members are private to the\n   dynarray implementation):\n\n     struct DYNARRAY_STRUCT\n\n   The following functions are provided:\n\n     void DYNARRAY_PREFIX##init (struct DYNARRAY_STRUCT *);\n     void DYNARRAY_PREFIX##free (struct DYNARRAY_STRUCT *);\n     bool DYNARRAY_PREFIX##has_failed (const struct DYNARRAY_STRUCT *);\n     void DYNARRAY_PREFIX##mark_failed (struct DYNARRAY_STRUCT *);\n     size_t DYNARRAY_PREFIX##size (const struct DYNARRAY_STRUCT *);\n     DYNARRAY_ELEMENT *DYNARRAY_PREFIX##begin (const struct DYNARRAY_STRUCT *);\n     DYNARRAY_ELEMENT *DYNARRAY_PREFIX##end (const struct DYNARRAY_STRUCT *);\n     DYNARRAY_ELEMENT *DYNARRAY_PREFIX##at (struct DYNARRAY_STRUCT *, size_t);\n     void DYNARRAY_PREFIX##add (struct DYNARRAY_STRUCT *, DYNARRAY_ELEMENT);\n     DYNARRAY_ELEMENT *DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *);\n     bool DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *, size_t);\n     void DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *);\n     void DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *);\n\n   The following functions are provided are provided if the\n   prerequisites are met:\n\n     bool DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *,\n                                     DYNARRAY_FINAL_TYPE *);\n       (if DYNARRAY_FINAL_TYPE is defined)\n     DYNARRAY_ELEMENT *DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *,\n                                                  size_t *);\n       (if DYNARRAY_FINAL_TYPE is not defined)\n*/\n\n#include <malloc/dynarray.h>\n\n#include <errno.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifndef DYNARRAY_STRUCT\n# error \"DYNARRAY_STRUCT must be defined\"\n#endif\n\n#ifndef DYNARRAY_ELEMENT\n# error \"DYNARRAY_ELEMENT must be defined\"\n#endif\n\n#ifndef DYNARRAY_PREFIX\n# error \"DYNARRAY_PREFIX must be defined\"\n#endif\n\n#ifdef DYNARRAY_INITIAL_SIZE\n# if DYNARRAY_INITIAL_SIZE < 0\n#  error \"DYNARRAY_INITIAL_SIZE must be non-negative\"\n# endif\n# if DYNARRAY_INITIAL_SIZE > 0\n#  define DYNARRAY_HAVE_SCRATCH 1\n# else\n#  define DYNARRAY_HAVE_SCRATCH 0\n# endif\n#else\n/* Provide a reasonable default which limits the size of\n   DYNARRAY_STRUCT.  */\n# define DYNARRAY_INITIAL_SIZE \\\n  (sizeof (DYNARRAY_ELEMENT) > 64 ? 2 : 128 / sizeof (DYNARRAY_ELEMENT))\n# define DYNARRAY_HAVE_SCRATCH 1\n#endif\n\n/* Public type definitions.  */\n\n/* All fields of this struct are private to the implementation.  */\nstruct DYNARRAY_STRUCT\n{\n  union\n  {\n    struct dynarray_header dynarray_abstract;\n    struct\n    {\n      /* These fields must match struct dynarray_header.  */\n      size_t used;\n      size_t allocated;\n      DYNARRAY_ELEMENT *array;\n    } dynarray_header;\n  } u;\n\n#if DYNARRAY_HAVE_SCRATCH\n  /* Initial inline allocation.  */\n  DYNARRAY_ELEMENT scratch[DYNARRAY_INITIAL_SIZE];\n#endif\n};\n\n/* Internal use only: Helper macros.  */\n\n/* Ensure macro-expansion of DYNARRAY_PREFIX.  */\n#define DYNARRAY_CONCAT0(prefix, name) prefix##name\n#define DYNARRAY_CONCAT1(prefix, name) DYNARRAY_CONCAT0(prefix, name)\n#define DYNARRAY_NAME(name) DYNARRAY_CONCAT1(DYNARRAY_PREFIX, name)\n\n/* Use DYNARRAY_FREE instead of DYNARRAY_NAME (free),\n   so that Gnulib does not change 'free' to 'rpl_free'.  */\n#define DYNARRAY_FREE DYNARRAY_CONCAT1 (DYNARRAY_NAME (f), ree)\n\n/* Address of the scratch buffer if any.  */\n#if DYNARRAY_HAVE_SCRATCH\n# define DYNARRAY_SCRATCH(list) (list)->scratch\n#else\n# define DYNARRAY_SCRATCH(list) NULL\n#endif\n\n/* Internal use only: Helper functions.  */\n\n/* Internal function.  Call DYNARRAY_ELEMENT_FREE with the array\n   elements.  Name mangling needed due to the DYNARRAY_ELEMENT_FREE\n   macro expansion.  */\nstatic inline void\nDYNARRAY_NAME (free__elements__) (DYNARRAY_ELEMENT *__dynarray_array,\n                                  size_t __dynarray_used)\n{\n#ifdef DYNARRAY_ELEMENT_FREE\n  for (size_t __dynarray_i = 0; __dynarray_i < __dynarray_used; ++__dynarray_i)\n    DYNARRAY_ELEMENT_FREE (&__dynarray_array[__dynarray_i]);\n#endif /* DYNARRAY_ELEMENT_FREE */\n}\n\n/* Internal function.  Free the non-scratch array allocation.  */\nstatic inline void\nDYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list)\n{\n#if DYNARRAY_HAVE_SCRATCH\n  if (list->u.dynarray_header.array != list->scratch)\n    free (list->u.dynarray_header.array);\n#else\n  free (list->u.dynarray_header.array);\n#endif\n}\n\n/* Public functions.  */\n\n/* Initialize a dynamic array object.  This must be called before any\n   use of the object.  */\n__attribute_nonnull__ ((1))\nstatic void\nDYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list)\n{\n  list->u.dynarray_header.used = 0;\n  list->u.dynarray_header.allocated = DYNARRAY_INITIAL_SIZE;\n  list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);\n}\n\n/* Deallocate the dynamic array and its elements.  */\n__attribute_maybe_unused__ __attribute_nonnull__ ((1))\nstatic void\nDYNARRAY_FREE (struct DYNARRAY_STRUCT *list)\n{\n  DYNARRAY_NAME (free__elements__)\n    (list->u.dynarray_header.array, list->u.dynarray_header.used);\n  DYNARRAY_NAME (free__array__) (list);\n  DYNARRAY_NAME (init) (list);\n}\n\n/* Return true if the dynamic array is in an error state.  */\n__attribute_nonnull__ ((1))\nstatic inline bool\nDYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list)\n{\n  return list->u.dynarray_header.allocated == __dynarray_error_marker ();\n}\n\n/* Mark the dynamic array as failed.  All elements are deallocated as\n   a side effect.  */\n__attribute_nonnull__ ((1))\nstatic void\nDYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list)\n{\n  DYNARRAY_NAME (free__elements__)\n    (list->u.dynarray_header.array, list->u.dynarray_header.used);\n  DYNARRAY_NAME (free__array__) (list);\n  list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);\n  list->u.dynarray_header.used = 0;\n  list->u.dynarray_header.allocated = __dynarray_error_marker ();\n}\n\n/* Return the number of elements which have been added to the dynamic\n   array.  */\n__attribute_nonnull__ ((1))\nstatic inline size_t\nDYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list)\n{\n  return list->u.dynarray_header.used;\n}\n\n/* Return a pointer to the array element at INDEX.  Terminate the\n   process if INDEX is out of bounds.  */\n__attribute_nonnull__ ((1))\nstatic inline DYNARRAY_ELEMENT *\nDYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index)\n{\n  if (__glibc_unlikely (index >= DYNARRAY_NAME (size) (list)))\n    __libc_dynarray_at_failure (DYNARRAY_NAME (size) (list), index);\n  return list->u.dynarray_header.array + index;\n}\n\n/* Return a pointer to the first array element, if any.  For a\n   zero-length array, the pointer can be NULL even though the dynamic\n   array has not entered the failure state.  */\n__attribute_nonnull__ ((1))\nstatic inline DYNARRAY_ELEMENT *\nDYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list)\n{\n  return list->u.dynarray_header.array;\n}\n\n/* Return a pointer one element past the last array element.  For a\n   zero-length array, the pointer can be NULL even though the dynamic\n   array has not entered the failure state.  */\n__attribute_nonnull__ ((1))\nstatic inline DYNARRAY_ELEMENT *\nDYNARRAY_NAME (end) (struct DYNARRAY_STRUCT *list)\n{\n  return list->u.dynarray_header.array + list->u.dynarray_header.used;\n}\n\n/* Internal function.  Slow path for the add function below.  */\nstatic void\nDYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)\n{\n  if (__glibc_unlikely\n      (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,\n                                         DYNARRAY_SCRATCH (list),\n                                         sizeof (DYNARRAY_ELEMENT))))\n    {\n      DYNARRAY_NAME (mark_failed) (list);\n      return;\n    }\n\n  /* Copy the new element and increase the array length.  */\n  list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;\n}\n\n/* Add ITEM at the end of the array, enlarging it by one element.\n   Mark *LIST as failed if the dynamic array allocation size cannot be\n   increased.  */\n__attribute_nonnull__ ((1))\nstatic inline void\nDYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)\n{\n  /* Do nothing in case of previous error.  */\n  if (DYNARRAY_NAME (has_failed) (list))\n    return;\n\n  /* Enlarge the array if necessary.  */\n  if (__glibc_unlikely (list->u.dynarray_header.used\n                        == list->u.dynarray_header.allocated))\n    {\n      DYNARRAY_NAME (add__) (list, item);\n      return;\n    }\n\n  /* Copy the new element and increase the array length.  */\n  list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;\n}\n\n/* Internal function.  Building block for the emplace functions below.\n   Assumes space for one more element in *LIST.  */\nstatic inline DYNARRAY_ELEMENT *\nDYNARRAY_NAME (emplace__tail__) (struct DYNARRAY_STRUCT *list)\n{\n  DYNARRAY_ELEMENT *result\n    = &list->u.dynarray_header.array[list->u.dynarray_header.used];\n  ++list->u.dynarray_header.used;\n#if defined (DYNARRAY_ELEMENT_INIT)\n  DYNARRAY_ELEMENT_INIT (result);\n#elif defined (DYNARRAY_ELEMENT_FREE)\n  memset (result, 0, sizeof (*result));\n#endif\n  return result;\n}\n\n/* Internal function.  Slow path for the emplace function below.  */\nstatic DYNARRAY_ELEMENT *\nDYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list)\n{\n  if (__glibc_unlikely\n      (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,\n                                         DYNARRAY_SCRATCH (list),\n                                         sizeof (DYNARRAY_ELEMENT))))\n    {\n      DYNARRAY_NAME (mark_failed) (list);\n      return NULL;\n    }\n  return DYNARRAY_NAME (emplace__tail__) (list);\n}\n\n/* Allocate a place for a new element in *LIST and return a pointer to\n   it.  The pointer can be NULL if the dynamic array cannot be\n   enlarged due to a memory allocation failure.  */\n__attribute_maybe_unused__ __attribute_warn_unused_result__\n__attribute_nonnull__ ((1))\nstatic\n/* Avoid inlining with the larger initialization code.  */\n#if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE))\ninline\n#endif\nDYNARRAY_ELEMENT *\nDYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list)\n{\n  /* Do nothing in case of previous error.  */\n  if (DYNARRAY_NAME (has_failed) (list))\n    return NULL;\n\n  /* Enlarge the array if necessary.  */\n  if (__glibc_unlikely (list->u.dynarray_header.used\n                        == list->u.dynarray_header.allocated))\n    return (DYNARRAY_NAME (emplace__) (list));\n  return DYNARRAY_NAME (emplace__tail__) (list);\n}\n\n/* Change the size of *LIST to SIZE.  If SIZE is larger than the\n   existing size, new elements are added (which can be initialized).\n   Otherwise, the list is truncated, and elements are freed.  Return\n   false on memory allocation failure (and mark *LIST as failed).  */\n__attribute_maybe_unused__ __attribute_nonnull__ ((1))\nstatic bool\nDYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)\n{\n  if (size > list->u.dynarray_header.used)\n    {\n      bool ok;\n#if defined (DYNARRAY_ELEMENT_INIT)\n      /* The new elements have to be initialized.  */\n      size_t old_size = list->u.dynarray_header.used;\n      ok = __libc_dynarray_resize (&list->u.dynarray_abstract,\n                                   size, DYNARRAY_SCRATCH (list),\n                                   sizeof (DYNARRAY_ELEMENT));\n      if (ok)\n        for (size_t i = old_size; i < size; ++i)\n          {\n            DYNARRAY_ELEMENT_INIT (&list->u.dynarray_header.array[i]);\n          }\n#elif defined (DYNARRAY_ELEMENT_FREE)\n      /* Zero initialization is needed so that the elements can be\n         safely freed.  */\n      ok = __libc_dynarray_resize_clear\n        (&list->u.dynarray_abstract, size,\n         DYNARRAY_SCRATCH (list), sizeof (DYNARRAY_ELEMENT));\n#else\n      ok =  __libc_dynarray_resize (&list->u.dynarray_abstract,\n                                    size, DYNARRAY_SCRATCH (list),\n                                    sizeof (DYNARRAY_ELEMENT));\n#endif\n      if (__glibc_unlikely (!ok))\n        DYNARRAY_NAME (mark_failed) (list);\n      return ok;\n    }\n  else\n    {\n      /* The list has shrunk in size.  Free the removed elements.  */\n      DYNARRAY_NAME (free__elements__)\n        (list->u.dynarray_header.array + size,\n         list->u.dynarray_header.used - size);\n      list->u.dynarray_header.used = size;\n      return true;\n    }\n}\n\n/* Remove the last element of LIST if it is present.  */\n__attribute_maybe_unused__ __attribute_nonnull__ ((1))\nstatic void\nDYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list)\n{\n  /* used > 0 implies that the array is the non-failed state.  */\n  if (list->u.dynarray_header.used > 0)\n    {\n      size_t new_length = list->u.dynarray_header.used - 1;\n#ifdef DYNARRAY_ELEMENT_FREE\n      DYNARRAY_ELEMENT_FREE (&list->u.dynarray_header.array[new_length]);\n#endif\n      list->u.dynarray_header.used = new_length;\n    }\n}\n\n/* Remove all elements from the list.  The elements are freed, but the\n   list itself is not.  */\n__attribute_maybe_unused__ __attribute_nonnull__ ((1))\nstatic void\nDYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)\n{\n  /* free__elements__ does nothing if the list is in the failed\n     state.  */\n  DYNARRAY_NAME (free__elements__)\n    (list->u.dynarray_header.array, list->u.dynarray_header.used);\n  list->u.dynarray_header.used = 0;\n}\n\n#ifdef DYNARRAY_FINAL_TYPE\n/* Transfer the dynamic array to a permanent location at *RESULT.\n   Returns true on success on false on allocation failure.  In either\n   case, *LIST is re-initialized and can be reused.  A NULL pointer is\n   stored in *RESULT if LIST refers to an empty list.  On success, the\n   pointer in *RESULT is heap-allocated and must be deallocated using\n   free.  */\n__attribute_maybe_unused__ __attribute_warn_unused_result__\n__attribute_nonnull__ ((1, 2))\nstatic bool\nDYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,\n                          DYNARRAY_FINAL_TYPE *result)\n{\n  struct dynarray_finalize_result res;\n  if (__libc_dynarray_finalize (&list->u.dynarray_abstract,\n                                DYNARRAY_SCRATCH (list),\n                                sizeof (DYNARRAY_ELEMENT), &res))\n    {\n      /* On success, the result owns all the data.  */\n      DYNARRAY_NAME (init) (list);\n      *result = (DYNARRAY_FINAL_TYPE) { res.array, res.length };\n      return true;\n    }\n  else\n    {\n      /* On error, we need to free all data.  */\n      DYNARRAY_FREE (list);\n      errno = ENOMEM;\n      return false;\n    }\n}\n#else /* !DYNARRAY_FINAL_TYPE */\n/* Transfer the dynamic array to a heap-allocated array and return a\n   pointer to it.  The pointer is NULL if memory allocation fails, or\n   if the array is empty, so this function should be used only for\n   arrays which are known not be empty (usually because they always\n   have a sentinel at the end).  If LENGTHP is not NULL, the array\n   length is written to *LENGTHP.  *LIST is re-initialized and can be\n   reused.  */\n__attribute_maybe_unused__ __attribute_warn_unused_result__\n__attribute_nonnull__ ((1))\nstatic DYNARRAY_ELEMENT *\nDYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp)\n{\n  struct dynarray_finalize_result res;\n  if (__libc_dynarray_finalize (&list->u.dynarray_abstract,\n                                DYNARRAY_SCRATCH (list),\n                                sizeof (DYNARRAY_ELEMENT), &res))\n    {\n      /* On success, the result owns all the data.  */\n      DYNARRAY_NAME (init) (list);\n      if (lengthp != NULL)\n        *lengthp = res.length;\n      return res.array;\n    }\n  else\n    {\n      /* On error, we need to free all data.  */\n      DYNARRAY_FREE (list);\n      errno = ENOMEM;\n      return NULL;\n    }\n}\n#endif /* !DYNARRAY_FINAL_TYPE */\n\n/* Undo macro definitions.  */\n\n#undef DYNARRAY_CONCAT0\n#undef DYNARRAY_CONCAT1\n#undef DYNARRAY_NAME\n#undef DYNARRAY_SCRATCH\n#undef DYNARRAY_HAVE_SCRATCH\n\n#undef DYNARRAY_STRUCT\n#undef DYNARRAY_ELEMENT\n#undef DYNARRAY_PREFIX\n#undef DYNARRAY_ELEMENT_FREE\n#undef DYNARRAY_ELEMENT_INIT\n#undef DYNARRAY_INITIAL_SIZE\n#undef DYNARRAY_FINAL_TYPE\n"
  },
  {
    "path": "gnulib/malloc/dynarray.h",
    "content": "/* Type-safe arrays which grow dynamically.  Shared definitions.\n   Copyright (C) 2017-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n/* To use the dynarray facility, you need to include\n   <malloc/dynarray-skeleton.c> and define the parameter macros\n   documented in that file.\n\n   A minimal example which provides a growing list of integers can be\n   defined like this:\n\n     struct int_array\n     {\n       // Pointer to result array followed by its length,\n       // as required by DYNARRAY_FINAL_TYPE.\n       int *array;\n       size_t length;\n     };\n\n     #define DYNARRAY_STRUCT dynarray_int\n     #define DYNARRAY_ELEMENT int\n     #define DYNARRAY_PREFIX dynarray_int_\n     #define DYNARRAY_FINAL_TYPE struct int_array\n     #include <malloc/dynarray-skeleton.c>\n\n   To create a three-element array with elements 1, 2, 3, use this\n   code:\n\n     struct dynarray_int dyn;\n     dynarray_int_init (&dyn);\n     for (int i = 1; i <= 3; ++i)\n       {\n         int *place = dynarray_int_emplace (&dyn);\n         assert (place != NULL);\n         *place = i;\n       }\n     struct int_array result;\n     bool ok = dynarray_int_finalize (&dyn, &result);\n     assert (ok);\n     assert (result.length == 3);\n     assert (result.array[0] == 1);\n     assert (result.array[1] == 2);\n     assert (result.array[2] == 3);\n     free (result.array);\n\n   If the elements contain resources which must be freed, define\n   DYNARRAY_ELEMENT_FREE appropriately, like this:\n\n     struct str_array\n     {\n       char **array;\n       size_t length;\n     };\n\n     #define DYNARRAY_STRUCT dynarray_str\n     #define DYNARRAY_ELEMENT char *\n     #define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr)\n     #define DYNARRAY_PREFIX dynarray_str_\n     #define DYNARRAY_FINAL_TYPE struct str_array\n     #include <malloc/dynarray-skeleton.c>\n\n   Compared to scratch buffers, dynamic arrays have the following\n   features:\n\n   - They have an element type, and are not just an untyped buffer of\n     bytes.\n\n   - When growing, previously stored elements are preserved.  (It is\n     expected that scratch_buffer_grow_preserve and\n     scratch_buffer_set_array_size eventually go away because all\n     current users are moved to dynamic arrays.)\n\n   - Scratch buffers have a more aggressive growth policy because\n     growing them typically means a retry of an operation (across an\n     NSS service module boundary), which is expensive.\n\n   - For the same reason, scratch buffers have a much larger initial\n     stack allocation.  */\n\n#ifndef _DYNARRAY_H\n#define _DYNARRAY_H\n\n#include <stdbool.h>\n#include <stddef.h>\n#include <string.h>\n\nstruct dynarray_header\n{\n  size_t used;\n  size_t allocated;\n  void *array;\n};\n\n/* Marker used in the allocated member to indicate that an error was\n   encountered.  */\nstatic inline size_t\n__dynarray_error_marker (void)\n{\n  return -1;\n}\n\n/* Internal function.  See the has_failed function in\n   dynarray-skeleton.c.  */\nstatic inline bool\n__dynarray_error (struct dynarray_header *list)\n{\n  return list->allocated == __dynarray_error_marker ();\n}\n\n/* Internal function.  Enlarge the dynamically allocated area of the\n   array to make room for one more element.  SCRATCH is a pointer to\n   the scratch area (which is not heap-allocated and must not be\n   freed).  ELEMENT_SIZE is the size, in bytes, of one element.\n   Return false on failure, true on success.  */\nbool __libc_dynarray_emplace_enlarge (struct dynarray_header *,\n                                      void *scratch, size_t element_size);\n\n/* Internal function.  Enlarge the dynamically allocated area of the\n   array to make room for at least SIZE elements (which must be larger\n   than the existing used part of the dynamic array).  SCRATCH is a\n   pointer to the scratch area (which is not heap-allocated and must\n   not be freed).  ELEMENT_SIZE is the size, in bytes, of one element.\n   Return false on failure, true on success.  */\nbool __libc_dynarray_resize (struct dynarray_header *, size_t size,\n                             void *scratch, size_t element_size);\n\n/* Internal function.  Like __libc_dynarray_resize, but clear the new\n   part of the dynamic array.  */\nbool __libc_dynarray_resize_clear (struct dynarray_header *, size_t size,\n                                   void *scratch, size_t element_size);\n\n/* Internal type.  */\nstruct dynarray_finalize_result\n{\n  void *array;\n  size_t length;\n};\n\n/* Internal function.  Copy the dynamically-allocated area to an\n   explicitly-sized heap allocation.  SCRATCH is a pointer to the\n   embedded scratch space.  ELEMENT_SIZE is the size, in bytes, of the\n   element type.  On success, true is returned, and pointer and length\n   are written to *RESULT.  On failure, false is returned.  The caller\n   has to take care of some of the memory management; this function is\n   expected to be called from dynarray-skeleton.c.  */\nbool __libc_dynarray_finalize (struct dynarray_header *list, void *scratch,\n                               size_t element_size,\n                               struct dynarray_finalize_result *result);\n\n\n/* Internal function.  Terminate the process after an index error.\n   SIZE is the number of elements of the dynamic array.  INDEX is the\n   lookup index which triggered the failure.  */\n_Noreturn void __libc_dynarray_at_failure (size_t size, size_t index);\n\n#ifndef _ISOMAC\nlibc_hidden_proto (__libc_dynarray_emplace_enlarge)\nlibc_hidden_proto (__libc_dynarray_resize)\nlibc_hidden_proto (__libc_dynarray_resize_clear)\nlibc_hidden_proto (__libc_dynarray_finalize)\nlibc_hidden_proto (__libc_dynarray_at_failure)\n#endif\n\n#endif /* _DYNARRAY_H */\n"
  },
  {
    "path": "gnulib/malloc/dynarray_at_failure.c",
    "content": "/* Report an dynamic array index out of bounds condition.\n   Copyright (C) 2017-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifndef _LIBC\n# include <libc-config.h>\n#endif\n\n#include <dynarray.h>\n#include <stdio.h>\n#include <stdlib.h>\n\nvoid\n__libc_dynarray_at_failure (size_t size, size_t index)\n{\n#ifdef _LIBC\n  char buf[200];\n  __snprintf (buf, sizeof (buf), \"Fatal glibc error: \"\n              \"array index %zu not less than array length %zu\\n\",\n              index, size);\n#else\n abort ();\n#endif\n}\nlibc_hidden_def (__libc_dynarray_at_failure)\n"
  },
  {
    "path": "gnulib/malloc/dynarray_emplace_enlarge.c",
    "content": "/* Increase the size of a dynamic array in preparation of an emplace operation.\n   Copyright (C) 2017-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifndef _LIBC\n# include <libc-config.h>\n#endif\n\n#include <dynarray.h>\n#include <errno.h>\n#include <intprops.h>\n#include <stdlib.h>\n#include <string.h>\n\nbool\n__libc_dynarray_emplace_enlarge (struct dynarray_header *list,\n                                 void *scratch, size_t element_size)\n{\n  size_t new_allocated;\n  if (list->allocated == 0)\n    {\n      /* No scratch buffer provided.  Choose a reasonable default\n         size.  */\n      if (element_size < 4)\n        new_allocated = 16;\n      else if (element_size < 8)\n        new_allocated = 8;\n      else\n        new_allocated = 4;\n    }\n  else\n    /* Increase the allocated size, using an exponential growth\n       policy.  */\n    {\n      new_allocated = list->allocated + list->allocated / 2 + 1;\n      if (new_allocated <= list->allocated)\n        {\n          /* Overflow.  */\n          __set_errno (ENOMEM);\n          return false;\n        }\n    }\n\n  size_t new_size;\n  if (INT_MULTIPLY_WRAPV (new_allocated, element_size, &new_size))\n    return false;\n  void *new_array;\n  if (list->array == scratch)\n    {\n      /* The previous array was not heap-allocated.  */\n      new_array = malloc (new_size);\n      if (new_array != NULL && list->array != NULL)\n        memcpy (new_array, list->array, list->used * element_size);\n    }\n  else\n    new_array = realloc (list->array, new_size);\n  if (new_array == NULL)\n    return false;\n  list->array = new_array;\n  list->allocated = new_allocated;\n  return true;\n}\nlibc_hidden_def (__libc_dynarray_emplace_enlarge)\n"
  },
  {
    "path": "gnulib/malloc/dynarray_finalize.c",
    "content": "/* Copy the dynamically-allocated area to an explicitly-sized heap allocation.\n   Copyright (C) 2017-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifndef _LIBC\n# include <libc-config.h>\n#endif\n\n#include <dynarray.h>\n#include <stdlib.h>\n#include <string.h>\n\nbool\n__libc_dynarray_finalize (struct dynarray_header *list,\n                          void *scratch, size_t element_size,\n                          struct dynarray_finalize_result *result)\n{\n  if (__dynarray_error (list))\n    /* The caller will reported the deferred error.  */\n    return false;\n\n  size_t used = list->used;\n\n  /* Empty list.  */\n  if (used == 0)\n    {\n      /* An empty list could still be backed by a heap-allocated\n         array.  Free it if necessary.  */\n      if (list->array != scratch)\n        free (list->array);\n      *result = (struct dynarray_finalize_result) { NULL, 0 };\n      return true;\n    }\n\n  size_t allocation_size = used * element_size;\n  void *heap_array = malloc (allocation_size);\n  if (heap_array != NULL)\n    {\n      /* The new array takes ownership of the strings.  */\n      if (list->array != NULL)\n        memcpy (heap_array, list->array, allocation_size);\n      if (list->array != scratch)\n        free (list->array);\n      *result = (struct dynarray_finalize_result)\n        { .array = heap_array, .length = used };\n      return true;\n    }\n  else\n    /* The caller will perform the freeing operation.  */\n    return false;\n}\nlibc_hidden_def (__libc_dynarray_finalize)\n"
  },
  {
    "path": "gnulib/malloc/dynarray_resize.c",
    "content": "/* Increase the size of a dynamic array.\n   Copyright (C) 2017-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifndef _LIBC\n# include <libc-config.h>\n#endif\n\n#include <dynarray.h>\n#include <errno.h>\n#include <intprops.h>\n#include <stdlib.h>\n#include <string.h>\n\nbool\n__libc_dynarray_resize (struct dynarray_header *list, size_t size,\n                        void *scratch, size_t element_size)\n{\n  /* The existing allocation provides sufficient room.  */\n  if (size <= list->allocated)\n    {\n      list->used = size;\n      return true;\n    }\n\n  /* Otherwise, use size as the new allocation size.  The caller is\n     expected to provide the final size of the array, so there is no\n     over-allocation here.  */\n\n  size_t new_size_bytes;\n  if (INT_MULTIPLY_WRAPV (size, element_size, &new_size_bytes))\n    {\n      /* Overflow.  */\n      __set_errno (ENOMEM);\n      return false;\n    }\n  void *new_array;\n  if (list->array == scratch)\n    {\n      /* The previous array was not heap-allocated.  */\n      new_array = malloc (new_size_bytes);\n      if (new_array != NULL && list->array != NULL)\n        memcpy (new_array, list->array, list->used * element_size);\n    }\n  else\n    new_array = realloc (list->array, new_size_bytes);\n  if (new_array == NULL)\n    return false;\n  list->array = new_array;\n  list->allocated = size;\n  list->used = size;\n  return true;\n}\nlibc_hidden_def (__libc_dynarray_resize)\n"
  },
  {
    "path": "gnulib/malloc/dynarray_resize_clear.c",
    "content": "/* Increase the size of a dynamic array and clear the new part.\n   Copyright (C) 2017-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifndef _LIBC\n# include <libc-config.h>\n#endif\n\n#include <dynarray.h>\n#include <string.h>\n\nbool\n__libc_dynarray_resize_clear (struct dynarray_header *list, size_t size,\n                              void *scratch, size_t element_size)\n{\n  size_t old_size = list->used;\n  if (!__libc_dynarray_resize (list, size, scratch, element_size))\n    return false;\n  /* __libc_dynarray_resize already checked for overflow.  */\n  char *array = list->array;\n  memset (array + (old_size * element_size), 0,\n          (size - old_size) * element_size);\n  return true;\n}\nlibc_hidden_def (__libc_dynarray_resize_clear)\n"
  },
  {
    "path": "gnulib/mbrtowc-impl-utf8.h",
    "content": "/* Convert multibyte character to wide character.\n   Copyright (C) 1999-2002, 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2008.  */\n\n/* This file contains the part of the body of the mbrtowc and mbrtoc32 functions\n   that handles the special case of the UTF-8 encoding.  */\n\n        /* Cf. unistr/u8-mbtouc.c.  */\n        unsigned char c = (unsigned char) p[0];\n\n        if (c < 0x80)\n          {\n            if (pwc != NULL)\n              *pwc = c;\n            res = (c == 0 ? 0 : 1);\n            goto success;\n          }\n        if (c >= 0xc2)\n          {\n            if (c < 0xe0)\n              {\n                if (m == 1)\n                  goto incomplete;\n                else /* m >= 2 */\n                  {\n                    unsigned char c2 = (unsigned char) p[1];\n\n                    if ((c2 ^ 0x80) < 0x40)\n                      {\n                        if (pwc != NULL)\n                          *pwc = ((unsigned int) (c & 0x1f) << 6)\n                                 | (unsigned int) (c2 ^ 0x80);\n                        res = 2;\n                        goto success;\n                      }\n                  }\n              }\n            else if (c < 0xf0)\n              {\n                if (m == 1)\n                  goto incomplete;\n                else\n                  {\n                    unsigned char c2 = (unsigned char) p[1];\n\n                    if ((c2 ^ 0x80) < 0x40\n                        && (c >= 0xe1 || c2 >= 0xa0)\n                        && (c != 0xed || c2 < 0xa0))\n                      {\n                        if (m == 2)\n                          goto incomplete;\n                        else /* m >= 3 */\n                          {\n                            unsigned char c3 = (unsigned char) p[2];\n\n                            if ((c3 ^ 0x80) < 0x40)\n                              {\n                                unsigned int wc =\n                                  (((unsigned int) (c & 0x0f) << 12)\n                                   | ((unsigned int) (c2 ^ 0x80) << 6)\n                                   | (unsigned int) (c3 ^ 0x80));\n\n                                if (FITS_IN_CHAR_TYPE (wc))\n                                  {\n                                    if (pwc != NULL)\n                                      *pwc = wc;\n                                    res = 3;\n                                    goto success;\n                                  }\n                              }\n                          }\n                      }\n                  }\n              }\n            else if (c <= 0xf4)\n              {\n                if (m == 1)\n                  goto incomplete;\n                else\n                  {\n                    unsigned char c2 = (unsigned char) p[1];\n\n                    if ((c2 ^ 0x80) < 0x40\n                        && (c >= 0xf1 || c2 >= 0x90)\n                        && (c < 0xf4 || (/* c == 0xf4 && */ c2 < 0x90)))\n                      {\n                        if (m == 2)\n                          goto incomplete;\n                        else\n                          {\n                            unsigned char c3 = (unsigned char) p[2];\n\n                            if ((c3 ^ 0x80) < 0x40)\n                              {\n                                if (m == 3)\n                                  goto incomplete;\n                                else /* m >= 4 */\n                                  {\n                                    unsigned char c4 = (unsigned char) p[3];\n\n                                    if ((c4 ^ 0x80) < 0x40)\n                                      {\n                                        unsigned int wc =\n                                          (((unsigned int) (c & 0x07) << 18)\n                                           | ((unsigned int) (c2 ^ 0x80) << 12)\n                                           | ((unsigned int) (c3 ^ 0x80) << 6)\n                                           | (unsigned int) (c4 ^ 0x80));\n\n                                        if (FITS_IN_CHAR_TYPE (wc))\n                                          {\n                                            if (pwc != NULL)\n                                              *pwc = wc;\n                                            res = 4;\n                                            goto success;\n                                          }\n                                      }\n                                  }\n                              }\n                          }\n                      }\n                  }\n              }\n          }\n        goto invalid;\n"
  },
  {
    "path": "gnulib/mbrtowc-impl.h",
    "content": "/* Convert multibyte character to wide character.\n   Copyright (C) 1999-2002, 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2008.  */\n\n/* This file contains the body of the mbrtowc and mbrtoc32 functions,\n   when GNULIB_defined_mbstate_t is defined.  */\n\n  char *pstate = (char *)ps;\n\n  if (s == NULL)\n    {\n      pwc = NULL;\n      s = \"\";\n      n = 1;\n    }\n\n  if (n == 0)\n    return (size_t)(-2);\n\n  /* Here n > 0.  */\n\n  if (pstate == NULL)\n    pstate = internal_state;\n\n  {\n    size_t nstate = pstate[0];\n    char buf[4];\n    const char *p;\n    size_t m;\n    enc_t enc;\n    int res;\n\n    switch (nstate)\n      {\n      case 0:\n        p = s;\n        m = n;\n        break;\n      case 3:\n        buf[2] = pstate[3];\n        FALLTHROUGH;\n      case 2:\n        buf[1] = pstate[2];\n        FALLTHROUGH;\n      case 1:\n        buf[0] = pstate[1];\n        p = buf;\n        m = nstate;\n        buf[m++] = s[0];\n        if (n >= 2 && m < 4)\n          {\n            buf[m++] = s[1];\n            if (n >= 3 && m < 4)\n              buf[m++] = s[2];\n          }\n        break;\n      default:\n        errno = EINVAL;\n        return (size_t)(-1);\n      }\n\n    /* Here m > 0.  */\n\n    enc = locale_encoding_classification ();\n\n    if (enc == enc_utf8) /* UTF-8 */\n      {\n        /* Achieve\n             - multi-thread safety and\n             - the ability to produce wide character values > WCHAR_MAX\n           by not calling mbtowc() at all.  */\n#include \"mbrtowc-impl-utf8.h\"\n      }\n    else\n      {\n        /* The hidden internal state of mbtowc would make this function not\n           multi-thread safe.  Achieve multi-thread safety through a lock.  */\n        wchar_t wc;\n        res = mbtowc_with_lock (&wc, p, m);\n\n        if (res >= 0)\n          {\n            if ((wc == 0) != (res == 0))\n              abort ();\n            if (pwc != NULL)\n              *pwc = wc;\n            goto success;\n          }\n\n        /* mbtowc does not distinguish between invalid and incomplete multibyte\n           sequences.  But mbrtowc needs to make this distinction.\n           There are two possible approaches:\n             - Use iconv() and its return value.\n             - Use built-in knowledge about the possible encodings.\n           Given the low quality of implementation of iconv() on the systems\n           that lack mbrtowc(), we use the second approach.\n           The possible encodings are:\n             - 8-bit encodings,\n             - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS,\n             - UTF-8 (already handled above).\n           Use specialized code for each.  */\n        if (m >= 4 || m >= MB_CUR_MAX)\n          goto invalid;\n        /* Here MB_CUR_MAX > 1 and 0 < m < 4.  */\n        switch (enc)\n          {\n          /* As a reference for this code, you can use the GNU libiconv\n             implementation.  Look for uses of the RET_TOOFEW macro.  */\n\n          case enc_eucjp: /* EUC-JP */\n            {\n              if (m == 1)\n                {\n                  unsigned char c = (unsigned char) p[0];\n\n                  if ((c >= 0xa1 && c < 0xff) || c == 0x8e || c == 0x8f)\n                    goto incomplete;\n                }\n              if (m == 2)\n                {\n                  unsigned char c = (unsigned char) p[0];\n\n                  if (c == 0x8f)\n                    {\n                      unsigned char c2 = (unsigned char) p[1];\n\n                      if (c2 >= 0xa1 && c2 < 0xff)\n                        goto incomplete;\n                    }\n                }\n              goto invalid;\n            }\n\n          case enc_94: /* EUC-KR, GB2312, BIG5 */\n            {\n              if (m == 1)\n                {\n                  unsigned char c = (unsigned char) p[0];\n\n                  if (c >= 0xa1 && c < 0xff)\n                    goto incomplete;\n                }\n              goto invalid;\n            }\n\n          case enc_euctw: /* EUC-TW */\n            {\n              if (m == 1)\n                {\n                  unsigned char c = (unsigned char) p[0];\n\n                  if ((c >= 0xa1 && c < 0xff) || c == 0x8e)\n                    goto incomplete;\n                }\n              else /* m == 2 || m == 3 */\n                {\n                  unsigned char c = (unsigned char) p[0];\n\n                  if (c == 0x8e)\n                    goto incomplete;\n                }\n              goto invalid;\n            }\n\n          case enc_gb18030: /* GB18030 */\n            {\n              if (m == 1)\n                {\n                  unsigned char c = (unsigned char) p[0];\n\n                  if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe))\n                    goto incomplete;\n                }\n              else /* m == 2 || m == 3 */\n                {\n                  unsigned char c = (unsigned char) p[0];\n\n                  if (c >= 0x90 && c <= 0xe3)\n                    {\n                      unsigned char c2 = (unsigned char) p[1];\n\n                      if (c2 >= 0x30 && c2 <= 0x39)\n                        {\n                          if (m == 2)\n                            goto incomplete;\n                          else /* m == 3 */\n                            {\n                              unsigned char c3 = (unsigned char) p[2];\n\n                              if (c3 >= 0x81 && c3 <= 0xfe)\n                                goto incomplete;\n                            }\n                        }\n                    }\n                }\n              goto invalid;\n            }\n\n          case enc_sjis: /* SJIS */\n            {\n              if (m == 1)\n                {\n                  unsigned char c = (unsigned char) p[0];\n\n                  if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)\n                      || (c >= 0xf0 && c <= 0xf9))\n                    goto incomplete;\n                }\n              goto invalid;\n            }\n\n          default:\n            /* An unknown multibyte encoding.  */\n            goto incomplete;\n          }\n      }\n\n   success:\n    /* res >= 0 is the corrected return value of\n       mbtowc_with_lock (&wc, p, m).  */\n    if (nstate >= (res > 0 ? res : 1))\n      abort ();\n    res -= nstate;\n    pstate[0] = 0;\n    return res;\n\n   incomplete:\n    {\n      size_t k = nstate;\n      /* Here 0 <= k < m < 4.  */\n      pstate[++k] = s[0];\n      if (k < m)\n        {\n          pstate[++k] = s[1];\n          if (k < m)\n            pstate[++k] = s[2];\n        }\n      if (k != m)\n        abort ();\n    }\n    pstate[0] = m;\n    return (size_t)(-2);\n\n   invalid:\n    errno = EILSEQ;\n    /* The conversion state is undefined, says POSIX.  */\n    return (size_t)(-1);\n  }\n"
  },
  {
    "path": "gnulib/mbrtowc.c",
    "content": "/* Convert multibyte character to wide character.\n   Copyright (C) 1999-2002, 2005-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 2008.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <wchar.h>\n\n#if GNULIB_defined_mbstate_t\n/* Implement mbrtowc() on top of mbtowc() for the non-UTF-8 locales\n   and directly for the UTF-8 locales.  */\n\n# include <errno.h>\n# include <stdint.h>\n# include <stdlib.h>\n\n# if defined _WIN32 && !defined __CYGWIN__\n\n#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#  include <windows.h>\n\n# elif HAVE_PTHREAD_API\n\n#  include <pthread.h>\n#  if HAVE_THREADS_H && HAVE_WEAK_SYMBOLS\n#   include <threads.h>\n#   pragma weak thrd_exit\n#   define c11_threads_in_use() (thrd_exit != NULL)\n#  else\n#   define c11_threads_in_use() 0\n#  endif\n\n# elif HAVE_THREADS_H\n\n#  include <threads.h>\n\n# endif\n\n# include \"attribute.h\"\n# include \"verify.h\"\n# include \"lc-charset-dispatch.h\"\n# include \"mbtowc-lock.h\"\n\nverify (sizeof (mbstate_t) >= 4);\nstatic char internal_state[4];\n\nsize_t\nmbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)\n{\n# define FITS_IN_CHAR_TYPE(wc)  ((wc) <= WCHAR_MAX)\n# include \"mbrtowc-impl.h\"\n}\n\n#else\n/* Override the system's mbrtowc() function.  */\n\n# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ\n#  include \"hard-locale.h\"\n#  include <locale.h>\n# endif\n\n# undef mbrtowc\n\nsize_t\nrpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)\n{\n  size_t ret;\n  wchar_t wc;\n\n# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG || MBRTOWC_EMPTY_INPUT_BUG\n  if (s == NULL)\n    {\n      pwc = NULL;\n      s = \"\";\n      n = 1;\n    }\n# endif\n\n# if MBRTOWC_EMPTY_INPUT_BUG\n  if (n == 0)\n    return (size_t) -2;\n# endif\n\n  if (! pwc)\n    pwc = &wc;\n\n# if MBRTOWC_RETVAL_BUG\n  {\n    static mbstate_t internal_state;\n\n    /* Override mbrtowc's internal state.  We cannot call mbsinit() on the\n       hidden internal state, but we can call it on our variable.  */\n    if (ps == NULL)\n      ps = &internal_state;\n\n    if (!mbsinit (ps))\n      {\n        /* Parse the rest of the multibyte character byte for byte.  */\n        size_t count = 0;\n        for (; n > 0; s++, n--)\n          {\n            ret = mbrtowc (&wc, s, 1, ps);\n\n            if (ret == (size_t)(-1))\n              return (size_t)(-1);\n            count++;\n            if (ret != (size_t)(-2))\n              {\n                /* The multibyte character has been completed.  */\n                *pwc = wc;\n                return (wc == 0 ? 0 : count);\n              }\n          }\n        return (size_t)(-2);\n      }\n  }\n# endif\n\n# if MBRTOWC_STORES_INCOMPLETE_BUG\n  ret = mbrtowc (&wc, s, n, ps);\n  if (ret < (size_t) -2 && pwc != NULL)\n    *pwc = wc;\n# else\n  ret = mbrtowc (pwc, s, n, ps);\n# endif\n\n# if MBRTOWC_NUL_RETVAL_BUG\n  if (ret < (size_t) -2 && !*pwc)\n    return 0;\n# endif\n\n# if MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ\n  if ((size_t) -2 <= ret && n != 0 && ! hard_locale (LC_CTYPE))\n    {\n      unsigned char uc = *s;\n      *pwc = uc;\n      return 1;\n    }\n# endif\n\n  return ret;\n}\n\n#endif\n"
  },
  {
    "path": "gnulib/mbsinit.c",
    "content": "/* Test for initial conversion state.\n   Copyright (C) 2008-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 2008.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <wchar.h>\n\n#include \"verify.h\"\n\n#if GNULIB_defined_mbstate_t\n\n/* Platforms that lack mbsinit() also lack mbrlen(), mbrtowc(), mbsrtowcs()\n   and wcrtomb(), wcsrtombs().\n   We assume that\n     - sizeof (mbstate_t) >= 4,\n     - only stateless encodings are supported (such as UTF-8 and EUC-JP, but\n       not ISO-2022 variants),\n     - for each encoding, the number of bytes for a wide character is <= 4.\n       (This maximum is attained for UTF-8, GB18030, EUC-TW.)\n   We define the meaning of mbstate_t as follows:\n     - In mb -> wc direction, mbstate_t's first byte contains the number of\n       buffered bytes (in the range 0..3), followed by up to 3 buffered bytes.\n       See mbrtowc.c.\n     - In wc -> mb direction, mbstate_t contains no information. In other\n       words, it is always in the initial state.  */\n\nverify (sizeof (mbstate_t) >= 4);\n\nint\nmbsinit (const mbstate_t *ps)\n{\n  const char *pstate = (const char *)ps;\n\n  return pstate == NULL || pstate[0] == 0;\n}\n\n#else\n\nint\nmbsinit (const mbstate_t *ps)\n{\n# if defined _WIN32 && !defined __CYGWIN__\n  /* Native Windows.  */\n  /* MSVC defines 'mbstate_t' as an 8-byte struct; the first 4 bytes matter.\n     On mingw, 'mbstate_t' is sometimes defined as 'int', sometimes defined as\n     an 8-byte struct, of which the first 4 bytes matter.  */\n  return ps == NULL || *(const unsigned int *)ps == 0;\n# else\n  /* Minix, HP-UX 11.00, Solaris 2.6, Interix, ...  */\n  /* Maybe this definition works, maybe not...  */\n  return ps == NULL || *(const char *)ps == 0;\n# endif\n}\n\n#endif\n"
  },
  {
    "path": "gnulib/mbsrtowcs-impl.h",
    "content": "/* Convert string to wide string.\n   Copyright (C) 2008-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 2008.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\nsize_t\nFUNC (DCHAR_T *dest, const char **srcp, size_t len, mbstate_t *ps)\n{\n  if (ps == NULL)\n    ps = &INTERNAL_STATE;\n  {\n    const char *src = *srcp;\n\n    if (dest != NULL)\n      {\n        DCHAR_T *destptr = dest;\n\n        for (; len > 0; destptr++, len--)\n          {\n            size_t src_avail;\n            size_t ret;\n\n            /* An optimized variant of\n               src_avail = strnlen1 (src, MB_LEN_MAX);  */\n            if (src[0] == '\\0')\n              src_avail = 1;\n            else if (src[1] == '\\0')\n              src_avail = 2;\n            else if (src[2] == '\\0')\n              src_avail = 3;\n            else if (MB_LEN_MAX <= 4 || src[3] == '\\0')\n              src_avail = 4;\n            else\n              src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4);\n\n            /* Parse the next multibyte character.  */\n            ret = MBRTOWC (destptr, src, src_avail, ps);\n\n            if (ret == (size_t)(-2))\n              /* Encountered a multibyte character that extends past a '\\0' byte\n                 or that is longer than MB_LEN_MAX bytes.  Cannot happen.  */\n              abort ();\n\n            if (ret == (size_t)(-1))\n              goto bad_input;\n            if (ret == 0)\n              {\n                src = NULL;\n                /* Here mbsinit (ps).  */\n                break;\n              }\n            src += ret;\n          }\n\n        *srcp = src;\n        return destptr - dest;\n      }\n    else\n      {\n        /* Ignore dest and len, don't store *srcp at the end, and\n           don't clobber *ps.  */\n        mbstate_t state = *ps;\n        size_t totalcount = 0;\n\n        for (;; totalcount++)\n          {\n            size_t src_avail;\n            size_t ret;\n\n            /* An optimized variant of\n               src_avail = strnlen1 (src, MB_LEN_MAX);  */\n            if (src[0] == '\\0')\n              src_avail = 1;\n            else if (src[1] == '\\0')\n              src_avail = 2;\n            else if (src[2] == '\\0')\n              src_avail = 3;\n            else if (MB_LEN_MAX <= 4 || src[3] == '\\0')\n              src_avail = 4;\n            else\n              src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4);\n\n            /* Parse the next multibyte character.  */\n            ret = MBRTOWC (NULL, src, src_avail, &state);\n\n            if (ret == (size_t)(-2))\n              /* Encountered a multibyte character that extends past a '\\0' byte\n                 or that is longer than MB_LEN_MAX bytes.  Cannot happen.  */\n              abort ();\n\n            if (ret == (size_t)(-1))\n              goto bad_input2;\n            if (ret == 0)\n              {\n                /* Here mbsinit (&state).  */\n                break;\n              }\n            src += ret;\n          }\n\n        return totalcount;\n      }\n\n   bad_input:\n    *srcp = src;\n   bad_input2:\n    errno = EILSEQ;\n    return (size_t)(-1);\n  }\n}\n"
  },
  {
    "path": "gnulib/mbsrtowcs-state.c",
    "content": "/* Convert string to wide string.\n   Copyright (C) 2008-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 2008.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n#include <wchar.h>\n\n/* Internal state used by the functions mbsrtowcs() and mbsnrtowcs().  */\nmbstate_t _gl_mbsrtowcs_state\n/* The state must initially be in the \"initial state\"; so, zero-initialize it.\n   On most systems, putting it into BSS is sufficient.  Not so on Mac OS X 10.3,\n   see <https://lists.gnu.org/r/bug-gnulib/2009-01/msg00329.html>.\n   When it needs an initializer, use 0 or {0} as initializer? 0 only works\n   when mbstate_t is a scalar type (such as when gnulib defines it, or on\n   AIX, IRIX, mingw). {0} works as an initializer in all cases: for a struct\n   or union type, but also for a scalar type (ISO C 99, 6.7.8.(11)).  */\n#if defined __ELF__\n  /* On ELF systems, variables in BSS behave well.  */\n#else\n  /* Use braces, to be on the safe side.  */\n  = { 0 }\n#endif\n  ;\n"
  },
  {
    "path": "gnulib/mbsrtowcs.c",
    "content": "/* Convert string to wide string.\n   Copyright (C) 2008-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 2008.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <wchar.h>\n\n#include <errno.h>\n#include <limits.h>\n#include <stdlib.h>\n\n#include \"strnlen1.h\"\n\n\nextern mbstate_t _gl_mbsrtowcs_state;\n\n#define FUNC mbsrtowcs\n#define DCHAR_T wchar_t\n#define INTERNAL_STATE _gl_mbsrtowcs_state\n#define MBRTOWC mbrtowc\n#include \"mbsrtowcs-impl.h\"\n"
  },
  {
    "path": "gnulib/mbtowc-impl.h",
    "content": "/* Convert multibyte character to wide character.\n   Copyright (C) 2011-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 2011.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* We don't need a static internal state, because the encoding is not state\n   dependent, and when mbrtowc returns (size_t)(-2). we throw the result\n   away. */\n\nint\nmbtowc (wchar_t *pwc, const char *s, size_t n)\n{\n  if (s == NULL)\n    return 0;\n  else\n    {\n      mbstate_t state;\n      wchar_t wc;\n      size_t result;\n\n      memset (&state, 0, sizeof (mbstate_t));\n      result = mbrtowc (&wc, s, n, &state);\n      if (result == (size_t)-1 || result == (size_t)-2)\n        {\n          errno = EILSEQ;\n          return -1;\n        }\n      if (pwc != NULL)\n        *pwc = wc;\n      return (wc == 0 ? 0 : result);\n    }\n}\n"
  },
  {
    "path": "gnulib/mbtowc-lock.c",
    "content": "/* Return the internal lock used by mbrtowc and mbrtoc32.\n   Copyright (C) 2019-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2019-2020.  */\n\n#include <config.h>\n\n/* When it is known that the gl_get_mbtowc_lock function is defined\n   by a dependency library, it should not be defined here.  */\n#if OMIT_MBTOWC_LOCK\n\n/* This declaration is solely to ensure that after preprocessing\n   this file is never empty.  */\ntypedef int dummy;\n\n#else\n\n/* This file defines the internal lock used by mbrtowc and mbrtoc32.\n   It is a separate compilation unit, so that only one copy of it is\n   present when linking statically.  */\n\n/* Prohibit renaming this symbol.  */\n# undef gl_get_mbtowc_lock\n\n/* Macro for exporting a symbol (function, not variable) defined in this file,\n   when compiled into a shared library.  */\n# ifndef DLL_EXPORTED\n#  if HAVE_VISIBILITY\n  /* Override the effect of the compiler option '-fvisibility=hidden'.  */\n#   define DLL_EXPORTED __attribute__((__visibility__(\"default\")))\n#  elif defined _WIN32 || defined __CYGWIN__\n#   define DLL_EXPORTED __declspec(dllexport)\n#  else\n#   define DLL_EXPORTED\n#  endif\n# endif\n\n# if defined _WIN32 && !defined __CYGWIN__\n\n#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#  include <windows.h>\n\n#  include \"windows-initguard.h\"\n\n/* The return type is a 'CRITICAL_SECTION *', not a 'glwthread_mutex_t *',\n   because the latter is not guaranteed to be a stable ABI in the future.  */\n\n/* Make sure the function gets exported from DLLs.  */\nDLL_EXPORTED CRITICAL_SECTION *gl_get_mbtowc_lock (void);\n\nstatic glwthread_initguard_t guard = GLWTHREAD_INITGUARD_INIT;\nstatic CRITICAL_SECTION lock;\n\n/* Returns the internal lock used by mbrtowc and mbrtoc32.  */\nCRITICAL_SECTION *\ngl_get_mbtowc_lock (void)\n{\n  if (!guard.done)\n    {\n      if (InterlockedIncrement (&guard.started) == 0)\n        {\n          /* This thread is the first one to need the lock.  Initialize it.  */\n          InitializeCriticalSection (&lock);\n          guard.done = 1;\n        }\n      else\n        {\n          /* Don't let guard.started grow and wrap around.  */\n          InterlockedDecrement (&guard.started);\n          /* Yield the CPU while waiting for another thread to finish\n             initializing this mutex.  */\n          while (!guard.done)\n            Sleep (0);\n        }\n    }\n  return &lock;\n}\n\n# elif HAVE_PTHREAD_API\n\n#  include <pthread.h>\n\nstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;\n\n/* Make sure the function gets exported from shared libraries.  */\nDLL_EXPORTED pthread_mutex_t *gl_get_mbtowc_lock (void);\n\n/* Returns the internal lock used by mbrtowc and mbrtoc32.  */\npthread_mutex_t *\ngl_get_mbtowc_lock (void)\n{\n  return &mutex;\n}\n\n# elif HAVE_THREADS_H\n\n#  include <threads.h>\n#  include <stdlib.h>\n\nstatic int volatile init_needed = 1;\nstatic once_flag init_once = ONCE_FLAG_INIT;\nstatic mtx_t mutex;\n\nstatic void\natomic_init (void)\n{\n  if (mtx_init (&mutex, mtx_plain) != thrd_success)\n    abort ();\n  init_needed = 0;\n}\n\n/* Make sure the function gets exported from shared libraries.  */\nDLL_EXPORTED mtx_t *gl_get_mbtowc_lock (void);\n\n/* Returns the internal lock used by mbrtowc and mbrtoc32.  */\nmtx_t *\ngl_get_mbtowc_lock (void)\n{\n  if (init_needed)\n    call_once (&init_once, atomic_init);\n  return &mutex;\n}\n\n# endif\n\n# if (defined _WIN32 || defined __CYGWIN__) && !defined _MSC_VER\n/* Make sure the '__declspec(dllimport)' in mbrtowc.c and mbrtoc32.c does not\n   cause a link failure when no DLLs are involved.  */\n#  if defined _WIN64 || defined _LP64\n#   define IMP(x) __imp_##x\n#  else\n#   define IMP(x) _imp__##x\n#  endif\nvoid * IMP(gl_get_mbtowc_lock) = &gl_get_mbtowc_lock;\n# endif\n\n#endif\n"
  },
  {
    "path": "gnulib/mbtowc-lock.h",
    "content": "/* Use the internal lock used by mbrtowc and mbrtoc32.\n   Copyright (C) 2019-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2019-2020.  */\n\n/* Use a lock, so that no two threads can invoke mbtowc at the same time.  */\n\nstatic inline int\nmbtowc_unlocked (wchar_t *pwc, const char *p, size_t m)\n{\n  /* Put the hidden internal state of mbtowc into its initial state.\n     This is needed at least with glibc, uClibc, and MSVC CRT.\n     See <https://sourceware.org/bugzilla/show_bug.cgi?id=9674>.  */\n  mbtowc (NULL, NULL, 0);\n\n  return mbtowc (pwc, p, m);\n}\n\n/* Prohibit renaming this symbol.  */\n#undef gl_get_mbtowc_lock\n\n#if GNULIB_MBRTOWC_SINGLE_THREAD\n\n/* All uses of this function are in a single thread.  No locking needed.  */\n\nstatic int\nmbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)\n{\n  return mbtowc_unlocked (pwc, p, m);\n}\n\n#elif defined _WIN32 && !defined __CYGWIN__\n\nextern __declspec(dllimport) CRITICAL_SECTION *gl_get_mbtowc_lock (void);\n\nstatic int\nmbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)\n{\n  CRITICAL_SECTION *lock = gl_get_mbtowc_lock ();\n  int ret;\n\n  EnterCriticalSection (lock);\n  ret = mbtowc_unlocked (pwc, p, m);\n  LeaveCriticalSection (lock);\n\n  return ret;\n}\n\n#elif HAVE_PTHREAD_API /* AIX, IRIX, Cygwin */\n\nextern\n# if defined _WIN32 || defined __CYGWIN__\n  __declspec(dllimport)\n# endif\n  pthread_mutex_t *gl_get_mbtowc_lock (void);\n\n# if HAVE_WEAK_SYMBOLS /* IRIX */\n\n   /* Avoid the need to link with '-lpthread'.  */\n#  pragma weak pthread_mutex_lock\n#  pragma weak pthread_mutex_unlock\n\n   /* Determine whether libpthread is in use.  */\n#  pragma weak pthread_mutexattr_gettype\n   /* See the comments in lock.h.  */\n#  define pthread_in_use() \\\n     (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())\n\n# else\n#  define pthread_in_use() 1\n# endif\n\nstatic int\nmbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)\n{\n  if (pthread_in_use())\n    {\n      pthread_mutex_t *lock = gl_get_mbtowc_lock ();\n      int ret;\n\n      if (pthread_mutex_lock (lock))\n        abort ();\n      ret = mbtowc_unlocked (pwc, p, m);\n      if (pthread_mutex_unlock (lock))\n        abort ();\n\n      return ret;\n    }\n  else\n    return mbtowc_unlocked (pwc, p, m);\n}\n\n#elif HAVE_THREADS_H\n\nextern mtx_t *gl_get_mbtowc_lock (void);\n\nstatic int\nmbtowc_with_lock (wchar_t *pwc, const char *p, size_t m)\n{\n  mtx_t *lock = gl_get_mbtowc_lock ();\n  int ret;\n\n  if (mtx_lock (lock) != thrd_success)\n    abort ();\n  ret = mbtowc_unlocked (pwc, p, m);\n  if (mtx_unlock (lock) != thrd_success)\n    abort ();\n\n  return ret;\n}\n\n#endif\n"
  },
  {
    "path": "gnulib/mbtowc.c",
    "content": "/* Convert multibyte character to wide character.\n   Copyright (C) 2011-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 2011.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n#include <stdlib.h>\n\n#include <errno.h>\n#include <string.h>\n#include <wchar.h>\n\n#include \"mbtowc-impl.h\"\n"
  },
  {
    "path": "gnulib/memchr.c",
    "content": "/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2021\n   Free Software Foundation, Inc.\n\n   Based on strlen implementation by Torbjorn Granlund (tege@sics.se),\n   with help from Dan Sahlin (dan@sics.se) and\n   commentary by Jim Blandy (jimb@ai.mit.edu);\n   adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu),\n   and implemented by Roland McGrath (roland@ai.mit.edu).\n\n   NOTE: The canonical source of this file is maintained with the GNU C Library.\n   Bugs can be reported to bug-glibc@prep.ai.mit.edu.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _LIBC\n# include <config.h>\n#endif\n\n#include <string.h>\n\n#include <stddef.h>\n\n#if defined _LIBC\n# include <memcopy.h>\n#else\n# define reg_char char\n#endif\n\n#include <limits.h>\n\n#if HAVE_BP_SYM_H || defined _LIBC\n# include <bp-sym.h>\n#else\n# define BP_SYM(sym) sym\n#endif\n\n#undef __memchr\n#ifdef _LIBC\n# undef memchr\n#endif\n\n#ifndef weak_alias\n# define __memchr memchr\n#endif\n\n/* Search no more than N bytes of S for C.  */\nvoid *\n__memchr (void const *s, int c_in, size_t n)\n{\n  /* On 32-bit hardware, choosing longword to be a 32-bit unsigned\n     long instead of a 64-bit uintmax_t tends to give better\n     performance.  On 64-bit hardware, unsigned long is generally 64\n     bits already.  Change this typedef to experiment with\n     performance.  */\n  typedef unsigned long int longword;\n\n  const unsigned char *char_ptr;\n  const longword *longword_ptr;\n  longword repeated_one;\n  longword repeated_c;\n  unsigned reg_char c;\n\n  c = (unsigned char) c_in;\n\n  /* Handle the first few bytes by reading one byte at a time.\n     Do this until CHAR_PTR is aligned on a longword boundary.  */\n  for (char_ptr = (const unsigned char *) s;\n       n > 0 && (size_t) char_ptr % sizeof (longword) != 0;\n       --n, ++char_ptr)\n    if (*char_ptr == c)\n      return (void *) char_ptr;\n\n  longword_ptr = (const longword *) char_ptr;\n\n  /* All these elucidatory comments refer to 4-byte longwords,\n     but the theory applies equally well to any size longwords.  */\n\n  /* Compute auxiliary longword values:\n     repeated_one is a value which has a 1 in every byte.\n     repeated_c has c in every byte.  */\n  repeated_one = 0x01010101;\n  repeated_c = c | (c << 8);\n  repeated_c |= repeated_c << 16;\n  if (0xffffffffU < (longword) -1)\n    {\n      repeated_one |= repeated_one << 31 << 1;\n      repeated_c |= repeated_c << 31 << 1;\n      if (8 < sizeof (longword))\n        {\n          size_t i;\n\n          for (i = 64; i < sizeof (longword) * 8; i *= 2)\n            {\n              repeated_one |= repeated_one << i;\n              repeated_c |= repeated_c << i;\n            }\n        }\n    }\n\n  /* Instead of the traditional loop which tests each byte, we will test a\n     longword at a time.  The tricky part is testing if *any of the four*\n     bytes in the longword in question are equal to c.  We first use an xor\n     with repeated_c.  This reduces the task to testing whether *any of the\n     four* bytes in longword1 is zero.\n\n     We compute tmp =\n       ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).\n     That is, we perform the following operations:\n       1. Subtract repeated_one.\n       2. & ~longword1.\n       3. & a mask consisting of 0x80 in every byte.\n     Consider what happens in each byte:\n       - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,\n         and step 3 transforms it into 0x80.  A carry can also be propagated\n         to more significant bytes.\n       - If a byte of longword1 is nonzero, let its lowest 1 bit be at\n         position k (0 <= k <= 7); so the lowest k bits are 0.  After step 1,\n         the byte ends in a single bit of value 0 and k bits of value 1.\n         After step 2, the result is just k bits of value 1: 2^k - 1.  After\n         step 3, the result is 0.  And no carry is produced.\n     So, if longword1 has only non-zero bytes, tmp is zero.\n     Whereas if longword1 has a zero byte, call j the position of the least\n     significant zero byte.  Then the result has a zero at positions 0, ...,\n     j-1 and a 0x80 at position j.  We cannot predict the result at the more\n     significant bytes (positions j+1..3), but it does not matter since we\n     already have a non-zero bit at position 8*j+7.\n\n     So, the test whether any byte in longword1 is zero is equivalent to\n     testing whether tmp is nonzero.  */\n\n  while (n >= sizeof (longword))\n    {\n      longword longword1 = *longword_ptr ^ repeated_c;\n\n      if ((((longword1 - repeated_one) & ~longword1)\n           & (repeated_one << 7)) != 0)\n        break;\n      longword_ptr++;\n      n -= sizeof (longword);\n    }\n\n  char_ptr = (const unsigned char *) longword_ptr;\n\n  /* At this point, we know that either n < sizeof (longword), or one of the\n     sizeof (longword) bytes starting at char_ptr is == c.  On little-endian\n     machines, we could determine the first such byte without any further\n     memory accesses, just by looking at the tmp result from the last loop\n     iteration.  But this does not work on big-endian machines.  Choose code\n     that works in both cases.  */\n\n  for (; n > 0; --n, ++char_ptr)\n    {\n      if (*char_ptr == c)\n        return (void *) char_ptr;\n    }\n\n  return NULL;\n}\n#ifdef weak_alias\nweak_alias (__memchr, BP_SYM (memchr))\n#endif\n"
  },
  {
    "path": "gnulib/memchr.valgrind",
    "content": "# Suppress a valgrind message about use of uninitialized memory in memchr().\n\n# Copyright (C) 2009-2021 Free Software Foundation, Inc.\n#\n# This file is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser General Public License as\n# published by the Free Software Foundation; either version 2.1 of the\n# License, or (at your option) any later version.\n#\n# This file is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser General Public License for more details.\n#\n# You should have received a copy of the GNU Lesser General Public License\n# along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\n# POSIX states that when the character is found, memchr must not read extra\n# bytes in an overestimated length (for example, where memchr is used to\n# implement strnlen).  However, we use a safe word read to provide a speedup.\n{\n    memchr-value4\n    Memcheck:Value4\n    fun:rpl_memchr\n}\n{\n    memchr-value8\n    Memcheck:Value8\n    fun:rpl_memchr\n}\n"
  },
  {
    "path": "gnulib/mempcpy.c",
    "content": "/* Copy memory area and return pointer after last written byte.\n   Copyright (C) 2003, 2007, 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <string.h>\n\n/* A function definition is only needed if HAVE_MEMPCPY is not defined.  */\n#if !HAVE_MEMPCPY\n\n/* Copy N bytes of SRC to DEST, return pointer to bytes after the\n   last written byte.  */\nvoid *\nmempcpy (void *dest, const void *src, size_t n)\n{\n  return (char *) memcpy (dest, src, n) + n;\n}\n\n#endif\n"
  },
  {
    "path": "gnulib/nl_langinfo-lock.c",
    "content": "/* Return the internal lock used by nl_langinfo.\n   Copyright (C) 2019-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2019-2020.  */\n\n#include <config.h>\n\n/* When it is known that the gl_get_nl_langinfo_lock function is defined\n   by a dependency library, it should not be defined here.  */\n#if OMIT_NL_LANGINFO_LOCK\n\n/* This declaration is solely to ensure that after preprocessing\n   this file is never empty.  */\ntypedef int dummy;\n\n#else\n\n/* This file defines the internal lock used by nl_langinfo.\n   It is a separate compilation unit, so that only one copy of it is\n   present when linking statically.  */\n\n/* Prohibit renaming this symbol.  */\n# undef gl_get_nl_langinfo_lock\n\n/* Macro for exporting a symbol (function, not variable) defined in this file,\n   when compiled into a shared library.  */\n# ifndef DLL_EXPORTED\n#  if HAVE_VISIBILITY\n  /* Override the effect of the compiler option '-fvisibility=hidden'.  */\n#   define DLL_EXPORTED __attribute__((__visibility__(\"default\")))\n#  elif defined _WIN32 || defined __CYGWIN__\n#   define DLL_EXPORTED __declspec(dllexport)\n#  else\n#   define DLL_EXPORTED\n#  endif\n# endif\n\n# if defined _WIN32 && !defined __CYGWIN__\n\n#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#  include <windows.h>\n\n#  include \"windows-initguard.h\"\n\n/* The return type is a 'CRITICAL_SECTION *', not a 'glwthread_mutex_t *',\n   because the latter is not guaranteed to be a stable ABI in the future.  */\n\n/* Make sure the function gets exported from DLLs.  */\nDLL_EXPORTED CRITICAL_SECTION *gl_get_nl_langinfo_lock (void);\n\nstatic glwthread_initguard_t guard = GLWTHREAD_INITGUARD_INIT;\nstatic CRITICAL_SECTION lock;\n\n/* Returns the internal lock used by nl_langinfo.  */\nCRITICAL_SECTION *\ngl_get_nl_langinfo_lock (void)\n{\n  if (!guard.done)\n    {\n      if (InterlockedIncrement (&guard.started) == 0)\n        {\n          /* This thread is the first one to need the lock.  Initialize it.  */\n          InitializeCriticalSection (&lock);\n          guard.done = 1;\n        }\n      else\n        {\n          /* Don't let guard.started grow and wrap around.  */\n          InterlockedDecrement (&guard.started);\n          /* Yield the CPU while waiting for another thread to finish\n             initializing this mutex.  */\n          while (!guard.done)\n            Sleep (0);\n        }\n    }\n  return &lock;\n}\n\n# elif HAVE_PTHREAD_API\n\n#  include <pthread.h>\n\nstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;\n\n/* Make sure the function gets exported from shared libraries.  */\nDLL_EXPORTED pthread_mutex_t *gl_get_nl_langinfo_lock (void);\n\n/* Returns the internal lock used by nl_langinfo.  */\npthread_mutex_t *\ngl_get_nl_langinfo_lock (void)\n{\n  return &mutex;\n}\n\n# elif HAVE_THREADS_H\n\n#  include <threads.h>\n#  include <stdlib.h>\n\nstatic int volatile init_needed = 1;\nstatic once_flag init_once = ONCE_FLAG_INIT;\nstatic mtx_t mutex;\n\nstatic void\natomic_init (void)\n{\n  if (mtx_init (&mutex, mtx_plain) != thrd_success)\n    abort ();\n  init_needed = 0;\n}\n\n/* Make sure the function gets exported from shared libraries.  */\nDLL_EXPORTED mtx_t *gl_get_nl_langinfo_lock (void);\n\n/* Returns the internal lock used by nl_langinfo.  */\nmtx_t *\ngl_get_nl_langinfo_lock (void)\n{\n  if (init_needed)\n    call_once (&init_once, atomic_init);\n  return &mutex;\n}\n\n# endif\n\n# if (defined _WIN32 || defined __CYGWIN__) && !defined _MSC_VER\n/* Make sure the '__declspec(dllimport)' in nl_langinfo.c does not cause\n   a link failure when no DLLs are involved.  */\n#  if defined _WIN64 || defined _LP64\n#   define IMP(x) __imp_##x\n#  else\n#   define IMP(x) _imp__##x\n#  endif\nvoid * IMP(gl_get_nl_langinfo_lock) = &gl_get_nl_langinfo_lock;\n# endif\n\n#endif\n"
  },
  {
    "path": "gnulib/nl_langinfo.c",
    "content": "/* nl_langinfo() replacement: query locale dependent information.\n\n   Copyright (C) 2007-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <langinfo.h>\n\n#include <locale.h>\n#include <stdlib.h>\n#include <string.h>\n#if defined _WIN32 && ! defined __CYGWIN__\n# define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n# include <windows.h>\n# include <stdio.h>\n#endif\n\n#if REPLACE_NL_LANGINFO && !NL_LANGINFO_MTSAFE\n# if defined _WIN32 && !defined __CYGWIN__\n\n#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#  include <windows.h>\n\n# elif HAVE_PTHREAD_API\n\n#  include <pthread.h>\n#  if HAVE_THREADS_H && HAVE_WEAK_SYMBOLS\n#   include <threads.h>\n#   pragma weak thrd_exit\n#   define c11_threads_in_use() (thrd_exit != NULL)\n#  else\n#   define c11_threads_in_use() 0\n#  endif\n\n# elif HAVE_THREADS_H\n\n#  include <threads.h>\n\n# endif\n#endif\n\n/* nl_langinfo() must be multithread-safe.  To achieve this without using\n   thread-local storage:\n     1. We use a specific static buffer for each possible argument.\n        So that different threads can call nl_langinfo with different arguments,\n        without interfering.\n     2. We use a simple strcpy or memcpy to fill this static buffer.  Filling it\n        through, for example, strcpy + strcat would not be guaranteed to leave\n        the buffer's contents intact if another thread is currently accessing\n        it.  If necessary, the contents is first assembled in a stack-allocated\n        buffer.  */\n\n#if !REPLACE_NL_LANGINFO || GNULIB_defined_CODESET\n/* Return the codeset of the current locale, if this is easily deducible.\n   Otherwise, return \"\".  */\nstatic char *\nctype_codeset (void)\n{\n  static char result[2 + 10 + 1];\n  char buf[2 + 10 + 1];\n  char locale[SETLOCALE_NULL_MAX];\n  char *codeset;\n  size_t codesetlen;\n\n  if (setlocale_null_r (LC_CTYPE, locale, sizeof (locale)))\n    locale[0] = '\\0';\n\n  codeset = buf;\n  codeset[0] = '\\0';\n\n  if (locale[0])\n    {\n      /* If the locale name contains an encoding after the dot, return it.  */\n      char *dot = strchr (locale, '.');\n\n      if (dot)\n        {\n          /* Look for the possible @... trailer and remove it, if any.  */\n          char *codeset_start = dot + 1;\n          char const *modifier = strchr (codeset_start, '@');\n\n          if (! modifier)\n            codeset = codeset_start;\n          else\n            {\n              codesetlen = modifier - codeset_start;\n              if (codesetlen < sizeof buf)\n                {\n                  codeset = memcpy (buf, codeset_start, codesetlen);\n                  codeset[codesetlen] = '\\0';\n                }\n            }\n        }\n    }\n\n# if defined _WIN32 && ! defined __CYGWIN__\n  /* If setlocale is successful, it returns the number of the\n     codepage, as a string.  Otherwise, fall back on Windows API\n     GetACP, which returns the locale's codepage as a number (although\n     this doesn't change according to what the 'setlocale' call specified).\n     Either way, prepend \"CP\" to make it a valid codeset name.  */\n  codesetlen = strlen (codeset);\n  if (0 < codesetlen && codesetlen < sizeof buf - 2)\n    memmove (buf + 2, codeset, codesetlen + 1);\n  else\n    sprintf (buf + 2, \"%u\", GetACP ());\n  /* For a locale name such as \"French_France.65001\", in Windows 10,\n     setlocale now returns \"French_France.utf8\" instead.  */\n  if (strcmp (buf + 2, \"65001\") == 0 || strcmp (buf + 2, \"utf8\") == 0)\n    return (char *) \"UTF-8\";\n  else\n    {\n      memcpy (buf, \"CP\", 2);\n      strcpy (result, buf);\n      return result;\n    }\n# else\n  strcpy (result, codeset);\n  return result;\n#endif\n}\n#endif\n\n\n#if REPLACE_NL_LANGINFO\n\n/* Override nl_langinfo with support for added nl_item values.  */\n\n# undef nl_langinfo\n\n/* Without locking, on Solaris 11.3, test-nl_langinfo-mt fails, with message\n   \"thread5 disturbed by threadN!\", even when threadN invokes only\n      nl_langinfo (CODESET);\n      nl_langinfo (CRNCYSTR);\n   Similarly on Solaris 10.  */\n\n# if !NL_LANGINFO_MTSAFE /* Solaris */\n\n#  define ITEMS (MAXSTRMSG + 1)\n#  define MAX_RESULT_LEN 80\n\nstatic char *\nnl_langinfo_unlocked (nl_item item)\n{\n  static char result[ITEMS][MAX_RESULT_LEN];\n\n  /* The result of nl_langinfo is in storage that can be overwritten by\n     other calls to nl_langinfo.  */\n  char *tmp = nl_langinfo (item);\n  if (item >= 0 && item < ITEMS && tmp != NULL)\n    {\n      size_t tmp_len = strlen (tmp);\n      if (tmp_len < MAX_RESULT_LEN)\n        strcpy (result[item], tmp);\n      else\n        {\n          /* Produce a truncated result.  Oh well...  */\n          result[item][MAX_RESULT_LEN - 1] = '\\0';\n          memcpy (result[item], tmp, MAX_RESULT_LEN - 1);\n        }\n      return result[item];\n    }\n  else\n    return tmp;\n}\n\n/* Use a lock, so that no two threads can invoke nl_langinfo_unlocked\n   at the same time.  */\n\n/* Prohibit renaming this symbol.  */\n#  undef gl_get_nl_langinfo_lock\n\n#  if defined _WIN32 && !defined __CYGWIN__\n\nextern __declspec(dllimport) CRITICAL_SECTION *gl_get_nl_langinfo_lock (void);\n\nstatic char *\nnl_langinfo_with_lock (nl_item item)\n{\n  CRITICAL_SECTION *lock = gl_get_nl_langinfo_lock ();\n  char *ret;\n\n  EnterCriticalSection (lock);\n  ret = nl_langinfo_unlocked (item);\n  LeaveCriticalSection (lock);\n\n  return ret;\n}\n\n#  elif HAVE_PTHREAD_API\n\nextern\n#   if defined _WIN32 || defined __CYGWIN__\n  __declspec(dllimport)\n#   endif\n  pthread_mutex_t *gl_get_nl_langinfo_lock (void);\n\n#   if HAVE_WEAK_SYMBOLS /* musl libc, FreeBSD, NetBSD, OpenBSD, Haiku */\n\n     /* Avoid the need to link with '-lpthread'.  */\n#    pragma weak pthread_mutex_lock\n#    pragma weak pthread_mutex_unlock\n\n     /* Determine whether libpthread is in use.  */\n#    pragma weak pthread_mutexattr_gettype\n     /* See the comments in lock.h.  */\n#    define pthread_in_use() \\\n       (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())\n\n#   else\n#    define pthread_in_use() 1\n#   endif\n\nstatic char *\nnl_langinfo_with_lock (nl_item item)\n{\n  if (pthread_in_use())\n    {\n      pthread_mutex_t *lock = gl_get_nl_langinfo_lock ();\n      char *ret;\n\n      if (pthread_mutex_lock (lock))\n        abort ();\n      ret = nl_langinfo_unlocked (item);\n      if (pthread_mutex_unlock (lock))\n        abort ();\n\n      return ret;\n    }\n  else\n    return nl_langinfo_unlocked (item);\n}\n\n#  elif HAVE_THREADS_H\n\nextern mtx_t *gl_get_nl_langinfo_lock (void);\n\nstatic char *\nnl_langinfo_with_lock (nl_item item)\n{\n  mtx_t *lock = gl_get_nl_langinfo_lock ();\n  char *ret;\n\n  if (mtx_lock (lock) != thrd_success)\n    abort ();\n  ret = nl_langinfo_unlocked (item);\n  if (mtx_unlock (lock) != thrd_success)\n    abort ();\n\n  return ret;\n}\n\n#  endif\n\n# else\n\n/* On other platforms, no lock is needed.  */\n#  define nl_langinfo_with_lock nl_langinfo\n\n# endif\n\nchar *\nrpl_nl_langinfo (nl_item item)\n{\n  switch (item)\n    {\n# if GNULIB_defined_CODESET\n    case CODESET:\n      return ctype_codeset ();\n# endif\n# if GNULIB_defined_T_FMT_AMPM\n    case T_FMT_AMPM:\n      return (char *) \"%I:%M:%S %p\";\n# endif\n# if GNULIB_defined_ALTMON\n    case ALTMON_1:\n    case ALTMON_2:\n    case ALTMON_3:\n    case ALTMON_4:\n    case ALTMON_5:\n    case ALTMON_6:\n    case ALTMON_7:\n    case ALTMON_8:\n    case ALTMON_9:\n    case ALTMON_10:\n    case ALTMON_11:\n    case ALTMON_12:\n      /* We don't ship the appropriate localizations with gnulib.  Therefore,\n         treat ALTMON_i like MON_i.  */\n      item = item - ALTMON_1 + MON_1;\n      break;\n# endif\n# if GNULIB_defined_ERA\n    case ERA:\n      /* The format is not standardized.  In glibc it is a sequence of strings\n         of the form \"direction:offset:start_date:end_date:era_name:era_format\"\n         with an empty string at the end.  */\n      return (char *) \"\";\n    case ERA_D_FMT:\n      /* The %Ex conversion in strftime behaves like %x if the locale does not\n         have an alternative time format.  */\n      item = D_FMT;\n      break;\n    case ERA_D_T_FMT:\n      /* The %Ec conversion in strftime behaves like %c if the locale does not\n         have an alternative time format.  */\n      item = D_T_FMT;\n      break;\n    case ERA_T_FMT:\n      /* The %EX conversion in strftime behaves like %X if the locale does not\n         have an alternative time format.  */\n      item = T_FMT;\n      break;\n    case ALT_DIGITS:\n      /* The format is not standardized.  In glibc it is a sequence of 10\n         strings, appended in memory.  */\n      return (char *) \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\";\n# endif\n# if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS\n    case YESEXPR:\n      return (char *) \"^[yY]\";\n    case NOEXPR:\n      return (char *) \"^[nN]\";\n# endif\n    default:\n      break;\n    }\n  return nl_langinfo_with_lock (item);\n}\n\n#else\n\n/* Provide nl_langinfo from scratch, either for native MS-Windows, or\n   for old Unix platforms without locales, such as Linux libc5 or\n   BeOS.  */\n\n# include <time.h>\n\nchar *\nnl_langinfo (nl_item item)\n{\n  char buf[100];\n  struct tm tmm = { 0 };\n\n  switch (item)\n    {\n    /* nl_langinfo items of the LC_CTYPE category */\n    case CODESET:\n      {\n        char *codeset = ctype_codeset ();\n        if (*codeset)\n          return codeset;\n      }\n# ifdef __BEOS__\n      return (char *) \"UTF-8\";\n# else\n      return (char *) \"ISO-8859-1\";\n# endif\n    /* nl_langinfo items of the LC_NUMERIC category */\n    case RADIXCHAR:\n      return localeconv () ->decimal_point;\n    case THOUSEP:\n      return localeconv () ->thousands_sep;\n# ifdef GROUPING\n    case GROUPING:\n      return localeconv () ->grouping;\n# endif\n    /* nl_langinfo items of the LC_TIME category.\n       TODO: Really use the locale.  */\n    case D_T_FMT:\n    case ERA_D_T_FMT:\n      return (char *) \"%a %b %e %H:%M:%S %Y\";\n    case D_FMT:\n    case ERA_D_FMT:\n      return (char *) \"%m/%d/%y\";\n    case T_FMT:\n    case ERA_T_FMT:\n      return (char *) \"%H:%M:%S\";\n    case T_FMT_AMPM:\n      return (char *) \"%I:%M:%S %p\";\n    case AM_STR:\n      {\n        static char result[80];\n        if (!strftime (buf, sizeof result, \"%p\", &tmm))\n          return (char *) \"AM\";\n        strcpy (result, buf);\n        return result;\n      }\n    case PM_STR:\n      {\n        static char result[80];\n        tmm.tm_hour = 12;\n        if (!strftime (buf, sizeof result, \"%p\", &tmm))\n          return (char *) \"PM\";\n        strcpy (result, buf);\n        return result;\n      }\n    case DAY_1:\n    case DAY_2:\n    case DAY_3:\n    case DAY_4:\n    case DAY_5:\n    case DAY_6:\n    case DAY_7:\n      {\n        static char result[7][50];\n        static char const days[][sizeof \"Wednesday\"] = {\n          \"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\",\n          \"Friday\", \"Saturday\"\n        };\n        tmm.tm_wday = item - DAY_1;\n        if (!strftime (buf, sizeof result[0], \"%A\", &tmm))\n          return (char *) days[item - DAY_1];\n        strcpy (result[item - DAY_1], buf);\n        return result[item - DAY_1];\n      }\n    case ABDAY_1:\n    case ABDAY_2:\n    case ABDAY_3:\n    case ABDAY_4:\n    case ABDAY_5:\n    case ABDAY_6:\n    case ABDAY_7:\n      {\n        static char result[7][30];\n        static char const abdays[][sizeof \"Sun\"] = {\n          \"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"\n        };\n        tmm.tm_wday = item - ABDAY_1;\n        if (!strftime (buf, sizeof result[0], \"%a\", &tmm))\n          return (char *) abdays[item - ABDAY_1];\n        strcpy (result[item - ABDAY_1], buf);\n        return result[item - ABDAY_1];\n      }\n    {\n      static char const months[][sizeof \"September\"] = {\n        \"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\",\n        \"September\", \"October\", \"November\", \"December\"\n      };\n      case MON_1:\n      case MON_2:\n      case MON_3:\n      case MON_4:\n      case MON_5:\n      case MON_6:\n      case MON_7:\n      case MON_8:\n      case MON_9:\n      case MON_10:\n      case MON_11:\n      case MON_12:\n        {\n          static char result[12][50];\n          tmm.tm_mon = item - MON_1;\n          if (!strftime (buf, sizeof result[0], \"%B\", &tmm))\n            return (char *) months[item - MON_1];\n          strcpy (result[item - MON_1], buf);\n          return result[item - MON_1];\n        }\n      case ALTMON_1:\n      case ALTMON_2:\n      case ALTMON_3:\n      case ALTMON_4:\n      case ALTMON_5:\n      case ALTMON_6:\n      case ALTMON_7:\n      case ALTMON_8:\n      case ALTMON_9:\n      case ALTMON_10:\n      case ALTMON_11:\n      case ALTMON_12:\n        {\n          static char result[12][50];\n          tmm.tm_mon = item - ALTMON_1;\n          /* The platforms without nl_langinfo() don't support strftime with\n             %OB.  We don't even need to try.  */\n          #if 0\n          if (!strftime (buf, sizeof result[0], \"%OB\", &tmm))\n          #endif\n            if (!strftime (buf, sizeof result[0], \"%B\", &tmm))\n              return (char *) months[item - ALTMON_1];\n          strcpy (result[item - ALTMON_1], buf);\n          return result[item - ALTMON_1];\n        }\n    }\n    case ABMON_1:\n    case ABMON_2:\n    case ABMON_3:\n    case ABMON_4:\n    case ABMON_5:\n    case ABMON_6:\n    case ABMON_7:\n    case ABMON_8:\n    case ABMON_9:\n    case ABMON_10:\n    case ABMON_11:\n    case ABMON_12:\n      {\n        static char result[12][30];\n        static char const abmonths[][sizeof \"Jan\"] = {\n          \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\",\n          \"Sep\", \"Oct\", \"Nov\", \"Dec\"\n        };\n        tmm.tm_mon = item - ABMON_1;\n        if (!strftime (buf, sizeof result[0], \"%b\", &tmm))\n          return (char *) abmonths[item - ABMON_1];\n        strcpy (result[item - ABMON_1], buf);\n        return result[item - ABMON_1];\n      }\n    case ERA:\n      return (char *) \"\";\n    case ALT_DIGITS:\n      return (char *) \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\";\n    /* nl_langinfo items of the LC_MONETARY category.  */\n    case CRNCYSTR:\n      return localeconv () ->currency_symbol;\n# ifdef INT_CURR_SYMBOL\n    case INT_CURR_SYMBOL:\n      return localeconv () ->int_curr_symbol;\n    case MON_DECIMAL_POINT:\n      return localeconv () ->mon_decimal_point;\n    case MON_THOUSANDS_SEP:\n      return localeconv () ->mon_thousands_sep;\n    case MON_GROUPING:\n      return localeconv () ->mon_grouping;\n    case POSITIVE_SIGN:\n      return localeconv () ->positive_sign;\n    case NEGATIVE_SIGN:\n      return localeconv () ->negative_sign;\n    case FRAC_DIGITS:\n      return & localeconv () ->frac_digits;\n    case INT_FRAC_DIGITS:\n      return & localeconv () ->int_frac_digits;\n    case P_CS_PRECEDES:\n      return & localeconv () ->p_cs_precedes;\n    case N_CS_PRECEDES:\n      return & localeconv () ->n_cs_precedes;\n    case P_SEP_BY_SPACE:\n      return & localeconv () ->p_sep_by_space;\n    case N_SEP_BY_SPACE:\n      return & localeconv () ->n_sep_by_space;\n    case P_SIGN_POSN:\n      return & localeconv () ->p_sign_posn;\n    case N_SIGN_POSN:\n      return & localeconv () ->n_sign_posn;\n# endif\n    /* nl_langinfo items of the LC_MESSAGES category\n       TODO: Really use the locale. */\n    case YESEXPR:\n      return (char *) \"^[yY]\";\n    case NOEXPR:\n      return (char *) \"^[nN]\";\n    default:\n      return (char *) \"\";\n    }\n}\n\n#endif\n"
  },
  {
    "path": "gnulib/regcomp.c",
    "content": "/* Extended regular expression matching and search library.\n   Copyright (C) 2002-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifdef _LIBC\n# include <locale/weight.h>\n#endif\n\nstatic reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,\n\t\t\t\t\t  size_t length, reg_syntax_t syntax);\nstatic void re_compile_fastmap_iter (regex_t *bufp,\n\t\t\t\t     const re_dfastate_t *init_state,\n\t\t\t\t     char *fastmap);\nstatic reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len);\n#ifdef RE_ENABLE_I18N\nstatic void free_charset (re_charset_t *cset);\n#endif /* RE_ENABLE_I18N */\nstatic void free_workarea_compile (regex_t *preg);\nstatic reg_errcode_t create_initial_state (re_dfa_t *dfa);\n#ifdef RE_ENABLE_I18N\nstatic void optimize_utf8 (re_dfa_t *dfa);\n#endif\nstatic reg_errcode_t analyze (regex_t *preg);\nstatic reg_errcode_t preorder (bin_tree_t *root,\n\t\t\t       reg_errcode_t (fn (void *, bin_tree_t *)),\n\t\t\t       void *extra);\nstatic reg_errcode_t postorder (bin_tree_t *root,\n\t\t\t\treg_errcode_t (fn (void *, bin_tree_t *)),\n\t\t\t\tvoid *extra);\nstatic reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node);\nstatic reg_errcode_t lower_subexps (void *extra, bin_tree_t *node);\nstatic bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg,\n\t\t\t\t bin_tree_t *node);\nstatic reg_errcode_t calc_first (void *extra, bin_tree_t *node);\nstatic reg_errcode_t calc_next (void *extra, bin_tree_t *node);\nstatic reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node);\nstatic Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint);\nstatic Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node,\n\t\t\t\t   unsigned int constraint);\nstatic reg_errcode_t calc_eclosure (re_dfa_t *dfa);\nstatic reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,\n\t\t\t\t\t Idx node, bool root);\nstatic reg_errcode_t calc_inveclosure (re_dfa_t *dfa);\nstatic Idx fetch_number (re_string_t *input, re_token_t *token,\n\t\t\t reg_syntax_t syntax);\nstatic int peek_token (re_token_t *token, re_string_t *input,\n\t\t\treg_syntax_t syntax);\nstatic bin_tree_t *parse (re_string_t *regexp, regex_t *preg,\n\t\t\t  reg_syntax_t syntax, reg_errcode_t *err);\nstatic bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg,\n\t\t\t\t  re_token_t *token, reg_syntax_t syntax,\n\t\t\t\t  Idx nest, reg_errcode_t *err);\nstatic bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg,\n\t\t\t\t re_token_t *token, reg_syntax_t syntax,\n\t\t\t\t Idx nest, reg_errcode_t *err);\nstatic bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg,\n\t\t\t\t     re_token_t *token, reg_syntax_t syntax,\n\t\t\t\t     Idx nest, reg_errcode_t *err);\nstatic bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg,\n\t\t\t\t  re_token_t *token, reg_syntax_t syntax,\n\t\t\t\t  Idx nest, reg_errcode_t *err);\nstatic bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp,\n\t\t\t\t re_dfa_t *dfa, re_token_t *token,\n\t\t\t\t reg_syntax_t syntax, reg_errcode_t *err);\nstatic bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa,\n\t\t\t\t      re_token_t *token, reg_syntax_t syntax,\n\t\t\t\t      reg_errcode_t *err);\nstatic reg_errcode_t parse_bracket_element (bracket_elem_t *elem,\n\t\t\t\t\t    re_string_t *regexp,\n\t\t\t\t\t    re_token_t *token, int token_len,\n\t\t\t\t\t    re_dfa_t *dfa,\n\t\t\t\t\t    reg_syntax_t syntax,\n\t\t\t\t\t    bool accept_hyphen);\nstatic reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,\n\t\t\t\t\t  re_string_t *regexp,\n\t\t\t\t\t  re_token_t *token);\n#ifdef RE_ENABLE_I18N\nstatic reg_errcode_t build_equiv_class (bitset_t sbcset,\n\t\t\t\t\tre_charset_t *mbcset,\n\t\t\t\t\tIdx *equiv_class_alloc,\n\t\t\t\t\tconst unsigned char *name);\nstatic reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,\n\t\t\t\t      bitset_t sbcset,\n\t\t\t\t      re_charset_t *mbcset,\n\t\t\t\t      Idx *char_class_alloc,\n\t\t\t\t      const char *class_name,\n\t\t\t\t      reg_syntax_t syntax);\n#else  /* not RE_ENABLE_I18N */\nstatic reg_errcode_t build_equiv_class (bitset_t sbcset,\n\t\t\t\t\tconst unsigned char *name);\nstatic reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,\n\t\t\t\t      bitset_t sbcset,\n\t\t\t\t      const char *class_name,\n\t\t\t\t      reg_syntax_t syntax);\n#endif /* not RE_ENABLE_I18N */\nstatic bin_tree_t *build_charclass_op (re_dfa_t *dfa,\n\t\t\t\t       RE_TRANSLATE_TYPE trans,\n\t\t\t\t       const char *class_name,\n\t\t\t\t       const char *extra,\n\t\t\t\t       bool non_match, reg_errcode_t *err);\nstatic bin_tree_t *create_tree (re_dfa_t *dfa,\n\t\t\t\tbin_tree_t *left, bin_tree_t *right,\n\t\t\t\tre_token_type_t type);\nstatic bin_tree_t *create_token_tree (re_dfa_t *dfa,\n\t\t\t\t      bin_tree_t *left, bin_tree_t *right,\n\t\t\t\t      const re_token_t *token);\nstatic bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa);\nstatic void free_token (re_token_t *node);\nstatic reg_errcode_t free_tree (void *extra, bin_tree_t *node);\nstatic reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node);\n\f\n/* This table gives an error message for each of the error codes listed\n   in regex.h.  Obviously the order here has to be same as there.\n   POSIX doesn't require that we do anything for REG_NOERROR,\n   but why not be nice?  */\n\nstatic const char __re_error_msgid[] =\n  {\n#define REG_NOERROR_IDX\t0\n    gettext_noop (\"Success\")\t/* REG_NOERROR */\n    \"\\0\"\n#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof \"Success\")\n    gettext_noop (\"No match\")\t/* REG_NOMATCH */\n    \"\\0\"\n#define REG_BADPAT_IDX\t(REG_NOMATCH_IDX + sizeof \"No match\")\n    gettext_noop (\"Invalid regular expression\") /* REG_BADPAT */\n    \"\\0\"\n#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof \"Invalid regular expression\")\n    gettext_noop (\"Invalid collation character\") /* REG_ECOLLATE */\n    \"\\0\"\n#define REG_ECTYPE_IDX\t(REG_ECOLLATE_IDX + sizeof \"Invalid collation character\")\n    gettext_noop (\"Invalid character class name\") /* REG_ECTYPE */\n    \"\\0\"\n#define REG_EESCAPE_IDX\t(REG_ECTYPE_IDX + sizeof \"Invalid character class name\")\n    gettext_noop (\"Trailing backslash\") /* REG_EESCAPE */\n    \"\\0\"\n#define REG_ESUBREG_IDX\t(REG_EESCAPE_IDX + sizeof \"Trailing backslash\")\n    gettext_noop (\"Invalid back reference\") /* REG_ESUBREG */\n    \"\\0\"\n#define REG_EBRACK_IDX\t(REG_ESUBREG_IDX + sizeof \"Invalid back reference\")\n    gettext_noop (\"Unmatched [, [^, [:, [., or [=\")\t/* REG_EBRACK */\n    \"\\0\"\n#define REG_EPAREN_IDX\t(REG_EBRACK_IDX + sizeof \"Unmatched [, [^, [:, [., or [=\")\n    gettext_noop (\"Unmatched ( or \\\\(\") /* REG_EPAREN */\n    \"\\0\"\n#define REG_EBRACE_IDX\t(REG_EPAREN_IDX + sizeof \"Unmatched ( or \\\\(\")\n    gettext_noop (\"Unmatched \\\\{\") /* REG_EBRACE */\n    \"\\0\"\n#define REG_BADBR_IDX\t(REG_EBRACE_IDX + sizeof \"Unmatched \\\\{\")\n    gettext_noop (\"Invalid content of \\\\{\\\\}\") /* REG_BADBR */\n    \"\\0\"\n#define REG_ERANGE_IDX\t(REG_BADBR_IDX + sizeof \"Invalid content of \\\\{\\\\}\")\n    gettext_noop (\"Invalid range end\")\t/* REG_ERANGE */\n    \"\\0\"\n#define REG_ESPACE_IDX\t(REG_ERANGE_IDX + sizeof \"Invalid range end\")\n    gettext_noop (\"Memory exhausted\") /* REG_ESPACE */\n    \"\\0\"\n#define REG_BADRPT_IDX\t(REG_ESPACE_IDX + sizeof \"Memory exhausted\")\n    gettext_noop (\"Invalid preceding regular expression\") /* REG_BADRPT */\n    \"\\0\"\n#define REG_EEND_IDX\t(REG_BADRPT_IDX + sizeof \"Invalid preceding regular expression\")\n    gettext_noop (\"Premature end of regular expression\") /* REG_EEND */\n    \"\\0\"\n#define REG_ESIZE_IDX\t(REG_EEND_IDX + sizeof \"Premature end of regular expression\")\n    gettext_noop (\"Regular expression too big\") /* REG_ESIZE */\n    \"\\0\"\n#define REG_ERPAREN_IDX\t(REG_ESIZE_IDX + sizeof \"Regular expression too big\")\n    gettext_noop (\"Unmatched ) or \\\\)\") /* REG_ERPAREN */\n  };\n\nstatic const size_t __re_error_msgid_idx[] =\n  {\n    REG_NOERROR_IDX,\n    REG_NOMATCH_IDX,\n    REG_BADPAT_IDX,\n    REG_ECOLLATE_IDX,\n    REG_ECTYPE_IDX,\n    REG_EESCAPE_IDX,\n    REG_ESUBREG_IDX,\n    REG_EBRACK_IDX,\n    REG_EPAREN_IDX,\n    REG_EBRACE_IDX,\n    REG_BADBR_IDX,\n    REG_ERANGE_IDX,\n    REG_ESPACE_IDX,\n    REG_BADRPT_IDX,\n    REG_EEND_IDX,\n    REG_ESIZE_IDX,\n    REG_ERPAREN_IDX\n  };\n\f\n/* Entry points for GNU code.  */\n\n/* re_compile_pattern is the GNU regular expression compiler: it\n   compiles PATTERN (of length LENGTH) and puts the result in BUFP.\n   Returns 0 if the pattern was valid, otherwise an error string.\n\n   Assumes the 'allocated' (and perhaps 'buffer') and 'translate' fields\n   are set in BUFP on entry.  */\n\nconst char *\nre_compile_pattern (const char *pattern, size_t length,\n\t\t    struct re_pattern_buffer *bufp)\n{\n  reg_errcode_t ret;\n\n  /* And GNU code determines whether or not to get register information\n     by passing null for the REGS argument to re_match, etc., not by\n     setting no_sub, unless RE_NO_SUB is set.  */\n  bufp->no_sub = !!(re_syntax_options & RE_NO_SUB);\n\n  /* Match anchors at newline.  */\n  bufp->newline_anchor = 1;\n\n  ret = re_compile_internal (bufp, pattern, length, re_syntax_options);\n\n  if (!ret)\n    return NULL;\n  return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);\n}\nweak_alias (__re_compile_pattern, re_compile_pattern)\n\n/* Set by 're_set_syntax' to the current regexp syntax to recognize.  Can\n   also be assigned to arbitrarily: each pattern buffer stores its own\n   syntax, so it can be changed between regex compilations.  */\n/* This has no initializer because initialized variables in Emacs\n   become read-only after dumping.  */\nreg_syntax_t re_syntax_options;\n\n\n/* Specify the precise syntax of regexps for compilation.  This provides\n   for compatibility for various utilities which historically have\n   different, incompatible syntaxes.\n\n   The argument SYNTAX is a bit mask comprised of the various bits\n   defined in regex.h.  We return the old syntax.  */\n\nreg_syntax_t\nre_set_syntax (reg_syntax_t syntax)\n{\n  reg_syntax_t ret = re_syntax_options;\n\n  re_syntax_options = syntax;\n  return ret;\n}\nweak_alias (__re_set_syntax, re_set_syntax)\n\nint\nre_compile_fastmap (struct re_pattern_buffer *bufp)\n{\n  re_dfa_t *dfa = bufp->buffer;\n  char *fastmap = bufp->fastmap;\n\n  memset (fastmap, '\\0', sizeof (char) * SBC_MAX);\n  re_compile_fastmap_iter (bufp, dfa->init_state, fastmap);\n  if (dfa->init_state != dfa->init_state_word)\n    re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap);\n  if (dfa->init_state != dfa->init_state_nl)\n    re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap);\n  if (dfa->init_state != dfa->init_state_begbuf)\n    re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap);\n  bufp->fastmap_accurate = 1;\n  return 0;\n}\nweak_alias (__re_compile_fastmap, re_compile_fastmap)\n\nstatic inline void\n__attribute__ ((always_inline))\nre_set_fastmap (char *fastmap, bool icase, int ch)\n{\n  fastmap[ch] = 1;\n  if (icase)\n    fastmap[tolower (ch)] = 1;\n}\n\n/* Helper function for re_compile_fastmap.\n   Compile fastmap for the initial_state INIT_STATE.  */\n\nstatic void\nre_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,\n\t\t\t char *fastmap)\n{\n  re_dfa_t *dfa = bufp->buffer;\n  Idx node_cnt;\n  bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));\n  for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)\n    {\n      Idx node = init_state->nodes.elems[node_cnt];\n      re_token_type_t type = dfa->nodes[node].type;\n\n      if (type == CHARACTER)\n\t{\n\t  re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);\n#ifdef RE_ENABLE_I18N\n\t  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)\n\t    {\n\t      unsigned char buf[MB_LEN_MAX];\n\t      unsigned char *p;\n\t      wchar_t wc;\n\t      mbstate_t state;\n\n\t      p = buf;\n\t      *p++ = dfa->nodes[node].opr.c;\n\t      while (++node < dfa->nodes_len\n\t\t     &&\tdfa->nodes[node].type == CHARACTER\n\t\t     && dfa->nodes[node].mb_partial)\n\t\t*p++ = dfa->nodes[node].opr.c;\n\t      memset (&state, '\\0', sizeof (state));\n\t      if (__mbrtowc (&wc, (const char *) buf, p - buf,\n\t\t\t     &state) == p - buf\n\t\t  && (__wcrtomb ((char *) buf, __towlower (wc), &state)\n\t\t      != (size_t) -1))\n\t\tre_set_fastmap (fastmap, false, buf[0]);\n\t    }\n#endif\n\t}\n      else if (type == SIMPLE_BRACKET)\n\t{\n\t  int i, ch;\n\t  for (i = 0, ch = 0; i < BITSET_WORDS; ++i)\n\t    {\n\t      int j;\n\t      bitset_word_t w = dfa->nodes[node].opr.sbcset[i];\n\t      for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)\n\t\tif (w & ((bitset_word_t) 1 << j))\n\t\t  re_set_fastmap (fastmap, icase, ch);\n\t    }\n\t}\n#ifdef RE_ENABLE_I18N\n      else if (type == COMPLEX_BRACKET)\n\t{\n\t  re_charset_t *cset = dfa->nodes[node].opr.mbcset;\n\t  Idx i;\n\n# ifdef _LIBC\n\t  /* See if we have to try all bytes which start multiple collation\n\t     elements.\n\t     e.g. In da_DK, we want to catch 'a' since \"aa\" is a valid\n\t\t  collation element, and don't catch 'b' since 'b' is\n\t\t  the only collation element which starts from 'b' (and\n\t\t  it is caught by SIMPLE_BRACKET).  */\n\t      if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0\n\t\t  && (cset->ncoll_syms || cset->nranges))\n\t\t{\n\t\t  const int32_t *table = (const int32_t *)\n\t\t    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);\n\t\t  for (i = 0; i < SBC_MAX; ++i)\n\t\t    if (table[i] < 0)\n\t\t      re_set_fastmap (fastmap, icase, i);\n\t\t}\n# endif /* _LIBC */\n\n\t  /* See if we have to start the match at all multibyte characters,\n\t     i.e. where we would not find an invalid sequence.  This only\n\t     applies to multibyte character sets; for single byte character\n\t     sets, the SIMPLE_BRACKET again suffices.  */\n\t  if (dfa->mb_cur_max > 1\n\t      && (cset->nchar_classes || cset->non_match || cset->nranges\n# ifdef _LIBC\n\t\t  || cset->nequiv_classes\n# endif /* _LIBC */\n\t\t ))\n\t    {\n\t      unsigned char c = 0;\n\t      do\n\t\t{\n\t\t  mbstate_t mbs;\n\t\t  memset (&mbs, 0, sizeof (mbs));\n\t\t  if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2)\n\t\t    re_set_fastmap (fastmap, false, (int) c);\n\t\t}\n\t      while (++c != 0);\n\t    }\n\n\t  else\n\t    {\n\t      /* ... Else catch all bytes which can start the mbchars.  */\n\t      for (i = 0; i < cset->nmbchars; ++i)\n\t\t{\n\t\t  char buf[256];\n\t\t  mbstate_t state;\n\t\t  memset (&state, '\\0', sizeof (state));\n\t\t  if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)\n\t\t    re_set_fastmap (fastmap, icase, *(unsigned char *) buf);\n\t\t  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)\n\t\t    {\n\t\t      if (__wcrtomb (buf, __towlower (cset->mbchars[i]), &state)\n\t\t\t  != (size_t) -1)\n\t\t\tre_set_fastmap (fastmap, false, *(unsigned char *) buf);\n\t\t    }\n\t\t}\n\t    }\n\t}\n#endif /* RE_ENABLE_I18N */\n      else if (type == OP_PERIOD\n#ifdef RE_ENABLE_I18N\n\t       || type == OP_UTF8_PERIOD\n#endif /* RE_ENABLE_I18N */\n\t       || type == END_OF_RE)\n\t{\n\t  memset (fastmap, '\\1', sizeof (char) * SBC_MAX);\n\t  if (type == END_OF_RE)\n\t    bufp->can_be_null = 1;\n\t  return;\n\t}\n    }\n}\n\f\n/* Entry point for POSIX code.  */\n/* regcomp takes a regular expression as a string and compiles it.\n\n   PREG is a regex_t *.  We do not expect any fields to be initialized,\n   since POSIX says we shouldn't.  Thus, we set\n\n     'buffer' to the compiled pattern;\n     'used' to the length of the compiled pattern;\n     'syntax' to RE_SYNTAX_POSIX_EXTENDED if the\n       REG_EXTENDED bit in CFLAGS is set; otherwise, to\n       RE_SYNTAX_POSIX_BASIC;\n     'newline_anchor' to REG_NEWLINE being set in CFLAGS;\n     'fastmap' to an allocated space for the fastmap;\n     'fastmap_accurate' to zero;\n     're_nsub' to the number of subexpressions in PATTERN.\n\n   PATTERN is the address of the pattern string.\n\n   CFLAGS is a series of bits which affect compilation.\n\n     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we\n     use POSIX basic syntax.\n\n     If REG_NEWLINE is set, then . and [^...] don't match newline.\n     Also, regexec will try a match beginning after every newline.\n\n     If REG_ICASE is set, then we considers upper- and lowercase\n     versions of letters to be equivalent when matching.\n\n     If REG_NOSUB is set, then when PREG is passed to regexec, that\n     routine will report only success or failure, and nothing about the\n     registers.\n\n   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for\n   the return codes and their meanings.)  */\n\nint\nregcomp (regex_t *__restrict preg, const char *__restrict pattern, int cflags)\n{\n  reg_errcode_t ret;\n  reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED\n\t\t\t : RE_SYNTAX_POSIX_BASIC);\n\n  preg->buffer = NULL;\n  preg->allocated = 0;\n  preg->used = 0;\n\n  /* Try to allocate space for the fastmap.  */\n  preg->fastmap = re_malloc (char, SBC_MAX);\n  if (__glibc_unlikely (preg->fastmap == NULL))\n    return REG_ESPACE;\n\n  syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;\n\n  /* If REG_NEWLINE is set, newlines are treated differently.  */\n  if (cflags & REG_NEWLINE)\n    { /* REG_NEWLINE implies neither . nor [^...] match newline.  */\n      syntax &= ~RE_DOT_NEWLINE;\n      syntax |= RE_HAT_LISTS_NOT_NEWLINE;\n      /* It also changes the matching behavior.  */\n      preg->newline_anchor = 1;\n    }\n  else\n    preg->newline_anchor = 0;\n  preg->no_sub = !!(cflags & REG_NOSUB);\n  preg->translate = NULL;\n\n  ret = re_compile_internal (preg, pattern, strlen (pattern), syntax);\n\n  /* POSIX doesn't distinguish between an unmatched open-group and an\n     unmatched close-group: both are REG_EPAREN.  */\n  if (ret == REG_ERPAREN)\n    ret = REG_EPAREN;\n\n  /* We have already checked preg->fastmap != NULL.  */\n  if (__glibc_likely (ret == REG_NOERROR))\n    /* Compute the fastmap now, since regexec cannot modify the pattern\n       buffer.  This function never fails in this implementation.  */\n    (void) re_compile_fastmap (preg);\n  else\n    {\n      /* Some error occurred while compiling the expression.  */\n      re_free (preg->fastmap);\n      preg->fastmap = NULL;\n    }\n\n  return (int) ret;\n}\nlibc_hidden_def (__regcomp)\nweak_alias (__regcomp, regcomp)\n\n/* Returns a message corresponding to an error code, ERRCODE, returned\n   from either regcomp or regexec.   We don't use PREG here.  */\n\nsize_t\nregerror (int errcode, const regex_t *__restrict preg, char *__restrict errbuf,\n\t  size_t errbuf_size)\n{\n  const char *msg;\n  size_t msg_size;\n  int nerrcodes = sizeof __re_error_msgid_idx / sizeof __re_error_msgid_idx[0];\n\n  if (__glibc_unlikely (errcode < 0 || errcode >= nerrcodes))\n    /* Only error codes returned by the rest of the code should be passed\n       to this routine.  If we are given anything else, or if other regex\n       code generates an invalid error code, then the program has a bug.\n       Dump core so we can fix it.  */\n    abort ();\n\n  msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]);\n\n  msg_size = strlen (msg) + 1; /* Includes the null.  */\n\n  if (__glibc_likely (errbuf_size != 0))\n    {\n      size_t cpy_size = msg_size;\n      if (__glibc_unlikely (msg_size > errbuf_size))\n\t{\n\t  cpy_size = errbuf_size - 1;\n\t  errbuf[cpy_size] = '\\0';\n\t}\n      memcpy (errbuf, msg, cpy_size);\n    }\n\n  return msg_size;\n}\nweak_alias (__regerror, regerror)\n\n\n#ifdef RE_ENABLE_I18N\n/* This static array is used for the map to single-byte characters when\n   UTF-8 is used.  Otherwise we would allocate memory just to initialize\n   it the same all the time.  UTF-8 is the preferred encoding so this is\n   a worthwhile optimization.  */\nstatic const bitset_t utf8_sb_map =\n{\n  /* Set the first 128 bits.  */\n# if (defined __GNUC__ || __clang_major__ >= 4) && !defined __STRICT_ANSI__\n  [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX\n# else\n#  if 4 * BITSET_WORD_BITS < ASCII_CHARS\n#   error \"bitset_word_t is narrower than 32 bits\"\n#  elif 3 * BITSET_WORD_BITS < ASCII_CHARS\n  BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX,\n#  elif 2 * BITSET_WORD_BITS < ASCII_CHARS\n  BITSET_WORD_MAX, BITSET_WORD_MAX,\n#  elif 1 * BITSET_WORD_BITS < ASCII_CHARS\n  BITSET_WORD_MAX,\n#  endif\n  (BITSET_WORD_MAX\n   >> (SBC_MAX % BITSET_WORD_BITS == 0\n       ? 0\n       : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS))\n# endif\n};\n#endif\n\n\nstatic void\nfree_dfa_content (re_dfa_t *dfa)\n{\n  Idx i, j;\n\n  if (dfa->nodes)\n    for (i = 0; i < dfa->nodes_len; ++i)\n      free_token (dfa->nodes + i);\n  re_free (dfa->nexts);\n  for (i = 0; i < dfa->nodes_len; ++i)\n    {\n      if (dfa->eclosures != NULL)\n\tre_node_set_free (dfa->eclosures + i);\n      if (dfa->inveclosures != NULL)\n\tre_node_set_free (dfa->inveclosures + i);\n      if (dfa->edests != NULL)\n\tre_node_set_free (dfa->edests + i);\n    }\n  re_free (dfa->edests);\n  re_free (dfa->eclosures);\n  re_free (dfa->inveclosures);\n  re_free (dfa->nodes);\n\n  if (dfa->state_table)\n    for (i = 0; i <= dfa->state_hash_mask; ++i)\n      {\n\tstruct re_state_table_entry *entry = dfa->state_table + i;\n\tfor (j = 0; j < entry->num; ++j)\n\t  {\n\t    re_dfastate_t *state = entry->array[j];\n\t    free_state (state);\n\t  }\n\tre_free (entry->array);\n      }\n  re_free (dfa->state_table);\n#ifdef RE_ENABLE_I18N\n  if (dfa->sb_char != utf8_sb_map)\n    re_free (dfa->sb_char);\n#endif\n  re_free (dfa->subexp_map);\n#ifdef DEBUG\n  re_free (dfa->re_str);\n#endif\n\n  re_free (dfa);\n}\n\n\n/* Free dynamically allocated space used by PREG.  */\n\nvoid\nregfree (regex_t *preg)\n{\n  re_dfa_t *dfa = preg->buffer;\n  if (__glibc_likely (dfa != NULL))\n    {\n      lock_fini (dfa->lock);\n      free_dfa_content (dfa);\n    }\n  preg->buffer = NULL;\n  preg->allocated = 0;\n\n  re_free (preg->fastmap);\n  preg->fastmap = NULL;\n\n  re_free (preg->translate);\n  preg->translate = NULL;\n}\nlibc_hidden_def (__regfree)\nweak_alias (__regfree, regfree)\n\f\n/* Entry points compatible with 4.2 BSD regex library.  We don't define\n   them unless specifically requested.  */\n\n#if defined _REGEX_RE_COMP || defined _LIBC\n\n/* BSD has one and only one pattern buffer.  */\nstatic struct re_pattern_buffer re_comp_buf;\n\nchar *\n# ifdef _LIBC\n/* Make these definitions weak in libc, so POSIX programs can redefine\n   these names if they don't use our functions, and still use\n   regcomp/regexec above without link errors.  */\nweak_function\n# endif\nre_comp (const char *s)\n{\n  reg_errcode_t ret;\n  char *fastmap;\n\n  if (!s)\n    {\n      if (!re_comp_buf.buffer)\n\treturn gettext (\"No previous regular expression\");\n      return 0;\n    }\n\n  if (re_comp_buf.buffer)\n    {\n      fastmap = re_comp_buf.fastmap;\n      re_comp_buf.fastmap = NULL;\n      __regfree (&re_comp_buf);\n      memset (&re_comp_buf, '\\0', sizeof (re_comp_buf));\n      re_comp_buf.fastmap = fastmap;\n    }\n\n  if (re_comp_buf.fastmap == NULL)\n    {\n      re_comp_buf.fastmap = re_malloc (char, SBC_MAX);\n      if (re_comp_buf.fastmap == NULL)\n\treturn (char *) gettext (__re_error_msgid\n\t\t\t\t + __re_error_msgid_idx[(int) REG_ESPACE]);\n    }\n\n  /* Since 're_exec' always passes NULL for the 'regs' argument, we\n     don't need to initialize the pattern buffer fields which affect it.  */\n\n  /* Match anchors at newlines.  */\n  re_comp_buf.newline_anchor = 1;\n\n  ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options);\n\n  if (!ret)\n    return NULL;\n\n  /* Yes, we're discarding 'const' here if !HAVE_LIBINTL.  */\n  return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);\n}\n\n#ifdef _LIBC\nlibc_freeres_fn (free_mem)\n{\n  __regfree (&re_comp_buf);\n}\n#endif\n\n#endif /* _REGEX_RE_COMP */\n\f\n/* Internal entry point.\n   Compile the regular expression PATTERN, whose length is LENGTH.\n   SYNTAX indicate regular expression's syntax.  */\n\nstatic reg_errcode_t\nre_compile_internal (regex_t *preg, const char * pattern, size_t length,\n\t\t     reg_syntax_t syntax)\n{\n  reg_errcode_t err = REG_NOERROR;\n  re_dfa_t *dfa;\n  re_string_t regexp;\n\n  /* Initialize the pattern buffer.  */\n  preg->fastmap_accurate = 0;\n  preg->syntax = syntax;\n  preg->not_bol = preg->not_eol = 0;\n  preg->used = 0;\n  preg->re_nsub = 0;\n  preg->can_be_null = 0;\n  preg->regs_allocated = REGS_UNALLOCATED;\n\n  /* Initialize the dfa.  */\n  dfa = preg->buffer;\n  if (__glibc_unlikely (preg->allocated < sizeof (re_dfa_t)))\n    {\n      /* If zero allocated, but buffer is non-null, try to realloc\n\t enough space.  This loses if buffer's address is bogus, but\n\t that is the user's responsibility.  If ->buffer is NULL this\n\t is a simple allocation.  */\n      dfa = re_realloc (preg->buffer, re_dfa_t, 1);\n      if (dfa == NULL)\n\treturn REG_ESPACE;\n      preg->allocated = sizeof (re_dfa_t);\n      preg->buffer = dfa;\n    }\n  preg->used = sizeof (re_dfa_t);\n\n  err = init_dfa (dfa, length);\n  if (__glibc_unlikely (err == REG_NOERROR && lock_init (dfa->lock) != 0))\n    err = REG_ESPACE;\n  if (__glibc_unlikely (err != REG_NOERROR))\n    {\n      free_dfa_content (dfa);\n      preg->buffer = NULL;\n      preg->allocated = 0;\n      return err;\n    }\n#ifdef DEBUG\n  /* Note: length+1 will not overflow since it is checked in init_dfa.  */\n  dfa->re_str = re_malloc (char, length + 1);\n  strncpy (dfa->re_str, pattern, length + 1);\n#endif\n\n  err = re_string_construct (&regexp, pattern, length, preg->translate,\n\t\t\t     (syntax & RE_ICASE) != 0, dfa);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    {\n    re_compile_internal_free_return:\n      free_workarea_compile (preg);\n      re_string_destruct (&regexp);\n      lock_fini (dfa->lock);\n      free_dfa_content (dfa);\n      preg->buffer = NULL;\n      preg->allocated = 0;\n      return err;\n    }\n\n  /* Parse the regular expression, and build a structure tree.  */\n  preg->re_nsub = 0;\n  dfa->str_tree = parse (&regexp, preg, syntax, &err);\n  if (__glibc_unlikely (dfa->str_tree == NULL))\n    goto re_compile_internal_free_return;\n\n  /* Analyze the tree and create the nfa.  */\n  err = analyze (preg);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    goto re_compile_internal_free_return;\n\n#ifdef RE_ENABLE_I18N\n  /* If possible, do searching in single byte encoding to speed things up.  */\n  if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL)\n    optimize_utf8 (dfa);\n#endif\n\n  /* Then create the initial state of the dfa.  */\n  err = create_initial_state (dfa);\n\n  /* Release work areas.  */\n  free_workarea_compile (preg);\n  re_string_destruct (&regexp);\n\n  if (__glibc_unlikely (err != REG_NOERROR))\n    {\n      lock_fini (dfa->lock);\n      free_dfa_content (dfa);\n      preg->buffer = NULL;\n      preg->allocated = 0;\n    }\n\n  return err;\n}\n\n/* Initialize DFA.  We use the length of the regular expression PAT_LEN\n   as the initial length of some arrays.  */\n\nstatic reg_errcode_t\ninit_dfa (re_dfa_t *dfa, size_t pat_len)\n{\n  __re_size_t table_size;\n#ifndef _LIBC\n  const char *codeset_name;\n#endif\n#ifdef RE_ENABLE_I18N\n  size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t));\n#else\n  size_t max_i18n_object_size = 0;\n#endif\n  size_t max_object_size =\n    MAX (sizeof (struct re_state_table_entry),\n\t MAX (sizeof (re_token_t),\n\t      MAX (sizeof (re_node_set),\n\t\t   MAX (sizeof (regmatch_t),\n\t\t\tmax_i18n_object_size))));\n\n  memset (dfa, '\\0', sizeof (re_dfa_t));\n\n  /* Force allocation of str_tree_storage the first time.  */\n  dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;\n\n  /* Avoid overflows.  The extra \"/ 2\" is for the table_size doubling\n     calculation below, and for similar doubling calculations\n     elsewhere.  And it's <= rather than <, because some of the\n     doubling calculations add 1 afterwards.  */\n  if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size) / 2\n\t\t\t<= pat_len))\n    return REG_ESPACE;\n\n  dfa->nodes_alloc = pat_len + 1;\n  dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc);\n\n  /*  table_size = 2 ^ ceil(log pat_len) */\n  for (table_size = 1; ; table_size <<= 1)\n    if (table_size > pat_len)\n      break;\n\n  dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);\n  dfa->state_hash_mask = table_size - 1;\n\n  dfa->mb_cur_max = MB_CUR_MAX;\n#ifdef _LIBC\n  if (dfa->mb_cur_max == 6\n      && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), \"UTF-8\") == 0)\n    dfa->is_utf8 = 1;\n  dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)\n\t\t       != 0);\n#else\n  codeset_name = nl_langinfo (CODESET);\n  if ((codeset_name[0] == 'U' || codeset_name[0] == 'u')\n      && (codeset_name[1] == 'T' || codeset_name[1] == 't')\n      && (codeset_name[2] == 'F' || codeset_name[2] == 'f')\n      && strcmp (codeset_name + 3 + (codeset_name[3] == '-'), \"8\") == 0)\n    dfa->is_utf8 = 1;\n\n  /* We check exhaustively in the loop below if this charset is a\n     superset of ASCII.  */\n  dfa->map_notascii = 0;\n#endif\n\n#ifdef RE_ENABLE_I18N\n  if (dfa->mb_cur_max > 1)\n    {\n      if (dfa->is_utf8)\n\tdfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;\n      else\n\t{\n\t  int i, j, ch;\n\n\t  dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);\n\t  if (__glibc_unlikely (dfa->sb_char == NULL))\n\t    return REG_ESPACE;\n\n\t  /* Set the bits corresponding to single byte chars.  */\n\t  for (i = 0, ch = 0; i < BITSET_WORDS; ++i)\n\t    for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)\n\t      {\n\t\twint_t wch = __btowc (ch);\n\t\tif (wch != WEOF)\n\t\t  dfa->sb_char[i] |= (bitset_word_t) 1 << j;\n# ifndef _LIBC\n\t\tif (isascii (ch) && wch != ch)\n\t\t  dfa->map_notascii = 1;\n# endif\n\t      }\n\t}\n    }\n#endif\n\n  if (__glibc_unlikely (dfa->nodes == NULL || dfa->state_table == NULL))\n    return REG_ESPACE;\n  return REG_NOERROR;\n}\n\n/* Initialize WORD_CHAR table, which indicate which character is\n   \"word\".  In this case \"word\" means that it is the word construction\n   character used by some operators like \"\\<\", \"\\>\", etc.  */\n\nstatic void\ninit_word_char (re_dfa_t *dfa)\n{\n  int i = 0;\n  int j;\n  int ch = 0;\n  dfa->word_ops_used = 1;\n  if (__glibc_likely (dfa->map_notascii == 0))\n    {\n      /* Avoid uint32_t and uint64_t as some non-GCC platforms lack\n\t them, an issue when this code is used in Gnulib.  */\n      bitset_word_t bits0 = 0x00000000;\n      bitset_word_t bits1 = 0x03ff0000;\n      bitset_word_t bits2 = 0x87fffffe;\n      bitset_word_t bits3 = 0x07fffffe;\n      if (BITSET_WORD_BITS == 64)\n\t{\n\t  /* Pacify gcc -Woverflow on 32-bit platformns.  */\n\t  dfa->word_char[0] = bits1 << 31 << 1 | bits0;\n\t  dfa->word_char[1] = bits3 << 31 << 1 | bits2;\n\t  i = 2;\n\t}\n      else if (BITSET_WORD_BITS == 32)\n\t{\n\t  dfa->word_char[0] = bits0;\n\t  dfa->word_char[1] = bits1;\n\t  dfa->word_char[2] = bits2;\n\t  dfa->word_char[3] = bits3;\n\t  i = 4;\n\t}\n      else\n        goto general_case;\n      ch = 128;\n\n      if (__glibc_likely (dfa->is_utf8))\n\t{\n\t  memset (&dfa->word_char[i], '\\0', (SBC_MAX - ch) / 8);\n\t  return;\n\t}\n    }\n\n general_case:\n  for (; i < BITSET_WORDS; ++i)\n    for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)\n      if (isalnum (ch) || ch == '_')\n\tdfa->word_char[i] |= (bitset_word_t) 1 << j;\n}\n\n/* Free the work area which are only used while compiling.  */\n\nstatic void\nfree_workarea_compile (regex_t *preg)\n{\n  re_dfa_t *dfa = preg->buffer;\n  bin_tree_storage_t *storage, *next;\n  for (storage = dfa->str_tree_storage; storage; storage = next)\n    {\n      next = storage->next;\n      re_free (storage);\n    }\n  dfa->str_tree_storage = NULL;\n  dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;\n  dfa->str_tree = NULL;\n  re_free (dfa->org_indices);\n  dfa->org_indices = NULL;\n}\n\n/* Create initial states for all contexts.  */\n\nstatic reg_errcode_t\ncreate_initial_state (re_dfa_t *dfa)\n{\n  Idx first, i;\n  reg_errcode_t err;\n  re_node_set init_nodes;\n\n  /* Initial states have the epsilon closure of the node which is\n     the first node of the regular expression.  */\n  first = dfa->str_tree->first->node_idx;\n  dfa->init_node = first;\n  err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    return err;\n\n  /* The back-references which are in initial states can epsilon transit,\n     since in this case all of the subexpressions can be null.\n     Then we add epsilon closures of the nodes which are the next nodes of\n     the back-references.  */\n  if (dfa->nbackref > 0)\n    for (i = 0; i < init_nodes.nelem; ++i)\n      {\n\tIdx node_idx = init_nodes.elems[i];\n\tre_token_type_t type = dfa->nodes[node_idx].type;\n\n\tIdx clexp_idx;\n\tif (type != OP_BACK_REF)\n\t  continue;\n\tfor (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx)\n\t  {\n\t    re_token_t *clexp_node;\n\t    clexp_node = dfa->nodes + init_nodes.elems[clexp_idx];\n\t    if (clexp_node->type == OP_CLOSE_SUBEXP\n\t\t&& clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx)\n\t      break;\n\t  }\n\tif (clexp_idx == init_nodes.nelem)\n\t  continue;\n\n\tif (type == OP_BACK_REF)\n\t  {\n\t    Idx dest_idx = dfa->edests[node_idx].elems[0];\n\t    if (!re_node_set_contains (&init_nodes, dest_idx))\n\t      {\n\t\treg_errcode_t merge_err\n                  = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);\n\t\tif (merge_err != REG_NOERROR)\n\t\t  return merge_err;\n\t\ti = 0;\n\t      }\n\t  }\n      }\n\n  /* It must be the first time to invoke acquire_state.  */\n  dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);\n  /* We don't check ERR here, since the initial state must not be NULL.  */\n  if (__glibc_unlikely (dfa->init_state == NULL))\n    return err;\n  if (dfa->init_state->has_constraint)\n    {\n      dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes,\n\t\t\t\t\t\t       CONTEXT_WORD);\n      dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes,\n\t\t\t\t\t\t     CONTEXT_NEWLINE);\n      dfa->init_state_begbuf = re_acquire_state_context (&err, dfa,\n\t\t\t\t\t\t\t &init_nodes,\n\t\t\t\t\t\t\t CONTEXT_NEWLINE\n\t\t\t\t\t\t\t | CONTEXT_BEGBUF);\n      if (__glibc_unlikely (dfa->init_state_word == NULL\n\t\t\t    || dfa->init_state_nl == NULL\n\t\t\t    || dfa->init_state_begbuf == NULL))\n\treturn err;\n    }\n  else\n    dfa->init_state_word = dfa->init_state_nl\n      = dfa->init_state_begbuf = dfa->init_state;\n\n  re_node_set_free (&init_nodes);\n  return REG_NOERROR;\n}\n\f\n#ifdef RE_ENABLE_I18N\n/* If it is possible to do searching in single byte encoding instead of UTF-8\n   to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change\n   DFA nodes where needed.  */\n\nstatic void\noptimize_utf8 (re_dfa_t *dfa)\n{\n  Idx node;\n  int i;\n  bool mb_chars = false;\n  bool has_period = false;\n\n  for (node = 0; node < dfa->nodes_len; ++node)\n    switch (dfa->nodes[node].type)\n      {\n      case CHARACTER:\n\tif (dfa->nodes[node].opr.c >= ASCII_CHARS)\n\t  mb_chars = true;\n\tbreak;\n      case ANCHOR:\n\tswitch (dfa->nodes[node].opr.ctx_type)\n\t  {\n\t  case LINE_FIRST:\n\t  case LINE_LAST:\n\t  case BUF_FIRST:\n\t  case BUF_LAST:\n\t    break;\n\t  default:\n\t    /* Word anchors etc. cannot be handled.  It's okay to test\n\t       opr.ctx_type since constraints (for all DFA nodes) are\n\t       created by ORing one or more opr.ctx_type values.  */\n\t    return;\n\t  }\n\tbreak;\n      case OP_PERIOD:\n\thas_period = true;\n\tbreak;\n      case OP_BACK_REF:\n      case OP_ALT:\n      case END_OF_RE:\n      case OP_DUP_ASTERISK:\n      case OP_OPEN_SUBEXP:\n      case OP_CLOSE_SUBEXP:\n\tbreak;\n      case COMPLEX_BRACKET:\n\treturn;\n      case SIMPLE_BRACKET:\n\t/* Just double check.  */\n\t{\n\t  int rshift = (ASCII_CHARS % BITSET_WORD_BITS == 0\n\t\t\t? 0\n\t\t\t: BITSET_WORD_BITS - ASCII_CHARS % BITSET_WORD_BITS);\n\t  for (i = ASCII_CHARS / BITSET_WORD_BITS; i < BITSET_WORDS; ++i)\n\t    {\n\t      if (dfa->nodes[node].opr.sbcset[i] >> rshift != 0)\n\t\treturn;\n\t      rshift = 0;\n\t    }\n\t}\n\tbreak;\n      default:\n\tabort ();\n      }\n\n  if (mb_chars || has_period)\n    for (node = 0; node < dfa->nodes_len; ++node)\n      {\n\tif (dfa->nodes[node].type == CHARACTER\n\t    && dfa->nodes[node].opr.c >= ASCII_CHARS)\n\t  dfa->nodes[node].mb_partial = 0;\n\telse if (dfa->nodes[node].type == OP_PERIOD)\n\t  dfa->nodes[node].type = OP_UTF8_PERIOD;\n      }\n\n  /* The search can be in single byte locale.  */\n  dfa->mb_cur_max = 1;\n  dfa->is_utf8 = 0;\n  dfa->has_mb_node = dfa->nbackref > 0 || has_period;\n}\n#endif\n\f\n/* Analyze the structure tree, and calculate \"first\", \"next\", \"edest\",\n   \"eclosure\", and \"inveclosure\".  */\n\nstatic reg_errcode_t\nanalyze (regex_t *preg)\n{\n  re_dfa_t *dfa = preg->buffer;\n  reg_errcode_t ret;\n\n  /* Allocate arrays.  */\n  dfa->nexts = re_malloc (Idx, dfa->nodes_alloc);\n  dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc);\n  dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);\n  dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);\n  if (__glibc_unlikely (dfa->nexts == NULL || dfa->org_indices == NULL\n\t\t\t|| dfa->edests == NULL || dfa->eclosures == NULL))\n    return REG_ESPACE;\n\n  dfa->subexp_map = re_malloc (Idx, preg->re_nsub);\n  if (dfa->subexp_map != NULL)\n    {\n      Idx i;\n      for (i = 0; i < preg->re_nsub; i++)\n\tdfa->subexp_map[i] = i;\n      preorder (dfa->str_tree, optimize_subexps, dfa);\n      for (i = 0; i < preg->re_nsub; i++)\n\tif (dfa->subexp_map[i] != i)\n\t  break;\n      if (i == preg->re_nsub)\n\t{\n\t  re_free (dfa->subexp_map);\n\t  dfa->subexp_map = NULL;\n\t}\n    }\n\n  ret = postorder (dfa->str_tree, lower_subexps, preg);\n  if (__glibc_unlikely (ret != REG_NOERROR))\n    return ret;\n  ret = postorder (dfa->str_tree, calc_first, dfa);\n  if (__glibc_unlikely (ret != REG_NOERROR))\n    return ret;\n  preorder (dfa->str_tree, calc_next, dfa);\n  ret = preorder (dfa->str_tree, link_nfa_nodes, dfa);\n  if (__glibc_unlikely (ret != REG_NOERROR))\n    return ret;\n  ret = calc_eclosure (dfa);\n  if (__glibc_unlikely (ret != REG_NOERROR))\n    return ret;\n\n  /* We only need this during the prune_impossible_nodes pass in regexec.c;\n     skip it if p_i_n will not run, as calc_inveclosure can be quadratic.  */\n  if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match)\n      || dfa->nbackref)\n    {\n      dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);\n      if (__glibc_unlikely (dfa->inveclosures == NULL))\n\treturn REG_ESPACE;\n      ret = calc_inveclosure (dfa);\n    }\n\n  return ret;\n}\n\n/* Our parse trees are very unbalanced, so we cannot use a stack to\n   implement parse tree visits.  Instead, we use parent pointers and\n   some hairy code in these two functions.  */\nstatic reg_errcode_t\npostorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),\n\t   void *extra)\n{\n  bin_tree_t *node, *prev;\n\n  for (node = root; ; )\n    {\n      /* Descend down the tree, preferably to the left (or to the right\n\t if that's the only child).  */\n      while (node->left || node->right)\n\tif (node->left)\n\t  node = node->left;\n\telse\n\t  node = node->right;\n\n      do\n\t{\n\t  reg_errcode_t err = fn (extra, node);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\t  if (node->parent == NULL)\n\t    return REG_NOERROR;\n\t  prev = node;\n\t  node = node->parent;\n\t}\n      /* Go up while we have a node that is reached from the right.  */\n      while (node->right == prev || node->right == NULL);\n      node = node->right;\n    }\n}\n\nstatic reg_errcode_t\npreorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),\n\t  void *extra)\n{\n  bin_tree_t *node;\n\n  for (node = root; ; )\n    {\n      reg_errcode_t err = fn (extra, node);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\treturn err;\n\n      /* Go to the left node, or up and to the right.  */\n      if (node->left)\n\tnode = node->left;\n      else\n\t{\n\t  bin_tree_t *prev = NULL;\n\t  while (node->right == prev || node->right == NULL)\n\t    {\n\t      prev = node;\n\t      node = node->parent;\n\t      if (!node)\n\t\treturn REG_NOERROR;\n\t    }\n\t  node = node->right;\n\t}\n    }\n}\n\n/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell\n   re_search_internal to map the inner one's opr.idx to this one's.  Adjust\n   backreferences as well.  Requires a preorder visit.  */\nstatic reg_errcode_t\noptimize_subexps (void *extra, bin_tree_t *node)\n{\n  re_dfa_t *dfa = (re_dfa_t *) extra;\n\n  if (node->token.type == OP_BACK_REF && dfa->subexp_map)\n    {\n      int idx = node->token.opr.idx;\n      node->token.opr.idx = dfa->subexp_map[idx];\n      dfa->used_bkref_map |= 1 << node->token.opr.idx;\n    }\n\n  else if (node->token.type == SUBEXP\n\t   && node->left && node->left->token.type == SUBEXP)\n    {\n      Idx other_idx = node->left->token.opr.idx;\n\n      node->left = node->left->left;\n      if (node->left)\n\tnode->left->parent = node;\n\n      dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx];\n      if (other_idx < BITSET_WORD_BITS)\n\tdfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx);\n    }\n\n  return REG_NOERROR;\n}\n\n/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation\n   of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP.  */\nstatic reg_errcode_t\nlower_subexps (void *extra, bin_tree_t *node)\n{\n  regex_t *preg = (regex_t *) extra;\n  reg_errcode_t err = REG_NOERROR;\n\n  if (node->left && node->left->token.type == SUBEXP)\n    {\n      node->left = lower_subexp (&err, preg, node->left);\n      if (node->left)\n\tnode->left->parent = node;\n    }\n  if (node->right && node->right->token.type == SUBEXP)\n    {\n      node->right = lower_subexp (&err, preg, node->right);\n      if (node->right)\n\tnode->right->parent = node;\n    }\n\n  return err;\n}\n\nstatic bin_tree_t *\nlower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node)\n{\n  re_dfa_t *dfa = preg->buffer;\n  bin_tree_t *body = node->left;\n  bin_tree_t *op, *cls, *tree1, *tree;\n\n  if (preg->no_sub\n      /* We do not optimize empty subexpressions, because otherwise we may\n\t have bad CONCAT nodes with NULL children.  This is obviously not\n\t very common, so we do not lose much.  An example that triggers\n\t this case is the sed \"script\" /\\(\\)/x.  */\n      && node->left != NULL\n      && (node->token.opr.idx >= BITSET_WORD_BITS\n\t  || !(dfa->used_bkref_map\n\t       & ((bitset_word_t) 1 << node->token.opr.idx))))\n    return node->left;\n\n  /* Convert the SUBEXP node to the concatenation of an\n     OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP.  */\n  op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP);\n  cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP);\n  tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls;\n  tree = create_tree (dfa, op, tree1, CONCAT);\n  if (__glibc_unlikely (tree == NULL || tree1 == NULL\n\t\t\t|| op == NULL || cls == NULL))\n    {\n      *err = REG_ESPACE;\n      return NULL;\n    }\n\n  op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx;\n  op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp;\n  return tree;\n}\n\n/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton\n   nodes.  Requires a postorder visit.  */\nstatic reg_errcode_t\ncalc_first (void *extra, bin_tree_t *node)\n{\n  re_dfa_t *dfa = (re_dfa_t *) extra;\n  if (node->token.type == CONCAT)\n    {\n      node->first = node->left->first;\n      node->node_idx = node->left->node_idx;\n    }\n  else\n    {\n      node->first = node;\n      node->node_idx = re_dfa_add_node (dfa, node->token);\n      if (__glibc_unlikely (node->node_idx == -1))\n\treturn REG_ESPACE;\n      if (node->token.type == ANCHOR)\n\tdfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;\n    }\n  return REG_NOERROR;\n}\n\n/* Pass 2: compute NEXT on the tree.  Preorder visit.  */\nstatic reg_errcode_t\ncalc_next (void *extra, bin_tree_t *node)\n{\n  switch (node->token.type)\n    {\n    case OP_DUP_ASTERISK:\n      node->left->next = node;\n      break;\n    case CONCAT:\n      node->left->next = node->right->first;\n      node->right->next = node->next;\n      break;\n    default:\n      if (node->left)\n\tnode->left->next = node->next;\n      if (node->right)\n\tnode->right->next = node->next;\n      break;\n    }\n  return REG_NOERROR;\n}\n\n/* Pass 3: link all DFA nodes to their NEXT node (any order will do).  */\nstatic reg_errcode_t\nlink_nfa_nodes (void *extra, bin_tree_t *node)\n{\n  re_dfa_t *dfa = (re_dfa_t *) extra;\n  Idx idx = node->node_idx;\n  reg_errcode_t err = REG_NOERROR;\n\n  switch (node->token.type)\n    {\n    case CONCAT:\n      break;\n\n    case END_OF_RE:\n      DEBUG_ASSERT (node->next == NULL);\n      break;\n\n    case OP_DUP_ASTERISK:\n    case OP_ALT:\n      {\n\tIdx left, right;\n\tdfa->has_plural_match = 1;\n\tif (node->left != NULL)\n\t  left = node->left->first->node_idx;\n\telse\n\t  left = node->next->node_idx;\n\tif (node->right != NULL)\n\t  right = node->right->first->node_idx;\n\telse\n\t  right = node->next->node_idx;\n\tDEBUG_ASSERT (left > -1);\n\tDEBUG_ASSERT (right > -1);\n\terr = re_node_set_init_2 (dfa->edests + idx, left, right);\n      }\n      break;\n\n    case ANCHOR:\n    case OP_OPEN_SUBEXP:\n    case OP_CLOSE_SUBEXP:\n      err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx);\n      break;\n\n    case OP_BACK_REF:\n      dfa->nexts[idx] = node->next->node_idx;\n      if (node->token.type == OP_BACK_REF)\n\terr = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);\n      break;\n\n    default:\n      DEBUG_ASSERT (!IS_EPSILON_NODE (node->token.type));\n      dfa->nexts[idx] = node->next->node_idx;\n      break;\n    }\n\n  return err;\n}\n\n/* Duplicate the epsilon closure of the node ROOT_NODE.\n   Note that duplicated nodes have constraint INIT_CONSTRAINT in addition\n   to their own constraint.  */\n\nstatic reg_errcode_t\nduplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,\n\t\t\tIdx root_node, unsigned int init_constraint)\n{\n  Idx org_node, clone_node;\n  bool ok;\n  unsigned int constraint = init_constraint;\n  for (org_node = top_org_node, clone_node = top_clone_node;;)\n    {\n      Idx org_dest, clone_dest;\n      if (dfa->nodes[org_node].type == OP_BACK_REF)\n\t{\n\t  /* If the back reference epsilon-transit, its destination must\n\t     also have the constraint.  Then duplicate the epsilon closure\n\t     of the destination of the back reference, and store it in\n\t     edests of the back reference.  */\n\t  org_dest = dfa->nexts[org_node];\n\t  re_node_set_empty (dfa->edests + clone_node);\n\t  clone_dest = duplicate_node (dfa, org_dest, constraint);\n\t  if (__glibc_unlikely (clone_dest == -1))\n\t    return REG_ESPACE;\n\t  dfa->nexts[clone_node] = dfa->nexts[org_node];\n\t  ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);\n\t  if (__glibc_unlikely (! ok))\n\t    return REG_ESPACE;\n\t}\n      else if (dfa->edests[org_node].nelem == 0)\n\t{\n\t  /* In case of the node can't epsilon-transit, don't duplicate the\n\t     destination and store the original destination as the\n\t     destination of the node.  */\n\t  dfa->nexts[clone_node] = dfa->nexts[org_node];\n\t  break;\n\t}\n      else if (dfa->edests[org_node].nelem == 1)\n\t{\n\t  /* In case of the node can epsilon-transit, and it has only one\n\t     destination.  */\n\t  org_dest = dfa->edests[org_node].elems[0];\n\t  re_node_set_empty (dfa->edests + clone_node);\n\t  /* If the node is root_node itself, it means the epsilon closure\n\t     has a loop.  Then tie it to the destination of the root_node.  */\n\t  if (org_node == root_node && clone_node != org_node)\n\t    {\n\t      ok = re_node_set_insert (dfa->edests + clone_node, org_dest);\n\t      if (__glibc_unlikely (! ok))\n\t        return REG_ESPACE;\n\t      break;\n\t    }\n\t  /* In case the node has another constraint, append it.  */\n\t  constraint |= dfa->nodes[org_node].constraint;\n\t  clone_dest = duplicate_node (dfa, org_dest, constraint);\n\t  if (__glibc_unlikely (clone_dest == -1))\n\t    return REG_ESPACE;\n\t  ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);\n\t  if (__glibc_unlikely (! ok))\n\t    return REG_ESPACE;\n\t}\n      else /* dfa->edests[org_node].nelem == 2 */\n\t{\n\t  /* In case of the node can epsilon-transit, and it has two\n\t     destinations. In the bin_tree_t and DFA, that's '|' and '*'.   */\n\t  org_dest = dfa->edests[org_node].elems[0];\n\t  re_node_set_empty (dfa->edests + clone_node);\n\t  /* Search for a duplicated node which satisfies the constraint.  */\n\t  clone_dest = search_duplicated_node (dfa, org_dest, constraint);\n\t  if (clone_dest == -1)\n\t    {\n\t      /* There is no such duplicated node, create a new one.  */\n\t      reg_errcode_t err;\n\t      clone_dest = duplicate_node (dfa, org_dest, constraint);\n\t      if (__glibc_unlikely (clone_dest == -1))\n\t\treturn REG_ESPACE;\n\t      ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);\n\t      if (__glibc_unlikely (! ok))\n\t\treturn REG_ESPACE;\n\t      err = duplicate_node_closure (dfa, org_dest, clone_dest,\n\t\t\t\t\t    root_node, constraint);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\treturn err;\n\t    }\n\t  else\n\t    {\n\t      /* There is a duplicated node which satisfies the constraint,\n\t\t use it to avoid infinite loop.  */\n\t      ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);\n\t      if (__glibc_unlikely (! ok))\n\t\treturn REG_ESPACE;\n\t    }\n\n\t  org_dest = dfa->edests[org_node].elems[1];\n\t  clone_dest = duplicate_node (dfa, org_dest, constraint);\n\t  if (__glibc_unlikely (clone_dest == -1))\n\t    return REG_ESPACE;\n\t  ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);\n\t  if (__glibc_unlikely (! ok))\n\t    return REG_ESPACE;\n\t}\n      org_node = org_dest;\n      clone_node = clone_dest;\n    }\n  return REG_NOERROR;\n}\n\n/* Search for a node which is duplicated from the node ORG_NODE, and\n   satisfies the constraint CONSTRAINT.  */\n\nstatic Idx\nsearch_duplicated_node (const re_dfa_t *dfa, Idx org_node,\n\t\t\tunsigned int constraint)\n{\n  Idx idx;\n  for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx)\n    {\n      if (org_node == dfa->org_indices[idx]\n\t  && constraint == dfa->nodes[idx].constraint)\n\treturn idx; /* Found.  */\n    }\n  return -1; /* Not found.  */\n}\n\n/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT.\n   Return the index of the new node, or -1 if insufficient storage is\n   available.  */\n\nstatic Idx\nduplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint)\n{\n  Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]);\n  if (__glibc_likely (dup_idx != -1))\n    {\n      dfa->nodes[dup_idx].constraint = constraint;\n      dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint;\n      dfa->nodes[dup_idx].duplicated = 1;\n\n      /* Store the index of the original node.  */\n      dfa->org_indices[dup_idx] = org_idx;\n    }\n  return dup_idx;\n}\n\nstatic reg_errcode_t\ncalc_inveclosure (re_dfa_t *dfa)\n{\n  Idx src, idx;\n  bool ok;\n  for (idx = 0; idx < dfa->nodes_len; ++idx)\n    re_node_set_init_empty (dfa->inveclosures + idx);\n\n  for (src = 0; src < dfa->nodes_len; ++src)\n    {\n      Idx *elems = dfa->eclosures[src].elems;\n      for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)\n\t{\n\t  ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src);\n\t  if (__glibc_unlikely (! ok))\n\t    return REG_ESPACE;\n\t}\n    }\n\n  return REG_NOERROR;\n}\n\n/* Calculate \"eclosure\" for all the node in DFA.  */\n\nstatic reg_errcode_t\ncalc_eclosure (re_dfa_t *dfa)\n{\n  Idx node_idx;\n  bool incomplete;\n  DEBUG_ASSERT (dfa->nodes_len > 0);\n  incomplete = false;\n  /* For each nodes, calculate epsilon closure.  */\n  for (node_idx = 0; ; ++node_idx)\n    {\n      reg_errcode_t err;\n      re_node_set eclosure_elem;\n      if (node_idx == dfa->nodes_len)\n\t{\n\t  if (!incomplete)\n\t    break;\n\t  incomplete = false;\n\t  node_idx = 0;\n\t}\n\n      DEBUG_ASSERT (dfa->eclosures[node_idx].nelem != -1);\n\n      /* If we have already calculated, skip it.  */\n      if (dfa->eclosures[node_idx].nelem != 0)\n\tcontinue;\n      /* Calculate epsilon closure of 'node_idx'.  */\n      err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\treturn err;\n\n      if (dfa->eclosures[node_idx].nelem == 0)\n\t{\n\t  incomplete = true;\n\t  re_node_set_free (&eclosure_elem);\n\t}\n    }\n  return REG_NOERROR;\n}\n\n/* Calculate epsilon closure of NODE.  */\n\nstatic reg_errcode_t\ncalc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)\n{\n  reg_errcode_t err;\n  Idx i;\n  re_node_set eclosure;\n  bool incomplete = false;\n  err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    return err;\n\n  /* An epsilon closure includes itself.  */\n  eclosure.elems[eclosure.nelem++] = node;\n\n  /* This indicates that we are calculating this node now.\n     We reference this value to avoid infinite loop.  */\n  dfa->eclosures[node].nelem = -1;\n\n  /* If the current node has constraints, duplicate all nodes\n     since they must inherit the constraints.  */\n  if (dfa->nodes[node].constraint\n      && dfa->edests[node].nelem\n      && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)\n    {\n      err = duplicate_node_closure (dfa, node, node, node,\n\t\t\t\t    dfa->nodes[node].constraint);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\treturn err;\n    }\n\n  /* Expand each epsilon destination nodes.  */\n  if (IS_EPSILON_NODE(dfa->nodes[node].type))\n    for (i = 0; i < dfa->edests[node].nelem; ++i)\n      {\n\tre_node_set eclosure_elem;\n\tIdx edest = dfa->edests[node].elems[i];\n\t/* If calculating the epsilon closure of 'edest' is in progress,\n\t   return intermediate result.  */\n\tif (dfa->eclosures[edest].nelem == -1)\n\t  {\n\t    incomplete = true;\n\t    continue;\n\t  }\n\t/* If we haven't calculated the epsilon closure of 'edest' yet,\n\t   calculate now. Otherwise use calculated epsilon closure.  */\n\tif (dfa->eclosures[edest].nelem == 0)\n\t  {\n\t    err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false);\n\t    if (__glibc_unlikely (err != REG_NOERROR))\n\t      return err;\n\t  }\n\telse\n\t  eclosure_elem = dfa->eclosures[edest];\n\t/* Merge the epsilon closure of 'edest'.  */\n\terr = re_node_set_merge (&eclosure, &eclosure_elem);\n\tif (__glibc_unlikely (err != REG_NOERROR))\n\t  return err;\n\t/* If the epsilon closure of 'edest' is incomplete,\n\t   the epsilon closure of this node is also incomplete.  */\n\tif (dfa->eclosures[edest].nelem == 0)\n\t  {\n\t    incomplete = true;\n\t    re_node_set_free (&eclosure_elem);\n\t  }\n      }\n\n  if (incomplete && !root)\n    dfa->eclosures[node].nelem = 0;\n  else\n    dfa->eclosures[node] = eclosure;\n  *new_set = eclosure;\n  return REG_NOERROR;\n}\n\f\n/* Functions for token which are used in the parser.  */\n\n/* Fetch a token from INPUT.\n   We must not use this function inside bracket expressions.  */\n\nstatic void\nfetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax)\n{\n  re_string_skip_bytes (input, peek_token (result, input, syntax));\n}\n\n/* Peek a token from INPUT, and return the length of the token.\n   We must not use this function inside bracket expressions.  */\n\nstatic int\npeek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)\n{\n  unsigned char c;\n\n  if (re_string_eoi (input))\n    {\n      token->type = END_OF_RE;\n      return 0;\n    }\n\n  c = re_string_peek_byte (input, 0);\n  token->opr.c = c;\n\n  token->word_char = 0;\n#ifdef RE_ENABLE_I18N\n  token->mb_partial = 0;\n  if (input->mb_cur_max > 1\n      && !re_string_first_byte (input, re_string_cur_idx (input)))\n    {\n      token->type = CHARACTER;\n      token->mb_partial = 1;\n      return 1;\n    }\n#endif\n  if (c == '\\\\')\n    {\n      unsigned char c2;\n      if (re_string_cur_idx (input) + 1 >= re_string_length (input))\n\t{\n\t  token->type = BACK_SLASH;\n\t  return 1;\n\t}\n\n      c2 = re_string_peek_byte_case (input, 1);\n      token->opr.c = c2;\n      token->type = CHARACTER;\n#ifdef RE_ENABLE_I18N\n      if (input->mb_cur_max > 1)\n\t{\n\t  wint_t wc = re_string_wchar_at (input,\n\t\t\t\t\t  re_string_cur_idx (input) + 1);\n\t  token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;\n\t}\n      else\n#endif\n\ttoken->word_char = IS_WORD_CHAR (c2) != 0;\n\n      switch (c2)\n\t{\n\tcase '|':\n\t  if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR))\n\t    token->type = OP_ALT;\n\t  break;\n\tcase '1': case '2': case '3': case '4': case '5':\n\tcase '6': case '7': case '8': case '9':\n\t  if (!(syntax & RE_NO_BK_REFS))\n\t    {\n\t      token->type = OP_BACK_REF;\n\t      token->opr.idx = c2 - '1';\n\t    }\n\t  break;\n\tcase '<':\n\t  if (!(syntax & RE_NO_GNU_OPS))\n\t    {\n\t      token->type = ANCHOR;\n\t      token->opr.ctx_type = WORD_FIRST;\n\t    }\n\t  break;\n\tcase '>':\n\t  if (!(syntax & RE_NO_GNU_OPS))\n\t    {\n\t      token->type = ANCHOR;\n\t      token->opr.ctx_type = WORD_LAST;\n\t    }\n\t  break;\n\tcase 'b':\n\t  if (!(syntax & RE_NO_GNU_OPS))\n\t    {\n\t      token->type = ANCHOR;\n\t      token->opr.ctx_type = WORD_DELIM;\n\t    }\n\t  break;\n\tcase 'B':\n\t  if (!(syntax & RE_NO_GNU_OPS))\n\t    {\n\t      token->type = ANCHOR;\n\t      token->opr.ctx_type = NOT_WORD_DELIM;\n\t    }\n\t  break;\n\tcase 'w':\n\t  if (!(syntax & RE_NO_GNU_OPS))\n\t    token->type = OP_WORD;\n\t  break;\n\tcase 'W':\n\t  if (!(syntax & RE_NO_GNU_OPS))\n\t    token->type = OP_NOTWORD;\n\t  break;\n\tcase 's':\n\t  if (!(syntax & RE_NO_GNU_OPS))\n\t    token->type = OP_SPACE;\n\t  break;\n\tcase 'S':\n\t  if (!(syntax & RE_NO_GNU_OPS))\n\t    token->type = OP_NOTSPACE;\n\t  break;\n\tcase '`':\n\t  if (!(syntax & RE_NO_GNU_OPS))\n\t    {\n\t      token->type = ANCHOR;\n\t      token->opr.ctx_type = BUF_FIRST;\n\t    }\n\t  break;\n\tcase '\\'':\n\t  if (!(syntax & RE_NO_GNU_OPS))\n\t    {\n\t      token->type = ANCHOR;\n\t      token->opr.ctx_type = BUF_LAST;\n\t    }\n\t  break;\n\tcase '(':\n\t  if (!(syntax & RE_NO_BK_PARENS))\n\t    token->type = OP_OPEN_SUBEXP;\n\t  break;\n\tcase ')':\n\t  if (!(syntax & RE_NO_BK_PARENS))\n\t    token->type = OP_CLOSE_SUBEXP;\n\t  break;\n\tcase '+':\n\t  if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))\n\t    token->type = OP_DUP_PLUS;\n\t  break;\n\tcase '?':\n\t  if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))\n\t    token->type = OP_DUP_QUESTION;\n\t  break;\n\tcase '{':\n\t  if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))\n\t    token->type = OP_OPEN_DUP_NUM;\n\t  break;\n\tcase '}':\n\t  if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))\n\t    token->type = OP_CLOSE_DUP_NUM;\n\t  break;\n\tdefault:\n\t  break;\n\t}\n      return 2;\n    }\n\n  token->type = CHARACTER;\n#ifdef RE_ENABLE_I18N\n  if (input->mb_cur_max > 1)\n    {\n      wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));\n      token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;\n    }\n  else\n#endif\n    token->word_char = IS_WORD_CHAR (token->opr.c);\n\n  switch (c)\n    {\n    case '\\n':\n      if (syntax & RE_NEWLINE_ALT)\n\ttoken->type = OP_ALT;\n      break;\n    case '|':\n      if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR))\n\ttoken->type = OP_ALT;\n      break;\n    case '*':\n      token->type = OP_DUP_ASTERISK;\n      break;\n    case '+':\n      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))\n\ttoken->type = OP_DUP_PLUS;\n      break;\n    case '?':\n      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))\n\ttoken->type = OP_DUP_QUESTION;\n      break;\n    case '{':\n      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))\n\ttoken->type = OP_OPEN_DUP_NUM;\n      break;\n    case '}':\n      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))\n\ttoken->type = OP_CLOSE_DUP_NUM;\n      break;\n    case '(':\n      if (syntax & RE_NO_BK_PARENS)\n\ttoken->type = OP_OPEN_SUBEXP;\n      break;\n    case ')':\n      if (syntax & RE_NO_BK_PARENS)\n\ttoken->type = OP_CLOSE_SUBEXP;\n      break;\n    case '[':\n      token->type = OP_OPEN_BRACKET;\n      break;\n    case '.':\n      token->type = OP_PERIOD;\n      break;\n    case '^':\n      if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE))\n\t  && re_string_cur_idx (input) != 0)\n\t{\n\t  char prev = re_string_peek_byte (input, -1);\n\t  if (!(syntax & RE_NEWLINE_ALT) || prev != '\\n')\n\t    break;\n\t}\n      token->type = ANCHOR;\n      token->opr.ctx_type = LINE_FIRST;\n      break;\n    case '$':\n      if (!(syntax & RE_CONTEXT_INDEP_ANCHORS)\n\t  && re_string_cur_idx (input) + 1 != re_string_length (input))\n\t{\n\t  re_token_t next;\n\t  re_string_skip_bytes (input, 1);\n\t  peek_token (&next, input, syntax);\n\t  re_string_skip_bytes (input, -1);\n\t  if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP)\n\t    break;\n\t}\n      token->type = ANCHOR;\n      token->opr.ctx_type = LINE_LAST;\n      break;\n    default:\n      break;\n    }\n  return 1;\n}\n\n/* Peek a token from INPUT, and return the length of the token.\n   We must not use this function out of bracket expressions.  */\n\nstatic int\npeek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)\n{\n  unsigned char c;\n  if (re_string_eoi (input))\n    {\n      token->type = END_OF_RE;\n      return 0;\n    }\n  c = re_string_peek_byte (input, 0);\n  token->opr.c = c;\n\n#ifdef RE_ENABLE_I18N\n  if (input->mb_cur_max > 1\n      && !re_string_first_byte (input, re_string_cur_idx (input)))\n    {\n      token->type = CHARACTER;\n      return 1;\n    }\n#endif /* RE_ENABLE_I18N */\n\n  if (c == '\\\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS)\n      && re_string_cur_idx (input) + 1 < re_string_length (input))\n    {\n      /* In this case, '\\' escape a character.  */\n      unsigned char c2;\n      re_string_skip_bytes (input, 1);\n      c2 = re_string_peek_byte (input, 0);\n      token->opr.c = c2;\n      token->type = CHARACTER;\n      return 1;\n    }\n  if (c == '[') /* '[' is a special char in a bracket exps.  */\n    {\n      unsigned char c2;\n      int token_len;\n      if (re_string_cur_idx (input) + 1 < re_string_length (input))\n\tc2 = re_string_peek_byte (input, 1);\n      else\n\tc2 = 0;\n      token->opr.c = c2;\n      token_len = 2;\n      switch (c2)\n\t{\n\tcase '.':\n\t  token->type = OP_OPEN_COLL_ELEM;\n\t  break;\n\n\tcase '=':\n\t  token->type = OP_OPEN_EQUIV_CLASS;\n\t  break;\n\n\tcase ':':\n\t  if (syntax & RE_CHAR_CLASSES)\n\t    {\n\t      token->type = OP_OPEN_CHAR_CLASS;\n\t      break;\n\t    }\n\t  FALLTHROUGH;\n\tdefault:\n\t  token->type = CHARACTER;\n\t  token->opr.c = c;\n\t  token_len = 1;\n\t  break;\n\t}\n      return token_len;\n    }\n  switch (c)\n    {\n    case '-':\n      token->type = OP_CHARSET_RANGE;\n      break;\n    case ']':\n      token->type = OP_CLOSE_BRACKET;\n      break;\n    case '^':\n      token->type = OP_NON_MATCH_LIST;\n      break;\n    default:\n      token->type = CHARACTER;\n    }\n  return 1;\n}\n\f\n/* Functions for parser.  */\n\n/* Entry point of the parser.\n   Parse the regular expression REGEXP and return the structure tree.\n   If an error occurs, ERR is set by error code, and return NULL.\n   This function build the following tree, from regular expression <reg_exp>:\n\t   CAT\n\t   / \\\n\t  /   \\\n   <reg_exp>  EOR\n\n   CAT means concatenation.\n   EOR means end of regular expression.  */\n\nstatic bin_tree_t *\nparse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax,\n       reg_errcode_t *err)\n{\n  re_dfa_t *dfa = preg->buffer;\n  bin_tree_t *tree, *eor, *root;\n  re_token_t current_token;\n  dfa->syntax = syntax;\n  fetch_token (&current_token, regexp, syntax | RE_CARET_ANCHORS_HERE);\n  tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);\n  if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))\n    return NULL;\n  eor = create_tree (dfa, NULL, NULL, END_OF_RE);\n  if (tree != NULL)\n    root = create_tree (dfa, tree, eor, CONCAT);\n  else\n    root = eor;\n  if (__glibc_unlikely (eor == NULL || root == NULL))\n    {\n      *err = REG_ESPACE;\n      return NULL;\n    }\n  return root;\n}\n\n/* This function build the following tree, from regular expression\n   <branch1>|<branch2>:\n\t   ALT\n\t   / \\\n\t  /   \\\n   <branch1> <branch2>\n\n   ALT means alternative, which represents the operator '|'.  */\n\nstatic bin_tree_t *\nparse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,\n\t       reg_syntax_t syntax, Idx nest, reg_errcode_t *err)\n{\n  re_dfa_t *dfa = preg->buffer;\n  bin_tree_t *tree, *branch = NULL;\n  bitset_word_t initial_bkref_map = dfa->completed_bkref_map;\n  tree = parse_branch (regexp, preg, token, syntax, nest, err);\n  if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))\n    return NULL;\n\n  while (token->type == OP_ALT)\n    {\n      fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);\n      if (token->type != OP_ALT && token->type != END_OF_RE\n\t  && (nest == 0 || token->type != OP_CLOSE_SUBEXP))\n\t{\n\t  bitset_word_t accumulated_bkref_map = dfa->completed_bkref_map;\n\t  dfa->completed_bkref_map = initial_bkref_map;\n\t  branch = parse_branch (regexp, preg, token, syntax, nest, err);\n\t  if (__glibc_unlikely (*err != REG_NOERROR && branch == NULL))\n\t    {\n\t      if (tree != NULL)\n\t\tpostorder (tree, free_tree, NULL);\n\t      return NULL;\n\t    }\n\t  dfa->completed_bkref_map |= accumulated_bkref_map;\n\t}\n      else\n\tbranch = NULL;\n      tree = create_tree (dfa, tree, branch, OP_ALT);\n      if (__glibc_unlikely (tree == NULL))\n\t{\n\t  *err = REG_ESPACE;\n\t  return NULL;\n\t}\n    }\n  return tree;\n}\n\n/* This function build the following tree, from regular expression\n   <exp1><exp2>:\n\tCAT\n\t/ \\\n       /   \\\n   <exp1> <exp2>\n\n   CAT means concatenation.  */\n\nstatic bin_tree_t *\nparse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token,\n\t      reg_syntax_t syntax, Idx nest, reg_errcode_t *err)\n{\n  bin_tree_t *tree, *expr;\n  re_dfa_t *dfa = preg->buffer;\n  tree = parse_expression (regexp, preg, token, syntax, nest, err);\n  if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))\n    return NULL;\n\n  while (token->type != OP_ALT && token->type != END_OF_RE\n\t && (nest == 0 || token->type != OP_CLOSE_SUBEXP))\n    {\n      expr = parse_expression (regexp, preg, token, syntax, nest, err);\n      if (__glibc_unlikely (*err != REG_NOERROR && expr == NULL))\n\t{\n\t  if (tree != NULL)\n\t    postorder (tree, free_tree, NULL);\n\t  return NULL;\n\t}\n      if (tree != NULL && expr != NULL)\n\t{\n\t  bin_tree_t *newtree = create_tree (dfa, tree, expr, CONCAT);\n\t  if (newtree == NULL)\n\t    {\n\t      postorder (expr, free_tree, NULL);\n\t      postorder (tree, free_tree, NULL);\n\t      *err = REG_ESPACE;\n\t      return NULL;\n\t    }\n\t  tree = newtree;\n\t}\n      else if (tree == NULL)\n\ttree = expr;\n      /* Otherwise expr == NULL, we don't need to create new tree.  */\n    }\n  return tree;\n}\n\n/* This function build the following tree, from regular expression a*:\n\t *\n\t |\n\t a\n*/\n\nstatic bin_tree_t *\nparse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,\n\t\t  reg_syntax_t syntax, Idx nest, reg_errcode_t *err)\n{\n  re_dfa_t *dfa = preg->buffer;\n  bin_tree_t *tree;\n  switch (token->type)\n    {\n    case CHARACTER:\n      tree = create_token_tree (dfa, NULL, NULL, token);\n      if (__glibc_unlikely (tree == NULL))\n\t{\n\t  *err = REG_ESPACE;\n\t  return NULL;\n\t}\n#ifdef RE_ENABLE_I18N\n      if (dfa->mb_cur_max > 1)\n\t{\n\t  while (!re_string_eoi (regexp)\n\t\t && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))\n\t    {\n\t      bin_tree_t *mbc_remain;\n\t      fetch_token (token, regexp, syntax);\n\t      mbc_remain = create_token_tree (dfa, NULL, NULL, token);\n\t      tree = create_tree (dfa, tree, mbc_remain, CONCAT);\n\t      if (__glibc_unlikely (mbc_remain == NULL || tree == NULL))\n\t\t{\n\t\t  *err = REG_ESPACE;\n\t\t  return NULL;\n\t\t}\n\t    }\n\t}\n#endif\n      break;\n\n    case OP_OPEN_SUBEXP:\n      tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err);\n      if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))\n\treturn NULL;\n      break;\n\n    case OP_OPEN_BRACKET:\n      tree = parse_bracket_exp (regexp, dfa, token, syntax, err);\n      if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))\n\treturn NULL;\n      break;\n\n    case OP_BACK_REF:\n      if (!__glibc_likely (dfa->completed_bkref_map & (1 << token->opr.idx)))\n\t{\n\t  *err = REG_ESUBREG;\n\t  return NULL;\n\t}\n      dfa->used_bkref_map |= 1 << token->opr.idx;\n      tree = create_token_tree (dfa, NULL, NULL, token);\n      if (__glibc_unlikely (tree == NULL))\n\t{\n\t  *err = REG_ESPACE;\n\t  return NULL;\n\t}\n      ++dfa->nbackref;\n      dfa->has_mb_node = 1;\n      break;\n\n    case OP_OPEN_DUP_NUM:\n      if (syntax & RE_CONTEXT_INVALID_DUP)\n\t{\n\t  *err = REG_BADRPT;\n\t  return NULL;\n\t}\n      FALLTHROUGH;\n    case OP_DUP_ASTERISK:\n    case OP_DUP_PLUS:\n    case OP_DUP_QUESTION:\n      if (syntax & RE_CONTEXT_INVALID_OPS)\n\t{\n\t  *err = REG_BADRPT;\n\t  return NULL;\n\t}\n      else if (syntax & RE_CONTEXT_INDEP_OPS)\n\t{\n\t  fetch_token (token, regexp, syntax);\n\t  return parse_expression (regexp, preg, token, syntax, nest, err);\n\t}\n      FALLTHROUGH;\n    case OP_CLOSE_SUBEXP:\n      if ((token->type == OP_CLOSE_SUBEXP)\n\t  && !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD))\n\t{\n\t  *err = REG_ERPAREN;\n\t  return NULL;\n\t}\n      FALLTHROUGH;\n    case OP_CLOSE_DUP_NUM:\n      /* We treat it as a normal character.  */\n\n      /* Then we can these characters as normal characters.  */\n      token->type = CHARACTER;\n      /* mb_partial and word_char bits should be initialized already\n\t by peek_token.  */\n      tree = create_token_tree (dfa, NULL, NULL, token);\n      if (__glibc_unlikely (tree == NULL))\n\t{\n\t  *err = REG_ESPACE;\n\t  return NULL;\n\t}\n      break;\n\n    case ANCHOR:\n      if ((token->opr.ctx_type\n\t   & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST))\n\t  && dfa->word_ops_used == 0)\n\tinit_word_char (dfa);\n      if (token->opr.ctx_type == WORD_DELIM\n\t  || token->opr.ctx_type == NOT_WORD_DELIM)\n\t{\n\t  bin_tree_t *tree_first, *tree_last;\n\t  if (token->opr.ctx_type == WORD_DELIM)\n\t    {\n\t      token->opr.ctx_type = WORD_FIRST;\n\t      tree_first = create_token_tree (dfa, NULL, NULL, token);\n\t      token->opr.ctx_type = WORD_LAST;\n\t    }\n\t  else\n\t    {\n\t      token->opr.ctx_type = INSIDE_WORD;\n\t      tree_first = create_token_tree (dfa, NULL, NULL, token);\n\t      token->opr.ctx_type = INSIDE_NOTWORD;\n\t    }\n\t  tree_last = create_token_tree (dfa, NULL, NULL, token);\n\t  tree = create_tree (dfa, tree_first, tree_last, OP_ALT);\n\t  if (__glibc_unlikely (tree_first == NULL || tree_last == NULL\n\t\t\t\t|| tree == NULL))\n\t    {\n\t      *err = REG_ESPACE;\n\t      return NULL;\n\t    }\n\t}\n      else\n\t{\n\t  tree = create_token_tree (dfa, NULL, NULL, token);\n\t  if (__glibc_unlikely (tree == NULL))\n\t    {\n\t      *err = REG_ESPACE;\n\t      return NULL;\n\t    }\n\t}\n      /* We must return here, since ANCHORs can't be followed\n\t by repetition operators.\n\t eg. RE\"^*\" is invalid or \"<ANCHOR(^)><CHAR(*)>\",\n\t     it must not be \"<ANCHOR(^)><REPEAT(*)>\".  */\n      fetch_token (token, regexp, syntax);\n      return tree;\n\n    case OP_PERIOD:\n      tree = create_token_tree (dfa, NULL, NULL, token);\n      if (__glibc_unlikely (tree == NULL))\n\t{\n\t  *err = REG_ESPACE;\n\t  return NULL;\n\t}\n      if (dfa->mb_cur_max > 1)\n\tdfa->has_mb_node = 1;\n      break;\n\n    case OP_WORD:\n    case OP_NOTWORD:\n      tree = build_charclass_op (dfa, regexp->trans,\n\t\t\t\t \"alnum\",\n\t\t\t\t \"_\",\n\t\t\t\t token->type == OP_NOTWORD, err);\n      if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))\n\treturn NULL;\n      break;\n\n    case OP_SPACE:\n    case OP_NOTSPACE:\n      tree = build_charclass_op (dfa, regexp->trans,\n\t\t\t\t \"space\",\n\t\t\t\t \"\",\n\t\t\t\t token->type == OP_NOTSPACE, err);\n      if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))\n\treturn NULL;\n      break;\n\n    case OP_ALT:\n    case END_OF_RE:\n      return NULL;\n\n    case BACK_SLASH:\n      *err = REG_EESCAPE;\n      return NULL;\n\n    default:\n      /* Must not happen?  */\n      DEBUG_ASSERT (false);\n      return NULL;\n    }\n  fetch_token (token, regexp, syntax);\n\n  while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS\n\t || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)\n    {\n      bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token,\n\t\t\t\t\t   syntax, err);\n      if (__glibc_unlikely (*err != REG_NOERROR && dup_tree == NULL))\n\t{\n\t  if (tree != NULL)\n\t    postorder (tree, free_tree, NULL);\n\t  return NULL;\n\t}\n      tree = dup_tree;\n      /* In BRE consecutive duplications are not allowed.  */\n      if ((syntax & RE_CONTEXT_INVALID_DUP)\n\t  && (token->type == OP_DUP_ASTERISK\n\t      || token->type == OP_OPEN_DUP_NUM))\n\t{\n\t  if (tree != NULL)\n\t    postorder (tree, free_tree, NULL);\n\t  *err = REG_BADRPT;\n\t  return NULL;\n\t}\n    }\n\n  return tree;\n}\n\n/* This function build the following tree, from regular expression\n   (<reg_exp>):\n\t SUBEXP\n\t    |\n\t<reg_exp>\n*/\n\nstatic bin_tree_t *\nparse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,\n\t       reg_syntax_t syntax, Idx nest, reg_errcode_t *err)\n{\n  re_dfa_t *dfa = preg->buffer;\n  bin_tree_t *tree;\n  size_t cur_nsub;\n  cur_nsub = preg->re_nsub++;\n\n  fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);\n\n  /* The subexpression may be a null string.  */\n  if (token->type == OP_CLOSE_SUBEXP)\n    tree = NULL;\n  else\n    {\n      tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);\n      if (__glibc_unlikely (*err == REG_NOERROR\n\t\t\t    && token->type != OP_CLOSE_SUBEXP))\n\t{\n\t  if (tree != NULL)\n\t    postorder (tree, free_tree, NULL);\n\t  *err = REG_EPAREN;\n\t}\n      if (__glibc_unlikely (*err != REG_NOERROR))\n\treturn NULL;\n    }\n\n  if (cur_nsub <= '9' - '1')\n    dfa->completed_bkref_map |= 1 << cur_nsub;\n\n  tree = create_tree (dfa, tree, NULL, SUBEXP);\n  if (__glibc_unlikely (tree == NULL))\n    {\n      *err = REG_ESPACE;\n      return NULL;\n    }\n  tree->token.opr.idx = cur_nsub;\n  return tree;\n}\n\n/* This function parse repetition operators like \"*\", \"+\", \"{1,3}\" etc.  */\n\nstatic bin_tree_t *\nparse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,\n\t      re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err)\n{\n  bin_tree_t *tree = NULL, *old_tree = NULL;\n  Idx i, start, end, start_idx = re_string_cur_idx (regexp);\n  re_token_t start_token = *token;\n\n  if (token->type == OP_OPEN_DUP_NUM)\n    {\n      end = 0;\n      start = fetch_number (regexp, token, syntax);\n      if (start == -1)\n\t{\n\t  if (token->type == CHARACTER && token->opr.c == ',')\n\t    start = 0; /* We treat \"{,m}\" as \"{0,m}\".  */\n\t  else\n\t    {\n\t      *err = REG_BADBR; /* <re>{} is invalid.  */\n\t      return NULL;\n\t    }\n\t}\n      if (__glibc_likely (start != -2))\n\t{\n\t  /* We treat \"{n}\" as \"{n,n}\".  */\n\t  end = ((token->type == OP_CLOSE_DUP_NUM) ? start\n\t\t : ((token->type == CHARACTER && token->opr.c == ',')\n\t\t    ? fetch_number (regexp, token, syntax) : -2));\n\t}\n      if (__glibc_unlikely (start == -2 || end == -2))\n\t{\n\t  /* Invalid sequence.  */\n\t  if (__glibc_unlikely (!(syntax & RE_INVALID_INTERVAL_ORD)))\n\t    {\n\t      if (token->type == END_OF_RE)\n\t\t*err = REG_EBRACE;\n\t      else\n\t\t*err = REG_BADBR;\n\n\t      return NULL;\n\t    }\n\n\t  /* If the syntax bit is set, rollback.  */\n\t  re_string_set_index (regexp, start_idx);\n\t  *token = start_token;\n\t  token->type = CHARACTER;\n\t  /* mb_partial and word_char bits should be already initialized by\n\t     peek_token.  */\n\t  return elem;\n\t}\n\n      if (__glibc_unlikely ((end != -1 && start > end)\n\t\t\t    || token->type != OP_CLOSE_DUP_NUM))\n\t{\n\t  /* First number greater than second.  */\n\t  *err = REG_BADBR;\n\t  return NULL;\n\t}\n\n      if (__glibc_unlikely (RE_DUP_MAX < (end == -1 ? start : end)))\n\t{\n\t  *err = REG_ESIZE;\n\t  return NULL;\n\t}\n    }\n  else\n    {\n      start = (token->type == OP_DUP_PLUS) ? 1 : 0;\n      end = (token->type == OP_DUP_QUESTION) ? 1 : -1;\n    }\n\n  fetch_token (token, regexp, syntax);\n\n  if (__glibc_unlikely (elem == NULL))\n    return NULL;\n  if (__glibc_unlikely (start == 0 && end == 0))\n    {\n      postorder (elem, free_tree, NULL);\n      return NULL;\n    }\n\n  /* Extract \"<re>{n,m}\" to \"<re><re>...<re><re>{0,<m-n>}\".  */\n  if (__glibc_unlikely (start > 0))\n    {\n      tree = elem;\n      for (i = 2; i <= start; ++i)\n\t{\n\t  elem = duplicate_tree (elem, dfa);\n\t  tree = create_tree (dfa, tree, elem, CONCAT);\n\t  if (__glibc_unlikely (elem == NULL || tree == NULL))\n\t    goto parse_dup_op_espace;\n\t}\n\n      if (start == end)\n\treturn tree;\n\n      /* Duplicate ELEM before it is marked optional.  */\n      elem = duplicate_tree (elem, dfa);\n      if (__glibc_unlikely (elem == NULL))\n        goto parse_dup_op_espace;\n      old_tree = tree;\n    }\n  else\n    old_tree = NULL;\n\n  if (elem->token.type == SUBEXP)\n    {\n      uintptr_t subidx = elem->token.opr.idx;\n      postorder (elem, mark_opt_subexp, (void *) subidx);\n    }\n\n  tree = create_tree (dfa, elem, NULL,\n\t\t      (end == -1 ? OP_DUP_ASTERISK : OP_ALT));\n  if (__glibc_unlikely (tree == NULL))\n    goto parse_dup_op_espace;\n\n  /* This loop is actually executed only when end != -1,\n     to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?...  We have\n     already created the start+1-th copy.  */\n  if (TYPE_SIGNED (Idx) || end != -1)\n    for (i = start + 2; i <= end; ++i)\n      {\n\telem = duplicate_tree (elem, dfa);\n\ttree = create_tree (dfa, tree, elem, CONCAT);\n\tif (__glibc_unlikely (elem == NULL || tree == NULL))\n\t  goto parse_dup_op_espace;\n\n\ttree = create_tree (dfa, tree, NULL, OP_ALT);\n\tif (__glibc_unlikely (tree == NULL))\n\t  goto parse_dup_op_espace;\n      }\n\n  if (old_tree)\n    tree = create_tree (dfa, old_tree, tree, CONCAT);\n\n  return tree;\n\n parse_dup_op_espace:\n  *err = REG_ESPACE;\n  return NULL;\n}\n\n/* Size of the names for collating symbol/equivalence_class/character_class.\n   I'm not sure, but maybe enough.  */\n#define BRACKET_NAME_BUF_SIZE 32\n\n#ifndef _LIBC\n\n# ifdef RE_ENABLE_I18N\n/* Convert the byte B to the corresponding wide character.  In a\n   unibyte locale, treat B as itself.  In a multibyte locale, return\n   WEOF if B is an encoding error.  */\nstatic wint_t\nparse_byte (unsigned char b, re_charset_t *mbcset)\n{\n  return mbcset == NULL ? b : __btowc (b);\n}\n# endif\n\n  /* Local function for parse_bracket_exp only used in case of NOT _LIBC.\n     Build the range expression which starts from START_ELEM, and ends\n     at END_ELEM.  The result are written to MBCSET and SBCSET.\n     RANGE_ALLOC is the allocated size of mbcset->range_starts, and\n     mbcset->range_ends, is a pointer argument since we may\n     update it.  */\n\nstatic reg_errcode_t\n# ifdef RE_ENABLE_I18N\nbuild_range_exp (const reg_syntax_t syntax,\n                 bitset_t sbcset,\n                 re_charset_t *mbcset,\n                 Idx *range_alloc,\n                 const bracket_elem_t *start_elem,\n                 const bracket_elem_t *end_elem)\n# else /* not RE_ENABLE_I18N */\nbuild_range_exp (const reg_syntax_t syntax,\n                 bitset_t sbcset,\n                 const bracket_elem_t *start_elem,\n                 const bracket_elem_t *end_elem)\n# endif /* not RE_ENABLE_I18N */\n{\n  unsigned int start_ch, end_ch;\n  /* Equivalence Classes and Character Classes can't be a range start/end.  */\n  if (__glibc_unlikely (start_elem->type == EQUIV_CLASS\n\t\t\t|| start_elem->type == CHAR_CLASS\n\t\t\t|| end_elem->type == EQUIV_CLASS\n\t\t\t|| end_elem->type == CHAR_CLASS))\n    return REG_ERANGE;\n\n  /* We can handle no multi character collating elements without libc\n     support.  */\n  if (__glibc_unlikely ((start_elem->type == COLL_SYM\n\t\t\t && strlen ((char *) start_elem->opr.name) > 1)\n\t\t\t|| (end_elem->type == COLL_SYM\n\t\t\t    && strlen ((char *) end_elem->opr.name) > 1)))\n    return REG_ECOLLATE;\n\n# ifdef RE_ENABLE_I18N\n  {\n    wchar_t wc;\n    wint_t start_wc;\n    wint_t end_wc;\n\n    start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch\n\t\t: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]\n\t\t   : 0));\n    end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch\n\t      : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]\n\t\t : 0));\n    start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM)\n\t\t? parse_byte (start_ch, mbcset) : start_elem->opr.wch);\n    end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM)\n\t      ? parse_byte (end_ch, mbcset) : end_elem->opr.wch);\n    if (start_wc == WEOF || end_wc == WEOF)\n      return REG_ECOLLATE;\n    else if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES)\n\t\t\t       && start_wc > end_wc))\n      return REG_ERANGE;\n\n    /* Got valid collation sequence values, add them as a new entry.\n       However, for !_LIBC we have no collation elements: if the\n       character set is single byte, the single byte character set\n       that we build below suffices.  parse_bracket_exp passes\n       no MBCSET if dfa->mb_cur_max == 1.  */\n    if (mbcset)\n      {\n\t/* Check the space of the arrays.  */\n\tif (__glibc_unlikely (*range_alloc == mbcset->nranges))\n\t  {\n\t    /* There is not enough space, need realloc.  */\n\t    wchar_t *new_array_start, *new_array_end;\n\t    Idx new_nranges;\n\n\t    /* +1 in case of mbcset->nranges is 0.  */\n\t    new_nranges = 2 * mbcset->nranges + 1;\n\t    /* Use realloc since mbcset->range_starts and mbcset->range_ends\n\t       are NULL if *range_alloc == 0.  */\n\t    new_array_start = re_realloc (mbcset->range_starts, wchar_t,\n\t\t\t\t\t  new_nranges);\n\t    new_array_end = re_realloc (mbcset->range_ends, wchar_t,\n\t\t\t\t\tnew_nranges);\n\n\t    if (__glibc_unlikely (new_array_start == NULL\n\t\t\t\t  || new_array_end == NULL))\n\t      {\n\t\tre_free (new_array_start);\n\t\tre_free (new_array_end);\n\t\treturn REG_ESPACE;\n\t      }\n\n\t    mbcset->range_starts = new_array_start;\n\t    mbcset->range_ends = new_array_end;\n\t    *range_alloc = new_nranges;\n\t  }\n\n\tmbcset->range_starts[mbcset->nranges] = start_wc;\n\tmbcset->range_ends[mbcset->nranges++] = end_wc;\n      }\n\n    /* Build the table for single byte characters.  */\n    for (wc = 0; wc < SBC_MAX; ++wc)\n      {\n\tif (start_wc <= wc && wc <= end_wc)\n\t  bitset_set (sbcset, wc);\n      }\n  }\n# else /* not RE_ENABLE_I18N */\n  {\n    unsigned int ch;\n    start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch\n\t\t: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]\n\t\t   : 0));\n    end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch\n\t      : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]\n\t\t : 0));\n    if (start_ch > end_ch)\n      return REG_ERANGE;\n    /* Build the table for single byte characters.  */\n    for (ch = 0; ch < SBC_MAX; ++ch)\n      if (start_ch <= ch  && ch <= end_ch)\n\tbitset_set (sbcset, ch);\n  }\n# endif /* not RE_ENABLE_I18N */\n  return REG_NOERROR;\n}\n#endif /* not _LIBC */\n\n#ifndef _LIBC\n/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..\n   Build the collating element which is represented by NAME.\n   The result are written to MBCSET and SBCSET.\n   COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a\n   pointer argument since we may update it.  */\n\nstatic reg_errcode_t\n# ifdef RE_ENABLE_I18N\nbuild_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,\n\t\t\tIdx *coll_sym_alloc, const unsigned char *name)\n# else /* not RE_ENABLE_I18N */\nbuild_collating_symbol (bitset_t sbcset, const unsigned char *name)\n# endif /* not RE_ENABLE_I18N */\n{\n  size_t name_len = strlen ((const char *) name);\n  if (__glibc_unlikely (name_len != 1))\n    return REG_ECOLLATE;\n  else\n    {\n      bitset_set (sbcset, name[0]);\n      return REG_NOERROR;\n    }\n}\n#endif /* not _LIBC */\n\n/* This function parse bracket expression like \"[abc]\", \"[a-c]\",\n   \"[[.a-a.]]\" etc.  */\n\nstatic bin_tree_t *\nparse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,\n\t\t   reg_syntax_t syntax, reg_errcode_t *err)\n{\n#ifdef _LIBC\n  const unsigned char *collseqmb;\n  const char *collseqwc;\n  uint32_t nrules;\n  int32_t table_size;\n  const int32_t *symb_table;\n  const unsigned char *extra;\n\n  /* Local function for parse_bracket_exp used in _LIBC environment.\n     Seek the collating symbol entry corresponding to NAME.\n     Return the index of the symbol in the SYMB_TABLE,\n     or -1 if not found.  */\n\n  auto inline int32_t\n  __attribute__ ((always_inline))\n  seek_collating_symbol_entry (const unsigned char *name, size_t name_len)\n    {\n      int32_t elem;\n\n      for (elem = 0; elem < table_size; elem++)\n\tif (symb_table[2 * elem] != 0)\n\t  {\n\t    int32_t idx = symb_table[2 * elem + 1];\n\t    /* Skip the name of collating element name.  */\n\t    idx += 1 + extra[idx];\n\t    if (/* Compare the length of the name.  */\n\t\tname_len == extra[idx]\n\t\t/* Compare the name.  */\n\t\t&& memcmp (name, &extra[idx + 1], name_len) == 0)\n\t      /* Yep, this is the entry.  */\n\t      return elem;\n\t  }\n      return -1;\n    }\n\n  /* Local function for parse_bracket_exp used in _LIBC environment.\n     Look up the collation sequence value of BR_ELEM.\n     Return the value if succeeded, UINT_MAX otherwise.  */\n\n  auto inline unsigned int\n  __attribute__ ((always_inline))\n  lookup_collation_sequence_value (bracket_elem_t *br_elem)\n    {\n      if (br_elem->type == SB_CHAR)\n\t{\n\t  /*\n\t  if (MB_CUR_MAX == 1)\n\t  */\n\t  if (nrules == 0)\n\t    return collseqmb[br_elem->opr.ch];\n\t  else\n\t    {\n\t      wint_t wc = __btowc (br_elem->opr.ch);\n\t      return __collseq_table_lookup (collseqwc, wc);\n\t    }\n\t}\n      else if (br_elem->type == MB_CHAR)\n\t{\n\t  if (nrules != 0)\n\t    return __collseq_table_lookup (collseqwc, br_elem->opr.wch);\n\t}\n      else if (br_elem->type == COLL_SYM)\n\t{\n\t  size_t sym_name_len = strlen ((char *) br_elem->opr.name);\n\t  if (nrules != 0)\n\t    {\n\t      int32_t elem, idx;\n\t      elem = seek_collating_symbol_entry (br_elem->opr.name,\n\t\t\t\t\t\t  sym_name_len);\n\t      if (elem != -1)\n\t\t{\n\t\t  /* We found the entry.  */\n\t\t  idx = symb_table[2 * elem + 1];\n\t\t  /* Skip the name of collating element name.  */\n\t\t  idx += 1 + extra[idx];\n\t\t  /* Skip the byte sequence of the collating element.  */\n\t\t  idx += 1 + extra[idx];\n\t\t  /* Adjust for the alignment.  */\n\t\t  idx = (idx + 3) & ~3;\n\t\t  /* Skip the multibyte collation sequence value.  */\n\t\t  idx += sizeof (unsigned int);\n\t\t  /* Skip the wide char sequence of the collating element.  */\n\t\t  idx += sizeof (unsigned int) *\n\t\t    (1 + *(unsigned int *) (extra + idx));\n\t\t  /* Return the collation sequence value.  */\n\t\t  return *(unsigned int *) (extra + idx);\n\t\t}\n\t      else if (sym_name_len == 1)\n\t\t{\n\t\t  /* No valid character.  Match it as a single byte\n\t\t     character.  */\n\t\t  return collseqmb[br_elem->opr.name[0]];\n\t\t}\n\t    }\n\t  else if (sym_name_len == 1)\n\t    return collseqmb[br_elem->opr.name[0]];\n\t}\n      return UINT_MAX;\n    }\n\n  /* Local function for parse_bracket_exp used in _LIBC environment.\n     Build the range expression which starts from START_ELEM, and ends\n     at END_ELEM.  The result are written to MBCSET and SBCSET.\n     RANGE_ALLOC is the allocated size of mbcset->range_starts, and\n     mbcset->range_ends, is a pointer argument since we may\n     update it.  */\n\n  auto inline reg_errcode_t\n  __attribute__ ((always_inline))\n  build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc,\n\t\t   bracket_elem_t *start_elem, bracket_elem_t *end_elem)\n    {\n      unsigned int ch;\n      uint32_t start_collseq;\n      uint32_t end_collseq;\n\n      /* Equivalence Classes and Character Classes can't be a range\n\t start/end.  */\n      if (__glibc_unlikely (start_elem->type == EQUIV_CLASS\n\t\t\t    || start_elem->type == CHAR_CLASS\n\t\t\t    || end_elem->type == EQUIV_CLASS\n\t\t\t    || end_elem->type == CHAR_CLASS))\n\treturn REG_ERANGE;\n\n      /* FIXME: Implement rational ranges here, too.  */\n      start_collseq = lookup_collation_sequence_value (start_elem);\n      end_collseq = lookup_collation_sequence_value (end_elem);\n      /* Check start/end collation sequence values.  */\n      if (__glibc_unlikely (start_collseq == UINT_MAX\n\t\t\t    || end_collseq == UINT_MAX))\n\treturn REG_ECOLLATE;\n      if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES)\n\t\t\t    && start_collseq > end_collseq))\n\treturn REG_ERANGE;\n\n      /* Got valid collation sequence values, add them as a new entry.\n\t However, if we have no collation elements, and the character set\n\t is single byte, the single byte character set that we\n\t build below suffices. */\n      if (nrules > 0 || dfa->mb_cur_max > 1)\n\t{\n\t  /* Check the space of the arrays.  */\n\t  if (__glibc_unlikely (*range_alloc == mbcset->nranges))\n\t    {\n\t      /* There is not enough space, need realloc.  */\n\t      uint32_t *new_array_start;\n\t      uint32_t *new_array_end;\n\t      Idx new_nranges;\n\n\t      /* +1 in case of mbcset->nranges is 0.  */\n\t      new_nranges = 2 * mbcset->nranges + 1;\n\t      new_array_start = re_realloc (mbcset->range_starts, uint32_t,\n\t\t\t\t\t    new_nranges);\n\t      new_array_end = re_realloc (mbcset->range_ends, uint32_t,\n\t\t\t\t\t  new_nranges);\n\n\t      if (__glibc_unlikely (new_array_start == NULL\n\t\t\t\t    || new_array_end == NULL))\n\t\treturn REG_ESPACE;\n\n\t      mbcset->range_starts = new_array_start;\n\t      mbcset->range_ends = new_array_end;\n\t      *range_alloc = new_nranges;\n\t    }\n\n\t  mbcset->range_starts[mbcset->nranges] = start_collseq;\n\t  mbcset->range_ends[mbcset->nranges++] = end_collseq;\n\t}\n\n      /* Build the table for single byte characters.  */\n      for (ch = 0; ch < SBC_MAX; ch++)\n\t{\n\t  uint32_t ch_collseq;\n\t  /*\n\t  if (MB_CUR_MAX == 1)\n\t  */\n\t  if (nrules == 0)\n\t    ch_collseq = collseqmb[ch];\n\t  else\n\t    ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));\n\t  if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)\n\t    bitset_set (sbcset, ch);\n\t}\n      return REG_NOERROR;\n    }\n\n  /* Local function for parse_bracket_exp used in _LIBC environment.\n     Build the collating element which is represented by NAME.\n     The result are written to MBCSET and SBCSET.\n     COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a\n     pointer argument since we may update it.  */\n\n  auto inline reg_errcode_t\n  __attribute__ ((always_inline))\n  build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,\n\t\t\t  Idx *coll_sym_alloc, const unsigned char *name)\n    {\n      int32_t elem, idx;\n      size_t name_len = strlen ((const char *) name);\n      if (nrules != 0)\n\t{\n\t  elem = seek_collating_symbol_entry (name, name_len);\n\t  if (elem != -1)\n\t    {\n\t      /* We found the entry.  */\n\t      idx = symb_table[2 * elem + 1];\n\t      /* Skip the name of collating element name.  */\n\t      idx += 1 + extra[idx];\n\t    }\n\t  else if (name_len == 1)\n\t    {\n\t      /* No valid character, treat it as a normal\n\t\t character.  */\n\t      bitset_set (sbcset, name[0]);\n\t      return REG_NOERROR;\n\t    }\n\t  else\n\t    return REG_ECOLLATE;\n\n\t  /* Got valid collation sequence, add it as a new entry.  */\n\t  /* Check the space of the arrays.  */\n\t  if (__glibc_unlikely (*coll_sym_alloc == mbcset->ncoll_syms))\n\t    {\n\t      /* Not enough, realloc it.  */\n\t      /* +1 in case of mbcset->ncoll_syms is 0.  */\n\t      Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;\n\t      /* Use realloc since mbcset->coll_syms is NULL\n\t\t if *alloc == 0.  */\n\t      int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,\n\t\t\t\t\t\t   new_coll_sym_alloc);\n\t      if (__glibc_unlikely (new_coll_syms == NULL))\n\t\treturn REG_ESPACE;\n\t      mbcset->coll_syms = new_coll_syms;\n\t      *coll_sym_alloc = new_coll_sym_alloc;\n\t    }\n\t  mbcset->coll_syms[mbcset->ncoll_syms++] = idx;\n\t  return REG_NOERROR;\n\t}\n      else\n\t{\n\t  if (__glibc_unlikely (name_len != 1))\n\t    return REG_ECOLLATE;\n\t  else\n\t    {\n\t      bitset_set (sbcset, name[0]);\n\t      return REG_NOERROR;\n\t    }\n\t}\n    }\n#endif\n\n  re_token_t br_token;\n  re_bitset_ptr_t sbcset;\n#ifdef RE_ENABLE_I18N\n  re_charset_t *mbcset;\n  Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;\n  Idx equiv_class_alloc = 0, char_class_alloc = 0;\n#endif /* not RE_ENABLE_I18N */\n  bool non_match = false;\n  bin_tree_t *work_tree;\n  int token_len;\n  bool first_round = true;\n#ifdef _LIBC\n  collseqmb = (const unsigned char *)\n    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);\n  nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);\n  if (nrules)\n    {\n      /*\n      if (MB_CUR_MAX > 1)\n      */\n      collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);\n      table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB);\n      symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE,\n\t\t\t\t\t\t  _NL_COLLATE_SYMB_TABLEMB);\n      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,\n\t\t\t\t\t\t   _NL_COLLATE_SYMB_EXTRAMB);\n    }\n#endif\n  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);\n#ifdef RE_ENABLE_I18N\n  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);\n#endif /* RE_ENABLE_I18N */\n#ifdef RE_ENABLE_I18N\n  if (__glibc_unlikely (sbcset == NULL || mbcset == NULL))\n#else\n  if (__glibc_unlikely (sbcset == NULL))\n#endif /* RE_ENABLE_I18N */\n    {\n      re_free (sbcset);\n#ifdef RE_ENABLE_I18N\n      re_free (mbcset);\n#endif\n      *err = REG_ESPACE;\n      return NULL;\n    }\n\n  token_len = peek_token_bracket (token, regexp, syntax);\n  if (__glibc_unlikely (token->type == END_OF_RE))\n    {\n      *err = REG_BADPAT;\n      goto parse_bracket_exp_free_return;\n    }\n  if (token->type == OP_NON_MATCH_LIST)\n    {\n#ifdef RE_ENABLE_I18N\n      mbcset->non_match = 1;\n#endif /* not RE_ENABLE_I18N */\n      non_match = true;\n      if (syntax & RE_HAT_LISTS_NOT_NEWLINE)\n\tbitset_set (sbcset, '\\n');\n      re_string_skip_bytes (regexp, token_len); /* Skip a token.  */\n      token_len = peek_token_bracket (token, regexp, syntax);\n      if (__glibc_unlikely (token->type == END_OF_RE))\n\t{\n\t  *err = REG_BADPAT;\n\t  goto parse_bracket_exp_free_return;\n\t}\n    }\n\n  /* We treat the first ']' as a normal character.  */\n  if (token->type == OP_CLOSE_BRACKET)\n    token->type = CHARACTER;\n\n  while (1)\n    {\n      bracket_elem_t start_elem, end_elem;\n      unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE];\n      unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE];\n      reg_errcode_t ret;\n      int token_len2 = 0;\n      bool is_range_exp = false;\n      re_token_t token2;\n\n      start_elem.opr.name = start_name_buf;\n      start_elem.type = COLL_SYM;\n      ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,\n\t\t\t\t   syntax, first_round);\n      if (__glibc_unlikely (ret != REG_NOERROR))\n\t{\n\t  *err = ret;\n\t  goto parse_bracket_exp_free_return;\n\t}\n      first_round = false;\n\n      /* Get information about the next token.  We need it in any case.  */\n      token_len = peek_token_bracket (token, regexp, syntax);\n\n      /* Do not check for ranges if we know they are not allowed.  */\n      if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS)\n\t{\n\t  if (__glibc_unlikely (token->type == END_OF_RE))\n\t    {\n\t      *err = REG_EBRACK;\n\t      goto parse_bracket_exp_free_return;\n\t    }\n\t  if (token->type == OP_CHARSET_RANGE)\n\t    {\n\t      re_string_skip_bytes (regexp, token_len); /* Skip '-'.  */\n\t      token_len2 = peek_token_bracket (&token2, regexp, syntax);\n\t      if (__glibc_unlikely (token2.type == END_OF_RE))\n\t\t{\n\t\t  *err = REG_EBRACK;\n\t\t  goto parse_bracket_exp_free_return;\n\t\t}\n\t      if (token2.type == OP_CLOSE_BRACKET)\n\t\t{\n\t\t  /* We treat the last '-' as a normal character.  */\n\t\t  re_string_skip_bytes (regexp, -token_len);\n\t\t  token->type = CHARACTER;\n\t\t}\n\t      else\n\t\tis_range_exp = true;\n\t    }\n\t}\n\n      if (is_range_exp == true)\n\t{\n\t  end_elem.opr.name = end_name_buf;\n\t  end_elem.type = COLL_SYM;\n\t  ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,\n\t\t\t\t       dfa, syntax, true);\n\t  if (__glibc_unlikely (ret != REG_NOERROR))\n\t    {\n\t      *err = ret;\n\t      goto parse_bracket_exp_free_return;\n\t    }\n\n\t  token_len = peek_token_bracket (token, regexp, syntax);\n\n#ifdef _LIBC\n\t  *err = build_range_exp (sbcset, mbcset, &range_alloc,\n\t\t\t\t  &start_elem, &end_elem);\n#else\n# ifdef RE_ENABLE_I18N\n\t  *err = build_range_exp (syntax, sbcset,\n\t\t\t\t  dfa->mb_cur_max > 1 ? mbcset : NULL,\n\t\t\t\t  &range_alloc, &start_elem, &end_elem);\n# else\n\t  *err = build_range_exp (syntax, sbcset, &start_elem, &end_elem);\n# endif\n#endif /* RE_ENABLE_I18N */\n\t  if (__glibc_unlikely (*err != REG_NOERROR))\n\t    goto parse_bracket_exp_free_return;\n\t}\n      else\n\t{\n\t  switch (start_elem.type)\n\t    {\n\t    case SB_CHAR:\n\t      bitset_set (sbcset, start_elem.opr.ch);\n\t      break;\n#ifdef RE_ENABLE_I18N\n\t    case MB_CHAR:\n\t      /* Check whether the array has enough space.  */\n\t      if (__glibc_unlikely (mbchar_alloc == mbcset->nmbchars))\n\t\t{\n\t\t  wchar_t *new_mbchars;\n\t\t  /* Not enough, realloc it.  */\n\t\t  /* +1 in case of mbcset->nmbchars is 0.  */\n\t\t  mbchar_alloc = 2 * mbcset->nmbchars + 1;\n\t\t  /* Use realloc since array is NULL if *alloc == 0.  */\n\t\t  new_mbchars = re_realloc (mbcset->mbchars, wchar_t,\n\t\t\t\t\t    mbchar_alloc);\n\t\t  if (__glibc_unlikely (new_mbchars == NULL))\n\t\t    goto parse_bracket_exp_espace;\n\t\t  mbcset->mbchars = new_mbchars;\n\t\t}\n\t      mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;\n\t      break;\n#endif /* RE_ENABLE_I18N */\n\t    case EQUIV_CLASS:\n\t      *err = build_equiv_class (sbcset,\n#ifdef RE_ENABLE_I18N\n\t\t\t\t\tmbcset, &equiv_class_alloc,\n#endif /* RE_ENABLE_I18N */\n\t\t\t\t\tstart_elem.opr.name);\n\t      if (__glibc_unlikely (*err != REG_NOERROR))\n\t\tgoto parse_bracket_exp_free_return;\n\t      break;\n\t    case COLL_SYM:\n\t      *err = build_collating_symbol (sbcset,\n#ifdef RE_ENABLE_I18N\n\t\t\t\t\t     mbcset, &coll_sym_alloc,\n#endif /* RE_ENABLE_I18N */\n\t\t\t\t\t     start_elem.opr.name);\n\t      if (__glibc_unlikely (*err != REG_NOERROR))\n\t\tgoto parse_bracket_exp_free_return;\n\t      break;\n\t    case CHAR_CLASS:\n\t      *err = build_charclass (regexp->trans, sbcset,\n#ifdef RE_ENABLE_I18N\n\t\t\t\t      mbcset, &char_class_alloc,\n#endif /* RE_ENABLE_I18N */\n\t\t\t\t      (const char *) start_elem.opr.name,\n\t\t\t\t      syntax);\n\t      if (__glibc_unlikely (*err != REG_NOERROR))\n\t       goto parse_bracket_exp_free_return;\n\t      break;\n\t    default:\n\t      DEBUG_ASSERT (false);\n\t      break;\n\t    }\n\t}\n      if (__glibc_unlikely (token->type == END_OF_RE))\n\t{\n\t  *err = REG_EBRACK;\n\t  goto parse_bracket_exp_free_return;\n\t}\n      if (token->type == OP_CLOSE_BRACKET)\n\tbreak;\n    }\n\n  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */\n\n  /* If it is non-matching list.  */\n  if (non_match)\n    bitset_not (sbcset);\n\n#ifdef RE_ENABLE_I18N\n  /* Ensure only single byte characters are set.  */\n  if (dfa->mb_cur_max > 1)\n    bitset_mask (sbcset, dfa->sb_char);\n\n  if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes\n      || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes\n\t\t\t\t\t\t     || mbcset->non_match)))\n    {\n      bin_tree_t *mbc_tree;\n      int sbc_idx;\n      /* Build a tree for complex bracket.  */\n      dfa->has_mb_node = 1;\n      br_token.type = COMPLEX_BRACKET;\n      br_token.opr.mbcset = mbcset;\n      mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);\n      if (__glibc_unlikely (mbc_tree == NULL))\n\tgoto parse_bracket_exp_espace;\n      for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx)\n\tif (sbcset[sbc_idx])\n\t  break;\n      /* If there are no bits set in sbcset, there is no point\n\t of having both SIMPLE_BRACKET and COMPLEX_BRACKET.  */\n      if (sbc_idx < BITSET_WORDS)\n\t{\n\t  /* Build a tree for simple bracket.  */\n\t  br_token.type = SIMPLE_BRACKET;\n\t  br_token.opr.sbcset = sbcset;\n\t  work_tree = create_token_tree (dfa, NULL, NULL, &br_token);\n\t  if (__glibc_unlikely (work_tree == NULL))\n\t    goto parse_bracket_exp_espace;\n\n\t  /* Then join them by ALT node.  */\n\t  work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT);\n\t  if (__glibc_unlikely (work_tree == NULL))\n\t    goto parse_bracket_exp_espace;\n\t}\n      else\n\t{\n\t  re_free (sbcset);\n\t  work_tree = mbc_tree;\n\t}\n    }\n  else\n#endif /* not RE_ENABLE_I18N */\n    {\n#ifdef RE_ENABLE_I18N\n      free_charset (mbcset);\n#endif\n      /* Build a tree for simple bracket.  */\n      br_token.type = SIMPLE_BRACKET;\n      br_token.opr.sbcset = sbcset;\n      work_tree = create_token_tree (dfa, NULL, NULL, &br_token);\n      if (__glibc_unlikely (work_tree == NULL))\n\tgoto parse_bracket_exp_espace;\n    }\n  return work_tree;\n\n parse_bracket_exp_espace:\n  *err = REG_ESPACE;\n parse_bracket_exp_free_return:\n  re_free (sbcset);\n#ifdef RE_ENABLE_I18N\n  free_charset (mbcset);\n#endif /* RE_ENABLE_I18N */\n  return NULL;\n}\n\n/* Parse an element in the bracket expression.  */\n\nstatic reg_errcode_t\nparse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,\n\t\t       re_token_t *token, int token_len, re_dfa_t *dfa,\n\t\t       reg_syntax_t syntax, bool accept_hyphen)\n{\n#ifdef RE_ENABLE_I18N\n  int cur_char_size;\n  cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));\n  if (cur_char_size > 1)\n    {\n      elem->type = MB_CHAR;\n      elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp));\n      re_string_skip_bytes (regexp, cur_char_size);\n      return REG_NOERROR;\n    }\n#endif /* RE_ENABLE_I18N */\n  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */\n  if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS\n      || token->type == OP_OPEN_EQUIV_CLASS)\n    return parse_bracket_symbol (elem, regexp, token);\n  if (__glibc_unlikely (token->type == OP_CHARSET_RANGE) && !accept_hyphen)\n    {\n      /* A '-' must only appear as anything but a range indicator before\n\t the closing bracket.  Everything else is an error.  */\n      re_token_t token2;\n      (void) peek_token_bracket (&token2, regexp, syntax);\n      if (token2.type != OP_CLOSE_BRACKET)\n\t/* The actual error value is not standardized since this whole\n\t   case is undefined.  But ERANGE makes good sense.  */\n\treturn REG_ERANGE;\n    }\n  elem->type = SB_CHAR;\n  elem->opr.ch = token->opr.c;\n  return REG_NOERROR;\n}\n\n/* Parse a bracket symbol in the bracket expression.  Bracket symbols are\n   such as [:<character_class>:], [.<collating_element>.], and\n   [=<equivalent_class>=].  */\n\nstatic reg_errcode_t\nparse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp,\n\t\t      re_token_t *token)\n{\n  unsigned char ch, delim = token->opr.c;\n  int i = 0;\n  if (re_string_eoi(regexp))\n    return REG_EBRACK;\n  for (;; ++i)\n    {\n      if (i >= BRACKET_NAME_BUF_SIZE)\n\treturn REG_EBRACK;\n      if (token->type == OP_OPEN_CHAR_CLASS)\n\tch = re_string_fetch_byte_case (regexp);\n      else\n\tch = re_string_fetch_byte (regexp);\n      if (re_string_eoi(regexp))\n\treturn REG_EBRACK;\n      if (ch == delim && re_string_peek_byte (regexp, 0) == ']')\n\tbreak;\n      elem->opr.name[i] = ch;\n    }\n  re_string_skip_bytes (regexp, 1);\n  elem->opr.name[i] = '\\0';\n  switch (token->type)\n    {\n    case OP_OPEN_COLL_ELEM:\n      elem->type = COLL_SYM;\n      break;\n    case OP_OPEN_EQUIV_CLASS:\n      elem->type = EQUIV_CLASS;\n      break;\n    case OP_OPEN_CHAR_CLASS:\n      elem->type = CHAR_CLASS;\n      break;\n    default:\n      break;\n    }\n  return REG_NOERROR;\n}\n\n  /* Helper function for parse_bracket_exp.\n     Build the equivalence class which is represented by NAME.\n     The result are written to MBCSET and SBCSET.\n     EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes,\n     is a pointer argument since we may update it.  */\n\nstatic reg_errcode_t\n#ifdef RE_ENABLE_I18N\nbuild_equiv_class (bitset_t sbcset, re_charset_t *mbcset,\n\t\t   Idx *equiv_class_alloc, const unsigned char *name)\n#else /* not RE_ENABLE_I18N */\nbuild_equiv_class (bitset_t sbcset, const unsigned char *name)\n#endif /* not RE_ENABLE_I18N */\n{\n#ifdef _LIBC\n  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);\n  if (nrules != 0)\n    {\n      const int32_t *table, *indirect;\n      const unsigned char *weights, *extra, *cp;\n      unsigned char char_buf[2];\n      int32_t idx1, idx2;\n      unsigned int ch;\n      size_t len;\n      /* Calculate the index for equivalence class.  */\n      cp = name;\n      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);\n      weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE,\n\t\t\t\t\t       _NL_COLLATE_WEIGHTMB);\n      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,\n\t\t\t\t\t\t   _NL_COLLATE_EXTRAMB);\n      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,\n\t\t\t\t\t\t_NL_COLLATE_INDIRECTMB);\n      idx1 = findidx (table, indirect, extra, &cp, -1);\n      if (__glibc_unlikely (idx1 == 0 || *cp != '\\0'))\n\t/* This isn't a valid character.  */\n\treturn REG_ECOLLATE;\n\n      /* Build single byte matching table for this equivalence class.  */\n      len = weights[idx1 & 0xffffff];\n      for (ch = 0; ch < SBC_MAX; ++ch)\n\t{\n\t  char_buf[0] = ch;\n\t  cp = char_buf;\n\t  idx2 = findidx (table, indirect, extra, &cp, 1);\n/*\n\t  idx2 = table[ch];\n*/\n\t  if (idx2 == 0)\n\t    /* This isn't a valid character.  */\n\t    continue;\n\t  /* Compare only if the length matches and the collation rule\n\t     index is the same.  */\n\t  if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24)\n\t      && memcmp (weights + (idx1 & 0xffffff) + 1,\n\t\t\t weights + (idx2 & 0xffffff) + 1, len) == 0)\n\t    bitset_set (sbcset, ch);\n\t}\n      /* Check whether the array has enough space.  */\n      if (__glibc_unlikely (*equiv_class_alloc == mbcset->nequiv_classes))\n\t{\n\t  /* Not enough, realloc it.  */\n\t  /* +1 in case of mbcset->nequiv_classes is 0.  */\n\t  Idx new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1;\n\t  /* Use realloc since the array is NULL if *alloc == 0.  */\n\t  int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes,\n\t\t\t\t\t\t   int32_t,\n\t\t\t\t\t\t   new_equiv_class_alloc);\n\t  if (__glibc_unlikely (new_equiv_classes == NULL))\n\t    return REG_ESPACE;\n\t  mbcset->equiv_classes = new_equiv_classes;\n\t  *equiv_class_alloc = new_equiv_class_alloc;\n\t}\n      mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;\n    }\n  else\n#endif /* _LIBC */\n    {\n      if (__glibc_unlikely (strlen ((const char *) name) != 1))\n\treturn REG_ECOLLATE;\n      bitset_set (sbcset, *name);\n    }\n  return REG_NOERROR;\n}\n\n  /* Helper function for parse_bracket_exp.\n     Build the character class which is represented by NAME.\n     The result are written to MBCSET and SBCSET.\n     CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes,\n     is a pointer argument since we may update it.  */\n\nstatic reg_errcode_t\n#ifdef RE_ENABLE_I18N\nbuild_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,\n\t\t re_charset_t *mbcset, Idx *char_class_alloc,\n\t\t const char *class_name, reg_syntax_t syntax)\n#else /* not RE_ENABLE_I18N */\nbuild_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,\n\t\t const char *class_name, reg_syntax_t syntax)\n#endif /* not RE_ENABLE_I18N */\n{\n  int i;\n  const char *name = class_name;\n\n  /* In case of REG_ICASE \"upper\" and \"lower\" match the both of\n     upper and lower cases.  */\n  if ((syntax & RE_ICASE)\n      && (strcmp (name, \"upper\") == 0 || strcmp (name, \"lower\") == 0))\n    name = \"alpha\";\n\n#ifdef RE_ENABLE_I18N\n  /* Check the space of the arrays.  */\n  if (__glibc_unlikely (*char_class_alloc == mbcset->nchar_classes))\n    {\n      /* Not enough, realloc it.  */\n      /* +1 in case of mbcset->nchar_classes is 0.  */\n      Idx new_char_class_alloc = 2 * mbcset->nchar_classes + 1;\n      /* Use realloc since array is NULL if *alloc == 0.  */\n      wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t,\n\t\t\t\t\t       new_char_class_alloc);\n      if (__glibc_unlikely (new_char_classes == NULL))\n\treturn REG_ESPACE;\n      mbcset->char_classes = new_char_classes;\n      *char_class_alloc = new_char_class_alloc;\n    }\n  mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);\n#endif /* RE_ENABLE_I18N */\n\n#define BUILD_CHARCLASS_LOOP(ctype_func)\t\\\n  do {\t\t\t\t\t\t\\\n    if (__glibc_unlikely (trans != NULL))\t\t\t\\\n      {\t\t\t\t\t\t\\\n\tfor (i = 0; i < SBC_MAX; ++i)\t\t\\\n\t  if (ctype_func (i))\t\t\t\\\n\t    bitset_set (sbcset, trans[i]);\t\\\n      }\t\t\t\t\t\t\\\n    else\t\t\t\t\t\\\n      {\t\t\t\t\t\t\\\n\tfor (i = 0; i < SBC_MAX; ++i)\t\t\\\n\t  if (ctype_func (i))\t\t\t\\\n\t    bitset_set (sbcset, i);\t\t\\\n      }\t\t\t\t\t\t\\\n  } while (0)\n\n  if (strcmp (name, \"alnum\") == 0)\n    BUILD_CHARCLASS_LOOP (isalnum);\n  else if (strcmp (name, \"cntrl\") == 0)\n    BUILD_CHARCLASS_LOOP (iscntrl);\n  else if (strcmp (name, \"lower\") == 0)\n    BUILD_CHARCLASS_LOOP (islower);\n  else if (strcmp (name, \"space\") == 0)\n    BUILD_CHARCLASS_LOOP (isspace);\n  else if (strcmp (name, \"alpha\") == 0)\n    BUILD_CHARCLASS_LOOP (isalpha);\n  else if (strcmp (name, \"digit\") == 0)\n    BUILD_CHARCLASS_LOOP (isdigit);\n  else if (strcmp (name, \"print\") == 0)\n    BUILD_CHARCLASS_LOOP (isprint);\n  else if (strcmp (name, \"upper\") == 0)\n    BUILD_CHARCLASS_LOOP (isupper);\n  else if (strcmp (name, \"blank\") == 0)\n    BUILD_CHARCLASS_LOOP (isblank);\n  else if (strcmp (name, \"graph\") == 0)\n    BUILD_CHARCLASS_LOOP (isgraph);\n  else if (strcmp (name, \"punct\") == 0)\n    BUILD_CHARCLASS_LOOP (ispunct);\n  else if (strcmp (name, \"xdigit\") == 0)\n    BUILD_CHARCLASS_LOOP (isxdigit);\n  else\n    return REG_ECTYPE;\n\n  return REG_NOERROR;\n}\n\nstatic bin_tree_t *\nbuild_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,\n\t\t    const char *class_name,\n\t\t    const char *extra, bool non_match,\n\t\t    reg_errcode_t *err)\n{\n  re_bitset_ptr_t sbcset;\n#ifdef RE_ENABLE_I18N\n  re_charset_t *mbcset;\n  Idx alloc = 0;\n#endif /* not RE_ENABLE_I18N */\n  reg_errcode_t ret;\n  bin_tree_t *tree;\n\n  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);\n  if (__glibc_unlikely (sbcset == NULL))\n    {\n      *err = REG_ESPACE;\n      return NULL;\n    }\n#ifdef RE_ENABLE_I18N\n  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);\n  if (__glibc_unlikely (mbcset == NULL))\n    {\n      re_free (sbcset);\n      *err = REG_ESPACE;\n      return NULL;\n    }\n  mbcset->non_match = non_match;\n#endif /* RE_ENABLE_I18N */\n\n  /* We don't care the syntax in this case.  */\n  ret = build_charclass (trans, sbcset,\n#ifdef RE_ENABLE_I18N\n\t\t\t mbcset, &alloc,\n#endif /* RE_ENABLE_I18N */\n\t\t\t class_name, 0);\n\n  if (__glibc_unlikely (ret != REG_NOERROR))\n    {\n      re_free (sbcset);\n#ifdef RE_ENABLE_I18N\n      free_charset (mbcset);\n#endif /* RE_ENABLE_I18N */\n      *err = ret;\n      return NULL;\n    }\n  /* \\w match '_' also.  */\n  for (; *extra; extra++)\n    bitset_set (sbcset, *extra);\n\n  /* If it is non-matching list.  */\n  if (non_match)\n    bitset_not (sbcset);\n\n#ifdef RE_ENABLE_I18N\n  /* Ensure only single byte characters are set.  */\n  if (dfa->mb_cur_max > 1)\n    bitset_mask (sbcset, dfa->sb_char);\n#endif\n\n  /* Build a tree for simple bracket.  */\n  re_token_t br_token = { .type = SIMPLE_BRACKET, .opr.sbcset = sbcset };\n  tree = create_token_tree (dfa, NULL, NULL, &br_token);\n  if (__glibc_unlikely (tree == NULL))\n    goto build_word_op_espace;\n\n#ifdef RE_ENABLE_I18N\n  if (dfa->mb_cur_max > 1)\n    {\n      bin_tree_t *mbc_tree;\n      /* Build a tree for complex bracket.  */\n      br_token.type = COMPLEX_BRACKET;\n      br_token.opr.mbcset = mbcset;\n      dfa->has_mb_node = 1;\n      mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);\n      if (__glibc_unlikely (mbc_tree == NULL))\n\tgoto build_word_op_espace;\n      /* Then join them by ALT node.  */\n      tree = create_tree (dfa, tree, mbc_tree, OP_ALT);\n      if (__glibc_likely (mbc_tree != NULL))\n\treturn tree;\n    }\n  else\n    {\n      free_charset (mbcset);\n      return tree;\n    }\n#else /* not RE_ENABLE_I18N */\n  return tree;\n#endif /* not RE_ENABLE_I18N */\n\n build_word_op_espace:\n  re_free (sbcset);\n#ifdef RE_ENABLE_I18N\n  free_charset (mbcset);\n#endif /* RE_ENABLE_I18N */\n  *err = REG_ESPACE;\n  return NULL;\n}\n\n/* This is intended for the expressions like \"a{1,3}\".\n   Fetch a number from 'input', and return the number.\n   Return -1 if the number field is empty like \"{,1}\".\n   Return RE_DUP_MAX + 1 if the number field is too large.\n   Return -2 if an error occurred.  */\n\nstatic Idx\nfetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax)\n{\n  Idx num = -1;\n  unsigned char c;\n  while (1)\n    {\n      fetch_token (token, input, syntax);\n      c = token->opr.c;\n      if (__glibc_unlikely (token->type == END_OF_RE))\n\treturn -2;\n      if (token->type == OP_CLOSE_DUP_NUM || c == ',')\n\tbreak;\n      num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2)\n\t     ? -2\n\t     : num == -1\n\t     ? c - '0'\n\t     : MIN (RE_DUP_MAX + 1, num * 10 + c - '0'));\n    }\n  return num;\n}\n\f\n#ifdef RE_ENABLE_I18N\nstatic void\nfree_charset (re_charset_t *cset)\n{\n  re_free (cset->mbchars);\n# ifdef _LIBC\n  re_free (cset->coll_syms);\n  re_free (cset->equiv_classes);\n# endif\n  re_free (cset->range_starts);\n  re_free (cset->range_ends);\n  re_free (cset->char_classes);\n  re_free (cset);\n}\n#endif /* RE_ENABLE_I18N */\n\f\n/* Functions for binary tree operation.  */\n\n/* Create a tree node.  */\n\nstatic bin_tree_t *\ncreate_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,\n\t     re_token_type_t type)\n{\n  re_token_t t = { .type = type };\n  return create_token_tree (dfa, left, right, &t);\n}\n\nstatic bin_tree_t *\ncreate_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,\n\t\t   const re_token_t *token)\n{\n  bin_tree_t *tree;\n  if (__glibc_unlikely (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE))\n    {\n      bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1);\n\n      if (storage == NULL)\n\treturn NULL;\n      storage->next = dfa->str_tree_storage;\n      dfa->str_tree_storage = storage;\n      dfa->str_tree_storage_idx = 0;\n    }\n  tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++];\n\n  tree->parent = NULL;\n  tree->left = left;\n  tree->right = right;\n  tree->token = *token;\n  tree->token.duplicated = 0;\n  tree->token.opt_subexp = 0;\n  tree->first = NULL;\n  tree->next = NULL;\n  tree->node_idx = -1;\n\n  if (left != NULL)\n    left->parent = tree;\n  if (right != NULL)\n    right->parent = tree;\n  return tree;\n}\n\n/* Mark the tree SRC as an optional subexpression.\n   To be called from preorder or postorder.  */\n\nstatic reg_errcode_t\nmark_opt_subexp (void *extra, bin_tree_t *node)\n{\n  Idx idx = (uintptr_t) extra;\n  if (node->token.type == SUBEXP && node->token.opr.idx == idx)\n    node->token.opt_subexp = 1;\n\n  return REG_NOERROR;\n}\n\n/* Free the allocated memory inside NODE. */\n\nstatic void\nfree_token (re_token_t *node)\n{\n#ifdef RE_ENABLE_I18N\n  if (node->type == COMPLEX_BRACKET && node->duplicated == 0)\n    free_charset (node->opr.mbcset);\n  else\n#endif /* RE_ENABLE_I18N */\n    if (node->type == SIMPLE_BRACKET && node->duplicated == 0)\n      re_free (node->opr.sbcset);\n}\n\n/* Worker function for tree walking.  Free the allocated memory inside NODE\n   and its children. */\n\nstatic reg_errcode_t\nfree_tree (void *extra, bin_tree_t *node)\n{\n  free_token (&node->token);\n  return REG_NOERROR;\n}\n\n\n/* Duplicate the node SRC, and return new node.  This is a preorder\n   visit similar to the one implemented by the generic visitor, but\n   we need more infrastructure to maintain two parallel trees --- so,\n   it's easier to duplicate.  */\n\nstatic bin_tree_t *\nduplicate_tree (const bin_tree_t *root, re_dfa_t *dfa)\n{\n  const bin_tree_t *node;\n  bin_tree_t *dup_root;\n  bin_tree_t **p_new = &dup_root, *dup_node = root->parent;\n\n  for (node = root; ; )\n    {\n      /* Create a new tree and link it back to the current parent.  */\n      *p_new = create_token_tree (dfa, NULL, NULL, &node->token);\n      if (*p_new == NULL)\n\treturn NULL;\n      (*p_new)->parent = dup_node;\n      (*p_new)->token.duplicated = 1;\n      dup_node = *p_new;\n\n      /* Go to the left node, or up and to the right.  */\n      if (node->left)\n\t{\n\t  node = node->left;\n\t  p_new = &dup_node->left;\n\t}\n      else\n\t{\n\t  const bin_tree_t *prev = NULL;\n\t  while (node->right == prev || node->right == NULL)\n\t    {\n\t      prev = node;\n\t      node = node->parent;\n\t      dup_node = dup_node->parent;\n\t      if (!node)\n\t\treturn dup_root;\n\t    }\n\t  node = node->right;\n\t  p_new = &dup_node->right;\n\t}\n    }\n}\n"
  },
  {
    "path": "gnulib/regex.c",
    "content": "/* Extended regular expression matching and search library.\n   Copyright (C) 2002-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#define __STDC_WANT_IEC_60559_BFP_EXT__\n\n#ifndef _LIBC\n# include <libc-config.h>\n\n# if __GNUC_PREREQ (4, 6)\n#  pragma GCC diagnostic ignored \"-Wsuggest-attribute=pure\"\n# endif\n# if __GNUC_PREREQ (4, 3)\n#  pragma GCC diagnostic ignored \"-Wold-style-definition\"\n#  pragma GCC diagnostic ignored \"-Wtype-limits\"\n# endif\n#endif\n\n/* Make sure no one compiles this code with a C++ compiler.  */\n#if defined __cplusplus && defined _LIBC\n# error \"This is C code, use a C compiler\"\n#endif\n\n#ifdef _LIBC\n/* We have to keep the namespace clean.  */\n# define regfree(preg) __regfree (preg)\n# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)\n# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)\n# define regerror(errcode, preg, errbuf, errbuf_size) \\\n\t__regerror(errcode, preg, errbuf, errbuf_size)\n# define re_set_registers(bu, re, nu, st, en) \\\n\t__re_set_registers (bu, re, nu, st, en)\n# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \\\n\t__re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)\n# define re_match(bufp, string, size, pos, regs) \\\n\t__re_match (bufp, string, size, pos, regs)\n# define re_search(bufp, string, size, startpos, range, regs) \\\n\t__re_search (bufp, string, size, startpos, range, regs)\n# define re_compile_pattern(pattern, length, bufp) \\\n\t__re_compile_pattern (pattern, length, bufp)\n# define re_set_syntax(syntax) __re_set_syntax (syntax)\n# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \\\n\t__re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)\n# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)\n\n# include \"../locale/localeinfo.h\"\n#endif\n\n/* On some systems, limits.h sets RE_DUP_MAX to a lower value than\n   GNU regex allows.  Include it before <regex.h>, which correctly\n   #undefs RE_DUP_MAX and sets it to the right value.  */\n#include <limits.h>\n\n#include <regex.h>\n#include \"regex_internal.h\"\n\n#include \"regex_internal.c\"\n#include \"regcomp.c\"\n#include \"regexec.c\"\n\n/* Binary backward compatibility.  */\n#if _LIBC\n# include <shlib-compat.h>\n# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)\nlink_warning (re_max_failures, \"the 're_max_failures' variable is obsolete and will go away.\")\nint re_max_failures = 2000;\n# endif\n#endif\n"
  },
  {
    "path": "gnulib/regex.h",
    "content": "/* Definitions for data structures and routines for the regular\n   expression library.\n   Copyright (C) 1985, 1989-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifndef _REGEX_H\n#define _REGEX_H 1\n\n#include <sys/types.h>\n\n/* Allow the use in C++ code.  */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Define __USE_GNU to declare GNU extensions that violate the\n   POSIX name space rules.  */\n#ifdef _GNU_SOURCE\n# define __USE_GNU 1\n#endif\n\n#ifdef _REGEX_LARGE_OFFSETS\n\n/* Use types and values that are wide enough to represent signed and\n   unsigned byte offsets in memory.  This currently works only when\n   the regex code is used outside of the GNU C library; it is not yet\n   supported within glibc itself, and glibc users should not define\n   _REGEX_LARGE_OFFSETS.  */\n\n/* The type of object sizes.  */\ntypedef size_t __re_size_t;\n\n/* The type of object sizes, in places where the traditional code\n   uses unsigned long int.  */\ntypedef size_t __re_long_size_t;\n\n#else\n\n/* The traditional GNU regex implementation mishandles strings longer\n   than INT_MAX.  */\ntypedef unsigned int __re_size_t;\ntypedef unsigned long int __re_long_size_t;\n\n#endif\n\n/* The following two types have to be signed and unsigned integer type\n   wide enough to hold a value of a pointer.  For most ANSI compilers\n   ptrdiff_t and size_t should be likely OK.  Still size of these two\n   types is 2 for Microsoft C.  Ugh... */\ntypedef long int s_reg_t;\ntypedef unsigned long int active_reg_t;\n\n/* The following bits are used to determine the regexp syntax we\n   recognize.  The set/not-set meanings are chosen so that Emacs syntax\n   remains the value 0.  The bits are given in alphabetical order, and\n   the definitions shifted by one from the previous bit; thus, when we\n   add or remove a bit, only one other definition need change.  */\ntypedef unsigned long int reg_syntax_t;\n\n#ifdef __USE_GNU\n/* If this bit is not set, then \\ inside a bracket expression is literal.\n   If set, then such a \\ quotes the following character.  */\n# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)\n\n/* If this bit is not set, then + and ? are operators, and \\+ and \\? are\n     literals.\n   If set, then \\+ and \\? are operators and + and ? are literals.  */\n# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)\n\n/* If this bit is set, then character classes are supported.  They are:\n     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],\n     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].\n   If not set, then character classes are not supported.  */\n# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)\n\n/* If this bit is set, then ^ and $ are always anchors (outside bracket\n     expressions, of course).\n   If this bit is not set, then it depends:\n\t^  is an anchor if it is at the beginning of a regular\n\t   expression or after an open-group or an alternation operator;\n\t$  is an anchor if it is at the end of a regular expression, or\n\t   before a close-group or an alternation operator.\n\n   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because\n   POSIX draft 11.2 says that * etc. in leading positions is undefined.\n   We already implemented a previous draft which made those constructs\n   invalid, though, so we haven't changed the code back.  */\n# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)\n\n/* If this bit is set, then special characters are always special\n     regardless of where they are in the pattern.\n   If this bit is not set, then special characters are special only in\n     some contexts; otherwise they are ordinary.  Specifically,\n     * + ? and intervals are only special when not after the beginning,\n     open-group, or alternation operator.  */\n# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)\n\n/* If this bit is set, then *, +, ?, and { cannot be first in an re or\n     immediately after an alternation or begin-group operator.  */\n# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)\n\n/* If this bit is set, then . matches newline.\n   If not set, then it doesn't.  */\n# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)\n\n/* If this bit is set, then . doesn't match NUL.\n   If not set, then it does.  */\n# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)\n\n/* If this bit is set, nonmatching lists [^...] do not match newline.\n   If not set, they do.  */\n# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)\n\n/* If this bit is set, either \\{...\\} or {...} defines an\n     interval, depending on RE_NO_BK_BRACES.\n   If not set, \\{, \\}, {, and } are literals.  */\n# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)\n\n/* If this bit is set, +, ? and | aren't recognized as operators.\n   If not set, they are.  */\n# define RE_LIMITED_OPS (RE_INTERVALS << 1)\n\n/* If this bit is set, newline is an alternation operator.\n   If not set, newline is literal.  */\n# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)\n\n/* If this bit is set, then '{...}' defines an interval, and \\{ and \\}\n     are literals.\n  If not set, then '\\{...\\}' defines an interval.  */\n# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)\n\n/* If this bit is set, (...) defines a group, and \\( and \\) are literals.\n   If not set, \\(...\\) defines a group, and ( and ) are literals.  */\n# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)\n\n/* If this bit is set, then \\<digit> matches <digit>.\n   If not set, then \\<digit> is a back-reference.  */\n# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)\n\n/* If this bit is set, then | is an alternation operator, and \\| is literal.\n   If not set, then \\| is an alternation operator, and | is literal.  */\n# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)\n\n/* If this bit is set, then an ending range point collating higher\n     than the starting range point, as in [z-a], is invalid.\n   If not set, then when ending range point collates higher than the\n     starting range point, the range is ignored.  */\n# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)\n\n/* If this bit is set, then an unmatched ) is ordinary.\n   If not set, then an unmatched ) is invalid.  */\n# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)\n\n/* If this bit is set, succeed as soon as we match the whole pattern,\n   without further backtracking.  */\n# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)\n\n/* If this bit is set, do not process the GNU regex operators.\n   If not set, then the GNU regex operators are recognized. */\n# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)\n\n/* If this bit is set, turn on internal regex debugging.\n   If not set, and debugging was on, turn it off.\n   This only works if regex.c is compiled -DDEBUG.\n   We define this bit always, so that all that's needed to turn on\n   debugging is to recompile regex.c; the calling code can always have\n   this bit set, and it won't affect anything in the normal case. */\n# define RE_DEBUG (RE_NO_GNU_OPS << 1)\n\n/* If this bit is set, a syntactically invalid interval is treated as\n   a string of ordinary characters.  For example, the ERE 'a{1' is\n   treated as 'a\\{1'.  */\n# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)\n\n/* If this bit is set, then ignore case when matching.\n   If not set, then case is significant.  */\n# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)\n\n/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only\n   for ^, because it is difficult to scan the regex backwards to find\n   whether ^ should be special.  */\n# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)\n\n/* If this bit is set, then \\{ cannot be first in a regex or\n   immediately after an alternation, open-group or \\} operator.  */\n# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)\n\n/* If this bit is set, then no_sub will be set to 1 during\n   re_compile_pattern.  */\n# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)\n#endif\n\n/* This global variable defines the particular regexp syntax to use (for\n   some interfaces).  When a regexp is compiled, the syntax used is\n   stored in the pattern buffer, so changing this does not affect\n   already-compiled regexps.  */\nextern reg_syntax_t re_syntax_options;\n\f\n#ifdef __USE_GNU\n/* Define combinations of the above bits for the standard possibilities.\n   (The [[[ comments delimit what gets put into the Texinfo file, so\n   don't delete them!)  */\n/* [[[begin syntaxes]]] */\n# define RE_SYNTAX_EMACS 0\n\n# define RE_SYNTAX_AWK\t\t\t\t\t\t\t\\\n  (RE_BACKSLASH_ESCAPE_IN_LISTS   | RE_DOT_NOT_NULL\t\t\t\\\n   | RE_NO_BK_PARENS              | RE_NO_BK_REFS\t\t\t\\\n   | RE_NO_BK_VBAR                | RE_NO_EMPTY_RANGES\t\t\t\\\n   | RE_DOT_NEWLINE\t\t  | RE_CONTEXT_INDEP_ANCHORS\t\t\\\n   | RE_CHAR_CLASSES\t\t\t\t\t\t\t\\\n   | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)\n\n# define RE_SYNTAX_GNU_AWK\t\t\t\t\t\t\\\n  ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS\t\t\\\n    | RE_INVALID_INTERVAL_ORD)\t\t\t\t\t\t\\\n   & ~(RE_DOT_NOT_NULL | RE_CONTEXT_INDEP_OPS\t\t\t\t\\\n      | RE_CONTEXT_INVALID_OPS ))\n\n# define RE_SYNTAX_POSIX_AWK\t\t\t\t\t\t\\\n  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS\t\t\\\n   | RE_INTERVALS\t    | RE_NO_GNU_OPS\t\t\t\t\\\n   | RE_INVALID_INTERVAL_ORD)\n\n# define RE_SYNTAX_GREP\t\t\t\t\t\t\t\\\n  ((RE_SYNTAX_POSIX_BASIC | RE_NEWLINE_ALT)\t\t\t\t\\\n   & ~(RE_CONTEXT_INVALID_DUP | RE_DOT_NOT_NULL))\n\n# define RE_SYNTAX_EGREP\t\t\t\t\t\t\\\n  ((RE_SYNTAX_POSIX_EXTENDED | RE_INVALID_INTERVAL_ORD | RE_NEWLINE_ALT) \\\n   & ~(RE_CONTEXT_INVALID_OPS | RE_DOT_NOT_NULL))\n\n/* POSIX grep -E behavior is no longer incompatible with GNU.  */\n# define RE_SYNTAX_POSIX_EGREP\t\t\t\t\t\t\\\n  RE_SYNTAX_EGREP\n\n/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */\n# define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC\n\n# define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC\n\n/* Syntax bits common to both basic and extended POSIX regex syntax.  */\n# define _RE_SYNTAX_POSIX_COMMON\t\t\t\t\t\\\n  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL\t\t\\\n   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)\n\n# define RE_SYNTAX_POSIX_BASIC\t\t\t\t\t\t\\\n  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)\n\n/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes\n   RE_LIMITED_OPS, i.e., \\? \\+ \\| are not recognized.  Actually, this\n   isn't minimal, since other operators, such as \\`, aren't disabled.  */\n# define RE_SYNTAX_POSIX_MINIMAL_BASIC\t\t\t\t\t\\\n  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)\n\n# define RE_SYNTAX_POSIX_EXTENDED\t\t\t\t\t\\\n  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS\t\t\t\\\n   | RE_CONTEXT_INDEP_OPS   | RE_NO_BK_BRACES\t\t\t\t\\\n   | RE_NO_BK_PARENS        | RE_NO_BK_VBAR\t\t\t\t\\\n   | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)\n\n/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is\n   removed and RE_NO_BK_REFS is added.  */\n# define RE_SYNTAX_POSIX_MINIMAL_EXTENDED\t\t\t\t\\\n  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS\t\t\t\\\n   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES\t\t\t\t\\\n   | RE_NO_BK_PARENS        | RE_NO_BK_REFS\t\t\t\t\\\n   | RE_NO_BK_VBAR\t    | RE_UNMATCHED_RIGHT_PAREN_ORD)\n/* [[[end syntaxes]]] */\n\n/* Maximum number of duplicates an interval can allow.  POSIX-conforming\n   systems might define this in <limits.h>, but we want our\n   value, so remove any previous define.  */\n# ifdef _REGEX_INCLUDE_LIMITS_H\n#  include <limits.h>\n# endif\n# ifdef RE_DUP_MAX\n#  undef RE_DUP_MAX\n# endif\n\n/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored\n   the counter as a 2-byte signed integer.  This is no longer true, so\n   RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to\n   ((SIZE_MAX - 9) / 10) if _REGEX_LARGE_OFFSETS is defined.\n   However, there would be a huge performance problem if someone\n   actually used a pattern like a\\{214748363\\}, so RE_DUP_MAX retains\n   its historical value.  */\n# define RE_DUP_MAX (0x7fff)\n#endif\n\n\n/* POSIX 'cflags' bits (i.e., information for 'regcomp').  */\n\n/* If this bit is set, then use extended regular expression syntax.\n   If not set, then use basic regular expression syntax.  */\n#define REG_EXTENDED 1\n\n/* If this bit is set, then ignore case when matching.\n   If not set, then case is significant.  */\n#define REG_ICASE (1 << 1)\n\n/* If this bit is set, then anchors do not match at newline\n     characters in the string.\n   If not set, then anchors do match at newlines.  */\n#define REG_NEWLINE (1 << 2)\n\n/* If this bit is set, then report only success or fail in regexec.\n   If not set, then returns differ between not matching and errors.  */\n#define REG_NOSUB (1 << 3)\n\n\n/* POSIX 'eflags' bits (i.e., information for regexec).  */\n\n/* If this bit is set, then the beginning-of-line operator doesn't match\n     the beginning of the string (presumably because it's not the\n     beginning of a line).\n   If not set, then the beginning-of-line operator does match the\n     beginning of the string.  */\n#define REG_NOTBOL 1\n\n/* Like REG_NOTBOL, except for the end-of-line.  */\n#define REG_NOTEOL (1 << 1)\n\n/* Use PMATCH[0] to delimit the start and end of the search in the\n   buffer.  */\n#define REG_STARTEND (1 << 2)\n\n\n/* If any error codes are removed, changed, or added, update the\n   '__re_error_msgid' table in regcomp.c.  */\n\ntypedef enum\n{\n  _REG_ENOSYS = -1,\t/* This will never happen for this implementation.  */\n  _REG_NOERROR = 0,\t/* Success.  */\n  _REG_NOMATCH,\t\t/* Didn't find a match (for regexec).  */\n\n  /* POSIX regcomp return error codes.  (In the order listed in the\n     standard.)  */\n  _REG_BADPAT,\t\t/* Invalid pattern.  */\n  _REG_ECOLLATE,\t/* Invalid collating element.  */\n  _REG_ECTYPE,\t\t/* Invalid character class name.  */\n  _REG_EESCAPE,\t\t/* Trailing backslash.  */\n  _REG_ESUBREG,\t\t/* Invalid back reference.  */\n  _REG_EBRACK,\t\t/* Unmatched left bracket.  */\n  _REG_EPAREN,\t\t/* Parenthesis imbalance.  */\n  _REG_EBRACE,\t\t/* Unmatched \\{.  */\n  _REG_BADBR,\t\t/* Invalid contents of \\{\\}.  */\n  _REG_ERANGE,\t\t/* Invalid range end.  */\n  _REG_ESPACE,\t\t/* Ran out of memory.  */\n  _REG_BADRPT,\t\t/* No preceding re for repetition op.  */\n\n  /* Error codes we've added.  */\n  _REG_EEND,\t\t/* Premature end.  */\n  _REG_ESIZE,\t\t/* Too large (e.g., repeat count too large).  */\n  _REG_ERPAREN\t\t/* Unmatched ) or \\); not returned from regcomp.  */\n} reg_errcode_t;\n\n#if defined _XOPEN_SOURCE || defined __USE_XOPEN2K\n# define REG_ENOSYS\t_REG_ENOSYS\n#endif\n#define REG_NOERROR\t_REG_NOERROR\n#define REG_NOMATCH\t_REG_NOMATCH\n#define REG_BADPAT\t_REG_BADPAT\n#define REG_ECOLLATE\t_REG_ECOLLATE\n#define REG_ECTYPE\t_REG_ECTYPE\n#define REG_EESCAPE\t_REG_EESCAPE\n#define REG_ESUBREG\t_REG_ESUBREG\n#define REG_EBRACK\t_REG_EBRACK\n#define REG_EPAREN\t_REG_EPAREN\n#define REG_EBRACE\t_REG_EBRACE\n#define REG_BADBR\t_REG_BADBR\n#define REG_ERANGE\t_REG_ERANGE\n#define REG_ESPACE\t_REG_ESPACE\n#define REG_BADRPT\t_REG_BADRPT\n#define REG_EEND\t_REG_EEND\n#define REG_ESIZE\t_REG_ESIZE\n#define REG_ERPAREN\t_REG_ERPAREN\n\f\n/* This data structure represents a compiled pattern.  Before calling\n   the pattern compiler, the fields 'buffer', 'allocated', 'fastmap',\n   and 'translate' can be set.  After the pattern has been compiled,\n   the fields 're_nsub', 'not_bol' and 'not_eol' are available.  All\n   other fields are private to the regex routines.  */\n\n#ifndef RE_TRANSLATE_TYPE\n# define __RE_TRANSLATE_TYPE unsigned char *\n# ifdef __USE_GNU\n#  define RE_TRANSLATE_TYPE __RE_TRANSLATE_TYPE\n# endif\n#endif\n\n#ifdef __USE_GNU\n# define __REPB_PREFIX(name) name\n#else\n# define __REPB_PREFIX(name) __##name\n#endif\n\nstruct re_pattern_buffer\n{\n  /* Space that holds the compiled pattern.  The type\n     'struct re_dfa_t' is private and is not declared here.  */\n  struct re_dfa_t *__REPB_PREFIX(buffer);\n\n  /* Number of bytes to which 'buffer' points.  */\n  __re_long_size_t __REPB_PREFIX(allocated);\n\n  /* Number of bytes actually used in 'buffer'.  */\n  __re_long_size_t __REPB_PREFIX(used);\n\n  /* Syntax setting with which the pattern was compiled.  */\n  reg_syntax_t __REPB_PREFIX(syntax);\n\n  /* Pointer to a fastmap, if any, otherwise zero.  re_search uses the\n     fastmap, if there is one, to skip over impossible starting points\n     for matches.  */\n  char *__REPB_PREFIX(fastmap);\n\n  /* Either a translate table to apply to all characters before\n     comparing them, or zero for no translation.  The translation is\n     applied to a pattern when it is compiled and to a string when it\n     is matched.  */\n  __RE_TRANSLATE_TYPE __REPB_PREFIX(translate);\n\n  /* Number of subexpressions found by the compiler.  */\n  size_t re_nsub;\n\n  /* Zero if this pattern cannot match the empty string, one else.\n     Well, in truth it's used only in 're_search_2', to see whether or\n     not we should use the fastmap, so we don't set this absolutely\n     perfectly; see 're_compile_fastmap' (the \"duplicate\" case).  */\n  unsigned __REPB_PREFIX(can_be_null) : 1;\n\n  /* If REGS_UNALLOCATED, allocate space in the 'regs' structure\n     for 'max (RE_NREGS, re_nsub + 1)' groups.\n     If REGS_REALLOCATE, reallocate space if necessary.\n     If REGS_FIXED, use what's there.  */\n#ifdef __USE_GNU\n# define REGS_UNALLOCATED 0\n# define REGS_REALLOCATE 1\n# define REGS_FIXED 2\n#endif\n  unsigned __REPB_PREFIX(regs_allocated) : 2;\n\n  /* Set to zero when 're_compile_pattern' compiles a pattern; set to\n     one by 're_compile_fastmap' if it updates the fastmap.  */\n  unsigned __REPB_PREFIX(fastmap_accurate) : 1;\n\n  /* If set, 're_match_2' does not return information about\n     subexpressions.  */\n  unsigned __REPB_PREFIX(no_sub) : 1;\n\n  /* If set, a beginning-of-line anchor doesn't match at the beginning\n     of the string.  */\n  unsigned __REPB_PREFIX(not_bol) : 1;\n\n  /* Similarly for an end-of-line anchor.  */\n  unsigned __REPB_PREFIX(not_eol) : 1;\n\n  /* If true, an anchor at a newline matches.  */\n  unsigned __REPB_PREFIX(newline_anchor) : 1;\n};\n\ntypedef struct re_pattern_buffer regex_t;\n\f\n/* Type for byte offsets within the string.  POSIX mandates this.  */\n#ifdef _REGEX_LARGE_OFFSETS\n/* POSIX 1003.1-2008 requires that regoff_t be at least as wide as\n   ptrdiff_t and ssize_t.  We don't know of any hosts where ptrdiff_t\n   is wider than ssize_t, so ssize_t is safe.  ptrdiff_t is not\n   visible here, so use ssize_t.  */\ntypedef ssize_t regoff_t;\n#else\n/* The traditional GNU regex implementation mishandles strings longer\n   than INT_MAX.  */\ntypedef int regoff_t;\n#endif\n\n\n#ifdef __USE_GNU\n/* This is the structure we store register match data in.  See\n   regex.texinfo for a full description of what registers match.  */\nstruct re_registers\n{\n  __re_size_t num_regs;\n  regoff_t *start;\n  regoff_t *end;\n};\n\n\n/* If 'regs_allocated' is REGS_UNALLOCATED in the pattern buffer,\n   're_match_2' returns information about at least this many registers\n   the first time a 'regs' structure is passed.  */\n# ifndef RE_NREGS\n#  define RE_NREGS 30\n# endif\n#endif\n\n\n/* POSIX specification for registers.  Aside from the different names than\n   're_registers', POSIX uses an array of structures, instead of a\n   structure of arrays.  */\ntypedef struct\n{\n  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */\n  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */\n} regmatch_t;\n\f\n/* Declarations for routines.  */\n\n#ifdef __USE_GNU\n/* Sets the current default syntax to SYNTAX, and return the old syntax.\n   You can also simply assign to the 're_syntax_options' variable.  */\nextern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);\n\n/* Compile the regular expression PATTERN, with length LENGTH\n   and syntax given by the global 're_syntax_options', into the buffer\n   BUFFER.  Return NULL if successful, and an error string if not.\n\n   To free the allocated storage, you must call 'regfree' on BUFFER.\n   Note that the translate table must either have been initialized by\n   'regcomp', with a malloc'ed value, or set to NULL before calling\n   'regfree'.  */\nextern const char *re_compile_pattern (const char *__pattern, size_t __length,\n\t\t\t\t       struct re_pattern_buffer *__buffer);\n\n\n/* Compile a fastmap for the compiled pattern in BUFFER; used to\n   accelerate searches.  Return 0 if successful and -2 if was an\n   internal error.  */\nextern int re_compile_fastmap (struct re_pattern_buffer *__buffer);\n\n\n/* Search in the string STRING (with length LENGTH) for the pattern\n   compiled into BUFFER.  Start searching at position START, for RANGE\n   characters.  Return the starting position of the match, -1 for no\n   match, or -2 for an internal error.  Also return register\n   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */\nextern regoff_t re_search (struct re_pattern_buffer *__buffer,\n\t\t\t   const char *__String, regoff_t __length,\n\t\t\t   regoff_t __start, regoff_t __range,\n\t\t\t   struct re_registers *__regs);\n\n\n/* Like 're_search', but search in the concatenation of STRING1 and\n   STRING2.  Also, stop searching at index START + STOP.  */\nextern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,\n\t\t\t     const char *__string1, regoff_t __length1,\n\t\t\t     const char *__string2, regoff_t __length2,\n\t\t\t     regoff_t __start, regoff_t __range,\n\t\t\t     struct re_registers *__regs,\n\t\t\t     regoff_t __stop);\n\n\n/* Like 're_search', but return how many characters in STRING the regexp\n   in BUFFER matched, starting at position START.  */\nextern regoff_t re_match (struct re_pattern_buffer *__buffer,\n\t\t\t  const char *__String, regoff_t __length,\n\t\t\t  regoff_t __start, struct re_registers *__regs);\n\n\n/* Relates to 're_match' as 're_search_2' relates to 're_search'.  */\nextern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,\n\t\t\t    const char *__string1, regoff_t __length1,\n\t\t\t    const char *__string2, regoff_t __length2,\n\t\t\t    regoff_t __start, struct re_registers *__regs,\n\t\t\t    regoff_t __stop);\n\n\n/* Set REGS to hold NUM_REGS registers, storing them in STARTS and\n   ENDS.  Subsequent matches using BUFFER and REGS will use this memory\n   for recording register information.  STARTS and ENDS must be\n   allocated with malloc, and must each be at least 'NUM_REGS * sizeof\n   (regoff_t)' bytes long.\n\n   If NUM_REGS == 0, then subsequent matches should allocate their own\n   register data.\n\n   Unless this function is called, the first search or match using\n   BUFFER will allocate its own register data, without\n   freeing the old data.  */\nextern void re_set_registers (struct re_pattern_buffer *__buffer,\n\t\t\t      struct re_registers *__regs,\n\t\t\t      __re_size_t __num_regs,\n\t\t\t      regoff_t *__starts, regoff_t *__ends);\n#endif\t/* Use GNU */\n\n#if defined _REGEX_RE_COMP || (defined _LIBC && defined __USE_MISC)\n/* 4.2 bsd compatibility.  */\nextern char *re_comp (const char *);\nextern int re_exec (const char *);\n#endif\n\n/* For plain 'restrict', use glibc's __restrict if defined.\n   Otherwise, GCC 2.95 and later have \"__restrict\"; C99 compilers have\n   \"restrict\", and \"configure\" may have defined \"restrict\".\n   Other compilers use __restrict, __restrict__, and _Restrict, and\n   'configure' might #define 'restrict' to those words, so pick a\n   different name.  */\n#ifndef _Restrict_\n# if defined __restrict \\\n     || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \\\n     || __clang_major__ >= 3\n#  define _Restrict_ __restrict\n# elif 199901L <= __STDC_VERSION__ || defined restrict\n#  define _Restrict_ restrict\n# else\n#  define _Restrict_\n# endif\n#endif\n/* For the ISO C99 syntax\n     array_name[restrict]\n   use glibc's __restrict_arr if available.\n   Otherwise, GCC 3.1 and clang support this syntax (but not in C++ mode).\n   Other ISO C99 compilers support it as well.  */\n#ifndef _Restrict_arr_\n# ifdef __restrict_arr\n#  define _Restrict_arr_ __restrict_arr\n# elif ((199901L <= __STDC_VERSION__ \\\n         || 3 < __GNUC__ + (1 <= __GNUC_MINOR__) \\\n         || __clang_major__ >= 3) \\\n        && !defined __cplusplus)\n#  define _Restrict_arr_ _Restrict_\n# else\n#  define _Restrict_arr_\n# endif\n#endif\n\n/* POSIX compatibility.  */\nextern int regcomp (regex_t *_Restrict_ __preg,\n\t\t    const char *_Restrict_ __pattern,\n\t\t    int __cflags);\n\nextern int regexec (const regex_t *_Restrict_ __preg,\n\t\t    const char *_Restrict_ __String, size_t __nmatch,\n\t\t    regmatch_t __pmatch[_Restrict_arr_],\n\t\t    int __eflags);\n\nextern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,\n\t\t\tchar *_Restrict_ __errbuf, size_t __errbuf_size);\n\nextern void regfree (regex_t *__preg);\n\n\n#ifdef __cplusplus\n}\n#endif\t/* C++ */\n\n#endif /* regex.h */\n"
  },
  {
    "path": "gnulib/regex_internal.c",
    "content": "/* Extended regular expression matching and search library.\n   Copyright (C) 2002-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\nstatic void re_string_construct_common (const char *str, Idx len,\n\t\t\t\t\tre_string_t *pstr,\n\t\t\t\t\tRE_TRANSLATE_TYPE trans, bool icase,\n\t\t\t\t\tconst re_dfa_t *dfa);\nstatic re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,\n\t\t\t\t\t  const re_node_set *nodes,\n\t\t\t\t\t  re_hashval_t hash);\nstatic re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,\n\t\t\t\t\t  const re_node_set *nodes,\n\t\t\t\t\t  unsigned int context,\n\t\t\t\t\t  re_hashval_t hash);\nstatic reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,\n\t\t\t\t\t\tIdx new_buf_len);\n#ifdef RE_ENABLE_I18N\nstatic void build_wcs_buffer (re_string_t *pstr);\nstatic reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr);\n#endif /* RE_ENABLE_I18N */\nstatic void build_upper_buffer (re_string_t *pstr);\nstatic void re_string_translate_buffer (re_string_t *pstr);\nstatic unsigned int re_string_context_at (const re_string_t *input, Idx idx,\n\t\t\t\t\t  int eflags) __attribute__ ((pure));\n\f\n/* Functions for string operation.  */\n\n/* This function allocate the buffers.  It is necessary to call\n   re_string_reconstruct before using the object.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,\n\t\t    RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)\n{\n  reg_errcode_t ret;\n  Idx init_buf_len;\n\n  /* Ensure at least one character fits into the buffers.  */\n  if (init_len < dfa->mb_cur_max)\n    init_len = dfa->mb_cur_max;\n  init_buf_len = (len + 1 < init_len) ? len + 1: init_len;\n  re_string_construct_common (str, len, pstr, trans, icase, dfa);\n\n  ret = re_string_realloc_buffers (pstr, init_buf_len);\n  if (__glibc_unlikely (ret != REG_NOERROR))\n    return ret;\n\n  pstr->word_char = dfa->word_char;\n  pstr->word_ops_used = dfa->word_ops_used;\n  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;\n  pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;\n  pstr->valid_raw_len = pstr->valid_len;\n  return REG_NOERROR;\n}\n\n/* This function allocate the buffers, and initialize them.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_string_construct (re_string_t *pstr, const char *str, Idx len,\n\t\t     RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)\n{\n  reg_errcode_t ret;\n  memset (pstr, '\\0', sizeof (re_string_t));\n  re_string_construct_common (str, len, pstr, trans, icase, dfa);\n\n  if (len > 0)\n    {\n      ret = re_string_realloc_buffers (pstr, len + 1);\n      if (__glibc_unlikely (ret != REG_NOERROR))\n\treturn ret;\n    }\n  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;\n\n  if (icase)\n    {\n#ifdef RE_ENABLE_I18N\n      if (dfa->mb_cur_max > 1)\n\t{\n\t  while (1)\n\t    {\n\t      ret = build_wcs_upper_buffer (pstr);\n\t      if (__glibc_unlikely (ret != REG_NOERROR))\n\t\treturn ret;\n\t      if (pstr->valid_raw_len >= len)\n\t\tbreak;\n\t      if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)\n\t\tbreak;\n\t      ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);\n\t      if (__glibc_unlikely (ret != REG_NOERROR))\n\t\treturn ret;\n\t    }\n\t}\n      else\n#endif /* RE_ENABLE_I18N  */\n\tbuild_upper_buffer (pstr);\n    }\n  else\n    {\n#ifdef RE_ENABLE_I18N\n      if (dfa->mb_cur_max > 1)\n\tbuild_wcs_buffer (pstr);\n      else\n#endif /* RE_ENABLE_I18N  */\n\t{\n\t  if (trans != NULL)\n\t    re_string_translate_buffer (pstr);\n\t  else\n\t    {\n\t      pstr->valid_len = pstr->bufs_len;\n\t      pstr->valid_raw_len = pstr->bufs_len;\n\t    }\n\t}\n    }\n\n  return REG_NOERROR;\n}\n\n/* Helper functions for re_string_allocate, and re_string_construct.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)\n{\n#ifdef RE_ENABLE_I18N\n  if (pstr->mb_cur_max > 1)\n    {\n      wint_t *new_wcs;\n\n      /* Avoid overflow in realloc.  */\n      const size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx));\n      if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size)\n\t\t\t    < new_buf_len))\n\treturn REG_ESPACE;\n\n      new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);\n      if (__glibc_unlikely (new_wcs == NULL))\n\treturn REG_ESPACE;\n      pstr->wcs = new_wcs;\n      if (pstr->offsets != NULL)\n\t{\n\t  Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len);\n\t  if (__glibc_unlikely (new_offsets == NULL))\n\t    return REG_ESPACE;\n\t  pstr->offsets = new_offsets;\n\t}\n    }\n#endif /* RE_ENABLE_I18N  */\n  if (pstr->mbs_allocated)\n    {\n      unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,\n\t\t\t\t\t   new_buf_len);\n      if (__glibc_unlikely (new_mbs == NULL))\n\treturn REG_ESPACE;\n      pstr->mbs = new_mbs;\n    }\n  pstr->bufs_len = new_buf_len;\n  return REG_NOERROR;\n}\n\n\nstatic void\nre_string_construct_common (const char *str, Idx len, re_string_t *pstr,\n\t\t\t    RE_TRANSLATE_TYPE trans, bool icase,\n\t\t\t    const re_dfa_t *dfa)\n{\n  pstr->raw_mbs = (const unsigned char *) str;\n  pstr->len = len;\n  pstr->raw_len = len;\n  pstr->trans = trans;\n  pstr->icase = icase;\n  pstr->mbs_allocated = (trans != NULL || icase);\n  pstr->mb_cur_max = dfa->mb_cur_max;\n  pstr->is_utf8 = dfa->is_utf8;\n  pstr->map_notascii = dfa->map_notascii;\n  pstr->stop = pstr->len;\n  pstr->raw_stop = pstr->stop;\n}\n\n#ifdef RE_ENABLE_I18N\n\n/* Build wide character buffer PSTR->WCS.\n   If the byte sequence of the string are:\n     <mb1>(0), <mb1>(1), <mb2>(0), <mb2>(1), <sb3>\n   Then wide character buffer will be:\n     <wc1>   , WEOF    , <wc2>   , WEOF    , <wc3>\n   We use WEOF for padding, they indicate that the position isn't\n   a first byte of a multibyte character.\n\n   Note that this function assumes PSTR->VALID_LEN elements are already\n   built and starts from PSTR->VALID_LEN.  */\n\nstatic void\nbuild_wcs_buffer (re_string_t *pstr)\n{\n#ifdef _LIBC\n  unsigned char buf[MB_LEN_MAX];\n  DEBUG_ASSERT (MB_LEN_MAX >= pstr->mb_cur_max);\n#else\n  unsigned char buf[64];\n#endif\n  mbstate_t prev_st;\n  Idx byte_idx, end_idx, remain_len;\n  size_t mbclen;\n\n  /* Build the buffers from pstr->valid_len to either pstr->len or\n     pstr->bufs_len.  */\n  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;\n  for (byte_idx = pstr->valid_len; byte_idx < end_idx;)\n    {\n      wchar_t wc;\n      const char *p;\n\n      remain_len = end_idx - byte_idx;\n      prev_st = pstr->cur_state;\n      /* Apply the translation if we need.  */\n      if (__glibc_unlikely (pstr->trans != NULL))\n\t{\n\t  int i, ch;\n\n\t  for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)\n\t    {\n\t      ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];\n\t      buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];\n\t    }\n\t  p = (const char *) buf;\n\t}\n      else\n\tp = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;\n      mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);\n      if (__glibc_unlikely (mbclen == (size_t) -1 || mbclen == 0\n\t\t\t    || (mbclen == (size_t) -2\n\t\t\t\t&& pstr->bufs_len >= pstr->len)))\n\t{\n\t  /* We treat these cases as a singlebyte character.  */\n\t  mbclen = 1;\n\t  wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];\n\t  if (__glibc_unlikely (pstr->trans != NULL))\n\t    wc = pstr->trans[wc];\n\t  pstr->cur_state = prev_st;\n\t}\n      else if (__glibc_unlikely (mbclen == (size_t) -2))\n\t{\n\t  /* The buffer doesn't have enough space, finish to build.  */\n\t  pstr->cur_state = prev_st;\n\t  break;\n\t}\n\n      /* Write wide character and padding.  */\n      pstr->wcs[byte_idx++] = wc;\n      /* Write paddings.  */\n      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)\n\tpstr->wcs[byte_idx++] = WEOF;\n    }\n  pstr->valid_len = byte_idx;\n  pstr->valid_raw_len = byte_idx;\n}\n\n/* Build wide character buffer PSTR->WCS like build_wcs_buffer,\n   but for REG_ICASE.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nbuild_wcs_upper_buffer (re_string_t *pstr)\n{\n  mbstate_t prev_st;\n  Idx src_idx, byte_idx, end_idx, remain_len;\n  size_t mbclen;\n#ifdef _LIBC\n  char buf[MB_LEN_MAX];\n  DEBUG_ASSERT (pstr->mb_cur_max <= MB_LEN_MAX);\n#else\n  char buf[64];\n#endif\n\n  byte_idx = pstr->valid_len;\n  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;\n\n  /* The following optimization assumes that ASCII characters can be\n     mapped to wide characters with a simple cast.  */\n  if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed)\n    {\n      while (byte_idx < end_idx)\n\t{\n\t  wchar_t wc;\n\t  unsigned char ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];\n\n\t  if (isascii (ch) && mbsinit (&pstr->cur_state))\n\t    {\n\t      /* The next step uses the assumption that wchar_t is encoded\n\t\t ASCII-safe: all ASCII values can be converted like this.  */\n\t      wchar_t wcu = __towupper (ch);\n\t      if (isascii (wcu))\n\t\t{\n\t\t  pstr->mbs[byte_idx] = wcu;\n\t\t  pstr->wcs[byte_idx] = wcu;\n\t\t  byte_idx++;\n\t\t  continue;\n\t\t}\n\t    }\n\n\t  remain_len = end_idx - byte_idx;\n\t  prev_st = pstr->cur_state;\n\t  mbclen = __mbrtowc (&wc,\n\t\t\t      ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx\n\t\t\t       + byte_idx), remain_len, &pstr->cur_state);\n\t  if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2))\n\t    {\n\t      wchar_t wcu = __towupper (wc);\n\t      if (wcu != wc)\n\t\t{\n\t\t  size_t mbcdlen;\n\n\t\t  mbcdlen = __wcrtomb (buf, wcu, &prev_st);\n\t\t  if (__glibc_likely (mbclen == mbcdlen))\n\t\t    memcpy (pstr->mbs + byte_idx, buf, mbclen);\n\t\t  else\n\t\t    {\n\t\t      src_idx = byte_idx;\n\t\t      goto offsets_needed;\n\t\t    }\n\t\t}\n\t      else\n\t\tmemcpy (pstr->mbs + byte_idx,\n\t\t\tpstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);\n\t      pstr->wcs[byte_idx++] = wcu;\n\t      /* Write paddings.  */\n\t      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)\n\t\tpstr->wcs[byte_idx++] = WEOF;\n\t    }\n\t  else if (mbclen == (size_t) -1 || mbclen == 0\n\t\t   || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len))\n\t    {\n\t      /* It is an invalid character, an incomplete character\n\t\t at the end of the string, or '\\0'.  Just use the byte.  */\n\t      pstr->mbs[byte_idx] = ch;\n\t      /* And also cast it to wide char.  */\n\t      pstr->wcs[byte_idx++] = (wchar_t) ch;\n\t      if (__glibc_unlikely (mbclen == (size_t) -1))\n\t\tpstr->cur_state = prev_st;\n\t    }\n\t  else\n\t    {\n\t      /* The buffer doesn't have enough space, finish to build.  */\n\t      pstr->cur_state = prev_st;\n\t      break;\n\t    }\n\t}\n      pstr->valid_len = byte_idx;\n      pstr->valid_raw_len = byte_idx;\n      return REG_NOERROR;\n    }\n  else\n    for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;)\n      {\n\twchar_t wc;\n\tconst char *p;\n      offsets_needed:\n\tremain_len = end_idx - byte_idx;\n\tprev_st = pstr->cur_state;\n\tif (__glibc_unlikely (pstr->trans != NULL))\n\t  {\n\t    int i, ch;\n\n\t    for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)\n\t      {\n\t\tch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];\n\t\tbuf[i] = pstr->trans[ch];\n\t      }\n\t    p = (const char *) buf;\n\t  }\n\telse\n\t  p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;\n\tmbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);\n\tif (__glibc_likely (0 < mbclen && mbclen < (size_t) -2))\n\t  {\n\t    wchar_t wcu = __towupper (wc);\n\t    if (wcu != wc)\n\t      {\n\t\tsize_t mbcdlen;\n\n\t\tmbcdlen = __wcrtomb ((char *) buf, wcu, &prev_st);\n\t\tif (__glibc_likely (mbclen == mbcdlen))\n\t\t  memcpy (pstr->mbs + byte_idx, buf, mbclen);\n\t\telse if (mbcdlen != (size_t) -1)\n\t\t  {\n\t\t    size_t i;\n\n\t\t    if (byte_idx + mbcdlen > pstr->bufs_len)\n\t\t      {\n\t\t\tpstr->cur_state = prev_st;\n\t\t\tbreak;\n\t\t      }\n\n\t\t    if (pstr->offsets == NULL)\n\t\t      {\n\t\t\tpstr->offsets = re_malloc (Idx, pstr->bufs_len);\n\n\t\t\tif (pstr->offsets == NULL)\n\t\t\t  return REG_ESPACE;\n\t\t      }\n\t\t    if (!pstr->offsets_needed)\n\t\t      {\n\t\t\tfor (i = 0; i < (size_t) byte_idx; ++i)\n\t\t\t  pstr->offsets[i] = i;\n\t\t\tpstr->offsets_needed = 1;\n\t\t      }\n\n\t\t    memcpy (pstr->mbs + byte_idx, buf, mbcdlen);\n\t\t    pstr->wcs[byte_idx] = wcu;\n\t\t    pstr->offsets[byte_idx] = src_idx;\n\t\t    for (i = 1; i < mbcdlen; ++i)\n\t\t      {\n\t\t\tpstr->offsets[byte_idx + i]\n\t\t\t  = src_idx + (i < mbclen ? i : mbclen - 1);\n\t\t\tpstr->wcs[byte_idx + i] = WEOF;\n\t\t      }\n\t\t    pstr->len += mbcdlen - mbclen;\n\t\t    if (pstr->raw_stop > src_idx)\n\t\t      pstr->stop += mbcdlen - mbclen;\n\t\t    end_idx = (pstr->bufs_len > pstr->len)\n\t\t\t      ? pstr->len : pstr->bufs_len;\n\t\t    byte_idx += mbcdlen;\n\t\t    src_idx += mbclen;\n\t\t    continue;\n\t\t  }\n\t\telse\n\t\t  memcpy (pstr->mbs + byte_idx, p, mbclen);\n\t      }\n\t    else\n\t      memcpy (pstr->mbs + byte_idx, p, mbclen);\n\n\t    if (__glibc_unlikely (pstr->offsets_needed != 0))\n\t      {\n\t\tsize_t i;\n\t\tfor (i = 0; i < mbclen; ++i)\n\t\t  pstr->offsets[byte_idx + i] = src_idx + i;\n\t      }\n\t    src_idx += mbclen;\n\n\t    pstr->wcs[byte_idx++] = wcu;\n\t    /* Write paddings.  */\n\t    for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)\n\t      pstr->wcs[byte_idx++] = WEOF;\n\t  }\n\telse if (mbclen == (size_t) -1 || mbclen == 0\n\t\t || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len))\n\t  {\n\t    /* It is an invalid character or '\\0'.  Just use the byte.  */\n\t    int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];\n\n\t    if (__glibc_unlikely (pstr->trans != NULL))\n\t      ch = pstr->trans [ch];\n\t    pstr->mbs[byte_idx] = ch;\n\n\t    if (__glibc_unlikely (pstr->offsets_needed != 0))\n\t      pstr->offsets[byte_idx] = src_idx;\n\t    ++src_idx;\n\n\t    /* And also cast it to wide char.  */\n\t    pstr->wcs[byte_idx++] = (wchar_t) ch;\n\t    if (__glibc_unlikely (mbclen == (size_t) -1))\n\t      pstr->cur_state = prev_st;\n\t  }\n\telse\n\t  {\n\t    /* The buffer doesn't have enough space, finish to build.  */\n\t    pstr->cur_state = prev_st;\n\t    break;\n\t  }\n      }\n  pstr->valid_len = byte_idx;\n  pstr->valid_raw_len = src_idx;\n  return REG_NOERROR;\n}\n\n/* Skip characters until the index becomes greater than NEW_RAW_IDX.\n   Return the index.  */\n\nstatic Idx\nre_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)\n{\n  mbstate_t prev_st;\n  Idx rawbuf_idx;\n  size_t mbclen;\n  wint_t wc = WEOF;\n\n  /* Skip the characters which are not necessary to check.  */\n  for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;\n       rawbuf_idx < new_raw_idx;)\n    {\n      wchar_t wc2;\n      Idx remain_len = pstr->raw_len - rawbuf_idx;\n      prev_st = pstr->cur_state;\n      mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,\n\t\t\t  remain_len, &pstr->cur_state);\n      if (__glibc_unlikely (mbclen == (size_t) -2 || mbclen == (size_t) -1\n\t\t\t    || mbclen == 0))\n\t{\n\t  /* We treat these cases as a single byte character.  */\n\t  if (mbclen == 0 || remain_len == 0)\n\t    wc = L'\\0';\n\t  else\n\t    wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx);\n\t  mbclen = 1;\n\t  pstr->cur_state = prev_st;\n\t}\n      else\n\twc = wc2;\n      /* Then proceed the next character.  */\n      rawbuf_idx += mbclen;\n    }\n  *last_wc = wc;\n  return rawbuf_idx;\n}\n#endif /* RE_ENABLE_I18N  */\n\n/* Build the buffer PSTR->MBS, and apply the translation if we need.\n   This function is used in case of REG_ICASE.  */\n\nstatic void\nbuild_upper_buffer (re_string_t *pstr)\n{\n  Idx char_idx, end_idx;\n  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;\n\n  for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)\n    {\n      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];\n      if (__glibc_unlikely (pstr->trans != NULL))\n\tch = pstr->trans[ch];\n      pstr->mbs[char_idx] = toupper (ch);\n    }\n  pstr->valid_len = char_idx;\n  pstr->valid_raw_len = char_idx;\n}\n\n/* Apply TRANS to the buffer in PSTR.  */\n\nstatic void\nre_string_translate_buffer (re_string_t *pstr)\n{\n  Idx buf_idx, end_idx;\n  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;\n\n  for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)\n    {\n      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx];\n      pstr->mbs[buf_idx] = pstr->trans[ch];\n    }\n\n  pstr->valid_len = buf_idx;\n  pstr->valid_raw_len = buf_idx;\n}\n\n/* This function re-construct the buffers.\n   Concretely, convert to wide character in case of pstr->mb_cur_max > 1,\n   convert to upper case in case of REG_ICASE, apply translation.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)\n{\n  Idx offset;\n\n  if (__glibc_unlikely (pstr->raw_mbs_idx <= idx))\n    offset = idx - pstr->raw_mbs_idx;\n  else\n    {\n      /* Reset buffer.  */\n#ifdef RE_ENABLE_I18N\n      if (pstr->mb_cur_max > 1)\n\tmemset (&pstr->cur_state, '\\0', sizeof (mbstate_t));\n#endif /* RE_ENABLE_I18N */\n      pstr->len = pstr->raw_len;\n      pstr->stop = pstr->raw_stop;\n      pstr->valid_len = 0;\n      pstr->raw_mbs_idx = 0;\n      pstr->valid_raw_len = 0;\n      pstr->offsets_needed = 0;\n      pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF\n\t\t\t   : CONTEXT_NEWLINE | CONTEXT_BEGBUF);\n      if (!pstr->mbs_allocated)\n\tpstr->mbs = (unsigned char *) pstr->raw_mbs;\n      offset = idx;\n    }\n\n  if (__glibc_likely (offset != 0))\n    {\n      /* Should the already checked characters be kept?  */\n      if (__glibc_likely (offset < pstr->valid_raw_len))\n\t{\n\t  /* Yes, move them to the front of the buffer.  */\n#ifdef RE_ENABLE_I18N\n\t  if (__glibc_unlikely (pstr->offsets_needed))\n\t    {\n\t      Idx low = 0, high = pstr->valid_len, mid;\n\t      do\n\t\t{\n\t\t  mid = (high + low) / 2;\n\t\t  if (pstr->offsets[mid] > offset)\n\t\t    high = mid;\n\t\t  else if (pstr->offsets[mid] < offset)\n\t\t    low = mid + 1;\n\t\t  else\n\t\t    break;\n\t\t}\n\t      while (low < high);\n\t      if (pstr->offsets[mid] < offset)\n\t\t++mid;\n\t      pstr->tip_context = re_string_context_at (pstr, mid - 1,\n\t\t\t\t\t\t\teflags);\n\t      /* This can be quite complicated, so handle specially\n\t\t only the common and easy case where the character with\n\t\t different length representation of lower and upper\n\t\t case is present at or after offset.  */\n\t      if (pstr->valid_len > offset\n\t\t  && mid == offset && pstr->offsets[mid] == offset)\n\t\t{\n\t\t  memmove (pstr->wcs, pstr->wcs + offset,\n\t\t\t   (pstr->valid_len - offset) * sizeof (wint_t));\n\t\t  memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset);\n\t\t  pstr->valid_len -= offset;\n\t\t  pstr->valid_raw_len -= offset;\n\t\t  for (low = 0; low < pstr->valid_len; low++)\n\t\t    pstr->offsets[low] = pstr->offsets[low + offset] - offset;\n\t\t}\n\t      else\n\t\t{\n\t\t  /* Otherwise, just find out how long the partial multibyte\n\t\t     character at offset is and fill it with WEOF/255.  */\n\t\t  pstr->len = pstr->raw_len - idx + offset;\n\t\t  pstr->stop = pstr->raw_stop - idx + offset;\n\t\t  pstr->offsets_needed = 0;\n\t\t  while (mid > 0 && pstr->offsets[mid - 1] == offset)\n\t\t    --mid;\n\t\t  while (mid < pstr->valid_len)\n\t\t    if (pstr->wcs[mid] != WEOF)\n\t\t      break;\n\t\t    else\n\t\t      ++mid;\n\t\t  if (mid == pstr->valid_len)\n\t\t    pstr->valid_len = 0;\n\t\t  else\n\t\t    {\n\t\t      pstr->valid_len = pstr->offsets[mid] - offset;\n\t\t      if (pstr->valid_len)\n\t\t\t{\n\t\t\t  for (low = 0; low < pstr->valid_len; ++low)\n\t\t\t    pstr->wcs[low] = WEOF;\n\t\t\t  memset (pstr->mbs, 255, pstr->valid_len);\n\t\t\t}\n\t\t    }\n\t\t  pstr->valid_raw_len = pstr->valid_len;\n\t\t}\n\t    }\n\t  else\n#endif\n\t    {\n\t      pstr->tip_context = re_string_context_at (pstr, offset - 1,\n\t\t\t\t\t\t\teflags);\n#ifdef RE_ENABLE_I18N\n\t      if (pstr->mb_cur_max > 1)\n\t\tmemmove (pstr->wcs, pstr->wcs + offset,\n\t\t\t (pstr->valid_len - offset) * sizeof (wint_t));\n#endif /* RE_ENABLE_I18N */\n\t      if (__glibc_unlikely (pstr->mbs_allocated))\n\t\tmemmove (pstr->mbs, pstr->mbs + offset,\n\t\t\t pstr->valid_len - offset);\n\t      pstr->valid_len -= offset;\n\t      pstr->valid_raw_len -= offset;\n\t      DEBUG_ASSERT (pstr->valid_len > 0);\n\t    }\n\t}\n      else\n\t{\n#ifdef RE_ENABLE_I18N\n\t  /* No, skip all characters until IDX.  */\n\t  Idx prev_valid_len = pstr->valid_len;\n\n\t  if (__glibc_unlikely (pstr->offsets_needed))\n\t    {\n\t      pstr->len = pstr->raw_len - idx + offset;\n\t      pstr->stop = pstr->raw_stop - idx + offset;\n\t      pstr->offsets_needed = 0;\n\t    }\n#endif\n\t  pstr->valid_len = 0;\n#ifdef RE_ENABLE_I18N\n\t  if (pstr->mb_cur_max > 1)\n\t    {\n\t      Idx wcs_idx;\n\t      wint_t wc = WEOF;\n\n\t      if (pstr->is_utf8)\n\t\t{\n\t\t  const unsigned char *raw, *p, *end;\n\n\t\t  /* Special case UTF-8.  Multi-byte chars start with any\n\t\t     byte other than 0x80 - 0xbf.  */\n\t\t  raw = pstr->raw_mbs + pstr->raw_mbs_idx;\n\t\t  end = raw + (offset - pstr->mb_cur_max);\n\t\t  if (end < pstr->raw_mbs)\n\t\t    end = pstr->raw_mbs;\n\t\t  p = raw + offset - 1;\n#ifdef _LIBC\n\t\t  /* We know the wchar_t encoding is UCS4, so for the simple\n\t\t     case, ASCII characters, skip the conversion step.  */\n\t\t  if (isascii (*p) && __glibc_likely (pstr->trans == NULL))\n\t\t    {\n\t\t      memset (&pstr->cur_state, '\\0', sizeof (mbstate_t));\n\t\t      /* pstr->valid_len = 0; */\n\t\t      wc = (wchar_t) *p;\n\t\t    }\n\t\t  else\n#endif\n\t\t    for (; p >= end; --p)\n\t\t      if ((*p & 0xc0) != 0x80)\n\t\t\t{\n\t\t\t  mbstate_t cur_state;\n\t\t\t  wchar_t wc2;\n\t\t\t  Idx mlen = raw + pstr->len - p;\n\t\t\t  unsigned char buf[6];\n\t\t\t  size_t mbclen;\n\n\t\t\t  const unsigned char *pp = p;\n\t\t\t  if (__glibc_unlikely (pstr->trans != NULL))\n\t\t\t    {\n\t\t\t      int i = mlen < 6 ? mlen : 6;\n\t\t\t      while (--i >= 0)\n\t\t\t\tbuf[i] = pstr->trans[p[i]];\n\t\t\t      pp = buf;\n\t\t\t    }\n\t\t\t  /* XXX Don't use mbrtowc, we know which conversion\n\t\t\t     to use (UTF-8 -> UCS4).  */\n\t\t\t  memset (&cur_state, 0, sizeof (cur_state));\n\t\t\t  mbclen = __mbrtowc (&wc2, (const char *) pp, mlen,\n\t\t\t\t\t      &cur_state);\n\t\t\t  if (raw + offset - p <= mbclen\n\t\t\t      && mbclen < (size_t) -2)\n\t\t\t    {\n\t\t\t      memset (&pstr->cur_state, '\\0',\n\t\t\t\t      sizeof (mbstate_t));\n\t\t\t      pstr->valid_len = mbclen - (raw + offset - p);\n\t\t\t      wc = wc2;\n\t\t\t    }\n\t\t\t  break;\n\t\t\t}\n\t\t}\n\n\t      if (wc == WEOF)\n\t\tpstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;\n\t      if (wc == WEOF)\n\t\tpstr->tip_context\n\t\t  = re_string_context_at (pstr, prev_valid_len - 1, eflags);\n\t      else\n\t\tpstr->tip_context = ((__glibc_unlikely (pstr->word_ops_used != 0)\n\t\t\t\t      && IS_WIDE_WORD_CHAR (wc))\n\t\t\t\t     ? CONTEXT_WORD\n\t\t\t\t     : ((IS_WIDE_NEWLINE (wc)\n\t\t\t\t\t && pstr->newline_anchor)\n\t\t\t\t\t? CONTEXT_NEWLINE : 0));\n\t      if (__glibc_unlikely (pstr->valid_len))\n\t\t{\n\t\t  for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)\n\t\t    pstr->wcs[wcs_idx] = WEOF;\n\t\t  if (pstr->mbs_allocated)\n\t\t    memset (pstr->mbs, 255, pstr->valid_len);\n\t\t}\n\t      pstr->valid_raw_len = pstr->valid_len;\n\t    }\n\t  else\n#endif /* RE_ENABLE_I18N */\n\t    {\n\t      int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];\n\t      pstr->valid_raw_len = 0;\n\t      if (pstr->trans)\n\t\tc = pstr->trans[c];\n\t      pstr->tip_context = (bitset_contain (pstr->word_char, c)\n\t\t\t\t   ? CONTEXT_WORD\n\t\t\t\t   : ((IS_NEWLINE (c) && pstr->newline_anchor)\n\t\t\t\t      ? CONTEXT_NEWLINE : 0));\n\t    }\n\t}\n      if (!__glibc_unlikely (pstr->mbs_allocated))\n\tpstr->mbs += offset;\n    }\n  pstr->raw_mbs_idx = idx;\n  pstr->len -= offset;\n  pstr->stop -= offset;\n\n  /* Then build the buffers.  */\n#ifdef RE_ENABLE_I18N\n  if (pstr->mb_cur_max > 1)\n    {\n      if (pstr->icase)\n\t{\n\t  reg_errcode_t ret = build_wcs_upper_buffer (pstr);\n\t  if (__glibc_unlikely (ret != REG_NOERROR))\n\t    return ret;\n\t}\n      else\n\tbuild_wcs_buffer (pstr);\n    }\n  else\n#endif /* RE_ENABLE_I18N */\n    if (__glibc_unlikely (pstr->mbs_allocated))\n      {\n\tif (pstr->icase)\n\t  build_upper_buffer (pstr);\n\telse if (pstr->trans != NULL)\n\t  re_string_translate_buffer (pstr);\n      }\n    else\n      pstr->valid_len = pstr->len;\n\n  pstr->cur_idx = 0;\n  return REG_NOERROR;\n}\n\nstatic unsigned char\n__attribute__ ((pure))\nre_string_peek_byte_case (const re_string_t *pstr, Idx idx)\n{\n  int ch;\n  Idx off;\n\n  /* Handle the common (easiest) cases first.  */\n  if (__glibc_likely (!pstr->mbs_allocated))\n    return re_string_peek_byte (pstr, idx);\n\n#ifdef RE_ENABLE_I18N\n  if (pstr->mb_cur_max > 1\n      && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))\n    return re_string_peek_byte (pstr, idx);\n#endif\n\n  off = pstr->cur_idx + idx;\n#ifdef RE_ENABLE_I18N\n  if (pstr->offsets_needed)\n    off = pstr->offsets[off];\n#endif\n\n  ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];\n\n#ifdef RE_ENABLE_I18N\n  /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I\n     this function returns CAPITAL LETTER I instead of first byte of\n     DOTLESS SMALL LETTER I.  The latter would confuse the parser,\n     since peek_byte_case doesn't advance cur_idx in any way.  */\n  if (pstr->offsets_needed && !isascii (ch))\n    return re_string_peek_byte (pstr, idx);\n#endif\n\n  return ch;\n}\n\nstatic unsigned char\nre_string_fetch_byte_case (re_string_t *pstr)\n{\n  if (__glibc_likely (!pstr->mbs_allocated))\n    return re_string_fetch_byte (pstr);\n\n#ifdef RE_ENABLE_I18N\n  if (pstr->offsets_needed)\n    {\n      Idx off;\n      int ch;\n\n      /* For tr_TR.UTF-8 [[:islower:]] there is\n\t [[: CAPITAL LETTER I WITH DOT lower:]] in mbs.  Skip\n\t in that case the whole multi-byte character and return\n\t the original letter.  On the other side, with\n\t [[: DOTLESS SMALL LETTER I return [[:I, as doing\n\t anything else would complicate things too much.  */\n\n      if (!re_string_first_byte (pstr, pstr->cur_idx))\n\treturn re_string_fetch_byte (pstr);\n\n      off = pstr->offsets[pstr->cur_idx];\n      ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];\n\n      if (! isascii (ch))\n\treturn re_string_fetch_byte (pstr);\n\n      re_string_skip_bytes (pstr,\n\t\t\t    re_string_char_size_at (pstr, pstr->cur_idx));\n      return ch;\n    }\n#endif\n\n  return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];\n}\n\nstatic void\nre_string_destruct (re_string_t *pstr)\n{\n#ifdef RE_ENABLE_I18N\n  re_free (pstr->wcs);\n  re_free (pstr->offsets);\n#endif /* RE_ENABLE_I18N  */\n  if (pstr->mbs_allocated)\n    re_free (pstr->mbs);\n}\n\n/* Return the context at IDX in INPUT.  */\n\nstatic unsigned int\nre_string_context_at (const re_string_t *input, Idx idx, int eflags)\n{\n  int c;\n  if (__glibc_unlikely (idx < 0))\n    /* In this case, we use the value stored in input->tip_context,\n       since we can't know the character in input->mbs[-1] here.  */\n    return input->tip_context;\n  if (__glibc_unlikely (idx == input->len))\n    return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF\n\t    : CONTEXT_NEWLINE | CONTEXT_ENDBUF);\n#ifdef RE_ENABLE_I18N\n  if (input->mb_cur_max > 1)\n    {\n      wint_t wc;\n      Idx wc_idx = idx;\n      while(input->wcs[wc_idx] == WEOF)\n\t{\n\t  DEBUG_ASSERT (wc_idx >= 0);\n\t  --wc_idx;\n\t  if (wc_idx < 0)\n\t    return input->tip_context;\n\t}\n      wc = input->wcs[wc_idx];\n      if (__glibc_unlikely (input->word_ops_used != 0)\n\t  && IS_WIDE_WORD_CHAR (wc))\n\treturn CONTEXT_WORD;\n      return (IS_WIDE_NEWLINE (wc) && input->newline_anchor\n\t      ? CONTEXT_NEWLINE : 0);\n    }\n  else\n#endif\n    {\n      c = re_string_byte_at (input, idx);\n      if (bitset_contain (input->word_char, c))\n\treturn CONTEXT_WORD;\n      return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;\n    }\n}\n\f\n/* Functions for set operation.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_node_set_alloc (re_node_set *set, Idx size)\n{\n  set->alloc = size;\n  set->nelem = 0;\n  set->elems = re_malloc (Idx, size);\n  if (__glibc_unlikely (set->elems == NULL)\n      && (MALLOC_0_IS_NONNULL || size != 0))\n    return REG_ESPACE;\n  return REG_NOERROR;\n}\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_node_set_init_1 (re_node_set *set, Idx elem)\n{\n  set->alloc = 1;\n  set->nelem = 1;\n  set->elems = re_malloc (Idx, 1);\n  if (__glibc_unlikely (set->elems == NULL))\n    {\n      set->alloc = set->nelem = 0;\n      return REG_ESPACE;\n    }\n  set->elems[0] = elem;\n  return REG_NOERROR;\n}\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)\n{\n  set->alloc = 2;\n  set->elems = re_malloc (Idx, 2);\n  if (__glibc_unlikely (set->elems == NULL))\n    return REG_ESPACE;\n  if (elem1 == elem2)\n    {\n      set->nelem = 1;\n      set->elems[0] = elem1;\n    }\n  else\n    {\n      set->nelem = 2;\n      if (elem1 < elem2)\n\t{\n\t  set->elems[0] = elem1;\n\t  set->elems[1] = elem2;\n\t}\n      else\n\t{\n\t  set->elems[0] = elem2;\n\t  set->elems[1] = elem1;\n\t}\n    }\n  return REG_NOERROR;\n}\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_node_set_init_copy (re_node_set *dest, const re_node_set *src)\n{\n  dest->nelem = src->nelem;\n  if (src->nelem > 0)\n    {\n      dest->alloc = dest->nelem;\n      dest->elems = re_malloc (Idx, dest->alloc);\n      if (__glibc_unlikely (dest->elems == NULL))\n\t{\n\t  dest->alloc = dest->nelem = 0;\n\t  return REG_ESPACE;\n\t}\n      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));\n    }\n  else\n    re_node_set_init_empty (dest);\n  return REG_NOERROR;\n}\n\n/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to\n   DEST. Return value indicate the error code or REG_NOERROR if succeeded.\n   Note: We assume dest->elems is NULL, when dest->alloc is 0.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,\n\t\t\t   const re_node_set *src2)\n{\n  Idx i1, i2, is, id, delta, sbase;\n  if (src1->nelem == 0 || src2->nelem == 0)\n    return REG_NOERROR;\n\n  /* We need dest->nelem + 2 * elems_in_intersection; this is a\n     conservative estimate.  */\n  if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)\n    {\n      Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;\n      Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);\n      if (__glibc_unlikely (new_elems == NULL))\n\treturn REG_ESPACE;\n      dest->elems = new_elems;\n      dest->alloc = new_alloc;\n    }\n\n  /* Find the items in the intersection of SRC1 and SRC2, and copy\n     into the top of DEST those that are not already in DEST itself.  */\n  sbase = dest->nelem + src1->nelem + src2->nelem;\n  i1 = src1->nelem - 1;\n  i2 = src2->nelem - 1;\n  id = dest->nelem - 1;\n  for (;;)\n    {\n      if (src1->elems[i1] == src2->elems[i2])\n\t{\n\t  /* Try to find the item in DEST.  Maybe we could binary search?  */\n\t  while (id >= 0 && dest->elems[id] > src1->elems[i1])\n\t    --id;\n\n\t  if (id < 0 || dest->elems[id] != src1->elems[i1])\n            dest->elems[--sbase] = src1->elems[i1];\n\n\t  if (--i1 < 0 || --i2 < 0)\n\t    break;\n\t}\n\n      /* Lower the highest of the two items.  */\n      else if (src1->elems[i1] < src2->elems[i2])\n\t{\n\t  if (--i2 < 0)\n\t    break;\n\t}\n      else\n\t{\n\t  if (--i1 < 0)\n\t    break;\n\t}\n    }\n\n  id = dest->nelem - 1;\n  is = dest->nelem + src1->nelem + src2->nelem - 1;\n  delta = is - sbase + 1;\n\n  /* Now copy.  When DELTA becomes zero, the remaining\n     DEST elements are already in place; this is more or\n     less the same loop that is in re_node_set_merge.  */\n  dest->nelem += delta;\n  if (delta > 0 && id >= 0)\n    for (;;)\n      {\n\tif (dest->elems[is] > dest->elems[id])\n\t  {\n\t    /* Copy from the top.  */\n\t    dest->elems[id + delta--] = dest->elems[is--];\n\t    if (delta == 0)\n\t      break;\n\t  }\n\telse\n\t  {\n\t    /* Slide from the bottom.  */\n\t    dest->elems[id + delta] = dest->elems[id];\n\t    if (--id < 0)\n\t      break;\n\t  }\n      }\n\n  /* Copy remaining SRC elements.  */\n  memcpy (dest->elems, dest->elems + sbase, delta * sizeof (Idx));\n\n  return REG_NOERROR;\n}\n\n/* Calculate the union set of the sets SRC1 and SRC2. And store it to\n   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_node_set_init_union (re_node_set *dest, const re_node_set *src1,\n\t\t\tconst re_node_set *src2)\n{\n  Idx i1, i2, id;\n  if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)\n    {\n      dest->alloc = src1->nelem + src2->nelem;\n      dest->elems = re_malloc (Idx, dest->alloc);\n      if (__glibc_unlikely (dest->elems == NULL))\n\treturn REG_ESPACE;\n    }\n  else\n    {\n      if (src1 != NULL && src1->nelem > 0)\n\treturn re_node_set_init_copy (dest, src1);\n      else if (src2 != NULL && src2->nelem > 0)\n\treturn re_node_set_init_copy (dest, src2);\n      else\n\tre_node_set_init_empty (dest);\n      return REG_NOERROR;\n    }\n  for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)\n    {\n      if (src1->elems[i1] > src2->elems[i2])\n\t{\n\t  dest->elems[id++] = src2->elems[i2++];\n\t  continue;\n\t}\n      if (src1->elems[i1] == src2->elems[i2])\n\t++i2;\n      dest->elems[id++] = src1->elems[i1++];\n    }\n  if (i1 < src1->nelem)\n    {\n      memcpy (dest->elems + id, src1->elems + i1,\n\t     (src1->nelem - i1) * sizeof (Idx));\n      id += src1->nelem - i1;\n    }\n  else if (i2 < src2->nelem)\n    {\n      memcpy (dest->elems + id, src2->elems + i2,\n\t     (src2->nelem - i2) * sizeof (Idx));\n      id += src2->nelem - i2;\n    }\n  dest->nelem = id;\n  return REG_NOERROR;\n}\n\n/* Calculate the union set of the sets DEST and SRC. And store it to\n   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_node_set_merge (re_node_set *dest, const re_node_set *src)\n{\n  Idx is, id, sbase, delta;\n  if (src == NULL || src->nelem == 0)\n    return REG_NOERROR;\n  if (dest->alloc < 2 * src->nelem + dest->nelem)\n    {\n      Idx new_alloc = 2 * (src->nelem + dest->alloc);\n      Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc);\n      if (__glibc_unlikely (new_buffer == NULL))\n\treturn REG_ESPACE;\n      dest->elems = new_buffer;\n      dest->alloc = new_alloc;\n    }\n\n  if (__glibc_unlikely (dest->nelem == 0))\n    {\n      dest->nelem = src->nelem;\n      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));\n      return REG_NOERROR;\n    }\n\n  /* Copy into the top of DEST the items of SRC that are not\n     found in DEST.  Maybe we could binary search in DEST?  */\n  for (sbase = dest->nelem + 2 * src->nelem,\n       is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; )\n    {\n      if (dest->elems[id] == src->elems[is])\n\tis--, id--;\n      else if (dest->elems[id] < src->elems[is])\n\tdest->elems[--sbase] = src->elems[is--];\n      else /* if (dest->elems[id] > src->elems[is]) */\n\t--id;\n    }\n\n  if (is >= 0)\n    {\n      /* If DEST is exhausted, the remaining items of SRC must be unique.  */\n      sbase -= is + 1;\n      memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (Idx));\n    }\n\n  id = dest->nelem - 1;\n  is = dest->nelem + 2 * src->nelem - 1;\n  delta = is - sbase + 1;\n  if (delta == 0)\n    return REG_NOERROR;\n\n  /* Now copy.  When DELTA becomes zero, the remaining\n     DEST elements are already in place.  */\n  dest->nelem += delta;\n  for (;;)\n    {\n      if (dest->elems[is] > dest->elems[id])\n\t{\n\t  /* Copy from the top.  */\n\t  dest->elems[id + delta--] = dest->elems[is--];\n\t  if (delta == 0)\n\t    break;\n\t}\n      else\n\t{\n\t  /* Slide from the bottom.  */\n\t  dest->elems[id + delta] = dest->elems[id];\n\t  if (--id < 0)\n\t    {\n\t      /* Copy remaining SRC elements.  */\n\t      memcpy (dest->elems, dest->elems + sbase,\n\t\t      delta * sizeof (Idx));\n\t      break;\n\t    }\n\t}\n    }\n\n  return REG_NOERROR;\n}\n\n/* Insert the new element ELEM to the re_node_set* SET.\n   SET should not already have ELEM.\n   Return true if successful.  */\n\nstatic bool\n__attribute_warn_unused_result__\nre_node_set_insert (re_node_set *set, Idx elem)\n{\n  Idx idx;\n  /* In case the set is empty.  */\n  if (set->alloc == 0)\n    return __glibc_likely (re_node_set_init_1 (set, elem) == REG_NOERROR);\n\n  if (__glibc_unlikely (set->nelem) == 0)\n    {\n      /* We already guaranteed above that set->alloc != 0.  */\n      set->elems[0] = elem;\n      ++set->nelem;\n      return true;\n    }\n\n  /* Realloc if we need.  */\n  if (set->alloc == set->nelem)\n    {\n      Idx *new_elems;\n      set->alloc = set->alloc * 2;\n      new_elems = re_realloc (set->elems, Idx, set->alloc);\n      if (__glibc_unlikely (new_elems == NULL))\n\treturn false;\n      set->elems = new_elems;\n    }\n\n  /* Move the elements which follows the new element.  Test the\n     first element separately to skip a check in the inner loop.  */\n  if (elem < set->elems[0])\n    {\n      for (idx = set->nelem; idx > 0; idx--)\n\tset->elems[idx] = set->elems[idx - 1];\n    }\n  else\n    {\n      for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)\n\tset->elems[idx] = set->elems[idx - 1];\n      DEBUG_ASSERT (set->elems[idx - 1] < elem);\n    }\n\n  /* Insert the new element.  */\n  set->elems[idx] = elem;\n  ++set->nelem;\n  return true;\n}\n\n/* Insert the new element ELEM to the re_node_set* SET.\n   SET should not already have any element greater than or equal to ELEM.\n   Return true if successful.  */\n\nstatic bool\n__attribute_warn_unused_result__\nre_node_set_insert_last (re_node_set *set, Idx elem)\n{\n  /* Realloc if we need.  */\n  if (set->alloc == set->nelem)\n    {\n      Idx *new_elems;\n      set->alloc = (set->alloc + 1) * 2;\n      new_elems = re_realloc (set->elems, Idx, set->alloc);\n      if (__glibc_unlikely (new_elems == NULL))\n\treturn false;\n      set->elems = new_elems;\n    }\n\n  /* Insert the new element.  */\n  set->elems[set->nelem++] = elem;\n  return true;\n}\n\n/* Compare two node sets SET1 and SET2.\n   Return true if SET1 and SET2 are equivalent.  */\n\nstatic bool\n__attribute__ ((pure))\nre_node_set_compare (const re_node_set *set1, const re_node_set *set2)\n{\n  Idx i;\n  if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)\n    return false;\n  for (i = set1->nelem ; --i >= 0 ; )\n    if (set1->elems[i] != set2->elems[i])\n      return false;\n  return true;\n}\n\n/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */\n\nstatic Idx\n__attribute__ ((pure))\nre_node_set_contains (const re_node_set *set, Idx elem)\n{\n  __re_size_t idx, right, mid;\n  if (set->nelem <= 0)\n    return 0;\n\n  /* Binary search the element.  */\n  idx = 0;\n  right = set->nelem - 1;\n  while (idx < right)\n    {\n      mid = (idx + right) / 2;\n      if (set->elems[mid] < elem)\n\tidx = mid + 1;\n      else\n\tright = mid;\n    }\n  return set->elems[idx] == elem ? idx + 1 : 0;\n}\n\nstatic void\nre_node_set_remove_at (re_node_set *set, Idx idx)\n{\n  if (idx < 0 || idx >= set->nelem)\n    return;\n  --set->nelem;\n  for (; idx < set->nelem; idx++)\n    set->elems[idx] = set->elems[idx + 1];\n}\n\f\n\n/* Add the token TOKEN to dfa->nodes, and return the index of the token.\n   Or return -1 if an error occurred.  */\n\nstatic Idx\nre_dfa_add_node (re_dfa_t *dfa, re_token_t token)\n{\n  if (__glibc_unlikely (dfa->nodes_len >= dfa->nodes_alloc))\n    {\n      size_t new_nodes_alloc = dfa->nodes_alloc * 2;\n      Idx *new_nexts, *new_indices;\n      re_node_set *new_edests, *new_eclosures;\n      re_token_t *new_nodes;\n\n      /* Avoid overflows in realloc.  */\n      const size_t max_object_size = MAX (sizeof (re_token_t),\n\t\t\t\t\t  MAX (sizeof (re_node_set),\n\t\t\t\t\t       sizeof (Idx)));\n      if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size)\n\t\t\t    < new_nodes_alloc))\n\treturn -1;\n\n      new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);\n      if (__glibc_unlikely (new_nodes == NULL))\n\treturn -1;\n      dfa->nodes = new_nodes;\n      new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);\n      new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);\n      new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);\n      new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);\n      if (__glibc_unlikely (new_nexts == NULL || new_indices == NULL\n\t\t\t    || new_edests == NULL || new_eclosures == NULL))\n\t{\n\t   re_free (new_nexts);\n\t   re_free (new_indices);\n\t   re_free (new_edests);\n\t   re_free (new_eclosures);\n\t   return -1;\n\t}\n      dfa->nexts = new_nexts;\n      dfa->org_indices = new_indices;\n      dfa->edests = new_edests;\n      dfa->eclosures = new_eclosures;\n      dfa->nodes_alloc = new_nodes_alloc;\n    }\n  dfa->nodes[dfa->nodes_len] = token;\n  dfa->nodes[dfa->nodes_len].constraint = 0;\n#ifdef RE_ENABLE_I18N\n  dfa->nodes[dfa->nodes_len].accept_mb =\n    ((token.type == OP_PERIOD && dfa->mb_cur_max > 1)\n     || token.type == COMPLEX_BRACKET);\n#endif\n  dfa->nexts[dfa->nodes_len] = -1;\n  re_node_set_init_empty (dfa->edests + dfa->nodes_len);\n  re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);\n  return dfa->nodes_len++;\n}\n\nstatic re_hashval_t\ncalc_state_hash (const re_node_set *nodes, unsigned int context)\n{\n  re_hashval_t hash = nodes->nelem + context;\n  Idx i;\n  for (i = 0 ; i < nodes->nelem ; i++)\n    hash += nodes->elems[i];\n  return hash;\n}\n\n/* Search for the state whose node_set is equivalent to NODES.\n   Return the pointer to the state, if we found it in the DFA.\n   Otherwise create the new one and return it.  In case of an error\n   return NULL and set the error code in ERR.\n   Note: - We assume NULL as the invalid state, then it is possible that\n\t   return value is NULL and ERR is REG_NOERROR.\n\t - We never return non-NULL value in case of any errors, it is for\n\t   optimization.  */\n\nstatic re_dfastate_t *\n__attribute_warn_unused_result__\nre_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,\n\t\t  const re_node_set *nodes)\n{\n  re_hashval_t hash;\n  re_dfastate_t *new_state;\n  struct re_state_table_entry *spot;\n  Idx i;\n#if defined GCC_LINT || defined lint\n  /* Suppress bogus uninitialized-variable warnings.  */\n  *err = REG_NOERROR;\n#endif\n  if (__glibc_unlikely (nodes->nelem == 0))\n    {\n      *err = REG_NOERROR;\n      return NULL;\n    }\n  hash = calc_state_hash (nodes, 0);\n  spot = dfa->state_table + (hash & dfa->state_hash_mask);\n\n  for (i = 0 ; i < spot->num ; i++)\n    {\n      re_dfastate_t *state = spot->array[i];\n      if (hash != state->hash)\n\tcontinue;\n      if (re_node_set_compare (&state->nodes, nodes))\n\treturn state;\n    }\n\n  /* There are no appropriate state in the dfa, create the new one.  */\n  new_state = create_ci_newstate (dfa, nodes, hash);\n  if (__glibc_unlikely (new_state == NULL))\n    *err = REG_ESPACE;\n\n  return new_state;\n}\n\n/* Search for the state whose node_set is equivalent to NODES and\n   whose context is equivalent to CONTEXT.\n   Return the pointer to the state, if we found it in the DFA.\n   Otherwise create the new one and return it.  In case of an error\n   return NULL and set the error code in ERR.\n   Note: - We assume NULL as the invalid state, then it is possible that\n\t   return value is NULL and ERR is REG_NOERROR.\n\t - We never return non-NULL value in case of any errors, it is for\n\t   optimization.  */\n\nstatic re_dfastate_t *\n__attribute_warn_unused_result__\nre_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,\n\t\t\t  const re_node_set *nodes, unsigned int context)\n{\n  re_hashval_t hash;\n  re_dfastate_t *new_state;\n  struct re_state_table_entry *spot;\n  Idx i;\n#if defined GCC_LINT || defined lint\n  /* Suppress bogus uninitialized-variable warnings.  */\n  *err = REG_NOERROR;\n#endif\n  if (nodes->nelem == 0)\n    {\n      *err = REG_NOERROR;\n      return NULL;\n    }\n  hash = calc_state_hash (nodes, context);\n  spot = dfa->state_table + (hash & dfa->state_hash_mask);\n\n  for (i = 0 ; i < spot->num ; i++)\n    {\n      re_dfastate_t *state = spot->array[i];\n      if (state->hash == hash\n\t  && state->context == context\n\t  && re_node_set_compare (state->entrance_nodes, nodes))\n\treturn state;\n    }\n  /* There are no appropriate state in 'dfa', create the new one.  */\n  new_state = create_cd_newstate (dfa, nodes, context, hash);\n  if (__glibc_unlikely (new_state == NULL))\n    *err = REG_ESPACE;\n\n  return new_state;\n}\n\n/* Finish initialization of the new state NEWSTATE, and using its hash value\n   HASH put in the appropriate bucket of DFA's state table.  Return value\n   indicates the error code if failed.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nregister_state (const re_dfa_t *dfa, re_dfastate_t *newstate,\n\t\tre_hashval_t hash)\n{\n  struct re_state_table_entry *spot;\n  reg_errcode_t err;\n  Idx i;\n\n  newstate->hash = hash;\n  err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    return REG_ESPACE;\n  for (i = 0; i < newstate->nodes.nelem; i++)\n    {\n      Idx elem = newstate->nodes.elems[i];\n      if (!IS_EPSILON_NODE (dfa->nodes[elem].type))\n\tif (! re_node_set_insert_last (&newstate->non_eps_nodes, elem))\n\t  return REG_ESPACE;\n    }\n\n  spot = dfa->state_table + (hash & dfa->state_hash_mask);\n  if (__glibc_unlikely (spot->alloc <= spot->num))\n    {\n      Idx new_alloc = 2 * spot->num + 2;\n      re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,\n\t\t\t\t\t      new_alloc);\n      if (__glibc_unlikely (new_array == NULL))\n\treturn REG_ESPACE;\n      spot->array = new_array;\n      spot->alloc = new_alloc;\n    }\n  spot->array[spot->num++] = newstate;\n  return REG_NOERROR;\n}\n\nstatic void\nfree_state (re_dfastate_t *state)\n{\n  re_node_set_free (&state->non_eps_nodes);\n  re_node_set_free (&state->inveclosure);\n  if (state->entrance_nodes != &state->nodes)\n    {\n      re_node_set_free (state->entrance_nodes);\n      re_free (state->entrance_nodes);\n    }\n  re_node_set_free (&state->nodes);\n  re_free (state->word_trtable);\n  re_free (state->trtable);\n  re_free (state);\n}\n\n/* Create the new state which is independent of contexts.\n   Return the new state if succeeded, otherwise return NULL.  */\n\nstatic re_dfastate_t *\n__attribute_warn_unused_result__\ncreate_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,\n\t\t    re_hashval_t hash)\n{\n  Idx i;\n  reg_errcode_t err;\n  re_dfastate_t *newstate;\n\n  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);\n  if (__glibc_unlikely (newstate == NULL))\n    return NULL;\n  err = re_node_set_init_copy (&newstate->nodes, nodes);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    {\n      re_free (newstate);\n      return NULL;\n    }\n\n  newstate->entrance_nodes = &newstate->nodes;\n  for (i = 0 ; i < nodes->nelem ; i++)\n    {\n      re_token_t *node = dfa->nodes + nodes->elems[i];\n      re_token_type_t type = node->type;\n      if (type == CHARACTER && !node->constraint)\n\tcontinue;\n#ifdef RE_ENABLE_I18N\n      newstate->accept_mb |= node->accept_mb;\n#endif /* RE_ENABLE_I18N */\n\n      /* If the state has the halt node, the state is a halt state.  */\n      if (type == END_OF_RE)\n\tnewstate->halt = 1;\n      else if (type == OP_BACK_REF)\n\tnewstate->has_backref = 1;\n      else if (type == ANCHOR || node->constraint)\n\tnewstate->has_constraint = 1;\n    }\n  err = register_state (dfa, newstate, hash);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    {\n      free_state (newstate);\n      newstate = NULL;\n    }\n  return newstate;\n}\n\n/* Create the new state which is depend on the context CONTEXT.\n   Return the new state if succeeded, otherwise return NULL.  */\n\nstatic re_dfastate_t *\n__attribute_warn_unused_result__\ncreate_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,\n\t\t    unsigned int context, re_hashval_t hash)\n{\n  Idx i, nctx_nodes = 0;\n  reg_errcode_t err;\n  re_dfastate_t *newstate;\n\n  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);\n  if (__glibc_unlikely (newstate == NULL))\n    return NULL;\n  err = re_node_set_init_copy (&newstate->nodes, nodes);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    {\n      re_free (newstate);\n      return NULL;\n    }\n\n  newstate->context = context;\n  newstate->entrance_nodes = &newstate->nodes;\n\n  for (i = 0 ; i < nodes->nelem ; i++)\n    {\n      re_token_t *node = dfa->nodes + nodes->elems[i];\n      re_token_type_t type = node->type;\n      unsigned int constraint = node->constraint;\n\n      if (type == CHARACTER && !constraint)\n\tcontinue;\n#ifdef RE_ENABLE_I18N\n      newstate->accept_mb |= node->accept_mb;\n#endif /* RE_ENABLE_I18N */\n\n      /* If the state has the halt node, the state is a halt state.  */\n      if (type == END_OF_RE)\n\tnewstate->halt = 1;\n      else if (type == OP_BACK_REF)\n\tnewstate->has_backref = 1;\n\n      if (constraint)\n\t{\n\t  if (newstate->entrance_nodes == &newstate->nodes)\n\t    {\n\t      re_node_set *entrance_nodes = re_malloc (re_node_set, 1);\n\t      if (__glibc_unlikely (entrance_nodes == NULL))\n\t\t{\n\t\t  free_state (newstate);\n\t\t  return NULL;\n\t\t}\n\t      newstate->entrance_nodes = entrance_nodes;\n\t      if (re_node_set_init_copy (newstate->entrance_nodes, nodes)\n\t\t  != REG_NOERROR)\n\t\t{\n\t\t  free_state (newstate);\n\t\t  return NULL;\n\t\t}\n\t      nctx_nodes = 0;\n\t      newstate->has_constraint = 1;\n\t    }\n\n\t  if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))\n\t    {\n\t      re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);\n\t      ++nctx_nodes;\n\t    }\n\t}\n    }\n  err = register_state (dfa, newstate, hash);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    {\n      free_state (newstate);\n      newstate = NULL;\n    }\n  return  newstate;\n}\n"
  },
  {
    "path": "gnulib/regex_internal.h",
    "content": "/* Extended regular expression matching and search library.\n   Copyright (C) 2002-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#ifndef _REGEX_INTERNAL_H\n#define _REGEX_INTERNAL_H 1\n\n#include <ctype.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <langinfo.h>\n#include <locale.h>\n#include <wchar.h>\n#include <wctype.h>\n#include <stdbool.h>\n#include <stdint.h>\n\n#ifndef _LIBC\n# include <dynarray.h>\n#endif\n\n#include <intprops.h>\n#include <verify.h>\n\n#if defined DEBUG && DEBUG != 0\n# include <assert.h>\n# define DEBUG_ASSERT(x) assert (x)\n#else\n# define DEBUG_ASSERT(x) assume (x)\n#endif\n\n#ifdef _LIBC\n# include <libc-lock.h>\n# define lock_define(name) __libc_lock_define (, name)\n# define lock_init(lock) (__libc_lock_init (lock), 0)\n# define lock_fini(lock) ((void) 0)\n# define lock_lock(lock) __libc_lock_lock (lock)\n# define lock_unlock(lock) __libc_lock_unlock (lock)\n#elif defined GNULIB_LOCK && !defined GNULIB_REGEX_SINGLE_THREAD\n# include \"glthread/lock.h\"\n# define lock_define(name) gl_lock_define (, name)\n# define lock_init(lock) glthread_lock_init (&(lock))\n# define lock_fini(lock) glthread_lock_destroy (&(lock))\n# define lock_lock(lock) glthread_lock_lock (&(lock))\n# define lock_unlock(lock) glthread_lock_unlock (&(lock))\n#elif defined GNULIB_PTHREAD && !defined GNULIB_REGEX_SINGLE_THREAD\n# include <pthread.h>\n# define lock_define(name) pthread_mutex_t name;\n# define lock_init(lock) pthread_mutex_init (&(lock), 0)\n# define lock_fini(lock) pthread_mutex_destroy (&(lock))\n# define lock_lock(lock) pthread_mutex_lock (&(lock))\n# define lock_unlock(lock) pthread_mutex_unlock (&(lock))\n#else\n# define lock_define(name)\n# define lock_init(lock) 0\n# define lock_fini(lock) ((void) 0)\n  /* The 'dfa' avoids an \"unused variable 'dfa'\" warning from GCC.  */\n# define lock_lock(lock) ((void) dfa)\n# define lock_unlock(lock) ((void) 0)\n#endif\n\n/* In case that the system doesn't have isblank().  */\n#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))\n# define isblank(ch) ((ch) == ' ' || (ch) == '\\t')\n#endif\n\n/* regex code assumes isascii has its usual numeric meaning,\n   even if the portable character set uses EBCDIC encoding,\n   and even if wint_t is wider than int.  */\n#ifndef _LIBC\n# undef isascii\n# define isascii(c) (((c) & ~0x7f) == 0)\n#endif\n\n#ifdef _LIBC\n# ifndef _RE_DEFINE_LOCALE_FUNCTIONS\n#  define _RE_DEFINE_LOCALE_FUNCTIONS 1\n#   include <locale/localeinfo.h>\n#   include <locale/coll-lookup.h>\n# endif\n#endif\n\n/* This is for other GNU distributions with internationalized messages.  */\n#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC\n# include <libintl.h>\n# ifdef _LIBC\n#  undef gettext\n#  define gettext(msgid) \\\n  __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES)\n# endif\n#else\n# undef gettext\n# define gettext(msgid) (msgid)\n#endif\n\n#ifndef gettext_noop\n/* This define is so xgettext can find the internationalizable\n   strings.  */\n# define gettext_noop(String) String\n#endif\n\n#if (defined MB_CUR_MAX && HAVE_WCTYPE_H && HAVE_ISWCTYPE) || _LIBC\n# define RE_ENABLE_I18N\n#endif\n\n/* Number of ASCII characters.  */\n#define ASCII_CHARS 0x80\n\n/* Number of single byte characters.  */\n#define SBC_MAX (UCHAR_MAX + 1)\n\n#define COLL_ELEM_LEN_MAX 8\n\n/* The character which represents newline.  */\n#define NEWLINE_CHAR '\\n'\n#define WIDE_NEWLINE_CHAR L'\\n'\n\n/* Rename to standard API for using out of glibc.  */\n#ifndef _LIBC\n# undef __wctype\n# undef __iswalnum\n# undef __iswctype\n# undef __towlower\n# undef __towupper\n# define __wctype wctype\n# define __iswalnum iswalnum\n# define __iswctype iswctype\n# define __towlower towlower\n# define __towupper towupper\n# define __btowc btowc\n# define __mbrtowc mbrtowc\n# define __wcrtomb wcrtomb\n# define __regfree regfree\n#endif /* not _LIBC */\n\n#ifndef SSIZE_MAX\n# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))\n#endif\n#ifndef ULONG_WIDTH\n# define ULONG_WIDTH REGEX_UINTEGER_WIDTH (ULONG_MAX)\n/* The number of usable bits in an unsigned integer type with maximum\n   value MAX, as an int expression suitable in #if.  Cover all known\n   practical hosts.  This implementation exploits the fact that MAX is\n   1 less than a power of 2, and merely counts the number of 1 bits in\n   MAX; \"COBn\" means \"count the number of 1 bits in the low-order n bits\".  */\n# define REGEX_UINTEGER_WIDTH(max) REGEX_COB128 (max)\n# define REGEX_COB128(n) (REGEX_COB64 ((n) >> 31 >> 31 >> 2) + REGEX_COB64 (n))\n# define REGEX_COB64(n) (REGEX_COB32 ((n) >> 31 >> 1) + REGEX_COB32 (n))\n# define REGEX_COB32(n) (REGEX_COB16 ((n) >> 16) + REGEX_COB16 (n))\n# define REGEX_COB16(n) (REGEX_COB8 ((n) >> 8) + REGEX_COB8 (n))\n# define REGEX_COB8(n) (REGEX_COB4 ((n) >> 4) + REGEX_COB4 (n))\n# define REGEX_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + ((n) & 1))\n# if ULONG_MAX / 2 + 1 != 1ul << (ULONG_WIDTH - 1)\n#  error \"ULONG_MAX out of range\"\n# endif\n#endif\n\n/* The type of indexes into strings.  This is signed, not size_t,\n   since the API requires indexes to fit in regoff_t anyway, and using\n   signed integers makes the code a bit smaller and presumably faster.\n   The traditional GNU regex implementation uses int for indexes.\n   The POSIX-compatible implementation uses a possibly-wider type.\n   The name 'Idx' is three letters to minimize the hassle of\n   reindenting a lot of regex code that formerly used 'int'.  */\ntypedef regoff_t Idx;\n#ifdef _REGEX_LARGE_OFFSETS\n# define IDX_MAX SSIZE_MAX\n#else\n# define IDX_MAX INT_MAX\n#endif\n\n/* A hash value, suitable for computing hash tables.  */\ntypedef __re_size_t re_hashval_t;\n\n/* An integer used to represent a set of bits.  It must be unsigned,\n   and must be at least as wide as unsigned int.  */\ntypedef unsigned long int bitset_word_t;\n/* All bits set in a bitset_word_t.  */\n#define BITSET_WORD_MAX ULONG_MAX\n/* Number of bits in a bitset_word_t.  */\n#define BITSET_WORD_BITS ULONG_WIDTH\n\n/* Number of bitset_word_t values in a bitset_t.  */\n#define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)\n\ntypedef bitset_word_t bitset_t[BITSET_WORDS];\ntypedef bitset_word_t *re_bitset_ptr_t;\ntypedef const bitset_word_t *re_const_bitset_ptr_t;\n\n#define PREV_WORD_CONSTRAINT 0x0001\n#define PREV_NOTWORD_CONSTRAINT 0x0002\n#define NEXT_WORD_CONSTRAINT 0x0004\n#define NEXT_NOTWORD_CONSTRAINT 0x0008\n#define PREV_NEWLINE_CONSTRAINT 0x0010\n#define NEXT_NEWLINE_CONSTRAINT 0x0020\n#define PREV_BEGBUF_CONSTRAINT 0x0040\n#define NEXT_ENDBUF_CONSTRAINT 0x0080\n#define WORD_DELIM_CONSTRAINT 0x0100\n#define NOT_WORD_DELIM_CONSTRAINT 0x0200\n\ntypedef enum\n{\n  INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,\n  WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,\n  WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,\n  INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,\n  LINE_FIRST = PREV_NEWLINE_CONSTRAINT,\n  LINE_LAST = NEXT_NEWLINE_CONSTRAINT,\n  BUF_FIRST = PREV_BEGBUF_CONSTRAINT,\n  BUF_LAST = NEXT_ENDBUF_CONSTRAINT,\n  WORD_DELIM = WORD_DELIM_CONSTRAINT,\n  NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT\n} re_context_type;\n\ntypedef struct\n{\n  Idx alloc;\n  Idx nelem;\n  Idx *elems;\n} re_node_set;\n\ntypedef enum\n{\n  NON_TYPE = 0,\n\n  /* Node type, These are used by token, node, tree.  */\n  CHARACTER = 1,\n  END_OF_RE = 2,\n  SIMPLE_BRACKET = 3,\n  OP_BACK_REF = 4,\n  OP_PERIOD = 5,\n#ifdef RE_ENABLE_I18N\n  COMPLEX_BRACKET = 6,\n  OP_UTF8_PERIOD = 7,\n#endif /* RE_ENABLE_I18N */\n\n  /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used\n     when the debugger shows values of this enum type.  */\n#define EPSILON_BIT 8\n  OP_OPEN_SUBEXP = EPSILON_BIT | 0,\n  OP_CLOSE_SUBEXP = EPSILON_BIT | 1,\n  OP_ALT = EPSILON_BIT | 2,\n  OP_DUP_ASTERISK = EPSILON_BIT | 3,\n  ANCHOR = EPSILON_BIT | 4,\n\n  /* Tree type, these are used only by tree. */\n  CONCAT = 16,\n  SUBEXP = 17,\n\n  /* Token type, these are used only by token.  */\n  OP_DUP_PLUS = 18,\n  OP_DUP_QUESTION,\n  OP_OPEN_BRACKET,\n  OP_CLOSE_BRACKET,\n  OP_CHARSET_RANGE,\n  OP_OPEN_DUP_NUM,\n  OP_CLOSE_DUP_NUM,\n  OP_NON_MATCH_LIST,\n  OP_OPEN_COLL_ELEM,\n  OP_CLOSE_COLL_ELEM,\n  OP_OPEN_EQUIV_CLASS,\n  OP_CLOSE_EQUIV_CLASS,\n  OP_OPEN_CHAR_CLASS,\n  OP_CLOSE_CHAR_CLASS,\n  OP_WORD,\n  OP_NOTWORD,\n  OP_SPACE,\n  OP_NOTSPACE,\n  BACK_SLASH\n\n} re_token_type_t;\n\n#ifdef RE_ENABLE_I18N\ntypedef struct\n{\n  /* Multibyte characters.  */\n  wchar_t *mbchars;\n\n  /* Collating symbols.  */\n# ifdef _LIBC\n  int32_t *coll_syms;\n# endif\n\n  /* Equivalence classes. */\n# ifdef _LIBC\n  int32_t *equiv_classes;\n# endif\n\n  /* Range expressions. */\n# ifdef _LIBC\n  uint32_t *range_starts;\n  uint32_t *range_ends;\n# else /* not _LIBC */\n  wchar_t *range_starts;\n  wchar_t *range_ends;\n# endif /* not _LIBC */\n\n  /* Character classes. */\n  wctype_t *char_classes;\n\n  /* If this character set is the non-matching list.  */\n  unsigned int non_match : 1;\n\n  /* # of multibyte characters.  */\n  Idx nmbchars;\n\n  /* # of collating symbols.  */\n  Idx ncoll_syms;\n\n  /* # of equivalence classes. */\n  Idx nequiv_classes;\n\n  /* # of range expressions. */\n  Idx nranges;\n\n  /* # of character classes. */\n  Idx nchar_classes;\n} re_charset_t;\n#endif /* RE_ENABLE_I18N */\n\ntypedef struct\n{\n  union\n  {\n    unsigned char c;\t\t/* for CHARACTER */\n    re_bitset_ptr_t sbcset;\t/* for SIMPLE_BRACKET */\n#ifdef RE_ENABLE_I18N\n    re_charset_t *mbcset;\t/* for COMPLEX_BRACKET */\n#endif /* RE_ENABLE_I18N */\n    Idx idx;\t\t\t/* for BACK_REF */\n    re_context_type ctx_type;\t/* for ANCHOR */\n  } opr;\n#if (__GNUC__ >= 2 || defined __clang__) && !defined __STRICT_ANSI__\n  re_token_type_t type : 8;\n#else\n  re_token_type_t type;\n#endif\n  unsigned int constraint : 10;\t/* context constraint */\n  unsigned int duplicated : 1;\n  unsigned int opt_subexp : 1;\n#ifdef RE_ENABLE_I18N\n  unsigned int accept_mb : 1;\n  /* These 2 bits can be moved into the union if needed (e.g. if running out\n     of bits; move opr.c to opr.c.c and move the flags to opr.c.flags).  */\n  unsigned int mb_partial : 1;\n#endif\n  unsigned int word_char : 1;\n} re_token_t;\n\n#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT)\n\nstruct re_string_t\n{\n  /* Indicate the raw buffer which is the original string passed as an\n     argument of regexec(), re_search(), etc..  */\n  const unsigned char *raw_mbs;\n  /* Store the multibyte string.  In case of \"case insensitive mode\" like\n     REG_ICASE, upper cases of the string are stored, otherwise MBS points\n     the same address that RAW_MBS points.  */\n  unsigned char *mbs;\n#ifdef RE_ENABLE_I18N\n  /* Store the wide character string which is corresponding to MBS.  */\n  wint_t *wcs;\n  Idx *offsets;\n  mbstate_t cur_state;\n#endif\n  /* Index in RAW_MBS.  Each character mbs[i] corresponds to\n     raw_mbs[raw_mbs_idx + i].  */\n  Idx raw_mbs_idx;\n  /* The length of the valid characters in the buffers.  */\n  Idx valid_len;\n  /* The corresponding number of bytes in raw_mbs array.  */\n  Idx valid_raw_len;\n  /* The length of the buffers MBS and WCS.  */\n  Idx bufs_len;\n  /* The index in MBS, which is updated by re_string_fetch_byte.  */\n  Idx cur_idx;\n  /* length of RAW_MBS array.  */\n  Idx raw_len;\n  /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN.  */\n  Idx len;\n  /* End of the buffer may be shorter than its length in the cases such\n     as re_match_2, re_search_2.  Then, we use STOP for end of the buffer\n     instead of LEN.  */\n  Idx raw_stop;\n  /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS.  */\n  Idx stop;\n\n  /* The context of mbs[0].  We store the context independently, since\n     the context of mbs[0] may be different from raw_mbs[0], which is\n     the beginning of the input string.  */\n  unsigned int tip_context;\n  /* The translation passed as a part of an argument of re_compile_pattern.  */\n  RE_TRANSLATE_TYPE trans;\n  /* Copy of re_dfa_t's word_char.  */\n  re_const_bitset_ptr_t word_char;\n  /* true if REG_ICASE.  */\n  unsigned char icase;\n  unsigned char is_utf8;\n  unsigned char map_notascii;\n  unsigned char mbs_allocated;\n  unsigned char offsets_needed;\n  unsigned char newline_anchor;\n  unsigned char word_ops_used;\n  int mb_cur_max;\n};\ntypedef struct re_string_t re_string_t;\n\n\nstruct re_dfa_t;\ntypedef struct re_dfa_t re_dfa_t;\n\n#ifndef _LIBC\n# define IS_IN(libc) false\n#endif\n\n#define re_string_peek_byte(pstr, offset) \\\n  ((pstr)->mbs[(pstr)->cur_idx + offset])\n#define re_string_fetch_byte(pstr) \\\n  ((pstr)->mbs[(pstr)->cur_idx++])\n#define re_string_first_byte(pstr, idx) \\\n  ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF)\n#define re_string_is_single_byte_char(pstr, idx) \\\n  ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \\\n\t\t\t\t|| (pstr)->wcs[(idx) + 1] != WEOF))\n#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx)\n#define re_string_cur_idx(pstr) ((pstr)->cur_idx)\n#define re_string_get_buffer(pstr) ((pstr)->mbs)\n#define re_string_length(pstr) ((pstr)->len)\n#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx])\n#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))\n#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))\n\n#ifdef _LIBC\n# define MALLOC_0_IS_NONNULL 1\n#elif !defined MALLOC_0_IS_NONNULL\n# define MALLOC_0_IS_NONNULL 0\n#endif\n\n#ifndef MAX\n# define MAX(a,b) ((a) < (b) ? (b) : (a))\n#endif\n#ifndef MIN\n# define MIN(a,b) ((a) < (b) ? (a) : (b))\n#endif\n\n#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))\n#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))\n#define re_free(p) free (p)\n\nstruct bin_tree_t\n{\n  struct bin_tree_t *parent;\n  struct bin_tree_t *left;\n  struct bin_tree_t *right;\n  struct bin_tree_t *first;\n  struct bin_tree_t *next;\n\n  re_token_t token;\n\n  /* 'node_idx' is the index in dfa->nodes, if 'type' == 0.\n     Otherwise 'type' indicate the type of this node.  */\n  Idx node_idx;\n};\ntypedef struct bin_tree_t bin_tree_t;\n\n#define BIN_TREE_STORAGE_SIZE \\\n  ((1024 - sizeof (void *)) / sizeof (bin_tree_t))\n\nstruct bin_tree_storage_t\n{\n  struct bin_tree_storage_t *next;\n  bin_tree_t data[BIN_TREE_STORAGE_SIZE];\n};\ntypedef struct bin_tree_storage_t bin_tree_storage_t;\n\n#define CONTEXT_WORD 1\n#define CONTEXT_NEWLINE (CONTEXT_WORD << 1)\n#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1)\n#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1)\n\n#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD)\n#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE)\n#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF)\n#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF)\n#define IS_ORDINARY_CONTEXT(c) ((c) == 0)\n\n#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_')\n#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR)\n#define IS_WIDE_WORD_CHAR(ch) (__iswalnum (ch) || (ch) == L'_')\n#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR)\n\n#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \\\n ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \\\n  || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \\\n  || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\\\n  || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context)))\n\n#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \\\n ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \\\n  || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \\\n  || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \\\n  || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context)))\n\nstruct re_dfastate_t\n{\n  re_hashval_t hash;\n  re_node_set nodes;\n  re_node_set non_eps_nodes;\n  re_node_set inveclosure;\n  re_node_set *entrance_nodes;\n  struct re_dfastate_t **trtable, **word_trtable;\n  unsigned int context : 4;\n  unsigned int halt : 1;\n  /* If this state can accept \"multi byte\".\n     Note that we refer to multibyte characters, and multi character\n     collating elements as \"multi byte\".  */\n  unsigned int accept_mb : 1;\n  /* If this state has backreference node(s).  */\n  unsigned int has_backref : 1;\n  unsigned int has_constraint : 1;\n};\ntypedef struct re_dfastate_t re_dfastate_t;\n\nstruct re_state_table_entry\n{\n  Idx num;\n  Idx alloc;\n  re_dfastate_t **array;\n};\n\n/* Array type used in re_sub_match_last_t and re_sub_match_top_t.  */\n\ntypedef struct\n{\n  Idx next_idx;\n  Idx alloc;\n  re_dfastate_t **array;\n} state_array_t;\n\n/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP.  */\n\ntypedef struct\n{\n  Idx node;\n  Idx str_idx; /* The position NODE match at.  */\n  state_array_t path;\n} re_sub_match_last_t;\n\n/* Store information about the node NODE whose type is OP_OPEN_SUBEXP.\n   And information about the node, whose type is OP_CLOSE_SUBEXP,\n   corresponding to NODE is stored in LASTS.  */\n\ntypedef struct\n{\n  Idx str_idx;\n  Idx node;\n  state_array_t *path;\n  Idx alasts; /* Allocation size of LASTS.  */\n  Idx nlasts; /* The number of LASTS.  */\n  re_sub_match_last_t **lasts;\n} re_sub_match_top_t;\n\nstruct re_backref_cache_entry\n{\n  Idx node;\n  Idx str_idx;\n  Idx subexp_from;\n  Idx subexp_to;\n  bitset_word_t eps_reachable_subexps_map;\n  char more;\n};\n\ntypedef struct\n{\n  /* The string object corresponding to the input string.  */\n  re_string_t input;\n  const re_dfa_t *const dfa;\n  /* EFLAGS of the argument of regexec.  */\n  int eflags;\n  /* Where the matching ends.  */\n  Idx match_last;\n  Idx last_node;\n  /* The state log used by the matcher.  */\n  re_dfastate_t **state_log;\n  Idx state_log_top;\n  /* Back reference cache.  */\n  Idx nbkref_ents;\n  Idx abkref_ents;\n  struct re_backref_cache_entry *bkref_ents;\n  int max_mb_elem_len;\n  Idx nsub_tops;\n  Idx asub_tops;\n  re_sub_match_top_t **sub_tops;\n} re_match_context_t;\n\ntypedef struct\n{\n  re_dfastate_t **sifted_states;\n  re_dfastate_t **limited_states;\n  Idx last_node;\n  Idx last_str_idx;\n  re_node_set limits;\n} re_sift_context_t;\n\nstruct re_fail_stack_ent_t\n{\n  Idx idx;\n  Idx node;\n  regmatch_t *regs;\n  re_node_set eps_via_nodes;\n};\n\nstruct re_fail_stack_t\n{\n  Idx num;\n  Idx alloc;\n  struct re_fail_stack_ent_t *stack;\n};\n\nstruct re_dfa_t\n{\n  re_token_t *nodes;\n  size_t nodes_alloc;\n  size_t nodes_len;\n  Idx *nexts;\n  Idx *org_indices;\n  re_node_set *edests;\n  re_node_set *eclosures;\n  re_node_set *inveclosures;\n  struct re_state_table_entry *state_table;\n  re_dfastate_t *init_state;\n  re_dfastate_t *init_state_word;\n  re_dfastate_t *init_state_nl;\n  re_dfastate_t *init_state_begbuf;\n  bin_tree_t *str_tree;\n  bin_tree_storage_t *str_tree_storage;\n  re_bitset_ptr_t sb_char;\n  int str_tree_storage_idx;\n\n  /* number of subexpressions 're_nsub' is in regex_t.  */\n  re_hashval_t state_hash_mask;\n  Idx init_node;\n  Idx nbackref; /* The number of backreference in this dfa.  */\n\n  /* Bitmap expressing which backreference is used.  */\n  bitset_word_t used_bkref_map;\n  bitset_word_t completed_bkref_map;\n\n  unsigned int has_plural_match : 1;\n  /* If this dfa has \"multibyte node\", which is a backreference or\n     a node which can accept multibyte character or multi character\n     collating element.  */\n  unsigned int has_mb_node : 1;\n  unsigned int is_utf8 : 1;\n  unsigned int map_notascii : 1;\n  unsigned int word_ops_used : 1;\n  int mb_cur_max;\n  bitset_t word_char;\n  reg_syntax_t syntax;\n  Idx *subexp_map;\n#ifdef DEBUG\n  char* re_str;\n#endif\n  lock_define (lock)\n};\n\n#define re_node_set_init_empty(set) memset (set, '\\0', sizeof (re_node_set))\n#define re_node_set_remove(set,id) \\\n  (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))\n#define re_node_set_empty(p) ((p)->nelem = 0)\n#define re_node_set_free(set) re_free ((set)->elems)\n\f\n\ntypedef enum\n{\n  SB_CHAR,\n  MB_CHAR,\n  EQUIV_CLASS,\n  COLL_SYM,\n  CHAR_CLASS\n} bracket_elem_type;\n\ntypedef struct\n{\n  bracket_elem_type type;\n  union\n  {\n    unsigned char ch;\n    unsigned char *name;\n    wchar_t wch;\n  } opr;\n} bracket_elem_t;\n\n\n/* Functions for bitset_t operation.  */\n\nstatic inline void\nbitset_set (bitset_t set, Idx i)\n{\n  set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS;\n}\n\nstatic inline void\nbitset_clear (bitset_t set, Idx i)\n{\n  set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS);\n}\n\nstatic inline bool\nbitset_contain (const bitset_t set, Idx i)\n{\n  return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1;\n}\n\nstatic inline void\nbitset_empty (bitset_t set)\n{\n  memset (set, '\\0', sizeof (bitset_t));\n}\n\nstatic inline void\nbitset_set_all (bitset_t set)\n{\n  memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS));\n  if (SBC_MAX % BITSET_WORD_BITS != 0)\n    set[BITSET_WORDS - 1] =\n      ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1;\n}\n\nstatic inline void\nbitset_copy (bitset_t dest, const bitset_t src)\n{\n  memcpy (dest, src, sizeof (bitset_t));\n}\n\nstatic inline void\nbitset_not (bitset_t set)\n{\n  int bitset_i;\n  for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i)\n    set[bitset_i] = ~set[bitset_i];\n  if (SBC_MAX % BITSET_WORD_BITS != 0)\n    set[BITSET_WORDS - 1] =\n      ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1)\n       & ~set[BITSET_WORDS - 1]);\n}\n\nstatic inline void\nbitset_merge (bitset_t dest, const bitset_t src)\n{\n  int bitset_i;\n  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)\n    dest[bitset_i] |= src[bitset_i];\n}\n\nstatic inline void\nbitset_mask (bitset_t dest, const bitset_t src)\n{\n  int bitset_i;\n  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)\n    dest[bitset_i] &= src[bitset_i];\n}\n\n#ifdef RE_ENABLE_I18N\n/* Functions for re_string.  */\nstatic int\n__attribute__ ((pure, unused))\nre_string_char_size_at (const re_string_t *pstr, Idx idx)\n{\n  int byte_idx;\n  if (pstr->mb_cur_max == 1)\n    return 1;\n  for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)\n    if (pstr->wcs[idx + byte_idx] != WEOF)\n      break;\n  return byte_idx;\n}\n\nstatic wint_t\n__attribute__ ((pure, unused))\nre_string_wchar_at (const re_string_t *pstr, Idx idx)\n{\n  if (pstr->mb_cur_max == 1)\n    return (wint_t) pstr->mbs[idx];\n  return (wint_t) pstr->wcs[idx];\n}\n\n# ifdef _LIBC\n#  include <locale/weight.h>\n# endif\n\nstatic int\n__attribute__ ((pure, unused))\nre_string_elem_size_at (const re_string_t *pstr, Idx idx)\n{\n# ifdef _LIBC\n  const unsigned char *p, *extra;\n  const int32_t *table, *indirect;\n  uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);\n\n  if (nrules != 0)\n    {\n      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);\n      extra = (const unsigned char *)\n\t_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);\n      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,\n\t\t\t\t\t\t_NL_COLLATE_INDIRECTMB);\n      p = pstr->mbs + idx;\n      findidx (table, indirect, extra, &p, pstr->len - idx);\n      return p - pstr->mbs - idx;\n    }\n  else\n# endif /* _LIBC */\n    return 1;\n}\n#endif /* RE_ENABLE_I18N */\n\n#ifdef _LIBC\n# if __GNUC__ >= 7\n#  define FALLTHROUGH __attribute__ ((__fallthrough__))\n# else\n#  define FALLTHROUGH ((void) 0)\n# endif\n#else\n# include \"attribute.h\"\n#endif\n\n#endif /*  _REGEX_INTERNAL_H */\n"
  },
  {
    "path": "gnulib/regexec.c",
    "content": "/* Extended regular expression matching and search library.\n   Copyright (C) 2002-2021 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\nstatic reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,\n\t\t\t\t     Idx n);\nstatic void match_ctx_clean (re_match_context_t *mctx);\nstatic void match_ctx_free (re_match_context_t *cache);\nstatic reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, Idx node,\n\t\t\t\t\t  Idx str_idx, Idx from, Idx to);\nstatic Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx);\nstatic reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, Idx node,\n\t\t\t\t\t   Idx str_idx);\nstatic re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,\n\t\t\t\t\t\t    Idx node, Idx str_idx);\nstatic void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,\n\t\t\t   re_dfastate_t **limited_sts, Idx last_node,\n\t\t\t   Idx last_str_idx);\nstatic reg_errcode_t re_search_internal (const regex_t *preg,\n\t\t\t\t\t const char *string, Idx length,\n\t\t\t\t\t Idx start, Idx last_start, Idx stop,\n\t\t\t\t\t size_t nmatch, regmatch_t pmatch[],\n\t\t\t\t\t int eflags);\nstatic regoff_t re_search_2_stub (struct re_pattern_buffer *bufp,\n\t\t\t\t  const char *string1, Idx length1,\n\t\t\t\t  const char *string2, Idx length2,\n\t\t\t\t  Idx start, regoff_t range,\n\t\t\t\t  struct re_registers *regs,\n\t\t\t\t  Idx stop, bool ret_len);\nstatic regoff_t re_search_stub (struct re_pattern_buffer *bufp,\n\t\t\t\tconst char *string, Idx length, Idx start,\n\t\t\t\tregoff_t range, Idx stop,\n\t\t\t\tstruct re_registers *regs,\n\t\t\t\tbool ret_len);\nstatic unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch,\n                              Idx nregs, int regs_allocated);\nstatic reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx);\nstatic Idx check_matching (re_match_context_t *mctx, bool fl_longest_match,\n\t\t\t   Idx *p_match_first);\nstatic Idx check_halt_state_context (const re_match_context_t *mctx,\n\t\t\t\t     const re_dfastate_t *state, Idx idx);\nstatic void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,\n\t\t\t regmatch_t *prev_idx_match, Idx cur_node,\n\t\t\t Idx cur_idx, Idx nmatch);\nstatic reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,\n\t\t\t\t      Idx str_idx, Idx dest_node, Idx nregs,\n\t\t\t\t      regmatch_t *regs, regmatch_t *prevregs,\n\t\t\t\t      re_node_set *eps_via_nodes);\nstatic reg_errcode_t set_regs (const regex_t *preg,\n\t\t\t       const re_match_context_t *mctx,\n\t\t\t       size_t nmatch, regmatch_t *pmatch,\n\t\t\t       bool fl_backtrack);\nstatic reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs);\n\n#ifdef RE_ENABLE_I18N\nstatic int sift_states_iter_mb (const re_match_context_t *mctx,\n\t\t\t\tre_sift_context_t *sctx,\n\t\t\t\tIdx node_idx, Idx str_idx, Idx max_str_idx);\n#endif /* RE_ENABLE_I18N */\nstatic reg_errcode_t sift_states_backward (const re_match_context_t *mctx,\n\t\t\t\t\t   re_sift_context_t *sctx);\nstatic reg_errcode_t build_sifted_states (const re_match_context_t *mctx,\n\t\t\t\t\t  re_sift_context_t *sctx, Idx str_idx,\n\t\t\t\t\t  re_node_set *cur_dest);\nstatic reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx,\n\t\t\t\t\t      re_sift_context_t *sctx,\n\t\t\t\t\t      Idx str_idx,\n\t\t\t\t\t      re_node_set *dest_nodes);\nstatic reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa,\n\t\t\t\t\t    re_node_set *dest_nodes,\n\t\t\t\t\t    const re_node_set *candidates);\nstatic bool check_dst_limits (const re_match_context_t *mctx,\n\t\t\t      const re_node_set *limits,\n\t\t\t      Idx dst_node, Idx dst_idx, Idx src_node,\n\t\t\t      Idx src_idx);\nstatic int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx,\n\t\t\t\t\tint boundaries, Idx subexp_idx,\n\t\t\t\t\tIdx from_node, Idx bkref_idx);\nstatic int check_dst_limits_calc_pos (const re_match_context_t *mctx,\n\t\t\t\t      Idx limit, Idx subexp_idx,\n\t\t\t\t      Idx node, Idx str_idx,\n\t\t\t\t      Idx bkref_idx);\nstatic reg_errcode_t check_subexp_limits (const re_dfa_t *dfa,\n\t\t\t\t\t  re_node_set *dest_nodes,\n\t\t\t\t\t  const re_node_set *candidates,\n\t\t\t\t\t  re_node_set *limits,\n\t\t\t\t\t  struct re_backref_cache_entry *bkref_ents,\n\t\t\t\t\t  Idx str_idx);\nstatic reg_errcode_t sift_states_bkref (const re_match_context_t *mctx,\n\t\t\t\t\tre_sift_context_t *sctx,\n\t\t\t\t\tIdx str_idx, const re_node_set *candidates);\nstatic reg_errcode_t merge_state_array (const re_dfa_t *dfa,\n\t\t\t\t\tre_dfastate_t **dst,\n\t\t\t\t\tre_dfastate_t **src, Idx num);\nstatic re_dfastate_t *find_recover_state (reg_errcode_t *err,\n\t\t\t\t\t re_match_context_t *mctx);\nstatic re_dfastate_t *transit_state (reg_errcode_t *err,\n\t\t\t\t     re_match_context_t *mctx,\n\t\t\t\t     re_dfastate_t *state);\nstatic re_dfastate_t *merge_state_with_log (reg_errcode_t *err,\n\t\t\t\t\t    re_match_context_t *mctx,\n\t\t\t\t\t    re_dfastate_t *next_state);\nstatic reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx,\n\t\t\t\t\t\tre_node_set *cur_nodes,\n\t\t\t\t\t\tIdx str_idx);\n#if 0\nstatic re_dfastate_t *transit_state_sb (reg_errcode_t *err,\n\t\t\t\t\tre_match_context_t *mctx,\n\t\t\t\t\tre_dfastate_t *pstate);\n#endif\n#ifdef RE_ENABLE_I18N\nstatic reg_errcode_t transit_state_mb (re_match_context_t *mctx,\n\t\t\t\t       re_dfastate_t *pstate);\n#endif /* RE_ENABLE_I18N */\nstatic reg_errcode_t transit_state_bkref (re_match_context_t *mctx,\n\t\t\t\t\t  const re_node_set *nodes);\nstatic reg_errcode_t get_subexp (re_match_context_t *mctx,\n\t\t\t\t Idx bkref_node, Idx bkref_str_idx);\nstatic reg_errcode_t get_subexp_sub (re_match_context_t *mctx,\n\t\t\t\t     const re_sub_match_top_t *sub_top,\n\t\t\t\t     re_sub_match_last_t *sub_last,\n\t\t\t\t     Idx bkref_node, Idx bkref_str);\nstatic Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,\n\t\t\t     Idx subexp_idx, int type);\nstatic reg_errcode_t check_arrival (re_match_context_t *mctx,\n\t\t\t\t    state_array_t *path, Idx top_node,\n\t\t\t\t    Idx top_str, Idx last_node, Idx last_str,\n\t\t\t\t    int type);\nstatic reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx,\n\t\t\t\t\t\t   Idx str_idx,\n\t\t\t\t\t\t   re_node_set *cur_nodes,\n\t\t\t\t\t\t   re_node_set *next_nodes);\nstatic reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa,\n\t\t\t\t\t       re_node_set *cur_nodes,\n\t\t\t\t\t       Idx ex_subexp, int type);\nstatic reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa,\n\t\t\t\t\t\t   re_node_set *dst_nodes,\n\t\t\t\t\t\t   Idx target, Idx ex_subexp,\n\t\t\t\t\t\t   int type);\nstatic reg_errcode_t expand_bkref_cache (re_match_context_t *mctx,\n\t\t\t\t\t re_node_set *cur_nodes, Idx cur_str,\n\t\t\t\t\t Idx subexp_num, int type);\nstatic bool build_trtable (const re_dfa_t *dfa, re_dfastate_t *state);\n#ifdef RE_ENABLE_I18N\nstatic int check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,\n\t\t\t\t    const re_string_t *input, Idx idx);\n# ifdef _LIBC\nstatic unsigned int find_collation_sequence_value (const unsigned char *mbs,\n\t\t\t\t\t\t   size_t name_len);\n# endif /* _LIBC */\n#endif /* RE_ENABLE_I18N */\nstatic Idx group_nodes_into_DFAstates (const re_dfa_t *dfa,\n\t\t\t\t       const re_dfastate_t *state,\n\t\t\t\t       re_node_set *states_node,\n\t\t\t\t       bitset_t *states_ch);\nstatic bool check_node_accept (const re_match_context_t *mctx,\n\t\t\t       const re_token_t *node, Idx idx);\nstatic reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len);\n\f\n/* Entry point for POSIX code.  */\n\n/* regexec searches for a given pattern, specified by PREG, in the\n   string STRING.\n\n   If NMATCH is zero or REG_NOSUB was set in the cflags argument to\n   'regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at\n   least NMATCH elements, and we set them to the offsets of the\n   corresponding matched substrings.\n\n   EFLAGS specifies \"execution flags\" which affect matching: if\n   REG_NOTBOL is set, then ^ does not match at the beginning of the\n   string; if REG_NOTEOL is set, then $ does not match at the end.\n\n   Return 0 if a match is found, REG_NOMATCH if not, REG_BADPAT if\n   EFLAGS is invalid.  */\n\nint\nregexec (const regex_t *__restrict preg, const char *__restrict string,\n\t size_t nmatch, regmatch_t pmatch[], int eflags)\n{\n  reg_errcode_t err;\n  Idx start, length;\n  re_dfa_t *dfa = preg->buffer;\n\n  if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))\n    return REG_BADPAT;\n\n  if (eflags & REG_STARTEND)\n    {\n      start = pmatch[0].rm_so;\n      length = pmatch[0].rm_eo;\n    }\n  else\n    {\n      start = 0;\n      length = strlen (string);\n    }\n\n  lock_lock (dfa->lock);\n  if (preg->no_sub)\n    err = re_search_internal (preg, string, length, start, length,\n\t\t\t      length, 0, NULL, eflags);\n  else\n    err = re_search_internal (preg, string, length, start, length,\n\t\t\t      length, nmatch, pmatch, eflags);\n  lock_unlock (dfa->lock);\n  return err != REG_NOERROR;\n}\n\n#ifdef _LIBC\nlibc_hidden_def (__regexec)\n\n# include <shlib-compat.h>\nversioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);\n\n# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)\n__typeof__ (__regexec) __compat_regexec;\n\nint\nattribute_compat_text_section\n__compat_regexec (const regex_t *__restrict preg,\n\t\t  const char *__restrict string, size_t nmatch,\n\t\t  regmatch_t pmatch[], int eflags)\n{\n  return regexec (preg, string, nmatch, pmatch,\n\t\t  eflags & (REG_NOTBOL | REG_NOTEOL));\n}\ncompat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);\n# endif\n#endif\n\n/* Entry points for GNU code.  */\n\n/* re_match, re_search, re_match_2, re_search_2\n\n   The former two functions operate on STRING with length LENGTH,\n   while the later two operate on concatenation of STRING1 and STRING2\n   with lengths LENGTH1 and LENGTH2, respectively.\n\n   re_match() matches the compiled pattern in BUFP against the string,\n   starting at index START.\n\n   re_search() first tries matching at index START, then it tries to match\n   starting from index START + 1, and so on.  The last start position tried\n   is START + RANGE.  (Thus RANGE = 0 forces re_search to operate the same\n   way as re_match().)\n\n   The parameter STOP of re_{match,search}_2 specifies that no match exceeding\n   the first STOP characters of the concatenation of the strings should be\n   concerned.\n\n   If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match\n   and all groups is stored in REGS.  (For the \"_2\" variants, the offsets are\n   computed relative to the concatenation, not relative to the individual\n   strings.)\n\n   On success, re_match* functions return the length of the match, re_search*\n   return the position of the start of the match.  They return -1 on\n   match failure, -2 on error.  */\n\nregoff_t\nre_match (struct re_pattern_buffer *bufp, const char *string, Idx length,\n\t  Idx start, struct re_registers *regs)\n{\n  return re_search_stub (bufp, string, length, start, 0, length, regs, true);\n}\n#ifdef _LIBC\nweak_alias (__re_match, re_match)\n#endif\n\nregoff_t\nre_search (struct re_pattern_buffer *bufp, const char *string, Idx length,\n\t   Idx start, regoff_t range, struct re_registers *regs)\n{\n  return re_search_stub (bufp, string, length, start, range, length, regs,\n\t\t\t false);\n}\n#ifdef _LIBC\nweak_alias (__re_search, re_search)\n#endif\n\nregoff_t\nre_match_2 (struct re_pattern_buffer *bufp, const char *string1, Idx length1,\n\t    const char *string2, Idx length2, Idx start,\n\t    struct re_registers *regs, Idx stop)\n{\n  return re_search_2_stub (bufp, string1, length1, string2, length2,\n\t\t\t   start, 0, regs, stop, true);\n}\n#ifdef _LIBC\nweak_alias (__re_match_2, re_match_2)\n#endif\n\nregoff_t\nre_search_2 (struct re_pattern_buffer *bufp, const char *string1, Idx length1,\n\t     const char *string2, Idx length2, Idx start, regoff_t range,\n\t     struct re_registers *regs, Idx stop)\n{\n  return re_search_2_stub (bufp, string1, length1, string2, length2,\n\t\t\t   start, range, regs, stop, false);\n}\n#ifdef _LIBC\nweak_alias (__re_search_2, re_search_2)\n#endif\n\nstatic regoff_t\nre_search_2_stub (struct re_pattern_buffer *bufp, const char *string1,\n\t\t  Idx length1, const char *string2, Idx length2, Idx start,\n\t\t  regoff_t range, struct re_registers *regs,\n\t\t  Idx stop, bool ret_len)\n{\n  const char *str;\n  regoff_t rval;\n  Idx len;\n  char *s = NULL;\n\n  if (__glibc_unlikely ((length1 < 0 || length2 < 0 || stop < 0\n\t\t\t || INT_ADD_WRAPV (length1, length2, &len))))\n    return -2;\n\n  /* Concatenate the strings.  */\n  if (length2 > 0)\n    if (length1 > 0)\n      {\n\ts = re_malloc (char, len);\n\n\tif (__glibc_unlikely (s == NULL))\n\t  return -2;\n#ifdef _LIBC\n\tmemcpy (__mempcpy (s, string1, length1), string2, length2);\n#else\n\tmemcpy (s, string1, length1);\n\tmemcpy (s + length1, string2, length2);\n#endif\n\tstr = s;\n      }\n    else\n      str = string2;\n  else\n    str = string1;\n\n  rval = re_search_stub (bufp, str, len, start, range, stop, regs,\n\t\t\t ret_len);\n  re_free (s);\n  return rval;\n}\n\n/* The parameters have the same meaning as those of re_search.\n   Additional parameters:\n   If RET_LEN is true the length of the match is returned (re_match style);\n   otherwise the position of the match is returned.  */\n\nstatic regoff_t\nre_search_stub (struct re_pattern_buffer *bufp, const char *string, Idx length,\n\t\tIdx start, regoff_t range, Idx stop, struct re_registers *regs,\n\t\tbool ret_len)\n{\n  reg_errcode_t result;\n  regmatch_t *pmatch;\n  Idx nregs;\n  regoff_t rval;\n  int eflags = 0;\n  re_dfa_t *dfa = bufp->buffer;\n  Idx last_start = start + range;\n\n  /* Check for out-of-range.  */\n  if (__glibc_unlikely (start < 0 || start > length))\n    return -1;\n  if (__glibc_unlikely (length < last_start\n\t\t\t|| (0 <= range && last_start < start)))\n    last_start = length;\n  else if (__glibc_unlikely (last_start < 0\n\t\t\t     || (range < 0 && start <= last_start)))\n    last_start = 0;\n\n  lock_lock (dfa->lock);\n\n  eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;\n  eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;\n\n  /* Compile fastmap if we haven't yet.  */\n  if (start < last_start && bufp->fastmap != NULL && !bufp->fastmap_accurate)\n    re_compile_fastmap (bufp);\n\n  if (__glibc_unlikely (bufp->no_sub))\n    regs = NULL;\n\n  /* We need at least 1 register.  */\n  if (regs == NULL)\n    nregs = 1;\n  else if (__glibc_unlikely (bufp->regs_allocated == REGS_FIXED\n\t\t\t     && regs->num_regs <= bufp->re_nsub))\n    {\n      nregs = regs->num_regs;\n      if (__glibc_unlikely (nregs < 1))\n\t{\n\t  /* Nothing can be copied to regs.  */\n\t  regs = NULL;\n\t  nregs = 1;\n\t}\n    }\n  else\n    nregs = bufp->re_nsub + 1;\n  pmatch = re_malloc (regmatch_t, nregs);\n  if (__glibc_unlikely (pmatch == NULL))\n    {\n      rval = -2;\n      goto out;\n    }\n\n  result = re_search_internal (bufp, string, length, start, last_start, stop,\n\t\t\t       nregs, pmatch, eflags);\n\n  rval = 0;\n\n  /* I hope we needn't fill their regs with -1's when no match was found.  */\n  if (result != REG_NOERROR)\n    rval = result == REG_NOMATCH ? -1 : -2;\n  else if (regs != NULL)\n    {\n      /* If caller wants register contents data back, copy them.  */\n      bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs,\n\t\t\t\t\t   bufp->regs_allocated);\n      if (__glibc_unlikely (bufp->regs_allocated == REGS_UNALLOCATED))\n\trval = -2;\n    }\n\n  if (__glibc_likely (rval == 0))\n    {\n      if (ret_len)\n\t{\n\t  DEBUG_ASSERT (pmatch[0].rm_so == start);\n\t  rval = pmatch[0].rm_eo - start;\n\t}\n      else\n\trval = pmatch[0].rm_so;\n    }\n  re_free (pmatch);\n out:\n  lock_unlock (dfa->lock);\n  return rval;\n}\n\nstatic unsigned\nre_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs,\n\t      int regs_allocated)\n{\n  int rval = REGS_REALLOCATE;\n  Idx i;\n  Idx need_regs = nregs + 1;\n  /* We need one extra element beyond 'num_regs' for the '-1' marker GNU code\n     uses.  */\n\n  /* Have the register data arrays been allocated?  */\n  if (regs_allocated == REGS_UNALLOCATED)\n    { /* No.  So allocate them with malloc.  */\n      regs->start = re_malloc (regoff_t, need_regs);\n      if (__glibc_unlikely (regs->start == NULL))\n\treturn REGS_UNALLOCATED;\n      regs->end = re_malloc (regoff_t, need_regs);\n      if (__glibc_unlikely (regs->end == NULL))\n\t{\n\t  re_free (regs->start);\n\t  return REGS_UNALLOCATED;\n\t}\n      regs->num_regs = need_regs;\n    }\n  else if (regs_allocated == REGS_REALLOCATE)\n    { /* Yes.  If we need more elements than were already\n\t allocated, reallocate them.  If we need fewer, just\n\t leave it alone.  */\n      if (__glibc_unlikely (need_regs > regs->num_regs))\n\t{\n\t  regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);\n\t  regoff_t *new_end;\n\t  if (__glibc_unlikely (new_start == NULL))\n\t    return REGS_UNALLOCATED;\n\t  new_end = re_realloc (regs->end, regoff_t, need_regs);\n\t  if (__glibc_unlikely (new_end == NULL))\n\t    {\n\t      re_free (new_start);\n\t      return REGS_UNALLOCATED;\n\t    }\n\t  regs->start = new_start;\n\t  regs->end = new_end;\n\t  regs->num_regs = need_regs;\n\t}\n    }\n  else\n    {\n      DEBUG_ASSERT (regs_allocated == REGS_FIXED);\n      /* This function may not be called with REGS_FIXED and nregs too big.  */\n      DEBUG_ASSERT (nregs <= regs->num_regs);\n      rval = REGS_FIXED;\n    }\n\n  /* Copy the regs.  */\n  for (i = 0; i < nregs; ++i)\n    {\n      regs->start[i] = pmatch[i].rm_so;\n      regs->end[i] = pmatch[i].rm_eo;\n    }\n  for ( ; i < regs->num_regs; ++i)\n    regs->start[i] = regs->end[i] = -1;\n\n  return rval;\n}\n\n/* Set REGS to hold NUM_REGS registers, storing them in STARTS and\n   ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use\n   this memory for recording register information.  STARTS and ENDS\n   must be allocated using the malloc library routine, and must each\n   be at least NUM_REGS * sizeof (regoff_t) bytes long.\n\n   If NUM_REGS == 0, then subsequent matches should allocate their own\n   register data.\n\n   Unless this function is called, the first search or match using\n   PATTERN_BUFFER will allocate its own register data, without\n   freeing the old data.  */\n\nvoid\nre_set_registers (struct re_pattern_buffer *bufp, struct re_registers *regs,\n\t\t  __re_size_t num_regs, regoff_t *starts, regoff_t *ends)\n{\n  if (num_regs)\n    {\n      bufp->regs_allocated = REGS_REALLOCATE;\n      regs->num_regs = num_regs;\n      regs->start = starts;\n      regs->end = ends;\n    }\n  else\n    {\n      bufp->regs_allocated = REGS_UNALLOCATED;\n      regs->num_regs = 0;\n      regs->start = regs->end = NULL;\n    }\n}\n#ifdef _LIBC\nweak_alias (__re_set_registers, re_set_registers)\n#endif\n\f\n/* Entry points compatible with 4.2 BSD regex library.  We don't define\n   them unless specifically requested.  */\n\n#if defined _REGEX_RE_COMP || defined _LIBC\nint\n# ifdef _LIBC\nweak_function\n# endif\nre_exec (const char *s)\n{\n  return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);\n}\n#endif /* _REGEX_RE_COMP */\n\f\n/* Internal entry point.  */\n\n/* Searches for a compiled pattern PREG in the string STRING, whose\n   length is LENGTH.  NMATCH, PMATCH, and EFLAGS have the same\n   meaning as with regexec.  LAST_START is START + RANGE, where\n   START and RANGE have the same meaning as with re_search.\n   Return REG_NOERROR if we find a match, and REG_NOMATCH if not,\n   otherwise return the error code.\n   Note: We assume front end functions already check ranges.\n   (0 <= LAST_START && LAST_START <= LENGTH)  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nre_search_internal (const regex_t *preg, const char *string, Idx length,\n\t\t    Idx start, Idx last_start, Idx stop, size_t nmatch,\n\t\t    regmatch_t pmatch[], int eflags)\n{\n  reg_errcode_t err;\n  const re_dfa_t *dfa = preg->buffer;\n  Idx left_lim, right_lim;\n  int incr;\n  bool fl_longest_match;\n  int match_kind;\n  Idx match_first;\n  Idx match_last = -1;\n  Idx extra_nmatch;\n  bool sb;\n  int ch;\n  re_match_context_t mctx = { .dfa = dfa };\n  char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate\n\t\t    && start != last_start && !preg->can_be_null)\n\t\t   ? preg->fastmap : NULL);\n  RE_TRANSLATE_TYPE t = preg->translate;\n\n  extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0;\n  nmatch -= extra_nmatch;\n\n  /* Check if the DFA haven't been compiled.  */\n  if (__glibc_unlikely (preg->used == 0 || dfa->init_state == NULL\n\t\t\t|| dfa->init_state_word == NULL\n\t\t\t|| dfa->init_state_nl == NULL\n\t\t\t|| dfa->init_state_begbuf == NULL))\n    return REG_NOMATCH;\n\n  /* We assume front-end functions already check them.  */\n  DEBUG_ASSERT (0 <= last_start && last_start <= length);\n\n  /* If initial states with non-begbuf contexts have no elements,\n     the regex must be anchored.  If preg->newline_anchor is set,\n     we'll never use init_state_nl, so do not check it.  */\n  if (dfa->init_state->nodes.nelem == 0\n      && dfa->init_state_word->nodes.nelem == 0\n      && (dfa->init_state_nl->nodes.nelem == 0\n\t  || !preg->newline_anchor))\n    {\n      if (start != 0 && last_start != 0)\n        return REG_NOMATCH;\n      start = last_start = 0;\n    }\n\n  /* We must check the longest matching, if nmatch > 0.  */\n  fl_longest_match = (nmatch != 0 || dfa->nbackref);\n\n  err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,\n\t\t\t    preg->translate, (preg->syntax & RE_ICASE) != 0,\n\t\t\t    dfa);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    goto free_return;\n  mctx.input.stop = stop;\n  mctx.input.raw_stop = stop;\n  mctx.input.newline_anchor = preg->newline_anchor;\n\n  err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    goto free_return;\n\n  /* We will log all the DFA states through which the dfa pass,\n     if nmatch > 1, or this dfa has \"multibyte node\", which is a\n     back-reference or a node which can accept multibyte character or\n     multi character collating element.  */\n  if (nmatch > 1 || dfa->has_mb_node)\n    {\n      /* Avoid overflow.  */\n      if (__glibc_unlikely ((MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *))\n\t\t\t     <= mctx.input.bufs_len)))\n\t{\n\t  err = REG_ESPACE;\n\t  goto free_return;\n\t}\n\n      mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);\n      if (__glibc_unlikely (mctx.state_log == NULL))\n\t{\n\t  err = REG_ESPACE;\n\t  goto free_return;\n\t}\n    }\n\n  match_first = start;\n  mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF\n\t\t\t   : CONTEXT_NEWLINE | CONTEXT_BEGBUF;\n\n  /* Check incrementally whether the input string matches.  */\n  incr = (last_start < start) ? -1 : 1;\n  left_lim = (last_start < start) ? last_start : start;\n  right_lim = (last_start < start) ? start : last_start;\n  sb = dfa->mb_cur_max == 1;\n  match_kind =\n    (fastmap\n     ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)\n\t| (start <= last_start ? 2 : 0)\n\t| (t != NULL ? 1 : 0))\n     : 8);\n\n  for (;; match_first += incr)\n    {\n      err = REG_NOMATCH;\n      if (match_first < left_lim || right_lim < match_first)\n\tgoto free_return;\n\n      /* Advance as rapidly as possible through the string, until we\n\t find a plausible place to start matching.  This may be done\n\t with varying efficiency, so there are various possibilities:\n\t only the most common of them are specialized, in order to\n\t save on code size.  We use a switch statement for speed.  */\n      switch (match_kind)\n\t{\n\tcase 8:\n\t  /* No fastmap.  */\n\t  break;\n\n\tcase 7:\n\t  /* Fastmap with single-byte translation, match forward.  */\n\t  while (__glibc_likely (match_first < right_lim)\n\t\t && !fastmap[t[(unsigned char) string[match_first]]])\n\t    ++match_first;\n\t  goto forward_match_found_start_or_reached_end;\n\n\tcase 6:\n\t  /* Fastmap without translation, match forward.  */\n\t  while (__glibc_likely (match_first < right_lim)\n\t\t && !fastmap[(unsigned char) string[match_first]])\n\t    ++match_first;\n\n\tforward_match_found_start_or_reached_end:\n\t  if (__glibc_unlikely (match_first == right_lim))\n\t    {\n\t      ch = match_first >= length\n\t\t       ? 0 : (unsigned char) string[match_first];\n\t      if (!fastmap[t ? t[ch] : ch])\n\t\tgoto free_return;\n\t    }\n\t  break;\n\n\tcase 4:\n\tcase 5:\n\t  /* Fastmap without multi-byte translation, match backwards.  */\n\t  while (match_first >= left_lim)\n\t    {\n\t      ch = match_first >= length\n\t\t       ? 0 : (unsigned char) string[match_first];\n\t      if (fastmap[t ? t[ch] : ch])\n\t\tbreak;\n\t      --match_first;\n\t    }\n\t  if (match_first < left_lim)\n\t    goto free_return;\n\t  break;\n\n\tdefault:\n\t  /* In this case, we can't determine easily the current byte,\n\t     since it might be a component byte of a multibyte\n\t     character.  Then we use the constructed buffer instead.  */\n\t  for (;;)\n\t    {\n\t      /* If MATCH_FIRST is out of the valid range, reconstruct the\n\t\t buffers.  */\n\t      __re_size_t offset = match_first - mctx.input.raw_mbs_idx;\n\t      if (__glibc_unlikely (offset\n\t\t\t\t    >= (__re_size_t) mctx.input.valid_raw_len))\n\t\t{\n\t\t  err = re_string_reconstruct (&mctx.input, match_first,\n\t\t\t\t\t       eflags);\n\t\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t\t    goto free_return;\n\n\t\t  offset = match_first - mctx.input.raw_mbs_idx;\n\t\t}\n\t      /* If MATCH_FIRST is out of the buffer, leave it as '\\0'.\n\t\t Note that MATCH_FIRST must not be smaller than 0.  */\n\t      ch = (match_first >= length\n\t\t    ? 0 : re_string_byte_at (&mctx.input, offset));\n\t      if (fastmap[ch])\n\t\tbreak;\n\t      match_first += incr;\n\t      if (match_first < left_lim || match_first > right_lim)\n\t\t{\n\t\t  err = REG_NOMATCH;\n\t\t  goto free_return;\n\t\t}\n\t    }\n\t  break;\n\t}\n\n      /* Reconstruct the buffers so that the matcher can assume that\n\t the matching starts from the beginning of the buffer.  */\n      err = re_string_reconstruct (&mctx.input, match_first, eflags);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\tgoto free_return;\n\n#ifdef RE_ENABLE_I18N\n     /* Don't consider this char as a possible match start if it part,\n\tyet isn't the head, of a multibyte character.  */\n      if (!sb && !re_string_first_byte (&mctx.input, 0))\n\tcontinue;\n#endif\n\n      /* It seems to be appropriate one, then use the matcher.  */\n      /* We assume that the matching starts from 0.  */\n      mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;\n      match_last = check_matching (&mctx, fl_longest_match,\n\t\t\t\t   start <= last_start ? &match_first : NULL);\n      if (match_last != -1)\n\t{\n\t  if (__glibc_unlikely (match_last == -2))\n\t    {\n\t      err = REG_ESPACE;\n\t      goto free_return;\n\t    }\n\t  else\n\t    {\n\t      mctx.match_last = match_last;\n\t      if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)\n\t\t{\n\t\t  re_dfastate_t *pstate = mctx.state_log[match_last];\n\t\t  mctx.last_node = check_halt_state_context (&mctx, pstate,\n\t\t\t\t\t\t\t     match_last);\n\t\t}\n\t      if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)\n\t\t  || dfa->nbackref)\n\t\t{\n\t\t  err = prune_impossible_nodes (&mctx);\n\t\t  if (err == REG_NOERROR)\n\t\t    break;\n\t\t  if (__glibc_unlikely (err != REG_NOMATCH))\n\t\t    goto free_return;\n\t\t  match_last = -1;\n\t\t}\n\t      else\n\t\tbreak; /* We found a match.  */\n\t    }\n\t}\n\n      match_ctx_clean (&mctx);\n    }\n\n  DEBUG_ASSERT (match_last != -1);\n  DEBUG_ASSERT (err == REG_NOERROR);\n\n  /* Set pmatch[] if we need.  */\n  if (nmatch > 0)\n    {\n      Idx reg_idx;\n\n      /* Initialize registers.  */\n      for (reg_idx = 1; reg_idx < nmatch; ++reg_idx)\n\tpmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1;\n\n      /* Set the points where matching start/end.  */\n      pmatch[0].rm_so = 0;\n      pmatch[0].rm_eo = mctx.match_last;\n      /* FIXME: This function should fail if mctx.match_last exceeds\n\t the maximum possible regoff_t value.  We need a new error\n\t code REG_OVERFLOW.  */\n\n      if (!preg->no_sub && nmatch > 1)\n\t{\n\t  err = set_regs (preg, &mctx, nmatch, pmatch,\n\t\t\t  dfa->has_plural_match && dfa->nbackref > 0);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    goto free_return;\n\t}\n\n      /* At last, add the offset to each register, since we slid\n\t the buffers so that we could assume that the matching starts\n\t from 0.  */\n      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)\n\tif (pmatch[reg_idx].rm_so != -1)\n\t  {\n#ifdef RE_ENABLE_I18N\n\t    if (__glibc_unlikely (mctx.input.offsets_needed != 0))\n\t      {\n\t\tpmatch[reg_idx].rm_so =\n\t\t  (pmatch[reg_idx].rm_so == mctx.input.valid_len\n\t\t   ? mctx.input.valid_raw_len\n\t\t   : mctx.input.offsets[pmatch[reg_idx].rm_so]);\n\t\tpmatch[reg_idx].rm_eo =\n\t\t  (pmatch[reg_idx].rm_eo == mctx.input.valid_len\n\t\t   ? mctx.input.valid_raw_len\n\t\t   : mctx.input.offsets[pmatch[reg_idx].rm_eo]);\n\t      }\n#else\n\t    DEBUG_ASSERT (mctx.input.offsets_needed == 0);\n#endif\n\t    pmatch[reg_idx].rm_so += match_first;\n\t    pmatch[reg_idx].rm_eo += match_first;\n\t  }\n      for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx)\n\t{\n\t  pmatch[nmatch + reg_idx].rm_so = -1;\n\t  pmatch[nmatch + reg_idx].rm_eo = -1;\n\t}\n\n      if (dfa->subexp_map)\n\tfor (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)\n\t  if (dfa->subexp_map[reg_idx] != reg_idx)\n\t    {\n\t      pmatch[reg_idx + 1].rm_so\n\t\t= pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;\n\t      pmatch[reg_idx + 1].rm_eo\n\t\t= pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;\n\t    }\n    }\n\n free_return:\n  re_free (mctx.state_log);\n  if (dfa->nbackref)\n    match_ctx_free (&mctx);\n  re_string_destruct (&mctx.input);\n  return err;\n}\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nprune_impossible_nodes (re_match_context_t *mctx)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  Idx halt_node, match_last;\n  reg_errcode_t ret;\n  re_dfastate_t **sifted_states;\n  re_dfastate_t **lim_states = NULL;\n  re_sift_context_t sctx;\n  DEBUG_ASSERT (mctx->state_log != NULL);\n  match_last = mctx->match_last;\n  halt_node = mctx->last_node;\n\n  /* Avoid overflow.  */\n  if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *))\n\t\t\t<= match_last))\n    return REG_ESPACE;\n\n  sifted_states = re_malloc (re_dfastate_t *, match_last + 1);\n  if (__glibc_unlikely (sifted_states == NULL))\n    {\n      ret = REG_ESPACE;\n      goto free_return;\n    }\n  if (dfa->nbackref)\n    {\n      lim_states = re_malloc (re_dfastate_t *, match_last + 1);\n      if (__glibc_unlikely (lim_states == NULL))\n\t{\n\t  ret = REG_ESPACE;\n\t  goto free_return;\n\t}\n      while (1)\n\t{\n\t  memset (lim_states, '\\0',\n\t\t  sizeof (re_dfastate_t *) * (match_last + 1));\n\t  sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,\n\t\t\t match_last);\n\t  ret = sift_states_backward (mctx, &sctx);\n\t  re_node_set_free (&sctx.limits);\n\t  if (__glibc_unlikely (ret != REG_NOERROR))\n\t      goto free_return;\n\t  if (sifted_states[0] != NULL || lim_states[0] != NULL)\n\t    break;\n\t  do\n\t    {\n\t      --match_last;\n\t      if (match_last < 0)\n\t\t{\n\t\t  ret = REG_NOMATCH;\n\t\t  goto free_return;\n\t\t}\n\t    } while (mctx->state_log[match_last] == NULL\n\t\t     || !mctx->state_log[match_last]->halt);\n\t  halt_node = check_halt_state_context (mctx,\n\t\t\t\t\t\tmctx->state_log[match_last],\n\t\t\t\t\t\tmatch_last);\n\t}\n      ret = merge_state_array (dfa, sifted_states, lim_states,\n\t\t\t       match_last + 1);\n      re_free (lim_states);\n      lim_states = NULL;\n      if (__glibc_unlikely (ret != REG_NOERROR))\n\tgoto free_return;\n    }\n  else\n    {\n      sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last);\n      ret = sift_states_backward (mctx, &sctx);\n      re_node_set_free (&sctx.limits);\n      if (__glibc_unlikely (ret != REG_NOERROR))\n\tgoto free_return;\n      if (sifted_states[0] == NULL)\n\t{\n\t  ret = REG_NOMATCH;\n\t  goto free_return;\n\t}\n    }\n  re_free (mctx->state_log);\n  mctx->state_log = sifted_states;\n  sifted_states = NULL;\n  mctx->last_node = halt_node;\n  mctx->match_last = match_last;\n  ret = REG_NOERROR;\n free_return:\n  re_free (sifted_states);\n  re_free (lim_states);\n  return ret;\n}\n\n/* Acquire an initial state and return it.\n   We must select appropriate initial state depending on the context,\n   since initial states may have constraints like \"\\<\", \"^\", etc..  */\n\nstatic inline re_dfastate_t *\n__attribute__ ((always_inline))\nacquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,\n\t\t\t    Idx idx)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  if (dfa->init_state->has_constraint)\n    {\n      unsigned int context;\n      context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags);\n      if (IS_WORD_CONTEXT (context))\n\treturn dfa->init_state_word;\n      else if (IS_ORDINARY_CONTEXT (context))\n\treturn dfa->init_state;\n      else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context))\n\treturn dfa->init_state_begbuf;\n      else if (IS_NEWLINE_CONTEXT (context))\n\treturn dfa->init_state_nl;\n      else if (IS_BEGBUF_CONTEXT (context))\n\t{\n\t  /* It is relatively rare case, then calculate on demand.  */\n\t  return re_acquire_state_context (err, dfa,\n\t\t\t\t\t   dfa->init_state->entrance_nodes,\n\t\t\t\t\t   context);\n\t}\n      else\n\t/* Must not happen?  */\n\treturn dfa->init_state;\n    }\n  else\n    return dfa->init_state;\n}\n\n/* Check whether the regular expression match input string INPUT or not,\n   and return the index where the matching end.  Return -1 if\n   there is no match, and return -2 in case of an error.\n   FL_LONGEST_MATCH means we want the POSIX longest matching.\n   If P_MATCH_FIRST is not NULL, and the match fails, it is set to the\n   next place where we may want to try matching.\n   Note that the matcher assumes that the matching starts from the current\n   index of the buffer.  */\n\nstatic Idx\n__attribute_warn_unused_result__\ncheck_matching (re_match_context_t *mctx, bool fl_longest_match,\n\t\tIdx *p_match_first)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  reg_errcode_t err;\n  Idx match = 0;\n  Idx match_last = -1;\n  Idx cur_str_idx = re_string_cur_idx (&mctx->input);\n  re_dfastate_t *cur_state;\n  bool at_init_state = p_match_first != NULL;\n  Idx next_start_idx = cur_str_idx;\n\n  err = REG_NOERROR;\n  cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);\n  /* An initial state must not be NULL (invalid).  */\n  if (__glibc_unlikely (cur_state == NULL))\n    {\n      DEBUG_ASSERT (err == REG_ESPACE);\n      return -2;\n    }\n\n  if (mctx->state_log != NULL)\n    {\n      mctx->state_log[cur_str_idx] = cur_state;\n\n      /* Check OP_OPEN_SUBEXP in the initial state in case that we use them\n\t later.  E.g. Processing back references.  */\n      if (__glibc_unlikely (dfa->nbackref))\n\t{\n\t  at_init_state = false;\n\t  err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\n\t  if (cur_state->has_backref)\n\t    {\n\t      err = transit_state_bkref (mctx, &cur_state->nodes);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\treturn err;\n\t    }\n\t}\n    }\n\n  /* If the RE accepts NULL string.  */\n  if (__glibc_unlikely (cur_state->halt))\n    {\n      if (!cur_state->has_constraint\n\t  || check_halt_state_context (mctx, cur_state, cur_str_idx))\n\t{\n\t  if (!fl_longest_match)\n\t    return cur_str_idx;\n\t  else\n\t    {\n\t      match_last = cur_str_idx;\n\t      match = 1;\n\t    }\n\t}\n    }\n\n  while (!re_string_eoi (&mctx->input))\n    {\n      re_dfastate_t *old_state = cur_state;\n      Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1;\n\n      if ((__glibc_unlikely (next_char_idx >= mctx->input.bufs_len)\n\t   && mctx->input.bufs_len < mctx->input.len)\n\t  || (__glibc_unlikely (next_char_idx >= mctx->input.valid_len)\n\t      && mctx->input.valid_len < mctx->input.len))\n\t{\n\t  err = extend_buffers (mctx, next_char_idx + 1);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    {\n\t      DEBUG_ASSERT (err == REG_ESPACE);\n\t      return -2;\n\t    }\n\t}\n\n      cur_state = transit_state (&err, mctx, cur_state);\n      if (mctx->state_log != NULL)\n\tcur_state = merge_state_with_log (&err, mctx, cur_state);\n\n      if (cur_state == NULL)\n\t{\n\t  /* Reached the invalid state or an error.  Try to recover a valid\n\t     state using the state log, if available and if we have not\n\t     already found a valid (even if not the longest) match.  */\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return -2;\n\n\t  if (mctx->state_log == NULL\n\t      || (match && !fl_longest_match)\n\t      || (cur_state = find_recover_state (&err, mctx)) == NULL)\n\t    break;\n\t}\n\n      if (__glibc_unlikely (at_init_state))\n\t{\n\t  if (old_state == cur_state)\n\t    next_start_idx = next_char_idx;\n\t  else\n\t    at_init_state = false;\n\t}\n\n      if (cur_state->halt)\n\t{\n\t  /* Reached a halt state.\n\t     Check the halt state can satisfy the current context.  */\n\t  if (!cur_state->has_constraint\n\t      || check_halt_state_context (mctx, cur_state,\n\t\t\t\t\t   re_string_cur_idx (&mctx->input)))\n\t    {\n\t      /* We found an appropriate halt state.  */\n\t      match_last = re_string_cur_idx (&mctx->input);\n\t      match = 1;\n\n\t      /* We found a match, do not modify match_first below.  */\n\t      p_match_first = NULL;\n\t      if (!fl_longest_match)\n\t\tbreak;\n\t    }\n\t}\n    }\n\n  if (p_match_first)\n    *p_match_first += next_start_idx;\n\n  return match_last;\n}\n\n/* Check NODE match the current context.  */\n\nstatic bool\ncheck_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context)\n{\n  re_token_type_t type = dfa->nodes[node].type;\n  unsigned int constraint = dfa->nodes[node].constraint;\n  if (type != END_OF_RE)\n    return false;\n  if (!constraint)\n    return true;\n  if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context))\n    return false;\n  return true;\n}\n\n/* Check the halt state STATE match the current context.\n   Return 0 if not match, if the node, STATE has, is a halt node and\n   match the context, return the node.  */\n\nstatic Idx\ncheck_halt_state_context (const re_match_context_t *mctx,\n\t\t\t  const re_dfastate_t *state, Idx idx)\n{\n  Idx i;\n  unsigned int context;\n  DEBUG_ASSERT (state->halt);\n  context = re_string_context_at (&mctx->input, idx, mctx->eflags);\n  for (i = 0; i < state->nodes.nelem; ++i)\n    if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context))\n      return state->nodes.elems[i];\n  return 0;\n}\n\n/* Compute the next node to which \"NFA\" transit from NODE(\"NFA\" is a NFA\n   corresponding to the DFA).\n   Return the destination node, and update EPS_VIA_NODES;\n   return -1 on match failure, -2 on error.  */\n\nstatic Idx\nproceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,\n\t\t   regmatch_t *prevregs,\n\t\t   Idx *pidx, Idx node, re_node_set *eps_via_nodes,\n\t\t   struct re_fail_stack_t *fs)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  if (IS_EPSILON_NODE (dfa->nodes[node].type))\n    {\n      re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;\n      re_node_set *edests = &dfa->edests[node];\n\n      if (! re_node_set_contains (eps_via_nodes, node))\n        {\n          bool ok = re_node_set_insert (eps_via_nodes, node);\n          if (__glibc_unlikely (! ok))\n            return -2;\n        }\n\n      /* Pick a valid destination, or return -1 if none is found.  */\n      Idx dest_node = -1;\n      for (Idx i = 0; i < edests->nelem; i++)\n\t{\n\t  Idx candidate = edests->elems[i];\n\t  if (!re_node_set_contains (cur_nodes, candidate))\n\t    continue;\n          if (dest_node == -1)\n\t    dest_node = candidate;\n\n\t  else\n\t    {\n\t      /* In order to avoid infinite loop like \"(a*)*\", return the second\n\t\t epsilon-transition if the first was already considered.  */\n\t      if (re_node_set_contains (eps_via_nodes, dest_node))\n\t\treturn candidate;\n\n\t      /* Otherwise, push the second epsilon-transition on the fail stack.  */\n\t      else if (fs != NULL\n\t\t       && push_fail_stack (fs, *pidx, candidate, nregs, regs,\n\t\t\t\t\t   prevregs, eps_via_nodes))\n\t\treturn -2;\n\n\t      /* We know we are going to exit.  */\n\t      break;\n\t    }\n\t}\n      return dest_node;\n    }\n  else\n    {\n      Idx naccepted = 0;\n      re_token_type_t type = dfa->nodes[node].type;\n\n#ifdef RE_ENABLE_I18N\n      if (dfa->nodes[node].accept_mb)\n\tnaccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx);\n      else\n#endif /* RE_ENABLE_I18N */\n      if (type == OP_BACK_REF)\n\t{\n\t  Idx subexp_idx = dfa->nodes[node].opr.idx + 1;\n\t  if (subexp_idx < nregs)\n\t    naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;\n\t  if (fs != NULL)\n\t    {\n\t      if (subexp_idx >= nregs\n\t\t  || regs[subexp_idx].rm_so == -1\n\t\t  || regs[subexp_idx].rm_eo == -1)\n\t\treturn -1;\n\t      else if (naccepted)\n\t\t{\n\t\t  char *buf = (char *) re_string_get_buffer (&mctx->input);\n\t\t  if (mctx->input.valid_len - *pidx < naccepted\n\t\t      || (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,\n\t\t\t\t  naccepted)\n\t\t\t  != 0))\n\t\t    return -1;\n\t\t}\n\t    }\n\n\t  if (naccepted == 0)\n\t    {\n\t      Idx dest_node;\n\t      bool ok = re_node_set_insert (eps_via_nodes, node);\n\t      if (__glibc_unlikely (! ok))\n\t\treturn -2;\n\t      dest_node = dfa->edests[node].elems[0];\n\t      if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,\n\t\t\t\t\tdest_node))\n\t\treturn dest_node;\n\t    }\n\t}\n\n      if (naccepted != 0\n\t  || check_node_accept (mctx, dfa->nodes + node, *pidx))\n\t{\n\t  Idx dest_node = dfa->nexts[node];\n\t  *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;\n\t  if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL\n\t\t     || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,\n\t\t\t\t\t       dest_node)))\n\t    return -1;\n\t  re_node_set_empty (eps_via_nodes);\n\t  return dest_node;\n\t}\n    }\n  return -1;\n}\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\npush_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,\n\t\t Idx nregs, regmatch_t *regs, regmatch_t *prevregs,\n\t\t re_node_set *eps_via_nodes)\n{\n  reg_errcode_t err;\n  Idx num = fs->num++;\n  if (fs->num == fs->alloc)\n    {\n      struct re_fail_stack_ent_t *new_array;\n      new_array = re_realloc (fs->stack, struct re_fail_stack_ent_t,\n                              fs->alloc * 2);\n      if (new_array == NULL)\n\treturn REG_ESPACE;\n      fs->alloc *= 2;\n      fs->stack = new_array;\n    }\n  fs->stack[num].idx = str_idx;\n  fs->stack[num].node = dest_node;\n  fs->stack[num].regs = re_malloc (regmatch_t, 2 * nregs);\n  if (fs->stack[num].regs == NULL)\n    return REG_ESPACE;\n  memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);\n  memcpy (fs->stack[num].regs + nregs, prevregs, sizeof (regmatch_t) * nregs);\n  err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);\n  return err;\n}\n\nstatic Idx\npop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs,\n\t\tregmatch_t *regs, regmatch_t *prevregs,\n\t\tre_node_set *eps_via_nodes)\n{\n  if (fs == NULL || fs->num == 0)\n    return -1;\n  Idx num = --fs->num;\n  *pidx = fs->stack[num].idx;\n  memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);\n  memcpy (prevregs, fs->stack[num].regs + nregs, sizeof (regmatch_t) * nregs);\n  re_node_set_free (eps_via_nodes);\n  re_free (fs->stack[num].regs);\n  *eps_via_nodes = fs->stack[num].eps_via_nodes;\n  DEBUG_ASSERT (0 <= fs->stack[num].node);\n  return fs->stack[num].node;\n}\n\n\n#define DYNARRAY_STRUCT  regmatch_list\n#define DYNARRAY_ELEMENT regmatch_t\n#define DYNARRAY_PREFIX  regmatch_list_\n#include <malloc/dynarray-skeleton.c>\n\n/* Set the positions where the subexpressions are starts/ends to registers\n   PMATCH.\n   Note: We assume that pmatch[0] is already set, and\n   pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nset_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,\n\t  regmatch_t *pmatch, bool fl_backtrack)\n{\n  const re_dfa_t *dfa = preg->buffer;\n  Idx idx, cur_node;\n  re_node_set eps_via_nodes;\n  struct re_fail_stack_t *fs;\n  struct re_fail_stack_t fs_body = { 0, 2, NULL };\n  struct regmatch_list prev_match;\n  regmatch_list_init (&prev_match);\n\n  DEBUG_ASSERT (nmatch > 1);\n  DEBUG_ASSERT (mctx->state_log != NULL);\n  if (fl_backtrack)\n    {\n      fs = &fs_body;\n      fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);\n      if (fs->stack == NULL)\n\treturn REG_ESPACE;\n    }\n  else\n    fs = NULL;\n\n  cur_node = dfa->init_node;\n  re_node_set_init_empty (&eps_via_nodes);\n\n  if (!regmatch_list_resize (&prev_match, nmatch))\n    {\n      regmatch_list_free (&prev_match);\n      free_fail_stack_return (fs);\n      return REG_ESPACE;\n    }\n  regmatch_t *prev_idx_match = regmatch_list_begin (&prev_match);\n  memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);\n\n  for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)\n    {\n      update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);\n\n      if ((idx == pmatch[0].rm_eo && cur_node == mctx->last_node)\n\t  || (fs && re_node_set_contains (&eps_via_nodes, cur_node)))\n\t{\n\t  Idx reg_idx;\n\t  cur_node = -1;\n\t  if (fs)\n\t    {\n\t      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)\n\t\tif (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)\n\t\t  {\n\t\t    cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,\n\t\t\t\t\t       prev_idx_match, &eps_via_nodes);\n\t\t    break;\n\t\t  }\n\t    }\n\t  if (cur_node < 0)\n\t    {\n\t      re_node_set_free (&eps_via_nodes);\n\t      regmatch_list_free (&prev_match);\n\t      return free_fail_stack_return (fs);\n\t    }\n\t}\n\n      /* Proceed to next node.  */\n      cur_node = proceed_next_node (mctx, nmatch, pmatch, prev_idx_match,\n\t\t\t\t    &idx, cur_node,\n\t\t\t\t    &eps_via_nodes, fs);\n\n      if (__glibc_unlikely (cur_node < 0))\n\t{\n\t  if (__glibc_unlikely (cur_node == -2))\n\t    {\n\t      re_node_set_free (&eps_via_nodes);\n\t      regmatch_list_free (&prev_match);\n\t      free_fail_stack_return (fs);\n\t      return REG_ESPACE;\n\t    }\n\t  cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,\n\t\t\t\t     prev_idx_match, &eps_via_nodes);\n\t  if (cur_node < 0)\n\t    {\n\t      re_node_set_free (&eps_via_nodes);\n\t      regmatch_list_free (&prev_match);\n\t      free_fail_stack_return (fs);\n\t      return REG_NOMATCH;\n\t    }\n\t}\n    }\n  re_node_set_free (&eps_via_nodes);\n  regmatch_list_free (&prev_match);\n  return free_fail_stack_return (fs);\n}\n\nstatic reg_errcode_t\nfree_fail_stack_return (struct re_fail_stack_t *fs)\n{\n  if (fs)\n    {\n      Idx fs_idx;\n      for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)\n\t{\n\t  re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);\n\t  re_free (fs->stack[fs_idx].regs);\n\t}\n      re_free (fs->stack);\n    }\n  return REG_NOERROR;\n}\n\nstatic void\nupdate_regs (const re_dfa_t *dfa, regmatch_t *pmatch,\n\t     regmatch_t *prev_idx_match, Idx cur_node, Idx cur_idx, Idx nmatch)\n{\n  int type = dfa->nodes[cur_node].type;\n  if (type == OP_OPEN_SUBEXP)\n    {\n      Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;\n\n      /* We are at the first node of this sub expression.  */\n      if (reg_num < nmatch)\n\t{\n\t  pmatch[reg_num].rm_so = cur_idx;\n\t  pmatch[reg_num].rm_eo = -1;\n\t}\n    }\n  else if (type == OP_CLOSE_SUBEXP)\n    {\n      /* We are at the last node of this sub expression.  */\n      Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;\n      if (reg_num < nmatch)\n\t{\n\t  if (pmatch[reg_num].rm_so < cur_idx)\n\t    {\n\t      pmatch[reg_num].rm_eo = cur_idx;\n\t      /* This is a non-empty match or we are not inside an optional\n\t\t subexpression.  Accept this right away.  */\n\t      memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);\n\t    }\n\t  else\n\t    {\n\t      if (dfa->nodes[cur_node].opt_subexp\n\t\t  && prev_idx_match[reg_num].rm_so != -1)\n\t\t/* We transited through an empty match for an optional\n\t\t   subexpression, like (a?)*, and this is not the subexp's\n\t\t   first match.  Copy back the old content of the registers\n\t\t   so that matches of an inner subexpression are undone as\n\t\t   well, like in ((a?))*.  */\n\t\tmemcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch);\n\t      else\n\t\t/* We completed a subexpression, but it may be part of\n\t\t   an optional one, so do not update PREV_IDX_MATCH.  */\n\t\tpmatch[reg_num].rm_eo = cur_idx;\n\t    }\n\t}\n    }\n}\n\n/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0\n   and sift the nodes in each states according to the following rules.\n   Updated state_log will be wrote to STATE_LOG.\n\n   Rules: We throw away the Node 'a' in the STATE_LOG[STR_IDX] if...\n     1. When STR_IDX == MATCH_LAST(the last index in the state_log):\n\tIf 'a' isn't the LAST_NODE and 'a' can't epsilon transit to\n\tthe LAST_NODE, we throw away the node 'a'.\n     2. When 0 <= STR_IDX < MATCH_LAST and 'a' accepts\n\tstring 's' and transit to 'b':\n\ti. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw\n\t   away the node 'a'.\n\tii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is\n\t    thrown away, we throw away the node 'a'.\n     3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b':\n\ti. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the\n\t   node 'a'.\n\tii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away,\n\t    we throw away the node 'a'.  */\n\n#define STATE_NODE_CONTAINS(state,node) \\\n  ((state) != NULL && re_node_set_contains (&(state)->nodes, node))\n\nstatic reg_errcode_t\nsift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx)\n{\n  reg_errcode_t err;\n  int null_cnt = 0;\n  Idx str_idx = sctx->last_str_idx;\n  re_node_set cur_dest;\n\n  DEBUG_ASSERT (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);\n\n  /* Build sifted state_log[str_idx].  It has the nodes which can epsilon\n     transit to the last_node and the last_node itself.  */\n  err = re_node_set_init_1 (&cur_dest, sctx->last_node);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    return err;\n  err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    goto free_return;\n\n  /* Then check each states in the state_log.  */\n  while (str_idx > 0)\n    {\n      /* Update counters.  */\n      null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0;\n      if (null_cnt > mctx->max_mb_elem_len)\n\t{\n\t  memset (sctx->sifted_states, '\\0',\n\t\t  sizeof (re_dfastate_t *) * str_idx);\n\t  re_node_set_free (&cur_dest);\n\t  return REG_NOERROR;\n\t}\n      re_node_set_empty (&cur_dest);\n      --str_idx;\n\n      if (mctx->state_log[str_idx])\n\t{\n\t  err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    goto free_return;\n\t}\n\n      /* Add all the nodes which satisfy the following conditions:\n\t - It can epsilon transit to a node in CUR_DEST.\n\t - It is in CUR_SRC.\n\t And update state_log.  */\n      err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\tgoto free_return;\n    }\n  err = REG_NOERROR;\n free_return:\n  re_node_set_free (&cur_dest);\n  return err;\n}\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nbuild_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,\n\t\t     Idx str_idx, re_node_set *cur_dest)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes;\n  Idx i;\n\n  /* Then build the next sifted state.\n     We build the next sifted state on 'cur_dest', and update\n     'sifted_states[str_idx]' with 'cur_dest'.\n     Note:\n     'cur_dest' is the sifted state from 'state_log[str_idx + 1]'.\n     'cur_src' points the node_set of the old 'state_log[str_idx]'\n     (with the epsilon nodes pre-filtered out).  */\n  for (i = 0; i < cur_src->nelem; i++)\n    {\n      Idx prev_node = cur_src->elems[i];\n      int naccepted = 0;\n      bool ok;\n      DEBUG_ASSERT (!IS_EPSILON_NODE (dfa->nodes[prev_node].type));\n\n#ifdef RE_ENABLE_I18N\n      /* If the node may accept \"multi byte\".  */\n      if (dfa->nodes[prev_node].accept_mb)\n\tnaccepted = sift_states_iter_mb (mctx, sctx, prev_node,\n\t\t\t\t\t str_idx, sctx->last_str_idx);\n#endif /* RE_ENABLE_I18N */\n\n      /* We don't check backreferences here.\n\t See update_cur_sifted_state().  */\n      if (!naccepted\n\t  && check_node_accept (mctx, dfa->nodes + prev_node, str_idx)\n\t  && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],\n\t\t\t\t  dfa->nexts[prev_node]))\n\tnaccepted = 1;\n\n      if (naccepted == 0)\n\tcontinue;\n\n      if (sctx->limits.nelem)\n\t{\n\t  Idx to_idx = str_idx + naccepted;\n\t  if (check_dst_limits (mctx, &sctx->limits,\n\t\t\t\tdfa->nexts[prev_node], to_idx,\n\t\t\t\tprev_node, str_idx))\n\t    continue;\n\t}\n      ok = re_node_set_insert (cur_dest, prev_node);\n      if (__glibc_unlikely (! ok))\n\treturn REG_ESPACE;\n    }\n\n  return REG_NOERROR;\n}\n\n/* Helper functions.  */\n\nstatic reg_errcode_t\nclean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx)\n{\n  Idx top = mctx->state_log_top;\n\n  if ((next_state_log_idx >= mctx->input.bufs_len\n       && mctx->input.bufs_len < mctx->input.len)\n      || (next_state_log_idx >= mctx->input.valid_len\n\t  && mctx->input.valid_len < mctx->input.len))\n    {\n      reg_errcode_t err;\n      err = extend_buffers (mctx, next_state_log_idx + 1);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\treturn err;\n    }\n\n  if (top < next_state_log_idx)\n    {\n      memset (mctx->state_log + top + 1, '\\0',\n\t      sizeof (re_dfastate_t *) * (next_state_log_idx - top));\n      mctx->state_log_top = next_state_log_idx;\n    }\n  return REG_NOERROR;\n}\n\nstatic reg_errcode_t\nmerge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst,\n\t\t   re_dfastate_t **src, Idx num)\n{\n  Idx st_idx;\n  reg_errcode_t err;\n  for (st_idx = 0; st_idx < num; ++st_idx)\n    {\n      if (dst[st_idx] == NULL)\n\tdst[st_idx] = src[st_idx];\n      else if (src[st_idx] != NULL)\n\t{\n\t  re_node_set merged_set;\n\t  err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes,\n\t\t\t\t\t&src[st_idx]->nodes);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\t  dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);\n\t  re_node_set_free (&merged_set);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\t}\n    }\n  return REG_NOERROR;\n}\n\nstatic reg_errcode_t\nupdate_cur_sifted_state (const re_match_context_t *mctx,\n\t\t\t re_sift_context_t *sctx, Idx str_idx,\n\t\t\t re_node_set *dest_nodes)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  reg_errcode_t err = REG_NOERROR;\n  const re_node_set *candidates;\n  candidates = ((mctx->state_log[str_idx] == NULL) ? NULL\n\t\t: &mctx->state_log[str_idx]->nodes);\n\n  if (dest_nodes->nelem == 0)\n    sctx->sifted_states[str_idx] = NULL;\n  else\n    {\n      if (candidates)\n\t{\n\t  /* At first, add the nodes which can epsilon transit to a node in\n\t     DEST_NODE.  */\n\t  err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\n\t  /* Then, check the limitations in the current sift_context.  */\n\t  if (sctx->limits.nelem)\n\t    {\n\t      err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,\n\t\t\t\t\t mctx->bkref_ents, str_idx);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\treturn err;\n\t    }\n\t}\n\n      sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\treturn err;\n    }\n\n  if (candidates && mctx->state_log[str_idx]->has_backref)\n    {\n      err = sift_states_bkref (mctx, sctx, str_idx, candidates);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\treturn err;\n    }\n  return REG_NOERROR;\n}\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nadd_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,\n\t\t       const re_node_set *candidates)\n{\n  reg_errcode_t err = REG_NOERROR;\n  Idx i;\n\n  re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    return err;\n\n  if (!state->inveclosure.alloc)\n    {\n      err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\treturn REG_ESPACE;\n      for (i = 0; i < dest_nodes->nelem; i++)\n\t{\n\t  err = re_node_set_merge (&state->inveclosure,\n\t\t\t\t   dfa->inveclosures + dest_nodes->elems[i]);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return REG_ESPACE;\n\t}\n    }\n  return re_node_set_add_intersect (dest_nodes, candidates,\n\t\t\t\t    &state->inveclosure);\n}\n\nstatic reg_errcode_t\nsub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes,\n\t\t       const re_node_set *candidates)\n{\n    Idx ecl_idx;\n    reg_errcode_t err;\n    re_node_set *inv_eclosure = dfa->inveclosures + node;\n    re_node_set except_nodes;\n    re_node_set_init_empty (&except_nodes);\n    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)\n      {\n\tIdx cur_node = inv_eclosure->elems[ecl_idx];\n\tif (cur_node == node)\n\t  continue;\n\tif (IS_EPSILON_NODE (dfa->nodes[cur_node].type))\n\t  {\n\t    Idx edst1 = dfa->edests[cur_node].elems[0];\n\t    Idx edst2 = ((dfa->edests[cur_node].nelem > 1)\n\t\t\t ? dfa->edests[cur_node].elems[1] : -1);\n\t    if ((!re_node_set_contains (inv_eclosure, edst1)\n\t\t && re_node_set_contains (dest_nodes, edst1))\n\t\t|| (edst2 > 0\n\t\t    && !re_node_set_contains (inv_eclosure, edst2)\n\t\t    && re_node_set_contains (dest_nodes, edst2)))\n\t      {\n\t\terr = re_node_set_add_intersect (&except_nodes, candidates,\n\t\t\t\t\t\t dfa->inveclosures + cur_node);\n\t\tif (__glibc_unlikely (err != REG_NOERROR))\n\t\t  {\n\t\t    re_node_set_free (&except_nodes);\n\t\t    return err;\n\t\t  }\n\t      }\n\t  }\n      }\n    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)\n      {\n\tIdx cur_node = inv_eclosure->elems[ecl_idx];\n\tif (!re_node_set_contains (&except_nodes, cur_node))\n\t  {\n\t    Idx idx = re_node_set_contains (dest_nodes, cur_node) - 1;\n\t    re_node_set_remove_at (dest_nodes, idx);\n\t  }\n      }\n    re_node_set_free (&except_nodes);\n    return REG_NOERROR;\n}\n\nstatic bool\ncheck_dst_limits (const re_match_context_t *mctx, const re_node_set *limits,\n\t\t  Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  Idx lim_idx, src_pos, dst_pos;\n\n  Idx dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);\n  Idx src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);\n  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)\n    {\n      Idx subexp_idx;\n      struct re_backref_cache_entry *ent;\n      ent = mctx->bkref_ents + limits->elems[lim_idx];\n      subexp_idx = dfa->nodes[ent->node].opr.idx;\n\n      dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],\n\t\t\t\t\t   subexp_idx, dst_node, dst_idx,\n\t\t\t\t\t   dst_bkref_idx);\n      src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],\n\t\t\t\t\t   subexp_idx, src_node, src_idx,\n\t\t\t\t\t   src_bkref_idx);\n\n      /* In case of:\n\t <src> <dst> ( <subexp> )\n\t ( <subexp> ) <src> <dst>\n\t ( <subexp1> <src> <subexp2> <dst> <subexp3> )  */\n      if (src_pos == dst_pos)\n\tcontinue; /* This is unrelated limitation.  */\n      else\n\treturn true;\n    }\n  return false;\n}\n\nstatic int\ncheck_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries,\n\t\t\t     Idx subexp_idx, Idx from_node, Idx bkref_idx)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  const re_node_set *eclosures = dfa->eclosures + from_node;\n  Idx node_idx;\n\n  /* Else, we are on the boundary: examine the nodes on the epsilon\n     closure.  */\n  for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)\n    {\n      Idx node = eclosures->elems[node_idx];\n      switch (dfa->nodes[node].type)\n\t{\n\tcase OP_BACK_REF:\n\t  if (bkref_idx != -1)\n\t    {\n\t      struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;\n\t      do\n\t\t{\n\t\t  Idx dst;\n\t\t  int cpos;\n\n\t\t  if (ent->node != node)\n\t\t    continue;\n\n\t\t  if (subexp_idx < BITSET_WORD_BITS\n\t\t      && !(ent->eps_reachable_subexps_map\n\t\t\t   & ((bitset_word_t) 1 << subexp_idx)))\n\t\t    continue;\n\n\t\t  /* Recurse trying to reach the OP_OPEN_SUBEXP and\n\t\t     OP_CLOSE_SUBEXP cases below.  But, if the\n\t\t     destination node is the same node as the source\n\t\t     node, don't recurse because it would cause an\n\t\t     infinite loop: a regex that exhibits this behavior\n\t\t     is ()\\1*\\1*  */\n\t\t  dst = dfa->edests[node].elems[0];\n\t\t  if (dst == from_node)\n\t\t    {\n\t\t      if (boundaries & 1)\n\t\t\treturn -1;\n\t\t      else /* if (boundaries & 2) */\n\t\t\treturn 0;\n\t\t    }\n\n\t\t  cpos =\n\t\t    check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,\n\t\t\t\t\t\t dst, bkref_idx);\n\t\t  if (cpos == -1 /* && (boundaries & 1) */)\n\t\t    return -1;\n\t\t  if (cpos == 0 && (boundaries & 2))\n\t\t    return 0;\n\n\t\t  if (subexp_idx < BITSET_WORD_BITS)\n\t\t    ent->eps_reachable_subexps_map\n\t\t      &= ~((bitset_word_t) 1 << subexp_idx);\n\t\t}\n\t      while (ent++->more);\n\t    }\n\t  break;\n\n\tcase OP_OPEN_SUBEXP:\n\t  if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx)\n\t    return -1;\n\t  break;\n\n\tcase OP_CLOSE_SUBEXP:\n\t  if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx)\n\t    return 0;\n\t  break;\n\n\tdefault:\n\t    break;\n\t}\n    }\n\n  return (boundaries & 2) ? 1 : 0;\n}\n\nstatic int\ncheck_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit,\n\t\t\t   Idx subexp_idx, Idx from_node, Idx str_idx,\n\t\t\t   Idx bkref_idx)\n{\n  struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;\n  int boundaries;\n\n  /* If we are outside the range of the subexpression, return -1 or 1.  */\n  if (str_idx < lim->subexp_from)\n    return -1;\n\n  if (lim->subexp_to < str_idx)\n    return 1;\n\n  /* If we are within the subexpression, return 0.  */\n  boundaries = (str_idx == lim->subexp_from);\n  boundaries |= (str_idx == lim->subexp_to) << 1;\n  if (boundaries == 0)\n    return 0;\n\n  /* Else, examine epsilon closure.  */\n  return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,\n\t\t\t\t      from_node, bkref_idx);\n}\n\n/* Check the limitations of sub expressions LIMITS, and remove the nodes\n   which are against limitations from DEST_NODES. */\n\nstatic reg_errcode_t\ncheck_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes,\n\t\t     const re_node_set *candidates, re_node_set *limits,\n\t\t     struct re_backref_cache_entry *bkref_ents, Idx str_idx)\n{\n  reg_errcode_t err;\n  Idx node_idx, lim_idx;\n\n  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)\n    {\n      Idx subexp_idx;\n      struct re_backref_cache_entry *ent;\n      ent = bkref_ents + limits->elems[lim_idx];\n\n      if (str_idx <= ent->subexp_from || ent->str_idx < str_idx)\n\tcontinue; /* This is unrelated limitation.  */\n\n      subexp_idx = dfa->nodes[ent->node].opr.idx;\n      if (ent->subexp_to == str_idx)\n\t{\n\t  Idx ops_node = -1;\n\t  Idx cls_node = -1;\n\t  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)\n\t    {\n\t      Idx node = dest_nodes->elems[node_idx];\n\t      re_token_type_t type = dfa->nodes[node].type;\n\t      if (type == OP_OPEN_SUBEXP\n\t\t  && subexp_idx == dfa->nodes[node].opr.idx)\n\t\tops_node = node;\n\t      else if (type == OP_CLOSE_SUBEXP\n\t\t       && subexp_idx == dfa->nodes[node].opr.idx)\n\t\tcls_node = node;\n\t    }\n\n\t  /* Check the limitation of the open subexpression.  */\n\t  /* Note that (ent->subexp_to = str_idx != ent->subexp_from).  */\n\t  if (ops_node >= 0)\n\t    {\n\t      err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,\n\t\t\t\t\t   candidates);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\treturn err;\n\t    }\n\n\t  /* Check the limitation of the close subexpression.  */\n\t  if (cls_node >= 0)\n\t    for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)\n\t      {\n\t\tIdx node = dest_nodes->elems[node_idx];\n\t\tif (!re_node_set_contains (dfa->inveclosures + node,\n\t\t\t\t\t   cls_node)\n\t\t    && !re_node_set_contains (dfa->eclosures + node,\n\t\t\t\t\t      cls_node))\n\t\t  {\n\t\t    /* It is against this limitation.\n\t\t       Remove it form the current sifted state.  */\n\t\t    err = sub_epsilon_src_nodes (dfa, node, dest_nodes,\n\t\t\t\t\t\t candidates);\n\t\t    if (__glibc_unlikely (err != REG_NOERROR))\n\t\t      return err;\n\t\t    --node_idx;\n\t\t  }\n\t      }\n\t}\n      else /* (ent->subexp_to != str_idx)  */\n\t{\n\t  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)\n\t    {\n\t      Idx node = dest_nodes->elems[node_idx];\n\t      re_token_type_t type = dfa->nodes[node].type;\n\t      if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)\n\t\t{\n\t\t  if (subexp_idx != dfa->nodes[node].opr.idx)\n\t\t    continue;\n\t\t  /* It is against this limitation.\n\t\t     Remove it form the current sifted state.  */\n\t\t  err = sub_epsilon_src_nodes (dfa, node, dest_nodes,\n\t\t\t\t\t       candidates);\n\t\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t\t    return err;\n\t\t}\n\t    }\n\t}\n    }\n  return REG_NOERROR;\n}\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nsift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,\n\t\t   Idx str_idx, const re_node_set *candidates)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  reg_errcode_t err;\n  Idx node_idx, node;\n  re_sift_context_t local_sctx;\n  Idx first_idx = search_cur_bkref_entry (mctx, str_idx);\n\n  if (first_idx == -1)\n    return REG_NOERROR;\n\n  local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized.  */\n\n  for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)\n    {\n      Idx enabled_idx;\n      re_token_type_t type;\n      struct re_backref_cache_entry *entry;\n      node = candidates->elems[node_idx];\n      type = dfa->nodes[node].type;\n      /* Avoid infinite loop for the REs like \"()\\1+\".  */\n      if (node == sctx->last_node && str_idx == sctx->last_str_idx)\n\tcontinue;\n      if (type != OP_BACK_REF)\n\tcontinue;\n\n      entry = mctx->bkref_ents + first_idx;\n      enabled_idx = first_idx;\n      do\n\t{\n\t  Idx subexp_len;\n\t  Idx to_idx;\n\t  Idx dst_node;\n\t  bool ok;\n\t  re_dfastate_t *cur_state;\n\n\t  if (entry->node != node)\n\t    continue;\n\t  subexp_len = entry->subexp_to - entry->subexp_from;\n\t  to_idx = str_idx + subexp_len;\n\t  dst_node = (subexp_len ? dfa->nexts[node]\n\t\t      : dfa->edests[node].elems[0]);\n\n\t  if (to_idx > sctx->last_str_idx\n\t      || sctx->sifted_states[to_idx] == NULL\n\t      || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node)\n\t      || check_dst_limits (mctx, &sctx->limits, node,\n\t\t\t\t   str_idx, dst_node, to_idx))\n\t    continue;\n\n\t  if (local_sctx.sifted_states == NULL)\n\t    {\n\t      local_sctx = *sctx;\n\t      err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\tgoto free_return;\n\t    }\n\t  local_sctx.last_node = node;\n\t  local_sctx.last_str_idx = str_idx;\n\t  ok = re_node_set_insert (&local_sctx.limits, enabled_idx);\n\t  if (__glibc_unlikely (! ok))\n\t    {\n\t      err = REG_ESPACE;\n\t      goto free_return;\n\t    }\n\t  cur_state = local_sctx.sifted_states[str_idx];\n\t  err = sift_states_backward (mctx, &local_sctx);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    goto free_return;\n\t  if (sctx->limited_states != NULL)\n\t    {\n\t      err = merge_state_array (dfa, sctx->limited_states,\n\t\t\t\t       local_sctx.sifted_states,\n\t\t\t\t       str_idx + 1);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\tgoto free_return;\n\t    }\n\t  local_sctx.sifted_states[str_idx] = cur_state;\n\t  re_node_set_remove (&local_sctx.limits, enabled_idx);\n\n\t  /* mctx->bkref_ents may have changed, reload the pointer.  */\n\t  entry = mctx->bkref_ents + enabled_idx;\n\t}\n      while (enabled_idx++, entry++->more);\n    }\n  err = REG_NOERROR;\n free_return:\n  if (local_sctx.sifted_states != NULL)\n    {\n      re_node_set_free (&local_sctx.limits);\n    }\n\n  return err;\n}\n\n\n#ifdef RE_ENABLE_I18N\nstatic int\nsift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,\n\t\t     Idx node_idx, Idx str_idx, Idx max_str_idx)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  int naccepted;\n  /* Check the node can accept \"multi byte\".  */\n  naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx);\n  if (naccepted > 0 && str_idx + naccepted <= max_str_idx\n      && !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted],\n\t\t\t       dfa->nexts[node_idx]))\n    /* The node can't accept the \"multi byte\", or the\n       destination was already thrown away, then the node\n       couldn't accept the current input \"multi byte\".   */\n    naccepted = 0;\n  /* Otherwise, it is sure that the node could accept\n     'naccepted' bytes input.  */\n  return naccepted;\n}\n#endif /* RE_ENABLE_I18N */\n\n\f\n/* Functions for state transition.  */\n\n/* Return the next state to which the current state STATE will transit by\n   accepting the current input byte, and update STATE_LOG if necessary.\n   Return NULL on failure.\n   If STATE can accept a multibyte char/collating element/back reference\n   update the destination of STATE_LOG.  */\n\nstatic re_dfastate_t *\n__attribute_warn_unused_result__\ntransit_state (reg_errcode_t *err, re_match_context_t *mctx,\n\t       re_dfastate_t *state)\n{\n  re_dfastate_t **trtable;\n  unsigned char ch;\n\n#ifdef RE_ENABLE_I18N\n  /* If the current state can accept multibyte.  */\n  if (__glibc_unlikely (state->accept_mb))\n    {\n      *err = transit_state_mb (mctx, state);\n      if (__glibc_unlikely (*err != REG_NOERROR))\n\treturn NULL;\n    }\n#endif /* RE_ENABLE_I18N */\n\n  /* Then decide the next state with the single byte.  */\n#if 0\n  if (0)\n    /* don't use transition table  */\n    return transit_state_sb (err, mctx, state);\n#endif\n\n  /* Use transition table  */\n  ch = re_string_fetch_byte (&mctx->input);\n  for (;;)\n    {\n      trtable = state->trtable;\n      if (__glibc_likely (trtable != NULL))\n\treturn trtable[ch];\n\n      trtable = state->word_trtable;\n      if (__glibc_likely (trtable != NULL))\n\t{\n\t  unsigned int context;\n\t  context\n\t    = re_string_context_at (&mctx->input,\n\t\t\t\t    re_string_cur_idx (&mctx->input) - 1,\n\t\t\t\t    mctx->eflags);\n\t  if (IS_WORD_CONTEXT (context))\n\t    return trtable[ch + SBC_MAX];\n\t  else\n\t    return trtable[ch];\n\t}\n\n      if (!build_trtable (mctx->dfa, state))\n\t{\n\t  *err = REG_ESPACE;\n\t  return NULL;\n\t}\n\n      /* Retry, we now have a transition table.  */\n    }\n}\n\n/* Update the state_log if we need */\nstatic re_dfastate_t *\nmerge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx,\n\t\t      re_dfastate_t *next_state)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  Idx cur_idx = re_string_cur_idx (&mctx->input);\n\n  if (cur_idx > mctx->state_log_top)\n    {\n      mctx->state_log[cur_idx] = next_state;\n      mctx->state_log_top = cur_idx;\n    }\n  else if (mctx->state_log[cur_idx] == 0)\n    {\n      mctx->state_log[cur_idx] = next_state;\n    }\n  else\n    {\n      re_dfastate_t *pstate;\n      unsigned int context;\n      re_node_set next_nodes, *log_nodes, *table_nodes = NULL;\n      /* If (state_log[cur_idx] != 0), it implies that cur_idx is\n\t the destination of a multibyte char/collating element/\n\t back reference.  Then the next state is the union set of\n\t these destinations and the results of the transition table.  */\n      pstate = mctx->state_log[cur_idx];\n      log_nodes = pstate->entrance_nodes;\n      if (next_state != NULL)\n\t{\n\t  table_nodes = next_state->entrance_nodes;\n\t  *err = re_node_set_init_union (&next_nodes, table_nodes,\n\t\t\t\t\t     log_nodes);\n\t  if (__glibc_unlikely (*err != REG_NOERROR))\n\t    return NULL;\n\t}\n      else\n\tnext_nodes = *log_nodes;\n      /* Note: We already add the nodes of the initial state,\n\t then we don't need to add them here.  */\n\n      context = re_string_context_at (&mctx->input,\n\t\t\t\t      re_string_cur_idx (&mctx->input) - 1,\n\t\t\t\t      mctx->eflags);\n      next_state = mctx->state_log[cur_idx]\n\t= re_acquire_state_context (err, dfa, &next_nodes, context);\n      /* We don't need to check errors here, since the return value of\n\t this function is next_state and ERR is already set.  */\n\n      if (table_nodes != NULL)\n\tre_node_set_free (&next_nodes);\n    }\n\n  if (__glibc_unlikely (dfa->nbackref) && next_state != NULL)\n    {\n      /* Check OP_OPEN_SUBEXP in the current state in case that we use them\n\t later.  We must check them here, since the back references in the\n\t next state might use them.  */\n      *err = check_subexp_matching_top (mctx, &next_state->nodes,\n\t\t\t\t\tcur_idx);\n      if (__glibc_unlikely (*err != REG_NOERROR))\n\treturn NULL;\n\n      /* If the next state has back references.  */\n      if (next_state->has_backref)\n\t{\n\t  *err = transit_state_bkref (mctx, &next_state->nodes);\n\t  if (__glibc_unlikely (*err != REG_NOERROR))\n\t    return NULL;\n\t  next_state = mctx->state_log[cur_idx];\n\t}\n    }\n\n  return next_state;\n}\n\n/* Skip bytes in the input that correspond to part of a\n   multi-byte match, then look in the log for a state\n   from which to restart matching.  */\nstatic re_dfastate_t *\nfind_recover_state (reg_errcode_t *err, re_match_context_t *mctx)\n{\n  re_dfastate_t *cur_state;\n  do\n    {\n      Idx max = mctx->state_log_top;\n      Idx cur_str_idx = re_string_cur_idx (&mctx->input);\n\n      do\n\t{\n\t  if (++cur_str_idx > max)\n\t    return NULL;\n\t  re_string_skip_bytes (&mctx->input, 1);\n\t}\n      while (mctx->state_log[cur_str_idx] == NULL);\n\n      cur_state = merge_state_with_log (err, mctx, NULL);\n    }\n  while (*err == REG_NOERROR && cur_state == NULL);\n  return cur_state;\n}\n\n/* Helper functions for transit_state.  */\n\n/* From the node set CUR_NODES, pick up the nodes whose types are\n   OP_OPEN_SUBEXP and which have corresponding back references in the regular\n   expression. And register them to use them later for evaluating the\n   corresponding back references.  */\n\nstatic reg_errcode_t\ncheck_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes,\n\t\t\t   Idx str_idx)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  Idx node_idx;\n  reg_errcode_t err;\n\n  /* TODO: This isn't efficient.\n\t   Because there might be more than one nodes whose types are\n\t   OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all\n\t   nodes.\n\t   E.g. RE: (a){2}  */\n  for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx)\n    {\n      Idx node = cur_nodes->elems[node_idx];\n      if (dfa->nodes[node].type == OP_OPEN_SUBEXP\n\t  && dfa->nodes[node].opr.idx < BITSET_WORD_BITS\n\t  && (dfa->used_bkref_map\n\t      & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx)))\n\t{\n\t  err = match_ctx_add_subtop (mctx, node, str_idx);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\t}\n    }\n  return REG_NOERROR;\n}\n\n#if 0\n/* Return the next state to which the current state STATE will transit by\n   accepting the current input byte.  Return NULL on failure.  */\n\nstatic re_dfastate_t *\ntransit_state_sb (reg_errcode_t *err, re_match_context_t *mctx,\n\t\t  re_dfastate_t *state)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  re_node_set next_nodes;\n  re_dfastate_t *next_state;\n  Idx node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input);\n  unsigned int context;\n\n  *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);\n  if (__glibc_unlikely (*err != REG_NOERROR))\n    return NULL;\n  for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)\n    {\n      Idx cur_node = state->nodes.elems[node_cnt];\n      if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx))\n\t{\n\t  *err = re_node_set_merge (&next_nodes,\n\t\t\t\t    dfa->eclosures + dfa->nexts[cur_node]);\n\t  if (__glibc_unlikely (*err != REG_NOERROR))\n\t    {\n\t      re_node_set_free (&next_nodes);\n\t      return NULL;\n\t    }\n\t}\n    }\n  context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags);\n  next_state = re_acquire_state_context (err, dfa, &next_nodes, context);\n  /* We don't need to check errors here, since the return value of\n     this function is next_state and ERR is already set.  */\n\n  re_node_set_free (&next_nodes);\n  re_string_skip_bytes (&mctx->input, 1);\n  return next_state;\n}\n#endif\n\n#ifdef RE_ENABLE_I18N\nstatic reg_errcode_t\ntransit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  reg_errcode_t err;\n  Idx i;\n\n  for (i = 0; i < pstate->nodes.nelem; ++i)\n    {\n      re_node_set dest_nodes, *new_nodes;\n      Idx cur_node_idx = pstate->nodes.elems[i];\n      int naccepted;\n      Idx dest_idx;\n      unsigned int context;\n      re_dfastate_t *dest_state;\n\n      if (!dfa->nodes[cur_node_idx].accept_mb)\n\tcontinue;\n\n      if (dfa->nodes[cur_node_idx].constraint)\n\t{\n\t  context = re_string_context_at (&mctx->input,\n\t\t\t\t\t  re_string_cur_idx (&mctx->input),\n\t\t\t\t\t  mctx->eflags);\n\t  if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint,\n\t\t\t\t\t   context))\n\t    continue;\n\t}\n\n      /* How many bytes the node can accept?  */\n      naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input,\n\t\t\t\t\t   re_string_cur_idx (&mctx->input));\n      if (naccepted == 0)\n\tcontinue;\n\n      /* The node can accepts 'naccepted' bytes.  */\n      dest_idx = re_string_cur_idx (&mctx->input) + naccepted;\n      mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted\n\t\t\t       : mctx->max_mb_elem_len);\n      err = clean_state_log_if_needed (mctx, dest_idx);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\treturn err;\n      DEBUG_ASSERT (dfa->nexts[cur_node_idx] != -1);\n      new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx];\n\n      dest_state = mctx->state_log[dest_idx];\n      if (dest_state == NULL)\n\tdest_nodes = *new_nodes;\n      else\n\t{\n\t  err = re_node_set_init_union (&dest_nodes,\n\t\t\t\t\tdest_state->entrance_nodes, new_nodes);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\t}\n      context = re_string_context_at (&mctx->input, dest_idx - 1,\n\t\t\t\t      mctx->eflags);\n      mctx->state_log[dest_idx]\n\t= re_acquire_state_context (&err, dfa, &dest_nodes, context);\n      if (dest_state != NULL)\n\tre_node_set_free (&dest_nodes);\n      if (__glibc_unlikely (mctx->state_log[dest_idx] == NULL\n\t\t\t    && err != REG_NOERROR))\n\treturn err;\n    }\n  return REG_NOERROR;\n}\n#endif /* RE_ENABLE_I18N */\n\nstatic reg_errcode_t\ntransit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  reg_errcode_t err;\n  Idx i;\n  Idx cur_str_idx = re_string_cur_idx (&mctx->input);\n\n  for (i = 0; i < nodes->nelem; ++i)\n    {\n      Idx dest_str_idx, prev_nelem, bkc_idx;\n      Idx node_idx = nodes->elems[i];\n      unsigned int context;\n      const re_token_t *node = dfa->nodes + node_idx;\n      re_node_set *new_dest_nodes;\n\n      /* Check whether 'node' is a backreference or not.  */\n      if (node->type != OP_BACK_REF)\n\tcontinue;\n\n      if (node->constraint)\n\t{\n\t  context = re_string_context_at (&mctx->input, cur_str_idx,\n\t\t\t\t\t  mctx->eflags);\n\t  if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))\n\t    continue;\n\t}\n\n      /* 'node' is a backreference.\n\t Check the substring which the substring matched.  */\n      bkc_idx = mctx->nbkref_ents;\n      err = get_subexp (mctx, node_idx, cur_str_idx);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\tgoto free_return;\n\n      /* And add the epsilon closures (which is 'new_dest_nodes') of\n\t the backreference to appropriate state_log.  */\n      DEBUG_ASSERT (dfa->nexts[node_idx] != -1);\n      for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)\n\t{\n\t  Idx subexp_len;\n\t  re_dfastate_t *dest_state;\n\t  struct re_backref_cache_entry *bkref_ent;\n\t  bkref_ent = mctx->bkref_ents + bkc_idx;\n\t  if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx)\n\t    continue;\n\t  subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from;\n\t  new_dest_nodes = (subexp_len == 0\n\t\t\t    ? dfa->eclosures + dfa->edests[node_idx].elems[0]\n\t\t\t    : dfa->eclosures + dfa->nexts[node_idx]);\n\t  dest_str_idx = (cur_str_idx + bkref_ent->subexp_to\n\t\t\t  - bkref_ent->subexp_from);\n\t  context = re_string_context_at (&mctx->input, dest_str_idx - 1,\n\t\t\t\t\t  mctx->eflags);\n\t  dest_state = mctx->state_log[dest_str_idx];\n\t  prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0\n\t\t\t: mctx->state_log[cur_str_idx]->nodes.nelem);\n\t  /* Add 'new_dest_node' to state_log.  */\n\t  if (dest_state == NULL)\n\t    {\n\t      mctx->state_log[dest_str_idx]\n\t\t= re_acquire_state_context (&err, dfa, new_dest_nodes,\n\t\t\t\t\t    context);\n\t      if (__glibc_unlikely (mctx->state_log[dest_str_idx] == NULL\n\t\t\t\t    && err != REG_NOERROR))\n\t\tgoto free_return;\n\t    }\n\t  else\n\t    {\n\t      re_node_set dest_nodes;\n\t      err = re_node_set_init_union (&dest_nodes,\n\t\t\t\t\t    dest_state->entrance_nodes,\n\t\t\t\t\t    new_dest_nodes);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\t{\n\t\t  re_node_set_free (&dest_nodes);\n\t\t  goto free_return;\n\t\t}\n\t      mctx->state_log[dest_str_idx]\n\t\t= re_acquire_state_context (&err, dfa, &dest_nodes, context);\n\t      re_node_set_free (&dest_nodes);\n\t      if (__glibc_unlikely (mctx->state_log[dest_str_idx] == NULL\n\t\t\t\t    && err != REG_NOERROR))\n\t\tgoto free_return;\n\t    }\n\t  /* We need to check recursively if the backreference can epsilon\n\t     transit.  */\n\t  if (subexp_len == 0\n\t      && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem)\n\t    {\n\t      err = check_subexp_matching_top (mctx, new_dest_nodes,\n\t\t\t\t\t       cur_str_idx);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\tgoto free_return;\n\t      err = transit_state_bkref (mctx, new_dest_nodes);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\tgoto free_return;\n\t    }\n\t}\n    }\n  err = REG_NOERROR;\n free_return:\n  return err;\n}\n\n/* Enumerate all the candidates which the backreference BKREF_NODE can match\n   at BKREF_STR_IDX, and register them by match_ctx_add_entry().\n   Note that we might collect inappropriate candidates here.\n   However, the cost of checking them strictly here is too high, then we\n   delay these checking for prune_impossible_nodes().  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nget_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  Idx subexp_num, sub_top_idx;\n  const char *buf = (const char *) re_string_get_buffer (&mctx->input);\n  /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX.  */\n  Idx cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);\n  if (cache_idx != -1)\n    {\n      const struct re_backref_cache_entry *entry\n\t= mctx->bkref_ents + cache_idx;\n      do\n\tif (entry->node == bkref_node)\n\t  return REG_NOERROR; /* We already checked it.  */\n      while (entry++->more);\n    }\n\n  subexp_num = dfa->nodes[bkref_node].opr.idx;\n\n  /* For each sub expression  */\n  for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx)\n    {\n      reg_errcode_t err;\n      re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];\n      re_sub_match_last_t *sub_last;\n      Idx sub_last_idx, sl_str, bkref_str_off;\n\n      if (dfa->nodes[sub_top->node].opr.idx != subexp_num)\n\tcontinue; /* It isn't related.  */\n\n      sl_str = sub_top->str_idx;\n      bkref_str_off = bkref_str_idx;\n      /* At first, check the last node of sub expressions we already\n\t evaluated.  */\n      for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx)\n\t{\n\t  regoff_t sl_str_diff;\n\t  sub_last = sub_top->lasts[sub_last_idx];\n\t  sl_str_diff = sub_last->str_idx - sl_str;\n\t  /* The matched string by the sub expression match with the substring\n\t     at the back reference?  */\n\t  if (sl_str_diff > 0)\n\t    {\n\t      if (__glibc_unlikely (bkref_str_off + sl_str_diff\n\t\t\t\t    > mctx->input.valid_len))\n\t\t{\n\t\t  /* Not enough chars for a successful match.  */\n\t\t  if (bkref_str_off + sl_str_diff > mctx->input.len)\n\t\t    break;\n\n\t\t  err = clean_state_log_if_needed (mctx,\n\t\t\t\t\t\t   bkref_str_off\n\t\t\t\t\t\t   + sl_str_diff);\n\t\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t\t    return err;\n\t\t  buf = (const char *) re_string_get_buffer (&mctx->input);\n\t\t}\n\t      if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0)\n\t\t/* We don't need to search this sub expression any more.  */\n\t\tbreak;\n\t    }\n\t  bkref_str_off += sl_str_diff;\n\t  sl_str += sl_str_diff;\n\t  err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,\n\t\t\t\tbkref_str_idx);\n\n\t  /* Reload buf, since the preceding call might have reallocated\n\t     the buffer.  */\n\t  buf = (const char *) re_string_get_buffer (&mctx->input);\n\n\t  if (err == REG_NOMATCH)\n\t    continue;\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\t}\n\n      if (sub_last_idx < sub_top->nlasts)\n\tcontinue;\n      if (sub_last_idx > 0)\n\t++sl_str;\n      /* Then, search for the other last nodes of the sub expression.  */\n      for (; sl_str <= bkref_str_idx; ++sl_str)\n\t{\n\t  Idx cls_node;\n\t  regoff_t sl_str_off;\n\t  const re_node_set *nodes;\n\t  sl_str_off = sl_str - sub_top->str_idx;\n\t  /* The matched string by the sub expression match with the substring\n\t     at the back reference?  */\n\t  if (sl_str_off > 0)\n\t    {\n\t      if (__glibc_unlikely (bkref_str_off >= mctx->input.valid_len))\n\t\t{\n\t\t  /* If we are at the end of the input, we cannot match.  */\n\t\t  if (bkref_str_off >= mctx->input.len)\n\t\t    break;\n\n\t\t  err = extend_buffers (mctx, bkref_str_off + 1);\n\t\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t\t    return err;\n\n\t\t  buf = (const char *) re_string_get_buffer (&mctx->input);\n\t\t}\n\t      if (buf [bkref_str_off++] != buf[sl_str - 1])\n\t\tbreak; /* We don't need to search this sub expression\n\t\t\t  any more.  */\n\t    }\n\t  if (mctx->state_log[sl_str] == NULL)\n\t    continue;\n\t  /* Does this state have a ')' of the sub expression?  */\n\t  nodes = &mctx->state_log[sl_str]->nodes;\n\t  cls_node = find_subexp_node (dfa, nodes, subexp_num,\n\t\t\t\t       OP_CLOSE_SUBEXP);\n\t  if (cls_node == -1)\n\t    continue; /* No.  */\n\t  if (sub_top->path == NULL)\n\t    {\n\t      sub_top->path = calloc (sizeof (state_array_t),\n\t\t\t\t      sl_str - sub_top->str_idx + 1);\n\t      if (sub_top->path == NULL)\n\t\treturn REG_ESPACE;\n\t    }\n\t  /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node\n\t     in the current context?  */\n\t  err = check_arrival (mctx, sub_top->path, sub_top->node,\n\t\t\t       sub_top->str_idx, cls_node, sl_str,\n\t\t\t       OP_CLOSE_SUBEXP);\n\t  if (err == REG_NOMATCH)\n\t      continue;\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t      return err;\n\t  sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str);\n\t  if (__glibc_unlikely (sub_last == NULL))\n\t    return REG_ESPACE;\n\t  err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,\n\t\t\t\tbkref_str_idx);\n\t  buf = (const char *) re_string_get_buffer (&mctx->input);\n\t  if (err == REG_NOMATCH)\n\t    continue;\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\t}\n    }\n  return REG_NOERROR;\n}\n\n/* Helper functions for get_subexp().  */\n\n/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR.\n   If it can arrive, register the sub expression expressed with SUB_TOP\n   and SUB_LAST.  */\n\nstatic reg_errcode_t\nget_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top,\n\t\tre_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str)\n{\n  reg_errcode_t err;\n  Idx to_idx;\n  /* Can the subexpression arrive the back reference?  */\n  err = check_arrival (mctx, &sub_last->path, sub_last->node,\n\t\t       sub_last->str_idx, bkref_node, bkref_str,\n\t\t       OP_OPEN_SUBEXP);\n  if (err != REG_NOERROR)\n    return err;\n  err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx,\n\t\t\t     sub_last->str_idx);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    return err;\n  to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;\n  return clean_state_log_if_needed (mctx, to_idx);\n}\n\n/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX.\n   Search '(' if FL_OPEN, or search ')' otherwise.\n   TODO: This function isn't efficient...\n\t Because there might be more than one nodes whose types are\n\t OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all\n\t nodes.\n\t E.g. RE: (a){2}  */\n\nstatic Idx\nfind_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,\n\t\t  Idx subexp_idx, int type)\n{\n  Idx cls_idx;\n  for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx)\n    {\n      Idx cls_node = nodes->elems[cls_idx];\n      const re_token_t *node = dfa->nodes + cls_node;\n      if (node->type == type\n\t  && node->opr.idx == subexp_idx)\n\treturn cls_node;\n    }\n  return -1;\n}\n\n/* Check whether the node TOP_NODE at TOP_STR can arrive to the node\n   LAST_NODE at LAST_STR.  We record the path onto PATH since it will be\n   heavily reused.\n   Return REG_NOERROR if it can arrive, REG_NOMATCH if it cannot,\n   REG_ESPACE if memory is exhausted.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\ncheck_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node,\n\t       Idx top_str, Idx last_node, Idx last_str, int type)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  reg_errcode_t err = REG_NOERROR;\n  Idx subexp_num, backup_cur_idx, str_idx, null_cnt;\n  re_dfastate_t *cur_state = NULL;\n  re_node_set *cur_nodes, next_nodes;\n  re_dfastate_t **backup_state_log;\n  unsigned int context;\n\n  subexp_num = dfa->nodes[top_node].opr.idx;\n  /* Extend the buffer if we need.  */\n  if (__glibc_unlikely (path->alloc < last_str + mctx->max_mb_elem_len + 1))\n    {\n      re_dfastate_t **new_array;\n      Idx old_alloc = path->alloc;\n      Idx incr_alloc = last_str + mctx->max_mb_elem_len + 1;\n      Idx new_alloc;\n      if (__glibc_unlikely (IDX_MAX - old_alloc < incr_alloc))\n\treturn REG_ESPACE;\n      new_alloc = old_alloc + incr_alloc;\n      if (__glibc_unlikely (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc))\n\treturn REG_ESPACE;\n      new_array = re_realloc (path->array, re_dfastate_t *, new_alloc);\n      if (__glibc_unlikely (new_array == NULL))\n\treturn REG_ESPACE;\n      path->array = new_array;\n      path->alloc = new_alloc;\n      memset (new_array + old_alloc, '\\0',\n\t      sizeof (re_dfastate_t *) * (path->alloc - old_alloc));\n    }\n\n  str_idx = path->next_idx ? path->next_idx : top_str;\n\n  /* Temporary modify MCTX.  */\n  backup_state_log = mctx->state_log;\n  backup_cur_idx = mctx->input.cur_idx;\n  mctx->state_log = path->array;\n  mctx->input.cur_idx = str_idx;\n\n  /* Setup initial node set.  */\n  context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);\n  if (str_idx == top_str)\n    {\n      err = re_node_set_init_1 (&next_nodes, top_node);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\treturn err;\n      err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);\n      if (__glibc_unlikely (err != REG_NOERROR))\n\t{\n\t  re_node_set_free (&next_nodes);\n\t  return err;\n\t}\n    }\n  else\n    {\n      cur_state = mctx->state_log[str_idx];\n      if (cur_state && cur_state->has_backref)\n\t{\n\t  err = re_node_set_init_copy (&next_nodes, &cur_state->nodes);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\t}\n      else\n\tre_node_set_init_empty (&next_nodes);\n    }\n  if (str_idx == top_str || (cur_state && cur_state->has_backref))\n    {\n      if (next_nodes.nelem)\n\t{\n\t  err = expand_bkref_cache (mctx, &next_nodes, str_idx,\n\t\t\t\t    subexp_num, type);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    {\n\t      re_node_set_free (&next_nodes);\n\t      return err;\n\t    }\n\t}\n      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);\n      if (__glibc_unlikely (cur_state == NULL && err != REG_NOERROR))\n\t{\n\t  re_node_set_free (&next_nodes);\n\t  return err;\n\t}\n      mctx->state_log[str_idx] = cur_state;\n    }\n\n  for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;)\n    {\n      re_node_set_empty (&next_nodes);\n      if (mctx->state_log[str_idx + 1])\n\t{\n\t  err = re_node_set_merge (&next_nodes,\n\t\t\t\t   &mctx->state_log[str_idx + 1]->nodes);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    {\n\t      re_node_set_free (&next_nodes);\n\t      return err;\n\t    }\n\t}\n      if (cur_state)\n\t{\n\t  err = check_arrival_add_next_nodes (mctx, str_idx,\n\t\t\t\t\t      &cur_state->non_eps_nodes,\n\t\t\t\t\t      &next_nodes);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    {\n\t      re_node_set_free (&next_nodes);\n\t      return err;\n\t    }\n\t}\n      ++str_idx;\n      if (next_nodes.nelem)\n\t{\n\t  err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    {\n\t      re_node_set_free (&next_nodes);\n\t      return err;\n\t    }\n\t  err = expand_bkref_cache (mctx, &next_nodes, str_idx,\n\t\t\t\t    subexp_num, type);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    {\n\t      re_node_set_free (&next_nodes);\n\t      return err;\n\t    }\n\t}\n      context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);\n      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);\n      if (__glibc_unlikely (cur_state == NULL && err != REG_NOERROR))\n\t{\n\t  re_node_set_free (&next_nodes);\n\t  return err;\n\t}\n      mctx->state_log[str_idx] = cur_state;\n      null_cnt = cur_state == NULL ? null_cnt + 1 : 0;\n    }\n  re_node_set_free (&next_nodes);\n  cur_nodes = (mctx->state_log[last_str] == NULL ? NULL\n\t       : &mctx->state_log[last_str]->nodes);\n  path->next_idx = str_idx;\n\n  /* Fix MCTX.  */\n  mctx->state_log = backup_state_log;\n  mctx->input.cur_idx = backup_cur_idx;\n\n  /* Then check the current node set has the node LAST_NODE.  */\n  if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node))\n    return REG_NOERROR;\n\n  return REG_NOMATCH;\n}\n\n/* Helper functions for check_arrival.  */\n\n/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them\n   to NEXT_NODES.\n   TODO: This function is similar to the functions transit_state*(),\n\t however this function has many additional works.\n\t Can't we unify them?  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\ncheck_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx,\n\t\t\t      re_node_set *cur_nodes, re_node_set *next_nodes)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  bool ok;\n  Idx cur_idx;\n#ifdef RE_ENABLE_I18N\n  reg_errcode_t err = REG_NOERROR;\n#endif\n  re_node_set union_set;\n  re_node_set_init_empty (&union_set);\n  for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)\n    {\n      int naccepted = 0;\n      Idx cur_node = cur_nodes->elems[cur_idx];\n      DEBUG_ASSERT (!IS_EPSILON_NODE (dfa->nodes[cur_node].type));\n\n#ifdef RE_ENABLE_I18N\n      /* If the node may accept \"multi byte\".  */\n      if (dfa->nodes[cur_node].accept_mb)\n\t{\n\t  naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input,\n\t\t\t\t\t       str_idx);\n\t  if (naccepted > 1)\n\t    {\n\t      re_dfastate_t *dest_state;\n\t      Idx next_node = dfa->nexts[cur_node];\n\t      Idx next_idx = str_idx + naccepted;\n\t      dest_state = mctx->state_log[next_idx];\n\t      re_node_set_empty (&union_set);\n\t      if (dest_state)\n\t\t{\n\t\t  err = re_node_set_merge (&union_set, &dest_state->nodes);\n\t\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t\t    {\n\t\t      re_node_set_free (&union_set);\n\t\t      return err;\n\t\t    }\n\t\t}\n\t      ok = re_node_set_insert (&union_set, next_node);\n\t      if (__glibc_unlikely (! ok))\n\t\t{\n\t\t  re_node_set_free (&union_set);\n\t\t  return REG_ESPACE;\n\t\t}\n\t      mctx->state_log[next_idx] = re_acquire_state (&err, dfa,\n\t\t\t\t\t\t\t    &union_set);\n\t      if (__glibc_unlikely (mctx->state_log[next_idx] == NULL\n\t\t\t\t    && err != REG_NOERROR))\n\t\t{\n\t\t  re_node_set_free (&union_set);\n\t\t  return err;\n\t\t}\n\t    }\n\t}\n#endif /* RE_ENABLE_I18N */\n      if (naccepted\n\t  || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))\n\t{\n\t  ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);\n\t  if (__glibc_unlikely (! ok))\n\t    {\n\t      re_node_set_free (&union_set);\n\t      return REG_ESPACE;\n\t    }\n\t}\n    }\n  re_node_set_free (&union_set);\n  return REG_NOERROR;\n}\n\n/* For all the nodes in CUR_NODES, add the epsilon closures of them to\n   CUR_NODES, however exclude the nodes which are:\n    - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN.\n    - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN.\n*/\n\nstatic reg_errcode_t\ncheck_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes,\n\t\t\t  Idx ex_subexp, int type)\n{\n  reg_errcode_t err;\n  Idx idx, outside_node;\n  re_node_set new_nodes;\n  DEBUG_ASSERT (cur_nodes->nelem);\n  err = re_node_set_alloc (&new_nodes, cur_nodes->nelem);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    return err;\n  /* Create a new node set NEW_NODES with the nodes which are epsilon\n     closures of the node in CUR_NODES.  */\n\n  for (idx = 0; idx < cur_nodes->nelem; ++idx)\n    {\n      Idx cur_node = cur_nodes->elems[idx];\n      const re_node_set *eclosure = dfa->eclosures + cur_node;\n      outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type);\n      if (outside_node == -1)\n\t{\n\t  /* There are no problematic nodes, just merge them.  */\n\t  err = re_node_set_merge (&new_nodes, eclosure);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    {\n\t      re_node_set_free (&new_nodes);\n\t      return err;\n\t    }\n\t}\n      else\n\t{\n\t  /* There are problematic nodes, re-calculate incrementally.  */\n\t  err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node,\n\t\t\t\t\t      ex_subexp, type);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    {\n\t      re_node_set_free (&new_nodes);\n\t      return err;\n\t    }\n\t}\n    }\n  re_node_set_free (cur_nodes);\n  *cur_nodes = new_nodes;\n  return REG_NOERROR;\n}\n\n/* Helper function for check_arrival_expand_ecl.\n   Check incrementally the epsilon closure of TARGET, and if it isn't\n   problematic append it to DST_NODES.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\ncheck_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,\n\t\t\t      Idx target, Idx ex_subexp, int type)\n{\n  Idx cur_node;\n  for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);)\n    {\n      bool ok;\n\n      if (dfa->nodes[cur_node].type == type\n\t  && dfa->nodes[cur_node].opr.idx == ex_subexp)\n\t{\n\t  if (type == OP_CLOSE_SUBEXP)\n\t    {\n\t      ok = re_node_set_insert (dst_nodes, cur_node);\n\t      if (__glibc_unlikely (! ok))\n\t\treturn REG_ESPACE;\n\t    }\n\t  break;\n\t}\n      ok = re_node_set_insert (dst_nodes, cur_node);\n      if (__glibc_unlikely (! ok))\n\treturn REG_ESPACE;\n      if (dfa->edests[cur_node].nelem == 0)\n\tbreak;\n      if (dfa->edests[cur_node].nelem == 2)\n\t{\n\t  reg_errcode_t err;\n\t  err = check_arrival_expand_ecl_sub (dfa, dst_nodes,\n\t\t\t\t\t      dfa->edests[cur_node].elems[1],\n\t\t\t\t\t      ex_subexp, type);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    return err;\n\t}\n      cur_node = dfa->edests[cur_node].elems[0];\n    }\n  return REG_NOERROR;\n}\n\n\n/* For all the back references in the current state, calculate the\n   destination of the back references by the appropriate entry\n   in MCTX->BKREF_ENTS.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nexpand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,\n\t\t    Idx cur_str, Idx subexp_num, int type)\n{\n  const re_dfa_t *const dfa = mctx->dfa;\n  reg_errcode_t err;\n  Idx cache_idx_start = search_cur_bkref_entry (mctx, cur_str);\n  struct re_backref_cache_entry *ent;\n\n  if (cache_idx_start == -1)\n    return REG_NOERROR;\n\n restart:\n  ent = mctx->bkref_ents + cache_idx_start;\n  do\n    {\n      Idx to_idx, next_node;\n\n      /* Is this entry ENT is appropriate?  */\n      if (!re_node_set_contains (cur_nodes, ent->node))\n\tcontinue; /* No.  */\n\n      to_idx = cur_str + ent->subexp_to - ent->subexp_from;\n      /* Calculate the destination of the back reference, and append it\n\t to MCTX->STATE_LOG.  */\n      if (to_idx == cur_str)\n\t{\n\t  /* The backreference did epsilon transit, we must re-check all the\n\t     node in the current state.  */\n\t  re_node_set new_dests;\n\t  reg_errcode_t err2, err3;\n\t  next_node = dfa->edests[ent->node].elems[0];\n\t  if (re_node_set_contains (cur_nodes, next_node))\n\t    continue;\n\t  err = re_node_set_init_1 (&new_dests, next_node);\n\t  err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type);\n\t  err3 = re_node_set_merge (cur_nodes, &new_dests);\n\t  re_node_set_free (&new_dests);\n\t  if (__glibc_unlikely (err != REG_NOERROR || err2 != REG_NOERROR\n\t\t\t\t|| err3 != REG_NOERROR))\n\t    {\n\t      err = (err != REG_NOERROR ? err\n\t\t     : (err2 != REG_NOERROR ? err2 : err3));\n\t      return err;\n\t    }\n\t  /* TODO: It is still inefficient...  */\n\t  goto restart;\n\t}\n      else\n\t{\n\t  re_node_set union_set;\n\t  next_node = dfa->nexts[ent->node];\n\t  if (mctx->state_log[to_idx])\n\t    {\n\t      bool ok;\n\t      if (re_node_set_contains (&mctx->state_log[to_idx]->nodes,\n\t\t\t\t\tnext_node))\n\t\tcontinue;\n\t      err = re_node_set_init_copy (&union_set,\n\t\t\t\t\t   &mctx->state_log[to_idx]->nodes);\n\t      ok = re_node_set_insert (&union_set, next_node);\n\t      if (__glibc_unlikely (err != REG_NOERROR || ! ok))\n\t\t{\n\t\t  re_node_set_free (&union_set);\n\t\t  err = err != REG_NOERROR ? err : REG_ESPACE;\n\t\t  return err;\n\t\t}\n\t    }\n\t  else\n\t    {\n\t      err = re_node_set_init_1 (&union_set, next_node);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\treturn err;\n\t    }\n\t  mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set);\n\t  re_node_set_free (&union_set);\n\t  if (__glibc_unlikely (mctx->state_log[to_idx] == NULL\n\t\t\t\t&& err != REG_NOERROR))\n\t    return err;\n\t}\n    }\n  while (ent++->more);\n  return REG_NOERROR;\n}\n\n/* Build transition table for the state.\n   Return true if successful.  */\n\nstatic bool __attribute_noinline__\nbuild_trtable (const re_dfa_t *dfa, re_dfastate_t *state)\n{\n  reg_errcode_t err;\n  Idx i, j;\n  int ch;\n  bool need_word_trtable = false;\n  bitset_word_t elem, mask;\n  Idx ndests; /* Number of the destination states from 'state'.  */\n  re_dfastate_t **trtable;\n  re_dfastate_t *dest_states[SBC_MAX];\n  re_dfastate_t *dest_states_word[SBC_MAX];\n  re_dfastate_t *dest_states_nl[SBC_MAX];\n  re_node_set follows;\n  bitset_t acceptable;\n\n  /* We build DFA states which corresponds to the destination nodes\n     from 'state'.  'dests_node[i]' represents the nodes which i-th\n     destination state contains, and 'dests_ch[i]' represents the\n     characters which i-th destination state accepts.  */\n  re_node_set dests_node[SBC_MAX];\n  bitset_t dests_ch[SBC_MAX];\n\n  /* Initialize transition table.  */\n  state->word_trtable = state->trtable = NULL;\n\n  /* At first, group all nodes belonging to 'state' into several\n     destinations.  */\n  ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);\n  if (__glibc_unlikely (ndests <= 0))\n    {\n      /* Return false in case of an error, true otherwise.  */\n      if (ndests == 0)\n\t{\n\t  state->trtable = (re_dfastate_t **)\n\t    calloc (sizeof (re_dfastate_t *), SBC_MAX);\n          if (__glibc_unlikely (state->trtable == NULL))\n            return false;\n\t  return true;\n\t}\n      return false;\n    }\n\n  err = re_node_set_alloc (&follows, ndests + 1);\n  if (__glibc_unlikely (err != REG_NOERROR))\n    {\n    out_free:\n      re_node_set_free (&follows);\n      for (i = 0; i < ndests; ++i)\n\tre_node_set_free (dests_node + i);\n      return false;\n    }\n\n  bitset_empty (acceptable);\n\n  /* Then build the states for all destinations.  */\n  for (i = 0; i < ndests; ++i)\n    {\n      Idx next_node;\n      re_node_set_empty (&follows);\n      /* Merge the follows of this destination states.  */\n      for (j = 0; j < dests_node[i].nelem; ++j)\n\t{\n\t  next_node = dfa->nexts[dests_node[i].elems[j]];\n\t  if (next_node != -1)\n\t    {\n\t      err = re_node_set_merge (&follows, dfa->eclosures + next_node);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\tgoto out_free;\n\t    }\n\t}\n      dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);\n      if (__glibc_unlikely (dest_states[i] == NULL && err != REG_NOERROR))\n\tgoto out_free;\n      /* If the new state has context constraint,\n\t build appropriate states for these contexts.  */\n      if (dest_states[i]->has_constraint)\n\t{\n\t  dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,\n\t\t\t\t\t\t\t  CONTEXT_WORD);\n\t  if (__glibc_unlikely (dest_states_word[i] == NULL\n\t\t\t\t&& err != REG_NOERROR))\n\t    goto out_free;\n\n\t  if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)\n\t    need_word_trtable = true;\n\n\t  dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,\n\t\t\t\t\t\t\tCONTEXT_NEWLINE);\n\t  if (__glibc_unlikely (dest_states_nl[i] == NULL && err != REG_NOERROR))\n\t    goto out_free;\n\t}\n      else\n\t{\n\t  dest_states_word[i] = dest_states[i];\n\t  dest_states_nl[i] = dest_states[i];\n\t}\n      bitset_merge (acceptable, dests_ch[i]);\n    }\n\n  if (!__glibc_unlikely (need_word_trtable))\n    {\n      /* We don't care about whether the following character is a word\n\t character, or we are in a single-byte character set so we can\n\t discern by looking at the character code: allocate a\n\t 256-entry transition table.  */\n      trtable = state->trtable =\n\t(re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);\n      if (__glibc_unlikely (trtable == NULL))\n\tgoto out_free;\n\n      /* For all characters ch...:  */\n      for (i = 0; i < BITSET_WORDS; ++i)\n\tfor (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;\n\t     elem;\n\t     mask <<= 1, elem >>= 1, ++ch)\n\t  if (__glibc_unlikely (elem & 1))\n\t    {\n\t      /* There must be exactly one destination which accepts\n\t\t character ch.  See group_nodes_into_DFAstates.  */\n\t      for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)\n\t\t;\n\n\t      /* j-th destination accepts the word character ch.  */\n\t      if (dfa->word_char[i] & mask)\n\t\ttrtable[ch] = dest_states_word[j];\n\t      else\n\t\ttrtable[ch] = dest_states[j];\n\t    }\n    }\n  else\n    {\n      /* We care about whether the following character is a word\n\t character, and we are in a multi-byte character set: discern\n\t by looking at the character code: build two 256-entry\n\t transition tables, one starting at trtable[0] and one\n\t starting at trtable[SBC_MAX].  */\n      trtable = state->word_trtable =\n\t(re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);\n      if (__glibc_unlikely (trtable == NULL))\n\tgoto out_free;\n\n      /* For all characters ch...:  */\n      for (i = 0; i < BITSET_WORDS; ++i)\n\tfor (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;\n\t     elem;\n\t     mask <<= 1, elem >>= 1, ++ch)\n\t  if (__glibc_unlikely (elem & 1))\n\t    {\n\t      /* There must be exactly one destination which accepts\n\t\t character ch.  See group_nodes_into_DFAstates.  */\n\t      for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)\n\t\t;\n\n\t      /* j-th destination accepts the word character ch.  */\n\t      trtable[ch] = dest_states[j];\n\t      trtable[ch + SBC_MAX] = dest_states_word[j];\n\t    }\n    }\n\n  /* new line */\n  if (bitset_contain (acceptable, NEWLINE_CHAR))\n    {\n      /* The current state accepts newline character.  */\n      for (j = 0; j < ndests; ++j)\n\tif (bitset_contain (dests_ch[j], NEWLINE_CHAR))\n\t  {\n\t    /* k-th destination accepts newline character.  */\n\t    trtable[NEWLINE_CHAR] = dest_states_nl[j];\n\t    if (need_word_trtable)\n\t      trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j];\n\t    /* There must be only one destination which accepts\n\t       newline.  See group_nodes_into_DFAstates.  */\n\t    break;\n\t  }\n    }\n\n  re_node_set_free (&follows);\n  for (i = 0; i < ndests; ++i)\n    re_node_set_free (dests_node + i);\n  return true;\n}\n\n/* Group all nodes belonging to STATE into several destinations.\n   Then for all destinations, set the nodes belonging to the destination\n   to DESTS_NODE[i] and set the characters accepted by the destination\n   to DEST_CH[i].  Return the number of destinations if successful,\n   -1 on internal error.  */\n\nstatic Idx\ngroup_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,\n\t\t\t    re_node_set *dests_node, bitset_t *dests_ch)\n{\n  reg_errcode_t err;\n  bool ok;\n  Idx i, j, k;\n  Idx ndests; /* Number of the destinations from 'state'.  */\n  bitset_t accepts; /* Characters a node can accept.  */\n  const re_node_set *cur_nodes = &state->nodes;\n  bitset_empty (accepts);\n  ndests = 0;\n\n  /* For all the nodes belonging to 'state',  */\n  for (i = 0; i < cur_nodes->nelem; ++i)\n    {\n      re_token_t *node = &dfa->nodes[cur_nodes->elems[i]];\n      re_token_type_t type = node->type;\n      unsigned int constraint = node->constraint;\n\n      /* Enumerate all single byte character this node can accept.  */\n      if (type == CHARACTER)\n\tbitset_set (accepts, node->opr.c);\n      else if (type == SIMPLE_BRACKET)\n\t{\n\t  bitset_merge (accepts, node->opr.sbcset);\n\t}\n      else if (type == OP_PERIOD)\n\t{\n#ifdef RE_ENABLE_I18N\n\t  if (dfa->mb_cur_max > 1)\n\t    bitset_merge (accepts, dfa->sb_char);\n\t  else\n#endif\n\t    bitset_set_all (accepts);\n\t  if (!(dfa->syntax & RE_DOT_NEWLINE))\n\t    bitset_clear (accepts, '\\n');\n\t  if (dfa->syntax & RE_DOT_NOT_NULL)\n\t    bitset_clear (accepts, '\\0');\n\t}\n#ifdef RE_ENABLE_I18N\n      else if (type == OP_UTF8_PERIOD)\n\t{\n\t  if (ASCII_CHARS % BITSET_WORD_BITS == 0)\n\t    memset (accepts, -1, ASCII_CHARS / CHAR_BIT);\n\t  else\n\t    bitset_merge (accepts, utf8_sb_map);\n\t  if (!(dfa->syntax & RE_DOT_NEWLINE))\n\t    bitset_clear (accepts, '\\n');\n\t  if (dfa->syntax & RE_DOT_NOT_NULL)\n\t    bitset_clear (accepts, '\\0');\n\t}\n#endif\n      else\n\tcontinue;\n\n      /* Check the 'accepts' and sift the characters which are not\n\t match it the context.  */\n      if (constraint)\n\t{\n\t  if (constraint & NEXT_NEWLINE_CONSTRAINT)\n\t    {\n\t      bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR);\n\t      bitset_empty (accepts);\n\t      if (accepts_newline)\n\t\tbitset_set (accepts, NEWLINE_CHAR);\n\t      else\n\t\tcontinue;\n\t    }\n\t  if (constraint & NEXT_ENDBUF_CONSTRAINT)\n\t    {\n\t      bitset_empty (accepts);\n\t      continue;\n\t    }\n\n\t  if (constraint & NEXT_WORD_CONSTRAINT)\n\t    {\n\t      bitset_word_t any_set = 0;\n\t      if (type == CHARACTER && !node->word_char)\n\t\t{\n\t\t  bitset_empty (accepts);\n\t\t  continue;\n\t\t}\n#ifdef RE_ENABLE_I18N\n\t      if (dfa->mb_cur_max > 1)\n\t\tfor (j = 0; j < BITSET_WORDS; ++j)\n\t\t  any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));\n\t      else\n#endif\n\t\tfor (j = 0; j < BITSET_WORDS; ++j)\n\t\t  any_set |= (accepts[j] &= dfa->word_char[j]);\n\t      if (!any_set)\n\t\tcontinue;\n\t    }\n\t  if (constraint & NEXT_NOTWORD_CONSTRAINT)\n\t    {\n\t      bitset_word_t any_set = 0;\n\t      if (type == CHARACTER && node->word_char)\n\t\t{\n\t\t  bitset_empty (accepts);\n\t\t  continue;\n\t\t}\n#ifdef RE_ENABLE_I18N\n\t      if (dfa->mb_cur_max > 1)\n\t\tfor (j = 0; j < BITSET_WORDS; ++j)\n\t\t  any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));\n\t      else\n#endif\n\t\tfor (j = 0; j < BITSET_WORDS; ++j)\n\t\t  any_set |= (accepts[j] &= ~dfa->word_char[j]);\n\t      if (!any_set)\n\t\tcontinue;\n\t    }\n\t}\n\n      /* Then divide 'accepts' into DFA states, or create a new\n\t state.  Above, we make sure that accepts is not empty.  */\n      for (j = 0; j < ndests; ++j)\n\t{\n\t  bitset_t intersec; /* Intersection sets, see below.  */\n\t  bitset_t remains;\n\t  /* Flags, see below.  */\n\t  bitset_word_t has_intersec, not_subset, not_consumed;\n\n\t  /* Optimization, skip if this state doesn't accept the character.  */\n\t  if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))\n\t    continue;\n\n\t  /* Enumerate the intersection set of this state and 'accepts'.  */\n\t  has_intersec = 0;\n\t  for (k = 0; k < BITSET_WORDS; ++k)\n\t    has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k];\n\t  /* And skip if the intersection set is empty.  */\n\t  if (!has_intersec)\n\t    continue;\n\n\t  /* Then check if this state is a subset of 'accepts'.  */\n\t  not_subset = not_consumed = 0;\n\t  for (k = 0; k < BITSET_WORDS; ++k)\n\t    {\n\t      not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k];\n\t      not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k];\n\t    }\n\n\t  /* If this state isn't a subset of 'accepts', create a\n\t     new group state, which has the 'remains'. */\n\t  if (not_subset)\n\t    {\n\t      bitset_copy (dests_ch[ndests], remains);\n\t      bitset_copy (dests_ch[j], intersec);\n\t      err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);\n\t      if (__glibc_unlikely (err != REG_NOERROR))\n\t\tgoto error_return;\n\t      ++ndests;\n\t    }\n\n\t  /* Put the position in the current group. */\n\t  ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);\n\t  if (__glibc_unlikely (! ok))\n\t    goto error_return;\n\n\t  /* If all characters are consumed, go to next node. */\n\t  if (!not_consumed)\n\t    break;\n\t}\n      /* Some characters remain, create a new group. */\n      if (j == ndests)\n\t{\n\t  bitset_copy (dests_ch[ndests], accepts);\n\t  err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);\n\t  if (__glibc_unlikely (err != REG_NOERROR))\n\t    goto error_return;\n\t  ++ndests;\n\t  bitset_empty (accepts);\n\t}\n    }\n  assume (ndests <= SBC_MAX);\n  return ndests;\n error_return:\n  for (j = 0; j < ndests; ++j)\n    re_node_set_free (dests_node + j);\n  return -1;\n}\n\n#ifdef RE_ENABLE_I18N\n/* Check how many bytes the node 'dfa->nodes[node_idx]' accepts.\n   Return the number of the bytes the node accepts.\n   STR_IDX is the current index of the input string.\n\n   This function handles the nodes which can accept one character, or\n   one collating element like '.', '[a-z]', opposite to the other nodes\n   can only accept one byte.  */\n\n# ifdef _LIBC\n#  include <locale/weight.h>\n# endif\n\nstatic int\ncheck_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,\n\t\t\t const re_string_t *input, Idx str_idx)\n{\n  const re_token_t *node = dfa->nodes + node_idx;\n  int char_len, elem_len;\n  Idx i;\n\n  if (__glibc_unlikely (node->type == OP_UTF8_PERIOD))\n    {\n      unsigned char c = re_string_byte_at (input, str_idx), d;\n      if (__glibc_likely (c < 0xc2))\n\treturn 0;\n\n      if (str_idx + 2 > input->len)\n\treturn 0;\n\n      d = re_string_byte_at (input, str_idx + 1);\n      if (c < 0xe0)\n\treturn (d < 0x80 || d > 0xbf) ? 0 : 2;\n      else if (c < 0xf0)\n\t{\n\t  char_len = 3;\n\t  if (c == 0xe0 && d < 0xa0)\n\t    return 0;\n\t}\n      else if (c < 0xf8)\n\t{\n\t  char_len = 4;\n\t  if (c == 0xf0 && d < 0x90)\n\t    return 0;\n\t}\n      else if (c < 0xfc)\n\t{\n\t  char_len = 5;\n\t  if (c == 0xf8 && d < 0x88)\n\t    return 0;\n\t}\n      else if (c < 0xfe)\n\t{\n\t  char_len = 6;\n\t  if (c == 0xfc && d < 0x84)\n\t    return 0;\n\t}\n      else\n\treturn 0;\n\n      if (str_idx + char_len > input->len)\n\treturn 0;\n\n      for (i = 1; i < char_len; ++i)\n\t{\n\t  d = re_string_byte_at (input, str_idx + i);\n\t  if (d < 0x80 || d > 0xbf)\n\t    return 0;\n\t}\n      return char_len;\n    }\n\n  char_len = re_string_char_size_at (input, str_idx);\n  if (node->type == OP_PERIOD)\n    {\n      if (char_len <= 1)\n\treturn 0;\n      /* FIXME: I don't think this if is needed, as both '\\n'\n\t and '\\0' are char_len == 1.  */\n      /* '.' accepts any one character except the following two cases.  */\n      if ((!(dfa->syntax & RE_DOT_NEWLINE)\n\t   && re_string_byte_at (input, str_idx) == '\\n')\n\t  || ((dfa->syntax & RE_DOT_NOT_NULL)\n\t      && re_string_byte_at (input, str_idx) == '\\0'))\n\treturn 0;\n      return char_len;\n    }\n\n  elem_len = re_string_elem_size_at (input, str_idx);\n  if ((elem_len <= 1 && char_len <= 1) || char_len == 0)\n    return 0;\n\n  if (node->type == COMPLEX_BRACKET)\n    {\n      const re_charset_t *cset = node->opr.mbcset;\n# ifdef _LIBC\n      const unsigned char *pin\n\t= ((const unsigned char *) re_string_get_buffer (input) + str_idx);\n      Idx j;\n      uint32_t nrules;\n# endif /* _LIBC */\n      int match_len = 0;\n      wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)\n\t\t    ? re_string_wchar_at (input, str_idx) : 0);\n\n      /* match with multibyte character?  */\n      for (i = 0; i < cset->nmbchars; ++i)\n\tif (wc == cset->mbchars[i])\n\t  {\n\t    match_len = char_len;\n\t    goto check_node_accept_bytes_match;\n\t  }\n      /* match with character_class?  */\n      for (i = 0; i < cset->nchar_classes; ++i)\n\t{\n\t  wctype_t wt = cset->char_classes[i];\n\t  if (__iswctype (wc, wt))\n\t    {\n\t      match_len = char_len;\n\t      goto check_node_accept_bytes_match;\n\t    }\n\t}\n\n# ifdef _LIBC\n      nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);\n      if (nrules != 0)\n\t{\n\t  unsigned int in_collseq = 0;\n\t  const int32_t *table, *indirect;\n\t  const unsigned char *weights, *extra;\n\t  const char *collseqwc;\n\n\t  /* match with collating_symbol?  */\n\t  if (cset->ncoll_syms)\n\t    extra = (const unsigned char *)\n\t      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);\n\t  for (i = 0; i < cset->ncoll_syms; ++i)\n\t    {\n\t      const unsigned char *coll_sym = extra + cset->coll_syms[i];\n\t      /* Compare the length of input collating element and\n\t\t the length of current collating element.  */\n\t      if (*coll_sym != elem_len)\n\t\tcontinue;\n\t      /* Compare each bytes.  */\n\t      for (j = 0; j < *coll_sym; j++)\n\t\tif (pin[j] != coll_sym[1 + j])\n\t\t  break;\n\t      if (j == *coll_sym)\n\t\t{\n\t\t  /* Match if every bytes is equal.  */\n\t\t  match_len = j;\n\t\t  goto check_node_accept_bytes_match;\n\t\t}\n\t    }\n\n\t  if (cset->nranges)\n\t    {\n\t      if (elem_len <= char_len)\n\t\t{\n\t\t  collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);\n\t\t  in_collseq = __collseq_table_lookup (collseqwc, wc);\n\t\t}\n\t      else\n\t\tin_collseq = find_collation_sequence_value (pin, elem_len);\n\t    }\n\t  /* match with range expression?  */\n\t  /* FIXME: Implement rational ranges here, too.  */\n\t  for (i = 0; i < cset->nranges; ++i)\n\t    if (cset->range_starts[i] <= in_collseq\n\t\t&& in_collseq <= cset->range_ends[i])\n\t      {\n\t\tmatch_len = elem_len;\n\t\tgoto check_node_accept_bytes_match;\n\t      }\n\n\t  /* match with equivalence_class?  */\n\t  if (cset->nequiv_classes)\n\t    {\n\t      const unsigned char *cp = pin;\n\t      table = (const int32_t *)\n\t\t_NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);\n\t      weights = (const unsigned char *)\n\t\t_NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);\n\t      extra = (const unsigned char *)\n\t\t_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);\n\t      indirect = (const int32_t *)\n\t\t_NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);\n\t      int32_t idx = findidx (table, indirect, extra, &cp, elem_len);\n\t      int32_t rule = idx >> 24;\n\t      idx &= 0xffffff;\n\t      if (idx > 0)\n\t\t{\n\t\t  size_t weight_len = weights[idx];\n\t\t  for (i = 0; i < cset->nequiv_classes; ++i)\n\t\t    {\n\t\t      int32_t equiv_class_idx = cset->equiv_classes[i];\n\t\t      int32_t equiv_class_rule = equiv_class_idx >> 24;\n\t\t      equiv_class_idx &= 0xffffff;\n\t\t      if (weights[equiv_class_idx] == weight_len\n\t\t\t  && equiv_class_rule == rule\n\t\t\t  && memcmp (weights + idx + 1,\n\t\t\t\t     weights + equiv_class_idx + 1,\n\t\t\t\t     weight_len) == 0)\n\t\t\t{\n\t\t\t  match_len = elem_len;\n\t\t\t  goto check_node_accept_bytes_match;\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t}\n      else\n# endif /* _LIBC */\n\t{\n\t  /* match with range expression?  */\n\t  for (i = 0; i < cset->nranges; ++i)\n\t    {\n\t      if (cset->range_starts[i] <= wc && wc <= cset->range_ends[i])\n\t\t{\n\t\t  match_len = char_len;\n\t\t  goto check_node_accept_bytes_match;\n\t\t}\n\t    }\n\t}\n    check_node_accept_bytes_match:\n      if (!cset->non_match)\n\treturn match_len;\n      else\n\t{\n\t  if (match_len > 0)\n\t    return 0;\n\t  else\n\t    return (elem_len > char_len) ? elem_len : char_len;\n\t}\n    }\n  return 0;\n}\n\n# ifdef _LIBC\nstatic unsigned int\nfind_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)\n{\n  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);\n  if (nrules == 0)\n    {\n      if (mbs_len == 1)\n\t{\n\t  /* No valid character.  Match it as a single byte character.  */\n\t  const unsigned char *collseq = (const unsigned char *)\n\t    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);\n\t  return collseq[mbs[0]];\n\t}\n      return UINT_MAX;\n    }\n  else\n    {\n      int32_t idx;\n      const unsigned char *extra = (const unsigned char *)\n\t_NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);\n      int32_t extrasize = (const unsigned char *)\n\t_NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra;\n\n      for (idx = 0; idx < extrasize;)\n\t{\n\t  int mbs_cnt;\n\t  bool found = false;\n\t  int32_t elem_mbs_len;\n\t  /* Skip the name of collating element name.  */\n\t  idx = idx + extra[idx] + 1;\n\t  elem_mbs_len = extra[idx++];\n\t  if (mbs_len == elem_mbs_len)\n\t    {\n\t      for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt)\n\t\tif (extra[idx + mbs_cnt] != mbs[mbs_cnt])\n\t\t  break;\n\t      if (mbs_cnt == elem_mbs_len)\n\t\t/* Found the entry.  */\n\t\tfound = true;\n\t    }\n\t  /* Skip the byte sequence of the collating element.  */\n\t  idx += elem_mbs_len;\n\t  /* Adjust for the alignment.  */\n\t  idx = (idx + 3) & ~3;\n\t  /* Skip the collation sequence value.  */\n\t  idx += sizeof (uint32_t);\n\t  /* Skip the wide char sequence of the collating element.  */\n\t  idx = idx + sizeof (uint32_t) * (*(int32_t *) (extra + idx) + 1);\n\t  /* If we found the entry, return the sequence value.  */\n\t  if (found)\n\t    return *(uint32_t *) (extra + idx);\n\t  /* Skip the collation sequence value.  */\n\t  idx += sizeof (uint32_t);\n\t}\n      return UINT_MAX;\n    }\n}\n# endif /* _LIBC */\n#endif /* RE_ENABLE_I18N */\n\n/* Check whether the node accepts the byte which is IDX-th\n   byte of the INPUT.  */\n\nstatic bool\ncheck_node_accept (const re_match_context_t *mctx, const re_token_t *node,\n\t\t   Idx idx)\n{\n  unsigned char ch;\n  ch = re_string_byte_at (&mctx->input, idx);\n  switch (node->type)\n    {\n    case CHARACTER:\n      if (node->opr.c != ch)\n        return false;\n      break;\n\n    case SIMPLE_BRACKET:\n      if (!bitset_contain (node->opr.sbcset, ch))\n        return false;\n      break;\n\n#ifdef RE_ENABLE_I18N\n    case OP_UTF8_PERIOD:\n      if (ch >= ASCII_CHARS)\n        return false;\n      FALLTHROUGH;\n#endif\n    case OP_PERIOD:\n      if ((ch == '\\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE))\n\t  || (ch == '\\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL)))\n\treturn false;\n      break;\n\n    default:\n      return false;\n    }\n\n  if (node->constraint)\n    {\n      /* The node has constraints.  Check whether the current context\n\t satisfies the constraints.  */\n      unsigned int context = re_string_context_at (&mctx->input, idx,\n\t\t\t\t\t\t   mctx->eflags);\n      if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))\n\treturn false;\n    }\n\n  return true;\n}\n\n/* Extend the buffers, if the buffers have run out.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nextend_buffers (re_match_context_t *mctx, int min_len)\n{\n  reg_errcode_t ret;\n  re_string_t *pstr = &mctx->input;\n\n  /* Avoid overflow.  */\n  if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) / 2\n\t\t\t<= pstr->bufs_len))\n    return REG_ESPACE;\n\n  /* Double the lengths of the buffers, but allocate at least MIN_LEN.  */\n  ret = re_string_realloc_buffers (pstr,\n\t\t\t\t   MAX (min_len,\n\t\t\t\t\tMIN (pstr->len, pstr->bufs_len * 2)));\n  if (__glibc_unlikely (ret != REG_NOERROR))\n    return ret;\n\n  if (mctx->state_log != NULL)\n    {\n      /* And double the length of state_log.  */\n      /* XXX We have no indication of the size of this buffer.  If this\n\t allocation fail we have no indication that the state_log array\n\t does not have the right size.  */\n      re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *,\n\t\t\t\t\t      pstr->bufs_len + 1);\n      if (__glibc_unlikely (new_array == NULL))\n\treturn REG_ESPACE;\n      mctx->state_log = new_array;\n    }\n\n  /* Then reconstruct the buffers.  */\n  if (pstr->icase)\n    {\n#ifdef RE_ENABLE_I18N\n      if (pstr->mb_cur_max > 1)\n\t{\n\t  ret = build_wcs_upper_buffer (pstr);\n\t  if (__glibc_unlikely (ret != REG_NOERROR))\n\t    return ret;\n\t}\n      else\n#endif /* RE_ENABLE_I18N  */\n\tbuild_upper_buffer (pstr);\n    }\n  else\n    {\n#ifdef RE_ENABLE_I18N\n      if (pstr->mb_cur_max > 1)\n\tbuild_wcs_buffer (pstr);\n      else\n#endif /* RE_ENABLE_I18N  */\n\t{\n\t  if (pstr->trans != NULL)\n\t    re_string_translate_buffer (pstr);\n\t}\n    }\n  return REG_NOERROR;\n}\n\n\f\n/* Functions for matching context.  */\n\n/* Initialize MCTX.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nmatch_ctx_init (re_match_context_t *mctx, int eflags, Idx n)\n{\n  mctx->eflags = eflags;\n  mctx->match_last = -1;\n  if (n > 0)\n    {\n      /* Avoid overflow.  */\n      size_t max_object_size =\n\tMAX (sizeof (struct re_backref_cache_entry),\n\t     sizeof (re_sub_match_top_t *));\n      if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size) < n))\n\treturn REG_ESPACE;\n\n      mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);\n      mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);\n      if (__glibc_unlikely (mctx->bkref_ents == NULL || mctx->sub_tops == NULL))\n\treturn REG_ESPACE;\n    }\n  /* Already zero-ed by the caller.\n     else\n       mctx->bkref_ents = NULL;\n     mctx->nbkref_ents = 0;\n     mctx->nsub_tops = 0;  */\n  mctx->abkref_ents = n;\n  mctx->max_mb_elem_len = 1;\n  mctx->asub_tops = n;\n  return REG_NOERROR;\n}\n\n/* Clean the entries which depend on the current input in MCTX.\n   This function must be invoked when the matcher changes the start index\n   of the input, or changes the input string.  */\n\nstatic void\nmatch_ctx_clean (re_match_context_t *mctx)\n{\n  Idx st_idx;\n  for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)\n    {\n      Idx sl_idx;\n      re_sub_match_top_t *top = mctx->sub_tops[st_idx];\n      for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx)\n\t{\n\t  re_sub_match_last_t *last = top->lasts[sl_idx];\n\t  re_free (last->path.array);\n\t  re_free (last);\n\t}\n      re_free (top->lasts);\n      if (top->path)\n\t{\n\t  re_free (top->path->array);\n\t  re_free (top->path);\n\t}\n      re_free (top);\n    }\n\n  mctx->nsub_tops = 0;\n  mctx->nbkref_ents = 0;\n}\n\n/* Free all the memory associated with MCTX.  */\n\nstatic void\nmatch_ctx_free (re_match_context_t *mctx)\n{\n  /* First, free all the memory associated with MCTX->SUB_TOPS.  */\n  match_ctx_clean (mctx);\n  re_free (mctx->sub_tops);\n  re_free (mctx->bkref_ents);\n}\n\n/* Add a new backreference entry to MCTX.\n   Note that we assume that caller never call this function with duplicate\n   entry, and call with STR_IDX which isn't smaller than any existing entry.\n*/\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nmatch_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from,\n\t\t     Idx to)\n{\n  if (mctx->nbkref_ents >= mctx->abkref_ents)\n    {\n      struct re_backref_cache_entry* new_entry;\n      new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,\n\t\t\t      mctx->abkref_ents * 2);\n      if (__glibc_unlikely (new_entry == NULL))\n\t{\n\t  re_free (mctx->bkref_ents);\n\t  return REG_ESPACE;\n\t}\n      mctx->bkref_ents = new_entry;\n      memset (mctx->bkref_ents + mctx->nbkref_ents, '\\0',\n\t      sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);\n      mctx->abkref_ents *= 2;\n    }\n  if (mctx->nbkref_ents > 0\n      && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)\n    mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1;\n\n  mctx->bkref_ents[mctx->nbkref_ents].node = node;\n  mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx;\n  mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from;\n  mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to;\n\n  /* This is a cache that saves negative results of check_dst_limits_calc_pos.\n     If bit N is clear, means that this entry won't epsilon-transition to\n     an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression.  If\n     it is set, check_dst_limits_calc_pos_1 will recurse and try to find one\n     such node.\n\n     A backreference does not epsilon-transition unless it is empty, so set\n     to all zeros if FROM != TO.  */\n  mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map\n    = (from == to ? -1 : 0);\n\n  mctx->bkref_ents[mctx->nbkref_ents++].more = 0;\n  if (mctx->max_mb_elem_len < to - from)\n    mctx->max_mb_elem_len = to - from;\n  return REG_NOERROR;\n}\n\n/* Return the first entry with the same str_idx, or -1 if none is\n   found.  Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */\n\nstatic Idx\nsearch_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)\n{\n  Idx left, right, mid, last;\n  last = right = mctx->nbkref_ents;\n  for (left = 0; left < right;)\n    {\n      mid = (left + right) / 2;\n      if (mctx->bkref_ents[mid].str_idx < str_idx)\n\tleft = mid + 1;\n      else\n\tright = mid;\n    }\n  if (left < last && mctx->bkref_ents[left].str_idx == str_idx)\n    return left;\n  else\n    return -1;\n}\n\n/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches\n   at STR_IDX.  */\n\nstatic reg_errcode_t\n__attribute_warn_unused_result__\nmatch_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx)\n{\n  DEBUG_ASSERT (mctx->sub_tops != NULL);\n  DEBUG_ASSERT (mctx->asub_tops > 0);\n  if (__glibc_unlikely (mctx->nsub_tops == mctx->asub_tops))\n    {\n      Idx new_asub_tops = mctx->asub_tops * 2;\n      re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops,\n\t\t\t\t\t\t   re_sub_match_top_t *,\n\t\t\t\t\t\t   new_asub_tops);\n      if (__glibc_unlikely (new_array == NULL))\n\treturn REG_ESPACE;\n      mctx->sub_tops = new_array;\n      mctx->asub_tops = new_asub_tops;\n    }\n  mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t));\n  if (__glibc_unlikely (mctx->sub_tops[mctx->nsub_tops] == NULL))\n    return REG_ESPACE;\n  mctx->sub_tops[mctx->nsub_tops]->node = node;\n  mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx;\n  return REG_NOERROR;\n}\n\n/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches\n   at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.\n   Return the new entry if successful, NULL if memory is exhausted.  */\n\nstatic re_sub_match_last_t *\nmatch_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx)\n{\n  re_sub_match_last_t *new_entry;\n  if (__glibc_unlikely (subtop->nlasts == subtop->alasts))\n    {\n      Idx new_alasts = 2 * subtop->alasts + 1;\n      re_sub_match_last_t **new_array = re_realloc (subtop->lasts,\n\t\t\t\t\t\t    re_sub_match_last_t *,\n\t\t\t\t\t\t    new_alasts);\n      if (__glibc_unlikely (new_array == NULL))\n\treturn NULL;\n      subtop->lasts = new_array;\n      subtop->alasts = new_alasts;\n    }\n  new_entry = calloc (1, sizeof (re_sub_match_last_t));\n  if (__glibc_likely (new_entry != NULL))\n    {\n      subtop->lasts[subtop->nlasts] = new_entry;\n      new_entry->node = node;\n      new_entry->str_idx = str_idx;\n      ++subtop->nlasts;\n    }\n  return new_entry;\n}\n\nstatic void\nsift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,\n\t       re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx)\n{\n  sctx->sifted_states = sifted_sts;\n  sctx->limited_states = limited_sts;\n  sctx->last_node = last_node;\n  sctx->last_str_idx = last_str_idx;\n  re_node_set_init_empty (&sctx->limits);\n}\n"
  },
  {
    "path": "gnulib/setlocale-lock.c",
    "content": "/* Return the internal lock used by setlocale_null_r.\n   Copyright (C) 2019-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2019.  */\n\n#include <config.h>\n\n/* When it is known that the gl_get_setlocale_null_lock function is defined\n   by a dependency library, it should not be defined here.  */\n#if OMIT_SETLOCALE_LOCK\n\n/* This declaration is solely to ensure that after preprocessing\n   this file is never empty.  */\ntypedef int dummy;\n\n#else\n\n/* This file defines the internal lock used by setlocale_null_r.\n   It is a separate compilation unit, so that only one copy of it is\n   present when linking statically.  */\n\n/* Prohibit renaming this symbol.  */\n# undef gl_get_setlocale_null_lock\n\n/* Macro for exporting a symbol (function, not variable) defined in this file,\n   when compiled into a shared library.  */\n# ifndef DLL_EXPORTED\n#  if HAVE_VISIBILITY\n  /* Override the effect of the compiler option '-fvisibility=hidden'.  */\n#   define DLL_EXPORTED __attribute__((__visibility__(\"default\")))\n#  elif defined _WIN32 || defined __CYGWIN__\n#   define DLL_EXPORTED __declspec(dllexport)\n#  else\n#   define DLL_EXPORTED\n#  endif\n# endif\n\n# if defined _WIN32 && !defined __CYGWIN__\n\n#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#  include <windows.h>\n\n#  include \"windows-initguard.h\"\n\n/* The return type is a 'CRITICAL_SECTION *', not a 'glwthread_mutex_t *',\n   because the latter is not guaranteed to be a stable ABI in the future.  */\n\n/* Make sure the function gets exported from DLLs.  */\nDLL_EXPORTED CRITICAL_SECTION *gl_get_setlocale_null_lock (void);\n\nstatic glwthread_initguard_t guard = GLWTHREAD_INITGUARD_INIT;\nstatic CRITICAL_SECTION lock;\n\n/* Returns the internal lock used by setlocale_null_r.  */\nCRITICAL_SECTION *\ngl_get_setlocale_null_lock (void)\n{\n  if (!guard.done)\n    {\n      if (InterlockedIncrement (&guard.started) == 0)\n        {\n          /* This thread is the first one to need the lock.  Initialize it.  */\n          InitializeCriticalSection (&lock);\n          guard.done = 1;\n        }\n      else\n        {\n          /* Don't let guard.started grow and wrap around.  */\n          InterlockedDecrement (&guard.started);\n          /* Yield the CPU while waiting for another thread to finish\n             initializing this mutex.  */\n          while (!guard.done)\n            Sleep (0);\n        }\n    }\n  return &lock;\n}\n\n# elif HAVE_PTHREAD_API\n\n#  include <pthread.h>\n\nstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;\n\n/* Make sure the function gets exported from shared libraries.  */\nDLL_EXPORTED pthread_mutex_t *gl_get_setlocale_null_lock (void);\n\n/* Returns the internal lock used by setlocale_null_r.  */\npthread_mutex_t *\ngl_get_setlocale_null_lock (void)\n{\n  return &mutex;\n}\n\n# elif HAVE_THREADS_H\n\n#  include <threads.h>\n#  include <stdlib.h>\n\nstatic int volatile init_needed = 1;\nstatic once_flag init_once = ONCE_FLAG_INIT;\nstatic mtx_t mutex;\n\nstatic void\natomic_init (void)\n{\n  if (mtx_init (&mutex, mtx_plain) != thrd_success)\n    abort ();\n  init_needed = 0;\n}\n\n/* Make sure the function gets exported from shared libraries.  */\nDLL_EXPORTED mtx_t *gl_get_setlocale_null_lock (void);\n\n/* Returns the internal lock used by setlocale_null_r.  */\nmtx_t *\ngl_get_setlocale_null_lock (void)\n{\n  if (init_needed)\n    call_once (&init_once, atomic_init);\n  return &mutex;\n}\n\n# endif\n\n# if (defined _WIN32 || defined __CYGWIN__) && !defined _MSC_VER\n/* Make sure the '__declspec(dllimport)' in setlocale_null.c does not cause\n   a link failure when no DLLs are involved.  */\n#  if defined _WIN64 || defined _LP64\n#   define IMP(x) __imp_##x\n#  else\n#   define IMP(x) _imp__##x\n#  endif\nvoid * IMP(gl_get_setlocale_null_lock) = &gl_get_setlocale_null_lock;\n# endif\n\n#endif\n"
  },
  {
    "path": "gnulib/setlocale_null.c",
    "content": "/* Query the name of the current global locale.\n   Copyright (C) 2019-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2019.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include \"setlocale_null.h\"\n\n#include <errno.h>\n#include <locale.h>\n#include <stdlib.h>\n#include <string.h>\n#if defined _WIN32 && !defined __CYGWIN__\n# include <wchar.h>\n#endif\n\n#if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE)\n# if defined _WIN32 && !defined __CYGWIN__\n\n#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#  include <windows.h>\n\n# elif HAVE_PTHREAD_API\n\n#  include <pthread.h>\n#  if HAVE_THREADS_H && HAVE_WEAK_SYMBOLS\n#   include <threads.h>\n#   pragma weak thrd_exit\n#   define c11_threads_in_use() (thrd_exit != NULL)\n#  else\n#   define c11_threads_in_use() 0\n#  endif\n\n# elif HAVE_THREADS_H\n\n#  include <threads.h>\n\n# endif\n#endif\n\n/* Use the system's setlocale() function, not the gnulib override, here.  */\n#undef setlocale\n\nstatic const char *\nsetlocale_null_androidfix (int category)\n{\n  const char *result = setlocale (category, NULL);\n\n#ifdef __ANDROID__\n  if (result == NULL)\n    switch (category)\n      {\n      case LC_CTYPE:\n      case LC_NUMERIC:\n      case LC_TIME:\n      case LC_COLLATE:\n      case LC_MONETARY:\n      case LC_MESSAGES:\n      case LC_ALL:\n      case LC_PAPER:\n      case LC_NAME:\n      case LC_ADDRESS:\n      case LC_TELEPHONE:\n      case LC_MEASUREMENT:\n        result = \"C\";\n        break;\n      default:\n        break;\n      }\n#endif\n\n  return result;\n}\n\nstatic int\nsetlocale_null_unlocked (int category, char *buf, size_t bufsize)\n{\n#if defined _WIN32 && !defined __CYGWIN__ && defined _MSC_VER\n  /* On native Windows, nowadays, the setlocale() implementation is based\n     on _wsetlocale() and uses malloc() for the result.  We are better off\n     using _wsetlocale() directly.  */\n  const wchar_t *result = _wsetlocale (category, NULL);\n\n  if (result == NULL)\n    {\n      /* CATEGORY is invalid.  */\n      if (bufsize > 0)\n        /* Return an empty string in BUF.\n           This is a convenience for callers that don't want to write explicit\n           code for handling EINVAL.  */\n        buf[0] = '\\0';\n      return EINVAL;\n    }\n  else\n    {\n      size_t length = wcslen (result);\n      if (length < bufsize)\n        {\n          size_t i;\n\n          /* Convert wchar_t[] -> char[], assuming plain ASCII.  */\n          for (i = 0; i <= length; i++)\n            buf[i] = result[i];\n\n          return 0;\n        }\n      else\n        {\n          if (bufsize > 0)\n            {\n              /* Return a truncated result in BUF.\n                 This is a convenience for callers that don't want to write\n                 explicit code for handling ERANGE.  */\n              size_t i;\n\n              /* Convert wchar_t[] -> char[], assuming plain ASCII.  */\n              for (i = 0; i < bufsize; i++)\n                buf[i] = result[i];\n              buf[bufsize - 1] = '\\0';\n            }\n          return ERANGE;\n        }\n    }\n#else\n  const char *result = setlocale_null_androidfix (category);\n\n  if (result == NULL)\n    {\n      /* CATEGORY is invalid.  */\n      if (bufsize > 0)\n        /* Return an empty string in BUF.\n           This is a convenience for callers that don't want to write explicit\n           code for handling EINVAL.  */\n        buf[0] = '\\0';\n      return EINVAL;\n    }\n  else\n    {\n      size_t length = strlen (result);\n      if (length < bufsize)\n        {\n          memcpy (buf, result, length + 1);\n          return 0;\n        }\n      else\n        {\n          if (bufsize > 0)\n            {\n              /* Return a truncated result in BUF.\n                 This is a convenience for callers that don't want to write\n                 explicit code for handling ERANGE.  */\n              memcpy (buf, result, bufsize - 1);\n              buf[bufsize - 1] = '\\0';\n            }\n          return ERANGE;\n        }\n    }\n#endif\n}\n\n#if !(SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE) /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin */\n\n/* Use a lock, so that no two threads can invoke setlocale_null_unlocked\n   at the same time.  */\n\n/* Prohibit renaming this symbol.  */\n# undef gl_get_setlocale_null_lock\n\n# if defined _WIN32 && !defined __CYGWIN__\n\nextern __declspec(dllimport) CRITICAL_SECTION *gl_get_setlocale_null_lock (void);\n\nstatic int\nsetlocale_null_with_lock (int category, char *buf, size_t bufsize)\n{\n  CRITICAL_SECTION *lock = gl_get_setlocale_null_lock ();\n  int ret;\n\n  EnterCriticalSection (lock);\n  ret = setlocale_null_unlocked (category, buf, bufsize);\n  LeaveCriticalSection (lock);\n\n  return ret;\n}\n\n# elif HAVE_PTHREAD_API /* musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin */\n\nextern\n#  if defined _WIN32 || defined __CYGWIN__\n  __declspec(dllimport)\n#  endif\n  pthread_mutex_t *gl_get_setlocale_null_lock (void);\n\n#  if HAVE_WEAK_SYMBOLS /* musl libc, FreeBSD, NetBSD, OpenBSD, Haiku */\n\n    /* Avoid the need to link with '-lpthread'.  */\n#   pragma weak pthread_mutex_lock\n#   pragma weak pthread_mutex_unlock\n\n    /* Determine whether libpthread is in use.  */\n#   pragma weak pthread_mutexattr_gettype\n    /* See the comments in lock.h.  */\n#   define pthread_in_use() \\\n      (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())\n\n#  else\n#   define pthread_in_use() 1\n#  endif\n\nstatic int\nsetlocale_null_with_lock (int category, char *buf, size_t bufsize)\n{\n  if (pthread_in_use())\n    {\n      pthread_mutex_t *lock = gl_get_setlocale_null_lock ();\n      int ret;\n\n      if (pthread_mutex_lock (lock))\n        abort ();\n      ret = setlocale_null_unlocked (category, buf, bufsize);\n      if (pthread_mutex_unlock (lock))\n        abort ();\n\n      return ret;\n    }\n  else\n    return setlocale_null_unlocked (category, buf, bufsize);\n}\n\n# elif HAVE_THREADS_H\n\nextern mtx_t *gl_get_setlocale_null_lock (void);\n\nstatic int\nsetlocale_null_with_lock (int category, char *buf, size_t bufsize)\n{\n  mtx_t *lock = gl_get_setlocale_null_lock ();\n  int ret;\n\n  if (mtx_lock (lock) != thrd_success)\n    abort ();\n  ret = setlocale_null_unlocked (category, buf, bufsize);\n  if (mtx_unlock (lock) != thrd_success)\n    abort ();\n\n  return ret;\n}\n\n# endif\n\n#endif\n\nint\nsetlocale_null_r (int category, char *buf, size_t bufsize)\n{\n#if SETLOCALE_NULL_ALL_MTSAFE\n# if SETLOCALE_NULL_ONE_MTSAFE\n\n  return setlocale_null_unlocked (category, buf, bufsize);\n\n# else\n\n  if (category == LC_ALL)\n    return setlocale_null_unlocked (category, buf, bufsize);\n  else\n    return setlocale_null_with_lock (category, buf, bufsize);\n\n# endif\n#else\n# if SETLOCALE_NULL_ONE_MTSAFE\n\n  if (category == LC_ALL)\n    return setlocale_null_with_lock (category, buf, bufsize);\n  else\n    return setlocale_null_unlocked (category, buf, bufsize);\n\n# else\n\n  return setlocale_null_with_lock (category, buf, bufsize);\n\n# endif\n#endif\n}\n\nconst char *\nsetlocale_null (int category)\n{\n#if SETLOCALE_NULL_ALL_MTSAFE && SETLOCALE_NULL_ONE_MTSAFE\n  return setlocale_null_androidfix (category);\n#else\n\n  /* This call must be multithread-safe.  To achieve this without using\n     thread-local storage:\n       1. We use a specific static buffer for each possible CATEGORY\n          argument.  So that different threads can call setlocale_mtsafe\n          with different CATEGORY arguments, without interfering.\n       2. We use a simple strcpy or memcpy to fill this static buffer.\n          Filling it through, for example, strcpy + strcat would not be\n          guaranteed to leave the buffer's contents intact if another thread\n          is currently accessing it.  If necessary, the contents is first\n          assembled in a stack-allocated buffer.  */\n  if (category == LC_ALL)\n    {\n# if SETLOCALE_NULL_ALL_MTSAFE\n      return setlocale_null_androidfix (LC_ALL);\n# else\n      char buf[SETLOCALE_NULL_ALL_MAX];\n      static char resultbuf[SETLOCALE_NULL_ALL_MAX];\n\n      if (setlocale_null_r (LC_ALL, buf, sizeof (buf)))\n        return \"C\";\n      strcpy (resultbuf, buf);\n      return resultbuf;\n# endif\n    }\n  else\n    {\n# if SETLOCALE_NULL_ONE_MTSAFE\n      return setlocale_null_androidfix (category);\n# else\n      enum\n        {\n          LC_CTYPE_INDEX,\n          LC_NUMERIC_INDEX,\n          LC_TIME_INDEX,\n          LC_COLLATE_INDEX,\n          LC_MONETARY_INDEX,\n          LC_MESSAGES_INDEX,\n#  ifdef LC_PAPER\n          LC_PAPER_INDEX,\n#  endif\n#  ifdef LC_NAME\n          LC_NAME_INDEX,\n#  endif\n#  ifdef LC_ADDRESS\n          LC_ADDRESS_INDEX,\n#  endif\n#  ifdef LC_TELEPHONE\n          LC_TELEPHONE_INDEX,\n#  endif\n#  ifdef LC_MEASUREMENT\n          LC_MEASUREMENT_INDEX,\n#  endif\n#  ifdef LC_IDENTIFICATION\n          LC_IDENTIFICATION_INDEX,\n#  endif\n          LC_INDICES_COUNT\n        }\n        i;\n      char buf[SETLOCALE_NULL_MAX];\n      static char resultbuf[LC_INDICES_COUNT][SETLOCALE_NULL_MAX];\n      int err;\n\n      err = setlocale_null_r (category, buf, sizeof (buf));\n      if (err == EINVAL)\n        return NULL;\n      if (err)\n        return \"C\";\n\n      switch (category)\n        {\n        case LC_CTYPE:          i = LC_CTYPE_INDEX;          break;\n        case LC_NUMERIC:        i = LC_NUMERIC_INDEX;        break;\n        case LC_TIME:           i = LC_TIME_INDEX;           break;\n        case LC_COLLATE:        i = LC_COLLATE_INDEX;        break;\n        case LC_MONETARY:       i = LC_MONETARY_INDEX;       break;\n        case LC_MESSAGES:       i = LC_MESSAGES_INDEX;       break;\n#  ifdef LC_PAPER\n        case LC_PAPER:          i = LC_PAPER_INDEX;          break;\n#  endif\n#  ifdef LC_NAME\n        case LC_NAME:           i = LC_NAME_INDEX;           break;\n#  endif\n#  ifdef LC_ADDRESS\n        case LC_ADDRESS:        i = LC_ADDRESS_INDEX;        break;\n#  endif\n#  ifdef LC_TELEPHONE\n        case LC_TELEPHONE:      i = LC_TELEPHONE_INDEX;      break;\n#  endif\n#  ifdef LC_MEASUREMENT\n        case LC_MEASUREMENT:    i = LC_MEASUREMENT_INDEX;    break;\n#  endif\n#  ifdef LC_IDENTIFICATION\n        case LC_IDENTIFICATION: i = LC_IDENTIFICATION_INDEX; break;\n#  endif\n        default:\n          /* If you get here, a #ifdef LC_xxx is missing.  */\n          abort ();\n        }\n\n      strcpy (resultbuf[i], buf);\n      return resultbuf[i];\n# endif\n    }\n#endif\n}\n"
  },
  {
    "path": "gnulib/setlocale_null.h",
    "content": "/* Query the name of the current global locale.\n   Copyright (C) 2019-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2019.  */\n\n#ifndef _SETLOCALE_NULL_H\n#define _SETLOCALE_NULL_H\n\n#include <stddef.h>\n\n#include \"arg-nonnull.h\"\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/* Recommended size of a buffer for a locale name for a single category.\n   On glibc systems, you can have locale names that are relative file names;\n   assume a maximum length 256.\n   In native Windows, in 2018 the longest locale name was of length 58\n   (\"FYRO Macedonian_Former Yugoslav Republic of Macedonia.1251\").  */\n#define SETLOCALE_NULL_MAX (256+1)\n\n/* Recommended size of a buffer for a locale name with all categories.\n   On glibc systems, you can have locale names that are relative file names;\n   assume maximum length 256 for each.  There are 12 categories; so, the\n   maximum total length is 148+12*256.\n   In native Windows, there are 5 categories, and the maximum total length is\n   55+5*58.  */\n#define SETLOCALE_NULL_ALL_MAX (148+12*256+1)\n\n/* setlocale_null_r (CATEGORY, BUF, BUFSIZE) is like setlocale (CATEGORY, NULL),\n   except that\n     - it is guaranteed to be multithread-safe,\n     - it returns the resulting locale category name or locale name in the\n       user-supplied buffer BUF, which must be BUFSIZE bytes long.\n   The recommended minimum buffer size is\n     - SETLOCALE_NULL_MAX for CATEGORY != LC_ALL, and\n     - SETLOCALE_NULL_ALL_MAX for CATEGORY == LC_ALL.\n   The return value is an error code: 0 if the call is successful, EINVAL if\n   CATEGORY is invalid, or ERANGE if BUFSIZE is smaller than the length needed\n   size (including the trailing NUL byte).  In the latter case, a truncated\n   result is returned in BUF, but still NUL-terminated if BUFSIZE > 0.\n   For this call to be multithread-safe, *all* calls to\n   setlocale (CATEGORY, NULL) in all other threads must have been converted\n   to use setlocale_null_r or setlocale_null as well, and the other threads\n   must not make other setlocale invocations (since changing the global locale\n   has side effects on all threads).  */\nextern int setlocale_null_r (int category, char *buf, size_t bufsize)\n  _GL_ARG_NONNULL ((2));\n\n/* setlocale_null (CATEGORY) is like setlocale (CATEGORY, NULL), except that\n   it is guaranteed to be multithread-safe.\n   The return value is NULL if CATEGORY is invalid.\n   For this call to be multithread-safe, *all* calls to\n   setlocale (CATEGORY, NULL) in all other threads must have been converted\n   to use setlocale_null_r or setlocale_null as well, and the other threads\n   must not make other setlocale invocations (since changing the global locale\n   has side effects on all threads).  */\nextern const char *setlocale_null (int category);\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _SETLOCALE_NULL_H */\n"
  },
  {
    "path": "gnulib/stdbool.in.h",
    "content": "/* Copyright (C) 2001-2003, 2006-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <haible@clisp.cons.org>, 2001.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _GL_STDBOOL_H\n#define _GL_STDBOOL_H\n\n/* ISO C 99 <stdbool.h> for platforms that lack it.  */\n\n/* Usage suggestions:\n\n   Programs that use <stdbool.h> should be aware of some limitations\n   and standards compliance issues.\n\n   Standards compliance:\n\n       - <stdbool.h> must be #included before 'bool', 'false', 'true'\n         can be used.\n\n       - You cannot assume that sizeof (bool) == 1.\n\n       - Programs should not undefine the macros bool, true, and false,\n         as C99 lists that as an \"obsolescent feature\".\n\n   Limitations of this substitute, when used in a C89 environment:\n\n       - <stdbool.h> must be #included before the '_Bool' type can be used.\n\n       - You cannot assume that _Bool is a typedef; it might be a macro.\n\n       - Bit-fields of type 'bool' are not supported.  Portable code\n         should use 'unsigned int foo : 1;' rather than 'bool foo : 1;'.\n\n       - In C99, casts and automatic conversions to '_Bool' or 'bool' are\n         performed in such a way that every nonzero value gets converted\n         to 'true', and zero gets converted to 'false'.  This doesn't work\n         with this substitute.  With this substitute, only the values 0 and 1\n         give the expected result when converted to _Bool' or 'bool'.\n\n       - C99 allows the use of (_Bool)0.0 in constant expressions, but\n         this substitute cannot always provide this property.\n\n   Also, it is suggested that programs use 'bool' rather than '_Bool';\n   this isn't required, but 'bool' is more common.  */\n\n\n/* 7.16. Boolean type and values */\n\n/* BeOS <sys/socket.h> already #defines false 0, true 1.  We use the same\n   definitions below, but temporarily we have to #undef them.  */\n#if defined __BEOS__ && !defined __HAIKU__\n# include <OS.h> /* defines bool but not _Bool */\n# undef false\n# undef true\n#endif\n\n#ifdef __cplusplus\n# define _Bool bool\n# define bool bool\n#else\n# if defined __BEOS__ && !defined __HAIKU__\n  /* A compiler known to have 'bool'.  */\n  /* If the compiler already has both 'bool' and '_Bool', we can assume they\n     are the same types.  */\n#  if !@HAVE__BOOL@\ntypedef bool _Bool;\n#  endif\n# else\n#  if !defined __GNUC__\n   /* If @HAVE__BOOL@:\n        Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when\n        the built-in _Bool type is used.  See\n          https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html\n          https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html\n          https://lists.gnu.org/r/bug-coreutils/2005-10/msg00086.html\n        Similar bugs are likely with other compilers as well; this file\n        wouldn't be used if <stdbool.h> was working.\n        So we override the _Bool type.\n      If !@HAVE__BOOL@:\n        Need to define _Bool ourselves. As 'signed char' or as an enum type?\n        Use of a typedef, with SunPRO C, leads to a stupid\n          \"warning: _Bool is a keyword in ISO C99\".\n        Use of an enum type, with IRIX cc, leads to a stupid\n          \"warning(1185): enumerated type mixed with another type\".\n        Even the existence of an enum type, without a typedef,\n          \"Invalid enumerator. (badenum)\" with HP-UX cc on Tru64.\n        The only benefit of the enum, debuggability, is not important\n        with these compilers.  So use 'signed char' and no enum.  */\n#   define _Bool signed char\n#  else\n   /* With this compiler, trust the _Bool type if the compiler has it.  */\n#   if !@HAVE__BOOL@\n   /* For the sake of symbolic names in gdb, define true and false as\n      enum constants, not only as macros.\n      It is tempting to write\n         typedef enum { false = 0, true = 1 } _Bool;\n      so that gdb prints values of type 'bool' symbolically.  But then\n      values of type '_Bool' might promote to 'int' or 'unsigned int'\n      (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int'\n      (see ISO C 99 6.3.1.1.(2)).  So add a negative value to the\n      enum; this ensures that '_Bool' promotes to 'int'.  */\ntypedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;\n#   endif\n#  endif\n# endif\n# define bool _Bool\n#endif\n\n/* The other macros must be usable in preprocessor directives.  */\n#ifdef __cplusplus\n# define false false\n# define true true\n#else\n# define false 0\n# define true 1\n#endif\n\n#define __bool_true_false_are_defined 1\n\n#endif /* _GL_STDBOOL_H */\n"
  },
  {
    "path": "gnulib/stddef.in.h",
    "content": "/* A substitute for POSIX 2008 <stddef.h>, for platforms that have issues.\n\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Eric Blake.  */\n\n/*\n * POSIX 2008 <stddef.h> for platforms that have issues.\n * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stddef.h.html>\n */\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n#if defined __need_wchar_t || defined __need_size_t  \\\n  || defined __need_ptrdiff_t || defined __need_NULL \\\n  || defined __need_wint_t\n/* Special invocation convention inside gcc header files.  In\n   particular, gcc provides a version of <stddef.h> that blindly\n   redefines NULL even when __need_wint_t was defined, even though\n   wint_t is not normally provided by <stddef.h>.  Hence, we must\n   remember if special invocation has ever been used to obtain wint_t,\n   in which case we need to clean up NULL yet again.  */\n\n# if !(defined _@GUARD_PREFIX@_STDDEF_H && defined _GL_STDDEF_WINT_T)\n#  ifdef __need_wint_t\n#   define _GL_STDDEF_WINT_T\n#  endif\n#  @INCLUDE_NEXT@ @NEXT_STDDEF_H@\n   /* On TinyCC, make sure that the macros that indicate the special invocation\n      convention get undefined.  */\n#  undef __need_wchar_t\n#  undef __need_size_t\n#  undef __need_ptrdiff_t\n#  undef __need_NULL\n#  undef __need_wint_t\n# endif\n\n#else\n/* Normal invocation convention.  */\n\n# ifndef _@GUARD_PREFIX@_STDDEF_H\n\n/* On AIX 7.2, with xlc in 64-bit mode, <stddef.h> defines max_align_t to a\n   type with alignment 4, but 'long' has alignment 8.  */\n#  if defined _AIX && defined __LP64__\n#   if !GNULIB_defined_max_align_t\n#    ifdef _MAX_ALIGN_T\n/* /usr/include/stddef.h has already defined max_align_t.  Override it.  */\ntypedef long rpl_max_align_t;\n#     define max_align_t rpl_max_align_t\n#    else\n/* Prevent /usr/include/stddef.h from defining max_align_t.  */\ntypedef long max_align_t;\n#     define _MAX_ALIGN_T\n#    endif\n#    define GNULIB_defined_max_align_t 1\n#   endif\n#  endif\n\n/* The include_next requires a split double-inclusion guard.  */\n\n#  @INCLUDE_NEXT@ @NEXT_STDDEF_H@\n\n/* On NetBSD 5.0, the definition of NULL lacks proper parentheses.  */\n#  if (@REPLACE_NULL@ \\\n       && (!defined _@GUARD_PREFIX@_STDDEF_H || defined _GL_STDDEF_WINT_T))\n#   undef NULL\n#   ifdef __cplusplus\n   /* ISO C++ says that the macro NULL must expand to an integer constant\n      expression, hence '((void *) 0)' is not allowed in C++.  */\n#    if __GNUG__ >= 3\n    /* GNU C++ has a __null macro that behaves like an integer ('int' or\n       'long') but has the same size as a pointer.  Use that, to avoid\n       warnings.  */\n#     define NULL __null\n#    else\n#     define NULL 0L\n#    endif\n#   else\n#    define NULL ((void *) 0)\n#   endif\n#  endif\n\n#  ifndef _@GUARD_PREFIX@_STDDEF_H\n#   define _@GUARD_PREFIX@_STDDEF_H\n\n/* Some platforms lack wchar_t.  */\n#if !@HAVE_WCHAR_T@\n# define wchar_t int\n#endif\n\n/* Some platforms lack max_align_t.  The check for _GCC_MAX_ALIGN_T is\n   a hack in case the configure-time test was done with g++ even though\n   we are currently compiling with gcc.\n   On MSVC, max_align_t is defined only in C++ mode, after <cstddef> was\n   included.  Its definition is good since it has an alignment of 8 (on x86\n   and x86_64).\n   Similarly on OS/2 kLIBC.  */\n#if (defined _MSC_VER || (defined __KLIBC__ && !defined __LIBCN__)) \\\n    && defined __cplusplus\n# include <cstddef>\n#else\n# if ! (@HAVE_MAX_ALIGN_T@ || (defined _GCC_MAX_ALIGN_T && !defined __clang__))\n#  if !GNULIB_defined_max_align_t\n/* On the x86, the maximum storage alignment of double, long, etc. is 4,\n   but GCC's C11 ABI for x86 says that max_align_t has an alignment of 8,\n   and the C11 standard allows this.  Work around this problem by\n   using __alignof__ (which returns 8 for double) rather than _Alignof\n   (which returns 4), and align each union member accordingly.  */\n#   if defined __GNUC__ || (__clang_major__ >= 4)\n#    define _GL_STDDEF_ALIGNAS(type) \\\n       __attribute__ ((__aligned__ (__alignof__ (type))))\n#   else\n#    define _GL_STDDEF_ALIGNAS(type) /* */\n#   endif\ntypedef union\n{\n  char *__p _GL_STDDEF_ALIGNAS (char *);\n  double __d _GL_STDDEF_ALIGNAS (double);\n  long double __ld _GL_STDDEF_ALIGNAS (long double);\n  long int __i _GL_STDDEF_ALIGNAS (long int);\n} rpl_max_align_t;\n#   define max_align_t rpl_max_align_t\n#   define GNULIB_defined_max_align_t 1\n#  endif\n# endif\n#endif\n\n#  endif /* _@GUARD_PREFIX@_STDDEF_H */\n# endif /* _@GUARD_PREFIX@_STDDEF_H */\n#endif /* __need_XXX */\n"
  },
  {
    "path": "gnulib/stdint.in.h",
    "content": "/* Copyright (C) 2001-2002, 2004-2021 Free Software Foundation, Inc.\n   Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood.\n   This file is part of gnulib.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/*\n * ISO C 99 <stdint.h> for platforms that lack it.\n * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdint.h.html>\n */\n\n#ifndef _@GUARD_PREFIX@_STDINT_H\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n/* When including a system file that in turn includes <inttypes.h>,\n   use the system <inttypes.h>, not our substitute.  This avoids\n   problems with (for example) VMS, whose <sys/bitypes.h> includes\n   <inttypes.h>.  */\n#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H\n\n/* On Android (Bionic libc), <sys/types.h> includes this file before\n   having defined 'time_t'.  Therefore in this case avoid including\n   other system header files; just include the system's <stdint.h>.\n   Ideally we should test __BIONIC__ here, but it is only defined after\n   <sys/cdefs.h> has been included; hence test __ANDROID__ instead.  */\n#if defined __ANDROID__ && defined _GL_INCLUDING_SYS_TYPES_H\n# @INCLUDE_NEXT@ @NEXT_STDINT_H@\n#else\n\n/* Get those types that are already defined in other system include\n   files, so that we can \"#define int8_t signed char\" below without\n   worrying about a later system include file containing a \"typedef\n   signed char int8_t;\" that will get messed up by our macro.  Our\n   macros should all be consistent with the system versions, except\n   for the \"fast\" types and macros, which we recommend against using\n   in public interfaces due to compiler differences.  */\n\n#if @HAVE_STDINT_H@\n# if defined __sgi && ! defined __c99\n   /* Bypass IRIX's <stdint.h> if in C89 mode, since it merely annoys users\n      with \"This header file is to be used only for c99 mode compilations\"\n      diagnostics.  */\n#  define __STDINT_H__\n# endif\n\n  /* Some pre-C++11 <stdint.h> implementations need this.  */\n# ifdef __cplusplus\n#  ifndef __STDC_CONSTANT_MACROS\n#   define __STDC_CONSTANT_MACROS 1\n#  endif\n#  ifndef __STDC_LIMIT_MACROS\n#   define __STDC_LIMIT_MACROS 1\n#  endif\n# endif\n\n  /* Other systems may have an incomplete or buggy <stdint.h>.\n     Include it before <inttypes.h>, since any \"#include <stdint.h>\"\n     in <inttypes.h> would reinclude us, skipping our contents because\n     _@GUARD_PREFIX@_STDINT_H is defined.\n     The include_next requires a split double-inclusion guard.  */\n# @INCLUDE_NEXT@ @NEXT_STDINT_H@\n#endif\n\n#if ! defined _@GUARD_PREFIX@_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H\n#define _@GUARD_PREFIX@_STDINT_H\n\n/* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX,\n   LONG_MIN, LONG_MAX, ULONG_MAX, _GL_INTEGER_WIDTH.  */\n#include <limits.h>\n\n/* Override WINT_MIN and WINT_MAX if gnulib's <wchar.h> or <wctype.h> overrides\n   wint_t.  */\n#if @GNULIBHEADERS_OVERRIDE_WINT_T@\n# undef WINT_MIN\n# undef WINT_MAX\n# define WINT_MIN 0x0U\n# define WINT_MAX 0xffffffffU\n#endif\n\n#if ! @HAVE_C99_STDINT_H@\n\n/* <sys/types.h> defines some of the stdint.h types as well, on glibc,\n   IRIX 6.5, and OpenBSD 3.8 (via <machine/types.h>).\n   AIX 5.2 <sys/types.h> isn't needed and causes troubles.\n   Mac OS X 10.4.6 <sys/types.h> includes <stdint.h> (which is us), but\n   relies on the system <stdint.h> definitions, so include\n   <sys/types.h> after @NEXT_STDINT_H@.  */\n# if @HAVE_SYS_TYPES_H@ && ! defined _AIX\n#  include <sys/types.h>\n# endif\n\n# if @HAVE_INTTYPES_H@\n  /* In OpenBSD 3.8, <inttypes.h> includes <machine/types.h>, which defines\n     int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__.\n     <inttypes.h> also defines intptr_t and uintptr_t.  */\n#  include <inttypes.h>\n# elif @HAVE_SYS_INTTYPES_H@\n  /* Solaris 7 <sys/inttypes.h> has the types except the *_fast*_t types, and\n     the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX.  */\n#  include <sys/inttypes.h>\n# endif\n\n# if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__\n  /* Linux libc4 >= 4.6.7 and libc5 have a <sys/bitypes.h> that defines\n     int{8,16,32,64}_t and __BIT_TYPES_DEFINED__.  In libc5 >= 5.2.2 it is\n     included by <sys/types.h>.  */\n#  include <sys/bitypes.h>\n# endif\n\n# undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H\n\n/* Minimum and maximum values for an integer type under the usual assumption.\n   Return an unspecified value if BITS == 0, adding a check to pacify\n   picky compilers.  */\n\n/* These are separate macros, because if you try to merge these macros into\n   a single one, HP-UX cc rejects the resulting expression in constant\n   expressions.  */\n# define _STDINT_UNSIGNED_MIN(bits, zero) \\\n    (zero)\n# define _STDINT_SIGNED_MIN(bits, zero) \\\n    (~ _STDINT_MAX (1, bits, zero))\n\n# define _STDINT_MAX(signed, bits, zero) \\\n    (((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1)\n\n#if !GNULIB_defined_stdint_types\n\n/* 7.18.1.1. Exact-width integer types */\n\n/* Here we assume a standard architecture where the hardware integer\n   types have 8, 16, 32, optionally 64 bits.  */\n\n# undef int8_t\n# undef uint8_t\ntypedef signed char gl_int8_t;\ntypedef unsigned char gl_uint8_t;\n# define int8_t gl_int8_t\n# define uint8_t gl_uint8_t\n\n# undef int16_t\n# undef uint16_t\ntypedef short int gl_int16_t;\ntypedef unsigned short int gl_uint16_t;\n# define int16_t gl_int16_t\n# define uint16_t gl_uint16_t\n\n# undef int32_t\n# undef uint32_t\ntypedef int gl_int32_t;\ntypedef unsigned int gl_uint32_t;\n# define int32_t gl_int32_t\n# define uint32_t gl_uint32_t\n\n/* If the system defines INT64_MAX, assume int64_t works.  That way,\n   if the underlying platform defines int64_t to be a 64-bit long long\n   int, the code below won't mistakenly define it to be a 64-bit long\n   int, which would mess up C++ name mangling.  We must use #ifdef\n   rather than #if, to avoid an error with HP-UX 10.20 cc.  */\n\n# ifdef INT64_MAX\n#  define GL_INT64_T\n# else\n/* Do not undefine int64_t if gnulib is not being used with 64-bit\n   types, since otherwise it breaks platforms like Tandem/NSK.  */\n#  if LONG_MAX >> 31 >> 31 == 1\n#   undef int64_t\ntypedef long int gl_int64_t;\n#   define int64_t gl_int64_t\n#   define GL_INT64_T\n#  elif defined _MSC_VER\n#   undef int64_t\ntypedef __int64 gl_int64_t;\n#   define int64_t gl_int64_t\n#   define GL_INT64_T\n#  else\n#   undef int64_t\ntypedef long long int gl_int64_t;\n#   define int64_t gl_int64_t\n#   define GL_INT64_T\n#  endif\n# endif\n\n# ifdef UINT64_MAX\n#  define GL_UINT64_T\n# else\n#  if ULONG_MAX >> 31 >> 31 >> 1 == 1\n#   undef uint64_t\ntypedef unsigned long int gl_uint64_t;\n#   define uint64_t gl_uint64_t\n#   define GL_UINT64_T\n#  elif defined _MSC_VER\n#   undef uint64_t\ntypedef unsigned __int64 gl_uint64_t;\n#   define uint64_t gl_uint64_t\n#   define GL_UINT64_T\n#  else\n#   undef uint64_t\ntypedef unsigned long long int gl_uint64_t;\n#   define uint64_t gl_uint64_t\n#   define GL_UINT64_T\n#  endif\n# endif\n\n/* Avoid collision with Solaris 2.5.1 <pthread.h> etc.  */\n# define _UINT8_T\n# define _UINT32_T\n# define _UINT64_T\n\n\n/* 7.18.1.2. Minimum-width integer types */\n\n/* Here we assume a standard architecture where the hardware integer\n   types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types\n   are the same as the corresponding N_t types.  */\n\n# undef int_least8_t\n# undef uint_least8_t\n# undef int_least16_t\n# undef uint_least16_t\n# undef int_least32_t\n# undef uint_least32_t\n# undef int_least64_t\n# undef uint_least64_t\n# define int_least8_t int8_t\n# define uint_least8_t uint8_t\n# define int_least16_t int16_t\n# define uint_least16_t uint16_t\n# define int_least32_t int32_t\n# define uint_least32_t uint32_t\n# ifdef GL_INT64_T\n#  define int_least64_t int64_t\n# endif\n# ifdef GL_UINT64_T\n#  define uint_least64_t uint64_t\n# endif\n\n/* 7.18.1.3. Fastest minimum-width integer types */\n\n/* Note: Other <stdint.h> substitutes may define these types differently.\n   It is not recommended to use these types in public header files. */\n\n/* Here we assume a standard architecture where the hardware integer\n   types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types\n   are taken from the same list of types.  The following code normally\n   uses types consistent with glibc, as that lessens the chance of\n   incompatibility with older GNU hosts.  */\n\n# undef int_fast8_t\n# undef uint_fast8_t\n# undef int_fast16_t\n# undef uint_fast16_t\n# undef int_fast32_t\n# undef uint_fast32_t\n# undef int_fast64_t\n# undef uint_fast64_t\ntypedef signed char gl_int_fast8_t;\ntypedef unsigned char gl_uint_fast8_t;\n\n# ifdef __sun\n/* Define types compatible with SunOS 5.10, so that code compiled under\n   earlier SunOS versions works with code compiled under SunOS 5.10.  */\ntypedef int gl_int_fast32_t;\ntypedef unsigned int gl_uint_fast32_t;\n# else\ntypedef long int gl_int_fast32_t;\ntypedef unsigned long int gl_uint_fast32_t;\n# endif\ntypedef gl_int_fast32_t gl_int_fast16_t;\ntypedef gl_uint_fast32_t gl_uint_fast16_t;\n\n# define int_fast8_t gl_int_fast8_t\n# define uint_fast8_t gl_uint_fast8_t\n# define int_fast16_t gl_int_fast16_t\n# define uint_fast16_t gl_uint_fast16_t\n# define int_fast32_t gl_int_fast32_t\n# define uint_fast32_t gl_uint_fast32_t\n# ifdef GL_INT64_T\n#  define int_fast64_t int64_t\n# endif\n# ifdef GL_UINT64_T\n#  define uint_fast64_t uint64_t\n# endif\n\n/* 7.18.1.4. Integer types capable of holding object pointers */\n\n/* kLIBC's <stdint.h> defines _INTPTR_T_DECLARED and needs its own\n   definitions of intptr_t and uintptr_t (which use int and unsigned)\n   to avoid clashes with declarations of system functions like sbrk.\n   Similarly, MinGW WSL-5.4.1 <stdint.h> needs its own intptr_t and\n   uintptr_t to avoid conflicting declarations of system functions like\n   _findclose in <io.h>.  */\n# if !((defined __KLIBC__ && defined _INTPTR_T_DECLARED) \\\n       || defined __MINGW32__)\n#  undef intptr_t\n#  undef uintptr_t\n#  ifdef _WIN64\ntypedef long long int gl_intptr_t;\ntypedef unsigned long long int gl_uintptr_t;\n#  else\ntypedef long int gl_intptr_t;\ntypedef unsigned long int gl_uintptr_t;\n#  endif\n#  define intptr_t gl_intptr_t\n#  define uintptr_t gl_uintptr_t\n# endif\n\n/* 7.18.1.5. Greatest-width integer types */\n\n/* Note: These types are compiler dependent. It may be unwise to use them in\n   public header files. */\n\n/* If the system defines INTMAX_MAX, assume that intmax_t works, and\n   similarly for UINTMAX_MAX and uintmax_t.  This avoids problems with\n   assuming one type where another is used by the system.  */\n\n# ifndef INTMAX_MAX\n#  undef INTMAX_C\n#  undef intmax_t\n#  if LONG_MAX >> 30 == 1\ntypedef long long int gl_intmax_t;\n#   define intmax_t gl_intmax_t\n#  elif defined GL_INT64_T\n#   define intmax_t int64_t\n#  else\ntypedef long int gl_intmax_t;\n#   define intmax_t gl_intmax_t\n#  endif\n# endif\n\n# ifndef UINTMAX_MAX\n#  undef UINTMAX_C\n#  undef uintmax_t\n#  if ULONG_MAX >> 31 == 1\ntypedef unsigned long long int gl_uintmax_t;\n#   define uintmax_t gl_uintmax_t\n#  elif defined GL_UINT64_T\n#   define uintmax_t uint64_t\n#  else\ntypedef unsigned long int gl_uintmax_t;\n#   define uintmax_t gl_uintmax_t\n#  endif\n# endif\n\n/* Verify that intmax_t and uintmax_t have the same size.  Too much code\n   breaks if this is not the case.  If this check fails, the reason is likely\n   to be found in the autoconf macros.  */\ntypedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t)\n                                ? 1 : -1];\n\n# define GNULIB_defined_stdint_types 1\n# endif /* !GNULIB_defined_stdint_types */\n\n/* 7.18.2. Limits of specified-width integer types */\n\n/* 7.18.2.1. Limits of exact-width integer types */\n\n/* Here we assume a standard architecture where the hardware integer\n   types have 8, 16, 32, optionally 64 bits.  */\n\n# undef INT8_MIN\n# undef INT8_MAX\n# undef UINT8_MAX\n# define INT8_MIN  (~ INT8_MAX)\n# define INT8_MAX  127\n# define UINT8_MAX  255\n\n# undef INT16_MIN\n# undef INT16_MAX\n# undef UINT16_MAX\n# define INT16_MIN  (~ INT16_MAX)\n# define INT16_MAX  32767\n# define UINT16_MAX  65535\n\n# undef INT32_MIN\n# undef INT32_MAX\n# undef UINT32_MAX\n# define INT32_MIN  (~ INT32_MAX)\n# define INT32_MAX  2147483647\n# define UINT32_MAX  4294967295U\n\n# if defined GL_INT64_T && ! defined INT64_MAX\n/* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0\n   evaluates the latter incorrectly in preprocessor expressions.  */\n#  define INT64_MIN  (- INTMAX_C (1) << 63)\n#  define INT64_MAX  INTMAX_C (9223372036854775807)\n# endif\n\n# if defined GL_UINT64_T && ! defined UINT64_MAX\n#  define UINT64_MAX  UINTMAX_C (18446744073709551615)\n# endif\n\n/* 7.18.2.2. Limits of minimum-width integer types */\n\n/* Here we assume a standard architecture where the hardware integer\n   types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types\n   are the same as the corresponding N_t types.  */\n\n# undef INT_LEAST8_MIN\n# undef INT_LEAST8_MAX\n# undef UINT_LEAST8_MAX\n# define INT_LEAST8_MIN  INT8_MIN\n# define INT_LEAST8_MAX  INT8_MAX\n# define UINT_LEAST8_MAX  UINT8_MAX\n\n# undef INT_LEAST16_MIN\n# undef INT_LEAST16_MAX\n# undef UINT_LEAST16_MAX\n# define INT_LEAST16_MIN  INT16_MIN\n# define INT_LEAST16_MAX  INT16_MAX\n# define UINT_LEAST16_MAX  UINT16_MAX\n\n# undef INT_LEAST32_MIN\n# undef INT_LEAST32_MAX\n# undef UINT_LEAST32_MAX\n# define INT_LEAST32_MIN  INT32_MIN\n# define INT_LEAST32_MAX  INT32_MAX\n# define UINT_LEAST32_MAX  UINT32_MAX\n\n# undef INT_LEAST64_MIN\n# undef INT_LEAST64_MAX\n# ifdef GL_INT64_T\n#  define INT_LEAST64_MIN  INT64_MIN\n#  define INT_LEAST64_MAX  INT64_MAX\n# endif\n\n# undef UINT_LEAST64_MAX\n# ifdef GL_UINT64_T\n#  define UINT_LEAST64_MAX  UINT64_MAX\n# endif\n\n/* 7.18.2.3. Limits of fastest minimum-width integer types */\n\n/* Here we assume a standard architecture where the hardware integer\n   types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types\n   are taken from the same list of types.  */\n\n# undef INT_FAST8_MIN\n# undef INT_FAST8_MAX\n# undef UINT_FAST8_MAX\n# define INT_FAST8_MIN  SCHAR_MIN\n# define INT_FAST8_MAX  SCHAR_MAX\n# define UINT_FAST8_MAX  UCHAR_MAX\n\n# undef INT_FAST16_MIN\n# undef INT_FAST16_MAX\n# undef UINT_FAST16_MAX\n# define INT_FAST16_MIN  INT_FAST32_MIN\n# define INT_FAST16_MAX  INT_FAST32_MAX\n# define UINT_FAST16_MAX  UINT_FAST32_MAX\n\n# undef INT_FAST32_MIN\n# undef INT_FAST32_MAX\n# undef UINT_FAST32_MAX\n# ifdef __sun\n#  define INT_FAST32_MIN  INT_MIN\n#  define INT_FAST32_MAX  INT_MAX\n#  define UINT_FAST32_MAX  UINT_MAX\n# else\n#  define INT_FAST32_MIN  LONG_MIN\n#  define INT_FAST32_MAX  LONG_MAX\n#  define UINT_FAST32_MAX  ULONG_MAX\n# endif\n\n# undef INT_FAST64_MIN\n# undef INT_FAST64_MAX\n# ifdef GL_INT64_T\n#  define INT_FAST64_MIN  INT64_MIN\n#  define INT_FAST64_MAX  INT64_MAX\n# endif\n\n# undef UINT_FAST64_MAX\n# ifdef GL_UINT64_T\n#  define UINT_FAST64_MAX  UINT64_MAX\n# endif\n\n/* 7.18.2.4. Limits of integer types capable of holding object pointers */\n\n# undef INTPTR_MIN\n# undef INTPTR_MAX\n# undef UINTPTR_MAX\n# ifdef _WIN64\n#  define INTPTR_MIN  LLONG_MIN\n#  define INTPTR_MAX  LLONG_MAX\n#  define UINTPTR_MAX  ULLONG_MAX\n# else\n#  define INTPTR_MIN  LONG_MIN\n#  define INTPTR_MAX  LONG_MAX\n#  define UINTPTR_MAX  ULONG_MAX\n# endif\n\n/* 7.18.2.5. Limits of greatest-width integer types */\n\n# ifndef INTMAX_MAX\n#  undef INTMAX_MIN\n#  ifdef INT64_MAX\n#   define INTMAX_MIN  INT64_MIN\n#   define INTMAX_MAX  INT64_MAX\n#  else\n#   define INTMAX_MIN  INT32_MIN\n#   define INTMAX_MAX  INT32_MAX\n#  endif\n# endif\n\n# ifndef UINTMAX_MAX\n#  ifdef UINT64_MAX\n#   define UINTMAX_MAX  UINT64_MAX\n#  else\n#   define UINTMAX_MAX  UINT32_MAX\n#  endif\n# endif\n\n/* 7.18.3. Limits of other integer types */\n\n/* ptrdiff_t limits */\n# undef PTRDIFF_MIN\n# undef PTRDIFF_MAX\n# if @APPLE_UNIVERSAL_BUILD@\n#  ifdef _LP64\n#   define PTRDIFF_MIN  _STDINT_SIGNED_MIN (64, 0l)\n#   define PTRDIFF_MAX  _STDINT_MAX (1, 64, 0l)\n#  else\n#   define PTRDIFF_MIN  _STDINT_SIGNED_MIN (32, 0)\n#   define PTRDIFF_MAX  _STDINT_MAX (1, 32, 0)\n#  endif\n# else\n#  define PTRDIFF_MIN  \\\n    _STDINT_SIGNED_MIN (@BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@)\n#  define PTRDIFF_MAX  \\\n    _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@)\n# endif\n\n/* sig_atomic_t limits */\n# undef SIG_ATOMIC_MIN\n# undef SIG_ATOMIC_MAX\n# if @HAVE_SIGNED_SIG_ATOMIC_T@\n#  define SIG_ATOMIC_MIN  \\\n    _STDINT_SIGNED_MIN (@BITSIZEOF_SIG_ATOMIC_T@, 0@SIG_ATOMIC_T_SUFFIX@)\n# else\n#  define SIG_ATOMIC_MIN  \\\n    _STDINT_UNSIGNED_MIN (@BITSIZEOF_SIG_ATOMIC_T@, 0@SIG_ATOMIC_T_SUFFIX@)\n# endif\n# define SIG_ATOMIC_MAX  \\\n   _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \\\n                0@SIG_ATOMIC_T_SUFFIX@)\n\n\n/* size_t limit */\n# undef SIZE_MAX\n# if @APPLE_UNIVERSAL_BUILD@\n#  ifdef _LP64\n#   define SIZE_MAX  _STDINT_MAX (0, 64, 0ul)\n#  else\n#   define SIZE_MAX  _STDINT_MAX (0, 32, 0ul)\n#  endif\n# else\n#  define SIZE_MAX  _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@)\n# endif\n\n/* wchar_t limits */\n/* Get WCHAR_MIN, WCHAR_MAX.\n   This include is not on the top, above, because on OSF/1 4.0 we have a\n   sequence of nested includes\n   <wchar.h> -> <stdio.h> -> <getopt.h> -> <stdlib.h>, and the latter includes\n   <stdint.h> and assumes its types are already defined.  */\n# if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX)\n#  define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H\n#  include <wchar.h>\n#  undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H\n# endif\n# undef WCHAR_MIN\n# undef WCHAR_MAX\n# if @HAVE_SIGNED_WCHAR_T@\n#  define WCHAR_MIN  \\\n    _STDINT_SIGNED_MIN (@BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)\n# else\n#  define WCHAR_MIN  \\\n    _STDINT_UNSIGNED_MIN (@BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)\n# endif\n# define WCHAR_MAX  \\\n   _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)\n\n/* wint_t limits */\n/* If gnulib's <wchar.h> or <wctype.h> overrides wint_t, @WINT_T_SUFFIX@ is not\n   accurate, therefore use the definitions from above.  */\n# if !@GNULIBHEADERS_OVERRIDE_WINT_T@\n#  undef WINT_MIN\n#  undef WINT_MAX\n#  if @HAVE_SIGNED_WINT_T@\n#   define WINT_MIN  \\\n     _STDINT_SIGNED_MIN (@BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)\n#  else\n#   define WINT_MIN  \\\n     _STDINT_UNSIGNED_MIN (@BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)\n#  endif\n#  define WINT_MAX  \\\n    _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)\n# endif\n\n/* 7.18.4. Macros for integer constants */\n\n/* 7.18.4.1. Macros for minimum-width integer constants */\n/* According to ISO C 99 Technical Corrigendum 1 */\n\n/* Here we assume a standard architecture where the hardware integer\n   types have 8, 16, 32, optionally 64 bits, and int is 32 bits.  */\n\n# undef INT8_C\n# undef UINT8_C\n# define INT8_C(x) x\n# define UINT8_C(x) x\n\n# undef INT16_C\n# undef UINT16_C\n# define INT16_C(x) x\n# define UINT16_C(x) x\n\n# undef INT32_C\n# undef UINT32_C\n# define INT32_C(x) x\n# define UINT32_C(x) x ## U\n\n# undef INT64_C\n# undef UINT64_C\n# if LONG_MAX >> 31 >> 31 == 1\n#  define INT64_C(x) x##L\n# elif defined _MSC_VER\n#  define INT64_C(x) x##i64\n# else\n#  define INT64_C(x) x##LL\n# endif\n# if ULONG_MAX >> 31 >> 31 >> 1 == 1\n#  define UINT64_C(x) x##UL\n# elif defined _MSC_VER\n#  define UINT64_C(x) x##ui64\n# else\n#  define UINT64_C(x) x##ULL\n# endif\n\n/* 7.18.4.2. Macros for greatest-width integer constants */\n\n# ifndef INTMAX_C\n#  if LONG_MAX >> 30 == 1\n#   define INTMAX_C(x)   x##LL\n#  elif defined GL_INT64_T\n#   define INTMAX_C(x)   INT64_C(x)\n#  else\n#   define INTMAX_C(x)   x##L\n#  endif\n# endif\n\n# ifndef UINTMAX_C\n#  if ULONG_MAX >> 31 == 1\n#   define UINTMAX_C(x)  x##ULL\n#  elif defined GL_UINT64_T\n#   define UINTMAX_C(x)  UINT64_C(x)\n#  else\n#   define UINTMAX_C(x)  x##UL\n#  endif\n# endif\n\n#endif /* !@HAVE_C99_STDINT_H@ */\n\n/* Macros specified by ISO/IEC TS 18661-1:2014.  */\n\n#if (!defined UINTMAX_WIDTH \\\n     && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__))\n# ifdef INT8_MAX\n#  define INT8_WIDTH _GL_INTEGER_WIDTH (INT8_MIN, INT8_MAX)\n# endif\n# ifdef UINT8_MAX\n#  define UINT8_WIDTH _GL_INTEGER_WIDTH (0, UINT8_MAX)\n# endif\n# ifdef INT16_MAX\n#  define INT16_WIDTH _GL_INTEGER_WIDTH (INT16_MIN, INT16_MAX)\n# endif\n# ifdef UINT16_MAX\n#  define UINT16_WIDTH _GL_INTEGER_WIDTH (0, UINT16_MAX)\n# endif\n# ifdef INT32_MAX\n#  define INT32_WIDTH _GL_INTEGER_WIDTH (INT32_MIN, INT32_MAX)\n# endif\n# ifdef UINT32_MAX\n#  define UINT32_WIDTH _GL_INTEGER_WIDTH (0, UINT32_MAX)\n# endif\n# ifdef INT64_MAX\n#  define INT64_WIDTH _GL_INTEGER_WIDTH (INT64_MIN, INT64_MAX)\n# endif\n# ifdef UINT64_MAX\n#  define UINT64_WIDTH _GL_INTEGER_WIDTH (0, UINT64_MAX)\n# endif\n# define INT_LEAST8_WIDTH _GL_INTEGER_WIDTH (INT_LEAST8_MIN, INT_LEAST8_MAX)\n# define UINT_LEAST8_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST8_MAX)\n# define INT_LEAST16_WIDTH _GL_INTEGER_WIDTH (INT_LEAST16_MIN, INT_LEAST16_MAX)\n# define UINT_LEAST16_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST16_MAX)\n# define INT_LEAST32_WIDTH _GL_INTEGER_WIDTH (INT_LEAST32_MIN, INT_LEAST32_MAX)\n# define UINT_LEAST32_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST32_MAX)\n# define INT_LEAST64_WIDTH _GL_INTEGER_WIDTH (INT_LEAST64_MIN, INT_LEAST64_MAX)\n# define UINT_LEAST64_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST64_MAX)\n# define INT_FAST8_WIDTH _GL_INTEGER_WIDTH (INT_FAST8_MIN, INT_FAST8_MAX)\n# define UINT_FAST8_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST8_MAX)\n# define INT_FAST16_WIDTH _GL_INTEGER_WIDTH (INT_FAST16_MIN, INT_FAST16_MAX)\n# define UINT_FAST16_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST16_MAX)\n# define INT_FAST32_WIDTH _GL_INTEGER_WIDTH (INT_FAST32_MIN, INT_FAST32_MAX)\n# define UINT_FAST32_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST32_MAX)\n# define INT_FAST64_WIDTH _GL_INTEGER_WIDTH (INT_FAST64_MIN, INT_FAST64_MAX)\n# define UINT_FAST64_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST64_MAX)\n# define INTPTR_WIDTH _GL_INTEGER_WIDTH (INTPTR_MIN, INTPTR_MAX)\n# define UINTPTR_WIDTH _GL_INTEGER_WIDTH (0, UINTPTR_MAX)\n# define INTMAX_WIDTH _GL_INTEGER_WIDTH (INTMAX_MIN, INTMAX_MAX)\n# define UINTMAX_WIDTH _GL_INTEGER_WIDTH (0, UINTMAX_MAX)\n# define PTRDIFF_WIDTH _GL_INTEGER_WIDTH (PTRDIFF_MIN, PTRDIFF_MAX)\n# define SIZE_WIDTH _GL_INTEGER_WIDTH (0, SIZE_MAX)\n# define WCHAR_WIDTH _GL_INTEGER_WIDTH (WCHAR_MIN, WCHAR_MAX)\n# ifdef WINT_MAX\n#  define WINT_WIDTH _GL_INTEGER_WIDTH (WINT_MIN, WINT_MAX)\n# endif\n# ifdef SIG_ATOMIC_MAX\n#  define SIG_ATOMIC_WIDTH _GL_INTEGER_WIDTH (SIG_ATOMIC_MIN, SIG_ATOMIC_MAX)\n# endif\n#endif /* !WINT_WIDTH && (_GNU_SOURCE || __STDC_WANT_IEC_60559_BFP_EXT__) */\n\n#endif /* _@GUARD_PREFIX@_STDINT_H */\n#endif /* !(defined __ANDROID__ && ...) */\n#endif /* !defined _@GUARD_PREFIX@_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */\n"
  },
  {
    "path": "gnulib/stdlib.in.h",
    "content": "/* A GNU-like <stdlib.h>.\n\n   Copyright (C) 1995, 2001-2004, 2006-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n#if defined __need_system_stdlib_h || defined __need_malloc_and_calloc\n/* Special invocation conventions inside some gnulib header files,\n   and inside some glibc header files, respectively.  */\n\n#@INCLUDE_NEXT@ @NEXT_STDLIB_H@\n\n#else\n/* Normal invocation convention.  */\n\n#ifndef _@GUARD_PREFIX@_STDLIB_H\n\n/* The include_next requires a split double-inclusion guard.  */\n#@INCLUDE_NEXT@ @NEXT_STDLIB_H@\n\n#ifndef _@GUARD_PREFIX@_STDLIB_H\n#define _@GUARD_PREFIX@_STDLIB_H\n\n/* NetBSD 5.0 mis-defines NULL.  */\n#include <stddef.h>\n\n/* MirBSD 10 defines WEXITSTATUS in <sys/wait.h>, not in <stdlib.h>.  */\n#if @GNULIB_SYSTEM_POSIX@ && !defined WEXITSTATUS\n# include <sys/wait.h>\n#endif\n\n/* Solaris declares getloadavg() in <sys/loadavg.h>.  */\n#if (@GNULIB_GETLOADAVG@ || defined GNULIB_POSIXCHECK) && @HAVE_SYS_LOADAVG_H@\n/* OpenIndiana has a bug: <sys/time.h> must be included before\n   <sys/loadavg.h>.  */\n# include <sys/time.h>\n# include <sys/loadavg.h>\n#endif\n\n/* Native Windows platforms declare _mktemp() in <io.h>.  */\n#if defined _WIN32 && !defined __CYGWIN__\n# include <io.h>\n#endif\n\n#if @GNULIB_RANDOM_R@\n\n/* OSF/1 5.1 declares 'struct random_data' in <random.h>, which is included\n   from <stdlib.h> if _REENTRANT is defined.  Include it whenever we need\n   'struct random_data'.  */\n# if @HAVE_RANDOM_H@\n#  include <random.h>\n# endif\n\n# if !@HAVE_STRUCT_RANDOM_DATA@ || @REPLACE_RANDOM_R@ || !@HAVE_RANDOM_R@\n#  include <stdint.h>\n# endif\n\n# if !@HAVE_STRUCT_RANDOM_DATA@\n/* Define 'struct random_data'.\n   But allow multiple gnulib generated <stdlib.h> replacements to coexist.  */\n#  if !GNULIB_defined_struct_random_data\nstruct random_data\n{\n  int32_t *fptr;                /* Front pointer.  */\n  int32_t *rptr;                /* Rear pointer.  */\n  int32_t *state;               /* Array of state values.  */\n  int rand_type;                /* Type of random number generator.  */\n  int rand_deg;                 /* Degree of random number generator.  */\n  int rand_sep;                 /* Distance between front and rear.  */\n  int32_t *end_ptr;             /* Pointer behind state table.  */\n};\n#   define GNULIB_defined_struct_random_data 1\n#  endif\n# endif\n#endif\n\n#if (@GNULIB_MKSTEMP@ || @GNULIB_MKSTEMPS@ || @GNULIB_MKOSTEMP@ || @GNULIB_MKOSTEMPS@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !(defined _WIN32 && ! defined __CYGWIN__)\n/* On Mac OS X 10.3, only <unistd.h> declares mkstemp.  */\n/* On Mac OS X 10.5, only <unistd.h> declares mkstemps.  */\n/* On Mac OS X 10.13, only <unistd.h> declares mkostemp and mkostemps.  */\n/* On Cygwin 1.7.1, only <unistd.h> declares getsubopt.  */\n/* But avoid namespace pollution on glibc systems and native Windows.  */\n# include <unistd.h>\n#endif\n\n/* The __attribute__ feature is available in gcc versions 2.5 and later.\n   The attribute __pure__ was added in gcc 2.96.  */\n#ifndef _GL_ATTRIBUTE_PURE\n# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__\n#  define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))\n# else\n#  define _GL_ATTRIBUTE_PURE /* empty */\n# endif\n#endif\n\n/* The definition of _Noreturn is copied here.  */\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n\n\n/* Some systems do not define EXIT_*, despite otherwise supporting C89.  */\n#ifndef EXIT_SUCCESS\n# define EXIT_SUCCESS 0\n#endif\n/* Tandem/NSK and other platforms that define EXIT_FAILURE as -1 interfere\n   with proper operation of xargs.  */\n#ifndef EXIT_FAILURE\n# define EXIT_FAILURE 1\n#elif EXIT_FAILURE != 1\n# undef EXIT_FAILURE\n# define EXIT_FAILURE 1\n#endif\n\n\n#if @GNULIB__EXIT@\n/* Terminate the current process with the given return code, without running\n   the 'atexit' handlers.  */\n# if !@HAVE__EXIT@\n_GL_FUNCDECL_SYS (_Exit, _Noreturn void, (int status));\n# endif\n_GL_CXXALIAS_SYS (_Exit, void, (int status));\n_GL_CXXALIASWARN (_Exit);\n#elif defined GNULIB_POSIXCHECK\n# undef _Exit\n# if HAVE_RAW_DECL__EXIT\n_GL_WARN_ON_USE (_Exit, \"_Exit is unportable - \"\n                 \"use gnulib module _Exit for portability\");\n# endif\n#endif\n\n\n/* Allocate memory with indefinite extent and specified alignment.  */\n#if @GNULIB_ALIGNED_ALLOC@\n# if @REPLACE_ALIGNED_ALLOC@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef aligned_alloc\n#   define aligned_alloc rpl_aligned_alloc\n#  endif\n_GL_FUNCDECL_RPL (aligned_alloc, void *, (size_t alignment, size_t size));\n_GL_CXXALIAS_RPL (aligned_alloc, void *, (size_t alignment, size_t size));\n# else\n#  if @HAVE_ALIGNED_ALLOC@\n_GL_CXXALIAS_SYS (aligned_alloc, void *, (size_t alignment, size_t size));\n#  endif\n# endif\n# if @HAVE_ALIGNED_ALLOC@\n_GL_CXXALIASWARN (aligned_alloc);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef aligned_alloc\n# if HAVE_RAW_DECL_ALIGNED_ALLOC\n_GL_WARN_ON_USE (aligned_alloc, \"aligned_alloc is not portable - \"\n                 \"use gnulib module aligned_alloc for portability\");\n# endif\n#endif\n\n#if @GNULIB_ATOLL@\n/* Parse a signed decimal integer.\n   Returns the value of the integer.  Errors are not detected.  */\n# if !@HAVE_ATOLL@\n_GL_FUNCDECL_SYS (atoll, long long, (const char *string)\n                                    _GL_ATTRIBUTE_PURE\n                                    _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (atoll, long long, (const char *string));\n_GL_CXXALIASWARN (atoll);\n#elif defined GNULIB_POSIXCHECK\n# undef atoll\n# if HAVE_RAW_DECL_ATOLL\n_GL_WARN_ON_USE (atoll, \"atoll is unportable - \"\n                 \"use gnulib module atoll for portability\");\n# endif\n#endif\n\n#if @GNULIB_CALLOC_POSIX@\n# if @REPLACE_CALLOC@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef calloc\n#   define calloc rpl_calloc\n#  endif\n_GL_FUNCDECL_RPL (calloc, void *, (size_t nmemb, size_t size));\n_GL_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size));\n# else\n_GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (calloc);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef calloc\n/* Assume calloc is always declared.  */\n_GL_WARN_ON_USE (calloc, \"calloc is not POSIX compliant everywhere - \"\n                 \"use gnulib module calloc-posix for portability\");\n#endif\n\n#if @GNULIB_CANONICALIZE_FILE_NAME@\n# if @REPLACE_CANONICALIZE_FILE_NAME@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define canonicalize_file_name rpl_canonicalize_file_name\n#  endif\n_GL_FUNCDECL_RPL (canonicalize_file_name, char *, (const char *name)\n                                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name));\n# else\n#  if !@HAVE_CANONICALIZE_FILE_NAME@\n_GL_FUNCDECL_SYS (canonicalize_file_name, char *, (const char *name)\n                                                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name));\n# endif\n# ifndef GNULIB_defined_canonicalize_file_name\n#  define GNULIB_defined_canonicalize_file_name \\\n     (!@HAVE_CANONICALIZE_FILE_NAME@ || @REPLACE_CANONICALIZE_FILE_NAME@)\n# endif\n_GL_CXXALIASWARN (canonicalize_file_name);\n#elif defined GNULIB_POSIXCHECK\n# undef canonicalize_file_name\n# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME\n_GL_WARN_ON_USE (canonicalize_file_name,\n                 \"canonicalize_file_name is unportable - \"\n                 \"use gnulib module canonicalize-lgpl for portability\");\n# endif\n#endif\n\n#if @GNULIB_MDA_ECVT@\n/* On native Windows, map 'ecvt' to '_ecvt', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::ecvt on all platforms that have\n   it.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef ecvt\n#   define ecvt _ecvt\n#  endif\n_GL_CXXALIAS_MDA (ecvt, char *,\n                  (double number, int ndigits, int *decptp, int *signp));\n# else\n#  if @HAVE_DECL_ECVT@\n_GL_CXXALIAS_SYS (ecvt, char *,\n                  (double number, int ndigits, int *decptp, int *signp));\n#  endif\n# endif\n# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_ECVT@\n_GL_CXXALIASWARN (ecvt);\n# endif\n#endif\n\n#if @GNULIB_MDA_FCVT@\n/* On native Windows, map 'fcvt' to '_fcvt', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::fcvt on all platforms that have\n   it.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef fcvt\n#   define fcvt _fcvt\n#  endif\n_GL_CXXALIAS_MDA (fcvt, char *,\n                  (double number, int ndigits, int *decptp, int *signp));\n# else\n#  if @HAVE_DECL_FCVT@\n_GL_CXXALIAS_SYS (fcvt, char *,\n                  (double number, int ndigits, int *decptp, int *signp));\n#  endif\n# endif\n# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_FCVT@\n_GL_CXXALIASWARN (fcvt);\n# endif\n#endif\n\n#if @GNULIB_FREE_POSIX@\n# if @REPLACE_FREE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef free\n#   define free rpl_free\n#  endif\n_GL_FUNCDECL_RPL (free, void, (void *ptr));\n_GL_CXXALIAS_RPL (free, void, (void *ptr));\n# else\n_GL_CXXALIAS_SYS (free, void, (void *ptr));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (free);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef free\n/* Assume free is always declared.  */\n_GL_WARN_ON_USE (free, \"free is not future POSIX compliant everywhere - \"\n                 \"use gnulib module free for portability\");\n#endif\n\n#if @GNULIB_MDA_GCVT@\n/* On native Windows, map 'gcvt' to '_gcvt', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::gcvt on all platforms that have\n   it.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef gcvt\n#   define gcvt _gcvt\n#  endif\n_GL_CXXALIAS_MDA (gcvt, char *, (double number, int ndigits, char *buf));\n# else\n#  if @HAVE_DECL_GCVT@\n_GL_CXXALIAS_SYS (gcvt, char *, (double number, int ndigits, char *buf));\n#  endif\n# endif\n# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_GCVT@\n_GL_CXXALIASWARN (gcvt);\n# endif\n#endif\n\n#if @GNULIB_GETLOADAVG@\n/* Store max(NELEM,3) load average numbers in LOADAVG[].\n   The three numbers are the load average of the last 1 minute, the last 5\n   minutes, and the last 15 minutes, respectively.\n   LOADAVG is an array of NELEM numbers.  */\n# if !@HAVE_DECL_GETLOADAVG@\n_GL_FUNCDECL_SYS (getloadavg, int, (double loadavg[], int nelem)\n                                   _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (getloadavg, int, (double loadavg[], int nelem));\n_GL_CXXALIASWARN (getloadavg);\n#elif defined GNULIB_POSIXCHECK\n# undef getloadavg\n# if HAVE_RAW_DECL_GETLOADAVG\n_GL_WARN_ON_USE (getloadavg, \"getloadavg is not portable - \"\n                 \"use gnulib module getloadavg for portability\");\n# endif\n#endif\n\n#if @GNULIB_GETSUBOPT@\n/* Assuming *OPTIONP is a comma separated list of elements of the form\n   \"token\" or \"token=value\", getsubopt parses the first of these elements.\n   If the first element refers to a \"token\" that is member of the given\n   NULL-terminated array of tokens:\n     - It replaces the comma with a NUL byte, updates *OPTIONP to point past\n       the first option and the comma, sets *VALUEP to the value of the\n       element (or NULL if it doesn't contain an \"=\" sign),\n     - It returns the index of the \"token\" in the given array of tokens.\n   Otherwise it returns -1, and *OPTIONP and *VALUEP are undefined.\n   For more details see the POSIX specification.\n   https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsubopt.html */\n# if !@HAVE_GETSUBOPT@\n_GL_FUNCDECL_SYS (getsubopt, int,\n                  (char **optionp, char *const *tokens, char **valuep)\n                  _GL_ARG_NONNULL ((1, 2, 3)));\n# endif\n_GL_CXXALIAS_SYS (getsubopt, int,\n                  (char **optionp, char *const *tokens, char **valuep));\n_GL_CXXALIASWARN (getsubopt);\n#elif defined GNULIB_POSIXCHECK\n# undef getsubopt\n# if HAVE_RAW_DECL_GETSUBOPT\n_GL_WARN_ON_USE (getsubopt, \"getsubopt is unportable - \"\n                 \"use gnulib module getsubopt for portability\");\n# endif\n#endif\n\n#if @GNULIB_GRANTPT@\n/* Change the ownership and access permission of the slave side of the\n   pseudo-terminal whose master side is specified by FD.  */\n# if !@HAVE_GRANTPT@\n_GL_FUNCDECL_SYS (grantpt, int, (int fd));\n# endif\n_GL_CXXALIAS_SYS (grantpt, int, (int fd));\n_GL_CXXALIASWARN (grantpt);\n#elif defined GNULIB_POSIXCHECK\n# undef grantpt\n# if HAVE_RAW_DECL_GRANTPT\n_GL_WARN_ON_USE (grantpt, \"grantpt is not portable - \"\n                 \"use gnulib module grantpt for portability\");\n# endif\n#endif\n\n/* If _GL_USE_STDLIB_ALLOC is nonzero, the including module does not\n   rely on GNU or POSIX semantics for malloc and realloc (for example,\n   by never specifying a zero size), so it does not need malloc or\n   realloc to be redefined.  */\n#if @GNULIB_MALLOC_POSIX@\n# if @REPLACE_MALLOC@\n#  if !((defined __cplusplus && defined GNULIB_NAMESPACE) \\\n        || _GL_USE_STDLIB_ALLOC)\n#   undef malloc\n#   define malloc rpl_malloc\n#  endif\n_GL_FUNCDECL_RPL (malloc, void *, (size_t size));\n_GL_CXXALIAS_RPL (malloc, void *, (size_t size));\n# else\n_GL_CXXALIAS_SYS (malloc, void *, (size_t size));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (malloc);\n# endif\n#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC\n# undef malloc\n/* Assume malloc is always declared.  */\n_GL_WARN_ON_USE (malloc, \"malloc is not POSIX compliant everywhere - \"\n                 \"use gnulib module malloc-posix for portability\");\n#endif\n\n/* Convert a multibyte character to a wide character.  */\n#if @GNULIB_MBTOWC@\n# if @REPLACE_MBTOWC@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbtowc\n#   define mbtowc rpl_mbtowc\n#  endif\n_GL_FUNCDECL_RPL (mbtowc, int,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n));\n_GL_CXXALIAS_RPL (mbtowc, int,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n));\n# else\n#  if !@HAVE_MBTOWC@\n_GL_FUNCDECL_SYS (mbtowc, int,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n));\n#  endif\n_GL_CXXALIAS_SYS (mbtowc, int,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (mbtowc);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef mbtowc\n# if HAVE_RAW_DECL_MBTOWC\n_GL_WARN_ON_USE (mbtowc, \"mbtowc is not portable - \"\n                 \"use gnulib module mbtowc for portability\");\n# endif\n#endif\n\n#if @GNULIB_MKDTEMP@\n/* Create a unique temporary directory from TEMPLATE.\n   The last six characters of TEMPLATE must be \"XXXXXX\";\n   they are replaced with a string that makes the directory name unique.\n   Returns TEMPLATE, or a null pointer if it cannot get a unique name.\n   The directory is created mode 700.  */\n# if !@HAVE_MKDTEMP@\n_GL_FUNCDECL_SYS (mkdtemp, char *, (char * /*template*/) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (mkdtemp, char *, (char * /*template*/));\n_GL_CXXALIASWARN (mkdtemp);\n#elif defined GNULIB_POSIXCHECK\n# undef mkdtemp\n# if HAVE_RAW_DECL_MKDTEMP\n_GL_WARN_ON_USE (mkdtemp, \"mkdtemp is unportable - \"\n                 \"use gnulib module mkdtemp for portability\");\n# endif\n#endif\n\n#if @GNULIB_MKOSTEMP@\n/* Create a unique temporary file from TEMPLATE.\n   The last six characters of TEMPLATE must be \"XXXXXX\";\n   they are replaced with a string that makes the file name unique.\n   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)\n   and O_TEXT, O_BINARY (defined in \"binary-io.h\").\n   The file is then created, with the specified flags, ensuring it didn't exist\n   before.\n   The file is created read-write (mask at least 0600 & ~umask), but it may be\n   world-readable and world-writable (mask 0666 & ~umask), depending on the\n   implementation.\n   Returns the open file descriptor if successful, otherwise -1 and errno\n   set.  */\n# if !@HAVE_MKOSTEMP@\n_GL_FUNCDECL_SYS (mkostemp, int, (char * /*template*/, int /*flags*/)\n                                 _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (mkostemp, int, (char * /*template*/, int /*flags*/));\n_GL_CXXALIASWARN (mkostemp);\n#elif defined GNULIB_POSIXCHECK\n# undef mkostemp\n# if HAVE_RAW_DECL_MKOSTEMP\n_GL_WARN_ON_USE (mkostemp, \"mkostemp is unportable - \"\n                 \"use gnulib module mkostemp for portability\");\n# endif\n#endif\n\n#if @GNULIB_MKOSTEMPS@\n/* Create a unique temporary file from TEMPLATE.\n   The last six characters of TEMPLATE before a suffix of length\n   SUFFIXLEN must be \"XXXXXX\";\n   they are replaced with a string that makes the file name unique.\n   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)\n   and O_TEXT, O_BINARY (defined in \"binary-io.h\").\n   The file is then created, with the specified flags, ensuring it didn't exist\n   before.\n   The file is created read-write (mask at least 0600 & ~umask), but it may be\n   world-readable and world-writable (mask 0666 & ~umask), depending on the\n   implementation.\n   Returns the open file descriptor if successful, otherwise -1 and errno\n   set.  */\n# if !@HAVE_MKOSTEMPS@\n_GL_FUNCDECL_SYS (mkostemps, int,\n                  (char * /*template*/, int /*suffixlen*/, int /*flags*/)\n                  _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (mkostemps, int,\n                  (char * /*template*/, int /*suffixlen*/, int /*flags*/));\n_GL_CXXALIASWARN (mkostemps);\n#elif defined GNULIB_POSIXCHECK\n# undef mkostemps\n# if HAVE_RAW_DECL_MKOSTEMPS\n_GL_WARN_ON_USE (mkostemps, \"mkostemps is unportable - \"\n                 \"use gnulib module mkostemps for portability\");\n# endif\n#endif\n\n#if @GNULIB_MKSTEMP@\n/* Create a unique temporary file from TEMPLATE.\n   The last six characters of TEMPLATE must be \"XXXXXX\";\n   they are replaced with a string that makes the file name unique.\n   The file is then created, ensuring it didn't exist before.\n   The file is created read-write (mask at least 0600 & ~umask), but it may be\n   world-readable and world-writable (mask 0666 & ~umask), depending on the\n   implementation.\n   Returns the open file descriptor if successful, otherwise -1 and errno\n   set.  */\n# if @REPLACE_MKSTEMP@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define mkstemp rpl_mkstemp\n#  endif\n_GL_FUNCDECL_RPL (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (mkstemp, int, (char * /*template*/));\n# else\n#  if ! @HAVE_MKSTEMP@\n_GL_FUNCDECL_SYS (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (mkstemp, int, (char * /*template*/));\n# endif\n_GL_CXXALIASWARN (mkstemp);\n#elif defined GNULIB_POSIXCHECK\n# undef mkstemp\n# if HAVE_RAW_DECL_MKSTEMP\n_GL_WARN_ON_USE (mkstemp, \"mkstemp is unportable - \"\n                 \"use gnulib module mkstemp for portability\");\n# endif\n#endif\n\n#if @GNULIB_MKSTEMPS@\n/* Create a unique temporary file from TEMPLATE.\n   The last six characters of TEMPLATE prior to a suffix of length\n   SUFFIXLEN must be \"XXXXXX\";\n   they are replaced with a string that makes the file name unique.\n   The file is then created, ensuring it didn't exist before.\n   The file is created read-write (mask at least 0600 & ~umask), but it may be\n   world-readable and world-writable (mask 0666 & ~umask), depending on the\n   implementation.\n   Returns the open file descriptor if successful, otherwise -1 and errno\n   set.  */\n# if !@HAVE_MKSTEMPS@\n_GL_FUNCDECL_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/)\n                                 _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/));\n_GL_CXXALIASWARN (mkstemps);\n#elif defined GNULIB_POSIXCHECK\n# undef mkstemps\n# if HAVE_RAW_DECL_MKSTEMPS\n_GL_WARN_ON_USE (mkstemps, \"mkstemps is unportable - \"\n                 \"use gnulib module mkstemps for portability\");\n# endif\n#endif\n\n#if @GNULIB_MDA_MKTEMP@\n/* On native Windows, map 'mktemp' to '_mktemp', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::mktemp always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mktemp\n#   define mktemp _mktemp\n#  endif\n_GL_CXXALIAS_MDA (mktemp, char *, (char * /*template*/));\n# else\n_GL_CXXALIAS_SYS (mktemp, char *, (char * /*template*/));\n# endif\n_GL_CXXALIASWARN (mktemp);\n#endif\n\n/* Allocate memory with indefinite extent and specified alignment.  */\n#if @GNULIB_POSIX_MEMALIGN@\n# if @REPLACE_POSIX_MEMALIGN@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef posix_memalign\n#   define posix_memalign rpl_posix_memalign\n#  endif\n_GL_FUNCDECL_RPL (posix_memalign, int,\n                  (void **memptr, size_t alignment, size_t size)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (posix_memalign, int,\n                  (void **memptr, size_t alignment, size_t size));\n# else\n#  if @HAVE_POSIX_MEMALIGN@\n_GL_CXXALIAS_SYS (posix_memalign, int,\n                  (void **memptr, size_t alignment, size_t size));\n#  endif\n# endif\n# if @HAVE_POSIX_MEMALIGN@\n_GL_CXXALIASWARN (posix_memalign);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef posix_memalign\n# if HAVE_RAW_DECL_POSIX_MEMALIGN\n_GL_WARN_ON_USE (posix_memalign, \"posix_memalign is not portable - \"\n                 \"use gnulib module posix_memalign for portability\");\n# endif\n#endif\n\n#if @GNULIB_POSIX_OPENPT@\n/* Return an FD open to the master side of a pseudo-terminal.  Flags should\n   include O_RDWR, and may also include O_NOCTTY.  */\n# if !@HAVE_POSIX_OPENPT@\n_GL_FUNCDECL_SYS (posix_openpt, int, (int flags));\n# endif\n_GL_CXXALIAS_SYS (posix_openpt, int, (int flags));\n_GL_CXXALIASWARN (posix_openpt);\n#elif defined GNULIB_POSIXCHECK\n# undef posix_openpt\n# if HAVE_RAW_DECL_POSIX_OPENPT\n_GL_WARN_ON_USE (posix_openpt, \"posix_openpt is not portable - \"\n                 \"use gnulib module posix_openpt for portability\");\n# endif\n#endif\n\n#if @GNULIB_PTSNAME@\n/* Return the pathname of the pseudo-terminal slave associated with\n   the master FD is open on, or NULL on errors.  */\n# if @REPLACE_PTSNAME@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef ptsname\n#   define ptsname rpl_ptsname\n#  endif\n_GL_FUNCDECL_RPL (ptsname, char *, (int fd));\n_GL_CXXALIAS_RPL (ptsname, char *, (int fd));\n# else\n#  if !@HAVE_PTSNAME@\n_GL_FUNCDECL_SYS (ptsname, char *, (int fd));\n#  endif\n_GL_CXXALIAS_SYS (ptsname, char *, (int fd));\n# endif\n_GL_CXXALIASWARN (ptsname);\n#elif defined GNULIB_POSIXCHECK\n# undef ptsname\n# if HAVE_RAW_DECL_PTSNAME\n_GL_WARN_ON_USE (ptsname, \"ptsname is not portable - \"\n                 \"use gnulib module ptsname for portability\");\n# endif\n#endif\n\n#if @GNULIB_PTSNAME_R@\n/* Set the pathname of the pseudo-terminal slave associated with\n   the master FD is open on and return 0, or set errno and return\n   non-zero on errors.  */\n# if @REPLACE_PTSNAME_R@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef ptsname_r\n#   define ptsname_r rpl_ptsname_r\n#  endif\n_GL_FUNCDECL_RPL (ptsname_r, int, (int fd, char *buf, size_t len));\n_GL_CXXALIAS_RPL (ptsname_r, int, (int fd, char *buf, size_t len));\n# else\n#  if !@HAVE_PTSNAME_R@\n_GL_FUNCDECL_SYS (ptsname_r, int, (int fd, char *buf, size_t len));\n#  endif\n_GL_CXXALIAS_SYS (ptsname_r, int, (int fd, char *buf, size_t len));\n# endif\n# ifndef GNULIB_defined_ptsname_r\n#  define GNULIB_defined_ptsname_r (!@HAVE_PTSNAME_R@ || @REPLACE_PTSNAME_R@)\n# endif\n_GL_CXXALIASWARN (ptsname_r);\n#elif defined GNULIB_POSIXCHECK\n# undef ptsname_r\n# if HAVE_RAW_DECL_PTSNAME_R\n_GL_WARN_ON_USE (ptsname_r, \"ptsname_r is not portable - \"\n                 \"use gnulib module ptsname_r for portability\");\n# endif\n#endif\n\n#if @GNULIB_PUTENV@\n# if @REPLACE_PUTENV@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef putenv\n#   define putenv rpl_putenv\n#  endif\n_GL_FUNCDECL_RPL (putenv, int, (char *string) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (putenv, int, (char *string));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef putenv\n#   define putenv _putenv\n#  endif\n_GL_CXXALIAS_MDA (putenv, int, (char *string));\n# else\n_GL_CXXALIAS_SYS (putenv, int, (char *string));\n# endif\n_GL_CXXALIASWARN (putenv);\n#elif @GNULIB_MDA_PUTENV@\n/* On native Windows, map 'putenv' to '_putenv', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::putenv always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef putenv\n#   define putenv _putenv\n#  endif\n/* Need to cast, because on mingw, the parameter is either\n   'const char *string' or 'char *string'.  */\n_GL_CXXALIAS_MDA_CAST (putenv, int, (char *string));\n# else\n_GL_CXXALIAS_SYS (putenv, int, (char *string));\n# endif\n_GL_CXXALIASWARN (putenv);\n#endif\n\n#if @GNULIB_QSORT_R@\n/* Sort an array of NMEMB elements, starting at address BASE, each element\n   occupying SIZE bytes, in ascending order according to the comparison\n   function COMPARE.  */\n# if @REPLACE_QSORT_R@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef qsort_r\n#   define qsort_r rpl_qsort_r\n#  endif\n_GL_FUNCDECL_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size,\n                                  int (*compare) (void const *, void const *,\n                                                  void *),\n                                  void *arg) _GL_ARG_NONNULL ((1, 4)));\n_GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size,\n                                  int (*compare) (void const *, void const *,\n                                                  void *),\n                                  void *arg));\n# else\n#  if !@HAVE_QSORT_R@\n_GL_FUNCDECL_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size,\n                                  int (*compare) (void const *, void const *,\n                                                  void *),\n                                  void *arg) _GL_ARG_NONNULL ((1, 4)));\n#  endif\n_GL_CXXALIAS_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size,\n                                  int (*compare) (void const *, void const *,\n                                                  void *),\n                                  void *arg));\n# endif\n_GL_CXXALIASWARN (qsort_r);\n#elif defined GNULIB_POSIXCHECK\n# undef qsort_r\n# if HAVE_RAW_DECL_QSORT_R\n_GL_WARN_ON_USE (qsort_r, \"qsort_r is not portable - \"\n                 \"use gnulib module qsort_r for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_RANDOM_R@\n# if !@HAVE_RANDOM_R@\n#  ifndef RAND_MAX\n#   define RAND_MAX 2147483647\n#  endif\n# endif\n#endif\n\n\n#if @GNULIB_RANDOM@\n# if @REPLACE_RANDOM@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef random\n#   define random rpl_random\n#  endif\n_GL_FUNCDECL_RPL (random, long, (void));\n_GL_CXXALIAS_RPL (random, long, (void));\n# else\n#  if !@HAVE_RANDOM@\n_GL_FUNCDECL_SYS (random, long, (void));\n#  endif\n/* Need to cast, because on Haiku, the return type is\n                               int.  */\n_GL_CXXALIAS_SYS_CAST (random, long, (void));\n# endif\n_GL_CXXALIASWARN (random);\n#elif defined GNULIB_POSIXCHECK\n# undef random\n# if HAVE_RAW_DECL_RANDOM\n_GL_WARN_ON_USE (random, \"random is unportable - \"\n                 \"use gnulib module random for portability\");\n# endif\n#endif\n\n#if @GNULIB_RANDOM@\n# if @REPLACE_RANDOM@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef srandom\n#   define srandom rpl_srandom\n#  endif\n_GL_FUNCDECL_RPL (srandom, void, (unsigned int seed));\n_GL_CXXALIAS_RPL (srandom, void, (unsigned int seed));\n# else\n#  if !@HAVE_RANDOM@\n_GL_FUNCDECL_SYS (srandom, void, (unsigned int seed));\n#  endif\n/* Need to cast, because on FreeBSD, the first parameter is\n                                       unsigned long seed.  */\n_GL_CXXALIAS_SYS_CAST (srandom, void, (unsigned int seed));\n# endif\n_GL_CXXALIASWARN (srandom);\n#elif defined GNULIB_POSIXCHECK\n# undef srandom\n# if HAVE_RAW_DECL_SRANDOM\n_GL_WARN_ON_USE (srandom, \"srandom is unportable - \"\n                 \"use gnulib module random for portability\");\n# endif\n#endif\n\n#if @GNULIB_RANDOM@\n# if @REPLACE_INITSTATE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef initstate\n#   define initstate rpl_initstate\n#  endif\n_GL_FUNCDECL_RPL (initstate, char *,\n                  (unsigned int seed, char *buf, size_t buf_size)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (initstate, char *,\n                  (unsigned int seed, char *buf, size_t buf_size));\n# else\n#  if !@HAVE_INITSTATE@ || !@HAVE_DECL_INITSTATE@\n_GL_FUNCDECL_SYS (initstate, char *,\n                  (unsigned int seed, char *buf, size_t buf_size)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n/* Need to cast, because on FreeBSD, the first parameter is\n                        unsigned long seed.  */\n_GL_CXXALIAS_SYS_CAST (initstate, char *,\n                       (unsigned int seed, char *buf, size_t buf_size));\n# endif\n_GL_CXXALIASWARN (initstate);\n#elif defined GNULIB_POSIXCHECK\n# undef initstate\n# if HAVE_RAW_DECL_INITSTATE\n_GL_WARN_ON_USE (initstate, \"initstate is unportable - \"\n                 \"use gnulib module random for portability\");\n# endif\n#endif\n\n#if @GNULIB_RANDOM@\n# if @REPLACE_SETSTATE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef setstate\n#   define setstate rpl_setstate\n#  endif\n_GL_FUNCDECL_RPL (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (setstate, char *, (char *arg_state));\n# else\n#  if !@HAVE_SETSTATE@ || !@HAVE_DECL_SETSTATE@\n_GL_FUNCDECL_SYS (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1)));\n#  endif\n/* Need to cast, because on Mac OS X 10.13, HP-UX, Solaris the first parameter\n   is                                     const char *arg_state.  */\n_GL_CXXALIAS_SYS_CAST (setstate, char *, (char *arg_state));\n# endif\n_GL_CXXALIASWARN (setstate);\n#elif defined GNULIB_POSIXCHECK\n# undef setstate\n# if HAVE_RAW_DECL_SETSTATE\n_GL_WARN_ON_USE (setstate, \"setstate is unportable - \"\n                 \"use gnulib module random for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_RANDOM_R@\n# if @REPLACE_RANDOM_R@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef random_r\n#   define random_r rpl_random_r\n#  endif\n_GL_FUNCDECL_RPL (random_r, int, (struct random_data *buf, int32_t *result)\n                                 _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (random_r, int, (struct random_data *buf, int32_t *result));\n# else\n#  if !@HAVE_RANDOM_R@\n_GL_FUNCDECL_SYS (random_r, int, (struct random_data *buf, int32_t *result)\n                                 _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (random_r, int, (struct random_data *buf, int32_t *result));\n# endif\n_GL_CXXALIASWARN (random_r);\n#elif defined GNULIB_POSIXCHECK\n# undef random_r\n# if HAVE_RAW_DECL_RANDOM_R\n_GL_WARN_ON_USE (random_r, \"random_r is unportable - \"\n                 \"use gnulib module random_r for portability\");\n# endif\n#endif\n\n#if @GNULIB_RANDOM_R@\n# if @REPLACE_RANDOM_R@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef srandom_r\n#   define srandom_r rpl_srandom_r\n#  endif\n_GL_FUNCDECL_RPL (srandom_r, int,\n                  (unsigned int seed, struct random_data *rand_state)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (srandom_r, int,\n                  (unsigned int seed, struct random_data *rand_state));\n# else\n#  if !@HAVE_RANDOM_R@\n_GL_FUNCDECL_SYS (srandom_r, int,\n                  (unsigned int seed, struct random_data *rand_state)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (srandom_r, int,\n                  (unsigned int seed, struct random_data *rand_state));\n# endif\n_GL_CXXALIASWARN (srandom_r);\n#elif defined GNULIB_POSIXCHECK\n# undef srandom_r\n# if HAVE_RAW_DECL_SRANDOM_R\n_GL_WARN_ON_USE (srandom_r, \"srandom_r is unportable - \"\n                 \"use gnulib module random_r for portability\");\n# endif\n#endif\n\n#if @GNULIB_RANDOM_R@\n# if @REPLACE_RANDOM_R@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef initstate_r\n#   define initstate_r rpl_initstate_r\n#  endif\n_GL_FUNCDECL_RPL (initstate_r, int,\n                  (unsigned int seed, char *buf, size_t buf_size,\n                   struct random_data *rand_state)\n                  _GL_ARG_NONNULL ((2, 4)));\n_GL_CXXALIAS_RPL (initstate_r, int,\n                  (unsigned int seed, char *buf, size_t buf_size,\n                   struct random_data *rand_state));\n# else\n#  if !@HAVE_RANDOM_R@\n_GL_FUNCDECL_SYS (initstate_r, int,\n                  (unsigned int seed, char *buf, size_t buf_size,\n                   struct random_data *rand_state)\n                  _GL_ARG_NONNULL ((2, 4)));\n#  endif\n/* Need to cast, because on Haiku, the third parameter is\n                                                     unsigned long buf_size.  */\n_GL_CXXALIAS_SYS_CAST (initstate_r, int,\n                       (unsigned int seed, char *buf, size_t buf_size,\n                        struct random_data *rand_state));\n# endif\n_GL_CXXALIASWARN (initstate_r);\n#elif defined GNULIB_POSIXCHECK\n# undef initstate_r\n# if HAVE_RAW_DECL_INITSTATE_R\n_GL_WARN_ON_USE (initstate_r, \"initstate_r is unportable - \"\n                 \"use gnulib module random_r for portability\");\n# endif\n#endif\n\n#if @GNULIB_RANDOM_R@\n# if @REPLACE_RANDOM_R@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef setstate_r\n#   define setstate_r rpl_setstate_r\n#  endif\n_GL_FUNCDECL_RPL (setstate_r, int,\n                  (char *arg_state, struct random_data *rand_state)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (setstate_r, int,\n                  (char *arg_state, struct random_data *rand_state));\n# else\n#  if !@HAVE_RANDOM_R@\n_GL_FUNCDECL_SYS (setstate_r, int,\n                  (char *arg_state, struct random_data *rand_state)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n/* Need to cast, because on Haiku, the first parameter is\n                        void *arg_state.  */\n_GL_CXXALIAS_SYS_CAST (setstate_r, int,\n                       (char *arg_state, struct random_data *rand_state));\n# endif\n_GL_CXXALIASWARN (setstate_r);\n#elif defined GNULIB_POSIXCHECK\n# undef setstate_r\n# if HAVE_RAW_DECL_SETSTATE_R\n_GL_WARN_ON_USE (setstate_r, \"setstate_r is unportable - \"\n                 \"use gnulib module random_r for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_REALLOC_POSIX@\n# if @REPLACE_REALLOC@\n#  if !((defined __cplusplus && defined GNULIB_NAMESPACE) \\\n        || _GL_USE_STDLIB_ALLOC)\n#   undef realloc\n#   define realloc rpl_realloc\n#  endif\n_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size));\n_GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size));\n# else\n_GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (realloc);\n# endif\n#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC\n# undef realloc\n/* Assume realloc is always declared.  */\n_GL_WARN_ON_USE (realloc, \"realloc is not POSIX compliant everywhere - \"\n                 \"use gnulib module realloc-posix for portability\");\n#endif\n\n\n#if @GNULIB_REALLOCARRAY@\n# if @REPLACE_REALLOCARRAY@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef reallocarray\n#   define reallocarray rpl_reallocarray\n#  endif\n_GL_FUNCDECL_RPL (reallocarray, void *,\n                  (void *ptr, size_t nmemb, size_t size));\n_GL_CXXALIAS_RPL (reallocarray, void *,\n                  (void *ptr, size_t nmemb, size_t size));\n# else\n#  if ! @HAVE_REALLOCARRAY@\n_GL_FUNCDECL_SYS (reallocarray, void *,\n                  (void *ptr, size_t nmemb, size_t size));\n#  endif\n_GL_CXXALIAS_SYS (reallocarray, void *,\n                  (void *ptr, size_t nmemb, size_t size));\n# endif\n_GL_CXXALIASWARN (reallocarray);\n#elif defined GNULIB_POSIXCHECK\n# undef reallocarray\n# if HAVE_RAW_DECL_REALLOCARRAY\n_GL_WARN_ON_USE (reallocarray, \"reallocarray is not portable - \"\n                 \"use gnulib module reallocarray for portability\");\n# endif\n#endif\n\n#if @GNULIB_REALPATH@\n# if @REPLACE_REALPATH@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define realpath rpl_realpath\n#  endif\n_GL_FUNCDECL_RPL (realpath, char *,\n                  (const char *restrict name, char *restrict resolved)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (realpath, char *,\n                  (const char *restrict name, char *restrict resolved));\n# else\n#  if !@HAVE_REALPATH@\n_GL_FUNCDECL_SYS (realpath, char *,\n                  (const char *restrict name, char *restrict resolved)\n                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (realpath, char *,\n                  (const char *restrict name, char *restrict resolved));\n# endif\n_GL_CXXALIASWARN (realpath);\n#elif defined GNULIB_POSIXCHECK\n# undef realpath\n# if HAVE_RAW_DECL_REALPATH\n_GL_WARN_ON_USE (realpath, \"realpath is unportable - use gnulib module \"\n                 \"canonicalize or canonicalize-lgpl for portability\");\n# endif\n#endif\n\n#if @GNULIB_RPMATCH@\n/* Test a user response to a question.\n   Return 1 if it is affirmative, 0 if it is negative, or -1 if not clear.  */\n# if !@HAVE_RPMATCH@\n_GL_FUNCDECL_SYS (rpmatch, int, (const char *response) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (rpmatch, int, (const char *response));\n_GL_CXXALIASWARN (rpmatch);\n#elif defined GNULIB_POSIXCHECK\n# undef rpmatch\n# if HAVE_RAW_DECL_RPMATCH\n_GL_WARN_ON_USE (rpmatch, \"rpmatch is unportable - \"\n                 \"use gnulib module rpmatch for portability\");\n# endif\n#endif\n\n#if @GNULIB_SECURE_GETENV@\n/* Look up NAME in the environment, returning 0 in insecure situations.  */\n# if !@HAVE_SECURE_GETENV@\n_GL_FUNCDECL_SYS (secure_getenv, char *,\n                  (char const *name) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (secure_getenv, char *, (char const *name));\n_GL_CXXALIASWARN (secure_getenv);\n#elif defined GNULIB_POSIXCHECK\n# undef secure_getenv\n# if HAVE_RAW_DECL_SECURE_GETENV\n_GL_WARN_ON_USE (secure_getenv, \"secure_getenv is unportable - \"\n                 \"use gnulib module secure_getenv for portability\");\n# endif\n#endif\n\n#if @GNULIB_SETENV@\n/* Set NAME to VALUE in the environment.\n   If REPLACE is nonzero, overwrite an existing value.  */\n# if @REPLACE_SETENV@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef setenv\n#   define setenv rpl_setenv\n#  endif\n_GL_FUNCDECL_RPL (setenv, int,\n                  (const char *name, const char *value, int replace)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (setenv, int,\n                  (const char *name, const char *value, int replace));\n# else\n#  if !@HAVE_DECL_SETENV@\n_GL_FUNCDECL_SYS (setenv, int,\n                  (const char *name, const char *value, int replace)\n                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (setenv, int,\n                  (const char *name, const char *value, int replace));\n# endif\n# if !(@REPLACE_SETENV@ && !@HAVE_DECL_SETENV@)\n_GL_CXXALIASWARN (setenv);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef setenv\n# if HAVE_RAW_DECL_SETENV\n_GL_WARN_ON_USE (setenv, \"setenv is unportable - \"\n                 \"use gnulib module setenv for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRTOD@\n /* Parse a double from STRING, updating ENDP if appropriate.  */\n# if @REPLACE_STRTOD@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strtod rpl_strtod\n#  endif\n#  define GNULIB_defined_strtod_function 1\n_GL_FUNCDECL_RPL (strtod, double,\n                  (const char *restrict str, char **restrict endp)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strtod, double,\n                  (const char *restrict str, char **restrict endp));\n# else\n#  if !@HAVE_STRTOD@\n_GL_FUNCDECL_SYS (strtod, double,\n                  (const char *restrict str, char **restrict endp)\n                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strtod, double,\n                  (const char *restrict str, char **restrict endp));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (strtod);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strtod\n# if HAVE_RAW_DECL_STRTOD\n_GL_WARN_ON_USE (strtod, \"strtod is unportable - \"\n                 \"use gnulib module strtod for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRTOLD@\n /* Parse a 'long double' from STRING, updating ENDP if appropriate.  */\n# if @REPLACE_STRTOLD@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strtold rpl_strtold\n#  endif\n#  define GNULIB_defined_strtold_function 1\n_GL_FUNCDECL_RPL (strtold, long double,\n                  (const char *restrict str, char **restrict endp)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strtold, long double,\n                  (const char *restrict str, char **restrict endp));\n# else\n#  if !@HAVE_STRTOLD@\n_GL_FUNCDECL_SYS (strtold, long double,\n                  (const char *restrict str, char **restrict endp)\n                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strtold, long double,\n                  (const char *restrict str, char **restrict endp));\n# endif\n_GL_CXXALIASWARN (strtold);\n#elif defined GNULIB_POSIXCHECK\n# undef strtold\n# if HAVE_RAW_DECL_STRTOLD\n_GL_WARN_ON_USE (strtold, \"strtold is unportable - \"\n                 \"use gnulib module strtold for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRTOL@\n/* Parse a signed integer whose textual representation starts at STRING.\n   The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,\n   it may be decimal or octal (with prefix \"0\") or hexadecimal (with prefix\n   \"0x\").\n   If ENDPTR is not NULL, the address of the first byte after the integer is\n   stored in *ENDPTR.\n   Upon overflow, the return value is LONG_MAX or LONG_MIN, and errno is set\n   to ERANGE.  */\n# if @REPLACE_STRTOL@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strtol rpl_strtol\n#  endif\n#  define GNULIB_defined_strtol_function 1\n_GL_FUNCDECL_RPL (strtol, long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strtol, long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base));\n# else\n#  if !@HAVE_STRTOL@\n_GL_FUNCDECL_SYS (strtol, long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base)\n                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strtol, long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base));\n# endif\n_GL_CXXALIASWARN (strtol);\n#elif defined GNULIB_POSIXCHECK\n# undef strtol\n# if HAVE_RAW_DECL_STRTOL\n_GL_WARN_ON_USE (strtol, \"strtol is unportable - \"\n                 \"use gnulib module strtol for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRTOLL@\n/* Parse a signed integer whose textual representation starts at STRING.\n   The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,\n   it may be decimal or octal (with prefix \"0\") or hexadecimal (with prefix\n   \"0x\").\n   If ENDPTR is not NULL, the address of the first byte after the integer is\n   stored in *ENDPTR.\n   Upon overflow, the return value is LLONG_MAX or LLONG_MIN, and errno is set\n   to ERANGE.  */\n# if @REPLACE_STRTOLL@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strtoll rpl_strtoll\n#  endif\n#  define GNULIB_defined_strtoll_function 1\n_GL_FUNCDECL_RPL (strtoll, long long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strtoll, long long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base));\n# else\n#  if !@HAVE_STRTOLL@\n_GL_FUNCDECL_SYS (strtoll, long long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base)\n                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strtoll, long long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base));\n# endif\n_GL_CXXALIASWARN (strtoll);\n#elif defined GNULIB_POSIXCHECK\n# undef strtoll\n# if HAVE_RAW_DECL_STRTOLL\n_GL_WARN_ON_USE (strtoll, \"strtoll is unportable - \"\n                 \"use gnulib module strtoll for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRTOUL@\n/* Parse an unsigned integer whose textual representation starts at STRING.\n   The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,\n   it may be decimal or octal (with prefix \"0\") or hexadecimal (with prefix\n   \"0x\").\n   If ENDPTR is not NULL, the address of the first byte after the integer is\n   stored in *ENDPTR.\n   Upon overflow, the return value is ULONG_MAX, and errno is set to ERANGE.  */\n# if @REPLACE_STRTOUL@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strtoul rpl_strtoul\n#  endif\n#  define GNULIB_defined_strtoul_function 1\n_GL_FUNCDECL_RPL (strtoul, unsigned long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strtoul, unsigned long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base));\n# else\n#  if !@HAVE_STRTOUL@\n_GL_FUNCDECL_SYS (strtoul, unsigned long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base)\n                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strtoul, unsigned long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base));\n# endif\n_GL_CXXALIASWARN (strtoul);\n#elif defined GNULIB_POSIXCHECK\n# undef strtoul\n# if HAVE_RAW_DECL_STRTOUL\n_GL_WARN_ON_USE (strtoul, \"strtoul is unportable - \"\n                 \"use gnulib module strtoul for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRTOULL@\n/* Parse an unsigned integer whose textual representation starts at STRING.\n   The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,\n   it may be decimal or octal (with prefix \"0\") or hexadecimal (with prefix\n   \"0x\").\n   If ENDPTR is not NULL, the address of the first byte after the integer is\n   stored in *ENDPTR.\n   Upon overflow, the return value is ULLONG_MAX, and errno is set to\n   ERANGE.  */\n# if @REPLACE_STRTOULL@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strtoull rpl_strtoull\n#  endif\n#  define GNULIB_defined_strtoull_function 1\n_GL_FUNCDECL_RPL (strtoull, unsigned long long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base)\n                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strtoull, unsigned long long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base));\n# else\n#  if !@HAVE_STRTOULL@\n_GL_FUNCDECL_SYS (strtoull, unsigned long long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base)\n                  _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strtoull, unsigned long long,\n                  (const char *restrict string, char **restrict endptr,\n                   int base));\n# endif\n_GL_CXXALIASWARN (strtoull);\n#elif defined GNULIB_POSIXCHECK\n# undef strtoull\n# if HAVE_RAW_DECL_STRTOULL\n_GL_WARN_ON_USE (strtoull, \"strtoull is unportable - \"\n                 \"use gnulib module strtoull for portability\");\n# endif\n#endif\n\n#if @GNULIB_UNLOCKPT@\n/* Unlock the slave side of the pseudo-terminal whose master side is specified\n   by FD, so that it can be opened.  */\n# if !@HAVE_UNLOCKPT@\n_GL_FUNCDECL_SYS (unlockpt, int, (int fd));\n# endif\n_GL_CXXALIAS_SYS (unlockpt, int, (int fd));\n_GL_CXXALIASWARN (unlockpt);\n#elif defined GNULIB_POSIXCHECK\n# undef unlockpt\n# if HAVE_RAW_DECL_UNLOCKPT\n_GL_WARN_ON_USE (unlockpt, \"unlockpt is not portable - \"\n                 \"use gnulib module unlockpt for portability\");\n# endif\n#endif\n\n#if @GNULIB_UNSETENV@\n/* Remove the variable NAME from the environment.  */\n# if @REPLACE_UNSETENV@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef unsetenv\n#   define unsetenv rpl_unsetenv\n#  endif\n_GL_FUNCDECL_RPL (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (unsetenv, int, (const char *name));\n# else\n#  if !@HAVE_DECL_UNSETENV@\n_GL_FUNCDECL_SYS (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (unsetenv, int, (const char *name));\n# endif\n# if !(@REPLACE_UNSETENV@ && !@HAVE_DECL_UNSETENV@)\n_GL_CXXALIASWARN (unsetenv);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef unsetenv\n# if HAVE_RAW_DECL_UNSETENV\n_GL_WARN_ON_USE (unsetenv, \"unsetenv is unportable - \"\n                 \"use gnulib module unsetenv for portability\");\n# endif\n#endif\n\n/* Convert a wide character to a multibyte character.  */\n#if @GNULIB_WCTOMB@\n# if @REPLACE_WCTOMB@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wctomb\n#   define wctomb rpl_wctomb\n#  endif\n_GL_FUNCDECL_RPL (wctomb, int, (char *s, wchar_t wc));\n_GL_CXXALIAS_RPL (wctomb, int, (char *s, wchar_t wc));\n# else\n_GL_CXXALIAS_SYS (wctomb, int, (char *s, wchar_t wc));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wctomb);\n# endif\n#endif\n\n\n#endif /* _@GUARD_PREFIX@_STDLIB_H */\n#endif /* _@GUARD_PREFIX@_STDLIB_H */\n#endif\n"
  },
  {
    "path": "gnulib/streq.h",
    "content": "/* Optimized string comparison.\n   Copyright (C) 2001-2002, 2007, 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>.  */\n\n#ifndef _GL_STREQ_H\n#define _GL_STREQ_H\n\n#include <string.h>\n\n/* STREQ_OPT allows to optimize string comparison with a small literal string.\n     STREQ_OPT (s, \"EUC-KR\", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0)\n   is semantically equivalent to\n     strcmp (s, \"EUC-KR\") == 0\n   just faster.  */\n\n/* Help GCC to generate good code for string comparisons with\n   immediate strings. */\n#if (defined __GNUC__ || defined __clang__) && defined __OPTIMIZE__\n\nstatic inline int\nstreq9 (const char *s1, const char *s2)\n{\n  return strcmp (s1 + 9, s2 + 9) == 0;\n}\n\nstatic inline int\nstreq8 (const char *s1, const char *s2, char s28)\n{\n  if (s1[8] == s28)\n    {\n      if (s28 == 0)\n        return 1;\n      else\n        return streq9 (s1, s2);\n    }\n  else\n    return 0;\n}\n\nstatic inline int\nstreq7 (const char *s1, const char *s2, char s27, char s28)\n{\n  if (s1[7] == s27)\n    {\n      if (s27 == 0)\n        return 1;\n      else\n        return streq8 (s1, s2, s28);\n    }\n  else\n    return 0;\n}\n\nstatic inline int\nstreq6 (const char *s1, const char *s2, char s26, char s27, char s28)\n{\n  if (s1[6] == s26)\n    {\n      if (s26 == 0)\n        return 1;\n      else\n        return streq7 (s1, s2, s27, s28);\n    }\n  else\n    return 0;\n}\n\nstatic inline int\nstreq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28)\n{\n  if (s1[5] == s25)\n    {\n      if (s25 == 0)\n        return 1;\n      else\n        return streq6 (s1, s2, s26, s27, s28);\n    }\n  else\n    return 0;\n}\n\nstatic inline int\nstreq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28)\n{\n  if (s1[4] == s24)\n    {\n      if (s24 == 0)\n        return 1;\n      else\n        return streq5 (s1, s2, s25, s26, s27, s28);\n    }\n  else\n    return 0;\n}\n\nstatic inline int\nstreq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28)\n{\n  if (s1[3] == s23)\n    {\n      if (s23 == 0)\n        return 1;\n      else\n        return streq4 (s1, s2, s24, s25, s26, s27, s28);\n    }\n  else\n    return 0;\n}\n\nstatic inline int\nstreq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28)\n{\n  if (s1[2] == s22)\n    {\n      if (s22 == 0)\n        return 1;\n      else\n        return streq3 (s1, s2, s23, s24, s25, s26, s27, s28);\n    }\n  else\n    return 0;\n}\n\nstatic inline int\nstreq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)\n{\n  if (s1[1] == s21)\n    {\n      if (s21 == 0)\n        return 1;\n      else\n        return streq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28);\n    }\n  else\n    return 0;\n}\n\nstatic inline int\nstreq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)\n{\n  if (s1[0] == s20)\n    {\n      if (s20 == 0)\n        return 1;\n      else\n        return streq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28);\n    }\n  else\n    return 0;\n}\n\n#define STREQ_OPT(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \\\n  streq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28)\n\n#else\n\n#define STREQ_OPT(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \\\n  (strcmp (s1, s2) == 0)\n\n#endif\n\n#endif /* _GL_STREQ_H */\n"
  },
  {
    "path": "gnulib/string.in.h",
    "content": "/* A GNU-like <string.h>.\n\n   Copyright (C) 1995-1996, 2001-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n#if defined _GL_ALREADY_INCLUDING_STRING_H\n/* Special invocation convention:\n   - On OS X/NetBSD we have a sequence of nested includes\n       <string.h> -> <strings.h> -> \"string.h\"\n     In this situation system _chk variants due to -D_FORTIFY_SOURCE\n     might be used after any replacements defined here.  */\n\n#@INCLUDE_NEXT@ @NEXT_STRING_H@\n\n#else\n/* Normal invocation convention.  */\n\n#ifndef _@GUARD_PREFIX@_STRING_H\n\n#define _GL_ALREADY_INCLUDING_STRING_H\n\n/* The include_next requires a split double-inclusion guard.  */\n#@INCLUDE_NEXT@ @NEXT_STRING_H@\n\n#undef _GL_ALREADY_INCLUDING_STRING_H\n\n#ifndef _@GUARD_PREFIX@_STRING_H\n#define _@GUARD_PREFIX@_STRING_H\n\n/* NetBSD 5.0 mis-defines NULL.  */\n#include <stddef.h>\n\n/* MirBSD defines mbslen as a macro.  */\n#if @GNULIB_MBSLEN@ && defined __MirBSD__\n# include <wchar.h>\n#endif\n\n/* The __attribute__ feature is available in gcc versions 2.5 and later.\n   The attribute __pure__ was added in gcc 2.96.  */\n#ifndef _GL_ATTRIBUTE_PURE\n# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__\n#  define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))\n# else\n#  define _GL_ATTRIBUTE_PURE /* empty */\n# endif\n#endif\n\n/* NetBSD 5.0 declares strsignal in <unistd.h>, not in <string.h>.  */\n/* But in any case avoid namespace pollution on glibc systems.  */\n#if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) && defined __NetBSD__ \\\n    && ! defined __GLIBC__\n# include <unistd.h>\n#endif\n\n/* AIX 7.2 declares ffsl and ffsll in <strings.h>, not in <string.h>.  */\n/* But in any case avoid namespace pollution on glibc systems.  */\n#if ((@GNULIB_FFSL@ || @GNULIB_FFSLL@ || defined GNULIB_POSIXCHECK) \\\n     && defined _AIX) \\\n    && ! defined __GLIBC__\n# include <strings.h>\n#endif\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n\n\n/* Clear a block of memory.  The compiler will not delete a call to\n   this function, even if the block is dead after the call.  */\n#if @GNULIB_EXPLICIT_BZERO@\n# if ! @HAVE_EXPLICIT_BZERO@\n_GL_FUNCDECL_SYS (explicit_bzero, void,\n                  (void *__dest, size_t __n) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (explicit_bzero, void, (void *__dest, size_t __n));\n_GL_CXXALIASWARN (explicit_bzero);\n#elif defined GNULIB_POSIXCHECK\n# undef explicit_bzero\n# if HAVE_RAW_DECL_EXPLICIT_BZERO\n_GL_WARN_ON_USE (explicit_bzero, \"explicit_bzero is unportable - \"\n                 \"use gnulib module explicit_bzero for portability\");\n# endif\n#endif\n\n/* Find the index of the least-significant set bit.  */\n#if @GNULIB_FFSL@\n# if !@HAVE_FFSL@\n_GL_FUNCDECL_SYS (ffsl, int, (long int i));\n# endif\n_GL_CXXALIAS_SYS (ffsl, int, (long int i));\n_GL_CXXALIASWARN (ffsl);\n#elif defined GNULIB_POSIXCHECK\n# undef ffsl\n# if HAVE_RAW_DECL_FFSL\n_GL_WARN_ON_USE (ffsl, \"ffsl is not portable - use the ffsl module\");\n# endif\n#endif\n\n\n/* Find the index of the least-significant set bit.  */\n#if @GNULIB_FFSLL@\n# if @REPLACE_FFSLL@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define ffsll rpl_ffsll\n#  endif\n_GL_FUNCDECL_RPL (ffsll, int, (long long int i));\n_GL_CXXALIAS_RPL (ffsll, int, (long long int i));\n# else\n#  if !@HAVE_FFSLL@\n_GL_FUNCDECL_SYS (ffsll, int, (long long int i));\n#  endif\n_GL_CXXALIAS_SYS (ffsll, int, (long long int i));\n# endif\n_GL_CXXALIASWARN (ffsll);\n#elif defined GNULIB_POSIXCHECK\n# undef ffsll\n# if HAVE_RAW_DECL_FFSLL\n_GL_WARN_ON_USE (ffsll, \"ffsll is not portable - use the ffsll module\");\n# endif\n#endif\n\n\n#if @GNULIB_MDA_MEMCCPY@\n/* On native Windows, map 'memccpy' to '_memccpy', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::memccpy always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef memccpy\n#   define memccpy _memccpy\n#  endif\n_GL_CXXALIAS_MDA (memccpy, void *,\n                  (void *dest, const void *src, int c, size_t n));\n# else\n_GL_CXXALIAS_SYS (memccpy, void *,\n                  (void *dest, const void *src, int c, size_t n));\n# endif\n_GL_CXXALIASWARN (memccpy);\n#endif\n\n\n/* Return the first instance of C within N bytes of S, or NULL.  */\n#if @GNULIB_MEMCHR@\n# if @REPLACE_MEMCHR@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef memchr\n#   define memchr rpl_memchr\n#  endif\n_GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n));\n# else\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C\" { const void * std::memchr (const void *, int, size_t); }\n       extern \"C++\" { void * std::memchr (void *, int, size_t); }  */\n_GL_CXXALIAS_SYS_CAST2 (memchr,\n                        void *, (void const *__s, int __c, size_t __n),\n                        void const *, (void const *__s, int __c, size_t __n));\n# endif\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n));\n_GL_CXXALIASWARN1 (memchr, void const *,\n                   (void const *__s, int __c, size_t __n));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (memchr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef memchr\n/* Assume memchr is always declared.  */\n_GL_WARN_ON_USE (memchr, \"memchr has platform-specific bugs - \"\n                 \"use gnulib module memchr for portability\" );\n#endif\n\n/* Return the first occurrence of NEEDLE in HAYSTACK.  */\n#if @GNULIB_MEMMEM@\n# if @REPLACE_MEMMEM@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define memmem rpl_memmem\n#  endif\n_GL_FUNCDECL_RPL (memmem, void *,\n                  (void const *__haystack, size_t __haystack_len,\n                   void const *__needle, size_t __needle_len)\n                  _GL_ATTRIBUTE_PURE\n                  _GL_ARG_NONNULL ((1, 3)));\n_GL_CXXALIAS_RPL (memmem, void *,\n                  (void const *__haystack, size_t __haystack_len,\n                   void const *__needle, size_t __needle_len));\n# else\n#  if ! @HAVE_DECL_MEMMEM@\n_GL_FUNCDECL_SYS (memmem, void *,\n                  (void const *__haystack, size_t __haystack_len,\n                   void const *__needle, size_t __needle_len)\n                  _GL_ATTRIBUTE_PURE\n                  _GL_ARG_NONNULL ((1, 3)));\n#  endif\n_GL_CXXALIAS_SYS (memmem, void *,\n                  (void const *__haystack, size_t __haystack_len,\n                   void const *__needle, size_t __needle_len));\n# endif\n_GL_CXXALIASWARN (memmem);\n#elif defined GNULIB_POSIXCHECK\n# undef memmem\n# if HAVE_RAW_DECL_MEMMEM\n_GL_WARN_ON_USE (memmem, \"memmem is unportable and often quadratic - \"\n                 \"use gnulib module memmem-simple for portability, \"\n                 \"and module memmem for speed\" );\n# endif\n#endif\n\n/* Copy N bytes of SRC to DEST, return pointer to bytes after the\n   last written byte.  */\n#if @GNULIB_MEMPCPY@\n# if ! @HAVE_MEMPCPY@\n_GL_FUNCDECL_SYS (mempcpy, void *,\n                  (void *restrict __dest, void const *restrict __src,\n                   size_t __n)\n                  _GL_ARG_NONNULL ((1, 2)));\n# endif\n_GL_CXXALIAS_SYS (mempcpy, void *,\n                  (void *restrict __dest, void const *restrict __src,\n                   size_t __n));\n_GL_CXXALIASWARN (mempcpy);\n#elif defined GNULIB_POSIXCHECK\n# undef mempcpy\n# if HAVE_RAW_DECL_MEMPCPY\n_GL_WARN_ON_USE (mempcpy, \"mempcpy is unportable - \"\n                 \"use gnulib module mempcpy for portability\");\n# endif\n#endif\n\n/* Search backwards through a block for a byte (specified as an int).  */\n#if @GNULIB_MEMRCHR@\n# if ! @HAVE_DECL_MEMRCHR@\n_GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1)));\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" { const void * std::memrchr (const void *, int, size_t); }\n       extern \"C++\" { void * std::memrchr (void *, int, size_t); }  */\n_GL_CXXALIAS_SYS_CAST2 (memrchr,\n                        void *, (void const *, int, size_t),\n                        void const *, (void const *, int, size_t));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (memrchr, void *, (void *, int, size_t));\n_GL_CXXALIASWARN1 (memrchr, void const *, (void const *, int, size_t));\n# else\n_GL_CXXALIASWARN (memrchr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef memrchr\n# if HAVE_RAW_DECL_MEMRCHR\n_GL_WARN_ON_USE (memrchr, \"memrchr is unportable - \"\n                 \"use gnulib module memrchr for portability\");\n# endif\n#endif\n\n/* Find the first occurrence of C in S.  More efficient than\n   memchr(S,C,N), at the expense of undefined behavior if C does not\n   occur within N bytes.  */\n#if @GNULIB_RAWMEMCHR@\n# if ! @HAVE_RAWMEMCHR@\n_GL_FUNCDECL_SYS (rawmemchr, void *, (void const *__s, int __c_in)\n                                     _GL_ATTRIBUTE_PURE\n                                     _GL_ARG_NONNULL ((1)));\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" { const void * std::rawmemchr (const void *, int); }\n       extern \"C++\" { void * std::rawmemchr (void *, int); }  */\n_GL_CXXALIAS_SYS_CAST2 (rawmemchr,\n                        void *, (void const *__s, int __c_in),\n                        void const *, (void const *__s, int __c_in));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (rawmemchr, void *, (void *__s, int __c_in));\n_GL_CXXALIASWARN1 (rawmemchr, void const *, (void const *__s, int __c_in));\n# else\n_GL_CXXALIASWARN (rawmemchr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef rawmemchr\n# if HAVE_RAW_DECL_RAWMEMCHR\n_GL_WARN_ON_USE (rawmemchr, \"rawmemchr is unportable - \"\n                 \"use gnulib module rawmemchr for portability\");\n# endif\n#endif\n\n/* Copy SRC to DST, returning the address of the terminating '\\0' in DST.  */\n#if @GNULIB_STPCPY@\n# if ! @HAVE_STPCPY@\n_GL_FUNCDECL_SYS (stpcpy, char *,\n                  (char *restrict __dst, char const *restrict __src)\n                  _GL_ARG_NONNULL ((1, 2)));\n# endif\n_GL_CXXALIAS_SYS (stpcpy, char *,\n                  (char *restrict __dst, char const *restrict __src));\n_GL_CXXALIASWARN (stpcpy);\n#elif defined GNULIB_POSIXCHECK\n# undef stpcpy\n# if HAVE_RAW_DECL_STPCPY\n_GL_WARN_ON_USE (stpcpy, \"stpcpy is unportable - \"\n                 \"use gnulib module stpcpy for portability\");\n# endif\n#endif\n\n/* Copy no more than N bytes of SRC to DST, returning a pointer past the\n   last non-NUL byte written into DST.  */\n#if @GNULIB_STPNCPY@\n# if @REPLACE_STPNCPY@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef stpncpy\n#   define stpncpy rpl_stpncpy\n#  endif\n_GL_FUNCDECL_RPL (stpncpy, char *,\n                  (char *restrict __dst, char const *restrict __src,\n                   size_t __n)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (stpncpy, char *,\n                  (char *restrict __dst, char const *restrict __src,\n                   size_t __n));\n# else\n#  if ! @HAVE_STPNCPY@\n_GL_FUNCDECL_SYS (stpncpy, char *,\n                  (char *restrict __dst, char const *restrict __src,\n                   size_t __n)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (stpncpy, char *,\n                  (char *restrict __dst, char const *restrict __src,\n                   size_t __n));\n# endif\n_GL_CXXALIASWARN (stpncpy);\n#elif defined GNULIB_POSIXCHECK\n# undef stpncpy\n# if HAVE_RAW_DECL_STPNCPY\n_GL_WARN_ON_USE (stpncpy, \"stpncpy is unportable - \"\n                 \"use gnulib module stpncpy for portability\");\n# endif\n#endif\n\n#if defined GNULIB_POSIXCHECK\n/* strchr() does not work with multibyte strings if the locale encoding is\n   GB18030 and the character to be searched is a digit.  */\n# undef strchr\n/* Assume strchr is always declared.  */\n_GL_WARN_ON_USE_CXX (strchr,\n                     const char *, char *, (const char *, int),\n                     \"strchr cannot work correctly on character strings \"\n                     \"in some multibyte locales - \"\n                     \"use mbschr if you care about internationalization\");\n#endif\n\n/* Find the first occurrence of C in S or the final NUL byte.  */\n#if @GNULIB_STRCHRNUL@\n# if @REPLACE_STRCHRNUL@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strchrnul rpl_strchrnul\n#  endif\n_GL_FUNCDECL_RPL (strchrnul, char *, (const char *__s, int __c_in)\n                                     _GL_ATTRIBUTE_PURE\n                                     _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strchrnul, char *,\n                  (const char *str, int ch));\n# else\n#  if ! @HAVE_STRCHRNUL@\n_GL_FUNCDECL_SYS (strchrnul, char *, (char const *__s, int __c_in)\n                                     _GL_ATTRIBUTE_PURE\n                                     _GL_ARG_NONNULL ((1)));\n#  endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" { const char * std::strchrnul (const char *, int); }\n       extern \"C++\" { char * std::strchrnul (char *, int); }  */\n_GL_CXXALIAS_SYS_CAST2 (strchrnul,\n                        char *, (char const *__s, int __c_in),\n                        char const *, (char const *__s, int __c_in));\n# endif\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in));\n_GL_CXXALIASWARN1 (strchrnul, char const *, (char const *__s, int __c_in));\n# else\n_GL_CXXALIASWARN (strchrnul);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strchrnul\n# if HAVE_RAW_DECL_STRCHRNUL\n_GL_WARN_ON_USE (strchrnul, \"strchrnul is unportable - \"\n                 \"use gnulib module strchrnul for portability\");\n# endif\n#endif\n\n/* Duplicate S, returning an identical malloc'd string.  */\n#if @GNULIB_STRDUP@\n# if @REPLACE_STRDUP@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strdup\n#   define strdup rpl_strdup\n#  endif\n_GL_FUNCDECL_RPL (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strdup, char *, (char const *__s));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strdup\n#   define strdup _strdup\n#  endif\n_GL_CXXALIAS_MDA (strdup, char *, (char const *__s));\n# else\n#  if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup\n    /* strdup exists as a function and as a macro.  Get rid of the macro.  */\n#   undef strdup\n#  endif\n#  if !(@HAVE_DECL_STRDUP@ || defined strdup)\n_GL_FUNCDECL_SYS (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strdup, char *, (char const *__s));\n# endif\n_GL_CXXALIASWARN (strdup);\n#elif defined GNULIB_POSIXCHECK\n# undef strdup\n# if HAVE_RAW_DECL_STRDUP\n_GL_WARN_ON_USE (strdup, \"strdup is unportable - \"\n                 \"use gnulib module strdup for portability\");\n# endif\n#elif @GNULIB_MDA_STRDUP@\n/* On native Windows, map 'creat' to '_creat', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::strdup always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strdup\n#   define strdup _strdup\n#  endif\n_GL_CXXALIAS_MDA (strdup, char *, (char const *__s));\n# else\n#  if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup\n#   undef strdup\n#  endif\n_GL_CXXALIAS_SYS (strdup, char *, (char const *__s));\n# endif\n_GL_CXXALIASWARN (strdup);\n#endif\n\n/* Append no more than N characters from SRC onto DEST.  */\n#if @GNULIB_STRNCAT@\n# if @REPLACE_STRNCAT@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strncat\n#   define strncat rpl_strncat\n#  endif\n_GL_FUNCDECL_RPL (strncat, char *,\n                  (char *restrict dest, const char *restrict src, size_t n)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (strncat, char *,\n                  (char *restrict dest, const char *restrict src, size_t n));\n# else\n_GL_CXXALIAS_SYS (strncat, char *,\n                  (char *restrict dest, const char *restrict src, size_t n));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (strncat);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strncat\n# if HAVE_RAW_DECL_STRNCAT\n_GL_WARN_ON_USE (strncat, \"strncat is unportable - \"\n                 \"use gnulib module strncat for portability\");\n# endif\n#endif\n\n/* Return a newly allocated copy of at most N bytes of STRING.  */\n#if @GNULIB_STRNDUP@\n# if @REPLACE_STRNDUP@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strndup\n#   define strndup rpl_strndup\n#  endif\n_GL_FUNCDECL_RPL (strndup, char *, (char const *__s, size_t __n)\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n));\n# else\n#  if ! @HAVE_DECL_STRNDUP@\n_GL_FUNCDECL_SYS (strndup, char *, (char const *__s, size_t __n)\n                                   _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strndup, char *, (char const *__s, size_t __n));\n# endif\n_GL_CXXALIASWARN (strndup);\n#elif defined GNULIB_POSIXCHECK\n# undef strndup\n# if HAVE_RAW_DECL_STRNDUP\n_GL_WARN_ON_USE (strndup, \"strndup is unportable - \"\n                 \"use gnulib module strndup for portability\");\n# endif\n#endif\n\n/* Find the length (number of bytes) of STRING, but scan at most\n   MAXLEN bytes.  If no '\\0' terminator is found in that many bytes,\n   return MAXLEN.  */\n#if @GNULIB_STRNLEN@\n# if @REPLACE_STRNLEN@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strnlen\n#   define strnlen rpl_strnlen\n#  endif\n_GL_FUNCDECL_RPL (strnlen, size_t, (char const *__s, size_t __maxlen)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strnlen, size_t, (char const *__s, size_t __maxlen));\n# else\n#  if ! @HAVE_DECL_STRNLEN@\n_GL_FUNCDECL_SYS (strnlen, size_t, (char const *__s, size_t __maxlen)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strnlen, size_t, (char const *__s, size_t __maxlen));\n# endif\n_GL_CXXALIASWARN (strnlen);\n#elif defined GNULIB_POSIXCHECK\n# undef strnlen\n# if HAVE_RAW_DECL_STRNLEN\n_GL_WARN_ON_USE (strnlen, \"strnlen is unportable - \"\n                 \"use gnulib module strnlen for portability\");\n# endif\n#endif\n\n#if defined GNULIB_POSIXCHECK\n/* strcspn() assumes the second argument is a list of single-byte characters.\n   Even in this simple case, it does not work with multibyte strings if the\n   locale encoding is GB18030 and one of the characters to be searched is a\n   digit.  */\n# undef strcspn\n/* Assume strcspn is always declared.  */\n_GL_WARN_ON_USE (strcspn, \"strcspn cannot work correctly on character strings \"\n                 \"in multibyte locales - \"\n                 \"use mbscspn if you care about internationalization\");\n#endif\n\n/* Find the first occurrence in S of any character in ACCEPT.  */\n#if @GNULIB_STRPBRK@\n# if ! @HAVE_STRPBRK@\n_GL_FUNCDECL_SYS (strpbrk, char *, (char const *__s, char const *__accept)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1, 2)));\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C\" { const char * strpbrk (const char *, const char *); }\n       extern \"C++\" { char * strpbrk (char *, const char *); }  */\n_GL_CXXALIAS_SYS_CAST2 (strpbrk,\n                        char *, (char const *__s, char const *__accept),\n                        const char *, (char const *__s, char const *__accept));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (strpbrk, char *, (char *__s, char const *__accept));\n_GL_CXXALIASWARN1 (strpbrk, char const *,\n                   (char const *__s, char const *__accept));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (strpbrk);\n# endif\n# if defined GNULIB_POSIXCHECK\n/* strpbrk() assumes the second argument is a list of single-byte characters.\n   Even in this simple case, it does not work with multibyte strings if the\n   locale encoding is GB18030 and one of the characters to be searched is a\n   digit.  */\n#  undef strpbrk\n_GL_WARN_ON_USE_CXX (strpbrk,\n                     const char *, char *, (const char *, const char *),\n                     \"strpbrk cannot work correctly on character strings \"\n                     \"in multibyte locales - \"\n                     \"use mbspbrk if you care about internationalization\");\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strpbrk\n# if HAVE_RAW_DECL_STRPBRK\n_GL_WARN_ON_USE_CXX (strpbrk,\n                     const char *, char *, (const char *, const char *),\n                     \"strpbrk is unportable - \"\n                     \"use gnulib module strpbrk for portability\");\n# endif\n#endif\n\n#if defined GNULIB_POSIXCHECK\n/* strspn() assumes the second argument is a list of single-byte characters.\n   Even in this simple case, it cannot work with multibyte strings.  */\n# undef strspn\n/* Assume strspn is always declared.  */\n_GL_WARN_ON_USE (strspn, \"strspn cannot work correctly on character strings \"\n                 \"in multibyte locales - \"\n                 \"use mbsspn if you care about internationalization\");\n#endif\n\n#if defined GNULIB_POSIXCHECK\n/* strrchr() does not work with multibyte strings if the locale encoding is\n   GB18030 and the character to be searched is a digit.  */\n# undef strrchr\n/* Assume strrchr is always declared.  */\n_GL_WARN_ON_USE_CXX (strrchr,\n                     const char *, char *, (const char *, int),\n                     \"strrchr cannot work correctly on character strings \"\n                     \"in some multibyte locales - \"\n                     \"use mbsrchr if you care about internationalization\");\n#endif\n\n/* Search the next delimiter (char listed in DELIM) starting at *STRINGP.\n   If one is found, overwrite it with a NUL, and advance *STRINGP\n   to point to the next char after it.  Otherwise, set *STRINGP to NULL.\n   If *STRINGP was already NULL, nothing happens.\n   Return the old value of *STRINGP.\n\n   This is a variant of strtok() that is multithread-safe and supports\n   empty fields.\n\n   Caveat: It modifies the original string.\n   Caveat: These functions cannot be used on constant strings.\n   Caveat: The identity of the delimiting character is lost.\n   Caveat: It doesn't work with multibyte strings unless all of the delimiter\n           characters are ASCII characters < 0x30.\n\n   See also strtok_r().  */\n#if @GNULIB_STRSEP@\n# if ! @HAVE_STRSEP@\n_GL_FUNCDECL_SYS (strsep, char *,\n                  (char **restrict __stringp, char const *restrict __delim)\n                  _GL_ARG_NONNULL ((1, 2)));\n# endif\n_GL_CXXALIAS_SYS (strsep, char *,\n                  (char **restrict __stringp, char const *restrict __delim));\n_GL_CXXALIASWARN (strsep);\n# if defined GNULIB_POSIXCHECK\n#  undef strsep\n_GL_WARN_ON_USE (strsep, \"strsep cannot work correctly on character strings \"\n                 \"in multibyte locales - \"\n                 \"use mbssep if you care about internationalization\");\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strsep\n# if HAVE_RAW_DECL_STRSEP\n_GL_WARN_ON_USE (strsep, \"strsep is unportable - \"\n                 \"use gnulib module strsep for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRSTR@\n# if @REPLACE_STRSTR@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strstr rpl_strstr\n#  endif\n_GL_FUNCDECL_RPL (strstr, char *, (const char *haystack, const char *needle)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (strstr, char *, (const char *haystack, const char *needle));\n# else\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" { const char * strstr (const char *, const char *); }\n       extern \"C++\" { char * strstr (char *, const char *); }  */\n_GL_CXXALIAS_SYS_CAST2 (strstr,\n                        char *, (const char *haystack, const char *needle),\n                        const char *, (const char *haystack, const char *needle));\n# endif\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (strstr, char *, (char *haystack, const char *needle));\n_GL_CXXALIASWARN1 (strstr, const char *,\n                   (const char *haystack, const char *needle));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (strstr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n/* strstr() does not work with multibyte strings if the locale encoding is\n   different from UTF-8:\n   POSIX says that it operates on \"strings\", and \"string\" in POSIX is defined\n   as a sequence of bytes, not of characters.  */\n# undef strstr\n/* Assume strstr is always declared.  */\n_GL_WARN_ON_USE (strstr, \"strstr is quadratic on many systems, and cannot \"\n                 \"work correctly on character strings in most \"\n                 \"multibyte locales - \"\n                 \"use mbsstr if you care about internationalization, \"\n                 \"or use strstr if you care about speed\");\n#endif\n\n/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive\n   comparison.  */\n#if @GNULIB_STRCASESTR@\n# if @REPLACE_STRCASESTR@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strcasestr rpl_strcasestr\n#  endif\n_GL_FUNCDECL_RPL (strcasestr, char *,\n                  (const char *haystack, const char *needle)\n                  _GL_ATTRIBUTE_PURE\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (strcasestr, char *,\n                  (const char *haystack, const char *needle));\n# else\n#  if ! @HAVE_STRCASESTR@\n_GL_FUNCDECL_SYS (strcasestr, char *,\n                  (const char *haystack, const char *needle)\n                  _GL_ATTRIBUTE_PURE\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" { const char * strcasestr (const char *, const char *); }\n       extern \"C++\" { char * strcasestr (char *, const char *); }  */\n_GL_CXXALIAS_SYS_CAST2 (strcasestr,\n                        char *, (const char *haystack, const char *needle),\n                        const char *, (const char *haystack, const char *needle));\n# endif\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (strcasestr, char *, (char *haystack, const char *needle));\n_GL_CXXALIASWARN1 (strcasestr, const char *,\n                   (const char *haystack, const char *needle));\n# else\n_GL_CXXALIASWARN (strcasestr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n/* strcasestr() does not work with multibyte strings:\n   It is a glibc extension, and glibc implements it only for unibyte\n   locales.  */\n# undef strcasestr\n# if HAVE_RAW_DECL_STRCASESTR\n_GL_WARN_ON_USE (strcasestr, \"strcasestr does work correctly on character \"\n                 \"strings in multibyte locales - \"\n                 \"use mbscasestr if you care about \"\n                 \"internationalization, or use c-strcasestr if you want \"\n                 \"a locale independent function\");\n# endif\n#endif\n\n/* Parse S into tokens separated by characters in DELIM.\n   If S is NULL, the saved pointer in SAVE_PTR is used as\n   the next starting point.  For example:\n        char s[] = \"-abc-=-def\";\n        char *sp;\n        x = strtok_r(s, \"-\", &sp);      // x = \"abc\", sp = \"=-def\"\n        x = strtok_r(NULL, \"-=\", &sp);  // x = \"def\", sp = NULL\n        x = strtok_r(NULL, \"=\", &sp);   // x = NULL\n                // s = \"abc\\0-def\\0\"\n\n   This is a variant of strtok() that is multithread-safe.\n\n   For the POSIX documentation for this function, see:\n   https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtok.html\n\n   Caveat: It modifies the original string.\n   Caveat: These functions cannot be used on constant strings.\n   Caveat: The identity of the delimiting character is lost.\n   Caveat: It doesn't work with multibyte strings unless all of the delimiter\n           characters are ASCII characters < 0x30.\n\n   See also strsep().  */\n#if @GNULIB_STRTOK_R@\n# if @REPLACE_STRTOK_R@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strtok_r\n#   define strtok_r rpl_strtok_r\n#  endif\n_GL_FUNCDECL_RPL (strtok_r, char *,\n                  (char *restrict s, char const *restrict delim,\n                   char **restrict save_ptr)\n                  _GL_ARG_NONNULL ((2, 3)));\n_GL_CXXALIAS_RPL (strtok_r, char *,\n                  (char *restrict s, char const *restrict delim,\n                   char **restrict save_ptr));\n# else\n#  if @UNDEFINE_STRTOK_R@ || defined GNULIB_POSIXCHECK\n#   undef strtok_r\n#  endif\n#  if ! @HAVE_DECL_STRTOK_R@\n_GL_FUNCDECL_SYS (strtok_r, char *,\n                  (char *restrict s, char const *restrict delim,\n                   char **restrict save_ptr)\n                  _GL_ARG_NONNULL ((2, 3)));\n#  endif\n_GL_CXXALIAS_SYS (strtok_r, char *,\n                  (char *restrict s, char const *restrict delim,\n                   char **restrict save_ptr));\n# endif\n_GL_CXXALIASWARN (strtok_r);\n# if defined GNULIB_POSIXCHECK\n_GL_WARN_ON_USE (strtok_r, \"strtok_r cannot work correctly on character \"\n                 \"strings in multibyte locales - \"\n                 \"use mbstok_r if you care about internationalization\");\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strtok_r\n# if HAVE_RAW_DECL_STRTOK_R\n_GL_WARN_ON_USE (strtok_r, \"strtok_r is unportable - \"\n                 \"use gnulib module strtok_r for portability\");\n# endif\n#endif\n\n\n/* The following functions are not specified by POSIX.  They are gnulib\n   extensions.  */\n\n#if @GNULIB_MBSLEN@\n/* Return the number of multibyte characters in the character string STRING.\n   This considers multibyte characters, unlike strlen, which counts bytes.  */\n# ifdef __MirBSD__  /* MirBSD defines mbslen as a macro.  Override it.  */\n#  undef mbslen\n# endif\n# if @HAVE_MBSLEN@  /* AIX, OSF/1, MirBSD define mbslen already in libc.  */\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define mbslen rpl_mbslen\n#  endif\n_GL_FUNCDECL_RPL (mbslen, size_t, (const char *string)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (mbslen, size_t, (const char *string));\n# else\n_GL_FUNCDECL_SYS (mbslen, size_t, (const char *string)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_SYS (mbslen, size_t, (const char *string));\n# endif\n_GL_CXXALIASWARN (mbslen);\n#endif\n\n#if @GNULIB_MBSNLEN@\n/* Return the number of multibyte characters in the character string starting\n   at STRING and ending at STRING + LEN.  */\n_GL_EXTERN_C size_t mbsnlen (const char *string, size_t len)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1));\n#endif\n\n#if @GNULIB_MBSCHR@\n/* Locate the first single-byte character C in the character string STRING,\n   and return a pointer to it.  Return NULL if C is not found in STRING.\n   Unlike strchr(), this function works correctly in multibyte locales with\n   encodings such as GB18030.  */\n# if defined __hpux\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define mbschr rpl_mbschr /* avoid collision with HP-UX function */\n#  endif\n_GL_FUNCDECL_RPL (mbschr, char *, (const char *string, int c)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (mbschr, char *, (const char *string, int c));\n# else\n_GL_FUNCDECL_SYS (mbschr, char *, (const char *string, int c)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_SYS (mbschr, char *, (const char *string, int c));\n# endif\n_GL_CXXALIASWARN (mbschr);\n#endif\n\n#if @GNULIB_MBSRCHR@\n/* Locate the last single-byte character C in the character string STRING,\n   and return a pointer to it.  Return NULL if C is not found in STRING.\n   Unlike strrchr(), this function works correctly in multibyte locales with\n   encodings such as GB18030.  */\n# if defined __hpux || defined __INTERIX\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define mbsrchr rpl_mbsrchr /* avoid collision with system function */\n#  endif\n_GL_FUNCDECL_RPL (mbsrchr, char *, (const char *string, int c)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (mbsrchr, char *, (const char *string, int c));\n# else\n_GL_FUNCDECL_SYS (mbsrchr, char *, (const char *string, int c)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_SYS (mbsrchr, char *, (const char *string, int c));\n# endif\n_GL_CXXALIASWARN (mbsrchr);\n#endif\n\n#if @GNULIB_MBSSTR@\n/* Find the first occurrence of the character string NEEDLE in the character\n   string HAYSTACK.  Return NULL if NEEDLE is not found in HAYSTACK.\n   Unlike strstr(), this function works correctly in multibyte locales with\n   encodings different from UTF-8.  */\n_GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if @GNULIB_MBSCASECMP@\n/* Compare the character strings S1 and S2, ignoring case, returning less than,\n   equal to or greater than zero if S1 is lexicographically less than, equal to\n   or greater than S2.\n   Note: This function may, in multibyte locales, return 0 for strings of\n   different lengths!\n   Unlike strcasecmp(), this function works correctly in multibyte locales.  */\n_GL_EXTERN_C int mbscasecmp (const char *s1, const char *s2)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if @GNULIB_MBSNCASECMP@\n/* Compare the initial segment of the character string S1 consisting of at most\n   N characters with the initial segment of the character string S2 consisting\n   of at most N characters, ignoring case, returning less than, equal to or\n   greater than zero if the initial segment of S1 is lexicographically less\n   than, equal to or greater than the initial segment of S2.\n   Note: This function may, in multibyte locales, return 0 for initial segments\n   of different lengths!\n   Unlike strncasecmp(), this function works correctly in multibyte locales.\n   But beware that N is not a byte count but a character count!  */\n_GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if @GNULIB_MBSPCASECMP@\n/* Compare the initial segment of the character string STRING consisting of\n   at most mbslen (PREFIX) characters with the character string PREFIX,\n   ignoring case.  If the two match, return a pointer to the first byte\n   after this prefix in STRING.  Otherwise, return NULL.\n   Note: This function may, in multibyte locales, return non-NULL if STRING\n   is of smaller length than PREFIX!\n   Unlike strncasecmp(), this function works correctly in multibyte\n   locales.  */\n_GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if @GNULIB_MBSCASESTR@\n/* Find the first occurrence of the character string NEEDLE in the character\n   string HAYSTACK, using case-insensitive comparison.\n   Note: This function may, in multibyte locales, return success even if\n   strlen (haystack) < strlen (needle) !\n   Unlike strcasestr(), this function works correctly in multibyte locales.  */\n_GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if @GNULIB_MBSCSPN@\n/* Find the first occurrence in the character string STRING of any character\n   in the character string ACCEPT.  Return the number of bytes from the\n   beginning of the string to this occurrence, or to the end of the string\n   if none exists.\n   Unlike strcspn(), this function works correctly in multibyte locales.  */\n_GL_EXTERN_C size_t mbscspn (const char *string, const char *accept)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if @GNULIB_MBSPBRK@\n/* Find the first occurrence in the character string STRING of any character\n   in the character string ACCEPT.  Return the pointer to it, or NULL if none\n   exists.\n   Unlike strpbrk(), this function works correctly in multibyte locales.  */\n# if defined __hpux\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */\n#  endif\n_GL_FUNCDECL_RPL (mbspbrk, char *, (const char *string, const char *accept)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (mbspbrk, char *, (const char *string, const char *accept));\n# else\n_GL_FUNCDECL_SYS (mbspbrk, char *, (const char *string, const char *accept)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_SYS (mbspbrk, char *, (const char *string, const char *accept));\n# endif\n_GL_CXXALIASWARN (mbspbrk);\n#endif\n\n#if @GNULIB_MBSSPN@\n/* Find the first occurrence in the character string STRING of any character\n   not in the character string REJECT.  Return the number of bytes from the\n   beginning of the string to this occurrence, or to the end of the string\n   if none exists.\n   Unlike strspn(), this function works correctly in multibyte locales.  */\n_GL_EXTERN_C size_t mbsspn (const char *string, const char *reject)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if @GNULIB_MBSSEP@\n/* Search the next delimiter (multibyte character listed in the character\n   string DELIM) starting at the character string *STRINGP.\n   If one is found, overwrite it with a NUL, and advance *STRINGP to point\n   to the next multibyte character after it.  Otherwise, set *STRINGP to NULL.\n   If *STRINGP was already NULL, nothing happens.\n   Return the old value of *STRINGP.\n\n   This is a variant of mbstok_r() that supports empty fields.\n\n   Caveat: It modifies the original string.\n   Caveat: These functions cannot be used on constant strings.\n   Caveat: The identity of the delimiting character is lost.\n\n   See also mbstok_r().  */\n_GL_EXTERN_C char * mbssep (char **stringp, const char *delim)\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if @GNULIB_MBSTOK_R@\n/* Parse the character string STRING into tokens separated by characters in\n   the character string DELIM.\n   If STRING is NULL, the saved pointer in SAVE_PTR is used as\n   the next starting point.  For example:\n        char s[] = \"-abc-=-def\";\n        char *sp;\n        x = mbstok_r(s, \"-\", &sp);      // x = \"abc\", sp = \"=-def\"\n        x = mbstok_r(NULL, \"-=\", &sp);  // x = \"def\", sp = NULL\n        x = mbstok_r(NULL, \"=\", &sp);   // x = NULL\n                // s = \"abc\\0-def\\0\"\n\n   Caveat: It modifies the original string.\n   Caveat: These functions cannot be used on constant strings.\n   Caveat: The identity of the delimiting character is lost.\n\n   See also mbssep().  */\n_GL_EXTERN_C char * mbstok_r (char *restrict string, const char *delim,\n                              char **save_ptr)\n     _GL_ARG_NONNULL ((2, 3));\n#endif\n\n/* Map any int, typically from errno, into an error message.  */\n#if @GNULIB_STRERROR@\n# if @REPLACE_STRERROR@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strerror\n#   define strerror rpl_strerror\n#  endif\n_GL_FUNCDECL_RPL (strerror, char *, (int));\n_GL_CXXALIAS_RPL (strerror, char *, (int));\n# else\n_GL_CXXALIAS_SYS (strerror, char *, (int));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (strerror);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strerror\n/* Assume strerror is always declared.  */\n_GL_WARN_ON_USE (strerror, \"strerror is unportable - \"\n                 \"use gnulib module strerror to guarantee non-NULL result\");\n#endif\n\n/* Map any int, typically from errno, into an error message.  Multithread-safe.\n   Uses the POSIX declaration, not the glibc declaration.  */\n#if @GNULIB_STRERROR_R@\n# if @REPLACE_STRERROR_R@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strerror_r\n#   define strerror_r rpl_strerror_r\n#  endif\n_GL_FUNCDECL_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen)\n                                   _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen));\n# else\n#  if !@HAVE_DECL_STRERROR_R@\n_GL_FUNCDECL_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen)\n                                   _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen));\n# endif\n# if @HAVE_DECL_STRERROR_R@\n_GL_CXXALIASWARN (strerror_r);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strerror_r\n# if HAVE_RAW_DECL_STRERROR_R\n_GL_WARN_ON_USE (strerror_r, \"strerror_r is unportable - \"\n                 \"use gnulib module strerror_r-posix for portability\");\n# endif\n#endif\n\n/* Return the name of the system error code ERRNUM.  */\n#if @GNULIB_STRERRORNAME_NP@\n# if @REPLACE_STRERRORNAME_NP@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strerrorname_np\n#   define strerrorname_np rpl_strerrorname_np\n#  endif\n_GL_FUNCDECL_RPL (strerrorname_np, const char *, (int errnum));\n_GL_CXXALIAS_RPL (strerrorname_np, const char *, (int errnum));\n# else\n#  if !@HAVE_STRERRORNAME_NP@\n_GL_FUNCDECL_SYS (strerrorname_np, const char *, (int errnum));\n#  endif\n_GL_CXXALIAS_SYS (strerrorname_np, const char *, (int errnum));\n# endif\n_GL_CXXALIASWARN (strerrorname_np);\n#elif defined GNULIB_POSIXCHECK\n# undef strerrorname_np\n# if HAVE_RAW_DECL_STRERRORNAME_NP\n_GL_WARN_ON_USE (strerrorname_np, \"strerrorname_np is unportable - \"\n                 \"use gnulib module strerrorname_np for portability\");\n# endif\n#endif\n\n/* Return an abbreviation string for the signal number SIG.  */\n#if @GNULIB_SIGABBREV_NP@\n# if ! @HAVE_SIGABBREV_NP@\n_GL_FUNCDECL_SYS (sigabbrev_np, const char *, (int sig));\n# endif\n_GL_CXXALIAS_SYS (sigabbrev_np, const char *, (int sig));\n_GL_CXXALIASWARN (sigabbrev_np);\n#elif defined GNULIB_POSIXCHECK\n# undef sigabbrev_np\n# if HAVE_RAW_DECL_SIGABBREV_NP\n_GL_WARN_ON_USE (sigabbrev_np, \"sigabbrev_np is unportable - \"\n                 \"use gnulib module sigabbrev_np for portability\");\n# endif\n#endif\n\n/* Return an English description string for the signal number SIG.  */\n#if @GNULIB_SIGDESCR_NP@\n# if ! @HAVE_SIGDESCR_NP@\n_GL_FUNCDECL_SYS (sigdescr_np, const char *, (int sig));\n# endif\n_GL_CXXALIAS_SYS (sigdescr_np, const char *, (int sig));\n_GL_CXXALIASWARN (sigdescr_np);\n#elif defined GNULIB_POSIXCHECK\n# undef sigdescr_np\n# if HAVE_RAW_DECL_SIGDESCR_NP\n_GL_WARN_ON_USE (sigdescr_np, \"sigdescr_np is unportable - \"\n                 \"use gnulib module sigdescr_np for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRSIGNAL@\n# if @REPLACE_STRSIGNAL@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strsignal rpl_strsignal\n#  endif\n_GL_FUNCDECL_RPL (strsignal, char *, (int __sig));\n_GL_CXXALIAS_RPL (strsignal, char *, (int __sig));\n# else\n#  if ! @HAVE_DECL_STRSIGNAL@\n_GL_FUNCDECL_SYS (strsignal, char *, (int __sig));\n#  endif\n/* Need to cast, because on Cygwin 1.5.x systems, the return type is\n   'const char *'.  */\n_GL_CXXALIAS_SYS_CAST (strsignal, char *, (int __sig));\n# endif\n_GL_CXXALIASWARN (strsignal);\n#elif defined GNULIB_POSIXCHECK\n# undef strsignal\n# if HAVE_RAW_DECL_STRSIGNAL\n_GL_WARN_ON_USE (strsignal, \"strsignal is unportable - \"\n                 \"use gnulib module strsignal for portability\");\n# endif\n#endif\n\n#if @GNULIB_STRVERSCMP@\n# if !@HAVE_STRVERSCMP@\n_GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1, 2)));\n# endif\n_GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *));\n_GL_CXXALIASWARN (strverscmp);\n#elif defined GNULIB_POSIXCHECK\n# undef strverscmp\n# if HAVE_RAW_DECL_STRVERSCMP\n_GL_WARN_ON_USE (strverscmp, \"strverscmp is unportable - \"\n                 \"use gnulib module strverscmp for portability\");\n# endif\n#endif\n\n\n#endif /* _@GUARD_PREFIX@_STRING_H */\n#endif /* _@GUARD_PREFIX@_STRING_H */\n#endif\n"
  },
  {
    "path": "gnulib/strnlen.c",
    "content": "/* Find the length of STRING, but scan at most MAXLEN characters.\n   Copyright (C) 2005-2007, 2009-2021 Free Software Foundation, Inc.\n   Written by Simon Josefsson.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n#include <string.h>\n\n/* Find the length of STRING, but scan at most MAXLEN characters.\n   If no '\\0' terminator is found in that many characters, return MAXLEN.  */\n\nsize_t\nstrnlen (const char *string, size_t maxlen)\n{\n  const char *end = memchr (string, '\\0', maxlen);\n  return end ? (size_t) (end - string) : maxlen;\n}\n"
  },
  {
    "path": "gnulib/strnlen1.c",
    "content": "/* Find the length of STRING + 1, but scan at most MAXLEN bytes.\n   Copyright (C) 2005-2006, 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include \"strnlen1.h\"\n\n#include <string.h>\n\n/* Find the length of STRING + 1, but scan at most MAXLEN bytes.\n   If no '\\0' terminator is found in that many characters, return MAXLEN.  */\n/* This is the same as strnlen (string, maxlen - 1) + 1.  */\nsize_t\nstrnlen1 (const char *string, size_t maxlen)\n{\n  const char *end = (const char *) memchr (string, '\\0', maxlen);\n  if (end != NULL)\n    return end - string + 1;\n  else\n    return maxlen;\n}\n"
  },
  {
    "path": "gnulib/strnlen1.h",
    "content": "/* Find the length of STRING + 1, but scan at most MAXLEN bytes.\n   Copyright (C) 2005, 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _STRNLEN1_H\n#define _STRNLEN1_H\n\n#include <stddef.h>\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/* Find the length of STRING + 1, but scan at most MAXLEN bytes.\n   If no '\\0' terminator is found in that many characters, return MAXLEN.  */\n/* This is the same as strnlen (string, maxlen - 1) + 1.  */\nextern size_t strnlen1 (const char *string, size_t maxlen)\n  _GL_ATTRIBUTE_PURE;\n\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif /* _STRNLEN1_H */\n"
  },
  {
    "path": "gnulib/sys_types.in.h",
    "content": "/* Provide a more complete sys/types.h.\n\n   Copyright (C) 2011-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n#if defined _WIN32 && !defined __CYGWIN__ \\\n    && (defined __need_off_t || defined __need___off64_t \\\n        || defined __need_ssize_t || defined __need_time_t)\n\n/* Special invocation convention inside mingw header files.  */\n\n#@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@\n\n#else\n/* Normal invocation convention.  */\n\n#ifndef _@GUARD_PREFIX@_SYS_TYPES_H\n\n/* The include_next requires a split double-inclusion guard.  */\n# define _GL_INCLUDING_SYS_TYPES_H\n#@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@\n# undef _GL_INCLUDING_SYS_TYPES_H\n\n#ifndef _@GUARD_PREFIX@_SYS_TYPES_H\n#define _@GUARD_PREFIX@_SYS_TYPES_H\n\n/* Override off_t if Large File Support is requested on native Windows.  */\n#if @WINDOWS_64_BIT_OFF_T@\n/* Same as int64_t in <stdint.h>.  */\n# if defined _MSC_VER\n#  define off_t __int64\n# else\n#  define off_t long long int\n# endif\n/* Indicator, for gnulib internal purposes.  */\n# define _GL_WINDOWS_64_BIT_OFF_T 1\n#endif\n\n/* Override dev_t and ino_t if distinguishable inodes support is requested\n   on native Windows.  */\n#if @WINDOWS_STAT_INODES@\n\n# if @WINDOWS_STAT_INODES@ == 2\n/* Experimental, not useful in Windows 10.  */\n\n/* Define dev_t to a 64-bit type.  */\n#  if !defined GNULIB_defined_dev_t\ntypedef unsigned long long int rpl_dev_t;\n#   undef dev_t\n#   define dev_t rpl_dev_t\n#   define GNULIB_defined_dev_t 1\n#  endif\n\n/* Define ino_t to a 128-bit type.  */\n#  if !defined GNULIB_defined_ino_t\n/* MSVC does not have a 128-bit integer type.\n   GCC has a 128-bit integer type __int128, but only on 64-bit targets.  */\ntypedef struct { unsigned long long int _gl_ino[2]; } rpl_ino_t;\n#   undef ino_t\n#   define ino_t rpl_ino_t\n#   define GNULIB_defined_ino_t 1\n#  endif\n\n# else /* @WINDOWS_STAT_INODES@ == 1 */\n\n/* Define ino_t to a 64-bit type.  */\n#  if !defined GNULIB_defined_ino_t\ntypedef unsigned long long int rpl_ino_t;\n#   undef ino_t\n#   define ino_t rpl_ino_t\n#   define GNULIB_defined_ino_t 1\n#  endif\n\n# endif\n\n/* Indicator, for gnulib internal purposes.  */\n# define _GL_WINDOWS_STAT_INODES @WINDOWS_STAT_INODES@\n\n#endif\n\n/* MSVC 9 defines size_t in <stddef.h>, not in <sys/types.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if (defined _WIN32 && ! defined __CYGWIN__) && ! defined __GLIBC__\n# include <stddef.h>\n#endif\n\n#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */\n#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */\n#endif /* __need_XXX */\n"
  },
  {
    "path": "gnulib/unistd.c",
    "content": "/* Inline functions for <unistd.h>.\n\n   Copyright (C) 2012-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n#define _GL_UNISTD_INLINE _GL_EXTERN_INLINE\n#include \"unistd.h\"\ntypedef int dummy;\n"
  },
  {
    "path": "gnulib/unistd.in.h",
    "content": "/* Substitute for and wrapper around <unistd.h>.\n   Copyright (C) 2003-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _@GUARD_PREFIX@_UNISTD_H\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n#if @HAVE_UNISTD_H@ && defined _GL_INCLUDING_UNISTD_H\n/* Special invocation convention:\n   - On Mac OS X 10.3.9 we have a sequence of nested includes\n     <unistd.h> -> <signal.h> -> <pthread.h> -> <unistd.h>\n     In this situation, the functions are not yet declared, therefore we cannot\n     provide the C++ aliases.  */\n\n#@INCLUDE_NEXT@ @NEXT_UNISTD_H@\n\n#else\n/* Normal invocation convention.  */\n\n/* The include_next requires a split double-inclusion guard.  */\n#if @HAVE_UNISTD_H@\n# define _GL_INCLUDING_UNISTD_H\n# @INCLUDE_NEXT@ @NEXT_UNISTD_H@\n# undef _GL_INCLUDING_UNISTD_H\n#endif\n\n/* Get all possible declarations of gethostname().  */\n#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \\\n  && !defined _GL_INCLUDING_WINSOCK2_H\n# define _GL_INCLUDING_WINSOCK2_H\n# include <winsock2.h>\n# undef _GL_INCLUDING_WINSOCK2_H\n#endif\n\n#if !defined _@GUARD_PREFIX@_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H\n#define _@GUARD_PREFIX@_UNISTD_H\n\n/* NetBSD 5.0 mis-defines NULL.  Also get size_t.  */\n/* But avoid namespace pollution on glibc systems.  */\n#ifndef __GLIBC__\n# include <stddef.h>\n#endif\n\n/* mingw doesn't define the SEEK_* or *_FILENO macros in <unistd.h>.  */\n/* MSVC declares 'unlink' in <stdio.h>, not in <unistd.h>.  We must include\n   it before we  #define unlink rpl_unlink.  */\n/* Cygwin 1.7.1 declares symlinkat in <stdio.h>, not in <unistd.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if (!(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) \\\n     || ((@GNULIB_UNLINK@ || defined GNULIB_POSIXCHECK) \\\n         && (defined _WIN32 && ! defined __CYGWIN__)) \\\n     || ((@GNULIB_SYMLINKAT@ || defined GNULIB_POSIXCHECK) \\\n         && defined __CYGWIN__)) \\\n    && ! defined __GLIBC__\n# include <stdio.h>\n#endif\n\n/* Cygwin 1.7.1 and Android 4.3 declare unlinkat in <fcntl.h>, not in\n   <unistd.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \\\n    && (defined __CYGWIN__ || defined __ANDROID__) \\\n    && ! defined __GLIBC__\n# include <fcntl.h>\n#endif\n\n/* mingw fails to declare _exit in <unistd.h>.  */\n/* mingw, MSVC, BeOS, Haiku declare environ in <stdlib.h>, not in\n   <unistd.h>.  */\n/* Solaris declares getcwd not only in <unistd.h> but also in <stdlib.h>.  */\n/* OSF Tru64 Unix cannot see gnulib rpl_strtod when system <stdlib.h> is\n   included here.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if !defined __GLIBC__ && !defined __osf__\n# define __need_system_stdlib_h\n# include <stdlib.h>\n# undef __need_system_stdlib_h\n#endif\n\n/* Native Windows platforms declare _chdir, _getcwd, _rmdir in\n   <io.h> and/or <direct.h>, not in <unistd.h>.\n   They also declare _access(), _chmod(), _close(), _dup(), _dup2(), _isatty(),\n   _lseek(), _read(), _unlink(), _write() in <io.h>.  */\n#if defined _WIN32 && !defined __CYGWIN__\n# include <io.h>\n# include <direct.h>\n#endif\n\n/* Native Windows platforms declare _execl*, _execv* in <process.h>.  */\n#if defined _WIN32 && !defined __CYGWIN__\n# include <process.h>\n#endif\n\n/* AIX and OSF/1 5.1 declare getdomainname in <netdb.h>, not in <unistd.h>.\n   NonStop Kernel declares gethostname in <netdb.h>, not in <unistd.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if ((@GNULIB_GETDOMAINNAME@ && (defined _AIX || defined __osf__)) \\\n     || (@GNULIB_GETHOSTNAME@ && defined __TANDEM)) \\\n    && !defined __GLIBC__\n# include <netdb.h>\n#endif\n\n/* Mac OS X 10.13, Solaris 11.4, and Android 9.0 declare getentropy in\n   <sys/random.h>, not in <unistd.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if (@GNULIB_GETENTROPY@ || defined GNULIB_POSIXCHECK) \\\n    && ((defined __APPLE__ && defined __MACH__) || defined __sun \\\n        || defined __ANDROID__) \\\n    && @UNISTD_H_HAVE_SYS_RANDOM_H@ \\\n    && !defined __GLIBC__\n# include <sys/random.h>\n#endif\n\n/* Android 4.3 declares fchownat in <sys/stat.h>, not in <unistd.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if (@GNULIB_FCHOWNAT@ || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \\\n    && !defined __GLIBC__\n# include <sys/stat.h>\n#endif\n\n/* MSVC defines off_t in <sys/types.h>.\n   May also define off_t to a 64-bit type on native Windows.  */\n/* Get off_t, ssize_t, mode_t.  */\n#include <sys/types.h>\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n\n\n/* Get getopt(), optarg, optind, opterr, optopt.  */\n#if @GNULIB_GETOPT_POSIX@ && @GNULIB_UNISTD_H_GETOPT@ && !defined _GL_SYSTEM_GETOPT\n# include <getopt-cdefs.h>\n# include <getopt-pfx-core.h>\n#endif\n\n#ifndef _GL_INLINE_HEADER_BEGIN\n #error \"Please include config.h first.\"\n#endif\n_GL_INLINE_HEADER_BEGIN\n#ifndef _GL_UNISTD_INLINE\n# define _GL_UNISTD_INLINE _GL_INLINE\n#endif\n\n/* Hide some function declarations from <winsock2.h>.  */\n\n#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@\n# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef socket\n#   define socket              socket_used_without_including_sys_socket_h\n#   undef connect\n#   define connect             connect_used_without_including_sys_socket_h\n#   undef accept\n#   define accept              accept_used_without_including_sys_socket_h\n#   undef bind\n#   define bind                bind_used_without_including_sys_socket_h\n#   undef getpeername\n#   define getpeername         getpeername_used_without_including_sys_socket_h\n#   undef getsockname\n#   define getsockname         getsockname_used_without_including_sys_socket_h\n#   undef getsockopt\n#   define getsockopt          getsockopt_used_without_including_sys_socket_h\n#   undef listen\n#   define listen              listen_used_without_including_sys_socket_h\n#   undef recv\n#   define recv                recv_used_without_including_sys_socket_h\n#   undef send\n#   define send                send_used_without_including_sys_socket_h\n#   undef recvfrom\n#   define recvfrom            recvfrom_used_without_including_sys_socket_h\n#   undef sendto\n#   define sendto              sendto_used_without_including_sys_socket_h\n#   undef setsockopt\n#   define setsockopt          setsockopt_used_without_including_sys_socket_h\n#   undef shutdown\n#   define shutdown            shutdown_used_without_including_sys_socket_h\n#  else\n    _GL_WARN_ON_USE (socket,\n                     \"socket() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (connect,\n                     \"connect() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (accept,\n                     \"accept() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (bind,\n                     \"bind() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (getpeername,\n                     \"getpeername() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (getsockname,\n                     \"getsockname() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (getsockopt,\n                     \"getsockopt() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (listen,\n                     \"listen() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (recv,\n                     \"recv() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (send,\n                     \"send() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (recvfrom,\n                     \"recvfrom() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (sendto,\n                     \"sendto() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (setsockopt,\n                     \"setsockopt() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (shutdown,\n                     \"shutdown() used without including <sys/socket.h>\");\n#  endif\n# endif\n# if !defined _@GUARD_PREFIX@_SYS_SELECT_H\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef select\n#   define select              select_used_without_including_sys_select_h\n#  else\n    _GL_WARN_ON_USE (select,\n                     \"select() used without including <sys/select.h>\");\n#  endif\n# endif\n#endif\n\n\n/* OS/2 EMX lacks these macros.  */\n#ifndef STDIN_FILENO\n# define STDIN_FILENO 0\n#endif\n#ifndef STDOUT_FILENO\n# define STDOUT_FILENO 1\n#endif\n#ifndef STDERR_FILENO\n# define STDERR_FILENO 2\n#endif\n\n/* Ensure *_OK macros exist.  */\n#ifndef F_OK\n# define F_OK 0\n# define X_OK 1\n# define W_OK 2\n# define R_OK 4\n#endif\n\n\n/* Declare overridden functions.  */\n\n\n#if @GNULIB_ACCESS@\n# if @REPLACE_ACCESS@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef access\n#   define access rpl_access\n#  endif\n_GL_FUNCDECL_RPL (access, int, (const char *file, int mode)\n                               _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (access, int, (const char *file, int mode));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef access\n#   define access _access\n#  endif\n_GL_CXXALIAS_MDA (access, int, (const char *file, int mode));\n# else\n_GL_CXXALIAS_SYS (access, int, (const char *file, int mode));\n# endif\n_GL_CXXALIASWARN (access);\n#elif defined GNULIB_POSIXCHECK\n# undef access\n# if HAVE_RAW_DECL_ACCESS\n/* The access() function is a security risk.  */\n_GL_WARN_ON_USE (access, \"access does not always support X_OK - \"\n                 \"use gnulib module access for portability; \"\n                 \"also, this function is a security risk - \"\n                 \"use the gnulib module faccessat instead\");\n# endif\n#elif @GNULIB_MDA_ACCESS@\n/* On native Windows, map 'access' to '_access', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::access always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef access\n#   define access _access\n#  endif\n_GL_CXXALIAS_MDA (access, int, (const char *file, int mode));\n# else\n_GL_CXXALIAS_SYS (access, int, (const char *file, int mode));\n# endif\n_GL_CXXALIASWARN (access);\n#endif\n\n\n#if @GNULIB_CHDIR@\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef chdir\n#   define chdir _chdir\n#  endif\n_GL_CXXALIAS_MDA (chdir, int, (const char *file));\n# else\n_GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIASWARN (chdir);\n#elif defined GNULIB_POSIXCHECK\n# undef chdir\n# if HAVE_RAW_DECL_CHDIR\n_GL_WARN_ON_USE (chown, \"chdir is not always in <unistd.h> - \"\n                 \"use gnulib module chdir for portability\");\n# endif\n#elif @GNULIB_MDA_CHDIR@\n/* On native Windows, map 'chdir' to '_chdir', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::chdir always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef chdir\n#   define chdir _chdir\n#  endif\n_GL_CXXALIAS_MDA (chdir, int, (const char *file));\n# else\n_GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIASWARN (chdir);\n#endif\n\n\n#if @GNULIB_CHOWN@\n/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE\n   to GID (if GID is not -1).  Follow symbolic links.\n   Return 0 if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html.  */\n# if @REPLACE_CHOWN@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef chown\n#   define chown rpl_chown\n#  endif\n_GL_FUNCDECL_RPL (chown, int, (const char *file, uid_t uid, gid_t gid)\n                              _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (chown, int, (const char *file, uid_t uid, gid_t gid));\n# else\n#  if !@HAVE_CHOWN@\n_GL_FUNCDECL_SYS (chown, int, (const char *file, uid_t uid, gid_t gid)\n                              _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (chown, int, (const char *file, uid_t uid, gid_t gid));\n# endif\n_GL_CXXALIASWARN (chown);\n#elif defined GNULIB_POSIXCHECK\n# undef chown\n# if HAVE_RAW_DECL_CHOWN\n_GL_WARN_ON_USE (chown, \"chown fails to follow symlinks on some systems and \"\n                 \"doesn't treat a uid or gid of -1 on some systems - \"\n                 \"use gnulib module chown for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_CLOSE@\n# if @REPLACE_CLOSE@\n/* Automatically included by modules that need a replacement for close.  */\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef close\n#   define close rpl_close\n#  endif\n_GL_FUNCDECL_RPL (close, int, (int fd));\n_GL_CXXALIAS_RPL (close, int, (int fd));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef close\n#   define close _close\n#  endif\n_GL_CXXALIAS_MDA (close, int, (int fd));\n# else\n_GL_CXXALIAS_SYS (close, int, (int fd));\n# endif\n_GL_CXXALIASWARN (close);\n#elif @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@\n# undef close\n# define close close_used_without_requesting_gnulib_module_close\n#elif defined GNULIB_POSIXCHECK\n# undef close\n/* Assume close is always declared.  */\n_GL_WARN_ON_USE (close, \"close does not portably work on sockets - \"\n                 \"use gnulib module close for portability\");\n#elif @GNULIB_MDA_CLOSE@\n/* On native Windows, map 'close' to '_close', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::close always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef close\n#   define close _close\n#  endif\n_GL_CXXALIAS_MDA (close, int, (int fd));\n# else\n_GL_CXXALIAS_SYS (close, int, (int fd));\n# endif\n_GL_CXXALIASWARN (close);\n#endif\n\n\n#if @GNULIB_COPY_FILE_RANGE@\n# if !@HAVE_COPY_FILE_RANGE@\n_GL_FUNCDECL_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos,\n                                             int ofd, off_t *opos,\n                                             size_t len, unsigned flags));\n_GL_CXXALIAS_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos,\n                                             int ofd, off_t *opos,\n                                             size_t len, unsigned flags));\n# endif\n_GL_CXXALIASWARN (copy_file_range);\n#elif defined GNULIB_POSIXCHECK\n# if HAVE_RAW_DECL_COPY_FILE_RANGE\n_GL_WARN_ON_USE (copy_file_range,\n                 \"copy_file_range is unportable - \"\n                 \"use gnulib module copy_file_range for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_DUP@\n# if @REPLACE_DUP@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define dup rpl_dup\n#  endif\n_GL_FUNCDECL_RPL (dup, int, (int oldfd));\n_GL_CXXALIAS_RPL (dup, int, (int oldfd));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef dup\n#   define dup _dup\n#  endif\n_GL_CXXALIAS_MDA (dup, int, (int oldfd));\n# else\n_GL_CXXALIAS_SYS (dup, int, (int oldfd));\n# endif\n_GL_CXXALIASWARN (dup);\n#elif defined GNULIB_POSIXCHECK\n# undef dup\n# if HAVE_RAW_DECL_DUP\n_GL_WARN_ON_USE (dup, \"dup is unportable - \"\n                 \"use gnulib module dup for portability\");\n# endif\n#elif @GNULIB_MDA_DUP@\n/* On native Windows, map 'dup' to '_dup', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::dup always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef dup\n#   define dup _dup\n#  endif\n_GL_CXXALIAS_MDA (dup, int, (int oldfd));\n# else\n_GL_CXXALIAS_SYS (dup, int, (int oldfd));\n# endif\n_GL_CXXALIASWARN (dup);\n#endif\n\n\n#if @GNULIB_DUP2@\n/* Copy the file descriptor OLDFD into file descriptor NEWFD.  Do nothing if\n   NEWFD = OLDFD, otherwise close NEWFD first if it is open.\n   Return newfd if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup2.html>.  */\n# if @REPLACE_DUP2@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define dup2 rpl_dup2\n#  endif\n_GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd));\n_GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef dup2\n#   define dup2 _dup2\n#  endif\n_GL_CXXALIAS_MDA (dup2, int, (int oldfd, int newfd));\n# else\n_GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd));\n# endif\n_GL_CXXALIASWARN (dup2);\n#elif defined GNULIB_POSIXCHECK\n# undef dup2\n# if HAVE_RAW_DECL_DUP2\n_GL_WARN_ON_USE (dup2, \"dup2 is unportable - \"\n                 \"use gnulib module dup2 for portability\");\n# endif\n#elif @GNULIB_MDA_DUP2@\n/* On native Windows, map 'dup2' to '_dup2', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::dup2 always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef dup2\n#   define dup2 _dup2\n#  endif\n_GL_CXXALIAS_MDA (dup2, int, (int oldfd, int newfd));\n# else\n_GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd));\n# endif\n_GL_CXXALIASWARN (dup2);\n#endif\n\n\n#if @GNULIB_DUP3@\n/* Copy the file descriptor OLDFD into file descriptor NEWFD, with the\n   specified flags.\n   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)\n   and O_TEXT, O_BINARY (defined in \"binary-io.h\").\n   Close NEWFD first if it is open.\n   Return newfd if successful, otherwise -1 and errno set.\n   See the Linux man page at\n   <https://www.kernel.org/doc/man-pages/online/pages/man2/dup3.2.html>.  */\n# if @HAVE_DUP3@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define dup3 rpl_dup3\n#  endif\n_GL_FUNCDECL_RPL (dup3, int, (int oldfd, int newfd, int flags));\n_GL_CXXALIAS_RPL (dup3, int, (int oldfd, int newfd, int flags));\n# else\n_GL_FUNCDECL_SYS (dup3, int, (int oldfd, int newfd, int flags));\n_GL_CXXALIAS_SYS (dup3, int, (int oldfd, int newfd, int flags));\n# endif\n_GL_CXXALIASWARN (dup3);\n#elif defined GNULIB_POSIXCHECK\n# undef dup3\n# if HAVE_RAW_DECL_DUP3\n_GL_WARN_ON_USE (dup3, \"dup3 is unportable - \"\n                 \"use gnulib module dup3 for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_ENVIRON@\n# if defined __CYGWIN__ && !defined __i386__\n/* The 'environ' variable is defined in a DLL. Therefore its declaration needs\n   the '__declspec(dllimport)' attribute, but the system's <unistd.h> lacks it.\n   This leads to a link error on 64-bit Cygwin when the option\n   -Wl,--disable-auto-import is in use.  */\n_GL_EXTERN_C __declspec(dllimport) char **environ;\n# endif\n# if !@HAVE_DECL_ENVIRON@\n/* Set of environment variables and values.  An array of strings of the form\n   \"VARIABLE=VALUE\", terminated with a NULL.  */\n#  if defined __APPLE__ && defined __MACH__\n#   include <TargetConditionals.h>\n#   if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR\n#    define _GL_USE_CRT_EXTERNS\n#   endif\n#  endif\n#  ifdef _GL_USE_CRT_EXTERNS\n#   include <crt_externs.h>\n#   define environ (*_NSGetEnviron ())\n#  else\n#   ifdef __cplusplus\nextern \"C\" {\n#   endif\nextern char **environ;\n#   ifdef __cplusplus\n}\n#   endif\n#  endif\n# endif\n#elif defined GNULIB_POSIXCHECK\n# if HAVE_RAW_DECL_ENVIRON\n_GL_UNISTD_INLINE char ***\n_GL_WARN_ON_USE_ATTRIBUTE (\"environ is unportable - \"\n                           \"use gnulib module environ for portability\")\nrpl_environ (void)\n{\n  return &environ;\n}\n#  undef environ\n#  define environ (*rpl_environ ())\n# endif\n#endif\n\n\n#if @GNULIB_EUIDACCESS@\n/* Like access(), except that it uses the effective user id and group id of\n   the current process.  */\n# if !@HAVE_EUIDACCESS@\n_GL_FUNCDECL_SYS (euidaccess, int, (const char *filename, int mode)\n                                   _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (euidaccess, int, (const char *filename, int mode));\n_GL_CXXALIASWARN (euidaccess);\n# if defined GNULIB_POSIXCHECK\n/* Like access(), this function is a security risk.  */\n_GL_WARN_ON_USE (euidaccess, \"the euidaccess function is a security risk - \"\n                 \"use the gnulib module faccessat instead\");\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef euidaccess\n# if HAVE_RAW_DECL_EUIDACCESS\n_GL_WARN_ON_USE (euidaccess, \"euidaccess is unportable - \"\n                 \"use gnulib module euidaccess for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_EXECL@\n# if @REPLACE_EXECL@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execl\n#   define execl rpl_execl\n#  endif\n_GL_FUNCDECL_RPL (execl, int, (const char *program, const char *arg, ...)\n                              _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (execl, int, (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execl, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execl);\n#elif defined GNULIB_POSIXCHECK\n# undef execl\n# if HAVE_RAW_DECL_EXECL\n_GL_WARN_ON_USE (execl, \"execl behaves very differently on mingw - \"\n                 \"use gnulib module execl for portability\");\n# endif\n#elif @GNULIB_MDA_EXECL@\n/* On native Windows, map 'execl' to '_execl', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execl always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execl\n#   define execl _execl\n#  endif\n_GL_CXXALIAS_MDA (execl, intptr_t, (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execl, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execl);\n#endif\n\n#if @GNULIB_EXECLE@\n# if @REPLACE_EXECLE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execle\n#   define execle rpl_execle\n#  endif\n_GL_FUNCDECL_RPL (execle, int, (const char *program, const char *arg, ...)\n                               _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (execle, int, (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execle, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execle);\n#elif defined GNULIB_POSIXCHECK\n# undef execle\n# if HAVE_RAW_DECL_EXECLE\n_GL_WARN_ON_USE (execle, \"execle behaves very differently on mingw - \"\n                 \"use gnulib module execle for portability\");\n# endif\n#elif @GNULIB_MDA_EXECLE@\n/* On native Windows, map 'execle' to '_execle', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execle always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execle\n#   define execle _execle\n#  endif\n_GL_CXXALIAS_MDA (execle, intptr_t,\n                  (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execle, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execle);\n#endif\n\n#if @GNULIB_EXECLP@\n# if @REPLACE_EXECLP@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execlp\n#   define execlp rpl_execlp\n#  endif\n_GL_FUNCDECL_RPL (execlp, int, (const char *program, const char *arg, ...)\n                               _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (execlp, int, (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execlp, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execlp);\n#elif defined GNULIB_POSIXCHECK\n# undef execlp\n# if HAVE_RAW_DECL_EXECLP\n_GL_WARN_ON_USE (execlp, \"execlp behaves very differently on mingw - \"\n                 \"use gnulib module execlp for portability\");\n# endif\n#elif @GNULIB_MDA_EXECLP@\n/* On native Windows, map 'execlp' to '_execlp', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execlp always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execlp\n#   define execlp _execlp\n#  endif\n_GL_CXXALIAS_MDA (execlp, intptr_t,\n                  (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execlp, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execlp);\n#endif\n\n\n#if @GNULIB_EXECV@\n# if @REPLACE_EXECV@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execv\n#   define execv rpl_execv\n#  endif\n_GL_FUNCDECL_RPL (execv, int, (const char *program, char * const *argv)\n                              _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (execv, int, (const char *program, char * const *argv));\n# else\n_GL_CXXALIAS_SYS (execv, int, (const char *program, char * const *argv));\n# endif\n_GL_CXXALIASWARN (execv);\n#elif defined GNULIB_POSIXCHECK\n# undef execv\n# if HAVE_RAW_DECL_EXECV\n_GL_WARN_ON_USE (execv, \"execv behaves very differently on mingw - \"\n                 \"use gnulib module execv for portability\");\n# endif\n#elif @GNULIB_MDA_EXECV@\n/* On native Windows, map 'execv' to '_execv', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execv always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execv\n#   define execv _execv\n#  endif\n_GL_CXXALIAS_MDA_CAST (execv, intptr_t,\n                       (const char *program, char * const *argv));\n# else\n_GL_CXXALIAS_SYS (execv, int, (const char *program, char * const *argv));\n# endif\n_GL_CXXALIASWARN (execv);\n#endif\n\n#if @GNULIB_EXECVE@\n# if @REPLACE_EXECVE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execve\n#   define execve rpl_execve\n#  endif\n_GL_FUNCDECL_RPL (execve, int,\n                  (const char *program, char * const *argv, char * const *env)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (execve, int,\n                  (const char *program, char * const *argv, char * const *env));\n# else\n_GL_CXXALIAS_SYS (execve, int,\n                  (const char *program, char * const *argv, char * const *env));\n# endif\n_GL_CXXALIASWARN (execve);\n#elif defined GNULIB_POSIXCHECK\n# undef execve\n# if HAVE_RAW_DECL_EXECVE\n_GL_WARN_ON_USE (execve, \"execve behaves very differently on mingw - \"\n                 \"use gnulib module execve for portability\");\n# endif\n#elif @GNULIB_MDA_EXECVE@\n/* On native Windows, map 'execve' to '_execve', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execve always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execve\n#   define execve _execve\n#  endif\n_GL_CXXALIAS_MDA_CAST (execve, intptr_t,\n                       (const char *program, char * const *argv,\n                        char * const *env));\n# else\n_GL_CXXALIAS_SYS (execve, int,\n                  (const char *program, char * const *argv, char * const *env));\n# endif\n_GL_CXXALIASWARN (execve);\n#endif\n\n#if @GNULIB_EXECVP@\n# if @REPLACE_EXECVP@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execvp\n#   define execvp rpl_execvp\n#  endif\n_GL_FUNCDECL_RPL (execvp, int, (const char *program, char * const *argv)\n                               _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (execvp, int, (const char *program, char * const *argv));\n# else\n_GL_CXXALIAS_SYS (execvp, int, (const char *program, char * const *argv));\n# endif\n_GL_CXXALIASWARN (execvp);\n#elif defined GNULIB_POSIXCHECK\n# undef execvp\n# if HAVE_RAW_DECL_EXECVP\n_GL_WARN_ON_USE (execvp, \"execvp behaves very differently on mingw - \"\n                 \"use gnulib module execvp for portability\");\n# endif\n#elif @GNULIB_MDA_EXECVP@\n/* On native Windows, map 'execvp' to '_execvp', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execvp always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execvp\n#   define execvp _execvp\n#  endif\n_GL_CXXALIAS_MDA_CAST (execvp, intptr_t,\n                       (const char *program, char * const *argv));\n# else\n_GL_CXXALIAS_SYS (execvp, int, (const char *program, char * const *argv));\n# endif\n_GL_CXXALIASWARN (execvp);\n#endif\n\n#if @GNULIB_EXECVPE@\n# if @REPLACE_EXECVPE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execvpe\n#   define execvpe rpl_execvpe\n#  endif\n_GL_FUNCDECL_RPL (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env));\n# else\n#  if !@HAVE_DECL_EXECVPE@\n_GL_FUNCDECL_SYS (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env));\n# endif\n_GL_CXXALIASWARN (execvpe);\n#elif defined GNULIB_POSIXCHECK\n# undef execvpe\n# if HAVE_RAW_DECL_EXECVPE\n_GL_WARN_ON_USE (execvpe, \"execvpe behaves very differently on mingw - \"\n                 \"use gnulib module execvpe for portability\");\n# endif\n#elif @GNULIB_MDA_EXECVPE@\n/* On native Windows, map 'execvpe' to '_execvpe', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execvpe on all platforms that have\n   it.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execvpe\n#   define execvpe _execvpe\n#  endif\n_GL_CXXALIAS_MDA_CAST (execvpe, intptr_t,\n                       (const char *program, char * const *argv,\n                        char * const *env));\n# elif @HAVE_EXECVPE@\n#  if !@HAVE_DECL_EXECVPE@\n_GL_FUNCDECL_SYS (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env));\n# endif\n# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_EXECVPE@\n_GL_CXXALIASWARN (execvpe);\n# endif\n#endif\n\n\n#if @GNULIB_FACCESSAT@\n# if @REPLACE_FACCESSAT@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef faccessat\n#   define faccessat rpl_faccessat\n#  endif\n_GL_FUNCDECL_RPL (faccessat, int,\n                  (int fd, char const *name, int mode, int flag)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (faccessat, int,\n                  (int fd, char const *name, int mode, int flag));\n# else\n#  if !@HAVE_FACCESSAT@\n_GL_FUNCDECL_SYS (faccessat, int,\n                  (int fd, char const *file, int mode, int flag)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (faccessat, int,\n                  (int fd, char const *file, int mode, int flag));\n# endif\n_GL_CXXALIASWARN (faccessat);\n#elif defined GNULIB_POSIXCHECK\n# undef faccessat\n# if HAVE_RAW_DECL_FACCESSAT\n_GL_WARN_ON_USE (faccessat, \"faccessat is not portable - \"\n                 \"use gnulib module faccessat for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_FCHDIR@\n/* Change the process' current working directory to the directory on which\n   the given file descriptor is open.\n   Return 0 if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html>.  */\n# if ! @HAVE_FCHDIR@\n_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/));\n\n/* Gnulib internal hooks needed to maintain the fchdir metadata.  */\n_GL_EXTERN_C int _gl_register_fd (int fd, const char *filename)\n     _GL_ARG_NONNULL ((2));\n_GL_EXTERN_C void _gl_unregister_fd (int fd);\n_GL_EXTERN_C int _gl_register_dup (int oldfd, int newfd);\n_GL_EXTERN_C const char *_gl_directory_name (int fd);\n\n# else\n#  if !@HAVE_DECL_FCHDIR@\n_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/));\n#  endif\n# endif\n_GL_CXXALIAS_SYS (fchdir, int, (int /*fd*/));\n_GL_CXXALIASWARN (fchdir);\n#elif defined GNULIB_POSIXCHECK\n# undef fchdir\n# if HAVE_RAW_DECL_FCHDIR\n_GL_WARN_ON_USE (fchdir, \"fchdir is unportable - \"\n                 \"use gnulib module fchdir for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_FCHOWNAT@\n# if @REPLACE_FCHOWNAT@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef fchownat\n#   define fchownat rpl_fchownat\n#  endif\n_GL_FUNCDECL_RPL (fchownat, int, (int fd, char const *file,\n                                  uid_t owner, gid_t group, int flag)\n                                 _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (fchownat, int, (int fd, char const *file,\n                                  uid_t owner, gid_t group, int flag));\n# else\n#  if !@HAVE_FCHOWNAT@\n_GL_FUNCDECL_SYS (fchownat, int, (int fd, char const *file,\n                                  uid_t owner, gid_t group, int flag)\n                                 _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (fchownat, int, (int fd, char const *file,\n                                  uid_t owner, gid_t group, int flag));\n# endif\n_GL_CXXALIASWARN (fchownat);\n#elif defined GNULIB_POSIXCHECK\n# undef fchownat\n# if HAVE_RAW_DECL_FCHOWNAT\n_GL_WARN_ON_USE (fchownat, \"fchownat is not portable - \"\n                 \"use gnulib module fchownat for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_FDATASYNC@\n/* Synchronize changes to a file.\n   Return 0 if successful, otherwise -1 and errno set.\n   See POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html>.  */\n# if !@HAVE_FDATASYNC@ || !@HAVE_DECL_FDATASYNC@\n_GL_FUNCDECL_SYS (fdatasync, int, (int fd));\n# endif\n_GL_CXXALIAS_SYS (fdatasync, int, (int fd));\n_GL_CXXALIASWARN (fdatasync);\n#elif defined GNULIB_POSIXCHECK\n# undef fdatasync\n# if HAVE_RAW_DECL_FDATASYNC\n_GL_WARN_ON_USE (fdatasync, \"fdatasync is unportable - \"\n                 \"use gnulib module fdatasync for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_FSYNC@\n/* Synchronize changes, including metadata, to a file.\n   Return 0 if successful, otherwise -1 and errno set.\n   See POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html>.  */\n# if !@HAVE_FSYNC@\n_GL_FUNCDECL_SYS (fsync, int, (int fd));\n# endif\n_GL_CXXALIAS_SYS (fsync, int, (int fd));\n_GL_CXXALIASWARN (fsync);\n#elif defined GNULIB_POSIXCHECK\n# undef fsync\n# if HAVE_RAW_DECL_FSYNC\n_GL_WARN_ON_USE (fsync, \"fsync is unportable - \"\n                 \"use gnulib module fsync for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_FTRUNCATE@\n/* Change the size of the file to which FD is opened to become equal to LENGTH.\n   Return 0 if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html>.  */\n# if @REPLACE_FTRUNCATE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef ftruncate\n#   define ftruncate rpl_ftruncate\n#  endif\n_GL_FUNCDECL_RPL (ftruncate, int, (int fd, off_t length));\n_GL_CXXALIAS_RPL (ftruncate, int, (int fd, off_t length));\n# else\n#  if !@HAVE_FTRUNCATE@\n_GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length));\n#  endif\n_GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length));\n# endif\n_GL_CXXALIASWARN (ftruncate);\n#elif defined GNULIB_POSIXCHECK\n# undef ftruncate\n# if HAVE_RAW_DECL_FTRUNCATE\n_GL_WARN_ON_USE (ftruncate, \"ftruncate is unportable - \"\n                 \"use gnulib module ftruncate for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_GETCWD@\n/* Get the name of the current working directory, and put it in SIZE bytes\n   of BUF.\n   Return BUF if successful, or NULL if the directory couldn't be determined\n   or SIZE was too small.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html>.\n   Additionally, the gnulib module 'getcwd' guarantees the following GNU\n   extension: If BUF is NULL, an array is allocated with 'malloc'; the array\n   is SIZE bytes long, unless SIZE == 0, in which case it is as big as\n   necessary.  */\n# if @REPLACE_GETCWD@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define getcwd rpl_getcwd\n#  endif\n_GL_FUNCDECL_RPL (getcwd, char *, (char *buf, size_t size));\n_GL_CXXALIAS_RPL (getcwd, char *, (char *buf, size_t size));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getcwd\n#   define getcwd _getcwd\n#  endif\n_GL_CXXALIAS_MDA (getcwd, char *, (char *buf, size_t size));\n# else\n/* Need to cast, because on mingw, the second parameter is\n                                                   int size.  */\n_GL_CXXALIAS_SYS_CAST (getcwd, char *, (char *buf, size_t size));\n# endif\n_GL_CXXALIASWARN (getcwd);\n#elif defined GNULIB_POSIXCHECK\n# undef getcwd\n# if HAVE_RAW_DECL_GETCWD\n_GL_WARN_ON_USE (getcwd, \"getcwd is unportable - \"\n                 \"use gnulib module getcwd for portability\");\n# endif\n#elif @GNULIB_MDA_GETCWD@\n/* On native Windows, map 'getcwd' to '_getcwd', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::getcwd always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getcwd\n#   define getcwd _getcwd\n#  endif\n/* Need to cast, because on mingw, the second parameter is either\n   'int size' or 'size_t size'.  */\n_GL_CXXALIAS_MDA_CAST (getcwd, char *, (char *buf, size_t size));\n# else\n_GL_CXXALIAS_SYS_CAST (getcwd, char *, (char *buf, size_t size));\n# endif\n_GL_CXXALIASWARN (getcwd);\n#endif\n\n\n#if @GNULIB_GETDOMAINNAME@\n/* Return the NIS domain name of the machine.\n   WARNING! The NIS domain name is unrelated to the fully qualified host name\n            of the machine.  It is also unrelated to email addresses.\n   WARNING! The NIS domain name is usually the empty string or \"(none)\" when\n            not using NIS.\n\n   Put up to LEN bytes of the NIS domain name into NAME.\n   Null terminate it if the name is shorter than LEN.\n   If the NIS domain name is longer than LEN, set errno = EINVAL and return -1.\n   Return 0 if successful, otherwise set errno and return -1.  */\n# if @REPLACE_GETDOMAINNAME@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getdomainname\n#   define getdomainname rpl_getdomainname\n#  endif\n_GL_FUNCDECL_RPL (getdomainname, int, (char *name, size_t len)\n                                      _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (getdomainname, int, (char *name, size_t len));\n# else\n#  if !@HAVE_DECL_GETDOMAINNAME@\n_GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len)\n                                      _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (getdomainname, int, (char *name, size_t len));\n# endif\n_GL_CXXALIASWARN (getdomainname);\n#elif defined GNULIB_POSIXCHECK\n# undef getdomainname\n# if HAVE_RAW_DECL_GETDOMAINNAME\n_GL_WARN_ON_USE (getdomainname, \"getdomainname is unportable - \"\n                 \"use gnulib module getdomainname for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_GETDTABLESIZE@\n/* Return the maximum number of file descriptors in the current process.\n   In POSIX, this is same as sysconf (_SC_OPEN_MAX).  */\n# if @REPLACE_GETDTABLESIZE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getdtablesize\n#   define getdtablesize rpl_getdtablesize\n#  endif\n_GL_FUNCDECL_RPL (getdtablesize, int, (void));\n_GL_CXXALIAS_RPL (getdtablesize, int, (void));\n# else\n#  if !@HAVE_GETDTABLESIZE@\n_GL_FUNCDECL_SYS (getdtablesize, int, (void));\n#  endif\n/* Need to cast, because on AIX, the parameter list is\n                                           (...).  */\n_GL_CXXALIAS_SYS_CAST (getdtablesize, int, (void));\n# endif\n_GL_CXXALIASWARN (getdtablesize);\n#elif defined GNULIB_POSIXCHECK\n# undef getdtablesize\n# if HAVE_RAW_DECL_GETDTABLESIZE\n_GL_WARN_ON_USE (getdtablesize, \"getdtablesize is unportable - \"\n                 \"use gnulib module getdtablesize for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_GETENTROPY@\n/* Fill a buffer with random bytes.  */\n# if !@HAVE_GETENTROPY@\n_GL_FUNCDECL_SYS (getentropy, int, (void *buffer, size_t length));\n# endif\n_GL_CXXALIAS_SYS (getentropy, int, (void *buffer, size_t length));\n_GL_CXXALIASWARN (getentropy);\n#elif defined GNULIB_POSIXCHECK\n# undef getentropy\n# if HAVE_RAW_DECL_GETENTROPY\n_GL_WARN_ON_USE (getentropy, \"getentropy is unportable - \"\n                 \"use gnulib module getentropy for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_GETGROUPS@\n/* Return the supplemental groups that the current process belongs to.\n   It is unspecified whether the effective group id is in the list.\n   If N is 0, return the group count; otherwise, N describes how many\n   entries are available in GROUPS.  Return -1 and set errno if N is\n   not 0 and not large enough.  Fails with ENOSYS on some systems.  */\n# if @REPLACE_GETGROUPS@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getgroups\n#   define getgroups rpl_getgroups\n#  endif\n_GL_FUNCDECL_RPL (getgroups, int, (int n, gid_t *groups));\n_GL_CXXALIAS_RPL (getgroups, int, (int n, gid_t *groups));\n# else\n#  if !@HAVE_GETGROUPS@\n_GL_FUNCDECL_SYS (getgroups, int, (int n, gid_t *groups));\n#  endif\n_GL_CXXALIAS_SYS (getgroups, int, (int n, gid_t *groups));\n# endif\n_GL_CXXALIASWARN (getgroups);\n#elif defined GNULIB_POSIXCHECK\n# undef getgroups\n# if HAVE_RAW_DECL_GETGROUPS\n_GL_WARN_ON_USE (getgroups, \"getgroups is unportable - \"\n                 \"use gnulib module getgroups for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_GETHOSTNAME@\n/* Return the standard host name of the machine.\n   WARNING! The host name may or may not be fully qualified.\n\n   Put up to LEN bytes of the host name into NAME.\n   Null terminate it if the name is shorter than LEN.\n   If the host name is longer than LEN, set errno = EINVAL and return -1.\n   Return 0 if successful, otherwise set errno and return -1.  */\n# if @UNISTD_H_HAVE_WINSOCK2_H@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef gethostname\n#   define gethostname rpl_gethostname\n#  endif\n_GL_FUNCDECL_RPL (gethostname, int, (char *name, size_t len)\n                                    _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len));\n# else\n#  if !@HAVE_GETHOSTNAME@\n_GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len)\n                                    _GL_ARG_NONNULL ((1)));\n#  endif\n/* Need to cast, because on Solaris 10 and OSF/1 5.1 systems, the second\n   parameter is\n                                                      int len.  */\n_GL_CXXALIAS_SYS_CAST (gethostname, int, (char *name, size_t len));\n# endif\n_GL_CXXALIASWARN (gethostname);\n#elif @UNISTD_H_HAVE_WINSOCK2_H@\n# undef gethostname\n# define gethostname gethostname_used_without_requesting_gnulib_module_gethostname\n#elif defined GNULIB_POSIXCHECK\n# undef gethostname\n# if HAVE_RAW_DECL_GETHOSTNAME\n_GL_WARN_ON_USE (gethostname, \"gethostname is unportable - \"\n                 \"use gnulib module gethostname for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_GETLOGIN@\n/* Returns the user's login name, or NULL if it cannot be found.  Upon error,\n   returns NULL with errno set.\n\n   See <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getlogin.html>.\n\n   Most programs don't need to use this function, because the information is\n   available through environment variables:\n     ${LOGNAME-$USER}        on Unix platforms,\n     $USERNAME               on native Windows platforms.\n */\n# if !@HAVE_DECL_GETLOGIN@\n_GL_FUNCDECL_SYS (getlogin, char *, (void));\n# endif\n_GL_CXXALIAS_SYS (getlogin, char *, (void));\n_GL_CXXALIASWARN (getlogin);\n#elif defined GNULIB_POSIXCHECK\n# undef getlogin\n# if HAVE_RAW_DECL_GETLOGIN\n_GL_WARN_ON_USE (getlogin, \"getlogin is unportable - \"\n                 \"use gnulib module getlogin for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_GETLOGIN_R@\n/* Copies the user's login name to NAME.\n   The array pointed to by NAME has room for SIZE bytes.\n\n   Returns 0 if successful.  Upon error, an error number is returned, or -1 in\n   the case that the login name cannot be found but no specific error is\n   provided (this case is hopefully rare but is left open by the POSIX spec).\n\n   See <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getlogin.html>.\n\n   Most programs don't need to use this function, because the information is\n   available through environment variables:\n     ${LOGNAME-$USER}        on Unix platforms,\n     $USERNAME               on native Windows platforms.\n */\n# if @REPLACE_GETLOGIN_R@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define getlogin_r rpl_getlogin_r\n#  endif\n_GL_FUNCDECL_RPL (getlogin_r, int, (char *name, size_t size)\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (getlogin_r, int, (char *name, size_t size));\n# else\n#  if !@HAVE_DECL_GETLOGIN_R@\n_GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size)\n                                   _GL_ARG_NONNULL ((1)));\n#  endif\n/* Need to cast, because on Solaris 10 systems, the second argument is\n                                                     int size.  */\n_GL_CXXALIAS_SYS_CAST (getlogin_r, int, (char *name, size_t size));\n# endif\n_GL_CXXALIASWARN (getlogin_r);\n#elif defined GNULIB_POSIXCHECK\n# undef getlogin_r\n# if HAVE_RAW_DECL_GETLOGIN_R\n_GL_WARN_ON_USE (getlogin_r, \"getlogin_r is unportable - \"\n                 \"use gnulib module getlogin_r for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_GETPAGESIZE@\n# if @REPLACE_GETPAGESIZE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define getpagesize rpl_getpagesize\n#  endif\n_GL_FUNCDECL_RPL (getpagesize, int, (void));\n_GL_CXXALIAS_RPL (getpagesize, int, (void));\n# else\n/* On HP-UX, getpagesize exists, but it is not declared in <unistd.h> even if\n   the compiler options -D_HPUX_SOURCE -D_XOPEN_SOURCE=600 are used.  */\n#  if defined __hpux\n_GL_FUNCDECL_SYS (getpagesize, int, (void));\n#  endif\n#  if !@HAVE_GETPAGESIZE@\n#   if !defined getpagesize\n/* This is for POSIX systems.  */\n#    if !defined _gl_getpagesize && defined _SC_PAGESIZE\n#     if ! (defined __VMS && __VMS_VER < 70000000)\n#      define _gl_getpagesize() sysconf (_SC_PAGESIZE)\n#     endif\n#    endif\n/* This is for older VMS.  */\n#    if !defined _gl_getpagesize && defined __VMS\n#     ifdef __ALPHA\n#      define _gl_getpagesize() 8192\n#     else\n#      define _gl_getpagesize() 512\n#     endif\n#    endif\n/* This is for BeOS.  */\n#    if !defined _gl_getpagesize && @HAVE_OS_H@\n#     include <OS.h>\n#     if defined B_PAGE_SIZE\n#      define _gl_getpagesize() B_PAGE_SIZE\n#     endif\n#    endif\n/* This is for AmigaOS4.0.  */\n#    if !defined _gl_getpagesize && defined __amigaos4__\n#     define _gl_getpagesize() 2048\n#    endif\n/* This is for older Unix systems.  */\n#    if !defined _gl_getpagesize && @HAVE_SYS_PARAM_H@\n#     include <sys/param.h>\n#     ifdef EXEC_PAGESIZE\n#      define _gl_getpagesize() EXEC_PAGESIZE\n#     else\n#      ifdef NBPG\n#       ifndef CLSIZE\n#        define CLSIZE 1\n#       endif\n#       define _gl_getpagesize() (NBPG * CLSIZE)\n#      else\n#       ifdef NBPC\n#        define _gl_getpagesize() NBPC\n#       endif\n#      endif\n#     endif\n#    endif\n#    if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#     define getpagesize() _gl_getpagesize ()\n#    else\n#     if !GNULIB_defined_getpagesize_function\n_GL_UNISTD_INLINE int\ngetpagesize ()\n{\n  return _gl_getpagesize ();\n}\n#      define GNULIB_defined_getpagesize_function 1\n#     endif\n#    endif\n#   endif\n#  endif\n/* Need to cast, because on Cygwin 1.5.x systems, the return type is size_t.  */\n_GL_CXXALIAS_SYS_CAST (getpagesize, int, (void));\n# endif\n# if @HAVE_DECL_GETPAGESIZE@\n_GL_CXXALIASWARN (getpagesize);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef getpagesize\n# if HAVE_RAW_DECL_GETPAGESIZE\n_GL_WARN_ON_USE (getpagesize, \"getpagesize is unportable - \"\n                 \"use gnulib module getpagesize for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_GETPASS@\n/* Function getpass() from module 'getpass':\n     Read a password from /dev/tty or stdin.\n   Function getpass() from module 'getpass-gnu':\n     Read a password of arbitrary length from /dev/tty or stdin.  */\n# if @REPLACE_GETPASS@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getpass\n#   define getpass rpl_getpass\n#  endif\n_GL_FUNCDECL_RPL (getpass, char *, (const char *prompt)\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (getpass, char *, (const char *prompt));\n# else\n#  if !@HAVE_GETPASS@\n_GL_FUNCDECL_SYS (getpass, char *, (const char *prompt)\n                                   _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (getpass, char *, (const char *prompt));\n# endif\n_GL_CXXALIASWARN (getpass);\n#elif defined GNULIB_POSIXCHECK\n# undef getpass\n# if HAVE_RAW_DECL_GETPASS\n_GL_WARN_ON_USE (getpass, \"getpass is unportable - \"\n                 \"use gnulib module getpass or getpass-gnu for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_MDA_GETPID@\n/* On native Windows, map 'getpid' to '_getpid', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::getpid always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getpid\n#   define getpid _getpid\n#  endif\n_GL_CXXALIAS_MDA (getpid, int, (void));\n# else\n_GL_CXXALIAS_SYS (getpid, pid_t, (void));\n# endif\n_GL_CXXALIASWARN (getpid);\n#endif\n\n\n#if @GNULIB_GETUSERSHELL@\n/* Return the next valid login shell on the system, or NULL when the end of\n   the list has been reached.  */\n# if !@HAVE_DECL_GETUSERSHELL@\n_GL_FUNCDECL_SYS (getusershell, char *, (void));\n# endif\n_GL_CXXALIAS_SYS (getusershell, char *, (void));\n_GL_CXXALIASWARN (getusershell);\n#elif defined GNULIB_POSIXCHECK\n# undef getusershell\n# if HAVE_RAW_DECL_GETUSERSHELL\n_GL_WARN_ON_USE (getusershell, \"getusershell is unportable - \"\n                 \"use gnulib module getusershell for portability\");\n# endif\n#endif\n\n#if @GNULIB_GETUSERSHELL@\n/* Rewind to pointer that is advanced at each getusershell() call.  */\n# if !@HAVE_DECL_GETUSERSHELL@\n_GL_FUNCDECL_SYS (setusershell, void, (void));\n# endif\n_GL_CXXALIAS_SYS (setusershell, void, (void));\n_GL_CXXALIASWARN (setusershell);\n#elif defined GNULIB_POSIXCHECK\n# undef setusershell\n# if HAVE_RAW_DECL_SETUSERSHELL\n_GL_WARN_ON_USE (setusershell, \"setusershell is unportable - \"\n                 \"use gnulib module getusershell for portability\");\n# endif\n#endif\n\n#if @GNULIB_GETUSERSHELL@\n/* Free the pointer that is advanced at each getusershell() call and\n   associated resources.  */\n# if !@HAVE_DECL_GETUSERSHELL@\n_GL_FUNCDECL_SYS (endusershell, void, (void));\n# endif\n_GL_CXXALIAS_SYS (endusershell, void, (void));\n_GL_CXXALIASWARN (endusershell);\n#elif defined GNULIB_POSIXCHECK\n# undef endusershell\n# if HAVE_RAW_DECL_ENDUSERSHELL\n_GL_WARN_ON_USE (endusershell, \"endusershell is unportable - \"\n                 \"use gnulib module getusershell for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_GROUP_MEMBER@\n/* Determine whether group id is in calling user's group list.  */\n# if !@HAVE_GROUP_MEMBER@\n_GL_FUNCDECL_SYS (group_member, int, (gid_t gid));\n# endif\n_GL_CXXALIAS_SYS (group_member, int, (gid_t gid));\n_GL_CXXALIASWARN (group_member);\n#elif defined GNULIB_POSIXCHECK\n# undef group_member\n# if HAVE_RAW_DECL_GROUP_MEMBER\n_GL_WARN_ON_USE (group_member, \"group_member is unportable - \"\n                 \"use gnulib module group-member for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_ISATTY@\n# if @REPLACE_ISATTY@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef isatty\n#   define isatty rpl_isatty\n#  endif\n#  define GNULIB_defined_isatty 1\n_GL_FUNCDECL_RPL (isatty, int, (int fd));\n_GL_CXXALIAS_RPL (isatty, int, (int fd));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef isatty\n#   define isatty _isatty\n#  endif\n_GL_CXXALIAS_MDA (isatty, int, (int fd));\n# else\n_GL_CXXALIAS_SYS (isatty, int, (int fd));\n# endif\n_GL_CXXALIASWARN (isatty);\n#elif defined GNULIB_POSIXCHECK\n# undef isatty\n# if HAVE_RAW_DECL_ISATTY\n_GL_WARN_ON_USE (isatty, \"isatty has portability problems on native Windows - \"\n                 \"use gnulib module isatty for portability\");\n# endif\n#elif @GNULIB_MDA_ISATTY@\n/* On native Windows, map 'isatty' to '_isatty', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::isatty always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef isatty\n#   define isatty _isatty\n#  endif\n_GL_CXXALIAS_MDA (isatty, int, (int fd));\n# else\n_GL_CXXALIAS_SYS (isatty, int, (int fd));\n# endif\n_GL_CXXALIASWARN (isatty);\n#endif\n\n\n#if @GNULIB_LCHOWN@\n/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE\n   to GID (if GID is not -1).  Do not follow symbolic links.\n   Return 0 if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/lchown.html>.  */\n# if @REPLACE_LCHOWN@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef lchown\n#   define lchown rpl_lchown\n#  endif\n_GL_FUNCDECL_RPL (lchown, int, (char const *file, uid_t owner, gid_t group)\n                               _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (lchown, int, (char const *file, uid_t owner, gid_t group));\n# else\n#  if !@HAVE_LCHOWN@\n_GL_FUNCDECL_SYS (lchown, int, (char const *file, uid_t owner, gid_t group)\n                               _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (lchown, int, (char const *file, uid_t owner, gid_t group));\n# endif\n_GL_CXXALIASWARN (lchown);\n#elif defined GNULIB_POSIXCHECK\n# undef lchown\n# if HAVE_RAW_DECL_LCHOWN\n_GL_WARN_ON_USE (lchown, \"lchown is unportable to pre-POSIX.1-2001 systems - \"\n                 \"use gnulib module lchown for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_LINK@\n/* Create a new hard link for an existing file.\n   Return 0 if successful, otherwise -1 and errno set.\n   See POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html>.  */\n# if @REPLACE_LINK@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define link rpl_link\n#  endif\n_GL_FUNCDECL_RPL (link, int, (const char *path1, const char *path2)\n                             _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (link, int, (const char *path1, const char *path2));\n# else\n#  if !@HAVE_LINK@\n_GL_FUNCDECL_SYS (link, int, (const char *path1, const char *path2)\n                             _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (link, int, (const char *path1, const char *path2));\n# endif\n_GL_CXXALIASWARN (link);\n#elif defined GNULIB_POSIXCHECK\n# undef link\n# if HAVE_RAW_DECL_LINK\n_GL_WARN_ON_USE (link, \"link is unportable - \"\n                 \"use gnulib module link for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_LINKAT@\n/* Create a new hard link for an existing file, relative to two\n   directories.  FLAG controls whether symlinks are followed.\n   Return 0 if successful, otherwise -1 and errno set.  */\n# if @REPLACE_LINKAT@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef linkat\n#   define linkat rpl_linkat\n#  endif\n_GL_FUNCDECL_RPL (linkat, int,\n                  (int fd1, const char *path1, int fd2, const char *path2,\n                   int flag)\n                  _GL_ARG_NONNULL ((2, 4)));\n_GL_CXXALIAS_RPL (linkat, int,\n                  (int fd1, const char *path1, int fd2, const char *path2,\n                   int flag));\n# else\n#  if !@HAVE_LINKAT@\n_GL_FUNCDECL_SYS (linkat, int,\n                  (int fd1, const char *path1, int fd2, const char *path2,\n                   int flag)\n                  _GL_ARG_NONNULL ((2, 4)));\n#  endif\n_GL_CXXALIAS_SYS (linkat, int,\n                  (int fd1, const char *path1, int fd2, const char *path2,\n                   int flag));\n# endif\n_GL_CXXALIASWARN (linkat);\n#elif defined GNULIB_POSIXCHECK\n# undef linkat\n# if HAVE_RAW_DECL_LINKAT\n_GL_WARN_ON_USE (linkat, \"linkat is unportable - \"\n                 \"use gnulib module linkat for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_LSEEK@\n/* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END.\n   Return the new offset if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html>.  */\n# if @REPLACE_LSEEK@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define lseek rpl_lseek\n#  endif\n_GL_FUNCDECL_RPL (lseek, off_t, (int fd, off_t offset, int whence));\n_GL_CXXALIAS_RPL (lseek, off_t, (int fd, off_t offset, int whence));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef lseek\n#   define lseek _lseek\n#  endif\n_GL_CXXALIAS_MDA (lseek, off_t, (int fd, off_t offset, int whence));\n# else\n_GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence));\n# endif\n_GL_CXXALIASWARN (lseek);\n#elif defined GNULIB_POSIXCHECK\n# undef lseek\n# if HAVE_RAW_DECL_LSEEK\n_GL_WARN_ON_USE (lseek, \"lseek does not fail with ESPIPE on pipes on some \"\n                 \"systems - use gnulib module lseek for portability\");\n# endif\n#elif @GNULIB_MDA_LSEEK@\n/* On native Windows, map 'lseek' to '_lseek', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::lseek always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef lseek\n#   define lseek _lseek\n#  endif\n_GL_CXXALIAS_MDA (lseek, long, (int fd, long offset, int whence));\n# else\n_GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence));\n# endif\n_GL_CXXALIASWARN (lseek);\n#endif\n\n\n#if @GNULIB_PIPE@\n/* Create a pipe, defaulting to O_BINARY mode.\n   Store the read-end as fd[0] and the write-end as fd[1].\n   Return 0 upon success, or -1 with errno set upon failure.  */\n# if !@HAVE_PIPE@\n_GL_FUNCDECL_SYS (pipe, int, (int fd[2]) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (pipe, int, (int fd[2]));\n_GL_CXXALIASWARN (pipe);\n#elif defined GNULIB_POSIXCHECK\n# undef pipe\n# if HAVE_RAW_DECL_PIPE\n_GL_WARN_ON_USE (pipe, \"pipe is unportable - \"\n                 \"use gnulib module pipe-posix for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_PIPE2@\n/* Create a pipe, applying the given flags when opening the read-end of the\n   pipe and the write-end of the pipe.\n   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)\n   and O_TEXT, O_BINARY (defined in \"binary-io.h\").\n   Store the read-end as fd[0] and the write-end as fd[1].\n   Return 0 upon success, or -1 with errno set upon failure.\n   See also the Linux man page at\n   <https://www.kernel.org/doc/man-pages/online/pages/man2/pipe2.2.html>.  */\n# if @HAVE_PIPE2@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define pipe2 rpl_pipe2\n#  endif\n_GL_FUNCDECL_RPL (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (pipe2, int, (int fd[2], int flags));\n# else\n_GL_FUNCDECL_SYS (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_SYS (pipe2, int, (int fd[2], int flags));\n# endif\n_GL_CXXALIASWARN (pipe2);\n#elif defined GNULIB_POSIXCHECK\n# undef pipe2\n# if HAVE_RAW_DECL_PIPE2\n_GL_WARN_ON_USE (pipe2, \"pipe2 is unportable - \"\n                 \"use gnulib module pipe2 for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_PREAD@\n/* Read at most BUFSIZE bytes from FD into BUF, starting at OFFSET.\n   Return the number of bytes placed into BUF if successful, otherwise\n   set errno and return -1.  0 indicates EOF.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html>.  */\n# if @REPLACE_PREAD@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef pread\n#   define pread rpl_pread\n#  endif\n_GL_FUNCDECL_RPL (pread, ssize_t,\n                  (int fd, void *buf, size_t bufsize, off_t offset)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (pread, ssize_t,\n                  (int fd, void *buf, size_t bufsize, off_t offset));\n# else\n#  if !@HAVE_PREAD@\n_GL_FUNCDECL_SYS (pread, ssize_t,\n                  (int fd, void *buf, size_t bufsize, off_t offset)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (pread, ssize_t,\n                  (int fd, void *buf, size_t bufsize, off_t offset));\n# endif\n_GL_CXXALIASWARN (pread);\n#elif defined GNULIB_POSIXCHECK\n# undef pread\n# if HAVE_RAW_DECL_PREAD\n_GL_WARN_ON_USE (pread, \"pread is unportable - \"\n                 \"use gnulib module pread for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_PWRITE@\n/* Write at most BUFSIZE bytes from BUF into FD, starting at OFFSET.\n   Return the number of bytes written if successful, otherwise\n   set errno and return -1.  0 indicates nothing written.  See the\n   POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html>.  */\n# if @REPLACE_PWRITE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef pwrite\n#   define pwrite rpl_pwrite\n#  endif\n_GL_FUNCDECL_RPL (pwrite, ssize_t,\n                  (int fd, const void *buf, size_t bufsize, off_t offset)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (pwrite, ssize_t,\n                  (int fd, const void *buf, size_t bufsize, off_t offset));\n# else\n#  if !@HAVE_PWRITE@\n_GL_FUNCDECL_SYS (pwrite, ssize_t,\n                  (int fd, const void *buf, size_t bufsize, off_t offset)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (pwrite, ssize_t,\n                  (int fd, const void *buf, size_t bufsize, off_t offset));\n# endif\n_GL_CXXALIASWARN (pwrite);\n#elif defined GNULIB_POSIXCHECK\n# undef pwrite\n# if HAVE_RAW_DECL_PWRITE\n_GL_WARN_ON_USE (pwrite, \"pwrite is unportable - \"\n                 \"use gnulib module pwrite for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_READ@\n/* Read up to COUNT bytes from file descriptor FD into the buffer starting\n   at BUF.  See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html>.  */\n# if @REPLACE_READ@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef read\n#   define read rpl_read\n#  endif\n_GL_FUNCDECL_RPL (read, ssize_t, (int fd, void *buf, size_t count)\n                                 _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (read, ssize_t, (int fd, void *buf, size_t count));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef read\n#   define read _read\n#  endif\n_GL_CXXALIAS_MDA (read, ssize_t, (int fd, void *buf, size_t count));\n# else\n_GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count));\n# endif\n_GL_CXXALIASWARN (read);\n#elif @GNULIB_MDA_READ@\n/* On native Windows, map 'read' to '_read', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::read always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef read\n#   define read _read\n#  endif\n#  ifdef __MINGW32__\n_GL_CXXALIAS_MDA (read, int, (int fd, void *buf, unsigned int count));\n#  else\n_GL_CXXALIAS_MDA (read, ssize_t, (int fd, void *buf, unsigned int count));\n#  endif\n# else\n_GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count));\n# endif\n_GL_CXXALIASWARN (read);\n#endif\n\n\n#if @GNULIB_READLINK@\n/* Read the contents of the symbolic link FILE and place the first BUFSIZE\n   bytes of it into BUF.  Return the number of bytes placed into BUF if\n   successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>.  */\n# if @REPLACE_READLINK@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define readlink rpl_readlink\n#  endif\n_GL_FUNCDECL_RPL (readlink, ssize_t,\n                  (const char *restrict file,\n                   char *restrict buf, size_t bufsize)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (readlink, ssize_t,\n                  (const char *restrict file,\n                   char *restrict buf, size_t bufsize));\n# else\n#  if !@HAVE_READLINK@\n_GL_FUNCDECL_SYS (readlink, ssize_t,\n                  (const char *restrict file,\n                   char *restrict buf, size_t bufsize)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (readlink, ssize_t,\n                  (const char *restrict file,\n                   char *restrict buf, size_t bufsize));\n# endif\n_GL_CXXALIASWARN (readlink);\n#elif defined GNULIB_POSIXCHECK\n# undef readlink\n# if HAVE_RAW_DECL_READLINK\n_GL_WARN_ON_USE (readlink, \"readlink is unportable - \"\n                 \"use gnulib module readlink for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_READLINKAT@\n# if @REPLACE_READLINKAT@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define readlinkat rpl_readlinkat\n#  endif\n_GL_FUNCDECL_RPL (readlinkat, ssize_t,\n                  (int fd, char const *restrict file,\n                   char *restrict buf, size_t len)\n                  _GL_ARG_NONNULL ((2, 3)));\n_GL_CXXALIAS_RPL (readlinkat, ssize_t,\n                  (int fd, char const *restrict file,\n                   char *restrict buf, size_t len));\n# else\n#  if !@HAVE_READLINKAT@\n_GL_FUNCDECL_SYS (readlinkat, ssize_t,\n                  (int fd, char const *restrict file,\n                   char *restrict buf, size_t len)\n                  _GL_ARG_NONNULL ((2, 3)));\n#  endif\n_GL_CXXALIAS_SYS (readlinkat, ssize_t,\n                  (int fd, char const *restrict file,\n                   char *restrict buf, size_t len));\n# endif\n_GL_CXXALIASWARN (readlinkat);\n#elif defined GNULIB_POSIXCHECK\n# undef readlinkat\n# if HAVE_RAW_DECL_READLINKAT\n_GL_WARN_ON_USE (readlinkat, \"readlinkat is not portable - \"\n                 \"use gnulib module readlinkat for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_RMDIR@\n/* Remove the directory DIR.  */\n# if @REPLACE_RMDIR@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define rmdir rpl_rmdir\n#  endif\n_GL_FUNCDECL_RPL (rmdir, int, (char const *name) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (rmdir, int, (char const *name));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef rmdir\n#   define rmdir _rmdir\n#  endif\n_GL_CXXALIAS_MDA (rmdir, int, (char const *name));\n# else\n_GL_CXXALIAS_SYS (rmdir, int, (char const *name));\n# endif\n_GL_CXXALIASWARN (rmdir);\n#elif defined GNULIB_POSIXCHECK\n# undef rmdir\n# if HAVE_RAW_DECL_RMDIR\n_GL_WARN_ON_USE (rmdir, \"rmdir is unportable - \"\n                 \"use gnulib module rmdir for portability\");\n# endif\n#elif @GNULIB_MDA_RMDIR@\n/* On native Windows, map 'rmdir' to '_rmdir', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::rmdir always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef rmdir\n#   define rmdir _rmdir\n#  endif\n_GL_CXXALIAS_MDA (rmdir, int, (char const *name));\n# else\n_GL_CXXALIAS_SYS (rmdir, int, (char const *name));\n# endif\n_GL_CXXALIASWARN (rmdir);\n#endif\n\n\n#if @GNULIB_SETHOSTNAME@\n/* Set the host name of the machine.\n   The host name may or may not be fully qualified.\n\n   Put LEN bytes of NAME into the host name.\n   Return 0 if successful, otherwise, set errno and return -1.\n\n   Platforms with no ability to set the hostname return -1 and set\n   errno = ENOSYS.  */\n# if !@HAVE_SETHOSTNAME@ || !@HAVE_DECL_SETHOSTNAME@\n_GL_FUNCDECL_SYS (sethostname, int, (const char *name, size_t len)\n                                    _GL_ARG_NONNULL ((1)));\n# endif\n/* Need to cast, because on Solaris 11 2011-10, Mac OS X 10.5, IRIX 6.5\n   and FreeBSD 6.4 the second parameter is int.  On Solaris 11\n   2011-10, the first parameter is not const.  */\n_GL_CXXALIAS_SYS_CAST (sethostname, int, (const char *name, size_t len));\n_GL_CXXALIASWARN (sethostname);\n#elif defined GNULIB_POSIXCHECK\n# undef sethostname\n# if HAVE_RAW_DECL_SETHOSTNAME\n_GL_WARN_ON_USE (sethostname, \"sethostname is unportable - \"\n                 \"use gnulib module sethostname for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_SLEEP@\n/* Pause the execution of the current thread for N seconds.\n   Returns the number of seconds left to sleep.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/sleep.html>.  */\n# if @REPLACE_SLEEP@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef sleep\n#   define sleep rpl_sleep\n#  endif\n_GL_FUNCDECL_RPL (sleep, unsigned int, (unsigned int n));\n_GL_CXXALIAS_RPL (sleep, unsigned int, (unsigned int n));\n# else\n#  if !@HAVE_SLEEP@\n_GL_FUNCDECL_SYS (sleep, unsigned int, (unsigned int n));\n#  endif\n_GL_CXXALIAS_SYS (sleep, unsigned int, (unsigned int n));\n# endif\n_GL_CXXALIASWARN (sleep);\n#elif defined GNULIB_POSIXCHECK\n# undef sleep\n# if HAVE_RAW_DECL_SLEEP\n_GL_WARN_ON_USE (sleep, \"sleep is unportable - \"\n                 \"use gnulib module sleep for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_MDA_SWAB@\n/* On native Windows, map 'swab' to '_swab', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::swab always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef swab\n#   define swab _swab\n#  endif\n/* Need to cast, because in old mingw the arguments are\n                             (const char *from, char *to, size_t n).  */\n_GL_CXXALIAS_MDA_CAST (swab, void, (char *from, char *to, int n));\n# else\n#  if defined __hpux /* HP-UX */\n_GL_CXXALIAS_SYS (swab, void, (const char *from, char *to, int n));\n#  elif defined __sun && !defined _XPG4 /* Solaris */\n_GL_CXXALIAS_SYS (swab, void, (const char *from, char *to, ssize_t n));\n#  else\n_GL_CXXALIAS_SYS (swab, void, (const void *from, void *to, ssize_t n));\n#  endif\n# endif\n_GL_CXXALIASWARN (swab);\n#endif\n\n\n#if @GNULIB_SYMLINK@\n# if @REPLACE_SYMLINK@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef symlink\n#   define symlink rpl_symlink\n#  endif\n_GL_FUNCDECL_RPL (symlink, int, (char const *contents, char const *file)\n                                _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (symlink, int, (char const *contents, char const *file));\n# else\n#  if !@HAVE_SYMLINK@\n_GL_FUNCDECL_SYS (symlink, int, (char const *contents, char const *file)\n                                _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (symlink, int, (char const *contents, char const *file));\n# endif\n_GL_CXXALIASWARN (symlink);\n#elif defined GNULIB_POSIXCHECK\n# undef symlink\n# if HAVE_RAW_DECL_SYMLINK\n_GL_WARN_ON_USE (symlink, \"symlink is not portable - \"\n                 \"use gnulib module symlink for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_SYMLINKAT@\n# if @REPLACE_SYMLINKAT@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef symlinkat\n#   define symlinkat rpl_symlinkat\n#  endif\n_GL_FUNCDECL_RPL (symlinkat, int,\n                  (char const *contents, int fd, char const *file)\n                  _GL_ARG_NONNULL ((1, 3)));\n_GL_CXXALIAS_RPL (symlinkat, int,\n                  (char const *contents, int fd, char const *file));\n# else\n#  if !@HAVE_SYMLINKAT@\n_GL_FUNCDECL_SYS (symlinkat, int,\n                  (char const *contents, int fd, char const *file)\n                  _GL_ARG_NONNULL ((1, 3)));\n#  endif\n_GL_CXXALIAS_SYS (symlinkat, int,\n                  (char const *contents, int fd, char const *file));\n# endif\n_GL_CXXALIASWARN (symlinkat);\n#elif defined GNULIB_POSIXCHECK\n# undef symlinkat\n# if HAVE_RAW_DECL_SYMLINKAT\n_GL_WARN_ON_USE (symlinkat, \"symlinkat is not portable - \"\n                 \"use gnulib module symlinkat for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_TRUNCATE@\n/* Change the size of the file designated by FILENAME to become equal to LENGTH.\n   Return 0 if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html>.  */\n# if @REPLACE_TRUNCATE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef truncate\n#   define truncate rpl_truncate\n#  endif\n_GL_FUNCDECL_RPL (truncate, int, (const char *filename, off_t length)\n                                 _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (truncate, int, (const char *filename, off_t length));\n# else\n#  if !@HAVE_DECL_TRUNCATE@\n_GL_FUNCDECL_SYS (truncate, int, (const char *filename, off_t length)\n                                 _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (truncate, int, (const char *filename, off_t length));\n# endif\n_GL_CXXALIASWARN (truncate);\n#elif defined GNULIB_POSIXCHECK\n# undef truncate\n# if HAVE_RAW_DECL_TRUNCATE\n_GL_WARN_ON_USE (truncate, \"truncate is unportable - \"\n                 \"use gnulib module truncate for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_TTYNAME_R@\n/* Store at most BUFLEN characters of the pathname of the terminal FD is\n   open on in BUF.  Return 0 on success, otherwise an error number.  */\n# if @REPLACE_TTYNAME_R@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef ttyname_r\n#   define ttyname_r rpl_ttyname_r\n#  endif\n_GL_FUNCDECL_RPL (ttyname_r, int,\n                  (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (ttyname_r, int,\n                  (int fd, char *buf, size_t buflen));\n# else\n#  if !@HAVE_DECL_TTYNAME_R@\n_GL_FUNCDECL_SYS (ttyname_r, int,\n                  (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (ttyname_r, int,\n                  (int fd, char *buf, size_t buflen));\n# endif\n_GL_CXXALIASWARN (ttyname_r);\n#elif defined GNULIB_POSIXCHECK\n# undef ttyname_r\n# if HAVE_RAW_DECL_TTYNAME_R\n_GL_WARN_ON_USE (ttyname_r, \"ttyname_r is not portable - \"\n                 \"use gnulib module ttyname_r for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_UNLINK@\n# if @REPLACE_UNLINK@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef unlink\n#   define unlink rpl_unlink\n#  endif\n_GL_FUNCDECL_RPL (unlink, int, (char const *file) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (unlink, int, (char const *file));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef unlink\n#   define unlink _unlink\n#  endif\n_GL_CXXALIAS_MDA (unlink, int, (char const *file));\n# else\n_GL_CXXALIAS_SYS (unlink, int, (char const *file));\n# endif\n_GL_CXXALIASWARN (unlink);\n#elif defined GNULIB_POSIXCHECK\n# undef unlink\n# if HAVE_RAW_DECL_UNLINK\n_GL_WARN_ON_USE (unlink, \"unlink is not portable - \"\n                 \"use gnulib module unlink for portability\");\n# endif\n#elif @GNULIB_MDA_UNLINK@\n/* On native Windows, map 'unlink' to '_unlink', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::unlink always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef unlink\n#   define unlink _unlink\n#  endif\n_GL_CXXALIAS_MDA (unlink, int, (char const *file));\n# else\n_GL_CXXALIAS_SYS (unlink, int, (char const *file));\n# endif\n_GL_CXXALIASWARN (unlink);\n#endif\n\n\n#if @GNULIB_UNLINKAT@\n# if @REPLACE_UNLINKAT@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef unlinkat\n#   define unlinkat rpl_unlinkat\n#  endif\n_GL_FUNCDECL_RPL (unlinkat, int, (int fd, char const *file, int flag)\n                                 _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (unlinkat, int, (int fd, char const *file, int flag));\n# else\n#  if !@HAVE_UNLINKAT@\n_GL_FUNCDECL_SYS (unlinkat, int, (int fd, char const *file, int flag)\n                                 _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (unlinkat, int, (int fd, char const *file, int flag));\n# endif\n_GL_CXXALIASWARN (unlinkat);\n#elif defined GNULIB_POSIXCHECK\n# undef unlinkat\n# if HAVE_RAW_DECL_UNLINKAT\n_GL_WARN_ON_USE (unlinkat, \"unlinkat is not portable - \"\n                 \"use gnulib module unlinkat for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_USLEEP@\n/* Pause the execution of the current thread for N microseconds.\n   Returns 0 on completion, or -1 on range error.\n   See the POSIX:2001 specification\n   <https://pubs.opengroup.org/onlinepubs/009695399/functions/usleep.html>.  */\n# if @REPLACE_USLEEP@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef usleep\n#   define usleep rpl_usleep\n#  endif\n_GL_FUNCDECL_RPL (usleep, int, (useconds_t n));\n_GL_CXXALIAS_RPL (usleep, int, (useconds_t n));\n# else\n#  if !@HAVE_USLEEP@\n_GL_FUNCDECL_SYS (usleep, int, (useconds_t n));\n#  endif\n/* Need to cast, because on Haiku, the first parameter is\n                                     unsigned int n.  */\n_GL_CXXALIAS_SYS_CAST (usleep, int, (useconds_t n));\n# endif\n_GL_CXXALIASWARN (usleep);\n#elif defined GNULIB_POSIXCHECK\n# undef usleep\n# if HAVE_RAW_DECL_USLEEP\n_GL_WARN_ON_USE (usleep, \"usleep is unportable - \"\n                 \"use gnulib module usleep for portability\");\n# endif\n#endif\n\n\n#if @GNULIB_WRITE@\n/* Write up to COUNT bytes starting at BUF to file descriptor FD.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html>.  */\n# if @REPLACE_WRITE@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef write\n#   define write rpl_write\n#  endif\n_GL_FUNCDECL_RPL (write, ssize_t, (int fd, const void *buf, size_t count)\n                                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void *buf, size_t count));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef write\n#   define write _write\n#  endif\n_GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, size_t count));\n# else\n_GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count));\n# endif\n_GL_CXXALIASWARN (write);\n#elif @GNULIB_MDA_WRITE@\n/* On native Windows, map 'write' to '_write', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::write always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef write\n#   define write _write\n#  endif\n#  ifdef __MINGW32__\n_GL_CXXALIAS_MDA (write, int, (int fd, const void *buf, unsigned int count));\n#  else\n_GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, unsigned int count));\n#  endif\n# else\n_GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count));\n# endif\n_GL_CXXALIASWARN (write);\n#endif\n\n_GL_INLINE_HEADER_END\n\n#endif /* _@GUARD_PREFIX@_UNISTD_H */\n#endif /* _GL_INCLUDING_UNISTD_H */\n#endif /* _@GUARD_PREFIX@_UNISTD_H */\n"
  },
  {
    "path": "gnulib/verify.h",
    "content": "/* Compile-time assert-like macros.\n\n   Copyright (C) 2005-2006, 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Paul Eggert, Bruno Haible, and Jim Meyering.  */\n\n#ifndef _GL_VERIFY_H\n#define _GL_VERIFY_H\n\n\n/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert (R, DIAGNOSTIC)\n   works as per C11.  This is supported by GCC 4.6.0+ and by clang 4+.\n\n   Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as\n   per C2X.  This is supported by GCC 9.1+.\n\n   Support compilers claiming conformance to the relevant standard,\n   and also support GCC when not pedantic.  If we were willing to slow\n   'configure' down we could also use it with other compilers, but\n   since this affects only the quality of diagnostics, why bother?  */\n#ifndef __cplusplus\n# if (201112L <= __STDC_VERSION__ \\\n      || (!defined __STRICT_ANSI__ \\\n          && (4 < __GNUC__ + (6 <= __GNUC_MINOR__) || 4 <= __clang_major__)))\n#  define _GL_HAVE__STATIC_ASSERT 1\n# endif\n# if (202000L <= __STDC_VERSION__ \\\n      || (!defined __STRICT_ANSI__ && 9 <= __GNUC__))\n#  define _GL_HAVE__STATIC_ASSERT1 1\n# endif\n#endif\n\n/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other\n   system headers, defines a conflicting _Static_assert that is no\n   better than ours; override it.  */\n#ifndef _GL_HAVE__STATIC_ASSERT\n# include <stddef.h>\n# undef _Static_assert\n#endif\n\n/* Each of these macros verifies that its argument R is nonzero.  To\n   be portable, R should be an integer constant expression.  Unlike\n   assert (R), there is no run-time overhead.\n\n   If _Static_assert works, verify (R) uses it directly.  Similarly,\n   _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct\n   that is an operand of sizeof.\n\n   The code below uses several ideas for C++ compilers, and for C\n   compilers that do not support _Static_assert:\n\n   * The first step is ((R) ? 1 : -1).  Given an expression R, of\n     integral or boolean or floating-point type, this yields an\n     expression of integral type, whose value is later verified to be\n     constant and nonnegative.\n\n   * Next this expression W is wrapped in a type\n     struct _gl_verify_type {\n       unsigned int _gl_verify_error_if_negative: W;\n     }.\n     If W is negative, this yields a compile-time error.  No compiler can\n     deal with a bit-field of negative size.\n\n     One might think that an array size check would have the same\n     effect, that is, that the type struct { unsigned int dummy[W]; }\n     would work as well.  However, inside a function, some compilers\n     (such as C++ compilers and GNU C) allow local parameters and\n     variables inside array size expressions.  With these compilers,\n     an array size check would not properly diagnose this misuse of\n     the verify macro:\n\n       void function (int n) { verify (n < 0); }\n\n   * For the verify macro, the struct _gl_verify_type will need to\n     somehow be embedded into a declaration.  To be portable, this\n     declaration must declare an object, a constant, a function, or a\n     typedef name.  If the declared entity uses the type directly,\n     such as in\n\n       struct dummy {...};\n       typedef struct {...} dummy;\n       extern struct {...} *dummy;\n       extern void dummy (struct {...} *);\n       extern struct {...} *dummy (void);\n\n     two uses of the verify macro would yield colliding declarations\n     if the entity names are not disambiguated.  A workaround is to\n     attach the current line number to the entity name:\n\n       #define _GL_CONCAT0(x, y) x##y\n       #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)\n       extern struct {...} * _GL_CONCAT (dummy, __LINE__);\n\n     But this has the problem that two invocations of verify from\n     within the same macro would collide, since the __LINE__ value\n     would be the same for both invocations.  (The GCC __COUNTER__\n     macro solves this problem, but is not portable.)\n\n     A solution is to use the sizeof operator.  It yields a number,\n     getting rid of the identity of the type.  Declarations like\n\n       extern int dummy [sizeof (struct {...})];\n       extern void dummy (int [sizeof (struct {...})]);\n       extern int (*dummy (void)) [sizeof (struct {...})];\n\n     can be repeated.\n\n   * Should the implementation use a named struct or an unnamed struct?\n     Which of the following alternatives can be used?\n\n       extern int dummy [sizeof (struct {...})];\n       extern int dummy [sizeof (struct _gl_verify_type {...})];\n       extern void dummy (int [sizeof (struct {...})]);\n       extern void dummy (int [sizeof (struct _gl_verify_type {...})]);\n       extern int (*dummy (void)) [sizeof (struct {...})];\n       extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})];\n\n     In the second and sixth case, the struct type is exported to the\n     outer scope; two such declarations therefore collide.  GCC warns\n     about the first, third, and fourth cases.  So the only remaining\n     possibility is the fifth case:\n\n       extern int (*dummy (void)) [sizeof (struct {...})];\n\n   * GCC warns about duplicate declarations of the dummy function if\n     -Wredundant-decls is used.  GCC 4.3 and later have a builtin\n     __COUNTER__ macro that can let us generate unique identifiers for\n     each dummy function, to suppress this warning.\n\n   * This implementation exploits the fact that older versions of GCC,\n     which do not support _Static_assert, also do not warn about the\n     last declaration mentioned above.\n\n   * GCC warns if -Wnested-externs is enabled and 'verify' is used\n     within a function body; but inside a function, you can always\n     arrange to use verify_expr instead.\n\n   * In C++, any struct definition inside sizeof is invalid.\n     Use a template type to work around the problem.  */\n\n/* Concatenate two preprocessor tokens.  */\n#define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)\n#define _GL_CONCAT0(x, y) x##y\n\n/* _GL_COUNTER is an integer, preferably one that changes each time we\n   use it.  Use __COUNTER__ if it works, falling back on __LINE__\n   otherwise.  __LINE__ isn't perfect, but it's better than a\n   constant.  */\n#if defined __COUNTER__ && __COUNTER__ != __COUNTER__\n# define _GL_COUNTER __COUNTER__\n#else\n# define _GL_COUNTER __LINE__\n#endif\n\n/* Generate a symbol with the given prefix, making it unique if\n   possible.  */\n#define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)\n\n/* Verify requirement R at compile-time, as an integer constant expression\n   that returns 1.  If R is false, fail at compile-time, preferably\n   with a diagnostic that includes the string-literal DIAGNOSTIC.  */\n\n#define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \\\n   (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC)))\n\n#ifdef __cplusplus\n# if !GNULIB_defined_struct__gl_verify_type\ntemplate <int w>\n  struct _gl_verify_type {\n    unsigned int _gl_verify_error_if_negative: w;\n  };\n#  define GNULIB_defined_struct__gl_verify_type 1\n# endif\n# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \\\n    _gl_verify_type<(R) ? 1 : -1>\n#elif defined _GL_HAVE__STATIC_ASSERT\n# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \\\n    struct {                                   \\\n      _Static_assert (R, DIAGNOSTIC);          \\\n      int _gl_dummy;                          \\\n    }\n#else\n# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \\\n    struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }\n#endif\n\n/* Verify requirement R at compile-time, as a declaration without a\n   trailing ';'.  If R is false, fail at compile-time.\n\n   This macro requires three or more arguments but uses at most the first\n   two, so that the _Static_assert macro optionally defined below supports\n   both the C11 two-argument syntax and the C2X one-argument syntax.\n\n   Unfortunately, unlike C11, this implementation must appear as an\n   ordinary declaration, and cannot appear inside struct { ... }.  */\n\n#if 200410 <= __cpp_static_assert\n# define _GL_VERIFY(R, DIAGNOSTIC, ...) static_assert (R, DIAGNOSTIC)\n#elif defined _GL_HAVE__STATIC_ASSERT\n# define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC)\n#else\n# define _GL_VERIFY(R, DIAGNOSTIC, ...)                                \\\n    extern int (*_GL_GENSYM (_gl_verify_function) (void))\t       \\\n      [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]\n#endif\n\n/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h.  */\n#ifdef _GL_STATIC_ASSERT_H\n# if !defined _GL_HAVE__STATIC_ASSERT1 && !defined _Static_assert\n#  define _Static_assert(...) \\\n     _GL_VERIFY (__VA_ARGS__, \"static assertion failed\", -)\n# endif\n# if __cpp_static_assert < 201411 && !defined static_assert\n#  define static_assert _Static_assert /* C11 requires this #define.  */\n# endif\n#endif\n\n/* @assert.h omit start@  */\n\n#if 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))\n# define _GL_HAS_BUILTIN_TRAP 1\n#elif defined __has_builtin\n# define _GL_HAS_BUILTIN_TRAP __has_builtin (__builtin_trap)\n#else\n# define _GL_HAS_BUILTIN_TRAP 0\n#endif\n\n#if 4 < __GNUC__ + (5 <= __GNUC_MINOR__)\n# define _GL_HAS_BUILTIN_UNREACHABLE 1\n#elif defined __has_builtin\n# define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable)\n#else\n# define _GL_HAS_BUILTIN_UNREACHABLE 0\n#endif\n\n/* Each of these macros verifies that its argument R is nonzero.  To\n   be portable, R should be an integer constant expression.  Unlike\n   assert (R), there is no run-time overhead.\n\n   There are two macros, since no single macro can be used in all\n   contexts in C.  verify_expr (R, E) is for scalar contexts, including\n   integer constant expression contexts.  verify (R) is for declaration\n   contexts, e.g., the top level.  */\n\n/* Verify requirement R at compile-time.  Return the value of the\n   expression E.  */\n\n#define verify_expr(R, E) \\\n   (_GL_VERIFY_TRUE (R, \"verify_expr (\" #R \", \" #E \")\") ? (E) : (E))\n\n/* Verify requirement R at compile-time, as a declaration without a\n   trailing ';'.  verify (R) acts like static_assert (R) except that\n   it is portable to C11/C++14 and earlier, it can issue better\n   diagnostics, and its name is shorter and may be more convenient.  */\n\n#ifdef __PGI\n/* PGI barfs if R is long.  */\n# define verify(R) _GL_VERIFY (R, \"verify (...)\", -)\n#else\n# define verify(R) _GL_VERIFY (R, \"verify (\" #R \")\", -)\n#endif\n\n/* Assume that R always holds.  Behavior is undefined if R is false,\n   fails to evaluate, or has side effects.\n\n   'assume (R)' is a directive from the programmer telling the\n   compiler that R is true so the compiler needn't generate code to\n   test R.  This is why 'assume' is in verify.h: it's related to\n   static checking (in this case, static checking done by the\n   programmer), not dynamic checking.\n\n   'assume (R)' can affect compilation of all the code, not just code\n   that happens to be executed after the assume (R) is \"executed\".\n   For example, if the code mistakenly does 'assert (R); assume (R);'\n   the compiler is entitled to optimize away the 'assert (R)'.\n\n   Although assuming R can help a compiler generate better code or\n   diagnostics, performance can suffer if R uses hard-to-optimize\n   features such as function calls not inlined by the compiler.\n\n   Avoid Clang's __builtin_assume, as it breaks GNU Emacs master\n   as of 2020-08-23T21:09:49Z!eggert@cs.ucla.edu; see\n   <https://bugs.gnu.org/43152#71>.  It's not known whether this breakage\n   is a Clang bug or an Emacs bug; play it safe for now.  */\n\n#if _GL_HAS_BUILTIN_UNREACHABLE\n# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())\n#elif 1200 <= _MSC_VER\n# define assume(R) __assume (R)\n#elif (defined GCC_LINT || defined lint) && _GL_HAS_BUILTIN_TRAP\n  /* Doing it this way helps various packages when configured with\n     --enable-gcc-warnings, which compiles with -Dlint.  It's nicer\n     when 'assume' silences warnings even with older GCCs.  */\n# define assume(R) ((R) ? (void) 0 : __builtin_trap ())\n#else\n  /* Some tools grok NOTREACHED, e.g., Oracle Studio 12.6.  */\n# define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0)\n#endif\n\n/* @assert.h omit end@  */\n\n#endif\n"
  },
  {
    "path": "gnulib/warn-on-use.h",
    "content": "/* A C macro for emitting warnings if a function is used.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_WARN_ON_USE (function, \"literal string\") issues a declaration\n   for FUNCTION which will then trigger a compiler warning containing\n   the text of \"literal string\" anywhere that function is called, if\n   supported by the compiler.  If the compiler does not support this\n   feature, the macro expands to an unused extern declaration.\n\n   _GL_WARN_ON_USE_ATTRIBUTE (\"literal string\") expands to the\n   attribute used in _GL_WARN_ON_USE.  If the compiler does not support\n   this feature, it expands to empty.\n\n   These macros are useful for marking a function as a potential\n   portability trap, with the intent that \"literal string\" include\n   instructions on the replacement function that should be used\n   instead.\n   _GL_WARN_ON_USE is for functions with 'extern' linkage.\n   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'\n   linkage.\n\n   However, one of the reasons that a function is a portability trap is\n   if it has the wrong signature.  Declaring FUNCTION with a different\n   signature in C is a compilation error, so this macro must use the\n   same type as any existing declaration so that programs that avoid\n   the problematic FUNCTION do not fail to compile merely because they\n   included a header that poisoned the function.  But this implies that\n   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already\n   have a declaration.  Use of this macro implies that there must not\n   be any other macro hiding the declaration of FUNCTION; but\n   undefining FUNCTION first is part of the poisoning process anyway\n   (although for symbols that are provided only via a macro, the result\n   is a compilation error rather than a warning containing\n   \"literal string\").  Also note that in C++, it is only safe to use if\n   FUNCTION has no overloads.\n\n   For an example, it is possible to poison 'getline' by:\n   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],\n     [getline]) in configure.ac, which potentially defines\n     HAVE_RAW_DECL_GETLINE\n   - adding this code to a header that wraps the system <stdio.h>:\n     #undef getline\n     #if HAVE_RAW_DECL_GETLINE\n     _GL_WARN_ON_USE (getline, \"getline is required by POSIX 2008, but\"\n       \"not universally present; use the gnulib module getline\");\n     #endif\n\n   It is not possible to directly poison global variables.  But it is\n   possible to write a wrapper accessor function, and poison that\n   (less common usage, like &environ, will cause a compilation error\n   rather than issue the nice warning, but the end result of informing\n   the developer about their portability problem is still achieved):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     rpl_environ (void) { return &environ; }\n     _GL_WARN_ON_USE (rpl_environ, \"environ is not always properly declared\");\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   or better (avoiding contradictory use of 'static' and 'extern'):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     _GL_WARN_ON_USE_ATTRIBUTE (\"environ is not always properly declared\")\n     rpl_environ (void) { return &environ; }\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   */\n#ifndef _GL_WARN_ON_USE\n\n# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function __attribute__ ((__warning__ (message)))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__warning__ (message)))\n# elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# else /* Unsupported.  */\n#  define _GL_WARN_ON_USE(function, message) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# endif\n#endif\n\n/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, \"message\")\n   is like _GL_WARN_ON_USE (function, \"message\"), except that in C++ mode the\n   function is declared with the given prototype, consisting of return type,\n   parameters, and attributes.\n   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does\n   not work in this case.  */\n#ifndef _GL_WARN_ON_USE_CXX\n# if !defined __cplusplus\n#  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n     _GL_WARN_ON_USE (function, msg)\n# else\n#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes \\\n  __attribute__ ((__warning__ (msg)))\n#  elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_clang function parameters_and_attributes \\\n  __attribute__ ((__diagnose_if__ (1, msg, \"warning\")))\n#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes\n#  else /* Unsupported.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  endif\n# endif\n#endif\n\n/* _GL_WARN_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#ifndef _GL_WARN_EXTERN_C\n# if defined __cplusplus\n#  define _GL_WARN_EXTERN_C extern \"C\"\n# else\n#  define _GL_WARN_EXTERN_C extern\n# endif\n#endif\n"
  },
  {
    "path": "gnulib/wchar.in.h",
    "content": "/* A substitute for ISO C99 <wchar.h>, for platforms that have issues.\n\n   Copyright (C) 2007-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Eric Blake.  */\n\n/*\n * ISO C 99 <wchar.h> for platforms that have issues.\n * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/wchar.h.html>\n *\n * For now, this just ensures proper prerequisite inclusion order and\n * the declaration of wcwidth().\n */\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n#if (((defined __need_mbstate_t || defined __need_wint_t)               \\\n      && !defined __MINGW32__)                                          \\\n     || (defined __hpux                                                 \\\n         && ((defined _INTTYPES_INCLUDED                                \\\n              && !defined _GL_FINISHED_INCLUDING_SYSTEM_INTTYPES_H)     \\\n             || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H))               \\\n     || (defined __MINGW32__ && defined __STRING_H_SOURCED__)           \\\n     || defined _GL_ALREADY_INCLUDING_WCHAR_H)\n/* Special invocation convention:\n   - Inside glibc and uClibc header files, but not MinGW.\n   - On HP-UX 11.00 we have a sequence of nested includes\n     <wchar.h> -> <stdlib.h> -> <stdint.h>, and the latter includes <wchar.h>,\n     once indirectly <stdint.h> -> <sys/types.h> -> <inttypes.h> -> <wchar.h>\n     and once directly.  In both situations 'wint_t' is not yet defined,\n     therefore we cannot provide the function overrides; instead include only\n     the system's <wchar.h>.\n   - With MinGW 3.22, when <string.h> includes <wchar.h>, only some part of\n     <wchar.h> is actually processed, and that doesn't include 'mbstate_t'.\n   - On IRIX 6.5, similarly, we have an include <wchar.h> -> <wctype.h>, and\n     the latter includes <wchar.h>.  But here, we have no way to detect whether\n     <wctype.h> is completely included or is still being included.  */\n\n#@INCLUDE_NEXT@ @NEXT_WCHAR_H@\n\n#else\n/* Normal invocation convention.  */\n\n#ifndef _@GUARD_PREFIX@_WCHAR_H\n\n#define _GL_ALREADY_INCLUDING_WCHAR_H\n\n#if @HAVE_FEATURES_H@\n# include <features.h> /* for __GLIBC__ */\n#endif\n\n/* In some builds of uClibc, <wchar.h> is nonexistent and wchar_t is defined\n   by <stddef.h>.\n   But avoid namespace pollution on glibc systems.  */\n#if !(defined __GLIBC__ && !defined __UCLIBC__)\n# include <stddef.h>\n#endif\n\n/* Include the original <wchar.h> if it exists.\n   Some builds of uClibc lack it.  */\n/* The include_next requires a split double-inclusion guard.  */\n#if @HAVE_WCHAR_H@\n# @INCLUDE_NEXT@ @NEXT_WCHAR_H@\n#endif\n\n#undef _GL_ALREADY_INCLUDING_WCHAR_H\n\n#ifndef _@GUARD_PREFIX@_WCHAR_H\n#define _@GUARD_PREFIX@_WCHAR_H\n\n/* The __attribute__ feature is available in gcc versions 2.5 and later.\n   The attribute __pure__ was added in gcc 2.96.  */\n#ifndef _GL_ATTRIBUTE_PURE\n# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__\n#  define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))\n# else\n#  define _GL_ATTRIBUTE_PURE /* empty */\n# endif\n#endif\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n\n\n/* Define wint_t and WEOF.  (Also done in wctype.in.h.)  */\n#if !@HAVE_WINT_T@ && !defined wint_t\n# define wint_t int\n# ifndef WEOF\n#  define WEOF -1\n# endif\n#else\n/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h> or\n   <stddef.h>.  This is too small: ISO C 99 section 7.24.1.(2) says that\n   wint_t must be \"unchanged by default argument promotions\".  Override it.  */\n# if @GNULIBHEADERS_OVERRIDE_WINT_T@\n#  if !GNULIB_defined_wint_t\n#   if @HAVE_CRTDEFS_H@\n#    include <crtdefs.h>\n#   else\n#    include <stddef.h>\n#   endif\ntypedef unsigned int rpl_wint_t;\n#   undef wint_t\n#   define wint_t rpl_wint_t\n#   define GNULIB_defined_wint_t 1\n#  endif\n# endif\n# ifndef WEOF\n#  define WEOF ((wint_t) -1)\n# endif\n#endif\n\n\n/* Override mbstate_t if it is too small.\n   On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for\n   implementing mbrtowc for encodings like UTF-8.\n   On AIX and MSVC, mbrtowc needs to be overridden, but mbstate_t exists and is\n   large enough and overriding it would cause problems in C++ mode.  */\n#if !(((defined _WIN32 && !defined __CYGWIN__) || @HAVE_MBSINIT@) && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@\n# if !GNULIB_defined_mbstate_t\n#  if !(defined _AIX || defined _MSC_VER)\ntypedef int rpl_mbstate_t;\n#   undef mbstate_t\n#   define mbstate_t rpl_mbstate_t\n#  endif\n#  define GNULIB_defined_mbstate_t 1\n# endif\n#endif\n\n\n/* Convert a single-byte character to a wide character.  */\n#if @GNULIB_BTOWC@\n# if @REPLACE_BTOWC@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef btowc\n#   define btowc rpl_btowc\n#  endif\n_GL_FUNCDECL_RPL (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE);\n_GL_CXXALIAS_RPL (btowc, wint_t, (int c));\n# else\n#  if !@HAVE_BTOWC@\n_GL_FUNCDECL_SYS (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE);\n#  endif\n/* Need to cast, because on mingw, the return type is 'unsigned short'.  */\n_GL_CXXALIAS_SYS_CAST (btowc, wint_t, (int c));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (btowc);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef btowc\n# if HAVE_RAW_DECL_BTOWC\n_GL_WARN_ON_USE (btowc, \"btowc is unportable - \"\n                 \"use gnulib module btowc for portability\");\n# endif\n#endif\n\n\n/* Convert a wide character to a single-byte character.  */\n#if @GNULIB_WCTOB@\n# if @REPLACE_WCTOB@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wctob\n#   define wctob rpl_wctob\n#  endif\n_GL_FUNCDECL_RPL (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE);\n_GL_CXXALIAS_RPL (wctob, int, (wint_t wc));\n# else\n#  if !defined wctob && !@HAVE_DECL_WCTOB@\n/* wctob is provided by gnulib, or wctob exists but is not declared.  */\n_GL_FUNCDECL_SYS (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE);\n#  endif\n_GL_CXXALIAS_SYS (wctob, int, (wint_t wc));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wctob);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wctob\n# if HAVE_RAW_DECL_WCTOB\n_GL_WARN_ON_USE (wctob, \"wctob is unportable - \"\n                 \"use gnulib module wctob for portability\");\n# endif\n#endif\n\n\n/* Test whether *PS is in the initial state.  */\n#if @GNULIB_MBSINIT@\n# if @REPLACE_MBSINIT@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbsinit\n#   define mbsinit rpl_mbsinit\n#  endif\n_GL_FUNCDECL_RPL (mbsinit, int, (const mbstate_t *ps));\n_GL_CXXALIAS_RPL (mbsinit, int, (const mbstate_t *ps));\n# else\n#  if !@HAVE_MBSINIT@\n_GL_FUNCDECL_SYS (mbsinit, int, (const mbstate_t *ps));\n#  endif\n_GL_CXXALIAS_SYS (mbsinit, int, (const mbstate_t *ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (mbsinit);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef mbsinit\n# if HAVE_RAW_DECL_MBSINIT\n_GL_WARN_ON_USE (mbsinit, \"mbsinit is unportable - \"\n                 \"use gnulib module mbsinit for portability\");\n# endif\n#endif\n\n\n/* Convert a multibyte character to a wide character.  */\n#if @GNULIB_MBRTOWC@\n# if @REPLACE_MBRTOWC@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbrtowc\n#   define mbrtowc rpl_mbrtowc\n#  endif\n_GL_FUNCDECL_RPL (mbrtowc, size_t,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n,\n                   mbstate_t *restrict ps));\n_GL_CXXALIAS_RPL (mbrtowc, size_t,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n,\n                   mbstate_t *restrict ps));\n# else\n#  if !@HAVE_MBRTOWC@\n_GL_FUNCDECL_SYS (mbrtowc, size_t,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n,\n                   mbstate_t *restrict ps));\n#  endif\n_GL_CXXALIAS_SYS (mbrtowc, size_t,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n,\n                   mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (mbrtowc);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef mbrtowc\n# if HAVE_RAW_DECL_MBRTOWC\n_GL_WARN_ON_USE (mbrtowc, \"mbrtowc is unportable - \"\n                 \"use gnulib module mbrtowc for portability\");\n# endif\n#endif\n\n\n/* Recognize a multibyte character.  */\n#if @GNULIB_MBRLEN@\n# if @REPLACE_MBRLEN@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbrlen\n#   define mbrlen rpl_mbrlen\n#  endif\n_GL_FUNCDECL_RPL (mbrlen, size_t,\n                  (const char *restrict s, size_t n, mbstate_t *restrict ps));\n_GL_CXXALIAS_RPL (mbrlen, size_t,\n                  (const char *restrict s, size_t n, mbstate_t *restrict ps));\n# else\n#  if !@HAVE_MBRLEN@\n_GL_FUNCDECL_SYS (mbrlen, size_t,\n                  (const char *restrict s, size_t n, mbstate_t *restrict ps));\n#  endif\n_GL_CXXALIAS_SYS (mbrlen, size_t,\n                  (const char *restrict s, size_t n, mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (mbrlen);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef mbrlen\n# if HAVE_RAW_DECL_MBRLEN\n_GL_WARN_ON_USE (mbrlen, \"mbrlen is unportable - \"\n                 \"use gnulib module mbrlen for portability\");\n# endif\n#endif\n\n\n/* Convert a string to a wide string.  */\n#if @GNULIB_MBSRTOWCS@\n# if @REPLACE_MBSRTOWCS@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbsrtowcs\n#   define mbsrtowcs rpl_mbsrtowcs\n#  endif\n_GL_FUNCDECL_RPL (mbsrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (mbsrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t len,\n                   mbstate_t *restrict ps));\n# else\n#  if !@HAVE_MBSRTOWCS@\n_GL_FUNCDECL_SYS (mbsrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (mbsrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t len,\n                   mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (mbsrtowcs);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef mbsrtowcs\n# if HAVE_RAW_DECL_MBSRTOWCS\n_GL_WARN_ON_USE (mbsrtowcs, \"mbsrtowcs is unportable - \"\n                 \"use gnulib module mbsrtowcs for portability\");\n# endif\n#endif\n\n\n/* Convert a string to a wide string.  */\n#if @GNULIB_MBSNRTOWCS@\n# if @REPLACE_MBSNRTOWCS@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbsnrtowcs\n#   define mbsnrtowcs rpl_mbsnrtowcs\n#  endif\n_GL_FUNCDECL_RPL (mbsnrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t srclen, size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (mbsnrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t srclen, size_t len,\n                   mbstate_t *restrict ps));\n# else\n#  if !@HAVE_MBSNRTOWCS@\n_GL_FUNCDECL_SYS (mbsnrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t srclen, size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (mbsnrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t srclen, size_t len,\n                   mbstate_t *restrict ps));\n# endif\n_GL_CXXALIASWARN (mbsnrtowcs);\n#elif defined GNULIB_POSIXCHECK\n# undef mbsnrtowcs\n# if HAVE_RAW_DECL_MBSNRTOWCS\n_GL_WARN_ON_USE (mbsnrtowcs, \"mbsnrtowcs is unportable - \"\n                 \"use gnulib module mbsnrtowcs for portability\");\n# endif\n#endif\n\n\n/* Convert a wide character to a multibyte character.  */\n#if @GNULIB_WCRTOMB@\n# if @REPLACE_WCRTOMB@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcrtomb\n#   define wcrtomb rpl_wcrtomb\n#  endif\n_GL_FUNCDECL_RPL (wcrtomb, size_t,\n                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));\n_GL_CXXALIAS_RPL (wcrtomb, size_t,\n                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));\n# else\n#  if !@HAVE_WCRTOMB@\n_GL_FUNCDECL_SYS (wcrtomb, size_t,\n                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));\n#  endif\n_GL_CXXALIAS_SYS (wcrtomb, size_t,\n                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcrtomb);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcrtomb\n# if HAVE_RAW_DECL_WCRTOMB\n_GL_WARN_ON_USE (wcrtomb, \"wcrtomb is unportable - \"\n                 \"use gnulib module wcrtomb for portability\");\n# endif\n#endif\n\n\n/* Convert a wide string to a string.  */\n#if @GNULIB_WCSRTOMBS@\n# if @REPLACE_WCSRTOMBS@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcsrtombs\n#   define wcsrtombs rpl_wcsrtombs\n#  endif\n_GL_FUNCDECL_RPL (wcsrtombs, size_t,\n                  (char *restrict dest, const wchar_t **restrict srcp,\n                   size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (wcsrtombs, size_t,\n                  (char *restrict dest, const wchar_t **restrict srcp,\n                   size_t len,\n                   mbstate_t *restrict ps));\n# else\n#  if !@HAVE_WCSRTOMBS@\n_GL_FUNCDECL_SYS (wcsrtombs, size_t,\n                  (char *restrict dest, const wchar_t **restrict srcp,\n                   size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (wcsrtombs, size_t,\n                  (char *restrict dest, const wchar_t **restrict srcp,\n                   size_t len,\n                   mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsrtombs);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsrtombs\n# if HAVE_RAW_DECL_WCSRTOMBS\n_GL_WARN_ON_USE (wcsrtombs, \"wcsrtombs is unportable - \"\n                 \"use gnulib module wcsrtombs for portability\");\n# endif\n#endif\n\n\n/* Convert a wide string to a string.  */\n#if @GNULIB_WCSNRTOMBS@\n# if @REPLACE_WCSNRTOMBS@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcsnrtombs\n#   define wcsnrtombs rpl_wcsnrtombs\n#  endif\n_GL_FUNCDECL_RPL (wcsnrtombs, size_t,\n                  (char *restrict dest,\n                   const wchar_t **restrict srcp, size_t srclen,\n                   size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (wcsnrtombs, size_t,\n                  (char *restrict dest,\n                   const wchar_t **restrict srcp, size_t srclen,\n                   size_t len,\n                   mbstate_t *restrict ps));\n# else\n#  if !@HAVE_WCSNRTOMBS@ || (defined __cplusplus && defined __sun)\n_GL_FUNCDECL_SYS (wcsnrtombs, size_t,\n                  (char *restrict dest,\n                   const wchar_t **restrict srcp, size_t srclen,\n                   size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (wcsnrtombs, size_t,\n                  (char *restrict dest,\n                   const wchar_t **restrict srcp, size_t srclen,\n                   size_t len,\n                   mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsnrtombs);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsnrtombs\n# if HAVE_RAW_DECL_WCSNRTOMBS\n_GL_WARN_ON_USE (wcsnrtombs, \"wcsnrtombs is unportable - \"\n                 \"use gnulib module wcsnrtombs for portability\");\n# endif\n#endif\n\n\n/* Return the number of screen columns needed for WC.  */\n#if @GNULIB_WCWIDTH@\n# if @REPLACE_WCWIDTH@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcwidth\n#   define wcwidth rpl_wcwidth\n#  endif\n_GL_FUNCDECL_RPL (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE);\n_GL_CXXALIAS_RPL (wcwidth, int, (wchar_t));\n# else\n#  if !@HAVE_DECL_WCWIDTH@\n/* wcwidth exists but is not declared.  */\n_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE);\n#  endif\n_GL_CXXALIAS_SYS (wcwidth, int, (wchar_t));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcwidth);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcwidth\n# if HAVE_RAW_DECL_WCWIDTH\n_GL_WARN_ON_USE (wcwidth, \"wcwidth is unportable - \"\n                 \"use gnulib module wcwidth for portability\");\n# endif\n#endif\n\n\n/* Search N wide characters of S for C.  */\n#if @GNULIB_WMEMCHR@\n# if !@HAVE_WMEMCHR@\n_GL_FUNCDECL_SYS (wmemchr, wchar_t *, (const wchar_t *s, wchar_t c, size_t n)\n                                      _GL_ATTRIBUTE_PURE);\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" {\n         const wchar_t * std::wmemchr (const wchar_t *, wchar_t, size_t);\n         wchar_t * std::wmemchr (wchar_t *, wchar_t, size_t);\n       }  */\n_GL_CXXALIAS_SYS_CAST2 (wmemchr,\n                        wchar_t *, (const wchar_t *, wchar_t, size_t),\n                        const wchar_t *, (const wchar_t *, wchar_t, size_t));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (wmemchr, wchar_t *, (wchar_t *s, wchar_t c, size_t n));\n_GL_CXXALIASWARN1 (wmemchr, const wchar_t *,\n                   (const wchar_t *s, wchar_t c, size_t n));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmemchr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmemchr\n# if HAVE_RAW_DECL_WMEMCHR\n_GL_WARN_ON_USE (wmemchr, \"wmemchr is unportable - \"\n                 \"use gnulib module wmemchr for portability\");\n# endif\n#endif\n\n\n/* Compare N wide characters of S1 and S2.  */\n#if @GNULIB_WMEMCMP@\n# if !@HAVE_WMEMCMP@\n_GL_FUNCDECL_SYS (wmemcmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n)\n                  _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wmemcmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmemcmp);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmemcmp\n# if HAVE_RAW_DECL_WMEMCMP\n_GL_WARN_ON_USE (wmemcmp, \"wmemcmp is unportable - \"\n                 \"use gnulib module wmemcmp for portability\");\n# endif\n#endif\n\n\n/* Copy N wide characters of SRC to DEST.  */\n#if @GNULIB_WMEMCPY@\n# if !@HAVE_WMEMCPY@\n_GL_FUNCDECL_SYS (wmemcpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wmemcpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmemcpy);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmemcpy\n# if HAVE_RAW_DECL_WMEMCPY\n_GL_WARN_ON_USE (wmemcpy, \"wmemcpy is unportable - \"\n                 \"use gnulib module wmemcpy for portability\");\n# endif\n#endif\n\n\n/* Copy N wide characters of SRC to DEST, guaranteeing correct behavior for\n   overlapping memory areas.  */\n#if @GNULIB_WMEMMOVE@\n# if !@HAVE_WMEMMOVE@\n_GL_FUNCDECL_SYS (wmemmove, wchar_t *,\n                  (wchar_t *dest, const wchar_t *src, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wmemmove, wchar_t *,\n                  (wchar_t *dest, const wchar_t *src, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmemmove);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmemmove\n# if HAVE_RAW_DECL_WMEMMOVE\n_GL_WARN_ON_USE (wmemmove, \"wmemmove is unportable - \"\n                 \"use gnulib module wmemmove for portability\");\n# endif\n#endif\n\n\n/* Copy N wide characters of SRC to DEST.\n   Return pointer to wide characters after the last written wide character.  */\n#if @GNULIB_WMEMPCPY@\n# if !@HAVE_WMEMPCPY@\n_GL_FUNCDECL_SYS (wmempcpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wmempcpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmempcpy);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmempcpy\n# if HAVE_RAW_DECL_WMEMPCPY\n_GL_WARN_ON_USE (wmempcpy, \"wmempcpy is unportable - \"\n                 \"use gnulib module wmempcpy for portability\");\n# endif\n#endif\n\n\n/* Set N wide characters of S to C.  */\n#if @GNULIB_WMEMSET@\n# if !@HAVE_WMEMSET@\n_GL_FUNCDECL_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmemset);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmemset\n# if HAVE_RAW_DECL_WMEMSET\n_GL_WARN_ON_USE (wmemset, \"wmemset is unportable - \"\n                 \"use gnulib module wmemset for portability\");\n# endif\n#endif\n\n\n/* Return the number of wide characters in S.  */\n#if @GNULIB_WCSLEN@\n# if !@HAVE_WCSLEN@\n_GL_FUNCDECL_SYS (wcslen, size_t, (const wchar_t *s) _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcslen, size_t, (const wchar_t *s));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcslen);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcslen\n# if HAVE_RAW_DECL_WCSLEN\n_GL_WARN_ON_USE (wcslen, \"wcslen is unportable - \"\n                 \"use gnulib module wcslen for portability\");\n# endif\n#endif\n\n\n/* Return the number of wide characters in S, but at most MAXLEN.  */\n#if @GNULIB_WCSNLEN@\n# if !@HAVE_WCSNLEN@\n_GL_FUNCDECL_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen)\n                                   _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen));\n_GL_CXXALIASWARN (wcsnlen);\n#elif defined GNULIB_POSIXCHECK\n# undef wcsnlen\n# if HAVE_RAW_DECL_WCSNLEN\n_GL_WARN_ON_USE (wcsnlen, \"wcsnlen is unportable - \"\n                 \"use gnulib module wcsnlen for portability\");\n# endif\n#endif\n\n\n/* Copy SRC to DEST.  */\n#if @GNULIB_WCSCPY@\n# if !@HAVE_WCSCPY@\n_GL_FUNCDECL_SYS (wcscpy, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n# endif\n_GL_CXXALIAS_SYS (wcscpy, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcscpy);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcscpy\n# if HAVE_RAW_DECL_WCSCPY\n_GL_WARN_ON_USE (wcscpy, \"wcscpy is unportable - \"\n                 \"use gnulib module wcscpy for portability\");\n# endif\n#endif\n\n\n/* Copy SRC to DEST, returning the address of the terminating L'\\0' in DEST.  */\n#if @GNULIB_WCPCPY@\n# if !@HAVE_WCPCPY@\n_GL_FUNCDECL_SYS (wcpcpy, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n# endif\n_GL_CXXALIAS_SYS (wcpcpy, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n_GL_CXXALIASWARN (wcpcpy);\n#elif defined GNULIB_POSIXCHECK\n# undef wcpcpy\n# if HAVE_RAW_DECL_WCPCPY\n_GL_WARN_ON_USE (wcpcpy, \"wcpcpy is unportable - \"\n                 \"use gnulib module wcpcpy for portability\");\n# endif\n#endif\n\n\n/* Copy no more than N wide characters of SRC to DEST.  */\n#if @GNULIB_WCSNCPY@\n# if !@HAVE_WCSNCPY@\n_GL_FUNCDECL_SYS (wcsncpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wcsncpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsncpy);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsncpy\n# if HAVE_RAW_DECL_WCSNCPY\n_GL_WARN_ON_USE (wcsncpy, \"wcsncpy is unportable - \"\n                 \"use gnulib module wcsncpy for portability\");\n# endif\n#endif\n\n\n/* Copy no more than N characters of SRC to DEST, returning the address of\n   the last character written into DEST.  */\n#if @GNULIB_WCPNCPY@\n# if !@HAVE_WCPNCPY@\n_GL_FUNCDECL_SYS (wcpncpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wcpncpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n_GL_CXXALIASWARN (wcpncpy);\n#elif defined GNULIB_POSIXCHECK\n# undef wcpncpy\n# if HAVE_RAW_DECL_WCPNCPY\n_GL_WARN_ON_USE (wcpncpy, \"wcpncpy is unportable - \"\n                 \"use gnulib module wcpncpy for portability\");\n# endif\n#endif\n\n\n/* Append SRC onto DEST.  */\n#if @GNULIB_WCSCAT@\n# if !@HAVE_WCSCAT@\n_GL_FUNCDECL_SYS (wcscat, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n# endif\n_GL_CXXALIAS_SYS (wcscat, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcscat);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcscat\n# if HAVE_RAW_DECL_WCSCAT\n_GL_WARN_ON_USE (wcscat, \"wcscat is unportable - \"\n                 \"use gnulib module wcscat for portability\");\n# endif\n#endif\n\n\n/* Append no more than N wide characters of SRC onto DEST.  */\n#if @GNULIB_WCSNCAT@\n# if !@HAVE_WCSNCAT@\n_GL_FUNCDECL_SYS (wcsncat, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src,\n                   size_t n));\n# endif\n_GL_CXXALIAS_SYS (wcsncat, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src,\n                   size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsncat);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsncat\n# if HAVE_RAW_DECL_WCSNCAT\n_GL_WARN_ON_USE (wcsncat, \"wcsncat is unportable - \"\n                 \"use gnulib module wcsncat for portability\");\n# endif\n#endif\n\n\n/* Compare S1 and S2.  */\n#if @GNULIB_WCSCMP@\n# if !@HAVE_WCSCMP@\n_GL_FUNCDECL_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)\n                               _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcscmp);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcscmp\n# if HAVE_RAW_DECL_WCSCMP\n_GL_WARN_ON_USE (wcscmp, \"wcscmp is unportable - \"\n                 \"use gnulib module wcscmp for portability\");\n# endif\n#endif\n\n\n/* Compare no more than N wide characters of S1 and S2.  */\n#if @GNULIB_WCSNCMP@\n# if !@HAVE_WCSNCMP@\n_GL_FUNCDECL_SYS (wcsncmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n)\n                  _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcsncmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsncmp);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsncmp\n# if HAVE_RAW_DECL_WCSNCMP\n_GL_WARN_ON_USE (wcsncmp, \"wcsncmp is unportable - \"\n                 \"use gnulib module wcsncmp for portability\");\n# endif\n#endif\n\n\n/* Compare S1 and S2, ignoring case.  */\n#if @GNULIB_WCSCASECMP@\n# if !@HAVE_WCSCASECMP@\n_GL_FUNCDECL_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2)\n                                   _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2));\n_GL_CXXALIASWARN (wcscasecmp);\n#elif defined GNULIB_POSIXCHECK\n# undef wcscasecmp\n# if HAVE_RAW_DECL_WCSCASECMP\n_GL_WARN_ON_USE (wcscasecmp, \"wcscasecmp is unportable - \"\n                 \"use gnulib module wcscasecmp for portability\");\n# endif\n#endif\n\n\n/* Compare no more than N chars of S1 and S2, ignoring case.  */\n#if @GNULIB_WCSNCASECMP@\n# if !@HAVE_WCSNCASECMP@\n_GL_FUNCDECL_SYS (wcsncasecmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n)\n                  _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcsncasecmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n));\n_GL_CXXALIASWARN (wcsncasecmp);\n#elif defined GNULIB_POSIXCHECK\n# undef wcsncasecmp\n# if HAVE_RAW_DECL_WCSNCASECMP\n_GL_WARN_ON_USE (wcsncasecmp, \"wcsncasecmp is unportable - \"\n                 \"use gnulib module wcsncasecmp for portability\");\n# endif\n#endif\n\n\n/* Compare S1 and S2, both interpreted as appropriate to the LC_COLLATE\n   category of the current locale.  */\n#if @GNULIB_WCSCOLL@\n# if !@HAVE_WCSCOLL@\n_GL_FUNCDECL_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2));\n# endif\n_GL_CXXALIAS_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcscoll);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcscoll\n# if HAVE_RAW_DECL_WCSCOLL\n_GL_WARN_ON_USE (wcscoll, \"wcscoll is unportable - \"\n                 \"use gnulib module wcscoll for portability\");\n# endif\n#endif\n\n\n/* Transform S2 into array pointed to by S1 such that if wcscmp is applied\n   to two transformed strings the result is the as applying 'wcscoll' to the\n   original strings.  */\n#if @GNULIB_WCSXFRM@\n# if !@HAVE_WCSXFRM@\n_GL_FUNCDECL_SYS (wcsxfrm, size_t,\n                  (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wcsxfrm, size_t,\n                  (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsxfrm);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsxfrm\n# if HAVE_RAW_DECL_WCSXFRM\n_GL_WARN_ON_USE (wcsxfrm, \"wcsxfrm is unportable - \"\n                 \"use gnulib module wcsxfrm for portability\");\n# endif\n#endif\n\n\n/* Duplicate S, returning an identical malloc'd string.  */\n#if @GNULIB_WCSDUP@\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcsdup\n#   define wcsdup _wcsdup\n#  endif\n_GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s));\n# else\n#  if !@HAVE_WCSDUP@\n_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s));\n#  endif\n_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s));\n# endif\n_GL_CXXALIASWARN (wcsdup);\n#elif defined GNULIB_POSIXCHECK\n# undef wcsdup\n# if HAVE_RAW_DECL_WCSDUP\n_GL_WARN_ON_USE (wcsdup, \"wcsdup is unportable - \"\n                 \"use gnulib module wcsdup for portability\");\n# endif\n#elif @GNULIB_MDA_WCSDUP@\n/* On native Windows, map 'wcsdup' to '_wcsdup', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::wcsdup always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcsdup\n#   define wcsdup _wcsdup\n#  endif\n_GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s));\n# else\n_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s));\n#  if @HAVE_DECL_WCSDUP@\n_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s));\n#  endif\n# endif\n# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_WCSDUP@\n_GL_CXXALIASWARN (wcsdup);\n# endif\n#endif\n\n\n/* Find the first occurrence of WC in WCS.  */\n#if @GNULIB_WCSCHR@\n# if !@HAVE_WCSCHR@\n_GL_FUNCDECL_SYS (wcschr, wchar_t *, (const wchar_t *wcs, wchar_t wc)\n                                     _GL_ATTRIBUTE_PURE);\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" {\n         const wchar_t * std::wcschr (const wchar_t *, wchar_t);\n         wchar_t * std::wcschr (wchar_t *, wchar_t);\n       }  */\n_GL_CXXALIAS_SYS_CAST2 (wcschr,\n                        wchar_t *, (const wchar_t *, wchar_t),\n                        const wchar_t *, (const wchar_t *, wchar_t));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (wcschr, wchar_t *, (wchar_t *wcs, wchar_t wc));\n_GL_CXXALIASWARN1 (wcschr, const wchar_t *, (const wchar_t *wcs, wchar_t wc));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcschr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcschr\n# if HAVE_RAW_DECL_WCSCHR\n_GL_WARN_ON_USE (wcschr, \"wcschr is unportable - \"\n                 \"use gnulib module wcschr for portability\");\n# endif\n#endif\n\n\n/* Find the last occurrence of WC in WCS.  */\n#if @GNULIB_WCSRCHR@\n# if !@HAVE_WCSRCHR@\n_GL_FUNCDECL_SYS (wcsrchr, wchar_t *, (const wchar_t *wcs, wchar_t wc)\n                                      _GL_ATTRIBUTE_PURE);\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" {\n         const wchar_t * std::wcsrchr (const wchar_t *, wchar_t);\n         wchar_t * std::wcsrchr (wchar_t *, wchar_t);\n       }  */\n_GL_CXXALIAS_SYS_CAST2 (wcsrchr,\n                        wchar_t *, (const wchar_t *, wchar_t),\n                        const wchar_t *, (const wchar_t *, wchar_t));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (wcsrchr, wchar_t *, (wchar_t *wcs, wchar_t wc));\n_GL_CXXALIASWARN1 (wcsrchr, const wchar_t *, (const wchar_t *wcs, wchar_t wc));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsrchr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsrchr\n# if HAVE_RAW_DECL_WCSRCHR\n_GL_WARN_ON_USE (wcsrchr, \"wcsrchr is unportable - \"\n                 \"use gnulib module wcsrchr for portability\");\n# endif\n#endif\n\n\n/* Return the length of the initial segmet of WCS which consists entirely\n   of wide characters not in REJECT.  */\n#if @GNULIB_WCSCSPN@\n# if !@HAVE_WCSCSPN@\n_GL_FUNCDECL_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject)\n                                   _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcscspn);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcscspn\n# if HAVE_RAW_DECL_WCSCSPN\n_GL_WARN_ON_USE (wcscspn, \"wcscspn is unportable - \"\n                 \"use gnulib module wcscspn for portability\");\n# endif\n#endif\n\n\n/* Return the length of the initial segmet of WCS which consists entirely\n   of wide characters in ACCEPT.  */\n#if @GNULIB_WCSSPN@\n# if !@HAVE_WCSSPN@\n_GL_FUNCDECL_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept)\n                                  _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsspn);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsspn\n# if HAVE_RAW_DECL_WCSSPN\n_GL_WARN_ON_USE (wcsspn, \"wcsspn is unportable - \"\n                 \"use gnulib module wcsspn for portability\");\n# endif\n#endif\n\n\n/* Find the first occurrence in WCS of any character in ACCEPT.  */\n#if @GNULIB_WCSPBRK@\n# if !@HAVE_WCSPBRK@\n_GL_FUNCDECL_SYS (wcspbrk, wchar_t *,\n                  (const wchar_t *wcs, const wchar_t *accept)\n                  _GL_ATTRIBUTE_PURE);\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" {\n         const wchar_t * std::wcspbrk (const wchar_t *, const wchar_t *);\n         wchar_t * std::wcspbrk (wchar_t *, const wchar_t *);\n       }  */\n_GL_CXXALIAS_SYS_CAST2 (wcspbrk,\n                        wchar_t *, (const wchar_t *, const wchar_t *),\n                        const wchar_t *, (const wchar_t *, const wchar_t *));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (wcspbrk, wchar_t *,\n                   (wchar_t *wcs, const wchar_t *accept));\n_GL_CXXALIASWARN1 (wcspbrk, const wchar_t *,\n                   (const wchar_t *wcs, const wchar_t *accept));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcspbrk);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcspbrk\n# if HAVE_RAW_DECL_WCSPBRK\n_GL_WARN_ON_USE (wcspbrk, \"wcspbrk is unportable - \"\n                 \"use gnulib module wcspbrk for portability\");\n# endif\n#endif\n\n\n/* Find the first occurrence of NEEDLE in HAYSTACK.  */\n#if @GNULIB_WCSSTR@\n# if !@HAVE_WCSSTR@\n_GL_FUNCDECL_SYS (wcsstr, wchar_t *,\n                  (const wchar_t *restrict haystack,\n                   const wchar_t *restrict needle)\n                  _GL_ATTRIBUTE_PURE);\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" {\n         const wchar_t * std::wcsstr (const wchar_t *, const wchar_t *);\n         wchar_t * std::wcsstr (wchar_t *, const wchar_t *);\n       }  */\n_GL_CXXALIAS_SYS_CAST2 (wcsstr,\n                        wchar_t *,\n                        (const wchar_t *restrict, const wchar_t *restrict),\n                        const wchar_t *,\n                        (const wchar_t *restrict, const wchar_t *restrict));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (wcsstr, wchar_t *,\n                   (wchar_t *restrict haystack,\n                    const wchar_t *restrict needle));\n_GL_CXXALIASWARN1 (wcsstr, const wchar_t *,\n                   (const wchar_t *restrict haystack,\n                    const wchar_t *restrict needle));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsstr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsstr\n# if HAVE_RAW_DECL_WCSSTR\n_GL_WARN_ON_USE (wcsstr, \"wcsstr is unportable - \"\n                 \"use gnulib module wcsstr for portability\");\n# endif\n#endif\n\n\n/* Divide WCS into tokens separated by characters in DELIM.  */\n#if @GNULIB_WCSTOK@\n# if @REPLACE_WCSTOK@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcstok\n#   define wcstok rpl_wcstok\n#  endif\n_GL_FUNCDECL_RPL (wcstok, wchar_t *,\n                  (wchar_t *restrict wcs, const wchar_t *restrict delim,\n                   wchar_t **restrict ptr));\n_GL_CXXALIAS_RPL (wcstok, wchar_t *,\n                  (wchar_t *restrict wcs, const wchar_t *restrict delim,\n                   wchar_t **restrict ptr));\n# else\n#  if !@HAVE_WCSTOK@\n_GL_FUNCDECL_SYS (wcstok, wchar_t *,\n                  (wchar_t *restrict wcs, const wchar_t *restrict delim,\n                   wchar_t **restrict ptr));\n#  endif\n_GL_CXXALIAS_SYS (wcstok, wchar_t *,\n                  (wchar_t *restrict wcs, const wchar_t *restrict delim,\n                   wchar_t **restrict ptr));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcstok);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcstok\n# if HAVE_RAW_DECL_WCSTOK\n_GL_WARN_ON_USE (wcstok, \"wcstok is unportable - \"\n                 \"use gnulib module wcstok for portability\");\n# endif\n#endif\n\n\n/* Determine number of column positions required for first N wide\n   characters (or fewer if S ends before this) in S.  */\n#if @GNULIB_WCSWIDTH@\n# if @REPLACE_WCSWIDTH@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcswidth\n#   define wcswidth rpl_wcswidth\n#  endif\n_GL_FUNCDECL_RPL (wcswidth, int, (const wchar_t *s, size_t n)\n                                 _GL_ATTRIBUTE_PURE);\n_GL_CXXALIAS_RPL (wcswidth, int, (const wchar_t *s, size_t n));\n# else\n#  if !@HAVE_WCSWIDTH@\n_GL_FUNCDECL_SYS (wcswidth, int, (const wchar_t *s, size_t n)\n                                 _GL_ATTRIBUTE_PURE);\n#  endif\n_GL_CXXALIAS_SYS (wcswidth, int, (const wchar_t *s, size_t n));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcswidth);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcswidth\n# if HAVE_RAW_DECL_WCSWIDTH\n_GL_WARN_ON_USE (wcswidth, \"wcswidth is unportable - \"\n                 \"use gnulib module wcswidth for portability\");\n# endif\n#endif\n\n\n/* Convert *TP to a date and time wide string.  See\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/wcsftime.html>.  */\n#if @GNULIB_WCSFTIME@\n# if @REPLACE_WCSFTIME@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcsftime\n#   define wcsftime rpl_wcsftime\n#  endif\n_GL_FUNCDECL_RPL (wcsftime, size_t,\n                  (wchar_t *restrict __buf, size_t __bufsize,\n                   const wchar_t *restrict __fmt,\n                   const struct tm *restrict __tp)\n                  _GL_ARG_NONNULL ((1, 3, 4)));\n_GL_CXXALIAS_RPL (wcsftime, size_t,\n                  (wchar_t *restrict __buf, size_t __bufsize,\n                   const wchar_t *restrict __fmt,\n                   const struct tm *restrict __tp));\n# else\n#  if !@HAVE_WCSFTIME@\n_GL_FUNCDECL_SYS (wcsftime, size_t,\n                  (wchar_t *restrict __buf, size_t __bufsize,\n                   const wchar_t *restrict __fmt,\n                   const struct tm *restrict __tp)\n                  _GL_ARG_NONNULL ((1, 3, 4)));\n#  endif\n_GL_CXXALIAS_SYS (wcsftime, size_t,\n                  (wchar_t *restrict __buf, size_t __bufsize,\n                   const wchar_t *restrict __fmt,\n                   const struct tm *restrict __tp));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsftime);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsftime\n# if HAVE_RAW_DECL_WCSFTIME\n_GL_WARN_ON_USE (wcsftime, \"wcsftime is unportable - \"\n                 \"use gnulib module wcsftime for portability\");\n# endif\n#endif\n\n\n#endif /* _@GUARD_PREFIX@_WCHAR_H */\n#endif /* _@GUARD_PREFIX@_WCHAR_H */\n#endif\n"
  },
  {
    "path": "gnulib/wcrtomb.c",
    "content": "/* Convert wide character to multibyte character.\n   Copyright (C) 2008-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 2008.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <wchar.h>\n\n#include <errno.h>\n#include <stdlib.h>\n\n\nsize_t\nwcrtomb (char *s, wchar_t wc, mbstate_t *ps)\n#undef wcrtomb\n{\n  /* This implementation of wcrtomb supports only stateless encodings.\n     ps must be in the initial state.  */\n  if (ps != NULL && !mbsinit (ps))\n    {\n      errno = EINVAL;\n      return (size_t)(-1);\n    }\n\n#if !HAVE_WCRTOMB                       /* IRIX 6.5 */ \\\n    || WCRTOMB_RETVAL_BUG               /* Solaris 11.3, MSVC */ \\\n    || WCRTOMB_C_LOCALE_BUG             /* Android */\n  if (s == NULL)\n    /* We know the NUL wide character corresponds to the NUL character.  */\n    return 1;\n  else\n#endif\n    {\n#if HAVE_WCRTOMB\n# if WCRTOMB_C_LOCALE_BUG               /* Android */\n      /* Implement consistently with mbrtowc(): through a 1:1 correspondence,\n         as in ISO-8859-1.  */\n      if (wc >= 0 && wc <= 0xff)\n        {\n          *s = (unsigned char) wc;\n          return 1;\n        }\n      else\n        {\n          errno = EILSEQ;\n          return (size_t)(-1);\n        }\n# else\n      return wcrtomb (s, wc, ps);\n# endif\n#else                                   /* IRIX 6.5 */\n      /* Fallback for platforms that don't have wcrtomb().\n         Implement on top of wctomb().\n         This code is not multithread-safe.  */\n      int ret = wctomb (s, wc);\n\n      if (ret >= 0)\n        return ret;\n      else\n        {\n          errno = EILSEQ;\n          return (size_t)(-1);\n        }\n#endif\n    }\n}\n"
  },
  {
    "path": "gnulib/wctype-h.c",
    "content": "/* Inline functions for <wctype.h>.\n\n   Copyright (C) 2012-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Normally this would be wctype.c, but that name's already taken.  */\n\n#include <config.h>\n\n#define _GL_WCTYPE_INLINE _GL_EXTERN_INLINE\n#include \"wctype.h\"\n"
  },
  {
    "path": "gnulib/wctype.in.h",
    "content": "/* A substitute for ISO C99 <wctype.h>, for platforms that lack it.\n\n   Copyright (C) 2006-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible and Paul Eggert.  */\n\n/*\n * ISO C 99 <wctype.h> for platforms that lack it.\n * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/wctype.h.html>\n *\n * iswctype, towctrans, towlower, towupper, wctrans, wctype,\n * wctrans_t, and wctype_t are not yet implemented.\n */\n\n#if __GNUC__ >= 3\n@PRAGMA_SYSTEM_HEADER@\n#endif\n@PRAGMA_COLUMNS@\n\n#if (defined __MINGW32__ && defined __CTYPE_H_SOURCED__)\n\n/* Special invocation convention:\n   - With MinGW 3.22, when <ctype.h> includes <wctype.h>, only some part of\n     <wctype.h> is being processed, which doesn't include the idempotency\n     guard.   */\n\n#@INCLUDE_NEXT@ @NEXT_WCTYPE_H@\n\n#else\n/* Normal invocation convention.  */\n\n#ifndef _@GUARD_PREFIX@_WCTYPE_H\n\n#if @HAVE_WINT_T@\n/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */\n# include <wchar.h>\n#endif\n\n/* Native Windows (mingw, MSVC) have declarations of towupper, towlower, and\n   isw* functions in <ctype.h>, <wchar.h> as well as in <wctype.h>.  Include\n   <ctype.h>, <wchar.h> in advance to avoid rpl_ prefix being added to the\n   declarations.  */\n#if defined _WIN32 && ! defined __CYGWIN__\n# include <ctype.h>\n# include <wchar.h>\n#endif\n\n/* Include the original <wctype.h> if it exists.\n   BeOS 5 has the functions but no <wctype.h>.  */\n/* The include_next requires a split double-inclusion guard.  */\n#if @HAVE_WCTYPE_H@\n# @INCLUDE_NEXT@ @NEXT_WCTYPE_H@\n#endif\n\n#ifndef _@GUARD_PREFIX@_WCTYPE_H\n#define _@GUARD_PREFIX@_WCTYPE_H\n\n#ifndef _GL_INLINE_HEADER_BEGIN\n #error \"Please include config.h first.\"\n#endif\n_GL_INLINE_HEADER_BEGIN\n#ifndef _GL_WCTYPE_INLINE\n# define _GL_WCTYPE_INLINE _GL_INLINE\n#endif\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n\n/* Solaris 2.6 <wctype.h> includes <widec.h> which includes <euc.h> which\n   #defines a number of identifiers in the application namespace.  Revert\n   these #defines.  */\n#ifdef __sun\n# undef multibyte\n# undef eucw1\n# undef eucw2\n# undef eucw3\n# undef scrw1\n# undef scrw2\n# undef scrw3\n#endif\n\n/* Define wint_t and WEOF.  (Also done in wchar.in.h.)  */\n#if !@HAVE_WINT_T@ && !defined wint_t\n# define wint_t int\n# ifndef WEOF\n#  define WEOF -1\n# endif\n#else\n/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h> or\n   <stddef.h>.  This is too small: ISO C 99 section 7.24.1.(2) says that\n   wint_t must be \"unchanged by default argument promotions\".  Override it.  */\n# if @GNULIBHEADERS_OVERRIDE_WINT_T@\n#  if !GNULIB_defined_wint_t\n#   if @HAVE_CRTDEFS_H@\n#    include <crtdefs.h>\n#   else\n#    include <stddef.h>\n#   endif\ntypedef unsigned int rpl_wint_t;\n#   undef wint_t\n#   define wint_t rpl_wint_t\n#   define GNULIB_defined_wint_t 1\n#  endif\n# endif\n# ifndef WEOF\n#  define WEOF ((wint_t) -1)\n# endif\n#endif\n\n\n#if !GNULIB_defined_wctype_functions\n\n/* FreeBSD 4.4 to 4.11 has <wctype.h> but lacks the functions.\n   Linux libc5 has <wctype.h> and the functions but they are broken.\n   mingw and MSVC have <wctype.h> and the functions but they take a wchar_t\n   as argument, not an rpl_wint_t.\n   Assume all 11 functions (all isw* except iswblank) are implemented the\n   same way, or not at all.  */\n# if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@\n\n#  if @GNULIBHEADERS_OVERRIDE_WINT_T@ /* implies @REPLACE_ISWCNTRL@ */\n\n_GL_WCTYPE_INLINE int\nrpl_iswalnum (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? iswalnum ((wchar_t) wc) : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswalpha (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? iswalpha ((wchar_t) wc) : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswblank (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? iswblank ((wchar_t) wc) : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswcntrl (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? iswcntrl ((wchar_t) wc) : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswdigit (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? wc >= '0' && wc <= '9' : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswgraph (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? iswgraph ((wchar_t) wc) : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswlower (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? iswlower ((wchar_t) wc) : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswprint (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? iswprint ((wchar_t) wc) : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswpunct (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? iswpunct ((wchar_t) wc) : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswspace (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? iswspace ((wchar_t) wc) : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswupper (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? iswupper ((wchar_t) wc) : 0);\n}\n\n_GL_WCTYPE_INLINE int\nrpl_iswxdigit (wint_t wc)\n{\n  return ((wchar_t) wc == wc\n          ? (wc >= '0' && wc <= '9')\n            || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F')\n          : 0);\n}\n\n_GL_WCTYPE_INLINE wint_t\nrpl_towlower (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? (wchar_t) towlower ((wchar_t) wc) : wc);\n}\n\n_GL_WCTYPE_INLINE wint_t\nrpl_towupper (wint_t wc)\n{\n  return ((wchar_t) wc == wc ? (wchar_t) towupper ((wchar_t) wc) : wc);\n}\n\n#   if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#    undef iswalnum\n#    undef iswalpha\n#    undef iswblank\n#    undef iswcntrl\n#    undef iswdigit\n#    undef iswgraph\n#    undef iswlower\n#    undef iswprint\n#    undef iswpunct\n#    undef iswspace\n#    undef iswupper\n#    undef iswxdigit\n#    undef towlower\n#    undef towupper\n#    define iswalnum rpl_iswalnum\n#    define iswalpha rpl_iswalpha\n#    define iswblank rpl_iswblank\n#    define iswcntrl rpl_iswcntrl\n#    define iswdigit rpl_iswdigit\n#    define iswgraph rpl_iswgraph\n#    define iswlower rpl_iswlower\n#    define iswprint rpl_iswprint\n#    define iswpunct rpl_iswpunct\n#    define iswspace rpl_iswspace\n#    define iswupper rpl_iswupper\n#    define iswxdigit rpl_iswxdigit\n#    define towlower rpl_towlower\n#    define towupper rpl_towupper\n#   endif\n\n#  else\n\n/* IRIX 5.3 has macros but no functions, its isw* macros refer to an\n   undefined variable _ctmp_ and to <ctype.h> macros like _P, and they\n   refer to system functions like _iswctype that are not in the\n   standard C library.  Rather than try to get ancient buggy\n   implementations like this to work, just disable them.  */\n#   undef iswalnum\n#   undef iswalpha\n#   undef iswblank\n#   undef iswcntrl\n#   undef iswdigit\n#   undef iswgraph\n#   undef iswlower\n#   undef iswprint\n#   undef iswpunct\n#   undef iswspace\n#   undef iswupper\n#   undef iswxdigit\n#   undef towlower\n#   undef towupper\n\n/* Linux libc5 has <wctype.h> and the functions but they are broken.  */\n#   if @REPLACE_ISWCNTRL@\n#    if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#     define iswalnum rpl_iswalnum\n#     define iswalpha rpl_iswalpha\n#     define iswblank rpl_iswblank\n#     define iswcntrl rpl_iswcntrl\n#     define iswdigit rpl_iswdigit\n#     define iswgraph rpl_iswgraph\n#     define iswlower rpl_iswlower\n#     define iswprint rpl_iswprint\n#     define iswpunct rpl_iswpunct\n#     define iswspace rpl_iswspace\n#     define iswupper rpl_iswupper\n#     define iswxdigit rpl_iswxdigit\n#    endif\n#   endif\n#   if @REPLACE_TOWLOWER@\n#    if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#     define towlower rpl_towlower\n#     define towupper rpl_towupper\n#    endif\n#   endif\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWCNTRL@\nrpl_iswalnum\n#   else\niswalnum\n#   endif\n         (wint_t wc)\n{\n  return ((wc >= '0' && wc <= '9')\n          || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'));\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWCNTRL@\nrpl_iswalpha\n#   else\niswalpha\n#   endif\n         (wint_t wc)\n{\n  return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z';\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWCNTRL@\nrpl_iswblank\n#   else\niswblank\n#   endif\n         (wint_t wc)\n{\n  return wc == ' ' || wc == '\\t';\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWCNTRL@\nrpl_iswcntrl\n#   else\niswcntrl\n#   endif\n        (wint_t wc)\n{\n  return (wc & ~0x1f) == 0 || wc == 0x7f;\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWDIGIT@\nrpl_iswdigit\n#   else\niswdigit\n#   endif\n         (wint_t wc)\n{\n  return wc >= '0' && wc <= '9';\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWCNTRL@\nrpl_iswgraph\n#   else\niswgraph\n#   endif\n         (wint_t wc)\n{\n  return wc >= '!' && wc <= '~';\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWCNTRL@\nrpl_iswlower\n#   else\niswlower\n#   endif\n         (wint_t wc)\n{\n  return wc >= 'a' && wc <= 'z';\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWCNTRL@\nrpl_iswprint\n#   else\niswprint\n#   endif\n         (wint_t wc)\n{\n  return wc >= ' ' && wc <= '~';\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWCNTRL@\nrpl_iswpunct\n#   else\niswpunct\n#   endif\n         (wint_t wc)\n{\n  return (wc >= '!' && wc <= '~'\n          && !((wc >= '0' && wc <= '9')\n               || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')));\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWCNTRL@\nrpl_iswspace\n#   else\niswspace\n#   endif\n         (wint_t wc)\n{\n  return (wc == ' ' || wc == '\\t'\n          || wc == '\\n' || wc == '\\v' || wc == '\\f' || wc == '\\r');\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWCNTRL@\nrpl_iswupper\n#   else\niswupper\n#   endif\n         (wint_t wc)\n{\n  return wc >= 'A' && wc <= 'Z';\n}\n\n_GL_WCTYPE_INLINE int\n#   if @REPLACE_ISWXDIGIT@\nrpl_iswxdigit\n#   else\niswxdigit\n#   endif\n          (wint_t wc)\n{\n  return ((wc >= '0' && wc <= '9')\n          || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F'));\n}\n\n_GL_WCTYPE_INLINE wint_t\n#   if @REPLACE_TOWLOWER@\nrpl_towlower\n#   else\ntowlower\n#   endif\n         (wint_t wc)\n{\n  return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc);\n}\n\n_GL_WCTYPE_INLINE wint_t\n#   if @REPLACE_TOWLOWER@\nrpl_towupper\n#   else\ntowupper\n#   endif\n         (wint_t wc)\n{\n  return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc);\n}\n\n#  endif\n\n# else\n/* Only some of the functions are missing or broken.  */\n\n#  if @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@)\n/* Only the iswblank function is missing.  */\n#   if @REPLACE_ISWBLANK@\n#    if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#     define iswblank rpl_iswblank\n#    endif\n_GL_FUNCDECL_RPL (iswblank, int, (wint_t wc));\n#   else\n_GL_FUNCDECL_SYS (iswblank, int, (wint_t wc));\n#   endif\n#  endif\n\n#  if @GNULIB_ISWDIGIT@\n#   if @REPLACE_ISWDIGIT@\n#    if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#     undef iswdigit\n#     define iswdigit rpl_iswdigit\n#    endif\n_GL_FUNCDECL_RPL (iswdigit, int, (wint_t wc));\n#   endif\n#  endif\n\n#  if @GNULIB_ISWXDIGIT@\n#   if @REPLACE_ISWXDIGIT@\n#    if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#     undef iswxdigit\n#     define iswxdigit rpl_iswxdigit\n#    endif\n_GL_FUNCDECL_RPL (iswxdigit, int, (wint_t wc));\n#   endif\n#  endif\n\n# endif\n\n# if defined __MINGW32__ && !@GNULIBHEADERS_OVERRIDE_WINT_T@\n\n/* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t.\n   The functions towlower and towupper are implemented in the MSVCRT library\n   to take a wchar_t argument and return a wchar_t result.  mingw declares\n   these functions to take a wint_t argument and return a wint_t result.\n   This means that:\n   1. When the user passes an argument outside the range 0x0000..0xFFFF, the\n      function will look only at the lower 16 bits.  This is allowed according\n      to POSIX.\n   2. The return value is returned in the lower 16 bits of the result register.\n      The upper 16 bits are random: whatever happened to be in that part of the\n      result register.  We need to fix this by adding a zero-extend from\n      wchar_t to wint_t after the call.  */\n\n_GL_WCTYPE_INLINE wint_t\nrpl_towlower (wint_t wc)\n{\n  return (wint_t) (wchar_t) towlower (wc);\n}\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define towlower rpl_towlower\n#  endif\n\n_GL_WCTYPE_INLINE wint_t\nrpl_towupper (wint_t wc)\n{\n  return (wint_t) (wchar_t) towupper (wc);\n}\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define towupper rpl_towupper\n#  endif\n\n# endif /* __MINGW32__ && !@GNULIBHEADERS_OVERRIDE_WINT_T@ */\n\n# define GNULIB_defined_wctype_functions 1\n#endif\n\n#if @REPLACE_ISWCNTRL@\n_GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc));\n#else\n_GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc));\n#endif\n#if @REPLACE_ISWCNTRL@\n_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc));\n#else\n_GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc));\n#endif\n#if @REPLACE_ISWCNTRL@\n_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc));\n#else\n_GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc));\n#endif\n#if @GNULIB_ISWDIGIT@\n# if @REPLACE_ISWDIGIT@\n_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc));\n# else\n_GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc));\n# endif\n#endif\n#if @REPLACE_ISWCNTRL@\n_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc));\n#else\n_GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc));\n#endif\n#if @REPLACE_ISWCNTRL@\n_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc));\n#else\n_GL_CXXALIAS_SYS (iswlower, int, (wint_t wc));\n#endif\n#if @REPLACE_ISWCNTRL@\n_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc));\n#else\n_GL_CXXALIAS_SYS (iswprint, int, (wint_t wc));\n#endif\n#if @REPLACE_ISWCNTRL@\n_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc));\n#else\n_GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc));\n#endif\n#if @REPLACE_ISWCNTRL@\n_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc));\n#else\n_GL_CXXALIAS_SYS (iswspace, int, (wint_t wc));\n#endif\n#if @REPLACE_ISWCNTRL@\n_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc));\n#else\n_GL_CXXALIAS_SYS (iswupper, int, (wint_t wc));\n#endif\n#if @GNULIB_ISWXDIGIT@\n# if @REPLACE_ISWXDIGIT@\n_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc));\n# else\n_GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc));\n# endif\n#endif\n#if __GLIBC__ >= 2\n_GL_CXXALIASWARN (iswalnum);\n_GL_CXXALIASWARN (iswalpha);\n_GL_CXXALIASWARN (iswcntrl);\n_GL_CXXALIASWARN (iswdigit);\n_GL_CXXALIASWARN (iswgraph);\n_GL_CXXALIASWARN (iswlower);\n_GL_CXXALIASWARN (iswprint);\n_GL_CXXALIASWARN (iswpunct);\n_GL_CXXALIASWARN (iswspace);\n_GL_CXXALIASWARN (iswupper);\n_GL_CXXALIASWARN (iswxdigit);\n#endif\n\n#if @GNULIB_ISWBLANK@\n# if @REPLACE_ISWCNTRL@ || @REPLACE_ISWBLANK@\n_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc));\n# else\n_GL_CXXALIAS_SYS (iswblank, int, (wint_t wc));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (iswblank);\n# endif\n#endif\n\n#if !@HAVE_WCTYPE_T@\n# if !GNULIB_defined_wctype_t\ntypedef void * wctype_t;\n#  define GNULIB_defined_wctype_t 1\n# endif\n#endif\n\n/* Get a descriptor for a wide character property.  */\n#if @GNULIB_WCTYPE@\n# if !@HAVE_WCTYPE_T@\n_GL_FUNCDECL_SYS (wctype, wctype_t, (const char *name));\n# endif\n_GL_CXXALIAS_SYS (wctype, wctype_t, (const char *name));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wctype);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wctype\n# if HAVE_RAW_DECL_WCTYPE\n_GL_WARN_ON_USE (wctype, \"wctype is unportable - \"\n                 \"use gnulib module wctype for portability\");\n# endif\n#endif\n\n/* Test whether a wide character has a given property.\n   The argument WC must be either a wchar_t value or WEOF.\n   The argument DESC must have been returned by the wctype() function.  */\n#if @GNULIB_ISWCTYPE@\n# if @GNULIBHEADERS_OVERRIDE_WINT_T@\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef iswctype\n#   define iswctype rpl_iswctype\n#  endif\n_GL_FUNCDECL_RPL (iswctype, int, (wint_t wc, wctype_t desc));\n_GL_CXXALIAS_RPL (iswctype, int, (wint_t wc, wctype_t desc));\n# else\n#  if !@HAVE_WCTYPE_T@\n_GL_FUNCDECL_SYS (iswctype, int, (wint_t wc, wctype_t desc));\n#  endif\n_GL_CXXALIAS_SYS (iswctype, int, (wint_t wc, wctype_t desc));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (iswctype);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef iswctype\n# if HAVE_RAW_DECL_ISWCTYPE\n_GL_WARN_ON_USE (iswctype, \"iswctype is unportable - \"\n                 \"use gnulib module iswctype for portability\");\n# endif\n#endif\n\n#if @REPLACE_TOWLOWER@ || defined __MINGW32__\n_GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc));\n_GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc));\n#else\n_GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc));\n_GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc));\n#endif\n#if __GLIBC__ >= 2\n_GL_CXXALIASWARN (towlower);\n_GL_CXXALIASWARN (towupper);\n#endif\n\n#if !@HAVE_WCTRANS_T@\n# if !GNULIB_defined_wctrans_t\ntypedef void * wctrans_t;\n#  define GNULIB_defined_wctrans_t 1\n# endif\n#endif\n\n/* Get a descriptor for a wide character case conversion.  */\n#if @GNULIB_WCTRANS@\n# if !@HAVE_WCTRANS_T@\n_GL_FUNCDECL_SYS (wctrans, wctrans_t, (const char *name));\n# endif\n_GL_CXXALIAS_SYS (wctrans, wctrans_t, (const char *name));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wctrans);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wctrans\n# if HAVE_RAW_DECL_WCTRANS\n_GL_WARN_ON_USE (wctrans, \"wctrans is unportable - \"\n                 \"use gnulib module wctrans for portability\");\n# endif\n#endif\n\n/* Perform a given case conversion on a wide character.\n   The argument WC must be either a wchar_t value or WEOF.\n   The argument DESC must have been returned by the wctrans() function.  */\n#if @GNULIB_TOWCTRANS@\n# if !@HAVE_WCTRANS_T@\n_GL_FUNCDECL_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc));\n# endif\n_GL_CXXALIAS_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (towctrans);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef towctrans\n# if HAVE_RAW_DECL_TOWCTRANS\n_GL_WARN_ON_USE (towctrans, \"towctrans is unportable - \"\n                 \"use gnulib module towctrans for portability\");\n# endif\n#endif\n\n_GL_INLINE_HEADER_END\n\n#endif /* _@GUARD_PREFIX@_WCTYPE_H */\n#endif /* _@GUARD_PREFIX@_WCTYPE_H */\n#endif\n"
  },
  {
    "path": "gnulib/windows-initguard.h",
    "content": "/* Init guards, somewhat like spinlocks (native Windows implementation).\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-win32.h.  */\n\n#ifndef _WINDOWS_INITGUARD_H\n#define _WINDOWS_INITGUARD_H\n\n#define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#include <windows.h>\n\ntypedef struct\n        {\n          volatile int done;\n          volatile LONG started;\n        }\n        glwthread_initguard_t;\n\n#define GLWTHREAD_INITGUARD_INIT { 0, -1 }\n\n#endif /* _WINDOWS_INITGUARD_H */\n"
  },
  {
    "path": "gnulib/windows-mutex.c",
    "content": "/* Plain mutexes (native Windows implementation).\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-win32.h.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include \"windows-mutex.h\"\n\n#include <errno.h>\n\nvoid\nglwthread_mutex_init (glwthread_mutex_t *mutex)\n{\n  InitializeCriticalSection (&mutex->lock);\n  mutex->guard.done = 1;\n}\n\nint\nglwthread_mutex_lock (glwthread_mutex_t *mutex)\n{\n  if (!mutex->guard.done)\n    {\n      if (InterlockedIncrement (&mutex->guard.started) == 0)\n        /* This thread is the first one to need this mutex.  Initialize it.  */\n        glwthread_mutex_init (mutex);\n      else\n        {\n          /* Don't let mutex->guard.started grow and wrap around.  */\n          InterlockedDecrement (&mutex->guard.started);\n          /* Yield the CPU while waiting for another thread to finish\n             initializing this mutex.  */\n          while (!mutex->guard.done)\n            Sleep (0);\n        }\n    }\n  EnterCriticalSection (&mutex->lock);\n  return 0;\n}\n\nint\nglwthread_mutex_trylock (glwthread_mutex_t *mutex)\n{\n  if (!mutex->guard.done)\n    {\n      if (InterlockedIncrement (&mutex->guard.started) == 0)\n        /* This thread is the first one to need this mutex.  Initialize it.  */\n        glwthread_mutex_init (mutex);\n      else\n        {\n          /* Don't let mutex->guard.started grow and wrap around.  */\n          InterlockedDecrement (&mutex->guard.started);\n          /* Let another thread finish initializing this mutex, and let it also\n             lock this mutex.  */\n          return EBUSY;\n        }\n    }\n  if (!TryEnterCriticalSection (&mutex->lock))\n    return EBUSY;\n  return 0;\n}\n\nint\nglwthread_mutex_unlock (glwthread_mutex_t *mutex)\n{\n  if (!mutex->guard.done)\n    return EINVAL;\n  LeaveCriticalSection (&mutex->lock);\n  return 0;\n}\n\nint\nglwthread_mutex_destroy (glwthread_mutex_t *mutex)\n{\n  if (!mutex->guard.done)\n    return EINVAL;\n  DeleteCriticalSection (&mutex->lock);\n  mutex->guard.done = 0;\n  return 0;\n}\n"
  },
  {
    "path": "gnulib/windows-mutex.h",
    "content": "/* Plain mutexes (native Windows implementation).\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-win32.h.  */\n\n#ifndef _WINDOWS_MUTEX_H\n#define _WINDOWS_MUTEX_H\n\n#define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#include <windows.h>\n\n#include \"windows-initguard.h\"\n\ntypedef struct\n        {\n          glwthread_initguard_t guard; /* protects the initialization */\n          CRITICAL_SECTION lock;\n        }\n        glwthread_mutex_t;\n\n#define GLWTHREAD_MUTEX_INIT { GLWTHREAD_INITGUARD_INIT }\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nextern void glwthread_mutex_init (glwthread_mutex_t *mutex);\nextern int glwthread_mutex_lock (glwthread_mutex_t *mutex);\nextern int glwthread_mutex_trylock (glwthread_mutex_t *mutex);\nextern int glwthread_mutex_unlock (glwthread_mutex_t *mutex);\nextern int glwthread_mutex_destroy (glwthread_mutex_t *mutex);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _WINDOWS_MUTEX_H */\n"
  },
  {
    "path": "gnulib/windows-once.c",
    "content": "/* Once-only control (native Windows implementation).\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-win32.h.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include \"windows-once.h\"\n\n#include <stdlib.h>\n\nvoid\nglwthread_once (glwthread_once_t *once_control, void (*initfunction) (void))\n{\n  if (once_control->inited <= 0)\n    {\n      if (InterlockedIncrement (&once_control->started) == 0)\n        {\n          /* This thread is the first one to come to this once_control.  */\n          InitializeCriticalSection (&once_control->lock);\n          EnterCriticalSection (&once_control->lock);\n          once_control->inited = 0;\n          initfunction ();\n          once_control->inited = 1;\n          LeaveCriticalSection (&once_control->lock);\n        }\n      else\n        {\n          /* Don't let once_control->started grow and wrap around.  */\n          InterlockedDecrement (&once_control->started);\n          /* Some other thread has already started the initialization.\n             Yield the CPU while waiting for the other thread to finish\n             initializing and taking the lock.  */\n          while (once_control->inited < 0)\n            Sleep (0);\n          if (once_control->inited <= 0)\n            {\n              /* Take the lock.  This blocks until the other thread has\n                 finished calling the initfunction.  */\n              EnterCriticalSection (&once_control->lock);\n              LeaveCriticalSection (&once_control->lock);\n              if (!(once_control->inited > 0))\n                abort ();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "gnulib/windows-once.h",
    "content": "/* Once-only control (native Windows implementation).\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-win32.h.  */\n\n#ifndef _WINDOWS_ONCE_H\n#define _WINDOWS_ONCE_H\n\n#define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#include <windows.h>\n\ntypedef struct\n        {\n          volatile int inited;\n          volatile LONG started;\n          CRITICAL_SECTION lock;\n        }\n        glwthread_once_t;\n\n#define GLWTHREAD_ONCE_INIT { -1, -1 }\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nextern void glwthread_once (glwthread_once_t *once_control,\n                            void (*initfunction) (void));\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _WINDOWS_ONCE_H */\n"
  },
  {
    "path": "gnulib/windows-recmutex.c",
    "content": "/* Plain recursive mutexes (native Windows implementation).\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-win32.h.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include \"windows-recmutex.h\"\n\n#include <errno.h>\n\nvoid\nglwthread_recmutex_init (glwthread_recmutex_t *mutex)\n{\n  mutex->owner = 0;\n  mutex->depth = 0;\n  InitializeCriticalSection (&mutex->lock);\n  mutex->guard.done = 1;\n}\n\nint\nglwthread_recmutex_lock (glwthread_recmutex_t *mutex)\n{\n  if (!mutex->guard.done)\n    {\n      if (InterlockedIncrement (&mutex->guard.started) == 0)\n        /* This thread is the first one to need this mutex.  Initialize it.  */\n        glwthread_recmutex_init (mutex);\n      else\n        {\n          /* Don't let mutex->guard.started grow and wrap around.  */\n          InterlockedDecrement (&mutex->guard.started);\n          /* Yield the CPU while waiting for another thread to finish\n             initializing this mutex.  */\n          while (!mutex->guard.done)\n            Sleep (0);\n        }\n    }\n  {\n    DWORD self = GetCurrentThreadId ();\n    if (mutex->owner != self)\n      {\n        EnterCriticalSection (&mutex->lock);\n        mutex->owner = self;\n      }\n    if (++(mutex->depth) == 0) /* wraparound? */\n      {\n        mutex->depth--;\n        return EAGAIN;\n      }\n  }\n  return 0;\n}\n\nint\nglwthread_recmutex_trylock (glwthread_recmutex_t *mutex)\n{\n  if (!mutex->guard.done)\n    {\n      if (InterlockedIncrement (&mutex->guard.started) == 0)\n        /* This thread is the first one to need this mutex.  Initialize it.  */\n        glwthread_recmutex_init (mutex);\n      else\n        {\n          /* Don't let mutex->guard.started grow and wrap around.  */\n          InterlockedDecrement (&mutex->guard.started);\n          /* Let another thread finish initializing this mutex, and let it also\n             lock this mutex.  */\n          return EBUSY;\n        }\n    }\n  {\n    DWORD self = GetCurrentThreadId ();\n    if (mutex->owner != self)\n      {\n        if (!TryEnterCriticalSection (&mutex->lock))\n          return EBUSY;\n        mutex->owner = self;\n      }\n    if (++(mutex->depth) == 0) /* wraparound? */\n      {\n        mutex->depth--;\n        return EAGAIN;\n      }\n  }\n  return 0;\n}\n\nint\nglwthread_recmutex_unlock (glwthread_recmutex_t *mutex)\n{\n  if (mutex->owner != GetCurrentThreadId ())\n    return EPERM;\n  if (mutex->depth == 0)\n    return EINVAL;\n  if (--(mutex->depth) == 0)\n    {\n      mutex->owner = 0;\n      LeaveCriticalSection (&mutex->lock);\n    }\n  return 0;\n}\n\nint\nglwthread_recmutex_destroy (glwthread_recmutex_t *mutex)\n{\n  if (mutex->owner != 0)\n    return EBUSY;\n  DeleteCriticalSection (&mutex->lock);\n  mutex->guard.done = 0;\n  return 0;\n}\n"
  },
  {
    "path": "gnulib/windows-recmutex.h",
    "content": "/* Plain recursive mutexes (native Windows implementation).\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-win32.h.  */\n\n#ifndef _WINDOWS_RECMUTEX_H\n#define _WINDOWS_RECMUTEX_H\n\n#define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#include <windows.h>\n\n#include \"windows-initguard.h\"\n\n/* The native Windows documentation says that CRITICAL_SECTION already\n   implements a recursive lock.  But we need not rely on it: It's easy to\n   implement a recursive lock without this assumption.  */\n\ntypedef struct\n        {\n          glwthread_initguard_t guard; /* protects the initialization */\n          DWORD owner;\n          unsigned long depth;\n          CRITICAL_SECTION lock;\n        }\n        glwthread_recmutex_t;\n\n#define GLWTHREAD_RECMUTEX_INIT { GLWTHREAD_INITGUARD_INIT, 0, 0 }\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nextern void glwthread_recmutex_init (glwthread_recmutex_t *mutex);\nextern int glwthread_recmutex_lock (glwthread_recmutex_t *mutex);\nextern int glwthread_recmutex_trylock (glwthread_recmutex_t *mutex);\nextern int glwthread_recmutex_unlock (glwthread_recmutex_t *mutex);\nextern int glwthread_recmutex_destroy (glwthread_recmutex_t *mutex);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _WINDOWS_RECMUTEX_H */\n"
  },
  {
    "path": "gnulib/windows-rwlock.c",
    "content": "/* Read-write locks (native Windows implementation).\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-win32.h.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include \"windows-rwlock.h\"\n\n#include <errno.h>\n#include <stdlib.h>\n\n/* Don't assume that UNICODE is not defined.  */\n#undef CreateEvent\n#define CreateEvent CreateEventA\n\n/* In this file, the waitqueues are implemented as circular arrays.  */\n#define glwthread_waitqueue_t glwthread_carray_waitqueue_t\n\nstatic void\nglwthread_waitqueue_init (glwthread_waitqueue_t *wq)\n{\n  wq->array = NULL;\n  wq->count = 0;\n  wq->alloc = 0;\n  wq->offset = 0;\n}\n\n/* Enqueues the current thread, represented by an event, in a wait queue.\n   Returns INVALID_HANDLE_VALUE if an allocation failure occurs.  */\nstatic HANDLE\nglwthread_waitqueue_add (glwthread_waitqueue_t *wq)\n{\n  HANDLE event;\n  unsigned int index;\n\n  if (wq->count == wq->alloc)\n    {\n      unsigned int new_alloc = 2 * wq->alloc + 1;\n      HANDLE *new_array =\n        (HANDLE *) realloc (wq->array, new_alloc * sizeof (HANDLE));\n      if (new_array == NULL)\n        /* No more memory.  */\n        return INVALID_HANDLE_VALUE;\n      /* Now is a good opportunity to rotate the array so that its contents\n         starts at offset 0.  */\n      if (wq->offset > 0)\n        {\n          unsigned int old_count = wq->count;\n          unsigned int old_alloc = wq->alloc;\n          unsigned int old_offset = wq->offset;\n          unsigned int i;\n          if (old_offset + old_count > old_alloc)\n            {\n              unsigned int limit = old_offset + old_count - old_alloc;\n              for (i = 0; i < limit; i++)\n                new_array[old_alloc + i] = new_array[i];\n            }\n          for (i = 0; i < old_count; i++)\n            new_array[i] = new_array[old_offset + i];\n          wq->offset = 0;\n        }\n      wq->array = new_array;\n      wq->alloc = new_alloc;\n    }\n  /* Whether the created event is a manual-reset one or an auto-reset one,\n     does not matter, since we will wait on it only once.  */\n  event = CreateEvent (NULL, TRUE, FALSE, NULL);\n  if (event == INVALID_HANDLE_VALUE)\n    /* No way to allocate an event.  */\n    return INVALID_HANDLE_VALUE;\n  index = wq->offset + wq->count;\n  if (index >= wq->alloc)\n    index -= wq->alloc;\n  wq->array[index] = event;\n  wq->count++;\n  return event;\n}\n\n/* Notifies the first thread from a wait queue and dequeues it.  */\nstatic void\nglwthread_waitqueue_notify_first (glwthread_waitqueue_t *wq)\n{\n  SetEvent (wq->array[wq->offset + 0]);\n  wq->offset++;\n  wq->count--;\n  if (wq->count == 0 || wq->offset == wq->alloc)\n    wq->offset = 0;\n}\n\n/* Notifies all threads from a wait queue and dequeues them all.  */\nstatic void\nglwthread_waitqueue_notify_all (glwthread_waitqueue_t *wq)\n{\n  unsigned int i;\n\n  for (i = 0; i < wq->count; i++)\n    {\n      unsigned int index = wq->offset + i;\n      if (index >= wq->alloc)\n        index -= wq->alloc;\n      SetEvent (wq->array[index]);\n    }\n  wq->count = 0;\n  wq->offset = 0;\n}\n\nvoid\nglwthread_rwlock_init (glwthread_rwlock_t *lock)\n{\n  InitializeCriticalSection (&lock->lock);\n  glwthread_waitqueue_init (&lock->waiting_readers);\n  glwthread_waitqueue_init (&lock->waiting_writers);\n  lock->runcount = 0;\n  lock->guard.done = 1;\n}\n\nint\nglwthread_rwlock_rdlock (glwthread_rwlock_t *lock)\n{\n  if (!lock->guard.done)\n    {\n      if (InterlockedIncrement (&lock->guard.started) == 0)\n        /* This thread is the first one to need this lock.  Initialize it.  */\n        glwthread_rwlock_init (lock);\n      else\n        {\n          /* Don't let lock->guard.started grow and wrap around.  */\n          InterlockedDecrement (&lock->guard.started);\n          /* Yield the CPU while waiting for another thread to finish\n             initializing this lock.  */\n          while (!lock->guard.done)\n            Sleep (0);\n        }\n    }\n  EnterCriticalSection (&lock->lock);\n  /* Test whether only readers are currently running, and whether the runcount\n     field will not overflow, and whether no writer is waiting.  The latter\n     condition is because POSIX recommends that \"write locks shall take\n     precedence over read locks\", to avoid \"writer starvation\".  */\n  if (!(lock->runcount + 1 > 0 && lock->waiting_writers.count == 0))\n    {\n      /* This thread has to wait for a while.  Enqueue it among the\n         waiting_readers.  */\n      HANDLE event = glwthread_waitqueue_add (&lock->waiting_readers);\n      if (event != INVALID_HANDLE_VALUE)\n        {\n          DWORD result;\n          LeaveCriticalSection (&lock->lock);\n          /* Wait until another thread signals this event.  */\n          result = WaitForSingleObject (event, INFINITE);\n          if (result == WAIT_FAILED || result == WAIT_TIMEOUT)\n            abort ();\n          CloseHandle (event);\n          /* The thread which signalled the event already did the bookkeeping:\n             removed us from the waiting_readers, incremented lock->runcount.  */\n          if (!(lock->runcount > 0))\n            abort ();\n          return 0;\n        }\n      else\n        {\n          /* Allocation failure.  Weird.  */\n          do\n            {\n              LeaveCriticalSection (&lock->lock);\n              Sleep (1);\n              EnterCriticalSection (&lock->lock);\n            }\n          while (!(lock->runcount + 1 > 0));\n        }\n    }\n  lock->runcount++;\n  LeaveCriticalSection (&lock->lock);\n  return 0;\n}\n\nint\nglwthread_rwlock_wrlock (glwthread_rwlock_t *lock)\n{\n  if (!lock->guard.done)\n    {\n      if (InterlockedIncrement (&lock->guard.started) == 0)\n        /* This thread is the first one to need this lock.  Initialize it.  */\n        glwthread_rwlock_init (lock);\n      else\n        {\n          /* Don't let lock->guard.started grow and wrap around.  */\n          InterlockedDecrement (&lock->guard.started);\n          /* Yield the CPU while waiting for another thread to finish\n             initializing this lock.  */\n          while (!lock->guard.done)\n            Sleep (0);\n        }\n    }\n  EnterCriticalSection (&lock->lock);\n  /* Test whether no readers or writers are currently running.  */\n  if (!(lock->runcount == 0))\n    {\n      /* This thread has to wait for a while.  Enqueue it among the\n         waiting_writers.  */\n      HANDLE event = glwthread_waitqueue_add (&lock->waiting_writers);\n      if (event != INVALID_HANDLE_VALUE)\n        {\n          DWORD result;\n          LeaveCriticalSection (&lock->lock);\n          /* Wait until another thread signals this event.  */\n          result = WaitForSingleObject (event, INFINITE);\n          if (result == WAIT_FAILED || result == WAIT_TIMEOUT)\n            abort ();\n          CloseHandle (event);\n          /* The thread which signalled the event already did the bookkeeping:\n             removed us from the waiting_writers, set lock->runcount = -1.  */\n          if (!(lock->runcount == -1))\n            abort ();\n          return 0;\n        }\n      else\n        {\n          /* Allocation failure.  Weird.  */\n          do\n            {\n              LeaveCriticalSection (&lock->lock);\n              Sleep (1);\n              EnterCriticalSection (&lock->lock);\n            }\n          while (!(lock->runcount == 0));\n        }\n    }\n  lock->runcount--; /* runcount becomes -1 */\n  LeaveCriticalSection (&lock->lock);\n  return 0;\n}\n\nint\nglwthread_rwlock_tryrdlock (glwthread_rwlock_t *lock)\n{\n  if (!lock->guard.done)\n    {\n      if (InterlockedIncrement (&lock->guard.started) == 0)\n        /* This thread is the first one to need this lock.  Initialize it.  */\n        glwthread_rwlock_init (lock);\n      else\n        {\n          /* Don't let lock->guard.started grow and wrap around.  */\n          InterlockedDecrement (&lock->guard.started);\n          /* Yield the CPU while waiting for another thread to finish\n             initializing this lock.  */\n          while (!lock->guard.done)\n            Sleep (0);\n        }\n    }\n  /* It's OK to wait for this critical section, because it is never taken for a\n     long time.  */\n  EnterCriticalSection (&lock->lock);\n  /* Test whether only readers are currently running, and whether the runcount\n     field will not overflow, and whether no writer is waiting.  The latter\n     condition is because POSIX recommends that \"write locks shall take\n     precedence over read locks\", to avoid \"writer starvation\".  */\n  if (!(lock->runcount + 1 > 0 && lock->waiting_writers.count == 0))\n    {\n      /* This thread would have to wait for a while.  Return instead.  */\n      LeaveCriticalSection (&lock->lock);\n      return EBUSY;\n    }\n  lock->runcount++;\n  LeaveCriticalSection (&lock->lock);\n  return 0;\n}\n\nint\nglwthread_rwlock_trywrlock (glwthread_rwlock_t *lock)\n{\n  if (!lock->guard.done)\n    {\n      if (InterlockedIncrement (&lock->guard.started) == 0)\n        /* This thread is the first one to need this lock.  Initialize it.  */\n        glwthread_rwlock_init (lock);\n      else\n        {\n          /* Don't let lock->guard.started grow and wrap around.  */\n          InterlockedDecrement (&lock->guard.started);\n          /* Yield the CPU while waiting for another thread to finish\n             initializing this lock.  */\n          while (!lock->guard.done)\n            Sleep (0);\n        }\n    }\n  /* It's OK to wait for this critical section, because it is never taken for a\n     long time.  */\n  EnterCriticalSection (&lock->lock);\n  /* Test whether no readers or writers are currently running.  */\n  if (!(lock->runcount == 0))\n    {\n      /* This thread would have to wait for a while.  Return instead.  */\n      LeaveCriticalSection (&lock->lock);\n      return EBUSY;\n    }\n  lock->runcount--; /* runcount becomes -1 */\n  LeaveCriticalSection (&lock->lock);\n  return 0;\n}\n\nint\nglwthread_rwlock_unlock (glwthread_rwlock_t *lock)\n{\n  if (!lock->guard.done)\n    return EINVAL;\n  EnterCriticalSection (&lock->lock);\n  if (lock->runcount < 0)\n    {\n      /* Drop a writer lock.  */\n      if (!(lock->runcount == -1))\n        abort ();\n      lock->runcount = 0;\n    }\n  else\n    {\n      /* Drop a reader lock.  */\n      if (!(lock->runcount > 0))\n        {\n          LeaveCriticalSection (&lock->lock);\n          return EPERM;\n        }\n      lock->runcount--;\n    }\n  if (lock->runcount == 0)\n    {\n      /* POSIX recommends that \"write locks shall take precedence over read\n         locks\", to avoid \"writer starvation\".  */\n      if (lock->waiting_writers.count > 0)\n        {\n          /* Wake up one of the waiting writers.  */\n          lock->runcount--;\n          glwthread_waitqueue_notify_first (&lock->waiting_writers);\n        }\n      else\n        {\n          /* Wake up all waiting readers.  */\n          lock->runcount += lock->waiting_readers.count;\n          glwthread_waitqueue_notify_all (&lock->waiting_readers);\n        }\n    }\n  LeaveCriticalSection (&lock->lock);\n  return 0;\n}\n\nint\nglwthread_rwlock_destroy (glwthread_rwlock_t *lock)\n{\n  if (!lock->guard.done)\n    return EINVAL;\n  if (lock->runcount != 0)\n    return EBUSY;\n  DeleteCriticalSection (&lock->lock);\n  if (lock->waiting_readers.array != NULL)\n    free (lock->waiting_readers.array);\n  if (lock->waiting_writers.array != NULL)\n    free (lock->waiting_writers.array);\n  lock->guard.done = 0;\n  return 0;\n}\n"
  },
  {
    "path": "gnulib/windows-rwlock.h",
    "content": "/* Read-write locks (native Windows implementation).\n   Copyright (C) 2005-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Bruno Haible <bruno@clisp.org>, 2005.\n   Based on GCC's gthr-win32.h.  */\n\n#ifndef _WINDOWS_RWLOCK_H\n#define _WINDOWS_RWLOCK_H\n\n#define WIN32_LEAN_AND_MEAN  /* avoid including junk */\n#include <windows.h>\n\n#include \"windows-initguard.h\"\n\n/* It is impossible to implement read-write locks using plain locks, without\n   introducing an extra thread dedicated to managing read-write locks.\n   Therefore here we need to use the low-level Event type.  */\n\ntypedef struct\n        {\n          HANDLE *array; /* array of waiting threads, each represented by an event */\n          unsigned int count; /* number of waiting threads */\n          unsigned int alloc; /* length of allocated array */\n          unsigned int offset; /* index of first waiting thread in array */\n        }\n        glwthread_carray_waitqueue_t;\ntypedef struct\n        {\n          glwthread_initguard_t guard; /* protects the initialization */\n          CRITICAL_SECTION lock; /* protects the remaining fields */\n          glwthread_carray_waitqueue_t waiting_readers; /* waiting readers */\n          glwthread_carray_waitqueue_t waiting_writers; /* waiting writers */\n          int runcount; /* number of readers running, or -1 when a writer runs */\n        }\n        glwthread_rwlock_t;\n\n#define GLWTHREAD_RWLOCK_INIT { GLWTHREAD_INITGUARD_INIT }\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nextern void glwthread_rwlock_init (glwthread_rwlock_t *lock);\nextern int glwthread_rwlock_rdlock (glwthread_rwlock_t *lock);\nextern int glwthread_rwlock_wrlock (glwthread_rwlock_t *lock);\nextern int glwthread_rwlock_tryrdlock (glwthread_rwlock_t *lock);\nextern int glwthread_rwlock_trywrlock (glwthread_rwlock_t *lock);\nextern int glwthread_rwlock_unlock (glwthread_rwlock_t *lock);\nextern int glwthread_rwlock_destroy (glwthread_rwlock_t *lock);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _WINDOWS_RWLOCK_H */\n"
  },
  {
    "path": "gnulib/wmemchr-impl.h",
    "content": "/* Search wide character array for a wide character.\n   Copyright (C) 1999, 2011-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 1999.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\nwchar_t *\nwmemchr (const wchar_t *s, wchar_t c, size_t n)\n{\n  for (; n > 0; s++, n--)\n    {\n      if (*s == c)\n        return (wchar_t *) s;\n    }\n  return NULL;\n}\n"
  },
  {
    "path": "gnulib/wmemchr.c",
    "content": "/* Search wide character array for a wide character.\n   Copyright (C) 2011-2021 Free Software Foundation, Inc.\n   Written by Bruno Haible <bruno@clisp.org>, 2011.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <wchar.h>\n\n#include \"wmemchr-impl.h\"\n"
  },
  {
    "path": "gnulib/wmempcpy.c",
    "content": "/* Copy wide character array, return pointer after last written wide character.\n   Copyright (C) 2020-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#include <config.h>\n\n/* Specification.  */\n#include <wchar.h>\n\n/* Copy N wide characters of SRC to DEST.\n   Return pointer to wide characters after the last written wide character.  */\nwchar_t *\nwmempcpy (wchar_t *dest, const wchar_t *src, size_t n)\n{\n  return wmemcpy (dest, src, n) + n;\n}\n"
  },
  {
    "path": "libreadtags/.circleci/config.yml",
    "content": "version: 2\njobs:\n  fedora40_cmake:\n    working_directory: ~/libreadtags\n    docker:\n      - image: docker.io/fedora:40\n    steps:\n      - run:\n          name: Install Git\n          command: |\n            yum -y install git\n      - checkout\n      - run:\n          name: Install build tools\n          command: |\n            yum -y install gcc cmake\n      - run:\n          name: Build\n          command: |\n            mkdir build\n            cmake -DCMAKE_BUILD_TYPE=Release -DLIBREADTAGS_BUILD_SHARED=ON -S . -B build\n            cmake --build build --target readtags\n      - run:\n          name: Build test cases\n          command: |\n            cmake --build build\n      - run:\n          name: Run the test cases\n          command: |\n            ctest --test-dir build || cat build/Testing/Temporary/LastTest.log\n      - run:\n          name: Install\n          command: |\n            cmake --build build --target install\n            test -e /usr/local/include/readtags.h\n            test -e /usr/local/lib/libreadtags.so\n  fedora40_autotools:\n    working_directory: ~/libreadtags\n    docker:\n      - image: docker.io/fedora:40\n    steps:\n      - run:\n          name: Install Git\n          command: |\n            yum -y install git\n      - checkout\n      - run:\n          name: Install build tools\n          command: |\n            yum -y install gcc automake autoconf libtool make\n      - run:\n          name: Build\n          command: |\n            bash ./autogen.sh\n            ./configure\n            make\n      - run:\n          name: Test\n          command: |\n            make check VERBOSE=1\n  fedora40_distcheck:\n    working_directory: ~/libreadtags\n    docker:\n      - image: docker.io/fedora:40\n    steps:\n      - run:\n          name: Install Git\n          command: |\n            yum -y install git\n      - checkout\n      - run:\n          name: Install build tools\n          command: |\n            yum -y install gcc automake autoconf libtool make\n      - run:\n          name: Build\n          command: |\n            bash ./autogen.sh\n            ./configure\n      - run:\n          name: Test\n          command: |\n            make distcheck\nworkflows:\n  version: 2\n  build_and_test:\n    jobs:\n      - fedora40_cmake\n      - fedora40_autotools\n      - fedora40_distcheck\n"
  },
  {
    "path": "libreadtags/.dir-locals.el",
    "content": ";; Don't forget putting (add-hook 'hack-local-variables-hook (lambda () (editorconfig-apply))) to your .emacs.\n((c-mode . ((c-file-style . \"linux\"))))\n"
  },
  {
    "path": "libreadtags/.editorconfig",
    "content": "root = true\n\n[*]\nend_of_line = lf\ninsert_final_newline = true\n\n[*.{c,h,sh}]\nindent_size = 4\nindent_style = tab\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": "libreadtags/.github/workflows/msys2.yml",
    "content": "#\n# Derrived from .github/workflows/testing-msys2.yml of universal-ctags/ctags repo\n#\nname: run test cases on MSYS2\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n    runs-on: windows-latest\n\n    strategy:\n      matrix:\n        msystem: [MSYS, MINGW32, MINGW64]\n\n    defaults:\n      run:\n        shell: msys2 {0}\n\n    steps:\n    - uses: msys2/setup-msys2@v2\n      with:\n        msystem: ${{ matrix.msystem }}\n        update: true\n        install: git make automake1.16 autoconf libtool\n\n    - if:  matrix.msystem == 'MSYS'\n      run: pacman -S --noconfirm gcc\n\n    - if:  matrix.msystem == 'MINGW32'\n      run: pacman -S --noconfirm mingw-w64-i686-toolchain\n\n    - if:  matrix.msystem == 'MINGW64'\n      run: pacman -S --noconfirm mingw-w64-x86_64-toolchain\n\n    - run: ln -s /usr/bin/automake-1.16 /usr/bin/automake\n    - run: ln -s /usr/bin/aclocal-1.16  /usr/bin/aclocal\n\n    - run: git config --global core.autocrlf input\n      shell: bash\n    - uses: actions/checkout@v2\n\n    - run: ./autogen.sh\n    - run: ./configure --prefix=/usr\n    - run: make V=1\n    - run: make check V=1\n    - run: cat tests/test-suite.log\n      if: failure()\n    - run: for x in tests/*.log; do echo '#' $x; cat $x; done\n      if: failure()\n"
  },
  {
    "path": "libreadtags/.gitignore",
    "content": ".deps\n.libs\n*.a\n*.gcda\n*.gcno\n*.gcov\n*.la\n*.lo\n*.o\n*.pc\n*.so\n*.tar.gz\n*~\naclocal.m4\nautom4te.cache\ncompile\nconfig.guess\nconfig.log\nconfig.status\nconfig.status\nconfig.sub\nconfigure\ndepcomp\ninstall-sh\nlibtool\nltmain.sh\nm4\nMakefile\nMakefile.in\nmissing\ntest-driver\n\ntests/*.log\ntests/*.trs\ntests/test-api-tagsClose\ntests/test-api-tagsFind\ntests/test-api-tagsFirst\ntests/test-api-tagsFindPseudoTag\ntests/test-api-tagsFirstPseudoTag\ntests/test-api-tagsOpen\ntests/test-api-tagsSetSortType\ntests/test-fix-large-tags\ntests/test-fix-null-deref\ntests/test-fix-unescaping\ntests/test-fix-unescaping-input-fields\ntests/test-fix-unescaping-input-fields-exuberant\ntests/test-fix-unescaping-input-fields-no-mode\ntests/test-fix-unescaping-input-fields-backslash\ntests/test-fix-unescaping-input-fields-no-filesep\n\nbuild\n"
  },
  {
    "path": "libreadtags/.indent.pro",
    "content": "--blank-before-sizeof\n--blank-lines-after-procedures\n--brace-indent0\n--braces-after-if-line\n--braces-on-struct-decl-line\n--break-after-boolean-operator\n--case-brace-indentation0\n--case-indentation0\n--comment-indentation0\n--continuation-indentation4\n--cuddle-do-while\n--declaration-comment-column0\n--declaration-indentation0\n--dont-break-function-decl-args\n--dont-break-procedure-type\n--dont-line-up-parentheses\n--honour-newlines\n--indent-level4\n--line-length80\n--paren-indentation4\n--preprocessor-indentation1\n--no-blank-lines-after-commas\n--space-after-cast\n--space-after-for\n--space-after-if\n--space-after-procedure-calls\n--space-after-while\n--space-special-semicolon\n--start-left-side-of-comments\n--struct-brace-indentation4\n--tab-size4\n"
  },
  {
    "path": "libreadtags/.uncrustify.cfg",
    "content": "tok_split_gte=false\nutf8_byte=false\nutf8_force=false\nindent_cmt_with_tabs=false\nindent_align_string=false\nindent_braces=false\nindent_braces_no_func=false\nindent_braces_no_class=false\nindent_braces_no_struct=false\nindent_brace_parent=false\nindent_namespace=false\nindent_extern=false\nindent_class=false\nindent_class_colon=false\nindent_else_if=false\nindent_var_def_cont=false\nindent_func_call_param=false\nindent_func_def_param=false\nindent_func_proto_param=false\nindent_func_class_param=false\nindent_func_ctor_var_param=false\nindent_template_param=false\nindent_func_param_double=false\nindent_relative_single_line_comments=false\nindent_col1_comment=false\nindent_access_spec_body=false\nindent_paren_nl=false\nindent_comma_paren=false\nindent_bool_paren=false\nindent_first_bool_expr=false\nindent_square_nl=false\nindent_preserve_sql=false\nindent_align_assign=true\nsp_balance_nested_parens=false\nalign_keep_tabs=false\nalign_with_tabs=false\nalign_on_tabstop=false\nalign_number_left=false\nalign_func_params=false\nalign_same_func_call_params=false\nalign_var_def_colon=false\nalign_var_def_attribute=false\nalign_var_def_inline=false\nalign_right_cmt_mix=false\nalign_on_operator=false\nalign_mix_var_proto=false\nalign_single_line_func=false\nalign_single_line_brace=false\nalign_nl_cont=false\nalign_left_shift=true\nalign_oc_decl_colon=false\nnl_collapse_empty_body=false\nnl_assign_leave_one_liners=false\nnl_class_leave_one_liners=false\nnl_enum_leave_one_liners=false\nnl_getset_leave_one_liners=false\nnl_func_leave_one_liners=false\nnl_if_leave_one_liners=false\nnl_multi_line_cond=false\nnl_multi_line_define=false\nnl_before_case=false\nnl_after_case=false\nnl_after_return=false\nnl_after_semicolon=false\nnl_after_brace_open=false\nnl_after_brace_open_cmt=false\nnl_after_vbrace_open=false\nnl_after_vbrace_open_empty=false\nnl_after_brace_close=false\nnl_after_vbrace_close=false\nnl_define_macro=false\nnl_squeeze_ifdef=false\nnl_ds_struct_enum_cmt=false\nnl_ds_struct_enum_close_brace=false\nnl_create_if_one_liner=false\nnl_create_for_one_liner=false\nnl_create_while_one_liner=false\nls_for_split_full=false\nls_func_split_full=false\nnl_after_multiline_comment=false\neat_blanks_after_open_brace=false\neat_blanks_before_close_brace=false\nmod_full_brace_if_chain=false\nmod_pawn_semicolon=false\nmod_full_paren_if_bool=false\nmod_remove_extra_semicolon=false\nmod_sort_import=false\nmod_sort_using=false\nmod_sort_include=false\nmod_move_case_break=false\nmod_remove_empty_return=false\ncmt_indent_multi=true\ncmt_c_group=false\ncmt_c_nl_start=false\ncmt_c_nl_end=false\ncmt_cpp_group=false\ncmt_cpp_nl_start=false\ncmt_cpp_nl_end=false\ncmt_cpp_to_c=false\ncmt_star_cont=false\ncmt_multi_check_last=true\ncmt_insert_before_preproc=false\npp_indent_at_level=false\npp_region_indent_code=false\npp_if_indent_code=false\npp_define_at_level=false\ninput_tab_size=4\noutput_tab_size=4\nindent_columns=4\nindent_brace=0\nindent_switch_case=4\nnl_after_func_body=2\nnl_after_func_body_one_liner=2\nindent_with_tabs=1\nsp_arith=add\nsp_assign=add\nsp_assign_default=add\nsp_enum_assign=add\nsp_bool=add\nsp_compare=add\nsp_inside_paren=remove\nsp_paren_paren=remove\nsp_before_ptr_star=force\nsp_between_ptr_star=remove\nsp_after_ptr_star=remove\nsp_after_ptr_star_func=remove\nsp_before_sparen=force\nsp_before_semi_for_empty=force\nsp_before_square=add\nsp_before_squares=add\nsp_after_cast=force\nsp_sizeof_paren=force\nsp_func_call_paren=force\nsp_return_paren=force\nsp_not=force\nnl_start_of_file=remove\nnl_end_of_file=remove\nnl_enum_brace=remove\nnl_struct_brace=remove\nnl_union_brace=remove\nnl_if_brace=add\nnl_brace_else=add\nnl_elseif_brace=add\nnl_else_brace=add\nnl_else_if=remove\nnl_for_brace=add\nnl_while_brace=add\nnl_do_brace=add\nnl_brace_while=remove\nnl_switch_brace=add\nnl_fdef_brace=force\n"
  },
  {
    "path": "libreadtags/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.22)\nproject(\n        readtags\n\t#\n\t# Synchronize VERSION with the value in configure.ac.\n        VERSION 0.4.0\n        DESCRIPTION \"a library for looking up tag entries in tag files\"\n        HOMEPAGE_URL \"https://github.com/universal-ctags/libreadtags\"\n        LANGUAGES C\n)\n\nset(CMAKE_C_STANDARD 99)\n\noption(LIBREADTAGS_BUILD_SHARED \"Build shared/static library\" OFF)\n\n# You don't have to edit API_VERSION.\n# See https://cmake.org/cmake/help/latest/command/cmake_file_api.html\nset(API_VERSION 1)\n#\n# Synchronize BUILD_VERSION with the value appended to libreadtags.so.<>.\n# that is built with Autotools.\nset(BUILD_VERSION 1.1.2)\n\n# Taken from https://gitlab.kitware.com/cmake/community/-/wikis/contrib/macros/TestInline\n# Inspired from /usr/share/autoconf/autoconf/c.m4\nforeach(KEYWORD \"inline\" \"__inline__\" \"__inline\")\n  if(NOT DEFINED C_INLINE)\n    try_compile(C_HAS_${KEYWORD} \"${CMAKE_CURRENT_BINARY_DIR}\"\n      \"${CMAKE_CURRENT_SOURCE_DIR}/test_inline.c\"\n      COMPILE_DEFINITIONS \"-Dinline=${KEYWORD}\")\n    if(C_HAS_${KEYWORD})\n      SET(C_INLINE TRUE)\n      ADD_DEFINITIONS(\"-Dinline=${KEYWORD}\")\n    endif(C_HAS_${KEYWORD})\n  endif(NOT DEFINED C_INLINE)\nendforeach(KEYWORD)\nif(NOT DEFINED C_INLINE)\n  ADD_DEFINITIONS(\"-Dinline=\")\nendif(NOT DEFINED C_INLINE)\n\nif (LIBREADTAGS_BUILD_SHARED)\n    message(STATUS \"Building shared library\")\n    add_library(${PROJECT_NAME} SHARED readtags.c)\n    set_target_properties(${PROJECT_NAME} PROPERTIES\n            VERSION ${BUILD_VERSION}\n            SOVERSION ${API_VERSION}\n            PUBLIC_HEADER readtags.h\n    )\n    install(TARGETS ${PROJECT_NAME}\n            LIBRARY DESTINATION lib\n            PUBLIC_HEADER DESTINATION include\n    )\nelse ()\n    message(STATUS \"Building static library\")\n    add_library(${PROJECT_NAME} STATIC readtags.c)\n    install(TARGETS ${PROJECT_NAME}\n            ARCHIVE DESTINATION lib\n            PUBLIC_HEADER DESTINATION include\n    )\nendif ()\n\nadd_library(universal-ctags::${PROJECT_NAME} ALIAS ${PROJECT_NAME})\n\ntarget_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\n\nenable_testing()\nset(test_cases\n  test-api-tagsOpen\n  test-api-tagsFind\n  test-api-tagsFindPseudoTag\n  test-api-tagsFirstPseudoTag\n  test-api-tagsFirst\n  test-api-tagsClose\n  test-api-tagsSetSortType\n\n  test-fix-unescaping\n  test-fix-null-deref\n  test-fix-large-tags\n  test-fix-unescaping-input-fields\n  test-fix-unescaping-input-fields-exuberant\n  test-fix-unescaping-input-fields-no-mode\n  test-fix-unescaping-input-fields-backslash\n  test-fix-unescaping-input-fields-no-filesep\n)\n\nforeach(t IN LISTS test_cases)\n  add_executable(${t} tests/${t}.c)\n  target_link_libraries(${t} readtags)\n  add_test(NAME ${t}\n    COMMAND ${t}\n    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests)\nendforeach()\n\n#\n# TODO:\n#\n# * Support find_package\n#\n#   ParticleG's comments quoted from\n#   https://github.com/universal-ctags/libreadtags/pull/51#issuecomment-2148017962\n#\n#      Actually, if we prepare CMakeList.txt properly, other CMake projects\n#      just need to use find_package method to load this package, see\n#      Finding Packages. But if you use CMake method FetchContent to add\n#      libreadtags to your project, then current changes should be enough.\n#\n"
  },
  {
    "path": "libreadtags/Makefile.am",
    "content": "AUTOMAKE_OPTIONS = foreign\nACLOCAL_AMFLAGS = -I m4\n\nAM_CFLAGS=-Wall\n\nEXTRA_DIST = README.md NEWS.md CMakeLists.txt test_inline.c\n\nlib_LTLIBRARIES    = libreadtags.la\nlibreadtags_la_LDFLAGS = -no-undefined -version-info $(LT_VERSION)\nlibreadtags_la_CFLAGS  = $(GCOV_CFLAGS)\n\nlibreadtags_la_SOURCES = readtags.c readtags.h\nnobase_include_HEADERS = readtags.h\n\nEXTRA_DIST += libreadtags.pc.in\npkgconfigdir = $(libdir)/pkgconfig\npkgconfig_DATA = libreadtags.pc\n\nSUBDIRS = . tests\n"
  },
  {
    "path": "libreadtags/NEWS.md",
    "content": "# Version XXX\n\n- imporve performance; put inline keyword on a hot spot function.\n\n\t- before this change\n\n\t\t```\n\t\t$ /bin/time ./readtags -t ~/.citre/kernel82.tags -l > /dev/null\n\t\t9.59user 0.42system 0:10.06elapsed 99%CPU (0avgtext+0avgdata 2819340maxresident)k\n\t\t0inputs+0outputs (0major+44149minor)pagefaults 0swaps\n\t\t```\n\n\t- after this change\n\n\t\t```\n\t\t$ /bin/time ./readtags -t ~/.citre/kernel82.tags -l > /dev/null\n\t\t7.82user 0.43system 0:08.30elapsed 99%CPU (0avgtext+0avgdata 2819688maxresident)k\n\t\t0inputs+0outputs (0major+44138minor)pagefaults 0swaps\n\t\t```\n\n# Version 0.4.0\n\n- support cmake as a build system (ParticleG <particle_g@outlook.com>)\n\n- add libreadtags-uninstalled.pc.in.\n\n# Version 0.3.0\n\n- fix calls to ctype functions (Colomban Wendling <ban@herbesfolles.org>)\n\n- read input fields, values at the second column in a tag file, with\n  unescaping if !_TAG_OUTPUT_MODE is \"u-ctags\" and\n  !_TAG_OUTPUT_FILESEP is \"slash\" in the tag file.\n\n- LT_VERSION 2:2:1\n\n\t- no change in public interface\n\n# Version 0.2.1\n\n- use \"m\" mode flag of fopen only when compiling with glibc 2.3 or higher.\n\n- LT_VERSION 2:1:1\n\n\t- no change in public interface\n\n# Version 0.2.0\n\n- delete debug output automatically printed when DEBUG is defiend in\n  build-time.\n\n- fix potential crashes trigged when passing NULL as `file` parameter\n  to the API functions. Provided by rootkea (GitHub account).\n\n- add a new error constant `TagErrnoFileMaybeTooBig` to represent\n  the case that the given tags file is too large for the platform APIs\n  (ftell and fseek) used in libreadtags.\n  See https://github.com/universal-ctags/libreadtags/issues/36 about the\n  background of this change.\n\n- allow the library to read larger (> 2G) tag files on Win32 platform.\n  The tag file size was limited to 2G on the platform because the library\n  used fseek and ftell. In this version, they are replaced with _fseeki64 and\n  _ftelli64.\n\n- add a new API function (tagsFindPseudoTag) for finding a pseudo tag for\n  given name.\n\n- Use mmap(2) when opening a tags file if fopen() supports \"m\" mode flag.\n\n- LT_VERSION 2:0:1\n\n\t- extend the API\n\n\t\t- add a constant: TagErrnoFileMaybeTooBig\n\t\t- add a function: tagsFindPseudoTag\n\n# Version 0.1.0\n\n- propagate internal errors to caller\n\n- LT_VERSION 1:0:0\n\n\t- extend the API for the error propagation\n\n\t\t- add tagsGetErrno function\n\t\t- add tagErrno eum type\n\n\t- break the API\n\n\t\t- rename sortType to tagSortType for avoiding name conflictions\n\t\t  However, sortType is still defined as a macro.\n\t\t  See readtags.h\n"
  },
  {
    "path": "libreadtags/README.md",
    "content": "# libreadtags\n\nlibreadtags is a library for reading tags files generated by ctags.\nlibreadtags assumes the tags file format explained in [tags(5)](https://docs.ctags.io/en/latest/man/tags.5.html)\nof Universal-ctags.\n\nSee the comments at the top of readtags.h about the license and copyright.\nlibreadtags was derived from readtags.c of Exuberant-ctags.\n\nNEWS.md describes note worty changes.\n\nIf you are looking for command line interface for tags files,\nyou will like [readtags command](https://docs.ctags.io/en/latest/man/readtags.1.html)\nshipped as part of Universal-ctags. It uses libreadtags extensively.\n\nYou can build libreadtags with GNU Autotools and CMake.\n\n## Autotools Usage\n\n### Build\n```shell\ntest -e autogen.sh && ./autogen.sh\n./configure\nmake\n```\n\n### Test\n```shell\nmake check\n```\n\n\n## CMake Usage\n\n### Build as a standalone project\n\n#### Configure and build only\n\n```shell\nmkdir build\ncmake -DCMAKE_BUILD_TYPE=Release -DLIBREADTAGS_BUILD_SHARED=ON -S . -B build\ncmake --build build --target readtags\n```\n\n#### Configure, build, and test\n```shell\nmkdir build\ncmake -DCMAKE_BUILD_TYPE=Release -DLIBREADTAGS_BUILD_SHARED=ON -S . -B build\ncmake --build build\nctest --test-dir build\n```\n\n#### Configure and install\n\nThis will install the library and headers to `/usr/local`.\n\n```shell\nmkdir build\ncmake -DCMAKE_BUILD_TYPE=Release -DLIBREADTAGS_BUILD_SHARED=ON -S . -B build\nsudo cmake --build build --target install\n```\n\n### Integrate into other CMake projects\n\n```cmake\ninclude(FetchContent)\n\nFetchContent_Declare(\n        readtags\n        GIT_REPOSITORY https://github.com/universal-ctags/libreadtags.git\n        GIT_TAG master\n)\n\nFetchContent_MakeAvailable(readtags)\n\ntarget_link_libraries(your_target PRIVATE universal-ctags::readtags)\n```\n"
  },
  {
    "path": "libreadtags/autogen.sh",
    "content": "#!/bin/sh\n\nset -xe\n\nfor c in autoconf automake libtoolize autoreconf; do\n\ttype $c || exit 1\ndone\n\nautoreconf -vfi\n"
  },
  {
    "path": "libreadtags/configure.ac",
    "content": "# -*- Autoconf -*-\n#\n# When updating the above version, you also update VERSION in CMakeList.txt.\nAC_INIT(libreadtags, 0.4.0)\nAC_CONFIG_MACRO_DIR([m4])\nAC_CONFIG_SRCDIR([readtags.c])\n\nAM_INIT_AUTOMAKE\nAC_PROG_LIBTOOL\n\n# LT_VERSION => CURRENT[:REVISION[:AGE]]\n#\n# (the following instructions are taken from configure.ac in libskk\n#  See also \"7 Library interface versions\" in the libtool info document.)\n#\n# If library source has changed since last release, increment revision\n# If public symbols have been added, removed or changed since last release,\n#  increment current and set revision to 0\n# If public symbols have been added since last release, increment age\n# If public symbols have been removed since last release, set age to 0\n#\n# Revision history\n#\n# 0:0:0\n#    initial version; API is the same as readtags.h in Exuberant-ctags.\n#    (libreadtags.so.0.0.0)\n#\n# 1:0:0\n#    introduced tagsGetErrno() and tagErrno.\n#    rename sortType to tagSortType.\n#    (libreadtags.so.1.0.0)\n#\n# 2:0:1\n#    introduced TagErrnoFileMayTooBig.\n#    introduced tagsFindPseudoTag.\n#    (libreadtags.so.1.1.0)\n#\n# 2:1:1\n#    no change in public interface.\n#    (libreadtags.so.1.1.1)\n#\n# 2:2:1\n#    no change in public interface.\n#    (libreadtags.so.1.1.2)\n#\n# When updating LT_VERSION, update BUILD_VERSION of CMakeLists.txt.\n#\nAC_SUBST(LT_VERSION, [2:2:1])\n\nAC_ARG_ENABLE([gcov],\n\t[AS_HELP_STRING([--enable-gcov],\n\t\t[enable 'gcov' coverage testing tool [no]])])\nif test \"${enable_gcov}\" = \"yes\"; then\n\tGCOV_CFLAGS=\"--coverage\"\nfi\nAC_SUBST([GCOV_CFLAGS])\n\nAC_PROG_CC_C99\nAC_C_INLINE\n\nAC_CONFIG_FILES([Makefile\n\t\tlibreadtags.pc\n\t\tlibreadtags-uninstalled.pc\n\t\ttests/Makefile])\nAC_OUTPUT\n"
  },
  {
    "path": "libreadtags/libreadtags-uninstalled.pc.in",
    "content": "abs_top_srcdir=@abs_top_srcdir@\nabs_top_builddir=@abs_top_builddir@\n\nprefix=\nexec_prefix=\nlibdir=${abs_top_builddir}\nincludedir=${abs_top_builddir}\n\nName: libreadtags Uninstalled\nDescription: a library for looking up tag entries in tag files (Uninstalled)\nVersion: @VERSION@\nRequires:\nLibs: -L${libdir} -lreadtags\nCflags: -I${includedir}\n"
  },
  {
    "path": "libreadtags/libreadtags.pc.in",
    "content": "prefix=@prefix@\nexec_prefix=@exec_prefix@\nlibdir=@libdir@\nincludedir=@includedir@\n\nName: libreadtags\nDescription: a library for looking up tag entries in tag files\nVersion: @VERSION@\nRequires:\nLibs: -L${libdir} -lreadtags\nCflags: -I${includedir}\n"
  },
  {
    "path": "libreadtags/readtags.c",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   This source code is released into the public domain.\n*\n*   This module contains functions for reading tag files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#ifdef HAVE_CTAGS_INLINE_H\n/* the build script of ctags can insert thee macro\n   definition for READTAGS_INLINE. */\n#include \"inline.h\"\n#else\n/* Makefile generated by configure defines inline. */\n#define READTAGS_INLINE static inline\n#endif\n\n#include <stdlib.h>\n#include <string.h>\n#include <ctype.h>\n#include <stdio.h>\n#include <errno.h>\n#include <sys/types.h>  /* to declare off_t */\n\n#include \"readtags.h\"\n\n/*\n*   MACROS\n*/\n#define TAB '\\t'\n\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef struct {\n\tsize_t size;\n\tchar *buffer;\n} vstring;\n\n/* Define readtags' own off_t. */\n#ifdef _WIN32\ntypedef long long rt_off_t;\n#else\ntypedef off_t rt_off_t;\n#endif\n\n/* Information about current tag file */\nstruct sTagFile {\n\t\t/* has the file been opened and this structure initialized? */\n\tunsigned char initialized;\n\t\t/* format of tag file */\n\tunsigned char format;\n\t\t/* 1 \"u-ctags\" is set to !_TAG_OUTPUT_MODE pseudo tag\n\t\t * and \"slash\" is set to !_TAG_OUTPUT_FILESEP\n\t\t * pseudo tag in the tags file. */\n\tunsigned char inputUCtagsMode;\n\t\t/* how is the tag file sorted? */\n\ttagSortType sortMethod;\n\t\t/* pointer to file structure */\n\tFILE* fp;\n\t\t/* file position of first character of `line' */\n\trt_off_t pos;\n\t\t/* size of tag file in seekable positions */\n\trt_off_t size;\n\t\t/* last line read */\n\tvstring line;\n\t\t/* name of tag in last line read */\n\tvstring name;\n\t\t/* defines tag search state */\n\tstruct {\n\t\t\t\t/* file position of last match for tag */\n\t\t\trt_off_t pos;\n\t\t\t\t/* name of tag last searched for */\n\t\t\tchar *name;\n\t\t\t\t/* length of name for partial matches */\n\t\t\tsize_t nameLength;\n\t\t\t\t/* performing partial match */\n\t\t\tshort partial;\n\t\t\t\t/* ignoring case */\n\t\t\tshort ignorecase;\n\t} search;\n\t\t/* miscellaneous extension fields */\n\tstruct {\n\t\t\t\t/* number of entries in `list' */\n\t\t\tunsigned short max;\n\t\t\t\t/* list of key value pairs */\n\t\t\ttagExtensionField *list;\n\t} fields;\n\t\t/* buffers to be freed at close */\n\tstruct {\n\t\t\t/* name of program author */\n\t\tchar *author;\n\t\t\t/* name of program */\n\t\tchar *name;\n\t\t\t/* URL of distribution */\n\t\tchar *url;\n\t\t\t/* program version */\n\t\tchar *version;\n\t} program;\n\t\t/* 0 (initial state set by calloc), errno value,\n\t\t * or tagErrno typed value */\n\tint err;\n};\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic const char *const EmptyString = \"\";\nstatic const char *const PseudoTagPrefix = \"!_\";\nstatic const size_t PseudoTagPrefixLength = 2;\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic rt_off_t readtags_ftell(FILE *fp)\n{\n\trt_off_t pos;\n\n#ifdef _WIN32\n\tpos = _ftelli64(fp);\n#else\n\tpos = ftell(fp);\n#endif\n\n\treturn pos;\n}\n\nstatic int readtags_fseek(FILE *fp, rt_off_t pos, int whence)\n{\n\tint ret;\n\n#ifdef _WIN32\n\tret = _fseeki64(fp, pos, whence);\n#else\n\tret = fseek(fp, pos, whence);\n#endif\n\n\treturn ret;\n}\n\n/* Converts a hexadecimal digit to its value */\nstatic int xdigitValue (unsigned char digit)\n{\n\tif (digit >= '0' && digit <= '9')\n\t\treturn digit - '0';\n\telse if (digit >= 'a' && digit <= 'f')\n\t\treturn 10 + digit - 'a';\n\telse if (digit >= 'A' && digit <= 'F')\n\t\treturn 10 + digit - 'A';\n\telse\n\t\treturn 0;\n}\n\n/*\n * Reads the first character from the string, possibly un-escaping it, and\n * advances *s to the start of the next character.\n */\nREADTAGS_INLINE\nint readTagCharacter (const char **const s)\n{\n\tconst unsigned char *p = (const unsigned char *) *s;\n\tint c = *p;\n\n\tp++;\n\n\tif (c == '\\\\')\n\t{\n\t\tswitch (*p)\n\t\t{\n\t\t\tcase 't': c = '\\t'; p++; break;\n\t\t\tcase 'r': c = '\\r'; p++; break;\n\t\t\tcase 'n': c = '\\n'; p++; break;\n\t\t\tcase '\\\\': c = '\\\\'; p++; break;\n\t\t\t/* Universal-CTags extensions */\n\t\t\tcase 'a': c = '\\a'; p++; break;\n\t\t\tcase 'b': c = '\\b'; p++; break;\n\t\t\tcase 'v': c = '\\v'; p++; break;\n\t\t\tcase 'f': c = '\\f'; p++; break;\n\t\t\tcase 'x':\n\t\t\t\tif (isxdigit (p[1]) && isxdigit (p[2]))\n\t\t\t\t{\n\t\t\t\t\tint val = (xdigitValue (p[1]) << 4) | xdigitValue (p[2]);\n\t\t\t\t\tif (val < 0x80)\n\t\t\t\t\t{\n\t\t\t\t\t\tp += 3;\n\t\t\t\t\t\tc = val;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t*s = (const char *) p;\n\n\treturn c;\n}\n\n/*\n * Compare two strings, ignoring case.\n * Return 0 for match, < 0 for smaller, > 0 for bigger\n * Make sure case is folded to uppercase in comparison (like for 'sort -f')\n * This makes a difference when one of the chars lies between upper and lower\n * ie. one of the chars [ \\ ] ^ _ ` for ascii. (The '_' in particular !)\n */\nstatic int taguppercmp (const char *s1, const char *s2)\n{\n\tint result;\n\tint c1, c2;\n\tdo\n\t{\n\t\tc1 = (unsigned char)*s1++;\n\t\tc2 = readTagCharacter (&s2);\n\n\t\tresult = toupper (c1) - toupper (c2);\n\t} while (result == 0  &&  c1 != '\\0'  &&  c2 != '\\0');\n\treturn result;\n}\n\nstatic int tagnuppercmp (const char *s1, const char *s2, size_t n)\n{\n\tint result;\n\tint c1, c2;\n\tdo\n\t{\n\t\tc1 = (unsigned char)*s1++;\n\t\tc2 = readTagCharacter (&s2);\n\n\t\tresult = toupper (c1) - toupper (c2);\n\t} while (result == 0  &&  --n > 0  &&  c1 != '\\0'  &&  c2 != '\\0');\n\treturn result;\n}\n\nstatic int tagcmp (const char *s1, const char *s2)\n{\n\tint result;\n\tint c1, c2;\n\tdo\n\t{\n\t\tc1 = (unsigned char)*s1++;\n\t\tc2 = readTagCharacter (&s2);\n\n\t\tresult = c1 - c2;\n\t} while (result == 0  &&  c1 != '\\0'  &&  c2 != '\\0');\n\treturn result;\n}\n\nstatic int tagncmp (const char *s1, const char *s2, size_t n)\n{\n\tint result;\n\tint c1, c2;\n\tdo\n\t{\n\t\tc1 = *s1++;\n\t\tc2 = readTagCharacter (&s2);\n\n\t\tresult = c1 - c2;\n\t} while (result == 0  &&  --n > 0  &&  c1 != '\\0'  &&  c2 != '\\0');\n\treturn result;\n}\n\nstatic tagResult growString (vstring *s)\n{\n\ttagResult result = TagFailure;\n\tsize_t newLength;\n\tchar *newLine;\n\tif (s->size == 0)\n\t{\n\t\tnewLength = 128;\n\t\tnewLine = (char*) malloc (newLength);\n\t\tif (newLine)\n\t\t\t*newLine = '\\0';\n\t}\n\telse\n\t{\n\t\tnewLength = 2 * s->size;\n\t\tnewLine = (char*) realloc (s->buffer, newLength);\n\t}\n\tif (newLine == NULL)\n\t\tperror (\"string too large\");\n\telse\n\t{\n\t\ts->buffer = newLine;\n\t\ts->size = newLength;\n\t\tresult = TagSuccess;\n\t}\n\treturn result;\n}\n\n/* Copy name of tag out of tag line */\nstatic tagResult copyName (tagFile *const file)\n{\n\tsize_t length;\n\tconst char *end = strchr (file->line.buffer, '\\t');\n\tif (end == NULL)\n\t{\n\t\tend = strchr (file->line.buffer, '\\n');\n\t\tif (end == NULL)\n\t\t\tend = strchr (file->line.buffer, '\\r');\n\t}\n\tif (end != NULL)\n\t\tlength = end - file->line.buffer;\n\telse\n\t\tlength = strlen (file->line.buffer);\n\twhile (length >= file->name.size)\n\t{\n\t\tif (growString (&file->name) != TagSuccess)\n\t\t\treturn TagFailure;\n\t}\n\tstrncpy (file->name.buffer, file->line.buffer, length);\n\tfile->name.buffer [length] = '\\0';\n\treturn TagSuccess;\n}\n\n/* Return 1 on success.\n * Return 0 on failure or EOF.\n * errno is set to *err unless EOF.\n */\nstatic int readTagLineRaw (tagFile *const file, int *err)\n{\n\tint result = 1;\n\tint reReadLine;\n\n\t/*  If reading the line places any character other than a null or a\n\t *  newline at the last character position in the buffer (one less than\n\t *  the buffer size), then we must resize the buffer and reattempt to read\n\t *  the line.\n\t */\n\tdo\n\t{\n\t\tchar *const pLastChar = file->line.buffer + file->line.size - 2;\n\t\tchar *line;\n\n\t\tfile->pos = readtags_ftell (file->fp);\n\t\tif (file->pos < 0)\n\t\t{\n\t\t\t*err = errno;\n\t\t\tresult = 0;\n\t\t\tbreak;\n\t\t}\n\t\treReadLine = 0;\n\t\t*pLastChar = '\\0';\n\t\tline = fgets (file->line.buffer, (int) file->line.size, file->fp);\n\t\tif (line == NULL)\n\t\t{\n\t\t\t/* read error */\n\t\t\t*err = 0;\n\t\t\tif (! feof (file->fp))\n\t\t\t\t*err = errno;\n\t\t\tresult = 0;\n\t\t}\n\t\telse if (*pLastChar != '\\0'  &&\n\t\t\t\t\t*pLastChar != '\\n'  &&  *pLastChar != '\\r')\n\t\t{\n\t\t\t/*  buffer overflow */\n\t\t\tif (growString (&file->line) != TagSuccess)\n\t\t\t{\n\t\t\t\t*err = ENOMEM;\n\t\t\t\tresult = 0;\n\t\t\t}\n\n\t\t\tif (readtags_fseek (file->fp, file->pos, SEEK_SET) < 0)\n\t\t\t{\n\t\t\t\t*err = errno;\n\t\t\t\tresult = 0;\n\t\t\t}\n\t\t\treReadLine = 1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsize_t i = strlen (file->line.buffer);\n\t\t\twhile (i > 0  &&\n\t\t\t\t   (file->line.buffer [i - 1] == '\\n' || file->line.buffer [i - 1] == '\\r'))\n\t\t\t{\n\t\t\t\tfile->line.buffer [i - 1] = '\\0';\n\t\t\t\t--i;\n\t\t\t}\n\t\t}\n\t} while (reReadLine  &&  result);\n\tif (result)\n\t{\n\t\tif (copyName (file) != TagSuccess)\n\t\t{\n\t\t\t*err = ENOMEM;\n\t\t\tresult = 0;\n\t\t}\n\t}\n\treturn result;\n}\n\n/* Return 1 on success.\n * Return 0 on failure or EOF.\n * errno is set to *err unless EOF.\n */\nstatic int readTagLine (tagFile *const file, int *err)\n{\n\tint result;\n\tdo\n\t{\n\t\tresult = readTagLineRaw (file, err);\n\t} while (result && *file->name.buffer == '\\0');\n\treturn result;\n}\n\nstatic tagResult growFields (tagFile *const file)\n{\n\ttagResult result = TagFailure;\n\tunsigned short newCount = (unsigned short) 2 * file->fields.max;\n\ttagExtensionField *newFields = (tagExtensionField*)\n\t\t\trealloc (file->fields.list, newCount * sizeof (tagExtensionField));\n\tif (newFields == NULL)\n\t\tperror (\"too many extension fields\");\n\telse\n\t{\n\t\tfile->fields.list = newFields;\n\t\tfile->fields.max = newCount;\n\t\tresult = TagSuccess;\n\t}\n\treturn result;\n}\n\nstatic tagResult parseExtensionFields (tagFile *const file, tagEntry *const entry,\n\t\t\t\t\t\t\t\t\t   char *const string, int *err)\n{\n\tchar *p = string;\n\tchar *tail = string + (string? strlen(string):0);\n\tsize_t q_len;\n\n\twhile (p != NULL  &&  *p != '\\0')\n\t{\n\t\twhile (*p == TAB)\n\t\t\t*p++ = '\\0';\n\t\tif (*p != '\\0')\n\t\t{\n\t\t\tchar *colon;\n\t\t\tchar *field = p;\n\t\t\tp = strchr (p, TAB);\n\t\t\tif (p != NULL)\n\t\t\t\t*p++ = '\\0';\n\t\t\tcolon = strchr (field, ':');\n\t\t\tif (colon == NULL)\n\t\t\t\tentry->kind = field;\n\t\t\telse\n\t\t\t{\n\t\t\t\tconst char *key = field;\n\t\t\t\tchar *q = colon + 1;\n\t\t\t\tconst char *value = q;\n\t\t\t\tconst int key_len = colon - key;\n\t\t\t\t*colon = '\\0';\n\n\t\t\t\tq_len = tail - q;\n\n\t\t\t\t/* Unescaping */\n\t\t\t\twhile (*q != '\\0')\n\t\t\t\t{\n\t\t\t\t\tconst char *next = q;\n\t\t\t\t\tint ch = readTagCharacter (&next);\n\t\t\t\t\tsize_t skip = next - q;\n\n\t\t\t\t\t*q = (char) ch;\n\t\t\t\t\tq++;\n\t\t\t\t\tq_len -= skip;\n\t\t\t\t\tif (skip > 1)\n\t\t\t\t\t{\n\t\t\t\t\t\t/* + 1 is for moving the area including the last '\\0'. */\n\t\t\t\t\t\tmemmove (q, next, q_len + 1);\n\t\t\t\t\t\tif (p)\n\t\t\t\t\t\t\tp -= skip - 1;\n\t\t\t\t\t\tif (tail != string)\n\t\t\t\t\t\t\ttail -= skip - 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (key_len == 4)\n\t\t\t\t{\n\t\t\t\t\tif (memcmp (key, \"kind\", 4) == 0)\n\t\t\t\t\t\tentry->kind = value;\n\t\t\t\t\telse if (memcmp (key, \"file\", 4) == 0)\n\t\t\t\t\t\tentry->fileScope = 1;\n\t\t\t\t\telse if (memcmp (key, \"line\", 4) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tchar *endptr = NULL;\n\t\t\t\t\t\tlong m = strtol (value, &endptr, 10);\n\t\t\t\t\t\tif (*endptr != '\\0' || m < 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t*err = TagErrnoUnexpectedLineno;\n\t\t\t\t\t\t\treturn TagFailure;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentry->address.lineNumber = m;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tgoto normalField;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\tnormalField:\n\t\t\t\t\tif (entry->fields.count == file->fields.max)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (growFields (file) != TagSuccess)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t*err = ENOMEM;\n\t\t\t\t\t\t\treturn TagFailure;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfile->fields.list [entry->fields.count].key = key;\n\t\t\t\t\tfile->fields.list [entry->fields.count].value = value;\n\t\t\t\t\t++entry->fields.count;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn TagSuccess;\n}\n\nstatic int isOdd (unsigned int i)\n{\n\treturn  (i % 2);\n}\n\nstatic unsigned int countContinuousBackslashesBackward(const char *from,\n\t\t\t\t\t\t     const char *till)\n{\n\tunsigned int counter = 0;\n\n\tfor (; from > till; from--)\n\t{\n\t\tif (*from == '\\\\')\n\t\t\tcounter++;\n\t\telse\n\t\t\tbreak;\n\t}\n\treturn counter;\n}\n\n/* When unescaping, the input string becomes shorter.\n * e.g. \\t occupies two bytes on the tag file.\n * It is converted to 0x9 and occupies one byte.\n * memmove called here for shortening the line\n * buffer. */\nstatic char *unescapeInPlace (char *q, char **tab, size_t *p_len)\n{\n\tchar *p = q;\n\n\twhile (*p != '\\0')\n\t{\n\t\tconst char *next = p;\n\t\tint ch = readTagCharacter (&next);\n\t\tsize_t skip = next - p;\n\n\t\t*p = (char) ch;\n\t\tp++;\n\t\t*p_len -= skip;\n\t\tif (skip > 1)\n\t\t{\n\t\t\t/* + 1 is for moving the area including the last '\\0'. */\n\t\t\tmemmove (p, next, *p_len + 1);\n\t\t\tif (*tab)\n\t\t\t\t*tab -= skip - 1;\n\t\t}\n\t}\n\n\treturn p;\n}\n\nstatic tagResult parseTagLine (tagFile *file, tagEntry *const entry, int *err)\n{\n\tint i;\n\tchar *p = file->line.buffer;\n\tsize_t p_len = strlen (p);\n\tchar *tab = strchr (p, TAB);\n\n\tmemset(entry, 0, sizeof(*entry));\n\n\tentry->name = p;\n\tif (tab != NULL)\n\t{\n\t\t*tab = '\\0';\n\t}\n\n\tp = unescapeInPlace (p, &tab, &p_len);\n\n\tif (tab != NULL)\n\t{\n\t\tp = tab + 1;\n\t\tentry->file = p;\n\t\ttab = strchr (p, TAB);\n\t\tif (file->inputUCtagsMode)\n\t\t{\n\t\t\tif (tab != NULL)\n\t\t\t{\n\t\t\t\t*tab = '\\0';\n\t\t\t}\n\t\t\tp = unescapeInPlace (p, &tab, &p_len);\n\t\t}\n\n\t\tif (tab != NULL)\n\t\t{\n\t\t\tint fieldsPresent;\n\t\t\tint combinedPattern;\n\t\t\t*tab = '\\0';\n\t\t\tp = tab + 1;\n\t\t\tif (*p == '/'  ||  *p == '?')\n\t\t\t{\n\t\t\t\t/* parse pattern */\n\t\t\t\tint delimiter = *(unsigned char*) p;\n\t\t\t\tentry->address.lineNumber = 0;\n\t\t\t\tentry->address.pattern = p;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tp = strchr (p + 1, delimiter);\n\t\t\t\t} while (p != NULL\n\t\t\t\t\t &&  isOdd (countContinuousBackslashesBackward (p - 1,\n\t\t\t\t\t\t\t\t\t\t\tentry->address.pattern)));\n\n\t\t\t\tif (p == NULL)\n\t\t\t\t{\n\t\t\t\t\t/* TODO: invalid pattern */\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\t++p;\n\t\t\t}\n\t\t\telse if (isdigit (*(unsigned char*) p))\n\t\t\t{\n\t\t\t\t/* parse line number */\n\t\t\t\tentry->address.pattern = p;\n\t\t\t\tentry->address.lineNumber = atol (p);\n\t\t\t\twhile (isdigit (*(unsigned char*) p))\n\t\t\t\t\t++p;\n\t\t\t\tif (p)\n\t\t\t\t{\n\t\t\t\t\tcombinedPattern = (strncmp (p, \";/\", 2) == 0) ||\n\t\t\t\t\t\t\t\t\t\t\t(strncmp (p, \";?\", 2) == 0);\n\t\t\t\t\tif (combinedPattern)\n\t\t\t\t\t{\n\t\t\t\t\t\t++p;\n\t\t\t\t\t\t/* parse pattern */\n\t\t\t\t\t\tint delimiter = *(unsigned char*) p;\n\t\t\t\t\t\tdo\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tp = strchr (p + 1, delimiter);\n\t\t\t\t\t\t} while (p != NULL\n\t\t\t\t\t\t\t &&  isOdd (countContinuousBackslashesBackward (p - 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\tentry->address.pattern)));\n\n\t\t\t\t\t\tif (p == NULL)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* TODO: invalid pattern */\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t++p;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* TODO: invalid pattern */\n\t\t\t}\n\n\t\t\tif (p)\n\t\t\t{\n\t\t\t\tfieldsPresent = (strncmp (p, \";\\\"\", 2) == 0);\n\t\t\t\t*p = '\\0';\n\t\t\t\tif (fieldsPresent)\n\t\t\t\t{\n\t\t\t\t\tif (parseExtensionFields (file, entry, p + 2, err) != TagSuccess)\n\t\t\t\t\t\treturn TagFailure;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif (entry->fields.count > 0)\n\t\tentry->fields.list = file->fields.list;\n\tfor (i = entry->fields.count  ;  i < file->fields.max  ;  ++i)\n\t{\n\t\tfile->fields.list [i].key = NULL;\n\t\tfile->fields.list [i].value = NULL;\n\t}\n\treturn TagSuccess;\n}\n\nstatic char *duplicate (const char *str)\n{\n\tchar *result = NULL;\n\tif (str != NULL)\n\t{\n\t\tresult = strdup (str);\n\t\tif (result == NULL)\n\t\t\tperror (NULL);\n\t}\n\treturn result;\n}\n\nstatic int isPseudoTagLine (const char *buffer)\n{\n\treturn (strncmp (buffer, PseudoTagPrefix, PseudoTagPrefixLength) == 0);\n}\n\nstatic tagResult readPseudoTags (tagFile *const file, tagFileInfo *const info)\n{\n\tfpos_t startOfLine;\n\tint err = 0;\n\ttagResult result = TagSuccess;\n\tconst size_t prefixLength = strlen (PseudoTagPrefix);\n\tint tag_output_mode_u_ctags = 0;\n\tint tag_output_filesep_slash = 0;\n\n\tinfo->file.format     = 1;\n\tinfo->file.sort       = TAG_UNSORTED;\n\tinfo->program.author  = NULL;\n\tinfo->program.name    = NULL;\n\tinfo->program.url     = NULL;\n\tinfo->program.version = NULL;\n\n\twhile (1)\n\t{\n\t\tif (fgetpos (file->fp, &startOfLine) < 0)\n\t\t{\n\t\t\terr = errno;\n\t\t\tbreak;\n\t\t}\n\t\tif (! readTagLine (file, &err))\n\t\t\tbreak;\n\t\tif (!isPseudoTagLine (file->line.buffer))\n\t\t\tbreak;\n\t\telse\n\t\t{\n\t\t\ttagEntry entry;\n\t\t\tconst char *key, *value;\n\t\t\tif (parseTagLine (file, &entry, &err) != TagSuccess)\n\t\t\t\tbreak;\n\t\t\tkey = entry.name + prefixLength;\n\t\t\tvalue = entry.file;\n\t\t\tif (strcmp (key, \"TAG_FILE_SORTED\") == 0)\n\t\t\t{\n\t\t\t\tchar *endptr = NULL;\n\t\t\t\tlong m = strtol (value, &endptr, 10);\n\t\t\t\tif (*endptr != '\\0' || m < 0 || m > 2)\n\t\t\t\t{\n\t\t\t\t\terr = TagErrnoUnexpectedSortedMethod;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tfile->sortMethod = (tagSortType) m;\n\t\t\t}\n\t\t\telse if (strcmp (key, \"TAG_FILE_FORMAT\") == 0)\n\t\t\t{\n\t\t\t\tchar *endptr = NULL;\n\t\t\t\tlong m = strtol (value, &endptr, 10);\n\t\t\t\tif (*endptr != '\\0' || m < 1 || m > 2)\n\t\t\t\t{\n\t\t\t\t\terr = TagErrnoUnexpectedFormat;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tfile->format = (unsigned char) m;\n\t\t\t}\n\t\t\telse if (strcmp (key, \"TAG_PROGRAM_AUTHOR\") == 0)\n\t\t\t{\n\t\t\t\tfile->program.author = duplicate (value);\n\t\t\t\tif (value && file->program.author == NULL)\n\t\t\t\t{\n\t\t\t\t\terr = ENOMEM;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (strcmp (key, \"TAG_PROGRAM_NAME\") == 0)\n\t\t\t{\n\t\t\t\tfile->program.name = duplicate (value);\n\t\t\t\tif (value && file->program.name == NULL)\n\t\t\t\t{\n\t\t\t\t\terr = ENOMEM;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (strcmp (key, \"TAG_PROGRAM_URL\") == 0)\n\t\t\t{\n\t\t\t\tfile->program.url = duplicate (value);\n\t\t\t\tif (value && file->program.url == NULL)\n\t\t\t\t{\n\t\t\t\t\terr = ENOMEM;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (strcmp (key, \"TAG_PROGRAM_VERSION\") == 0)\n\t\t\t{\n\t\t\t\tfile->program.version = duplicate (value);\n\t\t\t\tif (value && file->program.version == NULL)\n\t\t\t\t{\n\t\t\t\t\terr = ENOMEM;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (strcmp (key, \"TAG_OUTPUT_MODE\") == 0)\n\t\t\t{\n\t\t\t\tif (strcmp (value, \"u-ctags\") == 0)\n\t\t\t\t\ttag_output_mode_u_ctags = 1;\n\t\t\t}\n\t\t\telse if (strcmp (key, \"TAG_OUTPUT_FILESEP\") == 0)\n\t\t\t{\n\t\t\t\tif (strcmp (value, \"slash\") == 0)\n\t\t\t\t\ttag_output_filesep_slash = 1;\n\t\t\t}\n\n\t\t\tinfo->file.format     = file->format;\n\t\t\tinfo->file.sort       = file->sortMethod;\n\t\t\tinfo->program.author  = file->program.author;\n\t\t\tinfo->program.name    = file->program.name;\n\t\t\tinfo->program.url     = file->program.url;\n\t\t\tinfo->program.version = file->program.version;\n\t\t}\n\t}\n\n\tif (tag_output_mode_u_ctags && tag_output_filesep_slash)\n\t\tfile->inputUCtagsMode = 1;\n\n\tif (fsetpos (file->fp, &startOfLine) < 0)\n\t\terr = errno;\n\n\tinfo->status.error_number = err;\n\tif (err)\n\t\tresult = TagFailure;\n\treturn result;\n}\n\nstatic int doesFilePointPseudoTag (tagFile *const file, void *unused)\n{\n\treturn isPseudoTagLine (file->name.buffer);\n}\n\nstatic tagResult gotoFirstLogicalTag (tagFile *const file)\n{\n\tfpos_t startOfLine;\n\n\tif (readtags_fseek(file->fp, 0, SEEK_SET) == -1)\n\t{\n\t\tfile->err = errno;\n\t\treturn TagFailure;\n\t}\n\n\twhile (1)\n\t{\n\t\tif (fgetpos (file->fp, &startOfLine) < 0)\n\t\t{\n\t\t\tfile->err = errno;\n\t\t\treturn TagFailure;\n\t\t}\n\t\tif (! readTagLine (file, &file->err))\n\t\t{\n\t\t\tif (file->err)\n\t\t\t\treturn TagFailure;\n\t\t\tbreak;\n\t\t}\n\t\tif (!isPseudoTagLine (file->line.buffer))\n\t\t\tbreak;\n\t}\n\tif (fsetpos (file->fp, &startOfLine) < 0)\n\t{\n\t\tfile->err = errno;\n\t\treturn TagFailure;\n\t}\n\treturn TagSuccess;\n}\n\nstatic tagFile *initialize (const char *const filePath, tagFileInfo *const info)\n{\n\ttagFile *result = (tagFile*) calloc ((size_t) 1, sizeof (tagFile));\n\n\tif (result == NULL)\n\t{\n\t\tinfo->status.opened = 0;\n\t\tinfo->status.error_number = ENOMEM;\n\t\treturn NULL;\n\t}\n\n\tif (growString (&result->line) != TagSuccess)\n\t\tgoto mem_error;\n\tif (growString (&result->name) != TagSuccess)\n\t\tgoto mem_error;\n\tresult->fields.max = 20;\n\tresult->fields.list = (tagExtensionField*) calloc (\n\t\tresult->fields.max, sizeof (tagExtensionField));\n\tif (result->fields.list == NULL)\n\t\tgoto mem_error;\n\n#if defined(__GLIBC__) && (__GLIBC__ >= 2) \\\n\t&& defined(__GLIBC_MINOR__) && (__GLIBC_MINOR__ >= 3)\n\tresult->fp = fopen (filePath, \"rbm\");\n#endif\n\tif (result->fp == NULL)\n\t{\n\t\terrno = 0;\n\t\tresult->fp = fopen (filePath, \"rb\");\n\t}\n\tif (result->fp == NULL)\n\t{\n\t\tinfo->status.error_number = errno;\n\t\tgoto file_error;\n\t}\n\n\t/* Record the size of the tags file to `size` field of result. */\n\tif (readtags_fseek (result->fp, 0, SEEK_END) == -1)\n\t{\n\t\tinfo->status.error_number = errno;\n\t\tgoto file_error;\n\t}\n\tresult->size = readtags_ftell (result->fp);\n\tif (result->size == -1)\n\t{\n\t\t/* fseek() retruns an int value.\n\t\t * We observed following behavior on Windows;\n\t\t * if sizeof(int) of the platform is too small for\n\t\t * representing the size of the tags file, fseek()\n\t\t * returns -1 and it doesn't set errno.\n\t\t */\n\t\tinfo->status.error_number = errno;\n\t\tif (info->status.error_number == 0)\n\t\t\tinfo->status.error_number = TagErrnoFileMaybeTooBig;\n\n\t\tgoto file_error;\n\t}\n\tif (readtags_fseek(result->fp, 0, SEEK_SET) == -1)\n\t{\n\t\tinfo->status.error_number = errno;\n\t\tgoto file_error;\n\t}\n\n\tif (readPseudoTags (result, info) == TagFailure)\n\t\tgoto file_error;\n\n\tinfo->status.opened = 1;\n\tresult->initialized = 1;\n\n\treturn result;\n mem_error:\n\tinfo->status.error_number = ENOMEM;\n file_error:\n\tfree (result->line.buffer);\n\tfree (result->name.buffer);\n\tfree (result->fields.list);\n\tif (result->fp)\n\t\tfclose (result->fp);\n\tfree (result);\n\tinfo->status.opened = 0;\n\treturn NULL;\n}\n\nstatic void terminate (tagFile *const file)\n{\n\tfclose (file->fp);\n\n\tfree (file->line.buffer);\n\tfree (file->name.buffer);\n\tfree (file->fields.list);\n\n\tif (file->program.author != NULL)\n\t\tfree (file->program.author);\n\tif (file->program.name != NULL)\n\t\tfree (file->program.name);\n\tif (file->program.url != NULL)\n\t\tfree (file->program.url);\n\tif (file->program.version != NULL)\n\t\tfree (file->program.version);\n\tif (file->search.name != NULL)\n\t\tfree (file->search.name);\n\n\tmemset (file, 0, sizeof (tagFile));\n\n\tfree (file);\n}\n\nstatic tagResult readNext (tagFile *const file, tagEntry *const entry)\n{\n\ttagResult result;\n\n\tif (file == NULL)\n\t\treturn TagFailure;\n\n\tif (! file->initialized)\n\t{\n\t\tfile->err = TagErrnoInvalidArgument;\n\t\treturn TagFailure;\n\t}\n\n\tif (! readTagLine (file, &file->err))\n\t\treturn TagFailure;\n\n\tresult = (entry != NULL)\n\t\t? parseTagLine (file, entry, &file->err)\n\t\t: TagSuccess;\n\n\treturn result;\n}\n\nstatic const char *readFieldValue (\n\tconst tagEntry *const entry, const char *const key)\n{\n\tconst char *result = NULL;\n\tint i;\n\tif (strcmp (key, \"kind\") == 0)\n\t\tresult = entry->kind;\n\telse if (strcmp (key, \"file\") == 0)\n\t\tresult = EmptyString;\n\telse for (i = 0  ;  i < entry->fields.count  &&  result == NULL  ;  ++i)\n\t\tif (strcmp (entry->fields.list [i].key, key) == 0)\n\t\t\tresult = entry->fields.list [i].value;\n\treturn result;\n}\n\nstatic int readTagLineSeek (tagFile *const file, const rt_off_t pos)\n{\n\tif (readtags_fseek (file->fp, pos, SEEK_SET) < 0)\n\t{\n\t\tfile->err = errno;\n\t\treturn 0;\n\t}\n\n\t/* read probable partial line */\n\tif (!readTagLine (file, &file->err))\n\t\treturn 0;\n\n\t/* read complete line */\n\tif (pos > 0)\n\t\treturn readTagLine (file, &file->err);\n\n\treturn 1;\n}\n\nstatic int nameComparison (tagFile *const file)\n{\n\tint result;\n\tif (file->search.ignorecase)\n\t{\n\t\tif (file->search.partial)\n\t\t\tresult = tagnuppercmp (file->search.name, file->name.buffer,\n\t\t\t\t\tfile->search.nameLength);\n\t\telse\n\t\t\tresult = taguppercmp (file->search.name, file->name.buffer);\n\t}\n\telse\n\t{\n\t\tif (file->search.partial)\n\t\t\tresult = tagncmp (file->search.name, file->name.buffer,\n\t\t\t\t\tfile->search.nameLength);\n\t\telse\n\t\t\tresult = tagcmp (file->search.name, file->name.buffer);\n\t}\n\treturn result;\n}\n\nstatic tagResult findFirstNonMatchBefore (tagFile *const file)\n{\n#define JUMP_BACK 512\n\tint more_lines;\n\tint comp;\n\trt_off_t start = file->pos;\n\trt_off_t pos = start;\n\tdo\n\t{\n\t\tif (pos < (rt_off_t) JUMP_BACK)\n\t\t\tpos = 0;\n\t\telse\n\t\t\tpos = pos - JUMP_BACK;\n\t\tmore_lines = readTagLineSeek (file, pos);\n\t\tif (more_lines == 0 && file->err)\n\t\t\treturn TagFailure;\n\t\tcomp = nameComparison (file);\n\t} while (more_lines  &&  comp == 0  &&  pos > 0  &&  pos < start);\n\treturn TagSuccess;\n}\n\nstatic tagResult findFirstMatchBefore (tagFile *const file)\n{\n\ttagResult result = TagFailure;\n\tint more_lines;\n\trt_off_t start = file->pos;\n\tif (findFirstNonMatchBefore (file) != TagSuccess)\n\t\treturn TagFailure;\n\tdo\n\t{\n\t\tmore_lines = readTagLine (file, &file->err);\n\t\tif (more_lines == 0 && file->err)\n\t\t\treturn TagFailure;\n\t\tif (nameComparison (file) == 0)\n\t\t\tresult = TagSuccess;\n\t} while (more_lines  &&  result != TagSuccess  &&  file->pos < start);\n\treturn result;\n}\n\nstatic tagResult findBinary (tagFile *const file)\n{\n\ttagResult result = TagFailure;\n\trt_off_t lower_limit = 0;\n\trt_off_t upper_limit = file->size;\n\trt_off_t last_pos = 0;\n\trt_off_t pos = upper_limit / 2;\n\twhile (result != TagSuccess)\n\t{\n\t\tif (! readTagLineSeek (file, pos))\n\t\t{\n\t\t\tif (file->err)\n\t\t\t\tbreak;\n\t\t\t/* in case we fell off end of file */\n\t\t\tresult = findFirstMatchBefore (file);\n\t\t\tbreak;\n\t\t}\n\t\telse if (pos == last_pos)\n\t\t{\n\t\t\t/* prevent infinite loop if we backed up to beginning of file */\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tconst int comp = nameComparison (file);\n\t\t\tlast_pos = pos;\n\t\t\tif (comp < 0)\n\t\t\t{\n\t\t\t\tupper_limit = pos;\n\t\t\t\tpos = lower_limit + ((upper_limit - lower_limit) / 2);\n\t\t\t}\n\t\t\telse if (comp > 0)\n\t\t\t{\n\t\t\t\tlower_limit = pos;\n\t\t\t\tpos = lower_limit + ((upper_limit - lower_limit) / 2);\n\t\t\t}\n\t\t\telse if (pos == 0)\n\t\t\t\tresult = TagSuccess;\n\t\t\telse\n\t\t\t{\n\t\t\t\tresult = findFirstMatchBefore (file);\n\t\t\t\tif (result != TagSuccess && file->err)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\nstatic tagResult findSequentialFull (tagFile *const file,\n\t\t\t\t\t\t\t\t\t int (* isAcceptable) (tagFile *const, void *),\n\t\t\t\t\t\t\t\t\t void *data)\n{\n\tif (file == NULL)\n\t\treturn TagFailure;\n\n\tif (!file->initialized || file->err)\n\t{\n\t\tfile->err = TagErrnoInvalidArgument;\n\t\treturn TagFailure;\n\t}\n\n\ttagResult result = TagFailure;\n\twhile (result == TagFailure)\n\t{\n\t\tif (! readTagLine (file, &file->err))\n\t\t\tbreak;\n\t\tif (isAcceptable (file, data))\n\t\t\tresult = TagSuccess;\n\t}\n\treturn result;\n}\n\nstatic int nameAcceptable (tagFile *const file, void *unused)\n{\n\treturn (nameComparison (file) == 0);\n}\n\nstatic tagResult findSequential (tagFile *const file)\n{\n\treturn findSequentialFull (file, nameAcceptable, NULL);\n}\n\nstatic tagResult find (tagFile *const file, tagEntry *const entry,\n\t\t\t\t\t   const char *const name, const int options)\n{\n\ttagResult result;\n\tif (file->search.name != NULL)\n\t\tfree (file->search.name);\n\tfile->search.name = duplicate (name);\n\tif (file->search.name == NULL)\n\t{\n\t\tfile->err = ENOMEM;\n\t\treturn TagFailure;\n\t}\n\tfile->search.nameLength = strlen (name);\n\tfile->search.partial = (options & TAG_PARTIALMATCH) != 0;\n\tfile->search.ignorecase = (options & TAG_IGNORECASE) != 0;\n\tif (readtags_fseek (file->fp, 0, SEEK_END) < 0)\n\t{\n\t\tfile->err = errno;\n\t\treturn TagFailure;\n\t}\n\tfile->size = readtags_ftell (file->fp);\n\tif (file->size == -1)\n\t{\n\t\tfile->err = errno;\n\t\treturn TagFailure;\n\t}\n\tif (readtags_fseek(file->fp, 0, SEEK_SET) == -1)\n\t{\n\t\tfile->err = errno;\n\t\treturn TagFailure;\n\t}\n\tif ((file->sortMethod == TAG_SORTED      && !file->search.ignorecase) ||\n\t\t(file->sortMethod == TAG_FOLDSORTED  &&  file->search.ignorecase))\n\t{\n\t\tresult = findBinary (file);\n\t\tif (result == TagFailure && file->err)\n\t\t\treturn TagFailure;\n\t}\n\telse\n\t{\n\t\tresult = findSequential (file);\n\t\tif (result == TagFailure && file->err)\n\t\t\treturn TagFailure;\n\t}\n\n\tif (result != TagSuccess)\n\t\tfile->search.pos = file->size;\n\telse\n\t{\n\t\tfile->search.pos = file->pos;\n\t\tresult = (entry != NULL)\n\t\t\t? parseTagLine (file, entry, &file->err)\n\t\t\t: TagSuccess;\n\t}\n\treturn result;\n}\n\nstatic tagResult findNextFull (tagFile *const file, tagEntry *const entry,\n\t\t\t\t\t\t\t   int sorted,\n\t\t\t\t\t\t\t   int (* isAcceptable) (tagFile *const, void *),\n\t\t\t\t\t\t\t   void *data)\n{\n\ttagResult result;\n\tif (sorted)\n\t{\n\t\tresult = tagsNext (file, entry);\n\t\tif (result == TagSuccess  && !isAcceptable (file, data))\n\t\t\tresult = TagFailure;\n\t}\n\telse\n\t{\n\t\tresult = findSequentialFull (file, isAcceptable, data);\n\t\tif (result == TagSuccess  &&  entry != NULL)\n\t\t\tresult = parseTagLine (file, entry, &file->err);\n\t}\n\treturn result;\n}\n\nstatic tagResult findNext (tagFile *const file, tagEntry *const entry)\n{\n\treturn findNextFull (file, entry,\n\t\t\t\t\t\t (file->sortMethod == TAG_SORTED      && !file->search.ignorecase) ||\n\t\t\t\t\t\t (file->sortMethod == TAG_FOLDSORTED  &&  file->search.ignorecase),\n\t\t\t\t\t\t nameAcceptable, NULL);\n}\n\nstatic tagResult findPseudoTag (tagFile *const file, int rewindBeforeFinding, tagEntry *const entry)\n{\n\tif (file == NULL)\n\t\treturn TagFailure;\n\n\tif (!file->initialized || file->err)\n\t{\n\t\tfile->err = TagErrnoInvalidArgument;\n\t\treturn TagFailure;\n\t}\n\n\tif (rewindBeforeFinding)\n\t{\n\t\tif (readtags_fseek(file->fp, 0, SEEK_SET) == -1)\n\t\t{\n\t\t\tfile->err = errno;\n\t\t\treturn TagFailure;\n\t\t}\n\t}\n\treturn findNextFull (file, entry,\n\t\t\t\t\t\t (file->sortMethod == TAG_SORTED || file->sortMethod == TAG_FOLDSORTED),\n\t\t\t\t\t\t doesFilePointPseudoTag,\n\t\t\t\t\t\t NULL);\n}\n\n\n/*\n*  EXTERNAL INTERFACE\n*/\n\nextern tagFile *tagsOpen (const char *const filePath, tagFileInfo *const info)\n{\n\ttagFileInfo infoDummy;\n\treturn initialize (filePath, info? info: &infoDummy);\n}\n\nextern tagResult tagsSetSortType (tagFile *const file, const tagSortType type)\n{\n\tif (file == NULL)\n\t\treturn TagFailure;\n\n\tif (!file->initialized || file->err)\n\t{\n\t\tfile->err = TagErrnoInvalidArgument;\n\t\treturn TagFailure;\n\t}\n\n\tswitch (type)\n\t{\n\tcase TAG_UNSORTED:\n\tcase TAG_SORTED:\n\tcase TAG_FOLDSORTED:\n\t\tfile->sortMethod = type;\n\t\treturn TagSuccess;\n\tdefault:\n\t\tfile->err = TagErrnoUnexpectedSortedMethod;\n\t\treturn TagFailure;\n\t}\n}\n\nextern tagResult tagsFirst (tagFile *const file, tagEntry *const entry)\n{\n\tif (file == NULL)\n\t\treturn TagFailure;\n\n\tif (!file->initialized || file->err)\n\t{\n\t\tfile->err = TagErrnoInvalidArgument;\n\t\treturn TagFailure;\n\t}\n\n\tif (gotoFirstLogicalTag (file) != TagSuccess)\n\t\treturn TagFailure;\n\treturn readNext (file, entry);\n}\n\nextern tagResult tagsNext (tagFile *const file, tagEntry *const entry)\n{\n\tif (file == NULL)\n\t\treturn TagFailure;\n\n\tif (!file->initialized || file->err)\n\t{\n\t\tfile->err = TagErrnoInvalidArgument;\n\t\treturn TagFailure;\n\t}\n\n\treturn readNext (file, entry);\n}\n\nextern const char *tagsField (const tagEntry *const entry, const char *const key)\n{\n\tconst char *result = NULL;\n\tif (entry != NULL)\n\t\tresult = readFieldValue (entry, key);\n\treturn result;\n}\n\nextern tagResult tagsFind (tagFile *const file, tagEntry *const entry,\n\t\t\t\t\t\t   const char *const name, const int options)\n{\n\tif (file == NULL)\n\t\treturn TagFailure;\n\n\tif (!file->initialized || file->err)\n\t{\n\t\tfile->err = TagErrnoInvalidArgument;\n\t\treturn TagFailure;\n\t}\n\n\treturn find (file, entry, name, options);\n}\n\nextern tagResult tagsFindNext (tagFile *const file, tagEntry *const entry)\n{\n\tif (file == NULL)\n\t\treturn TagFailure;\n\n\tif (!file->initialized || file->err)\n\t{\n\t\tfile->err = TagErrnoInvalidArgument;\n\t\treturn TagFailure;\n\t}\n\n\treturn findNext (file, entry);\n}\n\nextern tagResult tagsFirstPseudoTag (tagFile *const file, tagEntry *const entry)\n{\n\treturn findPseudoTag (file, 1, entry);\n}\n\nextern tagResult tagsNextPseudoTag (tagFile *const file, tagEntry *const entry)\n{\n\treturn findPseudoTag (file, 0, entry);\n}\n\nextern tagResult tagsFindPseudoTag (tagFile *const file, tagEntry *const entry,\n\t\t\t\t\t\t\t\t\tconst char *const name, const int match)\n{\n\tsize_t len;\n\ttagEntry entry0;\n\ttagEntry *entryp = entry? entry: &entry0;\n\n\ttagResult r = tagsFirstPseudoTag (file, entryp);\n\tif (r != TagSuccess)\n\t\treturn r;\n\n\tif (match & TAG_PARTIALMATCH)\n\t\tlen = strlen (name);\n\n\tdo\n\t{\n\t\tif (match & TAG_PARTIALMATCH)\n\t\t{\n\t\t\tif (strncmp (entryp->name, name, len) == 0)\n\t\t\t\treturn TagSuccess;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (strcmp (entryp->name, name) == 0)\n\t\t\t\treturn TagSuccess;\n\t\t}\n\t\tr = tagsNextPseudoTag (file, entryp);\n\t}\n\twhile (r == TagSuccess);\n\n\treturn r;\n}\n\nextern tagResult tagsClose (tagFile *const file)\n{\n\ttagResult result = TagFailure;\n\tif (file != NULL  &&  file->initialized)\n\t{\n\t\tterminate (file);\n\t\tresult = TagSuccess;\n\t}\n\treturn result;\n}\n\nextern int tagsGetErrno (tagFile *const file)\n{\n\tif (file == NULL)\n\t\treturn TagErrnoInvalidArgument;\n\treturn file->err;\n}\n"
  },
  {
    "path": "libreadtags/readtags.h",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   This source code is released for the public domain.\n*\n*   This file defines the public interface for looking up tag entries in tag\n*   files.\n*\n*   The functions defined in this interface are intended to provide tag file\n*   support to a software tool. The tag lookups provided are sufficiently fast\n*   enough to permit opening a sorted tag file, searching for a matching tag,\n*   then closing the tag file each time a tag is looked up (search times are\n*   on the order of hundredths of a second, even for huge tag files). This is\n*   the recommended use of this library for most tool applications. Adhering\n*   to this approach permits a user to regenerate a tag file at will without\n*   the tool needing to detect and resynchronize with changes to the tag file.\n*   Even for an unsorted 24MB tag file, tag searches take about one second.\n*/\n#ifndef READTAGS_H\n#define READTAGS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*\n*  MACROS\n*/\n\n/* Options for tagsSetSortType() */\ntypedef enum {\n\tTAG_UNSORTED, TAG_SORTED, TAG_FOLDSORTED\n} tagSortType ;\n\n/* For source code level compatibility, sortType is defined here.\n*  Define TAG_NO_COMPAT_SORT_TYPE if you want to avoid namespace pollution.\n*/\n#ifndef TAG_NO_COMPAT_SORT_TYPE\n#define sortType tagSortType\n#endif\n\n/* Options for tagsFind() and tagsFindPseudoTag() */\n#define TAG_FULLMATCH     0x0\n#define TAG_PARTIALMATCH  0x1\n\n#define TAG_OBSERVECASE   0x0\n#define TAG_IGNORECASE    0x2\n\n/*\n*  DATA DECLARATIONS\n*/\n\ntypedef enum { TagFailure = 0, TagSuccess = 1 } tagResult;\n\ntypedef enum {\n\tTagErrnoUnexpectedSortedMethod = -1, /* Unexpected sorted method */\n\tTagErrnoUnexpectedFormat       = -2, /* Unexpected format number */\n\tTagErrnoUnexpectedLineno       = -3, /* Unexpected value for line: field\n\t\t\t\t\t\t\t\t\t\t  * (Zero or a positive integer is expected.) */\n\tTagErrnoInvalidArgument        = -4, /* Unexpected argument passed to the API\n\t\t\t\t\t\t\t\t\t\t  * function */\n\tTagErrnoFileMaybeTooBig        = -5, /* Maybe the tags file is too big */\n} tagErrno;\n\nstruct sTagFile;\n\ntypedef struct sTagFile tagFile;\n\n/* This structure contains information about the tag file. */\ntypedef struct {\n\n\tstruct {\n\t\t\t/* was the tag file successfully opened? */\n\t\tint opened;\n\n\t\t\t/* errno value or tagErrno typed value\n\t\t\t   when 'opened' is false */\n\t\tint error_number;\n\t} status;\n\n\t\t/* information about the structure of the tag file */\n\tstruct {\n\t\t\t\t/* format of tag file (1 = original, 2 = extended) */\n\t\t\tshort format;\n\n\t\t\t\t/* how is the tag file sorted? */\n\t\t\ttagSortType sort;\n\t} file;\n\n\n\t\t/* information about the program which created this tag file */\n\tstruct {\n\t\t\t/* name of author of generating program (may be null) */\n\t\tconst char *author;\n\n\t\t\t/* name of program (may be null) */\n\t\tconst char *name;\n\n\t\t\t/* URL of distribution (may be null) */\n\t\tconst char *url;\n\n\t\t\t/* program version (may be null) */\n\t\tconst char *version;\n\t} program;\n\n} tagFileInfo;\n\n/* This structure contains information about an extension field for a tag.\n * These exist at the end of the tag in the form \"key:value\").\n */\ntypedef struct {\n\n\t\t/* the key of the extension field */\n\tconst char *key;\n\n\t\t/* the value of the extension field (may be an empty string) */\n\tconst char *value;\n\n} tagExtensionField;\n\n/* This structure contains information about a specific tag. */\ntypedef struct {\n\n\t\t/* name of tag */\n\tconst char *name;\n\n\t\t/* path of source file containing definition of tag.\n\t\t   For a broken tags file, this can be NULL. */\n\tconst char *file;\n\n\t\t/* address for locating tag in source file */\n\tstruct {\n\t\t\t/* pattern for locating source line\n\t\t\t * (may be NULL if not present) */\n\t\tconst char *pattern;\n\n\t\t\t/* line number in source file of tag definition\n\t\t\t * (may be zero if not known) */\n\t\tunsigned long lineNumber;\n\t} address;\n\n\t\t/* kind of tag (may by name, character, or NULL if not known) */\n\tconst char *kind;\n\n\t\t/* is tag of file-limited scope? */\n\tshort fileScope;\n\n\t\t/* miscellaneous extension fields */\n\tstruct {\n\t\t\t/* number of entries in `list' */\n\t\tunsigned short count;\n\n\t\t\t/* list of key value pairs */\n\t\ttagExtensionField *list;\n\t} fields;\n\n} tagEntry;\n\n\n/*\n*  FUNCTION PROTOTYPES\n*/\n\n/*\n*  This function must be called before calling other functions in this\n*  library. It is passed the path to the tag file to read and a (possibly\n*  null) pointer to a structure which, if not null, will be populated with\n*  information about the tag file. If successful, the function will return a\n*  handle which must be supplied to other calls to read information from the\n*  tag file, and info.status.opened will be set to true.\n*  If unsuccessful, the function will return NULL, and\n*  info.status.opened will be set to false and\n*  info.status.error_number will be set to either the errno value\n*  representing the system error preventing the tag file from being\n*  successfully opened, or the tagErrno typed value representing the\n*  library level error. The error_number will be ENOMEM if the memory\n*  allocation for the handle is failed.\n*/\nextern tagFile *tagsOpen (const char *const filePath, tagFileInfo *const info);\n\n/*\n*  This function allows the client to override the normal automatic detection\n*  of how a tag file is sorted. Permissible values for `type' are\n*  TAG_UNSORTED, TAG_SORTED, TAG_FOLDSORTED. Tag files in the new extended\n*  format contain a key indicating whether or not they are sorted. However,\n*  tag files in the original format do not contain such a key even when\n*  sorted, preventing this library from taking advantage of fast binary\n*  lookups. If the client knows that such an unmarked tag file is indeed\n*  sorted (or not), it can override the automatic detection. Note that\n*  incorrect lookup results will result if a tag file is marked as sorted when\n*  it actually is not. The function will return TagSuccess if called on an\n*  open tag file or TagFailure if not.\n*/\nextern tagResult tagsSetSortType (tagFile *const file, const tagSortType type);\n\n/*\n*  Reads the first tag in the file, if any. It is passed the handle to an\n*  opened tag file and a (possibly null) pointer to a structure which, if not\n*  null, will be populated with information about the first tag file entry.\n*  The function will return TagSuccess another tag entry is found, or\n*  TagFailure if not (i.e. it reached end of file).\n*/\nextern tagResult tagsFirst (tagFile *const file, tagEntry *const entry);\n\n/*\n*  Step to the next tag in the file, if any. It is passed the handle to an\n*  opened tag file and a (possibly null) pointer to a structure which, if not\n*  null, will be populated with information about the next tag file entry. The\n*  function will return TagSuccess another tag entry is found, or TagFailure\n*  if not (i.e. it reached end of file). It will always read the first tag in\n*  the file immediately after calling tagsOpen().\n*/\nextern tagResult tagsNext (tagFile *const file, tagEntry *const entry);\n\n/*\n*  Retrieve the value associated with the extension field for a specified key.\n*  It is passed a pointer to a structure already populated with values by a\n*  previous call to tagsNext(), tagsFind(), or tagsFindNext(), and a string\n*  containing the key of the desired extension field. If no such field of the\n*  specified key exists, the function will return null.\n*/\nextern const char *tagsField (const tagEntry *const entry, const char *const key);\n\n/*\n*  Find the first tag matching `name'. The structure pointed to by `entry'\n*  will be populated with information about the tag file entry. If a tag file\n*  is sorted using the C locale, a binary search algorithm is used to search\n*  the tag file, resulting in very fast tag lookups, even in huge tag files.\n*  Various options controlling the matches can be combined by bit-wise or-ing\n*  certain values together. The available values are:\n*\n*    TAG_PARTIALMATCH\n*        Tags whose leading characters match `name' will qualify.\n*\n*    TAG_FULLMATCH\n*        Only tags whose full lengths match `name' will qualify.\n*\n*    TAG_IGNORECASE\n*        Matching will be performed in a case-insensitive manner. Note that\n*        this disables binary searches of the tag file.\n*\n*    TAG_OBSERVECASE\n*        Matching will be performed in a case-sensitive manner. Note that\n*        this enables binary searches of the tag file.\n*\n*  The function will return TagSuccess if a tag matching the name is found, or\n*  TagFailure if not.\n*/\nextern tagResult tagsFind (tagFile *const file, tagEntry *const entry, const char *const name, const int options);\n\n/*\n*  Find the next tag matching the name and options supplied to the most recent\n*  call to tagsFind() for the same tag file. The structure pointed to by\n*  `entry' will be populated with information about the tag file entry. The\n*  function will return TagSuccess if another tag matching the name is found,\n*  or TagFailure if not.\n*/\nextern tagResult tagsFindNext (tagFile *const file, tagEntry *const entry);\n\n/*\n*  Does the same as tagsFirst(), but is specialized to pseudo tags.\n*  If tagFileInfo doesn't contain pseudo tags you are interested in, read\n*  them sequentially with this function and tagsNextPseudoTag().\n*/\nextern tagResult tagsFirstPseudoTag (tagFile *const file, tagEntry *const entry);\n\n/*\n*  Does the same as tagsNext(), but is specialized to pseudo tags. Use with\n*  tagsFirstPseudoTag().\n*/\nextern tagResult tagsNextPseudoTag (tagFile *const file, tagEntry *const entry);\n\n/*\n* Does the same as tagsFind(), but is specialized to pseudo tags.\n* The available values for `match' are:\n*\n*    TAG_PARTIALMATCH\n*        Tags whose leading characters match `name' will qualify.\n*\n*    TAG_FULLMATCH\n*        Only tags whose full lengths match `name' will qualify.\n*\n* NOTE: unlike tagsFind(), this function uses liner-searching even if\n* the tags file is sorted.\n*/\nextern tagResult tagsFindPseudoTag (tagFile *const file, tagEntry *const entry, const char *const name, const int match);\n\n/*\n*  Call tagsClose() at completion of reading the tag file, which will\n*  close the file and free any internal memory allocated. The function will\n*  return TagFailure if no file is currently open, TagSuccess otherwise.\n*/\nextern tagResult tagsClose (tagFile *const file);\n\n/*\n*  Get the error status set in the last API call.\n*  Much of the API functions return TagFailure because (1) no tag is\n*  found, or (2) an error occurs. tagsGetErrno() is for distinguishing\n*  (1) or (2). This function will return 0 for (1). The errno value\n*  representing the system error or tagErrno value for (2).\n*\n*  This function does not deal with the results of tagsOpen(),\n*  tagsClose(), and tagsField().\n*/\nextern int tagsGetErrno (tagFile *const file);\n\n#ifdef __cplusplus\n};\n#endif\n\n#endif\n"
  },
  {
    "path": "libreadtags/test_inline.c",
    "content": "/* Taken from  https://gitlab.kitware.com/cmake/community/-/wikis/contrib/macros/TestInline\n * for using \"inline\" with cmake build. */\n/* Test source lifted from /usr/share/autoconf/autoconf/c.m4 */\ntypedef int foo_t;\nstatic inline foo_t static_foo(){return 0;}\nfoo_t foo(){return 0;}\nint main(int argc, char *argv[]){return 0;}\n"
  },
  {
    "path": "libreadtags/tests/Makefile.am",
    "content": "TESTS = \\\n\t\\\n\ttest-api-tagsOpen \\\n\ttest-api-tagsFind \\\n\ttest-api-tagsFindPseudoTag \\\n\ttest-api-tagsFirstPseudoTag \\\n\ttest-api-tagsFirst \\\n\ttest-api-tagsClose \\\n\ttest-api-tagsSetSortType \\\n\t\\\n\ttest-fix-unescaping \\\n\ttest-fix-null-deref \\\n\ttest-fix-large-tags \\\n\ttest-fix-unescaping-input-fields \\\n\ttest-fix-unescaping-input-fields-exuberant \\\n\ttest-fix-unescaping-input-fields-no-mode \\\n\ttest-fix-unescaping-input-fields-backslash \\\n\ttest-fix-unescaping-input-fields-no-filesep \\\n\t\\\n\t$(NULL)\n\ncheck_PROGRAMS = \\\n\t\\\n\ttest-api-tagsOpen \\\n\ttest-api-tagsFind \\\n\ttest-api-tagsFindPseudoTag \\\n\ttest-api-tagsFirstPseudoTag \\\n\ttest-api-tagsFirst \\\n\ttest-api-tagsClose \\\n\ttest-api-tagsSetSortType \\\n\t\\\n\ttest-fix-unescaping \\\n\ttest-fix-null-deref \\\n\ttest-fix-large-tags \\\n\ttest-fix-unescaping-input-fields \\\n\ttest-fix-unescaping-input-fields-exuberant \\\n\ttest-fix-unescaping-input-fields-no-mode \\\n\ttest-fix-unescaping-input-fields-backslash \\\n\ttest-fix-unescaping-input-fields-no-filesep \\\n\t\\\n\t$(NULL)\n\nEXTRA_DIST = test-fields.h\n\nAM_CPPFLAGS = -I $(top_srcdir) -DTAG_NO_COMPAT_SORT_TYPE\nAM_CFLAGS = $(GCOV_CFLAGS)\nDEPS = $(top_builddir)/libreadtags.la\nLDADD = $(top_builddir)/libreadtags.la\n\ntest_api_tagsOpen = test-api-tagsOpen.c\ntest_api_tagsOpen_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += api-tagsOpen-ectags.tags\nEXTRA_DIST += api-tagsOpen-wrong-format-nonum.tags\nEXTRA_DIST += api-tagsOpen-wrong-format-num.tags\nEXTRA_DIST += api-tagsOpen-wrong-sort-method-nonum.tags\nEXTRA_DIST += api-tagsOpen-wrong-sort-method-num.tags\nEXTRA_DIST += api-tagsOpen-incomplete-program-author-0.tags\nEXTRA_DIST += api-tagsOpen-incomplete-program-author-1.tags\nEXTRA_DIST += api-tagsOpen-incomplete-program-author-2.tags\nEXTRA_DIST += api-tagsOpen-incomplete-program-author-3.tags\nEXTRA_DIST += api-tagsOpen-incomplete-program-author-4.tags\nEXTRA_DIST += api-tagsOpen-incomplete-program-author-5.tags\n\ntest_api_tagsFind = test-api-tagsFind.c\ntest_api_tagsFind_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += duplicated-names.c\nEXTRA_DIST += duplicated-names--sorted-yes.tags\nEXTRA_DIST += duplicated-names--sorted-no.tags\nEXTRA_DIST += duplicated-names--sorted-foldcase.tags\nEXTRA_DIST += broken-line-field-in-middle.tags\n\ntest_api_tagsFindPseudoTag = test-api-tagsFindPseudoTag.c\ntest_api_tagsFindPseudoTag_DEPENDENCIES = $(DEPS)\n\ntest_api_tagsFirstPseudoTag = test-api-tagsFirstPseudoTag.c\ntest_api_tagsFirstPseudoTag_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += ptag-sort-no.tags\nEXTRA_DIST += ptag-sort-yes.tags\n\ntest_api_tagsFirst = test-api-tagsFirst.c\ntest_api_tagsFirst_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += empty.tags\nEXTRA_DIST += empty-no-newline.tags\nEXTRA_DIST += broken-line-field.tags\nEXTRA_DIST += broken-line-field-other-than-first.tags\n\ntest_api_tagsClose = test-api-tagsClose.c\ntest_api_tagsClose_DEPENDENCIES = $(DEPS)\n\ntest_api_tagsSetSortType = test-api-tagsSetSortType.c\ntest_api_tagsSetSortType_DEPENDENCIES = $(DEPS)\n\ntest_fix_unescaping = test-fix-unescaping.c\ntest_fix_unescaping_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += unescaping.tags\n\ntest_fix_null_deref = test-fix-null-deref.c\ntest_fix_null_deref_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += null-deref.tags\n\ntest_fix_large_tags = test-fix-large-tags.c\ntest_fix_large_tags_DEPENDENCIES = $(DEPS)\n\ntest_fix_unescaping_input_fields = test-fix-unescaping-input-fields.c\ntest_fix_unescaping_input_fields_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += unescaping-input-fields.tags\n\ntest_fix_unescaping_input_fields_exuberant = test-fix-unescaping-input-fields-exuberant.c\ntest_fix_unescaping_input_fields_exuberant_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += unescaping-input-fields-exuberant.tags\n\ntest_fix_unescaping_input_fields_no_mode = test-fix-unescaping-input-fields-no-mode.c\ntest_fix_unescaping_input_fields_no_mode_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += unescaping-input-fields-no-mode.tags\n\ntest_fix_unescaping_input_fields_backslash = test-fix-unescaping-input-fields-backslash.c\ntest_fix_unescaping_input_fields_backslash_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += unescaping-input-fields-backslash.tags\n\ntest_fix_unescaping_input_fields_no_filesep = test-fix-unescaping-input-fields-no-filesep.c\ntest_fix_unescaping_input_fields_no_filesep_DEPENDENCIES = $(DEPS)\nEXTRA_DIST += unescaping-input-fields-no-filesep.tags\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-ectags.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tDarren Hiebert\t/dhiebert@users.sourceforge.net/\n!_TAG_PROGRAM_NAME\tExuberant Ctags\t//\n!_TAG_PROGRAM_URL\thttp://ctags.sourceforge.net\t/official site/\n!_TAG_PROGRAM_VERSION\t5.8\t//\nmain\ttest-api-tagsOpen.c\t/^main(void)$/;\"\tf\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-incomplete-program-author-0.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-incomplete-program-author-1.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-incomplete-program-author-2.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\t\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-incomplete-program-author-3.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-incomplete-program-author-4.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-incomplete-program-author-5.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-wrong-format-nonum.tags",
    "content": "!_TAG_FILE_FORMAT\tx\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-wrong-format-num.tags",
    "content": "!_TAG_FILE_FORMAT\t3\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-wrong-sort-method-nonum.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t-x\t/0=unsorted, 1=sorted, 2=foldcase/\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/api-tagsOpen-wrong-sort-method-num.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t3\t/0=unsorted, 1=sorted, 2=foldcase/\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/broken-line-field-in-middle.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/jet/var/libreadtags/tests/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t5.9.0\t/a8bf418d/\nM\tduplicated-names.c\t/^int M (void) { return 0; }$/;\"\tf\tline:24\ttyperef:typename:int\nN\tduplicated-names.c\t/^int N;$/;\"\tv\tline:9\ttyperef:typename:int\nO\tduplicated-names.c\t/^int O (void) { return 0; }$/;\"\tf\tline:7\ttyperef:typename:int\nduplicated-names.c\tduplicated-names.c\t1;\"\tF\tline:1\tepoch:1608822975\nm\tduplicated-names.c\t/^int m;$/;\"\tv\tline:23\ttyperef:typename:int\nmain\tduplicated-names.c\t/^int main(int n)$/;\"\tf\tline:14\ttyperef:typename:int\nn\tduplicated-names.c\t/^\tint n;$/;\"\tm\tline:-11\tstruct:n\ttyperef:typename:int\tfile:\nn\tduplicated-names.c\t/^struct n {$/;\"\ts\tline:10\tfile:\nn\tduplicated-names.c\t/^typedef int n;$/;\"\tt\tline:13\ttyperef:typename:int\tfile:\no\tduplicated-names.c\t/^int o;$/;\"\tv\tline:6\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/broken-line-field-other-than-first.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/jet/var/libreadtags/tests/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t5.9.0\t/a8bf418d/\nM\tduplicated-names.c\t/^int M (void) { return 0; }$/;\"\tf\tline:24\ttyperef:typename:int\nN\tduplicated-names.c\t/^int N;$/;\"\tv\tline:9\ttyperef:typename:int\nO\tduplicated-names.c\t/^int O (void) { return 0; }$/;\"\tf\tline:x7\ttyperef:typename:int\nduplicated-names.c\tduplicated-names.c\t1;\"\tF\tline:x1\tepoch:1608822975\nm\tduplicated-names.c\t/^int m;$/;\"\tv\tline:x23\ttyperef:typename:int\nmain\tduplicated-names.c\t/^int main(int n)$/;\"\tf\tline:x14\ttyperef:typename:int\nn\tduplicated-names.c\t/^\tint n;$/;\"\tm\tline:x11\tstruct:n\ttyperef:typename:int\tfile:\nn\tduplicated-names.c\t/^struct n {$/;\"\ts\tline:x10\tfile:\nn\tduplicated-names.c\t/^typedef int n;$/;\"\tt\tline:x13\ttyperef:typename:int\tfile:\no\tduplicated-names.c\t/^int o;$/;\"\tv\tline:x6\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/broken-line-field.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROC_CWD\t/home/jet/var/libreadtags/tests/\t//\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t5.9.0\t/a8bf418d/\nM\tduplicated-names.c\t/^int M (void) { return 0; }$/;\"\tf\tline:x24\ttyperef:typename:int\nN\tduplicated-names.c\t/^int N;$/;\"\tv\tline:x9\ttyperef:typename:int\nO\tduplicated-names.c\t/^int O (void) { return 0; }$/;\"\tf\tline:x7\ttyperef:typename:int\nduplicated-names.c\tduplicated-names.c\t1;\"\tF\tline:x1\tepoch:1608822975\nm\tduplicated-names.c\t/^int m;$/;\"\tv\tline:x23\ttyperef:typename:int\nmain\tduplicated-names.c\t/^int main(int n)$/;\"\tf\tline:x14\ttyperef:typename:int\nn\tduplicated-names.c\t/^\tint n;$/;\"\tm\tline:x11\tstruct:n\ttyperef:typename:int\tfile:\nn\tduplicated-names.c\t/^struct n {$/;\"\ts\tline:x10\tfile:\nn\tduplicated-names.c\t/^typedef int n;$/;\"\tt\tline:x13\ttyperef:typename:int\tfile:\no\tduplicated-names.c\t/^int o;$/;\"\tv\tline:x6\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/duplicated-names--sorted-foldcase.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t2\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nM\tinput.c\t/^int M (void) { return 0; }$/;\"\tf\ttyperef:typename:int\nm\tinput.c\t/^int m;$/;\"\tv\ttyperef:typename:int\nmain\tinput.c\t/^int main(int n)$/;\"\tf\ttyperef:typename:int\nn\tinput.c\t/^\t\tint n;$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nn\tinput.c\t/^\tfor (int n = 0; n < 1; n++)$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nn\tinput.c\t/^\tint n;$/;\"\tm\tstruct:n\ttyperef:typename:int\tfile:\nn\tinput.c\t/^int main(int n)$/;\"\tz\tfunction:main\ttyperef:typename:int\tfile:\nN\tinput.c\t/^int N;$/;\"\tv\ttyperef:typename:int\nn\tinput.c\t/^struct n {$/;\"\ts\tfile:\nn\tinput.c\t/^typedef int n;$/;\"\tt\ttyperef:typename:int\tfile:\nO\tinput.c\t/^int O (void) { return 0; }$/;\"\tf\ttyperef:typename:int\no\tinput.c\t/^int o;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/duplicated-names--sorted-no.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\no\tinput.c\t/^int o;$/;\"\tv\ttyperef:typename:int\nO\tinput.c\t/^int O (void) { return 0; }$/;\"\tf\ttyperef:typename:int\nN\tinput.c\t/^int N;$/;\"\tv\ttyperef:typename:int\nn\tinput.c\t/^struct n {$/;\"\ts\tfile:\nn\tinput.c\t/^\tint n;$/;\"\tm\tstruct:n\ttyperef:typename:int\tfile:\nn\tinput.c\t/^typedef int n;$/;\"\tt\ttyperef:typename:int\tfile:\nmain\tinput.c\t/^int main(int n)$/;\"\tf\ttyperef:typename:int\nn\tinput.c\t/^int main(int n)$/;\"\tz\tfunction:main\ttyperef:typename:int\tfile:\nn\tinput.c\t/^\tfor (int n = 0; n < 1; n++)$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nn\tinput.c\t/^\t\tint n;$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nm\tinput.c\t/^int m;$/;\"\tv\ttyperef:typename:int\nM\tinput.c\t/^int M (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/duplicated-names--sorted-yes.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nM\tinput.c\t/^int M (void) { return 0; }$/;\"\tf\ttyperef:typename:int\nN\tinput.c\t/^int N;$/;\"\tv\ttyperef:typename:int\nO\tinput.c\t/^int O (void) { return 0; }$/;\"\tf\ttyperef:typename:int\nm\tinput.c\t/^int m;$/;\"\tv\ttyperef:typename:int\nmain\tinput.c\t/^int main(int n)$/;\"\tf\ttyperef:typename:int\nn\tinput.c\t/^\t\tint n;$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nn\tinput.c\t/^\tfor (int n = 0; n < 1; n++)$/;\"\tl\tfunction:main\ttyperef:typename:int\tfile:\nn\tinput.c\t/^\tint n;$/;\"\tm\tstruct:n\ttyperef:typename:int\tfile:\nn\tinput.c\t/^int main(int n)$/;\"\tz\tfunction:main\ttyperef:typename:int\tfile:\nn\tinput.c\t/^struct n {$/;\"\ts\tfile:\nn\tinput.c\t/^typedef int n;$/;\"\tt\ttyperef:typename:int\tfile:\no\tinput.c\t/^int o;$/;\"\tv\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/duplicated-names.c",
    "content": "/*\n * for s in yes foldcase no; do\n *   u-ctags --quiet --options=NONE -o duplicated-names--sorted-$s.tags --kinds-C='*' --sort=$s duplicated-names.c\n * done\n *\n * u-ctags --extras=+pf --fields=+n -o - duplicated-names.c \\\n * | sed -e 's/line:/line:x/' \\\n * > broken-line-field.tags\n *\n\n */\nint o;\nint O (void) { return 0; }\n\nint N;\nstruct n {\n\tint n;\n};\ntypedef int n;\nint main(int n)\n{\n\tfor (int n = 0; n < 1; n++)\n\t{\n\t\tint n;\n\t\treturn 0;\n\t}\n}\n\nint m;\nint M (void) { return 0; }\n"
  },
  {
    "path": "libreadtags/tests/empty-no-newline.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/"
  },
  {
    "path": "libreadtags/tests/empty.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\n"
  },
  {
    "path": "libreadtags/tests/null-deref.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\n\\x21a\n"
  },
  {
    "path": "libreadtags/tests/ptag-sort-no.tags",
    "content": "!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\n"
  },
  {
    "path": "libreadtags/tests/ptag-sort-yes.tags",
    "content": "!_JSON_OUTPUT_VERSION\t0.0\t/in development/\n!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_KIND_DESCRIPTION!C\tD,macroparam\t/parameters inside macro definitions/\n!_TAG_KIND_DESCRIPTION!C\tL,label\t/goto labels/\n!_TAG_KIND_DESCRIPTION!C\td,macro\t/macro definitions/\n!_TAG_KIND_DESCRIPTION!C\te,enumerator\t/enumerators (values inside an enumeration)/\n!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n!_TAG_KIND_DESCRIPTION!C\tg,enum\t/enumeration names/\n!_TAG_KIND_DESCRIPTION!C\th,header\t/included header files/\n!_TAG_KIND_DESCRIPTION!C\tl,local\t/local variables/\n!_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n!_TAG_KIND_DESCRIPTION!C\tp,prototype\t/function prototypes/\n!_TAG_KIND_DESCRIPTION!C\ts,struct\t/structure names/\n!_TAG_KIND_DESCRIPTION!C\tt,typedef\t/typedefs/\n!_TAG_KIND_DESCRIPTION!C\tu,union\t/union names/\n!_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n!_TAG_KIND_DESCRIPTION!C\tx,externvar\t/external and forward variable declarations/\n!_TAG_KIND_DESCRIPTION!C\tz,parameter\t/function parameters inside function definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tC,custom\t/customizable variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tD,derivedMode\t/derived major mode/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tG,group\t/customization groups/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tH,face\t/customizable faces/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tM,minorMode\t/minor modes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tT,theme\t/custom themes/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tV,varalias\t/aliases for variables/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ta,alias\t/aliases for functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tc,const\t/constants/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\te,error\t/errors/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tf,function\t/functions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ti,inline\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tm,macro\t/macros/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\ts,subst\t/inline function/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tu,unknown\t/unknown type of definitions/\n!_TAG_KIND_DESCRIPTION!EmacsLisp\tv,variable\t/variables/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/9b73623f/\nafunc\tinput.el\t/^(defun afunc () nil)$/;\"\tf\nmain\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n"
  },
  {
    "path": "libreadtags/tests/test-api-tagsClose.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing tagsClose() API function for broken argument\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\tfprintf (stderr, \"closing NULL...\");\n\tif (tagsClose (NULL) == TagSuccess)\n\t{\n\t\tfprintf (stderr, \"successful unexpectedly\\n\");\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-api-tagsFind.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing tagsFind() and tagsFindNext() API functions\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n\nstruct expectation {\n\tchar *name;\n\tchar *file;\n\tchar *pattern;\n\tchar *kind;\n\tchar *scope_kind;\n\tchar *scope_name;\n\tchar *typeref;\n\tint fileScope;\n\n\ttagResult result;\n\tint       err;\n};\n\n#define COUNT(x) (sizeof(x)/sizeof(x[0]))\n\nenum extraTest { TESTX_NO_REMAIN, TESTX_INVALID_ARG };\n\nstatic int\ncheck_finding0 (tagFile *t, const char *name, const int options,\n\t\t\t\tstruct expectation *expectations, int count, enum extraTest xtest)\n{\n\ttagEntry e;\n\tstruct expectation *x;\n\tint err;\n\n\tfor (int i = 0; i < count; i++)\n\t{\n\t\tfprintf (stderr, \"[%d/%d] finding \\\"%s\\\" (%d)...\", i + 1, count, name, options);\n\t\ttagResult r = (i == 0)\n\t\t\t? tagsFind (t, &e, name, options)\n\t\t\t: tagsFindNext (t, &e);\n\t\tx = expectations + i;\n\t\tif (r == TagSuccess)\n\t\t{\n\t\t\tif (x->result == TagFailure)\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"found unexpectedly\\n\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\telse\n\t\t\t\tfprintf (stderr, \"found as expected\\n\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (x->result == TagFailure)\n\t\t\t{\n\t\t\t\terr = tagsGetErrno (t);\n\t\t\t\tif (err == x->err)\n\t\t\t\t{\n\t\t\t\t\tif (err == 0)\n\t\t\t\t\t\tfprintf (stderr, \"not found, and it is expected\\n\");\n\t\t\t\t\telse\n\t\t\t\t\t\tfprintf (stderr, \"error as expected: %d\\n\", err);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfprintf (stderr, \"error number doesn't match: %d (expected: %d)\\n\",\n\t\t\t\t\t\t\t err, x->err);\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif ((err = tagsGetErrno (t)))\n\t\t\t\t\tfprintf (stderr, \"error: %d\\n\", err);\n\t\t\t\telse\n\t\t\t\t\tfprintf (stderr, \"not found\\n\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tfprintf (stderr, \"checking name field...\");\n\t\tif (!(e.name && strcmp (x->name, e.name) == 0))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected: %s\\n\", e.name? e.name: \"<NULL>\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\n\t\tfprintf (stderr, \"checking file field...\");\n\t\tif (!(e.file && strcmp (x->file, e.file) == 0))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected\\n\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\n\t\tfprintf (stderr, \"checking pattern field...\");\n\t\tif (!(e.address.pattern && strcmp (x->pattern, e.address.pattern) == 0))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected: %s\\n\",\n\t\t\t\t\t e.address.pattern? e.address.pattern: \"<NULL>\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\n\t\tfprintf (stderr, \"checking kind field...\");\n\t\tif (!(e.kind && strcmp (x->kind, e.kind) == 0))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected\\n\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\n\t\tif (x->scope_kind)\n\t\t{\n\t\t\tfprintf (stderr, \"checking scope field...\");\n\t\t\tconst char *scope = tagsField (&e, x->scope_kind);\n\t\t\tif (scope == NULL || strcmp (scope, x->scope_name) != 0)\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"unexpected: %s\\n\", scope? scope: \"<NULL>\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tfprintf (stderr, \"ok\\n\");\n\t\t}\n\n\t\tif (x->typeref)\n\t\t{\n\t\t\tfprintf (stderr, \"checking typeref field...\");\n\t\t\tconst char *typeref = tagsField (&e, \"typeref\");\n\t\t\tif (typeref == NULL || strcmp (typeref, x->typeref) != 0)\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"unexpected: %s\\n\", typeref? typeref: \"<NULL>\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tfprintf (stderr, \"ok\\n\");\n\t\t}\n\n\t\tfprintf (stderr, \"checking file field...\");\n\t\tif (x->fileScope != e.fileScope)\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected\\n\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\t}\n\n\tif (xtest == TESTX_NO_REMAIN)\n\t{\n\t\tfprintf (stderr, \"verifying no remain....\");\n\t\tif (tagsFindNext (t, &e) == TagSuccess)\n\t\t{\n\t\t\tfprintf (stderr, \"still existing\\n\");\n\t\t\treturn 1;\n\t\t}\n\t\telse if ((err = tagsGetErrno (t)))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected error: %d\\n\", err);\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\t}\n\telse if (xtest == TESTX_NO_REMAIN)\n\t{\n\t\tfprintf (stderr, \"call tagsFindNext after getting an error....\");\n\t\tif (tagsFindNext (t, &e) == TagSuccess)\n\t\t{\n\t\t\tfprintf (stderr, \"unexpectedly successful\\n\");\n\t\t\treturn 1;\n\t\t}\n\n\t\terr = tagsGetErrno (t);\n\t\tif (err != TagErrnoInvalidArgument)\n\t\t{\n\t\t\tfprintf (stderr, \"errer number doesn't match: %d (expected: %d)\\n\",\n\t\t\t\t\t err, TagErrnoInvalidArgument);\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"get TagErrnoInvalidArgument expectedly\\n\");\n\t}\n\n\treturn 0;\n}\n\nstatic int\ncheck_finding (const char *tags, const char *name, const int options,\n\t\t\t   struct expectation *expectations, int count, enum extraTest xtest)\n{\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tfprintf (stderr, \"opening %s...\", tags);\n\tt = tagsOpen (tags, &info);\n\tif (!t)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d, error_number: %d)\\n\",\n\t\t\t\t t, info.status.opened, info.status.error_number);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tif (check_finding0 (t, name, options, expectations, count, xtest) != 0)\n\t\treturn 1;\n\n\tfprintf (stderr, \"closing the tag file...\");\n\tif (tagsClose (t) != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\treturn 0;\n}\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\t/*\n\t * sorted=yes\n\t */\n\tconst char *tags_sorted_yes = \"./duplicated-names--sorted-yes.tags\";\n\tstruct expectation sorted_yes_FULLMATCH_OBSERVECASE [] = {\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^\t\tint n;$/\",\n\t\t\t.kind = \"l\",\n\t\t\t.scope_kind = \"function\",\n\t\t\t.scope_name = \"main\",\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^\tfor (int n = 0; n < 1; n++)$/\",\n\t\t\t.kind = \"l\",\n\t\t\t.scope_kind = \"function\",\n\t\t\t.scope_name = \"main\",\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^\tint n;$/\",\n\t\t\t.kind = \"m\",\n\t\t\t.scope_kind = \"struct\",\n\t\t\t.scope_name = \"n\",\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int main(int n)$/\",\n\t\t\t.kind = \"z\",\n\t\t\t.scope_kind = \"function\",\n\t\t\t.scope_name = \"main\",\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^struct n {$/\",\n\t\t\t.kind = \"s\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = NULL,\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^typedef int n;$/\",\n\t\t\t.kind = \"t\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t};\n\n\tstruct expectation sorted_yes_FULLMATCH_IGNORECASE [COUNT(sorted_yes_FULLMATCH_OBSERVECASE) + 1] = {\n\t\t[0] = {\n\t\t\t.name = \"N\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int N;$/\",\n\t\t\t.kind = \"v\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 0,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t};\n\tfor (int i = 0; i < COUNT(sorted_yes_FULLMATCH_OBSERVECASE); i++)\n\t\tsorted_yes_FULLMATCH_IGNORECASE [i + 1] = sorted_yes_FULLMATCH_OBSERVECASE [i];\n\n\tstruct expectation sorted_yes_PARTIALMATCH_OBSERVECASE [] = {\n\t\t{\n\t\t\t.name = \"m\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int m;$/\",\n\t\t\t.kind = \"v\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 0,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"main\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int main(int n)$/\",\n\t\t\t.kind = \"f\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 0,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t};\n\n\tstruct expectation sorted_yes_PARTIALMATCH_IGNORECASE [COUNT(sorted_yes_PARTIALMATCH_OBSERVECASE) + 1] = {\n\t\t[0] = {\n\t\t\t.name = \"M\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int M (void) { return 0; }$/\",\n\t\t\t.kind = \"f\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 0,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t};\n\tfor (int i = 0; i < COUNT(sorted_yes_PARTIALMATCH_OBSERVECASE); i++)\n\t\tsorted_yes_PARTIALMATCH_IGNORECASE [i + 1] = sorted_yes_PARTIALMATCH_OBSERVECASE [i];\n\n\tif (check_finding (tags_sorted_yes, \"n\", TAG_FULLMATCH|TAG_OBSERVECASE,\n\t\t\t\t\t   sorted_yes_FULLMATCH_OBSERVECASE, COUNT(sorted_yes_FULLMATCH_OBSERVECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\tif (check_finding (tags_sorted_yes, \"n\", TAG_FULLMATCH|TAG_IGNORECASE,\n\t\t\t\t\t   sorted_yes_FULLMATCH_IGNORECASE, COUNT(sorted_yes_FULLMATCH_IGNORECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\tif (check_finding (tags_sorted_yes, \"m\", TAG_PARTIALMATCH|TAG_OBSERVECASE,\n\t\t\t\t\t   sorted_yes_PARTIALMATCH_OBSERVECASE, COUNT(sorted_yes_PARTIALMATCH_OBSERVECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\tif (check_finding (tags_sorted_yes, \"m\", TAG_PARTIALMATCH|TAG_IGNORECASE,\n\t\t\t\t\t   sorted_yes_PARTIALMATCH_IGNORECASE, COUNT(sorted_yes_PARTIALMATCH_IGNORECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\n\t/*\n\t * sorted=no\n\t */\n\tconst char *tags_sorted_no = \"./duplicated-names--sorted-no.tags\";\n\tstruct expectation sorted_no_FULLMATCH_OBSERVECASE [] = {\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^struct n {$/\",\n\t\t\t.kind = \"s\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = NULL,\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^\tint n;$/\",\n\t\t\t.kind = \"m\",\n\t\t\t.scope_kind = \"struct\",\n\t\t\t.scope_name = \"n\",\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^typedef int n;$/\",\n\t\t\t.kind = \"t\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int main(int n)$/\",\n\t\t\t.kind = \"z\",\n\t\t\t.scope_kind = \"function\",\n\t\t\t.scope_name = \"main\",\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^\tfor (int n = 0; n < 1; n++)$/\",\n\t\t\t.kind = \"l\",\n\t\t\t.scope_kind = \"function\",\n\t\t\t.scope_name = \"main\",\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"n\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^\t\tint n;$/\",\n\t\t\t.kind = \"l\",\n\t\t\t.scope_kind = \"function\",\n\t\t\t.scope_name = \"main\",\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 1,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t};\n\n\tstruct expectation sorted_no_FULLMATCH_IGNORECASE [COUNT(sorted_no_FULLMATCH_OBSERVECASE) + 1] = {\n\t\t[0] = {\n\t\t\t.name = \"N\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int N;$/\",\n\t\t\t.kind = \"v\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 0,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t};\n\tfor (int i = 0; i < COUNT(sorted_no_FULLMATCH_OBSERVECASE); i++)\n\t\tsorted_no_FULLMATCH_IGNORECASE [i + 1] = sorted_no_FULLMATCH_OBSERVECASE [i];\n\n\tstruct expectation sorted_no_PARTIALMATCH_OBSERVECASE [] = {\n\t\t{\n\t\t\t.name = \"main\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int main(int n)$/\",\n\t\t\t.kind = \"f\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 0,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.name = \"m\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int m;$/\",\n\t\t\t.kind = \"v\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 0,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t};\n\n\tstruct expectation sorted_no_PARTIALMATCH_IGNORECASE [COUNT(sorted_no_PARTIALMATCH_OBSERVECASE) + 1] = {\n\t\t[COUNT(sorted_no_PARTIALMATCH_OBSERVECASE)] = {\n\t\t\t.name = \"M\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int M (void) { return 0; }$/\",\n\t\t\t.kind = \"f\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 0,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t};\n\tfor (int i = 0; i < COUNT(sorted_no_PARTIALMATCH_OBSERVECASE); i++)\n\t\tsorted_no_PARTIALMATCH_IGNORECASE [i] = sorted_no_PARTIALMATCH_OBSERVECASE [i];\n\n\tif (check_finding (tags_sorted_no, \"n\", TAG_FULLMATCH|TAG_OBSERVECASE,\n\t\t\t\t\t   sorted_no_FULLMATCH_OBSERVECASE, COUNT(sorted_no_FULLMATCH_OBSERVECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\tif (check_finding (tags_sorted_no, \"n\", TAG_FULLMATCH|TAG_IGNORECASE,\n\t\t\t\t\t   sorted_no_FULLMATCH_IGNORECASE, COUNT(sorted_no_FULLMATCH_IGNORECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\tif (check_finding (tags_sorted_no, \"m\", TAG_PARTIALMATCH|TAG_OBSERVECASE,\n\t\t\t\t\t   sorted_no_PARTIALMATCH_OBSERVECASE, COUNT(sorted_no_PARTIALMATCH_OBSERVECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\tif (check_finding (tags_sorted_no, \"m\", TAG_PARTIALMATCH|TAG_IGNORECASE,\n\t\t\t\t\t   sorted_no_PARTIALMATCH_IGNORECASE, COUNT(sorted_no_PARTIALMATCH_IGNORECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\n\t/*\n\t * sorted=foldcase\n\t */\n\tconst char *tags_sorted_foldcase = \"./duplicated-names--sorted-foldcase.tags\";\n\tstruct expectation sorted_foldcase_FULLMATCH_OBSERVECASE [COUNT(sorted_yes_FULLMATCH_OBSERVECASE)];\n\tfor (int i = 0; i < COUNT(sorted_foldcase_FULLMATCH_OBSERVECASE); i++)\n\t\tsorted_foldcase_FULLMATCH_OBSERVECASE [i] =  sorted_yes_FULLMATCH_OBSERVECASE [i];\n\n\tstruct expectation sorted_foldcase_FULLMATCH_IGNORECASE [COUNT(sorted_foldcase_FULLMATCH_OBSERVECASE) + 1] = {\n\t\t[4] = {\n\t\t\t.name = \"N\",\n\t\t\t.file = \"input.c\",\n\t\t\t.pattern = \"/^int N;$/\",\n\t\t\t.kind = \"v\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 0,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t[5] = sorted_foldcase_FULLMATCH_OBSERVECASE[4],\n\t\t[6] = sorted_foldcase_FULLMATCH_OBSERVECASE[5],\n\t};\n\tfor (int i = 0; i < 4; i++)\n\t\tsorted_foldcase_FULLMATCH_IGNORECASE [i] = sorted_foldcase_FULLMATCH_OBSERVECASE [i];\n\n\tstruct expectation sorted_foldcase_PARTIALMATCH_OBSERVECASE [COUNT(sorted_yes_PARTIALMATCH_OBSERVECASE)];\n\tfor (int i = 0; i < COUNT(sorted_foldcase_PARTIALMATCH_OBSERVECASE); i++)\n\t\tsorted_foldcase_PARTIALMATCH_OBSERVECASE [i] =  sorted_yes_PARTIALMATCH_OBSERVECASE [i];\n\n\tstruct expectation sorted_foldcase_PARTIALMATCH_IGNORECASE [COUNT(sorted_yes_PARTIALMATCH_IGNORECASE)];\n\tfor (int i = 0; i < COUNT(sorted_foldcase_PARTIALMATCH_IGNORECASE); i++)\n\t\tsorted_foldcase_PARTIALMATCH_IGNORECASE [i] =  sorted_yes_PARTIALMATCH_IGNORECASE [i];\n\n\n\tif (check_finding (tags_sorted_foldcase, \"n\", TAG_FULLMATCH|TAG_OBSERVECASE,\n\t\t\t\t\t   sorted_foldcase_FULLMATCH_OBSERVECASE, COUNT(sorted_foldcase_FULLMATCH_OBSERVECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\tif (check_finding (tags_sorted_foldcase, \"n\", TAG_FULLMATCH|TAG_IGNORECASE,\n\t\t\t\t\t   sorted_foldcase_FULLMATCH_IGNORECASE, COUNT(sorted_foldcase_FULLMATCH_IGNORECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\tif (check_finding (tags_sorted_foldcase, \"m\", TAG_PARTIALMATCH|TAG_OBSERVECASE,\n\t\t\t\t\t   sorted_foldcase_PARTIALMATCH_OBSERVECASE, COUNT(sorted_foldcase_PARTIALMATCH_OBSERVECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\tif (check_finding (tags_sorted_foldcase, \"m\", TAG_PARTIALMATCH|TAG_IGNORECASE,\n\t\t\t\t\t   sorted_foldcase_PARTIALMATCH_IGNORECASE, COUNT(sorted_foldcase_PARTIALMATCH_IGNORECASE),\n\t\t\t\t\t   TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\t/*\n\t * Not found\n\t */\n\tconst char *tags_not_found = \"./duplicated-names--sorted-yes.tags\";\n\tstruct expectation not_found_case = {\n\t\t.result = TagFailure,\n\t\t.err    = 0,\n\t};\n\tif (check_finding (tags_not_found, \"noSuchItem\", TAG_FULLMATCH|TAG_IGNORECASE,\n\t\t\t\t\t   &not_found_case, 1, TESTX_NO_REMAIN) != 0)\n\t\treturn 1;\n\n\t/*\n\t * Broken line:\n\t */\n\tconst char *tags_broken_line_field = \"./broken-line-field-in-middle.tags\";\n\tstruct expectation broken_line_case = {\n\t\t.result = TagFailure,\n\t\t.err    = TagErrnoUnexpectedLineno,\n\t};\n\tif (check_finding (tags_broken_line_field, \"n\", TAG_FULLMATCH|TAG_OBSERVECASE,\n\t\t\t\t\t   &broken_line_case, 1, TESTX_INVALID_ARG) != 0)\n\t\treturn 1;\n\n\tstruct expectation broken_line_cases[] = {\n\t\t{\n\t\t\t.name = \"N\",\n\t\t\t.file = \"duplicated-names.c\",\n\t\t\t.pattern = \"/^int N;$/\",\n\t\t\t.kind = \"v\",\n\t\t\t.scope_kind = NULL,\n\t\t\t.scope_name = NULL,\n\t\t\t.typeref = \"typename:int\",\n\t\t\t.fileScope = 0,\n\t\t\t.result = TagSuccess,\n\t\t},\n\t\t{\n\t\t\t.result = TagFailure,\n\t\t\t.err    = TagErrnoUnexpectedLineno,\n\t\t},\n\t};\n\tif (check_finding (tags_broken_line_field, \"n\", TAG_FULLMATCH|TAG_IGNORECASE,\n\t\t\t\t\t   broken_line_cases, COUNT(broken_line_cases), TESTX_INVALID_ARG) != 0)\n\t\treturn 1;\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-api-tagsFindPseudoTag.c",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing tagsFindPseudoTag() API function\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n\nstruct expectation {\n\tchar *name;\n\tchar *file;\n\tchar *pattern;\n};\n\n#define COUNT(x) (sizeof(x)/sizeof(x[0]))\n\nstatic int\ncheck_finding0 (tagFile *t, struct expectation *expectations, int count, int match)\n{\n\ttagEntry e;\n\tstruct expectation *x;\n\tint err;\n\n\tfor (int i = 0; i < count; i++)\n\t{\n\t\tx = expectations + i;\n\t\tfprintf (stderr, \"[%d/%d] finding ptags in %s matching...\", i + 1, count,\n\t\t\t\t match == TAG_FULLMATCH? \"full\": \"partial\");\n\t\tif (tagsFindPseudoTag (t, &e, x->name, match) != TagSuccess)\n\t\t{\n\t\t\tif ((err = tagsGetErrno (t)))\n\t\t\t\tfprintf (stderr, \"error: %d\\n\", err);\n\t\t\telse\n\t\t\t\tfprintf (stderr, \"cannot find: %s\\n\", x->name);\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"found\\n\");\n\n\t\tfprintf (stderr, \"checking name field...\");\n\t\tif (match == TAG_FULLMATCH)\n\t\t{\n\t\t\tif (!(e.name && strcmp (x->name, e.name) == 0))\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"unexpected: %s\\n\", e.name? e.name: \"<NULL>\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (!(e.name && strncmp (x->name, e.name, strlen(x->name)) == 0))\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"unexpected: strncmp(%s, %s)\\n\",\n\t\t\t\t\t\t x->name, e.name? e.name: \"<NULL>\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\n\t\tfprintf (stderr, \"checking file field...\");\n\t\tif (!(e.file && strcmp (x->file, e.file) == 0))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected: %s\\n\", e.file? e.file: \"<NULL>\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\n\t\tfprintf (stderr, \"checking pattern field...\");\n\t\tif (!(e.address.pattern && strcmp (x->pattern, e.address.pattern) == 0))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected: %s\\n\",\n\t\t\t\t\t e.address.pattern? e.address.pattern: \"<NULL>\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\t}\n\n\treturn 0;\n}\n\nstatic int\ncheck_finding(const char *tags, struct expectation *expectations, int count, int match)\n{\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tfprintf (stderr, \"opening %s...\", tags);\n\tt = tagsOpen (tags, &info);\n\tif (!t)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d, error_number: %d)\\n\",\n\t\t\t\t t, info.status.opened, info.status.error_number);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tif (check_finding0 (t, expectations, count, match) != 0)\n\t\treturn 1;\n\n\tfprintf (stderr, \"closing the tag file...\");\n\tif (tagsClose (t) != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\treturn 0;\n}\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\t/*\n\t * sorted=yes\n\t */\n\tconst char *tags_sorted_yes = \"./ptag-sort-yes.tags\";\n\tstruct expectation exp_sorted_yes [] = {\n\t\t{ \"!_JSON_OUTPUT_VERSION\", \"0.0\", \"/in development/\", },\n\t\t{ \"!_TAG_FILE_FORMAT\", \"2\", \"/extended format; --format=1 will not append ;\\\" to lines/\", },\n\t\t{ \"!_TAG_FILE_SORTED\", \"1\", \"/0=unsorted, 1=sorted, 2=foldcase/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"D,macroparam\", \"/parameters inside macro definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"C,custom\", \"/customizable variables/\", },\n\t\t{ \"!_TAG_OUTPUT_FILESEP\", \"slash\", \"/slash or backslash/\", },\n\t\t{ \"!_TAG_OUTPUT_MODE\", \"u-ctags\", \"/u-ctags or e-ctags/\", },\n\t\t{ \"!_TAG_PATTERN_LENGTH_LIMIT\", \"96\", \"/0 for no limit/\", },\n\t\t{ \"!_TAG_PROGRAM_AUTHOR\", \"Universal Ctags Team\", \"//\", },\n\t\t{ \"!_TAG_PROGRAM_NAME\", \"Universal Ctags\", \"/Derived from Exuberant Ctags/\", },\n\t\t{ \"!_TAG_PROGRAM_URL\", \"https://ctags.io/\", \"/official site/\", },\n\t\t{ \"!_TAG_PROGRAM_VERSION\", \"0.0.0\", \"/9b73623f/\", },\n\t};\n\n\tif (check_finding (tags_sorted_yes, exp_sorted_yes, COUNT(exp_sorted_yes),\n\t\t\t\t\t   TAG_FULLMATCH) != 0)\n\t\treturn 1;\n\n\tstruct expectation exp_sorted_yes_partial [] = {\n\t\t{ \"!_JSON\", \"0.0\", \"/in development/\", },\n\t\t{ \"!_TAG_FILE\", \"2\", \"/extended format; --format=1 will not append ;\\\" to lines/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION\", \"D,macroparam\", \"/parameters inside macro definitions/\", },\n\t\t{ \"!_TAG_OUTPUT_\", \"slash\", \"/slash or backslash/\", },\n\t\t{ \"!_TAG_PATT\", \"96\", \"/0 for no limit/\", },\n\t\t{ \"!_TAG_PROGRAM_AUTHOR\", \"Universal Ctags Team\", \"//\", },\n\t\t{ \"!_TAG_PROGRAM_N\", \"Universal Ctags\", \"/Derived from Exuberant Ctags/\", },\n\t};\n\n\tif (check_finding (tags_sorted_yes, exp_sorted_yes_partial, COUNT(exp_sorted_yes_partial),\n\t\t\t\t\t   TAG_PARTIALMATCH) != 0)\n\t\treturn 1;\n\n\t/*\n\t * sorted=no\n\t */\n\tconst char *tags_sorted_no = \"./ptag-sort-no.tags\";\n\tstruct expectation exp_sorted_no [] = {\n\t\t{ \"!_JSON_OUTPUT_VERSION\", \"0.0\", \"/in development/\", },\n\t\t{ \"!_TAG_FILE_FORMAT\", \"2\", \"/extended format; --format=1 will not append ;\\\" to lines/\", },\n\t\t{ \"!_TAG_FILE_SORTED\", \"0\", \"/0=unsorted, 1=sorted, 2=foldcase/\", },\n\t\t{ \"!_TAG_PROGRAM_AUTHOR\", \"Universal Ctags Team\", \"//\", },\n\t\t{ \"!_TAG_PROGRAM_NAME\", \"Universal Ctags\", \"/Derived from Exuberant Ctags/\", },\n\t\t{ \"!_TAG_PROGRAM_URL\", \"https://ctags.io/\", \"/official site/\", },\n\t\t{ \"!_TAG_PROGRAM_VERSION\", \"0.0.0\", \"/9b73623f/\", },\n\t\t{ \"!_TAG_OUTPUT_MODE\", \"u-ctags\", \"/u-ctags or e-ctags/\", },\n\t\t{ \"!_TAG_OUTPUT_FILESEP\", \"slash\", \"/slash or backslash/\", },\n\t\t{ \"!_TAG_PATTERN_LENGTH_LIMIT\", \"96\", \"/0 for no limit/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"d,macro\", \"/macro definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"u,unknown\", \"/unknown type of definitions/\", },\n\t};\n\n\tif (check_finding (tags_sorted_no, exp_sorted_no, COUNT(exp_sorted_no), TAG_FULLMATCH) != 0)\n\t\treturn 1;\n\n\tstruct expectation exp_sorted_no_partial [] = {\n\t\t{ \"!_JSON\", \"0.0\", \"/in development/\", },\n\t\t{ \"!_TAG_FILE\", \"2\", \"/extended format; --format=1 will not append ;\\\" to lines/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION\", \"d,macro\", \"/macro definitions/\", },\n\t\t{ \"!_TAG_OUTPUT_\", \"u-ctags\", \"/u-ctags or e-ctags/\", },\n\t\t{ \"!_TAG_PATT\", \"96\", \"/0 for no limit/\", },\n\t\t{ \"!_TAG_PROGRAM_AUTHOR\", \"Universal Ctags Team\", \"//\", },\n\t\t{ \"!_TAG_PROGRAM_N\", \"Universal Ctags\", \"/Derived from Exuberant Ctags/\", },\n\t};\n\n\tif (check_finding (tags_sorted_no, exp_sorted_no_partial, COUNT(exp_sorted_no_partial),\n\t\t\t\t\t   TAG_PARTIALMATCH) != 0)\n\t\treturn 1;\n\n\t/* No entry */\n\tconst char *tags = \"./ptag-sort-yes.tags\";\n\ttagFileInfo info;\n\n\tfprintf (stderr, \"opening %s...\", tags);\n\ttagFile *t = tagsOpen (tags, &info);\n\tif (!t)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d, error_number: %d)\\n\",\n\t\t\t\t t, info.status.opened, info.status.error_number);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tstruct non_existing_testcase {\n\t\tconst char *matchstr;\n\t\tint match;\n\t} ne_tcase [2] = {\n\t\t{\n\t\t\t.matchstr = \"full\",\n\t\t\t.match = TAG_FULLMATCH,\n\t\t},\n\t\t{\n\t\t\t.matchstr = \"partial\",\n\t\t\t.match = TAG_PARTIALMATCH,\n\t\t}\n\t};\n\tfor (int i = 0; i < COUNT(ne_tcase); i++)\n\t{\n\t\tfprintf (stderr, \"try to find non-existing tag in %s matching...\",\n\t\t\t\t ne_tcase[i].matchstr);\n\t\ttagResult r = tagsFindPseudoTag (t, NULL, \"!NO_SUCH_PTAG\",\n\t\t\t\t\t\t\t\t\t\t ne_tcase[i].match);\n\t\tint err = tagsGetErrno (t);\n\t\tif (r == TagSuccess)\n\t\t{\n\t\t\tfprintf (stderr, \"found one unexpectedly\\n\");\n\t\t\treturn 1;\n\t\t}\n\t\telse if (err != 0)\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected errno: %d\\n\", err);\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\t}\n\n\tfprintf (stderr, \"closing the tag file...\");\n\tif (tagsClose (t) != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-api-tagsFirst.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing tagsFirst() and tagsNext() API functions\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n\nstruct entryExpectaion {\n\ttagResult result;\n\tconst char *name;\n\tint err;\n};\n\n#define LAST {\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t.result = TagFailure,\t\t\t\t\t\t\t\\\n\t\t.name   = \"last\",\t\t\t\t\t\t\t\t\\\n\t}\n\n#define isLast(ex) ((ex)->result == TagFailure && (ex)->name)\n\nstruct expectation {\n\tchar *file;\n\tstruct entryExpectaion first;\n\tstruct entryExpectaion *next;\n};\n\nstatic int\ncheck_one (tagFile *t, struct entryExpectaion *ex, tagEntry *e, int first)\n\n{\n\tfprintf (stderr, \"getting the %s entry...\", first? \"first\": \"next\");\n\ttagResult r;\n\n\tr = (first? tagsFirst: tagsNext) (t, e);\n\tif (r == ex->result)\n\t{\n\t\tif (r == TagSuccess)\n\t\t{\n\t\t\tif (strcmp (e->name, ex->name) == 0)\n\t\t\t\tfprintf (stderr, \"found expected one: %s\\n\", e->name);\n\t\t\telse\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"found unexpected one: %s (expected: %s)\\n\", e->name, ex->name);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfprintf (stderr, \"nothing found expectedly\\n\");\n\n\t\t\tfprintf (stderr, \"comparing errno...\");\n\t\t\tint err = tagsGetErrno (t);\n\t\t\tif (err == ex->err)\n\t\t\t\tfprintf (stderr, \"matched: %d\\n\", err);\n\t\t\telse\n\t\t\t{\n\t\t\t\tfprintf (stderr, \"unmatched: %d (expected: %d)\\n\", err, ex->err);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t}\n\telse if (ex->result == TagSuccess)\n\t{\n\t\tfprintf (stderr, \"nothing found unexpectedly\\n\");\n\t\treturn 1;\n\t}\n\telse\n\t{\n\t\tfprintf (stderr, \"something found unexpectedly: %s\\n\", e->name);\n\t\treturn 1;\n\t}\n\n\n\treturn 0;\n}\n\nstatic int\ncheck (struct expectation *x)\n{\n\ttagFile *t;\n\ttagFileInfo info;\n\tconst char *tags = x->file;\n\n\tfprintf (stderr, \"opening %s...\", tags);\n\tt = tagsOpen (tags, &info);\n\tif (!t)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d, error_number: %d)\\n\",\n\t\t\t\t t, info.status.opened, info.status.error_number);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\ttagEntry e;\n\tif (check_one (t, &x->first, &e, 1))\n\t\treturn 1;\n\n\tfor (int i = 0; !isLast (x->next + i); i++)\n\t\tif (check_one (t, x->next + i, &e, 0))\n\t\t\treturn 1;\n\n\tfprintf (stderr, \"closing the tag file...\");\n\tif (tagsClose (t) != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\treturn 0;\n}\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\tstruct expectation expectations [] = {\n\t\t{\n\t\t\t.file = \"duplicated-names--sorted-yes.tags\",\n\t\t\t.first = {\n\t\t\t\t.result = TagSuccess,\n\t\t\t\t.name = \"M\",\n\t\t\t},\n\t\t\t.next = ((struct entryExpectaion[]) {\n\t\t\t\t\t{TagSuccess, \"N\"},\n\t\t\t\t\t{TagSuccess, \"O\"},\n\t\t\t\t\t{TagSuccess, \"m\"},\n\t\t\t\t\t{TagSuccess, \"main\"},\n\t\t\t\t\t{TagSuccess, \"n\"},\n\t\t\t\t\t{TagSuccess, \"n\"},\n\t\t\t\t\t{TagSuccess, \"n\"},\n\t\t\t\t\t{TagSuccess, \"n\"},\n\t\t\t\t\t{TagSuccess, \"n\"},\n\t\t\t\t\t{TagSuccess, \"n\"},\n\t\t\t\t\t{TagSuccess, \"o\"},\n\t\t\t\t\tLAST,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\t.file = \"empty.tags\",\n\t\t\t.first = {\n\t\t\t\t.result = TagFailure,\n\t\t\t\t.err    = 0,\n\t\t\t},\n\t\t\t.next = ((struct entryExpectaion []) {\n\t\t\t\t\t{TagFailure, NULL, 0},\n\t\t\t\t\tLAST,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\t.file = \"empty-no-newline.tags\",\n\t\t\t.first = {\n\t\t\t\t.result = TagFailure,\n\t\t\t\t.err    = 0,\n\t\t\t},\n\t\t\t.next = ((struct entryExpectaion []) {\n\t\t\t\t\t{TagFailure, NULL, 0},\n\t\t\t\t\tLAST,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\t.file = \"broken-line-field.tags\",\n\t\t\t.first = {\n\t\t\t\t.result = TagFailure,\n\t\t\t\t.name   = NULL,\n\t\t\t\t.err = TagErrnoUnexpectedLineno,\n\t\t\t},\n\t\t\t.next = ((struct entryExpectaion []) {\n\t\t\t\t\tLAST,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\t.file = \"broken-line-field-other-than-first.tags\",\n\t\t\t.first = {\n\t\t\t\t.result = TagSuccess,\n\t\t\t\t.name   = \"M\",\n\t\t\t},\n\t\t\t.next = ((struct entryExpectaion []) {\n\t\t\t\t\t{\n\t\t\t\t\t\t.result = TagSuccess,\n\t\t\t\t\t\t.name   = \"N\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t.result = TagFailure,\n\t\t\t\t\t\t.name   = NULL,\n\t\t\t\t\t\t.err    = TagErrnoUnexpectedLineno,\n\n\t\t\t\t\t},\n\t\t\t\t\tLAST,\n\t\t\t\t}),\n\t\t},\n\t};\n\n\tfor (int i = 0; i < sizeof (expectations) / sizeof (expectations[0]); i++)\n\t\tif (check (expectations + i))\n\t\t\treturn 1;\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-api-tagsFirstPseudoTag.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing tagsFirstPseudoTag() and tagsNextPseudoTag() API functions\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n\nstruct expectation {\n\tchar *name;\n\tchar *file;\n\tchar *pattern;\n};\n\n#define COUNT(x) (sizeof(x)/sizeof(x[0]))\n\nstatic int\ncheck_iterating0 (tagFile *t, struct expectation *expectations, int count)\n{\n\ttagEntry e;\n\tstruct expectation *x;\n\tint err;\n\n\tfor (int i = 0; i < count; i++)\n\t{\n\t\tfprintf (stderr, \"[%d/%d] iterating ptags...\", i + 1, count);\n\t\tif (i == 0)\n\t\t{\n\t\t\tif (tagsFirstPseudoTag (t, &e) != TagSuccess)\n\t\t\t{\n\t\t\t\tif ((err = tagsGetErrno (t)))\n\t\t\t\t\tfprintf (stderr, \"error: %d\\n\", err);\n\t\t\t\telse\n\t\t\t\t\tfprintf (stderr, \"no more ptag\\n\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (tagsNextPseudoTag (t, &e) != TagSuccess)\n\t\t\t{\n\t\t\t\tif ((err = tagsGetErrno (t)))\n\t\t\t\t\tfprintf (stderr, \"error: %d\\n\", err);\n\t\t\t\telse\n\t\t\t\t\tfprintf (stderr, \"no more ptag\\n\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tfprintf (stderr, \"found\\n\");\n\n\t\tx = expectations + i;\n\n\t\tfprintf (stderr, \"checking name field...\");\n\t\tif (!(e.name && strcmp (x->name, e.name) == 0))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected: %s\\n\", e.name? e.name: \"<NULL>\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\n\t\tfprintf (stderr, \"checking file field...\");\n\t\tif (!(e.file && strcmp (x->file, e.file) == 0))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected: %s\\n\", e.file? e.file: \"<NULL>\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\n\t\tfprintf (stderr, \"checking pattern field...\");\n\t\tif (!(e.address.pattern && strcmp (x->pattern, e.address.pattern) == 0))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected: %s\\n\",\n\t\t\t\t\t e.address.pattern? e.address.pattern: \"<NULL>\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\t}\n\n\tfprintf (stderr, \"verifying no remain....\");\n\tif (tagsNextPseudoTag (t, &e) == TagSuccess)\n\t{\n\t\tif ((err = tagsGetErrno (t)))\n\t\t\tfprintf (stderr, \"error: %d\\n\", err);\n\t\telse\n\t\t\tfprintf (stderr, \"still existing\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\treturn 0;\n}\n\nstatic int\ncheck_iterating (const char *tags, struct expectation *expectations, int count)\n{\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tfprintf (stderr, \"opening %s...\", tags);\n\tt = tagsOpen (tags, &info);\n\tif (!t)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d, error_number: %d)\\n\",\n\t\t\t\t t, info.status.opened, info.status.error_number);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tif (check_iterating0 (t, expectations, count) != 0)\n\t\treturn 1;\n\n\tfprintf (stderr, \"closing the tag file...\");\n\tif (tagsClose (t) != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\treturn 0;\n}\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\t/*\n\t * sorted=yes\n\t */\n\tconst char *tags_sorted_yes = \"./ptag-sort-yes.tags\";\n\tstruct expectation exp_sorted_yes [] = {\n\t\t{ \"!_JSON_OUTPUT_VERSION\", \"0.0\", \"/in development/\", },\n\t\t{ \"!_TAG_FILE_FORMAT\", \"2\", \"/extended format; --format=1 will not append ;\\\" to lines/\", },\n\t\t{ \"!_TAG_FILE_SORTED\", \"1\", \"/0=unsorted, 1=sorted, 2=foldcase/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"D,macroparam\", \"/parameters inside macro definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"L,label\", \"/goto labels/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"d,macro\", \"/macro definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"e,enumerator\", \"/enumerators (values inside an enumeration)/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"f,function\", \"/function definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"g,enum\", \"/enumeration names/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"h,header\", \"/included header files/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"l,local\", \"/local variables/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"m,member\", \"/struct, and union members/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"p,prototype\", \"/function prototypes/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"s,struct\", \"/structure names/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"t,typedef\", \"/typedefs/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"u,union\", \"/union names/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"v,variable\", \"/variable definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"x,externvar\", \"/external and forward variable declarations/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"z,parameter\", \"/function parameters inside function definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"C,custom\", \"/customizable variables/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"D,derivedMode\", \"/derived major mode/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"G,group\", \"/customization groups/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"H,face\", \"/customizable faces/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"M,minorMode\", \"/minor modes/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"T,theme\", \"/custom themes/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"V,varalias\", \"/aliases for variables/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"a,alias\", \"/aliases for functions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"c,const\", \"/constants/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"e,error\", \"/errors/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"f,function\", \"/functions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"i,inline\", \"/inline function/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"m,macro\", \"/macros/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"s,subst\", \"/inline function/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"u,unknown\", \"/unknown type of definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"v,variable\", \"/variables/\", },\n\t\t{ \"!_TAG_OUTPUT_FILESEP\", \"slash\", \"/slash or backslash/\", },\n\t\t{ \"!_TAG_OUTPUT_MODE\", \"u-ctags\", \"/u-ctags or e-ctags/\", },\n\t\t{ \"!_TAG_PATTERN_LENGTH_LIMIT\", \"96\", \"/0 for no limit/\", },\n\t\t{ \"!_TAG_PROGRAM_AUTHOR\", \"Universal Ctags Team\", \"//\", },\n\t\t{ \"!_TAG_PROGRAM_NAME\", \"Universal Ctags\", \"/Derived from Exuberant Ctags/\", },\n\t\t{ \"!_TAG_PROGRAM_URL\", \"https://ctags.io/\", \"/official site/\", },\n\t\t{ \"!_TAG_PROGRAM_VERSION\", \"0.0.0\", \"/9b73623f/\", },\n\t};\n\n\tif (check_iterating (tags_sorted_yes, exp_sorted_yes, COUNT(exp_sorted_yes)) != 0)\n\t\treturn 1;\n\n\n\t/*\n\t * sorted=no\n\t */\n\tconst char *tags_sorted_no = \"./ptag-sort-no.tags\";\n\tstruct expectation exp_sorted_no [] = {\n\t\t{ \"!_JSON_OUTPUT_VERSION\", \"0.0\", \"/in development/\", },\n\t\t{ \"!_TAG_FILE_FORMAT\", \"2\", \"/extended format; --format=1 will not append ;\\\" to lines/\", },\n\t\t{ \"!_TAG_FILE_SORTED\", \"0\", \"/0=unsorted, 1=sorted, 2=foldcase/\", },\n\t\t{ \"!_TAG_PROGRAM_AUTHOR\", \"Universal Ctags Team\", \"//\", },\n\t\t{ \"!_TAG_PROGRAM_NAME\", \"Universal Ctags\", \"/Derived from Exuberant Ctags/\", },\n\t\t{ \"!_TAG_PROGRAM_URL\", \"https://ctags.io/\", \"/official site/\", },\n\t\t{ \"!_TAG_PROGRAM_VERSION\", \"0.0.0\", \"/9b73623f/\", },\n\t\t{ \"!_TAG_OUTPUT_MODE\", \"u-ctags\", \"/u-ctags or e-ctags/\", },\n\t\t{ \"!_TAG_OUTPUT_FILESEP\", \"slash\", \"/slash or backslash/\", },\n\t\t{ \"!_TAG_PATTERN_LENGTH_LIMIT\", \"96\", \"/0 for no limit/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"d,macro\", \"/macro definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"e,enumerator\", \"/enumerators (values inside an enumeration)/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"f,function\", \"/function definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"g,enum\", \"/enumeration names/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"h,header\", \"/included header files/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"l,local\", \"/local variables/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"m,member\", \"/struct, and union members/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"p,prototype\", \"/function prototypes/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"s,struct\", \"/structure names/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"t,typedef\", \"/typedefs/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"u,union\", \"/union names/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"v,variable\", \"/variable definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"x,externvar\", \"/external and forward variable declarations/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"z,parameter\", \"/function parameters inside function definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"L,label\", \"/goto labels/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!C\", \"D,macroparam\", \"/parameters inside macro definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"u,unknown\", \"/unknown type of definitions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"f,function\", \"/functions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"v,variable\", \"/variables/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"c,const\", \"/constants/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"m,macro\", \"/macros/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"a,alias\", \"/aliases for functions/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"V,varalias\", \"/aliases for variables/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"s,subst\", \"/inline function/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"i,inline\", \"/inline function/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"e,error\", \"/errors/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"M,minorMode\", \"/minor modes/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"D,derivedMode\", \"/derived major mode/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"C,custom\", \"/customizable variables/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"G,group\", \"/customization groups/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"H,face\", \"/customizable faces/\", },\n\t\t{ \"!_TAG_KIND_DESCRIPTION!EmacsLisp\", \"T,theme\", \"/custom themes/\", },\n\t};\n\n\tif (check_iterating (tags_sorted_no, exp_sorted_no, COUNT(exp_sorted_no)) != 0)\n\t\treturn 1;\n\n\t/* No entry */\n\tconst char *tags = \"./ptag-sort-yes.tags\";\n\ttagFileInfo info;\n\n\tfprintf (stderr, \"opening %s...\", tags);\n\ttagFile *t = tagsOpen (tags, &info);\n\tif (!t)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d, error_number: %d)\\n\",\n\t\t\t\t t, info.status.opened, info.status.error_number);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\n\tfprintf (stderr, \"visiting the first tag with NULL tagEntry...\");\n\tif (tagsFirstPseudoTag (t, NULL) != TagSuccess)\n\t{\n\t\tint err;\n\t\tif ((err = tagsGetErrno (t)))\n\t\t\tfprintf (stderr, \"error: %d\\n\", err);\n\t\telse\n\t\t\tfprintf (stderr, \"no first ptag\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"visiting the next tag with NULL tagEntry...\");\n\tif (tagsNextPseudoTag (t, NULL) != TagSuccess)\n\t{\n\t\tint err;\n\t\tif ((err = tagsGetErrno (t)))\n\t\t\tfprintf (stderr, \"error: %d\\n\", err);\n\t\telse\n\t\t\tfprintf (stderr, \"no more ptag\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"closing the tag file...\");\n\tif (tagsClose (t) != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-api-tagsOpen.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing tagsOpen() API function\n*/\n\n#include \"readtags.h\"\n\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n\nstatic int\ncheck_info (tagFileInfo *info, tagFileInfo *expected)\n{\n\n\tfprintf (stderr, \"inspecting info->file.format...\");\n\tif (info->file.format != expected->file.format)\n\t{\n\t\tfprintf (stderr, \"unexpected result: %d\\n\", info->file.format);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"inspecting info->file.sort...\");\n\tif (info->file.sort != expected->file.sort)\n\t{\n\t\tfprintf (stderr, \"unexpected result: %d\\n\", info->file.sort);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"inspecting info->program.author...\");\n\tif (strcmp (info->program.author, expected->program.author))\n\t{\n\t\tfprintf (stderr, \"unexpected result: %s\\n\", info->program.author);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"inspecting info->program.name...\");\n\tif (strcmp (info->program.name, expected->program.name))\n\t{\n\t\tfprintf (stderr, \"unexpected result: %s\\n\", info->program.name);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"inspecting info->program.url...\");\n\tif (strcmp (info->program.url, expected->program.url))\n\t{\n\t\tfprintf (stderr, \"unexpected result: %s\\n\", info->program.url);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"inspecting info->program.version...\");\n\tif (strcmp (info->program.version, expected->program.version))\n\t{\n\t\tfprintf (stderr, \"unexpected result: %s\\n\", expected->program.version);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\treturn 0;\n}\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tconst char *tags0 = \"./no-such-file.tags\";\n\tfprintf (stderr, \"opening no-existing tags file...\");\n\tt = tagsOpen (tags0, &info);\n\tif (! (t == NULL\n\t\t   && info.status.opened == 0\n\t\t   && info.status.error_number != 0))\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d, error_number: %d)\\n\",\n\t\t\t\t t, info.status.opened, info.status.error_number);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"opening no-existing tags file with NULL tagFileInfo...\");\n\tt = tagsOpen (tags0, NULL);\n\tif (t != NULL)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p)\\n\", t);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\ttagFileInfo expected1 = {\n\t\t.file.format = 2,\n\t\t.file.sort = TAG_SORTED,\n\t\t.program.author = \"Darren Hiebert\",\n\t\t.program.name = \"Exuberant Ctags\",\n\t\t.program.url = \"http://ctags.sourceforge.net\",\n\t\t.program.version = \"5.8\",\n\t};\n\tconst char *tags1 = \"./api-tagsOpen-ectags.tags\";\n\tfprintf (stderr, \"opening an existing tags file...\");\n\tt = tagsOpen (tags1, &info);\n\tif (t == NULL\n\t\t|| info.status.opened == 0)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d)\\n\",\n\t\t\t\t t, info.status.opened);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\n\tif (check_info (&info, &expected1) != 0)\n\t\treturn 1;\n\n\tfprintf (stderr, \"closing the tag file...\");\n\tif (tagsClose (t) != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"opening an existing tags file with NULL tagFileInfo...\");\n\tt = tagsOpen (tags1, NULL);\n\tif (t == NULL)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"closing the tag file...\");\n\tif (tagsClose (t) != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"opening a / (an error is expected)...\");\n\tinfo.status.error_number = 0;\n\tt = tagsOpen (\"/\", &info);\n\tif (t != NULL)\n\t{\n\t\tfprintf (stderr, \"unexpected result (!NULL)\\n\");\n\t\treturn 1;\n\t}\n\telse if (info.status.opened)\n\t{\n\t\tfprintf (stderr, \"unexpected result (opened != 0)\\n\");\n\t\treturn 1;\n\t}\n\telse if (info.status.error_number == 0)\n\t{\n\t\tfprintf (stderr, \"no error\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok (errno: %d)\\n\", info.status.error_number);\n\n\tfprintf (stderr, \"closing the unopened tag file...\");\n\tif (tagsClose (t) == TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"opening an broken tags file (format: unexpected number)...\");\n\tt = tagsOpen (\"./api-tagsOpen-wrong-format-num.tags\", &info);\n\tif (t)\n\t{\n\t\tfprintf (stderr, \"opened well unexpectedly (NULL)\\n\");\n\t\treturn 1;\n\t}\n\telse if (info.status.error_number != TagErrnoUnexpectedFormat)\n\t{\n\t\tfprintf (stderr, \"unexpected error (!= TagErrnoUnexpectedFormat)\\n\");\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\tfprintf (stderr, \"closing the unopened tag file...\");\n\tif (tagsClose (t) == TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"opening an broken tags file (format: not a number)...\");\n\tt = tagsOpen (\"./api-tagsOpen-wrong-format-nonum.tags\", &info);\n\tif (t)\n\t{\n\t\tfprintf (stderr, \"opened well unexpectedly (NULL)\\n\");\n\t\treturn 1;\n\t}\n\telse if (info.status.error_number != TagErrnoUnexpectedFormat)\n\t{\n\t\tfprintf (stderr, \"unexpected error (!= TagErrnoUnexpectedFormat)\\n\");\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\tfprintf (stderr, \"closing the unopened tag file...\");\n\tif (tagsClose (t) == TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"opening an broken tags file (sort: unexpected number)...\");\n\tt = tagsOpen (\"./api-tagsOpen-wrong-sort-method-num.tags\", &info);\n\tif (t)\n\t{\n\t\tfprintf (stderr, \"opened well unexpectedly (NULL)\\n\");\n\t\treturn 1;\n\t}\n\telse if (info.status.error_number != TagErrnoUnexpectedSortedMethod)\n\t{\n\t\tfprintf (stderr, \"unexpected error (!= TagErrnoUnexpectedSortedMethod)\\n\");\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\tfprintf (stderr, \"closing the unopened tag file...\");\n\tif (tagsClose (t) == TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"opening an broken tags file (sort: not a number)...\");\n\tt = tagsOpen (\"./api-tagsOpen-wrong-sort-method-nonum.tags\", &info);\n\tif (t)\n\t{\n\t\tfprintf (stderr, \"opened well unexpectedly (NULL)\\n\");\n\t\treturn 1;\n\t}\n\telse if (info.status.error_number != TagErrnoUnexpectedSortedMethod)\n\t{\n\t\tfprintf (stderr, \"unexpected error (!= TagErrnoUnexpectedSortedMethod)\\n\");\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\tfprintf (stderr, \"closing the unopened tag file...\");\n\tif (tagsClose (t) == TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tconst char* broken_PROGRAM_AUTHOR [6] = {\n\t\t\"Universal Ctags Team\",\n\t\t\"Universal Ctags Team\",\n\t\t\"\",\n\t\tNULL,\n\t\tNULL,\n\t\tNULL,\n\t};\n\tfor (int i = 0; i < 6; i++)\n\t{\n\t\tchar tagf_name_tmpl [] = \"./api-tagsOpen-incomplete-program-author-%d.tags\";\n\t\tchar tagf_name [sizeof (tagf_name_tmpl) - 1];\n\t\tfprintf (stderr, \"opening a tags file with incomplete PROGRAM_AUTHOR field [trimming level: %d]...\", i);\n\t\tsnprintf (tagf_name, sizeof (tagf_name), tagf_name_tmpl, i);\n\t\tt = tagsOpen (tagf_name, &info);\n\t\tif (t == NULL)\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected error: %d %s\\n\", info.status.error_number,\n\t\t\t\t\t info.status.error_number > 0\n\t\t\t\t\t ? strerror (info.status.error_number)\n\t\t\t\t\t : \"\");\n\t\t\treturn 1;\n\t\t}\n\t\tif (!((broken_PROGRAM_AUTHOR [i] == info.program.author)\n\t\t\t  || (broken_PROGRAM_AUTHOR [i]\n\t\t\t\t  && info.program.author\n\t\t\t\t  && strcmp (broken_PROGRAM_AUTHOR [i], info.program.author)) == 0))\n\t\t{\n\t\t\tfprintf (stderr, \"unexpected value: %s (!= %s)\\n\",\n\t\t\t\t\t info.program.author? info.program.author: \"(null)\",\n\t\t\t\t\t broken_PROGRAM_AUTHOR [i]? broken_PROGRAM_AUTHOR [i]: \"(null)\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"closing the unopened tag file...\");\n\t\tif (tagsClose (t) == TagFailure)\n\t\t{\n\t\t\tfprintf (stderr, \"successful unexpectedly\\n\");\n\t\t\treturn 1;\n\t\t}\n\t\tfprintf (stderr, \"ok\\n\");\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-api-tagsSetSortType.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing tagsSetSort() API function\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n\nstatic int\ncheck (tagFile *t, tagSortType method)\n{\n\tfprintf (stderr, \"set the sort method to %d...\", method);\n\tif (tagsSetSortType (t, method) != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"failed unexpectedly\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\treturn 0;\n}\n\nstatic int\ncheck_invalid (tagFile *t, tagSortType method, int error_expected)\n{\n\tfprintf (stderr, \"passing invalid value (%d) as a sort method...\", method);\n\tif (tagsSetSortType (t, method) == TagSuccess)\n\t{\n\t\tfprintf (stderr, \"successful unexpectedly\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tint err = tagsGetErrno (t);\n\tfprintf (stderr, \"verifying the error number...\");\n\tif (err != error_expected)\n\t{\n\t\tfprintf (stderr, \"unexpected error number (actual: %d, expected: %d)\\n\",\n\t\t\t\t err, error_expected);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\treturn 0;\n}\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tconst char *sorted_tags = \"./duplicated-names--sorted-yes.tags\";\n\tfprintf (stderr, \"opening a tags file (%s)...\", sorted_tags);\n\tt = tagsOpen (sorted_tags, &info);\n\tif (t == NULL\n\t\t|| info.status.opened == 0)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d)\\n\",\n\t\t\t\t t, info.status.opened);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\tfprintf (stderr, \"verify sort type defined in the tags file...\");\n\tif (info.file.sort != TAG_SORTED)\n\t{\n\t\tfprintf (stderr, \"unexpected result: %d (expected: %d)\\n\",\n\t\t\t\t info.file.sort, TAG_SORTED);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok (%d)\\n\", info.file.sort);\n\n\ttagSortType methods[] = {\n\t\tTAG_FOLDSORTED,\n\t\tTAG_UNSORTED,\n\t\tTAG_SORTED,\n\t};\n\n\tfor (int i = 0; i < sizeof (methods)/sizeof (methods[0]); i++)\n\t\tif (check (t, methods [i]))\n\t\t\treturn 1;\n\n\tstruct expectation {\n\t\tint method;\n\t\tint err;\n\t} invalid_methods [] = {\n\t\t{\n\t\t\t.method = -1,\n\t\t\t.err = TagErrnoUnexpectedSortedMethod,\n\t\t},\n\t\t{\n\t\t\t/* Once an invalid argument is passed, calling the API function with the\n\t\t\t * same tagFile is failed always. tagsSetSortType() is not an exception. */\n\t\t\t.method = TAG_SORTED,\n\t\t\t.err  = TagErrnoInvalidArgument,\n\t\t},\n\t};\n\n\tfor (int i = 0; i < sizeof (invalid_methods)/sizeof (invalid_methods[0]); i++)\n\t\tif (check_invalid (t, invalid_methods [i].method, invalid_methods [i].err))\n\t\t\treturn 1;\n\n\tfprintf (stderr, \"closing the tag file...\");\n\tif (tagsClose (t) != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"unexpected result\\n\");\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-fields.h",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing the fix for handling unescaping\n*/\n\n#ifndef TEST_FIELDS_H\n#define TEST_FIELDS_H\n\n#define NEXT()\t\t\t\t\t\t\t\t\t\t\\\n\tr = tagsNext (t, &e);\t\t\t\t\t\t\t\\\n\tif (r != TagSuccess)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tfprintf (stderr, \"error in tagsNext\\n\");\t\\\n\t\treturn 1;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tdo {} while (0)\n\n#define CHECK(EXP,FIELD)\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tif (strcmp (EXP, e.FIELD) != 0)\t\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tfprintf (stderr, \"unexpected \" #FIELD \"(expected: %s, actual: %s) in tagsFirst\\n\", \\\n\t\t\t\t EXP, e.FIELD);\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn 1;\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t} \\\n\tdo {} while (0)\n\n#define CHECK_X(FIELD,EXP)\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned short i;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tfor (i = 0; i < e.fields.count; i++)\t\t\t\t\t\t\t\\\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tif (strcmp (e.fields.list [i].key, FIELD) == 0)\t\t\t\t\\\n\t\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\tif (strcmp(e.fields.list [i].value, EXP) == 0)\t\t\t\\\n\t\t\t\t\tbreak;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\telse\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\tfprintf (stderr, \"unexpected \" #FIELD \"(expected: %s, actual: %s) in tagsFirst\\n\", \\\n\t\t\t\t\t\t\t EXP, e.fields.list [i].value);\t\t\t\t\\\n\t\t\t\t\treturn 1;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (i >= e.fields.count)\t\t\t\t\t\t\t\t\t\t\\\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tfprintf (stderr, \"unexpected \" #FIELD \" field is not found in tagsFirst (count: %u)\\n\", \\\n\t\t\t\t\t e.fields.count);\t\t\t\t\t\t\t\t\t\\\n\t\t\treturn 1;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CHECK3(NAME,FILE,PAT)\t\t\t\t\t\\\n\tCHECK ((NAME), name);\t\t\t\t\t\t\\\n\tCHECK ((FILE), file);\t\t\t\t\t\t\\\n\tCHECK ((PAT),  address.pattern)\n\n#define NEXT_CHECK3(NAME,FILE,PAT)\t\t\t\t\\\n\tNEXT ();\t\t\t\t\t\t\t\t\t\\\n\tCHECK3 (NAME,FILE,PAT)\n\n#endif\t/* !TEST_FIELDS_H */\n"
  },
  {
    "path": "libreadtags/tests/test-fix-large-tags.c",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing the way to report \"too large tags file\".\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <errno.h>\n\n#define\tTAGS \"./remove-me-after-testing.tags\"\n#define KEY \"xdigitValue\"\n\nstatic int\nmake_large_tags (const char *output)\n{\n\tFILE *fp = fopen(output, \"w\");\n\tif (fp == NULL)\n\t\treturn 1;\n\n\tint r = 0;\n\tconst char *ptags [] = {\n\t\t\"!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\\\" to lines/\",\n\t\t\"!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\",\n\t\t\"!_TAG_OUTPUT_EXCMD\tmixed\t/number, pattern, mixed, or combineV2/\",\n\t\t\"!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\",\n\t\t\"!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\",\n\t\t\"!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\",\n\t\t\"!_TAG_PROC_CWD\t/home/jet/var/libreadtags-new/\t//\",\n\t\t\"!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\",\n\t\t\"!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\",\n\t\t\"!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\",\n\t\t\"!_TAG_PROGRAM_VERSION\t5.9.0\t/966e51373/\",\n\t};\n\n\tfor (unsigned int i = 0; i < sizeof (ptags) / sizeof (ptags[0]); i++)\n\t{\n\t\tif (fputs(ptags[i], fp) < 0)\n\t\t{\n\t\t\tr = 1;\n\t\t\tbreak;\n\t\t}\n\t\tif (fputc('\\n', fp) == EOF)\n\t\t{\n\t\t\tr = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst unsigned int count = 21474836;\t/* $(( (2 ** 31) / 100)) */\n\tfor (unsigned int i = 0; i < count; i++)\n\t{\n\t\tif (fputs(\"EmptyString\", fp) < 0)\n\t\t{\n\t\t\tr = 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (fprintf(fp, \"%u\", i) < 1)\n\t\t{\n\t\t\tr = 1;\n\t\t\tbreak;\n\t\t}\n\t\tif (fputs(\"\treadtags.c\t/^static const char *const EmptyString\", fp) < 0)\n\t\t{\n\t\t\tr = 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (fprintf(fp, \"%u\", i) < 1)\n\t\t{\n\t\t\tr = 1;\n\t\t\tbreak;\n\t\t}\n\t\tif (fputs(\" = \\\"\\\";$/;\\\"\tv\ttyperef:typename:const char * const\tfile:\\n\", fp) < 0)\n\t\t{\n\t\t\tr = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (r == 0)\n\t{\n\t\tif (fputs(KEY, fp) < 0)\n\t\t\tr = 1;\n\t\telse if (fputs(\"\treadtags.c\t/^static int xdigitValue (char digit)$/;\\\"\tf\ttyperef:typename:int\tfile:\\n\", fp) < 0)\n\t\t\tr = 1;\n\t}\n\n\tif (fclose (fp))\n\t\tr = 1;\n\n\treturn r;\n}\n\nint\nmain (void)\n{\n\tfprintf (stderr, \"generating a large (> 2G) tags file (%s)...\", TAGS);\n\n\terrno = 0;\n\tint r = make_large_tags (TAGS);\n\tif (r)\n\t{\n\t\tfprintf(stderr, \"unexpected result: %s%s%d\\n\",\n\t\t\t\terrno? strerror(errno): \"\",\n\t\t\t\terrno? \": \": \"\",\n\t\t\t\tr);\n\t\treturn 99;\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"opening tags file (%s)...\", TAGS);\n\ttagFileInfo info;\n\ttagFile *t = tagsOpen (TAGS, &info);\n\tif ((info.status.opened == 0\n\t\t && (\n\t\t\t info.status.error_number == EFBIG\n\t\t\t || info.status.error_number == TagErrnoFileMaybeTooBig)))\n\t{\n\t\tr = 1;\n\t\tfprintf(stderr, \"failed with expected error: %d\\n\", info.status.error_number);\n\t}\n\telse if (t && info.status.opened)\n\t\tfprintf(stderr, \"done\\n\");\n\telse\n\t{\n\t\tr = 1;\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d, error_number: %d<%s>)\\n\",\n\t\t\t\t t, info.status.opened, info.status.error_number,\n\t\t\t\t (info.status.error_number >= 0)? strerror (info.status.error_number): \"\");\n\t}\n\n\tif (t)\n\t{\n\t\ttagEntry e;\n\t\tfprintf (stderr, \"finding \\\"%s\\\"...\", KEY);\n\t\tif (tagsFind (t, &e, KEY, TAG_FULLMATCH) == TagSuccess)\n\t\t\tfprintf (stderr, \"found as expected\\n\");\n\t\telse\n\t\t{\n\t\t\tr = 1;\n\t\t\tfprintf (stderr, \"not found unexpectedly\\n\");\n\t\t}\n\t\ttagsClose (t);\n\t}\n\n\tremove(TAGS);\n\treturn r;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-fix-null-deref.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing the guard condition for NULL pointer dereference\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tconst char *tags0 = \"./null-deref.tags\";\n\tt = tagsOpen (tags0, &info);\n\tif (t == NULL\n\t\t|| info.status.opened == 0)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d)\\n\",\n\t\t\t\t t, info.status.opened);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\ttagEntry e;\n\n\t/* Without fix, this program crashes in tagsFirst(). */\n\ttagsFirst (t, &e);\n\ttagsClose (t);\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-fix-unescaping-input-fields-backslash.c",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing the fix for handling unescaping\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"test-fields.h\"\n\n\n#define CHECK3(NAME,FILE,PAT)\t\t\t\t\t\\\n\tCHECK ((NAME), name);\t\t\t\t\t\t\\\n\tCHECK ((FILE), file);\t\t\t\t\t\t\\\n\tCHECK ((PAT),  address.pattern)\n\n#define NEXT_CHECK3(NAME,FILE,PAT)\t\t\t\t\\\n\tNEXT ();\t\t\t\t\t\t\t\t\t\\\n\tCHECK3 (NAME,FILE,PAT)\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tconst char *tags0 = \"./unescaping-input-fields-backslash.tags\";\n\tt = tagsOpen (tags0, &info);\n\tif (t == NULL\n\t\t|| info.status.opened == 0)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d)\\n\",\n\t\t\t\t t, info.status.opened);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\ttagEntry e;\n\ttagResult r;\n\n\tr = tagsFirst (t, &e);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsFirst\\n\");\n\t\treturn 1;\n\t}\n\n\tCHECK3 (\"tab0\", \"\\\\tabc\", \"/^tab0$/\");\n\tNEXT_CHECK3 (\"tab1\", \"a\\\\tbc\", \"/^tab1$/\");\n\tNEXT_CHECK3 (\"tab2\", \"ab\\\\tc\", \"/^tab2$/\");\n\tNEXT_CHECK3 (\"tab3\", \"abc\\\\t\", \"/^tab3$/\");\n\tNEXT_CHECK3 (\"tab4\", \"\\\\\\\\abc\", \"/^tab4$/\");\n\tNEXT_CHECK3 (\"tab5\", \"a\\\\\\\\bc\", \"/^tab5$/\");\n\tNEXT_CHECK3 (\"tab6\", \"ab\\\\\\\\c\", \"/^tab6$/\");\n\tNEXT_CHECK3 (\"tab7\", \"abc\\\\\\\\\", \"/^tab7$/\");\n\tNEXT_CHECK3 (\"tab8\", \"\\\\nabc\", \"/^tab8$/\");\n\tNEXT_CHECK3 (\"tab9\", \"a\\\\nbc\", \"/^tab9$/\");\n\tNEXT_CHECK3 (\"taba\", \"ab\\\\nc\", \"/^taba$/\");\n\tNEXT_CHECK3 (\"tabb\", \"abc\\\\n\", \"/^tabb$/\");\n\tNEXT_CHECK3 (\"tabc\", \"\\\\n\\\\\\\\abc\", \"/^tabc$/\");\n\tNEXT_CHECK3 (\"tabd\", \"\\\\\\\\\\\\nabc\", \"/^tabd$/\");\n\tNEXT_CHECK3 (\"tabe\", \"a\\\\n\\\\\\\\bc\", \"/^tabe$/\");\n\tNEXT_CHECK3 (\"tabf\", \"a\\\\\\\\\\\\nbc\", \"/^tabf$/\");\n\tNEXT_CHECK3 (\"tabg\", \"abc\\\\n\\\\\\\\\", \"/^tabg$/\");\n\tNEXT_CHECK3 (\"tabh\", \"abc\\\\\\\\\\\\n\", \"/^tabh$/\");\n\tNEXT_CHECK3 (\"tabi\", \"\\\\t\\\\\\\\\\\\n\",  \"/^tabi$/\");\n\tNEXT_CHECK3 (\"tabj\", \"ab\\\\t\\\\\\\\\\\\nc\",  \"/^tabj$/\");\n\n\tr = tagsClose(t);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsClose\\n\");\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-fix-unescaping-input-fields-exuberant.c",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing the fix for handling unescaping\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"test-fields.h\"\n\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tconst char *tags0 = \"./unescaping-input-fields-exuberant.tags\";\n\tt = tagsOpen (tags0, &info);\n\tif (t == NULL\n\t\t|| info.status.opened == 0)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d)\\n\",\n\t\t\t\t t, info.status.opened);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\ttagEntry e;\n\ttagResult r;\n\n\tr = tagsFirst (t, &e);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsFirst\\n\");\n\t\treturn 1;\n\t}\n\n\tCHECK3 (\"tab0\", \"\\\\tabc\", \"/^tab0$/\");\n\tNEXT_CHECK3 (\"tab1\", \"a\\\\tbc\", \"/^tab1$/\");\n\tNEXT_CHECK3 (\"tab2\", \"ab\\\\tc\", \"/^tab2$/\");\n\tNEXT_CHECK3 (\"tab3\", \"abc\\\\t\", \"/^tab3$/\");\n\tNEXT_CHECK3 (\"tab4\", \"\\\\\\\\abc\", \"/^tab4$/\");\n\tNEXT_CHECK3 (\"tab5\", \"a\\\\\\\\bc\", \"/^tab5$/\");\n\tNEXT_CHECK3 (\"tab6\", \"ab\\\\\\\\c\", \"/^tab6$/\");\n\tNEXT_CHECK3 (\"tab7\", \"abc\\\\\\\\\", \"/^tab7$/\");\n\tNEXT_CHECK3 (\"tab8\", \"\\\\nabc\", \"/^tab8$/\");\n\tNEXT_CHECK3 (\"tab9\", \"a\\\\nbc\", \"/^tab9$/\");\n\tNEXT_CHECK3 (\"taba\", \"ab\\\\nc\", \"/^taba$/\");\n\tNEXT_CHECK3 (\"tabb\", \"abc\\\\n\", \"/^tabb$/\");\n\tNEXT_CHECK3 (\"tabc\", \"\\\\n\\\\\\\\abc\", \"/^tabc$/\");\n\tNEXT_CHECK3 (\"tabd\", \"\\\\\\\\\\\\nabc\", \"/^tabd$/\");\n\tNEXT_CHECK3 (\"tabe\", \"a\\\\n\\\\\\\\bc\", \"/^tabe$/\");\n\tNEXT_CHECK3 (\"tabf\", \"a\\\\\\\\\\\\nbc\", \"/^tabf$/\");\n\tNEXT_CHECK3 (\"tabg\", \"abc\\\\n\\\\\\\\\", \"/^tabg$/\");\n\tNEXT_CHECK3 (\"tabh\", \"abc\\\\\\\\\\\\n\", \"/^tabh$/\");\n\tNEXT_CHECK3 (\"tabi\", \"\\\\t\\\\\\\\\\\\n\",  \"/^tabi$/\");\n\tNEXT_CHECK3 (\"tabj\", \"ab\\\\t\\\\\\\\\\\\nc\",  \"/^tabj$/\");\n\n\tr = tagsClose(t);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsClose\\n\");\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-fix-unescaping-input-fields-no-filesep.c",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing the fix for handling unescaping\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"test-fields.h\"\n\n\n#define CHECK3(NAME,FILE,PAT)\t\t\t\t\t\\\n\tCHECK ((NAME), name);\t\t\t\t\t\t\\\n\tCHECK ((FILE), file);\t\t\t\t\t\t\\\n\tCHECK ((PAT),  address.pattern)\n\n#define NEXT_CHECK3(NAME,FILE,PAT)\t\t\t\t\\\n\tNEXT ();\t\t\t\t\t\t\t\t\t\\\n\tCHECK3 (NAME,FILE,PAT)\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tconst char *tags0 = \"./unescaping-input-fields-no-filesep.tags\";\n\tt = tagsOpen (tags0, &info);\n\tif (t == NULL\n\t\t|| info.status.opened == 0)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d)\\n\",\n\t\t\t\t t, info.status.opened);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\ttagEntry e;\n\ttagResult r;\n\n\tr = tagsFirst (t, &e);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsFirst\\n\");\n\t\treturn 1;\n\t}\n\n\tCHECK3 (\"tab0\", \"\\\\tabc\", \"/^tab0$/\");\n\tNEXT_CHECK3 (\"tab1\", \"a\\\\tbc\", \"/^tab1$/\");\n\tNEXT_CHECK3 (\"tab2\", \"ab\\\\tc\", \"/^tab2$/\");\n\tNEXT_CHECK3 (\"tab3\", \"abc\\\\t\", \"/^tab3$/\");\n\tNEXT_CHECK3 (\"tab4\", \"\\\\\\\\abc\", \"/^tab4$/\");\n\tNEXT_CHECK3 (\"tab5\", \"a\\\\\\\\bc\", \"/^tab5$/\");\n\tNEXT_CHECK3 (\"tab6\", \"ab\\\\\\\\c\", \"/^tab6$/\");\n\tNEXT_CHECK3 (\"tab7\", \"abc\\\\\\\\\", \"/^tab7$/\");\n\tNEXT_CHECK3 (\"tab8\", \"\\\\nabc\", \"/^tab8$/\");\n\tNEXT_CHECK3 (\"tab9\", \"a\\\\nbc\", \"/^tab9$/\");\n\tNEXT_CHECK3 (\"taba\", \"ab\\\\nc\", \"/^taba$/\");\n\tNEXT_CHECK3 (\"tabb\", \"abc\\\\n\", \"/^tabb$/\");\n\tNEXT_CHECK3 (\"tabc\", \"\\\\n\\\\\\\\abc\", \"/^tabc$/\");\n\tNEXT_CHECK3 (\"tabd\", \"\\\\\\\\\\\\nabc\", \"/^tabd$/\");\n\tNEXT_CHECK3 (\"tabe\", \"a\\\\n\\\\\\\\bc\", \"/^tabe$/\");\n\tNEXT_CHECK3 (\"tabf\", \"a\\\\\\\\\\\\nbc\", \"/^tabf$/\");\n\tNEXT_CHECK3 (\"tabg\", \"abc\\\\n\\\\\\\\\", \"/^tabg$/\");\n\tNEXT_CHECK3 (\"tabh\", \"abc\\\\\\\\\\\\n\", \"/^tabh$/\");\n\tNEXT_CHECK3 (\"tabi\", \"\\\\t\\\\\\\\\\\\n\",  \"/^tabi$/\");\n\tNEXT_CHECK3 (\"tabj\", \"ab\\\\t\\\\\\\\\\\\nc\",  \"/^tabj$/\");\n\n\tr = tagsClose(t);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsClose\\n\");\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-fix-unescaping-input-fields-no-mode.c",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing the fix for handling unescaping\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"test-fields.h\"\n\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tconst char *tags0 = \"./unescaping-input-fields-no-mode.tags\";\n\tt = tagsOpen (tags0, &info);\n\tif (t == NULL\n\t\t|| info.status.opened == 0)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d)\\n\",\n\t\t\t\t t, info.status.opened);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\ttagEntry e;\n\ttagResult r;\n\n\tr = tagsFirst (t, &e);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsFirst\\n\");\n\t\treturn 1;\n\t}\n\n\tCHECK3 (\"tab0\", \"\\\\tabc\", \"/^tab0$/\");\n\tNEXT_CHECK3 (\"tab1\", \"a\\\\tbc\", \"/^tab1$/\");\n\tNEXT_CHECK3 (\"tab2\", \"ab\\\\tc\", \"/^tab2$/\");\n\tNEXT_CHECK3 (\"tab3\", \"abc\\\\t\", \"/^tab3$/\");\n\tNEXT_CHECK3 (\"tab4\", \"\\\\\\\\abc\", \"/^tab4$/\");\n\tNEXT_CHECK3 (\"tab5\", \"a\\\\\\\\bc\", \"/^tab5$/\");\n\tNEXT_CHECK3 (\"tab6\", \"ab\\\\\\\\c\", \"/^tab6$/\");\n\tNEXT_CHECK3 (\"tab7\", \"abc\\\\\\\\\", \"/^tab7$/\");\n\tNEXT_CHECK3 (\"tab8\", \"\\\\nabc\", \"/^tab8$/\");\n\tNEXT_CHECK3 (\"tab9\", \"a\\\\nbc\", \"/^tab9$/\");\n\tNEXT_CHECK3 (\"taba\", \"ab\\\\nc\", \"/^taba$/\");\n\tNEXT_CHECK3 (\"tabb\", \"abc\\\\n\", \"/^tabb$/\");\n\tNEXT_CHECK3 (\"tabc\", \"\\\\n\\\\\\\\abc\", \"/^tabc$/\");\n\tNEXT_CHECK3 (\"tabd\", \"\\\\\\\\\\\\nabc\", \"/^tabd$/\");\n\tNEXT_CHECK3 (\"tabe\", \"a\\\\n\\\\\\\\bc\", \"/^tabe$/\");\n\tNEXT_CHECK3 (\"tabf\", \"a\\\\\\\\\\\\nbc\", \"/^tabf$/\");\n\tNEXT_CHECK3 (\"tabg\", \"abc\\\\n\\\\\\\\\", \"/^tabg$/\");\n\tNEXT_CHECK3 (\"tabh\", \"abc\\\\\\\\\\\\n\", \"/^tabh$/\");\n\tNEXT_CHECK3 (\"tabi\", \"\\\\t\\\\\\\\\\\\n\",  \"/^tabi$/\");\n\tNEXT_CHECK3 (\"tabj\", \"ab\\\\t\\\\\\\\\\\\nc\",  \"/^tabj$/\");\n\n\tr = tagsClose(t);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsClose\\n\");\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-fix-unescaping-input-fields.c",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing the fix for handling unescaping\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"test-fields.h\"\n\n\n#define CHECK3(NAME,FILE,PAT)\t\t\t\t\t\\\n\tCHECK ((NAME), name);\t\t\t\t\t\t\\\n\tCHECK ((FILE), file);\t\t\t\t\t\t\\\n\tCHECK ((PAT),  address.pattern)\n\n#define NEXT_CHECK3(NAME,FILE,PAT)\t\t\t\t\\\n\tNEXT ();\t\t\t\t\t\t\t\t\t\\\n\tCHECK3 (NAME,FILE,PAT)\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tconst char *tags0 = \"./unescaping-input-fields.tags\";\n\tt = tagsOpen (tags0, &info);\n\tif (t == NULL\n\t\t|| info.status.opened == 0)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d)\\n\",\n\t\t\t\t t, info.status.opened);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\ttagEntry e;\n\ttagResult r;\n\n\tr = tagsFirst (t, &e);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsFirst\\n\");\n\t\treturn 1;\n\t}\n\n\tCHECK3 (\"tab0\", \"\\tabc\", \"/^tab0$/\");\n\tNEXT_CHECK3 (\"tab1\", \"a\\tbc\", \"/^tab1$/\");\n\tNEXT_CHECK3 (\"tab2\", \"ab\\tc\", \"/^tab2$/\");\n\tNEXT_CHECK3 (\"tab3\", \"abc\\t\", \"/^tab3$/\");\n\tNEXT_CHECK3 (\"tab4\", \"\\\\abc\", \"/^tab4$/\");\n\tNEXT_CHECK3 (\"tab5\", \"a\\\\bc\", \"/^tab5$/\");\n\tNEXT_CHECK3 (\"tab6\", \"ab\\\\c\", \"/^tab6$/\");\n\tNEXT_CHECK3 (\"tab7\", \"abc\\\\\", \"/^tab7$/\");\n\tNEXT_CHECK3 (\"tab8\", \"\\nabc\", \"/^tab8$/\");\n\tNEXT_CHECK3 (\"tab9\", \"a\\nbc\", \"/^tab9$/\");\n\tNEXT_CHECK3 (\"taba\", \"ab\\nc\", \"/^taba$/\");\n\tNEXT_CHECK3 (\"tabb\", \"abc\\n\", \"/^tabb$/\");\n\tNEXT_CHECK3 (\"tabc\", \"\\n\\\\abc\", \"/^tabc$/\");\n\tNEXT_CHECK3 (\"tabd\", \"\\\\\\nabc\", \"/^tabd$/\");\n\tNEXT_CHECK3 (\"tabe\", \"a\\n\\\\bc\", \"/^tabe$/\");\n\tNEXT_CHECK3 (\"tabf\", \"a\\\\\\nbc\", \"/^tabf$/\");\n\tNEXT_CHECK3 (\"tabg\", \"abc\\n\\\\\", \"/^tabg$/\");\n\tNEXT_CHECK3 (\"tabh\", \"abc\\\\\\n\", \"/^tabh$/\");\n\tNEXT_CHECK3 (\"tabi\", \"\\t\\\\\\n\",  \"/^tabi$/\");\n\tNEXT_CHECK3 (\"tabj\", \"ab\\t\\\\\\nc\",  \"/^tabj$/\");\n\n\tr = tagsClose(t);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsClose\\n\");\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/test-fix-unescaping.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*\n*   This source code is released into the public domain.\n*\n*   Testing the fix for handling unescaping\n*/\n\n#include \"readtags.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"test-fields.h\"\n\n\nint\nmain (void)\n{\n\tchar *srcdir = getenv (\"srcdir\");\n\tif (srcdir)\n\t{\n\t\tif (chdir (srcdir) == -1)\n\t\t{\n\t\t\tperror (\"chdir\");\n\t\t\treturn 99;\n\t\t}\n\t}\n\n\ttagFile *t;\n\ttagFileInfo info;\n\n\tconst char *tags0 = \"./unescaping.tags\";\n\tt = tagsOpen (tags0, &info);\n\tif (t == NULL\n\t\t|| info.status.opened == 0)\n\t{\n\t\tfprintf (stderr, \"unexpected result (t: %p, opened: %d)\\n\",\n\t\t\t\t t, info.status.opened);\n\t\treturn 1;\n\t}\n\tfprintf (stderr, \"ok\\n\");\n\n\ttagEntry e;\n\ttagResult r;\n\n\tr = tagsFirst (t, &e);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsFirst\\n\");\n\t\treturn 1;\n\t}\n\tCHECK (\"aa\", name);\n\tCHECK (\"main/Makefile\", file);\n\tCHECK (\"/^%:$/\", address.pattern);\n\tCHECK (\"t\", kind);\n\n\tNEXT ();\n\tCHECK (\"\\taa\", name);\n\tCHECK (\"parsers/Makefile\", file);\n\tCHECK (\"/^%:$/\", address.pattern);\n\tCHECK (\"t\", kind);\n\n\tNEXT ();\n\tCHECK (\"bb\", name);\n\tCHECK (\"main/Makefile\", file);\n\tCHECK (\"/^%:$/\", address.pattern);\n\tCHECK (\"t\", kind);\n\n\tNEXT ();\n\tCHECK (\"\\\\\\aa\", name);\n\tCHECK (\"parsers/cxx/Makefile\", file);\n\tCHECK (\"/^%:$/\", address.pattern);\n\tCHECK (\"t\", kind);\n\n\tNEXT ();\n\tCHECK (\"\\x01level1\", name);\n\tCHECK (\"input.rst\", file);\n\tCHECK (\"/^\\x01level1$/\", address.pattern);\n\tCHECK (\"c\", kind);\n\n\tNEXT ();\n\tCHECK (\"level2\", name);\n\tCHECK (\"input.rst\", file);\n\tCHECK (\"/^level2$/\", address.pattern);\n\tCHECK (\"s\", kind);\n\tCHECK_X (\"scope\", \"chapter:\\x01level1\");\n\n\tNEXT ();\n\tCHECK (\"!level3\\x03\", name);\n\tCHECK (\"input.rst\", file);\n\tCHECK (\"/^!level3\\x03$/\", address.pattern);\n\tCHECK (\"S\", kind);\n\tCHECK_X (\"scope\", \"section:level2\");\n\n\tNEXT ();\n\tCHECK (\"!level1+\", name);\n\tCHECK (\"input.rst\", file);\n\tCHECK (\"/^!level1+$/\", address.pattern);\n\tCHECK (\"c\", kind);\n\n\tNEXT ();\n\tCHECK (\"level2+\", name);\n\tCHECK (\"input.rst\", file);\n\tCHECK (\"/^level2+$/\", address.pattern);\n\tCHECK (\"s\", kind);\n\tCHECK_X (\"scope\", \"chapter:!level1+\");\n\n\tNEXT ();\n\tCHECK (\"\\x02level3+\\x04\", name);\n\tCHECK (\"input.rst\", file);\n\tCHECK (\"/^\\x02level3+\\x04$/\", address.pattern);\n\tCHECK (\"S\", kind);\n\tCHECK_X (\"scope\", \"section:level2+\");\n\n\tNEXT ();\n\tCHECK (\"ClassFour\", name);\n\tCHECK (\"input.php\", file);\n\tCHECK (\"/^  use NS2\\\\\\\\{NS30 as NameSpaceTreePointO, NS31\\\\\\\\Cls4 as ClassFour};$/\", address.pattern);\n\tCHECK (\"a\", kind);\n\tCHECK_X (\"typeref\", \"unknown:NS2\\\\NS31\\\\Cls4\");\n\n\tr = tagsClose(t);\n\tif (r != TagSuccess)\n\t{\n\t\tfprintf (stderr, \"error in tagsClose\\n\");\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "libreadtags/tests/unescaping-input-fields-backslash.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tbackslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\ntab0\t\\tabc\t/^tab0$/;\"\tn\ntab1\ta\\tbc\t/^tab1$/;\"\tn\ntab2\tab\\tc\t/^tab2$/;\"\tn\ntab3\tabc\\t\t/^tab3$/;\"\tn\ntab4\t\\\\abc\t/^tab4$/;\"\tn\ntab5\ta\\\\bc\t/^tab5$/;\"\tn\ntab6\tab\\\\c\t/^tab6$/;\"\tn\ntab7\tabc\\\\\t/^tab7$/;\"\tn\ntab8\t\\nabc\t/^tab8$/;\"\tn\ntab9\ta\\nbc\t/^tab9$/;\"\tn\ntaba\tab\\nc\t/^taba$/;\"\tn\ntabb\tabc\\n\t/^tabb$/;\"\tn\ntabc\t\\n\\\\abc\t/^tabc$/;\"\tn\ntabd\t\\\\\\nabc\t/^tabd$/;\"\tn\ntabe\ta\\n\\\\bc\t/^tabe$/;\"\tn\ntabf\ta\\\\\\nbc\t/^tabf$/;\"\tn\ntabg\tabc\\n\\\\\t/^tabg$/;\"\tn\ntabh\tabc\\\\\\n\t/^tabh$/;\"\tn\ntabi\t\\t\\\\\\n\t/^tabi$/;\"\tn\ntabj\tab\\t\\\\\\nc\t/^tabj$/;\"\tn\n"
  },
  {
    "path": "libreadtags/tests/unescaping-input-fields-exuberant.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\te-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\ntab0\t\\tabc\t/^tab0$/;\"\tn\ntab1\ta\\tbc\t/^tab1$/;\"\tn\ntab2\tab\\tc\t/^tab2$/;\"\tn\ntab3\tabc\\t\t/^tab3$/;\"\tn\ntab4\t\\\\abc\t/^tab4$/;\"\tn\ntab5\ta\\\\bc\t/^tab5$/;\"\tn\ntab6\tab\\\\c\t/^tab6$/;\"\tn\ntab7\tabc\\\\\t/^tab7$/;\"\tn\ntab8\t\\nabc\t/^tab8$/;\"\tn\ntab9\ta\\nbc\t/^tab9$/;\"\tn\ntaba\tab\\nc\t/^taba$/;\"\tn\ntabb\tabc\\n\t/^tabb$/;\"\tn\ntabc\t\\n\\\\abc\t/^tabc$/;\"\tn\ntabd\t\\\\\\nabc\t/^tabd$/;\"\tn\ntabe\ta\\n\\\\bc\t/^tabe$/;\"\tn\ntabf\ta\\\\\\nbc\t/^tabf$/;\"\tn\ntabg\tabc\\n\\\\\t/^tabg$/;\"\tn\ntabh\tabc\\\\\\n\t/^tabh$/;\"\tn\ntabi\t\\t\\\\\\n\t/^tabi$/;\"\tn\ntabj\tab\\t\\\\\\nc\t/^tabj$/;\"\tn\n"
  },
  {
    "path": "libreadtags/tests/unescaping-input-fields-no-filesep.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\ntab0\t\\tabc\t/^tab0$/;\"\tn\ntab1\ta\\tbc\t/^tab1$/;\"\tn\ntab2\tab\\tc\t/^tab2$/;\"\tn\ntab3\tabc\\t\t/^tab3$/;\"\tn\ntab4\t\\\\abc\t/^tab4$/;\"\tn\ntab5\ta\\\\bc\t/^tab5$/;\"\tn\ntab6\tab\\\\c\t/^tab6$/;\"\tn\ntab7\tabc\\\\\t/^tab7$/;\"\tn\ntab8\t\\nabc\t/^tab8$/;\"\tn\ntab9\ta\\nbc\t/^tab9$/;\"\tn\ntaba\tab\\nc\t/^taba$/;\"\tn\ntabb\tabc\\n\t/^tabb$/;\"\tn\ntabc\t\\n\\\\abc\t/^tabc$/;\"\tn\ntabd\t\\\\\\nabc\t/^tabd$/;\"\tn\ntabe\ta\\n\\\\bc\t/^tabe$/;\"\tn\ntabf\ta\\\\\\nbc\t/^tabf$/;\"\tn\ntabg\tabc\\n\\\\\t/^tabg$/;\"\tn\ntabh\tabc\\\\\\n\t/^tabh$/;\"\tn\ntabi\t\\t\\\\\\n\t/^tabi$/;\"\tn\ntabj\tab\\t\\\\\\nc\t/^tabj$/;\"\tn\n"
  },
  {
    "path": "libreadtags/tests/unescaping-input-fields-no-mode.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\ntab0\t\\tabc\t/^tab0$/;\"\tn\ntab1\ta\\tbc\t/^tab1$/;\"\tn\ntab2\tab\\tc\t/^tab2$/;\"\tn\ntab3\tabc\\t\t/^tab3$/;\"\tn\ntab4\t\\\\abc\t/^tab4$/;\"\tn\ntab5\ta\\\\bc\t/^tab5$/;\"\tn\ntab6\tab\\\\c\t/^tab6$/;\"\tn\ntab7\tabc\\\\\t/^tab7$/;\"\tn\ntab8\t\\nabc\t/^tab8$/;\"\tn\ntab9\ta\\nbc\t/^tab9$/;\"\tn\ntaba\tab\\nc\t/^taba$/;\"\tn\ntabb\tabc\\n\t/^tabb$/;\"\tn\ntabc\t\\n\\\\abc\t/^tabc$/;\"\tn\ntabd\t\\\\\\nabc\t/^tabd$/;\"\tn\ntabe\ta\\n\\\\bc\t/^tabe$/;\"\tn\ntabf\ta\\\\\\nbc\t/^tabf$/;\"\tn\ntabg\tabc\\n\\\\\t/^tabg$/;\"\tn\ntabh\tabc\\\\\\n\t/^tabh$/;\"\tn\ntabi\t\\t\\\\\\n\t/^tabi$/;\"\tn\ntabj\tab\\t\\\\\\nc\t/^tabj$/;\"\tn\n"
  },
  {
    "path": "libreadtags/tests/unescaping-input-fields.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\ntab0\t\\tabc\t/^tab0$/;\"\tn\ntab1\ta\\tbc\t/^tab1$/;\"\tn\ntab2\tab\\tc\t/^tab2$/;\"\tn\ntab3\tabc\\t\t/^tab3$/;\"\tn\ntab4\t\\\\abc\t/^tab4$/;\"\tn\ntab5\ta\\\\bc\t/^tab5$/;\"\tn\ntab6\tab\\\\c\t/^tab6$/;\"\tn\ntab7\tabc\\\\\t/^tab7$/;\"\tn\ntab8\t\\nabc\t/^tab8$/;\"\tn\ntab9\ta\\nbc\t/^tab9$/;\"\tn\ntaba\tab\\nc\t/^taba$/;\"\tn\ntabb\tabc\\n\t/^tabb$/;\"\tn\ntabc\t\\n\\\\abc\t/^tabc$/;\"\tn\ntabd\t\\\\\\nabc\t/^tabd$/;\"\tn\ntabe\ta\\n\\\\bc\t/^tabe$/;\"\tn\ntabf\ta\\\\\\nbc\t/^tabf$/;\"\tn\ntabg\tabc\\n\\\\\t/^tabg$/;\"\tn\ntabh\tabc\\\\\\n\t/^tabh$/;\"\tn\ntabi\t\\t\\\\\\n\t/^tabi$/;\"\tn\ntabj\tab\\t\\\\\\nc\t/^tabj$/;\"\tn\n"
  },
  {
    "path": "libreadtags/tests/unescaping.tags",
    "content": "!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n!_TAG_OUTPUT_FILESEP\tslash\t/slash or backslash/\n!_TAG_OUTPUT_MODE\tu-ctags\t/u-ctags or e-ctags/\n!_TAG_PATTERN_LENGTH_LIMIT\t96\t/0 for no limit/\n!_TAG_PROGRAM_AUTHOR\tUniversal Ctags Team\t//\n!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n!_TAG_PROGRAM_URL\thttps://ctags.io/\t/official site/\n!_TAG_PROGRAM_VERSION\t0.0.0\t/8d952eba/\naa\tmain/Makefile\t/^%:$/;\"\tt\n\\taa\tparsers/Makefile\t/^%:$/;\"\tt\nbb\tmain/Makefile\t/^%:$/;\"\tt\n\\\\\\aa\tparsers/cxx/Makefile\t/^%:$/;\"\tt\n\\x01level1\tinput.rst\t/^\u0001level1$/;\"\tc\nlevel2\tinput.rst\t/^level2$/;\"\ts\tscope:chapter:\\x01level1\n\\x21level3\\x03\tinput.rst\t/^!level3\u0003$/;\"\tS\tscope:section:level2\n\\x21level1+\tinput.rst\t/^!level1+$/;\"\tc\nlevel2+\tinput.rst\t/^level2+$/;\"\ts\tscope:chapter:!level1+\n\\x02level3+\\x04\tinput.rst\t/^\u0002level3+\u0004$/;\"\tS\tscope:section:level2+\nClassFour\tinput.php\t/^  use NS2\\\\{NS30 as NameSpaceTreePointO, NS31\\\\Cls4 as ClassFour};$/;\"\ta\ttyperef:unknown:NS2\\\\NS31\\\\Cls4\n"
  },
  {
    "path": "m4/00gnulib.m4",
    "content": "# 00gnulib.m4 serial 8\ndnl Copyright (C) 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl This file must be named something that sorts before all other\ndnl gnulib-provided .m4 files.  It is needed until the clang fix has\ndnl been included in Autoconf.\n\n# The following definitions arrange to use a compiler option\n# -Werror=implicit-function-declaration in AC_CHECK_DECL, when the\n# compiler is clang.  Without it, clang implicitly declares \"known\"\n# library functions in C mode, but not in C++ mode, which would cause\n# Gnulib to omit a declaration and thus later produce an error in C++\n# mode.  As of clang 9.0, these \"known\" functions are identified through\n# LIBBUILTIN invocations in the LLVM source file\n# llvm/tools/clang/include/clang/Basic/Builtins.def.\n# It's not possible to AC_REQUIRE the extra tests from AC_CHECK_DECL,\n# because AC_CHECK_DECL, like other Autoconf built-ins, is not supposed\n# to AC_REQUIRE anything: some configure.ac files have their first\n# AC_CHECK_DECL executed conditionally.  Therefore append the extra tests\n# to AC_PROG_CC.\nAC_DEFUN([gl_COMPILER_CLANG],\n[\ndnl AC_REQUIRE([AC_PROG_CC])\n  AC_CACHE_CHECK([whether the compiler is clang],\n    [gl_cv_compiler_clang],\n    [dnl Use _AC_COMPILE_IFELSE instead of AC_EGREP_CPP, to avoid error\n     dnl \"circular dependency of AC_LANG_COMPILER(C)\" if AC_PROG_CC has\n     dnl not yet been invoked.\n     _AC_COMPILE_IFELSE(\n        [AC_LANG_PROGRAM([[\n           #ifdef __clang__\n           barfbarf\n           #endif\n           ]],[[]])\n        ],\n        [gl_cv_compiler_clang=no],\n        [gl_cv_compiler_clang=yes])\n    ])\n])\nAC_DEFUN([gl_COMPILER_PREPARE_CHECK_DECL],\n[\ndnl AC_REQUIRE([AC_PROG_CC])\ndnl AC_REQUIRE([gl_COMPILER_CLANG])\n  AC_CACHE_CHECK([for compiler option needed when checking for declarations],\n    [gl_cv_compiler_check_decl_option],\n    [if test $gl_cv_compiler_clang = yes; then\n       dnl Test whether the compiler supports the option\n       dnl '-Werror=implicit-function-declaration'.\n       save_ac_compile=\"$ac_compile\"\n       ac_compile=\"$ac_compile -Werror=implicit-function-declaration\"\n       dnl Use _AC_COMPILE_IFELSE instead of AC_COMPILE_IFELSE, to avoid a\n       dnl warning \"AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS\".\n       _AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[]])],\n         [gl_cv_compiler_check_decl_option='-Werror=implicit-function-declaration'],\n         [gl_cv_compiler_check_decl_option=none])\n       ac_compile=\"$save_ac_compile\"\n     else\n       gl_cv_compiler_check_decl_option=none\n     fi\n    ])\n  if test \"x$gl_cv_compiler_check_decl_option\" != xnone; then\n    ac_compile_for_check_decl=\"$ac_compile $gl_cv_compiler_check_decl_option\"\n  else\n    ac_compile_for_check_decl=\"$ac_compile\"\n  fi\n])\ndnl Redefine _AC_CHECK_DECL_BODY so that it references ac_compile_for_check_decl\ndnl instead of ac_compile.  If, for whatever reason, the override of AC_PROG_CC\ndnl in zzgnulib.m4 is inactive, use the original ac_compile.\nm4_define([_AC_CHECK_DECL_BODY],\n[  ac_save_ac_compile=\"$ac_compile\"\n  if test -n \"$ac_compile_for_check_decl\"; then\n    ac_compile=\"$ac_compile_for_check_decl\"\n  fi]\nm4_defn([_AC_CHECK_DECL_BODY])[  ac_compile=\"$ac_save_ac_compile\"\n])\n\n# gl_00GNULIB\n# -----------\n# Witness macro that this file has been included.  Needed to force\n# Automake to include this file prior to all other gnulib .m4 files.\nAC_DEFUN([gl_00GNULIB])\n"
  },
  {
    "path": "m4/__inline.m4",
    "content": "# Test for __inline keyword\ndnl Copyright 2017-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl___INLINE],\n[\n  AC_CACHE_CHECK([whether the compiler supports the __inline keyword],\n    [gl_cv_c___inline],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n         [[typedef int foo_t;\n           static __inline foo_t foo (void) { return 0; }]],\n         [[return foo ();]])],\n       [gl_cv_c___inline=yes],\n       [gl_cv_c___inline=no])])\n  if test $gl_cv_c___inline = yes; then\n    AC_DEFINE([HAVE___INLINE], [1],\n      [Define to 1 if the compiler supports the keyword '__inline'.])\n  fi\n])\n"
  },
  {
    "path": "m4/absolute-header.m4",
    "content": "# absolute-header.m4 serial 17\ndnl Copyright (C) 2006-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Derek Price.\n\n# gl_ABSOLUTE_HEADER(HEADER1 HEADER2 ...)\n# ---------------------------------------\n# Find the absolute name of a header file, testing first if the header exists.\n# If the header were sys/inttypes.h, this macro would define\n# ABSOLUTE_SYS_INTTYPES_H to the '\"\"' quoted absolute name of sys/inttypes.h\n# in config.h\n# (e.g. '#define ABSOLUTE_SYS_INTTYPES_H \"///usr/include/sys/inttypes.h\"').\n# The three \"///\" are to pacify Sun C 5.8, which otherwise would say\n# \"warning: #include of /usr/include/... may be non-portable\".\n# Use '\"\"', not '<>', so that the /// cannot be confused with a C99 comment.\n# Note: This macro assumes that the header file is not empty after\n# preprocessing, i.e. it does not only define preprocessor macros but also\n# provides some type/enum definitions or function/variable declarations.\nAC_DEFUN([gl_ABSOLUTE_HEADER],\n[AC_REQUIRE([AC_CANONICAL_HOST])\nAC_LANG_PREPROC_REQUIRE()dnl\nm4_foreach_w([gl_HEADER_NAME], [$1],\n  [AS_VAR_PUSHDEF([gl_absolute_header],\n                  [gl_cv_absolute_]m4_defn([gl_HEADER_NAME]))dnl\n  AC_CACHE_CHECK([absolute name of <]m4_defn([gl_HEADER_NAME])[>],\n    [gl_absolute_header],\n    [AS_VAR_PUSHDEF([ac_header_exists],\n                    [ac_cv_header_]m4_defn([gl_HEADER_NAME]))dnl\n    AC_CHECK_HEADERS_ONCE(m4_defn([gl_HEADER_NAME]))dnl\n    if test AS_VAR_GET([ac_header_exists]) = yes; then\n      gl_ABSOLUTE_HEADER_ONE(m4_defn([gl_HEADER_NAME]))\n    fi\n    AS_VAR_POPDEF([ac_header_exists])dnl\n    ])dnl\n  AC_DEFINE_UNQUOTED(AS_TR_CPP([ABSOLUTE_]m4_defn([gl_HEADER_NAME])),\n                     [\"AS_VAR_GET([gl_absolute_header])\"],\n                     [Define this to an absolute name of <]m4_defn([gl_HEADER_NAME])[>.])\n  AS_VAR_POPDEF([gl_absolute_header])dnl\n])dnl\n])# gl_ABSOLUTE_HEADER\n\n# gl_ABSOLUTE_HEADER_ONE(HEADER)\n# ------------------------------\n# Like gl_ABSOLUTE_HEADER, except that:\n#   - it assumes that the header exists,\n#   - it uses the current CPPFLAGS,\n#   - it does not cache the result,\n#   - it is silent.\nAC_DEFUN([gl_ABSOLUTE_HEADER_ONE],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_LANG_CONFTEST([AC_LANG_SOURCE([[#include <]]m4_dquote([$1])[[>]])])\n  dnl AIX \"xlc -E\" and \"cc -E\" omit #line directives for header files\n  dnl that contain only a #include of other header files and no\n  dnl non-comment tokens of their own. This leads to a failure to\n  dnl detect the absolute name of <dirent.h>, <signal.h>, <poll.h>\n  dnl and others. The workaround is to force preservation of comments\n  dnl through option -C. This ensures all necessary #line directives\n  dnl are present. GCC supports option -C as well.\n  case \"$host_os\" in\n    aix*) gl_absname_cpp=\"$ac_cpp -C\" ;;\n    *)    gl_absname_cpp=\"$ac_cpp\" ;;\n  esac\nchangequote(,)\n  case \"$host_os\" in\n    mingw*)\n      dnl For the sake of native Windows compilers (excluding gcc),\n      dnl treat backslash as a directory separator, like /.\n      dnl Actually, these compilers use a double-backslash as\n      dnl directory separator, inside the\n      dnl   # line \"filename\"\n      dnl directives.\n      gl_dirsep_regex='[/\\\\]'\n      ;;\n    *)\n      gl_dirsep_regex='\\/'\n      ;;\n  esac\n  dnl A sed expression that turns a string into a basic regular\n  dnl expression, for use within \"/.../\".\n  gl_make_literal_regex_sed='s,[]$^\\\\.*/[],\\\\&,g'\n  gl_header_literal_regex=`echo '$1' \\\n                           | sed -e \"$gl_make_literal_regex_sed\"`\n  gl_absolute_header_sed=\"/${gl_dirsep_regex}${gl_header_literal_regex}/\"'{\n      s/.*\"\\(.*'\"${gl_dirsep_regex}${gl_header_literal_regex}\"'\\)\".*/\\1/\n      s|^/[^/]|//&|\n      p\n      q\n    }'\nchangequote([,])\n  dnl eval is necessary to expand gl_absname_cpp.\n  dnl Ultrix and Pyramid sh refuse to redirect output of eval,\n  dnl so use subshell.\n  AS_VAR_SET([gl_cv_absolute_]AS_TR_SH([[$1]]),\n[`(eval \"$gl_absname_cpp conftest.$ac_ext\") 2>&AS_MESSAGE_LOG_FD |\n  sed -n \"$gl_absolute_header_sed\"`])\n])\n"
  },
  {
    "path": "m4/alloca.m4",
    "content": "# alloca.m4 serial 20\ndnl Copyright (C) 2002-2004, 2006-2007, 2009-2021 Free Software Foundation,\ndnl Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_ALLOCA],\n[\n  AC_REQUIRE([AC_FUNC_ALLOCA])\n  if test $ac_cv_func_alloca_works = no; then\n    gl_PREREQ_ALLOCA\n  fi\n\n  # Define an additional variable used in the Makefile substitution.\n  if test $ac_cv_working_alloca_h = yes; then\n    AC_CACHE_CHECK([for alloca as a compiler built-in], [gl_cv_rpl_alloca], [\n      AC_EGREP_CPP([Need own alloca], [\n#if defined __GNUC__ || defined _AIX || defined _MSC_VER\n        Need own alloca\n#endif\n        ], [gl_cv_rpl_alloca=yes], [gl_cv_rpl_alloca=no])\n    ])\n    if test $gl_cv_rpl_alloca = yes; then\n      dnl OK, alloca can be implemented through a compiler built-in.\n      AC_DEFINE([HAVE_ALLOCA], [1],\n        [Define to 1 if you have 'alloca' after including <alloca.h>,\n         a header that may be supplied by this distribution.])\n      ALLOCA_H=alloca.h\n    else\n      dnl alloca exists as a library function, i.e. it is slow and probably\n      dnl a memory leak. Don't define HAVE_ALLOCA in this case.\n      ALLOCA_H=\n    fi\n  else\n    ALLOCA_H=alloca.h\n  fi\n  AC_SUBST([ALLOCA_H])\n  AM_CONDITIONAL([GL_GENERATE_ALLOCA_H], [test -n \"$ALLOCA_H\"])\n\n  if test $ac_cv_working_alloca_h = yes; then\n    HAVE_ALLOCA_H=1\n  else\n    HAVE_ALLOCA_H=0\n  fi\n  AC_SUBST([HAVE_ALLOCA_H])\n])\n\n# Prerequisites of lib/alloca.c.\n# STACK_DIRECTION is already handled by AC_FUNC_ALLOCA.\nAC_DEFUN([gl_PREREQ_ALLOCA], [:])\n\nm4_version_prereq([2.70], [], [\n\n# This works around a bug in autoconf <= 2.68 and has simplifications\n# from 2.70.  See:\n# https://lists.gnu.org/r/bug-gnulib/2011-06/msg00277.html\n# https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=6cd9f12520b0d6f76d3230d7565feba1ecf29497\n# https://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=15edf7fd8094fd14a89d9891dd72a9624762597a\n\n# _AC_LIBOBJ_ALLOCA\n# -----------------\n# Set up the LIBOBJ replacement of 'alloca'.  Well, not exactly\n# AC_LIBOBJ since we actually set the output variable 'ALLOCA'.\n# Nevertheless, for Automake, AC_LIBSOURCES it.\nm4_define([_AC_LIBOBJ_ALLOCA],\n[# The SVR3 libPW and SVR4 libucb both contain incompatible functions\n# that cause trouble.  Some versions do not even contain alloca or\n# contain a buggy version.  If you still want to use their alloca,\n# use ar to extract alloca.o from them instead of compiling alloca.c.\nAC_LIBSOURCES(alloca.c)\nAC_SUBST([ALLOCA], [\\${LIBOBJDIR}alloca.$ac_objext])dnl\nAC_DEFINE(C_ALLOCA, 1, [Define to 1 if using 'alloca.c'.])\n\nAC_CACHE_CHECK([stack direction for C alloca],\n               [ac_cv_c_stack_direction],\n[AC_RUN_IFELSE([AC_LANG_SOURCE(\n[AC_INCLUDES_DEFAULT\nint\nfind_stack_direction (int *addr, int depth)\n{\n  int dir, dummy = 0;\n  if (! addr)\n    addr = &dummy;\n  *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;\n  dir = depth ? find_stack_direction (addr, depth - 1) : 0;\n  return dir + dummy;\n}\n\nint\nmain (int argc, char **argv)\n{\n  return find_stack_direction (0, argc + !argv + 20) < 0;\n}])],\n               [ac_cv_c_stack_direction=1],\n               [ac_cv_c_stack_direction=-1],\n               [ac_cv_c_stack_direction=0])])\nAH_VERBATIM([STACK_DIRECTION],\n[/* If using the C implementation of alloca, define if you know the\n   direction of stack growth for your system; otherwise it will be\n   automatically deduced at runtime.\n        STACK_DIRECTION > 0 => grows toward higher addresses\n        STACK_DIRECTION < 0 => grows toward lower addresses\n        STACK_DIRECTION = 0 => direction of growth unknown */\n#undef STACK_DIRECTION])dnl\nAC_DEFINE_UNQUOTED(STACK_DIRECTION, $ac_cv_c_stack_direction)\n])# _AC_LIBOBJ_ALLOCA\n])\n"
  },
  {
    "path": "m4/attributes.m4",
    "content": "dnl Taken from https://sourceforge.net/p/xine/xine-lib-1.2/ci/default/tree/m4/attributes.m4\ndnl\ndnl Macros to check the presence of generic (non-typed) symbols.\ndnl Copyright (c) 2006-2008 Diego Pettenò <flameeyes@gmail.com>\ndnl Copyright (c) 2006-2008 xine project\ndnl\ndnl This program is free software; you can redistribute it and/or modify\ndnl it under the terms of the GNU General Public License as published by\ndnl the Free Software Foundation; either version 2, or (at your option)\ndnl any later version.\ndnl\ndnl This program is distributed in the hope that it will be useful,\ndnl but WITHOUT ANY WARRANTY; without even the implied warranty of\ndnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\ndnl GNU General Public License for more details.\ndnl\ndnl You should have received a copy of the GNU General Public License\ndnl along with this program; if not, write to the Free Software\ndnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\ndnl 02110-1301, USA.\ndnl\ndnl As a special exception, the copyright owners of the\ndnl macro gives unlimited permission to copy, distribute and modify the\ndnl configure scripts that are the output of Autoconf when processing the\ndnl Macro. You need not follow the terms of the GNU General Public\ndnl License when using or distributing such scripts, even though portions\ndnl of the text of the Macro appear in them. The GNU General Public\ndnl License (GPL) does govern all other use of the material that\ndnl constitutes the Autoconf Macro.\ndnl\ndnl This special exception to the GPL applies to versions of the\ndnl Autoconf Macro released by this project. When you make and\ndnl distribute a modified version of the Autoconf Macro, you may extend\ndnl this special exception to the GPL to apply to your modified version as\ndnl well.\n\ndnl Check if the flag is supported by compiler\ndnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])\n\nAC_DEFUN([CC_CHECK_CFLAGS_SILENT], [\n  AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]),\n    [ac_save_CFLAGS=\"$CFLAGS\"\n     CFLAGS=\"$CFLAGS $1\"\n     AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])],\n       [eval \"AS_TR_SH([cc_cv_cflags_$1])='yes'\"],\n       [eval \"AS_TR_SH([cc_cv_cflags_$1])='no'\"])\n     CFLAGS=\"$ac_save_CFLAGS\"\n    ])\n\n  AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],\n    [$2], [$3])\n])\n\ndnl Check if the flag is supported by compiler (cacheable)\ndnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])\n\nAC_DEFUN([CC_CHECK_CFLAGS], [\n  AC_CACHE_CHECK([if $CC supports $1 flag],\n    AS_TR_SH([cc_cv_cflags_$1]),\n    CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!\n  )\n\n  AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],\n    [$2], [$3])\n])\n\ndnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])\ndnl Check for CFLAG and appends them to CFLAGS if supported\nAC_DEFUN([CC_CHECK_CFLAG_APPEND], [\n  AC_CACHE_CHECK([if $CC supports $1 flag],\n    AS_TR_SH([cc_cv_cflags_$1]),\n    CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!\n  )\n\n  AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],\n    [CFLAGS=\"$CFLAGS $1\"; DEBUG_CFLAGS=\"$DEBUG_CFLAGS $1\"; $2], [$3])\n])\n\ndnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not])\nAC_DEFUN([CC_CHECK_CFLAGS_APPEND], [\n  for flag in $1; do\n    CC_CHECK_CFLAG_APPEND($flag, [$2], [$3])\n  done\n])\n\ndnl Check if the flag is supported by linker (cacheable)\ndnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])\n\nAC_DEFUN([CC_CHECK_LDFLAGS], [\n  AC_CACHE_CHECK([if $CC supports $1 flag],\n    AS_TR_SH([cc_cv_ldflags_$1]),\n    [ac_save_LDFLAGS=\"$LDFLAGS\"\n     LDFLAGS=\"$LDFLAGS $1\"\n     AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])],\n       [eval \"AS_TR_SH([cc_cv_ldflags_$1])='yes'\"],\n       [eval \"AS_TR_SH([cc_cv_ldflags_$1])=\"])\n     LDFLAGS=\"$ac_save_LDFLAGS\"\n    ])\n\n  AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],\n    [$2], [$3])\n])\n\ndnl define the LDFLAGS_NOUNDEFINED variable with the correct value for\ndnl the current linker to avoid undefined references in a shared object.\nAC_DEFUN([CC_NOUNDEFINED], [\n  dnl We check $host for which systems to enable this for.\n  AC_REQUIRE([AC_CANONICAL_HOST])\n\n  case $host in\n     dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads\n     dnl are requested, as different implementations are present; to avoid problems\n     dnl use -Wl,-z,defs only for those platform not behaving this way.\n     dnl\n     dnl MinGW platforms: for libraries required -no-undefined,\n     dnl use it only for libraries in mingw32-w64 \n\n     *-freebsd* | *-openbsd*) ;;\n     *-mingw* | *-cygwin*)\n        LDFLAGS_NOUNDEFINED=\"-no-undefined\"\n        ;;\n     *)\n        dnl First of all check for the --no-undefined variant of GNU ld. This allows\n        dnl for a much more readable commandline, so that people can understand what\n        dnl it does without going to look for what the heck -z defs does.\n\tfor possible_flags in \"-Wl,--no-undefined\" \"-Wl,-z,defs\"; do\n          CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED=\"$possible_flags\"])\n\t  if test \"x$LDFLAGS_NOUNDEFINED\" = \"x\"; then break; fi\n        done\n\t;;\n  esac\n\n  AC_SUBST([LDFLAGS_NOUNDEFINED])\n])\n\ndnl Check for a -Werror flag or equivalent. -Werror is the GCC\ndnl and ICC flag that tells the compiler to treat all the warnings\ndnl as fatal. We usually need this option to make sure that some\ndnl constructs (like attributes) are not simply ignored.\ndnl\ndnl Other compilers don't support -Werror per se, but they support\ndnl an equivalent flag:\ndnl  - Sun Studio compiler supports -errwarn=%all\nAC_DEFUN([CC_CHECK_WERROR], [\n  AC_CACHE_CHECK(\n    [for $CC way to treat warnings as errors],\n    [cc_cv_werror],\n    [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror],\n      [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])])\n    ])\n])\n\nAC_DEFUN([CC_CHECK_ATTRIBUTE], [\n  AC_REQUIRE([CC_CHECK_WERROR])\n  AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))],\n    AS_TR_SH([cc_cv_attribute_$1]),\n    [ac_save_CFLAGS=\"$CFLAGS\"\n     CFLAGS=\"$CFLAGS $cc_cv_werror\"\n     AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])],\n       [eval \"AS_TR_SH([cc_cv_attribute_$1])='yes'\"],\n       [eval \"AS_TR_SH([cc_cv_attribute_$1])='no'\"])\n     CFLAGS=\"$ac_save_CFLAGS\"\n    ])\n\n  AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes],\n    [AC_DEFINE(\n       AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1,\n         [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))]\n         )\n     $4],\n    [$5])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [\n  CC_CHECK_ATTRIBUTE(\n    [constructor],,\n    [void __attribute__((constructor)) ctor() { int a; }],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_FORMAT], [\n  CC_CHECK_ATTRIBUTE(\n    [format], [format(printf, n, n)],\n    [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [\n  CC_CHECK_ATTRIBUTE(\n    [format_arg], [format_arg(printf)],\n    [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [\n  CC_CHECK_ATTRIBUTE(\n    [visibility_$1], [visibility(\"$1\")],\n    [void __attribute__((visibility(\"$1\"))) $1_function() { }],\n    [$2], [$3])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_NONNULL], [\n  CC_CHECK_ATTRIBUTE(\n    [nonnull], [nonnull()],\n    [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_UNUSED], [\n  CC_CHECK_ATTRIBUTE(\n    [unused], ,\n    [void some_function(void *foo, __attribute__((unused)) void *bar);],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_WARN_UNUSED_RESULT], [\n  CC_CHECK_ATTRIBUTE(\n    [warn_unused_result], ,\n    [void *some_function(void) __attribute__((warn_unused_result));],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_SENTINEL], [\n  CC_CHECK_ATTRIBUTE(\n    [sentinel], ,\n    [void some_function(void *foo, ...) __attribute__((sentinel));],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_WEAK], [\n  CC_CHECK_ATTRIBUTE(\n    [weak], ,\n    [void some_function(void *, int) __attribute__((weak));],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [\n  CC_CHECK_ATTRIBUTE(\n    [deprecated], ,\n    [void some_function(void *foo, ...) __attribute__((deprecated));],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_ALIAS], [\n  CC_CHECK_ATTRIBUTE(\n    [alias], [weak, alias],\n    [void other_function(void *foo) { }\n     void some_function(void *foo) __attribute__((weak, alias(\"other_function\")));],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_MALLOC], [\n  CC_CHECK_ATTRIBUTE(\n    [malloc], ,\n    [void * __attribute__((malloc)) my_alloc(int n);],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_PACKED], [\n  CC_CHECK_ATTRIBUTE(\n    [packed], ,\n    [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_CONST], [\n  CC_CHECK_ATTRIBUTE(\n    [const], ,\n    [int __attribute__((const)) twopow(int n) { return 1 << n; } ],\n    [$1], [$2])\n])\n\nAC_DEFUN([CC_FLAG_VISIBILITY], [\n  AC_REQUIRE([CC_CHECK_WERROR])\n  AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],\n    [cc_cv_flag_visibility],\n    [cc_flag_visibility_save_CFLAGS=\"$CFLAGS\"\n     CFLAGS=\"$CFLAGS $cc_cv_werror\"\n     CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],\n\tcc_cv_flag_visibility='yes',\n\tcc_cv_flag_visibility='no')\n     CFLAGS=\"$cc_flag_visibility_save_CFLAGS\"])\n\n  AS_IF([test \"x$cc_cv_flag_visibility\" = \"xyes\"],\n    [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,\n       [Define this if the compiler supports the -fvisibility flag])\n     $1],\n    [$2])\n])\n\nAC_DEFUN([CC_FUNC_EXPECT], [\n  AC_REQUIRE([CC_CHECK_WERROR])\n  AC_CACHE_CHECK([if compiler has __builtin_expect function],\n    [cc_cv_func_expect],\n    [ac_save_CFLAGS=\"$CFLAGS\"\n     CFLAGS=\"$CFLAGS $cc_cv_werror\"\n     AC_COMPILE_IFELSE(\n       [int some_function() {\n        int a = 3;\n        return (int)__builtin_expect(a, 3);\n\t}],\n       [cc_cv_func_expect=yes],\n       [cc_cv_func_expect=no])\n     CFLAGS=\"$ac_save_CFLAGS\"\n    ])\n\n  AS_IF([test \"x$cc_cv_func_expect\" = \"xyes\"],\n    [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1,\n     [Define this if the compiler supports __builtin_expect() function])\n     $1],\n    [$2])\n])\n\nAC_DEFUN([CC_ATTRIBUTE_ALIGNED], [\n  AC_REQUIRE([CC_CHECK_WERROR])\n  AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported],\n    [cc_cv_attribute_aligned],\n    [ac_save_CFLAGS=\"$CFLAGS\"\n     CFLAGS=\"$CFLAGS $cc_cv_werror\"\n     for cc_attribute_align_try in 64 32 16 8 4 2; do\n        AC_COMPILE_IFELSE([AC_LANG_SOURCE([\n          int main() {\n            static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0;\n            return c;\n          }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break])\n     done\n     CFLAGS=\"$ac_save_CFLAGS\"\n  ])\n\n  if test \"x$cc_cv_attribute_aligned\" != \"x\"; then\n     AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],\n       [Define the highest alignment supported])\n  fi\n])\n"
  },
  {
    "path": "m4/ax_check_compile_flag.m4",
    "content": "# ===========================================================================\n#  https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html\n# ===========================================================================\n#\n# SYNOPSIS\n#\n#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])\n#\n# DESCRIPTION\n#\n#   Check whether the given FLAG works with the current language's compiler\n#   or gives an error.  (Warnings, however, are ignored)\n#\n#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on\n#   success/failure.\n#\n#   If EXTRA-FLAGS is defined, it is added to the current language's default\n#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with\n#   the flags: \"CFLAGS EXTRA-FLAGS FLAG\".  This can for example be used to\n#   force the compiler to issue an error when a bad flag is given.\n#\n#   INPUT gives an alternative input source to AC_COMPILE_IFELSE.\n#\n#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this\n#   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.\n#\n# LICENSE\n#\n#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>\n#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>\n#\n#   Copying and distribution of this file, with or without modification, are\n#   permitted in any medium without royalty provided the copyright notice\n#   and this notice are preserved.  This file is offered as-is, without any\n#   warranty.\n\n#serial 6\n\nAC_DEFUN([AX_CHECK_COMPILE_FLAG],\n[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF\nAS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl\nAC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [\n  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS\n  _AC_LANG_PREFIX[]FLAGS=\"$[]_AC_LANG_PREFIX[]FLAGS $4 $1\"\n  AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],\n    [AS_VAR_SET(CACHEVAR,[yes])],\n    [AS_VAR_SET(CACHEVAR,[no])])\n  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])\nAS_VAR_IF(CACHEVAR,yes,\n  [m4_default([$2], :)],\n  [m4_default([$3], :)])\nAS_VAR_POPDEF([CACHEVAR])dnl\n])dnl AX_CHECK_COMPILE_FLAGS\n"
  },
  {
    "path": "m4/btowc.m4",
    "content": "# btowc.m4 serial 12\ndnl Copyright (C) 2008-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_BTOWC],\n[\n  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])\n\n  dnl Check whether <wchar.h> is usable at all, first. Otherwise the test\n  dnl program below may lead to an endless loop. See\n  dnl <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42440>.\n  AC_REQUIRE([gl_WCHAR_H_INLINE_OK])\n\n  AC_CHECK_FUNCS_ONCE([btowc])\n  if test $ac_cv_func_btowc = no; then\n    HAVE_BTOWC=0\n  else\n\n    AC_REQUIRE([AC_PROG_CC])\n    AC_REQUIRE([gt_LOCALE_FR])\n    AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n\n    dnl Cygwin 1.7.2 btowc('\\0') is WEOF, not 0.\n    AC_CACHE_CHECK([whether btowc(0) is correct],\n      [gl_cv_func_btowc_nul],\n      [\n        AC_RUN_IFELSE(\n          [AC_LANG_SOURCE([[\n#include <wchar.h>\nint main ()\n{\n  if (btowc ('\\0') != 0)\n    return 1;\n  return 0;\n}]])],\n          [gl_cv_func_btowc_nul=yes],\n          [gl_cv_func_btowc_nul=no],\n          [\nchangequote(,)dnl\n           case \"$host_os\" in\n                      # Guess no on Cygwin.\n             cygwin*) gl_cv_func_btowc_nul=\"guessing no\" ;;\n                      # Guess yes on native Windows.\n             mingw*)  gl_cv_func_btowc_nul=\"guessing yes\" ;;\n                      # Guess yes otherwise.\n             *)       gl_cv_func_btowc_nul=\"guessing yes\" ;;\n           esac\nchangequote([,])dnl\n          ])\n      ])\n\n    dnl IRIX 6.5 btowc(EOF) is 0xFF, not WEOF.\n    AC_CACHE_CHECK([whether btowc(EOF) is correct],\n      [gl_cv_func_btowc_eof],\n      [\n        dnl Initial guess, used when cross-compiling or when no suitable locale\n        dnl is present.\nchangequote(,)dnl\n        case \"$host_os\" in\n                  # Guess no on IRIX.\n          irix*)  gl_cv_func_btowc_eof=\"guessing no\" ;;\n                  # Guess yes on native Windows.\n          mingw*) gl_cv_func_btowc_eof=\"guessing yes\" ;;\n                  # Guess yes otherwise.\n          *)      gl_cv_func_btowc_eof=\"guessing yes\" ;;\n        esac\nchangequote([,])dnl\n        if test $LOCALE_FR != none; then\n          AC_RUN_IFELSE(\n            [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <stdio.h>\n#include <wchar.h>\nint main ()\n{\n  if (setlocale (LC_ALL, \"$LOCALE_FR\") != NULL)\n    {\n      if (btowc (EOF) != WEOF)\n        return 1;\n    }\n  return 0;\n}]])],\n            [gl_cv_func_btowc_eof=yes],\n            [gl_cv_func_btowc_eof=no],\n            [:])\n        fi\n      ])\n\n    case \"$gl_cv_func_btowc_nul\" in\n      *yes) ;;\n      *) REPLACE_BTOWC=1 ;;\n    esac\n    case \"$gl_cv_func_btowc_eof\" in\n      *yes) ;;\n      *) REPLACE_BTOWC=1 ;;\n    esac\n  fi\n])\n\n# Prerequisites of lib/btowc.c.\nAC_DEFUN([gl_PREREQ_BTOWC], [\n  :\n])\n"
  },
  {
    "path": "m4/builtin-expect.m4",
    "content": "dnl Check for __builtin_expect.\n\ndnl Copyright 2016-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl Written by Paul Eggert.\n\nAC_DEFUN([gl___BUILTIN_EXPECT],\n[\n  AC_CACHE_CHECK([for __builtin_expect],\n    [gl_cv___builtin_expect],\n    [AC_LINK_IFELSE(\n       [AC_LANG_SOURCE([[\n         int\n         main (int argc, char **argv)\n         {\n           argc = __builtin_expect (argc, 100);\n           return argv[argc != 100][0];\n         }]])],\n       [gl_cv___builtin_expect=yes],\n       [AC_LINK_IFELSE(\n          [AC_LANG_SOURCE([[\n             #include <builtins.h>\n             int\n             main (int argc, char **argv)\n             {\n               argc = __builtin_expect (argc, 100);\n               return argv[argc != 100][0];\n             }]])],\n          [gl_cv___builtin_expect=\"in <builtins.h>\"],\n          [gl_cv___builtin_expect=no])])])\n  if test \"$gl_cv___builtin_expect\" = yes; then\n    AC_DEFINE([HAVE___BUILTIN_EXPECT], [1])\n  elif test \"$gl_cv___builtin_expect\" = \"in <builtins.h>\"; then\n    AC_DEFINE([HAVE___BUILTIN_EXPECT], [2])\n  fi\n  AH_VERBATIM([HAVE___BUILTIN_EXPECT],\n    [/* Define to 1 if the compiler supports __builtin_expect,\n   and to 2 if <builtins.h> does.  */\n#undef HAVE___BUILTIN_EXPECT\n#ifndef HAVE___BUILTIN_EXPECT\n# define __builtin_expect(e, c) (e)\n#elif HAVE___BUILTIN_EXPECT == 2\n# include <builtins.h>\n#endif\n    ])\n])\n"
  },
  {
    "path": "m4/codeset.m4",
    "content": "# codeset.m4 serial 5 (gettext-0.18.2)\ndnl Copyright (C) 2000-2002, 2006, 2008-2014, 2016, 2019-2021 Free Software\ndnl Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\n\nAC_DEFUN([AM_LANGINFO_CODESET],\n[\n  AC_CACHE_CHECK([for nl_langinfo and CODESET], [am_cv_langinfo_codeset],\n    [AC_LINK_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <langinfo.h>]],\n          [[char* cs = nl_langinfo(CODESET); return !cs;]])],\n       [am_cv_langinfo_codeset=yes],\n       [am_cv_langinfo_codeset=no])\n    ])\n  if test $am_cv_langinfo_codeset = yes; then\n    AC_DEFINE([HAVE_LANGINFO_CODESET], [1],\n      [Define if you have <langinfo.h> and nl_langinfo(CODESET).])\n  fi\n])\n"
  },
  {
    "path": "m4/ctype_h.m4",
    "content": "# ctype_h.m4 serial 9\ndnl Copyright (C) 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN_ONCE([gl_CTYPE_H],\n[\n  AC_REQUIRE([gl_CTYPE_H_DEFAULTS])\n\n  dnl <ctype.h> is always overridden, because of GNULIB_POSIXCHECK.\n  gl_NEXT_HEADERS([ctype.h])\n\n  dnl Check for declarations of anything we want to poison if the\n  dnl corresponding gnulib module is not in use.\n  gl_WARN_ON_USE_PREPARE([[#include <ctype.h>\n    ]], [isblank])\n])\n\n# gl_CTYPE_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_CTYPE_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_CTYPE_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_CTYPE_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_CTYPE_H_MODULE_INDICATOR_DEFAULTS], [\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISBLANK])\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_CTYPE_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_CTYPE_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_CTYPE_H_DEFAULTS],\n[\n  dnl Assume proper GNU behavior unless another module says otherwise.\n  HAVE_ISBLANK=1;   AC_SUBST([HAVE_ISBLANK])\n])\n"
  },
  {
    "path": "m4/eealloc.m4",
    "content": "# eealloc.m4 serial 3\ndnl Copyright (C) 2003, 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_EEALLOC],\n[\n  AC_REQUIRE([gl_EEMALLOC])\n  AC_REQUIRE([gl_EEREALLOC])\n])\n\nAC_DEFUN([gl_EEMALLOC],\n[\n  _AC_FUNC_MALLOC_IF(\n    [gl_cv_func_malloc_0_nonnull=1],\n    [gl_cv_func_malloc_0_nonnull=0])\n  AC_DEFINE_UNQUOTED([MALLOC_0_IS_NONNULL], [$gl_cv_func_malloc_0_nonnull],\n    [If malloc(0) is != NULL, define this to 1.  Otherwise define this\n     to 0.])\n])\n\nAC_DEFUN([gl_EEREALLOC],\n[\n  _AC_FUNC_REALLOC_IF(\n    [gl_cv_func_realloc_0_nonnull=1],\n    [gl_cv_func_realloc_0_nonnull=0])\n  AC_DEFINE_UNQUOTED([REALLOC_0_IS_NONNULL], [$gl_cv_func_realloc_0_nonnull],\n    [If realloc(NULL,0) is != NULL, define this to 1.  Otherwise define this\n     to 0.])\n])\n"
  },
  {
    "path": "m4/extensions.m4",
    "content": "# serial 22  -*- Autoconf -*-\n# Enable extensions on systems that normally disable them.\n\n# Copyright (C) 2003, 2006-2021 Free Software Foundation, Inc.\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\ndnl Define to empty for the benefit of Autoconf 2.69 and earlier, so that\ndnl AC_USE_SYSTEM_EXTENSIONS (below) can be used unchanged from Autoconf 2.70+.\nm4_ifndef([AC_CHECK_INCLUDES_DEFAULT],\n  [AC_DEFUN([AC_CHECK_INCLUDES_DEFAULT], [])])\n\n# This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from git\n# Autoconf.  Perhaps we can remove this once we can assume Autoconf\n# is recent-enough everywhere, but since Autoconf mutates rapidly\n# enough in this area it's likely we'll need to redefine\n# AC_USE_SYSTEM_EXTENSIONS for quite some time.\n\n# If autoconf reports a warning\n#     warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS\n# or  warning: AC_RUN_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS\n# the fix is\n#   1) to ensure that AC_USE_SYSTEM_EXTENSIONS is never directly invoked\n#      but always AC_REQUIREd,\n#   2) to ensure that for each occurrence of\n#        AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])\n#      or\n#        AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])\n#      the corresponding gnulib module description has 'extensions' among\n#      its dependencies. This will ensure that the gl_USE_SYSTEM_EXTENSIONS\n#      invocation occurs in gl_EARLY, not in gl_INIT.\n\nm4_version_prereq([2.70.1], [], [\n\n# AC_USE_SYSTEM_EXTENSIONS\n# ------------------------\n# Enable extensions on systems that normally disable them,\n# typically due to standards-conformance issues.\n# We unconditionally define as many of the known feature-enabling\n# as possible, reserving conditional behavior for macros that are\n# known to cause problems on some platforms (such as __EXTENSIONS__).\nAC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS],\n[AC_BEFORE([$0], [AC_PREPROC_IFELSE])dnl\nAC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl\nAC_BEFORE([$0], [AC_LINK_IFELSE])dnl\nAC_BEFORE([$0], [AC_RUN_IFELSE])dnl\nAC_BEFORE([$0], [AC_CHECK_INCLUDES_DEFAULT])dnl\ndnl #undef in AH_VERBATIM gets replaced with #define by AC_DEFINE.\ndnl Use a different key than __EXTENSIONS__, as that name broke existing\ndnl configure.ac when using autoheader 2.62.\ndnl The macros below are in alphabetical order ignoring leading _ or __\ndnl prefixes.\nAH_VERBATIM([USE_SYSTEM_EXTENSIONS],\n[/* Enable extensions on AIX 3, Interix.  */\n#ifndef _ALL_SOURCE\n# undef _ALL_SOURCE\n#endif\n/* Enable general extensions on macOS.  */\n#ifndef _DARWIN_C_SOURCE\n# undef _DARWIN_C_SOURCE\n#endif\n/* Enable general extensions on Solaris.  */\n#ifndef __EXTENSIONS__\n# undef __EXTENSIONS__\n#endif\n/* Enable GNU extensions on systems that have them.  */\n#ifndef _GNU_SOURCE\n# undef _GNU_SOURCE\n#endif\n/* Enable X/Open compliant socket functions that do not require linking\n   with -lxnet on HP-UX 11.11.  */\n#ifndef _HPUX_ALT_XOPEN_SOCKET_API\n# undef _HPUX_ALT_XOPEN_SOCKET_API\n#endif\n/* Identify the host operating system as Minix.\n   This macro does not affect the system headers' behavior.\n   A future release of Autoconf may stop defining this macro.  */\n#ifndef _MINIX\n# undef _MINIX\n#endif\n/* Enable general extensions on NetBSD.\n   Enable NetBSD compatibility extensions on Minix.  */\n#ifndef _NETBSD_SOURCE\n# undef _NETBSD_SOURCE\n#endif\n/* Enable OpenBSD compatibility extensions on NetBSD.\n   Oddly enough, this does nothing on OpenBSD.  */\n#ifndef _OPENBSD_SOURCE\n# undef _OPENBSD_SOURCE\n#endif\n/* Define to 1 if needed for POSIX-compatible behavior.  */\n#ifndef _POSIX_SOURCE\n# undef _POSIX_SOURCE\n#endif\n/* Define to 2 if needed for POSIX-compatible behavior.  */\n#ifndef _POSIX_1_SOURCE\n# undef _POSIX_1_SOURCE\n#endif\n/* Enable POSIX-compatible threading on Solaris.  */\n#ifndef _POSIX_PTHREAD_SEMANTICS\n# undef _POSIX_PTHREAD_SEMANTICS\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-5:2014.  */\n#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__\n# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-1:2014.  */\n#ifndef __STDC_WANT_IEC_60559_BFP_EXT__\n# undef __STDC_WANT_IEC_60559_BFP_EXT__\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-2:2015.  */\n#ifndef __STDC_WANT_IEC_60559_DFP_EXT__\n# undef __STDC_WANT_IEC_60559_DFP_EXT__\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-4:2015.  */\n#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__\n# undef __STDC_WANT_IEC_60559_FUNCS_EXT__\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-3:2015.  */\n#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__\n# undef __STDC_WANT_IEC_60559_TYPES_EXT__\n#endif\n/* Enable extensions specified by ISO/IEC TR 24731-2:2010.  */\n#ifndef __STDC_WANT_LIB_EXT2__\n# undef __STDC_WANT_LIB_EXT2__\n#endif\n/* Enable extensions specified by ISO/IEC 24747:2009.  */\n#ifndef __STDC_WANT_MATH_SPEC_FUNCS__\n# undef __STDC_WANT_MATH_SPEC_FUNCS__\n#endif\n/* Enable extensions on HP NonStop.  */\n#ifndef _TANDEM_SOURCE\n# undef _TANDEM_SOURCE\n#endif\n/* Enable X/Open extensions.  Define to 500 only if necessary\n   to make mbstate_t available.  */\n#ifndef _XOPEN_SOURCE\n# undef _XOPEN_SOURCE\n#endif\n])dnl\n\n  AC_REQUIRE([AC_CHECK_INCLUDES_DEFAULT])dnl\n  _AC_CHECK_HEADER_ONCE([wchar.h])\n  _AC_CHECK_HEADER_ONCE([minix/config.h])\n\ndnl Defining __EXTENSIONS__ may break the system headers on some systems.\ndnl (FIXME: Which ones?)\n  AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__],\n    [ac_cv_safe_to_define___extensions__],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM([[\n#         define __EXTENSIONS__ 1\n          ]AC_INCLUDES_DEFAULT])],\n       [ac_cv_safe_to_define___extensions__=yes],\n       [ac_cv_safe_to_define___extensions__=no])])\n\ndnl HP-UX 11.11 defines mbstate_t only if _XOPEN_SOURCE is defined to\ndnl 500, regardless of whether compiling with -Ae or -D_HPUX_SOURCE=1.\ndnl But defining _XOPEN_SOURCE may turn *off* extensions on platforms\ndnl not covered by turn-on-extensions macros (notably Dragonfly, Free,\ndnl and OpenBSD, which don't have any equivalent of _NETBSD_SOURCE) so\ndnl it should only be defined when necessary.\n  AC_CACHE_CHECK([whether _XOPEN_SOURCE should be defined],\n    [ac_cv_should_define__xopen_source],\n    [ac_cv_should_define__xopen_source=no\n    AS_IF([test $ac_cv_header_wchar_h = yes],\n      [AC_COMPILE_IFELSE(\n        [AC_LANG_PROGRAM([[\n          #include <wchar.h>\n          mbstate_t x;]])],\n        [],\n        [AC_COMPILE_IFELSE(\n          [AC_LANG_PROGRAM([[\n            #define _XOPEN_SOURCE 500\n            #include <wchar.h>\n            mbstate_t x;]])],\n          [ac_cv_should_define__xopen_source=yes])])])])\n\n  AC_DEFINE([_ALL_SOURCE])\n  AC_DEFINE([_DARWIN_C_SOURCE])\n  AC_DEFINE([_GNU_SOURCE])\n  AC_DEFINE([_HPUX_ALT_XOPEN_SOCKET_API])\n  AC_DEFINE([_NETBSD_SOURCE])\n  AC_DEFINE([_OPENBSD_SOURCE])\n  AC_DEFINE([_POSIX_PTHREAD_SEMANTICS])\n  AC_DEFINE([__STDC_WANT_IEC_60559_ATTRIBS_EXT__])\n  AC_DEFINE([__STDC_WANT_IEC_60559_BFP_EXT__])\n  AC_DEFINE([__STDC_WANT_IEC_60559_DFP_EXT__])\n  AC_DEFINE([__STDC_WANT_IEC_60559_FUNCS_EXT__])\n  AC_DEFINE([__STDC_WANT_IEC_60559_TYPES_EXT__])\n  AC_DEFINE([__STDC_WANT_LIB_EXT2__])\n  AC_DEFINE([__STDC_WANT_MATH_SPEC_FUNCS__])\n  AC_DEFINE([_TANDEM_SOURCE])\n  AS_IF([test $ac_cv_header_minix_config_h = yes],\n    [MINIX=yes\n    AC_DEFINE([_MINIX])\n    AC_DEFINE([_POSIX_SOURCE])\n    AC_DEFINE([_POSIX_1_SOURCE], [2])],\n    [MINIX=])\n  AS_IF([test $ac_cv_safe_to_define___extensions__ = yes],\n    [AC_DEFINE([__EXTENSIONS__])])\n  AS_IF([test $ac_cv_should_define__xopen_source = yes],\n    [AC_DEFINE([_XOPEN_SOURCE], [500])])\n])# AC_USE_SYSTEM_EXTENSIONS\n])\n\n# gl_USE_SYSTEM_EXTENSIONS\n# ------------------------\n# Enable extensions on systems that normally disable them,\n# typically due to standards-conformance issues.\nAC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS],\n[\n  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])\n\n  dnl On OpenBSD 6.8 with GCC, the include files contain a couple of\n  dnl definitions that are only activated with an explicit -D_ISOC11_SOURCE.\n  dnl That's because this version of GCC (4.2.1) supports the option\n  dnl '-std=gnu99' but not the option '-std=gnu11'.\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  case \"$host_os\" in\n    openbsd*)\n      AC_DEFINE([_ISOC11_SOURCE], [1],\n        [Define to enable the declarations of ISO C 11 types and functions.])\n      ;;\n  esac\n])\n"
  },
  {
    "path": "m4/extern-inline.m4",
    "content": "dnl 'extern inline' a la ISO C99.\n\ndnl Copyright 2012-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_EXTERN_INLINE],\n[\n  AH_VERBATIM([extern_inline],\n[/* Please see the Gnulib manual for how to use these macros.\n\n   Suppress extern inline with HP-UX cc, as it appears to be broken; see\n   <https://lists.gnu.org/r/bug-texinfo/2013-02/msg00030.html>.\n\n   Suppress extern inline with Sun C in standards-conformance mode, as it\n   mishandles inline functions that call each other.  E.g., for 'inline void f\n   (void) { } inline void g (void) { f (); }', c99 incorrectly complains\n   'reference to static identifier \"f\" in extern inline function'.\n   This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.\n\n   Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))\n   on configurations that mistakenly use 'static inline' to implement\n   functions or macros in standard C headers like <ctype.h>.  For example,\n   if isdigit is mistakenly implemented via a static inline function,\n   a program containing an extern inline function that calls isdigit\n   may not work since the C standard prohibits extern inline functions\n   from calling static functions (ISO C 99 section 6.7.4.(3).\n   This bug is known to occur on:\n\n     OS X 10.8 and earlier; see:\n     https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html\n\n     DragonFly; see\n     http://muscles.dragonflybsd.org/bulk/clang-master-potential/20141111_102002/logs/ah-tty-0.3.12.log\n\n     FreeBSD; see:\n     https://lists.gnu.org/r/bug-gnulib/2014-07/msg00104.html\n\n   OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and\n   for clang but remains for g++; see <https://trac.macports.org/ticket/41033>.\n   Assume DragonFly and FreeBSD will be similar.\n\n   GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99\n   inline semantics, unless -fgnu89-inline is used.  It defines a macro\n   __GNUC_STDC_INLINE__ to indicate this situation or a macro\n   __GNUC_GNU_INLINE__ to indicate the opposite situation.\n   GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline\n   semantics but warns, unless -fgnu89-inline is used:\n     warning: C99 inline functions are not supported; using GNU89\n     warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute\n   It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.\n */\n#if (((defined __APPLE__ && defined __MACH__) \\\n      || defined __DragonFly__ || defined __FreeBSD__) \\\n     && (defined __header_inline \\\n         ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \\\n            && ! defined __clang__) \\\n         : ((! defined _DONT_USE_CTYPE_INLINE_ \\\n             && (defined __GNUC__ || defined __cplusplus)) \\\n            || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \\\n                && defined __GNUC__ && ! defined __cplusplus))))\n# define _GL_EXTERN_INLINE_STDHEADER_BUG\n#endif\n#if ((__GNUC__ \\\n      ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \\\n      : (199901L <= __STDC_VERSION__ \\\n         && !defined __HP_cc \\\n         && !defined __PGI \\\n         && !(defined __SUNPRO_C && __STDC__))) \\\n     && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)\n# define _GL_INLINE inline\n# define _GL_EXTERN_INLINE extern inline\n# define _GL_EXTERN_INLINE_IN_USE\n#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \\\n       && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)\n# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__\n   /* __gnu_inline__ suppresses a GCC 4.2 diagnostic.  */\n#  define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))\n# else\n#  define _GL_INLINE extern inline\n# endif\n# define _GL_EXTERN_INLINE extern\n# define _GL_EXTERN_INLINE_IN_USE\n#else\n# define _GL_INLINE static _GL_UNUSED\n# define _GL_EXTERN_INLINE static _GL_UNUSED\n#endif\n\n/* In GCC 4.6 (inclusive) to 5.1 (exclusive),\n   suppress bogus \"no previous prototype for 'FOO'\"\n   and \"no previous declaration for 'FOO'\" diagnostics,\n   when FOO is an inline function in the header; see\n   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and\n   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>.  */\n#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__\n# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__\n#  define _GL_INLINE_HEADER_CONST_PRAGMA\n# else\n#  define _GL_INLINE_HEADER_CONST_PRAGMA \\\n     _Pragma (\"GCC diagnostic ignored \\\"-Wsuggest-attribute=const\\\"\")\n# endif\n# define _GL_INLINE_HEADER_BEGIN \\\n    _Pragma (\"GCC diagnostic push\") \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wmissing-prototypes\\\"\") \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wmissing-declarations\\\"\") \\\n    _GL_INLINE_HEADER_CONST_PRAGMA\n# define _GL_INLINE_HEADER_END \\\n    _Pragma (\"GCC diagnostic pop\")\n#else\n# define _GL_INLINE_HEADER_BEGIN\n# define _GL_INLINE_HEADER_END\n#endif])\n])\n"
  },
  {
    "path": "m4/flexmember.m4",
    "content": "# serial 5\n# Check for flexible array member support.\n\n# Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# Written by Paul Eggert.\n\nAC_DEFUN([AC_C_FLEXIBLE_ARRAY_MEMBER],\n[\n  AC_CACHE_CHECK([for flexible array member],\n    ac_cv_c_flexmember,\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <stdlib.h>\n            #include <stdio.h>\n            #include <stddef.h>\n            struct m { struct m *next, **list; char name[]; };\n            struct s { struct s *p; struct m *m; int n; double d[]; };]],\n          [[int m = getchar ();\n            size_t nbytes = offsetof (struct s, d) + m * sizeof (double);\n            nbytes += sizeof (struct s) - 1;\n            nbytes -= nbytes % sizeof (struct s);\n            struct s *p = malloc (nbytes);\n            p->p = p;\n            p->m = NULL;\n            p->d[0] = 0.0;\n            return p->d != (double *) NULL;]])],\n       [ac_cv_c_flexmember=yes],\n       [ac_cv_c_flexmember=no])])\n  if test $ac_cv_c_flexmember = yes; then\n    AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [],\n      [Define to nothing if C supports flexible array members, and to\n       1 if it does not.  That way, with a declaration like 'struct s\n       { int n; short d@<:@FLEXIBLE_ARRAY_MEMBER@:>@; };', the struct hack\n       can be used with pre-C99 compilers.\n       Use 'FLEXSIZEOF (struct s, d, N * sizeof (short))' to calculate\n       the size in bytes of such a struct containing an N-element array.])\n  else\n    AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [1])\n  fi\n])\n"
  },
  {
    "path": "m4/fnmatch.m4",
    "content": "# Check for fnmatch - serial 15.  -*- coding: utf-8 -*-\n\n# Copyright (C) 2000-2007, 2009-2021 Free Software Foundation, Inc.\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# Autoconf defines AC_FUNC_FNMATCH, but that is obsolescent.\n# New applications should use the macros below instead.\n\n# Request a POSIX compliant fnmatch function.\nAC_DEFUN([gl_FUNC_FNMATCH_POSIX],\n[\n  m4_divert_text([DEFAULTS], [gl_fnmatch_required=POSIX])\n\n  AC_REQUIRE([gl_FNMATCH_H])\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  gl_fnmatch_required_lowercase=`\n    echo $gl_fnmatch_required | LC_ALL=C tr '[[A-Z]]' '[[a-z]]'\n  `\n  AC_CHECK_FUNCS_ONCE([fnmatch])\n  if test $ac_cv_func_fnmatch = no; then\n    HAVE_FNMATCH=0\n  else\n    gl_fnmatch_cache_var=\"gl_cv_func_fnmatch_${gl_fnmatch_required_lowercase}\"\n    AC_CACHE_CHECK([for working $gl_fnmatch_required fnmatch],\n      [$gl_fnmatch_cache_var],\n      [dnl Some versions of Solaris, SCO, and the GNU C Library\n       dnl have a broken or incompatible fnmatch.\n       dnl So we run a test program.  If we are cross-compiling, take no chance.\n       dnl Thanks to John Oleynick, François Pinard, and Paul Eggert for this\n       dnl test.\n       if test $gl_fnmatch_required = GNU; then\n         gl_fnmatch_gnu_start=\n         gl_fnmatch_gnu_end=\n       else\n         gl_fnmatch_gnu_start='#if 0'\n         gl_fnmatch_gnu_end='#endif'\n       fi\n       AC_RUN_IFELSE(\n         [AC_LANG_PROGRAM(\n            [[#include <fnmatch.h>\n              static int\n              y (char const *pattern, char const *string, int flags)\n              {\n                return fnmatch (pattern, string, flags) == 0;\n              }\n              static int\n              n (char const *pattern, char const *string, int flags)\n              {\n                return fnmatch (pattern, string, flags) == FNM_NOMATCH;\n              }\n            ]],\n            [[char const *Apat = 'A' < '\\\\\\\\' ? \"[A-\\\\\\\\\\\\\\\\]\" : \"[\\\\\\\\\\\\\\\\-A]\";\n              char const *apat = 'a' < '\\\\\\\\' ? \"[a-\\\\\\\\\\\\\\\\]\" : \"[\\\\\\\\\\\\\\\\-a]\";\n              static char const A_1[] = { 'A' - 1, 0 };\n              static char const A01[] = { 'A' + 1, 0 };\n              static char const a_1[] = { 'a' - 1, 0 };\n              static char const a01[] = { 'a' + 1, 0 };\n              static char const bs_1[] = { '\\\\\\\\' - 1, 0 };\n              static char const bs01[] = { '\\\\\\\\' + 1, 0 };\n              int result = 0;\n              if (!n (\"a*\", \"\", 0))\n                return 1;\n              if (!y (\"a*\", \"abc\", 0))\n                return 1;\n              if (!y (\"[/b\", \"[/b\", 0)) /*\"]]\"*/ /* glibc Bugzilla bug 12378 */\n                return 1;\n              if (!n (\"d*/*1\", \"d/s/1\", FNM_PATHNAME))\n                return 2;\n              if (!y (\"a\\\\\\\\bc\", \"abc\", 0))\n                return 3;\n              if (!n (\"a\\\\\\\\bc\", \"abc\", FNM_NOESCAPE))\n                return 3;\n              if (!y (\"*x\", \".x\", 0))\n                return 4;\n              if (!n (\"*x\", \".x\", FNM_PERIOD))\n                return 4;\n              if (!y (Apat, \"\\\\\\\\\", 0))\n                return 5;\n              if (!y (Apat, \"A\", 0))\n                return 5;\n              if (!y (apat, \"\\\\\\\\\", 0))\n                return 5;\n              if (!y (apat, \"a\", 0))\n                return 5;\n              if (!(n (Apat, A_1, 0) == ('A' < '\\\\\\\\')))\n                return 5;\n              if (!(n (apat, a_1, 0) == ('a' < '\\\\\\\\')))\n                return 5;\n              if (!(y (Apat, A01, 0) == ('A' < '\\\\\\\\')))\n                return 5;\n              if (!(y (apat, a01, 0) == ('a' < '\\\\\\\\')))\n                return 5;\n              if (!(y (Apat, bs_1, 0) == ('A' < '\\\\\\\\')))\n                return 5;\n              if (!(y (apat, bs_1, 0) == ('a' < '\\\\\\\\')))\n                return 5;\n              if (!(n (Apat, bs01, 0) == ('A' < '\\\\\\\\')))\n                return 5;\n              if (!(n (apat, bs01, 0) == ('a' < '\\\\\\\\')))\n                return 5;\n              $gl_fnmatch_gnu_start\n              if (!y (\"xxXX\", \"xXxX\", FNM_CASEFOLD))\n                result |= 8;\n              if (!y (\"a++(x|yy)b\", \"a+xyyyyxb\", FNM_EXTMATCH))\n                result |= 16;\n              if (!n (\"d*/*1\", \"d/s/1\", FNM_FILE_NAME))\n                result |= 32;\n              if (!y (\"*\", \"x\", FNM_FILE_NAME | FNM_LEADING_DIR))\n                result |= 64;\n              if (!y (\"x*\", \"x/y/z\", FNM_FILE_NAME | FNM_LEADING_DIR))\n                result |= 64;\n              if (!y (\"*c*\", \"c/x\", FNM_FILE_NAME | FNM_LEADING_DIR))\n                result |= 64;\n              $gl_fnmatch_gnu_end\n              return result;\n            ]])],\n         [eval \"$gl_fnmatch_cache_var=yes\"],\n         [eval \"$gl_fnmatch_cache_var=no\"],\n         [case \"$host_os\" in\n                     # Guess yes on musl systems.\n            *-musl*) eval \"$gl_fnmatch_cache_var=\\\"guessing yes\\\"\" ;;\n                     # Guess no otherwise, even on glibc systems.\n            *)       eval \"$gl_fnmatch_cache_var=\\\"guessing no\\\"\" ;;\n          esac\n         ])\n      ])\n    eval \"gl_fnmatch_result=\\\"\\$$gl_fnmatch_cache_var\\\"\"\n    case \"$gl_fnmatch_result\" in\n      *yes) ;;\n      *) REPLACE_FNMATCH=1 ;;\n    esac\n  fi\n  if test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; then\n    gl_REPLACE_FNMATCH_H\n  fi\n])\n\n# Request a POSIX compliant fnmatch function with GNU extensions.\nAC_DEFUN([gl_FUNC_FNMATCH_GNU],\n[\n  m4_divert_text([INIT_PREPARE], [gl_fnmatch_required=GNU])\n\n  AC_REQUIRE([gl_FUNC_FNMATCH_POSIX])\n])\n\nAC_DEFUN([gl_PREREQ_FNMATCH],\n[\n  dnl Prerequisites of lib/fnmatch.c.\n  AC_REQUIRE([AC_TYPE_MBSTATE_T])\n  AC_CHECK_FUNCS_ONCE([mbsrtowcs])\n])\n"
  },
  {
    "path": "m4/fnmatch_h.m4",
    "content": "# fnmatch_h.m4 serial 7\ndnl Copyright (C) 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\n\nAC_DEFUN_ONCE([gl_FNMATCH_H],\n[\n  AC_REQUIRE([gl_FNMATCH_H_DEFAULTS])\n  m4_ifdef([gl_ANSI_CXX], [AC_REQUIRE([gl_ANSI_CXX])])\n  AC_CHECK_HEADERS_ONCE([fnmatch.h])\n  gl_CHECK_NEXT_HEADERS([fnmatch.h])\n\n  dnl Persuade glibc <fnmatch.h> to declare FNM_CASEFOLD etc.\n  dnl This is only needed if gl_fnmatch_required = GNU. It would be possible\n  dnl to avoid this dependency for gl_FUNC_FNMATCH_POSIX by putting\n  dnl gl_FUNC_FNMATCH_GNU into a separate .m4 file.\n  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])\n\n  if test $ac_cv_header_fnmatch_h = yes; then\n    HAVE_FNMATCH_H=1\n  else\n    HAVE_FNMATCH_H=0\n  fi\n  AC_SUBST([HAVE_FNMATCH_H])\n\n  m4_ifdef([gl_POSIXCHECK],\n    [FNMATCH_H=fnmatch.h],\n    [FNMATCH_H=''\n     if m4_ifdef([gl_ANSI_CXX], [test \"$CXX\" != no], [false]); then\n       dnl Override <fnmatch.h> always, to support the C++ GNULIB_NAMESPACE.\n       FNMATCH_H=fnmatch.h\n     else\n       if test $ac_cv_header_fnmatch_h != yes; then\n         dnl Provide a substitute <fnmatch.h> file.\n         FNMATCH_H=fnmatch.h\n       fi\n     fi\n    ])\n  AC_SUBST([FNMATCH_H])\n  AM_CONDITIONAL([GL_GENERATE_FNMATCH_H], [test -n \"$FNMATCH_H\"])\n\n  dnl Check for declarations of anything we want to poison if the\n  dnl corresponding gnulib module is not in use.\n  gl_WARN_ON_USE_PREPARE([[#include <fnmatch.h>\n    ]],\n    [fnmatch])\n])\n\ndnl Unconditionally enables the replacement of <fnmatch.h>.\nAC_DEFUN([gl_REPLACE_FNMATCH_H],\n[\n  gl_FNMATCH_H_REQUIRE_DEFAULTS\n  FNMATCH_H='fnmatch.h'\n  AM_CONDITIONAL([GL_GENERATE_FNMATCH_H], [test -n \"$FNMATCH_H\"])\n])\n\n# gl_FNMATCH_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_FNMATCH_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_FNMATCH_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n  dnl Define it also as a C macro, for the benefit of the unit tests.\n  gl_MODULE_INDICATOR_FOR_TESTS([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_FNMATCH_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_FNMATCH_H_MODULE_INDICATOR_DEFAULTS], [\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FNMATCH])\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_FNMATCH_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_FNMATCH_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_FNMATCH_H_DEFAULTS],\n[\n  dnl Assume POSIX behavior unless another module says otherwise.\n  HAVE_FNMATCH=1;            AC_SUBST([HAVE_FNMATCH])\n  REPLACE_FNMATCH=0;         AC_SUBST([REPLACE_FNMATCH])\n])\n"
  },
  {
    "path": "m4/gnulib-cache.m4",
    "content": "# Copyright (C) 2002-2021 Free Software Foundation, Inc.\n#\n# This file is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This file is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this file.  If not, see <https://www.gnu.org/licenses/>.\n#\n# As a special exception to the GNU General Public License,\n# this file may be distributed as part of a program that\n# contains a configuration script generated by Autoconf, under\n# the same distribution terms as the rest of that program.\n#\n# Generated by gnulib-tool.\n#\n# This file represents the specification of how gnulib-tool is used.\n# It acts as a cache: It is written and read by gnulib-tool.\n# In projects that use version control, this file is meant to be put under\n# version control, like the configure.ac and various Makefile.am files.\n\n\n# Specification in the form of a command-line invocation:\n# gnulib-tool --import \\\n#  --lib=libgnu \\\n#  --source-base=gnulib \\\n#  --m4-base=m4 \\\n#  --doc-base=doc \\\n#  --tests-base=tests \\\n#  --aux-dir=. \\\n#  --no-conditional-dependencies \\\n#  --no-libtool \\\n#  --macro-prefix=gl \\\n#  --no-vc-files \\\n#  fnmatch \\\n#  regex\n\n# Specification in the form of a few gnulib-tool.m4 macro invocations:\ngl_LOCAL_DIR([])\ngl_MODULES([\n  fnmatch\n  regex\n])\ngl_AVOID([])\ngl_SOURCE_BASE([gnulib])\ngl_M4_BASE([m4])\ngl_PO_BASE([])\ngl_DOC_BASE([doc])\ngl_TESTS_BASE([tests])\ngl_LIB([libgnu])\ngl_MAKEFILE_NAME([])\ngl_MACRO_PREFIX([gl])\ngl_PO_DOMAIN([])\ngl_WITNESS_C_MACRO([])\ngl_VC_FILES([false])\n"
  },
  {
    "path": "m4/gnulib-common.m4",
    "content": "# gnulib-common.m4 serial 66\ndnl Copyright (C) 2007-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_PREREQ([2.62])\n\n# gl_COMMON\n# is expanded unconditionally through gnulib-tool magic.\nAC_DEFUN([gl_COMMON], [\n  dnl Use AC_REQUIRE here, so that the code is expanded once only.\n  AC_REQUIRE([gl_00GNULIB])\n  AC_REQUIRE([gl_COMMON_BODY])\n  AC_REQUIRE([gl_ZZGNULIB])\n])\nAC_DEFUN([gl_COMMON_BODY], [\n  AH_VERBATIM([_GL_GNUC_PREREQ],\n[/* True if the compiler says it groks GNU C version MAJOR.MINOR.  */\n#if defined __GNUC__ && defined __GNUC_MINOR__\n# define _GL_GNUC_PREREQ(major, minor) \\\n    ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__))\n#else\n# define _GL_GNUC_PREREQ(major, minor) 0\n#endif\n])\n  AH_VERBATIM([_Noreturn],\n[/* The _Noreturn keyword of C11.  */\n#ifndef _Noreturn\n# if (defined __cplusplus \\\n      && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \\\n          || (defined _MSC_VER && 1900 <= _MSC_VER)) \\\n      && 0)\n    /* [[noreturn]] is not practically usable, because with it the syntax\n         extern _Noreturn void func (...);\n       would not be valid; such a declaration would only be valid with 'extern'\n       and '_Noreturn' swapped, or without the 'extern' keyword.  However, some\n       AIX system header files and several gnulib header files use precisely\n       this syntax with 'extern'.  */\n#  define _Noreturn [[noreturn]]\n# elif ((!defined __cplusplus || defined __clang__) \\\n        && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \\\n            || (!defined __STRICT_ANSI__ \\\n                && (_GL_GNUC_PREREQ (4, 7) \\\n                    || (defined __apple_build_version__ \\\n                        ? 6000000 <= __apple_build_version__ \\\n                        : 3 < __clang_major__ + (5 <= __clang_minor__))))))\n   /* _Noreturn works as-is.  */\n# elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C\n#  define _Noreturn __attribute__ ((__noreturn__))\n# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)\n#  define _Noreturn __declspec (noreturn)\n# else\n#  define _Noreturn\n# endif\n#endif\n])\n  AH_VERBATIM([isoc99_inline],\n[/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports\n   the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of\n   earlier versions), but does not display it by setting __GNUC_STDC_INLINE__.\n   __APPLE__ && __MACH__ test for Mac OS X.\n   __APPLE_CC__ tests for the Apple compiler and its version.\n   __STDC_VERSION__ tests for the C99 mode.  */\n#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__\n# define __GNUC_STDC_INLINE__ 1\n#endif])\n  AH_VERBATIM([attribute],\n[/* Attributes.  */\n#if (defined __has_attribute \\\n     && (!defined __clang_minor__ \\\n         || 3 < __clang_major__ + (5 <= __clang_minor__)))\n# define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__)\n#else\n# define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr\n# define _GL_ATTR_alloc_size _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_always_inline _GL_GNUC_PREREQ (3, 2)\n# define _GL_ATTR_artificial _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_cold _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_const _GL_GNUC_PREREQ (2, 95)\n# define _GL_ATTR_deprecated _GL_GNUC_PREREQ (3, 1)\n# define _GL_ATTR_diagnose_if 0\n# define _GL_ATTR_error _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_externally_visible _GL_GNUC_PREREQ (4, 1)\n# define _GL_ATTR_fallthrough _GL_GNUC_PREREQ (7, 0)\n# define _GL_ATTR_format _GL_GNUC_PREREQ (2, 7)\n# define _GL_ATTR_leaf _GL_GNUC_PREREQ (4, 6)\n# ifdef _ICC\n#  define _GL_ATTR_may_alias 0\n# else\n#  define _GL_ATTR_may_alias _GL_GNUC_PREREQ (3, 3)\n# endif\n# define _GL_ATTR_malloc _GL_GNUC_PREREQ (3, 0)\n# define _GL_ATTR_noinline _GL_GNUC_PREREQ (3, 1)\n# define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3)\n# define _GL_ATTR_nonstring _GL_GNUC_PREREQ (8, 0)\n# define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3)\n# define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7)\n# define _GL_ATTR_pure _GL_GNUC_PREREQ (2, 96)\n# define _GL_ATTR_returns_nonnull _GL_GNUC_PREREQ (4, 9)\n# define _GL_ATTR_sentinel _GL_GNUC_PREREQ (4, 0)\n# define _GL_ATTR_unused _GL_GNUC_PREREQ (2, 7)\n# define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4)\n#endif\n\n]dnl There is no _GL_ATTRIBUTE_ALIGNED; use stdalign's _Alignas instead.\n[\n#if _GL_HAS_ATTRIBUTE (alloc_size)\n# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))\n#else\n# define _GL_ATTRIBUTE_ALLOC_SIZE(args)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (always_inline)\n# define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))\n#else\n# define _GL_ATTRIBUTE_ALWAYS_INLINE\n#endif\n\n#if _GL_HAS_ATTRIBUTE (artificial)\n# define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__))\n#else\n# define _GL_ATTRIBUTE_ARTIFICIAL\n#endif\n\n/* Avoid __attribute__ ((cold)) on MinGW; see thread starting at\n   <https://lists.gnu.org/r/emacs-devel/2019-04/msg01152.html>.\n   Also, Oracle Studio 12.6 requires 'cold' not '__cold__'.  */\n#if _GL_HAS_ATTRIBUTE (cold) && !defined __MINGW32__\n# ifndef __SUNPRO_C\n#  define _GL_ATTRIBUTE_COLD __attribute__ ((__cold__))\n# else\n#  define _GL_ATTRIBUTE_COLD __attribute__ ((cold))\n# endif\n#else\n# define _GL_ATTRIBUTE_COLD\n#endif\n\n#if _GL_HAS_ATTRIBUTE (const)\n# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__))\n#else\n# define _GL_ATTRIBUTE_CONST\n#endif\n\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_DEPRECATED [[__deprecated__]]\n#elif _GL_HAS_ATTRIBUTE (deprecated)\n# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__))\n#else\n# define _GL_ATTRIBUTE_DEPRECATED\n#endif\n\n#if _GL_HAS_ATTRIBUTE (error)\n# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg)))\n# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg)))\n#elif _GL_HAS_ATTRIBUTE (diagnose_if)\n# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__diagnose_if__ (1, msg, \"error\")))\n# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__diagnose_if__ (1, msg, \"warning\")))\n#else\n# define _GL_ATTRIBUTE_ERROR(msg)\n# define _GL_ATTRIBUTE_WARNING(msg)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (externally_visible)\n# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE __attribute__ ((externally_visible))\n#else\n# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE\n#endif\n\n/* FALLTHROUGH is special, because it always expands to something.  */\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_FALLTHROUGH [[__fallthrough__]]\n#elif _GL_HAS_ATTRIBUTE (fallthrough)\n# define _GL_ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))\n#else\n# define _GL_ATTRIBUTE_FALLTHROUGH ((void) 0)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (format)\n# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))\n#else\n# define _GL_ATTRIBUTE_FORMAT(spec)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (leaf)\n# define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__))\n#else\n# define _GL_ATTRIBUTE_LEAF\n#endif\n\n/* Oracle Studio 12.6 mishandles may_alias despite __has_attribute OK.  */\n#if _GL_HAS_ATTRIBUTE (may_alias) && !defined __SUNPRO_C\n# define _GL_ATTRIBUTE_MAY_ALIAS __attribute__ ((__may_alias__))\n#else\n# define _GL_ATTRIBUTE_MAY_ALIAS\n#endif\n\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_MAYBE_UNUSED [[__maybe_unused__]]\n#elif _GL_HAS_ATTRIBUTE (unused)\n# define _GL_ATTRIBUTE_MAYBE_UNUSED __attribute__ ((__unused__))\n#else\n# define _GL_ATTRIBUTE_MAYBE_UNUSED\n#endif\n/* Earlier spellings of this macro.  */\n#define _GL_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED\n#define _UNUSED_PARAMETER_ _GL_ATTRIBUTE_MAYBE_UNUSED\n\n#if _GL_HAS_ATTRIBUTE (malloc)\n# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))\n#else\n# define _GL_ATTRIBUTE_MALLOC\n#endif\n\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_NODISCARD [[__nodiscard__]]\n#elif _GL_HAS_ATTRIBUTE (warn_unused_result)\n# define _GL_ATTRIBUTE_NODISCARD __attribute__ ((__warn_unused_result__))\n#else\n# define _GL_ATTRIBUTE_NODISCARD\n#endif\n\n#if _GL_HAS_ATTRIBUTE (noinline)\n# define _GL_ATTRIBUTE_NOINLINE __attribute__ ((__noinline__))\n#else\n# define _GL_ATTRIBUTE_NOINLINE\n#endif\n\n#if _GL_HAS_ATTRIBUTE (nonnull)\n# define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args))\n#else\n# define _GL_ATTRIBUTE_NONNULL(args)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (nonstring)\n# define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__))\n#else\n# define _GL_ATTRIBUTE_NONSTRING\n#endif\n\n/* There is no _GL_ATTRIBUTE_NORETURN; use _Noreturn instead.  */\n\n#if _GL_HAS_ATTRIBUTE (nothrow) && !defined __cplusplus\n# define _GL_ATTRIBUTE_NOTHROW __attribute__ ((__nothrow__))\n#else\n# define _GL_ATTRIBUTE_NOTHROW\n#endif\n\n#if _GL_HAS_ATTRIBUTE (packed)\n# define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__))\n#else\n# define _GL_ATTRIBUTE_PACKED\n#endif\n\n#if _GL_HAS_ATTRIBUTE (pure)\n# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))\n#else\n# define _GL_ATTRIBUTE_PURE\n#endif\n\n#if _GL_HAS_ATTRIBUTE (returns_nonnull)\n# define _GL_ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__))\n#else\n# define _GL_ATTRIBUTE_RETURNS_NONNULL\n#endif\n\n#if _GL_HAS_ATTRIBUTE (sentinel)\n# define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos))\n#else\n# define _GL_ATTRIBUTE_SENTINEL(pos)\n#endif\n\n]dnl There is no _GL_ATTRIBUTE_VISIBILITY; see m4/visibility.m4 instead.\n[\n/* To support C++ as well as C, use _GL_UNUSED_LABEL with trailing ';'.  */\n#if !defined __cplusplus || _GL_GNUC_PREREQ (4, 5)\n# define _GL_UNUSED_LABEL _GL_ATTRIBUTE_MAYBE_UNUSED\n#else\n# define _GL_UNUSED_LABEL\n#endif\n])\n  AH_VERBATIM([async_safe],\n[/* The _GL_ASYNC_SAFE marker should be attached to functions that are\n   signal handlers (for signals other than SIGABRT, SIGPIPE) or can be\n   invoked from such signal handlers.  Such functions have some restrictions:\n     * All functions that it calls should be marked _GL_ASYNC_SAFE as well,\n       or should be listed as async-signal-safe in POSIX\n       <https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04>\n       section 2.4.3.  Note that malloc(), sprintf(), and fwrite(), in\n       particular, are NOT async-signal-safe.\n     * All memory locations (variables and struct fields) that these functions\n       access must be marked 'volatile'.  This holds for both read and write\n       accesses.  Otherwise the compiler might optimize away stores to and\n       reads from such locations that occur in the program, depending on its\n       data flow analysis.  For example, when the program contains a loop\n       that is intended to inspect a variable set from within a signal handler\n           while (!signal_occurred)\n             ;\n       the compiler is allowed to transform this into an endless loop if the\n       variable 'signal_occurred' is not declared 'volatile'.\n   Additionally, recall that:\n     * A signal handler should not modify errno (except if it is a handler\n       for a fatal signal and ends by raising the same signal again, thus\n       provoking the termination of the process).  If it invokes a function\n       that may clobber errno, it needs to save and restore the value of\n       errno.  */\n#define _GL_ASYNC_SAFE\n])\n  AH_VERBATIM([micro_optimizations],\n[/* _GL_CMP (n1, n2) performs a three-valued comparison on n1 vs. n2, where\n   n1 and n2 are expressions without side effects, that evaluate to real\n   numbers (excluding NaN).\n   It returns\n     1  if n1 > n2\n     0  if n1 == n2\n     -1 if n1 < n2\n   The naïve code   (n1 > n2 ? 1 : n1 < n2 ? -1 : 0)  produces a conditional\n   jump with nearly all GCC versions up to GCC 10.\n   This variant     (n1 < n2 ? -1 : n1 > n2)  produces a conditional with many\n   GCC versions up to GCC 9.\n   The better code  (n1 > n2) - (n1 < n2)  from Hacker's Delight § 2-9\n   avoids conditional jumps in all GCC versions >= 3.4.  */\n#define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2)))\n])\n  dnl Hint which direction to take regarding cross-compilation guesses:\n  dnl When a user installs a program on a platform they are not intimately\n  dnl familiar with, --enable-cross-guesses=conservative is the appropriate\n  dnl choice.  It implements the \"If we don't know, assume the worst\" principle.\n  dnl However, when an operating system developer (on a platform which is not\n  dnl yet known to gnulib) builds packages for their platform, they want to\n  dnl expose, not hide, possible platform bugs; in this case,\n  dnl --enable-cross-guesses=risky is the appropriate choice.\n  dnl Sets the variables\n  dnl gl_cross_guess_normal    (to be used when 'yes' is good and 'no' is bad),\n  dnl gl_cross_guess_inverted  (to be used when 'no' is good and 'yes' is bad).\n  AC_ARG_ENABLE([cross-guesses],\n    [AS_HELP_STRING([--enable-cross-guesses={conservative|risky}],\n       [specify policy for cross-compilation guesses])],\n    [if test \"x$enableval\" != xconservative && test \"x$enableval\" != xrisky; then\n       AC_MSG_WARN([invalid argument supplied to --enable-cross-guesses])\n       enableval=conservative\n     fi\n     gl_cross_guesses=\"$enableval\"],\n    [gl_cross_guesses=conservative])\n  if test $gl_cross_guesses = risky; then\n    gl_cross_guess_normal=\"guessing yes\"\n    gl_cross_guess_inverted=\"guessing no\"\n  else\n    gl_cross_guess_normal=\"guessing no\"\n    gl_cross_guess_inverted=\"guessing yes\"\n  fi\n  dnl Preparation for running test programs:\n  dnl Tell glibc to write diagnostics from -D_FORTIFY_SOURCE=2 to stderr, not\n  dnl to /dev/tty, so they can be redirected to log files.  Such diagnostics\n  dnl arise e.g., in the macros gl_PRINTF_DIRECTIVE_N, gl_SNPRINTF_DIRECTIVE_N.\n  LIBC_FATAL_STDERR_=1\n  export LIBC_FATAL_STDERR_\n])\n\n# gl_MODULE_INDICATOR_INIT_VARIABLE([variablename])\n# gl_MODULE_INDICATOR_INIT_VARIABLE([variablename], [initialvalue])\n# initializes the shell variable that indicates the presence of the given module\n# as a C preprocessor expression.\nAC_DEFUN([gl_MODULE_INDICATOR_INIT_VARIABLE],\n[\n  GL_MODULE_INDICATOR_PREFIX[]_[$1]=m4_if([$2], , [0], [$2])\n  AC_SUBST(GL_MODULE_INDICATOR_PREFIX[]_[$1])\n])\n\n# gl_MODULE_INDICATOR_CONDITION\n# expands to a C preprocessor expression that evaluates to 1 or 0, depending\n# whether a gnulib module that has been requested shall be considered present\n# or not.\nm4_define([gl_MODULE_INDICATOR_CONDITION], [1])\n\n# gl_MODULE_INDICATOR_SET_VARIABLE([modulename])\n# sets the shell variable that indicates the presence of the given module to\n# a C preprocessor expression that will evaluate to 1.\nAC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE],\n[\n  gl_MODULE_INDICATOR_SET_VARIABLE_AUX(\n    [GL_MODULE_INDICATOR_PREFIX[]_GNULIB_[]m4_translit([[$1]],\n                                                       [abcdefghijklmnopqrstuvwxyz./-],\n                                                       [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])],\n    [gl_MODULE_INDICATOR_CONDITION])\n])\n\n# gl_MODULE_INDICATOR_SET_VARIABLE_AUX([variable])\n# modifies the shell variable to include the gl_MODULE_INDICATOR_CONDITION.\n# The shell variable's value is a C preprocessor expression that evaluates\n# to 0 or 1.\nAC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX],\n[\n  m4_if(m4_defn([gl_MODULE_INDICATOR_CONDITION]), [1],\n    [\n     dnl Simplify the expression VALUE || 1 to 1.\n     $1=1\n    ],\n    [gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([$1],\n                                             [gl_MODULE_INDICATOR_CONDITION])])\n])\n\n# gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([variable], [condition])\n# modifies the shell variable to include the given condition.  The shell\n# variable's value is a C preprocessor expression that evaluates to 0 or 1.\nAC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR],\n[\n  dnl Simplify the expression 1 || CONDITION to 1.\n  if test \"$[]$1\" != 1; then\n    dnl Simplify the expression 0 || CONDITION to CONDITION.\n    if test \"$[]$1\" = 0; then\n      $1=$2\n    else\n      $1=\"($[]$1 || $2)\"\n    fi\n  fi\n])\n\n# gl_MODULE_INDICATOR([modulename])\n# defines a C macro indicating the presence of the given module\n# in a location where it can be used.\n#                                             |  Value  |   Value   |\n#                                             | in lib/ | in tests/ |\n# --------------------------------------------+---------+-----------+\n# Module present among main modules:          |    1    |     1     |\n# --------------------------------------------+---------+-----------+\n# Module present among tests-related modules: |    0    |     1     |\n# --------------------------------------------+---------+-----------+\n# Module not present at all:                  |    0    |     0     |\n# --------------------------------------------+---------+-----------+\nAC_DEFUN([gl_MODULE_INDICATOR],\n[\n  AC_DEFINE_UNQUOTED([GNULIB_]m4_translit([[$1]],\n      [abcdefghijklmnopqrstuvwxyz./-],\n      [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]),\n    [gl_MODULE_INDICATOR_CONDITION],\n    [Define to a C preprocessor expression that evaluates to 1 or 0,\n     depending whether the gnulib module $1 shall be considered present.])\n])\n\n# gl_MODULE_INDICATOR_FOR_TESTS([modulename])\n# defines a C macro indicating the presence of the given module\n# in lib or tests. This is useful to determine whether the module\n# should be tested.\n#                                             |  Value  |   Value   |\n#                                             | in lib/ | in tests/ |\n# --------------------------------------------+---------+-----------+\n# Module present among main modules:          |    1    |     1     |\n# --------------------------------------------+---------+-----------+\n# Module present among tests-related modules: |    1    |     1     |\n# --------------------------------------------+---------+-----------+\n# Module not present at all:                  |    0    |     0     |\n# --------------------------------------------+---------+-----------+\nAC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS],\n[\n  AC_DEFINE([GNULIB_TEST_]m4_translit([[$1]],\n      [abcdefghijklmnopqrstuvwxyz./-],\n      [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]), [1],\n    [Define to 1 when the gnulib module $1 should be tested.])\n])\n\n# gl_ASSERT_NO_GNULIB_POSIXCHECK\n# asserts that there will never be a need to #define GNULIB_POSIXCHECK.\n# and thereby enables an optimization of configure and config.h.\n# Used by Emacs.\nAC_DEFUN([gl_ASSERT_NO_GNULIB_POSIXCHECK],\n[\n  dnl Override gl_WARN_ON_USE_PREPARE.\n  dnl But hide this definition from 'aclocal'.\n  AC_DEFUN([gl_W][ARN_ON_USE_PREPARE], [])\n])\n\n# gl_ASSERT_NO_GNULIB_TESTS\n# asserts that there will be no gnulib tests in the scope of the configure.ac\n# and thereby enables an optimization of config.h.\n# Used by Emacs.\nAC_DEFUN([gl_ASSERT_NO_GNULIB_TESTS],\n[\n  dnl Override gl_MODULE_INDICATOR_FOR_TESTS.\n  AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], [])\n])\n\n# Test whether <features.h> exists.\n# Set HAVE_FEATURES_H.\nAC_DEFUN([gl_FEATURES_H],\n[\n  AC_CHECK_HEADERS_ONCE([features.h])\n  if test $ac_cv_header_features_h = yes; then\n    HAVE_FEATURES_H=1\n  else\n    HAVE_FEATURES_H=0\n  fi\n  AC_SUBST([HAVE_FEATURES_H])\n])\n\n# gl_PROG_CC_C99\n# Modifies the value of the shell variable CC in an attempt to make $CC\n# understand ISO C99 source code.\nAC_DEFUN([gl_PROG_CC_C99],\n[\n  dnl Just use AC_PROG_CC_C99.\n  dnl When AC_PROG_CC_C99 and AC_PROG_CC_STDC are used together, the substituted\n  dnl value of CC will contain the C99 enabling options twice. But this is only\n  dnl a cosmetic problem.\n  dnl With Autoconf >= 2.70, use AC_PROG_CC since it implies AC_PROG_CC_C99;\n  dnl this avoids a \"warning: The macro `AC_PROG_CC_C99' is obsolete.\"\n  m4_version_prereq([2.70],\n    [AC_REQUIRE([AC_PROG_CC])],\n    [AC_REQUIRE([AC_PROG_CC_C99])])\n])\n\n# gl_PROG_AR_RANLIB\n# Determines the values for AR, ARFLAGS, RANLIB that fit with the compiler.\n# The user can set the variables AR, ARFLAGS, RANLIB if he wants to override\n# the values.\nAC_DEFUN([gl_PROG_AR_RANLIB],\n[\n  dnl Minix 3 comes with two toolchains: The Amsterdam Compiler Kit compiler\n  dnl as \"cc\", and GCC as \"gcc\". They have different object file formats and\n  dnl library formats. In particular, the GNU binutils programs ar and ranlib\n  dnl produce libraries that work only with gcc, not with cc.\n  AC_REQUIRE([AC_PROG_CC])\n  dnl The '][' hides this use from 'aclocal'.\n  AC_BEFORE([$0], [A][M_PROG_AR])\n  AC_CACHE_CHECK([for Minix Amsterdam compiler], [gl_cv_c_amsterdam_compiler],\n    [\n      AC_EGREP_CPP([Amsterdam],\n        [\n#ifdef __ACK__\nAmsterdam\n#endif\n        ],\n        [gl_cv_c_amsterdam_compiler=yes],\n        [gl_cv_c_amsterdam_compiler=no])\n    ])\n\n  dnl Don't compete with AM_PROG_AR's decision about AR/ARFLAGS if we are not\n  dnl building with __ACK__.\n  if test $gl_cv_c_amsterdam_compiler = yes; then\n    if test -z \"$AR\"; then\n      AR='cc -c.a'\n    fi\n    if test -z \"$ARFLAGS\"; then\n      ARFLAGS='-o'\n    fi\n  else\n    dnl AM_PROG_AR was added in automake v1.11.2.  AM_PROG_AR does not AC_SUBST\n    dnl ARFLAGS variable (it is filed into Makefile.in directly by automake\n    dnl script on-demand, if not specified by ./configure of course).\n    dnl Don't AC_REQUIRE the AM_PROG_AR otherwise the code for __ACK__ above\n    dnl will be ignored.  Also, pay attention to call AM_PROG_AR in else block\n    dnl because AM_PROG_AR is written so it could re-set AR variable even for\n    dnl __ACK__.  It may seem like its easier to avoid calling the macro here,\n    dnl but we need to AC_SUBST both AR/ARFLAGS (thus those must have some good\n    dnl default value and automake should usually know them).\n    dnl\n    dnl The '][' hides this use from 'aclocal'.\n    m4_ifdef([A][M_PROG_AR], [A][M_PROG_AR], [:])\n  fi\n\n  dnl In case the code above has not helped with setting AR/ARFLAGS, use\n  dnl Automake-documented default values for AR and ARFLAGS, but prefer\n  dnl ${host}-ar over ar (useful for cross-compiling).\n  AC_CHECK_TOOL([AR], [ar], [ar])\n  if test -z \"$ARFLAGS\"; then\n    ARFLAGS='cr'\n  fi\n\n  AC_SUBST([AR])\n  AC_SUBST([ARFLAGS])\n  if test -z \"$RANLIB\"; then\n    if test $gl_cv_c_amsterdam_compiler = yes; then\n      RANLIB=':'\n    else\n      dnl Use the ranlib program if it is available.\n      AC_PROG_RANLIB\n    fi\n  fi\n  AC_SUBST([RANLIB])\n])\n\n# AC_C_RESTRICT\n# This definition is copied from post-2.70 Autoconf and overrides the\n# AC_C_RESTRICT macro from autoconf 2.60..2.70.\nm4_version_prereq([2.70.1], [], [\nAC_DEFUN([AC_C_RESTRICT],\n[AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict],\n  [ac_cv_c_restrict=no\n   # Put '__restrict__' first, to avoid problems with glibc and non-GCC; see:\n   # https://lists.gnu.org/archive/html/bug-autoconf/2016-02/msg00006.html\n   # Put 'restrict' last, because C++ lacks it.\n   for ac_kw in __restrict__ __restrict _Restrict restrict; do\n     AC_COMPILE_IFELSE(\n      [AC_LANG_PROGRAM(\n         [[typedef int *int_ptr;\n           int foo (int_ptr $ac_kw ip) { return ip[0]; }\n           int bar (int [$ac_kw]); /* Catch GCC bug 14050.  */\n           int bar (int ip[$ac_kw]) { return ip[0]; }\n         ]],\n         [[int s[1];\n           int *$ac_kw t = s;\n           t[0] = 0;\n           return foo (t) + bar (t);\n         ]])],\n      [ac_cv_c_restrict=$ac_kw])\n     test \"$ac_cv_c_restrict\" != no && break\n   done\n  ])\n AH_VERBATIM([restrict],\n[/* Define to the equivalent of the C99 'restrict' keyword, or to\n   nothing if this is not supported.  Do not define if restrict is\n   supported only directly.  */\n#undef restrict\n/* Work around a bug in older versions of Sun C++, which did not\n   #define __restrict__ or support _Restrict or __restrict__\n   even though the corresponding Sun C compiler ended up with\n   \"#define restrict _Restrict\" or \"#define restrict __restrict__\"\n   in the previous line.  This workaround can be removed once\n   we assume Oracle Developer Studio 12.5 (2016) or later.  */\n#if defined __SUNPRO_CC && !defined __RESTRICT && !defined __restrict__\n# define _Restrict\n# define __restrict__\n#endif])\n case $ac_cv_c_restrict in\n   restrict) ;;\n   no) AC_DEFINE([restrict], []) ;;\n   *)  AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;;\n esac\n])# AC_C_RESTRICT\n])\n\n# gl_BIGENDIAN\n# is like AC_C_BIGENDIAN, except that it can be AC_REQUIREd.\n# Note that AC_REQUIRE([AC_C_BIGENDIAN]) does not work reliably because some\n# macros invoke AC_C_BIGENDIAN with arguments.\nAC_DEFUN([gl_BIGENDIAN],\n[\n  AC_C_BIGENDIAN\n])\n\n# A temporary file descriptor.\n# Must be less than 10, because dash 0.5.8 does not support redirections\n# with multi-digit file descriptors.\nm4_define([GL_TMP_FD], 9)\n\n# gl_SILENT(command)\n# executes command, but without the normal configure output.\n# This is useful when you want to invoke AC_CACHE_CHECK (or AC_CHECK_FUNC etc.)\n# inside another AC_CACHE_CHECK.\nAC_DEFUN([gl_SILENT],\n[\n  exec GL_TMP_FD>&AS_MESSAGE_FD AS_MESSAGE_FD>/dev/null\n  $1\n  exec AS_MESSAGE_FD>&GL_TMP_FD GL_TMP_FD>&-\n])\n\n# gl_CACHE_VAL_SILENT(cache-id, command-to-set-it)\n# is like AC_CACHE_VAL(cache-id, command-to-set-it), except that it does not\n# output a spurious \"(cached)\" mark in the midst of other configure output.\n# This macro should be used instead of AC_CACHE_VAL when it is not surrounded\n# by an AC_MSG_CHECKING/AC_MSG_RESULT pair.\nAC_DEFUN([gl_CACHE_VAL_SILENT],\n[\n  gl_SILENT([\n    AC_CACHE_VAL([$1], [$2])\n  ])\n])\n\n# gl_CC_ALLOW_WARNINGS\n# sets and substitutes a variable GL_CFLAG_ALLOW_WARNINGS, to a $(CC) option\n# that reverts a preceding '-Werror' option, if available.\n# This is expected to be '-Wno-error' on gcc, clang (except clang/MSVC), xlclang\n# and empty otherwise.\nAC_DEFUN([gl_CC_ALLOW_WARNINGS],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  AC_CACHE_CHECK([for C compiler option to allow warnings],\n    [gl_cv_cc_wallow],\n    [rm -f conftest*\n     echo 'int dummy;' > conftest.c\n     AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c 2>conftest1.err]) >/dev/null\n     AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -Wno-error -c conftest.c 2>conftest2.err]) >/dev/null\n     dnl Test the number of error output lines, because AIX xlc accepts the\n     dnl option '-Wno-error', just to produce a warning\n     dnl \"Option -Wno-error was incorrectly specified. The option will be ignored.\"\n     dnl afterwards.\n     if test $? = 0 && test `wc -l < conftest1.err` = `wc -l < conftest2.err`; then\n       gl_cv_cc_wallow='-Wno-error'\n     else\n       gl_cv_cc_wallow=none\n     fi\n     rm -f conftest*\n    ])\n  case \"$gl_cv_cc_wallow\" in\n    none) GL_CFLAG_ALLOW_WARNINGS='' ;;\n    *)    GL_CFLAG_ALLOW_WARNINGS=\"$gl_cv_cc_wallow\" ;;\n  esac\n  AC_SUBST([GL_CFLAG_ALLOW_WARNINGS])\n])\n\n# gl_CXX_ALLOW_WARNINGS\n# sets and substitutes a variable GL_CXXFLAG_ALLOW_WARNINGS, to a $(CC) option\n# that reverts a preceding '-Werror' option, if available.\nAC_DEFUN([gl_CXX_ALLOW_WARNINGS],\n[\n  dnl Requires AC_PROG_CXX or gl_PROG_ANSI_CXX.\n  if test -n \"$CXX\" && test \"$CXX\" != no; then\n    AC_CACHE_CHECK([for C++ compiler option to allow warnings],\n      [gl_cv_cxx_wallow],\n      [rm -f conftest*\n       echo 'int dummy;' > conftest.cc\n       AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -c conftest.cc 2>conftest1.err]) >/dev/null\n       AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -Wno-error -c conftest.cc 2>conftest2.err]) >/dev/null\n       dnl Test the number of error output lines, because AIX xlC accepts the\n       dnl option '-Wno-error', just to produce a warning\n       dnl \"Option -Wno-error was incorrectly specified. The option will be ignored.\"\n       dnl afterwards.\n       if test $? = 0 && test `wc -l < conftest1.err` = `wc -l < conftest2.err`; then\n         gl_cv_cxx_wallow='-Wno-error'\n       else\n         gl_cv_cxx_wallow=none\n       fi\n       rm -f conftest*\n      ])\n    case \"$gl_cv_cxx_wallow\" in\n      none) GL_CXXFLAG_ALLOW_WARNINGS='' ;;\n      *)    GL_CXXFLAG_ALLOW_WARNINGS=\"$gl_cv_cxx_wallow\" ;;\n    esac\n  else\n    GL_CXXFLAG_ALLOW_WARNINGS=''\n  fi\n  AC_SUBST([GL_CXXFLAG_ALLOW_WARNINGS])\n])\n\ndnl Expands to some code for use in .c programs that, on native Windows, defines\ndnl the Microsoft deprecated alias function names to the underscore-prefixed\ndnl actual function names. With this macro, these function names are available\ndnl without linking with '-loldnames' and without generating warnings.\ndnl Usage: Use it after all system header files are included.\ndnl          #include <...>\ndnl          #include <...>\ndnl          ]GL_MDA_DEFINES[\ndnl          ...\nAC_DEFUN([GL_MDA_DEFINES],[\nAC_REQUIRE([_GL_MDA_DEFINES])\n[$gl_mda_defines]\n])\nAC_DEFUN([_GL_MDA_DEFINES],\n[gl_mda_defines='\n#if defined _WIN32 && !defined __CYGWIN__\n#define access    _access\n#define chdir     _chdir\n#define chmod     _chmod\n#define close     _close\n#define creat     _creat\n#define dup       _dup\n#define dup2      _dup2\n#define ecvt      _ecvt\n#define execl     _execl\n#define execle    _execle\n#define execlp    _execlp\n#define execv     _execv\n#define execve    _execve\n#define execvp    _execvp\n#define execvpe   _execvpe\n#define fcloseall _fcloseall\n#define fcvt      _fcvt\n#define fdopen    _fdopen\n#define fileno    _fileno\n#define gcvt      _gcvt\n#define getcwd    _getcwd\n#define getpid    _getpid\n#define getw      _getw\n#define isatty    _isatty\n#define j0        _j0\n#define j1        _j1\n#define jn        _jn\n#define lfind     _lfind\n#define lsearch   _lsearch\n#define lseek     _lseek\n#define memccpy   _memccpy\n#define mkdir     _mkdir\n#define mktemp    _mktemp\n#define open      _open\n#define putenv    _putenv\n#define putw      _putw\n#define read      _read\n#define rmdir     _rmdir\n#define strdup    _strdup\n#define swab      _swab\n#define tempnam   _tempnam\n#define tzset     _tzset\n#define umask     _umask\n#define unlink    _unlink\n#define utime     _utime\n#define wcsdup    _wcsdup\n#define write     _write\n#define y0        _y0\n#define y1        _y1\n#define yn        _yn\n#endif\n'\n])\n"
  },
  {
    "path": "m4/gnulib-comp.m4",
    "content": "# DO NOT EDIT! GENERATED AUTOMATICALLY!\n# Copyright (C) 2002-2021 Free Software Foundation, Inc.\n#\n# This file is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 3 of the License, or\n# (at your option) any later version.\n#\n# This file is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this file.  If not, see <https://www.gnu.org/licenses/>.\n#\n# As a special exception to the GNU General Public License,\n# this file may be distributed as part of a program that\n# contains a configuration script generated by Autoconf, under\n# the same distribution terms as the rest of that program.\n#\n# Generated by gnulib-tool.\n#\n# This file represents the compiled summary of the specification in\n# gnulib-cache.m4. It lists the computed macro invocations that need\n# to be invoked from configure.ac.\n# In projects that use version control, this file can be treated like\n# other built files.\n\n\n# This macro should be invoked from ./configure.ac, in the section\n# \"Checks for programs\", right after AC_PROG_CC, and certainly before\n# any checks for libraries, header files, types and library functions.\nAC_DEFUN([gl_EARLY],\n[\n  m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace\n  m4_pattern_allow([^gl_ES$])dnl a valid locale name\n  m4_pattern_allow([^gl_LIBOBJS$])dnl a variable\n  m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable\n\n  # Pre-early section.\n  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])\n  AC_REQUIRE([gl_PROG_AR_RANLIB])\n\n  AC_REQUIRE([AM_PROG_CC_C_O])\n  # Code from module absolute-header:\n  # Code from module alloca-opt:\n  # Code from module attribute:\n  # Code from module btowc:\n  # Code from module builtin-expect:\n  # Code from module c99:\n  # Code from module ctype:\n  # Code from module dynarray:\n  # Code from module extensions:\n  # Code from module extern-inline:\n  # Code from module flexmember:\n  # Code from module fnmatch:\n  # Code from module fnmatch-h:\n  # Code from module hard-locale:\n  # Code from module idx:\n  # Code from module include_next:\n  # Code from module intprops:\n  # Code from module inttypes-incomplete:\n  # Code from module isblank:\n  # Code from module langinfo:\n  # Code from module libc-config:\n  # Code from module limits-h:\n  # Code from module localcharset:\n  # Code from module locale:\n  # Code from module localeconv:\n  # Code from module lock:\n  # Code from module mbrtowc:\n  # Code from module mbsinit:\n  # Code from module mbsrtowcs:\n  # Code from module mbtowc:\n  # Code from module memchr:\n  # Code from module mempcpy:\n  # Code from module multiarch:\n  # Code from module nl_langinfo:\n  # Code from module regex:\n  # Code from module setlocale-null:\n  # Code from module snippet/_Noreturn:\n  # Code from module snippet/arg-nonnull:\n  # Code from module snippet/c++defs:\n  # Code from module snippet/warn-on-use:\n  # Code from module ssize_t:\n  # Code from module std-gnu11:\n  # Code from module stdbool:\n  # Code from module stddef:\n  # Code from module stdint:\n  # Code from module stdlib:\n  # Code from module streq:\n  # Code from module string:\n  # Code from module strnlen:\n  # Code from module strnlen1:\n  # Code from module sys_types:\n  # Code from module threadlib:\n  gl_THREADLIB_EARLY\n  # Code from module unistd:\n  # Code from module verify:\n  # Code from module wchar:\n  # Code from module wcrtomb:\n  # Code from module wctype-h:\n  # Code from module windows-mutex:\n  # Code from module windows-once:\n  # Code from module windows-recmutex:\n  # Code from module windows-rwlock:\n  # Code from module wmemchr:\n  # Code from module wmempcpy:\n])\n\n# This macro should be invoked from ./configure.ac, in the section\n# \"Check for header files, types and library functions\".\nAC_DEFUN([gl_INIT],\n[\n  AM_CONDITIONAL([GL_COND_LIBTOOL], [false])\n  gl_cond_libtool=false\n  gl_libdeps=\n  gl_ltlibdeps=\n  gl_m4_base='m4'\n  m4_pushdef([AC_LIBOBJ], m4_defn([gl_LIBOBJ]))\n  m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gl_REPLACE_FUNCS]))\n  m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES]))\n  m4_pushdef([gl_LIBSOURCES_LIST], [])\n  m4_pushdef([gl_LIBSOURCES_DIR], [])\n  m4_pushdef([GL_MACRO_PREFIX], [gl])\n  m4_pushdef([GL_MODULE_INDICATOR_PREFIX], [GL])\n  gl_COMMON\n  gl_source_base='gnulib'\n  gl_FUNC_ALLOCA\n  gl_FUNC_BTOWC\n  if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then\n    AC_LIBOBJ([btowc])\n    gl_PREREQ_BTOWC\n  fi\n  gl_WCHAR_MODULE_INDICATOR([btowc])\n  gl___BUILTIN_EXPECT\n  gl_CTYPE_H\n  gl_CTYPE_H_REQUIRE_DEFAULTS\n  AC_PROG_MKDIR_P\n  AC_REQUIRE([gl_EXTERN_INLINE])\n  AC_C_FLEXIBLE_ARRAY_MEMBER\n  gl_FUNC_FNMATCH_POSIX\n  if test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; then\n    AC_LIBOBJ([fnmatch])\n    gl_PREREQ_FNMATCH\n  fi\n  gl_FNMATCH_MODULE_INDICATOR([fnmatch])\n  gl_FNMATCH_H\n  gl_FNMATCH_H_REQUIRE_DEFAULTS\n  AC_REQUIRE([gl_FUNC_SETLOCALE_NULL])\n  LIB_HARD_LOCALE=\"$LIB_SETLOCALE_NULL\"\n  AC_SUBST([LIB_HARD_LOCALE])\n  gl_INTTYPES_INCOMPLETE\n  gl_INTTYPES_H_REQUIRE_DEFAULTS\n  gl_FUNC_ISBLANK\n  if test $HAVE_ISBLANK = 0; then\n    AC_LIBOBJ([isblank])\n  fi\n  gl_MODULE_INDICATOR([isblank])\n  gl_CTYPE_MODULE_INDICATOR([isblank])\n  gl_LANGINFO_H\n  gl_LANGINFO_H_REQUIRE_DEFAULTS\n  gl___INLINE\n  gl_LIMITS_H\n  gl_LOCALCHARSET\n  dnl For backward compatibility. Some packages still use this.\n  LOCALCHARSET_TESTS_ENVIRONMENT=\n  AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT])\n  gl_LOCALE_H\n  gl_LOCALE_H_REQUIRE_DEFAULTS\n  gl_FUNC_LOCALECONV\n  if test $REPLACE_LOCALECONV = 1; then\n    AC_LIBOBJ([localeconv])\n    gl_PREREQ_LOCALECONV\n  fi\n  gl_LOCALE_MODULE_INDICATOR([localeconv])\n  gl_LOCK\n  gl_MODULE_INDICATOR([lock])\n  gl_FUNC_MBRTOWC\n  if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then\n    AC_LIBOBJ([mbrtowc])\n    if test $REPLACE_MBSTATE_T = 1; then\n      AC_LIBOBJ([lc-charset-dispatch])\n      AC_LIBOBJ([mbtowc-lock])\n      gl_PREREQ_MBTOWC_LOCK\n    fi\n    gl_PREREQ_MBRTOWC\n  fi\n  gl_WCHAR_MODULE_INDICATOR([mbrtowc])\n  gl_FUNC_MBSINIT\n  if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then\n    AC_LIBOBJ([mbsinit])\n    gl_PREREQ_MBSINIT\n  fi\n  gl_WCHAR_MODULE_INDICATOR([mbsinit])\n  gl_FUNC_MBSRTOWCS\n  if test $HAVE_MBSRTOWCS = 0 || test $REPLACE_MBSRTOWCS = 1; then\n    AC_LIBOBJ([mbsrtowcs])\n    AC_LIBOBJ([mbsrtowcs-state])\n    gl_PREREQ_MBSRTOWCS\n  fi\n  gl_WCHAR_MODULE_INDICATOR([mbsrtowcs])\n  gl_FUNC_MBTOWC\n  if test $HAVE_MBTOWC = 0 || test $REPLACE_MBTOWC = 1; then\n    AC_LIBOBJ([mbtowc])\n    gl_PREREQ_MBTOWC\n  fi\n  gl_STDLIB_MODULE_INDICATOR([mbtowc])\n  gl_FUNC_MEMCHR\n  if test $REPLACE_MEMCHR = 1; then\n    AC_LIBOBJ([memchr])\n    gl_PREREQ_MEMCHR\n  fi\n  gl_STRING_MODULE_INDICATOR([memchr])\n  gl_FUNC_MEMPCPY\n  if test $HAVE_MEMPCPY = 0; then\n    AC_LIBOBJ([mempcpy])\n    gl_PREREQ_MEMPCPY\n  fi\n  gl_STRING_MODULE_INDICATOR([mempcpy])\n  gl_MULTIARCH\n  gl_FUNC_NL_LANGINFO\n  if test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1; then\n    AC_LIBOBJ([nl_langinfo])\n  fi\n  if test $REPLACE_NL_LANGINFO = 1 && test $NL_LANGINFO_MTSAFE = 0; then\n    AC_LIBOBJ([nl_langinfo-lock])\n    gl_PREREQ_NL_LANGINFO_LOCK\n  fi\n  gl_LANGINFO_MODULE_INDICATOR([nl_langinfo])\n  gl_REGEX\n  if test $ac_use_included_regex = yes; then\n    AC_LIBOBJ([regex])\n    gl_PREREQ_REGEX\n  fi\n  gl_FUNC_SETLOCALE_NULL\n  if test $SETLOCALE_NULL_ALL_MTSAFE = 0 || test $SETLOCALE_NULL_ONE_MTSAFE = 0; then\n    AC_LIBOBJ([setlocale-lock])\n    gl_PREREQ_SETLOCALE_LOCK\n  fi\n  gl_LOCALE_MODULE_INDICATOR([setlocale_null])\n  gt_TYPE_SSIZE_T\n  AM_STDBOOL_H\n  gl_STDDEF_H\n  gl_STDDEF_H_REQUIRE_DEFAULTS\n  gl_STDINT_H\n  gl_STDLIB_H\n  gl_STDLIB_H_REQUIRE_DEFAULTS\n  gl_STRING_H\n  gl_STRING_H_REQUIRE_DEFAULTS\n  gl_FUNC_STRNLEN\n  if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then\n    AC_LIBOBJ([strnlen])\n    gl_PREREQ_STRNLEN\n  fi\n  gl_STRING_MODULE_INDICATOR([strnlen])\n  gl_SYS_TYPES_H\n  gl_SYS_TYPES_H_REQUIRE_DEFAULTS\n  AC_PROG_MKDIR_P\n  AC_REQUIRE([gl_THREADLIB])\n  gl_UNISTD_H\n  gl_UNISTD_H_REQUIRE_DEFAULTS\n  gl_WCHAR_H\n  gl_WCHAR_H_REQUIRE_DEFAULTS\n  gl_FUNC_WCRTOMB\n  if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then\n    AC_LIBOBJ([wcrtomb])\n    gl_PREREQ_WCRTOMB\n  fi\n  gl_WCHAR_MODULE_INDICATOR([wcrtomb])\n  gl_WCTYPE_H\n  gl_WCTYPE_H_REQUIRE_DEFAULTS\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  case \"$host_os\" in\n    mingw*)\n      AC_LIBOBJ([windows-mutex])\n      ;;\n  esac\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  case \"$host_os\" in\n    mingw*)\n      AC_LIBOBJ([windows-once])\n      ;;\n  esac\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  case \"$host_os\" in\n    mingw*)\n      AC_LIBOBJ([windows-recmutex])\n      ;;\n  esac\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  case \"$host_os\" in\n    mingw*)\n      AC_LIBOBJ([windows-rwlock])\n      ;;\n  esac\n  gl_FUNC_WMEMCHR\n  if test $HAVE_WMEMCHR = 0; then\n    AC_LIBOBJ([wmemchr])\n  fi\n  gl_WCHAR_MODULE_INDICATOR([wmemchr])\n  gl_FUNC_WMEMPCPY\n  if test $HAVE_WMEMPCPY = 0; then\n    AC_LIBOBJ([wmempcpy])\n  fi\n  gl_WCHAR_MODULE_INDICATOR([wmempcpy])\n  # End of code from modules\n  m4_ifval(gl_LIBSOURCES_LIST, [\n    m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ ||\n      for gl_file in ]gl_LIBSOURCES_LIST[ ; do\n        if test ! -r ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file ; then\n          echo \"missing file ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file\" >&2\n          exit 1\n        fi\n      done])dnl\n      m4_if(m4_sysval, [0], [],\n        [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])\n  ])\n  m4_popdef([GL_MODULE_INDICATOR_PREFIX])\n  m4_popdef([GL_MACRO_PREFIX])\n  m4_popdef([gl_LIBSOURCES_DIR])\n  m4_popdef([gl_LIBSOURCES_LIST])\n  m4_popdef([AC_LIBSOURCES])\n  m4_popdef([AC_REPLACE_FUNCS])\n  m4_popdef([AC_LIBOBJ])\n  AC_CONFIG_COMMANDS_PRE([\n    gl_libobjs=\n    gl_ltlibobjs=\n    if test -n \"$gl_LIBOBJS\"; then\n      # Remove the extension.\n      sed_drop_objext='s/\\.o$//;s/\\.obj$//'\n      for i in `for i in $gl_LIBOBJS; do echo \"$i\"; done | sed -e \"$sed_drop_objext\" | sort | uniq`; do\n        gl_libobjs=\"$gl_libobjs $i.$ac_objext\"\n        gl_ltlibobjs=\"$gl_ltlibobjs $i.lo\"\n      done\n    fi\n    AC_SUBST([gl_LIBOBJS], [$gl_libobjs])\n    AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs])\n  ])\n  gltests_libdeps=\n  gltests_ltlibdeps=\n  m4_pushdef([AC_LIBOBJ], m4_defn([gltests_LIBOBJ]))\n  m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gltests_REPLACE_FUNCS]))\n  m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES]))\n  m4_pushdef([gltests_LIBSOURCES_LIST], [])\n  m4_pushdef([gltests_LIBSOURCES_DIR], [])\n  m4_pushdef([GL_MACRO_PREFIX], [gltests])\n  m4_pushdef([GL_MODULE_INDICATOR_PREFIX], [GL])\n  gl_COMMON\n  gl_source_base='tests'\nchangequote(,)dnl\n  gltests_WITNESS=IN_`echo \"${PACKAGE-$PACKAGE_TARNAME}\" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS\nchangequote([, ])dnl\n  AC_SUBST([gltests_WITNESS])\n  gl_module_indicator_condition=$gltests_WITNESS\n  m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [$gl_module_indicator_condition])\n  m4_popdef([gl_MODULE_INDICATOR_CONDITION])\n  m4_ifval(gltests_LIBSOURCES_LIST, [\n    m4_syscmd([test ! -d ]m4_defn([gltests_LIBSOURCES_DIR])[ ||\n      for gl_file in ]gltests_LIBSOURCES_LIST[ ; do\n        if test ! -r ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file ; then\n          echo \"missing file ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file\" >&2\n          exit 1\n        fi\n      done])dnl\n      m4_if(m4_sysval, [0], [],\n        [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])\n  ])\n  m4_popdef([GL_MODULE_INDICATOR_PREFIX])\n  m4_popdef([GL_MACRO_PREFIX])\n  m4_popdef([gltests_LIBSOURCES_DIR])\n  m4_popdef([gltests_LIBSOURCES_LIST])\n  m4_popdef([AC_LIBSOURCES])\n  m4_popdef([AC_REPLACE_FUNCS])\n  m4_popdef([AC_LIBOBJ])\n  AC_CONFIG_COMMANDS_PRE([\n    gltests_libobjs=\n    gltests_ltlibobjs=\n    if test -n \"$gltests_LIBOBJS\"; then\n      # Remove the extension.\n      sed_drop_objext='s/\\.o$//;s/\\.obj$//'\n      for i in `for i in $gltests_LIBOBJS; do echo \"$i\"; done | sed -e \"$sed_drop_objext\" | sort | uniq`; do\n        gltests_libobjs=\"$gltests_libobjs $i.$ac_objext\"\n        gltests_ltlibobjs=\"$gltests_ltlibobjs $i.lo\"\n      done\n    fi\n    AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs])\n    AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs])\n  ])\n  LIBGNU_LIBDEPS=\"$gl_libdeps\"\n  AC_SUBST([LIBGNU_LIBDEPS])\n  LIBGNU_LTLIBDEPS=\"$gl_ltlibdeps\"\n  AC_SUBST([LIBGNU_LTLIBDEPS])\n])\n\n# Like AC_LIBOBJ, except that the module name goes\n# into gl_LIBOBJS instead of into LIBOBJS.\nAC_DEFUN([gl_LIBOBJ], [\n  AS_LITERAL_IF([$1], [gl_LIBSOURCES([$1.c])])dnl\n  gl_LIBOBJS=\"$gl_LIBOBJS $1.$ac_objext\"\n])\n\n# Like AC_REPLACE_FUNCS, except that the module name goes\n# into gl_LIBOBJS instead of into LIBOBJS.\nAC_DEFUN([gl_REPLACE_FUNCS], [\n  m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl\n  AC_CHECK_FUNCS([$1], , [gl_LIBOBJ($ac_func)])\n])\n\n# Like AC_LIBSOURCES, except the directory where the source file is\n# expected is derived from the gnulib-tool parameterization,\n# and alloca is special cased (for the alloca-opt module).\n# We could also entirely rely on EXTRA_lib..._SOURCES.\nAC_DEFUN([gl_LIBSOURCES], [\n  m4_foreach([_gl_NAME], [$1], [\n    m4_if(_gl_NAME, [alloca.c], [], [\n      m4_define([gl_LIBSOURCES_DIR], [gnulib])\n      m4_append([gl_LIBSOURCES_LIST], _gl_NAME, [ ])\n    ])\n  ])\n])\n\n# Like AC_LIBOBJ, except that the module name goes\n# into gltests_LIBOBJS instead of into LIBOBJS.\nAC_DEFUN([gltests_LIBOBJ], [\n  AS_LITERAL_IF([$1], [gltests_LIBSOURCES([$1.c])])dnl\n  gltests_LIBOBJS=\"$gltests_LIBOBJS $1.$ac_objext\"\n])\n\n# Like AC_REPLACE_FUNCS, except that the module name goes\n# into gltests_LIBOBJS instead of into LIBOBJS.\nAC_DEFUN([gltests_REPLACE_FUNCS], [\n  m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl\n  AC_CHECK_FUNCS([$1], , [gltests_LIBOBJ($ac_func)])\n])\n\n# Like AC_LIBSOURCES, except the directory where the source file is\n# expected is derived from the gnulib-tool parameterization,\n# and alloca is special cased (for the alloca-opt module).\n# We could also entirely rely on EXTRA_lib..._SOURCES.\nAC_DEFUN([gltests_LIBSOURCES], [\n  m4_foreach([_gl_NAME], [$1], [\n    m4_if(_gl_NAME, [alloca.c], [], [\n      m4_define([gltests_LIBSOURCES_DIR], [tests])\n      m4_append([gltests_LIBSOURCES_LIST], _gl_NAME, [ ])\n    ])\n  ])\n])\n\n# This macro records the list of files which have been installed by\n# gnulib-tool and may be removed by future gnulib-tool invocations.\nAC_DEFUN([gl_FILE_LIST], [\n  lib/_Noreturn.h\n  lib/alloca.in.h\n  lib/arg-nonnull.h\n  lib/attribute.h\n  lib/btowc.c\n  lib/c++defs.h\n  lib/cdefs.h\n  lib/ctype.in.h\n  lib/dynarray.h\n  lib/flexmember.h\n  lib/fnmatch.c\n  lib/fnmatch.in.h\n  lib/fnmatch_loop.c\n  lib/glthread/lock.c\n  lib/glthread/lock.h\n  lib/glthread/threadlib.c\n  lib/hard-locale.c\n  lib/hard-locale.h\n  lib/idx.h\n  lib/intprops.h\n  lib/inttypes.in.h\n  lib/isblank.c\n  lib/langinfo.in.h\n  lib/lc-charset-dispatch.c\n  lib/lc-charset-dispatch.h\n  lib/libc-config.h\n  lib/limits.in.h\n  lib/localcharset.c\n  lib/localcharset.h\n  lib/locale.in.h\n  lib/localeconv.c\n  lib/malloc/dynarray-skeleton.c\n  lib/malloc/dynarray.h\n  lib/malloc/dynarray_at_failure.c\n  lib/malloc/dynarray_emplace_enlarge.c\n  lib/malloc/dynarray_finalize.c\n  lib/malloc/dynarray_resize.c\n  lib/malloc/dynarray_resize_clear.c\n  lib/mbrtowc-impl-utf8.h\n  lib/mbrtowc-impl.h\n  lib/mbrtowc.c\n  lib/mbsinit.c\n  lib/mbsrtowcs-impl.h\n  lib/mbsrtowcs-state.c\n  lib/mbsrtowcs.c\n  lib/mbtowc-impl.h\n  lib/mbtowc-lock.c\n  lib/mbtowc-lock.h\n  lib/mbtowc.c\n  lib/memchr.c\n  lib/memchr.valgrind\n  lib/mempcpy.c\n  lib/nl_langinfo-lock.c\n  lib/nl_langinfo.c\n  lib/regcomp.c\n  lib/regex.c\n  lib/regex.h\n  lib/regex_internal.c\n  lib/regex_internal.h\n  lib/regexec.c\n  lib/setlocale-lock.c\n  lib/setlocale_null.c\n  lib/setlocale_null.h\n  lib/stdbool.in.h\n  lib/stddef.in.h\n  lib/stdint.in.h\n  lib/stdlib.in.h\n  lib/streq.h\n  lib/string.in.h\n  lib/strnlen.c\n  lib/strnlen1.c\n  lib/strnlen1.h\n  lib/sys_types.in.h\n  lib/unistd.c\n  lib/unistd.in.h\n  lib/verify.h\n  lib/warn-on-use.h\n  lib/wchar.in.h\n  lib/wcrtomb.c\n  lib/wctype-h.c\n  lib/wctype.in.h\n  lib/windows-initguard.h\n  lib/windows-mutex.c\n  lib/windows-mutex.h\n  lib/windows-once.c\n  lib/windows-once.h\n  lib/windows-recmutex.c\n  lib/windows-recmutex.h\n  lib/windows-rwlock.c\n  lib/windows-rwlock.h\n  lib/wmemchr-impl.h\n  lib/wmemchr.c\n  lib/wmempcpy.c\n  m4/00gnulib.m4\n  m4/__inline.m4\n  m4/absolute-header.m4\n  m4/alloca.m4\n  m4/btowc.m4\n  m4/builtin-expect.m4\n  m4/codeset.m4\n  m4/ctype_h.m4\n  m4/eealloc.m4\n  m4/extensions.m4\n  m4/extern-inline.m4\n  m4/flexmember.m4\n  m4/fnmatch.m4\n  m4/fnmatch_h.m4\n  m4/gnulib-common.m4\n  m4/include_next.m4\n  m4/inttypes.m4\n  m4/isblank.m4\n  m4/langinfo_h.m4\n  m4/limits-h.m4\n  m4/localcharset.m4\n  m4/locale-fr.m4\n  m4/locale-ja.m4\n  m4/locale-zh.m4\n  m4/locale_h.m4\n  m4/localeconv.m4\n  m4/lock.m4\n  m4/mbrtowc.m4\n  m4/mbsinit.m4\n  m4/mbsrtowcs.m4\n  m4/mbstate_t.m4\n  m4/mbtowc.m4\n  m4/memchr.m4\n  m4/mempcpy.m4\n  m4/mmap-anon.m4\n  m4/multiarch.m4\n  m4/nl_langinfo.m4\n  m4/off_t.m4\n  m4/pid_t.m4\n  m4/pthread_rwlock_rdlock.m4\n  m4/regex.m4\n  m4/setlocale_null.m4\n  m4/ssize_t.m4\n  m4/std-gnu11.m4\n  m4/stdbool.m4\n  m4/stddef_h.m4\n  m4/stdint.m4\n  m4/stdlib_h.m4\n  m4/string_h.m4\n  m4/strnlen.m4\n  m4/sys_types_h.m4\n  m4/threadlib.m4\n  m4/unistd_h.m4\n  m4/visibility.m4\n  m4/warn-on-use.m4\n  m4/wchar_h.m4\n  m4/wchar_t.m4\n  m4/wcrtomb.m4\n  m4/wctype_h.m4\n  m4/wint_t.m4\n  m4/wmemchr.m4\n  m4/wmempcpy.m4\n  m4/zzgnulib.m4\n])\n"
  },
  {
    "path": "m4/gnulib-tool.m4",
    "content": "# gnulib-tool.m4 serial 2\ndnl Copyright (C) 2004-2005, 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl The following macros need not be invoked explicitly.\ndnl Invoking them does nothing except to declare default arguments\ndnl for \"gnulib-tool --import\".\n\ndnl Usage: gl_LOCAL_DIR([DIR])\nAC_DEFUN([gl_LOCAL_DIR], [])\n\ndnl Usage: gl_MODULES([module1 module2 ...])\nAC_DEFUN([gl_MODULES], [])\n\ndnl Usage: gl_AVOID([module1 module2 ...])\nAC_DEFUN([gl_AVOID], [])\n\ndnl Usage: gl_SOURCE_BASE([DIR])\nAC_DEFUN([gl_SOURCE_BASE], [])\n\ndnl Usage: gl_M4_BASE([DIR])\nAC_DEFUN([gl_M4_BASE], [])\n\ndnl Usage: gl_PO_BASE([DIR])\nAC_DEFUN([gl_PO_BASE], [])\n\ndnl Usage: gl_DOC_BASE([DIR])\nAC_DEFUN([gl_DOC_BASE], [])\n\ndnl Usage: gl_TESTS_BASE([DIR])\nAC_DEFUN([gl_TESTS_BASE], [])\n\ndnl Usage: gl_WITH_TESTS\nAC_DEFUN([gl_WITH_TESTS], [])\n\ndnl Usage: gl_LIB([LIBNAME])\nAC_DEFUN([gl_LIB], [])\n\ndnl Usage: gl_LGPL or gl_LGPL([VERSION])\nAC_DEFUN([gl_LGPL], [])\n\ndnl Usage: gl_MAKEFILE_NAME([FILENAME])\nAC_DEFUN([gl_MAKEFILE_NAME], [])\n\ndnl Usage: gl_LIBTOOL\nAC_DEFUN([gl_LIBTOOL], [])\n\ndnl Usage: gl_MACRO_PREFIX([PREFIX])\nAC_DEFUN([gl_MACRO_PREFIX], [])\n\ndnl Usage: gl_PO_DOMAIN([DOMAIN])\nAC_DEFUN([gl_PO_DOMAIN], [])\n\ndnl Usage: gl_VC_FILES([BOOLEAN])\nAC_DEFUN([gl_VC_FILES], [])\n"
  },
  {
    "path": "m4/include_next.m4",
    "content": "# include_next.m4 serial 26\ndnl Copyright (C) 2006-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Paul Eggert and Derek Price.\n\ndnl Sets INCLUDE_NEXT, INCLUDE_NEXT_AS_FIRST_DIRECTIVE, PRAGMA_SYSTEM_HEADER,\ndnl and PRAGMA_COLUMNS.\ndnl\ndnl INCLUDE_NEXT expands to 'include_next' if the compiler supports it, or to\ndnl 'include' otherwise.\ndnl\ndnl INCLUDE_NEXT_AS_FIRST_DIRECTIVE expands to 'include_next' if the compiler\ndnl supports it in the special case that it is the first include directive in\ndnl the given file, or to 'include' otherwise.\ndnl\ndnl PRAGMA_SYSTEM_HEADER can be used in files that contain #include_next,\ndnl so as to avoid GCC warnings when the gcc option -pedantic is used.\ndnl '#pragma GCC system_header' has the same effect as if the file was found\ndnl through the include search path specified with '-isystem' options (as\ndnl opposed to the search path specified with '-I' options). Namely, gcc\ndnl does not warn about some things, and on some systems (Solaris and Interix)\ndnl __STDC__ evaluates to 0 instead of to 1. The latter is an undesired side\ndnl effect; we are therefore careful to use 'defined __STDC__' or '1' instead\ndnl of plain '__STDC__'.\ndnl\ndnl PRAGMA_COLUMNS can be used in files that override system header files, so\ndnl as to avoid compilation errors on HP NonStop systems when the gnulib file\ndnl is included by a system header file that does a \"#pragma COLUMNS 80\" (which\ndnl has the effect of truncating the lines of that file and all files that it\ndnl includes to 80 columns) and the gnulib file has lines longer than 80\ndnl columns.\n\nAC_DEFUN([gl_INCLUDE_NEXT],\n[\n  AC_LANG_PREPROC_REQUIRE()\n  AC_CACHE_CHECK([whether the preprocessor supports include_next],\n    [gl_cv_have_include_next],\n    [rm -rf conftestd1a conftestd1b conftestd2\n     mkdir conftestd1a conftestd1b conftestd2\n     dnl IBM C 9.0, 10.1 (original versions, prior to the 2009-01 updates) on\n     dnl AIX 6.1 support include_next when used as first preprocessor directive\n     dnl in a file, but not when preceded by another include directive. Check\n     dnl for this bug by including <stdio.h>.\n     dnl Additionally, with this same compiler, include_next is a no-op when\n     dnl used in a header file that was included by specifying its absolute\n     dnl file name. Despite these two bugs, include_next is used in the\n     dnl compiler's <math.h>. By virtue of the second bug, we need to use\n     dnl include_next as well in this case.\n     cat <<EOF > conftestd1a/conftest.h\n#define DEFINED_IN_CONFTESTD1\n#include_next <conftest.h>\n#ifdef DEFINED_IN_CONFTESTD2\nint foo;\n#else\n#error \"include_next doesn't work\"\n#endif\nEOF\n     cat <<EOF > conftestd1b/conftest.h\n#define DEFINED_IN_CONFTESTD1\n#include <stdio.h>\n#include_next <conftest.h>\n#ifdef DEFINED_IN_CONFTESTD2\nint foo;\n#else\n#error \"include_next doesn't work\"\n#endif\nEOF\n     cat <<EOF > conftestd2/conftest.h\n#ifndef DEFINED_IN_CONFTESTD1\n#error \"include_next test doesn't work\"\n#endif\n#define DEFINED_IN_CONFTESTD2\nEOF\n     gl_save_CPPFLAGS=\"$CPPFLAGS\"\n     CPPFLAGS=\"$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2\"\ndnl We intentionally avoid using AC_LANG_SOURCE here.\n     AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include <conftest.h>]],\n       [gl_cv_have_include_next=yes],\n       [CPPFLAGS=\"$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2\"\n        AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include <conftest.h>]],\n          [gl_cv_have_include_next=buggy],\n          [gl_cv_have_include_next=no])\n       ])\n     CPPFLAGS=\"$gl_save_CPPFLAGS\"\n     rm -rf conftestd1a conftestd1b conftestd2\n    ])\n  PRAGMA_SYSTEM_HEADER=\n  if test $gl_cv_have_include_next = yes; then\n    INCLUDE_NEXT=include_next\n    INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next\n    if test -n \"$GCC\"; then\n      PRAGMA_SYSTEM_HEADER='#pragma GCC system_header'\n    fi\n  else\n    if test $gl_cv_have_include_next = buggy; then\n      INCLUDE_NEXT=include\n      INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next\n    else\n      INCLUDE_NEXT=include\n      INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include\n    fi\n  fi\n  AC_SUBST([INCLUDE_NEXT])\n  AC_SUBST([INCLUDE_NEXT_AS_FIRST_DIRECTIVE])\n  AC_SUBST([PRAGMA_SYSTEM_HEADER])\n\n  dnl HP NonStop systems, which define __TANDEM, limit the line length\n  dnl after including some system header files.\n  AC_CACHE_CHECK([whether source code line length is unlimited],\n    [gl_cv_source_line_length_unlimited],\n    [AC_EGREP_CPP([choke me],\n       [\n#ifdef __TANDEM\nchoke me\n#endif\n       ],\n       [gl_cv_source_line_length_unlimited=no],\n       [gl_cv_source_line_length_unlimited=yes])\n    ])\n  if test $gl_cv_source_line_length_unlimited = no; then\n    PRAGMA_COLUMNS=\"#pragma COLUMNS 10000\"\n  else\n    PRAGMA_COLUMNS=\n  fi\n  AC_SUBST([PRAGMA_COLUMNS])\n])\n\n# gl_CHECK_NEXT_HEADERS(HEADER1 HEADER2 ...)\n# ------------------------------------------\n# For each arg foo.h, if #include_next works, define NEXT_FOO_H to be\n# '<foo.h>'; otherwise define it to be\n# '\"///usr/include/foo.h\"', or whatever other absolute file name is suitable.\n# Also, if #include_next works as first preprocessing directive in a file,\n# define NEXT_AS_FIRST_DIRECTIVE_FOO_H to be '<foo.h>'; otherwise define it to\n# be\n# '\"///usr/include/foo.h\"', or whatever other absolute file name is suitable.\n# That way, a header file with the following line:\n#       #@INCLUDE_NEXT@ @NEXT_FOO_H@\n# or\n#       #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_FOO_H@\n# behaves (after sed substitution) as if it contained\n#       #include_next <foo.h>\n# even if the compiler does not support include_next.\n# The three \"///\" are to pacify Sun C 5.8, which otherwise would say\n# \"warning: #include of /usr/include/... may be non-portable\".\n# Use '\"\"', not '<>', so that the /// cannot be confused with a C99 comment.\n# Note: This macro assumes that the header file is not empty after\n# preprocessing, i.e. it does not only define preprocessor macros but also\n# provides some type/enum definitions or function/variable declarations.\n#\n# This macro also checks whether each header exists, by invoking\n# AC_CHECK_HEADERS_ONCE or AC_CHECK_HEADERS on each argument.\nAC_DEFUN([gl_CHECK_NEXT_HEADERS],\n[\n  gl_NEXT_HEADERS_INTERNAL([$1], [check])\n])\n\n# gl_NEXT_HEADERS(HEADER1 HEADER2 ...)\n# ------------------------------------\n# Like gl_CHECK_NEXT_HEADERS, except do not check whether the headers exist.\n# This is suitable for headers like <stddef.h> that are standardized by C89\n# and therefore can be assumed to exist.\nAC_DEFUN([gl_NEXT_HEADERS],\n[\n  gl_NEXT_HEADERS_INTERNAL([$1], [assume])\n])\n\n# The guts of gl_CHECK_NEXT_HEADERS and gl_NEXT_HEADERS.\nAC_DEFUN([gl_NEXT_HEADERS_INTERNAL],\n[\n  AC_REQUIRE([gl_INCLUDE_NEXT])\n  AC_REQUIRE([AC_CANONICAL_HOST])\n\n  m4_if([$2], [check],\n    [AC_CHECK_HEADERS_ONCE([$1])\n    ])\n\n  m4_foreach_w([gl_HEADER_NAME], [$1],\n    [AS_VAR_PUSHDEF([gl_next_header],\n                    [gl_cv_next_]m4_defn([gl_HEADER_NAME]))\n     if test $gl_cv_have_include_next = yes; then\n       AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>'])\n     else\n       AC_CACHE_CHECK(\n         [absolute name of <]m4_defn([gl_HEADER_NAME])[>],\n         [gl_next_header],\n         [m4_if([$2], [check],\n            [AS_VAR_PUSHDEF([gl_header_exists],\n                            [ac_cv_header_]m4_defn([gl_HEADER_NAME]))\n             if test AS_VAR_GET([gl_header_exists]) = yes; then\n             AS_VAR_POPDEF([gl_header_exists])\n            ])\n           gl_ABSOLUTE_HEADER_ONE(gl_HEADER_NAME)\n           AS_VAR_COPY([gl_header], [gl_cv_absolute_]AS_TR_SH(gl_HEADER_NAME))\n           AS_VAR_SET([gl_next_header], ['\"'$gl_header'\"'])\n          m4_if([$2], [check],\n            [else\n               AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>'])\n             fi\n            ])\n         ])\n     fi\n     AC_SUBST(\n       AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])),\n       [AS_VAR_GET([gl_next_header])])\n     if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then\n       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'\n       gl_next_as_first_directive='<'gl_HEADER_NAME'>'\n     else\n       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'\n       gl_next_as_first_directive=AS_VAR_GET([gl_next_header])\n     fi\n     AC_SUBST(\n       AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])),\n       [$gl_next_as_first_directive])\n     AS_VAR_POPDEF([gl_next_header])])\n])\n\n# Autoconf 2.68 added warnings for our use of AC_COMPILE_IFELSE;\n# this fallback is safe for all earlier autoconf versions.\nm4_define_default([AC_LANG_DEFINES_PROVIDED])\n"
  },
  {
    "path": "m4/inttypes.m4",
    "content": "# inttypes.m4 serial 35\ndnl Copyright (C) 2006-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Derek Price, Bruno Haible.\ndnl Test whether <inttypes.h> is supported or must be substituted.\n\nAC_DEFUN_ONCE([gl_INTTYPES_H],\n[\n  AC_REQUIRE([gl_INTTYPES_INCOMPLETE])\n  gl_INTTYPES_PRI_SCN\n])\n\nAC_DEFUN_ONCE([gl_INTTYPES_INCOMPLETE],\n[\n  AC_REQUIRE([gl_STDINT_H])\n  AC_CHECK_HEADERS_ONCE([inttypes.h])\n\n  dnl Override <inttypes.h> always, so that the portability warnings work.\n  AC_REQUIRE([gl_INTTYPES_H_DEFAULTS])\n  gl_CHECK_NEXT_HEADERS([inttypes.h])\n\n  AC_REQUIRE([gl_MULTIARCH])\n\n  dnl Check for declarations of anything we want to poison if the\n  dnl corresponding gnulib module is not in use.\n  gl_WARN_ON_USE_PREPARE([[#include <inttypes.h>\n    ]], [imaxabs imaxdiv strtoimax strtoumax])\n\n  AC_REQUIRE([AC_C_RESTRICT])\n])\n\n# Ensure that the PRI* and SCN* macros are defined appropriately.\nAC_DEFUN([gl_INTTYPES_PRI_SCN],\n[\n  PRIPTR_PREFIX=\n  if test -n \"$STDINT_H\"; then\n    dnl Using the gnulib <stdint.h>. It defines intptr_t to 'long' or\n    dnl 'long long', depending on _WIN64.\n    AC_COMPILE_IFELSE(\n      [AC_LANG_PROGRAM([[\n         #ifdef _WIN64\n         LLP64\n         #endif\n         ]])\n      ],\n      [PRIPTR_PREFIX='\"l\"'],\n      [PRIPTR_PREFIX='\"ll\"'])\n  else\n    dnl Using the system's <stdint.h>.\n    for glpfx in '' l ll I64; do\n      case $glpfx in\n        '')  gltype1='int';;\n        l)   gltype1='long int';;\n        ll)  gltype1='long long int';;\n        I64) gltype1='__int64';;\n      esac\n      AC_COMPILE_IFELSE(\n        [AC_LANG_PROGRAM([[#include <stdint.h>\n           extern intptr_t foo;\n           extern $gltype1 foo;]])],\n        [PRIPTR_PREFIX='\"'$glpfx'\"'])\n      test -n \"$PRIPTR_PREFIX\" && break\n    done\n  fi\n  AC_SUBST([PRIPTR_PREFIX])\n\n  gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(\n    [INT32_MAX_LT_INTMAX_MAX],\n    [defined INT32_MAX && defined INTMAX_MAX],\n    [INT32_MAX < INTMAX_MAX],\n    [sizeof (int) < sizeof (long long int)])\n  if test $APPLE_UNIVERSAL_BUILD = 0; then\n    gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(\n      [INT64_MAX_EQ_LONG_MAX],\n      [defined INT64_MAX],\n      [INT64_MAX == LONG_MAX],\n      [sizeof (long long int) == sizeof (long int)])\n  else\n    INT64_MAX_EQ_LONG_MAX=-1\n  fi\n  gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(\n    [UINT32_MAX_LT_UINTMAX_MAX],\n    [defined UINT32_MAX && defined UINTMAX_MAX],\n    [UINT32_MAX < UINTMAX_MAX],\n    [sizeof (unsigned int) < sizeof (unsigned long long int)])\n  if test $APPLE_UNIVERSAL_BUILD = 0; then\n    gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION(\n      [UINT64_MAX_EQ_ULONG_MAX],\n      [defined UINT64_MAX],\n      [UINT64_MAX == ULONG_MAX],\n      [sizeof (unsigned long long int) == sizeof (unsigned long int)])\n  else\n    UINT64_MAX_EQ_ULONG_MAX=-1\n  fi\n])\n\n# Define the symbol $1 to be 1 if the condition is true, 0 otherwise.\n# If $2 is true, the condition is $3; otherwise if long long int is supported\n# approximate the condition with $4; otherwise, assume the condition is false.\n# The condition should work on all C99 platforms; the approximations should be\n# good enough to work on all practical pre-C99 platforms.\n# $2 is evaluated by the C preprocessor, $3 and $4 as compile-time constants.\nAC_DEFUN([gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION],\n[\n  AC_CACHE_CHECK([whether $3],\n    [gl_cv_test_$1],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[/* Work also in C++ mode.  */\n            #define __STDC_LIMIT_MACROS 1\n\n            /* Work if build is not clean.  */\n            #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H\n\n            #include <limits.h>\n            #if HAVE_STDINT_H\n             #include <stdint.h>\n            #endif\n\n            #if $2\n             #define CONDITION ($3)\n            #else\n             #define CONDITION ($4)\n            #endif\n            int test[CONDITION ? 1 : -1];]])],\n       [gl_cv_test_$1=yes],\n       [gl_cv_test_$1=no])])\n  if test $gl_cv_test_$1 = yes; then\n    $1=1;\n  else\n    $1=0;\n  fi\n  AC_SUBST([$1])\n])\n\n# gl_INTTYPES_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_INTTYPES_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_INTTYPES_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_INTTYPES_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_INTTYPES_H_MODULE_INDICATOR_DEFAULTS], [\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_IMAXABS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_IMAXDIV])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOIMAX])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOUMAX])\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_INTTYPES_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_INTTYPES_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_INTTYPES_H_DEFAULTS],\n[\n  dnl Assume proper GNU behavior unless another module says otherwise.\n  HAVE_DECL_IMAXABS=1;   AC_SUBST([HAVE_DECL_IMAXABS])\n  HAVE_DECL_IMAXDIV=1;   AC_SUBST([HAVE_DECL_IMAXDIV])\n  HAVE_DECL_STRTOIMAX=1; AC_SUBST([HAVE_DECL_STRTOIMAX])\n  HAVE_DECL_STRTOUMAX=1; AC_SUBST([HAVE_DECL_STRTOUMAX])\n  HAVE_IMAXDIV_T=1;      AC_SUBST([HAVE_IMAXDIV_T])\n  REPLACE_STRTOIMAX=0;   AC_SUBST([REPLACE_STRTOIMAX])\n  REPLACE_STRTOUMAX=0;   AC_SUBST([REPLACE_STRTOUMAX])\n  INT32_MAX_LT_INTMAX_MAX=1;  AC_SUBST([INT32_MAX_LT_INTMAX_MAX])\n  INT64_MAX_EQ_LONG_MAX='defined _LP64';  AC_SUBST([INT64_MAX_EQ_LONG_MAX])\n  PRIPTR_PREFIX=__PRIPTR_PREFIX;  AC_SUBST([PRIPTR_PREFIX])\n  UINT32_MAX_LT_UINTMAX_MAX=1;  AC_SUBST([UINT32_MAX_LT_UINTMAX_MAX])\n  UINT64_MAX_EQ_ULONG_MAX='defined _LP64';  AC_SUBST([UINT64_MAX_EQ_ULONG_MAX])\n])\n"
  },
  {
    "path": "m4/isblank.m4",
    "content": "# isblank.m4 serial 3\ndnl Copyright (C) 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_ISBLANK],\n[\n  dnl Persuade glibc <ctype.h> to declare isblank().\n  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])\n\n  AC_REQUIRE([gl_CTYPE_H_DEFAULTS])\n  AC_CHECK_FUNCS_ONCE([isblank])\n  if test $ac_cv_func_isblank = no; then\n    HAVE_ISBLANK=0\n  fi\n])\n"
  },
  {
    "path": "m4/langinfo_h.m4",
    "content": "# langinfo_h.m4 serial 12\ndnl Copyright (C) 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN_ONCE([gl_LANGINFO_H],\n[\n  AC_REQUIRE([gl_LANGINFO_H_DEFAULTS])\n\n  dnl Persuade glibc-2.0.6 <langinfo.h> to define CODESET.\n  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])\n\n  dnl <langinfo.h> is always overridden, because of GNULIB_POSIXCHECK.\n  gl_CHECK_NEXT_HEADERS([langinfo.h])\n\n  dnl Determine whether <langinfo.h> exists. It is missing on mingw and BeOS.\n  HAVE_LANGINFO_CODESET=0\n  HAVE_LANGINFO_T_FMT_AMPM=0\n  HAVE_LANGINFO_ALTMON=0\n  HAVE_LANGINFO_ERA=0\n  HAVE_LANGINFO_YESEXPR=0\n  AC_CHECK_HEADERS_ONCE([langinfo.h])\n  if test $ac_cv_header_langinfo_h = yes; then\n    HAVE_LANGINFO_H=1\n    dnl Determine what <langinfo.h> defines.\n    dnl CODESET is missing on OpenBSD 3.8.\n    dnl ERA etc. are missing on OpenBSD 6.7.\n    dnl T_FMT_AMPM and YESEXPR, NOEXPR are missing on IRIX 5.3.\n    dnl ALTMON_* are missing on glibc 2.26 and many other systems.\n    AC_CACHE_CHECK([whether langinfo.h defines CODESET],\n      [gl_cv_header_langinfo_codeset],\n      [AC_COMPILE_IFELSE(\n         [AC_LANG_PROGRAM([[#include <langinfo.h>\nint a = CODESET;\n]])],\n         [gl_cv_header_langinfo_codeset=yes],\n         [gl_cv_header_langinfo_codeset=no])\n      ])\n    if test $gl_cv_header_langinfo_codeset = yes; then\n      HAVE_LANGINFO_CODESET=1\n    fi\n    AC_CACHE_CHECK([whether langinfo.h defines T_FMT_AMPM],\n      [gl_cv_header_langinfo_t_fmt_ampm],\n      [AC_COMPILE_IFELSE(\n         [AC_LANG_PROGRAM([[#include <langinfo.h>\nint a = T_FMT_AMPM;\n]])],\n         [gl_cv_header_langinfo_t_fmt_ampm=yes],\n         [gl_cv_header_langinfo_t_fmt_ampm=no])\n      ])\n    if test $gl_cv_header_langinfo_t_fmt_ampm = yes; then\n      HAVE_LANGINFO_T_FMT_AMPM=1\n    fi\n    AC_CACHE_CHECK([whether langinfo.h defines ALTMON_1],\n      [gl_cv_header_langinfo_altmon],\n      [AC_COMPILE_IFELSE(\n         [AC_LANG_PROGRAM([[#include <langinfo.h>\nint a = ALTMON_1;\n]])],\n         [gl_cv_header_langinfo_altmon=yes],\n         [gl_cv_header_langinfo_altmon=no])\n      ])\n    if test $gl_cv_header_langinfo_altmon = yes; then\n      HAVE_LANGINFO_ALTMON=1\n    fi\n    AC_CACHE_CHECK([whether langinfo.h defines ERA],\n      [gl_cv_header_langinfo_era],\n      [AC_COMPILE_IFELSE(\n         [AC_LANG_PROGRAM([[#include <langinfo.h>\nint a = ERA;\n]])],\n         [gl_cv_header_langinfo_era=yes],\n         [gl_cv_header_langinfo_era=no])\n      ])\n    if test $gl_cv_header_langinfo_era = yes; then\n      HAVE_LANGINFO_ERA=1\n    fi\n    AC_CACHE_CHECK([whether langinfo.h defines YESEXPR],\n      [gl_cv_header_langinfo_yesexpr],\n      [AC_COMPILE_IFELSE(\n         [AC_LANG_PROGRAM([[#include <langinfo.h>\nint a = YESEXPR;\n]])],\n         [gl_cv_header_langinfo_yesexpr=yes],\n         [gl_cv_header_langinfo_yesexpr=no])\n      ])\n    if test $gl_cv_header_langinfo_yesexpr = yes; then\n      HAVE_LANGINFO_YESEXPR=1\n    fi\n  else\n    HAVE_LANGINFO_H=0\n  fi\n  AC_SUBST([HAVE_LANGINFO_H])\n  AC_SUBST([HAVE_LANGINFO_CODESET])\n  AC_SUBST([HAVE_LANGINFO_T_FMT_AMPM])\n  AC_SUBST([HAVE_LANGINFO_ALTMON])\n  AC_SUBST([HAVE_LANGINFO_ERA])\n  AC_SUBST([HAVE_LANGINFO_YESEXPR])\n\n  dnl Check for declarations of anything we want to poison if the\n  dnl corresponding gnulib module is not in use.\n  gl_WARN_ON_USE_PREPARE([[#include <langinfo.h>\n    ]], [nl_langinfo])\n])\n\n# gl_LANGINFO_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_LANGINFO_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_LANGINFO_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n  dnl Define it also as a C macro, for the benefit of the unit tests.\n  gl_MODULE_INDICATOR_FOR_TESTS([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_LANGINFO_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_LANGINFO_H_MODULE_INDICATOR_DEFAULTS], [\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NL_LANGINFO])\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_LANGINFO_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_LANGINFO_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_LANGINFO_H_DEFAULTS],\n[\n  dnl Assume proper GNU behavior unless another module says otherwise.\n  HAVE_NL_LANGINFO=1;    AC_SUBST([HAVE_NL_LANGINFO])\n  REPLACE_NL_LANGINFO=0; AC_SUBST([REPLACE_NL_LANGINFO])\n])\n"
  },
  {
    "path": "m4/limits-h.m4",
    "content": "dnl Check whether limits.h has needed features.\n\ndnl Copyright 2016-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Paul Eggert.\n\nAC_DEFUN_ONCE([gl_LIMITS_H],\n[\n  gl_CHECK_NEXT_HEADERS([limits.h])\n\n  AC_CACHE_CHECK([whether limits.h has LLONG_MAX, WORD_BIT, ULLONG_WIDTH etc.],\n    [gl_cv_header_limits_width],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#ifndef __STDC_WANT_IEC_60559_BFP_EXT__\n             #define __STDC_WANT_IEC_60559_BFP_EXT__ 1\n            #endif\n            #include <limits.h>\n            long long llm = LLONG_MAX;\n            int wb = WORD_BIT;\n            int ullw = ULLONG_WIDTH;\n          ]])],\n       [gl_cv_header_limits_width=yes],\n       [gl_cv_header_limits_width=no])])\n  if test \"$gl_cv_header_limits_width\" = yes; then\n    LIMITS_H=\n  else\n    LIMITS_H=limits.h\n  fi\n  AC_SUBST([LIMITS_H])\n  AM_CONDITIONAL([GL_GENERATE_LIMITS_H], [test -n \"$LIMITS_H\"])\n])\n\ndnl Unconditionally enables the replacement of <limits.h>.\nAC_DEFUN([gl_REPLACE_LIMITS_H],\n[\n  AC_REQUIRE([gl_LIMITS_H])\n  LIMITS_H='limits.h'\n  AM_CONDITIONAL([GL_GENERATE_LIMITS_H], [test -n \"$LIMITS_H\"])\n])\n"
  },
  {
    "path": "m4/localcharset.m4",
    "content": "# localcharset.m4 serial 8\ndnl Copyright (C) 2002, 2004, 2006, 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_LOCALCHARSET],\n[\n  dnl Prerequisites of lib/localcharset.c.\n  AC_REQUIRE([AM_LANGINFO_CODESET])\n])\n"
  },
  {
    "path": "m4/locale-fr.m4",
    "content": "# locale-fr.m4 serial 20\ndnl Copyright (C) 2003, 2005-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\n\ndnl Determine the name of a french locale with traditional encoding.\nAC_DEFUN([gt_LOCALE_FR],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_REQUIRE([AM_LANGINFO_CODESET])\n  AC_CACHE_CHECK([for a traditional french locale], [gt_cv_locale_fr], [\n    AC_LANG_CONFTEST([AC_LANG_SOURCE([[\n#include <locale.h>\n#include <time.h>\n#if HAVE_LANGINFO_CODESET\n# include <langinfo.h>\n#endif\n#include <stdlib.h>\n#include <string.h>\nstruct tm t;\nchar buf[16];\nint main () {\n  /* On BeOS and Haiku, locales are not implemented in libc.  Rather, libintl\n     imitates locale dependent behaviour by looking at the environment\n     variables, and all locales use the UTF-8 encoding.  */\n#if defined __BEOS__ || defined __HAIKU__\n  return 1;\n#else\n  /* Check whether the given locale name is recognized by the system.  */\n# if defined _WIN32 && !defined __CYGWIN__\n  /* On native Windows, setlocale(category, \"\") looks at the system settings,\n     not at the environment variables.  Also, when an encoding suffix such\n     as \".65001\" or \".54936\" is specified, it succeeds but sets the LC_CTYPE\n     category of the locale to \"C\".  */\n  if (setlocale (LC_ALL, getenv (\"LC_ALL\")) == NULL\n      || strcmp (setlocale (LC_CTYPE, NULL), \"C\") == 0)\n    return 1;\n# else\n  if (setlocale (LC_ALL, \"\") == NULL) return 1;\n# endif\n  /* Check whether nl_langinfo(CODESET) is nonempty and not \"ASCII\" or \"646\".\n     On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)\n     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.\n     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()\n     succeeds but then nl_langinfo(CODESET) is \"646\". In this situation,\n     some unit tests fail.\n     On MirBSD 10, when an unsupported locale is specified, setlocale()\n     succeeds but then nl_langinfo(CODESET) is \"UTF-8\".  */\n# if HAVE_LANGINFO_CODESET\n  {\n    const char *cs = nl_langinfo (CODESET);\n    if (cs[0] == '\\0' || strcmp (cs, \"ASCII\") == 0 || strcmp (cs, \"646\") == 0\n        || strcmp (cs, \"UTF-8\") == 0)\n      return 1;\n  }\n# endif\n# ifdef __CYGWIN__\n  /* On Cygwin, avoid locale names without encoding suffix, because the\n     locale_charset() function relies on the encoding suffix.  Note that\n     LC_ALL is set on the command line.  */\n  if (strchr (getenv (\"LC_ALL\"), '.') == NULL) return 1;\n# endif\n  /* Check whether in the abbreviation of the second month, the second\n     character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is only\n     one byte long. This excludes the UTF-8 encoding.  */\n  t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;\n  if (strftime (buf, sizeof (buf), \"%b\", &t) < 3 || buf[2] != 'v') return 1;\n# if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy.  */\n  /* Check whether the decimal separator is a comma.\n     On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point\n     are nl_langinfo(RADIXCHAR) are both \".\".  */\n  if (localeconv () ->decimal_point[0] != ',') return 1;\n# endif\n  return 0;\n#endif\n}\n      ]])])\n    if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then\n      case \"$host_os\" in\n        # Handle native Windows specially, because there setlocale() interprets\n        # \"ar\" as \"Arabic\" or \"Arabic_Saudi Arabia.1256\",\n        # \"fr\" or \"fra\" as \"French\" or \"French_France.1252\",\n        # \"ge\"(!) or \"deu\"(!) as \"German\" or \"German_Germany.1252\",\n        # \"ja\" as \"Japanese\" or \"Japanese_Japan.932\",\n        # and similar.\n        mingw*)\n          # Test for the native Windows locale name.\n          if (LC_ALL=French_France.1252 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n            gt_cv_locale_fr=French_France.1252\n          else\n            # None found.\n            gt_cv_locale_fr=none\n          fi\n          ;;\n        *)\n          # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because\n          # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the\n          # configure script would override the LC_ALL setting. Likewise for\n          # LC_CTYPE, which is also set at the beginning of the configure script.\n          # Test for the usual locale name.\n          if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n            gt_cv_locale_fr=fr_FR\n          else\n            # Test for the locale name with explicit encoding suffix.\n            if (LC_ALL=fr_FR.ISO-8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n              gt_cv_locale_fr=fr_FR.ISO-8859-1\n            else\n              # Test for the AIX, OSF/1, FreeBSD, NetBSD, OpenBSD locale name.\n              if (LC_ALL=fr_FR.ISO8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n                gt_cv_locale_fr=fr_FR.ISO8859-1\n              else\n                # Test for the HP-UX locale name.\n                if (LC_ALL=fr_FR.iso88591 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n                  gt_cv_locale_fr=fr_FR.iso88591\n                else\n                  # Test for the Solaris 7 locale name.\n                  if (LC_ALL=fr LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n                    gt_cv_locale_fr=fr\n                  else\n                    # None found.\n                    gt_cv_locale_fr=none\n                  fi\n                fi\n              fi\n            fi\n          fi\n          ;;\n      esac\n    fi\n    rm -fr conftest*\n  ])\n  LOCALE_FR=$gt_cv_locale_fr\n  AC_SUBST([LOCALE_FR])\n])\n\ndnl Determine the name of a french locale with UTF-8 encoding.\nAC_DEFUN([gt_LOCALE_FR_UTF8],\n[\n  AC_REQUIRE([AM_LANGINFO_CODESET])\n  AC_CACHE_CHECK([for a french Unicode locale], [gt_cv_locale_fr_utf8], [\n    AC_LANG_CONFTEST([AC_LANG_SOURCE([[\n#include <locale.h>\n#include <time.h>\n#if HAVE_LANGINFO_CODESET\n# include <langinfo.h>\n#endif\n#include <stdlib.h>\n#include <string.h>\nstruct tm t;\nchar buf[16];\nint main () {\n  /* On BeOS and Haiku, locales are not implemented in libc.  Rather, libintl\n     imitates locale dependent behaviour by looking at the environment\n     variables, and all locales use the UTF-8 encoding.  */\n#if !(defined __BEOS__ || defined __HAIKU__)\n  /* Check whether the given locale name is recognized by the system.  */\n# if defined _WIN32 && !defined __CYGWIN__\n  /* On native Windows, setlocale(category, \"\") looks at the system settings,\n     not at the environment variables.  Also, when an encoding suffix such\n     as \".65001\" or \".54936\" is specified, it succeeds but sets the LC_CTYPE\n     category of the locale to \"C\".  */\n  if (setlocale (LC_ALL, getenv (\"LC_ALL\")) == NULL\n      || strcmp (setlocale (LC_CTYPE, NULL), \"C\") == 0)\n    return 1;\n# else\n  if (setlocale (LC_ALL, \"\") == NULL) return 1;\n# endif\n  /* Check whether nl_langinfo(CODESET) is nonempty and not \"ASCII\" or \"646\".\n     On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)\n     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.\n     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()\n     succeeds but then nl_langinfo(CODESET) is \"646\". In this situation,\n     some unit tests fail.  */\n# if HAVE_LANGINFO_CODESET\n  {\n    const char *cs = nl_langinfo (CODESET);\n    if (cs[0] == '\\0' || strcmp (cs, \"ASCII\") == 0 || strcmp (cs, \"646\") == 0)\n      return 1;\n  }\n# endif\n# ifdef __CYGWIN__\n  /* On Cygwin, avoid locale names without encoding suffix, because the\n     locale_charset() function relies on the encoding suffix.  Note that\n     LC_ALL is set on the command line.  */\n  if (strchr (getenv (\"LC_ALL\"), '.') == NULL) return 1;\n# endif\n  /* Check whether in the abbreviation of the second month, the second\n     character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is\n     two bytes long, with UTF-8 encoding.  */\n  t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;\n  if (strftime (buf, sizeof (buf), \"%b\", &t) < 4\n      || buf[1] != (char) 0xc3 || buf[2] != (char) 0xa9 || buf[3] != 'v')\n    return 1;\n#endif\n#if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy.  */\n  /* Check whether the decimal separator is a comma.\n     On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point\n     are nl_langinfo(RADIXCHAR) are both \".\".  */\n  if (localeconv () ->decimal_point[0] != ',') return 1;\n#endif\n  return 0;\n}\n      ]])])\n    if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then\n      case \"$host_os\" in\n        # Handle native Windows specially, because there setlocale() interprets\n        # \"ar\" as \"Arabic\" or \"Arabic_Saudi Arabia.1256\",\n        # \"fr\" or \"fra\" as \"French\" or \"French_France.1252\",\n        # \"ge\"(!) or \"deu\"(!) as \"German\" or \"German_Germany.1252\",\n        # \"ja\" as \"Japanese\" or \"Japanese_Japan.932\",\n        # and similar.\n        mingw*)\n          # Test for the hypothetical native Windows locale name.\n          if (LC_ALL=French_France.65001 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n            gt_cv_locale_fr_utf8=French_France.65001\n          else\n            # None found.\n            gt_cv_locale_fr_utf8=none\n          fi\n          ;;\n        *)\n          # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because\n          # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the\n          # configure script would override the LC_ALL setting. Likewise for\n          # LC_CTYPE, which is also set at the beginning of the configure script.\n          # Test for the usual locale name.\n          if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n            gt_cv_locale_fr_utf8=fr_FR\n          else\n            # Test for the locale name with explicit encoding suffix.\n            if (LC_ALL=fr_FR.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n              gt_cv_locale_fr_utf8=fr_FR.UTF-8\n            else\n              # Test for the Solaris 7 locale name.\n              if (LC_ALL=fr.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n                gt_cv_locale_fr_utf8=fr.UTF-8\n              else\n                # None found.\n                gt_cv_locale_fr_utf8=none\n              fi\n            fi\n          fi\n          ;;\n      esac\n    fi\n    rm -fr conftest*\n  ])\n  LOCALE_FR_UTF8=$gt_cv_locale_fr_utf8\n  AC_SUBST([LOCALE_FR_UTF8])\n])\n"
  },
  {
    "path": "m4/locale-ja.m4",
    "content": "# locale-ja.m4 serial 15\ndnl Copyright (C) 2003, 2005-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\n\ndnl Determine the name of a japanese locale with EUC-JP encoding.\nAC_DEFUN([gt_LOCALE_JA],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_REQUIRE([AM_LANGINFO_CODESET])\n  AC_CACHE_CHECK([for a traditional japanese locale], [gt_cv_locale_ja], [\n    AC_LANG_CONFTEST([AC_LANG_SOURCE([[\n#include <locale.h>\n#include <time.h>\n#if HAVE_LANGINFO_CODESET\n# include <langinfo.h>\n#endif\n#include <stdlib.h>\n#include <string.h>\nstruct tm t;\nchar buf[16];\nint main ()\n{\n  /* On BeOS and Haiku, locales are not implemented in libc.  Rather, libintl\n     imitates locale dependent behaviour by looking at the environment\n     variables, and all locales use the UTF-8 encoding.  */\n#if defined __BEOS__ || defined __HAIKU__\n  return 1;\n#else\n  /* Check whether the given locale name is recognized by the system.  */\n# if defined _WIN32 && !defined __CYGWIN__\n  /* On native Windows, setlocale(category, \"\") looks at the system settings,\n     not at the environment variables.  Also, when an encoding suffix such\n     as \".65001\" or \".54936\" is specified, it succeeds but sets the LC_CTYPE\n     category of the locale to \"C\".  */\n  if (setlocale (LC_ALL, getenv (\"LC_ALL\")) == NULL\n      || strcmp (setlocale (LC_CTYPE, NULL), \"C\") == 0)\n    return 1;\n# else\n  if (setlocale (LC_ALL, \"\") == NULL) return 1;\n# endif\n  /* Check whether nl_langinfo(CODESET) is nonempty and not \"ASCII\" or \"646\".\n     On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)\n     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.\n     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()\n     succeeds but then nl_langinfo(CODESET) is \"646\". In this situation,\n     some unit tests fail.\n     On MirBSD 10, when an unsupported locale is specified, setlocale()\n     succeeds but then nl_langinfo(CODESET) is \"UTF-8\".  */\n# if HAVE_LANGINFO_CODESET\n  {\n    const char *cs = nl_langinfo (CODESET);\n    if (cs[0] == '\\0' || strcmp (cs, \"ASCII\") == 0 || strcmp (cs, \"646\") == 0\n        || strcmp (cs, \"UTF-8\") == 0)\n      return 1;\n  }\n# endif\n# ifdef __CYGWIN__\n  /* On Cygwin, avoid locale names without encoding suffix, because the\n     locale_charset() function relies on the encoding suffix.  Note that\n     LC_ALL is set on the command line.  */\n  if (strchr (getenv (\"LC_ALL\"), '.') == NULL) return 1;\n# endif\n  /* Check whether MB_CUR_MAX is > 1.  This excludes the dysfunctional locales\n     on Cygwin 1.5.x.  */\n  if (MB_CUR_MAX == 1)\n    return 1;\n  /* Check whether in a month name, no byte in the range 0x80..0x9F occurs.\n     This excludes the UTF-8 encoding (except on MirBSD).  */\n  {\n    const char *p;\n    t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;\n    if (strftime (buf, sizeof (buf), \"%B\", &t) < 2) return 1;\n    for (p = buf; *p != '\\0'; p++)\n      if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0)\n        return 1;\n  }\n  return 0;\n#endif\n}\n      ]])])\n    if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then\n      case \"$host_os\" in\n        # Handle native Windows specially, because there setlocale() interprets\n        # \"ar\" as \"Arabic\" or \"Arabic_Saudi Arabia.1256\",\n        # \"fr\" or \"fra\" as \"French\" or \"French_France.1252\",\n        # \"ge\"(!) or \"deu\"(!) as \"German\" or \"German_Germany.1252\",\n        # \"ja\" as \"Japanese\" or \"Japanese_Japan.932\",\n        # and similar.\n        mingw*)\n          # Note that on native Windows, the Japanese locale is\n          # Japanese_Japan.932, and CP932 is very different from EUC-JP, so we\n          # cannot use it here.\n          gt_cv_locale_ja=none\n          ;;\n        *)\n          # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because\n          # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the\n          # configure script would override the LC_ALL setting. Likewise for\n          # LC_CTYPE, which is also set at the beginning of the configure script.\n          # Test for the AIX locale name.\n          if (LC_ALL=ja_JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n            gt_cv_locale_ja=ja_JP\n          else\n            # Test for the locale name with explicit encoding suffix.\n            if (LC_ALL=ja_JP.EUC-JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n              gt_cv_locale_ja=ja_JP.EUC-JP\n            else\n              # Test for the HP-UX, OSF/1, NetBSD locale name.\n              if (LC_ALL=ja_JP.eucJP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n                gt_cv_locale_ja=ja_JP.eucJP\n              else\n                # Test for the IRIX, FreeBSD locale name.\n                if (LC_ALL=ja_JP.EUC LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n                  gt_cv_locale_ja=ja_JP.EUC\n                else\n                  # Test for the Solaris 7 locale name.\n                  if (LC_ALL=ja LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n                    gt_cv_locale_ja=ja\n                  else\n                    # Special test for NetBSD 1.6.\n                    if test -f /usr/share/locale/ja_JP.eucJP/LC_CTYPE; then\n                      gt_cv_locale_ja=ja_JP.eucJP\n                    else\n                      # None found.\n                      gt_cv_locale_ja=none\n                    fi\n                  fi\n                fi\n              fi\n            fi\n          fi\n          ;;\n      esac\n    fi\n    rm -fr conftest*\n  ])\n  LOCALE_JA=$gt_cv_locale_ja\n  AC_SUBST([LOCALE_JA])\n])\n"
  },
  {
    "path": "m4/locale-zh.m4",
    "content": "# locale-zh.m4 serial 15\ndnl Copyright (C) 2003, 2005-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\n\ndnl Determine the name of a chinese locale with GB18030 encoding.\nAC_DEFUN([gt_LOCALE_ZH_CN],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_REQUIRE([AM_LANGINFO_CODESET])\n  AC_CACHE_CHECK([for a transitional chinese locale], [gt_cv_locale_zh_CN], [\n    AC_LANG_CONFTEST([AC_LANG_SOURCE([[\n#include <locale.h>\n#include <stdlib.h>\n#include <time.h>\n#if HAVE_LANGINFO_CODESET\n# include <langinfo.h>\n#endif\n#include <stdlib.h>\n#include <string.h>\nstruct tm t;\nchar buf[16];\nint main ()\n{\n  /* On BeOS and Haiku, locales are not implemented in libc.  Rather, libintl\n     imitates locale dependent behaviour by looking at the environment\n     variables, and all locales use the UTF-8 encoding.  */\n#if defined __BEOS__ || defined __HAIKU__\n  return 1;\n#else\n  /* Check whether the given locale name is recognized by the system.  */\n# if defined _WIN32 && !defined __CYGWIN__\n  /* On native Windows, setlocale(category, \"\") looks at the system settings,\n     not at the environment variables.  Also, when an encoding suffix such\n     as \".65001\" or \".54936\" is specified, it succeeds but sets the LC_CTYPE\n     category of the locale to \"C\".  */\n  if (setlocale (LC_ALL, getenv (\"LC_ALL\")) == NULL\n      || strcmp (setlocale (LC_CTYPE, NULL), \"C\") == 0)\n    return 1;\n# else\n  if (setlocale (LC_ALL, \"\") == NULL) return 1;\n# endif\n  /* Check whether nl_langinfo(CODESET) is nonempty and not \"ASCII\" or \"646\".\n     On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)\n     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.\n     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()\n     succeeds but then nl_langinfo(CODESET) is \"646\". In this situation,\n     some unit tests fail.\n     On MirBSD 10, when an unsupported locale is specified, setlocale()\n     succeeds but then nl_langinfo(CODESET) is \"UTF-8\".  */\n# if HAVE_LANGINFO_CODESET\n  {\n    const char *cs = nl_langinfo (CODESET);\n    if (cs[0] == '\\0' || strcmp (cs, \"ASCII\") == 0 || strcmp (cs, \"646\") == 0\n        || strcmp (cs, \"UTF-8\") == 0)\n      return 1;\n  }\n# endif\n# ifdef __CYGWIN__\n  /* On Cygwin, avoid locale names without encoding suffix, because the\n     locale_charset() function relies on the encoding suffix.  Note that\n     LC_ALL is set on the command line.  */\n  if (strchr (getenv (\"LC_ALL\"), '.') == NULL) return 1;\n# endif\n  /* Check whether in a month name, no byte in the range 0x80..0x9F occurs.\n     This excludes the UTF-8 encoding (except on MirBSD).  */\n  {\n    const char *p;\n    t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;\n    if (strftime (buf, sizeof (buf), \"%B\", &t) < 2) return 1;\n    for (p = buf; *p != '\\0'; p++)\n      if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0)\n        return 1;\n  }\n  /* Check whether a typical GB18030 multibyte sequence is recognized as a\n     single wide character.  This excludes the GB2312 and GBK encodings.  */\n  if (mblen (\"\\203\\062\\332\\066\", 5) != 4)\n    return 1;\n  return 0;\n#endif\n}\n      ]])])\n    if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then\n      case \"$host_os\" in\n        # Handle native Windows specially, because there setlocale() interprets\n        # \"ar\" as \"Arabic\" or \"Arabic_Saudi Arabia.1256\",\n        # \"fr\" or \"fra\" as \"French\" or \"French_France.1252\",\n        # \"ge\"(!) or \"deu\"(!) as \"German\" or \"German_Germany.1252\",\n        # \"ja\" as \"Japanese\" or \"Japanese_Japan.932\",\n        # and similar.\n        mingw*)\n          # Test for the hypothetical native Windows locale name.\n          if (LC_ALL=Chinese_China.54936 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n            gt_cv_locale_zh_CN=Chinese_China.54936\n          else\n            # None found.\n            gt_cv_locale_zh_CN=none\n          fi\n          ;;\n        solaris2.8)\n          # On Solaris 8, the locales zh_CN.GB18030, zh_CN.GBK, zh.GBK are\n          # broken. One witness is the test case in gl_MBRTOWC_SANITYCHECK.\n          # Another witness is that \"LC_ALL=zh_CN.GB18030 bash -c true\" dumps core.\n          gt_cv_locale_zh_CN=none\n          ;;\n        *)\n          # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because\n          # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the\n          # configure script would override the LC_ALL setting. Likewise for\n          # LC_CTYPE, which is also set at the beginning of the configure script.\n          # Test for the locale name without encoding suffix.\n          if (LC_ALL=zh_CN LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n            gt_cv_locale_zh_CN=zh_CN\n          else\n            # Test for the locale name with explicit encoding suffix.\n            if (LC_ALL=zh_CN.GB18030 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then\n              gt_cv_locale_zh_CN=zh_CN.GB18030\n            else\n              # None found.\n              gt_cv_locale_zh_CN=none\n            fi\n          fi\n          ;;\n      esac\n    else\n      # If there was a link error, due to mblen(), the system is so old that\n      # it certainly doesn't have a chinese locale.\n      gt_cv_locale_zh_CN=none\n    fi\n    rm -fr conftest*\n  ])\n  LOCALE_ZH_CN=$gt_cv_locale_zh_CN\n  AC_SUBST([LOCALE_ZH_CN])\n])\n"
  },
  {
    "path": "m4/locale_h.m4",
    "content": "# locale_h.m4 serial 28\ndnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN_ONCE([gl_LOCALE_H],\n[\n  dnl Ensure to expand the default settings once only, before all statements\n  dnl that occur in other macros.\n  AC_REQUIRE([gl_LOCALE_H_DEFAULTS])\n\n  dnl Persuade glibc <locale.h> to define locale_t and the int_p_*, int_n_*\n  dnl members of 'struct lconv'.\n  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])\n\n  dnl If <stddef.h> is replaced, then <locale.h> must also be replaced.\n  AC_REQUIRE([gl_STDDEF_H])\n\n  AC_REQUIRE([gl_LOCALE_T])\n\n  dnl Solaris 11.0 defines the int_p_*, int_n_* members of 'struct lconv'\n  dnl only if _LCONV_C99 is defined.\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  case \"$host_os\" in\n    solaris*)\n      AC_DEFINE([_LCONV_C99], [1], [Define to 1 on Solaris.])\n      ;;\n  esac\n\n  AC_CACHE_CHECK([whether locale.h conforms to POSIX:2001],\n    [gl_cv_header_locale_h_posix2001],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <locale.h>\n            int x = LC_MESSAGES;\n            int y = sizeof (((struct lconv *) 0)->decimal_point);]],\n          [[]])],\n       [gl_cv_header_locale_h_posix2001=yes],\n       [gl_cv_header_locale_h_posix2001=no])])\n\n  dnl Check whether 'struct lconv' is complete.\n  dnl Bionic libc's 'struct lconv' is just a dummy.\n  dnl On OpenBSD 4.9, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 1.5.x,\n  dnl mingw, MSVC 9, it lacks the int_p_* and int_n_* members.\n  AC_CACHE_CHECK([whether struct lconv is properly defined],\n    [gl_cv_sys_struct_lconv_ok],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <locale.h>\n            struct lconv l;\n            int x = sizeof (l.decimal_point);\n            int y = sizeof (l.int_p_cs_precedes);]],\n          [[]])],\n       [gl_cv_sys_struct_lconv_ok=yes],\n       [gl_cv_sys_struct_lconv_ok=no])\n    ])\n  if test $gl_cv_sys_struct_lconv_ok = no; then\n    dnl On native Windows with MSVC, merely define these member names as macros.\n    dnl This avoids trouble in C++ mode.\n    case \"$host_os\" in\n      mingw*)\n        AC_EGREP_CPP([Special], [\n#ifdef _MSC_VER\n Special\n#endif\n          ],\n          [],\n          [REPLACE_STRUCT_LCONV=1])\n        ;;\n      *) REPLACE_STRUCT_LCONV=1 ;;\n    esac\n  fi\n\n  dnl <locale.h> is always overridden, because of GNULIB_POSIXCHECK.\n  gl_NEXT_HEADERS([locale.h])\n\n  dnl Check for declarations of anything we want to poison if the\n  dnl corresponding gnulib module is not in use.\n  gl_WARN_ON_USE_PREPARE([[#include <locale.h>\n/* Some systems provide declarations in a non-standard header.  */\n#if HAVE_XLOCALE_H\n# include <xlocale.h>\n#endif\n    ]],\n    [setlocale newlocale duplocale freelocale])\n])\n\ndnl Checks to determine whether the system has the locale_t type,\ndnl and how to obtain it.\nAC_DEFUN([gl_LOCALE_T],\n[\n  dnl Persuade glibc and Solaris <locale.h> to define locale_t.\n  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])\n\n  dnl Check whether use of locale_t requires inclusion of <xlocale.h>,\n  dnl e.g. on Mac OS X 10.5. If <locale.h> does not define locale_t by\n  dnl itself, we assume that <xlocale.h> will do so.\n  AC_CACHE_CHECK([whether locale.h defines locale_t],\n    [gl_cv_header_locale_has_locale_t],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <locale.h>\n            locale_t x;]],\n          [[]])],\n       [gl_cv_header_locale_has_locale_t=yes],\n       [gl_cv_header_locale_has_locale_t=no])\n    ])\n\n  dnl Check for <xlocale.h>.\n  AC_CHECK_HEADERS_ONCE([xlocale.h])\n  if test $ac_cv_header_xlocale_h = yes; then\n    HAVE_XLOCALE_H=1\n    if test $gl_cv_header_locale_has_locale_t = yes; then\n      gl_cv_header_locale_h_needs_xlocale_h=no\n    else\n      gl_cv_header_locale_h_needs_xlocale_h=yes\n    fi\n    HAVE_LOCALE_T=1\n  else\n    HAVE_XLOCALE_H=0\n    gl_cv_header_locale_h_needs_xlocale_h=no\n    if test $gl_cv_header_locale_has_locale_t = yes; then\n      HAVE_LOCALE_T=1\n    else\n      HAVE_LOCALE_T=0\n    fi\n  fi\n  AC_SUBST([HAVE_XLOCALE_H])\n])\n\n# gl_LOCALE_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_LOCALE_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_LOCALE_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n  dnl Define it also as a C macro, for the benefit of the unit tests.\n  gl_MODULE_INDICATOR_FOR_TESTS([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_LOCALE_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_LOCALE_H_MODULE_INDICATOR_DEFAULTS], [\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALECONV])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETLOCALE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETLOCALE_NULL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUPLOCALE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALENAME])\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_LOCALE_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_LOCALE_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_LOCALE_H_DEFAULTS],\n[\n  dnl Assume proper GNU behavior unless another module says otherwise.\n  HAVE_NEWLOCALE=1;       AC_SUBST([HAVE_NEWLOCALE])\n  HAVE_DUPLOCALE=1;       AC_SUBST([HAVE_DUPLOCALE])\n  HAVE_FREELOCALE=1;      AC_SUBST([HAVE_FREELOCALE])\n  REPLACE_LOCALECONV=0;   AC_SUBST([REPLACE_LOCALECONV])\n  REPLACE_SETLOCALE=0;    AC_SUBST([REPLACE_SETLOCALE])\n  REPLACE_NEWLOCALE=0;    AC_SUBST([REPLACE_NEWLOCALE])\n  REPLACE_DUPLOCALE=0;    AC_SUBST([REPLACE_DUPLOCALE])\n  REPLACE_FREELOCALE=0;   AC_SUBST([REPLACE_FREELOCALE])\n  REPLACE_STRUCT_LCONV=0; AC_SUBST([REPLACE_STRUCT_LCONV])\n  LOCALENAME_ENHANCE_LOCALE_FUNCS=0; AC_SUBST([LOCALENAME_ENHANCE_LOCALE_FUNCS])\n])\n"
  },
  {
    "path": "m4/localeconv.m4",
    "content": "# localeconv.m4 serial 1\ndnl Copyright (C) 2012-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_LOCALECONV],\n[\n  AC_REQUIRE([gl_LOCALE_H_DEFAULTS])\n  AC_REQUIRE([gl_LOCALE_H])\n\n  if test $REPLACE_STRUCT_LCONV = 1; then\n    REPLACE_LOCALECONV=1\n  fi\n])\n\n# Prerequisites of lib/localeconv.c.\nAC_DEFUN([gl_PREREQ_LOCALECONV],\n[\n  AC_CHECK_MEMBERS([struct lconv.decimal_point], [], [],\n    [[#include <locale.h>]])\n])\n"
  },
  {
    "path": "m4/lock.m4",
    "content": "# lock.m4 serial 14\ndnl Copyright (C) 2005-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\n\nAC_DEFUN([gl_LOCK],\n[\n  AC_REQUIRE([gl_THREADLIB])\n  if test \"$gl_threads_api\" = posix; then\n    # OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the\n    # pthread_rwlock_* functions.\n    has_rwlock=false\n    AC_CHECK_TYPE([pthread_rwlock_t],\n      [has_rwlock=true\n       AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1],\n         [Define if the POSIX multithreading library has read/write locks.])],\n      [],\n      [#include <pthread.h>])\n    if $has_rwlock; then\n      gl_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER\n    fi\n    # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro.\n    AC_COMPILE_IFELSE([\n      AC_LANG_PROGRAM(\n        [[#include <pthread.h>]],\n        [[\n#if __FreeBSD__ == 4\nerror \"No, in FreeBSD 4.0 recursive mutexes actually don't work.\"\n#elif (defined __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ \\\n       && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)\nerror \"No, in Mac OS X < 10.7 recursive mutexes actually don't work.\"\n#else\nint x = (int)PTHREAD_MUTEX_RECURSIVE;\nreturn !x;\n#endif\n        ]])],\n      [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], [1],\n         [Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE.])])\n  fi\n  gl_PREREQ_LOCK\n])\n\n# Prerequisites of lib/glthread/lock.c.\nAC_DEFUN([gl_PREREQ_LOCK], [:])\n"
  },
  {
    "path": "m4/mbrtowc.m4",
    "content": "# mbrtowc.m4 serial 38  -*- coding: utf-8 -*-\ndnl Copyright (C) 2001-2002, 2004-2005, 2008-2021 Free Software Foundation,\ndnl Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_MBRTOWC],\n[\n  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])\n  AC_REQUIRE([gl_PTHREADLIB])\n  AC_CHECK_HEADERS_ONCE([threads.h])\n\n  AC_REQUIRE([AC_TYPE_MBSTATE_T])\n  gl_MBSTATE_T_BROKEN\n\n  AC_CHECK_FUNCS_ONCE([mbrtowc])\n  if test $ac_cv_func_mbrtowc = no; then\n    HAVE_MBRTOWC=0\n    AC_CHECK_DECLS([mbrtowc],,, [[\n      #include <wchar.h>\n    ]])\n    if test $ac_cv_have_decl_mbrtowc = yes; then\n      dnl On Minix 3.1.8, the system's <wchar.h> declares mbrtowc() although\n      dnl it does not have the function. Avoid a collision with gnulib's\n      dnl replacement.\n      REPLACE_MBRTOWC=1\n    fi\n  else\n    if test $REPLACE_MBSTATE_T = 1; then\n      REPLACE_MBRTOWC=1\n    else\n      gl_MBRTOWC_NULL_ARG1\n      gl_MBRTOWC_NULL_ARG2\n      gl_MBRTOWC_RETVAL\n      gl_MBRTOWC_NUL_RETVAL\n      gl_MBRTOWC_STORES_INCOMPLETE\n      gl_MBRTOWC_EMPTY_INPUT\n      gl_MBRTOWC_C_LOCALE\n      case \"$gl_cv_func_mbrtowc_null_arg1\" in\n        *yes) ;;\n        *) AC_DEFINE([MBRTOWC_NULL_ARG1_BUG], [1],\n             [Define if the mbrtowc function has the NULL pwc argument bug.])\n           REPLACE_MBRTOWC=1\n           ;;\n      esac\n      case \"$gl_cv_func_mbrtowc_null_arg2\" in\n        *yes) ;;\n        *) AC_DEFINE([MBRTOWC_NULL_ARG2_BUG], [1],\n             [Define if the mbrtowc function has the NULL string argument bug.])\n           REPLACE_MBRTOWC=1\n           ;;\n      esac\n      case \"$gl_cv_func_mbrtowc_retval\" in\n        *yes) ;;\n        *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1],\n             [Define if the mbrtowc function returns a wrong return value.])\n           REPLACE_MBRTOWC=1\n           ;;\n      esac\n      case \"$gl_cv_func_mbrtowc_nul_retval\" in\n        *yes) ;;\n        *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1],\n             [Define if the mbrtowc function does not return 0 for a NUL character.])\n           REPLACE_MBRTOWC=1\n           ;;\n      esac\n      case \"$gl_cv_func_mbrtowc_stores_incomplete\" in\n        *no) ;;\n        *) AC_DEFINE([MBRTOWC_STORES_INCOMPLETE_BUG], [1],\n             [Define if the mbrtowc function stores a wide character when reporting incomplete input.])\n           REPLACE_MBRTOWC=1\n           ;;\n      esac\n      case \"$gl_cv_func_mbrtowc_empty_input\" in\n        *yes) ;;\n        *) AC_DEFINE([MBRTOWC_EMPTY_INPUT_BUG], [1],\n             [Define if the mbrtowc function does not return (size_t) -2\n              for empty input.])\n           REPLACE_MBRTOWC=1\n           ;;\n      esac\n      case \"$gl_cv_func_mbrtowc_C_locale_sans_EILSEQ\" in\n        *yes) ;;\n        *) AC_DEFINE([MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ], [1],\n             [Define if the mbrtowc function may signal encoding errors in the C locale.])\n           REPLACE_MBRTOWC=1\n           ;;\n      esac\n    fi\n  fi\n  if test $REPLACE_MBSTATE_T = 1; then\n    case \"$host_os\" in\n      mingw*) LIB_MBRTOWC= ;;\n      *)\n        gl_WEAK_SYMBOLS\n        case \"$gl_cv_have_weak\" in\n          *yes) LIB_MBRTOWC= ;;\n          *)    LIB_MBRTOWC=\"$LIBPTHREAD\" ;;\n        esac\n        ;;\n    esac\n  else\n    LIB_MBRTOWC=\n  fi\n  dnl LIB_MBRTOWC is expected to be '-pthread' or '-lpthread' on AIX\n  dnl with gcc or xlc, and empty otherwise.\n  AC_SUBST([LIB_MBRTOWC])\n])\n\ndnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that\ndnl redefines the semantics of the given mbstate_t type.\ndnl Result is REPLACE_MBSTATE_T.\ndnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to\ndnl avoid inconsistencies.\n\nAC_DEFUN([gl_MBSTATE_T_BROKEN],\n[\n  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])\n  AC_REQUIRE([AC_CANONICAL_HOST])\n\n  AC_REQUIRE([AC_TYPE_MBSTATE_T])\n  AC_CHECK_FUNCS_ONCE([mbsinit])\n  AC_CHECK_FUNCS_ONCE([mbrtowc])\n  dnl On native Windows, we know exactly how mbsinit() behaves and don't need\n  dnl to override it, even if - like on MSVC - mbsinit() is only defined as\n  dnl an inline function, not as a global function.\n  if case \"$host_os\" in\n       mingw*) true ;;\n       *) test $ac_cv_func_mbsinit = yes ;;\n     esac \\\n    && test $ac_cv_func_mbrtowc = yes; then\n    gl_MBRTOWC_INCOMPLETE_STATE\n    gl_MBRTOWC_SANITYCHECK\n    REPLACE_MBSTATE_T=0\n    case \"$gl_cv_func_mbrtowc_incomplete_state\" in\n      *yes) ;;\n      *) REPLACE_MBSTATE_T=1 ;;\n    esac\n    case \"$gl_cv_func_mbrtowc_sanitycheck\" in\n      *yes) ;;\n      *) REPLACE_MBSTATE_T=1 ;;\n    esac\n  else\n    REPLACE_MBSTATE_T=1\n  fi\n])\n\ndnl Test whether mbrtowc puts the state into non-initial state when parsing an\ndnl incomplete multibyte character.\ndnl Result is gl_cv_func_mbrtowc_incomplete_state.\n\nAC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([gt_LOCALE_JA])\n  AC_REQUIRE([gt_LOCALE_FR_UTF8])\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_CACHE_CHECK([whether mbrtowc handles incomplete characters],\n    [gl_cv_func_mbrtowc_incomplete_state],\n    [\n      dnl Initial guess, used when cross-compiling or when no suitable locale\n      dnl is present.\nchangequote(,)dnl\n      case \"$host_os\" in\n                     # Guess no on AIX and OSF/1.\n        aix* | osf*) gl_cv_func_mbrtowc_incomplete_state=\"guessing no\" ;;\n                     # Guess yes otherwise.\n        *)           gl_cv_func_mbrtowc_incomplete_state=\"guessing yes\" ;;\n      esac\nchangequote([,])dnl\n      if test $LOCALE_JA != none; then\n        AC_RUN_IFELSE(\n          [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <string.h>\n#include <wchar.h>\nint main ()\n{\n  if (setlocale (LC_ALL, \"$LOCALE_JA\") != NULL)\n    {\n      const char input[] = \"B\\217\\253\\344\\217\\251\\316er\"; /* \"Büßer\" */\n      mbstate_t state;\n      wchar_t wc;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))\n        if (mbsinit (&state))\n          return 2;\n    }\n  return 0;\n}]])],\n          [gl_cv_func_mbrtowc_incomplete_state=yes],\n          [gl_cv_func_mbrtowc_incomplete_state=no],\n          [:])\n      else\n        if test $LOCALE_FR_UTF8 != none; then\n          AC_RUN_IFELSE(\n            [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <string.h>\n#include <wchar.h>\nint main ()\n{\n  if (setlocale (LC_ALL, \"$LOCALE_FR_UTF8\") != NULL)\n    {\n      const char input[] = \"B\\303\\274\\303\\237er\"; /* \"Büßer\" */\n      mbstate_t state;\n      wchar_t wc;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))\n        if (mbsinit (&state))\n          return 2;\n    }\n  return 0;\n}]])],\n          [gl_cv_func_mbrtowc_incomplete_state=yes],\n          [gl_cv_func_mbrtowc_incomplete_state=no],\n          [:])\n        fi\n      fi\n    ])\n])\n\ndnl Test whether mbrtowc works not worse than mbtowc.\ndnl Result is gl_cv_func_mbrtowc_sanitycheck.\n\nAC_DEFUN([gl_MBRTOWC_SANITYCHECK],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([gt_LOCALE_ZH_CN])\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc],\n    [gl_cv_func_mbrtowc_sanitycheck],\n    [\n      dnl Initial guess, used when cross-compiling or when no suitable locale\n      dnl is present.\nchangequote(,)dnl\n      case \"$host_os\" in\n                    # Guess no on Solaris 8.\n        solaris2.8) gl_cv_func_mbrtowc_sanitycheck=\"guessing no\" ;;\n                    # Guess yes otherwise.\n        *)          gl_cv_func_mbrtowc_sanitycheck=\"guessing yes\" ;;\n      esac\nchangequote([,])dnl\n      if test $LOCALE_ZH_CN != none; then\n        AC_RUN_IFELSE(\n          [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <stdlib.h>\n#include <string.h>\n#include <wchar.h>\nint main ()\n{\n  /* This fails on Solaris 8:\n     mbrtowc returns 2, and sets wc to 0x00F0.\n     mbtowc returns 4 (correct) and sets wc to 0x5EDC.  */\n  if (setlocale (LC_ALL, \"$LOCALE_ZH_CN\") != NULL)\n    {\n      char input[] = \"B\\250\\271\\201\\060\\211\\070er\"; /* \"Büßer\" */\n      mbstate_t state;\n      wchar_t wc;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, input + 3, 6, &state) != 4\n          && mbtowc (&wc, input + 3, 6) == 4)\n        return 2;\n    }\n  return 0;\n}]])],\n          [gl_cv_func_mbrtowc_sanitycheck=yes],\n          [gl_cv_func_mbrtowc_sanitycheck=no],\n          [:])\n      fi\n    ])\n])\n\ndnl Test whether mbrtowc supports a NULL pwc argument correctly.\ndnl Result is gl_cv_func_mbrtowc_null_arg1.\n\nAC_DEFUN([gl_MBRTOWC_NULL_ARG1],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([gt_LOCALE_FR_UTF8])\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument],\n    [gl_cv_func_mbrtowc_null_arg1],\n    [\n      dnl Initial guess, used when cross-compiling or when no suitable locale\n      dnl is present.\nchangequote(,)dnl\n      case \"$host_os\" in\n                  # Guess no on Solaris.\n        solaris*) gl_cv_func_mbrtowc_null_arg1=\"guessing no\" ;;\n                  # Guess yes otherwise.\n        *)        gl_cv_func_mbrtowc_null_arg1=\"guessing yes\" ;;\n      esac\nchangequote([,])dnl\n      if test $LOCALE_FR_UTF8 != none; then\n        AC_RUN_IFELSE(\n          [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <stdlib.h>\n#include <string.h>\n#include <wchar.h>\nint main ()\n{\n  int result = 0;\n\n  if (setlocale (LC_ALL, \"$LOCALE_FR_UTF8\") != NULL)\n    {\n      char input[] = \"\\303\\237er\";\n      mbstate_t state;\n      wchar_t wc;\n      size_t ret;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      wc = (wchar_t) 0xBADFACE;\n      ret = mbrtowc (&wc, input, 5, &state);\n      if (ret != 2)\n        result |= 1;\n      if (!mbsinit (&state))\n        result |= 2;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      ret = mbrtowc (NULL, input, 5, &state);\n      if (ret != 2) /* Solaris 7 fails here: ret is -1.  */\n        result |= 4;\n      if (!mbsinit (&state))\n        result |= 8;\n    }\n  return result;\n}]])],\n          [gl_cv_func_mbrtowc_null_arg1=yes],\n          [gl_cv_func_mbrtowc_null_arg1=no],\n          [:])\n      fi\n    ])\n])\n\ndnl Test whether mbrtowc supports a NULL string argument correctly.\ndnl Result is gl_cv_func_mbrtowc_null_arg2.\n\nAC_DEFUN([gl_MBRTOWC_NULL_ARG2],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([gt_LOCALE_FR_UTF8])\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument],\n    [gl_cv_func_mbrtowc_null_arg2],\n    [\n      dnl Initial guess, used when cross-compiling or when no suitable locale\n      dnl is present.\nchangequote(,)dnl\n      case \"$host_os\" in\n              # Guess no on OSF/1.\n        osf*) gl_cv_func_mbrtowc_null_arg2=\"guessing no\" ;;\n              # Guess yes otherwise.\n        *)    gl_cv_func_mbrtowc_null_arg2=\"guessing yes\" ;;\n      esac\nchangequote([,])dnl\n      if test $LOCALE_FR_UTF8 != none; then\n        AC_RUN_IFELSE(\n          [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <string.h>\n#include <wchar.h>\nint main ()\n{\n  if (setlocale (LC_ALL, \"$LOCALE_FR_UTF8\") != NULL)\n    {\n      mbstate_t state;\n      wchar_t wc;\n      int ret;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      wc = (wchar_t) 0xBADFACE;\n      mbrtowc (&wc, NULL, 5, &state);\n      /* Check that wc was not modified.  */\n      if (wc != (wchar_t) 0xBADFACE)\n        return 2;\n    }\n  return 0;\n}]])],\n          [gl_cv_func_mbrtowc_null_arg2=yes],\n          [gl_cv_func_mbrtowc_null_arg2=no],\n          [:])\n      fi\n    ])\n])\n\ndnl Test whether mbrtowc, when parsing the end of a multibyte character,\ndnl correctly returns the number of bytes that were needed to complete the\ndnl character (not the total number of bytes of the multibyte character).\ndnl Result is gl_cv_func_mbrtowc_retval.\n\nAC_DEFUN([gl_MBRTOWC_RETVAL],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([gt_LOCALE_FR_UTF8])\n  AC_REQUIRE([gt_LOCALE_JA])\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_CACHE_CHECK([whether mbrtowc has a correct return value],\n    [gl_cv_func_mbrtowc_retval],\n    [\n      dnl Initial guess, used when cross-compiling or when no suitable locale\n      dnl is present.\nchangequote(,)dnl\n      case \"$host_os\" in\n                                   # Guess no on HP-UX, Solaris, native Windows.\n        hpux* | solaris* | mingw*) gl_cv_func_mbrtowc_retval=\"guessing no\" ;;\n                                   # Guess yes otherwise.\n        *)                         gl_cv_func_mbrtowc_retval=\"guessing yes\" ;;\n      esac\nchangequote([,])dnl\n      if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none \\\n         || { case \"$host_os\" in mingw*) true;; *) false;; esac; }; then\n        AC_RUN_IFELSE(\n          [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <string.h>\n#include <wchar.h>\nint main ()\n{\n  int result = 0;\n  int found_some_locale = 0;\n  /* This fails on Solaris.  */\n  if (setlocale (LC_ALL, \"$LOCALE_FR_UTF8\") != NULL)\n    {\n      char input[] = \"B\\303\\274\\303\\237er\"; /* \"Büßer\" */\n      mbstate_t state;\n      wchar_t wc;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))\n        {\n          input[1] = '\\0';\n          if (mbrtowc (&wc, input + 2, 5, &state) != 1)\n            result |= 1;\n        }\n      found_some_locale = 1;\n    }\n  /* This fails on HP-UX 11.11.  */\n  if (setlocale (LC_ALL, \"$LOCALE_JA\") != NULL)\n    {\n      char input[] = \"B\\217\\253\\344\\217\\251\\316er\"; /* \"Büßer\" */\n      mbstate_t state;\n      wchar_t wc;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))\n        {\n          input[1] = '\\0';\n          if (mbrtowc (&wc, input + 2, 5, &state) != 2)\n            result |= 2;\n        }\n      found_some_locale = 1;\n    }\n  /* This fails on native Windows.  */\n  if (setlocale (LC_ALL, \"Japanese_Japan.932\") != NULL)\n    {\n      char input[] = \"<\\223\\372\\226\\173\\214\\352>\"; /* \"<日本語>\" */\n      mbstate_t state;\n      wchar_t wc;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))\n        {\n          input[3] = '\\0';\n          if (mbrtowc (&wc, input + 4, 4, &state) != 1)\n            result |= 4;\n        }\n      found_some_locale = 1;\n    }\n  if (setlocale (LC_ALL, \"Chinese_Taiwan.950\") != NULL)\n    {\n      char input[] = \"<\\244\\351\\245\\273\\273\\171>\"; /* \"<日本語>\" */\n      mbstate_t state;\n      wchar_t wc;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))\n        {\n          input[3] = '\\0';\n          if (mbrtowc (&wc, input + 4, 4, &state) != 1)\n            result |= 8;\n        }\n      found_some_locale = 1;\n    }\n  if (setlocale (LC_ALL, \"Chinese_China.936\") != NULL)\n    {\n      char input[] = \"<\\310\\325\\261\\276\\325\\132>\"; /* \"<日本語>\" */\n      mbstate_t state;\n      wchar_t wc;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2))\n        {\n          input[3] = '\\0';\n          if (mbrtowc (&wc, input + 4, 4, &state) != 1)\n            result |= 16;\n        }\n      found_some_locale = 1;\n    }\n  return (found_some_locale ? result : 77);\n}]])],\n          [gl_cv_func_mbrtowc_retval=yes],\n          [if test $? != 77; then\n             gl_cv_func_mbrtowc_retval=no\n           fi\n          ],\n          [:])\n      fi\n    ])\n])\n\ndnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0.\ndnl Result is gl_cv_func_mbrtowc_nul_retval.\n\nAC_DEFUN([gl_MBRTOWC_NUL_RETVAL],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([gt_LOCALE_ZH_CN])\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character],\n    [gl_cv_func_mbrtowc_nul_retval],\n    [\n      dnl Initial guess, used when cross-compiling or when no suitable locale\n      dnl is present.\nchangequote(,)dnl\n      case \"$host_os\" in\n                       # Guess no on Solaris 8 and 9.\n        solaris2.[89]) gl_cv_func_mbrtowc_nul_retval=\"guessing no\" ;;\n                       # Guess yes otherwise.\n        *)             gl_cv_func_mbrtowc_nul_retval=\"guessing yes\" ;;\n      esac\nchangequote([,])dnl\n      if test $LOCALE_ZH_CN != none; then\n        AC_RUN_IFELSE(\n          [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <string.h>\n#include <wchar.h>\nint main ()\n{\n  /* This fails on Solaris 8 and 9.  */\n  if (setlocale (LC_ALL, \"$LOCALE_ZH_CN\") != NULL)\n    {\n      mbstate_t state;\n      wchar_t wc;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, \"\", 1, &state) != 0)\n        return 2;\n    }\n  return 0;\n}]])],\n          [gl_cv_func_mbrtowc_nul_retval=yes],\n          [gl_cv_func_mbrtowc_nul_retval=no],\n          [:])\n      fi\n    ])\n])\n\ndnl Test whether mbrtowc stores a wide character when reporting incomplete\ndnl input.\n\nAC_DEFUN([gl_MBRTOWC_STORES_INCOMPLETE],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_CACHE_CHECK([whether mbrtowc stores incomplete characters],\n    [gl_cv_func_mbrtowc_stores_incomplete],\n    [\n     dnl Initial guess, used when cross-compiling or when no suitable locale\n     dnl is present.\nchangequote(,)dnl\n     case \"$host_os\" in\n               # Guess yes on native Windows.\n       mingw*) gl_cv_func_mbrtowc_stores_incomplete=\"guessing yes\" ;;\n       *)      gl_cv_func_mbrtowc_stores_incomplete=\"guessing no\" ;;\n     esac\nchangequote([,])dnl\n     case \"$host_os\" in\n       mingw*)\n         AC_RUN_IFELSE(\n           [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <string.h>\n#include <wchar.h>\nint main ()\n{\n  int result = 0;\n  if (setlocale (LC_ALL, \"French_France.65001\") != NULL)\n    {\n      wchar_t wc = (wchar_t) 0xBADFACE;\n      mbstate_t state;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, \"\\303\", 1, &state) == (size_t)(-2)\n          && wc != (wchar_t) 0xBADFACE)\n        result |= 1;\n    }\n  if (setlocale (LC_ALL, \"Japanese_Japan.932\") != NULL)\n    {\n      wchar_t wc = (wchar_t) 0xBADFACE;\n      mbstate_t state;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, \"\\226\", 1, &state) == (size_t)(-2)\n          && wc != (wchar_t) 0xBADFACE)\n        result |= 2;\n    }\n  if (setlocale (LC_ALL, \"Chinese_Taiwan.950\") != NULL)\n    {\n      wchar_t wc = (wchar_t) 0xBADFACE;\n      mbstate_t state;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, \"\\245\", 1, &state) == (size_t)(-2)\n          && wc != (wchar_t) 0xBADFACE)\n        result |= 4;\n    }\n  if (setlocale (LC_ALL, \"Chinese_China.936\") != NULL)\n    {\n      wchar_t wc = (wchar_t) 0xBADFACE;\n      mbstate_t state;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, \"\\261\", 1, &state) == (size_t)(-2)\n          && wc != (wchar_t) 0xBADFACE)\n        result |= 8;\n    }\n  return result;\n}]])],\n           [gl_cv_func_mbrtowc_stores_incomplete=no],\n           [gl_cv_func_mbrtowc_stores_incomplete=yes],\n           [:])\n         ;;\n       *)\n         AC_REQUIRE([gt_LOCALE_FR_UTF8])\n         if test $LOCALE_FR_UTF8 != none; then\n           AC_RUN_IFELSE(\n             [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <string.h>\n#include <wchar.h>\nint main ()\n{\n  if (setlocale (LC_ALL, \"$LOCALE_FR_UTF8\") != NULL)\n    {\n      wchar_t wc = (wchar_t) 0xBADFACE;\n      mbstate_t state;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (&wc, \"\\303\", 1, &state) == (size_t)(-2)\n          && wc != (wchar_t) 0xBADFACE)\n        return 1;\n    }\n  return 0;\n}]])],\n             [gl_cv_func_mbrtowc_stores_incomplete=no],\n             [gl_cv_func_mbrtowc_stores_incomplete=yes],\n             [:])\n         fi\n         ;;\n     esac\n    ])\n])\n\ndnl Test whether mbrtowc returns the correct value on empty input.\n\nAC_DEFUN([gl_MBRTOWC_EMPTY_INPUT],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_CACHE_CHECK([whether mbrtowc works on empty input],\n    [gl_cv_func_mbrtowc_empty_input],\n    [\n      dnl Initial guess, used when cross-compiling or when no suitable locale\n      dnl is present.\nchangequote(,)dnl\n      case \"$host_os\" in\n                              # Guess no on AIX and glibc systems.\n        aix* | *-gnu* | gnu*) gl_cv_func_mbrtowc_empty_input=\"guessing no\" ;;\n                              # Guess yes on native Windows.\n        mingw*)               gl_cv_func_mbrtowc_empty_input=\"guessing yes\" ;;\n        *)                    gl_cv_func_mbrtowc_empty_input=\"guessing yes\" ;;\n      esac\nchangequote([,])dnl\n      AC_RUN_IFELSE(\n        [AC_LANG_SOURCE([[\n           #include <wchar.h>\n           static wchar_t wc;\n           static mbstate_t mbs;\n           int\n           main (void)\n           {\n             return mbrtowc (&wc, \"\", 0, &mbs) != (size_t) -2;\n           }]])],\n        [gl_cv_func_mbrtowc_empty_input=yes],\n        [gl_cv_func_mbrtowc_empty_input=no],\n        [:])\n    ])\n])\n\ndnl Test whether mbrtowc reports encoding errors in the C locale.\ndnl Although POSIX was never intended to allow this, the GNU C Library\ndnl and other implementations do it.  See:\ndnl https://sourceware.org/bugzilla/show_bug.cgi?id=19932\n\nAC_DEFUN([gl_MBRTOWC_C_LOCALE],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_CACHE_CHECK([whether the C locale is free of encoding errors],\n    [gl_cv_func_mbrtowc_C_locale_sans_EILSEQ],\n    [\n     dnl Initial guess, used when cross-compiling or when no suitable locale\n     dnl is present.\n     gl_cv_func_mbrtowc_C_locale_sans_EILSEQ=\"$gl_cross_guess_normal\"\n\n     AC_RUN_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <limits.h>\n            #include <locale.h>\n            #include <wchar.h>\n          ]], [[\n            int i;\n            char *locale = setlocale (LC_ALL, \"C\");\n            if (! locale)\n              return 2;\n            for (i = CHAR_MIN; i <= CHAR_MAX; i++)\n              {\n                char c = i;\n                wchar_t wc;\n                mbstate_t mbs = { 0, };\n                size_t ss = mbrtowc (&wc, &c, 1, &mbs);\n                if (1 < ss)\n                  return 3;\n              }\n            return 0;\n          ]])],\n      [gl_cv_func_mbrtowc_C_locale_sans_EILSEQ=yes],\n      [gl_cv_func_mbrtowc_C_locale_sans_EILSEQ=no],\n      [case \"$host_os\" in\n                 # Guess yes on native Windows.\n         mingw*) gl_cv_func_mbrtowc_C_locale_sans_EILSEQ=\"guessing yes\" ;;\n       esac\n      ])\n    ])\n])\n\n# Prerequisites of lib/mbrtowc.c and lib/lc-charset-dispatch.c.\nAC_DEFUN([gl_PREREQ_MBRTOWC], [\n  AC_REQUIRE([AC_C_INLINE])\n  :\n])\n\n# Prerequisites of lib/mbtowc-lock.c.\nAC_DEFUN([gl_PREREQ_MBTOWC_LOCK],\n[\n  gl_VISIBILITY\n])\n\n\ndnl From Paul Eggert\n\ndnl This is an override of an autoconf macro.\n\nAC_DEFUN([AC_FUNC_MBRTOWC],\n[\n  dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60.\n  AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared],\n    [gl_cv_func_mbrtowc],\n    [AC_LINK_IFELSE(\n       [AC_LANG_PROGRAM(\n            [[#include <wchar.h>]],\n            [[wchar_t wc;\n              char const s[] = \"\";\n              size_t n = 1;\n              mbstate_t state;\n              return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])],\n       [gl_cv_func_mbrtowc=yes],\n       [gl_cv_func_mbrtowc=no])])\n  if test $gl_cv_func_mbrtowc = yes; then\n    AC_DEFINE([HAVE_MBRTOWC], [1],\n      [Define to 1 if mbrtowc and mbstate_t are properly declared.])\n  fi\n])\n"
  },
  {
    "path": "m4/mbsinit.m4",
    "content": "# mbsinit.m4 serial 9\ndnl Copyright (C) 2008, 2010-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_MBSINIT],\n[\n  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])\n  AC_REQUIRE([AC_CANONICAL_HOST])\n\n  AC_REQUIRE([AC_TYPE_MBSTATE_T])\n  gl_MBSTATE_T_BROKEN\n\n  AC_CHECK_FUNCS_ONCE([mbsinit])\n  if test $ac_cv_func_mbsinit = no; then\n    HAVE_MBSINIT=0\n    AC_CHECK_DECLS([mbsinit],,, [[\n      #include <wchar.h>\n    ]])\n    if test $ac_cv_have_decl_mbsinit = yes; then\n      dnl On Minix 3.1.8, the system's <wchar.h> declares mbsinit() although\n      dnl it does not have the function. Avoid a collision with gnulib's\n      dnl replacement.\n      REPLACE_MBSINIT=1\n    fi\n  else\n    if test $REPLACE_MBSTATE_T = 1; then\n      REPLACE_MBSINIT=1\n    else\n      dnl On mingw, mbsinit() always returns 1, which is inappropriate for\n      dnl states produced by mbrtowc() for an incomplete multibyte character\n      dnl in multibyte locales.\n      case \"$host_os\" in\n        mingw*) REPLACE_MBSINIT=1 ;;\n      esac\n    fi\n  fi\n])\n\n# Prerequisites of lib/mbsinit.c.\nAC_DEFUN([gl_PREREQ_MBSINIT], [\n  :\n])\n"
  },
  {
    "path": "m4/mbsrtowcs.m4",
    "content": "# mbsrtowcs.m4 serial 14\ndnl Copyright (C) 2008-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_MBSRTOWCS],\n[\n  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])\n\n  AC_REQUIRE([AC_TYPE_MBSTATE_T])\n  gl_MBSTATE_T_BROKEN\n\n  AC_CHECK_FUNCS_ONCE([mbsrtowcs])\n  if test $ac_cv_func_mbsrtowcs = no; then\n    HAVE_MBSRTOWCS=0\n    AC_CHECK_DECLS([mbsrtowcs],,, [[\n      #include <wchar.h>\n    ]])\n    if test $ac_cv_have_decl_mbsrtowcs = yes; then\n      dnl On Minix 3.1.8, the system's <wchar.h> declares mbsrtowcs() although\n      dnl it does not have the function. Avoid a collision with gnulib's\n      dnl replacement.\n      REPLACE_MBSRTOWCS=1\n    fi\n  else\n    if test $REPLACE_MBSTATE_T = 1; then\n      REPLACE_MBSRTOWCS=1\n    else\n      gl_MBSRTOWCS_WORKS\n      case \"$gl_cv_func_mbsrtowcs_works\" in\n        *yes) ;;\n        *) REPLACE_MBSRTOWCS=1 ;;\n      esac\n    fi\n  fi\n])\n\ndnl Test whether mbsrtowcs works.\ndnl Result is gl_cv_func_mbsrtowcs_works.\n\nAC_DEFUN([gl_MBSRTOWCS_WORKS],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([gt_LOCALE_FR])\n  AC_REQUIRE([gt_LOCALE_FR_UTF8])\n  AC_REQUIRE([gt_LOCALE_JA])\n  AC_REQUIRE([gt_LOCALE_ZH_CN])\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_CACHE_CHECK([whether mbsrtowcs works],\n    [gl_cv_func_mbsrtowcs_works],\n    [\n      dnl Initial guess, used when cross-compiling or when no suitable locale\n      dnl is present.\nchangequote(,)dnl\n      case \"$host_os\" in\n                                   # Guess no on HP-UX, Solaris, mingw.\n        hpux* | solaris* | mingw*) gl_cv_func_mbsrtowcs_works=\"guessing no\" ;;\n                                   # Guess yes otherwise.\n        *)                         gl_cv_func_mbsrtowcs_works=\"guessing yes\" ;;\n      esac\nchangequote([,])dnl\n      if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then\n        AC_RUN_IFELSE(\n          [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <string.h>\n#include <wchar.h>\nint main ()\n{\n  int result = 0;\n  /* Test whether the function supports a NULL destination argument.\n     This fails on native Windows.  */\n  if (setlocale (LC_ALL, \"$LOCALE_FR\") != NULL)\n    {\n      const char input[] = \"\\337er\";\n      const char *src = input;\n      mbstate_t state;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbsrtowcs (NULL, &src, 1, &state) != 3\n          || src != input)\n        result |= 1;\n    }\n  /* Test whether the function works when started with a conversion state\n     in non-initial state.  This fails on HP-UX 11.11 and Solaris 10.  */\n  if (setlocale (LC_ALL, \"$LOCALE_FR_UTF8\") != NULL)\n    {\n      const char input[] = \"B\\303\\274\\303\\237er\";\n      mbstate_t state;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (NULL, input + 1, 1, &state) == (size_t)(-2))\n        if (!mbsinit (&state))\n          {\n            const char *src = input + 2;\n            if (mbsrtowcs (NULL, &src, 10, &state) != 4)\n              result |= 2;\n          }\n    }\n  if (setlocale (LC_ALL, \"$LOCALE_JA\") != NULL)\n    {\n      const char input[] = \"<\\306\\374\\313\\334\\270\\354>\";\n      mbstate_t state;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (NULL, input + 3, 1, &state) == (size_t)(-2))\n        if (!mbsinit (&state))\n          {\n            const char *src = input + 4;\n            if (mbsrtowcs (NULL, &src, 10, &state) != 3)\n              result |= 4;\n          }\n    }\n  if (setlocale (LC_ALL, \"$LOCALE_ZH_CN\") != NULL)\n    {\n      const char input[] = \"B\\250\\271\\201\\060\\211\\070er\";\n      mbstate_t state;\n\n      memset (&state, '\\0', sizeof (mbstate_t));\n      if (mbrtowc (NULL, input + 1, 1, &state) == (size_t)(-2))\n        if (!mbsinit (&state))\n          {\n            const char *src = input + 2;\n            if (mbsrtowcs (NULL, &src, 10, &state) != 4)\n              result |= 8;\n          }\n    }\n  return result;\n}]])],\n          [gl_cv_func_mbsrtowcs_works=yes],\n          [gl_cv_func_mbsrtowcs_works=no],\n          [:])\n      fi\n    ])\n])\n\n# Prerequisites of lib/mbsrtowcs.c.\nAC_DEFUN([gl_PREREQ_MBSRTOWCS], [\n  :\n])\n"
  },
  {
    "path": "m4/mbstate_t.m4",
    "content": "# mbstate_t.m4 serial 14\ndnl Copyright (C) 2000-2002, 2008-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\n# From Paul Eggert.\n\n# BeOS 5 has <wchar.h> but does not define mbstate_t,\n# so you can't declare an object of that type.\n# Check for this incompatibility with Standard C.\n\n# AC_TYPE_MBSTATE_T\n# -----------------\nAC_DEFUN([AC_TYPE_MBSTATE_T],\n[\n   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) dnl for HP-UX 11.11\n\n   AC_CACHE_CHECK([for mbstate_t], [ac_cv_type_mbstate_t],\n     [AC_COMPILE_IFELSE(\n        [AC_LANG_PROGRAM(\n           [AC_INCLUDES_DEFAULT[\n             #include <wchar.h>]],\n           [[mbstate_t x; return sizeof x;]])],\n        [ac_cv_type_mbstate_t=yes],\n        [ac_cv_type_mbstate_t=no])])\n   if test $ac_cv_type_mbstate_t = yes; then\n     AC_DEFINE([HAVE_MBSTATE_T], [1],\n               [Define to 1 if <wchar.h> declares mbstate_t.])\n   else\n     AC_DEFINE([mbstate_t], [int],\n               [Define to a type if <wchar.h> does not define.])\n   fi\n])\n"
  },
  {
    "path": "m4/mbtowc.m4",
    "content": "# mbtowc.m4 serial 3\ndnl Copyright (C) 2011-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_MBTOWC],\n[\n  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])\n\n  AC_CHECK_FUNCS([mbtowc])\n  if test $ac_cv_func_mbtowc = no; then\n    HAVE_MBTOWC=0\n  else\n    if false; then\n      REPLACE_MBTOWC=1\n    fi\n  fi\n])\n\n# Prerequisites of lib/mbtowc.c.\nAC_DEFUN([gl_PREREQ_MBTOWC], [\n  :\n])\n"
  },
  {
    "path": "m4/memchr.m4",
    "content": "# memchr.m4 serial 18\ndnl Copyright (C) 2002-2004, 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN_ONCE([gl_FUNC_MEMCHR],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n\n  dnl Check for prerequisites for memory fence checks.\n  gl_FUNC_MMAP_ANON\n  AC_CHECK_HEADERS_ONCE([sys/mman.h])\n  AC_CHECK_FUNCS_ONCE([mprotect])\n\n  AC_REQUIRE([gl_STRING_H_DEFAULTS])\n  # Detect platform-specific bugs in some versions of glibc:\n  # memchr should not dereference anything with length 0\n  #   https://bugzilla.redhat.com/show_bug.cgi?id=499689\n  # memchr should not dereference overestimated length after a match\n  #   https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737\n  #   https://sourceware.org/bugzilla/show_bug.cgi?id=10162\n  # memchr should cast the second argument to 'unsigned char'.\n  #   This bug exists in Android 4.3.\n  # Assume that memchr works on platforms that lack mprotect.\n  AC_CACHE_CHECK([whether memchr works], [gl_cv_func_memchr_works],\n    [AC_RUN_IFELSE([AC_LANG_PROGRAM([[\n#include <string.h>\n#if HAVE_SYS_MMAN_H\n# include <fcntl.h>\n# include <unistd.h>\n# include <sys/types.h>\n# include <sys/mman.h>\n# ifndef MAP_FILE\n#  define MAP_FILE 0\n# endif\n#endif\n]], [[\n  int result = 0;\n  char *fence = NULL;\n#if HAVE_SYS_MMAN_H && HAVE_MPROTECT\n# if HAVE_MAP_ANONYMOUS\n  const int flags = MAP_ANONYMOUS | MAP_PRIVATE;\n  const int fd = -1;\n# else /* !HAVE_MAP_ANONYMOUS */\n  const int flags = MAP_FILE | MAP_PRIVATE;\n  int fd = open (\"/dev/zero\", O_RDONLY, 0666);\n  if (fd >= 0)\n# endif\n    {\n      int pagesize = getpagesize ();\n      char *two_pages =\n        (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE,\n                       flags, fd, 0);\n      if (two_pages != (char *)(-1)\n          && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0)\n        fence = two_pages + pagesize;\n    }\n#endif\n  if (fence)\n    {\n      /* Test against bugs on glibc systems.  */\n      if (memchr (fence, 0, 0))\n        result |= 1;\n      strcpy (fence - 9, \"12345678\");\n      if (memchr (fence - 9, 0, 79) != fence - 1)\n        result |= 2;\n      if (memchr (fence - 1, 0, 3) != fence - 1)\n        result |= 4;\n      /* Test against bug on AIX 7.2.  */\n      if (memchr (fence - 4, '6', 16) != fence - 4)\n        result |= 8;\n    }\n  /* Test against bug on Android 4.3.  */\n  {\n    char input[3];\n    input[0] = 'a';\n    input[1] = 'b';\n    input[2] = 'c';\n    if (memchr (input, 0x789abc00 | 'b', 3) != input + 1)\n      result |= 16;\n  }\n  return result;\n]])],\n       [gl_cv_func_memchr_works=yes],\n       [gl_cv_func_memchr_works=no],\n       [case \"$host_os\" in\n                           # Guess no on Android.\n          linux*-android*) gl_cv_func_memchr_works=\"guessing no\" ;;\n                           # Guess yes on native Windows.\n          mingw*)          gl_cv_func_memchr_works=\"guessing yes\" ;;\n                           # If we don't know, obey --enable-cross-guesses.\n          *)               gl_cv_func_memchr_works=\"$gl_cross_guess_normal\" ;;\n        esac\n       ])\n    ])\n  case \"$gl_cv_func_memchr_works\" in\n    *yes) ;;\n    *) REPLACE_MEMCHR=1 ;;\n  esac\n])\n\n# Prerequisites of lib/memchr.c.\nAC_DEFUN([gl_PREREQ_MEMCHR], [\n  AC_CHECK_HEADERS([bp-sym.h])\n])\n"
  },
  {
    "path": "m4/mempcpy.m4",
    "content": "# mempcpy.m4 serial 12\ndnl Copyright (C) 2003-2004, 2006-2007, 2009-2021 Free Software Foundation,\ndnl Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_MEMPCPY],\n[\n  dnl Persuade glibc <string.h> to declare mempcpy().\n  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])\n\n  dnl The mempcpy() declaration in lib/string.in.h uses 'restrict'.\n  AC_REQUIRE([AC_C_RESTRICT])\n\n  AC_REQUIRE([gl_STRING_H_DEFAULTS])\n  AC_CHECK_FUNCS([mempcpy])\n  if test $ac_cv_func_mempcpy = no; then\n    HAVE_MEMPCPY=0\n  fi\n])\n\n# Prerequisites of lib/mempcpy.c.\nAC_DEFUN([gl_PREREQ_MEMPCPY], [\n  :\n])\n"
  },
  {
    "path": "m4/mmap-anon.m4",
    "content": "# mmap-anon.m4 serial 12\ndnl Copyright (C) 2005, 2007, 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\n# Detect how mmap can be used to create anonymous (not file-backed) memory\n# mappings.\n# - On Linux, AIX, OSF/1, Solaris, Cygwin, Interix, Haiku, both MAP_ANONYMOUS\n#   and MAP_ANON exist and have the same value.\n# - On HP-UX, only MAP_ANONYMOUS exists.\n# - On Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, only MAP_ANON exists.\n# - On IRIX, neither exists, and a file descriptor opened to /dev/zero must be\n#   used.\n\nAC_DEFUN_ONCE([gl_FUNC_MMAP_ANON],\n[\n  dnl Persuade glibc <sys/mman.h> to define MAP_ANONYMOUS.\n  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])\n\n  # Check for mmap(). Don't use AC_FUNC_MMAP, because it checks too much: it\n  # fails on HP-UX 11, because MAP_FIXED mappings do not work. But this is\n  # irrelevant for anonymous mappings.\n  AC_CHECK_FUNC([mmap], [gl_have_mmap=yes], [gl_have_mmap=no])\n\n  # Try to allow MAP_ANONYMOUS.\n  gl_have_mmap_anonymous=no\n  if test $gl_have_mmap = yes; then\n    AC_MSG_CHECKING([for MAP_ANONYMOUS])\n    AC_EGREP_CPP([I cannot identify this map], [\n#include <sys/mman.h>\n#ifdef MAP_ANONYMOUS\n    I cannot identify this map\n#endif\n],\n      [gl_have_mmap_anonymous=yes])\n    if test $gl_have_mmap_anonymous != yes; then\n      AC_EGREP_CPP([I cannot identify this map], [\n#include <sys/mman.h>\n#ifdef MAP_ANON\n    I cannot identify this map\n#endif\n],\n        [AC_DEFINE([MAP_ANONYMOUS], [MAP_ANON],\n          [Define to a substitute value for mmap()'s MAP_ANONYMOUS flag.])\n         gl_have_mmap_anonymous=yes])\n    fi\n    AC_MSG_RESULT([$gl_have_mmap_anonymous])\n    if test $gl_have_mmap_anonymous = yes; then\n      AC_DEFINE([HAVE_MAP_ANONYMOUS], [1],\n        [Define to 1 if mmap()'s MAP_ANONYMOUS flag is available after including\n         config.h and <sys/mman.h>.])\n    fi\n  fi\n])\n"
  },
  {
    "path": "m4/multiarch.m4",
    "content": "# multiarch.m4 serial 9\ndnl Copyright (C) 2008-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\n# Determine whether the compiler is or may be producing universal binaries.\n#\n# On Mac OS X 10.5 and later systems, the user can create libraries and\n# executables that work on multiple system types--known as \"fat\" or\n# \"universal\" binaries--by specifying multiple '-arch' options to the\n# compiler but only a single '-arch' option to the preprocessor.  Like\n# this:\n#\n#     ./configure CC=\"gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64\" \\\n#                 CXX=\"g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64\" \\\n#                 CPP=\"gcc -E\" CXXCPP=\"g++ -E\"\n#\n# Detect this situation and set APPLE_UNIVERSAL_BUILD accordingly.\n\nAC_DEFUN_ONCE([gl_MULTIARCH],\n[\n  dnl Code similar to autoconf-2.63 AC_C_BIGENDIAN.\n  AC_CACHE_CHECK([whether the compiler produces multi-arch binaries],\n    [gl_cv_c_multiarch],\n    [gl_cv_c_multiarch=no\n     AC_COMPILE_IFELSE(\n       [AC_LANG_SOURCE(\n         [[#ifndef __APPLE_CC__\n            not a universal capable compiler\n           #endif\n           typedef int dummy;\n         ]])],\n       [\n        dnl Check for potential -arch flags.  It is not universal unless\n        dnl there are at least two -arch flags with different values.\n        arch=\n        prev=\n        for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do\n          if test -n \"$prev\"; then\n            case $word in\n              i?86 | x86_64 | ppc | ppc64 | arm | arm64)\n                if test -z \"$arch\" || test \"$arch\" = \"$word\"; then\n                  arch=\"$word\"\n                else\n                  gl_cv_c_multiarch=yes\n                fi\n                ;;\n            esac\n            prev=\n          else\n            if test \"x$word\" = \"x-arch\"; then\n              prev=arch\n            fi\n          fi\n        done\n       ])\n    ])\n  if test $gl_cv_c_multiarch = yes; then\n    APPLE_UNIVERSAL_BUILD=1\n  else\n    APPLE_UNIVERSAL_BUILD=0\n  fi\n  AC_SUBST([APPLE_UNIVERSAL_BUILD])\n])\n"
  },
  {
    "path": "m4/nl_langinfo.m4",
    "content": "# nl_langinfo.m4 serial 8\ndnl Copyright (C) 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_NL_LANGINFO],\n[\n  AC_REQUIRE([gl_LANGINFO_H_DEFAULTS])\n  AC_REQUIRE([gl_LANGINFO_H])\n  AC_CHECK_FUNCS_ONCE([nl_langinfo])\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_REQUIRE([gl_FUNC_SETLOCALE_NULL])\n  AC_REQUIRE([gl_PTHREADLIB])\n  AC_CHECK_HEADERS_ONCE([threads.h])\n  if test $ac_cv_func_nl_langinfo = yes; then\n    # On Irix 6.5, YESEXPR is defined, but nl_langinfo(YESEXPR) is broken.\n    AC_CACHE_CHECK([whether YESEXPR works],\n      [gl_cv_func_nl_langinfo_yesexpr_works],\n      [AC_RUN_IFELSE(\n         [AC_LANG_PROGRAM([[#include <langinfo.h>\n]], [[return !*nl_langinfo(YESEXPR);\n]])],\n         [gl_cv_func_nl_langinfo_yesexpr_works=yes],\n         [gl_cv_func_nl_langinfo_yesexpr_works=no],\n         [\n         case \"$host_os\" in\n                   # Guess no on irix systems.\n           irix*)  gl_cv_func_nl_langinfo_yesexpr_works=\"guessing no\";;\n                   # Guess yes elsewhere.\n           *)      gl_cv_func_nl_langinfo_yesexpr_works=\"guessing yes\";;\n         esac\n         ])\n      ])\n    case $gl_cv_func_nl_langinfo_yesexpr_works in\n      *yes) FUNC_NL_LANGINFO_YESEXPR_WORKS=1 ;;\n      *)    FUNC_NL_LANGINFO_YESEXPR_WORKS=0 ;;\n    esac\n    AC_DEFINE_UNQUOTED([FUNC_NL_LANGINFO_YESEXPR_WORKS],\n      [$FUNC_NL_LANGINFO_YESEXPR_WORKS],\n      [Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string.])\n    # On Solaris 10 and Solaris 11.3, nl_langinfo is not multithread-safe.\n    case \"$host_os\" in\n      solaris*) NL_LANGINFO_MTSAFE=0 ;;\n      *)        NL_LANGINFO_MTSAFE=1 ;;\n    esac\n    AC_DEFINE_UNQUOTED([NL_LANGINFO_MTSAFE], [$NL_LANGINFO_MTSAFE],\n      [Define to 1 if nl_langinfo is multithread-safe.])\n    if test $HAVE_LANGINFO_CODESET = 1 \\\n       && test $HAVE_LANGINFO_T_FMT_AMPM = 1 \\\n       && test $HAVE_LANGINFO_ALTMON = 1 \\\n       && test $HAVE_LANGINFO_ERA = 1 \\\n       && test $FUNC_NL_LANGINFO_YESEXPR_WORKS = 1 \\\n       && test $NL_LANGINFO_MTSAFE = 1; then\n      :\n    else\n      REPLACE_NL_LANGINFO=1\n      AC_DEFINE([REPLACE_NL_LANGINFO], [1],\n        [Define if nl_langinfo exists but is overridden by gnulib.])\n    fi\n  else\n    HAVE_NL_LANGINFO=0\n  fi\n  if test $HAVE_NL_LANGINFO = 0 || test $HAVE_LANGINFO_CODESET = 0; then\n    LIB_NL_LANGINFO=\"$LIB_SETLOCALE_NULL\"\n  else\n    LIB_NL_LANGINFO=\n  fi\n  dnl LIB_NL_LANGINFO is expected to be empty everywhere.\n  AC_SUBST([LIB_NL_LANGINFO])\n])\n\n# Prerequisites of lib/nl_langinfo-lock.c.\nAC_DEFUN([gl_PREREQ_NL_LANGINFO_LOCK],\n[\n  gl_VISIBILITY\n])\n"
  },
  {
    "path": "m4/off_t.m4",
    "content": "# off_t.m4 serial 1\ndnl Copyright (C) 2012-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl Check whether to override the 'off_t' type.\ndnl Set WINDOWS_64_BIT_OFF_T.\n\nAC_DEFUN([gl_TYPE_OFF_T],\n[\n  m4_ifdef([gl_LARGEFILE], [\n    AC_REQUIRE([gl_LARGEFILE])\n  ], [\n    WINDOWS_64_BIT_OFF_T=0\n  ])\n  AC_SUBST([WINDOWS_64_BIT_OFF_T])\n])\n"
  },
  {
    "path": "m4/pid_t.m4",
    "content": "# pid_t.m4 serial 4\ndnl Copyright (C) 2020-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\n# The following implementation works around a problem in autoconf <= 2.69.\nm4_version_prereq([2.70], [], [\n\ndnl Define pid_t if the headers don't define it.\nAC_DEFUN([AC_TYPE_PID_T],\n[\n  AC_CHECK_TYPE([pid_t],\n    [],\n    [dnl On 64-bit native Windows, define it to the equivalent of 'intptr_t'\n     dnl (= 'long long' = '__int64'), because that is the return type\n     dnl of the _spawnv* functions\n     dnl <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/spawnvp-wspawnvp>\n     dnl and the argument type of the _cwait function\n     dnl <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/cwait>.\n     dnl Otherwise (on 32-bit Windows and on old Unix platforms), define it\n     dnl to 'int'.\n     AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM([[\n          #if defined _WIN64 && !defined __CYGWIN__\n          LLP64\n          #endif\n          ]])\n       ],\n       [gl_pid_type='int'],\n       [gl_pid_type='__int64'])\n     AC_DEFINE_UNQUOTED([pid_t], [$gl_pid_type],\n       [Define as a signed integer type capable of holding a process identifier.])\n    ],\n    [AC_INCLUDES_DEFAULT])\n])\n\n])# m4_version_prereq 2.70\n"
  },
  {
    "path": "m4/pthread_rwlock_rdlock.m4",
    "content": "# pthread_rwlock_rdlock.m4 serial 4\ndnl Copyright (C) 2017-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\ndnl Inspired by\ndnl https://github.com/linux-test-project/ltp/blob/master/testcases/open_posix_testsuite/conformance/interfaces/pthread_rwlock_rdlock/2-2.c\ndnl by Intel Corporation.\n\ndnl Test whether in a situation where\ndnl   - an rwlock is taken by a reader and has a writer waiting,\ndnl   - an additional reader requests the lock,\ndnl   - the waiting writer and the requesting reader threads have the same\ndnl     priority,\ndnl the requesting reader thread gets blocked, so that at some point the\ndnl waiting writer can acquire the lock.\ndnl Without such a guarantee, when there a N readers and each of the readers\ndnl spends more than 1/Nth of the time with the lock held, there is a high\ndnl probability that the waiting writer will not get the lock in a given finite\ndnl time, a phenomenon called \"writer starvation\".\ndnl Without such a guarantee, applications have a hard time avoiding writer\ndnl starvation.\ndnl\ndnl POSIX:2017 makes this requirement only for implementations that support TPS\ndnl (Thread Priority Scheduling) and only for the scheduling policies SCHED_FIFO\ndnl and SCHED_RR, see\ndnl https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_rdlock.html\ndnl but this test verifies the guarantee regardless of TPS and regardless of\ndnl scheduling policy.\ndnl Glibc does not provide this guarantee (and never will on Linux), see\ndnl https://sourceware.org/bugzilla/show_bug.cgi?id=13701\ndnl https://bugzilla.redhat.com/show_bug.cgi?id=1410052\nAC_DEFUN([gl_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER],\n[\n  AC_REQUIRE([gl_THREADLIB_EARLY])\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_CACHE_CHECK([whether pthread_rwlock_rdlock prefers a writer to a reader],\n    [gl_cv_pthread_rwlock_rdlock_prefer_writer],\n    [save_LIBS=\"$LIBS\"\n     LIBS=\"$LIBS $LIBMULTITHREAD\"\n     AC_RUN_IFELSE(\n       [AC_LANG_SOURCE([[\n#include <errno.h>\n#include <pthread.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#define SUCCEED() exit (0)\n#define FAILURE() exit (1)\n#define UNEXPECTED(n) (exit (10 + (n)))\n\n/* The main thread creates the waiting writer and the requesting reader threads\n   in the default way; this guarantees that they have the same priority.\n   We can reuse the main thread as first reader thread.  */\n\nstatic pthread_rwlock_t lock;\nstatic pthread_t reader1;\nstatic pthread_t writer;\nstatic pthread_t reader2;\nstatic pthread_t timer;\n/* Used to pass control from writer to reader2 and from reader2 to timer,\n   as in a relay race.\n   Passing control from one running thread to another running thread\n   is most likely faster than to create the second thread.  */\nstatic pthread_mutex_t baton;\n\nstatic void *\ntimer_func (void *ignored)\n{\n  /* Step 13 (can be before or after step 12):\n     The timer thread takes the baton, then waits a moment to make sure\n     it can tell whether the second reader thread is blocked at step 12.  */\n  if (pthread_mutex_lock (&baton))\n    UNEXPECTED (13);\n  usleep (100000);\n  /* By the time we get here, it's clear that the second reader thread is\n     blocked at step 12.  This is the desired behaviour.  */\n  SUCCEED ();\n}\n\nstatic void *\nreader2_func (void *ignored)\n{\n  int err;\n\n  /* Step 8 (can be before or after step 7):\n     The second reader thread takes the baton, then waits a moment to make sure\n     the writer thread has reached step 7.  */\n  if (pthread_mutex_lock (&baton))\n    UNEXPECTED (8);\n  usleep (100000);\n  /* Step 9: The second reader thread requests the lock.  */\n  err = pthread_rwlock_tryrdlock (&lock);\n  if (err == 0)\n    FAILURE ();\n  else if (err != EBUSY)\n    UNEXPECTED (9);\n  /* Step 10: Launch a timer, to test whether the next call blocks.  */\n  if (pthread_create (&timer, NULL, timer_func, NULL))\n    UNEXPECTED (10);\n  /* Step 11: Release the baton.  */\n  if (pthread_mutex_unlock (&baton))\n    UNEXPECTED (11);\n  /* Step 12: The second reader thread requests the lock.  */\n  err = pthread_rwlock_rdlock (&lock);\n  if (err == 0)\n    FAILURE ();\n  else\n    UNEXPECTED (12);\n}\n\nstatic void *\nwriter_func (void *ignored)\n{\n  /* Step 4: Take the baton, so that the second reader thread does not go ahead\n     too early.  */\n  if (pthread_mutex_lock (&baton))\n    UNEXPECTED (4);\n  /* Step 5: Create the second reader thread.  */\n  if (pthread_create (&reader2, NULL, reader2_func, NULL))\n    UNEXPECTED (5);\n  /* Step 6: Release the baton.  */\n  if (pthread_mutex_unlock (&baton))\n    UNEXPECTED (6);\n  /* Step 7: The writer thread requests the lock.  */\n  if (pthread_rwlock_wrlock (&lock))\n    UNEXPECTED (7);\n  return NULL;\n}\n\nint\nmain ()\n{\n  reader1 = pthread_self ();\n\n  /* Step 1: The main thread initializes the lock and the baton.  */\n  if (pthread_rwlock_init (&lock, NULL))\n    UNEXPECTED (1);\n  if (pthread_mutex_init (&baton, NULL))\n    UNEXPECTED (1);\n  /* Step 2: The main thread acquires the lock as a reader.  */\n  if (pthread_rwlock_rdlock (&lock))\n    UNEXPECTED (2);\n  /* Step 3: Create the writer thread.  */\n  if (pthread_create (&writer, NULL, writer_func, NULL))\n    UNEXPECTED (3);\n  /* Job done.  Go to sleep.  */\n  for (;;)\n    {\n      sleep (1);\n    }\n}\n]])],\n       [gl_cv_pthread_rwlock_rdlock_prefer_writer=yes],\n       [gl_cv_pthread_rwlock_rdlock_prefer_writer=no],\n       [case \"$host_os\" in\n                         # Guess no on glibc systems.\n          *-gnu* | gnu*) gl_cv_pthread_rwlock_rdlock_prefer_writer=\"guessing no\" ;;\n                         # Guess no on musl systems.\n          *-musl*)       gl_cv_pthread_rwlock_rdlock_prefer_writer=\"guessing no\" ;;\n                         # Guess no on bionic systems.\n          *-android*)    gl_cv_pthread_rwlock_rdlock_prefer_writer=\"guessing no\" ;;\n                         # Guess yes on native Windows with the mingw-w64 winpthreads library.\n                         # Guess no on native Windows with the gnulib windows-rwlock module.\n          mingw*)        if test \"$gl_use_threads\" = yes || test \"$gl_use_threads\" = posix; then\n                           gl_cv_pthread_rwlock_rdlock_prefer_writer=\"guessing yes\"\n                         else\n                           gl_cv_pthread_rwlock_rdlock_prefer_writer=\"guessing no\"\n                         fi\n                         ;;\n                         # If we don't know, obey --enable-cross-guesses.\n          *)             gl_cv_pthread_rwlock_rdlock_prefer_writer=\"$gl_cross_guess_normal\" ;;\n         esac\n       ])\n     LIBS=\"$save_LIBS\"\n    ])\n  case \"$gl_cv_pthread_rwlock_rdlock_prefer_writer\" in\n    *yes)\n      AC_DEFINE([HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER], [1],\n        [Define if the 'pthread_rwlock_rdlock' function prefers a writer to a reader.])\n      ;;\n  esac\n])\n"
  },
  {
    "path": "m4/regex.m4",
    "content": "# serial 73\n\n# Copyright (C) 1996-2001, 2003-2021 Free Software Foundation, Inc.\n#\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\ndnl Initially derived from code in GNU grep.\ndnl Mostly written by Jim Meyering.\n\nAC_PREREQ([2.50])\n\nAC_DEFUN([gl_REGEX],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n  AC_ARG_WITH([included-regex],\n    [AS_HELP_STRING([--without-included-regex],\n                    [don't compile regex; this is the default on systems\n                     with recent-enough versions of the GNU C Library\n                     (use with caution on other systems).])])\n\n  case $with_included_regex in #(\n  yes|no) ac_use_included_regex=$with_included_regex\n        ;;\n  '')\n    # If the system regex support is good enough that it passes the\n    # following run test, then default to *not* using the included regex.c.\n    # If cross compiling, assume the test would fail and use the included\n    # regex.c.\n    AC_CHECK_DECLS_ONCE([alarm])\n    AC_CHECK_HEADERS_ONCE([malloc.h])\n    AC_CACHE_CHECK([for working re_compile_pattern],\n                   [gl_cv_func_re_compile_pattern_working],\n      [AC_RUN_IFELSE(\n        [AC_LANG_PROGRAM(\n          [[#include <regex.h>\n\n            #include <locale.h>\n            #include <limits.h>\n            #include <string.h>\n\n            #if defined M_CHECK_ACTION || HAVE_DECL_ALARM\n            # include <signal.h>\n            # include <unistd.h>\n            #endif\n\n            #if HAVE_MALLOC_H\n            # include <malloc.h>\n            #endif\n\n            #ifdef M_CHECK_ACTION\n            /* Exit with distinguishable exit code.  */\n            static void sigabrt_no_core (int sig) { raise (SIGTERM); }\n            #endif\n          ]],\n          [[int result = 0;\n            static struct re_pattern_buffer regex;\n            unsigned char folded_chars[UCHAR_MAX + 1];\n            int i;\n            const char *s;\n            struct re_registers regs;\n\n            /* Some builds of glibc go into an infinite loop on this\n               test.  Use alarm to force death, and mallopt to avoid\n               malloc recursion in diagnosing the corrupted heap. */\n#if HAVE_DECL_ALARM\n            signal (SIGALRM, SIG_DFL);\n            alarm (2);\n#endif\n#ifdef M_CHECK_ACTION\n            signal (SIGABRT, sigabrt_no_core);\n            mallopt (M_CHECK_ACTION, 2);\n#endif\n\n            if (setlocale (LC_ALL, \"en_US.UTF-8\"))\n              {\n                {\n                  /* https://sourceware.org/ml/libc-hacker/2006-09/msg00008.html\n                     This test needs valgrind to catch the bug on Debian\n                     GNU/Linux 3.1 x86, but it might catch the bug better\n                     on other platforms and it shouldn't hurt to try the\n                     test here.  */\n                  static char const pat[] = \"insert into\";\n                  static char const data[] =\n                    \"\\xFF\\0\\x12\\xA2\\xAA\\xC4\\xB1,K\\x12\\xC4\\xB1*\\xACK\";\n                  re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE\n                                 | RE_ICASE);\n                  memset (&regex, 0, sizeof regex);\n                  s = re_compile_pattern (pat, sizeof pat - 1, &regex);\n                  if (s)\n                    result |= 1;\n                  else\n                    {\n                      if (re_search (&regex, data, sizeof data - 1,\n                                     0, sizeof data - 1, &regs)\n                          != -1)\n                        result |= 1;\n                      regfree (&regex);\n                    }\n                }\n\n                {\n                  /* This test is from glibc bug 15078.\n                     The test case is from Andreas Schwab in\n                     <https://sourceware.org/ml/libc-alpha/2013-01/msg00967.html>.\n                     */\n                  static char const pat[] = \"[^x]x\";\n                  static char const data[] =\n                    /* <U1000><U103B><U103D><U1014><U103A><U102F><U1015><U103A> */\n                    \"\\xe1\\x80\\x80\"\n                    \"\\xe1\\x80\\xbb\"\n                    \"\\xe1\\x80\\xbd\"\n                    \"\\xe1\\x80\\x94\"\n                    \"\\xe1\\x80\\xba\"\n                    \"\\xe1\\x80\\xaf\"\n                    \"\\xe1\\x80\\x95\"\n                    \"\\xe1\\x80\\xba\"\n                    \"x\";\n                  re_set_syntax (0);\n                  memset (&regex, 0, sizeof regex);\n                  s = re_compile_pattern (pat, sizeof pat - 1, &regex);\n                  if (s)\n                    result |= 1;\n                  else\n                    {\n                      i = re_search (&regex, data, sizeof data - 1,\n                                     0, sizeof data - 1, 0);\n                      if (i != 0 && i != 21)\n                        result |= 1;\n                      regfree (&regex);\n                    }\n                }\n\n                if (! setlocale (LC_ALL, \"C\"))\n                  return 1;\n              }\n\n            /* This test is from glibc bug 3957, reported by Andrew Mackey.  */\n            re_set_syntax (RE_SYNTAX_EGREP | RE_HAT_LISTS_NOT_NEWLINE);\n            memset (&regex, 0, sizeof regex);\n            s = re_compile_pattern (\"a[^x]b\", 6, &regex);\n            if (s)\n              result |= 2;\n            else\n              {\n                /* This should fail, but succeeds for glibc-2.5.  */\n                if (re_search (&regex, \"a\\nb\", 3, 0, 3, &regs) != -1)\n                  result |= 2;\n                regfree (&regex);\n              }\n\n            /* This regular expression is from Spencer ere test number 75\n               in grep-2.3.  */\n            re_set_syntax (RE_SYNTAX_POSIX_EGREP);\n            memset (&regex, 0, sizeof regex);\n            for (i = 0; i <= UCHAR_MAX; i++)\n              folded_chars[i] = i;\n            regex.translate = folded_chars;\n            s = re_compile_pattern (\"a[[:@:>@:]]b\\n\", 11, &regex);\n            /* This should fail with _Invalid character class name_ error.  */\n            if (!s)\n              {\n                result |= 4;\n                regfree (&regex);\n              }\n\n            /* Ensure that [b-a] is diagnosed as invalid, when\n               using RE_NO_EMPTY_RANGES. */\n            re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_NO_EMPTY_RANGES);\n            memset (&regex, 0, sizeof regex);\n            s = re_compile_pattern (\"a[b-a]\", 6, &regex);\n            if (s == 0)\n              {\n                result |= 8;\n                regfree (&regex);\n              }\n\n            /* This should succeed, but does not for glibc-2.1.3.  */\n            memset (&regex, 0, sizeof regex);\n            s = re_compile_pattern (\"{1\", 2, &regex);\n            if (s)\n              result |= 8;\n            else\n              regfree (&regex);\n\n            /* The following example is derived from a problem report\n               against gawk from Jorge Stolfi <stolfi@ic.unicamp.br>.  */\n            memset (&regex, 0, sizeof regex);\n            s = re_compile_pattern (\"[an\\371]*n\", 7, &regex);\n            if (s)\n              result |= 8;\n            else\n              {\n                /* This should match, but does not for glibc-2.2.1.  */\n                if (re_match (&regex, \"an\", 2, 0, &regs) != 2)\n                  result |= 8;\n                else\n                  {\n                    free (regs.start);\n                    free (regs.end);\n                  }\n                regfree (&regex);\n              }\n\n            memset (&regex, 0, sizeof regex);\n            s = re_compile_pattern (\"x\", 1, &regex);\n            if (s)\n              result |= 8;\n            else\n              {\n                /* glibc-2.2.93 does not work with a negative RANGE argument.  */\n                if (re_search (&regex, \"wxy\", 3, 2, -2, &regs) != 1)\n                  result |= 8;\n                else\n                  {\n                    free (regs.start);\n                    free (regs.end);\n                  }\n                regfree (&regex);\n              }\n\n            /* The version of regex.c in older versions of gnulib\n               ignored RE_ICASE.  Detect that problem too.  */\n            re_set_syntax (RE_SYNTAX_EMACS | RE_ICASE);\n            memset (&regex, 0, sizeof regex);\n            s = re_compile_pattern (\"x\", 1, &regex);\n            if (s)\n              result |= 16;\n            else\n              {\n                if (re_search (&regex, \"WXY\", 3, 0, 3, &regs) < 0)\n                  result |= 16;\n                else\n                  {\n                    free (regs.start);\n                    free (regs.end);\n                  }\n                regfree (&regex);\n              }\n\n            /* Catch a bug reported by Vin Shelton in\n               https://lists.gnu.org/r/bug-coreutils/2007-06/msg00089.html\n               */\n            re_set_syntax (RE_SYNTAX_POSIX_BASIC\n                           & ~RE_CONTEXT_INVALID_DUP\n                           & ~RE_NO_EMPTY_RANGES);\n            memset (&regex, 0, sizeof regex);\n            s = re_compile_pattern (\"[[:alnum:]_-]\\\\\\\\+\\$\", 16, &regex);\n            if (s)\n              result |= 32;\n            else\n              regfree (&regex);\n\n            /* REG_STARTEND was added to glibc on 2004-01-15.\n               Reject older versions.  */\n            if (! REG_STARTEND)\n              result |= 64;\n\n            /* Matching with the compiled form of this regexp would provoke\n               an assertion failure prior to glibc-2.28:\n                 regexec.c:1375: pop_fail_stack: Assertion 'num >= 0' failed\n               With glibc-2.28, compilation fails and reports the invalid\n               back reference.  */\n            re_set_syntax (RE_SYNTAX_POSIX_EGREP);\n            memset (&regex, 0, sizeof regex);\n            s = re_compile_pattern (\"0|()0|\\\\\\\\1|0\", 10, &regex);\n            if (!s)\n              {\n                memset (&regs, 0, sizeof regs);\n                i = re_search (&regex, \"x\", 1, 0, 1, &regs);\n                if (i != -1)\n                  result |= 64;\n                if (0 <= i)\n                  {\n                    free (regs.start);\n                    free (regs.end);\n                  }\n                regfree (&regex);\n              }\n            else\n              {\n                if (strcmp (s, \"Invalid back reference\"))\n                  result |= 64;\n              }\n\n            /* glibc bug 11053.  */\n            re_set_syntax (RE_SYNTAX_POSIX_BASIC);\n            memset (&regex, 0, sizeof regex);\n            static char const pat_sub2[] = \"\\\\\\\\(a*\\\\\\\\)*a*\\\\\\\\1\";\n            s = re_compile_pattern (pat_sub2, sizeof pat_sub2 - 1, &regex);\n            if (s)\n              result |= 64;\n            else\n              {\n                memset (&regs, 0, sizeof regs);\n                static char const data[] = \"a\";\n                int datalen = sizeof data - 1;\n                i = re_search (&regex, data, datalen, 0, datalen, &regs);\n                if (i != 0)\n                  result |= 64;\n                else if (regs.num_regs < 2)\n                  result |= 64;\n                else if (! (regs.start[0] == 0 && regs.end[0] == 1))\n                  result |= 64;\n                else if (! (regs.start[1] == 0 && regs.end[1] == 0))\n                  result |= 64;\n                regfree (&regex);\n                free (regs.start);\n                free (regs.end);\n              }\n\n#if 0\n            /* It would be nice to reject hosts whose regoff_t values are too\n               narrow (including glibc on hosts with 64-bit ptrdiff_t and\n               32-bit int), but we should wait until glibc implements this\n               feature.  Otherwise, support for equivalence classes and\n               multibyte collation symbols would always be broken except\n               when compiling --without-included-regex.   */\n            if (sizeof (regoff_t) < sizeof (ptrdiff_t)\n                || sizeof (regoff_t) < sizeof (ssize_t))\n              result |= 64;\n#endif\n\n            return result;\n          ]])],\n        [gl_cv_func_re_compile_pattern_working=yes],\n        [gl_cv_func_re_compile_pattern_working=no],\n        [case \"$host_os\" in\n                   # Guess no on native Windows.\n           mingw*) gl_cv_func_re_compile_pattern_working=\"guessing no\" ;;\n                   # Otherwise obey --enable-cross-guesses.\n           *)      gl_cv_func_re_compile_pattern_working=\"$gl_cross_guess_normal\" ;;\n         esac\n        ])\n      ])\n    case \"$gl_cv_func_re_compile_pattern_working\" in #(\n      *yes) ac_use_included_regex=no;; #(\n      *no) ac_use_included_regex=yes;;\n    esac\n    ;;\n  *) AC_MSG_ERROR([Invalid value for --with-included-regex: $with_included_regex])\n    ;;\n  esac\n\n  if test $ac_use_included_regex = yes; then\n    AC_DEFINE([_REGEX_INCLUDE_LIMITS_H], [1],\n      [Define if you want <regex.h> to include <limits.h>, so that it\n       consistently overrides <limits.h>'s RE_DUP_MAX.])\n    AC_DEFINE([_REGEX_LARGE_OFFSETS], [1],\n      [Define if you want regoff_t to be at least as wide POSIX requires.])\n    AC_DEFINE([re_syntax_options], [rpl_re_syntax_options],\n      [Define to rpl_re_syntax_options if the replacement should be used.])\n    AC_DEFINE([re_set_syntax], [rpl_re_set_syntax],\n      [Define to rpl_re_set_syntax if the replacement should be used.])\n    AC_DEFINE([re_compile_pattern], [rpl_re_compile_pattern],\n      [Define to rpl_re_compile_pattern if the replacement should be used.])\n    AC_DEFINE([re_compile_fastmap], [rpl_re_compile_fastmap],\n      [Define to rpl_re_compile_fastmap if the replacement should be used.])\n    AC_DEFINE([re_search], [rpl_re_search],\n      [Define to rpl_re_search if the replacement should be used.])\n    AC_DEFINE([re_search_2], [rpl_re_search_2],\n      [Define to rpl_re_search_2 if the replacement should be used.])\n    AC_DEFINE([re_match], [rpl_re_match],\n      [Define to rpl_re_match if the replacement should be used.])\n    AC_DEFINE([re_match_2], [rpl_re_match_2],\n      [Define to rpl_re_match_2 if the replacement should be used.])\n    AC_DEFINE([re_set_registers], [rpl_re_set_registers],\n      [Define to rpl_re_set_registers if the replacement should be used.])\n    AC_DEFINE([re_comp], [rpl_re_comp],\n      [Define to rpl_re_comp if the replacement should be used.])\n    AC_DEFINE([re_exec], [rpl_re_exec],\n      [Define to rpl_re_exec if the replacement should be used.])\n    AC_DEFINE([regcomp], [rpl_regcomp],\n      [Define to rpl_regcomp if the replacement should be used.])\n    AC_DEFINE([regexec], [rpl_regexec],\n      [Define to rpl_regexec if the replacement should be used.])\n    AC_DEFINE([regerror], [rpl_regerror],\n      [Define to rpl_regerror if the replacement should be used.])\n    AC_DEFINE([regfree], [rpl_regfree],\n      [Define to rpl_regfree if the replacement should be used.])\n  fi\n])\n\n# Prerequisites of lib/regex.c and lib/regex_internal.c.\nAC_DEFUN([gl_PREREQ_REGEX],\n[\n  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])\n  AC_REQUIRE([AC_C_INLINE])\n  AC_REQUIRE([AC_C_RESTRICT])\n  AC_REQUIRE([AC_TYPE_MBSTATE_T])\n  AC_REQUIRE([gl_EEMALLOC])\n  AC_CHECK_HEADERS([libintl.h])\n  AC_CHECK_FUNCS_ONCE([isblank iswctype])\n  AC_CHECK_DECLS([isblank], [], [], [[#include <ctype.h>]])\n])\n"
  },
  {
    "path": "m4/setlocale_null.m4",
    "content": "# setlocale_null.m4 serial 5\ndnl Copyright (C) 2019-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_SETLOCALE_NULL],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_REQUIRE([gl_PTHREADLIB])\n  AC_CHECK_HEADERS_ONCE([threads.h])\n\n  AC_CACHE_CHECK([whether setlocale (LC_ALL, NULL) is multithread-safe],\n    [gl_cv_func_setlocale_null_all_mtsafe],\n    [case \"$host_os\" in\n       # Guess no on musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Haiku, Cygwin.\n       *-musl* | darwin* | freebsd* | midnightbsd* | netbsd* | openbsd* | aix* | haiku* | cygwin*)\n         gl_cv_func_setlocale_null_all_mtsafe=no ;;\n       # Guess yes on glibc, HP-UX, IRIX, Solaris, native Windows.\n       *-gnu* | gnu* | hpux* | irix* | solaris* | mingw*)\n         gl_cv_func_setlocale_null_all_mtsafe=yes ;;\n       # If we don't know, obey --enable-cross-guesses.\n       *)\n         gl_cv_func_setlocale_null_all_mtsafe=\"$gl_cross_guess_normal\" ;;\n     esac\n    ])\n  dnl On platforms without multithreading, there is no issue.\n  case \"$host_os\" in\n    mingw*) ;;\n    *)\n      if test $gl_pthread_api = no && test $ac_cv_header_threads_h = no; then\n        gl_cv_func_setlocale_null_all_mtsafe=\"trivially yes\"\n      fi\n      ;;\n  esac\n  case \"$gl_cv_func_setlocale_null_all_mtsafe\" in\n    *yes) SETLOCALE_NULL_ALL_MTSAFE=1 ;;\n    *)    SETLOCALE_NULL_ALL_MTSAFE=0 ;;\n  esac\n  AC_DEFINE_UNQUOTED([SETLOCALE_NULL_ALL_MTSAFE], [$SETLOCALE_NULL_ALL_MTSAFE],\n    [Define to 1 if setlocale (LC_ALL, NULL) is multithread-safe.])\n\n  dnl This is about a single category (not LC_ALL).\n  AC_CACHE_CHECK([whether setlocale (category, NULL) is multithread-safe],\n    [gl_cv_func_setlocale_null_one_mtsafe],\n    [case \"$host_os\" in\n       # Guess no on OpenBSD, AIX.\n       openbsd* | aix*)\n         gl_cv_func_setlocale_null_one_mtsafe=no ;;\n       # Guess yes on glibc, musl libc, macOS, FreeBSD, NetBSD, HP-UX, IRIX, Solaris, Haiku, Cygwin, native Windows.\n       *-gnu* | gnu* | *-musl* | darwin* | freebsd* | midnightbsd* | netbsd* | hpux* | irix* | solaris* | haiku* | cygwin* | mingw*)\n         gl_cv_func_setlocale_null_one_mtsafe=yes ;;\n       # If we don't know, obey --enable-cross-guesses.\n       *)\n         gl_cv_func_setlocale_null_one_mtsafe=\"$gl_cross_guess_normal\" ;;\n     esac\n    ])\n  dnl On platforms without multithreading, there is no issue.\n  case \"$host_os\" in\n    mingw*) ;;\n    *)\n      if test $gl_pthread_api = no && test $ac_cv_header_threads_h = no; then\n        gl_cv_func_setlocale_null_one_mtsafe=\"trivially yes\"\n      fi\n      ;;\n  esac\n  case \"$gl_cv_func_setlocale_null_one_mtsafe\" in\n    *yes) SETLOCALE_NULL_ONE_MTSAFE=1 ;;\n    *)    SETLOCALE_NULL_ONE_MTSAFE=0 ;;\n  esac\n  AC_DEFINE_UNQUOTED([SETLOCALE_NULL_ONE_MTSAFE], [$SETLOCALE_NULL_ONE_MTSAFE],\n    [Define to 1 if setlocale (category, NULL) is multithread-safe.])\n\n  dnl Determine link dependencies of lib/setlocale_null.c and lib/setlocale-lock.c.\n  if test $SETLOCALE_NULL_ALL_MTSAFE = 0 || test $SETLOCALE_NULL_ONE_MTSAFE = 0; then\n    case \"$host_os\" in\n      mingw*) LIB_SETLOCALE_NULL= ;;\n      *)\n        gl_WEAK_SYMBOLS\n        case \"$gl_cv_have_weak\" in\n          *yes) LIB_SETLOCALE_NULL= ;;\n          *)    LIB_SETLOCALE_NULL=\"$LIBPTHREAD\" ;;\n        esac\n        ;;\n    esac\n  else\n    LIB_SETLOCALE_NULL=\n  fi\n  dnl LIB_SETLOCALE_NULL is expected to be '-pthread' or '-lpthread' on AIX\n  dnl with gcc or xlc, and empty otherwise.\n  AC_SUBST([LIB_SETLOCALE_NULL])\n])\n\n# Prerequisites of lib/setlocale-lock.c.\nAC_DEFUN([gl_PREREQ_SETLOCALE_LOCK],\n[\n  gl_VISIBILITY\n])\n"
  },
  {
    "path": "m4/ssize_t.m4",
    "content": "# ssize_t.m4 serial 5 (gettext-0.18.2)\ndnl Copyright (C) 2001-2003, 2006, 2010-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\ndnl Test whether ssize_t is defined.\n\nAC_DEFUN([gt_TYPE_SSIZE_T],\n[\n  AC_CACHE_CHECK([for ssize_t], [gt_cv_ssize_t],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <sys/types.h>]],\n          [[int x = sizeof (ssize_t *) + sizeof (ssize_t);\n            return !x;]])],\n       [gt_cv_ssize_t=yes], [gt_cv_ssize_t=no])])\n  if test $gt_cv_ssize_t = no; then\n    AC_DEFINE([ssize_t], [int],\n              [Define as a signed type of the same size as size_t.])\n  fi\n])\n"
  },
  {
    "path": "m4/std-gnu11.m4",
    "content": "# Prefer GNU C11 and C++11 to earlier versions.  -*- coding: utf-8 -*-\n\n# This implementation is taken from GNU Autoconf lib/autoconf/c.m4\n# commit 017d5ddd82854911f0119691d91ea8a1438824d6\n# dated Sun Apr 3 13:57:17 2016 -0700\n# This implementation will be obsolete once we can assume Autoconf 2.70\n# or later is installed everywhere a Gnulib program might be developed.\n\nm4_version_prereq([2.70], [], [\n\n\n# Copyright (C) 2001-2021 Free Software Foundation, Inc.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\n# Written by David MacKenzie, with help from\n# Akim Demaille, Paul Eggert,\n# François Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,\n# Roland McGrath, Noah Friedman, david d zuhn, and many others.\n\n\n# AC_PROG_CC([COMPILER ...])\n# --------------------------\n# COMPILER ... is a space separated list of C compilers to search for.\n# This just gives the user an opportunity to specify an alternative\n# search list for the C compiler.\nAC_DEFUN_ONCE([AC_PROG_CC],\n[AC_LANG_PUSH(C)dnl\nAC_ARG_VAR([CC],     [C compiler command])dnl\nAC_ARG_VAR([CFLAGS], [C compiler flags])dnl\n_AC_ARG_VAR_LDFLAGS()dnl\n_AC_ARG_VAR_LIBS()dnl\n_AC_ARG_VAR_CPPFLAGS()dnl\nm4_ifval([$1],\n      [AC_CHECK_TOOLS(CC, [$1])],\n[AC_CHECK_TOOL(CC, gcc)\nif test -z \"$CC\"; then\n  dnl Here we want:\n  dnl\tAC_CHECK_TOOL(CC, cc)\n  dnl but without the check for a tool without the prefix.\n  dnl Until the check is removed from there, copy the code:\n  if test -n \"$ac_tool_prefix\"; then\n    AC_CHECK_PROG(CC, [${ac_tool_prefix}cc], [${ac_tool_prefix}cc])\n  fi\nfi\nif test -z \"$CC\"; then\n  AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)\nfi\nif test -z \"$CC\"; then\n  AC_CHECK_TOOLS(CC, cl.exe)\nfi\nif test -z \"$CC\"; then\n  AC_CHECK_TOOL(CC, clang)\nfi\n])\n\ntest -z \"$CC\" && AC_MSG_FAILURE([no acceptable C compiler found in \\$PATH])\n\n# Provide some information about the compiler.\n_AS_ECHO_LOG([checking for _AC_LANG compiler version])\nset X $ac_compile\nac_compiler=$[2]\nfor ac_option in --version -v -V -qversion -version; do\n  _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])\ndone\n\nm4_expand_once([_AC_COMPILER_EXEEXT])[]dnl\nm4_expand_once([_AC_COMPILER_OBJEXT])[]dnl\n_AC_LANG_COMPILER_GNU\nif test $ac_compiler_gnu = yes; then\n  GCC=yes\nelse\n  GCC=\nfi\n_AC_PROG_CC_G\ndnl\ndnl Set ac_prog_cc_stdc to the supported C version.\ndnl Also set the documented variable ac_cv_prog_cc_stdc;\ndnl its name was chosen when it was cached, but it is no longer cached.\n_AC_PROG_CC_C11([ac_prog_cc_stdc=c11\n\t\t ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11],\n  [_AC_PROG_CC_C99([ac_prog_cc_stdc=c99\n\t\t    ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99],\n     [_AC_PROG_CC_C89([ac_prog_cc_stdc=c89\n\t\t       ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89],\n\t\t      [ac_prog_cc_stdc=no\n\t\t       ac_cv_prog_cc_stdc=no])])])\ndnl\nAC_LANG_POP(C)dnl\n])# AC_PROG_CC\n\n\n\n# AC_PROG_CXX([LIST-OF-COMPILERS])\n# --------------------------------\n# LIST-OF-COMPILERS is a space separated list of C++ compilers to search\n# for (if not specified, a default list is used).  This just gives the\n# user an opportunity to specify an alternative search list for the C++\n# compiler.\n# aCC\tHP-UX C++ compiler much better than `CC', so test before.\n# FCC   Fujitsu C++ compiler\n# KCC\tKAI C++ compiler\n# RCC\tRational C++\n# xlC_r\tAIX C Set++ (with support for reentrant code)\n# xlC\tAIX C Set++\nAC_DEFUN([AC_PROG_CXX],\n[AC_LANG_PUSH(C++)dnl\nAC_ARG_VAR([CXX],      [C++ compiler command])dnl\nAC_ARG_VAR([CXXFLAGS], [C++ compiler flags])dnl\n_AC_ARG_VAR_LDFLAGS()dnl\n_AC_ARG_VAR_LIBS()dnl\n_AC_ARG_VAR_CPPFLAGS()dnl\n_AC_ARG_VAR_PRECIOUS([CCC])dnl\nif test -z \"$CXX\"; then\n  if test -n \"$CCC\"; then\n    CXX=$CCC\n  else\n    AC_CHECK_TOOLS(CXX,\n\t\t   [m4_default([$1],\n\t\t\t       [g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++])],\n\t\t   g++)\n  fi\nfi\n# Provide some information about the compiler.\n_AS_ECHO_LOG([checking for _AC_LANG compiler version])\nset X $ac_compile\nac_compiler=$[2]\nfor ac_option in --version -v -V -qversion; do\n  _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])\ndone\n\nm4_expand_once([_AC_COMPILER_EXEEXT])[]dnl\nm4_expand_once([_AC_COMPILER_OBJEXT])[]dnl\n_AC_LANG_COMPILER_GNU\nif test $ac_compiler_gnu = yes; then\n  GXX=yes\nelse\n  GXX=\nfi\n_AC_PROG_CXX_G\n_AC_PROG_CXX_CXX11([ac_prog_cxx_stdcxx=cxx11\n\t\t    ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11\n\t\t    ac_cv_prog_cxx_cxx98=$ac_cv_prog_cxx_cxx11],\n   [_AC_PROG_CXX_CXX98([ac_prog_cxx_stdcxx=cxx98\n\t\t        ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98],\n\t\t       [ac_prog_cxx_stdcxx=no\n\t\t        ac_cv_prog_cxx_stdcxx=no])])\nAC_LANG_POP(C++)dnl\n])# AC_PROG_CXX\n\n\n# _AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,\n#\t\tACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)\n# --------------------------------------------------------------\n# Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99')\n# by trying to compile a program of TEST-PROLOGUE and TEST-BODY.  If this fails,\n# try again with each compiler option in the space-separated OPTION-LIST; if one\n# helps, append it to CC.  If eventually successful, run ACTION-IF-AVAILABLE,\n# else ACTION-IF-UNAVAILABLE.\nAC_DEFUN([_AC_C_STD_TRY],\n[AC_MSG_CHECKING([for $CC option to enable ]m4_translit($1, [c], [C])[ features])\nAC_CACHE_VAL(ac_cv_prog_cc_$1,\n[ac_cv_prog_cc_$1=no\nac_save_CC=$CC\nAC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])\nfor ac_arg in '' $4\ndo\n  CC=\"$ac_save_CC $ac_arg\"\n  _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg])\n  test \"x$ac_cv_prog_cc_$1\" != \"xno\" && break\ndone\nrm -f conftest.$ac_ext\nCC=$ac_save_CC\n])# AC_CACHE_VAL\nac_prog_cc_stdc_options=\ncase \"x$ac_cv_prog_cc_$1\" in\n  x)\n    AC_MSG_RESULT([none needed]) ;;\n  xno)\n    AC_MSG_RESULT([unsupported]) ;;\n  *)\n    ac_prog_cc_stdc_options=\" $ac_cv_prog_cc_$1\"\n    CC=$CC$ac_prog_cc_stdc_options\n    AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;;\nesac\nAS_IF([test \"x$ac_cv_prog_cc_$1\" != xno], [$5], [$6])\n])# _AC_C_STD_TRY\n\n# _AC_C_C99_TEST_HEADER\n# ---------------------\n# A C header suitable for testing for C99.\nAC_DEFUN([_AC_C_C99_TEST_HEADER],\n[[#include <stdarg.h>\n#include <stdbool.h>\n#include <stddef.h>\n#include <stdlib.h>\n#include <wchar.h>\n#include <stdio.h>\n\n// Check varargs macros.  These examples are taken from C99 6.10.3.5.\n#define debug(...) fprintf (stderr, __VA_ARGS__)\n#define showlist(...) puts (#__VA_ARGS__)\n#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))\nstatic void\ntest_varargs_macros (void)\n{\n  int x = 1234;\n  int y = 5678;\n  debug (\"Flag\");\n  debug (\"X = %d\\n\", x);\n  showlist (The first, second, and third items.);\n  report (x>y, \"x is %d but y is %d\", x, y);\n}\n\n// Check long long types.\n#define BIG64 18446744073709551615ull\n#define BIG32 4294967295ul\n#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)\n#if !BIG_OK\n  your preprocessor is broken;\n#endif\n#if BIG_OK\n#else\n  your preprocessor is broken;\n#endif\nstatic long long int bignum = -9223372036854775807LL;\nstatic unsigned long long int ubignum = BIG64;\n\nstruct incomplete_array\n{\n  int datasize;\n  double data[];\n};\n\nstruct named_init {\n  int number;\n  const wchar_t *name;\n  double average;\n};\n\ntypedef const char *ccp;\n\nstatic inline int\ntest_restrict (ccp restrict text)\n{\n  // See if C++-style comments work.\n  // Iterate through items via the restricted pointer.\n  // Also check for declarations in for loops.\n  for (unsigned int i = 0; *(text+i) != '\\0'; ++i)\n    continue;\n  return 0;\n}\n\n// Check varargs and va_copy.\nstatic bool\ntest_varargs (const char *format, ...)\n{\n  va_list args;\n  va_start (args, format);\n  va_list args_copy;\n  va_copy (args_copy, args);\n\n  const char *str = \"\";\n  int number = 0;\n  float fnumber = 0;\n\n  while (*format)\n    {\n      switch (*format++)\n\t{\n\tcase 's': // string\n\t  str = va_arg (args_copy, const char *);\n\t  break;\n\tcase 'd': // int\n\t  number = va_arg (args_copy, int);\n\t  break;\n\tcase 'f': // float\n\t  fnumber = va_arg (args_copy, double);\n\t  break;\n\tdefault:\n\t  break;\n\t}\n    }\n  va_end (args_copy);\n  va_end (args);\n\n  return *str && number && fnumber;\n}]])# _AC_C_C99_TEST_HEADER\n\n# _AC_C_C99_TEST_BODY\n# -------------------\n# A C body suitable for testing for C99, assuming the corresponding header.\nAC_DEFUN([_AC_C_C99_TEST_BODY],\n[[\n  // Check bool.\n  _Bool success = false;\n\n  // Check restrict.\n  if (test_restrict (\"String literal\") == 0)\n    success = true;\n  char *restrict newvar = \"Another string\";\n\n  // Check varargs.\n  success &= test_varargs (\"s, d' f .\", \"string\", 65, 34.234);\n  test_varargs_macros ();\n\n  // Check flexible array members.\n  struct incomplete_array *ia =\n    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));\n  ia->datasize = 10;\n  for (int i = 0; i < ia->datasize; ++i)\n    ia->data[i] = i * 1.234;\n\n  // Check named initializers.\n  struct named_init ni = {\n    .number = 34,\n    .name = L\"Test wide string\",\n    .average = 543.34343,\n  };\n\n  ni.number = 58;\n\n  int dynamic_array[ni.number];\n  dynamic_array[ni.number - 1] = 543;\n\n  // work around unused variable warnings\n  return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'\n\t  || dynamic_array[ni.number - 1] != 543);\n]])\n\n# _AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])\n# ----------------------------------------------------------------\n# If the C compiler is not in ISO C99 mode by default, try to add an\n# option to output variable CC to make it so.  This macro tries\n# various options that select ISO C99 on some system or another.  It\n# considers the compiler to be in ISO C99 mode if it handles _Bool,\n# // comments, flexible array members, inline, long long int, mixed\n# code and declarations, named initialization of structs, restrict,\n# va_copy, varargs macros, variable declarations in for loops and\n# variable length arrays.\nAC_DEFUN([_AC_PROG_CC_C99],\n[_AC_C_STD_TRY([c99],\n[_AC_C_C99_TEST_HEADER],\n[_AC_C_C99_TEST_BODY],\ndnl Try\ndnl GCC\t\t-std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999)\ndnl IBM XL C\t-qlanglvl=extc1x (V12.1; does not pass C11 test)\ndnl IBM XL C\t-qlanglvl=extc99\ndnl\t\t(pre-V12.1; unused restrictive mode: -qlanglvl=stdc99)\ndnl HP cc\t-AC99\ndnl Intel ICC\t-std=c99, -c99 (deprecated)\ndnl IRIX\t-c99\ndnl Solaris\t-D_STDC_C99=\ndnl\t\tcc's -xc99 option uses linker magic to define the external\ndnl\t\tsymbol __xpg4 as if by \"int __xpg4 = 1;\", which enables C99\ndnl\t\tbehavior for C library functions.  This is not wanted here,\ndnl\t\tbecause it means that a single module compiled with -xc99\ndnl\t\talters C runtime behavior for the entire program, not for\ndnl\t\tjust the module.  Instead, define the (private) symbol\ndnl\t\t_STDC_C99, which suppresses a bogus failure in <stdbool.h>.\ndnl\t\tThe resulting compiler passes the test case here, and that's\ndnl\t\tgood enough.  For more, please see the thread starting at:\ndnl            https://lists.gnu.org/r/autoconf/2010-12/msg00059.html\ndnl Tru64\t-c99\ndnl with extended modes being tried first.\n[[-std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc1x -qlanglvl=extc99]], [$1], [$2])[]dnl\n])# _AC_PROG_CC_C99\n\n\n# _AC_PROG_CC_C11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])\n# ----------------------------------------------------------------\n# If the C compiler is not in ISO C11 mode by default, try to add an\n# option to output variable CC to make it so.  This macro tries\n# various options that select ISO C11 on some system or another.  It\n# considers the compiler to be in ISO C11 mode if it handles _Alignas,\n# _Alignof, _Noreturn, _Static_assert, UTF-8 string literals,\n# duplicate typedefs, and anonymous structures and unions.\nAC_DEFUN([_AC_PROG_CC_C11],\n[_AC_C_STD_TRY([c11],\n[_AC_C_C99_TEST_HEADER[\n// Check _Alignas.\nchar _Alignas (double) aligned_as_double;\nchar _Alignas (0) no_special_alignment;\nextern char aligned_as_int;\nchar _Alignas (0) _Alignas (int) aligned_as_int;\n\n// Check _Alignof.\nenum\n{\n  int_alignment = _Alignof (int),\n  int_array_alignment = _Alignof (int[100]),\n  char_alignment = _Alignof (char)\n};\n_Static_assert (0 < -_Alignof (int), \"_Alignof is signed\");\n\n// Check _Noreturn.\nint _Noreturn does_not_return (void) { for (;;) continue; }\n\n// Check _Static_assert.\nstruct test_static_assert\n{\n  int x;\n  _Static_assert (sizeof (int) <= sizeof (long int),\n                  \"_Static_assert does not work in struct\");\n  long int y;\n};\n\n// Check UTF-8 literals.\n#define u8 syntax error!\nchar const utf8_literal[] = u8\"happens to be ASCII\" \"another string\";\n\n// Check duplicate typedefs.\ntypedef long *long_ptr;\ntypedef long int *long_ptr;\ntypedef long_ptr long_ptr;\n\n// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.\nstruct anonymous\n{\n  union {\n    struct { int i; int j; };\n    struct { int k; long int l; } w;\n  };\n  int m;\n} v1;\n]],\n[_AC_C_C99_TEST_BODY[\n  v1.i = 2;\n  v1.w.k = 5;\n  _Static_assert ((offsetof (struct anonymous, i)\n\t\t   == offsetof (struct anonymous, w.k)),\n\t\t  \"Anonymous union alignment botch\");\n]],\ndnl Try\ndnl GCC\t\t-std=gnu11 (unused restrictive mode: -std=c11)\ndnl with extended modes being tried first.\ndnl\ndnl Do not try -qlanglvl=extc1x, because IBM XL C V12.1 (the latest version as\ndnl of September 2012) does not pass the C11 test.  For now, try extc1x when\ndnl compiling the C99 test instead, since it enables _Static_assert and\ndnl _Noreturn, which is a win.  If -qlanglvl=extc11 or -qlanglvl=extc1x passes\ndnl the C11 test in some future version of IBM XL C, we'll add it here,\ndnl preferably extc11.\n[[-std=gnu11]], [$1], [$2])[]dnl\n])# _AC_PROG_CC_C11\n\n\n# AC_PROG_CC_C89\n# --------------\n# Do not use AU_ALIAS here and in AC_PROG_CC_C99 and AC_PROG_CC_STDC,\n# as that'd be incompatible with how Automake redefines AC_PROG_CC.  See\n# <https://lists.gnu.org/r/autoconf/2012-10/msg00048.html>.\nAU_DEFUN([AC_PROG_CC_C89],\n  [AC_REQUIRE([AC_PROG_CC])],\n  [$0 is obsolete; use AC_PROG_CC]\n)\n\n# AC_PROG_CC_C99\n# --------------\nAU_DEFUN([AC_PROG_CC_C99],\n  [AC_REQUIRE([AC_PROG_CC])],\n  [$0 is obsolete; use AC_PROG_CC]\n)\n\n# AC_PROG_CC_STDC\n# ---------------\nAU_DEFUN([AC_PROG_CC_STDC],\n  [AC_REQUIRE([AC_PROG_CC])],\n  [$0 is obsolete; use AC_PROG_CC]\n)\n\n\n# AC_C_PROTOTYPES\n# ---------------\n# Check if the C compiler supports prototypes, included if it needs\n# options.\nAC_DEFUN([AC_C_PROTOTYPES],\n[AC_REQUIRE([AC_PROG_CC])dnl\nif test \"$ac_prog_cc_stdc\" != no; then\n  AC_DEFINE(PROTOTYPES, 1,\n\t    [Define to 1 if the C compiler supports function prototypes.])\n  AC_DEFINE(__PROTOTYPES, 1,\n\t    [Define like PROTOTYPES; this can be used by system headers.])\nfi\n])# AC_C_PROTOTYPES\n\n\n# _AC_CXX_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,\n#\t\t  ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)\n# ----------------------------------------------------------------\n# Check whether the C++ compiler accepts features of STANDARD (e.g\n# `cxx98', `cxx11') by trying to compile a program of TEST-PROLOGUE\n# and TEST-BODY.  If this fails, try again with each compiler option\n# in the space-separated OPTION-LIST; if one helps, append it to CXX.\n# If eventually successful, run ACTION-IF-AVAILABLE, else\n# ACTION-IF-UNAVAILABLE.\nAC_DEFUN([_AC_CXX_STD_TRY],\n[AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features])\nAC_LANG_PUSH(C++)dnl\nAC_CACHE_VAL(ac_cv_prog_cxx_$1,\n[ac_cv_prog_cxx_$1=no\nac_save_CXX=$CXX\nAC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])\nfor ac_arg in '' $4\ndo\n  CXX=\"$ac_save_CXX $ac_arg\"\n  _AC_COMPILE_IFELSE([], [ac_cv_prog_cxx_$1=$ac_arg])\n  test \"x$ac_cv_prog_cxx_$1\" != \"xno\" && break\ndone\nrm -f conftest.$ac_ext\nCXX=$ac_save_CXX\n])# AC_CACHE_VAL\nac_prog_cxx_stdcxx_options=\ncase \"x$ac_cv_prog_cxx_$1\" in\n  x)\n    AC_MSG_RESULT([none needed]) ;;\n  xno)\n    AC_MSG_RESULT([unsupported]) ;;\n  *)\n    ac_prog_cxx_stdcxx_options=\" $ac_cv_prog_cxx_$1\"\n    CXX=$CXX$ac_prog_cxx_stdcxx_options\n    AC_MSG_RESULT([$ac_cv_prog_cxx_$1]) ;;\nesac\nAC_LANG_POP(C++)dnl\nAS_IF([test \"x$ac_cv_prog_cxx_$1\" != xno], [$5], [$6])\n])# _AC_CXX_STD_TRY\n\n# _AC_CXX_CXX98_TEST_HEADER\n# -------------------------\n# A C++ header suitable for testing for CXX98.\nAC_DEFUN([_AC_CXX_CXX98_TEST_HEADER],\n[[\n#include <algorithm>\n#include <cstdlib>\n#include <fstream>\n#include <iomanip>\n#include <iostream>\n#include <list>\n#include <map>\n#include <set>\n#include <sstream>\n#include <stdexcept>\n#include <string>\n#include <utility>\n#include <vector>\n\nnamespace test {\n  typedef std::vector<std::string> string_vec;\n  typedef std::pair<int,bool> map_value;\n  typedef std::map<std::string,map_value> map_type;\n  typedef std::set<int> set_type;\n\n  template<typename T>\n  class printer {\n  public:\n    printer(std::ostringstream& os): os(os) {}\n    void operator() (T elem) { os << elem << std::endl; }\n  private:\n    std::ostringstream& os;\n  };\n}\n]])# _AC_CXX_CXX98_TEST_HEADER\n\n# _AC_CXX_CXX98_TEST_BODY\n# -----------------------\n# A C++ body suitable for testing for CXX98, assuming the corresponding header.\nAC_DEFUN([_AC_CXX_CXX98_TEST_BODY],\n[[\n\ntry {\n  // Basic string.\n  std::string teststr(\"ASCII text\");\n  teststr += \" string\";\n\n  // Simple vector.\n  test::string_vec testvec;\n  testvec.push_back(teststr);\n  testvec.push_back(\"foo\");\n  testvec.push_back(\"bar\");\n  if (testvec.size() != 3) {\n    throw std::runtime_error(\"vector size is not 1\");\n  }\n\n  // Dump vector into stringstream and obtain string.\n  std::ostringstream os;\n  for (test::string_vec::const_iterator i = testvec.begin();\n       i != testvec.end(); ++i) {\n    if (i + 1 != testvec.end()) {\n      os << teststr << '\\n';\n    }\n  }\n  // Check algorithms work.\n  std::for_each(testvec.begin(), testvec.end(), test::printer<std::string>(os));\n  std::string os_out = os.str();\n\n  // Test pair and map.\n  test::map_type testmap;\n  testmap.insert(std::make_pair(std::string(\"key\"),\n                                std::make_pair(53,false)));\n\n  // Test set.\n  int values[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};\n  test::set_type testset(values, values + sizeof(values)/sizeof(values[0]));\n  std::list<int> testlist(testset.begin(), testset.end());\n  std::copy(testset.begin(), testset.end(), std::back_inserter(testlist));\n} catch (const std::exception& e) {\n  std::cerr << \"Caught exception: \" << e.what() << std::endl;\n\n  // Test fstream\n  std::ofstream of(\"test.txt\");\n  of << \"Test ASCII text\\n\" << std::flush;\n  of << \"N= \" << std::hex << std::setw(8) << std::left << 534 << std::endl;\n  of.close();\n}\nstd::exit(0);\n]])\n\n# _AC_CXX_CXX11_TEST_HEADER\n# -------------------------\n# A C++ header suitable for testing for CXX11.\nAC_DEFUN([_AC_CXX_CXX11_TEST_HEADER],\n[[\n#include <deque>\n#include <functional>\n#include <memory>\n#include <tuple>\n#include <array>\n#include <regex>\n#include <iostream>\n\nnamespace cxx11test\n{\n  typedef std::shared_ptr<std::string> sptr;\n  typedef std::weak_ptr<std::string> wptr;\n\n  typedef std::tuple<std::string,int,double> tp;\n  typedef std::array<int, 20> int_array;\n\n  constexpr int get_val() { return 20; }\n\n  struct testinit\n  {\n    int i;\n    double d;\n  };\n\n  class delegate  {\n  public:\n    delegate(int n) : n(n) {}\n    delegate(): delegate(2354) {}\n\n    virtual int getval() { return this->n; };\n  protected:\n    int n;\n  };\n\n  class overridden : public delegate {\n  public:\n    overridden(int n): delegate(n) {}\n    virtual int getval() override final { return this->n * 2; }\n  };\n\n  class nocopy {\n  public:\n    nocopy(int i): i(i) {}\n    nocopy() = default;\n    nocopy(const nocopy&) = delete;\n    nocopy & operator=(const nocopy&) = delete;\n  private:\n    int i;\n  };\n}\n]])# _AC_CXX_CXX11_TEST_HEADER\n\n# _AC_CXX_CXX11_TEST_BODY\n# -----------------------\n# A C++ body suitable for testing for CXX11, assuming the corresponding header.\nAC_DEFUN([_AC_CXX_CXX11_TEST_BODY],\n[[\n{\n  // Test auto and decltype\n  std::deque<int> d;\n  d.push_front(43);\n  d.push_front(484);\n  d.push_front(3);\n  d.push_front(844);\n  int total = 0;\n  for (auto i = d.begin(); i != d.end(); ++i) { total += *i; }\n\n  auto a1 = 6538;\n  auto a2 = 48573953.4;\n  auto a3 = \"String literal\";\n\n  decltype(a2) a4 = 34895.034;\n}\n{\n  // Test constexpr\n  short sa[cxx11test::get_val()] = { 0 };\n}\n{\n  // Test initializer lists\n  cxx11test::testinit il = { 4323, 435234.23544 };\n}\n{\n  // Test range-based for and lambda\n  cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};\n  for (int &x : array) { x += 23; }\n  std::for_each(array.begin(), array.end(), [](int v1){ std::cout << v1; });\n}\n{\n  using cxx11test::sptr;\n  using cxx11test::wptr;\n\n  sptr sp(new std::string(\"ASCII string\"));\n  wptr wp(sp);\n  sptr sp2(wp);\n}\n{\n  cxx11test::tp tuple(\"test\", 54, 45.53434);\n  double d = std::get<2>(tuple);\n  std::string s;\n  int i;\n  std::tie(s,i,d) = tuple;\n}\n{\n  static std::regex filename_regex(\"^_?([a-z0-9_.]+-)+[a-z0-9]+$\");\n  std::string testmatch(\"Test if this string matches\");\n  bool match = std::regex_search(testmatch, filename_regex);\n}\n{\n  cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};\n  cxx11test::int_array::size_type size = array.size();\n}\n{\n  // Test constructor delegation\n  cxx11test::delegate d1;\n  cxx11test::delegate d2();\n  cxx11test::delegate d3(45);\n}\n{\n  // Test override and final\n  cxx11test::overridden o1(55464);\n}\n{\n  // Test nullptr\n  char *c = nullptr;\n}\n{\n  // Test template brackets\n  std::vector<std::pair<int,char*>> v1;\n}\n{\n  // Unicode literals\n  char const *utf8 = u8\"UTF-8 string \\u2500\";\n  char16_t const *utf16 = u\"UTF-8 string \\u2500\";\n  char32_t const *utf32 = U\"UTF-32 string \\u2500\";\n}\n]])\n\n# _AC_PROG_CXX_CXX98 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])\n# -------------------------------------------------------------------\n\n# If the C++ compiler is not in ISO C++98 mode by default, try to add\n# an option to output variable CXX to make it so.  This macro tries\n# various options that select ISO C++98 on some system or another.  It\n# considers the compiler to be in ISO C++98 mode if it handles basic\n# features of the std namespace including: string, containers (list,\n# map, set, vector), streams (fstreams, iostreams, stringstreams,\n# iomanip), pair, exceptions and algorithms.\n\n\nAC_DEFUN([_AC_PROG_CXX_CXX98],\n[_AC_CXX_STD_TRY([cxx98],\n[_AC_CXX_CXX98_TEST_HEADER],\n[_AC_CXX_CXX98_TEST_BODY],\ndnl Try\ndnl GCC\t\t-std=gnu++98 (unused restrictive mode: -std=c++98)\ndnl IBM XL C\t-qlanglvl=extended\ndnl HP aC++\t-AA\ndnl Intel ICC\t-std=gnu++98\ndnl Solaris\tN/A (default)\ndnl Tru64\tN/A (default, but -std gnu could be used)\ndnl with extended modes being tried first.\n[[-std=gnu++98 -std=c++98 -qlanglvl=extended -AA]], [$1], [$2])[]dnl\n])# _AC_PROG_CXX_CXX98\n\n# _AC_PROG_CXX_CXX11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])\n# -------------------------------------------------------------------\n# If the C++ compiler is not in ISO CXX11 mode by default, try to add\n# an option to output variable CXX to make it so.  This macro tries\n# various options that select ISO C++11 on some system or another.  It\n# considers the compiler to be in ISO C++11 mode if it handles all the\n# tests from the C++98 checks, plus the following: Language features\n# (auto, constexpr, decltype, default/deleted constructors, delegate\n# constructors, final, initializer lists, lambda functions, nullptr,\n# override, range-based for loops, template brackets without spaces,\n# unicode literals) and library features (array, memory (shared_ptr,\n# weak_ptr), regex and tuple types).\nAC_DEFUN([_AC_PROG_CXX_CXX11],\n[_AC_CXX_STD_TRY([cxx11],\n[_AC_CXX_CXX11_TEST_HEADER\n_AC_CXX_CXX98_TEST_HEADER],\n[_AC_CXX_CXX11_TEST_BODY\n_AC_CXX_CXX98_TEST_BODY],\ndnl Try\ndnl GCC\t\t-std=gnu++11 (unused restrictive mode: -std=c++11) [and 0x variants]\ndnl IBM XL C\t-qlanglvl=extended0x\ndnl\t\t(pre-V12.1; unused restrictive mode: -qlanglvl=stdcxx11)\ndnl HP aC++\t-AA\ndnl Intel ICC\t-std=c++11 -std=c++0x\ndnl Solaris\tN/A (no support)\ndnl Tru64\tN/A (no support)\ndnl with extended modes being tried first.\n[[-std=gnu++11 -std=c++11 -std=gnu++0x -std=c++0x -qlanglvl=extended0x -AA]], [$1], [$2])[]dnl\n])# _AC_PROG_CXX_CXX11\n\n\n])# m4_version_prereq\n"
  },
  {
    "path": "m4/stdbool.m4",
    "content": "# Check for stdbool.h that conforms to C99.\n\ndnl Copyright (C) 2002-2006, 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\n#serial 8\n\n# Prepare for substituting <stdbool.h> if it is not supported.\n\nAC_DEFUN([AM_STDBOOL_H],\n[\n  AC_REQUIRE([AC_CHECK_HEADER_STDBOOL])\n  AC_REQUIRE([AC_CANONICAL_HOST])\n\n  dnl On some platforms, <stdbool.h> does not exist or does not conform to C99.\n  dnl On Solaris 10 with CC=cc CXX=CC, <stdbool.h> exists but is not usable\n  dnl in C++ mode (and no <cstdbool> exists). In this case, we use our\n  dnl replacement, also in C mode (for binary compatibility between C and C++).\n  if test \"$ac_cv_header_stdbool_h\" = yes; then\n    case \"$host_os\" in\n      solaris*)\n        if test -z \"$GCC\"; then\n          STDBOOL_H='stdbool.h'\n        else\n          STDBOOL_H=''\n        fi\n        ;;\n      *)\n        STDBOOL_H=''\n        ;;\n    esac\n  else\n    STDBOOL_H='stdbool.h'\n  fi\n  AC_SUBST([STDBOOL_H])\n  AM_CONDITIONAL([GL_GENERATE_STDBOOL_H], [test -n \"$STDBOOL_H\"])\n\n  if test \"$ac_cv_type__Bool\" = yes; then\n    HAVE__BOOL=1\n  else\n    HAVE__BOOL=0\n  fi\n  AC_SUBST([HAVE__BOOL])\n])\n\n# AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future.\nAC_DEFUN([gl_STDBOOL_H], [AM_STDBOOL_H])\n\n# This version of the macro is needed in autoconf <= 2.68.\n\nAC_DEFUN([AC_CHECK_HEADER_STDBOOL],\n  [AC_CACHE_CHECK([for stdbool.h that conforms to C99],\n     [ac_cv_header_stdbool_h],\n     [AC_COMPILE_IFELSE(\n        [AC_LANG_PROGRAM(\n           [[\n             #include <stdbool.h>\n\n             #ifdef __cplusplus\n              typedef bool Bool;\n             #else\n              typedef _Bool Bool;\n              #ifndef bool\n               \"error: bool is not defined\"\n              #endif\n              #ifndef false\n               \"error: false is not defined\"\n              #endif\n              #if false\n               \"error: false is not 0\"\n              #endif\n              #ifndef true\n               \"error: true is not defined\"\n              #endif\n              #if true != 1\n               \"error: true is not 1\"\n              #endif\n             #endif\n\n             #ifndef __bool_true_false_are_defined\n              \"error: __bool_true_false_are_defined is not defined\"\n             #endif\n\n             struct s { Bool s: 1; Bool t; bool u: 1; bool v; } s;\n\n             char a[true == 1 ? 1 : -1];\n             char b[false == 0 ? 1 : -1];\n             char c[__bool_true_false_are_defined == 1 ? 1 : -1];\n             char d[(bool) 0.5 == true ? 1 : -1];\n             /* See body of main program for 'e'.  */\n             char f[(Bool) 0.0 == false ? 1 : -1];\n             char g[true];\n             char h[sizeof (Bool)];\n             char i[sizeof s.t];\n             enum { j = false, k = true, l = false * true, m = true * 256 };\n             /* The following fails for\n                HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */\n             Bool n[m];\n             char o[sizeof n == m * sizeof n[0] ? 1 : -1];\n             char p[-1 - (Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];\n             /* Catch a bug in an HP-UX C compiler.  See\n                https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html\n                https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html\n              */\n             Bool q = true;\n             Bool *pq = &q;\n             bool *qq = &q;\n           ]],\n           [[\n             bool e = &s;\n             *pq |= q; *pq |= ! q;\n             *qq |= q; *qq |= ! q;\n             /* Refer to every declared value, to avoid compiler optimizations.  */\n             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l\n                     + !m + !n + !o + !p + !q + !pq + !qq);\n           ]])],\n        [ac_cv_header_stdbool_h=yes],\n        [ac_cv_header_stdbool_h=no])])\n   AC_CHECK_TYPES([_Bool])\n])\n"
  },
  {
    "path": "m4/stddef_h.m4",
    "content": "# stddef_h.m4 serial 11\ndnl Copyright (C) 2009-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl A placeholder for <stddef.h>, for platforms that have issues.\n\nAC_DEFUN_ONCE([gl_STDDEF_H],\n[\n  AC_REQUIRE([gl_STDDEF_H_DEFAULTS])\n  AC_REQUIRE([gt_TYPE_WCHAR_T])\n\n  dnl Persuade OpenBSD <stddef.h> to declare max_align_t.\n  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])\n\n  STDDEF_H=\n\n  dnl Test whether the type max_align_t exists and whether its alignment\n  dnl \"is as great as is supported by the implementation in all contexts\".\n  AC_CACHE_CHECK([for good max_align_t],\n    [gl_cv_type_max_align_t],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <stddef.h>\n            unsigned int s = sizeof (max_align_t);\n            #if defined __GNUC__ || defined __clang__ || defined __IBM__ALIGNOF__\n            int check1[2 * (__alignof__ (double) <= __alignof__ (max_align_t)) - 1];\n            int check2[2 * (__alignof__ (long double) <= __alignof__ (max_align_t)) - 1];\n            #endif\n            typedef struct { char a; max_align_t b; } max_helper;\n            typedef struct { char a; long b; } long_helper;\n            typedef struct { char a; double b; } double_helper;\n            typedef struct { char a; long double b; } long_double_helper;\n            int check3[2 * (offsetof (long_helper, b) <= offsetof (max_helper, b)) - 1];\n            int check4[2 * (offsetof (double_helper, b) <= offsetof (max_helper, b)) - 1];\n            int check5[2 * (offsetof (long_double_helper, b) <= offsetof (max_helper, b)) - 1];\n          ]])],\n       [gl_cv_type_max_align_t=yes],\n       [gl_cv_type_max_align_t=no])\n    ])\n  if test $gl_cv_type_max_align_t = no; then\n    HAVE_MAX_ALIGN_T=0\n    STDDEF_H=stddef.h\n  fi\n\n  if test $gt_cv_c_wchar_t = no; then\n    HAVE_WCHAR_T=0\n    STDDEF_H=stddef.h\n  fi\n\n  AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions],\n    [gl_cv_decl_null_works],\n    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h>\n      int test[2 * (sizeof NULL == sizeof (void *)) -1];\n]])],\n      [gl_cv_decl_null_works=yes],\n      [gl_cv_decl_null_works=no])])\n  if test $gl_cv_decl_null_works = no; then\n    REPLACE_NULL=1\n    STDDEF_H=stddef.h\n  fi\n\n  AC_SUBST([STDDEF_H])\n  AM_CONDITIONAL([GL_GENERATE_STDDEF_H], [test -n \"$STDDEF_H\"])\n  if test -n \"$STDDEF_H\"; then\n    gl_NEXT_HEADERS([stddef.h])\n  fi\n])\n\n# gl_STDDEF_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_STDDEF_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_STDDEF_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_STDDEF_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDDEF_H_MODULE_INDICATOR_DEFAULTS], [\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_STDDEF_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_STDDEF_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_STDDEF_H_DEFAULTS],\n[\n  dnl Assume proper GNU behavior unless another module says otherwise.\n  REPLACE_NULL=0;                AC_SUBST([REPLACE_NULL])\n  HAVE_MAX_ALIGN_T=1;            AC_SUBST([HAVE_MAX_ALIGN_T])\n  HAVE_WCHAR_T=1;                AC_SUBST([HAVE_WCHAR_T])\n])\n"
  },
  {
    "path": "m4/stdint.m4",
    "content": "# stdint.m4 serial 60\ndnl Copyright (C) 2001-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Paul Eggert and Bruno Haible.\ndnl Test whether <stdint.h> is supported or must be substituted.\n\nAC_PREREQ([2.61])\n\nAC_DEFUN_ONCE([gl_STDINT_H],\n[\n  AC_PREREQ([2.59])dnl\n  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n\n  AC_REQUIRE([gl_LIMITS_H])\n  AC_REQUIRE([gt_TYPE_WINT_T])\n\n  dnl For backward compatibility. Some packages may still be testing these\n  dnl macros.\n  AC_DEFINE([HAVE_LONG_LONG_INT], [1],\n    [Define to 1 if the system has the type 'long long int'.])\n  AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1],\n    [Define to 1 if the system has the type 'unsigned long long int'.])\n\n  dnl Check for <wchar.h>, in the same way as gl_WCHAR_H does.\n  AC_CHECK_HEADERS_ONCE([wchar.h])\n  if test $ac_cv_header_wchar_h = yes; then\n    HAVE_WCHAR_H=1\n  else\n    HAVE_WCHAR_H=0\n  fi\n  AC_SUBST([HAVE_WCHAR_H])\n\n  dnl Check for <inttypes.h>.\n  AC_CHECK_HEADERS_ONCE([inttypes.h])\n  if test $ac_cv_header_inttypes_h = yes; then\n    HAVE_INTTYPES_H=1\n  else\n    HAVE_INTTYPES_H=0\n  fi\n  AC_SUBST([HAVE_INTTYPES_H])\n\n  dnl Check for <sys/types.h>.\n  AC_CHECK_HEADERS_ONCE([sys/types.h])\n  if test $ac_cv_header_sys_types_h = yes; then\n    HAVE_SYS_TYPES_H=1\n  else\n    HAVE_SYS_TYPES_H=0\n  fi\n  AC_SUBST([HAVE_SYS_TYPES_H])\n\n  gl_CHECK_NEXT_HEADERS([stdint.h])\n  if test $ac_cv_header_stdint_h = yes; then\n    HAVE_STDINT_H=1\n  else\n    HAVE_STDINT_H=0\n  fi\n  AC_SUBST([HAVE_STDINT_H])\n\n  dnl Now see whether we need a substitute <stdint.h>.\n  if test $ac_cv_header_stdint_h = yes; then\n    AC_CACHE_CHECK([whether stdint.h conforms to C99],\n      [gl_cv_header_working_stdint_h],\n      [gl_cv_header_working_stdint_h=no\n       AC_COMPILE_IFELSE([\n         AC_LANG_PROGRAM([[\n#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */\n#define __STDC_CONSTANT_MACROS 1\n#define __STDC_LIMIT_MACROS 1\n#include <stdint.h>\n/* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in <wchar.h>.  */\n#if !(defined WCHAR_MIN && defined WCHAR_MAX)\n#error \"WCHAR_MIN, WCHAR_MAX not defined in <stdint.h>\"\n#endif\n]\ngl_STDINT_INCLUDES\n[\n#ifdef INT8_MAX\nint8_t a1 = INT8_MAX;\nint8_t a1min = INT8_MIN;\n#endif\n#ifdef INT16_MAX\nint16_t a2 = INT16_MAX;\nint16_t a2min = INT16_MIN;\n#endif\n#ifdef INT32_MAX\nint32_t a3 = INT32_MAX;\nint32_t a3min = INT32_MIN;\n#endif\n#ifdef INT64_MAX\nint64_t a4 = INT64_MAX;\nint64_t a4min = INT64_MIN;\n#endif\n#ifdef UINT8_MAX\nuint8_t b1 = UINT8_MAX;\n#else\ntypedef int b1[(unsigned char) -1 != 255 ? 1 : -1];\n#endif\n#ifdef UINT16_MAX\nuint16_t b2 = UINT16_MAX;\n#endif\n#ifdef UINT32_MAX\nuint32_t b3 = UINT32_MAX;\n#endif\n#ifdef UINT64_MAX\nuint64_t b4 = UINT64_MAX;\n#endif\nint_least8_t c1 = INT8_C (0x7f);\nint_least8_t c1max = INT_LEAST8_MAX;\nint_least8_t c1min = INT_LEAST8_MIN;\nint_least16_t c2 = INT16_C (0x7fff);\nint_least16_t c2max = INT_LEAST16_MAX;\nint_least16_t c2min = INT_LEAST16_MIN;\nint_least32_t c3 = INT32_C (0x7fffffff);\nint_least32_t c3max = INT_LEAST32_MAX;\nint_least32_t c3min = INT_LEAST32_MIN;\nint_least64_t c4 = INT64_C (0x7fffffffffffffff);\nint_least64_t c4max = INT_LEAST64_MAX;\nint_least64_t c4min = INT_LEAST64_MIN;\nuint_least8_t d1 = UINT8_C (0xff);\nuint_least8_t d1max = UINT_LEAST8_MAX;\nuint_least16_t d2 = UINT16_C (0xffff);\nuint_least16_t d2max = UINT_LEAST16_MAX;\nuint_least32_t d3 = UINT32_C (0xffffffff);\nuint_least32_t d3max = UINT_LEAST32_MAX;\nuint_least64_t d4 = UINT64_C (0xffffffffffffffff);\nuint_least64_t d4max = UINT_LEAST64_MAX;\nint_fast8_t e1 = INT_FAST8_MAX;\nint_fast8_t e1min = INT_FAST8_MIN;\nint_fast16_t e2 = INT_FAST16_MAX;\nint_fast16_t e2min = INT_FAST16_MIN;\nint_fast32_t e3 = INT_FAST32_MAX;\nint_fast32_t e3min = INT_FAST32_MIN;\nint_fast64_t e4 = INT_FAST64_MAX;\nint_fast64_t e4min = INT_FAST64_MIN;\nuint_fast8_t f1 = UINT_FAST8_MAX;\nuint_fast16_t f2 = UINT_FAST16_MAX;\nuint_fast32_t f3 = UINT_FAST32_MAX;\nuint_fast64_t f4 = UINT_FAST64_MAX;\n#ifdef INTPTR_MAX\nintptr_t g = INTPTR_MAX;\nintptr_t gmin = INTPTR_MIN;\n#endif\n#ifdef UINTPTR_MAX\nuintptr_t h = UINTPTR_MAX;\n#endif\nintmax_t i = INTMAX_MAX;\nuintmax_t j = UINTMAX_MAX;\n\n/* Check that SIZE_MAX has the correct type, if possible.  */\n#if 201112 <= __STDC_VERSION__\nint k = _Generic (SIZE_MAX, size_t: 0);\n#elif (2 <= __GNUC__ || 4 <= __clang_major__ || defined __IBM__TYPEOF__ \\\n       || (0x5110 <= __SUNPRO_C && !__STDC__))\nextern size_t k;\nextern __typeof__ (SIZE_MAX) k;\n#endif\n\n#include <limits.h> /* for CHAR_BIT */\n#define TYPE_MINIMUM(t) \\\n  ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t)))\n#define TYPE_MAXIMUM(t) \\\n  ((t) ((t) 0 < (t) -1 \\\n        ? (t) -1 \\\n        : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))\nstruct s {\n  int check_PTRDIFF:\n      PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t)\n      && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t)\n      ? 1 : -1;\n  /* Detect bug in FreeBSD 6.0/ia64 and FreeBSD 13.0/arm64.  */\n  int check_SIG_ATOMIC:\n      SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t)\n      && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t)\n      ? 1 : -1;\n  int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1;\n  int check_WCHAR:\n      WCHAR_MIN == TYPE_MINIMUM (wchar_t)\n      && WCHAR_MAX == TYPE_MAXIMUM (wchar_t)\n      ? 1 : -1;\n  /* Detect bug in mingw.  */\n  int check_WINT:\n      WINT_MIN == TYPE_MINIMUM (wint_t)\n      && WINT_MAX == TYPE_MAXIMUM (wint_t)\n      ? 1 : -1;\n\n  /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others.  */\n  int check_UINT8_C:\n        (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1;\n  int check_UINT16_C:\n        (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1;\n\n  /* Detect bugs in OpenBSD 3.9 stdint.h.  */\n#ifdef UINT8_MAX\n  int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1;\n#endif\n#ifdef UINT16_MAX\n  int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1;\n#endif\n#ifdef UINT32_MAX\n  int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1;\n#endif\n#ifdef UINT64_MAX\n  int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1;\n#endif\n  int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1;\n  int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1;\n  int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1;\n  int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1;\n  int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1;\n  int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1;\n  int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1;\n  int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1;\n  int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1;\n  int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1;\n  int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1;\n};\n         ]])],\n         [dnl Determine whether the various *_MIN, *_MAX macros are usable\n          dnl in preprocessor expression. We could do it by compiling a test\n          dnl program for each of these macros. It is faster to run a program\n          dnl that inspects the macro expansion.\n          dnl This detects a bug on HP-UX 11.23/ia64.\n          AC_RUN_IFELSE([\n            AC_LANG_PROGRAM([[\n#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */\n#define __STDC_CONSTANT_MACROS 1\n#define __STDC_LIMIT_MACROS 1\n#include <stdint.h>\n]\ngl_STDINT_INCLUDES\n[\n#include <stdio.h>\n#include <string.h>\n#define MVAL(macro) MVAL1(macro)\n#define MVAL1(expression) #expression\nstatic const char *macro_values[] =\n  {\n#ifdef INT8_MAX\n    MVAL (INT8_MAX),\n#endif\n#ifdef INT16_MAX\n    MVAL (INT16_MAX),\n#endif\n#ifdef INT32_MAX\n    MVAL (INT32_MAX),\n#endif\n#ifdef INT64_MAX\n    MVAL (INT64_MAX),\n#endif\n#ifdef UINT8_MAX\n    MVAL (UINT8_MAX),\n#endif\n#ifdef UINT16_MAX\n    MVAL (UINT16_MAX),\n#endif\n#ifdef UINT32_MAX\n    MVAL (UINT32_MAX),\n#endif\n#ifdef UINT64_MAX\n    MVAL (UINT64_MAX),\n#endif\n    NULL\n  };\n]], [[\n  const char **mv;\n  for (mv = macro_values; *mv != NULL; mv++)\n    {\n      const char *value = *mv;\n      /* Test whether it looks like a cast expression.  */\n      if (strncmp (value, \"((unsigned int)\"/*)*/, 15) == 0\n          || strncmp (value, \"((unsigned short)\"/*)*/, 17) == 0\n          || strncmp (value, \"((unsigned char)\"/*)*/, 16) == 0\n          || strncmp (value, \"((int)\"/*)*/, 6) == 0\n          || strncmp (value, \"((signed short)\"/*)*/, 15) == 0\n          || strncmp (value, \"((signed char)\"/*)*/, 14) == 0)\n        return mv - macro_values + 1;\n    }\n  return 0;\n]])],\n              [gl_cv_header_working_stdint_h=yes],\n              [],\n              [case \"$host_os\" in\n                         # Guess yes on native Windows.\n                 mingw*) gl_cv_header_working_stdint_h=\"guessing yes\" ;;\n                         # In general, assume it works.\n                 *)      gl_cv_header_working_stdint_h=\"guessing yes\" ;;\n               esac\n              ])\n         ])\n      ])\n  fi\n\n  HAVE_C99_STDINT_H=0\n  HAVE_SYS_BITYPES_H=0\n  HAVE_SYS_INTTYPES_H=0\n  STDINT_H=stdint.h\n  case \"$gl_cv_header_working_stdint_h\" in\n    *yes)\n      HAVE_C99_STDINT_H=1\n      dnl Now see whether the system <stdint.h> works without\n      dnl __STDC_CONSTANT_MACROS/__STDC_LIMIT_MACROS defined.\n      dnl If not, there would be problems when stdint.h is included from C++.\n      AC_CACHE_CHECK([whether stdint.h works without ISO C predefines],\n        [gl_cv_header_stdint_without_STDC_macros],\n        [gl_cv_header_stdint_without_STDC_macros=no\n         AC_COMPILE_IFELSE([\n           AC_LANG_PROGRAM([[\n#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */\n#include <stdint.h>\n]\ngl_STDINT_INCLUDES\n[\nintmax_t im = INTMAX_MAX;\nint32_t i32 = INT32_C (0x7fffffff);\n           ]])],\n           [gl_cv_header_stdint_without_STDC_macros=yes])\n        ])\n\n      if test $gl_cv_header_stdint_without_STDC_macros = no; then\n        AC_DEFINE([__STDC_CONSTANT_MACROS], [1],\n          [Define to 1 if the system <stdint.h> predates C++11.])\n        AC_DEFINE([__STDC_LIMIT_MACROS], [1],\n          [Define to 1 if the system <stdint.h> predates C++11.])\n      fi\n      AC_CACHE_CHECK([whether stdint.h has UINTMAX_WIDTH etc.],\n        [gl_cv_header_stdint_width],\n        [gl_cv_header_stdint_width=no\n         AC_COMPILE_IFELSE(\n           [AC_LANG_PROGRAM([[\n              /* Work if build is not clean.  */\n              #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1\n              #ifndef __STDC_WANT_IEC_60559_BFP_EXT__\n               #define __STDC_WANT_IEC_60559_BFP_EXT__ 1\n              #endif\n              #include <stdint.h>\n              ]gl_STDINT_INCLUDES[\n              int iw = UINTMAX_WIDTH;\n              ]])],\n           [gl_cv_header_stdint_width=yes])])\n      if test \"$gl_cv_header_stdint_width\" = yes; then\n        STDINT_H=\n      fi\n      ;;\n    *)\n      dnl Check for <sys/inttypes.h>, and for\n      dnl <sys/bitypes.h> (used in Linux libc4 >= 4.6.7 and libc5).\n      AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h])\n      if test $ac_cv_header_sys_inttypes_h = yes; then\n        HAVE_SYS_INTTYPES_H=1\n      fi\n      if test $ac_cv_header_sys_bitypes_h = yes; then\n        HAVE_SYS_BITYPES_H=1\n      fi\n      gl_STDINT_TYPE_PROPERTIES\n      ;;\n  esac\n\n  dnl The substitute stdint.h needs the substitute limit.h's _GL_INTEGER_WIDTH.\n  gl_REPLACE_LIMITS_H\n\n  AC_SUBST([HAVE_C99_STDINT_H])\n  AC_SUBST([HAVE_SYS_BITYPES_H])\n  AC_SUBST([HAVE_SYS_INTTYPES_H])\n  AC_SUBST([STDINT_H])\n  AM_CONDITIONAL([GL_GENERATE_STDINT_H], [test -n \"$STDINT_H\"])\n])\n\ndnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES)\ndnl Determine the size of each of the given types in bits.\nAC_DEFUN([gl_STDINT_BITSIZEOF],\n[\n  dnl Use a shell loop, to avoid bloating configure, and\n  dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into\n  dnl   config.h.in,\n  dnl - extra AC_SUBST calls, so that the right substitutions are made.\n  m4_foreach_w([gltype], [$1],\n    [AH_TEMPLATE([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),\n       [Define to the number of bits in type ']gltype['.])])\n  for gltype in $1 ; do\n    AC_CACHE_CHECK([for bit size of $gltype], [gl_cv_bitsizeof_${gltype}],\n      [AC_COMPUTE_INT([result], [sizeof ($gltype) * CHAR_BIT],\n         [$2\n#include <limits.h>], [result=unknown])\n       eval gl_cv_bitsizeof_${gltype}=\\$result\n      ])\n    eval result=\\$gl_cv_bitsizeof_${gltype}\n    if test $result = unknown; then\n      dnl Use a nonempty default, because some compilers, such as IRIX 5 cc,\n      dnl do a syntax check even on unused #if conditions and give an error\n      dnl on valid C code like this:\n      dnl   #if 0\n      dnl   # if  > 32\n      dnl   # endif\n      dnl   #endif\n      result=0\n    fi\n    GLTYPE=`echo \"$gltype\" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`\n    AC_DEFINE_UNQUOTED([BITSIZEOF_${GLTYPE}], [$result])\n    eval BITSIZEOF_${GLTYPE}=\\$result\n  done\n  m4_foreach_w([gltype], [$1],\n    [AC_SUBST([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])\n])\n\ndnl gl_CHECK_TYPES_SIGNED(TYPES, INCLUDES)\ndnl Determine the signedness of each of the given types.\ndnl Define HAVE_SIGNED_TYPE if type is signed.\nAC_DEFUN([gl_CHECK_TYPES_SIGNED],\n[\n  dnl Use a shell loop, to avoid bloating configure, and\n  dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into\n  dnl   config.h.in,\n  dnl - extra AC_SUBST calls, so that the right substitutions are made.\n  m4_foreach_w([gltype], [$1],\n    [AH_TEMPLATE([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),\n       [Define to 1 if ']gltype[' is a signed integer type.])])\n  for gltype in $1 ; do\n    AC_CACHE_CHECK([whether $gltype is signed], [gl_cv_type_${gltype}_signed],\n      [AC_COMPILE_IFELSE(\n         [AC_LANG_PROGRAM([$2[\n            int verify[2 * (($gltype) -1 < ($gltype) 0) - 1];]])],\n         result=yes, result=no)\n       eval gl_cv_type_${gltype}_signed=\\$result\n      ])\n    eval result=\\$gl_cv_type_${gltype}_signed\n    GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`\n    if test \"$result\" = yes; then\n      AC_DEFINE_UNQUOTED([HAVE_SIGNED_${GLTYPE}], [1])\n      eval HAVE_SIGNED_${GLTYPE}=1\n    else\n      eval HAVE_SIGNED_${GLTYPE}=0\n    fi\n  done\n  m4_foreach_w([gltype], [$1],\n    [AC_SUBST([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])\n])\n\ndnl gl_INTEGER_TYPE_SUFFIX(TYPES, INCLUDES)\ndnl Determine the suffix to use for integer constants of the given types.\ndnl Define t_SUFFIX for each such type.\nAC_DEFUN([gl_INTEGER_TYPE_SUFFIX],\n[\n  dnl Use a shell loop, to avoid bloating configure, and\n  dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into\n  dnl   config.h.in,\n  dnl - extra AC_SUBST calls, so that the right substitutions are made.\n  m4_foreach_w([gltype], [$1],\n    [AH_TEMPLATE(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX],\n       [Define to l, ll, u, ul, ull, etc., as suitable for\n        constants of type ']gltype['.])])\n  for gltype in $1 ; do\n    AC_CACHE_CHECK([for $gltype integer literal suffix],\n      [gl_cv_type_${gltype}_suffix],\n      [eval gl_cv_type_${gltype}_suffix=no\n       eval result=\\$gl_cv_type_${gltype}_signed\n       if test \"$result\" = yes; then\n         glsufu=\n       else\n         glsufu=u\n       fi\n       for glsuf in \"$glsufu\" ${glsufu}l ${glsufu}ll ${glsufu}i64; do\n         case $glsuf in\n           '')  gltype1='int';;\n           l)   gltype1='long int';;\n           ll)  gltype1='long long int';;\n           i64) gltype1='__int64';;\n           u)   gltype1='unsigned int';;\n           ul)  gltype1='unsigned long int';;\n           ull) gltype1='unsigned long long int';;\n           ui64)gltype1='unsigned __int64';;\n         esac\n         AC_COMPILE_IFELSE(\n           [AC_LANG_PROGRAM([$2[\n              extern $gltype foo;\n              extern $gltype1 foo;]])],\n           [eval gl_cv_type_${gltype}_suffix=\\$glsuf])\n         eval result=\\$gl_cv_type_${gltype}_suffix\n         test \"$result\" != no && break\n       done])\n    GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`\n    eval result=\\$gl_cv_type_${gltype}_suffix\n    test \"$result\" = no && result=\n    eval ${GLTYPE}_SUFFIX=\\$result\n    AC_DEFINE_UNQUOTED([${GLTYPE}_SUFFIX], [$result])\n  done\n  m4_foreach_w([gltype], [$1],\n    [AC_SUBST(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])])\n])\n\ndnl gl_STDINT_INCLUDES\nAC_DEFUN([gl_STDINT_INCLUDES],\n[[\n  #include <stddef.h>\n  #include <signal.h>\n  #if HAVE_WCHAR_H\n  # include <wchar.h>\n  #endif\n]])\n\ndnl gl_STDINT_TYPE_PROPERTIES\ndnl Compute HAVE_SIGNED_t, BITSIZEOF_t and t_SUFFIX, for all the types t\ndnl of interest to stdint.in.h.\nAC_DEFUN([gl_STDINT_TYPE_PROPERTIES],\n[\n  AC_REQUIRE([gl_MULTIARCH])\n  if test $APPLE_UNIVERSAL_BUILD = 0; then\n    gl_STDINT_BITSIZEOF([ptrdiff_t size_t],\n      [gl_STDINT_INCLUDES])\n  fi\n  gl_STDINT_BITSIZEOF([sig_atomic_t wchar_t wint_t],\n    [gl_STDINT_INCLUDES])\n  gl_CHECK_TYPES_SIGNED([sig_atomic_t wchar_t wint_t],\n    [gl_STDINT_INCLUDES])\n  gl_cv_type_ptrdiff_t_signed=yes\n  gl_cv_type_size_t_signed=no\n  if test $APPLE_UNIVERSAL_BUILD = 0; then\n    gl_INTEGER_TYPE_SUFFIX([ptrdiff_t size_t],\n      [gl_STDINT_INCLUDES])\n  fi\n  gl_INTEGER_TYPE_SUFFIX([sig_atomic_t wchar_t wint_t],\n    [gl_STDINT_INCLUDES])\n\n  dnl If wint_t is smaller than 'int', it cannot satisfy the ISO C 99\n  dnl requirement that wint_t is \"unchanged by default argument promotions\".\n  dnl In this case gnulib's <wchar.h> and <wctype.h> override wint_t.\n  dnl Set the variable BITSIZEOF_WINT_T accordingly.\n  if test $GNULIBHEADERS_OVERRIDE_WINT_T = 1; then\n    BITSIZEOF_WINT_T=32\n  fi\n])\n"
  },
  {
    "path": "m4/stdlib_h.m4",
    "content": "# stdlib_h.m4 serial 63\ndnl Copyright (C) 2007-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN_ONCE([gl_STDLIB_H],\n[\n  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])\n  gl_NEXT_HEADERS([stdlib.h])\n\n  dnl Check for declarations of anything we want to poison if the\n  dnl corresponding gnulib module is not in use, and which is not\n  dnl guaranteed by C89.\n  gl_WARN_ON_USE_PREPARE([[#include <stdlib.h>\n#if HAVE_SYS_LOADAVG_H\n/* OpenIndiana has a bug: <sys/time.h> must be included before\n   <sys/loadavg.h>.  */\n# include <sys/time.h>\n# include <sys/loadavg.h>\n#endif\n#if HAVE_RANDOM_H\n# include <random.h>\n#endif\n    ]], [_Exit aligned_alloc atoll canonicalize_file_name free\n    getloadavg getsubopt grantpt\n    initstate initstate_r mbtowc mkdtemp mkostemp mkostemps mkstemp mkstemps\n    posix_memalign posix_openpt ptsname ptsname_r qsort_r\n    random random_r reallocarray realpath rpmatch secure_getenv setenv\n    setstate setstate_r srandom srandom_r\n    strtod strtol strtold strtoll strtoul strtoull unlockpt unsetenv])\n\n  AC_REQUIRE([AC_C_RESTRICT])\n\n  AC_CHECK_DECLS_ONCE([ecvt])\n  if test $ac_cv_have_decl_ecvt = no; then\n    HAVE_DECL_ECVT=0\n  fi\n  AC_CHECK_DECLS_ONCE([fcvt])\n  if test $ac_cv_have_decl_fcvt = no; then\n    HAVE_DECL_FCVT=0\n  fi\n  AC_CHECK_DECLS_ONCE([gcvt])\n  if test $ac_cv_have_decl_gcvt = no; then\n    HAVE_DECL_GCVT=0\n  fi\n])\n\n# gl_STDLIB_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_STDLIB_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_STDLIB_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n  dnl Define it also as a C macro, for the benefit of the unit tests.\n  gl_MODULE_INDICATOR_FOR_TESTS([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_STDLIB_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS], [\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB__EXIT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ALIGNED_ALLOC])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ATOLL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CALLOC_POSIX])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CANONICALIZE_FILE_NAME])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREE_POSIX])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOADAVG])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETSUBOPT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GRANTPT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MALLOC_POSIX])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBTOWC])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKDTEMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKOSTEMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKOSTEMPS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKSTEMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKSTEMPS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_MEMALIGN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POSIX_OPENPT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTSNAME])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTSNAME_R])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PUTENV])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_QSORT_R])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM_R])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOCARRAY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOC_POSIX])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALPATH])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RPMATCH])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SECURE_GETENV])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETENV])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOD])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOLD])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOLL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOUL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOULL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SYSTEM_POSIX])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNLOCKPT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNSETENV])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCTOMB])\n    dnl Support Microsoft deprecated alias function names by default.\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_ECVT], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FCVT], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GCVT], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_MKTEMP], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_PUTENV], [1])\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_STDLIB_H_DEFAULTS],\n[\n  dnl Assume proper GNU behavior unless another module says otherwise.\n  HAVE__EXIT=1;              AC_SUBST([HAVE__EXIT])\n  HAVE_ALIGNED_ALLOC=1;      AC_SUBST([HAVE_ALIGNED_ALLOC])\n  HAVE_ATOLL=1;              AC_SUBST([HAVE_ATOLL])\n  HAVE_CANONICALIZE_FILE_NAME=1;  AC_SUBST([HAVE_CANONICALIZE_FILE_NAME])\n  HAVE_DECL_ECVT=1;          AC_SUBST([HAVE_DECL_ECVT])\n  HAVE_DECL_FCVT=1;          AC_SUBST([HAVE_DECL_FCVT])\n  HAVE_DECL_GCVT=1;          AC_SUBST([HAVE_DECL_GCVT])\n  HAVE_DECL_GETLOADAVG=1;    AC_SUBST([HAVE_DECL_GETLOADAVG])\n  HAVE_GETSUBOPT=1;          AC_SUBST([HAVE_GETSUBOPT])\n  HAVE_GRANTPT=1;            AC_SUBST([HAVE_GRANTPT])\n  HAVE_INITSTATE=1;          AC_SUBST([HAVE_INITSTATE])\n  HAVE_DECL_INITSTATE=1;     AC_SUBST([HAVE_DECL_INITSTATE])\n  HAVE_MBTOWC=1;             AC_SUBST([HAVE_MBTOWC])\n  HAVE_MKDTEMP=1;            AC_SUBST([HAVE_MKDTEMP])\n  HAVE_MKOSTEMP=1;           AC_SUBST([HAVE_MKOSTEMP])\n  HAVE_MKOSTEMPS=1;          AC_SUBST([HAVE_MKOSTEMPS])\n  HAVE_MKSTEMP=1;            AC_SUBST([HAVE_MKSTEMP])\n  HAVE_MKSTEMPS=1;           AC_SUBST([HAVE_MKSTEMPS])\n  HAVE_POSIX_MEMALIGN=1;     AC_SUBST([HAVE_POSIX_MEMALIGN])\n  HAVE_POSIX_OPENPT=1;       AC_SUBST([HAVE_POSIX_OPENPT])\n  HAVE_PTSNAME=1;            AC_SUBST([HAVE_PTSNAME])\n  HAVE_PTSNAME_R=1;          AC_SUBST([HAVE_PTSNAME_R])\n  HAVE_QSORT_R=1;            AC_SUBST([HAVE_QSORT_R])\n  HAVE_RANDOM=1;             AC_SUBST([HAVE_RANDOM])\n  HAVE_RANDOM_H=1;           AC_SUBST([HAVE_RANDOM_H])\n  HAVE_RANDOM_R=1;           AC_SUBST([HAVE_RANDOM_R])\n  HAVE_REALLOCARRAY=1;       AC_SUBST([HAVE_REALLOCARRAY])\n  HAVE_REALPATH=1;           AC_SUBST([HAVE_REALPATH])\n  HAVE_RPMATCH=1;            AC_SUBST([HAVE_RPMATCH])\n  HAVE_SECURE_GETENV=1;      AC_SUBST([HAVE_SECURE_GETENV])\n  HAVE_SETENV=1;             AC_SUBST([HAVE_SETENV])\n  HAVE_DECL_SETENV=1;        AC_SUBST([HAVE_DECL_SETENV])\n  HAVE_SETSTATE=1;           AC_SUBST([HAVE_SETSTATE])\n  HAVE_DECL_SETSTATE=1;      AC_SUBST([HAVE_DECL_SETSTATE])\n  HAVE_STRTOD=1;             AC_SUBST([HAVE_STRTOD])\n  HAVE_STRTOL=1;             AC_SUBST([HAVE_STRTOL])\n  HAVE_STRTOLD=1;            AC_SUBST([HAVE_STRTOLD])\n  HAVE_STRTOLL=1;            AC_SUBST([HAVE_STRTOLL])\n  HAVE_STRTOUL=1;            AC_SUBST([HAVE_STRTOUL])\n  HAVE_STRTOULL=1;           AC_SUBST([HAVE_STRTOULL])\n  HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA])\n  HAVE_SYS_LOADAVG_H=0;      AC_SUBST([HAVE_SYS_LOADAVG_H])\n  HAVE_UNLOCKPT=1;           AC_SUBST([HAVE_UNLOCKPT])\n  HAVE_DECL_UNSETENV=1;      AC_SUBST([HAVE_DECL_UNSETENV])\n  REPLACE_ALIGNED_ALLOC=0;   AC_SUBST([REPLACE_ALIGNED_ALLOC])\n  REPLACE_CALLOC=0;          AC_SUBST([REPLACE_CALLOC])\n  REPLACE_CANONICALIZE_FILE_NAME=0;  AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME])\n  REPLACE_FREE=0;            AC_SUBST([REPLACE_FREE])\n  REPLACE_INITSTATE=0;       AC_SUBST([REPLACE_INITSTATE])\n  REPLACE_MALLOC=0;          AC_SUBST([REPLACE_MALLOC])\n  REPLACE_MBTOWC=0;          AC_SUBST([REPLACE_MBTOWC])\n  REPLACE_MKSTEMP=0;         AC_SUBST([REPLACE_MKSTEMP])\n  REPLACE_POSIX_MEMALIGN=0;  AC_SUBST([REPLACE_POSIX_MEMALIGN])\n  REPLACE_PTSNAME=0;         AC_SUBST([REPLACE_PTSNAME])\n  REPLACE_PTSNAME_R=0;       AC_SUBST([REPLACE_PTSNAME_R])\n  REPLACE_PUTENV=0;          AC_SUBST([REPLACE_PUTENV])\n  REPLACE_QSORT_R=0;         AC_SUBST([REPLACE_QSORT_R])\n  REPLACE_RANDOM=0;          AC_SUBST([REPLACE_RANDOM])\n  REPLACE_RANDOM_R=0;        AC_SUBST([REPLACE_RANDOM_R])\n  REPLACE_REALLOC=0;         AC_SUBST([REPLACE_REALLOC])\n  REPLACE_REALLOCARRAY=0;    AC_SUBST([REPLACE_REALLOCARRAY])\n  REPLACE_REALPATH=0;        AC_SUBST([REPLACE_REALPATH])\n  REPLACE_SETENV=0;          AC_SUBST([REPLACE_SETENV])\n  REPLACE_SETSTATE=0;        AC_SUBST([REPLACE_SETSTATE])\n  REPLACE_STRTOD=0;          AC_SUBST([REPLACE_STRTOD])\n  REPLACE_STRTOL=0;          AC_SUBST([REPLACE_STRTOL])\n  REPLACE_STRTOLD=0;         AC_SUBST([REPLACE_STRTOLD])\n  REPLACE_STRTOLL=0;         AC_SUBST([REPLACE_STRTOLL])\n  REPLACE_STRTOUL=0;         AC_SUBST([REPLACE_STRTOUL])\n  REPLACE_STRTOULL=0;        AC_SUBST([REPLACE_STRTOULL])\n  REPLACE_UNSETENV=0;        AC_SUBST([REPLACE_UNSETENV])\n  REPLACE_WCTOMB=0;          AC_SUBST([REPLACE_WCTOMB])\n])\n"
  },
  {
    "path": "m4/string_h.m4",
    "content": "# Configure a GNU-like replacement for <string.h>.\n\n# Copyright (C) 2007-2021 Free Software Foundation, Inc.\n# This file is free software; the Free Software Foundation\n# gives unlimited permission to copy and/or distribute it,\n# with or without modifications, as long as this notice is preserved.\n\n# serial 32\n\n# Written by Paul Eggert.\n\nAC_DEFUN_ONCE([gl_STRING_H],\n[\n  dnl Ensure to expand the default settings once only, before all statements\n  dnl that occur in other macros.\n  AC_REQUIRE([gl_STRING_H_DEFAULTS])\n  gl_NEXT_HEADERS([string.h])\n\n  dnl Check for declarations of anything we want to poison if the\n  dnl corresponding gnulib module is not in use, and which is not\n  dnl guaranteed by C89.\n  gl_WARN_ON_USE_PREPARE([[#include <string.h>\n    ]],\n    [ffsl ffsll memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul\n     strdup strncat strndup strnlen strpbrk strsep strcasestr strtok_r\n     strerror_r strerrorname_np sigabbrev_np sigdescr_np strsignal strverscmp])\n\n  AC_REQUIRE([AC_C_RESTRICT])\n])\n\n# gl_STRING_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_STRING_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_STRING_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n  dnl Define it also as a C macro, for the benefit of the unit tests.\n  gl_MODULE_INDICATOR_FOR_TESTS([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_STRING_H_MODULE_INDICATOR_DEFAULTS], [\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXPLICIT_BZERO])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFSL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFSLL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMCHR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMMEM])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMPCPY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MEMRCHR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RAWMEMCHR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STPCPY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STPNCPY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCHRNUL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRDUP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNCAT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNDUP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNLEN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRPBRK])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSEP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSRCHR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSTR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCASECMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNCASECMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSPCASECMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCASESTR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCSPN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSPBRK])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSPN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSEP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSTOK_R])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR_R])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERRORNAME_NP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGABBREV_NP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGDESCR_NP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSIGNAL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRVERSCMP])\n    dnl Support Microsoft deprecated alias function names by default.\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_MEMCCPY], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_STRDUP], [1])\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_STRING_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_STRING_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_STRING_H_DEFAULTS],\n[\n  HAVE_MBSLEN=0;             AC_SUBST([HAVE_MBSLEN])\n  dnl Assume proper GNU behavior unless another module says otherwise.\n  HAVE_EXPLICIT_BZERO=1;        AC_SUBST([HAVE_EXPLICIT_BZERO])\n  HAVE_FFSL=1;                  AC_SUBST([HAVE_FFSL])\n  HAVE_FFSLL=1;                 AC_SUBST([HAVE_FFSLL])\n  HAVE_DECL_MEMMEM=1;           AC_SUBST([HAVE_DECL_MEMMEM])\n  HAVE_MEMPCPY=1;               AC_SUBST([HAVE_MEMPCPY])\n  HAVE_DECL_MEMRCHR=1;          AC_SUBST([HAVE_DECL_MEMRCHR])\n  HAVE_RAWMEMCHR=1;             AC_SUBST([HAVE_RAWMEMCHR])\n  HAVE_STPCPY=1;                AC_SUBST([HAVE_STPCPY])\n  HAVE_STPNCPY=1;               AC_SUBST([HAVE_STPNCPY])\n  HAVE_STRCHRNUL=1;             AC_SUBST([HAVE_STRCHRNUL])\n  HAVE_DECL_STRDUP=1;           AC_SUBST([HAVE_DECL_STRDUP])\n  HAVE_DECL_STRNDUP=1;          AC_SUBST([HAVE_DECL_STRNDUP])\n  HAVE_DECL_STRNLEN=1;          AC_SUBST([HAVE_DECL_STRNLEN])\n  HAVE_STRPBRK=1;               AC_SUBST([HAVE_STRPBRK])\n  HAVE_STRSEP=1;                AC_SUBST([HAVE_STRSEP])\n  HAVE_STRCASESTR=1;            AC_SUBST([HAVE_STRCASESTR])\n  HAVE_DECL_STRTOK_R=1;         AC_SUBST([HAVE_DECL_STRTOK_R])\n  HAVE_DECL_STRERROR_R=1;       AC_SUBST([HAVE_DECL_STRERROR_R])\n  HAVE_STRERRORNAME_NP=1;       AC_SUBST([HAVE_STRERRORNAME_NP])\n  HAVE_SIGABBREV_NP=1;          AC_SUBST([HAVE_SIGABBREV_NP])\n  HAVE_SIGDESCR_NP=1;           AC_SUBST([HAVE_SIGDESCR_NP])\n  HAVE_DECL_STRSIGNAL=1;        AC_SUBST([HAVE_DECL_STRSIGNAL])\n  HAVE_STRVERSCMP=1;            AC_SUBST([HAVE_STRVERSCMP])\n  REPLACE_FFSLL=0;              AC_SUBST([REPLACE_FFSLL])\n  REPLACE_MEMCHR=0;             AC_SUBST([REPLACE_MEMCHR])\n  REPLACE_MEMMEM=0;             AC_SUBST([REPLACE_MEMMEM])\n  REPLACE_STPNCPY=0;            AC_SUBST([REPLACE_STPNCPY])\n  REPLACE_STRCHRNUL=0;          AC_SUBST([REPLACE_STRCHRNUL])\n  REPLACE_STRDUP=0;             AC_SUBST([REPLACE_STRDUP])\n  REPLACE_STRNCAT=0;            AC_SUBST([REPLACE_STRNCAT])\n  REPLACE_STRNDUP=0;            AC_SUBST([REPLACE_STRNDUP])\n  REPLACE_STRNLEN=0;            AC_SUBST([REPLACE_STRNLEN])\n  REPLACE_STRSTR=0;             AC_SUBST([REPLACE_STRSTR])\n  REPLACE_STRCASESTR=0;         AC_SUBST([REPLACE_STRCASESTR])\n  REPLACE_STRTOK_R=0;           AC_SUBST([REPLACE_STRTOK_R])\n  REPLACE_STRERROR=0;           AC_SUBST([REPLACE_STRERROR])\n  REPLACE_STRERROR_R=0;         AC_SUBST([REPLACE_STRERROR_R])\n  REPLACE_STRERRORNAME_NP=0;    AC_SUBST([REPLACE_STRERRORNAME_NP])\n  REPLACE_STRSIGNAL=0;          AC_SUBST([REPLACE_STRSIGNAL])\n  UNDEFINE_STRTOK_R=0;          AC_SUBST([UNDEFINE_STRTOK_R])\n])\n"
  },
  {
    "path": "m4/strnlen.m4",
    "content": "# strnlen.m4 serial 14\ndnl Copyright (C) 2002-2003, 2005-2007, 2009-2021 Free Software Foundation,\ndnl Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_STRNLEN],\n[\n  AC_REQUIRE([gl_STRING_H_DEFAULTS])\n\n  dnl Persuade glibc <string.h> to declare strnlen().\n  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])\n\n  AC_CHECK_DECLS_ONCE([strnlen])\n  if test $ac_cv_have_decl_strnlen = no; then\n    HAVE_DECL_STRNLEN=0\n  else\n    m4_pushdef([AC_LIBOBJ], [:])\n    dnl Note: AC_FUNC_STRNLEN does AC_LIBOBJ([strnlen]).\n    AC_FUNC_STRNLEN\n    m4_popdef([AC_LIBOBJ])\n    if test $ac_cv_func_strnlen_working = no; then\n      REPLACE_STRNLEN=1\n    fi\n  fi\n])\n\n# Prerequisites of lib/strnlen.c.\nAC_DEFUN([gl_PREREQ_STRNLEN], [:])\n"
  },
  {
    "path": "m4/sys_types_h.m4",
    "content": "# sys_types_h.m4 serial 13\ndnl Copyright (C) 2011-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN_ONCE([gl_SYS_TYPES_H],\n[\n  AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS])\n\n  dnl Use sane struct stat types in OpenVMS 8.2 and later.\n  AC_DEFINE([_USE_STD_STAT], 1, [For standard stat data types on VMS.])\n\n  gl_NEXT_HEADERS([sys/types.h])\n\n  dnl Ensure the type pid_t gets defined.\n  AC_REQUIRE([AC_TYPE_PID_T])\n\n  dnl Ensure the type mode_t gets defined.\n  AC_REQUIRE([AC_TYPE_MODE_T])\n\n  dnl Whether to override the 'off_t' type.\n  AC_REQUIRE([gl_TYPE_OFF_T])\n\n  dnl Whether to override the 'dev_t' and 'ino_t' types.\n  m4_ifdef([gl_WINDOWS_STAT_INODES], [\n    AC_REQUIRE([gl_WINDOWS_STAT_INODES])\n  ], [\n    WINDOWS_STAT_INODES=0\n  ])\n  AC_SUBST([WINDOWS_STAT_INODES])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_SYS_TYPES_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_TYPE_H_MODULE_INDICATOR_DEFAULTS], [\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_SYS_TYPE_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_SYS_TYPES_H_DEFAULTS],\n[\n])\n\n# This works around a buggy version in autoconf <= 2.69.\n# See <https://lists.gnu.org/r/autoconf/2016-08/msg00014.html>\n# The 2.70 version isn't quoted properly, so override it too.\n\nm4_version_prereq([2.70.1], [], [\n\nm4_undefine([AC_HEADER_MAJOR])\nAC_DEFUN([AC_HEADER_MAJOR],\n[AC_CHECK_HEADERS_ONCE([sys/types.h])\nAC_CHECK_HEADER([sys/mkdev.h],\n                [AC_DEFINE([MAJOR_IN_MKDEV], [1],\n                           [Define to 1 if `major', `minor', and `makedev' are\n                            declared in <mkdev.h>.])])\nif test $ac_cv_header_sys_mkdev_h = no; then\n  AC_CHECK_HEADER([sys/sysmacros.h],\n                  [AC_DEFINE([MAJOR_IN_SYSMACROS], [1],\n                             [Define to 1 if `major', `minor', and `makedev'\n                              are declared in <sysmacros.h>.])])\nfi\n])# AC_HEADER_MAJOR\n\n])\n"
  },
  {
    "path": "m4/threadlib.m4",
    "content": "# threadlib.m4 serial 31\ndnl Copyright (C) 2005-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\n\nAC_PREREQ([2.60])\n\ndnl The general structure of the multithreading modules in gnulib is that we\ndnl have three set of modules:\ndnl\ndnl   * POSIX API:\ndnl     pthread, which combines\ndnl       pthread-h\ndnl       pthread-thread\ndnl       pthread-once\ndnl       pthread-mutex\ndnl       pthread-rwlock\ndnl       pthread-cond\ndnl       pthread-tss\ndnl       pthread-spin\ndnl     sched_yield\ndnl\ndnl   * ISO C API:\ndnl     threads, which combines\ndnl       threads-h\ndnl       thrd\ndnl       mtx\ndnl       cnd\ndnl       tss\ndnl\ndnl   * Gnulib API, with an implementation that can be chosen at configure\ndnl     time through the option --enable-threads=...\ndnl       thread\ndnl       lock\ndnl       cond\ndnl       tls\ndnl       yield\ndnl\ndnl They are independent, except for the fact that\ndnl   - the implementation of the ISO C API may use the POSIX (or some other\ndnl     platform dependent) API,\ndnl   - the implementation of the Gnulib API may use the POSIX or ISO C or\ndnl     some other platform dependent API, depending on the --enable-threads\ndnl     option.\ndnl\ndnl This file contains macros for all of these APIs!\n\ndnl ============================================================================\ndnl Macros for all thread APIs\n\nAC_DEFUN([gl_ANYTHREADLIB_EARLY],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  if test -z \"$gl_anythreadlib_early_done\"; then\n    case \"$host_os\" in\n      osf*)\n        # On OSF/1, the compiler needs the flag -D_REENTRANT so that it\n        # groks <pthread.h>. cc also understands the flag -pthread, but\n        # we don't use it because 1. gcc-2.95 doesn't understand -pthread,\n        # 2. putting a flag into CPPFLAGS that has an effect on the linker\n        # causes the AC_LINK_IFELSE test below to succeed unexpectedly,\n        # leading to wrong values of LIBTHREAD and LTLIBTHREAD.\n        CPPFLAGS=\"$CPPFLAGS -D_REENTRANT\"\n        ;;\n    esac\n    # Some systems optimize for single-threaded programs by default, and\n    # need special flags to disable these optimizations. For example, the\n    # definition of 'errno' in <errno.h>.\n    case \"$host_os\" in\n      aix* | freebsd*) CPPFLAGS=\"$CPPFLAGS -D_THREAD_SAFE\" ;;\n      solaris*) CPPFLAGS=\"$CPPFLAGS -D_REENTRANT\" ;;\n    esac\n    gl_anythreadlib_early_done=done\n  fi\n])\n\ndnl Checks whether the compiler and linker support weak declarations of symbols.\n\nAC_DEFUN([gl_WEAK_SYMBOLS],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_CACHE_CHECK([whether imported symbols can be declared weak],\n    [gl_cv_have_weak],\n    [gl_cv_have_weak=no\n     dnl First, test whether the compiler accepts it syntactically.\n     AC_LINK_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[extern void xyzzy ();\n#pragma weak xyzzy]],\n          [[xyzzy();]])],\n       [gl_cv_have_weak=maybe])\n     if test $gl_cv_have_weak = maybe; then\n       dnl Second, test whether it actually works. On Cygwin 1.7.2, with\n       dnl gcc 4.3, symbols declared weak always evaluate to the address 0.\n       AC_RUN_IFELSE(\n         [AC_LANG_SOURCE([[\n#include <stdio.h>\n#pragma weak fputs\nint main ()\n{\n  return (fputs == NULL);\n}]])],\n         [gl_cv_have_weak=yes],\n         [gl_cv_have_weak=no],\n         [dnl When cross-compiling, assume that only ELF platforms support\n          dnl weak symbols.\n          AC_EGREP_CPP([Extensible Linking Format],\n            [#ifdef __ELF__\n             Extensible Linking Format\n             #endif\n            ],\n            [gl_cv_have_weak=\"guessing yes\"],\n            [gl_cv_have_weak=\"guessing no\"])\n         ])\n     fi\n     dnl But when linking statically, weak symbols don't work.\n     case \" $LDFLAGS \" in\n       *\" -static \"*) gl_cv_have_weak=no ;;\n     esac\n     dnl Test for a bug in FreeBSD 11: A link error occurs when using a weak\n     dnl symbol and linking against a shared library that has a dependency on\n     dnl the shared library that defines the symbol.\n     case \"$gl_cv_have_weak\" in\n       *yes)\n         case \"$host_os\" in\n           freebsd* | dragonfly* | midnightbsd*)\n             : > conftest1.c\n             $CC $CPPFLAGS $CFLAGS $LDFLAGS -fPIC -shared -o libempty.so conftest1.c -lpthread >&AS_MESSAGE_LOG_FD 2>&1\n             cat <<EOF > conftest2.c\n#include <pthread.h>\n#pragma weak pthread_mutexattr_gettype\nint main ()\n{\n  return (pthread_mutexattr_gettype != NULL);\n}\nEOF\n             $CC $CPPFLAGS $CFLAGS $LDFLAGS -o conftest conftest2.c libempty.so >&AS_MESSAGE_LOG_FD 2>&1 \\\n               || gl_cv_have_weak=no\n             rm -f conftest1.c libempty.so conftest2.c conftest\n             ;;\n         esac\n         ;;\n     esac\n    ])\n  case \"$gl_cv_have_weak\" in\n    *yes)\n      AC_DEFINE([HAVE_WEAK_SYMBOLS], [1],\n        [Define to 1 if the compiler and linker support weak declarations of symbols.])\n      ;;\n  esac\n])\n\ndnl ============================================================================\ndnl Macros for the POSIX API\n\ndnl gl_PTHREADLIB\ndnl -------------\ndnl Tests for the libraries needs for using the POSIX threads API.\ndnl Sets the variable LIBPTHREAD to the linker options for use in a Makefile.\ndnl Sets the variable LIBPMULTITHREAD, for programs that really need\ndnl multithread functionality. The difference between LIBPTHREAD and\ndnl LIBPMULTITHREAD is that on platforms supporting weak symbols, typically\ndnl LIBPTHREAD is empty whereas LIBPMULTITHREAD is not.\ndnl Sets the variable LIB_SCHED_YIELD to the linker options needed to use the\ndnl sched_yield() function.\ndnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for\ndnl multithread-safe programs.\ndnl Defines the C macro HAVE_PTHREAD_API if (at least parts of) the POSIX\ndnl threads API is available.\n\ndnl The guts of gl_PTHREADLIB. Needs to be expanded only once.\n\nAC_DEFUN([gl_PTHREADLIB_BODY],\n[\n  AC_REQUIRE([gl_ANYTHREADLIB_EARLY])\n  if test -z \"$gl_pthreadlib_body_done\"; then\n    gl_pthread_api=no\n    LIBPTHREAD=\n    LIBPMULTITHREAD=\n    # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that\n    # it groks <pthread.h>. It's added above, in gl_ANYTHREADLIB_EARLY.\n    AC_CHECK_HEADER([pthread.h],\n      [gl_have_pthread_h=yes], [gl_have_pthread_h=no])\n    if test \"$gl_have_pthread_h\" = yes; then\n      # Other possible tests:\n      #   -lpthreads (FSU threads, PCthreads)\n      #   -lgthreads\n      # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist\n      # in libc. IRIX 6.5 has the first one in both libc and libpthread, but\n      # the second one only in libpthread, and lock.c needs it.\n      #\n      # If -pthread works, prefer it to -lpthread, since Ubuntu 14.04\n      # needs -pthread for some reason.  See:\n      # https://lists.gnu.org/r/bug-gnulib/2014-09/msg00023.html\n      save_LIBS=$LIBS\n      for gl_pthread in '' '-pthread'; do\n        LIBS=\"$LIBS $gl_pthread\"\n        AC_LINK_IFELSE(\n          [AC_LANG_PROGRAM(\n             [[#include <pthread.h>\n               pthread_mutex_t m;\n               pthread_mutexattr_t ma;\n             ]],\n             [[pthread_mutex_lock (&m);\n               pthread_mutexattr_init (&ma);]])],\n          [gl_pthread_api=yes\n           LIBPTHREAD=$gl_pthread\n           LIBPMULTITHREAD=$gl_pthread])\n        LIBS=$save_LIBS\n        test $gl_pthread_api = yes && break\n      done\n      echo \"$as_me:__oline__: gl_pthread_api=$gl_pthread_api\" >&AS_MESSAGE_LOG_FD\n      echo \"$as_me:__oline__: LIBPTHREAD=$LIBPTHREAD\" >&AS_MESSAGE_LOG_FD\n\n      gl_pthread_in_glibc=no\n      # On Linux with glibc >= 2.34, libc contains the fully functional\n      # pthread functions.\n      case \"$host_os\" in\n        linux*)\n          AC_EGREP_CPP([Lucky user],\n            [#include <features.h>\n             #ifdef __GNU_LIBRARY__\n              #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 34) || (__GLIBC__ > 2)\n               Lucky user\n              #endif\n             #endif\n            ],\n            [gl_pthread_in_glibc=yes],\n            [])\n          ;;\n      esac\n      echo \"$as_me:__oline__: gl_pthread_in_glibc=$gl_pthread_in_glibc\" >&AS_MESSAGE_LOG_FD\n\n      # Test for libpthread by looking for pthread_kill. (Not pthread_self,\n      # since it is defined as a macro on OSF/1.)\n      if test $gl_pthread_api = yes && test -z \"$LIBPTHREAD\"; then\n        # The program links fine without libpthread. But it may actually\n        # need to link with libpthread in order to create multiple threads.\n        AC_CHECK_LIB([pthread], [pthread_kill],\n          [if test $gl_pthread_in_glibc = yes; then\n             LIBPMULTITHREAD=\n           else\n             LIBPMULTITHREAD=-lpthread\n             # On Solaris and HP-UX, most pthread functions exist also in libc.\n             # Therefore pthread_in_use() needs to actually try to create a\n             # thread: pthread_create from libc will fail, whereas\n             # pthread_create will actually create a thread.\n             # On Solaris 10 or newer, this test is no longer needed, because\n             # libc contains the fully functional pthread functions.\n             case \"$host_os\" in\n               solaris | solaris2.[1-9] | solaris2.[1-9].* | hpux*)\n                 AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1],\n                   [Define if the pthread_in_use() detection is hard.])\n             esac\n           fi\n          ])\n      elif test $gl_pthread_api != yes; then\n        # Some library is needed. Try libpthread and libc_r.\n        AC_CHECK_LIB([pthread], [pthread_kill],\n          [gl_pthread_api=yes\n           LIBPTHREAD=-lpthread\n           LIBPMULTITHREAD=-lpthread])\n        if test $gl_pthread_api != yes; then\n          # For FreeBSD 4.\n          AC_CHECK_LIB([c_r], [pthread_kill],\n            [gl_pthread_api=yes\n             LIBPTHREAD=-lc_r\n             LIBPMULTITHREAD=-lc_r])\n        fi\n      fi\n      echo \"$as_me:__oline__: LIBPMULTITHREAD=$LIBPMULTITHREAD\" >&AS_MESSAGE_LOG_FD\n    fi\n    AC_MSG_CHECKING([whether POSIX threads API is available])\n    AC_MSG_RESULT([$gl_pthread_api])\n    AC_SUBST([LIBPTHREAD])\n    AC_SUBST([LIBPMULTITHREAD])\n    if test $gl_pthread_api = yes; then\n      AC_DEFINE([HAVE_PTHREAD_API], [1],\n        [Define if you have the <pthread.h> header and the POSIX threads API.])\n    fi\n\n    dnl On some systems, sched_yield is in librt, rather than in libpthread.\n    AC_LINK_IFELSE(\n      [AC_LANG_PROGRAM(\n         [[#include <sched.h>]],\n         [[sched_yield ();]])],\n      [LIB_SCHED_YIELD=\n      ],\n      [dnl Solaris 7...10 has sched_yield in librt, not in libpthread or libc.\n       AC_CHECK_LIB([rt], [sched_yield], [LIB_SCHED_YIELD=-lrt],\n         [dnl Solaris 2.5.1, 2.6 has sched_yield in libposix4, not librt.\n          AC_CHECK_LIB([posix4], [sched_yield], [LIB_SCHED_YIELD=-lposix4])])\n      ])\n    AC_SUBST([LIB_SCHED_YIELD])\n\n    gl_pthreadlib_body_done=done\n  fi\n])\n\nAC_DEFUN([gl_PTHREADLIB],\n[\n  AC_REQUIRE([gl_ANYTHREADLIB_EARLY])\n  gl_PTHREADLIB_BODY\n])\n\ndnl ============================================================================\ndnl Macros for the ISO C API\n\ndnl gl_STDTHREADLIB\ndnl ---------------\ndnl Tests for the libraries needs for using the ISO C threads API.\ndnl Sets the variable LIBSTDTHREAD to the linker options for use in a Makefile.\ndnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for\ndnl multithread-safe programs.\ndnl Defines the C macro HAVE_THREADS_H if (at least parts of) the ISO C threads\ndnl API is available.\n\ndnl The guts of gl_STDTHREADLIB. Needs to be expanded only once.\n\nAC_DEFUN([gl_STDTHREADLIB_BODY],\n[\n  AC_REQUIRE([gl_ANYTHREADLIB_EARLY])\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  if test -z \"$gl_stdthreadlib_body_done\"; then\n    AC_CHECK_HEADERS_ONCE([threads.h])\n\n    case \"$host_os\" in\n      mingw*)\n        LIBSTDTHREAD=\n        ;;\n      *)\n        gl_PTHREADLIB_BODY\n        if test $ac_cv_header_threads_h = yes; then\n          dnl glibc >= 2.29 has thrd_create in libpthread.\n          dnl FreeBSD >= 10 has thrd_create in libstdthreads; this library depends\n          dnl on libpthread (for the symbol 'pthread_mutexattr_gettype').\n          dnl glibc >= 2.34, AIX >= 7.1, and Solaris >= 11.4 have thrd_create in\n          dnl libc.\n          AC_CHECK_FUNCS([thrd_create])\n          if test $ac_cv_func_thrd_create = yes; then\n            LIBSTDTHREAD=\n          else\n            AC_CHECK_LIB([stdthreads], [thrd_create], [\n              LIBSTDTHREAD='-lstdthreads -lpthread'\n            ], [\n              dnl Guess that thrd_create is in libpthread.\n              LIBSTDTHREAD=\"$LIBPMULTITHREAD\"\n            ])\n          fi\n        else\n          dnl Libraries needed by thrd.c, mtx.c, cnd.c, tss.c.\n          LIBSTDTHREAD=\"$LIBPMULTITHREAD $LIB_SCHED_YIELD\"\n        fi\n        ;;\n    esac\n    AC_SUBST([LIBSTDTHREAD])\n\n    AC_MSG_CHECKING([whether ISO C threads API is available])\n    AC_MSG_RESULT([$ac_cv_header_threads_h])\n    gl_stdthreadlib_body_done=done\n  fi\n])\n\nAC_DEFUN([gl_STDTHREADLIB],\n[\n  AC_REQUIRE([gl_ANYTHREADLIB_EARLY])\n  gl_STDTHREADLIB_BODY\n])\n\ndnl ============================================================================\ndnl Macros for the Gnulib API\n\ndnl gl_THREADLIB\ndnl ------------\ndnl Tests for a multithreading library to be used.\ndnl If the configure.ac contains a definition of the gl_THREADLIB_DEFAULT_NO\ndnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the\ndnl default is 'no', otherwise it is system dependent. In both cases, the user\ndnl can change the choice through the options --enable-threads=choice or\ndnl --disable-threads.\ndnl Defines at most one of the macros USE_ISOC_THREADS, USE_POSIX_THREADS,\ndnl USE_ISOC_AND_POSIX_THREADS, USE_WINDOWS_THREADS.\ndnl The choice --enable-threads=isoc+posix is available only on platforms that\ndnl have both the ISO C and the POSIX threads APIs. It has the effect of using\ndnl the ISO C API for most things and the POSIX API only for creating and\ndnl controlling threads (because there is no equivalent to pthread_atfork in\ndnl the ISO C API).\ndnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use\ndnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with\ndnl libtool).\ndnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for\ndnl programs that really need multithread functionality. The difference\ndnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak\ndnl symbols, typically LIBTHREAD is empty whereas LIBMULTITHREAD is not.\ndnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for\ndnl multithread-safe programs.\ndnl Since support for GNU pth was removed, $LTLIBTHREAD and $LIBTHREAD have the\ndnl same value, and similarly $LTLIBMULTITHREAD and $LIBMULTITHREAD have the\ndnl same value. Only system libraries are needed.\n\nAC_DEFUN([gl_THREADLIB_EARLY],\n[\n  AC_REQUIRE([gl_THREADLIB_EARLY_BODY])\n])\n\ndnl The guts of gl_THREADLIB_EARLY. Needs to be expanded only once.\n\nAC_DEFUN([gl_THREADLIB_EARLY_BODY],\n[\n  dnl Ordering constraints: This macro modifies CPPFLAGS in a way that\n  dnl influences the result of the autoconf tests that test for *_unlocked\n  dnl declarations, on AIX 5 at least. Therefore it must come early.\n  AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl\n  AC_BEFORE([$0], [gl_ARGP])dnl\n\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  dnl _GNU_SOURCE is needed for pthread_rwlock_t on glibc systems.\n  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])\n  dnl Check for multithreading.\n  m4_ifdef([gl_THREADLIB_DEFAULT_NO],\n    [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])],\n    [m4_divert_text([DEFAULTS], [gl_use_threads_default=])])\n  m4_divert_text([DEFAULTS], [gl_use_winpthreads_default=])\n  AC_ARG_ENABLE([threads],\nAS_HELP_STRING([--enable-threads={isoc|posix|isoc+posix|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [\nAS_HELP_STRING([--disable-threads], [build without multithread safety])]),\n    [gl_use_threads=$enableval],\n    [if test -n \"$gl_use_threads_default\"; then\n       gl_use_threads=\"$gl_use_threads_default\"\n     else\nchangequote(,)dnl\n       case \"$host_os\" in\n         dnl Disable multithreading by default on OSF/1, because it interferes\n         dnl with fork()/exec(): When msgexec is linked with -lpthread, its\n         dnl child process gets an endless segmentation fault inside execvp().\n         osf*) gl_use_threads=no ;;\n         dnl Disable multithreading by default on Cygwin 1.5.x, because it has\n         dnl bugs that lead to endless loops or crashes. See\n         dnl <https://cygwin.com/ml/cygwin/2009-08/msg00283.html>.\n         cygwin*)\n               case `uname -r` in\n                 1.[0-5].*) gl_use_threads=no ;;\n                 *)         gl_use_threads=yes ;;\n               esac\n               ;;\n         dnl Obey gl_AVOID_WINPTHREAD on mingw.\n         mingw*)\n               case \"$gl_use_winpthreads_default\" in\n                 yes) gl_use_threads=posix ;;\n                 no)  gl_use_threads=windows ;;\n                 *)   gl_use_threads=yes ;;\n               esac\n               ;;\n         *)    gl_use_threads=yes ;;\n       esac\nchangequote([,])dnl\n     fi\n    ])\n  if test \"$gl_use_threads\" = yes \\\n     || test \"$gl_use_threads\" = isoc \\\n     || test \"$gl_use_threads\" = posix \\\n     || test \"$gl_use_threads\" = isoc+posix; then\n    # For using <threads.h> or <pthread.h>:\n    gl_ANYTHREADLIB_EARLY\n  fi\n])\n\ndnl The guts of gl_THREADLIB. Needs to be expanded only once.\n\nAC_DEFUN([gl_THREADLIB_BODY],\n[\n  AC_REQUIRE([gl_THREADLIB_EARLY_BODY])\n  gl_threads_api=none\n  LIBTHREAD=\n  LTLIBTHREAD=\n  LIBMULTITHREAD=\n  LTLIBMULTITHREAD=\n  if test \"$gl_use_threads\" != no; then\n    dnl Check whether the compiler and linker support weak declarations.\n    gl_WEAK_SYMBOLS\n    if case \"$gl_cv_have_weak\" in *yes) true;; *) false;; esac; then\n      dnl If we use weak symbols to implement pthread_in_use / pth_in_use /\n      dnl thread_in_use, we also need to test whether the ISO C 11 thrd_create\n      dnl facility is in use.\n      AC_CHECK_HEADERS_ONCE([threads.h])\n      :\n    fi\n    if test \"$gl_use_threads\" = isoc || test \"$gl_use_threads\" = isoc+posix; then\n      AC_CHECK_HEADERS_ONCE([threads.h])\n      gl_have_isoc_threads=\"$ac_cv_header_threads_h\"\n    fi\n    if test \"$gl_use_threads\" = yes \\\n       || test \"$gl_use_threads\" = posix \\\n       || test \"$gl_use_threads\" = isoc+posix; then\n      gl_PTHREADLIB_BODY\n      LIBTHREAD=$LIBPTHREAD LTLIBTHREAD=$LIBPTHREAD\n      LIBMULTITHREAD=$LIBPMULTITHREAD LTLIBMULTITHREAD=$LIBPMULTITHREAD\n      if test $gl_pthread_api = yes; then\n        if test \"$gl_use_threads\" = isoc+posix && test \"$gl_have_isoc_threads\" = yes; then\n          gl_threads_api='isoc+posix'\n          AC_DEFINE([USE_ISOC_AND_POSIX_THREADS], [1],\n            [Define if the combination of the ISO C and POSIX multithreading APIs can be used.])\n          LIBTHREAD= LTLIBTHREAD=\n        else\n          gl_threads_api=posix\n          AC_DEFINE([USE_POSIX_THREADS], [1],\n            [Define if the POSIX multithreading library can be used.])\n          if test -z \"$LIBMULTITHREAD\" && test -z \"$LTLIBMULTITHREAD\"; then\n            AC_DEFINE([USE_POSIX_THREADS_FROM_LIBC], [1],\n              [Define if references to the POSIX multithreading library are satisfied by libc.])\n          else\n            if case \"$gl_cv_have_weak\" in *yes) true;; *) false;; esac; then\n              AC_DEFINE([USE_POSIX_THREADS_WEAK], [1],\n                [Define if references to the POSIX multithreading library should be made weak.])\n              LIBTHREAD= LTLIBTHREAD=\n            else\n              case \"$host_os\" in\n                freebsd* | dragonfly* | midnightbsd*)\n                  if test \"x$LIBTHREAD\" != \"x$LIBMULTITHREAD\"; then\n                    dnl If weak symbols can't tell whether pthread_create(), pthread_key_create()\n                    dnl etc. will succeed, we need a runtime test.\n                    AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1],\n                      [Define if the pthread_in_use() detection is hard.])\n                  fi\n                  ;;\n              esac\n            fi\n          fi\n        fi\n      fi\n    fi\n    if test $gl_threads_api = none; then\n      if test \"$gl_use_threads\" = isoc && test \"$gl_have_isoc_threads\" = yes; then\n        gl_STDTHREADLIB_BODY\n        LIBTHREAD=$LIBSTDTHREAD LTLIBTHREAD=$LIBSTDTHREAD\n        LIBMULTITHREAD=$LIBSTDTHREAD LTLIBMULTITHREAD=$LIBSTDTHREAD\n        gl_threads_api=isoc\n        AC_DEFINE([USE_ISOC_THREADS], [1],\n          [Define if the ISO C multithreading library can be used.])\n      fi\n    fi\n    if test $gl_threads_api = none; then\n      case \"$gl_use_threads\" in\n        yes | windows | win32) # The 'win32' is for backward compatibility.\n          if { case \"$host_os\" in\n                 mingw*) true;;\n                 *) false;;\n               esac\n             }; then\n            gl_threads_api=windows\n            AC_DEFINE([USE_WINDOWS_THREADS], [1],\n              [Define if the native Windows multithreading API can be used.])\n          fi\n          ;;\n      esac\n    fi\n  fi\n  AC_MSG_CHECKING([for multithread API to use])\n  AC_MSG_RESULT([$gl_threads_api])\n  AC_SUBST([LIBTHREAD])\n  AC_SUBST([LTLIBTHREAD])\n  AC_SUBST([LIBMULTITHREAD])\n  AC_SUBST([LTLIBMULTITHREAD])\n])\n\nAC_DEFUN([gl_THREADLIB],\n[\n  AC_REQUIRE([gl_THREADLIB_EARLY])\n  AC_REQUIRE([gl_THREADLIB_BODY])\n])\n\n\ndnl gl_DISABLE_THREADS\ndnl ------------------\ndnl Sets the gl_THREADLIB default so that threads are not used by default.\ndnl The user can still override it at installation time, by using the\ndnl configure option '--enable-threads'.\n\nAC_DEFUN([gl_DISABLE_THREADS], [\n  m4_divert_text([INIT_PREPARE], [gl_use_threads_default=no])\n])\n\n\ndnl gl_AVOID_WINPTHREAD\ndnl -------------------\ndnl Sets the gl_THREADLIB default so that on mingw, a dependency to the\ndnl libwinpthread DLL (mingw-w64 winpthreads library) is avoided.\ndnl The user can still override it at installation time, by using the\ndnl configure option '--enable-threads'.\n\nAC_DEFUN([gl_AVOID_WINPTHREAD], [\n  m4_divert_text([INIT_PREPARE], [gl_use_winpthreads_default=no])\n])\n\n\ndnl ============================================================================\n\n\ndnl Survey of platforms:\ndnl\ndnl Platform           Available  Compiler    Supports   test-lock\ndnl                    flavours   option      weak       result\ndnl ---------------    ---------  ---------   --------   ---------\ndnl Linux 2.4/glibc    posix      -lpthread       Y      OK\ndnl\ndnl Linux/glibc 2.34   posix                      Y      OK\ndnl\ndnl GNU Hurd/glibc     posix      -lpthread       Y      OK\ndnl\ndnl Ubuntu 14.04       posix      -pthread        Y      OK\ndnl\ndnl FreeBSD 5.3        posix      -lc_r           Y\ndnl                    posix      -lkse ?         Y\ndnl                    posix      -lpthread ?     Y\ndnl                    posix      -lthr           Y\ndnl\ndnl FreeBSD 5.2        posix      -lc_r           Y\ndnl                    posix      -lkse           Y\ndnl                    posix      -lthr           Y\ndnl\ndnl FreeBSD 4.0,4.10   posix      -lc_r           Y      OK\ndnl\ndnl NetBSD 1.6         --\ndnl\ndnl OpenBSD 3.4        posix      -lpthread       Y      OK\ndnl\ndnl Mac OS X 10.[123]  posix      -lpthread       Y      OK\ndnl\ndnl Solaris 7,8,9      posix      -lpthread       Y      Sol 7,8: 0.0; Sol 9: OK\ndnl\ndnl HP-UX 11           posix      -lpthread       N (cc) OK\ndnl                                               Y (gcc)\ndnl\ndnl IRIX 6.5           posix      -lpthread       Y      0.5\ndnl\ndnl AIX 4.3,5.1        posix      -lpthread       N      AIX 4: 0.5; AIX 5: OK\ndnl\ndnl OSF/1 4.0,5.1      posix      -pthread (cc)   N      OK\ndnl                               -lpthread (gcc) Y\ndnl\ndnl Cygwin             posix      -lpthread       Y      OK\ndnl\ndnl Mingw              windows                    N      OK\ndnl\ndnl BeOS 5             --\ndnl\ndnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is\ndnl turned off:\ndnl   OK if all three tests terminate OK,\ndnl   0.5 if the first test terminates OK but the second one loops endlessly,\ndnl   0.0 if the first test already loops endlessly.\n"
  },
  {
    "path": "m4/unistd_h.m4",
    "content": "# unistd_h.m4 serial 89\ndnl Copyright (C) 2006-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl Written by Simon Josefsson, Bruno Haible.\n\nAC_DEFUN_ONCE([gl_UNISTD_H],\n[\n  dnl Ensure to expand the default settings once only, before all statements\n  dnl that occur in other macros.\n  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])\n\n  gl_CHECK_NEXT_HEADERS([unistd.h])\n  if test $ac_cv_header_unistd_h = yes; then\n    HAVE_UNISTD_H=1\n  else\n    HAVE_UNISTD_H=0\n  fi\n  AC_SUBST([HAVE_UNISTD_H])\n\n  dnl Ensure the type pid_t gets defined.\n  AC_REQUIRE([AC_TYPE_PID_T])\n\n  dnl Determine WINDOWS_64_BIT_OFF_T.\n  AC_REQUIRE([gl_TYPE_OFF_T])\n\n  dnl Check for declarations of anything we want to poison if the\n  dnl corresponding gnulib module is not in use.\n  gl_WARN_ON_USE_PREPARE([[\n#if HAVE_UNISTD_H\n# include <unistd.h>\n#endif\n/* Some systems declare various items in the wrong headers.  */\n#if !(defined __GLIBC__ && !defined __UCLIBC__)\n# include <fcntl.h>\n# include <stdio.h>\n# include <stdlib.h>\n# if defined _WIN32 && ! defined __CYGWIN__\n#  include <io.h>\n# endif\n#endif\n    ]], [access chdir chown copy_file_range dup dup2 dup3 environ euidaccess\n    execl execle execlp execv execve execvp execvpe\n    faccessat fchdir\n    fchownat fdatasync fsync ftruncate getcwd getdomainname getdtablesize\n    getentropy getgroups gethostname getlogin getlogin_r getpagesize getpass\n    getusershell setusershell endusershell\n    group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite\n    readlink readlinkat rmdir sethostname sleep symlink symlinkat\n    truncate ttyname_r unlink unlinkat usleep])\n\n  AC_REQUIRE([AC_C_RESTRICT])\n\n  AC_CHECK_DECLS_ONCE([execvpe])\n  if test $ac_cv_have_decl_execvpe = no; then\n    HAVE_DECL_EXECVPE=0\n  fi\n])\n\n# gl_UNISTD_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_UNISTD_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_UNISTD_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n  dnl Define it also as a C macro, for the benefit of the unit tests.\n  gl_MODULE_INDICATOR_FOR_TESTS([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_UNISTD_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_UNISTD_H_MODULE_INDICATOR_DEFAULTS], [\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ACCESS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CHDIR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CHOWN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CLOSE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_COPY_FILE_RANGE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUP2])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUP3])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ENVIRON])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EUIDACCESS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECLE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECLP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECV])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECVE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECVP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_EXECVPE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FACCESSAT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHDIR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHOWNAT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FDATASYNC])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSYNC])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTRUNCATE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETCWD])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETDOMAINNAME])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETDTABLESIZE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETENTROPY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETGROUPS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETHOSTNAME])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOGIN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOGIN_R])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETOPT_POSIX])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPAGESIZE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETPASS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETUSERSHELL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GROUP_MEMBER])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISATTY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LCHOWN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LINK])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LINKAT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LSEEK])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PIPE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PIPE2])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PREAD])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PWRITE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_READ])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_READLINK])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_READLINKAT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RMDIR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETHOSTNAME])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SLEEP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SYMLINK])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SYMLINKAT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TRUNCATE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TTYNAME_R])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_GETOPT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_NONBLOCKING])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_SIGPIPE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNLINK])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNLINKAT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_USLEEP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WRITE])\n    dnl Support Microsoft deprecated alias function names by default.\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_ACCESS], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CHDIR], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CLOSE], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_DUP], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_DUP2], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECL], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECLE], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECLP], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECV], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECVE], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECVP], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_EXECVPE], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GETCWD], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_GETPID], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_ISATTY], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_LSEEK], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_READ], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_RMDIR], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_SWAB], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_UNLINK], [1])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_WRITE], [1])\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_UNISTD_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_UNISTD_H_DEFAULTS],\n[\n  dnl Assume proper GNU behavior unless another module says otherwise.\n  HAVE_CHOWN=1;           AC_SUBST([HAVE_CHOWN])\n  HAVE_COPY_FILE_RANGE=1; AC_SUBST([HAVE_COPY_FILE_RANGE])\n  HAVE_DUP3=1;            AC_SUBST([HAVE_DUP3])\n  HAVE_EUIDACCESS=1;      AC_SUBST([HAVE_EUIDACCESS])\n  HAVE_EXECVPE=1;         AC_SUBST([HAVE_EXECVPE])\n  HAVE_FACCESSAT=1;       AC_SUBST([HAVE_FACCESSAT])\n  HAVE_FCHDIR=1;          AC_SUBST([HAVE_FCHDIR])\n  HAVE_FCHOWNAT=1;        AC_SUBST([HAVE_FCHOWNAT])\n  HAVE_FDATASYNC=1;       AC_SUBST([HAVE_FDATASYNC])\n  HAVE_FSYNC=1;           AC_SUBST([HAVE_FSYNC])\n  HAVE_FTRUNCATE=1;       AC_SUBST([HAVE_FTRUNCATE])\n  HAVE_GETDTABLESIZE=1;   AC_SUBST([HAVE_GETDTABLESIZE])\n  HAVE_GETENTROPY=1;      AC_SUBST([HAVE_GETENTROPY])\n  HAVE_GETGROUPS=1;       AC_SUBST([HAVE_GETGROUPS])\n  HAVE_GETHOSTNAME=1;     AC_SUBST([HAVE_GETHOSTNAME])\n  HAVE_GETLOGIN=1;        AC_SUBST([HAVE_GETLOGIN])\n  HAVE_GETPAGESIZE=1;     AC_SUBST([HAVE_GETPAGESIZE])\n  HAVE_GETPASS=1;         AC_SUBST([HAVE_GETPASS])\n  HAVE_GROUP_MEMBER=1;    AC_SUBST([HAVE_GROUP_MEMBER])\n  HAVE_LCHOWN=1;          AC_SUBST([HAVE_LCHOWN])\n  HAVE_LINK=1;            AC_SUBST([HAVE_LINK])\n  HAVE_LINKAT=1;          AC_SUBST([HAVE_LINKAT])\n  HAVE_PIPE=1;            AC_SUBST([HAVE_PIPE])\n  HAVE_PIPE2=1;           AC_SUBST([HAVE_PIPE2])\n  HAVE_PREAD=1;           AC_SUBST([HAVE_PREAD])\n  HAVE_PWRITE=1;          AC_SUBST([HAVE_PWRITE])\n  HAVE_READLINK=1;        AC_SUBST([HAVE_READLINK])\n  HAVE_READLINKAT=1;      AC_SUBST([HAVE_READLINKAT])\n  HAVE_SETHOSTNAME=1;     AC_SUBST([HAVE_SETHOSTNAME])\n  HAVE_SLEEP=1;           AC_SUBST([HAVE_SLEEP])\n  HAVE_SYMLINK=1;         AC_SUBST([HAVE_SYMLINK])\n  HAVE_SYMLINKAT=1;       AC_SUBST([HAVE_SYMLINKAT])\n  HAVE_UNLINKAT=1;        AC_SUBST([HAVE_UNLINKAT])\n  HAVE_USLEEP=1;          AC_SUBST([HAVE_USLEEP])\n  HAVE_DECL_ENVIRON=1;    AC_SUBST([HAVE_DECL_ENVIRON])\n  HAVE_DECL_EXECVPE=1;    AC_SUBST([HAVE_DECL_EXECVPE])\n  HAVE_DECL_FCHDIR=1;     AC_SUBST([HAVE_DECL_FCHDIR])\n  HAVE_DECL_FDATASYNC=1;  AC_SUBST([HAVE_DECL_FDATASYNC])\n  HAVE_DECL_GETDOMAINNAME=1; AC_SUBST([HAVE_DECL_GETDOMAINNAME])\n  HAVE_DECL_GETLOGIN=1;   AC_SUBST([HAVE_DECL_GETLOGIN])\n  HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R])\n  HAVE_DECL_GETPAGESIZE=1; AC_SUBST([HAVE_DECL_GETPAGESIZE])\n  HAVE_DECL_GETUSERSHELL=1; AC_SUBST([HAVE_DECL_GETUSERSHELL])\n  HAVE_DECL_SETHOSTNAME=1; AC_SUBST([HAVE_DECL_SETHOSTNAME])\n  HAVE_DECL_TRUNCATE=1;   AC_SUBST([HAVE_DECL_TRUNCATE])\n  HAVE_DECL_TTYNAME_R=1;  AC_SUBST([HAVE_DECL_TTYNAME_R])\n  HAVE_OS_H=0;            AC_SUBST([HAVE_OS_H])\n  HAVE_SYS_PARAM_H=0;     AC_SUBST([HAVE_SYS_PARAM_H])\n  REPLACE_ACCESS=0;       AC_SUBST([REPLACE_ACCESS])\n  REPLACE_CHOWN=0;        AC_SUBST([REPLACE_CHOWN])\n  REPLACE_CLOSE=0;        AC_SUBST([REPLACE_CLOSE])\n  REPLACE_DUP=0;          AC_SUBST([REPLACE_DUP])\n  REPLACE_DUP2=0;         AC_SUBST([REPLACE_DUP2])\n  REPLACE_EXECL=0;        AC_SUBST([REPLACE_EXECL])\n  REPLACE_EXECLE=0;       AC_SUBST([REPLACE_EXECLE])\n  REPLACE_EXECLP=0;       AC_SUBST([REPLACE_EXECLP])\n  REPLACE_EXECV=0;        AC_SUBST([REPLACE_EXECV])\n  REPLACE_EXECVE=0;       AC_SUBST([REPLACE_EXECVE])\n  REPLACE_EXECVP=0;       AC_SUBST([REPLACE_EXECVP])\n  REPLACE_EXECVPE=0;      AC_SUBST([REPLACE_EXECVPE])\n  REPLACE_FACCESSAT=0;    AC_SUBST([REPLACE_FACCESSAT])\n  REPLACE_FCHOWNAT=0;     AC_SUBST([REPLACE_FCHOWNAT])\n  REPLACE_FTRUNCATE=0;    AC_SUBST([REPLACE_FTRUNCATE])\n  REPLACE_GETCWD=0;       AC_SUBST([REPLACE_GETCWD])\n  REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME])\n  REPLACE_GETDTABLESIZE=0; AC_SUBST([REPLACE_GETDTABLESIZE])\n  REPLACE_GETLOGIN_R=0;   AC_SUBST([REPLACE_GETLOGIN_R])\n  REPLACE_GETGROUPS=0;    AC_SUBST([REPLACE_GETGROUPS])\n  REPLACE_GETPAGESIZE=0;  AC_SUBST([REPLACE_GETPAGESIZE])\n  REPLACE_GETPASS=0;      AC_SUBST([REPLACE_GETPASS])\n  REPLACE_ISATTY=0;       AC_SUBST([REPLACE_ISATTY])\n  REPLACE_LCHOWN=0;       AC_SUBST([REPLACE_LCHOWN])\n  REPLACE_LINK=0;         AC_SUBST([REPLACE_LINK])\n  REPLACE_LINKAT=0;       AC_SUBST([REPLACE_LINKAT])\n  REPLACE_LSEEK=0;        AC_SUBST([REPLACE_LSEEK])\n  REPLACE_PREAD=0;        AC_SUBST([REPLACE_PREAD])\n  REPLACE_PWRITE=0;       AC_SUBST([REPLACE_PWRITE])\n  REPLACE_READ=0;         AC_SUBST([REPLACE_READ])\n  REPLACE_READLINK=0;     AC_SUBST([REPLACE_READLINK])\n  REPLACE_READLINKAT=0;   AC_SUBST([REPLACE_READLINKAT])\n  REPLACE_RMDIR=0;        AC_SUBST([REPLACE_RMDIR])\n  REPLACE_SLEEP=0;        AC_SUBST([REPLACE_SLEEP])\n  REPLACE_SYMLINK=0;      AC_SUBST([REPLACE_SYMLINK])\n  REPLACE_SYMLINKAT=0;    AC_SUBST([REPLACE_SYMLINKAT])\n  REPLACE_TRUNCATE=0;     AC_SUBST([REPLACE_TRUNCATE])\n  REPLACE_TTYNAME_R=0;    AC_SUBST([REPLACE_TTYNAME_R])\n  REPLACE_UNLINK=0;       AC_SUBST([REPLACE_UNLINK])\n  REPLACE_UNLINKAT=0;     AC_SUBST([REPLACE_UNLINKAT])\n  REPLACE_USLEEP=0;       AC_SUBST([REPLACE_USLEEP])\n  REPLACE_WRITE=0;        AC_SUBST([REPLACE_WRITE])\n  UNISTD_H_HAVE_SYS_RANDOM_H=0; AC_SUBST([UNISTD_H_HAVE_SYS_RANDOM_H])\n  UNISTD_H_HAVE_WINSOCK2_H=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H])\n  UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0;\n                           AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS])\n])\n"
  },
  {
    "path": "m4/visibility.m4",
    "content": "# visibility.m4 serial 8\ndnl Copyright (C) 2005, 2008, 2010-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\n\ndnl Tests whether the compiler supports the command-line option\ndnl -fvisibility=hidden and the function and variable attributes\ndnl __attribute__((__visibility__(\"hidden\"))) and\ndnl __attribute__((__visibility__(\"default\"))).\ndnl Does *not* test for __visibility__(\"protected\") - which has tricky\ndnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on\ndnl Mac OS X.\ndnl Does *not* test for __visibility__(\"internal\") - which has processor\ndnl dependent semantics.\ndnl Does *not* test for #pragma GCC visibility push(hidden) - which is\ndnl \"really only recommended for legacy code\".\ndnl Set the variable CFLAG_VISIBILITY.\ndnl Defines and sets the variable HAVE_VISIBILITY.\n\nAC_DEFUN([gl_VISIBILITY],\n[\n  AC_REQUIRE([AC_PROG_CC])\n  CFLAG_VISIBILITY=\n  HAVE_VISIBILITY=0\n  if test -n \"$GCC\"; then\n    dnl First, check whether -Werror can be added to the command line, or\n    dnl whether it leads to an error because of some other option that the\n    dnl user has put into $CC $CFLAGS $CPPFLAGS.\n    AC_CACHE_CHECK([whether the -Werror option is usable],\n      [gl_cv_cc_vis_werror],\n      [gl_save_CFLAGS=\"$CFLAGS\"\n       CFLAGS=\"$CFLAGS -Werror\"\n       AC_COMPILE_IFELSE(\n         [AC_LANG_PROGRAM([[]], [[]])],\n         [gl_cv_cc_vis_werror=yes],\n         [gl_cv_cc_vis_werror=no])\n       CFLAGS=\"$gl_save_CFLAGS\"\n      ])\n    dnl Now check whether visibility declarations are supported.\n    AC_CACHE_CHECK([for simple visibility declarations],\n      [gl_cv_cc_visibility],\n      [gl_save_CFLAGS=\"$CFLAGS\"\n       CFLAGS=\"$CFLAGS -fvisibility=hidden\"\n       dnl We use the option -Werror and a function dummyfunc, because on some\n       dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning\n       dnl \"visibility attribute not supported in this configuration; ignored\"\n       dnl at the first function definition in every compilation unit, and we\n       dnl don't want to use the option in this case.\n       if test $gl_cv_cc_vis_werror = yes; then\n         CFLAGS=\"$CFLAGS -Werror\"\n       fi\n       AC_COMPILE_IFELSE(\n         [AC_LANG_PROGRAM(\n            [[extern __attribute__((__visibility__(\"hidden\"))) int hiddenvar;\n              extern __attribute__((__visibility__(\"default\"))) int exportedvar;\n              extern __attribute__((__visibility__(\"hidden\"))) int hiddenfunc (void);\n              extern __attribute__((__visibility__(\"default\"))) int exportedfunc (void);\n              void dummyfunc (void);\n              int hiddenvar;\n              int exportedvar;\n              int hiddenfunc (void) { return 51; }\n              int exportedfunc (void) { return 1225736919; }\n              void dummyfunc (void) {}\n            ]],\n            [[]])],\n         [gl_cv_cc_visibility=yes],\n         [gl_cv_cc_visibility=no])\n       CFLAGS=\"$gl_save_CFLAGS\"\n      ])\n    if test $gl_cv_cc_visibility = yes; then\n      CFLAG_VISIBILITY=\"-fvisibility=hidden\"\n      HAVE_VISIBILITY=1\n    fi\n  fi\n  AC_SUBST([CFLAG_VISIBILITY])\n  AC_SUBST([HAVE_VISIBILITY])\n  AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY],\n    [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.])\n])\n"
  },
  {
    "path": "m4/warn-on-use.m4",
    "content": "# warn-on-use.m4 serial 9\ndnl Copyright (C) 2010-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\n# gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES)\n# ---------------------------------------\n# If the module 'posixcheck' is in use:\n#\n# For each whitespace-separated element in the list of NAMES, define\n# HAVE_RAW_DECL_name if the function has a declaration among INCLUDES\n# even after being undefined as a macro.\n#\n# See warn-on-use.h for some hints on how to poison function names, as\n# well as ideas on poisoning global variables and macros.  NAMES may\n# include global variables, but remember that only functions work with\n# _GL_WARN_ON_USE.  Typically, INCLUDES only needs to list a single\n# header, but if the replacement header pulls in other headers because\n# some systems declare functions in the wrong header, then INCLUDES\n# should do likewise.\n#\n# It is generally safe to assume declarations for functions declared\n# in the intersection of C89 and C11 (such as printf) without\n# needing gl_WARN_ON_USE_PREPARE.\nAC_DEFUN([gl_WARN_ON_USE_PREPARE],\n[\n  m4_ifdef([gl_POSIXCHECK],\n    [m4_foreach_w([gl_decl], [$2],\n       [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])),\n         [Define to 1 if ]m4_defn([gl_decl])[ is declared even after\n          undefining macros.])])dnl\n     for gl_func in m4_flatten([$2]); do\n       AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl\n       AC_CACHE_CHECK([whether $gl_func is declared without a macro],\n         [gl_Symbol],\n         [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$1],\n[[#undef $gl_func\n  (void) $gl_func;]])],\n           [AS_VAR_SET([gl_Symbol], [yes])], [AS_VAR_SET([gl_Symbol], [no])])])\n       AS_VAR_IF([gl_Symbol], [yes],\n         [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1])\n          dnl shortcut - if the raw declaration exists, then set a cache\n          dnl variable to allow skipping any later AC_CHECK_DECL efforts\n          eval ac_cv_have_decl_$gl_func=yes])\n       AS_VAR_POPDEF([gl_Symbol])dnl\n     done\n    ])\n])\n"
  },
  {
    "path": "m4/wchar_h.m4",
    "content": "dnl A placeholder for ISO C99 <wchar.h>, for platforms that have issues.\n\ndnl Copyright (C) 2007-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl Written by Eric Blake.\n\n# wchar_h.m4 serial 53\n\nAC_DEFUN_ONCE([gl_WCHAR_H],\n[\n  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])\n  AC_REQUIRE([gl_WCHAR_H_INLINE_OK])\n  dnl Prepare for creating substitute <wchar.h>.\n  dnl Check for <wchar.h> (missing in Linux uClibc when built without wide\n  dnl character support).\n  dnl <wchar.h> is always overridden, because of GNULIB_POSIXCHECK.\n  gl_CHECK_NEXT_HEADERS([wchar.h])\n  if test $ac_cv_header_wchar_h = yes; then\n    HAVE_WCHAR_H=1\n  else\n    HAVE_WCHAR_H=0\n  fi\n  AC_SUBST([HAVE_WCHAR_H])\n\n  AC_REQUIRE([gl_FEATURES_H])\n\n  AC_REQUIRE([gt_TYPE_WINT_T])\n  if test $gt_cv_c_wint_t = yes; then\n    HAVE_WINT_T=1\n  else\n    HAVE_WINT_T=0\n  fi\n  AC_SUBST([HAVE_WINT_T])\n\n  AC_REQUIRE([gl_TYPE_WINT_T_PREREQ])\n\n  dnl Check for declarations of anything we want to poison if the\n  dnl corresponding gnulib module is not in use.\n  gl_WARN_ON_USE_PREPARE([[\n      #include <wchar.h>\n    ]],\n    [btowc wctob mbsinit mbrtowc mbrlen mbsrtowcs mbsnrtowcs wcrtomb\n     wcsrtombs wcsnrtombs wcwidth\n     wmemchr wmemcmp wmemcpy wmemmove wmempcpy wmemset\n     wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat wcscmp\n     wcsncmp wcscasecmp wcsncasecmp wcscoll wcsxfrm wcsdup wcschr wcsrchr\n     wcscspn wcsspn wcspbrk wcsstr wcstok wcswidth wcsftime\n    ])\n\n  AC_REQUIRE([AC_C_RESTRICT])\n\n  AC_CHECK_DECLS([wcsdup], [], [], [[\n      #include <wchar.h>\n    ]])\n  if test $ac_cv_have_decl_wcsdup = no; then\n    HAVE_DECL_WCSDUP=0\n  fi\n])\n\ndnl Check whether <wchar.h> is usable at all.\nAC_DEFUN([gl_WCHAR_H_INLINE_OK],\n[\n  dnl Test whether <wchar.h> suffers due to the transition from '__inline' to\n  dnl 'gnu_inline'. See <https://sourceware.org/bugzilla/show_bug.cgi?id=4022>\n  dnl and <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42440>. In summary,\n  dnl glibc version 2.5 or older, together with gcc version 4.3 or newer and\n  dnl the option -std=c99 or -std=gnu99, leads to a broken <wchar.h>.\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_CACHE_CHECK([whether <wchar.h> uses 'inline' correctly],\n    [gl_cv_header_wchar_h_correct_inline],\n    [gl_cv_header_wchar_h_correct_inline=yes\n     case \"$host_os\" in\n       *-gnu* | gnu*)\n         AC_LANG_CONFTEST([\n           AC_LANG_SOURCE([[\n             #define wcstod renamed_wcstod\n             #include <wchar.h>\n             extern int zero (void);\n             int main () { return zero(); }\n           ]])])\n         dnl Do not rename the object file from conftest.$ac_objext to\n         dnl conftest1.$ac_objext, as this will cause the link to fail on\n         dnl z/OS when using the XPLINK object format (due to duplicate\n         dnl CSECT names). Instead, temporarily redefine $ac_compile so\n         dnl that the object file has the latter name from the start.\n         save_ac_compile=\"$ac_compile\"\n         ac_compile=`echo \"$save_ac_compile\" | sed s/conftest/conftest1/`\n         if echo '#include \"conftest.c\"' >conftest1.c \\\n            && AC_TRY_EVAL([ac_compile]); then\n           AC_LANG_CONFTEST([\n             AC_LANG_SOURCE([[\n               #define wcstod renamed_wcstod\n               #include <wchar.h>\n               int zero (void) { return 0; }\n             ]])])\n           dnl See note above about renaming object files.\n           ac_compile=`echo \"$save_ac_compile\" | sed s/conftest/conftest2/`\n           if echo '#include \"conftest.c\"' >conftest2.c \\\n              && AC_TRY_EVAL([ac_compile]); then\n             if $CC -o conftest$ac_exeext $CFLAGS $LDFLAGS conftest1.$ac_objext conftest2.$ac_objext $LIBS >&AS_MESSAGE_LOG_FD 2>&1; then\n               :\n             else\n               gl_cv_header_wchar_h_correct_inline=no\n             fi\n           fi\n         fi\n         ac_compile=\"$save_ac_compile\"\n         rm -f conftest[12].c conftest[12].$ac_objext conftest$ac_exeext\n         ;;\n     esac\n    ])\n  if test $gl_cv_header_wchar_h_correct_inline = no; then\n    AC_MSG_ERROR([<wchar.h> cannot be used with this compiler ($CC $CFLAGS $CPPFLAGS).\nThis is a known interoperability problem of glibc <= 2.5 with gcc >= 4.3 in\nC99 mode. You have four options:\n  - Add the flag -fgnu89-inline to CC and reconfigure, or\n  - Fix your include files, using parts of\n    <https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b037a293a48718af30d706c2e18c929d0e69a621>, or\n  - Use a gcc version older than 4.3, or\n  - Don't use the flags -std=c99 or -std=gnu99.\nConfiguration aborted.])\n  fi\n])\n\n# gl_WCHAR_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_WCHAR_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_WCHAR_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n  dnl Define it also as a C macro, for the benefit of the unit tests.\n  gl_MODULE_INDICATOR_FOR_TESTS([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_WCHAR_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_WCHAR_H_MODULE_INDICATOR_DEFAULTS], [\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_BTOWC])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCTOB])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSINIT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBRTOWC])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBRLEN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSRTOWCS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNRTOWCS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCRTOMB])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSRTOMBS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNRTOMBS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCWIDTH])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMCHR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMCMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMCPY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMMOVE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMPCPY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WMEMSET])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSLEN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNLEN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCPY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCPCPY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNCPY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCPNCPY])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCAT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNCAT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNCMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCASECMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSNCASECMP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCOLL])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSXFRM])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSDUP])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCHR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSRCHR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSCSPN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSSPN])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSPBRK])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSSTR])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSTOK])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSWIDTH])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCSFTIME])\n    dnl Support Microsoft deprecated alias function names by default.\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_WCSDUP], [1])\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_WCHAR_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_WCHAR_H_DEFAULTS],\n[\n  dnl Assume proper GNU behavior unless another module says otherwise.\n  HAVE_BTOWC=1;         AC_SUBST([HAVE_BTOWC])\n  HAVE_MBSINIT=1;       AC_SUBST([HAVE_MBSINIT])\n  HAVE_MBRTOWC=1;       AC_SUBST([HAVE_MBRTOWC])\n  HAVE_MBRLEN=1;        AC_SUBST([HAVE_MBRLEN])\n  HAVE_MBSRTOWCS=1;     AC_SUBST([HAVE_MBSRTOWCS])\n  HAVE_MBSNRTOWCS=1;    AC_SUBST([HAVE_MBSNRTOWCS])\n  HAVE_WCRTOMB=1;       AC_SUBST([HAVE_WCRTOMB])\n  HAVE_WCSRTOMBS=1;     AC_SUBST([HAVE_WCSRTOMBS])\n  HAVE_WCSNRTOMBS=1;    AC_SUBST([HAVE_WCSNRTOMBS])\n  HAVE_WMEMCHR=1;       AC_SUBST([HAVE_WMEMCHR])\n  HAVE_WMEMCMP=1;       AC_SUBST([HAVE_WMEMCMP])\n  HAVE_WMEMCPY=1;       AC_SUBST([HAVE_WMEMCPY])\n  HAVE_WMEMMOVE=1;      AC_SUBST([HAVE_WMEMMOVE])\n  HAVE_WMEMPCPY=1;      AC_SUBST([HAVE_WMEMPCPY])\n  HAVE_WMEMSET=1;       AC_SUBST([HAVE_WMEMSET])\n  HAVE_WCSLEN=1;        AC_SUBST([HAVE_WCSLEN])\n  HAVE_WCSNLEN=1;       AC_SUBST([HAVE_WCSNLEN])\n  HAVE_WCSCPY=1;        AC_SUBST([HAVE_WCSCPY])\n  HAVE_WCPCPY=1;        AC_SUBST([HAVE_WCPCPY])\n  HAVE_WCSNCPY=1;       AC_SUBST([HAVE_WCSNCPY])\n  HAVE_WCPNCPY=1;       AC_SUBST([HAVE_WCPNCPY])\n  HAVE_WCSCAT=1;        AC_SUBST([HAVE_WCSCAT])\n  HAVE_WCSNCAT=1;       AC_SUBST([HAVE_WCSNCAT])\n  HAVE_WCSCMP=1;        AC_SUBST([HAVE_WCSCMP])\n  HAVE_WCSNCMP=1;       AC_SUBST([HAVE_WCSNCMP])\n  HAVE_WCSCASECMP=1;    AC_SUBST([HAVE_WCSCASECMP])\n  HAVE_WCSNCASECMP=1;   AC_SUBST([HAVE_WCSNCASECMP])\n  HAVE_WCSCOLL=1;       AC_SUBST([HAVE_WCSCOLL])\n  HAVE_WCSXFRM=1;       AC_SUBST([HAVE_WCSXFRM])\n  HAVE_WCSDUP=1;        AC_SUBST([HAVE_WCSDUP])\n  HAVE_WCSCHR=1;        AC_SUBST([HAVE_WCSCHR])\n  HAVE_WCSRCHR=1;       AC_SUBST([HAVE_WCSRCHR])\n  HAVE_WCSCSPN=1;       AC_SUBST([HAVE_WCSCSPN])\n  HAVE_WCSSPN=1;        AC_SUBST([HAVE_WCSSPN])\n  HAVE_WCSPBRK=1;       AC_SUBST([HAVE_WCSPBRK])\n  HAVE_WCSSTR=1;        AC_SUBST([HAVE_WCSSTR])\n  HAVE_WCSTOK=1;        AC_SUBST([HAVE_WCSTOK])\n  HAVE_WCSWIDTH=1;      AC_SUBST([HAVE_WCSWIDTH])\n  HAVE_WCSFTIME=1;      AC_SUBST([HAVE_WCSFTIME])\n  HAVE_DECL_WCTOB=1;    AC_SUBST([HAVE_DECL_WCTOB])\n  HAVE_DECL_WCSDUP=1;   AC_SUBST([HAVE_DECL_WCSDUP])\n  HAVE_DECL_WCWIDTH=1;  AC_SUBST([HAVE_DECL_WCWIDTH])\n  REPLACE_MBSTATE_T=0;  AC_SUBST([REPLACE_MBSTATE_T])\n  REPLACE_BTOWC=0;      AC_SUBST([REPLACE_BTOWC])\n  REPLACE_WCTOB=0;      AC_SUBST([REPLACE_WCTOB])\n  REPLACE_MBSINIT=0;    AC_SUBST([REPLACE_MBSINIT])\n  REPLACE_MBRTOWC=0;    AC_SUBST([REPLACE_MBRTOWC])\n  REPLACE_MBRLEN=0;     AC_SUBST([REPLACE_MBRLEN])\n  REPLACE_MBSRTOWCS=0;  AC_SUBST([REPLACE_MBSRTOWCS])\n  REPLACE_MBSNRTOWCS=0; AC_SUBST([REPLACE_MBSNRTOWCS])\n  REPLACE_WCRTOMB=0;    AC_SUBST([REPLACE_WCRTOMB])\n  REPLACE_WCSRTOMBS=0;  AC_SUBST([REPLACE_WCSRTOMBS])\n  REPLACE_WCSNRTOMBS=0; AC_SUBST([REPLACE_WCSNRTOMBS])\n  REPLACE_WCWIDTH=0;    AC_SUBST([REPLACE_WCWIDTH])\n  REPLACE_WCSWIDTH=0;   AC_SUBST([REPLACE_WCSWIDTH])\n  REPLACE_WCSFTIME=0;   AC_SUBST([REPLACE_WCSFTIME])\n  REPLACE_WCSTOK=0;     AC_SUBST([REPLACE_WCSTOK])\n])\n"
  },
  {
    "path": "m4/wchar_t.m4",
    "content": "# wchar_t.m4 serial 4 (gettext-0.18.2)\ndnl Copyright (C) 2002-2003, 2008-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\ndnl Test whether <stddef.h> has the 'wchar_t' type.\ndnl Prerequisite: AC_PROG_CC\n\nAC_DEFUN([gt_TYPE_WCHAR_T],\n[\n  AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <stddef.h>\n            wchar_t foo = (wchar_t)'\\0';]],\n          [[]])],\n       [gt_cv_c_wchar_t=yes],\n       [gt_cv_c_wchar_t=no])])\n  if test $gt_cv_c_wchar_t = yes; then\n    AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.])\n  fi\n])\n"
  },
  {
    "path": "m4/wcrtomb.m4",
    "content": "# wcrtomb.m4 serial 17\ndnl Copyright (C) 2008-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_WCRTOMB],\n[\n  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])\n\n  AC_REQUIRE([AC_TYPE_MBSTATE_T])\n  gl_MBSTATE_T_BROKEN\n\n  AC_CHECK_FUNCS_ONCE([wcrtomb])\n  if test $ac_cv_func_wcrtomb = no; then\n    HAVE_WCRTOMB=0\n    AC_CHECK_DECLS([wcrtomb],,, [[\n      #include <wchar.h>\n    ]])\n    if test $ac_cv_have_decl_wcrtomb = yes; then\n      dnl On Minix 3.1.8, the system's <wchar.h> declares wcrtomb() although\n      dnl it does not have the function. Avoid a collision with gnulib's\n      dnl replacement.\n      REPLACE_WCRTOMB=1\n    fi\n  else\n    dnl We don't actually need to override wcrtomb when redefining the semantics\n    dnl of the mbstate_t type. Tested on 32-bit AIX.\n    dnl if test $REPLACE_MBSTATE_T = 1; then\n    dnl   REPLACE_WCRTOMB=1\n    dnl fi\n    if test $REPLACE_WCRTOMB = 0; then\n      dnl On Android 4.3, wcrtomb produces wrong characters in the C locale.\n      dnl On AIX 4.3, OSF/1 5.1 and Solaris <= 11.3, wcrtomb (NULL, 0, NULL)\n      dnl sometimes returns 0 instead of 1.\n      AC_REQUIRE([AC_PROG_CC])\n      AC_REQUIRE([gt_LOCALE_FR])\n      AC_REQUIRE([gt_LOCALE_FR_UTF8])\n      AC_REQUIRE([gt_LOCALE_JA])\n      AC_REQUIRE([gt_LOCALE_ZH_CN])\n      AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles\n      AC_CACHE_CHECK([whether wcrtomb works in the C locale],\n        [gl_cv_func_wcrtomb_works],\n        [AC_RUN_IFELSE(\n           [AC_LANG_SOURCE([[\n#include <string.h>\n#include <stdlib.h>\n#include <wchar.h>\nint main ()\n{\n  mbstate_t state;\n  char out[64];\n  int count;\n  memset (&state, 0, sizeof (state));\n  out[0] = 'x';\n  count = wcrtomb (out, L'a', &state);\n  return !(count == 1 && out[0] == 'a');\n}]])],\n           [gl_cv_func_wcrtomb_works=yes],\n           [gl_cv_func_wcrtomb_works=no],\n           [case \"$host_os\" in\n                               # Guess no on Android.\n              linux*-android*) gl_cv_func_wcrtomb_works=\"guessing no\";;\n                               # Guess yes otherwise.\n              *)               gl_cv_func_wcrtomb_works=\"guessing yes\";;\n            esac\n           ])\n        ])\n      case \"$gl_cv_func_wcrtomb_works\" in\n        *yes) ;;\n        *) AC_DEFINE([WCRTOMB_C_LOCALE_BUG], [1],\n             [Define if the wcrtomb function does not work in the C locale.])\n           REPLACE_WCRTOMB=1 ;;\n      esac\n    fi\n    if test $REPLACE_WCRTOMB = 0; then\n      AC_CACHE_CHECK([whether wcrtomb return value is correct],\n        [gl_cv_func_wcrtomb_retval],\n        [\n          dnl Initial guess, used when cross-compiling or when no suitable locale\n          dnl is present.\nchangequote(,)dnl\n          case \"$host_os\" in\n            # Guess no on AIX 4, OSF/1, Solaris, native Windows.\n            aix4* | osf* | solaris* | mingw*) gl_cv_func_wcrtomb_retval=\"guessing no\" ;;\n            # Guess yes otherwise.\n            *)                                gl_cv_func_wcrtomb_retval=\"guessing yes\" ;;\n          esac\nchangequote([,])dnl\n          if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then\n            AC_RUN_IFELSE(\n              [AC_LANG_SOURCE([[\n#include <locale.h>\n#include <string.h>\n#include <wchar.h>\n#include <stdlib.h>\nint main ()\n{\n  int result = 0;\n  if (setlocale (LC_ALL, \"$LOCALE_FR\") != NULL)\n    {\n      if (wcrtomb (NULL, 0, NULL) != 1)\n        result |= 1;\n    }\n  if (setlocale (LC_ALL, \"$LOCALE_FR_UTF8\") != NULL)\n    {\n      if (wcrtomb (NULL, 0, NULL) != 1)\n        result |= 2;\n      {\n        wchar_t wc = (wchar_t) 0xBADFACE;\n        if (mbtowc (&wc, \"\\303\\274\", 2) == 2)\n          if (wcrtomb (NULL, wc, NULL) != 1)\n            result |= 2;\n      }\n    }\n  if (setlocale (LC_ALL, \"$LOCALE_JA\") != NULL)\n    {\n      if (wcrtomb (NULL, 0, NULL) != 1)\n        result |= 4;\n    }\n  if (setlocale (LC_ALL, \"$LOCALE_ZH_CN\") != NULL)\n    {\n      if (wcrtomb (NULL, 0, NULL) != 1)\n        result |= 8;\n    }\n  return result;\n}]])],\n              [gl_cv_func_wcrtomb_retval=yes],\n              [gl_cv_func_wcrtomb_retval=no],\n              [:])\n          fi\n        ])\n      case \"$gl_cv_func_wcrtomb_retval\" in\n        *yes) ;;\n        *) AC_DEFINE([WCRTOMB_RETVAL_BUG], [1],\n             [Define if the wcrtomb function has an incorrect return value.])\n           REPLACE_WCRTOMB=1 ;;\n      esac\n    fi\n  fi\n])\n\n# Prerequisites of lib/wcrtomb.c.\nAC_DEFUN([gl_PREREQ_WCRTOMB], [\n  :\n])\n"
  },
  {
    "path": "m4/wctype_h.m4",
    "content": "# wctype_h.m4 serial 30\n\ndnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it.\n\ndnl Copyright (C) 2006-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl Written by Paul Eggert.\n\nAC_DEFUN_ONCE([gl_WCTYPE_H],\n[\n  AC_REQUIRE([gl_WCTYPE_H_DEFAULTS])\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_CHECK_FUNCS_ONCE([iswcntrl])\n  if test $ac_cv_func_iswcntrl = yes; then\n    HAVE_ISWCNTRL=1\n  else\n    HAVE_ISWCNTRL=0\n  fi\n  AC_SUBST([HAVE_ISWCNTRL])\n\n  AC_REQUIRE([gt_TYPE_WINT_T])\n  if test $gt_cv_c_wint_t = yes; then\n    HAVE_WINT_T=1\n  else\n    HAVE_WINT_T=0\n  fi\n  AC_SUBST([HAVE_WINT_T])\n\n  AC_REQUIRE([gl_TYPE_WINT_T_PREREQ])\n\n  gl_CHECK_NEXT_HEADERS([wctype.h])\n  if test $ac_cv_header_wctype_h = yes; then\n    if test $ac_cv_func_iswcntrl = yes; then\n      dnl Linux libc5 has an iswprint function that returns 0 for all arguments.\n      dnl The other functions are likely broken in the same way.\n      AC_CACHE_CHECK([whether iswcntrl works], [gl_cv_func_iswcntrl_works],\n        [\n          AC_RUN_IFELSE(\n            [AC_LANG_SOURCE([[\n               #include <wchar.h>\n               #include <wctype.h>\n               int main () { return iswprint ('x') == 0; }\n            ]])],\n            [gl_cv_func_iswcntrl_works=yes], [gl_cv_func_iswcntrl_works=no],\n            [dnl Guess no on Linux libc5, yes otherwise.\n             AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>\n                          #if __GNU_LIBRARY__ == 1\n                          Linux libc5 i18n is broken.\n                          #endif]], [[]])],\n              [gl_cv_func_iswcntrl_works=\"guessing yes\"],\n              [gl_cv_func_iswcntrl_works=\"guessing no\"])\n            ])\n        ])\n    fi\n    HAVE_WCTYPE_H=1\n  else\n    HAVE_WCTYPE_H=0\n  fi\n  AC_SUBST([HAVE_WCTYPE_H])\n\n  if test $GNULIBHEADERS_OVERRIDE_WINT_T = 1; then\n    REPLACE_ISWCNTRL=1\n  else\n    case \"$gl_cv_func_iswcntrl_works\" in\n      *yes) REPLACE_ISWCNTRL=0 ;;\n      *)    REPLACE_ISWCNTRL=1 ;;\n    esac\n  fi\n  AC_SUBST([REPLACE_ISWCNTRL])\n\n  if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then\n    dnl Redefine all of iswcntrl, ..., iswxdigit in <wctype.h>.\n    :\n  fi\n\n  if test $REPLACE_ISWCNTRL = 1; then\n    REPLACE_TOWLOWER=1\n  else\n    AC_CHECK_FUNCS([towlower])\n    if test $ac_cv_func_towlower = yes; then\n      REPLACE_TOWLOWER=0\n    else\n      AC_CHECK_DECLS([towlower],,,\n        [[#include <wchar.h>\n          #if HAVE_WCTYPE_H\n          # include <wctype.h>\n          #endif\n        ]])\n      if test $ac_cv_have_decl_towlower = yes; then\n        dnl On Minix 3.1.8, the system's <wctype.h> declares towlower() and\n        dnl towupper() although it does not have the functions. Avoid a\n        dnl collision with gnulib's replacement.\n        REPLACE_TOWLOWER=1\n      else\n        REPLACE_TOWLOWER=0\n      fi\n    fi\n  fi\n  AC_SUBST([REPLACE_TOWLOWER])\n\n  if test $HAVE_ISWCNTRL = 0 || test $REPLACE_TOWLOWER = 1; then\n    dnl Redefine towlower, towupper in <wctype.h>.\n    :\n  fi\n\n  dnl We assume that the wctype() and iswctype() functions exist if and only\n  dnl if the type wctype_t is defined in <wchar.h> or in <wctype.h> if that\n  dnl exists.\n  dnl HP-UX 11.00 declares all these in <wchar.h> and lacks <wctype.h>.\n  AC_CACHE_CHECK([for wctype_t], [gl_cv_type_wctype_t],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <wchar.h>\n            #if HAVE_WCTYPE_H\n            # include <wctype.h>\n            #endif\n            wctype_t a;\n          ]],\n          [[]])],\n       [gl_cv_type_wctype_t=yes],\n       [gl_cv_type_wctype_t=no])\n    ])\n  if test $gl_cv_type_wctype_t = no; then\n    HAVE_WCTYPE_T=0\n  fi\n\n  dnl We assume that the wctrans() and towctrans() functions exist if and only\n  dnl if the type wctrans_t is defined in <wctype.h>.\n  AC_CACHE_CHECK([for wctrans_t], [gl_cv_type_wctrans_t],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <wchar.h>\n            #include <wctype.h>\n            wctrans_t a;\n          ]],\n          [[]])],\n       [gl_cv_type_wctrans_t=yes],\n       [gl_cv_type_wctrans_t=no])\n    ])\n  if test $gl_cv_type_wctrans_t = no; then\n    HAVE_WCTRANS_T=0\n  fi\n\n  dnl Check for declarations of anything we want to poison if the\n  dnl corresponding gnulib module is not in use.\n  gl_WARN_ON_USE_PREPARE([[\n#if !(defined __GLIBC__ && !defined __UCLIBC__)\n# include <wchar.h>\n#endif\n#include <wctype.h>\n    ]],\n    [wctype iswctype wctrans towctrans\n    ])\n])\n\n# gl_WCTYPE_MODULE_INDICATOR([modulename])\n# sets the shell variable that indicates the presence of the given module\n# to a C preprocessor expression that will evaluate to 1.\n# This macro invocation must not occur in macros that are AC_REQUIREd.\nAC_DEFUN([gl_WCTYPE_MODULE_INDICATOR],\n[\n  dnl Ensure to expand the default settings once only.\n  gl_WCTYPE_H_REQUIRE_DEFAULTS\n  gl_MODULE_INDICATOR_SET_VARIABLE([$1])\n  dnl Define it also as a C macro, for the benefit of the unit tests.\n  gl_MODULE_INDICATOR_FOR_TESTS([$1])\n])\n\n# Initializes the default values for AC_SUBSTed shell variables.\n# This macro must not be AC_REQUIREd.  It must only be invoked, and only\n# outside of macros or in macros that are not AC_REQUIREd.\nAC_DEFUN([gl_WCTYPE_H_REQUIRE_DEFAULTS],\n[\n  m4_defun(GL_MODULE_INDICATOR_PREFIX[_WCTYPE_H_MODULE_INDICATOR_DEFAULTS], [\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWBLANK])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWDIGIT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWXDIGIT])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCTYPE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWCTYPE])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCTRANS])\n    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TOWCTRANS])\n  ])\n  m4_require(GL_MODULE_INDICATOR_PREFIX[_WCTYPE_H_MODULE_INDICATOR_DEFAULTS])\n  AC_REQUIRE([gl_WCTYPE_H_DEFAULTS])\n])\n\nAC_DEFUN([gl_WCTYPE_H_DEFAULTS],\n[\n  dnl Assume proper GNU behavior unless another module says otherwise.\n  HAVE_ISWBLANK=1;      AC_SUBST([HAVE_ISWBLANK])\n  HAVE_WCTYPE_T=1;      AC_SUBST([HAVE_WCTYPE_T])\n  HAVE_WCTRANS_T=1;     AC_SUBST([HAVE_WCTRANS_T])\n  REPLACE_ISWBLANK=0;   AC_SUBST([REPLACE_ISWBLANK])\n  REPLACE_ISWDIGIT=0;   AC_SUBST([REPLACE_ISWDIGIT])\n  REPLACE_ISWXDIGIT=0;  AC_SUBST([REPLACE_ISWXDIGIT])\n])\n"
  },
  {
    "path": "m4/wint_t.m4",
    "content": "# wint_t.m4 serial 11\ndnl Copyright (C) 2003, 2007-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\ndnl Test whether <wchar.h> has the 'wint_t' type and whether gnulib's\ndnl <wchar.h> or <wctype.h> would, if present, override 'wint_t'.\ndnl Prerequisite: AC_PROG_CC\n\nAC_DEFUN([gt_TYPE_WINT_T],\n[\n  AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t],\n    [AC_COMPILE_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <wchar.h>\n            wint_t foo = (wchar_t)'\\0';]],\n          [[]])],\n       [gt_cv_c_wint_t=yes],\n       [gt_cv_c_wint_t=no])])\n  if test $gt_cv_c_wint_t = yes; then\n    AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.])\n\n    dnl Determine whether gnulib's <wchar.h> or <wctype.h> would, if present,\n    dnl override 'wint_t'.\n    AC_CACHE_CHECK([whether wint_t is large enough],\n      [gl_cv_type_wint_t_large_enough],\n      [AC_COMPILE_IFELSE(\n         [AC_LANG_PROGRAM(\n            [[#include <wchar.h>\n              int verify[sizeof (wint_t) < sizeof (int) ? -1 : 1];\n            ]])],\n         [gl_cv_type_wint_t_large_enough=yes],\n         [gl_cv_type_wint_t_large_enough=no])])\n    if test $gl_cv_type_wint_t_large_enough = no; then\n      GNULIBHEADERS_OVERRIDE_WINT_T=1\n    else\n      GNULIBHEADERS_OVERRIDE_WINT_T=0\n    fi\n  else\n    GNULIBHEADERS_OVERRIDE_WINT_T=0\n  fi\n  AC_SUBST([GNULIBHEADERS_OVERRIDE_WINT_T])\n])\n\ndnl Prerequisites of the 'wint_t' override.\nAC_DEFUN([gl_TYPE_WINT_T_PREREQ],\n[\n  AC_CHECK_HEADERS_ONCE([crtdefs.h])\n  if test $ac_cv_header_crtdefs_h = yes; then\n    HAVE_CRTDEFS_H=1\n  else\n    HAVE_CRTDEFS_H=0\n  fi\n  AC_SUBST([HAVE_CRTDEFS_H])\n])\n"
  },
  {
    "path": "m4/wmemchr.m4",
    "content": "# wmemchr.m4 serial 5\ndnl Copyright (C) 2011-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_WMEMCHR],\n[\n  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])\n  dnl We cannot use AC_CHECK_FUNCS here, because the MSVC 9 header files\n  dnl provide this function as an inline function definition.\n  AC_CACHE_CHECK([for wmemchr], [gl_cv_func_wmemchr],\n    [AC_LINK_IFELSE(\n       [AC_LANG_PROGRAM(\n          [[#include <wchar.h>\n          ]],\n          [[return ! wmemchr ((const wchar_t *) 0, (wchar_t) ' ', 0);]])\n       ],\n       [gl_cv_func_wmemchr=yes],\n       [gl_cv_func_wmemchr=no])\n    ])\n  if test $gl_cv_func_wmemchr = no; then\n    HAVE_WMEMCHR=0\n  fi\n])\n"
  },
  {
    "path": "m4/wmempcpy.m4",
    "content": "# wmempcpy.m4 serial 1\ndnl Copyright (C) 2020-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\nAC_DEFUN([gl_FUNC_WMEMPCPY],\n[\n  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])\n\n  dnl Persuade glibc <wchar.h> to declare wmempcpy().\n  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])\n\n  dnl The wmempcpy() declaration in lib/wchar.in.h uses 'restrict'.\n  AC_REQUIRE([AC_C_RESTRICT])\n\n  AC_CHECK_FUNCS_ONCE([wmempcpy])\n  if test $ac_cv_func_wmempcpy = no; then\n    HAVE_WMEMPCPY=0\n  fi\n])\n"
  },
  {
    "path": "m4/zzgnulib.m4",
    "content": "# zzgnulib.m4 serial 1\ndnl Copyright (C) 2020-2021 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl This file must be named something that sorts after all other\ndnl package- or gnulib-provided .m4 files - at least for those packages\ndnl that redefine AC_PROG_CC.\n\ndnl Redefine AC_PROG_CC so that it ends with invocations of gl_COMPILER_CLANG\ndnl and gl_COMPILER_PREPARE_CHECK_DECL.\nm4_define([AC_PROG_CC],\n  m4_defn([AC_PROG_CC])[\ngl_COMPILER_CLANG\ngl_COMPILER_PREPARE_CHECK_DECL\n])\n\n# gl_ZZGNULIB\n# -----------\n# Witness macro that this file has been included.  Needed to force\n# Automake to include this file after all other gnulib .m4 files.\nAC_DEFUN([gl_ZZGNULIB])\n"
  },
  {
    "path": "main/CommonPrelude.c",
    "content": "const char ctagsCommonPrelude []=\n\"%\\n\"\n\"% Copyright (c) 2021, Masatake YAMATO\\n\"\n\"% Copyright (c) 2021, Red Hat, Inc.\\n\"\n\"%\\n\"\n\"% This source code is released for free distribution under the terms of the\\n\"\n\"% GNU General Public License version 2 or (at your option) any later version.\\n\"\n\"%\\n\"\n\"\\n\"\n\"%\\n\"\n\"% The documentation table\\n\"\n\"%\\n\"\n\"\\n\"\n\"% __PROCDOCS:dict<proc:name, doc:string>\\n\"\n\"/__procdocs 30 dict def\\n\"\n\"\\n\"\n\"% name value __BDEF -\\n\"\n\"/__bdef { bind def }  bind def\\n\"\n\"\\n\"\n\"% doc:string key:name any:val __DOCDEF -\\n\"\n\"/__bddef {\\n\"\n\"    1 index exch __bdef\\n\"\n\"    exch __procdocs 3 1 roll put\\n\"\n\"} __bdef\\n\"\n\"\\n\"\n\"\\n\"\n\"%\\n\"\n\"% procedures\\n\"\n\"%\\n\"\n\"(any n:int _NDUP any1 ... anyn)\\n\"\n\"/_ndup { { dup } repeat } __bddef\\n\"\n\"\\n\"\n\"(x:any x:any _DEDUP x:any\\n\"\n\" x:any y:any _DEDUP x:any y:any)\\n\"\n\"/_dedup {\\n\"\n\"    count 1 gt {\\n\"\n\"        2 copy eq {\\n\"\n\"            pop\\n\"\n\"        } if\\n\"\n\"    } if\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(space:int space:int _DEDUP_SPACES space:int\\n\"\n\" otherthanspace:int space:int _DEDUP_SPACES otherthanspace:int space:int)\\n\"\n\"/_dedup_spaces {\\n\"\n\"    count 0 gt {\\n\"\n\"        dup ?\\\\_ eq {\\n\"\n\"            _dedup\\n\"\n\"        } if\\n\"\n\"    } if\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"% 32 32 _dedup_spaces pstack clear (---) ==\\n\"\n\"% 32 41 _dedup_spaces pstack clear (---) ==\\n\"\n\"% 41 32 _dedup_spaces pstack clear (---) ==\\n\"\n\"% 32 _dedup_spaces pstack clear (---) ==\\n\"\n\"% 41 _dedup_spaces pstack clear (---) ==\\n\"\n\"% quit\\n\"\n\"\\n\"\n\"/__buildstring {\\n\"\n\"    {\\n\"\n\"\t    counttomark dup 1 eq {\\n\"\n\"\t        pop exch pop\\n\"\n\"\t        exit\\n\"\n\"\t    } {\\n\"\n\"\t        -1 roll 1 index exch _putlast!\\n\"\n\"\t    } ifelse\\n\"\n\"    } loop\\n\"\n\"} __bdef\\n\"\n\"\\n\"\n\"(mark char:int|substring:string... _BUILDSTRING string)\\n\"\n\"/_buildstring {\\n\"\n\"    0 string __buildstring\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(string char:int|string _PUTLAST! -)\\n\"\n\"/_putlast!  {\\n\"\n\"    1 index length exch\\n\"\n\"    dup type /integertype eq {\\n\"\n\"\t    put\\n\"\n\"    } {\\n\"\n\"\t    putinterval\\n\"\n\"    } ifelse\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(target:string fromto:str _TR! -)\\n\"\n\"/_tr! {\\n\"\n\"    %\\n\"\n\"    % () is not allowed.\\n\"\n\"    % The reason must be be documented.\\n\"\n\"    %\\n\"\n\"    0 string\\n\"\n\"    % str [int<from> int<to>] str'\\n\"\n\"    2 index {\\n\"\n\"\t% str [int<from> int<to>] str' int<chr>\\n\"\n\"\t    dup 3 index 0 get\\n\"\n\"\t% str [int<from> int<to>] str' int<chr> int<chr> int<from>\\n\"\n\"\t    eq {% str [int<from> int<to>] str' int<chr>\\n\"\n\"\t        pop\\n\"\n\"\t        dup 2 index 1 get _putlast!\\n\"\n\"\t    } {% str [int<from> int<to>] str' int<chr>\\n\"\n\"\t        1 index exch _putlast!\\n\"\n\"\t    } ifelse\\n\"\n\"    } forall\\n\"\n\"    % str [int<from> int<to>] str'\\n\"\n\"    exch pop\\n\"\n\"    0 exch putinterval\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(string _NORMALIZE_SPACES! -)\\n\"\n\"/_normalize_spaces! {\\n\"\n\"    dup\\n\"\n\"    dup (\\\\n ) _tr!\\n\"\n\"    dup (\\\\t ) _tr!\\n\"\n\"    dup (\\\\r ) _tr!\\n\"\n\"    dup (\\\\f ) _tr!\\n\"\n\"    dup (\\\\v ) _tr!\\n\"\n\"    mark exch { _dedup_spaces } forall _buildstring\\n\"\n\"    exch copy pop\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(string _CHOP string)\\n\"\n\"/_chop {\\n\"\n\"    mark exch {} forall pop _buildstring\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(string _CHOP_SPACE string)\\n\"\n\"/_chop_space {\\n\"\n\"    dup length dup 0 gt {\\n\"\n\"        % string length\\n\"\n\"        1 sub\\n\"\n\"        % string `length - 1`\\n\"\n\"        1 index exch\\n\"\n\"        % string string `length - 1`\\n\"\n\"        get (\\\\n\\\\t\\\\r\\\\f\\\\v ) exch _amember {\\n\"\n\"            _chop\\n\"\n\"        } if\\n\"\n\"    } {\\n\"\n\"        pop                     % pop the length\\n\"\n\"    } ifelse\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"% /x mark 40 (a) 32 32 10 (b) 10 10 9 9 (xyz) 9 9 41 _buildstring def\\n\"\n\"% x _normalize_spaces! x pstack\\n\"\n\"\\n\"\n\"(tag:int _SCOPEREF -)\\n\"\n\"/_scoperef {\\n\"\n\"    _scopetop not { 0 } if scope:\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(tag:int _SCOPEPUSH -)\\n\"\n\"/_scopepush {\\n\"\n\"    dup _scoperef _scopeset\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(string _ISSTRING string true\\n\"\n\" any:!string _ISSTRING false)\\n\"\n\"/_isstring {\\n\"\n\"    dup type /stringtype eq {\\n\"\n\"        true\\n\"\n\"    } {\\n\"\n\"        pop false\\n\"\n\"    } ifelse\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(array key _AMEMBER true|fales)\\n\"\n\"/_amember {\\n\"\n\"    false 3 1 roll\\n\"\n\"    % false array key\\n\"\n\"    exch {\\n\"\n\"        % false key elt\\n\"\n\"        1 index\\n\"\n\"        % false key elt key\\n\"\n\"        eq {\\n\"\n\"            % false key\\n\"\n\"            exch pop true exch\\n\"\n\"            exit\\n\"\n\"        } if\\n\"\n\"        % false key\\n\"\n\"    } forall\\n\"\n\"    pop\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(array key _AINDEX nth:int true\\n\"\n\" array key _AINDEX false)\\n\"\n\"/_aindex {\\n\"\n\"    0 3 1 roll\\n\"\n\"    % idx array key\\n\"\n\"    exch {\\n\"\n\"        % idx key elt\\n\"\n\"        1 index\\n\"\n\"        eq {\\n\"\n\"            % idx key\\n\"\n\"            pop true exit\\n\"\n\"        } {\\n\"\n\"            % idx key\\n\"\n\"            exch 1 add exch\\n\"\n\"        } ifelse\\n\"\n\"    } forall\\n\"\n\"    dup true ne { pop pop false } if\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"% define @1 ~ @9.\\n\"\n\"1 1 9 {\\n\"\n\"    dup\\n\"\n\"    mark (- @) 3 -1 roll ?0 add ( start:matchloc) _buildstring\\n\"\n\"    exch dup\\n\"\n\"    mark (@) 3 -1 roll ?0 add _buildstring cvn\\n\"\n\"    exch\\n\"\n\"    [ exch /start /_matchloc cvx ] cvx __bddef\\n\"\n\"} for\\n\"\n\"\\n\"\n\"% define 1@ ~ 9@.\\n\"\n\"1 1 9 {\\n\"\n\"    dup\\n\"\n\"    mark (- ) 3 -1 roll ?0 add (@ end:matchloc) _buildstring\\n\"\n\"    exch dup\\n\"\n\"    mark exch ?0 add (@) _buildstring cvn\\n\"\n\"    exch\\n\"\n\"    [ exch /end /_matchloc cvx ] cvx __bddef\\n\"\n\"} for\\n\"\n\"\\n\"\n\"(name:str kind:name matchloc _TAG tag\\n\"\n\" name:str kind:name _TAG tag)\\n\"\n\"/_tag {\\n\"\n\"    dup type /nametype eq {\\n\"\n\"        % name:str kind:name\\n\"\n\"        null exch null\\n\"\n\"        % name:str null kind:name null\\n\"\n\"    } {\\n\"\n\"        % name:str kind:name matchloc\\n\"\n\"        null 3 1 roll null exch\\n\"\n\"        % name:str null kind:name matchloc null\\n\"\n\"    } ifelse\\n\"\n\"    _foreignreftag\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(name:str kind:name role:name matchloc _REFTAG tag\\n\"\n\" name:str kind:name role:name _REFTAG tag)\\n\"\n\"/_reftag {\\n\"\n\"    dup type /nametype eq {\\n\"\n\"        % name:str kind:name role:name\\n\"\n\"        null 3 1 roll\\n\"\n\"        % name:str null kind:name role:name\\n\"\n\"    } {\\n\"\n\"        % name:str kind:name role:name matchloc\\n\"\n\"        null 4 1 roll\\n\"\n\"        % name:str null kind:name role:name matchloc\\n\"\n\"    } ifelse\\n\"\n\"    _foreignreftag\\n\"\n\"} __bddef\\n\"\n\"\\n\"\n\"(name:str lang:name kind:name matchloc _FOREIGNTAG tag\\n\"\n\" name:str lang:name kind:name _FOREIGNTAG tag)\\n\"\n\"/_foreigntag {\\n\"\n\"    dup type /nametype eq {\\n\"\n\"        % name:str lang:name kind:name\\n\"\n\"        null\\n\"\n\"        % name:str lang:name kind:name null\\n\"\n\"        _foreignreftag\\n\"\n\"    } {\\n\"\n\"        % name:str language:name kind:name matchloc\\n\"\n\"        null exch\\n\"\n\"        % name:str language:name kind:name null matchloc\\n\"\n\"        _foreignreftag\\n\"\n\"    } ifelse\\n\"\n\"} __bddef\\n\"\n;\n"
  },
  {
    "path": "main/CommonPrelude.ps",
    "content": "%\n% Copyright (c) 2021, Masatake YAMATO\n% Copyright (c) 2021, Red Hat, Inc.\n%\n% This source code is released for free distribution under the terms of the\n% GNU General Public License version 2 or (at your option) any later version.\n%\n\n%\n% The documentation table\n%\n\n% __PROCDOCS:dict<proc:name, doc:string>\n/__procdocs 30 dict def\n\n% name value __BDEF -\n/__bdef { bind def }  bind def\n\n% doc:string key:name any:val __DOCDEF -\n/__bddef {\n    1 index exch __bdef\n    exch __procdocs 3 1 roll put\n} __bdef\n\n\n%\n% procedures\n%\n(any n:int _NDUP any1 ... anyn)\n/_ndup { { dup } repeat } __bddef\n\n(x:any x:any _DEDUP x:any\n x:any y:any _DEDUP x:any y:any)\n/_dedup {\n    count 1 gt {\n        2 copy eq {\n            pop\n        } if\n    } if\n} __bddef\n\n(space:int space:int _DEDUP_SPACES space:int\n otherthanspace:int space:int _DEDUP_SPACES otherthanspace:int space:int)\n/_dedup_spaces {\n    count 0 gt {\n        dup ?\\_ eq {\n            _dedup\n        } if\n    } if\n} __bddef\n\n% 32 32 _dedup_spaces pstack clear (---) ==\n% 32 41 _dedup_spaces pstack clear (---) ==\n% 41 32 _dedup_spaces pstack clear (---) ==\n% 32 _dedup_spaces pstack clear (---) ==\n% 41 _dedup_spaces pstack clear (---) ==\n% quit\n\n/__buildstring {\n    {\n\t    counttomark dup 1 eq {\n\t        pop exch pop\n\t        exit\n\t    } {\n\t        -1 roll 1 index exch _putlast!\n\t    } ifelse\n    } loop\n} __bdef\n\n(mark char:int|substring:string... _BUILDSTRING string)\n/_buildstring {\n    0 string __buildstring\n} __bddef\n\n(string char:int|string _PUTLAST! -)\n/_putlast!  {\n    1 index length exch\n    dup type /integertype eq {\n\t    put\n    } {\n\t    putinterval\n    } ifelse\n} __bddef\n\n(target:string fromto:str _TR! -)\n/_tr! {\n    %\n    % () is not allowed.\n    % The reason must be be documented.\n    %\n    0 string\n    % str [int<from> int<to>] str'\n    2 index {\n\t% str [int<from> int<to>] str' int<chr>\n\t    dup 3 index 0 get\n\t% str [int<from> int<to>] str' int<chr> int<chr> int<from>\n\t    eq {% str [int<from> int<to>] str' int<chr>\n\t        pop\n\t        dup 2 index 1 get _putlast!\n\t    } {% str [int<from> int<to>] str' int<chr>\n\t        1 index exch _putlast!\n\t    } ifelse\n    } forall\n    % str [int<from> int<to>] str'\n    exch pop\n    0 exch putinterval\n} __bddef\n\n(string _NORMALIZE_SPACES! -)\n/_normalize_spaces! {\n    dup\n    dup (\\n ) _tr!\n    dup (\\t ) _tr!\n    dup (\\r ) _tr!\n    dup (\\f ) _tr!\n    dup (\\v ) _tr!\n    mark exch { _dedup_spaces } forall _buildstring\n    exch copy pop\n} __bddef\n\n(string _CHOP string)\n/_chop {\n    mark exch {} forall pop _buildstring\n} __bddef\n\n(string _CHOP_SPACE string)\n/_chop_space {\n    dup length dup 0 gt {\n        % string length\n        1 sub\n        % string `length - 1`\n        1 index exch\n        % string string `length - 1`\n        get (\\n\\t\\r\\f\\v ) exch _amember {\n            _chop\n        } if\n    } {\n        pop                     % pop the length\n    } ifelse\n} __bddef\n\n% /x mark 40 (a) 32 32 10 (b) 10 10 9 9 (xyz) 9 9 41 _buildstring def\n% x _normalize_spaces! x pstack\n\n(tag:int _SCOPEREF -)\n/_scoperef {\n    _scopetop not { 0 } if scope:\n} __bddef\n\n(tag:int _SCOPEPUSH -)\n/_scopepush {\n    dup _scoperef _scopeset\n} __bddef\n\n(string _ISSTRING string true\n any:!string _ISSTRING false)\n/_isstring {\n    dup type /stringtype eq {\n        true\n    } {\n        pop false\n    } ifelse\n} __bddef\n\n(array key _AMEMBER true|fales)\n/_amember {\n    false 3 1 roll\n    % false array key\n    exch {\n        % false key elt\n        1 index\n        % false key elt key\n        eq {\n            % false key\n            exch pop true exch\n            exit\n        } if\n        % false key\n    } forall\n    pop\n} __bddef\n\n(array key _AINDEX nth:int true\n array key _AINDEX false)\n/_aindex {\n    0 3 1 roll\n    % idx array key\n    exch {\n        % idx key elt\n        1 index\n        eq {\n            % idx key\n            pop true exit\n        } {\n            % idx key\n            exch 1 add exch\n        } ifelse\n    } forall\n    dup true ne { pop pop false } if\n} __bddef\n\n% define @1 ~ @9.\n1 1 9 {\n    dup\n    mark (- @) 3 -1 roll ?0 add ( start:matchloc) _buildstring\n    exch dup\n    mark (@) 3 -1 roll ?0 add _buildstring cvn\n    exch\n    [ exch /start /_matchloc cvx ] cvx __bddef\n} for\n\n% define 1@ ~ 9@.\n1 1 9 {\n    dup\n    mark (- ) 3 -1 roll ?0 add (@ end:matchloc) _buildstring\n    exch dup\n    mark exch ?0 add (@) _buildstring cvn\n    exch\n    [ exch /end /_matchloc cvx ] cvx __bddef\n} for\n\n(name:str kind:name matchloc _TAG tag\n name:str kind:name _TAG tag)\n/_tag {\n    dup type /nametype eq {\n        % name:str kind:name\n        null exch null\n        % name:str null kind:name null\n    } {\n        % name:str kind:name matchloc\n        null 3 1 roll null exch\n        % name:str null kind:name matchloc null\n    } ifelse\n    _foreignreftag\n} __bddef\n\n(name:str kind:name role:name matchloc _REFTAG tag\n name:str kind:name role:name _REFTAG tag)\n/_reftag {\n    dup type /nametype eq {\n        % name:str kind:name role:name\n        null 3 1 roll\n        % name:str null kind:name role:name\n    } {\n        % name:str kind:name role:name matchloc\n        null 4 1 roll\n        % name:str null kind:name role:name matchloc\n    } ifelse\n    _foreignreftag\n} __bddef\n\n(name:str lang:name kind:name matchloc _FOREIGNTAG tag\n name:str lang:name kind:name _FOREIGNTAG tag)\n/_foreigntag {\n    dup type /nametype eq {\n        % name:str lang:name kind:name\n        null\n        % name:str lang:name kind:name null\n        _foreignreftag\n    } {\n        % name:str language:name kind:name matchloc\n        null exch\n        % name:str language:name kind:name null matchloc\n        _foreignreftag\n    } ifelse\n} __bddef\n"
  },
  {
    "path": "main/Makefile",
    "content": "all:\n.SUFFIXES:\n.SUFFIXES: .c .o\n\n.c.o:\n\t$(MAKE) -C .. main/$@\n%:\n\t$(MAKE) -C .. $@\n"
  },
  {
    "path": "main/args.c",
    "content": "/*\n*   Copyright (c) 1999-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for reading command line arguments.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <stdio.h>\n#include <string.h>\n#include <ctype.h>\n\n#include \"args_p.h\"\n#include \"debug.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic char *nextStringArg (const char** const next)\n{\n\tchar* result = NULL;\n\tconst char* start;\n\n\tAssert (*next != NULL);\n\tfor (start = *next  ;  isspace ((unsigned char) *start)  ;  ++start)\n\t\t;\n\tif (*start == '\\0')\n\t\t*next = start;\n\telse\n\t{\n\t\tsize_t length;\n\t\tconst char* end;\n\n\t\tfor (end = start; *end != '\\0' && ! isspace ((unsigned char) *end); ++end)\n\t\t\t;\n\t\tlength = end - start;\n\t\tAssert (length > 0);\n\t\tresult = xMalloc (length + 1, char);\n\t\tstrncpy (result, start, length);\n\t\tresult [length] = '\\0';\n\t\t*next = end;\n\t}\n\treturn result;\n}\n\nstatic char* nextStringLine (const char** const next)\n{\n\tchar* result = NULL;\n\tsize_t length;\n\tconst char* end;\n\n\tAssert (*next != NULL);\n\tfor (end = *next ;  *end != '\\n'  &&  *end != '\\0' ;  ++end)\n\t\t;\n\tlength = end - *next;\n\tif (length > 0)\n\t{\n\t\tresult = xMalloc (length + 1, char);\n\t\tstrncpy (result, *next, length);\n\t\tresult [length] = '\\0';\n\t}\n\tif (*end == '\\n')\n\t\t++end;\n\telse if (*end == '\\r')\n\t{\n\t\t++end;\n\t\tif (*end == '\\n')\n\t\t\t++end;\n\t}\n\t*next = end;\n\treturn result;\n}\n\nstatic char* nextString (const Arguments* const current, const char** const next)\n{\n\tchar* result;\n\tif (current->lineMode)\n\t\tresult = nextStringLine (next);\n\telse\n\t\tresult = nextStringArg (next);\n\treturn result;\n}\n\nstatic char* nextFileArg (FILE* const fp)\n{\n\tchar* result = NULL;\n\tAssert (fp != NULL);\n\tif (! feof (fp))\n\t{\n\t\tvString* vs = vStringNew ();\n\t\tint c;\n\t\tdo\n\t\t\tc = fgetc (fp);\n\t\twhile (isspace (c));\n\n\t\tif (c != EOF)\n\t\t{\n\t\t\tdo\n\t\t\t{\n\t\t\t\tvStringPut (vs, c);\n\t\t\t\tc = fgetc (fp);\n\t\t\t} while (c != EOF  &&  ! isspace (c));\n\t\t\tAssert (vStringLength (vs) > 0);\n\t\t\tresult = xMalloc (vStringLength (vs) + 1, char);\n\t\t\tstrcpy (result, vStringValue (vs));\n\t\t}\n\t\tvStringDelete (vs);\n\t}\n\treturn result;\n}\n\nstatic char* nextFileLine (FILE* const fp)\n{\n\tchar* result = NULL;\n\tAssert (fp != NULL);\n\tif (! feof (fp))\n\t{\n\t\tvString* vs = vStringNew ();\n\t\tint c;\n\n\t\tc = fgetc (fp);\n\t\twhile (c != EOF)\n\t\t{\n\t\t\tif (c != '\\n'  &&  c != '\\r')\n\t\t\t\tvStringPut (vs, c);\n\t\t\telse if (vStringLength (vs) > 0)\n\t\t\t\tbreak;\n\t\t\tc = fgetc (fp);\n\t\t}\n\t\tif (c != EOF  ||  vStringLength (vs) > 0)\n\t\t{\n\t\t\tif (c == '\\r')\n\t\t\t{\n\t\t\t\tc = fgetc (fp);\n\t\t\t\tif (c != '\\n')\n\t\t\t\t\tc = ungetc (c, fp);\n\t\t\t}\n\t\t\tvStringStripTrailing (vs);\n\t\t\tvStringStripLeading (vs);\n\t\t\tresult = xMalloc (vStringLength (vs) + 1, char);\n\t\t\tstrcpy (result, vStringValue (vs));\n\t\t}\n\t\tvStringDelete (vs);\n\t}\n\treturn result;\n}\n\nstatic bool isCommentLine (char* line)\n{\n\twhile (isspace((unsigned char) *line))\n\t\t++line;\n\treturn (*line == '#');\n}\n\nstatic bool isOptscriptLine (char *line)\n{\n\tsize_t len = strlen (line);\n\tif (len < 2)\n\t\treturn false;\n\tif (line [len - 1] == '{' && line [len - 2] == '{')\n\t\treturn true;\n\treturn false;\n}\n\nstatic char* nextOptscriptLines (FILE* const fp, char *line)\n{\n\tvString *vstr = vStringNewInit (line);\n\tvStringPut (vstr, '\\n');\n\teFree (line);\n\n\t/* \\n}}, \\n=>1, }=>2, }=>3  */\n\tint endMarkers = 0;\n\tint c;\n\twhile (true)\n\t{\n\t\tc = fgetc (fp);\n\t\tif (c == EOF)\n\t\t\tbreak;\n\n\t\tif (c == '\\r' || c == '\\n')\n\t\t{\n\t\t\tif (c == '\\r')\n\t\t\t{\n\t\t\t\tc = fgetc (fp);\n\t\t\t\tif (c != '\\n')\n\t\t\t\t{\n\t\t\t\t\tungetc(c, fp);\n\t\t\t\t\tc = '\\n';\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (c == '\\n')\n\t\t\t{\n\t\t\t\tvStringPut (vstr, c);\n\t\t\t\tif (endMarkers != 1)\n\t\t\t\t\tendMarkers = 1;\n\t\t\t}\n\t\t}\n\t\telse if (c == '}')\n\t\t{\n\t\t\tvStringPut (vstr, c);\n\t\t\tif (endMarkers == 1 || endMarkers == 2)\n\t\t\t\tendMarkers++;\n\t\t\tif (endMarkers == 3)\n\t\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tendMarkers = 0;\n\t\t\tvStringPut (vstr, c);\n\t\t}\n\t}\n\n\tif (c == EOF)\n\t{\n\t\tswitch (endMarkers)\n\t\t{\n\t\tcase 0:\n\t\t\tvStringPut (vstr, '\\n');\n\t\t\t/* Fall through */\n\t\tcase 1:\n\t\t\tvStringPut (vstr, '}');\n\t\t\t/* Fall through */\n\t\tcase 2:\n\t\t\tvStringPut (vstr, '}');\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tc = fgetc (fp);\n\twhile (c != EOF)\n\t{\n\t\tif (c == '\\n')\n\t\t\tbreak;\n\t\tif (c == '\\r')\n\t\t{\n\t\t\tc = fgetc (fp);\n\t\t\tif (c == '\\n')\n\t\t\t\tbreak;\n\t\t\tungetc (c, fp);\n\t\t}\n\t\tc = fgetc (fp);\n\t}\n\treturn vStringDeleteUnwrap (vstr);\n}\n\nstatic char* nextFileLineSkippingComments (FILE* const fp)\n{\n\tchar* result;\n\tbool comment;\n\tbool optscript;\n\n\tdo\n\t{\n\t\tresult = nextFileLine (fp);\n\t\tcomment = false;\n\t\toptscript = false;\n\t\tif (result)\n\t\t{\n\t\t\tcomment = isCommentLine (result);\n\t\t\toptscript = isOptscriptLine (result);\n\t\t}\n\t\tif (comment)\n\t\t\teFree (result);\n\t\telse if (optscript)\n\t\t\tresult = nextOptscriptLines (fp, result);\n\t} while (comment);\n\n\treturn result;\n}\n\nstatic char* nextFileString (const Arguments* const current, FILE* const fp)\n{\n\tchar* result;\n\tif (current->lineMode)\n\t\tresult = nextFileLineSkippingComments (fp);\n\telse\n\t\tresult = nextFileArg (fp);\n\treturn result;\n}\n\nextern Arguments* argNewFromString (const char* const string)\n{\n\tArguments* result = xMalloc (1, Arguments);\n\tmemset (result, 0, sizeof (Arguments));\n\tresult->type = ARG_STRING;\n\tresult->u.stringArgs.next = string;\n\tresult->item = nextString (result, &result->u.stringArgs.next);\n\treturn result;\n}\n\nextern Arguments* argNewFromArgv (char* const* const argv)\n{\n\tArguments* result = xMalloc (1, Arguments);\n\tmemset (result, 0, sizeof (Arguments));\n\tresult->type = ARG_ARGV;\n\tresult->u.argvArgs.argv = argv;\n\tresult->u.argvArgs.item = result->u.argvArgs.argv;\n\tresult->item = *result->u.argvArgs.item;\n\treturn result;\n}\n\nextern Arguments* argNewFromFile (FILE* const fp)\n{\n\tArguments* result = xMalloc (1, Arguments);\n\tmemset (result, 0, sizeof (Arguments));\n\tresult->type = ARG_FILE;\n\tresult->u.fileArgs.fp = fp;\n\tresult->item = nextFileString (result, result->u.fileArgs.fp);\n\treturn result;\n}\n\nextern Arguments* argNewFromLineFile (FILE* const fp)\n{\n\tArguments* result = xMalloc (1, Arguments);\n\tmemset (result, 0, sizeof (Arguments));\n\tresult->type = ARG_FILE;\n\tresult->lineMode = true;\n\tresult->u.fileArgs.fp = fp;\n\tresult->item = nextFileString (result, result->u.fileArgs.fp);\n\treturn result;\n}\n\nextern char *argItem (const Arguments* const current)\n{\n\tAssert (current != NULL);\n\tAssert (! argOff (current));\n\treturn current->item;\n}\n\nextern bool argOff (const Arguments* const current)\n{\n\tAssert (current != NULL);\n\treturn (bool) (current->item == NULL);\n}\n\nextern void argSetWordMode (Arguments* const current)\n{\n\tAssert (current != NULL);\n\tcurrent->lineMode = false;\n}\n\nextern void argSetLineMode (Arguments* const current)\n{\n\tAssert (current != NULL);\n\tcurrent->lineMode = true;\n}\n\nextern void argForth (Arguments* const current)\n{\n\tAssert (current != NULL);\n\tAssert (! argOff (current));\n\tswitch (current->type)\n\t{\n\t\tcase ARG_STRING:\n\t\t\tif (current->item != NULL)\n\t\t\t\teFree (current->item);\n\t\t\tcurrent->item = nextString (current, &current->u.stringArgs.next);\n\t\t\tbreak;\n\t\tcase ARG_ARGV:\n\t\t\t++current->u.argvArgs.item;\n\t\t\tcurrent->item = *current->u.argvArgs.item;\n\t\t\tbreak;\n\t\tcase ARG_FILE:\n\t\t\tif (current->item != NULL)\n\t\t\t\teFree (current->item);\n\t\t\tcurrent->item = nextFileString (current, current->u.fileArgs.fp);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tAssert (\"Invalid argument type\" == NULL);\n\t\t\tbreak;\n\t}\n}\n\nextern void argDelete (Arguments* const current)\n{\n\tAssert (current != NULL);\n\tif ((current->type ==  ARG_STRING\n\t\t || current->type ==  ARG_FILE) &&  current->item != NULL)\n\t\teFree (current->item);\n\tmemset (current, 0, sizeof (Arguments));\n\teFree (current);\n}\n"
  },
  {
    "path": "main/args_p.h",
    "content": "/*\n*   Copyright (c) 1999-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines external interface to command line argument reading.\n*/\n#ifndef CTAGS_MAIN_ARGS_PRIVATE_H\n#define CTAGS_MAIN_ARGS_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <stdio.h>\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef enum { ARG_NONE, ARG_STRING, ARG_ARGV, ARG_FILE } argType;\n\ntypedef struct sArgs {\n\targType type;\n\tunion {\n\t\tstruct sStringArgs {\n\t\t\tconst char* next;\n\t\t} stringArgs;\n\t\tstruct sArgvArgs {\n\t\t\tchar* const* argv;\n\t\t\tchar* const* item;\n\t\t} argvArgs;\n\t\tstruct sFileArgs {\n\t\t\tFILE* fp;\n\t\t} fileArgs;\n\t} u;\n\tchar* item;\n\tbool lineMode;\n} Arguments;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern Arguments* argNewFromString (const char* const string);\nextern Arguments* argNewFromArgv (char* const* const argv);\nextern Arguments* argNewFromFile (FILE* const fp);\nextern Arguments* argNewFromLineFile (FILE* const fp);\nextern char *argItem (const Arguments* const current);\nextern bool argOff (const Arguments* const current);\nextern void argSetWordMode (Arguments* const current);\nextern void argSetLineMode (Arguments* const current);\nextern void argForth (Arguments* const current);\nextern void argDelete (Arguments* const current);\n\n#endif  /* CTAGS_MAIN_ARGS_PRIVATE_H */\n"
  },
  {
    "path": "main/cmd.c",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"main_p.h\"\n\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nint main(int argc, char **argv)\n{\n\treturn ctags_cli_main (argc, argv);\n}\n"
  },
  {
    "path": "main/collector.c",
    "content": "/*\n*   Copyright (c) 2025, Red Hat, Inc.\n*   Copyright (c) 2025, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n\n#include \"collector.h\"\n#include \"routines.h\"\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nvoid collectorInit (collector *collector, int xdata)\n{\n\tcollector->repr = vStringNew ();\n\tcollector->lastLen = 0;\n\tcollector->xdata = xdata;\n}\n\nvoid collectorFini (collector *collector)\n{\n\tvStringDelete (collector->repr);\n}\n\nvoid collectorStamp (collector *collector, int xdata)\n{\n\tcollector->lastLen = vStringLength (collector->repr);\n\tcollector->xdata = xdata;\n}\n\nchar *collectorStrdup (collector *collector)\n{\n\n\treturn eStrdup (vStringValue (collector->repr));\n}\n\nvoid collectorPut (collector *collector, char c)\n{\n\tvStringPut (collector->repr, c);\n}\n\nvoid collectorCat (collector *collector, vString *vstr)\n{\n\tvStringCat (collector->repr, vstr);\n}\n\nvoid collectorCatS (collector *collector, const char *str)\n{\n\tvStringCatS (collector->repr, str);\n}\n\nvoid collectorJoin (collector *collector, char c, vString *vstr)\n{\n\tvStringJoin (collector->repr, c, vstr);\n}\n"
  },
  {
    "path": "main/collector.h",
    "content": "/*\n*   Copyright (c) 2025, Red Hat, Inc.\n*   Copyright (c) 2025, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n#ifndef CTAGS_MAIN_COLLECTOR_H\n#define CTAGS_MAIN_COLLECTOR_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n#include \"vstring.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\n\n/* vString based string collector.\n *\n * This data type is for building values for signature and typeref fields\n * from tokens.\n */\nstruct sCollector {\n\tvString *repr;\n\tsize_t lastLen;\n\tint xdata;\n};\ntypedef struct sCollector collector;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nvoid collectorInit (collector *collector, int xdata);\nvoid collectorFini (collector *collector);\nvoid collectorStamp (collector *collector, int xdata);\nchar *collectorStrdup (collector *collector);\nvoid collectorPut (collector *collector, char c);\nvoid collectorCat (collector *collector, vString *vstr);\nvoid collectorCatS (collector *collector, const char *str);\nvoid collectorJoin (collector *collector, char c, vString *vstr);\n#endif\t/* CTAGS_MAIN_COLLECTOR_H */\n"
  },
  {
    "path": "main/colprint.c",
    "content": "/*\n*   Copyright (c) 2017 Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"colprint_p.h\"\n#include \"ptrarray.h\"\n#include \"routines.h\"\n#include \"strlist.h\"\n#include \"vstring.h\"\n\n#include <stdarg.h>\n#include <stdio.h>\n#include <string.h>\n\n\nenum colprintJustification {\n\tCOLPRINT_LEFT  = 0,\n\tCOLPRINT_RIGHT = 1,\n\tCOLPRINT_JUST  = 1 << 0,\n\tCOLPRINT_LAST  = 1 << 1,\t/* private use */\n};\n\nstruct colprintHeaderColumn {\n\tvString *value;\n\tenum colprintJustification justification;\n\tsize_t maxWidth;\n\tbool needPrefix;\n};\n\nstruct colprintTable {\n\tptrArray *header;\n\tptrArray *lines;\n};\n\nstatic void fillWithWhitespaces (size_t i, FILE *fp)\n{\n\twhile (i-- > 0)\n\t{\n\t\tfputc(' ', fp);\n\t}\n}\n\nstatic struct colprintHeaderColumn * colprintHeaderColumnNew (const char* spec)\n{\n\tint offset = 2;\n\tstruct colprintHeaderColumn *headerCol = xCalloc (1, struct colprintHeaderColumn);\n\n\tif (strstr(spec, \"L:\") == spec)\n\t\theaderCol->justification = COLPRINT_LEFT;\n\telse if (strstr(spec, \"R:\") == spec)\n\t\theaderCol->justification = COLPRINT_RIGHT;\n\telse\n\t{\n\t\theaderCol->justification = COLPRINT_LEFT;\n\t\toffset = 0;\n\t}\n\n\theaderCol->value = vStringNewInit(spec + offset);\n\theaderCol->maxWidth = vStringLength(headerCol->value);\n\treturn headerCol;\n}\n\nstatic void colprintHeaderColumnDelete (struct colprintHeaderColumn * headerCol)\n{\n\tvStringDelete (headerCol->value);\n\teFree (headerCol);\n}\n\nstruct colprintTable *colprintTableNew (const char* columnHeader, ... /* NULL TERMINATED */)\n{\n\tchar *tmp;\n\tva_list ap;\n\tstruct colprintTable *table;\n\tstruct colprintHeaderColumn *headerCol;\n\n\n\ttable = xCalloc (1, struct colprintTable);\n\ttable->header = ptrArrayNew ((ptrArrayDeleteFunc)colprintHeaderColumnDelete);\n\ttable->lines  = ptrArrayNew ((ptrArrayDeleteFunc)stringListDelete);\n\n\theaderCol = colprintHeaderColumnNew(columnHeader);\n\tptrArrayAdd (table->header, headerCol);\n\n\tva_start(ap, columnHeader);\n\twhile (1)\n\t{\n\t\ttmp = va_arg(ap, char*);\n\t\tif (tmp)\n\t\t{\n\t\t\theaderCol = colprintHeaderColumnNew(tmp);\n\t\t\tptrArrayAdd (table->header, headerCol);\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\tva_end(ap);\n\n\tstruct colprintHeaderColumn *last_col =\tptrArrayLast (table->header);\n\tif (last_col)\n\t\tlast_col->justification |= COLPRINT_LAST;\n\n\treturn table;\n}\n\nvoid colprintTableDelete (struct colprintTable *table)\n{\n\tptrArrayDelete(table->header);\n\ttable->header = NULL;\n\n\tptrArrayDelete(table->lines);\n\ttable->header = NULL;\n\n\teFree (table);\n}\n\nstatic void colprintColumnPrintGeneric (vString *column, struct colprintHeaderColumn *spec, bool machinable, FILE *fp)\n{\n\tsize_t maxWidth = spec->maxWidth + (spec->needPrefix? 1: 0);\n\n\tif ((column == spec->value) && (spec->needPrefix))\n\t{\n\t\tfputc('#', fp);\n\t\tmaxWidth--;\n\t}\n\n\tif (machinable)\n\t{\n\t\tfputs (vStringValue (column), fp);\n\t\tif (! (spec->justification & COLPRINT_LAST))\n\t\t\tfputc ('\\t', fp);\n\t}\n\telse\n\t{\n\t\tsize_t padLen = 0;\n\t\tsize_t colLen = vStringLength (column);\n\t\tif (colLen < maxWidth)\n\t\t\tpadLen = maxWidth - colLen;\n\t\tif ((spec->justification & COLPRINT_JUST) == COLPRINT_LEFT)\n\t\t{\n\t\t\tfputs (vStringValue (column), fp);\n\t\t\tif (! (spec->justification & COLPRINT_LAST))\n\t\t\t{\n\t\t\t\tfillWithWhitespaces (padLen, fp);\n\t\t\t\tfputc (' ', fp);\n\t\t\t}\n\t\t}\n\t\telse if ((spec->justification & COLPRINT_JUST) == COLPRINT_RIGHT)\n\t\t{\n\t\t\tfillWithWhitespaces (padLen, fp);\n\t\t\tfputs (vStringValue (column), fp);\n\t\t\tfputc (' ', fp);\n\t\t}\n\t}\n}\n\nstatic void colprintHeaderColumnPrint (struct colprintHeaderColumn *headerCol, bool machinable, FILE* fp)\n{\n\tcolprintColumnPrintGeneric (headerCol->value, headerCol, machinable, fp);\n}\n\nstatic void colprintHeaderPrint (ptrArray *header, unsigned int startFrom, bool withHeader, bool machinable, FILE *fp)\n{\n\tunsigned int i;\n\n\tif (!withHeader)\n\t\treturn;\n\n\tfor (i = startFrom; i < ptrArrayCount(header); i++)\n\t{\n\t\tstruct colprintHeaderColumn *headerCol = ptrArrayItem (header, i);\n\t\tcolprintHeaderColumnPrint (headerCol, machinable, fp);\n\t}\n\tfputc('\\n', fp);\n}\n\nstatic void colprintLinePrint  (stringList *line, unsigned int startFrom, ptrArray *header, bool machinable, FILE *fp)\n{\n\tunsigned int i;\n\n\tfor (i = startFrom; i < stringListCount (line); i++)\n\t{\n\t\tvString *value = stringListItem(line, i);\n\t\tstruct colprintHeaderColumn *spec = ptrArrayItem (header, i);\n\t\tcolprintColumnPrintGeneric(value, spec, machinable, fp);\n\t}\n}\nstatic void colprintLinesPrint (ptrArray *lines, unsigned int startFrom, ptrArray *header, bool machinable, FILE *fp)\n{\n\tunsigned int i;\n\n\tfor (i = 0; i < ptrArrayCount (lines); i++)\n\t{\n\t\tstringList *line = ptrArrayItem (lines, i);\n\t\tcolprintLinePrint (line, startFrom, header, machinable, fp);\n\t\tfputc('\\n', fp);\n\t}\n}\n\nstatic void colprintUpdateMaxWidths (ptrArray *header, ptrArray *lines, unsigned int startFrom)\n{\n\tfor (unsigned int c = 0; c < ptrArrayCount(header); c++)\n\t{\n\t\tstruct colprintHeaderColumn *spec = ptrArrayItem (header, c);\n\n\t\tif (c == startFrom)\n\t\t\tspec->needPrefix = true;\n\t\telse\n\t\t\tspec->needPrefix = false;\n\t}\n\n\tfor (unsigned int c = 0; c < ptrArrayCount(header); c++)\n\t{\n\t\tstruct colprintHeaderColumn *spec = ptrArrayItem (header, c);\n\n\t\tfor (unsigned int l = 0; l < ptrArrayCount(lines); l++)\n\t\t{\n\t\t\tstruct colprintLine *line = ptrArrayItem(lines, l);\n\t\t\tvString *column = ptrArrayItem((ptrArray *)line, c);\n\t\t\tif (spec->maxWidth < vStringLength(column))\n\t\t\t\tspec->maxWidth = vStringLength(column);\n\t\t}\n\t}\n}\n\nvoid colprintTablePrint (struct colprintTable *table, unsigned int startFrom, bool withHeader, bool machinable, FILE *fp)\n{\n\tcolprintUpdateMaxWidths (table->header, table->lines, startFrom);\n\n\tcolprintHeaderPrint (table->header, startFrom, withHeader, machinable, fp);\n\tcolprintLinesPrint (table->lines, startFrom, table->header, machinable, fp);\n}\n\nvoid colprintTableSort  (struct colprintTable *table, int (* compareFn) (struct colprintLine *, struct colprintLine *))\n{\n\tptrArraySort (table->lines, (int (*) (const void *, const void *))compareFn);\n}\n\nstruct colprintLine *colprintTableGetNewLine (struct colprintTable *table)\n{\n\tstringList *line = stringListNew ();\n\n\tptrArrayAdd (table->lines, line);\n\treturn (struct colprintLine *)line;\n}\n\nstatic void colprintLineAppendColumn (struct colprintLine *line, vString *column)\n{\n\tstringList *slist = (stringList *)line;\n\tstringListAdd (slist, column);\n}\n\nvoid colprintLineAppendColumnCString (struct colprintLine *line, const char *column)\n{\n\tvString* vcol = vStringNewInit (column? column: \"\");\n\tcolprintLineAppendColumn (line, vcol);\n}\n\nvoid colprintLineAppendColumnVString (struct colprintLine *line, vString* column)\n{\n\tcolprintLineAppendColumnCString(line, vStringValue (column));\n}\n\nvoid colprintLineAppendColumnChar (struct colprintLine *line, char column)\n{\n\tvString* vcol = vStringNew ();\n\tvStringPut (vcol, column);\n\tcolprintLineAppendColumn (line, vcol);\n}\n\nvoid colprintLineAppendColumnInt  (struct colprintLine *line, unsigned int column)\n{\n\tchar buf[12];\n\n\tsnprintf(buf, sizeof(buf), \"%u\", column);\n\tcolprintLineAppendColumnCString\t(line, buf);\n}\n\nvoid colprintLineAppendColumnBool  (struct colprintLine *line, bool column)\n{\n\tcolprintLineAppendColumnCString\t(line, column? \"yes\": \"no\");\n}\n\nvoid colprintLineAppendColumnVersion (struct colprintLine *line, unsigned int version)\n{\n\tchar buf[12+1];\n\tsnprintf(buf, sizeof(buf), \"%u\", version);\n\tcolprintLineAppendColumnCString\t(line, buf);\n}\n\nconst char *colprintLineGetColumn (struct colprintLine *line, unsigned int column)\n{\n\tstringList *slist = (stringList *)line;\n\tif (column <= stringListCount(slist))\n\t{\n\t\tvString *vstr = stringListItem (slist, column);\n\t\treturn vStringValue (vstr);\n\t}\n\telse\n\t\treturn NULL;\n}\n"
  },
  {
    "path": "main/colprint_p.h",
    "content": "/*\n*   Copyright (c) 2017 Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n#ifndef CTAGS_MAIN_COLPRINT_PRIVATE_H\n#define CTAGS_MAIN_COLPRINT_PRIVATE_H\n\n#include \"general.h\"\n\n#include \"vstring.h\"\n#include <stdio.h>\n\nstruct colprintTable;\nstruct colprintLine;\n\n/* Each column must have a prefix for specifying justification: \"L:\" or \"R:\". */\nstruct colprintTable *colprintTableNew (const char* columnHeader, ... /* NULL TERMINATED */);\nvoid colprintTableDelete (struct colprintTable *table);\nvoid colprintTablePrint (struct colprintTable *table, unsigned int startFrom, bool withHeader, bool machinable, FILE *fp);\nvoid colprintTableSort  (struct colprintTable *table, int (* compareFn) (struct colprintLine *, struct colprintLine *));\n\nstruct colprintLine *colprintTableGetNewLine (struct colprintTable *table);\n\nvoid colprintLineAppendColumnCString (struct colprintLine *line, const char* column);\nvoid colprintLineAppendColumnVString (struct colprintLine *line, vString* column);\nvoid colprintLineAppendColumnChar (struct colprintLine *line, char column);\nvoid colprintLineAppendColumnInt  (struct colprintLine *line, unsigned int column);\n\n/* Appends \"yes\" or \"no\". */\nvoid colprintLineAppendColumnBool (struct colprintLine *line, bool column);\nvoid colprintLineAppendColumnVersion (struct colprintLine *line, unsigned int version);\n\nconst char *colprintLineGetColumn (struct colprintLine *line, unsigned int column);\n\n#endif /* CTAGS_MAIN_COLPRINT_PRIVATE_H */\n"
  },
  {
    "path": "main/ctags.h",
    "content": "/*\n*   Copyright (c) 1996-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Program definitions\n*/\n#ifndef CTAGS_MAIN_CTAGS_H\n#define CTAGS_MAIN_CTAGS_H\n\n#include \"general.h\"\n\n/*\n*   MACROS\n*/\n\n/* VERSION.REVISION.PATCH:\n\n   For incompatible changes for the command line interface (CLI)\n   of ctags or readtags commands, increment VERSION.\n   Removing a parameter of a parser is part of incompatible change\n   for the CLI.\n   When OUTPUT_VERSION_AGE set to 0, increment VERSION. Set REVISION\n   and PATCH to 0.\n   For changing setting versionAge member of a parser, increment\n   VERSION. Set REVISION and PATCH to 0.\n   When chaging VERSION, set REVISION and PATCH to 0.\n\n   For uppper compatible changes for the CLI,\n   increment REVISION.\n   Adding a new parameter to a parser is an uppper compatible change.\n   When incrementing OUTPUT_VERSION_CURRENT but not setting\n   OUTPUT_VERSION_AGE to 0, increment REVISION.\n   For changing increment versionCurrent member of a parser but not\n   setting versionAge to 0, increment REVISION.\n   When changing REVISION, set PATCH to 0.\n\n   For implementation changes like bug fixes, increment PATCH. */\n\n#if defined (HAVE_CONFIG_H)\n/* You must update PACKAGE_VERSION in configure.ac, too.\n * The --version option of readtags also prints this. */\n# define PROGRAM_VERSION PACKAGE_VERSION\n#else\n# define PROGRAM_VERSION \"6.2.0\"\n#endif\n#define PROGRAM_NAME      \"Universal Ctags\"\n#define PROGRAM_URL       \"https://ctags.io/\"\n#define PROGRAM_COPYRIGHT \"Copyright (C) 2015-2025\"\n#define AUTHOR_NAME       \"Universal Ctags Team\"\n\n/* The concept of CURRENT and AGE is taken from libtool.\n * However, we deleted REVISION in libtool when importing\n * the concept of versioning from libtool.\n *\n * If common fields, common extras, pseudo tags have been added,\n * removed or changed since last release, increment CURRENT.\n * If they have been added since last release, increment AGE.\n * If they have been removed since last release, set AGE to 0\n *\n * From the command line of ctags, you can see the version\n * information with --version and --version=NONE.\n *\n * In the tags file, !_TAGS_OUTPUT_VERSION shows the the version.\n *\n * Chaning for the command line interface, and implementation changes\n * like bug fixes don't affect the CURRENT an AGE.\n */\n#define OUTPUT_VERSION_CURRENT 1\n#define OUTPUT_VERSION_AGE 1\n\n/*\n * Constant\n */\nextern const char* ctags_repoinfo;\n#define CTAGS_FIELD_PREFIX \"UCTAGS\"\n\n/*\n * Reserved words\n */\n#define RSV_LANGMAP_DEFAULT \"default\"\n#define RSV_LANG_ALL \"all\"\n#define RSV_LANG_AUTO \"auto\"\n#define RSV_NONE \"NONE\"\n#endif\t/* CTAGS_MAIN_CTAGS_H */\n"
  },
  {
    "path": "main/debug.c",
    "content": "/*\n*   Copyright (c) 1996-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains debugging functions.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <ctype.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <stdarg.h>\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"options.h\"\n#include \"parse_p.h\"\n#include \"read.h\"\n#include \"read_p.h\"\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n#ifdef DEBUG\n#include \"htable.h\"\n\n\nextern void lineBreak (void) {}  /* provides a line-specified break point */\n\nextern void debugPrintf (\n\t\tconst enum eDebugLevels level, const char *const format, ... )\n{\n\tva_list ap;\n\n\tva_start (ap, format);\n\tif (debug (level))\n\t\tvprintf (format, ap);\n\tfflush (stdout);\n\tva_end (ap);\n}\n\nextern void debugPutc (const int level, const int c)\n{\n\tif (debug (level)  &&  c != EOF)\n\t{\n\t\tputchar (c);\n\t\tfflush (stdout);\n\t}\n}\n\nextern void debugParseNest (const bool increase, const unsigned int level)\n{\n\tdebugPrintf (DEBUG_PARSE, \"<*%snesting:%d*>\", increase ? \"++\" : \"--\", level);\n}\n\nextern void debugCppNest (const bool begin, const unsigned int level)\n{\n\tdebugPrintf (DEBUG_CPP, \"<*cpp:%s level %d*>\", begin ? \"begin\":\"end\", level);\n}\n\nextern void debugCppIgnore (const bool ignore)\n{\n\tdebugPrintf (DEBUG_CPP, \"<*cpp:%s ignore*>\", ignore ? \"begin\":\"end\");\n}\n\nextern void debugEntry (const tagEntryInfo *const tag)\n{\n\tconst char *const scope = tag->isFileScope ? \"{fs}\" : \"\";\n\n\tif (debug (DEBUG_PARSE))\n\t{\n\t\tlangType lang = (tag->extensionFields.scopeLangType == LANG_AUTO)\n\t\t\t? tag->langType\n\t\t\t: tag->extensionFields.scopeLangType;\n\t\tkindDefinition *scopeKindDef = getLanguageKind(lang,\n\t\t\t\t\t\t\t\t\t\t\t\t\t   tag->extensionFields.scopeKindIndex);\n\t\tprintf (\"<#%s%s:%s\", scope, getTagKindName(tag), tag->name);\n\n\t\tif (tag->extensionFields.scopeKindIndex != KIND_GHOST_INDEX  &&\n\t\t\t\ttag->extensionFields.scopeName != NULL)\n\t\t\tprintf (\" [%s:%s]\", scopeKindDef->name,\n\t\t\t\t\ttag->extensionFields.scopeName);\n\n\t\tif (isFieldEnabled (FIELD_INHERITANCE) &&\n\t\t\t\ttag->extensionFields.inheritance != NULL)\n\t\t\tprintf (\" [inherits:%s]\", tag->extensionFields.inheritance);\n\n\t\tif (isFieldEnabled (FIELD_FILE_SCOPE) &&\n\t\t\t\ttag->isFileScope && ! isInputHeaderFile ())\n\t\t\tprintf (\" [file:]\");\n\n\t\tif (isFieldEnabled (FIELD_ACCESS) &&\n\t\t\t\ttag->extensionFields.access != NULL)\n\t\t\tprintf (\" [access:%s]\", tag->extensionFields.access);\n\n\t\tif (isFieldEnabled (FIELD_IMPLEMENTATION) &&\n\t\t\t\ttag->extensionFields.implementation != NULL)\n\t\t\tprintf (\" [imp:%s]\", tag->extensionFields.implementation);\n\n\t\tif (isFieldEnabled (FIELD_TYPE_REF) &&\n\t\t\t\ttag->extensionFields.typeRef [0] != NULL  &&\n\t\t\t\ttag->extensionFields.typeRef [1] != NULL)\n\t\t\tprintf (\" [%s:%s]\", tag->extensionFields.typeRef [0],\n\t\t\t\t\ttag->extensionFields.typeRef [1]);\n\n\t\tprintf (\"#>\");\n\t\tfflush (stdout);\n\t}\n}\n\nextern void debugAssert (const char *assertion, const char *file, unsigned int line, const char *function)\n{\n\tfprintf(stderr, \"ctags: %s:%u: %s%sAssertion `%s' failed.\\n\",\n\t        file, line,\n\t        function ? function : \"\", function ? \": \" : \"\",\n\t        assertion);\n\tif (getInputFileName())\n\t{\n\t\tfprintf(stderr, \"ctags: %s:%u: parsing %s:%lu as %s\\n\",\n\t\t        file, line,\n\t\t        getInputFileName(), getInputLineNumber(),\n\t\t        getInputLanguageName());\n\t}\n\tfflush(stderr);\n\tabort();\n}\n\nstatic int debugScopeDepth;\n#define DEBUG_INDENT_UNIT 4\n\nstatic char debugPrefix[DEBUG_INDENT_UNIT + 1];\n\nextern void debugInit (void)\n{\n\tmemset(debugPrefix, ' ', DEBUG_INDENT_UNIT);\n\tdebugPrefix[DEBUG_INDENT_UNIT] = '\\0';\n}\n\nextern void debugIndent(void)\n{\n\tfor(int i=0;i< debugScopeDepth;i++)\n\t\tfputs(debugPrefix, stderr);\n}\n\nextern void debugInc(void)\n{\n\tdebugScopeDepth++;\n}\n\nextern void debugDec(void)\n{\n\tdebugScopeDepth--;\n\tif(debugScopeDepth < 0)\n\t\tdebugScopeDepth = 0;\n}\n\n\n\nstruct circularRefChecker {\n\thashTable *visitTable;\n\tint counter;\n};\n\nextern void circularRefCheckerDestroy (struct circularRefChecker * checker)\n{\n\thashTableDelete (checker->visitTable);\n\tchecker->visitTable = NULL;\n\teFree (checker);\n}\n\nextern struct circularRefChecker * circularRefCheckerNew (void)\n{\n\tAssert (sizeof(void *) >= sizeof(int));\n\n\tstruct circularRefChecker *c = xMalloc (1, struct circularRefChecker);\n\n\tc->visitTable = hashTableNew (17, hashPtrhash, hashPtreq, NULL, NULL);\n\tc->counter = 0;\n\n\treturn c;\n}\n\nextern int circularRefCheckerCheck (struct circularRefChecker *c, void *ptr)\n{\n\tunion conv {\n\t\tint i;\n\t\tvoid *ptr;\n\t} v;\n\n\tv.ptr = hashTableGetItem(c->visitTable, ptr);\n\tif (v.ptr)\n\t\treturn v.i;\n\telse\n\t{\n\t\tv.i = ++c->counter;\n\t\thashTablePutItem (c->visitTable, ptr, v.ptr);\n\t\treturn 0;\n\t}\n}\n\nextern int circularRefCheckerGetCurrent (struct circularRefChecker *c)\n{\n\treturn c->counter;\n}\n\nextern void circularRefCheckClear (struct circularRefChecker *c)\n{\n\thashTableClear (c->visitTable);\n\tc->counter = 0;\n}\n\n#endif\n"
  },
  {
    "path": "main/debug.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to debug.c\n*/\n#ifndef CTAGS_MAIN_DEBUG_H\n#define CTAGS_MAIN_DEBUG_H\n\n/*\n*   Include files\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"gvars.h\"\n#include \"types.h\"\n#ifdef DEBUG\n# include <assert.h>\n#endif\n\n/*\n*   Macros\n*/\n\n#if defined _MSC_VER\n/* See https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros */\n# define ASSERT_FUNCTION __FUNCTION__\n#elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L\n# define ASSERT_FUNCTION __func__\n#else\n# define ASSERT_FUNCTION ((const char*)0)\n#endif\n\n#ifdef DEBUG\n# define debug(level)      ((ctags_debugLevel & (long)(level)) != 0)\n# define DebugStatement(x) x\n# define PrintStatus(x)    if (debug(DEBUG_STATUS)) printf x;\n# ifdef NDEBUG\n#  define Assert(c) do {} while(0)\n#  define AssertNotReached() do {} while(0)\n# else\n   /* We expect cc supports c99 standard. */\n#  define Assert(c) ((c) ? ((void)0) : debugAssert(#c, __FILE__, __LINE__, ASSERT_FUNCTION))\n#  define AssertNotReached() Assert(!\"The control reaches unexpected place\")\n# endif\n#else\n# define DebugStatement(x)\n# define PrintStatus(x)\n# define Assert(c) do {} while(0)\n# define AssertNotReached() do {} while(0)\n# ifndef NDEBUG\n#  define NDEBUG\n# endif\n#endif\n\n#ifdef DEBUG\n/* This makes valgrind report an error earlier. */\n#define DISABLE_OBJPOOL\n#endif\n/*\n*   Data declarations\n*/\n\n/*  Defines the debugging levels.\n */\nenum eDebugLevels {\n\tDEBUG_READ   = 0x01,  /* echo raw (filtered) characters */\n\tDEBUG_PARSE  = 0x02,  /* echo parsing results */\n\tDEBUG_STATUS = 0x04,  /* echo file status information */\n\tDEBUG_OPTION = 0x08,  /* echo option parsing */\n\tDEBUG_CPP    = 0x10,  /* echo characters out of pre-processor */\n\tDEBUG_RAW    = 0x20   /* echo raw (filtered) characters */\n};\n\n/*\n*   Function prototypes\n*/\nextern void lineBreak (void);\nextern void debugPrintf (const enum eDebugLevels level, const char *const format, ...) CTAGS_ATTR_PRINTF (2, 3);\nextern void debugPutc (const int level, const int c);\nextern void debugParseNest (const bool increase, const unsigned int level);\nextern void debugCppNest (const bool begin, const unsigned int level);\nextern void debugCppIgnore (const bool ignore);\nextern void debugEntry (const tagEntryInfo *const tag);\nextern void debugAssert (const char *assertion, const char *file, unsigned int line, const char *function) attr__noreturn;\n\n#ifdef DEBUG\n#define DEBUG_INIT() debugInit()\nextern void debugInit (void);\nextern void debugIndent(void);\nextern void debugInc(void);\nextern void debugDec(void);\n\nstruct circularRefChecker;\nextern struct circularRefChecker * circularRefCheckerNew (void);\nextern void circularRefCheckerDestroy (struct circularRefChecker * checker);\nextern int circularRefCheckerCheck (struct circularRefChecker *c, void *ptr);\nextern int circularRefCheckerGetCurrent (struct circularRefChecker *c);\nextern void circularRefCheckClear (struct circularRefChecker *c);\n\n#else\n#define DEBUG_INIT() do { } while(0)\n#endif\t/* DEBUG */\n#endif  /* CTAGS_MAIN_DEBUG_H */\n"
  },
  {
    "path": "main/dependency.c",
    "content": "/*\n *\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#include \"general.h\"  /* must always come first */\n\n#include \"debug.h\"\n#include \"dependency.h\"\n#include \"options.h\"\n#include \"parse_p.h\"\n#include \"read.h\"\n#include \"read_p.h\"\n#include \"routines.h\"\n#include \"subparser.h\"\n#include \"subparser_p.h\"\n#include \"xtag.h\"\n\n#include <string.h>\n\nstruct slaveControlBlock {\n\tslaveParser *slaveParsers;\t/* The parsers on this list must be initialized when\n\t\t\t\t\t\t\t\t   this parser is initialized. */\n\tsubparser   *subparsersDefault;\n\tsubparser   *subparsersInUse;\n\tlangType     owner;\n};\n\nextern void linkDependencyAtInitializeParsing (depType dtype,\n\t\t\t\t\t\t   parserDefinition *const master,\n\t\t\t\t\t\t   struct slaveControlBlock *masterSCB,\n\t\t\t\t\t\t   struct kindControlBlock *masterKCB,\n\t\t\t\t\t\t   parserDefinition *const slave,\n\t\t\t\t\t\t   struct kindControlBlock *slaveKCB,\n\t\t\t\t\t\t   void *data)\n{\n\tif (dtype == DEPTYPE_KIND_OWNER)\n\t\tlinkKindDependency (masterKCB, slaveKCB);\n\telse if (dtype == DEPTYPE_SUBPARSER || dtype == DEPTYPE_FOREIGNER)\n\t{\n\t\tslaveParser *s = xMalloc (1, slaveParser);\n\n\t\ts->type = dtype;\n\t\ts->id = slave->id;\n\t\ts->data = data;\n\n\t\ts->next = masterSCB->slaveParsers;\n\t\tmasterSCB->slaveParsers = s;\n\t}\n}\n\nstatic void attachSubparser (struct slaveControlBlock *base_sb, subparser *subparser)\n{\n\t   subparser->next = base_sb->subparsersDefault;\n\t   base_sb->subparsersDefault = subparser;\n}\n\n\nextern struct slaveControlBlock *allocSlaveControlBlock (parserDefinition *parser)\n{\n\tstruct slaveControlBlock *cb;\n\n\tcb = xMalloc (1, struct slaveControlBlock);\n\tcb->slaveParsers = NULL;\n\tcb->subparsersDefault = NULL;\n\tcb->subparsersInUse = NULL;\n\tcb->owner = parser->id;\n\n\treturn cb;\n}\n\nextern void freeSlaveControlBlock (struct slaveControlBlock *cb)\n{\n\teFree (cb);\n}\n\nextern void initializeDependencies (parserDefinition *parser,\n\t\t\t\t\t\t\t\t\tstruct slaveControlBlock *cb)\n{\n\tunsigned int i;\n\tslaveParser *sp;\n\n\t/* Initialize slaves */\n\tsp = cb->slaveParsers;\n\twhile (sp != NULL)\n\t{\n\t\tif (sp->type == DEPTYPE_SUBPARSER)\n\t\t{\n\t\t\tsubparser *sub;\n\n\t\t\tsub = (subparser *)sp->data;\n\t\t\tsub->slaveParser = sp;\n\t\t}\n\n\t\tif (sp->type == DEPTYPE_KIND_OWNER\n\t\t\t|| (sp->type == DEPTYPE_SUBPARSER &&\n\t\t\t\t(((subparser *)sp->data)->direction & SUBPARSER_BASE_RUNS_SUB)))\n\t\t{\n\t\t\tinitializeParser (sp->id);\n\t\t\tif (sp->type == DEPTYPE_SUBPARSER\n\t\t\t\t&& isXtagEnabled (XTAG_SUBPARSER))\n\t\t\t{\n\t\t\t\tsubparser *subparser = sp->data;\n\t\t\t\tattachSubparser (cb, subparser);\n\t\t\t}\n\t\t}\n\t\tsp = sp->next;\n\t}\n\n\t/* Initialize masters that act as base parsers. */\n\tfor (i = 0; i < parser->dependencyCount; i++)\n\t{\n\t\tparserDependency *d = parser->dependencies + i;\n\t\tif ((d->type == DEPTYPE_SUBPARSER &&\n\t\t\t ((subparser *)(d->data))->direction & SUBPARSER_SUB_RUNS_BASE)\n\t\t\t|| (d->type == DEPTYPE_FOREIGNER))\n\t\t{\n\t\t\tlangType baseParser;\n\t\t\tbaseParser = getNamedLanguage (d->upperParser, 0);\n\t\t\tAssert (baseParser != LANG_IGNORE);\n\t\t\tinitializeParser (baseParser);\n\t\t\tif (d->type == DEPTYPE_FOREIGNER && d->data)\n\t\t\t\t*((langType *)d->data) = baseParser;\n\t\t}\n\t}\n}\n\nextern void finalizeDependencies (parserDefinition *parser,\n\t\t\t\t\t\t\t\t  struct slaveControlBlock *cb)\n{\n\twhile (cb->slaveParsers)\n\t{\n\t\tslaveParser *sp = cb->slaveParsers;\n\t\tcb->slaveParsers = sp->next;\n\t\tsp->next = NULL;\n\t\teFree (sp);\n\t}\n}\n\nextern void notifyInputStart (void)\n{\n\tsubparser *s;\n\n\t/* for running prelude of optlib */\n\tlangType lang = getInputLanguage ();\n\tnotifyLanguageRegexInputStart (lang);\n\n\tforeachSubparser(s, true)\n\t{\n\t\tenterSubparser(s);\n\t\tif (s->inputStart)\n\t\t\ts->inputStart (s);\n\t\t/* propagate the event recursively */\n\t\tnotifyInputStart ();\n\t\tleaveSubparser();\n\t}\n}\n\nextern void notifyInputEnd   (void)\n{\n\tsubparser *s;\n\n\tforeachSubparser(s, true)\n\t{\n\t\tenterSubparser(s);\n\t\t/* propagate the event recursively */\n\t\tnotifyInputEnd ();\n\t\tif (s->inputEnd)\n\t\t\ts->inputEnd (s);\n\t\tleaveSubparser();\n\t}\n\n\t/* for running sequel of optlib */\n\tlangType lang = getInputLanguage ();\n\tnotifyLanguageRegexInputEnd (lang);\n}\n\nextern void notifyMakeTagEntry (const tagEntryInfo *tag, int corkIndex)\n{\n\tsubparser *s;\n\n\tforeachSubparser(s, false)\n\t{\n\t\tif (s->makeTagEntryNotify)\n\t\t{\n\t\t\tenterSubparser(s);\n\t\t\ts->makeTagEntryNotify (s, tag, corkIndex);\n\t\t\tleaveSubparser();\n\t\t}\n\t}\n}\n\nextern langType getSubparserLanguage (subparser *s)\n{\n\treturn s->slaveParser->id;\n}\n\nextern void chooseExclusiveSubparser (subparser *s, void *data)\n{\n\tif (s->exclusiveSubparserChosenNotify)\n\t{\n\t\ts->chosenAsExclusiveSubparser = true;\n\t\tenterSubparser(s);\n\t\ts->exclusiveSubparserChosenNotify (s, data);\n\t\tverbose (\"%s is chosen as exclusive subparser\\n\",\n\t\t\t\t getLanguageName (getSubparserLanguage (s)));\n\t\tleaveSubparser();\n\t}\n}\n\nextern subparser *getFirstSubparser(struct slaveControlBlock *controlBlock)\n{\n\tif (controlBlock)\n\t\treturn controlBlock->subparsersInUse;\n\treturn NULL;\n}\n\nextern void useDefaultSubparsers (struct slaveControlBlock *controlBlock)\n{\n\tcontrolBlock->subparsersInUse = controlBlock->subparsersDefault;\n}\n\nextern void useSpecifiedSubparser (struct slaveControlBlock *controlBlock, subparser *s)\n{\n\ts->schedulingBaseparserExplicitly = true;\n\tcontrolBlock->subparsersInUse = s;\n}\n\nextern void setupSubparsersInUse (struct slaveControlBlock *controlBlock)\n{\n\tif (!controlBlock->subparsersInUse)\n\t\tuseDefaultSubparsers(controlBlock);\n}\n\nextern subparser* teardownSubparsersInUse (struct slaveControlBlock *controlBlock)\n{\n\tsubparser *tmp;\n\tsubparser *s = NULL;\n\n\ttmp = controlBlock->subparsersInUse;\n\tcontrolBlock->subparsersInUse = NULL;\n\n\tif (tmp && tmp->schedulingBaseparserExplicitly)\n\t{\n\t\ttmp->schedulingBaseparserExplicitly = false;\n\t\ts = tmp;\n\t}\n\n\tif (s)\n\t\treturn s;\n\n\twhile (tmp)\n\t{\n\t\tif (tmp->chosenAsExclusiveSubparser)\n\t\t{\n\t\t\ts = tmp;\n\t\t}\n\t\ttmp = tmp->next;\n\t}\n\n\treturn s;\n}\n\n\nstatic int subparserDepth;\n\nextern void enterSubparser(subparser *subparser)\n{\n\tsubparserDepth++;\n\tpushLanguage (getSubparserLanguage (subparser));\n}\n\nextern void leaveSubparser(void)\n{\n\tpopLanguage ();\n\tsubparserDepth--;\n}\n\nextern bool doesSubparserRun (void)\n{\n\tif (getLanguageForBaseParser () == getInputLanguage())\n\t\treturn false;\n\treturn subparserDepth;\n}\n\nextern slaveParser *getFirstSlaveParser (struct slaveControlBlock *scb)\n{\n\tif (scb)\n\t\treturn scb->slaveParsers;\n\treturn NULL;\n}\n\nextern subparser *getLanguageSubparser (langType sublang,\n\t\t\t\t\t\t\t\t\t\tbool including_none_crafted_parser)\n{\n\tsubparser *s;\n\n\tforeachSubparser (s, including_none_crafted_parser)\n\t{\n\t\tif (getSubparserLanguage (s) == sublang)\n\t\t\treturn s;\n\t}\n\treturn NULL;\n}\n\nextern struct colprintTable * subparserColprintTableNew (void)\n{\n\treturn colprintTableNew (\"L:NAME\", \"L:BASEPARSER\", \"L:DIRECTIONS\", NULL);\n}\n\nextern void subparserColprintAddSubparsers (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\t\t\tstruct slaveControlBlock *scb)\n{\n\tslaveParser *tmp;\n\n\tpushLanguage (scb->owner);\n\tforeachSlaveParser(tmp)\n\t{\n\t\tif (tmp->type != DEPTYPE_SUBPARSER)\n\t\t\tcontinue;\n\n\t\tif (!isLanguageVisible (tmp->id))\n\t\t\tcontinue;\n\n\t\tstruct colprintLine *line = colprintTableGetNewLine(table);\n\n\t\tcolprintLineAppendColumnCString (line, getLanguageName (tmp->id));\n\t\tcolprintLineAppendColumnCString (line, getLanguageName (scb->owner));\n\n\t\tconst char *direction;\n\t\tswitch (((subparser *)tmp->data)->direction)\n\t\t{\n\t\tcase SUBPARSER_BASE_RUNS_SUB:\n\t\t\tdirection = \"base => sub {shared}\";\n\t\t\tbreak;\n\t\tcase SUBPARSER_SUB_RUNS_BASE:\n\t\t\tdirection = \"base <= sub {dedicated}\";\n\t\t\tbreak;\n\t\tcase SUBPARSER_BI_DIRECTION:\n\t\t\tdirection = \"base <> sub {bidirectional}\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tdirection  = \"UNKNOWN(INTERNAL BUG)\";\n\t\t\tbreak;\n\t\t}\n\t\tcolprintLineAppendColumnCString (line, direction);\n\t}\n\tpopLanguage ();\n}\n\nstatic int subparserColprintCompareLines (struct colprintLine *a , struct colprintLine *b)\n{\n\tconst char *a_name = colprintLineGetColumn (a, 0);\n\tconst char *b_name = colprintLineGetColumn (b, 0);\n\n\tint r;\n\tr = strcmp (a_name, b_name);\n\tif (r != 0)\n\t\treturn r;\n\n\tconst char *a_baseparser = colprintLineGetColumn (a, 1);\n\tconst char *b_baseparser = colprintLineGetColumn (b, 1);\n\n\treturn strcmp(a_baseparser, b_baseparser);\n}\n\nextern void subparserColprintTablePrint (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\t\t bool withListHeader, bool machinable, FILE *fp)\n{\n\tcolprintTableSort (table, subparserColprintCompareLines);\n\tcolprintTablePrint (table, 0, withListHeader, machinable, fp);\n}\n\nextern const char *dependencyTypeString(enum eDepType e)\n{ /* Generated by misc/enumstr.sh with cmdline:\n     misc/enumstr.sh main/dependency.h eDepType dependencyTypeString DEPTYPE_  */\n\tswitch (e)\n\t{\n\t\tcase   DEPTYPE_KIND_OWNER: return \"KIND_OWNER\";\n\t\tcase    DEPTYPE_SUBPARSER: return \"SUBPARSER\";\n\t\tcase    DEPTYPE_FOREIGNER: return \"FOREIGNER\";\n\t\tcase       COUNT_DEPTYPES: return \"COUNT_DEPTYPES\";\n\t\tdefault:                   return \"UNKNOWN\";\n\t}\n}\n"
  },
  {
    "path": "main/dependency.h",
    "content": "/*\n *\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_DEPENDENCY_H\n#define CTAGS_MAIN_DEPENDENCY_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"types.h\"\n\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef enum eDepType {\n\tDEPTYPE_KIND_OWNER,\n\tDEPTYPE_SUBPARSER,\n\tDEPTYPE_FOREIGNER,\n\tCOUNT_DEPTYPES,\n} depType;\n\nstruct sParserDependency {\n\tdepType type;\n\tconst char *upperParser;\n\tvoid *data;\n};\n\nstruct sSlaveParser {\n\tdepType type;\n\tlangType id;\n\tvoid *data;\n\tslaveParser *next;\n};\n\n#endif\t/* CTAGS_MAIN_DEPENDENCY_H */\n"
  },
  {
    "path": "main/dependency_p.h",
    "content": "/*\n *\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_DEPENDENCY_PRIVATE_H\n#define CTAGS_MAIN_DEPENDENCY_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"dependency.h\"\n#include \"kind.h\"\n#include \"types.h\"\n\n/*\n*   MACROS\n*/\n#define foreachSlaveParser(VAR)\t\t\t\\\n\tVAR = NULL;\t\t\t\t\t\t\t\t\\\n\twhile ((VAR = getNextSlaveParser (VAR)) != NULL)\n\n\n/*\n*   DATA DECLARATIONS\n*/\nstruct slaveControlBlock;\t/* Opaque data type for parse.c */\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void linkDependencyAtInitializeParsing (depType dtype,\n\t\t\t\t\t\t   parserDefinition *const master,\n\t\t\t\t\t\t   struct slaveControlBlock *masterSCB,\n\t\t\t\t\t\t   struct kindControlBlock *masterKCB,\n\t\t\t\t\t\t   parserDefinition *const slave,\n\t\t\t\t\t\t   struct kindControlBlock *slaveKCB,\n\t\t\t\t\t\t   void *data);\n\nextern struct slaveControlBlock *allocSlaveControlBlock (parserDefinition *parser);\nextern void freeSlaveControlBlock (struct slaveControlBlock *cb);\nextern void initializeDependencies (parserDefinition *parser,\n\t\t\t\t\t\t\t\t\tstruct slaveControlBlock *cb);\nextern void finalizeDependencies (parserDefinition *parser,\n\t\t\t\t\t\t\t\t  struct slaveControlBlock *cb);\n\nextern slaveParser *getFirstSlaveParser(struct slaveControlBlock *controlBlock);\nextern slaveParser *getNextSlaveParser(slaveParser *last);\n\nextern const char *dependencyTypeString(enum eDepType e);\n#endif\t/* CTAGS_MAIN_DEPENDENCY_PRIVATE_H */\n"
  },
  {
    "path": "main/e_msoft.h",
    "content": "/*\n*   Copyright (c) 2002-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Configures ctags for Microsoft environment.\n*/\n#ifndef E_MSOFT_H\n#define E_MSOFT_H\n\n#define CASE_INSENSITIVE_FILENAMES 1\n#define MANUAL_GLOBBING 1\n#define MSDOS_STYLE_PATH 1\n#define HAVE_FCNTL_H 1\n#define HAVE_IO_H 1\n#define HAVE_SYS_STAT_H 1\n#define HAVE_SYS_TYPES_H 1\n#define HAVE_CHSIZE 1\n#define HAVE_DIRECT_H 1\n#define HAVE_STRICMP 1\n#define HAVE_STRNICMP 1\n#define HAVE_STRERROR 1\n#define HAVE__FINDFIRST 1\n#define HAVE_FINDNEXT 1\n#define findfirst_t intptr_t\n#define HAVE_MKSTEMP 1\n#define HAVE_FNMATCH 1\n#define HAVE_FNMATCH_H 1\n#define HAVE_PUTENV 1\n#define TMPDIR \"\\\\\"\n\nint mkstemp (char *template_name);\n\n#ifdef _MSC_VER\n\n# if _MSC_VER < 1900\n#  define snprintf _snprintf\n# endif\n\n#if (_MSC_VER >= 1800) // Visual Studio 2013 or newer\n#define HAVE_STDBOOL_H 1\n#else\ntypedef enum { false, true } bool;\n#endif\n\n# ifndef _CRT_SECURE_NO_DEPRECATE\n#  define _CRT_SECURE_NO_DEPRECATE 1\n# endif\n# pragma warning(disable : 4996)\n\n#elif defined (__MINGW32__)\n\n# include <_mingw.h>\n# define HAVE_STDBOOL_H 1\n# define HAVE_DIRENT_H 1\n# define ffblk _finddata_t\n# define FA_DIREC _A_SUBDIR\n# define ff_name name\n\n# if defined(__USE_MINGW_ANSI_STDIO) && defined(__MINGW64_VERSION_MAJOR)\n#  define HAVE_ASPRINTF 1\n# endif\n\n#endif\n\n#endif\n"
  },
  {
    "path": "main/entry.c",
    "content": "/*\n*   Copyright (c) 1996-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for creating tag entries.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <ctype.h>        /* to define isspace () */\n#include <errno.h>\n\n#if defined (HAVE_SYS_TYPES_H)\n# include <sys/types.h>\t  /* to declare off_t on some hosts */\n#endif\n#if defined (HAVE_TYPES_H)\n# include <types.h>       /* to declare off_t on some hosts */\n#endif\n#if defined (HAVE_UNISTD_H)\n# include <unistd.h>      /* to declare close (), ftruncate (), truncate () */\n#endif\n\n/*  These header files provide for the functions necessary to do file\n *  truncation.\n */\n#ifdef HAVE_FCNTL_H\n# include <fcntl.h>\n#endif\n#ifdef HAVE_IO_H\n# include <io.h>\n#endif\n\n#include <stdint.h>\n#include <limits.h>  /* to define INT_MAX */\n\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"field.h\"\n#include \"fmt_p.h\"\n#include \"kind.h\"\n#include \"interval_tree_generic.h\"\n#include \"nestlevel.h\"\n#include \"options_p.h\"\n#include \"ptag_p.h\"\n#include \"rbtree.h\"\n#include \"read.h\"\n#include \"read_p.h\"\n#include \"routines.h\"\n#include \"routines_p.h\"\n#include \"parse_p.h\"\n#include \"ptrarray.h\"\n#include \"sort_p.h\"\n#include \"strlist.h\"\n#include \"subparser_p.h\"\n#include \"trashbox.h\"\n#include \"writer_p.h\"\n#include \"xtag_p.h\"\n\n/*\n*   MACROS\n*/\n\n/*\n *  Portability defines\n */\n#if !defined(HAVE_TRUNCATE) && !defined(HAVE_FTRUNCATE) && !defined(HAVE_CHSIZE)\n# define USE_REPLACEMENT_TRUNCATE\n#endif\n\n/*  Hack for ridiculous practice of Microsoft Visual C++.\n */\n#if defined (_WIN32) && defined (_MSC_VER)\n# define chsize         _chsize\n# define open           _open\n# define close          _close\n# define O_RDWR         _O_RDWR\n#endif\n\n\n/*  Maintains the state of the tag file.\n */\ntypedef struct eTagFile {\n\tchar *name;\n\tchar *directory;\n\tMIO *mio;\n\tstruct sNumTags { unsigned long added, prev; } numTags;\n\tstruct sMax { size_t line, tag; } max;\n\tvString *vLine;\n\n\tint cork;\n\tunsigned int corkFlags;\n\tptrArray *corkQueue;\n\tstruct rb_root intervaltab;\n\n\tbool patternCacheValid;\n} tagFile;\n\ntypedef struct sTagEntryInfoX  {\n\ttagEntryInfo slot;\n\tint corkIndex;\n\tstruct rb_root symtab;\n\tstruct rb_node symnode;\n\tstruct rb_node intervalnode;\n\tunsigned long __intervalnode_subtree_last;\n} tagEntryInfoX;\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic tagFile TagFile = {\n\tNULL,               /* tag file name */\n\tNULL,               /* tag file directory (absolute) */\n\tNULL,               /* file pointer */\n\t{ 0, 0 },           /* numTags */\n\t{ 0, 0 },        /* max */\n\tNULL,                /* vLine */\n\t.cork = false,\n\t.corkQueue = NULL,\n\t/* .intervaltab = RB_ROOT,\n\t *\n\t * msvc doesn't accept the above expression:\n\t *\n\t *   main\\entry.c(128) : error C2099: initializer is not a constant\n\t *\n\t */\n\t.patternCacheValid = false,\n};\n\nstatic bool TagsToStdout = false;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n#ifdef NEED_PROTO_TRUNCATE\nextern int truncate (const char *path, off_t length);\n#endif\n\n#ifdef NEED_PROTO_FTRUNCATE\nextern int ftruncate (int fd, off_t length);\n#endif\n\n#define INTERVAL_START(node) ((node)->slot.lineNumber)\n#define INTERVAL_END(node) (getTagEndLine (&(node)->slot))\n\nINTERVAL_TREE_DEFINE(tagEntryInfoX, intervalnode,\n\t\t\t\t\t unsigned long, __intervalnode_subtree_last,\n\t\t\t\t\t INTERVAL_START, INTERVAL_END, /*static*/, intervaltab)\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nextern void freeTagFileResources (void)\n{\n\tif (TagFile.directory != NULL)\n\t\teFree (TagFile.directory);\n\tvStringDelete (TagFile.vLine);\n}\n\nextern const char *tagFileName (void)\n{\n\treturn TagFile.name;\n}\n\n/*\n*   Pseudo tag support\n*/\n\nextern void abort_if_ferror(MIO *const mio)\n{\n\tif (mio != NULL && mio_error (mio))\n\t\terror (FATAL | PERROR, \"cannot write tag file\");\n}\n\nstatic void rememberMaxLengths (const size_t nameLength, const size_t lineLength)\n{\n\tif (nameLength > TagFile.max.tag)\n\t\tTagFile.max.tag = nameLength;\n\n\tif (lineLength > TagFile.max.line)\n\t\tTagFile.max.line = lineLength;\n}\n\nstatic void addCommonPseudoTags (void)\n{\n\tfor (int i = 0; i < PTAG_COUNT; i++)\n\t{\n\t\tif (isPtagCommonInParsers (i))\n\t\t\tmakePtagIfEnabled (i, LANG_IGNORE, &Option);\n\t}\n}\n\nextern void makeFileTag (const char *const fileName)\n{\n\ttagEntryInfo tag;\n\n\tif (!isXtagEnabled(XTAG_FILE_NAMES))\n\t\treturn;\n\n\tinitTagEntry (&tag, baseFilename (fileName), KIND_FILE_INDEX);\n\n\ttag.isFileEntry     = true;\n\ttag.lineNumberEntry = true;\n\tmarkTagExtraBit (&tag, XTAG_FILE_NAMES);\n\n\ttag.lineNumber = 1;\n\tif (isFieldEnabled (FIELD_END_LINE))\n\t{\n\t\t/* isFieldEnabled is called again in the rendering\n\t\t   stage. However, it is called here for avoiding\n\t\t   unnecessary read line loop. */\n\t\twhile (readLineFromInputFile () != NULL)\n\t\t\t; /* Do nothing */\n\t\tsetTagEndLine(&tag, getInputLineNumber ());\n\t}\n\n\tif (isFieldEnabled (FIELD_EPOCH))\n\t\ttag.extensionFields.epoch = getInputFileMtime ();\n\n\tmakeTagEntry (&tag);\n}\n\nstatic void updateSortedFlag (\n\t\tconst char *const line, MIO *const mio, MIOPos startOfLine)\n{\n\tconst char *const tab = strchr (line, '\\t');\n\n\tif (tab != NULL)\n\t{\n\t\tconst long boolOffset = tab - line + 1;  /* where it should be */\n\n\t\tif (line [boolOffset] == '0'  ||  line [boolOffset] == '1')\n\t\t{\n\t\t\tMIOPos nextLine;\n\n\t\t\tif (mio_getpos (mio, &nextLine) == -1 || mio_setpos (mio, &startOfLine) == -1)\n\t\t\t\terror (WARNING, \"Failed to update 'sorted' pseudo-tag\");\n\t\t\telse\n\t\t\t{\n\t\t\t\tMIOPos flagLocation;\n\t\t\t\tint c, d;\n\n\t\t\t\tdo\n\t\t\t\t\tc = mio_getc (mio);\n\t\t\t\twhile (c != '\\t'  &&  c != '\\n');\n\t\t\t\tmio_getpos (mio, &flagLocation);\n\t\t\t\td = mio_getc (mio);\n\t\t\t\tif (c == '\\t'  &&  (d == '0'  ||  d == '1')  &&\n\t\t\t\t\td != (int) Option.sorted)\n\t\t\t\t{\n\t\t\t\t\tmio_setpos (mio, &flagLocation);\n\t\t\t\t\tmio_putc (mio, Option.sorted == SO_FOLDSORTED ? '2' :\n\t\t\t\t\t\t(Option.sorted == SO_SORTED ? '1' : '0'));\n\t\t\t\t}\n\t\t\t\tmio_setpos (mio, &nextLine);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/*  Look through all line beginning with \"!_TAG_FILE\", and update those which\n *  require it.\n */\nstatic long unsigned int updatePseudoTags (MIO *const mio)\n{\n\tenum { maxEntryLength = 20 };\n\tchar entry [maxEntryLength + 1];\n\tunsigned long linesRead = 0;\n\tMIOPos startOfLine;\n\tsize_t entryLength;\n\tconst char *line;\n\n\tsprintf (entry, \"%sTAG_FILE\", PSEUDO_TAG_PREFIX);\n\tentryLength = strlen (entry);\n\tAssert (entryLength < maxEntryLength);\n\n\tmio_getpos (mio, &startOfLine);\n\tline = readLineRaw (TagFile.vLine, mio);\n\twhile (line != NULL  &&  line [0] == entry [0])\n\t{\n\t\t++linesRead;\n\t\tif (strncmp (line, entry, entryLength) == 0)\n\t\t{\n\t\t\tchar tab, classType [16];\n\n\t\t\tif (sscanf (line + entryLength, \"%15s%c\", classType, &tab) == 2  &&\n\t\t\t\ttab == '\\t')\n\t\t\t{\n\t\t\t\tif (strcmp (classType, \"_SORTED\") == 0)\n\t\t\t\t\tupdateSortedFlag (line, mio, startOfLine);\n\t\t\t}\n\t\t\tmio_getpos (mio, &startOfLine);\n\t\t}\n\t\tline = readLineRaw (TagFile.vLine, mio);\n\t}\n\twhile (line != NULL)  /* skip to end of file */\n\t{\n\t\t++linesRead;\n\t\tline = readLineRaw (TagFile.vLine, mio);\n\t}\n\treturn linesRead;\n}\n\n/*\n *  Tag file management\n */\n\nstatic bool isValidTagAddress (const char *const excmd)\n{\n\tbool isValid = false;\n\n\tif (strchr (\"/?\", excmd [0]) != NULL)\n\t\tisValid = true;\n\telse\n\t{\n\t\tchar *address = xMalloc (strlen (excmd) + 1, char);\n\t\tif (sscanf (excmd, \"%[^;\\n]\", address) == 1  &&\n\t\t\tstrspn (address,\"0123456789\") == strlen (address))\n\t\t\t\tisValid = true;\n\t\teFree (address);\n\t}\n\treturn isValid;\n}\n\nstatic bool isCtagsLine (const char *const line)\n{\n\tenum fieldList { TAG, TAB1, SRC_FILE, TAB2, EXCMD, NUM_FIELDS };\n\tbool ok = false;  /* we assume not unless confirmed */\n\tconst size_t fieldLength = strlen (line) + 1;\n\tchar *const fields = xMalloc (NUM_FIELDS * fieldLength, char);\n\n\tif (fields == NULL)\n\t\terror (FATAL, \"Cannot analyze tag file\");\n\telse\n\t{\n#define field(x)\t\t(fields + ((size_t) (x) * fieldLength))\n\n\t\tconst int numFields = sscanf (\n\t\t\tline, \"%[^\\t]%[\\t]%[^\\t]%[\\t]%[^\\r\\n]\",\n\t\t\tfield (TAG), field (TAB1), field (SRC_FILE),\n\t\t\tfield (TAB2), field (EXCMD));\n\n\t\t/*  There must be exactly five fields: two tab fields containing\n\t\t *  exactly one tab each, the tag must not begin with \"#\", and the\n\t\t *  file name should not end with \";\", and the excmd must be\n\t\t *  acceptable.\n\t\t *\n\t\t *  These conditions will reject tag-looking lines like:\n\t\t *      int a;        <C-comment>\n\t\t *      #define LABEL <C-comment>\n\t\t */\n\t\tif (numFields == NUM_FIELDS   &&\n\t\t\tstrlen (field (TAB1)) == 1  &&\n\t\t\tstrlen (field (TAB2)) == 1  &&\n\t\t\tfield (TAG) [0] != '#'      &&\n\t\t\tfield (SRC_FILE) [strlen (field (SRC_FILE)) - 1] != ';'  &&\n\t\t\tisValidTagAddress (field (EXCMD)))\n\t\t\t\tok = true;\n\n\t\teFree (fields);\n\t}\n\treturn ok;\n}\n\nstatic bool isEtagsLine (const char *const line)\n{\n\tbool result = false;\n\tif (line [0] == '\\f')\n\t\tresult = (bool) (line [1] == '\\n'  ||  line [1] == '\\r');\n\treturn result;\n}\n\nstatic bool isTagFile (const char *const filename)\n{\n\tbool ok = false;  /* we assume not unless confirmed */\n\tMIO *const mio = mio_new_file (filename, \"rb\");\n\n\tif (mio == NULL  &&  errno == ENOENT)\n\t\tok = true;\n\telse if (mio != NULL)\n\t{\n\t\tconst char *line = readLineRaw (TagFile.vLine, mio);\n\n\t\tif (line == NULL)\n\t\t\tok = true;\n\t\telse\n\t\t\tok = (bool) (isCtagsLine (line) || isEtagsLine (line));\n\t\tmio_unref (mio);\n\t}\n\treturn ok;\n}\n\nextern void openTagFile (void)\n{\n\tsetDefaultTagFileName ();\n\tTagsToStdout = isDestinationStdout ();\n\n\tif (TagFile.vLine == NULL)\n\t\tTagFile.vLine = vStringNew ();\n\n\t/*  Open the tags file.\n\t */\n\tif (TagsToStdout)\n\t{\n\t\tif (Option.interactive == INTERACTIVE_SANDBOX)\n\t\t{\n\t\t\tTagFile.mio = mio_new_memory (NULL, 0, eRealloc, eFreeNoNullCheck);\n\t\t\tTagFile.name = NULL;\n\t\t}\n\t\telse\n\t\t\tTagFile.mio = tempFile (\"w+\", &TagFile.name);\n\t\tif (isXtagEnabled (XTAG_PSEUDO_TAGS))\n\t\t\taddCommonPseudoTags ();\n\t}\n\telse\n\t{\n\t\tbool fileExists;\n\t\tbool directoryExists;\n\n\t\tTagFile.name = eStrdup (Option.tagFileName);\n\n\t\tdirectoryExists = doesDirectoryExist (TagFile.name);\n\t\tif (directoryExists)\n\t\t\terror (FATAL,\n\t\t\t\t   \"\\\"%s\\\" already exists as a directory; I cannot write tag entries there.\\n\"\n\t\t\t\t   \"Remove the directory or specify a file name with -o <tagfile> option.\",\n\t\t\t\t   TagFile.name);\n\n\t\tfileExists = doesFileExist (TagFile.name);\n\t\tif (fileExists  &&  ! isTagFile (TagFile.name))\n\t\t\terror (FATAL,\n\t\t\t  \"\\\"%s\\\" doesn't look like a tag file; I refuse to overwrite it.\",\n\t\t\t\t  TagFile.name);\n\n\t\tif (Option.etags)\n\t\t{\n\t\t\tif (Option.append  &&  fileExists)\n\t\t\t\tTagFile.mio = mio_new_file (TagFile.name, \"a+b\");\n\t\t\telse\n\t\t\t\tTagFile.mio = mio_new_file (TagFile.name, \"w+b\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (Option.append  &&  fileExists)\n\t\t\t{\n\t\t\t\tTagFile.mio = mio_new_file (TagFile.name, \"r+\");\n\t\t\t\tif (TagFile.mio != NULL)\n\t\t\t\t{\n\t\t\t\t\tTagFile.numTags.prev = updatePseudoTags (TagFile.mio);\n\t\t\t\t\tmio_unref (TagFile.mio);\n\t\t\t\t\tTagFile.mio = mio_new_file (TagFile.name, \"a+\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tTagFile.mio = mio_new_file (TagFile.name, \"w\");\n\t\t\t\tif (TagFile.mio != NULL && isXtagEnabled (XTAG_PSEUDO_TAGS))\n\t\t\t\t\taddCommonPseudoTags ();\n\t\t\t}\n\t\t}\n\t\tif (TagFile.mio == NULL)\n\t\t\terror (FATAL | PERROR, \"cannot open tag file\");\n\t}\n\n\tif (TagFile.directory == NULL)\n\t{\n\t\tif (TagsToStdout)\n\t\t\tTagFile.directory = eStrdup (CurrentDirectory);\n\t\telse\n\t\t\tTagFile.directory = absoluteDirname (TagFile.name);\n\t}\n}\n\n#ifdef USE_REPLACEMENT_TRUNCATE\n\nstatic void copyBytes (MIO* const fromMio, MIO* const toMio, const long size)\n{\n\tenum { BufferSize = 1000 };\n\tlong toRead, numRead;\n\tchar* buffer = xMalloc (BufferSize, char);\n\tlong remaining = size;\n\tdo\n\t{\n\t\ttoRead = (0 < remaining && remaining < BufferSize) ?\n\t\t\t\t\tremaining : (long) BufferSize;\n\t\tnumRead = mio_read (fromMio, buffer, (size_t) 1, (size_t) toRead);\n\t\tif (mio_write (toMio, buffer, (size_t)1, (size_t)numRead) < (size_t)numRead)\n\t\t\terror (FATAL | PERROR, \"cannot complete write\");\n\t\tif (remaining > 0)\n\t\t\tremaining -= numRead;\n\t} while (numRead == toRead  &&  remaining != 0);\n\teFree (buffer);\n}\n\nstatic void copyFile (const char *const from, const char *const to, const long size)\n{\n\tMIO* const fromMio = mio_new_file (from, \"rb\");\n\tif (fromMio == NULL)\n\t\terror (FATAL | PERROR, \"cannot open file to copy\");\n\telse\n\t{\n\t\tMIO* const toMio = mio_new_file (to, \"wb\");\n\t\tif (toMio == NULL)\n\t\t\terror (FATAL | PERROR, \"cannot open copy destination\");\n\t\telse\n\t\t{\n\t\t\tcopyBytes (fromMio, toMio, size);\n\t\t\tmio_unref (toMio);\n\t\t}\n\t\tmio_unref (fromMio);\n\t}\n}\n\n/*  Replacement for missing library function.\n */\nstatic int replacementTruncate (const char *const name, const long size)\n{\n#define WHOLE_FILE  -1L\n\tchar *tempName = NULL;\n\tMIO *mio = tempFile (\"w\", &tempName);\n\tmio_unref (mio);\n\tcopyFile (name, tempName, size);\n\tcopyFile (tempName, name, WHOLE_FILE);\n\tremove (tempName);\n\teFree (tempName);\n\n\treturn 0;\n}\n\n#endif\n\n#ifndef EXTERNAL_SORT\nstatic void internalSortTagFile (void)\n{\n\tMIO *mio;\n\n\t/*  Open/Prepare the tag file and place its lines into allocated buffers.\n\t */\n\tif (TagsToStdout)\n\t{\n\t\tmio = TagFile.mio;\n\t\tmio_seek (mio, 0, SEEK_SET);\n\t}\n\telse\n\t{\n\t\tmio = mio_new_file (tagFileName (), \"r\");\n\t\tif (mio == NULL)\n\t\t\tfailedSort (mio, NULL);\n\t}\n\n\tinternalSortTags (TagsToStdout,\n\t\t\t  mio,\n\t\t\t  TagFile.numTags.added + TagFile.numTags.prev);\n\n\tif (! TagsToStdout)\n\t\tmio_unref (mio);\n}\n#endif\n\nstatic void sortTagFile (void)\n{\n\tif (TagFile.numTags.added > 0L)\n\t{\n\t\tif (Option.sorted != SO_UNSORTED)\n\t\t{\n\t\t\tverbose (\"sorting tag file\\n\");\n#ifdef EXTERNAL_SORT\n\t\t\texternalSortTags (TagsToStdout, TagFile.mio);\n#else\n\t\t\tinternalSortTagFile ();\n#endif\n\t\t}\n\t\telse if (TagsToStdout)\n\t\t\tcatFile (TagFile.mio);\n\t}\n}\n\nstatic void resizeTagFile (const long newSize)\n{\n\tint result;\n\n\tif (!TagFile.name)\n\t{\n\t\tmio_try_resize (TagFile.mio, newSize);\n\t\treturn;\n\t}\n\n#ifdef USE_REPLACEMENT_TRUNCATE\n\tresult = replacementTruncate (TagFile.name, newSize);\n#else\n# ifdef HAVE_TRUNCATE\n\tresult = truncate (TagFile.name, (off_t) newSize);\n# else\n\tconst int fd = open (TagFile.name, O_RDWR);\n\n\tif (fd == -1)\n\t\tresult = -1;\n\telse\n\t{\n#  ifdef HAVE_FTRUNCATE\n\t\tresult = ftruncate (fd, (off_t) newSize);\n#  else\n#   ifdef HAVE_CHSIZE\n\t\tresult = chsize (fd, newSize);\n#   endif\n#  endif\n\t\tclose (fd);\n\t}\n# endif\n#endif\n\tif (result == -1)\n\t\terror (WARNING, \"Cannot shorten tag file: errno = %d\\n\", errno);\n}\n\nstatic void writeEtagsIncludes (MIO *const mio)\n{\n\tif (Option.etagsInclude)\n\t{\n\t\tunsigned int i;\n\t\tfor (i = 0  ;  i < stringListCount (Option.etagsInclude)  ;  ++i)\n\t\t{\n\t\t\tvString *item = stringListItem (Option.etagsInclude, i);\n\t\t\tmio_printf (mio, \"\\f\\n%s,include\\n\", vStringValue (item));\n\t\t}\n\t}\n}\n\nextern void closeTagFile (const bool resize)\n{\n\tlong desiredSize, size;\n\n\tif (Option.etags)\n\t\twriteEtagsIncludes (TagFile.mio);\n\tmio_flush (TagFile.mio);\n\n\tabort_if_ferror (TagFile.mio);\n\tdesiredSize = mio_tell (TagFile.mio);\n\tmio_seek (TagFile.mio, 0L, SEEK_END);\n\tsize = mio_tell (TagFile.mio);\n\tif (! TagsToStdout)\n\t\t/* The tag file should be closed before resizing. */\n\t\tif (mio_unref (TagFile.mio) != 0)\n\t\t\terror (FATAL | PERROR, \"cannot close tag file\");\n\n\tif (resize  &&  desiredSize < size)\n\t{\n\t\tDebugStatement (\n\t\t\tdebugPrintf (DEBUG_STATUS, \"shrinking %s from %ld to %ld bytes\\n\",\n\t\t\t\tTagFile.name? TagFile.name: \"<mio>\", size, desiredSize); )\n\t\tresizeTagFile (desiredSize);\n\t}\n\tsortTagFile ();\n\tif (TagsToStdout)\n\t{\n\t\tif (mio_unref (TagFile.mio) != 0)\n\t\t\terror (FATAL | PERROR, \"cannot close tag file\");\n\t\tif (TagFile.name)\n\t\t\tremove (TagFile.name);  /* remove temporary file */\n\t}\n\n\tTagFile.mio = NULL;\n\tif (TagFile.name)\n\t\teFree (TagFile.name);\n\tTagFile.name = NULL;\n}\n\n/*\n *  Tag entry management\n */\n\n/*  This function copies the current line out to a specified file. It has no\n *  effect on the fileGetc () function.  During copying, any '\\' characters\n *  are doubled and a leading '^' or trailing '$' is also quoted. End of line\n *  characters (line feed or carriage return) are dropped.\n */\nstatic size_t appendInputLine (int putc_func (char , void *), const char *const line,\n\t\t\t\t\t\t\t   unsigned int patternLengthLimit,\n\t\t\t\t\t\t\t   void * data, bool *omitted)\n{\n\tsize_t length = 0;\n\tconst char *p;\n\tint extraLength = 0;\n\n\t/*  Write everything up to, but not including, a line end character.\n\t */\n\t*omitted = false;\n\tfor (p = line  ;  *p != '\\0'  ;  ++p)\n\t{\n\t\tconst int next = *(p + 1);\n\t\tconst int c = *p;\n\n\t\tif (c == '\\r'  ||  c == '\\n')\n\t\t\tbreak;\n\n\t\tif (patternLengthLimit != 0 && length >= patternLengthLimit &&\n\t\t\t/* Do not cut inside a multi-byte UTF-8 character, but safe-guard it not to\n\t\t\t * allow more than one extra valid UTF-8 character in case it's not actually\n\t\t\t * UTF-8.  To do that, limit to an extra 3 UTF-8 sub-bytes (0b10xxxxxx). */\n\t\t\t((((unsigned char) c) & 0xc0) != 0x80 || ++extraLength > 3))\n\t\t{\n\t\t\t*omitted = true;\n\t\t\tbreak;\n\t\t}\n\t\t/*  If character is '\\', or a terminal '$', then quote it.\n\t\t */\n\t\tif (c == '\\\\'  ||  c == (Option.backward ? '?' : '/')  ||\n\t\t\t(c == '$'  &&  (next == '\\n'  ||  next == '\\r')))\n\t\t{\n\t\t\tputc_func ('\\\\', data);\n\t\t\t++length;\n\t\t}\n\t\tputc_func (c, data);\n\t\t++length;\n\t}\n\n\treturn length;\n}\n\nstatic int vstring_putc (char c, void *data)\n{\n\tvString *str = data;\n\tvStringPut (str, c);\n\treturn 1;\n}\n\nstatic int vstring_puts (const char* s, void *data)\n{\n\tvString *str = data;\n\tsize_t len = vStringLength (str);\n\tvStringCatS (str, s);\n\treturn (int) (vStringLength (str) - len);\n}\n\n#ifdef DEBUG\nstatic bool isPosSet (MIOPos pos)\n{\n\tchar * p = (char *)&pos;\n\tbool r = false;\n\tunsigned int i;\n\n\tfor (i = 0; i < sizeof(pos); i++)\n\t\tr |= p[i];\n\treturn r;\n}\n#endif\n\nextern char *readLineFromBypassForTag (vString *const vLine, const tagEntryInfo *const tag,\n\t\t\t\t\t\t\t\t\t   long *const pSeekValue)\n{\n\tAssert (isPosSet (tag->filePosition) || (tag->pattern == NULL));\n\treturn readLineFromBypass (vLine, tag->filePosition, pSeekValue);\n}\n\n/*  Truncates the text line containing the tag at the character following the\n *  tag, providing a character which designates the end of the tag.\n *  Returns the length of the truncated line (or 0 if it doesn't truncate).\n */\nextern size_t truncateTagLineAfterTag (\n\t\tchar *const line, const char *const token, const bool discardNewline)\n{\n\tsize_t len = 0;\n\tchar *p = strrstr (line, token);\n\n\tif (p != NULL)\n\t{\n\t\tp += strlen (token);\n\t\tif (*p != '\\0'  &&  ! (*p == '\\n'  &&  discardNewline))\n\t\t\t++p;    /* skip past character terminating character */\n\t\t*p = '\\0';\n\t\tlen = p - line;\n\t}\n\n\treturn len;\n}\n\nstatic char* getFullQualifiedScopeNameFromCorkQueue (const tagEntryInfo * inner_scope)\n{\n\n\tint kindIndex = KIND_GHOST_INDEX;\n\tlangType lang;\n\tconst tagEntryInfo *scope = inner_scope;\n\tconst tagEntryInfo *root_scope = NULL;\n\tstringList *queue = stringListNew ();\n\tvString *v;\n\tvString *n;\n\tunsigned int c;\n\tconst char *sep;\n\n\twhile (scope)\n\t{\n\t\tif (!scope->placeholder)\n\t\t{\n\t\t\tif (kindIndex != KIND_GHOST_INDEX)\n\t\t\t{\n\t\t\t\tsep = scopeSeparatorFor (lang, kindIndex, scope->kindIndex);\n\t\t\t\tv = vStringNewInit (sep);\n\t\t\t\tstringListAdd (queue, v);\n\t\t\t}\n\t\t\t/* TODO: scope field of SCOPE can be used for optimization. */\n\t\t\tv = vStringNewInit (scope->name);\n\t\t\tstringListAdd (queue, v);\n\t\t\tkindIndex = scope->kindIndex;\n\t\t\tlang = scope->langType;\n\t\t\troot_scope = scope;\n\t\t}\n\t\tint scopeIndex = scope->extensionFields.scopeIndex;\n\t\tscope =  getEntryInCorkQueue (scopeIndex);\n\n\t\tif (scope && scope->extensionFields.scopeIndex == scopeIndex)\n\t\t{\n\t\t\terror (WARNING,\n\t\t\t\t   \"interanl error: scope information made a loop structure: %s in %s:%lu\",\n\t\t\t\t   scope->name, scope->inputFileName, scope->lineNumber);\n\t\t\t/* Force break this while-loop. */\n\t\t\tscope = NULL;\n\t\t}\n\t}\n\n\tn = vStringNew ();\n\tsep = root_scope? scopeSeparatorFor (root_scope->langType, root_scope->kindIndex, KIND_GHOST_INDEX): NULL;\n\tif (sep)\n\t\tvStringCatS(n, sep);\n\n\twhile ((c = stringListCount (queue)) > 0)\n\t{\n\t\tv = stringListLast (queue);\n\t\tvStringCat (n, v);\n\t\tvStringDelete (v);\n\t\tstringListRemoveLast (queue);\n\t}\n\tstringListDelete (queue);\n\n\treturn vStringDeleteUnwrap (n);\n}\n\nextern void getTagScopeInformation (tagEntryInfo *const tag,\n\t\t\t\t\t\t\t\t\tconst char **kind, const char **name)\n{\n\tif (kind)\n\t\t*kind = NULL;\n\tif (name)\n\t\t*name = NULL;\n\n\tconst tagEntryInfo * scope = getEntryInCorkQueue (tag->extensionFields.scopeIndex);\n\tif (tag->extensionFields.scopeKindIndex == KIND_GHOST_INDEX\n\t\t&& tag->extensionFields.scopeName == NULL\n\t\t&& scope\n\t\t&& ptrArrayCount (TagFile.corkQueue) > 0)\n\t{\n\t\tchar *full_qualified_scope_name = getFullQualifiedScopeNameFromCorkQueue(scope);\n\t\tAssert (full_qualified_scope_name);\n\n\t\t/* Make the information reusable to generate full qualified entry, and xformat output*/\n\t\ttag->extensionFields.scopeLangType = scope->langType;\n\t\ttag->extensionFields.scopeKindIndex = scope->kindIndex;\n\t\ttag->extensionFields.scopeName = full_qualified_scope_name;\n\t}\n\n\tif (tag->extensionFields.scopeKindIndex != KIND_GHOST_INDEX  &&\n\t\ttag->extensionFields.scopeName != NULL)\n\t{\n\t\tif (kind)\n\t\t{\n\t\t\tlangType lang = (tag->extensionFields.scopeLangType == LANG_AUTO)\n\t\t\t\t? tag->langType\n\t\t\t\t: tag->extensionFields.scopeLangType;\n\t\t\tkindDefinition *kdef = getLanguageKind (lang,\n\t\t\t\t\t\t\t\t\t\t\t\t\ttag->extensionFields.scopeKindIndex);\n\t\t\t*kind = kdef->name;\n\t\t}\n\t\tif (name)\n\t\t\t*name = tag->extensionFields.scopeName;\n\t}\n}\n\n\nstatic int   makePatternStringCommon (const tagEntryInfo *const tag,\n\t\t\t\t\t\t\t\t\t  int (* putc_func) (char , void *),\n\t\t\t\t\t\t\t\t\t  int (* puts_func) (const char* , void *),\n\t\t\t\t\t\t\t\t\t  void *output)\n{\n\tint length = 0;\n\n\tchar *line;\n\tint searchChar;\n\tconst char *terminator;\n\tbool  omitted;\n\tsize_t line_len;\n\n\tbool making_cache = false;\n\tint (* puts_o_func)(const char* , void *);\n\tvoid * o_output;\n\n\tstatic vString *cached_pattern;\n\tstatic MIOPos   cached_location;\n\tif (TagFile.patternCacheValid\n\t\t&& (! tag->truncateLineAfterTag)\n\t\t&& (memcmp (&tag->filePosition, &cached_location, sizeof(MIOPos)) == 0))\n\t\treturn puts_func (vStringValue (cached_pattern), output);\n\n\tline = readLineFromBypassForTag (TagFile.vLine, tag, NULL);\n\tif (line == NULL)\n\t{\n\t\t/* This can be occurs if the size of input file is zero, and\n\t\t   an empty regex pattern (//) matches to the input. */\n\t\tline = \"\";\n\t\tline_len = 0;\n\t}\n\telse\n\t\tline_len = vStringLength (TagFile.vLine);\n\n\tif (tag->truncateLineAfterTag)\n\t{\n\t\tsize_t truncted_len;\n\n\t\ttruncted_len = truncateTagLineAfterTag (line, tag->name, false);\n\t\tif (truncted_len > 0)\n\t\t\tline_len = truncted_len;\n\t}\n\n\tsearchChar = Option.backward ? '?' : '/';\n\tterminator = (line_len > 0 && (line [line_len - 1] == '\\n')) ? \"$\": \"\";\n\n\tif (!tag->truncateLineAfterTag)\n\t{\n\t\tmaking_cache = true;\n\t\tcached_pattern = vStringNewOrClearWithAutoRelease (cached_pattern);\n\n\t\tputs_o_func = puts_func;\n\t\to_output    = output;\n\t\tputc_func   = vstring_putc;\n\t\tputs_func   = vstring_puts;\n\t\toutput      = cached_pattern;\n\t}\n\n\tlength += putc_func(searchChar, output);\n\tif ((tag->boundaryInfo & AREA_BOUNDARY_START) == 0)\n\t\tlength += putc_func('^', output);\n\tlength += appendInputLine (putc_func, line, Option.patternLengthLimit,\n\t\t\t\t\t\t\t   output, &omitted);\n\tlength += puts_func (omitted? \"\": terminator, output);\n\tlength += putc_func (searchChar, output);\n\n\tif (making_cache)\n\t{\n\t\tputs_o_func (vStringValue (cached_pattern), o_output);\n\t\tcached_location = tag->filePosition;\n\t\tTagFile.patternCacheValid = true;\n\t}\n\n\treturn length;\n}\n\nextern char* makePatternString (const tagEntryInfo *const tag)\n{\n\tvString* pattern = vStringNew ();\n\tmakePatternStringCommon (tag, vstring_putc, vstring_puts, pattern);\n\treturn vStringDeleteUnwrap (pattern);\n}\n\nstatic tagField* tagFieldNew (fieldType ftype, const char *value, bool valueOwner)\n{\n\ttagField *f = xMalloc (1, tagField);\n\n\tf->ftype = ftype;\n\tf->value = value;\n\tf->valueOwner = valueOwner;\n\treturn f;\n}\n\nstatic void tagFieldDelete (tagField * f)\n{\n\tif (f->valueOwner)\n\t\teFree((void *)f->value);\n\teFree (f);\n}\n\nstatic void attachParserFieldGeneric (tagEntryInfo *const tag, fieldType ftype, const char * value,\n\t\t\t\t\t\t\t\t\t  bool valueOwner)\n{\n\tif (tag->usedParserFields < PRE_ALLOCATED_PARSER_FIELDS)\n\t{\n\t\ttag->parserFields [tag->usedParserFields].ftype = ftype;\n\t\ttag->parserFields [tag->usedParserFields].value = value;\n\t\ttag->parserFields [tag->usedParserFields].valueOwner = valueOwner;\n\t\ttag->usedParserFields++;\n\t}\n\telse if (tag->parserFieldsDynamic == NULL)\n\t{\n\t\ttag->parserFieldsDynamic = ptrArrayNew((ptrArrayDeleteFunc)tagFieldDelete);\n\t\tPARSER_TRASH_BOX(tag->parserFieldsDynamic, ptrArrayDelete);\n\t\tattachParserFieldGeneric (tag, ftype, value, valueOwner);\n\t}\n\telse\n\t{\n\t\ttagField *f = tagFieldNew (ftype, value, valueOwner);\n\t\tptrArrayAdd(tag->parserFieldsDynamic, f);\n\t\ttag->usedParserFields++;\n\t}\n}\n\nextern void attachParserField (tagEntryInfo *const tag, fieldType ftype, const char * value)\n{\n\tAssert (tag != NULL);\n\n\tif (tag->inCorkQueue)\n\t{\n\t\tconst char * v;\n\t\tv = eStrdup (value);\n\n\t\tbool dynfields_allocated = tag->parserFieldsDynamic? true: false;\n\t\tattachParserFieldGeneric (tag, ftype, v, true);\n\t\tif (!dynfields_allocated && tag->parserFieldsDynamic)\n\t\t\tPARSER_TRASH_BOX_TAKE_BACK(tag->parserFieldsDynamic);\n\t}\n\telse\n\t\tattachParserFieldGeneric (tag, ftype, value, false);\n}\n\nextern void attachParserFieldToCorkEntry (int index,\n\t\t\t\t\t fieldType ftype,\n\t\t\t\t\t const char *value)\n{\n\ttagEntryInfo * tag = getEntryInCorkQueue (index);\n\tif (tag)\n\t\tattachParserField (tag, ftype, value);\n}\n\nextern const tagField* getParserFieldForIndex (const tagEntryInfo * tag, int index)\n{\n\tif (index < 0\n\t\t|| tag->usedParserFields <= ((unsigned int)index) )\n\t\treturn NULL;\n\telse if (index < PRE_ALLOCATED_PARSER_FIELDS)\n\t\treturn tag->parserFields + index;\n\telse\n\t{\n\t\tunsigned int n = index - PRE_ALLOCATED_PARSER_FIELDS;\n\t\treturn ptrArrayItem(tag->parserFieldsDynamic, n);\n\t}\n}\n\nextern const char* getParserFieldValueForType (const tagEntryInfo *const tag, fieldType ftype)\n{\n\tfor (unsigned int i = 0; i < tag->usedParserFields; i++)\n\t{\n\t\tconst tagField *f = getParserFieldForIndex (tag, (int)i);\n\t\tif (f && f->ftype == ftype)\n\t\t\treturn f->value;\n\t}\n\treturn NULL;\n}\n\nstatic void copyParserFields (const tagEntryInfo *const tag, tagEntryInfo* slot)\n{\n\tunsigned int i;\n\tconst char* value;\n\n\tfor (i = 0; i < tag->usedParserFields; i++)\n\t{\n\t\tconst tagField *f = getParserFieldForIndex (tag, i);\n\t\tAssert(f);\n\n\t\tvalue = f->value;\n\t\tif (value)\n\t\t\tvalue = eStrdup (value);\n\n\t\tattachParserFieldGeneric (slot,\n\t\t\t\t\t\t\t\t  f->ftype,\n\t\t\t\t\t\t\t\t  value,\n\t\t\t\t\t\t\t\t  true);\n\t}\n\n}\n\nstatic tagEntryInfo *newNilTagEntry (unsigned int corkFlags)\n{\n\ttagEntryInfoX *x = xCalloc (1, tagEntryInfoX);\n\tx->corkIndex = CORK_NIL;\n\tx->symtab = RB_ROOT;\n\tx->slot.kindIndex = KIND_FILE_INDEX;\n\tx->slot.inputFileName = getInputFileName ();\n\tx->slot.inputFileName = eStrdup (x->slot.inputFileName);\n\tx->slot.sourceFileName = getSourceFileTagPath();\n\tif (x->slot.sourceFileName)\n\t\tx->slot.sourceFileName = eStrdup (x->slot.sourceFileName);\n\treturn &(x->slot);\n}\n\nstatic void copyExtraDynamic (const tagEntryInfo *const src, tagEntryInfo *const dst)\n{\n\tif (dst->extraDynamic)\n\t{\n\t\tunsigned int n = countXtags () - XTAG_COUNT;\n\t\tdst->extraDynamic = xCalloc ((n / 8) + 1, uint8_t);\n\t\tmemcpy (dst->extraDynamic, src->extraDynamic, (n / 8) + 1);\n\t\tPARSER_TRASH_BOX(dst->extraDynamic, eFree);\n\t}\n}\n\nstatic tagEntryInfoX *copyTagEntry (const tagEntryInfo *const tag,\n\t\t\t\t\t\t\t\t\tconst char *shareInputFileName,\n\t\t\t\t\t\t\t\t\tconst char *sharedSourceFileName,\n\t\t\t\t\t\t\t\t\tunsigned int corkFlags)\n{\n\ttagEntryInfoX *x = xMalloc (1, tagEntryInfoX);\n\tx->symtab = RB_ROOT;\n\tx->corkIndex = CORK_NIL;\n\tmemset(&x->intervalnode, 0, sizeof (x->intervalnode));\n\tx->__intervalnode_subtree_last = 0;\n\ttagEntryInfo *slot = (tagEntryInfo *)x;\n\n\t*slot = *tag;\n\n\tif (slot->pattern)\n\t\tslot->pattern = eStrdup (slot->pattern);\n\n\tif (slot->inputFileName == getInputFileName ())\n\t{\n\t\tslot->inputFileName = shareInputFileName;\n\t\tslot->isInputFileNameShared = 1;\n\t}\n\telse\n\t{\n\t\tslot->inputFileName = eStrdup (slot->inputFileName);\n\t\tslot->isInputFileNameShared = 0;\n\t}\n\n\tslot->name = eStrdup (slot->name);\n\tif (slot->extensionFields.access)\n\t\tslot->extensionFields.access = eStrdup (slot->extensionFields.access);\n\tif (slot->extensionFields.implementation)\n\t\tslot->extensionFields.implementation = eStrdup (slot->extensionFields.implementation);\n\tif (slot->extensionFields.inheritance)\n\t\tslot->extensionFields.inheritance = eStrdup (slot->extensionFields.inheritance);\n\tif (slot->extensionFields.scopeName)\n\t\tslot->extensionFields.scopeName = eStrdup (slot->extensionFields.scopeName);\n\tif (slot->extensionFields.signature)\n\t\tslot->extensionFields.signature = eStrdup (slot->extensionFields.signature);\n\tif (slot->extensionFields.typeRef[0])\n\t\tslot->extensionFields.typeRef[0] = eStrdup (slot->extensionFields.typeRef[0]);\n\tif (slot->extensionFields.typeRef[1])\n\t\tslot->extensionFields.typeRef[1] = eStrdup (slot->extensionFields.typeRef[1]);\n#ifdef HAVE_LIBXML\n\tif (slot->extensionFields.xpath)\n\t\tslot->extensionFields.xpath = eStrdup (slot->extensionFields.xpath);\n#endif\n\n\tcopyExtraDynamic (tag, slot);\n\tif (slot->extraDynamic)\n\t\tPARSER_TRASH_BOX_TAKE_BACK(slot->extraDynamic);\n\n\tif (slot->sourceFileName == NULL)\n\t\tslot->isSourceFileNameShared = 0;\n\telse if (strcmp(slot->sourceFileName, sharedSourceFileName) == 0)\n\t{\n\t\t/* strcmp() is needed here.\n\t\t * sharedSourceFileName can be changed during parsing a file.\n\t\t * So we cannot use the condition like:\n\t\t *\n\t\t *    if (slot->sourceFileName == getSourceFileTagPath()) { ... }\n\t\t *\n\t\t */\n\t\tslot->sourceFileName = sharedSourceFileName;\n\t\tslot->isSourceFileNameShared = 1;\n\t}\n\telse\n\t{\n\t\tslot->sourceFileName = eStrdup (slot->sourceFileName);\n\t\tslot->isSourceFileNameShared = 0;\n\t}\n\n\tslot->usedParserFields = 0;\n\tslot->parserFieldsDynamic = NULL;\n\tcopyParserFields (tag, slot);\n\tif (slot->parserFieldsDynamic)\n\t\tPARSER_TRASH_BOX_TAKE_BACK(slot->parserFieldsDynamic);\n\n\treturn x;\n}\n\nstatic void clearParserFields (tagEntryInfo *const tag)\n{\n\tunsigned int i, n;\n\tconst char* value;\n\n\tif ( tag->usedParserFields < PRE_ALLOCATED_PARSER_FIELDS )\n\t\tn = tag->usedParserFields;\n\telse\n\t\tn = PRE_ALLOCATED_PARSER_FIELDS;\n\n\tfor (i = 0; i < n; i++)\n\t{\n\t\tvalue = tag->parserFields[i].value;\n\t\tif (value && tag->parserFields[i].valueOwner)\n\t\t\teFree ((char *)value);\n\t\ttag->parserFields[i].value = NULL;\n\t\ttag->parserFields[i].ftype = FIELD_UNKNOWN;\n\t}\n\tif (tag->parserFieldsDynamic)\n\t{\n\t\tptrArrayDelete (tag->parserFieldsDynamic);\n\t\ttag->parserFieldsDynamic = NULL;\n\t}\n}\n\nstatic void deleteTagEnry (void *data)\n{\n\ttagEntryInfo *slot = data;\n\n\tif (slot->kindIndex == KIND_FILE_INDEX)\n\t{\n\t\teFree ((char *)slot->inputFileName);\n\t\tif (slot->sourceFileName)\n\t\t\teFree ((char *)slot->sourceFileName);\n\t\tgoto out;\n\t}\n\n\tif (slot->pattern)\n\t\teFree ((char *)slot->pattern);\n\n\tif (!slot->isInputFileNameShared)\n\t\teFree ((char *)slot->inputFileName);\n\n\teFree ((char *)slot->name);\n\n\tif (slot->extensionFields.access)\n\t\teFree ((char *)slot->extensionFields.access);\n\tif (slot->extensionFields.implementation)\n\t\teFree ((char *)slot->extensionFields.implementation);\n\tif (slot->extensionFields.inheritance)\n\t\teFree ((char *)slot->extensionFields.inheritance);\n\tif (slot->extensionFields.scopeName)\n\t\teFree ((char *)slot->extensionFields.scopeName);\n\tif (slot->extensionFields.signature)\n\t\teFree ((char *)slot->extensionFields.signature);\n\tif (slot->extensionFields.typeRef[0])\n\t\teFree ((char *)slot->extensionFields.typeRef[0]);\n\tif (slot->extensionFields.typeRef[1])\n\t\teFree ((char *)slot->extensionFields.typeRef[1]);\n#ifdef HAVE_LIBXML\n\tif (slot->extensionFields.xpath)\n\t\teFree ((char *)slot->extensionFields.xpath);\n#endif\n\n\tif (slot->extraDynamic)\n\t\teFree (slot->extraDynamic);\n\n\tif (slot->sourceFileName && !slot->isSourceFileNameShared)\n\t\teFree ((char *)slot->sourceFileName);\n\n\tclearParserFields (slot);\n\n out:\n\teFree (slot);\n}\n\nstatic void corkSymtabPut (tagEntryInfoX *scope, const char* name, tagEntryInfoX *item)\n{\n\tstruct rb_root *root = &scope->symtab;\n\n\tstruct rb_node **new = &(root->rb_node), *parent = NULL;\n\n\twhile (*new)\n\t{\n\t\ttagEntryInfoX *this = container_of(*new, tagEntryInfoX, symnode);\n\t\tint result = strcmp(item->slot.name, this->slot.name);\n\n\t\tparent = *new;\n\n\t\tif (result < 0)\n\t\t\tnew = &((*new)->rb_left);\n\t\telse if (result > 0)\n\t\t\tnew = &((*new)->rb_right);\n\t\telse\n\t\t{\n\t\t\tunsigned long lthis = this->slot.lineNumber;\n\t\t\tunsigned long litem = item->slot.lineNumber;\n\n\t\t\t/* Comparing lineNumber */\n\t\t\tif (litem < lthis)\n\t\t\t\tnew = &((*new)->rb_left);\n\t\t\telse if (litem > lthis)\n\t\t\t\tnew = &((*new)->rb_right);\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* Comparing memory address */\n\t\t\t\tif (item < this)\n\t\t\t\t\tnew = &((*new)->rb_left);\n\t\t\t\telse if (item > this)\n\t\t\t\t\tnew = &((*new)->rb_right);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tAssertNotReached(); /* registering the same object twice. */\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tverbose (\"symtbl[:=] %s<-%s/%p (line: %lu)\\n\",\n\t\t\t*new? container_of(*new, tagEntryInfoX, symnode)->slot.name: \"*root*\",\n\t\t\t item->slot.name, &item->slot, item->slot.lineNumber);\n\t/* Add new node and rebalance tree. */\n\trb_link_node(&item->symnode, parent, new);\n\trb_insert_color(&item->symnode, root);\n}\n\nstatic void corkSymtabUnlink (tagEntryInfoX *scope, tagEntryInfoX *item)\n{\n\tstruct rb_root *root = &scope->symtab;\n\trb_erase (&item->symnode, root);\n}\n\nextern bool foreachEntriesInScope (int corkIndex,\n\t\t\t\t\t\t\t\t   const char *name,\n\t\t\t\t\t\t\t\t   entryForeachFunc func,\n\t\t\t\t\t\t\t\t   void *data)\n{\n\ttagEntryInfoX *x = ptrArrayItem (TagFile.corkQueue, corkIndex);\n\n\tstruct rb_root *root = &x->symtab;\n\ttagEntryInfoX *rep = NULL;\n\n\t/* More than one tag can have a same name.\n\t * Visit them from the last.\n\t *\n\t * 1. find one of them as the representative,\n\t * 2. find the last one of them from the representative with rb_next,\n\t * 3. call FUNC iteratively from the last to the first.\n\t */\n\tif (name)\n\t{\n\t\tstruct rb_node *node = root->rb_node;\n\t\twhile (node)\n\t\t{\n\t\t\ttagEntryInfoX *entry = container_of(node, tagEntryInfoX, symnode);\n\t\t\tint result;\n\n\t\t\tresult = strcmp(name, entry->slot.name);\n\n\t\t\tif (result < 0)\n\t\t\t\tnode = node->rb_left;\n\t\t\telse if (result > 0)\n\t\t\t\tnode = node->rb_right;\n\t\t\telse\n\t\t\t{\n\t\t\t\trep = entry;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (rep == NULL)\n\t\t\treturn true;\n\n\t\tverbose(\"symtbl[<>] %s->%p\\n\", name, &rep->slot);\n\t}\n\n\tstruct rb_node *last;\n\n\tif (name)\n\t{\n\t\tstruct rb_node *tmp = &rep->symnode;\n\t\tlast = tmp;\n\n\t\twhile ((tmp = rb_next (tmp)))\n\t\t{\n\t\t\ttagEntryInfoX *entry = container_of(tmp, tagEntryInfoX, symnode);\n\t\t\tif (strcmp(name, entry->slot.name) == 0)\n\t\t\t{\n\t\t\t\tverbose (\"symtbl[ >] %s->%p\\n\", name, &container_of(tmp, tagEntryInfoX, symnode)->slot);\n\t\t\t\tlast = tmp;\n\t\t\t}\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t}\n\telse\n\t{\n\t\tlast = rb_last(root);\n\t\tverbose (\"last for %d<%p>: %p\\n\", corkIndex, root, last);\n\t}\n\n\tif (!last)\n\t{\n\t\tverbose (\"symtbl[>V] %s->%p\\n\", name? name: \"(null)\", NULL);\n\t\treturn true;\t\t\t/* Nothing here in this node. */\n\t}\n\n\tverbose (\"symtbl[>|] %s->%p\\n\", name, &container_of(last, tagEntryInfoX, symnode)->slot);\n\n\tstruct rb_node *cursor = last;\n\tbool revisited_rep = false;\n\tdo\n\t{\n\t\ttagEntryInfoX *entry = container_of(cursor, tagEntryInfoX, symnode);\n\t\tif (!revisited_rep || !name || !strcmp(name, entry->slot.name))\n\t\t{\n\t\t\tverbose (\"symtbl[< ] %s->%p\\n\", name, &entry->slot);\n\t\t\tif (!func (entry->corkIndex, &entry->slot, data))\n\t\t\t\treturn false;\n\t\t\tif (cursor == &rep->symnode)\n\t\t\t\trevisited_rep = true;\n\t\t}\n\t\telse if (name)\n\t\t\tbreak;\n\t}\n\twhile ((cursor = rb_prev(cursor)));\n\n\treturn true;\n}\n\nstruct countData {\n\tbool onlyDefinitionTag;\n\tunsigned int count;\n\tentryForeachFunc func;\n\tvoid *cbData;\n};\n\nstatic bool countEntryMaybe (int corkIndex, tagEntryInfo *entry, void *cbData)\n{\n\tstruct countData *data = cbData;\n\tif (data->onlyDefinitionTag\n\t\t&& !isRoleAssigned (entry, ROLE_DEFINITION_INDEX))\n\t\treturn true;\n\n\tif (data->func == NULL\n\t\t|| data->func (corkIndex, entry, data->cbData))\n\t\tdata->count++;\n\treturn true;\n}\n\nunsigned int countEntriesInScope (int corkIndex, bool onlyDefinitionTag,\n\t\t\t\t\t\t\t\t  entryForeachFunc func, void *cbData)\n{\n\tstruct countData data = {\n\t\t.onlyDefinitionTag = onlyDefinitionTag,\n\t\t.count = 0,\n\t\t.func = func,\n\t\t.cbData = cbData,\n\t};\n\n\tforeachEntriesInScope (corkIndex, NULL,\n\t\t\t\t\t\t   &countEntryMaybe,\n\t\t\t\t\t\t   &data);\n\n\treturn data.count;\n}\n\nstruct anyEntryInScopeData {\n\tint index;\n\tbool onlyDefinitionTag;\n};\n\nstatic bool findName (int corkIndex, tagEntryInfo *entry, void *cbData)\n{\n\tstruct anyEntryInScopeData *data = cbData;\n\n\tif (data->onlyDefinitionTag && !isRoleAssigned (entry, ROLE_DEFINITION_INDEX))\n\t\treturn true;\n\n\tdata->index = corkIndex;\n\treturn false;\n}\n\nint anyEntryInScope (int corkIndex, const char *name, bool onlyDefinitionTag)\n{\n\tstruct anyEntryInScopeData data = {\n\t\t.index = CORK_NIL,\n\t\t.onlyDefinitionTag = onlyDefinitionTag,\n\t};\n\n\tif (foreachEntriesInScope (corkIndex, name, findName, &data) == false)\n\t\treturn data.index;\n\n\treturn CORK_NIL;\n}\n\nstruct anyKindsEntryInScopeData {\n\tint  index;\n\tconst int *kinds;\n\tint  count;\n\tbool onlyDefinitionTag;\n};\n\nstatic bool findNameOfKinds (int corkIndex, tagEntryInfo *entry, void *data)\n{\n\tstruct anyKindsEntryInScopeData * kdata = data;\n\n\tfor (int i = 0; i < kdata->count; i++)\n\t{\n\t\tint k = kdata->kinds [i];\n\t\tif (entry->kindIndex == k\n\t\t\t&& ((!kdata->onlyDefinitionTag)\n\t\t\t\t|| isRoleAssigned (entry, ROLE_DEFINITION_INDEX)))\n\t\t{\n\t\t\tkdata->index = corkIndex;\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nint anyKindEntryInScope (int corkIndex,\n\t\t\t\t\t\t const char *name, int kind,\n\t\t\t\t\t\t bool onlyDefinitionTag)\n{\n\treturn anyKindsEntryInScope (corkIndex, name, &kind, 1, onlyDefinitionTag);\n}\n\nint anyKindsEntryInScope (int corkIndex,\n\t\t\t\t\t\t  const char *name,\n\t\t\t\t\t\t  const int *kinds, int count,\n\t\t\t\t\t\t  bool onlyDefinitionTag)\n{\n\tstruct anyKindsEntryInScopeData data = {\n\t\t.index = CORK_NIL,\n\t\t.kinds = kinds,\n\t\t.count = count,\n\t\t.onlyDefinitionTag = onlyDefinitionTag,\n\t};\n\n\tif (foreachEntriesInScope (corkIndex, name, findNameOfKinds, &data) == false)\n\t\treturn data.index;\n\n\treturn CORK_NIL;\n}\n\nint anyKindsEntryInScopeRecursive (int corkIndex,\n\t\t\t\t\t\t\t\t   const char *name,\n\t\t\t\t\t\t\t\t   const int *kinds, int count,\n\t\t\t\t\t\t\t\t   bool onlyDefinitionTag)\n{\n\tstruct anyKindsEntryInScopeData data = {\n\t\t.index = CORK_NIL,\n\t\t.kinds = kinds,\n\t\t.count = count,\n\t\t.onlyDefinitionTag = onlyDefinitionTag,\n\t};\n\n\ttagEntryInfo *e;\n\tdo\n\t{\n\t\tif (foreachEntriesInScope (corkIndex, name, findNameOfKinds, &data) == false)\n\t\t\treturn data.index;\n\n\t\tif (corkIndex == CORK_NIL)\n\t\t\tbreak;\n\n\t\te = getEntryInCorkQueue (corkIndex);\n\t\tif (!e)\n\t\t\tbreak;\n\t\tcorkIndex = e->extensionFields.scopeIndex;\n\t}\n\twhile (1);\n\n\treturn CORK_NIL;\n}\n\nextern void registerEntry (int corkIndex)\n{\n\tAssert (TagFile.corkFlags & CORK_SYMTAB);\n\tAssert (corkIndex != CORK_NIL);\n\n\ttagEntryInfoX *e = ptrArrayItem (TagFile.corkQueue, corkIndex);\n\t{\n\t\ttagEntryInfoX *scope = ptrArrayItem (TagFile.corkQueue, e->slot.extensionFields.scopeIndex);\n\t\tcorkSymtabPut (scope, e->slot.name, e);\n\t}\n}\n\nextern void unregisterEntry (int corkIndex)\n{\n\tAssert (TagFile.corkFlags & CORK_SYMTAB);\n\tAssert (corkIndex != CORK_NIL);\n\n\ttagEntryInfoX *e = ptrArrayItem (TagFile.corkQueue, corkIndex);\n\t{\n\t\ttagEntryInfoX *scope = ptrArrayItem (TagFile.corkQueue, e->slot.extensionFields.scopeIndex);\n\t\tcorkSymtabUnlink (scope, e);\n\t}\n\n}\n\nstatic int queueTagEntry (const tagEntryInfo *const tag)\n{\n\tstatic bool warned;\n\n\tint corkIndex;\n\ttagEntryInfo * nil = ptrArrayItem (TagFile.corkQueue, 0);\n\ttagEntryInfoX * entry = copyTagEntry (tag, nil->inputFileName, nil->sourceFileName,\n\t\t\t\t\t\t\t\t\t\tTagFile.corkFlags);\n\n\tif (ptrArrayCount (TagFile.corkQueue) == (size_t)INT_MAX)\n\t{\n\t\tif (!warned)\n\t\t{\n\t\t\twarned = true;\n\t\t\terror (WARNING,\n\t\t\t\t   \"The tag entry queue overflows; drop the tag entry at %lu in %s\",\n\t\t\t\t   tag->lineNumber,\n\t\t\t\t   tag->inputFileName);\n\t\t}\n\t\treturn CORK_NIL;\n\t}\n\twarned = false;\n\n\tcorkIndex = (int)ptrArrayAdd (TagFile.corkQueue, entry);\n\tentry->corkIndex = corkIndex;\n\tentry->slot.inCorkQueue = 1;\n\n\t/* Don't put FQ tags to interval table.\n\t * About placeholder, a parser should call\n\t * removeFromIntervalTabMaybe() explicitly.\n\t */\n\tif (! isTagExtraBitMarked (&entry->slot, XTAG_FILE_NAMES)\n\t\t&& getTagEndLine (&entry->slot) > entry->slot.lineNumber\n\t\t&& !isTagExtraBitMarked (tag, XTAG_QUALIFIED_TAGS))\n\t{\n\t\tintervaltab_insert(entry, &TagFile.intervaltab);\n\t\tentry->slot.inIntevalTab = 1;\n\t}\n\treturn corkIndex;\n}\n\nextern void updateTagLine (tagEntryInfo *tag, unsigned long lineNumber,\n\t\t\t\t\t\t   MIOPos filePosition)\n{\n\ttagEntryInfoX *entry = NULL;\n\tif (tag->inIntevalTab)\n\t{\n\t\tentry = (tagEntryInfoX *)tag;\n\t\tremoveFromIntervalTabMaybe (entry->corkIndex);\n\t}\n\n\ttag->lineNumber = lineNumber;\n\ttag->filePosition = filePosition;\n\ttag->boundaryInfo = getAreaBoundaryInfo (lineNumber);\n\n\tif (entry && tag->lineNumber < getTagEndLine (tag))\n\t{\n\t\tintervaltab_insert(entry, &TagFile.intervaltab);\n\t\ttag->inIntevalTab = 1;\n\t}\n}\n\nextern void setTagEndLine(tagEntryInfo *tag, unsigned long endLine)\n{\n\tif (endLine != 0 && endLine < tag->lineNumber)\n\t{\n\t\terror (WARNING,\n\t\t\t   \"given end line (%lu) for the tag (%s) in the file (%s) is smaller than its start line: %lu\",\n\t\t\t   endLine,\n\t\t\t   tag->name,\n\t\t\t   tag->inputFileName,\n\t\t\t   tag->lineNumber);\n#if 0\n\t\tAssert ((endLine == 0 || endLine >= tag->lineNumber));\n\t\t/*\n\t\t * If we enable this assertion, (option based) user parsers can\n\t\t * crash. No user wants this behavior even if the one pass\n\t\t * --enable-debuggng to configre when building; jut warning\n\t\t * is enough.\n\t\t *\n\t\t * Till implementing the way to detect whether a builtin parser\n\t\t * calls this setTagEndLine() or a user parser callit, we canot\n\t\t * enable this assertion. The assertion should be enabled for\n\t\t * builtin parsers.\n\t\t */\n#endif\n\t\treturn;\n\t}\n\n\tif (isTagExtraBitMarked (tag, XTAG_FILE_NAMES)\n\t\t|| !tag->inCorkQueue\n\t\t|| isTagExtraBitMarked (tag, XTAG_QUALIFIED_TAGS))\n\t{\n\t\ttag->extensionFields._endLine = endLine;\n\t\treturn;\n\t}\n\n\ttagEntryInfoX *entry = (tagEntryInfoX *)tag;\n\n\tif (tag->inIntevalTab)\n\t\tremoveFromIntervalTabMaybe (entry->corkIndex);\n\n\ttag->extensionFields._endLine = endLine;\n\tif (endLine > tag->lineNumber)\n\t{\n\t\tintervaltab_insert(entry, &TagFile.intervaltab);\n\t\ttag->inIntevalTab = 1;\n\t}\n}\n\nextern void setTagEndLineToCorkEntry (int corkIndex, unsigned long endLine)\n{\n\ttagEntryInfo *entry = getEntryInCorkQueue (corkIndex);\n\tif (entry)\n\t\tsetTagEndLine (entry, endLine);\n}\n\nextern void setupWriter (void *writerClientData)\n{\n\twriterSetup (TagFile.mio, writerClientData);\n}\n\nextern bool teardownWriter (const char *filename)\n{\n\treturn writerTeardown (TagFile.mio, filename);\n}\n\nstatic bool isTagWritable (const tagEntryInfo *const tag)\n{\n\tif (tag->placeholder)\n\t\treturn false;\n\n\tif (! isLanguageEnabled(tag->langType) )\n\t\treturn false;\n\n\tif (! isLanguageKindEnabled(tag->langType, tag->kindIndex))\n\t\treturn false;\n\n\tif (tag->extensionFields.roleBits)\n\t{\n\t\tsize_t available_roles;\n\n\t\tif (!isXtagEnabled (XTAG_REFERENCE_TAGS))\n\t\t\treturn false;\n\n\t\tavailable_roles = countLanguageRoles(tag->langType,\n\t\t\t\t\t\t\t\t\t\t\t tag->kindIndex);\n\t\tif (tag->extensionFields.roleBits >=\n\t\t\t(makeRoleBit(available_roles)))\n\t\t\treturn false;\n\n\t\t/* TODO: optimization\n\t\t   A Bitmasks representing all enabled roles can be calculated at the\n\t\t   end of initializing the parser. Calculating each time when checking\n\t\t   a tag entry is not needed. */\n\t\tfor (unsigned int roleIndex = 0; roleIndex < available_roles; roleIndex++)\n\t\t{\n\t\t\tif (isRoleAssigned(tag, roleIndex))\n\t\t\t{\n\t\t\t\tif (isLanguageRoleEnabled (tag->langType, tag->kindIndex,\n\t\t\t\t\t\t\t\t\t\t\t roleIndex))\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t}\n\t\treturn false;\n\t}\n\telse if (isLanguageKindRefOnly(tag->langType, tag->kindIndex))\n\t{\n\t\terror (WARNING, \"PARSER BUG: a definition tag for a refonly kind(%s.%s) of is made: %s found in %s.\",\n\t\t\t   getLanguageName(tag->langType),\n\t\t\t   getLanguageKind(tag->langType, tag->kindIndex)->name,\n\t\t\t   tag->name, tag->inputFileName);\n\t\t/* This one is not so critical. */\n\t}\n\n\tif (!isXtagEnabled(XTAG_ANONYMOUS)\n\t\t&& isTagExtraBitMarked(tag, XTAG_ANONYMOUS))\n\t\treturn false;\n\n\treturn true;\n}\n\nstatic void buildFqTagCache (tagEntryInfo *const tag)\n{\n\tgetTagScopeInformation (tag, NULL, NULL);\n}\n\nstatic void writeTagEntry (tagEntryInfo *const tag)\n{\n\tint length = 0;\n\n\tAssert (tag->kindIndex != KIND_GHOST_INDEX);\n\n\tDebugStatement ( debugEntry (tag); )\n\n\tif (isTagExtraBitMarked(tag, XTAG_NULLTAG))\n\t{\n\t\tif (!writerCanPrintNullTag())\n\t\t\treturn;\n\n\t\tif (!isXtagEnabled(XTAG_NULLTAG))\n\t\t\treturn;\n\t}\n\n#ifdef _WIN32\n\tif (getFilenameSeparator(Option.useSlashAsFilenameSeparator) == FILENAME_SEP_USE_SLASH)\n\t{\n\t\tAssert (tag->inputFileName);\n\t\tchar *c = (char *)(tag->inputFileName);\n\t\twhile (*c)\n\t\t{\n\t\t\tif (*c == PATH_SEPARATOR)\n\t\t\t\t*c = OUTPUT_PATH_SEPARATOR;\n\t\t\tc++;\n\t\t}\n\t}\n#endif\n\n\tif (includeExtensionFlags ()\n\t\t&& isXtagEnabled (XTAG_QUALIFIED_TAGS)\n\t\t&& doesInputLanguageRequestAutomaticFQTag (tag)\n\t\t&& !isTagExtraBitMarked (tag, XTAG_QUALIFIED_TAGS)\n\t\t&& !tag->skipAutoFQEmission)\n\t{\n\t\t/* const is discarded to update the cache field of TAG. */\n\t\tbuildFqTagCache (tag);\n\t}\n\n\tlength = writerWriteTag (TagFile.mio, tag);\n\n\tif (length > 0)\n\t{\n\t\t++TagFile.numTags.added;\n\t\trememberMaxLengths (strlen (tag->name), (size_t) length);\n\t}\n\tDebugStatement ( if (TagFile.mio) mio_flush (TagFile.mio); )\n\n\tabort_if_ferror (TagFile.mio);\n}\n\nextern bool writePseudoTag (const ptagDesc *desc,\n\t\t\t\t\t\t\tconst char *const fileName,\n\t\t\t\t\t\t\tconst char *const pattern,\n\t\t\t\t\t\t\tconst char *const parserName)\n{\n\tint length;\n\n\tlength = writerWritePtag (TagFile.mio, desc, fileName,\n\t\t\t\t\t\t\t  pattern, parserName);\n\tif (length < 0)\n\t\treturn false;\n\n\tabort_if_ferror (TagFile.mio);\n\n\t++TagFile.numTags.added;\n\trememberMaxLengths (strlen (desc->name), (size_t) length);\n\n\treturn true;\n}\n\nextern void corkTagFile (unsigned int corkFlags)\n{\n\tTagFile.cork++;\n\tif (TagFile.cork == 1)\n\t{\n\t\tTagFile.corkFlags = corkFlags;\n\t\tTagFile.corkQueue = ptrArrayNew (deleteTagEnry);\n\t\ttagEntryInfo *nil = newNilTagEntry (corkFlags);\n\t\tptrArrayAdd (TagFile.corkQueue, nil);\n\t\tTagFile.intervaltab = RB_ROOT;\n\t}\n}\n\nextern void uncorkTagFile (void)\n{\n\tunsigned int i;\n\n\tTagFile.cork--;\n\n\tif (TagFile.cork > 0)\n\t\treturn ;\n\n\tfor (i = 1; i < ptrArrayCount (TagFile.corkQueue); i++)\n\t{\n\t\ttagEntryInfo *tag = ptrArrayItem (TagFile.corkQueue, i);\n\n\t\tif (!isTagWritable(tag))\n\t\t\tcontinue;\n\n\t\twriteTagEntry (tag);\n\n\t\tif (doesInputLanguageRequestAutomaticFQTag (tag)\n\t\t\t&& isXtagEnabled (XTAG_QUALIFIED_TAGS)\n\t\t\t&& !isTagExtraBitMarked (tag, XTAG_QUALIFIED_TAGS)\n\t\t\t&& !tag->skipAutoFQEmission\n\t\t\t&& ((tag->extensionFields.scopeKindIndex != KIND_GHOST_INDEX\n\t\t\t\t && tag->extensionFields.scopeName != NULL\n\t\t\t\t && tag->extensionFields.scopeIndex != CORK_NIL)\n\t\t\t\t|| (tag->extensionFields.scopeKindIndex == KIND_GHOST_INDEX\n\t\t\t\t\t&& tag->extensionFields.scopeName == NULL\n\t\t\t\t\t&& tag->extensionFields.scopeIndex == CORK_NIL)))\n\t\t\tmakeQualifiedTagEntry (tag);\n\t}\n\n\tptrArrayDelete (TagFile.corkQueue);\n\tTagFile.corkQueue = NULL;\n}\n\nextern tagEntryInfo *getEntryInCorkQueue (int n)\n{\n\tif ((CORK_NIL < n) && (((size_t)n) < ptrArrayCount (TagFile.corkQueue)))\n\t\treturn ptrArrayItem (TagFile.corkQueue, n);\n\telse\n\t\treturn NULL;\n}\n\nextern tagEntryInfo *getEntryOfNestingLevel (const NestingLevel *nl)\n{\n\tif (nl == NULL)\n\t\treturn NULL;\n\treturn getEntryInCorkQueue (nl->corkIndex);\n}\n\nextern size_t countEntryInCorkQueue (void)\n{\n\treturn ptrArrayCount (TagFile.corkQueue);\n}\n\nextern void markTagAsPlaceholder (tagEntryInfo *e, bool placeholder)\n{\n\te->placeholder = placeholder;\n}\n\nextern void markCorkEntryAsPlaceholder (int index, bool placeholder)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue(index);\n\tif (e)\n\t\tmarkTagAsPlaceholder(e, placeholder);\n}\n\nextern int makePlaceholder (const char *const name)\n{\n\ttagEntryInfo e;\n\n\tinitTagEntry (&e, name, KIND_GHOST_INDEX);\n\tmarkTagAsPlaceholder(&e, true);\n\n\t/*\n\t * makePlaceholder may be called even before reading any bytes\n\t * from the input stream. In such case, initTagEntry fills\n\t * the lineNumber field of the placeholder tag with 0.\n\t * This breaks an assertion in makeTagEntry. Following adjustment\n\t * is for avoiding it.\n\t */\n\tif (e.lineNumber == 0)\n\t\te.lineNumber = 1;\n\n\treturn makeTagEntry (&e);\n}\n\nextern int makeTagEntry (tagEntryInfo *const tag)\n{\n\tint r = CORK_NIL;\n\tAssert (tag->name != NULL);\n\tAssert(tag->lineNumber > 0);\n\n\tif (!TagFile.cork)\n\t\tif (!isTagWritable (tag))\n\t\t\tgoto out;\n\n\tif (tag->name [0] == '\\0' && (!tag->placeholder))\n\t{\n\t\tif (! tag->allowNullTag)\n\t\t{\n\t\t\terror (NOTICE, \"ignoring null tag in %s(line: %lu, language: %s)\",\n\t\t\t\t   getInputFileName (), tag->lineNumber,\n\t\t\t\t   getLanguageName (tag->langType));\n\t\t\tgoto out;\n\t\t}\n\n\t\t/* writeTagEntry decides whether ctags emits this tag or not.\n\t\t * At this point, we just mark the tag as a null tag. */\n\t\tif (! tag->placeholder)\n\t\t\tmarkTagExtraBit(tag, XTAG_NULLTAG);\n\t}\n\n\tif (TagFile.cork)\n\t\tr = queueTagEntry (tag);\n\telse\n\t\twriteTagEntry (tag);\n\n\tif (r != CORK_NIL)\n\t\tnotifyMakeTagEntry (tag, r);\n\nout:\n\treturn r;\n}\n\nextern int makeQualifiedTagEntry (const tagEntryInfo *const e)\n{\n\tint r = CORK_NIL;\n\ttagEntryInfo x;\n\tint xk;\n\tconst char *sep;\n\tstatic vString *fqn;\n\n\tif (isXtagEnabled (XTAG_QUALIFIED_TAGS))\n\t{\n\t\tx = *e;\n\t\tmarkTagExtraBit (&x, XTAG_QUALIFIED_TAGS);\n\n\t\tfqn = vStringNewOrClearWithAutoRelease (fqn);\n\n\t\tif (e->extensionFields.scopeName)\n\t\t{\n\t\t\tvStringCatS (fqn, e->extensionFields.scopeName);\n\t\t\txk = e->extensionFields.scopeKindIndex;\n\t\t\tsep = scopeSeparatorFor (e->langType, e->kindIndex, xk);\n\t\t\tvStringCatS (fqn, sep);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* This is an top level item. prepend a root separator\n\t\t\t   if the kind of the item has. */\n\t\t\tsep = scopeSeparatorFor (e->langType, e->kindIndex, KIND_GHOST_INDEX);\n\t\t\tif (sep == NULL)\n\t\t\t{\n\t\t\t\t/* No root separator. The name of the\n\t\t\t\t   optional tag and that of full qualified tag\n\t\t\t\t   are the same; recording the full qualified tag\n\t\t\t\t   is meaningless. */\n\t\t\t\treturn r;\n\t\t\t}\n\t\t\telse\n\t\t\t\tvStringCatS (fqn, sep);\n\t\t}\n\t\tvStringCatS (fqn, e->name);\n\n\t\tx.name = vStringValue (fqn);\n\t\t/* makeExtraTagEntry of c.c doesn't clear scope\n\t\t   related fields. */\n#if 0\n\t\tx.extensionFields.scopeKind = NULL;\n\t\tx.extensionFields.scopeName = NULL;\n\t\tx.extensionFields.scopeIndex = CORK_NIL;\n#endif\n\n\t\tbool in_subparser\n\t\t\t= isTagExtraBitMarked (&x,\n\t\t\t\t\t\t\t\t   XTAG_SUBPARSER);\n\n\t\tif (in_subparser)\n\t\t\tpushLanguage(x.langType);\n\n\t\tr = makeTagEntry (&x);\n\n\t\tif (in_subparser)\n\t\t\tpopLanguage();\n\t}\n\treturn r;\n}\n\nextern void setTagPositionFromTag (tagEntryInfo *const dst,\n\t\t\t\t\t\t\t\t   const tagEntryInfo *const src)\n{\n\tupdateTagLine (dst, src->lineNumber, src->filePosition);\n\tdst->boundaryInfo = src->boundaryInfo;\n}\n\nstatic void initTagEntryFull (tagEntryInfo *const e, const char *const name,\n\t\t\t\t\t\t\t  unsigned long lineNumber,\n\t\t\t\t\t\t\t  langType langType_,\n\t\t\t\t\t\t\t  MIOPos      filePosition,\n\t\t\t\t\t\t\t  const char *inputFileName,\n\t\t\t\t\t\t\t  int kindIndex,\n\t\t\t\t\t\t\t  roleBitsType roleBits,\n\t\t\t\t\t\t\t  const char *sourceFileName,\n\t\t\t\t\t\t\t  langType sourceLangType,\n\t\t\t\t\t\t\t  long sourceLineNumberDifference)\n{\n\tint i;\n\n\tAssert (getInputFileName() != NULL);\n\n\tmemset (e, 0, sizeof (tagEntryInfo));\n\te->lineNumberEntry = (bool) (Option.locate == EX_LINENUM);\n\te->lineNumber      = lineNumber;\n\te->boundaryInfo    = getAreaBoundaryInfo (lineNumber);\n\te->langType        = langType_;\n\te->filePosition    = filePosition;\n\te->inputFileName   = inputFileName;\n\te->name            = name;\n\te->extensionFields.scopeLangType = LANG_AUTO;\n\te->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;\n\te->extensionFields.scopeIndex     = CORK_NIL;\n\n\tAssert (kindIndex < 0 || kindIndex < (int)countLanguageKinds(langType_));\n\te->kindIndex = kindIndex;\n\n\tAssert (roleBits == 0\n\t\t\t|| (roleBits < (makeRoleBit(countLanguageRoles(langType_, kindIndex)))));\n\te->extensionFields.roleBits = roleBits;\n\tif (roleBits)\n\t\tmarkTagExtraBit (e, XTAG_REFERENCE_TAGS);\n\n\te->extensionFields.nth = NO_NTH_FIELD;\n\n\tif (isAreaStacked ())\n\t\tmarkTagExtraBit (e, XTAG_GUEST);\n\tif (doesSubparserRun ())\n\t\tmarkTagExtraBit (e, XTAG_SUBPARSER);\n\n\te->sourceLangType = sourceLangType;\n\te->sourceFileName = sourceFileName;\n\te->sourceLineNumberDifference = sourceLineNumberDifference;\n\n\te->usedParserFields = 0;\n\n\tfor ( i = 0; i < PRE_ALLOCATED_PARSER_FIELDS; i++ )\n\t\te->parserFields[i].ftype = FIELD_UNKNOWN;\n\n\tif (isParserMarkedNoEmission ())\n\t\te->placeholder = 1;\n\n\te->allowNullTag = doesLanguageAllowNullTag (e->langType);\n}\n\nextern void initTagEntry (tagEntryInfo *const e, const char *const name,\n\t\t\t\t\t\t  int kindIndex)\n{\n\tinitTagEntryFull(e, name,\n\t\t\t getInputLineNumber (),\n\t\t\t getInputLanguage (),\n\t\t\t getInputFilePosition (),\n\t\t\t getInputFileTagPath (),\n\t\t\t kindIndex,\n\t\t\t 0,\n\t\t\t getSourceFileTagPath(),\n\t\t\t getSourceLanguage(),\n\t\t\t getSourceLineNumber() - getInputLineNumber ());\n}\n\nextern void initRefTagEntry (tagEntryInfo *const e, const char *const name,\n\t\t\t\t\t\t\t int kindIndex, int roleIndex)\n{\n\tinitForeignRefTagEntry (e, name, getInputLanguage (), kindIndex, roleIndex);\n}\n\nextern void initForeignTagEntry (tagEntryInfo *const e, const char *const name,\n\t\t\t\t\t\t\t\t langType type,\n\t\t\t\t\t\t\t\t int kindIndex)\n{\n\tinitForeignRefTagEntry (e, name, type, kindIndex, ROLE_DEFINITION_INDEX);\n}\n\nextern void initForeignRefTagEntry (tagEntryInfo *const e, const char *const name,\n\t\t\t\t\t\t\t\t\tlangType langType,\n\t\t\t\t\t\t\t\t\tint kindIndex, int roleIndex)\n{\n\tinitTagEntryFull(e, name,\n\t\t\t getInputLineNumber (),\n\t\t\t langType,\n\t\t\t getInputFilePosition (),\n\t\t\t getInputFileTagPath (),\n\t\t\t kindIndex,\n\t\t\t makeRoleBit(roleIndex),\n\t\t\t getSourceFileTagPath(),\n\t\t\t getSourceLanguage(),\n\t\t\t getSourceLineNumber() - getInputLineNumber ());\n}\n\nstatic void markTagExtraBitFull (tagEntryInfo *const tag, xtagType extra, bool mark)\n{\n\tunsigned int index;\n\tunsigned int offset;\n\tuint8_t *slot;\n\n\tAssert (extra != XTAG_UNKNOWN);\n\n\tif (extra < XTAG_COUNT)\n\t{\n\t\tindex = (extra / 8);\n\t\toffset = (extra % 8);\n\t\tslot = tag->extra;\n\t}\n\telse if (tag->extraDynamic)\n\t{\n\t\tAssert (extra < countXtags ());\n\n\t\tindex = ((extra - XTAG_COUNT) / 8);\n\t\toffset = ((extra - XTAG_COUNT) % 8);\n\t\tslot = tag->extraDynamic;\n\t}\n\telse\n\t{\n\t\tAssert (extra < countXtags ());\n\t\tAssert (XTAG_COUNT <= countXtags ());\n\t\tunsigned int n = countXtags () - XTAG_COUNT;\n\t\ttag->extraDynamic = xCalloc ((n / 8) + 1, uint8_t);\n\t\tif (!tag->inCorkQueue)\n\t\t\tPARSER_TRASH_BOX(tag->extraDynamic, eFree);\n\t\tmarkTagExtraBitFull (tag, extra, mark);\n\t\treturn;\n\t}\n\n\tif (mark)\n\t\tslot [ index ] |= (1 << offset);\n\telse\n\t\tslot [ index ] &= ~(1 << offset);\n}\n\nextern void markTagExtraBit (tagEntryInfo *const tag, xtagType extra)\n{\n\tmarkTagExtraBitFull (tag, extra, true);\n}\n\nextern void unmarkTagExtraBit (tagEntryInfo *const tag, xtagType extra)\n{\n\tmarkTagExtraBitFull (tag, extra, false);\n}\n\nextern bool isTagExtraBitMarked (const tagEntryInfo *const tag, xtagType extra)\n{\n\tunsigned int index;\n\tunsigned int offset;\n\tconst uint8_t *slot;\n\n\tAssert (extra != XTAG_UNKNOWN);\n\n\tif (extra < XTAG_COUNT)\n\t{\n\t\tindex = (extra / 8);\n\t\toffset = (extra % 8);\n\t\tslot = tag->extra;\n\t}\n\telse if (!tag->extraDynamic)\n\t\treturn false;\n\telse\n\t{\n\t\tAssert (extra < countXtags ());\n\t\tindex = ((extra - XTAG_COUNT) / 8);\n\t\toffset = ((extra - XTAG_COUNT) % 8);\n\t\tslot = tag->extraDynamic;\n\t}\n\treturn !! ((slot [ index ]) & (1 << offset));\n}\n\nextern bool isTagExtra (const tagEntryInfo *const tag)\n{\n\tfor (unsigned int i = 0; i < countXtags(); i++)\n\t\tif (isTagExtraBitMarked (tag, i))\n\t\t\treturn true;\n\treturn false;\n}\n\nextern void resetTagCorkState (tagEntryInfo *const tag,\n\t\t\t\t\t\t\t   enum resetTagMemberAction xtagAction,\n\t\t\t\t\t\t\t   enum resetTagMemberAction parserFieldsAction)\n{\n\ttagEntryInfo original = *tag;\n\n\ttag->inCorkQueue = 0;\n\n\tswitch (xtagAction)\n\t{\n\tcase RESET_TAG_MEMBER_COPY:\n\t\tcopyExtraDynamic (&original, tag);\n\t\tbreak;\n\tcase RESET_TAG_MEMBER_CLEAR:\n\t\ttag->extraDynamic = NULL;\n\t\tbreak;\n\tcase RESET_TAG_MEMBER_DONTTOUCH:\n\t\tbreak;\n\t}\n\n\tswitch (parserFieldsAction)\n\t{\n\tcase RESET_TAG_MEMBER_COPY:\n\t\ttag->usedParserFields = 0;\n\t\ttag->parserFieldsDynamic = NULL;\n\t\tcopyParserFields (&original, tag);\n\t\tbreak;\n\tcase RESET_TAG_MEMBER_CLEAR:\n\t\ttag->usedParserFields = 0;\n\t\ttag->parserFieldsDynamic = NULL;\n\t\tbreak;\n\tcase RESET_TAG_MEMBER_DONTTOUCH:\n\t\tbreak;\n\t}\n}\n\nstatic void assignRoleFull (tagEntryInfo *const e, int roleIndex, bool assign)\n{\n\tif (roleIndex == ROLE_DEFINITION_INDEX)\n\t{\n\t\tif (assign)\n\t\t{\n\t\t\te->extensionFields.roleBits = 0;\n\t\t\tmarkTagExtraBitFull (e, XTAG_REFERENCE_TAGS, false);\n\t\t}\n\t}\n\telse if (roleIndex > ROLE_DEFINITION_INDEX)\n\t{\n\t\tAssert (roleIndex < (int)countLanguageRoles(e->langType, e->kindIndex));\n\n\t\tif (assign)\n\t\t\te->extensionFields.roleBits |= (makeRoleBit(roleIndex));\n\t\telse\n\t\t\te->extensionFields.roleBits &= ~(makeRoleBit(roleIndex));\n\t\tmarkTagExtraBitFull (e, XTAG_REFERENCE_TAGS, e->extensionFields.roleBits);\n\t}\n\telse\n\t\tAssertNotReached();\n}\n\nextern void assignRole (tagEntryInfo *const e, int roleIndex)\n{\n\tassignRoleFull(e, roleIndex, true);\n}\n\nextern void unassignRole (tagEntryInfo *const e, int roleIndex)\n{\n\tassignRoleFull(e, roleIndex, false);\n}\n\nextern bool isRoleAssigned (const tagEntryInfo *const e, int roleIndex)\n{\n\tif (roleIndex == ROLE_DEFINITION_INDEX)\n\t\treturn (!e->extensionFields.roleBits);\n\telse\n\t\treturn (e->extensionFields.roleBits & makeRoleBit(roleIndex));\n}\n\nextern unsigned long numTagsAdded (void)\n{\n\treturn TagFile.numTags.added;\n}\n\nextern void setNumTagsAdded (unsigned long nadded)\n{\n\tTagFile.numTags.added = nadded;\n}\n\nextern unsigned long numTagsTotal (void)\n{\n\treturn TagFile.numTags.added + TagFile.numTags.prev;\n}\n\nextern unsigned long maxTagsLine (void)\n{\n\treturn (unsigned long)TagFile.max.line;\n}\n\nextern void invalidatePatternCache (void)\n{\n\tTagFile.patternCacheValid = false;\n}\n\nextern void tagFilePosition (MIOPos *p)\n{\n\t/* mini-geany doesn't set TagFile.mio. */\n\tif (TagFile.mio == NULL)\n\t\treturn;\n\n\tif (mio_getpos (TagFile.mio, p) == -1)\n\t\terror (FATAL|PERROR,\n\t\t\t   \"failed to get file position of the tag file\\n\");\n}\n\nextern void setTagFilePosition (MIOPos *p, bool truncation)\n{\n\t/* mini-geany doesn't set TagFile.mio. */\n\tif (TagFile.mio == NULL)\n\t\treturn;\n\n\n\tlong t0 = 0;\n\tif (truncation) {\n\t\tt0 = mio_tell (TagFile.mio);\n\t\tif (t0 == -1)\n\t\t\terror (FATAL|PERROR,\n\t\t\t\t   \"failed to tell the file position of the tag file (t0)\\n\");\n\t}\n\n\n\tif (mio_setpos (TagFile.mio, p) == -1)\n\t\terror (FATAL|PERROR,\n\t\t\t   \"failed to set file position of the tag file\\n\");\n\n\tif (truncation)\n\t{\n\t\tlong t1 = mio_tell (TagFile.mio);\n\t\tif (t1 == -1)\n\t\t\terror (FATAL|PERROR,\n\t\t\t\t   \"failed to tell the file position of the tag file (t1)\\n\");\n\n\t\tif (!mio_try_resize (TagFile.mio, (size_t)t1))\n\t\t\terror (FATAL|PERROR,\n\t\t\t\t   \"failed to truncate the tag file %ld -> %ld\\n\", t0, t1);\n\t}\n}\n\nextern const char* getTagFileDirectory (void)\n{\n\treturn TagFile.directory;\n}\n\nstatic bool markAsPlaceholderRecursively (int index, tagEntryInfo *e, void *data CTAGS_ATTR_UNUSED)\n{\n\tmarkTagAsPlaceholder (e, true);\n\tmarkAllEntriesInScopeAsPlaceholder (index);\n\treturn true;\n}\n\nextern void markAllEntriesInScopeAsPlaceholder (int index)\n{\n\tforeachEntriesInScope (index, NULL, markAsPlaceholderRecursively, NULL);\n}\n\nextern int queryIntervalTabByLine(unsigned long lineNum)\n{\n\treturn queryIntervalTabByRange(lineNum, lineNum);\n}\n\nextern int queryIntervalTabByRange(unsigned long start, unsigned long end)\n{\n\tint index = CORK_NIL;\n\n\ttagEntryInfoX *ex = intervaltab_iter_first(&TagFile.intervaltab, start, end);\n\twhile (ex) {\n\t\tindex = ex->corkIndex;\n\t\tex = intervaltab_iter_next(ex, start, end);\n\t}\n\treturn index;\n}\n\nextern int queryIntervalTabByCorkEntry(int corkIndex)\n{\n\tAssert (corkIndex != CORK_NIL);\n\n\ttagEntryInfoX *ex = ptrArrayItem (TagFile.corkQueue, corkIndex);\n\ttagEntryInfo *e = &ex->slot;\n\n\tif (getTagEndLine (e) == 0)\n\t\treturn queryIntervalTabByLine(e->lineNumber);\n\treturn queryIntervalTabByRange(e->lineNumber, getTagEndLine (e));\n}\n\nextern bool removeFromIntervalTabMaybe(int corkIndex)\n{\n\tif (corkIndex == CORK_NIL)\n\t\treturn false;\n\n\ttagEntryInfoX *ex = ptrArrayItem (TagFile.corkQueue, corkIndex);\n\ttagEntryInfo *e = &ex->slot;\n\tif (!e->inIntevalTab)\n\t\treturn false;\n\n\tintervaltab_remove(ex, &TagFile.intervaltab);\n\te->inIntevalTab = 0;\n\treturn true;\n}\n"
  },
  {
    "path": "main/entry.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to entry.c\n*/\n#ifndef CTAGS_MAIN_ENTRY_H\n#define CTAGS_MAIN_ENTRY_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"types.h\"\n\n#include <stdint.h>\n#include <time.h>\n\n#include \"field.h\"\n#include \"xtag.h\"\n#include \"mio.h\"\n#include \"ptrarray.h\"\n#include \"nestlevel.h\"\n\n/*\n*   MACROS\n*/\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef struct sTagField {\n\tfieldType  ftype;\n\tconst char* value;\n\tbool valueOwner;\t\t\t/* used only in parserFieldsDynamic */\n} tagField;\n\ntypedef uint64_t roleBitsType;\n\n/*  Information about the current tag candidate.\n */\nstruct sTagEntryInfo {\n\t/*\n\t * the bit fields parsers may access for setting DIRECTLY\n\t */\n\tunsigned int lineNumberEntry:1;  /* pattern or line number entry */\n\tunsigned int isFileScope    :1;  /* is tag visible only within input file? */\n\tunsigned int truncateLineAfterTag :1;  /* truncate tag line at end of tag name? */\n\tunsigned int skipAutoFQEmission:1; /* If a parser makes a fq tag for the\n\t\t\t\t\t\t\t\t\t\t  current tag by itself, set this. */\n\n\t/*\n\t * the bit fields parser may access for setting via accessor\n\t */\n\tunsigned int placeholder    :1;\t /* is used only for keeping corkIndex based scope chain.\n\t\t\t\t\t    Put this entry to cork queue but\n\t\t\t\t\t\tthe tag is not printed:\n\t\t\t\t\t\t* not printed as a tag entry,\n\t\t\t\t\t\t* never used as a part of automatically generated FQ tag, and\n\t\t\t\t\t\t* not printed as a part of scope.\n\t\t\t\t\t\tSee getTagScopeInformation() and\n\t\t\t\t\t\tgetFullQualifiedScopeNameFromCorkQueue. */\n\n\t/*\n\t * the bit fields only the main part can access.\n\t */\n\tunsigned int isFileEntry    :1;  /* is this just an entry for a file name? */\n\tunsigned int isPseudoTag:1;\t/* Used only in xref output.\n\t\t\t\t\t\t\t\t   If a tag is a pseudo, set this. */\n\tunsigned int inCorkQueue:1;\n\tunsigned int isInputFileNameShared: 1; /* shares the value for inputFileName.\n\t\t\t\t\t\t\t\t\t\t\t* Set in the cork queue; don't touch this.*/\n\tunsigned int isSourceFileNameShared: 1; /* shares the value for sourceFileName.\n\t\t\t\t\t\t\t\t\t\t\t * Set in the cork queue; don't touch this.*/\n\tunsigned int boundaryInfo: 2; /* info about the stacked input area */\n\tunsigned int inIntevalTab:1;\n\tunsigned int allowNullTag:1;\t/* allow a tag with an empty string.\n\t\t\t\t\t\t\t\t\t * To allow your parser to emit null tags without\n\t\t\t\t\t\t\t\t\t * setting this per-entry allowNullTag,\n\t\t\t\t\t\t\t\t\t * set parserDefinition::allowNullTag instead.\n\t\t\t\t\t\t\t\t\t *\n\t\t\t\t\t\t\t\t\t * Set this member before calling makeTagEntry.\n\t\t\t\t\t\t\t\t\t */\n\n\tunsigned long lineNumber;     /* line number of tag;\n\t\t\t\t\t\t\t\t\t use updateTagLine() for updating this member. */\n\tconst char* pattern;\t      /* pattern for locating input line\n\t\t\t\t       * (may be NULL if not present) *//*  */\n\tMIOPos      filePosition;     /* file position of line containing tag */\n\tlangType langType;         /* language of input file */\n\tconst char *inputFileName;   /* name of input file.\n\t\t\t\t\t\t\t\t\tYou cannot modify the contents of buffer pointed\n\t\t\t\t\t\t\t\t\tby this member of the tagEntryInfo returned from\n\t\t\t\t\t\t\t\t\tgetEntryInCorkQueue(). The buffer may be shared\n\t\t\t\t\t\t\t\t\tbetween tag entries in the cork queue.\n\n\t\t\t\t\t\t\t\t\tFurther more, modifying this member of the\n\t\t\t\t\t\t\t\t\ttagEntryInfo returned from getEntryInCorkQueue()\n\t\t\t\t\t\t\t\t\tmay cause a memory leak. */\n\tconst char *name;             /* name of the tag */\n\tint kindIndex;\t      /* kind descriptor */\n\tuint8_t extra[ ((XTAG_COUNT) / 8) + 1 ];\n\tuint8_t *extraDynamic;\t\t/* Dynamically allocated but freed by per parser TrashBox */\n\n\tstruct {\n\t\tconst char* access;\n\t\tconst char* implementation;\n\t\tconst char* inheritance;\n\n\t\t/* Which scopeKindIndex belong to. If the value is LANG_AUTO,\n\t\t   the value for langType field of this structure is used as default value.\n\t\t   LANG_AUTO is set automatically in initTagEntryInfo. */\n\t\tlangType    scopeLangType;\n\t\tint         scopeKindIndex;\n\t\tconst char* scopeName;\n\t\tint         scopeIndex;   /* cork queue entry for upper scope tag.\n\t\t\t\t\t     This field is meaningful if the value\n\t\t\t\t\t     is not CORK_NIL, scopeKindIndex is KIND_GHOST_INDEX,\n\t\t\t\t\t     and scopeName is NULL.\n\t\t\t\t\t     CXX parser violates this rule; see the comment inside\n\t\t\t\t\t     cxxTagBegin(). */\n\n\t\tconst char* signature;\n\n\t\t/* type (union/struct/etc.) and name for a variable or typedef. */\n\t\tconst char* typeRef [2];  /* e.g., \"struct\" and struct name */\n\n#define ROLE_DEFINITION_INDEX -1\n#define ROLE_DEFINITION_NAME \"def\"\n#define ROLE_MAX_COUNT (sizeof(roleBitsType) * 8)\n\t\troleBitsType roleBits; /* for role of reference tag */\n\n#ifdef HAVE_LIBXML\n\t\tconst char* xpath;\n#endif\n\t\tunsigned long _endLine;\t/* Don't set directly. Use setTagEndLine() and getTagEndLine() */\n\t\ttime_t epoch;\n#define NO_NTH_FIELD -1\n\t\tshort nth;\n\t} extensionFields;  /* list of extension fields*/\n\n\t/* `usedParserFields' tracks how many parser specific fields are\n\t   used. If it is a few (less than PRE_ALLOCATED_PARSER_FIELDS),\n\t   statically allocated parserFields is used. If more fields than\n\t   PRE_ALLOCATED_PARSER_FIELDS is defined and attached, parserFieldsDynamic\n\t   is used. */\n\tunsigned int usedParserFields;\n#define PRE_ALLOCATED_PARSER_FIELDS 5\n#define NO_PARSER_FIELD -1\n\ttagField     parserFields [PRE_ALLOCATED_PARSER_FIELDS];\n\tptrArray *   parserFieldsDynamic;\n\n\t/* Following source* fields are used only when #line is found\n\t   in input and --line-directive is given in ctags command line. */\n\tlangType sourceLangType;\n\tconst char *sourceFileName;\n\tunsigned long sourceLineNumberDifference;\n};\n\ntypedef bool (* entryForeachFunc) (int corkIndex,\n\t\t\t\t\t\t\t\t   tagEntryInfo * entry,\n\t\t\t\t\t\t\t\t   void * data);\n\n/*\n*   GLOBAL VARIABLES\n*/\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern int makeTagEntry (tagEntryInfo *const tag);\nextern void initTagEntry (tagEntryInfo *const e, const char *const name,\n\t\t\t  int kindIndex);\nextern void initRefTagEntry (tagEntryInfo *const e, const char *const name,\n\t\t\t     int kindIndex, int roleIndex);\n\n/* initForeignRefTagEntry() is for making a tag for the language X when parsing\n * source code of Y language.\n * From the view point of the language Y, we call the language X a foreign\n * language.\n *\n * When making a tag for a foreign with this function, you must declare the\n * language X in the parser of Y with DEPTYPE_FOREIGNER dependency.\n */\nextern void initForeignTagEntry (tagEntryInfo *const e, const char *const name,\n\t\t\t\t\t\t\t\t langType type,\n\t\t\t\t\t\t\t\t int kindIndex);\nextern void initForeignRefTagEntry (tagEntryInfo *const e, const char *const name,\n\t\t\t\t\t\t\t\t\tlangType type,\n\t\t\t\t\t\t\t\t\tint kindIndex, int roleIndex);\nextern void assignRole(tagEntryInfo *const e, int roleIndex);\n#define clearRoles(E) assignRole((E), ROLE_DEFINITION_INDEX)\nextern void unassignRole(tagEntryInfo *const e, int roleIndex);\nextern bool isRoleAssigned(const tagEntryInfo *const e, int roleIndex);\n\nextern int makeQualifiedTagEntry (const tagEntryInfo *const e);\n\nextern void setTagPositionFromTag (tagEntryInfo *const dst, const tagEntryInfo *const src);\n\n#define CORK_NIL 0\ntagEntryInfo *getEntryInCorkQueue   (int n);\ntagEntryInfo *getEntryOfNestingLevel (const NestingLevel *nl);\nsize_t        countEntryInCorkQueue (void);\n\n/* If a parser sets (CORK_QUEUE and )CORK_SYMTAB to useCork,\n * the parsesr can use symbol lookup tables for the current input.\n * Each scope has a symbol lookup table.\n * To register an tag to the table, use registerEntry().\n * registerEntry registers CORKINDEX to a symbol table of a parent tag\n * specified in the scopeIndex field of the tag specified with CORKINDEX.\n */\nvoid          registerEntry (int corkIndex);\nvoid        unregisterEntry (int corkIndex);\n\n/* foreachEntriesInScope is for traversing the symbol table for a table\n * specified with CORKINDEX. If CORK_NIL is given, this function traverses\n * top-level entries. If name is NULL, this function traverses all entries\n * under the scope.\n *\n * If FUNC returns false, this function returns false immediately\n * even if more entires in the scope.\n * If FUNC never returns false, this function returns true.\n * If FUNC is not called because no node for NAME in the symbol table,\n * this function returns true.\n */\nbool          foreachEntriesInScope (int corkIndex,\n\t\t\t\t\t\t\t\t\t const char *name, /* or NULL */\n\t\t\t\t\t\t\t\t\t entryForeachFunc func,\n\t\t\t\t\t\t\t\t\t void *data);\n\nunsigned int countEntriesInScope    (int corkIndex, bool onlyDefinitionTag,\n\t\t\t\t\t\t\t\t\t entryForeachFunc func, void *data);\n\n/* Return the cork index for NAME in the scope specified with CORKINDEX.\n * Even if more than one entries for NAME are in the scope, this function\n * just returns one of them. Returning CORK_NIL means there is no entry\n * for NAME.\n */\nint           anyEntryInScope       (int corkIndex,\n\t\t\t\t\t\t\t\t\t const char *name,\n\t\t\t\t\t\t\t\t\t bool onlyDefinitionTag);\n\nint           anyKindEntryInScope (int corkIndex,\n\t\t\t\t\t\t\t\t   const char *name, int kind,\n\t\t\t\t\t\t\t\t   bool onlyDefinitionTag);\n\nint           anyKindsEntryInScope (int corkIndex,\n\t\t\t\t\t\t\t\t\tconst char *name,\n\t\t\t\t\t\t\t\t\tconst int * kinds, int count,\n\t\t\t\t\t\t\t\t\tbool onlyDefinitionTag);\n\nint           anyKindsEntryInScopeRecursive (int corkIndex,\n\t\t\t\t\t\t\t\t\t\t\t const char *name,\n\t\t\t\t\t\t\t\t\t\t\t const int * kinds, int count,\n\t\t\t\t\t\t\t\t\t\t\t bool onlyDefinitionTag);\n\nextern void    updateTagLine(tagEntryInfo *tag, unsigned long lineNumber, MIOPos filePosition);\nextern void    setTagEndLine (tagEntryInfo *tag, unsigned long endLine);\nextern void    setTagEndLineToCorkEntry (int corkIndex, unsigned long endLine);\n#define getTagEndLine(tag) ((tag)->extensionFields._endLine)\n\nextern int     queryIntervalTabByLine(unsigned long lineNum);\nextern int     queryIntervalTabByRange(unsigned long startLine, unsigned long endLine);\nextern int     queryIntervalTabByCorkEntry(int corkIndex);\nextern bool    removeFromIntervalTabMaybe(int corkIndex);\n\nextern void    markTagExtraBit     (tagEntryInfo *const tag, xtagType extra);\nextern void    unmarkTagExtraBit   (tagEntryInfo *const tag, xtagType extra);\nextern bool isTagExtraBitMarked (const tagEntryInfo *const tag, xtagType extra);\n\n/* If any extra bit is on, return true. */\nextern bool isTagExtra (const tagEntryInfo *const tag);\n\n/*\n  In the following frequently used code-pattern:\n\n     tagEntryInfo *original = getEntryInCorkQueue (index);\n     tagEntryInfo xtag = *original;\n\t ... customize XTAG ...\n\t makeTagEntry (&xtag);\n\n   ORIGINAL and XTAG share some memory objects through their members.\n   TagEntryInfo::name is one of obvious ones.\n   When updating the member in the ... customize XTAG ... stage, you will\n   do:\n\n      vStringValue *xtag_name = vStringNewInit (xtags->name);\n\t  ... customize XTAG_NAME with vString functions ...\n\t  xtag.name = vStringValue (xtag_name);\n\t  makeTagEntry (&xtag);\n\t  vStringDelete (xtag_name);\n\n   There are some vague ones: extraDynamic and parserFieldsDynamic.\n   resetTagCorkState does:\n\n   - mark the TAG is not in cork queue: set inCorkQueue 0.\n   - copy,  clear, or dont touch the extraDynamic member.\n   - copy,  clear, or dont touch the parserFieldsDynamic member.\n\n*/\n\nenum resetTagMemberAction {\n\tRESET_TAG_MEMBER_COPY,\n\tRESET_TAG_MEMBER_CLEAR,\n\tRESET_TAG_MEMBER_DONTTOUCH,\n};\n\nextern void resetTagCorkState (tagEntryInfo *const tag,\n\t\t\t\t\t\t\t   enum resetTagMemberAction xtagAction,\n\t\t\t\t\t\t\t   enum resetTagMemberAction parserFieldsAction);\n\n/* Functions for attaching parser specific fields\n *\n * Which function should I use?\n * ----------------------------\n * Case A:\n *\n * If your parser uses the Cork API, and your parser called\n * makeTagEntry () already, you can use both\n * attachParserFieldToCorkEntry () and attachParserField ().\n *\n * attachParserField () and attachParserFieldToCorkEntry () duplicates\n * the memory object specified with `value' and stores the duplicated\n * object to the entry on the cork queue. So the parser must/can free\n * the original one passed to the functions after calling. The cork\n * queue manages the life of the duplicated object. It is not the\n * parser's concern.\n *\n *\n * Case B:\n *\n * If your parser called one of initTagEntry () family but didn't call\n * makeTagEntry () for a tagEntry yet, use attachParserField ().\n *\n * The parser (== caller) must keep the memory object specified with `value'\n * till calling makeTagEntry (). The parser must free the memory object\n * after calling makeTagEntry () if it is allocated dynamically in the\n * parser side.\n *\n * Interpretation of VALUE\n * -----------------------\n * The VALUE is interpreted very differently depending on the output\n * format: ctags, xref, and json. See field.h.\n *\n * WARNING: updating the VALUE\n * ---------------------------\n * In the current implementation, there is no way to update the value\n * for a given field or detach the value from the given field.\n * For the same combination of TAG and FTYPE, you can call the\n * attachParser* function only once.\n */\nextern void attachParserField (tagEntryInfo *const tag, fieldType ftype, const char* value);\nextern void attachParserFieldToCorkEntry (int index, fieldType ftype, const char* value);\nextern const char* getParserFieldValueForType (const tagEntryInfo *const tag, fieldType ftype);\n\nextern int makePlaceholder (const char *const name);\nextern void markTagAsPlaceholder (tagEntryInfo *e, bool placeholder);\nextern void markCorkEntryAsPlaceholder (int index, bool placeholder);\n\n/* Marking all tag entries entries under the scope specified\n * with index recursively.\n *\n * The parser calling this function enables CORK_SYMTAB.\n * Entries to be marked must be registered to the scope\n * specified with index or its descendant scopes with\n * registerEntry ().\n *\n * Call makePlaceholder () at the start of your parser for\n * making the root scope where the entries are registered.\n */\nextern void markAllEntriesInScopeAsPlaceholder (int index);\n\n#endif  /* CTAGS_MAIN_ENTRY_H */\n"
  },
  {
    "path": "main/entry_p.h",
    "content": "/*\n*   Copyright (c) 2017, Red Hat, Inc.\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   main part private interface to entry.c\n*/\n#ifndef CTAGS_PRIVATE_ENTRY_H\n#define CTAGS_PRIVATE_ENTRY_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"entry.h\"\n#include \"types.h\"\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern const kindDefinition* getTagKind(const tagEntryInfo *const tag);\nextern char getTagKindLetter(const tagEntryInfo *const tag);\nextern const char* getTagKindName(const tagEntryInfo *const tag);\n\nextern const roleDefinition* getTagRole(const tagEntryInfo *const tag, int roleIndex);\n\nextern void freeTagFileResources (void);\nextern const char *tagFileName (void);\nextern void openTagFile (void);\nextern void closeTagFile (const bool resize);\nextern void  setupWriter (void *writerClientData);\nextern bool  teardownWriter (const char *inputFilename);\n\nextern unsigned long numTagsAdded(void);\nextern void setNumTagsAdded (unsigned long nadded);\nextern unsigned long numTagsTotal(void);\nextern unsigned long maxTagsLine(void);\nextern void invalidatePatternCache(void);\nextern void tagFilePosition (MIOPos *p);\nextern void setTagFilePosition (MIOPos *p, bool truncation);\nextern const char* getTagFileDirectory (void);\nextern void getTagScopeInformation (tagEntryInfo *const tag,\n\t\t\t\t    const char **kind, const char **name);\n\n/* Getting line associated with tag */\nextern char *readLineFromBypassForTag (vString *const vLine, const tagEntryInfo *const tag,\n\t\t\t\t   long *const pSeekValue);\n\n/* Generating pattern associated tag, caller must do eFree for the returned value. */\nextern char* makePatternString (const tagEntryInfo *const tag);\n\n\n/* language is optional: can be NULL. */\nextern bool writePseudoTag (const ptagDesc *pdesc,\n\t\t\t       const char *const fileName,\n\t\t\t       const char *const pattern,\n\t\t\t       const char *const parserName);\n\nvoid          corkTagFile(unsigned int corkFlags);\nvoid          uncorkTagFile(void);\n\nextern void makeFileTag (const char *const fileName);\n\nextern const tagField* getParserFieldForIndex (const tagEntryInfo * tag, int index);\n\n\nCTAGS_INLINE roleBitsType makeRoleBit(int roleIndex)\n{\n\tif (roleIndex == ROLE_DEFINITION_INDEX)\n\t\treturn 0;\n\telse\n\t\treturn ((roleBitsType)1) << roleIndex;\n}\n\n#endif\t/* CTAGS_PRIVATE_ENTRY_H */\n"
  },
  {
    "path": "main/entry_private.c",
    "content": "/*\n*   Copyright (c) 2017, Red Hat, Inc.\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   main part private interface to entry.c\n*/\n\n#include \"general.h\"\n#include \"entry_p.h\"\n#include \"parse_p.h\"\n\nextern const kindDefinition* getTagKind(const tagEntryInfo *const tag)\n{\n\treturn getLanguageKind(tag->langType, tag->kindIndex);\n}\n\nextern char getTagKindLetter(const tagEntryInfo *const tag)\n{\n\tkindDefinition *kdef = getLanguageKind(tag->langType, tag->kindIndex);\n\treturn kdef->letter;\n}\n\nextern const char* getTagKindName(const tagEntryInfo *const tag)\n{\n\tkindDefinition *kdef = getLanguageKind(tag->langType, tag->kindIndex);\n\treturn kdef->name;\n}\n\nextern const roleDefinition* getTagRole(const tagEntryInfo *const tag,\n\t\t\t\t\t\t\t\t\t\tint roleIndex)\n{\n\tif (roleIndex == ROLE_DEFINITION_INDEX)\n\t\treturn NULL;\n\treturn getLanguageRole(tag->langType, tag->kindIndex, roleIndex);\n}\n"
  },
  {
    "path": "main/error.c",
    "content": "/*\n*   Copyright (c) 2002-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains a lose assortment of shared functions.\n*/\n\n#include \"general.h\"  /* must always come first */\n#include <string.h>\n#include <errno.h>\n\n#include \"error_p.h\"\n#include \"options_p.h\"\n#include \"routines_p.h\"\n\n#ifdef HAVE_JANSSON\n#include <jansson.h>\n#endif\n\n#define selected(var,feature)\t(((int)(var) & (int)(feature)) == (int)feature)\n\nstatic errorPrintFunc errorPrinter;\nstatic void *errorPrinterData;\n\nextern void setErrorPrinter (errorPrintFunc printer, void *data)\n{\n\terrorPrinter = printer;\n\terrorPrinterData = data;\n}\n\nextern bool stderrDefaultErrorPrinter (const errorSelection selection,\n\t\t\t\t\t  const char *const format,\n\t\t\t\t\t  va_list ap, void *data CTAGS_ATTR_UNUSED)\n{\n\tfprintf (stderr, \"%s: %s\", getExecutableName (),\n\t\t selected (selection, WARNING) ? \"Warning: \" :\n\t\t selected (selection, NOTICE) ? \"Notice: \" : \"\");\n\tvfprintf (stderr, format, ap);\n\tif (selected (selection, PERROR))\n\t{\n#ifdef HAVE_STRERROR\n\t\tfprintf (stderr, \" : %s\", strerror (errno));\n#else\n\t\tperror (\" \");\n#endif\n\t}\n\tfputs (\"\\n\", stderr);\n\n\treturn (selected (selection, FATAL) || Option.fatalWarnings)? true: false;\n}\n\nextern void error (const errorSelection selection,\n\t\t   const char *const format, ...)\n{\n\tva_list ap;\n\tbool shouldExit;\n\n\tif (Option.quiet && selected (selection, NOTICE))\n\t\treturn;\n\n\tva_start (ap, format);\n\tshouldExit = (* errorPrinter) (selection, format, ap, errorPrinterData);\n\tva_end (ap);\n\n\tif (shouldExit)\n\t\texit (1);\n}\n\n#ifdef HAVE_JANSSON\nbool jsonErrorPrinter (const errorSelection selection, const char *const format, va_list ap,\n\t\t\t\t\t   void *data CTAGS_ATTR_UNUSED)\n{\n#define ERR_BUFFER_SIZE 4096\n\tstatic char reason[ERR_BUFFER_SIZE];\n\n\tvsnprintf (reason, ERR_BUFFER_SIZE, format, ap);\n\treason [ERR_BUFFER_SIZE - 1] = '\\0'; /* Do we need this? */\n\n\tjson_t *response = json_object ();\n\tjson_object_set_new (response, \"_type\", json_string (\"error\"));\n\tjson_object_set_new (response, \"message\", json_string (reason));\n\tif (selected (selection, NOTICE))\n\t\tjson_object_set_new (response, \"notice\", json_true ());\n\tif (selected (selection, WARNING))\n\t\tjson_object_set_new (response, \"warning\", json_true ());\n\tif (selected (selection, FATAL))\n\t\tjson_object_set_new (response, \"fatal\", json_true ());\n\tif (selected (selection, PERROR))\n\t{\n\t\tjson_object_set_new (response, \"errno\", json_integer (errno));\n\t\tjson_object_set_new (response, \"perror\", json_string (strerror (errno)));\n\t}\n\tjson_dumpf (response, stdout, JSON_PRESERVE_ORDER);\n\tfprintf (stdout, \"\\n\");\n\n\tjson_decref (response);\n\n\treturn false;\n}\n#endif\n"
  },
  {
    "path": "main/error_p.h",
    "content": "/*\n*   Copyright (c) 2002-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains a lose assortment of shared functions.\n*/\n\n#ifndef CTAGS_MAIN_ERORR_H\n#define CTAGS_MAIN_ERORR_H\n\n#include \"general.h\"  /* must always come first */\n\n#include <stdarg.h>\n#include \"routines.h\"\n\ntypedef bool (* errorPrintFunc) (const errorSelection selection, const char *const format,\n\t\t\t\t    va_list ap, void *data) CTAGS_ATTR_PRINTF (2, 0);\n\nextern void setErrorPrinter (errorPrintFunc printer, void *data);\n\nextern bool stderrDefaultErrorPrinter (const errorSelection selection, const char *const format, va_list ap,\n\t\t\t\t\t  void *data) CTAGS_ATTR_PRINTF (2, 0);\n\n#endif\n"
  },
  {
    "path": "main/field.c",
    "content": "/*\n *\n *  Copyright (c) 2015, Red Hat, Inc.\n *  Copyright (c) 2015, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#include \"general.h\"  /* must always come first */\n\n#include <errno.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"ctags.h\"\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"entry_p.h\"\n#include \"field.h\"\n#include \"field_p.h\"\n#include \"kind.h\"\n#include \"options_p.h\"\n#include \"parse_p.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"trashbox.h\"\n#include \"writer_p.h\"\n#include \"xtag_p.h\"\n\n#include \"optscript.h\"\n#include \"script_p.h\"\n\ntypedef struct sFieldObject {\n\tfieldDefinition *def;\n\tvString     *buffer;\n\tconst char* nameWithPrefix;\n\tlangType language;\n\tfieldType sibling;\n} fieldObject;\n\nstatic const char *renderFieldName (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldNameNoEscape (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b);\nstatic const char *renderFieldInput (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldInputNoEscape (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldCompactInputLine (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldSignature (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldSignatureNoEscape (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldScope (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldScopeNoEscape (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldTyperef (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldInherits (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldKindName (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldLineNumber (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldLanguage (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldAccess (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldKindLetter (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldImplementation (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldFile (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldPattern (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldRoles (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldRefMarker (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldExtras (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldXpath (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldScopeKindName(const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldEnd (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldEpoch (const tagEntryInfo *const tag, const char *value, vString* b);\nstatic const char *renderFieldNth (const tagEntryInfo *const tag, const char *value, vString* b);\n\nstatic bool doesContainAnyCharInName (const tagEntryInfo *const tag, const char *value, const char *chars);\nstatic bool doesContainAnyCharInInput (const tagEntryInfo *const tag, const char*value, const char *chars);\nstatic bool doesContainAnyCharInFieldScope (const tagEntryInfo *const tag, const char *value, const char *chars);\nstatic bool doesContainAnyCharInSignature (const tagEntryInfo *const tag, const char *value, const char *chars);\n\nstatic bool     isTyperefFieldAvailable   (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nstatic bool     isFileFieldAvailable      (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nstatic bool     isInheritsFieldAvailable  (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nstatic bool     isAccessFieldAvailable    (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nstatic bool     isImplementationFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nstatic bool     isSignatureFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nstatic bool     isExtrasFieldAvailable    (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nstatic bool     isXpathFieldAvailable     (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nstatic bool     isEndFieldAvailable       (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nstatic bool     isEpochAvailable          (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nstatic bool     isNthAvailable            (const tagEntryInfo *const tag, const fieldDefinition *fdef);\n\nstatic EsObject* getFieldValueForName (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* setFieldValueForName (tagEntryInfo *, const fieldDefinition *, const EsObject *);\nstatic EsObject* getFieldValueForInput (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* getFieldValueForKind (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* getFieldValueForLanguage (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* getFieldValueForTyperef (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* setFieldValueForTyperef (tagEntryInfo *, const fieldDefinition *, const EsObject *);\nstatic EsObject* checkFieldValueForTyperef (const fieldDefinition *, const EsObject *);\nstatic EsObject* getFieldValueForScope (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* setFieldValueForScope (tagEntryInfo *, const fieldDefinition *, const EsObject *);\nstatic EsObject* checkFieldValueForScope (const fieldDefinition *, const EsObject *);\nstatic EsObject* getFieldValueForExtras (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* getFieldValueForAccess (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* setFieldValueForAccess (tagEntryInfo *, const fieldDefinition *, const EsObject *);\nstatic EsObject* getFieldValueForSignature (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* setFieldValueForSignature (tagEntryInfo *, const fieldDefinition *, const EsObject *);\nstatic EsObject* getFieldValueForRoles (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* getFieldValueForLineCommon (const tagEntryInfo *, const fieldDefinition *);\nstatic EsObject* checkFieldValueForLineCommon (const fieldDefinition *, const EsObject *);\nstatic EsObject* setFieldValueForLineCommon (tagEntryInfo *, const fieldDefinition *, const EsObject *);\nstatic EsObject* setFieldValueForInherits (tagEntryInfo *, const fieldDefinition *, const EsObject *);\n\n#define WITH_DEFAULT_VALUE(str) ((str)?(str):FIELD_NULL_LETTER_STRING)\n\nstatic fieldDefinition fieldDefinitionsFixed [] = {\n\t[FIELD_NAME] = {\n\t\t.letter             = 'N',\n\t\t.name               = \"name\",\n\t\t.description        = \"tag name\",\n\t\t.enabled            = true,\n\t\t.render             = renderFieldName,\n\t\t.renderNoEscaping   = renderFieldNameNoEscape,\n\t\t.doesContainAnyChar = doesContainAnyCharInName,\n\t\t.isValueAvailable   = NULL,\n\t\t.dataType           = FIELDTYPE_STRING,\n\t\t.getterValueType    = NULL,\n\t\t.getValueObject     = getFieldValueForName,\n\t\t.setterValueType    = NULL,\n\t\t.checkValueForSetter= NULL,\n\t\t.setValueObject     = setFieldValueForName,\n\t},\n\t[FIELD_INPUT_FILE] = {\n\t\t.letter             = 'F',\n\t\t.name               = \"input\",\n\t\t.description        = \"input file\",\n\t\t.enabled            = true,\n\t\t.render             = renderFieldInput,\n\t\t.renderNoEscaping   = renderFieldInputNoEscape,\n\t\t.doesContainAnyChar = doesContainAnyCharInInput,\n\t\t.isValueAvailable   = NULL,\n\t\t.dataType           = FIELDTYPE_STRING,\n\t\t.getterValueType    = NULL,\n\t\t.getValueObject     = getFieldValueForInput,\n\t\t.setterValueType    = NULL,\n\t\t.checkValueForSetter= NULL,\n\t\t.setValueObject     = NULL,\n\t},\n\t[FIELD_PATTERN] = {\n\t\t.letter             = 'P',\n\t\t.name               = \"pattern\",\n\t\t.description        = \"pattern\",\n\t\t.enabled            = true,\n\t\t.render             = renderFieldPattern,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable   = NULL,\n\t\t.dataType           = FIELDTYPE_STRING|FIELDTYPE_BOOL,\n\t},\n};\n\nstatic fieldDefinition fieldDefinitionsExuberant [] = {\n\t[FIELD_COMPACT_INPUT_LINE - FIELD_ECTAGS_START] = {\n\t\t.letter             = 'C',\n\t\t.name               = \"compact\",\n\t\t.description        = \"compact input line (used only in xref output)\",\n\t\t.enabled            = false,\n\t\t.render             = renderFieldCompactInputLine,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable   = NULL,\n\t\t.dataType           = FIELDTYPE_STRING,\n\t},\n\t[FIELD_FILE_SCOPE - FIELD_ECTAGS_START] = {\n\t\t.letter             = 'f',\n\t\t.name               = \"file\",\n\t\t.description        = \"File-restricted scoping\",\n\t\t.enabled            = true,\n\t\t.render             = renderFieldFile,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable   = isFileFieldAvailable,\n\t\t.dataType           = FIELDTYPE_BOOL,\n\t},\n\t[FIELD_KIND_LONG - FIELD_ECTAGS_START] = {\n\t\t.letter             = 'K',\n\t\t.name               = NULL,\n\t\t.description        = \"Kind of tag in long-name form\",\n\t\t.enabled            = false,\n\t\t.render             = renderFieldKindName,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable   = NULL,\n\t\t.dataType           = FIELDTYPE_STRING,\n\t},\n\t[FIELD_KIND - FIELD_ECTAGS_START] = {\n\t\t.letter             ='k',\n\t\t.name               = NULL,\n\t\t.description        = \"Kind of tag in one-letter form\",\n\t\t.enabled            = true,\n\t\t.render             = renderFieldKindLetter,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable   = NULL,\n\t\t.dataType           = FIELDTYPE_STRING,\n\t},\n\t[FIELD_LANGUAGE - FIELD_ECTAGS_START] = {\n\t\t.letter             = 'l',\n\t\t.name               = \"language\",\n\t\t.description        = \"Language of input file containing tag\",\n\t\t.enabled            = false,\n\t\t.render             = renderFieldLanguage,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.dataType           = FIELDTYPE_STRING,\n\t\t.getterValueType    = \"language\",\n\t\t.getValueObject     = getFieldValueForLanguage,\n\t\t.setterValueType    = NULL,\n\t\t.checkValueForSetter= NULL,\n\t\t.setValueObject     = NULL,\n\t},\n\t[FIELD_LINE_NUMBER - FIELD_ECTAGS_START] = {\n\t\t.letter             = 'n',\n\t\t.name               = \"line\",\n\t\t.description        = \"Line number of tag definition\",\n\t\t.enabled            = false,\n\t\t.render             = renderFieldLineNumber,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable   = NULL,\n\t\t.dataType           = FIELDTYPE_INTEGER,\n\t\t.getterValueType    = \"int\",\n\t\t.getValueObject     = getFieldValueForLineCommon,\n\t\t.setterValueType    = \"matchloc|line:int\", /* line <= getInputLineNumber(); */\n\t\t.checkValueForSetter= checkFieldValueForLineCommon,\n\t\t.setValueObject     = setFieldValueForLineCommon,\n\t},\n\t[FIELD_SCOPE - FIELD_ECTAGS_START] = {\n\t\t.letter\t\t\t\t= 's',\n\t\t.name\t\t\t\t= NULL,\n\t\t.description\t\t= \"[tags output] scope (kind:name) of tag definition, [xref and json output] name of scope\",\n\t\t.enabled\t\t\t= true,\n\t\t.render\t\t\t\t= renderFieldScope,\n\t\t.renderNoEscaping\t= renderFieldScopeNoEscape,\n\t\t.doesContainAnyChar = doesContainAnyCharInFieldScope,\n\t\t.isValueAvailable\t= NULL,\n\t\t.dataType\t\t\t= FIELDTYPE_STRING,\n\t},\n\t[FIELD_TYPE_REF - FIELD_ECTAGS_START] = {\n\t\t.letter\t\t\t\t= 't',\n\t\t.name\t\t\t\t= \"typeref\",\n\t\t.description\t\t= \"Type and name of a variable or typedef\",\n\t\t.enabled\t\t\t= true,\n\t\t.render\t\t\t\t= renderFieldTyperef,\n\t\t.renderNoEscaping\t= NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable\t= isTyperefFieldAvailable,\n\t\t.dataType\t\t\t= FIELDTYPE_STRING,\n\t\t.getterValueType    = \"[string string]\",\n\t\t.getValueObject     = getFieldValueForTyperef,\n\t\t.setterValueType    = \"[string string]|string|index:int|false\",\n\t\t.checkValueForSetter= checkFieldValueForTyperef,\n\t\t.setValueObject     = setFieldValueForTyperef,\n\t},\n\t[FIELD_KIND_KEY - FIELD_ECTAGS_START] = {\n\t\t.letter\t\t\t\t= 'z',\n\t\t.name\t\t\t\t= \"kind\",\n\t\t.description\t\t= \"[tags output] prepend \\\"kind:\\\" to k/ (or K/) field output, [xref and json output] kind in long-name form\",\n\t\t.enabled\t\t\t= false,\n\t\t/* Following renderer is for handling --_xformat=%{kind};\n\t\t   and is not for tags output. */\n\t\t.render\t\t\t\t= renderFieldKindName,\n\t\t.renderNoEscaping\t= NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable\t= NULL,\n\t\t.dataType\t\t\t= FIELDTYPE_STRING,\n\t\t.getterValueType    = \"name\",\n\t\t.getValueObject     = getFieldValueForKind,\n\t\t.setterValueType    = NULL,\n\t\t.checkValueForSetter= NULL,\n\t\t.setValueObject     = NULL,\n\t},\n\t[FIELD_INHERITANCE - FIELD_ECTAGS_START] = {\n\t\t.letter             = 'i',\n\t\t.name               = \"inherits\",\n\t\t.description        = \"Inheritance information\",\n\t\t.enabled            = false,\n\t\t.render             = renderFieldInherits,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable   = isInheritsFieldAvailable,\n\t\t.dataType           = FIELDTYPE_STRING|FIELDTYPE_BOOL,\n\t\t.getterValueType    = NULL,\n\t\t.getValueObject     = NULL,\n\t\t.setterValueType    = NULL,\n\t\t.checkValueForSetter= NULL,\n\t\t.setValueObject     = setFieldValueForInherits,\n\t},\n\t[FIELD_ACCESS - FIELD_ECTAGS_START] = {\n\t\t.letter             = 'a',\n\t\t.name               = \"access\",\n\t\t.description        = \"Access (or export) of class members\",\n\t\t.enabled            = false,\n\t\t.render             = renderFieldAccess,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable   = isAccessFieldAvailable,\n\t\t.dataType           = FIELDTYPE_STRING,\n\t\t.getterValueType    = NULL,\n\t\t.getValueObject     = getFieldValueForAccess,\n\t\t.setterValueType    = NULL,\n\t\t.checkValueForSetter= NULL,\n\t\t.setValueObject     = setFieldValueForAccess,\n\t},\n\t[FIELD_IMPLEMENTATION - FIELD_ECTAGS_START] = {\n\t\t.letter             = 'm',\n\t\t.name               = \"implementation\",\n\t\t.description        = \"Implementation information\",\n\t\t.enabled            = false,\n\t\t.render             = renderFieldImplementation,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable   = isImplementationFieldAvailable,\n\t\t.dataType           = FIELDTYPE_STRING,\n\n\t},\n\t[FIELD_SIGNATURE - FIELD_ECTAGS_START] = {\n\t\t.letter\t\t\t\t= 'S',\n\t\t.name\t\t\t\t= \"signature\",\n\t\t.description\t\t= \"Signature of routine (e.g. prototype or parameter list)\",\n\t\t.enabled\t\t\t= false,\n\t\t.render\t\t\t\t= renderFieldSignature,\n\t\t.renderNoEscaping\t= renderFieldSignatureNoEscape,\n\t\t.doesContainAnyChar = doesContainAnyCharInSignature,\n\t\t.isValueAvailable\t= isSignatureFieldAvailable,\n\t\t.dataType\t\t\t= FIELDTYPE_STRING,\n\t\t.getterValueType    = NULL,\n\t\t.getValueObject     = getFieldValueForSignature,\n\t\t.setterValueType    = NULL,\n\t\t.checkValueForSetter= NULL,\n\t\t.setValueObject     = setFieldValueForSignature,\n\t},\n};\n\nstatic fieldDefinition fieldDefinitionsUniversal [] = {\n\t[FIELD_REF_MARK - FIELDS_UCTAGS_START] = {\n\t\t.letter             = 'R',\n\t\t.name\t\t\t\t= NULL,\n\t\t.description\t\t= \"Marker (R or D) representing whether tag is definition or reference\",\n\t\t.enabled\t\t\t= false,\n\t\t.render\t\t\t\t= renderFieldRefMarker,\n\t\t.renderNoEscaping\t= NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable\t= NULL,\n\t\t.dataType\t\t\t= FIELDTYPE_STRING,\n\t},\n\t[FIELD_SCOPE_KEY - FIELDS_UCTAGS_START] = {\n\t\t.letter             = 'Z',\n\t\t.name               = \"scope\",\n\t\t.description        = \"[tags output] prepend \\\"scope:\\\" key to s/scope field output, [xref and json output] the same as s/ field\",\n\t\t.enabled            = false,\n\t\t/* Following renderer is for handling --_xformat=%{scope};\n\t\t   and is not for tags output. */\n\t\t.render             = renderFieldScope,\n\t\t.renderNoEscaping   = renderFieldScopeNoEscape,\n\t\t.doesContainAnyChar = doesContainAnyCharInFieldScope,\n\t\t.isValueAvailable   = NULL,\n\t\t.dataType           = FIELDTYPE_STRING,\n\t\t.getterValueType    = \"int\",\n\t\t.getValueObject     = getFieldValueForScope,\n\t\t.setterValueType    = \"int\",\n\t\t.checkValueForSetter= checkFieldValueForScope,\n\t\t.setValueObject     = setFieldValueForScope,\n\t},\n\t[FIELD_SCOPE_KIND_LONG - FIELDS_UCTAGS_START] = {\n\t\t.letter\t\t\t\t= 'p',\n\t\t.name\t\t\t\t= \"scopeKind\",\n\t\t.description\t\t= \"[tags output] no effect, [xref and json output] kind of scope in long-name form\",\n\t\t.enabled\t\t\t= false,\n\t\t.render\t\t\t\t= renderFieldScopeKindName,\n\t\t.renderNoEscaping\t= NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable\t= NULL,\n\t\t.dataType\t\t\t= FIELDTYPE_STRING,\n\t},\n\t[FIELD_ROLES - FIELDS_UCTAGS_START] = {\n\t\t.letter             = 'r',\n\t\t.name               = \"roles\",\n\t\t.description        = \"Roles\",\n\t\t.enabled            = false,\n\t\t.render             = renderFieldRoles,\n\t\t.renderNoEscaping   = NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable   = NULL,\n\t\t.dataType           = FIELDTYPE_STRING,\n\t\t.getterValueType    = \"[ role1:name ... rolen:name ]\",\n\t\t.getValueObject     = getFieldValueForRoles,\n\t\t.setterValueType    = NULL,\n\t\t.checkValueForSetter= NULL,\n\t\t.setValueObject     = NULL,\n\t},\n\t[FIELD_EXTRAS - FIELDS_UCTAGS_START] = {\n\t\t.letter\t\t\t\t= 'E',\n\t\t.name\t\t\t\t= \"extras\",\n\t\t.description\t\t= \"Extra tag type information\",\n\t\t.enabled\t\t\t= false,\n\t\t.render\t\t\t\t= renderFieldExtras,\n\t\t.renderNoEscaping\t= NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable\t= isExtrasFieldAvailable,\n\t\t.dataType\t\t\t= FIELDTYPE_STRING,\n\t\t.getterValueType    = \"[ extra1:name ... extran:name ]\",\n\t\t.getValueObject     = getFieldValueForExtras,\n\t\t.setterValueType    = NULL,\n\t\t.checkValueForSetter= NULL,\n\t\t.setValueObject     = NULL,\n\t},\n\t[FIELD_XPATH - FIELDS_UCTAGS_START] = {\n\t\t.letter\t\t\t\t= 'x',\n\t\t.name\t\t\t\t= \"xpath\",\n\t\t.description\t\t= \"xpath for the tag\",\n\t\t.enabled\t\t\t= false,\n\t\t.render\t\t\t\t= renderFieldXpath,\n\t\t.renderNoEscaping\t= NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable\t= isXpathFieldAvailable,\n\t\t.dataType\t\t\t= FIELDTYPE_STRING,\n\t},\n\t[FIELD_END_LINE - FIELDS_UCTAGS_START] = {\n\t\t.letter\t\t\t\t= 'e',\n\t\t.name\t\t\t\t= \"end\",\n\t\t.description\t\t= \"end lines of various items\",\n\t\t.enabled\t\t\t= false,\n\t\t.render\t\t\t\t= renderFieldEnd,\n\t\t.renderNoEscaping\t= NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable\t= isEndFieldAvailable,\n\t\t.dataType\t\t\t= FIELDTYPE_INTEGER,\n\t\t.getterValueType    = \"int\",\n\t\t.getValueObject     = getFieldValueForLineCommon,\n\t\t.setterValueType    = \"matchloc|int\",\n\t\t.checkValueForSetter= checkFieldValueForLineCommon,\n\t\t.setValueObject     = setFieldValueForLineCommon,\n\n\t},\n\t[FIELD_EPOCH - FIELDS_UCTAGS_START] = {\n\t\t.letter\t\t\t\t= 'T',\n\t\t.name\t\t\t\t= \"epoch\",\n\t\t.description\t\t= \"the last modified time of the input file (only for F/file kind tag)\",\n\t\t.enabled\t\t\t= true,\n\t\t.render\t\t\t\t= renderFieldEpoch,\n\t\t.renderNoEscaping\t= NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable\t= isEpochAvailable,\n\t\t.dataType\t\t\t= FIELDTYPE_INTEGER,\n\t},\n\t[FIELD_NTH - FIELDS_UCTAGS_START] = {\n\t\t.letter\t\t\t\t= 'o',\n\t\t.name\t\t\t\t= \"nth\",\n\t\t.description\t\t= \"the order in the parent scope\",\n\t\t.enabled\t\t\t= false,\n\t\t.render\t\t\t\t= renderFieldNth,\n\t\t.renderNoEscaping\t= NULL,\n\t\t.doesContainAnyChar = NULL,\n\t\t.isValueAvailable\t= isNthAvailable,\n\t\t.dataType\t\t\t= FIELDTYPE_INTEGER,\n\t},\n};\n\n\nstatic unsigned int       fieldObjectUsed = 0;\nstatic unsigned int       fieldObjectAllocated = 0;\nstatic fieldObject* fieldObjects = NULL;\n\nextern void initFieldObjects (void)\n{\n\tunsigned int i;\n\tfieldObject *fobj;\n\n\tAssert (fieldObjects == NULL);\n\n\tfieldObjectAllocated\n\t  = ARRAY_SIZE (fieldDefinitionsFixed)\n\t  + ARRAY_SIZE (fieldDefinitionsExuberant)\n\t  + ARRAY_SIZE (fieldDefinitionsUniversal);\n\tfieldObjects = xMalloc (fieldObjectAllocated, fieldObject);\n\tDEFAULT_TRASH_BOX(&fieldObjects, eFreeIndirect);\n\n\tfieldObjectUsed = 0;\n\n\tfor (i = 0; i < ARRAY_SIZE (fieldDefinitionsFixed); i++)\n\t{\n\t\tfobj = fieldObjects + i + fieldObjectUsed;\n\t\tfobj->def = fieldDefinitionsFixed + i;\n\t\tfobj->buffer = NULL;\n\t\tfobj->nameWithPrefix = fobj->def->name;\n\t\tfobj->language = LANG_IGNORE;\n\t\tfobj->sibling  = FIELD_UNKNOWN;\n\t\tfobj->def->ftype = i + fieldObjectUsed;\n\t}\n\tfieldObjectUsed += ARRAY_SIZE (fieldDefinitionsFixed);\n\n\tfor (i = 0; i < ARRAY_SIZE (fieldDefinitionsExuberant); i++)\n\t{\n\t\tfobj = fieldObjects + i + fieldObjectUsed;\n\t\tfobj->def = fieldDefinitionsExuberant +i;\n\t\tfobj->buffer = NULL;\n\t\tfobj->nameWithPrefix = fobj->def->name;\n\t\tfobj->language = LANG_IGNORE;\n\t\tfobj->sibling  = FIELD_UNKNOWN;\n\t\tfobj->def->ftype = i + fieldObjectUsed;\n\t}\n\tfieldObjectUsed += ARRAY_SIZE (fieldDefinitionsExuberant);\n\n\tfor (i = 0; i < ARRAY_SIZE (fieldDefinitionsUniversal); i++)\n\t{\n\t\tchar *nameWithPrefix;\n\n\t\tfobj = fieldObjects + i + fieldObjectUsed;\n\t\tfobj->def = fieldDefinitionsUniversal + i;\n\t\tfobj->buffer = NULL;\n\n\t\tif (fobj->def->name)\n\t\t{\n\t\t\tnameWithPrefix = eMalloc (sizeof CTAGS_FIELD_PREFIX + strlen (fobj->def->name) + 1);\n\t\t\tnameWithPrefix [0] = '\\0';\n\t\t\tstrcat (nameWithPrefix, CTAGS_FIELD_PREFIX);\n\t\t\tstrcat (nameWithPrefix, fobj->def->name);\n\t\t\tfobj->nameWithPrefix = nameWithPrefix;\n\t\t\tDEFAULT_TRASH_BOX(nameWithPrefix, eFree);\n\t\t}\n\t\telse\n\t\t\tfobj->nameWithPrefix = NULL;\n\t\tfobj->language = LANG_IGNORE;\n\t\tfobj->sibling  = FIELD_UNKNOWN;\n\t\tfobj->def->ftype = i + fieldObjectUsed;\n\t}\n\tfieldObjectUsed += ARRAY_SIZE (fieldDefinitionsUniversal);\n\n\tAssert ( fieldObjectAllocated == fieldObjectUsed );\n}\n\nstatic fieldObject* getFieldObject(fieldType type)\n{\n\tAssert ((0 <= type) && ((unsigned int)type < fieldObjectUsed));\n\treturn fieldObjects + type;\n}\n\nextern fieldType getFieldTypeForLetter (char letter)\n{\n\tunsigned int i;\n\n\tfor (i = 0; i < fieldObjectUsed; i++)\n\t{\n\t\tif (fieldObjects [i].def->letter == letter)\n\t\t\treturn i;\n\t}\n\treturn FIELD_UNKNOWN;\n}\n\nextern fieldType getFieldTypeForName (const char *name)\n{\n\treturn getFieldTypeForNameAndLanguage (name, LANG_IGNORE);\n}\n\nextern fieldType getFieldTypeForNameAndLanguage (const char *fieldName, langType language)\n{\n\tstatic bool initialized = false;\n\tunsigned int i;\n\n\tif (fieldName == NULL)\n\t\treturn FIELD_UNKNOWN;\n\n\tif (language == LANG_AUTO && (initialized == false))\n\t{\n\t\tinitialized = true;\n\t\tinitializeParser (LANG_AUTO);\n\t}\n\telse if (language != LANG_IGNORE && (initialized == false))\n\t\tinitializeParser (language);\n\n\tfor (i = 0; i < fieldObjectUsed; i++)\n\t{\n\t\tif (fieldObjects [i].def->name\n\t\t    && strcmp (fieldObjects [i].def->name, fieldName) == 0\n\t\t    && ((language == LANG_AUTO)\n\t\t\t|| (fieldObjects [i].language == language)))\n\t\t\treturn i;\n\t}\n\n\treturn FIELD_UNKNOWN;\n}\n\nextern const char* getFieldDescription (fieldType type)\n{\n\tfieldObject* fobj;\n\n\tfobj = getFieldObject (type);\n\treturn fobj->def->description;\n}\n\nextern const char* getFieldName(fieldType type)\n{\n\tfieldObject* fobj;\n\n\tfobj = getFieldObject (type);\n\tif (Option.putFieldPrefix)\n\t\treturn fobj->nameWithPrefix;\n\telse\n\t\treturn fobj->def->name;\n}\n\nextern unsigned char getFieldLetter (fieldType type)\n{\n\tfieldObject* fobj = getFieldObject (type);\n\n\treturn fobj->def->letter == '\\0'\n\t\t? FIELD_NULL_LETTER_CHAR\n\t\t: fobj->def->letter;\n}\n\nextern bool doesFieldHaveValue (fieldType type, const tagEntryInfo *tag)\n{\n\tif (getFieldObject(type)->def->isValueAvailable)\n\t\treturn getFieldObject(type)->def->isValueAvailable(tag,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   getFieldObject(type)->def);\n\telse\n\t\treturn true;\n}\n\nstatic const char *renderAsIs (vString* b CTAGS_ATTR_UNUSED, const char *s)\n{\n\treturn s;\n}\n\nstatic const char *renderEscapedString (const char *s,\n\t\t\t\t\tconst tagEntryInfo *const tag CTAGS_ATTR_UNUSED,\n\t\t\t\t\tvString* b)\n{\n\tvStringCatSWithEscaping (b, s);\n\treturn vStringValue (b);\n}\n\nstatic const char *renderEscapedName (const bool isTagName,\n\t\t\t\t      const char* s,\n\t\t\t\t      const tagEntryInfo *const tag,\n\t\t\t\t      vString* b)\n{\n\tint unexpected_byte = 0;\n\n\tif (isTagName && (!tag->isPseudoTag) &&  (*s == ' ' || *s == '!'))\n\t{\n\t\t/* Don't allow a leading space or exclamation mark as it conflicts with\n\t\t * pseudo-tags when sorting.  Anything with a lower byte value is\n\t\t * escaped by renderEscapedString() already. */\n\t\tunexpected_byte = *s;\n\t\tswitch (*s)\n\t\t{\n\t\t\tcase ' ': vStringCatS (b, \"\\\\x20\"); s++; break;\n\t\t\tcase '!': vStringCatS (b, \"\\\\x21\"); s++; break;\n\t\t\tdefault: AssertNotReached();\n\t\t}\n\t}\n\telse\n\t{\n\t\t/* Find the first byte needing escaping for the warning message */\n\t\tconst char *p = s;\n\n\t\twhile (*p > 0x1F && *p != 0x7F)\n\t\t\tp++;\n\t\tunexpected_byte = *p;\n\t}\n\n\tif (unexpected_byte)\n\t{\n\t\tconst kindDefinition *kdef = getTagKind (tag);\n\t\tverbose (\"Unexpected character %#04x included in a tagEntryInfo: %s\\n\", unexpected_byte, s);\n\t\tverbose (\"File: %s, Line: %lu, Lang: %s, Kind: %c\\n\",\n\t\t\t tag->inputFileName, tag->lineNumber, getLanguageName(tag->langType), kdef->letter);\n\t\tverbose (\"Escape the character\\n\");\n\t}\n\n\treturn renderEscapedString (s, tag, b);\n}\n\nstatic const char *renderFieldName (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\treturn renderEscapedName (true, tag->name, tag, b);\n}\n\nstatic const char *renderFieldNameNoEscape (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\treturn renderAsIs (b, tag->name);\n}\n\nstatic bool doesContainAnyCharInName (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, const char *chars)\n{\n\treturn strpbrk (tag->name, chars)? true: false;\n}\n\nstatic const char *renderFieldInput (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\tconst char *f = tag->inputFileName;\n\n\tif (Option.lineDirectives && tag->sourceFileName)\n\t\tf = tag->sourceFileName;\n\treturn renderEscapedString (f, tag, b);\n}\n\nstatic const char *renderFieldInputNoEscape (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\tconst char *f = tag->inputFileName;\n\n\tif (Option.lineDirectives && tag->sourceFileName)\n\t\tf = tag->sourceFileName;\n\n\treturn renderAsIs (b, f);\n}\n\nstatic bool doesContainAnyCharInInput (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, const char *chars)\n{\n\tconst char *f = tag->inputFileName;\n\n\tif (Option.lineDirectives && tag->sourceFileName)\n\t\tf = tag->sourceFileName;\n\n\treturn strpbrk (f, chars)? true: false;\n}\n\nstatic const char *renderFieldSignature (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\treturn renderEscapedString (WITH_DEFAULT_VALUE (tag->extensionFields.signature),\n\t\t\t\t    tag, b);\n}\n\nstatic const char *renderFieldSignatureNoEscape (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\treturn renderAsIs (b, WITH_DEFAULT_VALUE (tag->extensionFields.signature));\n}\n\nstatic bool doesContainAnyCharInSignature (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, const char *chars)\n{\n\treturn (tag->extensionFields.signature && strpbrk(tag->extensionFields.signature, chars))\n\t\t? true\n\t\t: false;\n}\n\nstatic const char *renderFieldScope (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\tconst char* scope;\n\n\tgetTagScopeInformation ((tagEntryInfo *const)tag, NULL, &scope);\n\treturn scope? renderEscapedName (false, scope, tag, b): NULL;\n}\n\nstatic const char *renderFieldScopeNoEscape (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\tconst char* scope;\n\n\tgetTagScopeInformation ((tagEntryInfo *const)tag, NULL, &scope);\n\treturn scope? renderAsIs (b, scope): NULL;\n}\n\nstatic bool doesContainAnyCharInFieldScope (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, const char *chars)\n{\n\tconst char* scope;\n\n\tgetTagScopeInformation ((tagEntryInfo *const)tag, NULL, &scope);\n\treturn (scope && strpbrk (scope, chars));\n}\n\n\nstatic const char *renderFieldInherits (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\treturn renderEscapedString (WITH_DEFAULT_VALUE (tag->extensionFields.inheritance),\n\t\t\t\t    tag, b);\n}\n\nstatic const char *renderFieldTyperef (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\t/* Return \"-\" instead of \"-:-\". */\n\tif (tag->extensionFields.typeRef [0] == NULL\n\t\t&& tag->extensionFields.typeRef [1] == NULL)\n\t\treturn renderAsIs (b, FIELD_NULL_LETTER_STRING);\n\n\tvStringCatS (b, WITH_DEFAULT_VALUE (tag->extensionFields.typeRef [0]));\n\tvStringPut  (b, ':');\n\treturn renderEscapedName (false, WITH_DEFAULT_VALUE (tag->extensionFields.typeRef [1]), tag, b);\n}\n\n\nstatic const char* renderFieldCommon (fieldType type,\n\t\t\t\t\t\t\t\t\t  const tagEntryInfo *tag,\n\t\t\t\t\t\t\t\t\t  int index,\n\t\t\t\t\t\t\t\t\t  bool noEscaping)\n{\n\tfieldObject *fobj = fieldObjects + type;\n\tconst char *value;\n\tfieldRenderer rfn;\n\n\tAssert (tag);\n\tAssert (index < 0 || ((unsigned int)index) < tag->usedParserFields);\n\n\tif (index >= 0)\n\t{\n\t\tconst tagField *f = getParserFieldForIndex (tag, index);\n\n\t\tvalue = f->value;\n\t}\n\telse\n\t\tvalue = NULL;\n\n\tif (noEscaping)\n\t\trfn = fobj->def->renderNoEscaping;\n\telse\n\t\trfn = fobj->def->render;\n\tAssert (rfn);\n\n\tfobj->buffer = vStringNewOrClearWithAutoRelease (fobj->buffer);\n\treturn rfn (tag, value, fobj->buffer);\n}\n\nextern const char* renderField (fieldType type, const tagEntryInfo *tag, int index)\n{\n\treturn renderFieldCommon (type, tag, index, false);\n}\n\nextern const char* renderFieldNoEscaping (fieldType type, const tagEntryInfo *tag, int index)\n{\n\treturn renderFieldCommon (type, tag, index, true);\n}\n\nstatic bool defaultDoesContainAnyChar (const tagEntryInfo *const tag CTAGS_ATTR_UNUSED, const char* value, const char* chars)\n{\n\treturn strpbrk (value, chars)? true: false;\n}\n\nextern bool  doesFieldHaveTabOrNewlineChar (fieldType type, const tagEntryInfo *tag, int index)\n{\n\tfieldObject *fobj = fieldObjects + type;\n\tconst char *value;\n\tbool (* doesContainAnyChar) (const tagEntryInfo *const, const char*, const char*) = fobj->def->doesContainAnyChar;\n\n\tAssert (tag);\n\tAssert (index == NO_PARSER_FIELD || ((unsigned int)index) < tag->usedParserFields);\n\n\tif (doesContainAnyChar == NULL)\n\t{\n\t\tif (index == NO_PARSER_FIELD)\n\t\t\treturn false;\n\t\telse\n\t\t\tdoesContainAnyChar = defaultDoesContainAnyChar;\n\t}\n\n\tif (index >= 0)\n\t{\n\t\tconst tagField *f = getParserFieldForIndex (tag, index);\n\n\t\tvalue = f->value;\n\t}\n\telse\n\t\tvalue = NULL;\n\n\treturn (* doesContainAnyChar) (tag, value, \"\\t\\n\");\n}\n\n/*  Writes \"line\", stripping leading and duplicate white space.\n */\nstatic const char* renderCompactInputLine (vString *b,  const char *const line)\n{\n\tbool lineStarted = false;\n\n\t/*  Write everything up to, but not including, the newline.\n\t */\n\tfor (const char *p = line; *p != '\\n' && *p != '\\0'; ++p)\n\t{\n\t\tint c = (unsigned char) *p;\n\t\tif (lineStarted  || ! isspace (c))  /* ignore leading spaces */\n\t\t{\n\t\t\tlineStarted = true;\n\t\t\tif (isspace (c))\n\t\t\t{\n\t\t\t\tint next;\n\n\t\t\t\t/*  Consume repeating white space.\n\t\t\t\t */\n\t\t\t\twhile (next = (unsigned char) *(p+1), isspace (next) && next != '\\n')\n\t\t\t\t\t++p;\n\t\t\t\tc = ' ';  /* force space character for any white space */\n\t\t\t}\n\t\t\tif (c != '\\r'  ||  *(p + 1) != '\\n')\n\t\t\t\tvStringPut (b, c);\n\t\t}\n\t}\n\treturn vStringValue (b);\n}\n\nstatic const char *renderFieldKindName (const tagEntryInfo *const tag, const char *value CTAGS_ATTR_UNUSED, vString* b)\n{\n\tconst char* name = getTagKindName (tag);\n\treturn renderAsIs (b, name);\n}\n\nstatic const char *renderFieldCompactInputLine (const tagEntryInfo *const tag,\n\t\t\t\t\t\tconst char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t vString* b)\n{\n\tconst char *line;\n\tstatic vString *tmp;\n\n\tif (tag->isPseudoTag)\n\t{\n\t\tAssert (tag->pattern);\n\t\treturn tag->pattern;\n\t}\n\n\ttmp = vStringNewOrClearWithAutoRelease (tmp);\n\n\tline = readLineFromBypassForTag (tmp, tag, NULL);\n\tif (line)\n\t\trenderCompactInputLine (b, line);\n\telse\n\t{\n\t\t/* If no associated line for tag is found, we cannot prepare\n\t\t * parameter to writeCompactInputLine(). In this case we\n\t\t * use an empty string as LINE.\n\t\t */\n\t\tvStringClear (b);\n\t}\n\n\treturn vStringValue (b);\n}\n\nstatic const char *renderFieldLineNumber (const tagEntryInfo *const tag,\n\t\t\t\t\t  const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t\t  vString* b)\n{\n\tlong ln = tag->lineNumber;\n\tchar buf[32] = {[0] = '\\0'};\n\n\tif (Option.lineDirectives && (tag->sourceLineNumberDifference != 0))\n\t\tln += tag->sourceLineNumberDifference;\n\tsnprintf (buf, sizeof(buf), \"%ld\", ln);\n\tvStringCatS (b, buf);\n\treturn vStringValue (b);\n}\n\nstruct renderRoleData {\n\tvString* b;\n\tint nRoleWritten;\n};\n\nstatic void renderRoleByIndex (const tagEntryInfo *const tag, int roleIndex, void *data)\n{\n\tstruct renderRoleData *rdata = data;\n\n\tif (!isLanguageRoleEnabled (tag->langType, tag->kindIndex, roleIndex))\n\t\treturn;\n\n\tif (rdata->nRoleWritten > 0)\n\t\tvStringPut(rdata->b, ',');\n\n\tconst roleDefinition * role = getTagRole(tag, roleIndex);\n\trenderRole (role, rdata->b);\n\trdata->nRoleWritten++;\n}\n\nstatic roleBitsType foreachRoleBits (const tagEntryInfo *const tag,\n\t\t\t\t\t\t\t\t\t void (* fn) (const tagEntryInfo *const, int, void *),\n\t\t\t\t\t\t\t\t\t void *data)\n{\n\troleBitsType rbits = tag->extensionFields.roleBits;\n\tif (!rbits)\n\t\treturn rbits;\n\n\tint roleCount = countLanguageRoles (tag->langType, tag->kindIndex);\n\n\tfor (int roleIndex = 0; roleIndex < roleCount; roleIndex++)\n\t{\n\t\tif ((rbits >> roleIndex) & (roleBitsType)1)\n\t\t\tfn (tag, roleIndex, data);\n\t}\n\treturn rbits;\n}\n\nstatic const char *renderFieldRoles (const tagEntryInfo *const tag,\n\t\t\t\t    const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t    vString* b)\n{\n\tstruct renderRoleData data = { .b = b, .nRoleWritten = 0 };\n\n\tif (!foreachRoleBits (tag, renderRoleByIndex, &data))\n\t\tvStringCatS (b, ROLE_DEFINITION_NAME);\n\treturn vStringValue (b);\n}\n\nstatic const char *renderFieldLanguage (const tagEntryInfo *const tag,\n\t\t\t\t\tconst char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t\tvString* b)\n{\n\tconst char *l;\n\n\tif (Option.lineDirectives && (tag->sourceLangType != LANG_IGNORE))\n\t\tl = getLanguageName(tag->sourceLangType);\n\telse\n\t{\n\t\tAssert (tag->langType != LANG_IGNORE);\n\t\tl = getLanguageName(tag->langType);\n\t}\n\n\treturn renderAsIs (b, WITH_DEFAULT_VALUE(l));\n}\n\nstatic const char *renderFieldAccess (const tagEntryInfo *const tag,\n\t\t\t\t      const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t      vString* b)\n{\n\treturn renderAsIs (b, WITH_DEFAULT_VALUE (tag->extensionFields.access));\n}\n\nstatic const char *renderFieldKindLetter (const tagEntryInfo *const tag,\n\t\t\t\t\t  const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t\t  vString* b)\n{\n\tstatic char c[2] = { [1] = '\\0' };\n\n\tc [0] = getTagKindLetter(tag);\n\n\treturn renderAsIs (b, c);\n}\n\nstatic const char *renderFieldImplementation (const tagEntryInfo *const tag,\n\t\t\t\t\t      const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t\t      vString* b)\n{\n\treturn renderAsIs (b, WITH_DEFAULT_VALUE (tag->extensionFields.implementation));\n}\n\nstatic const char *renderFieldFile (const tagEntryInfo *const tag,\n\t\t\t\t    const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t    vString* b)\n{\n\treturn renderAsIs (b, tag->isFileScope? \"file\": FIELD_NULL_LETTER_STRING);\n}\n\nstatic const char *renderFieldPattern (const tagEntryInfo *const tag,\n\t\t\t\t       const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t       vString* b)\n{\n\tif (tag->isFileEntry)\n\t\treturn NULL;\n\telse if (tag->pattern)\n\t\tvStringCatS (b, tag->pattern);\n\telse\n\t{\n\t\tchar* tmp;\n\n\t\ttmp = makePatternString (tag);\n\t\tvStringCatS (b, tmp);\n\t\teFree (tmp);\n\t}\n\treturn vStringValue (b);\n}\n\nstatic const char *renderFieldRefMarker (const tagEntryInfo *const tag,\n\t\t\t\t\t const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t\t vString* b)\n{\n\tstatic char c[2] = { [1] = '\\0' };\n\n\tc [0] = (tag->extensionFields.roleBits)? 'R': 'D';\n\n\treturn renderAsIs (b, c);\n}\n\nstatic const char *renderFieldExtras (const tagEntryInfo *const tag,\n\t\t\t\t     const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t     vString* b)\n{\n\tunsigned int i;\n\tbool hasExtra = false;\n\tunsigned int c = countXtags();\n\n\tfor (i = 0; i < c; i++)\n\t{\n\t\tconst char *name = getXtagName (i);\n\n\t\tif (!name)\n\t\t\tcontinue;\n\n\t\tif (isTagExtraBitMarked (tag, i))\n\t\t{\n\n\t\t\tif (hasExtra)\n\t\t\t\tvStringPut (b, ',');\n\t\t\tvStringCatS (b, name);\n\t\t\thasExtra = true;\n\t\t}\n\t}\n\n\tif (hasExtra)\n\t\treturn vStringValue (b);\n\telse\n\t\treturn NULL;\n}\n\nstatic const char *renderFieldXpath (const tagEntryInfo *const tag,\n\t\t\t\t     const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t     vString* b)\n{\n#ifdef HAVE_LIBXML\n\tif (tag->extensionFields.xpath)\n\t\treturn renderEscapedString (tag->extensionFields.xpath,\n\t\t\t\t\t    tag, b);\n#endif\n\treturn NULL;\n}\n\nstatic const char *renderFieldScopeKindName(const tagEntryInfo *const tag,\n\t\t\t\t\t    const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t\t    vString* b)\n{\n\tconst char* kind;\n\n\tgetTagScopeInformation ((tagEntryInfo *const)tag, &kind, NULL);\n\treturn kind? renderAsIs (b, kind): NULL;\n}\n\nstatic const char *renderFieldEnd (const tagEntryInfo *const tag,\n\t\t\t\t   const char *value CTAGS_ATTR_UNUSED,\n\t\t\t\t   vString* b)\n{\n\tstatic char buf[21];\n\n\tif (getTagEndLine (tag) != 0)\n\t{\n\t\tsprintf (buf, \"%lu\", getTagEndLine (tag));\n\t\treturn renderAsIs (b, buf);\n\t}\n\telse\n\t\treturn NULL;\n}\n\nstatic const char *renderFieldEpoch (const tagEntryInfo *const tag,\n\t\t\t\t\t\t\t\t\t  const char *value, vString* b)\n{\n#define buf_len 21\n\tstatic char buf[buf_len];\n#ifdef _MSC_VER\n#define FMTLL \"%I64d\"\n#else\n#define FMTLL \"%lld\"\n#endif\n\tif (snprintf (buf, buf_len, FMTLL, (long long)tag->extensionFields.epoch) > 0)\n\t\treturn renderAsIs (b, buf);\n\telse\n\t\treturn NULL;\n#undef FMTLL\n#undef buf_len\n}\n\nstatic const char *renderFieldNth (const tagEntryInfo *const tag,\n\t\t\t\t\t\t\t\t   const char *value, vString* b)\n{\n#define buf_len 12\n\tstatic char buf[buf_len];\n\n\tif (tag->extensionFields.nth > NO_NTH_FIELD\n\t\t&& snprintf (buf, buf_len, \"%d\", (int)tag->extensionFields.nth) > 0)\n\t\treturn renderAsIs (b, buf);\n\telse\n\t\treturn NULL;\n#undef buf_len\n}\n\nstatic bool isTyperefFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n\treturn (tag->extensionFields.typeRef [0] != NULL\n\t\t&& tag->extensionFields.typeRef [1] != NULL)? true: false;\n}\n\nstatic bool isFileFieldAvailable  (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n\treturn tag->isFileScope? true: false;\n}\n\nstatic bool isInheritsFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n\treturn (tag->extensionFields.inheritance != NULL)? true: false;\n}\n\nstatic bool isAccessFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n\treturn (tag->extensionFields.access != NULL)? true: false;\n}\n\nstatic bool isImplementationFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n\treturn (tag->extensionFields.implementation != NULL)? true: false;\n}\n\nstatic bool isSignatureFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n\treturn (tag->extensionFields.signature != NULL)? true: false;\n}\n\nstatic bool isExtrasFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n\treturn isTagExtra (tag);\n}\n\nstatic bool isXpathFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n#ifdef HAVE_LIBXML\n\treturn (tag->extensionFields.xpath != NULL)? true: false;\n#else\n\treturn false;\n#endif\n}\n\nstatic bool isEndFieldAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n\treturn (getTagEndLine(tag) != 0)? true: false;\n}\n\nstatic bool isEpochAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n\treturn (tag->kindIndex == KIND_FILE_INDEX)\n\t\t? true\n\t\t: false;\n}\n\nstatic bool isNthAvailable (const tagEntryInfo *const tag, const fieldDefinition *fdef CTAGS_ATTR_UNUSED)\n{\n\tAssert (tag->langType >= NO_NTH_FIELD);\n\treturn (tag->extensionFields.nth != NO_NTH_FIELD)? true: false;\n}\n\nextern bool isFieldEnabled (fieldType type)\n{\n\treturn getFieldObject(type)->def->enabled;\n}\n\nextern bool enableField (fieldType type, bool state)\n{\n\tfieldDefinition *def = getFieldObject(type)->def;\n\tbool old = def->enabled;\n\tgetFieldObject(type)->def->enabled = state;\n\n\tif (isCommonField (type))\n\t\tverbose (\"enable field \\\"%s\\\": %s\\n\",\n\t\t\t\t getFieldObject(type)->def->name,\n\t\t\t\t (state? \"yes\": \"no\"));\n\telse\n\t\tverbose (\"enable field \\\"%s\\\"<%s>: %s\\n\",\n\t\t\t\t getFieldObject(type)->def->name,\n\t\t\t\t getLanguageName (getFieldLanguage(type)),\n\t\t\t\t (state? \"yes\": \"no\"));\n\treturn old;\n}\n\nextern bool isCommonField (fieldType type)\n{\n\treturn (FIELD_BUILTIN_LAST < type)? false: true;\n}\n\nextern langType getFieldLanguage (fieldType type)\n{\n\treturn getFieldObject(type)->language;\n}\n\nextern unsigned int getFieldDataType (fieldType type)\n{\n\treturn getFieldObject(type)->def->dataType;\n}\n\nextern bool isFieldValueAvailableAlways (fieldType type)\n{\n\treturn getFieldObject(type)->def->isValueAvailable == NULL;\n}\n\nextern bool doesFieldHaveRenderer (fieldType type, bool noEscaping)\n{\n\tif (noEscaping)\n\t\treturn getFieldObject(type)->def->renderNoEscaping? true: false;\n\telse\n\t\treturn getFieldObject(type)->def->render? true: false;\n}\n\nextern unsigned int countFields (void)\n{\n\treturn fieldObjectUsed;\n}\n\nextern fieldType nextSiblingField (fieldType type)\n{\n\tfieldObject *fobj;\n\n\tfobj = fieldObjects + type;\n\treturn fobj->sibling;\n}\n\nstatic void updateSiblingField (fieldType type, const char* name)\n{\n\tint i;\n\tfieldObject *fobj;\n\n\tfor (i = type; i > 0; i--)\n\t{\n\t\tfobj = fieldObjects + i - 1;\n\t\tif (fobj->def->name && (strcmp (fobj->def->name, name) == 0))\n\t\t{\n\t\t\tAssert (fobj->sibling == FIELD_UNKNOWN);\n\t\t\tfobj->sibling = type;\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic const char* defaultRenderer (const tagEntryInfo *const tag CTAGS_ATTR_UNUSED,\n\t\t\t\t    const char *value,\n\t\t\t\t    vString * buffer CTAGS_ATTR_UNUSED)\n{\n\treturn renderEscapedString (value, tag, buffer);\n}\n\nextern bool isValueAvailableGeneric (const tagEntryInfo *const e, const fieldDefinition *fdef)\n{\n\treturn getParserFieldValueForType(e, fdef->ftype)? true: false;\n}\n\nextern int defineField (fieldDefinition *def, langType language)\n{\n\tfieldObject *fobj;\n\tchar *nameWithPrefix;\n\tsize_t i;\n\n\tAssert (def);\n\tAssert (def->name);\n\tfor (i = 0; i < strlen (def->name); i++)\n\t{\n\t\tAssert ( isalpha ((unsigned char) def->name [i]) );\n\t}\n\tdef->letter = NUL_FIELD_LETTER;\n\n\tif (fieldObjectUsed == fieldObjectAllocated)\n\t{\n\t\tfieldObjectAllocated *= 2;\n\t\tfieldObjects = xRealloc (fieldObjects, fieldObjectAllocated, fieldObject);\n\t}\n\tfobj = fieldObjects + (fieldObjectUsed);\n\tdef->ftype = fieldObjectUsed++;\n\n\tif (def->render == NULL)\n\t{\n\t\tdef->render = defaultRenderer;\n\t\tdef->renderNoEscaping = NULL;\n\t\tdef->doesContainAnyChar = NULL;\n\t}\n\n\tif (! def->dataType)\n\t\tdef->dataType = FIELDTYPE_STRING;\n\n\tif (def->isValueAvailable == NULL)\n\t\tdef->isValueAvailable = isValueAvailableGeneric;\n\n\tfobj->def = def;\n\n\tfobj->buffer = NULL;\n\n\tnameWithPrefix = eMalloc (sizeof CTAGS_FIELD_PREFIX + strlen (def->name) + 1);\n\tnameWithPrefix [0] = '\\0';\n\tstrcat (nameWithPrefix, CTAGS_FIELD_PREFIX);\n\tstrcat (nameWithPrefix, def->name);\n\tfobj->nameWithPrefix = nameWithPrefix;\n\tDEFAULT_TRASH_BOX(nameWithPrefix, eFree);\n\n\tfobj->language = language;\n\tfobj->sibling  = FIELD_UNKNOWN;\n\n\tupdateSiblingField (def->ftype, def->name);\n\tinstallOptscriptFieldAccessor (def->ftype);\n\n\tif (def->version > getLanguageVersionCurrent (language))\n\t\terror (WARNING, \"the version number (%u) of field \\\"%s\\\" of language \\\"%s\\\" \"\n\t\t\t   \"should be less than or equal to the current number (%u) of the language\",\n\t\t\t   def->version, def->name, getLanguageName (language),\n\t\t\t   getLanguageVersionCurrent (language));\n\n\treturn def->ftype;\n}\n\n#define FIELD_COL_LETTER      0\n#define FIELD_COL_NAME        1\n#define FIELD_COL_ENABLED     2\n#define FIELD_COL_LANGUAGE    3\n#define FIELD_COL_JSTYPE      4\n#define FIELD_COL_FIXED       5\n#define FIELD_COL_OPERATOR    6\n#define FIELD_COL_DESCRIPTION 7\n\nextern struct colprintTable * fieldColprintTableNew (void)\n{\n\treturn colprintTableNew (\"L:LETTER\", \"L:NAME\", \"L:ENABLED\",\n\t\t\t\t\t\t\t \"L:LANGUAGE\", \"L:JSTYPE\", \"L:FIXED\",\n\t\t\t\t\t\t\t \"L:OP\", \"R:VER\", \"L:DESCRIPTION\", NULL);\n}\n\nstatic void  fieldColprintAddLine (struct colprintTable *table, int i)\n{\n\tfieldObject *fobj = getFieldObject(i);\n\tfieldDefinition *fdef = fobj->def;\n\n\tstruct colprintLine *line = colprintTableGetNewLine(table);\n\n\tcolprintLineAppendColumnChar (line,\n\t\t\t\t\t\t\t\t  (fdef->letter == NUL_FIELD_LETTER)\n\t\t\t\t\t\t\t\t  ? FIELD_NULL_LETTER_CHAR\n\t\t\t\t\t\t\t\t  : fdef->letter);\n\n\tconst char *name = getFieldName (i);\n\tcolprintLineAppendColumnCString (line, name? name: RSV_NONE);\n\tcolprintLineAppendColumnBool (line, fdef->enabled);\n\tcolprintLineAppendColumnCString (line,\n\t\t\t\t\t\t\t\t\t fobj->language == LANG_IGNORE\n\t\t\t\t\t\t\t\t\t ? RSV_NONE\n\t\t\t\t\t\t\t\t\t : getLanguageName (fobj->language));\n\n\tchar  typefields [] = \"---\";\n\t{\n\t\tunsigned int bmask, offset;\n\t\tunsigned int type = getFieldDataType(i);\n\t\tfor (bmask = 1, offset = 0;\n\t\t\t bmask < FIELDTYPE_END_MARKER;\n\t\t\t bmask <<= 1, offset++)\n\t\t\tif (type & bmask)\n\t\t\t\ttypefields[offset] = fieldDataTypeFlags[offset];\n\t}\n\tcolprintLineAppendColumnCString (line, typefields);\n\tcolprintLineAppendColumnBool (line, writerDoesTreatFieldAsFixed (i));\n\n\tchar operator[] = {'-', '-', '\\0'};\n\tif (fdef->getValueObject)\n\t\toperator[0] = 'r';\n\tif (fdef->setValueObject)\n\t\toperator[1] = 'w';\n\tcolprintLineAppendColumnCString (line, operator);\n\tcolprintLineAppendColumnVersion (line, fdef->version);\n\tcolprintLineAppendColumnCString (line, fdef->description);\n}\n\nextern void fieldColprintAddCommonLines (struct colprintTable *table)\n{\n\tfor (int i = 0; i <= FIELD_BUILTIN_LAST; i++)\n\t\tfieldColprintAddLine(table, i);\n}\n\nextern void fieldColprintAddLanguageLines (struct colprintTable *table, langType language)\n{\n\tfor (unsigned int i = FIELD_BUILTIN_LAST + 1; i < fieldObjectUsed; i++)\n\t{\n\t\tfieldObject *fobj = getFieldObject(i);\n\t\tif (fobj->language == language)\n\t\t\tfieldColprintAddLine (table, i);\n\t}\n}\n\nstatic int fieldColprintCompareLines (struct colprintLine *a , struct colprintLine *b)\n{\n\tconst char *a_fixed  = colprintLineGetColumn (a, FIELD_COL_FIXED);\n\tconst char *b_fixed  = colprintLineGetColumn (b, FIELD_COL_FIXED);\n\tconst char *a_parser = colprintLineGetColumn (a, FIELD_COL_LANGUAGE);\n\tconst char *b_parser = colprintLineGetColumn (b, FIELD_COL_LANGUAGE);\n\n\tif ((strcmp (a_fixed, \"yes\") == 0)\n\t\t&& (strcmp (b_fixed, \"yes\") == 0))\n\t{\n\t\t/* name, input, pattern, compact */\n\t\tconst char *a_name  = colprintLineGetColumn (a, FIELD_COL_NAME);\n\t\tconst char *b_name  = colprintLineGetColumn (b, FIELD_COL_NAME);\n\t\tconst char *ref_name;\n\t\tunsigned int a_index = ~0U;\n\t\tunsigned int b_index = ~0U;\n\n\t\tfor (unsigned int i = 0; i < ARRAY_SIZE(fieldDefinitionsFixed); i++)\n\t\t{\n\t\t\tref_name = fieldDefinitionsFixed [i].name;\n\t\t\tif (strcmp (a_name, ref_name) == 0)\n\t\t\t\ta_index = i;\n\t\t\tif (strcmp (b_name, ref_name) == 0)\n\t\t\t\tb_index = i;\n\t\t\tif ((a_index != ~0U) || (b_index != ~0U))\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (a_index < b_index)\n\t\t\treturn -1;\n\t\telse if (a_index == b_index)\n\t\t\treturn 0;\t\t\t/* ??? */\n\t\telse\n\t\t\treturn 1;\n\t}\n\telse if ((strcmp (a_fixed, \"yes\") == 0)\n\t\t\t  && (strcmp (b_fixed, \"yes\") != 0))\n\t\treturn -1;\n\telse if ((strcmp (a_fixed, \"yes\") != 0)\n\t\t\t && (strcmp (b_fixed, \"yes\") == 0))\n\t\treturn 1;\n\n\tif (strcmp (a_parser, RSV_NONE) == 0\n\t\t&& strcmp (b_parser, RSV_NONE) != 0)\n\t\treturn -1;\n\telse if (strcmp (a_parser, RSV_NONE) != 0\n\t\t\t && strcmp (b_parser, RSV_NONE) == 0)\n\t\treturn 1;\n\telse if (strcmp (a_parser, RSV_NONE) != 0\n\t\t\t && strcmp (b_parser, RSV_NONE) != 0)\n\t{\n\t\tint r;\n\t\tr = strcmp (a_parser, b_parser);\n\t\tif (r != 0)\n\t\t\treturn r;\n\n\t\tconst char *a_name = colprintLineGetColumn (a, FIELD_COL_NAME);\n\t\tconst char *b_name = colprintLineGetColumn (b, FIELD_COL_NAME);\n\n\t\treturn strcmp(a_name, b_name);\n\t}\n\telse\n\t{\n\t\tconst char *a_letter = colprintLineGetColumn (a, FIELD_COL_LETTER);\n\t\tconst char *b_letter = colprintLineGetColumn (b, FIELD_COL_LETTER);\n\n\t\treturn strcmp(a_letter, b_letter);\n\t}\n}\n\nextern void fieldColprintTablePrint (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\t bool withListHeader, bool machinable, FILE *fp)\n{\n\tcolprintTableSort (table, fieldColprintCompareLines);\n\tcolprintTablePrint (table, 0, withListHeader, machinable, fp);\n}\n\nextern const char * getFieldGetterValueType (fieldType type)\n{\n\tfieldObject *fobj = getFieldObject (type);\n\treturn (fobj? fobj->def->getterValueType: NULL);\n}\n\nextern EsObject * getFieldValue (fieldType type, const tagEntryInfo *tag)\n{\n\tfieldObject* fobj;\n\n\tfobj = getFieldObject (type);\n\tif (fobj && fobj->def->getValueObject)\n\t\treturn fobj->def->getValueObject (tag, fobj->def);\n\treturn es_nil;\n}\n\nextern bool hasFieldGetter (fieldType type)\n{\n\tfieldObject *fobj = getFieldObject (type);\n\treturn (fobj && fobj->def->getValueObject);\n}\n\nextern const char * getFieldSetterValueType (fieldType type)\n{\n\tfieldObject *fobj = getFieldObject (type);\n\treturn (fobj? fobj->def->setterValueType: NULL);\n}\n\nextern EsObject * setFieldValue (fieldType type, tagEntryInfo *tag, const EsObject *val)\n{\n\tfieldObject *fobj;\n\n\tfobj = getFieldObject (type);\n\tif (fobj && fobj->def->setValueObject)\n\t\treturn fobj->def->setValueObject (tag, fobj->def, val);\n\treturn es_false;\n}\n\nextern bool hasFieldSetter (fieldType type)\n{\n\tfieldObject *fobj = getFieldObject (type);\n\treturn (fobj && fobj->def->setValueObject);\n}\n\n\nextern bool hasFieldValueCheckerForSetter (fieldType type)\n{\n\tfieldObject *fobj = getFieldObject (type);\n\treturn (fobj && fobj->def->checkValueForSetter);\n}\n\nextern EsObject* checkFieldValueForSetter (fieldType type, const EsObject *val)\n{\n\tfieldObject *fobj = getFieldObject (type);\n\treturn fobj->def->checkValueForSetter (fobj->def, val);\n}\n\nstatic EsObject* getFieldValueForName (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\treturn opt_string_new_from_cstr (tag->name);\n}\n\nstatic EsObject* setFieldValueForName (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *val)\n{\n\teFree ((char*) tag->name);\n\tconst char *cstr = opt_string_get_cstr (val);\n\ttag->name = eStrdup (cstr);\n\treturn es_false;\n}\n\nstatic EsObject* getFieldValueForInput (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\treturn opt_string_new_from_cstr (tag->inputFileName);\n}\n\nstatic EsObject* getFieldValueForKind (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\tconst char *kind_name = getLanguageKindName (tag->langType, tag->kindIndex);\n\treturn opt_name_new_from_cstr (kind_name);\n}\n\nstatic EsObject* getFieldValueForLanguage (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\tconst char * lang_name = getLanguageName (tag->langType);\n\treturn opt_name_new_from_cstr (lang_name);\n}\n\nstatic EsObject* getFieldValueForTyperef (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\tif (tag->extensionFields.typeRef [0] == NULL\n\t\t&& tag->extensionFields.typeRef [1] == NULL)\n\t\treturn es_nil;\n\n\tEsObject *a = opt_array_new ();\n\tEsObject *e0 = tag->extensionFields.typeRef [0]\n\t\t? opt_string_new_from_cstr(tag->extensionFields.typeRef [0])\n\t\t: es_false;\n\tEsObject *e1 = tag->extensionFields.typeRef [1]\n\t\t? opt_string_new_from_cstr(tag->extensionFields.typeRef [1])\n\t\t: es_false;\n\topt_array_put (a, 0, e0);\n\topt_array_put (a, 1, e1);\n\tes_object_unref (e0);\n\tes_object_unref (e1);\n\treturn a;\n}\n\nstatic EsObject* setFieldValueForTyperef (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)\n{\n\tconst char *tmp[2] = {NULL, NULL};\n\n\tfor (int i = 0 ; i < 2; i++)\n\t{\n\t\tif (tag->extensionFields.typeRef [i])\n\t\t\ttmp [i] = tag->extensionFields.typeRef [i];\n\t}\n\n\tif (es_boolean_p (obj))\n\t{\n\t\tfor (int i = 0 ; i < 2; i++)\n\t\t{\n\t\t\tif (tag->extensionFields.typeRef [i])\n\t\t\t\ttag->extensionFields.typeRef [i] = NULL;\n\t\t}\n\t}\n\telse if (es_object_get_type (obj) == OPT_TYPE_ARRAY)\n\t{\n\t\tfor (int i = 0 ; i < 2; i++)\n\t\t{\n\t\t\tEsObject *e = opt_array_get (obj, i);\n\t\t\tif (es_boolean_p (e))\n\t\t\t{\n\t\t\t\tif (tag->extensionFields.typeRef [i])\n\t\t\t\t\ttag->extensionFields.typeRef [i] = NULL;\n\t\t\t}\n\t\t\telse if (es_object_get_type (e) == OPT_TYPE_STRING)\n\t\t\t{\n\t\t\t\ttag->extensionFields.typeRef [i] = eStrdup (opt_string_get_cstr (e));\n\t\t\t}\n\t\t}\n\t}\n\telse if (es_object_get_type (obj) == OPT_TYPE_STRING)\n\t{\n\t\tconst char *str = opt_string_get_cstr (obj);\n\t\ttag->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\ttag->extensionFields.typeRef [1] = eStrdup (str);\n\t}\n\telse if (es_integer_p (obj))\n\t{\n\t\tint index = es_integer_get (obj);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\tif (e)\n\t\t{\n\t\t\tconst char *name = e->name;\n\t\t\tconst char *kindName = getLanguageKindName (e->langType, e->kindIndex);\n\n\t\t\ttag->extensionFields.typeRef [0] = eStrdup (kindName);\n\t\t\ttag->extensionFields.typeRef [1] = eStrdup (name);\n\t\t}\n\t}\n\telse\n\t{\n\t\tAssertNotReached();\n\t\treturn OPT_ERR_TYPECHECK;\n\t}\n\n\tfor (int i = 0; i < 2; i++)\n\t\tif (tmp [i])\n\t\t\teFree ((char*)tmp[i]);\n\n\treturn es_false;\n}\n\nstatic EsObject* checkFieldValueForTyperef (const fieldDefinition *fdef, const EsObject *obj)\n{\n\tif (es_boolean_p (obj))\n\t{\n\t\tif (!es_object_equal (es_false, obj))\n\t\t\treturn OPT_ERR_TYPECHECK;\n\t}\n\telse if (es_object_get_type (obj) == OPT_TYPE_ARRAY)\n\t{\n\t\tif (opt_array_length (obj) != 2)\n\t\t\treturn OPT_ERR_TYPECHECK;\n\n\t\tfor (unsigned int i = 0; i < 2; i++)\n\t\t{\n\t\t\tEsObject *e = opt_array_get (obj, i);\n\t\t\tif (es_object_get_type (e) != OPT_TYPE_STRING)\n\t\t\t\treturn OPT_ERR_TYPECHECK;\n\t\t}\n\t}\n\telse if (es_object_get_type (obj) == OPT_TYPE_STRING)\n\t\t;\n\telse if (es_integer_p (obj))\n\t{\n\t\tint index0 = es_integer_get (obj);\n\t\tif (index0 < 0)\n\t\t\treturn OPT_ERR_RANGECHECK;\n\n\t\tunsigned int index = index0;\n\t\tif (index == 0 || index >= countEntryInCorkQueue ())\n\t\t\treturn OPTSCRIPT_ERR_NOTAGENTRY;\n\t}\n\telse\n\t\treturn OPT_ERR_TYPECHECK;\n\treturn es_false;\n}\n\nstatic EsObject* getFieldValueForScope (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\treturn es_integer_new (tag->extensionFields.scopeIndex);\n}\n\nstatic EsObject* setFieldValueForScope (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)\n{\n\tunsigned int index = es_integer_get (obj);\n\tif (index < countEntryInCorkQueue ())\n\t{\n\t\ttag->extensionFields.scopeIndex = (int)index;\n\t\treturn es_false;\n\t}\n\n\treturn OPTSCRIPT_ERR_NOTAGENTRY;\n}\n\nstatic EsObject* checkFieldValueForScope (const fieldDefinition *fdef, const EsObject *obj)\n{\n\tif (!es_integer_p (obj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tif (es_integer_get (obj) < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\treturn es_false;\n}\n\nstatic EsObject* getFieldValueForExtras (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\tif (!isTagExtra (tag))\n\t\treturn es_nil;\n\n\tEsObject* a = opt_array_new ();\n\n\tfor (unsigned int i = 0; i < countXtags (); i++)\n\t{\n\t\tif (!isTagExtraBitMarked (tag, i))\n\t\t\tcontinue;\n\n\t\tlangType lang = getXtagLanguage (i);\n\t\tconst char *lang_name = (lang == LANG_IGNORE)\n\t\t\t? NULL\n\t\t\t: getLanguageName (lang);\n\t\tconst char *extra_name = getXtagName (i);\n\n\t\tEsObject *extra;\n\t\tif (lang_name == NULL)\n\t\t\textra = opt_name_new_from_cstr (extra_name);\n\t\telse\n\t\t{\n\t\t\tvString *tmp = vStringNewInit (lang_name);\n\t\t\tvStringPut (tmp, '.');\n\t\t\tvStringCatS (tmp, extra_name);\n\t\t\textra = opt_name_new_from_cstr (vStringValue (tmp));\n\t\t\tvStringDelete (tmp);\n\t\t}\n\t\topt_array_add (a, extra);\n\t\tes_object_unref (extra);\n\t}\n\treturn a;\n}\n\nstatic EsObject* getFieldValueForCOMMON (const char *field, const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\tif (!field)\n\t\treturn es_nil;\n\treturn (opt_name_new_from_cstr (field));\n}\n\nstatic EsObject* setFieldValueForCOMMON (const char **field, tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)\n{\n\tif (*field)\n\t\teFree ((char *)*field);\n\n\tconst char *str = opt_string_get_cstr (obj);\n\t*field = eStrdup (str);\n\treturn es_false;\n}\n\nstatic EsObject* getFieldValueForAccess (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\treturn getFieldValueForCOMMON(tag->extensionFields.access, tag, fdef);\n}\n\nstatic EsObject* setFieldValueForAccess (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)\n{\n\treturn setFieldValueForCOMMON(&tag->extensionFields.access, tag, fdef, obj);\n}\n\nstatic EsObject* getFieldValueForSignature (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\treturn getFieldValueForCOMMON(tag->extensionFields.signature, tag, fdef);\n}\n\nstatic EsObject* setFieldValueForSignature (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)\n{\n\treturn setFieldValueForCOMMON(&tag->extensionFields.signature, tag, fdef, obj);\n}\n\nstatic void makeRolesArray (const tagEntryInfo *const tag, int roleIndex, void *data)\n{\n\tEsObject *a = data;\n\n\tconst roleDefinition *role = getTagRole (tag, roleIndex);\n\tEsObject *r = opt_name_new_from_cstr (role->name);\n\topt_array_add (a, r);\n\tes_object_unref (r);\n}\n\nstatic EsObject* getFieldValueForRoles (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\tEsObject *a = opt_array_new ();\n\n\tif (!foreachRoleBits (tag, makeRolesArray, a))\n\t{\n\t\tEsObject *r = opt_name_new_from_cstr (ROLE_DEFINITION_NAME);\n\t\topt_array_add (a, r);\n\t\tes_object_unref (r);\n\t}\n\treturn a;\n}\n\nstatic EsObject* getFieldValueForLineCommon (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\tif (fdef->ftype == FIELD_END_LINE)\n\t\treturn ((int)getTagEndLine (tag) == 0)\n\t\t\t? es_nil\n\t\t\t: es_integer_new ((int)getTagEndLine (tag));\n\telse\n\t\treturn ((int)tag->lineNumber == 0)\n\t\t\t? es_nil\n\t\t\t: es_integer_new ((int)tag->lineNumber);\n}\n\nstatic EsObject* checkFieldValueForLineCommon (const fieldDefinition *fdef, const EsObject *obj)\n{\n\treturn es_false;\n}\n\nstatic EsObject* setFieldValueForLineCommon (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)\n{\n\tunsigned int l;\n\tif (es_object_get_type (obj) == OPT_TYPE_MATCHLOC)\n\t{\n\t\tmatchLoc *loc = es_pointer_get (obj);\n\t\tl = loc->line;\n\t}\n\telse if (es_integer_p (obj))\n\t{\n\t\tint l0 = es_integer_get (obj);\n\t\tif (l0 < 1)\n\t\t\treturn OPT_ERR_RANGECHECK;\n\n\t\tl = (unsigned int)l0;\n\t\t/* If the new line number is too large,\n\t\t   we cannot fill tag->filePosition with\n\t\t   getInputFilePositionForLine(); */\n\t\tif (fdef->ftype == FIELD_LINE_NUMBER\n\t\t\t&& l > getInputLineNumber())\n\t\t\treturn OPT_ERR_RANGECHECK;\n\t}\n\telse\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tif (fdef->ftype == FIELD_END_LINE)\n\t\tsetTagEndLine(tag, (unsigned long)l);\n\telse\n\t\tupdateTagLine (tag, l, getInputFilePositionForLine (l));\n\n\treturn es_false;\n}\n\nstatic EsObject* setFieldValueForInherits (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)\n{\n\tif (es_object_get_type (obj) == OPT_TYPE_STRING)\n\t{\n\t\tif (tag->extensionFields.inheritance)\n\t\t\teFree ((void *)tag->extensionFields.inheritance);\n\t\tconst char *str = opt_string_get_cstr (obj);\n\t\ttag->extensionFields.inheritance = eStrdup (str);\n\t}\n\telse if (es_object_equal (es_false, obj))\n\t{\n\t\tif (tag->extensionFields.inheritance)\n\t\t{\n\t\t\teFree ((void *)tag->extensionFields.inheritance);\n\t\t\ttag->extensionFields.inheritance = NULL;\n\t\t}\n\t}\n\telse\n\t\treturn OPT_ERR_RANGECHECK; /* true is not acceptable. */\n\n\treturn es_false;\n}\n\nextern EsObject* getFieldValueGeneric (const tagEntryInfo *tag, const fieldDefinition *fdef)\n{\n\tconst char *value = getParserFieldValueForType(tag, fdef->ftype);\n\tunsigned int dt = fdef->dataType;\n\n\tif (dt & FIELDTYPE_STRING)\n\t{\n\t\tif (value == NULL)\n\t\t\treturn es_nil;\n\t\treturn (dt & FIELDTYPE_BOOL && value[0] == '\\0')\n\t\t\t? es_false\n\t\t\t: opt_string_new_from_cstr (value);\n\t}\n\telse if (dt & FIELDTYPE_INTEGER)\n\t{\n\t\tlong tmp;\n\n\t\tif (value == NULL)\n\t\t\treturn es_nil;\n\t\telse if (value[0] == '\\0')\n\t\t\ttmp = 0;\n\t\telse if (!strToLong (value, 10, &tmp))\n\t\t\ttmp = 1;\n\n\t\treturn es_integer_new ((int)tmp);\n\t}\n\telse if (dt & FIELDTYPE_BOOL)\n\t\treturn value? es_true: es_nil;\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn es_nil;\n\t}\n}\n\nextern EsObject* setFieldValueGeneric (tagEntryInfo *tag, const fieldDefinition *fdef, const EsObject *obj)\n{\n\tunsigned int dt = fdef->dataType;\n\tconst char * val;\n\tchar buf[1 /* [+-] */ + 20 + 1 /* for \\0 */];\n\n\tif (dt & FIELDTYPE_STRING)\n\t{\n\t\tif (es_object_get_type (obj) == OPT_TYPE_STRING)\n\t\t\tval = opt_string_get_cstr (obj);\n\t\telse if ((dt & FIELDTYPE_BOOL) && es_object_equal (es_false, obj))\n\t\t\tval = \"\";\n\t\telse\n\t\t\treturn OPT_ERR_TYPECHECK;\n\t}\n\telse if (dt & FIELDTYPE_INTEGER)\n\t{\n\t\tint tmp = es_integer_get (obj);\n\t\t/* 2^64 => \"18446744073709551616\" */\n\t\tsnprintf(buf, sizeof(buf), \"%d\", tmp);\n\t\tval = buf;\n\t}\n\telse if (dt & FIELDTYPE_BOOL)\n\t{\n\t\tif (es_boolean_get (obj))\n\t\t\tval = \"\";\n\t\telse\n\t\t{\n\t\t\tif (doesFieldHaveValue(fdef->ftype, tag))\n\t\t\t\treturn OPTSCRIPT_ERR_FIELDRESET;\n\t\t\tval = NULL;\n\t\t}\n\t}\n\telse\n\t{\n\t\tval = \"\";\n\t\tAssertNotReached ();\n\t}\n\n\tif (val)\n\t\tattachParserField (tag, fdef->ftype, val);\n\treturn es_false;\n}\n"
  },
  {
    "path": "main/field.h",
    "content": "/*\n *\n *  Copyright (c) 2015, Red Hat, Inc.\n *  Copyright (c) 2015, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_FIELD_H\n#define CTAGS_MAIN_FIELD_H\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"\n#include \"types.h\"\n\n#include \"vstring.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef enum eFieldType { /* extension field content control */\n\tFIELD_UNKNOWN = -1,\n\n\t/* BASIC FIELDS */\n\tFIELD_NAME,\n\tFIELD_INPUT_FILE,\n\tFIELD_PATTERN,\n\n\tFIELD_ECTAGS_START,\n\tFIELD_COMPACT_INPUT_LINE = FIELD_ECTAGS_START,\n\n\t/* EXTENSION FIELDS */\n\tFIELD_JSON_LOOP_START,\n\tFIELD_FILE_SCOPE = FIELD_JSON_LOOP_START,\n\tFIELD_KIND_LONG,\n\tFIELD_KIND,\n\tFIELD_LANGUAGE,\n\tFIELD_LINE_NUMBER,\n\tFIELD_SCOPE,\n\tFIELD_TYPE_REF,\n\tFIELD_KIND_KEY,\n\tFIELD_ECTAGS_LOOP_START,\n\tFIELD_INHERITANCE = FIELD_ECTAGS_LOOP_START,\n\tFIELD_ACCESS,\n\tFIELD_IMPLEMENTATION,\n\tFIELD_SIGNATURE,\n\tFIELD_ECTAGS_LOOP_LAST = FIELD_SIGNATURE,\n\n\t/* Extension fields newly introduced in Universal Ctags. */\n\tFIELDS_UCTAGS_START,\n\tFIELD_REF_MARK = FIELDS_UCTAGS_START,\n\tFIELD_SCOPE_KEY,\n\tFIELD_SCOPE_KIND_LONG,\n\tFIELD_UCTAGS_LOOP_START,\n\tFIELD_ROLES = FIELD_UCTAGS_LOOP_START,\n\tFIELD_EXTRAS,\n\tFIELD_XPATH,\n\tFIELD_END_LINE,\n\tFIELD_EPOCH,\n\tFIELD_NTH,\n\n\tFIELD_BUILTIN_LAST = FIELD_NTH,\n} fieldType ;\n\n#define fieldDataTypeFlags \"sib\" /* used in --list-fields */\ntypedef enum eFieldDataType {\n\tFIELDTYPE_STRING  = 1 << 0,\n\tFIELDTYPE_INTEGER = 1 << 1,\n\tFIELDTYPE_BOOL    = 1 << 2,\n\n\t/* used in --list-fields */\n\tFIELDTYPE_END_MARKER = 1 << 3,\n\n\t/* If you want to allow a field to be accessed from code\n\t * written in optscript, append FIELDTYPE_SCRIPTABLE to\n\t * dataType member of the field's fieldDefinition.\n\t *\n\t * For the field defined in optlib, set {datatype=TYPE} flag to\n\t * --_fielddef-<LANG>=... option. Just specifying a type is\n\t * enough; FIELDTYPE_SCRIPTABLE is automatically append to the\n\t * filed definition. If you don't set the flag explicitly,\n\t * FIELDTYPE_SCRIPTABLE is not appended. */\n\tFIELDTYPE_SCRIPTABLE = FIELDTYPE_END_MARKER,\n} fieldDataType;\n/* Interpretation of VALUE of field\n *\n * With attachParserField() declared in entry.h, you can set a C string\n * as a VALUE for the specified field.\n *\n * The VALUE is interpreted very differently depending on the output\n * format: ctags, xref, and json.\n *\n * For FIELDTYPE_STRING\n * =====================================================================\n *\n * output and getter\n * ---------------------------------------------------------------------\n *\n * Consider if you set \"str\" to the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | foo:str\n *   xref | str\n *   json | \"foo\": \"str\"\n * -------+-------------\n *   :foo | (foo) => (foo) true\n *\n * Consider if you set \"\" to the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | foo:\n *   xref | (nothing)\n *   json | \"foo\": \"\"\n * -------+-------------\n *   :foo | () => () true\n *\n * Consider if you don't set the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | (nothing)\n *   xref | (nothing)\n *   json | (nothing)\n * -------+-------------\n *   :foo | null => false\n *\n * setter\n * ---------------------------------------------------------------------\n *\n *     stack | C sting stored to the field\n * ----------+----------------------------\n *   . (str) | \"str\"\n *      . () | \"\"\n *  . object | ERROR:typecheck\n *\n *\n * For FIELDTYPE_STRING|FIELDTYPE_BOOL\n * =====================================================================\n *\n * output and getter\n * ---------------------------------------------------------------------\n *\n * If a field holds \"\" (empty C string), the json writer prints it as\n * false, and the xref writer prints it as -.  In the xref format,\n * there is no way to distinguish the output for the value \"\" and\n * \"-\". Both are printed as \"-\".  If the value is a non-empty C\n * string, Both json writer and xref writer print it as-is.\n *\n * Consider if you set \"str\" to the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | foo:str\n *   xref | str\n *   json | \"foo\": \"str\"\n * -------+-------------\n *   :foo | (str) => (str) true\n *\n * Consider if you set \"\" to the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | foo:\n *   xref | - (as specified as FIELD_NULL_LETTER_CHAR/FIELD_NULL_LETTER_STRING)\n *   json | \"foo\": false\n * -------+-------------\n *   :foo | false => false true\n *\n * Consider if you don't set the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | (nothing)\n *   xref | (nothing)\n *   json | (nothing)\n * -------+-------------\n *   :foo | null => false\n *\n * setter\n * ---------------------------------------------------------------------\n *\n *     stack | C sting stored to the field\n * ----------+----------------------------\n *   . (str) | \"str\"\n *      . () | \"\"\n *   . false | \"\"\n *    . true | ERROR:typecheck\n *  . object | ERROR:typecheck\n *\n *\n * For FIELDTYPE_BOOL\n * =====================================================================\n *\n * output and getter\n * ---------------------------------------------------------------------\n *\n * Whether a field holds \"\" (an empty C string) or a non-epmty C string,\n * the json writer prints it as true. In the same condition, the xref\n * writer prints the name of the field.\n *\n * If a value is not set, the field is treated as if it holds false.\n * The json writer prints nothing for the field holding false.\n * The xref writer prints - for the field holding false.\n\n * Consider if you set \"str\" to the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | foo:\n *   xref | foo\n *   json | \"foo\": true\n * -------+-------------\n *   :foo | true => true true\n *\n * Consider if you set \"\" to the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | foo:\n *   xref | foo\n *   json | \"foo\": true\n * -------+-------------\n *   :foo | true => true true\n *\n * Consider if you don't set the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | (nothing)\n *   xref | - (as specified as FIELD_NULL_LETTER_CHAR/FIELD_NULL_LETTER_STRING)\n *   json | (nothing)\n * -------+-------------\n *   :foo | null => false\n *\n * setter\n * ---------------------------------------------------------------------\n *\n *     stack | C sting stored to the field\n * ----------+----------------------------\n *   . false | do nothing if the field was not set.\n *           | ERROR:fieldreset if the field was already set.\n *           |                  This is a limit of current implementation.\n *    . true | \"\"\n *  . object | ERROR:typecheck\n *\n *\n * For FIELDTYPE_INTEGER\n * =====================================================================\n *\n * output and getter\n * ---------------------------------------------------------------------\n *\n * If a field holds \"\" (an empty C string), the all writers print it as\n * 0. If a field holds a string that strtol(3) cannot convert to an integer,\n * all the writers print it as 1.\n *\n * Consider if you set \"99\" to the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | foo:99\n *   xref | 99\n *   json | \"foo\": 99\n * -------+-------------\n *   :foo | 99 => 99 true\n\n * Consider if you set \"str\" to the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | foo:1\n *   xref | 1\n *   json | \"foo\": 1\n * -------+-------------\n *   :foo | 1 => 1 true\n\n * Consider if you set \"\" to the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-------------\n *  ctags | foo:0\n *   xref | 0\n *   json | \"foo\": 0\n * -------+-------------\n *   :foo | 0 => 0 true\n *\n * Consider if you don't set the field \"foo\":\n *\n * WRITER | OUTPUT\n * -------+-----------\n *  ctags | (nothing)\n *   xref | (nothing)\n *   json | (nothing)\n * -------+-------------\n *   :foo | null => false\n *\n * setter\n * ---------------------------------------------------------------------\n *\n *     stack | C sting stored to the field\n * ----------+----------------------------\n *     . int | int\n *       . 1 | \"1\" (as an example)\n *  . object | ERROR:typecheck\n *\n *\n * The other data types and the combinations of types are not implemented yet.\n *\n */\n\ntypedef const char* (*fieldRenderer)(const tagEntryInfo *const,\n\t\t\t\t\t\t\t\t\t const char *,\n\t\t\t\t\t\t\t\t\t vString *);\n\nstruct sFieldDefinition {\n\t/* letter, and ftype are initialized in the main part,\n\t   not in a parser. */\n#define NUL_FIELD_LETTER '\\0'\n\tunsigned char letter;\n\tconst char* name;\n\tconst char* description;\n\tbool enabled;\n\n\tfieldRenderer render;\n\tfieldRenderer renderNoEscaping;\n\tbool (* doesContainAnyChar) (const tagEntryInfo *const, const char*, const char *);\n\n\tbool (* isValueAvailable) (const tagEntryInfo *const, const fieldDefinition *);\n\n\tconst char * getterValueType; /* used in --_list-operators */\n\tstruct _EsObject * (* getValueObject) (const tagEntryInfo *, const fieldDefinition *);\n\tconst char * setterValueType; /* used in --_list-operators */\n\n\t/* Return es_false if passed value is acceptable.\n\t   Return an error object is unacceptable. */\n\tstruct _EsObject * (* checkValueForSetter) (const fieldDefinition *, const struct _EsObject *);\n\tstruct _EsObject * (* setValueObject) (tagEntryInfo *, const fieldDefinition *, const struct _EsObject *);\n\n\tfieldDataType dataType; /* used in json output. See OP column in --list-fields. */\n\n\tunsigned int    version;\n\n\tunsigned int ftype;\t/* Given from the main part */\n};\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern bool isFieldEnabled (fieldType type);\n\nextern bool isValueAvailableGeneric (const tagEntryInfo *const tag, const fieldDefinition *fdef);\nextern struct _EsObject* getFieldValueGeneric (const tagEntryInfo *tag, const fieldDefinition *fdef);\nextern struct _EsObject* setFieldValueGeneric (tagEntryInfo *tag, const fieldDefinition *fdef, const struct _EsObject *obj);\n\n#endif\t/* CTAGS_MAIN_FIELD_H */\n"
  },
  {
    "path": "main/field_p.h",
    "content": "/*\n *\n *  Copyright (c) 2015, Red Hat, Inc.\n *  Copyright (c) 2015, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_FIELD_PRIVATE_H\n#define CTAGS_MAIN_FIELD_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n#include \"colprint_p.h\"\n#include \"field.h\"\n#include \"optscript.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\n\n#define FIELD_NULL_LETTER_CHAR '-'\n#define FIELD_NULL_LETTER_STRING \"-\"\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern fieldType getFieldTypeForLetter (char letter);\n\n/*\n   `getFieldTypeForName' is for looking for a field not owned by any parser,\n\n   `getFieldTypeForNameAndLanguage' can be used for getting all fields having\n   the same name; specify `LANG_AUTO' as `language' parameter to get the first\n   field having the name. With the returned fieldType, `nextSiblingField' gets\n   the next field having the same name. `nextSiblingField' returns `FIELD_UNKNOWN'\n   at the end of iteration.\n\n   Specifying `LANG_IGNORE' has the same effects as `LANG_AUTO'. However,\n   internally, each parser is not initialized. `LANG_IGNORE' is a bit faster. */\nextern fieldType getFieldTypeForName (const char *name);\nextern fieldType getFieldTypeForNameAndLanguage (const char *fieldName, langType language);\nextern bool enableField (fieldType type, bool state);\nextern bool isCommonField (fieldType type);\n\n/* Return LANG_IGNORE if the field is a common field.*/\nextern langType getFieldLanguage (fieldType type);\n\nextern const char* getFieldDescription (fieldType type);\nextern const char* getFieldName (fieldType type);\nextern unsigned char getFieldLetter (fieldType type);\nextern unsigned int getFieldDataType (fieldType type);\nextern bool isFieldValueAvailableAlways (fieldType type);\n\n/* Whether the field specified with TYPE has a\n   method for rendering in the current format. */\nextern bool doesFieldHaveRenderer (fieldType type, bool noEscaping);\n\nextern bool doesFieldHaveValue (fieldType type, const tagEntryInfo *tag);\n\nextern const char* renderField (fieldType type, const tagEntryInfo *tag, int index);\nextern const char* renderFieldNoEscaping (fieldType type, const tagEntryInfo *tag, int index);\nextern bool  doesFieldHaveTabOrNewlineChar (fieldType type, const tagEntryInfo *tag, int index);\n\nextern void initFieldObjects (void);\nextern unsigned int countFields (void);\n\n/* language should be typed to langType.\n   Use int here to avoid circular dependency */\nextern int defineField (fieldDefinition *spec, langType language);\nextern fieldType nextSiblingField (fieldType type);\n\n/* --list-fields implementation. LANGUAGE must be initialized. */\nextern struct colprintTable * fieldColprintTableNew (void);\nextern void fieldColprintAddCommonLines (struct colprintTable *table);\nextern void fieldColprintAddLanguageLines (struct colprintTable *table, langType language);\nextern void fieldColprintTablePrint (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\t bool withListHeader, bool machinable, FILE *fp);\n\n/* tag is assumed that it is in the cork queue. */\nextern EsObject * getFieldValue (fieldType type, const tagEntryInfo *tag);\nextern bool hasFieldGetter (fieldType type);\nextern const char * getFieldGetterValueType (fieldType type);\nextern EsObject * setFieldValue (fieldType type, tagEntryInfo *tag, const EsObject *val);\nextern bool hasFieldSetter (fieldType type);\nextern const char * getFieldSetterValueType (fieldType type);\nextern bool hasFieldValueCheckerForSetter (fieldType type);\nextern EsObject *checkFieldValueForSetter (fieldType type, const EsObject *val);\n\n#endif\t/* CTAGS_MAIN_FIELD_PRIVATE_H */\n"
  },
  {
    "path": "main/flags.c",
    "content": "/*\n*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions to process command line options.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <stdio.h>\n\n#include \"ctags.h\"\n#include \"flags_p.h\"\n#include \"vstring.h\"\n#include \"routines.h\"\n\nextern const char *flagsEval (const char* flags_original, flagDefinition* defs, unsigned int ndefs, void* data)\n{\n\tunsigned int i, j;\n\tchar *flags;\n\tconst char *optscript = NULL;\n\n\tif (!flags_original)\n\t\treturn NULL;\n\n\tflags = eStrdup (flags_original);\n\tfor (i = 0 ; flags [i] != '\\0' ; ++i)\n\t{\n\t\tif (flags [i] == LONG_FLAGS_OPEN && flags [i + 1] == LONG_FLAGS_OPEN)\n\t\t{\n\t\t\toptscript = flags_original + i;\n\t\t\tbreak;\n\t\t}\n\t\telse if (flags [i] == LONG_FLAGS_OPEN)\n\t\t{\n\t\t\tconst char* aflag = flags + i + 1;\n\t\t\tchar* needle_close_paren = strchr(aflag, LONG_FLAGS_CLOSE);\n\t\t\tconst char* param;\n\t\t\tchar* needle_equal;\n\n\t\t\tif (needle_close_paren == NULL)\n\t\t\t{\n\t\t\t\terror (WARNING, \"long flags specifier opened with `%c' is not closed `%c': \\\"%s\\\"\",\n\t\t\t\t       LONG_FLAGS_OPEN, LONG_FLAGS_CLOSE, flags_original);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t*needle_close_paren = '\\0';\n\t\t\tneedle_equal = strchr(aflag, '=');\n\t\t\tif ((needle_equal == NULL || (needle_equal >= needle_close_paren)))\n\t\t\t{\n\t\t\t\tneedle_equal = NULL;\n\t\t\t\tparam = NULL;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tparam = needle_equal + 1;\n\t\t\t\t*needle_equal = '\\0';\n\t\t\t}\n\n\t\t\tfor ( j = 0 ; j < ndefs ; ++j )\n\t\t\t\tif (defs[j].longStr && (strcmp(aflag, defs[j].longStr) == 0))\n\t\t\t\t\tdefs[j].longProc(aflag, param, data);\n\n\t\t\tif (needle_equal)\n\t\t\t\t*needle_equal = '=';\n\t\t\t*needle_close_paren = LONG_FLAGS_CLOSE;\n\n\t\t\ti = needle_close_paren - flags;\n\t\t}\n\t\telse for (j = 0 ; j < ndefs ; ++j)\n\t\t\tif (flags[i] == defs[j].shortChar)\n\t\t\t\tdefs[j].shortProc(flags[i], data);\n\t}\n\teFree (flags);\n\treturn optscript;\n}\n\nextern struct colprintTable * flagsColprintTableNew (void)\n{\n\treturn colprintTableNew (\"L:LETTER\", \"L:NAME\", \"L:DESCRIPTION\", NULL);\n}\n\nextern void flagsColprintAddDefinitions (struct colprintTable *table, flagDefinition* def,\n\t\t\t\t\t\t\t\t\t\t unsigned int ndefs)\n{\n\tvString *longName = vStringNew ();\n\n\tfor (unsigned int i = 0; i < ndefs; i++)\n\t{\n\t\tstruct colprintLine * line;\n\t\tchar shortChar;\n\t\tconst char *paramName;\n\t\tconst char *description;\n\n\n\t\tline = colprintTableGetNewLine(table);\n\n\t\tshortChar = def[i].shortChar;\n\t\tif (shortChar == '\\0')\n\t\t\tshortChar = '-';\n\t\tcolprintLineAppendColumnChar (line, shortChar);\n\n\t\tvStringCopyS (longName, def[i].longStr? def[i].longStr: RSV_NONE);\n\t\tparamName = def[i].paramName;\n\t\tif (paramName)\n\t\t{\n\t\t\tvStringPut (longName, '=');\n\t\t\tvStringCatS (longName, paramName);\n\t\t}\n\t\tcolprintLineAppendColumnVString (line, longName);\n\t\tvStringClear(longName);\n\n\t\tdescription = def[i].description? def[i].description: \"\";\n\t\tcolprintLineAppendColumnCString (line, description);\n\t}\n\n\tvStringDelete(longName);\n}\n\nstatic int flagsColprintCompareLines(struct colprintLine *a , struct colprintLine *b)\n{\n\tconst char *a_letter = colprintLineGetColumn (a, 0);\n\tconst char *b_letter = colprintLineGetColumn (b, 0);\n\n\tif (a_letter[0] != '-' && b_letter[0] == '-')\n\t\treturn -1;\n\telse if (a_letter[0] == '-' && b_letter[0] != '-')\n\t\treturn 1;\n\telse if (a_letter[0] != '-' && b_letter[0] != '-')\n\t\treturn strcmp(a_letter, b_letter);\n\n\n\tconst char *a_name = colprintLineGetColumn (a, 1);\n\tconst char *b_name = colprintLineGetColumn (b, 1);\n\n\tif (a_name[0] != '_' && b_name[0] == '_')\n\t\treturn -1;\n\telse if (a_name[0] == '_' && b_name[0] != '_')\n\t\treturn 1;\n\n\treturn strcmp(a_name, b_name);\n}\n\nextern void flagsColprintTablePrint (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\t bool withListHeader, bool machinable, FILE *fp)\n{\n\tcolprintTableSort (table, flagsColprintCompareLines);\n\tcolprintTablePrint (table, 0, withListHeader, machinable, fp);\n}\n"
  },
  {
    "path": "main/flags_p.h",
    "content": "/*\n*\n*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines external interface to option processing.\n*/\n#ifndef CTAGS_MAIN_FLAGS_PRIVATE_H\n#define CTAGS_MAIN_FLAGS_PRIVATE_H\n\n#include \"general.h\"\n#include \"colprint_p.h\"\n\n\n#define LONG_FLAGS_OPEN  '{'\n#define LONG_FLAGS_CLOSE '}'\n\ntypedef struct sFlagDefinition {\n\tchar shortChar;\n\tconst char *longStr;\n\tvoid (* shortProc) (char c,  void *data);\n\tvoid (* longProc)  (const char* const s, const char* const param, void *data);\n\tconst char *paramName;\n\tconst char *description;\n} flagDefinition;\n\n/* Return {{optscript}} part. */\nextern const char*  flagsEval (const char* flags, flagDefinition* defs, unsigned int ndefs, void* data);\nextern struct colprintTable * flagsColprintTableNew (void);\nextern void flagsColprintAddDefinitions (struct colprintTable *table, flagDefinition* def, unsigned int ndefs);\nextern void flagsColprintTablePrint (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\t bool withListHeader, bool machinable, FILE *fp);\n#endif\t/* CTAGS_MAIN_FLAGS_PRIVATE_H */\n"
  },
  {
    "path": "main/fmt.c",
    "content": "/*\n *\n *  Copyright (c) 2015, Red Hat, Inc.\n *  Copyright (c) 2015, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#include \"general.h\"\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"fmt_p.h\"\n#include \"field.h\"\n#include \"field_p.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include <string.h>\n#include <errno.h>\n\ntypedef union uFmtSpec {\n\tchar *const_str;\n\tstruct {\n\t\tfieldType ftype;\n\t\tint width;\n\t\tchar *raw_fmtstr;\n\t} field;\n} fmtSpec;\n\nstruct sFmtElement {\n\tunion uFmtSpec spec;\n\tint (* printer) (fmtSpec*, MIO* fp, const tagEntryInfo *);\n\tstruct sFmtElement *next;\n};\n\nstatic int printLiteral (fmtSpec* fspec, MIO* fp, const tagEntryInfo * tag CTAGS_ATTR_UNUSED)\n{\n\treturn mio_puts (fp, fspec->const_str);\n}\n\nstatic bool isParserFieldCompatibleWithFtype (const tagField *pfield, int baseFtype)\n{\n\tdo {\n\t\tif (pfield->ftype == baseFtype)\n\t\t\treturn true;\n\t\tbaseFtype = nextSiblingField (baseFtype);\n\t} while (baseFtype != FIELD_UNKNOWN);\n\treturn false;\n}\n\nstatic int printTagField (fmtSpec* fspec, MIO* fp, const tagEntryInfo * tag)\n{\n\tint i;\n\tint width = fspec->field.width;\n\tfieldType ftype;\n\tconst char* str = NULL;\n\n\tftype = fspec->field.ftype;\n\n\tif (isCommonField (ftype))\n\t\tstr = renderField (ftype, tag, NO_PARSER_FIELD);\n\telse\n\t{\n\t\tunsigned int findex;\n\t\tconst tagField *f = NULL;\n\n\t\tfor (findex = 0; findex < tag->usedParserFields; findex++)\n\t\t{\n\t\t\tf = getParserFieldForIndex(tag, findex);\n\t\t\tif (isParserFieldCompatibleWithFtype (f, ftype))\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( /* No parser specific field is attached. */\n\t\t\tf == NULL\n\t\t\t/* Any parser specific fields attached to the tag doesn't compatible\n\t\t\t * with the spec specified in the format string. */\n\t\t\t||  findex == tag->usedParserFields)\n\t\t{\n\t\t\tstr = \"\";\n\n\t\t\tunsigned int dt = getFieldDataType (ftype);\n\t\t\tif ((dt & FIELDTYPE_STRING) == 0\n\t\t\t\t&& (dt & FIELDTYPE_BOOL))\n\t\t\t\tstr = FIELD_NULL_LETTER_STRING;\n\t\t}\n\n\t\telse if (isFieldEnabled (f->ftype))\n\t\t{\n\t\t\tunsigned int dt = getFieldDataType (f->ftype);\n\t\t\tif (dt & FIELDTYPE_STRING)\n\t\t\t{\n\t\t\t\tstr = renderField (f->ftype, tag, findex);\n\t\t\t\tif ((dt & FIELDTYPE_BOOL) && str[0] == '\\0')\n\t\t\t\t\tstr = FIELD_NULL_LETTER_STRING;\n\t\t\t}\n\t\t\telse if (dt & FIELDTYPE_BOOL)\n\t\t\t\tstr = getFieldName (f->ftype);\n\t\t\telse if (dt & FIELDTYPE_INTEGER)\n\t\t\t{\n\t\t\t\tlong unused;\n\n\t\t\t\tstr = renderField (f->ftype, tag, findex);\n\t\t\t\tif (!strToLong (str, 10, &unused))\n\t\t\t\t\tstr = (str[0] == '\\0'? \"0\": \"1\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* Not implemented */\n\t\t\t\tAssertNotReached ();\n\t\t\t\tstr = \"CTAGS INTERNAL BUG!\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif (str == NULL)\n\t\tstr = \"\";\n\n\tif (width)\n\t\ti = mio_printf (fp, fspec->field.raw_fmtstr, width, str);\n\telse\n\t{\n\t\tmio_puts (fp, str);\n\t\ti = strlen (str);\n\t}\n\treturn i;\n}\n\nstatic fmtElement** queueLiteral (fmtElement **last, char *literal)\n{\n\tfmtElement *cur = xMalloc (1, fmtElement);\n\n\tcur->spec.const_str = literal;\n\tcur->printer = printLiteral;\n\tcur->next = NULL;\n\t*last = cur;\n\treturn &(cur->next);\n}\n\n/* `getLanguageComponentInFieldName' is used as part of the option parameter\n   for --_xformat option.\n\n   It splits the value of fullName into a language part and a field name part.\n   Here the two parts are combined with `.'.\n\n   If it cannot find a period, it returns LANG_IGNORE and sets\n   fullName to *fieldName.\n\n   If lang part if `*', it returns LANG_AUTO and sets the field\n   name part to *fieldName.\n\n   Though a period is found but no parser (langType) is found for\n   the language parser, this function returns LANG_IGNORE and sets\n   NULL to *fieldName.\n\n   A proper parser is found, this function returns langType for the\n   parser and sets the field name part to *fieldName. */\nstatic langType getLanguageComponentInFieldName (const char *fullName,\n\t\t\t\t\t\t const char **fieldName)\n{\n\tconst char *tmp;\n\tlangType language;\n\n\ttmp = strchr (fullName, '.');\n\tif (tmp)\n\t{\n\t\tsize_t len = tmp - fullName;\n\n\t\tif (len == 1 && fullName[0] == '*')\n\t\t{\n\t\t\tlanguage = LANG_AUTO;\n\t\t\t*fieldName = tmp + 1;\n\t\t}\n\t\telse if (len == 0)\n\t\t{\n\t\t\tlanguage = LANG_IGNORE;\n\t\t\t*fieldName = tmp + 1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlanguage = getNamedLanguage (fullName, len);\n\t\t\tif (language == LANG_IGNORE)\n\t\t\t\t*fieldName = NULL;\n\t\t\telse\n\t\t\t\t*fieldName = tmp + 1;\n\t\t}\n\t}\n\telse\n\t{\n\t\tlanguage = LANG_IGNORE;\n\t\t*fieldName = fullName;\n\t}\n\treturn language;\n}\n\nstatic fmtElement** queueTagField (fmtElement **last, long width, bool truncation,\n\t\t\t\t\t\t\t\t   char field_letter, const char *field_name)\n{\n\tfieldType ftype;\n\tfmtElement *cur;\n\tlangType language;\n\n\tif (field_letter == NUL_FIELD_LETTER)\n\t{\n\t\tconst char *f;\n\n\t\tlanguage = getLanguageComponentInFieldName (field_name, &f);\n\t\tif (f == NULL)\n\t\t\terror (FATAL, \"No suitable parser for field name: %s\", field_name);\n\t\tftype = getFieldTypeForNameAndLanguage (f, language);\n\t}\n\telse\n\t{\n\t\tlanguage = LANG_IGNORE;\n\t\tftype = getFieldTypeForLetter (field_letter);\n\t}\n\n\tif (ftype == FIELD_UNKNOWN)\n\t{\n\t\tif (field_letter == NUL_FIELD_LETTER)\n\t\t\terror (FATAL, \"No such field name: %s\", field_name);\n\t\telse\n\t\t\terror (FATAL, \"No such field letter: %c\", field_letter);\n\t}\n\n\tif (!doesFieldHaveRenderer (ftype, false))\n\t{\n\t\tAssert (field_letter != NUL_FIELD_LETTER);\n\t\terror (FATAL, \"The field cannot be printed in format output: %c\", field_letter);\n\t}\n\n\tcur = xMalloc (1, fmtElement);\n\n\tcur->spec.field.width = width;\n\tcur->spec.field.ftype = ftype;\n\n\tif (width < 0)\n\t{\n\t\tcur->spec.field.width *= -1;\n\t\tcur->spec.field.raw_fmtstr = (truncation? \"%-.*s\": \"%-*s\");\n\t}\n\telse if (width > 0)\n\t\tcur->spec.field.raw_fmtstr = (truncation? \"%.*s\": \"%*s\");\n\telse\n\t\tcur->spec.field.raw_fmtstr = NULL;\n\n\tenableField (ftype, true);\n\tif (language == LANG_AUTO)\n\t{\n\t\tfieldType ftype_next = ftype;\n\n\t\twhile ((ftype_next = nextSiblingField (ftype_next)) != FIELD_UNKNOWN)\n\t\t\tenableField (ftype_next, true);\n\t}\n\n\tcur->printer = printTagField;\n\tcur->next = NULL;\n\t*last = cur;\n\treturn &(cur->next);\n}\n\nextern fmtElement *fmtNew (const char*  fmtString)\n{\n\tint i;\n\tvString *literal = NULL;\n\tfmtElement *code  = NULL;\n\tfmtElement **last = &code;\n\tbool found_percent = false;\n\tlong column_width;\n\tconst char*  cursor;\n\n\tcursor = fmtString;\n\n\tfor (i = 0; cursor[i] != '\\0'; ++i)\n\t{\n\t\tif (found_percent)\n\t\t{\n\t\t\tfound_percent = false;\n\t\t\tif (cursor[i] == '%')\n\t\t\t{\n\t\t\t\tif (literal == NULL)\n\t\t\t\t\tliteral = vStringNew ();\n\t\t\t\tvStringPut (literal, cursor[i]);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tint justification_right = 1;\n\t\t\t\tbool truncation = false;\n\t\t\t\tvString *width = NULL;\n\t\t\t\tif (literal)\n\t\t\t\t{\n\t\t\t\t\tchar* l = vStringDeleteUnwrap (literal);\n\t\t\t\t\tliteral = NULL;\n\t\t\t\t\tlast = queueLiteral (last, l);\n\t\t\t\t}\n\t\t\t\tif (cursor [i] == '-')\n\t\t\t\t{\n\t\t\t\t\tjustification_right = -1;\n\t\t\t\t\ti++;\n\n\t\t\t\t\tif (cursor [i] == '\\0')\n\t\t\t\t\t\terror (FATAL, \"unexpectedly terminated just after '-': \\\"%s\\\"\", fmtString);\n\n\t\t\t\t}\n\t\t\t\tif (cursor [i] == '.')\n\t\t\t\t{\n\t\t\t\t\ttruncation = true;\n\t\t\t\t\ti++;\n\n\t\t\t\t\tif (cursor [i] == '\\0')\n\t\t\t\t\t\terror (FATAL, \"unexpectedly terminated just after '.': \\\"%s\\\"\", fmtString);\n\t\t\t\t}\n\n\t\t\t\twhile ( '0' <= cursor[i] && cursor[i] <= '9' )\n\t\t\t\t{\n\t\t\t\t\tif (width == NULL)\n\t\t\t\t\t\twidth = vStringNew ();\n\t\t\t\t\tvStringPut (width, cursor[i]);\n\t\t\t\t\ti++;\n\n\t\t\t\t\tif (cursor [i] == '\\0')\n\t\t\t\t\t\terror (FATAL, \"unexpectedly terminated during parsing column width: \\\"%s\\\"\", fmtString);\n\t\t\t\t}\n\n\t\t\t\tif (justification_right == -1 && width == NULL)\n\t\t\t\t\terror (FATAL, \"no column width given after '-': \\\"%s\\\"\", fmtString);\n\n\t\t\t\tcolumn_width = 0;\n\t\t\t\tif (width)\n\t\t\t\t{\n\t\t\t\t\tif(!strToLong (vStringValue (width), 0, &column_width))\n\t\t\t\t\t\terror (FATAL | PERROR, \"converting failed: %s\", vStringValue (width));\n\t\t\t\t\tvStringDelete (width);\n\t\t\t\t\twidth = NULL;\n\t\t\t\t\tcolumn_width *= justification_right;\n\t\t\t\t}\n\n\t\t\t\tif (cursor[i] == '{')\n\t\t\t\t{\n\t\t\t\t\tvString *field_name = vStringNew ();\n\n\t\t\t\t\ti++;\n\t\t\t\t\tfor (; cursor[i] != '}'; i++)\n\t\t\t\t\t\tvStringPut (field_name, cursor[i]);\n\n\t\t\t\t\tlast = queueTagField (last, column_width, truncation,\n\t\t\t\t\t\t\t\t\t\t  NUL_FIELD_LETTER, vStringValue (field_name));\n\n\t\t\t\t\tvStringDelete (field_name);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tlast = queueTagField (last, column_width, truncation,\n\t\t\t\t\t\t\t\t\t\t  cursor[i], NULL);\n\t\t\t}\n\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (cursor[i] == '%')\n\t\t\t\tfound_percent = true;\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (literal == NULL)\n\t\t\t\t\tliteral = vStringNew ();\n\n\t\t\t\tvStringPut (literal, cursor[i]);\n\t\t\t}\n\t\t}\n\t}\n\tif (literal)\n\t{\n\t\tchar* l = vStringDeleteUnwrap (literal);\n\t\tliteral = NULL;\n\t\tlast = queueLiteral (last, l);\n\t}\n\treturn code;\n}\n\nextern int fmtPrint   (fmtElement * fmtelts, MIO* fp, const tagEntryInfo *tag)\n{\n\tfmtElement *f = fmtelts;\n\tint i = 0;\n\twhile (f)\n\t{\n\t\ti += f->printer (&(f->spec), fp, tag);\n\t\tf = f->next;\n\t}\n\treturn i;\n}\n\nextern void fmtDelete  (fmtElement * fmtelts)\n{\n\tfmtElement *f = fmtelts;\n\tfmtElement *next;\n\n\twhile (f)\n\t{\n\t\tnext = f->next;\n\t\tif (f->printer == printLiteral)\n\t\t{\n\t\t\teFree (f->spec.const_str);\n\t\t\tf->spec.const_str = NULL;\n\t\t}\n\t\tf->next = NULL;\n\t\teFree (f);\n\t\tf = next;\n\t}\n}\n"
  },
  {
    "path": "main/fmt_p.h",
    "content": "/*\n *\n *  Copyright (c) 2015, Red Hat, Inc.\n *  Copyright (c) 2015, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#ifndef FMT_H\n#define FMT_H\n\n#include \"general.h\"\n#include \"entry.h\"\n#include \"mio.h\"\n\ntypedef struct sFmtElement fmtElement;\nextern fmtElement *fmtNew     (const char* fmtString);\nextern int         fmtPrint   (fmtElement * fmtelts, MIO* fp, const tagEntryInfo *tag);\nextern void        fmtDelete  (fmtElement * fmtelts);\n\n#endif\t/* FMT_H */\n"
  },
  {
    "path": "main/fname.c",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#include \"general.h\"\n#include \"fname.h\"\n\n#include <string.h>\n\n#include \"routines.h\"\n#include \"vstring.h\"\n\n\nstruct comp {\n\tchar *str;\n\tsize_t len;\n\tstruct comp *parent;\n\tstruct comp *child;\n};\n\n\nstruct canonFnameCacheTable {\n\thashTable *table;\n\tconst char *cwd;\n\tsize_t cwd_len;\n\tchar *input_last;\n\tchar *return_last;\n\tbool absoluteOnly;\n};\n\nextern struct canonFnameCacheTable *canonFnameCacheTableNew (const char *cwd, bool absoluteOnly)\n{\n\tstruct canonFnameCacheTable *r = xMalloc (1, struct canonFnameCacheTable);\n\tr->table = hashTableNew (7, hashCstrhash, hashCstreq,\n\t\t\t\t eFree, eFree);\n\tr->input_last = NULL;\n\tr->return_last = NULL;\n\n\tchar *cwd_tmp = eStrdup (cwd);\n\tr->cwd = canonicalizeAbsoluteFileName (cwd_tmp);\n\teFree (cwd_tmp);\n\tr->cwd_len = strlen (r->cwd);\n\n\tr->absoluteOnly = absoluteOnly;\n\n\treturn r;\n}\n\nextern void canonFnameCacheTableDelete (struct canonFnameCacheTable *cache_table)\n{\n\teFree ((void *)cache_table->cwd);\n\thashTableDelete (cache_table->table);\n\teFree (cache_table);\n}\n\nstatic void strcpy_comps (char *buf, struct comp *comp)\n{\n\twhile (comp)\n\t{\n\t\tbuf[0] = '/';\n\t\tmemcpy (buf + 1, comp->str, comp->len);\n\t\tbuf += (1 + comp->len);\n\t\tcomp = comp->child;\n\t}\n\tbuf[0] = '\\0';\n}\n\nstatic size_t strlen_comps (struct comp *comp)\n{\n\tsize_t n = 0;\n\n\twhile (comp)\n\t{\n\t\tn += (1 + comp->len);\n\t\tcomp = comp->child;\n\t}\n\treturn n;\n}\n\nstatic char *fsimplify_absz (struct comp *comp)\n{\n\tstruct comp *root = comp;\n\n\twhile (comp)\n\t{\n\t\t// fprintf (stderr, \"[stack] -%s-\\n\", comp->str);\n\t\troot = comp;\n\t\tcomp = comp->parent;\n\t}\n\n\tif (root->child && root->len == 0)\n\t\troot = root->child;\n\n\tsize_t len = strlen_comps (root);\n\tchar *buf = xMalloc (len + 1, char);\n\n\tstrcpy_comps(buf, root);\n\treturn buf;\n}\n\nstatic char *fsimplify_abs0 (char *fname, struct comp *parent)\n{\n\tchar *next = strchr (fname, '/');\n\tstruct comp comp = {\n\t\t.str = fname,\n\t\t.len = next? (next - fname): strlen (fname),\n\t\t.parent = parent,\n\t\t.child = NULL\n\t};\n\n\tif (comp.len  == 0\n\t\t|| (comp.len == 1 && fname [0] == '.'))\n\t{\n\t\tparent->child = NULL;\n\t\tif (next == NULL)\n\t\t\treturn fsimplify_absz (parent);\n\t\t*next = '\\0';\n\t\treturn fsimplify_abs0 (next + 1, parent);\n\t}\n\n\tif (comp.len == 2 && fname [0] == '.' && fname [1] == '.')\n\t{\n\t\tif (next == NULL)\n\t\t{\n\t\t\tif (parent->parent)\n\t\t\t{\n\t\t\t\tparent->parent->child = NULL;\n\t\t\t\treturn fsimplify_absz (parent->parent);\n\t\t\t}\n\t\t\treturn strdup(\"/\");\n\t\t}\n\t\t*next = '\\0';\n\t\tif (parent->parent)\n\t\t{\n\t\t\tparent->parent->child = NULL;\n\t\t\treturn fsimplify_abs0 (next + 1, parent->parent);\n\t\t}\n\t\tcomp.parent = NULL;\n\t\tcomp.str[0] = '\\0';\n\t\tcomp.len = 0;\n\t\treturn fsimplify_abs0 (next + 1, &comp);\n\t}\n\n\tparent->child = &comp;\n\tif (next == NULL)\n\t\treturn fsimplify_absz (&comp);\n\t*next = '\\0';\n\treturn fsimplify_abs0 (next + 1, &comp);\n}\n\nstatic bool is_special_link(const char *name)\n{\n\t/* strcmp (comp.str, \"..\") || !strcmp (comp.str, \".\") */\n\tif (name [0] != '.')\n\t\treturn false;\n\tif (name [1] == '\\0')\n\t\treturn true;\n\tif (name [1] != '.')\n\t\treturn false;\n\tif (name [2] == '\\0')\n\t\treturn true;\n\treturn false;\n}\n\nextern char *canonicalizeAbsoluteFileName (char *fname)\n{\n\tchar *next = strchr (fname, '/');\n\tif (next == NULL)\n\t{\n\t\tif (is_special_link(fname))\n\t\t{\n\t\t\tfname [0] = '/';\n\t\t\tfname [1] = '\\0';\n\t\t\treturn strdup (fname);\n\t\t}\n\t\tchar *r = xMalloc (strlen (fname) + 2, char);\n\t\tr[0] = '/';\n\t\tstrcpy (r + 1, fname);\n\t\treturn r;\n\t}\n\n\t*next = '\\0';\n\tstruct comp comp = {\n\t\t.str = fname,\n\t\t.len = next - fname,\n\t\t.parent = NULL,\n\t\t.child = NULL\n\t};\n\tif (is_special_link (comp.str))\n\t{\n\t\tcomp.str[0] = '\\0';\n\t\tcomp.len = 0;\n\t}\n\treturn fsimplify_abs0 (next + 1, &comp);\n}\n\nstatic char *canonicalizePathNew(const char *dir, size_t dir_len, const char *rela,\n\t\t\t\t\t\t\t\t bool absoluteOnly)\n{\n\tbool relative = false;\n\tvString *buf = vStringNew ();\n\n\tif (rela == NULL)\n\t\tvStringNCopyS (buf, dir, dir_len);\n\telse if (rela[0] == '/')\n\t\tvStringCopyS (buf, rela);\n\telse\n\t{\n\t\tvStringNCopyS (buf, dir, dir_len);\n\t\tvStringPut (buf, '/');\n\t\tvStringCatS (buf, rela);\n\t\tif (!absoluteOnly)\n\t\t\trelative = true;\n\t}\n\n\tchar *r = canonicalizeAbsoluteFileName (vStringValue (buf));\n\tif (relative)\n\t{\n\t\tif (strncmp (dir, r, dir_len) == 0)\n\t\t{\n\t\t\tif (r[dir_len] == '/')\n\t\t\t{\n\t\t\t\tif (r[dir_len + 1] == '\\0')\n\t\t\t\t\tvStringNCopyS (buf, \".\", 1);\n\t\t\t\telse\n\t\t\t\t\tvStringCopyS (buf, r + dir_len + 1);\n\t\t\t\teFree (r);\n\t\t\t\treturn vStringDeleteUnwrap (buf);\n\t\t\t}\n\t\t\telse if (r[dir_len] == '\\0')\n\t\t\t{\n\t\t\t\tvStringNCopyS (buf, \".\", 1);\n\t\t\t\teFree (r);\n\t\t\t\treturn vStringDeleteUnwrap (buf);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvStringDelete (buf);\n\t\t\t\treturn r;\n\t\t\t}\n\t\t}\n\t}\n\n\tvStringDelete (buf);\n\treturn r;\n}\n\nextern const char *canonicalizeFileName (struct canonFnameCacheTable *cache_table,\n\t\t\t\t\t\t\t\t\t\t const char *input)\n{\n\tif (cache_table->input_last)\n\t{\n\t\tif (strcmp (input, cache_table->input_last) == 0)\n\t\t\treturn cache_table->return_last;\n\t\tcache_table->input_last = NULL;\n\t}\n\n\tchar *r = hashTableGetItem (cache_table->table, input);\n\tif (r)\n\t\treturn r;\n\n\tr = canonicalizePathNew (cache_table->cwd, cache_table->cwd_len, input,\n\t\t\t\t\t\t\t cache_table->absoluteOnly);\n\n\tcache_table->input_last = eStrdup (input);\n\tcache_table->return_last = r;\n\thashTablePutItem (cache_table->table, cache_table->input_last, cache_table->return_last);\n\treturn cache_table->return_last;\n}\n"
  },
  {
    "path": "main/fname.h",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n#ifndef CTAGS_MAIN_FNAME_UTIL_H\n#define CTAGS_MAIN_FNAME_UTIL_H\n\n#include \"general.h\"\n\n#include \"htable.h\"\n\nstruct canonFnameCacheTable;\nextern struct canonFnameCacheTable *canonFnameCacheTableNew (const char *cwd, bool absoluteOnly);\nextern void canonFnameCacheTableDelete (struct canonFnameCacheTable *cache_table);\n\n/*\n * If INPUT is an absolute path (starting form '/'), return new absolute path\n * string after resolving '..', '.', and '//' in it. '//' is reduced to '/'.\n *\n * If INPUT is a relative path, resolve '.', '..', and '//' as if the current\n * working directly is the CWD passed canonFnameCacheTableNew(). The return\n * string may absolute or relative path form.\n *\n * Return the result in absolute path form always if CACHE_TABLE is made\n * with absoluteOnly == true.\n *\n * If CACHE_TABLE is made with absoluteOnly == false,\n * in most of all cases, the string return from this function doesn't\n * include \".\". There is one exception.\n * If the resolved file name is the same as CWD canonFnameCacheTableNew(),\n * this function returns just \".\".\n *\n * Don't free the cstring returned from this function directly.\n * This function stores the cstring to the CACHE_TABLE for processing the\n * same INPUT more than twice. canonFnameCacheTableDelete() destroys all C\n * strings returned from this function.\n */\nextern const char *canonicalizeFileName(struct canonFnameCacheTable *cache_table,\n\t\t\t\t\t\t\t\t\t\tconst char *input);\n\n/*\n * Resolve '.', '..', and '//' in FNAME as if the current working\n * directory is at '/'.\n *\n * eFree() is for freeing the cstring returned from this function.\n * This function may modify FNAME[] as a side effect.\n */\nextern char *canonicalizeAbsoluteFileName (char *fname);\n\n#endif\t/* CTAGS_MAIN_FNAME_UTIL_H */\n"
  },
  {
    "path": "main/gcc-attr.h",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n/* This is derived from general.h.\n   Only readtags related source file should include this.\n   ctags related source file should include genera.h instead. */\n\n#ifndef CTAGS_MAIN_GCC_ATTR_H\n#define CTAGS_MAIN_GCC_ATTR_H\n\n/*  Prevent warnings about unused variables in GCC. */\n#if defined (__GNUC__) && !defined (__GNUG__)\n# define CTAGS_ATTR_UNUSED __attribute__((unused))\n# define CTAGS_ATTR_PRINTF(s,f)  __attribute__((format (printf, s, f)))\n# define CTAGA_ATTR_ALIGNED(X) __attribute__((aligned(X)))\n# define attr__noreturn __attribute__((__noreturn__))\n#else\n# define CTAGS_ATTR_UNUSED\n# define CTAGS_ATTR_PRINTF(s,f)\n# define CTAGA_ATTR_ALIGNED(X)\n# define attr__noreturn\n#endif\n\n#endif\t/* CTAGS_MAIN_GCC_ATTR_H */\n"
  },
  {
    "path": "main/general.h",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Provides the general (non-ctags-specific) environment assumed by all.\n*/\n#ifndef CTAGS_MAIN_GENERAL_H\n#define CTAGS_MAIN_GENERAL_H\n\n/*\n*   INCLUDE FILES\n*/\n#if defined (HAVE_CONFIG_H)\n# include <config.h>\n#elif defined (_WIN32)\n# include \"e_msoft.h\"\n#endif\n\n/*  To provide timings features.\n */\n#include <time.h>\n\n/*\n*   MACROS\n*/\n#include \"gcc-attr.h\"\n\n/*\n *  Portability macros\n */\n#if !defined(HAVE_STRCASECMP) && !defined(strcasecmp)\n# ifdef HAVE_STRICMP\n#  define strcasecmp(s1,s2) stricmp(s1,s2)\n# else\n#  define strcasecmp(s1,s2) struppercmp(s1,s2)\n# endif\n#endif\n\n#if !defined(HAVE_STRNCASECMP) && !defined(strncasecmp)\n# ifdef HAVE_STRNICMP\n#  define strncasecmp(s1,s2,n) strnicmp(s1,s2,n)\n# else\n#  define strncasecmp(s1,s2,n) strnuppercmp(s1,s2,n)\n# endif\n#endif\n\n/*\n*   DATA DECLARATIONS\n*/\n\n#ifdef HAVE_STDBOOL_H\n# include <stdbool.h>\n#endif\n\n/*\n*   HACK for #1610.\n*/\n\n#ifdef ICONV_USE_LIB_PREFIX\n#define iconv libiconv\n#define iconv_open libiconv_open\n#define iconv_close libiconv_close\n#endif\n\n#endif  /* CTAGS_MAIN_GENERAL_H */\n"
  },
  {
    "path": "main/gvars.h",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*   Copyright (c) 2018, Red Hat, Inc.\n *  Copyright (c) 2018, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Declare variables visible to parsers\n*/\n#ifndef CTAGS_GVARS_H\n#define CTAGS_GVARS_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#ifdef DEBUG\n\n/* -d  debugging output */\nextern long ctags_debugLevel;\n\n#endif\t/* DEBUG */\n\n/* -V  verbose */\nextern bool ctags_verbose;\n\n#endif\t/* CTAGS_GVARS_H */\n"
  },
  {
    "path": "main/htable.c",
    "content": "/*\n*\n*   Copyright (c) 2014, Red Hat, Inc.\n*   Copyright (c) 2014, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines hashtable\n*/\n\n#include \"general.h\"\n#include \"debug.h\"\n#include \"htable.h\"\n#include \"routines.h\"\n\n#include <stdio.h>\n#include <string.h>\n\n\ntypedef struct sHashEntry hentry;\nstruct sHashEntry {\n\tvoid *key;\n\tvoid *value;\n\tunsigned int hash;\n\thentry *next;\n};\n\nstruct sHashTable {\n\thentry** table;\n\tunsigned int size;\n\tunsigned int count;\n\thashTableHashFunc hashfn;\n\thashTableEqualFunc equalfn;\n\thashTableDeleteFunc keyfreefn;\n\thashTableDeleteFunc valfreefn;\n\tvoid *valForNotUnknownKey;\n\thashTableDeleteFunc valForNotUnknownKeyfreefn;\n};\n\nstruct chainTracker {\n\tconst void *const target_key;\n\thashTableForeachFunc user_proc;\n\tvoid *user_data;\n\thashTableEqualFunc equalfn;\n};\n\nstatic hentry* entry_new (void *key, void *value, unsigned int hash, hentry* next)\n{\n\thentry* entry = xMalloc (1, hentry);\n\n\tentry->key = key;\n\tentry->value = value;\n\tentry->next = next;\n\tentry->hash = hash;\n\n\treturn entry;\n}\n\nstatic void entry_reset  (hentry* entry,\n\t\t\t\t\t\t  void *newkey,\n\t\t\t\t\t\t  void *newval,\n\t\t\t\t\t\t  hashTableDeleteFunc keyfreefn,\n\t\t\t\t\t\t  hashTableDeleteFunc valfreefn)\n{\n\tif (keyfreefn)\n\t\tkeyfreefn (entry->key);\n\tif (valfreefn)\n\t\tvalfreefn (entry->value);\n\n\tif (keyfreefn)\n\t\tentry->key = newkey;\n\tentry->value = newval;\n}\n\nstatic hentry* entry_destroy (hentry* entry,\n\t\t\t      hashTableDeleteFunc keyfreefn,\n\t\t\t      hashTableDeleteFunc valfreefn)\n{\n\thentry* tmp;\n\n\tentry_reset (entry, NULL, NULL, keyfreefn, valfreefn);\n\ttmp = entry->next;\n\teFree (entry);\n\n\treturn tmp;\n}\n\nstatic void  entry_reclaim (hentry* entry,\n\t\t\t    hashTableDeleteFunc keyfreefn,\n\t\t\t    hashTableDeleteFunc valfreefn)\n{\n\twhile (entry)\n\t\tentry = entry_destroy (entry, keyfreefn, valfreefn);\n}\n\n/* Looking for an entry having KEY as its key in the chain:\n * entry, entry->next, entry->next->next,...\n *\n * We have a chance to optimize for the case when a same key is\n * used repeatedly. By moving the entry found in the last time to\n * the head of the chain, we can avoid taking time for tracking\n * down the ->next-> chain.\n * The cost for the optimization is very small.\n */\nstatic void *entry_find (hentry** root_entry, const void* const key, hashTableEqualFunc equalfn,\n\t\t\t\t\t\t void *valForNotUnknownKey)\n{\n\thentry *entry = *root_entry;\n\thentry *last = NULL;\n\twhile (entry)\n\t{\n\t\tif (equalfn( key, entry->key))\n\t\t{\n\t\t\tif (last)\n\t\t\t{\n\t\t\t\tlast->next = entry->next;\n\t\t\t\tentry->next = *root_entry;\n\t\t\t\t*root_entry = entry;\n\t\t\t}\n\t\t\treturn entry->value;\n\t\t}\n\n\t\tlast = entry;\n\t\tentry = entry->next;\n\t}\n\treturn valForNotUnknownKey;\n}\n\nstatic bool\t\tentry_delete (hentry **entry, const void *key, hashTableEqualFunc equalfn,\n\t\t\t      hashTableDeleteFunc keyfreefn, hashTableDeleteFunc valfreefn)\n{\n\twhile (*entry)\n\t{\n\t\tif (equalfn (key, (*entry)->key))\n\t\t{\n\t\t\t*entry = entry_destroy (*entry, keyfreefn, valfreefn);\n\t\t\treturn true;\n\t\t}\n\t\tentry = &((*entry)->next);\n\t}\n\treturn false;\n}\n\nstatic bool\t\tentry_update (hentry *entry, void *key, void *value, hashTableEqualFunc equalfn,\n\t\t\t      hashTableDeleteFunc keyfreefn, hashTableDeleteFunc valfreefn)\n{\n\twhile (entry)\n\t{\n\t\tif (equalfn (key, entry->key))\n\t\t{\n\t\t\tentry_reset (entry, key, value, keyfreefn, valfreefn);\n\t\t\treturn true;\n\t\t}\n\t\tentry = entry->next;\n\t}\n\treturn false;\n}\n\nstatic bool  entry_foreach (hentry *entry, hashTableForeachFunc proc, void *user_data)\n{\n\twhile (entry)\n\t{\n\t\tif (!proc (entry->key, entry->value, user_data))\n\t\t\treturn false;\n\t\tentry = entry->next;\n\t}\n\treturn true;\n}\n\nextern hashTable *hashTableNew    (unsigned int size,\n\t\t\t\t   hashTableHashFunc hashfn,\n\t\t\t\t   hashTableEqualFunc equalfn,\n\t\t\t\t   hashTableDeleteFunc keyfreefn,\n\t\t\t\t   hashTableDeleteFunc valfreefn)\n{\n\thashTable *htable;\n\n\thtable = xMalloc (1, hashTable);\n\n\tif (size < 3)\n\t\tsize = 3;\n\tif ((size % 2) == 0)\n\t\tsize++;\n\n\thtable->size = size;\n\thtable->count = 0;\n\thtable->table = xCalloc (size, hentry*);\n\n\thtable->hashfn = hashfn;\n\thtable->equalfn = equalfn;\n\thtable->keyfreefn = keyfreefn;\n\thtable->valfreefn = valfreefn;\n\thtable->valForNotUnknownKey = NULL;\n\thtable->valForNotUnknownKeyfreefn = NULL;\n\n\treturn htable;\n}\n\nextern void hashTableSetValueForUnknownKey (hashTable *htable,\n\t\t\t\t\t\t\t\t\t\t\tvoid *val,\n\t\t\t\t\t\t\t\t\t\t\thashTableDeleteFunc valfreefn)\n{\n\tif (htable->valfreefn)\n\t\thtable->valfreefn (htable->valForNotUnknownKey);\n\n\thtable->valForNotUnknownKey = val;\n\thtable->valForNotUnknownKeyfreefn = valfreefn;\n}\n\nextern void       hashTableDelete (hashTable *htable)\n{\n\tif (!htable)\n\t\treturn;\n\n\thashTableClear (htable);\n\n\tif (htable->valForNotUnknownKeyfreefn)\n\t\thtable->valForNotUnknownKeyfreefn (htable->valForNotUnknownKey);\n\teFree (htable->table);\n\teFree (htable);\n}\n\nextern void       hashTableClear (hashTable *htable)\n{\n\tunsigned int i;\n\tif (!htable)\n\t\treturn;\n\n\tfor (i = 0; i < htable->size; i++)\n\t{\n\t\thentry *entry;\n\n\t\tentry = htable->table[i];\n\t\tentry_reclaim (entry, htable->keyfreefn, htable->valfreefn);\n\t\thtable->table[i] = NULL;\n\t}\n}\n\nstatic void       hashTablePutItem00    (hashTable *htable, void *key, void *value, unsigned int h)\n{\n\tunsigned int i = h % htable->size;\n\thtable->table[i] = entry_new(key, value, h, htable->table[i]);\n\thtable->count++;\n}\n\n/* \"doubling\" primes smaller than 2^32 */\nstatic const unsigned int primes[] = {\n\t3, 7, 17, 37, 79, 163, 331, 673, 1361, 2729, 5471, 10949, 21911,\n\t43853, 87719, 175447, 350899, 701819, 1403641, 2807303, 5614657,\n\t11229331, 22458671, 44917381, 89834777, 179669557, 359339171,\n\t718678369, 1437356741, 2874713497,\n};\n\nstatic unsigned int\nprime_double(unsigned int i)\n{\n\tunsigned int j;\n\n\tAssert (i > 2);\n\tAssert (i % 2);\n\n\tfor (j = 0; j < sizeof(primes) / sizeof(primes[0]); ++j)\n\t\tif (primes[j] > i)\n\t\t\treturn primes[j];\n\n\treturn i;\n}\n\nstatic void       hashTableGrow        (hashTable *htable)\n{\n\tunsigned int current_size = htable->size;\n\tunsigned int new_size = prime_double (current_size);\n\n\tif (new_size <= current_size)\n\t\treturn;\n\n\thentry** new_table = xCalloc (new_size, hentry*);\n\tfor (unsigned int i = 0; i < current_size; i++)\n\t{\n\t\thentry *entry;\n\t\twhile ((entry = htable->table[i]))\n\t\t{\n\t\t\tunsigned int hash = entry->hash;\n\t\t\tunsigned int j = hash % new_size;\n\t\t\thtable->table[i] = entry->next;\n\t\t\tentry->next = new_table[j];\n\t\t\tnew_table[j] = entry;\n\t\t}\n\t}\n\n\thentry** old_table = htable->table;\n\thtable->table = new_table;\n\thtable->size = new_size;\n\teFree (old_table);\n}\n\nstatic void       hashTablePutItem0    (hashTable *htable, void *key, void *value, unsigned int h)\n{\n\tif (((double)htable->count / (double)htable->size) < 0.8)\n\t{\n\t\thashTablePutItem00 (htable, key, value,  h);\n\t\treturn;\n\t}\n\n\thashTableGrow (htable);\n\thashTablePutItem00 (htable, key, value, h);\n}\n\nextern void       hashTablePutItem    (hashTable *htable, void *key, void *value)\n{\n\thashTablePutItem0 (htable, key, value, htable->hashfn (key));\n}\n\nextern void*      hashTableGetItem   (hashTable *htable, const void * key)\n{\n\tunsigned int h, i;\n\n\th = htable->hashfn (key);\n\ti = h % htable->size;\n\treturn entry_find(& (htable->table[i]), key, htable->equalfn, htable->valForNotUnknownKey);\n}\n\nextern bool     hashTableDeleteItem (hashTable *htable, const void *key)\n{\n\tunsigned int h;\n\tunsigned int i;\n\th = htable->hashfn (key);\n\ti = h % htable->size;\n\n\tbool r = entry_delete(&htable->table[i], key,\n\t\t\t    htable->equalfn, htable->keyfreefn, htable->valfreefn);\n\tif (r)\n\t\thtable->count--;\n\treturn r;\n}\n\nextern bool    hashTableUpdateItem (hashTable *htable, const void *key, void *value)\n{\n\tunsigned int h, i;\n\n\th = htable->hashfn (key);\n\ti = h % htable->size;\n\tbool r = entry_update(htable->table[i], (void *)key, value,\n\t\t\t\t\t\t  htable->equalfn, NULL, htable->valfreefn);\n\treturn r;\n}\n\nextern bool    hashTableUpdateOrPutItem (hashTable *htable, void *key, void *value)\n{\n\tunsigned int h, i;\n\n\th = htable->hashfn (key);\n\ti = h % htable->size;\n\tbool r = entry_update(htable->table[i], key, value,\n\t\t\t\t\t\t  htable->equalfn, NULL, htable->valfreefn);\n\tif (!r)\n\t\thashTablePutItem0(htable, key, value, h);\n\n\treturn r;\n}\n\nextern bool    hashTableHasItem    (hashTable *htable, const void *key)\n{\n\treturn hashTableGetItem (htable, key) == htable->valForNotUnknownKey? false: true;\n}\n\nextern bool       hashTableForeachItem (hashTable *htable, hashTableForeachFunc proc, void *user_data)\n{\n\tunsigned int i;\n\n\tfor (i = 0; i < htable->size; i++)\n\t\tif (!entry_foreach(htable->table[i], proc, user_data))\n\t\t\treturn false;\n\treturn true;\n}\n\nstatic bool track_chain (const void *const key, void *value, void *chain_data)\n{\n\tstruct chainTracker *chain_tracker = chain_data;\n\n\tif (chain_tracker->equalfn (chain_tracker->target_key, key))\n\t{\n\t\tif (! chain_tracker->user_proc (key, value, chain_tracker->user_data))\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\nextern bool       hashTableForeachItemOnChain (hashTable *htable, const void *key, hashTableForeachFunc proc, void *user_data)\n{\n\tunsigned int h, i;\n\tstruct chainTracker chain_tracker = {\n\t\t.target_key = key,\n\t\t.user_proc = proc,\n\t\t.user_data = user_data,\n\t\t.equalfn   = htable->equalfn,\n\t};\n\n\th = htable->hashfn (key);\n\ti = h % htable->size;\n\tif (!entry_foreach(htable->table[i], track_chain, &chain_tracker))\n\t\treturn false;\n\treturn true;\n}\n\nextern void hashTablePrintStatistics(hashTable *htable)\n{\n\tif (htable->size == 0 || htable->count == 0)\n\t\tfprintf(stderr, \"size: %u, count: %u, average: 0\\n\",\n\t\t\t\thtable->size, htable->count);\n\n\tdouble sum = 0.0;\n\tfor (size_t i = 0; i < htable->size; i++)\n\t{\n\t\thentry *e = htable->table[i];\n\t\twhile (e)\n\t\t{\n\t\t\tsum += 1.0;\n\t\t\te = e->next;\n\t\t}\n\t}\n\tdouble average = sum / (double)htable->size;\n\n\tdouble variance = 0.0;\n\tfor (size_t i = 0; i < htable->size; i++)\n\t{\n\t\tdouble sum0 = 0;\n\t\thentry *e = htable->table[i];\n\t\twhile (e)\n\t\t{\n\t\t\tsum0 += 1.0;\n\t\t\te = e->next;\n\t\t}\n\t\tdouble d = sum0 - average;\n\t\tvariance += (d * d);\n\t}\n\tvariance = variance / (double)htable->size;\n\tfprintf(stderr, \"size: %u, count: %u, average: %lf, s.d.: sqrt(%lf)\\n\",\n\t\t\thtable->size, htable->count, average, variance);\n}\n\nextern unsigned int hashTableCountItem   (hashTable *htable)\n{\n\treturn htable->count;\n}\n\nunsigned int hashPtrhash (const void * const x)\n{\n\tunion {\n\t\tconst void * ptr;\n\t\tunsigned int ui;\n\t} v;\n\tv.ui = 0;\n\tv.ptr = x;\n\n\treturn v.ui;\n}\n\nbool hashPtreq (const void *const a, const void *const b)\n{\n\treturn (a == b)? true: false;\n}\n\n\n/* http://www.cse.yorku.ca/~oz/hash.html */\nstatic unsigned long\ndjb2(const unsigned char *str)\n{\n\tunsigned long hash = 5381;\n\tint c;\n\n\twhile ((c = *str++))\n\t\thash = ((hash << 5) + hash) + c; /* hash * 33 + c */\n\n\treturn hash;\n}\n\nstatic unsigned long\ncasedjb2(const unsigned char *str)\n{\n\tunsigned long hash = 5381;\n\tint c;\n\n\twhile ((c = *str++))\n\t{\n\t\tif (('a' <= c) && (c <= 'z'))\n\t\t\tc += ('A' - 'a');\n\t\thash = ((hash << 5) + hash) + c; /* hash * 33 + c */\n\t}\n\n\treturn hash;\n}\n\n\nunsigned int hashCstrhash (const void *const x)\n{\n\tconst char *const s = x;\n\treturn (unsigned int)djb2((const unsigned char *)s);\n}\n\nbool hashCstreq (const void * const a, const void *const b)\n{\n\treturn !!(strcmp (a, b) == 0);\n}\n\nunsigned int hashInthash (const void *const x)\n{\n       union tmp {\n               unsigned int u;\n               int i;\n       } x0;\n\n       x0.u = 0;\n       x0.i = *(int *)x;\n       return x0.u;\n}\n\nbool hashInteq (const void *const a, const void *const b)\n{\n       int ai = *(int *)a;\n       int bi = *(int *)b;\n\n       return !!(ai == bi);\n}\n\n\nunsigned int hashCstrcasehash (const void *const x)\n{\n\tconst char *const s = x;\n\treturn (unsigned int)casedjb2((const unsigned char *)s);\n}\n\nbool hashCstrcaseeq (const void *const a, const void *const b)\n{\n\treturn !!(strcasecmp (a, b) == 0);\n}\n"
  },
  {
    "path": "main/htable.h",
    "content": "/*\n*\n*   Copyright (c) 2014, Red Hat, Inc.\n*   Copyright (c) 2014, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines hashtable\n*/\n#ifndef CTAGS_MAIN_HTABLE_H\n#define CTAGS_MAIN_HTABLE_H\n\n#include \"general.h\"\n#include <stdint.h>\n\n/* This hashtable allows adding multiple items for the same key.\n *\n * hashTablePutItem() adds a key/item pair to the htable even if the\n * htable has an item for the key already.\n *\n * hashTableGetItem() returns the first occurrence item for the given\n * key.\n *\n * hashTableDeleteItem() deletes the first occurrence item for the given\n * key.\n *\n * Use hashTableForeachItemOnChain () to process all items for the same key.\n */\ntypedef struct sHashTable hashTable;\ntypedef unsigned int (* hashTableHashFunc)  (const void * const key);\ntypedef bool      (* hashTableEqualFunc) (const void* a, const void* b);\ntypedef void         (* hashTableDeleteFunc)  (void * ptr);\n\n/* To continue interation, return true.\n * To break interation, return false. */\ntypedef bool         (* hashTableForeachFunc) (const void *key, void *value, void *user_data);\n\nunsigned int hashPtrhash (const void * x);\nbool hashPtreq (const void * a, const void * constb);\n\nunsigned int hashCstrhash (const void * x);\nbool hashCstreq (const void * a, const void * b);\n\nunsigned int hashCstrcasehash (const void * x);\nbool hashCstrcaseeq (const void * a, const void * b);\n\nunsigned int hashInthash (const void * x);\nbool hashInteq (const void * a, const void * b);\n\nextern hashTable* hashTableNew         (unsigned int size,\n\t\t\t\t\thashTableHashFunc hashfn,\n\t\t\t\t\thashTableEqualFunc equalfn,\n\t\t\t\t\thashTableDeleteFunc keyfreefn,\n\t\t\t\t\thashTableDeleteFunc valfreefn);\n\n/* By default, hashTableGetItem() returns NULL for a unknown key.\n * It means you cannot store NULL as a value for a key.\n * With hashTableSetValueForUnknownKey(), you can specific\n * an alternative address representing the value for for unknown\n * keys.\n */\nextern void hashTableSetValueForUnknownKey (hashTable *htable,\n\t\t\t\t\t\t\t\t\t\t\tvoid *val,\n\t\t\t\t\t\t\t\t\t\t\thashTableDeleteFunc valfreefn);\n\nextern void       hashTableDelete      (hashTable *htable);\nextern void       hashTableClear       (hashTable *htable);\nextern void       hashTablePutItem     (hashTable *htable, void *key, void *value);\nextern void*      hashTableGetItem     (hashTable *htable, const void * key);\nextern bool    hashTableHasItem     (hashTable * htable, const void * key);\nextern bool    hashTableDeleteItem  (hashTable *htable, const void *key);\n\n/* If KEY is found, this function updates the value for KEY and returns true.\n * If KEY is not found, this function just returns false.\n *\n * KEY is just referred. The HTABLE takes the ownership of VALUE when KEY is found. */\nextern bool       hashTableUpdateItem  (hashTable *htable, const void *key, void *value);\n\n/* If KEY is found, this function updates the value for KEY and returns true.\n * If KEY is not found, this function adds KEY and VALUE and returns false.\n *\n * The HTABLE takes the ownership of KEY only if KEY is not found.\n * The HTABLE takes the ownership of VALUE either when KEY is found or not. */\nextern bool       hashTableUpdateOrPutItem  (hashTable *htable, void *key, void *value);\n\n/* Return true if proc never returns false; proc returns true for all\n * the items, or htable holds no item.\n *\n * Return false if htable holds at least one item and proc returns false\n * for one of the items. */\nextern bool       hashTableForeachItem (hashTable *htable, hashTableForeachFunc proc, void *user_data);\n\n/* This function is useful for htable having multiple items for a key.\n * By giving a key, you can traverse all the items associated with the\n * key via proc.  * \"Chain\" means group of items associated with a\n * key. */\nextern bool       hashTableForeachItemOnChain (hashTable *htable, const void *key, hashTableForeachFunc proc, void *user_data);\n\nextern unsigned int hashTableCountItem   (hashTable *htable);\n\nextern void hashTablePrintStatistics(hashTable *htable);\n\n#define HT_PTR_TO_INT(P) ((int)(intptr_t)(P))\n#define HT_INT_TO_PTR(P) ((void*)(intptr_t)(P))\n#define HT_PTR_TO_UINT(P) ((unsigned int)(uintptr_t)(P))\n#define HT_UINT_TO_PTR(P) ((void*)(uintptr_t)(P))\n\n#endif\t/* CTAGS_MAIN_HTABLE_H */\n"
  },
  {
    "path": "main/inline.h",
    "content": "/*\n *\n *  Copyright (c) 2016, 2017 Matthew Brush\n *\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#ifndef CTAGS_MAIN_INLINE_H\n#define CTAGS_MAIN_INLINE_H\n\n#ifdef HAVE_CONFIG_H\n// AC_C_INLINE defines inline. The definition is in config.h.\n#include \"config.h\"\n# define CTAGS_INLINE static inline\n#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n# define CTAGS_INLINE static inline\n#elif defined(_MSC_VER)\n# define CTAGS_INLINE static __inline\n#elif defined(__GNUC__) || defined(__clang__)\n# define CTAGS_INLINE static __inline__\n// #elif ... other compilers/tests here ...\n// # define CTAGS_INLINE ...\n#else\n# define CTAGS_INLINE static\n#endif\n\n#define READTAGS_INLINE CTAGS_INLINE\n\n#endif /* CTAGS_MAIN_INLINE_H */\n"
  },
  {
    "path": "main/interactive_p.h",
    "content": "/*\n*   Copyright (c) 2016, Aman Gupta\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines interface to interactive loop.\n*/\n#ifndef CTAGS_MAIN_INTERACTIVE_H\n#define CTAGS_MAIN_INTERACTIVE_H\n\n#include \"general.h\"\n#include \"options_p.h\"\n#include \"routines.h\"\n\n\nstruct interactiveModeArgs\n{\n\tbool sandbox;\n};\n\nvoid interactiveLoop (cookedArgs *args, void *user);\nbool jsonErrorPrinter (const errorSelection selection, const char *const format, va_list ap,\n\t\t\t\t\t  void *data);\nint installSyscallFilter (void);\n\n#endif  /* CTAGS_MAIN_INTERACTIVE_H */\n\n/* vi:set tabstop=4 shiftwidth=4: */\n"
  },
  {
    "path": "main/intern.c",
    "content": "/*\n*\n*   Copyright (c) 2024, Red Hat, Inc.\n*   Copyright (c) 2024, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n\n#include \"general.h\"\n\n#include \"htable.h\"\n#include \"intern.h\"\n#include \"routines.h\"\n\n#include <string.h>\n\nstruct obentry {\n\tstruct obentry *next;\n\tchar quark [];\n};\n\n/* $ find linux -type f | wc -l\n   86267 */\n#define OBARRAY_SIZE    87719\nstatic struct obentry *obarray [OBARRAY_SIZE];\n\nconst char *intern (const char *name)\n{\n\tunsigned int hv = hashCstrhash (name) % OBARRAY_SIZE;\n\tstruct obentry* tmp = obarray [hv];\n\n\twhile (tmp)\n\t{\n\t\tif (!strcmp (tmp->quark, name))\n\t\t\treturn tmp->quark;\n\t\ttmp = tmp->next;\n\t}\n\n\tsize_t len = strlen (name);\n\tstruct obentry *s = eMalloc (sizeof (struct obentry) + len + 1);\n\ts->next = obarray[hv];\n\tmemcpy (s->quark, name, len + 1);\n\n\tobarray[hv] = s;\n\treturn s->quark;\n}\n"
  },
  {
    "path": "main/intern.h",
    "content": "/*\n*\n*   Copyright (c) 2024, Red Hat, Inc.\n*   Copyright (c) 2024, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n#ifndef CTAGS_MAIN_INTERN_H\n#define CTAGS_MAIN_INTERN_H\n\nconst char *intern (const char *name);\n\n#endif\t/* CTAGS_MAIN_INTERN_H */\n"
  },
  {
    "path": "main/interval_tree_generic.h",
    "content": "/*\n  Interval Trees\n  (C) 2012  Michel Lespinasse <walken@google.com>\n\n  This program is free software; you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation; either version 2 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  include/linux/interval_tree_generic.h\n*/\n\n#include \"general.h\"\n\n#include <stdbool.h>\n\n#include \"rbtree_augmented.h\"\n\n#include \"inline.h\"\n\n/*\n * Template for implementing interval trees\n *\n * ITSTRUCT:   struct type of the interval tree nodes\n * ITRB:       name of struct rb_node field within ITSTRUCT\n * ITTYPE:     type of the interval endpoints\n * ITSUBTREE:  name of ITTYPE field within ITSTRUCT holding last-in-subtree\n * ITSTART(n): start endpoint of ITSTRUCT node n\n * ITLAST(n):  last endpoint of ITSTRUCT node n\n * ITSTATIC:   'static' or empty\n * ITPREFIX:   prefix to use for the inline tree definitions\n *\n * Note - before using this, please consider if non-generic version\n * (interval_tree.h) would work for you...\n */\n\n#define INTERVAL_TREE_DEFINE(ITSTRUCT, ITRB, ITTYPE, ITSUBTREE,\t\t\t\\\n\t\t\t     ITSTART, ITLAST, ITSTATIC, ITPREFIX)\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n/* Callbacks for augmented rbtree insert and remove */\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nCTAGS_INLINE ITTYPE ITPREFIX ## _compute_subtree_last(ITSTRUCT *node)\t\\\n{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tITTYPE max = ITLAST(node), subtree_last;\t\t\t\t\t\t\t\\\n\tif (node->ITRB.rb_left) {\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tsubtree_last = rb_entry(node->ITRB.rb_left,\t\t\t\t\t\t\\\n\t\t\t\t\tITSTRUCT, ITRB)->ITSUBTREE;\t\t\t\t\t\t\t\\\n\t\tif (max < subtree_last)\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tmax = subtree_last;\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tif (node->ITRB.rb_right) {\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tsubtree_last = rb_entry(node->ITRB.rb_right,\t\t\t\t\t\\\n\t\t\t\t\tITSTRUCT, ITRB)->ITSUBTREE;\t\t\t\t\t\t\t\\\n\t\tif (max < subtree_last)\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tmax = subtree_last;\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\treturn max;\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nRB_DECLARE_CALLBACKS(static, ITPREFIX ## _augment, ITSTRUCT, ITRB,\t\t\\\n\t\t     ITTYPE, ITSUBTREE, ITPREFIX ## _compute_subtree_last)\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n/* Insert / remove interval nodes from the tree */\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, struct rb_root *root)\t\\\n{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstruct rb_node **link = &root->rb_node, *rb_parent = NULL;\t\t\t\\\n\tITTYPE start = ITSTART(node), last = ITLAST(node);\t\t\t\t\t\\\n\tITSTRUCT *parent;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\twhile (*link) {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\trb_parent = *link;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tparent = rb_entry(rb_parent, ITSTRUCT, ITRB);\t\t\t\t\t\\\n\t\tif (parent->ITSUBTREE < last)\t\t\t\t\t\t\t\t\t\\\n\t\t\tparent->ITSUBTREE = last;\t\t\t\t\t\t\t\t\t\\\n\t\tif (start < ITSTART(parent))\t\t\t\t\t\t\t\t\t\\\n\t\t\tlink = &parent->ITRB.rb_left;\t\t\t\t\t\t\t\t\\\n\t\telse\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tlink = &parent->ITRB.rb_right;\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tnode->ITSUBTREE = last;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\trb_link_node(&node->ITRB, rb_parent, link);\t\t\t\t\t\t\t\\\n\trb_insert_augmented(&node->ITRB, root, &ITPREFIX ## _augment);\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, struct rb_root *root)\t\\\n{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\trb_erase_augmented(&node->ITRB, root, &ITPREFIX ## _augment);\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n/*\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n * Iterate over intervals intersecting [start;last]\t\t\t\t\t\t\\\n *\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n * Note that a node's interval intersects [start;last] iff:\t\t\t\t\\\n *   Cond1: ITSTART(node) <= last\t\t\t\t\t\t\t\t\t\t\\\n * and\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n *   Cond2: start <= ITLAST(node)\t\t\t\t\t\t\t\t\t\t\\\n */\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic ITSTRUCT *\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nITPREFIX ## _subtree_search(ITSTRUCT *node, ITTYPE start, ITTYPE last)\t\\\n{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\twhile (true) {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t/*\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t * Loop invariant: start <= node->ITSUBTREE\t\t\t\t\t\t\\\n\t\t * (Cond2 is satisfied by one of the subtree nodes)\t\t\t\t\\\n\t\t */\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (node->ITRB.rb_left) {\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tITSTRUCT *left = rb_entry(node->ITRB.rb_left,\t\t\t\t\\\n\t\t\t\t\t\t  ITSTRUCT, ITRB);\t\t\t\t\t\t\t\t\\\n\t\t\tif (start <= left->ITSUBTREE) {\t\t\t\t\t\t\t\t\\\n\t\t\t\t/*\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t * Some nodes in left subtree satisfy Cond2.\t\t\t\\\n\t\t\t\t * Iterate to find the leftmost such node N.\t\t\t\\\n\t\t\t\t * If it also satisfies Cond1, that's the\t\t\t\t\\\n\t\t\t\t * match we are looking for. Otherwise, there\t\t\t\\\n\t\t\t\t * is no matching interval as nodes to the\t\t\t\t\\\n\t\t\t\t * right of N can't satisfy Cond1 either.\t\t\t\t\\\n\t\t\t\t */\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\tnode = left;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\tcontinue;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (ITSTART(node) <= last) {\t\t/* Cond1 */\t\t\t\t\t\\\n\t\t\tif (start <= ITLAST(node))\t/* Cond2 */\t\t\t\t\t\t\\\n\t\t\t\treturn node;\t/* node is leftmost match */\t\t\t\\\n\t\t\tif (node->ITRB.rb_right) {\t\t\t\t\t\t\t\t\t\\\n\t\t\t\tnode = rb_entry(node->ITRB.rb_right,\t\t\t\t\t\\\n\t\t\t\t\t\tITSTRUCT, ITRB);\t\t\t\t\t\t\t\t\\\n\t\t\t\tif (start <= node->ITSUBTREE)\t\t\t\t\t\t\t\\\n\t\t\t\t\tcontinue;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn NULL;\t/* No match */\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nITSTATIC ITSTRUCT *\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nITPREFIX ## _iter_first(struct rb_root *root, ITTYPE start, ITTYPE last) \\\n{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tITSTRUCT *node;\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tif (!root->rb_node)\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn NULL;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tnode = rb_entry(root->rb_node, ITSTRUCT, ITRB);\t\t\t\t\t\t\\\n\tif (node->ITSUBTREE < start)\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn NULL;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\treturn ITPREFIX ## _subtree_search(node, start, last);\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nITSTATIC ITSTRUCT *\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nITPREFIX ## _iter_next(ITSTRUCT *node, ITTYPE start, ITTYPE last)\t\t\\\n{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstruct rb_node *rb = node->ITRB.rb_right, *prev;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\twhile (true) {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t/*\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t * Loop invariants:\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t *   Cond1: ITSTART(node) <= last\t\t\t\t\t\t\t\t\\\n\t\t *   rb == node->ITRB.rb_right\t\t\t\t\t\t\t\t\t\\\n\t\t *\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t * First, search right subtree if suitable\t\t\t\t\t\t\\\n\t\t */\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (rb) {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tITSTRUCT *right = rb_entry(rb, ITSTRUCT, ITRB);\t\t\t\t\\\n\t\t\tif (start <= right->ITSUBTREE)\t\t\t\t\t\t\t\t\\\n\t\t\t\treturn ITPREFIX ## _subtree_search(right,\t\t\t\t\\\n\t\t\t\t\t\t\t\tstart, last);\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t/* Move up the tree until we come from a node's left child */\t\\\n\t\tdo {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\trb = rb_parent(&node->ITRB);\t\t\t\t\t\t\t\t\\\n\t\t\tif (!rb)\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\treturn NULL;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tprev = &node->ITRB;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tnode = rb_entry(rb, ITSTRUCT, ITRB);\t\t\t\t\t\t\\\n\t\t\trb = node->ITRB.rb_right;\t\t\t\t\t\t\t\t\t\\\n\t\t} while (prev == rb);\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t/* Check if the node intersects [start;last] */\t\t\t\t\t\\\n\t\tif (last < ITSTART(node))\t\t/* !Cond1 */\t\t\t\t\t\\\n\t\t\treturn NULL;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\telse if (start <= ITLAST(node))\t\t/* Cond2 */\t\t\t\t\t\\\n\t\t\treturn node;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\n"
  },
  {
    "path": "main/keyword.c",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Manages a keyword hash.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <ctype.h>\n\n#include \"debug.h\"\n#include \"keyword.h\"\n#include \"keyword_p.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef struct sHashEntry {\n\tstruct sHashEntry *next;\n\tconst char *string;\n\tlangType language;\n\tint value;\n} hashEntry;\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic const unsigned int TableSize = 2039;  /* prime */\nstatic hashEntry **HashTable = NULL;\nstatic unsigned int MaxEntryLen = 0;\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic hashEntry **getHashTable (void)\n{\n\tstatic bool allocated = false;\n\n\tif (! allocated)\n\t{\n\t\tunsigned int i;\n\n\t\tHashTable = xMalloc (TableSize, hashEntry*);\n\n\t\tfor (i = 0  ;  i < TableSize  ;  ++i)\n\t\t\tHashTable [i] = NULL;\n\n\t\tallocated = true;\n\t}\n\treturn HashTable;\n}\n\nstatic hashEntry *getHashTableEntry (unsigned long hashedValue)\n{\n\thashEntry **const table = getHashTable ();\n\thashEntry *entry;\n\n\tAssert (hashedValue < TableSize);\n\tentry = table [hashedValue];\n\n\treturn entry;\n}\n\nstatic unsigned int hashValue (const char *const string, langType language,\n\tunsigned int maxLen, bool *maxLenReached)\n{\n\tconst char *p;\n\tunsigned int h = 5381;\n\n\tAssert (string != NULL);\n\n\t/* \"djb\" hash as used in g_str_hash() in glib */\n\tfor (p = string; *p != '\\0'; p++)\n\t{\n\t\th = (h << 5) + h + (signed char) tolower ((unsigned char) *p);\n\n\t\tif (p > string + maxLen)\n\t\t{\n\t\t\t*maxLenReached = true;\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* consider language as an extra \"character\" and add it to the hash */\n\th = (h << 5) + h + language;\n\n\t*maxLenReached = false;\n\treturn h;\n}\n\nstatic hashEntry *newEntry (\n\t\tconst char *const string, langType language, int value)\n{\n\thashEntry *const entry = xMalloc (1, hashEntry);\n\n\tentry->next     = NULL;\n\tentry->string   = string;\n\tentry->language = language;\n\tentry->value    = value;\n\n\treturn entry;\n}\n\n/*  Note that it is assumed that a \"value\" of zero means an undefined keyword\n *  and clients of this function should observe this. Also, all keywords added\n *  should be added in lower case. If we encounter a case-sensitive language\n *  whose keywords are in upper case, we will need to redesign this.\n */\nextern void addKeyword (const char *const string, langType language, int value)\n{\n\tbool dummy;\n\tconst unsigned int index = hashValue (string, language, 1000, &dummy) % TableSize;\n\thashEntry *entry = getHashTableEntry (index);\n\tsize_t len = strlen (string);\n\n\tif (len > MaxEntryLen)\n\t\tMaxEntryLen = len;\n\n\tif (entry == NULL)\n\t{\n\t\thashEntry **const table = getHashTable ();\n\t\ttable [index] = newEntry (string, language, value);\n\t}\n\telse\n\t{\n\t\thashEntry *prev = NULL;\n\n\t\twhile (entry != NULL)\n\t\t{\n\t\t\tif (language == entry->language  &&\n\t\t\t\tstrcmp (string, entry->string) == 0)\n\t\t\t{\n\t\t\t\tAssert ((\"Already in table\" == NULL));\n\t\t\t}\n\t\t\tprev = entry;\n\t\t\tentry = entry->next;\n\t\t}\n\t\tif (entry == NULL)\n\t\t{\n\t\t\tAssert (prev != NULL);\n\t\t\tprev->next = newEntry (string, language, value);\n\t\t}\n\t}\n}\n\nstatic int lookupKeywordFull (const char *const string, bool caseSensitive, langType language)\n{\n\tbool maxLenReached;\n\tconst unsigned int index = hashValue (string, language, MaxEntryLen, &maxLenReached) % TableSize;\n\thashEntry *entry;\n\tint result = KEYWORD_NONE;\n\n\tif (maxLenReached)\n\t\treturn KEYWORD_NONE;\n\n\tentry = getHashTableEntry (index);\n\n\twhile (entry != NULL)\n\t{\n\t\tif (language == entry->language &&\n\t\t\t((caseSensitive && strcmp (string, entry->string) == 0) ||\n\t\t\t (!caseSensitive && strcasecmp (string, entry->string) == 0)))\n\t\t{\n\t\t\tresult = entry->value;\n\t\t\tbreak;\n\t\t}\n\t\tentry = entry->next;\n\t}\n\treturn result;\n}\n\nextern int lookupKeyword (const char *const string, langType language)\n{\n\treturn lookupKeywordFull (string, true, language);\n}\n\nextern int lookupCaseKeyword (const char *const string, langType language)\n{\n\treturn lookupKeywordFull (string, false, language);\n}\n\nextern void freeKeywordTable (void)\n{\n\tif (HashTable != NULL)\n\t{\n\t\tunsigned int i;\n\n\t\tfor (i = 0  ;  i < TableSize  ;  ++i)\n\t\t{\n\t\t\thashEntry *entry = HashTable [i];\n\n\t\t\twhile (entry != NULL)\n\t\t\t{\n\t\t\t\thashEntry *next = entry->next;\n\t\t\t\teFree (entry);\n\t\t\t\tentry = next;\n\t\t\t}\n\t\t}\n\t\teFree (HashTable);\n\t}\n}\n\n#ifdef DEBUG\n\nstatic void printEntry (const hashEntry *const entry)\n{\n\tprintf (\"  %-15s %-7s\\n\", entry->string, getLanguageName (entry->language));\n}\n\nstatic unsigned int printBucket (const unsigned int i)\n{\n\thashEntry **const table = getHashTable ();\n\thashEntry *entry = table [i];\n\tunsigned int measure = 1;\n\tbool first = true;\n\n\tprintf (\"%2d:\", i);\n\tif (entry == NULL)\n\t\tprintf (\"\\n\");\n\telse while (entry != NULL)\n\t{\n\t\tif (! first)\n\t\t\tprintf (\"    \");\n\t\telse\n\t\t{\n\t\t\tprintf (\" \");\n\t\t\tfirst = false;\n\t\t}\n\t\tprintEntry (entry);\n\t\tentry = entry->next;\n\t\tmeasure = 2 * measure;\n\t}\n\treturn measure - 1;\n}\n\nextern void printKeywordTable (void)\n{\n\tunsigned long emptyBucketCount = 0;\n\tunsigned long measure = 0;\n\tunsigned int i;\n\n\tfor (i = 0  ;  i < TableSize  ;  ++i)\n\t{\n\t\tconst unsigned int pass = printBucket (i);\n\n\t\tmeasure += pass;\n\t\tif (pass == 0)\n\t\t\t++emptyBucketCount;\n\t}\n\n\tprintf (\"spread measure = %ld\\n\", measure);\n\tprintf (\"%ld empty buckets\\n\", emptyBucketCount);\n}\n\n#endif\n\nextern void dumpKeywordTable (FILE *fp)\n{\n\tunsigned int i;\n\tfor (i = 0  ;  i < TableSize  ;  ++i)\n\t{\n\t\thashEntry **const table = getHashTable ();\n\t\thashEntry *entry = table [i];\n\t\twhile (entry != NULL)\n\t\t{\n\t\t\tfprintf(fp, \"%s\t%s\\n\", entry->string, getLanguageName (entry->language));\n\t\t\tentry = entry->next;\n\t\t}\n\t}\n}\n\nextern void addKeywordGroup (const struct keywordGroup *const groupdef,\n\t\t\t\t\t\t\t langType language)\n{\n\tfor (int i = 0; groupdef->keywords[i]; i++)\n\t{\n\t\tif (groupdef->addingUnlessExisting)\n\t\t{\n\t\t\tif (lookupKeyword (groupdef->keywords[i],\n\t\t\t\t\t\t\t   language) != KEYWORD_NONE)\n\t\t\t\tcontinue;\t\t/* already added */\n\t\t}\n\t\telse\n\t\t\tAssert (lookupKeyword (groupdef->keywords[i],\n\t\t\t\t\t\t\t\t   language) == KEYWORD_NONE);\n\t\taddKeyword (groupdef->keywords[i], language, groupdef->value);\n\t}\n}\n\nextern void addDialectalKeywords (const struct dialectalKeyword *const dkeywords,\n\t\t\t\t\t\t\t\t  size_t nDkeyword,\n\t\t\t\t\t\t\t\t  langType language,\n\t\t\t\t\t\t\t\t  const char **dialectMap,\n\t\t\t\t\t\t\t\t  size_t nMap)\n{\n\tint dialect = -1;\n\tconst char *name = getLanguageName (language);\n\n\tAssert(name);\n\n\tfor (size_t i = 0; i < nMap; i++)\n\t{\n\t\tif (strcmp(dialectMap[i], name) == 0)\n\t\t{\n\t\t\tdialect = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\tAssert (dialect != -1);\n\n\tfor (size_t i = 0; i < nDkeyword; i++)\n\t{\n\t\tconst struct dialectalKeyword *p = dkeywords + i;\n\t\tif (p->isValid[dialect])\n\t\t\taddKeyword (p->keyword, language, p->value);\n\t}\n}\n"
  },
  {
    "path": "main/keyword.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to keyword.c\n*/\n#ifndef CTAGS_MAIN_KEYWORD_H\n#define CTAGS_MAIN_KEYWORD_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"types.h\"\n\n/*\n*   MACROS\n*/\n#define KEYWORD_NONE -1\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void addKeyword (const char *const string, langType language, int value);\nextern int lookupKeyword (const char *const string, langType language);\nextern int lookupCaseKeyword (const char *const string, langType language);\n\n/*\n* KEYWORD GROUP API: Adding keywords for value in batch\n*/\nstruct keywordGroup {\n\tint value;\n\tbool addingUnlessExisting;\n\tconst char *keywords []; \t/* NULL terminated */\n};\n\nextern void addKeywordGroup (const struct keywordGroup *const groupdef,\n\t\t\t\t\t\t\t langType language);\n\n/*\n* DIALECTAL KEYWROD API\n*/\n#define MAX_DIALECTS 10\nstruct dialectalKeyword {\n\tconst char *keyword;\n\tint value;\n\n\t/* If this keyword is valid for Nth dialect,\n\t   isValid[N] should be 1; else 0. */\n\tbool isValid [MAX_DIALECTS];\n};\n\nextern void addDialectalKeywords (const struct dialectalKeyword *const dkeywords,\n\t\t\t\t\t\t\t\t  size_t nDkeyword,\n\t\t\t\t\t\t\t\t  langType language,\n\t\t\t\t\t\t\t\t  const char **dialectMap,\n\t\t\t\t\t\t\t\t  size_t nMap);\n\n#endif  /* CTAGS_MAIN_KEYWORD_H */\n"
  },
  {
    "path": "main/keyword_p.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   main part private interface to keyword.c\n*/\n#ifndef CTAGS_MAIN_KEYWORD_PRIVATE_H\n#define CTAGS_MAIN_KEYWORD_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include <stdio.h>\n\nextern void freeKeywordTable (void);\n\nextern void dumpKeywordTable (FILE *fp);\n\n#ifdef DEBUG\nextern void printKeywordTable (void);\n#endif\n\n#endif\t/* CTAGS_MAIN_KEYWORD_PRIVATE_H */\n"
  },
  {
    "path": "main/kind.c",
    "content": "/*\n *\n *  Copyright (c) 2015, Red Hat, Inc.\n *  Copyright (c) 2015, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#include \"general.h\"\n\n#include <ctype.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"colprint_p.h\"\n#include \"ctags.h\"\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"parse_p.h\"\n#include \"options.h\"\n#include \"ptrarray.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\ntypedef struct sRoleObject {\n\troleDefinition *def;\n\tfreeRoleDefFunc free;\n} roleObject;\n\nstruct roleControlBlock {\n\troleObject *role;\n\tunsigned int count;\n\tint owner;\n};\n\ntypedef struct sKindObject {\n\tkindDefinition *def;\n\tfreeKindDefFunc free;\n\tstruct roleControlBlock *rcb;\n\tptrArray * dynamicSeparators;\n} kindObject;\n\nstruct kindControlBlock {\n\tkindObject *kind;\n\tunsigned int count;\n\tlangType owner;\n\tscopeSeparator defaultScopeSeparator;\n\tscopeSeparator defaultRootScopeSeparator;\n};\n\nextern const char *renderRole (const roleDefinition* const role, vString* b)\n{\n\tvStringCatS (b, role->name);\n\treturn vStringValue (b);\n}\n\nextern void printKind (const kindDefinition* const kind, bool indent)\n{\n\tprintf (\"%s%c  %s%s\\n\", indent ? \"    \" : \"\", kind->letter,\n\t\t\tkind->description != NULL ? kind->description :\n\t\t\t(kind->name != NULL ? kind->name : \"\"),\n\t\t\tkind->enabled ? \"\" : \" [off]\");\n}\n\nextern void enableKind (kindDefinition *kind, bool enable)\n{\n\tkindDefinition *slave;\n\n\tif (kind->master)\n\t\tenableKind (kind->master, enable);\n\telse\n\t{\n\t\tkind->enabled = enable;\n\t\tfor (slave = kind->slave; slave; slave = slave->slave)\n\t\t\tslave->enabled = enable;\n\t}\n}\n\nextern void enableRole (roleDefinition *role, bool enable)\n{\n\trole->enabled = enable;\n}\n\nstatic void initRoleObject (roleObject *robj, roleDefinition *rdef, freeRoleDefFunc freefunc, int roleId)\n{\n#ifdef DEBUG\n\tsize_t len = strlen (rdef->name);\n\tfor (int i = 0; i < len; i++)\n\t\tAssert (isalnum ((unsigned char) rdef->name [i]));\n#endif\n\trobj->def = rdef;\n\trobj->free = freefunc;\n\trobj->def->id = roleId;\n}\n\nstatic struct roleControlBlock* allocRoleControlBlock (kindObject *kind)\n{\n\tunsigned int j;\n\tstruct roleControlBlock* rcb;\n\n\trcb = xMalloc(1, struct roleControlBlock);\n\trcb->count = kind->def->nRoles;\n\trcb->owner = kind->def->id;\n\trcb->role = xMalloc(rcb->count, roleObject);\n\tfor (j = 0; j < rcb->count; j++)\n\t\tinitRoleObject (rcb->role + j, kind->def->roles + j, NULL, j);\n\n\treturn rcb;\n}\n\nextern struct kindControlBlock* allocKindControlBlock (parserDefinition *parser)\n{\n\tunsigned int i;\n\tstruct kindControlBlock *kcb;\n\n\tkcb = xMalloc (1, struct kindControlBlock);\n\tkcb->kind = xMalloc (parser->kindCount, kindObject);\n\tkcb->count = parser->kindCount;\n\tkcb->owner = parser->id;\n\n\tkcb->defaultScopeSeparator.parentKindIndex = KIND_WILDCARD_INDEX;\n\tkcb->defaultScopeSeparator.separator = NULL;\n\tif (parser->defaultScopeSeparator)\n\t\tkcb->defaultScopeSeparator.separator = eStrdup (parser->defaultScopeSeparator);\n\n\tkcb->defaultRootScopeSeparator.parentKindIndex = KIND_GHOST_INDEX;\n\tkcb->defaultRootScopeSeparator.separator = NULL;\n\tif (parser->defaultRootScopeSeparator)\n\t\tkcb->defaultRootScopeSeparator.separator = eStrdup (parser->defaultRootScopeSeparator);\n\n\tfor (i = 0; i < parser->kindCount; ++i)\n\t{\n\t\tkindObject *kind = kcb->kind + i;\n\t\tkind->def = parser->kindTable + i;\n\n\t\tAssert (kind->def->letter != KIND_FILE_DEFAULT_LETTER);\n\t\tAssert (kind->def->name == NULL /* SELF (RUNTIME) TEST NEEDS THIS. */\n\t\t\t\t|| strcmp(kind->def->name, KIND_FILE_DEFAULT_NAME));\n\n\t\tkind->free = NULL;\n\t\tkind->def->id = i;\n\t\tkind->rcb = allocRoleControlBlock (kind);\n\t\tkind->dynamicSeparators = NULL;\n\t}\n\n\treturn kcb;\n}\n\nstatic void freeRoleControlBlock (struct roleControlBlock *rcb)\n{\n\tunsigned int i;\n\tfor (i = 0; i < rcb->count; ++i)\n\t{\n\t\tif (rcb->role[i].free)\n\t\t\trcb->role [i].free (rcb->role [i].def);\n\t}\n\teFreeNoNullCheck (rcb->role);\n\teFree (rcb);\n}\n\nextern void freeKindControlBlock (struct kindControlBlock* kcb)\n{\n\tunsigned int i;\n\n\tfor (i = 0; i < kcb->count; ++i)\n\t{\n\t\tif (kcb->kind [i].free)\n\t\t\tkcb->kind [i].free (kcb->kind [i].def);\n\t\tfreeRoleControlBlock (kcb->kind [i].rcb);\n\t\tif (kcb->kind [i].dynamicSeparators)\n\t\t\tptrArrayDelete(kcb->kind [i].dynamicSeparators);\n\t}\n\n\tif (kcb->defaultRootScopeSeparator.separator)\n\t\teFree((char *)kcb->defaultRootScopeSeparator.separator);\n\tif (kcb->defaultScopeSeparator.separator)\n\t\teFree((char *)kcb->defaultScopeSeparator.separator);\n\n\tif (kcb->kind)\n\t\teFree (kcb->kind);\n\teFree (kcb);\n}\n\nextern int  defineKind (struct kindControlBlock* kcb, kindDefinition *def,\n\t\t\t\t\t\tfreeKindDefFunc freeKindDef)\n{\n\tdef->id = kcb->count++;\n\tkcb->kind = xRealloc (kcb->kind, kcb->count, kindObject);\n\tkcb->kind [def->id].def = def;\n\tkcb->kind [def->id].free = freeKindDef;\n\tkcb->kind [def->id].rcb = allocRoleControlBlock(kcb->kind + def->id);\n\tkcb->kind [def->id].dynamicSeparators = NULL;\n\n\tif (def->version > getLanguageVersionCurrent (kcb->owner))\n\t\terror (WARNING, \"the version number (%u) of kind \\\"%c,%s\\\" of language \\\"%s\\\" \"\n\t\t\t   \"should be less than or equal to the current number (%u) of the language\",\n\t\t\t   def->version, def->letter, def->name, getLanguageName (kcb->owner),\n\t\t\t   getLanguageVersionCurrent (kcb->owner));\n\n\tverbose (\"Add kind[%d] \\\"%c,%s,%s\\\" to %s\\n\", def->id,\n\t\t\t def->letter, def->name, def->description,\n\t\t\t getLanguageName (kcb->owner));\n\n\treturn def->id;\n}\n\nextern int defineRole (struct kindControlBlock* kcb, int kindIndex,\n\t\t\t\t\t   roleDefinition *def, freeRoleDefFunc freeRoleDef)\n{\n\tstruct roleControlBlock *rcb = kcb->kind[kindIndex].rcb;\n\tint roleIndex = rcb->count++;\n\n\tif (roleIndex == ROLE_MAX_COUNT)\n\t{\n\t\trcb->count--;\n\t\terror (FATAL, \"Too many role definition for kind \\\"%s\\\" of language \\\"%s\\\" (> %d)\",\n\t\t\t   kcb->kind[kindIndex].def->name,\n\t\t\t   getLanguageName (kcb->owner),\n\t\t\t   (int)(ROLE_MAX_COUNT - 1));\n\t}\n\n\trcb->role = xRealloc (rcb->role, rcb->count, roleObject);\n\tinitRoleObject (rcb->role + roleIndex, def, freeRoleDef, roleIndex);\n\n\tif (def->version > getLanguageVersionCurrent (kcb->owner))\n\t\terror (WARNING, \"the version number (%u) of role \\\"%s\\\" of language \\\"%s\\\" \"\n\t\t\t   \"should be less than or equal to the current number (%u) of the language\",\n\t\t\t   def->version, def->name, getLanguageName (kcb->owner),\n\t\t\t   getLanguageVersionCurrent (kcb->owner));\n\tkindDefinition * kdef = getKind (kcb, kindIndex);\n\tif (kdef->version > def->version)\n\t\terror (WARNING, \"the version number (%u) of role \\\"%s\\\" in kind \\\"%c,%s\\\" of language \\\"%s\\\" \"\n\t\t\t   \"should be greater than or equal to the version number (%u) of its kind\",\n\t\t\t   def->version, def->name,\n\t\t\t   kdef->letter, kdef->name,\n\t\t\t   getLanguageName (kcb->owner),\n\t\t\t   kdef->version);\n\n\treturn roleIndex;\n}\n\nextern bool isRoleEnabled (struct kindControlBlock* kcb, int kindIndex, int roleIndex)\n{\n\troleDefinition *rdef = getRole (kcb, kindIndex, roleIndex);\n\treturn rdef->enabled;\n}\n\nextern unsigned int countKinds (struct kindControlBlock* kcb)\n{\n\treturn kcb->count;\n}\n\nextern unsigned int countRoles (struct kindControlBlock* kcb, int kindIndex)\n{\n\treturn kcb->kind [kindIndex].rcb->count;\n}\n\nextern kindDefinition *getKind (struct kindControlBlock* kcb, int kindIndex)\n{\n\treturn kcb->kind [kindIndex].def;\n}\n\nextern kindDefinition *getKindForLetter (struct kindControlBlock* kcb, char letter)\n{\n\tunsigned int i;\n\tkindDefinition * kdef;\n\n\tfor (i = 0;  i < countKinds (kcb);  ++i)\n\t{\n\t\tkdef = getKind (kcb, i);\n\t\tif (kdef->letter == letter)\n\t\t\treturn kdef;\n\t}\n\treturn NULL;\n}\n\nextern kindDefinition *getKindForName (struct kindControlBlock* kcb, const char* name)\n{\n\tunsigned int i;\n\tkindDefinition * kdef;\n\n\tfor (i = 0;  i < countKinds (kcb);  ++i)\n\t{\n\t\tkdef = getKind (kcb, i);\n\t\tAssert(kdef);\n\t\tif (kdef->name && (strcmp(kdef->name, name) == 0))\n\t\t\treturn kdef;\n\t}\n\treturn NULL;\n}\n\nextern int getKindIndexForLetter (struct kindControlBlock* kcb, char letter)\n{\n\tunsigned int i;\n\tkindDefinition * kdef;\n\n\tfor (i = 0;  i < countKinds (kcb);  ++i)\n\t{\n\t\tkdef = getKind (kcb, i);\n\t\tif (kdef->letter == letter)\n\t\t\treturn (unsigned int)i;\n\t}\n\treturn KIND_GHOST_INDEX;\n}\n\nextern int getKindIndexForName (struct kindControlBlock* kcb, const char* name)\n{\n\tunsigned int i;\n\tkindDefinition * kdef;\n\n\tfor (i = 0;  i < countKinds (kcb);  ++i)\n\t{\n\t\tkdef = getKind (kcb, i);\n\t\tAssert(kdef);\n\t\tif (kdef->name && (strcmp(kdef->name, name) == 0))\n\t\t\treturn (int)i;\n\t}\n\treturn KIND_GHOST_INDEX;\n}\n\nextern roleDefinition* getRole(struct kindControlBlock* kcb, int kindIndex, int roleIndex)\n{\n\tstruct roleControlBlock *rcb = kcb->kind[kindIndex].rcb;\n\treturn rcb->role [roleIndex].def;\n}\n\nextern roleDefinition* getRoleForName(struct kindControlBlock* kcb,\n\t\t\t\t\t\t\t\t\t  int kindIndex, const char* name)\n{\n\tunsigned int i;\n\troleDefinition *rdef;\n\n\tfor (i = 0; i < countRoles (kcb, kindIndex); ++i)\n\t{\n\t\trdef = getRole(kcb, kindIndex, i);\n\t\tAssert(rdef);\n\t\tif (rdef->name && (strcmp(rdef->name, name) == 0))\n\t\t\treturn rdef;\n\t}\n\treturn NULL;\n}\n\nstatic void linkKinds (langType master, kindDefinition *masterKind, kindDefinition *slaveKind)\n{\n\tkindDefinition *tail;\n\n\tslaveKind->master = masterKind;\n\n\ttail = slaveKind;\n\twhile (tail->slave)\n\t{\n\t\ttail->enabled = masterKind->enabled;\n\t\ttail = tail->slave;\n\t}\n\n\ttail->slave = masterKind->slave;\n\tmasterKind->slave = slaveKind;\n\n\tmasterKind->syncWith = master;\n\tslaveKind->syncWith = master;\n}\n\nextern void linkKindDependency (struct kindControlBlock *masterKCB,\n\t\t\t\t\t\t\t\tstruct kindControlBlock *slaveKCB)\n{\n\tunsigned int k_slave, k_master;\n\tkindDefinition *kind_slave, *kind_master;\n\n\tfor (k_slave = 0; k_slave < countKinds (slaveKCB); k_slave++)\n\t{\n\t\tkind_slave = getKind(slaveKCB, k_slave);\n\t\tif (kind_slave->syncWith == LANG_AUTO)\n\t\t{\n\t\t\tfor (k_master = 0; k_master < countKinds (masterKCB); k_master++)\n\t\t\t{\n\t\t\t\tkind_master = getKind(masterKCB, k_master);\n\t\t\t\tif ((kind_slave->letter == kind_master->letter)\n\t\t\t\t    && (strcmp (kind_slave->name, kind_master->name) == 0))\n\t\t\t\t{\n\t\t\t\t\tlinkKinds (masterKCB->owner, kind_master, kind_slave);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void scopeSeparatorDelete (void *data)\n{\n\tscopeSeparator *sep = data;\n\teFree ((void *)sep->separator);\n\tsep->separator = NULL;\n\teFree (sep);\n}\n\nextern int defineScopeSeparator(struct kindControlBlock* kcb,\n\t\t\t\t\t\t\t\tint kindIndex,\n\t\t\t\t\t\t\t\tint parentKindIndex, const char *separator)\n{\n\tif (kindIndex == KIND_WILDCARD_INDEX)\n\t{\n\t\tif (parentKindIndex == KIND_WILDCARD_INDEX)\n\t\t{\n\t\t\tif (kcb->defaultScopeSeparator.separator)\n\t\t\t\teFree ((char *)kcb->defaultScopeSeparator.separator);\n\t\t\tverbose (\"Installing default separator for %s: %s\\n\",\n\t\t\t\t\t getLanguageName (kcb->owner), separator);\n\t\t\tkcb->defaultScopeSeparator.separator = eStrdup (separator);\n\t\t}\n\t\telse if (parentKindIndex == KIND_GHOST_INDEX)\n\t\t{\n\t\t\tif (kcb->defaultRootScopeSeparator.separator)\n\t\t\t\teFree ((char *)kcb->defaultRootScopeSeparator.separator);\n\t\t\tverbose (\"Installing default root separator for %s: %s\\n\",\n\t\t\t\t\t getLanguageName (kcb->owner),\n\t\t\t\t\t separator);\n\t\t\tkcb->defaultRootScopeSeparator.separator = eStrdup (separator);\n\t\t}\n\t\telse\n\t\t\terror (FATAL,\n\t\t\t\t   \"Don't specify a real kind as parent when defining a default scope separator: %d\",\n\t\t\t\t   parentKindIndex);\n\t\treturn 0;\n\t}\n\tAssert (kcb->count > kindIndex);\n\tkindObject *kind = kcb->kind + kindIndex;\n\n\tif (!kind->dynamicSeparators)\n\t\tkind->dynamicSeparators = ptrArrayNew (scopeSeparatorDelete);\n\n\tscopeSeparator *sep = xMalloc (1, scopeSeparator);\n\tsep->parentKindIndex = parentKindIndex;\n\tsep->separator = eStrdup(separator);\n\tptrArrayAdd (kind->dynamicSeparators, sep);\n\n\treturn 0;\n}\n\nstatic scopeSeparator *getScopeSeparatorDynamic(kindObject *kobj, int parentKindIndex)\n{\n\tscopeSeparator *sep;\n\n\tif (kobj->dynamicSeparators)\n\t{\n\t\tfor (unsigned int i = ptrArrayCount (kobj->dynamicSeparators); 0 < i ; i--)\n\t\t{\n\t\t\tsep = ptrArrayItem (kobj->dynamicSeparators, i - 1);\n\t\t\tif (sep->parentKindIndex == parentKindIndex)\n\t\t\t\treturn sep;\n\t\t}\n\t}\n\treturn NULL;\n}\n\nstatic const scopeSeparator *getScopeSeparatorStatic(kindDefinition *kdef, int parentKindIndex)\n{\n\tscopeSeparator *table = kdef->separators;\n\n\tif (table == NULL)\n\t\treturn NULL;\n\n\twhile (table - kdef->separators < (int)kdef->separatorCount)\n\t{\n\t\tif (table->parentKindIndex == parentKindIndex)\n\t\t\treturn table;\n\n\t\t/* If a caller wants a root separator for kdef,\n\t\t   we should not return a wildcard table. */\n\t\tif (parentKindIndex != KIND_GHOST_INDEX\n\t\t\t&& table->parentKindIndex == KIND_WILDCARD_INDEX)\n\t\t\treturn table;\n\n\t\ttable++;\n\t}\n\n\treturn NULL;\n}\n\nextern const scopeSeparator *getScopeSeparator(struct kindControlBlock* kcb,\n\t\t\t\t\t\t\t\t\t\t\t   int kindIndex, int parentKindIndex)\n{\n\tAssert (kindIndex != KIND_GHOST_INDEX);\n\tAssert (kindIndex != KIND_FILE_INDEX);\n\tAssert (kindIndex != KIND_WILDCARD_INDEX);\n\n\tAssert (parentKindIndex != KIND_WILDCARD_INDEX);\n\tAssert (parentKindIndex != KIND_FILE_INDEX);\n\t/* A caller specifies KIND_GHOST_INDEX for parentKindIndex when it\n\t * wants root separator. */\n\n\tAssert (kcb->count > kindIndex);\n\tkindObject *kobj = kcb->kind + kindIndex;\n\tconst scopeSeparator *sep;\n\n\tsep = getScopeSeparatorDynamic (kobj, parentKindIndex);\n\tif (sep)\n\t\treturn sep;\n\n\tsep = getScopeSeparatorStatic (kobj->def, parentKindIndex);\n\tif (sep)\n\t\treturn sep;\n\n\t/* Cannot find a suitable sep definition.\n\t * Use default one. */\n\tif (parentKindIndex == KIND_GHOST_INDEX)\n\t{\n\t\tif (kcb->defaultRootScopeSeparator.separator)\n\t\t\treturn &kcb->defaultRootScopeSeparator;\n\t\treturn NULL;\n\t}\n\telse\n\t{\n\t\tif (kcb->defaultScopeSeparator.separator)\n\t\t\treturn &kcb->defaultScopeSeparator;\n\n\t\tstatic scopeSeparator defaultSeparator = {\n\t\t\t.separator = \".\",\n\t\t\t.parentKindIndex = KIND_WILDCARD_INDEX,\n\t\t};\n\t\treturn &defaultSeparator;\n\t}\n}\n\n#ifdef DEBUG\nextern bool doesParserUseKind (struct kindControlBlock* kcb, char letter)\n{\n\tunsigned int k;\n\tkindDefinition *kdef;\n\n\tfor (k = 0; k < countKinds (kcb); k++)\n\t{\n\t\tkdef = getKind(kcb, k);\n\t\tif (kdef->letter == letter)\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n#endif\n\nextern struct colprintTable * kindColprintTableNew (void)\n{\n\treturn colprintTableNew (\"L:LANGUAGE\", \"L:LETTER\", \"L:NAME\", \"L:ENABLED\",\n\t\t\t\t\t\t\t \"L:REFONLY\", \"L:NROLES\", \"L:MASTER\",\n\t\t\t\t\t\t\t \"R:VER\", \"L:DESCRIPTION\",\n\t\t\t\t\t\t\t NULL);\n}\n\nstatic void kindColprintFillLine (struct colprintLine *line,\n\t\t\t\t\t\t\t\t  const char *langName,\n\t\t\t\t\t\t\t\t  kindDefinition *kdef)\n{\n\tlangType lang = getNamedLanguage (langName, 0);\n\tunsigned int count = countLanguageRoles(lang, kdef->id);\n\tcolprintLineAppendColumnCString (line, langName);\n\tcolprintLineAppendColumnChar (line, kdef->letter);\n\tcolprintLineAppendColumnCString (line, kdef->name\n\t\t\t\t\t\t\t\t\t ? kdef->name\n\t\t\t\t\t\t\t\t\t : \"ThisShouldNotBePrintedKindNameMustBeGiven\");\n\tcolprintLineAppendColumnBool (line, kdef->enabled);\n\tcolprintLineAppendColumnBool (line, kdef->referenceOnly);\n\tcolprintLineAppendColumnInt (line, count);\n\tcolprintLineAppendColumnCString (line, (kdef->master\n\t\t\t\t\t\t\t\t\t\t\t|| kdef->slave ) ?\n\t\t\t\t\t\t\t\t\t getLanguageName (kdef->syncWith): RSV_NONE);\n\tcolprintLineAppendColumnVersion (line, kdef->version);\n\tcolprintLineAppendColumnCString (line, kdef->description? kdef->description: \"NO DESCRIPTION GIVEN\");\n}\n\nextern void kindColprintAddLanguageLines (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\t\t  struct kindControlBlock* kcb)\n{\n\tconst char *lang = getLanguageName (kcb->owner);\n\tfor (unsigned int i = 0; i < countKinds (kcb); i++)\n\t{\n\t\tkindDefinition *kdef = getKind (kcb, i);\n\t\tstruct colprintLine *line = colprintTableGetNewLine(table);\n\n\t\tkindColprintFillLine (line, lang, kdef);\n\t}\n}\n\nstatic int kindColprintCompareLines (struct colprintLine *a , struct colprintLine *b)\n{\n\tconst char *a_parser = colprintLineGetColumn (a, 0);\n\tconst char *b_parser = colprintLineGetColumn (b, 0);\n\tconst char *a_letter;\n\tconst char *b_letter;\n\tint r;\n\n\tr = strcmp (a_parser, b_parser);\n\tif (r != 0)\n\t\treturn r;\n\n\ta_letter = colprintLineGetColumn (a, 1);\n\tb_letter = colprintLineGetColumn (b, 1);\n\tr = strcmp (a_letter, b_letter);\n\tif (r != 0)\n\t\treturn r;\n\n\treturn 0;\n}\n\nextern void kindColprintTablePrint (struct colprintTable *table, bool noparser,\n\t\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp)\n{\n\tcolprintTableSort (table, kindColprintCompareLines);\n\tcolprintTablePrint (table, noparser? 1: 0, withListHeader, machinable, fp);\n}\n\n\nextern struct colprintTable * roleColprintTableNew (void)\n{\n\treturn colprintTableNew (\"L:LANGUAGE\", \"L:KIND(L/N)\", \"L:NAME\",\n\t\t\t\t\t\t\t \"L:ENABLED\", \"R:VER\", \"L:DESCRIPTION\", NULL);\n}\n\nextern void roleColprintAddRoles (struct colprintTable *table, struct kindControlBlock *kcb,\n\t\t\t\t\t\t\t\t  const char *kindspecs)\n{\n\tconst char* lang;\n\tvString *kind_l_and_n;\n\n\tlang = getLanguageName (kcb->owner);\n\tkind_l_and_n = vStringNew ();\n\tfor (const char *c = kindspecs; *c != '\\0'; c++)\n\t{\n\t\tconst char *kname = NULL;\n\t\tsize_t kname_len;\n\n\t\tif (*c == '{')\n\t\t{\n\t\t\tconst char *start = c + 1;\n\t\t\tconst char *end = strchr(c, '}');\n\n\t\t\tif (!end)\n\t\t\t\terror (FATAL, \"'{' is not closed with '}' in \\\"%s\\\"\", c);\n\t\t\tif (start == end)\n\t\t\t\terror (FATAL, \"empty kind name is given in \\\"%s\\\"\", c);\n\n\t\t\tkname = start;\n\t\t\tkname_len = end - start;\n\t\t\tc = end;\n\t\t}\n\n\t\tfor (unsigned int i = 0; i < countKinds (kcb); i++)\n\t\t{\n\t\t\tconst kindDefinition *k = getKind (kcb, i);\n\n\t\t\tif ((kname\n\t\t\t\t && strlen (k->name) == kname_len\n\t\t\t\t && strncmp (k->name, kname, kname_len) == 0)\n\t\t\t\t|| (!kname && *c == k->letter)\n\t\t\t\t|| (!kname && *c == KIND_WILDCARD_LETTER))\n\t\t\t{\n\t\t\t\tunsigned int nRoles = countRoles(kcb, i);\n\t\t\t\tfor (unsigned int j = 0; j < nRoles; j++)\n\t\t\t\t{\n\t\t\t\t\tconst roleDefinition *r = getRole (kcb, i, j);\n\t\t\t\t\tstruct colprintLine *line = colprintTableGetNewLine(table);\n\n\t\t\t\t\tcolprintLineAppendColumnCString (line, lang);\n\n\t\t\t\t\tvStringPut (kind_l_and_n, k->letter);\n\t\t\t\t\tvStringPut (kind_l_and_n, '/');\n\t\t\t\t\tvStringCatS (kind_l_and_n, k->name);\n\t\t\t\t\tcolprintLineAppendColumnVString (line, kind_l_and_n);\n\t\t\t\t\tvStringClear (kind_l_and_n);\n\n\t\t\t\t\tcolprintLineAppendColumnCString (line, r->name);\n\t\t\t\t\tcolprintLineAppendColumnCString (line,\n\t\t\t\t\t\t\t\t\t\t\t\t\t r->enabled ? \"on\" : \"off\");\n\t\t\t\t\tcolprintLineAppendColumnVersion (line, r->version);\n\t\t\t\t\tcolprintLineAppendColumnCString (line, r->description);\n\t\t\t\t}\n\t\t\t\tif (! (!kname && *c == KIND_WILDCARD_LETTER))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tvStringDelete (kind_l_and_n);\n#if 0\n\tif ((i == countKinds (kcb)) && (*c != KIND_WILDCARD) && (!allowMissingKind))\n\t\terror (FATAL, \"No such letter kind in %s: %c\\n\", lang->name, *c);\n#endif\n}\n\nstatic int roleColprintCompareLines(struct colprintLine *a, struct colprintLine *b)\n{\n\tint r;\n\n\tconst char *a_parser, *b_parser;\n\ta_parser = colprintLineGetColumn (a, 0);\n\tb_parser = colprintLineGetColumn (b, 0);\n\n\tr = strcmp(a_parser, b_parser);\n\tif (r != 0)\n\t\treturn r;\n\n\tconst char *a_kindln, *b_kindln;\n\ta_kindln = colprintLineGetColumn (a, 1);\n\tb_kindln = colprintLineGetColumn (b, 1);\n\n\tr = strcmp(a_kindln, b_kindln);\n\tif (r != 0)\n\t\treturn r;\n\n\tconst char *a_role, *b_role;\n\ta_role = colprintLineGetColumn (a, 2);\n\tb_role = colprintLineGetColumn (b, 2);\n\n\treturn strcmp(a_role, b_role);\n}\n\nextern void roleColprintTablePrint (struct colprintTable *table, bool noparser,\n\t\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp)\n{\n\tcolprintTableSort (table, roleColprintCompareLines);\n\tcolprintTablePrint (table, noparser? 1: 0, withListHeader, machinable, fp);\n}\n"
  },
  {
    "path": "main/kind.h",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n#ifndef CTAGS_MAIN_KIND_H\n#define CTAGS_MAIN_KIND_H\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"\n#include \"types.h\"\n#include \"routines.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\n\nstruct sRoleDefinition {\n\tbool enabled;\n\tchar* name;\t\t  /* role name */\n\tchar* description;\t  /* displayed in --help output */\n\n\tunsigned int    version;\n\n\tint id;\n};\n\n/*\n * Predefined kinds\n */\n#define KIND_REGEX_DEFAULT_LETTER 'r'\n#define KIND_REGEX_DEFAULT_NAME \"regex\"\n\n#define KIND_NULL_LETTER    '\\0'\n\n/* GHOST kind can be used for a value for\n * initializing a variable holding a kind index,\n * or filling a struct member holding a kind index.\n *\n * Typical case is filling a scope related struct\n * member with GHOST to represent root name scope.\n *\n * input.c:\n *\n *     int main (void) { return 0; }\n *\n * Consider that tagging \"main\" in above input.\n * You may wonder what kind of value\n * should be used to fill tag.extensionFields.scopeKindIndex.\n * KIND_GHOST_INDEX can be used for the purpose.\n */\n#define KIND_GHOST_INDEX -1\n#define KIND_GHOST_LETTER   ' '\n#define KIND_GHOST_NAME \"ghost\"\n\n#define KIND_FILE_INDEX -2\n#define KIND_FILE_DEFAULT_LETTER 'F'\n#define KIND_FILE_DEFAULT_NAME \"file\"\n\n#define KIND_WILDCARD_INDEX -3\n#define KIND_WILDCARD_LETTER '*'\n\ntypedef struct sScopeSeparator {\n\tint parentKindIndex;\n\tconst char *separator;\n} scopeSeparator;\n\nstruct sKindDefinition {\n\tbool enabled;          /* are tags for kind enabled? */\n\tchar  letter;               /* kind letter */\n\tchar* name;\t\t  /* kind name */\n\tchar* description;\t  /* displayed in --help output */\n\tbool referenceOnly;\n\tint nRoles;\t\t/* The number of role elements. */\n\troleDefinition *roles;\n\tscopeSeparator *separators;\n\tunsigned int separatorCount;\n\n\tunsigned int    version;\n\n\tint id;\n\n\t/* TODO:Following fields should be moved to kindObject. */\n\t/* Usage of `syncWith' field is a bit tricky.\n\n\t   If `LANG_AUTO' is specified to `syncWith' field of a kind\n\t   (target kind), the main part of ctags updates the field with\n\t   the id of a  parser (master parser) when initializing\n\t   parsers. It also updates `slave' and `master' fields.\n\n\t   If the value other than `LANG_AUTO' is specified,\n\t   the main part does nothing. */\n\tlangType syncWith;\n\tkindDefinition *slave;\n\tkindDefinition *master;\n};\n\n#define ATTACH_ROLES(RS) .nRoles = ARRAY_SIZE(RS), .roles = RS\n#define ATTACH_SEPARATORS(S) .separators = S, .separatorCount = ARRAY_SIZE(S)\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern const char *scopeSeparatorFor (langType lang, int kindIndex, int parentKindIndex);\n\n#endif\t/* CTAGS_MAIN_KIND_H */\n"
  },
  {
    "path": "main/kind_p.h",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n#ifndef CTAGS_MAIN_KIND_PRIVATE_H\n#define CTAGS_MAIN_KIND_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"\n#include \"kind.h\"\n#include \"vstring.h\"\n\n\n/*\n*   DATA DECLARATIONS\n*/\n\nstruct kindControlBlock;\ntypedef void (* freeKindDefFunc) (kindDefinition *);\ntypedef void (* freeRoleDefFunc) (roleDefinition *);\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void enableKind (kindDefinition *kind, bool enable);\nextern void enableRole (roleDefinition *role, bool enable);\nextern const char *renderRole (const roleDefinition* const def, vString* b);\n\nextern struct kindControlBlock* allocKindControlBlock (parserDefinition *parser);\nextern void freeKindControlBlock (struct kindControlBlock* kcb);\n\nextern int  defineKind (struct kindControlBlock* kcb, kindDefinition *def,\n\t\t\t\t\t\tfreeKindDefFunc freeKindDef);\nextern int defineRole (struct kindControlBlock* kcb, int kindIndex,\n\t\t\t\t\t   roleDefinition *def, freeRoleDefFunc freeRoleDef);\nextern bool isRoleEnabled (struct kindControlBlock* kcb, int kindIndex, int roleIndex);\n\nextern unsigned int countKinds (struct kindControlBlock* kcb);\nextern unsigned int countRoles (struct kindControlBlock* kcb, int kindIndex);\nextern kindDefinition *getKind (struct kindControlBlock* kcb, int kindIndex);\nextern kindDefinition *getKindForLetter (struct kindControlBlock* kcb, char letter);\nextern kindDefinition *getKindForName (struct kindControlBlock* kcb, const char* name);\nextern int getKindIndexForLetter (struct kindControlBlock* kcb, char letter);\nextern int getKindIndexForName (struct kindControlBlock* kcb, const char* name);\nextern roleDefinition* getRole(struct kindControlBlock* kcb, int kindIndex, int roleIndex);\nextern roleDefinition* getRoleForName(struct kindControlBlock* kcb, int kindIndex, const char* name);\nextern void linkKindDependency (struct kindControlBlock *masterKCB,\n\t\t\t\t\t\t\t\tstruct kindControlBlock *slaveKCB);\n\nextern int defineScopeSeparator(struct kindControlBlock* kcb,\n\t\t\t\t\t\t\t\tint kindIndex,\n\t\t\t\t\t\t\t\tint parentKindIndex, const char *separator);\nextern const  scopeSeparator *getScopeSeparator(struct kindControlBlock* kcb, int kindIndex, int parentKindIndex);\n\n/* for the obsolete --list-kinds option */\nextern void printKind (const kindDefinition* const kind, bool indent);\n\n/* for --list-kinds-full option. LANGUAGE must be initialized. */\nextern struct colprintTable * kindColprintTableNew (void);\nextern void kindColprintAddLanguageLines (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\t\t  struct kindControlBlock* kcb);\nextern void kindColprintTablePrint (struct colprintTable *table, bool noparser,\n\t\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp);\n\nextern struct colprintTable * roleColprintTableNew (void);\nextern void roleColprintAddRoles (struct colprintTable *table,\n\t\t\t\t\t\t\t\t  struct kindControlBlock* kcb,\n\t\t\t\t\t\t\t\t  const char *kindspecs);\nextern void roleColprintTablePrint (struct colprintTable *table, bool noparser,\n\t\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp);\n\n#ifdef DEBUG\nextern bool doesParserUseKind (struct kindControlBlock* kcb, char letter);\n#endif\n\n#endif\t/* CTAGS_MAIN_KIND_PRIVATE_H */\n"
  },
  {
    "path": "main/lregex-default.c",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for applying regular expression matching.\n*\n*   The code for utilizing the Gnu regex package with regards to processing the\n*   regex option and checking for regex matches was adapted from routines in\n*   Gnu etags.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <regex.h>\n#include \"lregex_p.h\"\n\n/*\n*    FUNCTION DECLARATIONS\n*/\nstatic int match (struct regexBackend *backend,\n\t\t\t\t  void *code, const char *input, size_t size,\n\t\t\t\t  regmatch_t pmatch[BACK_REFERENCE_COUNT]);\nstatic regexCompiledCode compile (struct regexBackend *backend,\n\t\t\t\t\t\t\t\t  const char *const regexp,\n\t\t\t\t\t\t\t\t  int flags);\nstatic void delete_code (void *code);\nstatic void set_icase_flag (int *flags);\n\n/*\n*    DATA DEFINITIONS\n*/\nstatic struct regexBackend defaultRegexBackend = {\n\t.name = \"default\",\n\t.fdefs = NULL,\n\t.fdef_count = 0,\n\t.set_icase_flag = set_icase_flag,\n\t.compile = compile,\n\t.match = match,\n\t.delete_code = delete_code,\n};\n\n/*\n*    FUNCTOIN DEFINITIONS\n*/\nextern void basic_regex_flag_short (char c, void* data)\n{\n\tstruct flagDefsDescriptor *desc = data;\n\n\tif (desc->backend)\n\t\terror (FATAL, \"regex backed is specified twice: %c\", c);\n\n\tdesc->backend = &defaultRegexBackend;\n\tdesc->flags   = (desc->regptype == REG_PARSER_MULTI_TABLE)? 0: REG_NEWLINE;\n}\n\nextern void basic_regex_flag_long (const char* const s, const char* const unused CTAGS_ATTR_UNUSED, void* data)\n{\n\tstruct flagDefsDescriptor *desc = data;\n\n\tif (desc->backend)\n\t\terror (FATAL, \"regex backed is specified twice: %s\", s);\n\n\tbasic_regex_flag_short ('b', data);\n}\n\nextern void extend_regex_flag_short (char c, void* data)\n{\n\tstruct flagDefsDescriptor *desc = data;\n\n\tif (desc->backend)\n\t\terror (FATAL, \"regex backed is specified twice: %c\", c);\n\n\tdesc->backend = &defaultRegexBackend;\n\tdesc->flags   = REG_EXTENDED;\n\tdesc->flags  |= (desc->regptype == REG_PARSER_MULTI_TABLE)? 0: REG_NEWLINE;\n}\n\nextern void extend_regex_flag_long (const char* const s, const char* const unused CTAGS_ATTR_UNUSED, void* data)\n{\n\tstruct flagDefsDescriptor *desc = data;\n\n\tif (desc->backend)\n\t\terror (FATAL, \"regex backed is specified twice: %s\", s);\n\n\textend_regex_flag_short('e', data);\n}\n\nstatic void delete_code (void *code)\n{\n\tregex_t *regex_code = code;\n\tregfree (regex_code);\n\teFree (regex_code);\n}\n\nstatic regexCompiledCode compile (struct regexBackend *backend,\n\t\t\t\t\t\t\t\t  const char *const regexp,\n\t\t\t\t\t\t\t\t  int flags)\n{\n\tregex_t *regex_code = xMalloc (1, regex_t);\n\tint errcode = regcomp (regex_code, regexp, flags);\n\tif (errcode != 0)\n\t{\n\t\tchar errmsg[256];\n\t\tregerror (errcode, regex_code, errmsg, sizeof(errmsg));\n\t\terror (WARNING, \"regcomp: %s\", errmsg);\n\t\tregfree (regex_code);\n\t\teFree (regex_code);\n\t\treturn (regexCompiledCode) { .backend = NULL, .code = NULL };\n\t}\n\treturn (regexCompiledCode) { .backend = &defaultRegexBackend, .code = regex_code };\n}\n\nstatic int match (struct regexBackend *backend,\n\t\t\t\t  void *code, const char *input, size_t size CTAGS_ATTR_UNUSED,\n\t\t\t\t  regmatch_t pmatch[BACK_REFERENCE_COUNT])\n{\n\treturn regexec ((regex_t *)code, input, BACK_REFERENCE_COUNT, pmatch, 0);\n}\n\nstatic void set_icase_flag (int *flags)\n{\n\t*flags |= REG_ICASE;\n}\n"
  },
  {
    "path": "main/lregex-pcre2.c",
    "content": "/*\n*  Copyright (c) 2021, Red Hat, Inc.\n*  Copyright (c) 2021, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for applying regular expression matching.\n*\n*   The code for utilizing the Gnu regex package with regards to processing the\n*   regex option and checking for regex matches was adapted from routines in\n*   Gnu etags.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#ifdef HAVE_PCRE2\n#define PCRE2_CODE_UNIT_WIDTH 8\n#include <pcre2.h>\n#endif\n\n#include \"lregex_p.h\"\n#include \"trashbox.h\"\n\n#include <string.h>\n\n/*\n*    FUNCTION DECLARATIONS\n*/\nstatic int match (struct regexBackend *backend,\n\t\t\t\t  void *code, const char *input, size_t size,\n\t\t\t\t  regmatch_t pmatch[BACK_REFERENCE_COUNT]);\nstatic regexCompiledCode compile (struct regexBackend *backend,\n\t\t\t\t\t\t\t\t  const char *const regexp,\n\t\t\t\t\t\t\t\t  int flags);\nstatic void delete_code (void *code);\nstatic void set_icase_flag (int *flags);\n\n/*\n*    DATA DEFINITIONS\n*/\nstatic struct regexBackend pcre2RegexBackend = {\n\t.name = \"pcre2\",\n\t.fdefs = NULL,\n\t.fdef_count = 0,\n\t.set_icase_flag = set_icase_flag,\n\t.compile = compile,\n\t.match = match,\n\t.delete_code = delete_code,\n};\n\n/*\n*    FUNCTOIN DEFINITIONS\n*/\nextern void pcre2_regex_flag_short (char c, void* data)\n{\n\tstruct flagDefsDescriptor *desc = data;\n\n\tif (desc->backend)\n\t\terror (FATAL, \"regex backed is specified twice: %c\", c);\n\n\tdesc->backend = &pcre2RegexBackend;\n\tdesc->flags   = (desc->regptype == REG_PARSER_MULTI_TABLE)? PCRE2_DOTALL: PCRE2_MULTILINE;\n}\n\nextern void pcre2_regex_flag_long (const char* const s, const char* const unused CTAGS_ATTR_UNUSED, void* data)\n{\n\tstruct flagDefsDescriptor *desc = data;\n\n\tif (desc->backend)\n\t\terror (FATAL, \"regex backed is specified twice: %s\", s);\n\n\tpcre2_regex_flag_short ('p', data);\n}\n\nstatic void delete_code (void *code)\n{\n\tpcre2_code_free (code);\n}\n\nstatic regexCompiledCode compile (struct regexBackend *backend,\n\t\t\t\t\t\t\t\t  const char *const regexp,\n\t\t\t\t\t\t\t\t  int flags)\n{\n\tint errornumber;\n\tPCRE2_SIZE erroroffset;\n\tpcre2_code *regex_code = pcre2_compile((PCRE2_SPTR)regexp,\n\t\t\t\t\t\t\t\t\t\t   PCRE2_ZERO_TERMINATED,\n\t\t\t\t\t\t\t\t\t\t   (uint32_t) flags,\n\t\t\t\t\t\t\t\t\t\t   &errornumber,\n\t\t\t\t\t\t\t\t\t\t   &erroroffset,\n\t\t\t\t\t\t\t\t\t\t   NULL);\n\tif (regex_code == NULL)\n\t{\n\t\tPCRE2_UCHAR buffer[256];\n\t\tpcre2_get_error_message(errornumber, buffer, sizeof(buffer));\n\t\terror (WARNING, \"PCRE2 compilation failed at offset %d: %s\", (int)erroroffset,\n\t\t\t   buffer);\n\t\treturn (regexCompiledCode) { .backend = NULL, .code = NULL };\n\t}\n\treturn (regexCompiledCode) { .backend = &pcre2RegexBackend, .code = regex_code };\n}\n\nstatic int match (struct regexBackend *backend,\n\t\t\t\t  void *code, const char *input, size_t size,\n\t\t\t\t  regmatch_t pmatch[BACK_REFERENCE_COUNT])\n{\n\tstatic pcre2_match_data *match_data;\n\tif (match_data == NULL)\n\t{\n\t\tmatch_data = pcre2_match_data_create (BACK_REFERENCE_COUNT, NULL);\n\t\tDEFAULT_TRASH_BOX (match_data, pcre2_match_data_free);\n\t}\n\n\tint rc = pcre2_match (code, (PCRE2_SPTR)input, size,\n\t\t\t\t\t\t  0, 0, match_data, NULL);\n\tif (rc > 0)\n\t{\n\t\tPCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);\n\t\tif (ovector[0] <= ovector[1])\n\t\t{\n\t\t\tmemset (pmatch, 0, sizeof(pmatch[0]) * BACK_REFERENCE_COUNT);\n\t\t\tfor (int i = 0; i < BACK_REFERENCE_COUNT; i++)\n\t\t\t{\n\t\t\t\tpmatch [i].rm_so = (i < rc)? ovector [2*i]  : -1;\n\t\t\t\tpmatch [i].rm_eo = (i < rc)? ovector [2*i+1]: -1;\n\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t}\n\treturn 1;\n}\n\nstatic void set_icase_flag (int *flags)\n{\n\t*flags |= PCRE2_CASELESS;\n}\n"
  },
  {
    "path": "main/lregex.c",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for applying regular expression matching.\n*\n*   The code for utilizing the Gnu regex package with regards to processing the\n*   regex option and checking for regex matches was adapted from routines in\n*   Gnu etags.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include <ctype.h>\n#include <stddef.h>\n#ifdef HAVE_SYS_TYPES_H\n# include <sys/types.h>  /* declare off_t (not known to regex.h on FreeBSD) */\n#endif\n\n#include <inttypes.h>\n\n#include \"debug.h\"\n#include \"colprint_p.h\"\n#include \"entry_p.h\"\n#include \"field_p.h\"\n#include \"flags_p.h\"\n#include \"htable.h\"\n#include \"kind.h\"\n#include \"options.h\"\n#include \"optscript.h\"\n#include \"parse_p.h\"\n#include \"promise.h\"\n#include \"read.h\"\n#include \"read_p.h\"\n#include \"routines.h\"\n#include \"routines_p.h\"\n#include \"script_p.h\"\n#include \"trace.h\"\n#include \"trashbox.h\"\n#include \"xtag_p.h\"\n\nstatic bool regexAvailable = false;\n\n/*\n*   MACROS\n*/\n\n/* The max depth of taction=enter/leave stack */\n#define MTABLE_STACK_MAX_DEPTH 64\n\n/* How many times ctags allows a mtable parser\n   stays at the same input position across table switching.\n\n   The value is derived from MTABLE_STACK_MAX_DEPTH.\n   No deep meaning is in that. It just for simplifying\n   Tmain cases. */\n#define MTABLE_MOTIONLESS_MAX (MTABLE_STACK_MAX_DEPTH + 1)\n\n#define DEFAULT_REGEX_BACKEND \"e\"\n\n/*\n*   DATA DECLARATIONS\n*/\n\nenum pType { PTRN_TAG, PTRN_CALLBACK };\n\nenum scopeAction {\n\tSCOPE_REF     = 1UL << 0,\n\tSCOPE_POP     = 1UL << 1,\n\tSCOPE_PUSH    = 1UL << 2,\n\tSCOPE_CLEAR   = 1UL << 3,\n\tSCOPE_REF_AFTER_POP = 1UL << 4,\n\tSCOPE_PLACEHOLDER = 1UL << 5,\n\tSCOPE_INTERVALTAB = 1UL << 6,\n};\n\nenum tableAction {\n\tTACTION_NOP,\n\tTACTION_ENTER,\t\t\t\t/* {tenter=N} */\n\tTACTION_LEAVE,\t\t\t\t/* {tleave} */\n\tTACTION_JUMP,\t\t\t\t\t/* {tjump=N} */\n\tTACTION_RESET,\t\t\t\t/* {treset=N} */\n\tTACTION_QUIT,\t\t\t\t\t/* {tquit} */\n};\n\nstruct fieldPattern {\n\tfieldType ftype;\n\tconst char *template;\n};\n\nstruct boundarySpec {\n\tint patternGroup;\n\tbool fromStartOfGroup;\n\tbool placeholder;\n};\n\nstruct guestLangSpec {\n\tenum guestLangSpecType {\n\t\tGUEST_LANG_UNKNOWN,\n\t\tGUEST_LANG_PLACEHOLDER,\t\t\t   /* _ */\n\t\tGUEST_LANG_STATIC_LANGNAME,\t\t   /* C, Python,... */\n\t\tGUEST_LANG_PTN_GROUP_FOR_LANGNAME, /* \\1, \\2, ..., \\9 */\n\t\tGUEST_LANG_PTN_GROUP_FOR_FILEMAP, /* *1, *2, ... *9 */\n\t} type;\n\tunion {\n\t\tlangType lang;\n\t\tint patternGroup;\n\t} spec;\n};\n\nstruct guestSpec {\n\tstruct guestLangSpec lang;\n#define GUEST_BOUNDARY_START 0\n#define GUEST_BOUNDARY_END  1\n\tstruct boundarySpec boundary[2];\n};\n\nstruct mGroupSpec {\n#define NO_MULTILINE -1\n\tint forLineNumberDetermination;\n\tint forNextScanning;\n\t/* true => start, false => end */\n\tbool nextFromStart;\n};\n\nstruct mTableActionSpec {\n\tenum tableAction action;\n\tstruct regexTable *table;\n\n\t/* used when action == TACTION_ENTER */\n\tstruct regexTable *continuation_table;\n};\n\ntypedef struct {\n\tregexCompiledCode pattern;\n\tenum pType type;\n\tbool exclusive;\n\tbool accept_empty_name;\n\tbool postrun;\n\tunion {\n\t\tstruct {\n\t\t\tint kindIndex;\n\t\t\troleBitsType roleBits;\n\t\t\tchar *name_pattern;\n\t\t} tag;\n\t\tstruct {\n\t\t\tregexCallback function;\n\t\t\tvoid *userData;\n\t\t} callback;\n\t} u;\n\tunsigned int scopeActions;\n\tbool *disabled;\n\n\tenum regexParserType regptype;\n\tstruct mGroupSpec mgroup;\n\tstruct guestSpec guest;\n\tstruct mTableActionSpec taction;\n\n\tint   xtagType;\n\tptrArray *fieldPatterns;\n\n\tchar *pattern_string;\n\n\tchar *anonymous_tag_prefix;\n\tlangType foreign_lang;\n\n\tstruct {\n\t\terrorSelection selection;\n\t\tchar *message_string;\n\t} message;\n\n\tchar *optscript_src;\n\tEsObject *optscript;\n\n\tint refcount;\n} regexPattern;\n\n\ntypedef struct {\n\t/* the pattern can be shared among entries using a refcount */\n\tregexPattern *pattern;\n\n\t/* but the statistics are per-table-entry */\n\tstruct {\n\t\tunsigned int match;\n\t\tunsigned int unmatch;\n\t} statistics;\n} regexTableEntry;\n\n\n#define TABLE_INDEX_UNUSED -1\nstruct regexTable {\n\tchar *name;\n\tptrArray *entries;\n};\n\nstruct boundaryInRequest {\n\tbool offset_set;\n\toff_t offset;\n};\n\nstruct guestRequest {\n\tbool lang_set;\n\tlangType lang;\n\n\tstruct boundaryInRequest boundary[2];\n};\n\ntypedef struct {\n\tconst char *line;\n\tconst char *start;\n\tconst regexPattern* const patbuf;\n\tconst regmatch_t* const pmatch;\n\tint nmatch;\n\tstruct mTableActionSpec taction;\n\tbool advanceto;\n\tunsigned int advanceto_delta;\n} scriptWindow;\n\nstruct lregexControlBlock {\n\tint currentScope;\n\tptrArray *entries [2];\n\n\tptrArray *tables;\n\tptrArray *tstack;\n\n\tstruct guestRequest *guest_req;\n\n\tEsObject *local_dict;\n\thashTable*param_dict;\n\n\tptrArray *hook[SCRIPT_HOOK_MAX];\n\tptrArray *hook_code[SCRIPT_HOOK_MAX];\n\n\tlangType owner;\n};\n\ntypedef struct {\n\tstruct lregexControlBlock *lcb;\n\tscriptWindow *window;\n} appData;\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic OptVM *optvm;\nstatic EsObject *lregex_dict = es_nil;\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nstatic int getTableIndexForName (const struct lregexControlBlock *const lcb, const char *name);\nstatic void deletePattern (regexPattern *p);\nstatic int  makePromiseForAreaSpecifiedWithOffsets (const char *parser,\n\t\t\t\t\t\t\t\t\t\t\t\t\toff_t startOffset,\n\t\t\t\t\t\t\t\t\t\t\t\t\toff_t endOffset);\n\nstatic struct guestRequest *guestRequestNew (void);\nstatic void   guestRequestDelete (struct guestRequest *);\nstatic bool   guestRequestIsFilled(struct guestRequest *);\nstatic void   guestRequestClear (struct guestRequest *);\nstatic void   guestRequestSubmit (struct guestRequest *);\n\nstatic EsObject *scriptRead (OptVM *vm, const char *src);\nstatic void scriptSetup (OptVM *vm, struct lregexControlBlock *lcb, int corkIndex, scriptWindow *window);\nstatic EsObject* scriptEval (OptVM *vm, EsObject *optscript);\nstatic void scriptEvalHook (OptVM *vm, struct lregexControlBlock *lcb, enum scriptHook hook);\nstatic void scriptTeardown (OptVM *vm, struct lregexControlBlock *lcb);\n\nstatic char* make_match_string (scriptWindow *window, int group);\nstatic matchLoc *make_mloc (scriptWindow *window, int group, bool start);\n\nstatic struct lregexControlBlock *get_current_lcb(OptVM *vm)\n{\n\tappData * d = opt_vm_get_app_data (vm);\n\treturn d->lcb;\n}\n\nstatic scriptWindow *get_current_window(OptVM *vm)\n{\n\tappData * d = opt_vm_get_app_data (vm);\n\treturn d->window;\n}\n\nstatic struct lregexControlBlock *set_current_lcb(OptVM *vm, struct lregexControlBlock *new_lcb)\n{\n\tappData * d = opt_vm_get_app_data (vm);\n\tstruct lregexControlBlock *old_lcb = d->lcb;\n\td->lcb = new_lcb;\n\treturn old_lcb;\n}\n\nstatic scriptWindow *set_current_window(OptVM *vm, scriptWindow *new_windown)\n{\n\tappData * d = opt_vm_get_app_data (vm);\n\tscriptWindow *old_window = d->window;\n\td->window = new_windown;\n\treturn old_window;\n}\n\nstatic void deleteTable (void *ptrn)\n{\n\tstruct regexTable *t = ptrn;\n\n\tptrArrayDelete (t->entries);\n\teFree (t->name);\n\teFree (t);\n}\n\nstatic void deleteTableEntry (void *ptrn)\n{\n\tregexTableEntry *e = ptrn;\n\tAssert (e && e->pattern);\n\tdeletePattern (e->pattern);\n\teFree (e);\n}\n\nstatic void deletePattern (regexPattern *p)\n{\n\tp->refcount--;\n\n\tif (p->refcount > 0)\n\t\treturn;\n\n\tp->pattern.backend->delete_code (p->pattern.code);\n\n\tif (p->type == PTRN_TAG)\n\t{\n\t\teFree (p->u.tag.name_pattern);\n\t\tp->u.tag.name_pattern = NULL;\n\t}\n\n\tif (p->fieldPatterns)\n\t{\n\t\tptrArrayDelete (p->fieldPatterns);\n\t\tp->fieldPatterns = NULL;\n\t}\n\n\teFree (p->pattern_string);\n\n\tif (p->message.message_string)\n\t\teFree (p->message.message_string);\n\n\tif (p->anonymous_tag_prefix)\n\t\teFree (p->anonymous_tag_prefix);\n\n\tif (p->optscript)\n\t\tes_object_unref (p->optscript);\n\tif (p->optscript_src)\n\t\teFree (p->optscript_src);\n\n\teFree (p);\n}\n\nstatic void clearPatternSet (struct lregexControlBlock *lcb)\n{\n\tptrArrayClear (lcb->entries [REG_PARSER_SINGLE_LINE]);\n\tptrArrayClear (lcb->entries [REG_PARSER_MULTI_LINE]);\n\tptrArrayClear (lcb->tables);\n}\n\nextern struct lregexControlBlock* allocLregexControlBlock (parserDefinition *parser)\n{\n\tstruct lregexControlBlock *lcb = xCalloc (1, struct lregexControlBlock);\n\n\tlcb->entries[REG_PARSER_SINGLE_LINE] = ptrArrayNew(deleteTableEntry);\n\tlcb->entries[REG_PARSER_MULTI_LINE] = ptrArrayNew(deleteTableEntry);\n\tlcb->tables = ptrArrayNew(deleteTable);\n\tlcb->tstack = ptrArrayNew(NULL);\n\tlcb->guest_req = guestRequestNew ();\n\tlcb->local_dict = es_nil;\n\tlcb->param_dict = hashTableNew (3, hashCstrhash, hashCstreq,\n\t\t\t\t\t\t\t\t\teFree, eFree);\n\n\tfor (int i = 0; i< SCRIPT_HOOK_MAX; i++)\n\t{\n\t\tlcb->hook[i] = ptrArrayNew (eFree);\n\t\tlcb->hook_code[i] = ptrArrayNew ((ptrArrayDeleteFunc)es_object_unref);\n\t}\n\tlcb->owner = parser->id;\n\n\treturn lcb;\n}\n\nextern void freeLregexControlBlock (struct lregexControlBlock* lcb)\n{\n\tclearPatternSet (lcb);\n\n\tptrArrayDelete (lcb->entries [REG_PARSER_SINGLE_LINE]);\n\tlcb->entries [REG_PARSER_SINGLE_LINE] = NULL;\n\tptrArrayDelete (lcb->entries [REG_PARSER_MULTI_LINE]);\n\tlcb->entries [REG_PARSER_MULTI_LINE] = NULL;\n\n\tptrArrayDelete (lcb->tables);\n\tlcb->tables = NULL;\n\n\tptrArrayDelete (lcb->tstack);\n\tlcb->tstack = NULL;\n\n\tguestRequestDelete (lcb->guest_req);\n\tlcb->guest_req = NULL;\n\n\tes_object_unref (lcb->local_dict);\n\tlcb->local_dict = es_nil;\n\n\thashTableDelete (lcb->param_dict);\n\tlcb->param_dict = NULL;\n\n\tfor (int i = 0; i < SCRIPT_HOOK_MAX; i++)\n\t{\n\t\tptrArrayDelete (lcb->hook[i]);\n\t\tlcb->hook[i] = NULL;\n\n\t\tptrArrayDelete (lcb->hook_code[i]);\n\t\tlcb->hook_code[i] = NULL;\n\t}\n\n\teFree (lcb);\n}\n\n/*\n*   Regex pseudo-parser\n*/\n\nstatic void initRegexTag (tagEntryInfo *e,\n\t\tconst char * name, int kindIndex, int roleIndex, int scopeIndex, int placeholder,\n\t\tunsigned long line, MIOPos *pos, int xtag_type, langType foreign_lang)\n{\n\tAssert (name != NULL  &&  ((name[0] != '\\0') || placeholder));\n\n\tif (foreign_lang == LANG_IGNORE)\n\t\tinitRefTagEntry (e, name, kindIndex, roleIndex);\n\telse\n\t\tinitForeignRefTagEntry (e, name, foreign_lang, kindIndex, roleIndex);\n\te->extensionFields.scopeIndex = scopeIndex;\n\tmarkTagAsPlaceholder(e, placeholder);\n\tif (line)\n\t\tupdateTagLine(e, line, *pos);\n\n\tif (xtag_type != XTAG_UNKNOWN)\n\t\tmarkTagExtraBit (e, xtag_type);\n}\n\n/*\n*   Regex pattern definition\n*/\n\n/* Take a string like \"/blah/\" and turn it into \"blah\", making sure\n * that the first and last characters are the same, and handling\n * quoted separator characters.  Actually, stops on the occurrence of\n * an unquoted separator.  Also turns \"\\t\" into a Tab character.\n * Turns \"\\n\" into a Newline character if MULTILINE is true.\n * Returns pointer to terminating separator.  Works in place.  Null\n * terminates name string.\n */\nstatic char* scanSeparators (char* name, bool multiline)\n{\n\tchar sep = name [0];\n\tchar *copyto = name;\n\tbool quoted = false;\n\n\tfor (++name ; *name != '\\0' ; ++name)\n\t{\n\t\tif (quoted)\n\t\t{\n\t\t\tif (*name == sep)\n\t\t\t\t*copyto++ = sep;\n\t\t\telse if (*name == 't')\n\t\t\t\t*copyto++ = '\\t';\n\t\t\telse if (multiline && *name == 'n')\n\t\t\t\t*copyto++ = '\\n';\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* Something else is quoted, so preserve the quote. */\n\t\t\t\t*copyto++ = '\\\\';\n\t\t\t\t*copyto++ = *name;\n\t\t\t}\n\t\t\tquoted = false;\n\t\t}\n\t\telse if (*name == '\\\\')\n\t\t\tquoted = true;\n\t\telse if (*name == sep)\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\t*copyto++ = *name;\n\t}\n\t*copyto = '\\0';\n\treturn name;\n}\n\n/* Parse `regexp', in form \"/regex/name/[k,Kind/]flags\" (where the separator\n * character is whatever the first character of `regexp' is), by breaking it\n * up into null terminated strings, removing the separators, and expanding\n * '\\t' into tabs. When complete, `regexp' points to the line matching\n * pattern, a pointer to the name matching pattern is written to `name', a\n * pointer to the kinds is written to `kinds' (possibly NULL), and a pointer\n * to the trailing flags is written to `flags'. If the pattern is not in the\n * correct format, a false value is returned.\n */\nstatic bool parseTagRegex (\n\t\tenum regexParserType regptype,\n\t\tchar* const regexp, char** const name,\n\t\tchar** const kinds, char** const flags)\n{\n\tbool result = false;\n\tconst int separator = (unsigned char) regexp [0];\n\n\t*name = scanSeparators (regexp, (regptype == REG_PARSER_MULTI_LINE\n\t\t\t\t\t\t\t\t\t || regptype == REG_PARSER_MULTI_TABLE));\n\tif (*regexp == '\\0')\n\t\terror (WARNING, \"empty regexp\");\n\telse if (**name != separator)\n\t\terror (WARNING, \"%s: incomplete regexp\", regexp);\n\telse\n\t{\n\t\tchar* const third = scanSeparators (*name, false);\n\t\tif (**name != '\\0' && (*name) [strlen (*name) - 1] == '\\\\')\n\t\t\terror (WARNING, \"error in name pattern: \\\"%s\\\"\", *name);\n\t\tif (*third != separator)\n\t\t\terror (WARNING, \"%s: regexp missing final separator\", regexp);\n\t\telse\n\t\t{\n\t\t\t/*\n\t\t\t * first----------V third------------V\n\t\t\t * --regex-<LANG>=/regexp/replacement/[kind-spec/][flags][{{\\n...\\n}}]\n\t\t\t * second----------------^ fourth---------------^\n\t\t\t */\n\n\t\t\t/*\n\t\t\t * The following code assumes \"{{\\n\" is never used in flags.\n\t\t\t * If the input comes from the command line or an optlib file,\n\t\t\t * this assumption is always correct; a new line character is never\n\t\t\t * put at the middle (or end) of the input.\n\t\t\t *\n\t\t\t * TODO: How about the input comes from the source code translated\n\t\t\t * by optlib2c?\n\t\t\t */\n\t\t\tchar *script = strstr (third, \"{{\\n\");\n\t\t\tif (script)\n\t\t\t{\n\t\t\t\t/* The script part should not be unescaed by scanSeparators().\n\t\t\t\t * By spitting the string, we can hide the script part from\n\t\t\t\t * scanSeparators(). */\n\t\t\t\tscript [0] = '\\0';\n\t\t\t}\n\n\t\t\tchar* const fourth = scanSeparators (third, false);\n\t\t\tif (*fourth == separator)\n\t\t\t{\n\t\t\t\t*kinds = third;\n\t\t\t\tscanSeparators (fourth, false);\n\t\t\t\t*flags = fourth;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t*flags = third;\n\t\t\t\t*kinds = NULL;\n\t\t\t}\n\n\t\t\tif (script)\n\t\t\t{\n\t\t\t\tAssert (*flags);\n\n\t\t\t\tchar *end = *flags + strlen (*flags);\n\t\t\t\tscript [0] = '{';\n\t\t\t\tif (end != script)\n\t\t\t\t{\n\t\t\t\t\tsize_t len = strlen (script);\n\t\t\t\t\tmemmove (end, script, len);\n\t\t\t\t\tend [len] = '\\0';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tresult = true;\n\t\t}\n\t}\n\treturn result;\n}\n\n\nstatic void pre_ptrn_flag_exclusive_short (char c CTAGS_ATTR_UNUSED, void* data)\n{\n\tregexPattern * ptrn = data;\n\tptrn->exclusive = true;\n}\n\nstatic void pre_ptrn_flag_exclusive_long (const char* const s CTAGS_ATTR_UNUSED, const char* const unused CTAGS_ATTR_UNUSED, void* data)\n{\n\tpre_ptrn_flag_exclusive_short ('x', data);\n}\n\nstatic void pre_ptrn_flag_postrun_long (const char* const s CTAGS_ATTR_UNUSED, const char* const unused CTAGS_ATTR_UNUSED, void* data)\n{\n\tregexPattern * ptrn = data;\n\tptrn->postrun = true;\n}\n\nstatic flagDefinition prePtrnFlagDef[] = {\n\t{ 'x',  \"exclusive\", pre_ptrn_flag_exclusive_short, pre_ptrn_flag_exclusive_long ,\n\t  NULL, \"skip testing the other patterns if a line is matched to this pattern\"},\n\t{ '\\0', \"postrun\",   NULL, pre_ptrn_flag_postrun_long,\n\t  NULL, \"run after parsing with built-in code, multline regex patterns, and multitable regex patterns\" },\n};\n\nstatic void scope_ptrn_flag_eval (const char* const f  CTAGS_ATTR_UNUSED,\n\t\t\t\t  const char* const v, void* data)\n{\n\tunsigned int *bfields = data;\n\n\tif (strcmp (v, \"ref\") == 0)\n\t\t*bfields |= SCOPE_REF;\n\telse if (strcmp (v, \"push\") == 0)\n\t\t*bfields |= (SCOPE_PUSH | SCOPE_REF);\n\telse if (strcmp (v, \"pop\") == 0)\n\t\t*bfields |= SCOPE_POP;\n\telse if (strcmp (v, \"clear\") == 0)\n\t\t*bfields |= SCOPE_CLEAR;\n\telse if (strcmp (v, \"set\") == 0)\n\t\t*bfields |= (SCOPE_CLEAR | SCOPE_PUSH);\n\telse if (strcmp (v, \"replace\") == 0)\n\t\t*bfields |= (SCOPE_POP|SCOPE_REF_AFTER_POP|SCOPE_PUSH);\n\telse if (strcmp (v, \"intervaltab\") == 0)\n\t\t*bfields |= SCOPE_INTERVALTAB;\n\telse\n\t\terror (FATAL, \"Unexpected value for scope flag in regex definition: scope=%s\", v);\n}\n\nstatic void placeholder_ptrn_flag_eval (const char* const f  CTAGS_ATTR_UNUSED,\n\t\t\t\t     const char* const v  CTAGS_ATTR_UNUSED, void* data)\n{\n\tunsigned int *bfields = data;\n\t*bfields |= SCOPE_PLACEHOLDER;\n}\n\nstatic flagDefinition scopePtrnFlagDef[] = {\n\t{ '\\0', \"scope\",     NULL, scope_ptrn_flag_eval,\n\t  \"ACTION\", \"use scope stack: ACTION = ref|push|pop|clear|set|replace|intervaltab\"},\n\t{ '\\0', \"placeholder\",  NULL, placeholder_ptrn_flag_eval,\n\t  NULL, \"don't put this tag to tags file.\"},\n};\n\nstatic void intervaltab_ptrn_flag_eval (const char* const f  CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\tconst char* const v, void* data)\n{\n\tunsigned int *bfields = data;\n\tif (strcmp (v, \"intervaltab\") != 0)\n\t{\n\t\terror (WARNING, \"Unexpected value for scope flag in mline regex definition: scope=%s\", v);\n\t\terror (WARNING, \"NOTE: --mline-regex-<LANG> accepts only {scope=intervaltab}\");\n\t\treturn;\n\t}\n\n\t*bfields |= SCOPE_INTERVALTAB;\n}\n\nstatic flagDefinition intervaltabPtrnFlagDef[] = {\n\t{ '\\0', \"scope\",     NULL, intervaltab_ptrn_flag_eval,\n\t  \"intervaltab\", \"set scope for the tag with the interval table\" },\n};\n\nstatic kindDefinition *kindNew (char letter, const char *name, const char *description)\n{\n\tkindDefinition *kdef = xCalloc (1, kindDefinition);\n\tkdef->letter        = letter;\n\tkdef->name = eStrdup (name);\n\tkdef->description = eStrdup(description? description: kdef->name);\n\tkdef->enabled = true;\n\treturn kdef;\n}\n\nstatic void kindFree (kindDefinition *kind)\n{\n\tkind->letter = '\\0';\n\teFree ((void *)kind->name);\n\tkind->name = NULL;\n\teFree ((void *)kind->description);\n\tkind->description = NULL;\n\teFree (kind);\n}\n\nstatic void initMgroup(struct mGroupSpec *mgroup)\n{\n\tmgroup->forLineNumberDetermination = NO_MULTILINE;\n\tmgroup->forNextScanning = NO_MULTILINE;\n\tmgroup->nextFromStart = false;\n}\n\nstatic void initGuestSpec (struct guestSpec *guest)\n{\n\tguest->lang.type = GUEST_LANG_UNKNOWN;\n}\n\nstatic void initTaction(struct mTableActionSpec *taction)\n{\n\ttaction->action = TACTION_NOP;\n\ttaction->table = NULL;\n}\n\nstatic regexPattern * refPattern (regexPattern * ptrn)\n{\n\tptrn->refcount++;\n\treturn ptrn;\n}\n\nstatic regexPattern * newPattern (regexCompiledCode* const pattern,\n\t\t\t\t\t\t\t\t  enum regexParserType regptype)\n{\n\tregexPattern *ptrn = xCalloc(1, regexPattern);\n\n\tptrn->pattern.backend = pattern->backend;\n\tptrn->pattern.code = pattern->code;\n\n\tptrn->exclusive = false;\n\tptrn->postrun = false;\n\tptrn->accept_empty_name = false;\n\tptrn->regptype = regptype;\n\tptrn->xtagType = XTAG_UNKNOWN;\n\n\tif (regptype == REG_PARSER_MULTI_LINE)\n\t\tinitMgroup(&ptrn->mgroup);\n\tif (regptype == REG_PARSER_MULTI_TABLE)\n\t\tinitTaction(&ptrn->taction);\n\tinitGuestSpec (&ptrn->guest);\n\n\tptrn->u.tag.roleBits = 0;\n\tptrn->refcount = 1;\n\n\tptrn->optscript = NULL;\n\tptrn->optscript_src = NULL;\n\n\tptrn->foreign_lang = LANG_IGNORE;\n\n\treturn ptrn;\n}\n\nstatic regexTableEntry * newRefPatternEntry (regexTableEntry * other)\n{\n\tregexTableEntry *entry = xCalloc (1, regexTableEntry);\n\n\tAssert (other && other->pattern);\n\n\tentry->pattern = refPattern(other->pattern);\n\treturn entry;\n}\n\nstatic regexTableEntry * newEntry (regexCompiledCode* const pattern,\n\t\t\t\t\t\t\t\t   enum regexParserType regptype)\n{\n\tregexTableEntry *entry = xCalloc (1, regexTableEntry);\n\tentry->pattern = newPattern (pattern, regptype);\n\treturn entry;\n}\n\nstatic regexPattern* addCompiledTagCommon (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t\t\t\t   int table_index,\n\t\t\t\t\t\t\t\t\t\t   regexCompiledCode* const pattern,\n\t\t\t\t\t\t\t\t\t\t   enum regexParserType regptype)\n{\n\tregexTableEntry *entry = newEntry (pattern, regptype);\n\n\tif (regptype == REG_PARSER_MULTI_TABLE)\n\t{\n\t\tstruct regexTable *table = ptrArrayItem (lcb->tables, table_index);\n\t\tAssert(table);\n\n\t\tptrArrayAdd (table->entries, entry);\n\t}\n\telse\n\t\tptrArrayAdd (lcb->entries[regptype], entry);\n\n\tuseRegexMethod(lcb->owner);\n\n\treturn entry->pattern;\n}\n\nstatic void pre_ptrn_flag_mgroup_long (const char* const s, const char* const v, void* data)\n{\n\tstruct mGroupSpec *mgroup = data;\n\tif (!v)\n\t{\n\t\terror (WARNING, \"no value is given for: %s\", s);\n\t\treturn;\n\t}\n\tif (!strToInt (v, 10, &mgroup->forLineNumberDetermination))\n\t{\n\t\terror (WARNING, \"wrong %s specification: %s\", s, v);\n\t\tmgroup->forLineNumberDetermination = NO_MULTILINE;\n\t}\n\telse if (mgroup->forLineNumberDetermination < 0\n\t\t\t || mgroup->forLineNumberDetermination >= BACK_REFERENCE_COUNT)\n\t{\n\t\terror (WARNING, \"out of range(0 ~ %d) %s specification: %s\",\n\t\t\t   (BACK_REFERENCE_COUNT - 1),\n\t\t\t   s, v);\n\t\tmgroup->forLineNumberDetermination = NO_MULTILINE;\n\t}\n}\n\nstatic void pre_ptrn_flag_advanceTo_long (const char* const s, const char* const v, void* data)\n{\n\tstruct mGroupSpec *mgroup = data;\n\tchar *vdup;\n\tchar *tmp;\n\n\n\tif (!v)\n\t{\n\t\terror (WARNING, \"no value is given for: %s\", s);\n\t\treturn;\n\t}\n\n\tvdup = eStrdup (v);\n\n\tmgroup->nextFromStart = false;\n\tif ((tmp = strstr(vdup, \"start\")))\n\t{\n\t\tmgroup->nextFromStart = true;\n\t\t*tmp = '\\0';\n\t}\n\telse if ((tmp = strstr(vdup, \"end\")))\n\t\t*tmp = '\\0';\n\n\tif (!strToInt (vdup, 10, &(mgroup->forNextScanning)))\n\t{\n\t\terror (WARNING, \"wrong %s specification: %s\", s, vdup);\n\t\tmgroup->nextFromStart = false;\n\t}\n\telse if (mgroup->forNextScanning < 0 || mgroup->forNextScanning >= BACK_REFERENCE_COUNT)\n\t{\n\t\terror (WARNING, \"out of range(0 ~ %d) %s specification: %s\",\n\t\t\t   (BACK_REFERENCE_COUNT - 1), s, vdup);\n\t\tmgroup->nextFromStart = false;\n\t}\n\n\teFree (vdup);\n}\n\nstruct guestPtrnFlagData {\n\tenum regexParserType type;\n\tstruct guestSpec *guest;\n};\n\nstatic void pre_ptrn_flag_guest_long (const char* const s, const char* const v, void* data)\n{\n\tstruct guestPtrnFlagData *flagData = data;\n\tenum regexParserType type = flagData->type;\n\tstruct guestSpec *guest = flagData->guest;\n\tstruct boundarySpec *current;\n\n\tif (!v)\n\t{\n\t\terror (WARNING, \"no value is given for: %s\", s);\n\t\treturn;\n\t}\n\n\tchar *tmp = strchr (v, ',');\n\tif (tmp == NULL)\n\t{\n\t\terror (WARNING, \"no terminator found for parser name: %s\", s);\n\t\treturn;\n\t}\n\n\tif ((tmp - v) == 0)\n\t{\n\t\tif (type == REG_PARSER_MULTI_LINE)\n\t\t{\n\t\t\terror (WARNING,\n\t\t\t\t   \"using placeholder for guest name field is not allowed in multiline regex spec: %s\", v);\n\t\t\tgoto err;\n\t\t}\n\n\t\tguest->lang.type = GUEST_LANG_PLACEHOLDER;\n\t}\n\telse if (*v == '\\\\' || *v == '*')\n\t{\n\t\tconst char *n_tmp = v + 1;\n\t\tconst char *n = n_tmp;\n\t\tfor (; isdigit ((unsigned char) *n_tmp); n_tmp++);\n\t\tchar c = *n_tmp;\n\t\t*(char *)n_tmp = '\\0';\n\t\tif (!strToInt (n, 10, &(guest->lang.spec.patternGroup)))\n\t\t{\n\t\t\terror (WARNING, \"wrong guest name specification: %s\", v);\n\t\t\tgoto err;\n\t\t}\n\t\telse if (guest->lang.spec.patternGroup >= BACK_REFERENCE_COUNT)\n\t\t{\n\t\t\terror (WARNING, \"wrong guest name specification (back reference count is too large): %d\",\n\t\t\t\t   guest->lang.spec.patternGroup);\n\t\t\tgoto err;\n\t\t}\n\n\t\t*(char *)n_tmp = c;\n\t\tif (*n_tmp != ',')\n\t\t{\n\t\t\terror (WARNING, \"wrong guest specification (garbage at the end of end guest spec): %s\", v);\n\t\t\tgoto err;\n\t\t}\n\n\t\tguest->lang.type = (*v == '\\\\')\n\t\t\t? GUEST_LANG_PTN_GROUP_FOR_LANGNAME\n\t\t\t: GUEST_LANG_PTN_GROUP_FOR_FILEMAP;\n\t}\n\telse\n\t{\n\t\tguest->lang.spec.lang = getNamedLanguageOrAlias (v, (tmp - v));\n\t\tif (guest->lang.spec.lang == LANG_IGNORE)\n\t\t{\n\t\t\terror (WARNING, \"no parser found for the guest spec: %s\", v);\n\t\t\tgoto err;\n\t\t}\n\t\tguest->lang.type = GUEST_LANG_STATIC_LANGNAME;\n\t}\n\n\ttmp++;\n\tif (*tmp == '\\0')\n\t{\n\t\terror (WARNING, \"no area spec found in the guest spec: %s\", v);\n\t\tgoto err;\n\t}\n\n\tfor (int i = 0; i < 2; i++)\n\t{\n\t\tcurrent = guest->boundary + i;\n\t\tconst char *current_field_str = (i == GUEST_BOUNDARY_START? \"start\": \"end\");\n\n\t\tif (tmp [0] == ((i == GUEST_BOUNDARY_START)? ',': '\\0'))\n\t\t{\n\t\t\tif (type == REG_PARSER_MULTI_LINE)\n\t\t\t\terror (WARNING,\n\t\t\t\t\t   \"using placeholder for %s field is not allowed in multiline regex spec: %s\",\n\t\t\t\t\t   current_field_str, v);\n\n\t\t\tcurrent->placeholder = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tchar *n = tmp;\n\n\t\t\tfor (; isdigit ((unsigned char) *tmp); tmp++);\n\t\t\tchar c = *tmp;\n\t\t\t*tmp = '\\0';\n\t\t\tif (!strToInt (n, 10, &(current->patternGroup)))\n\t\t\t{\n\t\t\t\terror (WARNING, \"wrong guest area specification (patternGroup of %s, number expected): %s:%s\",\n\t\t\t\t\t   current_field_str, v, n);\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t\t*tmp = c;\n\t\t\tif (*tmp == '\\0')\n\t\t\t{\n\t\t\t\terror (WARNING, \"wrong guest area specification (patternGroup of %s, nether start nor end given): %s\",\n\t\t\t\t\t   current_field_str, v);\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t\telse if (strncmp (tmp, \"start\", 5) == 0)\n\t\t\t{\n\t\t\t\tcurrent->fromStartOfGroup = true;\n\t\t\t\ttmp += 5;\n\t\t\t}\n\t\t\telse if (strncmp (tmp, \"end\", 3) == 0)\n\t\t\t{\n\t\t\t\tcurrent->fromStartOfGroup = false;\n\t\t\t\ttmp += 3;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\terror (WARNING, \"wrong guest area specification (%s): %s\",\n\t\t\t\t\t   current_field_str, v);\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t}\n\n\t\tif (i == 0)\n\t\t{\n\t\t\tif (*tmp != ',')\n\t\t\t{\n\t\t\t\terror (WARNING,\n\t\t\t\t\t   \"wrong guest area specification (separator between start and end boundaries): %s\", v);\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t\ttmp++;\n\t\t}\n\t\telse if (i == 1 && (*tmp != '\\0'))\n\t\t{\n\t\t\terror (WARNING, \"wrong guest area specification (garbage at the end of end boundary spec): %s\", v);\n\t\t\tgoto err;\n\t\t}\n\t}\n\treturn;\n err:\n\tguest->lang.type = GUEST_LANG_UNKNOWN;\n}\n\nstatic flagDefinition multilinePtrnFlagDef[] = {\n\t{ '\\0',  \"mgroup\", NULL, pre_ptrn_flag_mgroup_long,\n\t  \"N\", \"a group in pattern determining the line number of tag\"},\n\t{ '\\0',  \"_advanceTo\", NULL, pre_ptrn_flag_advanceTo_long,\n\t  \"N[start|end]\", \"a group in pattern from where the next scan starts [0end]\"},\n};\n\nstatic flagDefinition guestPtrnFlagDef[] = {\n#define EXPERIMENTAL \"_\"\n\t{ '\\0',  EXPERIMENTAL \"guest\", NULL, pre_ptrn_flag_guest_long,\n\t  \"PARSERSPEC,N0[start|end],N1[start|end]\", \"run guest parser on the area\"},\n};\n\nstatic bool hasMessage(const regexPattern *const ptrn)\n{\n\treturn (ptrn->message.selection > 0 && ptrn->message.message_string);\n}\n\nstruct commonFlagData {\n\tconst langType owner;\n\tconst struct lregexControlBlock *const lcb;\n\tregexPattern *ptrn;\n};\n\nstatic void common_flag_msg_long (const char* const s, const char* const v, void* data)\n{\n\tstruct commonFlagData *cdata = data;\n\tregexPattern *ptrn = cdata->ptrn;\n\n\tAssert (ptrn);\n\n\tif (hasMessage(ptrn))\n\t{\n\t\terror (WARNING, \"only one message flag may be given per regex (already set to '%s')\",\n\t\t\t   ptrn->message.message_string);\n\t\treturn;\n\t}\n\n\tif (strcmp (s, \"fatal\") == 0)\n\t{\n\t\tptrn->message.selection = FATAL;\n\t}\n\telse if (strcmp (s, \"warning\") == 0)\n\t{\n\t\tptrn->message.selection = WARNING;\n\t}\n\n\tAssert (ptrn->message.selection != 0);\n\n\tif (!v || !*v)\n\t{\n\t\terror (WARNING, \"no message value is given for {%s}\", s);\n\t\treturn;\n\t}\n\n\tconst char* begin = v;\n\tconst char* end = v + strlen (v);\n\t--end;\n\n\tif (*begin != '\"' || *end != '\"' || begin == end)\n\t{\n\t\terror (WARNING, \"argument for {%s} must be in double-quotes\", s);\n\t\treturn;\n\t}\n\n\t++begin;\n\n\tif (begin < end)\n\t\tptrn->message.message_string = eStrndup (begin, end - begin);\n}\n\nstatic void common_flag_extra_long (const char* const s, const char* const v, void* data)\n{\n\tstruct commonFlagData * cdata = data;\n\n\tAssert (cdata->ptrn);\n\n\tif (!v)\n\t{\n\t\terror (WARNING, \"no value is given for: %s\", s);\n\t\treturn;\n\t}\n\n\tlangType lang = (cdata->ptrn->foreign_lang == LANG_IGNORE)\n\t\t? cdata->owner\n\t\t: cdata->ptrn->foreign_lang;\n\tcdata->ptrn->xtagType = getXtagTypeForNameAndLanguage (v, lang);\n\tif (cdata->ptrn->xtagType == XTAG_UNKNOWN)\n\t\terror (WARNING, \"no such extra \\\"%s\\\" in %s\", v, getLanguageName(lang));\n}\n\n\nstatic struct fieldPattern * fieldPatternNew (fieldType ftype, const char *template)\n{\n\tstruct fieldPattern *fp;\n\n\tfp = xMalloc(1, struct fieldPattern);\n\tfp->ftype = ftype;\n\tfp->template = eStrdup(template);\n\n\treturn fp;\n}\n\nstatic void fieldPatternDelete (struct fieldPattern *fp)\n{\n\teFree ((void *)fp->template);\n\teFree (fp);\n}\n\nstatic void common_flag_field_long (const char* const s, const char* const v, void* data)\n{\n\tstruct commonFlagData * cdata = data;\n\tregexPattern *ptrn = cdata->ptrn;\n\n\tAssert (ptrn);\n\n\tstruct fieldPattern *fp;\n\tfieldType ftype;\n\tchar *fname;\n\tconst char* template;\n\tchar *tmp;\n\n\tif (!v)\n\t{\n\t\terror (WARNING, \"no value is given for: %s\", s);\n\t\treturn;\n\t}\n\n\ttmp = strchr (v, ':');\n\tif (tmp == NULL || tmp == v)\n\t{\n\t\terror (WARNING, \"no field name is given for: %s\", s);\n\t\treturn;\n\t}\n\n\tfname = eStrndup (v, tmp - v);\n\n\tlangType lang = (ptrn->foreign_lang == LANG_IGNORE)\n\t\t? cdata->owner\n\t\t: ptrn->foreign_lang;\n\tftype = getFieldTypeForNameAndLanguage (fname, lang);\n\tif (ftype == FIELD_UNKNOWN)\n\t{\n\t\terror (WARNING, \"no such field \\\"%s\\\" in %s\", fname, getLanguageName(lang));\n\t\teFree (fname);\n\t\treturn;\n\t}\n\n\tif (ptrn->fieldPatterns)\n\t{\n\t\tfor (unsigned int i = 0; i < ptrArrayCount(ptrn->fieldPatterns); i++)\n\t\t{\n\t\t\tfp = ptrArrayItem(ptrn->fieldPatterns, i);\n\t\t\tif (fp->ftype == ftype)\n\t\t\t{\n\t\t\t\terror (WARNING, \"duplicated field specification \\\"%s\\\" in %s\", fname, getLanguageName(cdata->owner));\n\t\t\t\teFree (fname);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\teFree (fname);\n\n\ttemplate = tmp + 1;\n\tfp = fieldPatternNew (ftype, template);\n\n\tif (ptrn->fieldPatterns == NULL)\n\t\tptrn->fieldPatterns = ptrArrayNew((ptrArrayDeleteFunc)fieldPatternDelete);\n\tptrArrayAdd(ptrn->fieldPatterns, fp);\n}\n\nstatic void common_flag_role_long (const char* const s, const char* const v, void* data)\n{\n\tstruct commonFlagData * cdata = data;\n\tregexPattern *ptrn = cdata->ptrn;\n\troleDefinition * role;\n\n\tAssert (ptrn);\n\n\tif (!v)\n\t{\n\t\terror (WARNING, \"no value is given for: %s\", s);\n\t\treturn;\n\t}\n\n\tlangType lang = (ptrn->foreign_lang == LANG_IGNORE)\n\t\t? cdata->owner\n\t\t: ptrn->foreign_lang;\n\trole = getLanguageRoleForName(lang,\n\t\t\t\t\t\t\t\t  ptrn->u.tag.kindIndex, v);\n\tif (!role)\n\t{\n\t\terror (WARNING, \"no such role: \\\"%s\\\" in kind: \\\"%s\\\" of language: \\\"%s\\\"\",\n\t\t\t   v,\n\t\t\t   getLanguageKind(lang, ptrn->u.tag.kindIndex)->name,\n\t\t\t   getLanguageName (lang));\n\t\treturn;\n\t}\n\n\tptrn->u.tag.roleBits |= makeRoleBit(role->id);\n}\n\nstatic void common_flag_anonymous_long (const char* const s, const char* const v, void* data)\n{\n\tstruct commonFlagData * cdata = data;\n\tregexPattern *ptrn = cdata->ptrn;\n\n\tAssert (ptrn);\n\n\tif (ptrn->anonymous_tag_prefix)\n\t{\n\t\terror (WARNING, \"an anonymous tag prefix for this pattern (%s) is already given: %s\",\n\t\t\t   ptrn->pattern_string? ptrn->pattern_string: \"\",\n\t\t\t   ptrn->anonymous_tag_prefix);\n\t\treturn;\n\t}\n\n\tif (!v)\n\t{\n\t\terror (WARNING, \"no PREFIX for anonymous regex flag is given (pattern == %s)\",\n\t\t\t   ptrn->pattern_string? ptrn->pattern_string: \"\");\n\t\treturn;\n\t}\n\n\tif (ptrn->u.tag.kindIndex == KIND_GHOST_INDEX)\n\t{\n\t\terror (WARNING, \"use \\\"%s\\\" regex flag only with an explicitly defined kind\", s);\n\t\treturn;\n\t}\n\n\tptrn->anonymous_tag_prefix = eStrdup (v);\n}\n\nstatic void precommon_flag_foreign_lang (const char* const s, const char* const v, void* data)\n{\n\tstruct commonFlagData * cdata = data;\n\tregexPattern *ptrn = cdata->ptrn;\n\n\tAssert (ptrn);\n\n\tif (ptrn->foreign_lang != LANG_IGNORE)\n\t\terror (FATAL, \"foreign language for this pattern (%s) is already given: %s\",\n\t\t\t   ptrn->pattern_string? ptrn->pattern_string: \"\",\n\t\t\t   getLanguageName(ptrn->foreign_lang));\n\n\tif (!v)\n\t\terror (FATAL, \"no LANG for foreign flag is given (pattern == %s)\",\n\t\t\t   ptrn->pattern_string? ptrn->pattern_string: \"\");\n\n\tlangType lang = getNamedLanguage (v, 0);\n\tif (lang == LANG_IGNORE)\n\t\terror (FATAL, \"language named '%s' specified is not found or not initialized yet\",\n\t\t\t   v);\n\n\tif (!doesLanguageHaveForeignDependency (cdata->owner, lang))\n\t\terror (FATAL, \"%s is not declared as a foreign language in %s parser\",\n\t\t\t   v, getLanguageName (cdata->owner));\n\n\tptrn->foreign_lang = lang;\n}\n\nstatic flagDefinition preCommonSpecFlagDef[] = {\n\t{ '\\0',  EXPERIMENTAL \"language\", NULL, precommon_flag_foreign_lang,\n\t  \"LANG\", \"make a foreign tag for LANG\"},\n};\n\nstatic flagDefinition commonSpecFlagDef[] = {\n\t{ '\\0',  \"fatal\", NULL, common_flag_msg_long ,\n\t  \"\\\"MESSAGE\\\"\", \"print the given MESSAGE and exit\"},\n\t{ '\\0',  \"warning\", NULL, common_flag_msg_long ,\n\t  \"\\\"MESSAGE\\\"\", \"print the given MESSAGE at WARNING level\"},\n#define EXPERIMENTAL \"_\"\n\t{ '\\0',  EXPERIMENTAL \"extra\", NULL, common_flag_extra_long ,\n\t  \"EXTRA\", \"record the tag only when the (foreign) extra is enabled\"},\n\t{ '\\0',  EXPERIMENTAL \"field\", NULL, common_flag_field_long ,\n\t  \"FIELD:VALUE\", \"record the matched string(VALUE) to the (foreign) language specific FIELD of the tag\"},\n\t{ '\\0',  EXPERIMENTAL \"role\", NULL, common_flag_role_long,\n\t  \"ROLE\", \"set the given ROLE to the roles field\"},\n\t{ '\\0',  EXPERIMENTAL \"anonymous\", NULL, common_flag_anonymous_long,\n\t  \"PREFIX\", \"make an anonymous tag with PREFIX\"},\n};\n\n\nstatic void pre_ptrn_flag_mtable_long (const char* const s, const char* const v, void* data)\n{\n\tstruct commonFlagData * cdata = data;\n\tregexPattern *ptrn = cdata->ptrn;\n\tstruct mTableActionSpec *taction;\n\tbool taking_table = true;\n\n\tAssert (ptrn);\n\tAssert (cdata->lcb);\n\n\ttaction = &ptrn->taction;\n\n\tif (strcmp (s, \"tenter\") == 0)\n\t\ttaction->action = TACTION_ENTER;\n\telse if (strcmp (s, \"tleave\") == 0)\n\t{\n\t\ttaction->action = TACTION_LEAVE;\n\t\ttaking_table = false;\n\t}\n\telse if (strcmp (s, \"tjump\") == 0)\n\t\ttaction->action = TACTION_JUMP;\n\telse if (strcmp (s, \"treset\") == 0)\n\t\ttaction->action = TACTION_RESET;\n\telse if (strcmp (s, \"tquit\") == 0)\n\t{\n\t\ttaction->action = TACTION_QUIT;\n\t\ttaking_table = false;\n\t}\n\n\tif (taking_table)\n\t{\n\t\tint t;\n\t\tchar *continuation = NULL;\n\n\n\t\tif (!v || (!*v))\n\t\t\terror (FATAL, \"no table is given for table action: %s\", s);\n\n\t\tif (taction->action == TACTION_ENTER\n\t\t\t&& (continuation = strchr (v, ',')))\n\t\t{\n\t\t\tchar *tableEnterTo;\n\n\t\t\ttableEnterTo = eStrndup (v, continuation - v);\n\t\t\tt = getTableIndexForName (cdata->lcb, tableEnterTo);\n\t\t\tif (t < 0)\n\t\t\t\terror (FATAL, \"table is not defined: %s\", tableEnterTo);\n\t\t\ttaction->table = ptrArrayItem (cdata->lcb->tables, t);\n\t\t\teFree (tableEnterTo);\n\n\t\t\tif (!*(continuation + 1))\n\t\t\t\terror (FATAL, \"no continuation table is given for: %s\", v);\n\n\t\t\tint t_cont = getTableIndexForName (cdata->lcb, continuation + 1);\n\t\t\tif (t_cont < 0)\n\t\t\t\terror (FATAL, \"table for continuation is not defined: %s\", continuation + 1);\n\t\t\ttaction->continuation_table = ptrArrayItem (cdata->lcb->tables, t_cont);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tt = getTableIndexForName (cdata->lcb, v);\n\t\t\tif (t < 0)\n\t\t\t\terror (FATAL, \"table is not defined: %s\", v);\n\t\t\ttaction->table = ptrArrayItem (cdata->lcb->tables, t);\n\t\t\ttaction->continuation_table = NULL;\n\t\t}\n\t}\n}\n\nstatic flagDefinition multitablePtrnFlagDef[] = {\n\t{ '\\0',  \"tenter\", NULL, pre_ptrn_flag_mtable_long ,\n\t  \"TABLE[,CONT]\", \"enter to given regext table (with specifying continuation)\"},\n\t{ '\\0',  \"tleave\", NULL, pre_ptrn_flag_mtable_long ,\n\t  NULL, \"leave from the current regext table\"},\n\t{ '\\0',  \"tjump\", NULL, pre_ptrn_flag_mtable_long ,\n\t  \"TABLE\", \"jump to another regext table(don't push the current table to state stack)\"},\n\t{ '\\0',  \"treset\", NULL, pre_ptrn_flag_mtable_long ,\n\t  \"TABLE\", \"clear the state stack and jump to given regex table\"},\n\t{ '\\0',  \"tquit\", NULL, pre_ptrn_flag_mtable_long ,\n\t  NULL, \"stop the parsing with this parser\"},\n};\n\n\nstatic void setKind(regexPattern * ptrn, const langType owner,\n\t\t\t\t\tconst char kindLetter, const char* kindName,\n\t\t\t\t\tconst char *const description,\n\t\t\t\t\tbool kind_explicitly_defined)\n{\n\tAssert (ptrn);\n\tAssert (ptrn->u.tag.name_pattern);\n\tAssert (kindName);\n\n\tlangType lang = (ptrn->foreign_lang == LANG_IGNORE? owner: ptrn->foreign_lang);\n\tkindDefinition *kdef = getLanguageKindForLetter (lang, kindLetter);\n\n\tif (kdef)\n\t{\n\t\tif (strcmp (kdef->name, kindName) && (strcmp(kindName, KIND_REGEX_DEFAULT_NAME)))\n\t\t\t/* When using a same kind letter for multiple regex patterns, the name of kind\n\t\t\t   should be the same. */\n\t\t\terror  (WARNING, \"Don't reuse the kind letter `%c' in a language %s (old: \\\"%s\\\", new: \\\"%s\\\")\",\n\t\t\t\t\tkdef->letter, getLanguageName (lang),\n\t\t\t\t\tkdef->name, kindName);\n\t\tptrn->u.tag.kindIndex = kdef->id;\n\t}\n\telse if (*ptrn->u.tag.name_pattern == '\\0' &&\n\t\t\t kindLetter == KIND_REGEX_DEFAULT_LETTER &&\n\t\t\t (strcmp(kindName, KIND_REGEX_DEFAULT_NAME) == 0) &&\n\t\t\t (!kind_explicitly_defined))\n\t\tptrn->u.tag.kindIndex = KIND_GHOST_INDEX;\n\telse\n\t{\n\t\tkdef = kindNew (kindLetter, kindName, description);\n\t\tdefineLanguageKind (lang, kdef, kindFree);\n\t\tptrn->u.tag.kindIndex = kdef->id;\n\t}\n}\n\nstatic void prePatternEvalFlags(struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t  regexPattern * ptrn,\n\t\t\t\t\t\t\t  enum regexParserType regptype,\n\t\t\t\t\t\t\t  const char* flags)\n{\n\tstruct commonFlagData commonFlagData = {\n\t\t.owner = lcb->owner,\n\t\t.lcb = lcb,\n\t\t.ptrn = ptrn\n\t};\n\n\tflagsEval (flags, preCommonSpecFlagDef, ARRAY_SIZE(preCommonSpecFlagDef), &commonFlagData);\n}\n\nstatic void patternEvalFlags (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t  regexPattern * ptrn,\n\t\t\t\t\t\t\t  enum regexParserType regptype,\n\t\t\t\t\t\t\t  const char* flags)\n{\n\tstruct commonFlagData commonFlagData = {\n\t\t.owner = lcb->owner,\n\t\t.lcb = lcb,\n\t\t.ptrn = ptrn\n\t};\n\n\tif (regptype == REG_PARSER_SINGLE_LINE)\n\t\tflagsEval (flags, prePtrnFlagDef, ARRAY_SIZE(prePtrnFlagDef), ptrn);\n\n\tconst char * optscript = flagsEval (flags, commonSpecFlagDef, ARRAY_SIZE(commonSpecFlagDef), &commonFlagData);\n\tif (optscript)\n\t{\n\t\tptrn->optscript = scriptRead (optvm, optscript);\n\t\tptrn->optscript_src = eStrdup (optscript);\n\t}\n\n\tif (regptype == REG_PARSER_SINGLE_LINE || regptype == REG_PARSER_MULTI_TABLE)\n\t{\n\t\tflagsEval (flags, scopePtrnFlagDef, ARRAY_SIZE(scopePtrnFlagDef), &ptrn->scopeActions);\n\t\tif ((ptrn->scopeActions & (SCOPE_REF|SCOPE_REF_AFTER_POP)) == (SCOPE_REF|SCOPE_REF_AFTER_POP))\n\t\t\terror (WARNING, \"%s: don't combine \\\"replace\\\" with the other scope action.\",\n\t\t\t\t   getLanguageName (lcb->owner));\n\t}\n\telse\n\t{\n\t\tflagsEval (flags, intervaltabPtrnFlagDef, ARRAY_SIZE(intervaltabPtrnFlagDef), &ptrn->scopeActions);\n\t\tAssert (ptrn->scopeActions == 0 || ptrn->scopeActions == SCOPE_INTERVALTAB);\n\t}\n\n\tif (regptype == REG_PARSER_MULTI_LINE || regptype == REG_PARSER_MULTI_TABLE)\n\t{\n\t\tptrn->mgroup.forNextScanning = 0;\n\t\t/* ptrn->mgroup.nextFromStart is initialized in initMgroup() already. */\n\t\tflagsEval (flags, multilinePtrnFlagDef, ARRAY_SIZE(multilinePtrnFlagDef), &ptrn->mgroup);\n\t}\n\n\tstruct guestPtrnFlagData guestPtrnFlagData = {\n\t\t.type = regptype,\n\t\t.guest = &ptrn->guest,\n\t};\n\tflagsEval (flags, guestPtrnFlagDef, ARRAY_SIZE(guestPtrnFlagDef), &guestPtrnFlagData);\n\n\tif (regptype == REG_PARSER_MULTI_TABLE)\n\t\tflagsEval (flags, multitablePtrnFlagDef, ARRAY_SIZE(multitablePtrnFlagDef), &commonFlagData);\n}\n\nstatic regexPattern *addCompiledTagPattern (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t\t\t\t\tint table_index,\n\t\t\t\t\t\t\t\t\t\t\tenum regexParserType regptype, regexCompiledCode* const pattern,\n\t\t\t\t\t    const char* const name, char kindLetter, const char* kindName,\n\t\t\t\t\t    char *const description, const char* flags,\n\t\t\t\t\t    bool kind_explicitly_defined,\n\t\t\t\t\t    bool *disabled)\n{\n\tregexPattern * ptrn = addCompiledTagCommon(lcb, table_index, pattern, regptype);\n\n\tptrn->type = PTRN_TAG;\n\tptrn->u.tag.name_pattern = eStrdup (name);\n\tptrn->disabled = disabled;\n\n\tprePatternEvalFlags (lcb, ptrn, regptype, flags);\n\tsetKind(ptrn, lcb->owner, kindLetter, kindName, description, kind_explicitly_defined);\n\tpatternEvalFlags (lcb, ptrn, regptype, flags);\n\n\treturn ptrn;\n}\n\nstatic regexPattern *addCompiledCallbackPattern (struct lregexControlBlock *lcb, regexCompiledCode* const pattern,\n\t\t\t\t\tconst regexCallback callback, const char* flags,\n\t\t\t\t\tbool *disabled,\n\t\t\t\t\tvoid *userData)\n{\n\tregexPattern * ptrn;\n\tptrn = addCompiledTagCommon(lcb, TABLE_INDEX_UNUSED, pattern, REG_PARSER_SINGLE_LINE);\n\tflagsEval (flags, prePtrnFlagDef, ARRAY_SIZE(prePtrnFlagDef), ptrn);\n\tptrn->type    = PTRN_CALLBACK;\n\tptrn->u.callback.function = callback;\n\tptrn->u.callback.userData = userData;\n\tptrn->disabled = disabled;\n\treturn ptrn;\n}\n\n#ifndef HAVE_PCRE2\nstatic void no_pcre2_regex_flag_short (char c, void* data)\n{\n\terror (WARNING, \"'p' flag is specied but pcre2 regex engine is not linked.\");\n}\nstatic void no_pcre2_regex_flag_long (const char* const s, const char* const unused CTAGS_ATTR_UNUSED, void* data)\n{\n\terror (WARNING, \"{pcre2} flag is specied but pcre2 regex engine is not linked.\");\n}\n#endif\n\nstatic flagDefinition backendFlagDefs[] = {\n\t{ 'b', \"basic\",  basic_regex_flag_short,  basic_regex_flag_long,\n\t  NULL, \"interpreted as a Posix basic regular expression.\"},\n\t{ 'e', \"extend\", extend_regex_flag_short, extend_regex_flag_long,\n\t  NULL, \"interpreted as a Posix extended regular expression (default)\"},\n#ifdef HAVE_PCRE2\n\t{ 'p', \"pcre2\",  pcre2_regex_flag_short, pcre2_regex_flag_long,\n\t  NULL, \"use pcre2 regex engine\"},\n#else\n\t{ 'p', \"pcre2\",  no_pcre2_regex_flag_short, no_pcre2_regex_flag_long,\n\t  NULL, \"pcre2 is NOT linked!\"},\n#endif\n};\n\nstatic void regex_flag_icase_short (char c CTAGS_ATTR_UNUSED, void* data)\n{\n\tstruct flagDefsDescriptor *desc = data;\n\tdesc->backend->set_icase_flag (&desc->flags);\n}\n\nstatic void regex_flag_icase_long (const char* s CTAGS_ATTR_UNUSED, const char* const unused CTAGS_ATTR_UNUSED, void* data)\n{\n\tregex_flag_icase_short ('i', data);\n}\n\nstatic flagDefinition backendCommonRegexFlagDefs[] = {\n\t{ 'i', \"icase\",  regex_flag_icase_short,  regex_flag_icase_long,\n\t  NULL, \"applied in a case-insensitive manner\"},\n};\n\n\nstatic struct flagDefsDescriptor choose_backend (const char *flags, enum regexParserType regptype, bool error_if_no_backend)\n{\n\tstruct flagDefsDescriptor desc = {\n\t\t.backend  = NULL,\n\t\t.flags = 0,\n\t\t.regptype = regptype,\n\t};\n\n\tif (flags)\n\t\tflagsEval (flags,\n\t\t\t\t   backendFlagDefs,\n\t\t\t\t   ARRAY_SIZE(backendFlagDefs),\n\t\t\t\t   &desc);\n\n\t/* Choose the default backend. */\n\tif (desc.backend == NULL)\n\t{\n\t\tif (flags && error_if_no_backend)\n\t\t\terror (FATAL, \"No sunch backend for the name: \\\"%s\\\"\", flags);\n\n\t\tflagsEval (DEFAULT_REGEX_BACKEND,\n\t\t\t\t   backendFlagDefs,\n\t\t\t\t   ARRAY_SIZE(backendFlagDefs),\n\t\t\t\t   &desc);\n\t}\n\treturn desc;\n}\n\nstatic regexCompiledCode compileRegex (enum regexParserType regptype,\n\t\t\t\t\t\t\t\t\t   const char* const regexp, const char* const flags)\n{\n\tstruct flagDefsDescriptor desc = choose_backend (flags, regptype, false);\n\n\t/* Evaluate backend specific flags */\n\tflagsEval (flags,\n\t\t\t   desc.backend->fdefs,\n\t\t\t   desc.backend->fdef_count,\n\t\t\t   &desc.flags);\n\n\tflagsEval (flags,\n\t\t\t   backendCommonRegexFlagDefs,\n\t\t\t   ARRAY_SIZE (backendCommonRegexFlagDefs),\n\t\t\t   &desc);\n\n\treturn desc.backend->compile (desc.backend, regexp, desc.flags);\n}\n\n\n/* If a letter and/or a name are defined in kindSpec, return true. */\nstatic bool parseKinds (\n\t\tconst char* const kindSpec, char* const kindLetter, char** const kindName,\n\t\tchar **description)\n{\n\t*description = NULL;\n\n\tif (kindSpec == NULL  ||  kindSpec [0] == '\\0')\n\t{\n\t\t*kindLetter = KIND_REGEX_DEFAULT_LETTER;\n\t\t*kindName = eStrdup (KIND_REGEX_DEFAULT_NAME);\n\t\treturn false;\n\t}\n\telse\n\t{\n\t\tbool explicitly_defined = false;\n\t\tconst char* k = kindSpec;\n\n\t\tif (k [0] != ','  &&  (k [1] == ','  ||  k [1] == '\\0'))\n\t\t{\n\t\t\t*kindLetter = *k++;\n\t\t\texplicitly_defined = true;\n\t\t}\n\t\telse\n\t\t\t*kindLetter = KIND_REGEX_DEFAULT_LETTER;\n\n\t\tif (*k == ',')\n\t\t\t++k;\n\n\t\tif (k [0] == '\\0')\n\t\t\t*kindName = eStrdup (KIND_REGEX_DEFAULT_NAME);\n\t\telse\n\t\t{\n\t\t\tconst char *const comma = strchr (k, ',');\n\n\t\t\tif (comma == NULL)\n\t\t\t{\n\t\t\t\tif (strlen (k) == 0)\n\t\t\t\t\t*kindName = eStrdup (KIND_REGEX_DEFAULT_NAME);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t*kindName = eStrdup (k);\n\t\t\t\t\texplicitly_defined = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (comma - k == 0)\n\t\t\t\t\t*kindName = eStrdup (KIND_REGEX_DEFAULT_NAME);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t*kindName = eStrndup (k, comma - k );\n\t\t\t\t\texplicitly_defined = true;\n\t\t\t\t}\n\t\t\t\tk = comma + 1;\n\t\t\t\tif (k [0] != '\\0')\n\t\t\t\t\t*description = eStrdup (k);\n\t\t\t}\n\t\t}\n\t\treturn explicitly_defined;\n\t}\n}\n\n/*\n*   Regex pattern matching\n*/\n\n\nstatic vString* substitute (\n\t\tconst char* const in, const char* out,\n\t\tconst int nmatch, const regmatch_t* const pmatch)\n{\n\tvString* result = vStringNew ();\n\tconst char* p;\n\tfor (p = out  ;  *p != '\\0'  ;  p++)\n\t{\n\t\tif (*p == '\\\\'  &&  isdigit ((unsigned char) *++p))\n\t\t{\n\t\t\tconst int dig = *p - '0';\n\t\t\tif (0 < dig  &&  dig < nmatch  &&  pmatch [dig].rm_so != -1)\n\t\t\t{\n\t\t\t\tconst int diglen = pmatch [dig].rm_eo - pmatch [dig].rm_so;\n\t\t\t\tvStringNCatSUnsafe (result, in + pmatch [dig].rm_so, diglen);\n\t\t\t}\n\t\t}\n\t\telse if (*p != '\\n'  &&  *p != '\\r')\n\t\t\tvStringPut (result, *p);\n\t}\n\treturn result;\n}\n\nstatic unsigned long getInputLineNumberInRegPType (enum regexParserType regptype,\n\t\t\t\t\t\t\t\t\t\t\t\t   off_t offset)\n{\n\treturn (regptype == REG_PARSER_MULTI_LINE || regptype == REG_PARSER_MULTI_TABLE)\n\t\t? getInputLineNumberForFileOffset (offset)\n\t\t: getInputLineNumber ();\n}\n\nstatic void fillEndLineFieldOfUpperScopes (struct lregexControlBlock *lcb, unsigned long endline)\n{\n\ttagEntryInfo *entry;\n\tint n = lcb->currentScope;\n\n\twhile ((entry = getEntryInCorkQueue (n))\n\t\t   && (getTagEndLine (entry) == 0))\n\t{\n\t\tsetTagEndLine (entry, endline);\n\t\tn = entry->extensionFields.scopeIndex;\n\t}\n}\n\nstatic bool hasNameSlot (const regexPattern* const patbuf)\n{\n\treturn (patbuf->u.tag.name_pattern[0] != '\\0'\n\t\t\t|| patbuf->anonymous_tag_prefix);\n}\n\nstatic int scopeActionRef (int currentScope)\n{\n\tint scope = currentScope;\n\ttagEntryInfo *entry;\n\twhile ((entry = getEntryInCorkQueue (scope)) && entry->placeholder)\n\t\t/* Look at parent */\n\t\tscope = entry->extensionFields.scopeIndex;\n\treturn scope;\n}\n\nstatic void matchTagPattern (struct lregexControlBlock *lcb,\n\t\tconst char* line,\n\t\tconst regexPattern* const patbuf,\n\t\tconst regmatch_t* const pmatch,\n\t\t\t     off_t offset, scriptWindow *window)\n{\n\tvString *const name =\n\t\t(patbuf->u.tag.name_pattern[0] != '\\0') ? substitute (line,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  patbuf->u.tag.name_pattern,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  BACK_REFERENCE_COUNT, pmatch):\n\t\t(patbuf->anonymous_tag_prefix) ? anonGenerateNew (patbuf->anonymous_tag_prefix,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  patbuf->u.tag.kindIndex):\n\t\tvStringNewInit (\"\");\n\tbool placeholder = !!((patbuf->scopeActions & SCOPE_PLACEHOLDER) == SCOPE_PLACEHOLDER);\n\tint scope = CORK_NIL;\n\tint n;\n\n\tvStringStripLeading (name);\n\tvStringStripTrailing (name);\n\n\tif (patbuf->scopeActions & SCOPE_REF)\n\t\tscope = scopeActionRef (lcb->currentScope);\n\tif (patbuf->scopeActions & SCOPE_CLEAR)\n\t{\n\t\tunsigned long endline = getInputLineNumberInRegPType(patbuf->regptype, offset);\n\n\t\t/*\n\t\t * SCOPE_CLEAR|SCOPE_PUSH implies that \"set\" was specified as the scope action.\n\t\t * If the specified action is \"set\", getInputLineNumberInRegPType()\n\t\t * returns the start line of the NEW scope. The cleared scopes are ended BEFORE\n\t\t * the new scope. There is a gap. We must adjust the \"end:\" field here.\n\t\t */\n\t\tif (patbuf->scopeActions & SCOPE_PUSH && endline > 0)\n\t\t\tendline--;\n\n\t\tfillEndLineFieldOfUpperScopes (lcb, endline);\n\t\tlcb->currentScope = CORK_NIL;\n\t}\n\tif (patbuf->scopeActions & SCOPE_POP)\n\t{\n\t\ttagEntryInfo *entry = getEntryInCorkQueue (lcb->currentScope);\n\n\t\tif (entry && (getTagEndLine (entry) == 0))\n\t\t{\n\t\t\tsetTagEndLine (entry, getInputLineNumberInRegPType(patbuf->regptype, offset));\n\n\t\t\t/*\n\t\t\t * SCOPE_POP|SCOPE_REF_AFTER_POP implies that \"replace\" was specified as the\n\t\t\t * scope action. If the specified action is \"replace\", getInputLineNumberInRegPType()\n\t\t\t * returns the start line of the NEW scope. The popped scope is ended BEFORE\n\t\t\t * the new scope. There is a gap. We must adjust the \"end:\" field here.\n\t\t\t */\n\t\t\tif ((patbuf->scopeActions & SCOPE_REF_AFTER_POP) &&\n\t\t\t\tgetTagEndLine (entry) > 1)\n\t\t\t\tsetTagEndLine (entry, getTagEndLine (entry) - 1);\n\t\t}\n\n\t\tlcb->currentScope = entry? entry->extensionFields.scopeIndex: CORK_NIL;\n\t}\n\tif (patbuf->scopeActions & SCOPE_REF_AFTER_POP)\n\t\tscope = scopeActionRef (lcb->currentScope);\n\n\tif (vStringLength (name) == 0 && (placeholder == false))\n\t{\n\t\tif (patbuf->accept_empty_name == false)\n\t\t\terror (WARNING, \"%s:%lu: null expansion of name pattern \\\"%s\\\"\",\n\t\t\t       getInputFileName (),\n\t\t\t\t   getInputLineNumberInRegPType(patbuf->regptype, offset),\n\t\t\t       patbuf->u.tag.name_pattern);\n\t\tn = CORK_NIL;\n\t}\n\telse\n\t{\n\t\tstatic TrashBox* field_trashbox;\n\t\tunsigned long ln = 0;\n\t\tMIOPos pos;\n\t\ttagEntryInfo e;\n\t\tint kind;\n\t\troleBitsType roleBits;\n\n\t\tif ((patbuf->regptype == REG_PARSER_MULTI_LINE)\n\t\t\t|| (patbuf->regptype == REG_PARSER_MULTI_TABLE))\n\t\t{\n\t\t\tln = getInputLineNumberForFileOffset (offset);\n\t\t\tpos = getInputFilePositionForLine (ln);\n\t\t}\n\n\t\tn = CORK_NIL;\n\t\tkind = patbuf->u.tag.kindIndex;\n\t\troleBits = patbuf->u.tag.roleBits;\n\n\t\tif (scope == CORK_NIL && (patbuf->scopeActions & SCOPE_INTERVALTAB))\n\t\t{\n\t\t\tunsigned long ln0 = ln;\n\t\t\tif (ln0 == 0)\n\t\t\t\tln0 = getInputLineNumber();\n\t\t\tif (ln0)\n\t\t\t\tscope = queryIntervalTabByLine(ln0);\n\t\t}\n\n\t\tinitRegexTag (&e, vStringValue (name), kind, ROLE_DEFINITION_INDEX, scope, placeholder,\n\t\t\t\t\t  ln, ln == 0? NULL: &pos, patbuf->xtagType, patbuf->foreign_lang);\n\n\t\tif (field_trashbox == NULL)\n\t\t{\n\t\t\tfield_trashbox = trashBoxNew();\n\t\t\tDEFAULT_TRASH_BOX (field_trashbox, trashBoxDelete);\n\t\t}\n\n\t\tif (patbuf->fieldPatterns)\n\t\t{\n\t\t\tfor (unsigned int i = 0; i < ptrArrayCount(patbuf->fieldPatterns); i++)\n\t\t\t{\n\t\t\t\tstruct fieldPattern *fp = ptrArrayItem(patbuf->fieldPatterns, i);\n\t\t\t\tif (isFieldEnabled (fp->ftype))\n\t\t\t\t{\n\t\t\t\t\tvString * const value = substitute (line, fp->template,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tBACK_REFERENCE_COUNT, pmatch);\n\t\t\t\t\tattachParserField (&e, fp->ftype, vStringValue (value));\n\t\t\t\t\ttrashBoxPut (field_trashbox, value,\n\t\t\t\t\t\t\t\t (TrashBoxDestroyItemProc)vStringDelete);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (roleBits)\n\t\t{\n\t\t\tunsigned int roleIndex;\n\n\t\t\tfor (roleIndex = 0;\n\t\t\t\t roleIndex < countLanguageRoles(e.langType, kind);\n\t\t\t\t roleIndex++)\n\t\t\t{\n\t\t\t\tif (roleBits & makeRoleBit(roleIndex))\n\t\t\t\t\tassignRole (&e, roleIndex);\n\t\t\t}\n\t\t}\n\n\t\tif (patbuf->anonymous_tag_prefix)\n\t\t\tmarkTagExtraBit (&e, XTAG_ANONYMOUS);\n\n\t\tn = makeTagEntry (&e);\n\n\t\ttrashBoxMakeEmpty(field_trashbox);\n\t}\n\n\tif (patbuf->scopeActions & SCOPE_PUSH)\n\t\tlcb->currentScope = n;\n\n\tif (n != CORK_NIL && window)\n\t{\n\t\tscriptSetup (optvm, lcb, n, window);\n\t\tEsObject *e = scriptEval (optvm, patbuf->optscript);\n\t\tif (es_error_p (e))\n\t\t\terror (WARNING, \"error when evaluating: %s %% input: %s, line:%lu\", patbuf->optscript_src,\n\t\t\t\t   getInputFileName (),\n\t\t\t\t   getInputLineNumberInRegPType(patbuf->regptype, offset));\n\t\tes_object_unref (e);\n\t\tscriptTeardown (optvm, lcb);\n\t}\n\n\tvStringDelete (name);\n}\n\nstatic bool matchCallbackPattern (\n\t\tconst vString* const line, const regexPattern* const patbuf,\n\t\tconst regmatch_t* const pmatch)\n{\n\tregexMatch matches [BACK_REFERENCE_COUNT];\n\tunsigned int count = 0;\n\tint i;\n\tfor (i = 0  ;  i < BACK_REFERENCE_COUNT  ;  ++i)\n\t{\n\t\tmatches [i].start  = pmatch [i].rm_so;\n\t\tmatches [i].length = pmatch [i].rm_eo - pmatch [i].rm_so;\n\t\t/* a valid match may have both offsets == -1,\n\t\t * e.g. (foo)*(bar) matching \"bar\" - see CTags bug 271.\n\t\t * As POSIX regex doesn't seem to have a way to count matches,\n\t\t * we return the count up to the last non-empty match. */\n\t\tif (pmatch [i].rm_so != -1)\n\t\t\tcount = i + 1;\n\t}\n\treturn patbuf->u.callback.function (vStringValue (line), matches, count,\n\t\t\t\t     patbuf->u.callback.userData);\n}\n\n\nstatic void printMessage(const langType language,\n\t\t\t\t\t\t const regexPattern *const ptrn,\n\t\t\t\t\t\t const off_t offset,\n\t\t\t\t\t\t const char *const line,\n\t\t\t\t\t\t const regmatch_t* const pmatch)\n{\n\tvString *msg;\n\n\tAssert (ptrn);\n\tAssert (ptrn->message.selection > 0);\n\tAssert (ptrn->message.message_string);\n\n\tmsg = substitute (line, ptrn->message.message_string, BACK_REFERENCE_COUNT, pmatch);\n\n\terror (ptrn->message.selection, \"%sMessage from regex<%s>: %s (%s:%lu)\",\n\t\t   (ptrn->message.selection == FATAL ? \"Fatal: \" : \"\"),\n\t\t   getLanguageName (language),\n\t\t   vStringValue (msg),\n\t\t   getInputFileName (),\n\t\t   getInputLineNumberInRegPType (ptrn->regptype, offset));\n\n\tvStringDelete (msg);\n}\n\nstatic bool isGuestRequestConsistent (struct guestRequest *guest_req)\n{\n\treturn (guest_req->lang != LANG_IGNORE)\n\t\t&& (guest_req->boundary[GUEST_BOUNDARY_START].offset\n\t\t\t< guest_req->boundary[GUEST_BOUNDARY_END].offset);\n}\n\nstatic bool fillGuestRequest (const char *start,\n\t\t\t\t\t\t\t  const char *current,\n\t\t\t\t\t\t\t  regmatch_t pmatch [BACK_REFERENCE_COUNT],\n\t\t\t\t\t\t\t  struct guestSpec *guest_spec,\n\t\t\t\t\t\t\t  struct guestRequest *guest_req)\n{\n\tif (guest_spec->lang.type == GUEST_LANG_UNKNOWN)\n\t\treturn false;\n\telse if (guest_spec->lang.type == GUEST_LANG_PLACEHOLDER)\n\t\t;\n\telse if (guest_spec->lang.type == GUEST_LANG_STATIC_LANGNAME)\n\t{\n\t\tguest_req->lang = guest_spec->lang.spec.lang;\n\t\tguest_req->lang_set = true;\n\t}\n\telse if (guest_spec->lang.type == GUEST_LANG_PTN_GROUP_FOR_LANGNAME)\n\t{\n\t\tconst char * name = current + pmatch [guest_spec->lang.spec.patternGroup].rm_so;\n\t\tint size = pmatch [guest_spec->lang.spec.patternGroup].rm_eo\n\t\t\t- pmatch [guest_spec->lang.spec.patternGroup].rm_so;\n\t\tif (size > 0)\n\t\t{\n\t\t\tguest_req->lang = getNamedLanguageOrAlias (name, size);\n\t\t\tguest_req->lang_set = true;\n\t\t}\n\t}\n\telse if (guest_spec->lang.type == GUEST_LANG_PTN_GROUP_FOR_FILEMAP)\n\t{\n\t\tconst char * name = current + pmatch [guest_spec->lang.spec.patternGroup].rm_so;\n\t\tint size = pmatch [guest_spec->lang.spec.patternGroup].rm_eo\n\t\t\t- pmatch [guest_spec->lang.spec.patternGroup].rm_so;\n\t\tchar *fname = (size > 0)? eStrndup (name, size): NULL;\n\n\t\tif (fname)\n\t\t{\n\t\t\tguest_req->lang = getLanguageForFilename (fname, LANG_AUTO);\n\t\t\tguest_req->lang_set = true;\n\t\t\teFree (fname);\n\t\t}\n\t}\n\n\tfor (int i = 0; i < 2; i++)\n\t{\n\t\tstruct boundarySpec *boundary_spec = guest_spec->boundary + i;\n\t\tstruct boundaryInRequest *boundary = guest_req->boundary + i;\n\t\tif (!boundary_spec->placeholder)\n\t\t{\n\t\t\tboundary->offset =  current - start + (boundary_spec->fromStartOfGroup\n\t\t\t\t\t\t\t\t\t\t\t\t   ? pmatch [boundary_spec->patternGroup].rm_so\n\t\t\t\t\t\t\t\t\t\t\t\t   : pmatch [boundary_spec->patternGroup].rm_eo);\n\t\t\tboundary->offset_set = true;\n\t\t}\n\t}\n\treturn guestRequestIsFilled (guest_req);\n}\n\nstatic bool matchRegexPattern (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t   const vString* const line,\n\t\t\t\t\t\t\t   regexTableEntry *entry)\n{\n\tbool result = false;\n\tregmatch_t pmatch [BACK_REFERENCE_COUNT];\n\tint match;\n\tregexPattern* patbuf = entry->pattern;\n\tstruct guestSpec *guest = &patbuf->guest;\n\n\tif (patbuf->disabled && *(patbuf->disabled))\n\t\treturn false;\n\n\tmatch = patbuf->pattern.backend->match (patbuf->pattern.backend,\n\t\t\t\t\t\t\t\t\t\t\tpatbuf->pattern.code, vStringValue (line),\n\t\t\t\t\t\t\t\t\t\t\tvStringLength (line),\n\t\t\t\t\t\t\t\t\t\t\tpmatch);\n\n\tif (match == 0)\n\t{\n\t\tresult = true;\n\t\tentry->statistics.match++;\n\t\tscriptWindow window = {\n\t\t\t.line = vStringValue (line),\n\t\t\t.start = 0,\n\t\t\t.patbuf = patbuf,\n\t\t\t.pmatch = pmatch,\n\t\t\t.nmatch = BACK_REFERENCE_COUNT,\n\t\t\t.advanceto = false,\n\t\t};\n\n\t\tif (patbuf->optscript && (! hasNameSlot (patbuf)))\n\t\t{\n\t\t\tscriptSetup (optvm, lcb, CORK_NIL, &window);\n\t\t\tEsObject *e = scriptEval (optvm, patbuf->optscript);\n\t\t\tif (es_error_p (e))\n\t\t\t\terror (WARNING, \"error when evaluating: %s %% input: %s\", patbuf->optscript_src,\n\t\t\t\t\t   getInputFileName ());\n\t\t\tes_object_unref (e);\n\t\t\tscriptTeardown (optvm, lcb);\n\t\t}\n\n\t\tif (hasMessage(patbuf))\n\t\t\tprintMessage(lcb->owner, patbuf, 0, vStringValue (line), pmatch);\n\n\t\tif (patbuf->type == PTRN_TAG)\n\t\t{\n\t\t\tmatchTagPattern (lcb, vStringValue (line), patbuf, pmatch, 0,\n\t\t\t\t\t\t\t (patbuf->optscript && hasNameSlot (patbuf))? &window: NULL);\n\n\t\t\tif (guest->lang.type != GUEST_LANG_UNKNOWN)\n\t\t\t{\n\t\t\t\tunsigned long ln = getInputLineNumber ();\n\t\t\t\tlong current = getInputFileOffsetForLine (ln);\n\t\t\t\tif (fillGuestRequest (vStringValue (line) - current,\n\t\t\t\t\t\t\t\t\t  vStringValue (line), pmatch, guest, lcb->guest_req))\n\t\t\t\t{\n\t\t\t\t\tAssert (lcb->guest_req->lang != LANG_AUTO);\n\t\t\t\t\tif (isGuestRequestConsistent(lcb->guest_req))\n\t\t\t\t\t\tguestRequestSubmit (lcb->guest_req);\n\t\t\t\t\tguestRequestClear (lcb->guest_req);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (patbuf->type == PTRN_CALLBACK)\n\t\t\tresult = matchCallbackPattern (line, patbuf, pmatch);\n\t\telse\n\t\t{\n\t\t\tAssert (\"invalid pattern type\" == NULL);\n\t\t\tresult = false;\n\t\t}\n\t}\n\telse\n\t\tentry->statistics.unmatch++;\n\treturn result;\n}\n\nstatic bool matchMultilineRegexPattern (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t\t\t\tconst vString* const allLines,\n\t\t\t\t\t\t\t\t\t\tregexTableEntry *entry)\n{\n\tconst char *start;\n\tconst char *current;\n\tregexPattern* patbuf = entry->pattern;\n\tstruct mGroupSpec *mgroup = &patbuf->mgroup;\n\tstruct guestSpec *guest = &patbuf->guest;\n\n\tbool result = false;\n\tregmatch_t pmatch [BACK_REFERENCE_COUNT];\n\tint match = 0;\n\tunsigned int delta = 1;\n\n\tAssert (patbuf);\n\n\tif (patbuf->disabled && *(patbuf->disabled))\n\t\treturn false;\n\n\tcurrent = start = vStringValue (allLines);\n\tdo\n\t{\n\t\tmatch = patbuf->pattern.backend->match (patbuf->pattern.backend,\n\t\t\t\t\t\t\t\t\t\t\t\tpatbuf->pattern.code, current,\n\t\t\t\t\t\t\t\t\t\t\t\tvStringLength (allLines) - (current - start),\n\t\t\t\t\t\t\t\t\t\t\t\tpmatch);\n\n\t\tif (match != 0)\n\t\t{\n\t\t\tentry->statistics.unmatch++;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (hasMessage(patbuf))\n\t\t\tprintMessage(lcb->owner, patbuf, (current + pmatch[0].rm_so) - start, current, pmatch);\n\n\t\tentry->statistics.match++;\n\t\tscriptWindow window = {\n\t\t\t.line = current,\n\t\t\t.start = start,\n\t\t\t.patbuf = patbuf,\n\t\t\t.pmatch = pmatch,\n\t\t\t.nmatch = BACK_REFERENCE_COUNT,\n\t\t\t.advanceto = false,\n\t\t};\n\n\t\tif (patbuf->optscript && (! hasNameSlot (patbuf)))\n\t\t{\n\t\t\tscriptSetup (optvm, lcb, CORK_NIL, &window);\n\t\t\tEsObject *e = scriptEval (optvm, patbuf->optscript);\n\t\t\tif (es_error_p (e))\n\t\t\t\terror (WARNING, \"error when evaluating: %s %% input: %s\", patbuf->optscript_src,\n\t\t\t\t\t   getInputFileName ());\n\t\t\tes_object_unref (e);\n\t\t\tscriptTeardown (optvm, lcb);\n\t\t}\n\n\t\tif (patbuf->type == PTRN_TAG)\n\t\t{\n\t\t\tAssert (mgroup->forLineNumberDetermination != NO_MULTILINE);\n\t\t\toff_t offset = (current + pmatch [mgroup->forLineNumberDetermination].rm_so)\n\t\t\t\t- start;\n\t\t\tmatchTagPattern (lcb, current, patbuf, pmatch, offset,\n\t\t\t\t\t\t\t (patbuf->optscript && hasNameSlot (patbuf))? &window: NULL);\n\t\t\tresult = true;\n\t\t}\n\t\telse if (patbuf->type == PTRN_CALLBACK)\n\t\t\t;\t/* Not implemented yet */\n\t\telse\n\t\t{\n\t\t\tAssert (\"invalid pattern type\" == NULL);\n\t\t\tresult = false;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (fillGuestRequest (start, current, pmatch, guest, lcb->guest_req))\n\t\t{\n\t\t\tAssert (lcb->guest_req->lang != LANG_AUTO);\n\t\t\tif (isGuestRequestConsistent(lcb->guest_req))\n\t\t\t\tguestRequestSubmit (lcb->guest_req);\n\t\t\tguestRequestClear (lcb->guest_req);\n\t\t}\n\n\t\tdelta = (mgroup->nextFromStart\n\t\t\t\t ? pmatch [mgroup->forNextScanning].rm_so\n\t\t\t\t : pmatch [mgroup->forNextScanning].rm_eo);\n\t\tif (delta == 0)\n\t\t{\n\t\t\tunsigned int pos = current - start;\n\t\t\terror (WARNING,\n\t\t\t\t   \"a multi line regex pattern doesn't advance the input cursor: %s\",\n\t\t\t\t   patbuf->pattern_string);\n\t\t\terror (WARNING, \"Language: %s, input file: %s, pos: %u\",\n\t\t\t\t   getLanguageName (lcb->owner), getInputFileName(), pos);\n\t\t\tbreak;\n\t\t}\n\t\tcurrent += delta;\n\n\t} while (current < start + vStringLength (allLines));\n\n\treturn result;\n}\n\n/* PUBLIC INTERFACE */\n\n/* Match against all patterns for specified language. Returns true if at least\n * on pattern matched.\n */\nextern bool regexIsPostRun (struct lregexControlBlock *lcb)\n{\n\tfor (unsigned int i = 0  ;  i < ptrArrayCount(lcb->entries[REG_PARSER_SINGLE_LINE])  ;  ++i)\n\t{\n\t\tregexTableEntry *entry = ptrArrayItem(lcb->entries[REG_PARSER_SINGLE_LINE], i);\n\t\tregexPattern *ptrn = entry->pattern;\n\n\t\tif (ptrn->postrun)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nextern bool matchRegex (struct lregexControlBlock *lcb, const vString* const line, bool postrun)\n{\n\tbool result = false;\n\tunsigned int i;\n\tfor (i = 0  ;  i < ptrArrayCount(lcb->entries[REG_PARSER_SINGLE_LINE])  ;  ++i)\n\t{\n\t\tregexTableEntry *entry = ptrArrayItem(lcb->entries[REG_PARSER_SINGLE_LINE], i);\n\t\tregexPattern *ptrn = entry->pattern;\n\n\t\tAssert (ptrn);\n\n\t\tif (postrun != ptrn->postrun)\n\t\t\tcontinue;\n\n\t\tif ((ptrn->xtagType != XTAG_UNKNOWN)\n\t\t\t&& (!isXtagEnabled (ptrn->xtagType)))\n\t\t\t\tcontinue;\n\n\t\tif (matchRegexPattern (lcb, line, entry))\n\t\t{\n\t\t\tresult = true;\n\t\t\tif (ptrn->exclusive)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treturn result;\n}\n\nextern void notifyRegexInputStart (struct lregexControlBlock *lcb)\n{\n\tlcb->currentScope = CORK_NIL;\n\n\tptrArrayClear (lcb->tstack);\n\tguestRequestClear (lcb->guest_req);\n\n\topt_vm_dstack_push (optvm, lregex_dict);\n\n\tif (es_null (lcb->local_dict))\n\t\tlcb->local_dict = opt_dict_new (23);\n\topt_vm_dstack_push (optvm, lcb->local_dict);\n\tset_current_lcb (optvm, lcb);\n\tscriptEvalHook (optvm, lcb, SCRIPT_HOOK_PRELUDE);\n}\n\nextern void notifyRegexInputEnd (struct lregexControlBlock *lcb)\n{\n\t/* Push a placeholder tag representing the end of input file.\n\t * From .ctags code, you can refer the placeholder tag with \".\".\n\t * The typical code pattern is \". :line\":, pushing the line\n\t * number of the last line of the input file.\n\t */\n\tint index = makePlaceholder (\"EndOfInput\");\n\toptscriptSetup (optvm, lcb->local_dict, index);\n\tscriptEvalHook (optvm, lcb, SCRIPT_HOOK_SEQUEL);\n\toptscriptTeardown (optvm, lcb->local_dict);\n\n\tunsigned int garbage;\n\tif ((garbage = opt_vm_ostack_count (optvm)) > 0)\n\t\terror (WARNING, \"[%s] %u objects are left on the operand stack: %s\",\n\t\t\t   getLanguageName (lcb->owner), garbage,\n\t\t\t   getInputFileName ());\n\n\tset_current_lcb (optvm, NULL);\n\topt_vm_clear (optvm, false);\n\topt_dict_clear (lcb->local_dict);\n\tunsigned long endline = getInputLineNumber ();\n\tfillEndLineFieldOfUpperScopes (lcb, endline);\n}\n\nextern void findRegexTagsMainloop (int (* driver)(void))\n{\n\t/* merely read all lines of the file */\n\twhile (driver () != EOF)\n\t\t;\n}\n\nstatic int fileReadLineDriver(void)\n{\n\treturn (readLineFromInputFile () == NULL)? EOF: 1;\n}\n\nextern void findRegexTags (void)\n{\n\tfindRegexTagsMainloop (fileReadLineDriver);\n}\n\nstatic bool doesExpectCorkInRegex0(ptrArray *entries)\n{\n\tfor (unsigned int i = 0; i < ptrArrayCount(entries); i++)\n\t{\n\t\tregexTableEntry *entry = ptrArrayItem(entries, i);\n\t\tAssert (entry && entry->pattern);\n\t\tif (entry->pattern->scopeActions\n\t\t\t|| entry->pattern->optscript\n\t\t\t)\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nextern bool doesExpectCorkInRegex (struct lregexControlBlock *lcb)\n{\n\tptrArray *entries;\n\n\tentries = lcb->entries[REG_PARSER_SINGLE_LINE];\n\tif (doesExpectCorkInRegex0 (entries))\n\t\treturn true;\n\n\tentries = lcb->entries[REG_PARSER_MULTI_LINE];\n\tif (doesExpectCorkInRegex0 (entries))\n\t\treturn true;\n\n\tfor (unsigned int i = 0; i < ptrArrayCount(lcb->tables); i++)\n\t{\n\t\tstruct regexTable *table = ptrArrayItem(lcb->tables, i);\n\t\tif (doesExpectCorkInRegex0 (table->entries))\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic char *escapeRegexPattern (const char* pattern)\n{\n\tvString *p = vStringNew ();\n\n\twhile (*pattern != '\\0')\n\t{\n\t\tchar c = *pattern;\n\t\tif (c == '\\n')\n\t\t\tvStringCatS(p, \"\\\\n\");\n\t\telse if (c == '\\t')\n\t\t\tvStringCatS(p, \"\\\\t\");\n\t\telse if (c == '\\\\')\n\t\t\tvStringCatS(p, \"\\\\\\\\\");\n\t\telse\n\t\t\tvStringPut(p, c);\n\n\t\tpattern++;\n\t}\n\n\treturn vStringDeleteUnwrap (p);\n}\n\nstatic regexPattern *addTagRegexInternal (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t\t\t\t  int table_index,\n\t\t\t\t\t  enum regexParserType regptype,\n\t\t\t\t\t  const char* const regex,\n\t\t\t\t\t  const char* const name,\n\t\t\t\t\t  const char* const kinds,\n\t\t\t\t\t  const char* const flags,\n\t\t\t\t\t  bool *disabled)\n{\n\tAssert (regex != NULL);\n\tAssert (name != NULL);\n\n\tif (!regexAvailable)\n\t\treturn NULL;\n\n\tregexCompiledCode cp = compileRegex (regptype, regex, flags);\n\tif (cp.code == NULL)\n\t{\n\t\terror (WARNING, \"pattern: %s\", regex);\n\t\tif (table_index != TABLE_INDEX_UNUSED)\n\t\t{\n\t\t\tstruct regexTable *table = ptrArrayItem (lcb->tables, table_index);\n\t\t\terror (WARNING, \"table: %s[%u]\", table->name, ptrArrayCount (table->entries));\n\t\t\terror (WARNING, \"language: %s\", getLanguageName (lcb->owner));\n\t\t}\n\t\telse\n\t\t\terror (WARNING, \"language: %s[%u]\", getLanguageName (lcb->owner),\n\t\t\t\t   ptrArrayCount (lcb->entries[regptype]));\n\n\t\tstruct flagDefsDescriptor desc = choose_backend (flags, regptype, false);\n\t\terror (WARNING, \"Failed in compiling the regex pattern with \\\"%s\\\" regex engine\",\n\t\t\t   desc.backend->name);\n\t\treturn NULL;\n\t}\n\n\tchar kindLetter;\n\tchar* kindName;\n\tchar* description;\n\tkindDefinition* fileKind;\n\n\tbool explictly_defined =  parseKinds (kinds, &kindLetter, &kindName, &description);\n\tfileKind = getLanguageKind (lcb->owner, KIND_FILE_INDEX);\n\tif (kindLetter == fileKind->letter)\n\t\terror (FATAL,\n\t\t\t   \"Kind letter \\'%c\\' used in regex definition \\\"%s\\\" of %s language is reserved in ctags main\",\n\t\t\t   kindLetter,\n\t\t\t   regex,\n\t\t\t   getLanguageName (lcb->owner));\n\telse if (!isalpha ((unsigned char)kindLetter))\n\t\terror (FATAL,\n\t\t\t   \"Kind letter must be an alphabetical character: \\\"%c\\\"\",\n\t\t\t   kindLetter);\n\n\tif (strcmp (kindName, fileKind->name) == 0)\n\t\terror (FATAL,\n\t\t\t   \"Kind name \\\"%s\\\" used in regex definition \\\"%s\\\" of %s language is reserved in ctags main\",\n\t\t\t   kindName,\n\t\t\t   regex,\n\t\t\t   getLanguageName (lcb->owner));\n\n\tconst char *option_base = (regptype == REG_PARSER_SINGLE_LINE? \"regex\"        :\n\t\t\t\t\t\t\t   regptype == REG_PARSER_MULTI_LINE ? \"mline-regex\"  :\n\t\t\t\t\t\t\t   regptype == REG_PARSER_MULTI_TABLE? \"_mtable-regex\":\n\t\t\t\t\t\t\t   NULL);\n\tAssert (option_base);\n\n\tfor (const char * p = kindName; *p; p++)\n\t{\n\t\tif (p == kindName)\n\t\t{\n\t\t\tif (!isalpha((unsigned char) *p))\n\t\t\t\terror (FATAL,\n\t\t\t\t\t   \"A kind name doesn't start with an alphabetical character: \"\n\t\t\t\t\t   \"'%s' in \\\"--%s-%s\\\" option\",\n\t\t\t\t\t   kindName,\n\t\t\t\t\t   option_base,\n\t\t\t\t\t   getLanguageName (lcb->owner));\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/*\n\t\t\t * People may object to this error.\n\t\t\t * Searching github repositories, I found not a few .ctags files\n\t\t\t * in which Exuberant-ctags users define kind names with whitespaces.\n\t\t\t * \"FATAL\" error breaks the compatibility.\n\t\t\t */\n\t\t\tif (!isalnum((unsigned char) *p))\n\t\t\t\terror (/* regptype == REG_PARSER_SINGLE_LINE? WARNING: */ FATAL,\n\t\t\t\t\t   \"Non-alphanumeric char is used in kind name: \"\n\t\t\t\t\t   \"'%s' in \\\"--%s-%s\\\" option\",\n\t\t\t\t\t   kindName,\n\t\t\t\t\t   option_base,\n\t\t\t\t\t   getLanguageName (lcb->owner));\n\n\t\t}\n\t}\n\n\tregexPattern *rptr = addCompiledTagPattern (lcb, table_index,\n\t\t\t\t\t\t\t\t\t\t\t\tregptype, &cp, name,\n\t\t\t\t\t\t\t\t\t\t\t\tkindLetter, kindName, description, flags,\n\t\t\t\t\t\t\t\t\t\t\t\texplictly_defined,\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled);\n\trptr->pattern_string = escapeRegexPattern(regex);\n\n\teFree (kindName);\n\tif (description)\n\t\teFree (description);\n\n\tif (*name == '\\0')\n\t{\n\t\tif (rptr->exclusive || rptr->scopeActions & SCOPE_PLACEHOLDER\n\t\t\t|| rptr->anonymous_tag_prefix\n\t\t\t|| regptype == REG_PARSER_MULTI_TABLE\n\t\t\t|| rptr->guest.lang.type != GUEST_LANG_UNKNOWN\n\t\t\t|| rptr->optscript\n\t\t\t)\n\t\t\trptr->accept_empty_name = true;\n\t\telse\n\t\t\terror (WARNING, \"%s: regexp missing name pattern\", regex);\n\t}\n\n\treturn rptr;\n}\n\nextern void addTagRegex (struct lregexControlBlock *lcb,\n\t\t\t const char* const regex,\n\t\t\t const char* const name,\n\t\t\t const char* const kinds,\n\t\t\t const char* const flags,\n\t\t\t bool *disabled)\n{\n\taddTagRegexInternal (lcb, TABLE_INDEX_UNUSED,\n\t\t\t\t\t\t REG_PARSER_SINGLE_LINE, regex, name, kinds, flags, disabled);\n}\n\nextern void addTagMultiLineRegex (struct lregexControlBlock *lcb, const char* const regex,\n\t\t\t\t\t\t\t\t  const char* const name, const char* const kinds, const char* const flags,\n\t\t\t\t\t\t\t\t  bool *disabled)\n{\n\tregexPattern *ptrn = addTagRegexInternal (lcb, TABLE_INDEX_UNUSED,\n\t\t\t\t\t\t\t\t\t\t\t  REG_PARSER_MULTI_LINE, regex, name, kinds, flags, disabled);\n\tif (!ptrn)\n\t\treturn;\n\n\tif (ptrn->mgroup.forLineNumberDetermination == NO_MULTILINE)\n\t{\n\t\tif (hasNameSlot(ptrn))\n\t\t\terror (WARNING, \"%s: no {mgroup=N} flag given in --mline-regex-<LANG>=/%s/... (%s)\",\n\t\t\t\t   regex,\n\t\t\t\t   getLanguageName (lcb->owner), ASSERT_FUNCTION);\n\t\tptrn->mgroup.forLineNumberDetermination = 0;\n\t}\n}\n\nextern void addTagMultiTableRegex(struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t\t  const char* const table_name,\n\t\t\t\t\t\t\t\t  const char* const regex,\n\t\t\t\t\t\t\t\t  const char* const name, const char* const kinds, const char* const flags,\n\t\t\t\t\t\t\t\t  bool *disabled)\n{\n\tint table_index = getTableIndexForName (lcb, table_name);\n\n\tif (table_index < 0)\n\t\terror (FATAL, \"unknown table name: %s\", table_name);\n\n\taddTagRegexInternal (lcb, table_index, REG_PARSER_MULTI_TABLE, regex, name, kinds, flags,\n\t\t\t\t\t\t disabled);\n}\n\nextern void addCallbackRegex (struct lregexControlBlock *lcb,\n\t\t\t      const char* const regex,\n\t\t\t      const char* const flags,\n\t\t\t      const regexCallback callback,\n\t\t\t      bool *disabled,\n\t\t\t      void * userData)\n{\n\tAssert (regex != NULL);\n\n\tif (!regexAvailable)\n\t\treturn;\n\n\n\tregexCompiledCode cp = compileRegex (REG_PARSER_SINGLE_LINE, regex, flags);\n\tif (cp.code == NULL)\n\t{\n\t\terror (WARNING, \"pattern: %s\", regex);\n\t\terror (WARNING, \"language: %s\", getLanguageName (lcb->owner));\n\t\treturn;\n\t}\n\n\tregexPattern *rptr = addCompiledCallbackPattern (lcb, &cp, callback, flags,\n\t\t\t\t\t\t\t\t\t\t\t\t\t disabled, userData);\n\trptr->pattern_string = escapeRegexPattern(regex);\n}\n\nstatic void addTagRegexOption (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t   enum regexParserType regptype,\n\t\t\t\t\t\t\t   const char* const pattern)\n{\n\tif (!regexAvailable)\n\t\treturn;\n\n\tint table_index = TABLE_INDEX_UNUSED;\n\tchar * regex_pat = NULL;\n\tchar *name, *kinds, *flags;\n\n\n\tif (regptype == REG_PARSER_MULTI_TABLE)\n\t{\n\t\tconst char *c;\n\t\tfor (c = pattern; *c; c++)\n\t\t{\n\t\t\tif (! (isalnum((unsigned char) *c) || *c == '_'))\n\t\t\t{\n\t\t\t\tif (*c &&  (*(c + 1) != '^'))\n\t\t\t\t{\n\t\t\t\t\tvString *tmp = vStringNew ();\n\n\t\t\t\t\t/* Put '^' as prefix for the pattern */\n\t\t\t\t\tvStringPut(tmp, *c);\n\t\t\t\t\tvStringPut(tmp, '^');\n\t\t\t\t\tvStringCatS(tmp, c + 1);\n\t\t\t\t\tregex_pat = vStringDeleteUnwrap(tmp);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tregex_pat = eStrdup (c);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (regex_pat == NULL || *regex_pat == '\\0')\n\t\t\terror (FATAL, \"wrong mtable pattern specification: %s\", pattern);\n\n\t\tchar *table_name = eStrndup(pattern, c - pattern);\n\t\ttable_index = getTableIndexForName (lcb, table_name);\n\t\tif (table_index < 0)\n\t\t\terror (FATAL, \"unknown table name: %s (in %s)\", table_name, pattern);\n\t\teFree(table_name);\n\t}\n\telse\n\t\tregex_pat = eStrdup (pattern);\n\n\tif (parseTagRegex (regptype, regex_pat, &name, &kinds, &flags))\n\t{\n\t\tregexPattern *ptrn = addTagRegexInternal (lcb, table_index, regptype, regex_pat, name, kinds, flags,\n\t\t\t\t\t\t\t\t\t\t\t\t  NULL);\n\t\tif (!ptrn)\n\t\t\tgoto out;\n\n\t\tif (regptype == REG_PARSER_MULTI_LINE\n\t\t\t&& ptrn->mgroup.forLineNumberDetermination == NO_MULTILINE)\n\t\t{\n\t\t\tif (hasNameSlot(ptrn))\n\t\t\t\terror (WARNING, \"%s: no {mgroup=N} flag given in --mline-regex-<LANG>=%s... (%s)\",\n\t\t\t\t\t   getLanguageName (lcb->owner),\n\t\t\t\t\t   pattern, ASSERT_FUNCTION);\n\t\t\tptrn->mgroup.forLineNumberDetermination = 0;\n\t\t}\n\t}\n\n out:\n\teFree (regex_pat);\n}\n\nextern void processTagRegexOption (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t\t   enum regexParserType regptype,\n\t\t\t\t\t\t\t\t   const char* const parameter)\n{\n\tif (parameter == NULL  ||  parameter [0] == '\\0')\n\t\tclearPatternSet (lcb);\n\telse if (parameter [0] != '@')\n\t\taddTagRegexOption (lcb, regptype, parameter);\n\telse if (! doesFileExist (parameter + 1))\n\t\terror (WARNING, \"cannot open regex file\");\n\telse\n\t{\n\t\tconst char* regexfile = parameter + 1;\n\n\t\tverbose (\"open a regex file: %s\\n\", regexfile);\n\t\tMIO* const mio = mio_new_file (regexfile, \"r\");\n\t\tif (mio == NULL)\n\t\t\terror (WARNING | PERROR, \"%s\", regexfile);\n\t\telse\n\t\t{\n\t\t\tvString* const regex = vStringNew ();\n\t\t\twhile (readLineRaw (regex, mio))\n\t\t\t{\n\t\t\t\tif (vStringLength (regex) > 1 && vStringValue (regex)[0] != '\\n')\n\t\t\t\t\taddTagRegexOption (lcb, regptype, vStringValue (regex));\n\t\t\t}\n\t\t\tmio_unref (mio);\n\t\t\tvStringDelete (regex);\n\t\t}\n\t}\n}\n\n/*\n*   Regex option parsing\n*/\n\nextern void printRegexFlags (bool withListHeader, bool machinable, const char *flags, FILE *fp)\n{\n\tstruct colprintTable * table = flagsColprintTableNew ();\n\n\tif (flags && *flags != '\\0')\n\t{\n\t\t/* Print backend specific flags.\n\t\t * This code is just stub because there is no backend having a specific flag.\n\t\t * The help message for this option is not updated. */\n\t\tstruct flagDefsDescriptor desc = choose_backend (flags, REG_PARSER_SINGLE_LINE, true);\n\t\tflagsColprintAddDefinitions (table, desc.backend->fdefs, desc.backend->fdef_count);\n\t}\n\telse\n\t{\n\t\tflagsColprintAddDefinitions (table, backendFlagDefs, ARRAY_SIZE(backendFlagDefs));\n\t\tflagsColprintAddDefinitions (table, backendCommonRegexFlagDefs, ARRAY_SIZE(backendCommonRegexFlagDefs));\n\t\tflagsColprintAddDefinitions (table, prePtrnFlagDef, ARRAY_SIZE (prePtrnFlagDef));\n\t\tflagsColprintAddDefinitions (table, guestPtrnFlagDef, ARRAY_SIZE (guestPtrnFlagDef));\n\t\tflagsColprintAddDefinitions (table, scopePtrnFlagDef, ARRAY_SIZE (scopePtrnFlagDef));\n\t\tflagsColprintAddDefinitions (table, preCommonSpecFlagDef, ARRAY_SIZE (preCommonSpecFlagDef));\n\t\tflagsColprintAddDefinitions (table, commonSpecFlagDef, ARRAY_SIZE (commonSpecFlagDef));\n\t}\n\n\tflagsColprintTablePrint (table, withListHeader, machinable, fp);\n\tcolprintTableDelete(table);\n}\n\nextern void printMultilineRegexFlags (bool withListHeader, bool machinable, const char *flags, FILE *fp)\n{\n\tstruct colprintTable * table = flagsColprintTableNew ();\n\n\tif (flags && *flags != '\\0')\n\t{\n\t\t/* Print backend specific flags.\n\t\t * This code is just stub because there is no backend having a specific flag.\n\t\t * The help message for this option is not updated. */\n\t\tstruct flagDefsDescriptor desc = choose_backend (flags, REG_PARSER_MULTI_LINE, true);\n\t\tflagsColprintAddDefinitions (table, desc.backend->fdefs, desc.backend->fdef_count);\n\t}\n\telse\n\t{\n\t\tflagsColprintAddDefinitions (table, backendFlagDefs, ARRAY_SIZE(backendFlagDefs));\n\t\tflagsColprintAddDefinitions (table, backendCommonRegexFlagDefs, ARRAY_SIZE(backendCommonRegexFlagDefs));\n\t\tflagsColprintAddDefinitions (table, multilinePtrnFlagDef, ARRAY_SIZE (multilinePtrnFlagDef));\n\t\tflagsColprintAddDefinitions (table, guestPtrnFlagDef, ARRAY_SIZE (guestPtrnFlagDef));\n\t\tflagsColprintAddDefinitions (table, intervaltabPtrnFlagDef, ARRAY_SIZE (intervaltabPtrnFlagDef));\n\t\tflagsColprintAddDefinitions (table, preCommonSpecFlagDef, ARRAY_SIZE (preCommonSpecFlagDef));\n\t\tflagsColprintAddDefinitions (table, commonSpecFlagDef, ARRAY_SIZE (commonSpecFlagDef));\n\t}\n\n\tflagsColprintTablePrint (table, withListHeader, machinable, fp);\n\tcolprintTableDelete(table);\n}\n\nextern void printMultitableRegexFlags (bool withListHeader, bool machinable, const char *flags, FILE *fp)\n{\n\tstruct colprintTable * table = flagsColprintTableNew ();\n\n\tif (flags && *flags != '\\0')\n\t{\n\t\t/* Print backend specific flags.\n\t\t * This code is just stub because there is no backend having a specific flag.\n\t\t * The help message for this option is not updated. */\n\t\tstruct flagDefsDescriptor desc = choose_backend (flags, REG_PARSER_MULTI_TABLE, true);\n\t\tflagsColprintAddDefinitions (table, desc.backend->fdefs, desc.backend->fdef_count);\n\t}\n\telse\n\t{\n\t\tflagsColprintAddDefinitions (table, backendFlagDefs, ARRAY_SIZE(backendFlagDefs));\n\t\tflagsColprintAddDefinitions (table, backendCommonRegexFlagDefs, ARRAY_SIZE(backendCommonRegexFlagDefs));\n\t\tflagsColprintAddDefinitions (table, multilinePtrnFlagDef, ARRAY_SIZE (multilinePtrnFlagDef));\n\t\tflagsColprintAddDefinitions (table, multitablePtrnFlagDef, ARRAY_SIZE (multitablePtrnFlagDef));\n\t\tflagsColprintAddDefinitions (table, guestPtrnFlagDef, ARRAY_SIZE (guestPtrnFlagDef));\n\t\tflagsColprintAddDefinitions (table, scopePtrnFlagDef, ARRAY_SIZE (scopePtrnFlagDef));\n\t\tflagsColprintAddDefinitions (table, preCommonSpecFlagDef, ARRAY_SIZE (preCommonSpecFlagDef));\n\t\tflagsColprintAddDefinitions (table, commonSpecFlagDef, ARRAY_SIZE (commonSpecFlagDef));\n\t}\n\n\tflagsColprintTablePrint (table, withListHeader, machinable, fp);\n\tcolprintTableDelete(table);\n}\n\nextern void freeRegexResources (void)\n{\n\tes_object_unref (lregex_dict);\n\tvoid *d = opt_vm_set_app_data(optvm, NULL);\n\tif (d)\n\t\teFree (d);\n\topt_vm_delete (optvm);\n}\n\nextern bool lregexControlBlockHasAny(struct lregexControlBlock *lcb)\n{\n\treturn (ptrArrayCount(lcb->entries [REG_PARSER_MULTI_LINE])\n\t\t\t|| ptrArrayCount(lcb->tables)\n\t\t\t|| ptrArrayCount(lcb->entries[REG_PARSER_SINGLE_LINE]));\n}\n\nextern bool regexNeedsMultilineBuffer (struct lregexControlBlock *lcb)\n{\n\tif  (ptrArrayCount(lcb->entries [REG_PARSER_MULTI_LINE]) > 0)\n\t\treturn true;\n\telse if (ptrArrayCount(lcb->tables) > 0)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nextern bool matchMultilineRegex (struct lregexControlBlock *lcb, const vString* const allLines)\n{\n\tbool result = false;\n\n\tunsigned int i;\n\n\tfor (i = 0; i < ptrArrayCount(lcb->entries [REG_PARSER_MULTI_LINE]); ++i)\n\t{\n\t\tregexTableEntry *entry = ptrArrayItem(lcb->entries [REG_PARSER_MULTI_LINE], i);\n\t\tAssert (entry && entry->pattern);\n\n\t\tif ((entry->pattern->xtagType != XTAG_UNKNOWN)\n\t\t\t&& (!isXtagEnabled (entry->pattern->xtagType)))\n\t\t\tcontinue;\n\n\t\tresult = matchMultilineRegexPattern (lcb, allLines, entry) || result;\n\t}\n\treturn result;\n}\n\nstatic int getTableIndexForName (const struct lregexControlBlock *const lcb, const char *name)\n{\n\tunsigned int i;\n\n\tfor (i = 0; i < ptrArrayCount(lcb->tables); i++)\n\t{\n\t\tstruct regexTable *table = ptrArrayItem(lcb->tables, i);\n\t\tif (strcmp (table->name, name) == 0)\n\t\t\treturn (int)i;\n\t}\n\n\treturn TABLE_INDEX_UNUSED;\n}\n\nextern void addRegexTable (struct lregexControlBlock *lcb, const char *name)\n{\n\tconst char *c;\n\tfor (c = name; *c; c++)\n\t\tif (! (isalnum((unsigned char) *c) || *c == '_'))\n\t\t\terror (FATAL, \"`%c' in \\\"%s\\\" is not acceptable as part of table name\", *c, name);\n\n\tif (getTableIndexForName(lcb, name) >= 0)\n\t{\n\t\terror (WARNING, \"regex table \\\"%s\\\" is already defined\", name);\n\t\treturn;\n\t}\n\n\tstruct regexTable *table = xCalloc(1, struct regexTable);\n\ttable->name = eStrdup (name);\n\ttable->entries = ptrArrayNew(deleteTableEntry);\n\n\tptrArrayAdd (lcb->tables, table);\n}\n\nstatic void dumpSstack(FILE* fp, int scope)\n{\n\ttagEntryInfo *entry;\n\tfprintf (fp, \"scope : \");\n\twhile ((entry = getEntryInCorkQueue (scope)))\n\t{\n\t\tfprintf(fp, \"%s\", entry->name);\n\n\t\tscope = entry->extensionFields.scopeIndex;\n\t\tif (scope != CORK_NIL)\n\t\t\tfprintf(fp, \"%c\", '/');\n\t}\n\tfprintf (fp, \"\\n\");\n}\n\nstatic void dumpTstack(FILE* fp, ptrArray *tstack)\n{\n\tfor (unsigned int i = ptrArrayCount(tstack); i > 0; i--)\n\t{\n\t\tchar tmp[2];\n\t\tstruct regexTable *t = ptrArrayItem(tstack, i - 1);\n\t\tif (i == 1)\n\t\t\ttmp[0] = '\\0';\n\t\telse\n\t\t{\n\t\t\ttmp[0] = '/';\n\t\t\ttmp[1] = '\\0';\n\t\t}\n\t\tfprintf(fp, \"%s%s\", t->name, tmp);\n\t}\n\tfprintf(fp, \"\\n\");\n}\n\nstatic void printInputLine(FILE* vfp, const char *c, const off_t offset)\n{\n\tvString *v = vStringNew ();\n\n\tfor (; *c && (*c != '\\n'); c++)\n\t\tvStringPut(v, *c);\n\n\tif (vStringLength (v) == 0 && *c == '\\n')\n\t\tvStringCatS (v, \"\\\\n\");\n\n\tfprintf (vfp, \"\\ninput : \\\"%s\\\" L%lu\\n\",\n\t\t\t vStringValue (v),\n\t\t\t getInputLineNumberForFileOffset(offset));\n\tvStringDelete(v);\n}\n\nstatic void printMultitableMessage(const langType language,\n\t\t\t\t\t\t\t\t   const char *const tableName,\n\t\t\t\t\t\t\t\t   const unsigned int index,\n\t\t\t\t\t\t\t\t   const regexPattern *const ptrn,\n\t\t\t\t\t\t\t\t   const off_t offset,\n\t\t\t\t\t\t\t\t   const char *const current,\n\t\t\t\t\t\t\t\t   const regmatch_t* const pmatch)\n{\n\tvString *msg;\n\n\tAssert (ptrn);\n\tAssert (ptrn->message.selection > 0);\n\tAssert (ptrn->message.message_string);\n\n\tmsg = substitute (current, ptrn->message.message_string, BACK_REFERENCE_COUNT, pmatch);\n\n\terror (ptrn->message.selection, \"%sMessage from mtable<%s/%s[%2u]>: %s (%s:%lu)\",\n\t\t   (ptrn->message.selection == FATAL ? \"Fatal: \" : \"\"),\n\t\t   getLanguageName (language),\n\t\t   tableName,\n\t\t   index,\n\t\t   vStringValue (msg),\n\t\t   getInputFileName (),\n\t\t   getInputLineNumberForFileOffset (offset));\n\n\tvStringDelete (msg);\n}\n\nstatic struct regexTable * matchMultitableRegexTable (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  struct regexTable *table, const vString *const start, unsigned int *offset)\n{\n\tstruct regexTable *next = NULL;\n\tconst char *current;\n\tregmatch_t pmatch [BACK_REFERENCE_COUNT];\n\tconst char *cstart = vStringValue(start);\n\tunsigned int delta;\n\n\n restart:\n\tcurrent = cstart + *offset;\n\n\t/* Accept the case *offset == vStringLength(start)\n\t   because we want an empty regex // still matches empty input. */\n\tif (*offset > vStringLength(start))\n\t{\n\t\t*offset = vStringLength(start);\n\t\tgoto out;\n\t}\n\n\tBEGIN_VERBOSE(vfp);\n\t{\n\t\tprintInputLine(vfp, current, *offset);\n\t}\n\tEND_VERBOSE();\n\n\tfor (unsigned int i = 0; i < ptrArrayCount(table->entries); i++)\n\t{\n\t\tregexTableEntry *entry = ptrArrayItem(table->entries, i);\n\t\tif ((entry->pattern->xtagType != XTAG_UNKNOWN)\n\t\t\t&& (!isXtagEnabled (entry->pattern->xtagType)))\n\t\t\tcontinue;\n\n\t\tregexPattern *ptrn = entry->pattern;\n\t\tstruct guestSpec *guest = &ptrn->guest;\n\n\t\tAssert (ptrn);\n\n\t\tBEGIN_VERBOSE(vfp);\n\t\t{\n\t\t\tchar s[3];\n\t\t\tif (*current == '\\n')\n\t\t\t{\n\t\t\t\ts [0] = '\\\\';\n\t\t\t\ts [1] = 'n';\n\t\t\t\ts [2] = '\\0';\n\t\t\t}\n\t\t\telse if (*current == '\\t')\n\t\t\t{\n\t\t\t\ts [0] = '\\\\';\n\t\t\t\ts [1] = 't';\n\t\t\t\ts [2] = '\\0';\n\t\t\t}\n\t\t\telse if (*current == '\\\\')\n\t\t\t{\n\t\t\t\ts [0] = '\\\\';\n\t\t\t\ts [1] = '\\\\';\n\t\t\t\ts [2] = '\\0';\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ts[0] = *current;\n\t\t\t\ts[1] = '\\0';\n\t\t\t}\n\n\t\t\tif (s[1] == '\\0')\n\t\t\t\tfprintf (vfp, \"match : '%s' %15s[%2u] /\", s, table->name, i);\n\t\t\telse if (s[0] == '\\0')\n\t\t\t\tfprintf (vfp, \"match :  '' %15s[%2u] /\", table->name, i);\n\t\t\telse\n\t\t\t\tfprintf (vfp, \"match :'%s' %15s[%2u] / \", s, table->name, i);\n\t\t\tfprintf (vfp, \"%s/\\n\", ptrn->pattern_string);\n\t\t}\n\t\tEND_VERBOSE();\n\n\t\tint match = 0;\n\n\t\tif (ptrn->disabled && *(ptrn->disabled))\n\t\t\tcontinue;\n\n\t\tmatch = ptrn->pattern.backend->match (ptrn->pattern.backend,\n\t\t\t\t\t\t\t\t\t\t\t  ptrn->pattern.code, current,\n\t\t\t\t\t\t\t\t\t\t\t  vStringLength(start) - (current - cstart),\n\t\t\t\t\t\t\t\t\t\t\t  pmatch);\n\t\tif (match == 0)\n\t\t{\n\t\t\tentry->statistics.match++;\n\t\t\tscriptWindow window = {\n\t\t\t\t.line = current,\n\t\t\t\t.start = cstart,\n\t\t\t\t.patbuf = ptrn,\n\t\t\t\t.pmatch = pmatch,\n\t\t\t\t.nmatch = BACK_REFERENCE_COUNT,\n\t\t\t\t.advanceto = false,\n\t\t\t};\n\t\t\tinitTaction (&window.taction);\n\n\t\t\tif (ptrn->optscript && (! hasNameSlot (ptrn)))\n\t\t\t{\n\t\t\t\tscriptSetup (optvm, lcb, CORK_NIL, &window);\n\t\t\t\tEsObject *e = scriptEval (optvm, ptrn->optscript);\n\t\t\t\tif (es_error_p (e))\n\t\t\t\t\terror (WARNING, \"error when evaluating: %s\", ptrn->optscript_src);\n\t\t\t\tes_object_unref (e);\n\t\t\t\tscriptTeardown (optvm, lcb);\n\t\t\t}\n\n\t\t\tif (ptrn->type == PTRN_TAG)\n\t\t\t{\n\t\t\t\tAssert (ptrn->mgroup.forLineNumberDetermination != NO_MULTILINE);\n\t\t\t\toff_t offset_for_tag = (current\n\t\t\t\t\t\t\t\t\t\t+ pmatch [ptrn->mgroup.forLineNumberDetermination].rm_so)\n\t\t\t\t\t- cstart;\n\t\t\t\tmatchTagPattern (lcb, current, ptrn, pmatch, offset_for_tag,\n\t\t\t\t\t\t\t\t (ptrn->optscript && hasNameSlot (ptrn))? &window: NULL);\n\n\t\t\t\tstruct mTableActionSpec *taction = (window.taction.action == TACTION_NOP)\n\t\t\t\t\t? &(ptrn->taction)\n\t\t\t\t\t: &window.taction;\n\n\t\t\t\tBEGIN_VERBOSE(vfp);\n\t\t\t\t{\n\t\t\t\t\tfprintf(vfp, \"result: matched %d bytes\\n\", (int)(pmatch[0].rm_eo));\n\t\t\t\t\tdumpSstack (vfp, lcb->currentScope);\n\t\t\t\t}\n\t\t\t\tEND_VERBOSE();\n\n\t\t\t\tif (hasMessage(ptrn))\n\t\t\t\t\tprintMultitableMessage (lcb->owner, table->name, i, ptrn,\n\t\t\t\t\t\t\t\t\t\t\t*offset, current, pmatch);\n\n\t\t\t\tif (fillGuestRequest (cstart, current, pmatch, guest, lcb->guest_req))\n\t\t\t\t{\n\t\t\t\t\tAssert (lcb->guest_req->lang != LANG_AUTO);\n\t\t\t\t\tif (isGuestRequestConsistent(lcb->guest_req))\n\t\t\t\t\t\tguestRequestSubmit (lcb->guest_req);\n\t\t\t\t\tguestRequestClear (lcb->guest_req);\n\t\t\t\t}\n\n\t\t\t\tif (window.advanceto)\n\t\t\t\t\tdelta = window.advanceto_delta;\n\t\t\t\telse\n\t\t\t\t\tdelta = (ptrn->mgroup.nextFromStart\n\t\t\t\t\t\t\t ? pmatch [ptrn->mgroup.forNextScanning].rm_so\n\t\t\t\t\t\t\t : pmatch [ptrn->mgroup.forNextScanning].rm_eo);\n\t\t\t\t*offset += delta;\n\n\t\t\t\tswitch (taction->action)\n\t\t\t\t{\n\t\t\t\tcase TACTION_NOP:\n\t\t\t\t\tBEGIN_VERBOSE(vfp);\n\t\t\t\t\t{\n\t\t\t\t\t\tfprintf(vfp, \"action: NOP in {%s}, stack: /\", table->name);\n\t\t\t\t\t\tdumpTstack(vfp, lcb->tstack);\n\t\t\t\t\t}\n\t\t\t\t\tEND_VERBOSE();\n\t\t\t\t\tbreak;\n\t\t\t\tcase TACTION_ENTER:\n\t\t\t\t\t/* TODO: Limit the depth of tstack.  */\n\t\t\t\t\tptrArrayAdd (lcb->tstack,\n\t\t\t\t\t\t\t\t taction->continuation_table\n\t\t\t\t\t\t\t\t ? taction->continuation_table\n\t\t\t\t\t\t\t\t : table);\n\t\t\t\t\tnext = taction->table;\n\t\t\t\t\tBEGIN_VERBOSE(vfp);\n\t\t\t\t\t{\n\t\t\t\t\t\tif (taction->continuation_table)\n\t\t\t\t\t\t\tfprintf(vfp, \"action: [enter] to {%s}, cont: {%s}, stack: /\",\n\t\t\t\t\t\t\t\t\tnext->name,\n\t\t\t\t\t\t\t\t\ttaction->continuation_table->name);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tfprintf(vfp, \"action: [enter] to {%s}, stack: /\", next->name);\n\t\t\t\t\t\tdumpTstack(vfp, lcb->tstack);\n\t\t\t\t\t}\n\t\t\t\t\tEND_VERBOSE();\n\t\t\t\t\tbreak;\n\t\t\t\tcase TACTION_LEAVE:\n\t\t\t\t\tBEGIN_VERBOSE(vfp);\n\t\t\t\t\t{\n\t\t\t\t\t\tfprintf(vfp, \"action: [leave] from {%s}, stack: /\", table->name);\n\t\t\t\t\t\tdumpTstack(vfp, lcb->tstack);\n\t\t\t\t\t}\n\t\t\t\t\tEND_VERBOSE();\n\t\t\t\t\tif (ptrArrayCount (lcb->tstack) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\terror (WARNING, \"leave is specified as regex table action but the table stack is empty\");\n\t\t\t\t\t\treturn NULL;\n\t\t\t\t\t}\n\t\t\t\t\tnext = ptrArrayLast(lcb->tstack);\n\t\t\t\t\tptrArrayRemoveLast (lcb->tstack);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TACTION_JUMP:\n\t\t\t\t\tnext = taction->table;\n\t\t\t\t\tBEGIN_VERBOSE(vfp);\n\t\t\t\t\t{\n\t\t\t\t\t\tfprintf(vfp, \"action: [jump] from {%s} to {%s}, stack: /\", table->name, next->name);\n\t\t\t\t\t\tdumpTstack(vfp, lcb->tstack);\n\t\t\t\t\t}\n\t\t\t\t\tEND_VERBOSE();\n\n\t\t\t\t\tbreak;\n\t\t\t\tcase TACTION_RESET:\n\t\t\t\t\tnext = taction->table;\n\t\t\t\t\tBEGIN_VERBOSE(vfp);\n\t\t\t\t\t{\n\t\t\t\t\t\tfprintf(vfp, \"action: [reset] to {%s}, stack: /\", next->name);\n\t\t\t\t\t}\n\t\t\t\t\tEND_VERBOSE();\n\n\t\t\t\t\tptrArrayClear (lcb->tstack);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TACTION_QUIT:\n\t\t\t\t\tBEGIN_VERBOSE(vfp);\n\t\t\t\t\t{\n\t\t\t\t\t\tfprintf(vfp, \"action: [quit], stack: /\");\n\t\t\t\t\t\tdumpTstack(vfp, lcb->tstack);\n\t\t\t\t\t}\n\t\t\t\t\tEND_VERBOSE();\n\t\t\t\t\treturn NULL;\n\t\t\t\t}\n\n\t\t\t\tif (next)\n\t\t\t\t\tbreak;\n\n\t\t\t\tif (delta == 0)\n\t\t\t\t{\n\t\t\t\t\terror (WARNING, \"Forcefully advance the input pos because\");\n\t\t\t\t\terror (WARNING, \"following conditions for entering infinite loop are satisfied:\");\n\t\t\t\t\terror (WARNING, \"+ matching the pattern succeeds,\");\n\t\t\t\t\terror (WARNING, \"+ the next table is not given, and\");\n\t\t\t\t\terror (WARNING, \"+ the input file pos doesn't advance.\");\n\t\t\t\t\terror (WARNING, \"Language: %s, input file: %s, pos: %u\",\n\t\t\t\t\t\t   getLanguageName (lcb->owner), getInputFileName(), *offset);\n\t\t\t\t\t++*offset;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (ptrn->type == PTRN_CALLBACK)\n\t\t\t\t;\t/* Not implemented yet */\n\t\t\telse\n\t\t\t{\n\t\t\t\tAssert (\"invalid pattern type\" == NULL);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tgoto restart;\n\t\t}\n\t\telse\n\t\t\tentry->statistics.unmatch++;\n\t}\n out:\n\tif (next == NULL && ptrArrayCount (lcb->tstack) > 0)\n\t{\n\t\tstatic int apop_count = 0;\n\t\tnext = ptrArrayLast(lcb->tstack);\n\t\tverbose(\"result: no match - autopop<%d> from {%s} to {%s} @ %lu\\n\", apop_count++, table->name, next->name,\n\t\t\t\tgetInputLineNumberForFileOffset(*offset));\n\t\tptrArrayRemoveLast (lcb->tstack);\n\t}\n\treturn next;\n}\n\nextern void extendRegexTable (struct lregexControlBlock *lcb, const char *src, const char *dist)\n{\n\n\tint i;\n\tstruct regexTable * src_table;\n\tstruct regexTable * dist_table;\n\n\tverbose (\"extend regex table  \\\"%s\\\" with \\\"%s\\\"\\n\", dist, src);\n\n\ti = getTableIndexForName (lcb, src);\n\tif (i < 0)\n\t\terror (FATAL, \"no such regex table in %s: %s\", getLanguageName(lcb->owner), src);\n\tsrc_table = ptrArrayItem(lcb->tables, i);\n\n\ti = getTableIndexForName (lcb, dist);\n\tif (i < 0)\n\t\terror (FATAL, \"no such regex table in %s: %s\", getLanguageName(lcb->owner), dist);\n\tdist_table = ptrArrayItem(lcb->tables, i);\n\n\tfor (unsigned int n = 0; n < ptrArrayCount(src_table->entries); n++)\n\t{\n\t\tregexTableEntry *entry = ptrArrayItem (src_table->entries, n);\n\t\tptrArrayAdd(dist_table->entries, newRefPatternEntry(entry));\n\t}\n}\n\nextern void printMultitableStatistics (struct lregexControlBlock *lcb)\n{\n\tif (ptrArrayCount(lcb->tables) == 0)\n\t\treturn;\n\n\tfprintf(stderr, \"\\nMTABLE REGEX STATISTICS of %s\\n\", getLanguageName (lcb->owner));\n\tfputs(\"==============================================\\n\", stderr);\n\tfor (unsigned int i = 0; i < ptrArrayCount(lcb->tables); i++)\n\t{\n\t\tstruct regexTable *table = ptrArrayItem (lcb->tables, i);\n\t\tfprintf(stderr, \"%s\\n\", table->name);\n\t\tfputs(\"-----------------------\\n\", stderr);\n\t\tfor (unsigned int j = 0; j < ptrArrayCount(table->entries); j++)\n\t\t{\n\t\t\tregexTableEntry *entry = ptrArrayItem (table->entries, j);\n\t\t\tAssert (entry && entry->pattern);\n\t\t\tfprintf(stderr, \"%10u/%-10u%-40s ref: %d\\n\",\n\t\t\t\t\tentry->statistics.match,\n\t\t\t\t\tentry->statistics.unmatch + entry->statistics.match,\n\t\t\t\t\tentry->pattern->pattern_string,\n\t\t\t\t\tentry->pattern->refcount);\n\t\t}\n\t\tfputc('\\n', stderr);\n\t}\n}\n\nextern bool matchMultitableRegex (struct lregexControlBlock *lcb, const vString* const allLines)\n{\n\tif (ptrArrayCount (lcb->tables) == 0)\n\t\treturn false;\n\n\tstruct regexTable *table = ptrArrayItem (lcb->tables, 0);\n\tunsigned int offset = 0;\n\n\tint motionless_counter = 0;\n\tunsigned int last_offset;\n\n\n\twhile (table)\n\t{\n\t\tlast_offset = offset;\n\t\ttable = matchMultitableRegexTable(lcb, table, allLines, &offset);\n\n\t\tif (last_offset == offset)\n\t\t\tmotionless_counter++;\n\t\telse\n\t\t\tmotionless_counter = 0;\n\n\t\tif (motionless_counter > MTABLE_MOTIONLESS_MAX)\n\t\t{\n\t\t\terror (WARNING, \"mtable<%s/%s>: the input cursor stays at %u in %s so long though the tables are switched\",\n\t\t\t\t   getLanguageName (lcb->owner),\n\t\t\t\t   table->name, offset, getInputFileName ());\n\t\t\tbreak;\n\t\t}\n\n\t\tif (table && (ptrArrayCount (lcb->tstack) > MTABLE_STACK_MAX_DEPTH))\n\t\t{\n\t\t\tunsigned int i;\n\t\t\tstruct regexTable *t;\n\n\t\t\terror (WARNING, \"mtable<%s/%s>: the tenter/tleave stack overflows at %u in %s\",\n\t\t\t\t   getLanguageName (lcb->owner),\n\t\t\t\t   table->name, offset, getInputFileName ());\n\t\t\terror (WARNING, \"DUMP FROM THE TOP:\");\n\t\t\t/* TODO: use dumpTstack */\n\t\t\tfor (i = ptrArrayCount(lcb->tstack); 0 < i; --i)\n\t\t\t{\n\t\t\t\tt = ptrArrayItem (lcb->tstack, i - 1);\n\t\t\t\terror (WARNING, \"%3u %s\", i - 1, t->name);\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nstatic int  makePromiseForAreaSpecifiedWithOffsets (const char *parser,\n\t\t\t\t\t\t\t\t\t\t\t\t\toff_t startOffset,\n\t\t\t\t\t\t\t\t\t\t\t\t\toff_t endOffset)\n{\n\tunsigned long startLine = getInputLineNumberForFileOffset(startOffset);\n\tunsigned long endLine = getInputLineNumberForFileOffset(endOffset);\n\tunsigned long startLineOffset = getInputFileOffsetForLine (startLine);\n\tunsigned long endLineOffset = getInputFileOffsetForLine (endLine);\n\n\tAssert(startOffset >= startLineOffset);\n\tAssert(endOffset >= endLineOffset);\n\n\treturn makePromise (parser,\n\t\t\t\t\t\tstartLine, startOffset - startLineOffset,\n\t\t\t\t\t\tendLine, endOffset - endLineOffset,\n\t\t\t\t\t\tstartOffset - startLineOffset);\n}\n\nstatic struct guestRequest *guestRequestNew (void)\n{\n\tstruct guestRequest *r = xMalloc (1, struct guestRequest);\n\n\n\tguestRequestClear (r);\n\treturn r;\n}\n\nstatic void   guestRequestDelete (struct guestRequest *r)\n{\n\teFree (r);\n}\n\nstatic bool   guestRequestIsFilled(struct guestRequest *r)\n{\n\treturn (r->lang_set && (r->boundary + 0)->offset_set && (r->boundary + 1)->offset_set);\n}\n\nstatic void   guestRequestClear (struct guestRequest *r)\n{\n\tr->lang_set = false;\n\tr->boundary[GUEST_BOUNDARY_START].offset_set = false;\n\tr->boundary[GUEST_BOUNDARY_END].offset_set = false;\n}\n\nstatic void   guestRequestSubmit (struct guestRequest *r)\n{\n\tconst char *langName = getLanguageName (r->lang);\n\tverbose (\"guestRequestSubmit: %s; \"\n\t\t\t \"range: %\"PRId64\" - %\"PRId64\"\\n\",\n\t\t\t langName,\n\t\t\t (int64_t)r->boundary[GUEST_BOUNDARY_START].offset,\n\t\t\t (int64_t)r->boundary[GUEST_BOUNDARY_END].offset);\n\tmakePromiseForAreaSpecifiedWithOffsets (langName,\n\t\t\t\t\t\t\t\t\t\t\tr->boundary[GUEST_BOUNDARY_START].offset,\n\t\t\t\t\t\t\t\t\t\t\tr->boundary[GUEST_BOUNDARY_END].offset);\n}\n\n/*\n * Script related functions\n */\n\n/* This functions expects { code }} as input.\n * Be care that curly brackets must be unbalanced.\n */\nstatic EsObject *scriptRead (OptVM *vm, const char *src)\n{\n\tsize_t len = strlen (src);\n\tAssert (len > 2);\n\tAssert (src[len - 1] == '}');\n\tAssert (src[len - 2] == '}');\n\n\tEsObject *obj = optscriptRead (vm, src + 1, len - 1 - 1);\n\tif (es_error_p (obj))\n\t\terror (FATAL, \"failed in loading an optscript: %s\", src);\n\treturn obj;\n}\n\nextern EsObject* scriptEval (OptVM *vm, EsObject *optscript)\n{\n\treturn optscriptEval (vm, optscript);\n}\n\nstatic void scriptEvalHook (OptVM *vm, struct lregexControlBlock *lcb, enum scriptHook hook)\n{\n\tif (ptrArrayCount (lcb->hook_code[hook]) == 0)\n\t{\n\t\tfor (unsigned int i = 0; i < ptrArrayCount (lcb->hook[hook]); i++)\n\t\t{\n\t\t\tconst char *src = ptrArrayItem (lcb->hook[hook], i);\n\t\t\tEsObject *code = scriptRead (vm, src);\n\t\t\tif (es_error_p (code))\n\t\t\t\terror (FATAL, \"error when reading hook[%d] code: %s\", hook, src);\n\t\t\tptrArrayAdd (lcb->hook_code[hook], es_object_ref (code));\n\t\t\tes_object_unref (code);\n\t\t}\n\t}\n\tfor (unsigned int i = 0; i < ptrArrayCount (lcb->hook_code[hook]); i++)\n\t{\n\t\tEsObject *code = ptrArrayItem (lcb->hook_code[hook], i);\n\t\tEsObject * e = optscriptEval (vm, code);\n\t\tif (es_error_p (e))\n\t\t\terror (WARNING, \"error when evaluating hook[%d] code: %s\",\n\t\t\t\t   hook, (char *)ptrArrayItem (lcb->hook[hook], i));\n\t}\n}\n\nstatic void scriptSetup (OptVM *vm, struct lregexControlBlock *lcb, int corkIndex, scriptWindow *window)\n{\n\tset_current_lcb (vm, lcb);\n\tset_current_window (vm, window);\n\toptscriptSetup (vm, lcb->local_dict, corkIndex);\n}\n\nstatic void scriptTeardown (OptVM *vm, struct lregexControlBlock *lcb)\n{\n\toptscriptTeardown (vm, lcb->local_dict);\n\tset_current_lcb (vm, NULL);\n\tset_current_window (vm, NULL);\n}\n\nextern void\taddOptscriptToHook (struct lregexControlBlock *lcb, enum scriptHook hook, const char *code)\n{\n\tptrArrayAdd (lcb->hook[hook], eStrdup (code));\n}\n\nextern void propagateParamToOptscript (struct lregexControlBlock *lcb, const char *param, const char *value)\n{\n\tAssert (param);\n\tAssert (value);\n\thashTablePutItem (lcb->param_dict, eStrdup (param), eStrdup (value));\n}\n\n/* Return true if available. */\nextern bool checkRegex (void)\n{\n#if defined (CHECK_REGCOMP)\n\t{\n\t\t/* Check for broken regcomp() on Cygwin */\n\t\tregex_t patbuf;\n\t\tint errcode;\n\t\tif (regcomp (&patbuf, \"/hello/\", 0) != 0)\n\t\t\terror (WARNING, \"Disabling broken regex\");\n\t\telse\n\t\t\tregexAvailable = true;\n\t}\n#else\n\t/* We are using bundled regex engine. */\n\tregexAvailable = true;\n#endif\n\n\treturn regexAvailable;\n}\n\nstatic EsObject *OPTSCRIPT_ERR_UNKNOWNKIND;\nstatic EsObject *OPTSCRIPT_ERR_UNKNOWNROLE;\n\nstatic EsObject* lrop_make_foreignreftag (OptVM *vm, EsObject *name)\n{\n\tmatchLoc *loc;\n\n\tif (opt_vm_ostack_count (vm) < 1)\n\t\treturn OPT_ERR_UNDERFLOW;\n\n\tint index;\n\tEsObject *top = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (top) == OPT_TYPE_MATCHLOC)\n\t{\n\t\tif (opt_vm_ostack_count (vm) < 5)\n\t\t\treturn OPT_ERR_UNDERFLOW;\n\t\tloc = es_pointer_get (top);\n\t\tindex = 1;\n\t}\n\telse\n\t{\n\t\tscriptWindow *window = get_current_window(vm);\n\t\tif (window->patbuf->regptype != REG_PARSER_SINGLE_LINE)\n\t\t\treturn OPT_ERR_TYPECHECK;\n\t\tif (opt_vm_ostack_count (vm) < 4)\n\t\t\treturn OPT_ERR_UNDERFLOW;\n\t\tloc = NULL;\n\t\tindex = 0;\n\t}\n\n\tEsObject *role_obj = opt_vm_ostack_peek (vm, index++);\n\tif (es_nil != role_obj\n\t\t&& es_object_get_type (role_obj) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *kind_obj = opt_vm_ostack_peek (vm, index++);\n\tif (es_object_get_type (kind_obj) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *lang_obj = opt_vm_ostack_peek (vm, index++);\n\tlangType lang;\n\tif (es_nil == lang_obj)\n\t\tlang = getInputLanguage ();\n\telse if (es_object_get_type (lang_obj) == OPT_TYPE_NAME)\n\t{\n\t\tEsObject *lang_sym = es_pointer_get (lang_obj);\n\t\tconst char *lang_str = es_symbol_get (lang_sym);\n\t\tlang = getNamedLanguage (lang_str, 0);\n\t\tif (lang == LANG_IGNORE)\n\t\t\treturn OPTSCRIPT_ERR_UNKNOWNLANGUAGE;\n\t}\n\telse\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *kind_sym = es_pointer_get (kind_obj);\n\tconst char *kind_str = es_symbol_get (kind_sym);\n\tkindDefinition* kind_def = getLanguageKindForName (lang, kind_str);\n\tif (!kind_def)\n\t\treturn OPTSCRIPT_ERR_UNKNOWNKIND;\n\tint kind_index = kind_def->id;\n\n\tint role_index;\n\tif (es_nil == role_obj)\n\t\trole_index = ROLE_DEFINITION_INDEX;\n\telse\n\t{\n\t\tEsObject *role_sym = es_pointer_get (role_obj);\n\t\tconst char *role_str = es_symbol_get (role_sym);\n\t\troleDefinition* role_def = getLanguageRoleForName (lang, kind_index, role_str);\n\t\tif (!role_def)\n\t\t\treturn OPTSCRIPT_ERR_UNKNOWNROLE;\n\t\trole_index = role_def->id;\n\t}\n\n\tEsObject *tname = opt_vm_ostack_peek (vm, index++);\n\tif (es_object_get_type (tname) != OPT_TYPE_STRING)\n\t\treturn OPT_ERR_TYPECHECK;\n\tconst char *n = opt_string_get_cstr (tname);\n\tif (n [0] == '\\0')\n\t\treturn OPT_ERR_RANGECHECK; /* TODO */\n\n\ttagEntryInfo *e = xMalloc (1, tagEntryInfo);\n\tinitRegexTag (e, eStrdup (n),\n\t\t\t\t  kind_index, role_index, CORK_NIL, false,\n\t\t\t\t  loc? loc->line: 0, loc? &loc->pos: NULL,\n\t\t\t\t  role_index == ROLE_DEFINITION_INDEX\n\t\t\t\t  ? XTAG_UNKNOWN\n\t\t\t\t  : XTAG_REFERENCE_TAGS, lang);\n\tEsObject *obj = es_pointer_new (OPT_TYPE_TAG, e);\n\tif (es_error_p (obj))\n\t\treturn obj;\n\n\twhile (index-- > 0)\n\t\topt_vm_ostack_pop (vm);\n\n\topt_vm_ostack_push (vm, obj);\n\tes_object_unref (obj);\n\treturn es_false;\n}\n\nstatic EsObject* lrop_assign_role_common (OptVM *vm, EsObject *name, bool assign)\n{\n\tEsObject *tag = opt_vm_ostack_peek (vm, 1);\n\ttagEntryInfo *e;\n\tif (es_integer_p (tag))\n\t{\n\t\tint n0 = es_integer_get (tag);\n\t\tif (n0 < 0)\n\t\t\treturn OPT_ERR_RANGECHECK;\n\t\tunsigned int n = n0;\n\t\tif (! (CORK_NIL < n && n < countEntryInCorkQueue()))\n\t\t\treturn OPT_ERR_RANGECHECK;\n\t\te = getEntryInCorkQueue (n);\n\t}\n\telse if (es_object_get_type (tag) == OPT_TYPE_TAG)\n\t\te = es_pointer_get (tag);\n\telse\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tif (e == NULL)\n\t\treturn OPTSCRIPT_ERR_NOTAGENTRY;\n\n\tlangType lang = e->langType;\n\tint kind_index = e->kindIndex;\n\tEsObject *role = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (role) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\tEsObject *role_sym = es_pointer_get (role);\n\tconst char *role_str = es_symbol_get (role_sym);\n\troleDefinition* role_def = getLanguageRoleForName (lang, kind_index, role_str);\n\tif (!role_def)\n\t\treturn OPTSCRIPT_ERR_UNKNOWNROLE;\n\tint role_index = role_def->id;\n\n\t(assign? assignRole: unassignRole) (e, role_index);\n\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_pop (vm);\n\n\treturn es_false;\n}\n\nstatic EsObject* lrop_assign_role (OptVM *vm, EsObject *name)\n{\n\treturn lrop_assign_role_common (vm, name, true);\n}\n\nstatic EsObject* lrop_unassign_role (OptVM *vm, EsObject *name)\n{\n\treturn lrop_assign_role_common (vm, name, false);\n}\n\n/* tag COMMIT int */\nstatic EsObject* lrop_commit_tag (OptVM *vm, EsObject *name)\n{\n\tEsObject *tag = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (tag) != OPT_TYPE_TAG)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\ttagEntryInfo *e = es_pointer_get (tag);\n\tint corkIndex = makeTagEntry (e);\n\tEsObject *n = es_integer_new (corkIndex);\n\tif (es_error_p (n))\n\t\treturn n;\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_push (vm, n);\n\tes_object_unref (n);\n\treturn es_false;\n}\n\nstatic EsObject* lrop_get_match_loc (OptVM *vm, EsObject *name)\n{\n\n\tbool start;\n\tEsObject *group;\n\n\tif (opt_vm_ostack_count (vm) < 1)\n\t\treturn OPT_ERR_UNDERFLOW;\n\n\tEsObject *tmp = opt_vm_ostack_top (vm);\n\n\tif (es_object_get_type (tmp) == ES_TYPE_INTEGER)\n\t{\n\t\tgroup = tmp;\n\t\tstart = true;\n\t}\n\telse\n\t{\n\t\tEsObject *pos = tmp;\n\n\t\tstatic EsObject *start_name, *end_name;\n\t\tif (!start_name)\n\t\t{\n\t\t\tstart_name = opt_name_new_from_cstr (\"start\");\n\t\t\tend_name = opt_name_new_from_cstr (\"end\");\n\t\t}\n\n\t\tif (es_object_equal (pos, start_name))\n\t\t\tstart = true;\n\t\telse if (es_object_equal (pos, end_name))\n\t\t\tstart = false;\n\t\telse\n\t\t\treturn OPT_ERR_TYPECHECK;\n\n\t\tif (opt_vm_ostack_count (vm) < 2)\n\t\t\treturn OPT_ERR_UNDERFLOW;\n\n\t\tgroup = opt_vm_ostack_peek (vm, 1);\n\t\tif (es_object_get_type (group) != ES_TYPE_INTEGER)\n\t\t\treturn OPT_ERR_TYPECHECK;\n\t}\n\n\tint g = es_integer_get (group);\n\tif (g < 1)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tscriptWindow *window = get_current_window (vm);\n\n\tmatchLoc *mloc = make_mloc (window, g, start);\n\tif (mloc == NULL)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tEsObject * mlocobj = es_pointer_new (OPT_TYPE_MATCHLOC, mloc);\n\tif (es_error_p (mlocobj))\n\t{\n\t\teFree (mloc);\n\t\treturn mlocobj;\n\t}\n\n\tif (group != tmp)\n\t\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_push (vm, mlocobj);\n\tes_object_unref (mlocobj);\n\treturn es_false;\n}\n\nstatic EsObject* ldrop_get_line_from_matchloc (OptVM *vm, EsObject *name)\n{\n\tEsObject *mlocobj = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (mlocobj) != OPT_TYPE_MATCHLOC)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tmatchLoc *mloc = es_pointer_get (mlocobj);\n\tEsObject *lineobj = es_integer_new (mloc->line);\n\tif (es_error_p (lineobj))\n\t\treturn lineobj;\n\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_push (vm, lineobj);\n\tes_object_unref (lineobj);\n\treturn es_false;\n}\n\nstatic matchLoc* make_mloc_from_tagEntryInfo(tagEntryInfo *e)\n{\n\tmatchLoc *mloc = xMalloc (1, matchLoc);\n\tmloc->delta = 0;\n\tmloc->line = e->lineNumber;\n\tmloc->pos = e->filePosition;\n\n\treturn mloc;\n}\n\nstatic EsObject* lrop_get_tag_loc (OptVM *vm, EsObject *name)\n{\n\tEsObject *nobj = opt_vm_ostack_top (vm);\n\n\tif (es_object_get_type (nobj) != ES_TYPE_INTEGER)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n0 = es_integer_get(nobj);\n\tif (n0 < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\tunsigned int n = n0;\n\tif (! (CORK_NIL < n && n < countEntryInCorkQueue()))\n\t\t\treturn OPT_ERR_RANGECHECK;\n\n\ttagEntryInfo *e = getEntryInCorkQueue (n);\n\tif (e == NULL)\n\t\treturn OPT_ERR_TYPECHECK; /* ??? */\n\n\tmatchLoc *mloc = make_mloc_from_tagEntryInfo (e);\n\tEsObject * mlocobj = es_pointer_new (OPT_TYPE_MATCHLOC, mloc);\n\tif (es_error_p (mlocobj))\n\t{\n\t\teFree (mloc);\n\t\treturn mlocobj;\n\t}\n\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_push (vm, mlocobj);\n\tes_object_unref (mlocobj);\n\treturn es_false;\n}\n\nstatic EsObject* lrop_get_match_string_common (OptVM *vm, int i, int npop)\n{\n\tscriptWindow *window = get_current_window (vm);\n\tconst char *cstr = make_match_string (window, i);\n\tif (!cstr)\n\t{\n\t\tfor (; npop > 0; npop--)\n\t\t\topt_vm_ostack_pop (vm);\n\t\topt_vm_ostack_push (vm, es_false);\n\t\treturn es_false;\n\t}\n\tEsObject *str = opt_string_new_from_cstr (cstr);\n\teFree ((void *)cstr);\n\n\tfor (; npop > 0; npop--)\n\t\topt_vm_ostack_pop (vm);\n\n\topt_vm_ostack_push (vm, str);\n\tes_object_unref (str);\n\treturn es_false;\n}\n\n/* Handles \\1, \\2, ... */\nstatic EsObject* lrop_get_match_string_named_group (OptVM *vm, EsObject *name)\n{\n\tvoid * data = es_symbol_get_data (name);\n\tint i = HT_PTR_TO_INT (data);\n\n\treturn lrop_get_match_string_common (vm, i, 0);\n}\n\nstatic EsObject* lrop_get_match_string_group_on_stack (OptVM *vm, EsObject *name)\n{\n\tEsObject *group = opt_vm_ostack_top (vm);\n\tif (!es_integer_p (group))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint g = es_integer_get (group);\n\tif (g < 1)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tEsObject *r = lrop_get_match_string_common (vm, g, 1);\n\tif (es_error_p (r))\n\t\treturn r;\n\n\tr = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (r) == OPT_TYPE_STRING)\n\t\topt_vm_ostack_push (vm, es_true);\n\treturn es_false;\n}\n\nstatic char* make_match_string (scriptWindow *window, int group)\n{\n\tif (window == NULL\n\t\t|| 0 >= group\n\t\t|| window->nmatch <= group\n\t\t|| window->pmatch [group].rm_so == -1)\n\t\treturn NULL;\n\n\tconst int len = window->pmatch [group].rm_eo - window->pmatch [group].rm_so;\n\tconst char *start = window->line + window->pmatch [group].rm_so;\n\n\treturn eStrndup (start, len);\n}\n\nstatic matchLoc *make_mloc (scriptWindow *window, int group, bool start)\n{\n\tif (window == NULL\n\t\t|| 0 > group\n\t\t|| window->nmatch <= group\n\t\t|| window->pmatch [group].rm_so == -1)\n\t\treturn NULL;\n\n\tmatchLoc *mloc = xMalloc (1, matchLoc);\n\tif (window->patbuf->regptype == REG_PARSER_SINGLE_LINE)\n\t{\n\t\tmloc->base  = 0;\n\t\tmloc->delta = 0;\n\t\tmloc->line = getInputLineNumber ();\n\t\tmloc->pos = getInputFilePosition ();\n\t}\n\telse\n\t{\n\t\tmloc->base  = window->line - window->start;\n\t\tmloc->delta = (start\n\t\t\t\t\t   ? window->pmatch [group].rm_so\n\t\t\t\t\t   : window->pmatch [group].rm_eo);\n\t\tmloc->line = getInputLineNumberForFileOffset (mloc->base + mloc->delta);\n\t\tmloc->pos  = getInputFilePositionForLine (mloc->line);\n\t}\n\treturn mloc;\n}\n\nstatic EsObject* lrop_set_scope (OptVM *vm, EsObject *name)\n{\n\tEsObject *corkIndex = opt_vm_ostack_top (vm);\n\tif (!es_integer_p (corkIndex))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n0 = es_integer_get (corkIndex);\n\tif (n0 < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\tunsigned int n = n0;\n\tif (n >= countEntryInCorkQueue())\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tstruct lregexControlBlock *lcb = get_current_lcb (vm);\n\tlcb->currentScope = n0;\n\n\topt_vm_ostack_pop (vm);\n\n\treturn es_false;\n}\n\nstatic EsObject* lrop_pop_scope (OptVM *vm, EsObject *name)\n{\n\tstruct lregexControlBlock *lcb = get_current_lcb (vm);\n\tif (lcb->currentScope != CORK_NIL)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (lcb->currentScope);\n\t\tif (e)\n\t\t\tlcb->currentScope = e->extensionFields.scopeIndex;\n\t}\n\treturn es_false;\n}\n\nstatic EsObject* lrop_clear_scope (OptVM *vm, EsObject *name)\n{\n\tstruct lregexControlBlock *lcb = get_current_lcb (vm);\n\tlcb->currentScope = CORK_NIL;\n\treturn es_false;\n}\n\nstatic EsObject* lrop_ref0_scope (OptVM *vm, EsObject *name)\n{\n\tstruct lregexControlBlock *lcb = get_current_lcb (vm);\n\n\tif (lcb->currentScope == 0)\n\t{\n\t\topt_vm_ostack_push (vm, es_false);\n\t\treturn es_false;\n\t}\n\n\tEsObject *q = es_integer_new (lcb->currentScope);\n\n\tif (es_error_p (q))\n\t\treturn q;\n\n\topt_vm_ostack_push (vm, q);\n\tes_object_unref (q);\n\topt_vm_ostack_push (vm, es_true);\n\treturn es_false;\n}\n\nstatic EsObject* lrop_refN_scope (OptVM *vm, EsObject *name)\n{\n\tEsObject *nobj = opt_vm_ostack_top (vm);\n\tif (!es_integer_p (nobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n = es_integer_get(nobj);\n\n\tstruct lregexControlBlock *lcb = get_current_lcb (vm);\n\tint scope = lcb->currentScope;\n\n\twhile (n--)\n\t{\n\t\tif (scope == CORK_NIL)\n\t\t\tbreak;\n\t\ttagEntryInfo *e = getEntryInCorkQueue (scope);\n\t\tif (e == NULL)\n\t\t\tbreak;\n\n\t\tscope = e->extensionFields.scopeIndex;\n\t}\n\n\tEsObject *q = es_integer_new (scope);\n\tif (es_error_p(q))\n\t\treturn q;\n\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_push (vm, q);\n\tes_object_unref (q);\n\n\treturn es_false;\n}\n\nstatic EsObject* lrop_get_scope_depth (OptVM *vm, EsObject *name)\n{\n\tstruct lregexControlBlock *lcb = get_current_lcb (vm);\n\tint scope = lcb->currentScope;\n\tint depth = 0;\n\n\twhile (scope != CORK_NIL)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (scope);\n\t\tif (!e)\n\t\t\tbreak;\n\t\tdepth++;\n\t\tscope = e->extensionFields.scopeIndex;\n\t}\n\n\tEsObject *q = es_integer_new (depth);\n\tif (es_error_p(q))\n\t\treturn q;\n\n\topt_vm_ostack_push (vm, q);\n\tes_object_unref (q);\n\treturn es_false;\n}\n\nstatic EsObject* lrop_repl (OptVM *vm, EsObject *name)\n{\n\tchar *old_prompt = opt_vm_set_prompt (vm, \"\\n% type \\\"quit\\\" for exiting from repl\\nOPT\");\n\n\topt_vm_print_prompt (vm);\n\topt_vm_set_prompt (vm, \"OPT\");\n\n\twhile (true)\n\t{\n\t\tEsObject *o = opt_vm_read (vm, NULL);\n\t\tif (es_object_equal (o, ES_READER_EOF))\n\t\t{\n\t\t\tes_object_unref (o);\n\t\t\tbreak;\n\t\t}\n\t\tEsObject *e = opt_vm_eval (vm, o);\n\t\tes_object_unref (o);\n\n\t\tif (es_error_p (e))\n\t\t{\n\t\t\tif (!es_object_equal (e, OPT_ERR_QUIT))\n\t\t\t\topt_vm_report_error (vm, e, NULL);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\topt_vm_set_prompt (vm, old_prompt);\n\treturn es_false;\n}\n\nstatic EsObject *OPTSCRIPT_ERR_UNKNOWNTABLE;\nstatic EsObject *OPTSCRIPT_ERR_NOTMTABLEPTRN;\n\nstatic struct regexTable *getRegexTableForOptscriptName (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t EsObject *tableName)\n{\n\tEsObject *table_sym = es_pointer_get (tableName);\n\tconst char *table_str = es_symbol_get (table_sym);\n\tint n = getTableIndexForName (lcb, table_str);\n\tif (n < 0)\n\t\treturn NULL;\n\treturn ptrArrayItem (lcb->tables, n);\n}\n\nstatic EsObject* lrop_tenter_common (OptVM *vm, EsObject *name, enum tableAction action)\n{\n\tscriptWindow *window = get_current_window (vm);\n\tif (window->patbuf->regptype != REG_PARSER_MULTI_TABLE)\n\t{\n\t\terror (WARNING, \"Use table related operators only with mtable regular expression\");\n\t\treturn OPTSCRIPT_ERR_NOTMTABLEPTRN;\n\t}\n\n\tEsObject *table = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (table) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tstruct lregexControlBlock *lcb = get_current_lcb(vm);\n\tstruct regexTable *t = getRegexTableForOptscriptName (lcb, table);\n\tif (t == NULL)\n\t\treturn OPTSCRIPT_ERR_UNKNOWNTABLE;\n\n\twindow->taction = (struct mTableActionSpec){\n\t\t.action             = action,\n\t\t.table              = t,\n\t\t.continuation_table = NULL,\n\t};\n\n\topt_vm_ostack_pop (vm);\n\treturn es_false;\n}\n\nstatic EsObject* lrop_tenter (OptVM *vm, EsObject *name)\n{\n\treturn lrop_tenter_common (vm, name, TACTION_ENTER);\n}\n\nstatic EsObject* lrop_tenter_with_continuation (OptVM *vm, EsObject *name)\n{\n\tscriptWindow *window = get_current_window (vm);\n\tif (window->patbuf->regptype != REG_PARSER_MULTI_TABLE)\n\t{\n\t\terror (WARNING, \"Use table related operators only with mtable regular expression\");\n\t\treturn OPTSCRIPT_ERR_NOTMTABLEPTRN;\n\t}\n\n\tEsObject *cont = opt_vm_ostack_top (vm);\n\tEsObject *table = opt_vm_ostack_peek (vm, 1);\n\n\tif (es_object_get_type (table) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\tif (es_object_get_type (cont) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tstruct lregexControlBlock *lcb = get_current_lcb (vm);\n\tstruct regexTable *t = getRegexTableForOptscriptName (lcb, table);\n\tif (t == NULL)\n\t\treturn OPTSCRIPT_ERR_UNKNOWNTABLE;\n\tstruct regexTable *c = getRegexTableForOptscriptName (lcb, cont);\n\tif (c == NULL)\n\t\treturn OPTSCRIPT_ERR_UNKNOWNTABLE;\n\n\twindow->taction = (struct mTableActionSpec){\n\t\t.action             = TACTION_ENTER,\n\t\t.table              = t,\n\t\t.continuation_table = c,\n\t};\n\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_pop (vm);\n\treturn es_false;\n}\n\nstatic EsObject* lrop_tleave (OptVM *vm, EsObject *name)\n{\n\tscriptWindow *window = get_current_window (vm);\n\tif (window->patbuf->regptype != REG_PARSER_MULTI_TABLE)\n\t{\n\t\terror (WARNING, \"Use table related operators only with mtable regular expression\");\n\t\treturn OPTSCRIPT_ERR_NOTMTABLEPTRN;\n\t}\n\n\twindow->taction.action = TACTION_LEAVE;\n\treturn es_false;\n}\n\nstatic EsObject* lrop_tjump (OptVM *vm, EsObject *name)\n{\n\treturn lrop_tenter_common (vm, name, TACTION_JUMP);\n}\n\nstatic EsObject* lrop_treset (OptVM *vm, EsObject *name)\n{\n\treturn lrop_tenter_common (vm, name, TACTION_RESET);\n}\n\nstatic EsObject* lrop_tquit (OptVM *vm, EsObject *name)\n{\n\tscriptWindow *window = get_current_window (vm);\n\tif (window->patbuf->regptype != REG_PARSER_MULTI_TABLE)\n\t{\n\t\terror (WARNING, \"Use table related operators only with mtable regular expression\");\n\t\treturn OPTSCRIPT_ERR_NOTMTABLEPTRN;\n\t}\n\n\twindow->taction.action = TACTION_QUIT;\n\treturn es_false;\n}\n\nstatic EsObject* lrop_traced (OptVM *vm, EsObject *name)\n{\n#ifdef DO_TRACING\n\tlangType lang = getInputLanguage ();\n\tif (isLanguageTraced (lang))\n\t\topt_vm_ostack_push (vm, es_true);\n\telse\n\t\topt_vm_ostack_push (vm, es_false);\n#else\n\topt_vm_ostack_push (vm, es_false);\n#endif\n\treturn false;\n}\n\nEsObject *OPTSCRIPT_ERR_UNKNOWNEXTRA;\nstatic EsObject* lrop_extraenabled (OptVM *vm, EsObject *name)\n{\n\tEsObject *extra = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (extra) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\txtagType xt = optscriptGetXtagType (extra);\n\tif (xt == XTAG_UNKNOWN)\n\t\treturn OPTSCRIPT_ERR_UNKNOWNEXTRA;\n\n\tEsObject *r = isXtagEnabled (xt)? es_true: es_false;\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_push (vm, r);\n\treturn es_false;\n}\n\nstatic EsObject *lrop_markextra (OptVM *vm, EsObject *name)\n{\n\tEsObject *tag = opt_vm_ostack_peek (vm, 1);\n\ttagEntryInfo *e;\n\tif (es_integer_p (tag))\n\t{\n\t\tint n0 = es_integer_get (tag);\n\t\tif (n0 < 0)\n\t\t\treturn OPT_ERR_RANGECHECK;\n\t\tunsigned int n = n0;\n\t\tif (! (CORK_NIL < n && n < countEntryInCorkQueue()))\n\t\t\treturn OPT_ERR_RANGECHECK;\n\t\te = getEntryInCorkQueue (n0);\n\t}\n\telse if (es_object_get_type (tag) == OPT_TYPE_TAG)\n\t\te = es_pointer_get (tag);\n\telse\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tif (e == NULL)\n\t\treturn OPTSCRIPT_ERR_NOTAGENTRY;\n\n\tEsObject *extra = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (extra) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\txtagType xt = optscriptGetXtagType (extra);\n\tif (xt == XTAG_UNKNOWN)\n\t\treturn OPTSCRIPT_ERR_UNKNOWNEXTRA;\n\n\tlangType lang = getXtagLanguage (xt);\n\tif (lang != LANG_IGNORE && e->langType != lang)\n\t{\n\t\terror (WARNING,\n\t\t\t   \"mismatch in the language of the tag (%s) and the language of field (%s)\",\n\t\t\t   getLanguageName (e->langType), getLanguageName (lang));\n\t\treturn OPTSCRIPT_ERR_UNKNOWNEXTRA;\n\t}\n\n\tmarkTagExtraBit (e, xt);\n\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_pop (vm);\n\n\treturn es_false;\n}\n\nstatic EsObject *lrop_advanceto (OptVM *vm, EsObject *name)\n{\n\tscriptWindow *window = get_current_window (vm);\n\tif (window->patbuf->regptype == REG_PARSER_SINGLE_LINE)\n\t{\n\t\terror (WARNING, \"don't use `%s' operator in --regex-<LANG> option\",\n\t\t\t   es_symbol_get (name));\n\t\treturn OPTSCRIPT_ERR_NOTMTABLEPTRN; /* TODO */\n\t}\n\n\tEsObject *mlocobj = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (mlocobj) != OPT_TYPE_MATCHLOC)\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tmatchLoc *loc = es_pointer_get (mlocobj);\n\twindow->advanceto = true;\n\twindow->advanceto_delta = loc->delta;\n\n\treturn es_true;\n}\n\nstatic EsObject *lrop_markplaceholder (OptVM *vm, EsObject *name)\n{\n\tEsObject *tag = opt_vm_ostack_top (vm);\n\n\tif (!es_integer_p (tag))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n0 = es_integer_get (tag);\n\tif (n0 < 0)\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tunsigned int n = n0;\n\tif (! (CORK_NIL < n && n < countEntryInCorkQueue()))\n\t\treturn OPT_ERR_RANGECHECK;\n\n\ttagEntryInfo *e = getEntryInCorkQueue (n0);\n\tif (e == NULL)\n\t\treturn OPTSCRIPT_ERR_NOTAGENTRY;\n\n\tmarkTagAsPlaceholder (e, true);\n\n\topt_vm_ostack_pop (vm);\n\treturn es_false;\n}\n\nstatic EsObject *lrop_makepromise (OptVM *vm, EsObject *name)\n{\n\tscriptWindow *window = get_current_window (vm);\n\tif (window->patbuf->regptype == REG_PARSER_SINGLE_LINE)\n\t{\n\t\terror (WARNING, \"don't use `%s' operator in --regex-<LANG> option\",\n\t\t\t   es_symbol_get (name));\n\t\treturn OPTSCRIPT_ERR_NOTMTABLEPTRN; /* TODO */\n\t}\n\n\tEsObject *endobj = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (endobj) != OPT_TYPE_MATCHLOC)\n\t\treturn OPT_ERR_TYPECHECK;\n\tmatchLoc *end = es_pointer_get (endobj);\n\toff_t end_off = (off_t)(end->base + end->delta);\n\n\tEsObject *startobj = opt_vm_ostack_peek (vm, 1);\n\tif (es_object_get_type (startobj) != OPT_TYPE_MATCHLOC)\n\t\treturn OPT_ERR_TYPECHECK;\n\tmatchLoc *start = es_pointer_get (startobj);\n\toff_t start_off = (off_t)(start->base + start->delta);\n\n\tif (! (start_off < end_off))\n\t\treturn OPT_ERR_RANGECHECK;\n\n\tEsObject *lang = opt_vm_ostack_peek (vm, 2);\n\tconst char *langc = opt_string_get_cstr (lang);\n\tlangType t = getNamedLanguageOrAlias (langc, 0);\n\tif (t == LANG_IGNORE)\n\t\treturn OPTSCRIPT_ERR_UNKNOWNLANGUAGE;\n\n\tif (start_off == end_off)\n\t{\n\t\topt_vm_ostack_pop (vm);\n\t\topt_vm_ostack_pop (vm);\n\t\topt_vm_ostack_pop (vm);\n\t\topt_vm_ostack_push (vm, es_false);\n\t\treturn es_false;\n\t}\n\n\tint promise = makePromiseForAreaSpecifiedWithOffsets (langc,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  start_off,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  end_off);\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_pop (vm);\n\n\tif (promise >= 0)\n\t{\n\t\tEsObject *promise_obj = es_integer_new (promise);\n\t\topt_vm_ostack_push (vm, promise_obj);\n\t\topt_vm_ostack_push (vm, es_true);\n\t\tes_object_unref(promise_obj);\n\t}\n\telse\n\t\topt_vm_ostack_push (vm, es_false);\n\n\treturn es_false;\n}\n\nstatic EsObject *lrop_param (OptVM *vm, EsObject *name)\n{\n\tstruct lregexControlBlock *lcb = get_current_lcb (vm);\n\tEsObject *key = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (key) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\tEsObject *key_sym = es_pointer_get (key);\n\tconst char *keyc = es_symbol_get (key_sym);\n\tconst char *valuec = hashTableGetItem (lcb->param_dict, keyc);\n\n\tif (valuec)\n\t{\n\t\topt_vm_ostack_pop (vm);\n\t\tEsObject *value = opt_string_new_from_cstr (valuec);\n\t\topt_vm_ostack_push (vm, value);\n\t\tes_object_unref (value);\n\t\topt_vm_ostack_push (vm, es_true);\n\t}\n\telse\n\t{\n\t\topt_vm_ostack_pop (vm);\n\t\topt_vm_ostack_push (vm, es_false);\n\t}\n\treturn false;\n}\n\nstatic EsObject *lrop_intervaltab (OptVM *vm, EsObject *name)\n{\n\tEsObject *nobj = opt_vm_ostack_top (vm);\n\tint parent;\n\n\tif (es_object_get_type (nobj) == ES_TYPE_INTEGER)\n\t{\n\t\tint index = es_integer_get(nobj);\n\t\tif (index < 0 || index == CORK_NIL)\n\t\t\treturn OPT_ERR_RANGECHECK;\n\t\tparent = queryIntervalTabByCorkEntry (index);\n\t}\n\telse if (es_object_get_type (nobj) == OPT_TYPE_TAG)\n\t{\n\t\ttagEntryInfo *e = es_pointer_get (nobj);\n\t\tif (getTagEndLine (e) == 0)\n\t\t\tparent = queryIntervalTabByLine(e->lineNumber);\n\t\telse\n\t\t\tparent = queryIntervalTabByRange(e->lineNumber,\n\t\t\t\t\t\t\t\t\t\t\t getTagEndLine(e));\n\t}\n\telse if (es_object_get_type (nobj) == OPT_TYPE_MATCHLOC)\n\t{\n\t\tmatchLoc *mloc = es_pointer_get (nobj);\n\t\tparent = queryIntervalTabByLine(mloc->line);\n\t}\n\telse if (es_object_get_type (nobj) == OPT_TYPE_ARRAY)\n\t{\n\t\tunsigned long start, end;\n\n\t\tif (opt_array_length(nobj) == 0)\n\t\t\treturn OPT_ERR_RANGECHECK;\n\n\t\tptrArray *a = es_pointer_get (nobj);\n\t\tEsObject *nobj0 = ptrArrayItem (a, 0);\n\t\tif (es_object_get_type (nobj0) != ES_TYPE_INTEGER)\n\t\t\treturn OPT_ERR_TYPECHECK;\n\t\tint n = es_integer_get (nobj0);\n\t\tif (n <= 0)\n\t\t\treturn OPT_ERR_RANGECHECK;\n\n\t\tstart = (unsigned long)n;\n\t\tif (ptrArrayCount(a) == 1)\n\t\t\tparent = queryIntervalTabByLine (start);\n\t\telse\n\t\t{\n\t\t\tnobj0 = ptrArrayItem (a, 1);\n\t\t\tif (es_object_get_type (nobj0) != ES_TYPE_INTEGER)\n\t\t\t\treturn OPT_ERR_TYPECHECK;\n\t\t\tint n = es_integer_get (nobj0);\n\t\t\tif (n <= 0)\n\t\t\t\treturn OPT_ERR_RANGECHECK;\n\n\t\t\tend = (unsigned long)n;\n\t\t\tif (end < start)\n\t\t\t\treturn OPT_ERR_RANGECHECK;\n\t\t\tparent = queryIntervalTabByRange (start, end);\n\t\t}\n\t}\n\telse\n\t\treturn OPT_ERR_TYPECHECK;\n\n\topt_vm_ostack_pop (vm);\n\tif (parent == CORK_NIL)\n\t\topt_vm_ostack_push (vm, es_false);\n\telse\n\t{\n\t\tEsObject *parent_obj = es_integer_new (parent);\n\t\topt_vm_ostack_push (vm, parent_obj);\n\t\topt_vm_ostack_push (vm, es_true);\n\t\tes_object_unref (parent_obj);\n\t}\n\treturn false;\n}\n\nstatic EsObject *lrop_anongen (OptVM *vm, EsObject *name)\n{\n\tint n_pop = 2;\n\n\tif (opt_vm_ostack_count (vm) < 2)\n\t\treturn OPT_ERR_UNDERFLOW;\n\n\tEsObject *kind_obj = opt_vm_ostack_top (vm);\n\tif (es_object_get_type (kind_obj) != OPT_TYPE_NAME)\n\t\treturn OPT_ERR_TYPECHECK;\n\tEsObject *kind_sym = es_pointer_get (kind_obj);\n\tconst char *kind_str = es_symbol_get (kind_sym);\n\n\tEsObject *tmp_obj = opt_vm_ostack_peek (vm, 1);\n\tlangType lang = LANG_IGNORE;\n\tEsObject *prefix_obj = es_nil;\n\tif (es_object_get_type (tmp_obj) == OPT_TYPE_NAME)\n\t{\n\t\tEsObject *lang_sym = es_pointer_get (tmp_obj);\n\t\tconst char *lang_str = es_symbol_get (lang_sym);\n\t\tlang = getNamedLanguageOrAlias (lang_str, 0);\n\t\tif (lang == LANG_IGNORE)\n\t\t\treturn OPTSCRIPT_ERR_UNKNOWNLANGUAGE;\n\t}\n\telse\n\t{\n\t\tlang = getInputLanguage ();\n\t\tprefix_obj = tmp_obj;\n\t}\n\tAssert(lang != LANG_IGNORE);\n\tAssert(lang != LANG_AUTO);\n\n\tkindDefinition* kind_def = getLanguageKindForName (lang, kind_str);\n\tif (!kind_def)\n\t\treturn OPTSCRIPT_ERR_UNKNOWNKIND;\n\tint kind_index = kind_def->id;\n\n\tif (es_null(prefix_obj))\n\t{\n\t\tn_pop++;\n\t\tif (opt_vm_ostack_count (vm) < 3)\n\t\t\treturn OPT_ERR_UNDERFLOW;\n\t\tprefix_obj = opt_vm_ostack_peek (vm, 2);\n\t}\n\tif (es_object_get_type (prefix_obj) != OPT_TYPE_STRING)\n\t\treturn OPT_ERR_TYPECHECK;\n\tconst char *prefix = opt_string_get_cstr (prefix_obj);\n\n\tvString *anon_vstr = anonGenerateNewFull (prefix, lang, kind_index);\n\tEsObject *anon_obj = opt_string_new_from_cstr (vStringValue(anon_vstr));\n\tvStringDelete(anon_vstr);\n\n\tfor (; n_pop > 0; n_pop--)\n\t\topt_vm_ostack_pop (vm);\n\n\topt_vm_ostack_push (vm, anon_obj);\n\tes_object_unref (anon_obj);\n\treturn es_false;\n}\n\nstatic struct optscriptOperatorRegistration lropOperators [] = {\n\t{\n\t\t.name     = \"_matchstr\",\n\t\t.fn       = lrop_get_match_string_group_on_stack,\n\t\t.arity    = 1,\n\t\t.help_str = \"group:int _MATCHSTR string true%\"\n\t\t\"group:int _MATCHSTR false\",\n\t},\n\t{\n\t\t.name     = \"_matchloc\",\n\t\t.fn       = lrop_get_match_loc,\n\t\t.arity    = -1,\n\t\t.help_str = \"group:int /start|/end _MATCHLOC matchloc%\"\n\t\t\"group:int _MATCHLOC matchloc\",\n\t},\n\t{\n\t\t.name     = \"_matchloc2line\",\n\t\t.fn       = ldrop_get_line_from_matchloc,\n\t\t.arity    = 1,\n\t\t.help_str = \"matchloc _MATCHLOC2LINE int:line\",\n\t},\n\t{\n\t\t.name     = \"_tagloc\",\n\t\t.fn       = lrop_get_tag_loc,\n\t\t.arity    = 1,\n\t\t.help_str = \"index:int _TAGLOC matchloc\",\n\t},\n\t{\n\t\t.name     = \"_foreignreftag\",\n\t\t.fn       = lrop_make_foreignreftag,\n\t\t.arity    = -1,\n\t\t.help_str = \"name:str lang:name kind:name role:name|null matchloc _FOREIGNREFTAG tag%\"\n\t\t\"name:str lang:name|null kind:name role:name|null _FOREIGNREFTAG tag%\",\n\t},\n\t{\n\t\t.name     = \"_commit\",\n\t\t.fn       = lrop_commit_tag,\n\t\t.arity    = 1,\n\t\t.help_str = \"tag _COMMIT int\",\n\t},\n\t{\n\t\t.name     = \"_scopeset\",\n\t\t.fn       = lrop_set_scope,\n\t\t.arity    = 1,\n\t\t.help_str = \"int _SCOPESET -\",\n\t},\n\t{\n\t\t.name     = \"_scopepop\",\n\t\t.fn       = lrop_pop_scope,\n\t\t.arity    = 0,\n\t\t.help_str = \"- _SCOPEPOP -\",\n\t},\n\t{\n\t\t.name     = \"_scopeclear\",\n\t\t.fn       = lrop_clear_scope,\n\t\t.arity    = 0,\n\t\t.help_str = \"- _SCOPECLEAR -\",\n\t},\n\t{\n\t\t.name     = \"_scopetop\",\n\t\t.fn       = lrop_ref0_scope,\n\t\t.arity    = 0,\n\t\t.help_str = \"- _SCOPETOP int true%\"\n\t\t\"- _SCOPETOP false\",\n\t},\n\t{\n\t\t.name     = \"_scopeNth\",\n\t\t.fn       = lrop_refN_scope,\n\t\t.arity    = 1,\n\t\t.help_str = \"index:int _SCOPENTH int\",\n\t},\n\t{\n\t\t.name     = \"_scopedepth\",\n\t\t.fn       = lrop_get_scope_depth,\n\t\t.arity    = 0,\n\t\t.help_str = \"- _SCOPEDEPTH int\",\n\t},\n\t{\n\t\t.name     = \"_repl\",\n\t\t.fn       = lrop_repl,\n\t\t.arity    = 0,\n\t\t.help_str = \"- _repl -\",\n\t},\n\t{\n\t\t.name     = \"_tenter\",\n\t\t.fn       = lrop_tenter,\n\t\t.arity    = 1,\n\t\t.help_str = \"table:name _TENTER -\",\n\t},\n\t{\n\t\t.name     = \"_tentercont\",\n\t\t.fn       = lrop_tenter_with_continuation,\n\t\t.arity    = 2,\n\t\t.help_str = \"table:name cont:name _TENTERCONT -\",\n\t},\n\t{\n\t\t.name     = \"_tleave\",\n\t\t.fn       = lrop_tleave,\n\t\t.arity    = 0,\n\t\t.help_str = \"- _TLEAVE -\",\n\t},\n\t{\n\t\t.name     = \"_tjump\",\n\t\t.fn       = lrop_tjump,\n\t\t.arity    = 1,\n\t\t.help_str = \"table:name _TJUMP -\",\n\t},\n\t{\n\t\t.name     = \"_treset\",\n\t\t.fn       = lrop_treset,\n\t\t.arity    = 1,\n\t\t.help_str = \"table:name _TRESET -\",\n\t},\n\t{\n\t\t.name     = \"_tquit\",\n\t\t.fn       = lrop_tquit,\n\t\t.arity    = 0,\n\t\t.help_str = \"- _TQUIT -\",\n\t},\n\t{\n\t\t.name     = \"_extraenabled\",\n\t\t.fn       = lrop_extraenabled,\n\t\t.arity    = 1,\n\t\t.help_str = \"extra:name _extraenabled bool%\"\n\t\t\"lang.extra:name _extraenabled bool\",\n\t},\n\t{\n\t\t.name     = \"_markextra\",\n\t\t.fn       = lrop_markextra,\n\t\t.arity    = 2,\n\t\t.help_str = \"tag:int|tag:tag extra:name _MARKEXTRA -%\"\n\t\t\"tag:int|tag:tag lang.extra:name _MARKEXTRA -\",\n\t},\n\t{\n\t\t.name     = \"_advanceto\",\n\t\t.fn       = lrop_advanceto,\n\t\t.arity    = 1,\n\t\t.help_str = \"matchloc _ADVANCETO -%\"\n\t},\n\t{\n\t\t.name     = \"_traced\",\n\t\t.fn       = lrop_traced,\n\t\t.arity    = 0,\n\t\t.help_str = \"- _TRACED true|false\",\n\t},\n\t{\n\t\t.name     = \"_markplaceholder\",\n\t\t.fn       = lrop_markplaceholder,\n\t\t.arity    = 1,\n\t\t.help_str = \"tag:int _MARKPLACEHOLDER -\",\n\t},\n\t{\n\t\t.name     = \"_makepromise\",\n\t\t.fn       = lrop_makepromise,\n\t\t.arity    = 3,\n\t\t.help_str = \"lang:string start:matchloc end:matchloc _MAKEPROMISE promise:int true%\"\n\t\t\"lang:string start:matchloc end:matchloc _MAKEPROMISE false\",\n\t},\n\t{\n\t\t.name     = \"_param\",\n\t\t.fn       = lrop_param,\n\t\t.arity    = 1,\n\t\t.help_str = \"param:name _PARAM value:string true%\"\n\t\t\"param:name _PARAM false\",\n\t},\n\t{\n\t\t.name     = \"_assignrole\",\n\t\t.fn       = lrop_assign_role,\n\t\t.arity    = 2,\n\t\t.help_str = \"tag:int|tag:tag role:name _ASSIGNROLE -\",\n\t},\n\t{\n\t\t.name     = \"_unassignrole\",\n\t\t.fn       = lrop_unassign_role,\n\t\t.arity    = 2,\n\t\t.help_str = \"tag:int|tag:tag role:name _UNASSIGNROLE -\",\n\t},\n\t{\n\t\t.name     = \"_intervaltab\",\n\t\t.fn       = lrop_intervaltab,\n\t\t.arity    = 1,\n\t\t.help_str = \"tag:int|tag:tag|matchloc|[line:int]|[startline:int endline:int] _INTERVALTAB parent:int true%\"\n\t\t\"tag:int|tag:tag|matchloc|[startline:int endline:int] _INTERVALTAB false\",\n\t},\n\t{\n\t\t.name     = \"_anongen\",\n\t\t.fn       = lrop_anongen,\n\t\t.arity    = -1,\n\t\t.help_str = \"prefix:string kind:name _ANONGEN anon:string%\"\n\t\t\"prefix:string lang:name kind:name _ANONGEN anon:string%\",\n\t},\n};\n\nextern bool installOptscriptFieldAccessor (fieldType ftype)\n{\n\t/* This function is called via defineField().\n\t   defineField() is called via --fielddef option of built-in parsers\n\t   defining their specific fields.\n\t   built-in parsers are initialized lazily in the current implementation.\n\t   optvm is initialized earlier than parsers. */\n\tAssert (!es_null(lregex_dict));\n\n\toptscriptInstallFieldAccessor (lregex_dict, ftype);\n\treturn true;\n}\n\nextern void initRegexOptscript (void)\n{\n\tif (!regexAvailable)\n\t\treturn;\n\n\tif (optvm)\n\t\treturn;\n\n\toptvm = optscriptInit ();\n\tappData *d = xCalloc (1, appData);\n\topt_vm_set_app_data (optvm, d);\n\tlregex_dict = opt_dict_new (17);\n\n\tOPTSCRIPT_ERR_UNKNOWNTABLE = es_error_intern (\"unknowntable\");\n\tOPTSCRIPT_ERR_NOTMTABLEPTRN = es_error_intern (\"notmtableptrn\");\n\tOPTSCRIPT_ERR_UNKNOWNEXTRA = es_error_intern (\"unknownextra\");\n\tOPTSCRIPT_ERR_UNKNOWNLANGUAGE = es_error_intern (\"unknownlanguage\");\n\tOPTSCRIPT_ERR_UNKNOWNKIND = es_error_intern (\"unknownkind\");\n\tOPTSCRIPT_ERR_UNKNOWNROLE = es_error_intern (\"unknownrole\");\n\tOPTSCRIPT_ERR_FIELDRESET = es_error_intern (\"fieldreset\");\n\n\toptscriptInstallProcs (lregex_dict, lrop_get_match_string_named_group);\n\n\toptscriptRegisterOperators (lregex_dict,\n\t\t\t\t\t\t\t\tlropOperators, ARRAY_SIZE(lropOperators));\n\n\textern const char ctagsCommonPrelude[];\n\topt_vm_dstack_push (optvm, lregex_dict);\n\tMIO *mio = mio_new_memory ((unsigned char*)ctagsCommonPrelude, strlen (ctagsCommonPrelude), NULL, NULL);\n\tEsObject *e = optscriptLoad (optvm, mio);\n\tif (es_error_p (e))\n\t\terror (FATAL, \"failed in loading built-in procedures\");\n\tmio_unref (mio);\n\topt_vm_dstack_pop (optvm);\n}\n\nextern void\tlistRegexOpscriptOperators (FILE *fp)\n{\n\tEsObject *procdocs;\n\tif (!opt_dict_known_and_get_cstr (lregex_dict,\n\t\t\t\t\t\t\t\t\t  \"__procdocs\",\n\t\t\t\t\t\t\t\t\t  &procdocs))\n\t\tprocdocs = NULL;\n\n\topt_vm_dstack_push (optvm, lregex_dict);\n\toptscriptHelp (optvm, fp, procdocs);\n\topt_vm_dstack_pop (optvm);\n}\n"
  },
  {
    "path": "main/lregex.h",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*   Copyright (c) 2017, Red Hat, Inc.\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for applying regular expression matching.\n*\n*   The code for utilizing the Gnu regex package with regards to processing the\n*   regex option and checking for regex matches was adapted from routines in\n*   Gnu etags.\n*/\n\n#ifndef CTAGS_MAIN_LREGEX_H\n#define CTAGS_MAIN_LREGEX_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef struct sTagRegexTable {\n\tconst char *const regex;\n\tconst char* const name;\n\tconst char* const kinds;\n\tconst char *const flags;\n\tbool    *disabled;\n\tbool  mline;\n} tagRegexTable;\n\ntypedef struct {\n\tsize_t start;   /* character index in line where match starts */\n\tsize_t length;  /* length of match */\n} regexMatch;\n\n/* Return value is referred when {exclusive} is also specified.\n   The input line is consumed when \"{exclusive}\" is specified and\n   the value returned from the callback function is true. */\ntypedef bool (*regexCallback) (const char *line, const regexMatch *matches, unsigned int count,\n\t\t\t       void *userData);\n\n#endif\t/* CTAGS_MAIN_LREGEX_H */\n"
  },
  {
    "path": "main/lregex_p.h",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*   Copyright (c) 2017, Red Hat, Inc.\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for applying regular expression matching.\n*\n*   The code for utilizing the Gnu regex package with regards to processing the\n*   regex option and checking for regex matches was adapted from routines in\n*   Gnu etags.\n*/\n#ifndef CTAGS_MAIN_LREGEX_PRIVATE_H\n#define CTAGS_MAIN_LREGEX_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n#include \"field.h\"\n#include \"flags_p.h\"\n#include \"kind_p.h\"\n#include \"lregex.h\"\n#include \"parse.h\"\n\n#include <regex.h>\n\n/*\n*   MACRO DEFINITIONS\n*/\n/* Back-references \\0 through \\9 */\n#define BACK_REFERENCE_COUNT 10\n\n/*\n*   DATA DECLARATIONS\n*/\nenum regexParserType {\n\tREG_PARSER_SINGLE_LINE,\n\tREG_PARSER_MULTI_LINE,\n\tREG_PARSER_MULTI_TABLE,\n};\n\nstruct lregexControlBlock;\n\ntypedef struct sRegexCompiledCode {\n\tstruct regexBackend *backend;\n\tvoid * code;\n} regexCompiledCode;\n\nstruct regexBackend {\n\tconst char *name;\n\tflagDefinition *fdefs;\n\tunsigned int fdef_count;\n\n\tvoid              (* set_icase_flag) (int *);\n\tregexCompiledCode (* compile)     (struct regexBackend *,\n\t\t\t\t\t\t\t\t\t   const char* const,\n\t\t\t\t\t\t\t\t\t   int);\n\tint               (* match)       (struct regexBackend *,\n\t\t\t\t\t\t\t\t\t   void *, const char *, size_t,\n\t\t\t\t\t\t\t\t\t   regmatch_t[BACK_REFERENCE_COUNT]);\n\tvoid              (* delete_code) (void *);\n};\n\nstruct flagDefsDescriptor {\n\tstruct regexBackend *backend;\n\tint flags;\n\tenum regexParserType regptype;\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern struct lregexControlBlock* allocLregexControlBlock (parserDefinition *parser);\nextern void freeLregexControlBlock (struct lregexControlBlock* lcb);\n\nextern void processTagRegexOption (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t\t   enum regexParserType,\n\t\t\t\t\t\t\t\t   const char* const parameter);\nextern void addTagRegex (struct lregexControlBlock *lcb, const char* const regex,\n\t\t\t\t\t\t const char* const name, const char* const kinds, const char* const flags,\n\t\t\t\t\t\t bool *disabled);\nextern void addTagMultiLineRegex (struct lregexControlBlock *lcb, const char* const regex,\n\t\t\t\t\t\t\t\t  const char* const name, const char* const kinds, const char* const flags,\n\t\t\t\t\t\t\t\t  bool *disabled);\nextern void addTagMultiTableRegex(struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t\t  const char* const table_name,\n\t\t\t\t\t\t\t\t  const char* const regex,\n\t\t\t\t\t\t\t\t  const char* const name, const char* const kinds, const char* const flags,\n\t\t\t\t\t\t\t\t  bool *disabled);\n\nextern bool lregexControlBlockHasAny(struct lregexControlBlock *lcb);\n\nextern bool matchRegex (struct lregexControlBlock *lcb, const vString* const line, bool postrun);\nextern bool regexIsPostRun (struct lregexControlBlock *lcb);\n\nextern bool doesExpectCorkInRegex (struct lregexControlBlock *lcb);\nextern void addCallbackRegex (struct lregexControlBlock *lcb,\n\t\t\t\t\t\t\t  const char* const regex,\n\t\t\t\t\t\t\t  const char* const flags,\n\t\t\t\t\t\t\t  const regexCallback callback,\n\t\t\t\t\t\t\t  bool *disabled,\n\t\t\t\t\t\t\t  void * userData);\nextern bool regexNeedsMultilineBuffer (struct lregexControlBlock *lcb);\nextern bool matchMultilineRegex (struct lregexControlBlock *lcb, const vString* const allLines);\nextern bool matchMultitableRegex (struct lregexControlBlock *lcb, const vString* const allLines);\n\nextern void notifyRegexInputStart (struct lregexControlBlock *lcb);\nextern void notifyRegexInputEnd (struct lregexControlBlock *lcb);\n\nextern void addRegexTable (struct lregexControlBlock *lcb, const char *name);\nextern void extendRegexTable (struct lregexControlBlock *lcb, const char *src, const char *dist);\n\nextern void initRegexOptscript (void);\nextern void listRegexOpscriptOperators (FILE *fp);\n\nextern bool installOptscriptFieldAccessor (fieldType ftype);\n\nextern void addOptscriptToHook (struct lregexControlBlock *lcb, enum scriptHook hook, const char *code);\nextern void propagateParamToOptscript (struct lregexControlBlock *lcb, const char *param, const char *value);\n\nextern void printMultitableStatistics (struct lregexControlBlock *lcb);\n\nextern void basic_regex_flag_short (char c, void* data);\nextern void basic_regex_flag_long (const char* const s, const char* const unused, void* data);\nextern void extend_regex_flag_short (char c, void* data);\nextern void extend_regex_flag_long (const char* const s, const char* const unused, void* data);\n#ifdef HAVE_PCRE2\nextern void pcre2_regex_flag_short (char c, void* data);\nextern void pcre2_regex_flag_long (const char* const s, const char* const unused, void* data);\n#endif\n\n#endif\t/* CTAGS_MAIN_LREGEX_PRIVATEH */\n"
  },
  {
    "path": "main/lxpath.c",
    "content": "/*\n*   Copyright (c) 2015, Masatake YAMATO\n*   Copyright (c) 2015, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for xpath meta parser.\n*/\n\n#include \"general.h\"  /* must always come first */\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"lxpath_p.h\"\n#include \"options.h\"\n#include \"parse_p.h\"\n#include \"read.h\"\n#include \"read_p.h\"\n#include \"routines.h\"\n#include \"xtag.h\"\n\n#ifdef HAVE_LIBXML\n#include <libxml/parser.h>\n#include <libxml/xpath.h>\n#include <libxml/tree.h>\n\nextern  void updateXMLTagLine (tagEntryInfo *e, xmlNode *node)\n{\n\tunsigned long abs_line = translateLineNumber (XML_GET_LINE (node));\n\tMIOPos rela_pos = getInputFilePositionForLine (abs_line);\n\n\tupdateTagLine (e, abs_line, rela_pos);\n}\n\nstatic void simpleXpathMakeTag (xmlNode *node,\n\t\t\t\tconst char *xpath,\n\t\t\t\tconst tagXpathMakeTagSpec *spec,\n\t\t\t\tvoid *userData)\n{\n\ttagEntryInfo tag;\n\txmlChar* str;\n\tchar *path;\n\tint kind;\n\n\tstr = xmlNodeGetContent(node);\n\tif (str == NULL)\n\t\treturn;\n\n\tif (spec->kind == KIND_GHOST_INDEX && spec->decideKind)\n\t\tkind = spec->decideKind (node, xpath, spec, userData);\n\telse\n\t\tkind = spec->kind;\n\tAssert (kind != KIND_GHOST_INDEX);\n\n\tif (spec->role == ROLE_DEFINITION_INDEX)\n\t\tinitTagEntry (&tag, (char *)str, kind);\n\telse if (isXtagEnabled(XTAG_REFERENCE_TAGS))\n\t\tinitRefTagEntry (&tag, (char *)str,\n\t\t\t\t kind,\n\t\t\t\t spec->role);\n\telse\n\t\tgoto out;\n\n\t/* TODO\n\t * - adjust the line number for the node forward if node is an attribute. */\n\tupdateXMLTagLine (&tag, node);\n\n\tpath = (char *)xmlGetNodePath (node);\n\ttag.extensionFields.xpath = path;\n\n\tif (spec->make)\n\t\tspec->make (node, xpath, spec, &tag, userData);\n\telse\n\t\tmakeTagEntry (&tag);\n\n\tif (path)\n\t\txmlFree (path);\nout:\n\txmlFree (str);\n}\n\nextern void addTagXpath (const langType language CTAGS_ATTR_UNUSED, tagXpathTable *xpathTable)\n{\n\tAssert (xpathTable->xpath);\n\tAssert (!xpathTable->xpathCompiled);\n\n\tverbose (\"compile a xpath expression: %s\\n\", (xmlChar *)xpathTable->xpath);\n\txpathTable->xpathCompiled = xmlXPathCompile ((xmlChar *)xpathTable->xpath);\n\tif (!xpathTable->xpathCompiled)\n\t\terror (WARNING, \"Failed to compile the Xpath expression: %s\", xpathTable->xpath);\n}\n\nextern void removeTagXpath (const langType language CTAGS_ATTR_UNUSED, tagXpathTable *xpathTable)\n{\n\tif (xpathTable->xpathCompiled)\n\t{\n\t\txmlXPathFreeCompExpr (xpathTable->xpathCompiled);\n\t\txpathTable->xpathCompiled = NULL;\n\t}\n}\n\nstatic void findXMLTagsCore (xmlXPathContext *ctx, xmlNode *root,\n\t\t\t     const tagXpathTableTable *xpathTableTable,\n\t\t\t     void *userData)\n{\n\tunsigned int i;\n\tint j;\n\txmlNode * node;\n\n\tAssert (root);\n\tAssert (xpathTableTable);\n\n\tfor (i = 0; i < xpathTableTable->count; ++i)\n\t{\n\t\txmlXPathObject *object;\n\t\txmlNodeSet *set;\n\t\tconst tagXpathTable *elt = xpathTableTable->table + i;\n\n\t\tif (! elt->xpathCompiled)\n\t\t\tcontinue;\n\n#if 0\n\t\t/* Older version of libxml2 doesn't have xmlXPathSetContextNode. */\n\t\tif (xmlXPathSetContextNode (root, ctx) != 0)\n\t\t{\n\t\t\terror (WARNING, \"Failed to set node to XpathContext\");\n\t\t\treturn;\n\t\t}\n#else\n\t\tctx->node = root;\n#endif\n\n\t\tobject = xmlXPathCompiledEval (elt->xpathCompiled, ctx);\n\t\tif (!object)\n\t\t\tcontinue;\n\n\t\tset = object->nodesetval;\n\n\t\tif (set)\n\t\t{\n\t\t\tfor (j = 0; j < xmlXPathNodeSetGetLength (set); ++j)\n\t\t\t{\n\t\t\t\tnode = xmlXPathNodeSetItem(set, j);\n\t\t\t\tif (elt->specType == LXPATH_TABLE_DO_MAKE)\n\t\t\t\t\tsimpleXpathMakeTag (node, elt->xpath, &(elt->spec.makeTagSpec), userData);\n\t\t\t\telse\n\t\t\t\t\telt->spec.recurSpec.enter (node, elt->xpath, &(elt->spec.recurSpec), ctx, userData);\n\t\t\t}\n\t\t}\n\t\txmlXPathFreeObject (object);\n\t}\n}\n\nstatic void suppressWarning (void *ctx CTAGS_ATTR_UNUSED, const char *msg CTAGS_ATTR_UNUSED, ...)\n{\n}\n\nstatic xmlDocPtr makeXMLDoc (void)\n{\n\tconst unsigned char* data;\n\tsize_t size;\n\txmlDocPtr doc;\n\n\tdoc = getInputFileUserData ();\n\tif (doc)\n\t{\n\t\tverbose (\"reuse xml doc data\\n\");\n\t\treturn doc;\n\t}\n\n\tdata = getInputFileData (&size);\n\tif (data)\n\t{\n\t\txmlSetGenericErrorFunc (NULL, suppressWarning);\n#ifdef IS_xmlLineNumbersDefault_DEPRECATED\n\t\tdoc = xmlReadMemory((const char *)data, size, NULL, NULL, 0);\n#else\n\t\txmlLineNumbersDefault (1);\n\t\tdoc = xmlParseMemory((const char*)data, size);\n#endif\n\t}\n\n\treturn doc;\n}\n\nextern void findXMLTagsFull (xmlXPathContext *ctx, xmlNode *root,\n\t\t\t int tableTableIndex,\n\t\t\t void (* runAfter) (xmlXPathContext *, xmlNode *, void *),\n\t\t\t void *userData)\n{\n\tbool usedAsEntryPoint = false;\n\txmlDocPtr doc = NULL;\n\n\tconst langType lang = getInputLanguage();\n\tconst tagXpathTableTable *xpathTableTable\n\t\t= getXpathTableTable (lang, tableTableIndex);\n\n\tif (ctx == NULL)\n\t{\n\t\tusedAsEntryPoint = true;\n\n\t\tfindRegexTags ();\n\n\t\tdoc = makeXMLDoc ();\n\n\t\tif (doc == NULL)\n\t\t{\n\t\t\tverbose (\"could not parse %s as a XML file\\n\", getInputFileName());\n\t\t\treturn;\n\t\t}\n\n\t\tctx = xmlXPathNewContext (doc);\n\t\tif (ctx == NULL)\n\t\t\terror (FATAL, \"failed to make a new xpath context for %s\", getInputFileName());\n\n\t\troot = xmlDocGetRootElement(doc);\n\t\tif (root == NULL)\n\t\t{\n\t\t\tverbose (\"could not get the root node for %s\\n\", getInputFileName());\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\tfindXMLTagsCore (ctx, root, xpathTableTable, userData);\n\tif (runAfter)\n\t\t(* runAfter) (ctx, root, userData);\n\nout:\n\tif (usedAsEntryPoint)\n\t{\n\t\txmlXPathFreeContext (ctx);\n\n\t\tif (doc != getInputFileUserData ())\n\t\t\txmlFreeDoc (doc);\n\t}\n}\n\n#else\n\nextern void addTagXpath (const langType language, tagXpathTable *xpathTable)\n{\n\txpathTable->xpathCompiled = NULL;\n}\n\nextern void removeTagXpath (const langType language CTAGS_ATTR_UNUSED, tagXpathTable *xpathTable CTAGS_ATTR_UNUSED)\n{\n}\n\nextern void findXMLTagsFull (xmlXPathContext *ctx, xmlNode *root,\n\t\t\t int tableTableIndex,\n\t\t\t void (* runAfter) (xmlXPathContext *, xmlNode *, void *),\n\t\t\t void *userData)\n{\n}\n\nextern  void updateXMLTagLine (tagEntryInfo *e, xmlNode *node)\n{\n}\n#endif\n\nextern void findXMLTags (xmlXPathContext *ctx, xmlNode *root,\n\t\t\t int tableTableIndex,\n\t\t\t void *userData)\n{\n\tfindXMLTagsFull (ctx, root, tableTableIndex, NULL, userData);\n}\n"
  },
  {
    "path": "main/lxpath.h",
    "content": "/*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Xpath based parer API\n*/\n#ifndef CTAGS_LXPATH_PARSE_H\n#define CTAGS_LXPATH_PARSE_H\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"  /* must always come first */\n#include \"types.h\"\n\n#ifdef HAVE_LIBXML\n#include <libxml/xpath.h>\n#include <libxml/tree.h>\n#else\n#define xmlNode void\n#define xmlXPathCompExpr void\n#define xmlXPathContext void\n#endif\n\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef struct sTagXpathMakeTagSpec {\n\t/* Kind used in making a tag.\n\t   If kind is KIND_GHOST_INDEX, a function\n\t   specified with decideKind is called to decide\n\t   the kind for the tag. */\n\tint   kind;\n\tint   role;\n\t/* If make is NULL, just makeTagEntry is used instead. */\n\tvoid (*make) (xmlNode *node,\n\t\t      const char *xpath,\n\t\t      const struct sTagXpathMakeTagSpec *spec,\n\t\t      tagEntryInfo *tag,\n\t\t      void *userData);\n\tint (*decideKind) (xmlNode *node,\n\t\t      const char *xpath,\n\t\t      const struct sTagXpathMakeTagSpec *spec,\n\t\t      void *userData);\n\t/* TODO: decideRole */\n} tagXpathMakeTagSpec;\n\ntypedef struct sTagXpathRecurSpec {\n\tvoid (*enter) (xmlNode *node,\n\t\t       const char *xpath,\n\t\t       const struct sTagXpathRecurSpec *spec,\n\t\t       xmlXPathContext *ctx,\n\t\t       void *userData);\n\n\tint  nextTable;\t\t/* A parser can use this field any purpose.\n\t\t\t\t   main/lxpath part doesn't touch this. */\n\n} tagXpathRecurSpec;\n\ntypedef struct sTagXpathTable\n{\n\tconst char *const xpath;\n\tenum  { LXPATH_TABLE_DO_MAKE, LXPATH_TABLE_DO_RECUR } specType;\n\tunion {\n\t\ttagXpathMakeTagSpec makeTagSpec;\n\t\ttagXpathRecurSpec   recurSpec;\n\t} spec;\n\txmlXPathCompExpr* xpathCompiled;\n} tagXpathTable;\n\ntypedef struct sTagXpathTableTable {\n\ttagXpathTable *table;\n\tunsigned int   count;\n} tagXpathTableTable;\n\ntypedef struct sXpathFileSpec {\n\t/*\n\t   NULL represents the associated field in DTD is not examined.\n\t   \"\" (an empty string) represents the associated field in DTD\n\t   (and root element) must not exist. */\n\tconst char *rootElementName;\n\tconst char *nameInDTD;\n\tconst char *externalID;\n\tconst char *systemID;\n\tconst char *rootNSPrefix;\n\tconst char *rootNSHref;\n} xpathFileSpec;\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\n/* Xpath interface */\nextern void findXMLTagsFull (xmlXPathContext *ctx, xmlNode *root,\n\t\t\t int tableTableIndex,\n\t\t\t void (* runAfter) (xmlXPathContext *, xmlNode *, void *),\n\t\t\t void *userData);\n\nextern void findXMLTags (xmlXPathContext *ctx, xmlNode *root,\n\t\t\t int tableTableIndex,\n\t\t\t void *userData);\n\nextern  void updateXMLTagLine (tagEntryInfo *e, xmlNode *node);\n\n#endif  /* CTAGS_LXPATH_PARSE_H */\n"
  },
  {
    "path": "main/lxpath_p.h",
    "content": "/*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Xpath based parer API for the main part\n*/\n#ifndef CTAGS_LXPATH_PARSE_PRIVATE_H\n#define CTAGS_LXPATH_PARSE_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"  /* must always come first */\n#include \"types.h\"\n#include \"lxpath.h\"\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern void addTagXpath (const langType language, tagXpathTable *xpathTable);\nextern void removeTagXpath (const langType language, tagXpathTable *xpathTable);\n\n#endif  /* CTAGS_LXPATH_PARSE_PRIVATE_H */\n"
  },
  {
    "path": "main/main.c",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   Author: Darren Hiebert <dhiebert@users.sourceforge.net>\n*           http://ctags.sourceforge.net\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*   It is provided on an as-is basis and no responsibility is accepted for its\n*   failure to perform as expected.\n*\n*   This is a reimplementation of the ctags (1) program. It is an attempt to\n*   provide a fully featured ctags program which is free of the limitations\n*   which most (all?) others are subject to.\n*\n*   This module contains the start-up code and routines to determine the list\n*   of files to parsed for tags.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#if HAVE_DECL___ENVIRON\n#include <unistd.h>\n#elif HAVE_DECL__NSGETENVIRON\n#include <crt_externs.h>\n#endif\n\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n\n/*  To provide directory searching for recursion feature.\n */\n\n#ifdef HAVE_DIRENT_H\n# ifdef HAVE_SYS_TYPES_H\n#  include <sys/types.h>  /* required by dirent.h */\n# endif\n# include <dirent.h>  /* to declare opendir() */\n#endif\n#ifdef HAVE_DIRECT_H\n# include <direct.h>  /* to _getcwd() */\n#endif\n#ifdef HAVE_IO_H\n# include <io.h>  /* to declare _findfirst() */\n#endif\n\n\n#include \"ctags.h\"\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"error_p.h\"\n#include \"field_p.h\"\n#include \"keyword_p.h\"\n#include \"main_p.h\"\n#include \"options_p.h\"\n#include \"optscript.h\"\n#include \"parse_p.h\"\n#include \"read_p.h\"\n#include \"routines_p.h\"\n#include \"stats_p.h\"\n#include \"trace.h\"\n#include \"trashbox_p.h\"\n#include \"writer_p.h\"\n#include \"xtag_p.h\"\n\n#ifdef HAVE_JANSSON\n#include \"interactive_p.h\"\n#include <jansson.h>\n#include <errno.h>\n#endif\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic mainLoopFunc mainLoop;\nstatic void *mainData;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nstatic bool createTagsForEntry (const char *const entryName);\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n#if defined (HAVE_OPENDIR) && (defined (HAVE_DIRENT_H) || defined (_MSC_VER))\nstatic bool recurseUsingOpendir (const char *const dirName)\n{\n\tbool resize = false;\n\tDIR *const dir = opendir (dirName);\n\tif (dir == NULL)\n\t\terror (WARNING | PERROR, \"cannot recurse into directory \\\"%s\\\"\", dirName);\n\telse\n\t{\n\t\tstruct dirent *entry;\n\t\twhile ((entry = readdir (dir)) != NULL)\n\t\t{\n\t\t\tif (strcmp (entry->d_name, \".\") != 0  &&\n\t\t\t\tstrcmp (entry->d_name, \"..\") != 0)\n\t\t\t{\n\t\t\t\tchar *filePath;\n\t\t\t\tbool free_p = false;\n\t\t\t\tif (strcmp (dirName, \".\") == 0)\n\t\t\t\t\tfilePath = entry->d_name;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfilePath = combinePathAndFile (dirName, entry->d_name);\n\t\t\t\t\tfree_p = true;\n\t\t\t\t}\n\t\t\t\tresize |= createTagsForEntry (filePath);\n\t\t\t\tif (free_p)\n\t\t\t\t\teFree (filePath);\n\t\t\t}\n\t\t}\n\t\tclosedir (dir);\n\t}\n\treturn resize;\n}\n#endif\n\n#ifdef HAVE__FINDFIRST\n\nstatic bool createTagsForWildcardEntry (\n\t\tconst char *const pattern, const size_t dirLength,\n\t\tconst char *const entryName)\n{\n\tbool resize = false;\n\t/* we must not recurse into the directories \".\" or \"..\" */\n\tif (strcmp (entryName, \".\") != 0  &&  strcmp (entryName, \"..\") != 0)\n\t{\n\t\tvString *const filePath = vStringNew ();\n\t\tvStringNCopyS (filePath, pattern, dirLength);\n\t\tvStringCatS (filePath, entryName);\n\t\tresize = createTagsForEntry (vStringValue (filePath));\n\t\tvStringDelete (filePath);\n\t}\n\treturn resize;\n}\n\nstatic bool createTagsForWildcardUsingFindfirst (const char *const pattern)\n{\n\tbool resize = false;\n\tconst size_t dirLength = baseFilename (pattern) - pattern;\n\tstruct _finddata_t fileInfo;\n\tintptr_t hFile = _findfirst (pattern, &fileInfo);\n\tif (hFile != -1L)\n\t{\n\t\tdo\n\t\t{\n\t\t\tconst char *const entry = (const char *) fileInfo.name;\n\t\t\tresize |= createTagsForWildcardEntry (pattern, dirLength, entry);\n\t\t} while (_findnext (hFile, &fileInfo) == 0);\n\t\t_findclose (hFile);\n\t}\n\treturn resize;\n}\n\n#endif\n\n\nstatic bool recurseIntoDirectory (const char *const dirName)\n{\n\tstatic unsigned int recursionDepth = 0;\n\n\trecursionDepth++;\n\n\tbool resize = false;\n\tif (isRecursiveLink (dirName))\n\t\tverbose (\"ignoring \\\"%s\\\" (recursive link)\\n\", dirName);\n\telse if (! Option.recurse)\n\t\tverbose (\"ignoring \\\"%s\\\" (directory)\\n\", dirName);\n\telse if(recursionDepth > Option.maxRecursionDepth)\n\t\tverbose (\"not descending in directory \\\"%s\\\" (depth %u > %u)\\n\",\n\t\t\t\tdirName, recursionDepth, Option.maxRecursionDepth);\n\telse\n\t{\n\t\tverbose (\"RECURSING into directory \\\"%s\\\"\\n\", dirName);\n#if defined (HAVE_OPENDIR) && (defined (HAVE_DIRENT_H) || defined (_MSC_VER))\n\t\tresize = recurseUsingOpendir (dirName);\n#elif defined (HAVE__FINDFIRST)\n\t\t{\n\t\t\tvString *const pattern = vStringNew ();\n\t\t\tvStringCopyS (pattern, dirName);\n\t\t\tvStringPut (pattern, OUTPUT_PATH_SEPARATOR);\n\t\t\tvStringCatS (pattern, \"*.*\");\n\t\t\tresize = createTagsForWildcardUsingFindfirst (vStringValue (pattern));\n\t\t\tvStringDelete (pattern);\n\t\t}\n#endif\n\t}\n\n\trecursionDepth--;\n\n\treturn resize;\n}\n\nstatic bool createTagsForEntry (const char *const entryName)\n{\n\tbool resize = false;\n\tfileStatus *status = eStat (entryName);\n\n\tAssert (entryName != NULL);\n\tif (isExcludedFile (entryName, true))\n\t\tverbose (\"excluding \\\"%s\\\" (the early stage)\\n\", entryName);\n\telse if (status->isSymbolicLink  &&  ! Option.followLinks)\n\t\tverbose (\"ignoring \\\"%s\\\" (symbolic link)\\n\", entryName);\n\telse if (! status->exists)\n\t\terror ((status->isSymbolicLink ? NOTICE : WARNING) | PERROR,\n\t\t\t   \"cannot open input file \\\"%s\\\"\", entryName);\n\telse if (status->isDirectory)\n\t\tresize = recurseIntoDirectory (entryName);\n\telse if (! status->isNormalFile)\n\t\tverbose (\"ignoring \\\"%s\\\" (special file)\\n\", entryName);\n\telse if (isExcludedFile (entryName, false))\n\t\tverbose (\"excluding \\\"%s\\\"\\n\", entryName);\n\telse\n\t\tresize = parseFile (entryName);\n\n\teStatFree (status);\n\treturn resize;\n}\n\n#ifdef MANUAL_GLOBBING\n\nstatic bool createTagsForWildcardArg (const char *const arg)\n{\n\tbool resize = false;\n\tvString *const pattern = vStringNewInit (arg);\n\tchar *patternS = vStringValue (pattern);\n\n#if defined (HAVE__FINDFIRST)\n\t/*  We must transform the \".\" and \"..\" forms into something that can\n\t *  be expanded by the _findfirst function.\n\t */\n\tif (Option.recurse  &&\n\t\t(strcmp (patternS, \".\") == 0  ||  strcmp (patternS, \"..\") == 0))\n\t{\n\t\tvStringPut (pattern, OUTPUT_PATH_SEPARATOR);\n\t\tvStringCatS (pattern, \"*.*\");\n\t}\n\tresize |= createTagsForWildcardUsingFindfirst (patternS);\n#endif\n\tvStringDelete (pattern);\n\treturn resize;\n}\n\n#endif\n\nstatic bool createTagsForArgs (cookedArgs *const args)\n{\n\tbool resize = false;\n\n\t/*  Generate tags for each argument on the command line.\n\t */\n\twhile (! cArgOff (args))\n\t{\n\t\tconst char *const arg = cArgItem (args);\n\n#ifdef MANUAL_GLOBBING\n\t\tresize |= createTagsForWildcardArg (arg);\n#else\n\t\tresize |= createTagsForEntry (arg);\n#endif\n\t\tcArgForth (args);\n\t\tparseCmdlineOptions (args);\n\t}\n\treturn resize;\n}\n\n/*  Read from an opened file a list of file names for which to generate tags.\n */\nstatic bool createTagsFromFileInput (FILE *const fp, const bool filter)\n{\n\tbool resize = false;\n\tif (fp != NULL)\n\t{\n\t\tcookedArgs *args = cArgNewFromLineFile (fp);\n\t\tparseCmdlineOptions (args);\n\t\twhile (! cArgOff (args))\n\t\t{\n\t\t\tresize |= createTagsForEntry (cArgItem (args));\n\t\t\tif (filter)\n\t\t\t{\n\t\t\t\tif (Option.filterTerminator != NULL)\n\t\t\t\t\tfputs (Option.filterTerminator, stdout);\n\t\t\t\tfflush (stdout);\n\t\t\t}\n\t\t\tcArgForth (args);\n\t\t\tparseCmdlineOptions (args);\n\t\t}\n\t\tcArgDelete (args);\n\t}\n\treturn resize;\n}\n\n/*  Read from a named file a list of file names for which to generate tags.\n */\nstatic bool createTagsFromListFile (const char *const fileName)\n{\n\tbool resize;\n\tAssert (fileName != NULL);\n\tif (strcmp (fileName, \"-\") == 0)\n\t\tresize = createTagsFromFileInput (stdin, false);\n\telse\n\t{\n\t\tFILE *const fp = fopen (fileName, \"r\");\n\t\tif (fp == NULL)\n\t\t\terror (FATAL | PERROR, \"cannot open list file \\\"%s\\\"\", fileName);\n\t\tresize = createTagsFromFileInput (fp, false);\n\t\tfclose (fp);\n\t}\n\treturn resize;\n}\n\nstatic bool etagsInclude (void)\n{\n\treturn (bool)(Option.etags && Option.etagsInclude != NULL);\n}\n\nextern void setMainLoop (mainLoopFunc func, void *data)\n{\n\tmainLoop = func;\n\tmainData = data;\n}\n\nstatic void runMainLoop (cookedArgs *args)\n{\n\t(* mainLoop) (args, mainData);\n}\n\nstatic void batchMakeTags (cookedArgs *args, void *user CTAGS_ATTR_UNUSED)\n{\n\tclock_t timeStamps [3];\n\tbool resize = false;\n\tbool files = (bool)(! cArgOff (args) || Option.fileList != NULL\n\t\t\t\t\t\t\t  || Option.filter);\n\n\tif (! files)\n\t{\n\t\tif (filesRequired ())\n\t\t\terror (FATAL, \"No files specified. Try \\\"%s --help\\\".\",\n\t\t\t\tgetExecutableName ());\n\t\telse if (! Option.recurse && ! etagsInclude ())\n\t\t\treturn;\n\t}\n\n#define timeStamp(n) timeStamps[(n)]=(Option.printTotals ? clock():(clock_t)0)\n\tif ((! Option.filter) && (! Option.printLanguage))\n\t\topenTagFile ();\n\n\ttimeStamp (0);\n\n\tif (! cArgOff (args))\n\t{\n\t\tverbose (\"Reading command line arguments\\n\");\n\t\tresize = createTagsForArgs (args);\n\t}\n\tif (Option.fileList != NULL)\n\t{\n\t\tverbose (\"Reading list file\\n\");\n\t\tresize = (bool) (createTagsFromListFile (Option.fileList) || resize);\n\t}\n\tif (Option.filter)\n\t{\n\t\tverbose (\"Reading filter input\\n\");\n\t\tresize = (bool) (createTagsFromFileInput (stdin, true) || resize);\n\t}\n\tif (! files  &&  Option.recurse)\n\t\tresize = recurseIntoDirectory (\".\");\n\n\ttimeStamp (1);\n\n\tif ((! Option.filter) && (!Option.printLanguage))\n\t\tcloseTagFile (resize);\n\n\ttimeStamp (2);\n\n\tif (Option.printTotals)\n\t{\n\t\tprintTotals (timeStamps, Option.append, Option.sorted);\n\t\tif (Option.printTotals > 1)\n\t\t\tfor (unsigned int i = 0; i < countParsers(); i++)\n\t\t\t\tprintParserStatisticsIfUsed (i);\n\t}\n\n#undef timeStamp\n}\n\n#ifdef HAVE_JANSSON\nvoid interactiveLoop (cookedArgs *args CTAGS_ATTR_UNUSED, void *user)\n{\n\tstruct interactiveModeArgs *iargs = user;\n\n\tif (iargs->sandbox) {\n\t\t/* As of jansson 2.6, the object hashing is seeded off\n\t\t   of /dev/urandom, so trigger the hash seeding\n\t\t   before installing the syscall filter.\n\t\t*/\n\t\tjson_t * tmp = json_object ();\n\t\tjson_decref (tmp);\n\n\t\tif (installSyscallFilter ()) {\n\t\t\terror (FATAL, \"install_syscall_filter failed\");\n\t\t\t/* The explicit exit call is needed because\n\t\t\t   \"error (FATAL,...\" just prints a message in\n\t\t\t   interactive mode. */\n\t\t\texit (1);\n\t\t}\n\t}\n\n\tchar buffer[1024];\n\tjson_t *request;\n\n\tfputs (\"{\\\"_type\\\": \\\"program\\\", \\\"name\\\": \\\"\" PROGRAM_NAME \"\\\", \\\"version\\\": \\\"\" PROGRAM_VERSION \"\\\"}\\n\", stdout);\n\tfflush (stdout);\n\n\twhile (fgets (buffer, sizeof(buffer), stdin))\n\t{\n\t\tif (buffer[0] == '\\n')\n\t\t\tcontinue;\n\n\t\trequest = json_loads (buffer, JSON_DISABLE_EOF_CHECK, NULL);\n\t\tif (! request)\n\t\t{\n\t\t\terror (FATAL, \"invalid json\");\n\t\t\tgoto next;\n\t\t}\n\n\t\tjson_t *command = json_object_get (request, \"command\");\n\t\tif (! command)\n\t\t{\n\t\t\terror (FATAL, \"command name not found\");\n\t\t\tgoto next;\n\t\t}\n\n\t\tif (!strcmp (\"generate-tags\", json_string_value (command)))\n\t\t{\n\t\t\tjson_int_t size = -1;\n\t\t\tconst char *filename;\n\n\t\t\tif (json_unpack (request, \"{ss}\", \"filename\", &filename) == -1)\n\t\t\t{\n\t\t\t\terror (FATAL, \"invalid generate-tags request\");\n\t\t\t\tgoto next;\n\t\t\t}\n\n\t\t\tjson_unpack (request, \"{sI}\", \"size\", &size);\n\n\t\t\topenTagFile ();\n\t\t\tif (size == -1)\n\t\t\t{\t\t\t\t\t/* read from disk */\n\t\t\t\tif (iargs->sandbox) {\n\t\t\t\t\terror (FATAL,\n\t\t\t\t\t\t   \"invalid request in sandbox submode: reading file contents from a file is limited\");\n\t\t\t\t\tcloseTagFile (false);\n\t\t\t\t\tgoto next;\n\t\t\t\t}\n\n\t\t\t\tcreateTagsForEntry (filename);\n\t\t\t}\n\t\t\telse\n\t\t\t{\t\t\t\t\t/* read nbytes from stream */\n\t\t\t\tunsigned char *data = eMalloc (size);\n\t\t\t\tsize = fread (data, 1, size, stdin);\n\t\t\t\tMIO *mio = mio_new_memory (data, size, eRealloc, eFreeNoNullCheck);\n\t\t\t\tparseFileWithMio (filename, mio, NULL);\n\t\t\t\tmio_unref (mio);\n\t\t\t}\n\n\t\t\tcloseTagFile (false);\n\t\t\tfputs (\"{\\\"_type\\\": \\\"completed\\\", \\\"command\\\": \\\"generate-tags\\\"}\\n\", stdout);\n\t\t\tfflush(stdout);\n\t\t}\n\t\telse\n\t\t{\n\t\t\terror (FATAL, \"unknown command name\");\n\t\t\tgoto next;\n\t\t}\n\n\tnext:\n\t\tjson_decref (request);\n\t}\n}\n#endif\n\nstatic bool isSafeVar (const char* var)\n{\n\tconst char *safe_vars[] = {\n\t\t\"BASH_FUNC_module()=\",\n\t\t\"BASH_FUNC_scl()=\",\n\t\tNULL\n\t};\n\tconst char *sv;\n\n\tfor (sv = safe_vars[0]; sv != NULL; sv++)\n\t\tif (strncmp(var, sv, strlen (sv)) == 0)\n\t\t\treturn true;\n\n\treturn false;\n}\n\nstatic void sanitizeEnviron (void)\n{\n\tchar **e;\n\tint i;\n\n#if HAVE_DECL___ENVIRON\n\te = __environ;\n#elif HAVE_DECL__NSGETENVIRON\n\t{\n\t\tchar ***ep = _NSGetEnviron();\n\t\tif (ep)\n\t\t\te = *ep;\n\t\telse\n\t\t\te = NULL;\n\t}\n#else\n\te = NULL;\n#endif\n\n\tif (!e)\n\t\treturn;\n\n\tfor (i = 0; e [i]; i++)\n\t{\n\t\tchar *value;\n\n\t\tvalue = strchr (e [i], '=');\n\t\tif (!value)\n\t\t\tcontinue;\n\n\t\tvalue++;\n\t\tif (!strncmp (value, \"() {\", 4))\n\t\t{\n\t\t\tif (isSafeVar (e [i]))\n\t\t\t\tcontinue;\n\t\t\terror (WARNING, \"reset environment: %s\", e [i]);\n\t\t\tvalue [0] = '\\0';\n\t\t}\n\t}\n}\n\n/*\n *\t\tStart up code\n */\n\nextern int ctags_cli_main (int argc CTAGS_ATTR_UNUSED, char **argv)\n{\n\tcookedArgs *args;\n\n#if defined(_WIN32) && defined(HAVE_MKSTEMP)\n\t/* MinGW-w64's mkstemp() uses rand() for generating temporary files. */\n\tsrand ((unsigned int) clock ());\n#endif\n\n\tinitDefaultTrashBox ();\n\n\tDEBUG_INIT();\n\n\tsetErrorPrinter (stderrDefaultErrorPrinter, NULL);\n\tsetMainLoop (batchMakeTags, NULL);\n\tsetTagWriter (WRITER_U_CTAGS, NULL);\n\n\tsetCurrentDirectory ();\n\tsetExecutableName (*argv++);\n\tsanitizeEnviron ();\n\tcheckRegex ();\n\tinitFieldObjects ();\n\tinitXtagObjects ();\n\n\targs = cArgNewFromArgv (argv);\n\tpreviewFirstOption (args);\n\tinitializeParsing ();\n\ttestEtagsInvocation ();\n\tinitOptions ();\n\tinitRegexOptscript ();\n\treadOptionConfiguration ();\n\tverbose (\"Reading initial options from command line\\n\");\n\tparseCmdlineOptions (args);\n\tcheckOptions ();\n\n\trunMainLoop (args);\n\n\t/*  Clean up.\n\t */\n\tcArgDelete (args);\n\tfreeKeywordTable ();\n\tfreeRoutineResources ();\n\tfreeInputFileResources ();\n\tfreeTagFileResources ();\n\tfreeOptionResources ();\n\tfreeParserResources ();\n\tfreeRegexResources ();\n#ifdef HAVE_ICONV\n\tfreeEncodingResources ();\n#endif\n\n\tfiniDefaultTrashBox();\n\n\tif (Option.printLanguage)\n\t\treturn (Option.printLanguage == true)? 0: 1;\n\n\treturn 0;\n}\n"
  },
  {
    "path": "main/main_p.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Main part private interface to main.c\n*/\n#ifndef CTAGS_MAIN_MAIN_PRIVATE_H\n#define CTAGS_MAIN_MAIN_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern int ctags_cli_main (int argc, char **argv);\n\n#endif  /* CTAGS_MAIN_MAIN_PRIVATE_H */\n"
  },
  {
    "path": "main/mbcs.c",
    "content": "/*\n*   $Id$\n*\n*   Copyright (c) 2015, vim-jp\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for checking multibyte character set.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#ifndef __USE_GNU\n# define __USE_GNU\n#endif\n#include \"general.h\"  /* must always come first */\n\n#ifdef HAVE_ICONV\n\n#include <stdio.h>\n#include <string.h>\n#include <iconv.h>\n#include <errno.h>\n#include \"options.h\"\n#include \"mbcs.h\"\n#include \"mbcs_p.h\"\n#include \"routines.h\"\n\nstatic iconv_t iconv_fd = (iconv_t) -1;\n\nextern bool openConverter (const char* inputEncoding, const char* outputEncoding)\n{\n\tif (!inputEncoding || !outputEncoding)\n\t{\n\t\tstatic bool warn = false;\n\t\t/* --output-encoding is specified but not --input-encoding provided */\n\t\tif (!warn && outputEncoding)\n\t\t{\n\t\t\terror (WARNING, \"--input-encoding is not specified\");\n\t\t\twarn = true;\n\t\t}\n\t\treturn false;\n\t}\n\ticonv_fd = iconv_open(outputEncoding, inputEncoding);\n\tif (iconv_fd == (iconv_t) -1)\n\t{\n\t\terror (FATAL,\n\t\t\t\t\t\"failed opening encoding from '%s' to '%s'\", inputEncoding, outputEncoding);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nextern bool isConverting (void)\n{\n\treturn iconv_fd != (iconv_t) -1;\n}\n\nextern bool convertString (vString *const string)\n{\n\tsize_t dest_len, src_len;\n\tchar *dest, *dest_ptr, *src;\n\tif (iconv_fd == (iconv_t) -1)\n\t\treturn false;\n\tsrc_len = vStringLength (string);\n\t/* Should be longest length of bytes. so maybe utf8. */\n\tdest_len = src_len * 4;\n\tdest_ptr = dest = xCalloc (dest_len, char);\n\tif (!dest)\n\t\treturn false;\n\tsrc = vStringValue (string);\nretry:\n\tif (iconv (iconv_fd, &src, &src_len, &dest_ptr, &dest_len) == (size_t) -1)\n\t{\n\t\tif (errno == EILSEQ)\n\t\t{\n\t\t\t*dest_ptr++ = '?';\n\t\t\tdest_len--;\n\t\t\tsrc++;\n\t\t\tsrc_len--;\n\t\t\tverbose (\"  Encoding: %s\\n\", strerror(errno));\n\t\t\tgoto retry;\n\t\t}\n\t\teFree (dest);\n\t\treturn false;\n\t}\n\n\tdest_len = dest_ptr - dest;\n\n\tvStringClear (string);\n\tif (vStringSize (string) < dest_len + 1)\n\t\tvStringResize (string, dest_len + 1);\n\tmemcpy (vStringValue (string), dest, dest_len + 1);\n\tvStringLength (string) = dest_len;\n\teFree (dest);\n\n\ticonv (iconv_fd, NULL, NULL, NULL, NULL);\n\n\treturn true;\n}\n\nextern void closeConverter (void)\n{\n\tif (iconv_fd != (iconv_t) -1)\n\t{\n\t\ticonv_close(iconv_fd);\n\t\ticonv_fd = (iconv_t) -1;\n\t}\n}\n\n#endif\t/* HAVE_ICONV */\n"
  },
  {
    "path": "main/mbcs.h",
    "content": "/*\n*   $Id$\n*\n*   Copyright (c) 2015, vim-jp\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for checking multibyte character set.\n*/\n#ifndef CTAGS_MAIN_MBCS_H\n#define CTAGS_MAIN_MBCS_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#ifdef HAVE_ICONV\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern bool isConverting (void);\n\n#endif /* HAVE_ICONV */\n\n#endif /* CTAGS_MAIN_MBCS_H */\n"
  },
  {
    "path": "main/mbcs_p.h",
    "content": "/*\n*   $Id$\n*\n*   Copyright (c) 2015, vim-jp\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for checking multibyte character set.\n*/\n#ifndef CTAGS_MAIN_MBCS_PRIVATE_H\n#define CTAGS_MAIN_MBCS_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"vstring.h\"\n\n#ifdef HAVE_ICONV\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern bool openConverter (const char*, const char*);\nextern bool convertString (vString *const);\nextern void closeConverter (void);\n\n#endif /* HAVE_ICONV */\n\n#endif /* CTAGS_MAIN_MBCS_PRIVATE_H */\n"
  },
  {
    "path": "main/mini-geany.c",
    "content": "/*\n*   Copyright (c) 2019, Jiri Techet\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Provides a simple application using ctags as a library and using the same\n*   set of ctags functions as the Geany editor\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include \"types.h\"\n#include \"routines.h\"\n#include \"mio.h\"\n#include \"error_p.h\"\n#include \"writer_p.h\"\n#include \"parse_p.h\"\n#include \"options_p.h\"\n#include \"trashbox_p.h\"\n#include \"field_p.h\"\n#include \"xtag_p.h\"\n#include \"entry_p.h\"\n#include \"param_p.h\"\n\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n\nstatic int writeEntry (tagWriter *writer, MIO * mio, const tagEntryInfo *const tag, void *clientData);\nstatic void rescanFailed (tagWriter *writer, unsigned long validTagNum, void *clientData);\n\n/* we need to be able to provide a custom writer using which we collect the tags */\ntagWriter customWriter = {\n\t.writeEntry = writeEntry,\n\t.writePtagEntry = NULL,\n\t.preWriteEntry = NULL,\n\t.postWriteEntry = NULL,\n\t.rescanFailedEntry = rescanFailed,\n\t.treatFieldAsFixed = NULL,\n\t.defaultFileName = \"tags_file_which_should_never_appear_anywhere\",\n\t.private = NULL,\n};\n\n\n/* we need to be able to provide an error printer which doesn't crash Geany on error */\nCTAGS_ATTR_PRINTF(2, 0)\nstatic bool nofatalErrorPrinter (const errorSelection selection,\n\t\t\t\t\t  const char *const format,\n\t\t\t\t\t  va_list ap, void *data CTAGS_ATTR_UNUSED)\n{\n\tfprintf (stderr, \"%s: \", (selection & WARNING) ? \"Warning: \" : \"Error\");\n\tvfprintf (stderr, format, ap);\n\tif (selection & PERROR)\n#ifdef HAVE_STRERROR\n\t\tfprintf (stderr, \" : %s\", strerror (errno));\n#else\n\t\tperror (\" \");\n#endif\n\tfputs (\"\\n\", stderr);\n\n\treturn false;\n}\n\n\nstatic void enableRoles(unsigned int lang, unsigned int kind)\n{\n\tunsigned int c = countLanguageRoles(lang, kind);\n\n\tfor (unsigned int i = 0; i < c; i++)\n\t{\n\t\troleDefinition* rdef = getLanguageRole(lang, kind, (int)i);\n\t\tenableRole(rdef, true);\n\t}\n}\n\n\n/* we need to be able to enable all kinds and roles for all languages (some are disabled by default) */\nstatic void enableKindsAndRoles(void)\n{\n\tunsigned int lang;\n\n\tfor (lang = 0; lang < countParsers(); lang++)\n\t{\n\t\tunsigned int kindNum = countLanguageKinds(lang);\n\t\tunsigned int kind;\n\n\t\tfor (kind = 0; kind < kindNum; kind++)\n\t\t{\n\t\t\tkindDefinition *def = getLanguageKind(lang, kind);\n\t\t\tenableKind(def, true);\n\t\t\tenableRoles(lang, kind);\n\t\t}\n\t}\n}\n\n\n/* we need to be able to initialize ctags like in main() but skipping some things */\nstatic void ctagsInit(void)\n{\n\tinitDefaultTrashBox ();\n\n\tsetErrorPrinter (nofatalErrorPrinter, NULL);\n\tsetTagWriter (WRITER_CUSTOM, &customWriter);\n\n\tcheckRegex ();\n\tinitFieldObjects ();\n\tinitXtagObjects ();\n\n\tinitializeParsing ();\n\tinitOptions ();\n\tinitRegexOptscript ();\n\n\t/* make sure all parsers are initialized */\n\tinitializeParser (LANG_AUTO);\n\n\t/* change default value which is false */\n\tenableXtag(XTAG_TAGS_GENERATED_BY_GUEST_PARSERS, true);\n\tenableXtag(XTAG_REFERENCE_TAGS, true);\n\n\t/* some kinds and roles we are interested in are disabled by default */\n\tenableKindsAndRoles();\n}\n\n\n/* we need to be able to get a name of a given language */\nstatic const char *ctagsGetLangName(int lang)\n{\n\treturn getLanguageName(lang);\n}\n\n\n/* we need to be able to get an int representing a given language */\nstatic int ctagsGetNamedLang(const char *name)\n{\n\treturn getNamedLanguage(name, 0);\n}\n\n\n/* we need to be able to get kind letters provided by a given language */\nstatic const char *ctagsGetLangKinds(int lang)\n{\n\tunsigned int kindNum = countLanguageKinds(lang);\n\tstatic char kinds[257];\n\tunsigned int i;\n\n\tfor (i = 0; i < kindNum; i++)\n\t\tkinds[i] = getLanguageKind(lang, i)->letter;\n\tkinds[i] = '\\0';\n\n\treturn kinds;\n}\n\n\n/* we need to be able to get kind name from a kind letter for a given language */\nstatic const char *ctagsGetKindName(char kind, int lang)\n{\n\tkindDefinition *def = getLanguageKindForLetter (lang, kind);\n\treturn def ? def->name : \"unknown\";\n}\n\n\n/* we need to be able to get kind letter from a kind name for a given language */\nstatic char ctagsGetKindFromName(const char *name, int lang)\n{\n\tkindDefinition *def = getLanguageKindForName (lang, name);\n\treturn def ? def->letter : '-';\n}\n\n\n/* we need to be able to get kind letter from a kind index */\nstatic char ctagsGetKindFromIndex(int index, int lang)\n{\n\treturn getLanguageKind(lang, index)->letter;\n}\n\n\n/* we need to be able to get the number of parsers */\nstatic unsigned int ctagsGetLangCount(void)\n{\n\treturn countParsers();\n}\n\n\nstatic void addIgnoreSymbol(const char *value)\n{\n\tlangType lang = getNamedLanguage (\"CPreProcessor\", 0);\n\t/*\n\t * In the future, we will rename applyParameter to\n\t * applyLanguageParam.\n\t */\n\tapplyParameter (lang, \"ignore\", value);\n}\n\n/*******************************************************************************\n * So let's just use what we have for our great client...\n ******************************************************************************/\n\n/* our internal tag representation - this is all the tag information we use in Geany */\ntypedef struct {\n\tchar *name;\n\tchar *signature;\n\tchar *scopeName;\n\tchar *inheritance;\n\tchar *varType;\n\tchar *access;\n\tchar *implementation;\n\tchar kindLetter;\n\tbool isFileScope;\n\tunsigned long lineNumber;\n\tint lang;\n\tbool isAnon;\n} Tag;\n\n\nstatic Tag *createTag(const tagEntryInfo *info)\n{\n\tTag *tag = xCalloc(1, Tag);\n\tif (info->name)\n\t\ttag->name = eStrdup(info->name);\n\tif (info->extensionFields.signature)\n\t\ttag->signature = eStrdup(info->extensionFields.signature);\n\tif (info->extensionFields.scopeName)\n\t\ttag->scopeName = eStrdup(info->extensionFields.scopeName);\n\tif (info->extensionFields.inheritance)\n\t\ttag->inheritance = eStrdup(info->extensionFields.inheritance);\n\tif (info->extensionFields.typeRef[1])\n\t\ttag->varType = eStrdup(info->extensionFields.typeRef[1]);\n\tif (info->extensionFields.access)\n\t\ttag->access = eStrdup(info->extensionFields.access);\n\tif (info->extensionFields.implementation)\n\t\ttag->implementation = eStrdup(info->extensionFields.implementation);\n\ttag->kindLetter = ctagsGetKindFromIndex(info->kindIndex, info->langType);\n\ttag->isFileScope = info->isFileScope;\n\ttag->lineNumber = info->lineNumber;\n\ttag->lang = info->langType;\n\ttag->isAnon = isTagExtraBitMarked(info, XTAG_ANONYMOUS);\n\treturn tag;\n}\n\n\nstatic void destroyTag(Tag *tag)\n{\n\tif (tag->name)\n\t\teFree(tag->name);\n\tif (tag->signature)\n\t\teFree(tag->signature);\n\tif (tag->scopeName)\n\t\teFree(tag->scopeName);\n\tif (tag->inheritance)\n\t\teFree(tag->inheritance);\n\tif (tag->varType)\n\t\teFree(tag->varType);\n\tif (tag->access)\n\t\teFree(tag->access);\n\tif (tag->implementation)\n\t\teFree(tag->implementation);\n\teFree(tag);\n}\n\n\n/* callback from ctags informing us about a new tag */\nstatic int writeEntry (tagWriter *writer, MIO *mio, const tagEntryInfo *const tag, void *clientData)\n{\n\tTag *t;\n\n\t/* apparently we have to call this to get the scope info - maybe we can\n\t * specify some option during initialization so we don't have to cal this\n\t * ?????? */\n\tgetTagScopeInformation((tagEntryInfo *)tag, NULL, NULL);\n\n\t/* convert tags into our internal representation and store them into an array */\n\tt = createTag(tag);\n\tptrArrayAdd((ptrArray *)clientData, t);\n\n\t/* output length - we don't write anything to the MIO */\n\treturn 0;\n}\n\n\n/* scan has failed so we have invalid tags in our array - validTagNum should\n * tell us the number of valid tags so remove all the extra tags and shrink the array */\nstatic void rescanFailed (tagWriter *writer, unsigned long validTagNum, void *clientData)\n{\n\tptrArray *tagArray = clientData;\n\tint num = ptrArrayCount(tagArray);\n\n\tif (num > validTagNum)\n\t{\n\t\tint i;\n\t\tfor (i = validTagNum; i < num; i++)\n\t\t{\n\t\t\tTag *tag = ptrArrayLast(tagArray);\n\t\t\tdestroyTag(tag);\n\t\t\tptrArrayRemoveLast(tagArray);\n\t\t}\n\t}\n}\n\n\n/* do whatever we want to do with the tags */\nstatic void processCollectedTags(ptrArray *tagArray)\n{\n\tint i;\n\tint num = ptrArrayCount(tagArray);\n\n\tfor (i = 0; i < num; i++)\n\t{\n\t\tTag *tag = ptrArrayItem(tagArray, i);\n\t\tprintf(\"%s\\tline: %lu\\tkind: %s\\t lang: %s\\n\",\n\t\t\ttag->name,\n\t\t\ttag->lineNumber,\n\t\t\tctagsGetKindName(tag->kindLetter, tag->lang),\n\t\t\tctagsGetLangName(tag->lang));\n\t}\n\n\t/* prepare for the next parsing by clearing the tag array */\n\tptrArrayClear(tagArray);\n}\n\n\nextern int main (int argc, char **argv)\n{\n\t/* called once when Geany starts */\n\tctagsInit();\n\n\t/* create empty tag array *\n\t * this is where we store the collected tags\n\t * NOTE: Geany doesn't use the ptrArray type - it is used just for the purpose of this demo */\n\tptrArray *tagArray = ptrArrayNew((ptrArrayDeleteFunc)destroyTag);\n\n\tprintf(\"This parser only parses C files - provide them as arguments on the \"\n\t\t\t\"command line or get a hard-coded buffer parsed when no arguments \"\n\t\t\t\"are provided\\n\\n\");\n\tif (argc == 1)  /* parsing contents of a buffer */\n\t{\n\t\tchar *program = \"FOO int foo() {}\\n\\n int bar() {}\\n\\n int main() {}\\n\";\n\t\tint lang = ctagsGetNamedLang(\"C\");\n\t\tconst char *kinds = ctagsGetLangKinds(lang);\n\t\tint i;\n\n\t\t/* we need to be able to set and clear ignore symbols */\n\t\taddIgnoreSymbol(\"int\");\n\t\t/* clear */\n\t\taddIgnoreSymbol(NULL);\n\t\t/* set to something else */\n\t\taddIgnoreSymbol(\"FOO\");\n\n\t\tprintf(\"The total number of parsers is: %d\\n\", ctagsGetLangCount());\n\t\tprintf(\"We are parsing %s which provides the following kinds:\\n\",\n\t\t\tctagsGetLangName(lang));\n\t\tfor (i = 0; kinds[i] != '\\0'; i++)\n\t\t{\n\t\t\tprintf(\"%c: %s\\n\",\n\t\t\t\t/* back and forth conversion - the same like just kinds[i] */\n\t\t\t\tctagsGetKindFromName(ctagsGetKindName(kinds[i], lang), lang),\n\t\t\t\tctagsGetKindName(kinds[i], lang));\n\t\t}\n\n\t\tprintf(\"\\nParsing buffer:\\n\");\n\t\t/* we always specify the language by ourselves and don't use ctags detection */\n\t\tparseRawBuffer(\"whatever\", (unsigned char *)program, strlen(program), lang, tagArray);\n\n\t\tprocessCollectedTags(tagArray);\n\t}\n\telse  /* parsing contents of a file */\n\t{\n\t\tint i;\n\t\tfor (i = 1; i < argc; i++)\n\t\t{\n\t\t\tprintf(\"\\nParsing %s:\\n\", argv[i]);\n\t\t\t/* parseRawBuffer() is called repeatadly during Geany execution */\n\t\t\tparseRawBuffer(argv[i], NULL, 0, getNamedLanguage(\"C\", 0), tagArray);\n\n\t\t\tprocessCollectedTags(tagArray);\n\t\t}\n\t}\n\n\tptrArrayDelete(tagArray);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "main/mio.c",
    "content": "/*\n *  MIO, an I/O abstraction layer replicating C file I/O API.\n *  Copyright (C) 2010  Colomban Wendling <ban@herbesfolles.org>\n *\n *  This program is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation; either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License along\n *  with this program; if not, write to the Free Software Foundation, Inc.,\n *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n */\n\n#include \"general.h\"  /* must always come first */\n#include \"routines.h\"\n#include \"debug.h\"\n\n#include \"mio.h\"\n\n#include <stdarg.h>\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <stdlib.h>\n#include <limits.h>\n\n#ifndef _MSC_VER\n#define MAY_HAVE_FTRUNCATE\n#include <unistd.h>\n#endif\n\n/* minimal reallocation chunk size */\n#define MIO_CHUNK_SIZE 4096\n\n#define MAX(a, b)  (((a) > (b)) ? (a) : (b))\n\n\n/**\n * SECTION:mio\n * @short_description: The MIO object\n * @include: mio/mio.h\n *\n * The #MIO object replicates the C file I/O API with support of both standard\n * file based operations and in-memory operations. Its goal is to ease the port\n * of an application that uses C file I/O API to perform in-memory operations.\n *\n * A #MIO object is created using mio_new_file(), mio_new_memory() or mio_new_mio(),\n * depending on whether you want file or in-memory operations.\n * Its life is managed by reference counting. Just after calling one of functions\n * for creating, the count is 1. mio_ref() increments the counter. mio_unref()\n * decrements it. When the counter becomes 0, the #MIO object will be destroyed\n * in mio_unref(). There is also some other convenient API to create file-based\n * #MIO objects for more complex cases, such as mio_new_file_full() and\n * mio_new_fp().\n *\n * Once the #MIO object is created, you can perform standard I/O operations on\n * it transparently without the need to care about the effective underlying\n * operations.\n *\n * The I/O API is almost exactly a replication of the standard C file I/O API\n * with the significant difference that the first parameter is always the #MIO\n * object to work on.\n */\n\n\ntypedef struct _MIOUserData MIOUserData;\nstruct _MIOUserData {\n\tvoid *d;\n\tMIODestroyNotify f;\n};\n\n/**\n * MIO:\n *\n * An object representing a #MIO stream. No assumptions should be made about\n * what compose this object, and none of its fields should be accessed directly.\n */\nstruct _MIO {\n\t/*< private >*/\n\tMIOType type;\n\tunsigned int refcount;\n\tunion {\n\t\tstruct {\n\t\t\tFILE *fp;\n\t\t\tMIOFCloseFunc close_func;\n\t\t} file;\n\t\tstruct {\n\t\t\tunsigned char *buf;\n\t\t\tint ungetch;\n\t\t\tsize_t pos;\n\t\t\tsize_t size;\n\t\t\tsize_t allocated_size;\n\t\t\tMIOReallocFunc realloc_func;\n\t\t\tMIODestroyNotify free_func;\n\t\t\tbool error;\n\t\t\tbool eof;\n\t\t} mem;\n\t} impl;\n\tMIOUserData udata;\n};\n\n\n/**\n * mio_new_file_full:\n * @filename: Filename to open, passed as-is to @open_func as the first argument\n * @mode: Mode in which open the file, passed as-is to @open_func as the second\n *        argument\n * @open_func: A function with the fopen() semantic to use to open the file\n * @close_func: A function with the fclose() semantic to close the file when\n *              the #MIO object is destroyed, or %NULL not to close the #FILE\n *              object\n *\n * Creates a new #MIO object working on a file, from a filename and an opening\n * function. See also mio_new_file().\n *\n * This function is generally overkill and mio_new_file() should often be used\n * instead, but it allows to specify a custom function to open a file, as well\n * as a close function. The former is useful e.g. if you need to wrap fopen()\n * for some reason (like filename encoding conversion for example), and the\n * latter allows you both to match your custom open function and to choose\n * whether the underlying #FILE object should or not be closed when mio_unref()\n * is called on the returned object.\n *\n * Free-function: mio_unref()\n *\n * Returns: A new #MIO on success, or %NULL on failure.\n */\nMIO *mio_new_file_full (const char *filename,\n\t\t\t\t\t\tconst char *mode,\n\t\t\t\t\t\tMIOFOpenFunc open_func,\n\t\t\t\t\t\tMIOFCloseFunc close_func)\n{\n\tMIO *mio;\n\n\t/* we need to create the MIO object first, because we may not be able to close\n\t * the opened file if the user passed NULL as the close function, which means\n\t * that everything must succeed if we've opened the file successfully */\n\tmio = xMalloc (1, MIO);\n\tif (mio)\n\t{\n\t\tFILE *fp = open_func (filename, mode);\n\n\t\tif (! fp)\n\t\t{\n\t\t\teFree (mio);\n\t\t\tmio = NULL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmio->type = MIO_TYPE_FILE;\n\t\t\tmio->impl.file.fp = fp;\n\t\t\tmio->impl.file.close_func = close_func;\n\t\t\tmio->refcount = 1;\n\t\t\tmio->udata.d = NULL;\n\t\t\tmio->udata.f = NULL;\n\t\t}\n\t}\n\n\treturn mio;\n}\n\n/**\n * mio_new_file:\n * @filename: Filename to open, same as the fopen()'s first argument\n * @mode: Mode in which open the file, fopen()'s second argument\n *\n * Creates a new #MIO object working on a file from a filename; wrapping\n * fopen().\n * This function simply calls mio_new_file_full() with the libc's fopen() and\n * fclose() functions.\n *\n * Free-function: mio_unref()\n *\n * Returns: A new #MIO on success, or %NULL on failure.\n */\nMIO *mio_new_file (const char *filename, const char *mode)\n{\n\treturn mio_new_file_full (filename, mode, fopen, fclose);\n}\n\n/**\n * mio_new_fp:\n * @fp: An opened #FILE object\n * @close_func: (allow-none): Function used to close @fp when the #MIO object\n *              gets destroyed, or %NULL not to close the #FILE object\n *\n * Creates a new #MIO object working on a file, from an already opened #FILE\n * object.\n *\n * <example>\n * <title>Typical use of this function</title>\n * <programlisting>\n * MIO *mio = mio_new_fp (fp, fclose);\n * </programlisting>\n * </example>\n *\n * Free-function: mio_unref()\n *\n * Returns: A new #MIO on success or %NULL on failure.\n */\nMIO *mio_new_fp (FILE *fp, MIOFCloseFunc close_func)\n{\n\tMIO *mio;\n\n\tif (!fp)\n\t\treturn NULL;\n\n\tmio = xMalloc (1, MIO);\n\tif (mio)\n\t{\n\t\tmio->type = MIO_TYPE_FILE;\n\t\tmio->impl.file.fp = fp;\n\t\tmio->impl.file.close_func = close_func;\n\t\tmio->refcount = 1;\n\t\tmio->udata.d = NULL;\n\t\tmio->udata.f = NULL;\n\t}\n\n\treturn mio;\n}\n\n/**\n * mio_new_memory:\n * @data: Initial data (may be %NULL)\n * @size: Length of @data in bytes\n * @realloc_func: A function with the realloc() semantic used to grow the\n *                buffer, or %NULL to disable buffer growing\n * @free_func: A function with the free() semantic to destroy the data together\n *             with the object, or %NULL not to destroy the data\n *\n * Creates a new #MIO object working on memory.\n *\n * To allow the buffer to grow, you must provide a @realloc_func, otherwise\n * trying to write after the end of the current data will fail.\n *\n * If you want the buffer to be freed together with the #MIO object, you must\n * give a @free_func; otherwise the data will still live after #MIO object\n * termination.\n *\n * <example>\n * <title>Basic creation of a non-growable, freeable #MIO object</title>\n * <programlisting>\n * MIO *mio = mio_new_memory (data, size, NULL, g_free);\n * </programlisting>\n * </example>\n *\n * <example>\n * <title>Basic creation of an empty growable and freeable #MIO object</title>\n * <programlisting>\n * MIO *mio = mio_new_memory (NULL, 0, g_try_realloc, g_free);\n * </programlisting>\n * </example>\n *\n * Free-function: mio_unref()\n *\n * Returns: A new #MIO on success, or %NULL on failure.\n */\nMIO *mio_new_memory (unsigned char *data,\n\t\t\t\t\t size_t size,\n\t\t\t\t\t MIOReallocFunc realloc_func,\n\t\t\t\t\t MIODestroyNotify free_func)\n{\n\tMIO *mio;\n\n\tmio = xMalloc (1, MIO);\n\tif (mio)\n\t{\n\t\tmio->type = MIO_TYPE_MEMORY;\n\t\tmio->impl.mem.buf = data;\n\t\tmio->impl.mem.ungetch = EOF;\n\t\tmio->impl.mem.pos = 0;\n\t\tmio->impl.mem.size = size;\n\t\tmio->impl.mem.allocated_size = size;\n\t\tmio->impl.mem.realloc_func = realloc_func;\n\t\tmio->impl.mem.free_func = free_func;\n\t\tmio->impl.mem.eof = false;\n\t\tmio->impl.mem.error = false;\n\t\tmio->refcount = 1;\n\t\tmio->udata.d = NULL;\n\t\tmio->udata.f = NULL;\n\t}\n\n\treturn mio;\n}\n\n/**\n * mio_new_mio:\n * @base: The original mio\n * @start: stream offset of the @base where new mio starts\n * @size: the length of the data copied from @base to new mio\n *\n * Creates a new #MIO object by copying data from existing #MIO (@base).\n * The range for copying is given with @start and @size.\n * Copying data at the range from @start to the end of @base is\n * done if -1 is given as @size.\n *\n * If @size is larger than the length from @start to the end of\n * @base, %NULL is returned.\n *\n * The function doesn't move the file position of @base.\n *\n * Free-function: mio_unref()\n *\n */\n\nMIO *mio_new_mio (MIO *base, long start, long size)\n{\n\tunsigned char *data;\n\tlong original_pos;\n\tMIO *submio;\n\tsize_t r;\n\n\toriginal_pos = mio_tell (base);\n\n\tif (size == -1)\n\t{\n\t\tlong end;\n\n\t\tif (mio_seek (base, 0, SEEK_END) != 0)\n\t\t\treturn NULL;\n\t\tend = mio_tell (base);\n\t\tAssert (end >= start);\n\t\tsize = end - start;\n\t}\n\n\tif (mio_seek (base, start, SEEK_SET) != 0)\n\t\treturn NULL;\n\n\tdata = xMalloc (size, unsigned char);\n\tr= mio_read (base, data, 1, size);\n\tmio_seek (base, original_pos, SEEK_SET);\n\n\tif (r != size)\n\t\tgoto cleanup;\n\n\tsubmio = mio_new_memory (data, size, eRealloc, eFreeNoNullCheck);\n\tif (! submio)\n\t\tgoto cleanup;\n\n\treturn submio;\n\ncleanup:\n\teFree (data);\n\treturn NULL;\n}\n\n/**\n * mio_ref:\n * @mio: A #MIO object\n *\n * Increments the reference counter of a #MIO.\n *\n * Returns: passed @mio.\n */\nMIO *mio_ref        (MIO *mio)\n{\n\tmio->refcount++;\n\treturn mio;\n}\n\n/**\n * mio_file_get_fp:\n * @mio: A #MIO object\n *\n * Gets the underlying #FILE object associated with a #MIO file stream.\n *\n * <warning><para>The returned object may become invalid after a call to\n * mio_unref() if the stream was configured to close the file when\n * destroyed.</para></warning>\n *\n * Returns: The underlying #FILE object of the given stream, or %NULL if the\n *          stream is not a file stream.\n */\nFILE *mio_file_get_fp (MIO *mio)\n{\n\tFILE *fp = NULL;\n\n\tif (mio->type == MIO_TYPE_FILE)\n\t\tfp = mio->impl.file.fp;\n\n\treturn fp;\n}\n\n/**\n * mio_memory_get_data:\n * @mio: A #MIO object\n * @size: (allow-none) (out): Return location for the length of the returned\n *        memory, or %NULL\n *\n * Gets the underlying memory buffer associated with a #MIO memory stream.\n *\n * <warning><para>The returned pointer and size may become invalid after a\n * successful write on the stream or after a call to mio_unref() if the stream\n * was configured to free the memory when destroyed.</para></warning>\n *\n * Returns: The memory buffer of the given #MIO stream, or %NULL if the stream\n *          is not a memory stream.\n */\nunsigned char *mio_memory_get_data (MIO *mio, size_t *size)\n{\n\tunsigned char *ptr = NULL;\n\n\tif (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tptr = mio->impl.mem.buf;\n\t\tif (size)\n\t\t\t*size = mio->impl.mem.size;\n\t}\n\n\treturn ptr;\n}\n\n/**\n * mio_unref:\n * @mio: A #MIO object\n *\n * Decrements the reference counter of a #MIO and destroys the #MIO\n * object if its counter becomes 0.\n *\n * Returns: Error code obtained from the registered MIOFCloseFunc or 0 on success.\n */\nint mio_unref (MIO *mio)\n{\n\tint rv = 0;\n\n\tif (mio)\n\t{\n\t\tif (--mio->refcount)\n\t\t\treturn 0;\n\n\t\tif (mio->udata.d && mio->udata.f)\n\t\t\tmio->udata.f (mio->udata.d);\n\n\t\tif (mio->type == MIO_TYPE_FILE)\n\t\t{\n\t\t\tif (mio->impl.file.close_func)\n\t\t\t\trv = mio->impl.file.close_func (mio->impl.file.fp);\n\t\t\tmio->impl.file.close_func = NULL;\n\t\t\tmio->impl.file.fp = NULL;\n\t\t}\n\t\telse if (mio->type == MIO_TYPE_MEMORY)\n\t\t{\n\t\t\tif (mio->impl.mem.free_func)\n\t\t\t\tmio->impl.mem.free_func (mio->impl.mem.buf);\n\t\t\tmio->impl.mem.buf = NULL;\n\t\t\tmio->impl.mem.pos = 0;\n\t\t\tmio->impl.mem.size = 0;\n\t\t\tmio->impl.mem.allocated_size = 0;\n\t\t\tmio->impl.mem.realloc_func = NULL;\n\t\t\tmio->impl.mem.free_func = NULL;\n\t\t\tmio->impl.mem.eof = false;\n\t\t\tmio->impl.mem.error = false;\n\t\t}\n\t\telse\n\t\t\tAssertNotReached ();\n\n\t\teFree (mio);\n\t}\n\n\treturn rv;\n}\n\n/**\n * mio_read:\n * @mio: A #MIO object\n * @ptr: Pointer to the memory to fill with the read data\n * @size: Size of each block to read\n * @nmemb: Number o blocks to read\n *\n * Reads raw data from a #MIO stream. This function behave the same as fread().\n *\n * Returns: The number of actually read blocks. If an error occurs or if the\n *          end of the stream is reached, the return value may be smaller than\n *          the requested block count, or even 0. This function doesn't\n *          distinguish between end-of-stream and an error, you should then use\n *          mio_eof() and mio_error() to determine which occurred.\n */\nsize_t mio_read (MIO *mio,\n\t\t\t\t void *ptr_,\n\t\t\t\t size_t size,\n\t\t\t\t size_t nmemb)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn fread (ptr_, size, nmemb, mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tsize_t n_read = 0;\n\n\t\tif (size != 0 && nmemb != 0)\n\t\t{\n\t\t\tsize_t size_avail = mio->impl.mem.size - mio->impl.mem.pos;\n\t\t\tsize_t copy_bytes = size * nmemb;\n\t\t\tunsigned char *ptr = ptr_;\n\n\t\t\tif (size_avail < copy_bytes)\n\t\t\t\tcopy_bytes = size_avail;\n\n\t\t\tif (copy_bytes > 0)\n\t\t\t{\n\t\t\t\tn_read = copy_bytes / size;\n\n\t\t\t\tif (mio->impl.mem.ungetch != EOF)\n\t\t\t\t{\n\t\t\t\t\t*ptr = (unsigned char) mio->impl.mem.ungetch;\n\t\t\t\t\tmio->impl.mem.ungetch = EOF;\n\t\t\t\t\tcopy_bytes--;\n\t\t\t\t\tmio->impl.mem.pos++;\n\t\t\t\t\tptr++;\n\t\t\t\t}\n\n\t\t\t\tmemcpy (ptr, &mio->impl.mem.buf[mio->impl.mem.pos], copy_bytes);\n\t\t\t\tmio->impl.mem.pos += copy_bytes;\n\t\t\t}\n\t\t\tif (mio->impl.mem.pos >= mio->impl.mem.size)\n\t\t\t\tmio->impl.mem.eof = true;\n\t\t}\n\n\t\treturn n_read;\n\t}\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/*\n * mem_try_resize:\n * @mio: A #MIO object of the type %MIO_TYPE_MEMORY\n * @new_size: Requested new size\n *\n * Tries to resize the underlying buffer of an in-memory #MIO object.\n * This supports both growing and shrinking.\n *\n * Returns: %true on success, %false otherwise.\n */\nstatic int mem_try_resize (MIO *mio, size_t new_size)\n{\n\tint success = false;\n\n\tif (mio->impl.mem.realloc_func)\n\t{\n\t\tif (new_size == ULONG_MAX)\n\t\t{\n#ifdef EOVERFLOW\n\t\t\terrno = EOVERFLOW;\n#endif\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (new_size > mio->impl.mem.size)\n\t\t\t{\n\t\t\t\tif (new_size <= mio->impl.mem.allocated_size)\n\t\t\t\t{\n\t\t\t\t\tmio->impl.mem.size = new_size;\n\t\t\t\t\tsuccess = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsize_t newsize;\n\t\t\t\t\tunsigned char *newbuf;\n\n\t\t\t\t\tnewsize = MAX (mio->impl.mem.allocated_size + MIO_CHUNK_SIZE,\n\t\t\t\t\t\t\t\t   new_size);\n\t\t\t\t\tnewbuf = mio->impl.mem.realloc_func (mio->impl.mem.buf, newsize);\n\t\t\t\t\tif (newbuf)\n\t\t\t\t\t{\n\t\t\t\t\t\tmio->impl.mem.buf = newbuf;\n\t\t\t\t\t\tmio->impl.mem.allocated_size = newsize;\n\t\t\t\t\t\tmio->impl.mem.size = new_size;\n\t\t\t\t\t\tsuccess = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tunsigned char *newbuf;\n\n\t\t\t\tnewbuf = mio->impl.mem.realloc_func (mio->impl.mem.buf, new_size);\n\t\t\t\tif (newbuf || new_size == 0)\n\t\t\t\t{\n\t\t\t\t\tmio->impl.mem.buf = newbuf;\n\t\t\t\t\tmio->impl.mem.allocated_size = new_size;\n\t\t\t\t\tmio->impl.mem.size = new_size;\n\t\t\t\t\tsuccess = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn success;\n}\n\nstatic int file_try_resize (MIO *mio, size_t new_size)\n{\n\tmio_flush (mio);\n\n\tFILE *fp = mio_file_get_fp (mio);\n\n#ifdef MAY_HAVE_FTRUNCATE\n\tif (ftruncate(fileno(fp), (off_t)new_size) < 0)\n\t\treturn false;\n#else\n\t/* See https://stackoverflow.com/questions/873454/how-to-truncate-a-file-in-c/874704#874704 */\n\tif ((errno = _chsize_s(_fileno(fp), (__int64)new_size)) != 0)\n\t\treturn false;\n#endif\n\treturn true;\n}\n\nint mio_try_resize (MIO *mio, size_t new_size)\n{\n\tif (mio->type == MIO_TYPE_MEMORY)\n\t\treturn mem_try_resize (mio, new_size);\n\telse\n\t\treturn file_try_resize (mio, new_size);\n}\n\n/*\n * mem_try_ensure_space:\n * @mio: A #MIO object\n * @n: Requested size from the current (cursor) position\n *\n * Tries to ensure there is enough space for @n bytes to be written from the\n * current cursor position.\n *\n * Returns: %true if there is enough space, %false otherwise.\n */\nstatic int mem_try_ensure_space (MIO *mio, size_t n)\n{\n\tint success = true;\n\n\tif (mio->impl.mem.pos + n > mio->impl.mem.size)\n\t\tsuccess = mem_try_resize (mio, mio->impl.mem.pos + n);\n\n\treturn success;\n}\n\n/**\n * mio_write:\n * @mio: A #MIO object\n * @ptr: Pointer to the memory to write on the stream\n * @size: Size of each block to write\n * @nmemb: Number of block to write\n *\n * Writes raw data to a #MIO stream. This function behaves the same as fwrite().\n *\n * Returns: The number of blocks actually written to the stream. This might be\n *          smaller than the requested count if a write error occurs.\n */\nsize_t mio_write (MIO *mio,\n\t\t\t\t  const void *ptr,\n\t\t\t\t  size_t size,\n\t\t\t\t  size_t nmemb)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn fwrite (ptr, size, nmemb, mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tsize_t n_written = 0;\n\n\t\tif (size != 0 && nmemb != 0)\n\t\t{\n\t\t\tif (mem_try_ensure_space (mio, size * nmemb))\n\t\t\t{\n\t\t\t\tmemcpy (&mio->impl.mem.buf[mio->impl.mem.pos], ptr, size * nmemb);\n\t\t\t\tmio->impl.mem.pos += size * nmemb;\n\t\t\t\tn_written = nmemb;\n\t\t\t}\n\t\t}\n\n\t\treturn n_written;\n\t}\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/**\n * mio_putc:\n * @mio: A #MIO object\n * @c: The character to write\n *\n * Writes a character to a #MIO stream. This function behaves the same as\n * fputc().\n *\n * Returns: The written character, or %EOF on error.\n */\nint mio_putc (MIO *mio, int c)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn fputc (c, mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tint rv = EOF;\n\n\t\tif (mem_try_ensure_space (mio, 1))\n\t\t{\n\t\t\tmio->impl.mem.buf[mio->impl.mem.pos] = (unsigned char)c;\n\t\t\tmio->impl.mem.pos++;\n\t\t\trv = (int)((unsigned char)c);\n\t\t}\n\n\t\treturn rv;\n\t}\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/**\n * mio_puts:\n * @mio: A #MIO object\n * @s: The string to write\n *\n * Writes a string to a #MIO object. This function behaves the same as fputs().\n *\n * Returns: A non-negative integer on success or %EOF on failure.\n */\nint mio_puts (MIO *mio, const char *s)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn fputs (s, mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tint rv = EOF;\n\t\tsize_t len;\n\n\t\tlen = strlen (s);\n\t\tif (mem_try_ensure_space (mio, len))\n\t\t{\n\t\t\tmemcpy (&mio->impl.mem.buf[mio->impl.mem.pos], s, len);\n\t\t\tmio->impl.mem.pos += len;\n\t\t\trv = 1;\n\t\t}\n\n\t\treturn rv;\n\t}\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/**\n * mio_vprintf:\n * @mio: A #MIO object\n * @format: A printf format string\n * @ap: The variadic argument list for the format\n *\n * Writes a formatted string into a #MIO stream. This function behaves the same\n * as vfprintf().\n *\n * Returns: The number of bytes written in the stream, or a negative value on\n *          failure.\n */\nint mio_vprintf (MIO *mio, const char *format, va_list ap)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn vfprintf (mio->impl.file.fp, format, ap);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tint rv = -1;\n\t\tsize_t n;\n\t\tsize_t old_pos;\n\t\tsize_t old_size;\n\t\tva_list ap_copy;\n\t\tchar dummy;\n\n\t\told_pos = mio->impl.mem.pos;\n\t\told_size = mio->impl.mem.size;\n\t\tva_copy (ap_copy, ap);\n\t\t/* compute the size we will need into the buffer */\n\t\tn = vsnprintf (&dummy, 1, format, ap_copy) + 1;\n\t\tva_end (ap_copy);\n\t\tif (mem_try_ensure_space (mio, n))\n\t\t{\n\t\t\tunsigned char c;\n\n\t\t\t/* backup character at n+1 that will be overwritten by a \\0 ... */\n\t\t\tc = mio->impl.mem.buf[mio->impl.mem.pos + (n - 1)];\n\t\t\trv = vsprintf ((char *)&mio->impl.mem.buf[mio->impl.mem.pos], format, ap);\n\t\t\t/* ...and restore it */\n\t\t\tmio->impl.mem.buf[mio->impl.mem.pos + (n - 1)] = c;\n\t\t\tif (rv >= 0 && (size_t)rv == (n - 1))\n\t\t\t{\n\t\t\t\t/* re-compute the actual size since we might have allocated one byte\n\t\t\t\t * more than needed */\n\t\t\t\tmio->impl.mem.size = MAX (old_size, old_pos + (unsigned int)rv);\n\t\t\t\tmio->impl.mem.pos += (unsigned int)rv;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmio->impl.mem.size = old_size;\n\t\t\t\trv = -1;\n\t\t\t}\n\t\t}\n\n\t\treturn rv;\n\t}\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/**\n * mio_printf:\n * @mio: A #MIO object\n * @format: A print format string\n * @...: Arguments of the format\n *\n * Writes a formatted string to a #MIO stream. This function behaves the same as\n * fprintf().\n *\n * Returns: The number of bytes written to the stream, or a negative value on\n *          failure.\n */\nint mio_printf (MIO *mio, const char *format, ...)\n{\n\tint rv;\n\tva_list ap;\n\n\tva_start (ap, format);\n\trv = mio_vprintf (mio, format, ap);\n\tva_end (ap);\n\n\treturn rv;\n}\n\n/**\n * mio_getc:\n * @mio: A #MIO object\n *\n * Gets the current character from a #MIO stream. This function behaves the same\n * as fgetc().\n *\n * Returns: The read character as a #int, or %EOF on error.\n */\nint mio_getc (MIO *mio)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn fgetc (mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tint rv = EOF;\n\n\t\tif (mio->impl.mem.ungetch != EOF)\n\t\t{\n\t\t\trv = mio->impl.mem.ungetch;\n\t\t\tmio->impl.mem.ungetch = EOF;\n\t\t\tmio->impl.mem.pos++;\n\t\t}\n\t\telse if (mio->impl.mem.pos < mio->impl.mem.size)\n\t\t{\n\t\t\trv = mio->impl.mem.buf[mio->impl.mem.pos];\n\t\t\tmio->impl.mem.pos++;\n\t\t}\n\t\telse\n\t\t\tmio->impl.mem.eof = true;\n\n\t\treturn rv;\n\t}\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/**\n * mio_ungetc:\n * @mio: A #MIO object\n * @ch: Character to put back in the stream\n *\n * Puts a character back in a #MIO stream. This function behaves the sames as\n * ungetc().\n *\n * <warning><para>It is only guaranteed that one character can be but back at a\n * time, even if the implementation may allow more.</para></warning>\n * <warning><para>Using this function while the stream cursor is at offset 0 is\n * not guaranteed to function properly. As the C99 standard says, it is \"an\n * obsolescent feature\".</para></warning>\n *\n * Returns: The character put back, or %EOF on error.\n */\nint mio_ungetc (MIO *mio, int ch)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn ungetc (ch, mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tint rv = EOF;\n\n\t\tif (ch != EOF && mio->impl.mem.ungetch == EOF)\n\t\t{\n\t\t\trv = mio->impl.mem.ungetch = ch;\n\t\t\tmio->impl.mem.pos--;\n\t\t\tmio->impl.mem.eof = false;\n\t\t}\n\n\t\treturn rv;\n\t}\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/**\n * mio_gets:\n * @mio: A #MIO object\n * @s: A string to fill with the read data\n * @size: The maximum number of bytes to read\n *\n * Reads a string from a #MIO stream, stopping after the first new-line\n * character or at the end of the stream. This function behaves the same as\n * fgets().\n *\n * Returns: @s on success, %NULL otherwise.\n */\nchar *mio_gets (MIO *mio, char *s, size_t size)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn fgets (s, (int)size, mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tchar *rv = NULL;\n\n\t\tif (size > 0)\n\t\t{\n\t\t\tsize_t i = 0;\n\t\t\tbool newline = false;\n\t\t\t/* Avoiding dereference inside the for loop below improves\n\t\t\t * performance so we do it here. */\n\t\t\tsize_t pos = mio->impl.mem.pos;\n\t\t\tsize_t buf_size = mio->impl.mem.size;\n\t\t\tunsigned char *buf = mio->impl.mem.buf;\n\n\t\t\tif (mio->impl.mem.ungetch != EOF)\n\t\t\t{\n\t\t\t\ts[i] = (char)mio->impl.mem.ungetch;\n\t\t\t\tmio->impl.mem.ungetch = EOF;\n\t\t\t\tpos++;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tfor (; pos < buf_size && i < (size - 1); i++)\n\t\t\t{\n\t\t\t\ts[i] = (char)buf[pos];\n\t\t\t\tpos++;\n\t\t\t\tif (s[i] == '\\n')\n\t\t\t\t{\n\t\t\t\t\ti++;\n\t\t\t\t\tnewline = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (i > 0)\n\t\t\t{\n\t\t\t\ts[i] = 0;\n\t\t\t\trv = s;\n\t\t\t}\n\t\t\tif (!newline && pos >= buf_size)\n\t\t\t\tmio->impl.mem.eof = true;\n\t\t\tmio->impl.mem.pos = pos;\n\t\t\tmio->impl.mem.size = buf_size;\n\t\t}\n\n\t\treturn rv;\n\t}\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/**\n * mio_clearerr:\n * @mio: A #MIO object\n *\n * Clears the error and end-of-stream indicators of a #MIO stream. This function\n * behaves the same as clearerr().\n */\nvoid mio_clearerr (MIO *mio)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\tclearerr (mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tmio->impl.mem.error = false;\n\t\tmio->impl.mem.eof = false;\n\t}\n\telse\n\t\tAssertNotReached ();\n}\n\n/**\n * mio_eof:\n * @mio: A #MIO object\n *\n * Checks whether the end-of-stream indicator of a #MIO stream is set. This\n * function behaves the same as feof().\n *\n * Returns: A non-null value if the stream reached its end, 0 otherwise.\n */\nint mio_eof (MIO *mio)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn feof (mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t\treturn mio->impl.mem.eof != false;\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/**\n * mio_error:\n * @mio: A #MIO object\n *\n * Checks whether the error indicator of a #MIO stream is set. This function\n * behaves the same as ferror().\n *\n * Returns: A non-null value if the stream have an error set, 0 otherwise.\n */\nint mio_error (MIO *mio)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn ferror (mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t\treturn mio->impl.mem.error != false;\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/**\n * mio_seek:\n * @mio: A #MIO object\n * @offset: Offset of the new place, from @whence\n * @whence: Move origin. SEEK_SET moves relative to the start of the stream,\n *          SEEK_CUR from the current position and SEEK_SET from the end of the\n *          stream.\n *\n * Sets the cursor position on a #MIO stream. This functions behaves the same as\n * fseek(). See also mio_tell() and mio_setpos().\n *\n * Returns: 0 on success, -1 otherwise, in which case errno should be set to\n *          indicate the error.\n */\nint mio_seek (MIO *mio, long offset, int whence)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn fseek (mio->impl.file.fp, offset, whence);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\t/* FIXME: should we support seeking out of bounds like lseek() seems to do? */\n\t\tint rv = -1;\n\n\t\tswitch (whence)\n\t\t{\n\t\t\tcase SEEK_SET:\n\t\t\t\tif (offset < 0 || (size_t)offset > mio->impl.mem.size)\n\t\t\t\t\terrno = EINVAL;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmio->impl.mem.pos = (size_t)offset;\n\t\t\t\t\trv = 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SEEK_CUR:\n\t\t\t\tif ((offset < 0 && (size_t)-offset > mio->impl.mem.pos) ||\n\t\t\t\t\tmio->impl.mem.pos + (size_t)offset > mio->impl.mem.size)\n\t\t\t\t{\n\t\t\t\t\terrno = EINVAL;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmio->impl.mem.pos = (size_t)(mio->impl.mem.pos + offset);\n\t\t\t\t\trv = 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase SEEK_END:\n\t\t\t\tif (offset > 0 || (size_t)-offset > mio->impl.mem.size)\n\t\t\t\t\terrno = EINVAL;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmio->impl.mem.pos = mio->impl.mem.size - (size_t)-offset;\n\t\t\t\t\trv = 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\terrno = EINVAL;\n\t\t}\n\t\tif (rv == 0)\n\t\t{\n\t\t\tmio->impl.mem.eof = false;\n\t\t\tmio->impl.mem.ungetch = EOF;\n\t\t}\n\n\t\treturn rv;\n\t}\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n\n}\n\n/**\n * mio_tell:\n * @mio: A #MIO object\n *\n * Gets the current cursor position of a #MIO stream. This function behaves the\n * same as ftell().\n *\n * Returns: The current offset from the start of the stream, or -1 or error, in\n *          which case errno is set to indicate the error.\n */\nlong mio_tell (MIO *mio)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn ftell (mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tlong rv = -1;\n\n\t\tif (mio->impl.mem.pos > LONG_MAX)\n\t\t{\n#ifdef EOVERFLOW\n\t\t\terrno = EOVERFLOW;\n#endif\n\t\t}\n\t\telse\n\t\t\trv = (long)mio->impl.mem.pos;\n\n\t\treturn rv;\n\t}\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn 0;\n\t}\n}\n\n/**\n * mio_rewind:\n * @mio: A #MIO object\n *\n * Resets the cursor position to 0, and also the end-of-stream and the error\n * indicators of a #MIO stream.\n * See also mio_seek() and mio_clearerr().\n */\nvoid mio_rewind (MIO *mio)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\trewind (mio->impl.file.fp);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\tmio->impl.mem.pos = 0;\n\t\tmio->impl.mem.ungetch = EOF;\n\t\tmio->impl.mem.eof = false;\n\t\tmio->impl.mem.error = false;\n\t}\n\telse\n\t\tAssertNotReached ();\n}\n\n/**\n * mio_getpos:\n * @mio: A #MIO stream\n * @pos: (out): A #MIOPos object to fill-in\n *\n * Stores the current position (and maybe other informations about the stream\n * state) of a #MIO stream in order to restore it later with mio_setpos(). This\n * function behaves the same as fgetpos().\n *\n * Returns: 0 on success, -1 otherwise, in which case errno is set to indicate\n *          the error.\n */\nint mio_getpos (MIO *mio, MIOPos *pos)\n{\n\tint rv = -1;\n\n\tmemset (pos, 0, sizeof (*pos));\n\n\tpos->type = mio->type;\n\tif (mio->type == MIO_TYPE_FILE)\n\t\trv = fgetpos (mio->impl.file.fp, &pos->impl.file);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\trv = -1;\n\n\t\tif (mio->impl.mem.pos == (size_t)-1)\n\t\t{\n\t\t\t/* this happens if ungetc() was called at the start of the stream */\n#ifdef EIO\n\t\t\terrno = EIO;\n#endif\n\t\t}\n\t\telse\n\t\t{\n\t\t\tpos->impl.mem = mio->impl.mem.pos;\n\t\t\trv = 0;\n\t\t}\n\t}\n\telse\n\t\tAssertNotReached();\n\n#ifdef MIO_DEBUG\n\tif (rv != -1)\n\t{\n\t\tpos->tag = mio;\n\t}\n#endif /* MIO_DEBUG */\n\n\treturn rv;\n}\n\n/**\n * mio_setpos:\n * @mio: A #MIO object\n * @pos: (in): A #MIOPos object filled-in by a previous call of mio_getpos() on\n *       the same stream\n *\n * Restores the position and state indicators of a #MIO stream previously saved\n * by mio_getpos().\n *\n * <warning><para>The #MIOPos object must have been initialized by a previous\n * call to mio_getpos() on the same stream.</para></warning>\n *\n * Returns: 0 on success, -1 otherwise, in which case errno is set to indicate\n *          the error.\n */\nint mio_setpos (MIO *mio, MIOPos *pos)\n{\n\tint rv = -1;\n\n#ifdef MIO_DEBUG\n\tif (pos->tag != mio)\n\t{\n\t\terror (FATAL, \"mio_setpos((MIO*)%p, (MIOPos*)%p, (MIOPos->tag): %p: \"\n\t\t\t\t\t\"Given MIOPos was not set by a previous call to mio_getpos() \"\n\t\t\t\t\t\"on the same MIO object, which means there is a bug in \"\n\t\t\t\t\t\"someone's code.\",\n\t\t\t\t\t(void *)mio, (void *)pos, (void *)pos->tag);\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n#endif /* MIO_DEBUG */\n\n\tif (mio->type == MIO_TYPE_FILE)\n\t\trv = fsetpos (mio->impl.file.fp, &pos->impl.file);\n\telse if (mio->type == MIO_TYPE_MEMORY)\n\t{\n\t\trv = -1;\n\n\t\tif (pos->impl.mem > mio->impl.mem.size)\n\t\t\terrno = EINVAL;\n\t\telse\n\t\t{\n\t\t\tmio->impl.mem.ungetch = EOF;\n\t\t\tmio->impl.mem.pos = pos->impl.mem;\n\t\t\trv = 0;\n\t\t}\n\t}\n\telse\n\t\tAssertNotReached ();\n\n\treturn rv;\n}\n\n/**\n * mio_flush:\n * @mio: A #MIO object\n *\n * Forces a write of all user-space buffered data for the given output or update\n * stream via the stream's underlying write function. Only applicable when using\n * FILE back-end.\n *\n * Returns: 0 on success, error code otherwise.\n */\nint mio_flush (MIO *mio)\n{\n\tif (mio->type == MIO_TYPE_FILE)\n\t\treturn fflush (mio->impl.file.fp);\n\treturn 0;\n}\n\n\n/**\n * mio_attach_user_data:\n * @mio: A #MIO object\n * @user_data: a pointer to any data object\n * @user_data_free_func: a call back function to destroy the data object passed as @user_data\n *\n * Attach any data object to a #MIO object. Attached data can be got with\n * mio_get_user_data(). The attached data is destroyed when new data is attached to\n * the #MIO object, or #the MIO object itself is destroyed. For destroying the data\n * @user_data_free_func is used.\n *\n */\n\nvoid  mio_attach_user_data (MIO *mio, void *user_data, MIODestroyNotify user_data_free_func)\n{\n\tif (mio->udata.d && mio->udata.f)\n\t\tmio->udata.f (mio->udata.d);\n\n\tmio->udata.d = user_data;\n\tmio->udata.f = user_data_free_func;\n}\n\n/**\n * mio_get_user_data:\n * @mio: A #MIO object\n *\n * Returns: user data attached with mio_attach_user_data() to a #MIO object.\n *\n */\nvoid *mio_get_user_data (MIO *mio)\n{\n\treturn mio->udata.d;\n}\n"
  },
  {
    "path": "main/mio.h",
    "content": "/*\n *  MIO, an I/O abstraction layer replicating C file I/O API.\n *  Copyright (C) 2010  Colomban Wendling <ban@herbesfolles.org>\n *\n *  This program is free software; you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation; either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License along\n *  with this program; if not, write to the Free Software Foundation, Inc.,\n *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n *\n */\n\n#ifndef MIO_H\n#define MIO_H\n\n#ifdef DEBUG\n/* If we use autoconf, DEBUG is set via configure. See DEBUG_CPPFLAGS in Makefile */\n#define MIO_DEBUG 1\n#endif\n\n#ifndef QUALIFIER\n#include \"general.h\"  /* must always come first */\n#else\n#include \"gcc-attr.h\"\n#endif\n\n#include <stdio.h>\n#include <stdarg.h>\n\n\n/**\n * MIOType:\n * @MIO_TYPE_FILE: #MIO object works on a file\n * @MIO_TYPE_MEMORY: #MIO object works in-memory\n *\n * Existing implementations.\n */\nenum _MIOType {\n\tMIO_TYPE_FILE,\n\tMIO_TYPE_MEMORY\n};\n\ntypedef enum _MIOType   MIOType;\ntypedef struct _MIO     MIO;\ntypedef struct _MIOPos  MIOPos;\n\n/**\n * MIOReallocFunc:\n * @ptr: Pointer to the memory to resize\n * @size: New size of the memory pointed by @ptr\n *\n * A function following the realloc() semantic.\n *\n * Returns: A pointer to the start of the new memory, or %NULL on failure.\n */\ntypedef void *(* MIOReallocFunc) (void * ptr, size_t size);\n\n/**\n * MIOFOpenFunc:\n * @filename: The filename to open\n * @mode: fopen() modes for opening @filename\n *\n * A function following the fclose() semantic, used to close a #FILE\n * object.\n *\n * Returns: A new #FILE object, or %NULL on failure\n */\ntypedef FILE *(* MIOFOpenFunc) (const char *filename, const char *mode);\n\n/**\n * MIOFCloseFunc:\n * @fp: An opened #FILE object\n *\n * A function following the fclose() semantic, used to close a #FILE\n * object.\n *\n * Returns: 0 on success, EOF otherwise.\n */\ntypedef int (* MIOFCloseFunc) (FILE *fp);\n\n/**\n * MIODestroyNotify:\n * @data: Data element being destroyed\n *\n * Specifies the type of function which is called when a data element is\n * destroyed. It is passed the pointer to the data element and should free any\n * memory and resources allocated for it.\n */\ntypedef void (*MIODestroyNotify) (void *data);\n\n/**\n * MIOPos:\n *\n * An object representing the state of a #MIO stream. This object can be\n * statically allocated but all its fields are private and should not be\n * accessed directly.\n */\nstruct _MIOPos {\n\t/*< private >*/\n\tMIOType type;\n#ifdef MIO_DEBUG\n\tvoid *tag;\n#endif\n\tunion {\n\t\tfpos_t file;\n\t\tsize_t mem;\n\t} impl;\n};\n\n\n\nMIO *mio_new_file (const char *filename, const char *mode);\nMIO *mio_new_file_full (const char *filename,\n\t\t\t\t\t\tconst char *mode,\n\t\t\t\t\t\tMIOFOpenFunc open_func,\n\t\t\t\t\t\tMIOFCloseFunc close_func);\nMIO *mio_new_fp (FILE *fp, MIOFCloseFunc close_func);\nMIO *mio_new_memory (unsigned char *data,\n\t\t\t\t\t size_t size,\n\t\t\t\t\t MIOReallocFunc realloc_func,\n\t\t\t\t\t MIODestroyNotify free_func);\n\nMIO *mio_new_mio    (MIO *base, long start, long size);\nMIO *mio_ref        (MIO *mio);\n\nint mio_unref (MIO *mio);\nFILE *mio_file_get_fp (MIO *mio);\nunsigned char *mio_memory_get_data (MIO *mio, size_t *size);\nsize_t mio_read (MIO *mio,\n\t\t\t\t void *ptr,\n\t\t\t\t size_t size,\n\t\t\t\t size_t nmemb);\nsize_t mio_write (MIO *mio,\n\t\t\t\t  const void *ptr,\n\t\t\t\t  size_t size,\n\t\t\t\t  size_t nmemb);\nint mio_getc (MIO *mio);\nchar *mio_gets (MIO *mio, char *s, size_t size);\nint mio_ungetc (MIO *mio, int ch);\nint mio_putc (MIO *mio, int c);\nint mio_puts (MIO *mio, const char *s);\n\nint mio_vprintf (MIO *mio, const char *format, va_list ap) CTAGS_ATTR_PRINTF (2, 0);\nint mio_printf (MIO *mio, const char *format, ...) CTAGS_ATTR_PRINTF (2, 3);\n\nvoid mio_clearerr (MIO *mio);\nint mio_eof (MIO *mio);\nint mio_error (MIO *mio);\nint mio_seek (MIO *mio, long offset, int whence);\nlong mio_tell (MIO *mio);\nvoid mio_rewind (MIO *mio);\nint mio_getpos (MIO *mio, MIOPos *pos);\nint mio_setpos (MIO *mio, MIOPos *pos);\nint mio_flush (MIO *mio);\n\nvoid  mio_attach_user_data (MIO *mio, void *user_data, MIODestroyNotify user_data_free_func);\nvoid *mio_get_user_data (MIO *mio);\n\nint mio_try_resize (MIO *mio, size_t new_size);\n\n#endif /* MIO_H */\n"
  },
  {
    "path": "main/nestlevel.c",
    "content": "/*\n*   Copyright (c) 1999-2002, Darren Hiebert\n*   Copyright 2009-2011 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines external interface to scope nesting levels for tags.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"routines.h\"\n#include \"nestlevel.h\"\n#include \"vstring.h\"\n\n#include <string.h>\n\n/* struct alignment trick, copied from GObject's gtype.c, which borrows\n * 2*szieof(size_t) from glibc */\n#define STRUCT_ALIGNMENT (2 * sizeof (size_t))\n#define ALIGN_STRUCT(offset) ((offset + (STRUCT_ALIGNMENT - 1)) & -STRUCT_ALIGNMENT)\n\n/* account for the user data alignment if we have user data, otherwise allocate\n * exactly what's needed not to waste memory for unneeded alignment */\n#define NL_SIZE(nls) ((nls)->userDataSize ? (ALIGN_STRUCT (sizeof (NestingLevel)) + ALIGN_STRUCT ((nls)->userDataSize)) : sizeof (NestingLevel))\n#define NL_USER_DATA(nl) ((void *)(((char *) nl) + ALIGN_STRUCT (sizeof (NestingLevel))))\n\n#define NL_NTH(nls,n) (NestingLevel *)(((char *)((nls)->levels)) + ((n) * NL_SIZE (nls)))\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nextern NestingLevels *nestingLevelsNewFull(size_t userDataSize,\n\t\t\t\t\t\t\t\t\t\t   void (* deleteUserData)(NestingLevel *, void *))\n{\n\tNestingLevels *nls = xCalloc (1, NestingLevels);\n\tnls->userDataSize = userDataSize;\n\tnls->deleteUserData = deleteUserData;\n\treturn nls;\n}\n\nextern NestingLevels *nestingLevelsNew(size_t userDataSize)\n{\n\treturn nestingLevelsNewFull (userDataSize, NULL);\n}\n\nextern void nestingLevelsFreeFull(NestingLevels *nls, void *ctxData)\n{\n\tint i;\n\tNestingLevel *nl;\n\n\tfor (i = 0; i < nls->n; i++)\n\t{\n\t\tnl = NL_NTH(nls, i);\n\t\tif (nls->deleteUserData)\n\t\t\tnls->deleteUserData (nl, ctxData);\n\t\tnl->corkIndex = CORK_NIL;\n\t}\n\tif (nls->levels) eFree(nls->levels);\n\teFree(nls);\n}\n\nextern NestingLevel * nestingLevelsPush(NestingLevels *nls, int corkIndex)\n{\n\tNestingLevel *nl = NULL;\n\n\tif (nls->n >= nls->allocated)\n\t{\n\t\tnls->allocated++;\n\t\tnls->levels = eRealloc(nls->levels,\n\t\t\t\t       nls->allocated * NL_SIZE (nls));\n\t}\n\tnl = NL_NTH(nls, nls->n);\n\tnls->n++;\n\n\tnl->corkIndex = corkIndex;\n\tif (nls->userDataSize > 0)\n\t\tmemset (NL_USER_DATA (nl), 0, ALIGN_STRUCT (nls->userDataSize));\n\n\treturn nl;\n}\n\nextern NestingLevel *nestingLevelsTruncate(NestingLevels *nls, int depth, int corkIndex)\n{\n\tNestingLevel *nl;\n\n\tnls->n = depth;\n\tnl = nestingLevelsGetCurrent(nls);\n\tnl->corkIndex = corkIndex;\n\treturn nl;\n}\n\n\nextern void nestingLevelsPopFull(NestingLevels *nls, void *ctxData)\n{\n\tNestingLevel *nl = nestingLevelsGetCurrent(nls);\n\n\tAssert (nl != NULL);\n\tif (nls->deleteUserData)\n\t\tnls->deleteUserData (nl, ctxData);\n\tnl->corkIndex = CORK_NIL;\n\tnls->n--;\n}\n\nextern NestingLevel *nestingLevelsGetNthFromRoot (const NestingLevels *nls, int n)\n{\n\tAssert (nls != NULL);\n\tif (nls->n > n && n >= 0)\n\t\treturn  NL_NTH(nls, n);\n\telse\n\t\treturn NULL;\n}\n\nextern NestingLevel *nestingLevelsGetNthParent (const NestingLevels *nls, int n)\n{\n\tAssert (nls != NULL);\n\treturn nestingLevelsGetNthFromRoot (nls, nls->n - 1 - n);\n}\n\nextern void *nestingLevelGetUserData (const NestingLevel *nl)\n{\n\treturn NL_USER_DATA (nl);\n}\n\n/* (This function comes from ruby.c)\n*\n* Returns a newly allocated vString describing the scope in 'nls'.\n* We record the current scope as a list of entered scopes.\n* Scopes corresponding to 'if' statements and the like are\n* represented by empty strings. Scopes corresponding to\n* modules and classes are represented by the name of the\n* module or class.\n*/\nextern vString* nestingLevelsToScopeNew (const NestingLevels* nls, const char infixSeparator)\n{\n\tint i;\n\tvString* result = vStringNew ();\n\tfor (i = 0; i < nls->n; ++i)\n\t{\n\t\tNestingLevel *nl = nestingLevelsGetNthFromRoot (nls, i);\n\t\ttagEntryInfo *e = getEntryOfNestingLevel (nl);\n\t\tif (e && (*e->name != '\\0') && (!e->placeholder))\n\t\t\tvStringJoinS (result, infixSeparator, e->name);\n\t}\n\treturn result;\n}\n"
  },
  {
    "path": "main/nestlevel.h",
    "content": "/*\n*   Copyright (c) 1999-2002, Darren Hiebert\n*   Copyright 2009-2011 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines external interface to scope nesting levels for tags.\n*/\n#ifndef CTAGS_MAIN_NESTLEVEL_H\n#define CTAGS_MAIN_NESTLEVEL_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"vstring.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef struct NestingLevel NestingLevel;\ntypedef struct NestingLevels NestingLevels;\n\nstruct NestingLevel\n{\n\tint corkIndex;\n\t/* user data is allocated at the end of this struct (possibly with some\n\t * offset for alignment), get it with nestingLevelGetUserData() */\n};\n\nstruct NestingLevels\n{\n\tvoid *levels;\n\tint n;\t\t\t\t\t/* number of levels in use */\n\tint allocated;\n\tsize_t userDataSize;\n\t/* The second argument is given via nestinglevelsPopFull\n\t * or nestinglevelFreeFull */\n\tvoid (* deleteUserData) (NestingLevel *, void *);\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern NestingLevels *nestingLevelsNew(size_t userDataSize);\nextern NestingLevels *nestingLevelsNewFull(size_t userDataSize,\n\t\t\t\t\t\t\t\t\t\t   void (* deleteUserData)(NestingLevel *, void *));\n#define nestingLevelsFree(NLS) nestingLevelsFreeFull(NLS, NULL)\nextern void nestingLevelsFreeFull(NestingLevels *nls, void *ctxData);\nextern NestingLevel *nestingLevelsPush(NestingLevels *nls, int corkIndex);\nextern NestingLevel * nestingLevelsTruncate(NestingLevels *nls, int depth, int corkIndex);\n#define nestingLevelsPop(NLS) nestingLevelsPopFull(NLS, NULL)\nextern void nestingLevelsPopFull(NestingLevels *nls, void *ctxData);\n#define nestingLevelsGetCurrent(NLS) nestingLevelsGetNthParent((NLS), 0)\nextern NestingLevel *nestingLevelsGetNthFromRoot(const NestingLevels *nls, int n);\nextern NestingLevel *nestingLevelsGetNthParent(const NestingLevels *nls, int n);\n\nextern void *nestingLevelGetUserData (const NestingLevel *nl);\n\nextern vString* nestingLevelsToScopeNew (const NestingLevels* nls, const char infixSeparator);\n\n#endif  /* CTAGS_MAIN_NESTLEVEL_H */\n"
  },
  {
    "path": "main/numarray.c",
    "content": "/*\n*   Copyright (c) 1999-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions managing resizable pointer arrays.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"debug.h\"\n#include \"numarray.h\"\n#include \"routines.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\n#define impNumArray(prefix,Prefix,type)\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstruct s##Prefix##Array {\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int max;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int count;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\ttype *array;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t};\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern prefix##Array *prefix##ArrayNew (void)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tprefix##Array* const result = xMalloc (1, prefix##Array);\t\t\\\n\t\tresult->max = 8;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tresult->count = 0;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tresult->array = xMalloc (result->max, type);\t\t\t\t\t\\\n\t\treturn result;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern unsigned int prefix##ArrayAdd (prefix##Array *const current, type num) \\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current != NULL);\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (current->count == current->max)\t\t\t\t\t\t\t\t\\\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tcurrent->max *= 2;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tcurrent->array = xRealloc (current->array, current->max, type);\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tcurrent->array [current->count] = num;\t\t\t\t\t\t\t\\\n\t\treturn current->count++;\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern type prefix##ArrayRemoveLast (prefix##Array *const current)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current != NULL);\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current->count > 0);\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\ttype last = prefix##ArrayLast (current);\t\t\t\t\t\t\\\n\t\t--current->count;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn last;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern void prefix##ArrayCombine (prefix##Array *const current, prefix##Array *const from) \\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int i;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current != NULL);\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (from != NULL);\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tfor (i = 0  ;  i < from->count  ;  ++i)\t\t\t\t\t\t\t\\\n\t\t\tprefix##ArrayAdd (current, from->array [i]);\t\t\t\t\\\n\t\tfrom->count = 0;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tprefix##ArrayDelete (from);\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern unsigned int prefix##ArrayCount (const prefix##Array *const current)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current != NULL);\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn current->count;\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern bool prefix##ArrayIsEmpty (const prefix##Array *const current)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn (prefix##ArrayCount(current) == 0);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern type prefix##ArrayItem (const prefix##Array *const current, const unsigned int indx)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current != NULL);\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn current->array [indx];\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern type prefix##ArrayLast (const prefix##Array *const current)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current != NULL);\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current->count > 0);\t\t\t\t\t\t\t\t\t\\\n\t\treturn current->array [current->count - 1];\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern void prefix##ArrayClear (prefix##Array *const current)\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current != NULL);\t\t\t\t\t\t\t\t\t\t\\\n\t\tcurrent->count = 0;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern void prefix##ArrayDelete (prefix##Array *const current)\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (current != NULL)\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tprefix##ArrayClear (current);\t\t\t\t\t\t\t\t\\\n\t\t\teFree (current->array);\t\t\t\t\t\t\t\t\t\t\\\n\t\t\teFree (current);\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern bool prefix##ArrayHasTest (const prefix##Array *const current, \\\n\t\t\t\t\t\t\t\t\t  bool (*test)(const type num, void *userData),\t\\\n\t\t\t\t\t\t\t\t\t  void *userData)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tbool result = false;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int i;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current != NULL);\t\t\t\t\t\t\t\t\t\t\\\n\t\tfor (i = 0  ;  ! result  &&  i < current->count  ;  ++i)\t\t\\\n\t\t\tresult = (*test)(current->array [i], userData);\t\t\t\t\\\n\t\treturn result;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstatic bool prefix##Eq (const type num, void *userData)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\ttype *num0 = userData;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn (num == *num0);\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern bool prefix##ArrayHas (const prefix##Array *const current, type num)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn prefix##ArrayHasTest (current, prefix##Eq, &num);\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern void prefix##ArrayReverse (const prefix##Array *const current) \\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int i, j;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\ttype tmp;\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (current != NULL);\t\t\t\t\t\t\t\t\t\t\\\n\t\tfor (i = 0, j = current->count - 1 ; i <  (current->count / 2); ++i, --j) \\\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\ttmp = current->array[i];\t\t\t\t\t\t\t\t\t\\\n\t\t\tcurrent->array[i] = current->array[j];\t\t\t\t\t\t\\\n\t\t\tcurrent->array[j] = tmp;\t\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern void prefix##ArrayDeleteItem (prefix##Array* const current, unsigned int indx) \\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tmemmove (current->array + indx, current->array + indx + 1,\t\t\\\n\t\t\t\t (current->count - indx - 1) * sizeof (*current->array)); \\\n\t\t--current->count;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstatic int prefix##GreaterThan(const void *a, const void *b)\t\t\\\n    {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\ttype an = *(type *)a;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\ttype bn = *(type *)b;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (an > bn)\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\treturn 1;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\telse if (an == bn)\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\treturn 0;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\telse\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\treturn -1;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstatic int prefix##LessThan(const void *a, const void *b)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn prefix##GreaterThan (b, a);\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern void prefix##ArraySort (prefix##Array *const current, bool descendingOrder) \\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (descendingOrder)\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tqsort (current->array, current->count, sizeof (type), prefix##GreaterThan); \\\n\t\telse\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tqsort (current->array, current->count, sizeof (type), prefix##LessThan); \\\n\t}\n\n/* We expect the linker we use is enough clever to delete dead code. */\nimpNumArray(char, Char, char)\nimpNumArray(uchar, Uchar, unsigned char)\nimpNumArray(int, Int, int)\nimpNumArray(uint, Uint, unsigned int)\nimpNumArray(long, Long, long)\nimpNumArray(ulong, Ulong, unsigned long)\n"
  },
  {
    "path": "main/numarray.h",
    "content": "/*\n*   Copyright (c) 1999-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines external interface to resizable pointer arrays.\n*/\n#ifndef CTAGS_MAIN_NUMARRAY_H\n#define CTAGS_MAIN_NUMARRAY_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n\n#define declNumArray(prefix,Prefix,type)\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstruct s##Prefix##Array;\t\t\t\t\t\t\t\t\t\t\t\\\n\ttypedef struct s##Prefix##Array prefix##Array;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\textern prefix##Array *prefix##ArrayNew (void);\t\t\t\t\t\t\\\n\textern unsigned int prefix##ArrayAdd (prefix##Array *const current, type num); \\\n\textern type prefix##ArrayRemoveLast (prefix##Array *const current);\t\\\n\textern void prefix##ArrayCombine (prefix##Array *const current, prefix##Array *const from);\t\\\n\textern void prefix##ArrayClear (prefix##Array *const current);\t\t\\\n\textern unsigned int prefix##ArrayCount (const prefix##Array *const current); \\\n\textern bool prefix##ArrayIsEmpty(const prefix##Array *const current); \\\n\textern type prefix##ArrayItem (const prefix##Array *const current, const unsigned int indx); \\\n\textern type prefix##ArrayLast (const prefix##Array *const current); \\\n\textern void prefix##ArrayDelete (prefix##Array *const current);\t\t\\\n\textern bool prefix##ArrayHasTest (const prefix##Array *const current, \\\n\t\t\t\t\t\t\t\t\t  bool (*test)(const type num, void *userData), \\\n\t\t\t\t\t\t\t\t\t  void *userData);\t\t\t\t\t\\\n\textern bool prefix##ArrayHas (const prefix##Array *const current, type num); \\\n\textern void prefix##ArrayReverse (const prefix##Array *const current); \\\n\textern void prefix##ArrayDeleteItem (prefix##Array* const current, unsigned int indx); \\\n\t\\\n\textern void prefix##ArraySort (prefix##Array *const current, bool descendingOrder);\n\ndeclNumArray(char, Char, char)\ndeclNumArray(uchar, Uchar, unsigned char)\ndeclNumArray(int, Int, int)\ndeclNumArray(uint, Uint, unsigned int)\ndeclNumArray(long, Long, long)\ndeclNumArray(ulong, Ulong, unsigned long)\n\n#endif  /* CTAGS_MAIN_NUMARRAY_H */\n"
  },
  {
    "path": "main/objpool.c",
    "content": "/*\n*   Copyright (c) 2016, Jiri Techet\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines generic pool for object reuse reducing the amount of allocations\n*   and deallocations.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"debug.h\"\n#include \"routines.h\"\n#include \"objpool.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\n\nstruct sObjPool {\n\tptrArray *array;\n\tunsigned int size;\n\tobjPoolCreateFunc createFunc;\n\tobjPoolDeleteFunc deleteFunc;\n\tobjPoolClearFunc clearFunc;\n\tvoid *createArg;\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nextern objPool *objPoolNew (unsigned int size,\n\tobjPoolCreateFunc createFunc, objPoolDeleteFunc deleteFunc, objPoolClearFunc clearFunc,\n\tvoid *createArg)\n{\n\tobjPool* const result = xMalloc (1, objPool);\n\tresult->array = ptrArrayNew (deleteFunc);\n\tresult->size = size;\n\tresult->createFunc = createFunc;\n\tresult->deleteFunc = deleteFunc;\n\tresult->clearFunc = clearFunc;\n\tresult->createArg = createArg;\n\treturn result;\n}\n\nextern void objPoolDelete (objPool *pool)\n{\n\tptrArrayDelete (pool->array);\n\teFree (pool);\n}\n\nextern void *objPoolGet (objPool *pool)\n{\n\tvoid *obj;\n\n\tif (ptrArrayCount (pool->array) > 0)\n\t{\n\t\tobj = ptrArrayLast (pool->array);\n\t\tptrArrayRemoveLast (pool->array);\n\t}\n\telse\n\t\tobj = pool->createFunc (pool->createArg);\n\n\tif (pool->clearFunc)\n\t\tpool->clearFunc (obj);\n\n\treturn obj;\n}\n\nextern void objPoolPut (objPool *pool, void *obj)\n{\n\tif (obj == NULL)\n\t\treturn;\n\n\tif (\n#ifdef DISABLE_OBJPOOL\n\t\t0 &&\n#endif\n\t\tptrArrayCount (pool->array) < pool->size\n\t\t)\n\t\tptrArrayAdd (pool->array, obj);\n\telse\n\t\tpool->deleteFunc (obj);\n}\n"
  },
  {
    "path": "main/objpool.h",
    "content": "/*\n*   Copyright (c) 2016, Jiri Techet\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines generic pool for object reuse reducing the amount of allocations\n*   and deallocations.\n*/\n#ifndef CTAGS_MAIN_OBJPOOL_H\n#define CTAGS_MAIN_OBJPOOL_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"ptrarray.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef void * (*objPoolCreateFunc) (void *createArg);\ntypedef void (*objPoolDeleteFunc) (void *data);\ntypedef void (*objPoolClearFunc) (void *data);\n\nstruct sObjPool;\ntypedef struct sObjPool objPool;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern objPool *objPoolNew (unsigned int size,\n\tobjPoolCreateFunc createFunc, objPoolDeleteFunc deleteFunc, objPoolClearFunc clearFunc,\n\tvoid *createArg);\nextern void objPoolDelete (objPool *pool);\nextern void *objPoolGet (objPool *pool);\nextern void objPoolPut (objPool *pool, void *obj);\n\n#endif  /* CTAGS_MAIN_OBJPOOL_H */\n"
  },
  {
    "path": "main/options.c",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions to process command line options.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#define OPTION_WRITE\n#include \"options_p.h\"\n\n#ifndef _GNU_SOURCE\n# define _GNU_SOURCE   /* for asprintf */\n#endif\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <ctype.h>  /* to declare isspace () */\n\n#include \"ctags.h\"\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"field_p.h\"\n#include \"gvars.h\"\n#include \"keyword_p.h\"\n#include \"parse_p.h\"\n#include \"ptag_p.h\"\n#include \"routines_p.h\"\n#include \"xtag_p.h\"\n#include \"param_p.h\"\n#include \"param.h\"\n#include \"error_p.h\"\n#include \"interactive_p.h\"\n#include \"writer_p.h\"\n#include \"trace.h\"\n#include \"flags_p.h\"\n\n#ifdef HAVE_JANSSON\n#include <jansson.h>\n#endif\n\n/*\n*   MACROS\n*/\n#define INVOCATION  \"Usage: %s [options] [file(s)]\\n\"\n\n#define CTAGS_ENVIRONMENT  \"CTAGS\"\n#define ETAGS_ENVIRONMENT  \"ETAGS\"\n\n#ifndef ETAGS\n# define ETAGS\t\"etags\"  /* name which causes default use of to -e */\n#endif\n\n/*  The following separators are permitted for list options.\n */\n#define EXTENSION_SEPARATOR '.'\n#define REXPR_START '%'\n#define REXPR_STOP '%'\n#define PATTERN_START '('\n#define PATTERN_STOP  ')'\n#define IGNORE_SEPARATORS   \", \\t\\n\"\n\n#ifndef DEFAULT_FILE_FORMAT\n# define DEFAULT_FILE_FORMAT  2\n#endif\n\n#if defined (HAVE_OPENDIR) || defined (HAVE__FINDFIRST)\n# define RECURSE_SUPPORTED\n#endif\n\n#define isCompoundOption(c)  (bool) (strchr (\"fohiILpdDb\", (c)) != NULL)\n\n#define ENTER(STAGE) do {\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tAssert (Stage <= OptionLoadingStage##STAGE);\t\t\t\t\t\\\n\t\tif (Stage != OptionLoadingStage##STAGE)\t\t\t\t\t\t\t\\\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tStage = OptionLoadingStage##STAGE;\t\t\t\t\t\t\t\\\n\t\t\tverbose (\"Entering configuration stage: loading %s\\n\", StageDescription[Stage]); \\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t} while (0)\n\n/*\n*   Data declarations\n*/\n\nenum eOptionLimits {\n\tMaxHeaderExtensions\t= 100,  /* maximum number of extensions in -h option */\n\tMaxSupportedTagFormat = 2\n};\n\ntypedef struct sOptionDescription {\n\tint usedByEtags;\n\tint experimentalOption;\n\tconst char *description;\n} optionDescription;\n\ntypedef void (*parametricOptionHandler) (const char *const option, const char *const parameter);\n\ntypedef const struct {\n\tconst char* name;   /* name of option as specified by user */\n\tparametricOptionHandler handler;  /* routine to handle option */\n\tbool initOnly;   /* option must be specified before any files */\n\tunsigned long acceptableStages;\n} parametricOption;\n\ntypedef const struct sBooleanOption {\n\tconst char* name;   /* name of option as specified by user */\n\tbool* pValue;    /* pointer to option value */\n\tbool initOnly;   /* option must be specified before any files */\n\tunsigned long acceptableStages;\n\tvoid (* set) (const struct sBooleanOption *const option, bool value);\n} booleanOption;\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic bool NonOptionEncountered = false;\nstatic stringList *OptionFiles;\n\ntypedef stringList searchPathList;\nstatic searchPathList *OptlibPathList;\n\nstatic stringList *Excluded, *ExcludedException;\nstatic bool FilesRequired = true;\nstatic bool SkipConfiguration;\n\nstatic const char *const HeaderExtensions [] = {\n\t\"h\", \"H\", \"hh\", \"hpp\", \"hxx\", \"h++\", \"inc\", \"def\", NULL\n};\n\nlong ctags_debugLevel = 0L;\nbool ctags_verbose = false;\n\noptionValues Option = {\n\t.append = false,\n\t.backward = false,\n\t.etags = false,\n\t.locate =\n#ifdef MACROS_USE_PATTERNS\n\tEX_PATTERN\n#else\n\tEX_MIX\n#endif\n\t,\n\t.recurse = false,\n\t.sorted = SO_SORTED,\n\t.xref = false,\n\t.customXfmt = NULL,\n\t.fileList = NULL,\n\t.tagFileName = NULL,\n\t.headerExt = NULL,\n\t.etagsInclude = NULL,\n\t.tagFileFormat = DEFAULT_FILE_FORMAT,\n#ifdef HAVE_ICONV\n\t.inputEncoding= NULL,\n\t.outputEncoding = NULL,\n#endif\n\t.language = LANG_AUTO,\n\t.followLinks = true,\n\t.filter = false,\n\t.filterTerminator = NULL,\n\t.tagRelative = TREL_NO,\n\t.printTotals = 0,\n\t.lineDirectives = false,\n\t.printLanguage =false,\n\t.guessLanguageEagerly = false,\n\t.quiet = false,\n\t.fatalWarnings = false,\n\t.patternLengthLimit = 96,\n\t.putFieldPrefix = false,\n\t.maxRecursionDepth = 0xffffffff,\n\t.interactive = false,\n\t.fieldsReset = false,\n#ifdef _WIN32\n\t.useSlashAsFilenameSeparator = FILENAME_SEP_UNSET,\n#endif\n#ifdef DEBUG\n\t.breakLine = 0,\n#endif\n};\n\nstruct localOptionValues {\n\tbool machinable;\t\t\t/* --machinable */\n\tbool withListHeader;\t\t/* --with-list-header */\n} localOption = {\n\t.machinable = false,\n\t.withListHeader = true,\n};\n\ntypedef enum eOptionLoadingStage {\n\tOptionLoadingStageNone,\n\tOptionLoadingStageCustom,\n\tOptionLoadingStageXdg,\n\tOptionLoadingStageHomeDir,\n\tOptionLoadingStageCurrentDir,\n\tOptionLoadingStageEnvVar,\n\tOptionLoadingStageCmdline,\n} OptionLoadingStage;\n\nstatic OptionLoadingStage Stage = OptionLoadingStageNone;\n#define STAGE_ANY ~0UL\n\n/*\n-   Locally used only\n*/\n\nstatic optionDescription LongOptionDescription [] = {\n {1,0,\"Input/Output Options\"},\n {1,0,\"  --exclude=<pattern>\"},\n {1,0,\"       Exclude files and directories matching <pattern>.\"},\n {1,0,\"       See also --exclude-exception option.\"},\n {1,0,\"  --exclude-exception=<pattern>\"},\n {1,0,\"      Don't exclude files and directories matching <pattern> even if\"},\n {1,0,\"      they match the pattern specified with --exclude option.\"},\n {1,0,\"  --filter[=(yes|no)]\"},\n {1,0,\"       Behave as a filter, reading file names from standard input and\"},\n {1,0,\"       writing tags to standard output [no].\"},\n {1,0,\"  --filter-terminator=<string>\"},\n {1,0,\"       Specify <string> to print to stdout following the tags for each file\"},\n {1,0,\"       parsed when --filter is enabled.\"},\n {1,0,\"  --links[=(yes|no)]\"},\n {1,0,\"       Indicate whether symbolic links should be followed [yes].\"},\n {1,0,\"  --maxdepth=<N>\"},\n#ifdef RECURSE_SUPPORTED\n {1,0,\"       Specify maximum recursion depth.\"},\n#else\n {1,0,\"       Not supported on this platform.\"},\n#endif\n {1,0,\"  --recurse[=(yes|no)]\"},\n#ifdef RECURSE_SUPPORTED\n {1,0,\"       Recurse into directories supplied on command line [no].\"},\n {1,0,\"  -R   Equivalent to --recurse.\"},\n#else\n {1,0,\"       Not supported on this platform.\"},\n {1,0,\"  -R   Not supported on this platform.\"},\n#endif\n {1,0,\"  -L <file>\"},\n {1,0,\"       A list of input file names is read from the specified <file>.\"},\n {1,0,\"       If specified as \\\"-\\\", then standard input is read.\"},\n {1,0,\"  --append[=(yes|no)]\"},\n {1,0,\"       Should tags should be appended to existing tag file [no]?\"},\n {1,0,\"  -a   Append the tags to an existing tag file.\"},\n {1,0,\"  -f <tagfile>\"},\n {1,0,\"       Write tags to specified <tagfile>. Value of \\\"-\\\" writes tags to stdout\"},\n {1,0,\"       [\\\"tags\\\"; or \\\"TAGS\\\" when -e supplied].\"},\n {1,0,\"  -o   Alternative for -f.\"},\n {1,0,\"\"},\n {1,0,\"Output Format Options\"},\n {0,0,\"  --format=(1|2)\"},\n#if DEFAULT_FILE_FORMAT == 1\n {0,0,\"       Force output of specified tag file format [1].\"},\n#else\n {0,0,\"       Force output of specified tag file format [2].\"},\n#endif\n#ifdef HAVE_JANSSON\n {0,0,\"  --output-format=(u-ctags|e-ctags|etags|xref|json)\"},\n#else\n {0,0,\"  --output-format=(u-ctags|e-ctags|etags|xref)\"},\n#endif\n {0,0,\"      Specify the output format. [u-ctags]\"},\n {0,0,\"  -e   Output tag file for use with Emacs.\"},\n {1,0,\"  -x   Print a tabular cross reference file to standard output.\"},\n {0,0,\"  --sort=(yes|no|foldcase)\"},\n {0,0,\"       Should tags be sorted (optionally ignoring case) [yes]?\"},\n {0,0,\"  -u   Equivalent to --sort=no.\"},\n {1,0,\"  --etags-include=<file>\"},\n {1,0,\"       Include reference to <file> in Emacs-style tag file (requires -e).\"},\n#ifdef HAVE_ICONV\n {1,0,\"  --input-encoding=<encoding>\"},\n {1,0,\"       Specify <encoding> of all input files.\"},\n {1,0,\"  --input-encoding-<LANG>=<encoding>\"},\n {1,0,\"       Specify <encoding> of the <LANG> input files.\"},\n {1,0,\"  --output-encoding=<encoding>\"},\n {1,0,\"       The <encoding> to write the tag file in. Defaults to UTF-8 if --input-encoding\"},\n {1,0,\"       is specified, otherwise no conversion is performed.\"},\n#endif\n {1,1,\"  --_xformat=<field_format>\"},\n {1,1,\"       Specify custom format for tabular cross reference (-x).\"},\n {1,1,\"       Fields can be specified with letter listed in --list-fields. [%-16N %-10K %4n %-16F %C]\"},\n {1,1,\"       e.g. --_xformat=%10N %10l:%K @ %-20F:%-20n\"},\n {1,0,\"\"},\n {1,0,\"Language Selection and Mapping Options\"},\n {1,0,\"  --language-force=(<language>|auto)\"},\n {1,0,\"       Force all files to be interpreted using specified <language>.\"},\n {1,0,\"  --languages=[+|-](<list>|all)\"},\n {1,0,\"       Restrict files scanned for tags to those mapped to languages\"},\n {1,0,\"       specified in the comma-separated <list>. The list can contain any\"},\n {1,0,\"       built-in or user-defined language [all].\"},\n {1,0,\"  --alias-<LANG>=[+|-](<pattern>|default)\"},\n {1,0,\"       Add a <pattern> detecting a name, can be used as an alternative name\"},\n {1,0,\"       for <LANG>.\"},\n {1,0,\"  --guess-language-eagerly\"},\n {1,0,\"       Guess the language of input file more eagerly\"},\n {1,0,\"       (but taking longer time for guessing):\"},\n {1,0,\"       o shebang, even if the input file is not executable,\"},\n {1,0,\"       o emacs mode specification at the beginning and end of input file, and\"},\n {1,0,\"       o vim syntax specification at the end of input file.\"},\n {1,0,\"  -G   Equivalent to --guess-language-eagerly.\"},\n {1,0,\"  --langmap=<map>[,<map>[...]]\"},\n {1,0,\"       Override default mapping of language to input file extension.\"},\n {1,0,\"       e.g. --langmap=c:.c.x,java:+.j,make:([Mm]akefile).mak\"},\n {1,0,\"  --map-<LANG>=[+|-]<extension>|<pattern>|<rexpr>\"},\n {1,0,\"       Set, add(+) or remove(-) the map for <LANG>.\"},\n {1,0,\"       Unlike --langmap, this doesn't take a list; only one file name <pattern>,\"},\n {1,0,\"       one file name <extension>, or one file <rexpr> can be specified at once.\"},\n {1,0,\"       Unlike --langmap the change with this option affects mapping of <LANG> only.\"},\n {1,0,\"\"},\n {1,0,\"Tags File Contents Options\"},\n {0,0,\"  --excmd=(number|pattern|mix|combine)\"},\n#ifdef MACROS_USE_PATTERNS\n {0,0,\"       Uses the specified type of EX command to locate tags [pattern].\"},\n#else\n {0,0,\"       Uses the specified type of EX command to locate tags [mix].\"},\n#endif\n {0,0,\"  -n   Equivalent to --excmd=number.\"},\n {0,0,\"  -N   Equivalent to --excmd=pattern.\"},\n {1,0,\"  --extras=[+|-][<flags>|*]\"},\n {1,0,\"       Include extra tag entries for selected information (<flags>: \\\"fFgpqrs\\\") [F].\"},\n {1,0,\"  --extras-(<LANG>|all)=[+|-][<flags>|*]\"},\n {1,0,\"       Include <LANG> own extra tag entries for selected information\"},\n {1,0,\"       (<flags>: see the output of --list-extras=<LANG> option).\"},\n {1,0,\"  --fields=[+|-][<flags>|*]\"},\n {1,0,\"       Include selected extension fields (<flags>: \\\"aCeEfFikKlmnNpPrRsStxzZ\\\") [fks].\"},\n {1,0,\"  --fields-(<LANG>|all)=[+|-][<flags>|*]\"},\n {1,0,\"       Include selected <LANG> own extension fields\"},\n {1,0,\"       (<flags>: see the output of --list-fields=<LANG> option).\"},\n {1,0,\"  --kinds-(<LANG>|all)=[+|-](<kinds>|*)\"},\n {1,0,\"       Enable/disable tag <kinds> for language <LANG>.\"},\n {0,0,\"  --pattern-length-limit=<N>\"},\n {0,0,\"      Cutoff patterns of tag entries after <N> characters. Disable by setting to 0. [96]\"},\n {0,0,\"  --pseudo-tags=[+|-](<pseudo-tag>|*)\"},\n {0,0,\"       Enable/disable emitting pseudo tag named <pseudo-tag>.\"},\n {0,0,\"       if '*' is given, enable emitting all pseudo tags.\"},\n {0,0,\"  --put-field-prefix\"},\n {0,0,\"       Put \\\"\" CTAGS_FIELD_PREFIX \"\\\" as prefix for the name of fields newly introduced in\"},\n {0,0,\"       universal-ctags.\"},\n {1,0,\"  --roles-(<LANG>|all).(<kind>|*)=[+|-][<roles>|*]\"},\n {1,0,\"       Enable/disable tag roles for kinds of language <LANG>.\"},\n {0,0,\"  --tag-relative=(yes|no|always|never)\"},\n {0,0,\"       Should paths be relative to location of tag file [no; yes when -e]?\"},\n {0,0,\"       always: be relative even if input files are passed in with absolute paths\" },\n {0,0,\"       never:  be absolute even if input files are passed in with relative paths\" },\n#ifdef _WIN32\n {1,0,\"  --use-slash-as-filename-separator[=(yes|no)]\"},\n {1,0,\"       Use slash as filename separator [yes] for u-ctags output format.\"},\n#endif\n {0,0,\"  -B   Use backward searching patterns (?...?).\"},\n {0,0,\"  -F   Use forward searching patterns (/.../; default).\"},\n {1,0,\"\"},\n {1,0,\"Option File Options\"},\n {1,0,\"  --options=<pathname>\"},\n {1,0,\"       Specify file (or directory) <pathname> from which command line options should be read.\"},\n {1,0,\"  --options-maybe=<pathname>\"},\n {1,0,\"       Do the same as --options but this doesn't make an error for non-existing file.\"},\n {1,0,\"  --optlib-dir=[+]<directory>\"},\n {1,0,\"       Add or set <directory> to optlib search path.\"},\n {1,1,\"  --_echo=<msg>\"},\n {1,1,\"       Echo <msg> to standard error. Useful to debug the chain\"},\n {1,1,\"       of loading option files.\"},\n {1,1,\"  --_force-quit[=<num>]\"},\n {1,1,\"       Quit when loading the option files is processed.\"},\n {1,1,\"       Useful to debug the chain of loading option files.\"},\n {1,0,\"\"},\n {1,0,\"optlib Options\"},\n {1,0,\"  --kinddef-<LANG>=<letter>,<name>,<description>\"},\n {1,0,\"       Define new kind for <LANG>.\"},\n {1,0,\"  --langdef=<name>\"},\n {1,0,\"       Define a new language to be parsed with regular expressions.\"},\n {1,0,\"  --mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]\"},\n {1,0,\"       Define multiline regular expression for locating tags in specific language.\"},\n {1,0,\"  --regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]\"},\n {1,0,\"       Define single-line regular expression for locating tags in specific language.\"},\n {1,1,\"  --_extradef-<LANG>=<name>,<description>\"},\n {1,1,\"       Define new extra for <LANG>. --extras-<LANG>=+{name} enables it.\"},\n {1,1,\"  --_fielddef-<LANG>=<name>,<description>\"},\n {1,1,\"       Define new field for <LANG>.\"},\n {1,1,\"  --_mtable-extend-<LANG>=disttable+srctable.\"},\n {1,1,\"       Copy patterns of a regex table to another regex table.\"},\n {1,1,\"  --_mtable-regex-<LANG>=<table>/<line_pattern>/<name_pattern>/[<flags>]\"},\n {1,1,\"       Define multitable regular expression for locating tags in specific language.\"},\n {1,1,\"  --_paramdef-<LANG>=<name>,<description>\"},\n {1,1,\"       Define new param for <LANG>.\"},\n {1,1,\"  --_prelude-<LANG>={{ optscript-code }}\"},\n {1,1,\"       Specify code run before parsing with <LANG> parser.\"},\n {1,1,\"  --_pretend-<NEWLANG>=<OLDLANG>\"},\n {1,1,\"       Make NEWLANG parser pretend OLDLANG parser in lang: field.\"},\n {1,1,\"  --_roledef-<LANG>.<kind>=<name>,<description>\"},\n {1,1,\"       Define new role for the kind in <LANG>.\"},\n {1,1,\"  --_scopesep-<LANG>=[<parent_kind_letter>|*]/(<child_kind_letter>|*):<separator>\"},\n {1,1,\"       Specify scope separator between <PARENT_KIND> and <KIND>.\"},\n {1,1,\"  --_sequel-<LANG>={{ optscript-code }}\"},\n {1,1,\"       Specify code run after parsing with <LANG> parser.\"},\n {1,1,\"  --_tabledef-<LANG>=<name>\"},\n {1,1,\"       Define new regex table for <LANG>.\"},\n {1,0,\"\"},\n {1,0,\"Language Specific Options\"},\n {1,0,\"  --if0[=(yes|no)]\"},\n {1,0,\"       Should code within #if 0 conditional branches be parsed [no]?\"},\n {0,0,\"  --line-directives[=(yes|no)]\"},\n {0,0,\"       Should '#line' directives be processed [no]?\"},\n {1,0,\"  -D <macro>=<definition>\"},\n {1,0,\"       (CPreProcessor) Give <definition> for <macro>.\"},\n {1,0,\"  -h (<list>|default)\"},\n {1,0,\"       Specify a <list> of file extensions to be treated as include files\"},\n {1,0,\"       [\\\".h.H.hh.hpp.hxx.h++.inc.def\\\"].\"},\n {1,0,\"  -I [+|-]<list>|@<file>\"},\n {1,0,\"       A <list> of tokens to be specially handled is read from either the\"},\n {1,0,\"       command line or the specified <file>.\"},\n {1,0,\"  --param-<LANG>.<name>=<argument>\"},\n {1,0,\"       Set <LANG> specific parameter. Available parameters can be listed with --list-params.\"},\n {1,0,\"\"},\n {1,0,\"Listing Options\"},\n {1,0,\"  --list-aliases[=(<language>|all)]\"},\n {1,0,\"       Output list of alias patterns.\"},\n {1,0,\"  --list-excludes\"},\n {1,0,\"       Output list of exclude patterns for excluding files/directories.\"},\n {1,0,\"  --list-extras[=(<language>|all)]\"},\n {1,0,\"       Output list of extra tag flags.\"},\n {1,0,\"  --list-features\"},\n {1,0,\"       Output list of compiled features.\"},\n {1,0,\"  --list-fields[=(<language>|all)]\"},\n {1,0,\"       Output list of fields.\"},\n {1,0,\"  --list-kinds[=(<language>|all)]\"},\n {1,0,\"       Output a list of all tag kinds for specified <language> or all.\"},\n {1,0,\"  --list-kinds-full[=(<language>|all)]\"},\n {1,0,\"       List the details of all tag kinds for specified <language> or all\"},\n {1,0,\"       For each line, associated language name is printed when \\\"all\\\" is\"},\n {1,0,\"       specified as language.\"},\n {1,0,\"  --list-languages\"},\n {1,0,\"       Output list of supported languages.\"},\n {1,0,\"  --list-map-extensions[=(<language>|all)]\"},\n {1,0,\"       Output list of language extensions in mapping.\"},\n {1,0,\"  --list-map-patterns[=(<language>|all)]\"},\n {1,0,\"       Output list of language patterns in mapping.\"},\n {1,0,\"  --list-map-rexprs[=(<language>|all)]\"},\n {1,0,\"       Output list of language regular expressions in mapping.\"},\n {1,0,\"  --list-maps[=(<language>|all)]\"},\n {1,0,\"       Output list of language mappings (both extensions and patterns).\"},\n {1,0,\"  --list-mline-regex-flags\"},\n {1,0,\"       Output list of flags which can be used in a multiline regex parser definition.\"},\n {1,0,\"  --list-output-formats\"},\n {1,0,\"       Output list of output formats.\"},\n {1,0,\"  --list-params[=(<language>|all)]\"},\n {1,0,\"       Output list of language parameters. This works with --machinable.\"},\n {0,0,\"  --list-pseudo-tags\"},\n {0,0,\"       Output list of pseudo tags.\"},\n {1,0,\"  --list-regex-flags\"},\n {1,0,\"       Output list of flags which can be used in a regex parser definition.\"},\n {1,0,\"  --list-roles[=(<language>|all)[.(<kindspecs>|*)]]\"},\n {1,0,\"       Output list of all roles of tag kind(s) specified for <language>.\"},\n {1,0,\"       Both letters and names can be used in <kindspecs>.\"},\n {1,0,\"       e.g. --list-roles=C.{header}d\"},\n {1,0,\"  --list-subparsers[=(<baselang>|all)]\"},\n {1,0,\"       Output list of subparsers for the base language.\"},\n {1,0,\"  --machinable[=(yes|no)]\"},\n {1,0,\"       Use tab separated representation in --list-* option output. [no]\"},\n {1,0,\"       --list-{aliases,extras,features,fields,kind-full,langdef-flags,params,\" },\n {1,0,\"       pseudo-tags,regex-flags,roles,subparsers} support this option.\"},\n {1,0,\"       Suitable for scripting. Specify before --list-* option.\"},\n {1,0,\"  --with-list-header[=(yes|no)]\"},\n {1,0,\"       Prepend the column descriptions in --list- output. [yes]\"},\n {1,0,\"       --list-{aliases,extras,features,fields,kind-full,langdef-flags,params,\" },\n {1,0,\"       pseudo-tags,regex-flags,roles,subparsers} support this option.\"},\n {1,0,\"       Specify before --list-* option.\"},\n {1,1,\"  --_list-extradef-flags\"},\n {1,1,\"       Output list of flags which can be used with --extradef option.\"},\n {1,1,\"  --_list-fielddef-flags\"},\n {1,1,\"       Output list of flags which can be used with --fielddef option.\"},\n {1,1,\"  --_list-kinddef-flags\"},\n {1,1,\"       Output list of flags which can be used with --kinddef option.\"},\n {1,1,\"  --_list-langdef-flags\"},\n {1,1,\"       Output list of flags which can be used with --langdef option.\"},\n {1,1,\"  --_list-mtable-regex-flags\"},\n {1,1,\"       Output list of flags which can be used in a multitable regex parser definition.\"},\n {1,1,\"  --_list-operators\"},\n {1,1,\"       Output list of optscript operators.\"},\n {1,1,\"  --_list-roledef-flags\"},\n {1,1,\"       Output list of flags which can be used with --roledef option.\"},\n {1,0,\"\"},\n {1,0,\"Miscellaneous Options\"},\n {1,0,\"  --describe-language=<language>\"},\n {1,0,\"       Print the various aspects of the parser implementing the language.\"},\n {1,0,\"  --help\"},\n {1,0,\"       Print this option summary.\"},\n {1,0,\"  -?   Print this option summary.\"},\n {1,0,\"  --help-full\"},\n {1,0,\"       Print this option summary including experimental features.\"},\n {1,0,\"  --license\"},\n {1,0,\"       Print details of software license.\"},\n {0,0,\"  --print-language\"},\n {0,0,\"       Don't make tags file but just print the guessed language name for\"},\n {0,0,\"       input file.\"},\n {1,0,\"  --quiet[=(yes|no)]\"},\n {0,0,\"       Don't print NOTICE class messages [no].\"},\n {1,0,\"  --totals[=(yes|no|extra)]\"},\n {1,0,\"       Print statistics about input and tag files [no].\"},\n {1,0,\"  --verbose[=(yes|no)]\"},\n {1,0,\"       Enable verbose messages describing actions on each input file.\"},\n {1,0,\"  --version[=<language>]\"},\n {1,0,\"       Print version identifier of the program to standard output.\"},\n {1,0,\"       Print version identifier of the parser for <language>.\"},\n {1,0,\"  -V   Equivalent to --verbose.\"},\n#ifdef DEBUG\n {1,0,\"  -b <line>\"},\n {1,0,\"       Set break line. (for DEBUG)\"},\n {1,0,\"  -d <level>\"},\n {1,0,\"       Set debug level. (for DEBUG)\"},\n#endif\n\n {1,1,\"  --_anonhash=<fname>\"},\n {1,1,\"       Used in u-ctags test harness\"},\n {1,1,\"  --_dump-keywords\"},\n {1,1,\"       Dump keywords of initialized parser(s).\"},\n {1,1,\"  --_dump-options\"},\n {1,1,\"       Dump options.\"},\n {1,1,\"  --_dump-prelude\"},\n {1,1,\"       Dump contents of optscript prelude.\"},\n {1,1,\"  --_fatal-warnings\"},\n {1,1,\"       Make all warnings fatal.\"},\n {1,1,\"  --_force-initializing\"},\n {1,1,\"       Initialize all parsers in early stage\"},\n#ifdef HAVE_JANSSON\n {0,1,\"  --_interactive\"\n#ifdef HAVE_SECCOMP\n  \"[=(default|sandbox)]\"\n#endif\n },\n {0,1,\"       Enter interactive mode (JSON over stdio).\"},\n#ifdef HAVE_SECCOMP\n {0,1,\"       Enter file I/O limited interactive mode if sandbox is specified. [default]\"},\n#endif\n#endif\n#ifdef DO_TRACING\n {1,1,\"  --_trace=<list>\"},\n {1,1,\"       Trace parsers for the languages.\"},\n#endif\n {1,1, NULL}\n};\n\nstatic const char* const License1 =\n\"This program is free software; you can redistribute it and/or\\n\"\n\"modify it under the terms of the GNU General Public License\\n\"\n\"as published by the Free Software Foundation; either version 2\"\n\"of the License, or (at your option) any later version.\\n\"\n\"\\n\";\nstatic const char* const License2 =\n\"This program is distributed in the hope that it will be useful,\\n\"\n\"but WITHOUT ANY WARRANTY; without even the implied warranty of\\n\"\n\"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\\n\"\n\"GNU General Public License for more details.\\n\"\n\"\\n\"\n\"You should have received a copy of the GNU General Public License\\n\"\n\"along with this program; if not, write to the Free Software\\n\"\n\"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\\n\";\n\n/*  Contains a set of strings describing the set of \"features\" compiled into\n *  the code.\n */\nstatic struct Feature {\n\tconst char *name;\n\tconst char *description;\n} Features [] = {\n#ifdef _WIN32\n\t{\"win32\", \"TO BE WRITTEN\"},\n#endif\n\t/* Following two features are always available on universal ctags */\n\t{\"wildcards\", \"can use glob matching\"},\n\t{\"regex\", \"can use regular expression based pattern matching\"},\n#ifdef USE_GNULIB_FNMATCH\n\t{\"gnulib_fnmatch\", \"linked with the Gnulib fnmatch library\"},\n#endif\n/* https://lists.gnu.org/archive/html/bug-gnulib/2011-07/msg00435.html */\n#ifdef _REGEX_INCLUDE_LIMITS_H\n\t{\"gnulib_regex\", \"linked with the Gnulib regular expression library\"},\n#endif\n#ifndef EXTERNAL_SORT\n\t{\"internal-sort\", \"uses internal sort routine instead of invoking sort command\"},\n#endif\n#ifdef CUSTOM_CONFIGURATION_FILE\n\t{\"custom-conf\", \"read \\\"\" CUSTOM_CONFIGURATION_FILE \"\\\" as config file\"},\n#endif\n#if defined (_WIN32)\n\t{\"unix-path-separator\", \"can use '/' as file name separator\"},\n#endif\n#ifdef HAVE_ICONV\n\t{\"iconv\", \"can convert input/output encodings\"},\n#endif\n#ifdef DEBUG\n\t{\"debug\", \"built with debugging features\"},\n#endif\n#if defined (HAVE_DIRENT_H) || defined (_MSC_VER)\n\t{\"option-directory\", \"TO BE WRITTEN\"},\n#endif\n#ifdef HAVE_LIBXML\n\t{\"xpath\", \"linked with library for parsing xml input\"},\n#endif\n#ifdef HAVE_JANSSON\n\t{\"json\", \"supports json format output\"},\n\t{\"interactive\", \"accepts source code from stdin\"},\n#endif\n#ifdef HAVE_SECCOMP\n\t{\"sandbox\", \"linked with code for system call level sandbox\"},\n#endif\n#ifdef HAVE_LIBYAML\n\t{\"yaml\", \"linked with library for parsing yaml input\"},\n#endif\n#ifdef CASE_INSENSITIVE_FILENAMES\n\t{\"case-insensitive-filenames\", \"TO BE WRITTEN\"},\n#endif\n#ifdef ENABLE_GCOV\n\t{\"gcov\", \"linked with code for coverage analysis\"},\n#endif\n#ifdef HAVE_PACKCC\n\t/* The test harnesses use this as hints for skipping test cases */\n\t{\"packcc\", \"has peg based parser(s)\"},\n#ifdef HAVE_PEGOF\n\t{\"pegof\", \"makes peg based parser(s) optimized (experimental)\"},\n#endif\n#endif\n\t{\"optscript\", \"can use the interpreter\"},\n#ifdef HAVE_PCRE2\n\t{\"pcre2\", \"has pcre2 regex engine\"},\n#endif\n\t{NULL,}\n};\n\nstatic const char *const StageDescription [] = {\n\t[OptionLoadingStageNone]   = \"not initialized\",\n\t[OptionLoadingStageCustom] = \"custom file\",\n\t[OptionLoadingStageXdg] = \"file(s) under $XDG_CONFIG_HOME and $HOME/.config\",\n\t[OptionLoadingStageHomeDir] = \"file(s) under $HOME\",\n\t[OptionLoadingStageCurrentDir] = \"file(s) under the current directory\",\n\t[OptionLoadingStageCmdline] = \"command line\",\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nstatic bool parseFileOptions (const char *const fileName);\nstatic bool parseAllConfigurationFilesOptionsInDirectory (const char *const fileName,\n\t\t\t\t\t\t\t     stringList* const already_loaded_files);\nstatic bool getBooleanOption (const char *const option, const char *const parameter);\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n#ifndef HAVE_ASPRINTF\n\n/* Some versions of MinGW are missing _vscprintf's declaration, although they\n * still provide the symbol in the import library.\n */\n#ifdef __MINGW32__\n_CRTIMP int _vscprintf(const char *format, va_list argptr);\n#endif\n\n#ifndef va_copy\n#define va_copy(dest, src) (dest = src)\n#endif\n\nint asprintf(char **strp, const char *fmt, ...)\n{\n\tva_list args;\n\tva_list args_copy;\n\tint length;\n\tsize_t size;\n\n\tva_start(args, fmt);\n\n\tva_copy(args_copy, args);\n\n#ifdef _WIN32\n\t/* We need to use _vscprintf to calculate the length as vsnprintf returns -1\n\t * if the number of characters to write is greater than count.\n\t */\n\tlength = _vscprintf(fmt, args_copy);\n#else\n\tchar dummy;\n\tlength = vsnprintf(&dummy, sizeof dummy, fmt, args_copy);\n#endif\n\n\tva_end(args_copy);\n\n\tAssert(length >= 0);\n\tsize = length + 1;\n\n\t*strp = malloc(size);\n\tif (!*strp) {\n\t\treturn -1;\n\t}\n\n\tva_start(args, fmt);\n\tvsnprintf(*strp, size, fmt, args);\n\tva_end(args);\n\n\treturn length;\n}\n#endif\n\nextern void verbose (const char *const format, ...)\n{\n\tif (ctags_verbose)\n\t{\n\t\tva_list ap;\n\t\tva_start (ap, format);\n\t\tvfprintf (stderr, format, ap);\n\t\tva_end (ap);\n\t}\n}\n\nstatic char *stringCopy (const char *const string)\n{\n\tchar* result = NULL;\n\tif (string != NULL)\n\t\tresult = eStrdup (string);\n\treturn result;\n}\n\nstatic void freeString (char **const pString)\n{\n\tif (*pString != NULL)\n\t{\n\t\teFree (*pString);\n\t\t*pString = NULL;\n\t}\n}\n\nextern void freeList (stringList** const pList)\n{\n\tif (*pList != NULL)\n\t{\n\t\tstringListDelete (*pList);\n\t\t*pList = NULL;\n\t}\n}\n\nextern void setDefaultTagFileName (void)\n{\n\tif (Option.filter || Option.interactive)\n\t\treturn;\n\n\tif (Option.tagFileName == NULL)\n\t{\n\t\tconst char *tmp = outputDefaultFileName ();\n\n\t\tif (tmp == NULL)\n\t\t\ttmp = \"-\";\n\n\t\tOption.tagFileName = stringCopy (tmp);\n\t}\n}\n\nextern bool filesRequired (void)\n{\n\tbool result = FilesRequired;\n\tif (Option.recurse)\n\t\tresult = false;\n\treturn result;\n}\n\nextern void checkOptions (void)\n{\n\tconst char* notice;\n\tif (Option.xref && (Option.customXfmt == NULL))\n\t{\n\t\tnotice = \"xref output\";\n\t\tif (isXtagEnabled(XTAG_FILE_NAMES))\n\t\t{\n\t\t\terror (WARNING, \"%s disables file name tags\", notice);\n\t\t\tenableXtag (XTAG_FILE_NAMES, false);\n\t\t}\n\t}\n\tif (Option.append)\n\t{\n\t\tnotice = \"append mode is not compatible with\";\n\t\tif (isDestinationStdout ())\n\t\t\terror (FATAL, \"%s tags to stdout\", notice);\n\t}\n\tif (Option.filter)\n\t{\n\t\tnotice = \"filter mode\";\n\t\tif (Option.printTotals)\n\t\t{\n\t\t\terror (WARNING, \"%s disables totals\", notice);\n\t\t\tOption.printTotals = 0;\n\t\t}\n\t\tif (Option.tagFileName != NULL)\n\t\t\terror (WARNING, \"%s ignores output tag file name\", notice);\n\t}\n\twriterCheckOptions (Option.fieldsReset);\n}\n\nextern langType getLanguageComponentInOptionFull (const char *const option,\n\t\t\t\t\t\t\t\t\t\t\t\t  const char *const prefix,\n\t\t\t\t\t\t\t\t\t\t\t\t  bool noPretending)\n{\n\tsize_t prefix_len;\n\tlangType language;\n\tconst char *lang;\n\tchar *sep = NULL;\n\tsize_t lang_len = 0;\n\n\tAssert (prefix && prefix[0]);\n\tAssert (option);\n\n\tprefix_len = strlen (prefix);\n\tif (strncmp (option, prefix, prefix_len) != 0)\n\t\treturn LANG_IGNORE;\n\telse\n\t{\n\t\tlang = option + prefix_len;\n\t\tif (lang [0] == '\\0')\n\t\t\treturn LANG_IGNORE;\n\t}\n\n\t/* Extract <LANG> from\n\t * --param-<LANG>.<PARAM>=..., and\n\t * --_roledef-<LANG>.<KIND>=... */\n\n\t/*  `:' is only for keeping self compatibility. */\n\tsep = strpbrk (lang, \":.\");\n\tif (sep)\n\t{\n\t\tif (*sep == ':')\n\t\t\terror (WARNING, \"using `:' as a separator is obsolete; use `.' instead: --%s\", option);\n\t\tlang_len = sep - lang;\n\t}\n\tlanguage = getNamedLanguageFull (lang, lang_len, noPretending, false);\n\tif (language == LANG_IGNORE)\n\t{\n\t\tconst char *langName = (lang_len == 0)? lang: eStrndup (lang, lang_len);\n\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", langName, option);\n\t}\n\n\treturn language;\n}\n\nextern langType getLanguageComponentInOption (const char *const option,\n\t\t\t\t\t\t\t\t\t\t\t  const char *const prefix)\n{\n\treturn getLanguageComponentInOptionFull (option, prefix, false);\n}\n\nstatic void setEtagsMode (void)\n{\n\tOption.etags = true;\n\tOption.sorted = SO_UNSORTED;\n\tOption.lineDirectives = false;\n\tOption.tagRelative = TREL_YES;\n\tenableLanguage (LANG_FALLBACK, true);\n\tsetTagWriter (WRITER_ETAGS, NULL);\n}\n\nextern void testEtagsInvocation (void)\n{\n\tchar* const execName = eStrdup (getExecutableName ());\n\tchar* const etags = eStrdup (ETAGS);\n#ifdef CASE_INSENSITIVE_FILENAMES\n\ttoLowerString (execName);\n\ttoLowerString (etags);\n#endif\n\tif (strstr (execName, etags) != NULL)\n\t{\n\t\tverbose (\"Running in etags mode\\n\");\n\t\tsetEtagsMode ();\n\t}\n\teFree (execName);\n\teFree (etags);\n}\n\nstatic void setXrefMode (void)\n{\n\tOption.xref = true;\n\tsetTagWriter (WRITER_XREF, NULL);\n}\n\n#ifdef HAVE_JANSSON\nstatic void setJsonMode (void)\n{\n\tenablePtag (PTAG_JSON_OUTPUT_VERSION, true);\n\tenablePtag (PTAG_OUTPUT_MODE, false);\n\tenablePtag (PTAG_FILE_FORMAT, false);\n\tsetTagWriter (WRITER_JSON, NULL);\n}\n#endif\n\n/*\n *  Cooked argument parsing\n */\n\nstatic void parseShortOption (cookedArgs *const args)\n{\n\targs->simple [0] = *args->shortOptions++;\n\targs->simple [1] = '\\0';\n\targs->item = eStrdup (args->simple);\n\tif (! isCompoundOption (*args->simple))\n\t\targs->parameter = \"\";\n\telse if (*args->shortOptions == '\\0')\n\t{\n\t\targForth (args->args);\n\t\tif (argOff (args->args))\n\t\t\targs->parameter = NULL;\n\t\telse\n\t\t\targs->parameter = argItem (args->args);\n\t\targs->shortOptions = NULL;\n\t}\n\telse\n\t{\n\t\targs->parameter = args->shortOptions;\n\t\targs->shortOptions = NULL;\n\t}\n}\n\nstatic void parseLongOption (cookedArgs *const args, const char *item)\n{\n\tconst char* const equal = strchr (item, '=');\n\tif (equal == NULL)\n\t{\n\t\targs->item = eStrdup (item);\n\t\targs->parameter = \"\";\n\t}\n\telse\n\t{\n\t\targs->item = eStrndup (item, equal - item);\n\t\targs->parameter = equal + 1;\n\t}\n\tAssert (args->item != NULL);\n\tAssert (args->parameter != NULL);\n}\n\nstatic void cArgRead (cookedArgs *const current)\n{\n\tchar* item;\n\n\tAssert (current != NULL);\n\tif (! argOff (current->args))\n\t{\n\t\titem = argItem (current->args);\n\t\tcurrent->shortOptions = NULL;\n\t\tAssert (item != NULL);\n\t\tif (strncmp (item, \"--\", (size_t) 2) == 0)\n\t\t{\n\t\t\tcurrent->isOption = true;\n\t\t\tcurrent->longOption = true;\n\t\t\tparseLongOption (current, item + 2);\n\t\t\tAssert (current->item != NULL);\n\t\t\tAssert (current->parameter != NULL);\n\t\t}\n\t\telse if (*item == '-')\n\t\t{\n\t\t\tcurrent->isOption = true;\n\t\t\tcurrent->longOption = false;\n\t\t\tcurrent->shortOptions = item + 1;\n\t\t\tparseShortOption (current);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcurrent->isOption = false;\n\t\t\tcurrent->longOption = false;\n\t\t\tcurrent->item = eStrdup (item);\n\t\t\tcurrent->parameter = NULL;\n\t\t}\n\t}\n}\n\nextern cookedArgs* cArgNewFromString (const char* string)\n{\n\tcookedArgs* const result = xMalloc (1, cookedArgs);\n\tmemset (result, 0, sizeof (cookedArgs));\n\tresult->args = argNewFromString (string);\n\tcArgRead (result);\n\treturn result;\n}\n\nextern cookedArgs* cArgNewFromArgv (char* const* const argv)\n{\n\tcookedArgs* const result = xMalloc (1, cookedArgs);\n\tmemset (result, 0, sizeof (cookedArgs));\n\tresult->args = argNewFromArgv (argv);\n\tcArgRead (result);\n\treturn result;\n}\n\nextern cookedArgs* cArgNewFromFile (FILE* const fp)\n{\n\tcookedArgs* const result = xMalloc (1, cookedArgs);\n\tmemset (result, 0, sizeof (cookedArgs));\n\tresult->args = argNewFromFile (fp);\n\tcArgRead (result);\n\treturn result;\n}\n\nextern cookedArgs* cArgNewFromLineFile (FILE* const fp)\n{\n\tcookedArgs* const result = xMalloc (1, cookedArgs);\n\tmemset (result, 0, sizeof (cookedArgs));\n\tresult->args = argNewFromLineFile (fp);\n\tcArgRead (result);\n\treturn result;\n}\n\nextern void cArgDelete (cookedArgs* const current)\n{\n\tAssert (current != NULL);\n\targDelete (current->args);\n\tif (current->item != NULL)\n\t\teFree (current->item);\n\tmemset (current, 0, sizeof (cookedArgs));\n\teFree (current);\n}\n\nstatic bool cArgOptionPending (cookedArgs* const current)\n{\n\tbool result = false;\n\tif (current->shortOptions != NULL)\n\t\tif (*current->shortOptions != '\\0')\n\t\t\tresult = true;\n\treturn result;\n}\n\nextern bool cArgOff (cookedArgs* const current)\n{\n\tAssert (current != NULL);\n\treturn (bool) (argOff (current->args) && ! cArgOptionPending (current));\n}\n\nextern bool cArgIsOption (cookedArgs* const current)\n{\n\tAssert (current != NULL);\n\treturn current->isOption;\n}\n\nextern const char* cArgItem (cookedArgs* const current)\n{\n\tAssert (current != NULL);\n\treturn current->item;\n}\n\nextern void cArgForth (cookedArgs* const current)\n{\n\tAssert (current != NULL);\n\tAssert (! cArgOff (current));\n\tif (current->item != NULL)\n\t\teFree (current->item);\n\tif (cArgOptionPending (current))\n\t\tparseShortOption (current);\n\telse\n\t{\n\t\tAssert (! argOff (current->args));\n\t\targForth (current->args);\n\t\tif (! argOff (current->args))\n\t\t\tcArgRead (current);\n\t\telse\n\t\t{\n\t\t\tcurrent->isOption = false;\n\t\t\tcurrent->longOption = false;\n\t\t\tcurrent->shortOptions = NULL;\n\t\t\tcurrent->item = NULL;\n\t\t\tcurrent->parameter = NULL;\n\t\t}\n\t}\n}\n\n/*\n *  File extension and language mapping\n */\n\nstatic void addExtensionList (\n\t\tstringList *const slist, const char *const elist, const bool clear)\n{\n\tchar *const extensionList = eStrdup (elist);\n\tconst char *extension = NULL;\n\tbool first = true;\n\n\tif (clear)\n\t{\n\t\tverbose (\"      clearing\\n\");\n\t\tstringListClear (slist);\n\t}\n\tverbose (\"      adding: \");\n\tif (elist != NULL  &&  *elist != '\\0')\n\t{\n\t\textension = extensionList;\n\t\tif (elist [0] == EXTENSION_SEPARATOR)\n\t\t\t++extension;\n\t}\n\twhile (extension != NULL)\n\t{\n\t\tchar *separator = strchr (extension, EXTENSION_SEPARATOR);\n\t\tif (separator != NULL)\n\t\t\t*separator = '\\0';\n\t\tverbose (\"%s%s\", first ? \"\" : \", \",\n\t\t\t\t*extension == '\\0' ? \"(NONE)\" : extension);\n\t\tstringListAdd (slist, vStringNewInit (extension));\n\t\tfirst = false;\n\t\tif (separator == NULL)\n\t\t\textension = NULL;\n\t\telse\n\t\t\textension = separator + 1;\n\t}\n\tBEGIN_VERBOSE(vfp);\n\t{\n\t\tfprintf (vfp, \"\\n      now: \");\n\t\tstringListPrint (slist, vfp);\n\t\tputc ('\\n', vfp);\n\t}\n\tEND_VERBOSE();\n}\n\nstatic bool isFalse (const char *parameter)\n{\n\treturn (bool) (\n\t\tstrcasecmp (parameter, \"0\"  ) == 0  ||\n\t\tstrcasecmp (parameter, \"n\"  ) == 0  ||\n\t\tstrcasecmp (parameter, \"no\" ) == 0  ||\n\t\tstrcasecmp (parameter, \"off\") == 0  ||\n\t\tstrcasecmp (parameter, \"false\") == 0 );\n}\n\nstatic bool isTrue (const char *parameter)\n{\n\treturn (bool) (\n\t\tstrcasecmp (parameter, \"1\"  ) == 0  ||\n\t\tstrcasecmp (parameter, \"y\"  ) == 0  ||\n\t\tstrcasecmp (parameter, \"yes\") == 0  ||\n\t\tstrcasecmp (parameter, \"on\" ) == 0  ||\n\t\tstrcasecmp (parameter, \"true\" ) == 0);\n}\n\nextern bool paramParserBool (const char *value, bool fallback,\n\t\t\t\t\t\t\t const char *errWhat, const char *errCategory)\n{\n\tbool r = fallback;\n\n\tif (value [0] == '\\0')\n\t\tr = true;\n\telse if (isFalse (value))\n\t\tr = false;\n\telse if (isTrue (value))\n\t\tr = true;\n\telse\n\t\terror (FATAL, \"Invalid value for \\\"%s\\\" %s\", errWhat, errCategory);\n\n\treturn r;\n}\n\n/*  Determines whether the specified file name is considered to be a header\n *  file for the purposes of determining whether enclosed tags are global or\n *  static.\n */\nextern bool isIncludeFile (const char *const fileName)\n{\n\tbool result = false;\n\tconst char *const extension = fileExtension (fileName);\n\tif (Option.headerExt != NULL)\n\t\tresult = stringListExtensionMatched (Option.headerExt, extension);\n\treturn result;\n}\n\n/*\n *  Specific option processing\n */\n\nstatic void processEtagsInclude (\n\t\tconst char *const option, const char *const parameter)\n{\n\tif (! Option.etags)\n\t\terror (FATAL, \"Etags must be enabled to use \\\"%s\\\" option\", option);\n\telse\n\t{\n\t\tvString *const file = vStringNewInit (parameter);\n\t\tif (Option.etagsInclude == NULL)\n\t\t\tOption.etagsInclude = stringListNew ();\n\t\tstringListAdd (Option.etagsInclude, file);\n\t\tFilesRequired = false;\n\t}\n}\n\nstatic void processExcludeOptionCommon (\n\tstringList** list, const char *const optname, const char *const parameter)\n{\n\tconst char *const fileName = parameter + 1;\n\tif (parameter [0] == '\\0')\n\t\tfreeList (list);\n\telse if (parameter [0] == '@')\n\t{\n\t\tstringList* const sl = stringListNewFromFile (fileName);\n\t\tif (sl == NULL)\n\t\t\terror (FATAL | PERROR, \"cannot open \\\"%s\\\"\", fileName);\n\t\tif (*list == NULL)\n\t\t\t*list = sl;\n\t\telse\n\t\t\tstringListCombine (*list, sl);\n\t\tverbose (\"    adding %s patterns from %s\\n\", optname, fileName);\n\t}\n\telse\n\t{\n\t\tvString *const item = vStringNewInit (parameter);\n#if defined (_WIN32)\n\t\tvStringTranslate(item, PATH_SEPARATOR, OUTPUT_PATH_SEPARATOR);\n#endif\n\t\tif (*list == NULL)\n\t\t\t*list = stringListNew ();\n\t\tstringListAdd (*list, item);\n\t\tverbose (\"    adding %s pattern: %s\\n\", optname, parameter);\n\t}\n}\n\nstatic void processExcludeOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tprocessExcludeOptionCommon (&Excluded, option, parameter);\n}\n\nstatic void processExcludeExceptionOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tprocessExcludeOptionCommon (&ExcludedException, option, parameter);\n}\n\nextern bool isExcludedFile (const char* const name,\n\t\t\t\t\t\t\tbool falseIfExceptionsAreDefined)\n{\n\tconst char* base = baseFilename (name);\n\tbool result = false;\n\n\tif (falseIfExceptionsAreDefined\n\t\t&& ExcludedException != NULL\n\t\t&& stringListCount (ExcludedException) > 0)\n\t\treturn false;\n\n\tif (Excluded != NULL)\n\t{\n\t\tresult = stringListFileMatched (Excluded, base);\n\t\tif (! result  &&  name != base)\n\t\t\tresult = stringListFileMatched (Excluded, name);\n\t}\n\n\tif (result && ExcludedException != NULL)\n\t{\n\t\tbool result_exception;\n\n\t\tresult_exception = stringListFileMatched (ExcludedException, base);\n\t\tif (! result_exception && name != base)\n\t\t\tresult_exception = stringListFileMatched (ExcludedException, name);\n\n\t\tif (result_exception)\n\t\t\tresult = false;\n\t}\n\treturn result;\n}\n\nstatic void processExcmdOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tswitch (*parameter)\n\t{\n\t\tcase 'm': Option.locate = EX_MIX;     break;\n\t\tcase 'n': Option.locate = EX_LINENUM; break;\n\t\tcase 'p': Option.locate = EX_PATTERN; break;\n\t\tdefault:\n\t\t\tif (strcmp(parameter, \"combine\") == 0)\n\t\t\t\tOption.locate = EX_COMBINE;\n\t\t\telse\n\t\t\t\terror (FATAL, \"Invalid value for \\\"%s\\\" option: %s\", option, parameter);\n\t\t\tbreak;\n\t}\n}\n\nstatic void resetXtags (langType lang, bool mode)\n{\n\tfor (unsigned int i = 0; i < countXtags (); i++)\n\t\tif ((lang == LANG_AUTO) || (lang == getXtagLanguage (i)))\n\t\t\tenableXtag (i, mode);\n}\n\nstatic void processExtraTagsOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\txtagType t;\n\tconst char *p = parameter;\n\tbool mode = true;\n\tint c;\n\tstatic vString *longName;\n\tbool inLongName = false;\n\tconst char *x;\n\n\tif (strcmp (option, \"extra\") == 0)\n\t\terror(WARNING, \"--extra option is obsolete; use --extras instead\");\n\n\tif (*p == '*')\n\t{\n\t\tresetXtags (LANG_IGNORE, true);\n\t\tp++;\n\t}\n\telse if (*p != '+'  &&  *p != '-')\n\t\tresetXtags (LANG_IGNORE, false);\n\n\tlongName = vStringNewOrClearWithAutoRelease (longName);\n\n\twhile ((c = (unsigned char) *p++) != '\\0')\n\t{\n\t\tswitch (c)\n\t\t{\n\t\tcase '+':\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\tmode = true;\n\t\t\tbreak;\n\t\tcase '-':\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\tmode = false;\n\t\t\tbreak;\n\t\tcase '{':\n\t\t\tif (inLongName)\n\t\t\t\terror(FATAL,\n\t\t\t\t      \"unexpected character in extra specification: \\'%c\\'\",\n\t\t\t\t      c);\n\t\t\tinLongName = true;\n\t\t\tbreak;\n\t\tcase '}':\n\t\t\tif (!inLongName)\n\t\t\t\terror(FATAL,\n\t\t\t\t      \"unexpected character in extra specification: \\'%c\\'\",\n\t\t\t\t      c);\n\t\t\tx = vStringValue (longName);\n\t\t\tt = getXtagTypeForNameAndLanguage (x, LANG_IGNORE);\n\n\t\t\tif (t == XTAG_UNKNOWN)\n\t\t\t\terror(WARNING, \"Unsupported parameter '{%s}' for \\\"%s\\\" option\",\n\t\t\t\t      x, option);\n\t\t\telse\n\t\t\t\tenableXtag (t, mode);\n\n\t\t\tinLongName = false;\n\t\t\tvStringClear (longName);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t{\n\t\t\t\tt = getXtagTypeForLetter (c);\n\t\t\t\tif (t == XTAG_UNKNOWN)\n\t\t\t\t\terror(WARNING, \"Unsupported parameter '%c' for \\\"%s\\\" option\",\n\t\t\t\t\t      c, option);\n\t\t\t\telse\n\t\t\t\t\tenableXtag (t, mode);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic void resetFieldsOption (langType lang, bool mode)\n{\n\tfor (unsigned int i = 0; i < countFields (); ++i)\n\t\tif ((lang == LANG_AUTO) || (lang == getFieldLanguage (i)))\n\t\t\tenableField (i, mode);\n\n\tif ((lang == LANG_AUTO || lang == LANG_IGNORE)&& !mode)\n\t\tOption.fieldsReset = true;\n}\n\nstatic void processFieldsOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tconst char *p = parameter;\n\tbool mode = true;\n\tint c;\n\tfieldType t;\n\n\tstatic vString * longName;\n\tbool inLongName = false;\n\n\tlongName = vStringNewOrClearWithAutoRelease (longName);\n\n\tif (*p == '*')\n\t{\n\t\tresetFieldsOption (LANG_IGNORE, true);\n\t\tp++;\n\t}\n\telse if (*p != '+'  &&  *p != '-')\n\t\tresetFieldsOption (LANG_IGNORE, false);\n\n\twhile ((c = (unsigned char) *p++) != '\\0') switch (c)\n\t{\n\t\tcase '+':\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\tmode = true;\n\t\t\tbreak;\n\t\tcase '-':\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\tmode = false;\n\t\t\tbreak;\n\t\tcase '{':\n\t\t\tif (inLongName)\n\t\t\t\terror(FATAL,\n\t\t\t\t      \"unexpected character in field specification: \\'%c\\'\",\n\t\t\t\t      c);\n\t\t\tinLongName = true;\n\t\t\tbreak;\n\t\tcase '}':\n\t\t\tif (!inLongName)\n\t\t\t\terror(FATAL,\n\t\t\t\t      \"unexpected character in field specification: \\'%c\\'\",\n\t\t\t\t      c);\n\n\t\t\t{\n\t\t\t\tconst char *f = vStringValue (longName);\n\t\t\t\tt = getFieldTypeForNameAndLanguage (f, LANG_IGNORE);\n\t\t\t}\n\n\t\t\tif (t == FIELD_UNKNOWN)\n\t\t\t\terror(FATAL, \"no such field: \\'%s\\'\", vStringValue (longName));\n\n\t\t\tenableField (t, mode);\n\n\t\t\tinLongName = false;\n\t\t\tvStringClear (longName);\n\t\t\tbreak;\n\t\tdefault :\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t{\n\t\t\t\tt = getFieldTypeForLetter (c);\n\t\t\t\tif (t == FIELD_UNKNOWN)\n\t\t\t\t\terror(WARNING, \"Unsupported parameter '%c' for \\\"%s\\\" option\",\n\t\t\t\t\t      c, option);\n\t\t\t\telse\n\t\t\t\t\tenableField (t, mode);\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n\nstatic void processFilterTerminatorOption (\n\t\tconst char *const option CTAGS_ATTR_UNUSED, const char *const parameter)\n{\n\tfreeString (&Option.filterTerminator);\n\tOption.filterTerminator = stringCopy (parameter);\n}\n\nstatic void processFormatOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tunsigned int format;\n\n\tif (sscanf (parameter, \"%u\", &format) < 1)\n\t\terror (FATAL, \"Invalid value for \\\"%s\\\" option\",option);\n\telse if (format <= (unsigned int) MaxSupportedTagFormat)\n\t\tOption.tagFileFormat = format;\n\telse\n\t\terror (FATAL, \"Unsupported value for \\\"%s\\\" option\", option);\n}\n\n#ifdef HAVE_ICONV\nstatic void processInputEncodingOption(const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\tconst char *const parameter)\n{\n\tif (Option.inputEncoding)\n\t\teFree (Option.inputEncoding);\n\telse\n\t{\n\t\tif (!Option.outputEncoding)\n\t\t\tOption.outputEncoding = eStrdup(\"UTF-8\");\n\t}\n\tOption.inputEncoding = eStrdup(parameter);\n}\n\nstatic void processOutputEncodingOption(const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\tconst char *const parameter)\n{\n\tif (Option.outputEncoding)\n\t\teFree (Option.outputEncoding);\n\tOption.outputEncoding = eStrdup(parameter);\n}\n#endif\n\nstatic void printInvocationDescription (void)\n{\n\tprintf (INVOCATION, getExecutableName ());\n}\n\nstatic int excludesCompare (struct colprintLine *a, struct colprintLine *b)\n{\n\treturn strcmp (colprintLineGetColumn (a, 0), colprintLineGetColumn (b, 0));\n}\n\nstatic void processListExcludesOption(const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t      const char *const parameter CTAGS_ATTR_UNUSED)\n{\n\tstruct colprintTable *table = colprintTableNew (\"L:NAME\", NULL);\n\n\tconst unsigned int max = Excluded ? stringListCount (Excluded) : 0;\n\n\tfor (unsigned int i = 0; i < max; ++i)\n\t{\n\t\tstruct colprintLine * line = colprintTableGetNewLine (table);\n\t\tcolprintLineAppendColumnVString (line, stringListItem (Excluded, i));\n\t}\n\n\tcolprintTableSort (table, excludesCompare);\n\tcolprintTablePrint (table, 0, localOption.withListHeader, localOption.machinable, stdout);\n\tcolprintTableDelete (table);\n\n\t/* No line is printed. */\n\tif (max == 0)\n\t\tputchar ('\\n');\n\n\texit (0);\n}\n\n\nstatic void printFeatureList (void)\n{\n\tint i;\n\n\tfor (i = 0 ; Features [i].name != NULL ; ++i)\n\t{\n\t\tif (i == 0)\n\t\t\tprintf (\"  Optional compiled features: \");\n\t\tif (strcmp (Features [i].name, \"regex\") != 0 || checkRegex ())\n\t\t\tprintf (\"%s+%s\", (i>0 ? \", \" : \"\"), Features [i].name);\n#ifdef CUSTOM_CONFIGURATION_FILE\n\t\tif (strcmp (Features [i].name, \"custom-conf\") == 0)\n\t\t\tprintf (\"=%s\", CUSTOM_CONFIGURATION_FILE);\n#endif\n\t}\n\tif (i > 0)\n\t\tputchar ('\\n');\n}\n\n\nstatic int featureCompare (struct colprintLine *a, struct colprintLine *b)\n{\n\treturn strcmp (colprintLineGetColumn (a, 0),\n\t\t\t\t   colprintLineGetColumn (b, 0));\n}\n\nstatic void processListFeaturesOption(const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t      const char *const parameter CTAGS_ATTR_UNUSED)\n{\n\tint i;\n\n\tstruct colprintTable *table = colprintTableNew (\"L:NAME\", \"L:DESCRIPTION\", NULL);\n\n\tfor (i = 0 ; Features [i].name != NULL ; ++i)\n\t{\n\t\tstruct colprintLine * line = colprintTableGetNewLine (table);\n\t\tif (strcmp (Features [i].name, \"regex\") != 0 || checkRegex ())\n\t\t{\n\t\t\tcolprintLineAppendColumnCString (line, Features [i].name);\n\t\t\tcolprintLineAppendColumnCString (line, Features [i].description);\n\t\t}\n\n\t}\n\n\tcolprintTableSort (table, featureCompare);\n\tcolprintTablePrint (table, 0, localOption.withListHeader, localOption.machinable, stdout);\n\tcolprintTableDelete (table);\n\n\tif (i == 0)\n\t\tputchar ('\\n');\n\texit (0);\n}\n\nstatic void processListFieldsOption(const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t    const char *const parameter)\n{\n\t/* Before listing, adjust states of enabled/disabled for fixed fields. */\n\twriterCheckOptions (Option.fieldsReset);\n\n\tstruct colprintTable * table = fieldColprintTableNew ();\n\n\tif (parameter [0] == '\\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)\n\t{\n\t\tfieldColprintAddCommonLines (table);\n\n\t\tinitializeParser (LANG_AUTO);\n\t\tfor (unsigned int i = 0; i < countParsers (); i++)\n\t\t{\n\t\t\tif (isLanguageVisible(i))\n\t\t\t\tfieldColprintAddLanguageLines (table, i);\n\t\t}\n\t}\n\telse if (strcasecmp (parameter, RSV_NONE) == 0)\n\t\tfieldColprintAddCommonLines (table);\n\telse\n\t{\n\t\tlangType language = getNamedLanguage (parameter, 0);\n\t\tif (language == LANG_IGNORE)\n\t\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", parameter, option);\n\n\t\tinitializeParser (language);\n\t\tfieldColprintAddLanguageLines (table, language);\n\t}\n\n\tfieldColprintTablePrint (table, localOption.withListHeader, localOption.machinable, stdout);\n\tcolprintTableDelete (table);\n\texit (0);\n}\n\nstatic void printProgramIdentification (void)\n{\n\tif ((ctags_repoinfo == NULL)\n\t    || (strcmp (ctags_repoinfo, PROGRAM_VERSION) == 0))\n\t\tprintf (\"%s %s, %s %s\\n\",\n\t\t\tPROGRAM_NAME, PROGRAM_VERSION,\n\t\t\tPROGRAM_COPYRIGHT, AUTHOR_NAME);\n\telse\n\t\tprintf (\"%s %s(%s), %s %s\\n\",\n\t\t\tPROGRAM_NAME, PROGRAM_VERSION, ctags_repoinfo,\n\t\t\tPROGRAM_COPYRIGHT, AUTHOR_NAME);\n\tprintf (\"Universal Ctags is derived from Exuberant Ctags.\\n\");\n\tprintf (\"Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert\\n\");\n\n\tprintf (\"  Compiled: %s, %s\\n\", __DATE__, __TIME__);\n\tprintf (\"  URL: %s\\n\", PROGRAM_URL);\n\tprintf (\"  Output version: %d.%d\\n\",\n\t\t\tOUTPUT_VERSION_CURRENT, OUTPUT_VERSION_AGE);\n\n\tprintFeatureList ();\n}\n\nstatic void processHelpOptionCommon (\n\t\tconst char *const option CTAGS_ATTR_UNUSED,\n\t\tconst char *const parameter CTAGS_ATTR_UNUSED,\n\t\tbool includingExperimentalOptions)\n{\n\tprintProgramIdentification ();\n\tputchar ('\\n');\n\tprintInvocationDescription ();\n\tputchar ('\\n');\n\n\tint i;\n\tfor (i = 0 ; LongOptionDescription [i].description != NULL ; ++i)\n\t{\n\t\tif ((! Option.etags || LongOptionDescription [i].usedByEtags)\n\t\t\t&& (! LongOptionDescription [i].experimentalOption || includingExperimentalOptions))\n\t\t\tputs (LongOptionDescription [i].description);\n\t}\n}\n\nstatic void processHelpOption (\n\t\tconst char *const option,\n\t\tconst char *const parameter)\n{\n\tprocessHelpOptionCommon (option, parameter, false);\n\texit (0);\n}\n\nstatic void processHelpFullOption (\n\t\tconst char *const option,\n\t\tconst char *const parameter)\n{\n\tprocessHelpOptionCommon (option, parameter, true);\n\texit (0);\n}\n\n#ifdef HAVE_JANSSON\nstatic void processInteractiveOption (\n\t\tconst char *const option CTAGS_ATTR_UNUSED,\n\t\tconst char *const parameter)\n{\n\tstatic struct interactiveModeArgs args;\n\n\n\tif (parameter && (strcmp (parameter, \"sandbox\") == 0))\n\t{\n\t\tOption.interactive = INTERACTIVE_SANDBOX;\n\t\targs.sandbox = true;\n\t}\n\telse if (parameter && (strcmp (parameter, \"default\") == 0))\n\t{\n\t\tOption.interactive = INTERACTIVE_DEFAULT;\n\t\targs.sandbox = false;\n\t}\n\telse if ((!parameter) || *parameter == '\\0')\n\t{\n\t\tOption.interactive = INTERACTIVE_DEFAULT;\n\t\targs.sandbox = false;\n\t}\n\telse\n\t\terror (FATAL, \"Unknown option argument \\\"%s\\\" for --%s option\",\n\t\t\t   parameter, option);\n\n#ifndef HAVE_SECCOMP\n\tif (args.sandbox)\n\t\terror (FATAL, \"sandbox submode is not supported on this platform\");\n#endif\n\n#ifdef ENABLE_GCOV\n\tif (args.sandbox)\n\t\terror (FATAL, \"sandbox submode does not work if gcov is instrumented\");\n#endif\n\n\tOption.sorted = SO_UNSORTED;\n\tsetMainLoop (interactiveLoop, &args);\n\tsetErrorPrinter (jsonErrorPrinter, NULL);\n\tsetTagWriter (WRITER_JSON, NULL);\n\tenablePtag (PTAG_JSON_OUTPUT_VERSION, true);\n\n\tjson_set_alloc_funcs (eMalloc, eFree);\n}\n#endif\n\nstatic void processIf0Option (const char *const option,\n\t\t\t\t\t\t\t  const char *const parameter)\n{\n\tbool if0 = getBooleanOption (option, parameter);\n\tlangType lang = getNamedLanguage (\"CPreProcessor\", 0);\n\tconst char *arg = if0? \"true\": \"false\";\n\n\tapplyLanguageParam (lang, \"if0\", arg);\n}\n\nstatic void processLanguageForceOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tlangType language;\n\tif (strcasecmp (parameter, RSV_LANG_AUTO) == 0)\n\t\tlanguage = LANG_AUTO;\n\telse\n\t\tlanguage = getNamedLanguage (parameter, 0);\n\n\tif (strcmp (option, \"lang\") == 0  ||  strcmp (option, \"language\") == 0)\n\t\terror (WARNING,\n\t\t\t   \"\\\"--%s\\\" option is obsolete; use \\\"--language-force\\\" instead\",\n\t\t\t   option);\n\tif (language == LANG_IGNORE)\n\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", parameter, option);\n\telse\n\t\tOption.language = language;\n}\nstatic char* skipPastMap (char* p)\n{\n\twhile (*p != EXTENSION_SEPARATOR  &&\n\t\t\t*p != PATTERN_START  &&  *p != ','  &&  *p != '\\0')\n\t\t++p;\n\treturn p;\n}\n\n/* Parses the mapping beginning at `map', adds it to the language map, and\n * returns first character past the map.\n */\nstatic char* extractMapFromParameter (const langType language,\n\t\t\t\t      char* parameter,\n\t\t\t\t      char** tail,\n\t\t\t\t      langmapType *mapType,\n\t\t\t\t      char* (* skip) (char *))\n{\n\tchar* p = NULL;\n\tconst char first = *parameter;\n\tchar  tmp;\n\tchar* result;\n\n\tif (first == EXTENSION_SEPARATOR)  /* extension map */\n\t{\n\t\t*mapType = LMAP_EXTENSION;\n\n\t\t++parameter;\n\t\tp = (* skip) (parameter);\n\t\tif (*p == '\\0')\n\t\t{\n\t\t\tresult = eStrdup (parameter);\n\t\t\t*tail = parameter + strlen (parameter);\n\t\t\treturn result;\n\t\t}\n\n\t\ttmp = *p;\n\t\t*p = '\\0';\n\t\tresult = eStrdup (parameter);\n\t\t*p = tmp;\n\t\t*tail = p;\n\t\treturn result;\n\t}\n\n\tif (first == PATTERN_START)  /* pattern map */\n\t{\n\t\t*mapType = LMAP_PATTERN;\n\n\t\t++parameter;\n\t\tfor (p = parameter  ;  *p != PATTERN_STOP  &&  *p != '\\0'  ;  ++p)\n\t\t{\n\t\t\tif (*p == '\\\\'  &&  *(p + 1) == PATTERN_STOP)\n\t\t\t\t++p;\n\t\t}\n\t\tif (*p == '\\0')\n\t\t\terror (FATAL, \"Unterminated file name pattern for %s language\",\n\t\t\t   getLanguageName (language));\n\n\t\ttmp = *p;\n\t\t*p = '\\0';\n\t\tresult = eStrdup (parameter);\n\t\t*p = tmp;\n\t\t*tail = p + 1;\n\t\treturn result;\n\t}\n\n\tif (first == REXPR_START)\n\t{\n\t\t*mapType = LMAP_REXPR;\n\n\t\t++parameter;\n\t\tvString *rexpr = vStringNew ();\n\t\tfor (p = parameter  ;  *p != REXPR_STOP  &&  *p != '\\0'  ;  ++p)\n\t\t{\n\t\t\tif (*p == '\\\\'  &&  *(p + 1) == REXPR_STOP)\n\t\t\t\tp++;\n\t\t\tvStringPut (rexpr, *p);\n\t\t}\n\t\tif (*p == '\\0')\n\t\t\terror (FATAL, \"Unterminated file name regular expression for %s language: %s\",\n\t\t\t\t   getLanguageName (language), parameter);\n\n\t\t*tail = p + 1;\n\t\treturn vStringDeleteUnwrap (rexpr);\n\t}\n\n\treturn NULL;\n}\n\nstatic void langmap_rexpr_icase_short (char c CTAGS_ATTR_UNUSED, void* data)\n{\n\tbool *icase = data;\n\t*icase = true;\n}\n\nstatic void langmap_rexpr_icase_long (const char* s CTAGS_ATTR_UNUSED, const char* const unused CTAGS_ATTR_UNUSED, void* data)\n{\n\tlangmap_rexpr_icase_short ('i', data);\n}\n\nstatic flagDefinition langmapRexprFlagDef[] = {\n\t{ 'i', \"icase\",  langmap_rexpr_icase_short,  langmap_rexpr_icase_long,\n\t  NULL, \"applied in a case-insensitive manner\"},\n};\n\nstatic char* addLanguageMap (const langType language, char* map_parameter,\n\t\t\t     bool exclusiveInAllLanguages, bool handleRexpr)\n{\n\tchar* p = NULL;\n\tlangmapType map_type;\n\tchar* map;\n\n\tmap = extractMapFromParameter (language, map_parameter, &p, &map_type, skipPastMap);\n\tif (map && map_type == LMAP_EXTENSION)\n\t\taddLanguageExtensionMap (language, map, exclusiveInAllLanguages);\n\telse if (map && map_type == LMAP_PATTERN)\n\t\taddLanguagePatternMap (language, map, exclusiveInAllLanguages);\n\telse if (handleRexpr && map && map_type == LMAP_REXPR)\n\t{\n\t\tbool icase = false;\n\n\t\tflagsEval (p, langmapRexprFlagDef, ARRAY_SIZE(langmapRexprFlagDef), &icase);\n\t\taddLanguageRexprMap (language, map, icase, exclusiveInAllLanguages);\n\t}\n\telse\n\t\terror (FATAL, \"Badly formed language map for %s language\",\n\t\t\t\tgetLanguageName (language));\n\n\tif (map)\n\t\teFree (map);\n\treturn p;\n}\n\nstatic char* removeLanguageMap (const langType language, char* map_parameter)\n{\n\tchar* p = NULL;\n\tlangmapType map_type;\n\tchar* map;\n\n\tmap = extractMapFromParameter (language, map_parameter, &p, &map_type, skipPastMap);\n\tif (map && map_type == LMAP_EXTENSION)\n\t\tremoveLanguageExtensionMap (language, map);\n\telse if (map && map_type == LMAP_PATTERN)\n\t\tremoveLanguagePatternMap (language, map);\n\telse if (map && map_type == LMAP_REXPR)\n\t{\n\t\tbool icase = false;\n\n\t\tflagsEval (p, langmapRexprFlagDef, ARRAY_SIZE(langmapRexprFlagDef), &icase);\n\t\tremoveLanguageRexprMap (language, map, icase);\n\t}\n\telse\n\t\terror (FATAL, \"Badly formed language map for %s language\",\n\t\t       getLanguageName (language));\n\n\tif (map)\n\t\teFree (map);\n\treturn p;\n}\n\nstatic char* processLanguageMap (char* map)\n{\n\tchar* const separator = strchr (map, ':');\n\tchar* result = NULL;\n\tif (separator != NULL)\n\t{\n\t\tlangType language;\n\t\tchar *list = separator + 1;\n\t\tbool clear = false;\n\t\t*separator = '\\0';\n\t\tlanguage = getNamedLanguage (map, 0);\n\t\tif (language != LANG_IGNORE)\n\t\t{\n\t\t\tconst char *const deflt = RSV_LANGMAP_DEFAULT;\n\t\t\tchar* p;\n\t\t\tif (*list == '+')\n\t\t\t\t++list;\n\t\t\telse\n\t\t\t\tclear = true;\n\t\t\tfor (p = list  ;  *p != ','  &&  *p != '\\0'  ;  ++p)  /*no-op*/ ;\n\t\t\tif ((size_t) (p - list) == strlen (deflt) &&\n\t\t\t\tstrncasecmp (list, deflt, p - list) == 0)\n\t\t\t{\n\t\t\t\tverbose (\"    Restoring default %s language map: \", getLanguageName (language));\n\t\t\t\tinstallLanguageMapDefault (language);\n\t\t\t\tlist = p;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (clear)\n\t\t\t\t{\n\t\t\t\t\tverbose (\"    Setting %s language map:\", getLanguageName (language));\n\t\t\t\t\tclearLanguageMap (language);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tverbose (\"    Adding to %s language map:\", getLanguageName (language));\n\t\t\t\twhile (list != NULL  &&  *list != '\\0'  &&  *list != ',')\n\t\t\t\t\tlist = addLanguageMap (language, list, true, false);\n\t\t\t\tverbose (\"\\n\");\n\t\t\t}\n\t\t\tif (list != NULL  &&  *list == ',')\n\t\t\t\t++list;\n\t\t\tresult = list;\n\t\t}\n\t}\n\treturn result;\n}\n\nstatic void processLanguageMapOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tchar *const maps = eStrdup (parameter);\n\tchar *map = maps;\n\n\tif (strcmp (parameter, RSV_LANGMAP_DEFAULT) == 0)\n\t{\n\t\tverbose (\"    Restoring default language maps:\\n\");\n\t\tinstallLanguageMapDefaults ();\n\t}\n\telse while (map != NULL  &&  *map != '\\0')\n\t{\n\t\tchar* const next = processLanguageMap (map);\n\t\tif (next == NULL)\n\t\t\terror (WARNING, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", parameter, option);\n\t\tmap = next;\n\t}\n\teFree (maps);\n}\n\nstatic void processLanguagesOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tchar *const langs = eStrdup (parameter);\n\tenum { Add, Remove, Replace } mode = Replace;\n\tbool first = true;\n\tchar *lang = langs;\n\tconst char* prefix = \"\";\n\tverbose (\"    Enabled languages: \");\n\twhile (lang != NULL)\n\t{\n\t\tchar *const end = strchr (lang, ',');\n\t\tif (lang [0] == '+')\n\t\t{\n\t\t\t++lang;\n\t\t\tmode = Add;\n\t\t\tprefix = \"+ \";\n\t\t}\n\t\telse if (lang [0] == '-')\n\t\t{\n\t\t\t++lang;\n\t\t\tmode = Remove;\n\t\t\tprefix = \"- \";\n\t\t}\n\t\tif (mode == Replace)\n\t\t\tenableLanguages (false);\n\t\tif (end != NULL)\n\t\t\t*end = '\\0';\n\t\tif (lang [0] != '\\0')\n\t\t{\n\t\t\tif (strcmp (lang, RSV_LANG_ALL) == 0)\n\t\t\t\tenableLanguages ((bool) (mode != Remove));\n\t\t\telse\n\t\t\t{\n\t\t\t\tconst langType language = getNamedLanguage (lang, 0);\n\t\t\t\tif (language == LANG_IGNORE)\n\t\t\t\t\terror (WARNING, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", lang, option);\n\t\t\t\telse\n\t\t\t\t\tenableLanguage (language, (bool) (mode != Remove));\n\t\t\t}\n\t\t\tverbose (\"%s%s%s\", (first ? \"\" : \", \"), prefix, lang);\n\t\t\tprefix = \"\";\n\t\t\tfirst = false;\n\t\t\tif (mode == Replace)\n\t\t\t\tmode = Add;\n\t\t}\n\t\tlang = (end != NULL ? end + 1 : NULL);\n\t}\n\tverbose (\"\\n\");\n\teFree (langs);\n}\n\nextern bool processMapOption (\n\t\t\tconst char *const option, const char *const parameter)\n{\n\tlangType language;\n\tconst char* spec;\n\tchar* map_parameter;\n\tbool clear = false;\n\tchar op;\n\n\tlanguage = getLanguageComponentInOption (option, \"map-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\tif (parameter == NULL || parameter [0] == '\\0')\n\t\terror (FATAL, \"no parameter is given for %s\", option);\n\n\tspec = parameter;\n\tif (*spec == '+' || *spec == '-')\n\t{\n\t\top = *spec;\n\t\tspec++;\n\t}\n\telse\n\t{\n\t\top = '\\0';\n\t\tclear = true;\n\t}\n\n\tif (clear)\n\t{\n\t\tverbose (\"    Setting %s language map:\", getLanguageName (language));\n\t\tclearLanguageMap (language);\n\t\top = '+';\n\t}\n\telse\n\t\tverbose (\"    %s %s %s %s language map:\",\n\t\t\t op == '+'? \"Adding\": \"Removing\",\n\t\t\t spec,\n\t\t\t op == '+'? \"to\": \"from\",\n\t\t\t getLanguageName (language));\n\tmap_parameter = eStrdup (spec);\n\n\tif (op == '+')\n\t\taddLanguageMap (language, map_parameter, false, true);\n\telse if (op == '-')\n\t\tremoveLanguageMap (language, map_parameter);\n\telse\n\t\tAssert (\"Should not reach here\" == NULL);\n\n\teFree (map_parameter);\n\tverbose (\"\\n\");\n\n\treturn true;\n}\n\nstatic void processLicenseOption (\n\t\tconst char *const option CTAGS_ATTR_UNUSED,\n\t\tconst char *const parameter CTAGS_ATTR_UNUSED)\n{\n\tprintProgramIdentification ();\n\tputs (\"\");\n\tputs (License1);\n\tputs (License2);\n\texit (0);\n}\n\nstatic void processListAliasesOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tif (parameter [0] == '\\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)\n\t\tprintLanguageAliases (LANG_AUTO,\n\t\t\t\t\t\t\t  localOption.withListHeader, localOption.machinable, stdout);\n\telse\n\t{\n\t\tlangType language = getNamedLanguage (parameter, 0);\n\t\tif (language == LANG_IGNORE)\n\t\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", parameter, option);\n\t\telse\n\t\t\tprintLanguageAliases (language,\n\t\t\t\t\t\t\t\t  localOption.withListHeader, localOption.machinable, stdout);\n\t}\n\texit (0);\n}\n\nstatic void processListExtrasOption (\n\t\tconst char *const option CTAGS_ATTR_UNUSED, const char *const parameter CTAGS_ATTR_UNUSED)\n{\n\tstruct colprintTable * table = xtagColprintTableNew ();\n\n\tif (parameter [0] == '\\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)\n\t{\n\t\txtagColprintAddCommonLines (table);\n\n\t\tinitializeParser (LANG_AUTO);\n\t\tfor (unsigned int i = 0; i < countParsers (); i++)\n\t\t{\n\t\t\tif (isLanguageVisible(i))\n\t\t\t\txtagColprintAddLanguageLines (table, i);\n\t\t}\n\t}\n\telse if (strcasecmp (parameter, RSV_NONE) == 0)\n\t\txtagColprintAddCommonLines (table);\n\telse\n\t{\n\t\tlangType language = getNamedLanguage (parameter, 0);\n\t\tif (language == LANG_IGNORE)\n\t\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", parameter, option);\n\n\t\tinitializeParser (language);\n\t\txtagColprintAddLanguageLines (table, language);\n\t}\n\n\txtagColprintTablePrint (table, localOption.withListHeader, localOption.machinable, stdout);\n\tcolprintTableDelete (table);\n\texit (0);\n}\n\nstatic void processListKindsOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tbool print_all = (strcmp (option, \"list-kinds-full\") == 0)? true: false;\n\n\tif (parameter [0] == '\\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)\n\t\tprintLanguageKinds (LANG_AUTO, print_all,\n\t\t\t\t\t\t\tlocalOption.withListHeader, localOption.machinable, stdout);\n\telse\n\t{\n\t\tlangType language = getNamedLanguage (parameter, 0);\n\t\tif (language == LANG_IGNORE)\n\t\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", parameter, option);\n\t\telse\n\t\t\tprintLanguageKinds (language, print_all,\n\t\t\t\t\t\t\t\tlocalOption.withListHeader, localOption.machinable, stdout);\n\t}\n\texit (0);\n}\n\nstatic void processListParametersOption (const char *const option,\n\t\t\t\t\t\t\t\t\t\t const char *const parameter)\n{\n\tif (parameter [0] == '\\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)\n\t\tprintLanguageParams (LANG_AUTO,\n\t\t\t\t\t\t\t localOption.withListHeader, localOption.machinable,\n\t\t\t\t\t\t\t stdout);\n\telse\n\t{\n\t\tlangType language = getNamedLanguage (parameter, 0);\n\t\tif (language == LANG_IGNORE)\n\t\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", parameter, option);\n\t\telse\n\t\t\tprintLanguageParams (language,\n\t\t\t\t\t\t\t\t localOption.withListHeader, localOption.machinable,\n\t\t\t\t\t\t\t\t stdout);\n\t}\n\texit (0);\n}\n\n\nstatic void processListMapsOptionForType (const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t\t  const char *const  parameter,\n\t\t\t\t\t  langmapType type)\n{\n\tif (parameter [0] == '\\0' || strcasecmp (parameter, RSV_LANG_ALL) == 0)\n\t\tprintLanguageMaps (LANG_AUTO, type,\n\t\t\t\t\t\t   localOption.withListHeader, localOption.machinable,\n\t\t\t\t\t\t   stdout);\n\telse\n\t{\n\t\tlangType language = getNamedLanguage (parameter, 0);\n\t\tif (language == LANG_IGNORE)\n\t\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", parameter, option);\n\t\telse\n\t\t\tprintLanguageMaps (language, type,\n\t\t\t\t\t\t\t   localOption.withListHeader, localOption.machinable,\n\t\t\t\t\t\t\t   stdout);\n\t}\n\texit (0);\n}\n\nstatic void processListMapExtensionsOption (const char *const option,\n\t\t\t\t\t const char *const parameter)\n{\n\tprocessListMapsOptionForType (option, parameter, LMAP_EXTENSION|LMAP_TABLE_OUTPUT);\n}\n\nstatic void processListMapPatternsOption (const char *const option,\n\t\t\t\t       const char *const parameter)\n{\n\tprocessListMapsOptionForType (option, parameter, LMAP_PATTERN|LMAP_TABLE_OUTPUT);\n}\n\nstatic void processListMapRexprsOption (const char *const option,\n\t\t\t\t       const char *const parameter)\n{\n\tprocessListMapsOptionForType (option, parameter, LMAP_REXPR|LMAP_TABLE_OUTPUT);\n}\n\n\nstatic void processListMapsOption (\n\t\tconst char *const option CTAGS_ATTR_UNUSED,\n\t\tconst char *const parameter CTAGS_ATTR_UNUSED)\n{\n\tprocessListMapsOptionForType (option, parameter, LMAP_ALL);\n}\n\nstatic void processListLanguagesOption (\n\t\tconst char *const option CTAGS_ATTR_UNUSED,\n\t\tconst char *const parameter)\n{\n\tenum parserCategory category = PARSER_CATEGORY_NONE;\n\n\tif (parameter)\n\t{\n\t\tif (strcmp(parameter, \"_libxml\") == 0)\n\t\t\tcategory = PARSER_CATEGORY_LIBXML;\n\t\telse if (strcmp(parameter, \"_libyaml\") == 0)\n\t\t\tcategory = PARSER_CATEGORY_LIBYAML;\n\t\telse if (strcmp(parameter, \"_packcc\") == 0)\n\t\t\tcategory = PARSER_CATEGORY_PACKCC;\n\t}\n\n\tprintLanguageList (category);\n\texit (0);\n}\n\n#define defineListFunctionForOption(target,proc)\t\t\t\t\t\t\\\n\tattr__noreturn\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstatic void processList##target##Option (\t\t\t\t\t\t\t\\\n\t\tconst char *const option CTAGS_ATTR_UNUSED,\t\t\t\t\t\t\\\n\t\tconst char *const parameter CTAGS_ATTR_UNUSED)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tproc (localOption.withListHeader, localOption.machinable, stdout); \\\n\t\texit (0);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t} attr__noreturn static void processList##target##Option (\t\t\t\\\n\t\tconst char *const option CTAGS_ATTR_UNUSED,\t\t\t\t\t\t\\\n\t\tconst char *const parameter CTAGS_ATTR_UNUSED) /* So we cat put ';' at the end of macro expansion. */\n\n#define defineListFunctionForOptionWithParameter(target,proc)\t\t\t\\\n\tattr__noreturn\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstatic void processList##target##Option (\t\t\t\t\t\t\t\\\n\t\tconst char *const option CTAGS_ATTR_UNUSED,\t\t\t\t\t\t\\\n\t\tconst char *const parameter)\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tproc (localOption.withListHeader, localOption.machinable, parameter, stdout); \\\n\t\texit (0);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t} attr__noreturn static void processList##target##Option (\t\t\t\\\n\t\tconst char *const option CTAGS_ATTR_UNUSED,\t\t\t\t\t\t\\\n\t\tconst char *const parameter) /* So we cat put ';' at the end of macro expansion. */\n\ndefineListFunctionForOption (PseudoTags, printPtags);\n\ndefineListFunctionForOptionWithParameter (RegexFlags, printRegexFlags);\ndefineListFunctionForOptionWithParameter (MultilineRegexFlags, printMultilineRegexFlags);\ndefineListFunctionForOptionWithParameter (MultitableRegexFlags, printMultitableRegexFlags);\n\ndefineListFunctionForOption (LangdefFlags, printLangdefFlags);\ndefineListFunctionForOption (KinddefFlags, printKinddefFlags);\ndefineListFunctionForOption (RoledefFlags, printRoledefFlags);\ndefineListFunctionForOption (FielddefFlags, printFielddefFlags);\ndefineListFunctionForOption (ExtradefFlags, printExtradefFlags);\n\ndefineListFunctionForOption (OutputFormats, printOutputFormats);\n\n\nattr__noreturn\nstatic void processListRolesOption (const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t     const char *const parameter)\n{\n\tconst char* sep;\n\tconst char *kindspecs;\n\tlangType lang;\n\n\n\tif (parameter == NULL || parameter[0] == '\\0')\n\t{\n\t\tprintLanguageRoles (LANG_AUTO, \"*\",\n\t\t\t\t\t\t\tlocalOption.withListHeader,\n\t\t\t\t\t\t\tlocalOption.machinable,\n\t\t\t\t\t\t\tstdout);\n\t\texit (0);\n\t}\n\n\tsep = strchr (parameter, '.');\n\n\tif (sep == NULL || sep [1] == '\\0')\n\t{\n\t\tvString* vstr = vStringNewInit (parameter);\n\t\tvStringCatS (vstr, (sep? \"*\": \".*\"));\n\t\tprocessListRolesOption (option, vStringValue (vstr));\n\t\t/* The control should never reached here. */\n\t}\n\n\tkindspecs = sep + 1;\n\tif (strncmp (parameter, \"all.\", 4) == 0\n\t\t/* Handle the case if no language is specified.\n\t\t * This case is not documented. */\n\t    || strncmp (parameter, \".\", 1) == 0)\n\t\tlang = LANG_AUTO;\n\telse\n\t{\n\t\tlang = getNamedLanguage (parameter, sep - parameter);\n\t\tif (lang == LANG_IGNORE)\n\t\t{\n\t\t\tconst char *langName = eStrndup (parameter, sep - parameter);\n\t\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\"\", langName, option);\n\t\t}\n\t}\n\tprintLanguageRoles (lang, kindspecs,\n\t\t\t\t\t\tlocalOption.withListHeader,\n\t\t\t\t\t\tlocalOption.machinable,\n\t\t\t\t\t\tstdout);\n\texit (0);\n}\n\nstatic void processListSubparsersOption (const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t     const char *const parameter)\n{\n\tlangType lang;\n\n\n\tif (parameter == NULL || parameter[0] == '\\0'\n\t\t|| (strcmp(parameter, RSV_LANG_ALL) == 0))\n\t{\n\t\tprintLanguageSubparsers(LANG_AUTO,\n\t\t\t\t\t\t\t\tlocalOption.withListHeader, localOption.machinable,\n\t\t\t\t\t\t\t\tstdout);\n\t\texit (0);\n\t}\n\n\tlang = getNamedLanguage (parameter, 0);\n\tif (lang == LANG_IGNORE)\n\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\"\", parameter, option);\n\n\tprintLanguageSubparsers(lang,\n\t\t\t\t\t\t\tlocalOption.withListHeader, localOption.machinable,\n\t\t\t\t\t\t\tstdout);\n\texit (0);\n}\n\nstatic void processDescribeLanguage(const char *const option,\n\t\t\t\t\t\t\t\t\tconst char *const parameter)\n{\n\t/* Version, enable */\n\tif (parameter == NULL || parameter[0] == '\\0')\n\t\terror (FATAL, \"No language given in \\\"--%s\\\" option\", option);\n\n\n\tlangType language = getNamedLanguage (parameter, 0);\n\tif (language == LANG_IGNORE)\n\t\terror (FATAL, \"Unknown language \\\"--%s\\\" in \\\"%s\\\"\", parameter, option);\n\n\tinitializeParser (language);\n\n\tprintf(\"About %s language\\n\", parameter);\n\tputs(\"=======================================================\");\n\n\tprintf(\"enabled: %s\\n\", isLanguageEnabled(language)? \"yes\": \"no\");\n\tprintf(\"version: %u.%u\\n\",\n\t\t   getLanguageVersionCurrent (language),\n\t\t   getLanguageVersionAge (language));\n\n\tputs(\"\");\n\tputs(\"Mappings/rexprs\");\n\tputs(\"-------------------------------------------------------\");\n\tprintLanguageMaps (language, LMAP_REXPR|LMAP_NO_LANG_PREFIX,\n\t\t\t\t\t   localOption.withListHeader, localOption.machinable,\n\t\t\t\t\t   stdout);\n\n\tputs(\"\");\n\tputs(\"Mappings/patterns\");\n\tputs(\"-------------------------------------------------------\");\n\tprintLanguageMaps (language, LMAP_PATTERN|LMAP_NO_LANG_PREFIX,\n\t\t\t\t\t   localOption.withListHeader, localOption.machinable,\n\t\t\t\t\t   stdout);\n\n\tputs(\"\");\n\tputs(\"Mappings/extensions\");\n\tputs(\"-------------------------------------------------------\");\n\tprintLanguageMaps (language, LMAP_EXTENSION|LMAP_NO_LANG_PREFIX,\n\t\t\t\t\t   localOption.withListHeader, localOption.machinable,\n\t\t\t\t\t   stdout);\n\n\tputs(\"\");\n\tputs(\"Aliases\");\n\tputs(\"-------------------------------------------------------\");\n\tprintLanguageAliases (language,\n\t\t\t\t\t\t  localOption.withListHeader, localOption.machinable, stdout);\n\n\tputs(\"\");\n\tputs(\"Kinds\");\n\tputs(\"-------------------------------------------------------\");\n\n\tprintLanguageKinds (language, true,\n\t\t\t\t\t\tlocalOption.withListHeader, localOption.machinable, stdout);\n\n\tputs(\"\");\n\tputs(\"Roles\");\n\tputs(\"-------------------------------------------------------\");\n\tprintLanguageRoles (language, \"*\",\n\t\t\t\t\t\tlocalOption.withListHeader,\n\t\t\t\t\t\tlocalOption.machinable,\n\t\t\t\t\t\tstdout);\n\n\tputs(\"\");\n\tputs(\"Fields\");\n\tputs(\"-------------------------------------------------------\");\n\t{\n\t\twriterCheckOptions (Option.fieldsReset);\n\t\tstruct colprintTable * table = fieldColprintTableNew ();\n\t\tfieldColprintAddLanguageLines (table, language);\n\t\tfieldColprintTablePrint (table, localOption.withListHeader, localOption.machinable, stdout);\n\t\tcolprintTableDelete (table);\n\t}\n\n\tputs(\"\");\n\tputs(\"Extras\");\n\tputs(\"-------------------------------------------------------\");\n\t{\n\t\tstruct colprintTable * table = xtagColprintTableNew ();\n\t\txtagColprintAddLanguageLines (table, language);\n\t\txtagColprintTablePrint (table, localOption.withListHeader, localOption.machinable, stdout);\n\t\tcolprintTableDelete (table);\n\t}\n\n\tputs(\"\");\n\tputs(\"Parameters\");\n\tputs(\"-------------------------------------------------------\");\n\tprintLanguageParams (language,\n\t\t\t\t\t\t localOption.withListHeader, localOption.machinable,\n\t\t\t\t\t\t stdout);\n\n\tputs (\"\");\n\tputs(\"Sub parsers stacked on this parser\");\n\tputs(\"-------------------------------------------------------\");\n\tprintLanguageSubparsers(language,\n\t\t\t\t\t\t\tlocalOption.withListHeader, localOption.machinable,\n\t\t\t\t\t\t\tstdout);\n\n\tputs(\"\");\n\tputs(\"Implementation specific status\");\n\tputs(\"-------------------------------------------------------\");\n\tprintf(\"allow null tags: %s\\n\", doesLanguageAllowNullTag(language)? \"yes\": \"no\");\n\n\texit (0);\n\n}\n\nstatic void processListOperators (const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t  const char *const parameter)\n{\n\tinitializeParser (LANG_AUTO);\n\tlistRegexOpscriptOperators (stdout);\n\texit (0);\n}\n\nstatic void freeSearchPathList (searchPathList** pathList)\n{\n\tstringListClear (*pathList);\n\tstringListDelete (*pathList);\n\t*pathList = NULL;\n}\n\nstatic vString* expandOnSearchPathList (searchPathList *pathList, const char* leaf,\n\t\t\t\t\tbool (* check) (const char *const))\n{\n\tfor (unsigned int i = stringListCount (pathList); i > 0; --i)\n\t{\n\t\tconst char* const body = vStringValue (stringListItem (pathList, i - 1));\n\t\tchar* tmp = combinePathAndFile (body, leaf);\n\n\t\tif ((* check) (tmp))\n\t\t{\n\t\t\tvString *r = vStringNewOwn (tmp);\n\t\t\treturn r;\n\t\t}\n\t\telse\n\t\t\teFree (tmp);\n\t}\n\treturn NULL;\n}\n\nstatic vString* expandOnOptlibPathList (const char* leaf)\n{\n\n\treturn expandOnSearchPathList (OptlibPathList, leaf,\n\t\t\t\t\t\t\t\t   doesFileExist);\n}\n\nstatic void processOptionFileCommon (\n\tconst char *const option, const char *const parameter,\n\tbool allowNonExistingFile)\n{\n\tconst char* path;\n\tvString* vpath = NULL;\n\tfileStatus *status;\n\n\tif (parameter [0] == '\\0')\n\t\terror (FATAL, \"no option file supplied for \\\"%s\\\"\", option);\n\n\tif (parameter [0] != '/' && parameter [0] != '.')\n\t{\n\t\tvpath = expandOnOptlibPathList (parameter);\n\t\tpath = vpath? vStringValue (vpath): parameter;\n\t}\n\telse\n\t\tpath = parameter;\n\n\tstatus = eStat (path);\n\tif (!status->exists)\n\t{\n\t\tif (!allowNonExistingFile)\n\t\t\terror (FATAL | PERROR, \"cannot stat \\\"%s\\\"\", path);\n\t}\n\telse if (status->isDirectory)\n\t{\n\t\tif (!parseAllConfigurationFilesOptionsInDirectory (path, NULL))\n\t\t\terror (FATAL | PERROR, \"cannot open option directory \\\"%s\\\"\", path);\n\t}\n\telse\n\t{\n\t\tif (!parseFileOptions (path))\n\t\t\terror (FATAL | PERROR, \"cannot open option file \\\"%s\\\"\", path);\n\t}\n\n\teStatFree (status);\n\tif (vpath)\n\t\tvStringDelete (vpath);\n}\n\nstatic void processOptionFile (\n\tconst char *const option, const char *const parameter)\n{\n\tprocessOptionFileCommon(option, parameter, false);\n}\n\nstatic void processOptionFileMaybe (\n\tconst char *const option, const char *const parameter)\n{\n\tprocessOptionFileCommon(option, parameter, true);\n}\n\nstatic void processOutputFormat (const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t const char *const parameter)\n{\n\tif (parameter [0] == '\\0')\n\t\terror (FATAL, \"no output format name supplied for \\\"%s\\\"\", option);\n\n\twriterType t = getWrierForOutputFormat (parameter);\n\tif (t == WRITER_DEFAULT)\n\t\treturn;\n\n\tswitch (t)\n\t{\n\tcase WRITER_UNAVAILABLE:\n\t\terror (FATAL,\n\t\t\t   \"the output format \\\"%s\\\" is not available on this platform\",\n\t\t\t   parameter);\n\t\tbreak;\n\tcase WRITER_UNKNOWN:\n\t\terror (FATAL, \"unknown output format name supplied for \\\"%s=%s\\\"\",\n\t\t\t   option, parameter);\n\t\tbreak;\n\n\tcase WRITER_U_CTAGS:\n\tcase WRITER_E_CTAGS:\n\t\tsetTagWriter (t, NULL);\n\t\tbreak;\n\tcase WRITER_ETAGS:\n\t\tsetEtagsMode ();\n\t\tbreak;\n\tcase WRITER_XREF:\n\t\tsetXrefMode ();\n\t\tbreak;\n#ifdef HAVE_JANSSON\n\tcase WRITER_JSON:\n\t\tsetJsonMode ();\n\t\tbreak;\n#endif\n\tcase WRITER_CUSTOM:\n\tcase WRITER_COUNT:\t\t\t/* Suppress warnings that gcc reports */\n\t\tAssertNotReached ();\n\t\tbreak;\n\t}\n}\n\nstatic void processPseudoTags (const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t       const char *const parameter)\n{\n\tconst char *p = parameter;\n\tbool s = true;\n\tptagType t;\n\tvString *str = vStringNew();\n\n\tif (*p == '\\0' || !strchr (\"*+-\", *p))\n\t{\n\t\tfor (unsigned int i = 0; i < PTAG_COUNT; i++)\n\t\t\tenablePtag (i, false);\n\t}\n\n\twhile (1)\n\t{\n\t\tif (*p == '\\0')\n\t\t\tbreak;\n\n\t\tif (*p == '*')\n\t\t{\n\t\t\tint i;\n\t\t\tfor (i = 0; i < PTAG_COUNT; i++)\n\t\t\t\tenablePtag (i, true);\n\t\t\tp++;\n\t\t\tcontinue;\n\t\t}\n\t\telse if (*p == '-')\n\t\t{\n\t\t\ts= false;\n\t\t\tp++;\n\t\t\tcontinue;\n\t\t}\n\t\telse if (*p == '+')\n\t\t{\n\t\t\ts = true;\n\t\t\tp++;\n\t\t\tcontinue;\n\t\t}\n\t\telse if (*p == '{')\n\t\t{\n\t\t\tconst char *origin = p;\n\n\t\t\tp++;\n\t\t\twhile (*p != '\\0' && *p != '}')\n\t\t\t{\n\t\t\t\tvStringPut (str, *p);\n\t\t\t\tp++;\n\t\t\t}\n\t\t\tif (*p != '}')\n\t\t\t\terror (FATAL, \"curly bracket specifying a pseudo tags is unbalanced: %s\",\n\t\t\t\t\t   origin);\n\t\t\tp++;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvStringCopyS (str, p);\n\t\t\tp += vStringLength (str);\n\t\t}\n\n\t\tchar *name = vStringValue (str);\n\t\tt = getPtagTypeForName (name);\n\t\tif (t == PTAG_UNKNOWN)\n\t\t\terror (FATAL, \"Unknown pseudo tag name: %s\", name);\n\t\tenablePtag (t, s);\n\t\tvStringClear (str);\n\t}\n\tvStringDelete (str);\n}\n\nstatic void processSortOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tif (isFalse (parameter))\n\t\tOption.sorted = SO_UNSORTED;\n\telse if (isTrue (parameter))\n\t\tOption.sorted = SO_SORTED;\n\telse if (strcasecmp (parameter, \"f\") == 0 ||\n\t\t\tstrcasecmp (parameter, \"fold\") == 0 ||\n\t\t\tstrcasecmp (parameter, \"foldcase\") == 0)\n\t\tOption.sorted = SO_FOLDSORTED;\n\telse\n\t\terror (FATAL, \"Invalid value for \\\"%s\\\" option\", option);\n}\n\nstatic void processTagRelative (\n\t\tconst char *const option, const char *const parameter)\n{\n\tif (isFalse (parameter))\n\t\tOption.tagRelative = TREL_NO;\n\telse if (isTrue (parameter) || *parameter == '\\0')\n\t\tOption.tagRelative = TREL_YES;\n\telse if (strcasecmp (parameter, \"always\") == 0)\n\t\tOption.tagRelative = TREL_ALWAYS;\n\telse if (strcasecmp (parameter, \"never\") == 0)\n\t\tOption.tagRelative = TREL_NEVER;\n\telse\n\t\terror (FATAL, \"Invalid value for \\\"%s\\\" option\", option);\n}\n\nstatic void processTotals (\n\t\tconst char *const option, const char *const parameter)\n{\n\tif (isFalse (parameter))\n\t\tOption.printTotals = 0;\n\telse if (isTrue (parameter) || *parameter == '\\0')\n\t\tOption.printTotals = 1;\n\telse if (strcasecmp (parameter, \"extra\") == 0)\n\t\tOption.printTotals = 2;\n\telse\n\t\terror (FATAL, \"Invalid value for \\\"%s\\\" option\", option);\n}\n\nstatic void installHeaderListDefaults (void)\n{\n\tOption.headerExt = stringListNewFromArgv (HeaderExtensions);\n\n\tBEGIN_VERBOSE(vfp);\n\t{\n\t\tfprintf (vfp, \"    Setting default header extensions: \");\n\t\tstringListPrint (Option.headerExt, vfp);\n\t\tputc ('\\n', vfp);\n\t}\n\tEND_VERBOSE();\n}\n\nstatic void processHeaderListOption (const int option, const char *parameter)\n{\n\t/*  Check to make sure that the user did not enter \"ctags -h *.c\"\n\t *  by testing to see if the list is a filename that exists.\n\t */\n\tif (doesFileExist (parameter))\n\t\terror (FATAL, \"-%c: Invalid list\", option);\n\tif (strcmp (parameter, \"default\") == 0)\n\t\tinstallHeaderListDefaults ();\n\telse\n\t{\n\t\tbool clear = true;\n\n\t\tif (parameter [0] == '+')\n\t\t{\n\t\t\t++parameter;\n\t\t\tclear = false;\n\t\t}\n\t\tif (Option.headerExt == NULL)\n\t\t\tOption.headerExt = stringListNew ();\n\t\tverbose (\"    Header Extensions:\\n\");\n\t\taddExtensionList (Option.headerExt, parameter, clear);\n\t}\n}\n\n/*\n *  Token ignore processing\n */\nstatic void readIgnoreList (langType lang, const char *const list)\n{\n\tchar* newList = stringCopy (list);\n\tconst char *token = strtok (newList, IGNORE_SEPARATORS);\n\n\twhile (token != NULL)\n\t{\n\t\tapplyLanguageParam (lang, \"ignore\", token);\n\t\ttoken = strtok (NULL, IGNORE_SEPARATORS);\n\t}\n\teFree (newList);\n}\n\nstatic void addIgnoreListFromFile (langType lang, const char *const fileName)\n{\n\tstringList* tokens = stringListNewFromFile (fileName);\n\tif (tokens == NULL)\n\t\terror (FATAL | PERROR, \"cannot open \\\"%s\\\"\", fileName);\n\n\tint c = stringListCount(tokens);\n\n\tfor(unsigned int i=0;i<c;i++)\n\t{\n\t\tvString * s = stringListItem(tokens,i);\n\t\tapplyLanguageParam (lang, \"ignore\", vStringValue(s));\n\t}\n\n\tstringListDelete(tokens);\n}\n\nstatic void processIgnoreOption (const char *const list, int IgnoreOrDefine)\n{\n\tlangType lang = getNamedLanguage (\"CPreProcessor\", 0);\n\n\tif (IgnoreOrDefine == 'D')\n\t\tapplyLanguageParam (lang, \"define\", list);\n\telse if (strchr (\"@./\\\\\", list [0]) != NULL)\n\t{\n\t\tconst char* fileName = (*list == '@') ? list + 1 : list;\n\t\taddIgnoreListFromFile (lang, fileName);\n\t}\n#if defined (_WIN32)\n\telse if (isalpha ((unsigned char) list [0])  &&  list [1] == ':')\n\t\taddIgnoreListFromFile (lang, list);\n#endif\n\telse if (strcmp (list, \"-\") == 0)\n\t\tapplyLanguageParam (lang, \"ignore\", NULL);\n\telse\n\t\treadIgnoreList (lang, list);\n}\n\nstatic void processAnonHashOption (const char *const option CTAGS_ATTR_UNUSED, const char *const parameter CTAGS_ATTR_UNUSED)\n{\n\tif (parameter == NULL || parameter[0] == '\\0')\n\t\terror (FATAL, \"Something string is needed for \\\"%s\\\" option\", option);\n\tchar buf [9];\n\n\tanonHashString (parameter, buf);\n\tprintf(\"%s\\n\", buf);\n\texit (0);\n}\n\nstatic void processDumpKeywordsOption (const char *const option CTAGS_ATTR_UNUSED, const char *const parameter CTAGS_ATTR_UNUSED)\n{\n\tdumpKeywordTable (stdout);\n}\n\nstatic void processEchoOption (const char *const option, const char *const parameter)\n{\n\tif (parameter == NULL || parameter[0] == '\\0')\n\t\terror (FATAL, \"Something message is needed for \\\"%s\\\" option\", option);\n\tnotice (\"%s\", parameter);\n}\n\nstatic void processForceInitOption (const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t    const char *const parameter CTAGS_ATTR_UNUSED)\n{\n\tverbose (\"force initializing all built-in parsers\\n\");\n\tinitializeParser (LANG_AUTO);\n}\n\nstatic void processForceQuitOption (const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t    const char *const parameter)\n{\n\tint s;\n\tif (parameter == NULL || parameter[0] == '\\0' || !strToInt(parameter, 0, &s))\n\t\ts = 0;\n\texit (s);\n}\n\nstatic void processVersionOption (\n\t\tconst char *const option,\n\t\tconst char *const parameter)\n{\n\tif (parameter == NULL || *parameter == '\\0')\n\t\tprintProgramIdentification ();\n\telse if (strcmp (parameter, RSV_NONE) == 0)\n\t{\n\t\tprintf(\"ctags: %s\\n\", PROGRAM_VERSION);\n\t\tif (! ((ctags_repoinfo == NULL)\n\t\t\t   || (strcmp (ctags_repoinfo, PROGRAM_VERSION) == 0)))\n\t\t\tprintf(\"repoinfo: %s\\n\", ctags_repoinfo);\n\t\tprintf(\"output: %d.%d\\n\", OUTPUT_VERSION_CURRENT, OUTPUT_VERSION_AGE);\n\t}\n\telse\n\t{\n\t\tlangType language = getNamedLanguage (parameter, 0);\n\t\tif (language == LANG_IGNORE)\n\t\t\terror (FATAL, \"Unknown language \\\"%s\\\" in \\\"%s\\\"\", parameter, option);\n\t\tunsigned int current = getLanguageVersionCurrent (language);\n\t\tunsigned int age = getLanguageVersionAge (language);\n\t\tprintf(\"parser/%s: %u.%u\\n\", parameter, current, age);\n\t}\n\texit (0);\n}\n\n#ifdef DO_TRACING\nstatic void processTraceOption(const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t   const char *const parameter)\n{\n\tconst char *langs = eStrdup (parameter);\n\tconst char *lang = langs;\n\n\ttraceMain();\n\n\twhile (lang != NULL)\n\t{\n\t\tif (*lang == '\\0')\n\t\t\tbreak;\n\t\tif (*lang == ',')\n\t\t{\n\t\t\tlang++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tchar *const end = strchr (lang, ',');\n\n\t\tif (end != NULL)\n\t\t\t*end = '\\0';\n\n\t\tconst langType language = getNamedLanguage (lang, 0);\n\t\tif (language == LANG_IGNORE)\n\t\t\terror (WARNING, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", lang, option);\n\t\telse\n\t\t{\n\t\t\ttraceLanguage (language);\n\t\t\tverbose (\"Enable tracing language: %s\\n\", lang);\n\n\t\t}\n\t\tlang = (end != NULL ? end + 1 : NULL);\n\t}\n\teFree ((char *)langs);\n}\n#endif\n\nstatic void processXformatOption (const char *const option CTAGS_ATTR_UNUSED,\n\t\t\t\t  const char *const parameter)\n{\n\tif (Option.customXfmt)\n\t\tfmtDelete (Option.customXfmt);\n\n\tOption.customXfmt = fmtNew (parameter);\n}\n\nstatic void prependToOptlibPathList (const char *const dir, bool report_in_verbose)\n{\n\tvString *elt = vStringNewInit (dir);\n\n\tif (report_in_verbose)\n\t\tverbose (\"Prepend %s to %s\\n\",\n\t\t\t\t dir, \"OptlibPathList\");\n\n\tstringListAdd (OptlibPathList, elt);\n}\n\nstatic void resetOptlibPathList (bool report_in_verbose)\n{\n\tfreeSearchPathList (&OptlibPathList);\n\tif (report_in_verbose)\n\t\tverbose (\"Reset OptlibPathList\\n\");\n\tOptlibPathList = stringListNew ();\n}\n\nstatic void processOptlibDir (\n\t\tconst char *const option, const char *const parameter)\n{\n\tconst char* path;\n\n\tAssert (parameter);\n\n\n\tif (parameter[0] == '\\0')\n\t\tresetOptlibPathList (true);\n\telse if (parameter[0] == '+')\n\t{\n\t\tpath = parameter + 1;\n\t\tif (path[0] == '\\0')\n\t\t\treturn;\n\t\tprependToOptlibPathList (path, true);\n\t}\n\telse\n\t{\n\t\tresetOptlibPathList (true);\n\t\tpath = parameter;\n\t\tprependToOptlibPathList (path, true);\n\t}\n}\n\nstatic void processMaxRecursionDepthOption (const char *const option, const char *const parameter)\n{\n\tif (parameter == NULL || parameter[0] == '\\0')\n\t\terror (FATAL, \"A parameter is needed after \\\"%s\\\" option\", option);\n\n\tif (atol (parameter) < 1)\n\t\terror (FATAL, \"-%s: Invalid maximum recursion depth\", option);\n\n\tOption.maxRecursionDepth = atol(parameter);\n}\n\nstatic void processPatternLengthLimit(const char *const option, const char *const parameter)\n{\n\tif (parameter == NULL || parameter[0] == '\\0')\n\t\terror (FATAL, \"A parameter is needed after \\\"%s\\\" option\", option);\n\n\tif (!strToUInt(parameter, 0, &Option.patternLengthLimit))\n\t\terror (FATAL, \"-%s: Invalid pattern length limit\", option);\n}\n\nextern bool ptagMakePatternLengthLimit (ptagDesc *pdesc, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\tconst void *data)\n{\n\tconst optionValues *opt = data;\n\tchar buf [21];\n\n\tif (snprintf (buf, 21, \"%u\", opt->patternLengthLimit) >= 0)\n\t\treturn writePseudoTag (pdesc, buf, \"0 for no limit\", NULL);\n\treturn false;\n}\n\nstatic void setBooleanToXtagWithWarning(booleanOption *const option, bool value)\n{\n\t/* WARNING/TODO: This function breaks encapsulation. */\n\n\tchar x = 0;\n\n\tif (strcmp (option->name, \"file-tags\") == 0)\n\t\tx = 'f';\n\telse if (strcmp (option->name, \"file-scope\") == 0)\n\t\tx = 'F';\n\n\tif (x)\n\t\terror (WARNING, \"\\\"--%s\\\" option is obsolete; use \\\"--extras=%c%c\\\" instead\",\n\t\t\t   option->name, value? '+': '-', x);\n\n\txtagType t = (xtagType)option->pValue;\n\tenableXtag (t, value);\n}\n\n/*\n *  Option tables\n */\n\nstatic void processDumpOptionsOption (const char *const option, const char *const parameter);\nstatic void processDumpPreludeOption (const char *const option, const char *const parameter);\n\nstatic parametricOption ParametricOptions [] = {\n\t{ \"describe-language\",      processDescribeLanguage,        true,   STAGE_ANY },\n\t{ \"etags-include\",          processEtagsInclude,            false,  STAGE_ANY },\n\t{ \"exclude\",                processExcludeOption,           false,  STAGE_ANY },\n\t{ \"exclude-exception\",      processExcludeExceptionOption,  false,  STAGE_ANY },\n\t{ \"excmd\",                  processExcmdOption,             false,  STAGE_ANY },\n\t{ \"extra\",                  processExtraTagsOption,         false,  STAGE_ANY },\n\t{ \"extras\",                 processExtraTagsOption,         false,  STAGE_ANY },\n\t{ \"fields\",                 processFieldsOption,            false,  STAGE_ANY },\n\t{ \"filter-terminator\",      processFilterTerminatorOption,  true,   STAGE_ANY },\n\t{ \"format\",                 processFormatOption,            true,   STAGE_ANY },\n\t{ \"help\",                   processHelpOption,              true,   STAGE_ANY },\n\t{ \"help-full\",              processHelpFullOption,          true,   STAGE_ANY },\n\t{ \"if0\",                    processIf0Option,               false,  STAGE_ANY },\n#ifdef HAVE_ICONV\n\t{ \"input-encoding\",         processInputEncodingOption,     false,  STAGE_ANY },\n\t{ \"output-encoding\",        processOutputEncodingOption,    false,  STAGE_ANY },\n#endif\n\t{ \"lang\",                   processLanguageForceOption,     false,  STAGE_ANY },\n\t{ \"language\",               processLanguageForceOption,     false,  STAGE_ANY },\n\t{ \"language-force\",         processLanguageForceOption,     false,  STAGE_ANY },\n\t{ \"languages\",              processLanguagesOption,         false,  STAGE_ANY },\n\t{ \"langdef\",                processLanguageDefineOption,    false,  STAGE_ANY },\n\t{ \"langmap\",                processLanguageMapOption,       false,  STAGE_ANY },\n\t{ \"license\",                processLicenseOption,           true,   STAGE_ANY },\n\t{ \"list-aliases\",           processListAliasesOption,       true,   STAGE_ANY },\n\t{ \"list-excludes\",          processListExcludesOption,      true,   STAGE_ANY },\n\t{ \"list-extras\",            processListExtrasOption,        true,   STAGE_ANY },\n\t{ \"list-features\",          processListFeaturesOption,      true,   STAGE_ANY },\n\t{ \"list-fields\",            processListFieldsOption,        true,   STAGE_ANY },\n\t{ \"list-kinds\",             processListKindsOption,         true,   STAGE_ANY },\n\t{ \"list-kinds-full\",        processListKindsOption,         true,   STAGE_ANY },\n\t{ \"list-languages\",         processListLanguagesOption,     true,   STAGE_ANY },\n\t{ \"list-maps\",              processListMapsOption,          true,   STAGE_ANY },\n\t{ \"list-map-extensions\",    processListMapExtensionsOption, true,   STAGE_ANY },\n\t{ \"list-map-patterns\",      processListMapPatternsOption,   true,   STAGE_ANY },\n\t{ \"list-map-rexprs\",        processListMapRexprsOption,     true,   STAGE_ANY },\n\t{ \"list-mline-regex-flags\", processListMultilineRegexFlagsOption, true, STAGE_ANY },\n\t{ \"list-output-formats\",    processListOutputFormatsOption, true,   STAGE_ANY },\n\t{ \"list-params\",            processListParametersOption,    true,   STAGE_ANY },\n\t{ \"list-pseudo-tags\",       processListPseudoTagsOption,    true,   STAGE_ANY },\n\t{ \"list-regex-flags\",       processListRegexFlagsOption,    true,   STAGE_ANY },\n\t{ \"list-roles\",             processListRolesOption,         true,   STAGE_ANY },\n\t{ \"list-subparsers\",        processListSubparsersOption,    true,   STAGE_ANY },\n\t{ \"maxdepth\",               processMaxRecursionDepthOption, true,   STAGE_ANY },\n\t{ \"optlib-dir\",             processOptlibDir,               false,  STAGE_ANY },\n\t{ \"options\",                processOptionFile,              false,  STAGE_ANY },\n\t{ \"options-maybe\",          processOptionFileMaybe,         false,  STAGE_ANY },\n\t{ \"output-format\",          processOutputFormat,            true,   STAGE_ANY },\n\t{ \"pattern-length-limit\",   processPatternLengthLimit,      true,   STAGE_ANY },\n\t{ \"pseudo-tags\",            processPseudoTags,              false,  STAGE_ANY },\n\t{ \"sort\",                   processSortOption,              true,   STAGE_ANY },\n\t{ \"tag-relative\",           processTagRelative,             true,   STAGE_ANY },\n\t{ \"totals\",                 processTotals,                  true,   STAGE_ANY },\n\t{ \"version\",                processVersionOption,           true,   STAGE_ANY },\n\t{ \"_anonhash\",              processAnonHashOption,          false,  STAGE_ANY },\n\t{ \"_dump-keywords\",         processDumpKeywordsOption,      false,  STAGE_ANY },\n\t{ \"_dump-options\",          processDumpOptionsOption,       false,  STAGE_ANY },\n\t{ \"_dump-prelude\",          processDumpPreludeOption,       false,  STAGE_ANY },\n\t{ \"_echo\",                  processEchoOption,              false,  STAGE_ANY },\n\t{ \"_force-initializing\",    processForceInitOption,         false,  STAGE_ANY },\n\t{ \"_force-quit\",            processForceQuitOption,         false,  STAGE_ANY },\n#ifdef HAVE_JANSSON\n\t{ \"_interactive\",           processInteractiveOption,       true,   STAGE_ANY },\n#endif\n\t{ \"_list-extradef-flags\",   processListExtradefFlagsOption, true,   STAGE_ANY },\n\t{ \"_list-fielddef-flags\",   processListFielddefFlagsOption, true,   STAGE_ANY },\n\t{ \"_list-kinddef-flags\",    processListKinddefFlagsOption,  true,   STAGE_ANY },\n\t{ \"_list-langdef-flags\",    processListLangdefFlagsOption,  true,   STAGE_ANY },\n\t{ \"_list-mtable-regex-flags\", processListMultitableRegexFlagsOption, true, STAGE_ANY },\n\t{ \"_list-operators\",        processListOperators,           true,   STAGE_ANY },\n\t{ \"_list-roledef-flags\",    processListRoledefFlagsOption,  true,   STAGE_ANY },\n#ifdef DO_TRACING\n\t{ \"_trace\",                 processTraceOption,             false,  STAGE_ANY },\n#endif\n\t{ \"_xformat\",               processXformatOption,           false,  STAGE_ANY },\n};\n\nstatic booleanOption BooleanOptions [] = {\n\t{ \"append\",         &Option.append,                 true,  STAGE_ANY },\n\t{ \"file-scope\",     ((bool *)XTAG_FILE_SCOPE),      false, STAGE_ANY, setBooleanToXtagWithWarning },\n\t{ \"file-tags\",      ((bool *)XTAG_FILE_NAMES),      false, STAGE_ANY, setBooleanToXtagWithWarning },\n\t{ \"filter\",         &Option.filter,                 true,  STAGE_ANY },\n\t{ \"guess-language-eagerly\", &Option.guessLanguageEagerly, false, STAGE_ANY },\n\t{ \"line-directives\",&Option.lineDirectives,         false, STAGE_ANY },\n\t{ \"links\",          &Option.followLinks,            false, STAGE_ANY },\n\t{ \"machinable\",     &localOption.machinable,        true,  STAGE_ANY },\n\t{ \"put-field-prefix\", &Option.putFieldPrefix,       false, STAGE_ANY },\n\t{ \"print-language\", &Option.printLanguage,          true,  STAGE_ANY },\n\t{ \"quiet\",          &Option.quiet,                  false, STAGE_ANY },\n#ifdef RECURSE_SUPPORTED\n\t{ \"recurse\",        &Option.recurse,                false, STAGE_ANY },\n#endif\n\t{ \"verbose\",        &ctags_verbose,                 false, STAGE_ANY },\n#ifdef _WIN32\n\t{ \"use-slash-as-filename-separator\", (bool *)&Option.useSlashAsFilenameSeparator, false, STAGE_ANY },\n#endif\n\t{ \"with-list-header\", &localOption.withListHeader,  true,  STAGE_ANY },\n\t{ \"_fatal-warnings\",&Option.fatalWarnings,          false, STAGE_ANY },\n};\n\n/*\n *  Generic option parsing\n */\n\nstatic void checkOptionOrder (const char* const option, bool longOption)\n{\n\tif (NonOptionEncountered)\n\t\terror (FATAL, \"-%s%s option may not follow a file name\", longOption? \"-\": \"\", option);\n}\n\nstatic bool processParametricOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tconst int count = sizeof (ParametricOptions) / sizeof (parametricOption);\n\tbool found = false;\n\tint i;\n\n\tfor (i = 0  ;  i < count  &&  ! found  ;  ++i)\n\t{\n\t\tparametricOption* const entry = &ParametricOptions [i];\n\t\tif (strcmp (option, entry->name) == 0)\n\t\t{\n\t\t\tfound = true;\n\t\t\tif (!(entry->acceptableStages & (1UL << Stage)))\n\t\t\t{\n\t\t\t\terror (WARNING, \"Cannot use --%s option in %s\",\n\t\t\t\t       option, StageDescription[Stage]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (entry->initOnly)\n\t\t\t\tcheckOptionOrder (option, true);\n\t\t\t(entry->handler) (option, parameter);\n\t\t}\n\t}\n\treturn found;\n}\n\nstatic bool getBooleanOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\treturn paramParserBool (parameter, true, option, \"option\");\n}\n\nstatic bool processBooleanOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tconst int count = sizeof (BooleanOptions) / sizeof (booleanOption);\n\tbool found = false;\n\tint i;\n\n\tfor (i = 0  ;  i < count  &&  ! found  ;  ++i)\n\t{\n\t\tbooleanOption* const entry = &BooleanOptions [i];\n\t\tif (strcmp (option, entry->name) == 0)\n\t\t{\n\t\t\tfound = true;\n\t\t\tif (!(entry->acceptableStages & (1UL << Stage)))\n\t\t\t{\n\t\t\t\terror (WARNING, \"Cannot use --%s option in %s\",\n\t\t\t\t       option, StageDescription[Stage]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (entry->initOnly)\n\t\t\t\tcheckOptionOrder (option, true);\n\n\t\t\tbool value = getBooleanOption (option, parameter);\n\t\t\tif (entry->set)\n\t\t\t\tentry->set (entry, value);\n\t\t\telse\n\t\t\t\t*entry->pValue = value;\n\t\t}\n\t}\n\treturn found;\n}\n\nstatic void enableLanguageField (langType language, const char *field, bool mode)\n{\n\n\tfieldType t;\n\n\tt = getFieldTypeForNameAndLanguage (field, language);\n\tif (t == FIELD_UNKNOWN)\n\t\terror(FATAL, \"no such field: \\'%s\\'\", field);\n\tenableField (t, mode);\n\tif (language == LANG_AUTO)\n\t{\n\t\tfieldType ftype_next = t;\n\n\t\twhile ((ftype_next = nextSiblingField (ftype_next)) != FIELD_UNKNOWN)\n\t\t\tenableField (ftype_next, mode);\n\t}\n}\n\nstatic void enableLanguageXtag (langType language, const char *xtag, bool mode)\n{\n\n\txtagType x;\n\n\tx = getXtagTypeForNameAndLanguage (xtag, language);\n\tif (x == XTAG_UNKNOWN)\n\t\terror(FATAL, \"no such extra: \\'%s\\'\", xtag);\n\tenableXtag (x, mode);\n\tif (language == LANG_AUTO)\n\t{\n\t\txtagType xtag_next = x;\n\n\t\twhile ((xtag_next = nextSiblingXtag (xtag_next)) != XTAG_UNKNOWN)\n\t\t\tenableXtag (xtag_next, mode);\n\t}\n}\n\nstatic bool processLangSpecificFieldsOption (const char *const option,\n\t\t\t\t\t\tconst char *const parameter)\n{\n#define PREFIX \"fields-\"\n#define PREFIX_LEN strlen(PREFIX)\n\tconst char* lang;\n\tsize_t len;\n\tlangType language = LANG_IGNORE;\n\tconst char *p = parameter;\n\tint c;\n\tstatic vString * longName;\n\tbool mode = true;\n\tconst char *f;\n\tbool inLongName = false;\n\n\tif ( strncmp (option, PREFIX, PREFIX_LEN) != 0 )\n\t\treturn false;\n\n\tlang = option + PREFIX_LEN;\n\tlen = strlen (lang);\n\tif (len == 0)\n\t\terror (FATAL, \"No language given in \\\"%s\\\" option\", option);\n\telse if (len == strlen(RSV_LANG_ALL) && (strncmp(lang, RSV_LANG_ALL, len) == 0))\n\t\tlanguage = LANG_AUTO;\n\telse\n\t\tlanguage = getNamedLanguage (lang, len);\n\n\tif (language == LANG_IGNORE)\n\t{\n\t\terror (WARNING, \"Unknown language: %s (ignoring \\\"--%s\\\")\", lang, option);\n\t\t/* The option is consumed in this function. */\n\t\treturn true;\n\t}\n\n\tinitializeParser (language);\n\n\tif (*p == '*')\n\t{\n\t\tresetFieldsOption (language, true);\n\t\tp++;\n\t}\n\telse if (*p == '{' || *p == '\\0')\n\t{\n\t\tresetFieldsOption (language, false);\n\t\tif (*p == '\\0')\n\t\t\treturn true;\n\t}\n\telse if (*p != '+' && *p != '-')\n\t\terror (WARNING, \"Wrong per language field specification: %s\", p);\n\n\tlongName = vStringNewOrClearWithAutoRelease (longName);\n\twhile ((c = (unsigned char) *p++) != '\\0')\n\t{\n\t\tswitch (c)\n\t\t{\n\t\tcase '+':\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\tmode = true;\n\t\t\tbreak;\n\t\tcase '-':\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\tmode = false;\n\t\t\tbreak;\n\t\tcase '{':\n\t\t\tif (inLongName)\n\t\t\t\terror (FATAL,\n\t\t\t\t       \"unexpected character in field specification: \\'%c\\'\",\n\t\t\t\t       c);\n\t\t\tinLongName = true;\n\t\t\tbreak;\n\t\tcase '}':\n\t\t\tif (!inLongName)\n\t\t\t\terror (FATAL,\n\t\t\t\t       \"unexpected character in field specification: \\'%c\\'\",\n\t\t\t\t       c);\n\n\t\t\tf = vStringValue (longName);\n\t\t\tenableLanguageField (language, f, mode);\n\t\t\tinLongName = false;\n\t\t\tvStringClear (longName);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\terror (FATAL,\n\t\t\t\t       \"only long name can be used in per language field spec: \\'%c\\'\",\n\t\t\t\t       c);\n\t\t\tbreak;\n\t\t}\n\t}\n#undef PREFIX_LEN\n#undef PREFIX\n\treturn true;\n}\n\nstatic bool processLangSpecificExtraOption (const char *const option,\n\t\t\t\t\t\tconst char *const parameter)\n{\n#define PREFIX \"extras-\"\n#define PREFIX_LEN strlen(PREFIX)\n\tconst char* lang;\n\tsize_t len;\n\tlangType language = LANG_IGNORE;\n\tconst char *p = parameter;\n\tint c;\n\tstatic vString * longName;\n\tbool mode = true;\n\tconst char *x;\n\tbool inLongName = false;\n\n\tif ( strncmp (option, PREFIX, PREFIX_LEN) != 0 )\n\t\treturn false;\n\n\tlang = option + PREFIX_LEN;\n\tlen = strlen (lang);\n\n\tif (len == 0)\n\t\terror (FATAL, \"No language given in \\\"%s\\\" option\", option);\n\telse if (len == strlen(RSV_LANG_ALL) && (strncmp(lang, RSV_LANG_ALL, len) == 0))\n\t\tlanguage = LANG_AUTO;\n\telse\n\t\tlanguage = getNamedLanguage (lang, len);\n\n\tif (language == LANG_IGNORE)\n\t{\n\t\terror (WARNING, \"Unknown language: %s (ignoring \\\"--%s\\\")\", lang, option);\n\t\t/* The option is consumed in this function. */\n\t\treturn true;\n\t}\n\n\tinitializeParser (language);\n\n\tif (*p == '*')\n\t{\n\t\tresetXtags (language, true);\n\t\tp++;\n\t}\n\telse if (*p == '{' || *p == '\\0')\n\t{\n\t\tresetXtags (language, false);\n\t\tif (*p == '\\0')\n\t\t\treturn true;\n\t}\n\telse if (*p != '+' && *p != '-')\n\t\terror (WARNING, \"Wrong per language extra specification: %s\", p);\n\n\tlongName = vStringNewOrClearWithAutoRelease (longName);\n\twhile ((c = (unsigned char) *p++) != '\\0')\n\t{\n\t\tswitch (c)\n\t\t{\n\t\tcase '+':\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\tmode = true;\n\t\t\tbreak;\n\t\tcase '-':\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\tmode = false;\n\t\t\tbreak;\n\t\tcase '{':\n\t\t\tif (inLongName)\n\t\t\t\terror (FATAL,\n\t\t\t\t       \"unexpected character in extra specification: \\'%c\\'\",\n\t\t\t\t       c);\n\t\t\tinLongName = true;\n\t\t\tbreak;\n\t\tcase '}':\n\t\t\tif (!inLongName)\n\t\t\t\terror (FATAL,\n\t\t\t\t       \"unexpected character in extra specification: \\'%c\\'\",\n\t\t\t\t       c);\n\n\t\t\tx = vStringValue (longName);\n\t\t\tenableLanguageXtag (language, x, mode);\n\t\t\tinLongName = false;\n\t\t\tvStringClear (longName);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\terror (FATAL,\n\t\t\t\t       \"only long name can be used in per language extra spec: \\'%c\\'\",\n\t\t\t\t       c);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn true;\n}\n\nstatic bool processRegexOption (const char *const option,\n\t\t\t\t\t\t\t\tconst char *const parameter)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"regex-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\tprocessLanguageRegexOption (language, REG_PARSER_SINGLE_LINE, parameter);\n\n\treturn true;\n}\n\nstatic bool processMultilineRegexOption (const char *const option,\n\t\t\t\t\t\t\t\t\t\t const char *const parameter)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"mline-regex-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\tprocessLanguageRegexOption (language, REG_PARSER_MULTI_LINE, parameter);\n\n\treturn true;\n}\n\nstatic bool processMultitableRegexOption (const char *const option,\n\t\t\t\t\t\t\t\t\t\t  const char *const parameter)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"_mtable-regex-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\tprocessLanguageRegexOption (language, REG_PARSER_MULTI_TABLE, parameter);\n\n\treturn true;\n}\n\nstatic bool processMultitableExtendingOption (const char *const option,\n\t\t\t\t\t\t\t\t\t\t\t  const char *const parameter)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"_mtable-extend-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\tprocessLanguageMultitableExtendingOption (language, parameter);\n\n\treturn true;\n}\n\nstatic void processLongOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tAssert (parameter != NULL);\n\tAssert (option != NULL);\n\n\tif (parameter [0] == '\\0')\n\t\tverbose (\"  Option: --%s\\n\", option);\n\telse\n\t\tverbose (\"  Option: --%s=%s\\n\", option, parameter);\n\n\tif (processBooleanOption (option, parameter))\n\t\t;\n\telse if (processLangSpecificFieldsOption(option, parameter))\n\t\t ;\n\telse if (processExtradefOption(option, parameter))\n\t\t;\n\telse if (processFielddefOption(option, parameter))\n\t\t;\n\telse if (processLangSpecificExtraOption(option, parameter))\n\t\t;\n\telse if (processParametricOption (option, parameter))\n\t\t;\n\telse if (processKinddefOption (option, parameter))\n\t\t;\n\telse if (processKindsOption (option, parameter))\n\t\t;\n\telse if (processAliasOption (option, parameter))\n\t\t;\n\telse if (processRegexOption (option, parameter))\n\t\t;\n\telse if (processMultilineRegexOption (option, parameter))\n\t\t;\n\telse if (processMapOption (option, parameter))\n\t\t;\n\telse if (processParamdefOption (option, parameter))\n\t\t;\n\telse if (processParamOption (option, parameter))\n\t\t;\n\telse if (processTabledefOption (option, parameter))\n\t\t;\n\telse if (processMultitableRegexOption (option, parameter))\n\t\t;\n\telse if (processMultitableExtendingOption (option, parameter))\n\t\t;\n#ifdef HAVE_ICONV\n\telse if (processLanguageEncodingOption (option, parameter))\n\t\t;\n#endif\n#ifndef RECURSE_SUPPORTED\n\telse if (strcmp (option, \"recurse\") == 0)\n\t\terror (WARNING, \"%s option not supported on this host\", option);\n#endif\n\telse if (processRoledefOption (option, parameter))\n\t\t;\n\telse if (processScopesepOption (option, parameter))\n\t\t;\n\telse if (processPreludeOption (option, parameter))\n\t\t;\n\telse if (processSequelOption (option, parameter))\n\t\t;\n\telse if (processPretendOption (option, parameter))\n\t\t;\n\telse if (processRolesOption (option, parameter))\n\t\t;\n\telse if (option[0] == '_' && option[1] == '_')\n\t\t/* ctags ignores an argument started from --__.\n\t\t * optlib2c may handle the argument. */\n\t\t;\n\telse\n\t\terror (FATAL, \"Unknown option: --%s\", option);\n}\n\nstatic void processShortOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tif (parameter == NULL  ||  parameter [0] == '\\0')\n\t\tverbose (\"  Option: -%s\\n\", option);\n\telse\n\t\tverbose (\"  Option: -%s %s\\n\", option, parameter);\n\n\tif (isCompoundOption (*option) && (parameter == NULL  ||  parameter [0] == '\\0'))\n\t\terror (FATAL, \"Missing parameter for \\\"%s\\\" option\", option);\n\telse switch (*option)\n\t{\n\t\tcase '?':\n\t\t\tprocessHelpOption (\"?\", NULL);\n\t\t\texit (0);\n\t\t\tbreak;\n\t\tcase 'a':\n\t\t\tcheckOptionOrder (option, false);\n\t\t\tOption.append = true;\n\t\t\tbreak;\n#ifdef DEBUG\n\t\tcase 'b':\n\t\t\tif (atol (parameter) < 0)\n\t\t\t\terror (FATAL, \"-%s: Invalid line number\", option);\n\t\t\tOption.breakLine = atol (parameter);\n\t\t\tbreak;\n\t\tcase 'd':\n\t\t\tif (!strToLong(parameter, 0, &ctags_debugLevel))\n\t\t\t\terror (FATAL, \"-%s: Invalid debug level\", option);\n\n\t\t\tif (debug (DEBUG_STATUS))\n\t\t\t\tctags_verbose = true;\n\t\t\tbreak;\n#endif\n\t\tcase 'B':\n\t\t\tOption.backward = true;\n\t\t\tbreak;\n\t\tcase 'D':\n\t\t\tprocessIgnoreOption (parameter, *option);\n\t\t\tbreak;\n\t\tcase 'e':\n\t\t\tcheckOptionOrder (option, false);\n\t\t\tsetEtagsMode ();\n\t\t\tbreak;\n\t\tcase 'f':\n\t\tcase 'o':\n\t\t\tcheckOptionOrder (option, false);\n\t\t\tif (Option.tagFileName != NULL)\n\t\t\t{\n\t\t\t\terror (WARNING,\n\t\t\t\t\t\"-%s option specified more than once, last value used\",\n\t\t\t\t\toption);\n\t\t\t\tfreeString (&Option.tagFileName);\n\t\t\t}\n\t\t\telse if (parameter [0] == '-'  &&  parameter [1] != '\\0')\n\t\t\t\terror (FATAL, \"output file name may not begin with a '-'\");\n\t\t\tOption.tagFileName = stringCopy (parameter);\n\t\t\tbreak;\n\t\tcase 'F':\n\t\t\tOption.backward = false;\n\t\t\tbreak;\n\t\tcase 'G':\n\t\t\tOption.guessLanguageEagerly = true;\n\t\t\tbreak;\n\t\tcase 'h':\n\t\t\tprocessHeaderListOption (*option, parameter);\n\t\t\tbreak;\n\t\tcase 'I':\n\t\t\tprocessIgnoreOption (parameter, *option);\n\t\t\tbreak;\n\t\tcase 'L':\n\t\t\tif (Option.fileList != NULL)\n\t\t\t{\n\t\t\t\terror (WARNING,\n\t\t\t\t\t\"-%s option specified more than once, last value used\",\n\t\t\t\t\toption);\n\t\t\t\tfreeString (&Option.fileList);\n\t\t\t}\n\t\t\tOption.fileList = stringCopy (parameter);\n\t\t\tbreak;\n\t\tcase 'n':\n\t\t\tOption.locate = EX_LINENUM;\n\t\t\tbreak;\n\t\tcase 'N':\n\t\t\tOption.locate = EX_PATTERN;\n\t\t\tbreak;\n\t\tcase 'R':\n#ifdef RECURSE_SUPPORTED\n\t\t\tOption.recurse = true;\n#else\n\t\t\terror (WARNING, \"-%s option not supported on this host\", option);\n#endif\n\t\t\tbreak;\n\t\tcase 'u':\n\t\t\tcheckOptionOrder (option, false);\n\t\t\tOption.sorted = SO_UNSORTED;\n\t\t\tbreak;\n\t\tcase 'V':\n\t\t\tctags_verbose = true;\n\t\t\tbreak;\n\t\tcase 'w':\n\t\t\t/* silently ignored */\n\t\t\tbreak;\n\t\tcase 'x':\n\t\t\tcheckOptionOrder (option, false);\n\t\t\tsetXrefMode ();\n\t\t\tbreak;\n\t\tdefault:\n\t\t\terror (FATAL, \"Unknown option: -%s\", option);\n\t\t\tbreak;\n\t}\n}\n\nstatic void parseOption (cookedArgs* const args)\n{\n\tAssert (! cArgOff (args));\n\tif (args->isOption)\n\t{\n\t\tif (args->longOption)\n\t\t\tprocessLongOption (args->item, args->parameter);\n\t\telse\n\t\t{\n\t\t\tconst char *parameter = args->parameter;\n\t\t\twhile (*parameter == ' ')\n\t\t\t\t++parameter;\n\t\t\tprocessShortOption (args->item, parameter);\n\t\t}\n\t\tcArgForth (args);\n\t}\n}\n\nstatic void parseOptions (cookedArgs* const args)\n{\n\twhile (! cArgOff (args)  &&  cArgIsOption (args))\n\t\tparseOption (args);\n\tif (! cArgOff (args)  &&  ! cArgIsOption (args))\n\t\tNonOptionEncountered = true;\n}\n\nextern void parseCmdlineOptions (cookedArgs* const args)\n{\n\tENTER (Cmdline);\n\tparseOptions (args);\n}\n\nstatic bool checkSameFile (const char *const fileName, void * userData)\n{\n\treturn isSameFile ((const char* const) userData, fileName);\n}\n\nstatic bool parseFileOptions (const char* const fileName)\n{\n\tbool fileFound = false;\n\tconst char* const format = \"Considering option file %s: %s\\n\";\n\tif (stringListHasTest (OptionFiles, checkSameFile, (void *) fileName))\n\t{\n\t\tverbose (format, fileName, \"already considered\");\n\t\tfileFound = true;\n\t}\n\telse\n\t{\n\t\tFILE* const fp = fopen (fileName, \"r\");\n\t\tif (fp == NULL)\n\t\t\tverbose (format, fileName, \"not found\");\n\t\telse\n\t\t{\n\t\t\tcookedArgs* const args = cArgNewFromLineFile (fp);\n\t\t\tvString* file = vStringNewInit (fileName);\n\t\t\tstringListAdd (OptionFiles, file);\n\t\t\tverbose (format, fileName, \"reading...\");\n\t\t\tparseOptions (args);\n\t\t\tif (NonOptionEncountered)\n\t\t\t\terror (WARNING, \"Ignoring non-option in %s\\n\", fileName);\n\t\t\tcArgDelete (args);\n\t\t\tfclose (fp);\n\t\t\tfileFound = true;\n\t\t}\n\t}\n\treturn fileFound;\n}\n\n/* Actions to be taken before reading any other options */\nextern void previewFirstOption (cookedArgs* const args)\n{\n\twhile (cArgIsOption (args))\n\t{\n\t\tif (strcmp (args->item, \"V\") == 0\n\t\t    || strcmp (args->item, \"verbose\") == 0\n\t\t    || strcmp (args->item, \"quiet\") == 0\n\t\t\t/* Make some fundamental options work even\n\t\t\t * if a bropen .ctags is given. */\n\t\t\t|| (strcmp (args->item, \"version\") == 0 &&\n\t\t\t\t(strcmp (args->parameter, RSV_NONE) == 0\n\t\t\t\t ||  (*args->parameter == '\\0')))\n\t\t\t|| strcmp (args->item, \"help\") == 0\n\t\t\t|| strcmp (args->item, \"help-full\") == 0\n\t\t\t|| strcmp (args->item, \"license\") == 0)\n\t\t\tparseOption (args);\n\t\telse if (strcmp (args->item, \"options\") == 0  &&\n\t\t\t\tstrcmp (args->parameter, RSV_NONE) == 0)\n\t\t{\n\t\t\tnotice (\"No options will be read from files or environment\");\n\t\t\tSkipConfiguration = true;\n\t\t\tcArgForth (args);\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n}\n\n#if defined (HAVE_DIRENT_H) || defined (_MSC_VER)\nextern int scanDirectory (const char *directory_name,\n\t\t\t\t\t\t  struct dirent ***array_pointer, int (*select_function) (const struct dirent *),\n\t\t\t\t\t\t  int (*compare_function) (const struct dirent **, const struct dirent **));\n\nstatic void parseConfigurationFileOptionsInDirectoryWithLeafname (const char* directory, const char* leafname)\n{\n\tchar* pathname = combinePathAndFile (directory, leafname);\n\tparseFileOptions (pathname);\n\teFree (pathname);\n}\n\nstatic int ignore_dot_file(const struct dirent* dent)\n{\n\t/* Ignore a file which name is started from dot. */\n\tif (*dent->d_name == '.')\n\t\treturn 0;\n\telse\n\t\treturn 1;\n}\n\nstatic int accept_only_dot_ctags(const struct dirent* dent)\n{\n\tsize_t len;\n\n\t/* accept only a file ended with \".ctags\" */\n\tlen = strlen(dent->d_name);\n\n\tif (len < 7)\n\t\treturn 0;\n\tif (strcmp(dent->d_name + (len - 6), \".ctags\") == 0)\n\t\treturn 1;\n\n\treturn 0;\n}\n\nstatic int alphaSort(const struct dirent ** a,\n\t\t\t\t\t\t\t\t\t  const struct dirent ** b)\n{\n\treturn strcmp ((*a)->d_name, (*b)->d_name);\n}\n\nstatic bool parseAllConfigurationFilesOptionsInDirectory (const char* const dirName,\n\t\t\t\t\t\t\t     stringList* const already_loaded_files)\n{\n\tstruct dirent **dents;\n\tint i, n;\n\n\tn = scanDirectory (dirName, &dents, ignore_dot_file, alphaSort);\n\tif (n < 0)\n\t\treturn false;\n\n\tfor (i = 0; i < n; i++)\n\t{\n\t\tchar* path;\n\t\tfileStatus *s;\n\n\t\tif (already_loaded_files && stringListHas (already_loaded_files, dents[i]->d_name))\n\t\t\tcontinue;\n\t\telse if (already_loaded_files)\n\t\t\tstringListAdd (already_loaded_files, vStringNewInit (dents[i]->d_name));\n\n\t\tpath = combinePathAndFile (dirName, dents[i]->d_name);\n\t\ts = eStat (path);\n\n\t\tif (s->exists && accept_only_dot_ctags(dents[i]))\n\t\t\tparseConfigurationFileOptionsInDirectoryWithLeafname (dirName,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  dents[i]->d_name);\n\t\teStatFree (s);\n\t\tfree (dents[i]);\n\t\teFree (path);\n\t}\n\tfree (dents);\n\treturn true;\n}\n#else\nstatic bool parseAllConfigurationFilesOptionsInDirectory (const char* const dirName,\n\t\t\t\t\t\t\t     stringList* const already_loaded_files)\n{\n\treturn false;\n}\n#endif\n\ntypedef char* (* preloadMakePathFunc) (const char*, const char*);\n\nstruct preloadPathElt {\n\tconst char *path;\t\t\t/* NULL means the end of list */\n\tbool isDirectory;\n\tpreloadMakePathFunc makePath;\n\tconst char *extra;\n\tOptionLoadingStage stage;\n};\n\nstatic char* prependEnvvar (const char *path, const char* envvar)\n{\n\tchar *full_path = NULL;\n\n\tconst char* const envval = getenv (envvar);\n\tif (envval && strlen (envval))\n\t\tfull_path = combinePathAndFile(envval, path);\n\n\treturn full_path;\n}\n\nstatic char *getConfigForXDG (const char *path CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t  const char* extra CTAGS_ATTR_UNUSED)\n{\n\tchar *r = prependEnvvar (\"ctags\", \"XDG_CONFIG_HOME\");\n\tif (r)\n\t\treturn r;\n\n\treturn prependEnvvar (\".config/ctags\", \"HOME\");\n}\n\n#ifdef _WIN32\nstatic char *getConfigAtHomeOnWindows (const char *path,\n\t\t\t\t\t\t\t\t\t   const char* extra CTAGS_ATTR_UNUSED)\n{\n\t/*\n\t * Windows users don't usually set HOME.\n\t * The OS sets HOMEDRIVE and HOMEPATH for them.\n\t */\n\tconst char* homeDrive = getenv (\"HOMEDRIVE\");\n\tconst char* homePath = getenv (\"HOMEPATH\");\n\tif (homeDrive != NULL && homePath != NULL)\n\t{\n\t\tvString* const windowsHome = vStringNew ();\n\t\tvStringCatS (windowsHome, homeDrive);\n\t\tvStringCatS (windowsHome, homePath);\n\n\t\tchar *tmp = vStringIsEmpty (windowsHome)\n\t\t\t? NULL\n\t\t\t: combinePathAndFile (vStringValue(windowsHome), path);\n\n\t\tvStringDelete (windowsHome);\n\t\treturn tmp;\n\t}\n\treturn NULL;\n}\n#endif\n\nstatic void preload (struct preloadPathElt *pathList)\n{\n\tunsigned int i;\n\tstringList* loaded;\n\n\tloaded = stringListNew ();\n\tfor (i = 0; pathList[i].path != NULL || pathList[i].makePath != NULL; ++i)\n\t{\n\t\tstruct preloadPathElt *elt = pathList + i;\n\t\tpreloadMakePathFunc maker = elt->makePath;\n\t\tconst char *path = elt->path;\n\n\n\t\tif (maker)\n\t\t\tpath = maker(elt->path, elt->extra);\n\n\t\tif (path == NULL)\n\t\t\tcontinue;\n\n\t\tAssert (Stage <= elt->stage);\n\t\tif (Stage != elt->stage)\n\t\t{\n\t\t\tStage = elt->stage;\n\t\t\tverbose (\"Entering configuration stage: loading %s\\n\", StageDescription[Stage]);\n\t\t}\n\n\t\tif (elt->isDirectory)\n\t\t\tparseAllConfigurationFilesOptionsInDirectory (path, loaded);\n\t\telse\n\t\t\tparseFileOptions (path);\n\n\t\tif (path != elt->path)\n\t\t\teFree ((void *)path);\n\t}\n\tstringListClear (loaded);\n\tstringListDelete (loaded);\n}\n\nstatic struct preloadPathElt preload_path_list [] = {\n#ifdef CUSTOM_CONFIGURATION_FILE\n\t{\n\t\t.path = CUSTOM_CONFIGURATION_FILE,\n\t\t.isDirectory = false,\n\t\t.makePath = NULL,\n\t\t.stage = OptionLoadingStageCustom,\n\t},\n#endif\n\t{\n\t\t.path = NULL,\n\t\t.isDirectory = true,\n\t\t.makePath = getConfigForXDG,\n\t\t.stage = OptionLoadingStageXdg,\n\t},\n\t{\n\t\t.path = \".ctags.d\",\n\t\t.isDirectory = true,\n\t\t.makePath = prependEnvvar,\n\t\t.extra = \"HOME\",\n\t\t.stage = OptionLoadingStageHomeDir,\n\t},\n#ifdef _WIN32\n\t{\n\t\t.path = \"ctags.d\",\n\t\t.isDirectory = true,\n\t\t.makePath = getConfigAtHomeOnWindows,\n\t\t.extra = NULL,\n\t\t.stage = OptionLoadingStageHomeDir,\n\t},\n#endif\n\t{\n\t\t.path = \".ctags.d\",\n\t\t.isDirectory = true,\n\t\t.makePath = NULL,\n\t\t.stage = OptionLoadingStageCurrentDir,\n\t},\n\t{\n\t\t.path = \"ctags.d\",\n\t\t.isDirectory = true,\n\t\t.makePath = NULL,\n\t\t.stage = OptionLoadingStageCurrentDir,\n\t},\n\t{\n\t\t.path = NULL,\n\t\t.makePath = NULL,\n\t},\n};\n\nstatic void parseConfigurationFileOptions (void)\n{\n\tpreload (preload_path_list);\n}\n\nextern void readOptionConfiguration (void)\n{\n\tif (! SkipConfiguration)\n\t\tparseConfigurationFileOptions ();\n}\n\nstatic stringList* optlibPathListNew(struct preloadPathElt *pathList)\n{\n\tstringList * appended = stringListNew ();\n\n\tfor (size_t i = 0; pathList[i].path != NULL || pathList[i].makePath != NULL; ++i)\n\t{\n\t\tstruct preloadPathElt *elt = pathList + i;\n\t\tpreloadMakePathFunc maker = elt->makePath;\n\t\tconst char *path = elt->path;\n\n\t\tif (!elt->isDirectory)\n\t\t\tcontinue;\n\n\t\tif (elt->stage == OptionLoadingStageCurrentDir)\n\t\t\tcontinue;\n\n\t\tif (maker)\n\t\t\tpath = maker(elt->path, elt->extra);\n\n\t\tif (path == NULL)\n\t\t\tcontinue;\n\n\t\tvString *vpath;\n\t\tif (path == elt->path)\n\t\t\tvpath = vStringNewInit (path);\n\t\telse\n\t\t\tvpath = vStringNewOwn ((char *)path);\n\t\tstringListAdd(appended, vpath);\n\t}\n\n\treturn appended;\n}\n\n/*\n*   Option initialization\n*/\n\nextern void initOptions (void)\n{\n\tOptionFiles = stringListNew ();\n\tOptlibPathList = optlibPathListNew (preload_path_list);\n\n\tverbose (\"Setting option defaults\\n\");\n\tinstallHeaderListDefaults ();\n\tverbose (\"  Installing default language mappings:\\n\");\n\tinstallLanguageMapDefaults ();\n\tverbose (\"  Installing default language aliases:\\n\");\n\tinstallLanguageAliasesDefaults ();\n\n\t/* always excluded by default */\n\tverbose (\"  Installing default exclude patterns:\\n\");\n\tprocessExcludeOption (NULL, \"{arch}\");\n\tprocessExcludeOption (NULL, \".arch-ids\");\n\tprocessExcludeOption (NULL, \".arch-inventory\");\n\tprocessExcludeOption (NULL, \"autom4te.cache\");\n\tprocessExcludeOption (NULL, \"BitKeeper\");\n\tprocessExcludeOption (NULL, \".bzr\");\n\tprocessExcludeOption (NULL, \".bzrignore\");\n\tprocessExcludeOption (NULL, \"CVS\");\n\tprocessExcludeOption (NULL, \".cvsignore\");\n\tprocessExcludeOption (NULL, \"_darcs\");\n\tprocessExcludeOption (NULL, \".deps\");\n\tprocessExcludeOption (NULL, \".dvi\");\n\tprocessExcludeOption (NULL, \".DS_Store\");\n\tprocessExcludeOption (NULL, \"EIFGEN\");\n\tprocessExcludeOption (NULL, \".git\");\n\tprocessExcludeOption (NULL, \".gitignore\");\n\tprocessExcludeOption (NULL, \".gitattributes\");\n\tprocessExcludeOption (NULL, \".hg\");\n\tprocessExcludeOption (NULL, \".hgignore\");\n\tprocessExcludeOption (NULL, \"PENDING\");\n\tprocessExcludeOption (NULL, \"RCS\");\n\tprocessExcludeOption (NULL, \"RESYNC\");\n\tprocessExcludeOption (NULL, \"SCCS\");\n\tprocessExcludeOption (NULL, \".svn\");\n\tprocessExcludeOption (NULL, \"*~\");\n\tprocessExcludeOption (NULL, \".*.swp\");\n\n\t/* Exclude binary files\n\t * -----------------------------------------------\n\t *\n\t * TODO\n\t *\n\t * It will be interesting if ctags can extract\n\t * symbols from these binaries.\n\t *\n\t * --langdef=nm --regex-nm=...\n\t * --langdef=elf --pre-processor-elf=/bin/nm ...\n\t *\n\t * vim/emacs users never wants the cursor to jump to\n\t * a binary file but may wants to utilize the symbol\n\t * information for completion.\n\t *\n\t * https://bitbucket.org/haypo/hachoir3 can be\n\t * used the alternative for /bin/nm\n\t */\n\tprocessExcludeOption (NULL, \"*.o\");\n\tprocessExcludeOption (NULL, \"*.a\");\n\tprocessExcludeOption (NULL, \"*.so\");\n\n\tprocessExcludeOption (NULL, \"*.obj\");\n\tprocessExcludeOption (NULL, \"*.lib\");\n\tprocessExcludeOption (NULL, \"*.dll\");\n\tprocessExcludeOption (NULL, \"*.exe\");\n\n\tprocessExcludeOption (NULL, \"*.gcno\");\n\tprocessExcludeOption (NULL, \"*.gcda\");\n\n\tprocessExcludeOption (NULL, \"*.class\");\n\n\tprocessExcludeOption (NULL, \"*.pyc\");\n\tprocessExcludeOption (NULL, \"*.pyo\");\n}\n\nextern void freeOptionResources (void)\n{\n\tfreeString (&Option.tagFileName);\n\tfreeString (&Option.fileList);\n\tfreeString (&Option.filterTerminator);\n\n\tfreeList (&Excluded);\n\tfreeList (&ExcludedException);\n\tfreeList (&Option.headerExt);\n\tfreeList (&Option.etagsInclude);\n\n\tfreeSearchPathList (&OptlibPathList);\n\n\tfreeList (&OptionFiles);\n}\n\nstatic void processDumpOptionsOption (const char *const option CTAGS_ATTR_UNUSED, const char *const parameter CTAGS_ATTR_UNUSED)\n{\n\tfprintf(stdout, \"# %s\\n\", \"ParametricOptions\");\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(ParametricOptions); i++)\n\t\tfprintf(stdout, \"%s\\n\", ParametricOptions[i].name);\n\n\tfprintf(stdout, \"# %s\\n\", \"BooleanOptions\");\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(BooleanOptions); i++)\n\t\tfprintf(stdout, \"%s\\n\", BooleanOptions[i].name);\n}\n\nstatic void processDumpPreludeOption (const char *const option CTAGS_ATTR_UNUSED, const char *const parameter CTAGS_ATTR_UNUSED)\n{\n\textern const char ctagsCommonPrelude[];\n\tfprintf(stdout, \"%s\\n\", ctagsCommonPrelude);\n\texit (0);\n}\n\nextern bool inSandbox (void)\n{\n\treturn (Option.interactive == INTERACTIVE_SANDBOX);\n}\n\nextern bool canUseLineNumberAsLocator (void)\n{\n\treturn (Option.locate != EX_PATTERN);\n}\n\nextern bool isDestinationStdout (void)\n{\n\tbool toStdout = false;\n\n\tif (Option.filter || Option.interactive ||\n\t\t(Option.tagFileName != NULL  &&  (strcmp (Option.tagFileName, \"-\") == 0\n\t\t\t\t\t\t  || strcmp (Option.tagFileName, \"/dev/stdout\") == 0\n\t\t)))\n\t\ttoStdout = true;\n\telse if (Option.tagFileName == NULL && NULL == outputDefaultFileName ())\n\t\ttoStdout = true;\n\n\treturn toStdout;\n}\n"
  },
  {
    "path": "main/options.h",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines external interface to option processing.\n*/\n#ifndef CTAGS_MAIN_OPTIONS_H\n#define CTAGS_MAIN_OPTIONS_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"gvars.h\"\n\n#include <stdarg.h>\n\n\n/*\n*   DATA DECLARATIONS\n*/\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void verbose (const char *const format, ...) CTAGS_ATTR_PRINTF (1, 2);\n\n#define BEGIN_VERBOSE(VFP) do { if (ctags_verbose) { \\\n                                FILE* VFP = stderr\n#define END_VERBOSE()      } } while (0)\n\n#define BEGIN_VERBOSE_IF(COND,VFP) do { if (ctags_verbose || (COND)) { \\\n                                FILE* VFP = stderr\n\n\nextern bool inSandbox (void);\n\n/* This is for emitting a tag for a common block of Fortran parser*/\nextern bool canUseLineNumberAsLocator (void);\n\n#endif  /* CTAGS_MAIN_OPTIONS_H */\n"
  },
  {
    "path": "main/options_p.h",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines internal interface to option processing.\n*/\n#ifndef CTAGS_MAIN_OPTIONS_PRIVATE_H\n#define CTAGS_MAIN_OPTIONS_PRIVATE_H\n\n#if defined(OPTION_WRITE)\n# define CONST_OPTION\n#else\n# define CONST_OPTION const\n#endif\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"args_p.h\"\n#include \"field.h\"\n#include \"fmt_p.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"strlist.h\"\n#include \"vstring.h\"\n\n/*\n*   MACROS\n*/\n#define includeExtensionFlags()         (Option.tagFileFormat > 1)\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef enum { OPTION_NONE, OPTION_SHORT, OPTION_LONG } optionType;\n\ntypedef struct sCookedArgs {\n\t/* private */\n\tArguments* args;\n\tchar *shortOptions;\n\tchar simple[2];\n\tbool isOption;\n\tbool longOption;\n\tconst char* parameter;\n\t/* public */\n\tchar* item;\n} cookedArgs;\n\ntypedef enum eLocate {\n\tEX_MIX,      /* line numbers for defines, patterns otherwise */\n\tEX_LINENUM,  /* -n  only line numbers in tag file */\n\tEX_PATTERN,  /* -N  only patterns in tag file */\n\tEX_COMBINE,  /* Combine linenum and pattern with `;'*/\n} exCmd;\n\ntypedef enum sortType {\n\tSO_UNSORTED,\n\tSO_SORTED,\n\tSO_FOLDSORTED\n} sortType;\n\ntypedef enum eTagRelative {\n\tTREL_NO,\n\tTREL_YES,\n\tTREL_ALWAYS,\n\tTREL_NEVER,\n} tagRelative;\n\n/*  This stores the command line options.\n */\ntypedef struct sOptionValues {\n\tbool append;         /* -a  append to \"tags\" file */\n\tbool backward;       /* -B  regexp patterns search backwards */\n\tbool etags;          /* -e  output Emacs style tags file */\n\texCmd locate;           /* --excmd  EX command used to locate tag */\n\tbool recurse;        /* -R  recurse into directories */\n\tsortType sorted;        /* -u,--sort  sort tags */\n\tbool xref;           /* -x  generate xref output instead */\n\tfmtElement *customXfmt;\t/* compiled code for --xformat=XFMT */\n\tchar *fileList;         /* -L  name of file containing names of files */\n\tchar *tagFileName;      /* -o  name of tags file */\n\tstringList* headerExt;  /* -h  header extensions */\n\tstringList* etagsInclude;/* --etags-include  list of TAGS files to include*/\n\tunsigned int tagFileFormat;/* --format  tag file format (level) */\n#ifdef HAVE_ICONV\n\tchar *inputEncoding;\t/* --input-encoding\tconvert text into --output-encoding */\n\tchar *outputEncoding;\t/* --output-encoding\twrite tags file as this encoding */\n#endif\n\tlangType language;      /* --lang specified language override */\n\tbool followLinks;    /* --link  follow symbolic links? */\n\tbool filter;         /* --filter  behave as filter: files in, tags out */\n\tchar* filterTerminator; /* --filter-terminator  string to output */\n\ttagRelative tagRelative;    /* --tag-relative file paths relative to tag file */\n\tint  printTotals;    /* --totals  print cumulative statistics */\n\tbool lineDirectives; /* --line-directives  process #line directives */\n\tbool printLanguage;  /* --print-language */\n\tbool guessLanguageEagerly; /* --guess-language-eagerly|-G */\n\tbool quiet;\t\t      /* --quiet */\n\tbool fatalWarnings;\t/* --_fatal-warnings */\n\tunsigned int patternLengthLimit; /* --pattern-length-limit=N */\n\tbool putFieldPrefix;\t\t /* --put-field-prefix */\n\tunsigned int maxRecursionDepth; /* --maxdepth=<max-recursion-depth> */\n\tbool fieldsReset;\t\t\t\t/* --fields=[^+-] */\n\tenum interactiveMode { INTERACTIVE_NONE = 0,\n\t\t\t\t\t\t   INTERACTIVE_DEFAULT,\n\t\t\t\t\t\t   INTERACTIVE_SANDBOX, } interactive; /* --interactive */\n#ifdef _WIN32\n\tenum filenameSepOp { FILENAME_SEP_NO_REPLACE = false,\n\t\t\t\t\t\t FILENAME_SEP_USE_SLASH  = true,\n\t\t\t\t\t\t FILENAME_SEP_UNSET,\n\t} useSlashAsFilenameSeparator; /* --use-slash-as-filename-separator */\n#endif\n#ifdef DEBUG\n\tunsigned long breakLine;/* -b  input line at which to call lineBreak() */\n#endif\n\n} optionValues;\n\ntypedef void (* mainLoopFunc) (cookedArgs *args, void *data);\n\n/*\n*   GLOBAL VARIABLES\n*/\n\nextern CONST_OPTION optionValues\t\tOption;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void freeList (stringList** const pString);\nextern void setDefaultTagFileName (void);\nextern void checkOptions (void);\nextern bool filesRequired (void);\nextern void testEtagsInvocation (void);\n\nextern cookedArgs* cArgNewFromString (const char* string);\nextern cookedArgs* cArgNewFromArgv (char* const* const argv);\nextern cookedArgs* cArgNewFromFile (FILE* const fp);\nextern cookedArgs* cArgNewFromLineFile (FILE* const fp);\nextern void cArgDelete (cookedArgs* const current);\nextern bool cArgOff (cookedArgs* const current);\nextern bool cArgIsOption (cookedArgs* const current);\nextern const char* cArgItem (cookedArgs* const current);\nextern void cArgForth (cookedArgs* const current);\nextern bool isExcludedFile (const char* const name,\n\t\t\t\t\t\t\tbool falseIfExceptionsAreDefined);\nextern bool isIncludeFile (const char *const fileName);\nextern void parseCmdlineOptions (cookedArgs* const cargs);\nextern void previewFirstOption (cookedArgs* const cargs);\nextern void readOptionConfiguration (void);\nextern void initOptions (void);\nextern void freeOptionResources (void);\n\nextern langType getLanguageComponentInOption (const char *const option,\n\t\t\t\t\t      const char *const prefix);\nextern langType getLanguageComponentInOptionFull (const char *const option,\n\t\t\t\t\t      const char *const prefix, bool noPretending);\n\nextern void processLanguageDefineOption (const char *const option, const char *const parameter);\nextern bool processMapOption (const char *const option, const char *const parameter);\nextern bool processParamdefOption (const char *const option, const char *const value);\nextern bool processParamOption (const char *const option, const char *const value);\nextern bool processKinddefOption (const char *const option, const char *const parameter);\nextern bool processKindsOption (const char *const option, const char *const parameter);\nextern bool processExtradefOption (const char *const option, const char *const parameter);\nextern bool processFielddefOption (const char *const option, const char *const parameter);\nextern bool processAliasOption (const char *const option, const char *const parameter);\nextern bool processTabledefOption (const char *const option, const char *const parameter);\n#ifdef HAVE_ICONV\nextern bool processLanguageEncodingOption (const char *const option, const char *const parameter);\n#endif\nextern bool processRoledefOption (const char *const option, const char *const parameter);\nextern bool processScopesepOption (const char *const option, const char *const parameter);\nextern bool processPreludeOption (const char *const option, const char *const parameter);\nextern bool processSequelOption (const char *const option, const char *const parameter);\nextern bool processPretendOption (const char *const option, const char *const parameter);\nextern bool processRolesOption (const char *const option, const char *const parameter);\n\nextern bool isDestinationStdout (void);\n\nextern void setMainLoop (mainLoopFunc func, void *data);\n\nextern bool ptagMakePatternLengthLimit (ptagDesc *pdesc, langType langType, const void *data);\n#endif  /* CTAGS_MAIN_OPTIONS_PRIVATE_H */\n"
  },
  {
    "path": "main/param.c",
    "content": "/*\n *\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#include \"general.h\"\n#include \"options.h\"\n#include \"param.h\"\n#include \"param_p.h\"\n#include \"parse.h\"\n\n#include <string.h>\n\ntypedef struct sParamObject {\n\tparamDefinition *def;\n\tfreeParamDefFunc free;\n} paramObject;\n\nstruct paramControlBlock {\n\tparamObject *param;\n\tunsigned int count;\n\tlangType owner;\n};\n\nextern struct paramControlBlock* allocParamControlBlock (parserDefinition *parser)\n{\n\tstruct paramControlBlock *pcb;\n\n\tpcb = xMalloc (1, struct paramControlBlock);\n\tpcb->param = xMalloc (parser->paramCount, paramObject);\n\tpcb->count = parser->paramCount;\n\tpcb->owner = parser->id;\n\n\tfor (unsigned int i = 0; i < parser->paramCount; ++i)\n\t{\n\t\tparamObject *param = pcb->param + i;\n\t\tparam->def = parser->paramTable + i;\n\t\tparam->free = NULL;\n\t}\n\n\treturn pcb;\n}\n\nextern void freeParamControlBlock (struct paramControlBlock* pcb)\n{\n\tfor (unsigned int i = 0; i< pcb->count; ++i)\n\t{\n\t\tif (pcb->param [i].free)\n\t\t\tpcb->param [i].free (pcb->param [i].def);\n\t}\n\tif (pcb->param)\n\t\teFree (pcb->param);\n\teFree (pcb);\n}\n\nextern int  defineParam (struct paramControlBlock* pcb, paramDefinition *def,\n\t\t\t\t\t\t freeParamDefFunc freeParamDef)\n{\n\tunsigned int id = pcb->count++;\n\tpcb->param = xRealloc (pcb->param, pcb->count, paramObject);\n\tpcb->param [id].def = def;\n\tpcb->param [id].free = freeParamDef;\n\n\tverbose (\"Add param[%d] \\\"%s,%s\\\" to %s\\n\", id,\n\t\t\t def->name, def->desc,\n\t\t\t getLanguageName (pcb->owner));\n\n\treturn id;\n}\n\nextern bool applyParam (struct paramControlBlock* pcb, const char *name, const char *args)\n{\n\tfor (unsigned int i = 0; i < pcb->count; i++)\n\t{\n\t\tparamDefinition *pdef = pcb->param[i].def;\n\t\tif (strcmp(pdef->name, name) == 0)\n\t\t{\n\t\t\tif (pdef->handleParam == NULL)\n\t\t\t\treturn true;\n\t\t\treturn pdef->handleParam (pcb->owner, name, args);\n\t\t}\n\t}\n\tconst char *lang = getLanguageName (pcb->owner);\n\terror (FATAL, \"no such parameter in %s: %s\", lang, name);\n\treturn false;\n}\n\nextern struct colprintTable * paramColprintTableNew (void)\n{\n\treturn colprintTableNew (\"L:LANGUAGE\", \"L:NAME\",\"L:DESCRIPTION\", NULL);\n}\n\nextern void paramColprintAddParams (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\tstruct paramControlBlock* pcb)\n{\n\tconst char *lang = getLanguageName (pcb->owner);\n\tfor (unsigned int i = 0; i < pcb->count; i++)\n\t{\n\t\tparamDefinition *pdef = pcb->param [i].def;\n\t\tstruct colprintLine *line = colprintTableGetNewLine(table);\n\n\t\tcolprintLineAppendColumnCString (line, lang);\n\t\tcolprintLineAppendColumnCString (line, pdef->name);\n\t\tcolprintLineAppendColumnCString (line, pdef->desc);\n\t}\n}\n\nstatic int paramColprintCompareLines (struct colprintLine *a , struct colprintLine *b)\n{\n\tconst char *a_parser = colprintLineGetColumn (a, 0);\n\tconst char *b_parser = colprintLineGetColumn (b, 0);\n\n\tint r;\n\tr = strcmp (a_parser, b_parser);\n\tif (r != 0)\n\t\treturn r;\n\n\tconst char *a_name = colprintLineGetColumn (a, 1);\n\tconst char *b_name = colprintLineGetColumn (b, 1);\n\n\treturn strcmp(a_name, b_name);\n}\n\nextern void paramColprintTablePrint (struct colprintTable *table, bool noparser,\n\t\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp)\n{\n\tcolprintTableSort (table, paramColprintCompareLines);\n\tcolprintTablePrint (table, noparser? 1: 0, withListHeader, machinable, fp);\n}\n"
  },
  {
    "path": "main/param.h",
    "content": "/*\n *\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_PARAM_H\n#define CTAGS_MAIN_PARAM_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n\n#include \"types.h\"\n\n\n/*\n*   DATA DECLARATIONS\n*/\nstruct sParamDefinition {\n\tconst char *name;\n\tconst char *desc;\n\tbool  (* handleParam) (langType lang, const char *name, const char *arg);\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern bool paramParserBool (const char *value, bool fallback,\n\t\t\t\t\t\t\t const char *errWhat, const char *errCategory);\n\n#endif\t/* CTAGS_MAIN_PARAM_H */\n"
  },
  {
    "path": "main/param_p.h",
    "content": "/*\n *\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_PARAM_PRIVATE_H\n#define CTAGS_MAIN_PARAM_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n\n#include \"types.h\"\n#include \"colprint_p.h\"\n\n\n/*\n*   DATA DECLARATIONS\n*/\nstruct paramControlBlock;\ntypedef void (* freeParamDefFunc) (paramDefinition *);\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern bool applyParameter (const langType language, const char *name, const char *args);\n\nextern struct colprintTable * paramColprintTableNew (void);\nextern void paramColprintAddParams (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\tstruct paramControlBlock* pcb);\nextern void paramColprintTablePrint (struct colprintTable *table, bool noparser,\n\t\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp);\n\nextern struct paramControlBlock* allocParamControlBlock (parserDefinition *parser);\nextern void freeParamControlBlock (struct paramControlBlock* pcb);\nextern int  defineParam (struct paramControlBlock* pcb, paramDefinition *def,\n\t\t\t\t\t\t freeParamDefFunc freeParamDef);\nextern bool applyParam (struct paramControlBlock* pcb, const char *name, const char *args);\n\n#endif\t/* CTAGS_MAIN_PARAM_PRIVATE_H */\n"
  },
  {
    "path": "main/parse.c",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for managing input languages and\n*   dispatching files to the appropriate language parser.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n/* TODO: This definition should be removed. */\n#define OPTION_WRITE\n#include \"options_p.h\"\n\n#include <string.h>\n#include <ctype.h>\n\n#include \"ctags.h\"\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"field_p.h\"\n#include \"flags_p.h\"\n#include \"htable.h\"\n#include \"keyword.h\"\n#include \"lxpath_p.h\"\n#include \"param.h\"\n#include \"param_p.h\"\n#include \"parse_p.h\"\n#include \"parsers_p.h\"\n#include \"promise.h\"\n#include \"promise_p.h\"\n#include \"ptag_p.h\"\n#include \"ptrarray.h\"\n#include \"read.h\"\n#include \"read_p.h\"\n#include \"rexprcode_p.h\"\n#include \"routines.h\"\n#include \"routines_p.h\"\n#include \"stats_p.h\"\n#include \"subparser.h\"\n#include \"subparser_p.h\"\n#include \"trace.h\"\n#include \"trashbox.h\"\n#include \"trashbox_p.h\"\n#include \"vstring.h\"\n#ifdef HAVE_ICONV\n# include \"mbcs_p.h\"\n#endif\n#include \"writer_p.h\"\n#include \"xtag_p.h\"\n\n/*\n * DATA TYPES\n */\nenum specType {\n\tSPEC_NONE,\n\tSPEC_NAME,\n\tSPEC_ALIAS = SPEC_NAME,\n\tSPEC_EXTENSION,\n\tSPEC_PATTERN,\n\tSPEC_REXPR,\n};\nconst char *specTypeName [] = {\n\t\"none\", \"name\", \"extension\", \"pattern\", \"rexpr\"\n};\n\ntypedef struct {\n\tlangType lang;\n\tconst char* spec;\n\tenum specType specType;\n}  parserCandidate;\n\ntypedef struct sParserObject {\n\tparserDefinition *def;\n\n\tkindDefinition* fileKind;\n\n\tstringList* currentPatterns;   /* current list of file name patterns */\n\tstringList* currentExtensions; /* current list of extensions */\n\tstringList* currentAliases;    /* current list of aliases */\n\tptrArray*   currentRexprs;\t   /* current list of regular expressions (rexprs). */\n\n\tunsigned int initialized:1;    /* initialize() is called or not */\n\tunsigned int dontEmit:1;\t   /* run but don't emit tags.\n\t\t\t\t\t\t\t\t\t  This parser was disabled but a subparser on\n\t\t\t\t\t\t\t\t\t  this parser makes this parser run (to drive\n\t\t\t\t\t\t\t\t\t  the subparser). */\n\tunsigned int pseudoTagPrinted:1;   /* pseudo tags about this parser\n\t\t\t\t\t\t\t\t\t\t  is emitted or not. */\n\tunsigned int justRunForSchedulingBase:1;\n\tunsigned int used;\t\t\t/* Used for printing language specific statistics. */\n\n\tunsigned int anonymousIdentiferId; /* managed by anon* functions */\n\n\tstruct slaveControlBlock *slaveControlBlock;\n\tstruct kindControlBlock *kindControlBlock;\n\tstruct lregexControlBlock *lregexControlBlock;\n\tstruct paramControlBlock *paramControlBlock;\n\n\tlangType pretendingAsLanguage; /* OLDLANG in --_pretend-<NEWLANG>=<OLDLANG>\n\t\t\t\t\t\t\t\t\t  is set here if this parser is NEWLANG.\n\t\t\t\t\t\t\t\t\t  LANG_IGNORE is set if no pretending. */\n\tlangType pretendedAsLanguage;  /* NEWLANG in --_pretend-<NEWLANG>=<OLDLANG>\n\t\t\t\t\t\t\t\t\t  is set here if this parser is OLDLANG.\n\t\t\t\t\t\t\t\t\t  LANG_IGNORE is set if no being pretended. */\n\n\tparserDefinitionFunc *parserDefFunc; /* Used when --languages=_CATEGORY\n\t\t\t\t\t\t\t\t\t\t\tis specified. */\n} parserObject;\n\n/*\n * FUNCTION PROTOTYPES\n */\n\nstatic void lazyInitialize (langType language);\nstatic void addParserPseudoTags (langType language);\nstatic void installKeywordTable (const langType language);\nstatic void installTagRegexTable (const langType language);\nstatic void installTagXpathTable (const langType language);\nstatic void anonResetMaybe (parserObject *parser);\nstatic void setupAnon (void);\nstatic void teardownAnon (void);\nstatic void uninstallTagXpathTable (const langType language);\nstatic bool hasLanguageAnyRegexPatterns (const langType language);\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic parserDefinition *FallbackParser (void);\nstatic parserDefinition *CTagsParser (void);\nstatic parserDefinition *CTagsSelfTestParser (void);\nstatic parserDefinitionFunc* BuiltInParsers[] = {\n#ifdef EXTERNAL_PARSER_LIST\n\tEXTERNAL_PARSER_LIST\n#else  /* ! EXTERNAL_PARSER_LIST */\n\tCTagsParser,\t\t\t\t/* This must be first entry. */\n\tFallbackParser,\t\t\t\t/* LANG_FALLBACK */\n\tCTagsSelfTestParser,\n\n\tPARSER_LIST,\n\tXML_PARSER_LIST\n#ifdef HAVE_LIBXML\n\t,\n#endif\n\tYAML_PARSER_LIST\n#ifdef HAVE_LIBYAML\n\t,\n#endif\n\t   PEG_PARSER_LIST\n#ifdef HAVE_PACKCC\n\t   ,\n#endif\n\t   OPTLIB2C_PCRE2_PARSER_LIST\n#ifdef HAVE_PCRE2\n\t  ,\n#endif\n#endif\t/* EXTERNAL_PARSER_LIST */\n};\nstatic parserObject* LanguageTable = NULL;\nstatic unsigned int LanguageCount = 0;\nstatic hashTable* LanguageHTable = NULL;\nstatic kindDefinition defaultFileKind = {\n\t.enabled     = false,\n\t.letter      = KIND_FILE_DEFAULT_LETTER,\n\t.name        = KIND_FILE_DEFAULT_NAME,\n\t.description = KIND_FILE_DEFAULT_NAME,\n};\n\nstatic langType ctagsSelfTestLang;\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic bool isLanguageNameChar(int c)\n{\n\tif (isgraph(c))\n\t{\n\t\tif (c == '\\'' || c == '\"' || c == ';')\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nextern unsigned int countParsers (void)\n{\n\treturn LanguageCount;\n}\n\nextern int makeSimpleTag (\n\t\tconst vString* const name, const int kindIndex)\n{\n\treturn makeSimpleRefTag (name, kindIndex, ROLE_DEFINITION_INDEX);\n}\n\nextern int makeSimpleRefTag (const vString* const name, const int kindIndex,\n\t\t\t\t int roleIndex)\n{\n\tint r = CORK_NIL;\n\n\tAssert (roleIndex < (int)countInputLanguageRoles(kindIndex));\n\n\t/* do not check for kind being disabled - that happens later in makeTagEntry() */\n\tif (name != NULL  &&  vStringLength (name) > 0)\n\t{\n\t\ttagEntryInfo e;\n\t\tinitRefTagEntry (&e, vStringValue (name), kindIndex, roleIndex);\n\n\t\tr = makeTagEntry (&e);\n\t}\n\treturn r;\n}\n\nextern int makeSimplePlaceholder(const vString* const name)\n{\n\treturn makePlaceholder (vStringValue (name));\n}\n\nextern bool isLanguageEnabled (const langType language)\n{\n\tconst parserDefinition* const def = LanguageTable [language].def;\n\treturn def->enabled;\n}\n\nextern bool isLanguageVisible (const langType language)\n{\n\tconst parserDefinition* const lang = LanguageTable [language].def;\n\n\treturn !lang->invisible;\n}\n\n/*\n*   parserDescription mapping management\n*/\n\nextern parserDefinition* parserNew (const char* name)\n{\n\tparserDefinition* result = xCalloc (1, parserDefinition);\n\tresult->name = eStrdup (name);\n\n\tresult->enabled = true;\n\treturn result;\n}\n\nextern bool doesLanguageAllowNullTag (const langType language)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\treturn LanguageTable [language].def->allowNullTag;\n}\n\nextern bool doesLanguageRequestAutomaticFQTag (const langType language)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\treturn LanguageTable [language].def->requestAutomaticFQTag;\n}\n\nstatic const char *getLanguageNameFull (const langType language, bool noPretending)\n{\n\tconst char* result;\n\n\tif (language == LANG_IGNORE)\n\t\tresult = \"unknown\";\n\telse\n\t{\n\t\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\t\tif (noPretending)\n\t\t\tresult = LanguageTable [language].def->name;\n\t\telse\n\t\t{\n\t\t\tlangType real_language = LanguageTable [language].pretendingAsLanguage;\n\t\t\tif (real_language == LANG_IGNORE)\n\t\t\t\tresult = LanguageTable [language].def->name;\n\t\t\telse\n\t\t\t{\n\t\t\t\tAssert (0 <= real_language  &&  real_language < (int) LanguageCount);\n\t\t\t\tresult = LanguageTable [real_language].def->name;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\nextern const char *getLanguageName (const langType language)\n{\n\treturn getLanguageNameFull (language, false);\n}\n\nextern const char *getLanguageKindName (const langType language, const int kindIndex)\n{\n\tkindDefinition* kdef = getLanguageKind (language, kindIndex);\n\treturn kdef->name;\n}\n\nstatic kindDefinition kindGhost = {\n\t.letter = KIND_GHOST_LETTER,\n\t.name = KIND_GHOST_NAME,\n\t.description = KIND_GHOST_NAME,\n};\n\nextern int defineLanguageKind (const langType language, kindDefinition *def,\n\t\t\t\t\t\t\t   freeKindDefFunc freeKindDef)\n{\n\treturn defineKind (LanguageTable [language].kindControlBlock, def, freeKindDef);\n}\n\nextern unsigned int countLanguageKinds (const langType language)\n{\n\treturn countKinds (LanguageTable [language].kindControlBlock);\n}\n\nextern unsigned int countLanguageRoles (const langType language, int kindIndex)\n{\n\treturn countRoles (LanguageTable [language].kindControlBlock, kindIndex);\n}\n\nextern kindDefinition* getLanguageKind (const langType language, int kindIndex)\n{\n\tkindDefinition* kdef;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\tswitch (kindIndex)\n\t{\n\tcase KIND_FILE_INDEX:\n\t\tkdef = LanguageTable [language].fileKind;\n\t\tbreak;\n\tcase KIND_GHOST_INDEX:\n\t\tkdef = &kindGhost;\n\t\tbreak;\n\tdefault:\n\t\tAssert (kindIndex >= 0);\n\t\tkdef = getKind (LanguageTable [language].kindControlBlock, kindIndex);\n\t}\n\treturn kdef;\n}\n\nextern kindDefinition* getLanguageKindForLetter (const langType language, char kindLetter)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tif (kindLetter == LanguageTable [language].fileKind->letter)\n\t\treturn LanguageTable [language].fileKind;\n\telse if (kindLetter == KIND_GHOST_LETTER)\n\t\treturn &kindGhost;\n\telse\n\t\treturn getKindForLetter (LanguageTable [language].kindControlBlock, kindLetter);\n}\n\nextern kindDefinition* getLanguageKindForName (const langType language, const char *kindName)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tAssert (kindName);\n\n\tif (strcmp(kindName, LanguageTable [language].fileKind->name) == 0)\n\t\treturn LanguageTable [language].fileKind;\n\telse if (strcmp(kindName, KIND_GHOST_NAME) == 0)\n\t\treturn &kindGhost;\n\telse\n\t\treturn getKindForName (LanguageTable [language].kindControlBlock, kindName);\n}\n\nextern roleDefinition* getLanguageRole(const langType language, int kindIndex, int roleIndex)\n{\n\treturn getRole (LanguageTable [language].kindControlBlock, kindIndex, roleIndex);\n}\n\nextern roleDefinition* getLanguageRoleForName (const langType language, int kindIndex,\n\t\t\t\t\t\t\t\t\t\t\t   const char *roleName)\n{\n\treturn getRoleForName (LanguageTable [language].kindControlBlock, kindIndex, roleName);\n}\n\nextern langType getNamedLanguageFull (const char *const name, size_t len, bool noPretending,\n\t\t\t\t\t\t\t\t\t  bool include_aliases)\n{\n\tlangType result = LANG_IGNORE;\n\tunsigned int i;\n\tAssert (name != NULL);\n\n\tif (len == 0)\n\t{\n\t\tparserDefinition *def = (parserDefinition *)hashTableGetItem (LanguageHTable, name);\n\t\tif (def)\n\t\t\tresult = def->id;\n\t}\n\telse\n\t\tfor (i = 0  ;  i < LanguageCount  &&  result == LANG_IGNORE  ;  ++i)\n\t\t{\n\t\t\tconst parserDefinition* const lang = LanguageTable [i].def;\n\t\t\tAssert (lang->name);\n\t\t\tvString* vstr = vStringNewInit (name);\n\t\t\tvStringTruncate (vstr, len);\n\n\t\t\tif (strcasecmp (vStringValue (vstr), lang->name) == 0)\n\t\t\t\tresult = i;\n\t\t\telse if (include_aliases)\n\t\t\t{\n\t\t\t\tstringList* const aliases = LanguageTable [i].currentAliases;\n\t\t\t\tif (aliases && stringListCaseMatched (aliases, vStringValue (vstr)))\n\t\t\t\t\tresult = i;\n\t\t\t}\n\t\t\tvStringDelete (vstr);\n\t\t}\n\n\tif (result != LANG_IGNORE\n\t\t&& (!noPretending)\n\t\t&& LanguageTable [result].pretendedAsLanguage != LANG_IGNORE)\n\t\tresult = LanguageTable [result].pretendedAsLanguage;\n\n\treturn result;\n}\n\nextern langType getNamedLanguage (const char *const name, size_t len)\n{\n\treturn getNamedLanguageFull (name, len, false, false);\n}\n\nextern langType getNamedLanguageOrAlias (const char *const name, size_t len)\n{\n\treturn getNamedLanguageFull (name, len, false, true);\n}\n\nstatic langType getNameOrAliasesLanguageAndSpec (const char *const key, langType start_index,\n\t\t\t\t\t\t const char **const spec, enum specType *specType)\n{\n\tlangType result = LANG_IGNORE;\n\tunsigned int i;\n\n\n\tif (start_index == LANG_AUTO)\n\t\t\tstart_index = 0;\n\telse if (start_index == LANG_IGNORE || start_index >= (int) LanguageCount)\n\t\treturn result;\n\n\tfor (i = start_index  ;  i < LanguageCount  &&  result == LANG_IGNORE  ;  ++i)\n\t{\n\t\tif (! isLanguageEnabled (i))\n\t\t\tcontinue;\n\n\t\tconst parserObject* const parser = LanguageTable + i;\n\t\tstringList* const aliases = parser->currentAliases;\n\t\tvString* tmp;\n\n\t\tif (parser->def->name != NULL && strcasecmp (key, parser->def->name) == 0)\n\t\t{\n\t\t\tresult = i;\n\t\t\t*spec = parser->def->name;\n\t\t\t*specType = SPEC_NAME;\n\t\t}\n\t\telse if (aliases != NULL  &&  (tmp = stringListFileFinds (aliases, key)))\n\t\t{\n\t\t\tresult = i;\n\t\t\t*spec = vStringValue(tmp);\n\t\t\t*specType = SPEC_ALIAS;\n\t\t}\n\t}\n\treturn result;\n}\n\nextern langType getLanguageForCommand (const char *const command, langType startFrom)\n{\n\tconst char *const tmp_command = baseFilename (command);\n\tchar *tmp_spec;\n\tenum specType tmp_specType;\n\n\treturn getNameOrAliasesLanguageAndSpec (tmp_command, startFrom,\n\t\t\t\t\t\t\t\t\t\t\t(const char **const)&tmp_spec,\n\t\t\t\t\t\t\t\t\t\t\t&tmp_specType);\n}\n\nstatic ptrArray* rexprsNew (void)\n{\n\treturn ptrArrayNew ((ptrArrayDeleteFunc)rExprCodeDelete);\n}\n\nstatic void rexprsDelete (ptrArray* rexprs)\n{\n\tptrArrayDelete (rexprs);\n}\n\nstatic void rExpressionsAddFromArray (ptrArray* rexprs, const struct rExprSrc *const array)\n{\n\tfor (unsigned int i = 0; array[i].expr; i++)\n\t{\n\t\tstruct rExprCode *rxcode = rExprCodeNew (array[i].expr, array[i].iCase);\n\t\tif (rxcode)\n\t\t\tptrArrayAdd (rexprs, rxcode);\n\t}\n}\n\nstatic struct rExprCode *rExpressionsFinds(ptrArray *rexprs, const char *fullName)\n{\n\tfor (unsigned int i = 0; i < ptrArrayCount (rexprs); i++)\n\t{\n\t\tstruct rExprCode *rxcode = ptrArrayItem (rexprs, i);\n\t\tif (rExprCodeMatch (rxcode, fullName))\n\t\t\treturn rxcode;\n\t}\n\treturn NULL;\n}\n\nstatic langType getPatternLanguageAndSpec (const char *const baseName,\n\t\t\t\t\t\t\t\t\t\t   const char *const fullName,\n\t\t\t\t\t\t\t\t\t\t   langType start_index,\n\t\t\t\t\t   const char **const spec, enum specType *specType)\n{\n\tlangType result = LANG_IGNORE;\n\tunsigned int i;\n\n\tif (start_index == LANG_AUTO)\n\t\t\tstart_index = 0;\n\telse if (start_index == LANG_IGNORE || start_index >= (int) LanguageCount)\n\t\treturn result;\n\n\t*spec = NULL;\n\n\tif (fullName == NULL)\n\t\tgoto classical_methods;\n\n\tfor (i = start_index  ;  i < LanguageCount  &&  result == LANG_IGNORE  ;  ++i)\n\t{\n\t\tif (! isLanguageEnabled (i))\n\t\t\tcontinue;\n\n\t\tparserObject *parser = LanguageTable + i;\n\t\tptrArray* const rexprs = parser->currentRexprs;\n\t\tstruct rExprCode *rxcode;\n\n\t\tif (rexprs != NULL && (rxcode = rExpressionsFinds (rexprs, fullName)))\n\t\t{\n\t\t\tresult = i;\n\t\t\t*spec = rExprCodeGetSource (rxcode);\n\t\t\t*specType = SPEC_REXPR;\n\t\t\tgoto found;\n\t\t}\n\t}\n\n classical_methods:\n\tfor (i = start_index  ;  i < LanguageCount  &&  result == LANG_IGNORE  ;  ++i)\n\t{\n\t\tif (! isLanguageEnabled (i))\n\t\t\tcontinue;\n\n\t\tparserObject *parser = LanguageTable + i;\n\t\tstringList* const ptrns = parser->currentPatterns;\n\t\tvString* tmp;\n\n\t\tif (ptrns != NULL && (tmp = stringListFileFinds (ptrns, baseName)))\n\t\t{\n\t\t\tresult = i;\n\t\t\t*spec = vStringValue(tmp);\n\t\t\t*specType = SPEC_PATTERN;\n\t\t\tgoto found;\n\t\t}\n\t}\n\n\tfor (i = start_index  ;  i < LanguageCount  &&  result == LANG_IGNORE  ;  ++i)\n\t{\n\t\tif (! isLanguageEnabled (i))\n\t\t\tcontinue;\n\n\t\tparserObject *parser = LanguageTable + i;\n\t\tstringList* const exts = parser->currentExtensions;\n\t\tvString* tmp;\n\n\t\tif (exts != NULL && (tmp = stringListExtensionFinds (exts,\n\t\t\t\t\t\t\t\t\t fileExtension (baseName))))\n\t\t{\n\t\t\tresult = i;\n\t\t\t*spec = vStringValue(tmp);\n\t\t\t*specType = SPEC_EXTENSION;\n\t\t\tgoto found;\n\t\t}\n\t}\nfound:\n\treturn result;\n}\n\nextern langType getLanguageForFilename (const char *const filename, langType startFrom)\n{\n\tconst char *const tmp_filename = baseFilename (filename);\n\tchar *tmp_spec;\n\tenum specType tmp_specType;\n\n\treturn getPatternLanguageAndSpec (tmp_filename, filename, startFrom,\n\t\t\t\t\t\t\t\t\t  (const char **const)&tmp_spec,\n\t\t\t\t\t\t\t\t\t  &tmp_specType);\n}\n\nconst char *scopeSeparatorFor (langType language, int kindIndex, int parentKindIndex)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\tparserObject *parser = LanguageTable + language;\n\tstruct kindControlBlock *kcb = parser->kindControlBlock;\n\n\tconst scopeSeparator *sep = getScopeSeparator (kcb, kindIndex, parentKindIndex);\n\treturn sep? sep->separator: NULL;\n}\n\nstatic bool processLangDefineScopesep(const langType language,\n\t\t\t\t\t\t\t\t  const char *const option,\n\t\t\t\t\t\t\t\t  const char *const parameter)\n{\n\tparserObject *parser;\n\tconst char * p = parameter;\n\n\n\tchar parentKletter;\n\tint parentKindex = KIND_FILE_INDEX;\n\tchar kletter;\n\tint kindex = KIND_FILE_INDEX;\n\tconst char *separator;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\n\n\t/*\n\t * Parent\n\t */\n\tparentKletter = p[0];\n\n\tif (parentKletter == '\\0')\n\t\terror (FATAL, \"no scope separator specified in \\\"--%s\\\" option\", option);\n\telse if (parentKletter == '/')\n\t\tparentKindex = KIND_GHOST_INDEX;\n\telse if (parentKletter == KIND_WILDCARD_LETTER)\n\t\tparentKindex = KIND_WILDCARD_INDEX;\n\telse if (parentKletter == KIND_FILE_DEFAULT_LETTER)\n\t\terror (FATAL,\n\t\t\t   \"the kind letter `%c' in \\\"--%s\\\" option is reserved for \\\"%s\\\" kind and no separator can be assigned to\",\n\t\t\t   KIND_FILE_DEFAULT_LETTER, option, KIND_FILE_DEFAULT_NAME);\n\telse if (isalpha ((unsigned char) parentKletter))\n\t{\n\t\tkindDefinition *kdef = getKindForLetter (parser->kindControlBlock, parentKletter);\n\t\tif (kdef == NULL)\n\t\t\terror (FATAL,\n\t\t\t\t   \"the kind for letter `%c' specified in \\\"--%s\\\" option is not defined.\",\n\t\t\t\t   parentKletter, option);\n\t\tparentKindex = kdef->id;\n\t}\n\telse\n\t\terror (FATAL,\n\t\t\t   \"the kind letter `%c` given in \\\"--%s\\\" option is not an alphabet\",\n\t\t\t   parentKletter, option);\n\n\n\t/*\n\t * Child\n\t */\n\tif (parentKindex == KIND_GHOST_INDEX)\n\t\tkletter = p[1];\n\telse\n\t{\n\t\tif (p[1] != '/')\n\t\t\terror (FATAL,\n\t\t\t\t   \"wrong separator specification in \\\"--%s\\\" option: no slash after parent kind letter `%c'\",\n\t\t\t\t   option, parentKletter);\n\t\tkletter = p[2];\n\t}\n\n\tif (kletter == '\\0')\n\t\terror (FATAL, \"no child kind letter in \\\"--%s\\\" option\", option);\n\telse if (kletter == '/')\n\t\terror (FATAL,\n\t\t\t   \"wrong separator specification in \\\"--%s\\\" option: don't specify slash char twice: %s\",\n\t\t\t   option, parameter);\n\telse if (kletter == ':')\n\t\terror (FATAL,\n\t\t\t   \"no child kind letter in \\\"--%s\\\" option\", option);\n\telse if (kletter == KIND_WILDCARD_LETTER)\n\t{\n\t\tif (parentKindex != KIND_WILDCARD_INDEX\n\t\t\t&& parentKindex != KIND_GHOST_INDEX)\n\t\t\terror (FATAL,\n\t\t\t\t   \"cannot use wild card for child kind unless parent kind is also wild card or empty\");\n\t\tkindex = KIND_WILDCARD_INDEX;\n\t}\n\telse if (kletter == KIND_FILE_DEFAULT_LETTER)\n\t\terror (FATAL,\n\t\t\t   \"the kind letter `%c' in \\\"--%s\\\" option is reserved for \\\"%s\\\" kind and no separator can be assigned to\",\n\t\t\t   KIND_FILE_DEFAULT_LETTER, option, KIND_FILE_DEFAULT_NAME);\n\telse if (isalpha ((unsigned char) kletter))\n\t{\n\t\tkindDefinition *kdef = getKindForLetter (parser->kindControlBlock, kletter);\n\t\tif (kdef == NULL)\n\t\t\terror (FATAL,\n\t\t\t\t   \"the kind for letter `%c' specified in \\\"--%s\\\" option is not defined.\",\n\t\t\t\t   kletter, option);\n\t\tkindex = kdef->id;\n\t}\n\telse\n\t\terror (FATAL,\n\t\t\t   \"the kind letter `%c` given in \\\"--%s\\\" option is not an alphabet\",\n\t\t\t   kletter, option);\n\n\t/*\n\t * Separator\n\t */\n\tif (parentKindex == KIND_GHOST_INDEX)\n\t{\n\t\tif (p[2] != ':')\n\t\t\terror (FATAL,\n\t\t\t\t   \"wrong separator specification in \\\"--%s\\\" option: cannot find a colon after child kind: %s\",\n\t\t\t\t   option, parameter);\n\t\tseparator = p + 3;\n\t}\n\telse\n\t{\n\t\tif (p[3] != ':')\n\t\t\terror (FATAL,\n\t\t\t\t   \"wrong separator specification in \\\"--%s\\\" option: cannot find a colon after child kind: %s\",\n\t\t\t\t   option, parameter);\n\t\tseparator = p + 4;\n\t}\n\n\tAssert (parentKindex != KIND_FILE_INDEX);\n\tAssert (kindex != KIND_FILE_INDEX);\n\tdefineScopeSeparator (parser->kindControlBlock, kindex, parentKindex, separator);\n\treturn true;\n}\n\nextern bool processScopesepOption (const char *const option, const char * const parameter)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"_scopesep-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\treturn processLangDefineScopesep (language, option, parameter);\n}\n\nstatic parserCandidate* parserCandidateNew(unsigned int count CTAGS_ATTR_UNUSED)\n{\n\tparserCandidate* candidates;\n\tunsigned int i;\n\n\tcandidates= xMalloc(LanguageCount, parserCandidate);\n\tfor (i = 0; i < LanguageCount; i++)\n\t{\n\t\tcandidates[i].lang = LANG_IGNORE;\n\t\tcandidates[i].spec = NULL;\n\t\tcandidates[i].specType = SPEC_NONE;\n\t}\n\treturn candidates;\n}\n\n/* If multiple parsers are found, return LANG_AUTO */\nstatic unsigned int nominateLanguageCandidates (const char *const key, const char *const fullKey CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\t\t\tparserCandidate** candidates)\n{\n\tunsigned int count;\n\tlangType i;\n\tconst char* spec = NULL;\n\tenum specType specType = SPEC_NONE;\n\n\t*candidates = parserCandidateNew(LanguageCount);\n\n\tfor (count = 0, i = LANG_AUTO; i != LANG_IGNORE; )\n\t{\n\t\ti = getNameOrAliasesLanguageAndSpec (key, i, &spec, &specType);\n\t\tif (i != LANG_IGNORE)\n\t\t{\n\t\t\t(*candidates)[count].lang = i++;\n\t\t\t(*candidates)[count].spec = spec;\n\t\t\t(*candidates)[count++].specType = specType;\n\t\t}\n\t}\n\n\treturn count;\n}\n\nstatic unsigned int\nnominateLanguageCandidatesForPattern(const char *const baseName, const char *const fullName,\n\t\t\t\t\t\t\t\t\t parserCandidate** candidates)\n{\n\tunsigned int count;\n\tlangType i;\n\tconst char* spec;\n\tenum specType specType = SPEC_NONE;\n\n\t*candidates = parserCandidateNew(LanguageCount);\n\n\tfor (count = 0, i = LANG_AUTO; i != LANG_IGNORE; )\n\t{\n\t\ti = getPatternLanguageAndSpec (baseName, fullName, i, &spec, &specType);\n\t\tif (i != LANG_IGNORE)\n\t\t{\n\t\t\t(*candidates)[count].lang = i++;\n\t\t\t(*candidates)[count].spec = spec;\n\t\t\t(*candidates)[count++].specType = specType;\n\t\t}\n\t}\n\treturn count;\n}\n\nstatic vString* extractEmacsModeAtFirstLine(MIO* input);\n\n/*  The name of the language interpreter, either directly or as the argument\n *  to \"env\".\n */\nstatic vString* determineInterpreter (const char* const cmd)\n{\n\tvString* const interpreter = vStringNew ();\n\tconst char* p = cmd;\n\tdo\n\t{\n\t\tvStringClear (interpreter);\n\t\tfor ( ;  isspace ((unsigned char) *p)  ;  ++p)\n\t\t\t;  /* no-op */\n\t\tfor ( ;  *p != '\\0'  &&  ! isspace ((unsigned char) *p)  ;  ++p)\n\t\t\tvStringPut (interpreter, *p);\n\t} while (strcmp (vStringValue (interpreter), \"env\") == 0);\n\treturn interpreter;\n}\n\nstatic vString* extractInterpreter (MIO* input)\n{\n\tvString* const vLine = vStringNew ();\n\tconst char* const line = readLineRaw (vLine, input);\n\tvString* interpreter = NULL;\n\n\tif (line != NULL  &&  line [0] == '#'  &&  line [1] == '!')\n\t{\n\t\t/* \"48.2.4.1 Specifying File Variables\" of Emacs info:\n\t\t   ---------------------------------------------------\n\t\t   In shell scripts, the first line is used to\n\t\t   identify the script interpreter, so you\n\t\t   cannot put any local variables there.  To\n\t\t   accommodate this, Emacs looks for local\n\t\t   variable specifications in the _second_\n\t\t   line if the first line specifies an\n\t\t   interpreter.  */\n\n\t\tinterpreter = extractEmacsModeAtFirstLine(input);\n\t\tif (!interpreter)\n\t\t{\n\t\t\tconst char* const lastSlash = strrchr (line, '/');\n\t\t\tconst char *const cmd = lastSlash != NULL ? lastSlash+1 : line+2;\n\t\t\tinterpreter = determineInterpreter (cmd);\n\t\t}\n\t}\n\tvStringDelete (vLine);\n\treturn interpreter;\n}\n\nstatic bool isShellZsh (const char *p)\n{\n\tp = strstr (p, \"sh-set-shell\");\n\tif (!p)\n\t\treturn false;\n\tp += strlen(\"sh-set-shell\");\n\n\tif (*p == ':')\n\t\tp++;\n\twhile (isspace ((unsigned char) *p))\n\t\tp++;\n\n\tif (strncmp (p, \"\\\"zsh\\\"\", 5) == 0\n\t\t|| strncmp (p, \"zsh\", 3) == 0)\n\t\treturn true;\n\treturn false;\n}\n\nstatic vString* determineEmacsModeAtFirstLine (const char* const line)\n{\n\tvString* mode = vStringNew ();\n\n\tconst char* p = strstr(line, \"-*-\");\n\tif (p == NULL)\n\t\tgoto out;\n\tp += strlen(\"-*-\");\n\n\tfor ( ;  isspace ((unsigned char) *p)  ;  ++p)\n\t\t;  /* no-op */\n\n\tif (strncasecmp(p, \"mode:\", strlen(\"mode:\")) == 0)\n\t{\n\t\t/* -*- mode: MODE; -*- */\n\t\tp += strlen(\"mode:\");\n\t\tfor ( ;  isspace ((unsigned char) *p)  ;  ++p)\n\t\t\t;  /* no-op */\n\t\tfor ( ;  *p != '\\0'  &&  isLanguageNameChar ((unsigned char) *p)  ;  ++p)\n\t\t\tvStringPut (mode, *p);\n\n\t\tif ((strcmp(vStringValue (mode), \"sh\") == 0\n\t\t\t || strcmp(vStringValue (mode), \"shell-script\") == 0)\n\t\t\t&& isShellZsh (p))\n\t\t\tvStringCopyS (mode, \"Zsh\");\n\t}\n\telse\n\t{\n\t\t/* -*- MODE -*- */\n\t\tconst char* end = strstr (p, \"-*-\");\n\n\t\tif (end == NULL)\n\t\t\tgoto out;\n\n\t\tfor ( ;  p < end &&  isLanguageNameChar ((unsigned char) *p)  ;  ++p)\n\t\t\tvStringPut (mode, *p);\n\n\t\tfor ( ;  isspace ((unsigned char) *p)  ;  ++p)\n\t\t\t;  /* no-op */\n\t\tif (strncmp(p, \"-*-\", strlen(\"-*-\")) != 0)\n\t\t\tvStringClear (mode);\n\t}\n\n\tvStringLower (mode);\n\nout:\n\treturn mode;\n\n}\n\nstatic vString* extractEmacsModeAtFirstLine(MIO* input)\n{\n\tvString* const vLine = vStringNew ();\n\tconst char* const line = readLineRaw (vLine, input);\n\tvString* mode = NULL;\n\tif (line != NULL)\n\t\tmode = determineEmacsModeAtFirstLine (line);\n\tvStringDelete (vLine);\n\n\tif (mode && (vStringLength(mode) == 0))\n\t{\n\t\tvStringDelete(mode);\n\t\tmode = NULL;\n\t}\n\treturn mode;\n}\n\nstatic vString* determineEmacsModeAtEOF (MIO* const fp)\n{\n\tvString* const vLine = vStringNew ();\n\tconst char* line;\n\tbool headerFound = false;\n\tconst char* p;\n\tvString* mode = vStringNew ();\n\tbool is_shell_mode = false;\n\n\twhile ((line = readLineRaw (vLine, fp)) != NULL)\n\t{\n\t\tif (headerFound && ((p = strstr (line, \"mode:\")) != NULL))\n\t\t{\n\t\t\tvStringClear (mode);\n\t\t\theaderFound = false;\n\n\t\t\tp += strlen (\"mode:\");\n\t\t\tfor ( ;  isspace ((unsigned char) *p)  ;  ++p)\n\t\t\t\t;  /* no-op */\n\t\t\tfor ( ;  *p != '\\0'  &&  isLanguageNameChar ((unsigned char) *p)  ;  ++p)\n\t\t\t\tvStringPut (mode, *p);\n\n\t\t\tis_shell_mode = ((strcasecmp (vStringValue (mode), \"sh\") == 0\n\t\t\t\t\t\t\t\t || strcasecmp (vStringValue (mode), \"shell-script\") == 0));\n\t\t}\n\t\telse if (headerFound && (p = strstr(line, \"End:\")))\n\t\t\theaderFound = false;\n\t\telse if (strstr (line, \"Local Variables:\"))\n\t\t\theaderFound = true;\n\t\telse if (is_shell_mode && (p = strstr (line, \"sh-set-shell\")))\n\t\t{\n\t\t\tp += strlen(\"sh-set-shell\");\n\t\t\twhile (isspace ((unsigned char) *p))\n\t\t\t\tp++;\n\t\t\tif (strncmp (p, \"\\\"zsh\\\"\", 5) == 0)\n\t\t\t\tvStringCopyS (mode, \"Zsh\");\n\t\t}\n\t}\n\tvStringDelete (vLine);\n\treturn mode;\n}\n\nstatic vString* extractEmacsModeLanguageAtEOF (MIO* input)\n{\n\tvString* mode;\n\n\t/* \"48.2.4.1 Specifying File Variables\" of Emacs info:\n\t   ---------------------------------------------------\n\t   you can define file local variables using a \"local\n\t   variables list\" near the end of the file.  The start of the\n\t   local variables list should be no more than 3000 characters\n\t   from the end of the file, */\n\tmio_seek(input, -3000, SEEK_END);\n\n\tmode = determineEmacsModeAtEOF (input);\n\tif (mode && (vStringLength (mode) == 0))\n\t{\n\t\tvStringDelete (mode);\n\t\tmode = NULL;\n\t}\n\n\treturn mode;\n}\n\nstatic vString* determineVimFileType (const char *const modeline)\n{\n\t/* considerable combinations:\n\t   --------------------------\n\t   ... filetype=\n\t   ... ft= */\n\n\tunsigned int i;\n\tconst char* p;\n\n\tconst char* const filetype_prefix[] = {\"filetype=\", \"ft=\"};\n\tvString* const filetype = vStringNew ();\n\n\tfor (i = 0; i < ARRAY_SIZE(filetype_prefix); i++)\n\t{\n\t\tif ((p = strrstr(modeline, filetype_prefix[i])) == NULL)\n\t\t\tcontinue;\n\n\t\tp += strlen(filetype_prefix[i]);\n\t\tfor ( ;  *p != '\\0'  &&  isalnum ((unsigned char) *p)  ;  ++p)\n\t\t\tvStringPut (filetype, *p);\n\t\tbreak;\n\t}\n\treturn filetype;\n}\n\nstatic vString* extractVimFileTypeCommon(MIO* input, bool eof)\n{\n\t/* http://vimdoc.sourceforge.net/htmldoc/options.html#modeline\n\n\t   [text]{white}{vi:|vim:|ex:}[white]se[t] {options}:[text]\n\t   options=> filetype=TYPE or ft=TYPE\n\n\t   'modelines' 'mls'\tnumber\t(default 5)\n\t\t\tglobal\n\t\t\t{not in Vi}\n\t\tIf 'modeline' is on 'modelines' gives the number of lines that is\n\t\tchecked for set commands. */\n\n\tvString* filetype = NULL;\n#define RING_SIZE 5\n\tvString* ring[RING_SIZE];\n\tint i, j;\n\tunsigned int k;\n\tconst char* const prefix[] = {\n\t\t\"vim:\", \"vi:\", \"ex:\"\n\t};\n\n\tfor (i = 0; i < RING_SIZE; i++)\n\t\tring[i] = vStringNew ();\n\n\ti = 0;\n\twhile ((readLineRaw (ring[i++], input)) != NULL)\n\t\tif (i == RING_SIZE)\n\t\t{\n\t\t\ti = 0;\n\t\t\tif (!eof)\n\t\t\t{\n\t\t\t\ti++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\tj = i;\n\tdo\n\t{\n\t\tconst char* p;\n\n\t\tj--;\n\t\tif (j < 0)\n\t\t\tj = RING_SIZE - 1;\n\n\t\tfor (k = 0; k < ARRAY_SIZE(prefix); k++)\n\t\t\tif ((p = strstr (vStringValue (ring[j]), prefix[k])) != NULL)\n\t\t\t{\n\t\t\t\tp += strlen(prefix[k]);\n\t\t\t\tfor ( ;  isspace ((unsigned char) *p)  ;  ++p)\n\t\t\t\t\t;  /* no-op */\n\t\t\t\tfiletype = determineVimFileType(p);\n\t\t\t\tbreak;\n\t\t\t}\n\t} while (((i == RING_SIZE)? (j != RING_SIZE - 1): (j != i)) && (!filetype));\n\n\tfor (i = RING_SIZE - 1; i >= 0; i--)\n\t\tvStringDelete (ring[i]);\n#undef RING_SIZE\n\n\tif (filetype && (vStringLength (filetype) == 0))\n\t{\n\t\tvStringDelete (filetype);\n\t\tfiletype = NULL;\n\t}\n\treturn filetype;\n\n\t/* TODO:\n\t   [text]{white}{vi:|vim:|ex:}[white]{options} */\n}\n\nstatic vString* extractVimFileTypeAtBOF(MIO* input)\n{\n\treturn extractVimFileTypeCommon (input, false);\n}\n\nstatic vString* extractVimFileTypeAtEOF(MIO* input)\n{\n\treturn extractVimFileTypeCommon (input, true);\n}\n\nstatic vString* extractMarkGeneric (MIO* input,\n\t\t\t\t\t\t\t\t\tvString * (* determiner)(const char *const, void *),\n\t\t\t\t\t\t\t\t\tvoid *data)\n{\n\tvString* const vLine = vStringNew ();\n\tconst char* const line = readLineRaw (vLine, input);\n\tvString* mode = NULL;\n\n\tif (line)\n\t\tmode = determiner (line, data);\n\n\tvStringDelete (vLine);\n\treturn mode;\n}\n\nstatic vString* determineZshAutoloadTag (const char *const modeline,\n\t\t\t\t\t\t\t\t\t\t void *data CTAGS_ATTR_UNUSED)\n{\n\t/* See \"Autoloaded files\" in zsh info.\n\t   -------------------------------------\n\t   #compdef ...\n\t   #autoload [ OPTIONS ] */\n\n\tif (((strncmp (modeline, \"#compdef\", 8) == 0)\n\t\t && isspace ((unsigned char) *(modeline + 8)))\n\t\t|| ((strncmp (modeline, \"#autoload\", 9) == 0)\n\t\t\t&& (isspace ((unsigned char) *(modeline + 9))\n\t\t\t\t|| *(modeline + 9) == '\\0')))\n\t\treturn vStringNewInit (\"zsh\");\n\telse\n\t\treturn NULL;\n}\n\nstatic vString* extractZshAutoloadTag(MIO* input)\n{\n\treturn extractMarkGeneric (input, determineZshAutoloadTag, NULL);\n}\n\nstatic vString* determinePHPMark(const char *const modeline,\n\t\tvoid *data CTAGS_ATTR_UNUSED)\n{\n\tif (strncmp (modeline, \"<?php\", 5) == 0)\n\t\treturn vStringNewInit (\"php\");\n\telse\n\t\treturn NULL;\n}\n\nstatic vString* extractPHPMark(MIO* input)\n{\n\treturn extractMarkGeneric (input, determinePHPMark, NULL);\n}\n\n\nstruct getLangCtx {\n\tconst char *fileName;\n\tMIO        *input;\n\tbool     err;\n};\n\n#define GLC_FOPEN_IF_NECESSARY0(_glc_, _label_) do {        \\\n\tif (!(_glc_)->input) {                                  \\\n\t\t(_glc_)->input = getMio((_glc_)->fileName, \"rb\", false);\t\\\n\t\tif (!(_glc_)->input) {                              \\\n\t\t\t(_glc_)->err = true;                            \\\n\t\t\tgoto _label_;                                   \\\n\t\t}                                                   \\\n\t}                                                       \\\n} while (0)                                                 \\\n\n#define GLC_FOPEN_IF_NECESSARY(_glc_, _label_, _doesParserRequireMemoryStream_) \\\n\tdo {\t\t\t\t\t\t\t\t\\\n\t\tif (!(_glc_)->input)\t\t\t\t\t\\\n\t\t\tGLC_FOPEN_IF_NECESSARY0 (_glc_, _label_);\t\\\n\t\tif ((_doesParserRequireMemoryStream_) &&\t\t\\\n\t\t\t(mio_memory_get_data((_glc_)->input, NULL) == NULL)) \\\n\t\t{\t\t\t\t\t\t\t\\\n\t\t\tMIO *tmp_ = (_glc_)->input;\t\t\t\\\n\t\t\t(_glc_)->input = mio_new_mio (tmp_, 0, -1);\t\\\n\t\t\tmio_unref (tmp_);\t\t\t\t\\\n\t\t\tif (!(_glc_)->input) {\t\t\t\t\\\n\t\t\t\t(_glc_)->err = true;\t\t\t\\\n\t\t\t\tgoto _label_;\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t} while (0)\n\n#define GLC_FCLOSE(_glc_) do {                              \\\n\tif ((_glc_)->input) {                                   \\\n\t\tmio_unref((_glc_)->input);                             \\\n\t\t(_glc_)->input = NULL;                              \\\n\t}                                                       \\\n} while (0)\n\nstatic const struct taster {\n\tvString* (* taste) (MIO *);\n\tconst char     *msg;\n} eager_tasters[] = {\n\t{\n\t\t.taste  = extractInterpreter,\n\t\t.msg    = \"interpreter\",\n\t},\n\t{\n\t\t.taste  = extractZshAutoloadTag,\n\t\t.msg    = \"zsh autoload tag\",\n\t},\n\t{\n\t\t.taste  = extractEmacsModeAtFirstLine,\n\t\t.msg    = \"emacs mode at the first line\",\n\t},\n\t{\n\t\t.taste  = extractEmacsModeLanguageAtEOF,\n\t\t.msg    = \"emacs mode at the EOF\",\n\t},\n\t{\n\t\t.taste  = extractVimFileTypeAtBOF,\n\t\t.msg    = \"vim modeline at the BOF\",\n\t},\n\t{\n\t\t.taste  = extractVimFileTypeAtEOF,\n\t\t.msg    = \"vim modeline at the EOF\",\n\t},\n\t{\n\t\t.taste  = extractPHPMark,\n\t\t.msg    = \"PHP marker\",\n\t}\n};\nstatic langType tasteLanguage (struct getLangCtx *glc, const struct taster *const tasters, int n_tasters,\n\t\t\t\t  langType *fallback);\n\n/* If all the candidates have the same specialized language selector, return\n * it.  Otherwise, return NULL.\n */\nstatic bool\nhasTheSameSelector (langType lang, selectLanguage candidate_selector)\n{\n\tselectLanguage *selector;\n\n\tselector = LanguageTable[ lang ].def->selectLanguage;\n\tif (selector == NULL)\n\t\treturn false;\n\n\twhile (*selector)\n\t{\n\t\tif (*selector == candidate_selector)\n\t\t\treturn true;\n\t\tselector++;\n\t}\n\treturn false;\n}\n\nstatic selectLanguage\ncommonSelector (const parserCandidate *candidates, int n_candidates)\n{\n\tAssert (n_candidates > 1);\n\tselectLanguage *selector;\n\tint i;\n\n\tselector = LanguageTable[ candidates[0].lang ].def->selectLanguage;\n\tif (selector == NULL)\n\t\treturn NULL;\n\n\twhile (*selector)\n\t{\n\t\tfor (i = 1; i < n_candidates; ++i)\n\t\t\tif (! hasTheSameSelector (candidates[i].lang, *selector))\n\t\t\t\tbreak;\n\t\tif (i == n_candidates)\n\t\t\treturn *selector;\n\t\tselector++;\n\t}\n\treturn NULL;\n}\n\n\n/* Calls the selector and returns the integer value of the parser for the\n * language associated with the string returned by the selector.\n */\nstatic int\npickLanguageBySelection (selectLanguage selector, MIO *input,\n\t\t\t\t\t\t parserCandidate *candidates,\n\t\t\t\t\t\t unsigned int nCandidates)\n{\n\tconst char *lang;\n\tlangType *cs = xMalloc(nCandidates, langType);\n\tunsigned int i;\n\n\tfor (i = 0; i < nCandidates; i++)\n\t\tcs[i] = candidates[i].lang;\n\tlang = selector(input, cs, nCandidates);\n\teFree (cs);\n\n\tif (lang)\n\t{\n\t\tverbose (\"\t\tselection: %s\\n\", lang);\n\t\treturn getNamedLanguage(lang, 0);\n\t}\n\telse\n\t{\n\tverbose (\"\t\tno selection\\n\");\n\t\treturn LANG_IGNORE;\n\t}\n}\n\nstatic int compareParsersByName (const void *a, const void* b)\n{\n\tconst parserDefinition *const *la = a, *const *lb = b;\n\treturn strcasecmp ((*la)->name, (*lb)->name);\n}\n\nstatic int sortParserCandidatesBySpecType (const void *a, const void *b)\n{\n\tconst parserCandidate *ap = a, *bp = b;\n\tif (ap->specType > bp->specType)\n\t\treturn -1;\n\telse if (ap->specType == bp->specType)\n\t{\n\t\t/* qsort, the function calling this function,\n\t\t   doesn't do \"stable sort\". To make the result of\n\t\t   sorting predictable, compare the names of parsers\n\t\t   when their specType is the same. */\n\t\tparserDefinition *la = LanguageTable [ap->lang].def;\n\t\tparserDefinition *lb = LanguageTable [bp->lang].def;\n\t\treturn compareParsersByName (&la, &lb);\n\t}\n\telse\n\t\treturn 1;\n}\n\nstatic unsigned int sortAndFilterParserCandidates (parserCandidate *candidates,\n\t\t\t\t\t\t   unsigned int n_candidates)\n{\n\tenum specType highestSpecType;\n\tunsigned int i;\n\tunsigned int r;\n\n\tif (n_candidates < 2)\n\t\treturn n_candidates;\n\n\tqsort (candidates, n_candidates, sizeof(*candidates),\n\t\t   sortParserCandidatesBySpecType);\n\n\thighestSpecType = candidates [0].specType;\n\tr = 1;\n\tfor (i = 1; i < n_candidates; i++)\n\t{\n\t\tif (candidates[i].specType == highestSpecType)\n\t\t\tr++;\n\t}\n\treturn r;\n}\n\nstatic void verboseReportCandidate (const char *header,\n\t\t\t\t\tparserCandidate *candidates,\n\t\t\t\t\tunsigned int n_candidates)\n{\n\tunsigned int i;\n\tverbose (\"\t\t#%s: %u\\n\", header, n_candidates);\n\tfor (i = 0; i < n_candidates; i++)\n\t\tverbose (\"\t\t\t%u: %s (%s: \\\"%s\\\")\\n\",\n\t\t\t i,\n\t\t\t LanguageTable[candidates[i].lang].def->name,\n\t\t\t specTypeName [candidates[i].specType],\n\t\t\t candidates[i].spec);\n}\n\nstatic bool doesCandidatesRequireMemoryStream(const parserCandidate *candidates,\n\t\t\t\t\t\t int n_candidates)\n{\n\tint i;\n\n\tfor (i = 0; i < n_candidates; i++)\n\t\tif (doesParserRequireMemoryStream (candidates[i].lang))\n\t\t\treturn true;\n\n\treturn false;\n}\n\nstatic langType getSpecLanguageCommon (const char *const spec, const char *const fullSpec, struct getLangCtx *glc,\n\t\t\t\t\t   unsigned int nominate (const char *const, const char *const, parserCandidate**),\n\t\t\t\t\t   langType *fallback)\n{\n\tlangType language;\n\tparserCandidate *candidates;\n\tunsigned int n_candidates;\n\n\tif (fallback)\n\t\t*fallback = LANG_IGNORE;\n\n\tn_candidates = (*nominate)(spec, fullSpec, &candidates);\n\tverboseReportCandidate (\"candidates\",\n\t\t\t\tcandidates, n_candidates);\n\n\tn_candidates = sortAndFilterParserCandidates (candidates, n_candidates);\n\tverboseReportCandidate (\"candidates after sorting and filtering\",\n\t\t\t\tcandidates, n_candidates);\n\n\tif (n_candidates == 1)\n\t{\n\t\tlanguage = candidates[0].lang;\n\t}\n\telse if (n_candidates > 1)\n\t{\n\t\tselectLanguage selector = commonSelector(candidates, n_candidates);\n\t\tbool memStreamRequired = doesCandidatesRequireMemoryStream (candidates,\n\t\t\t\t\t\t\t\t\t\t   n_candidates);\n\n\t\tGLC_FOPEN_IF_NECESSARY(glc, fopen_error, memStreamRequired);\n\t\tif (selector) {\n\t\t\tverbose (\"\tselector: %p\\n\", selector);\n\t\t\tlanguage = pickLanguageBySelection(selector, glc->input, candidates, n_candidates);\n\t\t} else {\n\t\t\tverbose (\"\tselector: NONE\\n\");\n\t\tfopen_error:\n\t\t\tlanguage = LANG_IGNORE;\n\t\t}\n\n\t\tAssert(language != LANG_AUTO);\n\n\t\tif (fallback)\n\t\t\t*fallback = candidates[0].lang;\n\t}\n\telse\n\t{\n\t\tlanguage = LANG_IGNORE;\n\t}\n\n\teFree(candidates);\n\tcandidates = NULL;\n\n\treturn language;\n}\n\nstatic langType getSpecLanguage (const char *const spec,\n\t\t\t\t\t\t\t\t struct getLangCtx *glc,\n\t\t\t\t langType *fallback)\n{\n\treturn getSpecLanguageCommon(spec, NULL, glc, nominateLanguageCandidates,\n\t\t\t\t\t fallback);\n}\n\nstatic langType getPatternLanguage (const char *const baseName,\n\t\t\t\t\t\t\t\t\tconst char *const fullName,\n\t\t\t\t\t\t\t\t\tstruct getLangCtx *glc,\n\t\t\t\t\tlangType *fallback)\n{\n\treturn getSpecLanguageCommon(baseName, fullName, glc,\n\t\t\t\t\t nominateLanguageCandidatesForPattern,\n\t\t\t\t\t fallback);\n}\n\n/* This function tries to figure out language contained in a file by\n * running a series of tests, trying to find some clues in the file.\n */\nstatic langType\ntasteLanguage (struct getLangCtx *glc, const struct taster *const tasters, int n_tasters,\n\t\t  langType *fallback)\n{\n\tint i;\n\n\tif (fallback)\n\t\t*fallback = LANG_IGNORE;\n\tfor (i = 0; i < n_tasters; ++i) {\n\t\tlangType language;\n\t\tvString* spec;\n\n\t\tmio_rewind(glc->input);\n\tspec = tasters[i].taste(glc->input);\n\n\t\tif (NULL != spec) {\n\t\t\tverbose (\"\t%s: %s\\n\", tasters[i].msg, vStringValue (spec));\n\t\t\tlanguage = getSpecLanguage (vStringValue (spec), glc,\n\t\t\t\t\t(fallback && (*fallback == LANG_IGNORE))? fallback: NULL);\n\t\t\tvStringDelete (spec);\n\t\t\tif (language != LANG_IGNORE)\n\t\t\t\treturn language;\n\t\t}\n\t}\n\n\treturn LANG_IGNORE;\n}\n\n\nstruct GetLanguageRequest {\n\tenum { GLR_OPEN, GLR_DISCARD, GLR_REUSE, } type;\n\tconst char *const fileName;\n\tMIO *mio;\n\ttime_t mtime;\n};\n\nstatic langType\ngetFileLanguageForRequestInternal (struct GetLanguageRequest *req)\n{\n\tconst char *const fileName = req->fileName;\n\tlangType language;\n\n\t/* ctags tries variety ways(HINTS) to choose a proper language\n\t   for given fileName. If multiple candidates are chosen in one of\n\t   the hint, a SELECTOR common between the candidate languages\n\t   is called.\n\n\t   \"selection failure\" means a selector common between the\n\t   candidates doesn't exist or the common selector returns NULL.\n\n\t   \"hint failure\" means the hint finds no candidate or\n\t   \"selection failure\" occurs though the hint finds multiple\n\t   candidates.\n\n\t   If a hint chooses multiple candidates, and selection failure is\n\t   occurred, the hint records one of the candidates as FALLBACK for\n\t   the hint. (The candidates are stored in an array. The first\n\t   element of the array is recorded. However, there is no\n\t   specification about the order of elements in the array.)\n\n\t   If all hints are failed, FALLBACKs of the hints are examined.\n\t   Which fallbacks should be chosen?  `enum hint' defines the order. */\n\tenum hint {\n\t\tHINT_INTERP,\n\t\tHINT_OTHER,\n\t\tHINT_FILENAME,\n\t\tHINT_TEMPLATE,\n\t\tN_HINTS,\n\t};\n\tlangType fallback[N_HINTS];\n\tint i;\n\tstruct getLangCtx glc = {\n\t\t.fileName = fileName,\n\t\t.input    = (req->type == GLR_REUSE)? mio_ref (req->mio): NULL,\n\t\t.err      = false,\n\t};\n\tconst char* const baseName = baseFilename (fileName);\n\tchar *templateFileNameSansExt = NULL;\n\tfileStatus *fstatus = NULL;\n\n\tfor (i = 0; i < N_HINTS; i++)\n\tfallback [i] = LANG_IGNORE;\n\n\tverbose (\"Get file language for %s\\n\", fileName);\n\n\tverbose (\"\tpattern: %s\\n\", baseName);\n\tlanguage = getPatternLanguage (baseName, fileName, &glc,\n\t\t\t\t   fallback + HINT_FILENAME);\n\tif (language != LANG_IGNORE || glc.err)\n\t\tgoto cleanup;\n\n\t{\n\t\tconst char* const tExt = \".in\";\n\t\ttemplateFileNameSansExt = filenameSansExtensionNew (fileName, tExt);\n\t\tif (templateFileNameSansExt)\n\t\t{\n\t\t\tverbose (\"\tpattern + template(%s): %s\\n\", tExt, templateFileNameSansExt);\n\t\t\tGLC_FOPEN_IF_NECESSARY(&glc, cleanup, false);\n\t\t\tmio_rewind(glc.input);\n\t\t\tconst char *const templateBaseFileNameSansExt = baseFilename (templateFileNameSansExt);\n\t\t\tlanguage = getPatternLanguage (templateBaseFileNameSansExt, templateFileNameSansExt, &glc,\n\t\t\t\t\t\t\t\t\t\t   fallback + HINT_TEMPLATE);\n\t\t\tif (language != LANG_IGNORE)\n\t\t\t\tgoto cleanup;\n\t\t}\n\t}\n\n\t/* If the input is already opened, we don't have to verify the existence. */\n\tif (glc.input || ((fstatus = eStat (fileName)) && fstatus->exists))\n\t{\n\t\tif ((fstatus && fstatus->isExecutable) || Option.guessLanguageEagerly)\n\t\t{\n\t\t\tGLC_FOPEN_IF_NECESSARY (&glc, cleanup, false);\n\t\t\tlanguage = tasteLanguage(&glc, eager_tasters, 1,\n\t\t\t\t\t\tfallback + HINT_INTERP);\n\t\t}\n\t\tif (language != LANG_IGNORE)\n\t\t\tgoto cleanup;\n\n\t\tif (Option.guessLanguageEagerly)\n\t\t{\n\t\t\tGLC_FOPEN_IF_NECESSARY(&glc, cleanup, false);\n\t\t\tlanguage = tasteLanguage(&glc,\n\t\t\t\t\t\t eager_tasters + 1,\n\t\t\t\t\t\t ARRAY_SIZE(eager_tasters) - 1,\n\t\t\t\t\t\t fallback + HINT_OTHER);\n\t\t}\n\t}\n\n\n  cleanup:\n\tif (req->type == GLR_OPEN && glc.input)\n\t{\n\t\treq->mio = mio_ref (glc.input);\n\t\tif (!fstatus)\n\t\t\tfstatus = eStat (fileName);\n\t\tif (fstatus)\n\t\t\treq->mtime = fstatus->mtime;\n\t}\n\tGLC_FCLOSE(&glc);\n\tif (fstatus)\n\t\teStatFree (fstatus);\n\tif (templateFileNameSansExt)\n\t\teFree (templateFileNameSansExt);\n\n\tfor (i = 0;\n\t language == LANG_IGNORE && i < N_HINTS;\n\t i++)\n\t{\n\t\tlanguage = fallback [i];\n\tif (language != LANG_IGNORE)\n\t\tverbose (\"\tfallback[hint = %d]: %s\\n\", i, getLanguageName (language));\n\t}\n\n\tif (language == LANG_IGNORE\n\t\t&& isLanguageEnabled (LANG_FALLBACK))\n\t{\n\t\tlanguage = LANG_FALLBACK;\n\t\tverbose (\"\tlast resort: using \\\"%s\\\" parser\\n\",\n\t\t\t\t getLanguageName (LANG_FALLBACK));\n\t}\n\treturn language;\n}\n\nstatic langType getFileLanguageForRequest (struct GetLanguageRequest *req)\n{\n\tlangType l = Option.language;\n\n\tif (l == LANG_AUTO)\n\t\treturn getFileLanguageForRequestInternal(req);\n\telse if (! isLanguageEnabled (l))\n\t{\n\t\terror (FATAL,\n\t\t\t   \"%s parser specified with --language-force is disabled\",\n\t\t\t   getLanguageName (l));\n\t\t/* For suppressing warnings. */\n\t\treturn LANG_AUTO;\n\t}\n\telse\n\t\treturn Option.language;\n}\n\nextern langType getLanguageForFilenameAndContents (const char *const fileName)\n{\n\tstruct GetLanguageRequest req = {\n\t\t.type = GLR_DISCARD,\n\t\t.fileName = fileName,\n\t\t.mtime = (time_t)0,\n\t};\n\n\treturn getFileLanguageForRequest (&req);\n}\n\ntypedef void (*languageCallback)  (langType language, void* user_data);\nstatic void foreachLanguage(languageCallback callback, void *user_data)\n{\n\tlangType result = LANG_IGNORE;\n\n\tunsigned int i;\n\tfor (i = 0  ;  i < LanguageCount  &&  result == LANG_IGNORE  ;  ++i)\n\t{\n\t\tconst parserDefinition* const lang = LanguageTable [i].def;\n\t\tif (lang->name != NULL)\n\t\t\tcallback(i, user_data);\n\t}\n}\n\nstatic void printLanguageMap (const langType language, FILE *fp)\n{\n\tbool first = true;\n\tunsigned int i;\n\tparserObject *parser = LanguageTable + language;\n\tptrArray* rexprs;\n\tstringList* map;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\trexprs = parser->currentRexprs;\n\tfor (i = 0 ; i < ptrArrayCount (rexprs) ; ++i)\n\t{\n\t\tstruct rExprCode *rxcode = ptrArrayItem (rexprs, i);\n\t\tconst char *rxsrc = rExprCodeGetSource (rxcode);\n\t\tbool iCase = rExprCodeGetICase (rxcode);\n\n\t\tfprintf (fp, \"%s%%%s%%%s\", (first ? \"\": \" \"),\n\t\t\t\t rxsrc, iCase? \"i\": \"\");\n\t\tfirst = false;\n\t}\n\n\tmap = parser->currentPatterns;\n\tfor (i = 0  ;  map != NULL  &&  i < stringListCount (map)  ;  ++i)\n\t{\n\t\tfprintf (fp, \"%s(%s)\", (first ? \"\" : \" \"),\n\t\t\t vStringValue (stringListItem (map, i)));\n\t\tfirst = false;\n\t}\n\n\tmap = parser->currentExtensions;\n\tfor (i = 0  ;  map != NULL  &&  i < stringListCount (map)  ;  ++i)\n\t{\n\t\tfprintf (fp, \"%s.%s\", (first ? \"\" : \" \"),\n\t\t\t vStringValue (stringListItem (map, i)));\n\t\tfirst = false;\n\t}\n}\n\nextern void installLanguageMapDefault (const langType language)\n{\n\tparserObject* parser;\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\n\tif (parser->currentRexprs != NULL)\n\t\trexprsDelete (parser->currentRexprs);\n\tif (parser->currentPatterns != NULL)\n\t\tstringListDelete (parser->currentPatterns);\n\tif (parser->currentExtensions != NULL)\n\t\tstringListDelete (parser->currentExtensions);\n\n\tparser->currentRexprs = rexprsNew ();\n\tif (parser->def->rexprs)\n\t\trExpressionsAddFromArray (parser->currentRexprs,\n\t\t\t\t\t\t\t\t  parser->def->rexprs);\n\n\tif (parser->def->patterns == NULL)\n\t\tparser->currentPatterns = stringListNew ();\n\telse\n\t{\n\t\tparser->currentPatterns =\n\t\t\tstringListNewFromArgv (parser->def->patterns);\n\t}\n\tif (parser->def->extensions == NULL)\n\t\tparser->currentExtensions = stringListNew ();\n\telse\n\t{\n\t\tparser->currentExtensions =\n\t\t\tstringListNewFromArgv (parser->def->extensions);\n\t}\n\tBEGIN_VERBOSE(vfp);\n\t{\n\tprintLanguageMap (language, vfp);\n\tputc ('\\n', vfp);\n\t}\n\tEND_VERBOSE();\n}\n\nextern void installLanguageMapDefaults (void)\n{\n\tunsigned int i;\n\tfor (i = 0  ;  i < LanguageCount  ;  ++i)\n\t{\n\t\tverbose (\"    %s: \", getLanguageName (i));\n\t\tinstallLanguageMapDefault (i);\n\t}\n}\n\nextern void installLanguageAliasesDefault (const langType language)\n{\n\tparserObject* parser;\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\tif (parser->currentAliases != NULL)\n\t\tstringListDelete (parser->currentAliases);\n\n\tif (parser->def->aliases == NULL)\n\t\tparser->currentAliases = stringListNew ();\n\telse\n\t{\n\t\tparser->currentAliases =\n\t\t\tstringListNewFromArgv (parser->def->aliases);\n\t}\n\tBEGIN_VERBOSE(vfp);\n\tif (parser->currentAliases != NULL)\n\t\tfor (unsigned int i = 0  ;  i < stringListCount (parser->currentAliases)  ;  ++i)\n\t\t\tfprintf (vfp, \" %s\", vStringValue (\n\t\t\t\t\t\t stringListItem (parser->currentAliases, i)));\n\tputc ('\\n', vfp);\n\tEND_VERBOSE();\n}\n\nextern void installLanguageAliasesDefaults (void)\n{\n\tunsigned int i;\n\tfor (i = 0  ;  i < LanguageCount  ;  ++i)\n\t{\n\t\tverbose (\"    %s: \", getLanguageName (i));\n\t\tinstallLanguageAliasesDefault (i);\n\t}\n}\n\nextern void clearLanguageMap (const langType language)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tptrArrayClear ((LanguageTable + language)->currentRexprs);\n\tstringListClear ((LanguageTable + language)->currentPatterns);\n\tstringListClear ((LanguageTable + language)->currentExtensions);\n}\n\nextern void clearLanguageAliases (const langType language)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\tparserObject* parser = (LanguageTable + language);\n\tif (parser->currentAliases)\n\t\tstringListClear (parser->currentAliases);\n}\n\nstatic bool removeLanguagePatternMap1(const langType language, const char *const pattern)\n{\n\tbool result = false;\n\tstringList* const ptrn = (LanguageTable + language)->currentPatterns;\n\n\tif (ptrn != NULL && stringListDeleteItemExtension (ptrn, pattern))\n\t{\n\t\tverbose (\" (removed from %s)\", getLanguageName (language));\n\t\tresult = true;\n\t}\n\treturn result;\n}\n\nextern bool removeLanguagePatternMap (const langType language, const char *const pattern)\n{\n\tbool result = false;\n\n\tif (language == LANG_AUTO)\n\t{\n\t\tunsigned int i;\n\t\tfor (i = 0  ;  i < LanguageCount ;  ++i)\n\t\t\tresult = removeLanguagePatternMap1 (i, pattern) || result;\n\t}\n\telse\n\t\tresult = removeLanguagePatternMap1 (language, pattern);\n\treturn result;\n}\n\nextern void addLanguagePatternMap (const langType language, const char* ptrn,\n\t\t\t\t   bool exclusiveInAllLanguages)\n{\n\tvString* const str = vStringNewInit (ptrn);\n\tparserObject* parser;\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\tif (exclusiveInAllLanguages)\n\t\tremoveLanguagePatternMap (LANG_AUTO, ptrn);\n\tstringListAdd (parser->currentPatterns, str);\n}\n\nstatic bool removeLanguageExtensionMap1 (const langType language, const char *const extension)\n{\n\tbool result = false;\n\tstringList* const exts = (LanguageTable + language)->currentExtensions;\n\n\tif (exts != NULL  &&  stringListDeleteItemExtension (exts, extension))\n\t{\n\t\tverbose (\" (removed from %s)\", getLanguageName (language));\n\t\tresult = true;\n\t}\n\treturn result;\n}\n\nextern bool removeLanguageExtensionMap (const langType language, const char *const extension)\n{\n\tbool result = false;\n\n\tif (language == LANG_AUTO)\n\t{\n\t\tunsigned int i;\n\t\tfor (i = 0  ;  i < LanguageCount ;  ++i)\n\t\t\tresult = removeLanguageExtensionMap1 (i, extension) || result;\n\t}\n\telse\n\t\tresult = removeLanguageExtensionMap1 (language, extension);\n\treturn result;\n}\n\nextern void addLanguageExtensionMap (\n\t\tconst langType language, const char* extension,\n\t\tbool exclusiveInAllLanguages)\n{\n\tvString* const str = vStringNewInit (extension);\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tif (exclusiveInAllLanguages)\n\t\tremoveLanguageExtensionMap (LANG_AUTO, extension);\n\tstringListAdd ((LanguageTable + language)->currentExtensions, str);\n}\n\nstatic bool removeLanguageRexprMap1(const langType language, const char *const rexpr, bool iCase)\n{\n\tbool result = false;\n\tptrArray* const rexprs = (LanguageTable + language)->currentRexprs;\n\n\tfor (unsigned int i = 0; i < ptrArrayCount (rexprs); i++)\n\t{\n\t\tstruct rExprCode *rxcode = ptrArrayItem (rexprs, i);\n\t\tif (strcmp (rExprCodeGetSource (rxcode), rexpr) == 0 &&\n\t\t\trExprCodeGetICase (rxcode) == iCase)\n\t\t{\n\t\t\tptrArrayDeleteItem (rexprs, i);\n\t\t\tverbose (\" (removed from %s)\", getLanguageName (language));\n\t\t\tresult = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn result;\n}\n\nextern bool removeLanguageRexprMap (const langType language, const char *const rexpr, bool iCase)\n{\n\tbool result = false;\n\n\t/* Currently, we don't provide CLI for removing rexpr from all languages\n\t * at once. */\n\tAssert (language != LANG_AUTO);\n\n\tresult = removeLanguageRexprMap1 (language, rexpr, iCase);\n\n\treturn result;\n}\n\nextern void addLanguageRexprMap (const langType language, const char* rexpr, bool iCase,\n\t\t\t\t   bool exclusiveInAllLanguages)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\tstruct rExprCode *rxcode = rExprCodeNew (rexpr, iCase);\n\tif (rxcode)\n\t{\n\t\tif (exclusiveInAllLanguages)\n\t\t\tremoveLanguageRexprMap (LANG_AUTO, rexpr, iCase);\n\n\t\tparserObject* parser = LanguageTable + language;\n\t\tif (!parser->currentRexprs)\n\t\t\tparser->currentRexprs = rexprsNew ();\n\t\tptrArray* const rexprs = parser->currentRexprs;\n\n\t\tptrArrayAdd (rexprs, rxcode);\n\t}\n}\n\nextern void addLanguageAlias (const langType language, const char* alias)\n{\n\tvString* const str = vStringNewInit (alias);\n\tparserObject* parser;\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\tif (parser->currentAliases == NULL)\n\t\tparser->currentAliases = stringListNew ();\n\tstringListAdd (parser->currentAliases, str);\n}\n\nextern void enableLanguage (const langType language, const bool state)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tLanguageTable [language].def->enabled = state;\n\n\tstatic bool warned_toml;\n\tstatic bool warned_cargo;\n\n\t/* See #4096 */\n\tif (!warned_toml && strcmp (LanguageTable [language].def->name, \"TOML\") == 0)\n\t{\n\t\twarned_toml = true;\n\t\terror (WARNING, \"The current implementation of the TOML parser is broken.\");\n\t}\n\n\tif (!warned_cargo && strcmp (LanguageTable [language].def->name, \"Cargo\") == 0)\n\t{\n\t\twarned_cargo = true;\n\t\terror (WARNING, \"Enabling Cargo subparser may enable TOML parser.\");\n\t}\n}\n\n#ifdef DO_TRACING\nextern void traceLanguage (langType language)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tLanguageTable [language].def->traced = true;\n}\nextern bool isLanguageTraced (langType language)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\treturn LanguageTable [language].def->traced;\n}\n#endif /* DO_TRACING */\n\nextern void enableLanguages (const bool state)\n{\n\tunsigned int i;\n\tfor (i = 0  ;  i < LanguageCount  ;  ++i)\n\t\tenableLanguage (i, state);\n}\n\nstatic void installFieldDefinition (const langType language)\n{\n\tunsigned int i;\n\tparserDefinition * parser;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable [language].def;\n\n\tif (parser->fieldTable != NULL)\n\t{\n\t\tfor (i = 0; i < parser->fieldCount; i++)\n\t\t\tdefineField (& parser->fieldTable [i], language);\n\t}\n}\n\nstatic void installXtagDefinition (const langType language)\n{\n\tunsigned int i;\n\tparserDefinition * parser;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable [language].def;\n\n\tif (parser->xtagTable != NULL)\n\t{\n\t\tfor (i = 0; i < parser->xtagCount; i++)\n\t\t\tdefineXtag (& parser->xtagTable [i], language);\n\t}\n}\n\nstatic void initializeParserOne (langType lang)\n{\n\tparserObject *const parser = LanguageTable + lang;\n\n\tif (parser->initialized)\n\t\tgoto out;\n\n\tverbose (\"Initialize parser: %s\\n\", parser->def->name);\n\tparser->initialized = true;\n\n\tinstallKeywordTable (lang);\n\tinstallTagXpathTable (lang);\n\tinstallFieldDefinition     (lang);\n\tinstallXtagDefinition      (lang);\n\n\t/* regex definitions refers xtag definitions.\n\t   So installing RegexTable must be after installing\n\t   xtag definitions. */\n\tinstallTagRegexTable (lang);\n\n\tif (parser->def->initialize != NULL)\n\t\tparser->def->initialize (lang);\n\n\tinitializeDependencies (parser->def, parser->slaveControlBlock);\n\n\tAssert (parser->fileKind != NULL);\n\tAssert (!doesParserUseKind (parser->kindControlBlock, parser->fileKind->letter));\n\n\treturn;\n\n out:\n\t/* lazyInitialize() installs findRegexTags() to parser->parser.\n\t   findRegexTags() should be installed to a parser if the parser is\n\t   optlib based(created by --langdef) and has some regex patterns(defined\n\t   with --regex-<LANG>). findRegexTags() makes regex matching work.\n\n\t   If a parser can be initialized during evaluating options,\n\t   --fields-<LANG>=+{something}, for an example.\n\t   If such option is evaluated first, evaluating --regex-<LANG>=...\n\t   option doesn't cause installing findRegexTags. As the result\n\t   regex matching doesn't work. lazyInitialize was called only\n\t   once when --fields-<LANG>=+{something} was evaluated. In the\n\t   timing ctags had not seen --regex-<LANG>=.... Even though\n\t   ctags saw --regex-<LANG>=.... after initializing, there\n\t   was no chance to install findRegexTags() to parser->parser.\n\n\t   Following code block gives extra chances to call lazyInitialize)\n\t   which installs findRegexTags() to parser->parser.\t */\n\tif (parser->def->initialize == lazyInitialize)\n\t\tparser->def->initialize (lang);\n}\n\nextern void initializeParser (langType lang)\n{\n\tif (lang == LANG_AUTO)\n\t{\n\t\tunsigned int i;\n\t\tfor (i = 0; i < countParsers(); i++)\n\t\t\tinitializeParserOne (i);\n\t}\n\telse\n\t\tinitializeParserOne (lang);\n}\n\nstatic void linkDependenciesAtInitializeParsing (parserDefinition *const parser)\n{\n\tunsigned int i;\n\tparserDependency *d;\n\tlangType upper;\n\tparserDefinition *lowerParser;\n\tparserObject *upperParser;\n\n\tfor (i = 0; i < parser->dependencyCount; i++)\n\t{\n\t\td = parser->dependencies + i;\n\n\t\tif (d->type == DEPTYPE_FOREIGNER)\n\t\t{\n\t\t\tupper = parser->id;\n\t\t\tlangType lower = getNamedLanguage (d->upperParser, 0);\n\t\t\tif (lower == LANG_IGNORE)\n\t\t\t\terror (FATAL,\n\t\t\t\t\t   \"Unknown language: \\\"%s\\\" as a foreigner for %s\",\n\t\t\t\t\t   d->upperParser, parser->name);\n\n\t\t\tlowerParser = LanguageTable [lower].def;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tupper = getNamedLanguage (d->upperParser, 0);\n\t\t\tlowerParser = parser;\n\t\t}\n\n\t\tupperParser = LanguageTable + upper;\n\n\t\tverbose (\"link dependencies: type = %s, upper = %s, lower = %s\\n\",\n\t\t\t\t dependencyTypeString(d->type),\n\t\t\t\t upperParser->def->name, lowerParser->name);\n\t\tlinkDependencyAtInitializeParsing (d->type, upperParser->def,\n\t\t\t\t\t\t\t\t\t\t   upperParser->slaveControlBlock,\n\t\t\t\t\t\t\t\t\t\t   upperParser->kindControlBlock,\n\t\t\t\t\t\t\t\t\t\t   lowerParser,\n\t\t\t\t\t\t\t\t\t\t   (LanguageTable + lowerParser->id)->kindControlBlock,\n\t\t\t\t\t\t\t\t\t\t   d->data);\n\t}\n}\n\n/* Used in both builtin and optlib parsers. */\nstatic void initializeParsingCommon (parserDefinition *def, bool is_builtin,\n\t\t\t\t\t\t\t\t\t parserDefinitionFunc* parserDefFunc)\n{\n\tparserObject *parser;\n\n\tif (is_builtin)\n\t\tverbose (\"%s%s\", LanguageCount > 0 ? \", \" : \"\", def->name);\n\telse\n\t\tverbose (\"Add optlib parser: %s\\n\", def->name);\n\n\tif (! (def->versionCurrent >= def->versionAge))\n\t\terror (WARNING, \"versionCurrent (%u) must be either equal to or greater than versionAge (%u): %s\",\n\t\t\t   def->versionCurrent, def->versionAge, def->name);\n\tif (is_builtin)\n\t\tAssert (def->versionCurrent >= def->versionAge);\n\n\tdef->id = LanguageCount++;\n\tparser = LanguageTable + def->id;\n\tparser->def = def;\n\tparser->parserDefFunc = parserDefFunc;\n\n\thashTablePutItem (LanguageHTable, def->name, def);\n\n\tparser->fileKind = &defaultFileKind;\n\n\tparser->kindControlBlock  = allocKindControlBlock (def);\n\tparser->slaveControlBlock = allocSlaveControlBlock (def);\n\tparser->lregexControlBlock = allocLregexControlBlock (def);\n\tparser->paramControlBlock = allocParamControlBlock (def);\n}\n\nstatic char *acceptableLangName(char *name)\n{\n\tfor (char *c = name; *c != '\\0'; c++)\n\t{\n\t\tif (isalnum ((unsigned char)*c))\n\t\t\tcontinue;\n\t\telse if (*c == '+' || *c == '#')\n\t\t\tcontinue;\n\t\telse\n\t\t\treturn c;\n\t}\n\treturn NULL;\n}\n\nstatic enum parserCategory getCategoryForParserFunc(parserDefinitionFunc* func)\n{\n\t/* Putting a NULL not to make a zero-sized array that some compilers don't support. */\n\tparserDefinitionFunc* libxml_fa [] = { NULL, XML_PARSER_LIST };\n\tparserDefinitionFunc* libyaml_fa[] = { NULL, YAML_PARSER_LIST };\n\tparserDefinitionFunc* packcc_fa[] = { NULL, PEG_PARSER_LIST };\n\n#define RETURN_IF_FOUND(c,C)\t\t\t\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tfor (size_t i = 0; i < ARRAY_SIZE(c##_fa); i++)\t\t\t\\\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tif (c##_fa[i] == func)\t\t\t\t\t\t\t\t\\\n\t\t\t\treturn PARSER_CATEGORY_##C;\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t} while (0)\n\n\tRETURN_IF_FOUND(libxml, LIBXML);\n\tRETURN_IF_FOUND(libyaml, LIBYAML);\n\tRETURN_IF_FOUND(packcc, PACKCC);\n\n#undef RETURN_IF_FOUND\n\n\treturn PARSER_CATEGORY_NONE;\n}\n\nextern void initializeParsing (void)\n{\n\tunsigned int builtInCount;\n\tunsigned int i;\n\n\tbuiltInCount = ARRAY_SIZE (BuiltInParsers);\n\tLanguageTable = xMalloc (builtInCount, parserObject);\n\tmemset(LanguageTable, 0, builtInCount * sizeof (parserObject));\n\tfor (i = 0; i < builtInCount; ++i)\n\t{\n\t\tLanguageTable [i].pretendingAsLanguage = LANG_IGNORE;\n\t\tLanguageTable [i].pretendedAsLanguage = LANG_IGNORE;\n\t}\n\n\tLanguageHTable = hashTableNew (127,\n\t\t\t\t\t\t\t\t   hashCstrcasehash,\n\t\t\t\t\t\t\t\t   hashCstrcaseeq,\n\t\t\t\t\t\t\t\t   NULL,\n\t\t\t\t\t\t\t\t   NULL);\n\tDEFAULT_TRASH_BOX(LanguageHTable, hashTableDelete);\n\n\tverbose (\"Installing parsers: \");\n\tfor (i = 0  ;  i < builtInCount  ;  ++i)\n\t{\n\t\tparserDefinition* const def = (*BuiltInParsers [i]) ();\n\t\tif (def != NULL)\n\t\t{\n\t\t\tAssert (def->name);\n\t\t\tAssert (def->name[0] != '\\0');\n\t\t\tAssert (strcmp (def->name, RSV_LANG_ALL));\n\t\t\tAssert (acceptableLangName (def->name) == NULL);\n\n\t\t\tif (def->method & METHOD_NOT_CRAFTED)\n\t\t\t\tdef->parser = findRegexTags;\n\t\t\telse\n\t\t\t\t/* parser definition must define one and only one parsing routine */\n\t\t\t\tAssert ((!!def->parser) + (!!def->parser2) == 1);\n\n\t\t\tinitializeParsingCommon (def, true, BuiltInParsers [i]);\n\t\t}\n\t}\n\tverbose (\"\\n\");\n\n\tfor (i = 0; i < builtInCount  ;  ++i)\n\t\tlinkDependenciesAtInitializeParsing (LanguageTable [i].def);\n}\n\nextern void freeParserResources (void)\n{\n\tunsigned int i;\n\tfor (i = 0  ;  i < LanguageCount  ;  ++i)\n\t{\n\t\tparserObject* const parser = LanguageTable + i;\n\n\t\tif (parser->def->finalize)\n\t\t\t(parser->def->finalize)((langType)i, (bool)parser->initialized);\n\n\t\tuninstallTagXpathTable (i);\n\n\t\tfreeLregexControlBlock (parser->lregexControlBlock);\n\t\tfreeKindControlBlock (parser->kindControlBlock);\n\t\tparser->kindControlBlock = NULL;\n\n\t\tfinalizeDependencies (parser->def, parser->slaveControlBlock);\n\t\tfreeSlaveControlBlock (parser->slaveControlBlock);\n\t\tparser->slaveControlBlock = NULL;\n\n\t\tfreeParamControlBlock (parser->paramControlBlock);\n\n\t\tif (parser->currentRexprs != NULL)\n\t\t{\n\t\t\trexprsDelete (parser->currentRexprs);\n\t\t\tparser->currentRexprs = NULL;\n\t\t}\n\t\tfreeList (&parser->currentPatterns);\n\t\tfreeList (&parser->currentExtensions);\n\t\tfreeList (&parser->currentAliases);\n\n\t\teFree (parser->def->name);\n\t\tparser->def->name = NULL;\n\t\teFree (parser->def);\n\t\tparser->def = NULL;\n\t}\n\tif (LanguageTable != NULL)\n\t\teFree (LanguageTable);\n\tLanguageTable = NULL;\n\tLanguageCount = 0;\n}\n\nstatic void doNothing (void)\n{\n}\n\nstatic void optlibRunBaseParser (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nstatic bool optlibIsDedicatedSubparser (parserDefinition* def)\n{\n\treturn (def->dependencies\n\t\t\t&& (def->dependencies->type == DEPTYPE_SUBPARSER)\n\t\t\t&& ((subparser *)def->dependencies->data)->direction & SUBPARSER_SUB_RUNS_BASE);\n}\n\nstatic void lazyInitialize (langType language)\n{\n\tparserDefinition* def;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tdef = LanguageTable [language].def;\n\n\tdef->parser = doNothing;\n\n\tif (def->method & METHOD_REGEX)\n\t{\n\t\tif (optlibIsDedicatedSubparser (def))\n\t\t\tdef->parser = optlibRunBaseParser;\n\t\telse\n\t\t\tdef->parser = findRegexTags;\n\t}\n}\n\nextern void enableDefaultFileKind (bool state)\n{\n\tdefaultFileKind.enabled = state;\n}\n\n/*\n*   Option parsing\n*/\nstruct preLangDefFlagData\n{\n\tconst char *const name;\n\tchar *base;\n\tsubparserRunDirection direction;\n\tbool autoFQTag;\n\tintArray *foreignLanguages;\n\tunsigned int versionCurrent;\n\tunsigned int versionAge;\n};\n\nstatic void pre_lang_def_flag_base_long (const char* const optflag, const char* const param, void* data)\n{\n\tstruct preLangDefFlagData * flag_data = data;\n\tlangType base;\n\n\tif (param[0] == '\\0')\n\t{\n\t\terror (WARNING, \"No base parser specified for \\\"%s\\\" flag of --langdef option\", optflag);\n\t\treturn;\n\t}\n\n\tbase = getNamedLanguage (param, 0);\n\tif (base == LANG_IGNORE)\n\t{\n\t\terror (WARNING, \"Unknown language(%s) is specified for \\\"%s\\\" flag of --langdef option\",\n\t\t\t   param, optflag);\n\t\treturn;\n\n\t}\n\n\tlangType cpreproc = getNamedLanguage (\"CPreProcessor\", 0);\n\tif (base == cpreproc)\n\t{\n\t\t/* See Tmain/optscript-preludes-stack.d */\n\t\terror (WARNING,\n\t\t\t   \"Because of an internal limitation, Making a sub parser based on the CPreProcessor parser is not allowed: %s\",\n\t\t\t   param);\n\t\treturn;\n\t}\n\n\tflag_data->base = eStrdup(param);\n}\n\n#define LANGDEF_FLAG_DEDICATED \"dedicated\"\n#define LANGDEF_FLAG_SHARED    \"shared\"\n#define LANGDEF_FLAG_BIDIR     \"bidirectional\"\nstatic void pre_lang_def_flag_direction_long (const char* const optflag, const char* const param CTAGS_ATTR_UNUSED, void* data)\n{\n\tstruct preLangDefFlagData * flag_data = data;\n\n\tif (strcmp(optflag, LANGDEF_FLAG_DEDICATED) == 0)\n\t\tflag_data->direction = SUBPARSER_SUB_RUNS_BASE;\n\telse if (strcmp(optflag, LANGDEF_FLAG_SHARED) == 0)\n\t\tflag_data->direction = SUBPARSER_BASE_RUNS_SUB;\n\telse if (strcmp(optflag, LANGDEF_FLAG_BIDIR) == 0)\n\t\tflag_data->direction = SUBPARSER_BI_DIRECTION;\n\telse\n\t\tAssertNotReached ();\n}\n\nstatic void pre_lang_def_flag_autoFQTag_long (const char* const optflag,\n\t\t\t\t\t\t\t\t\t\t\t  const char* const param CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\t\t  void* data)\n{\n\tstruct preLangDefFlagData * flag_data = data;\n\tflag_data->autoFQTag = true;\n}\n\nstatic void pre_lang_def_flag_foreignLanguage_long (const char* const optflag,\n\t\t\t\t\t\t\t\t\t\t\tconst char* const param,\n\t\t\t\t\t\t\t\t\t\t\tvoid* data)\n{\n\tstruct preLangDefFlagData * flag_data = data;\n\tif (!param)\n\t{\n\t\terror (WARNING, \"value for '%s' flag is empty\", optflag);\n\t\treturn;\n\t}\n\n\tlangType lang = getNamedLanguage (param, 0);\n\tif (lang == LANG_IGNORE)\n\t\terror (FATAL, \"language named '%s' is not found or not initialized yet\",\n\t\t\t   param);\n\n\tverbose (\"Foreign language for %s: %s\\n\", flag_data->name, getLanguageName (lang));\n\tintArrayAdd (flag_data->foreignLanguages, lang);\n}\n\nstatic void pre_lang_def_flag_version_long (const char* const optflag CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\t\tconst char* const param,\n\t\t\t\t\t\t\t\t\t\t\tvoid* data)\n{\n\tstruct preLangDefFlagData * flag_data = data;\n\tchar * verstr = eStrdup (param);\n\tchar * age = strchr(verstr, '.');\n\tif (!age)\n\t\terror (FATAL, \"Failed to parse the version number ('.') for language \\\"%s\\\": %s\",\n\t\t\t   flag_data->name, param);\n\t*age = '\\0';\n\tage++;\n\n\tif (!isdigit((unsigned char)*verstr) || !strToUInt (verstr, 10, &flag_data->versionCurrent))\n\t\terror (FATAL, \"Failed to parse the version number (the current part) for language \\\"%s\\\": %s\",\n\t\t\t   flag_data->name, param);\n\n\tif (!isdigit((unsigned char)*age) || !strToUInt (age, 10, &flag_data->versionAge))\n\t\terror (FATAL, \"Failed to parse the version number (the age part) for language \\\"%s\\\": %s\",\n\t\t\t   flag_data->name, param);\n\n\teFree (verstr);\n}\n\nstatic flagDefinition PreLangDefFlagDef [] = {\n\t{ '\\0',  \"base\", NULL, pre_lang_def_flag_base_long,\n\t  \"BASEPARSER\", \"utilize as a base parser\"},\n\t{ '\\0',  LANGDEF_FLAG_DEDICATED,  NULL,\n\t  pre_lang_def_flag_direction_long,\n\t  NULL, \"make the base parser dedicated to this subparser\"},\n\t{ '\\0',  LANGDEF_FLAG_SHARED,     NULL,\n\t  pre_lang_def_flag_direction_long,\n\t  NULL, \"share the base parser with the other subparsers\"\n\t},\n\t{ '\\0',  LANGDEF_FLAG_BIDIR,      NULL,\n\t  pre_lang_def_flag_direction_long,\n\t  NULL, \"utilize the base parser both 'dedicated' and 'shared' way\"\n\t},\n\t{ '\\0',  \"_autoFQTag\", NULL, pre_lang_def_flag_autoFQTag_long,\n\t  NULL, \"make full qualified tags automatically based on scope information\"},\n\t{ '\\0', \"_foreignLanguage\",    NULL, pre_lang_def_flag_foreignLanguage_long,\n\t  \"LANG\", \"initialize another parser\" },\n\t{ '\\0', \"version\",     NULL, pre_lang_def_flag_version_long,\n\t  \"CURRENT.AGE\", \"set the version of the parser\"},\n};\n\nstatic void optlibFreeDep (langType lang, bool initialized CTAGS_ATTR_UNUSED)\n{\n\tparserDefinition * pdef = LanguageTable [lang].def;\n\n\tfor (size_t i = 0; i < pdef->dependencyCount; i++)\n\t{\n\t\tparserDependency *dep = pdef->dependencies + i;\n\n\t\teFree ((char *)dep->upperParser); /* Dirty cast */\n\t\tdep->upperParser = NULL;\n\n\t\tif (dep->data)\n\t\t{\n\t\t\teFree (dep->data);\n\t\t\tdep->data = NULL;\n\t\t}\n\t}\n\tif (pdef->dependencies)\n\t{\n\t\teFree (pdef->dependencies);\n\t\tpdef->dependencies = NULL;\n\t}\n}\n\nstatic parserDefinition* OptlibParser(const char *name, const char *base,\n\t\t\t\t\t\t\t\t\t  subparserRunDirection direction,\n\t\t\t\t\t\t\t\t\t  intArray *foreignLanguages)\n{\n\tparserDefinition *def;\n\tparserDependency *dep = NULL;\n\n\tdef = parserNew (name);\n\tdef->initialize        = lazyInitialize;\n\tdef->method            = METHOD_NOT_CRAFTED;\n\n\tsize_t dep_count = (base? 1: 0) + intArrayCount (foreignLanguages);\n\n\tif (dep_count)\n\t{\n\t\tdep = xCalloc (dep_count, parserDependency);\n\t\tdef->dependencies = dep;\n\t\tdef->dependencyCount = dep_count;\n\t\tdef->finalize = optlibFreeDep;\n\t}\n\n\tif (base)\n\t{\n\t\tsubparser *sub = xCalloc (1, subparser);\n\n\t\tsub->direction = direction;\n\t\tdep[0].type = DEPTYPE_SUBPARSER;\n\t\tdep[0].upperParser = eStrdup (base);\n\t\tdep[0].data = sub;\n\t}\n\n\tfor (size_t i = 0 ; i < intArrayCount (foreignLanguages); i++)\n\t{\n\t\tsize_t index = (base? 1: 0) + i;\n\t\tlangType lang = intArrayItem (foreignLanguages, i);\n\t\tAssert (lang != LANG_IGNORE\n\t\t\t\t&& lang != LANG_AUTO\n\t\t\t\t&& lang < (int) LanguageCount);\n\n\t\tdep[index].type = DEPTYPE_FOREIGNER;\n\t\tdep[index].upperParser = eStrdup (getLanguageName (lang));\n\t\tdep[index].data = NULL;\n\t}\n\n\treturn def;\n}\n\nextern void processLanguageDefineOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tchar *name;\n\tchar *flags;\n\tparserDefinition*  def;\n\n\tflags = strchr (parameter, LONG_FLAGS_OPEN);\n\tif (flags)\n\t\tname = eStrndup (parameter, flags - parameter);\n\telse\n\t\tname = eStrdup (parameter);\n\n\t/* Veirfy that the name of new language is acceptable or not. */\n\tchar *unacceptable;\n\tif (name [0] == '\\0')\n\t{\n\t\teFree (name);\n\t\terror (FATAL, \"No language specified for \\\"%s\\\" option\", option);\n\t}\n\telse if (getNamedLanguage (name, 0) != LANG_IGNORE)\n\t{\n\t\t/* name cannot be freed because it is used in the FATAL message. */\n\t\terror (FATAL, \"Language \\\"%s\\\" already defined\", name);\n\t}\n\telse if (strcmp(name, RSV_LANG_ALL) == 0)\n\t{\n\t\teFree (name);\n\t\terror (FATAL, \"\\\"\" RSV_LANG_ALL \"\\\" is reserved; don't use it as the name for defining a new language\");\n\t}\n\telse if (strcmp(name, RSV_NONE) == 0)\n\t{\n\t\teFree (name);\n\t\terror (FATAL, \"\\\"\" RSV_NONE \"\\\" is reserved; don't use it as the name for defining a new language\");\n\n\t}\n\telse if ((unacceptable = acceptableLangName(name)))\n\t{\n\t\tchar c = *unacceptable;\n\n\t\t/* name cannot be freed because it is used in the FATAL message. */\n\t\t/* We accept '_'.\n\t\t * We accept # and + because they are already used in C# parser and C++ parser.\n\t\t * {... is already trimmed at the beginning of this function. */\n\t\tif ((c == '`') || (c == '\\''))\n\t\t\terror (FATAL, \"don't use \\\"%c\\\" in a language name (%s)\", c, name);\n\t\telse\n\t\t\terror (FATAL, \"don't use `%c' in a language name (%s)\", c, name);\n\t}\n\n\tLanguageTable = xRealloc (LanguageTable, LanguageCount + 1, parserObject);\n\tmemset (LanguageTable + LanguageCount, 0, sizeof(parserObject));\n\n\tstruct preLangDefFlagData data = {\n\t\t.name = name,\n\t\t.base = NULL,\n\t\t.direction = SUBPARSER_UNKNOWN_DIRECTION,\n\t\t.autoFQTag = false,\n\t\t.versionCurrent = 0,\n\t\t.versionAge = 0,\n\t};\n\tdata.foreignLanguages = intArrayNew ();\n\n\tflagsEval (flags, PreLangDefFlagDef, ARRAY_SIZE (PreLangDefFlagDef), &data);\n\n\tif (data.base == NULL && data.direction != SUBPARSER_UNKNOWN_DIRECTION)\n\t\terror (WARNING, \"Ignore the direction of subparser because \\\"{base=}\\\" is not given\");\n\n\tif (data.base && data.direction == SUBPARSER_UNKNOWN_DIRECTION)\n\t\tdata.direction = SUBPARSER_BASE_RUNS_SUB;\n\n\tdef = OptlibParser (name, data.base, data.direction,\n\t\t\t\t\t\tdata.foreignLanguages);\n\tif (data.base)\n\t\teFree (data.base);\n\n\tdef->requestAutomaticFQTag = data.autoFQTag;\n\tdef->versionCurrent = data.versionCurrent;\n\tdef->versionAge = data.versionAge;\n\n\tinitializeParsingCommon (def, false, NULL);\n\tlinkDependenciesAtInitializeParsing (def);\n\n\tLanguageTable [def->id].currentRexprs = rexprsNew ();\n\tLanguageTable [def->id].currentPatterns = stringListNew ();\n\tLanguageTable [def->id].currentExtensions = stringListNew ();\n\tLanguageTable [def->id].pretendingAsLanguage = LANG_IGNORE;\n\tLanguageTable [def->id].pretendedAsLanguage = LANG_IGNORE;\n\n\tintArrayDelete (data.foreignLanguages);\n\teFree (name);\n}\n\nextern bool doesLanguageHaveForeignDependency (const langType lang,\n\t\t\t\t\t\t\t\t\t\t\t   const langType foreignLang)\n{\n\tAssert (lang != LANG_IGNORE\n\t\t\t&& lang != LANG_AUTO\n\t\t\t&& lang < (int) LanguageCount);\n\tAssert (foreignLang != LANG_IGNORE\n\t\t\t&& foreignLang != LANG_AUTO\n\t\t\t&& foreignLang < (int) LanguageCount);\n\n\n\tparserDefinition * pdef = LanguageTable [lang].def;\n\n\tfor (size_t i = 0; i < pdef->dependencyCount; i++)\n\t{\n\t\tparserDependency *dep = pdef->dependencies + i;\n\n\t\tif (dep->type == DEPTYPE_FOREIGNER)\n\t\t{\n\t\t\tif (getNamedLanguage (dep->upperParser, 0) == foreignLang)\n\t\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nextern bool isLanguageKindEnabled (const langType language, int kindIndex)\n{\n\tkindDefinition * kdef = getLanguageKind (language, kindIndex);\n\treturn kdef->enabled;\n}\n\nextern bool isLanguageRoleEnabled (const langType language, int kindIndex, int roleIndex)\n{\n\treturn isRoleEnabled(LanguageTable [language].kindControlBlock,\n\t\t\t\t\t\t kindIndex, roleIndex);\n}\n\nextern bool isLanguageKindRefOnly (const langType language, int kindIndex)\n{\n\tkindDefinition * def =  getLanguageKind(language, kindIndex);\n\treturn def->referenceOnly;\n}\n\nstatic void resetLanguageKinds (const langType language, const bool mode)\n{\n\tconst parserObject* parser;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\n\t{\n\t\tunsigned int i;\n\t\tstruct kindControlBlock *kcb = parser->kindControlBlock;\n\n\t\tfor (i = 0  ;  i < countKinds (kcb)  ;  ++i)\n\t\t{\n\t\t\tkindDefinition *kdef = getKind (kcb, i);\n\t\t\tenableKind (kdef, mode);\n\t\t}\n\t}\n}\n\nstatic bool enableLanguageKindForLetter (\n\t\tconst langType language, const int kind, const bool mode)\n{\n\tbool result = false;\n\tkindDefinition* const def = getLanguageKindForLetter (language, kind);\n\tif (def != NULL)\n\t{\n\t\tenableKind (def, mode);\n\t\tresult = true;\n\t}\n\treturn result;\n}\n\nstatic bool enableLanguageKindForName (\n\tconst langType language, const char * const name, const bool mode)\n{\n\tbool result = false;\n\tkindDefinition* const def = getLanguageKindForName (language, name);\n\tif (def != NULL)\n\t{\n\t\tenableKind (def, mode);\n\t\tresult = true;\n\t}\n\treturn result;\n}\n\nstatic void processLangKindDefinition (\n\t\tconst langType language, const char *const option,\n\t\tconst char *const parameter)\n{\n\tconst char *p = parameter;\n\tbool mode = true;\n\tint c;\n\tstatic vString *longName;\n\tbool inLongName = false;\n\tconst char *k;\n\tbool r;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\tinitializeParser (language);\n\tif (*p == '*')\n\t{\n\t\tresetLanguageKinds (language, true);\n\t\tp++;\n\t}\n\telse if (*p != '+'  &&  *p != '-')\n\t\tresetLanguageKinds (language, false);\n\n\tlongName = vStringNewOrClearWithAutoRelease (longName);\n\n\twhile ((c = (unsigned char) *p++) != '\\0')\n\t{\n\t\tswitch (c)\n\t\t{\n\t\tcase '+':\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\tmode = true;\n\t\t\tbreak;\n\t\tcase '-':\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t\tmode = false;\n\t\t\tbreak;\n\t\tcase '{':\n\t\t\tif (inLongName)\n\t\t\t\terror(FATAL,\n\t\t\t\t\t  \"unexpected character in kind specification: \\'%c\\'\",\n\t\t\t\t\t  c);\n\t\t\tinLongName = true;\n\t\t\tbreak;\n\t\tcase '}':\n\t\t\tif (!inLongName)\n\t\t\t\terror(FATAL,\n\t\t\t\t\t  \"unexpected character in kind specification: \\'%c\\'\",\n\t\t\t\t\t  c);\n\t\t\tk = vStringValue (longName);\n\t\t\tr = enableLanguageKindForName (language, k, mode);\n\t\t\tif (! r)\n\t\t\t\terror (WARNING, \"Unsupported kind: '%s' for --%s option\",\n\t\t\t\t\t   k, option);\n\n\t\t\tinLongName = false;\n\t\t\tvStringClear (longName);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (inLongName)\n\t\t\t\tvStringPut (longName, c);\n\t\t\telse\n\t\t\t{\n\t\t\t\tr = enableLanguageKindForLetter (language, c, mode);\n\t\t\t\tif (! r)\n\t\t\t\t\terror (WARNING, \"Unsupported kind: '%c' for --%s option\",\n\t\t\t\t\t\t   c, option);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic void freeKdef (kindDefinition *kdef)\n{\n\teFree (kdef->name);\n\teFree (kdef->description);\n\teFree (kdef);\n}\n\nstatic char *extractDescriptionAndFlags(const char *input, const char **flags)\n{\n\tvString *vdesc = vStringNew();\n\tbool escaped = false;\n\n\tif (flags)\n\t\t*flags = NULL;\n\n\twhile (*input != '\\0')\n\t{\n\t\tif (escaped)\n\t\t{\n\t\t\tvStringPut (vdesc, *input);\n\t\t\tescaped = false;\n\n\t\t}\n\t\telse if (*input == '\\\\')\n\t\t\tescaped = true;\n\t\telse if (*input == LONG_FLAGS_OPEN)\n\t\t{\n\t\t\tif (flags)\n\t\t\t\t*flags = input;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tvStringPut (vdesc, *input);\n\t\tinput++;\n\t}\n\treturn vStringDeleteUnwrap(vdesc);\n}\n\nstatic void pre_kind_def_flag_refonly_long (const char* const optflag,\n\t\t\t\t\t\t\t\t\t\t\tconst char* const param, void* data)\n{\n\tkindDefinition *kdef = data;\n\tkdef->referenceOnly = true;\n}\n\nstatic void pre_kind_def_flag_version_long (const char* const optflag,\n\t\t\t\t\t\t\t\t\t\t\tconst char* const param, void* data)\n{\n\tkindDefinition *kdef = data;\n\n\tif (!isdigit((unsigned char)*param) || !strToUInt (param, 10, &kdef->version))\n\t\terror (FATAL, \"Failed to parse the version number for kind \\\"%s\\\": %s\",\n\t\t\t   kdef->name, param);\n}\n\nstatic flagDefinition PreKindDefFlagDef [] = {\n\t{ '\\0', \"_refonly\", NULL, pre_kind_def_flag_refonly_long,\n\t  NULL, \"use this kind reference tags only\"},\n\t{ '\\0', \"version\",  NULL, pre_kind_def_flag_version_long,\n\t  \"VERSION\", \"in which version of the parser this kind is added\"},\n};\n\nstatic bool processLangDefineKind(const langType language,\n\t\t\t\t\t\t\t\t  const char *const option,\n\t\t\t\t\t\t\t\t  const char *const parameter)\n{\n\tparserObject *parser;\n\n\tkindDefinition *kdef;\n\tchar letter;\n\tconst char * p = parameter;\n\tchar *name;\n\tchar *description;\n\tconst char *name_start;\n\tconst char *marker_end;\n\tsize_t name_len;\n\tconst char *flags;\n\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\n\tAssert (p);\n\n\tif (p[0] == '\\0')\n\t\terror (FATAL, \"no kind definition specified in \\\"--%s\\\" option\", option);\n\n\tletter = p[0];\n\tif (letter == ',')\n\t\terror (FATAL, \"no kind letter specified in \\\"--%s\\\" option\", option);\n\tif (/* See #1697. isalnum expects 0~255 as the range of characters. */\n\t\t!isalpha ((unsigned char)letter)\n\t\t)\n\t\terror (FATAL, \"the kind letter given in \\\"--%s\\\" option is not an alphabet\", option);\n\telse if (letter == KIND_FILE_DEFAULT_LETTER)\n\t\terror (FATAL, \"the kind letter `%c' in \\\"--%s\\\" option is reserved for \\\"%s\\\" kind\",\n\t\t\t   KIND_FILE_DEFAULT_LETTER, option, KIND_FILE_DEFAULT_NAME);\n\telse if (getKindForLetter (parser->kindControlBlock, letter))\n\t{\n\t\terror (WARNING, \"the kind for letter `%c' specified in \\\"--%s\\\" option is already defined.\",\n\t\t\t   letter, option);\n\t\treturn true;\n\t}\n\n\tif (p[1] != ',')\n\t\terror (FATAL, \"wrong kind definition in \\\"--%s\\\" option: no comma after letter\", option);\n\n\tp += 2;\n\tif (p[0] == '\\0')\n\t\terror (FATAL, \"no kind name specified in \\\"--%s\\\" option\", option);\n\tmarker_end = strchr (p, ',');\n\tif (!marker_end)\n\t\terror (FATAL, \"no kind description specified in \\\"--%s\\\" option\", option);\n\n\tname_start = p;\n\twhile (p != marker_end)\n\t{\n\t\tif (p == name_start)\n\t\t{\n\t\t\tif (!isalpha((unsigned char) *p))\n\t\t\t{\n\t\t\t\tchar *name_in_msg = eStrndup (name_start, marker_end - name_start);\n\t\t\t\terror (FATAL,\n\t\t\t\t\t   \"a kind name doesn't start with an alphabetical character: \"\n\t\t\t\t\t   \"'%s' in \\\"--%s\\\" option\",\n\t\t\t\t\t   name_in_msg, option);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (!isalnum ((unsigned char) *p))\n\t\t\t{\n\t\t\t\tchar *name_in_msg = eStrndup (name_start, marker_end - name_start);\n\t\t\t\terror (FATAL,\n\t\t\t\t\t   \"non-alphanumeric char is used as part of kind name: \"\n\t\t\t\t\t   \"'%s' in \\\"--%s\\\" option\",\n\t\t\t\t\t   name_in_msg, option);\n\t\t\t}\n\t\t}\n\t\tp++;\n\t}\n\n\tif (marker_end == name_start)\n\t\terror (FATAL, \"the kind name in \\\"--%s\\\" option is empty\", option);\n\n\tname_len = marker_end - name_start;\n\tif (strncmp (name_start, KIND_FILE_DEFAULT_NAME, name_len) == 0)\n\t\terror (FATAL,\n\t\t\t   \"the kind name \" KIND_FILE_DEFAULT_NAME \" in \\\"--%s\\\" option is reserved\",\n\t\t\t   option);\n\n\tname = eStrndup (name_start, name_len);\n\tif (getKindForName (parser->kindControlBlock, name))\n\t{\n\t\terror (WARNING, \"the kind for name `%s' specified in \\\"--%s\\\" option is already defined.\",\n\t\t\t   name, option);\n\t\teFree (name);\n\t\treturn true;\n\t}\n\n\tp++;\n\tif (p [0] == '\\0' || p [0] == LONG_FLAGS_OPEN)\n\t\terror (FATAL, \"found an empty kind description in \\\"--%s\\\" option\", option);\n\n\tdescription = extractDescriptionAndFlags (p, &flags);\n\n\tkdef = xCalloc (1, kindDefinition);\n\tkdef->enabled = true;\n\tkdef->letter = letter;\n\tkdef->name = name;\n\tkdef->description = description;\n\n\tflagsEval (flags, PreKindDefFlagDef, ARRAY_SIZE (PreKindDefFlagDef), kdef);\n\n\tdefineKind (parser->kindControlBlock, kdef, freeKdef);\n\treturn true;\n}\n\nstatic void freeRdef (roleDefinition *rdef)\n{\n\teFree (rdef->name);\n\teFree (rdef->description);\n\teFree (rdef);\n}\n\nstatic void pre_role_def_flag_version_long (const char* const optflag,\n\t\t\t\t\t\t\t\t\t\t\tconst char* const param, void* data)\n{\n\troleDefinition *rdef = data;\n\n\tif (!isdigit((unsigned char)*param) || !strToUInt (param, 10, &rdef->version))\n\t\terror (FATAL, \"Failed to parse the version number for role \\\"%s\\\": %s\",\n\t\t\t   rdef->name, param);\n}\n\nstatic flagDefinition PreRoleDefFlagDef [] = {\n\t{ '\\0', \"version\",  NULL, pre_role_def_flag_version_long,\n\t  \"VERSION\", \"in which version of the parser this role is added\"},\n};\n\nstatic bool processLangDefineRole(const langType language,\n\t\t\t\t\t\t\t\t  const char *const kindSpec,\n\t\t\t\t\t\t\t\t  const char *const option,\n\t\t\t\t\t\t\t\t  const char *const parameter)\n{\n\tparserObject *parser;\n\n\tkindDefinition *kdef;\n\troleDefinition *rdef;\n\tchar *name;\n\tchar *description;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tAssert (parameter);\n\n\tparser = LanguageTable + language;\n\n\tif (*kindSpec == '{')\n\t{\n\t\tconst char *end = strchr (kindSpec, '}');\n\t\tif (end == NULL)\n\t\t\terror (FATAL, \"no '}' representing the end of kind name in --%s option: %s\",\n\t\t\t\t   option, kindSpec);\n\t\tif (*(end + 1) != '\\0')\n\t\t\terror (FATAL, \"garbage after the kind specification %s in --%s option\",\n\t\t\t\t   kindSpec, option);\n\t\tchar *kindName = eStrndup (kindSpec + 1, end - (kindSpec + 1));\n\t\tif (strcmp (kindName, KIND_FILE_DEFAULT_NAME) == 0)\n\t\t\terror (FATAL, \"don't define a role for %c/%s kind; it has no role: --%s\",\n\t\t\t\t   KIND_FILE_DEFAULT_LETTER, KIND_FILE_DEFAULT_NAME,\n\t\t\t\t   option);\n\t\tkdef = getKindForName (parser->kindControlBlock, kindName);\n\t\tif (kdef == NULL)\n\t\t\terror (FATAL, \"the kind for name `%s' specified in \\\"--%s\\\" option is not defined.\",\n\t\t\t\t   kindName, option);\n\t\teFree (kindName);\n\t}\n\telse\n\t{\n\t\tchar kletter = *kindSpec;\n\t\tif (!isalnum ((unsigned char)kletter))\n\t\t\terror (FATAL, \"the kind letter given in \\\"--%s\\\" option is not an alphabet or a number\", option);\n\t\telse if (kletter == KIND_FILE_DEFAULT_LETTER)\n\t\t\terror (FATAL, \"the kind letter `%c' in \\\"--%s\\\" option is reserved for \\\"%s\\\" kind, and no role can be attached to it\",\n\t\t\t\t   KIND_FILE_DEFAULT_LETTER, option, KIND_FILE_DEFAULT_NAME);\n\t\telse if (*(kindSpec + 1) != '\\0')\n\t\t\terror (FATAL, \"more than one letters are specified as a kind spec in \\\"--%s\\\" option: use `{' and `}' for specifying a kind name\",\n\t\t\t\t   option);\n\n\t\tkdef = getKindForLetter (parser->kindControlBlock, kletter);\n\t\tif (kdef == NULL)\n\t\t{\n\t\t\terror (FATAL, \"the kind for letter `%c' specified in \\\"--%s\\\" option is not defined.\",\n\t\t\t\t   *kindSpec, option);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tconst char * p = parameter;\n\tconst char *tmp_end = strchr (p, ',');\n\tif (!tmp_end)\n\t\terror (FATAL, \"no role description specified in \\\"--%s\\\" option\", option);\n\n\tconst char * tmp_start = p;\n\twhile (p != tmp_end)\n\t{\n\t\tif (!isalnum ((unsigned char) *p))\n\t\t\terror (FATAL, \"unacceptable char as part of role name in \\\"--%s\\\" option: '%c'\",\n\t\t\t\t   option, *p);\n\t\tp++;\n\t}\n\n\tif (tmp_end == tmp_start)\n\t\terror (FATAL, \"the role name in \\\"--%s\\\" option is empty\", option);\n\n\tname = eStrndup (tmp_start, tmp_end - tmp_start);\n\tif (getRoleForName (parser->kindControlBlock, kdef->id, name))\n\t{\n\t\terror (WARNING, \"the role for name `%s' specified in \\\"--%s\\\" option is already defined.\",\n\t\t\t   name, option);\n\t\teFree (name);\n\t\treturn true;\n\t}\n\n\tp++;\n\tif (p [0] == '\\0' || p [0] == LONG_FLAGS_OPEN)\n\t\terror (FATAL, \"found an empty role description in \\\"--%s\\\" option\", option);\n\n\tconst char *flags;\n\tdescription = extractDescriptionAndFlags (p, &flags);\n\n\trdef = xCalloc (1, roleDefinition);\n\trdef->enabled = true;\n\trdef->name = name;\n\trdef->description = description;\n\n\tflagsEval (flags, PreRoleDefFlagDef, ARRAY_SIZE (PreRoleDefFlagDef), rdef);\n\n\tdefineRole (parser->kindControlBlock, kdef->id, rdef, freeRdef);\n\n\treturn true;\n}\n\nextern bool processKinddefOption (const char *const option, const char * const parameter)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"kinddef-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\treturn processLangDefineKind (language, option, parameter);\n}\n\nextern bool processRoledefOption (const char *const option, const char * const parameter)\n{\n#define PREFIX \"_roledef-\"\n#define PREFIX_LEN strlen(PREFIX)\n\n\tlangType language = getLanguageComponentInOption (option, PREFIX);\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tconst char* kindSpec = option + PREFIX_LEN + strlen (getLanguageName (language));\n\tif (*kindSpec == '\\0')\n\t\terror (FATAL, \"no kind is specifined in \\\"--%s=%s\\\"\", option, parameter);\n\tif (*kindSpec != '.')\n\t\terror (FATAL, \"no delimiter (.) where a kindspec starts is found in \\\"--%s\\\": %c\",\n\t\t\t   option, *kindSpec);\n\tkindSpec++;\n\n\treturn processLangDefineRole (language, kindSpec, option, parameter);\n#undef PREFIX\n#undef PREFIX_LEN\n}\n\nstruct langKindDefinitionStruct {\n\tconst char *const option;\n\tconst char *const parameter;\n};\nstatic void processLangKindDefinitionEach(\n\tlangType lang, void* user_data)\n{\n\tstruct langKindDefinitionStruct *arg = user_data;\n\tprocessLangKindDefinition (lang, arg->option, arg->parameter);\n}\n\nstatic bool parameterEnablingAllOrFileKind (const char *const option,\n\t\t\t\t\t\t\t\t\t\t\tconst char *const parameter,\n\t\t\t\t\t\t\t\t\t\t\tbool following_plus_or_minus_op)\n{\n\tsize_t file_long_flag_len = strlen(KIND_FILE_DEFAULT_NAME);\n\n\tswitch (parameter[0])\n\t{\n\t/* Though only '*' is documented as an acceptable kind spec for\n\t * --kinds-all option in our man page, we accept '\\0' here because\n\t * it will be useful for testing purpose. */\n\tcase '\\0':\n\t\tif (following_plus_or_minus_op)\n\t\t\terror(FATAL, \"no kind specification after + (or -) in --%s option\",\n\t\t\t\t  option);\n\t\telse\n\t\t\treturn true;\n\tcase '+':\n\tcase '-':\n\t\tif (following_plus_or_minus_op)\n\t\t\terror(FATAL, \"don't repeat + (nor -) in --%s option\",\n\t\t\t\t  option);\n\t\telse\n\t\t\treturn parameterEnablingAllOrFileKind (option, parameter + 1, true);\n\tcase KIND_WILDCARD_LETTER:\n\t\tif (following_plus_or_minus_op)\n\t\t\terror(FATAL, \"don't use '*' after + (nor -) in --%s option\",\n\t\t\t\t  option);\n\t\telse\n\t\t\treturn parameterEnablingAllOrFileKind (option, parameter + 1, false);\n\tcase KIND_FILE_DEFAULT_LETTER:\n\t\treturn parameterEnablingAllOrFileKind (option, parameter + 1, false);\n\tcase '{':\n\t\tif (strncmp (parameter + 1, KIND_FILE_DEFAULT_NAME, file_long_flag_len) == 0\n\t\t\t&& parameter [1 + file_long_flag_len] == '}')\n\t\t\treturn parameterEnablingAllOrFileKind (option,\n\t\t\t\t\t\t\t\t\t\t\t\t   parameter + 1 + file_long_flag_len + 1,\n\t\t\t\t\t\t\t\t\t\t\t\t   false);\n\t\tbreak;\n\t}\n\treturn false;\n}\n\nextern bool processKindsOption (\n\t\tconst char *const option, const char *const parameter)\n{\n#define PREFIX \"kinds-\"\n#define PREFIX_LEN strlen(PREFIX)\n\n\tbool handled = false;\n\tstruct langKindDefinitionStruct arg = {\n\t\t.option = option,\n\t\t.parameter = parameter,\n\t};\n\tlangType language;\n\n\tconst char* const dash = strchr (option, '-');\n\tif (dash != NULL  &&\n\t\t(strcmp (dash + 1, \"kinds\") == 0  ||  strcmp (dash + 1, \"types\") == 0))\n\t{\n\t\tsize_t len = dash - option;\n\t\tchar *langName = eStrndup (option, len);\n\n\t\tif ((len == 3) && (strcmp (langName, RSV_LANG_ALL) == 0))\n\t\t{\n\t\t\terror (WARNING,\n\t\t\t\t   \"\\\"--%s\\\" option is obsolete; use \\\"--kinds-%s\\\" instead\",\n\t\t\t\t   option, langName);\n\t\t\tif (!parameterEnablingAllOrFileKind (option, parameter, false))\n\t\t\t\terror (FATAL, \"only '*', 'F', \\\"{file}\\\" or their combination is acceptable as kind letter for --%s\", option);\n\t\t\tforeachLanguage(processLangKindDefinitionEach, &arg);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlanguage = getNamedLanguage (langName, 0);\n\t\t\tif (language == LANG_IGNORE)\n\t\t\t\terror (WARNING, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", langName, option);\n\t\t\telse\n\t\t\t\tprocessLangKindDefinition (language, option, parameter);\n\t\t}\n\t\teFree (langName);\n\t\thandled = true;\n\t}\n\telse if ( strncmp (option, PREFIX, PREFIX_LEN) == 0 )\n\t{\n\t\tconst char* lang;\n\n\t\tlang = option + PREFIX_LEN;\n\t\tif (lang[0] == '\\0')\n\t\t\terror (WARNING, \"No language given in \\\"%s\\\" option\", option);\n\t\telse if (strcmp (lang, RSV_LANG_ALL) == 0)\n\t\t{\n\t\t\tif (!parameterEnablingAllOrFileKind (option, parameter, false))\n\t\t\t\terror (FATAL, \"only '*', 'F', \\\"{file}\\\" or their combination is acceptable as kind letter for --%s\", option);\n\t\t\tforeachLanguage(processLangKindDefinitionEach, &arg);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlanguage = getNamedLanguage (lang, 0);\n\t\t\tif (language == LANG_IGNORE)\n\t\t\t\terror (WARNING, \"Unknown language \\\"%s\\\" in \\\"%s\\\" option\", lang, option);\n\t\t\telse\n\t\t\t\tprocessLangKindDefinition (language, option, parameter);\n\t\t}\n\t\thandled = true;\n\t}\n\treturn handled;\n#undef PREFIX\n#undef PREFIX_LEN\n}\n\n/*\n * The argument specification for --roles-<LANG>:<KIND>= option\n * =====================================================================\n *\n * --roles-all.*=\n * --roles-all=\n * => Disable all roles of all kinds in all languages.\n *\n * --roles-all.*='*'\n * --roles-all='*'\n * => Enable all roles of all kinds in all languages.\n *\n * --roles-<LANG>.*=\n * --roles-<LANG>=\n * => Disable all roles of all kinds.\n *\n * --roles-<LANG>.*=*\n * --roles-<LANG>=*\n * => Enable all roles of all kinds.\n *\n * --roles-<LANG>.{kind}=\n * --roles-<LANG>.k=\n * => Disable all roles of the kind specified with a letter.\n *\n * --roles-<LANG>.{kind}=*\n * --roles-<LANG>.k=*\n * => Enable all roles of the kind specified with a letter.\n *\n * --roles-<LANG>.{kind}=[+|-]{role}\n * --roles-<LANG>.k=[+|-]{role}\n * => Enable/disable the role of the kind specified with a letter.\n *\n *\n * Examples of combination\n * ---------------------------------------------------------------------\n *\n * --roles-<LANG>.k0=+{role0}-{role1}{role2}\n * --roles-<LANG>.{kind1}=+{role0}-{role1}{role2}\n *\n *\n * How --roledef should be change to align --roles-<LANG> notation\n * ---------------------------------------------------------------------\n *\n * --_roledef-<LANG>.k=role,description\n * --_roledef-<LANG>.{kind}=role,description\n *\n * The notation was\n *  --_roledef-<LANG>=k.role,description\n *\n *\n * How --param should be change to align --roles-<LANG> notation\n * ---------------------------------------------------------------------\n *\n * --param-<LANG>.name=argument\n *\n * The notation was\n * --param-<LANG>:name=argument\n *\n *\n * How --paramdef should be to align --roles-<LANG> notation\n * ---------------------------------------------------------------------\n *\n * --_paramdef-<LANG>.name=[ default (desription) ]\n *\n *\n * Discussion: which shoule we use . or : ?\n * ---------------------------------------------------------------------\n *\n * `.' is better because `:' implies fields.\n *\n */\nstruct langKindRoleDefinitionStruct {\n\tint kindIndex;\n\tconst char *const option;\n\tconst char *const parameter;\n};\n\ntypedef void (*kindCallback)  (langType language, int kindIndex, void* user_data);\nstatic void foreachKind(langType language, kindCallback callback, void *user_data)\n{\n\tunsigned int c = countLanguageKinds (language);\n\tfor (unsigned int i = 0; i < c; i++)\n\t\tcallback (language, (int)i, user_data);\n}\n\nstatic void resetKindRoles (const langType language, int kindIndex, const bool mode)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tunsigned int c = countLanguageRoles (language, kindIndex);\n\n\tfor (unsigned int i = 0; i < c; i++)\n\t{\n\t\troleDefinition* rdef = getLanguageRole (language, kindIndex, (int)i);\n\t\tenableRole (rdef, mode);\n\t}\n}\n\nstatic void resetKindRolesAsCallback (const langType language, int kindIndex, void *user_data)\n{\n\tbool mode = (bool)user_data;\n\tresetKindRoles (language, kindIndex, mode);\n}\n\nstatic void processLangKindRoleDefinition (\n\t\tconst langType language, const int kindIndex, const char *const option,\n\t\tconst char *const parameter)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tAssert (kindIndex != KIND_GHOST_INDEX);\n\tinitializeParser (language);\n\n\tconst char *p = parameter;\n\tbool mode = true;\n\n\tif (*p == '\\0')\n\t{\n\t\tresetKindRoles (language, kindIndex, false);\n\t\treturn;\n\t}\n\telse if (*p != '+' && *p != '-' )\n\t\tresetKindRoles (language, kindIndex, false);\n\n\twhile (*p != '\\0')\n\t{\n\t\tif (*p == '+')\n\t\t{\n\t\t\tmode = true;\n\t\t\tp++;\n\t\t}\n\t\telse if (*p == '-')\n\t\t{\n\t\t\tmode = false;\n\t\t\tp++;\n\t\t}\n\t\telse if (*p == '{')\n\t\t{\n\t\t\tp++;\n\t\t\tchar *q = strchr (p, '}');\n\t\t\tif (!q)\n\n\t\t\t\terror (FATAL, \"no '}' representing the end of role name in --%s option: %s\",\n\t\t\t\t\t   option, p);\n\t\t\tif (p == q)\n\t\t\t\terror (FATAL, \"empty role for the kind letter: %c\",\n\t\t\t\t\t   getLanguageKind (language, kindIndex)->letter);\n\n\t\t\tchar *rname = eStrndup (p,  q - p);\n\t\t\troleDefinition *rdef = getLanguageRoleForName (language, kindIndex, rname);\n\t\t\tif (!rdef)\n\t\t\t\terror (WARNING, \"no such role: \\\"%s\\\" in kind \\'%c\\' in language \\\"%s\\\"\",\n\t\t\t\t\t   rname, getLanguageKind (language, kindIndex)->letter,\n\t\t\t\t\t   getLanguageName (language));\n\t\t\telse\n\t\t\t\tenableRole (rdef, mode);\n\t\t\teFree (rname);\n\t\t\tp = q + 1;\n\t\t}\n\t\telse if (*p == '*')\n\t\t{\n\t\t\tresetKindRoles (language, kindIndex, true);\n\t\t\tp++;\n\t\t}\n\t\telse\n\t\t\terror (FATAL, \"unexpected character %c in --%s=%s option\",\n\t\t\t\t   *p, option, parameter);\n\t}\n}\n\nstatic void processLangKindRoleDefinitionEach (langType language, void* user_data)\n{\n\tstruct langKindRoleDefinitionStruct *arg = user_data;\n\n\tif (arg->kindIndex == KIND_GHOST_INDEX)\n\t{\n\t\tinitializeParser (language);\n\t\tforeachKind (language, resetKindRolesAsCallback,\n\t\t\t\t\t ((*(arg->parameter) == '*')? (void *)true: (void *)false));\n\t}\n\telse\n\t\tprocessLangKindRoleDefinition (language, arg->kindIndex,\n\t\t\t\t\t\t\t\t\t   arg->option, arg->parameter);\n}\n\nextern bool processRolesOption (const char *const option, const char *const parameter)\n{\n#define PREFIX \"roles-\"\n#define PREFIX_LEN strlen(PREFIX)\n\n\tif ( strncmp (option, PREFIX, PREFIX_LEN) != 0 )\n\t\treturn false;\n\n\tconst char* lang = option + PREFIX_LEN;\n\tif (lang[0] == '\\0')\n\t{\n\t\terror (WARNING, \"no language given in \\\"%s\\\" option\", option);\n\t\treturn true;\n\t}\n\n\t/*\n\t * --roles-all.*=\n\t * --roles-all=\n\t * => Disable all roles of all kinds in all languages.\n\t *\n\t * --roles-all.*='*'\n\t * --roles-all='*'\n\t * => Enable all roles of all kinds in all languages.\n\t */\n\tif (strncmp (lang, RSV_LANG_ALL, strlen(RSV_LANG_ALL)) == 0)\n\t{\n\t\tif (lang [strlen (RSV_LANG_ALL)] == '\\0'\n\t\t\t|| (strcmp (lang + strlen (RSV_LANG_ALL), \".*\") == 0))\n\t\t{\n\t\t\tif (*parameter == '\\0'\n\t\t\t\t|| strcmp(parameter, \"*\") == 0)\n\t\t\t{\n\t\t\t\tstruct langKindRoleDefinitionStruct arg = {\n\t\t\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t\t\t.option = option,\n\t\t\t\t\t.parameter = parameter,\n\t\t\t\t};\n\t\t\t\tforeachLanguage (processLangKindRoleDefinitionEach, &arg);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\terror (FATAL, \"only '*' or '' (empty string) is acceptable as an argument for --%s: %s\",\n\t\t\t\t\t   option,\n\t\t\t\t\t   parameter);\n\t\t}\n\t\telse if (lang [strlen(RSV_LANG_ALL)] == '.')\n\t\t\terror (FATAL, \"only '*' or '' (empty string) is acceptable as a kind spec for --%sall: --%s\",\n\t\t\t\t   PREFIX,\n\t\t\t\t   option);\n\t}\n\n\t/* Decide the language. */\n\tlangType language;\n\tconst char *dot = strchr (lang, '.');\n\tif (dot)\n\t\tlanguage = getNamedLanguage (lang, dot - lang);\n\telse\n\t\tlanguage = getNamedLanguage (lang, 0);\n\n\tif (language == LANG_IGNORE)\n\t{\n\t\tchar *lang0 = dot? eStrndup (lang, dot - lang): NULL;\n\t\terror (WARNING, \"unknown language \\\"%s\\\" in --%s option\",\n\t\t\t   (lang0? lang0: lang), option);\n\t\tif (lang0)\n\t\t\teFree (lang0);\n\t\treturn true;\n\t}\n\n\t/*\n\t * --roles-<LANG>.*=\n\t * --roles-<LANG>=\n\t * => Disable all roles of all kinds.\n\t *\n\t * --roles-<LANG>.*=*\n\t * --roles-<LANG>=*\n\t * => Enable all roles of all kinds.\n\t */\n\tif (dot == NULL || (strcmp (dot, \".*\") == 0))\n\t{\n\t\tif (*parameter == '\\0'\n\t\t\t|| strcmp(parameter, \"*\") == 0)\n\t\t{\n\t\t\tforeachKind (language, resetKindRolesAsCallback,\n\t\t\t\t\t\t ((*parameter == '*')? (void*)true: (void*)false));\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\terror (FATAL, \"only '*' or '' (empty string) is acceptable as an argument for --%s: %s\",\n\t\t\t\t   option,\n\t\t\t\t   parameter);\n\t}\n\n\t/* Decide the kind of the language. */\n\tparserObject *parser = LanguageTable + language;\n\tint kindIndex = KIND_GHOST_INDEX;\n\tconst char *kind = dot + 1;\n\tif (*kind == '{')\n\t{\n\t\tconst char *name_end = strchr (kind, '}');\n\t\tif (name_end == NULL)\n\t\t\terror (FATAL, \"no '}' representing the end of kind name in --%s option: %s\",\n\t\t\t\t   option, kind);\n\t\tchar *kindName = eStrndup (kind + 1, name_end - (kind + 1));\n\t\tif (strcmp (kindName, KIND_FILE_DEFAULT_NAME) == 0)\n\t\t{\n\t\t\terror (WARNING, \"don't enable/disable a role in %c/%s kind; it has no role: --%s\",\n\t\t\t\t   KIND_FILE_DEFAULT_LETTER, KIND_FILE_DEFAULT_NAME,\n\t\t\t\t   option);\n\t\t\treturn true;\n\t\t}\n\t\tkindIndex = getKindIndexForName (parser->kindControlBlock, kindName);\n\t\tif (kindIndex == KIND_GHOST_INDEX)\n\t\t{\n\t\t\teFree (kindName);\n\t\t\terror (WARNING, \"no such kind name as specified in --%s option\", option);\n\t\t\treturn true;\n\t\t}\n\t\tif (*(name_end + 1) != '\\0')\n\t\t\terror (FATAL, \"garbage after the kind specification {%s} in --%s option\",\n\t\t\t\t   kindName, option);\n\t\teFree (kindName);\n\t}\n\telse if (isalpha ((unsigned char)*kind))\n\t{\n\t\tif (*kind == KIND_FILE_DEFAULT_LETTER)\n\t\t{\n\t\t\terror (WARNING, \"don't enable/disable a role in %c/%s kind; it has no role: --%s\",\n\t\t\t\t   KIND_FILE_DEFAULT_LETTER, KIND_FILE_DEFAULT_NAME,\n\t\t\t\t   option);\n\t\t\treturn true;\n\t\t}\n\t\tkindIndex = getKindIndexForLetter (parser->kindControlBlock, *kind);\n\t\tif (kindIndex == KIND_GHOST_INDEX)\n\t\t{\n\t\t\terror (WARNING, \"no such kind letter as specified in --%s option\", option);\n\t\t\treturn true;\n\t\t}\n\t\tif (*(kind + 1) != '\\0')\n\t\t\terror (FATAL, \"garbage after the kind specification '%c' in --%s option\",\n\t\t\t\t   *kind, option);\n\t}\n\telse\n\t\terror (FATAL, \"'%c', unexpected character in --%s\", *kind, option);\n\n\n\t/*\n\t * --roles-<LANG>.{kind}=\n\t * --roles-<LANG>.k=\n\t * => Disable all roles of the kind specified with a letter.\n\t *\n\t * --roles-<LANG>.{kind}=*\n\t * --roles-<LANG>.k=*\n\t * => Enable all roles of the kind specified with a letter.\n\t *\n\t * --roles-<LANG>.{kind}=[+|-|]{role}\n\t * --roles-<LANG>.k=[+|-|]{role}\n\t * => Enable/disable the role of the kind specified with a letter.\n\t */\n\tprocessLangKindRoleDefinition (language, kindIndex, option, parameter);\n\n\treturn true;\n#undef PREFIX\n#undef PREFIX_LEN\n}\n\nextern void printLanguageRoles (const langType language, const char* kindspecs,\n\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp)\n{\n\tstruct colprintTable *table = roleColprintTableNew();\n\tparserObject *parser;\n\n\tinitializeParser (language);\n\n\tif (language == LANG_AUTO)\n\t{\n\t\tfor (unsigned int i = 0  ;  i < LanguageCount  ;  ++i)\n\t\t{\n\t\t\tif (!isLanguageVisible (i))\n\t\t\t\tcontinue;\n\n\t\t\tparser = LanguageTable + i;\n\t\t\troleColprintAddRoles (table, parser->kindControlBlock, kindspecs);\n\t\t}\n\t}\n\telse\n\t{\n\t\tparser = LanguageTable + language;\n\t\troleColprintAddRoles (table, parser->kindControlBlock, kindspecs);\n\t}\n\n\troleColprintTablePrint (table, (language != LANG_AUTO),\n\t\t\t\t\t\t\twithListHeader, machinable, fp);\n\tcolprintTableDelete (table);\n}\n\nstatic void printKinds (langType language, bool indent,\n\t\t\t\t\t\tstruct colprintTable * table)\n{\n\tconst parserObject *parser;\n\tstruct kindControlBlock *kcb;\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\tinitializeParser (language);\n\tparser = LanguageTable + language;\n\tkcb = parser->kindControlBlock;\n\n\tif (table)\n\t\tkindColprintAddLanguageLines (table, kcb);\n\telse\n\t{\n\t\tfor (unsigned int i = 0  ;  i < countKinds(kcb)  ;  ++i)\n\t\t\tprintKind (getKind(kcb, i), indent);\n\t}\n}\n\nextern void printLanguageKinds (const langType language, bool allKindFields,\n\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp)\n{\n\tstruct colprintTable * table = NULL;\n\n\tif (allKindFields)\n\t\ttable = kindColprintTableNew ();\n\n\tif (language == LANG_AUTO)\n\t{\n\t\tfor (unsigned int i = 0  ;  i < LanguageCount  ;  ++i)\n\t\t{\n\t\t\tconst parserDefinition* const lang = LanguageTable [i].def;\n\n\t\t\tif (lang->invisible)\n\t\t\t\tcontinue;\n\n\t\t\tif (!table)\n\t\t\t\tprintf (\"%s%s\\n\", lang->name, isLanguageEnabled (i) ? \"\" : \" [disabled]\");\n\t\t\tprintKinds (i, true, table);\n\t\t}\n\t}\n\telse\n\t\tprintKinds (language, false, table);\n\n\tif (allKindFields)\n\t{\n\t\tkindColprintTablePrint(table, (language == LANG_AUTO)? 0: 1,\n\t\t\t\t\t\t\t   withListHeader, machinable, fp);\n\t\tcolprintTableDelete (table);\n\t}\n}\n\nextern bool processParamOption (\n\t\t\tconst char *const option, const char *const value)\n{\n\tlangType language;\n\tconst char* name;\n\tconst char* sep;\n\n\tlanguage = getLanguageComponentInOption (option, \"param-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\tsep = option + strlen (\"param-\") + strlen (getLanguageName (language));\n\t/* `:' is only for keeping self compatibility */\n\tif (! (*sep == '.' || *sep == ':' ))\n\t\terror (FATAL, \"no separator(.) is given for %s=%s\", option, value);\n\tname = sep + 1;\n\n\tif (value == NULL || value [0] == '\\0')\n\t\terror (FATAL, \"no value is given for %s\", option);\n\n\tif (applyLanguageParam (language, name, value))\n\t\tpropagateParamToOptscript (LanguageTable [language].lregexControlBlock,\n\t\t\t\t\t\t\t\t   name, value);\n\treturn true;\n}\n\nstatic void freePdef (paramDefinition *pdef)\n{\n\teFree ((void *)pdef->name);\n\teFree ((void *)pdef->desc);\n\teFree (pdef);\n}\n\nstatic bool processLangDefineParam (const langType language,\n\t\t\t\t\t\t\t\t\tconst char *const option,\n\t\t\t\t\t\t\t\t\tconst char *const parameter)\n{\n\tparserObject *parser;\n\n\tparamDefinition *pdef;\n\tconst char * p = parameter;\n\tconst char *name_end;\n\tconst char *desc;\n\tconst char *flags;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tAssert (p);\n\n\tif (p[0] == '\\0')\n\t\terror (FATAL, \"no parameter definition specified in \\\"--%s\\\" option\", option);\n\n\tname_end = strchr (p, ',');\n\tif (!name_end)\n\t\terror (FATAL, \"no parameter description specified in \\\"--%s\\\" option\", option);\n\telse if (name_end == p)\n\t\terror (FATAL, \"the parameter name in \\\"--%s\\\" option is empty\", option);\n\n\tfor (; p < name_end; p++)\n\t{\n\t\tif (!isalnum ((unsigned char) *p) && *p != '_')\n\t\t\terror (FATAL, \"unacceptable char as part of parameter name in \\\"--%s\\\" option: '%c'\",\n\t\t\t\t   option, *p);\n\t}\n\n\tp++;\n\tif (p [0] == '\\0' || p [0] == LONG_FLAGS_OPEN)\n\t\terror (FATAL, \"parameter description in \\\"--%s\\\" option is empty\", option);\n\n\tdesc = extractDescriptionAndFlags (p, &flags);\n\n\tpdef = xCalloc (1, paramDefinition);\n\tpdef->name = eStrndup (parameter, name_end - parameter);\n\tpdef->desc = desc;\n\n\tflagsEval (flags, NULL, 0, pdef);\n\n\tparser = LanguageTable + language;\n\tdefineParam (parser->paramControlBlock, pdef, freePdef);\n\treturn true;\n}\n\nextern bool processParamdefOption (const char *const option, const char *const value)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"_paramdef-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\treturn processLangDefineParam (language, option, value);\n}\n\nstatic void printParams (struct colprintTable *table, langType language)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\tinitializeParser (language);\n\tparamColprintAddParams (table,\n\t\t\t\t\t\t\tLanguageTable [language].paramControlBlock);\n}\n\nextern void printLanguageParams (const langType language,\n\t\t\t\t\t\t\t\t bool withListHeader, bool machinable, FILE *fp)\n{\n\tstruct colprintTable *table =  paramColprintTableNew();\n\n\tif (language == LANG_AUTO)\n\t{\n\t\tfor (unsigned int i = 0; i < LanguageCount ; ++i)\n\t\t{\n\t\t\tconst parserDefinition* const lang = LanguageTable [i].def;\n\n\t\t\tif (lang->invisible)\n\t\t\t\tcontinue;\n\n\t\t\tprintParams (table, i);\n\t\t}\n\t}\n\telse\n\t\tprintParams (table, language);\n\n\tparamColprintTablePrint (table, (language != LANG_AUTO),\n\t\t\t\t\t\t\t withListHeader, machinable, fp);\n\tcolprintTableDelete (table);\n}\n\nstatic void processLangAliasOption (const langType language,\n\t\t\t\t\tconst char *const parameter)\n{\n\tconst char* alias;\n\tconst parserObject * parser;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\n\tif (parameter[0] == '\\0')\n\t{\n\t\tclearLanguageAliases (language);\n\t\tverbose (\"clear aliases for %s\\n\", parser->def->name);\n\t}\n\telse if (strcmp (parameter, RSV_LANGMAP_DEFAULT) == 0)\n\t{\n\t\tinstallLanguageAliasesDefault (language);\n\t\tverbose (\"reset aliases for %s\\n\", parser->def->name);\n\t}\n\telse if (parameter[0] == '+')\n\t{\n\t\talias = parameter + 1;\n\t\taddLanguageAlias(language, alias);\n\t\tverbose (\"add an alias %s to %s\\n\", alias, parser->def->name);\n\t}\n\telse if (parameter[0] == '-')\n\t{\n\t\tif (parser->currentAliases)\n\t\t{\n\t\t\talias = parameter + 1;\n\t\t\tif (stringListDeleteItemExtension (parser->currentAliases, alias))\n\t\t\t{\n\t\t\t\tverbose (\"remove an alias %s from %s\\n\", alias, parser->def->name);\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\talias = parameter;\n\t\tclearLanguageAliases (language);\n\t\taddLanguageAlias(language, alias);\n\t\tverbose (\"set alias %s to %s\\n\", alias, parser->def->name);\n\t}\n\n}\n\nextern bool processAliasOption (\n\t\tconst char *const option, const char *const parameter)\n{\n\tlangType language;\n\n\tAssert (parameter);\n\n#define PREFIX \"alias-\"\n\tif (strcmp (option, \"alias-\" RSV_LANG_ALL) == 0)\n\t{\n\t\tif ((parameter[0] == '\\0')\n\t\t\t|| (strcmp (parameter, RSV_LANGMAP_DEFAULT) == 0))\n\t\t{\n\t\t\tfor (unsigned int i = 0; i < LanguageCount; i++)\n\t\t\t{\n\t\t\t\tclearLanguageAliases (i);\n\t\t\t\tverbose (\"clear aliases for %s\\n\", getLanguageName(i));\n\t\t\t}\n\n\t\t\tif (parameter[0] != '\\0')\n\t\t\t{\n\t\t\t\tverbose (\"  Installing default language aliases:\\n\");\n\t\t\t\tinstallLanguageAliasesDefaults ();\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\terror (WARNING, \"Use \\\"%s\\\" option for reset (\\\"default\\\") or clearing (\\\"\\\")\", option);\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tlanguage = getLanguageComponentInOption (option, \"alias-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n#undef PREFIX\n\n\tprocessLangAliasOption (language, parameter);\n\treturn true;\n}\n\nstatic void printMaps (const langType language, langmapType type)\n{\n\tconst parserObject* parser;\n\tunsigned int i;\n\n\tparser = LanguageTable + language;\n\tif (! (LMAP_NO_LANG_PREFIX & type))\n\t\tprintf (\"%-8s\", parser->def->name);\n\tif (parser->currentRexprs != NULL && (type & LMAP_REXPR))\n\t{\n\t\tfor (i = 0 ; i < ptrArrayCount (parser->currentRexprs) ; ++i)\n\t\t{\n\t\t\tstruct rExprCode *rxcode = ptrArrayItem (parser->currentRexprs,\n\t\t\t\t\t\t\t\t\t\t\t\t\t i);\n\t\t\tvString *encodedSource = rExprCodeNewEncodedSource (rxcode);\n\t\t\tprintf (\" %s\", vStringValue (encodedSource));\n\t\t\tvStringDelete (encodedSource);\n\t\t}\n\t}\n\n\tif (parser->currentPatterns != NULL && (type & LMAP_PATTERN))\n\t\tfor (i = 0  ;  i < stringListCount (parser->currentPatterns)  ;  ++i)\n\t\t\tprintf (\" %s\", vStringValue (\n\t\t\t\t\t\tstringListItem (parser->currentPatterns, i)));\n\tif (parser->currentExtensions != NULL && (type & LMAP_EXTENSION))\n\t\tfor (i = 0  ;  i < stringListCount (parser->currentExtensions)  ;  ++i)\n\t\t\tprintf (\" *.%s\", vStringValue (\n\t\t\t\t\t\tstringListItem (parser->currentExtensions, i)));\n\tputchar ('\\n');\n}\n\nstatic struct colprintTable *mapColprintTableNew (langmapType type)\n{\n\tif ((type & LMAP_ALL) == LMAP_ALL)\n\t\treturn colprintTableNew (\"L:LANGUAGE\", \"L:TYPE\", \"L:MAP\", NULL);\n\telse if (type & LMAP_PATTERN)\n\t\treturn colprintTableNew (\"L:LANGUAGE\", \"L:PATTERN\", NULL);\n\telse if (type & LMAP_EXTENSION)\n\t\treturn colprintTableNew (\"L:LANGUAGE\", \"L:EXTENSION\", NULL);\n\telse if (type & LMAP_REXPR)\n\t\treturn colprintTableNew (\"L:LANGUAGE\", \"L:EXPRESSION\", \"L:CASE\", NULL);\n\telse\n\t{\n\t\tAssertNotReached ();\n\t\treturn NULL;\n\t}\n}\n\nstatic void mapColprintAddLanguage (struct colprintTable * table,\n\t\t\t\t\t\t\t\t\tlangmapType type,\n\t\t\t\t\t\t\t\t\tconst parserObject* parser)\n{\n\tstruct colprintLine * line;\n\tunsigned int count;\n\tunsigned int i;\n\n\tif ((type & LMAP_REXPR)\n\t\t&& parser->currentRexprs\n\t\t&& (0 < (count = ptrArrayCount (parser->currentRexprs))))\n\t{\n\t\tfor (i = 0; i < count; i++)\n\t\t{\n\t\t\tline = colprintTableGetNewLine (table);\n\t\t\tstruct rExprCode *rxcode = ptrArrayItem (parser->currentRexprs,\n\t\t\t\t\t\t\t\t\t\t\t\t\t i);\n\n\t\t\tcolprintLineAppendColumnCString (line, parser->def->name);\n\t\t\tif ((type & LMAP_ALL) != LMAP_REXPR)\n\t\t\t{\n\t\t\t\tcolprintLineAppendColumnCString (line, \"rexpr\");\n\t\t\t\tvString *encodedSource = rExprCodeNewEncodedSource (rxcode);\n\t\t\t\tcolprintLineAppendColumnVString (line, encodedSource);\n\t\t\t\tvStringDelete (encodedSource);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tconst char *rxsrc = rExprCodeGetSource (rxcode);\n\t\t\t\tbool iCase = rExprCodeGetICase (rxcode);\n\n\t\t\t\tcolprintLineAppendColumnCString (line, rxsrc);\n\t\t\t\tcolprintLineAppendColumnCString (line, iCase? \"insensitive\": \"sensitive\");\n\t\t\t}\n\t\t}\n\t}\n\n\tif ((type & LMAP_PATTERN) && (0 < (count = stringListCount (parser->currentPatterns))))\n\t{\n\t\tfor (i = 0; i < count; i++)\n\t\t{\n\t\t\tline = colprintTableGetNewLine (table);\n\t\t\tvString *pattern = stringListItem (parser->currentPatterns, i);\n\n\t\t\tcolprintLineAppendColumnCString (line, parser->def->name);\n\t\t\tif ((type & LMAP_ALL) != LMAP_PATTERN)\n\t\t\t\tcolprintLineAppendColumnCString (line, \"pattern\");\n\t\t\tcolprintLineAppendColumnVString (line, pattern);\n\t\t}\n\t}\n\n\tif ((type & LMAP_EXTENSION) && (0 < (count = stringListCount (parser->currentExtensions))))\n\t{\n\t\tfor (i = 0; i < count; i++)\n\t\t{\n\t\t\tline = colprintTableGetNewLine (table);\n\t\t\tvString *extension = stringListItem (parser->currentExtensions, i);\n\n\t\t\tcolprintLineAppendColumnCString (line, parser->def->name);\n\t\t\tif ((type & LMAP_ALL) != LMAP_EXTENSION)\n\t\t\t\tcolprintLineAppendColumnCString (line, \"extension\");\n\t\t\tcolprintLineAppendColumnVString (line, extension);\n\t\t}\n\t}\n}\n\nextern void printLanguageMaps (const langType language, langmapType type,\n\t\t\t\t\t\t\t   bool withListHeader, bool machinable, FILE *fp)\n{\n\t/* DON'T SORT THE LIST\n\n\t   The order of listing should be equal to the order of matching\n\t   for the parser selection. */\n\n\tstruct colprintTable * table = NULL;\n\tif (type & LMAP_TABLE_OUTPUT)\n\t\ttable = mapColprintTableNew(type);\n\n\tif (language == LANG_AUTO)\n\t{\n\t\tfor (unsigned int i = 0  ;  i < LanguageCount  ;  ++i)\n\t\t{\n\t\t\tif (!isLanguageVisible (i))\n\t\t\t\tcontinue;\n\n\t\t\tif (type & LMAP_TABLE_OUTPUT)\n\t\t\t{\n\t\t\t\tconst parserObject* parser = LanguageTable + i;\n\n\t\t\t\tmapColprintAddLanguage (table, type, parser);\n\t\t\t}\n\t\t\telse\n\t\t\t\tprintMaps (i, type);\n\t\t}\n\t}\n\telse\n\t{\n\t\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\t\tif (type & LMAP_TABLE_OUTPUT)\n\t\t{\n\t\t\tconst parserObject* parser = LanguageTable + language;\n\n\t\t\tmapColprintAddLanguage (table, type, parser);\n\t\t}\n\t\telse\n\t\t\tprintMaps (language, type);\n\t}\n\n\n\tif (type & LMAP_TABLE_OUTPUT)\n\t{\n\t\tcolprintTablePrint (table, (language == LANG_AUTO)? 0: 1,\n\t\t\t\t\t\t\twithListHeader, machinable, fp);\n\t\tcolprintTableDelete (table);\n\t}\n}\n\nstatic struct colprintTable *aliasColprintTableNew (void)\n{\n\treturn colprintTableNew (\"L:LANGUAGE\", \"L:ALIAS\", NULL);\n}\n\nstatic void aliasColprintAddLanguage (struct colprintTable * table,\n\t\t\t\t\t\t\t\t\t  const parserObject* parser)\n{\n\tunsigned int count;\n\n\tif (parser->currentAliases && (0 < (count = stringListCount (parser->currentAliases))))\n\t{\n\t\tfor (unsigned int i = 0; i < count; i++)\n\t\t{\n\t\t\tstruct colprintLine * line = colprintTableGetNewLine (table);\n\t\t\tvString *alias = stringListItem (parser->currentAliases, i);\n\n\t\t\tcolprintLineAppendColumnCString (line, parser->def->name);\n\t\t\tcolprintLineAppendColumnVString (line, alias);\n\t\t}\n\t}\n}\n\nextern void printLanguageAliases (const langType language,\n\t\t\t\t\t\t\t\t  bool withListHeader, bool machinable, FILE *fp)\n{\n\t/* DON'T SORT THE LIST\n\n\t   The order of listing should be equal to the order of matching\n\t   for the parser selection. */\n\n\tstruct colprintTable * table = aliasColprintTableNew();\n\tconst parserObject* parser;\n\n\tif (language == LANG_AUTO)\n\t{\n\t\tfor (unsigned int i = 0; i < LanguageCount; ++i)\n\t\t{\n\t\t\tparser = LanguageTable + i;\n\t\t\tif (parser->def->invisible)\n\t\t\t\tcontinue;\n\n\t\t\taliasColprintAddLanguage (table, parser);\n\t\t}\n\t}\n\telse\n\t{\n\t\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\t\tparser = LanguageTable + language;\n\t\taliasColprintAddLanguage (table, parser);\n\t}\n\n\tcolprintTablePrint (table, (language == LANG_AUTO)? 0: 1,\n\t\t\t\t\t\twithListHeader, machinable, fp);\n\tcolprintTableDelete (table);\n}\n\nstatic void printLanguage (const langType language, parserDefinition** ltable)\n{\n\tconst parserDefinition* lang;\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tlang = ltable [language];\n\n\tif (lang->invisible)\n\t\treturn;\n\n\tprintf (\"%s%s\\n\", lang->name, isLanguageEnabled (lang->id) ? \"\" : \" [disabled]\");\n}\n\nextern void printLanguageList (enum parserCategory category)\n{\n\tunsigned int i;\n\tunsigned int n;\n\tparserDefinition **ltable;\n\n\tltable = xMalloc (LanguageCount, parserDefinition*);\n\tfor (i = 0, n = 0 ; i < LanguageCount ; ++i)\n\t{\n\t\tparserObject *pobj = LanguageTable + i;\n\t\tif (category != PARSER_CATEGORY_NONE)\n\t\t{\n\t\t\tif (getCategoryForParserFunc(pobj->parserDefFunc) != category)\n\t\t\t\tcontinue;\n\t\t}\n\t\tltable[n] = pobj->def;\n\t\t++n;\n\t}\n\tqsort (ltable, n, sizeof (parserDefinition*), compareParsersByName);\n\n\tfor (i = 0  ;  i < n  ;  ++i)\n\t\tprintLanguage (i, ltable);\n\n\teFree (ltable);\n}\n\nstatic void xtagDefinitionDestroy (xtagDefinition *xdef)\n{\n\teFree ((void *)xdef->name);\n\teFree ((void *)xdef->description);\n\teFree (xdef);\n}\n\nstatic void pre_xtag_def_flag_version_long (const char* const optflag,\n\t\t\t\t\t\t\t\t\t\t\tconst char* const param, void* data)\n{\n\txtagDefinition *xdef = data;\n\n\tif (!isdigit((unsigned char)*param) || !strToUInt (param, 10, &xdef->version))\n\t\terror (FATAL, \"Failed to parse the version number for extra \\\"%s\\\": %s\",\n\t\t\t   xdef->name, param);\n}\n\nstatic flagDefinition PreXtagDefFlagDef [] = {\n\t{ '\\0', \"version\",  NULL, pre_xtag_def_flag_version_long,\n\t  \"VERSION\", \"in which version of the parser this extra is added\"},\n};\n\nstatic bool processLangDefineExtra (const langType language,\n\t\t\t\t\t\t\t\t\tconst char *const option,\n\t\t\t\t\t\t\t\t\tconst char *const parameter)\n{\n\txtagDefinition *xdef;\n\tconst char * p = parameter;\n\tconst char *name_end;\n\tconst char *desc;\n\tconst char *flags;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tAssert (p);\n\n\tif (p[0] == '\\0')\n\t\terror (FATAL, \"no extra definition specified in \\\"--%s\\\" option\", option);\n\n\tname_end = strchr (p, ',');\n\tif (!name_end)\n\t\terror (FATAL, \"no extra description specified in \\\"--%s\\\" option\", option);\n\telse if (name_end == p)\n\t\terror (FATAL, \"the extra name in \\\"--%s\\\" option is empty\", option);\n\n\tfor (; p < name_end; p++)\n\t{\n\t\tif (!isalnum ((unsigned char) *p))\n\t\t\terror (FATAL, \"unacceptable char as part of extra name in \\\"--%s\\\" option: '%c'\",\n\t\t\t\t   option, *p);\n\t}\n\n\tp++;\n\tif (p [0] == '\\0' || p [0] == LONG_FLAGS_OPEN)\n\t\terror (FATAL, \"extra description in \\\"--%s\\\" option is empty\", option);\n\n\tdesc = extractDescriptionAndFlags (p, &flags);\n\n\txdef = xCalloc (1, xtagDefinition);\n\txdef->enabled = false;\n\txdef->letter = NUL_XTAG_LETTER;\n\txdef->name = eStrndup (parameter, name_end - parameter);\n\txdef->description = desc;\n\txdef->isEnabled = NULL;\n\tDEFAULT_TRASH_BOX(xdef, xtagDefinitionDestroy);\n\n\tflagsEval (flags, PreXtagDefFlagDef, ARRAY_SIZE (PreXtagDefFlagDef), xdef);\n\n\tdefineXtag (xdef, language);\n\n\treturn true;\n}\n\nextern bool processExtradefOption (const char *const option, const char *const parameter)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"_\" \"extradef-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\treturn processLangDefineExtra (language, option, parameter);\n}\n\nstatic void fieldDefinitionDestroy (fieldDefinition *fdef)\n{\n\teFree ((void *)fdef->description);\n\teFree ((void *)fdef->name);\n\teFree (fdef);\n}\n\nstatic void field_def_flag_datatype_long (const char *const optflag CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\t  const char* const param,\n\t\t\t\t\t\t\t\t\t\t  void *data)\n{\n\tfieldDefinition *fdef = data;\n\n\tif (*param == '\\0')\n\t\terror (FATAL, \"no datatype given for field: \\\"%s\\\"\", fdef->name);\n\n\tfdef->dataType = FIELDTYPE_SCRIPTABLE;\n\tif (strcmp (param, \"int\") == 0)\n\t\tfdef->dataType |= FIELDTYPE_INTEGER;\n\telse if (strcmp (param, \"str\") == 0)\n\t\tfdef->dataType |= FIELDTYPE_STRING;\n\telse if (strcmp (param, \"bool\") == 0)\n\t\tfdef->dataType |= FIELDTYPE_BOOL;\n\telse if (strcmp (param, \"str+bool\") == 0)\n\t\tfdef->dataType |= FIELDTYPE_STRING|FIELDTYPE_BOOL;\n\telse\n\t\terror (FATAL, \"unknown datatype for field \\\"%s\\\": \\\"%s\\\"\", fdef->name, param);\n}\n\nstatic void field_def_flag_version_long (const char *const optflag CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\t const char* const param,\n\t\t\t\t\t\t\t\t\t\t void *data)\n{\n\tfieldDefinition *fdef = data;\n\n\tif (!isdigit((unsigned char)*param) || !strToUInt (param, 10, &fdef->version))\n\t\terror (FATAL, \"Failed to parse the version number for field \\\"%s\\\": %s\",\n\t\t\t   fdef->name, param);\n}\n\nstatic flagDefinition FieldDefFlagDef [] = {\n\t{ '\\0', \"datatype\", NULL, field_def_flag_datatype_long,\n\t  \"TYPE\", \"acceptable datatype of the field (str|bool|int|str+bool)\" },\n\t{ '\\0', \"version\",  NULL, field_def_flag_version_long,\n\t  \"VERSION\", \"in which version of the parser this field is added\"},\n};\n\nstatic bool processLangDefineField (const langType language,\n\t\t\t\t\t\t\t\t\tconst char *const option,\n\t\t\t\t\t\t\t\t\tconst char *const parameter)\n{\n\tfieldDefinition *fdef;\n\tconst char * p = parameter;\n\tconst char *name_end;\n\tconst char *desc;\n\tconst char *flags;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tAssert (p);\n\n\tif (p[0] == '\\0')\n\t\terror (FATAL, \"no field definition specified in \\\"--%s\\\" option\", option);\n\n\tname_end = strchr (p, ',');\n\tif (!name_end)\n\t\terror (FATAL, \"no field description specified in \\\"--%s\\\" option\", option);\n\telse if (name_end == p)\n\t\terror (FATAL, \"the field name in \\\"--%s\\\" option is empty\", option);\n\n\tfor (; p < name_end; p++)\n\t{\n\t\tif (!isalpha ((unsigned char) *p))\n\t\t\terror (FATAL, \"unacceptable char as part of field name in \\\"--%s\\\" option: '%c'\",\n\t\t\t\t   option, *p);\n\t}\n\n\tp++;\n\tif (p [0] == '\\0' || p [0] == LONG_FLAGS_OPEN)\n\t\terror (FATAL, \"field description in \\\"--%s\\\" option is empty\", option);\n\n\tdesc = extractDescriptionAndFlags (p, &flags);\n\n\tfdef = xCalloc (1, fieldDefinition);\n\tfdef->enabled = false;\n\tfdef->letter = NUL_FIELD_LETTER;\n\tfdef->name = eStrndup(parameter, name_end - parameter);\n\tfdef->description = desc;\n\n\tfdef->dataType = 0;\n\tflagsEval (flags, FieldDefFlagDef, ARRAY_SIZE (FieldDefFlagDef), fdef);\n\tif (!fdef->dataType)\n\t\tfdef->dataType = FIELDTYPE_STRING;\n\n\tfdef->isValueAvailable = (fdef->dataType & FIELDTYPE_SCRIPTABLE)\n\t\t? isValueAvailableGeneric\n\t\t: NULL;\n\tfdef->getValueObject = (fdef->dataType & FIELDTYPE_SCRIPTABLE)\n\t\t? getFieldValueGeneric\n\t\t: NULL;\n\tfdef->getterValueType = NULL;\n\tfdef->setValueObject = (fdef->dataType & FIELDTYPE_SCRIPTABLE)\n\t\t? setFieldValueGeneric\n\t\t: NULL;\n\tfdef->setterValueType = NULL;\n\n\tfdef->checkValueForSetter = NULL;\n\tfdef->ftype = FIELD_UNKNOWN;\n\tDEFAULT_TRASH_BOX(fdef, fieldDefinitionDestroy);\n\n\tdefineField (fdef, language);\n\n\treturn true;\n}\n\nextern bool processFielddefOption (const char *const option, const char *const parameter)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"_fielddef-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\treturn processLangDefineField (language, option, parameter);\n}\n\n/*\n*   File parsing\n*/\n\nstatic rescanReason createTagsForFile (const langType language,\n\t\t\t\t\t   const unsigned int passCount)\n{\n\tparserDefinition *const lang = LanguageTable [language].def;\n\trescanReason rescan = RESCAN_NONE;\n\n\tresetInputFile (language, passCount > 1 && !isAreaStacked ());\n\n\tAssert (lang->parser || lang->parser2);\n\n\tnotifyInputStart ();\n\n\tif (lang->parser != NULL)\n\t\tlang->parser ();\n\telse if (lang->parser2 != NULL)\n\t\trescan = lang->parser2 (passCount);\n\n\tnotifyInputEnd ();\n\n\treturn rescan;\n}\n\nextern void notifyLanguageRegexInputStart (langType language)\n{\n\tparserObject *pobj = LanguageTable + language;\n\n\tnotifyRegexInputStart(pobj->lregexControlBlock);\n}\n\nextern void notifyLanguageRegexInputEnd (langType language)\n{\n\tparserObject *pobj = LanguageTable + language;\n\n\tnotifyRegexInputEnd(pobj->lregexControlBlock);\n}\n\nstatic unsigned int parserCorkFlags (parserDefinition *parser)\n{\n\tsubparser *tmp;\n\tunsigned int r = 0;\n\n\tr |= parser->useCork;\n\n\tif (doesLanguageExpectCorkInRegex (parser->id)\n\t\t|| parser->requestAutomaticFQTag)\n\t\tr |= CORK_QUEUE;\n\n\tpushLanguage (parser->id);\n\tforeachSubparser(tmp, true)\n\t{\n\t\tlangType t = getSubparserLanguage (tmp);\n\t\tr |= parserCorkFlags (LanguageTable[t].def);\n\t}\n\tpopLanguage ();\n\treturn r;\n}\n\nstatic void setupLanguageSubparsersInUse (const langType language)\n{\n\tsubparser *tmp;\n\n\tsetupSubparsersInUse ((LanguageTable + language)->slaveControlBlock);\n\tforeachSubparser(tmp, true)\n\t{\n\t\tlangType t = getSubparserLanguage (tmp);\n\t\tenterSubparser (tmp);\n\t\tsetupLanguageSubparsersInUse(t);\n\t\tleaveSubparser ();\n\t}\n}\n\nstatic subparser* teardownLanguageSubparsersInUse (const langType language)\n{\n\tsubparser *tmp;\n\n\tforeachSubparser(tmp, true)\n\t{\n\t\tlangType t = getSubparserLanguage (tmp);\n\t\tenterSubparser (tmp);\n\t\tteardownLanguageSubparsersInUse(t);\n\t\tleaveSubparser ();\n\t}\n\treturn teardownSubparsersInUse ((LanguageTable + language)->slaveControlBlock);\n}\n\nstatic void\tinitializeParserStats (parserObject *parser)\n{\n\tif (Option.printTotals > 1 && parser->used == 0 && parser->def->initStats)\n\t\tparser->def->initStats (parser->def->id);\n\tparser->used = 1;\n}\n\nextern void printParserStatisticsIfUsed (langType language)\n{\n\tparserObject *parser = &(LanguageTable [language]);\n\n\tif (parser->used)\n\t{\n\t\tif (parser->def->printStats)\n\t\t{\n\t\t\tfprintf(stderr, \"\\nSTATISTICS of %s\\n\", getLanguageName (language));\n\t\t\tfputs(\"==============================================\\n\", stderr);\n\t\t\tparser->def->printStats (language);\n\t\t}\n\t\tprintLanguageMultitableStatistics (language);\n\t}\n}\n\nstatic bool createTagsWithFallback1 (const langType language,\n\t\t\t\t\t\t\t\t\t langType *exclusive_subparser)\n{\n\tbool tagFileResized = false;\n\tunsigned long numTags;\n\tMIOPos tagfpos;\n\tint lastPromise = getLastPromise ();\n\tunsigned int passCount = 0;\n\trescanReason whyRescan;\n\tparserObject *parser;\n\tunsigned int corkFlags;\n\tbool useCork = false;\n\n\tinitializeParser (language);\n\tparser = &(LanguageTable [language]);\n\n\tsetupLanguageSubparsersInUse (language);\n\n\tcorkFlags = parserCorkFlags (parser->def);\n\tuseCork = corkFlags & CORK_QUEUE;\n\tif (useCork)\n\t\tcorkTagFile(corkFlags);\n\n\tif (isXtagEnabled (XTAG_PSEUDO_TAGS))\n\t\taddParserPseudoTags (language);\n\tinitializeParserStats (parser);\n\tnumTags = numTagsAdded ();\n\ttagFilePosition (&tagfpos);\n\n\tanonResetMaybe (parser);\n\tparser->justRunForSchedulingBase = 0;\n\n\twhile ( ( whyRescan =\n\t\t  createTagsForFile (language, ++passCount) )\n\t\t!= RESCAN_NONE)\n\t{\n\t\tif (useCork)\n\t\t{\n\t\t\tuncorkTagFile();\n\t\t\tcorkTagFile(corkFlags);\n\t\t}\n\n\n\t\tif (whyRescan == RESCAN_FAILED)\n\t\t{\n\t\t\t/*  Restore prior state of tag file.\n\t\t\t*/\n\t\t\tsetTagFilePosition (&tagfpos, true);\n\t\t\tsetNumTagsAdded (numTags);\n\t\t\twriterRescanFailed (numTags);\n\t\t\ttagFileResized = true;\n\t\t\tbreakPromisesAfter(lastPromise);\n\t\t}\n\t\telse if (whyRescan == RESCAN_APPEND)\n\t\t{\n\t\t\ttagFilePosition (&tagfpos);\n\t\t\tnumTags = numTagsAdded ();\n\t\t\tlastPromise = getLastPromise ();\n\t\t}\n\t}\n\n\tif (!parser->justRunForSchedulingBase\n\t\t/* Force applying regex patterns */\n\t\t&& hasLanguageAnyRegexPatterns (language))\n\t\twhile (readLineFromInputFile () != NULL)\n\t\t\t; /* Do nothing */\n\n\tif (useCork)\n\t\tuncorkTagFile();\n\n\t{\n\t\tsubparser *s = teardownLanguageSubparsersInUse (language);\n\t\tif (exclusive_subparser && s)\n\t\t\t*exclusive_subparser = getSubparserLanguage (s);\n\t}\n\n\treturn tagFileResized;\n}\n\nextern bool runParserInArea (const langType language,\n\t\t\t\t\t\t\t unsigned long startLine, long startCharOffset,\n\t\t\t\t\t\t\t unsigned long endLine, long endCharOffset,\n\t\t\t\t\t\t\t unsigned long sourceLineOffset,\n\t\t\t\t\t\t\t int promise)\n{\n\tbool tagFileResized;\n\n\tverbose (\"runParserInArea: %s; \"\n\t\t\t \"file: %s, \"\n\t\t\t \"start(line: %lu, offset: %ld, srcline: %lu)\"\n\t\t\t \" - \"\n\t\t\t \"end(line: %lu, offset: %ld)\\n\",\n\t\t\t getLanguageName (language),\n\t\t\t getInputFileName (),\n\t\t\t startLine, startCharOffset, sourceLineOffset,\n\t\t\t endLine, endCharOffset);\n\n\tpushArea (doesParserRequireMemoryStream (language),\n\t\t\t  startLine, startCharOffset,\n\t\t\t  endLine, endCharOffset,\n\t\t\t  sourceLineOffset,\n\t\t\t  promise);\n\ttagFileResized = createTagsWithFallback1 (language, NULL);\n\tpopArea  ();\n\treturn tagFileResized;\n\n}\n\nstatic bool createTagsWithFallback (\n\tconst char *const fileName, const langType language,\n\tMIO *mio, time_t mtime, bool *failureInOpenning)\n{\n\tlangType exclusive_subparser = LANG_IGNORE;\n\tbool tagFileResized = false;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\tif (!openInputFile (fileName, language, mio, mtime))\n\t{\n\t\t*failureInOpenning = true;\n\t\treturn false;\n\t}\n\t*failureInOpenning = false;\n\n\ttagFileResized = createTagsWithFallback1 (language,\n\t\t\t\t\t\t\t\t\t\t\t  &exclusive_subparser);\n\ttagFileResized = forcePromises()? true: tagFileResized;\n\n\tpushLanguage ((exclusive_subparser == LANG_IGNORE)\n\t\t\t\t  ? language\n\t\t\t\t  : exclusive_subparser);\n\tmakeFileTag (fileName);\n\tpopLanguage ();\n\tcloseInputFile ();\n\n\treturn tagFileResized;\n}\n\nstatic void printGuessedParser (const char* const fileName, langType language)\n{\n\tconst char *parserName;\n\n\tif (language == LANG_IGNORE)\n\t{\n\t\tOption.printLanguage = ((int)true) + 1;\n\t\tparserName = RSV_NONE;\n\t}\n\telse\n\t{\n\t\tparserName = getLanguageName (language);\n\t}\n\n\tprintf(\"%s: %s\\n\", fileName, parserName);\n}\n\n#ifdef HAVE_ICONV\nstatic char **EncodingMap;\nstatic unsigned int EncodingMapMax;\n\nstatic void addLanguageEncoding (const langType language,\n\t\t\t\t\t\t\t\t\tconst char *const encoding)\n{\n\tif (language > EncodingMapMax || EncodingMapMax == 0)\n\t{\n\t\tint i;\n\t\tint istart = (EncodingMapMax == 0)? 0: EncodingMapMax + 1;\n\t\tEncodingMap = xRealloc (EncodingMap, (language + 1), char*);\n\t\tfor (i = istart;  i <= language  ;  ++i)\n\t\t{\n\t\t\tEncodingMap [i] = NULL;\n\t\t}\n\t\tEncodingMapMax = language;\n\t}\n\tif (EncodingMap [language])\n\t\teFree (EncodingMap [language]);\n\tEncodingMap [language] = eStrdup(encoding);\n\tif (!Option.outputEncoding)\n\t\tOption.outputEncoding = eStrdup(\"UTF-8\");\n}\n\nextern bool processLanguageEncodingOption (const char *const option, const char *const parameter)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"input-encoding-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\taddLanguageEncoding (language, parameter);\n\treturn true;\n}\n\nextern void freeEncodingResources (void)\n{\n\tif (EncodingMap)\n\t{\n\t\tunsigned int i;\n\t\tfor (i = 0  ;  i <= EncodingMapMax  ; ++i)\n\t\t{\n\t\t\tif (EncodingMap [i])\n\t\t\t\teFree (EncodingMap [i]);\n\t\t}\n\t\teFree (EncodingMap);\n\t}\n\tif (Option.inputEncoding)\n\t\teFree (Option.inputEncoding);\n\tif (Option.outputEncoding)\n\t\teFree (Option.outputEncoding);\n}\n\nextern const char *getLanguageEncoding (const langType language)\n{\n\tif (EncodingMap && language <= EncodingMapMax && EncodingMap [language])\n\t\treturn EncodingMap[language];\n\telse\n\t\treturn Option.inputEncoding;\n}\n#endif\n\nstatic void addParserPseudoTags (langType language)\n{\n\tparserObject *parser = LanguageTable + language;\n\tif (!parser->pseudoTagPrinted)\n\t{\n\t\tfor (int i = 0; i < PTAG_COUNT; i++)\n\t\t{\n\t\t\tif (isPtagParserSpecific (i))\n\t\t\t\tmakePtagIfEnabled (i, language, parser);\n\t\t}\n\t\tparser->pseudoTagPrinted = 1;\n\t}\n}\n\nextern bool doesParserRequireMemoryStream (const langType language)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparserDefinition *const lang = LanguageTable [language].def;\n\tunsigned int i;\n\n\tif (lang->tagXpathTableCount > 0\n\t\t|| lang->useMemoryStreamInput)\n\t{\n\t\tverbose (\"%s requires a memory stream for input\\n\", lang->name);\n\t\treturn true;\n\t}\n\n\tfor (i = 0; i < lang->dependencyCount; i++)\n\t{\n\t\tparserDependency *d = lang->dependencies + i;\n\t\tif (d->type == DEPTYPE_SUBPARSER &&\n\t\t\t((subparser *)(d->data))->direction & SUBPARSER_SUB_RUNS_BASE)\n\t\t{\n\t\t\tlangType baseParser;\n\t\t\tbaseParser = getNamedLanguage (d->upperParser, 0);\n\t\t\tif (doesParserRequireMemoryStream(baseParser))\n\t\t\t{\n\t\t\t\tverbose (\"%s/%s requires a memory stream for input\\n\", lang->name,\n\t\t\t\t\t\t LanguageTable[baseParser].def->name);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nextern bool parseFile (const char *const fileName)\n{\n\tTRACE_ENTER_TEXT(\"Parsing file %s\",fileName);\n\tbool bRet = parseFileWithMio (fileName, NULL, NULL);\n\tTRACE_LEAVE();\n\treturn bRet;\n}\n\nstatic bool parseMio (const char *const fileName, langType language, MIO* mio, time_t mtime, bool useSourceFileTagPath,\n\t\t\t\t\t  void *clientData)\n{\n\tbool tagFileResized = false;\n\tbool failureInOpenning = false;\n\n\tsetupWriter (clientData);\n\n\tsetupAnon ();\n\n\tinitParserTrashBox ();\n\n\ttagFileResized = createTagsWithFallback (fileName, language, mio, mtime, &failureInOpenning);\n\n\tfiniParserTrashBox ();\n\n\tteardownAnon ();\n\n\tif (useSourceFileTagPath && (!failureInOpenning))\n\t\treturn teardownWriter (getSourceFileTagPath())? true: tagFileResized;\n\telse\n\t\treturn teardownWriter(fileName);\n}\n\nextern bool parseFileWithMio (const char *const fileName, MIO *mio,\n\t\t\t\t\t\t\t  void *clientData)\n{\n\tbool tagFileResized = false;\n\tlangType language;\n\tstruct GetLanguageRequest req = {\n\t\t.type = mio? GLR_REUSE: GLR_OPEN,\n\t\t.fileName = fileName,\n\t\t.mio = mio,\n\t};\n\tmemset (&req.mtime, 0, sizeof (req.mtime));\n\n\tlanguage = getFileLanguageForRequest (&req);\n\tAssert (language != LANG_AUTO);\n\n\tif (Option.printLanguage)\n\t{\n\t\tprintGuessedParser (fileName, language);\n\t\treturn tagFileResized;\n\t}\n\n\tif (language == LANG_IGNORE)\n\t\tverbose (\"ignoring %s (unknown language/language disabled)\\n\",\n\t\t\t fileName);\n\telse\n\t{\n\t\tAssert(isLanguageEnabled (language));\n\n\t\tif (Option.filter && ! Option.interactive)\n\t\t\topenTagFile ();\n\n#ifdef HAVE_ICONV\n\t\t/* TODO: checkUTF8BOM can be used to update the encodings. */\n\t\topenConverter (getLanguageEncoding (language), Option.outputEncoding);\n#endif\n\t\ttagFileResized = parseMio (fileName, language, req.mio, req.mtime, true, clientData);\n\t\tif (Option.filter && ! Option.interactive)\n\t\t\tcloseTagFile (tagFileResized);\n\t\taddTotals (1, 0L, 0L);\n\n#ifdef HAVE_ICONV\n\t\tcloseConverter ();\n#endif\n\t}\n\n\tif (req.type == GLR_OPEN && req.mio)\n\t\tmio_unref (req.mio);\n\n\treturn tagFileResized;\n}\n\nextern bool parseRawBuffer(const char *fileName, unsigned char *buffer,\n\t\t\t size_t bufferSize, const langType language, void *clientData)\n{\n\tMIO *mio = NULL;\n\tbool r;\n\n\tif (buffer)\n\t\tmio = mio_new_memory (buffer, bufferSize, NULL, NULL);\n\n\tr = parseMio (fileName, language, mio, (time_t)0, false, clientData);\n\n\tif (buffer)\n\t\tmio_unref (mio);\n\n\treturn r;\n}\n\nstatic void matchLanguageMultilineRegexCommon (const langType language,\n\t\t\t\t\t\t\t\t\t\t\t   bool (* func) (struct lregexControlBlock *, const vString* const),\n\t\t\t\t\t\t\t\t\t\t\t   const vString* const allLines)\n{\n\tsubparser *tmp;\n\n\tfunc ((LanguageTable + language)->lregexControlBlock, allLines);\n\tforeachSubparser(tmp, true)\n\t{\n\t\tlangType t = getSubparserLanguage (tmp);\n\t\tenterSubparser (tmp);\n\t\tmatchLanguageMultilineRegexCommon (t, func, allLines);\n\t\tleaveSubparser ();\n\t}\n}\n\nextern void matchLanguageMultilineRegex (const langType language,\n\t\t\t\t\t\t\t\t\t\t const vString* const allLines)\n{\n\tmatchLanguageMultilineRegexCommon(language, matchMultilineRegex, allLines);\n}\n\nextern void matchLanguageMultitableRegex (const langType language,\n\t\t\t\t\t\t\t\t\t\t  const vString* const allLines)\n{\n\tmatchLanguageMultilineRegexCommon(language, matchMultitableRegex, allLines);\n}\n\nextern void processLanguageMultitableExtendingOption (langType language, const char *const parameter)\n{\n\tconst char* src;\n\tchar* dist;\n\tconst char *tmp;\n\n\ttmp = strchr(parameter, '+');\n\n\tif (!tmp)\n\t\terror (FATAL, \"no separator(+) found: %s\", parameter);\n\n\tif (tmp == parameter)\n\t\terror (FATAL, \"the name of source table is empty in table extending: %s\", parameter);\n\n\tsrc = tmp + 1;\n\tif (!*src)\n\t\terror (FATAL, \"the name of dist table is empty in table extending: %s\", parameter);\n\n\tdist = eStrndup(parameter, tmp  - parameter);\n\textendRegexTable(((LanguageTable + language)->lregexControlBlock), src, dist);\n\teFree (dist);\n}\n\nstatic bool lregexQueryParserAndSubparsers (const langType language, bool (* predicate) (struct lregexControlBlock *))\n{\n\tbool r;\n\tsubparser *tmp;\n\n\tr = predicate ((LanguageTable + language)->lregexControlBlock);\n\tif (!r)\n\t{\n\t\tforeachSubparser(tmp, true)\n\t\t{\n\t\t\tlangType t = getSubparserLanguage (tmp);\n\t\t\tenterSubparser (tmp);\n\t\t\tr = lregexQueryParserAndSubparsers (t, predicate);\n\t\t\tleaveSubparser ();\n\n\t\t\tif (r)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn r;\n}\n\nextern bool hasLanguagePostRunRegexPatterns (const langType language)\n{\n\treturn lregexQueryParserAndSubparsers (language, regexIsPostRun);\n}\n\nextern bool hasLanguageMultilineRegexPatterns (const langType language)\n{\n\treturn lregexQueryParserAndSubparsers (language, regexNeedsMultilineBuffer);\n}\n\nstatic bool hasLanguageAnyRegexPatterns (const langType language)\n{\n\treturn lregexQueryParserAndSubparsers (language, lregexControlBlockHasAny);\n}\n\nextern void addLanguageCallbackRegex (const langType language, const char *const regex, const char *const flags,\n\t\t\t\t\t\t\t\t\t  const regexCallback callback, bool *disabled, void *userData)\n{\n\taddCallbackRegex ((LanguageTable +language)->lregexControlBlock, regex, flags, callback, disabled, userData);\n}\n\nextern bool doesLanguageExpectCorkInRegex (const langType language)\n{\n\tbool hasScopeAction;\n\n\tpushLanguage (language);\n\thasScopeAction = lregexQueryParserAndSubparsers (language, doesExpectCorkInRegex);\n\tpopLanguage ();\n\n\treturn hasScopeAction;\n}\n\nextern void matchLanguageRegex (const langType language, const vString* const line, bool postrun)\n{\n\tsubparser *tmp;\n\n\tmatchRegex ((LanguageTable + language)->lregexControlBlock, line, postrun);\n\tforeachSubparser(tmp, true)\n\t{\n\t\tlangType t = getSubparserLanguage (tmp);\n\t\tenterSubparser (tmp);\n\t\tmatchLanguageRegex (t, line, postrun);\n\t\tleaveSubparser ();\n\t}\n}\n\nextern bool processLanguageRegexOption (langType language,\n\t\t\t\t\t\t\t\t\t\tenum regexParserType regptype,\n\t\t\t\t\t\t\t\t\t\tconst char *const parameter)\n{\n\tprocessTagRegexOption ((LanguageTable +language)->lregexControlBlock,\n\t\t\t\t\t\t   regptype, parameter);\n\n\treturn true;\n}\n\nextern bool processTabledefOption (const char *const option, const char *const parameter)\n{\n\tlangType language;\n\n\tlanguage = getLanguageComponentInOption (option, \"_tabledef-\");\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\tif (parameter == NULL || parameter[0] == '\\0')\n\t\terror (FATAL, \"A parameter is needed after \\\"%s\\\" option\", option);\n\n\taddRegexTable((LanguageTable +language)->lregexControlBlock, parameter);\n\treturn true;\n}\n\nextern void useRegexMethod (const langType language)\n{\n\tparserDefinition* lang;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tlang = LanguageTable [language].def;\n\tlang->method |= METHOD_REGEX;\n}\n\nstatic void useXpathMethod (const langType language)\n{\n\tparserDefinition* lang;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tlang = LanguageTable [language].def;\n\tlang->method |= METHOD_XPATH;\n}\n\nstatic void installTagRegexTable (const langType language)\n{\n\tparserObject* parser;\n\tparserDefinition* lang;\n\tunsigned int i;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\tlang = parser->def;\n\n\n\tif (lang->tagRegexTable != NULL)\n\t{\n\t\t/* ctags_cli_main() calls initRegexOptscript ().\n\t\t * However, mini-geany deasn't call ctags_cli_main().\n\t\t * So we call initRegexOptscript () here.\n\t\t */\n\t\tinitRegexOptscript ();\n\n\t\tfor (i = 0; i < lang->tagRegexCount; ++i)\n\t\t{\n\t\t\tif (lang->tagRegexTable [i].mline)\n\t\t\t\taddTagMultiLineRegex (parser->lregexControlBlock,\n\t\t\t\t\t\t\t\t\t  lang->tagRegexTable [i].regex,\n\t\t\t\t\t\t\t\t\t  lang->tagRegexTable [i].name,\n\t\t\t\t\t\t\t\t\t  lang->tagRegexTable [i].kinds,\n\t\t\t\t\t\t\t\t\t  lang->tagRegexTable [i].flags,\n\t\t\t\t\t\t\t\t\t  (lang->tagRegexTable [i].disabled));\n\t\t\telse\n\t\t\t\taddTagRegex (parser->lregexControlBlock,\n\t\t\t\t\t\t\t lang->tagRegexTable [i].regex,\n\t\t\t\t\t\t\t lang->tagRegexTable [i].name,\n\t\t\t\t\t\t\t lang->tagRegexTable [i].kinds,\n\t\t\t\t\t\t\t lang->tagRegexTable [i].flags,\n\t\t\t\t\t\t\t (lang->tagRegexTable [i].disabled));\n\t\t}\n\t}\n}\n\nstatic void installKeywordTable (const langType language)\n{\n\tparserDefinition* lang;\n\tunsigned int i;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tlang = LanguageTable [language].def;\n\n\tif (lang->keywordTable != NULL)\n\t{\n\t\tfor (i = 0; i < lang->keywordCount; ++i)\n\t\t\taddKeyword (lang->keywordTable [i].name,\n\t\t\t\t\tlanguage,\n\t\t\t\t\tlang->keywordTable [i].id);\n\t}\n}\n\nstatic void installTagXpathTable (const langType language)\n{\n\tparserDefinition* lang;\n\tunsigned int i, j;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tlang = LanguageTable [language].def;\n\n\tif (lang->tagXpathTableTable != NULL)\n\t{\n\t\tfor (i = 0; i < lang->tagXpathTableCount; ++i)\n\t\t\tfor (j = 0; j < lang->tagXpathTableTable[i].count; ++j)\n\t\t\t\taddTagXpath (language, lang->tagXpathTableTable[i].table + j);\n\t\tuseXpathMethod (language);\n\t}\n}\n\nstatic void uninstallTagXpathTable (const langType language)\n{\n\tparserDefinition* lang;\n\tunsigned int i, j;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tlang = LanguageTable [language].def;\n\n\tif (lang->tagXpathTableTable != NULL)\n\t{\n\t\tfor (i = 0; i < lang->tagXpathTableCount; ++i)\n\t\t\tfor (j = 0; j < lang->tagXpathTableTable[i].count; ++j)\n\t\t\t\tremoveTagXpath (language, lang->tagXpathTableTable[i].table + j);\n\t}\n}\n\nconst tagXpathTableTable *getXpathTableTable (const langType language, unsigned int nth)\n{\n\tparserDefinition* lang;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tlang = LanguageTable [language].def;\n\n\tAssert (nth < lang->tagXpathTableCount);\n\treturn lang->tagXpathTableTable + nth;\n}\n\nextern unsigned int getXpathFileSpecCount (const langType language)\n{\n\tparserDefinition* lang;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tlang = LanguageTable [language].def;\n\n\treturn lang->xpathFileSpecCount;\n}\n\nextern xpathFileSpec* getXpathFileSpec (const langType language, unsigned int nth)\n{\n\tparserDefinition* lang;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tlang = LanguageTable [language].def;\n\n\tAssert (nth < lang->xpathFileSpecCount);\n\treturn lang->xpathFileSpecs + nth;\n}\n\nextern bool makeKindSeparatorsPseudoTags (const langType language,\n\t\t\t\t\t\t const ptagDesc *pdesc)\n{\n\tparserObject* parser;\n\tparserDefinition* lang;\n\tstruct kindControlBlock *kcb;\n\tkindDefinition *kind;\n\tunsigned int kindCount;\n\tunsigned int i, j;\n\n\tbool r = false;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\tlang = parser->def;\n\tkcb = parser->kindControlBlock;\n\tkindCount = countKinds(kcb);\n\n\tif (kindCount == 0)\n\t\treturn r;\n\n\tfor (i = 0; i < kindCount; ++i)\n\t{\n\t\tkind = getKind (kcb, i);\n\t\tfor (j = 0; j < kind->separatorCount; ++j)\n\t\t{\n\t\t\tchar name[3] = {[1] = '\\0', [2] = '\\0'};\n\t\t\tconst kindDefinition *upperKind;\n\t\t\tconst scopeSeparator *sep;\n\n\t\t\tsep = kind->separators + j;\n\n\t\t\tif (sep->parentKindIndex == KIND_WILDCARD_INDEX)\n\t\t\t{\n\t\t\t\tname[0] = KIND_WILDCARD_LETTER;\n\t\t\t\tname[1] = kind->letter;\n\t\t\t}\n\t\t\telse if (sep->parentKindIndex == KIND_GHOST_INDEX)\n\t\t\t{\n\t\t\t\t/* This is root separator: no upper item is here. */\n\t\t\t\tname[0] = kind->letter;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tupperKind = getLanguageKind (language,\n\t\t\t\t\t\t\t\tsep->parentKindIndex);\n\t\t\t\tif (!upperKind)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tname[0] = upperKind->letter;\n\t\t\t\tname[1] = kind->letter;\n\t\t\t}\n\n\n\t\t\tr = writePseudoTag (pdesc, sep->separator? sep->separator: \"\",\n\t\t\t\t\t\tname, lang->name) || r;\n\t\t}\n\t}\n\n\treturn r;\n}\n\nstruct makeKindDescriptionPseudoTagData {\n\tconst char* langName;\n\tconst ptagDesc *pdesc;\n\tbool written;\n};\n\nstatic bool makeKindDescriptionPseudoTag (kindDefinition *kind,\n\t\t\t\t\t\t void *user_data)\n{\n\tstruct makeKindDescriptionPseudoTagData *data = user_data;\n\tvString *letter_and_name;\n\n\tletter_and_name = vStringNew ();\n\n\tvStringPut (letter_and_name, kind -> letter);\n\tvStringPut (letter_and_name, ',');\n\tvStringCatS (letter_and_name, kind -> name);\n\n\tdata->written |=  writePseudoTag (data->pdesc, vStringValue (letter_and_name),\n\t\t\t\t\t\t\t\t\t  kind->description? kind->description: kind->name,\n\t\t\t\t\t\t\t\t\t  data->langName);\n\n\tvStringDelete (letter_and_name);\n\n\treturn false;\n}\n\nstatic bool makeRoleDescriptionPseudoTag (kindDefinition *kind,\n\t\t\t\t\t\t\t\t\t\t  roleDefinition *role,\n\t\t\t\t\t\t\t\t\t\t  void *user_data)\n{\n\tstruct makeKindDescriptionPseudoTagData *data = user_data;\n\n\tvString *parser_and_kind_name = vStringNewInit (data->langName);\n\tvStringCatS (parser_and_kind_name, PSEUDO_TAG_SEPARATOR);\n\tvStringCatS (parser_and_kind_name, kind->name);\n\n\tdata->written |=  writePseudoTag (data->pdesc, role->name,\n\t\t\t\t\t\t\t\t\t  role->description? role->description: role->name,\n\t\t\t\t\t\t\t\t\t  vStringValue (parser_and_kind_name));\n\n\tvStringDelete (parser_and_kind_name);\n\n\treturn false;\n}\n\nextern bool makeKindDescriptionsPseudoTags (const langType language,\n\t\t\t\t\t\tconst ptagDesc *pdesc)\n{\n\tparserObject *parser;\n\tstruct kindControlBlock *kcb;\n\tparserDefinition* lang;\n\tkindDefinition *kind;\n\tunsigned int kindCount, i;\n\tstruct makeKindDescriptionPseudoTagData data;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\tkcb = parser->kindControlBlock;\n\tlang = parser->def;\n\n\tkindCount = countKinds(kcb);\n\n\tdata.langName = lang->name;\n\tdata.pdesc = pdesc;\n\tdata.written = false;\n\n\tfor (i = 0; i < kindCount; ++i)\n\t{\n\t\tif (!isLanguageKindEnabled (language, i))\n\t\t\tcontinue;\n\n\t\tkind = getKind (kcb, i);\n\t\tif (language == ctagsSelfTestLang\n\t\t\t&& (kind == NULL || kind->name == NULL))\n\t\t{\n\t\t\t/* The Self test parser may have broken kinds.\n\t\t\t * Let's skip it. */\n\t\t\tcontinue;\n\t\t}\n\t\tmakeKindDescriptionPseudoTag (kind, &data);\n\t}\n\n\treturn data.written;\n}\n\nstatic bool makeFieldDescriptionPseudoTag (const langType language,\n\t\t\t\t\t\t\t\t\t\t   fieldType f,\n\t\t\t\t\t\t\t\t\t\t   const ptagDesc *pdesc)\n{\n\tconst char *name = getFieldName (f);\n\n\tif (name == NULL || name [0] == '\\0')\n\t\treturn false;\n\n\treturn writePseudoTag (pdesc, name,\n\t\t\t\t\t\t   getFieldDescription (f),\n\t\t\t\t\t\t   language == LANG_IGNORE? NULL: getLanguageName (language));\n}\n\nextern bool makeFieldDescriptionsPseudoTags (const langType language,\n\t\t\t\t\t\t\t\t\t\t\t const ptagDesc *pdesc)\n{\n\tbool written = false;\n\tfor (unsigned int i = 0; i < countFields (); i++)\n\t{\n\t\tif (getFieldLanguage (i) == language\n\t\t\t&& isFieldEnabled (i))\n\t\t{\n\t\t\tif (makeFieldDescriptionPseudoTag (language, i, pdesc))\n\t\t\t\twritten = true;\n\t\t}\n\t}\n\treturn written;\n}\n\nstatic bool makeExtraDescriptionPseudoTag (const langType language,\n\t\t\t\t\t\t\t\t\t\t   xtagType x,\n\t\t\t\t\t\t\t\t\t\t   const ptagDesc *pdesc)\n{\n\tconst char *name = getXtagName (x);\n\n\tif (name == NULL || name [0] == '\\0')\n\t\treturn false;\n\n\treturn writePseudoTag (pdesc, name,\n\t\t\t\t\t\t   getXtagDescription (x),\n\t\t\t\t\t\t   language == LANG_IGNORE? NULL: getLanguageName (language));\n}\n\nextern bool makeExtraDescriptionsPseudoTags (const langType language,\n\t\t\t\t\t\t\t\t\t\t\t const ptagDesc *pdesc)\n{\n\tbool written = false;\n\tfor (unsigned int i = 0; i < countXtags (); i++)\n\t{\n\t\tif (getXtagLanguage (i) == language\n\t\t\t&& isXtagEnabled (i))\n\t\t{\n\t\t\tif (makeExtraDescriptionPseudoTag (language, i, pdesc))\n\t\t\t\twritten = true;\n\t\t}\n\t}\n\treturn written;\n}\n\nextern bool makeRoleDescriptionsPseudoTags (const langType language,\n\t\t\t\t\t\t\t\t\t\t\tconst ptagDesc *pdesc)\n{\n\tparserObject *parser;\n\tstruct kindControlBlock *kcb;\n\tparserDefinition* lang;\n\tkindDefinition *kind;\n\tstruct makeKindDescriptionPseudoTagData data;\n\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\tkcb = parser->kindControlBlock;\n\tlang = parser->def;\n\n\tunsigned int kindCount = countKinds(kcb);\n\n\tdata.langName = lang->name;\n\tdata.pdesc = pdesc;\n\tdata.written = false;\n\n\tfor (unsigned int i = 0; i < kindCount; ++i)\n\t{\n\t\tif (!isLanguageKindEnabled (language, i))\n\t\t\tcontinue;\n\n\t\tkind = getKind (kcb, i);\n\n\t\tunsigned int roleCount = countRoles (kcb, i);\n\t\tfor (unsigned int j = 0; j < roleCount; ++j)\n\t\t{\n\t\t\tif (isRoleEnabled (kcb, i, j))\n\t\t\t{\n\t\t\t\troleDefinition *role = getRole (kcb, i, j);\n\t\t\t\tmakeRoleDescriptionPseudoTag (kind, role, &data);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn data.written;\n}\n\nextern unsigned int getLanguageVersionCurrent (const langType language)\n{\n\tparserObject *parser;\n\tparserDefinition* lang;\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\tlang = parser->def;\n\treturn lang->versionCurrent;\n}\n\nextern unsigned int getLanguageVersionAge (const langType language)\n{\n\tparserObject *parser;\n\tparserDefinition* lang;\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\tparser = LanguageTable + language;\n\tlang = parser->def;\n\treturn lang->versionAge;\n}\n\n/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Anonymous name generator\n*/\nstatic ptrArray *parsersUsedInCurrentInput;\n\nstatic void setupAnon (void)\n{\n\tparsersUsedInCurrentInput = ptrArrayNew (NULL);\n}\n\nstatic void teardownAnon (void)\n{\n\tptrArrayDelete (parsersUsedInCurrentInput);\n}\n\nstatic void anonResetMaybe (parserObject *parser)\n{\n\tif (ptrArrayHas (parsersUsedInCurrentInput, parser))\n\t\treturn;\n\n\tparser -> anonymousIdentiferId = 0;\n\tptrArrayAdd (parsersUsedInCurrentInput, parser);\n}\n\nstatic unsigned int anonHash(const unsigned char *str)\n{\n\tunsigned int hash = 5381;\n\tint c;\n\n\twhile((c = *str++))\n\t\thash = ((hash << 5) + hash) + c; /* hash * 33 + c */\n\n\treturn hash ;\n}\n\nextern void anonHashString (const char *filename, char buf[9])\n{\n\tsprintf(buf, \"%08x\", anonHash((const unsigned char *)filename));\n}\n\nextern void anonConcatFull (vString *buffer, langType lang, int kind)\n{\n\tanonGenerateFull (buffer, NULL, lang, kind);\n}\n\nextern void anonGenerateFull (vString *buffer, const char *prefix, langType lang, int kind)\n{\n\tAssert(lang != LANG_IGNORE);\n\tparserObject* parser = LanguageTable + ((lang == LANG_AUTO)? getInputLanguage (): lang);\n\tparser -> anonymousIdentiferId ++;\n\n\tchar szNum[32];\n\tchar buf [9];\n\n\tif (prefix)\n\t\tvStringCopyS(buffer, prefix);\n\n\tanonHashString (getInputFileName(), buf);\n\tsprintf(szNum,\"%s%02x%02x\",buf,parser -> anonymousIdentiferId, kind);\n\tvStringCatS(buffer,szNum);\n}\n\nextern vString *anonGenerateNewFull (const char *prefix, langType lang, int kind)\n{\n\tvString *buffer = vStringNew ();\n\n\tanonGenerateFull (buffer, prefix, lang, kind);\n\treturn buffer;\n}\n\nextern bool applyLanguageParam (const langType language, const char *name, const char *args)\n{\n\tAssert (0 <= language  &&  language < (int) LanguageCount);\n\n\tinitializeParserOne (language);\n\treturn applyParam (LanguageTable [language].paramControlBlock, name, args);\n}\n\nextern subparser *getNextSubparser(subparser *last,\n\t\t\t\t\t\t\t\t   bool includingNoneCraftedParser)\n{\n\tlangType lang = getInputLanguage ();\n\tparserObject *parser = LanguageTable + lang;\n\tsubparser *r;\n\tlangType t;\n\n\tif (last == NULL)\n\t\tr = getFirstSubparser(parser->slaveControlBlock);\n\telse\n\t\tr = last->next;\n\n\tif (r == NULL)\n\t\treturn r;\n\n\tt = getSubparserLanguage(r);\n\tif (isLanguageEnabled (t) &&\n\t\t(includingNoneCraftedParser\n\t\t || ((((LanguageTable + t)->def->method) & METHOD_NOT_CRAFTED) == 0)))\n\t\treturn r;\n\telse\n\t\treturn getNextSubparser (r, includingNoneCraftedParser);\n}\n\nextern slaveParser *getNextSlaveParser(slaveParser *last)\n{\n\tlangType lang = getInputLanguage ();\n\tparserObject *parser = LanguageTable + lang;\n\tslaveParser *r;\n\n\tif (last == NULL)\n\t\tr = getFirstSlaveParser(parser->slaveControlBlock);\n\telse\n\t\tr = last->next;\n\n\treturn r;\n}\n\nextern void scheduleRunningBaseparser (int dependencyIndex)\n{\n\tlangType current = getInputLanguage ();\n\tparserObject *current_pobj = LanguageTable + current;\n\tparserDefinition *current_parser = current_pobj->def;\n\tparserDependency *dep = NULL;\n\n\tcurrent_pobj->justRunForSchedulingBase = 1;\n\n\tif (dependencyIndex == RUN_DEFAULT_SUBPARSERS)\n\t{\n\t\tfor (unsigned int i = 0; i < current_parser->dependencyCount; ++i)\n\t\t\tif (current_parser->dependencies[i].type == DEPTYPE_SUBPARSER)\n\t\t\t{\n\t\t\t\tdep = current_parser->dependencies + i;\n\t\t\t\tbreak;\n\t\t\t}\n\t}\n\telse\n\t\tdep = current_parser->dependencies + dependencyIndex;\n\n\tif (dep == NULL)\n\t\treturn;\n\n\tconst char *base_name = dep->upperParser;\n\tlangType base = getNamedLanguage (base_name, 0);\n\tparserObject *base_parser = LanguageTable + base;\n\n\tif (dependencyIndex == RUN_DEFAULT_SUBPARSERS)\n\t\tuseDefaultSubparsers(base_parser->slaveControlBlock);\n\telse\n\t\tuseSpecifiedSubparser (base_parser->slaveControlBlock,\n\t\t\t\t\t\t\t   dep->data);\n\n\tif (!isLanguageEnabled (base))\n\t{\n\t\tenableLanguage (base, true);\n\t\tbase_parser->dontEmit = true;\n\t\tverbose (\"force enable \\\"%s\\\" as base parser\\n\", base_parser->def->name);\n\t}\n\n\t{\n\t\tsubparser *tmp;\n\n\t\tverbose (\"scheduleRunningBaseparser %s with subparsers: \", base_name);\n\t\tpushLanguage (base);\n\t\tforeachSubparser(tmp, true)\n\t\t{\n\t\t\tlangType t = getSubparserLanguage (tmp);\n\t\t\tverbose (\"%s \", getLanguageName (t));\n\t\t}\n\t\tpopLanguage ();\n\t\tverbose (\"\\n\");\n\t}\n\n\n\tmakePromise(base_name, THIN_AREA_SPEC);\n}\n\nextern bool isParserMarkedNoEmission (void)\n{\n\tlangType lang = getInputLanguage();\n\tparserObject *parser = LanguageTable + lang;\n\n\treturn parser->dontEmit;\n}\n\n\nextern subparser* getSubparserRunningBaseparser (void)\n{\n\tlangType current = getInputLanguage ();\n\tparserObject *current_parser = LanguageTable + current;\n\tsubparser *s = getFirstSubparser (current_parser->slaveControlBlock);\n\n\tif (s && s->schedulingBaseparserExplicitly)\n\t\treturn s;\n\telse\n\t\treturn NULL;\n}\n\nextern void printLanguageSubparsers (const langType language,\n\t\t\t\t\t\t\t\t\t bool withListHeader, bool machinable, FILE *fp)\n{\n\tfor (int i = 0; i < (int) LanguageCount; i++)\n\t\tinitializeParserOne (i);\n\n\tstruct colprintTable * table = subparserColprintTableNew();\n\tparserObject *parser;\n\n\tif (language == LANG_AUTO)\n\t{\n\t\tfor (int i = 0; i < (int) LanguageCount; i++)\n\t\t{\n\t\t\tparser = LanguageTable + i;\n\t\t\tif (parser->def->invisible)\n\t\t\t\tcontinue;\n\n\t\t\tsubparserColprintAddSubparsers (table,\n\t\t\t\t\t\t\t\t\t\t\tparser->slaveControlBlock);\n\t\t}\n\t}\n\telse\n\t{\n\t\tparser = (LanguageTable + language);\n\t\tsubparserColprintAddSubparsers (table,\n\t\t\t\t\t\t\t\t\t\tparser->slaveControlBlock);\n\t}\n\n\tsubparserColprintTablePrint (table,\n\t\t\t\t\t\t\t\t withListHeader, machinable,\n\t\t\t\t\t\t\t\t fp);\n\tcolprintTableDelete (table);\n}\n\n#define defineSimplePrintFLagsFunction(target, flagDef) \\\n\textern void print##target##Flags (bool withListHeader, bool machinable, FILE *fp) \\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tstruct colprintTable * table =\tflagsColprintTableNew();\t\t\\\n\t\tflagsColprintAddDefinitions (table, flagDef, ARRAY_SIZE (flagDef)); \\\n\t\tflagsColprintTablePrint (table, withListHeader, machinable, fp); \\\n\t\tcolprintTableDelete(table);\t\t\t\t\t\t\t\t\t\t\\\n\t} extern void print##target##Flags (bool withListHeader, bool machinable, FILE *fp \\\n\t\t)\t\t\t\t\t\t/* So we can put ';' here. */\n\ndefineSimplePrintFLagsFunction(Langdef, PreLangDefFlagDef);\ndefineSimplePrintFLagsFunction(Kinddef, PreKindDefFlagDef);\ndefineSimplePrintFLagsFunction(Roledef, PreRoleDefFlagDef);\ndefineSimplePrintFLagsFunction(Fielddef, FieldDefFlagDef);\ndefineSimplePrintFLagsFunction(Extradef, PreXtagDefFlagDef);\n\nextern void printLanguageMultitableStatistics (langType language)\n{\n\tparserObject* const parser = LanguageTable + language;\n\tprintMultitableStatistics (parser->lregexControlBlock);\n}\n\nextern void addLanguageRegexTable (const langType language, const char *name)\n{\n\tparserObject* const parser = LanguageTable + language;\n\taddRegexTable (parser->lregexControlBlock, name);\n}\n\nextern void addLanguageTagMultiTableRegex(const langType language,\n\t\t\t\t\t\t\t\t\t\t  const char* const table_name,\n\t\t\t\t\t\t\t\t\t\t  const char* const regex,\n\t\t\t\t\t\t\t\t\t\t  const char* const name, const char* const kinds, const char* const flags,\n\t\t\t\t\t\t\t\t\t\t  bool *disabled)\n{\n\tparserObject* const parser = LanguageTable + language;\n\taddTagMultiTableRegex (parser->lregexControlBlock, table_name, regex,\n\t\t\t\t\t\t   name, kinds, flags, disabled);\n}\n\nextern void addLanguageOptscriptToHook (langType language, enum scriptHook hook, const char *const src)\n{\n\taddOptscriptToHook (LanguageTable [language].lregexControlBlock, hook, src);\n}\n\nstatic bool processHookOption (const char *const option, const char *const parameter, const char *prefix,\n\t\t\t\t\t\t\t   enum scriptHook hook)\n{\n\tlangType language = getLanguageComponentInOption (option, prefix);\n\tif (language == LANG_IGNORE)\n\t\treturn false;\n\n\tif (parameter == NULL || parameter[0] == '\\0')\n\t\terror (FATAL, \"A parameter is needed after \\\"%s\\\" option\", option);\n\n\tconst char * code = flagsEval (parameter, NULL, 0, NULL);\n\tif (code == NULL)\n\t\terror (FATAL, \"Cannot recognized a code block surrounded by `{{' and `}}' after \\\"%s\\\" option\", option);\n\taddLanguageOptscriptToHook (language, hook, code);\n\n\treturn true;\n}\n\nextern bool processPreludeOption (const char *const option, const char *const parameter)\n{\n\treturn processHookOption (option, parameter, \"_prelude-\", SCRIPT_HOOK_PRELUDE);\n}\n\nextern bool processSequelOption (const char *const option, const char *const parameter)\n{\n\treturn processHookOption (option, parameter, \"_sequel-\", SCRIPT_HOOK_SEQUEL);\n}\n\nextern bool processPretendOption (const char *const option, const char *const parameter)\n{\n\tlangType new_language, old_language;\n\n#define pretendOptionPrefix \"_pretend-\"\n\tnew_language = getLanguageComponentInOptionFull (option, pretendOptionPrefix, true);\n\tif (new_language == LANG_IGNORE)\n\t\treturn false;\n\n\tif (parameter == NULL || parameter[0] == '\\0')\n\t\terror (FATAL, \"A parameter is needed after \\\"%s\\\" option\", option);\n\n\told_language = getNamedLanguageFull (parameter, 0, true, false);\n\tif (old_language == LANG_IGNORE)\n\t\terror (FATAL, \"Unknown language \\\"%s\\\" in option \\\"--%s=%s\\\"\",\n\t\t\t   parameter, option, parameter);\n\n\tif (LanguageTable [new_language].pretendingAsLanguage != LANG_IGNORE)\n\t{\n\t\terror (FATAL, \"%s parser pretends as %s already\\n\",\n\t\t\t   getLanguageNameFull (new_language, true),\n\t\t\t   getLanguageNameFull (LanguageTable [new_language].pretendingAsLanguage, true));\n\t}\n\tif (LanguageTable [old_language].pretendedAsLanguage != LANG_IGNORE)\n\t{\n\t\terror (FATAL, \"%s parser is pretended as %s already\\n\",\n\t\t\t   getLanguageNameFull (old_language, true),\n\t\t\t   getLanguageNameFull (LanguageTable [old_language].pretendedAsLanguage, true));\n\t}\n\n\tverbose (\"%s pretends %s\\n\",\n\t\t\t getLanguageNameFull (new_language, true),\n\t\t\t getLanguageNameFull (old_language, true));\n\n\tLanguageTable [new_language].pretendingAsLanguage = old_language;\n\tLanguageTable [old_language].pretendedAsLanguage  = new_language;\n\n\tverbose (\"force enabling %s\\n\",\n\t\t\t getLanguageNameFull (new_language, true));\n\tenableLanguage (new_language, true);\n\n\tverbose (\"force disabling %s\\n\",\n\t\t\t getLanguageNameFull (old_language, true));\n\tenableLanguage (old_language, false);\n\n\treturn true;\n}\n\nextern unsigned int getLanguageCorkUsage (langType lang)\n{\n\tparserObject* const parser = LanguageTable + lang;\n\treturn parserCorkFlags (parser->def);\n}\n\n/*\n * The universal fallback parser.\n * If any parser doesn't handle the input, this parser is\n * used for the input when --languages=+Unknown is given.\n * writer-etags enables this parser implicitly.\n */\nstatic parserDefinition *FallbackParser (void)\n{\n\tparserDefinition *const def = parserNew (\"Unknown\");\n\tdef->extensions = NULL;\n\tdef->kindTable = NULL;\n\tdef->kindCount = 0;\n\n\t/* A user can extend this parser with --regex-Unknown=...\n\t * or --langdef=MyParser{base=Unknown}.\n\t *\n\t * TODO: if following conditions are met, dontFindTags()\n\t * defined below can be used.\n\t * - any regex pattern is not defined,\n\t * - any sub parser is not defined, and\n\t * - end: field is not enabled.\n\t */\n\tdef->parser = findRegexTags;\n\tdef->enabled = 0;\n\tdef->method = METHOD_REGEX;\n\treturn def;\n}\n\n/*\n * A dummy parser for printing pseudo tags in xref output\n */\nstatic void dontFindTags (void)\n{\n}\n\nstatic kindDefinition CtagsKinds[] = {\n\t{true, 'p', \"ptag\", \"pseudo tags\"},\n};\n\nstatic parserDefinition *CTagsParser (void)\n{\n\tparserDefinition *const def = parserNew (\"UniversalCtags\");\n\tdef->extensions = NULL;\n\tdef->kindTable = CtagsKinds;\n\tdef->kindCount = ARRAY_SIZE(CtagsKinds);\n\tdef->parser = dontFindTags;\n\tdef->invisible = true;\n\treturn def;\n}\n\n/*\n * A parser for CTagsSelfTest (CTST)\n */\n#define SELF_TEST_PARSER \"CTagsSelfTest\"\n#if defined(DEBUG) && defined(HAVE_SECCOMP)\nextern void getppid(void);\n#endif\n\nstatic bool CTST_GatherStats;\nstatic int CTST_num_handled_char;\n\ntypedef enum {\n\tK_BROKEN,\n\tK_NO_LETTER,\n\tK_NO_LONG_NAME,\n\tK_NOTHING_SPECIAL,\n\tK_GUEST_BEGINNING,\n\tK_GUEST_END,\n#if defined(DEBUG) && defined(HAVE_SECCOMP)\n\tK_CALL_GETPPID,\n#endif\n\tK_QUIT,\n\tK_DISABLED,\n\tK_ENABLED,\n\tK_ROLES,\n\tK_ROLES_DISABLED,\n\tK_FIELD_TESTING,\n\tK_TRIGGER_NOTICE,\n\tK_EMIT_NULL_TAG,\n\tK_DONT_EMIT_NULL_TAG,\n\tKIND_COUNT\n} CTST_Kind;\n\ntypedef enum {\n\tR_BROKEN_REF,\n} CTST_BrokenRole;\n\nstatic roleDefinition CTST_BrokenRoles [] = {\n\t{true, \"broken\", \"broken\" },\n};\n\ntypedef enum {\n\tR_DISABLED_KIND_DISABLED_ROLE,\n\tR_DISABLED_KIND_ENABLED_ROLE,\n} CTST_DisabledKindRole;\n\nstatic roleDefinition CTST_DisabledKindRoles [] = {\n\t{ false, \"disabled\", \"disabled role attached to disabled kind\" },\n\t{ true,  \"enabled\",  \"enabled role attached to disabled kind\"  },\n};\n\ntypedef enum {\n\tR_ENABLED_KIND_DISABLED_ROLE,\n\tR_ENABLED_KIND_ENABLED_ROLE,\n} CTST_EnabledKindRole;\n\nstatic roleDefinition CTST_EnabledKindRoles [] = {\n\t{ false, \"disabled\", \"disabled role attached to enabled kind\" },\n\t{ true,  \"enabled\",  \"enabled role attached to enabled kind\"  },\n};\n\ntypedef enum {\n\tR_ROLES_KIND_A_ROLE,\n\tR_ROLES_KIND_B_ROLE,\n\tR_ROLES_KIND_C_ROLE,\n\tR_ROLES_KIND_D_ROLE,\n} CTST_RolesKindRole;\n\nstatic roleDefinition CTST_RolesKindRoles [] = {\n\t{ true,  \"a\", \"A role\" },\n\t{ true,  \"b\", \"B role\" },\n\t{ false, \"c\", \"C role\" },\n\t{ true,  \"d\", \"D role\"  },\n};\n\ntypedef enum {\n\tR_ROLES_DISABLED_KIND_A_ROLE,\n\tR_ROLES_DISABLED_KIND_B_ROLE,\n} CTST_RolesDisableKindRole;\n\n\nstatic roleDefinition CTST_RolesDisabledKindRoles [] = {\n\t{ true,  \"A\", \"A role\" },\n\t{ true,  \"B\", \"B role\" },\n};\n\nstatic kindDefinition CTST_Kinds[KIND_COUNT] = {\n\t/* `a' is reserved for kinddef testing */\n\t{true, 'b', \"broken tag\", \"name with unwanted characters\",\n\t .referenceOnly = false, ATTACH_ROLES (CTST_BrokenRoles) },\n\t{true, KIND_NULL_LETTER, \"no letter\", \"kind with no letter\"\n\t /* use '@' when testing. */\n\t},\n\t{true, 'L', NULL, \"kind with no long name\" },\n\t{true, 'N', \"nothingSpecial\", \"emit a normal tag\" },\n\t{true, 'B', NULL, \"beginning of an area for a guest\" },\n\t{true, 'E', NULL, \"end of an area for a guest\" },\n#if defined(DEBUG) && defined(HAVE_SECCOMP)\n\t{true, 'P', \"callGetPPid\", \"trigger calling getppid(2) that seccomp sandbox disallows\"},\n#endif\n\t{true, 'Q', \"quit\", \"stop the parsing\"},\n\t{false,'d', \"disabled\", \"a kind disabled by default\",\n\t .referenceOnly = false, ATTACH_ROLES (CTST_DisabledKindRoles)},\n\t{true, 'e', \"enabled\", \"a kind enabled by default\",\n\t .referenceOnly = false, ATTACH_ROLES (CTST_EnabledKindRoles)},\n\t{true, 'r', \"roles\", \"emit a tag with multi roles\",\n\t .referenceOnly = true, ATTACH_ROLES (CTST_RolesKindRoles)},\n\t{false, 'R', \"rolesDisabled\", \"emit a tag with multi roles(disabled by default)\",\n\t .referenceOnly = true, ATTACH_ROLES (CTST_RolesDisabledKindRoles)},\n\t{true,  'f', \"fieldMaker\", \"tag for testing field:\" },\n\t{true,  'n', \"triggerNotice\", \"trigger notice output\"},\n\t{true,  'z', \"emitNullTag\", \"emit a tag having an empty string\"},\n\t{true,  'Z', \"dontEmitNullTag\", \"don't emit a tag having an empty string\"},\n};\n\ntypedef enum {\n\tF_BOOLEAN_FIELD,\n\tF_BOOLEAN_AND_STRING_FIELD,\n\tF_STRING_FIELD,\n\tF_INTEGER_FIELD,\n\tCOUNT_FIELD\n} CTSTField;\n\nstatic fieldDefinition CTSTFields[COUNT_FIELD] = {\n\t{ .name = \"bField\",\n\t  .description = \"field for testing boolean type\",\n\t  .dataType = FIELDTYPE_BOOL,\n\t  .enabled = true,\n\t},\n\t{ .name = \"sbField\",\n\t  .description = \"field for testing string|boolean type\",\n\t  .dataType = FIELDTYPE_STRING|FIELDTYPE_BOOL,\n\t  .enabled = true,\n\t},\n\t{ .name = \"sField\",\n\t  .description = \"field for testing string type\",\n\t  .dataType = FIELDTYPE_STRING,\n\t  .enabled = true,\n\t},\n\t{ .name = \"iField\",\n\t  .description = \"field for testing integer type\",\n\t  .dataType = FIELDTYPE_INTEGER,\n\t  .enabled = true,\n\t},\n};\n\nstatic void createCTSTTags (void)\n{\n\tint i;\n\tconst unsigned char *line;\n\ttagEntryInfo e;\n\n\tunsigned long lb = 0;\n\tunsigned long le = 0;\n\n\tint found_enabled_disabled[2] = {0, 0};\n\n\tbool quit = false;\n\n\tTRACE_ENTER_TEXT(\"Parsing starts\");\n\n\twhile (!quit && (line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tint c = line[0];\n\n\t\tfor (i = 0; i < KIND_COUNT; i++)\n\t\t\tif ((c == CTST_Kinds[i].letter && i != K_NO_LETTER)\n\t\t\t\t|| (c == '@' && i == K_NO_LETTER))\n\t\t\t{\n\t\t\t\tif (CTST_GatherStats)\n\t\t\t\t\tCTST_num_handled_char++;\n\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase K_BROKEN:\n\t\t\t\t\t\tinitTagEntry (&e, \"one\\nof\\rbroken\\tname\", i);\n\t\t\t\t\t\te.extensionFields.scopeKindIndex = K_BROKEN;\n\t\t\t\t\t\te.extensionFields.scopeName = \"\\\\Broken\\tContext\";\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tinitTagEntry (&e, \"only\\nnewline\", i);\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tinitTagEntry (&e, \"only\\ttab\", i);\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tinitTagEntry (&e, \"newline-in-scope\", i);\n\t\t\t\t\t\te.extensionFields.scopeKindIndex = K_BROKEN;\n\t\t\t\t\t\te.extensionFields.scopeName = \"parent\\nscope\";\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tinitTagEntry (&e, \"tab-in-scope\", i);\n\t\t\t\t\t\te.extensionFields.scopeKindIndex = K_BROKEN;\n\t\t\t\t\t\te.extensionFields.scopeName = \"parent\\tscope\";\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase K_NO_LETTER:\n\t\t\t\t\t\tinitTagEntry (&e, \"abnormal kindDefinition testing (no letter)\", i);\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase K_NO_LONG_NAME:\n\t\t\t\t\t\tinitTagEntry (&e, \"abnormal kindDefinition testing (no long name)\", i);\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase K_NOTHING_SPECIAL:\n\t\t\t\t\t\tif (!lb)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinitTagEntry (&e, \"NOTHING_SPECIAL\", i);\n\t\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase K_GUEST_BEGINNING:\n\t\t\t\t\t\tlb = getInputLineNumber ();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase K_GUEST_END:\n\t\t\t\t\t\tle = getInputLineNumber ();\n\t\t\t\t\t\tmakePromise (SELF_TEST_PARSER, lb + 1, 0, le, 0, lb + 1);\n\t\t\t\t\t\tbreak;\n#if defined(DEBUG) && defined(HAVE_SECCOMP)\n\t\t\t\t\tcase K_CALL_GETPPID:\n\t\t\t\t\t\tgetppid();\n\t\t\t\t\t\tbreak;\n#endif\n\t\t\t\t\tcase K_QUIT:\n\t\t\t\t\t\tquit = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase K_DISABLED:\n\t\t\t\t\tcase K_ENABLED:\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint role;\n\t\t\t\t\t\t\tchar *name;\n\t\t\t\t\t\t\tif (found_enabled_disabled[i == K_DISABLED]++ == 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trole = ROLE_DEFINITION_INDEX;\n\t\t\t\t\t\t\t\tname = (i == K_DISABLED)\n\t\t\t\t\t\t\t\t\t? \"disable-kind-no-role\"\n\t\t\t\t\t\t\t\t\t: \"enabled-kind-no-role\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (found_enabled_disabled[i == K_DISABLED]++ == 1)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trole = (i == K_DISABLED)\n\t\t\t\t\t\t\t\t\t? R_DISABLED_KIND_DISABLED_ROLE\n\t\t\t\t\t\t\t\t\t: R_ENABLED_KIND_DISABLED_ROLE;\n\t\t\t\t\t\t\t\tname = (i == K_DISABLED)\n\t\t\t\t\t\t\t\t\t? \"disable-kind-disabled-role\"\n\t\t\t\t\t\t\t\t\t: \"enabled-kind-disabled-role\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trole = (i == K_DISABLED)\n\t\t\t\t\t\t\t\t\t? R_DISABLED_KIND_ENABLED_ROLE\n\t\t\t\t\t\t\t\t\t: R_ENABLED_KIND_ENABLED_ROLE;\n\t\t\t\t\t\t\t\tname = (i == K_DISABLED)\n\t\t\t\t\t\t\t\t\t? \"disable-kind-enabled-role\"\n\t\t\t\t\t\t\t\t\t: \"enabled-kind-enabled-role\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinitRefTagEntry (&e, name, i, role);\n\t\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\tcase K_ROLES:\n\t\t\t\t\t{\n\t\t\t\t\t\tchar *name = \"multiRolesTarget\";\n\t\t\t\t\t\tint qindex;\n\t\t\t\t\t\ttagEntryInfo *qe;\n\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tassignRole(&e, R_ROLES_KIND_A_ROLE);\n\t\t\t\t\t\tassignRole(&e, R_ROLES_KIND_C_ROLE);\n\t\t\t\t\t\tassignRole(&e, R_ROLES_KIND_D_ROLE);\n\t\t\t\t\t\tqindex = makeTagEntry (&e);\n\t\t\t\t\t\tqe = getEntryInCorkQueue (qindex);\n\t\t\t\t\t\tif (qe)\n\t\t\t\t\t\t\tassignRole(qe, R_ROLES_KIND_B_ROLE);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase K_ROLES_DISABLED:\n\t\t\t\t\t{\n\t\t\t\t\t\tchar *name = \"multiRolesDisabledTarget\";\n\n\t\t\t\t\t\tinitRefTagEntry (&e, name, i, R_ROLES_DISABLED_KIND_A_ROLE);\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tinitRefTagEntry (&e, name, i, R_ROLES_DISABLED_KIND_B_ROLE);\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase K_FIELD_TESTING:\n\t\t\t\t\t{\n\t\t\t\t\t\tchar c = 'a';\n\t\t\t\t\t\tchar name []= {'\\0', 't', 'a', 'g', '\\0' };\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tattachParserField (&e,\n\t\t\t\t\t\t\t\t\t\t   CTSTFields[F_BOOLEAN_FIELD].ftype, \"\");\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tattachParserField (&e,\n\t\t\t\t\t\t\t\t\t\t   CTSTFields[F_BOOLEAN_FIELD].ftype, \"any-C-string-is-interpreted-as-true\");\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tattachParserField (&e,\n\t\t\t\t\t\t\t\t\t\t   CTSTFields[F_BOOLEAN_AND_STRING_FIELD].ftype, \"val\");\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tattachParserField (&e,\n\t\t\t\t\t\t\t\t\t\t   CTSTFields[F_BOOLEAN_AND_STRING_FIELD].ftype, \"\");\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tattachParserField (&e,\n\t\t\t\t\t\t\t\t\t\t   CTSTFields[F_STRING_FIELD].ftype, \"val\");\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tattachParserField (&e,\n\t\t\t\t\t\t\t\t\t\t   CTSTFields[F_STRING_FIELD].ftype, \"\");\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tattachParserField (&e,\n\t\t\t\t\t\t\t\t\t\t   CTSTFields[F_INTEGER_FIELD].ftype, \"23\");\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tattachParserField (&e,\n\t\t\t\t\t\t\t\t\t\t   CTSTFields[F_INTEGER_FIELD].ftype, \"-3\");\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tattachParserField (&e,\n\t\t\t\t\t\t\t\t\t\t   CTSTFields[F_INTEGER_FIELD].ftype, \"poison\");\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tname [0] = c++;\n\t\t\t\t\t\tinitTagEntry (&e, name, i);\n\t\t\t\t\t\tattachParserField (&e,\n\t\t\t\t\t\t\t\t\t\t   CTSTFields[F_INTEGER_FIELD].ftype, \"\");\n\t\t\t\t\t\tmakeTagEntry (&e);\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase K_TRIGGER_NOTICE:\n\t\t\t\t\t\tnotice (\"notice output for testing: %s\", CTST_Kinds [i].name);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase K_EMIT_NULL_TAG:\n\t\t\t\t\t\tinitTagEntry (&e, \"\", i);\n\t\t\t\t\t\te.allowNullTag = 1;\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase K_DONT_EMIT_NULL_TAG:\n\t\t\t\t\t\tinitTagEntry (&e, \"\", i);\n\t\t\t\t\t\te.allowNullTag = 0;\n\t\t\t\t\t\tmakeTagEntry (&e);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (quit)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t}\n\n\tTRACE_LEAVE();\n}\n\nstatic void initStatsCTST (langType lang CTAGS_ATTR_UNUSED)\n{\n\tCTST_GatherStats = true;\n}\n\nstatic void printStatsCTST (langType lang CTAGS_ATTR_UNUSED)\n{\n\tfprintf (stderr, \"The number of handled chars: %d\\n\",\n\t\t\t CTST_num_handled_char);\n}\n\nstatic void initCTST (langType language)\n{\n\tctagsSelfTestLang = language;\n}\n\nstatic parserDefinition *CTagsSelfTestParser (void)\n{\n\tstatic const char *const extensions[] = { NULL };\n\tparserDefinition *const def = parserNew (SELF_TEST_PARSER);\n\tdef->extensions = extensions;\n\tdef->kindTable = CTST_Kinds;\n\tdef->kindCount = KIND_COUNT;\n\tdef->parser = createCTSTTags;\n\tdef->initialize = initCTST;\n\tdef->invisible = true;\n\tdef->useMemoryStreamInput = true;\n\tdef->useCork = CORK_QUEUE;\n\tdef->initStats = initStatsCTST;\n\tdef->printStats = printStatsCTST;\n\tdef->fieldTable = CTSTFields;\n\tdef->fieldCount = ARRAY_SIZE (CTSTFields);\n\n\treturn def;\n}\n"
  },
  {
    "path": "main/parse.h",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Private definitions for parsing support.\n*/\n#ifndef CTAGS_MAIN_PARSE_H\n#define CTAGS_MAIN_PARSE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"types.h\"\n\n#include \"kind.h\"\n#include \"lregex.h\"\n#include \"lxpath.h\"\n#include \"vstring.h\"\n\n/*\n*   MACROS\n*/\n#define LANG_AUTO   (-1)\n#define LANG_IGNORE (-2)\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef enum {\n\tRESCAN_NONE,   /* No rescan needed */\n\tRESCAN_FAILED, /* Scan failed, clear out tags added, rescan */\n\tRESCAN_APPEND  /* Scan succeeded, rescan */\n} rescanReason;\n\ntypedef void (*createRegexTag) (const vString* const name);\ntypedef void (*simpleParser) (void);\ntypedef rescanReason (*rescanParser) (const unsigned int passCount);\ntypedef void (*parserInitialize) (langType language);\ntypedef void (*initStatistics) (langType language);\ntypedef void (*printStatistics) (langType langType);\n\n/* Per language finalizer is called anytime when ctags exits.\n   (Exceptions are a kind of options are given when invoked. Here\n   options are: --version, --help, --list-*, and so on.)\n\n   The finalizer is called even when the initializer of the\n   same parser is called or not. However, the finalizer can know\n   whether the associated initializer is invoked or not with the\n   second parameter: INITIALIZED. If it is true, the initializer\n   is called. */\ntypedef void (*parserFinalize) (langType language, bool initialized);\n\ntypedef enum {\n\tMETHOD_NOT_CRAFTED    = 1 << 0,\n\tMETHOD_REGEX          = 1 << 1,\n\tMETHOD_XPATH          = 1 << 2,\n} parsingMethod;\n\ntypedef struct {\n\tconst char *name;\n\tconst int id;\n} keywordTable;\n\ntypedef enum {\n\tCORK_NO_USE,\n\tCORK_QUEUE  = (1 << 0),\n\tCORK_SYMTAB = (1 << 1),\n} corkUsage;\n\n/* optlib2c requires the declaration here. */\nenum scriptHook {\n\tSCRIPT_HOOK_PRELUDE,\n\tSCRIPT_HOOK_SEQUEL,\n\tSCRIPT_HOOK_MAX,\n};\n\n/* --map-<LANG>=[+|-|]%regular-expression%[i] */\nstruct rExprSrc {\n\tconst char *expr;\t\t\t/* The last element must be NULL. */\n\tbool iCase;\n};\n#define REXPR_LAST_ENTRY { .expr = NULL, }\n\nstruct sParserDefinition {\n\t/* defined by parser */\n\tchar* name;                    /* name of language */\n\n\t/* The concept of CURRENT and AGE is taken from libtool.\n\t * However, we deleted REVISION in libtool when importing\n\t * the concept of versioning from libtool.\n\t *\n\t * If kinds, roles, fields, and/or extras have been added,\n\t * removed or changed since last release, increment CURRENT.\n\t * If they have been added since last release, increment AGE.\n\t * If they have been removed since last release, set AGE to 0\n\t *\n\t * From the command line of ctags, you can see the version\n\t * information with --version=<LANG>.\n\t *\n\t * In the tags file, !_TAGS_PARSER_VERSION!<LANG> shows the\n\t * information for <LANG>.\n\t */\n\tunsigned int    versionCurrent;\n\tunsigned int    versionAge;\n\n\tkindDefinition* kindTable;     /* tag kinds handled by parser */\n\tunsigned int kindCount;        /* size of `kinds' list */\n\tconst char *const *extensions; /* list of default extensions */\n\tconst char *const *patterns;   /* list of default file name patterns */\n\tconst char *const *aliases;    /* list of default aliases (alternative names) */\n\tconst struct rExprSrc * rexprs;  /* list of default file name regex patterns.\n\t\t\t\t\t\t\t\t\t  * Put REXPR_LAST_ENTRY as the last element. */\n\n\tparserInitialize initialize;   /* initialization routine, if needed */\n\tparserFinalize finalize;       /* finalize routine, if needed */\n\tsimpleParser parser;           /* simple parser (common case) */\n\trescanParser parser2;          /* rescanning parser (unusual case) */\n\tselectLanguage* selectLanguage; /* may be used to resolve conflicts */\n\tunsigned int method;           /* see METHOD_ definitions above */\n\tunsigned int useCork;          /* bit fields of corkUsage */\n\tbool useMemoryStreamInput;\n\tbool allowNullTag;             /* allow the parser emit tags with empty\n\t\t\t\t\t\t\t\t\t  strings. If you want to emit a few\n\t\t\t\t\t\t\t\t\t  specified tags with empty strings,\n\t\t\t\t\t\t\t\t\t  you don't need this parser-global\n\t\t\t\t\t\t\t\t\t  allowNullTag; set tagEntryInfo::allowNullTag\n\t\t\t\t\t\t\t\t\t  instead. */\n\tbool requestAutomaticFQTag;\n\ttagRegexTable *tagRegexTable;\n\tunsigned int tagRegexCount;\n\tconst keywordTable *keywordTable;\n\tunsigned int keywordCount;\n\ttagXpathTableTable *tagXpathTableTable;\n\tunsigned int tagXpathTableCount;\n\tbool invisible;\n\tbool enabled;\t       /* currently enabled? */\n\tfieldDefinition *fieldTable;\n\tunsigned int fieldCount;\n\txtagDefinition *xtagTable;\n\tunsigned int xtagCount;\n\n\tparserDependency * dependencies;\n\tunsigned int dependencyCount;\n\n\tparamDefinition *paramTable;\n\tunsigned int paramCount;\n\n\txpathFileSpec *xpathFileSpecs;\n\tunsigned int xpathFileSpecCount;\n\n\t/* Following two fields are used in a parser using cork. */\n\tconst char *defaultScopeSeparator;\n\tconst char *defaultRootScopeSeparator;\n\n\tinitStatistics initStats;\n\tprintStatistics printStats;\n\n\t/* used internally */\n\tlangType id;\t\t    /* id assigned to language */\n\tunsigned int traced:1;\n};\n\ntypedef parserDefinition* (parserDefinitionFunc) (void);\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\n/* Language processing and parsing */\nextern int makeSimpleTag (const vString* const name, const int kindIndex);\nextern int makeSimpleRefTag (const vString* const name, const int kindIndex,\n\t\t\t     int roleIndex);\nextern int makeSimplePlaceholder(const vString* const name);\nextern parserDefinition* parserNew (const char* name);\n\nextern const char *getLanguageName (const langType language);\nextern const char *getLanguageKindName (const langType language, const int kindIndex);\n\nextern langType getNamedLanguage (const char *const name, size_t len);\nextern langType getNamedLanguageOrAlias (const char *const name, size_t len);\nextern langType getLanguageForFilenameAndContents (const char *const fileName);\nextern langType getLanguageForCommand (const char *const command, langType startFrom);\nextern langType getLanguageForFilename (const char *const filename, langType startFrom);\nextern bool isLanguageEnabled (const langType language);\nextern bool isLanguageKindEnabled (const langType language, int kindIndex);\nextern bool isLanguageRoleEnabled (const langType language, int kindIndex, int roleIndex);\n\nextern kindDefinition* getLanguageKindForName (const langType language, const char *kindName);\nextern roleDefinition* getLanguageRoleForName (const langType language, int kindIndex,\n\t\t\t\t\t\t\t\t\t\t\t   const char *roleName);\n\nextern void initializeParser (langType language);\nextern unsigned int getLanguageCorkUsage (langType language);\n\n#ifdef HAVE_ICONV\nextern const char *getLanguageEncoding (const langType language);\n#endif\n\n\n/* Regex interface */\nextern void addLanguageCallbackRegex (const langType language, const char *const regex, const char *const flags,\n\t\t\t\t\t\t\t\t\t  const regexCallback callback, bool *disabled, void *userData);\nextern void findRegexTagsMainloop (int (* driver)(void));\nextern void findRegexTags (void);\n\n/* Multiline Regex Interface */\nextern void addLanguageRegexTable (const langType language, const char *name);\nextern void addLanguageTagMultiTableRegex(const langType language,\n\t\t\t\t\t\t\t\t\t\t  const char* const table_name,\n\t\t\t\t\t\t\t\t\t\t  const char* const regex,\n\t\t\t\t\t\t\t\t\t\t  const char* const name, const char* const kinds, const char* const flags,\n\t\t\t\t\t\t\t\t\t\t  bool *disabled);\n\nextern void addLanguageOptscriptToHook (langType language, enum scriptHook hook, const char *const src);\n\nextern void anonGenerateFull (vString *buffer, const char *prefix, langType lang, int kind);\n#define anonGenerate(B,P,K) anonGenerateFull((B), (P), LANG_AUTO, (K))\nextern void anonConcatFull   (vString *buffer, langType lang, int kind);\n#define anonConcat(B,K) anonConcatFull((B), LANG_AUTO, (K))\nextern vString *anonGenerateNewFull (const char *prefix, langType lang, int kind);\n#define anonGenerateNew(P,K) anonGenerateNewFull((P), LANG_AUTO, (K))\nextern void anonHashString (const char *filename, char buf[9]);\n\n#endif  /* CTAGS_MAIN_PARSE_H */\n"
  },
  {
    "path": "main/parse_p.h",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Private definitions for parsing support.\n*/\n#ifndef CTAGS_MAIN_PARSE_PRIVATE_H\n#define CTAGS_MAIN_PARSE_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"kind.h\"\n#include \"lregex_p.h\"\n#include \"parse.h\"\n#include \"parsers_p.h\"  /* contains list of parsers */\n#include \"strlist.h\"\n#ifdef EXTERNAL_PARSER_LIST_FILE\n#include EXTERNAL_PARSER_LIST_FILE\n#endif\n\n/*\n*   MACROS\n*/\n#define LANG_FALLBACK   (1)\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef enum {\n\tLMAP_REXPR     = 1 << 0,\n\tLMAP_PATTERN   = 1 << 1,\n\tLMAP_EXTENSION = 1 << 2,\n\tLMAP_ALL       = LMAP_PATTERN | LMAP_EXTENSION | LMAP_REXPR,\n\tLMAP_TABLE_OUTPUT = 1 << 3,\n\tLMAP_NO_LANG_PREFIX = 1 << 4,\n} langmapType;\n\nenum parserCategory\n{\n\tPARSER_CATEGORY_NONE,\n\tPARSER_CATEGORY_LIBXML,\n\tPARSER_CATEGORY_LIBYAML,\n\tPARSER_CATEGORY_PACKCC,\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\n/* Each parsers' definition function is called. The routine is expected to\n * return a structure allocated using parserNew(). This structure must,\n * at minimum, set the `parser' field.\n */\n#ifdef EXTERNAL_PARSER_LIST\nextern parserDefinitionFunc EXTERNAL_PARSER_LIST;\n#else /* ! EXTERNAL_PARSER_LIST */\nextern parserDefinitionFunc PARSER_LIST;\n#ifdef HAVE_LIBXML\nextern parserDefinitionFunc XML_PARSER_LIST;\n#endif\n#ifdef HAVE_LIBYAML\nextern parserDefinitionFunc YAML_PARSER_LIST;\n#endif\n#ifdef HAVE_PACKCC\nextern parserDefinitionFunc PEG_PARSER_LIST;\n#endif\n#ifdef HAVE_PCRE2\nextern parserDefinitionFunc OPTLIB2C_PCRE2_PARSER_LIST;\n#endif\n#endif /* EXTERNAL_PARSER_LIST */\n\nextern bool doesLanguageAllowNullTag (const langType language);\nextern bool doesLanguageRequestAutomaticFQTag (const langType language);\n\nextern langType getNamedLanguageFull (const char *const name, size_t len, bool noPretending, bool include_aliases);\n\nextern kindDefinition* getLanguageKind(const langType language, int kindIndex);\nextern kindDefinition* getLanguageKindForLetter (const langType language, char kindLetter);\nextern roleDefinition* getLanguageRole(const langType language, int kindIndex, int roleIndex);\nextern unsigned int getLanguageVersionCurrent (const langType language);\nextern unsigned int getLanguageVersionAge (const langType language);\n\nextern int defineLanguageKind (const langType language, kindDefinition *def,\n\t\t\t\t\t\t\t   freeKindDefFunc freeKindDef);\n\nextern unsigned int countLanguageKinds (const langType language);\nextern unsigned int countLanguageRoles (const langType language, int kindIndex);\n\nextern bool isLanguageKindRefOnly (const langType language, int kindIndex);\n\nextern bool isLanguageVisible (const langType language);\n\n\nextern void installLanguageMapDefault (const langType language);\nextern void installLanguageMapDefaults (void);\nextern void clearLanguageMap (const langType language);\nextern bool removeLanguageExtensionMap (const langType language, const char *const extension);\nextern void addLanguageExtensionMap (const langType language, const char* extension,\n\t\t\t\t     bool exclusiveInAllLanguages);\nextern bool removeLanguagePatternMap (const langType language, const char *const pattern);\nextern void addLanguagePatternMap (const langType language, const char* ptrn,\n\t\t\t\t   bool exclusiveInAllLanguages);\nextern bool removeLanguageRexprMap (const langType language, const char *const rexpr, bool iCase);\nextern void addLanguageRexprMap (const langType language, const char* rexpr, bool iCase,\n\t\t\t\t   bool exclusiveInAllLanguages);\n\nextern void installLanguageAliasesDefault (const langType language);\nextern void installLanguageAliasesDefaults (void);\nextern void clearLanguageAliases (const langType language);\nextern void addLanguageAlias (const langType language, const char* alias);\n\nextern void printLanguageMaps (const langType language, langmapType type,\n\t\t\t\t\t\t\t   bool withListHeader, bool machinable, FILE *fp);\nextern void enableLanguages (const bool state);\nextern void enableLanguage (const langType language, const bool state);\nextern void initializeParsing (void);\n\nextern unsigned int countParsers (void);\nextern void freeParserResources (void);\nextern void enableDefaultFileKind (bool state);\nextern void printLanguageKinds (const langType language, bool allKindFields,\n\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp);\nextern void printLanguageRoles (const langType language, const char* letters,\n\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp);\nextern void printLanguageAliases (const langType language,\n\t\t\t\t\t\t\t\t  bool withListHeader, bool machinable, FILE *fp);\nextern void printLanguageList (enum parserCategory category);\nextern void printLanguageParams (const langType language,\n\t\t\t\t\t\t\t\t bool withListHeader, bool machinable, FILE *fp);\nextern void printLanguageSubparsers (const langType language,\n\t\t\t\t\t\t\t\t\t bool withListHeader, bool machinable, FILE *fp);\nextern void printExtradefFlags (bool withListHeader, bool machinable, FILE *fp);\nextern void printLangdefFlags (bool withListHeader, bool machinable, FILE *fp);\nextern void printKinddefFlags (bool withListHeader, bool machinable, FILE *fp);\nextern void printRoledefFlags (bool withListHeader, bool machinable, FILE *fp);\nextern void printFielddefFlags (bool withListHeader, bool machinable, FILE *fp);\nextern bool doesParserRequireMemoryStream (const langType language);\nextern bool parseFile (const char *const fileName);\nextern bool parseFileWithMio (const char *const fileName, MIO *mio, void *clientData);\nextern bool parseRawBuffer(const char *fileName, unsigned char *buffer,\n\t\t\t    size_t bufferSize, const langType language, void *clientData);\n\nextern bool runParserInArea (const langType language,\n\t\t\t\t\t\t\t unsigned long startLine, long startCharOffset,\n\t\t\t\t\t\t\t unsigned long endLine, long endCharOffset,\n\t\t\t\t\t\t\t unsigned long sourceLineOffset,\n\t\t\t\t\t\t\t int promise);\n\n#ifdef HAVE_ICONV\nextern void freeEncodingResources (void);\n#endif\n\nextern bool doesLanguageHaveForeignDependency (const langType language, const langType foreign_lang);\n\n/* Regex interface */\nextern bool processLanguageRegexOption (langType language, enum regexParserType regptype, const char *const parameter);\nextern void notifyLanguageRegexInputStart (langType language);\nextern void notifyLanguageRegexInputEnd (langType language);\n\nextern bool hasLanguagePostRunRegexPatterns (const langType language);\nextern void matchLanguageRegex (const langType language, const vString* const line, bool postrun);\nextern void freeRegexResources (void);\nextern bool checkRegex (void);\nextern void useRegexMethod (const langType language);\nextern void printRegexFlags (bool withListHeader, bool machinable, const char *flags, FILE *fp);\nextern void printMultilineRegexFlags (bool withListHeader, bool machinable, const char *flags, FILE *fp);\nextern void printMultitableRegexFlags (bool withListHeader, bool machinable, const char *flags, FILE *fp);\nextern bool doesLanguageExpectCorkInRegex (const langType language);\n\n/* Multiline Regex Interface */\nextern bool hasLanguageMultilineRegexPatterns (const langType language);\nextern void matchLanguageMultilineRegex (const langType language, const vString* const allLines);\nextern void matchLanguageMultitableRegex (const langType language, const vString* const allLines);\n\nextern void processLanguageMultitableExtendingOption (langType language, const char *const parameter);\n\nextern unsigned int   getXpathFileSpecCount (const langType language);\nextern xpathFileSpec* getXpathFileSpec (const langType language, unsigned int nth);\n\nconst tagXpathTableTable *getXpathTableTable (const langType language, unsigned int nth);\n\nextern bool makeKindSeparatorsPseudoTags (const langType language,\n\t\t\t\t\t     const ptagDesc *pdesc);\nextern bool makeKindDescriptionsPseudoTags (const langType language,\n\t\t\t\t\t       const ptagDesc *pdesc);\nextern bool makeFieldDescriptionsPseudoTags (const langType language,\n\t\t\t\t\t       const ptagDesc *pdesc);\nextern bool makeExtraDescriptionsPseudoTags (const langType language,\n\t\t\t\t\t       const ptagDesc *pdesc);\nextern bool makeRoleDescriptionsPseudoTags (const langType language,\n\t\t\t\t\t       const ptagDesc *pdesc);\nextern bool makeParserVersionPseudoTags (const langType language,\n\t\t\t\t\t\t\t\t\t\t const ptagDesc *pdesc);\n\nextern void printLanguageMultitableStatistics (langType language);\nextern void printParserStatisticsIfUsed (langType lang);\n\n/* For keeping the API compatibility with Geany, we use a macro here. */\n#define applyLanguageParam applyParameter\n\n#endif\t/* CTAGS_MAIN_PARSE_PRIVATE_H */\n"
  },
  {
    "path": "main/parsers_p.h",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to all language parsing modules.\n*\n*   To add a new language parser, you need only modify this single input\n*   file to add the name of the parser definition function.\n*/\n#ifndef CTAGS_MAIN_PARSERS_H\n#define CTAGS_MAIN_PARSERS_H\n\n#ifdef HAVE_LIBXML\n#define XML_PARSER_LIST \\\n\tDbusIntrospectParser, \\\n\tGladeParser,  \\\n\tMaven2Parser, \\\n\tPlistXMLParser, \\\n\tRelaxNGParser, \\\n\tSvgParser, \\\n\tXrcParser, \\\n\tXmlParser, \\\n\tXsltParser\n#else\n#define XML_PARSER_LIST\n#endif\n\n#ifdef HAVE_LIBYAML\n#define YAML_PARSER_LIST\t\t\t\t\t\t\\\n\tYamlParser,\t\t\t\t\t\t\t\t\t\\\n\tAnsiblePlaybookParser, \\\n\tI18nRubyGemParser, \\\n\tOpenAPIParser, \\\n\tYamlFrontMatter\n#else\n#define YAML_PARSER_LIST\n#endif\n\n#ifdef HAVE_PACKCC\n#define PEG_PARSER_LIST\t\t\t\t\t\t\\\n\tVarlinkParser, \\\n\tKotlinParser,  \\\n\tThriftParser,  \\\n\tElmParser,     \\\n\tTomlParser\n#else\n#define PEG_PARSER_LIST\n#endif\n\n#ifdef HAVE_PCRE2\n#define OPTLIB2C_PCRE2_PARSER_LIST\t\t\t\\\n\tRDocParser\n#else\n#define OPTLIB2C_PCRE2_PARSER_LIST\n#endif\n\n/* Add the name of any new parser definition function here */\n#define PARSER_LIST \\\n\tAbaqusParser, \\\n\tAbcParser, \\\n\tAdaParser, \\\n\tAntParser, \\\n\tAsciidocParser, \\\n\tAsmParser, \\\n\tAspParser, \\\n\tAutoconfParser, \\\n\tAutoItParser, \\\n\tAutomakeParser, \\\n\tAwkParser, \\\n\tBasicParser, \\\n\tBatsParser, \\\n\tBetaParser, \\\n\tBibLaTeXParser, \\\n\tBibtexParser, \\\n\tClojureParser, \\\n\tCMakeParser, \\\n\tCParser, \\\n\tCargoParser, \\\n\tCppParser, \\\n\tCPreProParser, \\\n\tCssParser, \\\n\tCsharpParser, \\\n\tCtagsParser, \\\n\tCobolParser, \\\n\tCobolFreeParser, \\\n\tCobolVariableParser, \\\n\tCUDAParser, \\\n\tDParser, \\\n\tDbusServiceParser, \\\n\tDiffParser, \\\n\tDtdParser, \\\n\tDTSParser, \\\n\tDosBatchParser, \\\n\tEiffelParser, \\\n\tElixirParser, \\\n\tEmacsLispParser, \\\n\tErlangParser, \\\n\tFalconParser, \\\n\tFlexParser, \\\n\tForthParser, \\\n\tFortranParser, \\\n\tFrontMatterParser, \\\n\tFunctionParametersParser, \\\n\tFyppParser,\t   \\\n\tGdbinitParser, \\\n\tGDScriptParser, \\\n\tGemSpecParser, \\\n\tGoParser, \\\n\tGoModParser, \\\n\tGPerfParser, \\\n\tHaskellParser, \\\n\tHaxeParser, \\\n\tHtmlParser, \\\n\tIniconfParser, \\\n\tInkoParser, \\\n\tIPythonCellParser, \\\n\tITclParser, \\\n\tJavaParser, \\\n\tJavaPropertiesParser, \\\n\tJavaScriptParser, \\\n\tJNIParser, \\\n\tJsonParser, \\\n\tJuliaParser, \\\n\tKconfigParser, \\\n\tLdScriptParser, \\\n\tLEXParser, \\\n\tLispParser, \\\n\tLiterateHaskellParser, \\\n\tLuaParser, \\\n\tM4Parser, \\\n\tManParser, \\\n\tMakefileParser, \\\n\tMarkdownParser, \\\n\tMatLabParser, \\\n\tMesonParser, \\\n\tMesonOptionsParser, \\\n\tMooseParser, \\\n\tMyrddinParser, \\\n\tNftablesParser, \\\n\tNsisParser, \\\n\tObjcParser, \\\n\tOcamlParser, \\\n\tOdinParser, \\\n\tOrgParser, \\\n\tPasswdParser, \\\n\tPascalParser, \\\n\tPerlParser, \\\n\tPerl6Parser, \\\n\tPhpParser, \\\n\tPkgConfigParser, \\\n\tPodParser, \\\n\tPowerShellParser, \\\n\tPrologParser, \\\n\tProtobufParser, \\\n\tPuppetManifestParser, \\\n\tPythonParser, \\\n\tPythonEntryPointsParser, \\\n\tPythonLoggingConfigParser, \\\n\tQemuHXParser, \\\n\tQtMocParser, \\\n\tQuartoParser, \\\n\tRMarkdownParser, \\\n\tRParser, \\\n\tRakeParser, \\\n\tRakuParser, \\\n\tR6ClassParser, \\\n\tRSpecParser, \\\n\tRexxParser, \\\n\tRobotParser, \\\n\tRpmMacrosParser, \\\n\tRpmSpecParser, \\\n\tRstParser, \\\n\tRubyParser, \\\n\tRustParser, \\\n\tS4ClassParser, \\\n\tSchemeParser, \\\n\tSCSSParser, \\\n\tSELinuxInterfaceParser, \\\n\tSELinuxTypeEnforcementParser, \\\n\tSinexParser, \\\n\tShParser, \\\n\tSlangParser, \\\n\tSmlParser, \\\n\tScdocParser, \\\n\tSqlParser, \\\n\tSystemdUnitParser, \\\n\tSystemTapParser, \\\n\tTclParser, \\\n\tTclOOParser, \\\n\tTerraformParser, \\\n\tTerraformVariablesParser, \\\n\tTexParser, \\\n\tTexBeamerParser, \\\n\tTTCNParser, \\\n\tTxt2tagsParser, \\\n\tTypeScriptParser, \\\n\tTypeSpecParser, \\\n\tVParser, \\\n\tVeraParser, \\\n\tVerilogParser, \\\n\tSystemVerilogParser, \\\n\tVhdlParser, \\\n\tVimParser, \\\n\tWindResParser, \\\n\tYACCParser, \\\n\tYumRepoParser, \\\n\tZephirParser, \\\n\tZshParser\n\n#endif  /* CTAGS_MAIN_PARSERS_H */\n"
  },
  {
    "path": "main/portable-dirent_p.h",
    "content": "#include \"general.h\"\n\n#if defined  (HAVE_DIRENT_H)\n\n#include <dirent.h>\n\n#elif defined (_MSC_VER)\n/*\n * Taken from\n * https://github.com/tronkko/dirent/blob/master/include/dirent.h\n *\n * - s/malloc/eMalloc/\n * - s/free/eFree/\n */\n\n/*\n * Dirent interface for Microsoft Visual Studio\n * Version 1.21\n *\n * Copyright (C) 2006-2012 Toni Ronkko\n * This file is part of dirent.  Dirent may be freely distributed\n * under the MIT license.  For all details and documentation, see\n * https://github.com/tronkko/dirent\n */\n#ifndef DIRENT_H\n#define DIRENT_H\n\n/*\n * Include windows.h without Windows Sockets 1.1 to prevent conflicts with\n * Windows Sockets 2.0.\n */\n#ifndef WIN32_LEAN_AND_MEAN\n#   define WIN32_LEAN_AND_MEAN\n#endif\n#include <windows.h>\n\n#include <stdio.h>\n#include <stdarg.h>\n#include <wchar.h>\n#include <string.h>\n#include <stdlib.h>\n#include <malloc.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <errno.h>\n\n/* Indicates that d_type field is available in dirent structure */\n#define _DIRENT_HAVE_D_TYPE\n\n/* Indicates that d_namlen field is available in dirent structure */\n#define _DIRENT_HAVE_D_NAMLEN\n\n/* Entries missing from MSVC 6.0 */\n#if !defined(FILE_ATTRIBUTE_DEVICE)\n#   define FILE_ATTRIBUTE_DEVICE 0x40\n#endif\n\n/* File type and permission flags for stat(), general mask */\n#if !defined(S_IFMT)\n#   define S_IFMT _S_IFMT\n#endif\n\n/* Directory bit */\n#if !defined(S_IFDIR)\n#   define S_IFDIR _S_IFDIR\n#endif\n\n/* Character device bit */\n#if !defined(S_IFCHR)\n#   define S_IFCHR _S_IFCHR\n#endif\n\n/* Pipe bit */\n#if !defined(S_IFFIFO)\n#   define S_IFFIFO _S_IFFIFO\n#endif\n\n/* Regular file bit */\n#if !defined(S_IFREG)\n#   define S_IFREG _S_IFREG\n#endif\n\n/* Read permission */\n#if !defined(S_IREAD)\n#   define S_IREAD _S_IREAD\n#endif\n\n/* Write permission */\n#if !defined(S_IWRITE)\n#   define S_IWRITE _S_IWRITE\n#endif\n\n/* Execute permission */\n#if !defined(S_IEXEC)\n#   define S_IEXEC _S_IEXEC\n#endif\n\n/* Pipe */\n#if !defined(S_IFIFO)\n#   define S_IFIFO _S_IFIFO\n#endif\n\n/* Block device */\n#if !defined(S_IFBLK)\n#   define S_IFBLK 0\n#endif\n\n/* Link */\n#if !defined(S_IFLNK)\n#   define S_IFLNK 0\n#endif\n\n/* Socket */\n#if !defined(S_IFSOCK)\n#   define S_IFSOCK 0\n#endif\n\n/* Read user permission */\n#if !defined(S_IRUSR)\n#   define S_IRUSR S_IREAD\n#endif\n\n/* Write user permission */\n#if !defined(S_IWUSR)\n#   define S_IWUSR S_IWRITE\n#endif\n\n/* Execute user permission */\n#if !defined(S_IXUSR)\n#   define S_IXUSR 0\n#endif\n\n/* Read group permission */\n#if !defined(S_IRGRP)\n#   define S_IRGRP 0\n#endif\n\n/* Write group permission */\n#if !defined(S_IWGRP)\n#   define S_IWGRP 0\n#endif\n\n/* Execute group permission */\n#if !defined(S_IXGRP)\n#   define S_IXGRP 0\n#endif\n\n/* Read others permission */\n#if !defined(S_IROTH)\n#   define S_IROTH 0\n#endif\n\n/* Write others permission */\n#if !defined(S_IWOTH)\n#   define S_IWOTH 0\n#endif\n\n/* Execute others permission */\n#if !defined(S_IXOTH)\n#   define S_IXOTH 0\n#endif\n\n/* Maximum length of file name */\n#if !defined(PATH_MAX)\n#   define PATH_MAX MAX_PATH\n#endif\n#if !defined(FILENAME_MAX)\n#   define FILENAME_MAX MAX_PATH\n#endif\n#if !defined(NAME_MAX)\n#   define NAME_MAX FILENAME_MAX\n#endif\n\n/* File type flags for d_type */\n#define DT_UNKNOWN 0\n#define DT_REG S_IFREG\n#define DT_DIR S_IFDIR\n#define DT_FIFO S_IFIFO\n#define DT_SOCK S_IFSOCK\n#define DT_CHR S_IFCHR\n#define DT_BLK S_IFBLK\n#define DT_LNK S_IFLNK\n\n/* Macros for converting between st_mode and d_type */\n#define IFTODT(mode) ((mode) & S_IFMT)\n#define DTTOIF(type) (type)\n\n/*\n * File type macros.  Note that block devices, sockets and links cannot be\n * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are\n * only defined for compatibility.  These macros should always return false\n * on Windows.\n */\n#if !defined(S_ISFIFO)\n#   define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)\n#endif\n#if !defined(S_ISDIR)\n#   define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)\n#endif\n#if !defined(S_ISREG)\n#   define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)\n#endif\n#if !defined(S_ISLNK)\n#   define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)\n#endif\n#if !defined(S_ISSOCK)\n#   define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)\n#endif\n#if !defined(S_ISCHR)\n#   define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)\n#endif\n#if !defined(S_ISBLK)\n#   define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)\n#endif\n\n/* Return the exact length of d_namlen without zero terminator */\n#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)\n\n/* Return number of bytes needed to store d_namlen */\n#define _D_ALLOC_NAMLEN(p) (PATH_MAX)\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n/* Wide-character version */\nstruct _wdirent {\n    /* Always zero */\n    long d_ino;\n\n    /* Structure size */\n    unsigned short d_reclen;\n\n    /* Length of name without \\0 */\n    size_t d_namlen;\n\n    /* File type */\n    int d_type;\n\n    /* File name */\n    wchar_t d_name[PATH_MAX];\n};\ntypedef struct _wdirent _wdirent;\n\nstruct _WDIR {\n    /* Current directory entry */\n    struct _wdirent ent;\n\n    /* Private file data */\n    WIN32_FIND_DATAW data;\n\n    /* True if data is valid */\n    int cached;\n\n    /* Win32 search handle */\n    HANDLE handle;\n\n    /* Initial directory name */\n    wchar_t *patt;\n};\ntypedef struct _WDIR _WDIR;\n\nstatic _WDIR *_wopendir (const wchar_t *dirname);\nstatic struct _wdirent *_wreaddir (_WDIR *dirp);\nstatic int _wclosedir (_WDIR *dirp);\nstatic void _wrewinddir (_WDIR* dirp);\n\n\n/* For compatibility with Symbian */\n#define wdirent _wdirent\n#define WDIR _WDIR\n#define wopendir _wopendir\n#define wreaddir _wreaddir\n#define wclosedir _wclosedir\n#define wrewinddir _wrewinddir\n\n\n/* Multi-byte character versions */\nstruct dirent {\n    /* Always zero */\n    long d_ino;\n\n    /* Structure size */\n    unsigned short d_reclen;\n\n    /* Length of name without \\0 */\n    size_t d_namlen;\n\n    /* File type */\n    int d_type;\n\n    /* File name */\n    char d_name[PATH_MAX];\n};\ntypedef struct dirent dirent;\n\nstruct DIR {\n    struct dirent ent;\n    struct _WDIR *wdirp;\n};\ntypedef struct DIR DIR;\n\nstatic DIR *opendir (const char *dirname);\nstatic struct dirent *readdir (DIR *dirp);\nstatic int closedir (DIR *dirp);\nstatic void rewinddir (DIR* dirp);\n\n\n/* Internal utility functions */\nstatic WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);\nstatic WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);\n\nstatic int dirent_mbstowcs_s(\n    size_t *pReturnValue,\n    wchar_t *wcstr,\n    size_t sizeInWords,\n    const char *mbstr,\n    size_t count);\n\nstatic int dirent_wcstombs_s(\n    size_t *pReturnValue,\n    char *mbstr,\n    size_t sizeInBytes,\n    const wchar_t *wcstr,\n    size_t count);\n\nstatic void dirent_set_errno (int error);\n\n/*\n * Open directory stream DIRNAME for read and return a pointer to the\n * internal working area that is used to retrieve individual directory\n * entries.\n */\nstatic _WDIR*\n_wopendir(\n    const wchar_t *dirname)\n{\n    _WDIR *dirp = NULL;\n    int error;\n\n    /* Must have directory name */\n    if (dirname == NULL  ||  dirname[0] == '\\0') {\n        dirent_set_errno (ENOENT);\n        return NULL;\n    }\n\n    /* Allocate new _WDIR structure */\n    dirp = (_WDIR*) eMalloc (sizeof (struct _WDIR));\n    if (dirp != NULL) {\n        DWORD n;\n\n        /* Reset _WDIR structure */\n        dirp->handle = INVALID_HANDLE_VALUE;\n        dirp->patt = NULL;\n        dirp->cached = 0;\n\n        /* Compute the length of full path plus zero terminator\n         *\n         * Note that on WinRT there's no way to convert relative paths\n         * into absolute paths, so just assume its an absolute path.\n         */\n#       if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)\n            n = wcslen(dirname);\n#       else\n            n = GetFullPathNameW (dirname, 0, NULL, NULL);\n#       endif\n\n        /* Allocate room for absolute directory name and search pattern */\n        dirp->patt = (wchar_t*) eMalloc (sizeof (wchar_t) * n + 16);\n        if (dirp->patt) {\n\n            /*\n             * Convert relative directory name to an absolute one.  This\n             * allows rewinddir() to function correctly even when current\n             * working directory is changed between opendir() and rewinddir().\n             *\n             * Note that on WinRT there's no way to convert relative paths\n             * into absolute paths, so just assume its an absolute path.\n             */\n#           if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)\n                wcsncpy_s(dirp->patt, n+1, dirname, n);\n#           else\n                n = GetFullPathNameW (dirname, n, dirp->patt, NULL);\n#           endif\n            if (n > 0) {\n                wchar_t *p;\n\n                /* Append search pattern \\* to the directory name */\n                p = dirp->patt + n;\n                if (dirp->patt < p) {\n                    switch (p[-1]) {\n                    case '\\\\':\n                    case '/':\n                    case ':':\n                        /* Directory ends in path separator, e.g. c:\\temp\\ */\n                        /*NOP*/;\n                        break;\n\n                    default:\n                        /* Directory name doesn't end in path separator */\n                        *p++ = '\\\\';\n                    }\n                }\n                *p++ = '*';\n                *p = '\\0';\n\n                /* Open directory stream and retrieve the first entry */\n                if (dirent_first (dirp)) {\n                    /* Directory stream opened successfully */\n                    error = 0;\n                } else {\n                    /* Cannot retrieve first entry */\n                    error = 1;\n                    dirent_set_errno (ENOENT);\n                }\n\n            } else {\n                /* Cannot retrieve full path name */\n                dirent_set_errno (ENOENT);\n                error = 1;\n            }\n\n        } else {\n            /* Cannot allocate memory for search pattern */\n            error = 1;\n        }\n\n    } else {\n        /* Cannot allocate _WDIR structure */\n        error = 1;\n    }\n\n    /* Clean up in case of error */\n    if (error  &&  dirp) {\n        _wclosedir (dirp);\n        dirp = NULL;\n    }\n\n    return dirp;\n}\n\n/*\n * Read next directory entry.  The directory entry is returned in dirent\n * structure in the d_name field.  Individual directory entries returned by\n * this function include regular files, sub-directories, pseudo-directories\n * \".\" and \"..\" as well as volume labels, hidden files and system files.\n */\nstatic struct _wdirent*\n_wreaddir(\n    _WDIR *dirp)\n{\n    WIN32_FIND_DATAW *datap;\n    struct _wdirent *entp;\n\n    /* Read next directory entry */\n    datap = dirent_next (dirp);\n    if (datap) {\n        size_t n;\n        DWORD attr;\n\n        /* Pointer to directory entry to return */\n        entp = &dirp->ent;\n\n        /*\n         * Copy file name as wide-character string.  If the file name is too\n         * long to fit in to the destination buffer, then truncate file name\n         * to PATH_MAX characters and zero-terminate the buffer.\n         */\n        n = 0;\n        while (n + 1 < PATH_MAX  &&  datap->cFileName[n] != 0) {\n            entp->d_name[n] = datap->cFileName[n];\n            n++;\n        }\n        dirp->ent.d_name[n] = 0;\n\n        /* Length of file name excluding zero terminator */\n        entp->d_namlen = n;\n\n        /* File type */\n        attr = datap->dwFileAttributes;\n        if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {\n            entp->d_type = DT_CHR;\n        } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {\n            entp->d_type = DT_DIR;\n        } else {\n            entp->d_type = DT_REG;\n        }\n\n        /* Reset dummy fields */\n        entp->d_ino = 0;\n        entp->d_reclen = sizeof (struct _wdirent);\n\n    } else {\n\n        /* Last directory entry read */\n        entp = NULL;\n\n    }\n\n    return entp;\n}\n\n/*\n * Close directory stream opened by opendir() function.  This invalidates the\n * DIR structure as well as any directory entry read previously by\n * _wreaddir().\n */\nstatic int\n_wclosedir(\n    _WDIR *dirp)\n{\n    int ok;\n    if (dirp) {\n\n        /* Release search handle */\n        if (dirp->handle != INVALID_HANDLE_VALUE) {\n            FindClose (dirp->handle);\n            dirp->handle = INVALID_HANDLE_VALUE;\n        }\n\n        /* Release search pattern */\n        if (dirp->patt) {\n            eFree (dirp->patt);\n            dirp->patt = NULL;\n        }\n\n        /* Release directory structure */\n        eFree (dirp);\n        ok = /*success*/0;\n\n    } else {\n        /* Invalid directory stream */\n        dirent_set_errno (EBADF);\n        ok = /*failure*/-1;\n    }\n    return ok;\n}\n\n/*\n * Rewind directory stream such that _wreaddir() returns the very first\n * file name again.\n */\nstatic void\n_wrewinddir(\n    _WDIR* dirp)\n{\n    if (dirp) {\n        /* Release existing search handle */\n        if (dirp->handle != INVALID_HANDLE_VALUE) {\n            FindClose (dirp->handle);\n        }\n\n        /* Open new search handle */\n        dirent_first (dirp);\n    }\n}\n\n/* Get first directory entry (internal) */\nstatic WIN32_FIND_DATAW*\ndirent_first(\n    _WDIR *dirp)\n{\n    WIN32_FIND_DATAW *datap;\n\n    /* Open directory and retrieve the first entry */\n    dirp->handle = FindFirstFileExW(\n        dirp->patt, FindExInfoStandard, &dirp->data,\n        FindExSearchNameMatch, NULL, 0);\n    if (dirp->handle != INVALID_HANDLE_VALUE) {\n\n        /* a directory entry is now waiting in memory */\n        datap = &dirp->data;\n        dirp->cached = 1;\n\n    } else {\n\n        /* Failed to re-open directory: no directory entry in memory */\n        dirp->cached = 0;\n        datap = NULL;\n\n    }\n    return datap;\n}\n\n/* Get next directory entry (internal) */\nstatic WIN32_FIND_DATAW*\ndirent_next(\n    _WDIR *dirp)\n{\n    WIN32_FIND_DATAW *p;\n\n    /* Get next directory entry */\n    if (dirp->cached != 0) {\n\n        /* A valid directory entry already in memory */\n        p = &dirp->data;\n        dirp->cached = 0;\n\n    } else if (dirp->handle != INVALID_HANDLE_VALUE) {\n\n        /* Get the next directory entry from stream */\n        if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {\n            /* Got a file */\n            p = &dirp->data;\n        } else {\n            /* The very last entry has been processed or an error occured */\n            FindClose (dirp->handle);\n            dirp->handle = INVALID_HANDLE_VALUE;\n            p = NULL;\n        }\n\n    } else {\n\n        /* End of directory stream reached */\n        p = NULL;\n\n    }\n\n    return p;\n}\n\n/*\n * Open directory stream using plain old C-string.\n */\nstatic DIR*\nopendir(\n    const char *dirname)\n{\n    struct DIR *dirp;\n    int error;\n\n    /* Must have directory name */\n    if (dirname == NULL  ||  dirname[0] == '\\0') {\n        dirent_set_errno (ENOENT);\n        return NULL;\n    }\n\n    /* Allocate memory for DIR structure */\n    dirp = (DIR*) eMalloc (sizeof (struct DIR));\n    if (dirp) {\n        wchar_t wname[PATH_MAX];\n        size_t n;\n\n        /* Convert directory name to wide-character string */\n        error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);\n        if (!error) {\n\n            /* Open directory stream using wide-character name */\n            dirp->wdirp = _wopendir (wname);\n            if (dirp->wdirp) {\n                /* Directory stream opened */\n                error = 0;\n            } else {\n                /* Failed to open directory stream */\n                error = 1;\n            }\n\n        } else {\n            /*\n             * Cannot convert file name to wide-character string.  This\n             * occurs if the string contains invalid multi-byte sequences or\n             * the output buffer is too small to contain the resulting\n             * string.\n             */\n            error = 1;\n        }\n\n    } else {\n        /* Cannot allocate DIR structure */\n        error = 1;\n    }\n\n    /* Clean up in case of error */\n    if (error  &&  dirp) {\n        eFree (dirp);\n        dirp = NULL;\n    }\n\n    return dirp;\n}\n\n/*\n * Read next directory entry.\n *\n * When working with text consoles, please note that file names returned by\n * readdir() are represented in the default ANSI code page while any output to\n * console is typically formatted on another code page.  Thus, non-ASCII\n * characters in file names will not usually display correctly on console.  The\n * problem can be fixed in two ways: (1) change the character set of console\n * to 1252 using chcp utility and use Lucida Console font, or (2) use\n * _cprintf function when writing to console.  The _cprinf() will re-encode\n * ANSI strings to the console code page so many non-ASCII characters will\n * display correcly.\n */\nstatic struct dirent*\nreaddir(\n    DIR *dirp)\n{\n    WIN32_FIND_DATAW *datap;\n    struct dirent *entp;\n\n    /* Read next directory entry */\n    datap = dirent_next (dirp->wdirp);\n    if (datap) {\n        size_t n;\n        int error;\n\n        /* Attempt to convert file name to multi-byte string */\n        error = dirent_wcstombs_s(\n            &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);\n\n        /*\n         * If the file name cannot be represented by a multi-byte string,\n         * then attempt to use old 8+3 file name.  This allows traditional\n         * Unix-code to access some file names despite of unicode\n         * characters, although file names may seem unfamiliar to the user.\n         *\n         * Be ware that the code below cannot come up with a short file\n         * name unless the file system provides one.  At least\n         * VirtualBox shared folders fail to do this.\n         */\n        if (error  &&  datap->cAlternateFileName[0] != '\\0') {\n            error = dirent_wcstombs_s(\n                &n, dirp->ent.d_name, PATH_MAX,\n                datap->cAlternateFileName, PATH_MAX);\n        }\n\n        if (!error) {\n            DWORD attr;\n\n            /* Initialize directory entry for return */\n            entp = &dirp->ent;\n\n            /* Length of file name excluding zero terminator */\n            entp->d_namlen = n - 1;\n\n            /* File attributes */\n            attr = datap->dwFileAttributes;\n            if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {\n                entp->d_type = DT_CHR;\n            } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {\n                entp->d_type = DT_DIR;\n            } else {\n                entp->d_type = DT_REG;\n            }\n\n            /* Reset dummy fields */\n            entp->d_ino = 0;\n            entp->d_reclen = sizeof (struct dirent);\n\n        } else {\n            /*\n             * Cannot convert file name to multi-byte string so construct\n             * an erroneous directory entry and return that.  Note that\n             * we cannot return NULL as that would stop the processing\n             * of directory entries completely.\n             */\n            entp = &dirp->ent;\n            entp->d_name[0] = '?';\n            entp->d_name[1] = '\\0';\n            entp->d_namlen = 1;\n            entp->d_type = DT_UNKNOWN;\n            entp->d_ino = 0;\n            entp->d_reclen = 0;\n        }\n\n    } else {\n        /* No more directory entries */\n        entp = NULL;\n    }\n\n    return entp;\n}\n\n/*\n * Close directory stream.\n */\nstatic int\nclosedir(\n    DIR *dirp)\n{\n    int ok;\n    if (dirp) {\n\n        /* Close wide-character directory stream */\n        ok = _wclosedir (dirp->wdirp);\n        dirp->wdirp = NULL;\n\n        /* Release multi-byte character version */\n        eFree (dirp);\n\n    } else {\n\n        /* Invalid directory stream */\n        dirent_set_errno (EBADF);\n        ok = /*failure*/-1;\n\n    }\n    return ok;\n}\n\n/*\n * Rewind directory stream to beginning.\n */\nstatic void\nrewinddir(\n    DIR* dirp)\n{\n    /* Rewind wide-character string directory stream */\n    _wrewinddir (dirp->wdirp);\n}\n\n/* Convert multi-byte string to wide character string */\nstatic int\ndirent_mbstowcs_s(\n    size_t *pReturnValue,\n    wchar_t *wcstr,\n    size_t sizeInWords,\n    const char *mbstr,\n    size_t count)\n{\n    int error;\n\n#if defined(_MSC_VER)  &&  _MSC_VER >= 1400\n\n    /* Microsoft Visual Studio 2005 or later */\n    error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);\n\n#else\n\n    /* Older Visual Studio or non-Microsoft compiler */\n    size_t n;\n\n    /* Convert to wide-character string (or count characters) */\n    n = mbstowcs (wcstr, mbstr, sizeInWords);\n    if (!wcstr  ||  n < count) {\n\n        /* Zero-terminate output buffer */\n        if (wcstr  &&  sizeInWords) {\n            if (n >= sizeInWords) {\n                n = sizeInWords - 1;\n            }\n            wcstr[n] = 0;\n        }\n\n        /* Length of resulting multi-byte string WITH zero terminator */\n        if (pReturnValue) {\n            *pReturnValue = n + 1;\n        }\n\n        /* Success */\n        error = 0;\n\n    } else {\n\n        /* Could not convert string */\n        error = 1;\n\n    }\n\n#endif\n\n    return error;\n}\n\n/* Convert wide-character string to multi-byte string */\nstatic int\ndirent_wcstombs_s(\n    size_t *pReturnValue,\n    char *mbstr,\n    size_t sizeInBytes, /* max size of mbstr */\n    const wchar_t *wcstr,\n    size_t count)\n{\n    int error;\n\n#if defined(_MSC_VER)  &&  _MSC_VER >= 1400\n\n    /* Microsoft Visual Studio 2005 or later */\n    error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);\n\n#else\n\n    /* Older Visual Studio or non-Microsoft compiler */\n    size_t n;\n\n    /* Convert to multi-byte string (or count the number of bytes needed) */\n    n = wcstombs (mbstr, wcstr, sizeInBytes);\n    if (!mbstr  ||  n < count) {\n\n        /* Zero-terminate output buffer */\n        if (mbstr  &&  sizeInBytes) {\n            if (n >= sizeInBytes) {\n                n = sizeInBytes - 1;\n            }\n            mbstr[n] = '\\0';\n        }\n\n        /* Length of resulting multi-bytes string WITH zero-terminator */\n        if (pReturnValue) {\n            *pReturnValue = n + 1;\n        }\n\n        /* Success */\n        error = 0;\n\n    } else {\n\n        /* Cannot convert string */\n        error = 1;\n\n    }\n\n#endif\n\n    return error;\n}\n\n/* Set errno variable */\nstatic void\ndirent_set_errno(\n    int error)\n{\n#if defined(_MSC_VER)  &&  _MSC_VER >= 1400\n\n    /* Microsoft Visual Studio 2005 and later */\n    _set_errno (error);\n\n#else\n\n    /* Non-Microsoft compiler or older Microsoft compiler */\n    errno = error;\n\n#endif\n}\n\n\n#ifdef __cplusplus\n}\n#endif\n#endif /*DIRENT_H*/\n#endif /* HAVE_DIRENT_H */\n"
  },
  {
    "path": "main/portable-scandir.c",
    "content": "#include \"general.h\"\n/*\n * Taken from https://github.com/ClusterLabs/pacemaker/blob/master/replace/scandir.c\n */\n\n/* scandir: Scan a directory, collecting all (selected) items into a an array.\n *\n * This code borrowed from 'libit', which can be found here:\n *\n * http://www.iro.umontreal.ca/~pinard/libit/dist/scandir/\n *\n * The original author put this code in the public domain.\n * It has been modified slightly to get rid of warnings, etc.\n *\n * Below is the email I received from pinard@iro.umontreal.ca (François Pinard)\n * when I sent him an email asking him about the license, etc. of this\n * code which I obtained from his site.\n *\n * I think the correct spelling of his name is Rich Salz.  I think he's now\n * rsalz@datapower.com...\n * --\n * Rich Salz, Chief Security Architect\n * DataPower Technology                           http://www.datapower.com\n * XS40 XML Security Gateway   http://www.datapower.com/products/xs40.html\n *\n *\tCopyright(C):\tnone (public domain)\n *\tLicense:\tnone (public domain)\n *\tAuthor:\t\tRich Salz <rsalz@datapower.com>\n *\n *\n *\n *\t-- Alan Robertson\n *\t   alanr@unix.sh\n *\n **************************************************************************\n *\n * Subject:\tRe: Scandir replacement function\n * Date:\t18 May 2001 12:00:48 -0400\n * From:\tpinard@iro.umontreal.ca (François Pinard)\n * To:\t\tAlan Robertson <alanr@unix.sh>\n * References:\t1\n *\n *\n * [Alan Robertson]\n *\n * > Hi, I'd like to use your scandir replacement function found here:\n * > http://www.iro.umontreal.ca/~pinard/libit/dist/scandir/ But, it does\n * > not indicate authorship or licensing terms in it.  Could you tell me\n * > who wrote this code, under what license you distribute it, and whether\n * > and under what terms I may further distribute it?\n *\n * Hello, Alan.  These are (somewhat) explained in UNSHAR.HDR found in the\n * same directory.  The routines have been written by Rick Saltz (I'm not\n * completely sure of the spelling) a long while ago.  I think that nowadays,\n * Rick is better known as the main author of the nice INN package.\n *\n **************************************************************************\n *\n * I spent a little time verifying this with Rick Salz.\n * The results are below:\n *\n **************************************************************************\n *\n * Date: Tue, 20 Sep 2005 21:52:09 -0400 (EDT)\n * From: Rich Salz <rsalz@datapower.com>\n * To: Alan Robertson <alanr@unix.sh>\n * Subject: Re: Verifying permissions/licenses/etc on some old code of yours -\n *  scandir.c\n * In-Reply-To: <433071CA.8000107@unix.sh>\n * Message-ID: <Pine.LNX.4.44L0.0509202151270.9198-100000@smtp.datapower.com>\n * Content-Type: TEXT/PLAIN; charset=US-ASCII\n *\n * yes, it's most definitely in the public domain.\n *\n * I'm glad you find it useful.  I'm surprised it hasn't been replaced by,\n * e.g,. something in GLibC.  Ii'm impressed you tracked me down.\n *\n *\t/r$\n *\n * --\n * Rich Salz                  Chief Security Architect\n * DataPower Technology       http://www.datapower.com\n * XS40 XML Security Gateway  http://www.datapower.com/products/xs40.html\n * ---------------------------------------------------------------------->\n * Subject:\tscandir, ftw REDUX\n * Date: \t1 Jan 88 00:47:01 GMT\n * From: \trsalz@pebbles.bbn.com\n * Newsgroups:  comp.sources.misc\n *\n *\n * Forget my previous message -- I just decided for completeness's sake to\n * implement the SysV ftw(3) routine, too.\n *\n * To repeat, these are public-domain implementations of the SystemV ftw()\n * routine, the BSD scandir() and alphasort() routines, and documentation for\n * same.  The FTW manpage could be more readable, but so it goes.\n *\n * Anyhow, feel free to post these, and incorporate them into your existing\n * packages.  I have readdir() routiens for MSDOS and the Amiga if anyone\n *  wants them, and should have them for VMS by the end of January; let me\n *  know if you want copies.\n *\n *                        Yours in filesystems,\n *                                /r$\n *\n *                                Anyhow, feel free to post\n * ----------------------------------------------------------------------<\n *\n */\n\n#include \"routines.h\"\n#include \"routines_p.h\"\n\n#if defined (HAVE_SCANDIR) && defined (HAVE_DIRENT_H)\n#include <dirent.h>\n#elif defined (HAVE_DIRENT_H) || defined (_MSC_VER)\n# ifdef HAVE_DIRENT_H\n# include <dirent.h>\n# endif\n#define USE_SCANDIR_COMPARE_STRUCT_DIRENT\n\n#include <sys/types.h>\n\n#include <stdlib.h>\n#include <stddef.h>\n#include <string.h>\n\n#ifndef NULL\n#  define NULL ((void *) 0)\n#endif\n\n/* Initial guess at directory allocated.  */\n#define INITIAL_ALLOCATION 20\n\nint\nscandir(const char *directory_name,\n        struct dirent ***array_pointer, int (*select_function) (const struct dirent *),\n#ifdef USE_SCANDIR_COMPARE_STRUCT_DIRENT\n        /* This is what the linux man page says */\n        int (*compare_function) (const struct dirent **, const struct dirent **)\n#else\n        /* This is what the linux header file says ... */\n        int (*compare_function) (const void *, const void *)\n#endif\n    )\n{\n    DIR *directory;\n    struct dirent **array;\n    struct dirent *entry;\n    struct dirent *copy;\n    int allocated = INITIAL_ALLOCATION;\n    int counter = 0;\n\n    /* Get initial list space and open directory.  */\n\n    if (directory = opendir(directory_name), directory == NULL)\n        return -1;\n\n    if (array = (struct dirent **)eMalloc(allocated * sizeof(struct dirent *)), array == NULL)\n        return -1;\n\n    /* Read entries in the directory.  */\n\n    while (entry = readdir(directory), entry)\n        if (select_function == NULL || (*select_function) (entry)) {\n            /* User wants them all, or he wants this one.  Copy the entry.  */\n\n            /*\n             * On some OSes the declaration of \"entry->d_name\" is a minimal-length\n             * placeholder.  Example: Solaris:\n             *      /usr/include/sys/dirent.h:\n             *              \"char d_name[1];\"\n             *      man page \"dirent(3)\":\n             *              The field d_name is the beginning of the character array\n             *              giving the name of the directory entry. This name is\n             *              null terminated and may have at most MAXNAMLEN chars.\n             * So our malloc length may need to be increased accordingly.\n             *      sizeof(entry->d_name): space (possibly minimal) in struct.\n             *      strlen(entry->d_name): actual length of the entry.\n             *\n             *                      John Kavadias <john_kavadias@hotmail.com>\n             *                      David Lee <t.d.lee@durham.ac.uk>\n             */\n            int namelength = strlen(entry->d_name) + 1; /* length with NULL */\n            int extra = 0;\n\n            if (sizeof(entry->d_name) <= namelength) {\n                /* allocated space <= required space */\n                extra += namelength - sizeof(entry->d_name);\n            }\n\n            if (copy = (struct dirent *)eMalloc(sizeof(struct dirent) + extra), copy == NULL) {\n                closedir(directory);\n                eFree(array);\n                return -1;\n            }\n            copy->d_ino = entry->d_ino;\n            copy->d_reclen = entry->d_reclen;\n            strcpy(copy->d_name, entry->d_name);\n\n            /* Save the copy.  */\n\n            if (counter + 1 == allocated) {\n                allocated <<= 1;\n                array = (struct dirent **)\n                    eRealloc((char *)array, allocated * sizeof(struct dirent *));\n                if (array == NULL) {\n                    closedir(directory);\n                    eFree(array);\n                    eFree(copy);\n                    return -1;\n                }\n            }\n            array[counter++] = copy;\n        }\n\n    /* Close things off.  */\n\n    array[counter] = NULL;\n    *array_pointer = array;\n    closedir(directory);\n\n    /* Sort?  */\n\n    if (counter > 1 && compare_function)\n        qsort((char *)array, counter, sizeof(struct dirent *)\n              , (int (*)(const void *, const void *))(compare_function));\n\n    return counter;\n}\n#endif\n\n#if defined (HAVE_DIRENT_H) || defined (_MSC_VER)\nint scanDirectory (const char *directory_name,\n\t\t\t\t   struct dirent ***array_pointer, int (*select_function) (const struct dirent *),\n\t\t\t\t   int (*compare_function) (const struct dirent **, const struct dirent **))\n{\n\treturn scandir (directory_name, array_pointer, select_function, compare_function);\n}\n#endif\n"
  },
  {
    "path": "main/promise.c",
    "content": "/*\n *\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#include \"general.h\"\n#include \"parse_p.h\"\n#include \"promise.h\"\n#include \"promise_p.h\"\n#include \"ptrarray.h\"\n#include \"debug.h\"\n#include \"read_p.h\"\n#include \"trashbox.h\"\n#include \"xtag.h\"\n#include \"numarray.h\"\n#include \"routines.h\"\n#include \"options.h\"\n\n#include <string.h>\n\nstruct promise {\n\tlangType lang;\n\tunsigned long startLine;\n\tlong startColumn;\n\tunsigned long endLine;\n\tlong endColumn;\n\tunsigned long sourceLineOffset;\n\tint parent_promise;\n\tptrArray *modifiers;\n};\n\ntypedef void ( *promiseInputModifier) (unsigned char * input,\n\t\t\t\t\t\t\t\t\t   size_t size,\n\t\t\t\t\t\t\t\t\t   unsigned long startLine, long startColumn,\n\t\t\t\t\t\t\t\t\t   unsigned long endLine, long endColumn,\n\t\t\t\t\t\t\t\t\t   void *data);\ntypedef void ( *promiseDestroyAttachedData) (void *data);\n\nstruct modifier {\n\tpromiseInputModifier modifier;\n\tpromiseDestroyAttachedData destroyData;\n\tvoid *data;\n};\n\nstatic struct promise *promises;\nstatic int promise_count;\nstatic int promise_allocated;\n\n#define NO_PROMISE -1\nstatic int current_promise = NO_PROMISE;\n\nstatic void attachPromiseModifier (int promise,\n\t\t\t\t\t\t\t\t   promiseInputModifier modifier,\n\t\t\t\t\t\t\t\t   promiseDestroyAttachedData destroyData,\n\t\t\t\t\t\t\t\t   void *data);\n\n\nint  makePromise   (const char *parser,\n\t\t    unsigned long startLine, long startColumn,\n\t\t    unsigned long endLine, long endColumn,\n\t\t    unsigned long sourceLineOffset)\n{\n\tstruct promise *p;\n\tint r;\n\tlangType lang = LANG_IGNORE;\n\n\tconst bool is_thin_area_spec =\n\t\tisThinAreaSpec(startLine, startColumn,\n\t\t\t\t\t   endLine, endColumn,\n\t\t\t\t\t   sourceLineOffset);\n\n\tif (!is_thin_area_spec\n\t\t&& (startLine > endLine\n\t\t\t|| (startLine == endLine && startColumn >= endColumn)))\n\t\treturn -1;\n\n\tverbose(\"makePromise: %s > %s start(line: %lu, offset: %ld, srcline: %lu), end(line: %lu, offset: %ld)\\n\",\n\t\t\tgetInputLanguageName (),\n\t\t\tparser? parser: \"*\", startLine, startColumn, sourceLineOffset,\n\t\t\tendLine, endColumn);\n\n\tif ((!is_thin_area_spec)\n\t\t&& ( !isXtagEnabled (XTAG_GUEST)))\n\t\treturn -1;\n\n\tif (parser)\n\t{\n\t\tlang = getNamedLanguage (parser, 0);\n\t\tif (lang == LANG_IGNORE)\n\t\t\treturn -1;\n\t}\n\n\tif ( promise_count == promise_allocated)\n\t{\n\t\tsize_t c = promise_allocated? (promise_allocated * 2): 8;\n\t\tif (promises)\n\t\t\tDEFAULT_TRASH_BOX_TAKE_BACK(promises);\n\t\tpromises = xRealloc (promises, c, struct promise);\n\t\tDEFAULT_TRASH_BOX(promises, eFree);\n\t\tpromise_allocated = c;\n\t}\n\n\tp = promises + promise_count;\n\tp->parent_promise = current_promise;\n\tp->lang = lang;\n\n\tif (is_thin_area_spec && isAreaStacked())\n\t{\n\t\tgetAreaInfo (&p->startLine,\n\t\t\t\t\t &p->startColumn,\n\t\t\t\t\t &p->endLine,\n\t\t\t\t\t &p->endColumn);\n\t\tp->sourceLineOffset = p->startLine;\n\t}\n\telse\n\t{\n\t\tp->startLine = startLine;\n\t\tp->startColumn = startColumn;\n\t\tp->endLine = endLine;\n\t\tp->endColumn = endColumn;\n\t\tp->sourceLineOffset = sourceLineOffset;\n\t}\n\n\tp->modifiers = NULL;\n\n\tr = promise_count;\n\tpromise_count++;\n\treturn r;\n}\n\nstatic void freeModifier (void *data)\n{\n\tstruct modifier *m = data;\n\tm->destroyData(m->data);\n\teFree (m);\n}\n\nstatic void attachPromiseModifier (int promise,\n\t\t\t\t\t\t\t\t   promiseInputModifier modifier,\n\t\t\t\t\t\t\t\t   promiseDestroyAttachedData destroyData,\n\t\t\t\t\t\t\t\t   void *data)\n{\n\tstruct modifier *m = xMalloc (1, struct modifier);\n\n\tm->modifier = modifier;\n\tm->destroyData = destroyData;\n\tm->data = data;\n\n\tstruct promise *p = promises + promise;\n\tif (!p->modifiers)\n\t\tp->modifiers = ptrArrayNew(freeModifier);\n\n\tptrArrayAdd (p->modifiers, m);\n}\n\nstatic void freeModifiers(int promise)\n{\n\tfor (int i = promise; i < promise_count; i++)\n\t{\n\t\tstruct promise *p = promises + promise;\n\t\tif (p->modifiers)\n\t\t{\n\t\t\tptrArrayDelete (p->modifiers);\n\t\t\tp->modifiers = NULL;\n\t\t}\n\t}\n}\n\nvoid breakPromisesAfter (int promise)\n{\n\tAssert (promise_count >= promise);\n\tif (promise == NO_PROMISE)\n\t\tpromise = 0;\n\n\tfreeModifiers(promise);\n\tpromise_count = promise;\n}\n\nbool forcePromises (void)\n{\n\tint i;\n\tbool tagFileResized = false;\n\n\tfor (i = 0; i < promise_count; ++i)\n\t{\n\t\tcurrent_promise = i;\n\t\tstruct promise *p = promises + i;\n\n\t\tif (p->lang != LANG_IGNORE && isLanguageEnabled (p->lang))\n\t\t\ttagFileResized = runParserInArea (p->lang,\n\t\t\t\t\t\t\t\t\t\t\t  p->startLine,\n\t\t\t\t\t\t\t\t\t\t\t  p->startColumn,\n\t\t\t\t\t\t\t\t\t\t\t  p->endLine,\n\t\t\t\t\t\t\t\t\t\t\t  p->endColumn,\n\t\t\t\t\t\t\t\t\t\t\t  p->sourceLineOffset,\n\t\t\t\t\t\t\t\t\t\t\t  i)\n\t\t\t\t? true\n\t\t\t\t: tagFileResized;\n\t}\n\n\tfreeModifiers (0);\n\tcurrent_promise  = NO_PROMISE;\n\tpromise_count = 0;\n\treturn tagFileResized;\n}\n\n\nint getLastPromise (void)\n{\n\treturn promise_count - 1;\n}\n\nstatic unsigned char* fill_or_skip (unsigned char *input, const unsigned char *const input_end, const bool filling)\n{\n\tif ( !(input < input_end))\n\t\treturn NULL;\n\n\tunsigned char *next = memchr(input, '\\n', input_end - input);\n\tif (next)\n\t{\n\t\tif (filling)\n\t\t\tmemset(input, ' ', next - input);\n\t\tinput = next + 1;\n\t\tif (input == input_end)\n\t\t\treturn NULL;\n\t\telse\n\t\t\treturn input;\n\t}\n\telse\n\t{\n\t\tif (filling)\n\t\t\tmemset(input, ' ', input_end - input);\n\t\treturn NULL;\n\t}\n}\n\nstatic void line_filler (unsigned char *input, size_t const size,\n\t\t\t\t\t\t unsigned long const startLine, long const startColumn,\n\t\t\t\t\t\t unsigned long const endLine, long const endColumn,\n\t\t\t\t\t\t void *data)\n{\n\tconst ulongArray *lines = data;\n\tconst size_t count = ulongArrayCount (lines);\n\tunsigned int start_index, end_index;\n\tunsigned int i;\n\n\tfor (i = 0; i < count; i++)\n\t{\n\t\tconst unsigned long line = ulongArrayItem (lines, i);\n\t\tif (line >= startLine)\n\t\t{\n\t\t\tif (line > endLine)\n\t\t\t\treturn;\t\t\t/* Not over-wrapping */\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (i == count)\n\t\treturn;\t\t\t\t\t/* Not over-wrapping */\n\tstart_index = i;\n\n\tfor (; i < count; i++)\n\t{\n\t\tconst unsigned long line = ulongArrayItem (lines, i);\n\t\tif (line > endLine)\n\t\t\tbreak;\n\t}\n\tend_index = i;\n\n\tunsigned long input_line = startLine;\n\tconst unsigned char *const input_end = input + size;\n\tfor (i = start_index; i < end_index; i++)\n\t{\n\t\tconst unsigned long line = ulongArrayItem (lines, i);\n\n\t\twhile (1)\n\t\t{\n\t\t\tif (input_line == line)\n\t\t\t{\n\t\t\t\tinput = fill_or_skip (input, input_end, true);\n\t\t\t\tinput_line++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tinput = fill_or_skip (input, input_end, false);\n\t\t\t\tinput_line++;\n\t\t\t}\n\t\t\tif (input == NULL)\n\t\t\t\treturn;\n\t\t}\n\t}\n}\n\nvoid promiseAttachLineFiller (int promise, ulongArray *lines)\n{\n\tattachPromiseModifier (promise, line_filler,\n\t\t\t\t\t\t   (promiseDestroyAttachedData)ulongArrayDelete,\n\t\t\t\t\t\t   lines);\n}\n\n\nstatic void collectModifiers(int promise, ptrArray *modifiers)\n{\n\twhile (promise != NO_PROMISE)\n\t{\n\t\tstruct promise *p = promises + promise;\n\t\tif (p->modifiers)\n\t\t{\n\t\t\tfor (int i = ptrArrayCount(p->modifiers); i > 0; i--)\n\t\t\t{\n\t\t\t\tstruct modifier *m = ptrArrayItem(p->modifiers, i - 1);\n\t\t\t\tptrArrayAdd (modifiers, m);\n\t\t\t}\n\t\t}\n\t\tpromise = p->parent_promise;\n\t}\n}\n\nvoid runModifiers (int promise,\n\t\t\t\t   unsigned long startLine, long startColumn,\n\t\t\t\t   unsigned long endLine, long endColumn,\n\t\t\t\t   unsigned char *input,\n\t\t\t\t   size_t size)\n{\n\tptrArray *modifiers = ptrArrayNew (NULL);\n\n\tcollectModifiers (promise, modifiers);\n\tfor (int i = ptrArrayCount (modifiers); i > 0 ; i--)\n\t{\n\t\tstruct modifier *m = ptrArrayItem (modifiers, i - 1);\n\t\tm->modifier (input, size,\n\t\t\t\t\t startLine, startColumn,\n\t\t\t\t\t endLine, endColumn,\n\t\t\t\t\t m->data);\n\t}\n\tptrArrayDelete (modifiers);\n}\n\nvoid promiseUpdateLanguage  (int promise, langType lang)\n{\n\tAssert (promise >= 0);\n\n\tstruct promise *p = promises + promise;\n\n\tp->lang = lang;\n}\n"
  },
  {
    "path": "main/promise.h",
    "content": "/*\n *\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_PROMISE_H\n#define CTAGS_MAIN_PROMISE_H\n\n#include \"general.h\"\n#include \"mio.h\"\n#include \"parse.h\"\n#include \"numarray.h\"\n\n#define EOL_COLUMN -1\n\n/* args (startLine): [absolute]\n * args (startColumn): [buggy]\n * args (endLine): [absolute]\n * args (endColumn): [absolute]\n * args (sourceLineOffset): [buggy]\n */\n/* parser can be NULL; give a name with promiseUpdateLanguage()\n * when the name can be determined. */\nint  makePromise   (const char *parser,\n\t\t    unsigned long startLine, long startColumn,\n\t\t    unsigned long endLine, long endColumn,\n\t\t    unsigned long sourceLineOffset);\n\n/* Fill the line with white spaces.\n   The callee takes the ownership of lines. */\nvoid promiseAttachLineFiller (int promise, ulongArray *lines);\n\nvoid promiseUpdateLanguage  (int promise, langType lang);\n\n#endif\t/* CTAGS_MAIN_PROMISE_H */\n"
  },
  {
    "path": "main/promise_p.h",
    "content": "/*\n *\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_PROMISE_PRIVATE_H\n#define CTAGS_MAIN_PROMISE_PRIVATE_H\n\n#include \"general.h\"\n\nbool forcePromises (void);\nvoid breakPromisesAfter (int promise);\nint getLastPromise (void);\n\n/* args (startLine): [buggy]\n * args (startColumn): [buggy]\n * args (endLine): [buggy]\n * args (endColumn): [buggy]\n */\nvoid runModifiers (int promise,\n\t\t\t\t   unsigned long startLine, long startColumn,\n\t\t\t\t   unsigned long endLine, long endColumn,\n\t\t\t\t   unsigned char *input,\n\t\t\t\t   size_t size);\n\n#endif\t/* CTAGS_MAIN_PROMISE_PRIVATE_H */\n"
  },
  {
    "path": "main/ptag.c",
    "content": "/*\n *\n *  Copyright (c) 1996-2002, Darren Hiebert\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#include \"general.h\"  /* must always come first */\n\n#include \"colprint_p.h\"\n#include \"ctags.h\"\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"options_p.h\"\n#include \"parse_p.h\"\n#include \"ptag_p.h\"\n#include \"routines_p.h\"\n#include \"writer_p.h\"\n#include <string.h>\n\n\nstatic bool ptagMakeFormat (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\tconst void *data CTAGS_ATTR_UNUSED)\n{\n\tchar format [11];\n\tconst char *formatComment = \"unknown format\";\n\tconst optionValues *opt = data;\n\n\tsprintf (format, \"%u\", opt->tagFileFormat);\n\tif (opt->tagFileFormat == 1)\n\t\tformatComment = \"original ctags format\";\n\telse if (opt->tagFileFormat == 2)\n\t\tformatComment =\n\t\t\t\"extended format; --format=1 will not append ;\\\" to lines\";\n\treturn writePseudoTag (desc, format, formatComment, NULL);\n}\n\nstatic bool ptagMakeHowSorted (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t   const void *data CTAGS_ATTR_UNUSED)\n{\n\tconst optionValues *opt = data;\n\treturn writePseudoTag (desc,\n\t\t\t       opt->sorted == SO_FOLDSORTED ? \"2\" :\n\t\t\t       (opt->sorted == SO_SORTED ? \"1\" : \"0\"),\n\t\t\t       \"0=unsorted, 1=sorted, 2=foldcase\",\n\t\t\t       NULL);\n}\n\nstatic bool ptagMakeAuthor (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\tconst void *data CTAGS_ATTR_UNUSED)\n{\n\treturn writePseudoTag (desc,\n\t\t\t\t\t\t   AUTHOR_NAME,  \"\", NULL);\n}\n\nstatic bool ptagMakeProgName (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t  const void *data CTAGS_ATTR_UNUSED)\n{\n\treturn writePseudoTag (desc,\n\t\t\t\t\t\t   PROGRAM_NAME,  \"Derived from Exuberant Ctags\", NULL);\n}\n\nstatic bool ptagMakeProgURL (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t const void *data CTAGS_ATTR_UNUSED)\n{\n\treturn writePseudoTag (desc,\n\t\t\t\t\t\t   PROGRAM_URL, \"official site\", NULL);\n}\n\nstatic bool ptagMakeProgVersion (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t const void *data CTAGS_ATTR_UNUSED)\n{\n\tconst char* repoinfo = ctags_repoinfo? ctags_repoinfo: \"\";\n\treturn writePseudoTag (desc, PROGRAM_VERSION, repoinfo, NULL);\n}\n\n#ifdef HAVE_ICONV\nstatic bool ptagMakeFileEncoding (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t  const void *data)\n{\n\tconst optionValues *opt = data;\n\tif (! opt->outputEncoding)\n\t\treturn false;\n\n\treturn writePseudoTag (desc, opt->outputEncoding, \"\", NULL);\n}\n#endif\n\nstatic bool ptagMakeKindSeparators (ptagDesc *desc, langType language,\n\t\t\t\t\t\t\t\t\tconst void *data CTAGS_ATTR_UNUSED)\n{\n\treturn makeKindSeparatorsPseudoTags (language, desc);\n}\n\nstatic bool ptagMakeKindDescriptions (ptagDesc *desc, langType language,\n\t\t\t\t\t\t\t\t\t  const void *data CTAGS_ATTR_UNUSED)\n{\n\treturn makeKindDescriptionsPseudoTags (language, desc);\n}\n\nstatic bool ptagMakeFieldDescriptions (ptagDesc *desc, langType language,\n\t\t\t\t\t\t\t\t\t   const void *data CTAGS_ATTR_UNUSED)\n{\n\treturn makeFieldDescriptionsPseudoTags (language, desc);\n}\n\nstatic bool ptagMakeExtraDescriptions (ptagDesc *desc, langType language,\n\t\t\t\t\t\t\t\t\t   const void *data CTAGS_ATTR_UNUSED)\n{\n\treturn makeExtraDescriptionsPseudoTags (language, desc);\n}\n\nstatic bool ptagMakeRoleDescriptions (ptagDesc *desc, langType language,\n\t\t\t\t\t\t\t\t\t  const void *data CTAGS_ATTR_UNUSED)\n{\n\treturn makeRoleDescriptionsPseudoTags (language, desc);\n}\n\nstatic bool ptagMakeProcCwd (ptagDesc *desc, langType language,\n\t\t\t\t\t\t\t\t\t   const void *data CTAGS_ATTR_UNUSED)\n{\n\treturn writePseudoTag (desc, CurrentDirectory, \"\", NULL);\n}\n\nstatic bool ptagMakeParserVersion(ptagDesc *desc, langType language,\n\t\t\t\t\t\t\t\t  const void *data CTAGS_ATTR_UNUSED)\n{\n\tchar buf[32];\t\t\t/* 2^32 '.' 2^32 '\\0' */\n\tsnprintf (buf, sizeof(buf), \"%u.%u\",\n\t\t\t  getLanguageVersionCurrent(language),\n\t\t\t  getLanguageVersionAge(language));\n\tconst char *name = getLanguageName(language);\n\treturn writePseudoTag (desc, buf, \"current.age\", name);\n}\n\nstatic bool ptagMakeOutputVersion (ptagDesc *desc, langType language,\n\t\t\t\t\t\t\t\t   const void *data CTAGS_ATTR_UNUSED)\n{\n\tchar buf[32];\t\t\t/* 2^32 '.' 2^32 '\\0' */\n\tsnprintf (buf, sizeof(buf), \"%u.%u\",\n\t\t\t  OUTPUT_VERSION_CURRENT, OUTPUT_VERSION_AGE);\n\treturn writePseudoTag (desc, buf, \"current.age\", NULL);\n}\n\nstatic ptagDesc ptagDescs [] = {\n\t{\n\t  /* The prefix is not \"TAG_\".\n\t     Only --output-format=json use this ptag. */\n\t  false, \"JSON_OUTPUT_VERSION\",\n\t  \"the version of json output stream format\",\n\t  ptagMakeJsonOutputVersion,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_FILE_FORMAT\",\n\t  \"the version of tags file format\",\n\t  ptagMakeFormat,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_FILE_SORTED\",\n\t  \"how tags are sorted\",\n\t  ptagMakeHowSorted,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_PROGRAM_AUTHOR\",\n\t  \"the author of this ctags implementation\",\n\t  ptagMakeAuthor,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_PROGRAM_NAME\",\n\t  \"the name of this ctags implementation\",\n\t  ptagMakeProgName,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_PROGRAM_URL\",\n\t  \"the official site URL of this ctags implementation\",\n\t  ptagMakeProgURL,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_PROGRAM_VERSION\",\n\t  \"the version of this ctags implementation\",\n\t  ptagMakeProgVersion,\n\t  PTAGF_COMMON },\n#ifdef HAVE_ICONV\n\t{ true, \"TAG_FILE_ENCODING\",\n\t  \"the encoding used in output tags file\",\n\t  ptagMakeFileEncoding,\n\t  PTAGF_COMMON },\n#endif\n\t{ false, \"TAG_KIND_SEPARATOR\",\n\t  \"the separators used in kinds\",\n\t  ptagMakeKindSeparators,\n\t  PTAGF_PARSER },\n\t{ true, \"TAG_KIND_DESCRIPTION\",\n\t  \"the letters, names and descriptions of enabled kinds in the language\",\n\t  ptagMakeKindDescriptions,\n\t  PTAGF_PARSER },\n\t{ true, \"TAG_FIELD_DESCRIPTION\",\n\t  \"the names and descriptions of enabled fields\",\n\t  ptagMakeFieldDescriptions,\n\t  PTAGF_COMMON|PTAGF_PARSER },\n\t{ true, \"TAG_EXTRA_DESCRIPTION\",\n\t  \"the names and descriptions of enabled extras\",\n\t  ptagMakeExtraDescriptions,\n\t  PTAGF_COMMON|PTAGF_PARSER },\n\t{ true, \"TAG_ROLE_DESCRIPTION\",\n\t  \"the names and descriptions of enabled roles\",\n\t  ptagMakeRoleDescriptions,\n\t  PTAGF_PARSER,\n\t  .jsonObjectKey = \"kindName\" },\n\t{ true, \"TAG_OUTPUT_MODE\",\n\t  \"the output mode: u-ctags or e-ctags\",\n\t  ptagMakeCtagsOutputMode,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_OUTPUT_FILESEP\",\n\t  \"the separator used in file name (slash or backslash)\",\n\t  ptagMakeCtagsOutputFilesep,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_PATTERN_LENGTH_LIMIT\",\n\t  \"the limit of pattern length\",\n\t  ptagMakePatternLengthLimit,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_PROC_CWD\",\n\t  \"the current working directory of the tags generator\",\n\t  ptagMakeProcCwd,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_OUTPUT_EXCMD\",\n\t  \"the excmd: number, pattern, mixed, or combine\",\n\t  ptagMakeCtagsOutputExcmd,\n\t  PTAGF_COMMON },\n\t{ true, \"TAG_PARSER_VERSION\",\n\t  \"the version of the parser (current.age)\",\n\t  ptagMakeParserVersion,\n\t  PTAGF_PARSER },\n\t{ true, \"TAG_OUTPUT_VERSION\",\n\t  \"the version of the output interface (current.age)\",\n\t  ptagMakeOutputVersion,\n\t  PTAGF_COMMON },\n};\n\nextern bool makePtagIfEnabled (ptagType type, langType language, const void *data)\n{\n\tptagDesc *desc;\n\n\tAssert (0 <= type && type < PTAG_COUNT);\n\n\tdesc = ptagDescs + type;\n\tif (desc->enabled)\n\t\treturn desc->makeTag (desc, language, data);\n\telse\n\t\treturn false;\n}\n\nextern bool isPtagEnabled (ptagType type)\n{\n\tptagDesc *desc;\n\n\tAssert (0 <= type && type < PTAG_COUNT);\n\n\tdesc = ptagDescs + type;\n\treturn desc->enabled;\n\n}\n\nextern bool enablePtag (ptagType type, bool state)\n{\n\tbool oldstate;\n\tptagDesc *desc;\n\n\tAssert (0 <= type && type < PTAG_COUNT);\n\n\tdesc = ptagDescs + type;\n\toldstate = desc->enabled;\n\tdesc->enabled = state;\n\treturn oldstate;\n}\n\nextern ptagDesc* getPtagDesc (ptagType type)\n{\n\tif (type == PTAG_UNKNOWN\n\t    || type >= PTAG_COUNT)\n\t\treturn NULL;\n\n\treturn ptagDescs + type;\n}\n\nextern ptagType getPtagTypeForName (const char *name)\n{\n\tint i;\n\n\tAssert (name);\n\tfor (i = 0; i < PTAG_COUNT; i++)\n\t\tif (strcmp (ptagDescs [i].name, name) == 0)\n\t\t\treturn i;\n\treturn PTAG_UNKNOWN;\n}\n\nextern bool isPtagCommonInParsers  (ptagType type)\n{\n\tptagDesc* pdesc = getPtagDesc (type);\n\treturn pdesc->flags & PTAGF_COMMON;\n}\n\nextern bool isPtagParserSpecific (ptagType type)\n{\n\tptagDesc* pdesc = getPtagDesc (type);\n\treturn pdesc->flags & PTAGF_PARSER;\n}\n\nstatic int ptagCompare (struct colprintLine *a, struct colprintLine *b)\n{\n\tconst char *a_name = colprintLineGetColumn (a, 0);\n\tconst char *b_name = colprintLineGetColumn (b, 0);\n\treturn strcmp(a_name, b_name);\n}\n\nextern void printPtags (bool withListHeader, bool machinable, FILE *fp)\n{\n\tstruct colprintTable *table = colprintTableNew (\"L:NAME\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"L:ENABLED\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"R:VER\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"L:DESCRIPTION\",\n\t\t\t\t\t\t\t\t\t\t\t\t\tNULL);\n\tfor (unsigned int i = 0; i < PTAG_COUNT; i++)\n\t{\n\t\tstruct colprintLine *line = colprintTableGetNewLine (table);\n\t\tcolprintLineAppendColumnCString (line, ptagDescs[i].name);\n\t\tcolprintLineAppendColumnCString (line, ptagDescs[i].enabled\n\t\t\t\t\t\t\t\t\t\t ? \"on\"\n\t\t\t\t\t\t\t\t\t\t : \"off\");\n\t\tcolprintLineAppendColumnVersion (line, ptagDescs[i].version);\n\t\tcolprintLineAppendColumnCString (line, ptagDescs[i].description);\n\t}\n\n\tcolprintTableSort (table, ptagCompare);\n\tcolprintTablePrint (table, 0, withListHeader, machinable, fp);\n\tcolprintTableDelete (table);\n}\n"
  },
  {
    "path": "main/ptag_p.h",
    "content": "/*\n *\n *  Copyright (c) 2016, Red Hat, Inc.\n *  Copyright (c) 2016, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_PTAG_PRIVATE_H\n#define CTAGS_MAIN_PTAG_PRIVATE_H\n\n#include \"general.h\"\n#include \"types.h\"\n\n#define PSEUDO_TAG_PREFIX       \"!_\"\n#define PSEUDO_TAG_SEPARATOR    \"!\"\n\ntypedef enum ePtagType { /* pseudo tag content control */\n\tPTAG_UNKNOWN = -1,\n\t/* Only --output-format=json use this ptag.\n\t   Applications of the output may expect this comes first in the output. */\n\tPTAG_JSON_OUTPUT_VERSION,\n\n\tPTAG_FILE_FORMAT,\n\tPTAG_FILE_SORTED,\n\tPTAG_PROGRAM_AUTHOR,\n\tPTAG_PROGRAM_NAME,\n\tPTAG_PROGRAM_URL,\n\tPTAG_PROGRAM_VERSION,\n#ifdef HAVE_ICONV\n\tPTAG_FILE_ENCODING,\n#endif\n\tPTAG_KIND_SEPARATOR,\n\tPTAG_KIND_DESCRIPTION,\n\tPTAG_FIELD_DESCRIPTION,\n\tPTAG_EXTRA_DESCRIPTION,\n\tPTAG_ROLE_DESCRIPTION,\n\tPTAG_OUTPUT_MODE,\n\tPTAG_OUTPUT_FILESEP,\n\tPTAG_PATTERN_TRUNCATION,\n\tPTAG_PROC_CWD,\n\tPTAG_OUTPUT_EXCMD,\n\tPTAG_PARSER_VERSION,\n\tPTAG_OUTPUT_VERSION,\n\tPTAG_COUNT\n} ptagType;\n\ntypedef enum ePtagFlag {\n\t/* use isPtagCommonInParsers() for testing. */\n\tPTAGF_COMMON = 1 << 0,\n\t/* use isPtagParserSpecific for testing.\n\t * PSEUDO_TAG_SEPARATOR is used for printing. */\n\tPTAGF_PARSER = 1 << 1,\n} ptagFlag;\n\nstruct sPtagDesc {\n\tbool enabled;\n\tconst char* name;\n\tconst char* description;  /* displayed in --list-pseudo-tags output */\n\n\t/* For making ptags for common in parsers, LANG_IGNOR is for the second\n\t * argument and a pointer for optionValues type value for the third argument\n\t * are passed.\n\t *\n\t * For parser specific ptags, the pointer for parserObject\n\t * of the parser is passed as the thrid argument.\n\t */\n\tbool (* makeTag) (ptagDesc *, langType, const void *);\n\n\tptagFlag flags;\n\n\t/* See writer-json.c */\n\tconst char *jsonObjectKey;\n\n\tunsigned int version;\n};\n\nextern bool makePtagIfEnabled (ptagType type, langType language, const void *data);\nextern ptagDesc* getPtagDesc (ptagType type);\nextern ptagType  getPtagTypeForName (const char *name);\nextern void printPtags (bool withListHeader, bool machinable, FILE *fp);\nextern bool isPtagEnabled (ptagType type);\nextern bool isPtagCommonInParsers (ptagType type);\nextern bool isPtagParserSpecific (ptagType type);\nextern bool enablePtag (ptagType type, bool state);\n\n#endif\t/* CTAGS_MAIN_PTAG_PRIVATE_H */\n"
  },
  {
    "path": "main/ptrarray.c",
    "content": "/*\n*   Copyright (c) 1999-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions managing resizable pointer arrays.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <stdlib.h>\n\n#include \"debug.h\"\n#include \"ptrarray.h\"\n#include \"routines.h\"\n#include \"sort_r.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\n\nstruct sPtrArray {\n\tunsigned int max;\n\tunsigned int count;\n\tvoid **array;\n\tint refcount;\n\tptrArrayDeleteFunc deleteFunc;\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nextern ptrArray *ptrArrayNew (ptrArrayDeleteFunc deleteFunc)\n{\n\tptrArray* const result = xMalloc (1, ptrArray);\n\tresult->max = 8;\n\tresult->count = 0;\n\tresult->array = xMalloc (result->max, void*);\n\tresult->refcount = 1;\n\tresult->deleteFunc = deleteFunc;\n\treturn result;\n}\n\nextern unsigned int ptrArrayAdd (ptrArray *const current, void *ptr)\n{\n\tAssert (current != NULL);\n\tif (current->count == current->max)\n\t{\n\t\tcurrent->max *= 2;\n\t\tcurrent->array = xRealloc (current->array, current->max, void*);\n\t}\n\tcurrent->array [current->count] = ptr;\n\treturn current->count++;\n}\n\nextern bool ptrArrayUpdate (ptrArray *const current,\n\t\t\t\t\t\t\tunsigned int indx, void *ptr, void *padding)\n{\n\tAssert (current != NULL);\n\tif (current->count > indx)\n\t{\n\t\tvoid *r = current->array [indx];\n\t\tif (current->deleteFunc)\n\t\t\tcurrent->deleteFunc (r);\n\t\tcurrent->array [indx] = ptr;\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\tunsigned int c = indx - current->count;\n\t\tfor (unsigned int i = 0; i < c; i++)\n\t\t\tptrArrayAdd (current, padding);\n\t\tptrArrayAdd (current, ptr);\n\t\treturn false;\n\t}\n\n}\nextern void *ptrArrayRemoveLast (ptrArray *const current)\n{\n\tAssert (current != NULL);\n\tAssert (current->count > 0);\n\tvoid *r = ptrArrayLast (current);\n\t--current->count;\n\treturn r;\n}\n\nextern void  ptrArrayDeleteLastInBatch (ptrArray *const current, unsigned int count)\n{\n\tAssert (current != NULL);\n\tAssert (current->count >= count);\n\twhile (count > 0)\n\t{\n\t\tvoid *r = ptrArrayLast (current);\n\t\tif (current->deleteFunc)\n\t\t\tcurrent->deleteFunc (r);\n\t\t--current->count;\n\t\t--count;\n\t}\n}\n\n/* Combine array `from' into `current', deleting `from' */\nextern void ptrArrayCombine (ptrArray *const current, ptrArray *const from)\n{\n\tunsigned int i;\n\tAssert (current != NULL);\n\tAssert (from != NULL);\n\tfor (i = 0  ;  i < from->count  ;  ++i)\n\t\tptrArrayAdd (current, from->array [i]);\n\tfrom->count = 0;\n\tptrArrayDelete (from);\n}\n\nextern unsigned int ptrArrayCount (const ptrArray *const current)\n{\n\tAssert (current != NULL);\n\treturn current->count;\n}\n\nextern void* ptrArrayItem (const ptrArray *const current, const unsigned int indx)\n{\n\tAssert (current != NULL);\n\tAssert (current->count > indx);\n\treturn current->array [indx];\n}\n\nextern void* ptrArrayItemFromLast (const ptrArray *const current, const unsigned int indx)\n{\n\tAssert (current != NULL);\n\tAssert (current->count > indx);\n\treturn current->array [current->count - 1 - indx];\n}\n\nextern void ptrArrayClear (ptrArray *const current)\n{\n\tAssert (current != NULL);\n\tif (current->deleteFunc)\n\t{\n\t\tunsigned int i;\n\t\tfor (i = 0  ;  i < current->count  ;  ++i)\n\t\t\tcurrent->deleteFunc (current->array [i]);\n\t}\n\tcurrent->count = 0;\n}\n\nextern void ptrArrayRef (ptrArray *const current)\n{\n\tcurrent->refcount++;\n}\n\nextern void ptrArrayUnref (ptrArray *const current)\n{\n\tif (current != NULL)\n\t{\n\t\tcurrent->refcount--;\n\t\tif (current->refcount > 0)\n\t\t\treturn;\n\t\tAssert(current->refcount == 0);\n\n\t\tptrArrayClear (current);\n\t\teFree (current->array);\n\t\teFree (current);\n\t}\n}\n\nextern bool ptrArrayHasTest (const ptrArray *const current,\n\t\t\t\t  bool (*test)(const void *ptr, void *userData),\n\t\t\t\t  void *userData)\n{\n\tbool result = false;\n\tunsigned int i;\n\tAssert (current != NULL);\n\tfor (i = 0  ;  ! result  &&  i < current->count  ;  ++i)\n\t\tresult = (*test)(current->array [i], userData);\n\treturn result;\n}\n\nstatic bool ptrEq (const void *ptr, void *userData)\n{\n\treturn (ptr == userData);\n}\n\nextern bool ptrArrayHas (const ptrArray *const current, void *ptr)\n{\n\treturn ptrArrayHasTest (current, ptrEq, ptr);\n}\n\nextern void ptrArrayReverse (const ptrArray *const current)\n{\n\tunsigned int i, j;\n\tvoid *tmp;\n\n\tAssert (current != NULL);\n\tfor (i = 0, j = current->count - 1 ; i <  (current->count / 2); ++i, --j)\n\t{\n\t\ttmp = current->array[i];\n\t\tcurrent->array[i] = current->array[j];\n\t\tcurrent->array[j] = tmp;\n\t}\n}\n\nextern void ptrArrayDeleteItem (ptrArray* const current, unsigned int indx)\n{\n\tvoid *ptr = current->array[indx];\n\n\tif (current->deleteFunc)\n\t\tcurrent->deleteFunc (ptr);\n\n\tmemmove (current->array + indx, current->array + indx + 1,\n\t\t\t(current->count - indx - 1) * sizeof (*current->array));\n\t--current->count;\n}\n\nextern void*ptrArrayRemoveItem (ptrArray* const current, unsigned int indx)\n{\n\tvoid *ptr = current->array[indx];\n\n\tmemmove (current->array + indx, current->array + indx + 1,\n\t\t\t(current->count - indx - 1) * sizeof (*current->array));\n\t--current->count;\n\n\treturn ptr;\n}\n\nextern void ptrArrayInsertItem (ptrArray* const current, unsigned int indx, void *ptr)\n{\n\tAssert (current != NULL);\n\tif (current->count == current->max)\n\t{\n\t\tcurrent->max *= 2;\n\t\tcurrent->array = xRealloc (current->array, current->max, void*);\n\t}\n\n\tmemmove (current->array + indx + 1, current->array + indx,\n\t\t\t (current->count - indx) * sizeof (*current->array));\n\tcurrent->array[indx] = ptr;\n\t++current->count;\n}\n\nstatic int ptrArraySortCompare(const void *a0, const void *b0, void *compare_fn)\n{\n\tint (*ptrArraySortCompareVar)(const void *, const void *) = compare_fn;\n\n\tvoid *const *a = (void *const *)a0;\n\tvoid *const *b = (void *const *)b0;\n\n\treturn ptrArraySortCompareVar (*a, *b);\n}\n\nextern void ptrArraySort (ptrArray *const current, int (*compare)(const void *, const void *))\n{\n\tsort_r (current->array, current->count, sizeof (void *), ptrArraySortCompare, compare);\n}\n\nstruct ptrArraySortRData\n{\n\tint (*compare_fn)(const void *, const void *, void *);\n\tvoid *userData;\n};\n\nstatic int ptrArraySortCompareR (const void *a0, const void *b0, void *data)\n{\n\tstruct ptrArraySortRData *rdata = data;\n\n\tvoid *const *a = (void *const *)a0;\n\tvoid *const *b = (void *const *)b0;\n\n\treturn rdata->compare_fn (*a, *b, rdata->userData);\n}\n\nextern void ptrArraySortR (ptrArray *const current, int (*compare)(const void *, const void *, void *),\n\t\t\t\t\t\t   void *userData)\n{\n\tstruct ptrArraySortRData data = {\n\t\t.compare_fn = compare,\n\t\t.userData = userData,\n\t};\n\tsort_r (current->array, current->count, sizeof (void *), ptrArraySortCompareR, &data);\n}\n"
  },
  {
    "path": "main/ptrarray.h",
    "content": "/*\n*   Copyright (c) 1999-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines external interface to resizable pointer arrays.\n*/\n#ifndef CTAGS_MAIN_PTRARRAY_H\n#define CTAGS_MAIN_PTRARRAY_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"types.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\nstruct sPtrArray;\ntypedef struct sPtrArray ptrArray;\n\ntypedef void (*ptrArrayDeleteFunc) (void *data);\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern ptrArray *ptrArrayNew (ptrArrayDeleteFunc deleteFunc);\nextern unsigned int ptrArrayAdd (ptrArray *const current, void *ptr);\nextern bool ptrArrayUpdate (ptrArray *const current, unsigned int indx, void *ptr, void *padding);\nextern void *ptrArrayRemoveLast (ptrArray *const current);\n#define ptrArrayDeleteLast(A) ptrArrayDeleteLastInBatch(A, 1)\nextern void  ptrArrayDeleteLastInBatch (ptrArray *const current, unsigned int count);\nextern void ptrArrayCombine (ptrArray *const current, ptrArray *const from);\nextern void ptrArrayClear (ptrArray *const current);\nextern unsigned int ptrArrayCount (const ptrArray *const current);\n#define ptrArrayIsEmpty(A) (ptrArrayCount(A) == 0)\nextern void* ptrArrayItem (const ptrArray *const current, const unsigned int indx);\nextern void* ptrArrayItemFromLast (const ptrArray *const current, const unsigned int indx);\n#define ptrArrayLast(A) ptrArrayItemFromLast(A, 0)\nextern void ptrArrayUnref (ptrArray *const current);\n#define ptrArrayDelete ptrArrayUnref\nextern void ptrArrayRef(ptrArray *const current);\nextern bool ptrArrayHasTest (const ptrArray *const current,\n\t\t\t\t  bool (*test)(const void *ptr, void *userData),\n\t\t\t\t  void *userData);\nextern bool ptrArrayHas (const ptrArray *const current, void *ptr);\nextern void ptrArrayReverse (const ptrArray *const current);\nextern void ptrArrayDeleteItem (ptrArray* const current, unsigned int indx);\nextern void*ptrArrayRemoveItem (ptrArray* const current, unsigned int indx);\nextern void ptrArrayInsertItem (ptrArray* const current, unsigned int indx, void *ptr);\n\nextern void ptrArraySort (ptrArray *const current, int (*compare)(const void *, const void *));\nextern void ptrArraySortR (ptrArray *const current, int (*compare)(const void *, const void *, void *),\n\t\t\t\t\t\t   void *userData);\n\n#endif  /* CTAGS_MAIN_PTRARRAY_H */\n"
  },
  {
    "path": "main/rbtree.c",
    "content": "/*\n  Red Black Trees\n  (C) 1999  Andrea Arcangeli <andrea@suse.de>\n  (C) 2002  David Woodhouse <dwmw2@infradead.org>\n  (C) 2012  Michel Lespinasse <walken@google.com>\n\n  This program is free software; you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation; either version 2 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  linux/lib/rbtree.c\n*/\n\n#include \"general.h\"\n#include <stdbool.h>\n#include \"rbtree_augmented.h\"\n#include \"inline.h\"\n\n/*\n * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree\n *\n *  1) A node is either red or black\n *  2) The root is black\n *  3) All leaves (NULL) are black\n *  4) Both children of every red node are black\n *  5) Every simple path from root to leaves contains the same number\n *     of black nodes.\n *\n *  4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two\n *  consecutive red nodes in a path and every red node is therefore followed by\n *  a black. So if B is the number of black nodes on every simple path (as per\n *  5), then the longest possible path due to 4 is 2B.\n *\n *  We shall indicate color with case, where black nodes are uppercase and red\n *  nodes will be lowercase. Unknown color nodes shall be drawn as red within\n *  parentheses and have some accompanying text comment.\n */\n\nCTAGS_INLINE void rb_set_black(struct rb_node *rb)\n{\n\trb->__rb_parent_color |= RB_BLACK;\n}\n\nCTAGS_INLINE struct rb_node *rb_red_parent(struct rb_node *red)\n{\n\treturn (struct rb_node *)red->__rb_parent_color;\n}\n\n/*\n * Helper function for rotations:\n * - old's parent and color get assigned to new\n * - old gets assigned new as a parent and 'color' as a color.\n */\nCTAGS_INLINE void\n__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,\n\t\t\tstruct rb_root *root, int color)\n{\n\tstruct rb_node *parent = rb_parent(old);\n\tnew->__rb_parent_color = old->__rb_parent_color;\n\trb_set_parent_color(old, new, color);\n\t__rb_change_child(old, new, parent, root);\n}\n\nCTAGS_INLINE void\n__rb_insert(struct rb_node *node, struct rb_root *root,\n\t\tvoid (*augment_rotate)(struct rb_node *old, struct rb_node *new))\n{\n\tstruct rb_node *parent = rb_red_parent(node), *gparent, *tmp;\n\n\twhile (true) {\n\t\t/*\n\t\t * Loop invariant: node is red\n\t\t *\n\t\t * If there is a black parent, we are done.\n\t\t * Otherwise, take some corrective action as we don't\n\t\t * want a red root or two consecutive red nodes.\n\t\t */\n\t\tif (!parent) {\n\t\t\trb_set_parent_color(node, NULL, RB_BLACK);\n\t\t\tbreak;\n\t\t} else if (rb_is_black(parent))\n\t\t\tbreak;\n\n\t\tgparent = rb_red_parent(parent);\n\n\t\ttmp = gparent->rb_right;\n\t\tif (parent != tmp) {\t/* parent == gparent->rb_left */\n\t\t\tif (tmp && rb_is_red(tmp)) {\n\t\t\t\t/*\n\t\t\t\t * Case 1 - color flips\n\t\t\t\t *\n\t\t\t\t *       G            g\n\t\t\t\t *      / \\          / \\\n\t\t\t\t *     p   u  -->   P   U\n\t\t\t\t *    /            /\n\t\t\t\t *   n            n\n\t\t\t\t *\n\t\t\t\t * However, since g's parent might be red, and\n\t\t\t\t * 4) does not allow this, we need to recurse\n\t\t\t\t * at g.\n\t\t\t\t */\n\t\t\t\trb_set_parent_color(tmp, gparent, RB_BLACK);\n\t\t\t\trb_set_parent_color(parent, gparent, RB_BLACK);\n\t\t\t\tnode = gparent;\n\t\t\t\tparent = rb_parent(node);\n\t\t\t\trb_set_parent_color(node, parent, RB_RED);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttmp = parent->rb_right;\n\t\t\tif (node == tmp) {\n\t\t\t\t/*\n\t\t\t\t * Case 2 - left rotate at parent\n\t\t\t\t *\n\t\t\t\t *      G             G\n\t\t\t\t *     / \\           / \\\n\t\t\t\t *    p   U  -->    n   U\n\t\t\t\t *     \\           /\n\t\t\t\t *      n         p\n\t\t\t\t *\n\t\t\t\t * This still leaves us in violation of 4), the\n\t\t\t\t * continuation into Case 3 will fix that.\n\t\t\t\t */\n\t\t\t\tparent->rb_right = tmp = node->rb_left;\n\t\t\t\tnode->rb_left = parent;\n\t\t\t\tif (tmp)\n\t\t\t\t\trb_set_parent_color(tmp, parent,\n\t\t\t\t\t\t\t\tRB_BLACK);\n\t\t\t\trb_set_parent_color(parent, node, RB_RED);\n\t\t\t\taugment_rotate(parent, node);\n\t\t\t\tparent = node;\n\t\t\t\ttmp = node->rb_right;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * Case 3 - right rotate at gparent\n\t\t\t *\n\t\t\t *        G           P\n\t\t\t *       / \\         / \\\n\t\t\t *      p   U  -->  n   g\n\t\t\t *     /                 \\\n\t\t\t *    n                   U\n\t\t\t */\n\t\t\tgparent->rb_left = tmp;  /* == parent->rb_right */\n\t\t\tparent->rb_right = gparent;\n\t\t\tif (tmp)\n\t\t\t\trb_set_parent_color(tmp, gparent, RB_BLACK);\n\t\t\t__rb_rotate_set_parents(gparent, parent, root, RB_RED);\n\t\t\taugment_rotate(gparent, parent);\n\t\t\tbreak;\n\t\t} else {\n\t\t\ttmp = gparent->rb_left;\n\t\t\tif (tmp && rb_is_red(tmp)) {\n\t\t\t\t/* Case 1 - color flips */\n\t\t\t\trb_set_parent_color(tmp, gparent, RB_BLACK);\n\t\t\t\trb_set_parent_color(parent, gparent, RB_BLACK);\n\t\t\t\tnode = gparent;\n\t\t\t\tparent = rb_parent(node);\n\t\t\t\trb_set_parent_color(node, parent, RB_RED);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttmp = parent->rb_left;\n\t\t\tif (node == tmp) {\n\t\t\t\t/* Case 2 - right rotate at parent */\n\t\t\t\tparent->rb_left = tmp = node->rb_right;\n\t\t\t\tnode->rb_right = parent;\n\t\t\t\tif (tmp)\n\t\t\t\t\trb_set_parent_color(tmp, parent,\n\t\t\t\t\t\t\t\tRB_BLACK);\n\t\t\t\trb_set_parent_color(parent, node, RB_RED);\n\t\t\t\taugment_rotate(parent, node);\n\t\t\t\tparent = node;\n\t\t\t\ttmp = node->rb_left;\n\t\t\t}\n\n\t\t\t/* Case 3 - left rotate at gparent */\n\t\t\tgparent->rb_right = tmp;  /* == parent->rb_left */\n\t\t\tparent->rb_left = gparent;\n\t\t\tif (tmp)\n\t\t\t\trb_set_parent_color(tmp, gparent, RB_BLACK);\n\t\t\t__rb_rotate_set_parents(gparent, parent, root, RB_RED);\n\t\t\taugment_rotate(gparent, parent);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/*\n * Inline version for rb_erase() use - we want to be able to inline\n * and eliminate the dummy_rotate callback there\n */\nCTAGS_INLINE void\n____rb_erase_color(struct rb_node *parent, struct rb_root *root,\n\tvoid (*augment_rotate)(struct rb_node *old, struct rb_node *new))\n{\n\tstruct rb_node *node = NULL, *sibling, *tmp1, *tmp2;\n\n\twhile (true) {\n\t\t/*\n\t\t * Loop invariants:\n\t\t * - node is black (or NULL on first iteration)\n\t\t * - node is not the root (parent is not NULL)\n\t\t * - All leaf paths going through parent and node have a\n\t\t *   black node count that is 1 lower than other leaf paths.\n\t\t */\n\t\tsibling = parent->rb_right;\n\t\tif (node != sibling) {\t/* node == parent->rb_left */\n\t\t\tif (rb_is_red(sibling)) {\n\t\t\t\t/*\n\t\t\t\t * Case 1 - left rotate at parent\n\t\t\t\t *\n\t\t\t\t *     P               S\n\t\t\t\t *    / \\             / \\\n\t\t\t\t *   N   s    -->    p   Sr\n\t\t\t\t *      / \\         / \\\n\t\t\t\t *     Sl  Sr      N   Sl\n\t\t\t\t */\n\t\t\t\tparent->rb_right = tmp1 = sibling->rb_left;\n\t\t\t\tsibling->rb_left = parent;\n\t\t\t\trb_set_parent_color(tmp1, parent, RB_BLACK);\n\t\t\t\t__rb_rotate_set_parents(parent, sibling, root,\n\t\t\t\t\t\t\tRB_RED);\n\t\t\t\taugment_rotate(parent, sibling);\n\t\t\t\tsibling = tmp1;\n\t\t\t}\n\t\t\ttmp1 = sibling->rb_right;\n\t\t\tif (!tmp1 || rb_is_black(tmp1)) {\n\t\t\t\ttmp2 = sibling->rb_left;\n\t\t\t\tif (!tmp2 || rb_is_black(tmp2)) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Case 2 - sibling color flip\n\t\t\t\t\t * (p could be either color here)\n\t\t\t\t\t *\n\t\t\t\t\t *    (p)           (p)\n\t\t\t\t\t *    / \\           / \\\n\t\t\t\t\t *   N   S    -->  N   s\n\t\t\t\t\t *      / \\           / \\\n\t\t\t\t\t *     Sl  Sr        Sl  Sr\n\t\t\t\t\t *\n\t\t\t\t\t * This leaves us violating 5) which\n\t\t\t\t\t * can be fixed by flipping p to black\n\t\t\t\t\t * if it was red, or by recursing at p.\n\t\t\t\t\t * p is red when coming from Case 1.\n\t\t\t\t\t */\n\t\t\t\t\trb_set_parent_color(sibling, parent,\n\t\t\t\t\t\t\t\tRB_RED);\n\t\t\t\t\tif (rb_is_red(parent))\n\t\t\t\t\t\trb_set_black(parent);\n\t\t\t\t\telse {\n\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\tparent = rb_parent(node);\n\t\t\t\t\t\tif (parent)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t/*\n\t\t\t\t * Case 3 - right rotate at sibling\n\t\t\t\t * (p could be either color here)\n\t\t\t\t *\n\t\t\t\t *   (p)           (p)\n\t\t\t\t *   / \\           / \\\n\t\t\t\t *  N   S    -->  N   Sl\n\t\t\t\t *     / \\             \\\n\t\t\t\t *    sl  Sr            s\n\t\t\t\t *                       \\\n\t\t\t\t *                        Sr\n\t\t\t\t */\n\t\t\t\tsibling->rb_left = tmp1 = tmp2->rb_right;\n\t\t\t\ttmp2->rb_right = sibling;\n\t\t\t\tparent->rb_right = tmp2;\n\t\t\t\tif (tmp1)\n\t\t\t\t\trb_set_parent_color(tmp1, sibling,\n\t\t\t\t\t\t\t\tRB_BLACK);\n\t\t\t\taugment_rotate(sibling, tmp2);\n\t\t\t\ttmp1 = sibling;\n\t\t\t\tsibling = tmp2;\n\t\t\t}\n\t\t\t/*\n\t\t\t * Case 4 - left rotate at parent + color flips\n\t\t\t * (p and sl could be either color here.\n\t\t\t *  After rotation, p becomes black, s acquires\n\t\t\t *  p's color, and sl keeps its color)\n\t\t\t *\n\t\t\t *      (p)             (s)\n\t\t\t *      / \\             / \\\n\t\t\t *     N   S     -->   P   Sr\n\t\t\t *        / \\         / \\\n\t\t\t *      (sl) sr      N  (sl)\n\t\t\t */\n\t\t\tparent->rb_right = tmp2 = sibling->rb_left;\n\t\t\tsibling->rb_left = parent;\n\t\t\trb_set_parent_color(tmp1, sibling, RB_BLACK);\n\t\t\tif (tmp2)\n\t\t\t\trb_set_parent(tmp2, parent);\n\t\t\t__rb_rotate_set_parents(parent, sibling, root,\n\t\t\t\t\t\tRB_BLACK);\n\t\t\taugment_rotate(parent, sibling);\n\t\t\tbreak;\n\t\t} else {\n\t\t\tsibling = parent->rb_left;\n\t\t\tif (rb_is_red(sibling)) {\n\t\t\t\t/* Case 1 - right rotate at parent */\n\t\t\t\tparent->rb_left = tmp1 = sibling->rb_right;\n\t\t\t\tsibling->rb_right = parent;\n\t\t\t\trb_set_parent_color(tmp1, parent, RB_BLACK);\n\t\t\t\t__rb_rotate_set_parents(parent, sibling, root,\n\t\t\t\t\t\t\tRB_RED);\n\t\t\t\taugment_rotate(parent, sibling);\n\t\t\t\tsibling = tmp1;\n\t\t\t}\n\t\t\ttmp1 = sibling->rb_left;\n\t\t\tif (!tmp1 || rb_is_black(tmp1)) {\n\t\t\t\ttmp2 = sibling->rb_right;\n\t\t\t\tif (!tmp2 || rb_is_black(tmp2)) {\n\t\t\t\t\t/* Case 2 - sibling color flip */\n\t\t\t\t\trb_set_parent_color(sibling, parent,\n\t\t\t\t\t\t\t\tRB_RED);\n\t\t\t\t\tif (rb_is_red(parent))\n\t\t\t\t\t\trb_set_black(parent);\n\t\t\t\t\telse {\n\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\tparent = rb_parent(node);\n\t\t\t\t\t\tif (parent)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t/* Case 3 - right rotate at sibling */\n\t\t\t\tsibling->rb_right = tmp1 = tmp2->rb_left;\n\t\t\t\ttmp2->rb_left = sibling;\n\t\t\t\tparent->rb_left = tmp2;\n\t\t\t\tif (tmp1)\n\t\t\t\t\trb_set_parent_color(tmp1, sibling,\n\t\t\t\t\t\t\t\tRB_BLACK);\n\t\t\t\taugment_rotate(sibling, tmp2);\n\t\t\t\ttmp1 = sibling;\n\t\t\t\tsibling = tmp2;\n\t\t\t}\n\t\t\t/* Case 4 - left rotate at parent + color flips */\n\t\t\tparent->rb_left = tmp2 = sibling->rb_right;\n\t\t\tsibling->rb_right = parent;\n\t\t\trb_set_parent_color(tmp1, sibling, RB_BLACK);\n\t\t\tif (tmp2)\n\t\t\t\trb_set_parent(tmp2, parent);\n\t\t\t__rb_rotate_set_parents(parent, sibling, root,\n\t\t\t\t\t\tRB_BLACK);\n\t\t\taugment_rotate(parent, sibling);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/* Non-inline version for rb_erase_augmented() use */\nvoid __rb_erase_color(struct rb_node *parent, struct rb_root *root,\n\tvoid (*augment_rotate)(struct rb_node *old, struct rb_node *new))\n{\n\t____rb_erase_color(parent, root, augment_rotate);\n}\n\n/*\n * Non-augmented rbtree manipulation functions.\n *\n * We use dummy augmented callbacks here, and have the compiler optimize them\n * out of the rb_insert_color() and rb_erase() function definitions.\n */\n\nCTAGS_INLINE void dummy_propagate(struct rb_node *node, struct rb_node *stop) {}\nCTAGS_INLINE void dummy_copy(struct rb_node *old, struct rb_node *new) {}\nCTAGS_INLINE void dummy_rotate(struct rb_node *old, struct rb_node *new) {}\n\nstatic const struct rb_augment_callbacks dummy_callbacks = {\n\tdummy_propagate, dummy_copy, dummy_rotate\n};\n\nvoid rb_insert_color(struct rb_node *node, struct rb_root *root)\n{\n\t__rb_insert(node, root, dummy_rotate);\n}\n\nvoid rb_erase(struct rb_node *node, struct rb_root *root)\n{\n\tstruct rb_node *rebalance;\n\trebalance = __rb_erase_augmented(node, root, &dummy_callbacks);\n\tif (rebalance)\n\t\t____rb_erase_color(rebalance, root, dummy_rotate);\n}\n\n/*\n * Augmented rbtree manipulation functions.\n *\n * This instantiates the same __always_inline functions as in the non-augmented\n * case, but this time with user-defined callbacks.\n */\n\nvoid __rb_insert_augmented(struct rb_node *node, struct rb_root *root,\n\tvoid (*augment_rotate)(struct rb_node *old, struct rb_node *new))\n{\n\t__rb_insert(node, root, augment_rotate);\n}\n\n/*\n * This function returns the first node (in sort order) of the tree.\n */\nstruct rb_node *rb_first(const struct rb_root *root)\n{\n\tstruct rb_node\t*n;\n\n\tn = root->rb_node;\n\tif (!n)\n\t\treturn NULL;\n\twhile (n->rb_left)\n\t\tn = n->rb_left;\n\treturn n;\n}\n\nstruct rb_node *rb_last(const struct rb_root *root)\n{\n\tstruct rb_node\t*n;\n\n\tn = root->rb_node;\n\tif (!n)\n\t\treturn NULL;\n\twhile (n->rb_right)\n\t\tn = n->rb_right;\n\treturn n;\n}\n\nstruct rb_node *rb_next(const struct rb_node *node)\n{\n\tstruct rb_node *parent;\n\n\tif (RB_EMPTY_NODE(node))\n\t\treturn NULL;\n\n\t/*\n\t * If we have a right-hand child, go down and then left as far\n\t * as we can.\n\t */\n\tif (node->rb_right) {\n\t\tnode = node->rb_right;\n\t\twhile (node->rb_left)\n\t\t\tnode=node->rb_left;\n\t\treturn (struct rb_node *)node;\n\t}\n\n\t/*\n\t * No right-hand children. Everything down and left is smaller than us,\n\t * so any 'next' node must be in the general direction of our parent.\n\t * Go up the tree; any time the ancestor is a right-hand child of its\n\t * parent, keep going up. First time it's a left-hand child of its\n\t * parent, said parent is our 'next' node.\n\t */\n\twhile ((parent = rb_parent(node)) && node == parent->rb_right)\n\t\tnode = parent;\n\n\treturn parent;\n}\n\nstruct rb_node *rb_prev(const struct rb_node *node)\n{\n\tstruct rb_node *parent;\n\n\tif (RB_EMPTY_NODE(node))\n\t\treturn NULL;\n\n\t/*\n\t * If we have a left-hand child, go down and then right as far\n\t * as we can.\n\t */\n\tif (node->rb_left) {\n\t\tnode = node->rb_left;\n\t\twhile (node->rb_right)\n\t\t\tnode=node->rb_right;\n\t\treturn (struct rb_node *)node;\n\t}\n\n\t/*\n\t * No left-hand children. Go up till we find an ancestor which\n\t * is a right-hand child of its parent.\n\t */\n\twhile ((parent = rb_parent(node)) && node == parent->rb_left)\n\t\tnode = parent;\n\n\treturn parent;\n}\n\nvoid rb_replace_node(struct rb_node *victim, struct rb_node *new,\n\t\t\t struct rb_root *root)\n{\n\tstruct rb_node *parent = rb_parent(victim);\n\n\t/* Set the surrounding nodes to point to the replacement */\n\t__rb_change_child(victim, new, parent, root);\n\tif (victim->rb_left)\n\t\trb_set_parent(victim->rb_left, new);\n\tif (victim->rb_right)\n\t\trb_set_parent(victim->rb_right, new);\n\n\t/* Copy the pointers/colour from the victim to the replacement */\n\t*new = *victim;\n}\n\nstatic struct rb_node *rb_left_deepest_node(const struct rb_node *node)\n{\n\tfor (;;) {\n\t\tif (node->rb_left)\n\t\t\tnode = node->rb_left;\n\t\telse if (node->rb_right)\n\t\t\tnode = node->rb_right;\n\t\telse\n\t\t\treturn (struct rb_node *)node;\n\t}\n}\n\nstruct rb_node *rb_next_postorder(const struct rb_node *node)\n{\n\tconst struct rb_node *parent;\n\tif (!node)\n\t\treturn NULL;\n\tparent = rb_parent(node);\n\n\t/* If we're sitting on node, we've already seen our children */\n\tif (parent && node == parent->rb_left && parent->rb_right) {\n\t\t/* If we are the parent's left node, go to the parent's right\n\t\t * node then all the way down to the left */\n\t\treturn rb_left_deepest_node(parent->rb_right);\n\t} else\n\t\t/* Otherwise we are the parent's right node, and the parent\n\t\t * should be next */\n\t\treturn (struct rb_node *)parent;\n}\n\nstruct rb_node *rb_first_postorder(const struct rb_root *root)\n{\n\tif (!root->rb_node)\n\t\treturn NULL;\n\n\treturn rb_left_deepest_node(root->rb_node);\n}\n"
  },
  {
    "path": "main/rbtree.h",
    "content": "/*\n  Red Black Trees\n  (C) 1999  Andrea Arcangeli <andrea@suse.de>\n\n  This program is free software; you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation; either version 2 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  linux/include/linux/rbtree.h\n\n  To use rbtrees you'll have to implement your own insert and search cores.\n  This will avoid us to use callbacks and to drop drammatically performances.\n  I know it's not the cleaner way,  but in C (not in C++) to get\n  performances and genericity...\n\n  See Documentation/rbtree.txt for documentation and samples.\n*/\n\n#ifndef\tCTAGS_MAIN_RBTREE_H\n#define\tCTAGS_MAIN_RBTREE_H\n\n#include \"general.h\"\n#include <stddef.h>\n#include <stdint.h>\n\n#include \"inline.h\"\n#include \"gcc-attr.h\"\n\n#if defined(container_of)\n  #undef container_of\n#if defined(HAVE_TYPEOF) && defined(HAVE_STATEMENT_EXPRESSION_EXT)\n  #define container_of(ptr, type, member) ({\t\t\t\\\n\t\tconst typeof( ((type *)0)->member ) *__mptr = (ptr);\t\\\n\t\t(type *)( (char *)__mptr - offsetof(type,member) );})\n#else\n  #define container_of(ptr, type, member) \\\n\t\t((type *)( (char *)ptr - offsetof(type,member)))\n#endif\t/* defined(HAVE_TYPEOF) && defined(HAVE_STATEMENT_EXPRESSION_EXT) */\n#else\n#if defined(HAVE_TYPEOF) && defined(HAVE_STATEMENT_EXPRESSION_EXT)\n  #define container_of(ptr, type, member) ({\t\t\t\\\n\t\tconst typeof( ((type *)0)->member ) *__mptr = (ptr);\t\\\n\t\t(type *)( (char *)__mptr - offsetof(type,member) );})\n#else\n  #define container_of(ptr, type, member) \\\n\t\t((type *)( (char *)ptr - offsetof(type,member)))\n#endif /* defined(HAVE_TYPEOF) && defined(HAVE_STATEMENT_EXPRESSION_EXT) */\n#endif /* defined(container_of) */\n\nstruct rb_node {\n\tuintptr_t  __rb_parent_color;\n\tstruct rb_node *rb_right;\n\tstruct rb_node *rb_left;\n} CTAGA_ATTR_ALIGNED(sizeof(long));\n\t/* The alignment might seem pointless, but allegedly CRIS needs it */\n\nstruct rb_root {\n\tstruct rb_node *rb_node;\n};\n\n\n#define rb_parent(r)   ((struct rb_node *)((r)->__rb_parent_color & ~3))\n\n#define RB_ROOT\t(struct rb_root) { NULL, }\n#define\trb_entry(ptr, type, member) container_of(ptr, type, member)\n\n#define RB_EMPTY_ROOT(root)  ((root)->rb_node == NULL)\n\n/* 'empty' nodes are nodes that are known not to be inserted in an rbtree */\n#define RB_EMPTY_NODE(node)  \\\n\t((node)->__rb_parent_color == (uintptr_t)(node))\n#define RB_CLEAR_NODE(node)  \\\n\t((node)->__rb_parent_color = (uintptr_t)(node))\n\n\nextern void rb_insert_color(struct rb_node *, struct rb_root *);\nextern void rb_erase(struct rb_node *, struct rb_root *);\n\n\n/* Find logical next and previous nodes in a tree */\nextern struct rb_node *rb_next(const struct rb_node *);\nextern struct rb_node *rb_prev(const struct rb_node *);\nextern struct rb_node *rb_first(const struct rb_root *);\nextern struct rb_node *rb_last(const struct rb_root *);\n\n/* Postorder iteration - always visit the parent after its children */\nextern struct rb_node *rb_first_postorder(const struct rb_root *);\nextern struct rb_node *rb_next_postorder(const struct rb_node *);\n\n/* Fast replacement of a single node without remove/rebalance/add/rebalance */\nextern void rb_replace_node(struct rb_node *victim, struct rb_node *new,\n\t\t\t\tstruct rb_root *root);\n\nCTAGS_INLINE void rb_link_node(struct rb_node * node, struct rb_node * parent,\n\t\t\t\tstruct rb_node ** rb_link)\n{\n\tnode->__rb_parent_color = (uintptr_t)parent;\n\tnode->rb_left = node->rb_right = NULL;\n\n\t*rb_link = node;\n}\n\n#define rb_entry_safe(ptr, type, member) \\\n\t({ typeof(ptr) ____ptr = (ptr); \\\n\t   ____ptr ? rb_entry(____ptr, type, member) : NULL; \\\n\t})\n\n/**\n * rbtree_postorder_for_each_entry_safe - iterate over rb_root in post order of\n * given type safe against removal of rb_node entry\n *\n * @pos:\tthe 'type *' to use as a loop cursor.\n * @n:\t\tanother 'type *' to use as temporary storage\n * @root:\t'rb_root *' of the rbtree.\n * @field:\tthe name of the rb_node field within 'type'.\n */\n#define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \\\n\tfor (pos = rb_entry_safe(rb_first_postorder(root), typeof(*pos), field); \\\n\t\t pos && ({ n = rb_entry_safe(rb_next_postorder(&pos->field), \\\n\t\t\ttypeof(*pos), field); 1; }); \\\n\t\t pos = n)\n\n#endif\t/* CTAGS_MAIN_RBTREE_H */\n"
  },
  {
    "path": "main/rbtree_augmented.h",
    "content": "/*\n  Red Black Trees\n  (C) 1999  Andrea Arcangeli <andrea@suse.de>\n  (C) 2002  David Woodhouse <dwmw2@infradead.org>\n  (C) 2012  Michel Lespinasse <walken@google.com>\n\n  This program is free software; you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation; either version 2 of the License, or\n  (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n  linux/include/linux/rbtree_augmented.h\n*/\n\n#ifndef CTAGS_MAIN_RBTREE_AUGMENTED_H\n#define CTAGS_MAIN_RBTREE_AUGMENTED_H\n\n#include \"general.h\"\n\n#include <stddef.h>\n#include <stdint.h>\n#include \"rbtree.h\"\n\n#include \"inline.h\"\n\n/*\n * Please note - only struct rb_augment_callbacks and the prototypes for\n * rb_insert_augmented() and rb_erase_augmented() are intended to be public.\n * The rest are implementation details you are not expected to depend on.\n *\n * See Documentation/rbtree.txt for documentation and samples.\n */\n\nstruct rb_augment_callbacks {\n\tvoid (*propagate)(struct rb_node *node, struct rb_node *stop);\n\tvoid (*copy)(struct rb_node *old, struct rb_node *new);\n\tvoid (*rotate)(struct rb_node *old, struct rb_node *new);\n};\n\nextern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,\n\tvoid (*augment_rotate)(struct rb_node *old, struct rb_node *new));\n/*\n * Fixup the rbtree and update the augmented information when rebalancing.\n *\n * On insertion, the user must update the augmented information on the path\n * leading to the inserted node, then call rb_link_node() as usual and\n * rb_augment_inserted() instead of the usual rb_insert_color() call.\n * If rb_augment_inserted() rebalances the rbtree, it will callback into\n * a user provided function to update the augmented information on the\n * affected subtrees.\n */\nCTAGS_INLINE void\nrb_insert_augmented(struct rb_node *node, struct rb_root *root,\n\t\t\tconst struct rb_augment_callbacks *augment)\n{\n\t__rb_insert_augmented(node, root, augment->rotate);\n}\n\n#define RB_DECLARE_CALLBACKS(rbstatic, rbname, rbstruct, rbfield,\t\\\n\t\t\t\t rbtype, rbaugmented, rbcompute)\t\t\\\nCTAGS_INLINE void\t\t\t\t\t\t\t\\\nrbname ## _propagate(struct rb_node *rb, struct rb_node *stop)\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\twhile (rb != stop) {\t\t\t\t\t\t\\\n\t\trbstruct *node = rb_entry(rb, rbstruct, rbfield);\t\\\n\t\trbtype augmented = rbcompute(node);\t\t\t\\\n\t\tif (node->rbaugmented == augmented)\t\t\t\\\n\t\t\tbreak;\t\t\t\t\t\t\\\n\t\tnode->rbaugmented = augmented;\t\t\t\t\\\n\t\trb = rb_parent(&node->rbfield);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\nCTAGS_INLINE void\t\t\t\t\t\t\t\\\nrbname ## _copy(struct rb_node *rb_old, struct rb_node *rb_new)\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\trbstruct *old = rb_entry(rb_old, rbstruct, rbfield);\t\t\\\n\trbstruct *new = rb_entry(rb_new, rbstruct, rbfield);\t\t\\\n\tnew->rbaugmented = old->rbaugmented;\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\nstatic void\t\t\t\t\t\t\t\t\\\nrbname ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new)\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\trbstruct *old = rb_entry(rb_old, rbstruct, rbfield);\t\t\\\n\trbstruct *new = rb_entry(rb_new, rbstruct, rbfield);\t\t\\\n\tnew->rbaugmented = old->rbaugmented;\t\t\t\t\\\n\told->rbaugmented = rbcompute(old);\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\\\nrbstatic const struct rb_augment_callbacks rbname = {\t\t\t\\\n\trbname ## _propagate, rbname ## _copy, rbname ## _rotate\t\\\n};\n\n\n#define\tRB_RED\t\t0\n#define\tRB_BLACK\t1\n\n#define __rb_parent(pc)    ((struct rb_node *)(pc & ~3))\n\n#define __rb_color(pc)     ((pc) & 1)\n#define __rb_is_black(pc)  __rb_color(pc)\n#define __rb_is_red(pc)    (!__rb_color(pc))\n#define rb_color(rb)       __rb_color((rb)->__rb_parent_color)\n#define rb_is_red(rb)      __rb_is_red((rb)->__rb_parent_color)\n#define rb_is_black(rb)    __rb_is_black((rb)->__rb_parent_color)\n\nCTAGS_INLINE void rb_set_parent(struct rb_node *rb, struct rb_node *p)\n{\n\trb->__rb_parent_color = rb_color(rb) | (uintptr_t)p;\n}\n\nCTAGS_INLINE void rb_set_parent_color(struct rb_node *rb,\n\t\t\t\t\t   struct rb_node *p, int color)\n{\n\trb->__rb_parent_color = (uintptr_t)p | color;\n}\n\nCTAGS_INLINE void\n__rb_change_child(struct rb_node *old, struct rb_node *new,\n\t\t  struct rb_node *parent, struct rb_root *root)\n{\n\tif (parent) {\n\t\tif (parent->rb_left == old)\n\t\t\tparent->rb_left = new;\n\t\telse\n\t\t\tparent->rb_right = new;\n\t} else\n\t\troot->rb_node = new;\n}\n\nextern void __rb_erase_color(struct rb_node *parent, struct rb_root *root,\n\tvoid (*augment_rotate)(struct rb_node *old, struct rb_node *new));\n\nCTAGS_INLINE struct rb_node *\n__rb_erase_augmented(struct rb_node *node, struct rb_root *root,\n\t\t\t const struct rb_augment_callbacks *augment)\n{\n\tstruct rb_node *child = node->rb_right, *tmp = node->rb_left;\n\tstruct rb_node *parent, *rebalance;\n\tuintptr_t pc;\n\n\tif (!tmp) {\n\t\t/*\n\t\t * Case 1: node to erase has no more than 1 child (easy!)\n\t\t *\n\t\t * Note that if there is one child it must be red due to 5)\n\t\t * and node must be black due to 4). We adjust colors locally\n\t\t * so as to bypass __rb_erase_color() later on.\n\t\t */\n\t\tpc = node->__rb_parent_color;\n\t\tparent = __rb_parent(pc);\n\t\t__rb_change_child(node, child, parent, root);\n\t\tif (child) {\n\t\t\tchild->__rb_parent_color = pc;\n\t\t\trebalance = NULL;\n\t\t} else\n\t\t\trebalance = __rb_is_black(pc) ? parent : NULL;\n\t\ttmp = parent;\n\t} else if (!child) {\n\t\t/* Still case 1, but this time the child is node->rb_left */\n\t\ttmp->__rb_parent_color = pc = node->__rb_parent_color;\n\t\tparent = __rb_parent(pc);\n\t\t__rb_change_child(node, tmp, parent, root);\n\t\trebalance = NULL;\n\t\ttmp = parent;\n\t} else {\n\t\tstruct rb_node *successor = child, *child2;\n\t\ttmp = child->rb_left;\n\t\tif (!tmp) {\n\t\t\t/*\n\t\t\t * Case 2: node's successor is its right child\n\t\t\t *\n\t\t\t *    (n)          (s)\n\t\t\t *    / \\          / \\\n\t\t\t *  (x) (s)  ->  (x) (c)\n\t\t\t *        \\\n\t\t\t *        (c)\n\t\t\t */\n\t\t\tparent = successor;\n\t\t\tchild2 = successor->rb_right;\n\t\t\taugment->copy(node, successor);\n\t\t} else {\n\t\t\t/*\n\t\t\t * Case 3: node's successor is leftmost under\n\t\t\t * node's right child subtree\n\t\t\t *\n\t\t\t *    (n)          (s)\n\t\t\t *    / \\          / \\\n\t\t\t *  (x) (y)  ->  (x) (y)\n\t\t\t *      /            /\n\t\t\t *    (p)          (p)\n\t\t\t *    /            /\n\t\t\t *  (s)          (c)\n\t\t\t *    \\\n\t\t\t *    (c)\n\t\t\t */\n\t\t\tdo {\n\t\t\t\tparent = successor;\n\t\t\t\tsuccessor = tmp;\n\t\t\t\ttmp = tmp->rb_left;\n\t\t\t} while (tmp);\n\t\t\tparent->rb_left = child2 = successor->rb_right;\n\t\t\tsuccessor->rb_right = child;\n\t\t\trb_set_parent(child, successor);\n\t\t\taugment->copy(node, successor);\n\t\t\taugment->propagate(parent, successor);\n\t\t}\n\n\t\tsuccessor->rb_left = tmp = node->rb_left;\n\t\trb_set_parent(tmp, successor);\n\n\t\tpc = node->__rb_parent_color;\n\t\ttmp = __rb_parent(pc);\n\t\t__rb_change_child(node, successor, tmp, root);\n\t\tif (child2) {\n\t\t\tsuccessor->__rb_parent_color = pc;\n\t\t\trb_set_parent_color(child2, parent, RB_BLACK);\n\t\t\trebalance = NULL;\n\t\t} else {\n\t\t\tuintptr_t pc2 = successor->__rb_parent_color;\n\t\t\tsuccessor->__rb_parent_color = pc;\n\t\t\trebalance = __rb_is_black(pc2) ? parent : NULL;\n\t\t}\n\t\ttmp = successor;\n\t}\n\n\taugment->propagate(tmp, NULL);\n\treturn rebalance;\n}\n\nCTAGS_INLINE void\nrb_erase_augmented(struct rb_node *node, struct rb_root *root,\n\t\t   const struct rb_augment_callbacks *augment)\n{\n\tstruct rb_node *rebalance = __rb_erase_augmented(node, root, augment);\n\tif (rebalance)\n\t\t__rb_erase_color(rebalance, root, augment->rotate);\n}\n\n#endif\t/* CTAGS_MAIN_RBTREE_AUGMENTED_H */\n"
  },
  {
    "path": "main/read.c",
    "content": "/*\n*   Copyright (c) 1996-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains low level input and tag file read functions (newline\n*   conversion for input files are performed at this level).\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <ctype.h>\n#include <stdlib.h>\n\n#define FILE_WRITE\n#include \"read.h\"\n#include \"read_p.h\"\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"routines.h\"\n#include \"routines_p.h\"\n#include \"options_p.h\"\n#include \"parse_p.h\"\n#include \"promise.h\"\n#include \"promise_p.h\"\n#include \"stats_p.h\"\n#include \"trace.h\"\n#include \"trashbox.h\"\n#ifdef HAVE_ICONV\n# include \"mbcs.h\"\n# include \"mbcs_p.h\"\n#endif\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef struct sLangStack {\n\tlangType *languages;\n\tunsigned int count;\n\tunsigned int size;\n} langStack;\n\n/*  Maintains the state of the current input file.\n */\ntypedef union sInputLangInfo {\n\tlangStack stack;\n\tlangType  type;\n} inputLangInfo;\n\ntypedef struct sInputFileInfo {\n\tvString *name;           /* name to report for input file */\n\tvString *tagPath;        /* path of input file relative to tag file */\n\tunsigned long lineNumber;/* line number in the input file */\n\tunsigned long lineNumberOrigin; /* The value set to `lineNumber'\n\t\t\t\t\t   when `resetInputFile' is called\n\t\t\t\t\t   on the area.\n\t\t\t\t\t   This is needed for stacked area. */\n\tbool isHeader;           /* is input file a header file? */\n} inputFileInfo;\n\ntypedef struct sComputPos {\n\tMIOPos  pos;\n\tlong    offset;\n\tbool open;\n\tint crAdjustment;\n\tsize_t posInAllLines;\n} compoundPos;\n\ntypedef struct sInputLineFposMap {\n\tcompoundPos *pos;\n\tunsigned int count;\n\tunsigned int size;\n} inputLineFposMap;\n\ntypedef struct sAreaInfo {\n\tlong startOffset;\n\tunsigned long startLine;\n\tlong startColumn;\n\tunsigned long endLine;\n\tlong endColumn;\n} areaInfo;\n\ntypedef struct sInputFile {\n\tvString    *path;          /* path of input file (if any) */\n\tvString    *line;          /* last line read from file */\n\tconst unsigned char* currentLine;  /* current line being worked on */\n\tMIO        *mio;           /* MIO stream used for reading the file */\n\tcompoundPos    filePosition;  /* file position of current line */\n\tunsigned int ungetchIdx;\n\tint         ungetchBuf[8]; /* characters that were ungotten */\n\n\tbool bomFound;\n\t/*  Contains data pertaining to the original `source' file in which the tag\n\t *  was defined. This may be different from the `input' file when #line\n\t *  directives are processed (i.e. the input file is preprocessor output).\n\t */\n\tinputFileInfo input; /* name, lineNumber */\n\tinputFileInfo source;\n\n\tareaInfo areaInfo;\n\n\t/* sourceTagPathHolder is a kind of trash box.\n\t   The buffer pointed by tagPath field of source field can\n\t   be referred from tagsEntryInfo instances. sourceTagPathHolder\n\t   is used keeping the buffer till all processing about the current\n\t   input file is done. After all processing is done, the buffers\n\t   in sourceTagPathHolder are destroyed. */\n\tstringList  * sourceTagPathHolder;\n\tinputLineFposMap lineFposMap;\n\tvString *allLines;\n\tint thinDepth;\n\ttime_t mtime;\n} inputFile;\n\nenum areaCoord {\n\tAREA_COORD_ABS,\n\tAREA_COORD_CURRENT,\n};\n\nstatic inputLangInfo inputLang;\nstatic langType sourceLang;\n\n/*\n*   FUNCTION DECLARATIONS\n*/\nstatic void     langStackInit (langStack *langStack);\nstatic langType langStackTop  (langStack *langStack);\nstatic langType langStackBotom(langStack *langStack);\nstatic void     langStackPush (langStack *langStack, langType type);\nstatic langType langStackPop  (langStack *langStack);\nstatic void     langStackClear(langStack *langStack);\n\nstatic MIOPos getInputFilePositionForLineFull (unsigned int line, enum areaCoord areaCoord);\nstatic MIOPos getInputFilePositionForFileOffset (long offset);\nstatic unsigned long getAreaStartLineNumber (void);\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic inputFile File;  /* static read through functions */\nstatic inputFile BackupFile;\t/* File is copied here when a guest parser is pushed */\nstatic compoundPos StartOfLine;  /* holds deferred position of start of line */\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nextern unsigned long getInputLineNumber (void)\n{\n\tif (!File.currentLine && File.input.lineNumber == 1 && isAreaStacked ())\n\t\treturn getAreaStartLineNumber ();\n\treturn File.input.lineNumber;\n}\n\nCTAGS_INLINE\nvoid callWithSavingPosition (MIO *mio,\n\t\t\t\t\t\t\t void (* fn) (MIO *, void *),\n\t\t\t\t\t\t\t void *data)\n{\n\tMIOPos origin;\n\n\tmio_getpos (mio, &origin);\n\tfn (mio, data);\n\tmio_setpos (mio, &origin);\n}\n\n/* args (startLine): [absolute]\n   args (startColumn): [buggy]\n   args (endLine): [absolute]\n   args (endColumn): [absolute] */\nextern void getAreaInfo (unsigned long *startLine,\n\t\t\t\t\t\t long *startColumn,\n\t\t\t\t\t\t unsigned long *endLine,\n\t\t\t\t\t\t long *endColumn)\n{\n\tif (startLine)\n\t\t*startLine = File.areaInfo.startLine;\n\tif (startColumn)\n\t\t*startColumn = File.areaInfo.startColumn;\n\tif (endLine)\n\t\t*endLine = File.areaInfo.endLine;\n\tif (endColumn)\n\t\t*endColumn = File.areaInfo.endColumn;\n}\n\n/* return: [absolute]\n * If the area is not stacked, return 0.\n * If the area is stacked, the line number of the start of the current\n * area in the absolute coordinate system.\n */\nstatic unsigned long getAreaStartLineNumber (void)\n{\n\tunsigned long startLine = 0;\n\n\tif (isAreaStacked())\n\t\tgetAreaInfo (&startLine, NULL, NULL, NULL);\n\treturn startLine;\n}\n\nextern unsigned long translateLineNumber (unsigned long line)\n{\n\tunsigned long area_start_line = getAreaStartLineNumber ();\n\treturn (area_start_line? area_start_line - 1: 0) + line;\n}\n\n/* return: [absolute] */\nCTAGS_INLINE\nlong getAreaStartOffset (void)\n{\n\treturn File.areaInfo.startOffset;\n}\n\nextern long translateFileOffset (unsigned long offset)\n{\n\treturn getAreaStartOffset () + offset;\n}\n\nextern int getInputColumnNumber (void)\n{\n\tint ret;\n\n\t/* input file ---> +-----------------+\n\t *                 |                 |\n\t *                 |   [.....X.......|\n\t *                 |.................|\n\t *                 |.....Y]          |\n\t *                 |                 |\n\t *                 +-----------------+\n\t */\n\n\tif (File.currentLine)\n\t{\n\t\tunsigned char *base = (unsigned char *) vStringValue (File.line);\n\t\tlong column_in_current_coord = File.currentLine - base - File.ungetchIdx;\n\n\t\t/* input file ---> +-----------------+\n\t\t *                 |                 |\n\t\t *                 |   [.....X.......|\n\t\t *                 <---dx--->\n\t\t *                 |.................|\n\t\t *                 |.....Y..]        |\n\t\t *                 <-dy->\n\t\t *                 |                 |\n\t\t *                 +-----------------+\n\t\t *\n\t\t * dy => column_in_current_coord.\n\t\t *\n\t\t * dx = x1 + x2:\n\t\t *\n\t\t *                 <x1><-x2->\n\t\t *                 |   [.....X.......|\n\t\t *                 <---dx--->\n\t\t *\n\t\t * x1 => guest_area_column.\n\t\t * x2 => column_in_current_coord.\n\t\t */\n\n\t\tlong guest_area_column = 0;\n\t\tif (isAreaStacked ())\n\t\t{\n\t\t\t/* X or Y */\n\t\t\tunsigned long startLine;\n\t\t\tlong startColumn;\n\t\t\tgetAreaInfo (&startLine, &startColumn, NULL, NULL);\n\t\t\tif (startLine == File.input.lineNumber)\n\t\t\t{\n\t\t\t\t/* We are at the start line of the guest area (X). */\n\t\t\t\tguest_area_column = startColumn;\n\t\t\t}\n\t\t}\n\n\t\tret = guest_area_column + column_in_current_coord;\n\t}\n\telse if (File.input.lineNumber)\n\t{\n\t\t/* currentLine is set to NULL but File.input.lineNumber is not zero.\n\t\t * This implies the parser saw EOF.\n\t\t * The way to calculate the offset at the end of file is tricky.\n\t\t *\n\t\t * input file ---> +-----------------+\n\t\t *                 |                 |\n\t\t *                 |   [.............|\n\t\t *                 |.................|\n\t\t *                 |.....Z]          |\n\t\t *                 <-dz->\n\t\t *                 |                 |\n\t\t *                 +-----------------+\n\t\t *\n\t\t * We must calculate dz but we cannot use File.currentLine.\n\t\t *\n\t\t * input file ---> +-----------------+\n\t\t *                 |<========== O ===|\n\t\t *                 |==>[<============|\n\t\t *                 |======= P =======|\n\t\t *                 |====>Z]          |\n\t\t *                 <-dz->\n\t\t *                 |                 |\n\t\t *                 +-----------------+\n\t\t *\n\t\t * O => getAreaStartOffset ()\n\t\t * P => mio_tell (File.mio) - (File.bomFound? 3: 0)\n\t\t *\n\t\t * input file ---> +-----------------+\n\t\t *                 |<================|\n\t\t *                 |===[====Q========|\n\t\t *                 |=================|\n\t\t *                 |====>Z]          |\n\t\t *                 <-dz->\n\t\t *                 |                 |\n\t\t *                 +-----------------+\n\t\t *\n\t\t * Q => getInputFileOffsetForLine(File.input.lineNumber)\n\t\t *\n\t\t * dz = O + P - Q\n\t\t */\n\t\tunsigned long ln = getInputLineNumber ();\n\t\tret = getAreaStartOffset ()\n\t\t\t+ mio_tell (File.mio) - (File.bomFound? 3: 0)\n\t\t\t- getInputFileOffsetForLine(ln)\n\t\t\t- File.ungetchIdx;\n\t}\n\telse\n\t{\n\t\t/* Read nothing yet. */\n\t\tlong guest_area_column = 0;\n\t\tif (isAreaStacked ())\n\t\t{\n\t\t\tunsigned long startLine CTAGS_ATTR_UNUSED;\n\t\t\tgetAreaInfo (&startLine, &guest_area_column, NULL, NULL);\n\t\t\tAssert (startLine == 1);\n\t\t}\n\t\tret = guest_area_column;\n\t}\n\n\treturn ret >= 0 ? ret : 0;\n}\n\nextern const char *getInputFileName (void)\n{\n\tif (!File.input.name)\n\t\treturn NULL;\n\treturn vStringValue (File.input.name);\n}\n\nextern MIOPos getInputFilePosition (void)\n{\n\treturn File.filePosition.pos;\n}\n\nstatic compoundPos* getInputFileCompoundPosForLine (unsigned int line)\n{\n\tint index;\n\tif (line > 0)\n\t{\n\t\tif (File.lineFposMap.count > (line - 1))\n\t\t\tindex = line - 1;\n\t\telse if (File.lineFposMap.count != 0)\n\t\t\tindex = File.lineFposMap.count - 1;\n\t\telse\n\t\t\tindex = 0;\n\t}\n\telse\n\t\tindex = 0;\n\n\treturn File.lineFposMap.pos + index;\n}\n\n\n/* case areaCoord == AREA_COORD_CURRENT:\n *    return: [current],\n *    args (line): [absolute]\n *\n * case areaCoord == AREA_COORD_ABS:\n *    return: [absolute],\n *    args (line): [absolute]\n */\nstatic MIOPos getInputFilePositionForLineFull (unsigned int line, enum areaCoord posAreaCoord)\n{\n\tif (line == 1 && File.lineFposMap.count == 0)\n\t{\n\t\t/* Any line is not read yet. */\n\t\tMIOPos pos;\n\n\t\tif (isAreaStacked() && (posAreaCoord == AREA_COORD_ABS))\n\t\t\tmio_getpos (BackupFile.mio, &pos);\n\t\telse\n\t\t\tmio_getpos (File.mio, &pos);\n\t\treturn pos;\n\t}\n\n\tif (isAreaStacked() && (posAreaCoord == AREA_COORD_CURRENT))\n\t{\n\t\tunsigned long area_start_ln = getAreaStartLineNumber ();\n\t\tlong abs_offset = getInputFileOffsetForLine (line);\n\t\tlong area_start_offset = getInputFileOffsetForLine (area_start_ln);\n\t\tlong rela_offset = abs_offset - area_start_offset;\n\t\tMIOPos rela_pos = getInputFilePositionForFileOffset (rela_offset);\n\t\treturn rela_pos;\n\t}\n\n\tcompoundPos *cpos = getInputFileCompoundPosForLine (line);\n\treturn cpos->pos;\n}\n\nextern MIOPos getInputFilePositionForLine (unsigned int line)\n{\n\treturn getInputFilePositionForLineFull (line, AREA_COORD_CURRENT);\n}\n\n\nextern long getInputFileOffsetForLine (unsigned int line)\n{\n\tcompoundPos *cpos = getInputFileCompoundPosForLine (line);\n\tlong r = cpos->offset - (File.bomFound? 3: 0) - cpos->crAdjustment;\n\tAssert (r >= 0);\n\treturn r;\n}\n\nstruct mioGetposCallbackData {\n\tMIOPos *pos;\n\tlong   offset;\n};\n\nstatic void tellAbsolutePosition (MIO *mio, void *data)\n{\n\tstruct mioGetposCallbackData *cb_data = data;\n\n\tmio_seek (mio, cb_data->offset, SEEK_SET);\n\tmio_getpos (mio, cb_data->pos);\n}\n\n/* return: [current],\n * args (offset): [current] */\nstatic MIOPos getInputFilePositionForFileOffset (long offset)\n{\n\tMIOPos pos;\n\tstruct mioGetposCallbackData data = {\n\t\t.pos = &pos,\n\t\t.offset = offset,\n\t};\n\n\tcallWithSavingPosition (File.mio,\n\t\t\t\t\t\t\ttellAbsolutePosition,\n\t\t\t\t\t\t\t&data);\n\n\treturn pos;\n}\n\nextern langType getInputLanguage (void)\n{\n\treturn langStackTop (&inputLang.stack);\n}\n\nextern const char *getInputLanguageName (void)\n{\n\treturn getLanguageName (getInputLanguage());\n}\n\nextern const char *getInputFileTagPath (void)\n{\n\treturn vStringValue (File.input.tagPath);\n}\n\nextern bool isInputLanguage (langType lang)\n{\n\treturn (bool)((lang) == getInputLanguage ());\n}\n\nextern bool isInputHeaderFile (void)\n{\n\treturn File.input.isHeader;\n}\n\nextern bool isInputLanguageKindEnabled (int kindIndex)\n{\n\treturn isLanguageKindEnabled (getInputLanguage (), kindIndex);\n}\n\nextern bool isInputLanguageRoleEnabled (int kindIndex, int roleIndex)\n{\n\treturn isLanguageRoleEnabled (getInputLanguage (),\n\t\t\t\t\t\t\t\t  kindIndex, roleIndex);\n}\n\nextern unsigned int countInputLanguageKinds (void)\n{\n\treturn countLanguageKinds (getInputLanguage ());\n}\n\nextern unsigned int countInputLanguageRoles (int kindIndex)\n{\n\treturn countLanguageRoles (getInputLanguage (), kindIndex);\n}\n\nextern bool doesInputLanguageRequestAutomaticFQTag (const tagEntryInfo *e)\n{\n\treturn doesLanguageRequestAutomaticFQTag (e->langType);\n}\n\nextern const char *getSourceFileTagPath (void)\n{\n\treturn vStringValue (File.source.tagPath);\n}\n\nextern langType getSourceLanguage (void)\n{\n\treturn sourceLang;\n}\n\nextern unsigned long getSourceLineNumber (void)\n{\n\treturn File.source.lineNumber;\n}\n\nstatic void freeInputFileInfo (inputFileInfo *finfo)\n{\n\tif (finfo->name)\n\t{\n\t\tvStringDelete (finfo->name);\n\t\tfinfo->name = NULL;\n\t}\n\tif (finfo->tagPath)\n\t{\n\t\tvStringDelete (finfo->tagPath);\n\t\tfinfo->tagPath = NULL;\n\t}\n}\n\nextern void freeInputFileResources (void)\n{\n\tif (File.path != NULL)\n\t\tvStringDelete (File.path);\n\tif (File.line != NULL)\n\t\tvStringDelete (File.line);\n\tfreeInputFileInfo (&File.input);\n\tfreeInputFileInfo (&File.source);\n}\n\nextern const unsigned char *getInputFileData (size_t *size)\n{\n\treturn mio_memory_get_data (File.mio, size);\n}\n\n/*\n * inputLineFposMap related functions\n */\nstatic void freeLineFposMap (inputLineFposMap *lineFposMap)\n{\n\tif (lineFposMap->pos)\n\t{\n\t\teFree (lineFposMap->pos);\n\t\tlineFposMap->pos = NULL;\n\t\tlineFposMap->count = 0;\n\t\tlineFposMap->size = 0;\n\t}\n}\n\nstatic void allocLineFposMap (inputLineFposMap *lineFposMap)\n{\n#define INITIAL_lineFposMap_LEN 256\n\tlineFposMap->pos = xCalloc (INITIAL_lineFposMap_LEN, compoundPos);\n\tlineFposMap->size = INITIAL_lineFposMap_LEN;\n\tlineFposMap->count = 0;\n}\n\nstatic void resetLineFposMap (inputLineFposMap *lineFposMap)\n{\n\tmemset(lineFposMap->pos, 0, sizeof(compoundPos) * lineFposMap->size);\n\tlineFposMap->count = 0;\n}\n\nstatic void appendLineFposMap (inputLineFposMap *lineFposMap, compoundPos *pos,\n\t\t\t\t\t\t\t   bool crAdjustment, size_t posInAllLines)\n{\n\tint lastCrAdjustment = 0;\n\n\tif (lineFposMap->size == lineFposMap->count)\n\t{\n\t\tlineFposMap->size *= 2;\n\t\tlineFposMap->pos = xRealloc (lineFposMap->pos,\n\t\t\t\t\t     lineFposMap->size,\n\t\t\t\t\t     compoundPos);\n\t}\n\n\tif (lineFposMap->count != 0)\n\t{\n\t\tlineFposMap->pos [lineFposMap->count - 1].open = false;\n\t\tlastCrAdjustment = lineFposMap->pos [lineFposMap->count - 1].crAdjustment;\n\t}\n\n\tlineFposMap->pos [lineFposMap->count] = *pos;\n\tlineFposMap->pos [lineFposMap->count].open = true;\n\tlineFposMap->pos [lineFposMap->count].crAdjustment\n\t\t= lastCrAdjustment + ((crAdjustment)? 1: 0);\n\tlineFposMap->pos [lineFposMap->count].posInAllLines = posInAllLines;\n\tlineFposMap->count++;\n}\n\nstatic int compoundPosForOffset (const void* oft, const void *p)\n{\n\tlong offset = *(long *)oft;\n\tconst compoundPos *pos = p;\n\tconst compoundPos *next = (compoundPos *)(((char *)pos) + sizeof (compoundPos));\n\n\tif (offset < (pos->offset - pos->crAdjustment))\n\t\treturn -1;\n\telse if (((pos->offset - pos->crAdjustment) <= offset)\n\t\t && (pos->open\n\t\t     || (offset < (next->offset - next->crAdjustment))))\n\t\treturn 0;\n\telse\n\t\treturn 1;\n}\n\nextern unsigned long getInputLineNumberForFileOffset(long offset)\n{\n\tcompoundPos *p;\n\n\tif (File.bomFound)\n\t\toffset += 3;\n\n\tp = bsearch (&offset, File.lineFposMap.pos, File.lineFposMap.count, sizeof (compoundPos),\n\t\t     compoundPosForOffset);\n\tif (p == NULL)\n\t\treturn 1;\t/* TODO: 0? */\n\telse\n\t\treturn 1 + (p - File.lineFposMap.pos);\n}\n\n/*\n *   Input file access functions\n */\n\nstatic void setOwnerDirectoryOfInputFile (const char *const fileName)\n{\n\tconst char *const head = fileName;\n\tconst char *const tail = baseFilename (head);\n\n\tif (File.path != NULL)\n\t\tvStringDelete (File.path);\n\tif (tail == head)\n\t\tFile.path = NULL;\n\telse\n\t{\n\t\tconst size_t length = tail - head - 1;\n\t\tFile.path = vStringNew ();\n\t\tvStringNCopyS (File.path, fileName, length);\n\t}\n}\n\nstatic void setInputFileParametersCommon (inputFileInfo *finfo, vString *const fileName,\n\t\t\t\t\t  const langType language,\n\t\t\t\t\t  stringList *holder)\n{\n\tif (finfo->name != NULL)\n\t\tvStringDelete (finfo->name);\n\tfinfo->name = fileName;\n\n\tif (finfo->tagPath != NULL)\n\t{\n\t\tif (holder)\n\t\t\tstringListAdd (holder, finfo->tagPath);\n\t\telse\n\t\t\tvStringDelete (finfo->tagPath);\n\t}\n\n\tif (0)\n\t\t;\n\telse if (  Option.tagRelative == TREL_ALWAYS )\n\t\tfinfo->tagPath =\n\t\t\tvStringNewOwn (relativeFilename (vStringValue (fileName),\n\t\t\t\t\t\t\t getTagFileDirectory ()));\n\telse if ( Option.tagRelative == TREL_NEVER )\n\t\tfinfo->tagPath =\n\t\t\tvStringNewOwn (absoluteFilename (vStringValue (fileName)));\n\telse if ( Option.tagRelative == TREL_NO || isAbsolutePath (vStringValue (fileName)) )\n\t\tfinfo->tagPath = vStringNewCopy (fileName);\n\telse\n\t\tfinfo->tagPath =\n\t\t\tvStringNewOwn (relativeFilename (vStringValue (fileName),\n\t\t\t\t\t\t\t getTagFileDirectory ()));\n\n\tfinfo->isHeader = isIncludeFile (vStringValue (fileName));\n}\n\nstatic void resetLangOnStack (inputLangInfo *langInfo, langType lang)\n{\n\tAssert (langInfo->stack.count > 0);\n\tlangStackClear  (& (langInfo->stack));\n\tlangStackPush (& (langInfo->stack), lang);\n}\n\nstatic langType baseLangOnStack (inputLangInfo *langInfo)\n{\n\tAssert (langInfo->stack.count > 0);\n\treturn langStackBotom (& (langInfo->stack));\n}\n\nstatic void pushLangOnStack (inputLangInfo *langInfo, langType lang)\n{\n\tlangStackPush (& langInfo->stack, lang);\n}\n\nstatic langType popLangOnStack (inputLangInfo *langInfo)\n{\n\treturn langStackPop (& langInfo->stack);\n}\n\nstatic void clearLangOnStack (inputLangInfo *langInfo)\n{\n\tlangStackClear (& langInfo->stack);\n}\n\nstatic void setInputFileParameters (vString *const fileName, const langType language)\n{\n\tsetInputFileParametersCommon (&File.input, fileName,\n\t\t\t\t      language, NULL);\n\tpushLangOnStack(&inputLang, language);\n}\n\nstatic void setSourceFileParameters (vString *const fileName, const langType language)\n{\n\tsetInputFileParametersCommon (&File.source, fileName,\n\t\t\t\t      language, File.sourceTagPathHolder);\n\tsourceLang = language;\n}\n\nstatic bool setSourceFileName (vString *const fileName)\n{\n\tconst langType language = getLanguageForFilenameAndContents (vStringValue (fileName));\n\tbool result = false;\n\tif (language != LANG_IGNORE)\n\t{\n\t\tvString *pathName;\n\t\tif (isAbsolutePath (vStringValue (fileName)) || File.path == NULL)\n\t\t\tpathName = vStringNewCopy (fileName);\n\t\telse\n\t\t{\n\t\t\tchar *tmp = combinePathAndFile (\n\t\t\t\tvStringValue (File.path), vStringValue (fileName));\n\t\t\tpathName = vStringNewOwn (tmp);\n\t\t}\n\t\tsetSourceFileParameters (pathName, language);\n\t\tresult = true;\n\t}\n\treturn result;\n}\n\n/*\n *   Line directive parsing\n */\n\nstatic void skipWhite (char **str)\n{\n\twhile (**str == ' '  ||  **str == '\\t')\n\t\t(*str)++;\n}\n\nstatic unsigned long readLineNumber (char **str)\n{\n\tchar *s;\n\tunsigned long lNum = 0;\n\n\tskipWhite (str);\n\ts = *str;\n\twhile (*s != '\\0' && isdigit ((unsigned char) *s))\n\t{\n\t\tlNum = (lNum * 10) + (*s - '0');\n\t\ts++;\n\t}\n\tif (*s != ' ' && *s != '\\t')\n\t\tlNum = 0;\n\t*str = s;\n\n\treturn lNum;\n}\n\n/* While ANSI only permits lines of the form:\n *   # line n \"filename\"\n * Earlier compilers generated lines of the form\n *   # n filename\n * GNU C will output lines of the form:\n *   # n \"filename\"\n * So we need to be fairly flexible in what we accept.\n */\nstatic vString *readFileName (char *s)\n{\n\tvString *const fileName = vStringNew ();\n\tbool quoteDelimited = false;\n\n\tskipWhite (&s);\n\tif (*s == '\"')\n\t{\n\t\ts++;  /* skip double-quote */\n\t\tquoteDelimited = true;\n\t}\n\twhile (*s != '\\0'  &&  *s != '\\n'  &&\n\t\t\t(quoteDelimited ? (*s != '\"') : (*s != ' '  &&  *s != '\\t')))\n\t{\n\t\tvStringPut (fileName, *s);\n\t\ts++;\n\t}\n\tvStringPut (fileName, '\\0');\n\n\treturn fileName;\n}\n\nstatic bool parseLineDirective (char *s)\n{\n\tbool result = false;\n\n\tskipWhite (&s);\n\tDebugStatement ( const char* lineStr = \"\"; )\n\n\tif (isdigit ((unsigned char) *s))\n\t\tresult = true;\n\telse if (strncmp (s, \"line\", 4) == 0)\n\t{\n\t\ts += 4;\n\t\tif (*s == ' '  ||  *s == '\\t')\n\t\t{\n\t\t\tDebugStatement ( lineStr = \"line\"; )\n\t\t\tresult = true;\n\t\t}\n\t}\n\tif (result)\n\t{\n\t\tconst unsigned long lNum = readLineNumber (&s);\n\t\tif (lNum == 0)\n\t\t\tresult = false;\n\t\telse\n\t\t{\n\t\t\tvString *const fileName = readFileName (s);\n\t\t\tif (vStringLength (fileName) == 0)\n\t\t\t{\n\t\t\t\tFile.source.lineNumber = lNum - 1;  /* applies to NEXT line */\n\t\t\t\tDebugStatement ( debugPrintf (DEBUG_RAW, \"#%s %ld\", lineStr, lNum); )\n\t\t\t}\n\t\t\telse if (setSourceFileName (fileName))\n\t\t\t{\n\t\t\t\tFile.source.lineNumber = lNum - 1;  /* applies to NEXT line */\n\t\t\t\tDebugStatement ( debugPrintf (DEBUG_RAW, \"#%s %ld \\\"%s\\\"\",\n\t\t\t\t\t\t\t\tlineStr, lNum, vStringValue (fileName)); )\n\t\t\t}\n\n\t\t\tif (vStringLength (fileName) > 0 &&\n\t\t\t\tlNum == 1)\n\t\t\t\tmakeFileTag (vStringValue (fileName));\n\t\t\tvStringDelete (fileName);\n\t\t\tresult = true;\n\t\t}\n\t}\n\treturn result;\n}\n\n/*\n *   Input file I/O operations\n */\n#ifdef DEBUG\n#define MAX_IN_MEMORY_FILE_SIZE 0\n#else\n#define MAX_IN_MEMORY_FILE_SIZE (1024*1024)\n#endif\n\nstatic MIO *getMioFull (const char *const fileName, const char *const openMode,\n\t\t    bool memStreamRequired, time_t *mtime)\n{\n\tFILE *src;\n\tfileStatus *st;\n\tunsigned long size;\n\tunsigned char *data;\n\n\tst = eStat (fileName);\n\tsize = st->size;\n\tif (mtime)\n\t\t*mtime = st->mtime;\n\teStatFree (st);\n\tif ((!memStreamRequired)\n\t    && (size > MAX_IN_MEMORY_FILE_SIZE || size == 0))\n\t\treturn mio_new_file (fileName, openMode);\n\n\tsrc = fopen (fileName, openMode);\n\tif (!src)\n\t\treturn NULL;\n\n\tdata = eMalloc (size);\n\tif (fread (data, 1, size, src) != size)\n\t{\n\t\teFree (data);\n\t\tfclose (src);\n\t\tif (memStreamRequired)\n\t\t\treturn NULL;\n\t\telse\n\t\t\treturn mio_new_file (fileName, openMode);\n\t}\n\tfclose (src);\n\treturn mio_new_memory (data, size, eRealloc, eFreeNoNullCheck);\n}\n\nextern MIO *getMio (const char *const fileName, const char *const openMode,\n\t\t    bool memStreamRequired)\n{\n\treturn getMioFull (fileName, openMode, memStreamRequired, NULL);\n}\n\n/* Return true if utf8 BOM is found */\nstatic bool checkUTF8BOM (MIO *mio, bool skipIfFound)\n{\n\tbool r = false;\n\tif ((0xEF == mio_getc (mio))\n\t\t&& (0xBB == mio_getc (mio))\n\t\t&& (0xBF == mio_getc (mio)))\n\t\tr = true;\n\n\tif (! (r && skipIfFound))\n\t\tmio_rewind (mio);\n\treturn r;\n}\n\nstatic void rewindInputFile (inputFile *f)\n{\n\tmio_rewind (f->mio);\n\tif (f->bomFound)\n\t{\n\t\tint c CTAGS_ATTR_UNUSED;\n\n\t\tc = mio_getc (f->mio);\n\t\tAssert (c == 0xEF);\n\t\tc = mio_getc (f->mio);\n\t\tAssert (c == 0xBB);\n\t\tc = mio_getc (f->mio);\n\t\tAssert (c == 0xBF);\n\t}\n}\n\n/*  This function opens an input file, and resets the line counter.  If it\n *  fails, it will display an error message and leave the File.mio set to NULL.\n */\nextern bool openInputFile (const char *const fileName, const langType language,\n\t\t\t      MIO *mio, time_t mtime)\n{\n\tconst char *const openMode = \"rb\";\n\tbool opened = false;\n\tbool memStreamRequired;\n\n\t/*\tIf another file was already open, then close it.\n\t */\n\tif (File.mio != NULL)\n\t{\n\t\tmio_unref (File.mio);  /* close any open input file */\n\t\tFile.mio = NULL;\n\t}\n\n\t/* File position is used as key for checking the availability of\n\t   pattern cache in entry.h. If an input file is changed, the\n\t   key is meaningless. So notifying the changing here. */\n\tinvalidatePatternCache();\n\n\tif (File.sourceTagPathHolder == NULL)\n\t{\n\t\tFile.sourceTagPathHolder = stringListNew ();\n\t\tDEFAULT_TRASH_BOX(File.sourceTagPathHolder, stringListDelete);\n\t}\n\tstringListClear (File.sourceTagPathHolder);\n\n\tmemStreamRequired = doesParserRequireMemoryStream (language);\n\n\tif (mio)\n\t{\n\t\tsize_t tmp;\n\t\tif (memStreamRequired && (!mio_memory_get_data (mio, &tmp)))\n\t\t\tmio = NULL;\n\t\telse\n\t\t\tmio_rewind (mio);\n\t}\n\n\tFile.mio = mio? mio_ref (mio): getMioFull (fileName, openMode, memStreamRequired, &File.mtime);\n\n\tif (File.mio == NULL)\n\t\terror (WARNING | PERROR, \"cannot open \\\"%s\\\"\", fileName);\n\telse\n\t{\n\t\topened = true;\n\n\t\tif (File.mio == mio)\n\t\t\tFile.mtime = mtime;\n\n\t\tFile.bomFound = checkUTF8BOM (File.mio, true);\n\n\t\tsetOwnerDirectoryOfInputFile (fileName);\n\t\tmio_getpos (File.mio, &StartOfLine.pos);\n\t\tmio_getpos (File.mio, &File.filePosition.pos);\n\t\tFile.filePosition.offset = StartOfLine.offset = mio_tell (File.mio);\n\t\tFile.currentLine  = NULL;\n\n\t\tFile.line = vStringNewOrClear (File.line);\n\t\tFile.ungetchIdx = 0;\n\n\t\tsetInputFileParameters  (vStringNewInit (fileName), language);\n\t\tFile.input.lineNumberOrigin = 0L;\n\t\tFile.input.lineNumber = File.input.lineNumberOrigin;\n\t\tsetSourceFileParameters (vStringNewInit (fileName), language);\n\t\tFile.source.lineNumberOrigin = 0L;\n\t\tFile.source.lineNumber = File.source.lineNumberOrigin;\n\t\tallocLineFposMap (&File.lineFposMap);\n\n\t\tFile.thinDepth = 0;\n\t\tverbose (\"OPENING%s %s as %s language %sfile [%s%s]\\n\",\n\t\t\t\t (File.bomFound? \"(skipping utf-8 bom)\": \"\"),\n\t\t\t\t fileName,\n\t\t\t\t getLanguageName (language),\n\t\t\t\t File.input.isHeader ? \"include \" : \"\",\n\t\t\t\t mio? \"reused\": \"new\",\n\t\t\t\t memStreamRequired? \",required\": \"\");\n\t}\n\treturn opened;\n}\n\nextern time_t getInputFileMtime (void)\n{\n\treturn File.mtime;\n}\n\nextern void resetInputFile (const langType language, bool resetLineFposMap_)\n{\n\tAssert (File.mio);\n\n\trewindInputFile  (&File);\n\tmio_getpos (File.mio, &StartOfLine.pos);\n\tmio_getpos (File.mio, &File.filePosition.pos);\n\tFile.filePosition.offset = StartOfLine.offset = mio_tell (File.mio);\n\tFile.currentLine  = NULL;\n\n\tAssert (File.line);\n\tvStringClear (File.line);\n\tFile.ungetchIdx = 0;\n\n\tif (hasLanguageMultilineRegexPatterns (language)\n\t\t|| hasLanguagePostRunRegexPatterns (language))\n\t\tFile.allLines = vStringNew ();\n\n\tif (resetLineFposMap_)\n\t\tresetLineFposMap(&File.lineFposMap);\n\n\tresetLangOnStack (& inputLang, language);\n\tFile.input.lineNumber = File.input.lineNumberOrigin;\n\tsourceLang = language;\n\tFile.source.lineNumber = File.source.lineNumberOrigin;\n}\n\nextern void closeInputFile (void)\n{\n\tif (File.mio != NULL)\n\t{\n\t\tclearLangOnStack (& inputLang);\n\n\t\t/*  The line count of the file is 1 too big, since it is one-based\n\t\t *  and is incremented upon each newline.\n\t\t */\n\t\tif (Option.printTotals)\n\t\t{\n\t\t\tfileStatus *status = eStat (vStringValue (File.input.name));\n\t\t\taddTotals (0, getInputLineNumber () - 1L, status->size);\n\t\t}\n\t\tmio_unref (File.mio);\n\t\tFile.mio = NULL;\n\t\tfreeLineFposMap (&File.lineFposMap);\n\t}\n}\n\nextern void *getInputFileUserData(void)\n{\n\treturn mio_get_user_data (File.mio);\n}\n\n/*  Action to take for each encountered input newline.\n */\nstatic void fileNewline (bool crAdjustment, size_t posInAllLines)\n{\n\tFile.filePosition = StartOfLine;\n\n\tif (BackupFile.mio == NULL)\n\t\tappendLineFposMap (&File.lineFposMap, &File.filePosition,\n\t\t\t\t\t\t   crAdjustment, posInAllLines);\n\n\tFile.input.lineNumber++;\n\tFile.source.lineNumber++;\n\tDebugStatement ( if (Option.breakLine == getInputLineNumber ()) lineBreak (); )\n\tDebugStatement ( debugPrintf (DEBUG_RAW, \"%6ld: \", getInputLineNumber ()); )\n}\n\nextern void ungetcToInputFile (int c)\n{\n\tconst size_t len = ARRAY_SIZE (File.ungetchBuf);\n\n\tAssert (File.ungetchIdx < len);\n\t/* we cannot rely on the assertion that might be disabled in non-debug mode */\n\tif (File.ungetchIdx < len)\n\t\tFile.ungetchBuf[File.ungetchIdx++] = c;\n}\n\ntypedef enum eEolType {\n\teol_eof = 0,\n\teol_nl,\n\teol_cr_nl,\n} eolType;\n\nstatic eolType readLine (vString *const vLine, MIO *const mio)\n{\n\tchar *str;\n\tsize_t size;\n\teolType r = eol_nl;\n\n\tvStringClear (vLine);\n\n\tstr = vStringValue (vLine);\n\tsize = vStringSize (vLine);\n\n\tfor (;;)\n\t{\n\t\tbool newLine;\n\t\tbool eof;\n\n\t\tif (mio_gets (mio, str, size) == NULL)\n\t\t{\n\t\t\tif (!mio_eof (mio))\n\t\t\t\terror (FATAL | PERROR, \"Failure on attempt to read file\");\n\t\t}\n\t\tvStringSetLength (vLine);\n\t\tnewLine = vStringLength (vLine) > 0 && vStringLast (vLine) == '\\n';\n\t\teof = mio_eof (mio);\n\t\tif (eof)\n\t\t\tr = eol_eof;\n\n\t\t/* Turn line breaks into a canonical form. The three commonly\n\t\t * used forms of line breaks are: LF (UNIX/Mac OS X), CR-LF (MS-DOS) and\n\t\t * CR (Mac OS 9). As CR-only EOL isn't handled by gets() and Mac OS 9\n\t\t * is dead, we only handle CR-LF EOLs and convert them into LF. */\n\t\tif (newLine && vStringLength (vLine) > 1 &&\n\t\t\tvStringChar (vLine, vStringLength (vLine) - 2) == '\\r')\n\t\t{\n\t\t\tvStringChar (vLine, vStringLength (vLine) - 2) = '\\n';\n\t\t\tvStringChop (vLine);\n\t\t\tr = eol_cr_nl;\n\t\t}\n\n\t\tif (newLine || eof)\n\t\t\tbreak;\n\n\t\tvStringResize (vLine, vStringLength (vLine) * 2);\n\t\tstr = vStringValue (vLine) + vStringLength (vLine);\n\t\tsize = vStringSize (vLine) - vStringLength (vLine);\n\t}\n\treturn r;\n}\n\nstatic vString *iFileGetLine (bool chop_newline)\n{\n\teolType eol;\n\tlangType lang = getInputLanguage();\n\n\tAssert (File.line);\n\teol = readLine (File.line, File.mio);\n\n\tif (vStringLength (File.line) > 0)\n\t{\n\t\t/* Use StartOfLine from previous iFileGetLine() call */\n\t\tfileNewline (eol == eol_cr_nl, File.allLines? vStringLength(File.allLines): 0);\n\t\t/* Store StartOfLine for the next iFileGetLine() call */\n\t\tmio_getpos (File.mio, &StartOfLine.pos);\n\t\tStartOfLine.offset = mio_tell (File.mio);\n\n\t\tif (Option.lineDirectives && vStringChar (File.line, 0) == '#')\n\t\t\tparseLineDirective (vStringValue (File.line) + 1);\n\n\t\tif (File.allLines)\n\t\t\tvStringCat (File.allLines, File.line);\n\n\t\tbool chopped = vStringStripNewline (File.line);\n\n\t\tmatchLanguageRegex (lang, File.line, false);\n\n\t\tif (chopped && !chop_newline)\n\t\t\tvStringPutNewlinAgainUnsafe (File.line);\n\n\t\treturn File.line;\n\t}\n\telse\n\t{\n\t\tif (File.allLines)\n\t\t{\n\t\t\tmatchLanguageMultilineRegex (lang, File.allLines);\n\t\t\tmatchLanguageMultitableRegex (lang, File.allLines);\n\n\t\t\tif (hasLanguagePostRunRegexPatterns (lang))\n\t\t\t{\n\n\t\t\t\tunsigned input_ln = File.input.lineNumber;\n\t\t\t\tunsigned source_ln = File.source.lineNumber;\n\t\t\t\tMIOPos pos = File.filePosition.pos;\n\n\t\t\t\tvString *line = vStringNew();\n\t\t\t\tfor (size_t i = 0; i < File.lineFposMap.count; i++)\n\t\t\t\t{\n\t\t\t\t\tFile.input.lineNumber = i + 1;\n\t\t\t\t\tFile.source.lineNumber = File.input.lineNumber;\n\t\t\t\t\tFile.filePosition.pos = File.lineFposMap.pos[i].pos;\n\n\t\t\t\t\tvStringNCopySUnsafe(line,\n\t\t\t\t\t\t\t\t\t\tvStringValue(File.allLines) +\n\t\t\t\t\t\t\t\t\t\tFile.lineFposMap.pos[i].posInAllLines,\n\t\t\t\t\t\t\t\t\t\t(((i + 1) < File.lineFposMap.count)\n\t\t\t\t\t\t\t\t\t\t ? File.lineFposMap.pos[i+1].posInAllLines\n\t\t\t\t\t\t\t\t\t\t : vStringLength (File.allLines))\n\t\t\t\t\t\t\t\t\t\t- File.lineFposMap.pos[i].posInAllLines);\n\t\t\t\t\tmatchLanguageRegex (lang, line, true);\n\t\t\t\t}\n\t\t\t\tvStringDelete(line);\n\n\t\t\t\tFile.filePosition.pos = pos;\n\t\t\t\tFile.input.lineNumber = input_ln;\n\t\t\t\tFile.source.lineNumber = source_ln;\n\t\t\t}\n\n\t\t\t/* To limit the execution of multiline/multitable parser(s) only\n\t\t\t   ONCE, clear File.allLines field. */\n\t\t\tvStringDelete (File.allLines);\n\t\t\tFile.allLines = NULL;\n\t\t}\n\t\treturn NULL;\n\t}\n}\n\n/*  Do not mix use of readLineFromInputFile () and getcFromInputFile () for the same file.\n */\nextern int getcFromInputFile (void)\n{\n\tint c;\n\n\t/*  If there is an ungotten character, then return it.  Don't do any\n\t *  other processing on it, though, because we already did that the\n\t *  first time it was read through getcFromInputFile ().\n\t */\n\tif (File.ungetchIdx > 0)\n\t{\n\t\tc = File.ungetchBuf[--File.ungetchIdx];\n\t\treturn c;  /* return here to avoid re-calling debugPutc () */\n\t}\n\tdo\n\t{\n\t\tif (File.currentLine != NULL)\n\t\t{\n\t\t\tc = *File.currentLine++;\n\t\t\tif (c == '\\0')\n\t\t\t\tFile.currentLine = NULL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvString* const line = iFileGetLine (false);\n\t\t\tif (line != NULL)\n\t\t\t\tFile.currentLine = (unsigned char*) vStringValue (line);\n\t\t\tif (File.currentLine == NULL)\n\t\t\t\tc = EOF;\n\t\t\telse\n\t\t\t\tc = '\\0';\n\t\t}\n\t} while (c == '\\0');\n\tDebugStatement ( debugPutc (DEBUG_READ, c); )\n\treturn c;\n}\n\n/* returns the nth previous character (0 meaning current), or def if nth cannot\n * be accessed.  Note that this can't access previous line data. */\nextern int getNthPrevCFromInputFile (unsigned int nth, int def)\n{\n\tconst unsigned char *base = (unsigned char *) vStringValue (File.line);\n\tconst unsigned int offset = File.ungetchIdx + 1 + nth;\n\n\tif (File.currentLine != NULL && File.currentLine >= base + offset)\n\t\treturn (int) *(File.currentLine - offset);\n\telse\n\t\treturn def;\n}\n\nextern int skipToCharacterInInputFile (int c)\n{\n\tint d;\n\tdo\n\t{\n\t\td = getcFromInputFile ();\n\t} while (d != EOF && d != c);\n\treturn d;\n}\n\nextern int skipToCharacterInInputFile2 (int c0, int c1)\n{\n\tint d;\n\tdo\n\t{\n\t\tskipToCharacterInInputFile(c0);\n\t\tdo\n\t\t\td = getcFromInputFile ();\n\t\twhile (d == c0 && d != c1);\n\t} while (d != EOF && d != c1);\n\treturn d;\n}\n\n/*  An alternative interface to getcFromInputFile (). Do not mix use of readLineFromInputFile()\n *  and getcFromInputFile() for the same file. The returned string does not contain\n *  the terminating newline. A NULL return value means that all lines in the\n *  file have been read and we are at the end of file.\n */\nextern const unsigned char *readLineFromInputFileWithLength (size_t *length)\n{\n\tvString* const line = iFileGetLine (true);\n\tconst unsigned char* result = NULL;\n\tif (line != NULL)\n\t{\n\t\tresult = (const unsigned char*) vStringValue (line);\n\t\t*length = vStringLength (line);\n\t\tDebugStatement ( debugPrintf (DEBUG_READ, \"%s\\n\", result); )\n\t}\n\treturn result;\n}\n\nextern const unsigned char *readLineFromInputFile (void)\n{\n\tsize_t dummy;\n\treturn readLineFromInputFileWithLength(&dummy);\n}\n\n/*\n *   Raw file line reading with automatic buffer sizing\n */\nextern char *readLineRaw (vString *const vLine, MIO *const mio)\n{\n\tif (mio == NULL)  /* to free memory allocated to buffer */\n\t\terror (FATAL, \"NULL file pointer\");\n\telse\n\t{\n\t\treadLine (vLine, mio);\n\n#ifdef HAVE_ICONV\n\t\tif (isConverting ())\n\t\t\tconvertString (vLine);\n#endif\n\t}\n\treturn vStringLength (vLine) > 0 ? vStringValue (vLine) : NULL;\n}\n\n/*  Places into the line buffer the contents of the line referenced by\n *  \"pos\".\n */\nstruct readLineRawCbData {\n\tMIOPos pos;\n\tlong *offset;\n\tvString *vLine;\n\tchar *result;\n};\n\nstatic void readLineRawCb (MIO *mio, void *data)\n{\n\tstruct readLineRawCbData *cb_data = data;\n\n\tmio_setpos (mio, &cb_data->pos);\n\tmio_clearerr (mio);\n\tif (cb_data->offset)\n\t\t*cb_data->offset = mio_tell (mio);\n\n\t/* If the file is empty, we can't get the line\n\t   for position 0. readLineFromBypass doesn't know\n\t   what itself should do; just report it to the caller. */\n\tcb_data->result = readLineRaw (cb_data->vLine, mio);\n}\n\nextern char *readLineFromBypass (\n\t\tvString *const vLine, MIOPos pos, long *const offset)\n{\n\tstruct readLineRawCbData data = {\n\t\t.pos = pos,\n\t\t.offset = offset,\n\t\t.vLine = vLine,\n\t\t.result = NULL,\n\t};\n\n\tcallWithSavingPosition (File.mio, readLineRawCb, &data);\n\n\treturn data.result;\n}\n\nextern void   pushArea (\n\t\t\t\t       bool useMemoryStreamInput,\n\t\t\t\t       unsigned long startLine, long startColumn,\n\t\t\t\t       unsigned long endLine, long endColumn,\n\t\t\t\t       unsigned long sourceLineOffset,\n\t\t\t\t       int promise)\n{\n\tlong p, q;\n\tMIOPos original;\n\tMIOPos tmp;\n\tMIO *subio;\n\n\tif (isThinAreaSpec (startLine, startColumn,\n\t\t\t\t\t\tendLine, endColumn,\n\t\t\t\t\t\tsourceLineOffset))\n\t{\n\t\tif ((!useMemoryStreamInput\n\t\t\t || mio_memory_get_data (File.mio, NULL)))\n\t\t{\n\t\t\tFile.thinDepth++;\n\t\t\tverbose (\"push thin area (%d)\\n\", File.thinDepth);\n\t\t\treturn;\n\t\t}\n\t\terror(WARNING, \"INTERNAL ERROR: though pushing MEMORY based thin area, \"\n\t\t\t  \"underlying area is a FILE base: %s@%s\",\n\t\t\t  vStringValue (File.input.name), vStringValue (File.input.tagPath));\n\t\tAssertNotReached ();\n\t}\n\tAssert (File.thinDepth == 0);\n\n\toriginal = getInputFilePosition ();\n\n\ttmp = getInputFilePositionForLine (startLine);\n\tmio_setpos (File.mio, &tmp);\n\tmio_seek (File.mio, startColumn, SEEK_CUR);\n\tp = mio_tell (File.mio);\n\n\ttmp = getInputFilePositionForLine (endLine);\n\tmio_setpos (File.mio, &tmp);\n\tif (endColumn == EOL_COLUMN)\n\t{\n\t\tlong line_start = mio_tell (File.mio);\n\t\tvString *tmpstr = vStringNew ();\n\t\treadLine (tmpstr, File.mio);\n\t\tendColumn = mio_tell (File.mio) - line_start;\n\t\tvStringDelete (tmpstr);\n\t\tAssert (endColumn >= 0);\n\t}\n\telse\n\t\tmio_seek (File.mio, endColumn, SEEK_CUR);\n\tq = mio_tell (File.mio);\n\n\tmio_setpos (File.mio, &original);\n\n\tinvalidatePatternCache();\n\n\tsize_t size = q - p;\n\tsubio = mio_new_mio (File.mio, p, size);\n\tif (subio == NULL)\n\t\terror (FATAL, \"memory for mio may be exhausted\");\n\n\trunModifiers (promise,\n\t\t\t\t  startLine, startColumn,\n\t\t\t\t  endLine, endColumn,\n\t\t\t\t  mio_memory_get_data (subio, NULL),\n\t\t\t\t  size);\n\n\tBackupFile = File;\n\n\tFile.mio = subio;\n\tFile.bomFound = false;\n\tFile.areaInfo.startOffset = p;\n\tFile.areaInfo.startLine = startLine;\n\tFile.areaInfo.startColumn = startColumn;\n\tFile.areaInfo.endLine = endLine;\n\tFile.areaInfo.endColumn = endColumn;\n\n\tFile.input.lineNumberOrigin = ((startLine == 0)? 0: startLine - 1);\n\tFile.source.lineNumberOrigin = ((sourceLineOffset == 0)? 0: sourceLineOffset - 1);\n}\n\nextern bool isAreaStacked (void)\n{\n\treturn !(File.areaInfo.startLine == 0\n\t\t\t && File.areaInfo.startColumn == 0\n\t\t\t && File.areaInfo.endLine == 0\n\t\t\t && File.areaInfo.endColumn == 0);\n}\n\nextern unsigned int getAreaBoundaryInfo (unsigned long lineNumber)\n{\n\tunsigned int info;\n\n\tif (!isAreaStacked())\n\t\treturn 0;\n\n\tinfo = 0;\n\tif (File.areaInfo.startLine == lineNumber\n\t    && File.areaInfo.startColumn != 0)\n\t\tinfo |= AREA_BOUNDARY_START;\n\tif (File.areaInfo.endLine == lineNumber\n\t    && File.areaInfo.endColumn != 0)\n\t\tinfo |= AREA_BOUNDARY_END;\n\n\treturn info;\n}\nextern void   popArea  (void)\n{\n\tif (File.thinDepth)\n\t{\n\t\tFile.thinDepth--;\n\t\tverbose (\"CLEARING thin flag(%d)\\n\", File.thinDepth);\n\t\treturn;\n\t}\n\tmio_unref (File.mio);\n\tFile = BackupFile;\n\tmemset (&BackupFile, 0, sizeof (BackupFile));\n}\n\nextern void pushLanguage (const langType language)\n{\n\tpushLangOnStack (& inputLang, language);\n}\n\nextern langType popLanguage (void)\n{\n\treturn popLangOnStack (& inputLang);\n}\n\nextern langType getLanguageForBaseParser (void)\n{\n\treturn baseLangOnStack (& inputLang);\n}\n\nstatic void langStackInit (langStack *langStack)\n{\n\tlangStack->count = 0;\n\tlangStack->size  = 1;\n\tlangStack->languages = xCalloc (langStack->size, langType);\n\tDEFAULT_TRASH_BOX(&(langStack->languages), eFreeIndirect);\n}\n\nstatic langType langStackTop (langStack *langStack)\n{\n\tAssert (langStack->count > 0);\n\treturn langStack->languages [langStack->count - 1];\n}\n\nstatic langType langStackBotom(langStack *langStack)\n{\n\tAssert (langStack->count > 0);\n\treturn langStack->languages [0];\n}\n\nstatic void     langStackClear (langStack *langStack)\n{\n\twhile (langStack->count > 0)\n\t\tlangStackPop (langStack);\n}\n\nstatic void     langStackPush (langStack *langStack, langType type)\n{\n\tif (langStack->size == 0)\n\t\tlangStackInit (langStack);\n\telse if (langStack->count == langStack->size)\n\t\tlangStack->languages = xRealloc (langStack->languages,\n\t\t\t\t\t\t ++ langStack->size, langType);\n\tlangStack->languages [ langStack->count ++ ] = type;\n}\n\nstatic langType langStackPop  (langStack *langStack)\n{\n\treturn langStack->languages [ -- langStack->count ];\n}\n\nextern bool isThinAreaSpec (unsigned long startLine, long startColumn,\n\t\t\t\t\t\t\tunsigned long endLine, long endColumn,\n\t\t\t\t\t\t\tunsigned long sourceLineOffset)\n{\n\treturn (startLine == 0 &&\n\t\t\tstartColumn == 0 &&\n\t\t\tendLine == 0 &&\n\t\t\tendColumn == 0 &&\n\t\t\tsourceLineOffset == 0);\n}\n\n#ifdef DO_TRACING\nextern bool isTraced (void)\n{\n\tif (File.mio == NULL)\n\t\t/* A parser is not given. In that case, just check whether --_trace option\n\t\t   is given or not. */\n\t\treturn isMainTraced ();\n\telse\n\t\t/* A parser is given. In that case, check whether the current parser is\n\t\t   specified in --_trace=<LANG>,... option */\n\t\treturn isLanguageTraced (getInputLanguage ());\n}\n#endif\t/* DO_TRACING */\n"
  },
  {
    "path": "main/read.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to read.c\n*/\n#ifndef CTAGS_MAIN_READ_H\n#define CTAGS_MAIN_READ_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <stdio.h>\n#include <ctype.h>\n\n#include \"types.h\"\n#include \"vstring.h\"\n#include \"mio.h\"\n\n/*\n*   MACROS\n*/\n\n/*\n*   DATA DECLARATIONS\n*/\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\n/*\n * We provide parsers some functions to get *locations*.\n *\n * We have three types of locations: line number, position, and\n * offset.\n *\n * Area\n * ----\n * An *area* is a contentious part of an input file.\n * If a parser runs as a *host parser*, the area covers whole the\n * input file.\n *\n * input file ---> +-----------------+\n *                 |<                |\n *                 |                 |\n *                 |      area       |\n *                 |                 |\n *                 |                >|\n *                 +-----------------+\n *\n * When a *host parser* finds a sub area where another programming\n * language is used, the parser can let another parser (*guest\n * parser*) suitable for the language process the sub area.\n *\n * input file ---> +-----------------+\n *                 |<      area      |\n *                 |   [.............|\n *                 |....area (sub)...|\n *                 |....]            |\n *                 |                >|\n *                 +-----------------+\n *\n * Regardless of whether a parser runs as a host or guest, we\n * call the area that the parser processes \"the current area\".\n * We call the area that the host parser processes \"the base area\".\n *\n * From the view of a host parser, its current area and its\n * base area are the same.\n * From the vie of a guest parser, its current area and its\n * base area are different.\n *\n * Coordinate system\n * -----------------\n * When dealing with the functions related to locations, we must\n * consider the *coordinate system* of locations.\n *\n * *Absolute coordinate system* is a coordinate system that origin\n * is at the start of the base area.\n *\n * *Current coordinate system* is a coordinate system that origin\n * is at the start of the current area.\n *\n * Let's see an example.\n *\n * Consider calling a function getting a location from a parser\n * running as a guest.\n *\n * input file ---> +-----------------+\n *                 |<   base area    |\n *                 |   [.........X...|\n *                 |..current area...|\n *                 |....]            |\n *                 |                >|\n *                 +-----------------+\n *\n * The line number for X is 2 in the absolute coordinate system.\n * The line number for X is 1 in the current coordinate system.\n */\n\n/* We have had many bugs caused by misunderstanding coordinate systems.\n * So we use markers [absolute], [current] or [buggy] and put them\n * on the declarations of functions getting locations.\n *\n * A function marked [buggy] may return [absolute] or [current]\n * locations. We should have no [buggy] marker in the future.\n *\n * [rename] is a marker for functions that should be renamed.\n */\n\n/* return: [absolute] */\nextern unsigned long getInputLineNumber (void);\n\n/* return: [absolute],\n * args (offset): [absolute] */\nextern unsigned long getInputLineNumberForFileOffset(long offset);\n\n/* Get the column number, the byte offset of the input from the\n * begging of the line.\n *\n * This function works only if the parser uses getcFromInputFile().\n * This function doesn't work if the parser uses readLineFromInputFile().\n *\n * return: [absolute]\n */\nextern int getInputColumnNumber (void);\n\n/* return: [current] */\nextern MIOPos getInputFilePosition (void);\n\n/* return: [current],\n * args (line): [absolute] */\nextern MIOPos getInputFilePositionForLine (unsigned int line);\n\n/* return: [absolute]\n * args (line): [current]\n *\n * LINE argument is assumed 1 based.\n */\nextern unsigned long translateLineNumber (unsigned long line);\n\n/* return: [absolute]\n * args (offset): [current]\n */\nextern long translateFileOffset (unsigned long offset);\n\nextern const char *getInputFileName (void);\nextern langType getInputLanguage (void);\nextern bool isInputLanguage (langType lang);\nextern bool isInputHeaderFile (void);\nextern bool isInputLanguageKindEnabled (int kindIndex);\nextern bool isInputLanguageRoleEnabled (int kindIndex, int roleIndex);\n\nextern const unsigned char *getInputFileData (size_t *size);\n\nextern int getcFromInputFile (void);\nextern int getNthPrevCFromInputFile (unsigned int nth, int def);\nextern int skipToCharacterInInputFile (int c);\nextern int skipToCharacterInInputFile2 (int c0, int c1);\nextern void ungetcToInputFile (int c);\nextern const unsigned char *readLineFromInputFile (void);\nextern const unsigned char *readLineFromInputFileWithLength (size_t *length);\n\nextern unsigned long getSourceLineNumber (void);\n\n/* Raw: reading from given a parameter, mio */\nextern char *readLineRaw (vString *const vLine, MIO *const mio);\n\nextern void     pushLanguage(const langType language);\nextern langType popLanguage (void);\n\n#endif  /* CTAGS_MAIN_READ_H */\n"
  },
  {
    "path": "main/read_p.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Main part private interface to read.c\n*/\n#ifndef CTAGS_MAIN_READ_PRIVATE_H\n#define CTAGS_MAIN_READ_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"mio.h\"\n#include \"types.h\"\n#include \"vstring.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\n\nenum areaBoundaryFlag {\n\tAREA_BOUNDARY_START = 1UL << 0,\n\tAREA_BOUNDARY_END   = 1UL << 1,\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern const char *getInputLanguageName (void);\nextern const char *getInputFileTagPath (void);\n\n/* return: [absolute],\n * args (line): [absolute] */\nextern long getInputFileOffsetForLine (unsigned int line);\n\nextern unsigned int countInputLanguageKinds (void);\nextern unsigned int countInputLanguageRoles (int kindIndex);\n\nextern bool doesInputLanguageRequestAutomaticFQTag (const tagEntryInfo *e);\nextern bool doesSubparserRun (void);\nextern langType getLanguageForBaseParser (void);\n\nextern bool isParserMarkedNoEmission (void);\nextern void freeInputFileResources (void);\n\n/* Stream opened by getMio can be passed to openInputFile as the 3rd\n   argument. If the 3rd argument is NULL, openInputFile calls getMio\n   internally. The 3rd argument is introduced for reusing mio object\n   created in parser guessing stage. */\nextern bool openInputFile (const char *const fileName, const langType language, MIO *mio, time_t mtime);\nextern MIO *getMio (const char *const fileName, const char *const openMode,\n\t\t\t\t    bool memStreamRequired);\nextern void resetInputFile (const langType language, bool resetLineFposMap_);\nextern void closeInputFile (void);\nextern void *getInputFileUserData(void);\n\n\n/* args (line): [absolute] */\nextern unsigned int getAreaBoundaryInfo (unsigned long lineNumber);\n\nextern const char *getSourceFileTagPath (void);\nextern langType getSourceLanguage (void);\n\nextern time_t getInputFileMtime (void);\n\n/* Bypass : read a line at POS from the current area WITHOUT updating the state of the area.\n * If OFFSET is not NULL, the function sets the offset value for POS.\n *\n * args (pos): [buggy]\n * args (offset): [buggy]\n */\nextern char *readLineFromBypass (vString *const vLine, MIOPos pos, long *const offset);\n\n/* args (startLine): [absolute]\n * args (startColumn): [buggy]\n * args (endLine): [absolute]\n * args (endColumn): [absolute]\n * args (sourceLineOffset): [buggy]\n */\nextern void   pushArea (\n\t\t\t\t       bool useMemoryStreamInput,\n\t\t\t\t       unsigned long startLine, long startColumn,\n\t\t\t\t       unsigned long endLine, long endColumn,\n\t\t\t\t       unsigned long sourceLineOffset,\n\t\t\t\t       int promise);\nextern void   popArea  (void);\n\nextern bool isAreaStacked (void);\n\n/* args (startLine): [absolute]\n * args (endLine): [absolute]\n * args (sourceLineOffset): [buggy]\n */\n#define THIN_AREA_SPEC 0, 0, 0, 0, 0\nextern bool isThinAreaSpec (unsigned long startLine, long startColumn,\n\t\t\t\t\t\t\tunsigned long endLine, long endColumn,\n\t\t\t\t\t\t\tunsigned long sourceLineOffset);\n\n/* args (startLine): [absolute]\n   args (startColumn): [buggy]\n   args (endLine): [absolute]\n   args (endColumn): [absolute] */\nextern void getAreaInfo (unsigned long *startLine,\n\t\t\t\t\t\t long *startColumn,\n\t\t\t\t\t\t unsigned long *endLine,\n\t\t\t\t\t\t long *endColumn);\n\n#endif  /* CTAGS_MAIN_READ_PRIVATE_H */\n"
  },
  {
    "path": "main/repoinfo.c",
    "content": "#include \"general.h\"\n#include \"ctags.h\"\n\n#ifdef HAVE_REPOINFO_H\n#include \"main/repoinfo.h\"\n#endif\n\n#ifndef CTAGS_REPOINFO\n#define CTAGS_REPOINFO ((char*)0)\n#endif\n\nconst char* ctags_repoinfo = CTAGS_REPOINFO;\n"
  },
  {
    "path": "main/rexprcode.c",
    "content": "/*\n*   Copyright (c) 2025, Red Hat, Inc.\n*   Copyright (c) 2025, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n\n#include \"routines.h\"\n#include \"rexprcode_p.h\"\n\n#include <regex.h>\n#include <string.h>\n\n/*\n*   DATA DECLARATIONS\n*/\nstruct rExprCode {\n\tregex_t *code;\n\tchar *src;\n\tbool iCase;\n};\n\n/*\n*   FUNCTION DECLARATIONS\n*/\nextern const char *rExprCodeGetSource (const struct rExprCode *rxcode)\n{\n\treturn rxcode->src;\n}\n\nextern bool rExprCodeGetICase (const struct rExprCode *rxcode)\n{\n\treturn rxcode->iCase;\n}\n\nextern vString *rExprCodeNewEncodedSource (const struct rExprCode *rxcode)\n{\n\tvString *encoded_src = vStringNew();\n\n\tvStringPut (encoded_src, '%');\n\n\tfor (const char *c = rExprCodeGetSource (rxcode); *c != '\\0'; c++)\n\t{\n\t\tif (*c == '%')\n\t\t\tvStringPut (encoded_src, '\\\\');\n\t\tvStringPut (encoded_src, *c);\n\t}\n\n\tvStringPut (encoded_src, '%');\n\tif (rExprCodeGetICase (rxcode))\n\t\tvStringPut (encoded_src, 'i');\n\n\treturn encoded_src;\n}\n\nextern struct rExprCode *rExprCodeNew(const char *rxsrc, bool iCase)\n{\n\tregex_t *regex_code = xMalloc (1, regex_t);\n\tint errcode = regcomp (regex_code, rxsrc,\n\t\t\t\t\t\t   REG_EXTENDED|REG_NOSUB|(iCase? REG_ICASE: 0));\n\tif (errcode != 0)\n\t{\n\t\tchar errmsg[256];\n\t\tregerror (errcode, regex_code, errmsg, sizeof(errmsg));\n\t\terror (WARNING, \"regcomp: %s\", errmsg);\n\t\tregfree (regex_code);\n\t\teFree (regex_code);\n\t\treturn NULL;\n\t}\n\n\tstruct rExprCode *rxcode = xMalloc (1, struct rExprCode);\n\n\trxcode->code = regex_code;\n\trxcode->src = eStrdup (rxsrc);\n\trxcode->iCase = iCase;\n\n\treturn rxcode;\n}\n\nextern void rExprCodeDelete (struct rExprCode *rxcode)\n{\n\tregfree (rxcode->code);\n\teFree (rxcode->code);\n\teFree (rxcode->src);\n\teFree (rxcode);\n}\n\nextern bool rExprCodeMatch (struct rExprCode *rxcode, const char *fname)\n{\n\treturn (regexec (rxcode->code, fname, 0, 0, 0) == 0);\n}\n"
  },
  {
    "path": "main/rexprcode_p.h",
    "content": "/*\n*   Copyright (c) 2025, Red Hat, Inc.\n*   Copyright (c) 2025, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n\n*/\n\n#ifndef CTAGS_MAIN_REXPRCODE_H\n#define CTAGS_MAIN_REXPRCODE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n\n#include \"vstring.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\n\nstruct rExprCode;\n\n/*\n*   FUNCTION DECLARATIONS\n*/\nextern const char *rExprCodeGetSource (const struct rExprCode *rxcode);\nextern vString *rExprCodeNewEncodedSource (const struct rExprCode *rxcode);\nextern bool rExprCodeGetICase (const struct rExprCode *rxcode);\nextern struct rExprCode *rExprCodeNew(const char *rxsrc, bool iCase);\nextern void rExprCodeDelete (struct rExprCode *rxcode);\nextern bool rExprCodeMatch (struct rExprCode *rxcode, const char *fname);\n\n#endif\t/* CTAGS_MAIN_REXPRCODE_H */\n"
  },
  {
    "path": "main/routines.c",
    "content": "/*\n*   Copyright (c) 2002-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains a lose assortment of shared functions.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <stdlib.h>  /* to declare malloc (), realloc (), mbcs() */\n#include <ctype.h>\n#include <string.h>\n#include <stdio.h>  /* to declare tempnam(), and SEEK_SET (hopefully) */\n\n#ifdef HAVE_FCNTL_H\n# include <fcntl.h>  /* to declare O_RDWR, O_CREAT, O_EXCL */\n#endif\n#ifdef HAVE_UNISTD_H\n# include <unistd.h>  /* to declare mkstemp () */\n#endif\n\n#include <limits.h>  /* to declare MB_LEN_MAX */\n#ifndef MB_LEN_MAX\n# define MB_LEN_MAX 6\n#endif\n\n/*  To declare \"struct stat\" and stat ().\n */\n#if defined (HAVE_SYS_TYPES_H)\n# include <sys/types.h>\n#else\n# if defined (HAVE_TYPES_H)\n#  include <types.h>\n# endif\n#endif\n#ifdef HAVE_SYS_STAT_H\n# include <sys/stat.h>\n#else\n# ifdef HAVE_STAT_H\n#  include <stat.h>\n# endif\n#endif\n\n#ifdef HAVE_DIRECT_H\n# include <direct.h>  /* to _getcwd */\n#endif\n#ifdef HAVE_IO_H\n# include <io.h>  /* to declare open() */\n#endif\n#include \"debug.h\"\n#include \"routines.h\"\n#include \"routines_p.h\"\n#include <errno.h>\n\n#include \"vstring.h\"\n\n/*\n*   MACROS\n*/\n#ifndef TMPDIR\n# define TMPDIR \"/tmp\"\n#endif\n\n/*  File type tests.\n */\n#ifndef S_ISREG\n# if defined (S_IFREG)\n#  define S_ISREG(mode)\t\t((mode) & S_IFREG)\n# endif\n#endif\n\n#ifndef S_ISLNK\n# ifdef S_IFLNK\n#  define S_ISLNK(mode)\t\t(((mode) & S_IFMT) == S_IFLNK)\n# else\n#  define S_ISLNK(mode)\t\tfalse  /* assume no soft links */\n# endif\n#endif\n\n#ifndef S_ISDIR\n# ifdef S_IFDIR\n#  define S_ISDIR(mode)\t\t(((mode) & S_IFMT) == S_IFDIR)\n# else\n#  define S_ISDIR(mode)\t\tfalse  /* assume no soft links */\n# endif\n#endif\n\n#ifndef S_IFMT\n# define S_IFMT 0\n#endif\n\n#ifndef S_IXUSR\n# define S_IXUSR 0\n#endif\n#ifndef S_IXGRP\n# define S_IXGRP 0\n#endif\n#ifndef S_IXOTH\n# define S_IXOTH 0\n#endif\n\n#ifndef S_IRUSR\n# define S_IRUSR 0400\n#endif\n#ifndef S_IWUSR\n# define S_IWUSR 0200\n#endif\n\n#ifndef S_ISUID\n# define S_ISUID 0\n#endif\n\n#ifndef S_ISGID\n# define S_ISGID 0\n#endif\n\n/*  Hack for ridiculous practice of Microsoft Visual C++.\n */\n#if defined (_WIN32)\n# if defined (_MSC_VER) || defined (__MINGW32__)\n#  ifndef stat\n#   define stat    _stat\n#  endif\n#  define getcwd  _getcwd\n#  define currentdrive() (_getdrive() + 'A' - 1)\n# else\n#  define currentdrive() 'C'\n# endif\n#endif\n\n#ifndef PATH_MAX\n# define PATH_MAX 256\n#endif\n\n/*\n *  Miscellaneous macros\n */\n\n\n/*\n*   DATA DEFINITIONS\n*/\n#if defined (MSDOS_STYLE_PATH)\nconst char *const PathDelimiters = \":/\\\\\";\n#endif\n\nchar *CurrentDirectory;\n\nstatic const char *ExecutableProgram;\nstatic const char *ExecutableName;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n#ifdef NEED_PROTO_STAT\nextern int stat (const char *, struct stat *);\n#endif\n#ifdef NEED_PROTO_LSTAT\nextern int lstat (const char *, struct stat *);\n#endif\n#if defined (_WIN32)\n# define lstat(fn,buf) stat(fn,buf)\n#endif\n\nstatic bool isPathSeparator (const int c);\nstatic char *strSeparator (const char *s);\nstatic char *strRSeparator (const char *s);\nstatic void canonicalizePath (char *const path);\n\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nextern void freeRoutineResources (void)\n{\n\tif (CurrentDirectory != NULL)\n\t\teFree (CurrentDirectory);\n}\n\nextern void setExecutableName (const char *const path)\n{\n\tExecutableProgram = path;\n\tExecutableName = baseFilename (path);\n}\n\nextern const char *getExecutableName (void)\n{\n\treturn ExecutableName;\n}\n\nextern const char *getExecutablePath (void)\n{\n\treturn ExecutableProgram;\n}\n\n/*\n *  compare file/dirname characters with platform-correct case sensitivity\n */\nstatic bool fnmChEq (int c1, int c2)\n{\n#ifdef _WIN32\n\treturn tolower( c1 ) == tolower( c2 );  /* case-insensitive */\n#else\n\treturn          c1   ==          c2  ;  /* case-  sensitive */\n#endif\n}\n\n/*\n *  Memory allocation functions\n */\n\nextern void *eMalloc (const size_t size)\n{\n\tvoid *buffer = malloc (size);\n\n\tif (buffer == NULL && size != 0)\n\t\terror (FATAL, \"out of memory\");\n\n\treturn buffer;\n}\n\nextern void *eCalloc (const size_t count, const size_t size)\n{\n\tvoid *buffer = calloc (count, size);\n\n\tif (buffer == NULL && count != 0 && size != 0)\n\t\terror (FATAL, \"out of memory\");\n\n\treturn buffer;\n}\n\nextern void *eRealloc (void *const ptr, const size_t size)\n{\n\tvoid *buffer;\n\tif (ptr == NULL)\n\t\tbuffer = eMalloc (size);\n\telse\n\t{\n\t\tbuffer = realloc (ptr, size);\n\t\tif (buffer == NULL && size != 0)\n\t\t\terror (FATAL, \"out of memory\");\n\t}\n\treturn buffer;\n}\n\nextern void eFree (void *const ptr)\n{\n\tAssert (ptr != NULL);\n\tfree (ptr);\n}\n\nextern void eFreeNoNullCheck (void *const ptr)\n{\n\tfree (ptr);\n}\n\nextern void eFreeIndirect(void **ptr)\n{\n\tif (ptr && *ptr)\n\t{\n\t\teFree (*ptr);\n\t\t*ptr = NULL;\n\t}\n}\n\n/*\n *  String manipulation functions\n */\n\n/*\n * Compare two strings, ignoring case.\n * Return 0 for match, < 0 for smaller, > 0 for bigger\n * Make sure case is folded to uppercase in comparison (like for 'sort -f')\n * This makes a difference when one of the chars lies between upper and lower\n * ie. one of the chars [ \\ ] ^ _ ` for ascii. (The '_' in particular !)\n */\nextern int struppercmp (const char *s1, const char *s2)\n{\n\tint result;\n\tdo\n\t{\n\t\tresult = toupper ((unsigned char) *s1) - toupper ((unsigned char) *s2);\n\t} while (result == 0  &&  *s1++ != '\\0'  &&  *s2++ != '\\0');\n\treturn result;\n}\n\nextern int strnuppercmp (const char *s1, const char *s2, size_t n)\n{\n\tint result;\n\tdo\n\t{\n\t\tresult = toupper ((unsigned char) *s1) - toupper ((unsigned char) *s2);\n\t} while (result == 0  &&  --n > 0  &&  *s1++ != '\\0'  &&  *s2++ != '\\0');\n\treturn result;\n}\n\nextern char* strrstr (const char *str, const char *substr)\n{\n\tconst size_t length = strlen (substr);\n\tconst char *p;\n\n\tfor (p = str + strlen(str) - length  ;  p >= str  ;  --p)\n\t\tif (strncmp (p, substr, length) == 0)\n\t\t\treturn (char*) p;\n\treturn NULL;\n}\n\nextern char* eStrdup (const char* str)\n{\n\tchar* result = xMalloc (strlen (str) + 1, char);\n\tstrcpy (result, str);\n\treturn result;\n}\n\nextern char* eStrndup (const char* str, size_t len)\n{\n\tchar* result = xMalloc (len + 1, char);\n\tstrncpy (result, str, len);\n\tresult [len] = '\\0';\n\treturn result;\n}\n\nextern void toLowerString (char* str)\n{\n\twhile (*str != '\\0')\n\t{\n\t\t*str = (char) tolower ((unsigned char) *str);\n\t\t++str;\n\t}\n}\n\nextern void toUpperString (char* str)\n{\n\twhile (*str != '\\0')\n\t{\n\t\t*str = (char) toupper ((unsigned char) *str);\n\t\t++str;\n\t}\n}\n\n/*  Newly allocated string containing lower case conversion of a string.\n */\nextern char* newLowerString (const char* str)\n{\n\tchar* const result = xMalloc (strlen (str) + 1, char);\n\tint i = 0;\n\tdo\n\t\tresult [i] = (char) tolower ((unsigned char) str [i]);\n\twhile (str [i++] != '\\0');\n\treturn result;\n}\n\n/*  Newly allocated string containing upper case conversion of a string.\n */\nextern char* newUpperString (const char* str)\n{\n\tchar* const result = xMalloc (strlen (str) + 1, char);\n\tint i = 0;\n\tdo\n\t\tresult [i] = (char) toupper ((unsigned char) str [i]);\n\twhile (str [i++] != '\\0');\n\treturn result;\n}\n\n/* Safe wrapper for strtoul\n *\n * The conversion result is placed in value and must only be used if the\n * function returned true.\n */\nextern bool strToULong(const char *const str, int base, unsigned long *value)\n{\n\tchar *endptr;\n\n\terrno = 0;\n\t*value = strtoul (str, &endptr, base);\n\treturn *endptr == '\\0' && str != endptr && errno == 0;\n}\n\n/* Safe wrapper for strtol/atol\n *\n * The conversion result is placed in value and must only be used if the\n * function returned true.\n */\nextern bool strToLong(const char *const str, int base, long *value)\n{\n\tchar *endptr;\n\n\terrno = 0;\n\t*value = strtol (str, &endptr, base);\n\treturn *endptr == '\\0' && str != endptr && errno == 0;\n}\n\nextern bool strToUInt(const char *const str, int base, unsigned int *value)\n{\n\tunsigned long ulong_value;\n\n\tif(!strToULong(str, base, &ulong_value) || ulong_value > UINT_MAX)\n\t\treturn false;\n\n\t*value = (unsigned int) ulong_value;\n\treturn true;\n}\n\nextern bool strToInt(const char *const str, int base, int *value)\n{\n\tlong long_value;\n\n\tif(!strToLong(str, base, &long_value) || long_value > INT_MAX || long_value < INT_MIN)\n\t\treturn false;\n\n\t*value = (int) long_value;\n\treturn true;\n}\n\n/*\n * File system functions\n */\n\nextern void setCurrentDirectory (void) /* TODO */\n{\n\tchar* buf;\n\tif (CurrentDirectory == NULL)\n\t\tCurrentDirectory = xMalloc ((size_t) (PATH_MAX + 1), char);\n\tbuf = getcwd (CurrentDirectory, PATH_MAX);\n\tif (buf == NULL)\n\t\terror (FATAL | PERROR, \"failed in getcwd()\");\n\tif (! isPathSeparator (CurrentDirectory [strlen (CurrentDirectory) - (size_t) 1]))\n\t{\n\t\tsprintf (CurrentDirectory + strlen (CurrentDirectory), \"%c\",\n\t\t\t\tOUTPUT_PATH_SEPARATOR);\n\t}\n\tcanonicalizePath (CurrentDirectory);\n}\n\n/* For caching of stat() calls */\nextern fileStatus *eStat (const char *const fileName)\n{\n\tstruct stat status;\n\tstatic fileStatus file;\n\tif (file.name == NULL  ||  strcmp (fileName, file.name) != 0)\n\t{\n\t\teStatFree (&file);\n\t\tfile.name = eStrdup (fileName);\n\t\tif (lstat (file.name, &status) != 0)\n\t\t{\n\t\t\tfile.isSymbolicLink = false;\n\t\t\tfile.exists = false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfile.isSymbolicLink = (bool) S_ISLNK (status.st_mode);\n\t\t\tif (file.isSymbolicLink  &&  stat (file.name, &status) != 0)\n\t\t\t{\n\t\t\t\tfile.isSymbolicLink = true;\n\t\t\t\tfile.exists = false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfile.exists = true;\n\t\t\t\tfile.isDirectory = (bool) S_ISDIR (status.st_mode);\n\t\t\t\tfile.isNormalFile = (bool) (S_ISREG (status.st_mode));\n\t\t\t\tfile.isExecutable = (bool) ((status.st_mode &\n\t\t\t\t\t(S_IXUSR | S_IXGRP | S_IXOTH)) != 0);\n\t\t\t\tfile.isSetuid = (bool) ((status.st_mode & S_ISUID) != 0);\n\t\t\t\tfile.isSetgid = (bool) ((status.st_mode & S_ISGID) != 0);\n\t\t\t\tfile.size = status.st_size;\n\t\t\t\tfile.mtime = status.st_mtime;\n\t\t\t}\n\t\t}\n\t}\n\treturn &file;\n}\n\nextern void eStatFree (fileStatus *status)\n{\n\tif (status->name != NULL)\n\t{\n\t\teFree (status->name);\n\t\tstatus->name = NULL;\n\t}\n}\n\nextern bool doesDirectoryExist (const char *const fileName)\n{\n\tfileStatus *status = eStat (fileName);\n\treturn status->exists && status->isDirectory;\n}\n\nextern bool doesFileExist (const char *const fileName)\n{\n\tfileStatus *status = eStat (fileName);\n\treturn status->exists;\n}\n\nextern bool doesExecutableExist (const char *const fileName)\n{\n\tfileStatus *status = eStat (fileName);\n\treturn status->exists && status->isExecutable;\n}\n\nextern bool isRecursiveLink (const char* const dirName)\n{\n\tbool result = false;\n\tfileStatus *status = eStat (dirName);\n\tif (status->isSymbolicLink)\n\t{\n\t\tchar* const path = absoluteFilename (dirName);\n\t\twhile (isPathSeparator (path [strlen (path) - 1]))\n\t\t\tpath [strlen (path) - 1] = '\\0';\n\t\twhile (! result  &&  strlen (path) > (size_t) 1)\n\t\t{\n\t\t\tchar *const separator = strRSeparator (path);\n\t\t\tif (separator == NULL)\n\t\t\t\tbreak;\n\t\t\telse if (separator == path)  /* backed up to root directory */\n\t\t\t\t*(separator + 1) = '\\0';\n\t\t\telse\n\t\t\t\t*separator = '\\0';\n\t\t\tresult = isSameFile (path, dirName);\n\t\t}\n\t\teFree (path);\n\t}\n\treturn result;\n}\n\n/*\n *  Pathname manipulation (O/S dependent!!!)\n */\n\nstatic bool isPathSeparator (const int c)\n{\n\tbool result;\n#if defined (MSDOS_STYLE_PATH)\n\tresult = (bool) (strchr (PathDelimiters, c) != NULL);\n#else\n\tresult = (bool) (c == PATH_SEPARATOR);\n#endif\n\treturn result;\n}\n\nstatic char *strSeparator (const char *s)\n{\n#if defined (MSDOS_STYLE_PATH)\n\treturn strpbrk (s, PathDelimiters);\n#else\n\treturn strchr (s, PATH_SEPARATOR);\n#endif\n}\n\nstatic char *strRSeparator (const char *s)\n{\n#if defined (MSDOS_STYLE_PATH)\n\tconst char *last = NULL;\n\n\twhile (( s = strSeparator (s) ))\n\t{\n\t\tlast = s;\n\t\ts++;\n\t}\n\treturn (char*) last;\n#else\n\treturn strrchr (s, PATH_SEPARATOR);\n#endif\n}\n\nstatic void canonicalizePath (char *const path CTAGS_ATTR_UNUSED)\n{\n# if defined (MSDOS_STYLE_PATH)\n\tchar *p;\n\tfor (p = path  ;  *p != '\\0'  ;  ++p)\n\t\tif (isPathSeparator (*p)  &&  *p != ':')\n\t\t\t*p = OUTPUT_PATH_SEPARATOR;\n# endif\n}\n\nextern bool isSameFile (const char *const name1, const char *const name2)\n{\n\tbool result = false;\n#if defined (HAVE_STAT_ST_INO)\n\tstruct stat stat1, stat2;\n\n\tif (stat (name1, &stat1) == 0  &&  stat (name2, &stat2) == 0)\n\t\tresult = (bool) (stat1.st_ino == stat2.st_ino);\n#else\n\t{\n\t\tchar *const n1 = absoluteFilename (name1);\n\t\tchar *const n2 = absoluteFilename (name2);\n\t\tcanonicalizePath (n1);\n\t\tcanonicalizePath (n2);\n# if defined (CASE_INSENSITIVE_FILENAMES)\n\t\tresult = (bool) (strcasecmp (n1, n2) == 0);\n# else\n\t\tresult = (bool) (strcmp (n1, n2) == 0);\n# endif\n\t\teFree (n1);\n\t\teFree (n2);\n\t}\n#endif\n\treturn result;\n}\n\nextern const char *baseFilename (const char *const filePath)\n{\n#if defined (MSDOS_STYLE_PATH)\n\tconst char *tail = NULL;\n\tunsigned int i;\n\n\t/*  Find whichever of the path delimiters is last.\n\t */\n\tfor (i = 0  ;  i < strlen (PathDelimiters)  ;  ++i)\n\t{\n# ifdef HAVE_MBLEN\n\t\tconst char *p;\n\t\tint ml;\n\n\t\t/* Some DBCS has letter contains 0x5C in trailing byte.\n\t\t * So skip to the trailing byte. */\n\t\tfor (p = filePath  ;  *p != '\\0'  ;  ++p)\n\t\t{\n\t\t\tml = mblen(p, MB_LEN_MAX);\n\t\t\tif (ml > 1)\n\t\t\t\tp += ml - 1;\n\t\t\telse if (*p == PathDelimiters [i] && p > tail)\n\t\t\t\ttail = p;\n\t\t}\n# else\n\t\tconst char *sep = strrchr (filePath, PathDelimiters [i]);\n\n\t\tif (sep > tail)\n\t\t\ttail = sep;\n# endif\n\t}\n#else\n\tconst char *tail = strRSeparator (filePath);\n#endif\n\tif (tail == NULL)\n\t\ttail = filePath;\n\telse\n\t\t++tail;  /* step past last delimiter */\n\n\treturn tail;\n}\n\nextern const char *fileExtension (const char *const fileName)\n{\n\tconst char *extension;\n\tconst char *pDelimiter;\n\tconst char *const base = baseFilename (fileName);\n\n\tpDelimiter = strrchr (base, '.');\n\n\tif (pDelimiter == NULL)\n\t\textension = \"\";\n\telse\n\t\textension = pDelimiter + 1;  /* skip to first char of extension */\n\n\treturn extension;\n}\n\nextern char* filenameSansExtensionNew (const char *const fileName,\n\t\t\t\t\t\t\t\t\t   const char *const templateExt)\n{\n\tAssert (templateExt);\n\tAssert (fileName);\n\n\tconst char *pDelimiter = strrstr (fileName, templateExt);\n\n\tif (pDelimiter && (strcmp (pDelimiter, templateExt) == 0))\n\t\treturn eStrndup (fileName, pDelimiter - fileName);\n\treturn NULL;\n}\n\nextern bool isAbsolutePath (const char *const path)\n{\n\tbool result;\n#if defined (MSDOS_STYLE_PATH)\n\tif (isPathSeparator (path [0]))\n\t\tresult = true;\n\telse if (isalpha ((unsigned char) path [0])  &&  path [1] == ':')\n\t{\n\t\tif (isPathSeparator (path [2]))\n\t\t\tresult = true;\n\t\telse\n\t\t{\n\t\t\tresult = false;\n\t\t\t/*  We don't support non-absolute file names with a drive\n\t\t\t *  letter, like `d:NAME' (it's too much hassle).\n\t\t\t */\n\t\t\terror (FATAL,\n\t\t\t\t\"%s: relative file names with drive letters not supported\",\n\t\t\t\tpath);\n\t\t}\n\t}\n\telse\n\t\tresult = false;\n#else\n\tresult = isPathSeparator (path [0]);\n#endif\n\treturn result;\n}\n\nextern char *combinePathAndFile (\n\tconst char *const path, const char *const file)\n{\n\tvString *const filePath = vStringNew ();\n\tsize_t len = strlen (path);\n\n\tif (len)\n\t{\n\t\tconst int lastChar = path [len - 1];\n\t\tbool terminated = isPathSeparator (lastChar);\n\t\tvStringCopyS (filePath, path);\n\t\tif (! terminated)\n\t\t\tvStringPut (filePath, OUTPUT_PATH_SEPARATOR);\n\t}\n\n\tvStringCatS (filePath, file);\n\treturn vStringDeleteUnwrap (filePath);\n}\n\n/* Return a newly-allocated string whose contents concatenate those of\n * s1, s2, s3.\n * Routine adapted from Gnu etags.\n */\nstatic char* concat (const char *s1, const char *s2, const char *s3)\n{\n\tint len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);\n\tchar *result = xMalloc (len1 + len2 + len3 + 1, char);\n\n\tstrcpy (result, s1);\n\tstrcpy (result + len1, s2);\n\tstrcpy (result + len1 + len2, s3);\n\tresult [len1 + len2 + len3] = '\\0';\n\n\treturn result;\n}\n\n/* Return a newly allocated string containing the absolute file name of FILE\n * given CWD (which should end with a slash).\n * Routine adapted from Gnu etags.\n */\nextern char* absoluteFilename (const char *file)\n{\n\tchar *slashp, *cp;\n\tchar *res = NULL;\n\tif (isAbsolutePath (file))\n\t{\n#ifdef MSDOS_STYLE_PATH\n\t\tif (file [1] == ':')\n\t\t\tres = eStrdup (file);\n\t\telse\n\t\t{\n\t\t\tchar drive [3];\n\t\t\tsprintf (drive, \"%c:\", currentdrive ());\n\t\t\tres = concat (drive, file, \"\");\n\t\t}\n#else\n\t\tres = eStrdup (file);\n#endif\n\t}\n\telse\n\t\tres = concat (CurrentDirectory, file, \"\");\n\n\t/* Delete the \"/dirname/..\" and \"/.\" substrings. */\n\tslashp = strSeparator (res);\n\twhile (slashp != NULL  &&  slashp [0] != '\\0')\n\t{\n\t\tif (slashp[1] == '.')\n\t\t{\n\t\t\tif (slashp [2] == '.' &&\n\t\t\t\t(isPathSeparator (slashp [3]) || slashp [3] == '\\0'))\n\t\t\t{\n\t\t\t\tcp = slashp;\n\t\t\t\tdo\n\t\t\t\t\tcp--;\n\t\t\t\twhile (cp >= res  &&  ! isAbsolutePath (cp));\n\t\t\t\tif (cp < res)\n\t\t\t\t\tcp = slashp;/* the absolute name begins with \"/..\" */\n#ifdef MSDOS_STYLE_PATH\n\t\t\t\t/* Under MSDOS and NT we get `d:/NAME' as absolute file name,\n\t\t\t\t * so the user could say `d:/../NAME'. We silently treat this\n\t\t\t\t * as `d:/NAME'.\n\t\t\t\t */\n\t\t\t\telse if (!isPathSeparator (cp [0]))\n\t\t\t\t\tcp = slashp;\n#endif\n\t\t\t\tmemmove (cp, slashp + 3, strlen (slashp + 3) + 1);\n\t\t\t\tslashp = cp;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (isPathSeparator (slashp [2])  ||  slashp [2] == '\\0')\n\t\t\t{\n\t\t\t\tmemmove (slashp, slashp + 2, strlen (slashp + 2) + 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tslashp = strSeparator (slashp + 1);\n\t}\n\n\tif (res [0] == '\\0')\n\t{\n\t\tconst char root [] = {OUTPUT_PATH_SEPARATOR, '\\0'};\n\t\teFree (res);\n\t\tres = eStrdup (root);\n\t}\n\telse\n\t{\n#ifdef MSDOS_STYLE_PATH\n\t\t/* Canonicalize drive letter case. */\n\t\tif (res [1] == ':'  &&  islower ((unsigned char) res [0]))\n\t\t\tres [0] = toupper ((unsigned char) res [0]);\n#endif\n\t}\n\tcanonicalizePath (res);\n\treturn res;\n}\n\n/* Return a newly allocated string containing the absolute file name of dir\n * where `file' resides given `CurrentDirectory'.\n * Routine adapted from Gnu etags.\n */\nextern char* absoluteDirname (char *file)\n{\n\tchar *slashp, *res;\n\tchar save;\n\tslashp = strRSeparator (file);\n\tif (slashp == NULL)\n\t\tres = eStrdup (CurrentDirectory);\n\telse\n\t{\n\t\tsave = slashp [1];\n\t\tslashp [1] = '\\0';\n\t\tres = absoluteFilename (file);\n\t\tslashp [1] = save;\n\t}\n\treturn res;\n}\n\n/* Return a newly allocated string containing the file name of FILE relative\n * to the absolute directory DIR (which should end with a slash).\n * Routine adapted from Gnu etags.\n */\nextern char* relativeFilename (const char *file, const char *dir)\n{\n\tconst char *fp, *dp;\n\tchar *absdir, *res;\n\tint i;\n\n\t/* Find the common root of file and dir (with a trailing slash). */\n\tabsdir = absoluteFilename (file);\n\tfp = absdir;\n\tdp = dir;\n\twhile (fnmChEq ((unsigned char) *fp++, (unsigned char) *dp++))\n\t\tcontinue;\n\tfp--;\n\tdp--;  /* back to the first differing char */\n\tdo\n\t{  /* look at the equal chars until path sep */\n\t\tif (fp == absdir)\n\t\t\treturn absdir;  /* first char differs, give up */\n\t\tfp--;\n\t\tdp--;\n\t} while (!isPathSeparator (*fp));\n\n\t/* Build a sequence of \"../\" strings for the resulting relative file name.\n\t */\n\ti = 0;\n\twhile ((dp = strSeparator (dp + 1)) != NULL)\n\t\ti += 1;\n\tres = xMalloc (3 * i + strlen (fp + 1) + 1, char);\n\tres [0] = '\\0';\n\twhile (i-- > 0)\n\t{\n\t\tconst char parent [] = {'.', '.', OUTPUT_PATH_SEPARATOR, '\\0'};\n\t\tstrcat (res, parent);\n\t}\n\n\t/* Add the file name relative to the common root of file and dir. */\n\tstrcat (res, fp + 1);\n\teFree (absdir);\n\n\treturn res;\n}\n\nextern FILE *tempFileFP (const char *const mode, char **const pName)\n{\n\tchar *name;\n\tFILE *fp;\n\tint fd;\n#if defined(HAVE_MKSTEMP)\n\tconst char *const pattern = \"tags.XXXXXX\";\n\tconst char *tmpdir = NULL;\n\tfileStatus *file = eStat (ExecutableProgram);\n# ifdef _WIN32\n\ttmpdir = getenv (\"TMP\");\n# else\n\tif (! file->isSetuid)\n\t\ttmpdir = getenv (\"TMPDIR\");\n# endif\n\tif (tmpdir == NULL)\n\t\ttmpdir = TMPDIR;\n\tname = xMalloc (strlen (tmpdir) + 1 + strlen (pattern) + 1, char);\n\tsprintf (name, \"%s%c%s\", tmpdir, OUTPUT_PATH_SEPARATOR, pattern);\n\tfd = mkstemp (name);\n# ifdef _WIN32\n\tif (fd == -1)\n\t{\n\t\t/* mkstemp() sometimes fails with unknown reasons.\n\t\t * Retry a few times. */\n\t\tint i;\n\t\tfor (i = 0; i < 5 && fd == -1; i++)\n\t\t{\n\t\t\tsprintf (name, \"%s%c%s\", tmpdir, OUTPUT_PATH_SEPARATOR, pattern);\n\t\t\tfd = mkstemp (name);\n\t\t}\n\t}\n# endif\n\teStatFree (file);\n#elif defined(HAVE_TEMPNAM)\n\tconst char *tmpdir = NULL;\n# ifdef _WIN32\n\ttmpdir = getenv (\"TMP\");\n# endif\n\tif (tmpdir == NULL)\n\t\ttmpdir = TMPDIR;\n\tname = tempnam (tmpdir, \"tags\");\n\tif (name == NULL)\n\t\terror (FATAL | PERROR, \"cannot allocate temporary file name\");\n\tfd = open (name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);\n#else\n\tname = xMalloc (L_tmpnam, char);\n\tif (tmpnam (name) != name)\n\t\terror (FATAL | PERROR, \"cannot assign temporary file name\");\n\tfd = open (name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);\n#endif\n\tif (fd == -1)\n\t\terror (FATAL | PERROR, \"cannot open temporary file: %s\", name);\n\tfp = fdopen (fd, mode);\n\tif (fp == NULL)\n\t\terror (FATAL | PERROR, \"cannot open temporary file\");\n\tAssert (*pName == NULL);\n\t*pName = name;\n\treturn fp;\n}\n\nextern MIO *tempFile (const char *const mode, char **const pName)\n{\n\tFILE *fp = tempFileFP (mode, pName);\n\treturn mio_new_fp (fp, fclose);\n}\n"
  },
  {
    "path": "main/routines.h",
    "content": "/*\n*   Copyright (c) 2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to routines.c\n*/\n#ifndef CTAGS_MAIN_ROUTINES_H\n#define CTAGS_MAIN_ROUTINES_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <stdio.h>\n\n\n/*\n*   MACROS\n*/\n#define xMalloc(n,Type)    (Type *)eMalloc((size_t)(n) * sizeof (Type))\n#define xCalloc(n,Type)    (Type *)eCalloc((size_t)(n), sizeof (Type))\n#define xRealloc(p,n,Type) (Type *)eRealloc((p), (n) * sizeof (Type))\n\n#define ARRAY_SIZE(X)      (sizeof (X) / sizeof (X[0]))\n#define ARRAY_AND_SIZE(X)  (X), ARRAY_SIZE(X)\n\n#define STRINGIFY(X) STRINGIFY_(X)\n#define STRINGIFY_(X) #X\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef int errorSelection;\nenum eErrorTypes { FATAL = 1, WARNING = 2, NOTICE = 4, PERROR = 8, };\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void error (const errorSelection selection, const char *const format, ...) CTAGS_ATTR_PRINTF (2, 3);\n#define notice(...) error (NOTICE, __VA_ARGS__)\n\n/* Memory allocation functions */\n#ifdef NEED_PROTO_MALLOC\nextern void *malloc (size_t);\nextern void *realloc (void *ptr, size_t);\n#endif\nextern void *eMalloc (const size_t size);\nextern void *eCalloc (const size_t count, const size_t size);\nextern void *eRealloc (void *const ptr, const size_t size);\nextern void eFree (void *const ptr);\nextern void eFreeNoNullCheck (void *const ptr);\nextern void eFreeIndirect(void **ptr);\n\n/* String manipulation functions */\nextern int struppercmp (const char *s1, const char *s2);\nextern int strnuppercmp (const char *s1, const char *s2, size_t n);\nextern char* strrstr (const char *str, const char *substr);\nextern char* eStrdup (const char* str);\nextern char* eStrndup (const char* str, size_t len);\nextern void toLowerString (char* str);\nextern void toUpperString (char* str);\nextern char* newLowerString (const char* str);\nextern char* newUpperString (const char* str);\nextern bool strToUInt(const char *const str, int base, unsigned int *value);\nextern bool strToULong(const char *const string, int base, unsigned long *value);\nextern bool strToInt(const char *const str, int base, int *value);\nextern bool strToLong(const char *const string, int base, long *value);\n\n/* File system functions */\nextern const char *baseFilename (const char *const filePath);\nextern const char *fileExtension (const char *const fileName);\n\nextern FILE *tempFileFP (const char *const mode, char **const pName);\n\n#endif  /* CTAGS_MAIN_ROUTINES_H */\n"
  },
  {
    "path": "main/routines_p.h",
    "content": "/*\n*   Copyright (c) 2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Main part private interface to routines.c\n*/\n#ifndef CTAGS_MAIN_ROUTINES_PRIVATE_H\n#define CTAGS_MAIN_ROUTINES_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"mio.h\"\n#include \"portable-dirent_p.h\"\n\n/*\n *  Portability macros\n */\n#ifndef PATH_SEPARATOR\n# if defined (MSDOS_STYLE_PATH)\n#  define PATH_SEPARATOR '\\\\'\n# else\n#  define PATH_SEPARATOR '/'\n# endif\n#endif\n\n#if defined (MSDOS_STYLE_PATH)\n# define OUTPUT_PATH_SEPARATOR\t'/'\n#else\n# define OUTPUT_PATH_SEPARATOR\tPATH_SEPARATOR\n#endif\n\n/*\n*   DATA DECLARATIONS\n*/\nextern char *CurrentDirectory;\n#if defined (MSDOS_STYLE_PATH)\nextern const char *const PathDelimiters;\n#endif\n\ntypedef struct {\n\t\t/* Name of file for which status is valid */\n\tchar* name;\n\n\t\t/* Does file exist? If not, members below do not contain valid data.\n\t\t * `isSymbolicLink' is the only exception.\n\t\t */\n\tbool exists;\n\n\t\t/* is file path a symbolic link to another file?\n\t\t * This member contains valid data even if `exists' member\n\t\t * is false.\n\t\t *\n\t\t * if ( exists &&  isSymbolicLink) => It is a valid symbolic link.\n\t\t * if ( exists && !isSymbolicLink) => It exists. It is not a symbolic link.\n\t\t * if (!exists &&  isSymbolicLink) => It is a broken symbolic link.\n\t\t * if (!exists && !isSymbolicLink) => It is not a valid file system entry.\n\t\t */\n\tbool isSymbolicLink;\n\n\t\t/* Is file (pointed to) a directory? */\n\tbool isDirectory;\n\n\t\t/* Is file (pointed to) a normal file? */\n\tbool isNormalFile;\n\n\t\t/* Is file (pointed to) executable? */\n\tbool isExecutable;\n\n\t\t/* Is file (pointed to) setuid? */\n\tbool isSetuid;\n\n\t\t/* Is file (pointed to) setgid? */\n\tbool isSetgid;\n\n\t\t/* Size of file (pointed to) */\n\tunsigned long size;\n\n\t\t/* The last modified time */\n\ttime_t mtime;\n} fileStatus;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void freeRoutineResources (void);\nextern void setExecutableName (const char *const path);\n\n/* File system functions */\nextern const char *getExecutableName (void);\nextern const char *getExecutablePath (void);\nextern void setCurrentDirectory (void);\nextern fileStatus *eStat (const char *const fileName);\nextern void eStatFree (fileStatus *status);\nextern bool doesFileExist (const char *const fileName);\nextern bool doesDirectoryExist (const char *const fileName);\nextern bool doesExecutableExist (const char *const fileName);\nextern bool isRecursiveLink (const char* const dirName);\nextern bool isSameFile (const char *const name1, const char *const name2);\nextern bool isAbsolutePath (const char *const path);\nextern char *combinePathAndFile (const char *const path, const char *const file);\nextern char* absoluteFilename (const char *file);\nextern char* absoluteDirname (char *file);\nextern char* relativeFilename (const char *file, const char *dir);\nextern MIO *tempFile (const char *const mode, char **const pName);\n\nextern char* filenameSansExtensionNew (const char *const fileName, const char *const templateExt);\n\n#endif  /* CTAGS_MAIN_ROUTINES_PRIVATE_H */\n"
  },
  {
    "path": "main/script.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains ctags specific optscript objects\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"field_p.h\"\n#include \"htable.h\"\t\t\t/* For HT_PTR_TO_INT */\n#include \"optscript.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"script_p.h\"\n#include \"xtag_p.h\"\n\n#include <ctype.h>\n#include <string.h>\n\nEsObject *OPTSCRIPT_ERR_NOTAGENTRY;\nEsObject *OPTSCRIPT_ERR_UNKNOWNLANGUAGE;\nEsObject *OPTSCRIPT_ERR_FIELDRESET;\n\nint OPT_TYPE_MATCHLOC;\nstatic int locEqual (const void *a, const void *b);\nstatic void locPrint (const void *a, MIO *out);\n\nint OPT_TYPE_TAG;\nstatic void tagFree (void *a);\nstatic int tagEqual (const void *a, const void *b);\nstatic void tagPrint (const void *a, MIO *out);\n\nstatic void vStringCatToupperS (vString *str, const char *s)\n{\n\tfor (const char *tmp = s; *tmp != '\\0'; tmp++)\n\t{\n\t\tint c = toupper ((unsigned char) *tmp);\n\t\tvStringPut (str, c);\n\t}\n}\n\nextern OptVM *optscriptInit (void)\n{\n\topt_init ();\n\tMIO *in  = mio_new_fp (stdin, NULL);\n\n\t/* stdout is for emitting tags.\n\t * The interpreter should not touch it; use only stderr. */\n\tMIO *out = mio_new_fp (stderr, NULL);\n\tMIO *err = mio_new_fp (stderr, NULL);\n\n\tOptVM *optvm = opt_vm_new (in, out, err);\n\n\tmio_unref (err);\n\tmio_unref (out);\n\tmio_unref (in);\n\n\tOPTSCRIPT_ERR_NOTAGENTRY = es_error_intern (\"notagentry\");\n\n\tOPT_TYPE_MATCHLOC = es_type_define_pointer (\"matchloc\",\n\t\t\t\t\t\t\t\t\t\t\t\teFreeNoNullCheck,\n\t\t\t\t\t\t\t\t\t\t\t\tlocEqual,\n\t\t\t\t\t\t\t\t\t\t\t\tlocPrint);\n\tOPT_TYPE_TAG = es_type_define_pointer (\"tagEntryInfo\",\n\t\t\t\t\t\t\t\t\t\t   tagFree,\n\t\t\t\t\t\t\t\t\t\t   tagEqual,\n\t\t\t\t\t\t\t\t\t\t   tagPrint);\n\treturn optvm;\n}\n\nstatic EsObject* lrop_get_field_value (OptVM *vm, EsObject *name)\n{\n\tEsObject *nobj = opt_vm_ostack_top (vm);\n\tif (!es_integer_p (nobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n = es_integer_get (nobj);\n\ttagEntryInfo *e = getEntryInCorkQueue (n);\n\tif (e == NULL)\n\t\treturn OPTSCRIPT_ERR_NOTAGENTRY;\n\n\tvoid * data = es_symbol_get_data (name);\n\tfieldType ftype = HT_PTR_TO_INT (data);\n\tEsObject *val = getFieldValue (ftype, e);\n\tif (es_error_p (val))\n\t\treturn val;\n\n\topt_vm_ostack_pop (vm);\n\n\tif (isFieldValueAvailableAlways (ftype))\n\t{\n\t\topt_vm_ostack_push (vm, val);\n\t\tes_object_unref (val);\n\t}\n\telse if (es_null (val))\n\t{\n\t\topt_vm_ostack_push (vm, es_false);\n\t}\n\telse\n\t{\n\t\topt_vm_ostack_push (vm, val);\n\t\topt_vm_ostack_push (vm, es_true);\n\t\tes_object_unref (val);\n\t}\n\treturn es_false;\n}\n\nstatic EsObject* lrop_set_field_value (OptVM *vm, EsObject *name)\n{\n\tEsObject *indexobj = opt_vm_ostack_peek (vm, 1);\n\tif (!es_integer_p (indexobj))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tint n = es_integer_get (indexobj);\n\ttagEntryInfo *e = getEntryInCorkQueue (n);\n\tif (e == NULL)\n\t\treturn OPTSCRIPT_ERR_NOTAGENTRY;\n\n\tvoid * data = es_symbol_get_data (name);\n\tfieldType ftype = HT_PTR_TO_INT (data);\n\tunsigned int fdata_type = getFieldDataType (ftype);\n\n\tEsObject *valobj = opt_vm_ostack_top (vm);\n\tint valtype = es_object_get_type (valobj);\n\n\tif (hasFieldValueCheckerForSetter (ftype))\n\t{\n\t\tEsObject *e = checkFieldValueForSetter (ftype, valobj);\n\t\tif (!es_object_equal (e, es_false))\n\t\t\treturn e;\n\t}\n\telse if ((fdata_type & FIELDTYPE_STRING) && (fdata_type & FIELDTYPE_BOOL)\n\t\t\t && ((valtype == OPT_TYPE_STRING) || (valtype == ES_TYPE_BOOLEAN)))\n\t\t;\t\t\t\t\t\t/* Accept; do nothing */\n\telse if (! (((fdata_type & FIELDTYPE_STRING) && (valtype == OPT_TYPE_STRING))\n\t\t\t\t|| ((fdata_type & FIELDTYPE_BOOL) && (valtype == ES_TYPE_BOOLEAN))\n\t\t\t\t|| ((fdata_type & FIELDTYPE_INTEGER) && (valtype == ES_TYPE_INTEGER))))\n\t\treturn OPT_ERR_TYPECHECK;\n\n\tEsObject *r = setFieldValue (ftype, e, valobj);\n\tif (es_error_p (r))\n\t\treturn r;\n\n\topt_vm_ostack_pop (vm);\n\topt_vm_ostack_pop (vm);\n\n\treturn es_false;\n}\n\nstatic void optscriptInstallFieldGetterFast (EsObject *dict, fieldType ftype,\n\t\t\t\t\t\t\t\t\t\t\t vString *op_name, vString *op_desc)\n{\n\tvStringPut (op_name, ':');\n\n\tlangType lang = getFieldLanguage (ftype);\n\tif (lang != LANG_IGNORE)\n\t{\n\t\tconst char *lname = getLanguageName (lang);\n\t\tvStringCatS (op_name, lname);\n\t\tvStringPut (op_name, '.');\n\t}\n\n\tconst char *fname = getFieldName (ftype);\n\tvStringCatS (op_name, fname);\n\n\tEsObject *op_sym = es_symbol_intern (vStringValue (op_name));\n\tes_symbol_set_data (op_sym, HT_INT_TO_PTR (ftype));\n\n\tconst char *vtype = getFieldGetterValueType (ftype);\n\tunsigned int fdata_type = getFieldDataType (ftype);\n\n\tvStringCatS (op_desc, \"int :\");\n\tvStringCatToupperS (op_desc, fname);\n\tvStringPut (op_desc, ' ');\n\n\tif (vtype)\n\t\tvStringCatS (op_desc, vtype);\n\telse\n\t{\n\t\tAssert (fdata_type);\n\t\tif (fdata_type & FIELDTYPE_STRING)\n\t\t\tvStringCatS (op_desc, \"string|\");\n\t\tif (fdata_type & FIELDTYPE_INTEGER)\n\t\t\tvStringCatS (op_desc, \"int|\");\n\t\tif (fdata_type & FIELDTYPE_BOOL)\n\t\t\tvStringCatS (op_desc, \"bool|\");\n\t\tvStringChop (op_desc);\n\t}\n\n\tif (!isFieldValueAvailableAlways (ftype))\n\t{\n\t\tvStringPut (op_desc, ' ');\n\t\tvStringCatS (op_desc, \"true%\");\n\t\tvStringCatS (op_desc, \"int :\");\n\t\tvStringCatToupperS (op_desc, fname);\n\t\tvStringCatS (op_desc, \" false\");\n\t}\n\n\tEsObject *op = opt_operator_new (lrop_get_field_value,\n\t\t\t\t\t\t\t\t\t vStringValue (op_name),\n\t\t\t\t\t\t\t\t\t 1, vStringValue (op_desc));\n\topt_dict_def (dict, op_sym, op);\n\tes_object_unref (op);\n}\n\nstatic void optscriptInstallFieldSetterFast (EsObject *dict, fieldType ftype,\n\t\t\t\t\t\t\t\t\t\t\t vString *op_name, vString *op_desc)\n{\n\tlangType lang = getFieldLanguage (ftype);\n\tif (lang != LANG_IGNORE)\n\t{\n\t\tconst char *lname = getLanguageName (lang);\n\t\tvStringCatS (op_name, lname);\n\t\tvStringPut (op_name, '.');\n\t}\n\n\tconst char *fname = getFieldName (ftype);\n\tvStringCatS (op_name, fname);\n\tvStringPut (op_name, ':');\n\n\tEsObject *op_sym = es_symbol_intern (vStringValue (op_name));\n\tes_symbol_set_data (op_sym, HT_INT_TO_PTR (ftype));\n\n\tconst char *vtype = getFieldSetterValueType (ftype);\n\tunsigned int fdata_type = getFieldDataType (ftype);\n\tvStringCatS (op_desc, \"tag:int \");\n\n\tif (vtype)\n\t\tvStringCatS (op_desc, vtype);\n\telse\n\t{\n\t\tAssert (fdata_type);\n\t\tif (fdata_type & FIELDTYPE_STRING)\n\t\t\tvStringCatS (op_desc, \"string|\");\n\t\tif (fdata_type & FIELDTYPE_INTEGER)\n\t\t\tvStringCatS (op_desc, \"int|\");\n\t\tif (fdata_type & FIELDTYPE_BOOL)\n\t\t\tvStringCatS (op_desc, \"bool|\");\n\t\tvStringChop (op_desc);\n\t}\n\n\tvStringPut (op_desc, ' ');\n\tvStringCatToupperS (op_desc, fname);\n\tvStringCatS (op_desc, \": -\");\n\n\tEsObject *op = opt_operator_new (lrop_set_field_value,\n\t\t\t\t\t\t\t\t\t vStringValue (op_name),\n\t\t\t\t\t\t\t\t\t 2, vStringValue (op_desc));\n\topt_dict_def (dict, op_sym, op);\n\tes_object_unref (op);\n}\n\nextern void optscriptInstallFieldAccessor (EsObject *dict, fieldType ftype)\n{\n\tvString *op_name = vStringNew ();\n\tvString *op_desc = vStringNew ();\n\n\tif (hasFieldGetter (ftype))\n\t{\n\t\toptscriptInstallFieldGetterFast (dict, ftype, op_name, op_desc);\n\t\tvStringClear (op_name);\n\t\tvStringClear (op_desc);\n\t}\n\n\tif (hasFieldSetter (ftype))\n\t\toptscriptInstallFieldSetterFast (dict, ftype, op_name, op_desc);\n\n\tvStringDelete (op_name);\n\tvStringDelete (op_desc);\n}\n\nstatic void optscriptInstallFieldAccessors (EsObject *dict)\n{\n\tvString *op_name = vStringNew ();\n\tvString *op_desc = vStringNew ();\n\n\t/* In the current implementation, the upper boundary of the loop\n\t   can be \"<= FIELD_BUILTIN_LAST\" because the parser specific fields\n\t   are registered via defineField. However, when we change the order\n\t   and the way to initialize parsers, we may have to use \"< countFields()\"\n\t   instead. */\n\tfor (fieldType ftype = 0; ftype <= FIELD_BUILTIN_LAST; ftype++)\n\t{\n\t\tif (hasFieldGetter (ftype))\n\t\t{\n\t\t\toptscriptInstallFieldGetterFast (dict, ftype, op_name, op_desc);\n\t\t\tvStringClear (op_name);\n\t\t\tvStringClear (op_desc);\n\t\t}\n\t\tif (hasFieldSetter (ftype))\n\t\t{\n\t\t\toptscriptInstallFieldSetterFast (dict, ftype, op_name, op_desc);\n\t\t\tvStringClear (op_name);\n\t\t\tvStringClear (op_desc);\n\t\t}\n\t}\n\n\tvStringDelete (op_name);\n\tvStringDelete (op_desc);\n}\n\n/* Define \\1, \\2,... \\9 */\nstatic void optscriptInstallMatchResultProcs (EsObject *dict,\n\t\t\t\t\t\t\t\t\t\t\t  OptOperatorFn fun)\n{\n\tchar name [] = { [0] = '\\\\', [2] = '\\0' };\n\tchar help [] = \"- \\\\_ string|false\";\n\tchar *p = strchr (help, '_');\n\tfor (int i = 1; i <= 9; i++)\n\t{\n\t\tname [1] = '0' + i;\n\t\t*p = name [1];\n\t\tEsObject *op_sym = es_symbol_intern (name);\n\t\tes_symbol_set_data (op_sym, HT_INT_TO_PTR (i));\n\t\tEsObject *op = opt_operator_new (fun, name, 0, help);\n\t\topt_dict_def (dict, op_sym, op);\n\t\tes_object_unref (op);\n\t}\n}\n\nextern void optscriptInstallProcs (EsObject *dict,\n\t\t\t\t\t\t\t\t   OptOperatorFn matchResultAccessor)\n{\n\toptscriptInstallFieldAccessors (dict);\n\toptscriptInstallMatchResultProcs (dict, matchResultAccessor);\n}\n\nstatic EsObject *optscript_CorkIndex_sym = es_nil;\nextern void optscriptSetup (OptVM *vm, EsObject *dict, int corkIndex)\n{\n\tif (corkIndex != CORK_NIL)\n\t{\n\t\tstatic EsObject *corkIndex_sym = es_nil;\n\t\tif (es_null (corkIndex_sym))\n\t\t\tcorkIndex_sym = es_symbol_intern (\".\");\n\t\tEsObject *corkIndex_val = es_integer_new (corkIndex);\n\t\topt_dict_def (dict, corkIndex_sym, corkIndex_val);\n\t\tes_object_unref (corkIndex_val);\n\t\toptscript_CorkIndex_sym = corkIndex_sym;\n\t}\n}\n\nextern void optscriptTeardown (OptVM *vm, EsObject *dict)\n{\n\tif (!es_null (optscript_CorkIndex_sym))\n\t{\n\t\topt_dict_undef (dict, optscript_CorkIndex_sym);\n\t\toptscript_CorkIndex_sym = es_nil;\n\t}\n}\n\nextern EsObject *optscriptRead (OptVM *vm, const char *src, size_t len)\n{\n\tif (len == 0)\n\t\tlen = strlen (src);\n\n\tMIO *mio = mio_new_memory ((unsigned char *)src, len, NULL, NULL);\n\tEsObject *obj = opt_vm_read (vm, mio);\n\tif (es_error_p (obj))\n\t\topt_vm_report_error (vm, obj, NULL);\n\tmio_unref (mio);\n\treturn obj;\n}\n\nextern EsObject* optscriptEval (OptVM *vm, EsObject *code)\n{\n\tstatic EsObject *exec = es_nil;\n\n\tif (es_null (exec))\n\t{\n\t\tMIO *mio = mio_new_memory ((unsigned char*)\"//exec\", 6, NULL, NULL);\n\t\texec = opt_vm_read (vm, mio);\n\t\tif (es_error_p (exec))\n\t\t{\n\t\t\topt_vm_report_error (vm, exec, NULL);\n\t\t\terror (FATAL, \"failed in converting //exec to an optscript object\");\n\t\t}\n\t\tmio_unref (mio);\n\t}\n\n\tEsObject *o = opt_vm_eval (vm, code);\n\tif (es_error_p (o))\n\t{\n\t\topt_vm_report_error (vm, o, NULL);\n\t\terror (FATAL, \"failed to push the proc representing the script\");\n\t}\n\tes_object_unref (o);\n\n\tEsObject *r = opt_vm_eval (vm, exec);\n\tif (es_error_p (r))\n\t\topt_vm_report_error (vm, r, NULL);\n\treturn r;\n}\n\nextern EsObject* optscriptDefine (EsObject *dict,\n\t\t\t\t\t\t\t\t  const char *name, EsObject *obj)\n{\n\tEsObject *sym = es_symbol_intern (name);\n\topt_dict_def (dict, sym, obj);\n\treturn sym;\n}\n\n\nextern EsObject *optscriptLoad (OptVM *vm, MIO *mio)\n{\n\twhile (true)\n\t{\n\t\tEsObject *o = opt_vm_read (vm, mio);\n\t\tif (es_object_equal (o, ES_READER_EOF))\n\t\t{\n\t\t\tes_object_unref (o);\n\t\t\treturn es_false;\n\t\t}\n\t\telse if (es_error_p (o))\n\t\t{\n\t\t\topt_vm_report_error (vm, o, NULL);\n\t\t\treturn o;\n\t\t}\n\n\t\tEsObject *e = opt_vm_eval (vm, o);\n\t\tif (es_error_p (e))\n\t\t{\n\t\t\topt_vm_report_error (vm, e, NULL);\n\t\t\tes_object_unref (o);\n\t\t\treturn e;\n\t\t}\n\n\t\tes_object_unref (o);\n\t}\n}\n\nextern EsObject *optscriptReadAndEval   (OptVM *vm, const char *src, size_t len)\n{\n\tEsObject *obj = optscriptRead (vm, src, len);\n\tif (es_error_p (obj))\n\t\treturn obj;\n\n\tEsObject *r = optscriptEval (vm, obj);\n\tes_object_unref (obj);\n\treturn r;\n}\n\nextern EsObject *optscriptReadAndDefine (OptVM *vm, EsObject *dict, const char *name,\n\t\t\t\t\t\t\t\t\t\t const char *src, size_t len)\n{\n\tEsObject *obj = optscriptRead (vm, src, len);\n\tif (es_error_p (obj))\n\t\treturn obj;\n\treturn optscriptDefine (dict, name, obj);\n}\n\nstatic bool procdocs_add_key_val (EsObject *proc, EsObject *help_str, void *data)\n{\n\tptrArray *a = data;\n\n\tif (es_object_get_type (help_str) == OPT_TYPE_STRING)\n\t\tptrArrayAdd (a, proc);\n\n\treturn true;\n}\n\nstatic const char* procdocs_get_help_str (EsObject *proc, void *data)\n{\n\tEsObject *dict = data;\n\tconst char *name = opt_name_get_cstr (proc);\n\tEsObject *help_str = NULL;\n\n\tif (opt_dict_known_and_get_cstr (dict, name, &help_str))\n\t\treturn opt_string_get_cstr(help_str);\n\treturn NULL;\n}\n\nstatic void procdocs_add (ptrArray *a, void *data)\n{\n\tEsObject *dict = data;\n\topt_dict_foreach (dict, procdocs_add_key_val, a);\n}\n\nstatic struct OptHelpExtender procdocs_help_extender = {\n\t.add = procdocs_add,\n\t.get_help_str = procdocs_get_help_str,\n};\n\nextern void optscriptHelp (OptVM *vm, FILE *fp, EsObject *procdocs)\n{\n\tMIO *out = mio_new_fp (fp, NULL);\n\topt_vm_help (vm, out, procdocs? &procdocs_help_extender: NULL, procdocs);\n\tmio_unref (out);\n}\n\nstatic int locEqual (const void *a, const void *b)\n{\n\tif (a == b)\n\t\treturn 1;\n\n\tconst matchLoc *al = a;\n\tconst matchLoc *bl = b;\n\n\tif (al->line == bl->line\n\t\t&& memcmp (&al->pos, &bl->pos, sizeof (al->pos)) == 0)\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic void locPrint (const void *a, MIO *out)\n{\n\tconst matchLoc *al = a;\n\tmio_printf (out, \"#<matchloc %p line: %lu>\", a, al->line);\n}\n\nstatic void tagFree (void *a)\n{\n\ttagEntryInfo *e = a;\n\teFree ((void *)e->name);\t/* TODO */\n\teFree (e);\n}\n\nstatic int tagEqual (const void *a, const void *b)\n{\n\tif (a == b)\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic void tagPrint (const void *a, MIO *out)\n{\n\tconst tagEntryInfo *tag = a;\n\tmio_printf (out, \"#<tagEntryInfo %p name: %s line: %lu>\",\n\t\t\t\ttag, tag->name, tag->lineNumber);\n}\n\nextern void optscriptRegisterOperators(EsObject * dict,\n\t\t\t\t\t\t\t\t\t   struct optscriptOperatorRegistration regs[], size_t count)\n{\n\tEsObject *op;\n\tEsObject *sym;\n\n\tfor (size_t i = 0; i < count; i++)\n\t{\n\t\tsym = es_symbol_intern (regs[i].name);\n\t\top = opt_operator_new (regs[i].fn, es_symbol_get (sym), regs[i].arity,\n\t\t\t\t\t\t\t   regs[i].help_str);\n\t\topt_dict_def (dict, sym, op);\n\t\tes_object_unref (op);\n\t}\n}\n\nextern xtagType optscriptGetXtagType (const EsObject *extra)\n{\n\tEsObject *extra_sym = es_pointer_get (extra);\n\tconst char *extra_str = es_symbol_get (extra_sym);\n\n\tconst char *sep = strchr (extra_str, '.');\n\tif (sep)\n\t{\n\t\tlangType lang = getNamedLanguage (extra_str, sep - extra_str);\n\t\tif (lang == LANG_IGNORE)\n\t\t\treturn XTAG_UNKNOWN;\n\n\t\treturn getXtagTypeForNameAndLanguage (sep + 1, lang);\n\t}\n\telse\n\t\treturn getXtagTypeForNameAndLanguage (extra_str, LANG_IGNORE);\n}\n"
  },
  {
    "path": "main/script_p.h",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains ctags specific optscript objects\n*/\n\n#ifndef CTAGS_MAIN_SCRIPT_PRIVATE_H\n#define CTAGS_MAIN_SCRIPT_PRIVATE_H\n\n#include \"general.h\"  /* must always come first */\n\n#include \"field.h\"\n#include \"optscript.h\"\n#include \"mio.h\"\n\nstruct optscriptOperatorRegistration {\n\tconst char *name;\n\tOptOperatorFn fn;\n\tint arity;\n\tconst char *help_str;\n};\nextern void optscriptRegisterOperators(EsObject * dict,\n\t\t\t\t\t\t\t\t\t   struct optscriptOperatorRegistration regs[], size_t count);\n\nextern EsObject *OPTSCRIPT_ERR_NOTAGENTRY;\nextern EsObject *OPTSCRIPT_ERR_UNKNOWNLANGUAGE;\nextern EsObject *OPTSCRIPT_ERR_UNKNOWNEXTRA;\nextern EsObject *OPTSCRIPT_ERR_FIELDRESET;\n\nextern OptVM *optscriptInit (void);\n\nextern void optscriptInstallProcs (EsObject *dict, OptOperatorFn matchResultAccessor);\nextern void optscriptInstallFieldAccessor (EsObject *dict, fieldType ftype);\n\nextern void optscriptSetup (OptVM *vm, EsObject *dict, int corkIndex);\nextern void optscriptTeardown (OptVM *vm, EsObject *dict);\n\n/* If len is 0, strlen (src) is used instead of 0. */\nextern EsObject *optscriptRead (OptVM *vm, const char *src, size_t len);\nextern EsObject *optscriptEval (OptVM *vm, EsObject *code);\nextern EsObject *optscriptDefine (EsObject *dict, const char *name, EsObject *obj);\n\nextern EsObject *optscriptReadAndEval   (OptVM *vm, const char *src, size_t len);\nextern EsObject *optscriptReadAndDefine (OptVM *vm, EsObject *dict, const char *name,\n\t\t\t\t\t\t\t\t\t\t const char *src, size_t len);\n\nextern EsObject *optscriptLoad          (OptVM *vm, MIO *mio);\n\nextern void      optscriptHelp          (OptVM *vm, FILE *fp, EsObject *procdocs);\n\nextern xtagType optscriptGetXtagType (const EsObject *extra);\n\ntypedef struct {\n\tunsigned long base;\t\t\t/* useless when the parser type is\n\t\t\t\t\t\t\t\t * REG_PARSER_SINGLE_LINE.\n\t\t\t\t\t\t\t\t * base + delta is the file offset. */\n\tunsigned long delta;\t\t/* for _advanceto operator, relateive from\n\t\t\t\t\t\t\t\t * the base. */\n\tunsigned long line;\n\tMIOPos pos;\n} matchLoc;\nextern int OPT_TYPE_MATCHLOC;\n\nextern int OPT_TYPE_TAG;\n#endif\t/* CTAGS_MAIN_SCRIPT_PRIVATE_H */\n"
  },
  {
    "path": "main/seccomp.c",
    "content": "/*\n*   Copyright (c) 2017, Google, Inc.\n*\n*   Author: Han-Wen Nienhuys <hanwen@google.com>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n\n#include \"general.h\"\n#include \"debug.h\"\n#include \"interactive_p.h\"\n#include \"routines.h\"\n\n#ifdef HAVE_SECCOMP\n#include <seccomp.h>\n\n\nint installSyscallFilter (void)\n{\n\t// Use SCMP_ACT_TRAP to get a core dump.\n\tscmp_filter_ctx ctx = seccomp_init (SCMP_ACT_KILL);\n\tif (ctx == NULL)\n\t{\n\t\treturn 1;\n\t}\n\n\t// Memory allocation.\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (mmap), 0);\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (munmap), 0);\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (mremap), 0);\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (brk), 0);\n\n\t// I/O\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (read), 0);\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (write), 0);\n\n\t// Clean exit\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (exit), 0);\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (exit_group), 0);\n\n\t// The bowels of stdio want to know the size of a file, even for stdout.\n#if (defined(__SNR_fstat) && __SNR_fstat)\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (fstat), 0);\n#endif\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (fstat64), 0);\n#ifdef __SNR_newfstatat\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (newfstatat), 0);\n#endif\n#ifdef __SNR_statx\n\t// armhf fallback\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (statx), 0);\n#endif\n\n\t// seems unnecessary, but this comes from\n\t// main/parse.c:2764 : tagFilePosition (&tagfpos);\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (lseek), 0);\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (_llseek), 0);\n\n\t// libxml2 uses pthread_once, which in turn uses a futex\n\tseccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS (futex), 0);\n\n\tverbose (\"Entering sandbox\\n\");\n\tint err = seccomp_load (ctx);\n\tif (err < 0)\n\t{\n\t\terror (WARNING, \"Failed to install syscall filter\");\n\t\t/* Error handling is done in upper layer. */\n\t}\n\n\tseccomp_release (ctx);\n\n\treturn err;\n}\n\n/*\n   TODO: on OSX, Seatbelt\n   (https://dev.chromium.org/developers/design-documents/sandbox/osx-sandboxing-design)\n   should be used for equivalent functionality.\n */\n\n#else\nint installSyscallFilter (void)\n{\n\tAssertNotReached ();\n\treturn -1;\n}\n#endif\n"
  },
  {
    "path": "main/selectors.c",
    "content": "/*\n * Copyright (c) 2015, Dmitri Tikhonov\n *\n * This source code is released for free distribution under the terms of the\n * GNU General Public License version 2 or (at your option) any later version.\n *\n * selectors.c -- routines for selecting a language\n */\n\n#include \"general.h\"\n\n#include <ctype.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"debug.h\"\n#include \"parse_p.h\"\n#include \"options.h\"\n#include \"selectors.h\"\n#include \"vstring.h\"\n#include \"mio.h\"\n\nstatic const char *TR_UNKNOWN = NULL;\nstatic const char *TR_BREAK   = \"/BREAK/\";\nstatic const char *TR_PERL5\t  = \"Perl\";\nstatic const char *TR_PERL6\t  = \"Perl6\";\n\nstatic const char *TR_OBJC\t  = \"ObjectiveC\";\nstatic const char *TR_MATLAB  = \"MatLab\";\n\nstatic const char *TR_R\t\t  = \"R\";\nstatic const char *TR_ASM\t  = \"Asm\";\n\nstatic const char *TR_REXX\t   = \"REXX\";\nstatic const char *TR_DOSBATCH = \"DosBatch\";\n\nstatic const char *TR_LISP\t   = \"Lisp\";\nstatic const char *TR_LEX\t   = \"LEX\";\n\nstatic const char *TR_FORTH\t   = \"Forth\";\nstatic const char *TR_FORTRAN  = \"Fortran\";\n\nstatic const char *TR_V = \"V\";\nstatic const char *TR_VERILOG = \"Verilog\";\n\nstatic const char *TR_PROLOG = \"Prolog\";\n\nstatic const char *TR_SYSTEMD_UNIT = \"SystemdUnit\";\nstatic const char *TR_DBUS_SERVICE = \"DBusService\";\n\nstatic const char *TR_HAXE = \"Haxe\";\nstatic const char *TR_QEMUHX = \"QemuHX\";\n\n#define startsWith(line,prefix)\t\t\t\t\t\t\t\t\t\\\n\t(strncmp(line, prefix, strlen(prefix)) == 0? true: false)\n\nstatic const char *selectByLines (MIO *input,\n\t\t\t\t\t\t\t\t  const char* (* lineTaster) (const char *, void *),\n\t\t\t\t\t\t\t\t  const char* defaultLang,\n\t\t\t\t\t\t\t\t  void *userData)\n{\n\tchar line[0x800];\n\twhile (mio_gets(input, line, sizeof(line))) {\n\t\tconst char *lang = lineTaster (line, userData);\n\t\tif (lang == TR_BREAK)\n\t\t\treturn defaultLang;\n\t\tif (lang)\n\t\t\treturn lang;\n\t}\n\treturn defaultLang;\n}\n\n/* Returns \"Perl\" or \"Perl6\" or NULL if it does not taste like anything */\nstatic const char *\ntastePerlLine (const char *line, void *data CTAGS_ATTR_UNUSED)\n{\n\twhile (isspace((unsigned char) *line))\n\t\t++line;\n#define STRLEN(s) (sizeof(s) - 1)\n/* Assume the first character has been checked: */\n#define CHECK_PART(line, s) (\t\t\t\t\t\t\t\t\\\n\t\t0 == strncmp((line) + 1, (s) + 1, STRLEN(s) - 1) && \\\n\t\t!isalnum((unsigned char) (line)[STRLEN(s)]))\n\tswitch (line[0]) {\n\tcase '#':\t\t/* TODO: taste modeline */\n\tcase '\\0':\n\t\treturn TR_UNKNOWN;\n\tcase '=':\n\t\tif (CHECK_PART(line, \"=head1\"))\n\t\t\treturn TR_PERL5;\n\t\tif (CHECK_PART(line, \"=head2\"))\n\t\t\treturn TR_PERL5;\n\t\tbreak;\n\tcase 'c':\n\t\tif (CHECK_PART(line, \"class\"))\n\t\t\treturn TR_PERL6;\n\t\tbreak;\n\tcase 'g':\n\t\tif (CHECK_PART(line, \"grammar\"))\n\t\t\treturn TR_PERL6;\n\t\tbreak;\n\tcase 'm':\n\t\t/* TODO: my may be many things: class, role, etc. */\n\t\tif (CHECK_PART(line, \"my class\"))\n\t\t\treturn TR_PERL6;\n\t\tif (CHECK_PART(line, \"method\"))\n\t\t\treturn TR_PERL6;\n\t\tif (CHECK_PART(line, \"multi\"))\n\t\t\treturn TR_PERL6;\n\t\tbreak;\n\tcase 'n':\n\t\tif (CHECK_PART(line, \"need\"))\n\t\t\treturn TR_PERL6;\n\t\tbreak;\n\tcase 'p':\n\t\tif (CHECK_PART(line, \"package\"))\n\t\t\treturn TR_PERL5;\n\t\tbreak;\n\tcase 'r':\n\t\tif (CHECK_PART(line, \"role\"))\n\t\t\treturn TR_PERL6;\n\t\tif (CHECK_PART(line, \"require 5\"))\n\t\t\treturn TR_PERL5;\n\t\tbreak;\n\tcase 'u':\n\t\tif (CHECK_PART(line, \"unit\"))\n\t\t\treturn TR_PERL6;\n\t\tif (CHECK_PART(line, \"use v6\"))\n\t\t\treturn TR_PERL6;\n\t\tif (CHECK_PART(line, \"use nqp\"))\n\t\t\treturn TR_PERL5;\n\t\tif (CHECK_PART(line, \"use warnings\"))\n\t\t\treturn TR_PERL5;\n\t\tbreak;\n\t}\n#undef CHECK_PART\n\treturn TR_UNKNOWN;\n}\n\nconst char *\nselectByPickingPerlVersion (MIO *input,\n\t\t\t\t\t\t\tlangType *candidates CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\tunsigned int nCandidates CTAGS_ATTR_UNUSED)\n{\n\t/* Default to Perl 5 */\n\treturn selectByLines (input, tastePerlLine, TR_PERL5, NULL);\n}\n\nstatic const char *\ntasteObjectiveCOrMatLabLines (const char *line, void *data CTAGS_ATTR_UNUSED)\n{\n\tif (startsWith (line, \"% \")\n\t\t|| startsWith (line, \"%{\"))\n\t\treturn TR_MATLAB;\n\telse if (startsWith (line, \"// \")\n\t\t\t || startsWith (line, \"/* \"))\n\t\treturn TR_OBJC;\n\telse if (startsWith (line, \"#include\")\n\t\t\t || startsWith (line, \"#import\")\n\t\t\t || startsWith (line, \"#define \")\n\t\t\t || startsWith (line, \"#ifdef \"))\n\t\treturn TR_OBJC;\n\telse if (startsWith (line, \"@interface \")\n\t\t\t || startsWith (line, \"@implementation \")\n\t\t\t || startsWith (line, \"@protocol \"))\n\t\treturn TR_OBJC;\n\telse if (startsWith (line, \"struct \")\n\t\t\t || startsWith (line, \"union \")\n\t\t\t || startsWith (line, \"typedef \"))\n\t\treturn TR_OBJC;\n\telse {\n\t\tif (startsWith (line, \"function \")) {\n\t\t\tconst char *p = line + strlen (\"function \");\n\t\t\twhile (isspace((unsigned char) *p))\n\t\t\t\tp++;\n\t\t\tif (*p != '\\0' && *p != '(')\n\t\t\t\treturn TR_MATLAB;\n\t\t}\n\t}\n\treturn NULL;\n}\n\nconst char *\nselectByObjectiveCAndMatLabKeywords (MIO * input,\n\t\t\t\t\t\t\t\t\t langType *candidates CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t unsigned int nCandidates CTAGS_ATTR_UNUSED)\n{\n\treturn selectByLines (input, tasteObjectiveCOrMatLabLines,\n\t\t\t\t\t\t  NULL, NULL);\n}\n\nstatic const char *\ntasteObjectiveC (const char *line, void *data CTAGS_ATTR_UNUSED)\n{\n\tif (startsWith (line, \"#import\")\n\t\t|| startsWith (line, \"@interface \")\n\t\t|| startsWith (line, \"@implementation \")\n\t\t|| startsWith (line, \"@protocol \"))\n\t\treturn TR_OBJC;\n\treturn NULL;\n}\n\nconst char *\nselectByObjectiveCKeywords (MIO * input,\n\t\t\t\t\t\t\tlangType *candidates,\n\t\t\t\t\t\t\tunsigned int nCandidates)\n{\n\t/* TODO: Ideally opening input should be delayed til\n\t   enable/disable based selection is done. */\n\n\tstatic langType objc = LANG_IGNORE;\n\tif (objc == LANG_IGNORE)\n\t\tobjc = getNamedLanguage (TR_OBJC, 0);\n\n\tbool objcInCandidate = false;\n\tconst char *altCandidateName = NULL;\n\tfor (unsigned int i = 0; i < nCandidates; i++)\n\t{\n\t\tif (candidates[i] == objc)\n\t\t{\n\t\t\tobjcInCandidate = true;\n\t\t\tbreak;\n\t\t}\n\t\telse if (altCandidateName == NULL)\n\t\t{\n\t\t\tif (isLanguageEnabled (candidates[i]))\n\t\t\t{\n\t\t\t\taltCandidateName = getLanguageName (candidates[i]);\n\t\t\t\tAssert (altCandidateName);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!objcInCandidate)\n\t\treturn altCandidateName;\n\tif (altCandidateName == NULL)\n\t{\n\t\tif (isLanguageEnabled (objc))\n\t\t\treturn TR_OBJC;\n\t\treturn NULL;\n\t}\n\n\tAssert (altCandidateName);\n\treturn selectByLines (input, tasteObjectiveC, altCandidateName,\n\t\t\t\t\t\t  NULL);\n}\n\nstatic const char *\ntasteR (const char *line, void *data CTAGS_ATTR_UNUSED)\n{\n\t/* As far as reading test cases in GNU assembler,\n\t   assembly language for d10v and d30v processors\n\t   uses \"<-\" as part its syntax. I cannot find better\n\t   hint for distinguishing between the assembly\n\t   language and R.\n\t   ----\n\t   binutils-2.15.92.0.2/gas/testsuite/gas/d30v/mul.s */\n\treturn strstr (line, \"<-\")? TR_R: NULL;\n}\n\nconst char *\nselectByArrowOfR (MIO *input,\n\t\t\t\t  langType *candidates CTAGS_ATTR_UNUSED,\n\t\t\t\t  unsigned int nCandidates CTAGS_ATTR_UNUSED)\n{\n\t/* TODO: Ideally opening input should be delayed till\n\t   enable/disable based selection is done. */\n\n\tstatic langType R\t= LANG_IGNORE;\n\tstatic langType Asm = LANG_IGNORE;\n\n\tif (R == LANG_IGNORE)\n\t\tR = getNamedLanguage (TR_R, 0);\n\n\tif (Asm == LANG_IGNORE)\n\t\tAsm = getNamedLanguage (TR_ASM, 0);\n\n\tAssert (0 <= R);\n\tAssert (0 <= Asm);\n\n\tif (! isLanguageEnabled (R))\n\t\treturn TR_ASM;\n\telse if (! isLanguageEnabled (Asm))\n\t\treturn TR_R;\n\n\treturn selectByLines (input, tasteR, NULL,\n\t\t\t\t\t\t  NULL);\n}\n\nstatic const char *\ntasteREXXOrDosBatch (const char *line, void *data)\n{\n\tbool * in_rexx_comment = data;\n\n\tif (startsWith (line, \":\"))\n\t\treturn TR_DOSBATCH;\n\telse if (*in_rexx_comment\n\t\t\t && strstr (line, \"*/\"))\n\t\treturn TR_REXX;\n\telse if (strstr (line, \"/*\"))\n\t{\n\t\t*in_rexx_comment = true;\n\t\treturn NULL;\n\t}\n\telse\n\t\treturn NULL;\n}\n\nconst char *\nselectByRexxCommentAndDosbatchLabelPrefix (MIO *input,\n\t\t\t\t\t\t\t\t\t\t   langType *candidates CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\t   unsigned int nCandidates CTAGS_ATTR_UNUSED)\n{\n\t/* TODO: Ideally opening input should be delayed till\n\t   enable/disable based selection is done. */\n\n\tstatic langType rexx\t = LANG_IGNORE;\n\tstatic langType dosbatch = LANG_IGNORE;\n\tbool in_rexx_comment = false;\n\n\tif (rexx == LANG_IGNORE)\n\t\trexx = getNamedLanguage (TR_R, 0);\n\n\tif (dosbatch == LANG_IGNORE)\n\t\tdosbatch = getNamedLanguage (TR_DOSBATCH, 0);\n\n\tAssert (0 <= rexx);\n\tAssert (0 <= dosbatch);\n\n\tif (! isLanguageEnabled (rexx))\n\t\treturn TR_DOSBATCH;\n\telse if (! isLanguageEnabled (dosbatch))\n\t\treturn TR_REXX;\n\n\treturn selectByLines (input, tasteREXXOrDosBatch,\n\t\t\t\t\t\t  NULL, &in_rexx_comment);\n}\n\nstatic const char *\ntasteLispOrLEXLines (const char *line, void *data CTAGS_ATTR_UNUSED)\n{\n\tif (strcmp(line, \"%{\\n\") == 0\n\t\t|| strcmp(line, \"%top{\\n\") == 0\n\t\t|| strcmp(line, \"%%\\n\") == 0)\n\t\treturn TR_LEX;\n\treturn TR_UNKNOWN;\n}\n\nconst char *\nselectLispOrLEXByLEXMarker (MIO *input,\n\t\t\t\t\t\t\tlangType *candidates CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\tunsigned int nCandidates CTAGS_ATTR_UNUSED)\n{\n\treturn selectByLines (input, tasteLispOrLEXLines, TR_LISP, NULL);\n}\n\nstatic const char *\ntasteFortranOrForthLines (const char *line, void *data CTAGS_ATTR_UNUSED)\n{\n\tif (line[0] && ((line[0] == ':' && line[1] && isspace((unsigned char)line[1]))\n\t\t\t\t\t|| line[0] == '\\\\'))\n\t\treturn TR_FORTH;\n\treturn TR_UNKNOWN;\n}\n\nconst char *\nselectFortranOrForthByForthMarker (MIO *input,\n\t\t\t\t\t\t\t\t   langType *candidates CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t   unsigned int nCandidates CTAGS_ATTR_UNUSED)\n{\n\treturn selectByLines (input, tasteFortranOrForthLines, TR_FORTRAN, NULL);\n}\n\nstruct VOrVerilogScore {\n\tint v;\n\tint verilog;\n};\n\nstatic const char *\ntasteVOrVerilogLines (const char *line, void *data)\n{\n\tstruct VOrVerilogScore *score = (struct VOrVerilogScore *)data;\n\n\twhile ((*line == ' ')\n\t\t   || (*line == '\\t'))\n\t\tline++;\n\n\t/* top 10 line-starting words most commonly present in first 150 lines of\n\t * all files in V v0.4 project source code (at time of writing) */\n\tif (strncmp(line, \"fn\", 2) == 0 ||      /* present in 82.8% files */\n\t\tstrncmp(line, \"return\", 6) == 0 ||  /* present in 46.2% files */\n\t\tstrncmp(line, \"mut\", 3) == 0 ||     /* present in 43.7% files */\n\t\tstrncmp(line, \"println\", 7) == 0 || /* present in 38.9% files */\n\t\tstrncmp(line, \"assert\", 6) == 0 ||  /* present in 38.8% files */\n\t\tstrncmp(line, \"struct\", 6) == 0 ||  /* present in 34.5% files */\n\t\t/* \"module\" is present in 29.6% files, but also ued in verilog */\n\t\tstrncmp(line, \"import\", 6) == 0 ||  /* present in 27.6% files */\n\t\tstrncmp(line, \"if\", 2) == 0 ||      /* present in 24.9% files */\n\t\tstrncmp(line, \"pub\", 3) == 0)       /* present in 24.1% files */\n\t\tscore->v++;\n\t/* `define, end, begin, and reg  imply Verilog */\n\telse if (strncmp(line, \"end\", 3) == 0\n\t\t\t || strncmp(line, \"begin\", 5) == 0\n\t\t\t || strncmp(line, \"reg\", 3) == 0\n\t\t\t || strncmp(line, \"wire\", 4) == 0\n\t\t\t || strncmp(line, \"parameter\", 9) == 0\n\t\t\t || strncmp(line, \"`define\", 5) == 0)\n\t\tscore->verilog++;\n\n\treturn TR_UNKNOWN;\n}\n\nconst char *\nselectVOrVerilogByKeywords (MIO *input,\n\t\t\t\t\t\t\tlangType *candidates CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\tunsigned int nCandidates CTAGS_ATTR_UNUSED)\n{\n\tstruct VOrVerilogScore score = {\n\t\t.v = 0,\n\t\t.verilog = 0,\n\t};\n\tselectByLines (input, tasteVOrVerilogLines, TR_UNKNOWN, &score);\n\n\tint d = score.v - score.verilog;\n\tif (d > 0)\n\t\treturn TR_V;\n\telse if (d < 0)\n\t\treturn TR_VERILOG;\n\telse\n\t\treturn TR_UNKNOWN;\n}\n\nstruct PerlOrPrologScore {\n\tint perl;\n\tint prolog;\n\tunsigned int linum;\n};\n\nstatic const char *\ntastePerlOrPrologLines (const char *line, void *data)\n{\n\tstruct PerlOrPrologScore *score = (struct PerlOrPrologScore *)data;\n\n\tscore->linum++;\n\n\tif (score->linum > 16)\n\t\treturn TR_BREAK;\n\n\tif (line[0] == '#' && line[1] != '!')\n\t{\n\t\t/* This is not a shebang: the comment line of perl */\n\t\tscore->perl++;\n\t}\n\telse if (line[0] == '%')\n\t{\n\t\tscore->prolog++;\n\t}\n\telse if (startsWith (line, \"use \"))\n\t{\n\t\tscore->perl++;\n\t}\n\telse if (startsWith (line, \":-\"))\n\t\tscore->prolog += 2;\n\telse if (strstr (line, \":-\"))\n\t\tscore->prolog++;\n\telse if (strstr (line, \"/*\"))\n\t\tscore->prolog++;\n\n\treturn TR_UNKNOWN;\n}\n\nconst char *\nselectPerlOrPrologByDistinctiveToken (struct _MIO *input, langType *candidates, unsigned int nCandidates)\n{\n\tstruct PerlOrPrologScore score = {\n\t\t.perl = 0,\n\t\t.prolog = 0,\n\t\t.linum = 0,\n\t};\n\tselectByLines (input, tastePerlOrPrologLines, TR_UNKNOWN, &score);\n\n\tint d = score.perl - score.prolog;\n\tif (d > 0)\n\t\treturn TR_PERL5;\n\telse if (d < 0)\n\t\treturn TR_PROLOG;\n\telse\n\t\treturn TR_UNKNOWN;\n}\n\nstatic const char *\ntasteDBusServiceOrSystemdUnit (const char *line, void *data CTAGS_ATTR_UNUSED)\n{\n\tif (startsWith (line, \"[D-BUS Service]\"))\n\t\treturn TR_DBUS_SERVICE;\n\tif (startsWith (line, \"[Unit]\"))\n\t\treturn TR_SYSTEMD_UNIT;\n\treturn TR_UNKNOWN;\n}\n\nconst char *\nselectByDBusServiceAndSystemdUnitSectionNames (MIO *input,\n\t\t\t\t\t\t\tlangType *candidates CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\tunsigned int nCandidates CTAGS_ATTR_UNUSED)\n{\n\treturn selectByLines (input, tasteDBusServiceOrSystemdUnit, TR_SYSTEMD_UNIT, NULL);\n}\n\nstatic const char *\ntasteHaxeOrQemuHX (const char *line, void *data CTAGS_ATTR_UNUSED)\n{\n\tif (startsWith (line, \"HXCOMM\"))\n\t\treturn TR_QEMUHX;\n\tif (startsWith (line, \"enum\")\n\t\t|| startsWith (line, \"interface\")\n\t\t|| startsWith (line, \"typedef\")\n\t\t|| startsWith (line, \"class\"))\n\t\treturn TR_HAXE;\n\treturn TR_UNKNOWN;\n}\n\nconst char *\nselectHaxeOrQemuHXByCommentMarker (MIO *input,\n\t\t\t\t\t\t\t\t   langType *candidates CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t   unsigned int nCandidates CTAGS_ATTR_UNUSED)\n{\n\treturn selectByLines (input, tasteHaxeOrQemuHX, TR_HAXE, NULL);\n}\n\n#ifdef HAVE_LIBXML\n#include <libxml/parser.h>\n#include <libxml/xpath.h>\n#include <libxml/tree.h>\n\nstatic void suppressWarning (void *ctx CTAGS_ATTR_UNUSED, const char *msg CTAGS_ATTR_UNUSED, ...)\n{\n}\n\nstatic xmlDocPtr\nxmlParseMIO (MIO *input)\n{\n\tconst unsigned char *buf;\n\tsize_t len;\n\n\tbuf = mio_memory_get_data (input, &len);\n\tAssert (buf);\n\n\txmlSetGenericErrorFunc (NULL, suppressWarning);\n#ifdef IS_xmlLineNumbersDefault_DEPRECATED\n\treturn xmlReadMemory((const char *)buf, len, NULL, NULL, 0);\n#else\n\txmlLineNumbersDefault (1);\n\treturn xmlParseMemory((const char *)buf, len);\n#endif\n\n}\n\nstatic bool\nmatchXpathFileSpec (xmlDocPtr doc, xpathFileSpec *spec)\n{\n\tif (spec->rootElementName)\n\t{\n\t\tif (*spec->rootElementName == '\\0')\n\t\t{\n\t\t\t/* The statement is just for keeping code symmetric.\n\t\t\t   Meaningless examination: a root element is\n\t\t\t   always there.*/\n\t\t\tif (doc->children && doc->children->name)\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (! (doc->children\n\t\t\t\t\t&& doc->children->name\n\t\t\t\t\t&& (strcmp (spec->rootElementName, (char *)doc->children->name) == 0)))\n\t\t\treturn false;\n\t\telse\n\t\t\tverbose (\"\t\tXml[rootElementName]== %s\\n\",\n\t\t\t\t\t spec->rootElementName);\n\t}\n\n\tif (spec->nameInDTD)\n\t{\n\t\tif (*spec->nameInDTD == '\\0')\n\t\t{\n\t\t\tif (doc->intSubset && doc->intSubset->name)\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (! (doc->intSubset\n\t\t\t\t\t&& doc->intSubset->name\n\t\t\t\t\t&& (strcmp (spec->nameInDTD, (char *)doc->intSubset->name) == 0)))\n\t\t\treturn false;\n\t\telse\n\t\t\tverbose (\"\t\tXml[nameInDTD]== %s\\n\",\n\t\t\t\t\t spec->nameInDTD);\n\t}\n\n\tif (spec->externalID)\n\t{\n\t\tif (*spec->externalID == '\\0')\n\t\t{\n\t\t\tif (doc->intSubset && doc->intSubset->ExternalID)\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (! (doc->intSubset\n\t\t\t\t\t&& doc->intSubset->ExternalID\n\t\t\t\t\t&& (strcmp (spec->externalID, (char *)doc->intSubset->ExternalID) == 0)))\n\t\t\treturn false;\n\t\telse\n\t\t\tverbose (\"\t\tXml[externalID]== %s\\n\",\n\t\t\t\t\t spec->externalID);\n\n\t}\n\n\tif (spec->systemID)\n\t{\n\t\tif (*spec->systemID == '\\0')\n\t\t{\n\t\t\tif (doc->intSubset && doc->intSubset->SystemID)\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (! (doc->intSubset\n\t\t\t\t\t&& doc->intSubset->SystemID\n\t\t\t\t\t&& (strcmp (spec->systemID, (char *)doc->intSubset->SystemID) == 0)))\n\t\t\treturn false;\n\t\telse\n\t\t\tverbose (\"\t\tXml[systemID]== %s\\n\",\n\t\t\t\t\t spec->systemID);\n\t}\n\n\tif (spec->rootNSPrefix)\n\t{\n\t\tif (*spec->rootNSPrefix == '\\0')\n\t\t{\n\t\t\tif (doc->children && doc->children->ns && doc->children->ns->prefix)\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (! (doc->children\n\t\t\t\t\t&& doc->children->ns\n\t\t\t\t\t&& doc->children->ns->prefix\n\t\t\t\t\t&& (strcmp (spec->rootNSPrefix, (char *)doc->children->ns->prefix))))\n\t\t\treturn false;\n\t\telse\n\t\t\tverbose (\"\t\tXml[rootNSPrefix]== %s\\n\",\n\t\t\t\t\t spec->rootNSPrefix);\n\t}\n\n\tif (spec->rootNSHref)\n\t{\n\t\tif (*spec->rootNSHref == '\\0')\n\t\t{\n\t\t\tif (doc->children && doc->children->ns && doc->children->ns->href)\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (! (doc->children\n\t\t\t\t\t&& doc->children->ns\n\t\t\t\t\t&& doc->children->ns->href\n\t\t\t\t\t&& (strcmp (spec->rootNSHref, (char *)doc->children->ns->href) == 0)))\n\t\t\treturn false;\n\t\telse\n\t\t\tverbose (\"\t\tXml[rootNSHref]== %s\\n\",\n\t\t\t\t\t spec->rootNSHref);\n\t}\n\treturn true;\n}\n\nstatic const char *\nselectParserForXmlDoc (xmlDocPtr doc,\n\t\t\t\t\t   langType *candidates,\n\t\t\t\t\t   unsigned int nCandidates)\n{\n\n\tunsigned int lang_index;\n\tbool xml_parser_is_in_candidate = false;\n\n\tverbose (\"\t\tXml[rootElementName]: %s\\n\",\n\t\t\t (doc->children && doc->children->name)\n\t\t\t ? ((char *)doc->children->name): \"-\");\n\tverbose (\"\t\tXml[nameInDTD]: %s\\n\",\n\t\t\t (doc->intSubset && doc->intSubset->name)\n\t\t\t ? ((char *)doc->intSubset->name): \"-\");\n\tverbose (\"\t\tXml[externalID]: %s\\n\",\n\t\t\t (doc->intSubset && doc->intSubset->ExternalID)\n\t\t\t ? ((char *)doc->intSubset->ExternalID): \"-\");\n\tverbose (\"\t\tXml[systemID]: %s\\n\",\n\t\t\t (doc->intSubset && doc->intSubset->SystemID)\n\t\t\t ? ((char *)doc->intSubset->SystemID): \"-\");\n\tverbose (\"\t\tXml[rootNSPrefix]: %s\\n\",\n\t\t\t (doc->children && doc->children->ns && doc->children->ns->prefix)\n\t\t\t ? ((char *)doc->children->ns->prefix): \"-\");\n\tverbose (\"\t\tXml[rootNSHref]: %s\\n\",\n\t\t\t (doc->children && doc->children->ns && doc->children->ns->href)\n\t\t\t ? ((char *)doc->children->ns->href): \"-\");\n\n\tfor (lang_index = 0; lang_index < nCandidates; lang_index++)\n\t{\n\t\tunsigned int spec_index;\n\t\txpathFileSpec* spec;\n\t\tunsigned int spec_count;\n\n\t\tverbose (\"\t\tlxpath examines %s\\n\", getLanguageName (candidates[lang_index]));\n\n\t\tspec_count = getXpathFileSpecCount (candidates[lang_index]);\n\t\tfor (spec_index = 0; spec_index < spec_count; spec_index++)\n\t\t{\n\t\t\tspec = getXpathFileSpec (candidates[lang_index], spec_index);\n\t\t\tif (matchXpathFileSpec (doc, spec))\n\t\t\t\treturn getLanguageName (candidates[lang_index]);\n\t\t}\n\n\t\tif (strcmp (getLanguageName (candidates[lang_index]), \"XML\") == 0)\n\t\t\txml_parser_is_in_candidate = true;\n\t}\n\n\tif (xml_parser_is_in_candidate)\n\t{\n\t\tverbose (\"\t\tUse generic XML parser as fallback\\n\");\n\t\treturn \"XML\";\n\t}\n\n\treturn NULL;\n}\n\nconst char *\nselectByXpathFileSpec (MIO *input,\n\t\t\t\t\t   langType *candidates,\n\t\t\t\t\t   unsigned int nCandidates)\n{\n\txmlDocPtr doc;\n\tconst char *r = NULL;\n\n\tdoc = xmlParseMIO (input);\n\tif (doc == NULL)\n\t\treturn NULL;\n\n\tr = selectParserForXmlDoc (doc, candidates, nCandidates);\n\n\tif (r == NULL)\n\t\txmlFreeDoc (doc);\n\telse\n\t\tmio_attach_user_data (input,\n\t\t\t\t\t\t\t  doc,(MIODestroyNotify)xmlFreeDoc);\n\n\treturn r;\n}\n\n#else\n\nconst char *\nselectByXpathFileSpec (MIO *input,\n\t\t\t\t\t   langType *candidates,\n\t\t\t\t\t   unsigned int nCandidates)\n{\n\treturn NULL;\n}\n\n#endif\n"
  },
  {
    "path": "main/selectors.h",
    "content": "/*\n * Copyright (c) 2015, Dmitri Tikhonov\n *\n * This source code is released for free distribution under the terms of the\n * GNU General Public License version 2 or (at your option) any later version.\n *\n * selectors.h\n */\n\n#ifndef CTAGS_MAIN_SELECTORS_H\n#define CTAGS_MAIN_SELECTORS_H\n\n#include \"types.h\"\n\nconst char *\nselectByPickingPerlVersion (struct _MIO *, langType *, unsigned int);\n\nconst char *\nselectByObjectiveCAndMatLabKeywords (struct _MIO *, langType *, unsigned int);\n\nconst char *\nselectByObjectiveCKeywords(struct _MIO *, langType *, unsigned int);\n\nconst char *\nselectByArrowOfR (struct _MIO *, langType *, unsigned int);\n\nconst char *\nselectByRexxCommentAndDosbatchLabelPrefix (struct _MIO *, langType *, unsigned int);\n\nconst char *\nselectLispOrLEXByLEXMarker (struct _MIO *, langType *, unsigned int);\n\nconst char *\nselectVOrVerilogByKeywords (struct _MIO *, langType *, unsigned int);\n\nconst char *\nselectByXpathFileSpec (struct _MIO *input, langType *candidates, unsigned int nCandidates);\n\nconst char *\nselectFortranOrForthByForthMarker (struct _MIO *input, langType *candidates, unsigned int nCandidates);\n\nconst char *\nselectPerlOrPrologByDistinctiveToken (struct _MIO *input, langType *candidates, unsigned int nCandidates);\n\nconst char *\nselectByDBusServiceAndSystemdUnitSectionNames (struct _MIO *input, langType *candidates, unsigned int nCandidates);\n\nconst char *\nselectHaxeOrQemuHXByCommentMarker (struct _MIO *input,\n\t\t\t\t\t\t\t\t   langType *candidates CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t   unsigned int nCandidates CTAGS_ATTR_UNUSED);\n#endif\n"
  },
  {
    "path": "main/sort.c",
    "content": "/*\n*   Copyright (c) 1996-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions to sort the tag entries.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <errno.h>\n#if defined (HAVE_IO_H)\n# include <io.h>\n#endif\n#include <stdlib.h>  /* to declare malloc () */\n#if defined (HAVE_UNISTD_H)\n# include <unistd.h>\n#endif\n#include <string.h>\n#include <stdio.h>\n\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"options_p.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"sort_p.h\"\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nextern void catFile (MIO *mio)\n{\n\tif (mio != NULL)\n\t{\n\t\tint c;\n\t\tmio_seek (mio, 0, SEEK_SET);\n\t\twhile ((c = mio_getc (mio)) != EOF)\n\t\t\tputchar (c);\n\t\tfflush (stdout);\n\t}\n}\n\n#ifdef EXTERNAL_SORT\n\n#ifdef NON_CONST_PUTENV_PROTOTYPE\n# define PE_CONST\n#else\n# define PE_CONST const\n#endif\n\n/*\n   Output file name should not be evaluated in system(3) function.\n   The name must be used as is. Quotations are required to block the\n   evaluation.\n\n   Normal single-quotes are used to quote a cstring:\n   a => 'a'\n   \" => '\"'\n\n   If a single-quote is included in the cstring, use double quotes for quoting it.\n   ' => ''\"'\"''\n*/\nstatic void appendCstringWithQuotes (vString *dest, const char* cstr)\n{\n#ifdef _WIN32\n\tvStringCatS (dest, cstr);\n#else\n\tvStringPut (dest, '\\'');\n\tfor (const char *o = cstr; *o; o++)\n\t{\n\t\tif (*o == '\\'')\n\t\t\tvStringCatS (dest, \"'\\\"'\\\"'\");\n\t\telse\n\t\t\tvStringPut (dest, *o);\n\t}\n\tvStringPut (dest, '\\'');\n#endif\n}\n\nextern void externalSortTags (const bool toStdout, MIO *tagFile)\n{\n\tconst char *const sortNormalCommand = \"sort -u\";\n\tconst char *const sortFoldedCommand = \"sort -u -f\";\n\tconst char *sortCommand =\n\t\tOption.sorted == SO_FOLDSORTED ? sortFoldedCommand : sortNormalCommand;\n# ifndef HAVE_SETENV\n\tPE_CONST char *const sortOrder1 = \"LC_COLLATE=C\";\n\tPE_CONST char *const sortOrder2 = \"LC_ALL=C\";\n# endif\n\tint ret = -1;\n\tint system_errno = 0;\n\n\tvString *cmd = vStringNew ();\n\t{\n\n\t\t/*  Ensure ASCII value sort order.\n\t\t */\n#if defined (HAVE_SETENV) || defined (HAVE_PUTENV)\n# ifdef HAVE_SETENV\n\t\tsetenv (\"LC_COLLATE\", \"C\", 1);\n\t\tsetenv (\"LC_ALL\", \"C\", 1);\n# else\n\t\tputenv (sortOrder1);\n\t\tputenv (sortOrder2);\n# endif\n#else\n\t\tvStringCatS (cmd, sortOrder1);\n\t\tvStringPut (cmd, ' ');\n\t\tvStringCatS (cmd, sortOrder2);\n\t\tvStringPut (cmd, ' ');\n#endif\n\t\tvStringCatS (cmd, sortCommand);\n\t\tif (! toStdout)\n\t\t{\n\t\t\tvStringCatS (cmd, \" -o \");\n\t\t\tappendCstringWithQuotes (cmd, tagFileName ());\n\t\t\tvStringPut (cmd, ' ');\n\t\t\tappendCstringWithQuotes (cmd, tagFileName ());\n\t\t}\n\t\tverbose (\"system (\\\"%s\\\")\\n\", vStringValue (cmd));\n\t\tif (toStdout)\n\t\t{\n\t\t\tconst int fdstdin = 0;\n\t\t\tint fdsave;\n\n\t\t\tfdsave = dup (fdstdin);\n\t\t\tif (fdsave < 0)\n\t\t\t\terror (FATAL | PERROR, \"cannot save stdin fd\");\n\t\t\tif (dup2 (fileno (mio_file_get_fp (tagFile)), fdstdin) < 0)\n\t\t\t\terror (FATAL | PERROR, \"cannot redirect stdin\");\n\t\t\tif (lseek (fdstdin, 0, SEEK_SET) != 0)\n\t\t\t\terror (FATAL | PERROR, \"cannot rewind tag file\");\n\t\t\tret = system (vStringValue (cmd));\n\t\t\tsystem_errno = errno;\n\t\t\tif (dup2 (fdsave, fdstdin) < 0)\n\t\t\t\terror (FATAL | PERROR, \"cannot restore stdin fd\");\n\t\t\tclose (fdsave);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tret = system (vStringValue (cmd));\n\t\t\tsystem_errno = errno;\n\t\t}\n\t}\n\tif (ret != 0)\n\t{\n\t\terrorSelection selection = FATAL;\n\t\tif (ret == -1)\n\t\t{\n\t\t\terrno = system_errno;\n\t\t\terror (selection|PERROR, \"cannot sort tag file\");\n\t\t}\n\n#ifdef HAVE_STRSIGNAL\n\t\terror (selection, \"cannot sort tag file: system (\\\"%s\\\") exited with %d (%s?)\",\n\t\t\t   vStringValue(cmd), ret, strsignal(ret));\n#else\n\t\terror (selection, \"cannot sort tag file: system (\\\"%s\\\") exited with %d\",\n\t\t\t   vStringValue(cmd), ret);\n#endif\n\n\t}\n\tvStringDelete (cmd);\n}\n\n#else\n\n/*\n *  These functions provide a basic internal sort. No great memory\n *  optimization is performed (e.g. recursive subdivided sorts),\n *  so have lots of memory if you have large tag files.\n */\n\nextern void failedSort (MIO *const mio, const char* msg)\n{\n\tconst char* const cannotSort = \"cannot sort tag file\";\n\tif (mio != NULL)\n\t\tmio_unref (mio);\n\tif (msg == NULL)\n\t\terror (FATAL | PERROR, \"%s\", cannotSort);\n\telse\n\t\terror (FATAL, \"%s: %s\", msg, cannotSort);\n}\n\nstatic int compareTagsFolded(const void *const one, const void *const two)\n{\n\tconst char *const line1 = *(const char* const*) one;\n\tconst char *const line2 = *(const char* const*) two;\n\n\treturn struppercmp (line1, line2);\n}\n\nstatic int compareTags (const void *const one, const void *const two)\n{\n\tconst char *const line1 = *(const char* const*) one;\n\tconst char *const line2 = *(const char* const*) two;\n\n\treturn strcmp (line1, line2);\n}\n\nstatic void writeSortedTags (\n\t\tchar **const table, const size_t numTags, const bool toStdout, bool newlineReplaced)\n{\n\tMIO *mio;\n\tsize_t i;\n\n\t/*  Write the sorted lines back into the tag file.\n\t */\n\tif (toStdout)\n\t\tmio = mio_new_fp (stdout, NULL);\n\telse\n\t{\n\t\tmio = mio_new_file (tagFileName (), \"w\");\n\t\tif (mio == NULL)\n\t\t\tfailedSort (mio, NULL);\n\t}\n\tfor (i = 0 ; i < numTags ; ++i)\n\t{\n\t\t/*  Here we filter out identical tag *lines* (including search\n\t\t *  pattern) if this is not an xref file.\n\t\t */\n\t\tif (i == 0  ||  Option.xref  ||  strcmp (table [i], table [i-1]) != 0)\n\t\t{\n\t\t\tif (mio_puts (mio, table [i]) == EOF)\n\t\t\t\tfailedSort (mio, NULL);\n\t\t\telse if (newlineReplaced)\n\t\t\t\tmio_putc (mio, '\\n');\n\t\t}\n\t}\n\tif (toStdout)\n\t\tmio_flush (mio);\n\tmio_unref (mio);\n}\n\nextern void internalSortTags (const bool toStdout, MIO* mio, size_t numTags)\n{\n\tvString *vLine = vStringNew ();\n\tconst char *line;\n\tsize_t i;\n\tint (*cmpFunc)(const void *, const void *);\n\tbool newlineReplaced = false;\n\n\t/*  Allocate a table of line pointers to be sorted.\n\t */\n\tconst size_t tableSize = numTags * sizeof (char *);\n\tchar **table = (char **) malloc (tableSize);  /* line pointers */\n\tDebugStatement ( size_t mallocSize = tableSize; )  /* cumulative total */\n\n\n\tcmpFunc = Option.sorted == SO_FOLDSORTED ? compareTagsFolded : compareTags;\n\tif (table == NULL)\n\t\tfailedSort (mio, \"out of memory\");\n\n\tfor (i = 0  ;  i < numTags  &&  ! mio_eof (mio)  ;  )\n\t{\n\t\tline = readLineRaw (vLine, mio);\n\t\tif (line == NULL)\n\t\t{\n\t\t\tif (! mio_eof (mio))\n\t\t\t\tfailedSort (mio, NULL);\n\t\t\tbreak;\n\t\t}\n\t\telse if (*line == '\\0'  ||  strcmp (line, \"\\n\") == 0)\n\t\t\t;  /* ignore blank lines */\n\t\telse\n\t\t{\n\t\t\tconst size_t stringSize = strlen (line) + 1;\n\n\t\t\ttable [i] = (char *) malloc (stringSize);\n\t\t\tif (table [i] == NULL)\n\t\t\t\tfailedSort (mio, \"out of memory\");\n\t\t\tDebugStatement ( mallocSize += stringSize; )\n\t\t\tstrcpy (table [i], line);\n\t\t\tif (table[i][stringSize - 2] == '\\n')\n\t\t\t{\n\t\t\t\ttable[i][stringSize - 2] = '\\0';\n\t\t\t\tnewlineReplaced = true;\n\t\t\t}\n\t\t\t++i;\n\t\t}\n\t}\n\tnumTags = i;\n\tvStringDelete (vLine);\n\n\t/*  Sort the lines.\n\t */\n\tqsort (table, numTags, sizeof (*table), cmpFunc);\n\n\twriteSortedTags (table, numTags, toStdout, newlineReplaced);\n\n\tPrintStatus ((\"sort memory: %ld bytes\\n\", (long) mallocSize));\n\tfor (i = 0 ; i < numTags ; ++i)\n\t\tfree (table [i]);\n\tfree (table);\n}\n\n#endif\n"
  },
  {
    "path": "main/sort_p.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to sort.c\n*/\n#ifndef CTAGS_MAIN_SORT_H\n#define CTAGS_MAIN_SORT_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <stdio.h>\n\n#include \"mio.h\"\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void catFile (MIO *mio);\n\n#ifdef EXTERNAL_SORT\nextern void externalSortTags (const bool toStdout, MIO *tagFile);\n#else\nextern void internalSortTags (const bool toStdout,\n\t\t\t      MIO *mio,\n\t\t\t      size_t numTags);\n#endif\n\n/* mio is closed in this function. */\nextern void failedSort (MIO *const mio, const char* msg);\n\n#endif  /* CTAGS_MAIN_SORT_H */\n"
  },
  {
    "path": "main/sort_r.h",
    "content": "/* Taken from\n * https://raw.githubusercontent.com/noporpoise/sort_r/refs/heads/master/sort_r.h\n * 1275373d990162f7d142de2fcaf43b535061466c */\n/* Isaac Turner 29 April 2014 Public Domain */\n#ifndef SORT_R_H_\n#define SORT_R_H_\n\n#include <stdlib.h> /* qsort_r(), qsort_s() */\n#include <string.h> /* needed for memcpy() */\n\n/*\n\nsort_r function to be exported.\n\nParameters:\n  base is the array to be sorted\n  nel is the number of elements in the array\n  width is the size in bytes of each element of the array\n  compar is the comparison function\n  arg is a pointer to be passed to the comparison function\n\nvoid sort_r(void *base, size_t nel, size_t width,\n            int (*compar)(const void *_a, const void *_b, void *_arg),\n            void *arg);\n\n*/\n\n#define _SORT_R_INLINE inline\n\n#if (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || \\\n     (defined __FreeBSD__ && !defined(qsort_r)) || defined __DragonFly__)\n#  define _SORT_R_BSD\n#elif (defined __GLIBC__ || (defined (__FreeBSD__) && defined(qsort_r)))\n#  define _SORT_R_LINUX\n#elif (defined _WIN32 || defined _WIN64 || defined __WINDOWS__ || \\\n       defined __MINGW32__ || defined __MINGW64__)\n#  define _SORT_R_WINDOWS\n#  undef _SORT_R_INLINE\n#  define _SORT_R_INLINE __inline\n#else\n  /* Using our own recursive quicksort sort_r_simple() */\n#endif\n\n#if (defined NESTED_QSORT && NESTED_QSORT == 0)\n#  undef NESTED_QSORT\n#endif\n\n#define SORT_R_SWAP(a,b,tmp) ((tmp) = (a), (a) = (b), (b) = (tmp))\n\n/* swap a and b */\n/* a and b must not be equal! */\nstatic _SORT_R_INLINE void sort_r_swap(char *__restrict a, char *__restrict b,\n                                       size_t w)\n{\n  char tmp, *end = a+w;\n  for(; a < end; a++, b++) { SORT_R_SWAP(*a, *b, tmp); }\n}\n\n/* swap a, b iff a>b */\n/* a and b must not be equal! */\n/* __restrict is same as restrict but better support on old machines */\nstatic _SORT_R_INLINE int sort_r_cmpswap(char *__restrict a,\n                                         char *__restrict b, size_t w,\n                                         int (*compar)(const void *_a,\n                                                       const void *_b,\n                                                       void *_arg),\n                                         void *arg)\n{\n  if(compar(a, b, arg) > 0) {\n    sort_r_swap(a, b, w);\n    return 1;\n  }\n  return 0;\n}\n\n/*\nSwap consecutive blocks of bytes of size na and nb starting at memory addr ptr,\nwith the smallest swap so that the blocks are in the opposite order. Blocks may\nbe internally re-ordered e.g.\n\n  12345ab  ->   ab34512\n  123abc   ->   abc123\n  12abcde  ->   deabc12\n*/\nstatic _SORT_R_INLINE void sort_r_swap_blocks(char *ptr, size_t na, size_t nb)\n{\n  if(na > 0 && nb > 0) {\n    if(na > nb) { sort_r_swap(ptr, ptr+na, nb); }\n    else { sort_r_swap(ptr, ptr+nb, na); }\n  }\n}\n\n/* Implement recursive quicksort ourselves */\n/* Note: quicksort is not stable, equivalent values may be swapped */\nstatic _SORT_R_INLINE void sort_r_simple(void *base, size_t nel, size_t w,\n                                         int (*compar)(const void *_a,\n                                                       const void *_b,\n                                                       void *_arg),\n                                         void *arg)\n{\n  char *b = (char *)base, *end = b + nel*w;\n\n  /* for(size_t i=0; i<nel; i++) {printf(\"%4i\", *(int*)(b + i*sizeof(int)));}\n  printf(\"\\n\"); */\n\n  if(nel < 10) {\n    /* Insertion sort for arbitrarily small inputs */\n    char *pi, *pj;\n    for(pi = b+w; pi < end; pi += w) {\n      for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,arg); pj -= w) {}\n    }\n  }\n  else\n  {\n    /* nel > 6; Quicksort */\n\n    int cmp;\n    char *pl, *ple, *pr, *pre, *pivot;\n    char *last = b+w*(nel-1), *tmp;\n\n    /*\n    Use median of second, middle and second-last items as pivot.\n    First and last may have been swapped with pivot and therefore be extreme\n    */\n    char *l[3];\n    l[0] = b + w;\n    l[1] = b+w*(nel/2);\n    l[2] = last - w;\n\n    /* printf(\"pivots: %i, %i, %i\\n\", *(int*)l[0], *(int*)l[1], *(int*)l[2]); */\n\n    if(compar(l[0],l[1],arg) > 0) { SORT_R_SWAP(l[0], l[1], tmp); }\n    if(compar(l[1],l[2],arg) > 0) {\n      SORT_R_SWAP(l[1], l[2], tmp);\n      if(compar(l[0],l[1],arg) > 0) { SORT_R_SWAP(l[0], l[1], tmp); }\n    }\n\n    /* swap mid value (l[1]), and last element to put pivot as last element */\n    if(l[1] != last) { sort_r_swap(l[1], last, w); }\n\n    /*\n    pl is the next item on the left to be compared to the pivot\n    pr is the last item on the right that was compared to the pivot\n    ple is the left position to put the next item that equals the pivot\n    ple is the last right position where we put an item that equals the pivot\n\n                                           v- end (beyond the array)\n      EEEEEELLLLLLLLuuuuuuuuGGGGGGGEEEEEEEE.\n      ^- b  ^- ple  ^- pl   ^- pr  ^- pre ^- last (where the pivot is)\n\n    Pivot comparison key:\n      E = equal, L = less than, u = unknown, G = greater than, E = equal\n    */\n    pivot = last;\n    ple = pl = b;\n    pre = pr = last;\n\n    /*\n    Strategy:\n    Loop into the list from the left and right at the same time to find:\n    - an item on the left that is greater than the pivot\n    - an item on the right that is less than the pivot\n    Once found, they are swapped and the loop continues.\n    Meanwhile items that are equal to the pivot are moved to the edges of the\n    array.\n    */\n    while(pl < pr) {\n      /* Move left hand items which are equal to the pivot to the far left.\n         break when we find an item that is greater than the pivot */\n      for(; pl < pr; pl += w) {\n        cmp = compar(pl, pivot, arg);\n        if(cmp > 0) { break; }\n        else if(cmp == 0) {\n          if(ple < pl) { sort_r_swap(ple, pl, w); }\n          ple += w;\n        }\n      }\n      /* break if last batch of left hand items were equal to pivot */\n      if(pl >= pr) { break; }\n      /* Move right hand items which are equal to the pivot to the far right.\n         break when we find an item that is less than the pivot */\n      for(; pl < pr; ) {\n        pr -= w; /* Move right pointer onto an unprocessed item */\n        cmp = compar(pr, pivot, arg);\n        if(cmp == 0) {\n          pre -= w;\n          if(pr < pre) { sort_r_swap(pr, pre, w); }\n        }\n        else if(cmp < 0) {\n          if(pl < pr) { sort_r_swap(pl, pr, w); }\n          pl += w;\n          break;\n        }\n      }\n    }\n\n    pl = pr; /* pr may have gone below pl */\n\n    /*\n    Now we need to go from: EEELLLGGGGEEEE\n                        to: LLLEEEEEEEGGGG\n\n    Pivot comparison key:\n      E = equal, L = less than, u = unknown, G = greater than, E = equal\n    */\n    sort_r_swap_blocks(b, ple-b, pl-ple);\n    sort_r_swap_blocks(pr, pre-pr, end-pre);\n\n    /*for(size_t i=0; i<nel; i++) {printf(\"%4i\", *(int*)(b + i*sizeof(int)));}\n    printf(\"\\n\");*/\n\n    sort_r_simple(b, (pl-ple)/w, w, compar, arg);\n    sort_r_simple(end-(pre-pr), (pre-pr)/w, w, compar, arg);\n  }\n}\n\n\n#if defined NESTED_QSORT\n\n  static _SORT_R_INLINE void sort_r(void *base, size_t nel, size_t width,\n                                    int (*compar)(const void *_a,\n                                                  const void *_b,\n                                                  void *aarg),\n                                    void *arg)\n  {\n    int nested_cmp(const void *a, const void *b)\n    {\n      return compar(a, b, arg);\n    }\n\n    qsort(base, nel, width, nested_cmp);\n  }\n\n#else /* !NESTED_QSORT */\n\n  /* Declare structs and functions */\n\n  #if defined _SORT_R_BSD\n\n    /* Ensure qsort_r is defined */\n    extern void qsort_r(void *base, size_t nel, size_t width, void *thunk,\n                        int (*compar)(void *_thunk,\n                                      const void *_a, const void *_b));\n\n  #endif\n\n  #if defined _SORT_R_BSD || defined _SORT_R_WINDOWS\n\n    /* BSD (qsort_r), Windows (qsort_s) require argument swap */\n\n    struct sort_r_data\n    {\n      void *arg;\n      int (*compar)(const void *_a, const void *_b, void *_arg);\n    };\n\n    static _SORT_R_INLINE int sort_r_arg_swap(void *s,\n                                              const void *a, const void *b)\n    {\n      struct sort_r_data *ss = (struct sort_r_data*)s;\n      return (ss->compar)(a, b, ss->arg);\n    }\n\n  #endif\n\n  #if defined _SORT_R_LINUX\n\n    typedef int(* __compar_d_fn_t)(const void *, const void *, void *);\n    extern void (qsort_r)(void *base, size_t nel, size_t width,\n                          __compar_d_fn_t __compar, void *arg)\n      __attribute__((nonnull (1, 4)));\n\n  #endif\n\n  /* implementation */\n\n  static _SORT_R_INLINE void sort_r(void *base, size_t nel, size_t width,\n                                    int (*compar)(const void *_a,\n                                                  const void *_b, void *_arg),\n                                    void *arg)\n  {\n    #if defined _SORT_R_LINUX\n\n      #if defined __GLIBC__ && ((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 8))\n\n        /* no qsort_r in glibc before 2.8, need to use nested qsort */\n        sort_r_simple(base, nel, width, compar, arg);\n\n      #else\n\n        qsort_r(base, nel, width, compar, arg);\n\n      #endif\n\n    #elif defined _SORT_R_BSD\n\n      struct sort_r_data tmp;\n      tmp.arg = arg;\n      tmp.compar = compar;\n      qsort_r(base, nel, width, &tmp, sort_r_arg_swap);\n\n    #elif defined _SORT_R_WINDOWS\n\n      struct sort_r_data tmp;\n      tmp.arg = arg;\n      tmp.compar = compar;\n      qsort_s(base, nel, width, sort_r_arg_swap, &tmp);\n\n    #else\n\n      /* Fall back to our own quicksort implementation */\n      sort_r_simple(base, nel, width, compar, arg);\n\n    #endif\n  }\n\n#endif /* !NESTED_QSORT */\n\n#undef _SORT_R_INLINE\n#undef _SORT_R_WINDOWS\n#undef _SORT_R_LINUX\n#undef _SORT_R_BSD\n\n#endif /* SORT_R_H_ */\n"
  },
  {
    "path": "main/stats.c",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   Author: Darren Hiebert <dhiebert@users.sourceforge.net>\n*           http://ctags.sourceforge.net\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*   It is provided on an as-is basis and no responsibility is accepted for its\n*   failure to perform as expected.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <stdio.h>\n\n#include \"entry_p.h\"\n#include \"options_p.h\"\n#include \"stats_p.h\"\n\n/*\n*   MACROS\n*/\n#define plural(value)  (((unsigned long)(value) == 1L) ? \"\" : \"s\")\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic struct { long files, lines, bytes; } Totals = { 0, 0, 0 };\n\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nextern void addTotals (\n\t\tconst unsigned int files, const long unsigned int lines,\n\t\tconst long unsigned int bytes)\n{\n\tTotals.files += files;\n\tTotals.lines += lines;\n\tTotals.bytes += bytes;\n}\n\nextern void printTotals (const clock_t *const timeStamps, bool append, sortType sorted)\n{\n\tconst unsigned long totalTags = numTagsTotal();\n\tconst unsigned long addedTags = numTagsAdded();\n\n\tfprintf (stderr, \"%ld file%s, %ld line%s (%ld kB) scanned\",\n\t\t\tTotals.files, plural (Totals.files),\n\t\t\tTotals.lines, plural (Totals.lines),\n\t\t\tTotals.bytes/1024L);\n\n\tconst double interval = ((double) (timeStamps [1] - timeStamps [0])) /\n\t\t\t\t\t\t\tCLOCKS_PER_SEC;\n\n\tfprintf (stderr, \" in %.01f seconds\", interval);\n\tif (interval != (double) 0.0)\n\t\tfprintf (stderr, \" (%lu kB/s)\",\n\t\t\t\t(unsigned long) (Totals.bytes / interval) / 1024L);\n\n\tfputc ('\\n', stderr);\n\n\tfprintf (stderr, \"%lu tag%s added to tag file\",\n\t\t\taddedTags, plural(addedTags));\n\tif (append)\n\t\tfprintf (stderr, \" (now %lu tags)\", totalTags);\n\tfputc ('\\n', stderr);\n\n\tif (totalTags > 0  &&  sorted != SO_UNSORTED)\n\t{\n\t\tfprintf (stderr, \"%lu tag%s sorted\", totalTags, plural (totalTags));\n\t\tfprintf (stderr, \" in %.02f seconds\",\n\t\t\t\t((double) (timeStamps [2] - timeStamps [1])) / CLOCKS_PER_SEC);\n\t\tfputc ('\\n', stderr);\n\t}\n\n#ifdef DEBUG\n\tfprintf (stderr, \"longest tag line = %lu\\n\",\n\t\t (unsigned long) maxTagsLine ());\n#endif\n}\n"
  },
  {
    "path": "main/stats_p.h",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   Author: Darren Hiebert <dhiebert@users.sourceforge.net>\n*           http://ctags.sourceforge.net\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*   It is provided on an as-is basis and no responsibility is accepted for its\n*   failure to perform as expected.\n*/\n\n#ifndef CTAGS_MAIN_STATS_PRIVATE_H\n#define CTAGS_MAIN_STATS_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"options_p.h\"\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void addTotals (const unsigned int files, const long unsigned int lines, const long unsigned int bytes);\nextern void printTotals (const clock_t *const timeStamps, bool append, sortType sorted);\n\n#endif  /* CTAGS_MAIN_STATS_PRIVATE_H */\n"
  },
  {
    "path": "main/strlist.c",
    "content": "/*\n*   Copyright (c) 1999-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions managing resizable string lists.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <fnmatch.h>\n\n#include \"debug.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"strlist.h\"\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nextern stringList *stringListNew (void)\n{\n\treturn ptrArrayNew ((ptrArrayDeleteFunc)vStringDelete);\n}\n\nextern void stringListAdd (stringList *const current, vString *string)\n{\n\tptrArrayAdd (current, string);\n}\n\nextern void stringListRemoveLast (stringList *const current)\n{\n\tptrArrayRemoveLast (current);\n}\n\n/* Combine list `from' into `current', deleting `from' */\nextern void stringListCombine (\n\t\tstringList *const current, stringList *const from)\n{\n\tptrArrayCombine (current, from);\n}\n\nextern stringList* stringListNewFromArgv (const char* const* const argv)\n{\n\tstringList* const result = stringListNew ();\n\tconst char *const *p;\n\tAssert (argv != NULL);\n\tfor (p = argv  ;  *p != NULL  ;  ++p)\n\t\tstringListAdd (result, vStringNewInit (*p));\n\treturn result;\n}\n\nextern stringList* stringListNewFromFile (const char* const fileName)\n{\n\tstringList* result = NULL;\n\tMIO* const mio = mio_new_file (fileName, \"r\");\n\tif (mio != NULL)\n\t{\n\t\tresult = stringListNew ();\n\t\twhile (! mio_eof (mio))\n\t\t{\n\t\t\tvString* const str = vStringNew ();\n\t\t\treadLineRaw (str, mio);\n\t\t\tvStringStripTrailing (str);\n\t\t\tif (vStringLength (str) > 0)\n\t\t\t\tstringListAdd (result, str);\n\t\t\telse\n\t\t\t\tvStringDelete (str);\n\t\t}\n\t\tmio_unref (mio);\n\t}\n\treturn result;\n}\n\nextern unsigned int stringListCount (const stringList *const current)\n{\n\treturn ptrArrayCount (current);\n}\n\nextern vString* stringListItem (\n\t\tconst stringList *const current, const unsigned int indx)\n{\n\treturn ptrArrayItem (current, indx);\n}\n\nextern vString* stringListLast (const stringList *const current)\n{\n\treturn ptrArrayLast (current);\n}\n\nextern void stringListClear (stringList *const current)\n{\n\tptrArrayClear (current);\n}\n\nextern void stringListDelete (stringList *const current)\n{\n\tptrArrayDelete (current);\n}\n\nstatic bool compareString (\n\t\tconst char *const string, vString *const itm)\n{\n\treturn (strcmp (string, vStringValue (itm)) == 0);\n}\n\nstatic bool compareStringInsensitive (\n\t\tconst char *const string, vString *const itm)\n{\n\treturn (strcasecmp (string, vStringValue (itm)) == 0);\n}\n\nstatic int stringListIndex (\n\t\tconst stringList *const current,\n\t\tconst char *const string,\n\t\tbool (*test)(const char *s, vString *const vs))\n{\n\tint result = -1;\n\tunsigned int i;\n\tAssert (current != NULL);\n\tAssert (string != NULL);\n\tAssert (test != NULL);\n\tfor (i = 0  ;  result == -1  &&  i < ptrArrayCount (current)  ;  ++i)\n\t\tif ((*test)(string, ptrArrayItem (current, i)))\n\t\t\tresult = i;\n\treturn result;\n}\n\nextern bool stringListHas (\n\t\tconst stringList *const current, const char *const string)\n{\n\tbool result;\n\tAssert (current != NULL);\n\tresult = stringListIndex (current, string, compareString) != -1;\n\treturn result;\n}\n\nstatic vString* stringListFinds (\n\t\tconst stringList *const current, const char *const string,\n\t\tbool (*test)(const char *s, vString *const vs))\n{\n\tint i;\n\n\tAssert (current != NULL);\n\tAssert (string != NULL);\n\n\ti = stringListIndex (current, string, test);\n\tif (i == -1)\n\t\treturn NULL;\n\telse\n\t\treturn stringListItem(current, i);\n}\n\nextern bool stringListHasInsensitive (\n\t\tconst stringList *const current, const char *const string)\n{\n\tbool result;\n\tAssert (current != NULL);\n\tAssert (string != NULL);\n\tresult = stringListIndex (current, string, compareStringInsensitive) != -1;\n\treturn result;\n}\n\nextern bool stringListHasTest (const stringList *const current,\n\t\t\t\t  bool (*test)(const char *s, void *userData),\n\t\t\t\t  void *userData)\n{\n\tbool result = false;\n\tunsigned int i;\n\tAssert (current != NULL);\n\tfor (i = 0  ;  ! result  &&  i < ptrArrayCount (current)  ;  ++i)\n\t\tresult = (*test)(vStringValue ((vString *)ptrArrayItem (current, i)), userData);\n\treturn result;\n}\n\nextern bool stringListDeleteItemExtension (stringList* const current, const char* const extension)\n{\n\tint where;\n#ifdef CASE_INSENSITIVE_FILENAMES\n\twhere = stringListIndex (current, extension, compareStringInsensitive);\n#else\n\twhere = stringListIndex (current, extension, compareString);\n#endif\n\tif (where != -1)\n\t\tptrArrayDeleteItem (current, where);\n\treturn where != -1;\n}\n\nextern bool stringListExtensionMatched (\n\t\tconst stringList* const current, const char* const extension)\n{\n#ifdef CASE_INSENSITIVE_FILENAMES\n\treturn stringListHasInsensitive (current, extension);\n#else\n\treturn stringListHas (current, extension);\n#endif\n}\n\nextern vString* stringListExtensionFinds (\n\t\tconst stringList* const current, const char* const extension)\n{\n#ifdef CASE_INSENSITIVE_FILENAMES\n\treturn stringListFinds (current, extension, compareStringInsensitive);\n#else\n\treturn stringListFinds (current, extension, compareString);\n#endif\n}\n\nextern bool stringListCaseMatched (const stringList* const list, const char* const str)\n{\n\treturn stringListCaseFinds(list, str)? true: false;\n}\n\nextern vString* stringListCaseFinds (const stringList* const list, const char* const str)\n{\n\treturn stringListFinds (list, str, compareStringInsensitive);\n}\n\nstatic bool fileNameMatched (\n\t\tconst vString* const vpattern, const char* const fileName)\n{\n\tconst char* const pattern = vStringValue (vpattern);\n\n#ifdef CASE_INSENSITIVE_FILENAMES\n\t{\n\t\tchar* const p = newUpperString (pattern);\n\t\tchar* const f = newUpperString (fileName);\n\t\tbool r = (fnmatch (p, f, 0) == 0);\n\t\teFree (f);\n\t\teFree (p);\n\t\treturn r;\n\t}\n#else\n\treturn (fnmatch (pattern, fileName, 0) == 0);\n#endif\n}\n\nextern bool stringListFileMatched (\n\t\t\tconst stringList* const current, const char* const fileName)\n{\n\treturn stringListFileFinds (current, fileName)? true: false;\n}\n\nextern vString* stringListFileFinds (\n\t\tconst stringList* const current, const char* const fileName)\n{\n\tvString* vstr = NULL;\n\tbool matched = false;\n\tunsigned int i;\n\tconst char * normalized = fileName;\n\n#if defined (_WIN32)\n\tvString *tmp = vStringNewInit (fileName);\n\tvStringTranslate (tmp, PATH_SEPARATOR, OUTPUT_PATH_SEPARATOR);\n\tnormalized = vStringValue (tmp);\n#endif\n\n\tfor (i = 0  ;  ! matched  &&  i < stringListCount (current)  ;  ++i)\n\t{\n\t\tvstr = stringListItem (current, i);\n\t\tmatched = fileNameMatched (vstr, normalized);\n\t}\n\n#if defined (_WIN32)\n\tvStringDelete (tmp);\n#endif\n\n\treturn matched? vstr: NULL;\n}\n\nextern void stringListPrint (const stringList *const current, FILE *fp)\n{\n\tunsigned int i;\n\tAssert (current != NULL);\n\tfor (i = 0  ;  i < ptrArrayCount (current)  ;  ++i)\n\t\tfprintf (fp, \"%s%s\", (i > 0) ? \", \" : \"\", vStringValue ((vString *)ptrArrayItem (current, i)));\n}\n\nextern void stringListReverse (const stringList *const current)\n{\n\tptrArrayReverse (current);\n}\n"
  },
  {
    "path": "main/strlist.h",
    "content": "/*\n*   Copyright (c) 1999-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines external interface to resizable string lists.\n*/\n#ifndef CTAGS_MAIN_STRLIST_H\n#define CTAGS_MAIN_STRLIST_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"routines_p.h\"\n#include \"vstring.h\"\n#include \"ptrarray.h\"\n\n#include <stdio.h>\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef ptrArray stringList;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern stringList *stringListNew (void);\nextern void stringListAdd (stringList *const current, vString *string);\nextern void stringListRemoveLast (stringList *const current);\nextern void stringListCombine (stringList *const current, stringList *const from);\nextern stringList* stringListNewFromArgv (const char* const* const list);\nextern stringList* stringListNewFromFile (const char* const fileName);\nextern void stringListClear (stringList *const current);\nextern unsigned int stringListCount (const stringList *const current);\nextern vString* stringListItem (const stringList *const current, const unsigned int indx);\nextern vString* stringListLast (const stringList *const current);\nextern void stringListDelete (stringList *const current);\nextern bool stringListHasInsensitive (const stringList *const current, const char *const string);\nextern bool stringListHas (const stringList *const current, const char *const string);\nextern bool stringListHasTest (const stringList *const current,\n\t\t\t\t  bool (*test)(const char *s, void *userData),\n\t\t\t\t  void *userData);\nextern bool stringListDeleteItemExtension (stringList* const current, const char* const extension);\n\n/*\n * stringListExtension{Matched,Finds}\n * They compares strcmp or strcasecmp.\n * The choice of case-sensitive or case-insensitive is platform-dependent.\n *\n * stringListFile{Matched,Finds}:\n * They do glob-matching with fnmatch().\n * The choice of case-sensitive or case-insensitive is platform-dependent.\n *\n * stringListCase{Matched,Finds}:\n * They always work case-insensitive way.\n */\nextern bool stringListExtensionMatched (const stringList* const list, const char* const extension);\nextern vString* stringListExtensionFinds (const stringList* const list, const char* const extension);\nextern bool stringListFileMatched (const stringList* const list, const char* const str);\nextern vString* stringListFileFinds (const stringList* const list, const char* const str);\nextern bool stringListCaseMatched (const stringList* const list, const char* const str);\nextern vString* stringListCaseFinds (const stringList* const list, const char* const str);\n\nextern void stringListPrint (const stringList *const current, FILE *fp);\nextern void stringListReverse (const stringList *const current);\n\n#endif  /* CTAGS_MAIN_STRLIST_H */\n"
  },
  {
    "path": "main/subparser.h",
    "content": "/*\n *\n *  Copyright (c) 2017, Red Hat, Inc.\n *  Copyright (c) 2017, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_SUBPARSER_H\n#define CTAGS_MAIN_SUBPARSER_H\n\n#include \"general.h\"\n\n#include \"dependency.h\"\n#include \"types.h\"\n\n/*\n*   MACROS\n*/\n#define foreachSubparser(VAR, INCLUDING_NONE_CRAFTED_PARSER)\\\n\tVAR = NULL;\t\t\t\t\t\t\t\t\\\n\twhile ((VAR = getNextSubparser (VAR, INCLUDING_NONE_CRAFTED_PARSER)) != NULL)\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef enum eSubparserRunDirection {\n\tSUBPARSER_UNKNOWN_DIRECTION =  0,\n\tSUBPARSER_BASE_RUNS_SUB = 1 << 0,\n\tSUBPARSER_SUB_RUNS_BASE = 1 << 1,\n\tSUBPARSER_BI_DIRECTION  = SUBPARSER_BASE_RUNS_SUB|SUBPARSER_SUB_RUNS_BASE,\n} subparserRunDirection;\n\nstruct sSubparser {\n\t/* private in the main part */\n\tslaveParser *slaveParser;\n\tsubparser *next;\n\tbool schedulingBaseparserExplicitly;\n\tbool chosenAsExclusiveSubparser;\n\n\t/* public to the parser */\n\tsubparserRunDirection direction;\n\n\tvoid (* inputStart) (subparser *s);\n\tvoid (* inputEnd) (subparser *s);\n\tvoid (* exclusiveSubparserChosenNotify) (subparser *s, void *data);\n\tvoid (* makeTagEntryNotify) (subparser *s, const tagEntryInfo *tag, int corkIndex);\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\n/* Interface for Baseparser */\nextern subparser *getNextSubparser(subparser *last, bool includingNoneCraftedParser);\nextern void enterSubparser(subparser *subparser);\nextern void leaveSubparser(void);\nextern subparser* getSubparserRunningBaseparser (void);\nextern void chooseExclusiveSubparser (subparser *s, void *data);\n\nextern subparser *getLanguageSubparser (langType sublang, bool including_none_crafted_parser);\nextern langType getSubparserLanguage (subparser *s);\n\n/* Interface for Subparsers   */\n#define RUN_DEFAULT_SUBPARSERS -1\nextern void scheduleRunningBaseparser (int dependencyIndex);\n\n#endif\t/* CTAGS_MAIN_SUBPARSER_H */\n"
  },
  {
    "path": "main/subparser_p.h",
    "content": "/*\n *\n *  Copyright (c) 2017, Red Hat, Inc.\n *  Copyright (c) 2017, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_SUBPARSER_PRIVATE_H\n#define CTAGS_MAIN_SUBPARSER_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"colprint_p.h\"\n#include \"dependency_p.h\"\n#include \"types.h\"\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern subparser *getFirstSubparser(struct slaveControlBlock *controlBlock);\n\n/* A base parser doesn't have to call the following three functions.\n   The main part calls them internally. */\nextern void notifyInputStart (void);\nextern void notifyInputEnd   (void);\nextern void notifyMakeTagEntry (const tagEntryInfo *info, int corkIndex);\n\nextern void setupSubparsersInUse (struct slaveControlBlock *controlBlock);\nextern subparser* teardownSubparsersInUse (struct slaveControlBlock *controlBlock);\n\nextern struct colprintTable * subparserColprintTableNew (void);\nextern void subparserColprintAddSubparsers (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\t\t\tstruct slaveControlBlock *scb);\nextern void subparserColprintTablePrint (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\t\t bool withListHeader, bool machinable, FILE *fp);\n\nextern void useDefaultSubparsers (struct slaveControlBlock *controlBlock);\nextern void useSpecifiedSubparser (struct slaveControlBlock *controlBlock, subparser *s);\n\n#endif\t/* CTAGS_MAIN_SUBPARSER_PRIVATE_H */\n"
  },
  {
    "path": "main/tokeninfo.c",
    "content": "/*\n*   Copyright (c) 2016, Masatake YAMATO <yamato@redhat.com>\n*   Copyright (c) 2016, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Python language\n*   files.\n*/\n\n#include \"general.h\"\n#include \"tokeninfo.h\"\n\n#include \"entry.h\"\n#include \"read.h\"\n#include \"routines.h\"\n\nstatic void* createToken (void *createArg)\n{\n\tstruct tokenInfoClass *klass = createArg;\n\ttokenInfo *token;\n\n\ttoken = eCalloc (1, sizeof (*token) + klass->extraSpace);\n\ttoken->klass = klass;\n\ttoken->string  = vStringNew ();\n\n\treturn token;\n}\n\nstatic void clearToken (void *data)\n{\n\ttokenInfo *token = data;\n\n\tif (token->klass->clear)\n\t\ttoken->klass->clear (token);\n\n\ttoken->type = token->klass->typeForUndefined;\n\ttoken->keyword = token->klass->keywordNone;\n\tvStringClear (token->string);\n\ttoken->lineNumber = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n}\n\nstatic void deleteToken (void *data)\n{\n\ttokenInfo *token = data;\n\n\tif (token->klass->delete)\n\t\ttoken->klass->delete (token);\n\n\tvStringDelete (token->string);\n\teFree (token);\n}\n\nvoid *newToken (struct tokenInfoClass *klass)\n{\n\treturn newTokenFull (klass, NULL);\n}\n\nvoid *newTokenFull (struct tokenInfoClass *klass, void *data)\n{\n\ttokenInfo *token = NULL;\n\n\tif (klass->nPreAlloc == 0)\n\t\tklass->nPreAlloc = 16;\n\n retry:\n\tif (klass->pool)\n\t\ttoken = objPoolGet (klass->pool);\n\telse\n\t{\n\t\tklass->pool = objPoolNew (klass->nPreAlloc,\n\t\t\t\t\t  createToken,\n\t\t\t\t\t  deleteToken,\n\t\t\t\t\t  clearToken,\n\t\t\t\t\t  klass);\n\t\tgoto retry;\n\t}\n\n\tif (klass->init)\n\t\tklass->init (token, data);\n\treturn token;\n}\n\nvoid  flashTokenBacklog (struct tokenInfoClass *klass)\n{\n\tif (klass->backlog)\n\t\tptrArrayClear (klass->backlog);\n}\n\nvoid tokenDelete (tokenInfo *token)\n{\n\tif (token != NULL)\n\t\tobjPoolPut (token->klass->pool, token);\n}\n\n\nvoid tokenReadFull (tokenInfo *token, void *data)\n{\n\tif (!token->klass->backlog)\n\t\ttoken->klass->backlog = ptrArrayNew ((ptrArrayDeleteFunc)tokenDelete);\n\n\tif (ptrArrayCount (token->klass->backlog) > 0)\n\t{\n\t\ttokenInfo *backlog = ptrArrayLast (token->klass->backlog);\n\t\ttokenCopyFull (token, backlog, data);\n\t\tptrArrayRemoveLast (token->klass->backlog);\n\t\ttokenDelete (backlog);\n\t}\n\telse\n\t{\n\t\ttoken->klass->read (token, data);\n\t\tif (!tokenIsEOF (token))\n\t\t\ttoken->klass->read_counter++;\n\t}\n}\n\nvoid tokenRead (tokenInfo *token)\n{\n\ttokenReadFull (token, NULL);\n}\n\nvoid tokenCopyFull  (tokenInfo *dest, tokenInfo *src, void *data)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tdest->keyword = src->keyword;\n\t/* klass */\n\tvStringCopy(dest->string, src->string);\n\tif (src->klass->copy)\n\t\tsrc->klass->copy (dest, src, data);\n}\n\nvoid tokenCopy      (tokenInfo *dest, tokenInfo *src)\n{\n\ttokenCopyFull (dest, src, NULL);\n}\n\nvoid *newTokenByCopying (tokenInfo *src)\n{\n\treturn newTokenByCopyingFull (src, NULL);\n}\n\nvoid *newTokenByCopyingFull (tokenInfo *src, void *data)\n{\n\tvoid * dest = newToken (src->klass);\n\ttokenCopyFull (dest, src, data);\n\treturn dest;\n}\n\nbool tokenSkipToTypeFull (tokenInfo *token, tokenType t, void *data)\n{\n\twhile (! (tokenIsEOF (token)\n\t\t\t  || token->type == t))\n\t\ttokenReadFull (token, data);\n\n\treturn (token->type == t)? true: false;\n}\n\nbool tokenSkipToType (tokenInfo *token, tokenType t)\n{\n\treturn tokenSkipToTypeFull (token, t, NULL);\n}\n\nvoid tokenUnreadFull (tokenInfo *token, void *data)\n{\n\ttokenInfo *backlog;\n\n\tif (!token->klass->backlog)\n\t\ttoken->klass->backlog = ptrArrayNew ((ptrArrayDeleteFunc)tokenDelete);\n\n\tbacklog = newToken (token->klass);\n\ttokenCopyFull (backlog, token, data);\n\tptrArrayAdd (token->klass->backlog, backlog);\n}\n\nvoid tokenUnread      (tokenInfo *token)\n{\n\ttokenUnreadFull (token, NULL);\n}\n\nstatic int tokenGetRightSideOfPair (tokenInfo *token)\n{\n\tint start = token->type;\n\tfor (unsigned i = 0; i < token->klass->pairCount; i++)\n\t\tif (start == token->klass->pairs[i].start)\n\t\t\treturn token->klass->pairs[i].end;\n\n\treturn token->klass->typeForUndefined;\n}\n\nstatic bool tokenTypeIsIn (tokenInfo *token, tokenType ts[], size_t count)\n{\n\ttokenType t = token->type;\n\n\tfor (size_t i = 0; i < count; i++)\n\t{\n\t\tif (t == ts[i])\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nbool tokenSkipToOneOfTypesImpl (tokenInfo *token, bool skipPair, tokenType ts[], size_t count)\n{\n\twhile (! tokenIsEOF (token))\n\t{\n\t\tif (tokenTypeIsIn (token, ts, count))\n\t\t\treturn true;\n\t\tif (skipPair &&\n\t\t\ttokenGetRightSideOfPair (token) != token->klass->typeForUndefined)\n\t\t\ttokenSkipOverPair (token);\n\t\telse\n\t\t\ttokenReadFull (token, NULL);\n\t}\n\n\treturn false;\n}\n\nbool tokenSkipOverPair (tokenInfo *token)\n{\n\treturn tokenSkipOverPairFull(token, NULL);\n}\n\nbool tokenSkipOverPairFull (tokenInfo *token, void *data)\n{\n\tint start = token->type;\n\tint end = token->klass->typeForUndefined;\n\n\tend = tokenGetRightSideOfPair (token);\n\n\tif (end == token->klass->typeForUndefined)\n\t\treturn false;\n\n\tint depth = 1;\n\tdo {\n\t\ttokenReadFull (token, data);\n\t\tif (token->type == start)\n\t\t\tdepth ++;\n\t\telse if (token->type == end)\n\t\t\tdepth--;\n\t} while ((!tokenIsEOF(token)) && (depth > 0));\n\n\treturn (depth == 0)? true: false;\n}\n\nvoid tokenInitTagEntry (tokenInfo *token, tagEntryInfo *e, int kind)\n{\n\tinitTagEntry (e, tokenString (token), kind);\n\te->lineNumber = token->lineNumber;\n\te->filePosition = token->filePosition;\n}\n\nvoid tokenInitRefTagEntry (tokenInfo *token, tagEntryInfo *e, int kind, int role)\n{\n\tinitRefTagEntry (e, tokenString (token), kind, role);\n\te->lineNumber = token->lineNumber;\n\te->filePosition = token->filePosition;\n}\n\nint tokenMakeSimpleTag (tokenInfo *token, int kind)\n{\n\ttagEntryInfo e;\n\n\ttokenInitTagEntry (token, &e, kind);\n\treturn makeTagEntry (&e);\n}\n\nint tokenMakeSimpleRefTag (tokenInfo *token, int kind, int role)\n{\n\ttagEntryInfo e;\n\ttokenInitRefTagEntry (token, &e, kind, role);\n\treturn makeTagEntry (&e);\n}\n"
  },
  {
    "path": "main/tokeninfo.h",
    "content": "/*\n*   Copyright (c) 2016, Masatake YAMATO <yamato@redhat.com>\n*   Copyright (c) 2016, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n\n#include \"general.h\"  /* must always come first */\n#include \"mio.h\"\n#include \"objpool.h\"\n#include \"vstring.h\"\n\n#ifndef CTAGS_MAIN_TOKEN_H\n#define CTAGS_MAIN_TOKEN_H\n\nstruct tokenClass;\nstruct tokenTypePair;\n\ntypedef short tokenType;\ntypedef short tokenKeyword;\n\ntypedef struct sTokenInfo {\n\ttokenType type;\n\ttokenKeyword keyword;\n\tvString *string;\n\tstruct tokenInfoClass *klass;\n\tunsigned long lineNumber;\n\tMIOPos filePosition;\n} tokenInfo;\n\nstruct tokenTypePair {\n\ttokenType start;\n\ttokenType end;\n};\n\n#define TOKEN(X)  ((tokenInfo *)X)\n\nstruct tokenInfoClass {\n\tunsigned int nPreAlloc;\n\ttokenType typeForUndefined;\n\ttokenKeyword keywordNone;\n\ttokenType typeForKeyword;\n\ttokenType typeForEOF;\n\tsize_t extraSpace;\n\tstruct tokenTypePair   *pairs;\n\tunsigned int        pairCount;\n\tvoid (*init)   (tokenInfo *token, void *data);\n\tvoid (*read)   (tokenInfo *token, void *data);\n\tvoid (*clear)  (tokenInfo *token);\n\tvoid (*delete) (tokenInfo *token);\n\tvoid (*copy)   (tokenInfo *dest, tokenInfo *src, void *data);\n\tobjPool *pool;\n\tptrArray *backlog;\n\n\t/* read_counter is incremented every time when reading a\n\t * new token from the input area unless the new token is EOF.\n\t *\n\t * When filling a tokenInfo from an entry in the backlog, we don't\n\t * regard it as \"reading a new token\".\n\t */\n\tint read_counter;\n};\n\nvoid *newToken       (struct tokenInfoClass *klass);\nvoid *newTokenFull   (struct tokenInfoClass *klass, void *data);\nvoid *newTokenByCopying (tokenInfo *src);\nvoid *newTokenByCopyingFull (tokenInfo *src, void *data);\n\nvoid  flashTokenBacklog (struct tokenInfoClass *klass);\nvoid  tokenDelete    (tokenInfo *token);\n\nvoid tokenReadFull   (tokenInfo *token, void *data);\nvoid tokenRead       (tokenInfo *token);\nvoid tokenUnreadFull (tokenInfo *token, void *data); /* DATA passed to copy method internally. */\nvoid tokenUnread     (tokenInfo *token);\n\n\nvoid tokenCopyFull   (tokenInfo *dest, tokenInfo *src, void *data);\nvoid tokenCopy       (tokenInfo *dest, tokenInfo *src);\n\n/* Helper macro & functions */\n\n#define tokenIsType(TKN,T)     ((TKN)->type == TOKEN_##T)\n#define tokenIsTypeVal(TKN,TV)   ((TKN)->type == (TV))\n#define tokenIsKeyword(TKN,K)  ((TKN)->type == TKN->klass->typeForKeyword \\\n\t\t\t\t\t\t\t\t\t&& (TKN)->keyword == KEYWORD_##K)\n#define tokenIsEOF(TKN)      ((TKN)->type == (TKN)->klass->typeForEOF)\n\n#define tokenString(TKN)       (vStringValue ((TKN)->string))\n#define tokenPutc(TKN,C)       (vStringPut ((TKN)->string, C))\n#define tokenCat(TKN,VS)       (vStringCat ((TKN)->string, VS))\n#define tokenCatS(TKN,S)       (vStringCatS ((TKN)->string, S))\n#define tokenLast(TKN)         (vStringIsEmpty((TKN)->string)? '\\0': vStringLast((TKN)->string))\n\n/* return true if t is found. In that case token holds an\n   language object type t.\n   return false if it reaches EOF. */\nbool tokenSkipToType (tokenInfo *token, tokenType t);\nbool tokenSkipToTypeFull (tokenInfo *token, tokenType t, void *data);\n\n#define tokenSkipToOneOfTypes(TOKEN, SKIPPAIR, ...)\t\t\t\t\t\t\\\n\ttokenSkipToOneOfTypesImpl(TOKEN, SKIPPAIR, ((tokenType []){__VA_ARGS__}), sizeof((tokenType []){__VA_ARGS__})/sizeof(tokenType))\nbool tokenSkipToOneOfTypesImpl (tokenInfo *token, bool skipPair, tokenType ts[], size_t count);\n\nbool tokenSkipOverPair (tokenInfo *token);\nbool tokenSkipOverPairFull (tokenInfo *token, void *data);\n\nvoid tokenInitTagEntry (tokenInfo *token, tagEntryInfo *e, int kind);\nvoid tokenInitRefTagEntry (tokenInfo *token, tagEntryInfo *e, int kind, int role);\nint tokenMakeSimpleTag (tokenInfo *token, int kind);\nint tokenMakeSimpleRefTag (tokenInfo *token, int kind, int role);\n\n#endif\n"
  },
  {
    "path": "main/trace.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Tracing facility.\n*/\n\n#include \"general.h\"\n#include \"trace.h\"\n\n#ifdef DO_TRACING\n\n#include \"options.h\"\n#include \"read.h\"\n\n#include <stdio.h>\n#include <stdarg.h>\n\nvoid traceEnter(const char * szFunction,const char * szFormat,...)\n{\n\tif (!isTraced())\n\t\treturn;\n\n\tdebugIndent ();\n\n\tfprintf(stderr,\"[>> %s][at %lu] \",szFunction,getInputLineNumber());\n\n\tva_list va;\n\tva_start(va,szFormat);\n\tvfprintf(stderr,szFormat,va);\n\tva_end(va);\n\n\tfprintf(stderr,\"\\n\");\n\n\tdebugInc();\n}\n\nvoid traceLeave(const char * szFunction,const char * szFormat,...)\n{\n\tif (!isTraced())\n\t\treturn;\n\n\tdebugDec();\n\tdebugIndent ();\n\n\tfprintf(stderr,\"[<< %s][at %lu] \",szFunction,getInputLineNumber());\n\n\tva_list va;\n\tva_start(va,szFormat);\n\tvfprintf(stderr,szFormat,va);\n\tva_end(va);\n\n\tfprintf(stderr,\"\\n\");\n}\n\nstatic void tracePrintFmtVa(const char * szFormat, va_list va)\n{\n\tif (!isTraced())\n\t\treturn;\n\n\tvfprintf(stderr,szFormat,va);\n}\n\nvoid tracePrint(const char * szFunction, const char * szFormat,...)\n{\n\tif (!isTraced())\n\t\treturn;\n\n\ttracePrintPrefix(szFunction);\n\n\tva_list va;\n\tva_start(va,szFormat);\n\ttracePrintFmtVa (szFormat,va);\n\tva_end(va);\n\n\ttracePrintNewline();\n}\n\nvoid tracePrintFmt(const char * szFormat,...)\n{\n\tva_list va;\n\tva_start(va,szFormat);\n\ttracePrintFmtVa (szFormat,va);\n\tva_end(va);\n}\n\nvoid tracePrintPrefix(const char * szFunction)\n{\n\tif (!isTraced())\n\t\treturn;\n\n\tdebugIndent();\n\n\tfprintf(stderr,\"[%s][at %lu] \",szFunction,getInputLineNumber());\n}\n\nvoid tracePrintNewline(void)\n{\n\tif (!isTraced())\n\t\treturn;\n\n\tfprintf(stderr,\"\\n\");\n}\n\nstatic bool tracingMain;\n\nvoid traceMain(void)\n{\n\tverbose(\"Tracing main part\\n\");\n\ttracingMain = true;\n}\n\nbool isMainTraced(void)\n{\n\treturn tracingMain;\n}\n\n#else\nbool isTraced (void) { return false; }\nvoid traceLanguage (langType language) {}\nbool isLanguageTraced (langType language) { return false; }\n\nvoid traceEnter(const char * szFunction,const char * szFormat,...) {}\nvoid traceLeave(const char * szFunction,const char * szFormat,...) {}\nvoid tracePrint(const char * szFunction,const char * szFormat,...) {}\n\nvoid tracePrintPrefix(const char * szFunction) {}\nvoid tracePrintFmt(const char * szFormat,...) {}\nvoid tracePrintNewline(void) {}\n\nvoid traceMain(void);\nbool isMainTraced(void) { return false; }\n\n#endif // DO_TRACING\n"
  },
  {
    "path": "main/trace.h",
    "content": "#ifndef ctags_trace_h_\n#define ctags_trace_h_\n/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Tracing facility.\n*/\n\n#include \"general.h\"\n#include \"debug.h\"\n\n//\n// Master tracing switch.\n//\n// Uncomment this to enable extensive debugging to stderr in code.\n// Use only for development as tracing reduces performance.\n//\n// \"./configure --enable-debugging\" defines DEBUG.\n// When running ctags, pass --_trace=<LANG>[,<LANG>]* option.\n//\n#ifdef DEBUG\n#define DO_TRACING\n#endif\n\nbool isTraced (void);\nvoid traceLanguage (langType language);\nbool isLanguageTraced (langType language);\n\nvoid traceEnter(const char * szFunction,const char * szFormat,...);\nvoid traceLeave(const char * szFunction,const char * szFormat,...);\nvoid tracePrint(const char * szFunction,const char * szFormat,...);\n\nvoid tracePrintPrefix(const char * szFunction);\nvoid tracePrintFmt(const char * szFormat,...);\nvoid tracePrintNewline(void);\n\nvoid traceMain(void);\nbool isMainTraced(void);\n\n#ifdef DO_TRACING\n\n\t#define TRACE_ENTER() traceEnter(ASSERT_FUNCTION,\"\")\n\t#define TRACE_LEAVE() traceLeave(ASSERT_FUNCTION,\"\")\n\n\t#define TRACE_ENTER_TEXT(_szFormat,...) \\\n\t\ttraceEnter(ASSERT_FUNCTION,_szFormat,## __VA_ARGS__)\n\n\t#define TRACE_LEAVE_TEXT(_szFormat,...) \\\n\t\ttraceLeave(ASSERT_FUNCTION,_szFormat,## __VA_ARGS__)\n\n\t#define TRACE_PRINT(_szFormat,...) \\\n\t\ttracePrint(ASSERT_FUNCTION,_szFormat,## __VA_ARGS__)\n\n\t/* TRACE_PRINT prints line at once.\n\t * If you want to print a trace line incrementally,\n\t * use following macros.\n\t *\n\t * TRACE_PRINT_PREFIX: just print a trace prefix. No newline.\n\t * TRACE_PRINT_FMT: print as a format. No prefix, no newline.\n\t * TRACE_PRINT_NEWLINE: just print a newline.\n\t */\n\t#define TRACE_PRINT_PREFIX() \\\n\t\ttracePrintPrefix(ASSERT_FUNCTION)\n\t#define TRACE_PRINT_FMT(_szFormat,...) \\\n\t\ttracePrintFmt(_szFormat,## __VA_ARGS__)\n\t#define TRACE_PRINT_NEWLINE() \\\n\t\ttracePrintNewline()\n\n\t#define TRACE_ASSERT(_condition,_szFormat,...) \\\n\t\tdo { \\\n\t\t\tif(!(_condition)) \\\n\t\t\t{ \\\n\t\t\t\ttracePrint(ASSERT_FUNCTION,_szFormat,## __VA_ARGS__); \\\n\t\t\t\tAssert(false); \\\n\t\t\t} \\\n\t\t} while(0)\n\n#else //!DO_TRACING\n\n\t#define TRACE_ENTER() do { } while(0)\n\t#define TRACE_LEAVE() do { } while(0)\n\n\t#define TRACE_ENTER_TEXT(_szFormat,...) do { } while(0)\n\t#define TRACE_LEAVE_TEXT(_szFormat,...) do { } while(0)\n\n\t#define TRACE_PRINT(_szFormat,...) do { } while(0)\n\n\t#define TRACE_PRINT_PREFIX() do { } while(0)\n\t#define TRACE_PRINT_FMT(_szFormat,...) do { } while(0)\n\t#define TRACE_PRINT_NEWLINE() do { } while(0)\n\n\t#define TRACE_ASSERT(_condition,_szFormat,...) do { } while(0)\n\n#endif //!DO_TRACING\n\n\n#endif //!ctags_trace_h_\n"
  },
  {
    "path": "main/trashbox.c",
    "content": "/*\n*\n*   Copyright (c) 2014, Red Hat, Inc.\n*   Copyright (c) 2014, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License.\n*\n*/\n\n#include \"general.h\"\n\n#include \"debug.h\"\n#include \"routines.h\"\n#include \"trashbox.h\"\n#include \"trashbox_p.h\"\n\ntypedef TrashBoxDestroyItemProc TrashDestroyItemProc;\ntypedef struct sTrash {\n\tvoid* item;\n\tstruct sTrash* next;\n\tTrashDestroyItemProc destrctor;\n} Trash;\n\nstruct sTrashBox {\n\tTrash *trash;\n};\n\nstatic TrashBox* defaultTrashBox;\nstatic TrashBox* parserTrashBox;\n\nstatic Trash* trashPut (Trash* trash, void* item,\n\t\t\tTrashDestroyItemProc destrctor);\nstatic Trash* trashTakeBack (Trash* trash, void* item, TrashDestroyItemProc* destrctor);\nstatic Trash* trashMakeEmpty (Trash* trash);\n\nextern TrashBox* trashBoxNew (void)\n{\n\tTrashBox *t = xMalloc (1, TrashBox);\n\tt->trash = NULL;\n\treturn t;\n}\n\nextern TrashBox* trashBoxStack     (TrashBox* trash_box)\n{\n\tTrashBox *t = trashBoxNew();\n\n\tif (!trash_box)\n\t\ttrash_box = defaultTrashBox;\n\n\ttrashBoxPut (trash_box, t, (TrashBoxDestroyItemProc) trashBoxDelete);\n\n\treturn t;\n}\n\nextern void trashBoxDelete (TrashBox* trash_box)\n{\n\tif (!trash_box)\n\t\ttrash_box = defaultTrashBox;\n\n\ttrashBoxMakeEmpty(trash_box);\n\n\teFree (trash_box);\n}\n\nextern void*  trashBoxPut (TrashBox* trash_box, void* item, TrashBoxDestroyItemProc destroy)\n{\n\tif (!trash_box)\n\t\ttrash_box = defaultTrashBox;\n\n\ttrash_box->trash = trashPut(trash_box->trash, item, destroy);\n\treturn item;\n}\n\nextern TrashBoxDestroyItemProc trashBoxTakeBack (TrashBox* trash_box, void* item)\n{\n\tTrashBoxDestroyItemProc d;\n\n\tif (!trash_box)\n\t\ttrash_box = defaultTrashBox;\n\n\ttrash_box->trash = trashTakeBack(trash_box->trash, item, &d);\n\treturn d;\n}\n\nextern void   trashBoxMakeEmpty (TrashBox* trash_box)\n{\n\tif (!trash_box)\n\t\ttrash_box = defaultTrashBox;\n\n\ttrash_box->trash = trashMakeEmpty (trash_box->trash);\n}\n\n\nextern void      trashBoxFree      (TrashBox* trash_box, void* item)\n{\n\tTrashBoxDestroyItemProc d;\n\n\tif (!trash_box)\n\t\ttrash_box = defaultTrashBox;\n\n\td = trashBoxTakeBack (trash_box, item);\n\td (item);\n}\n\nstatic Trash* trashPut (Trash* trash, void* item,\n\t\t\tTrashDestroyItemProc destrctor)\n{\n\tTrash* t = xMalloc (1, Trash);\n\tt->next = trash;\n\tt->item = item;\n\tt->destrctor = destrctor? destrctor: eFree;\n\treturn t;\n}\n\nstatic TrashBoxDestroyItemProc trashTakeBack0  (Trash** trash, void* item)\n{\n\tTrashBoxDestroyItemProc removed;\n\tTrash* tmp;\n\n\tremoved = NULL;\n\twhile (*trash)\n\t{\n\t\tif ( (*trash)->item ==  item )\n\t\t{\n\t\t\ttmp = *trash;\n\t\t\t*trash = (*trash)->next;\n\t\t\ttmp->next = NULL;\n\t\t\ttmp->item = NULL;\n\t\t\tremoved = tmp->destrctor;\n\n\t\t\teFree (tmp);\n\t\t\ttmp = NULL;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\ttrash = &(*trash)->next;\n\t}\n\n\tAssert (removed);\n\treturn removed;\n}\n\nstatic Trash* trashTakeBack (Trash* trash, void* item, TrashDestroyItemProc *destrctor)\n{\n\tTrashDestroyItemProc d;\n\td = trashTakeBack0 (&trash, item);\n\tif (destrctor)\n\t\t*destrctor = d;\n\n\treturn trash;\n}\n\nstatic Trash* trashMakeEmpty (Trash* trash)\n{\n\tTrash* tmp;\n\n\twhile (trash)\n\t{\n\t\ttmp = trash;\n\t\ttrash = trash->next;\n\t\ttmp->destrctor (tmp->item);\n\t\ttmp->item = NULL;\n\t\ttmp->destrctor = NULL;\n\t\teFree (tmp);\n\t}\n\treturn NULL;\n}\n\nextern void initDefaultTrashBox (void)\n{\n\tdefaultTrashBox = trashBoxNew ();\n}\n\nextern void finiDefaultTrashBox (void)\n{\n\ttrashBoxDelete (defaultTrashBox);\n\tdefaultTrashBox = NULL;\n}\n\nextern void initParserTrashBox (void)\n{\n\tparserTrashBox = trashBoxNew ();\n}\n\nextern void finiParserTrashBox  (void)\n{\n\ttrashBoxDelete (parserTrashBox);\n\tparserTrashBox = NULL;\n}\n\nextern void* parserTrashBoxPut  (void* item, TrashBoxDestroyItemProc destroy)\n{\n\treturn trashBoxPut(parserTrashBox, item, destroy);\n}\n\nextern TrashBoxDestroyItemProc parserTrashBoxTakeBack  (void* item)\n{\n\treturn trashBoxTakeBack(parserTrashBox, item);\n}\n\n#ifdef TRASH_TEST\n#include <stdio.h>\n\nint main (void)\n{\n\tTrash* trash = NULL;\n\tTrash* tmp;\n\tchar* d = eStrdup (\"d\");\n\tchar* b = eStrdup (\"b\");\n\n\ttrash = trashPut (trash, eStrdup (\"a\"));\n\ttrash = trashPut (trash, b);\n\ttrash = trashPut (trash, eStrdup (\"c\"));\n\ttrash = trashPut (trash, d);\n\n\ttrash = trashTakeBack (trash, b, NULL);\n\teFree (b);\n\n\tfputs(\"expects: dca\\nactual: \", stderr);\n\tfor (tmp = trash; tmp; tmp = tmp->next)\n\t\tfputs(tmp->item, stderr);\n\tfputc('\\n', stderr);\n\n\n\ttrash = trashTakeBack (trash, d, NULL);\n\teFree (d);\n\n\tfputs(\"expects: ca\\nactual: \", stderr);\n\tfor (tmp = trash; tmp; tmp = tmp->next)\n\t\tfputs(tmp->item, stderr);\n\tfputc('\\n', stderr);\n\n\ttrash = trashMakeEmpty (trash);\n\n\tfputs(\"expects: \\nactual: \", stderr);\n\tfor (tmp = trash; tmp; tmp = tmp->next)\n\t\tfputs(tmp->item, stderr);\n\tfputc('\\n', stderr);\n\treturn 0;\n}\n\n#include <stdlib.h>\nvoid eFree (void *ptr) { free(ptr); }\nvoid *eMalloc (const size_t size) { return malloc(size); }\nchar *eStrdup (const char* str) { return strdup(str); }\n#endif\n"
  },
  {
    "path": "main/trashbox.h",
    "content": "/*\n*\n*   Copyright (c) 2017, Red Hat, Inc.\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Facility for delayed memory releasing, inspired from AutoreleasePool\n*   of OpenStep.\n*/\n\n#ifndef CTAGS_MAIN_TRASH_H\n#define CTAGS_MAIN_TRASH_H\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"  /* must always come first */\n\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef void (* TrashBoxDestroyItemProc) (void *);\ntypedef struct sTrashBox TrashBox;\n\n/*\n*   MACROS\n*/\n\n#define DEFAULT_TRASH_BOX(PTR,PROC) trashBoxPut(NULL,PTR,(TrashBoxDestroyItemProc)PROC)\n#define DEFAULT_TRASH_BOX_TAKE_BACK(PTR) trashBoxTakeBack(NULL,PTR)\n\n#define PARSER_TRASH_BOX(PTR,PROC) parserTrashBoxPut(PTR,(TrashBoxDestroyItemProc)PROC)\n#define PARSER_TRASH_BOX_TAKE_BACK(PTR) parserTrashBoxTakeBack(PTR)\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern TrashBox* trashBoxNew       (void);\nextern TrashBox* trashBoxStack     (TrashBox* trash_box);\nextern void      trashBoxDelete    (TrashBox* trash_box);\nextern void*     trashBoxPut       (TrashBox* trash_box, void* item, TrashBoxDestroyItemProc destroy);\nextern TrashBoxDestroyItemProc trashBoxTakeBack  (TrashBox* trash_box, void* item);\nextern void      trashBoxFree      (TrashBox* trash_box, void* item);\nextern void      trashBoxMakeEmpty (TrashBox* trash_box);\n\n/* A parser trash box is prepared when `parser' method of a parser is called.\n * The parser can register a pair of a memory object and destructor for the object to\n * the trash box with parserTrashBoxPut ().\n *\n * The registered memory objects are destructed after `parser' method is finished in\n * the main side. You can delay the destruction with parserTrashBoxPut ().\n *\n * You can unregister the pair in the `parser' method with parserTrashBoxTakeBack ().\n * In that case, specify the memory object of the pair as the argument.\n */\nextern void* parserTrashBoxPut  (void* item, TrashBoxDestroyItemProc destroy);\nextern TrashBoxDestroyItemProc parserTrashBoxTakeBack  (void* item);\n\n#endif /* CTAGS_MAIN_TRASH_H */\n"
  },
  {
    "path": "main/trashbox_p.h",
    "content": "/*\n*\n*   Copyright (c) 2017, Red Hat, Inc.\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef CTAGS_MAIN_TRASH_PRIVATE_H\n#define CTAGS_MAIN_TRASH_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"  /* must always come first */\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern void initDefaultTrashBox (void);\nextern void finiDefaultTrashBox  (void);\n\nextern void initParserTrashBox (void);\nextern void finiParserTrashBox  (void);\n\n#endif\t/* CTAGS_MAIN_TRASH_PRIVATE_H */\n"
  },
  {
    "path": "main/types.h",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Private definitions for parsing support.\n*/\n\n#ifndef CTAGS_MAIN_TYPES_H\n#define CTAGS_MAIN_TYPES_H\n\ntypedef int langType;\n\nstruct sTagEntryInfo;\ntypedef struct sTagEntryInfo tagEntryInfo;\n\nstruct sPtagDesc;\ntypedef struct sPtagDesc ptagDesc;\n\nstruct sRoleDefinition;\ntypedef struct sRoleDefinition roleDefinition;\n\nstruct sKindDefinition;\ntypedef struct sKindDefinition kindDefinition;\n\nstruct sParserDefinition;\ntypedef struct sParserDefinition parserDefinition;\n\nstruct _MIO;\ntypedef const char * (*selectLanguage) (struct _MIO *, langType *, unsigned int);\n\nstruct sSlaveParser;\ntypedef struct sSlaveParser slaveParser;\n\nstruct sSubparser;\ntypedef struct sSubparser subparser;\n\nstruct sParserDependency;\ntypedef struct sParserDependency parserDependency;\n\nstruct sFieldDefinition;\ntypedef struct sFieldDefinition fieldDefinition;\n\nstruct sXtagDefinition;\ntypedef struct sXtagDefinition xtagDefinition;\n\nstruct sParamDefinition;\ntypedef struct sParamDefinition paramDefinition;\n\n#endif\t/* CTAGS_MAIN_TYPES_H */\n"
  },
  {
    "path": "main/unwindi.c",
    "content": "/*\n *\n *  Copyright (c) 2019, Red Hat, Inc.\n *  Copyright (c) 2019, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   Unwindable input stream / Unlimited ungetc\n *\n */\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"\n\n#include \"debug.h\"\n#include \"gcc-attr.h\"\n#include \"inline.h\"\n#include \"mio.h\"\n#include \"objpool.h\"\n#include \"ptrarray.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"trashbox.h\"\n#include \"unwindi.h\"\n\n#include <string.h>\n\ntypedef struct sUugcChar {\n\tint c;\n\t/* lineNumber before reading the char (frontLineNumber).\n\t * The lineNumber after reading the char (rearLineNumber) can be calculated:\n\t * If the char is \\n, rearLineNumber is frontLineNumber + 1.\n\t * If the char is not, rearLineNumber is the same as frontLineNumber. */\n\tunsigned long lineNumber;\n} uugcChar;\n\n\nstatic ptrArray *uugcInputFile;\nstatic uugcChar *uugcCurrentChar;\nstatic objPool  *uugcCharPool;\n\nstatic struct sUwiStats uwiStats;\n\nstatic void deleteChar (void *c)\n{\n\teFree (c);\n}\n\nstatic void* newChar (void *data CTAGS_ATTR_UNUSED)\n{\n\treturn xMalloc (1, uugcChar);\n}\n\nCTAGS_INLINE void uugcDeleteC (uugcChar *c)\n{\n\tif (c == uugcCurrentChar)\n\t\tuugcCurrentChar = NULL;\n\n\tobjPoolPut (uugcCharPool, c);\n}\n\nstatic void uugcActivate (void)\n{\n\tAssert (!uugcInputFile);\n\tAssert (!uugcCurrentChar);\n\n\tif (uugcCharPool == NULL)\n\t{\n\t\tuugcCharPool = objPoolNew(256,\n\t\t\t\t\t\t\t\t  newChar,\n\t\t\t\t\t\t\t\t  deleteChar,\n\t\t\t\t\t\t\t\t  NULL,\n\t\t\t\t\t\t\t\t  NULL);\n\t\tDEFAULT_TRASH_BOX(uugcCharPool, objPoolDelete);\n\t}\n\n\tuugcInputFile = ptrArrayNew ((ptrArrayDeleteFunc)uugcDeleteC);\n}\n\nstatic void uugcDeactive(void)\n{\n\tAssert (uugcInputFile);\n\tptrArrayDelete (uugcInputFile);\n\tuugcInputFile = NULL;\n\tuugcCurrentChar = NULL;\n}\n\nCTAGS_INLINE uugcChar *uugcNewC (int chr, unsigned long ln)\n{\n\tAssert (uugcCharPool);\n\n\tuugcChar *c = objPoolGet (uugcCharPool);\n\tc->c = chr;\n\tc->lineNumber = ln;\n\treturn c;\n}\n\nCTAGS_INLINE uugcChar *uugciGetC (void)\n{\n\tuugcChar *c;\n\n\tAssert (uugcInputFile);\n\n\tif (ptrArrayCount (uugcInputFile) > 0)\n\t{\n\t\tc = ptrArrayLast (uugcInputFile);\n\t\tptrArrayRemoveLast (uugcInputFile);\n\t}\n\telse\n\t{\n\t\tunsigned long lineNumber = getInputLineNumber ();\n\t\tint chr = getcFromInputFile();\n\t\tc = uugcNewC (chr, lineNumber);\n\t}\n\n\tuugcCurrentChar = c;\n\treturn uugcCurrentChar;\n}\n\nCTAGS_INLINE void uugcUngetC (uugcChar *c)\n{\n\tuugcCurrentChar = NULL;\n\n\tif (c->c == EOF)\n\t{\n\t\tptrArrayClear (uugcInputFile);\n\t\tuugcDeleteC (c);\n\t\treturn;\n\t}\n\n\tptrArrayAdd (uugcInputFile, c);\n}\n\nCTAGS_INLINE void uugcInjectC (int chr)\n{\n\tif (chr == EOF)\n\t\treturn;\n\n\tuugcChar *lastc = NULL;\n\tif (ptrArrayCount (uugcInputFile) > 0)\n\t\tlastc = ptrArrayLast (uugcInputFile);\n\n\tunsigned long lineNumber;\n\tif (lastc)\n\t{\n\t\tif (chr == '\\n' && lastc->lineNumber > 0)\n\t\t\tlineNumber = lastc->lineNumber - 1;\n\t\telse\n\t\t\tlineNumber = lastc->lineNumber;\n\t}\n\telse\n\t{\n\t\tlineNumber = getInputLineNumber ();\n\t\tif (chr == '\\n')\n\t\t\tlineNumber--;\n\t}\n\n\tuugcChar *c = uugcNewC(chr, lineNumber);\n\tuugcUngetC (c);\n}\n\nCTAGS_INLINE long uugcGetLineNumber (void)\n{\n\tAssert (uugcInputFile);\n\n\tif (uugcCurrentChar)\n\t{\n\t\tunsigned long ln;\n\t\tif (uugcCurrentChar->c == '\\n')\n\t\t\tln = uugcCurrentChar->lineNumber + 1;\n\t\telse\n\t\t\tln = uugcCurrentChar->lineNumber;\n\t\treturn ln;\n\t}\n\telse if (ptrArrayCount (uugcInputFile) > 0)\n\t{\n\t\tuugcChar *c = ptrArrayLast (uugcInputFile);\n\t\treturn c->lineNumber;\n\t}\n\telse\n\t\treturn getInputLineNumber ();\n}\n\nCTAGS_INLINE MIOPos uugcGetFilePosition (void)\n{\n\tif (uugcCurrentChar)\n\t{\n\t\tunsigned long ln;\n\t\tif (uugcCurrentChar->c == '\\n')\n\t\t\tln = uugcCurrentChar->lineNumber + 1;\n\t\telse\n\t\t\tln = uugcCurrentChar->lineNumber;\n\t\treturn getInputFilePositionForLine (ln);\n\t}\n\telse if (ptrArrayCount (uugcInputFile) > 0)\n\t{\n\t\tuugcChar *c = ptrArrayLast (uugcInputFile);\n\t\treturn getInputFilePositionForLine (c->lineNumber);\n\t}\n\telse\n\t\treturn getInputFilePosition ();\n}\n\nstatic ptrArray *uwiBuffer;\nstatic unsigned int *uwiMarkerStack;\nstatic unsigned int uwiMarkerStackLength;\nstatic unsigned int *uwiCurrentMarker;\n\nextern void uwiActivate (unsigned int stackLength)\n{\n\tAssert (stackLength > 0);\n\n\tuugcActivate ();\n\tuwiBuffer = ptrArrayNew ((ptrArrayDeleteFunc)uugcDeleteC);\n\tuwiMarkerStackLength = stackLength;\n\tuwiMarkerStack = xMalloc (stackLength, unsigned int);\n\tuwiCurrentMarker = NULL;\n\n\tuwiStatsInit (&uwiStats);\n}\n\nextern void uwiDeactivate (struct sUwiStats *statsToBeUpdated)\n{\n\tAssert (uwiBuffer);\n\tAssert (uwiMarkerStack);\n\n\tif (statsToBeUpdated)\n\t{\n\t\tif (statsToBeUpdated->maxLength < uwiStats.maxLength)\n\t\t\tstatsToBeUpdated->maxLength = uwiStats.maxLength;\n\t\tif (!statsToBeUpdated->overflow)\n\t\t\tstatsToBeUpdated->overflow = uwiStats.overflow;\n\t\tif (!statsToBeUpdated->underflow)\n\t\t\tstatsToBeUpdated->underflow = uwiStats.underflow;\n\t}\n\n\tptrArrayDelete (uwiBuffer);\n\teFree (uwiMarkerStack);\n\tuwiBuffer = NULL;\n\tuwiMarkerStack = NULL;\n\tuwiMarkerStackLength = 0;\n\tuugcDeactive();\n}\n\nextern int uwiGetC (void)\n{\n\tint c;\n\tuugcChar *chr = uugciGetC ();\n\n\tc = chr->c;\n\n\tif (uwiCurrentMarker)\n\t{\n\t\t*uwiCurrentMarker += 1;\n\t\tptrArrayAdd (uwiBuffer, chr);\n\t}\n\telse\n\t{\n\t\tuugcCurrentChar = NULL;\n\t\tuugcDeleteC (chr);\n\t}\n\n\treturn c;\n}\n\nextern void uwiUngetC (int c)\n{\n\tAssert (!uwiCurrentMarker);\n\tuugcInjectC (c);\n}\n\nextern unsigned long uwiGetLineNumber (void)\n{\n\treturn uugcGetLineNumber ();\n}\n\nextern MIOPos uwiGetFilePosition (void)\n{\n\treturn uugcGetFilePosition ();\n}\n\nextern void uwiPushMarker (void)\n{\n\n\tif (uwiStats.maxLength < (uwiCurrentMarker - uwiMarkerStack) + 1)\n\t\tuwiStats.maxLength = (uwiCurrentMarker - uwiMarkerStack) + 1;\n\n\tif (uwiCurrentMarker - uwiMarkerStack >= ( uwiMarkerStackLength - 1 )) {\n\t\terror (WARNING,\n\t\t\t\"trying to add too many markers during parsing: %s \"\n\t\t\t\"(this is a bug, please consider filing an issue)\", getInputFileName());\n\t\tuwiCurrentMarker = NULL;\n\t\tuwiStats.overflow = true;\n\t}\n\n\tif (uwiCurrentMarker) uwiCurrentMarker++;\n\telse uwiCurrentMarker = uwiMarkerStack;\n\n\t*uwiCurrentMarker = 0;\n}\n\nextern void uwiPopMarker (const int upto, const bool revertChars)\n{\n\tif (uwiCurrentMarker - uwiMarkerStack < 0) {\n\t\terror (WARNING,\n\t\t\t\t\"trying to drop too many markers during parsing: %s \"\n\t\t\t\t\"(this is a bug, please consider filing an issue)\", getInputFileName());\n\n\t\tuwiCurrentMarker = NULL;\n\t\tuwiStats.underflow = true;\n\t\treturn;\n\t}\n\n\tuwiClearMarker (upto, revertChars);\n\n\tif (uwiCurrentMarker == uwiMarkerStack) uwiCurrentMarker = NULL;\n\telse uwiCurrentMarker--;\n}\n\nextern void uwiClearMarker (const int upto, const bool revertChars)\n{\n\tAssert (uwiCurrentMarker);\n\tint count = (upto <= 0)? *uwiCurrentMarker : upto;\n\tvoid (*charHandler)(uugcChar *) = revertChars ? uugcUngetC : uugcDeleteC;\n\n\twhile (count-- > 0)\n\t{\n\t\tcharHandler (ptrArrayLast (uwiBuffer));\n\t\tptrArrayRemoveLast (uwiBuffer);\n\t\t*uwiCurrentMarker -= 1;\n\t}\n}\n\nextern void uwiDropMaker (void)\n{\n\tuwiPopMarker (0, false);\n}\n\nextern void uwiStatsInit (struct sUwiStats *stats)\n{\n\tmemset (stats, 0, sizeof (*stats));\n}\n\nextern void uwiStatsPrint (struct sUwiStats *stats)\n{\n\tfprintf(stderr, \"Unwinding the longest input stream stack usage: %d\\n\",\n\t\t\tstats->maxLength);\n\tfprintf(stderr, \"Unwinding input stream stack overflow incidence: %s\\n\",\n\t\t\tstats->overflow? \"yes\": \"no\");\n\tfprintf(stderr, \"Unwinding input stream stack underflow incidence: %s\\n\",\n\t\t\tstats->underflow? \"yes\": \"no\");\n}\n"
  },
  {
    "path": "main/unwindi.h",
    "content": "/*\n *\n *  Copyright (c) 2019, Red Hat, Inc.\n *  Copyright (c) 2019, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   Unwindable input stream\n *\n */\n#ifndef CTAGS_MAIN_UNWINDI_H\n#define CTAGS_MAIN_UNWINDI_H\n\n/* This header file unwindable input stream.\n * You cannot use this API combining with functions defined\n * in read.h:\n *\n * - getcFromInputFile\n * - ungetcToInputFile\n * - readLineFromInputFile\n * - getInputLineNumber\n * - getInputFilePosition\n * - getInputLineOffset\n *\n * Instead, you can use\n * - uwiGetC\n * - uwiUngetC\n * - uwiGetLineNumber\n * - uwiGetFilePosition\n *\n * You can mark a position in the current input stream with\n * uwiPushMarker().\n * Later, call uwiPopMarker() to unwind the input stream to the\n * position where you marked.\n *\n * uwiPopMarker() takes COUNT as a parameter. It controls unwinding\n * how many bytes. If -1 is passed as COUNT, unwinding to the marked\n * position.\n *\n * If you find that you don't have to unwind though you called\n * uwiPushMarker(), call uwiDropMaker().\n *\n * uwiPopMarker() and uwiDropMaker() release internally allocated resources and\n * clear the marker.\n *\n * If no marker is set, you can use uwiUngetC().\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\nstruct sUwiStats {\n\tint maxLength;\n\tbool overflow;\n\tbool underflow;\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void uwiActivate   (unsigned int);\nextern void uwiDeactivate (struct sUwiStats *statsToBeUpdated);\n\nextern void uwiStatsInit  (struct sUwiStats *stats);\nextern void uwiStatsPrint (struct sUwiStats *stats);\n\nextern int uwiGetC (void);\nextern void uwiUngetC (int c);\nextern unsigned long uwiGetLineNumber (void);\nextern MIOPos uwiGetFilePosition (void);\n\nextern void uwiPushMarker (void);\nextern void uwiClearMarker (const int count, const bool revertChars);\nextern void uwiPopMarker (const int count, const bool revertChars);\nextern void\tuwiDropMaker (void);\n#endif\t/* CTAGS_MAIN_UNWINDI_H */\n"
  },
  {
    "path": "main/utf8_str.c",
    "content": "/*\n*\n*   Copyright (c) 2023, Yinzuo Jiang\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines functions for UTF-8 string manipulation.\n*   utf8_strlen is derived from parsers/rst.c\n*/\n\n#include \"general.h\"\n\n#include \"utf8_str.h\"\n\n/* computes the length of an UTF-8 string\n * if the string doesn't look like UTF-8, return -1\n * FIXME consider East_Asian_Width Unicode property */\nint utf8_strlen (const char *buf, int buf_len)\n{\n\tint len = 0;\n\tconst char *end = buf + buf_len;\n\n\tfor (len = 0; buf < end; len++)\n\t{\n\t\t/* perform quick and naive validation (no sub-byte checking) */\n\t\tif (!(*buf & 0x80))\n\t\t\tbuf++;\n\t\telse if ((*buf & 0xe0) == 0xc0)\n\t\t\tbuf += 2;\n\t\telse if ((*buf & 0xf0) == 0xe0)\n\t\t\tbuf += 3;\n\t\telse if ((*buf & 0xf8) == 0xf0)\n\t\t\tbuf += 4;\n\t\telse\t/* not a valid leading UTF-8 byte, abort */\n\t\t\treturn -1;\n\n\t\tif (buf > end)\t/* incomplete last byte */\n\t\t\treturn -1;\n\t}\n\n\treturn len;\n}\n\n/* computes the raw buf length of an UTF-8 (ascii excluded) string\n * if the string doesn't look like UTF-8, return -1 */\nint utf8_raw_strlen (const char *buf, int buf_len)\n{\n\tint raw_len = 0;\n\tconst char *end = buf + buf_len;\n\n\twhile (buf < end)\n\t{\n\t\t/* perform quick and naive validation (no sub-byte checking) */\n\t\tif (!(*buf & 0x80))\n\t\t{\n\t\t\t/* stop at ascii character */\n\t\t\treturn raw_len;\n\t\t}\n\t\telse if ((*buf & 0xe0) == 0xc0)\n\t\t{\n\t\t\tbuf += 2;\n\t\t\traw_len += 2;\n\t\t}\n\t\telse if ((*buf & 0xf0) == 0xe0)\n\t\t{\n\t\t\tbuf += 3;\n\t\t\traw_len += 3;\n\t\t}\n\t\telse if ((*buf & 0xf8) == 0xf0)\n\t\t{\n\t\t\tbuf += 4;\n\t\t\traw_len += 4;\n\t\t}\n\t\telse\t/* not a valid leading UTF-8 byte, abort */\n\t\t\treturn -1;\n\n\t\tif (buf > end)\t/* incomplete last byte */\n\t\t\treturn -1;\n\t}\n\n\treturn raw_len;\n}\n"
  },
  {
    "path": "main/utf8_str.h",
    "content": "/*\n*\n*   Copyright (c) 2023, Yinzuo Jiang\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Defines functions for UTF-8 string manipulation.\n*   utf8_strlen is derived from parsers/rst.c\n*/\n\n#ifndef CTAGS_MAIN_UTF8_STR_H\n#define CTAGS_MAIN_UTF8_STR_H\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern int utf8_strlen (const char *buf, int buf_len);\nextern int utf8_raw_strlen (const char *buf, int buf_len);\n\n#endif /* CTAGS_MAIN_UTF8_STR_H */\n"
  },
  {
    "path": "main/vstring.c",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions supporting resizeable strings.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <limits.h>  /* to define INT_MAX */\n#include <string.h>\n#include <ctype.h>\n\n#include \"debug.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"trashbox.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic const size_t vStringInitialSize = 32;\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n/*\n*   External interface\n*/\n\nextern void vStringResize (vString *const string, const size_t newSize)\n{\n\tsize_t size = vStringInitialSize;\n\n\twhile (size < newSize)\n\t\tsize *= 2;\n\n\tif (size > string->size)\n\t{\n\t\tstring->size = size;\n\t\tstring->buffer = xRealloc (string->buffer, size, char);\n\t}\n}\n\nextern void vStringTruncate (vString *const string, const size_t length)\n{\n\tAssert (length <= string->length);\n\tstring->length = length;\n\tstring->buffer[string->length] = '\\0';\n\tDebugStatement ( memset (string->buffer + string->length, 0,\n\t                         string->size - string->length); )\n}\n\nextern void vStringDelete (vString *const string)\n{\n\tif (string != NULL)\n\t{\n\t\tif (string->buffer != NULL)\n\t\t\teFree (string->buffer);\n\t\teFree (string);\n\t}\n}\n\nextern vString *vStringNew (void)\n{\n\tvString *const string = xMalloc (1, vString);\n\n\tstring->length = 0;\n\tstring->size   = vStringInitialSize;\n\tstring->buffer = xMalloc (string->size, char);\n\n\tvStringClear (string);\n\n\treturn string;\n}\n\nextern vString *vStringNewCopy (const vString *const string)\n{\n\tvString *vs = vStringNew ();\n\tvStringCatS (vs, string->buffer);\n\treturn vs;\n}\n\nextern vString *vStringNewInit (const char *const s)\n{\n\tvString *vs = vStringNew ();\n\tvStringCatS (vs, s);\n\treturn vs;\n}\n\nextern vString *vStringNewNInit (const char *const s, const size_t length)\n{\n\tvString *vs = vStringNew ();\n\tvStringNCatS (vs, s, length);\n\treturn vs;\n}\n\nstatic void stringCat (\n\t\tvString *const string, const char *const s, const size_t length)\n{\n\tif (string->length + length + 1 > string->size)\n\t\tvStringResize (string, string->length + length + 1);\n\n\tmemcpy (string->buffer + string->length, s, length);\n\tstring->length += length;\n\tvStringPut (string, '\\0');\n}\n\nextern void vStringNCat (\n\t\tvString *const string, const vString *const s, const size_t length)\n{\n\tsize_t len = vStringLength (s);\n\n\tlen = len < length ? len: length;\n\tstringCat (string, s->buffer, len);\n}\n\nextern void vStringNCatS (\n\t\tvString *const string, const char *const s, const size_t length)\n{\n\tsize_t len = strnlen (s, length);\n\n\tstringCat (string, s, len);\n}\n\nextern void vStringNCatSUnsafe (\n\t\tvString *const string, const char *const s, const size_t length)\n{\n\tstringCat (string, s, length);\n}\n\nextern void vStringCat (vString *const string, const vString *const s)\n{\n\tsize_t len = vStringLength (s);\n\n\tstringCat (string, s->buffer, len);\n}\n\nextern void vStringCatS (vString *const string, const char *const s)\n{\n\tsize_t len = strlen (s);\n\n\tstringCat (string, s, len);\n}\n\n/*  Strip trailing newline from string.\n */\nextern bool vStringStripNewline (vString *const string)\n{\n\tconst size_t final = string->length - 1;\n\n\tif (string->length == 0)\n\t\treturn false;\n\n\tif (string->buffer [final] == '\\n')\n\t{\n\t\tstring->buffer [final] = '\\0';\n\t\tstring->length--;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/*  Strip leading white space from string.\n */\nextern void vStringStripLeading (vString *const string)\n{\n\tsize_t n = 0;\n\n\twhile (n < string->length && isspace ((unsigned char) string->buffer [n]))\n\t\tn++;\n\tvStringTruncateLeading (string, n);\n}\n\nextern void vStringTruncateLeading (vString *const string, const size_t length)\n{\n\tsize_t n = vStringLength (string);\n\tif (n > length)\n\t\tn = length;\n\tif (n > 0)\n\t{\n\t\tmemmove (string->buffer, string->buffer + n, string->length - n);\n\t\tvStringTruncate (string, string->length - n);\n\t}\n}\n\n/*  Strip trailing white space from string.\n */\nextern void vStringStripTrailing (vString *const string)\n{\n\twhile (string->length > 0 &&\n\t       isspace ((unsigned char) string->buffer [string->length - 1]))\n\t{\n\t\tstring->length--;\n\t\tstring->buffer [string->length] = '\\0';\n\t}\n}\n\n/*  Chop last character from string.\n */\nextern void vStringChop (vString *const string)\n{\n\tif (string->length > 0)\n\t{\n\t\t--string->length;\n\t\tstring->buffer [string->length] = '\\0';\n\t}\n}\n\nextern void vStringCopy (vString *const string, const vString *const s)\n{\n\tvStringClear (string);\n\tvStringCat (string, s);\n}\n\nextern void vStringCopyS (vString *const string, const char *const s)\n{\n\tvStringClear (string);\n\tvStringCatS (string, s);\n}\n\nextern void vStringNCopy (\n\t\tvString *const string, const vString *const s, const size_t length)\n{\n\tvStringClear (string);\n\tvStringNCat (string, s, length);\n}\n\nextern void vStringNCopyS (\n\t\tvString *const string, const char *const s, const size_t length)\n{\n\tvStringClear (string);\n\tvStringNCatS (string, s, length);\n}\n\nextern void vStringNCopySUnsafe (\n\t\tvString *const string, const char *const s, const size_t length)\n{\n\tvStringClear (string);\n\tvStringNCatSUnsafe (string, s, length);\n}\n\nextern void vStringCopyToLower (vString *const dest, const vString *const src)\n{\n\tconst size_t length = src->length;\n\tconst char *s = src->buffer;\n\tchar *d;\n\tsize_t i;\n\n\tif (dest->size < src->size)\n\t\tvStringResize (dest, src->size);\n\td = dest->buffer;\n\tfor (i = 0  ;  i < length  ;  ++i)\n\t\td [i] = (char) tolower ((unsigned char) s [i]);\n\td [i] = '\\0';\n}\n\nextern void vStringSetLength (vString *const string)\n{\n\tstring->length = strlen (string->buffer);\n}\n\nextern vString *vStringNewOwn (char *s)\n{\n\tvString *r;\n\n\tr = vStringNewInit (s);\n\teFree (s);\n\n\treturn r;\n}\n\nextern char    *vStringDeleteUnwrap       (vString *const string)\n{\n\tchar *buffer = NULL;\n\n\n\tif (string != NULL)\n\t{\n\t\tbuffer = string->buffer;\n\t\tstring->buffer = NULL;\n\n\t\tstring->size = 0;\n\t\tstring->length = 0;\n\n\t\teFree (string);\n\t}\n\n\treturn buffer;\n}\n\nextern char    *vStringStrdup (const vString *const string)\n{\n\tchar *str = xMalloc (vStringLength(string) + 1, char);\n\tstr[vStringLength(string)] = '\\0';\n\tmemcpy (str, string->buffer, vStringLength(string));\n\treturn str;\n}\n\nstatic int valueToXDigit (int v)\n{\n\tAssert (v >= 0 && v <= 0xF);\n\n\tif (v >= 0xA)\n\t\treturn 'A' + (v - 0xA);\n\telse\n\t\treturn '0' + v;\n}\n\nextern void vStringCatSWithEscaping (vString* b, const char *s)\n{\n\tfor(; *s; s++)\n\t{\n\t\tunsigned char c = (unsigned char) *s;\n\n\t\t/* escape control characters (incl. \\t) */\n\t\tif ((c > 0x00 && c <= 0x1F) || c == 0x7F || c == '\\\\')\n\t\t{\n\t\t\tvStringPut (b, '\\\\');\n\n\t\t\tswitch (c)\n\t\t\t{\n\t\t\t\t/* use a short form for known escapes */\n\t\t\tcase '\\a':\n\t\t\t\tc = 'a'; break;\n\t\t\tcase '\\b':\n\t\t\t\tc = 'b'; break;\n\t\t\tcase '\\t':\n\t\t\t\tc = 't'; break;\n\t\t\tcase '\\n':\n\t\t\t\tc = 'n'; break;\n\t\t\tcase '\\v':\n\t\t\t\tc = 'v'; break;\n\t\t\tcase '\\f':\n\t\t\t\tc = 'f'; break;\n\t\t\tcase '\\r':\n\t\t\t\tc = 'r'; break;\n\t\t\tcase '\\\\':\n\t\t\t\tc = '\\\\'; break;\n\t\t\tdefault:\n\t\t\t\tvStringPut (b, 'x');\n\t\t\t\tvStringPut (b, valueToXDigit ((c & 0xF0) >> 4));\n\t\t\t\tvStringPut (b, valueToXDigit (c & 0x0F));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tvStringPut (b, c);\n\t}\n}\n\nextern void vStringCatSWithEscapingAsPattern (vString *output, const char* input)\n{\n\twhile (*input)\n\t{\n\t\tswitch (*input)\n\t\t{\n\t\tcase '\\\\':\n\t\t\tvStringPut(output, '\\\\');\n\t\t\tvStringPut(output, '\\\\');\n\t\t\tbreak;\n\t\tcase '/':\n\t\t\tvStringPut(output, '\\\\');\n\t\t\tvStringPut(output, '/');\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tvStringPut(output, *input);\n\t\t\tbreak;\n\n\t\t}\n\t\tinput++;\n\t}\n}\n\nextern vString *vStringNewOrClear (vString *const string)\n{\n\tif (string)\n\t{\n\t\tvStringClear (string);\n\t\treturn string;\n\t}\n\telse\n\t\treturn vStringNew ();\n}\n\nextern vString *vStringNewOrClearWithAutoRelease (vString *const string)\n{\n\tvString *r;\n\n\tbool autoRelease = false;\n\tif (!string)\n\t\tautoRelease = true;\n\n\tr = vStringNewOrClear(string);\n\tif (autoRelease)\n\t\tDEFAULT_TRASH_BOX(r, vStringDelete);\n\n\treturn r;\n}\n\nextern void vStringTranslate(vString *const string, char fromC, char toC)\n{\n\tfor (unsigned int i = 0; i < vStringLength(string); i++)\n\t{\n\t\tif (string->buffer[i] == fromC)\n\t\t\tstring->buffer[i] = toC;\n\t}\n}\n"
  },
  {
    "path": "main/vstring.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Provides the external interface for resizeable strings.\n*/\n#ifndef CTAGS_MAIN_VSTRING_H\n#define CTAGS_MAIN_VSTRING_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <stdlib.h>  /* to define size_t */\n\n#include <stdio.h>\n\n#include \"debug.h\"\n#include \"inline.h\"\n\n/*\n*   MACROS\n*/\n\n#define vStringValue(vs)      ((vs)->buffer)\n#define vStringChar(vs,i)     ((vs)->buffer[i])\n#define vStringLast(vs)       ((vs)->buffer[(vs)->length - 1])\n#define vStringLastSafe(vs)   ((vs)->length? vStringLast(vs): 0)\n#define vStringLength(vs)     ((vs)->length)\n#define vStringIsEmpty(vs)    ((vs)->length == 0)\n#define vStringSize(vs)       ((vs)->size)\n#define vStringLower(vs)      toLowerString((vs)->buffer)\n#define vStringUpper(vs)      toUpperString((vs)->buffer)\n#define vStringClear(string) \\\n\tdo { \\\n\t\tvString *vStringClear_s = (string); \\\n\t\tvStringClear_s->length = 0; \\\n\t\tvStringClear_s->buffer[0] = '\\0'; \\\n\t} while (false)\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef struct sVString {\n\tsize_t  length;  /* size of buffer used */\n\tsize_t  size;    /* allocated size of buffer */\n\tchar   *buffer;  /* location of buffer */\n} vString;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern void vStringResize (vString *const string, const size_t newSize);\nextern vString *vStringNew (void);\nextern void vStringDelete (vString *const string);\nextern bool vStringStripNewline (vString *const string);\nextern void vStringStripLeading (vString *const string);\nextern void vStringChop (vString *const string);\nextern void vStringStripTrailing (vString *const string);\nextern void vStringCat (vString *const string, const vString *const s);\nextern void vStringCatS (vString *const string, const char *const s);\nextern void vStringNCat (vString *const string, const vString *const s, const size_t length);\n\n/* vStringNCatS calls strnlen(S,LENGTH) though it takes LENGTH because\n * it handles the case that the length of S is smaller than LENGTH.\n *\n * In the case a caller knows the length equals to or is greater than LENGTH,\n * calling strlen is just overhead. vStringNCatSUnsafe doesn't call strlen. */\nextern void vStringNCatS (vString *const string, const char *const s, const size_t length);\nextern void vStringNCatSUnsafe (vString *const string, const char *const s, const size_t length);\n\nextern vString *vStringNewCopy (const vString *const string);\nextern vString *vStringNewInit (const char *const s);\nextern vString *vStringNewNInit (const char *const s, const size_t length);\nextern void vStringCopy (vString *const string, const vString *const s);\nextern void vStringCopyS (vString *const string, const char *const s);\nextern void vStringNCopy (vString *const string, const vString *const s, const size_t length);\nextern void vStringNCopyS (vString *const string, const char *const s, const size_t length);\nextern void vStringNCopySUnsafe (vString *const string, const char *const s, const size_t length);\nextern void vStringCopyToLower (vString *const dest, const vString *const src);\nextern void vStringSetLength (vString *const string);\nextern void vStringTruncate (vString *const string, const size_t length);\n#define vStringTruncateTrailing vStringTruncate\nextern void vStringTruncateLeading (vString *const string, const size_t length);\nextern void vStringTranslate(vString *const string, char fromC, char toC);\n\nextern vString *vStringNewOrClear (vString *const string);\nextern vString *vStringNewOrClearWithAutoRelease (vString *const string);\n\nextern vString *vStringNewOwn (char *s);\nextern char    *vStringDeleteUnwrap (vString *const string);\nextern char    *vStringStrdup (const vString *const string);\n\nextern void vStringCatSWithEscaping (vString* b, const char *s);\nextern void vStringCatSWithEscapingAsPattern (vString *output, const char* input);\n\n/*\n*   INLINE FUNCTIONS\n*/\nCTAGS_INLINE void vStringPutNewlinAgainUnsafe (vString *const string)\n{\n\tstring->buffer [string->length++] = '\\n';\n}\n\nCTAGS_INLINE void vStringPutImpl (vString *const string, const int c)\n{\n\t/* verify the given character is an unsigned char value */\n\tAssert (c >= 0 && c <= 0xff);\n\n\tif (string->length + 1 == string->size)  /*  check for buffer overflow */\n\t\tvStringResize (string, string->size * 2);\n\n\tstring->buffer [string->length] = (char) c;\n\tif (c != '\\0')\n\t\tstring->buffer [++string->length] = '\\0';\n}\n\n#define vStringPut(s, c) (sizeof(c) == sizeof(char) \\\n\t\t\t\t\t\t  ? vStringPutImpl((s), (unsigned char) (c)) \\\n\t\t\t\t\t\t  : vStringPutImpl((s), (c)))\n\nCTAGS_INLINE bool vStringPutWithLimitImpl (vString *const string, const int c,\n\t\t\t\t\t\t\t\t\t\t   unsigned int maxlen)\n{\n\tif (vStringLength (string) < maxlen || maxlen == 0)\n\t{\n\t\tvStringPut (string, c);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n#define vStringPutWithLimit(s, c, l) \\\n\t(sizeof(c) == sizeof(char) \\\n\t ? vStringPutWithLimitImpl((s), (unsigned char) (c), (l)) \\\n\t : vStringPutWithLimitImpl((s), (c), (l)))\n\nCTAGS_INLINE void vStringAccumulate (vString *accumulator, vString *string)\n{\n\tvStringCat (accumulator, string);\n\tvStringClear (string);\n}\n\n#define vStringPutUnlessEmpty(s, c)\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (!vStringIsEmpty(s))\t\t\t\t\t\\\n\t\t\tvStringPut ((s), (c));\t\t\t\t\\\n\t} while (0)\n\n#define vStringJoin(string, c, s) do {\t\t\t\\\n\t\tvStringPutUnlessEmpty ((string), (c));\t\\\n\t\tvStringCat((string), (s));\t\t\t\t\\\n\t} while (0)\n\n#define vStringJoinS(string, c, s) do {\t\t\t\\\n\t\tvStringPutUnlessEmpty ((string), (c));\t\\\n\t\tvStringCatS((string), (s));\t\t\t\t\\\n\t} while (0)\n\n/* If cstrlit is a C string listeral and LTO is enabled,\n * this macro is efficient */\n#define vStringEqC(vstr, cstrlit) ((vStringLength ((vstr)) == strlen ((cstrlit)) \\\n\t\t\t\t\t\t\t\t\t&& strncmp (vStringValue ((vstr)), (cstrlit), strlen ((cstrlit))) == 0))\n#endif  /* CTAGS_MAIN_VSTRING_H */\n"
  },
  {
    "path": "main/writer-ctags.c",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to entry.c\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include \"entry_p.h\"\n#include \"field.h\"\n#include \"field_p.h\"\n#include \"mio.h\"\n#include \"options_p.h\"\n#include \"parse_p.h\"\n#include \"ptag_p.h\"\n#include \"read.h\"\n#include \"writer_p.h\"\n#include \"xtag.h\"\n#include \"xtag_p.h\"\n\n#include <string.h>\n\n#define CTAGS_FILE  \"tags\"\n\n\nstatic int writeCtagsEntry (tagWriter *writer CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\tMIO * mio, const tagEntryInfo *const tag,\n\t\t\t\t\t\t\tvoid *clientData);\nstatic int writeCtagsPtagEntry (tagWriter *writer CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\tMIO * mio, const ptagDesc *desc,\n\t\t\t\t\t\t\t\tconst char *const fileName,\n\t\t\t\t\t\t\t\tconst char *const pattern,\n\t\t\t\t\t\t\t\tconst char *const parserName,\n\t\t\t\t\t\t\t\tvoid *clientData);\nstatic bool treatFieldAsFixed (int fieldType);\nstatic void checkCtagsOptions (tagWriter *writer, bool fieldsWereReset);\n\n#ifdef _WIN32\nstatic enum filenameSepOp overrideFilenameSeparator (enum filenameSepOp currentSetting);\n#endif\t/* _WIN32 */\n\nstruct rejection {\n\tbool rejectionInThisInput;\n};\n\ntagWriter uCtagsWriter = {\n\t.oformat = \"u-ctags\",\n\t.writeEntry = writeCtagsEntry,\n\t.writePtagEntry = writeCtagsPtagEntry,\n\t.printPtagByDefault = true,\n\t.preWriteEntry = NULL,\n\t.postWriteEntry = NULL,\n\t.rescanFailedEntry = NULL,\n\t.treatFieldAsFixed = treatFieldAsFixed,\n\t.checkOptions = checkCtagsOptions,\n\t.canPrintNullTag = false,\n#ifdef _WIN32\n\t.overrideFilenameSeparator = overrideFilenameSeparator,\n#endif\n\t.defaultFileName = CTAGS_FILE,\n};\n\nstatic void *beginECtagsFile (tagWriter *writer CTAGS_ATTR_UNUSED, MIO * mio CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t  void *clientData CTAGS_ATTR_UNUSED)\n{\n\tstatic struct rejection rej;\n\n\trej.rejectionInThisInput = false;\n\n\treturn &rej;\n}\n\nstatic bool endECTagsFile (tagWriter *writer, MIO * mio CTAGS_ATTR_UNUSED, const char* filename CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t   void *clientData CTAGS_ATTR_UNUSED)\n{\n\tstruct rejection *rej = writer->private;\n\treturn rej->rejectionInThisInput;\n}\n\n#ifdef _WIN32\nstatic enum filenameSepOp overrideFilenameSeparator (enum filenameSepOp currentSetting)\n{\n\tif (currentSetting == FILENAME_SEP_UNSET)\n\t\treturn FILENAME_SEP_USE_SLASH;\n\treturn currentSetting;\n}\n#endif\n\ntagWriter eCtagsWriter = {\n\t.oformat = \"e-ctags\",\n\t.writeEntry = writeCtagsEntry,\n\t.writePtagEntry = writeCtagsPtagEntry,\n\t.printPtagByDefault = true,\n\t.preWriteEntry = beginECtagsFile,\n\t.postWriteEntry = endECTagsFile,\n\t.rescanFailedEntry = NULL,\n\t.treatFieldAsFixed = treatFieldAsFixed,\n\t.checkOptions = checkCtagsOptions,\n\t.canPrintNullTag = false,\n\t.defaultFileName = CTAGS_FILE,\n};\n\nstatic bool hasTagEntryTabOrNewlineChar (const tagEntryInfo * const tag)\n{\n\n\tif (doesFieldHaveTabOrNewlineChar (FIELD_NAME, tag, NO_PARSER_FIELD)\n\t\t|| doesFieldHaveTabOrNewlineChar (FIELD_INPUT_FILE, tag, NO_PARSER_FIELD))\n\t\treturn true;\n\n\tif (tag->lineNumberEntry)\n\t{\n\t\tif (Option.lineDirectives)\n\t\t{\n\t\t\tif (doesFieldHaveTabOrNewlineChar (FIELD_LINE_NUMBER, tag, NO_PARSER_FIELD))\n\t\t\t\treturn true;\n\t\t}\n\t}\n\telse if (doesFieldHaveTabOrNewlineChar (FIELD_PATTERN, tag, NO_PARSER_FIELD))\n\t{\n\t\t/* Pattern may have a tab char. However, doesFieldHaveTabOrNewlineChar returns\n\t\t * false because NO_PARSER_FIELD may not have doesContainAnyChar handler.\n\t\t */\n\t\treturn true;\n\t}\n\n\tif (includeExtensionFlags ())\n\t{\n\t\tif (isFieldEnabled (FIELD_SCOPE) && doesFieldHaveValue (FIELD_SCOPE, tag)\n\t\t\t&& (doesFieldHaveTabOrNewlineChar (FIELD_SCOPE_KIND_LONG, tag, NO_PARSER_FIELD)\n\t\t\t\t|| doesFieldHaveTabOrNewlineChar (FIELD_SCOPE, tag, NO_PARSER_FIELD)))\n\t\t\treturn true;\n\t\tif (isFieldEnabled (FIELD_TYPE_REF) && doesFieldHaveValue (FIELD_TYPE_REF, tag)\n\t\t\t&& doesFieldHaveTabOrNewlineChar (FIELD_TYPE_REF, tag, NO_PARSER_FIELD))\n\t\t\treturn true;\n\t\tif (isFieldEnabled (FIELD_FILE_SCOPE) && doesFieldHaveValue (FIELD_FILE_SCOPE, tag)\n\t\t\t&& doesFieldHaveTabOrNewlineChar (FIELD_FILE_SCOPE, tag, NO_PARSER_FIELD))\n\t\t\treturn true;\n\n\t\tint f[] = { FIELD_INHERITANCE,\n\t\t\t\t\tFIELD_ACCESS,\n\t\t\t\t\tFIELD_IMPLEMENTATION,\n\t\t\t\t\tFIELD_SIGNATURE,\n\t\t\t\t\tFIELD_ROLES,\n\t\t\t\t\tFIELD_EXTRAS,\n\t\t\t\t\tFIELD_XPATH,\n\t\t\t\t\tFIELD_END_LINE,\n\t\t\t\t\t-1};\n\t\tfor (unsigned int i = 0; f[i] >= 0; i++)\n\t\t{\n\t\t\tif (isFieldEnabled (f[i]) && doesFieldHaveValue (f[i], tag)\n\t\t\t\t&& doesFieldHaveTabOrNewlineChar (f[i], tag, NO_PARSER_FIELD))\n\t\t\t\treturn true;\n\t\t}\n\t}\n\n\tfor (unsigned int i = 0; i < tag->usedParserFields; i++)\n\t{\n\t\tconst tagField *f = getParserFieldForIndex(tag, i);\n\t\tfieldType ftype = f->ftype;\n\t\tif (isFieldEnabled (ftype))\n\t\t{\n\t\t\tif (doesFieldHaveTabOrNewlineChar (ftype, tag, i))\n\t\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n\nstatic const char* escapeFieldValueFull (tagWriter *writer, const tagEntryInfo * tag, fieldType ftype, int fieldIndex)\n{\n\tconst char *v;\n\tif (writer->type == WRITER_E_CTAGS && doesFieldHaveRenderer(ftype, true))\n\t\tv = renderFieldNoEscaping (ftype, tag, fieldIndex);\n\telse\n\t\tv = renderField (ftype, tag, fieldIndex);\n\n\treturn v;\n}\n\nstatic const char* escapeFieldValue (tagWriter *writer, const tagEntryInfo * tag, fieldType ftype)\n{\n\treturn escapeFieldValueFull (writer, tag, ftype, NO_PARSER_FIELD);\n}\n\nstatic int renderExtensionFieldMaybe (tagWriter *writer, int xftype, const tagEntryInfo *const tag, char sep[2], MIO *mio)\n{\n\tif (isFieldEnabled (xftype) && doesFieldHaveValue (xftype, tag))\n\t{\n\t\tint len;\n\t\tlen = mio_printf (mio, \"%s\\t%s:%s\", sep,\n\t\t\t\t  getFieldName (xftype),\n\t\t\t\t  escapeFieldValue (writer, tag, xftype));\n\t\tsep[0] = '\\0';\n\t\treturn len;\n\t}\n\telse\n\t\treturn 0;\n}\n\nstatic int addParserFields (tagWriter *writer, MIO * mio, const tagEntryInfo *const tag)\n{\n\tunsigned int i;\n\tint length = 0;\n\n\tfor (i = 0; i < tag->usedParserFields; i++)\n\t{\n\t\tconst tagField *f = getParserFieldForIndex(tag, i);\n\t\tfieldType ftype = f->ftype;\n\t\tif (! isFieldEnabled (ftype))\n\t\t\tcontinue;\n\n\t\tunsigned int dt = getFieldDataType (ftype);\n\t\tconst char *val;\n\n\t\tif (dt & FIELDTYPE_STRING)\n\t\t\tval = escapeFieldValueFull (writer, tag, ftype, i);\n\t\telse if (dt & FIELDTYPE_BOOL)\n\t\t\tval = \"\";\n\t\telse if (dt & FIELDTYPE_INTEGER)\n\t\t{\n\t\t\tlong tmp;\n\n\t\t\tval = escapeFieldValueFull (writer, tag, ftype, i);\n\t\t\tif (!strToLong (val, 10, &tmp))\n\t\t\t\tval = (val[0] == '\\0')? \"0\": \"1\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Not implemented */\n\t\t\tAssertNotReached ();\n\t\t\tval = \"CTAGS INTERNAL BUG!\";\n\t\t}\n\n\n\t\tlength += mio_printf(mio, \"\\t%s:%s\",\n\t\t\t\t\t\t\t getFieldName (ftype), val);\n\t}\n\treturn length;\n}\n\nstatic int writeLineNumberEntry (tagWriter *writer, MIO * mio, const tagEntryInfo *const tag)\n{\n\tif (Option.lineDirectives)\n\t\treturn mio_printf (mio, \"%s\", escapeFieldValue (writer, tag, FIELD_LINE_NUMBER));\n\telse\n\t\treturn mio_printf (mio, \"%lu\", tag->lineNumber);\n}\n\nstatic int addExtensionFields (tagWriter *writer, MIO *mio, const tagEntryInfo *const tag)\n{\n\tbool isKindKeyEnabled = isFieldEnabled (FIELD_KIND_KEY);\n\tbool isScopeEnabled = isFieldEnabled   (FIELD_SCOPE_KEY);\n\n\tconst char* const kindKey = isKindKeyEnabled\n\t\t?getFieldName (FIELD_KIND_KEY)\n\t\t:\"\";\n\tconst char* const kindFmt = isKindKeyEnabled\n\t\t?\"%s\\t%s:%s\"\n\t\t:\"%s\\t%s%s\";\n\tconst char* const scopeKey = isScopeEnabled\n\t\t?getFieldName (FIELD_SCOPE_KEY)\n\t\t:\"\";\n\tconst char* const scopeFmt = isScopeEnabled\n\t\t?\"%s\\t%s:%s:%s\"\n\t\t:\"%s\\t%s%s:%s\";\n\n\tchar sep [] = {';', '\"', '\\0'};\n\tint length = 0;\n\n\tconst char *str = NULL;\n\tkindDefinition *kdef = getLanguageKind(tag->langType, tag->kindIndex);\n\tconst char kind_letter_str[2] = {kdef->letter, '\\0'};\n\n\tif (kdef->name != NULL && (isFieldEnabled (FIELD_KIND_LONG)  ||\n\t\t (isFieldEnabled (FIELD_KIND)  && kdef->letter == KIND_NULL_LETTER)))\n\t{\n\t\t/* Use kind long name */\n\t\tstr = kdef->name;\n\t}\n\telse if (kdef->letter != KIND_NULL_LETTER  && (isFieldEnabled (FIELD_KIND) ||\n\t\t\t(isFieldEnabled (FIELD_KIND_LONG) &&  kdef->name == NULL)))\n\t{\n\t\t/* Use kind letter */\n\t\tstr = kind_letter_str;\n\t}\n\n\tif (str)\n\t{\n\t\tlength += mio_printf (mio, kindFmt, sep, kindKey, str);\n\t\tsep [0] = '\\0';\n\t}\n\n\tif (isFieldEnabled (FIELD_LINE_NUMBER) &&  doesFieldHaveValue (FIELD_LINE_NUMBER, tag))\n\t{\n\t\tlength += mio_printf (mio, \"%s\\t%s:%ld\", sep,\n\t\t\t\t   getFieldName (FIELD_LINE_NUMBER),\n\t\t\t\t   tag->lineNumber);\n\t\tsep [0] = '\\0';\n\t}\n\n\tlength += renderExtensionFieldMaybe (writer, FIELD_LANGUAGE, tag, sep, mio);\n\n\tif (isFieldEnabled (FIELD_SCOPE))\n\t{\n\t\tconst char* k, *v;\n\n\t\tk = escapeFieldValue (writer, tag, FIELD_SCOPE_KIND_LONG);\n\t\tv = escapeFieldValue (writer, tag, FIELD_SCOPE);\n\t\tif (k && v)\n\t\t{\n\t\t\tlength += mio_printf (mio, scopeFmt, sep, scopeKey, k, v);\n\t\t\tsep [0] = '\\0';\n\t\t}\n\t}\n\n\tif (isFieldEnabled (FIELD_TYPE_REF) && doesFieldHaveValue (FIELD_TYPE_REF, tag))\n\t{\n\t\tlength += mio_printf (mio, \"%s\\t%s:%s\", sep,\n\t\t\t\t      getFieldName (FIELD_TYPE_REF),\n\t\t\t\t      escapeFieldValue (writer, tag, FIELD_TYPE_REF));\n\t\tsep [0] = '\\0';\n\t}\n\n\tif (isFieldEnabled (FIELD_FILE_SCOPE) &&  doesFieldHaveValue (FIELD_FILE_SCOPE, tag))\n\t{\n\t\tlength += mio_printf (mio, \"%s\\t%s:\", sep,\n\t\t\t\t      getFieldName (FIELD_FILE_SCOPE));\n\t\tsep [0] = '\\0';\n\t}\n\n\tfor (int k = FIELD_ECTAGS_LOOP_START; k <= FIELD_ECTAGS_LOOP_LAST; k++)\n\t\tlength += renderExtensionFieldMaybe (writer, k, tag, sep, mio);\n\tfor (int k = FIELD_UCTAGS_LOOP_START; k <= FIELD_BUILTIN_LAST; k++)\n\t\tlength += renderExtensionFieldMaybe (writer, k, tag, sep, mio);\n\n\treturn length;\n}\n\nstatic int writeCtagsEntry (tagWriter *writer,\n\t\t\t\t\t\t\tMIO * mio, const tagEntryInfo *const tag,\n\t\t\t\t\t\t\tvoid *clientData CTAGS_ATTR_UNUSED)\n{\n\tif (writer->private)\n\t{\n\t\tstruct rejection *rej = writer->private;\n\t\tif (hasTagEntryTabOrNewlineChar (tag))\n\t\t{\n\t\t\trej->rejectionInThisInput = true;\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tint length = mio_printf (mio, \"%s\\t%s\\t\",\n\t\t\t      escapeFieldValue (writer, tag, FIELD_NAME),\n\t\t\t      escapeFieldValue (writer, tag, FIELD_INPUT_FILE));\n\n\t/* This is for handling 'common' of 'fortran'.  See the\n\t   description of --excmd=mixed in ctags.1.  In tags output, what\n\t   we call \"pattern\" is instructions for vi.\n\n\t   However, in the other formats, pattern should be pattern as its name. */\n\tif (tag->lineNumberEntry)\n\t\tlength += writeLineNumberEntry (writer, mio, tag);\n\telse\n\t{\n\t\tif (Option.locate == EX_COMBINE)\n\t\t\tlength += mio_printf(mio, \"%lu;\", tag->lineNumber);\n\t\tlength += mio_puts(mio, escapeFieldValue(writer, tag, FIELD_PATTERN));\n\t}\n\n\tif (includeExtensionFlags ())\n\t{\n\t\tlength += addExtensionFields (writer, mio, tag);\n\t\tlength += addParserFields (writer, mio, tag);\n\t}\n\n\tlength += mio_printf (mio, \"\\n\");\n\n\treturn length;\n}\n\nstatic int writeCtagsPtagEntry (tagWriter *writer,\n\t\t\t\tMIO * mio, const ptagDesc *desc,\n\t\t\t\tconst char *const fileName,\n\t\t\t\tconst char *const pattern,\n\t\t\t\tconst char *const parserName,\n\t\t\t\tvoid *clientData CTAGS_ATTR_UNUSED)\n{\n\n\tbool extras = includeExtensionFlags () && isFieldEnabled (FIELD_EXTRAS);\n\tconst char *xsep = extras? \";\\\"\t\": \"\";\n\tconst char *fsep = extras? \":\": \"\";\n\tconst char *fieldx = extras? getFieldName (FIELD_EXTRAS): \"\";\n\tconst char *xptag = extras? getXtagName (XTAG_PSEUDO_TAGS): \"\";\n\n\t/* Escaping:\n\t *\n\t * NAME:\n\t *    Defined in ctags. As far as we give a good pseudo tag name,\n\t *    we can print the name as is.\n\t *\n\t * parserName:\n\t *    This can be a part of NAME. An optlib can give a\n\t *    parserName but the characters that can be used in the name are\n\t *    limited in [a-zA-Z0-9+#]. We can print the name as is.\n\t *\n\t * fileName:\n\t *    Any characters can be used. Escaping is needed.\n\t *\n\t * pattern:\n\t *    Any characters can be used. Escaping is needed always.\n\t *\n\t * fieldx:\n\t *    No escaping is needed.\n\t *\n\t * xptag:\n\t *    No escaping is needed.\n\t *\n\t */\n\n\tvString *vfileName = vStringNew ();\n\tif (writer->type == WRITER_U_CTAGS\n#ifdef _WIN32\n\t\t&& getFilenameSeparator(Option.useSlashAsFilenameSeparator) == FILENAME_SEP_USE_SLASH\n#endif\n\t\t)\n\t{\n\t\tif (fileName)\n\t\t\tvStringCatSWithEscaping (vfileName, fileName);\n\t}\n\telse if (fileName)\n\t{\n\t\tchar *c = NULL;\n\t\tif ((c = strchr (fileName, '\\t')) || (c = strchr (fileName, '\\n')))\n\t\t{\n\t\t\tvStringDelete (vfileName);\n\t\t\terror (WARNING, \"skip priting %s%s pseudo tag; the input field of the pseudo tag includes a %s character: %s\",\n\t\t\t\t   PSEUDO_TAG_PREFIX, desc->name,\n\t\t\t\t   *c == '\\t'? \"tab\": \"newline\",\n\t\t\t\t   fileName);\n\t\t\treturn 0;\n\t\t}\n\t\tvStringCatS (vfileName, fileName);\n\t}\n\n\tvString *vpattern = vStringNew ();\n\tif (pattern)\n\t\tvStringCatSWithEscapingAsPattern (vpattern, pattern);\n\n\tint r = parserName\n\t\t? mio_printf (mio, \"%s%s%s%s\\t%s\\t/%s/%s%s%s%s\\n\",\n\t\t\t      PSEUDO_TAG_PREFIX, desc->name, PSEUDO_TAG_SEPARATOR, parserName,\n\t\t\t      vStringValue (vfileName), vStringValue (vpattern),\n\t\t\t\t  xsep, fieldx, fsep, xptag)\n\t\t: mio_printf (mio, \"%s%s\\t%s\\t/%s/%s%s%s%s\\n\",\n\t\t\t      PSEUDO_TAG_PREFIX, desc->name,\n\t\t\t      vStringValue (vfileName), vStringValue (vpattern),\n\t\t\t      xsep, fieldx, fsep, xptag);\n\n\tvStringDelete (vpattern);\n\tvStringDelete (vfileName);\n\n\treturn r;\n}\n\nstatic fieldType fixedFields [] = {\n\tFIELD_NAME,\n\tFIELD_INPUT_FILE,\n\tFIELD_PATTERN,\n};\n\nstatic bool treatFieldAsFixed (int fieldType)\n{\n\tfor (int i = 0; i < ARRAY_SIZE(fixedFields); i++)\n\t\tif (fixedFields [i] == fieldType)\n\t\t\treturn true;\n\treturn false;\n}\n\nstatic void checkCtagsOptions (tagWriter *writer CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t   bool fieldsWereReset)\n{\n\tif (isFieldEnabled (FIELD_KIND_KEY)\n\t\t&& (!(isFieldEnabled (FIELD_KIND_LONG) ||\n\t\t\t  isFieldEnabled (FIELD_KIND))))\n\t{\n\t\terror (WARNING, \"though %c/%s field is enabled, neither %c nor %c field is not enabled\",\n\t\t\t   getFieldLetter (FIELD_KIND_KEY),\n\t\t\t   getFieldName (FIELD_KIND_KEY),\n\t\t\t   getFieldLetter (FIELD_KIND),\n\t\t\t   getFieldLetter (FIELD_KIND_LONG));\n\t\terror (WARNING, \"enable the %c field to make the %c/%s field printable\",\n\t\t\t   getFieldLetter (FIELD_KIND_LONG),\n\t\t\t   getFieldLetter (FIELD_KIND_KEY),\n\t\t\t   getFieldName (FIELD_KIND_KEY));\n\t\tenableField (FIELD_KIND_LONG, true);\n\t}\n\tif (isFieldEnabled (FIELD_SCOPE_KEY)\n\t\t&& !isFieldEnabled (FIELD_SCOPE))\n\t{\n\t\terror (WARNING, \"though %c/%s field is enabled, %c field is not enabled\",\n\t\t\t   getFieldLetter (FIELD_SCOPE_KEY),\n\t\t\t   getFieldName (FIELD_SCOPE_KEY),\n\t\t\t   getFieldLetter (FIELD_SCOPE));\n\t\terror (WARNING, \"enable the %c field to make the %c/%s field printable\",\n\t\t\t   getFieldLetter (FIELD_SCOPE),\n\t\t\t   getFieldLetter (FIELD_SCOPE_KEY),\n\t\t\t   getFieldName (FIELD_SCOPE_KEY));\n\t\tenableField (FIELD_SCOPE, true);\n\t}\n\n\tfor (int i = 0; i < ARRAY_SIZE (fixedFields); i++)\n\t{\n\t\tif (!isFieldEnabled (fixedFields [i]))\n\t\t{\n\t\t\tenableField (fixedFields [i], true);\n\n\t\t\tif (fieldsWereReset)\n\t\t\t\tcontinue;\n\n\t\t\tconst char *name = getFieldName (fixedFields [i]);\n\t\t\tunsigned char letter = getFieldLetter (fixedFields [i]);\n\n\t\t\tif (name && letter != NUL_FIELD_LETTER)\n\t\t\t\terror(WARNING, \"Cannot disable fixed field: '%c'{%s} in ctags output mode\",\n\t\t\t\t      letter, name);\n\t\t\telse if (name)\n\t\t\t\terror(WARNING, \"Cannot disable fixed field: {%s} in ctags output mode\",\n\t\t\t\t      name);\n\t\t\telse if (letter != NUL_FIELD_LETTER)\n\t\t\t\terror(WARNING, \"Cannot disable fixed field: '%c' in ctags output mode\",\n\t\t\t\t      letter);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "main/writer-etags.c",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to entry.c\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"mio.h\"\n#include \"options_p.h\"\n#include \"parse.h\"\n#include \"parse_p.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"routines_p.h\"\n#include \"vstring.h\"\n#include \"writer_p.h\"\n\n\n#define ETAGS_FILE  \"TAGS\"\n\n\nstatic int writeEtagsEntry  (tagWriter *writer, MIO * mio, const tagEntryInfo *const tag,\n\t\t\t\t\t\t\t void *clientData CTAGS_ATTR_UNUSED);\nstatic void *beginEtagsFile (tagWriter *writer, MIO * mio,\n\t\t\t\t\t\t\t void *clientData CTAGS_ATTR_UNUSED);\nstatic bool  endEtagsFile   (tagWriter *writer, MIO * mio, const char* filename,\n\t\t\t\t\t\t\t void *clientData CTAGS_ATTR_UNUSED);\n\ntagWriter etagsWriter = {\n\t.oformat = \"etags\",\n\t.writeEntry = writeEtagsEntry,\n\t.writePtagEntry = NULL,\n\t.preWriteEntry = beginEtagsFile,\n\t.postWriteEntry = endEtagsFile,\n\t.rescanFailedEntry = NULL,\n\t.treatFieldAsFixed = NULL,\n\t.defaultFileName = ETAGS_FILE,\n};\n\nstruct sEtags {\n\tchar *name;\n\tMIO *mio;\n\tsize_t byteCount;\n\tvString *vLine;\n};\n\n\n\nstatic void *beginEtagsFile (tagWriter *writer CTAGS_ATTR_UNUSED, MIO *mio CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t void *clientData CTAGS_ATTR_UNUSED)\n{\n\tstatic struct sEtags etags = { NULL, NULL, 0, NULL };\n\n\tetags.mio = tempFile (\"w+b\", &etags.name);\n\tetags.byteCount = 0;\n\tetags.vLine = vStringNew ();\n\treturn &etags;\n}\n\nstatic bool endEtagsFile (tagWriter *writer,\n\t\t\t\t\t\t  MIO *mainfp, const char *filename,\n\t\t\t\t\t\t  void *clientData CTAGS_ATTR_UNUSED)\n{\n\tconst char *line;\n\tstruct sEtags *etags = writer->private;\n\n\tmio_printf (mainfp, \"\\f\\n%s,%ld\\n\", filename, (long) etags->byteCount);\n\tsetNumTagsAdded (numTagsAdded () + 1);\n\tabort_if_ferror (mainfp);\n\n\tif (etags->mio != NULL)\n\t{\n\t\tmio_rewind (etags->mio);\n\n\t\twhile ((line = readLineRaw (etags->vLine, etags->mio)) != NULL)\n\t\t\tmio_puts (mainfp, line);\n\n\t\tvStringDelete (etags->vLine);\n\t\tmio_unref (etags->mio);\n\t\tremove (etags->name);\n\t\teFree (etags->name);\n\t\tetags->vLine = NULL;\n\t\tetags->mio = NULL;\n\t\tetags->name = NULL;\n\t}\n\treturn false;\n}\n\nstatic const char* ada_suffix (const tagEntryInfo *const tag, const char *const line)\n{\n\tkindDefinition *kdef = getLanguageKind(tag->langType, tag->kindIndex);\n\n\tAssert (kdef);\n\n\t/* Mapping from ctags' kind letter to etags's suffix string.\n\t * See https://www.gnu.org/software/emacs/manual/html_node/emacs/Tag-Syntax.html */\n\tswitch (kdef->letter)\n\t{\n\tcase 'p':\n\tcase 'k':\n\t\treturn \"/b\";\n\tcase 'K':\n\t\treturn \"/k\";\n\tcase 'P':\n\t\treturn \"/s\";\n\tcase 't':\n\t\treturn \"/t\";\n\tcase 'R':\n\tcase 'r':\n\t{\n\t\t/* Unlike etags, ctags uses the procedure kind for both\n\t\t * procedures and functions. So in the level, emitting a tag,\n\t\t * we cannot distinguish whether a tag is for a procedureor a\n\t\t * function.\n\t\t *\n\t\t * If the typeref field of the tag is filled, we can say the tag\n\t\t * is for a function. However, Ada parser doesn't implement the\n\t\t * typeref field yet, and implementing it is not so easy.\n\t\t *\n\t\t * So we have to take an unclean way here: scanning the input\n\t\t * line again.\n\t\t * FIXME: remove the scanning code and implement the typeref field\n\t\t * in Ada.\n\t\t */\n\t\tconst char *r = strstr (line, \"return\");\n\t\tconst char *f = strstr (line, \"function\");\n\t\tconst char *p = strstr (line, \"procedure\");\n\t\tif (r && f)\n\t\t\treturn \"/f\";\n\t\telse if (p && !r)\n\t\t\treturn \"/p\";\n\t\treturn \"\";\t\t\t\t/* Unknown */\n\t}\n\tdefault:\n\t\treturn \"\";\n\t}\n}\n\nstatic int writeEtagsEntry (tagWriter *writer,\n\t\t\t\t\t\t\tMIO * mio, const tagEntryInfo *const tag,\n\t\t\t\t\t\t\tvoid *clientData CTAGS_ATTR_UNUSED)\n{\n\tlangType adaLangType = getNamedLanguage (\"Ada\", 0);\n\tAssert (adaLangType != LANG_IGNORE);\n\n\tint length;\n\tstruct sEtags *etags = writer->private;\n\n\tmio = etags->mio;\n\n\tif (tag->isFileEntry)\n\t\tlength = mio_printf (mio, \"\\177%s\\001%lu,0\\n\",\n\t\t\t\ttag->name, tag->lineNumber);\n\telse\n\t{\n\t\tsize_t len;\n\t\tlong seekValue;\n\t\tchar *const line =\n\t\t\t\treadLineFromBypassForTag (etags->vLine, tag, &seekValue);\n\t\tif (line == NULL || line [0] == '\\0')\n\t\t\treturn 0;\n\n\t\tlen = strlen (line);\n\n\t\tif (tag->truncateLineAfterTag)\n\t\t\ttruncateTagLineAfterTag (line, tag->name, true);\n\t\telse if (line [len - 1] == '\\n')\n\t\t\tline [--len] = '\\0';\n\n\t\tif (Option.patternLengthLimit > 0 && Option.patternLengthLimit < len)\n\t\t{\n\t\t\tunsigned int truncationLength = Option.patternLengthLimit;\n\n\t\t\t/* don't cut in the middle of a UTF-8 character, but don't allow\n\t\t\t * for more than one extra character in case it actually wasn't\n\t\t\t * UTF-8.  See also entry.c:appendInputLine() */\n\t\t\twhile (truncationLength < len &&\n\t\t\t       truncationLength < Option.patternLengthLimit + 3 &&\n\t\t\t       (((unsigned char) line[truncationLength]) & 0xc0) == 0x80)\n\t\t\t\ttruncationLength++;\n\n\t\t\tline [truncationLength] = '\\0';\n\t\t}\n\n\t\tlength = mio_printf (mio, \"%s\\177%s%s\\001%lu,%ld\\n\", line,\n\t\t\t\t\t\t\t tag->name,\n\t\t\t\t\t\t\t (tag->langType == adaLangType)\n\t\t\t\t\t\t\t ? ada_suffix (tag, line)\n\t\t\t\t\t\t\t : \"\",\n\t\t\t\t\t\t\t tag->lineNumber, seekValue);\n\t}\n\tetags->byteCount += length;\n\n\treturn length;\n}\n"
  },
  {
    "path": "main/writer-json.c",
    "content": "/*\n*   Copyright (c) 2016, Aman Gupta\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to entry.c\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"field_p.h\"\n#include \"mio.h\"\n#include \"options_p.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"ptag_p.h\"\n#include \"writer_p.h\"\n\n\n#include <string.h>\n\n#ifdef HAVE_JANSSON\n#include <jansson.h>\n\n/* The concept of CURRENT and AGE is taken from libtool.\n * However, we delete REVISION.\n * We will update more CURRENT frequently than the assumption\n * in libtool.\n *\n * If KEYS have been added, removed or changed since last release,\n * increment CURRENT.\n * If they have been added since last release, increment AGE.\n * If they have been removed since last release, set AGE to 0\n */\n#define JSON_WRITER_CURRENT 1\n#define JSON_WRITER_AGE 0\n\n#ifndef json_boolean /* compat with jansson < 2.4 */\n#define json_boolean(val)      ((val) ? json_true() : json_false())\n#endif\n\n\nstatic int writeJsonEntry  (tagWriter *writer CTAGS_ATTR_UNUSED,\n\t\t\t\tMIO * mio, const tagEntryInfo *const tag,\n\t\t\t\tvoid *clientData);\n\nstatic int writeJsonPtagEntry (tagWriter *writer CTAGS_ATTR_UNUSED,\n\t\t\t\tMIO * mio, const ptagDesc *desc,\n\t\t\t\tconst char *const fileName,\n\t\t\t\tconst char *const pattern,\n\t\t\t\tconst char *const parserName,\n\t\t\t\tvoid *clientData);\n\ntagWriter jsonWriter = {\n\t.oformat = \"json\",\n\t.writeEntry = writeJsonEntry,\n\t.writePtagEntry = writeJsonPtagEntry,\n\t.printPtagByDefault = true,\n\t.preWriteEntry = NULL,\n\t.postWriteEntry = NULL,\n\t.rescanFailedEntry = NULL,\n\t.treatFieldAsFixed = NULL,\n\t.canPrintNullTag = true,\n\t.defaultFileName = NULL,\n};\n\nstatic const char* escapeFieldValueRaw (const tagEntryInfo * tag, fieldType ftype, int fieldIndex)\n{\n\tconst char *v;\n\tif (doesFieldHaveRenderer(ftype, true))\n\t\tv = renderFieldNoEscaping (ftype, tag, fieldIndex);\n\telse\n\t\tv = renderField (ftype, tag, fieldIndex);\n\n\treturn v;\n}\n\nstatic json_t* escapeFieldValue (const tagEntryInfo * tag, fieldType ftype, bool returnEmptyStringAsNoValue)\n{\n\tconst char *str = escapeFieldValueRaw (tag, ftype, NO_PARSER_FIELD);\n\n\tif (str)\n\t{\n\t\tunsigned int dt = getFieldDataType(ftype);\n\t\tif (dt & FIELDTYPE_STRING)\n\t\t{\n\t\t\tif (dt & FIELDTYPE_BOOL && str[0] == '\\0')\n\t\t\t\treturn json_false();\n\t\t\telse\n\t\t\t\treturn json_string (str);\n\t\t}\n\t\telse if (dt & FIELDTYPE_INTEGER)\n\t\t{\n\t\t\tlong tmp;\n\n\t\t\tif (strToLong (str, 10, &tmp))\n\t\t\t\treturn json_integer (tmp);\n\t\t\telse\n\t\t\t\treturn NULL;\n\t\t}\n\t\telse if (dt & FIELDTYPE_BOOL)\n\t\t{\n\t\t\t/* TODO: This must be fixed when new boolean field is added.\n\t\t\t   Currently only `file:' field use this. */\n\t\t\treturn json_boolean (strcmp (\"-\", str)); /* \"-\" -> false */\n\t\t}\n\t\tAssertNotReached ();\n\t\treturn NULL;\n\t}\n\telse if (returnEmptyStringAsNoValue)\n\t\treturn json_false();\n\telse\n\t\treturn NULL;\n}\n\nstatic void renderExtensionFieldMaybe (int xftype, const tagEntryInfo *const tag, json_t *response)\n{\n\tconst char *fname = getFieldName (xftype);\n\n\tif (fname && doesFieldHaveRenderer (xftype, false) && isFieldEnabled (xftype) && doesFieldHaveValue (xftype, tag))\n\t{\n\t\tswitch (xftype)\n\t\t{\n\t\tcase FIELD_LINE_NUMBER:\n\t\t\tjson_object_set_new (response, fname,\n\t\t\t\t\t     json_integer (tag->lineNumber));\n\t\t\tbreak;\n\t\tcase FIELD_FILE_SCOPE:\n\t\t\tjson_object_set_new (response, fname,\n\t\t\t\t\t     json_boolean(1));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tjson_object_set_new (response, fname,\n\t\t\t\t\t     escapeFieldValue (tag, xftype, false));\n\t\t}\n\t}\n}\n\nstatic void addParserFields (json_t *response, const tagEntryInfo *const tag)\n{\n\tunsigned int i;\n\n\tfor (i = 0; i < tag->usedParserFields; i++)\n\t{\n\t\tconst tagField *f = getParserFieldForIndex(tag, i);\n\t\tfieldType ftype = f->ftype;\n\t\tif (! isFieldEnabled (ftype))\n\t\t\tcontinue;\n\n\t\tunsigned int dt = getFieldDataType (ftype);\n\t\tjson_t *o;\n\t\tif (dt & FIELDTYPE_STRING)\n\t\t{\n\t\t\tconst char *str = escapeFieldValueRaw (tag, ftype, i);\n\t\t\tif (dt & FIELDTYPE_BOOL && str[0] == '\\0')\n\t\t\t\to = json_false ();\n\t\t\telse\n\t\t\t\to = json_string (str);\n\t\t}\n\t\telse if (dt & FIELDTYPE_INTEGER)\n\t\t{\n\t\t\tconst char *str = escapeFieldValueRaw (tag, ftype, i);\n\t\t\tlong tmp;\n\n\t\t\tif (strToLong (str, 10, &tmp))\n\t\t\t\to = json_integer (tmp);\n\t\t\telse\n\t\t\t\to = json_integer(str[0] == '\\0'? 0: 1);\n\t\t}\n\t\telse if (dt & FIELDTYPE_BOOL)\n\t\t\to = json_true ();\n\t\telse\n\t\t{\n\t\t\tAssertNotReached ();\n\t\t\to = json_null ();\n\t\t}\n\n\t\tjson_object_set_new (response, getFieldName (ftype), o);\n\t}\n}\n\nstatic void addExtensionFields (json_t *response, const tagEntryInfo *const tag)\n{\n\tint k;\n\n\t/* FIELD_KIND has no name; getFieldName (FIELD_KIND) returns NULL.\n\t   FIELD_KIND_LONG does, too.\n\t   That cannot be changed to keep the compatibility of tags file format.\n\t   Use FIELD_KIND_KEY instead */\n\tif (isFieldEnabled (FIELD_KIND) || isFieldEnabled (FIELD_KIND_LONG))\n\t\tenableField (FIELD_KIND_KEY, true);\n\n\t/* FIELD_SCOPE has no name; getFieldName (FIELD_KIND_KEY) returns NULL.\n\t   That cannot be changed to keep the compatibility of tags file format.\n\t   Use FIELD_SCOPE_KEY and FIELD_SCOPE_KIND_LONG instead. */\n\tif (isFieldEnabled (FIELD_SCOPE))\n\t{\n\t\tenableField (FIELD_SCOPE_KEY, true);\n\t\tenableField (FIELD_SCOPE_KIND_LONG, true);\n\t}\n\n\tfor (k = FIELD_JSON_LOOP_START; k <= FIELD_BUILTIN_LAST; k++)\n\t\trenderExtensionFieldMaybe (k, tag, response);\n}\n\nstatic int writeJsonEntry (tagWriter *writer CTAGS_ATTR_UNUSED,\n\t\t\t       MIO * mio, const tagEntryInfo *const tag,\n\t\t\t\t   void *clientData CTAGS_ATTR_UNUSED)\n{\n\tint length = 0;\n\tjson_t *response = json_pack (\"{ss}\", \"_type\", \"tag\");\n\n\tif (isFieldEnabled (FIELD_NAME))\n\t{\n\t\tjson_t *name = json_string (tag->name);\n\t\tif (name == NULL)\n\t\t\tgoto out;\n\t\tjson_object_set_new (response, \"name\", name);\n\t}\n\tif (isFieldEnabled (FIELD_INPUT_FILE))\n\t\tjson_object_set_new (response, \"path\", json_string (tag->sourceFileName));\n\tif (isFieldEnabled (FIELD_PATTERN))\n\t{\n\t\tjson_t *pat = escapeFieldValue(tag, FIELD_PATTERN, true);\n\t\tjson_object_set_new (response, \"pattern\", pat);\n\t}\n\n\tif (includeExtensionFlags ())\n\t{\n\t\taddExtensionFields (response, tag);\n\t\taddParserFields (response, tag);\n\t}\n\n\t/* Print nothing if RESPONSE has only \"_type\" field. */\n\tif (json_object_size (response) == 1)\n\t\tgoto out;\n\n\tchar *buf = json_dumps (response, JSON_PRESERVE_ORDER);\n\tlength = mio_printf (mio, \"%s\\n\", buf);\n\n\tfree (buf);\n out:\n\tjson_decref (response);\n\n\treturn length;\n}\n\nstatic int writeJsonPtagEntry (tagWriter *writer CTAGS_ATTR_UNUSED,\n\t\t\t       MIO * mio, const ptagDesc *desc,\n\t\t\t       const char *const fileName,\n\t\t\t       const char *const pattern,\n\t\t\t       const char *const parserName,\n\t\t\t\t   void *clientData CTAGS_ATTR_UNUSED)\n{\n#define OPT(X) ((X)?(X):\"\")\n\tjson_t *response;\n\tchar *parserName0 = NULL;\n\n\tconst char *rest = ((JSON_WRITER_CURRENT > 0) && parserName && desc->jsonObjectKey)\n\t\t? strchr(parserName, '!')\n\t\t: NULL;\n\tif (rest)\n\t{\n\t\tparserName0 = eStrndup(parserName, rest - parserName);\n\t\tresponse = json_pack (\"{ss ss ss ss ss ss}\",\n\t\t\t\t      \"_type\", \"ptag\",\n\t\t\t\t      \"name\", desc->name,\n\t\t\t\t      \"parserName\", parserName0,\n\t\t\t\t      desc->jsonObjectKey, rest + 1,\n\t\t\t\t      \"path\", OPT(fileName),\n\t\t\t\t      \"pattern\", OPT(pattern));\n\t}\n\telse if (parserName)\n\t{\n\t\tresponse = json_pack (\"{ss ss ss ss ss}\",\n\t\t\t\t      \"_type\", \"ptag\",\n\t\t\t\t      \"name\", desc->name,\n\t\t\t\t      \"parserName\", parserName,\n\t\t\t\t      \"path\", OPT(fileName),\n\t\t\t\t      \"pattern\", OPT(pattern));\n\t}\n\telse\n\t{\n\t\tresponse = json_pack (\"{ss ss ss ss}\",\n\t\t\t\t      \"_type\", \"ptag\",\n\t\t\t\t      \"name\", desc->name,\n\t\t\t\t      \"path\", OPT(fileName),\n\t\t\t\t      \"pattern\", OPT(pattern));\n\t}\n\n\tchar *buf = json_dumps (response, JSON_PRESERVE_ORDER);\n\tint length = mio_printf (mio, \"%s\\n\", buf);\n\tfree (buf);\n\tjson_decref (response);\n\tif (parserName0)\n\t\teFree(parserName0);\n\n\treturn length;\n#undef OPT\n}\n\nextern bool ptagMakeJsonOutputVersion (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t   const void *data CTAGS_ATTR_UNUSED)\n{\n\treturn writePseudoTag (desc,\n\t\t\t       STRINGIFY(JSON_WRITER_CURRENT) \".\" STRINGIFY(JSON_WRITER_AGE),\n\t\t\t       \"in development\",\n\t\t\t       NULL);\n}\n\n#else /* HAVE_JANSSON */\n\ntagWriter jsonWriter = {\n\t.oformat = \"json\",\n\t.writeEntry = NULL,\n\t.writePtagEntry = NULL,\n\t.preWriteEntry = NULL,\n\t.postWriteEntry = NULL,\n\t.defaultFileName = \"-\",\n\t.canPrintNullTag = false,\n};\n\nextern bool ptagMakeJsonOutputVersion (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t   const void *data CTAGS_ATTR_UNUSED)\n{\n\treturn false;\n}\n\n#endif\n"
  },
  {
    "path": "main/writer-xref.c",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to entry.c\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"field_p.h\"\n#include \"fmt_p.h\"\n#include \"mio.h\"\n#include \"options_p.h\"\n#include \"ptag_p.h\"\n#include \"writer_p.h\"\n\n#include <string.h>\n\n\nstatic int writeXrefEntry  (tagWriter *writer CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\tMIO * mio, const tagEntryInfo *const tag,\n\t\t\t\t\t\t\tvoid *clientData CTAGS_ATTR_UNUSED);\nstatic int writeXrefPtagEntry (tagWriter *writer, MIO * mio, const ptagDesc *desc,\n\t\t\t\t\t\t\t   const char *const fileName,\n\t\t\t\t\t\t\t   const char *const pattern,\n\t\t\t\t\t\t\t   const char *const parserName,\n\t\t\t\t\t\t\t   void *clientData);\n\ntagWriter xrefWriter = {\n\t.oformat = \"xref\",\n\t.writeEntry = writeXrefEntry,\n\t.writePtagEntry = writeXrefPtagEntry,\n\t.printPtagByDefault = false,\n\t.preWriteEntry = NULL,\n\t.postWriteEntry = NULL,\n\t.rescanFailedEntry = NULL,\n\t.treatFieldAsFixed = NULL,\n\t.canPrintNullTag = true,\n\t.defaultFileName = NULL,\n};\n\nstatic int writeXrefPtagEntry (tagWriter *writer, MIO * mio, const ptagDesc *desc,\n\t\t\t\t\t\t\t   const char *const fileName,\n\t\t\t\t\t\t\t   const char *const pattern,\n\t\t\t\t\t\t\t   const char *const parserName,\n\t\t\t\t\t\t\t   void *clientData)\n{\n\ttagEntryInfo e;\n\tvString *name = vStringNewInit(PSEUDO_TAG_PREFIX);\n\n\tmemset (&e, 0, sizeof(e));\n\n\te.isPseudoTag = 1;\n\n\tvStringCatS (name, desc->name);\n\tif (parserName)\n\t{\n\t\tvStringCatS (name, PSEUDO_TAG_SEPARATOR);\n\t\tvStringCatS (name, parserName);\n\t}\n\te.name = vStringValue (name);\n\te.inputFileName = fileName;\n\te.pattern = pattern;\n\n\tint length = writeXrefEntry (writer, mio, &e, clientData);\n\n\tvStringDelete (name);\n\n\treturn length;\n}\n\nstatic int writeXrefEntry (tagWriter *writer CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t   MIO * mio, const tagEntryInfo *const tag,\n\t\t\t\t\t\t   void *clientData CTAGS_ATTR_UNUSED)\n{\n\tint length;\n\tstatic fmtElement *fmt1;\n\tstatic fmtElement *fmt2;\n\n\tif (Option.customXfmt)\n\t\tlength = fmtPrint (Option.customXfmt, mio, tag);\n\telse\n\t{\n\t\tif (tag->isFileEntry)\n\t\t\treturn 0;\n\n\t\tif (Option.tagFileFormat == 1)\n\t\t{\n\t\t\tif (fmt1 == NULL)\n\t\t\t\tfmt1 = fmtNew (\"%-16N %4n %-16F %C\");\n\t\t\tlength = fmtPrint (fmt1, mio, tag);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (fmt2 == NULL)\n\t\t\t\tfmt2 = fmtNew (\"%-16N %-10K %4n %-16F %C\");\n\t\t\tlength = fmtPrint (fmt2, mio, tag);\n\t\t}\n\t}\n\n\tmio_putc (mio, '\\n');\n\tlength++;\n\n\treturn length;\n}\n"
  },
  {
    "path": "main/writer.c",
    "content": "/*\n*   Copyright (c) 2016, Red Hat, Inc.\n*   Copyright (c) 2016, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n\n#include \"general.h\"\n\n#include \"colprint_p.h\"\n#include \"debug.h\"\n#include \"entry_p.h\"\n#include \"options_p.h\"\n#include \"writer_p.h\"\n\n#include <string.h>\n\nextern tagWriter uCtagsWriter;\nextern tagWriter eCtagsWriter;\nextern tagWriter etagsWriter;\nextern tagWriter xrefWriter;\n#ifdef HAVE_JANSSON\nextern tagWriter jsonWriter;\n#endif\n\nstatic tagWriter *writerTable [WRITER_COUNT] = {\n\t[WRITER_U_CTAGS] = &uCtagsWriter,\n\t[WRITER_E_CTAGS] = &eCtagsWriter,\n\t[WRITER_ETAGS] = &etagsWriter,\n\t[WRITER_XREF]  = &xrefWriter,\n#ifdef HAVE_JANSSON\n\t[WRITER_JSON]  = &jsonWriter,\n#endif\n\t[WRITER_CUSTOM] = NULL,\n};\n\nstatic tagWriter *writer;\n\nextern void setTagWriter (writerType wtype, tagWriter *customWriter)\n{\n\tif (wtype != WRITER_CUSTOM)\n\t\twriter = writerTable [wtype];\n\telse\n\t\twriter = customWriter;\n\twriter->type = wtype;\n}\n\nextern void writerSetup (MIO *mio, void *clientData)\n{\n\twriter->clientData = clientData;\n\n\tif (writer->preWriteEntry)\n\t\twriter->private = writer->preWriteEntry (writer, mio,\n\t\t\t\t\t\t\t\t\t\t\t\t writer->clientData);\n\telse\n\t\twriter->private = NULL;\n}\n\nextern bool writerTeardown (MIO *mio, const char *filename)\n{\n\tif (writer->postWriteEntry)\n\t{\n\t\tbool r;\n\t\tr = writer->postWriteEntry (writer, mio, filename,\n\t\t\t\t\t\t\t\t\twriter->clientData);\n\t\twriter->private = NULL;\n\t\treturn r;\n\t}\n\treturn false;\n}\n\nextern int writerWriteTag (MIO * mio, const tagEntryInfo *const tag)\n{\n\treturn writer->writeEntry (writer, mio, tag,\n\t\t\t\t\t\t\t   writer->clientData);\n}\n\nextern int writerWritePtag (MIO * mio,\n\t\t\t\t\t const ptagDesc *desc,\n\t\t\t\t\t const char *const fileName,\n\t\t\t\t\t const char *const pattern,\n\t\t\t\t\t const char *const parserName)\n{\n\tif (writer->writePtagEntry == NULL)\n\t\treturn -1;\n\n\treturn writer->writePtagEntry (writer, mio, desc, fileName,\n\t\t\t\t\t\t\t\t   pattern, parserName,\n\t\t\t\t\t\t\t\t   writer->clientData);\n\n}\n\nextern void writerRescanFailed (unsigned long validTagNum)\n{\n\tif (writer->rescanFailedEntry)\n\t\twriter->rescanFailedEntry(writer, validTagNum, writer->clientData);\n}\n\nextern bool ptagMakeCtagsOutputMode (ptagDesc *desc, langType langType CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t const void *data CTAGS_ATTR_UNUSED)\n{\n\tconst char *mode =\"\";\n\n\tif (&uCtagsWriter == writer)\n\t\tmode = \"u-ctags\";\n\telse if (&eCtagsWriter == writer)\n\t\tmode = \"e-ctags\";\n\n\treturn writePseudoTag (desc,\n\t\t\t\t\t\t   mode,\n\t\t\t\t\t\t   \"u-ctags or e-ctags\",\n\t\t\t\t\t\t   NULL);\n}\n\nextern const char *outputDefaultFileName (void)\n{\n\treturn writer->defaultFileName;\n}\n\nextern bool writerCanPrintPtag (void)\n{\n\treturn (writer->writePtagEntry)? true: false;\n}\n\nextern bool writerCanPrintNullTag (void)\n{\n\treturn writer->canPrintNullTag;\n}\nextern bool writerDoesTreatFieldAsFixed (int fieldType)\n{\n\tif (writer->treatFieldAsFixed)\n\t\treturn writer->treatFieldAsFixed (fieldType);\n\treturn false;\n}\n\n#ifdef _WIN32\nextern enum filenameSepOp getFilenameSeparator (enum filenameSepOp currentSetting)\n{\n\tif (writer->overrideFilenameSeparator)\n\t\treturn writer->overrideFilenameSeparator (currentSetting);\n\treturn currentSetting;\n}\n#endif\n\nextern bool ptagMakeCtagsOutputFilesep (ptagDesc *desc,\n\t\t\t\t\t\t\t\t\t\tlangType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\tconst void *data)\n{\n\tconst char *sep = \"slash\";\n#ifdef _WIN32\n\tconst optionValues *opt = data;\n\tif (getFilenameSeparator (opt->useSlashAsFilenameSeparator)\n\t\t!= FILENAME_SEP_USE_SLASH)\n\t\tsep = \"backslash\";\n#endif\n\treturn writePseudoTag (desc, sep, \"slash or backslash\", NULL);\n}\n\nextern bool ptagMakeCtagsOutputExcmd (ptagDesc *desc,\n\t\t\t\t\t\t\t\t\t  langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t  const void *data)\n{\n\tconst char *excmd;\n\tconst optionValues *opt = data;\n\tswitch (opt->locate)\n\t{\n\tcase EX_MIX:\n\t\texcmd = \"mixed\";\n\t\tbreak;\n\tcase EX_LINENUM:\n\t\texcmd = \"number\";\n\t\tbreak;\n\tcase EX_PATTERN:\n\t\texcmd = \"pattern\";\n\t\tbreak;\n\tcase EX_COMBINE:\n\t\texcmd = \"combineV2\";\n\t\tbreak;\n\tdefault:\n\t\tAssertNotReached ();\n\t\texcmd = \"bug!\";\n\t\tbreak;\n\t}\n\treturn writePseudoTag (desc, excmd,\n\t\t\t\t\t\t   \"number, pattern, mixed, or combineV2\",\n\t\t\t\t\t\t   NULL);\n}\n\nextern void writerCheckOptions (bool fieldsWereReset)\n{\n\tif (writer->checkOptions)\n\t\twriter->checkOptions (writer, fieldsWereReset);\n}\n\nextern bool writerPrintPtagByDefault (void)\n{\n\treturn writer->printPtagByDefault;\n}\n\nextern writerType getWrierForOutputFormat (const char *oformat)\n{\n\tfor (int i = 0; i < WRITER_CUSTOM; i++)\n\t{\n\t\tif (writerTable[i]->oformat == NULL)\n\t\t\tcontinue;\n\n\t\tif (strcmp(writerTable[i]->oformat, oformat) == 0)\n\t\t{\n\t\t\tif (writerTable[i]->writeEntry == NULL)\n\t\t\t\treturn WRITER_UNAVAILABLE;\n\t\t\telse\n\t\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn WRITER_UNKNOWN;\n}\n\n#define WRITER_COL_OFORMAT 0\n#define WRITER_COL_AVAILABLE 1\n#define WRITER_COL_NULLTAG 2\n\nstatic int writerColprintCompareLines (struct colprintLine *a , struct colprintLine *b)\n{\n\tconst char *a_oformat  = colprintLineGetColumn (a, WRITER_COL_OFORMAT);\n\tconst char *b_oformat  = colprintLineGetColumn (b, WRITER_COL_OFORMAT);\n\n\treturn strcmp(a_oformat, b_oformat);\n}\n\nextern struct colprintTable * writerColprintTableNew (void)\n{\n\treturn colprintTableNew (\"L:OFORMAT\", \"R:DEFAULT\", \"R:AVAILABLE\", \"R:NULLTAG\", NULL);\n}\n\nextern void printOutputFormats (bool withListHeader, bool machinable, FILE *fp)\n{\n\tstruct colprintTable * table = writerColprintTableNew ();\n\n\tfor (int i = 0; i < WRITER_COUNT; i++)\n\t{\n\t\tif (!writerTable[i])\n\t\t\tcontinue;\n\t\tif (!writerTable[i]->oformat)\n\t\t\tcontinue;\n\n\t\tstruct colprintLine * line = colprintTableGetNewLine (table);\n\t\tcolprintLineAppendColumnCString (line, writerTable[i]->oformat);\n\n\t\tcolprintLineAppendColumnBool (line, i == WRITER_DEFAULT);\n\t\tcolprintLineAppendColumnBool (line, writerTable[i]->writeEntry? true: false);\n\t\tcolprintLineAppendColumnBool (line, writerTable[i]->canPrintNullTag);\n\t}\n\n\tcolprintTableSort (table, writerColprintCompareLines);\n\tcolprintTablePrint (table, 0, withListHeader, machinable, fp);\n\tcolprintTableDelete (table);\n}\n"
  },
  {
    "path": "main/writer_p.h",
    "content": "/*\n*   Copyright (c) 2016, Red Hat, Inc.\n*   Copyright (c) 2016, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n#ifndef CTAGS_MAIN_WRITER_PRIVATE_H\n#define CTAGS_MAIN_WRITER_PRIVATE_H\n\n#include \"general.h\"  /* must always come first */\n#include \"mio.h\"\n#include \"options_p.h\"\n#include \"types.h\"\n\n/* Other than writeEntry can be NULL.\n   The value returned from preWriteEntry is passed to writeEntry,\n   and postWriteEntry. If a resource is allocated in\n   preWriteEntry, postWriteEntry should free it. */\n\ntypedef enum eWriterType {\n\tWRITER_UNAVAILABLE = -2,\t/* Defined but no implementation. */\n\tWRITER_UNKNOWN = -1,\n\tWRITER_DEFAULT,\n\tWRITER_U_CTAGS = WRITER_DEFAULT,\n\tWRITER_E_CTAGS,\n\tWRITER_ETAGS,\n\tWRITER_XREF,\n#ifdef HAVE_JANSSON\n\tWRITER_JSON,\n#endif\n\tWRITER_CUSTOM,\n\tWRITER_COUNT,\n} writerType;\n\nstruct sTagWriter;\ntypedef struct sTagWriter tagWriter;\nstruct sTagWriter {\n\tconst char *oformat;\t\t/* name used in CLI: --output-format=\n\t\t\t\t\t\t\t\t * NULL is acceptable.*/\n\tint (* writeEntry) (tagWriter *writer, MIO * mio, const tagEntryInfo *const tag,\n\t\t\t\t\t\tvoid *clientData);\n\tint (* writePtagEntry) (tagWriter *writer, MIO * mio, const ptagDesc *desc,\n\t\t\t\t\t\t\tconst char *const fileName,\n\t\t\t\t\t\t\tconst char *const pattern,\n\t\t\t\t\t\t\tconst char *const parserName,\n\t\t\t\t\t\t\tvoid *clientData);\n\tbool printPtagByDefault;\n\tvoid * (* preWriteEntry) (tagWriter *writer, MIO * mio,\n\t\t\t\t\t\t\t  void *clientData);\n\n\t/* Returning TRUE means the output file may be shrunk.\n\t   In such case the callee may do truncate output file. */\n\tbool (* postWriteEntry)  (tagWriter *writer, MIO * mio, const char* filename,\n\t\t\t\t\t\t\t  void *clientData);\n\tvoid (* rescanFailedEntry) (tagWriter *writer, unsigned long validTagNum,\n\t\t\t\t\t\t\t\tvoid *clientData);\n\tbool (* treatFieldAsFixed) (int fieldType);\n\n\tvoid (* checkOptions) (tagWriter *writer, bool fieldsWereReset);\n\n\tbool canPrintNullTag;\n\n#ifdef _WIN32\n\tenum filenameSepOp (* overrideFilenameSeparator) (enum filenameSepOp currentSetting);\n#endif\t/* _WIN32 */\n\n\tconst char *defaultFileName;\n\n\t/* The value returned from preWriteEntry is stored `private' field.\n\t   The value must be released in postWriteEntry. */\n\tvoid *private;\n\twriterType type;\n\t/* The value passed as the second argument for writerSetup iss\n\t * stored here. Unlink `private' field, ctags does nothing more. */\n\tvoid *clientData;\n};\n\n/* customWriter is used only if otype is WRITER_CUSTOM */\nextern void setTagWriter (writerType otype, tagWriter *customWriter);\nextern void writerSetup  (MIO *mio, void *clientData);\nextern bool writerTeardown (MIO *mio, const char *filename);\n\nint writerWriteTag (MIO * mio, const tagEntryInfo *const tag);\nint writerWritePtag (MIO * mio,\n\t\t\t\t\t const ptagDesc *desc,\n\t\t\t\t\t const char *const fileName,\n\t\t\t\t\t const char *const pattern,\n\t\t\t\t\t const char *const parserName);\n\nvoid writerRescanFailed (unsigned long validTagNum);\n\nextern const char *outputDefaultFileName (void);\n\nextern size_t truncateTagLineAfterTag (char *const line, const char *const token,\n\t\t\t     const bool discardNewline);\nextern void abort_if_ferror(MIO *const fp);\n\nextern bool ptagMakeJsonOutputVersion (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED, const void *data CTAGS_ATTR_UNUSED);\nextern bool ptagMakeCtagsOutputMode (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED, const void *data CTAGS_ATTR_UNUSED);\nextern bool ptagMakeCtagsOutputFilesep (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED, const void *data);\nextern bool ptagMakeCtagsOutputExcmd (ptagDesc *desc, langType language CTAGS_ATTR_UNUSED, const void *data);\n\nextern bool writerCanPrintPtag (void);\nextern bool writerCanPrintNullTag (void);\nextern bool writerDoesTreatFieldAsFixed (int fieldType);\n\nextern void writerCheckOptions (bool fieldsWereReset);\nextern bool writerPrintPtagByDefault (void);\n\nextern writerType getWrierForOutputFormat (const char *oformat);\nextern void printOutputFormats (bool withListHeader, bool machinable, FILE *fp);\n\n#ifdef _WIN32\nextern enum filenameSepOp getFilenameSeparator (enum filenameSepOp currentSetting);\n#endif\t/* _WIN32 */\n#endif\t/* CTAGS_MAIN_WRITER_PRIVATE_H */\n"
  },
  {
    "path": "main/xtag.c",
    "content": "/*\n *\n *  Copyright (c) 2015, Red Hat, Inc.\n *  Copyright (c) 2015, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#include \"general.h\"  /* must always come first */\n#include \"ctags.h\"\n#include \"debug.h\"\n#include \"options.h\"\n#include \"options_p.h\"\n#include \"parse_p.h\"\n#include \"routines.h\"\n#include \"trashbox.h\"\n#include \"writer_p.h\"\n#include \"xtag.h\"\n#include \"xtag_p.h\"\n\n#include <string.h>\n#include <ctype.h>\n\ntypedef struct sXtagObject {\n\txtagDefinition *def;\n\tlangType language;\n\txtagType sibling;\n} xtagObject;\n\nstatic bool isPseudoTagsEnabled (xtagDefinition *pdef CTAGS_ATTR_UNUSED)\n{\n\tif (!writerCanPrintPtag())\n\t\treturn false;\n\tif (!writerPrintPtagByDefault())\n\t\treturn false;\n\n\treturn ! isDestinationStdout ();\n}\n\nstatic bool isPseudoTagsFixed (xtagDefinition *pdef CTAGS_ATTR_UNUSED)\n{\n\tif (!writerCanPrintPtag())\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nstatic void enableFileKind (xtagDefinition *pdef, bool state)\n{\n\tenableDefaultFileKind(state);\n\tpdef->enabled = state;\n}\n\nstatic xtagDefinition xtagDefinitions [] = {\n\t{ true, 'F',  \"fileScope\",\n\t  \"Include tags of file scope\" },\n\t{ false, 'f', \"inputFile\",\n\t  \"Include an entry for the base file name of every input file\",\n\t  NULL,\n\t  NULL,\n\t  enableFileKind},\n\t{ false, 'p', \"pseudo\",\n\t  \"Include pseudo tags\",\n\t  isPseudoTagsEnabled,\n\t  isPseudoTagsFixed},\n\t{ false, 'q', \"qualified\",\n\t  \"Include an extra class-qualified tag entry for each tag\"},\n\t{ false, 'r', \"reference\",\n\t  \"Include reference tags\"},\n\t{ false, 'g', \"guest\",\n\t  \"Include tags generated by guest parsers\"},\n\t{ true, 's', \"subparser\",\n\t  \"Include tags generated by subparsers\"},\n\t{ true, '\\0', \"anonymous\",\n\t  \"Include tags for non-named objects like lambda\"},\n\t{ false, 'z', \"nulltag\",\n\t  \"Include tags with empty strings as their names\",\n\t  .version = 1, },\n};\n\nstatic unsigned int       xtagObjectUsed;\nstatic unsigned int       xtagObjectAllocated;\nstatic xtagObject* xtagObjects;\n\nstatic xtagObject* getXtagObject (xtagType type)\n{\n\tAssert ((0 <= type) && ((unsigned int)type < xtagObjectUsed));\n\treturn (xtagObjects + type);\n}\n\nextern xtagDefinition* getXtagDefinition (xtagType type)\n{\n\tAssert ((0 <= type) && ((unsigned int)type < xtagObjectUsed));\n\n\treturn getXtagObject (type)->def;\n}\n\ntypedef bool (* xtagPredicate) (xtagObject *pobj, langType language, const void *user_data);\nstatic xtagType  getXtagTypeGeneric (xtagPredicate predicate, langType language, const void *user_data)\n{\n\tstatic bool initialized = false;\n\tunsigned int i;\n\n\tif (language == LANG_AUTO && (initialized == false))\n\t{\n\t\tinitialized = true;\n\t\tinitializeParser (LANG_AUTO);\n\t}\n\telse if (language != LANG_IGNORE && (initialized == false))\n\t\tinitializeParser (language);\n\n\tfor (i = 0; i < xtagObjectUsed; i++)\n\t{\n\t\tif (predicate (xtagObjects + i, language, user_data))\n\t\t\treturn i;\n\t}\n\treturn XTAG_UNKNOWN;\n}\n\nstatic bool xtagEqualByLetter (xtagObject *pobj, langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t   const void *user_data)\n{\n\treturn (pobj->def->letter == *((char *)user_data))? true: false;\n}\n\nextern xtagType  getXtagTypeForLetter (char letter)\n{\n\treturn getXtagTypeGeneric (xtagEqualByLetter, LANG_IGNORE, &letter);\n}\n\nstatic bool xtagEqualByNameAndLanguage (xtagObject *pobj, langType language, const void *user_data)\n{\n\tconst char* name = user_data;\n\n\tif ((language == LANG_AUTO || pobj->language == language)\n\t\t&& (strcmp (pobj->def->name, name) == 0))\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nextern xtagType  getXtagTypeForNameAndLanguage (const char *name, langType language)\n{\n\treturn getXtagTypeGeneric (xtagEqualByNameAndLanguage, language, name);\n}\n\nextern struct colprintTable * xtagColprintTableNew (void)\n{\n\treturn colprintTableNew (\"L:LETTER\", \"L:NAME\", \"L:ENABLED\",\n\t\t\t\t\t\t\t \"L:LANGUAGE\", \"L:FIXED\", \"R:VER\", \"L:DESCRIPTION\", NULL);\n}\n\nstatic void  xtagColprintAddLine (struct colprintTable *table, int xtype)\n{\n\txtagObject* xobj = getXtagObject (xtype);\n\txtagDefinition *xdef = xobj->def;\n\n\tstruct colprintLine *line = colprintTableGetNewLine(table);\n\n\tcolprintLineAppendColumnChar (line,\n\t\t\t\t\t\t\t\t  (xdef->letter == NUL_XTAG_LETTER)\n\t\t\t\t\t\t\t\t  ? '-'\n\t\t\t\t\t\t\t\t  : xdef->letter);\n\tcolprintLineAppendColumnCString (line, xdef->name);\n\tcolprintLineAppendColumnBool (line, isXtagEnabled(xdef->xtype));\n\tcolprintLineAppendColumnCString (line,\n\t\t\t\t\t\t\t\t\t xobj->language == LANG_IGNORE\n\t\t\t\t\t\t\t\t\t ? RSV_NONE\n\t\t\t\t\t\t\t\t\t : getLanguageName (xobj->language));\n\tcolprintLineAppendColumnBool (line, isXtagFixed(xdef->xtype));\n\tcolprintLineAppendColumnVersion (line, xdef->version);\n\tcolprintLineAppendColumnCString (line, xdef->description);\n}\n\nextern void xtagColprintAddCommonLines (struct colprintTable *table)\n{\n\tfor (int i = 0; i < XTAG_COUNT; i++)\n\t\txtagColprintAddLine (table, i);\n}\n\nextern void xtagColprintAddLanguageLines (struct colprintTable *table, langType language)\n{\n\tfor (unsigned int i = XTAG_COUNT; i < xtagObjectUsed; i++)\n\t{\n\t\txtagObject* xobj = getXtagObject (i);\n\n\t\tif (xobj->language == language)\n\t\t\txtagColprintAddLine (table, i);\n\t}\n}\n\nstatic int xtagColprintCompareLines (struct colprintLine *a , struct colprintLine *b)\n{\n\tconst char *a_parser = colprintLineGetColumn (a, 3);\n\tconst char *b_parser = colprintLineGetColumn (b, 3);\n\n\tif (strcmp (a_parser, RSV_NONE) == 0\n\t\t&& strcmp (b_parser, RSV_NONE) != 0)\n\t\treturn -1;\n\telse if (strcmp (a_parser, RSV_NONE) != 0\n\t\t\t && strcmp (b_parser, RSV_NONE) == 0)\n\t\treturn 1;\n\telse if (strcmp (a_parser, RSV_NONE) != 0\n\t\t\t && strcmp (b_parser, RSV_NONE) != 0)\n\t{\n\t\tint r;\n\t\tr = strcmp (a_parser, b_parser);\n\t\tif (r != 0)\n\t\t\treturn r;\n\t}\n\telse\n\t{\n\t\tint r;\n\n\t\tconst char *a_letter = colprintLineGetColumn (a, 0);\n\t\tconst char *b_letter = colprintLineGetColumn (b, 0);\n\t\tr = strcmp(a_letter, b_letter);\n\t\tif (r != 0)\n\t\t\treturn r;\n\t}\n\n\tconst char *a_name = colprintLineGetColumn (a, 1);\n\tconst char *b_name = colprintLineGetColumn (b, 1);\n\n\treturn strcmp(a_name, b_name);\n}\n\nextern void xtagColprintTablePrint (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp)\n{\n\tcolprintTableSort (table, xtagColprintCompareLines);\n\tcolprintTablePrint (table, 0, withListHeader, machinable, fp);\n}\n\nextern bool isXtagEnabled (xtagType type)\n{\n\txtagDefinition* def = getXtagDefinition (type);\n\n\tAssert (def);\n\n\tif (def->isEnabled)\n\t\treturn def->isEnabled (def);\n\telse\n\t\treturn def->enabled;\n}\n\nextern bool isXtagFixed (xtagType type)\n{\n\txtagDefinition* def = getXtagDefinition (type);\n\n\tAssert (def);\n\n\tif (def->isFixed)\n\t\treturn def->isFixed (def);\n\n\treturn false;\n}\n\nextern bool enableXtag (xtagType type, bool state)\n{\n\tbool old;\n\txtagDefinition* def = getXtagDefinition (type);\n\n\tAssert (def);\n\n\told = isXtagEnabled (type);\n\n\tif (isXtagFixed(type))\n\t\tdef->enabled = old;\n\telse if (def->enable)\n\t\tdef->enable (def, state);\n\telse\n\t\tdef->enabled = state;\n\n\tdef->isEnabled = NULL;\n\n\treturn old;\n}\n\nextern bool isCommonXtag (xtagType type)\n{\n\treturn (type < XTAG_COUNT)? true: false;\n}\n\nextern langType getXtagLanguage (xtagType type)\n{\n\treturn getXtagObject (type)->language;\n}\n\nextern const char* getXtagName (xtagType type)\n{\n\txtagDefinition* def = getXtagDefinition (type);\n\tif (def)\n\t\treturn def->name;\n\telse\n\t\treturn NULL;\n}\n\nextern const char* getXtagDescription (xtagType type)\n{\n\txtagDefinition* def = getXtagDefinition (type);\n\tif (def)\n\t\treturn def->description;\n\telse\n\t\treturn NULL;\n}\n\nextern void initXtagObjects (void)\n{\n\txtagObject *xobj;\n\n\txtagObjectAllocated = ARRAY_SIZE (xtagDefinitions);\n\txtagObjects = xMalloc (xtagObjectAllocated, xtagObject);\n\tDEFAULT_TRASH_BOX(&xtagObjects, eFreeIndirect);\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE (xtagDefinitions); i++)\n\t{\n\t\txobj = xtagObjects + i;\n\t\txobj->def = xtagDefinitions + i;\n\t\txobj->def->xtype = i;\n\t\txobj->language = LANG_IGNORE;\n\t\txobj->sibling = XTAG_UNKNOWN;\n\t\txtagObjectUsed++;\n\t}\n}\n\nextern unsigned int countXtags (void)\n{\n\treturn xtagObjectUsed;\n}\n\nstatic void updateSiblingXtag (xtagType type, const char* name)\n{\n\tint i;\n\txtagObject *xobj;\n\n\tfor (i = type; i > 0; i--)\n\t{\n\t\txobj = xtagObjects + i - 1;\n\t\tif (xobj->def->name && (strcmp (xobj->def->name, name) == 0))\n\t\t{\n\t\t\tAssert (xobj->sibling == XTAG_UNKNOWN);\n\t\t\txobj->sibling = type;\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nextern int defineXtag (xtagDefinition *def, langType language)\n{\n\txtagObject *xobj;\n\tsize_t i;\n\n\tAssert (def);\n\tAssert (def->name);\n\tfor (i = 0; i < strlen (def->name); i++)\n\t{\n\t\tAssert ( isalnum ((unsigned char) def->name [i]) );\n\t}\n\tdef->letter = NUL_XTAG_LETTER;\n\n\tif (xtagObjectUsed == xtagObjectAllocated)\n\t{\n\t\txtagObjectAllocated *= 2;\n\t\txtagObjects = xRealloc (xtagObjects, xtagObjectAllocated, xtagObject);\n\t}\n\txobj = xtagObjects + (xtagObjectUsed);\n\tdef->xtype = xtagObjectUsed++;\n\txobj->def = def;\n\txobj->language = language;\n\txobj->sibling  = XTAG_UNKNOWN;\n\n\tupdateSiblingXtag (def->xtype, def->name);\n\n\tverbose (\"Add extra[%d]: %s,%s in %s\\n\",\n\t\t\t def->xtype,\n\t\t\t def->name, def->description,\n\t\t\t getLanguageName (language));\n\n\tif (def->version > getLanguageVersionCurrent (language))\n\t\terror (WARNING, \"the version number (%u) of extra \\\"%s\\\" of language \\\"%s\\\" \"\n\t\t\t   \"should be less than or equal to the current number (%u) of the language\",\n\t\t\t   def->version, def->name, getLanguageName (language),\n\t\t\t   getLanguageVersionCurrent (language));\n\n\treturn def->xtype;\n}\n\nextern xtagType nextSiblingXtag (xtagType type)\n{\n\txtagObject *xobj;\n\n\txobj = xtagObjects + type;\n\treturn xobj->sibling;\n}\n"
  },
  {
    "path": "main/xtag.h",
    "content": "/*\n *\n *  Copyright (c) 2015, Red Hat, Inc.\n *  Copyright (c) 2015, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_XTAG_H\n#define CTAGS_MAIN_XTAG_H\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef enum eXtagType { /* extra tag content control */\n\tXTAG_UNKNOWN = -1,\n\n\tXTAG_FILE_SCOPE,\n\tXTAG_FILE_NAMES,\n\tXTAG_PSEUDO_TAGS,\n\tXTAG_QUALIFIED_TAGS,\n\tXTAG_REFERENCE_TAGS,\n\tXTAG_GUEST,\n\tXTAG_TAGS_GENERATED_BY_GUEST_PARSERS = XTAG_GUEST, /* Geany uses the old name */\n\tXTAG_SUBPARSER,\n\tXTAG_ANONYMOUS,\n\tXTAG_NULLTAG,\n\n\tXTAG_COUNT\n} xtagType;\n\nstruct sXtagDefinition {\n\tbool enabled;\n\t/* letter, and ftype are initialized in the main part,\n\t   not in a parser. */\n#define NUL_XTAG_LETTER '\\0'\t/* Nothing todo with NULLTAG. */\n\tunsigned char letter;\n\tconst char* name;\t /* used in extra: field */\n\tconst char* description;  /* displayed in --list-extra output */\n\n\t/* If the value for \"enabled\" is given dynamically,\n\t   use this field.\n\n\t   \"enabled\" field of Pseudo extra tag depends on where\n\t   the output stream is connected to. If it is connected\n\t   to standard output, the tag is disabled by default.\n\t   If it is connected to a regular file, the tag is enabled\n\t   by default. */\n\tbool (* isEnabled) (struct sXtagDefinition *def);\n\tbool (* isFixed)   (struct sXtagDefinition *def);\n\tvoid (* enable)    (struct sXtagDefinition *def, bool state);\n\n\tunsigned int    version;\n\n\tunsigned int xtype;\t/* Given from the main part */\n};\n\nextern bool isXtagEnabled (xtagType type);\n\n#endif\t/* CTAGS_MAIN_FIELD_H */\n"
  },
  {
    "path": "main/xtag_p.h",
    "content": "/*\n *\n *  Copyright (c) 2015, Red Hat, Inc.\n *  Copyright (c) 2015, Masatake YAMATO\n *\n *  Author: Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n#ifndef CTAGS_MAIN_XTAG_PRIVATE_H\n#define CTAGS_MAIN_XTAG_PRIVATE_H\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"\n\n#include \"types.h\"\n#include \"xtag.h\"\n#include \"colprint_p.h\"\n\n#include <stdio.h>\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nextern xtagDefinition* getXtagDefinition (xtagType type);\nextern xtagType  getXtagTypeForLetter (char letter);\nextern xtagType  getXtagTypeForNameAndLanguage (const char *name, langType language);\n\nextern bool enableXtag (xtagType type, bool state);\nextern bool isXtagFixed (xtagType type);\nextern bool isCommonXtag (xtagType type);\n\n/* Return LANG_IGNORE for common fields. */\nextern langType getXtagLanguage (xtagType type);\n\nextern const char* getXtagName (xtagType type);\nextern const char* getXtagDescription (xtagType type);\n\nextern void initXtagObjects (void);\nextern unsigned int countXtags (void);\n\nextern int defineXtag (xtagDefinition *def, langType language);\nextern xtagType nextSiblingXtag (xtagType type);\n\n/* --list-extras implementation. LANGUAGE must be initialized. */\nextern struct colprintTable * xtagColprintTableNew (void);\nextern void xtagColprintAddCommonLines (struct colprintTable *table);\nextern void xtagColprintAddLanguageLines (struct colprintTable *table, langType language);\nextern void xtagColprintTablePrint (struct colprintTable *table,\n\t\t\t\t\t\t\t\t\tbool withListHeader, bool machinable, FILE *fp);\n\n#endif\t/* CTAGS_MAIN_FIELD_PRIVATE_H */\n"
  },
  {
    "path": "makefiles/help.mak",
    "content": "# -*- makefile -*-\n.PHONY: help\nCTAGS_PROG = $(CTAGS_NAME_EXECUTABLE)\n\nhelp:\n\t@echo \"Compilation targets:\"\n\t@echo \"  make                              - Build $(CTAGS_PROG)\"\n\t@echo \"  make V=1                          - Build $(CTAGS_PROG) with verbose output\"\n\t@echo \"  make -f mk_mingw.mak              - Build $(CTAGS_PROG) using MinGW\"\n\t@echo \"  make -f mk_mingw.mak V=1          - Build $(CTAGS_PROG) using MinGW with verbose output\"\n\t@echo \"  make -C docs html                 - Build HTML documents by Sphinx\"\n\t@echo \"\"\n\t@echo \"Testing targets:\"\n\t@echo \"  make units                        - Run parser unit test cases\"\n\t@echo \"  make tmain                        - Run ctags main functionality test cases\"\n\t@echo \"  make tlib                         - Run mini-geany test cases\"\n\t@echo \"  make tutil                        - Run utiltest test cases\"\n\t@echo \"  make man-test                     - Run testing examples in per-language man pages\"\n\t@echo \"  make check-genfile                - Run testing generated files are committed\"\n\t@echo \"  make check                        - Run all tests above\"\n\t@echo \"\"\n\t@echo \"  make fuzz                         - Verify that all parsers are able to properly process each available test unit\"\n\t@echo \"  make noise                        - Verify the behavior of parsers for broken input: a character injected or removed randomly\"\n\t@echo \"  make chop                         - Verify the behavior of parsers for broken input: randomly truncated from tail\"\n\t@echo \"  make slap                         - Verify the behavior of parsers for broken input: randomly truncated from head\"\n\t@echo \"  make roundtrip                    - Verify the behavior of readtags command\"\n\t@echo\n\t@echo \"Arguments that can be used in testing targets:\"\n\t@echo \"  V=1                               - Verbose output\"\n\t@echo \"  VG=1                              - Run test cases with Valgrind memory profiler\"\n\t@echo \"  LANGUAGES=<language>[,<language>] - Only run test cases of the selected languages\"\n\t@echo \"  CATEGORIES=<category>             - Only run tests available under folder Units/<category>.r\"\n\t@echo \"  UNITS=<case>[,<case>]             - Only run tests named Units/[category.r/]/<case>.d in units target\"\n\t@echo \"                                                           Tmain/<case>.d in tmain target\"\n\t@echo \"  PMAP=<newlang>/<oldlang>[,...]    - Make <newlang> parser pretend <oldlang> (units target only)\"\n\t@echo \"  THREADS=<n>                       - Use <n> threads to run test cases in units and tmain targets\"\n\t@echo \"\"\n\t@echo \"Input validation target:\"\n\t@echo \"  make validate-input               - Validate the input files themselves, not ctags\"\n\t@echo\n\t@echo \"Arguments that can be used in input validation target:\"\n\t@echo \"  VALIDATORS=<validator>,[<validator>] - Validate only input files expecting validated by VALIDATORs\"\n"
  },
  {
    "path": "makefiles/testing.mak",
    "content": "# -*- makefile -*-\n.PHONY: check units fuzz noise tmain tinst tlib man-test clean-units clean-tlib clean-tmain clean-gcov clean-man-test run-gcov codecheck cppcheck dicts validate-input check-genfile tutil\n\nEXTRA_DIST += misc/units misc/units.py misc/man-test.py\nEXTRA_DIST += misc/tlib misc/mini-geany.expected\nMAN_TEST_TMPDIR = ManTest\n\ncheck: tmain units tlib man-test check-genfile tutil\n\n# We may use CLEANFILES, DISTCLEANFILES, or etc.\nclean-local: clean-units clean-tmain clean-man-test clean-tlib clean-gcov\n\nCTAGS_TEST = ./ctags$(EXEEXT)\nREADTAGS_TEST = ./readtags$(EXEEXT)\nMINI_GEANY_TEST = ./mini-geany$(EXEEXT)\nOPTSCRIPT_TEST = ./optscript$(EXEEXT)\nUTILTEST_TEST = ./utiltest$(EXEEXT)\n\n# Make these macros empty from make's command line\n# if you don't want to (re)build these executables\n# before testing.\n# e.g.\n#\n#    $ make units CTAGS_DEP=\n#\nCTAGS_DEP = $(CTAGS_TEST)\nREADTAGS_DEP = $(READTAGS_TEST)\nMINI_GEANY_DEP = $(MINI_GEANY_TEST)\nOPTSCRIPT_DEP = $(OPTSCRIPT_TEST)\nUTILTEST_DEP = $(UTILTEST_TEST)\n\nif HAVE_TIMEOUT\nTIMEOUT = 1\nelse\nTIMEOUT = 0\nendif\n\nLANGUAGES=\nCATEGORIES=\nUNITS=\nPMAP=\n\nSILENT = $(SILENT_@AM_V@)\nSILENT_ = $(SILENT_@AM_DEFAULT_V@)\nSILENT_0 = @\n\nV_RUN = $(V_RUN_@AM_V@)\nV_RUN_ = $(V_RUN_@AM_DEFAULT_V@)\nV_RUN_0 = @echo \"  RUN      $@\";\n\n#\n# FUZZ Target\n#\n# SHELL must be dash or bash.\n#\nfuzz: $(CTAGS_DEP)\n\t$(V_RUN) \\\n\tif test -n \"$${ZSH_VERSION+set}\"; then set -o SH_WORD_SPLIT; fi; \\\n\tif test x$(VG) = x1; then\t\t\\\n\t\tVALGRIND=--with-valgrind;\t\\\n\tfi;\t\t\t\t\t\\\n\tc=\"$(srcdir)/misc/units fuzz \\\n\t\t--ctags=$(CTAGS_TEST) \\\n\t\t--languages=$(LANGUAGES) \\\n\t\t$${VALGRIND} --run-shrink \\\n\t\t--with-timeout=`expr $(TIMEOUT) '*' 10`\"; \\\n\t$(SHELL) $${c} $(srcdir)/Units\n\n#\n# NOISE Target\n#\nnoise: $(CTAGS_DEP)\n\t$(V_RUN) \\\n\tif test -n \"$${ZSH_VERSION+set}\"; then set -o SH_WORD_SPLIT; fi; \\\n\tif test x$(VG) = x1; then\t\t\\\n\t\tVALGRIND=--with-valgrind;\t\\\n\tfi;\t\t\t\t\t\\\n\tc=\"$(srcdir)/misc/units noise \\\n\t\t--ctags=$(CTAGS_TEST) \\\n\t\t--languages=$(LANGUAGES) \\\n\t\t$${VALGRIND} --run-shrink \\\n\t\t--with-timeout=$(TIMEOUT)\"; \\\n\t$(SHELL) $${c} $(srcdir)/Units\n\n#\n# CHOP Target\n#\nchop: $(CTAGS_DEP)\n\t$(V_RUN) \\\n\tif test -n \"$${ZSH_VERSION+set}\"; then set -o SH_WORD_SPLIT; fi; \\\n\tif test x$(VG) = x1; then\t\t\\\n\t\tVALGRIND=--with-valgrind;\t\\\n\tfi;\t\t\t\t\t\\\n\tc=\"$(srcdir)/misc/units chop \\\n\t\t--ctags=$(CTAGS_TEST) \\\n\t\t--languages=$(LANGUAGES) \\\n\t\t$${VALGRIND} --run-shrink \\\n\t\t--with-timeout=$(TIMEOUT)\"; \\\n\t$(SHELL) $${c} $(srcdir)/Units\nslap: $(CTAGS_DEP)\n\t$(V_RUN) \\\n\tif test -n \"$${ZSH_VERSION+set}\"; then set -o SH_WORD_SPLIT; fi; \\\n\tif test x$(VG) = x1; then\t\t\\\n\t\tVALGRIND=--with-valgrind;\t\\\n\tfi;\t\t\t\t\t\\\n\tc=\"$(srcdir)/misc/units slap \\\n\t\t--ctags=$(CTAGS_TEST) \\\n\t\t--languages=$(LANGUAGES) \\\n\t\t$${VALGRIND} --run-shrink \\\n\t\t--with-timeout=$(TIMEOUT)\"; \\\n\t$(SHELL) $${c} $(srcdir)/Units\n\n#\n# UNITS Target\n#\nunits: $(CTAGS_DEP)\n\t$(V_RUN) \\\n\tif test -n \"$${ZSH_VERSION+set}\"; then set -o SH_WORD_SPLIT; fi; \\\n\tif test x$(VG) = x1; then\t\t\\\n\t\tVALGRIND=--with-valgrind;\t\\\n\tfi;\t\t\t\t\t\\\n\tif ! test x$(CI) = x; then\t\\\n\t\tSHOW_DIFF_OUTPUT=--show-diff-output;\t\t\\\n\tfi;\t\t\t\t\t\t\t\\\n\tbuilddir=$$(pwd); \\\n\tif ! test x$(PYTHON) = x; then\t\\\n\t\tPROG=$(PYTHON);\t\t\\\n\t\tSCRIPT=$(srcdir)/misc/units.py;\t\\\n\t\tif type cygpath > /dev/null 2>&1; then\t\\\n\t\t\tbuilddir=$$(cygpath -m \"$$(pwd)\");\t\\\n\t\t\tif ! test x$(SHELL) = x; then\t\\\n\t\t\t\tSHELL_OPT=--shell=$$(cygpath -m $(SHELL));\t\\\n\t\t\tfi;\t\\\n\t\telse\t\\\n\t\t\tif ! test x$(SHELL) = x; then\t\\\n\t\t\t\tSHELL_OPT=--shell=$(SHELL);\t\\\n\t\t\tfi;\t\\\n\t\tfi;\t\\\n\telse\t\\\n\t\tPROG=$(SHELL);\t\t\\\n\t\tSCRIPT=$(srcdir)/misc/units;\t\\\n\tfi;\t\\\n\tif ! test x$(THREADS) = x; then \\\n\t\tTHREADS_OPT=--threads=$(THREADS); \\\n\tfi; \\\n\tmkdir -p $${builddir}/Units && \\\n\t\\\n\tc=\"$${SCRIPT} run \\\n\t\t--ctags=$(CTAGS_TEST) \\\n\t\t--languages=$(LANGUAGES) \\\n\t\t--categories=$(CATEGORIES) \\\n\t\t--units=$(UNITS) \\\n\t\t--with-pretense-map=$(PMAP) \\\n\t\t$${VALGRIND} --run-shrink \\\n\t\t--with-timeout=`expr $(TIMEOUT) '*' 10`\\\n\t\t$${SHELL_OPT} \\\n\t\t$${THREADS_OPT} \\\n\t\t$${SHOW_DIFF_OUTPUT}\"; \\\n\t\t $${PROG} $${c} $(srcdir)/Units $${builddir}/Units\n\nclean-units:\n\t$(SILENT) echo Cleaning test units\n\t$(SILENT) if test -d $$(pwd)/Units; then \\\n\t\t$(SHELL) $(srcdir)/misc/units clean $$(pwd)/Units; \\\n\tfi\n\n#\n# VALIDATE-INPUT Target\n#\nvalidate-input:\n\t$(V_RUN) \\\n\tif test -n \"$${ZSH_VERSION+set}\"; then set -o SH_WORD_SPLIT; fi; \\\n\tif test -n \"$(VALIDATORS)\"; then\t\\\n\t\tVALIDATORS=\"--validators=$(VALIDATORS)\"; \\\n\tfi; \\\n\tc=\"$(srcdir)/misc/units validate-input \\\n\t\t--categories=$(CATEGORIES) \\\n\t\t$${VALIDATORS}\"; \\\n\t$(SHELL) $${c} $(srcdir)/Units $(srcdir)/misc/validators\n\n#\n# Test main part, not parsers\n#\ntmain: $(CTAGS_DEP) $(READTAGS_DEP) $(OPTSCRIPT_DEP)\n\t$(V_RUN) \\\n\tif test -n \"$${ZSH_VERSION+set}\"; then set -o SH_WORD_SPLIT; fi; \\\n\tif test x$(VG) = x1; then\t\t\\\n\t\tVALGRIND=--with-valgrind;\t\\\n\tfi;\t\t\t\t\t\\\n\tif ! test x$(CI) = x; then\t\\\n\t\tSHOW_DIFF_OUTPUT=--show-diff-output;\t\t\\\n\tfi;\t\t\t\t\t\t\t\\\n\tbuilddir=$$(pwd); \\\n\tif ! test x$(PYTHON) = x; then\t\\\n\t\tPROG=$(PYTHON);\t\t\\\n\t\tSCRIPT=$(srcdir)/misc/units.py;\t\\\n\t\tif type cygpath > /dev/null 2>&1; then\t\\\n\t\t\tbuilddir=$$(cygpath -m \"$$(pwd)\");\t\\\n\t\t\tif ! test x$(SHELL) = x; then\t\\\n\t\t\t\tSHELL_OPT=--shell=$$(cygpath -m $(SHELL));\t\\\n\t\t\tfi;\t\\\n\t\telse\t\\\n\t\t\tif ! test x$(SHELL) = x; then\t\\\n\t\t\t\tSHELL_OPT=--shell=$(SHELL);\t\\\n\t\t\tfi;\t\\\n\t\tfi;\t\\\n\telse\t\\\n\t\tPROG=$(SHELL);\t\t\\\n\t\tSCRIPT=$(srcdir)/misc/units;\t\\\n\tfi;\t\\\n\tif ! test x$(THREADS) = x; then \\\n\t\tTHREADS_OPT=--threads=$(THREADS); \\\n\tfi; \\\n\tmkdir -p $${builddir}/Tmain && \\\n\t\\\n\tc=\"$${SCRIPT} tmain \\\n\t\t--ctags=$(CTAGS_TEST) \\\n\t\t--units=$(UNITS) \\\n\t\t$${VALGRIND} \\\n\t\t$${SHELL_OPT} \\\n\t\t$${THREADS_OPT} \\\n\t\t$${SHOW_DIFF_OUTPUT}\"; \\\n\t\t$${PROG} $${c} $(srcdir)/Tmain $${builddir}/Tmain\n\nclean-tmain:\n\t$(SILENT) echo Cleaning main part tests\n\t$(SILENT) if test -d $$(pwd)/Tmain; then \\\n\t\t$(SHELL) $(srcdir)/misc/units clean-tmain $$(pwd)/Tmain; \\\n\tfi\n\ntlib: $(MINI_GEANY_DEP)\n\t$(V_RUN) \\\n\tbuilddir=$$(pwd); \\\n\tmkdir -p $${builddir}/misc; \\\n\tif test -s '$(MINI_GEANY_TEST)'; then \\\n\t\tif $(SHELL) $(srcdir)/misc/tlib $(MINI_GEANY_TEST) \\\n\t\t\t$(srcdir)/misc/mini-geany.expected \\\n\t\t\t$${builddir}/misc/mini-geany.actual \\\n\t\t\t$(VG); then \\\n\t\t\techo 'mini-geany: OK'; true; \\\n\t\telse \\\n\t\t\techo 'mini-geany: FAILED'; false; \\\n\t\tfi; \\\n\telse \\\n\t\techo 'mini-geany: SKIP'; true; \\\n\tfi\nclean-tlib:\n\t$(SILENT) echo Cleaning libctags part tests\n\t$(SILENT) builddir=$$(pwd); \\\n\t\trm -f $${builddir}/misc/mini-geany.actual\n\n#\n# Test installation\n#\ntinst:\n\t$(V_RUN) \\\n\tbuilddir=$$(pwd); \\\n\trm -rf $$builddir/$(TINST_ROOT); \\\n\t$(SHELL) $(srcdir)/misc/tinst $(srcdir) $$builddir/$(TINST_ROOT)\n\n#\n# Test readtags\n#\nif USE_READCMD\nroundtrip: $(READTAGS_DEP)\n\t$(V_RUN) \\\n\tif ! test x$(CI) = x; then\t\\\n\t\tROUNDTRIP_FLAGS=--minitrip;\t\t\t\\\n\tfi;\t\t\t\t\t\t\t\\\n\tbuilddir=$$(pwd); \\\n\t$(SHELL) $(srcdir)/misc/roundtrip $(READTAGS_TEST) $${builddir}/Units $${ROUNDTRIP_FLAGS}\nelse\nroundtrip:\nendif\n\n#\n# Checking code in ctags own rules\n#\ncodecheck: $(CTAGS_DEP)\n\t$(V_RUN) $(SHELL) misc/src-check\n\n#\n# Report coverage (usable only if ctags is built with \"configure --enable-coverage-gcov\".)\n#\nrun-gcov:\n\t$(CTAGS_TEST) -o - $$(find ./Units -name 'input.*'| grep -v '.*b/.*') > /dev/null\n\tgcov $$(find -name '*.gcda')\n\nclean-gcov:\n\t$(SILENT) echo Cleaning coverage reports\n\t$(SILENT) rm -f $(ALL_SRCS:.c=.gcda)\n\t$(SILENT) rm -f $(srcdir)/*.gcov\n\n#\n# Cppcheck\n#\nCPPCHECK_DEFS   = -DHAVE_LIBYAML -DHAVE_LIBXML -DHAVE_COPROC -DHAVE_DECL___ENVIRON\nCPPCHECK_UNDEFS = -UDEBUG -UMIO_DEBUG -UCXX_DEBUGGING_ENABLED\nCPPCHECK_FLAGS  = --enable=all\n\ncppcheck:\n\tcppcheck $(CPPCHECK_DEFS) $(CPPCHECK_UNDEFS) $(CPPCHECK_FLAGS) \\\n\t\t $$(git  ls-files | grep '^\\(parsers\\|main\\)/.*\\.[ch]' )\n\n#\n# Testing examples in per-language man pages\n#\nman-test: $(CTAGS_DEP)\n\t$(V_RUN) \\\n\t$(PYTHON) $(srcdir)/misc/man-test.py $(MAN_TEST_TMPDIR) $(CTAGS_TEST) $(srcdir)/man/ctags-lang-*.7.rst.in\n\nclean-man-test:\n\trm -rf $(MAN_TEST_TMPDIR)\n\n# check if generated files are committed.\n#   Note: \"make -B\" cannot be used here, since it reruns automake\nchkgen_verbose = $(chkgen_verbose_@AM_V@)\nchkgen_verbose_ = $(chkgen_verbose_@AM_DEFAULT_V@)\nchkgen_verbose_0 = @echo CHKGEN \"    $@\";\n\ncgok             =  echo \"<ok>       $@:\"\ncgerr            =  echo \"<ERROR>    $@:\"\ncgskip           =  echo \"<skip>     $@:\"\n\nrecover_side_effects = cg-force-optlib2c-srcs cg-force-txt2cstr-srcs cg-force-man-docs\n\n# OPTLIB2C_SRCS : committed for win32 build\n.PHONY: cg-clean-optlib2c-srcs cg-force-optlib2c-srcs check-genfile-optlib2c-srcs\ncg-clean-optlib2c-srcs:\nif BUILD_IN_GIT_REPO\n\t$(chkgen_verbose)rm -f $(OPTLIB2C_SRCS)\nendif\ncg-force-optlib2c-srcs: cg-clean-optlib2c-srcs\nif BUILD_IN_GIT_REPO\n\t$(chkgen_verbose)$(MAKE) $(OPTLIB2C_SRCS)\nendif\ncheck-genfile-optlib2c-srcs: $(recover_side_effects) cg-force-optlib2c-srcs\nif BUILD_IN_GIT_REPO\n\t$(chkgen_verbose)if ! git diff --exit-code $(OPTLIB2C_DIR); then \\\n\t\t$(cgerr) \"Files under $(OPTLIB2C_DIR) are not up to date.\" ; \\\n\t\t$(cgerr) \"If you change $(OPTLIB2C_DIR)/foo.ctags, don't forget to add $(OPTLIB2C_DIR)/foo.c to your commit.\" ; \\\n\t\texit 1 ; \\\n\telse \\\n\t\t$(cgok) \"Files under $(OPTLIB2C_DIR) are up to date.\" ; \\\n\tfi\nendif\n\n# TXT2CSTR_SRCS : committed for win32 build\n.PHONY: cg-clean-txt2cstr-srcs cg-force-txt2cstr-srcs check-genfile-txt2cstr-srcs\ncg-clean-txt2cstr-srcs:\nif BUILD_IN_GIT_REPO\n\t$(chkgen_verbose)rm -f $(TXT2CSTR_SRCS)\nendif\ncg-force-txt2cstr-srcs: cg-clean-txt2cstr-srcs\nif BUILD_IN_GIT_REPO\n\t$(chkgen_verbose)$(MAKE) $(TXT2CSTR_SRCS)\nendif\ncheck-genfile-txt2cstr-srcs: $(recover_side_effects) cg-force-txt2cstr-srcs\nif BUILD_IN_GIT_REPO\n\t$(chkgen_verbose)if ! git diff --exit-code $(TXT2CSTR_DIR); then \\\n\t\t$(cgerr) \"Files under $(TXT2CSTR_DIR) are not up to date.\" ; \\\n\t\t$(cgerr) \"If you change $(TXT2CSTR_DIR)/foo.ps, don't forget to add $(TXT2CSTR_DIR)/foo.c to your commit.\" ; \\\n\t\texit 1 ; \\\n\telse \\\n\t\t$(cgok) \"Files under $(TXT2CSTR_DIR) are up to date.\" ; \\\n\tfi\nendif\n\n# man/*.in : committed for man pages to be genrated without rst2man\n#   make clean-docs remove both man/*.in and docs/man/*.rst\n.PHONY: cg-clean-man-docs cg-force-man-docs check-genfile-man-docs\ncg-clean-man-docs:\nif BUILD_IN_GIT_REPO\nif HAVE_RST2MAN\n\t$(chkgen_verbose)$(MAKE) -C man clean-docs\nendif\nendif\ncg-force-man-docs: cg-clean-man-docs\nif BUILD_IN_GIT_REPO\nif HAVE_RST2MAN\n\t$(chkgen_verbose)$(MAKE) -C man man-in\nendif\nendif\ncheck-genfile-man-docs:  $(recover_side_effects) cg-force-man-docs\nif BUILD_IN_GIT_REPO\nif HAVE_RST2MAN\n\t$(chkgen_verbose)if ! git diff --exit-code -- man; then \\\n\t\t$(cgerr) \"Files under man/ are not up to date.\" ; \\\n\t\t$(cgerr) \"Please execute 'make -C man man-in' and commit them.\" ; \\\n\t\texit 1 ; \\\n\telse \\\n\t\t$(cgok) \"Files under man are up to date.\" ; \\\n\tfi\nendif\nendif\n\n# docs/man/*.rst : committed for Read the Docs\n.PHONY: cg-force-update-docs check-genfile-update-docs\ncg-force-update-docs: check-genfile-man-docs\nif BUILD_IN_GIT_REPO\nif HAVE_RST2MAN\n\t$(chkgen_verbose)$(MAKE) -C man update-docs\nendif\nendif\n\ncheck-genfile-update-docs: cg-force-update-docs $(recover_side_effects)\nif BUILD_IN_GIT_REPO\nif HAVE_RST2MAN\n\t$(chkgen_verbose)if ! git diff --exit-code -- docs/man; then \\\n\t\t$(cgerr) \"Files under docs/man/ are not up to date.\" ; \\\n\t\t$(cgerr) \"Please execute 'make -C man update-docs' and commit them.\" ; \\\n\t\texit 1 ; \\\n\telse \\\n\t\t$(cgok) \"Files under docs/man are up to date.\" ; \\\n\tfi\nendif\nendif\n\n# win32/{ctags_vs2013.vcxproj*,peg_rule.mak} : committed for win32 build without POSIX tools\n#   regenerate files w/o out-of-source build and w/ GNU make\n.PHONY: cg-force-win32 check-genfile-win32\ncg-force-win32:\nif BUILD_IN_GIT_REPO\n\t$(chkgen_verbose)if test \"$(top_srcdir)\" = \"$(top_builddir)\" \\\n\t\t&& ($(MAKE) --version) 2>/dev/null | grep -q GNU ; then \\\n\t\t$(MAKE) -BC win32 ; \\\n\tfi\nendif\ncheck-genfile-win32: cg-force-win32 $(recover_side_effects)\nif BUILD_IN_GIT_REPO\n\t$(chkgen_verbose)if ! git diff --exit-code -- win32; then \\\n\t\tif test \"$(SKIP_CHECKGEN_WIN32)\" = \"yes\"; then \\\n\t\t\t$(cgskip) \"Skip checking the files under win32.\" ; \\\n\t\t\texit 0 ; \\\n\t\telse \\\n\t\t\t$(cgerr) \"Files under win32/ are not up to date.\" ; \\\n\t\t\t$(cgerr) \"Please execute 'make -BC win32' and commit them.\" ; \\\n\t\t\texit 1 ; \\\n\t\tfi \\\n\telse \\\n\t\t$(cgok) \"Files under win32 are up to date.\" ; \\\n\tfi\nendif\n\n.PHONY: check-genfile-add-docs-man\ncheck-genfile-add-docs-man: $(recover_side_effects)\n\t$(chkgen_verbose) {\\\n\t\t(cd man; git ls-files .) | grep ctags-lang- | sed -e 's/\\.in$$//' > TEMP-MAN-LS; \\\n\t\t(cd docs/man; git ls-files .) | grep ctags-lang-  > TEMP-DOCS-MAN-LS; \\\n\t\tif ! diff TEMP-MAN-LS TEMP-DOCS-MAN-LS; then \\\n\t\t\t$(cgerr) 'See \"<\" lines above.'; \\\n\t\t\t$(cgerr) 'docs/man/*rst genereated from man/*rst.in are not in the git repo'; \\\n\t\t\t$(cgerr) 'Please add the genereated file to the git repo'; \\\n\t\t\trm TEMP-MAN-LS TEMP-DOCS-MAN-LS; \\\n\t\t\texit 1 ; \\\n\t\telse \\\n\t\t\trm TEMP-MAN-LS TEMP-DOCS-MAN-LS; \\\n\t\t\t$(cgok) 'All rst files under docs/man are in our git repo'; \\\n\t\tfi; \\\n\t}\n\n.PHONY: check-genfile-docs-man-pages-rst\ncheck-genfile-docs-man-pages-rst: $(recover_side_effects)\n\t$(chkgen_verbose) for f in $$( (cd docs/man; git ls-files .) | grep ctags-lang- ); do \\\n\t\tif ! grep -q $$f docs/man-pages.rst; then \\\n\t\t\t$(cgerr) \"$$f is not found in docs/man-pages.rst\"; \\\n\t\t\t$(cgerr) \"Please add $$f to docs/man-pages.rst\"; \\\n\t\t\texit 1; \\\n\t\tfi; \\\n\tdone; \\\n\t$(cgok) \"docs/man-pages.rst includes all ctags-lang-*.rst\"\n\ncheck-genfile: \\\n\tcheck-genfile-optlib2c-srcs \\\n\tcheck-genfile-txt2cstr-srcs \\\n\tcheck-genfile-update-docs \\\n\tcheck-genfile-add-docs-man \\\n\tcheck-genfile-docs-man-pages-rst \\\n\tcheck-genfile-win32\n\n#\n# Test installation\n#\ntutil: $(UTILTEST_DEP)\n# See _VALGRIND_EXIT in misc/uints.py about 56.\n\t$(V_RUN) vg=; \\\n\tif test x$(VG) = x1; then \\\n\t\tvg=\"valgrind \"; \\\n\t\tvg=\"$$vg --leak-check=full\"; \\\n\t\tvg=\"$$vg --track-origins=yes\"; \\\n\t\tvg=\"$$vg --error-exitcode=56\"; \\\n\tfi; \\\n\t\\\n\tbuilddir=$$(pwd); \\\n\t$$vg $$builddir/$(UTILTEST_TEST) -v\n"
  },
  {
    "path": "man/GNUmakefile.am",
    "content": "#\n# This is a Makefile.am read by the Autotools.\n# GNU Make is needed.\n#\n#\tCopyright (c) 2017, Masatake YAMMATO\n#\tCopyright (c) 2017, Red Hat, Inc.\n#\n#\tThis source code is released for free distribution under the terms\n#\tof the GNU General Public License version 2 or (at your option) any\n#\tlater version.\n#\n\n# Note: RST2MAN, RST2HTML, RST2PDF, and RST2MAN_OPTIONS are defined by configure.ac\nRST2MAN_FLAGS = $(RST2MAN_OPTIONS)\nRST2HTML_FLAGS =\nRST2PDF_FLAGS =\nDOCS_DIR = ../docs/man\n\nSUFFIXES = .rst .html .pdf .in\n\n# The man_MANS or dist_man_MANS requires conventional file names for man files.\n# For example `$(basename $(files))` is not accepted.\nGEN_IN_MAN_FILES = \\\n\tctags.1 \\\n\tctags-optlib.7 \\\n\tctags-incompatibilities.7 \\\n\tctags-client-tools.7 \\\n\tctags-faq.7 \\\n\t\\\n\tctags-lang-asm.7 \\\n\tctags-lang-autoit.7 \\\n\tctags-lang-automake.7 \\\n\tctags-lang-c.7 \\\n\tctags-lang-c++.7 \\\n\tctags-lang-cuda.7 \\\n\tctags-lang-elm.7 \\\n\tctags-lang-emacslisp.7 \\\n\tctags-lang-fortran.7 \\\n\tctags-lang-gdscript.7 \\\n\tctags-lang-iPythonCell.7 \\\n\tctags-lang-i18nrubygem.7 \\\n\tctags-lang-inko.7 \\\n\tctags-lang-javascript.7 \\\n\tctags-lang-julia.7 \\\n\tctags-lang-kconfig.7 \\\n\tctags-lang-ldscript.7 \\\n\tctags-lang-lex.7 \\\n\tctags-lang-lisp.7 \\\n\tctags-lang-make.7 \\\n\tctags-lang-markdown.7 \\\n\tctags-lang-meson.7 \\\n\tctags-lang-odin.7 \\\n\tctags-lang-powershell.7 \\\n\tctags-lang-python.7 \\\n\tctags-lang-r.7 \\\n\tctags-lang-rmarkdown.7 \\\n\tctags-lang-scheme.7 \\\n\tctags-lang-scss.7 \\\n\tctags-lang-sql.7 \\\n\tctags-lang-systemtap.7 \\\n\tctags-lang-tcl.7 \\\n\tctags-lang-terraform.7 \\\n\tctags-lang-verilog.7 \\\n\tctags-lang-vim.7 \\\n\t\\\n\treadtags.1 \\\n\ttags.5 \\\n\tctags-json-output.5 \\\n\t\\\n\t$(NULL)\n\nman_pages  = $(GEN_IN_MAN_FILES)\nman_in_files = $(addsuffix .in,$(man_pages))\nrst_files  = $(addsuffix .rst,$(man_pages))\nhtml_pages = $(addsuffix .html,$(man_pages))\npdf_pages  = $(addsuffix .pdf,$(man_pages))\ndoc_files  = $(addprefix $(DOCS_DIR)/,$(rst_files))\n\n# for automake\n# generate man pages only when rst2man is installed\nif HAVE_RST2MAN\nman_MANS = $(man_pages)\nendif\nEXTRA_DIST = README $(addsuffix .rst.in,$(GEN_IN_MAN_FILES)) $(man_in_files)\nCLEANFILES = $(man_pages) $(addsuffix .rst,$(GEN_IN_MAN_FILES)) $(html_pages) $(pdf_pages)\nMAINTAINERCLEANFILES =  $(man_in_files)\n\n.PHONY: man man-in html pdf update-docs clean-docs\n\nall-am: update-docs\n\nman: $(man_pages)\nman-in: $(man_in_files)\nhtml: $(html_pages)\npdf: $(pdf_pages)\n\n# use `[@]` not to be replaced by automake\nREPLACE_CONF_VARS =\tsed \\\n\t\t-e s/[@]CTAGS_NAME_EXECUTABLE[@]/ctags/g \\\n\t\t-e s/[@]ETAGS_NAME_EXECUTABLE[@]/etags/g \\\n\t\t-e s/[@]VERSION[@]/$(VERSION)/g\n\nrst2man_verbose    = $(rst2man_verbose_@AM_V@)\nrst2man_verbose_   = $(rst2man_verbose_@AM_DEFAULT_V@)\nrst2man_verbose_0  = @echo RST2MAN \"   $@\";\n\nrst2html_verbose   = $(rst2html_verbose_@AM_V@)\nrst2html_verbose_  = $(rst2html_verbose_@AM_DEFAULT_V@)\nrst2html_verbose_0 = @echo RST2HTML \"  $@\";\n\nrst2pdf_verbose    = $(rst2pdf_verbose_@AM_V@)\nrst2pdf_verbose_   = $(rst2pdf_verbose_@AM_DEFAULT_V@)\nrst2pdf_verbose_0  = @echo RST2MAN \"   $@\";\n\nsed_verbose        = $(sed_verbose_@AM_V@)\nsed_verbose_       = $(sed_verbose_@AM_DEFAULT_V@)\nsed_verbose_0      = @echo SED \"       $@\";\n\nrm_verbose         = $(rm_verbose_@AM_V@)\nrm_verbose_        = $(rm_verbose_@AM_DEFAULT_V@)\nrm_verbose_0       = @echo RM \"        $@\";\n\n#\n# generate man\n#\n# generate *.in to be distributed\n%.in: %.rst.in\nif HAVE_RST2MAN\n\t$(rst2man_verbose)$(RST2MAN) $(RST2MAN_FLAGS) $< > $@\nelse\n\t$(error Cannot make $@: rst2man is not installed)\nendif\n\n%: %.in\n\t$(sed_verbose)$(REPLACE_CONF_VARS) < $< > $@\n\n#\n# generate HTML and PDF\n#\n%.rst: %.rst.in\n\t$(sed_verbose)$(REPLACE_CONF_VARS) < $< > $@\n\n%.html: %.rst\nif HAVE_RST2HTML\n\t$(rst2html_verbose)$(RST2HTML) $(RST2HTML_FLAGS) $< > $@\nelse\n\t$(error Cannot make $@: rst2html is not installed)\nendif\n\n%.pdf: %.rst\nif HAVE_RST2PDF\n\t$(rst2pdf_verbose)$(RST2PDF) $(RST2PDF_FLAGS) $< -o $@\nelse\n\t$(error Cannot make $@: rst2pdf is not installed)\nendif\n\n#\n# generate $(DOCS_DIR)/*.rst for Sphinx document\n#\nupdate-docs: $(doc_files)\n\n# Convert the names of man page files (without suffix) to man page citations.\n#   ctags.1 tags.5 ... => ctags(1) tags(5) ...\ncites := ${subst .,(,${addsuffix ),${man_pages}}}\n\n# Convert the man page citations to sed patterns for making hyperlinks.\n#   ctags(1) tags(5) ...\n#     => -e 's/\\<ctags(1)/:ref:`& <&>`/g' -e 's/\\<ctags(5)/:ref:`& <&>`/g' ...\nif HAS_GNU_SED\nreppat := $(foreach m,$(cites),-e 's/\\<$(m)/:ref:`& <&>`/g')\nelse\nreppat := $(foreach m,$(cites),-e 's/[[:<:]]$(m)/:ref:`& <&>`/g')\nendif\n\n# Delete the line \"------\" in the first 10 lines of $(DOCS_DIR)/*.rst to\n# suppress unnecessary section indices.\n$(DOCS_DIR)/%.rst: %.rst\n\t@$(MKDIR_P) $(DOCS_DIR)\n\t$(sed_verbose)sed $(reppat) -e '1,10s/^-*$$//' < $< > $@\n\n# remove generated files to be commited (used for `make checkgen`)\nclean-local: clean-docs\nclean-docs:\n\t$(rm_verbose)rm -f $(man_in_files) $(doc_files)\n"
  },
  {
    "path": "man/Makefile",
    "content": "# Based on https://github.com/universal-ctags/ctags/pull/3353#issuecomment-1103403502\n# posted by @eli-schwartz.\nall:\n\t@if type gmake > /dev/null 2>&1; then\t\t\t\t\t\t\t\\\n\t\tgmake $@;\t\t\t\t\t\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\t\t\t\\\n\t\techo \"WARNING: GNU make is needed for generating man pages.\";\t\t\t\\\n\t\techo \"WARNING: skip the operations in this directory: gmake $@\";\t\t\\\n\tfi\n\n.DEFAULT:\n\t@if type gmake > /dev/null 2>&1; then\t\t\t\t\t\t\t\\\n\t\tgmake $@;\t\t\t\t\t\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\t\t\t\\\n\t\techo \"WARNING: GNU make is needed for updating win32 related build-script.\";\t\\\n\t\techo \"WARNING: skip the operations in this directory: gmake $@\";\t\t\\\n\tfi\n\n.PHONY: all\n"
  },
  {
    "path": "man/README",
    "content": "Read docs/README.md and the \"Writing Documents\" section of\ndocs/contributions.rst for information on how to write man pages.\n\n\nTesting and verification\n---------------------------------------------------------------------\n* pick reserved words\n\n  - \"default\"\n  - \"all\"\n  - \"NONE\"\n  - '-'\n\n* verify whether + and - can be used as part of language names:\n\n  --langmap\n\tlanguages like C++ and/or Objective-C can be specified.\n\n  --languages\n\tlanguages like C++ and/or Objective-C can be specified.\n\n* TODO\n\n  - strcasecmp must be used when comparing the name of languages.\n"
  },
  {
    "path": "man/ctags-client-tools.7.rst.in",
    "content": ".. _ctags-client-tools(7):\n\n==============================================================\nctags-client-tools\n==============================================================\n---------------------------------------------------------------------------------\nHints for developing a tool using @CTAGS_NAME_EXECUTABLE@ command and tags output\n---------------------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** [options] [file(s)]\n|\t**@ETAGS_NAME_EXECUTABLE@** [options] [file(s)]\n\n\nDESCRIPTION\n-----------\n**Client tool** means a tool running the @CTAGS_NAME_EXECUTABLE@ command\nand/or reading a tags file generated by @CTAGS_NAME_EXECUTABLE@ command.\nThis man page gathers hints for people who develop client tools.\n\n\nPSEUDO-TAGS\n-----------\n**Pseudo-tags**, stored in a tag file, indicate how\n@CTAGS_NAME_EXECUTABLE@ generated the tags file: whether the\ntags file is sorted or not, which version of tags file format is used,\nthe name of tags generator, and so on. The opposite term for\npseudo-tags is **regular-tags**. A regular-tag is for a language\nobject in an input file. A pseudo-tag is for the tags file\nitself. Client tools may use pseudo-tags as reference for processing\nregular-tags.\n\nA pseudo-tag is stored in a tags file in the same format as\nregular-tags as described in tags(5), except that pseudo-tag names\nare prefixed with \"!_\". For the general information about\npseudo-tags, see \"TAG FILE INFORMATION\" in tags(5).\n\nAn example of a pseudo tag::\n\n\t!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\n\nThe value, \"Universal Ctags\", associated with the pseudo tag ``TAG_PROGRAM_NAME``, is\nused in the field for input file. The description, \"Derived from\nExuberant Ctags\", is used in the field for pattern.\n\nUniversal Ctags extends the naming scheme of the classical pseudo-tags\navailable in Exuberant Ctags for emitting language specific\ninformation as pseudo tags::\n\n\t!_{pseudo-tag-name}!{language-name}\t{associated-value}\t/{description}/\n\nThe language-name is appended to the pseudo-tag name with a separator, \"!\".\n\nAn example of pseudo tag with a language suffix::\n\n\t!_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n\nThis pseudo-tag says \"the function kind of C language is enabled\nwhen generating this tags file.\" ``--pseudo-tags`` is the option for\nenabling/disabling individual pseudo-tags. When enabling/disabling a\npseudo tag with the option, specify the tag name only\n``TAG_KIND_DESCRIPTION``, without the prefix (\"!_\") or the suffix (\"!C\").\n\n\nOptions for Pseudo-tags\n~~~~~~~~~~~~~~~~~~~~~~~\n``--extras=+p`` (or ``--extras=+{pseudo}``)\n\tForces writing pseudo-tags.\n\n\t@CTAGS_NAME_EXECUTABLE@ emits pseudo-tags by default when writing tags\n\tto a regular file (e.g. \"tags'.) However, when specifying ``-o -``\n\tor ``-f -`` for writing tags to standard output,\n\t@CTAGS_NAME_EXECUTABLE@ doesn't emit pseudo-tags. ``--extras=+p`` or\n\t``--extras=+{pseudo}`` will force pseudo-tags to be written.\n\n``--list-pseudo-tags``\n\tLists available types of pseudo-tags and shows whether they are enabled or disabled.\n\n\tRunning @CTAGS_NAME_EXECUTABLE@ with ``--list-pseudo-tags`` option\n\tlists available pseudo-tags. Some of pseudo-tags newly introduced\n\tin Universal Ctags project are disabled by default. Use\n\t``--pseudo-tags=...`` to enable them.\n\n``--pseudo-tags=[+|-]names|*``\n\tSpecifies a list of pseudo-tag types to include in the output.\n\n\tThe parameters are a set of pseudo tag names. Valid pseudo tag names\n\tcan be listed with ``--list-pseudo-tags``. Surround each name in the set\n\twith braces, like \"{TAG_PROGRAM_AUTHOR}\". You don't have to include the \"!_\"\n\tpseudo tag prefix when specifying a name in the option argument for ``--pseudo-tags=``\n\toption.\n\n\tpseudo-tags don't have a notation using one-letter flags.\n\n\tIf a name is preceded by either the '+' or '-' characters, that\n\ttags's effect has been added or removed. Otherwise the names replace\n\tany current settings. All entries are included if '*' is given.\n\tAll entries are removed if nothing ('') is given.\n\n``--fields=+E`` (or ``--fields=+{extras}``)\n\tAttach \"extras:pseudo\" field to pseudo-tags.\n\n\tAn example of pseudo tags with the field::\n\n\t\t!_TAG_PROGRAM_NAME\tUniversal Ctags\t/Derived from Exuberant Ctags/\textras:pseudo\n\n\tIf the name of a regular tag in a tag file starts with \"!_\", a\n\tclient tool cannot distinguish whether the tag is a regular-tag or\n\tpseudo-tag.  The fields attached with this option help the tool\n\tdistinguish them.\n\n\nList of notable pseudo-tags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nRunning ctags with ``--list-pseudo-tags`` option lists available types\nof pseudo-tags with short descriptions. This subsection shows hints\nfor using notable ones.\n\n``TAG_EXTRA_DESCRIPTION``  (new in Universal Ctags)\n\tIndicates the names and descriptions of enabled extras::\n\n\t  !_TAG_EXTRA_DESCRIPTION\t{extra-name}\t/description/\n\t  !_TAG_EXTRA_DESCRIPTION!{language-name}\t{extra-name}\t/description/\n\n\tIf your tool relies on some extra tags (extras), refer to\n\tthe pseudo-tags of this type. A tool can reject the tags file that\n\tdoesn't include expected extras, and raise an error in an early\n\tstage of processing.\n\n\tAn example of the pseudo-tags::\n\n\t  $ @CTAGS_NAME_EXECUTABLE@ --extras=+p --pseudo-tags='{TAG_EXTRA_DESCRIPTION}' -o - input.c\n\t  !_TAG_EXTRA_DESCRIPTION\tanonymous\t/Include tags for non-named objects like lambda/\n\t  !_TAG_EXTRA_DESCRIPTION\tfileScope\t/Include tags of file scope/\n\t  !_TAG_EXTRA_DESCRIPTION\tpseudo\t/Include pseudo tags/\n\t  !_TAG_EXTRA_DESCRIPTION\tsubparser\t/Include tags generated by subparsers/\n\t  ...\n\n\tA client tool can know \"{anonymous}\", \"{fileScope}\", \"{pseudo}\",\n\tand \"{subparser}\" extras are enabled from the output.\n\n\tUniversal Ctags version 6.0 will turn on this pseudo tag by default.\n\n``TAG_FIELD_DESCRIPTION``  (new in Universal Ctags)\n\tIndicates the names and descriptions of enabled fields::\n\n\t  !_TAG_FIELD_DESCRIPTION\t{field-name}\t/description/\n\t  !_TAG_FIELD_DESCRIPTION!{language-name}\t{field-name}\t/description/\n\n\tIf your tool relies on some fields, refer to the pseudo-tags of\n\tthis type.  A tool can reject a tags file that doesn't include\n\texpected fields, and raise an error in an early stage of\n\tprocessing.\n\n\tAn example of the pseudo-tags::\n\n\t  $ @CTAGS_NAME_EXECUTABLE@ --fields-C=+'{macrodef}' --extras=+p --pseudo-tags='{TAG_FIELD_DESCRIPTION}' -o - input.c\n\t  !_TAG_FIELD_DESCRIPTION\tfile\t/File-restricted scoping/\n\t  !_TAG_FIELD_DESCRIPTION\tinput\t/input file/\n\t  !_TAG_FIELD_DESCRIPTION\tname\t/tag name/\n\t  !_TAG_FIELD_DESCRIPTION\tpattern\t/pattern/\n\t  !_TAG_FIELD_DESCRIPTION\ttyperef\t/Type and name of a variable or typedef/\n\t  !_TAG_FIELD_DESCRIPTION!C\tmacrodef\t/macro definition/\n\t  ...\n\n\tA client tool can know \"{file}\", \"{input}\", \"{name}\", \"{pattern}\",\n\tand \"{typeref}\" fields are enabled from the output.\n\tThe fields are common in languages. In addition to the common fields,\n\tthe tool can known \"{macrodef}\" field of C language is also enabled.\n\n\tUniversal Ctags version 6.0 will turn on this pseudo tag by default.\n\n``TAG_FILE_ENCODING``  (new in Universal Ctags)\n\tTBW\n\n``TAG_FILE_FORMAT``\n\tSee also tags(5).\n\n``TAG_FILE_SORTED``\n\tSee also tags(5).\n\n``TAG_KIND_DESCRIPTION`` (new in Universal Ctags)\n\tIndicates the names and descriptions of enabled kinds::\n\n\t  !_TAG_KIND_DESCRIPTION!{language-name}\t{kind-letter},{kind-name}\t/description/\n\n\tIf your tool relies on some kinds, refer to the pseudo-tags of\n\tthis type.  A tool can reject the tags file that doesn't include\n\texpected kinds, and raise an error in an early stage of\n\tprocessing.\n\n\tKinds are language specific, so a language name is  always\n\tappended to the tag name as suffix.\n\n\tAn example of the pseudo-tags::\n\n\t  $ @CTAGS_NAME_EXECUTABLE@ --extras=+p --kinds-C=vfm --pseudo-tags='{TAG_KIND_DESCRIPTION}' -o - input.c\n\t  !_TAG_KIND_DESCRIPTION!C\tf,function\t/function definitions/\n\t  !_TAG_KIND_DESCRIPTION!C\tm,member\t/struct, and union members/\n\t  !_TAG_KIND_DESCRIPTION!C\tv,variable\t/variable definitions/\n\t  ...\n\n\tA client tool can know \"{function}\", \"{member}\", and \"{variable}\"\n\tkinds of C language are enabled from the output.\n\n\tUniversal Ctags version 6.0 will turn on this pseudo tag by default.\n\n``TAG_KIND_SEPARATOR`` (new in Universal Ctags)\n\tTBW\n\n``TAG_OUTPUT_EXCMD`` (new in Universal Ctags)\n\tIndicates the specified type of EX command with ``--excmd`` option.\n\n``TAG_OUTPUT_FILESEP`` (new in Universal Ctags)\n\tIndicates filename separators (\"slash\" or \"backslsh\") used in input fields.\n\n\tUniversal Ctags running on MS Windows replaces backslashes with slashes\n\twhen emitting input fields by default. This pseudo tag is for\n\tnotifying this replacement to client tools.\n\n\tSee also the description for ``--use-slash-as-filename-separator``\n\toption in ctags(1).\n\n``TAG_OUTPUT_MODE`` (new in Universal Ctags)\n\tIndicates whether using Universal Ctags extended escape sequences (\"u-ctags\") or not (\"e-ctags\").\n\n\tTo reduce illegal characters like <Tab> in tags files, Universal\n\tCtags extends the escape sequences originally used in Exuberant\n\tCtags, and applies the escaping rules to more fields.\n\n\tSee tags(5) about the escaping rules.\n\n\t``--output-format`` option is for choosing the output mode within\n\tthe tags output format. See ctags(1) about the option.\n\n\tIn \"e-ctags\" mode, for not violating the tags file format\n\tdescribed in tags(5), Universal Ctags skips emitting tag entries\n\tincluding illegal characters like <Tab>.\n\n\tIn input fields ({tagfile} in tags(5)), we have one more\n\tcondition for applying the escaping rules: ``\\`` characters\n\tare not used as filename separators. UNIX-like systems use ``/``\n\tfor the purpose. On MS Windows, Universal Ctags converts ``\\``\n\tin filenames to ``/`` by default. So, generally this condition is\n\tsatisfied. The condition is not satisfied only when you specify\n\t``--use-slash-as-filename-separator=no`` on MS Windows.\n\n``TAG_OUTPUT_VERSION`` (new in Universal Ctags 6.0)\n\tIndicates the language-common interface version of the output::\n\n\t  !_TAG_OUTPUT_VERSION\t{current}.{age}\t/.../\n\n\tThe public interface includes common fields, common extras,\n\tpseudo tags.\n\n\tThe maintainer of Universal Ctags may update the numbers,\n\t\"{current}\" and \"{age}\" in the same manner as explained\n\tin ``TAG_PARSER_VERSION``.\n\n``TAG_PARSER_VERSION`` (new in Universal Ctags 6.0)\n\tIndicates the interface version of the parser::\n\n\t  !_TAG_PARSER_VERSION!{language-name}\t{current}.{age}\t/.../\n\n\tThe public interfaces include kinds, roles, language specific fields,\n\tand language specific extras.\n\n\tThe maintainer of the parser for \"${language-name}\" may update\n\tthe numbers, \"{current}\" and \"{age}\" in the following rules:\n\n\t* If kinds, roles, language specific fields, and/or language\n\t  specific extras have been added, removed or changed since last\n\t  release, increment \"{current}\".\n\t* If they have been added since last release, increment \"{age}\".\n\t* If they have been removed since last release, set \"{age}\" to 0.\n\n\tThis concept is based on the versioning in **libtool**\n\t(`7.2 Libtool’s versioning system <https://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning>`_.)\n\tIn Universal Ctags, we simplified the concept with removing\n\t\"revision\" in the versioning in libtool.\n\n\tManual pages for languages may document changes that increase\n\tthe number of \"{current}\".\n\n``TAG_PATTERN_LENGTH_LIMIT`` (new in Universal Ctags)\n\tTBW\n\n``TAG_PROC_CWD`` (new in Universal Ctags)\n\tIndicates the working directory of @CTAGS_NAME_EXECUTABLE@ during processing.\n\n\tThis pseudo-tag helps a client tool solve the absolute paths for\n\tthe input files for tag entries even when they are tagged with\n\trelative paths.\n\n\tAn example of the pseudo-tags::\n\n\t  $ cat tags\n\t  !_TAG_PROC_CWD\t/tmp/\t//\n\t  main\tinput.c\t/^int main (void) { return 0; }$/;\"\tf\ttyperef:typename:int\n\t  ...\n\n\tFrom the regular tag for \"main\", the client tool can know the\n\t\"main\" is at \"input.c\".  However, it is a relative path. So if the\n\tdirectory where @CTAGS_NAME_EXECUTABLE@ run and the directory\n\twhere the client tool runs are different, the client tool cannot\n\tfind \"input.c\" from the file system. In that case,\n\t``TAG_PROC_CWD`` gives the tool a hint; \"input.c\" may be at \"/tmp\".\n\n``TAG_PROGRAM_NAME``\n\tIndicates the name of program generating this tags file.\n\n``TAG_PROGRAM_VERSION``\n\tIndicates the version of program generating this tags file.\n\n``TAG_ROLE_DESCRIPTION`` (new in Universal Ctags)\n\tIndicates the names and descriptions of enabled roles::\n\n\t  !_TAG_ROLE_DESCRIPTION!{language-name}!{kind-name}\t{role-name}\t/description/\n\n\tIf your tool relies on some roles, refer to the pseudo-tags of\n\tthis type. Note that a role owned by a disabled kind is not listed\n\teven if the role itself is enabled.\n\nREDUNDANT-KINDS\n---------------\nTBW (Write about --fields=+kKzZ)\n\nMULTIPLE-LANGUAGES FOR AN INPUT FILE\n------------------------------------\nUniversal ctags can run multiple parsers.\nThat means a parser, which supports multiple parsers (**guest parsers** or **sub-parsers**), may output tags for\ndifferent languages.\n\nGuest parsers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nA parser can run guest pursers on the areas in a source file.\n\nConsider the following text as a source file (\"input.html\"):\n\n.. code-block:: html\n\n\t<html><head>\n\t\t<script>class MyObject {}</script>\n\t\t<style type=\"text/css\">h1.heading { color: red; }</style>\n\t</htad>\n\t<h1 class='heading'>title</h1>\n\t</html>\n\nIf a user doesn't specify any extras, Universal ctags emits:\n\n.. code-block:: console\n\n\t$ ctags -o - input.html\n\ttitle\tinput.html\t/^<h1 class='heading'>title<\\/h1>$/;\"\th\n\nThese is no issue here.\n``running guest pursers`` extra is disabled by default.\n\nIf a user enables the ``running guest parsers`` extra with specifying\n``--extras=+{guest}`` or ``--extras=+g``, Universal ctags emits:\n\n.. code-block:: console\n\n\t$ ctags -o - --extras='{guest}' input.html\n\tMyObject\tinput.html\t/class MyObject {}/;\"\tc\n\th1.heading\tinput.html\t/h1.heading { color: red; }/;\"\tc\n\ttitle\tinput.html\t/^<h1 class='heading'>title<\\/h1>$/;\"\th\n\nUniversal ctags extracts the language objects for CSS and JavaScript; the HTML\nparser runs JavaScript parser on the area \"``<script>...</script>``\" area\nand CSS parser on the area \"``<style ...> ...</style>``\" area.\n\nIf a client tool assumes that ctags runs one parser for an input file,\nthe tool may tell \"MyObject is a class of HTML\" and/or \"h1.heading is\na class of HTML\" to its users. ``c`` is too few information to\ntell what is \"MyObject\" and what is \"h1.heading\" correctly. The\nclient tool needs more information.\n\n``language``/``l`` field can be used to show the language\nfor each tag.\n\n.. code-block:: console\n\n\t$ ctags -o - --extras='{guest}' --fields=+'{language}' input.html\n\tMyObject\tinput.html\t/class MyObject {}/;\"\tc\tlanguage:JavaScript\n\th1.heading\tinput.html\t/h1.heading { color: red; }/;\"\tc\tlanguage:CSS\n\ttitle\tinput.html\t/^<h1 class='heading'>title<\\/h1>$/;\"\th\tlanguage:HTML\n\nFor some class tools, the ``language:`` field provides enough information.\nUniversal ctags can emits more self-descriptive tag file.\n\n\nEnabling ``K`` field with ``--fields=+K`` option, Universal ctags uses\nlong-names instead of single-letter to represent kind fields:\n\n.. code-block:: console\n\n\t$ ctags -o - --extras='{guest}' --fields=+'{language}K' input.html\n\tMyObject\t/tmp/input.html\t/class MyObject {}/;\"\tclass\tlanguage:JavaScript\n\th1.heading\t/tmp/input.html\t/h1.heading { color: red; }/;\"\tclass\tlanguage:CSS\n\ttitle\t/tmp/input.html\t/^<h1 class='heading'>title<\\/h1>$/;\"\theading1\tlanguage:HTML\n\nThe long-name representation makes tag files larger.\nIf you want to keep a tag file small, you can make your tool utilize pseudo-tags\ninstead of enabling ``K`` field. Universal ctags emits the following line at the\nbeginning of a tags file by default:\n\n.. code-block:: console\n\n\t$ cat ./tags\n\t...\n\t!_TAG_KIND_DESCRIPTION!CSS\tc,class\t/classes/\n\t...\n\t!_TAG_KIND_DESCRIPTION!HTML\tc,class\t/classes/\n\t!_TAG_KIND_DESCRIPTION!HTML\th,heading1\t/H1 headings/\n\t...\n\t!_TAG_KIND_DESCRIPTION!JavaScript\tc,class\t/classes/\n\t...\n\nFrom the second field of the output, a tool can know the mapping\nbetween a single-letter for a kind and a long-name for the kind.\n\nUniversal ctags emits pseudo-tags to tag files by default. However, if\nyou make ctags emit to standard output with ``-o -`` or ``-f -``\noption, ctags doesn't print pseudo-tags.  ``pseudo``/``p`` extra\nforces emitting.\n\n.. code-block:: console\n\n\t$ ctags -o - --extras='{guest}{pseudo}' --fields=+'{language}' input.html\n\t...\n\t!_TAG_KIND_DESCRIPTION!CSS\tc,class\t/classes/\n\t...\n\t!_TAG_KIND_DESCRIPTION!HTML\tc,class\t/classes/\n\t!_TAG_KIND_DESCRIPTION!HTML\th,heading1\t/H1 headings/\n\t...\n\t!_TAG_KIND_DESCRIPTION!JavaScript\tc,class\t/classes/\n\t...\n\nSub-parsers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nTBW\n\nUTILIZING READTAGS\n-----------------------------------\nSee readtags(1) to know how to use readtags. This section is for discussing\nsome notable topics for client tools.\n\nBuild Filter/Sorter Expressions\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nCertain escape sequences in expressions are recognized by readtags. For\nexample, when searching for a tag that matches ``a\\?b``, if using a filter\nexpression like ``'(eq? $name \"a\\?b\")'``, since ``\\?`` is translated into a\nsingle ``?`` by readtags, it actually searches for ``a?b``.\n\nAnother problem is: If the client tools talks to readtags not by subprocess\ndirectly, but through a shell, then if a single quote appear in filter\nexpressions (which is also wrapped by single quotes), it terminates the\nexpression, producing broken expressions, and may even cause unintended shell\ninjection. Single quotes can be escaped using ``'\"'\"'``.\n\nSo, client tools need to:\n\n* Replace ``\\`` by ``\\\\``\n* Replace ``'`` by ``'\"'\"'``, if it talks to readtags through a shell.\n\ninside the expressions. If the expression also contains strings, ``\"`` in the\nstrings needs to be replaced by ``\\\"``.\n\nAnother thing to notice is that missing fields are represented by ``#f``, and\napplying string operators to them will produce an error. You should always\ncheck if a field is missing before applying string operators. See the\n\"Filtering\" section in readtags(1) to know how to do this. Run \"readtags -H\nfilter\" to see which operators take string arguments.\n\nBuild Filter/Sorter Expressions using Lisp Languages\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nClient tools written in Lisp could build the expression using lists. ``prin1``\n(in Common Lisp style Lisps) and ``write`` (in Scheme style Lisps) can\ntranslate the list into a string that can be directly used. For example, in\nEmacsLisp:\n\n.. code-block:: EmacsLisp\n\n   (let ((name \"hi\"))\n     (prin1 `(eq? $name ,name)))\n   => \"(eq\\\\? $name \"hi\")\"\n\nThe \"?\" is escaped, and readtags can handle it.\n\nEscape sequences produced by ``write`` in Scheme style Lisps are exactly those\nsupported by readtags, so any legal readtags expressions can be used. Common\nLisp style Lisps may produce escape sequences that are unrecgonized by\nreadtags, like ``\\#``, so symbols that contain \"#\" can't be used. Readtags\nprovides some aliases for these Lisps, so they should:\n\n* Use ``true`` for ``#t``.\n* Use ``false`` for ``#f``.\n* Use ``nil`` or ``()`` for ``()``.\n* Use ``(string->regexp \"PATTERN\")`` for ``#/PATTERN/``. Use\n  ``(string->regexp \"PATTERN\" :case-fold true)`` for ``#/PATTERN/i``. Notice\n  that ``string->regexp`` doesn't require escaping \"/\" in the pattern.\n\nNotice that if the client tool talks to readtags through a shell, then in the\nproduced string, ``'`` still needs to be replaced by ``'\"'\"'`` to prevent\nbroken expressions and shell injection.\n\nParse Readtags Output\n~~~~~~~~~~~~~~~~~~~~~\nIn the output of readtags, tabs can appear in all field values (e.g., the tag\nname itself could contain tabs), which makes it hard to split the line into\nfields. Client tools should use the ``-E`` option, which keeps the escape\nsequences in the tags file, so the only field that could contain tabs is the\npattern field.\n\nThe pattern field could:\n\n- Use a line number. It will look like ``number;\"`` (e.g. ``10;\"``).\n- Use a search pattern. It will look like ``/pattern/;\"`` or ``?pattern?;\"``.\n  Notice that the search pattern could contain tabs.\n- Combine these two, like ``number;/pattern/;\"`` or ``number;?pattern?;\"``.\n\nThese are true for tags files using extended format, which is the default one.\nThe legacy format (i.e. ``--format=1``) doesn't include the semicolons. It's\nold and barely used, so we won't discuss it here.\n\nClient tools could split the line using the following steps:\n\n* Find the first 2 tabs in the line, so we get the name and input field.\n* From the 2nd tab:\n\n  * If a ``/`` follows, then the pattern delimiter is ``/``.\n  * If a ``?`` follows, then the pattern delimiter is ``?``.\n  * If a number follows, then:\n\n\t* If a ``;/`` follows the number, then the delimiter is ``/``.\n\t* If a ``;?`` follows the number, then the delimiter is ``?``.\n\t* If a ``;\"`` follows the number, then the field uses only line number, and\n\t  there's no pattern delimiter (since there's no regex pattern). In this\n\t  case the pattern field ends at the 3rd tab.\n\n* After the opening delimiter, find the next unescaped pattern delimiter, and\n  that's the closing delimiter. It will be followed by ``;\"`` and then a tab.\n  That's the end of the pattern field. By \"unescaped pattern delimiter\", we\n  mean there's an even number (including 0) of backslashes before it.\n* From here, split the rest of the line into fields by tabs.\n\nThen, the escape sequences in fields other than the pattern field should be\ntranslated. See \"Proposal\" in tags(5) to know about all the escape sequences.\n\nMake Use of the Pattern Field\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe pattern field specifies how to find a tag in its source file. The code\ngenerating this field seems to have a long history, so there are some pitfalls\nand it's a bit hard to handle. A client tool could simply require the ``line:``\nfield and jump to the line it specifies, to avoid using the pattern field. But\nanyway, we'll discuss how to make the best use of it here.\n\nYou should take the words here merely as suggestions, and not standards. A\nclient tool could definitely develop better (or simpler) ways to use the\npattern field.\n\nFrom the last section, we know the pattern field could contain a line number\nand a search pattern. When it only contains the line number, handling it is\neasy: you simply go to that line.\n\nThe search pattern resembles an EX command, but as we'll see later, it's\nactually not a valid one, so some manual work are required to process it.\n\nThe search pattern could look like ``/pat/``, called \"forward search pattern\",\nor ``?pat?``, called \"backward search pattern\". Using a search pattern means\neven if the source file is updated, as long as the part containing the tag\ndoesn't change, we could still locate the tag correctly by searching.\n\nWhen the pattern field only contains the search pattern, you just search for\nit. The search direction (forward/backward) doesn't matter, as it's decided\nsolely by whether the ``-B`` option is enabled, and not the actual context. You\ncould always start the search from say the beginning of the file.\n\nWhen both the search pattern and the line number are presented, you could make\ngood use of the line number, by going to the line first, then searching for the\nnearest occurrence of the pattern. A way to do this is to search both forward\nand backward for the pattern, and when there is a occurrence on both sides, go\nto the nearer one.\n\nWhat's good about this is when there are multiple identical lines in the source\nfile (e.g. the COMMON block in Fortran), this could help us find the correct\none, even after the source file is updated and the tag position is shifted by a\nfew lines.\n\nNow let's discuss how to search for the pattern. After you trim the ``/`` or\n``?`` around it, the pattern resembles a regex pattern. It should be a regex\npattern, as required by being a valid EX command, but it's actually not, as\nyou'll see below.\n\nIt could begin with a ``^``, which means the pattern starts from the beginning\nof a line. It could also end with an *unescaped* ``$`` which means the pattern\nends at the end of a line. Let's keep this information, and trim them too.\n\nNow the remaining part is the actual string containing the tag. Some characters\nare escaped:\n\n* ``\\``.\n* ``$``, but only at the end of the string.\n* ``/``, but only in forward search patterns.\n* ``?``, but only in backward search patterns.\n\nYou need to unescape these to get the literal string. Now you could convert\nthis literal string to a regexp that matches it (by escaping, like\n``re.escape`` in Python or ``regexp-quote`` in Elisp), and assemble it with\n``^`` or ``$`` if the pattern originally has it, and finally search for the tag\nusing this regexp.\n\nRemark: About a Previous Format of the Pattern Field\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIn some earlier versions of Universal Ctags, the line number in the pattern\nfield is the actual line number minus one, for forward search patterns; or plus\none, for backward search patterns. The idea is to resemble an EX command: you\ngo to the line, then search forward/backward for the pattern, and you can\nalways find the correct one. But this denies the purpose of using a search\npattern: to tolerate file updates. For example, the tag is at line 50,\naccording to this scheme, the pattern field should be::\n\n\t49;/pat/;\"\n\nThen let's assume that some code above are removed, and the tag is now at\nline 45. Now you can't find it if you search forward from line 49.\n\nDue to this reason, Universal Ctags turns to use the actual line number. A\nclient tool could distinguish them by the ``TAG_OUTPUT_EXCMD`` pseudo tag, it's\n\"combine\" for the old scheme, and \"combineV2\" for the present scheme. But\nprobably there's no need to treat them differently, since \"search for the\nnearest occurrence from the line\" gives good result on both schemes.\n\nJSON OUTPUT\n-----------\nSee ctags-json-output(5).\n\nCHANGES\n-----------\n\nVersion 6.0\n~~~~~~~~~~~\n* ctags enables ``TAG_KIND_DESCRIPTION``, ``TAG_ROLE_DESCRIPTION``,\n  ``TAG_FIELD_DESCRIPTION``, and ``TAG_EXTRA_DESCRIPTION`` pseudo tags by default.\n* ``TAG_PARSER_VERSION`` is introduced.\n\nSEE ALSO\n--------\nctags(1), ctags-lang-python(7), ctags-incompatibilities(7), tags(5), ctags-json-output(5), readtags(1),\n`7.2 Libtool’s versioning system <https://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning>`\n"
  },
  {
    "path": "man/ctags-faq.7.rst.in",
    "content": ".. _ctags-faq(7):\n\n==============================================================\nctags-faq\n==============================================================\n--------------------------------------------------------------\nUniversal Ctags FAQ\n--------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nThis is the Universal Ctags FAQ (Frequently-Asked Questions).\nIt is based on `Exuberant Ctags FAQ <http://ctags.sourceforge.net/faq.html>`_\n\n.. contents::\n\nDESCRIPTION\n-----------\n\n.. TODO: https://github.com/universal-ctags/ctags/issues/2312\n\t#1421: feature: clean up stale tags when appending (`-a`)\n\t#2356: can't pre-process the macro but it works with Exuberant Ctags 5.8\n\t#2540: C/C++：conditional compilation like #ifdef will cause parse errror\n\nWhat is the difference between Universal Ctags and Exuberant Ctags?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUniversal Ctags is an unofficial fork of Exuberant Ctags.\nThe differences are summarized in ctags-incompatibilities(7) man page.\n\nThe most notable one is that Universal Ctags doesn't read ``~/.ctags`` file.\nInstead, it reads ``*.ctags`` under ``~/.ctags.d`` directory.\n\nHow can I avoid having to specify my favorite option every time?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nEither by setting the environment variable ``CTAGS`` to your custom\noptions, or putting them into a ``~/.ctags.d/anyname.ctags`` file in your home\ndirectory.\n\nWhat are these strange bits of text beginning with ``;\"`` which follow many of the lines in the tag file?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThese are *extension flags*. They are added in order to provide extra\ninformation about the tag that may be utilized by the editor in order to\nmore intelligently handle tags. They are appended to the EX command part of\nthe tag line in a manner that provides backwards compatibility with existing\nimplementations of the Vi editor. The semicolon is an EX command separator\nand the double quote begins an EX comment. Thus, the extension flags appear\nas an EX comment and should be ignored by the editor when it processes the\nEX command.\n\nSome non-vi editors, however, implement only the bare minimum of EX commands\nin order to process the search command or line number in the third field of\nthe tag file. If you encounter this problem, use the option ``--format=1`` to\ngenerate a tag file without these extensions (remember that you can set the\nCTAGS environment variable to any default arguments you wish to supply). Then\nask the supplier of your editor to implement handling of this feature of EX\ncommands.\n\nWhy can't I jump to ``class::member``?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBecause, by default, ctags only generates tags for the separate identifiers\nfound in the source files. If you specify the ``--extra=+q`` option, then\nctags will also generate a second, class-qualified tag for each class member\n(data and function/method) in the form ``class::member`` for C++, and in the form\n``class.method`` for Eiffel and Java.\n\nWhy do I end up on the wrong line when I jump to a tag?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBy default, ctags encodes the line number in the file where macro (``#define``)\ntags are found. This was done to remain compatible with the original UNIX\nversion of ctags. If you change the file containing the tag without\nrebuilding the tag file, the location of tag in the tag file may no longer\nmatch the current location.\n\nIn order to avoid this problem, you can specify the option ``--excmd=p``,\nwhich causes ctags to use a search pattern to locate macro tags. I have\nnever uncovered the reason why the original UNIX ctags used line numbers\nexclusively for macro tags, but have so far resisted changing the default\nbehavior of Exuberant (and Universal) Ctags to behave differently.\n\nHow do I jump to the tag I want instead of the wrong one by the same name?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA tag file is simple a list of tag names and where to find them. If there\nare duplicate entries, you often end up going to the wrong one because the\ntag file is sorted and your editor locates the first one in the tag file.\n\nStandard Vi provides no facilities to alter this behavior. However, Vim\nhas some nice features to minimize this problem, primarily by examining all\nmatches and choosing the best one under the circumstances. Vim also provides\ncommands which allow for selection of the desired matching tag.\n\nHow can I locate all references to a specific function or variable?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere are several packages already available which provide this capability.\nNamely, these are: GLOBAL source code tag system, GNU id-utils, cscope,\nand cflow. As of this writing, they can be found in the following locations:\n\n- GLOBAL:    http://www.gnu.org/software/global\n- id-utils:  http://www.gnu.org/software/idutils/idutils.html\n- cscope:    http://cscope.sourceforge.net\n- cflow:     ftp://www.ibiblio.org/pub/Linux/devel/lang/c\n\nWhy does appending tags to a tag file tag so long?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSometimes, in an attempt to build a global tag file for all source files in\na large source tree of many directories, someone will make an attempt to run\nctags in append (``-a``) mode on every directory in the hierarchy. Each time\nctags is invoked, its default behavior is to sort the tag file once the tags\nfor that execution have been added. As the cumulative tag file grows, the sort\ntime increases arithmetically.\n\nThe best way to avoid this problem (and the most efficient) is to make\nuse of the ``--recurse`` (or ``-R``) option of ctags by executing the following\ncommand in the root of the directory hierarchy (thus running ctags only once):\n\n\t.. code-block:: sh\n\n\t\tctags -R\n\nIf you really insist on running ctags separately on each directory, you can\navoid the sort pass each time by specifying the option ``--sort=no``. Once the\ntag file is completely built, use the sort command to manually sort the\nfinal tag file, or let the final invocation of ctags sort the file.\n\nHow should I set up tag files for a multi-level directory hierarchy?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere are a few ways of approaching this:\n\n1.  A local tag file in each directory containing only the tags for source\n    files in that directory.\n\n2.  One single big, global tag file present in the root directory of your\n    hierarchy, containing all tags present in all source files in the\n    hierarchy.\n\n3.  A local tag file in each directory containing only the tags for source\n    files in that directory, in addition to one single global tag file\n    present in the root directory of your hierarchy, containing all\n    non-static tags present in all source files in the hierarchy.\n\n4.  A local tag file in each directory of the hierarchy, each one\n    containing all tags present in source files in that directory and all\n    non-static tags in every directory below it (note that this implies\n    also having one big tag file in the root directory of the hierarchy).\n\nEach of these approaches has its own set of advantages and disadvantages,\ndepending upon your particular conditions. Which approach is deemed best\ndepends upon the following factors:\n\nA.  The ability of your editor to use multiple tag files.\n\n    If your editor cannot make use of multiple tag files (original vi\n    implementations could not), then one large tag file is the only way to\n    go if you ever desire to jump to tags located in other directories. If\n    you never need to jump to tags in another directory (i.e. the source\n    in each directory is entirely self-contained), then a local tag file\n    in each directory will fit your needs.\n\nB.  The time is takes for your editor to look up a tag in the tag file.\n\n    The significance of this factor depends upon the size of your source\n    tree and on whether the source files are located on a local or remote\n    file system. For source and tag files located on a local file system,\n    looking up a tag is not as big a hit as one might first imagine, since\n    vi implementations typically perform a binary search on a sorted tag\n    file. This may or may not be true for the editor you use. For files\n    located on a remote file system, reading a large file is an expensive\n    operation.\n\nC.  Whether or not you expect the source code to change and the time it\n    takes to rebuild a tag file to account for changes to the source code.\n\n    While Universal Ctags is particularly fast in scanning source code\n    (around 1-2 MB/sec), a large project may still result in objectionable\n    delays if one wishes to keep their tag file(s) up to date on a\n    frequent basis, or if the files are located on a remote file system.\n\nD.  The presence of duplicate tags in the source code and the ability to\n    handle them.\n\n    The impact of this factor is influenced by the following three issues:\n\n    1.  How common are duplicate tags in your project?\n\n    2.  Does your editor provide any facilities for dealing with duplicate\n        tags?\n\n        While standard vi does not, many modern vi implementations, such\n        as Vim have good facilities for selecting the desired match from\n        the list of duplicates. If your editor does not support duplicate\n        tags, then it will typically send you to only one of them, whether\n        or not that is the one you wanted (and not even notifying you that\n        there are other potential matches).\n\n    3.  What is the significance of duplicate tags?\n\n        For example, if you have two tags of the same name from entirely\n        isolated software components, jumping first to the match found\n        in component B while working in component A may be entirely\n        misleading, distracting or inconvenient (to keep having to choose\n        which one if your editor provides you with a list of matches).\n        However, if you have two tags of the same name for parallel builds\n        (say two initialization routines for different hosts), you may\n        always want to specify which one you want.\n\nOf the approaches listed above, I tend to favor Approach 3. My editor of\nchoice is Vim, which provides a rich set of features for handling multiple\ntag files, which partly influences my choice. If you are working with\nsource files on a remote file system, then I would recommend either\nApproach 3 or Approach 4, depending upon the hit when reading the global\ntag file.\n\nThe advantages of Approach 3 are many (assuming that your editor has\nthe ability to support both multiple tag files and duplicate tags). All\nlookups of tag located in the current directory are fast and the local\ntag file can be quickly and easily regenerated in one second or less\n(I have even mapped a keystroke to do this easily). A lookup of a\n(necessarily non-static) tag found in another directory fails a lookup in\nthe local tag file, but is found in the global tag file, which satisfies\nall cross-directory lookups. The global tag file can be automatically\nregenerated periodically with a cron job (and perhaps the local tag files\nalso).\n\nNow I give an example of how you would implement Approach 3. Means of\nimplementing the other approaches can be performed in a similar manner.\n\nHere is a visual representation of an example directory hierarchy:\n\n::\n\n\tproject\n\t`-----misccomp\n\t|       `...\n\t`-----sysint\n\t        `-----client\n\t        |       `-----hdrs\n\t        |       `-----lib\n\t        |       `-----src\n\t        |       `-----test\n\t        `-----common\n\t        |       `-----hdrs\n\t        |       `-----lib\n\t        |       `-----src\n\t        |       `-----test\n\t        `-----server\n\t                `-----hdrs\n\t                `-----lib\n\t                `-----src\n\t                `-----test\n\nHere is a recommended solution (conceptually) to build the tag files:\n\n1.  Within each of the leaf nodes (i.e. ``hdrs``, ``lib``, ``src``, ``test``) build a tag\n    file using \"``ctags *.[ch]``\". This can be easily be done for the whole\n    hierarchy by making a shell script, call it ``dirtags``, containing the\n    following lines:\n\n\t.. code-block:: sh\n\n\t\t#!/bin/sh\n\t\tcd $1\n\t\tctags *\n\n    Now execute the following command:\n\n\t.. code-block:: sh\n\n\t\tfind * -type d -exec dirtags {} \\;\n\n    These tag files are trivial (and extremely quick) to rebuild while\n    making changes within a directory. The following Vim key mapping is\n    quite useful to rebuild the tag file in the directory of the current\n    source file:\n\n\t.. code-block:: text\n\n\t\t:nmap ,t :!(cd %:p:h;ctags *.[ch])&<CR><CR>\n\n2.  Build the global tag file:\n\n\t.. code-block:: sh\n\n\t\tcd ~/project\n\t\tctags --file-scope=no -R\n\n    thus constructing a tag file containing only non-static tags for all\n    source files in all descendent directories.\n\n3.  Configure your editor to read the local tag file first, then consult\n    the global tag file when not found in the local tag file. In Vim,\n    this is done as follows:\n\n\t.. code-block:: text\n\n\t\t:set tags=./tags,tags,~/project/tags\n\nIf you wish to implement Approach 4, you would need to replace the\n``dirtags`` script of step 1 with the following:\n\n\t.. code-block:: sh\n\n\t\t#!/bin/sh\n\t\tcd $1\n\t\tctags *\n\t\t# Now append the non-static tags from descendent directories\n\t\tfind * -type d -prune -print | ctags -aR --file-scope=no -L-\n\nAnd replace the configuration of step 3 with this:\n\n\t.. code-block:: text\n\n\t\t:set tags=./tags;$HOME,tags\n\nAs a caveat, it should be noted that step 2 builds a global tag file whose\nfile names will be relative to the directory in which the global tag file\nis being built. This takes advantage of the Vim ``tagrelative`` option,\nwhich causes the path to be interpreted a relative to the location of the\ntag file instead of the current directory. For standard vi, which always\ninterprets the paths as relative to the current directory, we need to\nbuild the global tag file with absolute path names. This can be\naccomplished by replacing step 2 with the following:\n\n\t.. code-block:: sh\n\n\t\tcd ~/project\n\t\tctags --file-scope=no -R `pwd`\n\nDoes Universal Ctags support Unicode file names?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. MEMO: from https://github.com/universal-ctags/ctags/issues/1837\n\nYes, Unicode file names are supported on unix-like platforms (Linux, macOS,\nCygwin, etc.).\n\nHowever, on MS Windows, you need to use Windows 10 version 1903 or later to use\nUnicode file names. (This is an experimental feature, though.) On older versions\non Windows, Universal Ctags only support file names represented in the current\ncode page. If you still want to use Unicode file names on them, use Cygwin or\nMSYS2 version of Universal Ctags as a workaround.\n\nWhy does zsh cause \"zsh: no matches found\" error?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. MEMO: from https://github.com/universal-ctags/ctags/issues/2842\n\nzsh causes error on the following cases;\n\n\t.. code-block:: sh\n\n\t\tctags --extra=+* ...\n\t\tctags --exclude=foo/* ...\n\nThis is the 2nd most significant incompatibility *feature* of zsh.\n\nCited from \"Z-Shell Frequently-Asked Questions\", \"`2.1: Differences from sh and\nksh <http://zsh.sourceforge.net/FAQ/zshfaq02.html>`_\";\n\n\t... The next most classic difference is that unmatched glob patterns cause\n\tthe command to abort; set ``NO_NOMATCH`` for those.\n\nYou may add \"``setopt nonomatch``\" on your ``~/.zshrc``. Or you can escape glob\npatterns with backslash;\n\n\t.. code-block:: sh\n\n\t\tctags --extra=+\\* ...\n\t\tctags --exclude=foo/\\* ...\n\nOr quote them;\n\n\t.. code-block:: sh\n\n\t\tctags '--extra=+*' ...\n\t\tctags '--exclude=foo/*' ...\n\nSEE ALSO\n--------\n\nThe official Universal Ctags web site at:\n\nhttps://ctags.io/\n\nctags(1), tags(5)\n\nAUTHOR\n------\n\nThis FAQ is based on `Exuberant Ctags FAQ <http://ctags.sourceforge.net/faq.html>`_ by\nDarren Hiebert and vberthoux@users.sourceforge.net\n\nUniversal Ctags project: https://ctags.io/\n"
  },
  {
    "path": "man/ctags-incompatibilities.7.rst.in",
    "content": ".. _ctags-incompatibilities(7):\n\n==============================================================\nctags-incompatibilities\n==============================================================\n--------------------------------------------------------------\nIncompatibilities between Universal Ctags and Exuberant Ctags\n--------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** [options] [file(s)]\n|\t**@ETAGS_NAME_EXECUTABLE@** [options] [file(s)]\n\nDESCRIPTION\n-----------\n\nThis page describes major incompatible changes introduced to\nUniversal Ctags forked from Exuberant Ctags.\n\nOption files loading at starting up time (preload files)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUniversal Ctags doesn't load ``~/.ctags`` at starting up time.\nFile paths for preload files are changed.\nSee \"FILES\" section of ctags(1).\n\nEnvironment variables for arranging command lines\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUniversal Ctags doesn't read ``CTAGS`` and/or ``ETAGS`` environment\nvariables.\n\nBehavior when ``--excmd=mixed`` is given\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nExuberant Ctags uses line numbers as addresses for C preprocessor\nmacro definition tags. Universal Ctags uses patterns for the tags.\n\nIncompatibilities in command line interface\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nOrdering in a command line\n....................................................................................\n\n.. NOTE: #1889\n\nThe command line format of Universal Ctags is \"``ctags [options]\n[source_file(s)]``\" following the standard POSIX convention.\n\nExuberant Ctags accepts a option following a source file.\n\n.. code-block:: console\n\n\t$ ctags -o - foo.c --list-kinds=Sh\n\tf  functions\n\nUniversal Ctags warns and ignores the option ``--list-kinds=Sh`` as follows.\n\n.. code-block:: console\n\n\t$ ctags -o - foo.c --list-kinds=Sh\n\tctags: Warning: cannot open input file \"--list-kinds=Sh\" : No such file or directory\n\ta\tfoo.c\t/^void a () {}$/;\"\tf\ttyperef:typename:void\n\tb\tfoo.c\t/^void b () {}$/;\"\tf\ttyperef:typename:void\n\nThe order of application of patterns and extensions in ``--langmap``\n....................................................................................\n\nWhen applying mappings for a name of given source file,\nExuberant Ctags tests file name patterns *AFTER* file extensions\n(*e-map-order*). Universal Ctags does this differently; it tests file\nname patterns *BEFORE* file extensions (*u-map-order*).\n\nThis incompatible change is introduced to deal with the following\nsituation:\n\n\t* ``build.xml`` as a source file,\n\t* The Ant parser declares it handles a file name pattern ``build.xml``, and\n\t* The XML parser declares it handles a file extension ``.xml``.\n\nWhich parser should be used for parsing ``build.xml``?  The assumption\nof Universal Ctags is the user may want to use the Ant parser; the\nfile name pattern it declares is more specific than the file extension\nthat the XML parser declares. However, e-map-order chooses the XML\nparser.\n\nSo Universal Ctags uses the u-map-order even though it introduces an\nincompatibility.\n\n``--list-map-extensions=<language>`` and ``--list-map-patterns=<language>``\noptions are helpful to verify and the file extensions and the file\nname patterns of given *<language>*.\n\nRemove ``--file-tags`` and ``--file-scope`` options\n....................................................................................\n\nEven in Exuberant Ctags, ``--file-tags`` is not documented in its man page.\nInstead of specifying ``--file-tags`` or ``--file-tags=yes``, use\n``--extras=+f`` or ``--extras=+{inputFile}``.\n\nInstead of specifying ``--file-tags=no``, use\n``--extras=-f`` or ``--extras=-{inputFile}``.\n\nUniversal Ctags introduces ``F/fileScope`` extra as the replacement for\n``--file-scope`` option.\n\nInstead of specifying ``--file-tags`` or ``--file-tags=yes``, use\n``--extras=+F`` or ``--extras=+{fileScope}``.\n\nInstead of specifying ``--file-tags=no``, use\n``--extras=-F`` or ``--extras=-{fileScope}``.\n\nIncompatibilities in language and kind definitions\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nLanguage name defined with ``--langdef=name`` option\n....................................................................................\n\nThe characters you can use are more restricted than Exuberant Ctags.\nFor more details, see the description of ``--langdef=name`` in ctags-optlib(7).\n\nObsoleting ``--<LANG>-kinds`` option\n....................................................................................\n\nSome options have *<LANG>* as parameterized parts in their name like\n``--foo-<LANG>=...`` or ``--<LANG>-foo=...``. The most of all such\noptions in Exuberant Ctags have the former form, ``--foo-<LANG>=...``.\nThe exception is ``--<LANG>-kinds``.\n\nUniversal Ctags uses the former form for all *<LANG>* parameterized\noption. Use ``--kinds-<LANG>`` instead of ``--<LANG>-kinds`` in\nUniversal Ctags. ``--<LANG>-kinds`` still works but it will be\nremoved in the future.\n\nThe former form may be friendly to shell completion engines.\n\nDisallowing to define a kind with ``file`` as name\n....................................................................................\n\nThe kind name ``file`` is reserved.  Using it as part of kind spec in\n``--regex-<LANG>`` option is now disallowed.\n\nDisallowing to define a kind with '``F``' as letter\n....................................................................................\n\nThe kind letter '``F``' is reserved.  Using it as part of a kind spec in\n``--regex-<LANG>`` option is now disallowed.\n\nDisallowing to use other than alphabetical character as kind letter\n....................................................................................\n\nExuberant Ctags accepts a character other than alphabetical character\nas kind letter in ``--regex-<LANG>=...`` option.  Universal Ctags\naccepts only an alphabetical character.\n\nAcceptable characters as parts of a kind name\n....................................................................................\n\nExuberant Ctags accepts any character as a part of a kind name\ndefined with ``--regex-<LANG>=/regex/replacement/kind-spec/``.\n\nUniversal Ctags accepts only an alphabetical character as\nthe initial letter of a kind name.\nUniversal Ctags accepts only an alphabetical character or\nnumerical character as the rest letters.\n\nAn example::\n\n  --regex-Foo=/abstract +class +([a-z]+)/\\1/a,abstract class/i\n\nUniversal Ctags rejects this because the kind name, ``abstract class``,\nincludes a whitespace character.\n\nThis requirement is for making the output of Universal Ctags follow\nthe tags file format.\n\nA combination of a kind letter and a kind name\n....................................................................................\n\nIn Universal Ctags, the combination of\na kind letter and a kind name must be unique in a language.\n\nYou cannot define more than one kind reusing a kind letter with\ndifferent kind names. You cannot define more than one kind reusing a\nkind name with different kind letters.\n\nAn example::\n\n  --regex-Foo=/abstract +class +([a-z]+)/\\1/a,abstractClass/i\n  --regex-Foo=/attribute +([a-z]+)/\\1/a,attribute/i\n\nUniversal Ctags rejects this because the kind letter, '``a``', used twice\nfor defining a kind ``abstractClass`` and ``attribute``.\n\n\nIncompatibilities in tags file format\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUsing numerical character in the name part of tag tagfield\n....................................................................................\n\nThe version 2 tags file format, the default output format of\nExuberant Ctags, accepts only alphabetical characters in the name part\nof tag tagfield.\n\nUniversal Ctags introduces an exception to this specification; it may\nuse numerical characters in addition to alphabetical characters as the\nletters other than initial letter of the name part.\n\nThe kinds ``heading1``, ``heading2``, and ``heading3`` in the HTML parser\nare the examples.\n\nTruncating the pattern for long input lines\n....................................................................................\n\nTo prevent generating overly large tags files, a pattern field is\ntruncated, by default, when its size exceeds 96 bytes. A different\nlimit can be specified with ``--pattern-length-limit=N``. Specifying\n0 as *N* results no truncation as Exuberant Ctags does not.\n\nKind letters and names\n....................................................................................\n\nA kind letter '``F``' and a kind name ``file`` are reserved in the\nmain part. A parser cannot have a kind conflicting with\nthese reserved ones. Some incompatible changes are introduced\nto follow the above rule.\n\n* Cobol's ``file`` kind is renamed to ``fileDesc`` because the\n  kind name ``file`` is reserved.\n\n* Ruby's '``F``' (singletonMethod) is changed to '``S``'.\n\n* SQL's '``F``' (field) is changed to '``E``'.\n\nSEE ALSO\n--------\nctags(1), ctags-optlib(7), and tags(5).\n"
  },
  {
    "path": "man/ctags-json-output.5.rst.in",
    "content": ".. _ctags-json-output(5):\n\n==============================================================\nctags-json-output\n==============================================================\n---------------------------------------------------------------------------------\nJSON based ctags output\n---------------------------------------------------------------------------------\n:Version: 1.0\n:Manual group: Universal Ctags\n:Manual section: 5\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** --output-format=json ...\n\nDESCRIPTION\n-----------\nUniversal Ctags supports `JSON <https://www.json.org/>`_ (strictly\nspeaking `JSON Lines <https://jsonlines.org/>`_) output format if the\nctags executable is built with ``libjansson``.  JSON output goes to\nstandard output by default.\n\nFORMAT\n------\nEach JSON line represents a tag.\n\n.. code-block:: console\n\n\t$ ctags --extras=+p --output-format=json --fields=-s input.py\n\t{\"_type\": \"ptag\", \"name\": \"JSON_OUTPUT_VERSION\", \"path\": \"1.0\", \"pattern\": \"in development\"}\n\t{\"_type\": \"ptag\", \"name\": \"TAG_FILE_SORTED\", \"path\": \"1\", \"pattern\": \"0=unsorted, 1=sorted, 2=foldcase\"}\n\t...\n\t{\"_type\": \"tag\", \"name\": \"Klass\", \"path\": \"/tmp/input.py\", \"pattern\": \"/^class Klass:$/\", \"language\": \"Python\", \"kind\": \"class\"}\n\t{\"_type\": \"tag\", \"name\": \"method\", \"path\": \"/tmp/input.py\", \"pattern\": \"/^    def method(self):$/\", \"language\": \"Python\", \"kind\": \"member\", \"scope\": \"Klass\", \"scopeKind\": \"class\"}\n\t...\n\nA key not starting with ``_`` is mapped to a field of ctags.\n\"``--output-format=json --list-fields``\" options list the fields.\n\nA key starting with ``_`` represents meta information of the JSON\nline.  Currently only ``_type`` key is used. If the value for the key\nis ``tag``, the JSON line represents a regular tag. If the value is\n``ptag``, the line represents a pseudo-tag.\n\nThe output format can be changed in the\nfuture. ``JSON_OUTPUT_VERSION`` pseudo-tag provides a change\nclient-tools to handle the changes.  Current version is \"1.0\". A\nclient-tool can extract the version with ``path`` key from the\npseudo-tag.\n\nThe JSON output format is newly designed and has no limitation found\nin the default tags file format.\n\n* The values for ``kind`` key are represented in long-name flags.\n  No one-letter is here.\n\n* Scope names and scope kinds have distinguished keys: ``scope`` and ``scopeKind``.\n  They are combined in the default tags file format.\n\nDATA TYPE USED IN A FIELD\n-------------------------\nValues for the most of all keys are represented in JSON string type.\nHowever, some of them are represented in string, integer, and/or boolean type.\n\n\"``--output-format=json --list-fields``\" options show What kind of data type\nused in a field of JSON.\n\n.. code-block:: console\n\n\t$ ctags --output-format=json --list-fields\n\t#LETTER NAME           ENABLED LANGUAGE         JSTYPE FIXED DESCRIPTION\n\tF       input          yes     NONE             s--    no    input file\n\t...\n\tP       pattern        yes     NONE             s-b    no    pattern\n\t...\n\tf       file           yes     NONE             --b    no    File-restricted scoping\n\t...\n\te       end            no      NONE             -i-    no    end lines of various items\n\t...\n\n``JSTYPE`` column shows the data types.\n\n'``s``'\n\tstring\n\n'``i``'\n\tinteger\n\n'``b``'\n\tboolean (true or false)\n\nFor an example, the value for ``pattern`` field of ctags takes a string or a boolean value.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New key ``kindName`` for ``TAG_ROLE_DESCRIPTION`` pseudo tag\n\n  ``kindName`` is added to store the name of the kind in ``TAG_ROLE_DESCRIPTION``\n  pseudo tags.\n\n  In 0.0, a \"TAG_ROLE_DESCRIPTION\" pseudo tag was printed like:\n\n  .. code-block:: JSON\n\n      {\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\",\n                        \"parserName\": \"LANG!KIND\", }\n\n  In 1.0, it is printed like:\n\n  .. code-block:: JSON\n\n      {\"_type\": \"ptag\", \"name\": \"TAG_ROLE_DESCRIPTION\",\n                        \"parserName\": \"LANG\",\n                        \"kindName\": \"KIND\",  }\n\nSEE ALSO\n--------\nctags(1), tags(5), ctags-client-tools(7)\n"
  },
  {
    "path": "man/ctags-lang-asm.7.rst.in",
    "content": ".. _ctags-lang-asm(7):\n\n==============================================================\nctags-lang-asm\n==============================================================\n-----------------------------------------------------------------------------\nRandom notes about tagging Assembly language source code with Universal Ctags\n-----------------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Asm ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Asm ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Asm=+.asm ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Asm=+.ASM ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Asm=+.s ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Asm=+.S ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging assembly language\nsource code.\n\nThe parser of Universal Ctags has been extended to support the source\ncode to be processed with *GNU assembler* (*Gas*).\n\nPARAMETERS\n----------\nThe Asm parser has some parameters for adapting it to different\nassembler implementations.\n\nWriting a parser for assembly language source code is not easy because\nthe syntax for the language differ depending on the implementations of\nassemblers and target CPU architectures. For example, in *NASM*, `;`\nis a starter of a line comment. On the other hand, in Gas for i386,\n`;` is a line separator. The parameters explained this man page are\nfor mitigating the gaps of syntax.\n\nUse ``--param-Asm.{parameter}={value}`` option for adjusting the value\nfor a parameter. For example:\n\n.. code-block:: console\n\n\t$ @CTAGS_NAME_EXECUTABLE@ ... --param-Asm.runCPreProcessor=false ...\n\nThis command line sets ``false`` to ``runCPreProcessor`` parameter.\n\n``--list-params=Asm`` lists available parameters available in the\nAsm parser.\n\n``runCPreProcessor``: running C preprocessor\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBy default, the CPreProcessor parser processes the assembly language\nsource code before the Asm parser does.\n\nThe main effects of running the CPreProcessor parser;\n\n* lines started from `//` are stripped as comments,\n* areas surrounded by the pair of `/*` and `*/` are\n  stripped as comments, and\n* macros defined with `#define` are extracted as tags.\n\nSet ``runCPreProcessor`` to ``false`` for disabling the CPreProcessor\nparser running before the Asm parser.\n\n``commentCharsAtBOL``: adjusting line comment starter at the beginning of line\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBy default, the Asm parser ignores lines starting from `;`, `*`, or\n`@` as comments. `//` is also ignored if `runCPreProcessor` is `true`.\n\n``commentCharsAtBOL`` is for changing the characters for line comments.\n`BOL` is acronym standing for \"the beginning of line.\" The characters\nact as comment starters only if they are at the beginning\nof lines.\n\nThe next example if for assembler input using `!` and `>` as the comment starter:\n\n.. code-block:: console\n\n\t$ @CTAGS_NAME_EXECUTABLE@ ... --param-Asm.commentCharsAtBOL='!>' ...\n\n``commentCharsInMOL``: adjusting line comment starter in the middle of line\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSome dialects of assemblers support comments starting from the middle of line.\nA `;` character starts a comment anywhere on the line in Gas for CRIS for example.\n\n``commentCharsInMOL`` is for specifying the character for line comments.\n`MOL` is acronym standing for \"the middle of line.\" Unlike characters\nspecified with ``commentCharsAtBOL``, the characters specified with\n``commentCharsInMOL`` act as comment starts even if they are in the\nmiddle of lines.\n\nBy default, the Asm parser has no ``commentCharsInMOL`` characters.\n\n``extraLinesepChars``: adding line separators\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe Asm parser processes its input line-oriented way.  By default, the\nparser recognizes `\\n` as a line separator.  ``extraLinesepChars`` is\nfor adding more line separators.\n\nIn Gas for AArch64, the `;` character can be used as line separators.\nThe next example for adjusting the Asm parser to the extra line\nseparator:\n\n.. code-block:: console\n\n\t$ @CTAGS_NAME_EXECUTABLE@ ... --param-Asm.extraLinesepChars=';' ...\n\nEXPANDING C PREPROCESSOR MACROS\n-------------------------------\nThe Asm parser has the ability to expand **C preprocessor macros**\nbefore parsing.\n\n.. note::\n\n   Don't confuse C preprocessor macros and assembler implementation\n   specific macros. The Asm parser expands only C preprocessor macros.\n\nSpecifying following options are must for expansion::\n\n  --param-Asm.runCPreProcessor=true\n  --fields=+{signature}\n  --fields-CPreProcessor=+{macrodef}\n\nWith the above options, the parser expands macros defined in command\nline with ``-D`` option. See ctags(1) about the way to define a macro\nwith the ``-D`` option.\n\nWith ``--param-CPreProcessor._expand=1`` option, the parser expands\nmacros defined in the current input file in addition to macros defined\nwith the ``-D`` option.\n\nThough the parser expands macros, the parser doesn't extract language\nobjects like labels as you expect. You must adjust the parser specific\nparameters to utilize the macro expansion feature effectively. See\n\nAn example of macro expansion\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\"input.S\"\n\n.. code-block::\n\n\t#define ENTRY(LABEL) .global LABEL\t;\\\n\tLABEL\n\n\tENTRY(main):\n\t\tnop\n\n\"output.tags\"\nwith \"--options=NONE -o - --param-Asm.useCPreProcessor=1 --param-CPreProcessor._expand=1 --fields=+{signature} --fields-CPreProcessor=+{macrodef} --param-Asm.extraLinesepChars=; --fields-CPreProcessor=+{macrodef} input.S\"\n\n.. code-block:: tags\n\n\tENTRY\tinput.S\t/^#define ENTRY(/;\"\td\tfile:\tsignature:(LABEL)\tmacrodef:.global LABEL ;LABEL\n\tmain\tinput.S\t/^ENTRY(main):$/;\"\tl\n\tmain\tinput.S\t/^ENTRY(main):$/;\"\ts\n\nThe definition of `ENTRY` assumes `;` is a line separator in the host assembly language.\n``--param-Asm.extraLinesepChars=;`` is for satisfying the assumption in ctags side.\n\nKnown limitations\n~~~~~~~~~~~~~~~~~\nThe parser has no ability to expand the macros defined outside of the\ncurrent input file. The parser doesn't consider `#undef` when\nexpanding.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* The kind ``section`` is deleted.\n  The section specified with `.section` directive as tagged as\n  ``placement`` role of ``section`` kind of ``Asm`` language.\n  These kind and role are deleted.\n\n  Instead, it is tagged as ``destination`` role of ``inputSection``\n  kind of ``LdScript`` language.\n\nSEE ALSO\n--------\nctags(1),\nctags-lang-asm(7),\nInfo entries for GNU assembler\n"
  },
  {
    "path": "man/ctags-lang-autoit.7.rst.in",
    "content": ".. _ctags-lang-autoit(7):\n\n==============================================================\nctags-lang-autoit\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging AutoIt source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+AutoIt ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=AutoIt ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-AutoIt=+.au3 ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging AutoIt source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* Drop ``$`` from tags for variables names.\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-automake.7.rst.in",
    "content": ".. _ctags-lang-automake(7):\n\n==============================================================\nctags-lang-automake\n==============================================================\n--------------------------------------------------------------------------------------\nRandom notes about tagging Automake source code (Makefile.am) with Universal Ctags\n--------------------------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Automake ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Automake ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Automake=+.am ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Automake source code (Makefile.am).\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* Add ``canonicalizedName`` extra.\n* Add ``pseudodir`` kind.\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-c++.7.rst.in",
    "content": ".. _ctags-lang-c++(7):\n\n==============================================================\nctags-lang-c++\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging C++ source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+C++ ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=C++ ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-C++=+.c++  ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-C++=+.cc  ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-C++=+.cpp  ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-C++=+.h  ...\n|   ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging C++ source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New field ``section``\n\n* New field ``alias``\n\nChange since \"1.1\"\n~~~~~~~~~~~~~~~~~~\n\n* New kinds ``module`` and ``partition``\n\n* New roles ``imported`` and ``exported`` for ``header`` kind\n\nSEE ALSO\n--------\nctags(1),\nctags-lang-ldscript(7),\n`The new C/C++ parser <https://docs.ctags.io/en/latest/parser-cxx.html>`_ (https://docs.ctags.io/en/latest/parser-cxx.html)\n"
  },
  {
    "path": "man/ctags-lang-c.7.rst.in",
    "content": ".. _ctags-lang-c(7):\n\n==============================================================\nctags-lang-c\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging C source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+C ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=C ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-C=+.c ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging C source code.\n\nVERSIONS\n--------\n\nSee the output of\n\n| **@CTAGS_NAME_EXECUTABLE@** --describe-language=C\n\nSEE ALSO\n--------\nctags(1),\nctags-lang-ldscript(7),\n`The new C/C++ parser <https://docs.ctags.io/en/latest/parser-cxx.html>`_ (https://docs.ctags.io/en/latest/parser-cxx.html)\n"
  },
  {
    "path": "man/ctags-lang-cuda.7.rst.in",
    "content": ".. _ctags-lang-cuda(7):\n\n==============================================================\nctags-lang-cuda\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging CUDA source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+CUDA ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=CUDA ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-CUDA=+.cu  ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-CUDA=+.cuh  ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging CUDA source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New field ``section``\n\n* New field ``alias``\n\nSEE ALSO\n--------\nctags(1),\nctags-lang-ldscript(7),\n`The new C/C++ parser <https://docs.ctags.io/en/latest/parser-cxx.html>`_ (https://docs.ctags.io/en/latest/parser-cxx.html)\n"
  },
  {
    "path": "man/ctags-lang-elm.7.rst.in",
    "content": ".. _ctags-lang-elm(7):\n\n==============================================================\nctags-lang-elm\n==============================================================\n-------------------------------------------------------------------\nRandom notes about tagging Elm source code with Universal Ctags\n-------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Elm ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Elm ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Elm=+.elm ...\n\nDESCRIPTION\n-----------\nThe Elm parser is a PEG parser using PackCC, which is part of the\nctags infrastructure. It should correctly process all top level\nstatements, however there is a limitation with functions embedded\nin let/in blocks. They will mostly be fine, but sometimes a\nfunction in a let/in block will be omitted.\n\nEXAMPLES\n--------\n\nImports\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nImported modules are tagged, and their role is \"imported\", not \"def\".\nTypes, functions, etc which are exposed via imported module have their\nrole as \"exposed\".\n\nExposed items are marked as being in the scope of their own module,\nnot the module that's doing the importing.\n\n\"input.elm\"\n\n.. code-block:: Elm\n\n\tmodule SomeMod exposing (..)\n\n\timport MyMod exposing\n\t  ( map\n\t  , Maybe\n\t  , Result(..)\n\t  , MyList(Empty)\n\t  )\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+r --fields=+r input.elm\"\n\n.. code-block:: tags\n\n\tSomeMod\tinput.elm\t/^module SomeMod exposing (..)$/;\"\tm\troles:def\n\tMyMod\tinput.elm\t/^import MyMod exposing$/;\"\tm\troles:imported\n\tmap\tinput.elm\t/^  ( map$/;\"\tf\tmodule:MyMod\troles:exposed\n\tMaybe\tinput.elm\t/^  , Maybe$/;\"\tt\tmodule:MyMod\troles:exposed\n\tResult\tinput.elm\t/^  , Result(..)$/;\"\tt\tmodule:MyMod\troles:exposed\n\tMyList\tinput.elm\t/^  , MyList(Empty)$/;\"\tt\tmodule:MyMod\troles:exposed\n\tEmpty\tinput.elm\t/^  , MyList(Empty)$/;\"\tc\ttype:MyMod.MyList\troles:exposed\n\nNamespaces\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nNamespaces are tagged and their role is \"def\".\n\n\"input.elm\"\n\n.. code-block:: Elm\n\n\tmodule AMod exposing (..)\n\n\timport MyImport as NSpace exposing (impFunc)\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+r --fields=+r input.elm\"\n\n.. code-block:: tags\n\n\tAMod\tinput.elm\t/^module AMod exposing (..)$/;\"\tm\troles:def\n\tNSpace\tinput.elm\t/^import MyImport as NSpace exposing (impFunc)$/;\"\tn\tmodule:AMod\troles:def\tmoduleName:MyImport\n\tMyImport\tinput.elm\t/^import MyImport as NSpace exposing (impFunc)$/;\"\tm\troles:imported\n\timpFunc\tinput.elm\t/^import MyImport as NSpace exposing (impFunc)$/;\"\tf\tmodule:MyImport\troles:exposed\n\nType names\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nConstructors top level functions will have type names.\n\n\"input.elm\"\n\n.. code-block:: Elm\n\n\tfuncA : Int -> Int\n\tfuncA a = a + 1\n\n\ttype B\n\t    = B1Cons\n\t      { x : Float\n\t      , y : Float\n\t      }\n\t    | B2Cons String Integer\n\t    | B3Cons\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+r --fields=+r input.elm\"\n\n.. code-block:: tags\n\n\tfuncA\tinput.elm\t/^funcA a = a + 1$/;\"\tf\ttyperef:typename:Int -> Int\troles:def\n\tB\tinput.elm\t/^type B$/;\"\tt\troles:def\n\tB1Cons\tinput.elm\t/^    = B1Cons$/;\"\tc\ttype:B\ttyperef:typename:{ x : Float , y : Float } -> B\troles:def\n\tB2Cons\tinput.elm\t/^    | B2Cons String Integer$/;\"\tc\ttype:B\ttyperef:typename:String -> Integer -> B\troles:def\n\tB3Cons\tinput.elm\t/^    | B3Cons$/;\"\tc\ttype:B\ttyperef:typename:B\troles:def\n\nFunction parameter lists\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFunction parameter lists can be extracted into the tags file\nsignature field. They are not really function signatures, but\nit's the closest concept available in ctags.\nUse \"--fields=+S\".\n\n.. code-block:: Elm\n\n    funcA a1 a2 =\n        a1 + a2\n\n\"output.tags\"\nwith \"--sort=no --extras=+r --fields=+rS\"\n\n.. code-block:: tags\n\n    funcA\tinput.elm\t/^funcA a1 a2 =$/;\"\tf\tsignature:a1 a2\troles:def\n\nKNOWN LIMITATIONS\n-----------------\nThe ctags signature field is used for function parameter lists, even\nthough it's not an idea field. See above.\n\nElm requires all statements at the same logical level to have the\nsame indentation. If there is additional indentation that line is part\nof the previous one. Therefore without over-complicating the\nPEG parser we have the following limitations...\n\nSometimes functions in let/in blocks will be omitted.\n\nFunctions in let/in blocks will be marked as being in the scope of their\nouter function, regardless of how deeply nested the let/in block is.\n\nFunctions in let/in blocks won't have type names.\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7)\n"
  },
  {
    "path": "man/ctags-lang-emacslisp.7.rst.in",
    "content": ".. _ctags-lang-emacslisp(7):\n\n==============================================================\nctags-lang-emacslisp\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging EmacsLisp source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+EmacsLisp ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=EmacsLisp ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Lisp=+.el ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging EmacsLisp source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* Add ``definer`` field.\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-fortran.7.rst.in",
    "content": ".. _ctags-lang-fortran(7):\n\n==============================================================\nctags-lang-fortran\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging Fortran source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Fortran ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Fortran ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Fortran=+.f ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging FORTRAN source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New extra ``linkName``.\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-gdscript.7.rst.in",
    "content": ".. _ctags-lang-gdscript(7):\n\n==============================================================\nctags-lang-gdscript\n==============================================================\n--------------------------------------------------------------------\nRandom notes about tagging GDScript source code with Universal Ctags\n--------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+GDScript ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=GDScript ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-GDScript=+.gd ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging GDScript source code\nwith Universal Ctags.\n\nStoring Annotations\n-------------------\nLike the Python parser storing decorations to ``decorations`` field,\nthe GDScript parser stores annotations\nstarting from `@` to the language specific field, ``annotations``.\nThough the field is enabled explicitly in following examples, the\nfield is enabled by default.\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\t@export\n\tvar s = \"Hello\"\n\n\t@master\n\tfunc f(msg):\n\t\tprint(msg)\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --fields-GDScript=+{annotations} -o - input.gd\"\n\n.. code-block:: tags\n\n\ts\tinput.gd\t/^var s = \"Hello\"$/;\"\tv\tannotations:export\n\tf\tinput.gd\t/^func f(msg):$/;\"\tm\tannotations:master\n\nExtracting `func`\n-----------------\nA language object defined with `func` keyword is tagged with ``method`` kind.\nLike annotations, the parser stores keywords modifying `func` like `static` to\nthe ``annotations`` field.\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\tfunc f(x):\n\t\treturn x\n\n\tstatic func f_s(x):\n\t\treutrn x\n\n\tremote func f_r(x):\n\t\treturn x\n\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --fields=+K --fields-GDScript=+{annotations} -o - input.gd\"\n\n.. code-block:: tags\n\n\tf\tinput.gd\t/^func f(x):$/;\"\tmethod\n\tf_s\tinput.gd\t/^static func f_s(x):$/;\"\tmethod\tannotations:static\n\tf_r\tinput.gd\t/^remote func f_r(x):$/;\"\tmethod\tannotations:remote\n\nTagging implicitly defined classes\n----------------------------------\n\"A file is a class!\" in GDScript.  A class is implicitly\ndefined. Functions, variables, constants, and signals are parts of the\nclass though the class is unnamed by default.\n\nIf the language specific extra, ``implicitClass``, is enabled, the\nparser makes a anonymous tag for the class. The parser fills the scope\nfields of the tags for all language objects defined in the file with\nthe anonymous tag.\n\nLet's see an example demonstrating the effect of the extra.\n\nTurning off the extra:\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\tfunc f(x):\n\t\treturn x\n\n\"output.tags\"\nwith \"--options=NONE --fields=+KZ --extras-GDScript=-{implicitClass} -o - input.gd\"\n\n.. code-block:: tags\n\n\tf\tinput.gd\t/^func f(x):$/;\"\tmethod\n\nTurning on the extra:\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\tfunc g(x):\n\t\treturn x\n\n\"output.tags\"\nwith \"--options=NONE --fields=+KZ --extras-GDScript=+{implicitClass} -o - input.gd\"\n\n.. code-block:: tags\n\n\tanon_class_84011bee0100\tinput.gd\t/^func g(x):$/;\"\tclass\n\tg\tinput.gd\t/^func g(x):$/;\"\tmethod\tscope:class:anon_class_84011bee0100\n\nTagging the name specified with `class_name`\n---------------------------------------------\n`class_name` is a keyword for giving a name to the implicitly defined\nclass.  If ``implicitClass`` is turned off, the parser just extract\nthe name coming after the keyword with ``class`` kind. If\n``implicitClass`` is turned on, the parser converts the anonymous tag\nto a non-anonymous tag with the specified name.  When converting,\nthe parser also updates scope fields of the other tags in the file.\n\nTurning off the extra:\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\tclass_name c\n\n\tfunc f(x):\n\t\treturn x\n\n\"output.tags\"\nwith \"--options=NONE --fields=+KZ --extras-GDScript=-{implicitClass} -o - input.gd\"\n\n.. code-block:: tags\n\n\tc\tinput.gd\t/^class_name c$/;\"\tclass\n\tf\tinput.gd\t/^func f(x):$/;\"\tmethod\n\nTurning on the extra:\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\tclass_name C\n\tfunc g(x):\n\t\treturn x\n\n\"output.tags\"\nwith \"--options=NONE --fields=+KZ --extras-GDScript=+{implicitClass} -o - input.gd\"\n\n.. code-block:: tags\n\n\tC\tinput.gd\t/^class_name C$/;\"\tclass\n\tg\tinput.gd\t/^func g(x):$/;\"\tmethod\tscope:class:C\n\nFilling ``inherits`` field\n--------------------------\n`extends` keyword specifies the super class for the implicitly defined class.\nIf `implicitClass` extra is turned on, the parser fills ``inherits`` field\nof the tag for the implicitly defined class with the name of super class.\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\textends B\n\tclass_name C\n\n\"output.tags\"\nwith \"--options=NONE --fields=+Ki --extras-GDScript=+{implicitClass} -o - input.gd\"\n\n.. code-block:: tags\n\n\tC\tinput.gd\t/^class_name C$/;\"\tclass\tinherits:B\n\nWhen `--extras=+r` is given, the parser extracts the class specified with the\n`extends` keyword as a reference tag of ``class`` kind with ``extended`` role.\n\n\"input.gd\"\n\n.. code-block:: GDScript\n\n\textends B\n\n\"output.tags\"\nwith \"--options=NONE --fields=+rEK --extras=+r -o - input.gd\"\n\n.. code-block:: tags\n\n\tB\tinput.gd\t/^extends B$/;\"\tclass\troles:extended\textras:reference\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-i18nrubygem.7.rst.in",
    "content": ".. _ctags-lang-i18nrubgem(7):\n\n==============================================================\nctags-lang-i18nrubgem\n==============================================================\n------------------------------------------------------------------------\nRandom notes about tagging input for I18n Ruby Gem with Universal Ctags\n------------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n:Expected feature: yaml\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --extras=+s --languages=+I18nRubyGem ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --extras=+s --language-force=I18nRubyGem ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --extras=+s --map-I18nRubyGem=+.yaml ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --extras=+s --map-I18nRubyGem=+.yml ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging input for I18n Ruby\nGem [RUBYI18N]_. I18nRubyGem is a subparser running on Yaml parser. If a\ntop-level scalar token of a given Yaml source input is a local name [ISOCODES]_,\nI18nRubyGem activates itself. If not, I18nRubyGem does nothing.\n\n\"input.yaml\"\n\n.. code-block:: YAML\n\n\t---\n\tja:\n\t  msg:\n\t    error: エラー\n\t    function: 関数\n\n\"output.tags\"\nwith \"--options=NONE -o - --fields=+E input.yaml\"\n\n.. code-block:: tags\n\n\terror\tinput.yaml\t/^    error: エラー$/;\"\tk\tkeyInMiddle:ja.msg\textras:subparser\n\tfunction\tinput.yaml\t/^    function: 関数$/;\"\tk\tkeyInMiddle:ja.msg\textras:subparser\n\tja.msg.error\tinput.yaml\t/^    error: エラー$/;\"\tk\tkeyInMiddle:ja.msg\textras:subparser,localeful\n\tja.msg.function\tinput.yaml\t/^    function: 関数$/;\"\tk\tkeyInMiddle:ja.msg\textras:subparser,localeful\n\tmsg.error\tinput.yaml\t/^    error: エラー$/;\"\tk\tlocale:ja\textras:subparser,localeless\n\tmsg.function\tinput.yaml\t/^    function: 関数$/;\"\tk\tlocale:ja\textras:subparser,localeless\n\n\nWith the options, the parser emits three tag entries for a key:\n\"error\", \"js.msg.error\", and \"msg.error\" for the key \"error\", The\nparser emits \"error\" at the first line always.\n\nTo emit \"ja.msg.error\", a ``localeful`` extra tag, at the fifth line\nalways. If you specify ``--extra=+q`` or ``--extra=+{qualified}``,\nctags emits the same tag twice: a ``localeful`` tag, and a ``qualified`` tag.\nYou can suppress the ``localeful`` extra tags., specify\n``--extras-I18nRubyGem=-{localeful}``.\n\nTo emit \"msg.error\", a ``localeless`` extra tag, at the fifth line\nalways. The parser creates a ``localeless`` extra tag by truncating\nthe first component (e.g. \"ja.\") from the associated full qualified\nextra tag (e.g. \"ja.msg.error\").  ``localeless`` extra is enabled by\ndefault. If you don't need ``localeless`` extra tags, specify\n``--extras-I18nRubyGem=-{localeless}``.\n\nThe parser doesn't make tag entries for top-level and mid-level components like\n``ja`` and ``msg`` by default. If you need them, specify\n``--kinds-I18nRubyGem=+{locale}`` and/or\n``--kinds-I18nRubyGem=+{keyInMiddle}``.\n\nKNOWN BUGS\n----------\nThe mechanism activating I18nRubyGem subparser doesn't work well for YAML\nsource input containing multiple documents.\n\nSEE ALSO\n--------\nctags(1)\n\nREFERENCES\n----------\n.. [RUBYI18N] Ruby I18n, https://github.com/ruby-i18n/i18n\n.. [ISOCODES] iso-codes, https://salsa.debian.org/iso-codes-team/iso-codes\n"
  },
  {
    "path": "man/ctags-lang-iPythonCell.7.rst.in",
    "content": ".. _ctags-lang-iPythonCell(7):\n\n==============================================================\nctags-lang-iPythonCell\n==============================================================\n-------------------------------------------------------------------\nThe man page of the iPythonCell parser for Universal Ctags\n-------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --extras=+{subparser} --languages=+iPythonCell,Python \\\\\n|                     [--extras-IPythonCell=+{doubleSharps}] \\\\\n|                     [--regex-IPythonCell=/<PATTERN>/\\\\n/c/] ...\n\nDESCRIPTION\n-----------\niPythonCell parser is a subparser stacked on top of the Python parser.\nIt works when:\n\n* the Python parser is enabled,\n* the ``subparser`` extra is enabled, and\n* the iPythonCell parser itself is enabled.\n\nThe iPythonCell parser extracts cells explained as in vim-ipython-cell\n(https://github.com/hanschen/vim-ipython-cell/blob/master/README.md).\n\nKIND(S)\n-------\nThe iPythonCell parser defines only a ``cell`` kind.\n\nEXTRA(S)\n--------\n\nTagging cells staring with ``##...`` is disabled by default because\nthe pattern is too generic; with that pattern unwanted tags can be extracted.\n\nEnable ``doubleSharps`` language specific extra for tagging cells\nstaring with ``##...``.\n\nCUSTOMIZING\n-----------\nIf your favorite cell pattern is not supported in the parser, you can\ndefine the pattern in your ``.ctagd.d/your.ctags`` or command lines.\nHere is an example how to support \"``# CTAGS: ...``\":\n\n\"input.py\"\n\n.. code-block:: Python\n\n\tx=1\n\t# CTAGS: DEFINE F\n\tdef F():\n\t\t# CTAGS: DO NOTING\n\t\tpass\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --extras=+{subparser} --regex-IPythonCell=/[ \\t]*# CTAGS:[ ]?(.*)$/\\1/c/ -o - input.py\"\n\n.. code-block:: tags\n\n   x\tinput.py\t/^x=1$/;\"\tv\n   DEFINE F\tinput.py\t/^# CTAGS: DEFINE F$/;\"\tc\n   F\tinput.py\t/^def F():$/;\"\tf\n   DO NOTING\tinput.py\t/^\t# CTAGS: DO NOTING$/;\"\tc\n\nYou can put \"``--regex-IPythonCell=/[ \\t]*# CTAGS:[ ]?(.*)$/\\1/c/``\" in ``your.ctags``\nto avoid specifying the pattern repeatedly.\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7), ctags-lang-python(7)\n"
  },
  {
    "path": "man/ctags-lang-inko.7.rst.in",
    "content": ".. _ctags_lang-inko(7):\n\n======================================================================\nctags-lang-inko\n======================================================================\n\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Inko ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Inko ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Inko=+.inko ...\n\nDESCRIPTION\n-----------\nThis man page describes the Inko parser for Universal Ctags.\n\nThe input file is expected to be valid Inko source code, otherwise the output of\nctags is undefined.\n\nTags are generated for objects, traits, methods, attributes, and constants.\nString literals are ignored.\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7)\n"
  },
  {
    "path": "man/ctags-lang-javascript.7.rst.in",
    "content": ".. _ctags-lang-javascript(7):\n\n==============================================================\nctags-lang-javascript\n==============================================================\n-----------------------------------------------------------------------\nRandom notes about tagging JavaScript source code with Universal Ctags\n-----------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+JavaScript ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=JavaScript ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-JavaScript=+.js ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging JavaScript source code.\n\nCLASSES\n-------\n\nES6 introduced the ``class`` keyword, but there is still the original method of defining a function and attaching a ``prototype``.  ctags follows the convention that function names that start with a capital letter are class constructors.\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New role ``foreigndecl`` for ``function`` kind\n\nChange since \"1.1\"\n~~~~~~~~~~~~~~~~~~\n\n* New field ``properties``\n\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7)\n"
  },
  {
    "path": "man/ctags-lang-julia.7.rst.in",
    "content": ".. _ctags-lang-julia(7):\n\n==============================================================\nctags-lang-julia\n==============================================================\n-------------------------------------------------------------------\nRandom notes about tagging Julia source code with Universal-ctags\n-------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal-ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Julia ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Julia ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Julia=+.jl ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Julia source code.\n\nTAGGING ``import`` AND ``using`` EXPRESSIONS\n--------------------------------------------\n\nSummary\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n`using X`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     used               N/A\n\t==== ========== ================== ===================\n\n`using X: a, b`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     namespace          N/A\n\ta, b unknown    used               scope:module:X\n\t==== ========== ================== ===================\n\n`import X`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     imported           N/A\n\t==== ========== ================== ===================\n\n`import X.a, Y.b`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX, Y module     namespace          N/A\n\ta    unknown    imported           scope:module:X\n\tb    unknown    imported           scope:module:Y\n\t==== ========== ================== ===================\n\n`import X: a, b`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     namespace          N/A\n\ta,b  unknown    imported           scope:module:X\n\t==== ========== ================== ===================\n\nExamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\"input.jl\"\n\n.. code-block:: Julia\n\n\tusing X0\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzK input.jl\"\n\n.. code-block:: tags\n\n\tX0\tinput.jl\t/^using X0$/;\"\tkind:module\troles:used\n\n``--extras=+r`` (or ``--extras=+{reference}``) option is needed for this tag,\nsince it's a reference tag. This is because module ``X`` is not defined here.\nIt is defined in another file. Enable ``roles:`` field with ``--fields=+r`` is\nfor recording that the module is \"used\", i.e., loaded by ``using``.\n\n\"input.jl\"\n\n.. code-block:: Julia\n\n\timport X1.a, X2.b, X3\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzKZ input.jl\"\n\n.. code-block:: tags\n\n\tX1\tinput.jl\t/^import X1.a, X2.b, X3$/;\"\tkind:module\troles:namespace\n\tX2\tinput.jl\t/^import X1.a, X2.b, X3$/;\"\tkind:module\troles:namespace\n\tX3\tinput.jl\t/^import X1.a, X2.b, X3$/;\"\tkind:module\troles:imported\n\ta\tinput.jl\t/^import X1.a, X2.b, X3$/;\"\tkind:unknown\tscope:module:X1\troles:imported\n\tb\tinput.jl\t/^import X1.a, X2.b, X3$/;\"\tkind:unknown\tscope:module:X2\troles:imported\n\nWhy ``X1`` and ``X2`` have role \"namespace\", while ``X3`` have role \"imported\"?\nIt's because the symbol ``a`` in module ``X1``, and ``b`` in module ``X2`` are\nbrought to the current scope, but ``X1`` and ``X2`` themselves are not. We use\n\"namespace\" role for such modules.\n\n``X3`` is different. The symbol ``X3``, together with all exported symbols in\n``X3``, is brought to current scope. For such modules, we use \"imported\" or\n\"used\" role depending whether they are loaded by ``import`` or ``using``.\n\nAlso, notice that ``a`` and ``b`` have the \"unknown\" kind. This is because we\ncannot know whether it's a function, constant, or macro, etc.\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7)\n"
  },
  {
    "path": "man/ctags-lang-kconfig.7.rst.in",
    "content": ".. _ctags-lang-kconfig(7):\n\n==============================================================\nctags-lang-kconfig\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging Kconfig source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Kconfig ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Kconfig ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Kconfig=+(Kconfig*) ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Kconfig scripts.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``variable``\n\nSEE ALSO\n--------\nctags(1),\n`Kconfig Language <https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html>`_ (https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html),\n`Kconfig macro language <https://www.kernel.org/doc/html/latest/kbuild/kconfig-macro-language.html>`_ (https://www.kernel.org/doc/html/latest/kbuild/kconfig-macro-language.html),\n"
  },
  {
    "path": "man/ctags-lang-ldscript.7.rst.in",
    "content": ".. _ctags-lang-ldscript(7):\n\n==============================================================\nctags-lang-ldscript\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging LdScript source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+LdScript ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=LdScript ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-LdScript=+.lds ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-LdScript=+.lds.S ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging LdScript source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New role ``destination`` for ``inputSection`` kind\n\n* New role ``aliased`` for  ``symbol`` kind\n\nSEE ALSO\n--------\nctags(1),\nctags-lang-asm(7),\nctags-lang-c(7),\nctags-lang-c++(7),\nctags-lang-cuda(7)\n"
  },
  {
    "path": "man/ctags-lang-lex.7.rst.in",
    "content": ".. _ctags-lang-lex(7):\n\n==============================================================\nctags-lang-lex\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging Lex source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+LEX ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=LEX ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Lex=+.l ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging LEX source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New role ``grouping`` for ``cond`` kind\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-lisp.7.rst.in",
    "content": ".. _ctags-lang-lisp(7):\n\n==============================================================\nctags-lang-lisp\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging Lisp source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Lisp ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Lisp ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Lisp=+.cl ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Lisp=+.clisp ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Lisp=+.l ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Lisp=+.lisp ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Lisp=+.lsp ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Lisp source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* Add kinds:\n\n  + ``class``,\n  + ``generic``,\n  + ``method``,\n  + ``parameter``,\n  + ``struct``, and\n  + ``type``.\n\n* Add ``definer`` field.\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-make.7.rst.in",
    "content": ".. _ctags-lang-make(7):\n\n==============================================================\nctags-lang-make\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging Make source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Make ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Make ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Make=+([Mm]akefile) --map-Make=+(GNUmakefile) ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Make=+.mak --map-Make=+.mk ...\n\nDESCRIPTION\n-----------\nThis parser extracts macro and target definitions. It also extracts included files as references.\n\nExamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\"input.mak\"\n\n.. code-block:: Makefile\n\n   -include base.mak\n\n   SRC = hello.c\n\n   all: hello\n   hello: hello.o\n   hello.o: hello.c\n   $(CC) -c $(CFLAGS) $(CPPFLAGS) $<\n\n\"output.tags\"\nwith \"--options=NONE --extras=+r --fields=+KlrE -o - input.mak\"\n\n.. code-block:: tags\n\n   SRC\tinput.mak\t/^SRC = hello.c$/;\"\tmacro\tlanguage:Make\troles:def\n   all\tinput.mak\t/^all: hello$/;\"\ttarget\tlanguage:Make\troles:def\n   base.mak\tinput.mak\t/^-include base.mak$/;\"\tmakefile\tlanguage:Make\troles:optional\textras:reference\n   hello\tinput.mak\t/^hello: hello.o$/;\"\ttarget\tlanguage:Make\troles:def\n   hello.o\tinput.mak\t/^hello.o: hello.c$/;\"\ttarget\tlanguage:Make\troles:def\n\n\nEXTRACTING CPP MACRO DEFINTIONS DEFINED WITH -DFOO\n---------------------------------------------------\nWith ``-D`` option in a C compiler like gcc, a programmer can define a\nmacro outside C source files. The options appears on a Makefile\nfrequently. For an example:\n\n.. code-block:: Makefile\n\n   CPPFLAGS = -DDEBUG\n\nThe Make parser has heuristics [DINMAKE]_ for extracting the macros defined with\nthe option. With enabling ``CppDef`` extra, you can turn on the heuristics.\n\nExamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\"input.mak\"\n\n.. code-block:: Makefile\n\n   -include base.mak\n\n   CFLAGS = -g -O2\n   CPPFLAGS = -DOUTPUT=stdout\n   SRC = hello.c\n\n   all: hello\n   hello: hello.o\n   hello.o: hello.c\n   $(CC) -c $(CFLAGS) $(CPPFLAGS) $<\n\n\"output.tags\"\nwith \"--options=NONE --extras-Make=+{CppDef} --fields=+KlE -o - input.mak\"\n\n.. code-block:: tags\n\n   CFLAGS\tinput.mak\t/^CFLAGS = -g -O2$/;\"\tmacro\tlanguage:Make\n   CPPFLAGS\tinput.mak\t/^CPPFLAGS = -DOUTPUT=stdout$/;\"\tmacro\tlanguage:Make\n   OUTPUT\tinput.mak\t/^CPPFLAGS = -DOUTPUT=stdout$/;\"\tmacro\tlanguage:CPreProcessor\textras:CppDef\n   SRC\tinput.mak\t/^SRC = hello.c$/;\"\tmacro\tlanguage:Make\n   all\tinput.mak\t/^all: hello$/;\"\ttarget\tlanguage:Make\n   hello\tinput.mak\t/^hello: hello.o$/;\"\ttarget\tlanguage:Make\n   hello.o\tinput.mak\t/^hello.o: hello.c$/;\"\ttarget\tlanguage:Make\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New extra ``CppDef`` [DINMAKE]_\n\nSEE ALSO\n--------\nctags(1)\n\n.. [DINMAKE] `CONFIG_X86_X32_ABI is not visible (defined in Makefile, not C or Kconfig) <https://github.com/bootlin/elixir/issues/221>`_ (https://github.com/bootlin/elixir/issues/221)\n"
  },
  {
    "path": "man/ctags-lang-markdown.7.rst.in",
    "content": ".. _ctags-lang-markdown(7):\n\n==============================================================\nctags-lang-markdown\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging Markdown source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Markdown ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Markdown ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Markdown=+.md ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Markdown documents [XSYNTAX]_.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``hashtag`` [HASHTAG]_\n\nSEE ALSO\n--------\nctags(1)\n\n.. [XSYNTAX] `Extend Syntax <https://www.markdownguide.org/extended-syntax/>`_ (https://www.markdownguide.org/extended-syntax/) in Markdown Guide\n.. [HASHTAG] `Hashtags in Markdown notes for VSCode <https://github.com/vanadium23/markdown-hashtags#hashtags-in-markdown-notes-for-vscode>`_ (https://github.com/vanadium23/markdown-hashtags#hashtags-in-markdown-notes-for-vscode)\n"
  },
  {
    "path": "man/ctags-lang-meson.7.rst.in",
    "content": ".. _ctags-lang-meson(7):\n\n==============================================================\nctags-lang-meson\n==============================================================\n-----------------------------------------------------------------------\nRandom notes about tagging Meson build scripts with Universal Ctags\n-----------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Meson ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Meson ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Meson=+(meson.build) ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Meson build scripts.\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kinds ``cfgdata`` and ``cfgvar``\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7)\n"
  },
  {
    "path": "man/ctags-lang-odin.7.rst.in",
    "content": ".. _ctags-lang-odin(7):\n\n==============================================================\nctags-lang-odin\n==============================================================\n\nNotes about tagging Odin source code with Universal Ctags\n\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Odin ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Odin ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Odin=+.odin ...\n\nDESCRIPTION\n-----------\nThis man page gathers notes about tagging Odin source code\nwith Universal Ctags.\n\nThe Odin parser tags packages, procedures, constants, variables,\nstructs, enums, unions, struct members, enum values, type aliases,\nand foreign imports.\n\nDistinguishing types from constants\n------------------------------------\nIn Odin, the syntax for a type alias and a constant binding are\nidentical::\n\n\tMy_Type :: Other_Type\n\tMY_CONST :: OTHER_CONST\n\nWhen the right-hand side of a ``::`` binding is a plain identifier,\nthe parser cannot syntactically determine whether it is a type alias\nor a constant. In this case, the parser uses a naming-convention\nheuristic: if the name on the left-hand side contains any lowercase\nletter, it is tagged as a ``type`` (kind ``t``); if the name is\nentirely uppercase (and underscores/digits), it is tagged as a\n``const`` (kind ``c``).\n\nThis follows the strong Odin convention that type names use\n``Ada_Case`` and constants use ``SCREAMING_SNAKE_CASE``.\n\n\"input.odin\"\n\n.. code-block:: Odin\n\n\tpackage example\n\n\tHandle :: distinct rawptr\n\tVector2 :: [2]f32\n\tCallback :: proc(x: int) -> bool\n\tMy_Alias :: Some_Type\n\tMAX_SIZE :: SOME_VALUE\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --fields=+K -o - input.odin\"\n\n.. code-block:: tags\n\n\texample\tinput.odin\t/^package example$/;\"\tpackage\n\tHandle\tinput.odin\t/^Handle :: distinct rawptr$/;\"\ttype\tpackage:example\n\tVector2\tinput.odin\t/^Vector2 :: [2]f32$/;\"\ttype\tpackage:example\n\tCallback\tinput.odin\t/^Callback :: proc(x: int) -> bool$/;\"\ttype\tpackage:example\n\tMy_Alias\tinput.odin\t/^My_Alias :: Some_Type$/;\"\ttype\tpackage:example\n\tMAX_SIZE\tinput.odin\t/^MAX_SIZE :: SOME_VALUE$/;\"\tconst\tpackage:example\n\nNote that when the right-hand side is a keyword such as ``struct``,\n``enum``, ``union``, ``distinct``, ``proc``, ``map``, or a syntactic\nform such as ``^Type``, ``[N]Type``, or ``#type``, the parser\nidentifies the kind unambiguously without relying on the heuristic.\n\nThe heuristic will misclassify names that break the convention, such\nas an all-uppercase type alias (``HANDLE :: Some_Type`` would be\ntagged as ``const``) or a lowercase-containing constant\n(``kMaxSize :: SOME_VALUE`` would be tagged as ``type``).\nIn practice, these cases are rare in idiomatic Odin code.\n\nForeign blocks\n--------------\nThe parser extracts procedure and variable declarations from\n``foreign`` blocks.\n\n\"input.odin\"\n\n.. code-block:: Odin\n\n\tpackage ffi\n\n\tforeign import libc \"system:libc.so\"\n\n\tforeign libc {\n\t    puts :: proc \"c\" (s: cstring) -> i32 ---\n\t    errno: i32\n\t}\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --fields=+K -o - input.odin\"\n\n.. code-block:: tags\n\n\tffi\tinput.odin\t/^package ffi$/;\"\tpackage\n\tlibc\tinput.odin\t/^foreign import libc \"system:libc.so\"$/;\"\tforeign\tpackage:ffi\n\tputs\tinput.odin\t/^    puts :: proc \"c\" (s: cstring) -> i32 ---$/;\"\tproc\tpackage:ffi\n\terrno\tinput.odin\t/^    errno: i32$/;\"\tvar\tpackage:ffi\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7)\n"
  },
  {
    "path": "man/ctags-lang-powershell.7.rst.in",
    "content": ".. _ctags-lang-powershell(7):\n\n==============================================================\nctags-lang-powershell\n==============================================================\n-----------------------------------------------------------------------\nRandom notes about tagging PowerShell source code with Universal Ctags\n-----------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|  **@CTAGS_NAME_EXECUTABLE@** ... --languages=+PowerShell ...\n|  **@CTAGS_NAME_EXECUTABLE@** ... --language-force=PowerShell ...\n|  **@CTAGS_NAME_EXECUTABLE@** ... --map-powershell=+.ps1 ...\n|  **@CTAGS_NAME_EXECUTABLE@** ... --map-powershell=+.psm1 ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging PowerShell source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``enumlabel``\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-python.7.rst.in",
    "content": ".. _ctags-lang-python(7):\n\n==============================================================\nctags-lang-python\n==============================================================\n-------------------------------------------------------------------\nRandom notes about tagging python source code with Universal Ctags\n-------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Python ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Python ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Python=+.py ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging python source code.\n\nTAGGING ``import`` STATEMENTS\n-----------------------------\n\nSummary\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n`import X`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     imported           N/A\n\t==== ========== ================== ===================\n\n`import X as Y`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\tX    module     indirectlyImported N/A\n\tY    namespace  definition         nameref:module:X\n\t==== ========== ================== ===================\n\n`from X import *`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\t`X`  module     namespace          N/A\n\t==== ========== ================== ===================\n\n`from X import Y`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\t`X`  module     namespace          N/A\n\t`Y`  unknown    imported           scope:module:`X`\n\t==== ========== ================== ===================\n\n`from X import Y as Z`\n\n\t==== ========== ================== ===================\n\tname kind       role               other noticeable fields\n\t==== ========== ================== ===================\n\t`X`  module     namespace          N/A\n\t`Y`  unknown    indirectlyImported scope:module:`X`\n\t`Z`  unknown    definition         nameref:unknown:`Y`\n\t==== ========== ================== ===================\n\n..\n\t===================== ==== ========== ================== ===================\n\tinput code            name kind       role               other noticeable fields\n\t===================== ==== ========== ================== ===================\n\timport X              X    module     imported\n\timport X as Y         X    module     indirectlyImported\n\timport X as Y         Y    namespace  definition         nameref:module:X\n\tfrom X import *       X    module     namespace\n\tfrom X import Y       X    module     namespace\n\tfrom X import Y       Y    unknown    imported           scope:module:X\n\tfrom X import Y as Z  X    module     namespace\n\tfrom X import Y as Z  Y    unknown    indirectlyImported scope:module:X\n\tfrom X import Y as Z  Z    unknown    definition         nameref:unknown:Y\n\t===================== ==== ========== ================== ===================\n\n..  a table having merged cells cannot be converted to man page\n..\n\t+--------------------+------------------------------------------------------+\n\t|input code          |output tags                                           |\n\t|                    +----+----------+------------------+-------------------+\n\t|                    |name| kind     |role              |other noticeable fields  |\n\t+====================+====+==========+==================+===================+\n\t|import X            |X   | module   |imported          |                   |\n\t+--------------------+----+----------+------------------+-------------------+\n\t|import X as Y       |X   | module   |indirectlyImported|                   |\n\t|                    +----+----------+------------------+-------------------+\n\t|                    |Y   | namespace|definition        |nameref:module:X   |\n\t+--------------------+----+----------+------------------+-------------------+\n\t|from X import *     |X   | module   |namespace         |                   |\n\t+--------------------+----+----------+------------------+-------------------+\n\t|from X import Y     |X   | module   |namespace         |                   |\n\t|                    +----+----------+------------------+-------------------+\n\t|                    |Y   | unknown  |imported          |scope:module:X     |\n\t+--------------------+----+----------+------------------+-------------------+\n\t|from X import Y as Z|X   | module   |namespace         |                   |\n\t|                    +----+----------+------------------+-------------------+\n\t|                    |Y   | unknown  |indirectlyImported|scope:module:X     |\n\t|                    +----+----------+------------------+-------------------+\n\t|                    |Z   | unknown  |definition        |nameref:unknown:Y  |\n\t+--------------------+----+----------+------------------+-------------------+\n\nExamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\"input.py\"\n\n.. code-block:: Python\n\n   import X0\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzK input.py\"\n\n.. code-block:: tags\n\n\tX0\tinput.py\t/^import X0$/;\"\tkind:module\troles:imported\n\nA tag for an imported module has ``module`` kind with ``imported`` role.  The\nmodule is not defined here; it is defined in another file. So the tag for the\nimported module is a reference tag; specify ``--extras=+r`` (or\n``--extras=+{reference}``) option for tagging it.  \"roles:\" field enabled with\n``--fields=+r`` is for recording the module is \"imported\" to the tag file.\n\n\"input.py\"\n\n.. code-block:: Python\n\n\timport X1 as Y1\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzK --fields-Python=+{nameref} input.py\"\n\n.. code-block:: tags\n\n\tX1\tinput.py\t/^import X1 as Y1$/;\"\tkind:module\troles:indirectlyImported\n\tY1\tinput.py\t/^import X1 as Y1$/;\"\tkind:namespace\troles:def\tnameref:module:X1\n\n\"Y1\" introduces a new name and is defined here. So \"Y1\" is tagged as a\ndefinition tag.  \"X1\" is imported in a way that its name cannot be used\nin this source file. For letting client tools know that the name cannot be used,\n``indirectlyImported`` role is assigned for \"X1\".  \"Y1\" is the name for\naccessing objects defined in the module imported via \"X1\".  For recording this\nrelationship, ``nameref:`` field is attached to the tag of \"Y1\".  Instead of\n``module`` kind, ``namespace`` kind is assigned to \"Y1\" because \"Y1\" itself\nisn't a module.\n\n\"input.py\"\n\n.. code-block:: Python\n\n\tfrom X2 import *\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzK input.py\"\n\n.. code-block:: tags\n\n\tX2\tinput.py\t/^from X2 import *$/;\"\tkind:module\troles:namespace\n\nThe module is not defined here; it is defined in another file. So the tag for\nthe imported module is a reference tag. Unlike \"X0\" in \"import X0\", \"X2\" may not\nbe used because the names defined in \"X2\" can be used in this source file. To represent\nthe difference ``namespace`` role is attached to \"X2\" instead of ``imported``.\n\n\"input.py\"\n\n.. code-block:: Python\n\n\tfrom X3 import Y3\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzKZ input.py\"\n\n.. code-block:: tags\n\n\tX3\tinput.py\t/^from X3 import Y3$/;\"\tkind:module\troles:namespace\n\tY3\tinput.py\t/^from X3 import Y3$/;\"\tkind:unknown\tscope:module:X3\troles:imported\n\n\"Y3\" is a name for a language object defined in \"X3\" module. \"scope:module:X3\"\nattached to \"Y3\" represents this relation between \"Y3\" and \"X3\". ctags\nassigns ``unknown`` kind to \"Y3\" because ctags cannot know whether \"Y3\" is a\nclass, a variable, or a function from the input file.\n\n\"input.py\"\n\n.. code-block:: Python\n\n\tfrom X4 import Y4 as Z4\n\n\"output.tags\"\nwith \"--options=NONE -o - --extras=+r --fields=+rzKZ input.py\"\n\n.. code-block:: tags\n\n\tX4\tinput.py\t/^from X4 import Y4 as Z4$/;\"\tkind:module\troles:namespace\n\tY4\tinput.py\t/^from X4 import Y4 as Z4$/;\"\tkind:unknown\tscope:module:X4\troles:indirectlyImported\n\tZ4\tinput.py\t/^from X4 import Y4 as Z4$/;\"\tkind:unknown\troles:def\tnameref:unknown:Y4\n\n\"Y4\" is similar to \"Y3\" of \"from X3 import Y3\" but the name cannot be used here.\n``indirectlyImported`` role assigned to \"Y4\" representing this. \"Z4\" is the name for\naccessing the language object named in \"Y4\" in \"X4\" module. \"nameref:unknown:Y4\"\nattached to \"Z4\" and \"scope:module:X4\" attached to \"Y4\" represent the relations.\n\nLAMBDA EXPRESSION AND TYPE HINT\n-------------------------------\n\nSummary\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n`id = lambda var0: var0`\n\n\t=========== ========== ================== ===================\n\tname        kind       role               other noticeable fields\n\t=========== ========== ================== ===================\n\t`id`        function   definition         signature:(`var0`)\n\t=========== ========== ================== ===================\n\n`id_t: Callable[[int], int] = lambda var1: var1`\n\n\t=========== ========== ================== ===================\n\tname        kind       role               other noticeable fields\n\t=========== ========== ================== ===================\n\t`id_t`      variable   definition         typeref:typename:`Callable[[int], int]` nameref:function:anonFuncN\n\tanonFuncN   function   definition         signature:(`var1`)\n\t=========== ========== ================== ===================\n\nExamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\"input.py\"\n\n.. code-block:: Python\n\n\tfrom typing import Callable\n\tid = lambda var0: var0\n\tid_t: Callable[[int], int] = lambda var1: var1\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --fields=+KS --fields-Python=+{nameref} --extras=+{anonymous} input.py\"\n\n.. code-block:: tags\n\n\tid\tinput.py\t/^id = lambda var0: var0$/;\"\tfunction\tsignature:(var0)\n\tid_t\tinput.py\t/^id_t: Callable[[int], int] = lambda var1: var1$/;\"\\\n\t\tvariable\ttyperef:typename:Callable[[int], int]\tnameref:function:anonFunc84011d2c0101\n\tanonFunc84011d2c0101\tinput.py\t/^id_t: Callable[[int], int] = lambda var1: var1$/;\"\\\n\t\tfunction\tsignature:(var1)\n\nIf a variable (\"id\") with no type hint is initialized with a lambda expression,\nctags assigns ``function`` kind for the tag of \"id\".\n\nIf a variable (\"id_t\") with a type hint is initialized with a lambda expression,\nctags assigns ``variable`` kind for the tag of \"id_t\" with ``typeref:`` and\n``nameref:`` fields. ctags fills ``typeref:`` field with the value of the type\nhint. The way of filling ``nameref:`` is a bit complicated.\n\nFor the lambda expression used in initializing the type-hint'ed variable, ctags\ncreates ``anonymous`` extra tag (\"anonFunc84011d2c0101\"). ctags fills the\n``nameref:`` field of \"id_t\" with the name of ``anonymous`` extra tag:\n\"nameref:function:anonFunc84011d2c0101\".\n\nYou may think why ctags does so complicated, and why ctags doesn't emit\nfollowing tags output for the input::\n\n\tid\tinput.py\t/^id = \\\\$/;\"\tfunction\tsignature:(var0)\n\tid_t\tinput.py\t/^id_t: \\\\$/;\"\tfunction\ttyperef:typename:Callable[[int], int]\tsignature:(var1)\n\nThere is a reason. The other languages of ctags obey the following rule: ctags fills\n``typeref:`` field for a tag of a callable object (like function) with the type\nof its return value. If we consider \"id_t\" is a function, its ``typeref:`` field\nshould have \"typename:int\". However, for filling ``typeref:`` with \"typename:int\",\nctags has to analyze \"Callable[[int], int]\" deeper. We don't want to do so.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New role ``entryPoint`` for ``module`` kind\n\n  PythonEntryPoints parser emits tag entries having this role.\n\n* New role ``entryPoint`` for  ``function`` kind\n\n  PythonEntryPoints parser emits tag entries having this role.\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7), ctags-lang-iPythonCell(7)\n"
  },
  {
    "path": "man/ctags-lang-r.7.rst.in",
    "content": ".. _ctags-lang-r(7):\n\n==============================================================\nctags-lang-r\n==============================================================\n-------------------------------------------------------------------\nRandom notes about tagging R source code with Universal Ctags\n-------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+R ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=R ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-R=+.r ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging R source code\nwith Universal Ctags.\n\nKinds\n-----------\nIf a variable gets a value returned from a *well-known constructor*\nand the variable appears for the first time in the current input file,\nthe R parser makes a tag for the variable and attaches a kind\nassociated with the constructor to the tag regardless of whether\nthe variable appears in the top-level context or a function.\n\nWell-known constructor and kind mapping\n\n\t============  ==================\n\tConstructor   kind\n\t============  ==================\n\tfunction()    function\n\tc()           vector\n\tlist()        list\n\tdata.frame()  dataframe\n\t============  ==================\n\nIf a variable doesn't get a value returned from one of well-known\nconstructors, the R parser attaches ``globalVar`` or ``functionVar`` kind\nto the tag for the variable depending on the context.\n\nHere is an example demonstrating the usage of the kinds:\n\n\"input.r\"\n\n.. code-block:: R\n\n\tG <- 1\n\tv <- c(1, 2)\n\tl <- list(3, 4)\n\td <- data.frame(n = v)\n\tf <- function(a) {\n\t\tg <- function (b) a + b\n\t\tw <- c(1, 2)\n\t\tm <- list (3, 4)\n\t\te <- data.frame(n = w)\n\t\tL <- 2\n\t}\n\n\"output.tags\"\nwith \"--options=NONE --sort=no --fields=+KZ -o - input.r\"\n\n.. code-block:: tags\n\n\tG\tinput.r\t/^G <- 1$/;\"\tglobalVar\n\tv\tinput.r\t/^v <- c(1, 2)$/;\"\tvector\n\tl\tinput.r\t/^l <- list(3, 4)$/;\"\tlist\n\td\tinput.r\t/^d <- data.frame(n = v)$/;\"\tdataframe\n\tn\tinput.r\t/^d <- data.frame(n = v)$/;\"\tnameattr\tscope:dataframe:d\n\tf\tinput.r\t/^f <- function(a) {$/;\"\tfunction\n\tg\tinput.r\t/^\tg <- function (b) a + b$/;\"\tfunction\tscope:function:f\n\tw\tinput.r\t/^\tw <- c(1, 2)$/;\"\tvector\tscope:function:f\n\tm\tinput.r\t/^\tm <- list (3, 4)$/;\"\tlist\tscope:function:f\n\te\tinput.r\t/^\te <- data.frame(n = w)$/;\"\tdataframe\tscope:function:f\n\tn\tinput.r\t/^\te <- data.frame(n = w)$/;\"\tnameattr\tscope:dataframe:f.e\n\tL\tinput.r\t/^\tL <- 2$/;\"\tfunctionVar\tscope:function:f\n\n.. TODO:\n\n   - other kinds\n   - operators for assignment, <-, <<-, ->>, ->, =\n   - illuminating duplicated tags\n   - fields (constructor, assignmentop)\n   - sub parsers\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-rmarkdown.7.rst.in",
    "content": ".. _ctags_lang-rmarkdown(7):\n\n======================================================================\nctags-lang-rmarkdown\n======================================================================\n-----------------------------------------------------------------------\nRandom notes about tagging R Markdown source code with Universal Ctags\n-----------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ...--extras=+{subparser}{guest} --languages=+RMarkdown ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ...--extras=+{subparser}{guest} --language-force=RMarkdown ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ...--extras=+{subparser}{guest} --map-RMarkdown=+.rmd ...\n\nDESCRIPTION\n-----------\nRMarkdown parser is an exclusive subparser stacked on top of the Markdown parser.\nIt works when:\n\n* the Markdown parser is enabled,\n* the ``subparser`` extra is enabled, and\n* the RMarkdown parser itself is enabled.\n\nThe RMarkdown parser extends the way of detecting **codeblocks** from the\nMarkdown parser. This extension is for running guest parsers on **code chunks**.\n\nThe Markdown parser expects the following syntax represents codeblocks:\n\n.. code-block::\n\n\t```language-name\n\t\t...\n\t```\n\nFor an example\n\n.. code-block::\n\n\t```r\n\t\t...\n\t```\n\nThe RMarkdown parser accepts the following syntax for code chunks:\n\n.. code-block::\n\n\t```{language-name chunk-label, ...}\n\t\t...\n\t```\n\nFor an example\n\n.. code-block::\n\n\t```{r precalc fig.height=4}\n\t\t...\n\t```\n\nGive `--extras=+{guest}` for enabling ``guest`` to command line if you\nwant to run proper parsers on lines inside code chunks.\n\nThe parser extracts chunk labels coming after `language-name` as\n`chunklabel` kind objects. In the example, the RMarkdown parser\nextracts `precalc` as a `chunklabel` kind object.\nThe `chunklabel` kind is enabled by default.\n\nEXAMPLES\n--------\n\"input.rmd\"\n\n.. code-block:: RMarkdown\n\n\t# Section 1\n\n\t```{r myblock}\n\t\tzero_fun <- function () {\n\t\t\treturn 0\n\t\t}\n\t```\n\n\t# Section 2\n\n\"output.tags\"\nwith \"--options=NONE --extras=+{guest} --fields=+KZln -o - input.rmd\"\n\n.. code-block:: tags\n\n\tSection 1\tinput.rmd\t/^# Section 1$/;\"\tchapter\tline:1\tlanguage:Markdown\n\tSection 2\tinput.rmd\t/^# Section 2$/;\"\tchapter\tline:9\tlanguage:Markdown\n\tmyblock\tinput.rmd\t/^```{r myblock}$/;\"\tchunklabel\tline:3\tlanguage:RMarkdown\n\tzero_fun\tinput.rmd\t/^\tzero_fun <- function () {$/;\"\tfunction\tline:4\tlanguage:R\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7), ctags-lang-r(7),\n`R Markdown: The Definitive Guide <https://bookdown.org/yihui/rmarkdown/>`_\n"
  },
  {
    "path": "man/ctags-lang-scheme.7.rst.in",
    "content": ".. _ctags-lang-scheme(7):\n\n==============================================================\nctags-lang-scheme\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging Scheme source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Scheme ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Scheme ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Scheme=+.SCM ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Scheme=+.SM ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Scheme=+.sch ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Scheme=+.scheme ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Scheme=+.scm ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Scheme=+.sm ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Scheme=+.rkt ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Scheme source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* Add ``unknown`` kind.\n\n* Add ``definer`` field.\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-scss.7.rst.in",
    "content": ".. _ctags-lang-scss(7):\n\n==============================================================\nctags-lang-scss\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging SCSS source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+SCSS ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=SCSS ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Scss=+.scss ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging SCSS input.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``module`` and new role ``used`` of the ``module`` kind\n* New kind ``namespace``\n* New field ``module``\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-sql.7.rst.in",
    "content": ".. _ctags-lang-sql(7):\n\n==============================================================\nctags-lang-sql\n==============================================================\n-------------------------------------------------------------------\nThe man page of the SQL parser for Universal Ctags\n-------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... [--extras={guest}] --languages=+SQL ...\n\n\nDESCRIPTION\n-----------\nThe SQL parser supports various SQL dialects. PostgreSQL is one of them.\n\nPostgreSQL allows user-defined functions to be written in other\nlanguages (*procedural languages*) besides SQL and C [PL]_.\n\nThe SQL parser makes tags for language objects in the user-defined\nfunctions written in the procedural languages if the ``guest`` extra\nis enabled.\n\nThe SQL parser looks for a token coming after ``LANGUAGE`` keyword in\nthe source code to choose a proper guest parser.\n\n.. code-block:: psql\n\n   ... LANGUAGE plpythonu AS '... user-defined function ' ...\n   ... AS $$ user-defined function $$ LANGUAGE plv8 ...\n\nIn the above examples, ``plpythonu`` and ``plv8`` are the names of\nprocedural languages. The SQL parser trims `pl` at the start and `u`\nat the end of the name before finding a ctags parser.  For\n``plpythonu`` and ``plv8``, the SQL parser extracts ``python`` and\n``v8`` as the candidates of guest parsers.\n\nFor ``plpythonu``, ctags can run its Python parser.  ctags doesn't\nhave a parser named ``v8``. However, the JavaScript parser in ctags has\n``v8`` as an alias. So ctags can run the JavaScript parser as the\nguest parser for ``plv8``.\n\nEXAMPLES\n--------\ntagging code including a user-defined function in a string literal [GH3006]_:\n\n\"input.sql\"\n\n.. code-block:: psql\n\n\tCREATE OR REPLACE FUNCTION fun1() RETURNS VARCHAR AS '\n\tDECLARE\n\t\ttest1_var1 VARCHAR(64) := $$ABC$$;\n\t\ttest1_var2 VARCHAR(64) := $xyz$XYZ$xyz$;\n\t\ttest1_var3     INTEGER := 1;\n\tBEGIN\n\t\tRETURN  TO_CHAR(test_var3, ''000'') || test1_var1 || test1_var2;\n\tEND;\n\t' LANGUAGE plpgsql;\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+{guest} input.sql\"\n\n.. code-block:: tags\n\n\tfun1\tinput.sql\t/^CREATE OR REPLACE FUNCTION fun1() RETURNS VARCHAR AS '$/;\"\tf\ttyperef:typename:VARCHAR\n\ttest1_var1\tinput.sql\t/^\ttest1_var1 VARCHAR(64) := $$ABC$$;$/;\"\tv\n\ttest1_var2\tinput.sql\t/^\ttest1_var2 VARCHAR(64) := $xyz$XYZ$xyz$;$/;\"\tv\n\ttest1_var3\tinput.sql\t/^\ttest1_var3     INTEGER := 1;$/;\"\tv\n\ntagging code including a user-defined function in a dollar quote [GH3006]_:\n\n\"input.sql\"\n\n.. code-block:: psql\n\n\tCREATE OR REPLACE FUNCTION fun2() RETURNS VARCHAR LANGUAGE plpgsql AS $$\n\tDECLARE\n\t\ttest2_var1 VARCHAR(64) := 'ABC2';\n\t\ttest2_var2 VARCHAR(64) := 'XYZ2';\n\t\ttest2_var3        INTEGER := 2;\n\tBEGIN\n\t\tRETURN  TO_CHAR(test2_var3, '000') || test2_var1 || test2_var2;\n\tEND;\n\t$$;\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+{guest} input.sql\"\n\n.. code-block:: tags\n\n\tfun2\tinput.sql\t/^CREATE OR REPLACE FUNCTION fun2() RETURNS VARCHAR LANGUAGE plpgsql AS $\\$$/;\"\tf\ttyperef:typename:VARCHAR\n\ttest2_var1\tinput.sql\t/^\ttest2_var1 VARCHAR(64) := 'ABC2';$/;\"\tv\n\ttest2_var2\tinput.sql\t/^\ttest2_var2 VARCHAR(64) := 'XYZ2';$/;\"\tv\n\ttest2_var3\tinput.sql\t/^\ttest2_var3        INTEGER := 2;$/;\"\tv\n\ntagging code including a user-defined written in JavaScript:\n\n.. code-block:: psql\n\n\t-- Derived from https://github.com/plv8/plv8/blob/r3.0alpha/sql/plv8.sql\n\tCREATE FUNCTION test(keys text[], vals text[]) RETURNS text AS\n\t$$\n\t\tvar o = {};\n\t\tfor (var i = 0; i < keys.length; i++)\n\t\t\to[keys[i]] = vals[i];\n\t\treturn JSON.stringify(o);\n\t$$\n\tLANGUAGE plv8 IMMUTABLE STRICT;\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+{guest} input.sql\"\n\n.. code-block:: tags\n\n\ttest\tinput.sql\t/^CREATE FUNCTION test(keys text[], vals text[]) RETURNS text AS$/;\"\tf\n\to\tinput.sql\t/^\tvar o = {};$/;\"\tv\n\nKNOWN BUGS\n----------\nEscape sequences (`''`) in a string literal may make a guest parser confused.\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7)\n\nREFERENCES\n----------\n\n.. [PL] PostgreSQL 9.5.25 Documentation, \"Chapter 39. Procedural Languages\", https://www.postgresql.org/docs/9.5/xplang.html\n\n.. [GH3006] @bagl's comment submitted to https://github.com/universal-ctags/ctags/issues/3006\n"
  },
  {
    "path": "man/ctags-lang-systemtap.7.rst.in",
    "content": ".. _ctags-lang-systemtap(7):\n\n==============================================================\nctags-lang-systemtap\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging SystemTap source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+SystemTap ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=SystemTap ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-SystemTap=+.stp ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging SystemTap scripts.\n\nGuests\n~~~~~~~~~~~\nThe SystemTap parser runs CPreProcessor as a guest parser on the areas\nsurrounded by `%{` and `%}`.\n\n\"input.stp\"\n\n.. code-block:: SystemTap\n\n\t%{\n\t#define X 1\n\t%}\n\n\"output.tags\"\nwith \"--options=NONE -o - --sort=no --extras=+{guest} input.stp\"\n\n.. code-block:: tags\n\n\tX\tinput.stp\t/^#define X /;\"\td\tfile:\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New role ``attached`` for ``probe`` kind\n\nSEE ALSO\n--------\nctags(1), `SystemTap Language Reference <https://sourceware.org/systemtap/langref>`_ (https://sourceware.org/systemtap/langref/)\n"
  },
  {
    "path": "man/ctags-lang-tcl.7.rst.in",
    "content": ".. _ctags-lang-tcl(7):\n\n==============================================================\nctags-lang-tcl\n==============================================================\n-------------------------------------------------------------------\nRandom notes about tagging tcl source code with Universal Ctags\n-------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Tcl ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Tcl ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Tcl=+.tcl ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging tcl source code.\n\nTAGGING language objects of OO Extensions\n-----------------------------------------\n\nTclOO parser and ITcl parser are subparsers running on the Tcl parser.\nAs the names of parsers show, they are for tagging language objects of\nobject oriented programming extensions for the Tcl language.\n\nA pattern, \"namespace import oo\" in an input file activates the TclOO\nparser. A pattern, \"namespace import itcl\" in an input file activates\nthe ITcl parser.\n\nThere are cases that one of the OO extensions is used though neither\npattern are appeared in an input file.\n\nConsider the following input files:\n\n\"main.tcl\"\n\n.. code-block:: Tcl\n\n\tpackage require Itcl\n\tnamespace import itcl::*\n\tsource input.tcl\n\n\"input.tcl\"\n\n.. code-block:: Tcl\n\n\tclass MyClass {\n\t\tpublic method foo {} {\n\t\t}\n\t}\n\nThe pattern for activating the ITcl parser is not appeared\nin \"input.tcl\" though \"class\" command is used. As a result,\nctags cannot extract \"MyClass\".\n\nThe parameters `TclOO.forceUse=true|[false]` and\n`ITcl.forceuse=true|[false]` for handling this situation. With the\nparameter, you can force ctags to activate one of the subparsers.\n\nYou can use the parameters like ``--param-ITcl.forceuse=true``\nin a command-line.\n\nNote that you can enable only one of ITcl parser or TclOO parser.\nEnabling both parsers with specifying the parameters can cause\nunexpected results.\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-lang-terraform.7.rst.in",
    "content": ".. _ctags-lang-terraform(7):\n\n==============================================================\nctags-lang-terraform\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging Terraform files with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Terraform ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Terraform ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Terraform=+.tf ...\n|\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --extras=+{reference} --languages=+TerraformVariables ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --extras=+{reference} --language-force=TerraformVariables ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --extras=+{reference} --map-Terraform=+.tfvars ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging Terraform files.\n\nTIPS\n-----------\n\nExtracting variables assigned in Variable definitions\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSpecify ``--extras=+{reference}`` and ``--languages=+TerraformVariables``\nto extract variables assigned in variables definitions (`*.tfvars`).\nThe TerraformVariables parser extracts variables in `*.tfvars` files\nwith ``variable`` kind with ``assigned`` role of ``Terraform`` language.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``local``\n\nSEE ALSO\n--------\nctags(1),\n`Configuration Syntax <https://developer.hashicorp.com/terraform/language/syntax/configuration>`_ (https://developer.hashicorp.com/terraform/language/syntax/configuration),\n`Variable Definitions (.tfvars) Files <https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files>`_ (https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files)\n"
  },
  {
    "path": "man/ctags-lang-verilog.7.rst.in",
    "content": ".. _ctags_lang-verilog(7):\n\n======================================================================\nctags-lang-verilog\n======================================================================\n--------------------------------------------------------------------\nThe man page about SystemVerilog/Verilog parser for Universal Ctags\n--------------------------------------------------------------------\n\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... [--kinds-systemverilog=+Q] [--fields-SystemVerilog=+{parameter}] ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... [--fields-Verilog=+{parameter}] ...\n\n    +---------------+---------------+-------------------+\n    | Language      | Language ID   | File Mapping      |\n    +===============+===============+===================+\n    | SystemVerilog | SystemVerilog | .sv, .svh, svi    |\n    +---------------+---------------+-------------------+\n    | Verilog       | Verilog       | .v, .vh           |\n    +---------------+---------------+-------------------+\n\nDESCRIPTION\n-----------\nThis man page describes about the SystemVerilog/Verilog parser for Universal Ctags.\nSystemVerilog parser supports IEEE Std 1800-2017 keywords.\nVerilog parser supports IEEE Std 1364-2005 keywords.\n\nSupported Kinds\n~~~~~~~~~~~~~~~\n\n.. code-block:: console\n\n\t$ ctags --list-kinds-full=SystemVerilog\n\t#LETTER NAME       ENABLED REFONLY NROLES MASTER DESCRIPTION\n\tA       assert     yes     no      0      NONE   assertions (assert, assume, cover, restrict)\n\tC       class      yes     no      0      NONE   classes\n\tE       enum       yes     no      0      NONE   enumerators\n\tH       checker    yes     no      0      NONE   checkers\n\tI       interface  yes     no      0      NONE   interfaces\n\tK       package    yes     no      0      NONE   packages\n\tL       clocking   yes     no      0      NONE   clocking\n\tM       modport    yes     no      0      NONE   modports\n\tN       nettype    yes     no      0      NONE   nettype declarations\n\tO       constraint yes     no      0      NONE   constraints\n\tP       program    yes     no      0      NONE   programs\n\tQ       prototype  no      no      0      NONE   prototypes (extern, pure)\n\tR       property   yes     no      0      NONE   properties\n\tS       struct     yes     no      0      NONE   structs and unions\n\tT       typedef    yes     no      0      NONE   type declarations\n\tV       covergroup yes     no      0      NONE   covergroups\n\tb       block      yes     no      0      NONE   blocks (begin, fork)\n\tc       constant   yes     no      0      NONE   constants (parameter, specparam, enum values)\n\td       define     yes     no      0      NONE   text macros\n\te       event      yes     no      0      NONE   events\n\tf       function   yes     no      0      NONE   functions\n\ti       instance   yes     no      0      NONE   instances of module or interface\n\tl       ifclass    yes     no      0      NONE   interface class\n\tm       module     yes     no      0      NONE   modules\n\tn       net        yes     no      0      NONE   net data types\n\tp       port       yes     no      0      NONE   ports\n\tq       sequence   yes     no      0      NONE   sequences\n\tr       register   yes     no      0      NONE   variable data types\n\tt       task       yes     no      0      NONE   tasks\n\tw       member     yes     no      0      NONE   struct and union members\n\nNote that ``prototype`` (``Q``) is disabled by default.\n\n.. code-block:: console\n\n\t$ ctags --list-kinds-full=Verilog\n\t#LETTER NAME     ENABLED REFONLY NROLES MASTER DESCRIPTION\n\tb       block    yes     no      0      NONE   blocks (begin, fork)\n\tc       constant yes     no      0      NONE   constants (parameter, specparam)\n\td       define   yes     no      0      NONE   text macros\n\te       event    yes     no      0      NONE   events\n\tf       function yes     no      0      NONE   functions\n\ti       instance yes     no      0      NONE   instances of module\n\tm       module   yes     no      0      NONE   modules\n\tn       net      yes     no      0      NONE   net data types\n\tp       port     yes     no      0      NONE   ports\n\tr       register yes     no      0      NONE   variable data types\n\tt       task     yes     no      0      NONE   tasks\n\nSupported Language Specific Fields\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block:: console\n\n\t$ ctags --list-fields=Verilog\n\t#LETTER NAME      ENABLED LANGUAGE JSTYPE FIXED DESCRIPTION\n\t-       parameter no      Verilog  --b    no    parameter whose value can be overridden.\n\t$ ctags --list-fields=SystemVerilog\n\t#LETTER NAME      ENABLED LANGUAGE      JSTYPE FIXED DESCRIPTION\n\t-       parameter no      SystemVerilog --b    no    parameter whose value can be overridden.\n\n``parameter`` field\n....................\n\nIf the field ``parameter`` is enabled, a field ``parameter:`` is added on a parameter whose\nvalue can be overridden on an instantiated module, interface, or program.\nThis is useful for a editor plugin or extension to enable auto-instantiation of modules with\nparameters which can be overridden.\n\n.. code-block:: console\n\n    $ ctags ... --fields-Verilog=+{parameter} ...\n    $ ctags ... --fields-SystemVerilog=+{parameter} ...\n\nOn the following source code fields ``parameter:`` are added on\nparameters ``P*``, not on ones ``L*``.  Note that ``L4`` and ``L6`` is declared by\n``parameter`` statement, but fields ``parameter:`` are not added,\nbecause they cannot be overridden.\n\n\"input.sv\"\n\n.. code-block:: systemverilog\n\n\t// compilation unit scope\n\tparameter L1 = \"synonym for the localparam\";\n\n\tmodule with_parameter_port_list #(\n\t\tP1,\n\t\tlocalparam L2 = P1+1,\n\t\tparameter P2)\n\t\t( /*port list...*/ );\n\t\tparameter  L3 = \"synonym for the localparam\";\n\t\tlocalparam L4 = \"localparam\";\n\t\t// ...\n\tendmodule\n\n\tmodule with_empty_parameter_port_list #()\n\t\t( /*port list...*/ );\n\t\tparameter  L5 = \"synonym for the localparam\";\n\t\tlocalparam L6 = \"localparam\";\n\t\t// ...\n\tendmodule\n\n\tmodule no_parameter_port_list\n\t\t( /*port list...*/ );\n\t\tparameter  P3 = \"parameter\";\n\t\tlocalparam L7 = \"localparam\";\n\t\t// ...\n\tendmodule\n\n.. code-block:: console\n\n\t$ ctags -uo - --fields-SystemVerilog=+{parameter} input.sv\n\tL1\tinput.sv\t/^parameter L1 = \"synonym for the localparam\";$/;\"\tc\tparameter:\n\twith_parameter_port_list\tinput.sv\t/^module with_parameter_port_list #($/;\"\tm\n\tP1\tinput.sv\t/^\tP1,$/;\"\tc\tmodule:with_parameter_port_list\tparameter:\n\tL2\tinput.sv\t/^\tlocalparam L2 = P1+1,$/;\"\tc\tmodule:with_parameter_port_list\n\tP2\tinput.sv\t/^\tparameter P2)$/;\"\tc\tmodule:with_parameter_port_list\tparameter:\n\tL3\tinput.sv\t/^\tparameter  L3 = \"synonym for the localparam\";$/;\"\tc\tmodule:with_parameter_port_list\n\tL4\tinput.sv\t/^\tlocalparam L4 = \"localparam\";$/;\"\tc\tmodule:with_parameter_port_list\n\twith_empty_parameter_port_list\tinput.sv\t/^module with_empty_parameter_port_list #()$/;\"\tm\n\tL5\tinput.sv\t/^\tparameter  L5 = \"synonym for the localparam\";$/;\"\tc\tmodule:with_empty_parameter_port_list\n\tL6\tinput.sv\t/^\tlocalparam L6 = \"localparam\";$/;\"\tc\tmodule:with_empty_parameter_port_list\n\tno_parameter_port_list\tinput.sv\t/^module no_parameter_port_list$/;\"\tm\n\tP3\tinput.sv\t/^\tparameter  P3 = \"parameter\";$/;\"\tc\tmodule:no_parameter_port_list\tparameter:\n\tL7\tinput.sv\t/^\tlocalparam L7 = \"localparam\";$/;\"\tc\tmodule:no_parameter_port_list\n\nSupported Roles\n~~~~~~~~~~~~~~~\n\n.. code-block:: console\n\n\t$ ./ctags --list-roles=SystemVerilog\n\t#KIND(L/N) NAME ENABLED DESCRIPTION\n\tm/module   decl on      declaring instances\n\n\t$ ./ctags --list-roles=Verilog\n\t#KIND(L/N) NAME ENABLED DESCRIPTION\n\tm/module   decl on      declaring instances\n\nThe parser extracts names of modules used in instance declarations as\nreference tags. ``decl`` is the role for the tags. See \"TAG ENTRIES\"\nsection of ctags(1) about reference tags and roles.\n\n.. warning::\n\n   The support for references in Universal Ctags is still\n   experimental; the names of the roles may be changed in the future.\n\nTIPS\n~~~~\n\nIf you want to map files ``*.v`` to SystemVerilog, add\n``--map-SystemVerilog=+.v`` option.\n\nKNOWN ISSUES\n---------------------------------------------------------------------\n\nSee https://github.com/universal-ctags/ctags/issues/2674 for more information.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kind ``define``\n* map ``.vh`` to Verilog\n\nSEE ALSO\n--------\n\n- ctags(1)\n- ctags-client-tools(7)\n- Language Reference Manuals (LRM)\n\n   - IEEE Standard for SystemVerilog — Unified Hardware Design, Specification, and\n     Verification Language, IEEE Std 1800-2017,\n     https://ieeexplore.ieee.org/document/8299595\n   - IEEE Standard for Verilog Hardware Description Language, IEEE Std 1364-2005,\n     https://ieeexplore.ieee.org/document/1620780\n"
  },
  {
    "path": "man/ctags-lang-vim.7.rst.in",
    "content": ".. _ctags-lang-vim(7):\n\n==============================================================\nctags-lang-vim\n==============================================================\n---------------------------------------------------------------------\nRandom notes about tagging Vim source code with Universal Ctags\n---------------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --languages=+Vim ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --language-force=Vim ...\n|\t**@CTAGS_NAME_EXECUTABLE@** ... --map-Vim=+.vim ...\n\nDESCRIPTION\n-----------\nThis man page gathers random notes about tagging VIM source code.\n\nVERSIONS\n--------\n\nChange since \"0.0\"\n~~~~~~~~~~~~~~~~~~\n\n* New kinds ``heredoc`` and ``class``\n\nSEE ALSO\n--------\nctags(1)\n"
  },
  {
    "path": "man/ctags-optlib.7.rst.in",
    "content": ".. _ctags-optlib(7):\n\n==============================================================\nctags-optlib\n==============================================================\n--------------------------------------------------------------\nUniversal Ctags parser definition language\n--------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 7\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** [options] [file(s)]\n|\t**@ETAGS_NAME_EXECUTABLE@** [options] [file(s)]\n\nDESCRIPTION\n-----------\n\n*Exuberant Ctags*, the ancestor of *Universal Ctags*, has provided\nthe way to define a new parser from command line.  Universal Ctags\nextends and refines this feature. *optlib parser* is the name for such\nparser in Universal Ctags. \"opt\" intends a parser is defined with\ncombination of command line options. \"lib\" intends an optlib parser\ncan be more than ad-hoc personal configuration.\n\nThis man page is for people who want to define an optlib parser. The\nreaders should read ctags(1) of Universal Ctags first.\n\nFollowing options are for defining (or customizing) a parser:\n\n* ``--langdef=<name>``\n* ``--map-<LANG>=[+|-]<extension>|<pattern>|<rexpr>``\n* ``--kinddef-<LANG>=<letter>,<name>,<description>``\n* ``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``\n* ``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``\n\nFollowing options are for controlling loading parser definition:\n\n* ``--options=<pathname>``\n* ``--options-maybe=<pathname>``\n* ``--optlib-dir=[+]<directory>``\n\nThe design of options and notations for defining a parser in\nExuberant Ctags may focus on reducing the number of typing by user.\nReducing the number of typing is important for users who want to\ndefine (or customize) a parser quickly.\n\nOn the other hand, the design in Universal Ctags focuses on\nmaintainability. The notation of Universal Ctags is redundant than\nthat of Exuberant Ctags; the newly introduced kind should be declared\nexplicitly, (long) names are approved than one-letter flags\nspecifying kinds, and naming rules are stricter.\n\nThis man page explains only stable options and flags.  Universal Ctags\nalso introduces experimental options and flags which have names starting\nwith ``_``. For documentation on these options and flags, visit\nUniversal Ctags web site at https://ctags.io/.\n\n\nStoring a parser definition to a file\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThough it is possible to define a parser from command line, you don't\nwant to type the same command line each time when you need the parser.\nYou can store options for defining a parser into a file.\n\n@CTAGS_NAME_EXECUTABLE@ loads files (preload files) listed in \"FILES\"\nsection of ctags(1) at program starting up. You can put your parser\ndefinition needed usually to the files.\n\n``--options=<pathname>``, ``--options-maybe=<pathname>``, and\n``--optlib-dir=[+]<directory>`` are for loading optlib files you need\noccasionally. See \"Option File Options\" section of ctags(1) for\nthese options.\n\nAs explained in \"FILES\" section of ctags(1), options for defining a\nparser listed line by line in an optlib file. Prefixed white spaces are\nignored. A line starting with '#' is treated as a comment.  Escaping\nshell meta character is not needed.\n\nUse ``.ctags`` as file extension for optlib file. You can define\nmultiple parsers in an optlib file but it is better to make a file for\neach parser definition.\n\n``--_echo=<msg>`` and ``--_force-quit=<num>`` options are for debugging\noptlib parser.\n\n\nOverview for defining a parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n1. Design the parser\n\n   You need know both the target language and the ctags'\n   concepts (definition, reference, kind, role, field, extra). About\n   the concepts, ctags(1) of Universal Ctags may help you.\n\n2. Give a name to the parser\n\n   Use ``--langdef=<name>`` option. *<name>* is referred as *<LANG>* in\n   the later steps.\n\n3. Give a file pattern or file extension for activating the parser\n\n   Use ``--map-<LANG>=[+|-]<extension>|<pattern>|<rexpr>``.\n\n4. Define kinds\n\n   Use ``--kinddef-<LANG>=<letter>,<name>,<description>`` option.\n   Universal Ctags introduces this option.  Exuberant Ctags doesn't\n   have. In Exuberant Ctags, a kind is defined as a side effect of\n   specifying ``--regex-<LANG>=`` option. So user doesn't have a\n   chance to recognize how important the definition of kind.\n\n5. Define patterns\n\n   Use ``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``\n   option for a single-line regular expression. You can also use\n   ``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``\n   option for a multi-line regular expression.\n\n   As *<kind-spec>*, you can use the one-letter flag defined with\n   ``--kinddef-<LANG>=<letter>,<name>,<description>`` option.\n\nOPTIONS\n------------\n\n``--langdef=<name>``\n\tDefines a new user-defined language, *<name>*, to be parsed with regular\n\texpressions. Once defined, *<name>* may be used in other options taking\n\tlanguage names.\n\n\t*<name>* must consist of alphanumeric characters, '``#``', or '``+``'\n\t('[a-zA-Z0-9#+]+'). The graph characters other than '``#``' and\n\t'``+``' are disallowed (or reserved). Some of them (``[-=:{.]``) are\n\tdisallowed because they can make the command line parser of\n\t@CTAGS_NAME_EXECUTABLE@ confused. The rest of them are just\n\treserved for future extending @CTAGS_NAME_EXECUTABLE@.\n\n\t``all`` is an exception.  ``all`` as *<name>* is not acceptable. It is\n\ta reserved word. See the description of\n\t``--kinds-(<LANG>|all)=[+|-](<kinds>|*)`` option in ctags(1) about how the\n\treserved word is used.\n\n\t``NONE`` is another exception. ``NONE`` as *<name>* is not acceptable.\n\n\tThe names of built-in parsers are capitalized. When\n\t@CTAGS_NAME_EXECUTABLE@ evaluates an option in a command line, and\n\tchooses a parser, @CTAGS_NAME_EXECUTABLE@ uses the names of\n\tparsers in a case-insensitive way. Therefore, giving a name\n\tstarted from a lowercase character doesn't help you to avoid the\n\tparser name confliction. However, in a tags file,\n\t@CTAGS_NAME_EXECUTABLE@ prints parser names in a case-sensitive\n\tway; it prints a parser name as specified in ``--langdef=<name>``\n\toption.  Therefore, we recommend you to give a name started from a\n\tlowercase character to your private optlib parser. With this\n\tconvention, people can know where a tag entry in a tag file comes\n\tfrom a built-in parser or a private optlib parser.\n\n``--kinddef-<LANG>=<letter>,<name>,<description>``\n\tDefine a kind for *<LANG>*.\n\tBe not confused this with ``--kinds-<LANG>``.\n\n\t*<letter>* must be an alphabetical character ('[a-zA-EG-Z]')\n\tother than \"F\". \"F\" has been reserved for representing a file\n\tsince Exuberant Ctags.\n\n\t*<name>* must start with an alphabetic character, and the rest\n\tmust  be alphanumeric ('[a-zA-Z][a-zA-Z0-9]*'). Do not use\n\t\"file\" as *<name>*. It has been reserved for representing a file\n\tsince Exuberant Ctags.\n\n\tNote that using a number character in a *<name>* violates the\n\tversion 2 of tags file format though @CTAGS_NAME_EXECUTABLE@\n\taccepts it. For more detail, see tags(5).\n\n\t*<description>* comes from any printable ASCII characters. The\n\texception is ``{`` and ``\\``. ``{`` is reserved for adding flags\n\tthis option in the future. So put ``\\`` before ``{`` to include\n\t``{`` to a description. To include ``\\`` itself to a description,\n\tput ``\\`` before ``\\``.\n\n\tBoth *<letter>*, *<name>* and their combination must be unique in\n\ta *<LANG>*.\n\n\tThis option is newly introduced in Universal Ctags.  This option\n\treduces the typing defining a regex pattern with\n\t``--regex-<LANG>=``, and keeps the consistency of kind\n\tdefinitions in a language.\n\n\tThe *<letter>* can be used as an argument for ``--kinds-<LANG>``\n\toption to enable or disable the kind. Unless ``K`` field is\n\tenabled, the *<letter>* is used as value in the \"kind\" extension\n\tfield in tags output.\n\n\tThe *<name>* surrounded by braces can be used as an argument for\n\t``--kind-<LANG>`` option. If ``K`` field is enabled, the *<name>*\n\tis used as value in the \"kind\" extension field in tags output.\n\n\tThe *<description>* and *<letter>* are listed in ``--list-kinds``\n\toutput. All three elements of the kind-spec are listed in\n\t``--list-kinds-full`` output. Don't use braces in the\n\t*<description>*. They will be used meta characters in the future.\n\n``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``\n\tDefine a single-line regular expression.\n\n\tThe */<line_pattern>/<name_pattern>/* pair defines a regular expression\n\treplacement pattern, similar in style to ``sed`` substitution\n\tcommands, ``s/regexp/replacement/``, with which to generate tags from source files mapped to\n\tthe named language, *<LANG>*, (case-insensitive; either a built-in\n\tor user-defined language).\n\n\tThe regular expression, *<line_pattern>*, defines\n\tan extended regular expression (roughly that used by egrep(1)),\n\twhich is used to locate a single source line containing a tag and\n\tmay specify tab characters using ``\\t``.\n\n\tWhen a matching line is\n\tfound, a tag will be generated for the name defined by\n\t*<name_pattern>*, which generally will contain the special\n\tback-references ``\\1`` through ``\\9`` to refer to matching sub-expression\n\tgroups within *<line_pattern>*.\n\n\tThe '``/``' separator characters shown in the\n\tparameter to the option can actually be replaced by any\n\tcharacter. Note that whichever separator character is used will\n\thave to be escaped with a backslash ('``\\``') character wherever it is\n\tused in the parameter as something other than a separator. The\n\tregular expression defined by this option is added to the current\n\tlist of regular expressions for the specified language unless the\n\tparameter is omitted, in which case the current list is cleared.\n\n\tUnless modified by *<flags>*, *<line_pattern>* is interpreted as a POSIX\n\textended regular expression. The *<name_pattern>* should expand for all\n\tmatching lines to a non-empty string of characters, or a warning\n\tmessage will be reported unless ``{placeholder}`` regex flag is\n\tspecified.\n\n\tA kind specifier (*<kind-spec>*) for tags matching regexp may\n\tfollow *<name_pattern>*, which will determine what kind of tag is\n\treported in the ``kind`` extension field (see tags(5)).\n\n\t*<kind-spec>* has two forms: *one-letter form* and *full form*.\n\n\tThe\tone-letter form in the form of ``<letter>``. It just refers a kind\n\t*<letter>* defined with ``--kinddef-<LANG>``. This form is recommended in\n\tUniversal Ctags.\n\n\tThe full form of *<kind-spec>* is in the form of\n\t``<letter>,<name>,<description>``. Either the kind *<name>* and/or the\n\t*<description>* can be omitted. See the description of\n\t``--kinddef-<LANG>=<letter>,<name>,<description>`` option about the\n\telements.\n\n\tThe full form is supported only for keeping the compatibility with Exuberant\n\tCtags which does not have ``--kinddef-<LANG>`` option. Supporting the\n\tform will be removed from Universal Ctags in the future.\n\n\t.. MEMO: the following line is commented out\n\t\tIf *<kind-spec>* is omitted, it defaults to ``r,regex``.\n\n\tAbout *<flags>*, see \"FLAGS FOR ``--regex-<LANG>`` OPTION\".\n\n\tFor more information on the regular expressions used by\n\t@CTAGS_NAME_EXECUTABLE@, see either the regex(5,7) man page, or\n\tthe GNU info documentation for regex (e.g. \"``info regex``\").\n\n``--list-regex-flags``\n\tLists the flags that can be used in ``--regex-<LANG>`` option.\n\n``--list-mline-regex-flags``\n\tLists the flags that can be used in ``--mline-regex-<LANG>`` option.\n\n``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/{mgroup=<N>}[<flags>]``\n\tDefine a multi-line regular expression.\n\n\tThis option is similar to ``--regex-<LANG>`` option except the pattern is\n\tapplied to the whole file’s contents, not line by line.\n\n\tSee \"`FLAGS FOR --mline-regex-<LANG> OPTION`_\" about ``{mgroup=<N>}``.\n\t``{mgroup=<N>}`` flag is a must.\n\n``--_echo=<message>``\n\tPrint *<message>* to the standard error stream.  This is helpful to\n\tunderstand (and debug) optlib loading feature of Universal Ctags.\n\n``--_force-quit[=<num>]``\n\tExits immediately when this option is processed.  If *<num>* is used\n\tas exit status. The default is 0.  This is helpful to debug optlib\n\tloading feature of Universal Ctags.\n\n\nFLAGS FOR ``--regex-<LANG>`` OPTION\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can specify more than one flag, ``<letter>|{<name>}``, at the end of ``--regex-<LANG>`` to\ncontrol how Universal Ctags uses the pattern.\n\nExuberant Ctags uses a *<letter>* to represent a flag. In\nUniversal Ctags, a *<name>* surrounded by braces (name form) can be used\nin addition to *<letter>*. The name form makes a user reading an optlib\nfile easier.\n\nThe most of all flags newly added in Universal Ctags\ndon't have the one-letter representation. All of them have only the name\nrepresentation. ``--list-regex-flags`` lists all the flags.\n\n``basic`` (one-letter form ``b``)\n\tThe pattern is interpreted as a POSIX basic regular expression.\n\n``exclusive`` (one-letter form ``x``)\n\tSkip testing the other patterns if a line is matched to this\n\tpattern. This is useful to avoid using CPU to parse line comments.\n\n``extend`` (one-letter form ``e``)\n\tThe pattern is interpreted as a POSIX extended regular\n\texpression (default).\n\n``pcre2`` (one-letter form ``p``, experimental)\n\tThe pattern is interpreted as a PCRE2 regular expression explained\n\tin pcre2syntax(3).  This flag is available only if the ctags is\n\tbuilt with ``pcre2`` library. See the output of\n\t``--list-features`` option to know whether your ctags is\n\tbuilt-with ``pcre2`` or not.\n\n``icase`` (one-letter form ``i``)\n\tThe regular expression is to be applied in a case-insensitive\n\tmanner.\n\n``placeholder``\n\tDon't emit a tag captured with a regex pattern.  The replacement\n\tcan be an empty string.  See the following description of\n\t``scope=...`` flag about how this is useful.\n\n``postrun``\n\tMatch the pattern at the end of all the parsing processes, including:\n\n\t* running the built-in code for ``<LANG>``,\n\t* applying ``--mline-regex-<LANG>`` patterns,\n\t* applying ``--_mtable-regex-<LANG>`` patterns, and\n\t* applying non-``postrun`` ``--regex-<LANG>=`` patterns.\n\n\tThis flag is helpful when combined with ``scope=intervaltab``.\n\n\tThe built-in code processes source files line-by-line delivered by\n\tthe main part of @CTAGS_NAME_EXECUTABLE@.  The main part applies\n\tnon-``postrun`` ``--regex-<LANG>=`` patterns to a line just after\n\tdelivering the line to the code of built-in code. Thus,\n\tnon-``postrun`` ``--regex-<LANG>=`` patterns cannot refer to the tags\n\tinformation finally extracted by the built-in code.\n\n\tThis is where the ``postrun`` comes into play. The main part never\n\tapplies ``postrun`` ``--regex-<LANG>=`` patterns when delivering\n\tlines to the code of built-in code. Instead, it applies the\n\t``postrun`` patterns in batch after delivering all lines to the\n\tbuilt-in code. The ``postrun`` patterns can refer to the tags\n\tinformation extracted by the built-in code.\n\n\t``--mline-regex-<LANG>`` and ``--_mtable-regex-<LANG>`` have no\n\t``{postrun}`` flag because the main part always applies the\n\tpatterns specified with the options after running the built-in\n\tcode for ``<LANG>``.\n\n\tSee also the description of ``scope=intervaltab`` flag.\n\n``scope=intervaltab``\n\tUse the interval table maintained by the main part of\n\t@CTAGS_NAME_EXECUTABLE@ to fill in the ``scope:`` field.\n\tThis flag is useful for extending a built-in parser with the\n\t``--regex-<LANG>=`` option with ``postrun`` flag.\n\n\tThe interval table holds tag entries having both ``line:`` and\n\t``end:`` fields. These tag entries are stored in a table keyed by\n\ttheir ``line:`` and ``end:`` field pairs. Therefore, the table can\n\tanswer queries like, \"Is there a tag entry that includes\n\tthis line?\" or \"Which tag entry contains this line?\"\n\n\tThe source line, where ``postrun`` ``--regex-<LANG>`` pattern finds\n\ta language object, can be a key for such queries. The tag\n\tentry returned by the table is set in the ``scope:`` field of the\n\tnewly created tag entry for the language object.\n\n\t``postrun`` flag is needed for running the built-in parser that\n\tstores tag entries before applying patterns specified with\n\t``--regex-<LANG>``.\n\n\tSee also the example in \"`Using the interval table`_\".\n\n``scope=(ref|push|pop|clear|set|replace)``\n\tSpecify what to do with the internal scope stack.\n\n\tA parser programmed with ``--regex-<LANG>`` has a stack (scope\n\tstack) internally. You can use it for tracking scope\n\tinformation. The ``scope=...`` flag is for manipulating and\n\tutilizing the scope stack.\n\n\tIf ``{scope=push}`` is specified, a tag captured with\n\t``--regex-<LANG>`` is pushed to the stack. ``{scope=push}``\n\timplies ``{scope=ref}``.\n\n\tYou can fill the scope field (``scope:``) of captured tag with\n\t``{scope=ref}``. If ``{scope=ref}`` flag is given,\n\t@CTAGS_NAME_EXECUTABLE@ attaches the tag at the top to the tag\n\tcaptured with ``--regex-<LANG>`` as the value for the ``scope:``\n\tfield.\n\n\t@CTAGS_NAME_EXECUTABLE@ pops the tag at the top of the stack when\n\t``--regex-<LANG>`` with ``{scope=pop}`` is matched to the input\n\tline.\n\n\tSpecifying ``{scope=clear}`` removes all the tags in the scope.\n\tSpecifying ``{scope=set}`` removes all the tags in the scope, and\n\tthen pushes the captured tag as ``{scope=push}`` does.\n\n\t``{scope=replace}`` does the three things sequentially. First it\n\tdoes the same as ``{scope=pop}``, then fills the ``scope:`` field\n\tof the tag captured with ``--regex-<LANG>``, and pushes the tag to\n\tthe scope stack as if ``{scope=push}`` was given finally.\n\tYou cannot specify another scope action together with\n\t``{scope=replace}``.\n\n\tYou don't want to specify ``{scope=pop}{scope=push}`` as an\n\talternative to ``{scope=replace}``; ``{scope=pop}{scope=push}``\n\tfills the ``scope:`` field of the tag captured with ``--regex-<LANG>``\n\tfirst, then pops the tag at the top of the stack, and pushes\n\tthe captured tag to the scope stack finally. The timing when\n\tfilling the end field is different between ``{scope=replace}`` and\n\t``{scope=pop}{scope=push}``.\n\n\tIn some cases, you may want to use ``--regex-<LANG>`` only for its\n\tside effects: using it only to manipulate the stack but not for\n\tcapturing a tag. In such a case, make *<name_pattern>* component of\n\t``--regex-<LANG>`` option empty while specifying ``{placeholder}``\n\tas a regex flag. For example, a non-named tag can be put on\n\tthe stack by giving a regex flag \"``{scope=push}{placeholder}``\".\n\n\tYou may wonder what happens if a regex pattern with\n\t``{scope=ref}`` flag matches an input line but the stack is empty,\n\tor a non-named tag is at the top. If the regex pattern contains a\n\t``{scope=ref}`` flag and the stack is empty, the ``{scope=ref}``\n\tflag is ignored and nothing is attached to the ``scope:`` field.\n\n\tIf the top of the stack contains an unnamed tag,\n\t@CTAGS_NAME_EXECUTABLE@ searches deeper into the stack to find the\n\ttop-most named tag. If it reaches the bottom of the stack without\n\tfinding a named tag, the ``{scope=ref}`` flag is ignored and\n\tnothing is attached to the ``scope:`` field.\n\n\tWhen a named tag on the stack is popped or cleared as the side\n\teffect of a pattern matching, @CTAGS_NAME_EXECUTABLE@ attaches the\n\tline number of the match to the ``end:`` field of\n\tthe named tag.\n\n\t@CTAGS_NAME_EXECUTABLE@ clears all of the tags on the stack when it\n\treaches the end of the input source file. The line number of the\n\tend is attached to the ``end:`` field of the cleared tags.\n\n``warning=<message>``\n\tprint the given *<message>* at WARNING level\n\n``fatal=<message>``\n\tprint the given *<message>* and exit\n\nFLAGS FOR ``--mline-regex-<LANG>`` OPTION\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``mgroup=<N>``\n\tdecide the location of the tag extracted with\n\t``--mline-regex-<LANG>`` option.\n\n\t*<N>* is the number of a capture group in the pattern, which is\n\tused to record the line number location of the tag. ``mgroup=<N>``\n\tflag is not an optional. You **must** add an ``mgroup=<N>`` flag,\n\teven if the *<N>* is ``0`` (meaning the start position of the\n\twhole regex pattern).\n\n``scope=intervaltab``\n   See the description for the flag in\n   \"`FLAGS FOR --regex-<LANG> OPTION`_\".\n\n   Unlike ``--regex-<LANG>`` option, you don't have to specify\n   ``postrun`` flag.\n\nEXAMPLES\n-------------\n\nPerl Pod\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis is the definition (pod.ctags) used in ctags for parsing Pod\n(https://perldoc.perl.org/perlpod.html) file.\n\n.. code-block:: ctags\n\n   --langdef=pod\n   --map-pod=+.pod\n\n   --kinddef-pod=c,chapter,chapters\n   --kinddef-pod=s,section,sections\n   --kinddef-pod=S,subsection,subsections\n   --kinddef-pod=t,subsubsection,subsubsections\n\n   --regex-pod=/^=head1[ \\t]+(.+)/\\1/c/\n   --regex-pod=/^=head2[ \\t]+(.+)/\\1/s/\n   --regex-pod=/^=head3[ \\t]+(.+)/\\1/S/\n   --regex-pod=/^=head4[ \\t]+(.+)/\\1/t/\n\nUsing scope regex flags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nLet's think about writing a parser for a very small subset of the Ruby\nlanguage.\n\ninput source file (``input.srb``)::\n\n\tclass Example\n\t  def methodA\n\t\tputs \"in class_method\"\n\t  end\n\t  def methodB\n\t\tputs \"in class_method\"\n\t  end\n\tend\n\nThe parser for the input should capture ``Example`` with ``class`` kind,\n``methodA``, and ``methodB`` with ``method`` kind. ``methodA`` and ``methodB``\nshould have ``Example`` as their scope. ``end:`` fields of each tag\nshould have proper values.\n\noptlib file (``sub-ruby.ctags``):\n\n.. code-block:: ctags\n\n\t--langdef=subRuby\n\t--map-subRuby=.srb\n\t--kinddef-subRuby=c,class,classes\n\t--kinddef-subRuby=m,method,methods\n\t--regex-subRuby=/^class[ \\t]+([a-zA-Z][a-zA-Z0-9]+)/\\1/c/{scope=push}\n\t--regex-subRuby=/^end///{scope=pop}{placeholder}\n\t--regex-subRuby=/^[ \\t]+def[ \\t]+([a-zA-Z][a-zA-Z0-9_]+)/\\1/m/{scope=push}\n\t--regex-subRuby=/^[ \\t]+end///{scope=pop}{placeholder}\n\ncommand line and output::\n\n\t$ ctags --quiet --fields=+eK \\\n\t--options=./sub-ruby.ctags -o - input.srb\n\tExample\tinput.srb\t/^class Example$/;\"\tclass\tend:8\n\tmethodA\tinput.srb\t/^  def methodA$/;\"\tmethod\tclass:Example\tend:4\n\tmethodB\tinput.srb\t/^  def methodB$/;\"\tmethod\tclass:Example\tend:7\n\nUsing the interval table\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nLet's try to extract kernel threads defined in Linux kernel.\n\n``kthread_run`` is the function for creating and starting a\nkernel thread. For example, ``kswapd`` kernel thread is created\nwith the function like (quoted from linux/mm/vmscan.c):\n\n.. code-block:: C\n\n\tvoid kswapd_run(int nid)\n\t{\n\t\t\t/* ... */\n\t\t\tpgdat->kswapd = kthread_run(kswapd, pgdat, \"kswapd%d\", nid);\n\t\t\t/* ... */\n\n``kthread-v1.ctags`` illustrates the way to extract the name of kernel threads\nappeared at the third argument of ``kthread_run``.\n\n``kthread-v1.ctags``:\n\n.. code-block:: ctags\n\n\t--kinddef-C=K,kernelThread,the name of kernel thread in Linux kernel\n\t--regex-C=/kthread_run\\([^\"]+\"([^\"]+)\"/\\1/K/\n\nWith ``kthread-v1.ctags``, ctags emits the following tags:\n\n.. code-block:: console\n\n\t$ ctags --options=linux/kthread-v1.ctags  -o - vmscan.c\n\t...\n\tkswapd%d\tvmscan.c\t/^... = kthread_run(kswapd, pgdat, \"kswapd%d\"...$/;\"\tK\n\t...\n\nUsing the interval table, you can attach the name of the function\nwhere the kernel thread is defined.\n\n``kthread-v2.ctags``:\n\n.. code-block:: ctags\n\n\t--kinddef-C=K,kernelThread,the name of kernel thread in Linux kernel\n\t--regex-C=/kthread_run\\([^\"]+\"([^\"]+)\"/\\1/K/{postrun}{scope=intervaltab}\n\nWith ``kthread-v2.ctags``, ctags emits the following tags:\n\n.. code-block:: console\n\n\t$ ctags --options=linux/kthread-v2.ctags  -o - vmscan.c\n\t...\n\tkswapd%d\tvmscan.c\t/^... = kthread_run(kswapd, pgdat, \"kswapd%d\"...$/;\"\tK\tfunction:kswapd_run\n\t...\n\nWith the new .ctags file, ``function:kswapd_run`` is attach to\nthe tag entry as its scope field.\n\nSEE ALSO\n--------\n\nThe official Universal Ctags web site at:\n\nhttps://ctags.io/\n\nctags(1), tags(5), regex(3), regex(7), egrep(1), pcre2syntax(3)\n\nAUTHOR\n------\n\nUniversal Ctags project\nhttps://ctags.io/\n(This man page partially derived from ctags(1) of\nExecutable-ctags)\n\nDarren Hiebert <dhiebert@users.sourceforge.net>\nhttp://DarrenHiebert.com/\n"
  },
  {
    "path": "man/ctags.1.rst.in",
    "content": ".. _ctags(1):\n\n==============================================================\n@CTAGS_NAME_EXECUTABLE@\n==============================================================\n--------------------------------------------------------------\nGenerate tag files for source code\n--------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 1\n\nSYNOPSIS\n--------\n|\t**@CTAGS_NAME_EXECUTABLE@** [<options>] [<source_file(s)>]\n|\t**@ETAGS_NAME_EXECUTABLE@** [<options>] [<source_file(s)>]\n\n\nDESCRIPTION\n-----------\n\nThe *@CTAGS_NAME_EXECUTABLE@* and *@ETAGS_NAME_EXECUTABLE@* (see ``-e`` option) programs\n(hereinafter collectively referred to as @CTAGS_NAME_EXECUTABLE@,\nexcept where distinguished) generate an index (or \"tag\") file for a\nvariety of *language objects* found in *source file(s)*. This tag file allows\nthese items to be quickly and easily located by a text editor or other\nutilities (*client tools*). A *tag* signifies a language object for which an index entry is\navailable (or, alternatively, the index entry created for that object).\n\nAlternatively, @CTAGS_NAME_EXECUTABLE@ can generate a cross reference\nfile which lists, in human readable form, information about the various\nlanguage objects found in a set of source files.\n\nTag index files are supported by numerous editors, which allow the user to\nlocate the object associated with a name appearing in a source file and\njump to the file and line which defines the name. See the manual of your\nfavorite editor about utilizing @CTAGS_NAME_EXECUTABLE@ command and\nthe tag index files in the editor.\n\n@CTAGS_NAME_EXECUTABLE@ is capable of generating different *kinds* of tags\nfor each of many different *languages*. For a complete list of supported\nlanguages, the names by which they are recognized, and the kinds of tags\nwhich are generated for each, see the ``--list-languages`` and ``--list-kinds-full``\noptions.\n\nThis man page describes *Universal Ctags*, an implementation of ctags\nderived from *Exuberant Ctags*. The major incompatible changes between\nUniversal Ctags and Exuberant Ctags are enumerated in\nctags-incompatibilities(7).\n\nOne of the advantages of Exuberant Ctags is that it allows a user to\ndefine a new parser from the command line. Extending this capability is one\nof the major features of Universal Ctags. ctags-optlib(7)\ndescribes how the capability is extended.\n\nNewly introduced experimental features are not explained here. If you\nare interested in such features and @CTAGS_NAME_EXECUTABLE@ internals,\nvisit https://docs.ctags.io/.\n\n\nCOMMAND LINE INTERFACE\n----------------------\n\nDespite the wealth of available options, defaults are set so that\n@CTAGS_NAME_EXECUTABLE@ is most commonly executed without any options (e.g.\n\"``@CTAGS_NAME_EXECUTABLE@ *``\", or \"``@CTAGS_NAME_EXECUTABLE@ -R``\"), which will\ncreate a tag file in the current directory for all recognized source\nfiles. The options described below are provided merely to allow custom\ntailoring to meet special needs.\n\nNote that spaces separating the single-letter options from their parameters\nare optional.\n\nNote also that the boolean parameters to the long form options (those\nbeginning with ``--`` and that take a ``[=(yes|no)]`` parameter) may be omitted,\nin which case ``=yes`` is implied. (e.g. ``--sort`` is equivalent to ``--sort=yes``).\nNote further that ``=1``, ``=on``, and ``=true`` are considered synonyms for ``=yes``,\nand that ``=0``, ``=off``, and ``=false`` are considered synonyms for ``=no``.\n\nSome options are either ignored or useful only when used while running in\netags mode (see ``-e`` option). Such options will be noted.\n\n*<options>* must precede the *<source_file(s)>* following the standard POSIX\nconvention.\n\nOptions taking language names will accept those names in either upper or\nlower case. See the ``--list-languages`` option for a complete list of the\nbuilt-in language names.\n\n\nLetters and names\n~~~~~~~~~~~~~~~~~\n\nSome options take one-letter flags as parameters (e.g. ``--kinds-<LANG>`` option).\nSpecifying just letters help a user create a complicated command line\nquickly.  However, a command line including sequences of one-letter flags\nbecomes difficult to understand.\n\nUniversal Ctags accepts long-name flags in\naddition to such one-letter flags. The long-name and one-letter flags can be mixed in an\noption parameter by surrounding each long-name by braces. Thus, for an\nexample, the following three notations for ``--kinds-C`` option have\nthe same meaning::\n\n\t--kinds-C=+pLl\n\t--kinds-C=+{prototype}{label}{local}\n\t--kinds-C=+{prototype}L{local}\n\nNote that braces may be meta characters in your shell. Put\nsingle quotes in such case.\n\n``--list-...`` options shows one-letter flags and associated long-name flags.\n\n\nList options\n~~~~~~~~~~~~\n\nUniversal Ctags introduces many ``--list-...`` options that provide\nthe internal data of Universal Ctags (See \"`Listing Options`_\"). Both users and client tools may\nuse the data. ``--with-list-header`` and ``--machinable`` options\nadjust the output of the most of ``--list-...`` options.\n\nThe default setting (``--with-list-header=yes`` and ``--machinable=no``)\nis for using interactively from a terminal. The header that explains\nthe meaning of columns is simply added to the output, and each column is\naligned in all lines. The header line starts with a hash ('``#``') character.\n\nFor scripting in a client tool, ``--with-list-header=no`` and\n``--machinable=yes`` may be useful. The header is not added to the\noutput, and each column is separated by tab characters.\n\nNote the order of columns will change in the future release.\nHowever, labels in the header will not change. So by scanning\nthe header, a client tool can find the index for the target\ncolumn.\n\n.. options that should be explained and revised here\n   ``--list-features``    (done)\n   ``--machinable``       (done)\n   ``--with-list-header`` (done)\n\n\nOPTIONS\n------------\n@CTAGS_NAME_EXECUTABLE@ has more options than listed here.\nOptions starting with an underscore character, such as ``--_echo=<msg>``,\nare not listed here. They are experimental or for debugging purpose.\n\nNotation: ``<foo>`` is for a variable string ``foo``, ``[ ... ]`` for optional,\n``|`` for selection, and ``( ... )`` for grouping.  For example\n``--foo[=(yes|no)]`` means ``--foo``, ``--foo=yes``, or ``--foo=no``.\n\n.. _option_input_output_file:\n\nInput/Output File Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--exclude=<pattern>``\n\tAdd *<pattern>* to a list of excluded files and directories. This option may\n\tbe specified as many times as desired. For each file name considered\n\tby @CTAGS_NAME_EXECUTABLE@, each pattern specified using this option\n\twill be compared against both the complete path (e.g.\n\t``some/path/base.ext``) and the base name (e.g. ``base.ext``) of the file, thus\n\tallowing patterns which match a given file name irrespective of its\n\tpath, or match only a specific path.\n\n\tIf appropriate support is available\n\tfrom the runtime library of your C compiler, then pattern may\n\tcontain the usual shell wildcards (not regular expressions) common on\n\tUnix (be sure to quote the option parameter to protect the wildcards from\n\tbeing expanded by the shell before being passed to @CTAGS_NAME_EXECUTABLE@;\n\talso be aware that wildcards can match the slash character, '``/``').\n\tYou can determine if shell wildcards are available on your platform by\n\texamining the output of the ``--list-features`` option, which will include\n\t``wildcards`` in the compiled feature list; otherwise, pattern is matched\n\tagainst file names using a simple textual comparison.\n\n\tIf *<pattern>* begins with the character '``@``', then the rest of the string\n\tis interpreted as a file name from which to read exclusion patterns,\n\tone per line. If pattern is empty, the list of excluded patterns is\n\tcleared.\n\n\tNote that at program startup, the default exclude list contains names of\n\tcommon hidden and system files, patterns for binary files, and directories\n\tfor which it is generally not desirable to descend while processing the\n\t``--recurse`` option. To see the list of built-in exclude patterns, use\n\t``--list-excludes``.\n\n\tSee also the description for ``--exclude-exception=`` option.\n\n``--exclude-exception=<pattern>``\n\tAdd *<pattern>* to a list of included files and directories. The pattern\n\taffects the files and directories that are excluded by the pattern\n\tspecified with ``--exclude=`` option.\n\n\tFor an example, you want @CTAGS_NAME_EXECUTABLE@ to ignore all files\n\tunder ``foo`` directory except ``foo/main.c``, use the following command\n\tline: ``--exclude=foo/* --exclude-exception=foo/main.c``.\n\n``--filter[=(yes|no)]``\n\tMakes @CTAGS_NAME_EXECUTABLE@ behave as a filter, reading source\n\tfile names from standard input and printing their tags to standard\n\toutput on a file-by-file basis. If ``--sort`` is enabled, tags are sorted\n\tonly within the source file in which they are defined. File names are\n\tread from standard input in line-oriented input mode (see note for ``-L``\n\toption) and only after file names listed on the command line or from\n\tany file supplied using the ``-L`` option. When this option is enabled,\n\tthe options ``-f``, ``-o``, and ``--totals`` are ignored. This option is quite\n\tesoteric and is disabled by default.\n\n``--filter-terminator=<string>``\n\tSpecifies a *<string>* to print to standard output following the tags for\n\teach file name parsed when the ``--filter`` option is enabled. This may\n\tpermit an application reading the output of @CTAGS_NAME_EXECUTABLE@\n\tto determine when the output for each file is finished.\n\n\tNote that if the\n\tfile name read is a directory and ``--recurse`` is enabled, this string will\n\tbe printed only once at the end of all tags found for by descending\n\tthe directory. This string will always be separated from the last tag\n\tline for the file by its terminating newline.\n\n\tThis option is quite esoteric and is empty by default.\n\n``--links[=(yes|no)]``\n\tIndicates whether symbolic links (if supported) should be followed.\n\tWhen disabled, symbolic links are ignored. This option is on by default.\n\n``--maxdepth=<N>``\n\tLimits the depth of directory recursion enabled with the ``--recurse``\n\t(``-R``) option.\n\n``--recurse[=(yes|no)]``\n\tRecurse into directories encountered in the list of supplied files.\n\n\tIf the list of supplied files is empty and no file list is specified with\n\tthe ``-L`` option, then the current directory (i.e. '``.``') is assumed.\n\tSymbolic links are followed by default (See ``--links`` option). If you don't like these behaviors, either\n\texplicitly specify the files or pipe the output of ``find(1)`` into\n\t\"``@CTAGS_NAME_EXECUTABLE@ -L -``\" instead. See, also, the ``--exclude`` and\n\t``--maxdepth`` to limit recursion.\n\n\tNote: This option is not supported on\n\tall platforms at present. It is available if the output of the ``--help``\n\toption includes this option.\n\n.. TODO(code): --list-features option should support this.\n\n``-R``\n\tEquivalent to ``--recurse``.\n\n``-L <file>``\n\tRead from *<file>* a list of file names for which tags should be generated.\n\n\tIf file is specified as '``-``', then file names are read from standard\n\tinput. File names read using this option are processed following file\n\tnames appearing on the command line. Options are also accepted in this\n\tinput. If this option is specified more than once, only the last will\n\tapply.\n\n\tNote: file is read in line-oriented mode, where a new line is\n\tthe only delimiter and non-trailing white space is considered significant,\n\tin order that file names containing spaces may be supplied\n\t(however, trailing white space is stripped from lines); this can affect\n\thow options are parsed if included in the input.\n\n``--append[=(yes|no)]``\n\tIndicates whether tags generated from the specified files should be\n\tappended to those already present in the tag file or should replace them.\n\tThis option is ``no`` by default.\n\n``-a``\n\tEquivalent to ``--append``.\n\n``-f <tagfile>``\n\tUse the name specified by *<tagfile>* for the tag file (default is \"``tags``\",\n\tor \"``TAGS``\" when running in etags mode). If *<tagfile>* is specified as '``-``',\n\tthen the tags are written to standard output instead.\n\n\t@CTAGS_NAME_EXECUTABLE@\n\twill stubbornly refuse to take orders if tagfile exists and\n\tits first line contains something other than a valid tags line. This\n\twill save your neck if you mistakenly type \"``@CTAGS_NAME_EXECUTABLE@ -f\n\t*.c``\", which would otherwise overwrite your first C file with the tags\n\tgenerated by the rest! It will also refuse to accept a multi-character\n\tfile name which begins with a '``-``' (dash) character, since this most\n\tlikely means that you left out the tag file name and this option tried to\n\tgrab the next option as the file name. If you really want to name your\n\toutput tag file ``-ugly``, specify it as \"``-f ./-ugly``\".\n\n\tThis option must\n\tappear before the first file name. If this option is specified more\n\tthan once, only the last will apply.\n\n``-o <tagfile>``\n\tEquivalent to \"``-f tagfile``\".\n\n.. _option_output_format:\n\nOutput Format Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--format=(1|2)``\n\tChange the format of the output tag file. Currently the only valid\n\tvalues for level are 1 or 2. Level 1 specifies the original tag file\n\tformat and level 2 specifies a new extended format containing extension\n\tfields (but in a manner which retains backward-compatibility with\n\toriginal ``vi(1)`` implementations). The default level is 2.\n\t[Ignored in etags mode]\n\n``--output-format=(u-ctags|e-ctags|etags|xref|json)``\n\tSpecify the output format. The default is ``u-ctags``.\n\tSee tags(5) for ``u-ctags`` and ``e-ctags``.\n\t``TAG_OUTPUT_MODE`` pseudo tag indicates the choice,\n\t``u-ctags`` or ``e-ctags``. See ctags-client-tools(7)\n\tfor more about the pseudo tag.\n\n\tSee ``-e`` for ``etags``, and ``-x`` for ``xref``.\n\t``json`` format is available only if\n\tthe ctags executable is built with ``libjansson``.\n\tSee ctags-json-output(5) for more about ``json`` format.\n\n\tSee also ``--list-output-formats``.\n\n``-e``\n\tSame as ``--output-format=etags``.\n\tEnable etags mode, which will create a tag file for use with the Emacs\n\teditor. Alternatively, if @CTAGS_NAME_EXECUTABLE@ is invoked by a\n\tname containing the string \"@ETAGS_NAME_EXECUTABLE@\" (either by renaming,\n\tor creating a link to, the executable), etags mode will be enabled.\n\n``-x``\n\tSame as ``--output-format=xref``.\n\tPrint a tabular, human-readable cross reference (xref) file to standard\n\toutput instead of generating a tag file. The information contained in\n\tthe output includes: the tag name; the kind of tag; the line number,\n\tfile name, and source line (with extra white space condensed) of the\n\tfile which defines the tag. No tag file is written and all options\n\taffecting tag file output will be ignored.\n\n\tExample applications for this\n\tfeature are generating a listing of all functions located in a source\n\tfile (e.g. \"``@CTAGS_NAME_EXECUTABLE@ -x --kinds-c=f file``\"), or generating\n\ta list of all externally visible global variables located in a source\n\tfile (e.g. \"``@CTAGS_NAME_EXECUTABLE@ -x --kinds-c=v --extras=-F file``\").\n\n``--sort=(yes|no|foldcase)``\n\tIndicates whether the tag file should be sorted on the tag name\n\t(default is ``yes``). Note that the original ``vi(1)`` required sorted tags.\n\tThe ``foldcase`` value specifies case insensitive (or case-folded) sorting.\n\tFast binary searches of tag files sorted with case-folding will require\n\tspecial support from tools using tag files, such as that found in the\n\t@CTAGS_NAME_EXECUTABLE@ readtags library, or Vim version 6.2 or higher\n\t(using \"``set ignorecase``\").\n\t[Ignored in etags mode]\n\n``-u``\n\tEquivalent to ``--sort=no`` (i.e. \"unsorted\").\n\n``--etags-include=<file>``\n\tInclude a reference to *<file>* in the tag file. This option may be specified\n\tas many times as desired. This supports Emacs' capability to use a\n\ttag file which *includes* other tag files. [Available only in etags mode]\n\n``--input-encoding=<encoding>``\n\tSpecifies the *<encoding>* of the input files.\n\tIf this option is specified, Universal Ctags converts the input from this\n\tencoding to the encoding specified by ``--output-encoding=encoding``.\n\n``--input-encoding-<LANG>=<encoding>``\n\tSpecifies a specific input *<encoding>* for *<LANG>*. It overrides the global\n\tdefault value given with ``--input-encoding``.\n\n``--output-encoding=<encoding>``\n\tSpecifies the *<encoding>* of the tags file.\n\tUniversal Ctags converts the encoding of input files from the encoding\n\tspecified by ``--input-encoding=<encoding>`` to this encoding.\n\n\tIn addition *<encoding>* is specified at the top the tags file as the\n\tvalue for the ``TAG_FILE_ENCODING`` pseudo-tag. The default value of\n\t*<encoding>* is ``UTF-8``.\n\n.. _option_lang_mapping:\n\nLanguage Selection and Mapping Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--language-force=(<language>|auto)``\n\tBy default, @CTAGS_NAME_EXECUTABLE@ automatically selects the language\n\tof a source file, ignoring those files whose language cannot be\n\tdetermined (see \"`Determining file language`_\"). This option forces the specified\n\t*language* (case-insensitive; either built-in or user-defined) to be used\n\tfor every supplied file instead of automatically selecting the language\n\tbased upon its extension.\n\n\tIn addition, the special value ``auto`` indicates\n\tthat the language should be automatically selected (which effectively\n\tdisables this option).\n\n``--languages=[+|-](<list>|all)``\n\tSpecifies the languages for which tag generation is enabled, with *<list>*\n\tcontaining a comma-separated list of language names (case-insensitive;\n\teither built-in or user-defined).\n\n\tIf the first language of *<list>* is not\n\tpreceded by either a '``+``' or '``-``', the current list (the current settings\n\tof enabled/disabled languages managed in @CTAGS_NAME_EXECUTABLE@ internally)\n\twill be cleared before adding or removing the languages in *<list>*. Until a '``-``' is\n\tencountered, each language in the *<list>* will be added to the current list.\n\n\tAs either the '``+``' or '``-``' is encountered in the *<list>*, the languages\n\tfollowing it are added or removed from the current list, respectively.\n\tThus, it becomes simple to replace the current list with a new one, or\n\tto add or remove languages from the current list.\n\n\tThe actual list of\n\tfiles for which tags will be generated depends upon the language\n\textension mapping in effect (see the ``--langmap`` option). Note that the most of\n\tlanguages, including user-defined languages, are enabled unless explicitly\n\tdisabled using this option. Language names included in list may be any\n\tbuilt-in language or one previously defined with ``--langdef``.\n\n\tThe default\n\tis ``all``, which is also accepted as a valid argument. See the\n\t``--list-languages`` option for a list of the all (built-in and user-defined)\n\tlanguage names.\n\n\tNote ``--languages=`` option works cumulative way; the option can be\n\tspecified with different arguments multiple times in a command line.\n\n``--alias-<LANG>=[+|-](<pattern>|default)``\n\tAdds ('``+``') or removes ('``-``') an alias *<pattern>* to a language specified\n\twith *<LANG>*. @CTAGS_NAME_EXECUTABLE@ refers to the alias pattern in\n\t\"`Determining file language`_\" stage.\n\n\tThe parameter *<pattern>* is not a list. Use this option multiple\n\ttimes in a command line to add or remove multiple alias\n\tpatterns.\n\n\tTo restore the default language aliases, specify ``default``.\n\n\tUsing ``all`` for *<LANG>* has meaning in following two cases:\n\n\t``--alias-all=``\n\t\tThis clears aliases setting of all languages.\n\n\t``--alias-all=default``\n\t\tThis restores the default languages aliases for all languages.\n\n``--guess-language-eagerly``\n\tLooks into the file contents for heuristically guessing the proper language parser.\n\tSee \"`Determining file language`_\".\n\n``-G``\n\tEquivalent to ``--guess-language-eagerly``.\n\n``--langmap=<map>[,<map>[...]]``\n\tControls how file names are mapped to languages (see the ``--list-maps``\n\toption). Each comma-separated *<map>* consists of the language name (either\n\ta built-in or user-defined language), a colon, and a list of *file\n\textensions* and/or *file name patterns*. A file extension is specified by\n\tpreceding the extension with a period (e.g. ``.c``). A file name pattern\n\tis specified by enclosing the pattern in parentheses (e.g.\n\t``([Mm]akefile)``).\n\n\tIf appropriate support is available from the runtime\n\tlibrary of your C compiler, then the file name pattern may contain the usual\n\tshell wildcards common on Unix (be sure to quote the option parameter to\n\tprotect the wildcards from being expanded by the shell before being\n\tpassed to @CTAGS_NAME_EXECUTABLE@). You can determine if shell wildcards\n\tare available on your platform by examining the output of the\n\t``--list-features`` option, which will include ``wildcards`` in the compiled\n\tfeature list; otherwise, the file name patterns are matched against\n\tfile names using a simple textual comparison.\n\n\tWhen mapping a file extension or a file name pattern with\n\t``--langmap`` option, it will first be unmapped from any other\n\tlanguages. (``--map-<LANG>`` option provides more fine-grained\n\tcontrol.)\n\n\tIf the first character in a *<map>* is a plus sign ('``+``'), then the extensions and\n\tfile name patterns in that map will be appended to the current map\n\tfor that language; otherwise, the map will replace the current map.\n\tFor example, to specify that only files with extensions of ``.c`` and ``.x`` are\n\tto be treated as C language files, use ``--langmap=c:.c.x``; to also add\n\tfiles with extensions of ``.j`` as Java language files, specify\n\t``--langmap=c:.c.x,java:+.j``. To map makefiles (e.g. files named either\n\t``Makefile``, ``makefile``, or having the extension ``.mak``) to a language\n\tcalled ``make``, specify ``--langmap=make:([Mm]akefile).mak``. To map files\n\thaving no extension, specify a period not followed by a non-period\n\tcharacter (e.g. '``.``', ``..x``, ``.x.``).\n\n\tTo clear the mapping for a\n\tparticular language (thus inhibiting automatic generation of tags for\n\tthat language), specify an empty extension list (e.g. ``--langmap=fortran:``).\n\tTo restore the default language mappings for a particular language,\n\tsupply the keyword ``default`` for the mapping. To specify restore the\n\tdefault language mappings for all languages, specify ``--langmap=default``.\n\n\tNote that file name patterns are tested before file extensions when inferring\n\tthe language of a file. This order of Universal Ctags is different from\n\tExuberant Ctags. See ctags-incompatibilities(7) for the background of\n\tthis incompatible change.\n\n\tUnlike ``--map-<LANG>`` option, you cannot specify relative-path regular\n\t expressions to ``--langmap`` option.\n\n``--map-<LANG>=[+|-]<extension>|<pattern>|<rexpr>``\n\tThis option provides the way to control mapping(s) of file names to\n\tlanguages in a more fine-grained way than ``--langmap`` option.\n\n\tIn @CTAGS_NAME_EXECUTABLE@, more than one language can map to a\n\trelative-path regular expression (*<rexpr>*), file name *<pattern>*, or\n\tfile *<extension>* (*N:1 map*). Alternatively, ``--langmap``\n\toption handle only *1:1 map*, only one language mapping to one\n\tfile name *<pattern>* or file *<extension>*.  A typical N:1 map is\n\tseen in C++ and ObjectiveC language; both languages have a map to\n\t``.h`` as a file extension.\n\n\tA file extension is specified by preceding the extension with a period\n\t(e.g. ``.c``).  A file name pattern is specified by enclosing the pattern in\n\tparentheses (e.g.  ``([Mm]akefile)``). A relative-path regular expression is\n\tspecified by enclosing the expressions in percent signs '``%``'\n\t(e.g. ``%include/.*\\.h%``). To include a literal percent sign\n\tinside the regular expression, escape it as ``\\%``.\n\n\tA prefixed plus ('``+``') sign is for adding, and\n\tminus ('``-``') is for removing. No prefix means replacing the map of *<LANG>*.\n\n\tUnlike ``--langmap``, ``--map-<LANG>`` does not take a list; ``--map-<LANG>``\n\ttakes one extension, one pattern, or one regular expression. However, the\n\toption can be specified with different arguments multiple times in a command\n\tline.\n\n\tFor file extensions and file name patterns, the match is performed\n\twith a base file name, a file without any directory components.\n\tFor relative-path regular expressions, the match is performed with\n\ta relative-path incorporating the directory components. A\n\trelative-path is relative to the directory where ctags launches.\n\n\tAssume your shell is in ``/project/x`` directory and you have the following\n\tsource tree under the directory.\n\n\t.. code-block::\n\n\t\tsrc\n\t\t└── lib\n\t\t    ├── data.c\n\t\t    └── logic.c\n\n\tIf you run @CTAGS_NAME_EXECUTABLE@ with ``@CTAGS_NAME_EXECUTABLE@ -R src``,\n\tthe match is performed with ``src/lib/data.c`` and ``src/lib/logic.c`` If you\n\tgive ``--map-YourParser='%src/lib/.*\\.c%'``, @CTAGS_NAME_EXECUTABLE@\n\tchooses ``YourParser`` parser for processing ``data.c`` and ``logic.c`` in the\n\ttree.\n\n\tIf your shell is in ``/project/x/src`` and you run\n\t``@CTAGS_NAME_EXECUTABLE@ -R lib``, @CTAGS_NAME_EXECUTABLE@ may not choose\n\t``YourParser`` because the match is performed with ``lib/data.c`` and\n\t``lib/logic.c``.\n\n\tA relative-path regular expression can take a flag controlling its testing.\n\tThe flag comes after the last percent sign. Currently only one available flag:\n\n\t``{icase}`` (one-letter form '``i``')\n\t\tThe regular expression is to be applied in a case-insensitive\n\t\tmanner. (e.g. ``%include/.*\\.h%i`` or ``%include/.*\\.h%{icase}``\n\n\tThe relative-path regular expression is available since version 6.3.0.\n\n.. _option_tags_file_contents:\n\nTags File Contents Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSee \"`TAG ENTRIES`_\" about fields, kinds, roles, and extras.\n\n``--excmd=(number|pattern|mix|combine)``\n\tDetermines the type of ``EX`` command used to locate tags in the source\n\tfile. [Ignored in etags mode]\n\n\tThe valid values for type (either the entire word or the first letter\n\tis accepted) are:\n\n\t``number``\n\t\tUse only line numbers in the tag file for locating tags. This has\n\t\tfour advantages:\n\n\t\t1.\tSignificantly reduces the size of the resulting tag file.\n\t\t2.\tEliminates failures to find tags because the line defining the\n\t\t\ttag has changed, causing the pattern match to fail (note that\n\t\t\tsome editors, such as ``vim``, are able to recover in many such\n\t\t\tinstances).\n\t\t3.\tEliminates finding identical matching, but incorrect, source\n\t\t\tlines (see \"`BUGS`_\").\n\t\t4.\tRetains separate entries in the tag file for lines which are\n\t\t\tidentical in content. In pattern mode, duplicate entries are\n\t\t\tdropped because the search patterns they generate are identical,\n\t\t\tmaking the duplicate entries useless.\n\n\t\tHowever, this option has one significant drawback: changes to the\n\t\tsource files can cause the line numbers recorded in the tag file\n\t\tto no longer correspond to the lines in the source file, causing\n\t\tjumps to some tags to miss the target definition by one or more\n\t\tlines. Basically, this option is best used when the source code\n\t\tto which it is applied is not subject to change. Selecting this\n\t\toption type causes the following options to be ignored: ``-B``, ``-F``.\n\n\t\t``number`` type is ignored in Xref and JSON output formats. Use\n\t\t``--_xformat=\"...%n\"`` for Xref output format, or ``--fields=+n-P`` for\n\t\tJSON output format.\n\n\t\t.. NOTE: #2792\n\n\t``pattern``\n\t\tUse only search patterns for all tags, rather than the line numbers\n\t\tusually used for macro definitions. This has the advantage of\n\t\tnot referencing obsolete line numbers when lines have been added or\n\t\tremoved since the tag file was generated.\n\n\t``mixed``\n\t\tIn this mode, patterns are generally used with an exceptions.\n\t\tFor Fortran, line numbers\n\t\tare used for common blocks because their corresponding source lines\n\t\tare generally identical, making pattern searches useless\n\t\tfor finding all matches.\n\n\t\tExuberant Ctags has one more exception; for C, line numbers are used\n\t\tfor macro definition tags. Universal Ctags doesn't have this exception\n\t\tfor C.\n\n\t\tThis was the default format generated by the original ctags and is,\n\t\ttherefore, retained as the default for this option.\n\n\t``combine``\n\t\tConcatenate the line number and pattern with a semicolon in between.\n\n``-n``\n\tEquivalent to ``--excmd=number``.\n\n``-N``\n\tEquivalent to ``--excmd=pattern``.\n\n``--extras=[+|-][<flags>|*]``\n\tSpecifies whether to include extra tag entries for certain kinds of\n\tinformation. See also \"`Extras`_\" subsection to know what are extras.\n\n\tThe parameter *<flags>* is a set of one-letter flags (and/or long-name flags), each\n\trepresenting one kind of extra tag entry to include in the tag file.\n\tIf flags is preceded by either the '``+``' or '``-``' character, the effect of\n\teach flag is added to, or removed from, those currently enabled;\n\totherwise the flags replace any current settings. All entries are\n\tincluded  if '``*``' is given.\n\n\tThis ``--extras=`` option is for controlling extras common in all\n\tlanguages (or language-independent extras).  Universal Ctags also\n\tsupports language-specific extras. (See \"`Language-specific fields and\n\textras`_\" about the concept). Use ``--extras-<LANG>=`` option for\n\tcontrolling them.\n\n``--extras-(<LANG>|all)=[+|-][<flags>|*]``\n\tSpecifies whether to include extra tag entries for certain kinds of\n\tinformation for language *<LANG>*. Universal Ctags\n\tintroduces language-specific extras. See \"`Language-specific fields and\n\textras`_\" about the concept. This option is for controlling them.\n\n\tSpecifies ``all`` as *<LANG>* to apply the parameter *<flags>* to all\n\tlanguages; all extras are enabled with specifying '``*``' as the\n\tparameter flags. If specifying nothing as the parameter flags\n\t(``--extras-all=``), all extras are disabled. These two combinations\n\tare useful for testing.\n\n\tCheck the output of the ``--list-extras=<LANG>`` option for the\n\textras of specific language *<LANG>*.\n\n``--fields=[+|-][<flags>|*]``\n\tSpecifies which language-independent fields are to be included in the tag\n\tentries. Language-independent fields are extension fields which are common\n\tin all languages. See \"`TAG FILE FORMAT`_\" section, and \"`Extension fields`_\"\n\tsubsection, for details of extension fields.\n\n\tThe parameter *<flags>* is a set of one-letter or long-name flags,\n\teach representing one type of extension field to include.\n\tEach flag or group of flags may be preceded by either '``+``' to add it\n\tto the default set, or '``-``' to exclude it. In the absence of any\n\tpreceding '``+``' or '``-``' sign, only those fields explicitly listed in flags\n\twill be included in the output (i.e. overriding the default set). All\n\tfields are included if '``*``' is given.\n\n\tThis option is ignored if the\n\toption ``--format=1`` (legacy tag file format) has been specified.\n\n\tUse ``--fields-<LANG>=`` option for controlling language-specific fields.\n\n``--fields-(<LANG>|all)=[+|-][<flags>|*]``\n\tSpecifies which language-specific fields are to be included in\n\tthe tag entries. Universal Ctags\n\tsupports language-specific fields. (See \"`Language-specific fields and\n\textras`_\" about the concept).\n\n\tSpecify ``all`` as *<LANG>* to apply the parameter *<flags>* to all\n\tlanguages; all fields are enabled with specifying '``*``' as the\n\tparameter flags. If specifying nothing as the parameter *<flags>*\n\t(i.e. ``--fields-all=``), all fields are disabled. These two combinations\n\tare useful for testing.\n\n\tSee the description of ``--fields=[+|-][<flags>|*]`` about *<flags>*.\n\n\tUse ``--fields=`` option for controlling language-independent fields.\n\n\n``--kinds-(<LANG>|all)=[+|-](<kinds>|*)``\n\tSpecifies a list of language-specific *<kinds>* of tags (or kinds) to\n\tinclude in the output file for a particular language, where *<LANG>* is\n\tcase-insensitive and is one of the built-in language names (see the\n\t``--list-languages`` option for a complete list).\n\n\tThe parameter *<kinds>* is a group\n\tof one-letter or long-name flags designating kinds of tags (particular to the language)\n\tto either include or exclude from the output. The specific sets of\n\tflags recognized for each language, their meanings and defaults may be\n\tlist using the ``--list-kinds-full`` option.\n\n\tEach letter or group of letters\n\tmay be preceded by either '``+``' to add it to, or '``-``' to remove it from,\n\tthe default set. In the absence of any preceding '``+``' or '``-``' sign, only\n\tthose kinds explicitly listed in kinds will be included in the output\n\t(i.e. overriding the default for the specified language).\n\n\tSpecify '``*``' as the parameter to include all kinds implemented\n\tin *<LANG>* in the output. Furthermore if ``all`` is given as *<LANG>*,\n\tspecification of the parameter ``kinds`` affects all languages defined\n\tin @CTAGS_NAME_EXECUTABLE@. Giving ``all`` makes sense only when '``*``' or\n\t'``F``' is given as the parameter ``kinds``.\n\n\tAs an example for the C language, in order to add prototypes and\n\texternal variable declarations to the default set of tag kinds,\n\tbut exclude macros, use ``--kinds-c=+px-d``; to include only tags for\n\tfunctions, use ``--kinds-c=f``.\n\n\tSome kinds of C and C++ languages are synchronized; enabling\n\t(or disabling) a kind in one language enables the kind having\n\tthe same one-letter and long-name in the other language. See also the\n\tdescription of ``MASTER`` column of ``--list-kinds-full``.\n\n..\tCOMMENT:\n\t``--param-<LANG>.name=argument`` is moved to \"Language Specific Options\"\n\n``--pattern-length-limit=<N>``\n\tTruncate patterns of tag entries after *<N>* characters. Disable by setting to 0\n\t(default is 96).\n\n\tAn input source file with long lines and multiple tag matches per\n\tline can generate an excessively large tags file with an\n\tunconstrained pattern length. For example, running ctags on a\n\tminified JavaScript source file often exhibits this behavior.\n\n\tThe truncation avoids cutting in the middle of a UTF-8 code point\n\tspanning multiple bytes to prevent writing invalid byte sequences from\n\tvalid input files. This handling allows for an extra 3 bytes above the\n\tconfigured limit in the worse case of a 4 byte code point starting\n\tright before the limit. Please also note that this handling is fairly\n\tnaive and fast, and although it is resistant against any input, it\n\trequires a valid input to work properly; it is not guaranteed to work\n\tas the user expects when dealing with partially invalid UTF-8 input.\n\tThis also partially affect non-UTF-8 input, if the byte sequence at\n\tthe truncation length looks like a multibyte UTF-8 sequence. This\n\tshould however be rare, and in the worse case will lead to including\n\tup to an extra 3 bytes above the limit.\n\n``--pseudo-tags=[+|-](<pseudo-tag>|*)``\n\tEnable/disable emitting pseudo-tag named *<pseudo-tag>*.\n\tIf '``*``' is given, enable/disable emitting all pseudo-tags.\n\n``--put-field-prefix``\n\tPut ``UCTAGS`` as prefix for the name of fields newly introduced in\n\tUniversal Ctags.\n\n\tSome fields are newly introduced in Universal Ctags and more will\n\tbe introduced in the future. Other tags generators may also\n\tintroduce their specific fields.\n\n\tIn such a situation, there is a concern about conflicting field\n\tnames; mixing tags files generated by multiple tags generators\n\tincluding Universal Ctags is difficult. This option provides a\n\tworkaround for such station.\n\n\t.. code-block:: console\n\n\t\t$ @CTAGS_NAME_EXECUTABLE@ --fields='{line}{end}' -o - hello.c\n\t\tmain\thello.c\t/^main(int argc, char **argv)$/;\"\tf\tline:3\tend:6\n\t\t$ @CTAGS_NAME_EXECUTABLE@ --put-field-prefix --fields='{line}{end}' -o - hello.c\n\t\tmain\thello.c\t/^main(int argc, char **argv)$/;\"\tf\tline:3\tUCTAGSend:6\n\n\tIn the above example, the prefix is put to ``end`` field which is\n\tnewly introduced in Universal Ctags.\n\n``--roles-(<LANG>|all).(<kind>|*)=[+|-][<roles>|*]``\n\tSpecifies a list of kind-specific roles of tags to include in the\n\toutput file for a particular language.\n\t*<kind>* specifies the kind where the *<roles>* are defined.\n\t*<LANG>* specifies the language where the kind is defined.\n\tEach role in *<roles>* must be surrounded by braces (e.g. ``{system}``\n\tfor a role named \"system\").\n\n\tLike ``--kinds-<LANG>`` option, '``+``' is for adding the role to the\n\tlist, and '``-``' is for removing from the list. '``*``' is for including\n\tall roles of the kind to the list. \tThe option with no argument\n\tmakes the list empty.\n\n\tBoth a one-letter flag or a long name flag surrounded by braces are\n\tacceptable for specifying a kind (e.g. ``--roles-C.h=+{system}{local}``\n\tor ``--roles-C.{header}=+{system}{local}``).  '``*``' can be used for *<KIND>*\n\tonly for adding/removing all roles of all kinds in a language to/from\n\tthe list (e.g.  ``--roles-C.*=*`` or ``--roles-C.*=``).\n\n\t``all`` can be used for *<LANG>* only for adding/removing all roles of\n\tall kinds in all languages to/from the list\n\t(e.g.  ``--roles-all.*=*`` or ``--roles-all.*=``).\n\n``--tag-relative=(yes|no|always|never)``\n\tSpecifies how the file paths recorded in the tag file.\n\tThe default is ``yes`` when running in etags mode (see\n\tthe ``-e`` option), ``no`` otherwise.\n\n\t``yes``\n\t\tindicates that the file paths recorded in the tag file should be\n\t\t*relative to the directory containing the tag file*\n\t\tunless the files supplied on the command line\n\t\tare specified with absolute paths.\n\n\t``no``\n\t\tindicates that the file paths recorded in the tag file should be\n\t\t*relative to the current directory*\n\t\tunless the files supplied on the command line\n\t\tare specified with absolute paths.\n\n\t``always``\n\t\tindicates the recorded file paths should be relative\n\t\teven if source file names are passed in with absolute paths.\n\n\t``never``\n\t\tindicates the recorded file paths should be absolute\n\t\teven if source file names are passed in with relative paths.\n\n``--use-slash-as-filename-separator[=(yes|no)]``\n\tUses slash ('``/``') character as filename separators instead of backslash\n\t('``\\``') character when printing ``input:`` field.\n\tThe default is ``yes`` for the default \"u-ctags\" output format, and\n\t``no`` for the other formats.\n\n\t``TAG_OUTPUT_FILESEP`` pseudo tag is for representing  the choice of\n\tfilename separators with this option. See also ctags-client-tools(7).\n\n\tThis option is available on MS Windows only.\n\n``-B``\n\tUse backward searching patterns (e.g. ``?pattern?``). [Ignored in etags mode]\n\n``-F``\n\tUse forward searching patterns (e.g. ``/pattern/``) (default). [Ignored\n\tin etags mode]\n\nOption File Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n.. TODO: merge some of description in option-file.rst into FILE or a dedicated\n\tsection\n\n``--options=<pathname>``\n\tRead additional options from file or directory.\n\n\t@CTAGS_NAME_EXECUTABLE@ searches *<pathname>* in the optlib path list\n\tfirst. If @CTAGS_NAME_EXECUTABLE@ cannot find a file or directory\n\tin the list, @CTAGS_NAME_EXECUTABLE@ reads a file or directory\n\tat the specified *<pathname>*.\n\n\tIf a file is specified, it should contain one option per line. If\n\ta directory is specified, files suffixed with ``.ctags`` under it\n\tare read in alphabetical order.\n\n\tAs a special case, if ``--options=NONE`` is specified as the first\n\toption on the command line, preloading is disabled; the option\n\twill disable the automatic reading of any configuration options\n\tfrom a file (see \"`FILES`_\").\n\n``--options-maybe=<pathname>``\n\tSame as ``--options`` but doesn't cause an error if file\n\t(or directory) specified with *<pathname>* doesn't exist.\n\n``--optlib-dir=[+]<directory>``\n\tAdd an optlib *<directory>* to or reset the optlib path list.\n\tSee \"`Default optlib path list`_\" about the default elements for optlib path list.\n\noptlib Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSee ctags-optlib(7) for details of each option.\n\n``--kinddef-<LANG>=<letter>,<name>,<description>``\n\tDefine a kind for *<LANG>*.\n\tDon't be confused this with ``--kinds-<LANG>``.\n\n``--langdef=<name>``\n\tDefines a new user-defined language, *<name>*, to be parsed with regular\n\texpressions.\n\n``--mline-regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``\n\tDefine multi-line regular expression for locating tags in specific language.\n\n``--regex-<LANG>=/<line_pattern>/<name_pattern>/<kind-spec>/[<flags>]``\n\tDefine single-line regular expression for locating tags in specific language.\n\n.. _option_lang_specific:\n\nLanguage Specific Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--if0[=(yes|no)]``\n\tIndicates a preference as to whether code within an \"``#if 0``\" branch of a\n\tpreprocessor conditional should be examined for non-macro tags (macro\n\ttags are always included). Because the intent of this construct is to\n\tdisable code, the default value of this option is ``no`` (disabled).\n\n\tNote that this\n\tindicates a preference only and does not guarantee skipping code within\n\tan \"``#if 0``\" branch, since the fall-back algorithm used to generate\n\ttags when preprocessor conditionals are too complex follows all branches\n\tof a conditional.\n\n``--line-directives[=(yes|no)]``\n\tSpecifies whether ``#line`` directives should be recognized. These are\n\tpresent in the output of a preprocessor and contain the line number, and\n\tpossibly the file name, of the original source file(s) from which the\n\tpreprocessor output file was generated. This option is off by default.\n\n\tWhen enabled, this option will\n\tcause @CTAGS_NAME_EXECUTABLE@ to generate tag entries marked with the\n\tfile names and line numbers of their locations original source file(s),\n\tinstead of their actual locations in the preprocessor output. The actual\n\tfile names placed into the tag file will have the same leading path\n\tcomponents as the preprocessor output file, since it is assumed that\n\tthe original source files are located relative to the preprocessor\n\toutput file (unless, of course, the ``#line`` directive specifies an\n\tabsolute path).\n\n\tNote: This option is generally\n\tonly useful when used together with the ``--excmd=number`` (``-n``) option.\n\tAlso, you may have to use either the ``--langmap`` or ``--language-force`` option\n\tif the extension of the preprocessor output file is not known to\n\t@CTAGS_NAME_EXECUTABLE@.\n\n``-D <macro>=<definition>``\n\tDefines a C preprocessor *<macro>*. This emulates the behavior of the\n\tcorresponding gcc option. All types of macros are supported,\n\tincluding the ones with parameters and variable arguments.\n\tStringification, token pasting and recursive macro expansion are also\n\tsupported.\n\tThis extends the function provided by ``-I`` option.\n\n``-h (<list>|default)``\n\tSpecifies a *<list>* of file extensions, separated by periods, which are\n\tto be interpreted as include (or header) files. To indicate files having\n\tno extension, use a period not followed by a non-period character\n\t(e.g. '``.``', ``..x``, ``.x.``).\n\n\tThis option only affects how the scoping of\n\tparticular kinds of tags are interpreted (i.e. whether or not they are\n\tconsidered as globally visible or visible only within the file in which\n\tthey are defined); it does not map the extension to any particular\n\tlanguage. Any tag which is located in a non-include file and cannot be\n\tseen (e.g. linked to) from another file is considered to have file-limited\n\t(e.g. static) scope. No kind of tag appearing in an include file\n\twill be considered to have file-limited scope.\n\n\tIf the first character in the list is '``+``', then the extensions in the list will be\n\tappended to the current list; otherwise, the list will replace the\n\tcurrent list. See, also, the ``fileScope``/``F`` flag of ``--extras`` option.\n\n\tThe default list is\n\t``.h.H.hh.hpp.hxx.h++.inc.def``. To restore the default list, specify \"``-h\n\tdefault``\".\n\n\tNote that if an extension supplied to this option is not\n\talready mapped to a particular language (see \"`Determining file language`_\", above),\n\tyou will also need to use either the ``--map-<LANG>``, ``--langmap`` or\n\t``--language-force`` option.\n\n``-I <identifier-list>``\n\tSpecifies a *<identifier-list>* of identifiers which are to be specially handled while\n\tparsing C and C++ source files. This option is specifically provided\n\tto handle special cases arising through the use of preprocessor macros.\n\tWhen the identifiers listed are simple identifiers, these identifiers\n\twill be ignored during parsing of the source files.\n\n\tIf an identifier is\n\tsuffixed with a '``+``' character (i.e. \"``-I FOO+``\"), @CTAGS_NAME_EXECUTABLE@ will also\n\tignore any parenthesis-enclosed argument list which may immediately\n\tfollow the identifier in the source files. See the example of \"``-I\n\tMODULE_VERSION+``\" below.\n\n\tIf two identifiers are\n\tseparated with the '``=``' character (i.e. ``-I FOO=BAR``), the first identifiers is replaced by\n\tthe second identifiers for parsing purposes. The list of identifiers may\n\tbe supplied directly on the command line or read in from a separate file.\n\tSee the example of \"``-I CLASS=class``\" below.\n\n\tIf the first character of *<identifier-list>* is '``@``', '``.``' or a pathname\n\tseparator ('``/``' or '``\\``'), or the first two characters specify a drive\n\tletter (e.g. ``C:``), the parameter *<identifier-list>* will be interpreted as\n\ta filename from which to read a list of identifiers, one per input line.\n\n\tOtherwise, *<identifier-list>* is a list of identifiers (or identifier\n\tpairs) to be specially handled, each delimited by either a comma or\n\tby white space (in which case the list should be quoted to keep the\n\tentire list as one command line argument).\n\n\tMultiple ``-I`` options may be\n\tsupplied. To clear the list of ignore identifiers, supply a single\n\tdash ('``-``') for *<identifier-list>*.\n\n\tThis feature is useful when preprocessor macros are used in such a way\n\tthat they cause syntactic confusion due to their presence. Indeed,\n\tthis is the best way of working around a number of problems caused by\n\tthe presence of syntax-busting macros in source files (see \"`CAVEATS`_\").\n\tSome examples will illustrate this point.\n\n\t.. code-block:: C\n\n\t\tint foo ARGDECL4(void *, ptr, long int, nbytes)\n\n\tIn the above example, the macro ``ARGDECL4`` would be mistakenly\n\tinterpreted to be the name of the function instead of the correct name\n\tof ``foo``. Specifying \"``-I ARGDECL4``\" results in the correct behavior.\n\n\t.. code-block:: C\n\n\t\t/* creates an RCS version string in module */\n\t\tMODULE_VERSION(\"$Revision$\")\n\n\tIn the above example the macro invocation looks too much like a function\n\tdefinition because it is not followed by a semicolon (indeed, it\n\tcould even be followed by a global variable definition that would look\n\tmuch like a K&R style function parameter declaration). In fact, this\n\tseeming function definition could possibly even cause the rest of the\n\tfile to be skipped over while trying to complete the definition.\n\tSpecifying \"``-I MODULE_VERSION+``\" would avoid such a problem.\n\n\t.. code-block:: C\n\n\t\tCLASS Example {\n\t\t\t// your content here\n\t\t};\n\n\tThe example above uses ``CLASS`` as a preprocessor macro which expands to\n\tsomething different for each platform. For instance ``CLASS`` may be\n\tdefined as ``class __declspec(dllexport)`` on Win32 platforms and simply\n\t``class`` on UNIX. Normally, the absence of the C++ keyword ``class``\n\twould cause the source file to be incorrectly parsed. Correct behavior\n\tcan be restored by specifying \"``-I CLASS=class``\".\n\n``--param-<LANG>.<name>=<argument>``\n\tSet a *<LANG>* specific parameter, a parameter specific to the *<LANG>*.\n\n\tAvailable parameters can be listed with ``--list-params``.\n\n.. _option_listing:\n\nListing Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n``--list-aliases[=(<language>|all)]``\n\tLists the aliases for either the specified *<language>* or ``all``\n\tlanguages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\tThe aliases are used when heuristically testing a language parser for a\n\tsource file.\n\n``--list-excludes``\n\tLists the current exclusion patterns used to exclude files.\n\n``--list-extras[=(<language>|NONE|all)]``\n\tLists the extras recognized for either the specified *<language>* or\n\t``all`` languages. If ``NONE`` is specified, it lists only extras\n\tcommon in all languages.\n\tSee \"`Extras`_\" subsection to know what are extras.\n\t``all`` is used as default value if the option argument is omitted.\n\n\tAn extra can be enabled or disabled with ``--extras=`` for common\n\textras in all languages, or ``--extras-<LANG>=`` for the specified\n\tlanguage.  These option takes one-letter flag or long-name flag as a parameter\n\tfor specifying an extra.\n\n\tThe meaning of columns in output are as follows:\n\n\tLETTER\n\t\tOne-letter flag. '``-``' means the extra does not have one-letter flag.\n\n\tNAME\n\t\tLong-name flag. The long-name is used in ``extras`` field.\n\n\tENABLED\n\t\tWhether the extra is enabled or not. It takes ``yes`` or ``no``.\n\n\tLANGUAGE\n\t\tThe name of language if the extra is owned by a parser.\n\t\t``NONE`` means the extra is common in parsers.\n\n\tVER\n\t\tThe ctags output version introducing the extra for a language-independent\n\t\textra, or the parser version introducing the extra for a\n\t\tlanguage-specified extra. See the ``--version`` option and\n\t\t``TAG_OUTPUT_VERSION`` in ctags-client-tools(7) about the ctags output\n\t\tversion.\n\n\t\t(since version 6.3.0)\n\n\tDESCRIPTION\n\t\tHuman readable description for the extra.\n\n``--list-features``\n\tLists the compiled features.\n\n``--list-fields[=(<language>|NONE|all)]``\n\tLists the fields recognized for either the specified *<language>* or\n\t``all`` languages. If ``NONE`` is specified, it lists only fields\n\tcommon in all languages.\n\tSee \"`Extension fields`_\" subsection to know what are fields.\n\t``all`` is used as default value if the option argument is omitted.\n\n\tThe meaning of columns are as follows:\n\n\tLETTER\n\t\tOne-letter flag. '``-``' means the field does not have one-letter flag.\n\n\tNAME\n\t\tLong-name of field.\n\n\tENABLED\n\t\tWhether the field is enabled or not. It takes ``yes`` or ``no``.\n\n\tLANGUAGE\n\t\tThe name of language if the field is owned by a parser.\n\t\t``NONE`` means that the field is a language-independent field which is\n\t\tcommon in all languages.\n\n\tJSTYPE\n\t\tJSON type used in printing the value of field when ``--output-format=json``\n\t\tis specified. See ctags-client-tools(7).\n\n\tFIXED\n\t\tWhether this field can be disabled or not in tags output.\n\n\t\tSome fields are printed always in tags output.\n\t\tThey have ``yes`` as the value for this column.\n\n\t\tUnlike the tag output mode, JSON output mode allows disabling\n\t\tany fields.\n\n\tOP\n\t\tHow this field can be accessed from optscript code.\n\t\tThis field is for Universal Ctags developers.\n\n\tVER\n\t\tThe ctags output version introducing the field for a language-independent\n\t\tfield, or the parser version introducing the field for a\n\t\tlanguage-specified field. See the ``--version`` option and\n\t\t``TAG_OUTPUT_VERSION`` in ctags-client-tools(7) about the ctags output\n\t\tversion.\n\n\t\t(since version 6.3.0)\n\n\tDESCRIPTION\n\t\tHuman readable description for the field.\n\n``--list-kinds[=(<language>|all)]``\n\tSubset of ``--list-kinds-full``. This option is kept for\n\tbackward-compatibility with Exuberant Ctags.\n\n\tThis option prints only LETTER, DESCRIPTION, and ENABLED fields\n\tof ``--list-kinds-full`` output. However, the presentation of\n\tENABLED column is different from that of ``--list-kinds-full``\n\toption; ``[off]`` follows after description if the kind is disabled,\n\tand nothing follows\tif enabled. The most of all kinds are enabled\n\tby default.\n\n\tThe critical weakness of this option is that this option does not\n\tprint the name of kind. Universal Ctags introduces\n\t``--list-kinds-full`` because it considers that names are\n\timportant.\n\n\tThis option does not work with ``--machinable`` nor\n\t``--with-list-header``.\n\n``--list-kinds-full[=(<language>|all)]``\n\tLists the tag kinds recognized for either the specified *<language>*\n\tor ``all`` languages, and then exits. See \"`Kinds`_\" subsection to\n\tlearn what kinds are.\n\t``all`` is used as default value if the option argument is omitted.\n\n\tEach kind of tag recorded in the tag file is represented by a\n\tone-letter flag, or a long-name flag. They are also used to filter the tags\n\tplaced into the output through use of the ``--kinds-<LANG>``\n\toption.\n\n\tThe meaning of columns are as follows:\n\n\tLANGUAGE\n\t\tThe name of language having the kind.\n\n\tLETTER\n\t\tOne-letter flag. This must be unique in a language.\n\n\tNAME\n\t\tThe long-name flag of the kind. This can be used as the alternative\n\t\tto the one-letter flag described above. If enabling ``K`` field with\n\t\t``--fields=+K``, @CTAGS_NAME_EXECUTABLE@ uses long-names instead of\n\t\tone-letters in tags output. To enable/disable a kind with\n\t\t``--kinds-<LANG>`` option, long-name surrounded by braces instead\n\t\tof one-letter. See \"`Letters and names`_\" for details. This must be\n\t\tunique in a language.\n\n\tENABLED\n\t\tWhether the kind is enabled or not. It takes ``yes`` or ``no``.\n\n\tREFONLY\n\t\tWhether the kind is specialized for reference tagging or not.\n\t\tIf the column is ``yes``, the kind is for reference tagging, and\n\t\tit is never used for definition tagging. See also \"`TAG ENTRIES`_\".\n\n\tNROLES\n\t\tThe number of roles this kind has. See also \"`Roles`_\".\n\n\tMASTER\n\t\tThe master parser controlling enablement of the kind.\n\t\tA kind belongs to a language (owner) in Universal Ctags;\n\t\tenabling and disabling a kind in a language has no effect on\n\t\ta kind in another language even if both kinds has the\n\t\tsame one-letter flag and/or the same long-name flag. In other words,\n\t\tthe namespace of kinds are separated by language.\n\n\t\tHowever, Exuberant Ctags does not separate the kinds of C and\n\t\tC++. Enabling/disabling kindX in C language enables/disables a\n\t\tkind in C++ language having the same long-name flag with kindX. To\n\t\temulate this behavior in Universal Ctags, a concept named\n\t\t*master parser* is introduced. Enabling/disabling some kinds\n\t\tare synchronized under the control of a master language.\n\n\t\t.. code-block:: console\n\n\t\t\t$ ctags --kinds-C=+'{local}' --list-kinds-full \\\n\t\t\t  | grep -E '^(#|C\\+\\+ .* local)'\n\t\t\t#LANGUAGE  LETTER NAME   ENABLED REFONLY NROLES MASTER DESCRIPTION\n\t\t\tC++        l      local  yes     no      0      C      local variables\n\t\t\t$ ctags --kinds-C=-'{local}' --list-kinds-full \\\n\t\t\t  | grep -E '^(#|C\\+\\+ .* local)'\n\t\t\t#LANGUAGE  LETTER NAME   ENABLED REFONLY NROLES MASTER DESCRIPTION\n\t\t\tC++        l      local  no      no      0      C      local variables\n\n\t\tYou see ``ENABLED`` field of ``local`` kind of C++ language is changed\n\t\tThough ``local`` kind of C language is enabled/disabled. If you swap the languages, you\n\t\tsee the same result.\n\n\t\t.. TODO: need a reference to \"master parser\"\n\n\tVER\n\t\tThe parser version introducing the kind.\n\n\t\t(since version 6.3.0)\n\n\tDESCRIPTION\n\t\tHuman readable description for the kind.\n\n``--list-languages``\n\tLists the names of the languages understood by @CTAGS_NAME_EXECUTABLE@,\n\tand then exits. These language names are case insensitive and may be\n\tused in many other options like ``--language-force``,\n\t``--languages``, ``--kinds-<LANG>``, ``--regex-<LANG>``, and so on.\n\n\tEach language listed is disabled if followed by ``[disabled]``.\n\tTo use the parser for such a language, specify the language as an\n\targument of ``--languages=+`` option.\n\n\t``--machinable`` and ``--with-list-header`` options are ignored if they are\n\tspecified with this option.\n\n``--list-map-extensions[=(<language>|all)]``\n\tLists the file extensions which associate a file\n\tname with a language for either the specified *<language>* or ``all``\n\tlanguages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n``--list-map-patterns[=(<language>|all)]``\n\tLists the file name patterns which associate a file\n\tname with a language for either the specified *<language>* or ``all``\n\tlanguages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n``--list-map-rexprs[=(<language>|all)]``\n\tLists the relative-path regular expressions which associate a file\n\tname with a language for either the specified *<language>* or ``all``\n\tlanguages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n\t(since version 6.3.0)\n\n``--list-maps[=(<language>|all)]``\n\tLists the file name patterns, the file extensions, and the relative-path\n\tregular expressions which associate a file name with a language for either\n\tthe specified *<language>* or ``all`` languages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n\tTo list the file extensions, file name patterns, or relative-path regular\n\texpressions individually, use ``--list-map-extensions``,\n\t``--list-map-patterns``, or ``--list-map-rexprs`` option.\n\n\tSee the ``--langmap`` option, and \"`Determining file language`_\", above.\n\n\tThis option does not work with ``--machinable`` nor\n\t``--with-list-header``.\n\n``--list-mline-regex-flags``\n\tOutput list of flags which can be used in a multiline regex parser\n\tdefinition.\n\tSee ctags-optlib(7).\n\n``--list-output-formats``\n\tLists the output formats that can be used in ``--output-format`` option.\n\n\t``NULLTAG`` column represetns whether the format supports *null tags* or\n\tnot. See ``nulltag``/``z`` in \"`Extras`_\" about the null tags.\n\n\t(since version 6.2.0)\n\n``--list-params[=(<language>|all)]``\n\tLists the parameters for either the specified *<language>* or ``all``\n\tlanguages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n``--list-pseudo-tags``\n\tOutput list of pseudo-tags.\n\n``--list-regex-flags``\n\tLists the flags that can be used in ``--regex-<LANG>`` option.\n\tSee ctags-optlib(7).\n\n``--list-roles[=(<language>|all)[.(<kind-specs>|*)]]``\n\tList the roles for either the specified *<language>* or ``all`` languages.\n\t``all`` is used as default value if the option argument is omitted.\n\n\tIf the parameter *<kindspecs>* is given after the parameter\n\t*<language>* or ``all`` with concatenating with '``.``', list only roles\n\tdefined in the kinds. Both one-letter flags and long name flags surrounded\n\tby braces are acceptable as the parameter *<kindspecs>*.\n\n\tThe meaning of columns are as follows:\n\n\tLANGUAGE\n\t\tThe name of language having the role.\n\n\tKIND(L/N)\n\t\tThe one-letter flag and the long-name flag of kind having the role.\n\n\tNAME\n\t\tThe long-name flag of the role.\n\n\tENABLED\n\t\tWhether the kind is enabled or not. It takes ``yes`` or ``no``.\n\n\tVER\n\t\tThe parser version introducing the role.\n\n\t\t(since version 6.3.0)\n\n\tDESCRIPTION\n\t\tHuman readable description for the role.\n\n``--list-subparsers[=(<baselang>|all)]``\n\tLists the subparsers for a base language for either the specified\n\t*<baselang>* or ``all`` languages, and then exits.\n\t``all`` is used as default value if the option argument is omitted.\n\n``--machinable[=(yes|no)]``\n\tUse tab character as separators for ``--list-`` option output.  It\n\tmay be suitable for scripting. See \"`List options`_\" for considered\n\tuse cases. Disabled by default.\n\n``--with-list-header[=(yes|no)]``\n\tPrint headers describing columns in ``--list-`` option output.\n\tSee also \"`List options`_\".\n\n.. _option_misc:\n\nMiscellaneous Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``--describe-language=<language>``\n\tPrints the various aspects of the parser implementing the language.\n\n\t(since version 6.3.0)\n\n``--help``\n\tPrints to standard output a detailed usage description, and then exits.\n\n``-?``\n\tEquivalent to ``--help``.\n\n``--help-full``\n\tPrints to standard output a detailed usage description including experimental\n\tfeatures, and then exits. Visit https://docs.ctags.io/ for information\n\tabout the latest exciting experimental features.\n\n``--license``\n\tPrints a summary of the software license to standard output, and then exits.\n\n``--print-language``\n\tJust prints the language parsers for specified source files, and then exits.\n\n``--quiet[=(yes|no)]``\n\tWrite fewer messages (default is ``no``).\n\n``--totals[=(yes|no|extra)]``\n\tPrints statistics about the source files read and the tag file written\n\tduring the current invocation of @CTAGS_NAME_EXECUTABLE@. This option\n\tis ``no`` by default.\n\n\tThe ``extra`` value prints parser specific statistics for parsers\n\tgathering such information.\n\n``--verbose[=(yes|no)]``\n\tEnable verbose mode. This prints out information on option processing\n\tand a brief message describing what action is being taken for each file\n\tconsidered by @CTAGS_NAME_EXECUTABLE@. Normally, @CTAGS_NAME_EXECUTABLE@\n\tdoes not read command line arguments until after options are read\n\tfrom the configuration files (see \"`FILES`_\", below).\n\tHowever, if this option is the first argument on\n\tthe command line, it will take effect before any options are read from\n\tthese sources. The default is ``no``.\n\n``-V``\n\tEquivalent to ``--verbose``.\n\n``--version[=<language>|NONE]``\n\tPrints a version identifier for @CTAGS_NAME_EXECUTABLE@ to standard\n\toutput, and then exits. This is guaranteed to always contain the string\n\t\"Universal Ctags\". See also the description for ``TAG_PROGRAM_VERSION``\n\tand ``TAG_OUTPUT_VERSION`` in ctags-client-tools(7).\n\n\tIf ``NONE`` is given, prints the version identifier in a simplified way.\n\n\tIf *<language>* is given, print the version identifier for the parser\n\tfor *<language>*. See also the description for ``TAG_PARSER_VERSION`` in\n\tctags-client-tools(7).\n\nObsoleted Options\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThese options are kept for backward-compatibility with Exuberant Ctags.\n\n``-w``\n\tThis option is silently ignored for backward-compatibility with the\n\tctags of SVR4 Unix.\n\n``--file-scope[=(yes|no)]``\n\tThis options is removed. Use ``--extras=[+|-]F`` or\n\t``--extras=[+|-]{fileScope}`` instead.\n\n``--extra=[+|-][<flags>|*]``\n\tEquivalent to ``--extras=[+|-][<flags>|*]``, which was introduced to make\n\tthe option naming convention align to the other options like\n\t``--kinds-<LANG>=`` and ``--fields=``.\n\n``--<LANG>-kinds=[+|-](<kinds>|*)``\n\tThis option is obsolete. Use ``--kinds-<LANG>=...`` instead.\n\nOPERATIONAL DETAILS\n-------------------\nAs @CTAGS_NAME_EXECUTABLE@ considers each source file name in turn, it tries to\ndetermine the language of the file by applying tests described in\n\"`Determining file language`_\".\n\nIf a language was identified, the file is opened and then the appropriate\nlanguage parser is called to operate on the currently open file. The parser\nparses through the file and adds an entry to the tag file for each\nlanguage object it is written to handle. See \"`TAG FILE FORMAT`_\", below,\nfor details on these entries.\n\nNotes for C/C++ Parser\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. TODO: move the following description to parser-cxx.rst.\n\nThis implementation of @CTAGS_NAME_EXECUTABLE@ imposes no formatting\nrequirements on C code as do legacy implementations. Older implementations\nof ctags tended to rely upon certain formatting assumptions in order to\nhelp it resolve coding dilemmas caused by preprocessor conditionals.\n\nIn general, @CTAGS_NAME_EXECUTABLE@ tries to be smart about conditional\npreprocessor directives. If a preprocessor conditional is encountered\nwithin a statement which defines a tag, @CTAGS_NAME_EXECUTABLE@ follows\nonly the first branch of that conditional (except in the special case of\n``#if 0``, in which case it follows only the last branch). The reason for\nthis is that failing to pursue only one branch can result in ambiguous\nsyntax, as in the following example:\n\n.. code-block:: C\n\n\t#ifdef TWO_ALTERNATIVES\n\tstruct {\n\t#else\n\tunion {\n\t#endif\n\t\tshort a;\n\t\tlong b;\n\t}\n\nBoth branches cannot be followed, or braces become unbalanced and\n@CTAGS_NAME_EXECUTABLE@ would be unable to make sense of the syntax.\n\nIf the application of this heuristic fails to properly parse a file,\ngenerally due to complicated and inconsistent pairing within the\nconditionals, @CTAGS_NAME_EXECUTABLE@ will retry the file using a\ndifferent heuristic which does not selectively follow conditional\npreprocessor branches, but instead falls back to relying upon a closing\nbrace ('``}``') in column 1 as indicating the end of a block once any brace\nimbalance results from following a ``#if`` conditional branch.\n\n@CTAGS_NAME_EXECUTABLE@ will also try to specially handle arguments lists\nenclosed in double sets of parentheses in order to accept the following\nconditional construct::\n\n\textern void foo __ARGS((int one, char two));\n\nAny name immediately preceding the '``((``' will be automatically ignored and\nthe previous name will be used.\n\nC++ operator definitions are specially handled. In order for consistency\nwith all types of operators (overloaded and conversion), the operator\nname in the tag file will always be preceded by the string \"operator \"\n(i.e. even if the actual operator definition was written as \"operator<<\").\n\nAfter creating or appending to the tag file, it is sorted by the tag name,\nremoving identical tag lines.\n\n.. _guessing:\n\nDetermining file language\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFile name mapping\n..........................\n\nUnless the ``--language-force`` option is specified, the language of each source\nfile is automatically selected based upon a *mapping* of file names to\nlanguages. The mappings in effect for each language may be displayed using\nthe ``--list-maps`` option and may be changed using the ``--langmap`` or\n``--map-<LANG>`` options.\n\nIf the name of a file is not mapped to a language, @CTAGS_NAME_EXECUTABLE@ tries\nto heuristically guess the language for the file by inspecting its content.\n\nAll files that have no file name mapping and no guessed parser are\nignored. This permits running @CTAGS_NAME_EXECUTABLE@ on all files in\neither a single directory (e.g.  \"``@CTAGS_NAME_EXECUTABLE@ *``\"), or on\nall files in an entire source directory tree\n(e.g. \"``@CTAGS_NAME_EXECUTABLE@ -R``\"), since only those files whose\nnames are mapped to languages will be scanned.\n\nAn extension may be mapped to multiple parsers. For example, ``.h``\nare mapped to C++, C and ObjectiveC. These mappings can cause\nissues. @CTAGS_NAME_EXECUTABLE@ tries to select the proper parser\nfor the source file by applying heuristics to its content, however\nit is not perfect.  In case of issues one can use ``--language-force=<language>``,\n``--langmap=<map>[,<map>[...]]``, or the ``--map-<LANG>=[+|-]<extension>|<pattern>|<rexpr>``\noptions. (Some of the heuristics are applied whether ``--guess-language-eagerly``\nis given or not.)\n\nThe order of testing is relative-path regular expressions (specified with\n``--map-<LANG>=<rexpr>``), file name patterns, then file extensions.\n\n.. TODO: all heuristics??? To be confirmed.\n\nHeuristically guessing\n..........................\n\nIf @CTAGS_NAME_EXECUTABLE@ cannot select a parser from the mapping of file names,\nvarious heuristic tests are conducted to determine the language:\n\ntemplate file name testing\n\tIf the file name has an ``.in`` extension, @CTAGS_NAME_EXECUTABLE@ applies\n\tthe mapping to the file name without the extension. For example,\n\t``config.h`` is tested for a file named ``config.h.in``.\n\n\"interpreter\" testing\n\tThe first line of the file is checked to see if the file is a ``#!``\n\tscript for a recognized language. @CTAGS_NAME_EXECUTABLE@ looks for\n\ta parser having the same name.\n\n\tIf @CTAGS_NAME_EXECUTABLE@ finds no such parser,\n\t@CTAGS_NAME_EXECUTABLE@ looks for the name in alias lists. For\n\texample, consider if the first line is ``#!/bin/sh``.  Though\n\t@CTAGS_NAME_EXECUTABLE@ has a \"shell\" parser, it doesn't have a \"sh\"\n\tparser. However, ``sh`` is listed as an alias for ``shell``, therefore\n\t@CTAGS_NAME_EXECUTABLE@ selects the \"shell\" parser for the file.\n\n\tAn exception is ``env``. If ``env`` is specified (for example\n\t\"``#!/usr/bin/env python``\"), @CTAGS_NAME_EXECUTABLE@\n\treads more lines to find real interpreter specification.\n\n\tTo display the list of aliases, use ``--list-aliases`` option.\n\tTo add an item to the list or to remove an item from the list, use the\n\t``--alias-<LANG>=+<pattern>`` or ``--alias-<LANG>=-<pattern>`` option\n\trespectively.\n\n\"zsh autoload tag\" testing\n\tIf the first line starts with ``#compdef`` or ``#autoload``,\n\t@CTAGS_NAME_EXECUTABLE@ regards the line as \"zsh\".\n\n\"emacs mode at the first line\" testing\n\tThe Emacs editor has multiple editing modes specialized for programming\n\tlanguages. Emacs can recognize a marker called modeline in a file\n\tand utilize the marker for the mode selection. This heuristic test does\n\tthe same as what Emacs does.\n\n\t@CTAGS_NAME_EXECUTABLE@ treats ``MODE`` as a name of interpreter and applies the same\n\trule of \"interpreter\" testing if the first line has one of\n\tthe following patterns::\n\n\t\t-*- mode: MODE -*-\n\n\tor\n\n\t::\n\n\t\t-*- MODE -*-\n\n\"emacs mode at the EOF\" testing\n\tEmacs editor recognizes another marker at the end of file as a\n\tmode specifier. This heuristic test does the same as what Emacs does.\n\n\t@CTAGS_NAME_EXECUTABLE@ treats ``MODE`` as a name of an interpreter and applies the same\n\trule of \"interpreter\" heuristic testing, if the lines at the tail of the file\n\thave the following pattern::\n\n\t\tLocal Variables:\n\t\t...\n\t\tmode: MODE\n\t\t...\n\t\tEnd:\n\n\t3000 characters are sought from the end of file to find the pattern.\n\n\"vim modeline\" testing\n\tLike the modeline of the Emacs editor, Vim editor has the same concept.\n\t@CTAGS_NAME_EXECUTABLE@ treats ``TYPE`` as a name of interpreter and applies the same\n\trule of \"interpreter\" heuristic testing if the first or last 5 lines of the file\n\thave one of the following patterns::\n\n\t\tfiletype=TYPE\n\n\tor\n\n\t::\n\n\t\tft=TYPE\n\n\"PHP marker\" testing\n\tIf the first line is started with ``<?php``,\n\t@CTAGS_NAME_EXECUTABLE@ regards the line as \"php\".\n\nLooking into the file contents is a more expensive operation than file\nname matching. So @CTAGS_NAME_EXECUTABLE@ runs the testings in limited\nconditions.  \"interpreter\" testing is enabled only when a file is an\nexecutable or the ``--guess-language-eagerly`` (``-G`` in short) option is\ngiven. The other heuristic tests are enabled only when ``-G`` option is\ngiven.\n\nThe ``--print-language`` option can be used just to print the results of\nparser selections for given files instead of generating a tags file.\n\nExamples:\n\n.. code-block:: console\n\n\t$ @CTAGS_NAME_EXECUTABLE@ --print-language config.h.in input.m input.unknown\n\tconfig.h.in: C++\n\tinput.m: MatLab\n\tinput.unknown: NONE\n\n``NONE`` means that @CTAGS_NAME_EXECUTABLE@ does not select any parser for the file.\n\nTAG FILE FORMAT\n---------------\n\nThis section describes the tag file format briefly.  See tags(5) and\nctags-client-tools(7) for more details.\n\nWhen not running in etags mode, each entry in the tag file consists of a\nseparate line, each looking like this, called *regular tags*, in the most general case:\n\n::\n\n\t<tag_name><TAB><file_name><TAB><ex_cmd>;\"<TAB><extension_fields>\n\nThe fields and separators of these lines are specified as follows:\n\n\t1.\t``<tag_name>``: tag name\n\t2.\t``<TAB>``: single tab character\n\t3.\t``<file_name>``: name of the file in which the object associated with the tag is located\n\t4.\t``<TAB>``: single tab character\n\t5.\t``<ex_cmd>``: EX command used to locate the tag within the file; generally a\n\t\tsearch pattern (either ``/pattern/`` or ``?pattern?``) or line number (see\n\t\t``--excmd=<type>`` option).\n\t6.\t``;\"<TAB><extension_fields>``: a set of extension fields. See\n\t\t\"`Extension fields`_\" for more details.\n\n\t\tTag file format 2 (see ``--format``) extends the EX command\n\t\tto include the extension fields embedded in an EX comment immediately appended\n\t\tto the EX command, which leaves it backward-compatible with original\n\t\t``vi(1)`` implementations.\n\nA few special tags, called *pseudo tags*, are written into the tag file for internal purposes.\n\n::\n\n\t!_TAG_FILE_FORMAT       2       /extended format; --format=1 will not append ;\" to lines/\n\t!_TAG_FILE_SORTED       1       /0=unsorted, 1=sorted, 2=foldcase/\n\t...\n\n``--pseudo-tags=[+|-](<pseudo-tag>|*)`` option enables or disables emitting pseudo-tags.\n\nSee the output of \"``@CTAGS_NAME_EXECUTABLE@ --list-pseudo-tags``\" for the list of\nthe kinds.\nSee also tags(5) and ctags-client-tools(7) for more details of the pseudo tags.\n\nThese tags are composed in such a way that they always sort to the top of\nthe file. Therefore, the first two characters of these tags are used a magic\nnumber to detect a tag file for purposes of determining whether a\nvalid tag file is being overwritten rather than a source file.\n\nNote that the name of each source file will be recorded in the tag file\nexactly as it appears on the command line. Therefore, if the path you\nspecified on the command line was relative to the current directory, then\nit will be recorded in that same manner in the tag file. See, however,\nthe ``--tag-relative=(yes|no|always|never)`` option for how this behavior can be\nmodified.\n\n.. _tag_entries:\n\nTAG ENTRIES\n-----------\n\nA tag is an index for a language object. The concept of a tag and related\nitems in Exuberant Ctags are refined and extended in Universal Ctags.\n\nA tag is categorized into *definition tags* or *reference tags*.\nIn general, Exuberant Ctags only tags *definitions* of\nlanguage objects: places where newly named language objects *are introduced*.\nUniversal Ctags, on the other hand, can also tag *references* of language\nobjects: places where named language objects *are used*. However, support\nfor generating reference tags is new and limited to specific areas of\nspecific languages in the current version.\n\nExtension fields\n~~~~~~~~~~~~~~~~\n\nA tag can record various information, called *extension fields*.\n\nExtension fields are tab-separated key-value pairs appended to the end of\nthe EX command as a comment, as described above. These key value pairs\nappear in the general form ``key:value``.\n\nIn addition, information on the scope of the tag definition may be\navailable, with the key portion equal to some language-dependent construct\nname and its value the name declared for that construct in the program.\nThis scope entry indicates the scope in which the tag was found.\nFor example, a tag generated for a C structure member would have a scope\nlooking like ``struct:myStruct``.\n\n``--fields=[+|-][<flags>|*]`` and ``--fields-(<LANG>|all)=[+|-][<flags>|*]`` options specifies\nwhich available extension fields are to be included in the tag entries.\n\nSee the output of \"``@CTAGS_NAME_EXECUTABLE@ --list-fields``\" for the list of\nextension fields.\nThe essential fields are ``name``, ``input``, ``pattern``, and ``line``.\nThe meaning of major fields is as follows (long-name flag/one-letter flag):\n\n``access``/``a``\n\tIndicates the visibility of this class member, where value is specific\n\tto the language.\n\n``end``/``e``\n\tIndicates the line number of the end lines of the language object.\n\n``extras``/``E``\n\tExtra tag type information. See \"`Extras`_\" for details.\n\n``file``/``f``\n\tIndicates that the tag has file-limited visibility. This key has no\n\tcorresponding value. Enabled by default.\n\n``implementation``/``m``\n\tWhen present, this indicates a limited implementation (abstract vs.\n\tconcrete) of a routine or class, where value is specific to the\n\tlanguage (``virtual`` or ``pure virtual`` for C++; ``abstract`` for Java).\n\n``inherits``/``i``\n\tWhen present, value is a comma-separated list of classes from which\n\tthis class is derived (i.e. inherits from).\n\n``input``/``F``\n\tThe name of source file where ``name`` is defined or referenced.\n\n``k``\n\t`Kind <Kinds>`_ of tag as one-letter. Enabled by default.\n\tThis field has no long-name.\n\tSee also ``kind``/``z`` flag.\n\n``K``\n\t`Kind <Kinds>`_ of tag as long-name.\n\tThis field has no long-name.\n\tSee also ``kind``/``z`` flag.\n\n``kind``/``z``\n\tInclude the ``kind:`` key in `kind field <Kinds>`_.  See also ``k`` and ``K`` flags.\n\n``language``/``l``\n\tLanguage of source file containing tag\n\n``line``/``n``\n\tThe line number where ``name`` is defined or referenced in ``input``.\n\n``name``/``N``\n\tThe name of language objects.\n\n``nth``/``o``\n\tThe order in the parent scope.\n\t(i.e. 4th parameter in the function).\n\n``pattern``/``P``\n\tCan be used to search the ``name`` in ``input``\n\n``roles``/``r``\n\tRoles assigned to the tag. See \"`Roles`_\" for more details.\n\n``s``\n\tScope of tag definition. Enabled by default.\n\tThis field has no long-name.\n\tSee also ``scope``/``Z`` flag.\n\n``scope``/``Z``\n\tPrepend the ``scope:`` key to scope (``s``) field.\n\tSee also ``s`` flag.\n\n``scopeKind``/``p``\n\tKind of scope as long-name\n\n``signature``/``S``\n\tWhen present, value is a language-dependent representation of the\n\tsignature of a routine (e.g. prototype or parameter list). A routine signature in its complete form\n\tspecifies the return type of a routine and its formal argument list.\n\tThis extension field is presently supported only for C-based\n\tlanguages and does not include the return type.\n\n``typeref``/``t``\n\tType and name of a variable, typedef, or return type of\n\tcallable like function as ``typeref:`` field.\n\tEnabled by default.\n\nKinds\n......\n\n``kind`` is a field which represents the *kind* of language object\nspecified by a tag. Kinds used and defined are very different between\nparsers. For example, C language defines ``macro``, ``function``,\n``variable``, ``typedef``, etc.\n\n``--kinds-(<LANG>|all)=[+|-](<kinds>|*)`` option specifies a list of language-specific\nkinds of tags (or kinds) to include in the output file for a particular\nlanguage.\n\nSee the output of \"``@CTAGS_NAME_EXECUTABLE@ --list-kinds-full``\" for the complete\nlist of the kinds.\n\nIts value is either one of the\ncorresponding one-letter flags or a long-name flag. It is permitted\n(and is, in fact, the default) for the key portion of this field to be\nomitted. The optional behaviors are controlled with the ``--fields`` option as follows.\n\n.. code-block:: console\n\n\t$ ctags -o - kinds.c\n\tfoo     kinds.c /^int foo() {$/;\"       f       typeref:typename:int\n\t$ ctags --fields=+k -o - kinds.c\n\tfoo     kinds.c /^int foo() {$/;\"       f       typeref:typename:int\n\t$ ctags --fields=+K -o - kinds.c\n\tfoo     kinds.c /^int foo() {$/;\"       function        typeref:typename:int\n\t$ ctags --fields=+z -o - kinds.c\n\tfoo     kinds.c /^int foo() {$/;\"       kind:f  typeref:typename:int\n\t$ ctags --fields=+zK -o - kinds.c\n\tfoo     kinds.c /^int foo() {$/;\"       kind:function   typeref:typename:int\n\nRoles\n......\n\n*Role* is a newly introduced concept in Universal Ctags. Role is a\nconcept associated with reference tags, and is not implemented widely yet.\n\nAs described previously in \"`Kinds`_\", the ``kind`` field represents the type\nof language object specified with a tag, such as a function vs. a variable.\nSpecific kinds are defined for reference tags, such as the C++ kind ``header`` for\nheader file, or Java kind ``package`` for package statements. For such reference\nkinds, a ``roles`` field can be added to distinguish the role of the reference\nkind. In other words, the ``kind`` field identifies the *what* of the language\nobject, whereas the ``roles`` field identifies the *how* of a referenced language\nobject. Roles are only used with specific kinds.\n\nFor a definition tag, this field takes ``def`` as a value.\n\nFor example, ``Baz`` is tagged as a reference tag with kind ``package`` and with\nrole ``imported`` with the following code.\n\n.. code-block:: java\n\n\tpackage Bar;\n\timport Baz;\n\n\tclass Foo {\n\t\t\t// ...\n\t}\n\n.. code-block:: console\n\n\t$ ctags --fields=+KEr -uo - roles.java\n\tBar     roles.java     /^package Bar;$/;\"      package roles:def\n\tFoo     roles.java     /^class Foo {$/;\"       class   roles:def\n\t$ ctags --fields=+EKr --extras=+r -uo - roles.java\n\tBar     roles.java     /^package Bar;$/;\"      package roles:def\n\tBaz     roles.java     /^import Baz;$/;\"       package roles:imported  extras:reference\n\tFoo     roles.java     /^class Foo {$/;\"       class   roles:def\n\n``--roles-(<LANG>|all).(<kind>|all)=[+|-][<roles>|*]`` option specifies a list of kind-specific\nroles of tags to include in the output file for a particular language.\n\nInquire the output of \"``@CTAGS_NAME_EXECUTABLE@ --list-roles``\" for the list of\nroles.\n\n.. _extras:\n\nExtras\n~~~~~~\n\nGenerally, @CTAGS_NAME_EXECUTABLE@ tags only language objects appearing\nin source files, as is. In other words, a value for a ``name:`` field\nshould be found on the source file associated with the ``name:``. An\n``extra`` type tag (*extra*) is for tagging a language object with a processed\nname, or for tagging something not associated with a language object. A typical\nextra tag is ``qualified``, which tags a language object with a\nclass-qualified or scope-qualified name.\n\n``--extras-(<LANG>|all)=[+|-][<flags>|*]`` option specifies\nwhether to include extra tag entries for certain kinds of information.\n\nInquire the output of ``@CTAGS_NAME_EXECUTABLE@ --list-extras`` for the list of extras.\nThe meaning of major extras is as follows (long-name flag/one-letter flag):\n\n``anonymous``/none\n\tInclude an entry for the language object that has no name like lambda\n\tfunction. This extra has no one-letter flag and is enabled by\n\tdefault.\n\n\tThe extra tag is useful as a placeholder to fill scope fields\n\tfor language objects defined in a language object with no name.\n\n\t.. code-block:: C\n\n\t\tstruct {\n\t\t\tdouble x, y;\n\t\t} p = { .x = 0.0, .y = 0.0 };\n\n\t'``x``' and '``y``' are the members of a structure. When filling the scope\n\tfields for them, @CTAGS_NAME_EXECUTABLE@ has trouble because the struct\n\twhere '``x``' and '``y``' belong to has no name. For overcoming the trouble,\n\t@CTAGS_NAME_EXECUTABLE@ generates an anonymous extra tag for the struct\n\tand fills the scope fields with the name of the extra tag.\n\n\t.. code-block:: console\n\n\t\t$ ctags --fields=-f -uo - input.c\n\t\t__anon9f26d2460108\tinput.c\t/^struct {$/;\"\ts\n\t\tx\tinput.c\t/^\tdouble x, y;$/;\"\tm\tstruct:__anon9f26d2460108\n\t\ty\tinput.c\t/^\tdouble x, y;$/;\"\tm\tstruct:__anon9f26d2460108\n\t\tp\tinput.c\t/^} p = { .x = 0.0, .y = 0.0 };$/;\"\tv\ttyperef:struct:__anon9f26d2460108\n\n\tThe above tag output has ``__anon9f26d2460108`` as an anonymous extra tag.\n\tThe typeref field of '``p``' also receives the benefit of it.\n\n``fileScope``/``F``\n\tIndicates whether tags scoped only for a single file (i.e. tags which\n\tcannot be seen outside of the file in which they are defined, such as\n\tlanguage objects with ``static`` modifier of C language) should be included\n\tin the output. See also the ``-h`` option.\n\n\tThis extra tag is enabled by default. Add ``--extras=-F`` option not to\n\toutput tags scoped only for a single-file. This is the replacement for\n\t``--file-scope`` option of Exuberant Ctags.\n\n\t.. code-block:: c\n\n\t\tstatic int f() {\n\t\t\treturn 0;\n\t\t}\n\t\tint g() {\n\t\t\treturn 0;\n\t\t}\n\n\t.. code-block:: console\n\n\t\t$ ctags -uo - filescope.c\n\t\tf       filescope.c     /^static int f() {$/;\"  f       typeref:typename:int    file:\n\t\tg       filescope.c     /^int g() {$/;\" f       typeref:typename:int\n\t\t$ ctags --extras=-F -uo - filescope.c\n\t\tg       filescope.c     /^int g() {$/;\" f       typeref:typename:int\n\n``inputFile``/``f``\n\tInclude an entry for the base file name of every source file\n\t(e.g. ``example.c``), which addresses the first line of the file.\n\tThis flag is the replacement for ``--file-tags`` hidden option of\n\tExuberant Ctags.\n\n\tIf the ``end:`` field is enabled, the end line number of the file can be\n\tattached to the tag. (However, @CTAGS_NAME_EXECUTABLE@ omits the ``end:`` field\n\tif no newline is in the file like an empty file.)\n\n\tBy default, @CTAGS_NAME_EXECUTABLE@ doesn't create the ``inputFile``/``f`` extra\n\ttag for the source file when @CTAGS_NAME_EXECUTABLE@ doesn't find a parser\n\tfor it. Enabling ``Unknown`` parser with ``--languages=+Unknown`` forces\n\t@CTAGS_NAME_EXECUTABLE@ to create the extra tags for any source files.\n\n\tThe etags mode enables the ``Unknown`` parser implicitly.\n\n``nulltag``/``z``\n\tInclude tags (*null tags*) having empty strings as their names.\n\tGenerally speaking, trying to make a null tag is a sign of a parser bug\n\tor broken input. @CTAGS_NAME_EXECUTABLE@ warns such trying or throws the\n\tnull tag away. To suppress the warnings, use ``--quiet`` option.\n\n\tOn the other hand, null tags are valid in some languages.\n\tConsider ``{\"\":  val}`` in a JavaScript sourece code. The empty string is\n\tvalid as a key. If a parser intentionally makes a null tag (a valid null tag),\n\t@CTAGS_NAME_EXECUTABLE@ doesn't warn but discard it by default.\n\n\tThe discards are due because some output formats may not consider null tags.\n\n\tWith ``nulltag``/``z`` extra, you can force ctags to emit the nulltags. This extra\n\tis effective only if the output format supports null tags. ``--list-output-formats``\n\toption tells you which output formats support null tags.\n\n\t(since version 6.2.0)\n\n``pseudo``/``p``\n\tInclude pseudo-tags. Enabled by default unless the tag file is\n\twritten to standard output. See ctags-client-tools(7) about\n\tthe detail of pseudo-tags.\n\n``qualified``/``q``\n\tInclude an extra class-qualified or namespace-qualified tag entry\n\tfor each tag which is a member of a class or a namespace.\n\n\tThis may allow easier location of a specific tags when\n\tmultiple occurrences of a tag name occur in the tag file.\n\tNote, however, that this could potentially more than double\n\tthe size of the tag file.\n\n\tThe actual form of the qualified tag depends upon the language\n\tfrom which the tag was derived (using a form that is most\n\tnatural for how qualified calls are specified in the\n\tlanguage). For C++ and Perl, it is in the form\n\t``class::member``; for Eiffel and Java, it is in the form\n\t``class.member``.\n\n\tNote: Using backslash characters as separators forming\n\tqualified name in PHP. However, in tags output of\n\tUniversal Ctags, a backslash character in a name is escaped\n\twith a backslash character. See tags(5) about the escaping.\n\n\tThe following example demonstrates the ``qualified`` extra tag.\n\n\t.. code-block:: Java\n\n\t\tclass point {\n\t\t\tdouble x;\n\t\t};\n\n\tFor the above source file, @CTAGS_NAME_EXECUTABLE@ tags ``point`` and ``x`` by\n\tdefault.  If the ``qualified`` extra is enabled from the command line\n\t(``--extras=+q``), then ``point.x`` is also tagged even though the string\n\t\"``point.x``\" is not in the source code.\n\n\t.. code-block:: console\n\n\t\t$ ctags --fields=+K -uo - qualified.java\n\t\tpoint   qualified.java  /^class point {$/;\"     class\n\t\tx       qualified.java  /^      double x;$/;\"   field   class:point\n\t\t$ ctags --fields=+K --extras=+q -uo - qualified.java\n\t\tpoint   qualified.java  /^class point {$/;\"     class\n\t\tx       qualified.java  /^      double x;$/;\"   field   class:point\n\t\tpoint.x qualified.java  /^      double x;$/;\"   field   class:point\n\n``reference``/``r``\n\tInclude reference tags. See \"`TAG ENTRIES`_\" about reference tags.\n\n\tThe following example demonstrates the ``reference`` extra tag.\n\n\t.. code-block:: c\n\n\t\t#include <stdio.h>\n\t\t#include \"utils.h\"\n\t\t#define X\n\t\t#undef X\n\n\tThe ``roles:system`` or ``roles:local`` fields will be\n\tadded depending on whether the include file name begins with '``<``' or not.\n\n\t\"``#define X``\" emits a definition tag. On the other hand \"``#undef X``\" emits a\n\treference tag.\n\n\t.. code-block:: console\n\n\t\t$ ctags --fields=+EKr -uo - inc.c\n\t\tX       inc.c   /^#define X$/;\" macro   file:   roles:def       extras:fileScope\n\t\t$ ctags --fields=+EKr --extras=+r -uo - inc.c\n\t\tstdio.h inc.c   /^#include <stdio.h>/;\" header  roles:system    extras:reference\n\t\tutils.h inc.c   /^#include \"utils.h\"/;\" header  roles:local     extras:reference\n\t\tX       inc.c   /^#define X$/;\" macro   file:   roles:def       extras:fileScope\n\t\tX       inc.c   /^#undef X$/;\"  macro   file:   roles:undef     extras:fileScope,reference\n\nLanguage-specific fields and extras\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nExuberant Ctags has the concept of *fields* and *extras*. They are common\nbetween parsers of different languages. Universal Ctags extends this concept\nby providing language-specific fields and extras.\n\n.. Note: kinds are language-specific since e-ctags. roles are new to u-ctags.\n\n.. TODO: move the following \"Hot to ...\" sections to FAQ man page when available\n\nHOW TO USE WITH VI\n------------------\n\n``vi(1)`` will, by default, expect a tag file by the name ``tags`` in the current\ndirectory. Once the tag file is built, the following commands exercise\nthe tag indexing feature:\n\n``vi -t tag``\n\tStart vi and position the cursor at the file and line where ``tag``\n\tis defined.\n\n``:ta tag``\n\tFind a tag.\n\n``Ctrl-]``\n\tFind the tag under the cursor.\n\n``Ctrl-T``\n\tReturn to previous location before jump to tag (not widely implemented).\n\n\nHOW TO USE WITH GNU EMACS\n-------------------------\n\n``emacs(1)`` will, by default, expect a tag file by the name ``TAGS`` in the\ncurrent directory. Once the tag file is built, the following commands\nexercise the tag indexing feature:\n\n``M-x visit-tags-table <RET> FILE <RET>``\n\tSelect the tag file, ``FILE``, to use.\n\n``M-. [TAG] <RET>``\n\tFind the first definition of TAG. The default tag is the identifier\n\tunder the cursor.\n\n``M-*``\n\tPop back to where you previously invoked ``M-.``.\n\n``C-u M-.``\n\tFind the next definition for the last tag.\n\nFor more commands, see the Tags topic in the Emacs info document.\n\n\nHOW TO USE WITH NEDIT\n---------------------\n\nNEdit version 5.1 and later can handle the new extended tag file format\n(see ``--format``).\n\n* To make NEdit use the tag file, select \"File->Load Tags File\".\n* To jump to the definition for a tag, highlight the word, then press ``Ctrl-D``.\n\nNEdit 5.1 can read multiple tag files from different\ndirectories. Setting the X resource ``nedit.tagFile`` to the name of a tag\nfile instructs NEdit to automatically load that tag file at startup time.\n\n\nCAVEATS\n-------\n\nBecause @CTAGS_NAME_EXECUTABLE@ is neither a preprocessor nor a compiler,\nuse of preprocessor macros can fool @CTAGS_NAME_EXECUTABLE@ into either\nmissing tags or improperly generating inappropriate tags. Although\n@CTAGS_NAME_EXECUTABLE@ has been designed to handle certain common cases,\nthis is the single biggest cause of reported problems. In particular,\nthe use of preprocessor constructs which alter the textual syntax of C\ncan fool @CTAGS_NAME_EXECUTABLE@. You can work around many such problems\nby using the ``-I`` option.\n\nNote that since @CTAGS_NAME_EXECUTABLE@ generates patterns for locating\ntags (see the ``--excmd`` option), it is entirely possible that the wrong line\nmay be found by your editor if there exists another source line which is\nidentical to the line containing the tag. The following example\ndemonstrates this condition:\n\n.. code-block:: C\n\n\tint variable;\n\n\t/* ... */\n\tvoid foo(variable)\n\tint variable;\n\t{\n\t\t/* ... */\n\t}\n\nDepending upon which editor you use and where in the code you happen to be,\nit is possible that the search pattern may locate the local parameter\ndeclaration before it finds the actual global variable definition,\nsince the lines (and therefore their search patterns) are\nidentical.\n\nThis can be avoided by use of the ``--excmd=n`` option.\n\nINCOMPATIBLE CHANGES\n--------------------\nSee ctags-incompatibilities(7) about incompatibilities between Universal\nCtags and Exuberant Ctags.\n\nThis section describes major incompatibilities within versions of Universal\nCtags.\n\nUnifying the kind Letter for ``unknown`` kinds\n\tSome parsers used different kind letters for ``unknown`` kinds.\n\tEmacsLisp used ``u``. Go used ``u``. Julian used ``x``. Lisp used ``u``.\n\tLua used ``X``. and Python used ``x``. They were unified to ``Y`` in\n\tthe during development of version 5.9.x.\n\nBUGS\n----\n\n@CTAGS_NAME_EXECUTABLE@ has more options than ``ls(1)``.\n\n@CTAGS_NAME_EXECUTABLE@ assumes the input file is written in the correct\ngrammar.  Otherwise output of ctags is undefined. In other words it has garbage\nin, garbage out (GIGO) feature.\n\n.. TODO: move the following paragraph to parser-cxx.rst.\n\nWhen parsing a C++ member function definition (e.g. ``className::function``),\n@CTAGS_NAME_EXECUTABLE@ cannot determine whether the scope specifier\nis a class name or a namespace specifier and always lists it as a class name\nin the scope portion of the extension fields. Also, if a C++ function\nis defined outside of the class declaration (the usual case), the access\nspecification (i.e. public, protected, or private) and implementation\ninformation (e.g. virtual, pure virtual) contained in the function\ndeclaration are not known when the tag is generated for the function\ndefinition. It will, however be available for prototypes (e.g. ``--kinds-c++=+p``).\n\nNo qualified tags are generated for language objects inherited into a class.\n\nENVIRONMENT VARIABLES\n---------------------\n``TMPDIR``\n\tOn Unix-like hosts where ``mkstemp(3)`` is available, the value of this\n\tvariable specifies the directory in which to place temporary files.\n\tThis can be useful if the size of a temporary file becomes too large\n\tto fit on the partition holding the default temporary directory\n\tdefined at compilation time.\n\n\t@CTAGS_NAME_EXECUTABLE@ creates temporary\n\tfiles only if either (1) an emacs-style tag file is being\n\tgenerated, (2) the tag file is being sent to standard output, or\n\t(3) the program was compiled to use an internal sort algorithm to sort\n\tthe tag files instead of the ``sort(1)`` utility of the operating system.\n\tIf the ``sort(1)`` utility of the operating system is being used, it will\n\tgenerally observe this variable also.\n\n\tNote that if @CTAGS_NAME_EXECUTABLE@\n\tis setuid, the value of ``TMPDIR`` will be ignored.\n\n\nFILES\n-----\n\nOutput files\n~~~~~~~~~~~~\n\n``tags``\n\tThe default tag file created by @CTAGS_NAME_EXECUTABLE@.\n\n``TAGS``\n\tThe default tag file created by @ETAGS_NAME_EXECUTABLE@.\n\nPreloading option files\n~~~~~~~~~~~~~~~~~~~~~~~\n\n``$XDG_CONFIG_HOME/ctags/*.ctags``, or ``$HOME/.config/ctags/*.ctags`` if\n``$XDG_CONFIG_HOME`` is not defined\n\n``$HOME/.ctags.d/*.ctags``\n\n``$HOMEDRIVE$HOMEPATH/ctags.d/*.ctags`` (on MS Windows only)\n\n``.ctags.d/*.ctags``\n\n``ctags.d/*.ctags``\n\n\tIf any of these configuration files exist, each will be expected to\n\tcontain a set of default options which are read in the order listed\n\twhen @CTAGS_NAME_EXECUTABLE@ starts, but before any command line options\n\tare read. This makes it possible to set up personal or project-level defaults.\n\n\tIt\n\tis possible to compile @CTAGS_NAME_EXECUTABLE@ to read an additional\n\tconfiguration file before any of those shown above, which will be\n\tindicated if the output produced by the ``--version`` option lists the\n\t``custom-conf`` feature.\n\n\tOptions appearing on the command line will override options\n\tspecified in these files. Only options will be read from these\n\tfiles.\n\n\tNote that the option\n\tfiles are read in line-oriented mode in which spaces are significant\n\t(since shell quoting is not possible) but spaces at the beginning\n\tof a line are ignored. Each line of the file is read as\n\tone command line parameter (as if it were quoted with single quotes).\n\tTherefore, use new lines to indicate separate command-line arguments.\n\n\tA line starting with '``#``' is treated as a comment.\n\n\t``*.ctags`` files in a directory are loaded in alphabetical order.\n\nDefault optlib path list\n~~~~~~~~~~~~~~~~~~~~~~~~\n\n``$XDG_CONFIG_HOME/ctags``, or ``$HOME/.config/ctags`` if\n``$XDG_CONFIG_HOME`` is not defined\n\n``$HOME/.ctags.d``\n\n``$HOMEDRIVE$HOMEPATH/ctags.d`` (on MS Windows only)\n\n\tThese directories are parts of the optlib path list by default.\n\tSee \"`Option File Options`_\" about the optlib path list.\n\n\tIf you have a set of options that you want to enable\n\tconditionally, make a directory in the path in the optlib path\n\tlist, and put the options to the files having .ctags as extensions\n\tunder the directory. ``--options=<the-directory-name>`` is for\n\tenabling the options.\n\n\tFor example, consider you have some options you want to enable\n\tonly when tagging the Linux kernel source tree.  In that case,\n\tmake ``$HOME/.ctags.d/linux`` directory, put the options to\n\t``$HOME/.ctags.d/linux/my.ctags``. If you have many options, you\n\tcan split them into multiple files like\n\t``$HOME/.ctags.d/linux/device-driver.ctags`` and\n\t``$HOME/.ctags.d/linux/network-stack.ctags``. Either way, you can\n\tenable the options in the .ctags file(s) under the directory by\n\tadding ``--options=linux`` to your ctags command line.\n\nSEE ALSO\n--------\n\nSee ctags-optlib(7) for defining (or extending) a parser\nin a configuration file.\n\nSee tags(5) for the format of tag files.\n\nSee ctags-incompatibilities(7) about known incompatible changes\nwith Exuberant Ctags.\n\nSee ctags-client-tools(7) if you are interested in writing\na tool for processing tags files.\n\nSee ctags-lang-python(7) about python input specific notes.\n\nSee readtags(1) about a client tool for binary searching a\nname in a sorted tags file.\n\nThe official Universal Ctags web site at: https://ctags.io/\n\nAlso ``ex(1)``, ``vi(1)``, ``elvis(1)``, or, better yet, ``vim(1)``, the official editor of ctags.\nFor more information on ``vim(1)``, see the Vim web site at: https://www.vim.org/\n\nAbout the file format for ``TAGS``, see `emacs git\n<https://git.savannah.gnu.org/cgit/emacs.git/tree/etc/ETAGS.EBNF>`_.\n\nAUTHOR\n------\n\nUniversal Ctags project\nhttps://ctags.io/\n\nDarren Hiebert <dhiebert@users.sourceforge.net>\nhttp://DarrenHiebert.com/\n\n\nMOTIVATION\n----------\n\n\"Think ye at all times of rendering some service to every member of the\nhuman race.\"\n\n\"All effort and exertion put forth by man from the fullness of his heart is\nworship, if it is prompted by the highest motives and the will to do\nservice to humanity.\"\n\n-- From the Baha'i Writings\n\nCREDITS\n-------\nThis version of @CTAGS_NAME_EXECUTABLE@ (Universal Ctags) derived from\nthe repository, known as fishman-ctags, started by Reza Jelveh.\n\nThe fishman-ctags was derived from Exuberant Ctags.\n\nSome parsers are taken from ``tagmanager`` of the Geany (https://www.geany.org/)\nproject.\n\nExuberant Ctags was originally derived from and\ninspired by the ctags program by Steve Kirkendall <kirkenda@cs.pdx.edu>\nthat comes with the Elvis vi clone (though virtually none of the original\ncode remains).\n\nCredit is also due Bram Moolenaar <Bram@vim.org>, the author of vim,\nwho has devoted so much of his time and energy both to developing the editor\nas a service to others, and to helping the orphans of Uganda.\n\nThe section entitled \"`HOW TO USE WITH GNU EMACS`_\" was shamelessly stolen\nfrom the info page for GNU etags.\n"
  },
  {
    "path": "man/readtags.1.rst.in",
    "content": ".. _readtags(1):\n\n==============================================================\nreadtags\n==============================================================\n--------------------------------------------------------------\nFind tag file entries matching specified names\n--------------------------------------------------------------\n:Version: @VERSION@\n:Manual group: Universal Ctags\n:Manual section: 1\n\nSYNOPSIS\n--------\n|\t**readtags** -h | --help\n|\t**readtags** (-H | --help-expression) (filter|sorter|formatter)\n|\t**readtags** -v | --version\n|\t**readtags** [OPTION]... ACTION\n\nDESCRIPTION\n-----------\nThe **readtags** program filters, sorts and prints tag entries in a tags file.\nThe basic filtering is done using **actions**, by which you can list all\nregular tags, pseudo tags or regular tags matching specific name. Then, further\nfiltering, sorting, and formatting can be done using **post processors**, namely\n**filter expressions**, **sorter expressions**, and **formatter expressions**.\n\nACTIONS\n-------\n``-l``, ``--list``\n\tList regular tags.\n\n``[-] NAME``\n\tList regular tags matching NAME.\n\t\"-\" as NAME indicates arguments after this as NAME even if they start with -.\n\n``-D``, ``--list-pseudo-tags``\n\tList pseudo tags.\n\tYou can use this option with ``-Q`` option to extract specified pseudo tags.\n\nOPTIONS\n-------\n\nControlling the Tags Reading Behavior\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe behavior of reading tags can be controlled using these options:\n\n``-t TAGFILE``, ``--tag-file TAGFILE``\n\tUse specified tag file (default: \"tags\").\n\tGiving \"-\" as TAGFILE indicates reading the tags file content from the\n\tstandard input. \"-\" can make the command line simpler. However,\n\tit doesn't mean efficient; readtags stores the data to a temporary\n\tfile and reads that file for taking the ACTION.\n\n``-s[0|1|2]``, ``--override-sort-detection METHOD``\n\tOverride sort detection of tag file.\n\tMETHOD: unsorted|sorted|foldcase\n\nThe NAME action will perform binary search on sorted (including \"foldcase\")\ntags files, which is much faster then on unsorted tags files.\n\nControlling the NAME Action Behavior\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe behavior of the NAME action can be controlled using these options:\n\n``-i``, ``--icase-match``\n\tPerform case-insensitive matching in the NAME action.\n\n``-p``, ``--prefix-match``\n\tPerform prefix matching in the NAME action.\n\nControlling the Output\n~~~~~~~~~~~~~~~~~~~~~~\nBy default, the output of readtags contains only the name, input and pattern\nfield. The Output can be tweaked using these options:\n\n``-A``, ``--absolute-input``\n\tDo the same as ``-C`` option but use only absolute path form.\n\n``-C``, ``--canonicalize-input``\n\tResolve '..' and '.' in input fields of regular tags.\n\tThis produces a unique representation of the input path.\n\tThis option works only with tags files having ``!_TAG_PROC_CWD`` pseudo\n\ttag.\n\n\tNOTE: The current implementation accepts only ``!_TAG_PROC_CWD``\n\tstarting with ``/``; a Windows directory name starting with a\n\tdrive letter like ``C:\\Somewhere`` is not acceptable.\n\n``-d``, ``--debug``\n\tTurn on debugging output.\n\n``-E``, ``--escape-output``\n\tEscape characters like tabs in output as described in tags(5).\n\n``-e``, ``--extension-fields``\n\tInclude extension fields in output.\n\n``-n``, ``--line-number``\n\tAlso include the line number field when ``-e`` option is give.\n\n``-P``, ``--with-pseudo-tags``\n\tList pseudo tags as if ``-D`` option is specified but continues processing without exiting.\n\tEven if you specify the ``-Q`` and ``-P`` options together, ``-Q``  affects only\n\tregular tags; it doesn't affect pseudo tags.\n\nAbout the ``-E`` option: certain characters are escaped in a tags file, to make\nit machine-readable. e.g., ensuring no tabs character appear in fields other\nthan the pattern field. By default, readtags translates them to make it\nhuman-readable, but when utilizing readtags output in a script or a client\ntool, ``-E`` option should be used. See ctags-client-tools(7) for more\ndiscussion on this.\n\nAbout printing input fields ({tagfile} in tags(5)) with ``-E`` option: readtags\nalways prints the input field literally (as it is in the tags file), and when\nctags writes the tags file, the escaping rules are applied only when\n``TAG_OUTPUT_MODE`` pseudo tag has \"u-ctags\" and ``TAG_OUTPUT_FILESEP`` has\n\"slash\" as values for their input fields, as explained in\nctags-client-tools(7).\n\nFiltering, Sorting, and Formatting\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nFurther filtering, sorting, and formatting on the tags listed by actions\nare performed using:\n\n``-Q EXP``, ``--filter EXP``\n\tFilter the tags listed by ACTION with EXP before printing.\n\n``-S EXP``, ``--sorter EXP``\n\tSort the tags listed by ACTION with EXP before printing.\n\n``-F EXP``, ``--formatter EXP``\n\tFormat the tags listed by ACTION with EXP when printing.\n\nThese are discussed in the `EXPRESSION`_ section.\n\nExamples\n~~~~~~~~\n* List all tags in \"/path/to/tags\":\n\n  .. code-block:: console\n\n     $ readtags -t /path/to/tags -l\n\n* List all tags in \"tags\" that start with \"mymethod\":\n\n  .. code-block:: console\n\n     $ readtags -p - mymethod\n\n* List all tags matching \"mymethod\", case insensitively:\n\n  .. code-block:: console\n\n     $ readtags -i - mymethod\n\n* List all tags start with \"myvar\", and printing all fields (i.e., the whole line):\n\n  .. code-block:: console\n\n     $ readtags -p -ne - myvar\n\nEXPRESSION\n----------\nScheme-style expressions are used for the ``-Q``, ``-S``, and ``-F`` options.\nFor those who doesn't know Scheme or Lisp, just remember:\n\n* A function call is wrapped in a pair of parenthesis. The first item in it is\n  the function/operator name, the others are arguments.\n* Function calls can be nested.\n* Missing values and boolean false are represented by ``#f``. ``#t`` and all\n  other values are considered to be true.\n\nSo, ``(+ 1 (+ 2 3))`` means add 2 and 3 first, then add the result with 1.\n``(and \"string\" 1 #t)`` means logical AND on ``\"string\"``, ``1`` and ``#t``,\nand the result is true since there is no ``#f``.\n\nFiltering\n~~~~~~~~~\nThe tag entries that make the filter expression produces true value are printed\nby readtags.\n\nThe basic operators for filtering are ``eq?``, ``prefix?``, ``suffix?``,\n``substr?``, and ``#/PATTERN/``. Language common fields can be accessed using\nvariables starting with ``$``, e.g., ``$language`` represents the language field.\nFor example:\n\n* List all tags start with \"myfunc\" in Python code files:\n\n  .. code-block:: console\n\n     $ readtags -p -Q '(eq? $language \"Python\")' - myfunc\n\n``downcase`` or ``upcase`` operators can be used to perform case-insensitive\nmatching:\n\n* List all tags containing \"my\", case insensitively:\n\n    .. code-block:: console\n\n     $ readtags -Q '(substr? (downcase $name) \"my\")' -l\n\nWe have logical operators like ``and``, ``or`` and ``not``. The value of a\nmissing field is #f, so we could deal with missing fields:\n\n* List all tags containing \"impl\" in Python code files, but allow the\n  ``language:`` field to be missing:\n\n  .. code-block:: console\n\n     $ readtags -Q '(and (substr? $name \"impl\")\\\n                         (or (not $language)\\\n                             (eq? $language \"Python\")))' -l\n\n``#/PATTERN/`` is for the case when string predicates (``prefix?``, ``suffix?``,\nand ``substr?``) are not enough. You can use \"Posix extended regular expression\"\nas PATTERN.\n\n* List all tags inherits from the class \"A\":\n\n  .. code-block:: console\n\n     $ readtags -Q '(#/(^|,) ?A(,|$)/ $inherits)' -l\n\nHere ``$inherits`` is a comma-separated class list like \"A,B,C\", \"P, A, Q\", or\njust \"A\". Notice that this filter works on both situations where there's a\nspace after each comma or there's not.\n\nCase-insensitive matching can be performed by ``#/PATTERN/i``:\n\n* List all tags inherits from the class \"A\" or \"a\":\n\n  .. code-block:: console\n\n     $ readtags -Q '(#/(^|,) ?A(,|$)/i $inherits)' -l\n\nTo include \"/\" in a pattern, prefix ``\\`` to the \"/\".\n\nNOTE: The above regular expression pattern for inspecting inheritances is just\nan example to show how to use ``#/PATTERN/`` expression. Tags file generators\nhave no consensus about the format of ``inherits:``, e.g., whether there should\nbe a space after a comma. Even parsers in ctags have no consensus. Noticing the\nformat of the ``inherits:`` field of specific languages is needed for such\nqueries.\n\nThe expressions ``#/PATTERN/`` and ``#/PATTERN/i`` are for interactive use.\nReadtags also offers an alias ``string->regexp``, so ``#/PATTERN/`` is equal to\n``(string->regexp \"PATTERN\")``, and ``#/PATTERN/i`` is equal to\n``(string->regexp \"PATTERN\" :case-fold #t)``. ``string->regexp`` doesn't need\nto prefix ``\\`` for including \"/\" in a pattern. ``string->regexp`` may simplify\na client tool building an expression. See also ctags-client-tools(7) for\nbuilding expressions in your tool.\n\nLet's now consider missing fields. The tags file may have tag entries that has\nno ``inherits:`` field. In that case ``$inherits`` is #f, and the regular\nexpression matching raises an error, since string operators only work for\nstrings. To avoid this problem:\n\n* Safely list all tags inherits from the class \"A\":\n\n  .. code-block:: console\n\n     $ readtags -Q '(and $inherits (#/(^|,) ?A(,|$)/ $inherits))' -l\n\nThis makes sure ``$inherits`` is not missing first, then match it by regexp.\n\nSometimes you want to keep tags where the field *is* missing. For example, your\nwant to exclude reference tags, which is marked by the ``extras:`` field, then\nyou want to keep tags who doesn't have ``extras:`` field since they are also\nnot reference tags. Here's how to do it:\n\n* List all tags but the reference tags:\n\n  .. code-block:: console\n\n     $ readtags -Q '(or (not $extras) (#/(^|,) ?reference(,|$)/ $extras))' -l\n\nNotice that ``(not $extras)`` produces ``#t`` when ``$extras`` is missing, so\nthe whole ``or`` expression produces ``#t``.\n\n\nThe combination of ``ctags -o -`` and ``readtags -t -`` is handy for inspecting\na source file as far as the source file is enough short.\n\n* List all the large (> 100 lines) functions in a file:\n\n  .. code-block:: console\n\n     $ ctags -o - --fields=+neKz input.c \\\n       | ./readtags -t - -en \\\n                    -Q '(and (eq? $kind \"function\") $end $line (> (- $end $line) 100))' \\\n                    -l\n\n* List all the tags including line 80 in a file:\n\n  .. code-block:: console\n\n     $ ctags -o - --fields=+neKz input.c \\\n       | readtags -t - -ne \\\n                  -Q '(and $line\n                           (or (eq? $line 80)\n                               (and $end (< $line 80) (< 80 $end))))' \\\n         -l\n\nRun \"readtags -H filter\" to know about all valid functions and variables.\n\nSorting\n~~~~~~~\nWhen sorting, the sorter expression is evaluated on two tag entries to decide\nwhich should sort before the other one, until the order of all tag entries is\ndecided.\n\nIn a sorter expression, ``$`` and ``&`` are used to access the fields in the\ntwo tag entries, and let's call them $-entry and &-entry. The sorter expression\nshould have a value of -1, 0 or 1. The value -1 means the $-entry should be put\nabove the &-entry, 1 means the contrary, and 0 makes their order in the output\nuncertain.\n\nThe core operator of sorting is ``<>``. It's used to compare two strings or two\nnumbers (numbers are for the ``line:`` or ``end:`` fields). In ``(<> a b)``, if\n``a`` < ``b``, the result is -1; ``a`` > ``b`` produces 1, and ``a`` = ``b``\nproduces 0. Strings are compared using the ``strcmp`` function, see strcmp(3).\n\nFor example, sort by names, and make those shorter or alphabetically smaller\nones appear before the others:\n\n.. code-block:: console\n\n   $ readtags -S '(<> $name &name)' -l\n\nThis reads \"If the tag name in the $-entry is smaller, it goes before the\n&-entry\".\n\nThe ``<or>`` operator is used to chain multiple expressions until one returns\n-1 or 1. For example, sort by input file names, then line numbers if in the\nsame file:\n\n.. code-block:: console\n\n   $ readtags -S '(<or> (<> $input &input) (<> $line &line))' -l\n\nThe ``*-`` operator is used to flip the compare result. i.e., ``(*- (<> a b))``\nis the same as ``(<> b a)``.\n\nFilter expressions can be used in sorter expressions. The technique is use\n``if`` to produce integers that can be compared based on the filter, like:\n\n.. code-block:: lisp\n\n   (<> (if filter-expr-on-$-entry -1 1)\n       (if filter-expr-on-&-entry -1 1))\n\nSo if $-entry satisfies the filter, while &-entry doesn't, it's the same as\n``(<> -1 1)``, which produces ``-1``.\n\nFor example, we want to put tags with \"file\" kind below other tags, then the\nsorter would look like:\n\n.. code-block:: lisp\n\n   (<> (if (eq? $kind \"file\") 1 -1)\n       (if (eq? &kind \"file\") 1 -1))\n\nA quick read tells us: If $-entry has \"file\" kind, and &-entry doesn't, the\nsorter becomes ``(<> 1 -1)``, which produces ``1``, so the $-entry is put below\nthe &-entry, exactly what we want.\n\nFormatting\n~~~~~~~~~~\nA formatter expression defines how readtags prints tag entries.\n\nA formatter expression may produce a string, a boolean, an integer,\nor a list. Readtags prints the produced string, and integer as is.\nReadtags prints nothing for ``#f``, and a newline for ``#t``.\n\nA list could contain any number of strings, booleans,\nintegers, and/or lists. Readtags prints the elements of a list\nsequentially and recursively.\n\nAll the operators for filtering are also available in formatter\nexpressions. In addition to the operators, ``list`` is available\nin formatter expressions. As the name shows, ``list`` is for\nmaking a list. ``list`` makes a list containing arguments passed to\nthe operator. e.g., the following expression makes a list contains\n``1``, ``#f``, and ``\"hello\"``:\n\n.. code-block:: lisp\n\n   (list 1 #f \"hello\")\n\nNOTE: Unlike real-Lisp, backquote constructs are not available.\n\nTo show some examples, the following tags file (``output.tags``) is assumed\nas input for readtags:\n\n.. code-block:: tags\n\n   M\tinput.c\t4;\"\tmacro\tfile:\n   N\tinput.c\t3;\"\tmacro\tfile:\n   bar\tinput.c\t11;\"\tf\ttyperef:typename:void\tfile:\tsignature:(char ** argv,int * r)\n   foo\tinput.c\t6;\"\tf\ttyperef:typename:int\tfile:\tsignature:(int v)\n   main\tinput.c\t16;\"\tf\ttyperef:typename:int\tsignature:(int argc,char ** argv)\n\nAn example for printing only function names:\n\n.. code-block:: console\n\n   $ readtags -t output.tags -Q '(eq? $kind \"function\")' -F '(list $name #t)' -l\n   bar\n   foo\n   main\n\nDoing the same only with a formatter expression:\n\n.. code-block:: console\n\n   $ readtags -t output.tags -F '(if (eq? $kind \"function\") (list $name #t) #f)' -l\n   bar\n   foo\n   main\n\nGenerating declarations for the functions:\n\n.. code-block:: console\n\n   $ readtags -t output.tags -F \\\n     '(if (eq? $kind \"function\")\n         (list (if $file \"static \" #f) $typeref-name \" \" $name $signature \";\" #t)\n        #f)' -l\n   static void bar(char ** argv,int * r);\n   static int foo(int v);\n   int main(int argc,char ** argv);\n\nInspecting the Behavior of Expressions\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe `print` operator can be used to print the value of an expression. For\nexample:\n\n.. code-block:: console\n\n   $ readtags -Q '(print $name)' -l\n\nprints the name of each tag entry before it. Since the return value of\n``print`` is not #f, all the tag entries are printed. We could control this\nusing the ``begin`` or ``begin0`` operator. ``begin`` returns the value of its\nlast argument, and ``begin0`` returns the value of its first argument. For\nexample:\n\n.. code-block:: console\n\n   $ readtags -Q '(begin0 #f (print (prefix? \"ctags\" \"ct\")))' -l\n\nprints a bunch of \"#t\" (depending on how many lines are in the tags file), and\nthe actual tag entries are not printed.\n\nSEE ALSO\n--------\nSee tags(5) for the details of tags file format.\n\nSee ctags-client-tools(7) for the tips writing a\ntool utilizing tags file.\n\nThe official Universal Ctags web site at:\n\nhttps://ctags.io/\n\nThe git repository for the library used in readtags command:\n\nhttps://github.com/universal-ctags/libreadtags\n\nCREDITS\n-------\nUniversal Ctags project\nhttps://ctags.io/\n\nDarren Hiebert <dhiebert@users.sourceforge.net>\nhttp://DarrenHiebert.com/\n\nThe readtags command and libreadtags maintained at Universal Ctags\nare derived from readtags.c and readtags.h developed at\nhttp://ctags.sourceforge.net.\n"
  },
  {
    "path": "man/tags.5.rst.in",
    "content": ".. _tags(5):\n\n==============================================================\ntags\n==============================================================\n--------------------------------------------------------------\nVi tags file format extended in ctags projects\n--------------------------------------------------------------\n:Version: 2+\n:Manual group: Universal Ctags\n:Manual section: 5\n\nDESCRIPTION\n-----------\n\nThe contents of next section is a copy of FORMAT file in Exuberant\nCtags source code in its subversion repository at sourceforge.net.\n\nExceptions introduced in Universal Ctags are explained inline with\n\"EXCEPTION\" marker. Statements that are made further clear in Universal\nCtags are explained inline with \"COMMENT\" marker.\n\n----\n\nProposal for extended Vi tags file format\n-----------------------------------------\n\n| Version: 0.06 DRAFT\n| Date: 1998 Feb 8\n| Author: Bram Moolenaar <Bram at vim.org> and Darren Hiebert <dhiebert at users.sourceforge.net>\n\nIntroduction\n~~~~~~~~~~~~\n\nThe file format for the \"tags\" file, as used by Vi and many of its\ndescendants, has limited capabilities.\n\nThis additional functionality is desired:\n\n1. Static or local tags.\n   The scope of these tags is the file where they are defined.  The same tag\n   can appear in several files, without really being a duplicate.\n2. Duplicate tags.\n   Allow the same tag to occur more then once.  They can be located in\n   a different file and/or have a different command.\n3. Support for C++.\n   A tag is not only specified by its name, but also by the context (the\n   class name).\n4. Future extension.\n   When even more additional functionality is desired, it must be possible to\n   add this later, without breaking programs that don't support it.\n\n\nFrom proposal to standard\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo make this proposal into a standard for tags files, it needs to be supported\nby most people working on versions of Vi, ctags, etc..  Currently this\nstandard is supported by:\n\nDarren Hiebert <dhiebert at users.sourceforge.net>\n\tExuberant Ctags\n\nBram Moolenaar <Bram at vim.org>\n\tVim (Vi IMproved)\n\nThese have been or will be asked to support this standard:\n\nNvi\n\t\tKeith Bostic <bostic at bsdi.com>\n\nVile\n\t\tTom E. Dickey <dickey at clark.net>\n\nNEdit\n\t\tMark Edel <edel at ltx.com>\n\nCRiSP\n\t\tPaul Fox <fox at crisp.demon.co.uk>\n\nLemmy\n\t\tJames Iuliano <jai at accessone.com>\n\nZeus\n\t\tJussi Jumppanen <jussij at ca.com.au>\n\nElvis\n\t\tSteve Kirkendall <kirkenda at cs.pdx.edu>\n\nFTE\n\t\tMarko Macek <Marko.Macek at snet.fri.uni-lj.si>\n\n\nBackwards compatibility\n~~~~~~~~~~~~~~~~~~~~~~~\n\nA tags file that is generated in the new format should still be usable by Vi.\nThis makes it possible to distribute tags files that are usable by all\nversions and descendants of Vi.\n\nThis restricts the format to what Vi can handle.  The format is:\n\n1. The tags file is a list of lines, each line in the format::\n\n\t{tagname}<Tab>{tagfile}<Tab>{tagaddress}\n\n\n   {tagname}\n\tAny identifier, not containing white space..\n\n\tEXCEPTION: Universal Ctags violates this item of the proposal;\n\ttagname may contain spaces. However, tabs are not allowed.\n\n   <Tab>\n\tExactly one TAB character (although many versions of Vi can\n\thandle any amount of white space).\n\n   {tagfile}\n\tThe name of the file where {tagname} is defined, relative to\n\tthe current directory (or location of the tags file?).\n\n   {tagaddress}\n\tAny Ex command.  When executed, it behaves like 'magic' was\n\tnot set.\n\n2. The tags file is sorted on {tagname}.  This allows for a binary search in\n   the file.\n\n3. Duplicate tags are allowed, but which one is actually used is\n   unpredictable (because of the binary search).\n\nThe best way to add extra text to the line for the new functionality, without\nbreaking it for Vi, is to put a comment in the {tagaddress}.  This gives the\nfreedom to use any text, and should work in any traditional Vi implementation.\n\nFor example, when the old tags file contains::\n\n\tmain\tmain.c\t/^main(argc, argv)$/\n\tDEBUG\tdefines.c\t89\n\nThe new lines can be::\n\n\tmain\tmain.c\t/^main(argc, argv)$/;\"any additional text\n\tDEBUG\tdefines.c\t89;\"any additional text\n\nNote that the ';' is required to put the cursor in the right line, and then\nthe '\"' is recognized as the start of a comment.\n\nFor Posix compliant Vi versions this will NOT work, since only a line number\nor a search command is recognized.  I hope Posix can be adjusted.  Nvi suffers\nfrom this.\n\n\nSecurity\n~~~~~~~~\n\nVi allows the use of any Ex command in a tags file.  This has the potential of\na trojan horse security leak.\n\nThe proposal is to allow only Ex commands that position the cursor in a single\nfile.  Other commands, like editing another file, quitting the editor,\nchanging a file or writing a file, are not allowed.  It is therefore logical\nto call the command a tagaddress.\n\nSpecifically, these two Ex commands are allowed:\n\n* A decimal line number::\n\n\t89\n\n* A search command.  It is a regular expression pattern, as used by Vi,\n  enclosed in // or ??::\n\n\t/^int c;$/\n\t?main()?\n\nThere are two combinations possible:\n\n* Concatenation of the above, with ';' in between.  The meaning is that the\n  first line number or search command is used, the cursor is positioned in\n  that line, and then the second search command is used (a line number would\n  not be useful).  This can be done multiple times.  This is useful when the\n  information in a single line is not unique, and the search needs to start\n  in a specified line.\n  ::\n\n\t/struct xyz {/;/int count;/\n\t389;/struct foo/;/char *s;/\n\n* A trailing comment can be added, starting with ';\"' (two characters:\n  semi-colon and double-quote).  This is used below.\n  ::\n\n\t89;\" foo bar\n\nThis might be extended in the future.  What is currently missing is a way to\nposition the cursor in a certain column.\n\n\nGoals\n~~~~~\n\nNow the usage of the comment text has to be defined.  The following is aimed\nat:\n\n1. Keep the text short, because:\n\n   * The line length that Vi can handle is limited to 512 characters.\n   * Tags files can contain thousands of tags.  I have seen tags files of\n     several Mbytes.\n   * More text makes searching slower.\n\n2. Keep the text readable, because:\n\n   * It is often necessary to check the output of a new ctags program.\n   * Be able to edit the file by hand.\n   * Make it easier to write a program to produce or parse the file.\n\n3. Don't use special characters, because:\n\n   * It should be possible to treat a tags file like any normal text file.\n\nProposal\n~~~~~~~~\n\nUse a comment after the {tagaddress} field.  The format would be::\n\n\t{tagname}<Tab>{tagfile}<Tab>{tagaddress}[;\"<Tab>{tagfield}..]\n\n\n{tagname}\n\tAny identifier, not containing white space..\n\n\tEXCEPTION: Universal Ctags violates this item of the proposal;\n\tname may contain spaces. However, tabs are not allowed.\n\tConversion, for some characters including <Tab> in the \"value\",\n\texplained in the last of this section is applied.\n\n<Tab>\n\tExactly one TAB character (although many versions of Vi can\n\thandle any amount of white space).\n\n{tagfile}\n\tThe name of the file where {tagname} is defined, relative to\n\tthe current directory (or location of the tags file?).\n\n{tagaddress}\n\tAny Ex command.  When executed, it behaves like 'magic' was\n\tnot set.  It may be restricted to a line number or a search\n\tpattern (Posix).\n\n\tCOMMENT: {tagaddress} could contain tab characters. See\n\tctags-client-tools(7) to know how to programmatically extract {tagaddress}\n\t(called \"pattern field\" there) and parse it.\n\nOptionally:\n\n;\"\n\t\tsemicolon + doublequote: Ends the tagaddress in way that looks\n\t\tlike the start of a comment to Vi.\n\n{tagfield}\n\t\tSee below.\n\nA tagfield has a name, a colon, and a value: \"name:value\".\n\n* The name consist only out of alphabetical characters.  Upper and lower case\n  are allowed.  Lower case is recommended.  Case matters (\"kind:\" and \"Kind:\n  are different tagfields).\n\n  EXCEPTION: Universal Ctags allows users to use a numerical character\n  in the name other than its initial letter.\n\n* The value may be empty.\n  It cannot contain a <Tab>.\n\n  - When a value contains a ``\\t``, this stands for a <Tab>.\n  - When a value contains a ``\\r``, this stands for a <CR>.\n  - When a value contains a ``\\n``, this stands for a <NL>.\n  - When a value contains a ``\\\\``, this stands for a single ``\\`` character.\n\n  Other use of the backslash character is reserved for future expansion.\n  Warning: When a tagfield value holds an MS-DOS file name, the backslashes\n  must be doubled!\n\n  EXCEPTION: Universal Ctags introduces more conversion rules.\n\n  - When a value contains a ``\\a``, this stands for a <BEL> (0x07).\n  - When a value contains a ``\\b``, this stands for a <BS> (0x08).\n  - When a value contains a ``\\v``, this stands for a <VT> (0x0b).\n  - When a value contains a ``\\f``, this stands for a <FF> (0x0c).\n  - The characters in range 0x01 to 0x1F included, and 0x7F are\n    converted to ``\\x`` prefixed hexadecimal number if the characters are\n    not handled in the above \"value\" rules.\n\n  EXCEPTION: Universal Ctags allows all these escape sequences in {tagname}\n  and {tagfile} also. However, about {tagfile}, a condition must be\n  satisfied. See \"`Exceptions in Universal Ctags`_\" about the condition.\n\n  - The leading space (0x20) and ``!`` (0x21) in {tagname} are converted\n    to ``\\x`` prefixed hexadecimal number (``\\x20`` and ``\\x21``) if the\n    tag is not a pseudo-tag. As described later, a pseudo-tag starts with\n    ``!``. These rules are for distinguishing pseudo-tags and non pseudo-tags\n    (regular tags) when tags lines in a tag file are sorted.\n\nProposed tagfield names:\n\n=============== =============================================================================\nFIELD-NAME\tDESCRIPTION\n=============== =============================================================================\narity\t\tNumber of arguments for a function tag.\n\nclass\t\tName of the class for which this tag is a member or method.\n\nenum\t\tName of the enumeration in which this tag is an enumerator.\n\nfile\t\tStatic (local) tag, with a scope of the specified file.  When\n\t\tthe value is empty, {tagfile} is used.\n\nfunction\tFunction in which this tag is defined.  Useful for local\n\t\tvariables (and functions).  When functions nest (e.g., in\n\t\tPascal), the function names are concatenated, separated with\n\t\t'/', so it looks like a path.\n\nkind\t\tKind of tag.  The value depends on the language.  For C and\n\t\tC++ these kinds are recommended:\n\n\t\tc\n\t\t\tclass name\n\n\t\td\n\t\t\tdefine (from #define XXX)\n\n\t\te\n\t\t\tenumerator\n\n\t\tf\n\t\t\tfunction or method name\n\n\t\tF\n\t\t\tfile name\n\n\t\tg\n\t\t\tenumeration name\n\n\t\tm\n\t\t\tmember (of structure or class data)\n\n\t\tp\n\t\t\tfunction prototype\n\n\t\ts\n\t\t\tstructure name\n\n\t\tt\n\t\t\ttypedef\n\n\t\tu\n\t\t\tunion name\n\n\t\tv\n\t\t\tvariable\n\n\t\tWhen this field is omitted, the kind of tag is undefined.\n\nstruct\t\tName of the struct in which this tag is a member.\n\nunion\t\tName of the union in which this tag is a member.\n=============== =============================================================================\n\n\nNote that these are mostly for C and C++.  When tags programs are written for\nother languages, this list should be extended to include the used field names.\nThis will help users to be independent of the tags program used.\n\nExamples::\n\n\tasdf\tsub.cc\t/^asdf()$/;\"\tnew_field:some\\svalue\tfile:\n\tfoo_t\tsub.h\t/^typedef foo_t$/;\"\tkind:t\n\tfunc3\tsub.p\t/^func3()$/;\"\tfunction:/func1/func2\tfile:\n\tgetflag\tsub.c\t/^getflag(arg)$/;\"\tkind:f\tfile:\n\tinc\tsub.cc\t/^inc()$/;\"\tfile: class:PipeBuf\n\n\nThe name of the \"kind:\" field can be omitted.  This is to reduce the size of\nthe tags file by about 15%.  A program reading the tags file can recognize the\n\"kind:\" field by the missing ':'.  Examples::\n\n\tfoo_t\tsub.h\t/^typedef foo_t$/;\"\tt\n\tgetflag\tsub.c\t/^getflag(arg)$/;\"\tf\tfile:\n\n\nAdditional remarks:\n\n* When a tagfield appears twice in a tag line, only the last one is used.\n\n\nNote about line separators:\n\nVi traditionally runs on Unix systems, where the line separator is a single\nlinefeed character <NL>.  On MS-DOS and compatible systems <CR><NL> is the\nstandard line separator.  To increase portability, this line separator is also\nsupported.\n\nOn the Macintosh a single <CR> is used for line separator.  Supporting this on\nUnix systems causes problems, because most fgets() implementation don't see\nthe <CR> as a line separator.  Therefore the support for a <CR> as line\nseparator is limited to the Macintosh.\n\nSummary:\n\n==============  ======================  =========================\nline separator\tgenerated on\t\taccepted on\n==============  ======================  =========================\n<LF>\t\tUnix\t\t\tUnix, MS-DOS, Macintosh\n<CR>\t\tMacintosh\t\tMacintosh\n<CR><LF>\tMS-DOS\t\t\tUnix, MS-DOS, Macintosh\n==============  ======================  =========================\n\nThe characters <CR> and <LF> cannot be used inside a tag line.  This is not\nmentioned elsewhere (because it's obvious).\n\n\nNote about white space:\n\nVi allowed any white space to separate the tagname from the tagfile, and the\nfilename from the tagaddress.  This would need to be allowed for backwards\ncompatibility.  However, all known programs that generate tags use a single\n<Tab> to separate fields.\n\nThere is a problem for using file names with embedded white space in the\ntagfile field.  To work around this, the same special characters could be used\nas in the new fields, for example ``\\s``.  But, unfortunately, in MS-DOS the\nbackslash character is used to separate file names.  The file name\n``c:\\vim\\sap`` contains ``\\s``, but this is not a <Space>.  The number of\nbackslashes could be doubled, but that will add a lot of characters, and make\nparsing the tags file slower and clumsy.\n\nTo avoid these problems, we will only allow a <Tab> to separate fields, and\nnot support a file name or tagname that contains a <Tab> character.  This\nmeans that we are not 100% Vi compatible.  However, there is no known tags\nprogram that uses something else than a <Tab> to separate the fields.  Only\nwhen a user typed the tags file himself, or made his own program to generate a\ntags file, we could run into problems.  To solve this, the tags file should be\nfiltered, to replace the arbitrary white space with a single <Tab>.  This Vi\ncommand can be used::\n\n\t:%s/^\\([^ ^I]*\\)[ ^I]*\\([^ ^I]*\\)[ ^I]*/\\1^I\\2^I/\n\n(replace ^I with a real <Tab>).\n\nCOMMENT: Universal Ctags running on MS Windows converts the ``\\`` separator\nto ``/`` by default, and allows the escape sequences even in {tagfile}\nif a condition is satisfied. See \"`Exceptions in Universal Ctags`_\" about\nthe condition.\n\nTAG FILE INFORMATION:\n\nPseudo-tag lines can be used to encode information into the tag file regarding\ndetails about its content (e.g. have the tags been sorted?, are the optional\ntagfields present?), and regarding the program used to generate the tag file.\nThis information can be used both to optimize use of the tag file (e.g.\nenable/disable binary searching) and provide general information (what version\nof the generator was used).\n\nThe names of the tags used in these lines may be suitably chosen to ensure\nthat when sorted, they will always be located near the first lines of the tag\nfile.  The use of \"!_TAG_\" is recommended.  Note that a rare tag like \"!\"\ncan sort to before these lines.  The program reading the tags file should be\nsmart enough to skip over these tags.\n\nThe lines described below have been chosen to convey a select set of\ninformation.\n\nTag lines providing information about the content of the tag file::\n\n    !_TAG_FILE_FORMAT\t{version-number}\t/optional comment/\n    !_TAG_FILE_SORTED\t{0|1}\t\t\t/0=unsorted, 1=sorted/\n\nThe {version-number} used in the tag file format line reserves the value of\n\"1\" for tag files complying with the original UNIX vi/ctags format, and\nreserves the value \"2\" for tag files complying with this proposal. This value\nmay be used to determine if the extended features described in this proposal\nare present.\n\nTag lines providing information about the program used to generate the tag\nfile, and provided solely for documentation purposes::\n\n    !_TAG_PROGRAM_AUTHOR\t{author-name}\t/{email-address}/\n    !_TAG_PROGRAM_NAME\t{program-name}\t/optional comment/\n    !_TAG_PROGRAM_URL\t{URL}\t/optional comment/\n    !_TAG_PROGRAM_VERSION\t{version-id}\t/optional comment/\n\nEXCEPTION: Universal Ctags introduces more kinds of pseudo-tags.\nSee ctags-client-tools(7) about them.\n\nCOMMENT: Though pseudo-tags are semantically different from regular tags, They\nuse the same format, which is::\n\n\t{tagname}<Tab>{tagfile}<Tab>{tagaddress}\n\n, and the escape sequences and illegal characters explained in \"Proposal\"\nsection also applies to pseudo-tags.\n\n----\n\n\nExceptions in Universal Ctags\n--------------------------------------------\n\nUniversal Ctags supports this proposal with some\nexceptions.\n\n\nExceptions\n~~~~~~~~~~~\n\n#. {tagname} in tags file generated by Universal Ctags may contain\n   spaces and several escape sequences. Parsers for documents like Tex and\n   reStructuredText, or liberal languages such as JavaScript need these\n   exceptions. See {tagname} of Proposal section for more detail about the\n   conversion.\n\n#. {tagfile} in tags file generated by Universal Ctags may contain\n   spaces and several escape sequences if ``\\`` characters are not used as\n   filename separators. UNIX-like systems use ``/`` for the\n   purpose. On MS Windows, Universal Ctags converts ``\\`` in filenames\n   to ``/`` by default. So, generally this condition is satisfied.\n   Universal Ctags emits several pseudo tags telling whether the condition\n   is satisfied or not. See ctags-client-tools(7) about these pseudo tags.\n\n#. \"name\" part of {tagfield} in a tag generated by Universal Ctags may\n   contain numeric characters, but the first character of the \"name\"\n   must be alphabetic.\n\n   .. NOT REVIEWED YET (above item)\n\n.. _compat-output:\n\nCompatible output and weakness\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. NOT REVIEWED YET\n\nDefault behavior (``--output-format=u-ctags`` option) has the\nexceptions.  On the other hand, with ``--output-format=e-ctags`` option\nctags has no exception; Universal Ctags command may use the same file\nformat as Exuberant Ctags. However, ``--output-format=e-ctags`` throws\naway a tag entry which name includes a space or a tab\ncharacter. ``TAG_OUTPUT_MODE`` pseudo-tag tells which format is\nused when ctags generating tags file.\n\nSEE ALSO\n--------\nctags(1), ctags-client-tools(7), ctags-incompatibilities(7), readtags(1)\n"
  },
  {
    "path": "misc/addbom",
    "content": "#!/bin/sh\ne=/bin/echo\n\n$e -ne '\\xef'\n$e -ne '\\xbb'\n$e -ne '\\xbf'\ncat $1\n"
  },
  {
    "path": "misc/badinput.c",
    "content": "/* badinput.c: do bisect-quest to find minimal input which breaks the target command execution\n\n   Copyright (C) 2014 Masatake YAMATO\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n   Build\n   =======================================================================\n\n\t$ gcc -Wall badinput.c -o badinput\n\n   Usage\n   =======================================================================\n\n\t$ badinput CMDLINE_TEMPLATE INPUT OUTPUT\n\n   Description\n   =======================================================================\n\n   Consider a situation that a process execve'd from CMDLINE_TEMPLATE crashes or\n   enters into an infinite-loop when the process deals with INPUT file.\n\n   This program truncates both the head and tail of the INPUT file and\n   runs CMDLINE_TEMPLATE repeatedly till the process exits normally(==\n   0); and reports the shortest input which causes the crash or infinite-loop.\n\n   Here is an example:\n\n\t$ misc/badinput \"timeout 1 ./ctags -o - --language-force=Ada %s > /dev/null\" Test/1880687.js /tmp/output.txt\n\n   Ada parser of ctags enters an infinite-loop when Test/1880687.js is given.\n   The size of original Test/1880687.js is 2258 bytes.\n\n\t$ misc/badinput \"timeout 1 ./ctags -o - --language-force=Ada %s > /dev/null\" Test/1880687.js /tmp/output.txt\n\t[0, 2448]...31744\n\t[0, 0]...0\n\tstep(end): 0 [0, 2448]...31744\n\tstep(end): 1 [0, 1224]...31744\n\tstep(end): 2 [0, 612]...0\n\tstep(end): 3 [0, 918]...0\n\tstep(end): 4 [0, 1071]...0\n\tstep(end): 5 [0, 1147]...31744\n\tstep(end): 6 [0, 1109]...0\n\tstep(end): 7 [0, 1128]...31744\n\tstep(end): 8 [0, 1119]...0\n\tstep(end): 9 [0, 1123]...31744\n\tstep(end): 10 [0, 1121]...0\n\tstep(end): 11 [0, 1122]...31744\n\tstep(start): 0 [0, 1122]...31744\n\tstep(start): 1 [561, 1122]...31744\n\tstep(start): 2 [841, 1122]...31744\n\tstep(start): 3 [981, 1122]...31744\n\tstep(start): 4 [1051, 1122]...31744\n\tstep(start): 5 [1086, 1122]...0\n\tstep(start): 6 [1069, 1122]...31744\n\tstep(start): 7 [1077, 1122]...31744\n\tstep(start): 8 [1081, 1122]...31744\n\tstep(start): 9 [1083, 1122]...0\n\tstep(start): 10 [1082, 1122]...0\n\tMinimal bad input:\n\tfunction baz() {\n\t    }\n\t}\n\n\tfunction g(\n\t$\n\n   New shorter input, only 38 bytes, which can reproduce the issue is reported at the end.\n   This new input is useful for debugging.\n\n   The result is shown in stdout and is recorded to the file specified as OUTPUT. */\n\n#define _GNU_SOURCE\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <unistd.h>\n\n\nstatic void\nprint_help(const char *prog, FILE *fp, int status)\n{\n\tfprintf(fp, \"Usage:\\n\");\n\tfprintf(fp, \"\t%s --help|-h\\n\", prog);\n\tfprintf(fp, \"\t%s CMDLINE_TEMPLATE INPUT OUTPUT\\n\", prog);\n\texit (status);\n}\n\nstatic void\nload (const char* input_file, char** input, size_t* len)\n{\n\tint input_fd;\n\tstruct stat stat_buf;\n\n\tinput_fd = open (input_file, O_RDONLY);\n\tif (input_fd < 0)\n\t{\n\t\tperror (\"open(input)\");\n\t\texit(1);\n\t}\n\n\tif (fstat(input_fd, &stat_buf) < 0)\n\t{\n\t\tperror (\"fstat\");\n\t\texit(1);\n\t}\n\n\t*len = stat_buf.st_size;\n\t*input = malloc (*len);\n\tif (!*input)\n\t{\n\t\tfprintf(stderr, \"memory exhausted\\n\");\n\t\texit (1);\n\t}\n\n\tif (read (input_fd, *input, *len) != *len)\n\t{\n\t\tperror (\"read\");\n\t\texit (1);\n\t}\n}\n\nstatic void\nprepare(int output_fd, char * input, size_t len)\n{\n\tif (lseek (output_fd, 0, SEEK_SET == -1))\n\t{\n\t\tperror(\"lseek\");\n\t\texit (1);\n\t}\n\n\tif (ftruncate(output_fd, 0) == -1)\n\t{\n\t\tperror (\"truncate\");\n\t\texit (1);\n\t}\n\n\tif (write (output_fd, input, len) != len)\n\t{\n\t\tperror (\"write\");\n\t\texit (1);\n\t}\n}\n\nstatic int\ntest (char* cmdline, char * input, off_t start, size_t len, int output_fd)\n{\n\tint r;\n\n\tprepare (output_fd, input + start, len);\n\tfprintf (stderr, \"[%lu, %lu]...\", start, start + len);\n\tr = system(cmdline);\n\tfprintf(stderr, \"%d\\n\", r);\n\n\treturn r;\n}\n\nstatic int\nbisect(char* cmdline, char * input, size_t len, int output_fd)\n{\n\toff_t end;\n\toff_t start;\n\n\tunsigned int step;\n\tint delta;\n\n\toff_t failed = len;\n\toff_t successful = 0;\n\n\tend = len;\n\tfailed = len;\n\tsuccessful = 0;\n\tfor (step = 0; 1; step++)\n\t{\n\t\tfprintf(stderr, \"step(end): %d \", step);\n\t\tdelta = (len >> (step + 1));\n\t\tif (delta == 0)\n\t\t\tdelta = 1;\n\n\t\tif (test (cmdline, input, 0, end, output_fd) == 0)\n\t\t{\n\t\t\tsuccessful = end;\n\t\t\tif (end + 1 == failed)\n\t\t\t{\n\t\t\t\tend = failed;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t\tend += delta;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfailed = end;\n\t\t\tif (successful + 1 == end)\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t\tend -= delta;\n\t\t}\n\t}\n\n\tlen = end;\n\tstart = 0;\n\tfailed = 0;\n\tsuccessful = end;\n\tfor (step = 0; 1; step++)\n\t{\n\t\tfprintf(stderr, \"step(start): %d \", step);\n\t\tdelta = (len >> (step + 1));\n\t\tif (delta == 0)\n\t\t\tdelta = 1;\n\t\tif (test (cmdline, input, start, end - start, output_fd) == 0)\n\t\t{\n\t\t\tsuccessful = start;\n\t\t\tif (start - 1 == failed)\n\t\t\t{\n\t\t\t\tstart--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t\tstart -= delta;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfailed = start;\n\t\t\tif (successful - 1 == start)\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t\tstart += delta;\n\t\t}\n\n\t}\n\n\tlen = end - start;\n\tfprintf(stderr, \"Minimal bad input:\\n\");\n\tfwrite(input + start, 1, len, stdout);\n\tprepare (output_fd, input + start, len);\n\tprintf(\"\\n\");\n\n\treturn 0;\n}\n\nint\nmain(int argc, char** argv)\n{\n\tchar* cmdline_template;\n\tchar* input_file;\n\tchar* output_file;\n\n\tchar* cmdline;\n\tchar * input;\n\tsize_t len;\n\tint output_fd;\n\n\n\tif (argc == 2\n\t    && ((!strcmp(argv[2], \"--help\"))\n\t\t|| (!strcmp(argv[2], \"-h\"))))\n\t\tprint_help(argv[0], stdout, 0);\n\telse if (argc != 4)\n\t{\n\t\tfprintf(stderr,\"wrong number of arguments\\n\");\n\t\texit (1);\n\t}\n\n\tcmdline_template = argv[1];\n\tinput_file = argv[2];\n\toutput_file = argv[3];\n\n\tif (!strstr (cmdline_template, \"%s\"))\n\t{\n\t\tfprintf(stderr, \"no %%s is found in command line template\\n\");\n\t\texit (1);\n\t}\n\n\tload (input_file, &input, &len);\n\n\toutput_fd = open (output_file, O_WRONLY|O_CREAT, 0666);\n\tif (output_fd < 0)\n\t{\n\t\tperror (\"open(output)\");\n\t\texit (1);\n\t}\n\n\tif (asprintf (&cmdline, cmdline_template, output_file) == -1)\n\t{\n\t\tfprintf(stderr, \"error in asprintf\\n\");\n\t\texit (1);\n\t}\n\n\tif (test (cmdline, input, 0, len, output_fd) == 0)\n\t{\n\t\tfprintf(stderr, \"the target command line exits normally against the original input\\n\");\n\t\texit (1);\n\t}\n\n\tif (test (cmdline, input, 0, 0, output_fd) != 0)\n\t{\n\t\tfprintf(stderr, \"the target command line exits normally against the empty input\\n\");\n\t\texit (1);\n\t}\n\n\treturn bisect(cmdline, input, len, output_fd);\n}\n"
  },
  {
    "path": "misc/budge",
    "content": "#!/bin/sh\n#\n#   Copyright (C) 2014 Masatake YAMATO\n#\n#   This program is free software; you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation; either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n# ----------------------------------------------------------------------------------------\n# Show the ratio of the number of files handled by ctags to the number of all files of ctags source directory.\n# -----------------------------------------------------------------------------------------\n: ${CTAGS_TEST:=./ctags}\n\n#\n# Report all unsupported files\n#\nVERBOSE=0\n\nprint_help()\n{\n    echo \"Usage:\"\n    echo \"\t$0 -h|--help\"\n    echo \"\t$0 [-v|--verbose [-v|--verbose]]\"\n    exit $1\n}\n\nwhile [ $# -gt 0 ]; do\n    case $1 in\n\t-h|--help)\n\t    print_help 0\n\t    ;;\n\t-v|--verbose)\n\t    VERBOSE=`expr $VERBOSE + 1`\n\t    ;;\n\t-*)\n\t    echo \"unknown option: $1\"\n\t    print_help 1\n\t    ;;\n\t*)\n\t    echo \"unknown expected argument: $1\"\n\t    print_help 1\n\t    ;;\n    esac\n    shift\ndone\n\nCMDLINE=\"${CTAGS_TEST} --quiet --options=NONE -G --options-maybe=./.ctags.d --languages=all --options-maybe=misc/budge.ctags -R --print-language\"\nALL_FILES=$(git ls-files)\n\nTOTAL=0\nHAS_PARSER=0\nmember()\n{\n    local input=$1\n    local f\n    for f in $ALL_FILES; do\n\tif [ \"$f\" = \"$input\" ]; then\n\t    return 0\n\tfi\n    done\n    return 1\n}\n\nINPUT=\nLANG=\n${CMDLINE} | { while IFS=': \t' read INPUT LANG; do\n\t\t   if member \"$INPUT\"; then\n\t\t       if [ \"$LANG\" != NONE ]; then\n\t\t\t   if [ \"$VERBOSE\" -gt 1 ]; then\n\t\t\t       printf \"%-60s %s\\n\" $INPUT $LANG\n\t\t\t   fi\n\t\t\t   HAS_PARSER=$(( HAS_PARSER + 1 ))\n\t\t       else\n\t\t\t   if [ \"${VERBOSE}\" -gt 0 ]; then\n\t\t\t       printf \"%-60s %s\\n\" $INPUT NONE\n\t\t\t   fi\n\t\t       fi\n\t\t       TOTAL=$(( TOTAL + 1 ))\n\t\t   fi\n\t       done\n\t       echo \"[ctags|$(expr 100 '*' $HAS_PARSER  / $TOTAL)%]\"\n}\n"
  },
  {
    "path": "misc/budge.ctags",
    "content": "#\n# In the future these should be preload'ed\n#\n"
  },
  {
    "path": "misc/ctags-optlib-mode.el",
    "content": ";;\n;;  Copyright (c) 2019, Red Hat, Inc.\n;;  Copyright (c) 2019, Masatake YAMATO\n;;\n;;  Author: Masatake YAMATO <yamato@redhat.com>\n;;\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 2\n;; of the License, or (at your option) any later version.\n;;\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n;;\n;; You should have received a copy of the GNU General Public License\n;; along with this program; if not, write to the Free Software\n;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n;; USA.\n\n(require 'generic)\n\n(defun ctags-optlib-mode-setup-function ()\n  (let ((st (syntax-table)))\n    (modify-syntax-entry ?\\' \".\" st)\n    (modify-syntax-entry ?\\\" \".\" st)))\n\n(define-generic-mode ctags-optlib-mode\n  '(?# ?%)\n  nil\n  '(;;\n    ;; Language\n    ;;\n    (\"^[[:space:]]*--\\\\(langdef\\\\)=\\\\([a-zA-Z0-9]+\\\\)\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t))\n    (\"^[[:space:]]*--\\\\(map\\\\|alias\\\\|_?prelude\\\\|_?scopesep\\\\|__selector\\\\)-\\\\([a-zA-Z0-9]+\\\\)=.*\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t))\n    ;;\n    ;; Kinds\n    ;;\n    (\"^[[:space:]]*--\\\\(kinddef\\\\)-\\\\([^=]+\\\\)=\\\\([a-zA-Z]\\\\),\\\\([a-zA-Z0-9]+\\\\),\\\\(.*\\\\)$\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-constant-face t)\n     (4 font-lock-variable-name-face t)\n     (5 font-lock-doc-face t))\n    (\"^[[:space:]]*--\\\\(kinds\\\\)-\\\\([^=]+\\\\)=[+-]?\\\\([a-zA-Z]+\\\\)\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-constant-face t))\n    ;;\n    ;; Singe line regex\n    ;;\n    (\"^[[:space:]]*--\\\\(regex\\\\)-\\\\([^=]+\\\\)=\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t))\n    ;;\n    ;; Mline regex\n    ;;\n    (\"^[[:space:]]*--\\\\(mline-regex\\\\)-\\\\([^=]+\\\\)=\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t))\n    ;;\n    ;; Mtable regex\n    ;;\n    (\"^[[:space:]]*--\\\\(_tabledef\\\\)-\\\\([^=]+\\\\)=\\\\([a-zA-Z0-9_]+\\\\)\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-function-name-face t)\n     )\n    (\"^[[:space:]]*--\\\\(_mtable-regex\\\\)-\\\\([^=]+\\\\)=\\\\([a-zA-Z0-9_]+\\\\)/\\\\(.*\\\\)$\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-function-name-face t)\n     (4 nil t))\n    (\"^[[:space:]]*--\\\\(_mtable-extend\\\\)-\\\\([^=]+\\\\)=\\\\([a-zA-Z0-9_]+\\\\)\\\\+\\\\([a-zA-Z0-9_]+\\\\)\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-function-name-face t)\n     (4 font-lock-function-name-face t))\n    ;;\n    ;; Fields\n    ;;\n    (\"^[[:space:]]*--\\\\(_fielddef\\\\)-\\\\([a-zA-Z0-9]+\\\\)=\\\\([a-zA-Z0-9]+\\\\),\\\\(.*\\\\)$\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-variable-name-face t)\n     (4 font-lock-doc-face t))\n    (\"^[[:space:]]*--\\\\(fields\\\\)-\\\\([a-zA-Z0-9]+\\\\)=.?{\\\\([a-zA-Z0-9]+\\\\)}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-variable-name-face t))\n    ;;\n    ;; Roles\n    ;;\n    (\"^[[:space:]]*--\\\\(_roledef\\\\)-\\\\([a-zA-Z0-9]+\\\\)\\\\.\\\\(?:\\\\([a-zA-Z]\\\\)\\\\|{\\\\([a-zA-Z0-9]+\\\\)}\\\\)=\\\\([a-zA-Z0-9]+\\\\),\\\\(.*\\\\)$\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-constant-face t t)\n     (4 font-lock-constant-face t t)\n     (5 font-lock-variable-name-face t)\n     (6 font-lock-doc-face t))\n    ;;\n    ;; Extras\n    ;;\n    (\"^[[:space:]]*--\\\\(_extradef\\\\)-\\\\([a-zA-Z0-9]+\\\\)=\\\\([a-zA-Z0-9]+\\\\),\\\\(.*\\\\)$\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-variable-name-face t)\n     (4 font-lock-doc-face t))\n    (\"^[[:space:]]*--\\\\(extras\\\\)-\\\\([a-zA-Z0-9]+\\\\)=.?{\\\\([a-zA-Z0-9]+\\\\)}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-variable-name-face t))\n    ;;\n    ;; Parameters\n    ;;\n    (\"^[[:space:]]*--\\\\(_?paramdef\\\\)-\\\\([a-zA-Z0-9]+\\\\)=\\\\([a-zA-Z0-9]+\\\\),\\\\(.*\\\\)\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t)\n     (3 font-lock-variable-name-face t)\n     (4 font-lock-doc-face t))\n    ;;\n    ;; Flags\n    ;;\n    (\".*{\\\\(tenter\\\\|tjump\\\\)=\\\\([a-zA-Z0-9_]+\\\\)}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-function-name-face t))\n    (\".*{\\\\(tenter\\\\)=\\\\([a-zA-Z0-9_]+\\\\)\\\\(,\\\\([a-zA-Z0-9_]+\\\\)\\\\)}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-function-name-face t)\n     (4 font-lock-function-name-face t))\n    (\"{\\\\(_field\\\\)=\\\\([a-zA-Z0-9_]+\\\\):[^}]+}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-variable-name-face t))\n    (\"{\\\\(_role\\\\)=\\\\([a-zA-Z0-9_]+\\\\)}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-constant-face t))\n    (\"{\\\\(_extra\\\\)=\\\\([a-zA-Z0-9_]+\\\\)}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-variable-name-face t))\n    (\"{\\\\(base\\\\)=\\\\([a-zA-Z0-9]+\\\\)}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t))\n    (\"{\\\\(_advanceTo\\\\)=[0-9]+\\\\(start\\\\|end\\\\)}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-builtin-face t))\n    (\"{\\\\(scope\\\\)=\\\\(pop\\\\|ref\\\\|set\\\\|push\\\\|clear\\\\)}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-builtin-face t))\n    (\"{\\\\(icase\\\\|exclusive\\\\|tleave\\\\|placeholder\\\\|tquit\\\\|mgroup\\\\|dedicated\\\\|shared\\\\|_trace\\\\)[^}]*}\"\n     (1 font-lock-keyword-face t))\n    (\"{\\\\(_anonymous=\\\\)[^}]*}\"\n     (1 font-lock-keyword-face t))\n    (\"{\\\\(_guest=\\\\)\\\\([^,]+\\\\)?[^}]*}\"\n     (1 font-lock-keyword-face t)\n     (2 font-lock-type-face t t))\n    (\"\\\\<[p]\\\\>\" . font-lock-keyword-face)\n    (\"/\\\\([a-zA-Z]\\\\)/\"\n     (1 font-lock-constant-face t))\n    (\"{{$\\\\|^}}\" . font-lock-preprocessor-face)\n    ;;\n    )\n  '(\"\\\\.ctags\\\\'\")\n  '(ctags-optlib-mode-setup-function)\n  \"Mode for editing .ctags optlib parser file\")\n\n(provide 'ctags-optlib-mode)\n"
  },
  {
    "path": "misc/debuggen/README",
    "content": "This directory contains scripts generating code for debugging parsers.\nCurrently running the scripts is not integrated to our build system.\nTherefore you must run the script manually when you add something\nto the parsers.\n"
  },
  {
    "path": "misc/debuggen/libdebuggen.sh",
    "content": "#!/bin/sh\n#\n# libdebuggen.sh - common code used in debuggen/*.sh scripts\n#\n# Copyright (C) 2026 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\nerror()\n{\n\techo \"$@\" 1>&2\n\texit 1\n}\n\nverify_ctags()\n{\n\tif ! [ -x ./ctags ]; then\n\t\terror \"call after building ctags\"\n\tfi\n}\n\nverify_topdir()\n{\n\tcase $(dirname \"$1\") in\n\t\tmisc/debuggen|./misc/debuggen)\n\t\t\t:\n\t\t\t;;\n\t\t*)\n\t\t\terror \"run $1 from the top of the ctags source tree\"\n\t\t\t;;\n\tesac\n}\n\ngen_header()\n{\n\tlocal script=$1\n\tlocal language=$(echo $2 | tr a-z A-Z)\n\n\techo \"/* Automatically generated by $script */\"\n\techo\n\techo \"#ifndef CTAGS_PARSER_DEBUG_${language}_H\"\n\techo \"#define CTAGS_PARSER_DEBUG_${language}_H\"\n\techo\n\techo '#ifdef DO_TRACING'\n\techo '#include \"vstring.h\"'\n\techo\n}\n\ngen_enumtbl()\n{\n\tmisc/enumstr.sh \"$@\"\n\techo\n}\n\ngen_decodeToken()\n{\n\tlocal tokenType=$1\n\tlocal typeMember=$2\n\tlocal decodeTypeFn=$3\n\tlocal typeKeyword=$4\n\tlocal keywordMember=$5\n\tlocal decodeKeywordFn=$6\n\n\techo \"static const char *decodeToken (const ${tokenType} *t)\"\n\techo '{'\n\techo '\tstatic vString *buf;'\n\techo '\tbuf = vStringNewOrClearWithAutoRelease (buf);'\n\techo '\tvStringCopyS (buf, \"type: \");'\n\techo \"\tvStringCatS (buf, ${decodeTypeFn} (t->${typeMember}));\"\n\tif [ \"${typeKeyword}\" != \"-\" ]; then\n\t\techo \"\tif (t->${typeMember} == ${typeKeyword})\"\n\t\techo '\t{'\n\t\techo '\t\tvStringCatS (buf, \", keyword: \");'\n\t\techo \"\t\tvStringCatS (buf, ${decodeKeywordFn} (t->${keywordMember}));\"\n\t\techo '\t}'\n\tfi\n\techo '\treturn vStringValue (buf);'\n\techo '}'\n\techo\n\n}\n\ngen_footer()\n{\n\tlocal language=$(echo $1 | tr a-z A-Z)\n\n\techo\n\techo '#endif /* DO_TRACING */'\n\techo \"#endif /* CTAGS_PARSER_DEBUG_${language}_H */\"\n}\n"
  },
  {
    "path": "misc/debuggen/rust.sh",
    "content": "#!/bin/sh\n#\n# debuggen/rust.sh - Generating decodeToken function for Rust parser\n#\n# Copyright (C) 2026 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\nset -e\n\n. misc/debuggen/libdebuggen.sh\n\nverify_topdir \"$0\"\nverify_ctags\n\nLANGUAGE=rust\nINPUT=./parsers/${LANGUAGE}.c\nOUTPUT=./parsers/d-${LANGUAGE}.h\n\n\nexec > ${OUTPUT}\n\ngen_header \"$0\" ${LANGUAGE}\n\ngen_enumtbl ${INPUT} eTokenType decodeTokenType TOKEN_\n\ngen_footer \"${LANGUAGE}\"\n"
  },
  {
    "path": "misc/debuggen/typescript.sh",
    "content": "#!/bin/sh\n#\n# debuggen/typescript.sh - Generating decodeToken function for TypeScript parser\n#\n# Copyright (C) 2026 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\nset -e\n\n. misc/debuggen/libdebuggen.sh\n\nverify_topdir \"$0\"\nverify_ctags\n\nLANGUAGE=typescript\nINPUT=./parsers/${LANGUAGE}.c\nOUTPUT=./parsers/d-${LANGUAGE}.h\n\n\nexec > ${OUTPUT}\n\ngen_header \"$0\" ${LANGUAGE}\n\ngen_enumtbl ${INPUT} eTokenType decodeTokenType TOKEN_\ngen_enumtbl ${INPUT} eKeywordId decodeKeywordId KEYWORD_\n\ngen_decodeToken \"tokenInfo\" \"type\" decodeTokenType \\\n\t\t\t\t\"TOKEN_KEYWORD\" \"keyword\" decodeKeywordId\n\ngen_footer \"${LANGUAGE}\"\n"
  },
  {
    "path": "misc/enumstr.sh",
    "content": "#!/bin/sh\n#\n# enumstr.sh - a tool generating a function mapping enumerator to its\n# string representation\n#\n# Copyright (C) 2019 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n# Usage:\n#\n#  ./enumstr.sh <input-file> <enum-name> <funname> [PREFIX_FOR_TRIMMING] [--use-lower-bits-as-is]\n#\n# Example:\n#\n#   bash ./misc/enumstr.sh parsers/jscript.c eTokenType tokenTypeName\n#\ncolumn_width=20\n\nINPUT_FILE=$1\nENUM_NAME=$2\nFUNNAME=$3\nshift 3\n\nprint_usage()\n{\n\techo Usage:\n\techo\n\techo \"  $0 <input-file> <enum-name> <funname> [PREFIX_FOR_TRIMMING] [OPTIONS]\"\n\techo \"  $0 --help|-h\"\n\techo\n\techo Options:\n\techo\n\techo \"  --use-lower-bits-as-is\"\n\techo \"  --extern\"\n\techo\n\techo Example:\n\techo\n\techo '  $ bash ./misc/enumstr.sh parsers/jscript.c eTokenType tokenTypeName'\n\texit $1\n}\n\nif [ -z \"$INPUT_FILE\" ] || [ -z \"$ENUM_NAME\" ] || [ -z \"$FUNNAME\" ] || \\\n\t   [ \"$INPUT_FILE\" = '-h' ] || [ \"$ENUM_NAME\" = '-h' ] || [ \"$FUNNAME\" = '-h' ] || \\\n\t   [ \"$INPUT_FILE\" = '--help' ] || [ \"$ENUM_NAME\" = '--help' ] || [ \"$FUNNAME\" = '--help' ]; then\n\tprint_usage 1 1>&2\nfi\n\nUSE_LOWER_BITS_AS_IS=\nSCOPE='static'\n\nwhile [ $# -gt 0 ]; do\n\tcase \"$1\" in\n\t\t--help|-h)\n\t\t\tprint_usage 0\n\t\t\t;;\n\t\t--use-lower-bits-as-is)\n\t\t\tUSE_LOWER_BITS_AS_IS=$1\n\t\t\tshift 1\n\t\t\t;;\n\t\t--extern)\n\t\t\tSCOPE=extern\n\t\t\tshift 1\n\t\t\t;;\n\t\t-*)\n\t\t\techo \"Unknown option: $1\" 1>&2\n\t\t\texit 1\n\t\t\t;;\n\t\t*)\n\t\t\tPREFIX_FOR_TRIMMING=$1\n\t\t\tshift 1\n\t\t\t;;\n\tesac\ndone\n\nprintf '%s const char *'\"%s\"'(enum '%s' e)\\n' \"$SCOPE\" \"$FUNNAME\" \"$ENUM_NAME\"\nprintf '{ /* Generated by misc/enumstr.sh with cmdline:\\n'\necho \"     $0 $INPUT_FILE $ENUM_NAME $FUNNAME $PREFIX_FOR_TRIMMING $USE_LOWER_BITS_AS_IS */\"\necho '\tswitch (e)'\necho '\t{'\n./ctags --quiet --options=NONE --sort=no -o - --languages=C --kinds-C=e --map-C=+.h -x --_xformat=\"%N enum:%s\" $INPUT_FILE | grep $ENUM_NAME | while read N S; do\n\tn=$N\n\tif [ -n \"$PREFIX_FOR_TRIMMING\" ]; then\n\t\tn=${N#$PREFIX_FOR_TRIMMING}\n\tfi\n\tprintf \"\t\tcase %${column_width}s: return %s;\\n\" \"$N\" \"\\\"$n\\\"\"\ndone\n\nif [ -n \"$USE_LOWER_BITS_AS_IS\" ]; then\n\tprintf '\t\tdefault: %'\"$((${column_width} + 3))s;\\n\" \"break\"\nelse\n\tprintf '\t\tdefault: %'\"$((${column_width} - 3))s return %s;\\n\" ' ' \"\\\"UNKNOWN\\\"\"\nfi\necho '\t}'\nif [ -n \"$USE_LOWER_BITS_AS_IS\" ]; then\necho '\tstatic char buf[3];'\necho '\tif (isprint (e))'\necho '\t{'\necho '\t\tbuf[0] = e;'\necho \"\t\tbuf[1] = '\\0';\"\necho '\t}'\necho \"\telse if (e == '\\\\n')\"\necho '\t{'\necho \"\t\tbuf[0] = '\\\\\\';\"\necho \"\t\tbuf[1] = 'n';\"\necho \"\t\tbuf[2] = '\\0';\"\necho '\t}'\necho '\telse'\necho '\t{'\necho \"\t\tbuf[0] = '\\0';\"\necho '\t}'\necho '\treturn buf;'\nfi\necho '}'\n"
  },
  {
    "path": "misc/gen-repoinfo",
    "content": "#!/bin/sh\n\nif [ -z $1 ]; then\n\techo Usage: $0 headerfile\n\texit 1\nfi\nrinfoheader=$1\n\noldinfo=\nif [ -f $rinfoheader ]; then\n\toldinfo=`cat $rinfoheader`\nelse\n\techo > $rinfoheader\nfi\n\nrinfo=`git describe --tag --exact-match HEAD 2> /dev/null || git rev-parse --short HEAD`\nnewinfo=\"#define CTAGS_REPOINFO \\\"${rinfo}\\\"\"\n\nif [ \"$newinfo\" != \"$oldinfo\" ]; then\n\techo \"$newinfo\" > $rinfoheader\nfi\n"
  },
  {
    "path": "misc/gencxxtypedumper.sh",
    "content": "#!/bin/sh\n#\n# gencxxtypedumper - Generating cxxDebugTypeDecode function\n#\n# Copyright (C) 2014 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\nINPUT=./parsers/cxx/cxx_token.h\nCTAGS=./ctags\nOUTPUT=./parsers/cxx/cxx_debug_type.c\n\nexec > ${OUTPUT}\necho '/* Automatically generated by misc/gencxxtypedumper.sh */'\necho\necho '#include \"cxx_token.h\"'\necho '#include \"cxx_debug.h\"'\necho\necho '#ifdef CXX_DO_DEBUGGING'\necho \"static bool append(vString *buf, const char *str, bool appended)\"\necho \"{\"\necho \"\tif (appended) vStringPut(buf, ' ');\"\necho \"\tvStringCatS (buf, str);\"\necho \"\treturn true;\"\necho \"}\"\necho\necho 'const char * cxxDebugTypeDecode (enum CXXTokenType eType)'\necho '{'\necho '\tbool a = false;'\necho '\tstatic vString *buf;'\necho '\tbuf = vStringNewOrClearWithAutoRelease (buf);'\necho\n${CTAGS} -o - --sort=no --language-force=C --kinds-C=e -x --_xformat=\"%N\" \"${INPUT}\" \\\n\t| grep ^CXXTokenType \\\n\t| while read N; do\n\t\techo \"\tif (eType & $N) a = append (buf, \\\"${N#CXXTokenType}\\\", a);\"\ndone\necho '\tif (vStringLength(buf) == 0) vStringCatS(buf, \"REALLY-UNKNOWN\");'\necho '\treturn vStringValue (buf);'\necho '}'\necho '#endif'\n"
  },
  {
    "path": "misc/git-tag-maybe.sh",
    "content": "#!/bin/sh\n\nBASE=6.2\n\nset -e\n\n##################################### util #######################################\n\nCOLOR_RED='\\033[0;31m'          # Red\nCOLOR_GREEN='\\033[0;32m'        # Green\nCOLOR_PURPLE='\\033[0;35m'       # Purple\nCOLOR_OFF='\\033[0m'             # Reset\n\nnote() {\n    printf '\\n%b\\n' \"${COLOR_RED}$*${COLOR_OFF}\"\n}\n\nrun() {\n    printf '%b\\n' \"${COLOR_PURPLE}==>${COLOR_OFF} ${COLOR_GREEN}$*${COLOR_OFF}\"\n    eval \"$*\"\n}\n\n##################################### main #######################################\n\nbase=$BASE\ncal=$(date +%Y%m%d)\nchicken=0\nnew_tagname=\"p${base}.${cal}.${chicken}\"\n\nrun git --version\n\ncase \"$(git describe --tags --exact-match HEAD 2>/dev/null || true)\" in\n    p*.0)\n        note \"do nothing. because there are no commits since the latest tag.\"\n        exit 0\n        ;;\n    '') ;;\n    *)  echo \"found a tag but it is not periodical one; create a periodical tag\"\nesac\n\nfor old_tagname in $(git tag --list)\ndo\n    if [ \"$old_tagname\" = \"$new_tagname\" ] ; then\n        note \"do nothing. because $new_tagname tag already exists.\"\n        exit 0\n    fi\ndone\n\nrun git tag \"$new_tagname\"\nrun git push origin \"$new_tagname\"\n"
  },
  {
    "path": "misc/hasbom",
    "content": "#!/bin/sh\ntest \"$(od --endian=big -x -A n -N 3 $1)\" = \" efbb bf00\"\n"
  },
  {
    "path": "misc/man-test.py",
    "content": "#!/usr/bin/env python3\n\n#\n# man-test.py - test exapmles in a man page\n#\n# Copyright (C) 2021 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#\n# Python 3.5 or later is required.\n# On Windows, unix-like shell (e.g. bash) and diff command are needed.\n#\n\nimport sys\nimport re\nimport os\nimport subprocess\nimport copy\n\ndef print_usage(n, f):\n    print ('Usage: man-test.py TMPDIR CTAGS ctags-lang-<LANG>.7.rst.in...', file=f)\n    sys.exit(n)\n\ndef next_segment(line):\n    if line.endswith ('\\\\'):\n        return line[0:-1]\n    else:\n        return (line + '\\n')\n\ndef wash_cmdline(cmdline):\n    return cmdline\n\ndef verify_test_case(t):\n    prefix = '%(man_file)s[%(nth)d]:%(start_linum)d: '%t\n    msg = False\n    if not 'code' in t:\n        msg = 'cannot find input lines'\n    elif not 'tags' in t:\n        msg = 'cannot find expected tags output'\n    elif not 'cmdline' in t:\n        msg = 'cannot find ctags command line'\n\n    if msg:\n        msg = prefix + msg\n    return msg\n\ndef is_option(c):\n    if re.search('--[a-z_].*', c):\n        return True\n    elif re.search('^-[a-z]$', c):\n        return True\n    return False\n\ndef run_test_case(tmpdir, ctags, t):\n    d = tmpdir + '/' + str(os.getpid())\n    os.makedirs (d,exist_ok=True)\n    i = d + '/' + t['input_file_name']\n    o0 = 'actual.tags'\n    o = d + '/' + o0\n    e0 = 'expected.tags'\n    e = d + '/' + e0\n    D = d + '/' + 'tags.diff'\n    O0 = 'args.ctags'\n    O = d + '/' + O0\n    with open(i, mode='w', encoding='utf-8') as f:\n        f.write(t['code'])\n\n    with open(e, mode='w', encoding='utf-8') as g:\n        g.write(t['tags'])\n\n    inputf=None\n    with open(O, mode='w', encoding='utf-8') as Of:\n        in_pattern = False\n        for c in t['cmdline'].split():\n            if c == '--options=NONE':\n                continue\n            elif c.startswith('input.'):\n                inputf = c\n                continue\n            elif c.startswith('--regex-'):\n                in_pattern = c\n            elif in_pattern and not is_option(c):\n                # TODO: This doesn't work if whitespace is repeated.\n                in_pattern = in_pattern + ' ' + c\n            else:\n                if in_pattern:\n                    print (in_pattern, file=Of)\n                    in_pattern = False\n                print (c, file=Of)\n        if in_pattern:\n            print (in_pattern, file=Of)\n\n    with open(o, mode='w', encoding='utf-8') as h:\n        cmdline = [ctags, '--quiet', '--options=NONE',\n                   '--options=' + O0, inputf]\n        subprocess.run(cmdline, cwd=d, stdout=h)\n\n    with open(D, mode='w', encoding='utf-8') as diff:\n        r = subprocess.run(['diff', '-uN', '--strip-trailing-cr', o0, e0],\n                           cwd=d, stdout=diff).returncode\n\n    if r == 0:\n        t['result'] = True\n        t['result_readable'] = 'passed'\n    else:\n        with open(o, encoding='utf-8') as f:\n            t['actual_tags'] = f.read()\n        t['result'] = False\n        t['result_readable'] = 'failed'\n        with open(D, encoding='utf-8') as diff:\n            t['tags_diff'] = diff.read()\n    os.remove(O)\n    os.remove(i)\n    os.remove(e)\n    os.remove(o)\n    os.remove(D)\n    os.rmdir(d)\n    return t\n\ndef report_result(r):\n    print ('%(man_file)s[%(nth)d]:%(start_linum)d...%(result_readable)s'%r)\n\ndef report_failure(r):\n    print ('## %(man_file)s[%(nth)d]:%(start_linum)d'%r)\n    print ('### input')\n    print ('```')\n    print (r['code'])\n    print ('```')\n    print ('### cmdline')\n    print ('```')\n    print (r['cmdline'])\n    print ('```')\n    print ('### expected tags')\n    print ('```')\n    print (r['tags'])\n    print ('```')\n    print ('### actual tags')\n    print ('```')\n    print (r['actual_tags'])\n    print ('```')\n    print ('### diff of tag files')\n    print ('```')\n    print (r['tags_diff'])\n    print ('```')\n\nclass state:\n    start = 0\n    tags  = 1\n    code  = 2\n    code_done = 3\n    input = 4\n    output = 5\n    output_after_options = 6\n\ndef extract_test_cases(f):\n    linum=0\n    nth=0\n    s=state.start\n    test_spec = {}\n\n    for line in  f.readlines():\n        linum += 1\n        line = line.rstrip('\\r\\n')\n\n        if s == state.tags or s == state.code:\n            if prefix:\n                m = re.search('^' + prefix + '(.*)$', line)\n                if m:\n                    sink += next_segment(m.group(1))\n                    continue\n                if line == '':\n                    sink += '\\n'\n                    continue\n            else:\n                m = re.search('^([ \\t]+)(.+)$', line)\n                if m:\n                    prefix = m.group(1)\n                    sink += next_segment(m.group(2))\n                    continue\n                elif re.search ('^([ \\t]*)$', line):\n                    continue\n\n            sink = sink.rstrip('\\r\\n') + '\\n'\n\n            if s == state.code:\n                test_spec['code'] = sink\n                s = state.code_done\n            else:\n                test_spec['tags'] = sink\n                test_spec['nth'] = nth\n                nth += 1\n                test_spec['end_linum'] = linum\n                s = state.start\n                yield test_spec\n\n        m = s == state.start and re.search ('^\"(input\\\\.[^\"]+)\"$', line)\n        if m:\n            test_spec ['start_linum'] = linum\n            test_spec ['input_file_name'] = m.group(1)\n            s = state.input\n            continue\n        m = s == state.input and re.search ('^.. code-block::.*', line)\n        if m:\n            sink = ''\n            prefix = False\n            s = state.code\n            continue\n        m = s == state.code_done and re.search ('^\"output.tags\"$', line)\n        if m:\n            s = state.output\n            continue\n        m = s == state.output and re.search ('with[ \\t]\"([^\"]+)\"', line)\n        if m:\n            test_spec ['cmdline'] = wash_cmdline (m.group(1))\n            s = state.output_after_options\n            continue\n        if s == state.output_after_options \\\n           and (line == \"::\" or re.search ('^.. code-block:: *tags$', line)):\n            sink = ''\n            prefix = False\n            s = state.tags\n            continue\n\ndef extract_features (f):\n    for line in  f.readlines():\n        line = line.rstrip('\\r\\n')\n        m = re.search(':Expected feature:[ \\t]*([a-zA-Z0-9-_]+)', line)\n        if m:\n            yield m.group(1)\n        continue\n\n# Taken from misc/units.py\ndef has_feature (ctags, feat):\n    ret = subprocess.run([ctags, '--quiet', '--options=NONE',\n                          '--list-features', '--with-list=no'],\n                         stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\n    if feat in re.sub(r'(?m)^([^ ]+).*$', r'\\1',\n                      ret.stdout.decode('utf-8')).splitlines():\n        return True\n    return False\n\ndef report_skip(man_file, feat):\n    print ('%s[feat]:%s...skipped' % (man_file, feat))\n\ndef man_test (tmpdir, ctags, man_file):\n    failures = []\n    result = True\n    print ('# Run test cases in ' + man_file)\n    print ('```')\n    with open(man_file, encoding='utf-8') as f:\n        for x in extract_features (f):\n            if not has_feature(ctags, x):\n                report_skip(man_file, x)\n                print ('```')\n                return True\n        f.seek(0)\n        for t in extract_test_cases (f):\n            t['man_file'] = man_file\n            v = verify_test_case (t)\n            if v:\n                print (\"error: \" + v, file=sys.stderr)\n                result = False\n                continue\n            r = run_test_case (tmpdir, ctags, t)\n            report_result (r)\n            if not r['result']:\n                result = False\n                failures.append(copy.copy(r))\n    print ('```')\n    if (len(failures) > 0):\n        print ('# Failed test case(s)')\n        for f in failures:\n            report_failure(f)\n    return result\n\ndef man_tests (tmpdir, ctags, man_files):\n    result = 0\n    for m in man_files:\n        if not man_test(tmpdir, ctags, m):\n            result += 1\n    print ('OK' if result == 0 else 'FAILED')\n    return result == 0\n\nif (len(sys.argv) < 4) or (sys.argv[1] == '-h' or sys.argv[1] == '--help'):\n    print_usage (2, sys.stderr)\n\ntmpdir = sys.argv[1]\nctags = os.path.abspath(sys.argv[2])\nsys.exit(0 if man_tests (tmpdir, ctags, sys.argv[3:]) else 1)\n"
  },
  {
    "path": "misc/mg++",
    "content": "#!/bin/sh\n#\n# mg++ - testing whether g++ accepts an input with multiple C++ standards\n#\n# Copyright (C) 2014 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\nhelp()\n{\n    echo Usage: \"$0\" \"input.cpp\" 1>&2\n    exit $1\n}\n\nif [ $# = 0 ]; then\n    help 1 1>&2\nelif [ $1 = \"-h\" ] || [ $1 = \"--help\" ]; then\n    help 0\nfi\n\nif ! type g++ > /dev/null; then\n    echo \"No g++ found\" 1>&2\n    exit 1\nfi\n\nif ! [ -f $1 ]; then\n    echo \"No such file: $1\" 1>&2\n    exit 1\nfi\n\nSTDS=\"\nc++03\ngnu++03\nc++11\ngnu++11\nc++14\ngnu++14\nc++17\ngnu++17\nc++20\ngnu++20\nc++23\ngnu++23\n\"\n\ndummy=/tmp/input-$$.cpp\ncat > $dummy <<EOF\n// dummy input for mg++\nint main (void)\n{\n  return 0;\n}\nEOF\n\nfor s in $STDS; do\n    if ! g++ -fsyntax-only -c --std=$s -c $dummy; then\n\techo \"*** this g++ doesn't support --std=$s option\"\n\tcontinue\n    fi\n\n    printf \"%s...\" \"*** compile with --std=$s\"\n    LOG=$(g++ -fsyntax-only -c --std=$s $1 2>&1)\n    if [ $? = 0 ]; then\n\techo ok\n    else\n\techo error\n\techo \"$LOG\"\n\techo -----------------------------------\n    fi\ndone\n\nrm -f $dummy\n"
  },
  {
    "path": "misc/mini-geany.expected",
    "content": "This parser only parses C files - provide them as arguments on the command line or get a hard-coded buffer parsed when no arguments are provided\n\nWe are parsing C which provides the following kinds:\nd: macro\ne: enumerator\nf: function\ng: enum\nh: header\nl: local\nm: member\np: prototype\ns: struct\nt: typedef\nu: union\nv: variable\nx: externvar\nz: parameter\nL: label\nD: macroparam\n\nParsing buffer:\nfoo\tline: 1\tkind: function\t lang: C\nbar\tline: 3\tkind: function\t lang: C\nmain\tline: 5\tkind: function\t lang: C\n"
  },
  {
    "path": "misc/mk-interactive-request.sh",
    "content": "#!/bin/sh\n#\n# Taken from Tmain/interactive-mode.d/run.sh\n# Making requests for ctags running in interactive-mode\n#\n# e.g.\n# $ bash misc/mk-interactive-request.sh main/main.c | ./ctags --_interactive -o -\n#\nfilesize()\n{\n    wc -c < \"$1\"\n}\n\nfor f in \"$@\"; do\n\tif [ -f \"$f\" ]; then\n\t\tsize=$(filesize \"$f\")\n\t\techo '{\"command\":\"generate-tags\", \"filename\":\"'\"$f\"'\", \"size\":'\"$size\"'}'\n\t\tcat \"$f\"\n\telse\n\t\techo \"no such file: $f\" 1>&2\n\tfi\ndone\n"
  },
  {
    "path": "misc/news.bash",
    "content": "#!/bin/bash\n#\n# news.bash - enumerate the titles of issues and pull-requests closed between FROM..TO\n#\n# Copyright (C) 2023 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\nFROM=v6.1.0\nTO=.\nPROJ=universal-ctags\nREPO=ctags\n\nargs=(\"$@\")\n\npr_title()\n{\n    local N=$1\n    curl --no-progress-meter https://github.com/${PROJ}/${REPO}/pull/\"$N\" | grep '^  <title>' | \\\n\tsed -e 's!^[[:space:]]*<title>\\(.\\+Pull Request #[0-9]*\\).*</title>$!* \\1!' | \\\n\tsed -e \"s/&#39;/'/g\" -e 's/&amp;/\\&/g' -e 's/&quot;/\"/g' -e 's/&gt;/>/g' -e 's/&lt;/</g'\n}\n\nissue_title()\n{\n    local N=$1\n    curl --no-progress-meter https://github.com/${PROJ}/${REPO}/issues/\"$N\" | grep '^  <title>' | \\\n\tsed -e 's!^[[:space:]]*<title>\\(.\\+Issue #[0-9]*\\).*</title>$!* \\1!' | \\\n\tsed -e \"s/&#39;/'/g\" -e 's/&amp;/\\&/g' -e 's/&quot;/\"/g' -e 's/&gt;/>/g' -e 's/&lt;/</g'\n}\n\nusage()\n{\n    printf \"\t%s help|--help|-h\\n\" \"$0\"\n    printf \"\t%s pr [#]\\n\" \"$0\"\n    printf \"\t%s issue [#]\\n\" \"$0\"\n    printf \"\t%s man\\n\" \"$0\"\n}\n\nif [[ $# == 0 ]]; then\n    usage 1>&2\n    exit 1\nfi\n\ncase $1 in\n    (help|--help|-h)\n\tusage 1>&2\n\texit 0\n\t;;\n    (pr)\n\tshift\n\tif [[ $1 =~ [0-9]+ ]]; then\n\t    pr_title \"$1\"\n\t    exit 0\n\telse\n\t    echo\n\t    echo \".. generated by $0 ${args[@]}\" \"[$FROM..$TO]\"\n\t    echo\n\t    git log --oneline ${FROM}..${TO} \\\n\t\t| grep '[0-9a-f]\\+ Merge pull request #[0-9]\\+.*' \\\n\t\t| sed -ne 's/.*#\\([0-9]\\+\\) from.*/\\1/p' | while read N; do\n\t\tpr_title \"$N\"\n\t    done\n\t    exit 0\n\tfi\n\t;;\n    (issue)\n\tshift\n\tif [[ $1 =~ [0-9]+ ]]; then\n\t    issue_title \"$1\"\n\t    exit 0\n\telse\n\t    echo\n\t    echo \".. generated by $0 ${args[@]}\" \"[$FROM..$TO]\"\n\t    echo\n\t    git log ${FROM}..${TO} \\\n\t\t| sed -ne 's/^[[:space:]]*\\(Partially\\)\\?[[:space:]]*\\(closed\\?\\|fix\\(ed\\)\\?\\) *#\\([0-9]\\+\\).*/\\4 (\\1)/Ip' \\\n\t\t| sed -e  's/()//' | while read N; do\n\t\tissue_title $N\n\t    done | uniq\n\tfi\n\t;;\n    (man)\n\tgit diff ${FROM}..${TO} man/*.in\n\t;;\nesac\n"
  },
  {
    "path": "misc/optlib2c",
    "content": "#!/usr/bin/env perl\n#\n# optlib2c - a tool translating ctags option file to C\n#\n# Copyright (C) 2016 Masatake YAMATO\n# Copyright (C) 2016 Red Hat Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\nuse strict;\nuse warnings;\n#use Data::Dumper;\n#print Dumper(X);\n\nsub show_help {\n    print<<EOF;\nUsage:\n\t$0 --help\n\t$0 FILE.ctags > FILE.c\nEOF\n}\n\n\n########################################################################\n#\n# PARSE\n#\n########################################################################\nmy $langdef_flags =\n    [\n     [ qr/\\{base=([^\\}]+)\\}/, sub {\n\t $_[0]->{'base'} = $1;\n       } ],\n     [ qr/\\{(dedicated|shared|bidirectional)\\}/, sub {\n\t $_[0]->{'direction'} = $1;\n       } ],\n     [ qr/\\{_autoFQTag\\}/, sub {\n\t $_[0]->{'autoFQTag'} = 1;\n       } ],\n     [ qr/\\{version=([0-9]+)\\.([0-9]+)\\}/, sub {\n\t $_[0]->{'versionCurrent'} = $1;\n\t $_[0]->{'versionAge'} = $2;\n       } ],\n     [ qr/\\{_foreignLanguage=([^}]+)\\}/, sub {\n\t push @{$_[0]->{'foreignLanguages'}}, $1;\n       } ],\n    ];\n\nmy $kinddef_flags =\n    [\n     [ qr/\\{_refonly\\}/, sub {\n\t $_[0]->{'refonly'} = 1;\n       } ],\n     [ qr/\\{version=([0-9]+)\\}/, sub {\n\t $_[0]->{'version'} = $1;\n       } ],\n    ];\n\nmy $roledef_flags =\n    [\n     [ qr/\\{version=([0-9]+)\\}/, sub {\n\t $_[0]->{'version'} = $1;\n       } ],\n    ];\n\nmy $fielddef_flags =\n    [\n     [ qr/\\{datatype=([^\\}]+)\\}/, sub {\n\t my $datatype = \"FIELDTYPE_SCRIPTABLE|\";\n\n\t if ($1 eq 'str')\n\t {\n\t     $datatype .= \"FIELDTYPE_STRING\";\n\t }\n\t elsif ($1 eq 'int')\n\t {\n\t     $datatype .= \"FIELDTYPE_INTEGER\";\n\t }\n\t elsif ($1 eq 'bool')\n\t {\n\t     $datatype .= \"FIELDTYPE_BOOL\";\n\t }\n\t elsif ($1 eq 'str+bool')\n\t {\n\t     $datatype .= \"FIELDTYPE_STRING|FIELDTYPE_BOOL\";\n\t }\n\t elsif ($1 eq 'bool+str')\n\t {\n\t     die \"\\\"{datatype=$1}\\\": use str+bool instead of bool+str\";\n\t }\n\t else\n\t {\n\t     die \"Unknown datatype specification: \\\"{datatype=$1}\\\" in \\\"--_fielddef-<LANG>=...\\\"\";\n\t }\n\n\t $_[0]->{'datatype'} = $datatype;\n       } ],\n     [ qr/\\{version=([0-9]+)\\}/, sub {\n\t $_[0]->{'version'} = $1;\n       } ],\n    ];\n\nmy $extradef_flags =\n    [\n     [ qr/\\{version=([0-9]+)\\}/, sub {\n\t $_[0]->{'version'} = $1;\n       } ],\n    ];\n\nmy $options =\n    [\n     [ qr/^--options=(.*)/, sub {\n\t   parse_optlib ($1, $_[0]);\n\t   return 1;\n       } ],\n     [ qr/^--__selector-(.*)=(.*)/, sub {\n\t die \"Don't use --__selector-<LANG>= option before defining the language\"\n\t     if (! defined $_[0]->{'langdef'});\n\t $_[0]->{'selector'} = $2;\n\t return 1;\n       } ],\n     [ qr/^--langdef=([^\\{]+)(.*)/, sub {\n\t   die \"LANG is already defined as $_[0]->{'langdef'}: $1\"\n\t       if (defined $_[0]->{'langdef'});\n\t   die \"Don't use \\\"all\\\" as a language name. It is reserved word.\"\n\t       if ($1 eq \"all\");\n\t   die \"Don't use \\\"all\\\" as a language name. It is reserved word.\"\n\t       if ($1 eq \"NONE\");\n\n\t   $_[0]->{'langdef'} = $1;\n\t   my $rest = $2;\n\n\t   die \"Don't use a character as a language name other than alphanumeric, # and +: \"\n\t       . $_[0]->{'langdef'} unless ($_[0]->{'langdef'} =~ /^[a-zA-Z0-9#+]+$/);\n\n\t   $_[0]->{'autoFQTag'} = 0;\n\t   $_[0]->{'versionCurrent'} = 0;\n\t   $_[0]->{'versionAge'} = 0;\n\t   $_[0]->{'foreignLanguages'} = [];\n\t   parse_flags ($rest, $_[0], $langdef_flags);\n\n\t   return 1;\n       } ],\n     [ qr/^--kinddef-(.*)=([^,]),([^,]+),([^\\{]+)(.*)/, sub {\n\t die \"Don't use --kinddef-<LANG>=+ option before defining the language\"\n\t     if (! defined $_[0]->{'langdef'});\n\t die \"Adding a kind is allowed only to the language specified with --langdef: $1\"\n\t     unless ($_[0]->{'langdef'} eq $1);\n\n\t my $letter = $2;\n\t my $name = $3;\n\t my $desc = $4;\n\t my $rest = $5;\n\n\t die \"'F' as a kind letter is reserved for file kind.\"\n\t     if ($letter eq 'F');\n\t die \"unacceptable character is used for kind letter: $letter\"\n\t     unless ($letter =~ /^[a-zA-EG-Z]$/);\n\n\t die \"'file' as a kind name is reserved\"\n\t     if ($name eq 'file');\n\t die \"The initial letter of kind name must be alphabetic character: $name\"\n\t     unless (substr ($name, 0, 1) =~ /[a-zA-Z]/);\n\t die \"Letters used in kind name other than initial letter must be alphanumeric characters: $name\"\n\t     unless (substr ($name, 1) =~ /^[a-zA-Z0-9]+$/);\n\n\t my $kdef = { enabled => 1, letter => $letter, name => $name, desc => $desc,\n\t\t      refonly => 0, roles => [], seps => [], version => 0 };\n\t push @{$_[0]->{'kinddefs'}}, $kdef;\n\t parse_flags ($rest, $kdef, $kinddef_flags);\n\n\t return 1;\n       } ],\n     [ qr/^--_extradef-(.*)=([^,]+),([^\\{]+)(.*)/, sub {\n\t die \"Don't use --_extradef-<LANG>=+ option before defining the language\"\n\t     if (! defined $_[0]->{'langdef'});\n\t die \"Adding an extra is allowed only to the language specified with --langdef: $1\"\n\t     unless ($_[0]->{'langdef'} eq $1);\n\n\t my $name = $2;\n\t my $desc = $3;\n\t my $rest = $4;\n\n\t die \"unacceptable character is used for extra name: $name\"\n\t     unless ($name =~ /^[a-zA-Z0-9]+$/);\n\n\t my $xdef = { name => $name, desc => $desc, version => 0, };\n\t push @{$_[0]->{'extradefs'}}, $xdef;\n\t parse_flags ($rest, $xdef, $extradef_flags);\n\t return 1;\n       } ],\n     [ qr/^--_fielddef-(.*)=([^,]+),([^\\{]+)(.*)/, sub {\n\t die \"Don't use --_fielddef-<LANG>=+ option before defining the language\"\n\t     if (! defined $_[0]->{'langdef'});\n\t die \"Adding a field is allowed only to the language specified with --langdef: $1\"\n\t     unless ($_[0]->{'langdef'} eq $1);\n\n\t my $name = $2;\n\t my $desc = $3;\n\t my $rest = $4;\n\t die \"unacceptable character is used for field name: $name\"\n\t     unless ($name =~ /^[a-zA-Z]+$/);\n\n\t my $fdef = { name => $name, desc => $desc, version => 0 };\n\t push @{$_[0]->{'fielddefs'}}, $fdef;\n\t parse_flags ($rest, $fdef, $fielddef_flags);\n\n\t return 1;\n       } ],\n     [ qr/^--_roledef-([^.]*)\\.(?:([a-zA-Z])|\\{([a-zA-Z][a-zA-Z0-9]*)\\})=([a-zA-Z0-9]+),([^\\{]+)(.*)/, sub {\n\t   die \"Don't use --_roledef-<LANG>.<KNID>=+ option before defining the language\"\n\t     if (! defined $_[0]->{'langdef'});\n\t   die \"Adding a field is allowed only to the language specified with --langdef: $1\"\n\t     unless ($_[0]->{'langdef'} eq $1);\n\n\t   my $kind_found = 0;\n\t   for (@{$_[0]->{'kinddefs'}}) {\n\t       if ((defined $2 && $_->{'letter'} eq $2)\n\t\t   || (defined $3 && $_->{'name'} eq $3)) {\n\t\t   my $role = { enabled => 1, name => $4, desc => $5, owner => $_, version => 0 };\n\t\t   push @{$_->{'roles'}}, $role;\n\t\t   $kind_found = 1;\n\n\t\t   my $rest = $6;\n\t\t   parse_flags ($rest, $role, $roledef_flags);\n\n\t\t   last;\n\t       }\n\t   }\n\t   my $k;\n\t   $k = $2 if defined $2;\n\t   $k = $3 if defined $3;\n\t   die \"no such kind, \\\"$k\\\" where role \\\"$4\\\" is attached to\" if (! $kind_found);\n\t   return 1;\n       } ],\n     [ qr/^--roles-([^.]+)\\.(?:([a-zA-Z])|\\{([a-zA-Z][a-zA-Z0-9]*)\\})=-(.*)/, sub {\n\t   die \"Don't use --roles-<LANG>.<KIND>= option before defining the language\"\n\t       if (! defined $_[0]->{'langdef'});\n\t   my $kind;\n\t   my $kletter = $2;\n\t   my $kname = $3;\n\t   my $roles = $4;\n\n\t   for my $k (@{$_[0]->{'kinddefs'}}) {\n\t       if (defined $kletter && $k->{'letter'} eq $kletter\n\t\t   || defined $kname && $k->{'name'} eq $kname) {\n\t\t   $kind = $k;\n\t\t   last;\n\t       }\n\t   }\n\t   die \"Don't use --roles-<LANG>.<KIND>= option before defined the kind\"\n\t       if (! defined $kind);\n\n\t   if ($roles =~ /^{(.*)}$/) {\n\t       $roles = $1;\n\t   } else {\n\t       die \"The roles in --roles-<LANG>.<KIND>=-<ROLES> must be surrounded by '{' and '}'\";\n\t   }\n\t   my @rolesa = split /\\}\\{/, $roles;\n\n\t   parse_roles ($kind, \\@rolesa, $_[0]);\n\t   return 1;\n       } ],\n     [ qr/^--roles-([^.]+)\\.([^=]+)=(.*)/, sub {\n\t   die \"--roles-<LANG>.<KIND>= can be used only for disabling a role: $2\";\n       } ],\n     [ qr/^--languages=-(.*)/, sub {\n\t   die \"Don't use --languages=- option before defining the language\"\n\t       if (! defined $_[0]->{'langdef'});\n\t   die \"Only language specified with --langdef can be disabled: $1\"\n\t       unless ($_[0]->{'langdef'} eq $1);\n\t   $_[0]->{'disabled'} = 1;\n\t   return 1;\n       } ],\n     [ qr/^--language=(.*)/, sub {\n\t   die \"--languages can be used only for disabling a language defined with --langdef: $1\";\n       } ],\n     [ qr/^--map-([^=]*)=\\+(.*)/, sub {\n\t   die \"Don't use --map-<LANG>=+ option before defining the language\"\n\t       if (! defined $_[0]->{'langdef'});\n\t   die \"Adding a map is allowed only to the language specified with --langdef: $1\"\n\t       unless ($_[0]->{'langdef'} eq $1);\n\t   my $spec = $2;\n\t   if ($spec =~ /%(.+?)%(i|\\{icase\\})?/) {\n\t       # TODO: handle \\% in the regular expression.\n\t       my $rexpr = { expr => $1,\n\t\t\t     iCase => (defined $2 && ($2 eq 'i' || $2 eq '{icase}'))? 1: 0 };\n\t       push @{$_[0]->{'rexprs'}}, $rexpr;\n\t   } elsif ($spec =~ /\\((.*)\\)/) {\n\t       push @{$_[0]->{'patterns'}}, $1;\n\t   } elsif ($spec =~ /\\.(.*)/) {\n\t       push @{$_[0]->{'extensions'}}, $1;\n\t   } else {\n\t       die \"Unexpected notation is used in the argument for --map-$1= option\";\n\t   }\n\t   return 1;\n       } ],\n     [ qr/^--map-([^=]*)=[^+].*/, sub {\n\t   die \"map manipulation other than the appending(--map-<LANG>=+...) is not supported\";\n       } ],\n     [ qr /^--alias-([^=]*)=\\+(.*)/, sub {\n\t   die \"Don't use --alias-<LANG>=+ option before defining the language\"\n\t       if (! defined $_[0]->{'langdef'});\n\t   die \"Adding an alias is allowed only to the language specified with --langdef: $1\"\n\t       unless ($_[0]->{'langdef'} eq $1);\n\t   push @{$_[0]->{'aliases'}}, $2;\n\t   return 1;\n       } ],\n     [ qr/^--alias-([^=]*)=[^+].*/, sub {\n\t   die \"alias manipulation other than the appending(--alias-<LANG>=+...) is not supported\";\n       } ],\n     [ qr/^--regex-([^=]*)=(.*)/, sub {\n\t   die \"Don't use --regex-<LANG>= option before defining the language\"\n\t       if (! defined $_[0]->{'langdef'});\n\t   die \"Adding a regex is allowed only to the language specified with --langdef: $1\"\n\t       unless ($_[0]->{'langdef'} eq $1);\n\t   return parse_regex ($2, $_[0], 0);\n       } ],\n     [ qr/^--mline-regex-([^=]*)=(.*)/, sub {\n\t   die \"Don't use --mline-regex-<LANG>= option before defining the language\"\n\t       if (! defined $_[0]->{'langdef'});\n\t   die \"Adding a multiline regex is allowed only to the language specified with --langdef: $1\"\n\t       unless ($_[0]->{'langdef'} eq $1);\n\t   return parse_regex ($2, $_[0], 1);\n       } ],\n     [ qr/^--kinds-([^=]*)=-(.*)/, sub {\n\t   die \"Don't use --kinds-<LANG>= option before defining the language\"\n\t       if (! defined $_[0]->{'langdef'});\n\t   parse_kinds ($2, $_[0]);\n\t   return 1;\n       } ],\n     [ qr/^--kinds-([^=]*)=(.*)/, sub {\n\t   die \"--kinds-<LANG>= can be used only for disabling a kind: $1\";\n       } ],\n     [ qr/^--extras-([^=]*)=([-+])\\{(.+)\\}$/, sub {\n\t   die \"Don't use --extras-<LANG>= option before defining the language\"\n\t       if (! defined $_[0]->{'langdef'});\n\t   die \"Enabling/disabling an extra is allowed only to the language specified with --langdef: $1\"\n\t       unless ($_[0]->{'langdef'} eq $1);\n\t   die \"Specifing multiple extras in one --extras-... is not handled: {$3}\"\n\t       if ( index ($3, '{') != -1 );\n\t   parse_extras ($2, $3, $_[0]);\n\t   return 1;\n       } ],\n     [ qr/^--extras-([^=]*)=\\{/, sub {\n\t die \"--extras-<LANG>= can be used only for enabling or disabling an extra: $1\";\n       } ],\n     [ qr/^--extras-([^=]*)=(.)\\{/, sub {\n\t die \"Unknown flag($2) is passed to --extras-<LANG>= option\";\n       } ],\n     [ qr/^--fields-([^=]*)=([-+])\\{(.+)\\}$/, sub {\n\t   die \"Don't use --fields-<LANG>= option before defining the language\"\n\t       if (! defined $_[0]->{'langdef'});\n\t   die \"Enabling/disabling a field is allowed only to the language specified with --langdef: $1\"\n\t       unless ($_[0]->{'langdef'} eq $1);\n\t   die \"Specifing multiple fields in one --fields-... is not handled: {$3}\"\n\t       if ( index ($3, '{') != -1 );\n\t   parse_fields ($2, $3, $_[0]);\n\t   return 1;\n       } ],\n     [ qr/^--fields-([^=]*)=\\{/, sub {\n\t die \"--fields-<LANG>= can be used only for enabling or disabling a field: $1\";\n       } ],\n     [ qr/^--fields-([^=]*)=(.)\\{/, sub {\n\t die \"Unknown flag($2) is passed to --fields-<LANG>= option\";\n       } ],\n     [ qr/^--langmap=.*/, sub {\n\t die \"Use --map-<LANG> option instead of --langmap\";\n       } ],\n     [ qr/^--_tabledef-([^=]*)=(.*)/, sub {\n\t die \"Don't use --_tabledef-<LANG>= option before defining the language\"\n\t   if (! defined $_[0]->{'langdef'});\n\t die \"Adding a table is allowed only to the language specified with --langdef: $1\"\n\t   unless ($_[0]->{'langdef'} eq $1);\n\t $_[0]->{'tabledefs'}->{$2} = [];\n\t push @{$_[0]->{'tablenames'}}, \"$2\";\n\t return 1;\n       } ],\n     [ qr/^--_mtable-regex-([^=]*)=([^\\/]+)(\\/.*)/, sub {\n\t die \"Don't use --_mtable-regex-<LANG>= option before defining the language\"\n\t   if (! defined $_[0]->{'langdef'});\n\t die \"Adding a multitable regex is allowed only to the language specified with --langdef: $1\"\n\t   unless ($_[0]->{'langdef'} eq $1);\n\t return parse_regex ($3, $_[0], 1, $2);\n       } ],\n     [ qr/^--_mtable-extend-([^=]*)=([a-zA-Z_0-9]+)\\+([a-zA-Z_0-9]+)/, sub {\n\t die \"Don't use --_mline-extend-<LANG>= option before defining the language\"\n\t   if (! defined $_[0]->{'langdef'});\n\t die \"Extending a multitable regex is allowed only to the language specified with --langdef: $1\"\n\t   unless ($_[0]->{'langdef'} eq $1);\n\t extend_table($_[0], $2, $3);\n\t return 1;\n     } ],\n     [ qr/^--_(prelude|sequel)-([^=]*)=(\\{\\{)$/, sub {\n\t die \"Don't use --_mtable-regex-<LANG>= option before defining the language\"\n\t   if (! defined $_[0]->{'langdef'});\n\n\t my $hook = $_[0]->{$1};\n\t my $slot = @$hook;\n\t push @$hook, $3;\n\t return sub {\n\t   $hook->[$slot] = $hook->[$slot] . $_[0];\n\t }\n       }],\n     [ qr/^--_(prelude|sequel)-([^=]*)=(\\{\\{.*\\}\\})$/, sub {\n\t die \"Don't use --_mtable-regex-<LANG>= option before defining the language\"\n\t   if (! defined $_[0]->{'langdef'});\n\n\t my $hook = $_[0]->{$1};\n\t my $slot = @$hook;\n\t push @$hook, $3;\n\t return 1;\n       }],\n     [ qr/^--_scopesep-([^=]*)=([^,]?)\\/([^:]+):(.+)/, sub {\n\t die \"Don't use --_scopesep-<LANG>= option before defining the language\"\n\t   if (! defined $_[0]->{'langdef'});\n\t die \"Specifying a scope separator is allowed only to the language specified with --langdef: $1\"\n\t   unless ($_[0]->{'langdef'} eq $1);\n\t scopesep($_[0], $2, $3, $4);\n\t return 1;\n       } ],\n     [ qr/^--_paramdef-(.*)=([^,]+),([^\\{]+)/, sub {\n\t die \"Don't use --_paramdef-<LANG>=+ option before defining the language\"\n\t     if (! defined $_[0]->{'langdef'});\n\t die \"Adding a parameter is allowed only to the language specified with --langdef: $1\"\n\t     unless ($_[0]->{'langdef'} eq $1);\n\n\t my $name = $2;\n\t my $desc = $3;\n\n\t die \"unacceptable character is used for parameter name: $name\"\n\t     unless ($name =~ /^[_a-zA-Z0-9]+$/);\n\n\t push @{$_[0]->{'paramdefs'}}, { name => $name, desc => $desc };\n\t return 1;\n       } ],\n     [ qr/^-.*/, sub {\n\t die \"Unhandled option: \\\"$&\\\"\";\n       } ],\n     [ qr/.*/, sub {\n\t die \"Unhandled argument: \\\"$&\\\"\";\n       } ],\n    ];\n\nsub parse_flags\n{\n    my ($line, $opts, $table) = @_;\n\n    TOP: while (1) {\n\tfor (@{$table}) {\n\t    my ($pat, $action) = @{$_};\n\t    if ($line =~ $pat) {\n\t\t$line = \"$`$'\";\n\t\t$action -> ($opts);\n\t\tredo TOP;\n\t    }\n\t}\n\tlast;\n    }\n}\n\nsub parse_line {\n    my ($line, $opts, $table) = @_;\n    my $r = 0;\n\n    for (@{$table}) {\n\tmy ($pat, $action) = @{$_};\n\tif ($line =~ $pat) {\n\t    $r = $action -> ($opts);\n\t    last;\n\t}\n    }\n    $r;\n}\n\nsub gather_chars {\n    my $input = shift;\n    my $output = \"\";\n\n    my $escape = 0;\n    my $c;\n\n    # See scanSeparators() of lregex.c.\n    while (defined ($c = shift @{$input})) {\n\tif ($escape) {\n\t    if ($c eq '/') {\n\t\t$output = $output . $c;\n\t    } elsif ($c eq 't') {\n\t\t$output = $output . '\\\\' . 't';\n\t    } elsif ($c eq 'n') {\n\t\t$output = $output . '\\\\' . 'n';\n\t    } elsif ($c eq '\\\\') {\n\t\t$output = $output . '\\\\\\\\' . '\\\\\\\\';\n\t    } else {\n\t\t$output = $output . '\\\\\\\\' . $c;\n\t    }\n\t    $escape = 0;\n\t} elsif ($c eq '\"') {\n\t    $output = $output . '\\\\' . $c;\n\t} elsif ($c eq '\\\\') {\n\t    $escape = 1;\n\t} elsif ($c eq '/') {\n\t    last;\n\t} else {\n\t    $output = $output . $c;\n\t}\n    }\n\n    return ($output, (defined $c)? $c: \"\");\n}\n\nsub parse_regex {\n    my ($regspec, $opts, $mline, $table) = @_;\n\n    my @chars = split //, $regspec;\n\n    # TODO:\n    #\tctags allows using a char other than '/'\n    #\n    if (! ($chars[0] eq '/')) {\n\tif (!$mline) {\n\t    die \"--regex-<LANG>= option is not started from /: $regspec\";\n\t} else {\n\t    die \"--mline-regex-<LANG>= option is not started from /: $regspec\";\n\t}\n    }\n\n    shift @chars;\n    my $last_char;\n\n    my $regex;\n    ($regex, $last_char) = gather_chars (\\@chars);\n    if (! ($last_char eq '/')) {\n\tif (!$mline) {\n\t    die \"The pattern in --regex-<LANG>= option is not ended with /: $regspec\";\n\t} else {\n\t    die \"The pattern in --mline-regex-<LANG>= option is not ended with /: $regspec\";\n\t}\n    }\n\n    my $name;\n    ($name, $last_char) = gather_chars (\\@chars);\n    if (! ($last_char eq '/')) {\n\tdie \"Wrong kind/flags syntax: $regspec\";\n    }\n\n    my $tmp;\n    ($tmp, $last_char) = gather_chars (\\@chars);\n    my $kind = \"\";\n    my $flags;\n\n    if ( (! @chars) && (! ($last_char eq '/'))) {\n\t$flags = $tmp;\n\n    } else {\n\t$kind = $tmp;\n    }\n\n    if ($last_char eq '/') {\n\t($flags, $last_char) = gather_chars (\\@chars);\n    }\n\n    my $optscript = '';\n    if ($flags =~ /(.*)\\{\\{$/) {\n\t$flags = $1;\n\t$optscript = \"{{\\n\";\n    }\n\n    my $entry;\n    if (defined $table) {\n\n      if (! (substr ($regex, 0, 1) eq '^')) {\n\t$regex = '^' . $regex;\n      }\n      $entry = { 'regex' => $regex,\n\t\t 'name'  => $name,\n\t\t 'kind'  => $kind,\n\t\t 'flags' => $flags,\n\t\t 'mline' => $mline,\n\t\t 'optscript' => $optscript,\n\t       };\n      push @{$opts->{'tabledefs'}->{\"$table\"}}, $entry;\n    } else {\n      $entry = { 'regex' => $regex,\n\t\t 'name'  => $name,\n\t\t 'kind'  => $kind,\n\t\t 'flags' => $flags,\n\t\t 'mline' => $mline,\n\t\t 'optscript' => $optscript,\n\t       };\n      push @{$opts->{'regexs'}}, $entry;\n    }\n\n    if ($flags =~ '{scope=' || $optscript) {\n\t$opts->{'useCork'} = 1;\n    }\n\n    return $optscript\n\t? sub {\n\t    $entry->{'optscript'} = $entry->{'optscript'} . $_[0];\n\t}\n\t: 1;\n}\n\nsub extend_table {\n  my ($opts, $dist, $src) = @_;\n\n  for (@{$opts->{'tabledefs'}->{$src}}) {\n    push @{$opts->{'tabledefs'}->{$dist}}, $_;\n  }\n}\n\nsub parse_kinds {\n    my ($kinds, $opts) = @_;\n    for my $letter (split //, $kinds) {\n\tfor (@{$opts->{'kinddefs'}}) {\n\t    if ($_->{'letter'} eq $letter) {\n\t\t$_->{'enabled'} = 0;\n\t    }\n\t}\n    }\n}\n\nsub parse_roles {\n    my ($kind, $roles, $opts) = @_;\n\n    NEXT: for my $role (@$roles) {\n\tfor my $r (@{$kind->{'roles'}}) {\n\t    if ($role eq $r->{'name'}) {\n\t\t$r->{'enabled'} = 0;\n\t\tnext NEXT;\n\t    }\n\t}\n\tdie \"No role $_ is defined in kind $kind->{'name'}\"\n    }\n}\n\nsub parse_optlib {\n    my ($optlib, $opts) = @_;\n\n    open(my $optlibfh, \"<\", $optlib)\n\tor die \"cannot open the optlib file: \\\"$optlib\\\"\";\n\n    my $receiver = 0;\n    while (<$optlibfh>) {\n\tchomp;\n\n\tif (/^\\}\\}$/ && $receiver && ($receiver != 1)) {\n\t    $receiver->('}}');\n\t    $receiver = 1;\n\t}\n\telsif ($receiver && $receiver != 1) {\n\t    my $str = escape_as_cstr ($_);\n\t    $receiver->($str);\n\t    $receiver->(\"\\n\");\n\t} elsif ( /^[[:blank:]]*#.*/ ) {\n\t    next;\n\t} else {\n\t    s/^\\s*//;\n\t    next if ( /^\\s*$/ );\n\t    $receiver = parse_line ($_, $opts, $options);\n\t    if (! $receiver) {\n\t\treturn undef;\n\t    }\n\t}\n    }\n    return $opts;\n}\n\nsub parse_extras {\n    my ($flag, $extra, $opts) = @_;\n\n    $flag = ( $flag eq '+' )?1: 0;\n\n    # TODO: Hash table should be used for manage 'extradefs'.\n    for (@{$opts->{'extradefs'}}) {\n\tif ($_->{'name'} eq $extra)\n\t{\n\t    $_->{'enabled'} = $flag;\n\t}\n    }\n}\n\nsub parse_fields {\n    my ($flag, $field, $opts) = @_;\n\n    $flag = ( $flag eq '+' )?1: 0;\n\n    # TODO: Hash table should be used for manage 'fielddefs'.\n    for (@{$opts->{'fielddefs'}}) {\n\tif ($_->{'name'} eq $field)\n\t{\n\t    $_->{'enabled'} = $flag;\n\t}\n    }\n}\n\nsub scopesep {\n    my ($opts, $parent_kletter, $kletter, $sep) = @_;\n\n    if ($kletter eq '*') {\n\tif ($parent_kletter eq '*') {\n\t    $opts->{'defaultScopeSeparator'} = $sep;\n\t} elsif (!$parent_kletter) {\n\t    $opts->{'defaultRootScopeSeparator'} = $sep;\n\t} else {\n\t    die \"Unhandled kind letter during parsing --_scopsesep option: $parent_kletter\";\n\t}\n    } elsif ($kletter =~ /[a-zA-Z]/) {\n\tmy $kind;\n\tfor (@{$opts->{'kinddefs'}}) {\n\t    if ($_->{'letter'} eq $kletter) {\n\t\t$kind = $_;\n\t\tlast;\n\t    }\n\t}\n\tdie \"Unknown kind letter in --_scopsesep option: $kletter\"\n\t  unless defined $kind;\n\n\tif ($parent_kletter eq '*') {\n\t    push @{$kind->{'seps'}}, { parentKindIndex => 'KIND_WILDCARD_INDEX',\n\t\t\t\t       sep => $sep };\n\t} elsif (!$parent_kletter) {\n\t    push @{$kind->{'seps'}}, { parentKindIndex => 'KIND_GHOST_INDEX',\n\t\t\t\t       sep => $sep };\n\t} elsif ($parent_kletter =~ /[a-zA-Z]/) {\n\t    my $parent_kind;\n\t    for (@{$opts->{'kinddefs'}}) {\n\t\tif ($_->{'letter'} == $parent_kletter) {\n\t\t    $parent_kind = $_;\n\t\t    last;\n\t\t}\n\t    }\n\t    die \"Unknown kind letter in --_scopsesep option: $parent_kletter\"\n\t      unless defined $parent_kind;\n\t    push @{$kind->{'seps'}}, { parentKindIndex => 'K_' . (uc $parent_kind->{'name'}),\n\t\t\t\t       sep => $sep };\n\t}\n    } else {\n\tdie \"Unhandled kind letter during parsing --_scopsesep option: $kletter\";\n    }\n\n    $opts->{'hasSepSpeicifer'} = 1;\n}\n\n\n########################################################################\n#\n# EMIT\n#\n########################################################################\n\nsub emit_header {\n    my ($optlib, $opts) = @_;\n\n    print <<EOF;\n/*\n * Generated by $0 from ${optlib}, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\nEOF\n\n    if (defined $opts->{'base'}) {\n\tprint <<EOF;\n#include \"subparser.h\"\nEOF\n    }\n    if ((scalar @{$opts->{'foreignLanguages'}}) > 0) {\n\tprint <<EOF;\n#include \"dependency.h\"\nEOF\n}\n    if (defined $opts->{'selector'}) {\n\tprint <<EOF;\n#include \"selectors.h\"\nEOF\n    }\n    if ((scalar @{$opts->{'paramdefs'}}) > 0) {\n\tprint <<EOF;\n#include \"param.h\"\nEOF\n    }\n    print <<EOF;\n\n\nEOF\n}\n\nsub emit_initializer {\n    my $opts = shift;\n    my $may_unused = $opts->{'tablenames'} ? \"\": \" CTAGS_ATTR_UNUSED\";\n\n    print <<EOF;\nstatic void initialize$opts->{'Clangdef'}Parser (const langType language$may_unused)\n{\nEOF\n    for (@{$opts->{'prelude'}}) {\n\tmy $prelude = \"\";\n\tfor my $frag (split /\\n/, $_) {\n\t    $prelude = $prelude . \"\\n\\t\\t\\\"\" . $frag . ($frag =~ /.*\\}\\}$/\n\t\t\t\t\t\t\t? '\"'\n\t\t\t\t\t\t\t: '\\n\"');\n\t}\n\tprint <<EOF;\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE,$prelude);\nEOF\n    }\n    for (@{$opts->{'sequel'}}) {\n\tmy $sequel = \"\";\n\tfor my $frag (split /\\n/, $_) {\n\t    $sequel = $sequel . \"\\n\\t\\t\\\"\" . $frag . ($frag =~ /.*\\}\\}$/\n\t\t\t\t\t\t\t? '\"'\n\t\t\t\t\t\t\t: '\\n\"');\n\t}\n\tprint <<EOF;\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_SEQUEL,$sequel);\nEOF\n    }\n    if ($opts->{'tablenames'}) {\n      print \"\\n\";\n\n      for (@{$opts->{'tablenames'}}) {\n\tprint <<EOF;\n\taddLanguageRegexTable (language, \"$_\");\nEOF\n      }\n\n      print \"\\n\";\n\n      for my $table (@{$opts->{'tablenames'}}) {\n\tfor (@{$opts->{'tabledefs'}->{\"$table\"}}) {\n\t  my $optscript = \"\";\n\t  if ($_-> {'optscript'}) {\n\t    for my $frag (split /\\n/, $_-> {'optscript'}) {\n\t      $optscript = $optscript . \"\\n\\t\\t\\\"\" . $frag . ($frag =~ /.*\\}\\}$/\n\t\t\t\t\t\t\t      ? '\"'\n\t\t\t\t\t\t\t      : '\\n\"');\n\t    }\n\t  }\n\t  print <<EOF;\n\taddLanguageTagMultiTableRegex (language, \"$table\",\n\t                               \"$_->{'regex'}\",\n\t                               \"$_->{'name'}\", \"$_->{'kind'}\", \"$_->{'flags'}\"$optscript, NULL);\nEOF\n\t}\n      }\n    }\n    print <<EOF;\n}\n\nEOF\n    0;\n}\n\nsub emit_list {\n    my ($opts, $key) = @_;\n\n    print <<EOF;\n\tstatic const char *const $key [] = {\nEOF\n    for (@{$opts->{$key}}) {\n\tprint <<EOF;\n\t\t\\\"$_\\\",\nEOF\n    }\n\n    print <<EOF;\n\t\tNULL\n\t};\n\nEOF\n}\n\nsub emit_aliases {\n    emit_list $_[0], \"aliases\";\n}\n\nsub emit_extensions {\n    emit_list $_[0], \"extensions\";\n}\n\nsub emit_patterns {\n    emit_list $_[0], \"patterns\";\n}\n\nsub emit_rexprs {\n    my $opts = shift;\n\n    return if (! @{$opts->{'rexprs'}});\n\n    printf <<EOF;\n\tstatic const struct rExprSrc rexprs [] = {\nEOF\n    for (@{$opts->{'rexprs'}}) {\n\tmy $expr = escape_as_cstr (\"$_->{'expr'}\");\n\tmy $iCase = $_->{'iCase'}? \"true\": \"false\";\n\tprintf <<EOF;\n\t\t{\n\t\t  .expr = \"$expr\",\n\t\t  .iCase = $iCase,\n\t\t},\nEOF\n    }\n    printf <<EOF;\n\t\tREXPR_LAST_ENTRY\n\t};\n\nEOF\n}\n\n# TODO: handling '\\'\nsub escape_as_cstr {\n    my $input = shift;\n    my $output = \"\";\n\n    for my $c (split //, $input) {\n\tif ($c eq '\"') {\n\t    $output = $output . '\\\\' . '\"';\n\t} elsif ($c eq '\\\\') {\n\t    $output = $output . '\\\\' . '\\\\';\n\t} else {\n\t    $output = $output . $c;\n\t}\n    }\n\n    return $output;\n}\n\nsub emit_roledefs {\n    my $opts = shift;\n\n    for (@{$opts->{'kinddefs'}}) {\n\tnext unless @{$_->{'roles'}};\n\tmy $Kind = capitalize($_->{'name'});\n\tprint <<EOF;\n\tstatic roleDefinition $opts->{'Clangdef'}${Kind}RoleTable [] = {\nEOF\n\tfor (@{$_->{'roles'}}) {\n\t    my $desc = escape_as_cstr $_->{'desc'};\n\t    my $enabled = $_->{'enabled'}? \"true\": \"false\";\n\t    print <<EOF;\n\t\t{\n\t\t  $enabled, \"$_->{'name'}\", \"$desc\",\nEOF\n\t    if ($_->{'version'}) {\n\t\tprint <<EOF;\n\t\t  .version = $_->{'version'},\nEOF\n\t    }\n\t    print <<EOF;\n\t\t},\nEOF\n\t}\n\n\tprint <<EOF;\n\t};\nEOF\n    }\n    print <<EOF;\nEOF\n}\n\nsub emit_kinddef_enums {\n    my $opts = shift;\n\n    return if (! @{$opts->{'kinddefs'}});\n\n    print <<EOF;\ntypedef enum {\nEOF\n    for (@{$opts->{'kinddefs'}}) {\n\tmy $e = uc($_->{'name'});\n\tprint <<EOF;\n\tK_$e,\nEOF\n    }\n    print <<EOF;\n} $opts->{'Clangdef'}Kind;\n\n\nEOF\n}\n\nsub emit_scopeseps {\n    my $opts = shift;\n\n    return if (! @{$opts->{'kinddefs'}});\n\n    for (@{$opts->{'kinddefs'}}) {\n\tmy $seps = $_->{'seps'};\n\tif (@{$seps}) {\n\t    my $Kind = capitalize ($_->{'name'});\n\t    print <<EOF;\n\tstatic scopeSeparator $opts->{'Clangdef'}${Kind}Separators [] = {\nEOF\n\t    for (@{$seps}) {\n\t    print <<EOF;\n\t\t{ $_->{'parentKindIndex'}, \"$_->{'sep'}\" },\nEOF\n\t    }\n\t    print <<EOF;\n\t};\n\nEOF\n\t}\n    }\n}\n\nsub emit_kinddefs {\n    my $opts = shift;\n\n    return if (! @{$opts->{'kinddefs'}});\n\n    print <<EOF;\n\tstatic kindDefinition $opts->{'Clangdef'}KindTable [] = {\nEOF\n    for (@{$opts->{'kinddefs'}}) {\n      my $enabled = $_->{\"enabled\"}? \"true\": \"false\";\n      print <<EOF;\n\t\t{\nEOF\n      my $desc = escape_as_cstr $_->{'desc'};\n      print <<EOF;\n\t\t  $enabled, \\'$_->{'letter'}\\', \"$_->{'name'}\", \"$desc\",\nEOF\n      if ($_->{'refonly'}) {\n\t  print <<EOF;\n\t\t  .referenceOnly = true,\nEOF\n      }\n      my $Kind = capitalize($_->{'name'});\n      if (@{$_->{'roles'}}) {\n\t  print <<EOF;\n\t\t  ATTACH_ROLES($opts->{'Clangdef'}${Kind}RoleTable),\nEOF\n      }\n      if (@{$_->{'seps'}}) {\n\t  print <<EOF;\n\t\t  ATTACH_SEPARATORS($opts->{'Clangdef'}${Kind}Separators),\nEOF\n      }\n      if ($_->{'version'}) {\n\t  print <<EOF;\n\t\t  .version = $_->{'version'},\nEOF\n      }\n      print <<EOF;\n\t\t},\nEOF\n    }\n    print <<EOF;\n\t};\nEOF\n}\n\nsub emit_regexs {\n    my $opts = shift;\n\n    return if (! @{$opts->{'regexs'}});\n\n    print <<EOF;\n\tstatic tagRegexTable $opts->{'Clangdef'}TagRegexTable [] = {\nEOF\n    for (@{$opts->{'regexs'}}) {\n\tmy $flags;\n\tif ($_-> {'flags'}) {\n\t    $flags = '\"' . $_-> {'flags'} . '\"';\n\t    if ($_-> {'optscript'}) {\n\t\tfor my $frag (split /\\n/, $_-> {'optscript'}) {\n\t\t    $flags = $flags . \"\\n\\t\\t\\\"\" . $frag . ($frag =~ /.*\\}\\}$/\n\t\t\t\t\t\t\t    ? '\"'\n\t\t\t\t\t\t\t    : '\\n\"');\n\t\t}\n\t    }\n\t} else {\n\t    if ($_-> {'optscript'}) {\n\t\t$flags = '\"\"';\n\t\tfor my $frag (split /\\n/, $_-> {'optscript'}) {\n\t\t    $flags = $flags . \"\\n\\t\\t\\\"\" . $frag . ($frag =~ /.*\\}\\}$/\n\t\t\t\t\t\t\t    ? '\"'\n\t\t\t\t\t\t\t    : '\\n\"');\n\t\t}\n\t    } else {\n\t\t$flags = 'NULL';\n\t    }\n\t}\n\tmy $mline = $_-> {'mline'}? \"true\": \"false\";\n\tprint <<EOF;\n\t\t{\"$_->{'regex'}\", \"$_->{'name'}\",\n\t\t\"$_->{'kind'}\", $flags, NULL, $mline},\nEOF\n    }\n    print <<EOF;\n\t};\n\nEOF\n}\n\nsub emit_dependencies {\n    my $opts = shift;\n\n    return if ((! defined $opts->{'base'})\n\t       && ((scalar @{$opts->{'foreignLanguages'}}) == 0));\n\n    my $direction = \"SUBPARSER_BASE_RUNS_SUB\";\n\n    if (defined $opts->{'direction'})\n    {\n\tif ($opts->{'direction'} eq 'shared')\n\t{\n\t    $direction = \"SUBPARSER_BASE_RUNS_SUB\";\n\t} elsif ($opts->{'direction'} eq 'dedicated')\n\t{\n\t    $direction = \"SUBPARSER_SUB_RUNS_BASE\";\n\t} elsif ($opts->{'direction'} eq 'bidirectional')\n\t{\n\t    $direction = \"SUBPARSER_BI_DIRECTION\";\n\t}\n    }\n\n    if (defined $opts->{'base'}) {\n\tprint <<EOF;\n\tstatic subparser $opts->{'Clangdef'}Subparser = {\n\t\t.direction = $direction,\n\t};\nEOF\n    }\n\n    print <<EOF;\n\tstatic parserDependency $opts->{'Clangdef'}Dependencies [] = {\nEOF\n    my $i = 0;\n    if (defined $opts->{'base'}) {\n\tprint <<EOF;\n\t\t[$i] = { DEPTYPE_SUBPARSER, \"$opts->{'base'}\", &$opts->{'Clangdef'}Subparser },\nEOF\n\t$i++;\n    }\n    for (@{$opts->{'foreignLanguages'}}) {\n\tprint <<EOF;\n\t\t[$i] = { DEPTYPE_FOREIGNER, \"$_\", NULL },\nEOF\n\t$i++;\n    }\n\nprint <<EOF;\n\t};\nEOF\n\n}\n\nsub emit_xtags {\n    my $opts = shift;\n\n    return if (! @{$opts->{'extradefs'}});\n\n    print <<EOF;\n\tstatic xtagDefinition $opts->{'Clangdef'}XtagTable [] = {\nEOF\n    for (@{$opts->{'extradefs'}}) {\n      my $enabled = $_->{\"enabled\"}? \"true\": \"false\";\n      my $desc = escape_as_cstr $_->{'desc'};\n      print <<EOF;\n\t\t{\n\t\t  .enabled     = $enabled,\n\t\t  .name        = \"$_->{'name'}\",\n\t\t  .description = \"$desc\",\nEOF\n      if ($_->{'version'}) {\n\t  print <<EOF;\n\t\t  .version     = \"$_->{'version'}\",\nEOF\n      }\n      print <<EOF;\n\t\t},\nEOF\n    }\n    print <<EOF;\n\t};\nEOF\n}\n\nsub emit_params {\n    my $opts = shift;\n\n    return if (! @{$opts->{'paramdefs'}});\n\n    print <<EOF;\n\tstatic paramDefinition $opts->{'Clangdef'}ParamTable [] = {\nEOF\n    for (@{$opts->{'paramdefs'}}) {\n      my $desc = escape_as_cstr $_->{'desc'};\n      print <<EOF;\n\t\t{\n\t\t  .name        = \"$_->{'name'}\",\n\t\t  .desc        = \"$desc\",\n\t\t  .handleParam = NULL,\n\t\t},\nEOF\n    }\n    print <<EOF;\n\t};\nEOF\n}\n\nsub emit_fields {\n    my $opts = shift;\n\n    return if (! @{$opts->{'fielddefs'}});\n\n    print <<EOF;\n\tstatic fieldDefinition $opts->{'Clangdef'}FieldTable [] = {\nEOF\n    for (@{$opts->{'fielddefs'}}) {\n      my $enabled = $_->{\"enabled\"}? \"true\": \"false\";\n      my $desc = escape_as_cstr $_->{'desc'};\n      print <<EOF;\n\t\t{\n\t\t  .enabled     = $enabled,\n\t\t  .name        = \"$_->{'name'}\",\n\t\t  .description = \"$desc\",\nEOF\n      if (defined $_->{'datatype'}) {\n\t  print <<EOF;\n\t\t  .dataType = $_->{'datatype'},\n\t\t  .isValueAvailable = isValueAvailableGeneric,\n\t\t  .getValueObject = getFieldValueGeneric,\n\t\t  .setValueObject = setFieldValueGeneric,\nEOF\n      }\n      if ($_->{'version'}) {\n\t  print <<EOF;\n\t\t  .version     = $_->{'version'},\nEOF\n      }\n      print <<EOF;\n\t\t},\nEOF\n    }\n    print <<EOF;\n\t};\nEOF\n}\n\nsub emit_selector {\n    my $opts = shift;\n\n    if (defined $opts->{'selector'}) {\n\tprint <<EOF;\n\tstatic selectLanguage selectors[] = { $opts->{'selector'}, NULL };\nEOF\n    }\n}\n\nsub emit_fields_initialization {\n    my $opts = shift;\n    my $enabled = $opts->{\"disabled\"} ? \"false\": \"true\";\n    my $method;\n    my $sep;\n\n    $method  = \"METHOD_NOT_CRAFTED\";\n    if (@{$opts->{\"regexs\"}} || $opts->{'tablenames'}) {\n\t$method = \"${method}|METHOD_REGEX\";\n    }\n\n    print <<EOF;\n\tdef->versionCurrent= $opts->{'versionCurrent'};\n\tdef->versionAge    = $opts->{'versionAge'};\n\tdef->enabled       = ${enabled};\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\nEOF\n    if (@{$opts->{'rexprs'}}) {\n\tprint <<EOF;\n\tdef->rexprs        = rexprs;\nEOF\n    }\n    print <<EOF;\n\tdef->aliases       = aliases;\nEOF\n    if (defined $opts->{'selector'}) {\n\tprint <<EOF;\n\tdef->selectLanguage= selectors;\nEOF\n    }\nprint <<EOF;\n\tdef->method        = ${method};\nEOF\n\n    if ($opts->{'useCork'}) {\n\tprint <<EOF;\n\tdef->useCork       = CORK_QUEUE;\nEOF\n    }\n    if (@{$opts->{'kinddefs'}}) {\n\tprint <<EOF;\n\tdef->kindTable     = $opts->{'Clangdef'}KindTable;\n\tdef->kindCount     = ARRAY_SIZE($opts->{'Clangdef'}KindTable);\nEOF\n    }\n\n    if (@{$opts->{'fielddefs'}}) {\n\tprint <<EOF;\n\tdef->fieldTable    = $opts->{'Clangdef'}FieldTable;\n\tdef->fieldCount    = ARRAY_SIZE($opts->{'Clangdef'}FieldTable);\nEOF\n    }\n\n    if (@{$opts->{'extradefs'}}) {\n\tprint <<EOF;\n\tdef->xtagTable     = $opts->{'Clangdef'}XtagTable;\n\tdef->xtagCount     = ARRAY_SIZE($opts->{'Clangdef'}XtagTable);\nEOF\n    }\n\n    if (@{$opts->{'paramdefs'}}) {\n\tprint <<EOF;\n\tdef->paramTable    = $opts->{'Clangdef'}ParamTable;\n\tdef->paramCount    = ARRAY_SIZE($opts->{'Clangdef'}ParamTable);\nEOF\n    }\n\n    if (@{$opts->{'regexs'}}) {\n\tprint <<EOF;\n\tdef->tagRegexTable = $opts->{'Clangdef'}TagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE($opts->{'Clangdef'}TagRegexTable);\nEOF\n    }\n\n    if (defined $opts->{'base'} || (scalar @{$opts->{'foreignLanguages'}}) > 0) {\n\tprint <<EOF;\n\tdef->dependencies    = $opts->{'Clangdef'}Dependencies;\n\tdef->dependencyCount = ARRAY_SIZE($opts->{'Clangdef'}Dependencies);\nEOF\n    }\n\n    if ($opts->{'autoFQTag'}) {\n\tprint <<EOF;\n\tdef->requestAutomaticFQTag = true;\nEOF\n    }\n\n    if ($opts->{'defaultScopeSeparator'}) {\n\t$sep = \"$opts->{'defaultScopeSeparator'}\";\n\t$sep = escape_as_cstr \"$sep\";\n\tprint <<EOF;\n\tdef->defaultScopeSeparator = \"$sep\";\nEOF\n    }\n    if ($opts->{'defaultRootScopeSeparator'}) {\n\t$sep = $opts->{'defaultRootScopeSeparator'};\n\t$sep = escape_as_cstr \"$sep\";\n\tprint <<EOF;\n\tdef->defaultRootScopeSeparator = \"$sep\";\nEOF\n    }\n    print <<EOF;\n\tdef->initialize    = initialize$opts->{'Clangdef'}Parser;\n\nEOF\n}\n\nsub emit {\n    my ($optlib, $opts) = @_;\n\n    emit_header ($optlib, $opts);\n\n    if ($opts->{'hasSepSpeicifer'}) {\n\temit_kinddef_enums   $opts;\n    };\n    emit_initializer $opts;\n\n    print <<EOF;\nextern parserDefinition* $opts->{'Clangdef'}Parser (void)\n{\nEOF\n\n    emit_extensions      $opts;\n    emit_aliases         $opts;\n    emit_patterns        $opts;\n    emit_rexprs          $opts;\n    emit_roledefs        $opts;\n    emit_scopeseps       $opts;\n    emit_kinddefs        $opts;\n    emit_fields          $opts;\n    emit_xtags           $opts;\n    emit_params          $opts;\n    emit_regexs          $opts;\n    emit_dependencies    $opts;\n    emit_selector        $opts;\n\n    print \"\\n\";\n\n    print <<EOF;\n\tparserDefinition* const def = parserNew (\"$opts->{'langdef'}\");\n\nEOF\n\n    emit_fields_initialization $opts;\n\n    print <<EOF;\n\treturn def;\n}\nEOF\n}\n\n########################################################################\n#\n# REARRANGE\n#\n########################################################################\n\nsub capitalize {\n    my ($str) = $_[0];\n    my $c = substr ($str, 0, 1);\n\n    $c =~ tr/a-z/A-Z/;\n\n    return $c . substr($str, 1);\n}\n\nsub rearrange {\n    my ($opts) = @_;\n    my $langdef = $opts -> {'langdef'};\n    $opts -> {'Clangdef'} = capitalize ($langdef);\n}\n\n\n########################################################################\n#\n# MAIN\n#\n########################################################################\n\nsub main {\n    my $optlib;\n    my %opts = (langdef  => undef,\n\t\tClangdef => undef,\n\t\tdisabled => 0,\n\t\tpatterns => [],\n\t\textensions => [],\n\t\trexprs => [],\n\t\taliases => [],\n\t\tregexs => [# { regex => \"\", name => \"\", kind => \"\", flags => \"\", mline => 1|0, optscript => \"\" },\n\t\t\t  ],\n\t\tkinddefs => [# { letter => '', name => \"\", desc => \"\",\n\t\t\t     #   seps => [ {parentKindIndex => \"\", sep => \"\" } ]\n\t\t\t     # },\n\t\t\t    ],\n\t\textradefs => [ # { name => \"\", desc => \"\", enabled => 1|0 },\n\t\t\t     ],\n\t\tfielddefs => [ # { name => \"\", desc => \"\", enabled => 1|0 },\n\t\t\t      ],\n\t\tparamdefs => [ # { name => \"\", desc => \"\" },\n\t\t\t     ],\n\t\tbase => undef,\n\t\ttableNames => [ # \"\"\n\t\t\t       ],\n\t\ttabledefs => { # \"\" => [{ regex => \"\", name => \"\", kind => \"\", flags => \"\" }...],\n\t\t\t     },\n\t\tuseCork   => 0,\n\t\tdefaultScopeSeparator => undef,\n\t\tdefaultRootScopeSeparator => undef,\n\t\thasSepSpeicifer => 0,\n\t\tprelude => [ # \"\"\n\t\t\t   ],\n\t\tsequel =>  [ # \"\"\n\t\t\t   ],\n\t\tselector => undef,\n\t       );\n\n    for (@_) {\n\tif ( ($_ eq '-h') || ($_ eq '--help') ) {\n\t    show_help;\n\t    exit 0;\n\t} elsif ( /^-.*/ ) {\n\t    die \"unrecongnized option: $_\";\n\t} else {\n\t    if ($optlib) {\n\t\tdie \"Too man input files: @_\";\n\t    }\n\t    $optlib=$_;\n\t}\n    }\n\n    if (! $optlib) {\n\tdie \"No optlib file name is given\";\n    }\n\n    if (! parse_optlib ($optlib, \\%opts)) {\n\texit 1;\n    }\n\n    rearrange (\\%opts);\n\n    if (! emit ($optlib, \\%opts) ) {\n\texit 1;\n    }\n    0;\n}\n\nmain @ARGV;\n\n# optlib2c ends here.\n"
  },
  {
    "path": "misc/packcc/.github/workflows/testing.yml",
    "content": "name: run test cases\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  testing:\n    strategy:\n      matrix:\n        os: [ubuntu-20.04]\n        compiler: [gcc, clang]\n\n    runs-on: ${{ matrix.os }}\n\n    env:\n      CC: ${{ matrix.compiler }}\n\n    steps:\n    - uses: actions/checkout@v2\n    - name: install bats\n      run: |\n        curl -L -o bats-core-1.2.1.tar.gz https://github.com/bats-core/bats-core/archive/v1.2.1.tar.gz\n        tar zxvf bats-core-1.2.1.tar.gz\n        cd bats-core-1.2.1 &&\n        sudo ./install.sh /usr/local\n    - name: install uncrustify\n      run: |\n        curl -LO http://launchpadlibrarian.net/516341795/uncrustify_0.72.0+dfsg1-2_amd64.deb\n        sudo dpkg -i uncrustify_0.72.0+dfsg1-2_amd64.deb || true\n    - name: build packcc\n      run: |\n        (\n        cd  build/$CC\n        make all check\n        )\n"
  },
  {
    "path": "misc/packcc/.gitignore",
    "content": "*.o\n*.obj\n/build/**/tmp/\n/build/**/bin/\n/build/msvc/**/x86/\n/build/msvc/**/x64/\n/build/msvc/**/.vs/\n/benchmark/tmp/\n"
  },
  {
    "path": "misc/packcc/LICENSE",
    "content": "PackCC: a packrat parser generator for C.\n\nCopyright (c) 2014, 2019-2022 Arihiro Yoshida. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "misc/packcc/README.md",
    "content": "# PackCC #\n\n## Overview ##\n\n**PackCC** is a parser generator for C.\nIts main features are as follows:\n\n- Generates your parser in C from a grammar described in a **PEG**,\n- Gives your parser great efficiency by **packrat parsing**,\n- Supports direct and indirect **left-recursive** grammar rules.\n\nThe grammar of your parser can be described in a **PEG** ([Parsing Expression Grammar](http://en.wikipedia.org/wiki/Parsing_expression_grammar)).\nThe PEG is a [top-down parsing language](http://en.wikipedia.org/wiki/Top-down_parsing_language),\nand is similar to the [regular-expression](http://en.wikipedia.org/wiki/Regular_expression) grammar.\nCompared with a bottom-up parsing language, like Yacc's one, the PEG is much more intuitive and cannot be ambiguous.\nThe PEG does not require tokenization to be a separate step, and tokenization rules can be written in the same way as any other grammar rules.\n\nYour generated parser can parse inputs very efficiently by **packrat parsing**.\nThe packrat parsing is the [recursive descent parsing](http://en.wikipedia.org/wiki/Recursive_descent_parser) algorithm\nthat is accelerated using [memoization](http://en.wikipedia.org/wiki/Memoization).\nBy using packrat parsing, any input can be parsed in linear time.\nWithout it, however, the resulting parser could exhibit exponential time performance in the worst case due to the unlimited look-ahead capability.\n\nUnlike common packrat parsers, PackCC can support direct and indirect **left-recursive** grammar rules.\nThis powerful feature enables you to describe your language grammar in a much simpler way.\n<small>(The algorithm is based on the paper [*\"Packrat Parsers Can Support Left Recursion\"*](http://www.cs.ucla.edu/~todd/research/pub.php?id=pepm08)\nauthored by A. Warth, J. R. Douglass, and T. Millstein.)</small>\n\nSome additional features are as follows:\n\n- Thread-safe and reentrant,\n- Supports UTF-8 multibyte characters (version 1.4.0 or later),\n- Generates more ease-of-understanding parser source codes,\n- Consists of just a single compact source file,\n- Under MIT license. (not under a certain contagious license!)\n\nThe generated code is beautified and as ease-of-understanding as possible.\nActually, it uses lots of *goto* statements, but the control flows are much more traceable\nthan *goto* spaghetti storms generated by Yacc or other parser generators.\nThis feature is irrelevant to common users, but helpful for PackCC developers to debug it.\n\nPackCC itself is under MIT license, but you can distribute your generated code under any license you like.\n\n## Installation ##\n\nYou can obtain the executable `packcc` by compiling [`src/packcc.c`](src/packcc.c) using your favorite C compiler.\nFor convenience, the build environments using GCC, Clang, and Microsoft Visual Studio are prepared under [`build`](build) directory.\n\n### Using GCC ###\n\n#### Other than MinGW ####\n\n`packcc` will be built in both directories `build/gcc/debug/bin` and `build/gcc/release/bin` using `gcc` by executing the following commands:\n\n```\ncd build/gcc\nmake\nmake check  # bats-core and uncrustify are required (see tests/README.md)\n```\n\n`packcc` in the directory `build/gcc/release/bin` is suitable for practical use.\n\n#### MinGW ####\n\n`packcc` will be built in both directories `build/mingw-gcc/debug/bin` and `build/mingw-gcc/release/bin` using `gcc` by executing the following commands:\n\n```\ncd build/mingw-gcc\nmake\nmake check  # bats-core and uncrustify are required (see tests/README.md)\n```\n\n`packcc` in the directory `build/mingw-gcc/release/bin` is suitable for practical use.\n\n### Using Clang ###\n\n#### Other than MinGW ####\n\n`packcc` will be built in both directories `build/clang/debug/bin` and `build/clang/release/bin` using `clang` by executing the following commands:\n\n```\ncd build/clang\nmake\nmake check  # bats-core and uncrustify are required (see tests/README.md)\n```\n\n`packcc` in the directory `build/clang/release/bin` is suitable for practical use.\n\n#### MinGW ####\n\n`packcc` will be built in both directories `build/mingw-clang/debug/bin` and `build/mingw-clang/release/bin` using `clang` by executing the following commands:\n\n```\ncd build/mingw-clang\nmake\nmake check  # bats-core and uncrustify are required (see tests/README.md)\n```\n\n`packcc` in the directory `build/mingw-clang/release/bin` is suitable for practical use.\n\n### Using Microsoft Visual Studio ###\n\nYou have to install Microsoft Visual Studio 2019 in advance.\nAfter that, you can build `packcc.exe` by the following instructions:\n- Open the solution file `build\\msvc\\msvc.sln`,\n- Select a preferred solution configuration (*Debug* or *Release*) and a preferred solution platform (*x64* or *x86*),\n- Invoke the *Build Solution* menu item.\n\n`packcc.exe` will appear in `build\\msvc\\XXX\\YYY` directory.\nHere, `XXX` is `x64` or `x86`, and `YYY` is `Debug` or `Release`.\n`packcc.exe` in the directory `build\\msvc\\XXX\\Release` is suitable for practical use.\n\n## Usage ##\n\n### Command ###\n\nYou must prepare a PEG source file (see the following section).\nLet the file name `example.peg` for example.\n\n```\npackcc example.peg\n```\n\nBy running this, the parser source `example.h` and `example.c` are generated.\n\nIf no PEG file name is specified, the PEG source is read from the standard input, and `-.h` and `-.c` are generated.\n\nThe base name of the parser source files can be changed by `-o` option.\n\n```\npackcc -o parser example.peg\n```\n\nBy running this, the parser source `parser.h` and `parser.c` are generated.\n\nIf you want to disable UTF-8 support, specify the command line option `-a` or `--ascii` (version 1.4.0 or later).\n\nIf you want to insert `#line` directives in the generated source and header files, specify the command line option `-l` or `--lines` (version 1.7.0 or later).\nIt is helpful to trace compilation errors of the generated source and header files back to the codes written in the PEG source file.\n\nIf you want to confirm the version of the `packcc` command, execute the below.\n\n```\npackcc -v\n```\n\n### Syntax ###\n\nA grammar consists of a set of named rules.\nA rule definition can be split into multiple lines.\n\n**_rulename_ `<-` _pattern_**\n\nThe _rulename_ is the name of the rule to define.\nThe _pattern_ is a text pattern that contains one or more of the following elements.\n\n**_rulename_**\n\nThe element stands for the entire pattern in the rule with the name given by _rulename_.\n\n**_variable_`:`_rulename_**\n\nThe element stands for the entire pattern in the rule with the name given by _rulename_.\nThe _variable_ is an identifier associated with the semantic value returned from the rule by assigning to `$$` in its action.\nThe identifier can be referred to in subsequent actions as a variable.\nThe example is shown below.\n\n```\nterm <- l:term _ '+' _ r:factor { $$ = l + r; }\n```\n\nA variable identifier must consist of alphabets (both uppercase and lowercase letters), digits, and underscores.\nThe first letter must be an alphabet.\nThe reserved keywords in C cannot be used.\n\n**_sequence1_ `/` _sequence2_ `/` ... `/` _sequenceN_**\n\nEach _sequence_ is tried in turn until one of them matches, at which time matching for the overall pattern succeeds.\nIf no _sequence_ matches then the matching for the overall pattern fails.\nThe operator slash (`/`) has the least priority.\nThe example is shown below.\n\n```\n'foo' rule1 / 'bar'+ [0-9]? / rule2\n```\n\nThis pattern tries matching of the first sequence (`'foo' rule1`).\nIf it succeeds, then the overall pattern matching succeeds and ends without evaluating the subsequent sequences.\nOtherwise, it tries matching of the next sequence (`'bar'+ [0-9]?`).\nIf it succeeds, then the overall pattern matching succeeds and ends without evaluating the subsequent sequence.\nFinally, it tries matching of the last sequence (`rule2`).\nIf it succeeds, then the overall pattern matching succeeds.\nOtherwise, the overall pattern matching fails.\n\n**`'`_string_`'`**\n\nA character or string enclosed in single quotes is matched literally.\nThe ANSI C escape sequences are recognized within the characters.\nThe UNICODE escape sequences (ex. `\\u20AC`) are also recognized including surrogate pairs,\nif the command line option `-a` is not specified (version 1.4.0 or later).\nThe example is shown below.\n\n```\n'foo bar'\n```\n\n**`\"`_string_`\"`**\n\nA character or string enclosed in double quotes is matched literally.\nThe ANSI C escape sequences are recognized within the characters.\nThe UNICODE escape sequences (ex. `\\u20AC`) are also recognized including surrogate pairs,\nif the command line option `-a` is not specified (version 1.4.0 or later).\nThe example is shown below.\n\n```\n\"foo bar\"\n```\n\n**`[`_character class_`]`**\n\nA set of characters enclosed in square brackets matches any single character from the set.\nThe ANSI C escape sequences are recognized within the characters.\nThe UNICODE escape sequences (ex. `\\u20AC`) are also recognized including surrogate pairs,\nif the command line option `-a` is not specified (version 1.4.0 or later).\nIf the set begins with an up-arrow (`^`), the set is negated (the element matches any character not in the set).\nAny pair of characters separated with a dash (`-`) represents the range of characters from the first to the second, inclusive.\nThe examples are shown below.\n\n```\n[abc]\n[^abc]\n[a-zA-Z0-9_]\n```\n\n**`.`**\n\nA dot (`.`) matches any single character.\nNote that the only time this fails is at the end of input, where there is no character to match.\n\n**_element_ `?`**\n\nThe _element_ is optional.\nIf present on the input, it is consumed and the match succeeds.\nIf not present on the input, no text is consumed and the match succeeds anyway.\n\n**_element_ `*`**\n\nThe _element_ is optional and repeatable.\nIf present on the input, one or more occurrences of the _element_ are consumed and the match succeeds.\nIf no occurrence of the _element_ is present on the input, the match succeeds anyway.\n\n**_element_ `+`**\n\nThe _element_ is repeatable.\nIf present on the input, one or more occurrences of the _element_ are consumed and the match succeeds.\nIf no occurrence of the _element_ is present on the input, the match fails.\n\n**`&` _element_**\n\nThe predicate succeeds only if the _element_ can be matched.\nThe input text scanned while matching _element_ is not consumed from the input and remains available for subsequent matching.\n\n**`!` _element_**\n\nThe predicate succeeds only if the _element_ cannot be matched.\nThe input text scanned while matching _element_ is not consumed from the input and remains available for subsequent matching.\nA popular idiom is the following, which matches the end of input, after the last character of the input has already been consumed.\n\n```\n!.\n```\n\n**`(` _pattern_ `)`**\n\nParentheses are used for grouping (modifying the precedence of the _pattern_).\n\n**`<` _pattern_ `>`**\n\nAngle brackets are used for grouping (modifying the precedence of the _pattern_) and text capturing.\nThe captured text is numbered in evaluation order, and can be referred to later using `$1`, `$2`, etc.\n\n**`$`_n_**\n\nA dollar (`$`) followed by a positive integer represents a text previously captured.\nThe positive integer corresponds to the order of capturing.\nA `$1` represents the first captured text.\nThe examples are shown below.\n\n```\n< [0-9]+ > 'foo' $1\n```\n\nThis matches `0foo0`, `123foo123`, etc.\n\n```\n'[' < '='* > '[' ( !( ']' $1 ']' ) . )* ( ']' $1 ']' )\n```\n\nThis matches `[[`...`]]`, `[=[`...`]=]`, `[==[`...`]==]`, etc.\n\n**`{` _c source code_ `}`**\n\nCurly braces surround an action.\nThe action is arbitrary C source code to be executed at the end of matching.\nAny braces within the action must be properly nested.\nNote that braces in directive lines and in comments (`/*`...`*/` and `//`...) are appropriately ignored.\nOne or more actions can be inserted in any places between elements in the pattern.\nActions are not executed where matching fails.\n\n```\n[0-9]+ 'foo' { puts(\"OK\"); } 'bar' / [0-9]+ 'foo' 'baz'\n```\n\nIn this example, if the input is `012foobar`, the action `{ puts(\"OK\"); }` is to be executed, but if the input is `012foobaz`,\nthe action is not to be executed.\nAll matched actions are guaranteed to be executed only once.\n\nIn the action, the C source code can use the predefined variables below.\n\n- **`$$`**\n    The output variable, to which the result of the rule is stored.\n    The data type is the one specified by `%value`.\n    The default data type is `int`.\n- **`auxil`**\n    The user-defined data that has been given via the API function `pcc_create()`.\n    The data type is the one specified by `%auxil`.\n    The default data type is `void *`.\n- _variable_\n    The result of another rule that has already been evaluated.\n    If the rule has not been evaluated, it is ensured that the value is zero-cleared (version 1.7.1 or later).\n    The data type is the one specified by `%value`.\n    The default data type is `int`.\n- **`$`**_n_\n    The string of the captured text.\n    The _n_ is the positive integer that corresponds to the order of capturing.\n    The variable `$1` holds the string of the first captured text.\n- **`$`**_n_**`s`**\n    The start position in the input of the captured text, inclusive.\n    The _n_ is the positive integer that corresponds to the order of capturing.\n    The variable `$1s` holds the start position of the first captured text.\n- **`$`**_n_**`e`**\n    The end position in the input of the captured text, exclusive.\n    The _n_ is the positive integer that corresponds to the order of capturing.\n    The variable `$1e` holds the end position of the first captured text.\n- **`$0`**\n    The string of the text between the start position in the input at which the rule pattern begins to match\n    and the current position in the input at which the element immediately before the action ends to match.\n- **`$0s`**\n    The start position in the input at which the rule pattern begins to match.\n- **`$0e`**\n    The current position in the input at which the element immediately before the action ends to match.\n\nAn example is shown below.\n\n```\nterm <- l:term _ '+' _ r:factor { $$ = l + r; }\nfactor <- < [0-9]+ >            { $$ = atoi($1); }\n_ <- [ \\t]*\n```\n\nNote that the string data held by `$`_n_ and `$0` are discarded immediately after evaluation of the action.\nIf the string data are needed after the action, they must be copied in `$$` or `auxil`.\nIf they are required to be copied in `$$`, it is recommended to define a structure as the type of output data using `%value`,\nand to copy the necessary string data in its member variable.\nSimilarly, if they are required to be copied in `auxil`, it is recommended to define a structure as the type of user-defined data using `%auxil`,\nand to copy the necessary string data in its member variable.\n\nThe position values are 0-based; that is, the first position is 0.\nThe data type is `size_t` (before version 1.4.0, it was `int`).\n\n**_element_ `~` `{` _c source code_ `}`**\n\nCurly braces following tilde (`~`) surround an error action.\nThe error action is arbitrary C source code to be executed at the end of matching only if the preceding _element_ matching fails.\nAny braces within the error action must be properly nested.\nNote that braces in directive lines and in comments (`/*`...`*/` and `//`...) are appropriately ignored.\nOne or more error actions can be inserted in any places after elements in the pattern.\nThe operator tilde (`~`) binds less tightly than any other operator except alternation (`/`) and sequencing.\nThe error action is intended to make error handling and recovery code easier to write.\nIn the error action, all predefined variables described above are available as well.\nThe examples are shown below.\n\n```\nrule1 <- e1 e2 e3 ~{ error(\"e[12] ok; e3 has failed\"); }\nrule2 <- (e1 e2 e3) ~{ error(\"one of e[123] has failed\"); }\n```\n\n**`%header` `{` _c source code_ `}`**\n\nThe specified C source code is copied verbatim to the C header file before the generated parser API function declarations.\nAny braces in the C source code must be properly nested.\nNote that braces in directive lines and in comments (`/*`...`*/` and `//`...) are appropriately ignored.\n\n**`%source` `{` _c source code_ `}`**\n\nThe specified C source code is copied verbatim to the C source file before the generated parser implementation code.\nAny braces in the C source code must be properly nested.\nNote that braces in directive lines and in comments (`/*`...`*/` and `//`...) are appropriately ignored.\n\n**`%common` `{` _c source code_ `}`**\n\nThe specified C source code is copied verbatim to both of the C header file and the C source file\nbefore the generated parser API function declarations and the implementation code respectively.\nAny braces in the C source code must be properly nested.\nNote that braces in directive lines and in comments (`/*`...`*/` and `//`...) are appropriately ignored.\n\n**`%earlyheader` `{` _c source code_ `}`**\n\n**`%earlysource` `{` _c source code_ `}`**\n\n**`%earlycommon` `{` _c source code_ `}`**\n\nSame as `%header`, `%source` and `%common`, respectively.\nThe only difference is that these directives place the code at the very beginning of the generated file,\nbefore any code or includes generated by PackCC.\nThis can be useful for example when it is necessary to modify behavior of standard libraries via a macro definition.\n\n**`%value` `\"`_output data type_`\"`**\n\nThe type of output data, which is output as `$$` in each action and can be retrieved from the parser API function `pcc_parse()`,\nis changed to the specified one from the default `int`.\n\n**`%auxil` `\"`_user-defined data type_`\"`**\n\nThe type of user-defined data, which is passed to the parser API function `pcc_create()`,\nis changed to the specified one from the default `void *`.\n\n**`%prefix` `\"`_prefix_`\"`**\n\nThe prefix of the parser API functions is changed to the specified one from the default `pcc`.\n\n**`#`_comment_**\n\nA comment can be inserted between `#` and the end of the line.\n\n**`%%`**\n\nA double percent `%%` terminates the section for rule definitions of the grammar.\nAll text following `%%` is copied verbatim to the C source file after the generated parser implementation code.\n\n<small>(The specification is determined by referring to [peg/leg](http://piumarta.com/software/peg/) developed by Ian Piumarta.)</small>\n\n### Macros ###\n\nSome macros are prepared to customize the parser.\nThe macro definition should be in <u>`%source` section</u> in the PEG source.\n\n```\n%source {\n#define PCC_GETCHAR(auxil) get_character((auxil)->input)\n#define PCC_BUFFERSIZE 1024\n}\n```\n\nThe following macros are available.\n\n**`PCC_GETCHAR(`**_auxil_**`)`**\n\nThe function macro to get a character from the input.\nThe user-defined data passed to the API function `pcc_create()` can be retrieved from the argument _auxil_.\nIt can be ignored if no user-defined data.\nThis macro must return a character code as an `int` type, or `-1` if the input ends.\n\nThe default is defined as below.\n\n```C\n#define PCC_GETCHAR(auxil) getchar()\n```\n\n**`PCC_ERROR(`**_auxil_**`)`**\n\nThe function macro to handle a syntax error.\nThe user-defined data passed to the API function `pcc_create()` can be retrieved from the argument _auxil_.\nIt can be ignored if no user-defined data.\nThis macro need not return a value.\nIt may abort the process (by using `exit()` for example) when a fatal error occurs, and can also return normally to deal with warnings.\n\nThe default is defined as below.\n\n```C\n#define PCC_ERROR(auxil) pcc_error()\nstatic void pcc_error(void) {\n    fprintf(stderr, \"Syntax error\\n\");\n    exit(1);\n}\n```\n\n**`PCC_MALLOC(`**_auxil_**`,`**_size_**`)`**\n\nThe function macro to allocate a memory block.\nThe user-defined data passed to the API function `pcc_create()` can be retrieved from the argument _auxil_.\nIt can be ignored if no user-defined data.\nThe argument _size_ is the number of bytes to allocate.\nThis macro must return a pointer to the allocated memory block, or `NULL` if no sufficient memory is available.\n\nThe default is defined as below.\n\n```C\n#define PCC_MALLOC(auxil, size) pcc_malloc_e(size)\nstatic void *pcc_malloc_e(size_t size) {\n    void *p = malloc(size);\n    if (p == NULL) {\n        fprintf(stderr, \"Out of memory\\n\");\n        exit(1);\n    }\n    return p;\n}\n```\n\n**`PCC_REALLOC(`**_auxil_**`,`**_ptr_**`,`**_size_**`)`**\n\nThe function macro to reallocate the existing memory block.\nThe user-defined data passed to the API function `pcc_create()` can be retrieved from the argument _auxil_.\nIt can be ignored if no user-defined data.\nThe argument _ptr_ is the pointer to the previously allocated memory block.\nThe argument _size_ is the new number of bytes to reallocate.\nThis macro must return a pointer to the reallocated memory block, or `NULL` if no sufficient memory is available.\nThe contents of the memory block should be left unchanged in any case even if the reallocation fails.\n\nThe default is defined as below.\n\n```C\n#define PCC_REALLOC(auxil, ptr, size) pcc_realloc_e(ptr, size)\nstatic void *pcc_realloc_e(void *ptr, size_t size) {\n    void *p = realloc(ptr, size);\n    if (p == NULL) {\n        fprintf(stderr, \"Out of memory\\n\");\n        exit(1);\n    }\n    return p;\n}\n```\n\n**`PCC_FREE(`**_auxil_**`,`**_ptr_**`)`**\n\nThe function macro to free the existing memory block.\nThe user-defined data passed to the API function `pcc_create()` can be retrieved from the argument _auxil_.\nIt can be ignored if no user-defined data.\nThe argument _ptr_ is the pointer to the previously allocated memory block.\nThis macro need not return a value.\n\nThe default is defined as below.\n\n```C\n#define PCC_FREE(auxil, ptr) free(ptr)\n```\n\n**`PCC_DEBUG(`**_auxil_**`,`**_event_**`,`**_rule_**`,`**_level_**`,`**_pos_**`,`**_buffer_**`,`**_length_**`)`**\n\nThe function macro for debugging (version 1.5.0 or later).\nSometimes, especially for complex parsers, it is useful to see how exactly the parser processes the input.\nThis macro is called on important *events* and allows to log or display the current state of the parser.\nThe argument `rule` is a string that contains the name of the currently evaluated rule.\nThe non-negative integer `level` specifies how deep in the rule hierarchy the parser currently is.\nThe argument `pos` holds the position from the start of the current context in bytes.\nIn case of `event == PCC_DBG_MATCH`, the argument `buffer` holds the matched input and `length` is its size.\nFor other events, `buffer` and `length` indicate a part of the currently loaded input, which is used to evaluate the current rule.\n\n**Caution:** Since version 1.6.0, the first argument _auxil_ is added to this macro.\nThe user-defined data passed to the API function `pcc_create()` can be retrieved from this argument.\n\nThere are currently three supported events:\n - `PCC_DBG_EVALUATE` (= 0) - called when the parser starts to evaluate `rule`\n - `PCC_DBG_MATCH` (= 1) - called when `rule` is matched, at which point buffer holds entire matched string\n - `PCC_DBG_NOMATCH` (= 2) - called when the parser determines that the input does not match currently evaluated `rule`\n\nA very simple implementation could look like this:\n\n```C\nstatic const char *dbg_str[] = { \"Evaluating rule\", \"Matched rule\", \"Abandoning rule\" };\n#define PCC_DEBUG(auxil, event, rule, level, pos, buffer, length) \\\n    fprintf(stderr, \"%*s%s %s @%zu [%.*s]\\n\", (int)((level) * 2), \"\", dbg_str[event], rule, pos, (int)(length), buffer)\n```\n\nThe default is to do nothing:\n\n```C\n#define PCC_DEBUG(auxil, event, rule, level, pos, buffer, length) ((void)0)\n```\n\n**`PCC_BUFFERSIZE`**\n\nThe initial size (the number of characters) of the text buffer.\nThe text buffer is expanded as needed.\nThe default is `256`.\n\n**`PCC_ARRAYSIZE`**\n\nThe initial size (the number of elements) of the internal arrays other than the text buffer.\nThe arrays are expanded as needed.\nThe default is `2`.\n\n### API ###\n\nThe parser API has only 3 simple functions below.\n\n```C\npcc_context_t *pcc_create(void *auxil);\n```\n\nCreates a parser context.\nThis context needs to be passed to the functions below.\nThe `auxil` can be used to pass user-defined data to be bound to the context.\n`NULL` can be specified if no user-defined data.\n\n```C\nint pcc_parse(pcc_context_t *ctx, int *ret);\n```\n\nParses an input text (from standard input by default) and returns the result in `ret`.\nThe `ret` can be `NULL` if no output data is needed.\nThis function returns `0` if no text is left to be parsed, or a nonzero value otherwise.\n\n```C\nvoid pcc_destroy(pcc_context_t *ctx);\n```\n\nDestroys the parser context.\nAll resources allocated in the parser context are released.\n\nThe type of output data `ret` can be changed.\nIf you want change it to `char *`, specify `%value \"char *\"` in the PEG source.\nThe default is `int`.\n\nThe type of user-defined data `auxil` can be changed.\nIf you want change it to `long`, specify `%auxil \"long\"` in the PEG source.\nThe default is `void *`.\n\nThe prefix `pcc` can be changed.\nIf you want change it to `foo`, specify `%prefix \"foo\"` in the PEG source.\nThe default is `pcc`.\n\nAfter the above settings, the API functions change like below.\n\n```C\nfoo_context_t *foo_create(long auxil);\n```\n\n```C\nint foo_parse(foo_context_t *ctx, char **ret);\n```\n\n```C\nvoid foo_destroy(foo_context_t *ctx);\n```\n\nThe typical usage of the API functions is shown below.\n\n```C\nint ret;\npcc_context_t *ctx = pcc_create(NULL);\nwhile (pcc_parse(ctx, &ret));\npcc_destroy(ctx);\n```\n\n## Examples ##\n\n### Desktop calculator ###\n\nA simple example which provides interactive four arithmetic operations of integers is shown here.\nNote that **left-recursive** grammar rules are defined in this example.\n\n```\n%prefix \"calc\"\n\n%source {\n#include <stdio.h>\n#include <stdlib.h>\n}\n\nstatement <- _ e:expression _ EOL { printf(\"answer=%d\\n\", e); }\n           / ( !EOL . )* EOL      { printf(\"error\\n\"); }\n\nexpression <- e:term { $$ = e; }\n\nterm <- l:term _ '+' _ r:factor { $$ = l + r; }\n      / l:term _ '-' _ r:factor { $$ = l - r; }\n      / e:factor                { $$ = e; }\n\nfactor <- l:factor _ '*' _ r:unary { $$ = l * r; }\n        / l:factor _ '/' _ r:unary { $$ = l / r; }\n        / e:unary                  { $$ = e; }\n\nunary <- '+' _ e:unary { $$ = +e; }\n       / '-' _ e:unary { $$ = -e; }\n       / e:primary     { $$ = e; }\n\nprimary <- < [0-9]+ >               { $$ = atoi($1); }\n         / '(' _ e:expression _ ')' { $$ = e; }\n\n_      <- [ \\t]*\nEOL    <- '\\n' / '\\r\\n' / '\\r' / ';'\n\n%%\nint main() {\n    calc_context_t *ctx = calc_create(NULL);\n    while (calc_parse(ctx, NULL));\n    calc_destroy(ctx);\n    return 0;\n}\n```\n\n### AST builder for Tiny-C ###\n\nYou can find the more practical example in the directory [`examples/ast-tinyc`](examples/ast-tinyc).\nIt builds an AST (abstract syntax tree) from an input source file\nwritten in [Tiny-C](http://www.iro.umontreal.ca/~felipe/IFT2030-Automne2002/Complements/tinyc.c) and dump the AST.\n"
  },
  {
    "path": "misc/packcc/benchmark/benchmark.sh",
    "content": "#!/usr/bin/env bash\n#\n# Generates, builds and runs parsers from grammars directory for each git reference supplied as argument.\n# Each action is performed multiple times and the times are averaged. Peak memory consumption is also measured.\n# First reference is always taken as a \"baseline\" and others are compared to it. This should allow to compare\n# how any given commit affects PackCCs performance.\n#\n# Usage:\n#   ./benchmark.sh <git ref> ...\n#\n# Environment:\n#   CC              Compiler to use, default: \"cc -O2\"\n#   GEN_REPEATS     How many times to generate the parser, default: 10\n#   BUILD_REPEATS   How many times to build the parser, default: 5\n#   RUN_REPEATS     How many times to run the given parser, default: 20\n#\n# Example:\n#   CC=\"clang -O3\" ./benchmark.sh origin/master 6015afc HEAD\n\nbuild() {\n    echo \"Building packcc...\"\n    $CC -o \"$PACKCC\" $ROOTDIR/src/packcc.c\n}\n\nclean() {\n    rm -rf \"$BENCHDIR/tmp\"\n}\n\nformat() {\n    TIME=\"$1\"\n    if [ $((TIME / 1000000000)) -gt 10 ]; then\n        echo \"$((TIME / 1000000000)) s\"\n    elif [ $((TIME / 1000000)) -gt 10 ]; then\n        echo \"$((TIME / 1000000)) ms\"\n    elif [ $((TIME / 1000)) -gt 10 ]; then\n        echo \"$((TIME / 1000)) us\"\n    else\n        echo \"$TIME ns\"\n    fi\n}\n\nformat_mem() {\n    MEM=\"$1\"\n    if [ -z \"$TIME_CMD\" ]; then\n        echo \"??? kB\"\n    elif [ $((MEM / 1048576)) -gt 10 ]; then\n        echo \"$((MEM / 1048576)) GB\"\n    elif [ $((MEM / 1024)) -gt 10 ]; then\n        echo \"$((MEM / 1024)) MB\"\n    else\n        echo \"$MEM kB\"\n    fi\n}\n\nmeasure() {\n    COUNT=\"$1\"\n    shift\n    MEM=0\n    if [ \"$TIME_CMD\" ]; then\n        MEM=\"$(${TIME_CMD[@]} -f %M \"$@\" 2>&1 >/dev/null)\"\n    fi\n    START=\"$(date '+%s%N')\"\n    for ((i=0; i<COUNT; i++)); do\n        \"$@\" > /dev/null\n    done\n    END=\"$(date '+%s%N')\"\n    TIME=$(( END - START ))\n}\n\nbenchmark() {\n    KEY=\"${GRAMMAR}_${REF//\\//_}\"\n    NAME=\"tmp/parser_$KEY\"\n\n    echo \"Generating $GRAMMAR parser in $REF ($GEN_REPEATS times)...\"\n    measure \"$GEN_REPEATS\" \"$PACKCC\" -o \"$NAME\" \"$GRAMMAR_FILE\"\n    GEN_TIME[\"$KEY\"]=$TIME\n    GEN_MEM[\"$KEY\"]=$MEM\n    echo \"  Repeated $GEN_REPEATS times in $(format $TIME), peak memory $(format_mem $MEM)\"\n\n    echo \"Building $GRAMMAR parser in $REF ($BUILD_REPEATS times)...\"\n    measure \"$BUILD_REPEATS\" $CC -I. \"$NAME\".c -o \"$NAME\"\n    BUILD_TIME[\"$KEY\"]=$TIME\n    BUILD_MEM[\"$KEY\"]=$MEM\n    echo \"  Built $BUILD_REPEATS times in $(format $TIME), peak memory $(format_mem $MEM)\"\n\n    echo \"Running $GRAMMAR parser in $REF ($RUN_REPEATS times)...\"\n    measure \"$RUN_REPEATS\" \"./$NAME\" \"$INPUT\"\n    RUN_TIME[\"$KEY\"]=$TIME\n    RUN_MEM[\"$KEY\"]=$MEM\n    echo \"  Repeated $RUN_REPEATS times in $(format $TIME), peak memory $(format_mem $MEM)\"\n}\n\nprint_table() {\n    declare -n RESULTS_TIME=\"${1}_TIME\"\n    declare -n RESULTS_MEM=\"${1}_MEM\"\n    printf \"%-12s\" \"\"\n    for REF in \"${REFS[@]}\"; do\n        printf \"%-32s\" \"$REF\"\n    done\n    printf \"\\n\"\n    MEMORY=0\n    RELATIVE_MEM=\"???\"\n    COLOR_MEM=0\n    for GRAMMAR in \"${GRAMMARS[@]}\"; do\n        printf \"%-12s\" \"$GRAMMAR\"\n        for REF in \"${REFS[@]}\"; do\n            KEY=\"${GRAMMAR}_${REF//\\//_}\"\n            BASE=\"${GRAMMAR}_${REFS[0]//\\//_}\"\n            TIME=\"$((${RESULTS_TIME[\"$KEY\"]} / RUN_REPEATS))\"\n            RELATIVE_TIME=\"$((100 * RESULTS_TIME[\"$KEY\"] / RESULTS_TIME[\"$BASE\"]))\"\n            COLOR=$((RELATIVE_TIME == 100 ? 0 : ( RELATIVE_TIME > 100 ? 31 : 32)))\n            if [ \"$TIME_CMD\" ]; then\n                MEMORY=\"${RESULTS_MEM[\"$KEY\"]}\"\n                RELATIVE_MEM=\"$((100 * RESULTS_MEM[\"$KEY\"] / RESULTS_MEM[\"$BASE\"]))\"\n                COLOR_MEM=$((RELATIVE_MEM == 100 ? 0 : ( RELATIVE_MEM > 100 ? 31 : 32)))\n            fi\n            printf \"\\033[0;${COLOR}m%-16s\\033[0;${COLOR_MEM}m%-16s\\033[0m\" \"$(format $TIME) ($RELATIVE_TIME%)\" \"$(format_mem $MEMORY) ($RELATIVE_MEM%)\"\n        done\n        printf \"\\n\"\n    done\n}\n\nprint_results() {\n    echo\n    echo \"Generation performance:\"\n    echo \"=======================\"\n    print_table GEN\n    echo\n    echo \"Build performance:\"\n    echo \"==================\"\n    print_table BUILD\n    echo\n    echo \"Run performance:\"\n    echo \"================\"\n    print_table RUN\n    echo\n}\n\nmain() {\n    set -e\n\n    BENCHDIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n    ROOTDIR=\"$BENCHDIR/..\"\n    declare -a GRAMMARS=()\n    declare -A BUILD_TIME GEN_TIME RUN_TIME BUILD_MEM GEN_MEM RUN_MEM\n\n    declare -i GEN_REPEATS=\"${GEN_REPEATS:-1}\"\n    declare -i BUILD_REPEATS=\"${BUILD_REPEATS:-1}\"\n    declare -i RUN_REPEATS=\"${RUN_REPEATS:-1}\"\n    CC=\"${CC:-cc -O2}\"\n    REFS=(\"$@\")\n\n    if [[ $# -eq 0 || \"$1\" =~ -h|--help|--usage ]]; then\n        sed -n '3,/^$/s/^#//p' \"$0\"\n        exit 0\n    fi\n\n    if which busybox &> /dev/null; then\n        TIME_CMD=(busybox time)\n    elif which time &> /dev/null; then\n        TIME_CMD=(\"$(which time)\")\n    else\n        echo \"NOTE: No time command found, please install GNU time or busybox to measure memory consumption.\"\n        TIME_CMD=\"\"\n    fi\n\n    START_REF=\"$(git name-rev --name-only HEAD)\"\n    trap \"echo 'Returning to $START_REF...' && git checkout $START_REF\" EXIT ERR INT\n\n    cd \"$BENCHDIR\"\n    clean\n    mkdir \"tmp\"\n    cp -aL inputs grammars tmp/\n\n    for REF in \"${REFS[@]}\"; do\n        PACKCC=\"tmp/packcc_${REF//\\//_}\"\n        git checkout \"$REF\"\n        build\n        for GRAMMAR_FILE in \"tmp/grammars\"/*.peg ; do\n            GRAMMAR=\"$(basename \"$GRAMMAR_FILE\" .peg)\"\n            [ \"$REF\" == \"${REFS[0]}\" ] && GRAMMARS+=(\"$GRAMMAR\")\n            INPUT=\"$(ls \"tmp/inputs/$GRAMMAR\"*)\"\n            benchmark\n        done\n    done\n\n    print_results\n}\n\nmain \"$@\"\n"
  },
  {
    "path": "misc/packcc/benchmark/grammars/calc.peg",
    "content": "%prefix \"calc\"\n\n%source {\n#include <stdio.h>\n#include <stdlib.h>\n}\n\nstatement <- _ e:expression _ EOL { printf(\"answer=%d\\n\", e); }\n           / ( !EOL . )* EOL      { printf(\"error\\n\"); }\n\nexpression <- e:term { $$ = e; }\n\nterm <- l:term _ '+' _ r:factor { $$ = l + r; }\n      / l:term _ '-' _ r:factor { $$ = l - r; }\n      / e:factor                { $$ = e; }\n\nfactor <- l:factor _ '*' _ r:unary { $$ = l * r; }\n        / l:factor _ '/' _ r:unary { $$ = l / r; }\n        / e:unary                  { $$ = e; }\n\nunary <- '+' _ e:unary { $$ = +e; }\n       / '-' _ e:unary { $$ = -e; }\n       / e:primary     { $$ = e; }\n\nprimary <- < [0-9]+ >               { $$ = atoi($1); }\n         / '(' _ e:expression _ ')' { $$ = e; }\n\n_      <- [ \\t]*\nEOL    <- '\\n' / '\\r\\n' / '\\r' / ';'\n\n%%\nint main(int argc, char **argv) {\n    if (argc > 1) {\n        freopen(argv[1], \"r\", stdin);\n    }\n    calc_context_t *ctx = calc_create(NULL);\n    while (calc_parse(ctx, NULL));\n    calc_destroy(ctx);\n    return 0;\n}\n"
  },
  {
    "path": "misc/packcc/benchmark/grammars/json.peg",
    "content": "%prefix \"json\"\n\nfile <- _ (object / array) _\nobject <- '{' ( pair (',' pair)* / _ ) '}'\npair <- _ string _ ':' value\narray <- '[' ( value (',' value)* / _ ) ']'\nvalue <- _ (object / array / boolean / number / string / null) _\nboolean <- 'false' / 'true'\nnumber <- '-'? ('0' / [1-9] [0-9]*) ('.' [0-9]+)? ([eE] [-+]? [0-9]+)?\nstring <- '\"' ('\\\\\"' / [^\"])* '\"'\nnull <- 'null'\n_  <- [ \\n\\r\\t]*\n\n%%\nint main(int argc, char **argv) {\n    if (argc > 1) {\n        freopen(argv[1], \"r\", stdin);\n    }\n    json_context_t *ctx = json_create(NULL);\n    while (json_parse(ctx, NULL));\n    json_destroy(ctx);\n    return 0;\n}\n"
  },
  {
    "path": "misc/packcc/benchmark/grammars/kotlin.peg",
    "content": "file <- shebangLine? NL* fileAnnotation* _* packageHeader* _* importList* _* (filePart / _ / unparsable)* EOF\nfilePart <- (topLevelObject / (statement _* semi))\nunparsable <- [^\\n]+ NL* { printf(\"Syntax error at byte %d\\n\", $0s);}\n\n### Converted from peg/kotlin/KotlinParser.g4\n\n# options\n# // SECTION: general\n#kotlinFile <- shebangLine? NL* fileAnnotation* _* packageHeader _* importList _* topLevelObject* EOF\n#script <- shebangLine? NL* fileAnnotation* _* packageHeader _* importList _* (statement _* semi)* EOF\nshebangLine <- ShebangLine _* NL+\nfileAnnotation <- (AT_NO_WS / AT_PRE_WS) FILE NL* COLON _* NL* (LSQUARE _* unescapedAnnotation+ _* RSQUARE / unescapedAnnotation) _* NL*\npackageHeader <- PACKAGE _ <identifier> {printf(\"%s\", $1);} _* semi?\nimportList <- importHeader+\nimportHeader <- IMPORT _ identifier (DOT MULT / importAlias)? _* semi? _*\nimportAlias <- _ AS _ simpleIdentifier\ntopLevelObject <- declaration _* semis?\ntypeAlias <- modifiers? _* TYPE_ALIAS (_ / NL)* <simpleIdentifier> {printf(\"%s\\n\", $1);} _* (__* typeParameters)? __* ASSIGNMENT __* type\ndeclaration <- classDeclaration / objectDeclaration / functionDeclaration / propertyDeclaration / typeAlias\n\n# // SECTION: classes\nclassDeclaration <- modifiers? (CLASS / (FUN __*)? INTERFACE) _ NL* <simpleIdentifier> {printf(\"%s\\n\", $1);} (__* typeParameters)? (__* primaryConstructor)? (__* COLON __* delegationSpecifiers)? (__* typeConstraints)? (__* classBody / __* enumClassBody)?\nprimaryConstructor <- (modifiers? CONSTRUCTOR __*)? classParameters\nclassBody <- LCURL __* classMemberDeclarations __* RCURL\nclassParameters <- LPAREN __* (classParameter (__* COMMA __* classParameter)* (__* COMMA)?)? __* RPAREN\nclassParameter <- (modifiers? _* VAL / modifiers? _* VAR / modifiers? _*)? __* <simpleIdentifier> {printf(\"%s\\n\", $1);} _* COLON __* type (__* ASSIGNMENT __* expression)?\ndelegationSpecifiers <- annotatedDelegationSpecifier (__* COMMA __* annotatedDelegationSpecifier)*\ndelegationSpecifier <- constructorInvocation / explicitDelegation / userType / functionType\nconstructorInvocation <- userType _* valueArguments\nannotatedDelegationSpecifier <- annotation* __* delegationSpecifier\nexplicitDelegation <- (userType / functionType) __* BY __* expression\ntypeParameters <- LANGLE __* typeParameter (__* COMMA __* typeParameter)* (__* COMMA)? __* RANGLE\ntypeParameter <- typeParameterModifiers? __* simpleIdentifier (__* COLON __* type)?\ntypeConstraints <- WHERE __* typeConstraint (__* COMMA __* typeConstraint)*\ntypeConstraint <- annotation* simpleIdentifier __* COLON __* type\n\n# // SECTION: classMembers\nclassMemberDeclarations <- (classMemberDeclaration semis?)*\nclassMemberDeclaration <- secondaryConstructor / anonymousInitializer / companionObject / declaration\nanonymousInitializer <- INIT __* block\ncompanionObject <- modifiers? COMPANION __* OBJECT <(__* simpleIdentifier)?> {printf(\"%s\\n\", $1e-$1s != 0 ? $1 : \"Companion\");} (__* COLON __* delegationSpecifiers)? (__* classBody)?\nfunctionValueParameters <- LPAREN __* (functionValueParameter (__* COMMA __* functionValueParameter)* (__* COMMA)?)? __* RPAREN\nfunctionValueParameter <- parameterModifiers? _* parameter (__* ASSIGNMENT __* expression)?\nfunctionDeclaration <- modifiers? _* FUN _* (__* typeParameters)? _* (__* receiverTypeAndDot)? __* <simpleIdentifier> {printf(\"%s\\n\", $1);} __* functionValueParameters _* (__* COLON __* type)? _* (__* typeConstraints)? _* (__* functionBody)?\nfunctionBody <- block / ASSIGNMENT __* expression\nvariableDeclaration <- annotation* __* <simpleIdentifier> {printf(\"%s\\n\", $1);} (__* COLON __* type)?\nmultiVariableDeclaration <- LPAREN __* variableDeclaration _* (__* COMMA __* variableDeclaration)* _* (__* COMMA)? __* RPAREN\npropertyDeclaration <- modifiers? _* (VAL / VAR) _ (__* typeParameters)? (__* receiverTypeAndDot)? (__* (multiVariableDeclaration / variableDeclaration)) (__* typeConstraints)? (__* (ASSIGNMENT __* expression / propertyDelegate))? (semi? _* setter (NL* semi? _* getter)? / semi? _* getter (NL* semi? _* setter)?)?\npropertyDelegate <- BY __* expression\n# TODO: better handling of empty getters and setters?\ngetter <- (modifiers _*)? GET __* LPAREN __* RPAREN (__* COLON __* type)? __* functionBody / (modifiers _*)? GET !(_* [^;\\r\\n])\nsetter <- (modifiers _*)? SET __* LPAREN __* parameterWithOptionalType (__* COMMA)? __* RPAREN (__* COLON __* type)? __* functionBody / (modifiers _*)? SET !(_* [^;\\r\\n])\nparametersWithOptionalType <- LPAREN __* (parameterWithOptionalType (__* COMMA __* parameterWithOptionalType)* (__* COMMA)?)? __* RPAREN\nparameterWithOptionalType <- parameterModifiers? simpleIdentifier __* (COLON __* type)?\nparameter <- simpleIdentifier __* COLON __* type\nobjectDeclaration <- modifiers? _* OBJECT __* <simpleIdentifier> {printf(\"%s\\n\", $1);} (__* COLON __* delegationSpecifiers)? (__* classBody)?\nsecondaryConstructor <- modifiers? CONSTRUCTOR __* functionValueParameters (__* COLON __* constructorDelegationCall)? __* block?\nconstructorDelegationCall <- THIS __* valueArguments / SUPER __* valueArguments\n\n# // SECTION: enumClasses\nenumClassBody <- LCURL __* enumEntries? (__* SEMICOLON __* classMemberDeclarations)? __* RCURL\nenumEntries <- enumEntry (__* COMMA __* enumEntry)* __* COMMA?\nenumEntry <- (modifiers __*)? simpleIdentifier (__* valueArguments)? (__* classBody)?\n\n# // SECTION: types\ntype <- typeModifiers? ( functionType / nullableType / parenthesizedType / typeReference)\ntypeReference <- userType / DYNAMIC\nnullableType <- (typeReference / parenthesizedType) __* quest+\nquest <- !elvis (QUEST_WS / QUEST_NO_WS)\nuserType <- simpleUserType (__* DOT __* simpleUserType)*\nsimpleUserType <- simpleIdentifier (__* typeArguments)?\ntypeProjection <- typeProjectionModifiers? type / MULT\ntypeProjectionModifiers <- typeProjectionModifier+\ntypeProjectionModifier <- varianceModifier __* / annotation\nfunctionType <- (receiverType __* DOT __*)? functionTypeParameters __* ARROW __* type\nfunctionTypeParameters <- LPAREN __* (parameter / type)? _* (__* COMMA __* (parameter / type))* _* (__* COMMA)? __* RPAREN\nparenthesizedType <- LPAREN __* type __* RPAREN\nreceiverType <- (typeModifiers _*)? (nullableType / parenthesizedType / typeReference)\n# parenthesizedUserType <- LPAREN __* userType __* RPAREN / LPAREN __* parenthesizedUserType __* RPAREN\nreceiverTypeAndDot <- (typeModifiers _*)? (nullableType __* DOT __* / parenthesizedType __* DOT __* / (simpleUserType __* DOT __*)+)\n\n# // SECTION: statements\n#statements <- (statement (semis statement)*)? semis?\nstatements <- (statement _* (semis _* statement _*)*)? _* semis?\nstatement <- (label / annotation)* ( declaration / assignment / loopStatement / expression)\nlabel <- simpleIdentifier (AT_POST_WS / AT_NO_WS) __*\ncontrolStructureBody <- block / statement\nblock <- LCURL __* statements __* RCURL\nloopStatement <- forStatement / whileStatement / doWhileStatement\nforStatement <- FOR __* LPAREN _* annotation* _* (variableDeclaration / multiVariableDeclaration) _ IN _ inside_expression _* RPAREN __* (controlStructureBody)?\nwhileStatement <- WHILE __* LPAREN _* inside_expression _* RPAREN __* controlStructureBody / WHILE __* LPAREN _* expression _* RPAREN __* SEMICOLON\ndoWhileStatement <- DO __* controlStructureBody? __* WHILE __* LPAREN _* expression _* RPAREN\nassignment <- directlyAssignableExpression _* ASSIGNMENT __* expression / assignableExpression _* assignmentAndOperator __* expression\nsemi <- (_* (SEMICOLON / NL) _*) NL*\nsemis <- (_* (SEMICOLON / NL) _*)+\n\n# // SECTION: expressions\nexpression <- disjunction\ndisjunction <- conjunction (__* DISJ __* conjunction)*\nconjunction <- equality (__* CONJ __* equality)*\nequality <- comparison (_* equalityOperator __* comparison _*)*\ncomparison <- genericCallLikeComparison (_* comparisonOperator __* genericCallLikeComparison _*)*\ngenericCallLikeComparison <- infixOperation (_* callSuffix)*\ninfixOperation <- elvisExpression (_* inOperator __* elvisExpression / _* isOperator __* type)*\nelvisExpression <- infixFunctionCall (__* elvis __* infixFunctionCall)*\nelvis <- QUEST_NO_WS COLON\ninfixFunctionCall <- rangeExpression (_* simpleIdentifier __* rangeExpression)*\nrangeExpression <- additiveExpression (_* RANGE __* additiveExpression)*\nadditiveExpression <- multiplicativeExpression (_* additiveOperator __* multiplicativeExpression)*\nmultiplicativeExpression <- asExpression (_* multiplicativeOperator __* asExpression)*\nasExpression <- prefixUnaryExpression (__* asOperator __* type)*\nprefixUnaryExpression <- (unaryPrefix _*)* postfixUnaryExpression\nunaryPrefix <- annotation / label / prefixUnaryOperator __*\npostfixUnaryExpression <- primaryExpression (_* postfixUnarySuffix)+ / primaryExpression\npostfixUnarySuffix <- postfixUnaryOperator / typeArguments / callSuffix / indexingSuffix / navigationSuffix\ndirectlyAssignableExpression <- postfixUnaryExpression _* assignableSuffix / postfixUnaryExpression / simpleIdentifier / parenthesizedDirectlyAssignableExpression\nparenthesizedDirectlyAssignableExpression <- LPAREN __* inside_directlyAssignableExpression __* RPAREN\nassignableExpression <- prefixUnaryExpression / parenthesizedAssignableExpression\nparenthesizedAssignableExpression <- LPAREN __* inside_assignableExpression __* RPAREN\nassignableSuffix <- navigationSuffix / typeArguments / indexingSuffix\nindexingSuffix <- LSQUARE __* inside_expression (__* COMMA __* inside_expression)* (__* COMMA)? __* RSQUARE\nnavigationSuffix <- __* memberAccessOperator __* (simpleIdentifier / parenthesizedExpression / CLASS)\ncallSuffix <- typeArguments? _* valueArguments? _* annotatedLambda / typeArguments? _* valueArguments\nannotatedLambda <- annotation* _* label? __* lambdaLiteral\ntypeArguments <- LANGLE __* typeProjection (__* COMMA __* typeProjection)* (__* COMMA)? __* RANGLE\nvalueArguments <- LPAREN __* RPAREN / LPAREN __* inside_valueArgument (__* COMMA __* inside_valueArgument)* (__* COMMA)? __* RPAREN\n#valueArgument <- annotation? __* (simpleIdentifier __* ASSIGNMENT __*)? MULT? __* expression\nprimaryExpression <- thisExpression / superExpression / ifExpression / whenExpression / tryExpression / jumpExpression / parenthesizedExpression/ callableReference / stringLiteral / functionLiteral / objectLiteral / collectionLiteral  / simpleIdentifier / literalConstant\nparenthesizedExpression <- LPAREN __* inside_expression __* RPAREN\ncollectionLiteral <- LSQUARE __* inside_expression (__* COMMA __* inside_expression)* (__* COMMA)? __* RSQUARE / LSQUARE __* RSQUARE\nliteralConstant <- BooleanLiteral / CharacterLiteral / NullLiteral / RealLiteral / UnsignedLiteral / LongLiteral / HexLiteral / BinLiteral / IntegerLiteral\nstringLiteral <- multiLineStringLiteral / lineStringLiteral\nlineStringLiteral <- QUOTE_OPEN (lineStringExpression / lineStringContent)* QUOTE_CLOSE\n#lineStringLiteral <- QUOTE_OPEN (lineStringExpression / EscapedIdentifier / UniCharacterLiteral / stringChar)* QUOTE_CLOSE\nmultiLineStringLiteral <- TRIPLE_QUOTE_OPEN (multiLineStringExpression / multiLineStringContent / MultiLineStringQuote)* TRIPLE_QUOTE_CLOSE\n#multiLineStringLiteral <- TRIPLE_QUOTE_OPEN (multiLineStringExpression / MultiLineStringQuote / EscapedIdentifier / UniChracterLiteral / stringChar)* TRIPLE_QUOTE_CLOSE\nlineStringContent <- LineStrText / LineStrEscapedChar / LineStrRef\nlineStringExpression <- LineStrExprStart __* expression __* RCURL\nmultiLineStringContent <- MultiLineStrRef / MultiLineStrText / MultiLineStringQuote\nmultiLineStringExpression <- MultiLineStrExprStart __* expression __* RCURL\n\ninside_expression <- inside_disjunction\ninside_disjunction <- inside_conjunction (__* DISJ __* inside_conjunction)*\ninside_conjunction <- inside_equality (__* CONJ __* inside_equality)*\ninside_equality <- inside_comparison ((_ / NL)* equalityOperator __* inside_comparison (_ / NL)*)*\ninside_comparison <- inside_genericCallLikeComparison ((_ / NL)* comparisonOperator __* inside_genericCallLikeComparison (_ / NL)*)*\ninside_genericCallLikeComparison <- inside_infixOperation ((_ / NL)* callSuffix)*\ninside_infixOperation <- inside_elvisExpression ((_ / NL)* inOperator __* inside_elvisExpression / (_ / NL)* isOperator __* type)*\ninside_elvisExpression <- inside_infixFunctionCall (__* elvis __* inside_infixFunctionCall)*\ninside_infixFunctionCall <- inside_rangeExpression ((_ / NL)* simpleIdentifier __* inside_rangeExpression)*\ninside_rangeExpression <- inside_additiveExpression ((_ / NL)* RANGE __* inside_additiveExpression)*\ninside_additiveExpression <- inside_multiplicativeExpression ((_ / NL)* additiveOperator __* inside_multiplicativeExpression)*\ninside_multiplicativeExpression <- inside_asExpression ((_ / NL)* multiplicativeOperator __* inside_asExpression)*\ninside_asExpression <- inside_prefixUnaryExpression (__* asOperator __* type)*\ninside_prefixUnaryExpression <- (inside_unaryPrefix (_ / NL)*)* inside_postfixUnaryExpression\ninside_unaryPrefix <- annotation / label / prefixUnaryOperator __*\ninside_postfixUnaryExpression <- primaryExpression ((_ / NL)* inside_postfixUnarySuffix)+ / primaryExpression\ninside_postfixUnarySuffix <- postfixUnaryOperator / typeArguments / callSuffix / indexingSuffix / navigationSuffix\ninside_directlyAssignableExpression <- inside_postfixUnaryExpression (_ / NL)* assignableSuffix / inside_postfixUnaryExpression / simpleIdentifier / parenthesizedDirectlyAssignableExpression\ninside_assignableExpression <- inside_prefixUnaryExpression / parenthesizedAssignableExpression\ninside_valueArgument <- annotation? __* (simpleIdentifier __* ASSIGNMENT __*)? MULT? __* inside_expression\n\n\n#characterLiteral <- \"'\" (UniCharacterLiteral / EscapedIdentifier / [^\\n\\r'\\\\]) \"'\"\n#stringChar <- [^\"]\n\nlambdaLiteral <- LCURL {printf(\"<lambda>\\n\");} __* statements __* RCURL / LCURL {printf(\"<lambda>\\n\");} __* lambdaParameters? __* ARROW __* statements __* RCURL\nlambdaParameters <- lambdaParameter (__* COMMA __* lambdaParameter)* (__* COMMA)?\nlambdaParameter <- variableDeclaration / multiVariableDeclaration (__* COLON __* type)?\nanonymousFunction <- FUN {printf(\"<anonymous function>\");} (__* type __* DOT)? __* parametersWithOptionalType (__* COLON __* type)? (__* typeConstraints)? (__* functionBody)?\nfunctionLiteral <- lambdaLiteral / anonymousFunction\nobjectLiteral <- OBJECT __* COLON __* delegationSpecifiers __* classBody / OBJECT __* classBody\nthisExpression <- THIS_AT / THIS !(Letter / UnicodeDigit)\nsuperExpression <- SUPER_AT / SUPER (LANGLE __* type __* RANGLE)? (AT_NO_WS simpleIdentifier)?\nifExpression <- IF __* LPAREN __* expression __* RPAREN __* controlStructureBody? __* SEMICOLON? __* ELSE __* (controlStructureBody / SEMICOLON) / IF __* LPAREN __* expression __* RPAREN __* (controlStructureBody / SEMICOLON)\nwhenSubject <- LPAREN (annotation* __* VAL __* variableDeclaration __* ASSIGNMENT __*)? expression RPAREN\nwhenExpression <- WHEN __* whenSubject? __* LCURL __* (whenEntry __*)* __* RCURL\nwhenEntry <- whenCondition (__* COMMA __* whenCondition)* (__* COMMA)? __* ARROW __* controlStructureBody semi? / ELSE __* ARROW __* controlStructureBody semi?\nwhenCondition <- expression / rangeTest / typeTest\nrangeTest <- inOperator __* expression\ntypeTest <- isOperator __* type\ntryExpression <- TRY __* block ((__* catchBlock)+ (__* finallyBlock)? / __* finallyBlock)\ncatchBlock <- CATCH __* LPAREN _* (annotation _*)* simpleIdentifier _* COLON _* type (__* COMMA)? _* RPAREN __* block\nfinallyBlock <- FINALLY __* block\njumpExpression <- THROW __* expression / (RETURN_AT / RETURN) _* expression? / CONTINUE_AT / CONTINUE / BREAK_AT / BREAK\ncallableReference <- (receiverType? __* COLONCOLON __* (simpleIdentifier / CLASS))\nassignmentAndOperator <- ADD_ASSIGNMENT / SUB_ASSIGNMENT / MULT_ASSIGNMENT / DIV_ASSIGNMENT / MOD_ASSIGNMENT\nequalityOperator <- EQEQEQ / EQEQ / EXCL_EQEQ / EXCL_EQ\ncomparisonOperator <- LE / GE / LANGLE / RANGLE\ninOperator <- IN / NOT_IN\nisOperator <- IS / NOT_IS\nadditiveOperator <- ADD / SUB\nmultiplicativeOperator <- MULT / DIV / MOD\nasOperator <- AS_SAFE / AS\nprefixUnaryOperator <- INCR / DECR / SUB / ADD / excl\npostfixUnaryOperator <- INCR / DECR / EXCL_NO_WS excl\nexcl <- EXCL_WS / EXCL_NO_WS\nmemberAccessOperator <- DOT / safeNav / COLONCOLON\nsafeNav <- QUEST_NO_WS DOT\n\n# // SECTION: modifiers\nmodifiers <- (annotation / modifier)+\nparameterModifiers <- (annotation / parameterModifier)+\nmodifier <- (classModifier / memberModifier / visibilityModifier / functionModifier / propertyModifier / inheritanceModifier / parameterModifier / platformModifier) __*\ntypeModifiers <- typeModifier+\ntypeModifier <- annotation / SUSPEND __*\nclassModifier <- ENUM / SEALED / ANNOTATION / DATA / INNER\nmemberModifier <- OVERRIDE / LATEINIT\nvisibilityModifier <- PUBLIC / PRIVATE / INTERNAL / PROTECTED\nvarianceModifier <- IN / OUT\ntypeParameterModifiers <- typeParameterModifier+\ntypeParameterModifier <- reificationModifier __* / varianceModifier __* / annotation\nfunctionModifier <- TAILREC / OPERATOR / INFIX / INLINE / EXTERNAL / SUSPEND\npropertyModifier <- CONST\ninheritanceModifier <- ABSTRACT / FINAL / OPEN\nparameterModifier <- VARARG / NOINLINE / CROSSINLINE\nreificationModifier <- REIFIED\nplatformModifier <- EXPECT / ACTUAL\n\n# // SECTION: annotations\nannotation <- (singleAnnotation / multiAnnotation) __*\nsingleAnnotation <- annotationUseSiteTarget __* unescapedAnnotation / (AT_NO_WS / AT_PRE_WS) unescapedAnnotation\nmultiAnnotation <- annotationUseSiteTarget __* LSQUARE unescapedAnnotation+ RSQUARE / (AT_NO_WS / AT_PRE_WS) LSQUARE unescapedAnnotation+ RSQUARE\nannotationUseSiteTarget <- (AT_NO_WS / AT_PRE_WS) (FIELD / PROPERTY / GET / SET / RECEIVER / PARAM / SETPARAM / DELEGATE) __* COLON\nunescapedAnnotation <- constructorInvocation / userType\n\n# // SECTION: identifiers\nsimpleIdentifier <- !(hardKeyword !(Letter / '_' / UnicodeDigit)) Identifier / ABSTRACT / ANNOTATION / BY / CATCH / COMPANION / CONSTRUCTOR / CROSSINLINE / DATA / DYNAMIC / ENUM / EXTERNAL / FINAL / FINALLY / GET / IMPORT / INFIX / INIT / INLINE / INNER / INTERNAL / LATEINIT / NOINLINE / OPEN / OPERATOR / OUT / OVERRIDE / PRIVATE / PROTECTED / PUBLIC / REIFIED / SEALED / TAILREC / SET / VARARG / WHERE / FIELD / PROPERTY / RECEIVER / PARAM / SETPARAM / DELEGATE / FILE / EXPECT / ACTUAL / CONST / SUSPEND\nidentifier <- simpleIdentifier (__* DOT simpleIdentifier)*\n\nhardKeyword <- AS / BREAK / CLASS / CONTINUE / DO / ELSE / FOR / FUN / IF / IN / INTERFACE / IS / NullLiteral / OBJECT / PACKAGE / RETURN / SUPER / THIS / THROW / TRY / TYPE_ALIAS / TYPEOF / VAL / VAR / WHEN / WHILE / BooleanLiteral\n\n\n### Converted from peg/kotlin/KotlinLexer.g4\n\n\n# // SECTION: lexicalGeneral\nShebangLine <- '#!' [^\\r\\n]*\nDelimitedComment <- '/*' (DelimitedComment / !'*/' .)* '*/'\nLineComment <- '//' [^\\r\\n]*\n#WS <- [\\u0020\\u0009\\u000C]\n#NL <- '\\n' / '\\r' '\\n'?\nHidden <- DelimitedComment / LineComment / WS\n\n# // SECTION: separatorsAndOperations\n#RESERVED <- '...'\nDOT <- '.'\nCOMMA <- ','\nLPAREN <- '('\nRPAREN <- ')'\nLSQUARE <- '['\nRSQUARE <- ']'\nLCURL <- '{'\n# /*\n# * When using another programming language (not Java) to generate a parser,\n# * please replace this code with the corresponding code of a programming language you are using.\n# */\nRCURL <- '}'\nMULT <- '*'\nMOD <- '%'\nDIV <- '/'\nADD <- '+'\nSUB <- '-'\nINCR <- '++'\nDECR <- '--'\nCONJ <- '&&'\nDISJ <- '||'\nEXCL_WS <- '!' Hidden\nEXCL_NO_WS <- '!'\nCOLON <- ':'\nSEMICOLON <- ';'\nASSIGNMENT <- '=' !'='\nADD_ASSIGNMENT <- '+='\nSUB_ASSIGNMENT <- '-='\nMULT_ASSIGNMENT <- '*='\nDIV_ASSIGNMENT <- '/='\nMOD_ASSIGNMENT <- '%='\nARROW <- '->'\n#DOUBLE_ARROW <- '=>'\nRANGE <- '..'\nCOLONCOLON <- '::'\n#DOUBLE_SEMICOLON <- ';;'\n#HASH <- '#'\nAT_NO_WS <- '@'\nAT_POST_WS <- '@' (Hidden / NL)\nAT_PRE_WS <- (Hidden / NL) '@'\n#AT_BOTH_WS <- (Hidden / NL) '@' (Hidden / NL)\nQUEST_WS <- '?' Hidden\nQUEST_NO_WS <- '?'\nLANGLE <- '<'\nRANGLE <- '>'\nLE <- '<='\nGE <- '>='\nEXCL_EQ <- '!='\nEXCL_EQEQ <- '!=='\nAS_SAFE <- 'as?'\nEQEQ <- '=='\nEQEQEQ <- '==='\n#SINGLE_QUOTE <- '\\''\n\n# // SECTION: keywords\nRETURN_AT <- 'return@' Identifier\nCONTINUE_AT <- 'continue@' Identifier\nBREAK_AT <- 'break@' Identifier\nTHIS_AT <- 'this@' Identifier\nSUPER_AT <- 'super@' Identifier\nFILE <- 'file' !(Letter / UnicodeDigit)\nFIELD <- 'field' !(Letter / UnicodeDigit)\nPROPERTY <- 'property' !(Letter / UnicodeDigit)\nGET <- 'get' !(Letter / UnicodeDigit)\nSET <- 'set' !(Letter / UnicodeDigit)\nRECEIVER <- 'receiver' !(Letter / UnicodeDigit)\nPARAM <- 'param' !(Letter / UnicodeDigit)\nSETPARAM <- 'setparam' !(Letter / UnicodeDigit)\nDELEGATE <- 'delegate' !(Letter / UnicodeDigit)\nPACKAGE <- 'package' !(Letter / UnicodeDigit)\nIMPORT <- 'import' !(Letter / UnicodeDigit)\nCLASS <- 'class' !(Letter / UnicodeDigit)\nINTERFACE <- 'interface' !(Letter / UnicodeDigit)\nFUN <- 'fun' !(Letter / UnicodeDigit)\nOBJECT <- 'object' !(Letter / UnicodeDigit)\nVAL <- 'val' !(Letter / UnicodeDigit)\nVAR <- 'var' !(Letter / UnicodeDigit)\nTYPE_ALIAS <- 'typealias' !(Letter / UnicodeDigit)\nCONSTRUCTOR <- 'constructor' !(Letter / UnicodeDigit)\nBY <- 'by' !(Letter / UnicodeDigit)\nCOMPANION <- 'companion' !(Letter / UnicodeDigit)\nINIT <- 'init' !(Letter / UnicodeDigit)\nTHIS <- 'this' !(Letter / UnicodeDigit)\nSUPER <- 'super' !(Letter / UnicodeDigit)\nTYPEOF <- 'typeof' !(Letter / UnicodeDigit)\nWHERE <- 'where' !(Letter / UnicodeDigit)\nIF <- 'if' !(Letter / UnicodeDigit)\nELSE <- 'else' !(Letter / UnicodeDigit)\nWHEN <- 'when' !(Letter / UnicodeDigit)\nTRY <- 'try' !(Letter / UnicodeDigit)\nCATCH <- 'catch' !(Letter / UnicodeDigit)\nFINALLY <- 'finally' !(Letter / UnicodeDigit)\nFOR <- 'for' !(Letter / UnicodeDigit)\nDO <- 'do' !(Letter / UnicodeDigit)\nWHILE <- 'while' !(Letter / UnicodeDigit)\nTHROW <- 'throw' !(Letter / UnicodeDigit)\nRETURN <- 'return' !(Letter / UnicodeDigit)\nCONTINUE <- 'continue' !(Letter / UnicodeDigit)\nBREAK <- 'break' !(Letter / UnicodeDigit)\nAS <- 'as' !(Letter / UnicodeDigit)\nIS <- 'is' !(Letter / UnicodeDigit)\nIN <- 'in' !(Letter / UnicodeDigit)\nNOT_IS <- '!is' !(Letter / UnicodeDigit)\nNOT_IN <- '!in' !(Letter / UnicodeDigit)\nOUT <- 'out' !(Letter / UnicodeDigit)\nDYNAMIC <- 'dynamic' !(Letter / UnicodeDigit)\n\n# // SECTION: lexicalModifiers\nPUBLIC <- 'public' !(Letter / UnicodeDigit)\nPRIVATE <- 'private' !(Letter / UnicodeDigit)\nPROTECTED <- 'protected' !(Letter / UnicodeDigit)\nINTERNAL <- 'internal' !(Letter / UnicodeDigit)\nENUM <- 'enum' !(Letter / UnicodeDigit)\nSEALED <- 'sealed' !(Letter / UnicodeDigit)\nANNOTATION <- 'annotation' !(Letter / UnicodeDigit)\nDATA <- 'data' !(Letter / UnicodeDigit)\nINNER <- 'inner' !(Letter / UnicodeDigit)\nTAILREC <- 'tailrec' !(Letter / UnicodeDigit)\nOPERATOR <- 'operator' !(Letter / UnicodeDigit)\nINLINE <- 'inline' !(Letter / UnicodeDigit)\nINFIX <- 'infix' !(Letter / UnicodeDigit)\nEXTERNAL <- 'external' !(Letter / UnicodeDigit)\nSUSPEND <- 'suspend' !(Letter / UnicodeDigit)\nOVERRIDE <- 'override' !(Letter / UnicodeDigit)\nABSTRACT <- 'abstract' !(Letter / UnicodeDigit)\nFINAL <- 'final' !(Letter / UnicodeDigit)\nOPEN <- 'open' !(Letter / UnicodeDigit)\nCONST <- 'const' !(Letter / UnicodeDigit)\nLATEINIT <- 'lateinit' !(Letter / UnicodeDigit)\nVARARG <- 'vararg' !(Letter / UnicodeDigit)\nNOINLINE <- 'noinline' !(Letter / UnicodeDigit)\nCROSSINLINE <- 'crossinline' !(Letter / UnicodeDigit)\nREIFIED <- 'reified' !(Letter / UnicodeDigit)\nEXPECT <- 'expect' !(Letter / UnicodeDigit)\nACTUAL <- 'actual' !(Letter / UnicodeDigit)\n\n# // SECTION: literals\nDecDigit <- [0-9]\nDecDigitNoZero <- [1-9]\nDecDigitOrSeparator <- DecDigit / '_'\nDecDigits <- DecDigit DecDigitOrSeparator* / DecDigit\nDoubleExponent <- [eE] [-+]? DecDigits\nRealLiteral <- FloatLiteral / DoubleLiteral\nFloatLiteral <- DoubleLiteral [fF] / DecDigits [fF]\nDoubleLiteral <- DecDigits? '.' DecDigits DoubleExponent? / DecDigits DoubleExponent\nIntegerLiteral <- DecDigitNoZero DecDigitOrSeparator* / DecDigit\n#IntegerLiteral <- DecDigitNoZero DecDigitOrSeparator* DecDigit / DecDigit\nHexDigit <- [0-9a-fA-F]\nHexDigitOrSeparator <- HexDigit / '_'\nHexLiteral <- '0' [xX] HexDigit HexDigitOrSeparator* / '0' [xX] HexDigit\nBinDigit <- [01]\nBinDigitOrSeparator <- BinDigit / '_'\nBinLiteral <- '0' [bB] BinDigit BinDigitOrSeparator* / '0' [bB] BinDigit\nUnsignedLiteral <- (HexLiteral / BinLiteral / IntegerLiteral) [uU] [lL]?\nLongLiteral <- (HexLiteral / BinLiteral / IntegerLiteral) [lL]\nBooleanLiteral <- 'true'/ 'false'\nNullLiteral <- 'null'\nCharacterLiteral <- '\\'' (EscapeSeq / [^\\n\\r'\\\\]) '\\''\n\n# // SECTION: lexicalIdentifiers\n#UnicodeDigit <- UNICODE_CLASS_ND\nIdentifier <- '`' [^`\\r\\n]+ '`' / (Letter / '_') (Letter / '_' / UnicodeDigit)*\nIdentifierOrSoftKey <- Identifier / ABSTRACT / ANNOTATION / BY / CATCH / COMPANION / CONSTRUCTOR / CROSSINLINE / DATA / DYNAMIC / ENUM / EXTERNAL / FINAL / FINALLY / IMPORT / INFIX / INIT / INLINE / INNER / INTERNAL / LATEINIT / NOINLINE / OPEN / OPERATOR / OUT / OVERRIDE / PRIVATE / PROTECTED / PUBLIC / REIFIED / SEALED / TAILREC / VARARG / WHERE / GET / SET / FIELD / PROPERTY / RECEIVER / PARAM / SETPARAM / DELEGATE / FILE / EXPECT / ACTUAL / CONST / SUSPEND\nFieldIdentifier <- '$' IdentifierOrSoftKey\nUniCharacterLiteral <- '\\\\' 'u' HexDigit HexDigit HexDigit HexDigit\nEscapedIdentifier <- '\\\\' ('t' / 'b' / 'r' / 'n' / '\\'' / '\"' / '\\\\' / '$')\nEscapeSeq <- UniCharacterLiteral / EscapedIdentifier\n\n# // SECTION: characters\nLetter <- [\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376-\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E-\\u066F\\u0671-\\u06D3\\u06D5\\u06E5-\\u06E6\\u06EE-\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4-\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0\\u08A2-\\u08AC\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097F\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC-\\u09DD\\u09DF-\\u09E1\\u09F0-\\u09F1\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32-\\u0A33\\u0A35-\\u0A36\\u0A38-\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0-\\u0AE1\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C-\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58-\\u0C59\\u0C60-\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0-\\u0CE1\\u0CF1-\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32-\\u0E33\\u0E40-\\u0E46\\u0E81-\\u0E82\\u0E84\\u0E87-\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA-\\u0EAB\\u0EAD-\\u0EB0\\u0EB2-\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065-\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F0\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE-\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5-\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A-\\uA62B\\uA640-\\uA66E\\uA67F-\\uA697\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA793\\uA7A0-\\uA7AA\\uA7F8-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA80-\\uAAAF\\uAAB1\\uAAB5-\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uABC0-\\uABE2\\uAC00\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40-\\uFB41\\uFB43-\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]\nUnicodeDigit <- [\\u0030-\\u0039\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE6-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29\\u1040-\\u1049\\u1090-\\u1099\\u17E0-\\u17E9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19D9\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\uA620-\\uA629\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19]\n\n# // SECTION: strings\nQUOTE_OPEN <- '\"' !'\"\"'\nTRIPLE_QUOTE_OPEN <- '\"\"\"'\nQUOTE_CLOSE <- '\"'\nLineStrRef <- FieldIdentifier\n#LineStrText <- [^\\\\\"$]+ / '$'\nLineStrText <- [^\\\\\"$]+ / '$'\nLineStrEscapedChar <- EscapedIdentifier / UniCharacterLiteral\nLineStrExprStart <- '${'\nTRIPLE_QUOTE_CLOSE <- '\"\"\"\"\"'/ '\"\"\"\"' / '\"\"\"'\nMultiLineStringQuote <- '\"\"' !'\"' / '\"' !'\"\"'\nMultiLineStrRef <- FieldIdentifier\n#MultiLineStrText <- !('\"' / '$')+ / '$'\nMultiLineStrText <- [^\"$]+ / '$'\nMultiLineStrExprStart <- '${'\n\n_ <- (WS / DelimitedComment / LineComment)+\n__ <- ([ \\t\\f\\r\\n] / DelimitedComment / LineComment)+\nWS <- [ \\t\\f]\nNL <- _* ('\\n' / '\\r' '\\n'?) _*\nEOF <- !.\n\n%%\n\nint main(int argc, char **argv) {\n    if (argc > 1) {\n        freopen(argv[1], \"r\", stdin);\n    }\n    int ret;\n    pcc_context_t *ctx = pcc_create(NULL);\n    while (pcc_parse(ctx, &ret));\n    pcc_destroy(ctx);\n    return 0;\n}\n"
  },
  {
    "path": "misc/packcc/benchmark/inputs/calc.txt",
    "content": "(30738 * 23264 / 22572 - 17872)\n1640 * 8600\n(25293 + 5446 - 8430 + 6829)\n(15570 + 16599 + ((1337 * 5346 - 11359 * 551) - 14960 * 30086))\n(15111 - 10927 * 32362 * 30025)\n2359 * 5371\n349 * 4918\n17726 - 4964\n21226 * 10055\n(12300 + 29101 / 6378 * 20914)\n((11797 * 14761 + (6890 + 15914 - (12389 * 7100 + 12149 - 21937))) * 15504 + 27079)\n17781 * 4188\n((9967 + 13537 + 15725 - 20613) + 19564 + 30449)\n6369 + 13026\n31538 + 16603\n(32429 - 11401 - 29047 / 7680)\n25959 / 22650\n5895 - 13849\n(10312 - 29915 - 5292 + 23978)\n30068 + 16134\n2861 * 8574\n26934 - 28979\n32018 / 6956\n6212 - 30754\n(9830 - 23018 / 13028 + 26275)\n27569 - 21485\n7290 * 4748\n(20627 - 22687 - 31239 + 16810)\n29095 + 8258\n(6580 * 906 / 8953 * 13690)\n((((7022 - 21448 * 4992 + 3119) + 7593 - 19496) - 10951 - 9656) * 30712 - 5950)\n10576 + 20743\n(10717 + 17747 * (10356 - 9307 + 11102 + 28593))\n13473 / 31245\n(12932 + 18199 - (28264 - 8372 - 137 * 8561))\n14984 - 30779\n31927 - 1032\n15865 + 14649\n9017 - 15493\n(25994 / 2721 * 7519 - 28718)\n18363 * 4094\n32400 * 15307\n9955 - 29447\n10145 - 23332\n19398 / 27840\n25211 + 18210\n7390 / 14898\n9684 * 20873\n22019 * 25856\n(22917 * 12251 + 2116 / 30593)\n6159 * 1093\n(3369 - 22622 * 189 + 25500)\n13591 - 23285\n4624 - 8496\n1526 * 26734\n25487 * 24467\n26978 - 11784\n25231 / 32150\n(16562 + 9845 - 1800 - 26662)\n13272 + 25482\n6100 * 2582\n11746 - 1865\n(12063 + 31285 / 31472 - 2136)\n29673 + 3276\n7352 + 7640\n17332 - 10580\n20018 + 19408\n3789 - 29602\n(2698 * 21913 * 3475 * 18309)\n28133 - 22075\n23938 + 8482\n31078 + 2157\n((2164 * 13086 - 27911 - 15836) + 16167 * 16942)\n28747 + 24283\n7609 + 26933\n350 + 31322\n3211 - 24132\n17377 / 24456\n(5617 + 26664 / 15323 * 16105)\n(11993 - 3222 + 6596 - 13502)\n69 - 4410\n13148 - 26051\n29113 * 5140\n4971 - 2480\n9004 * 31434\n4938 * 12479\n22208 + 18717\n16219 - 19760\n(24354 + 28868 + 17160 + 891)\n16612 * 15115\n(8901 + 18373 + 9219 + 3461)\n32201 + 2520\n2198 + 8169\n16976 * 19706\n27944 + 21145\n((((14831 * 23714 / (6009 + 9540 * 20975 * 25927)) + 17053 * 30858) * 28367 - 6786) - (29865 - 6534 - 27873 + 9266))\n7094 + 206\n1073 * 12801\n((23077 + 20149 + 15143 - 27488) - 273 + 32595)\n2194 + 9039\n24877 - 23845\n25295 / 5245\n8217 - 20458\n8546 + 27458\n(24309 + 12145 * (22443 - 30463 - 30236 * 1703))\n22813 * 10323\n3330 * 20141\n26507 * 9196\n29584 / 24636\n7149 * 13523\n16938 + 3809\n6294 + 12226\n8900 - 17000\n25208 + 19246\n((6037 * 13555 + 14284 * 21791) + (5349 + 3450 / 23612 + 28052))\n6675 / 6796\n19691 - 1212\n213 + 6075\n27091 * 136\n10669 + 26101\n12133 * 11535\n9656 + 18280\n(565 + 17828 - 1442 - 11480)\n5163 - 28433\n20155 - 22361\n32304 - 24801\n20647 - 3930\n22777 * 28776\n23321 / 13717\n(17178 / 19708 + 986 + 12167)\n20370 + 30148\n19384 / 19146\n21571 - 14130\n(24851 / 12795 - 15519 * 6649)\n3138 * 21611\n28154 * 26774\n19783 - 12607\n4955 + 18822\n19545 + 24256\n17215 - 29977\n1408 + 8629\n16213 + 15310\n(15275 + 23538 + 21405 * 1105)\n3630 + 20070\n15529 - 29199\n9142 - 11431\n23408 * 1114\n((25900 + 4274 * (24911 - 32542 * 10309 + 5346)) + (((11575 * 30450 - (29267 * 26970 + (3136 + 17669 / ((12060 - 31442 + 8633 + 32310) * (9411 + 818 * 20733 + 17653))))) / 11344 * 24312) * 14580 - 24497))\n13700 + 13632\n15957 - 18223\n(1557 + 346 + 32585 - 14061)\n13411 / 25013\n11721 / 14292\n7388 * 30130\n9089 - 6362\n(14970 * 10975 + 26047 * 30934)\n25741 * 31468\n((18291 + 5490 * 32468 + 1744) / 31399 + 14471)\n((20897 * 1777 * (32727 / 7055 + 18317 + 20042)) / 29694 * 31329)\n(24760 - 20648 * (5593 - 28482 + 10087 * 20703))\n28949 + 23916\n((10296 - 26205 * 7144 + 16039) * 26252 * 56)\n18288 - 9099\n2911 + 8446\n24181 + 23159\n24631 * 10930\n24351 - 28742\n9105 + 8743\n23031 * 4316\n30420 + 31574\n(8318 / 29120 * 672 + 23957)\n10406 * 28690\n2923 * 27254\n(8330 * 7744 - 22299 + 10942)\n22344 - 19987\n1496 + 2564\n((3046 + 11944 + 26989 + 21418) - 1385 + 11817)\n25723 + 27814\n21267 + 21342\n20936 * 2944\n26845 * 19725\n14069 - 7907\n2793 - 15917\n20638 + 15156\n(4239 - 3476 - 30309 + 11708)\n27291 * 3936\n31941 * 9708\n24351 * 21910\n(21785 + 22414 * 6183 - 13624)\n1832 * 13496\n15873 / 29782\n(14612 / 17926 * (((6878 + 3668 * (17770 - 4276 * 13093 - 4571)) + ((12047 - 21759 * 32610 - 12332) * 12183 - 13356)) * 28084 + 5010))\n32225 + 4402\n14236 * 20520\n14082 / 9476\n((7621 / 4222 - (((30925 + 2778 + ((((15941 * 6329 + 4321 - 15383) - 18553 * 297) + 15702 - 30333) - 3534 + 24773)) - ((30872 + 10789 + 18480 * 23129) * 30351 + 24229)) * 15168 / 29510)) + 761 - 4275)\n22701 + 20509\n25571 + 6543\n17427 - 20317\n12637 * 7607\n7436 * 2072\n25519 * 22448\n1161 * 6743\n(16441 * 18665 + 17442 / 29564)\n29208 + 2244\n(9969 - 6308 * 15788 + 24477)\n22408 - 9239\n(31369 * 12152 * 27000 + 25185)\n(8364 * 15610 + 18016 - 19371)\n15626 * 19893\n(15977 - 9634 * 3280 * 2466)\n28038 - 15379\n15332 - 748\n(10227 * 17128 / 1323 + 8809)\n632 * 26935\n13650 * 10629\n29662 + 59\n11169 - 21997\n11684 - 31064\n((16241 - 1859 + ((8735 - 4189 / 25725 * 11254) + 16703 * 1303)) - 12447 + 770)\n(27706 - 14823 * 18219 - 8403)\n1096 - 20150\n(((31916 - 32280 + (17686 * 20864 + 2938 + 12659)) - 976 * 12429) - ((22495 + 11056 - 8113 / 32302) * (12947 + 18475 + 24002 + 1344)))\n(26381 + 14564 + 22649 + 25579)\n25173 * 18798\n23334 + 7119\n14936 + 7286\n7966 * 8457\n21356 / 18946\n31071 / 16787\n3682 * 5258\n27087 + 10536\n25013 * 18029\n(14269 - 18297 + 5923 * 21477)\n((22522 * 32446 * 25930 + 17113) + 20486 * 22451)\n(9412 - 16318 - 5352 + 12582)\n31129 - 15157\n5162 / 23603\n10690 + 15733\n(17829 - 7520 * 13437 + 13974)\n9488 * 17743\n6024 / 25571\n(5927 / 2178 * 11218 + 28906)\n16895 * 5536\n(30590 - 12817 - 29716 + 32049)\n29665 - 28910\n11435 * 16241\n24419 + 21630\n31759 * 14656\n4873 / 29234\n15572 + 18832\n(23833 * 9834 + 1113 / 31508)\n((3065 * 1718 + 200 - 12759) - 16871 * 24762)\n22097 - 1822\n2324 + 24512\n2533 * 8576\n1456 * 24595\n27050 + 10394\n14640 * 23498\n7792 + 30461\n((26032 - 15623 * 1997 + 30) * 29610 + 950)\n24951 - 17755\n(16058 * 414 + 6783 + 21677)\n9376 - 32673\n(25796 * 25848 * 4038 + 6599)\n(1952 + 20135 * 26124 * 7306)\n12291 - 26449\n4980 - 300\n(28482 * 26342 + 14699 + 12742)\n4036 * 10520\n27995 + 13651\n((26746 - 32370 - 7669 + 19521) + 7964 * 19189)\n(8512 * 28870 * 23008 - 24569)\n(18156 - 8767 + 12612 * 22434)\n((23888 * 5552 + (28132 * 2612 - 5289 + 8995)) * (10265 - 2635 + 26592 * 19887))\n14355 * 15627\n12900 + 24233\n20192 - 3431\n241 * 18936\n30668 * 13771\n4132 - 22926\n25074 * 8585\n13634 * 23647\n14419 / 19393\n4001 * 31779\n30721 + 11353\n(16792 + 21500 - 5865 * 127)\n((14093 * 22221 + ((558 * 8253 - (28562 + 25729 - 1224 + 19291)) * 19394 + 15316)) * 11344 - 6877)\n13593 - 16021\n15169 + 25189\n30858 * 29583\n(27827 * 23081 + 31247 / 2064)\n14448 + 27054\n30843 - 30116\n23627 / 838\n30862 + 7548\n31547 + 13818\n16169 + 19291\n24093 * 15872\n11188 - 32211\n18469 + 17051\n17781 - 14794\n1672 * 11462\n(18143 * 11116 - 8118 + 18762)\n21451 + 22476\n(10425 + 1195 - 4281 - 8751)\n25399 * 24857\n((17881 / 4465 - 1195 * 19233) * 21199 + 23580)\n3718 - 7690\n((29753 * 15564 / 28480 * 3254) * 14960 * 16808)\n((15986 / 17147 + 24132 * 32446) * 14299 - 28226)\n31846 * 26093\n32102 - 23859\n15904 * 30086\n2445 - 19230\n(15298 - 22323 + 22722 / 12455)\n(11016 - 13619 * (6172 / 12052 + 4456 - 27989))\n17054 + 11784\n3222 - 28979\n(27842 * 6936 * 17585 * 639)\n23668 * 17171\n(16119 * 26379 + 19926 * 26495)\n((15326 + 11741 - 20805 - 13260) * 20990 - 22745)\n12050 * 4356\n15056 / 21764\n21299 + 10263\n23843 - 17593\n27537 * 12718\n((9372 / 21711 / 2857 * 29068) * 8433 * 31642)\n15605 * 6078\n32391 + 26019\n(23115 * 11770 - 8176 - 20952)\n1743 * 16185\n20307 - 12413\n5946 * 26223\n25499 + 5652\n(1308 * 18017 * 12897 * 6873)\n10752 * 19570\n(5008 + 9 - 29921 * 16374)\n20750 * 28536\n(22335 * 5590 * 9619 + 24349)\n18414 / 30188\n22322 - 13818\n8154 + 7068\n27313 + 30691\n(1123 * 3368 * (30001 - 16644 * (12306 - 14753 - 17914 - 8230)))\n(2437 * 19709 * 24392 * 13519)\n800 - 19137\n4171 - 20123\n(22280 - 30914 + 28304 - 1044)\n11414 - 16576\n(16250 * 10876 - 30832 + 6904)\n8606 + 21935\n3696 + 26632\n2375 + 22584\n2579 + 11504\n26385 * 15479\n((387 - 1101 + 17596 * 29244) - 19240 - 23802)\n7204 + 30751\n10892 - 24718\n20805 * 13685\n31062 + 17893\n31746 - 29513\n13898 + 4176\n16861 - 10801\n6552 - 18788\n4543 / 21602\n20584 * 12612\n1038 + 790\n31751 / 31250\n24751 + 28369\n(22316 * 2648 * 19476 * 20247)\n30569 + 18381\n(426 * 28225 * 12933 * 1575)\n(15679 * 23610 - 30880 + 8522)\n32446 + 22299\n17288 - 9470\n7680 + 24816\n(25980 - 9879 / 21850 + 28250)\n30231 * 27135\n(13843 + 6561 * (9176 - 3216 - 15097 + 28206))\n17021 / 13186\n(646 - 14337 * 12151 - 14500)\n(29693 + 2945 - 16313 * 31784)\n6459 + 27702\n25894 + 24441\n4119 + 7229\n30024 - 32569\n17125 * 12070\n24066 / 6726\n30375 - 14429\n(((6610 - 31267 * 10666 + 31954) - 4335 * 10443) * 23478 * 3500)\n30327 + 9427\n14306 + 10444\n(27166 / 8995 + 11750 + 10221)\n20250 * 27204\n(28511 - 28992 - 1751 / 26887)\n(30906 + 8043 + 22547 * 24638)\n19527 / 685\n((32111 * 22259 - 3398 + 2494) * 27161 - 20169)\n28116 * 19578\n13652 * 17678\n(25746 + 17734 * 24929 + 20578)\n20967 + 18812\n(25604 + 22663 - 1166 * 8627)\n12211 * 29336\n9698 / 5620\n23567 + 30102\n(((9440 / 19874 - 11313 - 26560) + 22437 * 5489) + 4059 - 8166)\n(467 - 29276 + 13765 - 9774)\n(16133 + 15914 - ((14910 / 3875 * 6429 + 18758) * (9018 - 8668 * 2698 * 18288)))\n2283 + 19490\n30836 + 24698\n(10346 + 20354 - 16549 / 1327)\n4478 + 2401\n31821 / 21676\n13207 - 4090\n4048 * 31361\n15430 + 21345\n(26949 - 21948 * 3750 + 27628)\n21020 - 25859\n((9598 + 32368 + 29347 + 20374) * 17539 - 6694)\n21371 + 15288\n26920 + 11145\n18822 * 30119\n(28541 + 1102 - 16777 - 2463)\n28563 * 20483\n18165 - 28374\n13247 - 27928\n15170 + 30685\n30474 + 26294\n32095 + 12048\n21476 + 13010\n23180 * 7346\n23054 - 16102\n7820 + 24825\n18393 * 28104\n21189 * 12714\n(20868 * 23217 * 4753 - 6162)\n11210 + 9171\n(10653 * 17024 * 23825 * 32451)\n27164 + 20613\n22956 - 3511\n15263 * 18167\n1818 + 27899\n9591 / 5073\n21464 / 24477\n(11392 * 24347 + (32260 * 2479 - 23284 - 5865))\n13667 + 712\n((29321 - 8080 * (20784 + 8814 - 22133 - 24887)) - 19626 * 8737)\n19902 + 21564\n((5442 - 8223 + 1214 + 1033) * 20760 + 2815)\n(7993 - 5562 * 26301 - 27373)\n4580 - 18176\n21470 + 12098\n2302 * 19140\n(31779 + 11211 * 22916 + 27594)\n(23791 - 10546 / 10259 - 8598)\n((8411 + 20601 + 7247 + 13524) - (27838 * 27766 + (19431 * 20888 + 16770 - 42)))\n3007 - 5115\n24261 - 22191\n13246 - 13622\n28034 - 5410\n12421 - 12595\n11663 * 30799\n8490 + 31267\n16020 - 30712\n2587 - 22686\n9968 + 22218\n(13489 + 21455 - 30304 + 24625)\n((13161 * 11668 + (((31854 * 22611 * 17922 / 6338) - 25642 * 2959) - 26590 - 25377)) - 13071 - 2189)\n(30197 + 17200 - 6853 - 287)\n22920 * 24612\n27488 - 1959\n18932 * 29658\n6816 - 5442\n26717 * 14044\n27108 * 12860\n(9395 * 26863 / (((12175 - 2816 * 2052 * 16635) + 32019 / 7585) - 31866 - 21166))\n7392 * 13702\n12605 - 28488\n8382 + 21965\n10560 - 7074\n4622 - 4078\n21541 - 18584\n26322 * 3953\n19161 - 29206\n9889 * 26539\n22830 / 18243\n18393 * 3709\n22420 - 9446\n24301 * 17172\n18054 - 16384\n19558 - 24155\n(8649 * 9502 * (12883 / 25082 + (22016 * 14854 - (7618 + 8596 - 6868 / 32446))))\n11157 - 1312\n31922 * 9436\n21058 * 18414\n26121 * 14983\n28266 * 24847\n(3115 + 7524 + 10178 - 15029)\n25263 * 1493\n20838 + 383\n12993 * 19987\n28691 + 26301\n3528 + 6992\n(2326 - 8822 + 7504 + 11547)\n(12925 + 10240 * 26871 * 14790)\n22667 * 25051\n(3254 - 18274 + 24854 - 31215)\n(3201 / 23389 * 821 + 29085)\n29830 + 13156\n6828 + 28067\n(17129 - 2955 * (29950 + 31757 - 10341 * 32226))\n24066 - 20275\n23202 - 14724\n9891 * 1225\n17629 - 4913\n6009 + 16000\n(7639 / 30805 * 16930 - 28780)\n(7429 + 8177 - (7413 * 31700 + (4404 - 1335 * 9116 / 2917)))\n9997 - 8112\n((12271 + 12544 - 11005 * 18518) - 26373 - 12112)\n22101 - 15352\n20964 / 15858\n(14318 * 31755 + 17573 - 738)\n13002 + 31919\n(24658 - 12027 / (((24466 * 30750 + 4162 + 26353) + 29524 - 20574) * 29025 * 8759))\n10441 - 14880\n20931 * 2927\n10891 * 18464\n22922 - 13010\n(29439 + 1027 * 2963 * 128)\n26705 * 25286\n343 - 639\n20369 + 29500\n(24984 + 27506 - 29 - 2612)\n(2462 + 32175 * 9933 - 4264)\n24285 - 3325\n21631 - 25174\n20323 * 27887\n18258 * 20021\n30432 * 31013\n17180 - 16902\n29736 - 31158\n17577 - 6706\n25432 - 906\n24777 - 28732\n(11112 + 31154 * 29841 * 6681)\n25055 + 13203\n((31244 - 206 / 27258 - 11939) - 29634 + 26965)\n10112 * 25070\n20355 * 18894\n(19741 * 2635 + 27666 / 12060)\n15531 + 10097\n18879 - 23949\n30993 * 23035\n21605 + 20014\n(13230 - 21135 - 10039 / 8935)\n27436 - 25893\n655 - 4826\n31664 * 7568\n9190 + 188\n16359 * 29108\n10604 + 3980\n1321 * 10271\n30385 * 22935\n11921 - 18778\n15745 - 10366\n27115 + 18765\n((2095 - 27853 / (8091 * 10652 + 8271 + 5576)) * 27646 * 32264)\n(10594 + 9843 / 29870 - 27913)\n14783 * 6497\n(16700 * 10820 * 11538 * 6111)\n(18288 + 12044 - 4051 + 25311)\n(14380 + 22854 - 24113 / 11663)\n23878 - 9060\n5364 * 8228\n19499 + 15288\n(13244 + 23760 + (7432 * 17292 / 1283 + 18148))\n627 * 12273\n(22187 - 28819 + 18883 * 11618)\n10069 - 26605\n23998 + 29153\n30404 * 12057\n12363 + 24828\n(26055 - 21239 * 20678 + 26358)\n17684 - 26943\n20386 / 13946\n(7799 * 24907 - (27600 - 17925 + 20046 + 18357))\n412 - 29425\n26551 - 28693\n8215 - 24805\n134 + 13266\n(16639 - 173 - (9046 * 25655 - (4632 + 1596 / 27442 - 7100)))\n9896 * 31648\n17129 + 26945\n9272 * 12423\n9358 * 10571\n14001 - 20800\n(30484 * 1257 + 20778 - 21235)\n21716 + 8512\n(16308 + 10620 * (6991 * 31396 * 23908 + 27220))\n21069 + 780\n26783 / 1531\n(8878 * 9998 - 7523 + 14644)\n14938 + 13414\n2504 - 7174\n5938 + 6898\n(1921 + 24857 + 13081 / 8568)\n23806 - 6220\n11932 + 2944\n32705 + 32621\n20550 + 18280\n(19850 * 21895 - 4517 - 32258)\n25754 + 4433\n10527 + 17731\n7357 * 7785\n((12789 * 22128 + (17441 - 26387 + 15164 * 6840)) + 18552 - 6114)\n12004 + 3680\n17820 - 17759\n27957 * 12709\n30278 + 28047\n22430 + 27535\n10278 * 15120\n((20097 / 24534 - 1230 * 30145) * 3484 + 20651)\n11337 * 17808\n9553 - 6820\n20816 + 1114\n((14582 - 12183 * 1069 - 10024) * (13489 - 2970 - 11310 + 22034))\n12055 + 4738\n(14978 * 13008 * (22912 + 26414 - (30759 + 9829 - 26056 - 27675)))\n29482 - 26316\n19455 + 18119\n23493 + 27756\n23293 + 863\n(((16648 * 29405 - 15467 - 25782) * ((((22801 - 31887 * 25734 / 2276) + 31569 / 3905) - 27295 * 243) + 10778 * 14659)) - 10947 + 29436)\n19882 + 571\n8161 + 5047\n14831 * 16315\n31567 - 392\n11774 + 14711\n15975 * 2201\n17711 * 4178\n3127 - 24491\n485 + 24688\n30526 + 4881\n(16364 * 8123 * 8035 - 29535)\n17137 * 31035\n11407 - 12428\n16029 - 10179\n((23819 - 7302 + 15796 * 28985) + 16009 + 18403)\n24918 + 20465\n23792 + 24999\n6703 / 3916\n21941 + 29407\n(31828 * 5628 * 4609 + 11630)\n30202 + 12479\n(23612 + 15763 + 30780 * 27326)\n11769 * 23342\n24124 - 9658\n27976 / 11114\n28 - 25124\n19308 * 1699\n(23199 + 10545 * (22933 * 11662 * (11325 * 2135 + 29242 + 11337)))\n29657 - 30\n13345 * 5984\n12165 + 5883\n25460 + 159\n2745 - 3703\n(31586 - 20873 + (19202 + 23192 * 18961 - 13077))\n19151 * 20501\n27758 - 7372\n16434 * 30447\n25279 - 24445\n32112 - 24967\n(29232 - 12365 * 27071 + 28165)\n20205 + 27619\n24740 - 25665\n31785 + 31955\n11954 + 4476\n32645 * 18265\n13130 - 902\n27575 * 6687\n5704 - 17919\n5617 / 8283\n(13246 - 11014 * 17371 + 3582)\n11839 * 17352\n(8847 * 7914 - 28282 + 14161)\n21397 - 6613\n(22891 + 14140 + 7628 - 16616)\n14219 - 22489\n17981 + 2038\n23444 - 10234\n15576 - 13127\n10114 / 15651\n8545 * 61\n24674 + 19051\n((12813 - 6245 * (18115 / 25123 * 5892 - 18430)) * 19819 + 23032)\n3616 - 6281\n32766 + 20632\n(26763 / 9279 + 368 / 30602)\n24057 - 15188\n28890 + 23939\n16596 + 12279\n29569 / 19505\n13810 - 6861\n1546 * 2496\n20329 * 2245\n6369 * 29055\n13206 - 19749\n1047 + 24759\n5537 + 21872\n31622 - 29796\n15746 - 17848\n(7143 / 14281 - ((730 + 2806 + 17733 - 30937) - 25146 + 8272))\n7043 / 28350\n20535 + 14833\n27960 * 3383\n7083 - 21151\n9848 - 24828\n(25642 * 7602 * 3906 / 25699)\n(8613 - 21330 - 27782 * 12223)\n30990 * 27796\n10178 - 16870\n497 + 31472\n(((12902 - 31792 + 10973 * 8390) * 18830 + 27421) - 27796 + 15256)\n13998 * 27851\n22192 * 7718\n2391 - 3325\n30838 + 9207\n20206 * 29654\n(10946 * 32472 * 16678 + 7944)\n24905 + 27309\n30800 + 10997\n20311 - 25414\n(15761 * 23279 * 15653 + 24337)\n3071 / 1458\n21899 * 27454\n(29434 - 1449 - 3691 - 7960)\n15791 * 19869\n12119 * 31958\n(32139 * 6703 - 17194 - 23415)\n(19514 - 3066 - (7470 + 31971 - 29964 / 14755))\n(30241 + 23062 + 17249 - 11630)\n(22610 * 26274 - 11544 * 26719)\n16311 * 5981\n8871 + 21612\n28763 / 14935\n27562 * 9890\n24512 * 5867\n14992 - 18535\n(19669 * 30690 - (14149 - 12048 - (13410 + 14315 + 18551 * 10256)))\n29184 * 3273\n16343 * 6941\n(20093 / 29318 + 23883 + 17039)\n(((17218 - 16446 + ((1477 - 17229 / (19107 + 12638 * 16256 + 14774)) - 15670 - 30864)) * 25165 + 29899) - 32306 * 9474)\n(6896 + 10118 + 1506 * 31291)\n8641 + 23376\n2649 + 21603\n4963 * 19826\n2116 - 17823\n31017 * 28956\n(11639 - 13348 + 15984 + 21345)\n25342 * 18503\n2637 * 4655\n24959 - 2405\n2497 + 6488\n(20227 + 5525 * 10705 - 6795)\n((6734 * 18218 + 31001 * 28528) * 22309 - 11398)\n15670 * 9569\n28566 - 7015\n5895 * 6161\n13602 - 13870\n7850 + 2631\n9476 * 19912\n(24625 + 8352 + 23841 + 30905)\n31228 * 14087\n9498 / 30296\n17886 * 29886\n(((4165 + 31900 - 816 - 13399) * 8610 + 31788) + 16522 + 10807)\n1301 / 13507\n(20720 * 27583 / 31463 / 15157)\n2829 - 4811\n31045 / 19407\n7956 * 5368\n25360 * 6090\n(3236 + 7637 * ((25977 + 1422 + 30596 + 5320) + 673 - 5667))\n(17784 - 27458 * 7190 * 13128)\n15807 + 6886\n((19866 / 22263 + 28829 - 14040) + (((33 - 3785 * 27263 - 21646) + 7270 * 21570) + 19206 - 2032))\n15346 + 12310\n2849 + 18276\n17595 * 14435\n10900 + 2991\n(20842 + 9815 + 111 * 32389)\n6946 * 4299\n(((32453 * 12072 + 21997 * 29324) - (32663 + 5708 / 4599 + 31322)) + (4806 + 24969 + (30945 / 7961 / 21746 + 19012)))\n(31005 - 5151 - ((((8863 - 23838 * 25527 / 8376) - 1944 - 12705) + 1939 + 10476) - 29435 + 10225))\n31322 - 25233\n29036 + 20226\n5087 * 3318\n5012 + 32340\n((4895 + 2402 * 11403 * 26362) * 11488 + 20530)\n15103 - 9325\n5975 + 30372\n13221 + 10837\n(13475 + 15534 * 26361 + 8115)\n21388 - 19375\n21144 + 29884\n30847 * 18782\n17557 + 1888\n25016 + 925\n(24863 - 19580 + 7562 / 27141)\n14753 + 8273\n2082 - 11574\n12747 - 28238\n26124 + 16783\n(26510 - 19938 * 24945 + 10085)\n8540 + 3726\n16491 * 32700\n5330 - 6774\n(4585 - 23149 - 8459 / 22359)\n(9336 - 27650 + 22580 - 19240)\n4295 / 28710\n25041 + 14059\n23767 + 699\n14737 * 15553\n13254 / 29491\n17461 + 27398\n20423 + 5058\n(5228 * 1017 * (32659 + 15259 - 16428 - 22732))\n(23464 - 2012 + (3022 + 20435 * 14186 * 14936))\n(12155 - 481 + 7318 * 20345)\n(3303 * 635 - 9072 + 32600)\n19622 * 15192\n3698 * 32751\n29407 + 28559\n(((16909 / 22789 + 5270 * 17583) - (29235 - 8058 - 9512 - 3077)) - 25320 - 23484)\n8742 - 1380\n(32715 * 1612 - 27861 + 22474)\n8120 - 32328\n32222 + 14081\n15250 - 1564\n(12419 * 10123 - 5598 + 2412)\n(30654 + 6813 - 6566 + 13965)\n31968 - 28080\n20763 * 25574\n21933 / 29580\n18293 / 24488\n(4466 - 30987 - 32270 * 13750)\n31000 + 4314\n8992 * 14841\n28057 - 5795\n28846 - 20000\n29379 * 20302\n4296 + 22213\n(11194 + 8171 * 4092 / 11291)\n14072 + 27151\n28576 / 17938\n((3293 * 21985 - 15922 + 29938) * 29184 - 8193)\n(24551 - 30141 * 29731 / 31437)\n(28257 - 21492 + (17091 + 6316 + ((5008 + 4332 + 18530 - 12055) - 25121 - 27267)))\n(29077 - 10069 - 25152 - 25269)\n30814 - 27977\n(((31080 / 4982 + (13238 / 27700 * 13683 - 31545)) * 26984 - 23861) * 16234 * 24468)\n(30972 - 13896 - 19920 - 15496)\n1687 * 13826\n15961 + 21787\n25003 - 1743\n(14440 * 21204 - 22529 - 7581)\n14220 - 16646\n24446 + 11752\n21908 + 554\n10709 * 9356\n9441 - 7832\n19922 * 8351\n2970 - 19080\n(7624 - 11362 * 30972 + 1081)\n9621 * 27431\n(13664 * 10684 * 31766 * 26672)\n17487 - 17843\n27522 - 31518\n16725 + 24283\n32130 + 22224\n32418 + 8732\n(22717 + 19051 - (8262 + 13313 * 21864 + 29344))\n27832 / 4825\n17877 - 15534\n9608 - 15731\n(15470 - 23950 * 23620 - 27926)\n28040 + 20443\n15401 / 10406\n7116 - 5380\n20843 - 12667\n17006 * 30135\n12020 * 13349\n(11341 * 22398 * 31427 - 11384)\n28463 * 9869\n12139 + 6696\n6823 * 8816\n22856 - 2694\n(3312 * 28423 * 9632 + 5248)\n11720 * 19660\n6047 * 30189\n20581 * 20857\n(11491 - 9670 * 24011 * 5923)\n2927 - 3901\n5177 * 24260\n(6103 + 19213 - 16462 + 28431)\n26677 + 19840\n20825 - 25583\n(((20579 + 21000 - 3110 - 13610) * 23151 + 15265) * 8699 * 1932)\n(12610 * 3521 / 32117 + 28655)\n2867 * 30223\n4352 + 28457\n2192 * 14141\n4455 - 7277\n18446 * 2494\n31077 - 6299\n2470 + 1467\n24244 + 7091\n(17954 + 15780 - 25867 - 12857)\n(18583 - 14507 + 7568 * 22248)\n16991 - 27897\n26276 * 10326\n25017 + 31414\n(15888 + 29784 - 13362 / 789)\n24507 - 20061\n11854 / 5111\n(24719 + 19606 * 6411 - 21719)\n2206 + 13486\n13360 - 16127\n21667 + 10165\n14623 + 30166\n(26748 * 28504 / 297 - 17224)\n29801 - 10300\n5162 * 8266\n17541 / 27779\n(31 - 26415 - 2222 + 16208)\n(22146 * 5782 + (12139 * 18548 - (17725 * 9500 - 12202 * 19140)))\n30193 + 22046\n24416 - 21150\n14096 + 2402\n(((10141 - 32421 * 9292 + 26139) * 24108 - 4564) * 11605 - 20892)\n668 + 22996\n5694 + 17583\n13335 * 29486\n26681 - 13504\n25553 + 23687\n13338 * 15564\n((21781 - 30953 - 8450 + 24455) + 26313 - 501)\n7817 - 32735\n7387 + 9877\n(((((18143 * 12185 + (19671 * 6981 + 1024 + 20677)) - (17299 + 14705 * 32439 - 499)) * 22101 + 27833) - 24360 * 7196) * (25059 - 6994 - 21562 * 6695))\n16586 - 5203\n15882 - 10341\n24829 - 27919\n(20473 + 30180 + 20246 * 2186)\n16991 + 27897\n26650 + 5192\n9558 - 31320\n21826 - 18799\n16959 - 26078\n15087 - 28467\n(10479 / 17824 + 21421 * 26339)\n1295 + 9773\n((1494 + 20226 * 19653 * 3989) * 5526 * 23002)\n9513 * 6023\n5798 + 29998\n7918 * 30979\n24242 / 25560\n16536 - 16952\n3661 - 5499\n(29107 + 3632 * 21804 - 21347)\n((6884 * 9818 * (24461 * 6826 / 31989 - 8081)) + 29273 * 1047)\n((17811 + 27750 + 27461 - 8637) * (18869 + 27106 * (16758 / 5869 - 23910 * 9391)))\n18179 - 29808\n18970 * 1629\n31110 - 86\n26058 - 17583\n3113 + 20951\n(16734 + 6380 + 27196 - 30993)\n29473 * 24360\n474 + 1544\n28603 - 16934\n(14792 + 5539 - 32096 + 10766)\n(9084 - 12750 - 9988 + 23494)\n(((2587 * 10513 - 8793 - 2110) + 22397 + 16645) + (10591 + 26020 / 8055 - 11796))\n15454 + 28209\n7208 - 10427\n(16507 * 7131 * (19153 + 31468 - 21396 - 17962))\n4413 * 31252\n(15315 * 31327 * 29648 - 7312)\n19294 - 30469\n25556 - 30525\n31163 + 8050\n7251 * 19787\n1645 + 9138\n3256 * 14677\n14486 * 1876\n866 / 565\n10384 + 4294\n15889 * 18329\n27463 + 22993\n(16644 * 16096 / (12451 - 31198 + 29258 / 15006))\n25287 + 28193\n5265 * 30524\n15450 - 998\n8777 / 23242\n((((3364 + 30282 - 13175 + 6717) + 7528 * 14950) - (8077 - 15504 * 26492 - 5077)) - 17031 * 24999)\n24783 + 16530\n15738 - 17407\n7317 - 20453\n(24706 * 11826 + 13081 * 14096)\n8325 + 19664\n6343 + 30827\n11518 + 18287\n(11762 - 22682 + 3837 * 2043)\n4820 + 16323\n(3378 * 13399 * 12254 + 5119)\n(12510 + 3308 + (26124 + 11318 * (24869 / 30042 - 742 + 21266)))\n22283 * 16042\n((((20757 - 23126 - 30884 * 24618) + 23453 - 11204) - 18184 + 21520) + 13355 * 30096)\n3012 - 25678\n27003 - 10126\n(30590 - 8586 - 31545 - 5277)\n8133 + 23193\n5686 - 22162\n15237 * 29477\n15897 - 25237\n30204 + 5191\n(11382 - 20811 * (2518 * 31833 - 22271 + 16477))\n4756 - 8019\n11331 + 16917\n7934 + 8331\n(12754 - 25408 + 15679 * 12090)\n8032 * 17180\n7435 * 8648\n(32061 - 30089 + 15008 - 17938)\n8223 * 5565\n((19177 + 17243 - 17698 + 12874) + 16311 + 13015)\n261 - 3427\n22277 * 20638\n31867 * 28409\n((23675 * 2644 - 26209 + 9814) - 29661 / 27628)\n(887 + 10667 - 27913 + 24079)\n(18935 * 14187 * (3100 * 9866 * (19324 * 11742 * ((11671 + 1913 + 27775 * 400) * 9917 * 26918))))\n(30307 + 11925 - 30453 * 21102)\n6586 + 14208\n21538 + 24650\n14823 - 22694\n4852 - 27180\n18995 * 30860\n13325 + 14576\n16273 - 27949\n24410 * 2878\n12481 * 19417\n18704 / 11838\n30338 + 13359\n(4031 * 19197 - 10350 / 27949)\n19727 * 29197\n5418 / 3742\n4984 + 21642\n18391 / 7861\n8540 - 17374\n23914 * 7400\n9787 * 18889\n(27620 - 7487 + 27312 * 2620)\n27981 / 5963\n19349 * 3319\n23369 - 24550\n25018 / 8542\n18913 * 32010\n13232 + 30672\n((((2 + 27313 * 17386 - 23306) + 1701 - 2361) * 21236 - 11824) / 17459 * 20799)\n32715 * 21755\n((25943 + 3764 + 23430 * 279) + 17666 * 28758)\n(16511 * 14559 + 24439 + 8029)\n31462 * 12930\n4061 - 24766\n17601 * 20718\n22956 + 8996\n(31658 * 14604 - 13633 * 22354)\n(17596 * 3245 + 21392 + 14598)\n3318 - 5728\n30344 * 28798\n18244 + 19171\n24420 - 31751\n2300 + 30289\n(31954 - 21276 * ((((26910 / 1548 * 18528 + 11235) * (22969 - 5138 * 25361 - 3221)) * 29575 - 29479) - 19317 * 25637))\n12011 - 19907\n16709 * 27787\n847 - 12610\n(3450 + 19251 - 16515 - 3938)\n28864 * 5385\n12113 + 18573\n2151 * 25425\n8678 + 16121\n17355 + 2860\n10843 + 3764\n4652 - 26887\n(17666 * 17142 * 8401 * 18241)\n20589 / 4369\n(5033 / 28097 * 23564 * 24681)\n9002 + 27519\n23461 - 20709\n10106 - 14229\n((24856 + 16753 - 16142 - 16427) / 28828 - 8518)\n27124 + 19539\n13370 - 11678\n10316 - 9663\n13735 - 21806\n31453 - 6852\n18035 * 24168\n28978 + 20182\n1372 + 3179\n(20007 * 20801 + (23787 * 16046 + ((((3655 * 30162 - ((4053 + 29315 * 22164 * 11025) + (4314 - 5643 + ((20838 * 31202 - 11742 / 21787) - 32560 - 8756)))) + 26939 - 131) * 8728 * 32462) - 19178 + 20356)))\n4168 / 7716\n20028 * 19727\n11528 / 24609\n11562 + 30911\n11765 + 31970\n14908 * 9663\n3064 + 32124\n15012 + 10107\n28202 / 2453\n29112 - 20969\n(5040 + 7503 - 21195 + 11598)\n7590 + 31608\n7831 - 18427\n23068 * 12640\n2903 - 22787\n19272 + 538\n(12451 + 27687 * 16407 - 26857)\n29124 - 26371\n18415 + 25346\n19062 + 29186\n9146 * 5007\n16621 + 4504\n23223 + 6761\n((27705 * 7055 + 19066 * 31365) + 408 * 21651)\n(3109 - 31010 + 17838 * 1976)\n15445 - 31174\n13962 * 29543\n(9122 - 21689 + 8335 + 26424)\n9513 + 7558\n13065 / 19907\n(13204 - 11317 * 8131 * 6900)\n11705 - 2970\n(1400 / 19776 - 4655 + 16960)\n(27566 - 11567 / 24211 - 22857)\n17978 - 5111\n14648 + 26138\n11955 - 22388\n24927 + 3894\n(4278 - 6154 / 13451 + 26086)\n(26764 + 23336 / 2488 + 5300)\n18010 + 3175\n(21223 / 29154 + 14955 + 30817)\n3492 - 13294\n17656 + 229\n((3866 - 30502 - 49 + 32598) * (20966 - 5807 - (4527 - 11799 * 31916 * 31325)))\n(17592 - 31390 * (5301 * 28972 + 10624 * 30425))\n20785 + 27059\n(2954 - 31418 / 9413 - 20608)\n(15133 * 15528 * 9252 - 21385)\n(21337 + 16240 * 3949 - 12089)\n20350 + 22561\n18557 - 13257\n13493 / 18932\n30316 + 11885\n16396 + 9480\n854 * 17355\n19383 * 18343\n15723 - 30494\n20854 * 30592\n19347 - 6786\n(9512 - 31255 * 27181 * 17066)\n(8847 * 24370 - 31574 - 16621)\n6271 * 27784\n(27613 * 6473 - 9193 - 12877)\n27000 * 30172\n13702 + 4035\n13723 * 7586\n25670 - 1275\n20230 + 10297\n27994 + 27102\n15515 + 13815\n28973 * 11651\n13869 + 16415\n30220 - 30931\n(25457 + 15488 * 19200 * 21356)\n(8096 - 5013 + (10915 + 7854 / 11327 + 10701))\n20332 + 13753\n31607 - 16289\n23335 + 10570\n(7005 - 26279 * (((((9406 / 32419 + 30270 - 31158) * (((4440 / 9841 * 4197 + 949) - 14228 - 4904) + 10599 * 8590)) - 18970 - 14950) + (13713 * 6921 - 11365 * 23991)) * 4773 * 20538))\n17840 * 15575\n6988 + 26899\n29994 * 28184\n2042 * 22592\n21517 + 10273\n10572 - 28544\n14531 - 30803\n((4214 / 30951 * 5457 * 15215) + 11746 + 12927)\n5108 + 21696\n(16423 + 27590 * ((15248 - 19079 * 646 + 8058) * 14181 - 26196))\n6514 + 23366\n6244 * 14336\n(15423 * 28773 * 27709 - 3243)\n11097 * 2617\n8895 / 27204\n22835 - 3438\n(20918 - 24787 - 31677 + 807)\n22011 - 28747\n17479 + 26957\n(30294 + 14857 + 30016 + 15111)\n(3932 * 9274 + 1258 - 23684)\n((26828 * 19658 + 24558 * 11225) * 25253 + 20039)\n8444 + 1753\n18904 + 25447\n(22725 + 6887 - (5121 - 15284 + 6354 + 9215))\n489 + 21595\n11164 + 21723\n12906 - 20659\n30001 - 3641\n5979 + 4488\n(4585 / 19196 + 425 * 29959)\n15293 - 17860\n(5239 * 29256 - 32209 * 29179)\n16970 * 31153\n4746 + 30307\n(29079 + 11793 * 11808 - 10795)\n21174 + 4909\n20681 - 4322\n326 + 10449\n30886 - 20604\n26201 * 2443\n(16797 * 21469 - ((29903 - 21468 * 31927 * 27587) - (29537 - 23069 + 2903 + 3998)))\n5448 - 24534\n1853 + 15947\n6637 / 6008\n30931 + 31116\n((8409 + 12905 / 12571 + 17629) - ((21269 + 26664 * 8082 - 13472) * 2675 - 8737))\n8334 - 16555\n3693 / 24904\n3842 - 1322\n20683 - 8007\n22849 + 32747\n31783 + 32224\n(15620 / 16939 - 22958 - 28887)\n12268 - 16660\n27159 * 16409\n1865 * 32128\n18405 + 8900\n18069 + 30413\n27538 + 15637\n22146 * 10756\n28822 * 27835\n9482 * 11293\n7305 * 21561\n18461 - 19689\n(1914 + 23418 + ((28770 * 23757 / 26597 * 20343) - 23417 + 922))\n(31904 * 22322 * 27063 - 32638)\n12187 + 31848\n25428 * 16898\n((4679 - 4333 * (27534 - 13234 - 21217 - 15406)) / (32177 + 9049 - (20119 * 30719 - (12203 + 30864 / 8473 * 29684))))\n(17924 + 24942 + 10781 + 1898)\n3528 * 14072\n(3468 * 11764 + 10380 * 12569)\n20439 + 18014\n18620 - 21270\n(20195 * 28438 - 19650 * 13121)\n(11219 + 16761 + 28423 / 24700)\n26674 - 27721\n5521 - 29636\n((8802 + 11066 * 31294 * 1123) * 9957 + 6741)\n15392 - 18741\n13633 - 13978\n(19493 + 16539 + 13674 * 31349)\n13513 - 29488\n15699 - 10636\n11952 + 23651\n1830 - 23954\n15837 * 5650\n28506 + 26750\n(((27811 * 1120 * 7222 + 3539) * 2298 - 24197) + 10547 * 445)\n951 - 11990\n10821 + 18470\n18458 * 9585\n((17445 - 13251 + 27029 * 1708) - 22878 * 22546)\n24720 + 12274\n9615 * 22914\n7115 - 19200\n6538 - 10113\n12762 + 14774\n1178 + 5120\n17428 * 9545\n29183 - 18461\n21124 + 3673\n(17974 * 14274 * 793 / 3562)\n13965 - 18491\n(19381 * 3579 + 17218 * 27150)\n(1539 + 28942 + (3594 * 11190 * ((26777 - 26545 + 10722 - 26069) - ((10715 - 3670 + 31574 - 4529) / 31379 + 23108))))\n30241 - 30840\n18948 * 11390\n((17345 - 12489 - 27824 * 12223) / 20680 - 12616)\n18101 + 24861\n29583 + 19200\n16505 / 31098\n17190 * 5255\n21862 - 24130\n13554 - 6707\n23736 - 11554\n6811 - 13363\n(30628 + 23545 * 7698 + 9217)\n32661 + 29523\n25400 / 3121\n14277 / 16619\n6656 - 9408\n30345 * 21926\n((26187 - 16736 - 27512 + 27365) * 23301 * 21252)\n11174 - 3695\n22278 - 6826\n((27567 + 27514 - (23847 + 5053 * 15917 * 14602)) + 29435 / 7296)\n24480 + 6626\n1958 + 10600\n3676 - 15931\n15324 * 15727\n13892 + 14934\n(4244 + 21187 * (16632 - 19184 + ((15222 * 24803 * 7760 + 29299) / 26909 - 19464)))\n4203 - 19009\n(30069 * 12759 - 19344 * 630)\n23751 + 21863\n4861 + 2698\n22936 + 30928\n25584 - 17844\n8381 + 866\n5552 - 15332\n23704 - 12186\n4356 * 11216\n21366 * 13225\n2040 - 27857\n5806 + 3218\n((697 * 15496 + 14040 - 15205) + 20969 - 4361)\n11015 * 21220\n16810 - 20782\n10028 * 28332\n20551 - 13645\n565 * 24735\n(26393 * 11062 - (8416 + 2154 + 13474 + 18115))\n30195 * 30539\n8443 * 7336\n14218 + 3668\n(26294 * 29192 + 7696 * 4072)\n11396 + 31985\n10638 - 3338\n14597 - 22477\n1540 + 6320\n((20311 - 26249 - 1364 / 21910) + 17606 * 11093)\n(24534 + 22198 - 10844 - 20591)\n(12626 * 32696 + 29947 * 6463)\n(8526 + 28447 + 20677 - 15987)\n(8722 * 14210 - 25917 - 4755)\n21976 * 7918\n19677 - 23013\n29539 * 14235\n24365 + 1938\n16062 * 23522\n(27124 * 13609 + 7266 - 18678)\n3128 * 23992\n9706 / 25085\n17619 + 14560\n188 + 5129\n14225 + 23509\n(3483 + 770 + 17391 * 8097)\n14060 - 24862\n(19102 - 19201 + (23703 + 26395 * 26863 + 31377))\n26901 / 22818\n1079 + 3175\n25806 + 13449\n2364 * 9567\n(2187 + 19064 / ((1224 - 7334 - 5347 * 27501) / (2601 + 24609 - 11877 - 28949)))\n4878 + 27098\n12152 - 7351\n12255 + 10419\n(17154 * 10854 + 11129 * 8425)\n(((1213 + 7026 / 212 + 15861) * 24965 - 11636) * 13370 + 16464)\n18990 / 19913\n30389 - 17565\n15767 - 13401\n3626 + 2150\n18735 - 9372\n(23172 + 23112 - (30813 - 12132 - 31814 * 7935))\n31822 * 14055\n(12595 - 6594 - 3892 - 22237)\n6955 * 12683\n((5392 + 15979 + 1048 - 23667) + 27074 - 4996)\n(13700 + 18211 * 17262 - 28801)\n10998 * 21101\n(5977 * 12515 + 16985 - 31054)\n14405 - 11267\n5596 + 13291\n31268 + 12523\n12138 + 15742\n(10645 + 16489 * 14975 + 6009)\n24747 * 1585\n((((7806 * 28358 - 22416 + 27630) + 20704 - 13092) - 2568 - 3448) / 30155 + 13229)\n14810 + 29920\n(26104 * 3846 * 19132 * 22603)\n(1579 + 11559 + 20822 * 12675)\n13534 + 3054\n(9993 + 18827 + (10089 * 31869 + (13140 * 7220 + 24863 + 24000)))\n29065 - 13211\n1297 + 1702\n17942 * 13150\n21869 - 25810\n18477 + 5790\n7542 + 20391\n7717 + 4615\n20724 - 4851\n3323 * 12803\n(18890 * 22274 - 6629 * 24129)\n3540 * 1215\n31356 - 4257\n28140 + 32597\n30545 - 28740\n8259 - 13649\n19157 * 5824\n(1270 + 15378 * 1866 + 15035)\n8955 - 9901\n20237 + 10160\n(30062 + 11647 + 23097 - 7419)\n((16459 + 10418 * 2093 + 21072) - 10586 / 18695)\n19043 + 13181\n(4186 + 15417 + 9514 - 21274)\n(2748 - 4220 + 19265 / 5722)\n23957 - 31567\n6300 - 7928\n(7705 * 20567 + 20703 * 21504)\n10294 + 20652\n3978 * 14454\n7736 * 5919\n32099 + 14028\n16008 + 17990\n14817 + 19791\n18467 - 27998\n366 / 4485\n7989 / 30308\n152 - 3303\n(832 - 16494 + 13052 + 13996)\n25243 / 9467\n32226 + 10183\n(24392 + 20637 * 5662 + 5756)\n17759 / 8364\n13136 - 19846\n5048 * 2251\n31776 + 726\n24312 + 16882\n6892 + 19991\n32658 + 26502\n((15036 + 9875 * 24508 * 5468) - ((29192 * 8054 / (28003 * 27761 / 10247 / 26166)) + 14314 * 186))\n29836 + 10129\n11527 - 31135\n28670 * 7452\n1718 + 8925\n32755 + 4528\n((16174 * 27593 * 5080 + 7229) + 14263 + 7580)\n27192 * 481\n30093 / 28655\n(24739 + 556 + 29867 * 29530)\n(21564 * 7004 - 23787 / 14535)\n(27850 * 25037 / 17540 - 742)\n10635 * 19113\n26662 + 490\n((27650 + 8311 + 4017 * 15330) * 15522 - 20729)\n25219 * 10754\n19006 - 13439\n(22173 - 15842 * (13211 * 7124 - 7463 / 2142))\n31377 + 29741\n17963 - 29216\n8688 - 4624\n2552 - 22410\n(3623 - 20445 / (9587 * 27793 + 9854 + 3133))\n(539 * 8154 * 22637 + 9139)\n3477 - 9172\n29180 * 7686\n1232 * 23449\n32390 + 20441\n17914 * 21047\n9992 * 29694\n32736 * 17919\n19918 * 18878\n(22735 * 12788 - 28367 + 1896)\n(6626 + 31100 + (((6006 - 2548 * 5917 + 19831) + (31980 / 25191 - 11062 + 9576)) * 26628 / 28028))\n17566 + 21778\n((23691 + 28120 * 13266 - 26666) * 15755 * 11281)\n14597 * 90\n22004 / 18673\n2943 * 2415\n(19847 - 11746 - 1555 - 6470)\n(12520 * 16383 - 5994 / 1492)\n28275 - 29412\n2175 + 551\n(19021 - 29832 - 12157 * 11475)\n11395 + 17635\n16887 * 6371\n7057 * 30158\n(25948 - 14876 + 5519 - 4829)\n7781 - 293\n(28230 * 15096 + ((17504 + 12400 * 32200 + 27252) - 4552 - 1243))\n((22971 - 5710 + (8848 + 4154 / 1627 * 22079)) - ((3395 - 28567 + 12509 * 6893) - 12888 + 4887))\n(15896 - 19915 - 21720 - 13908)\n30419 - 15467\n(159 - 11853 + 28116 + 6921)\n7974 + 2346\n(20926 - 1964 - 10065 * 3220)\n9440 * 6282\n28478 * 20431\n((13002 - 4564 * 8293 - 29970) - 6409 + 17851)\n29667 + 31635\n6777 - 18707\n1697 * 16061\n11776 + 28294\n7651 * 17616\n24099 + 27080\n8337 + 19783\n28583 + 22392\n21716 - 18243\n2484 * 31501\n(17087 * 9674 * 19844 - 1330)\n(12997 - 6935 - 20069 + 22151)\n((17806 + 11899 + (((((26667 - 6823 + 13026 * 11963) + 11629 / 16456) + 140 - 28068) * (4609 - 2106 / 15311 - 23908)) - (22419 + 27358 * 20393 * 10371))) - 32721 - 18217)\n9191 * 24385\n18186 * 9559\n(21836 * 12898 + (9835 / 26878 * 27318 - 10133))\n(24304 * 23783 * 19146 * 20314)\n32058 + 5267\n23761 / 4876\n27792 + 14962\n31984 + 1844\n((26410 - 14674 + (2153 * 23833 + 14615 - 17280)) * 16623 + 16500)\n25042 - 26026\n(6805 - 29647 - 5350 - 6831)\n(13015 / 24260 * (30979 + 9658 - 31769 * 26303))\n30032 * 12288\n6222 * 30854\n(26314 - 5994 - 19102 * 9966)\n11069 + 5637\n4402 * 1599\n27620 + 12277\n18649 - 15879\n((26045 - 5915 * 6931 * 8887) - 5398 + 21)\n29597 * 30053\n27100 * 13976\n27382 * 18856\n23250 * 17618\n32601 / 26667\n5748 * 23017\n21574 + 7143\n1501 * 26556\n5952 * 23960\n11338 - 5723\n28080 + 25531\n31374 + 28675\n1746 * 21576\n9191 * 255\n8683 + 15349\n2049 - 25693\n20688 * 32699\n7394 * 4126\n(17115 + 9611 * (((18419 * 29595 + 29002 - 18806) + 5337 / 26943) - (1324 - 1451 + 7837 * 24388)))\n19424 + 17508\n(28325 + 8625 * 32424 - 23254)\n21573 - 31990\n3403 + 18489\n10488 * 29446\n19526 + 3894\n26394 - 7526\n13846 - 29095\n664 * 2853\n756 * 522\n(8124 * 8994 - 8761 * 3906)\n9172 - 27178\n30727 - 12071\n5998 * 15774\n8237 - 23490\n12103 - 5473\n28214 + 23694\n((((22353 * 22062 + (11954 + 13872 - 5130 - 9615)) - 4190 - 13412) - 28420 / 30832) - 1482 / 949)\n24910 + 1559\n3406 - 30207\n13034 + 5185\n(25758 / 846 - 3031 - 30082)\n19279 + 29885\n10715 * 23437\n(20733 - 10442 - 3270 + 20240)\n18641 - 27357\n26446 * 14424\n(16385 * 31612 - (((4322 - 11801 / 18714 - 3123) - 27981 * 18207) - 19750 - 6808))\n7162 + 23195\n1553 + 17882\n3461 - 4834\n10837 - 8736\n9848 - 19913\n((29314 - 549 - 6505 - 12113) - ((9807 - 9494 + (1041 - 26508 - 10246 + 9472)) / (19391 + 25124 * 16664 - 20576)))\n(3423 * 28110 * 6194 + 23004)\n(5404 * 16068 - 6778 / 12352)\n10536 * 7526\n30136 + 2749\n3776 + 23482\n9621 - 21353\n17486 * 22926\n(((4237 + 1454 * 14124 + 3093) * 4644 + 3298) * ((29950 * 6135 * 11461 * 31667) * 6755 * 5593))\n6649 + 9027\n(3332 * 18233 + 1069 + 22181)\n31901 + 14158\n15151 * 16505\n11321 * 15970\n((24612 * 8005 * (19355 - 8001 + ((12389 * 18269 * 22658 * 29905) + 23880 * 24266))) - 7518 - 3098)\n10435 + 29885\n8834 * 16895\n2239 / 4273\n(2627 + 32379 - 4147 + 8036)\n(3315 * 3180 - 8016 - 5301)\n26105 + 27243\n31337 - 20817\n(20723 * 27883 - ((4765 + 16204 * 7895 - 15783) * 16306 + 21458))\n19434 - 12622\n19485 - 13772\n(12027 * 11788 * 5557 * 16031)\n3722 * 10830\n18965 + 23572\n22337 - 27002\n3043 * 26027\n(8076 * 5363 - 16013 - 26311)\n10890 + 21359\n18096 * 13502\n30182 / 17357\n10796 * 28420\n29180 + 11702\n26983 - 29535\n1214 * 12471\n15787 - 22028\n24021 / 22246\n20037 - 9595\n(6372 + 3077 * 4119 + 3700)\n23438 - 13340\n26055 / 30391\n13020 + 13091\n18464 - 19247\n9814 + 25551\n5538 * 27953\n(17715 + 15142 * 32341 * 5838)\n(16261 - 21129 + ((15763 + 11435 + 31234 + 20637) - (22828 + 14824 - 23236 - 5673)))\n18400 + 26847\n30045 * 17625\n10610 + 6840\n19581 - 23540\n11410 - 11004\n((((2416 + 18249 - 2378 - 21940) / ((22962 * 3864 * 28220 * 31152) + 17222 - 20511)) + 1191 - 761) + (791 * 2371 + 5178 + 13021))\n12329 - 15495\n((20117 + 25695 * (23006 * 3143 + 6032 * 30240)) + 8929 - 25812)\n20801 + 5811\n1874 + 30577\n(31421 * 22235 * 10461 * 14769)\n31043 - 9704\n17991 * 19971\n1249 * 7942\n19936 - 6707\n13738 * 30839\n26514 * 2390\n((17165 - 16986 / 22435 - 121) / 32593 + 4951)\n9029 - 12733\n14683 + 16057\n32608 * 30701\n((8805 * 13344 - 9123 + 15908) - 13596 * 22702)\n8079 * 5496\n23144 + 29727\n24846 / 19466\n23413 * 14146\n19992 / 15332\n3498 + 4643\n(((31243 - 7906 * (2483 * 22079 * (11461 * 28779 - 29343 * 10958))) - 3041 * 25053) / 25428 - 9030)\n27182 * 27225\n(8133 + 10434 - 21321 * 10235)\n27839 - 18046\n23381 + 17395\n21553 - 1785\n28848 - 24400\n3250 * 28997\n16006 + 2460\n9940 + 22726\n16679 + 9910\n15393 * 21269\n17388 + 18452\n29037 + 8424\n10410 * 9345\n26257 / 1902\n18465 + 1127\n31781 / 22613\n15776 / 30682\n((8225 * 8281 + ((12484 - 29463 + 674 / 25397) - 19256 * 31087)) * 8808 * 6905)\n(16814 / 29681 + 17864 - 22911)\n29823 * 14479\n(14090 + 893 * 22862 - 17218)\n30592 * 26852\n21777 - 5950\n(7551 + 12464 - 19010 / 15304)\n6601 * 17940\n(29799 - 6512 * 3390 + 31017)\n24315 * 29194\n988 * 15082\n26516 - 619\n(16414 - 20756 * (15115 + 18695 - ((11794 + 13486 + 7838 * 19670) - 19208 / 11345)))\n32181 - 8175\n19133 + 23457\n753 * 23041\n((20887 - 5147 * (23527 * 31610 * 24562 * 27600)) - 16509 - 25832)\n10308 / 27964\n367 + 18495\n1169 - 14634\n16021 - 27469\n((22089 / 2162 * 21993 + 20837) + 8090 * 16134)\n30990 - 188\n22152 - 28664\n(6809 * 22418 - (28453 * 12236 * 21633 - 24220))\n((26404 - 3213 + 4073 - 17257) * 31244 / 29148)\n(22153 - 13314 - (10658 / 8982 - 28821 * 29028))\n23606 * 32618\n13762 + 22937\n31776 * 21156\n(10296 - 5159 - 27656 * 2169)\n494 * 980\n24157 + 18783\n26486 + 22283\n16672 - 31509\n20577 + 14848\n(17217 * 5066 - 21677 * 25110)\n(13793 + 13287 + 25534 * 1895)\n22957 - 14944\n8069 - 30671\n(20499 + 12466 * 28860 + 25914)\n2193 - 18680\n((2647 * 21430 * 3155 - 24858) - 23092 * 23593)\n25816 * 8406\n5804 * 27865\n9352 * 28202\n32004 + 1165\n13519 - 26045\n20969 - 18155\n29700 - 15565\n23348 * 8929\n21032 + 5601\n18977 + 4389\n25918 + 3594\n(12335 + 30505 - (19721 + 2181 + 14136 * 30822))\n7168 - 27670\n2279 * 16394\n4281 - 8660\n5283 / 21770\n24633 - 11423\n8707 * 28061\n32578 + 16723\n(23291 / 6612 + 4080 + 11906)\n810 - 25144\n20989 + 5174\n((2035 + 7388 - 5638 + 6349) - 5333 - 29880)\n32115 * 6738\n5972 + 26943\n32719 * 10595\n11437 - 3958\n29283 - 22951\n6182 - 14675\n(32334 + 7026 * 3894 - 2585)\n31481 * 21230\n14254 / 14656\n9662 - 27008\n26187 - 5136\n11637 + 23693\n21549 / 28773\n15060 / 14571\n18578 / 15993\n(16992 + 15117 * 8778 * 13557)\n11138 + 24121\n(653 * 11119 - (29894 * 24808 + 6734 * 18327))\n9079 + 15999\n6827 - 23208\n29285 + 12137\n17232 / 29480\n22244 - 28727\n(11300 * 22073 - 15182 * 351)\n23695 + 13273\n(26950 * 12611 - 23169 + 15295)\n25645 + 9394\n30594 * 9554\n(11940 + 30242 * ((16512 - 9815 - 32317 + 29247) - 3306 - 28019))\n(((3335 * 19047 + (27064 * 4623 - ((32528 * 12319 + 27167 - 19103) - 21704 * 21742))) * (32215 - 18330 - (24060 * 20188 + 29434 - 7184))) + 21244 - 6959)\n20691 - 25957\n7263 + 12565\n(32709 + 17885 - 27848 - 25290)\n6434 + 24661\n24788 + 8931\n24355 + 30205\n(6638 - 26095 - 5886 + 9694)\n27689 * 6426\n(21398 - 10047 / 22953 + 14128)\n30507 + 3832\n29354 + 2267\n((22660 - 32177 * 11775 / 20972) - 24750 + 26907)\n22312 + 7942\n27483 - 3832\n24122 * 22642\n31239 * 19811\n27196 - 25552\n(25934 * 7490 + (9521 * 14505 + 32387 - 28879))\n20759 - 2583\n32052 * 20638\n(24180 - 17875 + 27410 - 16845)\n13883 + 24919\n(12117 + 28991 - 29341 - 11675)\n(29384 / 15394 * 6430 - 5463)\n7824 - 31703\n(15082 * 17123 * 29453 + 10883)\n6199 + 23122\n11247 * 17149\n15409 * 16156\n4178 - 17422\n((2303 / 18052 + 10408 + 8136) + (205 - 4871 * 662 + 14083))\n29750 * 31373\n23223 - 22116\n10020 * 32763\n3388 + 916\n(29265 / 19163 / 11362 + 5895)\n10231 * 24990\n27436 * 23339\n(30371 + 25170 - 18533 - 1443)\n16167 + 24121\n(17522 - 27820 * 21726 - 13976)\n(((7874 - 2975 + 5529 + 31113) / 31777 * 28973) - 19493 + 29618)\n10793 * 28056\n(23301 + 8202 - 6904 + 30819)\n15848 * 28321\n20009 - 10643\n12437 + 25567\n22455 * 7631\n22503 * 21568\n2276 * 8551\n674 * 29224\n5064 * 23617\n31215 + 17816\n6011 * 10170\n3054 - 19774\n8888 + 14020\n9280 * 4685\n20036 - 8269\n12597 - 19986\n(11978 / 1940 - 32734 - 21384)\n28054 - 27066\n16789 * 31858\n4212 * 18784\n24308 * 12246\n21041 + 4978\n(28978 - 16911 + 13595 - 388)\n4926 - 24423\n20388 + 19294\n14226 - 12436\n12890 - 362\n((20518 + 14544 * 32677 - 26800) + 23978 - 12355)\n15804 - 14543\n15780 + 16796\n26890 * 18833\n12524 - 29973\n9374 + 16588\n18353 - 20294\n22181 + 16239\n5756 / 8203\n9021 / 11154\n3113 / 21474\n8971 - 18158\n17832 + 12155\n25645 / 12318\n25258 - 10597\n9549 - 23409\n24280 + 7773\n1364 * 28900\n12774 - 14010\n19552 + 4442\n12150 / 27637\n20941 / 15660\n10832 + 16940\n21913 * 12403\n32103 + 6232\n12858 + 4457\n((11407 - 18010 + 10198 + 22759) + (22061 - 22948 - (5885 * 7293 - 12271 - 18087)))\n7864 * 21389\n(17437 + 16144 * 26562 * 25977)\n24698 - 10584\n(28833 - 16694 * 30876 + 27247)\n29822 - 28311\n26337 - 5931\n28531 - 25470\n14557 + 22182\n24594 / 31523\n((28144 * 22627 - 25189 * 10907) + (21445 - 30947 - (20266 + 4640 * 5052 - 21217)))\n27168 + 16710\n(16638 + 16516 + 32125 * 17354)\n((16130 * 23542 / 10384 - 12362) / (19281 * 27435 + 23282 + 25659))\n19191 * 12553\n22009 + 29857\n2379 * 6444\n6167 - 13700\n(30157 + 5982 - 17051 / 11324)\n11332 * 2449\n22651 - 19299\n(14695 + 28288 + 27395 - 15041)\n(14886 * 24974 + (15492 + 12079 + 29404 + 18893))\n(((16000 + 15301 + 27633 * 30998) + 32472 + 14273) + 6735 * 7631)\n15943 - 21925\n8950 - 27370\n(572 * 13983 / 6324 * 7494)\n2126 + 31063\n19922 - 5144\n12472 + 30599\n23121 / 32552\n5332 / 28437\n4098 * 1502\n29519 * 7377\n(18284 * 26058 - 21802 * 28113)\n12409 - 30662\n(24584 * 21873 - 12238 - 19537)\n21861 + 14716\n30409 / 20583\n2590 - 27484\n4639 + 19836\n29397 + 7973\n27066 * 20705\n(6006 - 4312 - 6326 + 23985)\n19697 * 27958\n9230 + 28322\n21138 * 27431\n13829 / 23416\n940 / 27784\n(31327 - 12978 * 12013 - 23249)\n965 + 7852\n(22205 + 30762 + 19243 - 21178)\n(4139 * 4720 + 2049 / 16268)\n178 * 6798\n(11296 * 6242 * 14488 * 9211)\n26004 - 19784\n4325 + 24730\n(17342 + 2738 * 2529 * 17881)\n(20114 - 6431 - 2589 * 24550)\n(5647 - 357 + 27947 + 9666)\n17660 * 6451\n((8752 * 12989 * 30728 * 23086) + 4659 / 24770)\n(9077 + 6880 - (4433 * 16491 + (19060 - 14569 - (18603 + 21077 * 17198 - 27024))))\n16899 + 32459\n((2933 + 13218 - 7974 / 20630) + 19519 + 27640)\n9281 + 27332\n30637 * 28063\n1314 - 25435\n18686 + 30426\n(24881 * 1841 - 26737 * 473)\n5904 - 5308\n28962 - 1650\n31360 - 273\n13303 - 8848\n18420 + 16209\n19214 / 21715\n31522 - 20668\n31297 * 24212\n(2067 - 8305 * 14037 + 27015)\n32499 * 3343\n28315 - 29457\n18353 * 8502\n15827 - 10231\n(19702 - 27239 * (10680 + 8048 * (((11472 * 11802 * 28953 + 26847) * 27682 - 27532) - 27944 * 26335)))\n573 * 14469\n9226 - 6249\n9348 + 9758\n(23095 * 11725 + (16946 / 30566 * 5416 - 597))\n10223 * 5680\n2378 + 2122\n8096 * 13743\n27475 / 3069\n21644 - 14041\n1450 - 15041\n28107 + 26245\n10472 - 12269\n17846 - 32714\n11759 / 17623\n16830 * 21289\n7319 - 11432\n22544 * 11178\n22202 + 1739\n(30753 * 29493 + ((32611 * 16594 - 3159 * 8828) - (15030 - 29118 / 27839 + 325)))\n(15638 + 29824 * 10714 / 5368)\n31018 * 18991\n30314 * 14687\n6346 * 12633\n(31732 * 23038 * 10466 - 19854)\n9060 + 7745\n((20446 + 25198 + 7264 - 25757) * 1742 + 26774)\n21973 + 12772\n7954 * 28141\n26825 - 2230\n(27537 - 29191 * 3459 + 30487)\n17038 + 27537\n11087 - 25541\n589 + 15404\n32693 * 16687\n((3312 + 23526 + 16278 / 15679) + 23331 + 11938)\n15200 * 3375\n(22420 + 19811 + 16107 - 28825)\n1662 * 20427\n19655 * 2499\n14979 / 7551\n5402 - 24897\n887 / 11251\n13387 + 15360\n(15534 + 21032 + (4017 - 2953 - 11902 - 6740))\n(29865 - 16794 * 14401 - 13992)\n29141 + 8676\n(15104 + 19617 * 5425 - 23434)\n(27634 + 9329 / 32525 * 25873)\n29734 * 1851\n5896 * 24789\n30136 - 10399\n22592 * 28988\n6969 - 1615\n11182 * 19904\n22763 / 7863\n31865 + 13967\n3674 + 14968\n15266 - 8898\n27001 + 30836\n((27167 * 2154 - 25633 + 31660) + 17768 + 28114)\n26956 * 21557\n6599 * 11068\n13077 * 22255\n31929 + 18910\n11821 - 22160\n251 + 20570\n4840 * 12825\n6769 + 21840\n7990 * 15262\n9684 * 4188\n17580 - 7100\n12388 + 22245\n30465 / 27493\n20582 - 28117\n13670 / 25971\n14368 - 11338\n3089 * 11309\n26335 * 23927\n19546 - 4176\n27719 + 5970\n18656 / 29795\n18493 * 22774\n30051 / 31892\n16779 + 2512\n(13224 + 18543 + 19090 / 18520)\n(4166 - 31818 - 15315 * 18112)\n2292 - 20864\n22809 + 15458\n10088 + 24427\n((24482 + 14156 + 20290 - 4174) + ((25677 - 1151 + 15521 - 26833) + 326 - 28817))\n3225 - 23936\n26663 + 7705\n2597 + 13843\n27494 * 377\n22052 - 3513\n11282 - 5891\n15949 * 29183\n(11210 + 16561 + 9672 + 2813)\n4252 - 12995\n21332 - 15371\n27961 + 21546\n29521 * 27088\n13127 - 29118\n7499 * 6530\n(31615 * 13999 - ((19936 - 30765 + 23787 / 31516) - 30021 * 1772))\n(2226 * 27008 + 24617 - 11147)\n4785 * 22309\n30367 * 5485\n11734 - 28052\n15195 - 22962\n18999 * 7505\n27987 - 17952\n9357 + 4770\n19212 * 23737\n((22152 / 17307 + 3027 - 16615) * 14784 * 7632)\n14897 - 21255\n15077 * 5023\n13407 * 19394\n26486 - 8427\n(30527 + 6581 + 21539 - 8299)\n16891 - 12218\n31917 * 18122\n14484 - 25512\n28686 + 20799\n((((26027 - 15138 + 12967 * 15829) / 14105 + 20414) * 4904 + 12006) * (15649 - 12737 - 5699 / 16045))\n(24451 + 25963 * 22438 - 32014)\n7726 + 6000\n15933 * 3399\n(1982 - 21440 - 29934 * 1257)\n32406 - 11870\n23033 + 8797\n18228 / 20821\n6195 + 31778\n((27441 * 17925 + 31965 - 20648) * (6691 - 30779 + (12731 + 8972 - 10895 + 9424)))\n(21539 + 15069 / 17370 * 24328)\n10260 + 20625\n1736 - 21781\n(14625 - 22744 - 6130 * 4763)\n22014 * 23084\n26589 * 30893\n(19016 * 11062 - 8899 * 16574)\n12663 + 8103\n30519 * 29236\n(26143 - 29247 / 24610 * 31343)\n(19565 - 9995 + 31199 - 26462)\n11140 - 17980\n(31410 * 27130 + (15026 * 30905 + 18968 * 17852))\n16578 * 31930\n7146 + 5657\n5298 * 12310\n4658 + 13862\n28249 * 16372\n1550 * 22910\n13323 / 26956\n5171 + 27044\n(30078 + 17988 - 15931 + 16284)\n(27463 / 16352 - 22565 + 30128)\n24997 * 12029\n(5464 - 22154 + 24139 / 17859)\n19282 + 30428\n10839 * 6592\n25774 * 5310\n21242 * 25826\n8972 + 24510\n30137 + 3689\n3682 - 3552\n29116 + 18748\n3545 * 6895\n5541 * 31530\n1504 - 21099\n31075 - 14848\n26904 - 6272\n((1760 * 15711 * 30994 - 8418) - 5511 - 272)\n26886 - 16868\n13924 / 14708\n12027 - 19180\n32512 - 22267\n27745 + 29168\n((23901 + 1379 + 19526 + 789) + 19900 * 17710)\n31967 + 4932\n19164 + 27937\n21431 + 7930\n(21324 + 18471 * 19021 * 12244)\n18794 * 27588\n(12277 - 26604 / (21108 * 20673 * 25681 + 27822))\n23718 * 6501\n13070 * 23785\n10886 * 18197\n27779 - 31547\n(16520 * 11507 - 6299 - 17333)\n5677 - 12017\n(6055 - 1194 + 29215 - 830)\n24002 / 9410\n32542 - 13307\n(11534 * 4563 - 21740 / 13262)\n(20851 - 27056 + ((2416 + 21971 + (6306 * 284 - 28684 + 2450)) - 30479 - 972))\n(23822 + 17205 - (25256 - 5967 * (11336 + 27885 - 15466 * 14185)))\n3933 * 30991\n10178 * 21526\n31186 - 9205\n27548 + 9677\n3436 + 1756\n23758 - 3285\n13881 + 16034\n3997 * 23684\n(13922 * 14113 - 211 - 15836)\n(((15112 + 12076 + (17597 * 3852 + 8553 * 15874)) + 5150 - 15602) + 28133 - 8454)\n5147 - 18340\n32138 - 12520\n23041 * 14341\n(23663 + 17823 - 7832 - 13976)\n27448 * 10884\n11615 * 1512\n27168 + 31472\n26880 - 15378\n3390 + 12539\n1169 * 29173\n(19976 + 5900 - 29846 + 15346)\n21249 / 10920\n5864 - 12869\n(28602 - 10378 * 7399 - 1362)\n(16498 + 2608 + 28922 - 21467)\n24296 * 2153\n32096 - 19115\n32525 * 15732\n28113 * 6712\n16459 + 11584\n12051 - 27252\n475 + 11253\n(12388 - 16037 * (23654 + 11234 * 26416 - 20084))\n(24502 * 13678 + 18241 + 15946)\n6852 / 19642\n12474 - 23367\n27263 - 29380\n((20446 - 19690 * 21229 * 541) * (31142 + 13100 * (306 - 13184 + 15330 * 17056)))\n30900 - 16180\n28468 * 20130\n(23451 - 16146 * 18383 - 15767)\n22236 * 20528\n((((17795 - 25829 + 1357 / 8817) + 3272 - 27427) + 25611 + 19836) + 23338 - 4342)\n5668 + 8795\n11422 * 17858\n26830 - 10515\n(28769 - 11048 + 14501 * 26626)\n22226 + 22027\n((((30298 / 8553 / (10631 * 30747 - 15095 + 21446)) / 14566 - 28584) / (189 * 31735 * 529 - 17187)) + 5199 - 18454)\n(18925 - 9244 * 6766 / 32495)\n14696 * 21321\n(3225 - 1483 * 9458 - 6609)\n26141 * 11875\n29100 + 20359\n7089 * 2640\n21064 + 20541\n23213 - 3235\n30710 - 27894\n23165 + 28860\n31100 - 2200\n15799 * 7425\n(((26588 - 15929 + 22752 - 1564) - 23742 - 473) - 6367 * 4474)\n11947 - 22113\n(16173 + 26742 + (12188 - 14822 * 18694 + 24872))\n123 + 27504\n3831 / 29064\n5487 * 4529\n14807 / 22798\n29186 * 21686\n32756 * 4117\n18724 * 32531\n(29396 * 551 * 4721 * 24562)\n16064 * 18761\n1347 - 9497\n(19258 * 23904 - 4824 + 31471)\n13747 * 25147\n(7399 * 10630 + 19914 * 31941)\n1315 + 31248\n(((6416 * 4845 * 13808 - 10817) + 17026 / 9643) + 25160 * 30828)\n(8133 * 14413 - (7123 + 9707 * 22584 - 29645))\n16660 + 17951\n17437 * 5159\n4031 * 16284\n23732 + 6709\n9236 + 11381\n20063 * 8815\n((4997 + 21707 + 28459 + 12197) - 28261 - 3981)\n21541 * 29139\n31484 - 32308\n24526 - 11726\n25191 * 22884\n17637 - 21185\n32667 - 28107\n((19722 - 485 / 21767 - 791) + 7063 * 9268)\n18648 + 28537\n(25562 + 18264 * 21783 - 24209)\n17931 * 890\n31177 - 30940\n6843 * 22801\n(10322 * 15714 * 13784 + 23120)\n19901 + 30599\n19739 * 2084\n(29012 + 13285 - 13843 + 6561)\n(30964 - 31021 + (31998 * 8487 * ((5400 - 22167 + 31345 + 30936) + (25043 + 24369 * 27212 * 15425))))\n3973 * 3711\n(20654 + 14738 + 1959 * 5355)\n(1081 * 25151 - 30461 + 23648)\n23439 * 6772\n18751 - 12595\n(31651 * 31463 * 9672 - 3153)\n26116 - 22045\n5362 + 10754\n4438 + 21467\n7729 - 2499\n17115 + 23164\n(23029 + 22006 - 1970 * 21373)\n9934 * 32647\n11999 - 776\n(19417 + 31845 * (24081 - 19558 * (13433 - 32361 + 5152 - 28141)))\n17980 - 12291\n28876 - 8952\n28006 - 7181\n1608 - 27613\n19033 - 9187\n26820 / 30174\n2552 - 11510\n26296 + 3568\n4234 + 24582\n1734 + 17901\n24950 * 23347\n(28893 - 7487 - 2262 - 19859)\n21762 * 15234\n(12345 - 8475 + 1727 - 23365)\n(16272 + 17161 + 11083 + 28456)\n13306 * 6073\n(7123 - 5977 + (25678 * 2249 * 7776 * 31071))\n12600 * 26190\n29877 - 23217\n(5562 - 19524 * 17600 * 14524)\n2938 - 2869\n18802 * 25276\n26479 - 16574\n(20655 + 27598 + 1387 - 12468)\n19358 + 30822\n2246 - 2489\n14389 - 19807\n210 + 10599\n(1075 - 6648 - (((233 + 15975 + 19169 + 16569) - 22463 - 9759) - 27953 - 29092))\n(27956 + 12102 + (((6473 + 30122 * 11370 + 23502) + 31404 + 10504) / (9537 * 26371 - 27375 + 30877)))\n22724 + 12260\n28421 / 8052\n27616 * 16233\n20219 + 12621\n6557 + 21971\n4844 - 30599\n(2640 + 10862 + 27829 + 30855)\n22798 + 16336\n(11403 + 13227 - 3988 * 28626)\n25507 * 7165\n21136 - 27260\n22853 + 24529\n(1250 + 25215 - 10001 * 29377)\n14805 + 16902\n30246 + 5722\n13070 * 19433\n27925 - 23450\n17790 * 31718\n7347 + 13675\n9536 + 24210\n3834 * 12519\n6835 * 11815\n19427 - 9880\n26595 - 13789\n21432 * 1123\n(25197 / 32103 + (6727 - 16596 * 18620 - 29548))\n9534 + 17941\n(11221 + 5377 / (27029 + 18010 * 18524 / 4349))\n23444 * 13372\n5276 + 13742\n8472 * 5200\n18903 / 11026\n11759 * 6997\n(26891 * 15441 / 20767 - 19987)\n25447 - 23714\n(18161 - 13815 * 19027 * 17762)\n13391 - 8766\n29912 + 13922\n2007 / 28994\n(1762 + 2811 * ((31725 * 22200 - 13095 * 661) - (18675 + 28417 * 31868 + 25233)))\n(9844 * 20355 * 5703 - 9652)\n(21663 * 30120 + (9274 - 30524 + 30537 - 19583))\n((31599 + 21625 * (3018 + 26991 * 7543 - 7380)) - 4287 + 13243)\n24141 - 1407\n((24198 + 23997 * ((9390 + 31690 + 10568 + 31566) * 3150 + 18544)) + 20427 - 8099)\n5421 + 26888\n(27712 - 18045 * (1933 - 13900 + 24537 / 15325))\n10408 - 18392\n(18142 + 17923 + 4119 * 9571)\n27321 * 9855\n32149 * 283\n22855 - 15336\n(15649 * 12596 + 15751 - 2663)\n17938 - 28252\n20802 + 26110\n(23106 * 3138 / 7823 + 17931)\n(25143 - 10910 * 25015 + 3898)\n11340 + 15285\n21938 - 18014\n27564 * 32567\n12435 * 2179\n15074 - 19789\n20961 + 20915\n2626 / 32426\n30155 * 11031\n11928 + 21951\n30314 + 20576\n3766 * 15687\n18370 * 26344\n21685 - 108\n18225 * 12461\n25905 + 12743\n5266 * 3568\n25746 + 26511\n(3095 + 28194 + ((((31470 + 16677 + 22016 * 14854) + ((30233 - 6727 * 31807 * 29801) + 13643 * 6793)) + (((5392 - 22608 * ((21356 / 30702 + (19311 - 153 * 3368 + 2863)) + (23702 * 4993 - 30348 + 20297))) * 9399 - 32250) - 5399 + 5290)) - ((28532 * 32310 + 14083 / 8106) + 24209 - 21524)))\n(24931 - 4465 * 32352 - 89)\n4847 - 123\n12875 + 17673\n14141 + 24360\n16739 / 1338\n27009 + 8582\n((31110 + 1316 * 17648 * 3100) * 8124 * 20450)\n(15102 + 8873 - 32367 - 7362)\n5966 - 12595\n14035 + 1578\n7786 - 21\n27136 - 14557\n(21338 - 24954 - 8447 - 15304)\n32720 / 5432\n23753 * 21932\n24786 + 14068\n(9415 + 19435 * (12594 - 10242 - (8023 - 15428 * 18574 * 4079)))\n9689 * 27226\n(26196 * 29530 + 17622 - 10813)\n(31887 * 13569 - 27139 / 3341)\n(7498 - 3608 - 12602 * 15172)\n(21620 * 7993 + 12998 + 6105)\n12913 + 5296\n10268 - 2893\n16107 - 19328\n10848 + 7796\n4477 - 1538\n12029 + 32519\n(24357 + 31017 - 28589 - 19455)\n19316 * 28310\n6711 + 31968\n30892 - 12162\n19663 * 14230\n6725 / 6744\n22575 + 2549\n(31602 * 9196 - 18703 - 13024)\n23199 * 797\n9479 / 24321\n24647 - 18111\n12385 + 11621\n(31571 * 16250 + (7571 + 26121 * 10314 + 1440))\n32312 * 7230\n(19346 - 26395 + (9616 - 17324 / 16859 - 8130))\n4704 + 1556\n16493 / 23454\n(17535 + 4309 - 31522 + 32518)\n19421 * 32750\n23461 * 25668\n19462 * 23148\n16330 - 14495\n19646 * 15762\n2196 * 5687\n32105 - 26767\n10210 * 19325\n7346 - 3767\n(8198 - 20196 * 6924 * 23900)\n((19565 * 24558 - 4804 - 1129) + 22199 - 15938)\n20642 + 29579\n27422 - 22258\n((30558 * 5407 + 1625 / 24541) - 2971 + 5315)\n9320 * 306\n11525 - 19783\n25255 / 17680\n30924 - 26430\n30615 + 26592\n3154 * 10636\n(3863 * 14021 + 29051 - 26605)\n((29777 * 6269 + 27136 - 31194) * 11227 * 6332)\n24590 * 17991\n27075 - 23551\n1146 * 20454\n25522 / 8115\n((10304 + 7172 - 13271 - 9617) + 32221 - 4461)\n20122 - 3011\n31552 * 29944\n(28055 - 21264 - (30277 * 7387 + (16980 - 844 * 24371 - 31441)))\n20914 - 16771\n12853 / 20321\n7917 - 15034\n16240 / 13146\n19960 + 21773\n(13901 - 17434 / (10039 - 1177 + 18332 * 3353))\n12922 + 19273\n1824 / 6898\n419 + 19868\n18647 + 30292\n31418 + 12551\n31340 - 19577\n28371 + 7191\n24706 + 17461\n15786 - 16675\n29522 + 21944\n14125 * 32411\n23977 * 29726\n20752 - 3183\n2870 + 4697\n21590 + 11810\n16393 - 8984\n8216 * 26338\n32129 * 31629\n10088 - 26153\n2068 * 21612\n(21394 * 10461 * 14035 - 12865)\n18170 * 29680\n(26016 - 10803 + 24642 + 32721)\n25601 + 7715\n((7824 / 23819 + 6766 * 16566) * 18645 - 28556)\n3495 * 17723\n21454 - 15812\n14626 * 4761\n(((9833 * 5611 + (26781 * 4784 - 8086 * 10412)) + 23856 + 18732) + 18790 - 11720)\n5361 - 23281\n14445 + 13452\n15294 + 27845\n(18828 * 7094 + ((27769 * 19366 * 10797 + 32545) * 11921 * 9329))\n15994 + 14241\n14859 - 1074\n7703 - 8572\n25381 / 23467\n17158 + 19939\n19208 + 2187\n30748 + 13879\n25329 - 21834\n23316 + 30097\n7815 * 18065\n10565 * 8035\n9688 + 10922\n(15003 - 32652 / (9667 * 3659 - 22089 - 17569))\n7108 + 10493\n6377 * 12729\n(25475 + 10605 * 17998 - 16550)\n2575 + 19230\n29426 + 17746\n27591 / 27248\n5599 * 25049\n18022 - 30209\n21611 + 5454\n22260 * 22832\n8639 + 3036\n997 * 30855\n12027 + 18261\n1359 + 31648\n18765 + 16171\n10001 + 5384\n32035 * 2039\n19391 * 14324\n(24988 / 12069 / 20489 + 2802)\n(17257 * 3763 - 17050 / 2064)\n1050 * 15739\n(2699 * 22331 / (3066 - 3872 - 11468 + 18143))\n18189 * 24313\n28519 + 17722\n3528 - 23703\n7868 - 6652\n25660 - 27760\n15348 / 28960\n22593 - 21436\n22516 + 28241\n11708 * 968\n12948 + 31652\n28100 + 6568\n(15579 * 30477 + (25461 - 26551 - 18183 - 4743))\n2776 * 3903\n(5140 * 14669 * (831 * 15463 - 3595 * 7730))\n24935 - 6250\n2409 * 19892\n27012 - 15195\n1431 + 9995\n6707 + 23744\n15583 * 29806\n2501 + 8303\n(9838 * 16595 - 9435 - 14703)\n14690 * 15957\n10879 + 21947\n(11250 * 31835 - 16482 - 8077)\n(12189 - 14937 * 4381 * 26006)\n21496 * 17685\n8558 + 30835\n16708 + 80\n1978 * 6898\n27232 - 16803\n(20355 * 24638 + 18813 / 9402)\n7299 - 4418\n8056 / 2407\n7897 + 12744\n20409 - 157\n5242 * 16946\n3875 * 27754\n17107 - 30779\n(24918 * 6981 - 7878 * 26842)\n26288 - 1213\n14468 + 30438\n(391 + 27942 * 11116 * 15029)\n24458 - 27011\n22050 / 22395\n6615 - 29879\n(29407 * 13081 * 22230 / 1230)\n((16042 - 6317 + (15084 * 22000 / (22962 / 21844 + (27819 * 26493 + 9859 + 19695)))) * 6537 * 25582)\n(22609 * 17229 * (6145 * 16080 - ((12013 + 13319 * ((30727 - 5402 + 7448 - 7916) * 28541 - 1128)) * 23418 - 2451)))\n(1500 + 4656 + 11658 + 14383)\n17180 * 17831\n27874 + 10658\n12925 - 12670\n22522 + 28534\n31500 * 26811\n3929 - 15666\n31076 - 206\n7143 - 9212\n12167 + 6077\n(31960 - 11164 + 30436 - 7347)\n23594 - 26609\n29159 * 3057\n(32424 * 2243 - 7951 + 156)\n6047 + 31702\n22458 * 28436\n9605 + 1572\n21029 - 24151\n22629 - 22880\n(((26237 / 8431 - ((20932 - 27064 - (16411 * 8860 + 8159 - 19714)) / 13745 * 32586)) * 19975 + 12660) + 30035 * 13717)\n28236 - 314\n23853 + 21962\n21080 + 7629\n12711 / 7851\n((14047 + 6464 + 25773 / 10565) + (6620 * 11540 * 24234 / 11371))\n10374 + 24332\n17244 * 15753\n(26094 + 8964 - 6531 + 10949)\n22130 - 30363\n8740 - 9687\n2073 - 5728\n1514 + 4089\n21204 + 28852\n26299 + 14769\n19954 - 27946\n7465 - 13155\n21411 + 5165\n17207 - 2292\n22083 * 22802\n29886 * 10785\n27359 + 2630\n31786 + 28326\n(14356 - 18079 * 32250 - 17669)\n(((((26736 * 2597 / (6808 - 11681 - 27502 - 18003)) - 13278 + 26383) - 10060 - 6378) + ((14409 + 21799 / 10745 + 31176) - 28216 * 7122)) + 15624 - 13436)\n9118 / 16358\n27174 - 26878\n30887 + 30212\n26584 - 18734\n11590 + 17147\n24673 + 17937\n28137 * 5477\n6417 - 13292\n30137 - 4953\n19096 / 28906\n(8183 + 23336 - 27182 + 4921)\n23601 * 5930\n19322 * 28037\n31602 - 28504\n(26593 - 7090 + 23669 - 21636)\n21521 - 17152\n4811 + 13125\n(10365 - 5600 + 23223 + 8297)\n5174 - 21030\n(10965 + 23007 - 66 * 30568)\n22256 + 28931\n4399 / 7016\n28731 + 4172\n(6016 - 31643 - 4763 - 15825)\n((5826 * 9615 / 3108 - 5931) * 27292 + 21500)\n13139 - 10707\n22779 - 6464\n((6958 / 10043 - 10884 * 855) + 7265 - 24582)\n12283 * 16080\n(3524 + 16269 * 5911 - 22509)\n22877 - 6070\n12269 * 3107\n22542 - 19655\n24838 - 25674\n((1933 * 4003 + 23178 + 4387) * 7395 - 28917)\n((16737 * 30191 - 3273 * 10851) + 26746 + 9799)\n29677 + 7558\n31198 - 28303\n27304 * 16670\n20152 - 21768\n12336 + 1663\n(24283 * 9751 - 30841 * 6256)\n23473 + 837\n20152 * 7219\n(27428 - 7727 - ((27765 - 4459 * (16612 * 22696 + 19978 + 18040)) - 28237 + 21402))\n(25987 + 11802 - 18203 * 20185)\n19529 * 32452\n9809 * 15975\n2996 - 23152\n(28446 / 24209 * ((((16919 * 21174 + ((1531 - 20454 - 3282 / 23386) * 6949 - 20295)) * 21377 - 3165) * 9148 * 28729) + 21076 - 19052))\n2220 * 30610\n11079 + 7061\n2140 + 11927\n((28917 + 22165 * 8150 * 24242) - 22824 - 30713)\n((1463 * 21554 - 4566 - 25802) - 28901 - 20772)\n9296 - 11533\n10473 - 4117\n4262 + 2119\n3138 + 27454\n3138 * 23637\n(9704 + 31374 - 25380 / 27476)\n(28177 - 9753 / 31070 - 21353)\n13249 * 15179\n(31555 - 221 + 18700 * 16488)\n27188 / 30005\n8356 / 26711\n100 + 7265\n8533 * 27420\n10524 * 2763\n4619 * 19120\n110 * 2594\n2809 + 2293\n28151 * 9608\n(14094 + 14210 + 10430 + 7736)\n17170 + 12587\n4671 + 8663\n28764 * 5965\n1815 / 2988\n20103 + 21373\n23136 * 956\n26612 - 11446\n11405 - 22327\n32346 - 27370\n27688 * 29622\n32523 - 13029\n24557 - 25991\n(16217 * 29317 + 27796 * 31727)\n30501 * 11510\n(21214 * 8318 + 3574 + 19566)\n28118 + 24693\n26694 - 17874\n10488 - 990\n13339 * 5496\n(22690 + 31962 * 6389 + 29970)\n19407 - 9112\n26715 * 4746\n21487 * 13351\n((23982 * 8419 / 8743 + 24463) * (3419 - 3955 * 22016 - 6069))\n4734 - 10228\n31008 * 1486\n8226 - 4478\n7252 + 31274\n((12453 * 13112 + 29645 * 3117) - 31294 * 24732)\n((17394 - 2379 + 28585 - 26173) / 11001 + 13749)\n25719 / 24473\n29393 - 11783\n16479 + 1590\n15374 - 15970\n8023 + 24385\n(19093 * 8335 / 13793 - 2607)\n11216 / 21152\n((11334 * 15828 + 31018 + 15416) - (((29798 / 31448 - 17402 * 19939) + 15438 / 24607) - 363 * 16464))\n4779 + 651\n7965 - 6822\n24026 * 23606\n20686 + 2861\n(((31335 * 2967 - 13123 / 8921) * 31559 - 10399) / 26702 + 25460)\n18805 + 27788\n4575 + 8195\n((412 - 20039 * 2988 * 23043) * 22090 - 31844)\n30692 / 15284\n(18921 + 406 - (19384 - 22502 - (((24706 + 22405 - 19625 * 19421) * 1772 * 19948) / ((2030 - 22646 + (15391 * 5922 * (12574 - 5067 + 17455 / 2002))) + 20414 * 10558))))\n31369 * 19318\n12793 * 16901\n(29020 * 28302 + 32040 + 28535)\n1002 - 30391\n(23719 - 8378 + (378 * 23081 - ((25467 * 6371 * 1335 / 26207) + 30283 / 1681)))\n(4824 * 598 + 28333 * 4248)\n28593 + 31922\n(14646 + 25444 * 30044 + 262)\n19813 * 31743\n20013 - 1913\n((((12492 + 28067 + 28329 + 23163) + 18474 * 5129) + 11847 * 12990) + 25190 - 5940)\n(27912 - 31087 - 205 - 25175)\n((31595 * 22628 * 9067 + 12171) - 18015 + 9517)\n12927 * 16485\n23418 * 8951\n((22863 * 30392 + 28940 - 6491) + 27472 + 3348)\n32641 - 15402\n26119 + 18493\n29329 * 25054\n5924 + 1118\n((29005 + 30162 / 18301 - 27262) * ((7376 - 2408 - 5145 * 6071) * 21696 * 5136))\n8705 * 23321\n13745 - 21793\n6207 + 17372\n12021 + 18055\n4067 - 27668\n17207 - 1407\n12105 + 31284\n(31542 + 5416 + 19336 - 20232)\n9453 * 25734\n1694 - 19690\n20753 - 11365\n(9100 - 23915 * 7454 + 12958)\n15013 - 12973\n(3318 + 21461 + 24778 + 27133)\n32083 * 12159\n((7675 - 32413 * 11933 + 16959) * ((28119 - 5579 - (107 + 22734 * 759 * 13944)) * 15638 - 19034))\n14298 - 13540\n(13081 * 12659 - 19683 * 12794)\n(23573 * 6883 * (28628 * 29685 - 5362 + 14683))\n24471 * 13437\n9644 + 26170\n9787 - 7307\n(26245 + 15718 * (14359 + 13513 * 14244 + 1186))\n20434 - 25372\n19614 * 5917\n29193 - 19654\n22892 * 17428\n1893 + 27527\n21355 * 27186\n3536 - 6785\n26425 + 7262\n(29661 + 14574 + 5575 - 24359)\n14998 + 16037\n25175 - 1570\n16225 * 3177\n28773 - 24909\n(24087 * 25693 / 3034 - 14000)\n30796 + 28346\n5322 * 508\n(5210 * 5187 + 8698 - 15795)\n24720 - 26718\n18376 - 15069\n30271 + 20710\n31448 * 13748\n(4859 / 25917 + (23905 - 22681 * 28369 + 935))\n22063 * 15847\n(799 + 20299 * 4608 * 32568)\n(20457 * 12955 * 25944 - 392)\n((15706 - 9129 + 18302 + 3707) * (3510 - 29206 * 29931 - 12202))\n(224 / 32712 - 19808 + 21005)\n((10526 - 31788 / 5556 + 3574) + (14465 + 18789 * 17116 - 20126))\n9632 + 30886\n32620 * 30305\n((30135 * 22381 - (23005 * 24742 + (24957 + 545 * 21662 + 20552))) - 20193 - 15845)\n10681 + 1854\n9247 - 28850\n(56 + 28326 * 18371 - 31165)\n19107 - 7347\n24739 + 22299\n(6188 + 31361 / 17306 * 1758)\n(21314 - 20702 * 15383 - 3413)\n29991 - 7837\n(((((20317 + 30118 - (7192 * 19373 * (29560 - 28778 + 13552 * 23909))) / 8923 + 31177) - 28601 * 13897) + 16213 - 11825) + (15283 / 15375 * 8536 * 30236))\n(26832 - 18160 + 19972 - 28636)\n18729 + 22066\n28851 * 17225\n1179 - 19606\n18813 + 7730\n14642 * 1884\n6876 / 10322\n8635 + 887\n((3528 + 15860 * (32220 + 13944 / 31581 * 21710)) + 14215 * 22118)\n(((30309 * 17785 * 31839 + 24296) - 17213 - 955) - (1896 - 32255 + 12145 * 12475))\n30320 * 7430\n17334 - 609\n14843 * 7165\n17010 + 9905\n18632 + 19275\n9725 * 14339\n24310 - 20828\n18593 - 31397\n((6344 * 1659 * 25285 + 7900) - 24721 + 6331)\n11171 * 17349\n16956 - 27808\n17199 - 12544\n12130 - 21021\n24643 + 5328\n(22263 - 621 + 25745 - 3386)\n27770 - 23181\n((28869 * 3096 - 10279 / 10272) - 10312 - 18742)\n1784 - 9973\n(4195 + 7487 / 3642 + 18621)\n21034 * 11967\n(8014 * 10515 + 11625 + 16519)\n(31618 + 12040 * ((26959 * 27971 / (12521 + 32694 + 27561 * 6225)) + 17498 - 17754))\n((16909 * 17134 + 1231 - 19008) - 2694 * 31934)\n(7497 - 27082 + 14482 - 10651)\n(1695 * 15522 + 28883 / 6318)\n(7874 / 27208 / 29546 - 8453)\n20679 + 1458\n(28473 - 29324 * 7327 * 18956)\n4119 + 26546\n26448 - 13159\n((30749 - 13703 - 10735 + 8764) * 27375 + 30877)\n32434 * 31184\n16391 - 3225\n7775 * 29656\n15650 - 30711\n24182 - 10429\n27060 * 3674\n26087 - 11856\n10355 - 2338\n12046 / 25153\n29263 / 6069\n6606 + 19791\n23462 - 6915\n(23067 * 9311 + 3259 * 23848)\n(1415 + 2521 * 15875 + 26295)\n778 * 18520\n5221 + 22310\n21900 - 17341\n27231 + 28546\n(17805 * 382 * 25975 - 67)\n7423 + 14648\n((1159 - 7551 + (22043 - 16256 - 6799 + 420)) + 28869 / 12673)\n26955 + 22353\n(5767 + 11634 - 18666 - 11817)\n24664 * 5206\n(27001 + 8059 - 6483 + 12947)\n10456 - 2080\n17962 * 11306\n22116 + 24380\n683 * 18975\n6795 * 31384\n6550 - 17449\n25650 + 15654\n8603 * 532\n476 * 11681\n7142 + 7129\n8756 + 30717\n(657 - 19376 * 14770 - 25907)\n2601 * 31460\n21770 * 10820\n((21991 - 8926 / 12890 * 13051) - ((20544 - 20388 - 21582 * 32068) - 26651 * 15603))\n4081 * 29470\n1764 - 24180\n12484 + 27054\n19379 - 17514\n26915 * 11003\n15281 + 18414\n23141 * 8434\n30106 + 25301\n19012 + 25740\n13334 + 3305\n(((18117 * 1411 * 4140 * 10492) * 26414 - 7271) * 8704 + 25695)\n4965 * 10812\n(17826 * 26164 * (10558 + 15556 - (18229 * 9899 * 28242 / 12791)))\n10274 * 23773\n16011 - 9152\n5132 / 19616\n24427 * 9458\n(24383 * 1559 - 26228 * 28391)\n((18728 - 1454 - 25943 + 3764) * 13878 + 16363)\n25144 * 2379\n(28246 * 15744 + 19902 * 3972)\n(((16458 - 30786 * 7120 - 16259) / (5365 - 12041 - ((16684 / 10020 / 27799 + 10165) + 11798 * 17449))) * 10003 * 5012)\n((451 + 1105 - (8966 / 9429 + ((28209 - 26779 * 23259 * 19486) + (8826 * 28359 + (4155 - 4655 - 12794 * 3500))))) * 28983 + 22530)\n(30745 * 12579 - (16244 * 17247 - 7409 + 26405))\n(3659 + 9430 * 26867 + 5686)\n9799 + 23832\n((24314 + 5970 * 10718 * 16492) * 17436 * 21609)\n(19166 + 13294 - (9586 / 15914 * 12095 * 29273))\n23248 * 28334\n25352 * 23\n(30919 * 11906 - 28960 - 29577)\n10767 + 14682\n(15624 + 3839 - 13714 + 32062)\n17777 * 1947\n19395 / 28623\n((23308 * 13674 + 690 * 23248) + (7670 + 6312 * (31316 + 5411 + 22534 * 1838)))\n10577 * 13379\n28992 * 17926\n(8500 + 11129 + 26312 - 331)\n16456 * 11967\n7684 - 27709\n(30146 - 8310 * 8938 + 691)\n(((21775 - 26733 + 20389 + 9172) + 19656 / 1091) + (17437 * 8329 - 8170 + 7352))\n28354 + 20142\n15902 * 25841\n(3142 + 26471 * ((16561 * 2520 - 29137 / 17985) * (27281 - 22216 * 7884 + 31868)))\n1597 * 31130\n25472 + 11190\n26002 - 22994\n25094 + 20957\n(5082 + 1004 * 21559 * 26500)\n8669 * 23279\n24421 * 22760\n27148 + 18813\n10340 * 28197\n27240 * 22353\n1456 * 5362\n31420 * 23199\n27437 + 26979\n8778 + 27003\n10640 + 30979\n(29367 + 11882 + 11439 - 1330)\n17752 + 12140\n17434 + 386\n19102 / 9653\n2493 + 13160\n22748 - 32487\n12293 / 234\n4711 - 26726\n1602 + 19409\n15107 + 5710\n5829 - 21134\n10620 * 25644\n22578 - 11378\n(22485 * 2515 - (10968 - 13293 * 22277 + 24883))\n12949 - 27767\n10806 * 23406\n1659 * 21120\n5331 * 10040\n24448 * 13764\n28282 * 25916\n2241 - 32226\n(((6968 + 15940 / (((13765 / 9672 + ((16947 + 30450 - 28028 / 27354) * (10498 / 6885 - (24026 * 5565 * 4123 + 21812)))) * (3260 - 26691 / 15465 * 11124)) - 4013 * 11114)) + 25081 + 19927) + 4386 - 30862)\n(16868 - 20278 + 13366 + 15430)\n25841 - 19678\n9444 - 7415\n29831 - 2660\n19299 + 4431\n16872 + 15432\n(31360 - 31902 / 3082 + 17928)\n19593 * 14598\n30479 - 9563\n((12570 + 23497 + 14688 * 30249) - 18610 + 31495)\n642 - 25321\n(96 + 17966 * 590 * 16090)\n17445 / 27901\n25286 + 940\n((30316 + 10466 * 16796 + 9652) - 13687 - 10526)\n(8983 - 27199 - (21236 + 20286 + (27474 - 2499 * ((7371 * 17443 + 12119 + 11741) + (27871 - 9300 - 24083 * 3369)))))\n14944 + 5184\n10528 + 32628\n23017 - 13801\n16694 * 31638\n12577 + 6352\n2252 * 165\n17861 - 6137\n19685 - 7900\n(11997 * 31240 * 26235 + 9317)\n13624 + 25295\n26381 + 28451\n30110 / 4519\n31687 - 2237\n((31557 * 14837 + 13089 * 24917) * (21322 + 30001 - 7907 / 29221))\n(25985 - 2256 / 2486 + 10464)\n16475 - 2869\n24312 + 435\n15462 - 20061\n12219 / 17569\n13486 + 19792\n24201 + 10261\n23769 + 7854\n(7452 - 23264 + 26418 + 19476)\n19219 - 11296\n1258 - 15901\n((10629 - 1420 / 31810 + 10658) * 2675 + 17546)\n(8133 * 14669 / ((25539 * 28050 + 9874 + 11074) - 7451 * 10808))\n32048 * 5458\n26611 * 724\n19638 - 10507\n13857 + 18963\n98 * 21352\n(16490 - 17769 * 9630 * 18725)\n21805 + 13706\n(420 * 12671 + 16298 / 30502)\n1525 * 9206\n(6476 - 29740 - 23110 * 22267)\n31376 - 28154\n18407 + 25853\n31099 + 11548\n5747 - 31882\n20416 + 15822\n17886 + 19281\n10699 * 18544\n23772 - 21256\n7414 + 20076\n((28420 * 14349 * 14744 - 26193) - 31380 * 17591)\n(19575 - 7849 + (8439 + 24017 * ((18956 + 23151 / 28501 + 23748) - 2359 - 6710)))\n(7415 + 27147 - (854 / 14340 * 2122 + 17248))\n(1409 - 19499 - 13724 + 6201)\n14721 - 31120\n1381 - 13747\n26949 + 22353\n26219 - 7584\n15724 * 3630\n6544 + 32198\n28644 - 9756\n(23484 * 14832 - 13711 * 3920)\n27651 + 301\n18212 * 24736\n(17309 - 20471 * 32545 * 13179)\n(949 / 17484 + 19980 * 7899)\n((31957 + 14130 * 32135 * 23221) - 25070 - 5016)\n17213 + 2574\n16945 - 29\n4089 * 2610\n32388 * 28128\n11996 * 29807\n(4163 * 16221 + 16544 - 8597)\n29602 * 6924\n6668 - 29684\n(19663 + 29125 - (5721 * 24926 + 26365 + 9020))\n24839 / 11469\n31777 + 10653\n(4119 + 10063 + 21868 - 21896)\n1475 + 24024\n26299 + 16790\n19250 - 25104\n((20674 / 8838 * ((18188 - 16765 - ((13202 - 26299 + 128 * 31091) * 1025 + 20954)) + 15058 + 8362)) / 26676 * 6458)\n(14348 + 787 - 28300 - 14278)\n9243 / 24331\n(9157 * 20781 * (10319 + 6075 + 7545 * 23419))\n4310 - 18223\n28716 * 28860\n27461 - 26583\n26678 - 5128\n24480 + 7483\n((15153 / 30186 - (230 + 4267 + 12788 / 7626)) - 5916 / 12608)\n28794 * 2226\n(31895 * 3860 * 19813 + 24939)\n2194 * 22752\n28699 + 7814\n1073 - 20442\n20712 + 27288\n(10434 * 11466 - 4299 + 2534)\n654 + 26467\n952 + 7333\n(10661 / 9115 / 3240 - 12138)\n((18342 - 30838 / 24434 - 14342) - 12962 * 16015)\n11493 * 29310\n32107 - 26410\n11494 * 26659\n14388 + 19128\n17800 - 2347\n30548 + 31103\n((20167 / 3712 / (2726 * 26399 - (19154 + 3679 * 24263 / 14023))) - 27390 * 9452)\n901 * 30668\n16475 - 13306\n10166 / 8163\n(6472 + 29264 * ((11529 - 8040 - 21639 / 15777) - ((12811 - 8051 - ((28478 + 28644 - 629 - 31012) - 31766 - 27936)) + (9396 * 20150 + ((26547 + 5296 - 8185 + 2114) + 14732 * 11835)))))\n30907 - 29818\n11509 * 28706\n17275 * 17072\n19150 - 31489\n30898 - 29081\n11052 + 6476\n(7359 / 14113 + (19338 + 1308 - 13518 * 8658))\n1691 - 7282\n31167 - 25520\n10885 * 27481\n3557 + 20315\n28159 * 2412\n19063 + 19240\n19343 + 983\n(1254 * 22621 + 312 + 1530)\n22430 + 3982\n11479 - 7556\n(32308 * 29967 * 29112 * 25121)\n5644 * 12216\n10171 * 22656\n6710 / 14833\n15012 + 27257\n29481 + 11835\n18961 + 16993\n15869 * 19015\n21761 + 14232\n(32155 - 27811 - 6628 - 17171)\n29419 * 15065\n22646 - 27997\n((15569 - 30981 + 19502 * 16452) - 13981 * 30475)\n(3820 * 9818 + 30528 / 6862)\n507 * 14714\n301 - 3125\n(9192 - 28077 / 5753 + 14883)\n9107 + 29286\n(29533 * 2520 * (15110 - 23291 - 5094 + 32339))\n11282 - 27401\n((20763 / 4603 + (470 + 7936 - 12832 / 20090)) / ((1746 + 10521 + 17643 - 28046) + 2415 * 6223))\n(11392 * 24347 * 7917 * 21862)\n23930 - 32466\n17528 * 30140\n20673 - 18883\n11840 - 10917\n19466 * 22793\n(12434 * 18026 - (14552 * 1526 - 25264 * 29338))\n8463 + 27441\n28789 + 29223\n6679 * 20734\n8046 - 21133\n8034 - 3961\n8241 + 10380\n(27003 - 15546 * 14869 * 12665)\n4681 + 19077\n28009 * 13461\n5127 - 5775\n3945 * 23354\n(30738 * 6835 * (31292 * 26573 + 30683 - 279))\n((6051 - 8985 + 3717 * 26986) * (((6362 - 17739 * 2187 / 29587) + 6187 * 23838) + 20995 + 27334))\n3005 + 13184\n29178 + 32624\n16063 - 1060\n4718 - 15654\n2186 / 12121\n24740 / 6668\n29354 * 6187\n19859 * 821\n12808 + 25984\n24952 * 4557\n(19272 * 5879 * 15374 + 6374)\n29481 - 145\n24589 - 2303\n((10568 * 4565 * 30356 * 27307) + 12305 / 3857)\n20226 * 24270\n(27919 - 7475 / 10427 / 8296)\n20728 + 3852\n19922 - 23200\n30748 / 20664\n(19030 * 9051 - 28176 - 16418)\n27638 + 17249\n1111 - 9451\n2598 * 17830\n4152 + 20579\n6369 + 29380\n21312 + 1368\n14086 + 22694\n(21920 - 21386 * (7250 + 31483 * 3430 * 26512))\n17767 * 21559\n16907 - 24152\n14044 / 18761\n6335 - 27377\n(2175 - 3378 - 1714 * 26433)\n1576 * 31208\n12362 - 27119\n18401 + 16921\n14645 + 22923\n22103 + 19645\n13784 * 7430\n7007 * 22359\n29789 * 27912\n12407 + 13578\n9286 + 22834\n13134 / 12786\n(7248 - 5246 - 792 * 20898)\n7760 - 30676\n21011 - 31664\n22943 + 10168\n1486 * 7951\n11643 / 11091\n21513 + 25562\n20273 * 16441\n4836 + 10998\n3582 * 7824\n10448 + 22982\n26827 - 19220\n18398 - 25041\n7316 * 29874\n27936 - 22616\n(1958 * 13819 + (9302 * 28509 - 13312 + 16228))\n27412 * 11614\n5597 + 959\n13150 - 23870\n1277 + 8291\n2303 + 25069\n(18680 - 24368 - (29730 + 6786 * (8570 * 17237 + 29333 + 18212)))\n5217 - 139\n13690 + 18317\n21799 - 11484\n(17014 / 3272 + (28235 + 11272 + 2708 * 20611))\n6438 - 4321\n303 / 17318\n32341 + 24362\n18387 + 24588\n1466 + 28814\n32126 + 924\n26371 - 16311\n19543 - 32675\n28826 + 24069\n(27480 * 4469 + (13062 / 21911 - ((9546 + 9954 - 30156 * 30128) * 27283 + 12576)))\n24631 + 949\n15365 - 31888\n31157 / 12192\n(17606 - 6602 + 4630 * 28043)\n(29114 * 11982 * 4503 - 23309)\n29264 + 31840\n18138 + 19246\n((19531 * 21247 + 22510 - 8983) - (((8433 + 2010 - 4294 / 3139) - 24712 - 13972) - 2606 * 28610))\n29441 * 24908\n13588 * 30551\n12753 * 24190\n8542 - 6603\n20566 - 13613\n17490 + 22391\n14284 + 11593\n25225 * 23271\n10840 - 21491\n25235 + 16363\n28858 / 6855\n8526 - 29102\n(886 + 14043 - 5786 * 13416)\n7570 / 23444\n((((27694 + 23542 - 22623 - 3309) - ((3666 + 28118 + (4265 * 1215 + 5367 + 18757)) * (29082 / 29997 / 23366 * 3018))) + 10149 + 20145) - 9124 / 10963)\n6800 - 6580\n26706 * 7063\n12975 - 12359\n10181 - 12571\n28124 - 19924\n((10114 - 10594 * 16828 + 20745) - 7307 / 3253)\n31097 * 32234\n29299 / 17317\n3896 - 24953\n31906 + 22053\n(28899 + 2591 / 32231 * 17344)\n(((19737 * 23614 * 1271 * 21775) * 6302 + 6938) * 18905 / 23407)\n((1722 - 11216 * 8434 + 913) + 9292 / 14170)\n20868 + 12104\n19806 * 17198\n27819 - 3796\n5458 / 3292\n24552 + 8935\n9678 * 26796\n(8853 - 3610 - 23469 - 22006)\n5834 * 24413\n17249 / 20877\n28835 - 523\n(14113 - 11227 - 12001 + 20303)\n((20364 - 8080 / 10742 * 31414) - 21222 + 4215)\n(15489 - 5506 + 11997 + 15861)\n20756 - 19345\n20269 * 10760\n(3423 * 26394 - 7175 - 28596)\n2020 + 1606\n1296 + 1812\n19718 * 13615\n21264 * 11034\n27228 * 15378\n9983 + 6091\n29759 + 15988\n14288 * 8170\n14039 * 12120\n2139 + 31887\n(8879 + 10340 - ((11488 - 11475 + (23661 * 30263 + (16541 - 14147 - 24599 * 9103))) * 31530 - 1808))\n((14692 - 6581 + 31987 * 26353) - 13808 + 22358)\n6692 - 24302\n9396 * 30493\n32595 - 31609\n47 + 29119\n27801 * 24146\n16929 * 13949\n7326 + 9971\n(4672 - 26250 - 28201 - 427)\n7649 * 14423\n27360 / 12996\n19389 - 16997\n18967 * 5906\n21166 * 1354\n(18722 * 27995 - (8981 * 21270 - 16939 - 2075))\n32140 / 22859\n(17248 * 7851 * (605 + 17912 / 18754 / 17467))\n(20124 + 16349 + (998 + 21602 * (10972 - 31704 / 233 - 26912)))\n10257 / 14727\n(10329 - 17388 - ((8198 - 21357 * 30612 - 22610) - 29711 * 2021))\n((28389 - 24909 - 24577 * 21535) * 25658 - 6109)\n29957 + 23549\n19395 - 21693\n(1675 * 26240 + 17775 * 1968)\n21821 - 17297\n5780 - 4865\n12893 - 80\n1869 - 12700\n13548 - 10173\n12770 + 23503\n(11760 + 10543 - 6858 - 14761)\n2089 - 17842\n((((28326 - 31955 * 21695 * 30875) + (27762 + 10836 - 18120 - 23509)) * 25190 * 10294) + 32304 - 2193)\n26767 * 32149\n9402 * 14637\n(12302 / 9161 / 15986 + 5565)\n(30630 * 14520 * 2064 - 27945)\n12821 + 12081\n22699 + 8588\n26444 * 20372\n31177 + 12871\n20690 - 23533\n2986 + 31508\n(20961 - 15701 + 21899 - 22175)\n19262 * 15253\n18880 + 6552\n23292 * 1204\n(30563 / 10787 + 22322 * 10255)\n7743 + 23951\n(3912 - 20497 * (4649 + 9725 + 32649 * 18284))\n10007 - 1950\n29560 + 9061\n25229 * 29227\n15199 * 15778\n13654 * 3837\n2661 * 4839\n17439 / 23557\n13645 * 32743\n18646 / 20653\n24336 - 31663\n26350 * 6734\n(24474 + 8962 * 23054 + 13274)\n31217 * 10752\n6864 + 14869\n1085 + 22310\n18853 + 7162\n8042 + 28759\n(25409 - 20081 - (25538 - 27339 * 11755 - 14087))\n(20281 - 4800 * 18405 * 12614)\n((18683 * 12110 - 15105 * 29185) - 17220 + 21594)\n17967 * 3044\n((6133 - 2275 + 15796 * 28985) * 2236 + 19154)\n31153 * 8918\n23653 * 8533\n26434 * 10882\n27963 + 8761\n((23715 - 27749 * 29352 + 26145) + ((32070 - 31852 + 15198 + 4217) + 18168 / 9888))\n22110 + 12056\n29585 * 23144\n(28690 - 2949 + 7141 + 1176)\n27137 - 20286\n10745 * 4381\n29107 * 12184\n7676 * 3572\n32372 * 13194\n6731 * 8271\n20105 / 1868\n16868 + 1213\n12808 - 16733\n29671 - 9366\n29675 * 23759\n21235 - 31090\n29156 - 12306\n22187 + 26334\n((26191 + 14759 + (5964 - 14987 * ((28682 - 9893 - (30882 * 15284 + 32475 - 509)) + 8836 - 20939))) + 26311 - 19775)\n(28590 * 22981 - 26455 / 13744)\n(6861 * 29581 / 22532 / 6574)\n22932 / 759\n28889 / 30275\n1821 - 26573\n(32651 * 6164 + 30218 + 24614)\n30752 - 6590\n28916 - 30340\n(9671 / 2473 / 25362 + 29606)\n23764 - 21677\n20556 - 8301\n19378 - 23373\n23289 - 22584\n21366 - 25097\n((11230 + 19833 - 17625 - 21889) - 22439 + 1704)\n20657 * 29783\n((((28797 + 6770 * (6862 + 12026 * 6887 / 29429)) * 18871 + 17901) + 31448 - 23776) * (32593 + 26704 / ((7659 * 8238 - 9079 - 25033) + (14776 * 7188 - 22459 * 208))))\n16781 + 32633\n31861 + 12634\n25176 - 8906\n(8154 - 2409 * (16302 + 32229 * 6440 + 24118))\n6145 / 230\n11809 * 22791\n1761 * 4491\n21660 + 1003\n(26418 * 1604 * (981 * 17775 / 30124 / 31855))\n13275 + 16789\n(17958 * 26820 * 4799 / 25298)\n((15632 - 13457 * 4298 + 10797) - 21637 + 3339)\n1574 + 19350\n20650 * 15698\n10933 + 16966\n7837 * 7024\n14371 + 11715\n(((22617 * 27223 * 3843 - 9384) + (5071 * 3478 * (5990 - 7455 * 18305 - 11122))) * 19315 / 7874)\n11047 * 12270\n164 * 31209\n10466 - 301\n(25284 * 27644 * 18899 + 25854)\n1369 * 9793\n4825 - 12117\n690 - 27448\n4451 * 5088\n2031 + 32106\n17668 - 24623\n12612 * 13785\n11851 * 31716\n24887 - 3386\n((25460 - 275 + 24120 - 3186) - 26689 + 5165)\n24506 - 5294\n30876 - 30178\n(728 * 27402 * 15146 + 10486)\n(15298 - 23416 * 11083 - 12210)\n17175 * 26511\n14524 - 15687\n(22046 * 31154 * (27460 - 3535 * 28425 + 976))\n(13044 * 4786 / 30111 - 13778)\n4246 + 32302\n1325 + 4858\n4890 + 31967\n14079 + 22021\n31654 + 32250\n15471 * 5617\n(13430 - 17775 / 17663 * 31346)\n((27831 + 18959 + 17985 + 26342) + 2151 * 13448)\n(7916 * 12368 * 5701 / 26768)\n12401 - 31231\n18917 * 11883\n((9231 * 1149 + 592 - 707) + 30492 + 21119)\n19881 + 9663\n24844 - 9295\n(32711 * 31695 * (((27724 * 7027 + 25295 - 6887) * 15071 - 7043) * 5109 * 27485))\n(9461 + 12089 + 11218 + 16107)\n15149 * 1570\n5094 + 13597\n(9108 + 11141 - (709 + 10051 * 19145 + 28298))\n26554 * 17657\n(17632 - 7406 * 12524 - 9270)\n24399 * 26720\n32223 - 2812\n13837 - 2346\n7154 - 12392\n2634 + 9348\n18203 * 6941\n7663 - 29180\n10716 + 21002\n(28205 * 31609 * 26537 + 28491)\n2278 + 23919\n4689 * 24935\n25086 + 25352\n((((10485 + 6180 / (20625 + 3545 * ((24710 / 7831 + 13900 / 16576) + 11915 - 17187))) - 8484 * 26485) + 32344 * 28075) * 30471 + 10679)\n(29348 + 12531 - 30476 * 4426)\n32656 * 7487\n28720 * 8402\n7365 + 20082\n(10088 - 11569 + 15221 / 8515)\n16542 * 13629\n25099 + 20136\n27530 / 12816\n12858 / 28787\n(6272 * 4510 - 27741 * 14207)\n(29669 + 26180 * 1368 / 11812)\n27596 - 25692\n24564 + 8612\n12424 + 7564\n(31009 - 19682 + 13611 * 17109)\n22769 + 3504\n6444 * 21985\n((28172 * 15562 + 29252 + 1251) * 28134 + 19630)\n(1447 - 15070 * 16790 - 2052)\n((585 + 3019 + 27050 * 554) - 23141 - 12586)\n20316 / 14365\n(2964 * 5775 - 6010 * 23168)\n(21263 - 4014 + 26322 + 32373)\n772 * 17277\n4409 + 15862\n18709 * 2958\n7122 * 30344\n20571 / 21297\n9456 + 3828\n(29966 - 27958 * 7875 * 23362)\n19584 * 10156\n(7044 * 19774 - 28082 - 17822)\n1871 * 27756\n24768 - 29565\n5217 * 12578\n(4825 - 27975 - 8368 * 25418)\n26145 - 32481\n5259 - 31764\n5694 * 16076\n30831 + 27138\n14145 + 5557\n24074 * 31126\n31464 * 30560\n18731 * 21477\n23081 * 27037\n8939 + 1705\n((13558 + 26473 - (10519 - 18168 - (4955 - 8331 * (12649 - 15377 / 5556 + 22403)))) * ((31645 - 24697 + 14729 - 14353) - 18639 - 18126))\n(1087 * 8481 * (17546 + 20275 + 20045 + 31142))\n2180 * 30565\n13558 - 23151\n4389 - 24102\n23035 * 7845\n((4459 * 3955 + 17777 * 18717) + (20721 - 198 - 15804 * 6230))\n2682 * 24136\n30867 + 10283\n((22788 + 9600 * 6565 / 24859) - (28898 * 5913 + 7075 * 4175))\n16940 + 7653\n13261 / 16553\n9962 * 32100\n((4848 * 19954 * 21000 * 26124) + 15819 - 24401)\n7027 / 21821\n11409 + 13256\n(11458 - 20906 / 3673 * 9387)\n2659 + 30780\n9279 - 27865\n(27052 - 9321 * (22319 * 12415 + 14915 * 26512))\n(24176 - 2299 * 29339 * 23041)\n17265 * 10196\n(12386 + 3797 * 1751 * 27853)\n((31603 / 1393 * 2939 - 5396) * 20296 / 27434)\n21436 + 19004\n14426 + 2007\n8181 + 5495\n20144 + 23122\n26171 - 31047\n28 * 18172\n((20565 - 11186 * 1987 + 23000) + 4760 + 25326)\n1353 - 9940\n(2102 - 12068 * (20187 - 11536 - (9382 / 13229 * 21309 * 12868)))\n(26272 * 24610 * 4702 * 16967)\n20457 / 27376\n(26833 + 32461 * 13453 / 26435)\n25827 + 16585\n(24697 - 12060 - 25944 * 24516)\n(10581 * 21344 + (30327 * 22220 * 31276 * 20806))\n(21000 * 20529 + 1230 + 26084)\n32247 + 15155\n25848 * 29205\n((11780 - 32145 * 7491 * 6543) - 15503 - 27598)\n(8685 * 12332 + (26383 - 7784 + 32468 + 26841))\n10253 - 16076\n6956 / 31885\n27537 - 22194\n5271 * 8906\n28967 + 13275\n29111 - 20853\n(27081 - 21050 - (11417 + 2605 + 15443 * 13542))\n12771 + 30973\n15518 / 24409\n2102 + 19244\n16367 - 6350\n3359 * 30826\n26622 + 28466\n(9283 * 12356 + (14838 / 25331 + 27423 * 30358))\n20490 - 22109\n29504 + 1853\n((22513 - 4108 * 20743 * 8537) + 18745 + 28897)\n(24581 + 15578 + 18914 + 16522)\n(17487 - 10371 - 12630 - 21103)\n17333 * 10019\n(((1409 + 5588 + 27574 * 24479) * 1575 * 22000) * 16951 - 10454)\n(27962 * 27261 * 17385 + 1165)\n((31434 * 29866 + 26009 - 31499) * 17790 + 4154)\n1021 + 6037\n19477 + 13695\n17260 + 26809\n30059 * 1927\n20555 + 13997\n27617 * 26423\n20263 + 31842\n21515 + 4788\n12422 + 11348\n2874 * 11949\n(7453 * 19491 / 490 + 30134)\n4523 - 14327\n25329 + 8888\n19200 * 5921\n1153 - 11841\n12985 * 11526\n17459 * 5382\n(27323 + 19072 - 27263 + 28419)\n16125 - 14663\n22702 - 7723\n30993 * 21405\n17077 * 29722\n18169 - 8404\n7421 + 19695\n(14874 + 30293 * 18843 - 19895)\n7750 - 19089\n16083 - 14265\n24536 / 577\n9395 / 960\n3897 - 11008\n(7267 + 18179 - 5600 * 24174)\n3825 - 11850\n4461 + 23227\n23818 + 11239\n((21687 * 14939 - ((28565 - 14657 - (25808 + 28872 + 7429 * 21855)) - 26436 - 29873)) + 4545 - 28058)\n(10753 + 3342 * 16959 + 2299)\n10856 * 21092\n29762 + 12783\n23189 * 15866\n(17098 * 20288 + (16435 * 31323 + 19744 + 5364))\n17238 - 30910\n21801 - 107\n(16082 - 25543 * 31318 - 13231)\n26931 - 13408\n18243 * 20678\n15528 - 23619\n((14887 - 13069 + (16198 + 31685 * 25365 - 4221)) - 21877 * 25028)\n24186 - 6409\n31929 + 22241\n6604 * 31829\n26340 * 112\n15589 - 31443\n3433 * 10654\n14629 - 31469\n18083 + 5126\n25059 + 976\n17649 - 25462\n3282 * 12566\n11819 * 30291\n(18103 * 26119 - ((59 - 13549 - 17191 * 24171) / (17202 * 2979 - 31977 - 3155)))\n24057 - 29853\n7514 - 728\n((16533 + 26259 - (16758 / 5869 - 20940 + 3565)) - (16909 + 31628 + 29869 + 13261))\n4947 - 11016\n10838 + 24939\n3348 - 8853\n5179 * 22363\n(2488 - 26586 + 801 * 19035)\n3164 - 29154\n27259 + 17300\n29686 - 17799\n10898 + 18178\n(13651 + 7462 + 22145 * 32173)\n24275 / 10446\n6736 + 5493\n17869 + 8470\n(25837 + 1822 - (((22359 - 5988 - 14227 - 14739) / 798 * 14201) - (32480 + 17234 + ((25441 * 18271 - (12724 + 5157 * 17287 - 5068)) + 20784 - 32516))))\n13728 / 25100\n17073 - 18192\n7174 - 12665\n30780 - 31272\n((11773 * 20 - 16217 + 1124) - 14333 + 14051)\n1085 / 28194\n14492 + 16841\n(32277 + 30776 * 27413 / 23832)\n1158 - 14208\n22512 - 142\n24420 * 9806\n20004 - 30828\n15243 + 300\n3745 * 26915\n20837 - 12967\n30672 + 6033\n11480 - 20425\n17051 - 2189\n7836 - 24595\n17367 / 19177\n25940 + 9950\n19517 + 26583\n7365 - 1359\n5719 * 24704\n25954 - 5064\n9691 + 22036\n11427 / 11663\n(25859 + 15932 + ((26542 + 904 + 1762 - 23755) - 30351 * 30433))\n(48 * 31093 - 17486 * 763)\n(22438 - 29392 * 14805 - 9546)\n14850 - 22969\n25806 - 31903\n(3822 - 21913 + 1188 - 7852)\n15999 - 19826\n30998 + 15146\n18379 - 31982\n26323 - 29407\n11977 + 26389\n23507 * 17263\n28147 + 6456\n1889 - 6282\n31924 - 17801\n(1479 + 29008 - 16172 - 30922)\n18060 - 26296\n11249 - 6176\n30577 - 32622\n(5516 + 13167 - 5971 - 21934)\n21077 + 15695\n26032 - 27459\n25634 + 28334\n(6812 * 4433 - 25600 * 3960)\n24664 * 23321\n21050 + 30769\n(23468 + 22129 * 22621 * 17779)\n(8967 * 27673 - 21311 * 30778)\n14734 - 25320\n10942 + 16201\n4334 + 756\n(12585 + 2106 * (1186 * 7727 - 30373 - 32714))\n9781 - 31152\n4594 * 5946\n7469 - 17299\n((((18330 - 22208 - 8444 + 1367) * 30370 + 25375) - 8153 * 17833) * (21643 - 25614 * 25103 / 30350))\n31269 + 13233\n30351 * 22747\n14430 + 9252\n11938 - 27612\n29789 - 26565\n(31164 - 23309 + 11441 - 3745)\n9962 + 24341\n8250 - 32346\n(31464 + 3533 - (21747 - 18912 * (26310 - 14729 + 30406 + 20546)))\n5799 - 3276\n27506 * 27502\n22865 * 16579\n9279 + 2086\n26070 + 13668\n(644 - 4169 + 26753 - 29398)\n12889 - 23126\n((8828 * 29595 - 6005 + 15188) - 14952 + 16584)\n20573 * 31166\n31941 - 31132\n28735 - 25756\n25770 * 13511\n31605 - 1138\n24255 - 14684\n28613 * 30260\n21413 / 32051\n26599 - 1053\n8843 - 26049\n12030 - 27525\n((13265 / 13756 - ((4018 * 679 - 27597 - 29818) - 12073 * 7139)) - 29240 - 29540)\n(29953 - 11664 - (7663 / 22114 + 13584 + 18017))\n31869 / 15478\n29199 + 15597\n((26100 + 30209 - 4816 - 10824) + (2860 - 15628 * 16316 + 26889))\n552 + 14418\n(31592 * 29423 - ((6529 - 26846 * (8394 - 16450 - 19590 / 30504)) - 31542 * 16201))\n13883 + 23634\n(2707 + 952 / (((14278 - 26477 / (29341 + 13220 + (6183 + 6888 / (5560 - 2242 + 19352 * 6609)))) + 2183 * 20334) + 15913 * 14708))\n1388 / 8508\n12491 - 20069\n(20859 - 19891 - 19286 - 12591)\n22919 + 15942\n22167 * 32436\n8185 / 2068\n21609 * 3848\n(11547 * 11353 * (8264 * 806 - 30151 - 19592))\n6377 + 5846\n(9127 - 14182 + (20747 * 28257 / 19903 / 1255))\n27763 * 6590\n5189 - 26314\n10300 + 497\n27014 - 11059\n8704 / 10742\n15046 - 27711\n(22584 + 346 - 26941 - 18374)\n((14390 - 16057 - 14955 + 3848) * 17648 - 24327)\n879 + 8428\n(19466 / 2031 * 27381 + 32042)\n29786 * 16564\n4793 - 12885\n27007 * 27881\n15157 - 31793\n5800 - 8656\n2795 + 15601\n18386 - 14202\n30513 - 17330\n1454 * 4188\n21405 * 24523\n22182 + 10789\n9432 * 28537\n12278 + 30242\n9504 - 29630\n25039 * 25544\n(14233 * 28284 - 6793 * 6548)\n29728 - 14094\n1775 - 21653\n(9965 + 388 + 15664 * 29131)\n25243 / 21695\n8560 + 9961\n19713 * 13637\n7937 * 28674\n15041 - 1244\n20617 + 11876\n(25909 + 21449 - 2077 - 20862)\n(12666 - 18557 * 24987 - 25522)\n21135 - 15856\n9108 - 30659\n18898 - 10278\n11105 + 27960\n(16066 / 31896 - 5285 - 8636)\n26435 - 7906\n(13358 + 10737 * 265 * 22810)\n23019 + 23008\n(10464 + 24931 * 3638 + 29669)\n14781 + 1007\n(17241 - 31535 - 23476 - 12024)\n18542 + 5062\n(18749 - 22940 - (860 * 20825 + (27154 / 4314 * 17087 * 28472)))\n((9798 * 9613 + 26568 / 32100) * 20149 + 18523)\n15498 - 522\n22797 + 23287\n2526 * 11344\n(10583 - 9072 * 7377 * 6782)\n19069 + 28561\n2458 - 6416\n15612 * 16436\n(32449 - 21310 / 23024 * 23054)\n22959 / 2442\n537 / 21364\n(24984 / 19011 - 27482 + 26435)\n8853 - 765\n24473 - 12460\n5676 * 5424\n15100 * 11164\n24637 - 18527\n25216 + 8315\n180 + 27385\n5086 * 24417\n14788 * 17815\n(22715 * 14515 / 16178 + 30855)\n(19679 - 1266 + 32288 * 17120)\n22052 - 7846\n25755 - 26246\n24802 + 30999\n2303 - 8157\n13586 * 16051\n28381 - 17686\n24608 - 31160\n24541 + 20407\n14257 * 9085\n(29606 * 6463 * 24200 + 20857)\n17459 + 18787\n(24282 + 805 * 22411 / 17434)\n((9735 + 26162 / (31765 - 30037 - 22002 * 2125)) - (13593 + 10587 / 3559 - 17661))\n(2648 - 23849 + (6799 - 4897 * ((17041 - 10996 + ((28802 - 707 + 6932 + 18854) * 3487 * 10660)) + 22325 / 26799)))\n18780 + 2591\n31695 - 23278\n3610 * 26698\n29292 * 10019\n13815 * 29073\n8697 * 4932\n5947 + 5807\n26321 / 9710\n6548 * 180\n(16521 - 20407 + 15545 * 4351)\n5466 + 10682\n629 - 31038\n21571 / 25240\n21223 + 24091\n18707 + 7028\n(7080 * 25565 - 11301 + 15548)\n19728 - 13220\n16887 * 791\n6348 / 1870\n10095 * 729\n(469 + 23795 * 20652 - 361)\n12418 + 28803\n20281 + 28523\n(15065 - 11418 - 22132 * 27369)\n5843 * 17575\n15255 - 21205\n22461 + 5927\n22770 - 30299\n8383 * 32533\n9671 + 2875\n28675 - 24655\n4568 - 25317\n31198 - 17678\n2721 * 23470\n14396 + 27435\n26572 + 4568\n25760 / 7095\n2060 - 16918\n11023 + 12681\n5616 * 24501\n(21671 + 14882 - 7463 * 12836)\n(9412 - 16318 + 20035 - 26122)\n((22988 * 22780 - 7592 - 29739) - 2521 * 4100)\n9277 - 17575\n4567 + 10819\n8152 * 29914\n31733 * 8755\n(((24869 - 21637 + 12223 - 12581) * 22002 - 32294) * 22450 * 3502)\n2652 - 17636\n24394 * 31361\n(30840 * 28041 / (448 * 10751 + 26612 + 21801))\n19830 + 17454\n3258 + 11506\n3207 - 21727\n19298 + 22600\n15983 * 21844\n31496 * 12686\n22501 * 26213\n29849 + 4030\n3015 * 2663\n(30771 * 11442 - ((32027 * 11927 - 16522 / 27166) + 18837 * 31859))\n775 / 30740\n26697 - 25381\n14105 + 2302\n(((26984 - 21182 - 14434 * 30988) - 28842 - 21604) - (4593 * 27172 - 28606 + 1907))\n(25743 + 14786 + 9337 - 4641)\n10081 * 28939\n28186 * 31105\n25221 - 18156\n30337 * 30436\n(13821 + 5249 + (16315 - 32144 - 14205 * 23497))\n8498 * 7378\n23488 - 558\n(11299 - 1224 - 13016 + 966)\n1510 - 15115\n20944 * 13256\n20241 / 16261\n7842 * 27834\n(29783 + 21903 / 4831 - 68)\n20497 * 2279\n31106 + 2683\n24262 - 11289\n26190 * 2379\n21386 * 4140\n22688 - 21553\n2043 / 22500\n26955 * 28704\n7165 - 13782\n19736 + 26016\n30521 / 20088\n(28953 + 4526 - 13704 - 25828)\n30600 * 19403\n3365 * 24670\n30241 + 29155\n2379 + 11829\n30403 - 28478\n8291 + 31961\n31234 - 1121\n21625 - 16257\n3341 * 9552\n2259 * 22426\n26778 / 27809\n11971 + 3431\n14058 * 2102\n12586 - 15507\n23289 * 16967\n812 * 27146\n20158 / 28108\n135 - 5955\n609 / 14500\n23960 - 25963\n(18754 - 13819 * (14238 - 32699 - 29701 / 27798))\n((30950 * 25111 * 21477 - 26124) - 30244 * 32688)\n31157 - 15842\n(2088 * 32751 - 6801 + 4291)\n2994 * 10617\n(4271 + 7548 * (11644 + 13557 + 1520 + 5755))\n(20256 + 19026 - 11932 * 31137)\n11281 - 6829\n(1288 - 32676 + (((682 + 13797 / (((9755 * 3977 + 16874 + 14547) * 18301 * 24533) * (12484 * 4386 + 16553 + 10558))) / 8389 * 25889) - 13545 / 737))\n31199 - 29270\n18841 + 18019\n(7289 + 32446 + 14719 + 10215)\n5380 - 23595\n((((13023 - 12846 - 3310 * 32339) + 1800 + 9448) * 11083 / 31166) + (27501 - 4049 + 29607 / 6045))\n14103 - 28866\n(20837 + 22026 * 13226 - 10545)\n31575 - 5667\n12809 + 25222\n15007 - 4546\n31272 - 14796\n4328 * 27282\n28844 - 22403\n(31891 * 24582 - 3279 + 24521)\n13099 + 25536\n(22542 * 28516 + 8386 - 9309)\n((4216 + 26925 * 23386 - 6296) + (21106 * 18495 + 16764 * 32726))\n878 + 8853\n14769 * 28587\n30729 * 13517\n22340 - 20755\n((13971 / 28705 * (1513 / 20904 - 5270 + 903)) + 238 / 30148)\n((27500 + 22644 * 27871 * 408) / 27573 - 32540)\n28950 + 7918\n8707 + 17491\n7902 - 23168\n32576 - 7558\n16646 * 12782\n15287 + 16633\n29185 - 7760\n7631 * 15633\n12546 / 324\n6203 * 20260\n26366 + 8511\n20532 - 21871\n13566 * 18832\n30587 * 24425\n32754 * 11321\n(11164 * 19662 - 30669 / 14521)\n30611 + 27720\n22760 + 10955\n18704 - 24948\n15293 * 27587\n30033 * 31693\n27619 * 25028\n8713 - 24092\n30897 - 19958\n25569 * 16748\n(7707 * 21945 / 9829 + 23657)\n19918 + 11058\n4232 + 10830\n(8014 - 17668 + 20722 + 17589)\n(13807 + 12823 * (18130 + 30401 / 4910 / 24162))\n29504 - 8071\n(26433 + 22607 - 25514 + 22710)\n5613 * 17446\n22952 - 18033\n(6444 * 31785 - (27226 * 3797 + 7213 + 17198))\n12 * 15800\n6552 - 12021\n4239 - 22295\n(3820 * 10623 / (32412 * 12492 + 30074 * 489))\n((5490 + 12911 * 1969 + 31840) + 10746 * 27144)\n14401 + 20743\n18008 / 835\n25836 * 25090\n22873 * 989\n((17752 + 24276 * 26764 + 5463) + (23023 * 27233 + 29154 * 24683))\n(20463 - 20447 * (15198 * 1631 - (((23301 * 13257 - (17497 * 9774 + 8440 + 1118)) + ((20572 + 3626 - (5735 - 11797 + (31765 + 20365 * 30911 - 12636))) + 22898 * 25273)) - 30714 + 32319)))\n583 - 12748\n(9136 / 20879 - 17002 + 18015)\n30392 - 10835\n28254 * 25024\n(25616 - 23880 + 12563 * 31148)\n17597 * 7632\n31787 * 24780\n23748 * 24989\n13428 * 18018\n(8364 - 8700 / 6622 / 14668)\n(23420 * 4384 * 5561 - 27418)\n12905 * 776\n14410 - 2676\n437 - 12409\n21335 - 24353\n(27675 - 16769 * 3207 / 19063)\n29476 - 13989\n7553 - 12336\n(5906 + 14440 + (29286 + 17204 + 10943 - 9667))\n25178 * 6736\n4774 / 4295\n(17470 - 10592 - 25828 + 27695)\n(((16897 * 8820 * 17813 - 13434) + ((4057 + 4165 * (9704 + 11072 * 8644 - 7768)) - 27334 + 14691)) / 27575 * 13872)\n14195 * 20162\n15327 * 6379\n10636 * 27163\n2068 + 6946\n32235 - 9076\n30536 - 29433\n(20704 * 17699 - 28337 - 4848)\n19650 + 13221\n26327 - 16121\n11113 * 11362\n5629 * 28948\n17077 / 11163\n12916 - 13052\n10353 + 25362\n7811 - 5746\n10148 + 30879\n4519 * 21367\n17793 * 9326\n9078 / 26518\n(15554 + 15243 + 4324 - 19991)\n11562 * 9070\n(14670 - 23725 - (29199 + 24799 + (3609 * 29558 - 8864 * 6291)))\n(20002 * 24914 - 13146 - 26143)\n12427 * 26338\n30506 / 25415\n(7413 - 13543 - 20353 - 13514)\n20385 * 20300\n16529 + 17787\n16779 + 32512\n(21948 * 5650 + 16218 - 25161)\n9993 + 22989\n2508 - 17297\n2591 / 14348\n(17331 + 15281 * (7791 - 5450 + 20217 + 20218))\n29241 / 6514\n14424 * 10457\n30362 + 27486\n19623 / 20611\n17782 - 31698\n32160 * 10909\n7011 - 21892\n27581 + 404\n30803 * 6103\n(18449 + 17181 - 14206 - 17746)\n11760 + 3196\n(13076 / 30022 / ((20698 - 6997 * 24223 * 5302) + ((3485 * 4467 - 31955 - 1987) + (24229 + 21959 - ((4038 * 9830 * 2590 + 23127) * 18254 - 11121)))))\n31040 + 4944\n28309 - 3278\n10718 * 13150\n24706 - 32693\n7216 * 11566\n10831 + 12934\n17202 * 24522\n((26530 + 31192 + (((25573 + 5644 * 31403 + 17557) * (30846 - 29199 - 13337 + 19456)) * 32533 - 29897)) + 11195 - 11110)\n21816 / 22217\n24651 - 10109\n((18438 - 20362 * 9216 - 11874) * 8560 + 1701)\n15742 + 13178\n15069 * 1087\n5799 - 23424\n32433 * 5000\n(6930 - 12368 * 15382 + 24600)\n(29696 + 17870 + 12671 * 3170)\n441 + 27578\n6221 + 13336\n22012 + 19009\n32577 + 31562\n8105 * 18525\n32356 - 17830\n((14930 + 6738 * 17839 + 15565) + 26752 * 25478)\n18350 * 1169\n(25952 - 13628 + (26728 / 39 - 8446 * 283))\n(28365 - 15683 - (14590 * 26293 + 30102 + 21006))\n10163 - 12141\n12519 + 24470\n27506 * 30502\n6116 * 25716\n3324 / 32360\n20332 * 29301\n(30385 - 32472 + 18644 + 25265)\n32179 - 18583\n14258 * 16786\n30546 + 2401\n(116 * 1901 - 10520 + 15618)\n19281 + 23366\n9331 - 32291\n31478 + 1822\n20336 + 6136\n29612 + 27961\n6979 * 20550\n(14359 - 6205 + (24018 - 16705 - 3564 * 12835))\n6618 * 26313\n17331 * 21650\n(15432 + 5320 - 29652 * 24376)\n(16516 * 6431 * ((17141 + 4248 * 29117 * 32511) + (14407 - 30249 - 20612 + 11326)))\n(5097 * 4055 + 18866 * 7346)\n30146 + 18954\n10352 - 1668\n22013 / 26819\n19607 - 24085\n(16781 - 21496 * 11694 + 9614)\n18213 + 14284\n20245 + 23058\n8145 - 28054\n13881 * 13372\n23675 + 20445\n((((22974 * 555 + 30174 * 21536) * ((21198 - 858 + 555 * 21395) * (29890 - 14994 * 5878 + 7012))) - 25467 - 25821) + 2914 + 29862)\n((2666 * 8536 - 6478 / 17974) - 32511 + 3811)\n14332 + 29441\n(11450 * 4942 - 31558 * 24500)\n(28576 + 12133 + (19203 * 13267 * 11535 * 4333))\n(10805 + 5507 - 28213 + 18390)\n16520 * 30575\n28521 - 20764\n12263 * 19331\n(28188 + 18837 - 30136 + 23951)\n(5020 - 28220 - 11153 * 6966)\n24959 - 9681\n22658 + 15916\n28618 * 17831\n18471 + 5211\n2176 + 4687\n22487 + 6147\n(6630 * 27617 - (11885 - 1745 + 19864 - 5332))\n15737 + 14339\n21705 * 29569\n10254 - 16263\n10791 * 29181\n6605 * 11539\n29607 - 2554\n20523 / 26006\n(5892 - 4658 - 5897 - 4316)\n(31580 + 32425 * 14331 - 1041)\n(4136 * 5957 + 6270 - 1809)\n3164 * 16597\n25211 + 14104\n24756 * 21808\n12604 - 21528\n517 / 21787\n16762 + 5572\n23013 + 7275\n(6087 * 8463 * (31838 * 31434 + 15711 / 31254))\n((16776 + 1207 + 17876 - 29552) * (((27540 - 30415 * 28780 + 12219) * 32300 - 20094) * (23478 + 13141 - 25140 * 31615)))\n3635 * 23378\n(32071 - 25097 + (12736 + 13148 - 16802 * 22776))\n14702 - 10118\n27642 - 17817\n(9124 - 16891 * 15140 + 1865)\n28251 * 7723\n11964 - 29553\n8820 * 19152\n31660 - 18255\n((15095 * 22390 + 16801 - 7329) - 8495 + 1193)\n4062 / 13705\n20333 - 5250\n(16613 + 8296 - 714 / 15888)\n29935 * 21720\n((16421 - 28021 - 25193 - 19653) - 28382 * 17940)\n25529 * 15395\n(18091 - 20139 - 4821 - 21687)\n6613 + 15403\n2233 + 22095\n((((1167 - 5081 - (16735 * 31684 * (26514 - 18891 / 14536 + 13715))) * 1795 - 8795) + (6758 * 14572 + 17009 * 8522)) - 23392 - 25770)\n10146 + 521\n2073 / 29022\n(((6559 / 21260 + 18824 * 12123) * 3635 - 10006) + (29207 - 10185 - 19096 + 21194))\n3802 * 12972\n29527 - 17441\n16882 / 5601\n16375 * 8253\n12745 / 25384\n9346 * 32418\n5352 + 6322\n25569 * 28067\n((5759 / 15082 + 27130 * 11545) * 14387 + 26266)\n(3498 * 25115 - 27218 + 17626)\n27839 - 30703\n2704 * 32483\n3683 / 27408\n8463 * 4270\n3903 * 2098\n(1942 - 20022 + 24893 / 31150)\n477 * 5648\n16010 - 9404\n28376 * 13414\n26074 / 23530\n(20380 * 13907 - ((13912 * 11690 + 26456 - 25159) * 9300 + 9535))\n684 / 30699\n(27264 + 25342 - (18892 + 17671 + (3629 - 24476 * 18330 + 19819)))\n9118 + 14970\n4424 * 22086\n20741 - 8544\n3130 * 17231\n20111 - 5349\n(12928 - 3600 + 31938 + 7788)\n22582 + 14319\n(8588 * 18540 * 28757 * 8984)\n16100 * 1289\n13669 * 11091\n((26178 * 1125 + 1006 * 32533) / 29458 - 28767)\n12619 * 14195\n(28874 + 23467 + 32572 - 19435)\n2892 * 18684\n25303 * 2212\n(18995 * 12472 / 542 + 9670)\n12359 + 25417\n15246 * 22997\n29682 * 12629\n1303 + 4072\n11870 - 5284\n28237 * 13786\n22500 + 27276\n(18872 / 31647 - 19787 - 30593)\n2306 + 779\n8463 + 7997\n12353 * 21876\n(18046 + 3499 * 2529 + 13674)\n(27010 * 16487 - ((30924 + 11853 - (27585 * 10473 - 30976 * 1033)) + 25006 - 7182))\n1946 - 4422\n2396 + 3512\n71 - 21188\n18003 - 18720\n7305 + 11633\n13663 + 25966\n(10469 * 28015 + 1786 - 7702)\n10907 + 2452\n(((20432 + 4808 - (21111 + 8350 - 17528 + 4040)) / 6526 - 17483) - 18413 * 8256)\n(22717 - 19510 - 30997 + 23883)\n(144 - 15444 * 29355 - 19417)\n10143 + 21473\n((5494 + 17800 * 19479 - 2820) - 1109 + 7069)\n28942 - 21417\n9579 * 1807\n4719 - 1449\n1685 + 15326\n10960 * 25087\n31314 * 13519\n7366 - 28858\n(30092 / 15607 - (25865 + 21105 - 524 * 28188))\n17198 * 11841\n(27351 + 11843 - (4861 + 27662 + 20937 * 24739))\n4497 * 22618\n((495 - 7738 * 25872 - 11809) * 29307 - 27173)\n14440 + 22880\n27875 - 932\n13177 - 14780\n13666 + 650\n11267 - 6931\n(19804 + 23609 / 20922 - 4060)\n(((32616 * 9711 * 28237 + 21402) - 26688 - 28643) * 11525 - 17511)\n26626 - 8666\n6775 + 22561\n21427 * 9143\n12788 / 3813\n25744 + 24527\n21143 - 4179\n1612 + 17826\n15635 - 22565\n9731 / 31353\n16634 * 32264\n24831 + 9337\n32013 * 29704\n21126 - 18931\n390 + 3717\n1568 - 14635\n29992 * 911\n18070 + 25446\n3164 * 20123\n24620 * 3322\n17746 * 26431\n4140 * 6500\n18406 + 12681\n11191 + 5992\n4551 * 24328\n26896 * 10741\n7848 + 28082\n14993 + 29955\n(18492 - 28407 + (14240 * 13830 * (22475 - 415 - 25492 - 32173)))\n19188 * 29307\n5948 + 29740\n26490 - 8505\n13620 * 2172\n1607 + 27588\n(6245 + 21526 / 25783 * 11317)\n20550 - 11836\n11963 * 17043\n1103 + 32377\n7080 / 4295\n10739 - 17398\n27216 + 25731\n(17379 - 8209 / (23865 - 3167 * 17105 - 211))\n25390 - 4710\n(8424 + 15975 * 321 - 11334)\n19786 + 3399\n2180 * 9915\n11108 - 15598\n(18965 + 8225 - 21991 + 30065)\n32230 - 8350\n26288 * 9427\n27076 * 29642\n19340 + 11114\n5274 - 23874\n17927 * 12907\n(21060 - 7066 - 9750 - 23664)\n(6657 + 9530 + 32238 * 18339)\n31262 + 24986\n32423 - 2563\n748 - 18717\n16302 * 10019\n12278 - 26873\n(13421 + 16844 + 11806 + 15102)\n205 - 22922\n6225 / 4179\n5423 + 13589\n492 / 9463\n12929 / 10372\n(18425 + 10892 * 10020 * 29514)\n21735 - 2599\n28511 - 18120\n17766 - 28763\n(12792 + 28620 - 19641 * 15381)\n9267 + 17628\n22250 * 16761\n(9543 * 8901 + 21592 - 28635)\n16408 + 9497\n(29220 + 10530 - 21513 + 30211)\n31232 + 15540\n22043 + 9085\n11170 - 8062\n11035 * 21293\n17547 * 5347\n9996 * 13676\n(30322 + 16479 - 26915 * 16772)\n(7139 * 23908 - 29023 + 14790)\n25937 + 13954\n28902 * 23564\n13822 / 27396\n11836 - 206\n27763 * 21095\n(2406 - 18917 - (16282 - 31205 + 23749 - 31002))\n12291 + 30696\n32199 - 28711\n(4822 * 27927 * 13223 + 9037)\n1949 + 3494\n23589 - 4907\n28335 - 1111\n1870 - 31664\n5269 * 28792\n1860 * 20045\n11207 * 12497\n18178 + 548\n(12903 + 25385 * 27768 + 13564)\n(25354 - 12393 * 18133 * 28250)\n12798 / 20436\n32623 - 23890\n(14114 + 23852 + 2562 - 6642)\n17076 + 808\n27563 - 25337\n21038 * 30804\n24530 + 4146\n638 * 6720\n28891 + 21301\n17194 * 4388\n24746 - 16266\n23059 - 12464\n(3279 + 6097 * 19152 - 18780)\n29693 - 16416\n((29279 + 16963 * ((11921 * 15595 + 13829 * 21380) - 30690 + 14059)) + 20796 + 25338)\n31441 + 23969\n11296 / 18857\n26540 - 11450\n1130 * 11238\n15411 * 3349\n(32142 - 19454 / 24090 * 21243)\n14453 * 26733\n23978 - 22996\n26578 * 23891\n21991 - 13420\n6530 / 20570\n3620 + 1859\n(11443 + 28510 + (17142 + 12227 * 27298 - 18184))\n((15877 - 16113 - 24167 / 32767) - ((29742 - 7709 - 19549 * 10279) - 11913 * 728))\n8155 - 13879\n12708 - 14959\n32757 - 24698\n598 - 9143\n(19297 - 31295 * 17515 - 30072)\n9206 * 19686\n20087 - 30309\n5954 * 5196\n30717 + 5733\n28932 * 21922\n23491 * 15740\n23167 - 19226\n15854 / 5319\n24814 - 959\n(24708 * 29032 + 31117 / 19064)\n3062 - 1695\n32188 * 16247\n((27128 / 25905 - 9974 - 31520) - (7750 - 9972 - 16239 - 1774))\n1273 - 22611\n3182 * 10396\n15723 * 24758\n10443 / 29127\n25313 + 30761\n27085 - 16878\n535 / 1976\n(25364 - 13303 - (25102 + 30133 * 10852 - 21952))\n25478 - 16042\n2514 + 25021\n(12282 - 20884 - 174 - 5774)\n26478 + 20598\n20583 * 28969\n11144 + 10788\n639 / 19730\n16383 / 8745\n1252 - 5350\n(18417 - 7865 + 22965 * 4155)\n(10191 - 16612 + ((12743 * 26739 + 4581 + 32460) * (30055 - 22085 * (15433 + 14802 - 11154 + 6808))))\n((8680 - 26898 * 2652 + 1591) - ((14710 * 8820 - (1610 * 18016 + (((6967 + 1337 * 6341 + 19717) + (24943 - 3670 + ((24761 - 13652 * (31494 / 12335 * 357 - 29976)) * 20650 + 10585))) / 9259 + 18602))) + 12435 - 16858))\n(2018 + 20158 * ((2274 + 23956 - 22248 + 6634) + (7303 - 24048 + 18622 + 2136)))\n16717 * 30150\n22879 - 18703\n30543 + 2451\n28502 / 21308\n155 * 14661\n3755 + 5167\n(30192 - 1538 + 10882 * 15504)\n2415 - 6671\n32545 * 20224\n4931 - 21475\n(28918 * 4094 * (10184 * 9927 + 24686 * 6988))\n27763 * 9489\n24005 + 23044\n15541 * 28791\n21999 * 16907\n29470 / 17232\n3852 - 10040\n24509 + 15993\n7496 * 22700\n27486 * 12822\n18926 - 13279\n3522 + 26373\n31297 * 742\n28109 + 29821\n(20535 + 12053 - 11816 * 18757)\n19954 + 22189\n((27775 * 18689 + (14932 * 29659 + 2153 + 17141)) * 6319 + 17733)\n14736 - 29872\n19927 * 28917\n31256 - 4976\n2647 + 31060\n21089 - 13850\n6728 - 13656\n15795 - 3542\n30792 / 18620\n6670 + 20008\n(10522 * 26455 * 32604 * 23427)\n13700 * 2822\n2753 * 27317\n1061 + 28763\n21935 * 17259\n21488 - 20551\n15995 * 3943\n7243 + 24392\n8553 - 25111\n12729 + 23403\n(21362 * 11718 + 32474 - 14896)\n19170 / 21745\n(17478 / 19002 + 11340 + 3812)\n19953 + 7518\n29896 - 8118\n((((10119 - 17679 + 22374 - 20992) + (22611 + 8214 - 13039 - 10414)) * 13554 + 30071) / 22258 - 9386)\n20489 + 3794\n22991 * 16764\n(16811 * 27469 + (24563 + 153 + (5204 * 5124 + (11378 - 5844 - 1496 - 31577))))\n(26412 + 32322 - (26657 + 22210 * 14622 - 18888))\n(((23575 / 12785 * 4251 + 16524) * 10474 - 1019) - ((29784 - 30021 + 11301 - 27311) * 14658 + 2569))\n1668 - 999\n((542 - 20403 - 17808 + 3103) + 20956 - 14713)\n12323 + 16229\n1199 + 14260\n16613 * 22374\n28447 + 19000\n21398 - 17831\n(7869 * 26837 + 32630 * 2991)\n22191 + 11734\n25261 - 11579\n13018 * 2401\n(32120 * 12895 - 4122 + 4421)\n(4147 * 28975 + 3520 * 8273)\n14828 * 27357\n4222 * 10994\n2356 - 23344\n((10630 - 3729 - 5885 + 27767) * ((13204 / 26277 * ((23753 * 10239 - (15350 + 10316 + 4757 / 17618)) * 12917 * 5572)) / 15226 - 9718))\n1657 - 11758\n(18057 * 31758 / 21650 + 8030)\n12138 * 27530\n1734 - 28797\n23722 + 24678\n17740 + 25580\n12389 * 30264\n(18440 - 25152 - 21519 + 7574)\n10090 - 32300\n(5054 * 11466 + 15392 * 10505)\n(24366 * 11091 * 27973 - 4626)\n15298 - 4980\n(24111 - 16847 - 10115 * 18015)\n2832 / 20363\n(15775 - 7606 * 16071 - 17267)\n14705 + 28085\n19439 * 29426\n(15291 + 31135 + 29796 - 32174)\n10956 / 19322\n6479 - 29830\n28204 * 15954\n21288 - 19172\n(22692 + 10509 * ((3115 * 19858 * 30687 * 28219) * 5647 * 27148))\n((5487 - 22423 * (21792 * 3435 - 4136 - 16485)) - 29872 * 8883)\n(9844 / 23899 + 13630 - 24697)\n29263 + 19264\n17806 + 30817\n(5679 + 21731 - (17000 * 10251 * 8412 / 29299))\n22522 * 6783\n5625 / 13446\n17947 * 10528\n22876 * 21370\n32719 - 2791\n28776 - 5840\n19832 + 31566\n(23260 - 3532 * (32432 - 26557 + 8906 + 24516))\n(24177 - 6135 + 31782 + 69)\n(11764 * 2934 - 5790 + 4782)\n(7341 + 18440 + 28567 - 8883)\n20579 - 12081\n29764 * 7342\n11221 - 12103\n4487 - 9976\n24378 * 2025\n20192 + 30005\n15666 + 29529\n28889 + 2063\n(((24673 / 28548 - (12667 + 26264 * 6527 * 18106)) * 29361 * 9137) * 13268 + 10245)\n23805 * 5247\n(11740 / 29139 * 18991 + 18815)\n(8431 + 5673 * 17692 - 18586)\n(3761 * 1261 * 26776 - 63)\n(29743 + 11050 - 21297 * 14105)\n13451 - 10401\n22042 - 16876\n5736 * 18843\n17799 * 16808\n(19032 + 6895 + 21437 * 4550)\n(27938 + 28926 - 21853 * 24937)\n22539 + 13886\n(24910 + 23997 - (32004 / 25883 + 23161 + 10710))\n326 * 20659\n(14231 * 9586 * ((23081 - 6613 + (19692 + 9911 * 18497 / 24983)) - (30512 - 16343 + 27630 - 19610)))\n24001 * 6044\n8755 + 1183\n11001 * 16090\n1774 - 2799\n27772 / 8241\n5125 - 10904\n11220 * 21177\n12781 * 15756\n32329 - 8758\n8917 + 12756\n22423 - 2741\n28980 / 25816\n21605 - 27191\n23160 + 21339\n9029 + 20235\n(20262 - 9468 - 10150 - 2054)\n(12434 * 30453 - (25980 + 27433 + 28854 + 29526))\n6097 / 420\n(1343 - 23944 * (11366 - 13764 * (11709 + 18592 - 4215 - 30914)))\n9570 / 24394\n(12426 + 21335 * 32005 * 25135)\n(23272 - 14418 - 6638 - 14119)\n(((27191 - 11859 + (19124 * 16241 + (16811 - 31214 + 2797 * 1528))) - 25020 * 24408) - 17664 - 12381)\n(26974 * 25135 - 11526 * 25109)\n32704 - 24266\n11734 / 31918\n17561 + 32715\n23853 * 10760\n32061 + 28791\n28661 - 27581\n5476 * 30749\n3636 - 27336\n3587 + 26447\n12917 + 24666\n29736 + 9570\n(26148 - 5136 - 2150 - 331)\n(9527 + 7272 + ((31915 / 17636 - 32648 + 6911) * 32081 + 23049))\n25486 + 4655\n4762 + 15875\n12945 * 7931\n864 - 1460\n14867 / 13764\n2381 - 6207\n5455 - 27041\n14653 - 30504\n9502 * 29920\n(10066 + 5965 + (21942 - 16159 - (18751 - 29044 * 12554 + 19652)))\n4177 + 12839\n8412 + 32619\n18354 * 16635\n(28020 + 2001 + 27763 - 21251)\n15124 * 14983\n2115 - 7889\n(26741 * 25836 * 15582 * 22576)\n20779 + 14570\n(8939 + 2488 - (18933 - 28938 / 15648 * 17231))\n((20890 * 3558 + 14607 - 23335) * 713 + 1423)\n(11933 * 9738 + (17534 * 18355 + 21865 * 3314))\n6215 * 4876\n31376 / 30013\n25653 - 4592\n12010 - 27525\n2964 / 285\n25453 + 10034\n28844 + 29083\n5045 - 6395\n((29469 + 3201 * 3854 + 5013) + 26508 * 8944)\n11541 * 31205\n(10558 + 719 - (18327 / 30052 * (4608 - 4296 + (((9086 + 10271 - 29283 * 292) - 24176 * 1401) * ((2692 - 20457 + 14893 + 10130) + 19397 + 9715)))))\n26107 / 576\n21546 * 1375\n(11776 - 24784 - 24739 - 5917)\n9488 * 18129\n21347 + 19355\n13493 - 2470\n27715 * 21470\n26298 - 19039\n27304 * 10231\n(10323 * 18257 / 797 * 7565)\n204 - 11325\n30718 + 3188\n(27549 - 21469 + 21434 + 10415)\n650 * 29627\n19232 + 29522\n((17784 - 12656 + 27360 + 11923) + 25228 * 18452)\n(19237 + 6230 * 13142 + 15611)\n15890 - 366\n526 * 31083\n((23802 + 1325 - 17777 + 8246) - 9821 - 31198)\n((2169 + 23778 * (5486 + 1441 + 6949 + 15852)) - 4141 - 14628)\n(31806 / 25792 * (27809 + 16555 - (11833 * 31866 + 11240 - 24250)))\n7722 - 19037\n22697 * 28029\n16448 - 24612\n13909 * 26181\n1389 * 32006\n(25846 / 15988 + 8080 - 22909)\n32687 / 17746\n1403 * 4911\n14363 + 31901\n31589 - 23296\n9472 + 1937\n19698 + 11323\n1690 * 27210\n1090 + 20334\n7975 - 20231\n(22356 * 26584 + (1150 + 22764 - 897 - 4882))\n25093 - 8222\n14492 / 28279\n2726 * 29554\n(8595 - 8112 + 28017 + 11563)\n(11321 * 9884 + 15152 * 23784)\n23467 * 22136\n12164 * 5036\n25635 * 9648\n((1512 * 19244 * 25144 + 11705) - (871 * 3188 + (11701 * 31040 * (7777 * 25849 * 31501 - 1406))))\n22186 - 14565\n23096 - 14890\n17822 - 8542\n789 - 25042\n6256 * 20016\n21712 / 22437\n31287 * 16696\n17602 - 7126\n6326 * 902\n24701 + 340\n738 + 14159\n23764 - 5837\n18122 * 10302\n((17781 * 32598 - (29914 - 23961 - 24587 * 18826)) + 24372 * 24834)\n26897 * 31438\n7893 + 11854\n((2980 - 6912 - 14897 * 22686) * 31757 * 30225)\n(1117 / 8172 * 13764 - 11610)\n10303 + 9586\n(9137 - 24022 + 25144 + 28224)\n5122 / 7202\n25779 + 16235\n26896 - 5527\n(27285 + 6777 * 24167 - 7989)\n15222 - 9977\n12336 - 7188\n31401 * 31912\n28828 / 23102\n452 * 374\n(21139 + 17300 * 5074 * 13751)\n14913 + 22631\n17952 + 19346\n(12514 + 1150 + (12560 * 5466 + 11344 - 16158))\n20221 + 14478\n26578 * 12016\n25072 + 24642\n23800 * 566\n7736 + 32264\n27369 + 11783\n28105 * 3824\n6588 - 16052\n18044 * 16557\n(12219 + 18652 - (((19259 + 4627 - 11602 + 20627) + ((19661 + 1832 / ((27983 * 32087 * 9694 - 18978) / 27049 + 19641)) * 16442 + 4994)) + (17016 * 13951 + 25768 + 29743)))\n20600 + 25636\n31552 + 3077\n((6163 - 20201 * 24106 - 12655) * ((18450 + 26138 + 10115 - 1464) - 19510 - 26362))\n4412 - 30213\n((17227 - 17807 + 22543 - 27437) - 23016 * 2989)\n26621 * 26852\n371 - 16538\n795 * 10396\n(18042 - 1858 * 24124 - 24137)\n(22523 + 14720 + 13269 * 21777)\n22548 / 29433\n18066 + 12886\n12238 + 20658\n10802 - 2670\n26610 + 23854\n5648 - 6292\n31529 + 31209\n31841 + 31828\n(28980 + 26946 / 9703 + 16608)\n(20439 + 18761 + (32378 * 27606 - 19412 * 29195))\n(((553 * 29577 - 28441 * 8514) + (8818 * 14642 + (672 / 13728 + ((18671 - 10902 / 28692 - 6478) * (((5227 + 12358 - (9752 - 1221 * 5641 / 17901)) * (1825 * 18742 * 21808 * 6093)) * ((1655 - 22931 * 27302 + 15353) + 8880 + 5023)))))) * 15647 * 19935)\n3241 - 28480\n13717 + 6142\n21012 * 22238\n4631 - 657\n18258 + 27812\n32083 - 21332\n27658 + 20311\n3768 + 8511\n2430 - 32436\n15917 * 19055\n9852 + 11444\n1133 * 19747\n12266 * 11563\n32134 * 29955\n(18098 - 17559 + 16553 - 18344)\n13134 + 31110\n28938 * 14504\n22663 + 28118\n1910 - 31065\n28538 + 157\n(27256 * 15918 + (32580 + 12363 * 12324 - 26704))\n13821 * 18584\n(15302 + 9060 * 25933 + 26344)\n21417 / 5419\n21124 / 2531\n3292 * 18582\n(7831 * 11321 + 4220 * 14488)\n6185 + 23998\n16550 - 21046\n24075 + 4316\n7373 + 7222\n23007 - 6463\n24437 - 27051\n31546 / 2873\n12525 - 4809\n17137 / 13756\n9102 * 23142\n24577 - 22784\n5615 - 14617\n11193 * 31675\n31841 * 29367\n28658 - 5786\n6523 / 20032\n26440 + 14818\n24772 + 18681\n9280 + 6750\n13782 * 19678\n7889 - 30160\n20519 / 18071\n12878 + 14438\n((373 + 28280 * 11350 * 1849) - 31988 - 28059)\n23864 + 18053\n30958 - 3155\n(24267 + 3050 / 17459 - 14068)\n((24667 * 8978 * ((3554 - 8952 + 3036 * 19385) - 16433 - 19299)) + 3386 - 27799)\n(28352 * 8617 - 25031 * 2230)\n25688 + 7137\n27171 + 642\n20278 * 29277\n(15343 + 2435 * 12988 * 11056)\n29338 * 23786\n13697 * 30066\n25598 * 4341\n4362 + 23573\n(8173 - 17219 + 17018 * 17456)\n2677 - 20011\n15107 - 15688\n(15088 * 3734 * (21284 + 19222 + 18121 * 14681))\n14174 - 10855\n2269 * 2262\n11216 * 7878\n30382 / 36\n19299 + 8091\n(23376 * 765 + 8087 - 7061)\n((9997 - 4852 / ((16567 - 20597 * ((31975 - 17712 + 1566 * 26399) + (18633 * 6882 + 15306 - 29221))) + (((20765 - 4269 * 32191 * 9962) - 1073 * 13472) + 4904 - 21127))) + 32221 - 22452)\n10588 - 13941\n17727 - 4422\n17428 + 13638\n(6428 - 30801 - 15115 + 31318)\n(6306 * 30588 - (7092 * 15673 + 17421 + 21619))\n23174 - 7565\n23406 - 14676\n(19625 / 6755 - 2722 + 3781)\n((29844 / 11213 / 16476 - 18088) * ((31000 - 1942 * 23773 * 31166) * (25584 - 2532 + 21062 + 5967)))\n12134 - 24561\n18503 * 27878\n((12854 + 16053 * (206 * 12116 * (13987 - 21569 + (24917 * 6237 + 4573 - 28111)))) * 3842 / 27986)\n(26812 * 31956 * 3519 - 16890)\n27201 - 17604\n16046 * 5903\n(9095 * 6826 * 15307 + 14890)\n9116 + 29034\n14800 + 31971\n(6330 / 25552 + 12005 - 2230)\n7573 - 24124\n30559 * 16882\n2038 * 13311\n17407 + 20730\n29731 * 11646\n((8675 * 18879 + 14189 - 27917) - 6467 / 18611)\n16057 * 8996\n15068 - 11269\n11492 * 13442\n19720 * 20966\n((21396 - 8778 * ((23454 * 25942 - 24559 + 28934) * 11465 - 6896)) * 21207 + 6359)\n((23948 + 5431 - 25504 - 7425) - 5185 * 11013)\n27521 - 28454\n(((19639 * 19089 / (27360 + 18647 * 21168 * 23484)) - 21682 * 16728) - 7987 - 29948)\n(8872 - 32753 + ((32701 + 20055 + 29318 / 20053) + 25859 + 15932))\n11685 + 356\n6437 / 30187\n5410 + 14979\n31035 / 12563\n(6650 - 2562 - 3438 * 24854)\n((29605 + 2437 * (1215 - 12631 - 12167 * 17635)) + 17494 + 32495)\n17689 - 16364\n23881 + 419\n((12882 - 31231 - 5295 + 26109) * 4258 + 18550)\n7623 - 13531\n1048 + 4338\n16107 * 17252\n18853 - 32757\n3171 * 2620\n12329 * 9627\n10604 * 6443\n11858 - 30723\n25884 * 3567\n11397 * 32403\n(27531 * 27367 + 30067 + 10997)\n9595 * 7828\n527 - 15920\n18014 - 2939\n22391 * 13728\n29631 * 6948\n23125 + 11646\n10587 / 28580\n24566 * 3994\n(29083 - 1667 + 2277 * 11955)\n11989 - 29147\n6459 * 30570\n11777 - 9823\n(13190 * 18302 - (1220 / 20138 + 2282 - 24346))\n19393 - 5040\n10822 + 29963\n22087 / 20681\n1980 * 32529\n22985 * 30865\n22328 - 20073\n5297 + 10461\n1341 / 24803\n13942 * 13610\n31250 + 16758\n6574 - 27056\n29851 + 23168\n(16125 - 27177 * 21383 * 2338)\n8148 + 1931\n9401 + 18584\n(17236 + 30462 - 15794 + 11856)\n31786 * 16421\n14271 - 28458\n7268 * 9830\n22568 - 17044\n28328 + 4421\n(14476 + 20128 - 26929 + 12794)\n21978 - 30924\n20819 + 23244\n5174 + 16879\n(631 * 20731 + 6982 + 4330)\n30994 - 12853\n480 / 9056\n14399 * 5600\n(20236 - 23480 - (939 * 28870 / 10446 + 6404))\n3180 / 8952\n6512 * 4948\n859 + 8123\n25197 * 24119\n(17006 - 1606 * ((21598 * 21858 - 1464 + 22247) + 20697 * 20135))\n6967 * 20542\n((31088 - 28020 * 12129 - 9398) * 320 - 24595)\n(3357 - 8737 * ((((9558 - 6509 - 22491 * 25078) + 12917 + 18464) * 10869 + 22774) - (29019 - 3971 + 26308 - 11160)))\n13041 - 14359\n(19360 + 28186 / 13422 - 9000)\n9902 - 10889\n1850 + 22459\n13196 - 18371\n20565 - 17762\n20633 * 27033\n32589 + 3931\n2055 - 21878\n22543 * 67\n23235 + 6278\n26335 - 14115\n7079 + 28908\n14982 + 10854\n(29434 / 4885 - 30433 - 31846)\n25388 / 6797\n((15794 + 22032 + 32059 / 24674) - 21004 - 4716)\n20347 - 9841\n19980 + 699\n(26926 + 19750 - 27236 + 32740)\n16644 - 12378\n(23939 + 29688 * (28725 * 32456 - 27567 - 25861))\n11481 + 10262\n((1068 + 14312 * 1295 * 12840) + (5842 * 31799 - 3317 * 12105))\n(28005 * 10443 + 16280 - 6764)\n5610 * 7645\n15050 * 28142\n5111 * 9672\n19285 - 17910\n15031 * 14555\n(23837 + 11725 * (11888 * 9233 + 14710 - 27675))\n1823 + 20306\n2943 + 27734\n18874 / 17699\n(8998 * 27206 * (4526 * 16186 / 13620 * 4215))\n32551 * 4561\n14626 / 14275\n3591 * 5999\n(12639 - 28682 + 4709 + 27648)\n10152 + 10052\n(((14967 * 23007 * 31878 * 3704) * (520 - 16910 * 17880 - 19191)) + 12883 * 28359)\n14410 + 27131\n(18718 + 5935 - ((16793 / 16173 * 12709 * 10293) + 8656 - 1152))\n9033 + 7144\n9625 + 29952\n(19608 * 25135 - ((24686 * 20775 - 22487 + 20910) * (362 - 25593 + (28778 * 18019 - 27302 - 20187))))\n((14712 + 16419 + (10405 + 18076 + 31956 + 6342)) + (29532 * 14048 - 13911 - 18587))\n6002 - 8770\n32568 * 17444\n(31919 * 17487 * 20327 + 14521)\n10180 - 31072\n2062 + 10968\n(26312 + 29276 + 11231 - 23195)\n24587 * 29393\n10746 * 18347\n(28014 * 12227 * 32170 + 8077)\n(24421 * 12026 - 6388 - 17007)\n8521 - 8255\n(11605 * 8767 - (12898 - 23756 - (23598 + 20905 / 25459 - 21366)))\n2054 - 31081\n12336 * 15831\n(24662 + 26558 - 24236 - 21011)\n23214 + 9582\n25165 - 9054\n12488 + 8602\n10981 + 30030\n14626 / 25396\n6612 + 5079\n(11578 * 14906 * 27925 * 18075)\n3820 + 28181\n5750 * 24904\n19993 * 25118\n(23409 + 16449 - 216 * 28890)\n29580 + 6279\n21730 - 29688\n32476 + 31848\n6621 - 26652\n((19776 - 26844 - (11487 * 7289 - (18905 / 30071 + (22836 + 15836 - 26097 - 2898)))) - 13458 * 15255)\n5757 * 6071\n28506 - 28948\n32142 + 12219\n((1766 + 21980 * 12305 / 23629) + 18068 + 11648)\n26765 * 28874\n25887 + 5082\n25282 + 17325\n(24204 - 25145 * ((20679 + 28768 * (12483 - 2899 - 8834 * 9352)) - 23163 + 689))\n((8784 - 25236 * 7963 + 32455) * 27045 + 6865)\n24645 - 4221\n28072 / 24766\n7195 / 14845\n(14746 + 8800 + (30867 - 18993 / 20821 * 43))\n4128 * 18921\n23310 - 1681\n8894 * 32214\n24164 - 19864\n25766 * 13943\n1991 * 1156\n21677 - 783\n(((29881 - 18297 * (8872 - 27487 + 14387 * 882)) + 28638 + 22162) + 17951 + 20414)\n4147 + 8425\n(1288 * 26705 * 2747 + 11863)\n28015 * 3314\n13069 + 1835\n(27044 - 21634 - 20356 - 23136)\n10797 * 10547\n(25106 + 24860 * ((28561 - 4471 - 26206 * 3753) * 16559 - 19165))\n(32121 - 30428 * 27131 * 507)\n23877 * 19430\n11579 / 10371\n2409 - 21069\n16772 - 18580\n13242 + 5168\n8860 * 12153\n26167 * 17469\n19494 / 11494\n(7055 - 24223 + 7690 + 31644)\n20507 / 19662\n6676 * 12520\n30987 * 18228\n16427 * 6297\n10509 * 3626\n(31540 * 4843 * (785 - 12198 - (19393 / 24215 / 15872 - 31463)))\n27108 + 13909\n18714 * 17855\n30502 / 26541\n14612 + 9392\n18269 + 20368\n3991 - 18143\n(23948 * 13328 - 27314 - 16019)\n(21405 + 31989 + 1420 * 18106)\n19557 - 1059\n6827 - 27377\n32146 + 22353\n6346 / 25247\n13336 + 30665\n8752 * 11669\n21222 * 23351\n15001 * 26592\n18466 - 2078\n(31600 - 26651 / 19868 * 11423)\n25273 * 21807\n10792 * 16989\n785 + 22307\n7471 / 29123\n5988 - 18982\n(16956 + 24498 * ((20224 + 9034 - 28797 + 26937) * 16773 * 81))\n28885 * 19932\n11261 + 1342\n3963 + 8423\n(27270 + 26776 * (27624 + 18107 + 5115 * 5113))\n(3727 * 31319 / 19743 - 26953)\n(885 - 12201 + 10346 - 15408)\n13552 * 25814\n30169 - 8726\n23015 + 30613\n((9294 + 485 + (23158 * 11788 * 10646 - 6952)) - 23571 - 30297)\n23641 * 14168\n19928 * 13100\n2260 / 27951\n28510 + 3326\n(7275 / 2717 / (12659 + 18620 + 8616 / 32026))\n31480 + 3310\n16914 + 12211\n12234 - 10442\n2721 - 9611\n28430 / 384\n((6723 + 12930 + 4468 * 19234) / 31647 * 30977)\n(30183 / 5416 * 21560 * 3941)\n29671 + 18767\n(23402 * 6802 + 16331 + 6838)\n(23298 * 3693 - 16376 + 22235)\n(7771 - 12341 + 9662 * 13256)\n28195 + 16413\n((28386 + 20675 * 29544 + 16138) * 31651 - 24109)\n(((5853 * 32317 - 924 + 25760) - (((11689 + 3560 - 12092 * 14013) + (14436 - 32144 * ((16222 * 25365 * 24173 - 23447) * 26584 - 13322))) - 28916 * 2308)) * 25176 / 30540)\n19103 + 8340\n32600 * 20808\n((21884 + 20717 * 7302 * 15741) + 13230 - 27099)\n(((23896 + 20773 - 27604 / 25677) - 12609 * 5026) + 17096 - 21776)\n6301 / 19775\n7908 * 22285\n17207 - 22041\n27481 + 27544\n23947 - 23184\n28496 - 1691\n(28669 - 6338 - 30754 * 15934)\n32224 - 1739\n4946 + 6843\n13174 - 19286\n28123 - 23559\n(4297 * 32601 - ((19208 / 18979 - 21657 + 19262) * 18655 - 3189))\n390 * 3568\n7962 * 15990\n18945 / 15935\n12326 - 26928\n328 * 21017\n18614 + 19625\n293 + 16406\n(10226 - 13647 + (22687 * 31551 * 22437 - 21291))\n(5568 * 21940 + (5758 + 1518 - (16957 + 16965 / 22499 * 20426)))\n705 / 12794\n3161 * 31710\n25565 - 30830\n24609 * 22684\n18987 + 29249\n11927 + 9969\n8914 * 16915\n15265 + 11577\n14217 * 9240\n8913 - 18264\n(32364 + 29733 * 9770 - 26319)\n7385 + 9385\n4271 / 17820\n8277 - 4223\n19392 - 12615\n22828 * 1945\n10200 - 13998\n(23416 + 8799 - 9441 + 19200)\n(32431 * 3944 * (25164 * 4603 - (27925 * 20727 / 10249 - 12544)))\n22507 - 25436\n27933 - 11150\n((6117 + 23038 - (15167 - 2211 + 11885 * 12149)) + 19605 + 913)\n4206 * 7127\n9524 + 27185\n(17462 - 21942 * ((16683 - 32588 * 10835 - 22440) + ((28652 + 24839 * 18124 - 14079) - 17885 * 19420)))\n11444 + 16246\n27995 * 27799\n9491 * 28998\n24391 / 15447\n(32630 * 13928 * 11473 * 10193)\n13697 + 24981\n(26268 + 6629 + 2797 * 30556)\n10349 + 12303\n((761 + 12016 - 18162 * 17023) * 26129 - 26811)\n10798 * 10895\n29751 + 28867\n(24025 + 12668 + 23317 + 14866)\n11892 - 18968\n(24820 - 28732 + 25168 - 26216)\n29369 / 29624\n25623 + 7406\n27954 - 4004\n27740 + 32426\n(19807 * 20551 + 3890 - 30833)\n(19325 - 21987 + ((20843 * 289 - 4384 + 30477) + 24901 * 8728))\n22720 - 11550\n2226 * 9897\n30199 + 25544\n31742 - 4830\n22868 - 13117\n10798 + 957\n6872 * 19404\n24188 - 29571\n(655 - 20917 * 30022 - 30116)\n27463 - 13185\n26470 * 10572\n31327 + 460\n808 + 21513\n63 + 18662\n(9864 - 5055 - 22611 * 9983)\n22338 - 3940\n(17354 - 23808 * (16180 + 20567 - 2100 * 27644))\n10507 * 22745\n29498 * 10103\n16518 / 1412\n(((32655 * 2911 - 20887 - 5147) + 30305 - 17171) - (28885 + 23566 * 16731 + 15852))\n4707 - 13208\n11985 - 3163\n((23858 - 24507 * 998 - 7483) - 12154 + 24684)\n28644 / 20932\n4290 - 29005\n29462 / 6661\n16082 - 5344\n7542 + 32185\n26737 - 20574\n18134 - 3164\n(25619 - 29724 + (32614 + 32372 + (126 + 20983 - 24828 + 31041)))\n8964 - 16663\n24064 * 26695\n18343 * 13130\n1478 * 27246\n15399 * 1763\n8240 - 20527\n23294 - 13712\n11310 + 30023\n21031 * 6332\n(21904 * 8191 + 25087 - 8250)\n(23623 * 31611 * 2123 + 5702)\n16875 + 7913\n6652 - 22991\n22537 + 27511\n20312 + 6148\n29960 * 20456\n31690 * 8986\n1518 * 3644\n27551 * 909\n7682 * 13438\n13635 + 29769\n(24921 - 11310 + 13003 * 2511)\n19435 + 9482\n(1515 + 5641 - ((26413 + 20206 + 1639 + 5418) - 10444 * 12932))\n24621 / 14218\n26672 * 14156\n26864 - 29819\n27882 + 12185\n4966 + 23527\n(15056 + 10515 - 31620 - 7783)\n26519 * 4821\n9371 * 14491\n(2164 / 15315 + 5062 + 4695)\n19185 / 28529\n28685 + 16636\n24511 + 23929\n(19287 + 7555 * 26860 / 11778)\n8815 + 23953\n25175 + 31357\n(31052 + 6436 - 9704 + 11453)\n24808 - 24091\n23579 - 21817\n32267 * 24224\n107 + 31378\n14589 - 14454\n(15780 * 26885 + 29875 / 9564)\n14190 - 31765\n19777 - 31103\n2019 + 22463\n22571 - 7507\n28739 - 21221\n4570 / 9926\n4919 + 16850\n(6852 * 32091 - ((9632 - 28810 * 22008 + 1354) / 25399 + 10359))\n(22934 - 25904 * 20589 * 1065)\n19445 * 13427\n(14936 - 26521 - 31278 - 25423)\n13245 * 2376\n(11621 + 27654 * (5643 * 3459 - 4671 - 20409))\n(((18544 + 6394 - (19127 * 7564 - 6448 - 7475)) + ((27871 / 24822 * 19963 - 10302) - (25150 + 26510 - 12118 * 32228))) * 4671 / 26291)\n28450 - 28269\n12385 + 13247\n27163 + 7665\n5999 * 9396\n5619 - 29088\n12943 + 4966\n30048 * 15925\n(16197 - 7670 + 16175 - 15174)\n6031 + 28579\n(25098 + 18312 * 30312 - 20148)\n(16201 * 16312 - 23432 / 29710)\n14977 * 21432\n19793 - 4637\n(30932 * 15778 - 21018 - 30290)\n19993 / 2740\n25258 - 18842\n27957 - 23481\n515 + 32415\n12420 + 25511\n24596 * 12057\n10146 - 23928\n21437 + 20358\n23974 - 14613\n24755 - 18799\n10131 / 20204\n10273 + 6201\n(24237 * 17167 - 14044 * 15893)\n28639 - 21159\n19379 - 4768\n27265 - 19118\n11888 - 22740\n6735 + 7690\n6735 / 29890\n24297 + 13178\n8218 + 17419\n17265 - 17066\n12222 + 10869\n22491 - 7745\n8965 - 21923\n((3768 + 9791 / 7051 + 30006) * 6943 * 3066)\n20798 - 32624\n27934 * 31010\n1856 + 25480\n17167 + 801\n32655 * 11059\n28601 + 9110\n20884 + 8476\n32021 * 21143\n5833 * 7543\n18896 + 18610\n(16595 + 29689 - 19513 - 19746)\n14619 - 32489\n25820 * 10385\n(1748 - 5968 * 1378 - 25672)\n(31177 - 29971 + 26306 + 3529)\n28051 - 19443\n31256 / 8462\n(30310 / 508 - 19098 - 2579)\n8247 + 31482\n13198 + 27077\n18440 * 5862\n6395 - 29480\n10787 * 28651\n31268 * 2826\n19887 + 5374\n21920 / 17442\n2355 + 1935\n28791 * 18044\n6461 * 20623\n11093 / 18405\n(3206 * 22965 - (((31084 - 5626 * 26203 - 9826) + 31013 * 26107) - 20516 * 2697))\n26272 + 13529\n16980 + 17687\n7382 * 3791\n26628 + 9239\n(((11159 - 31373 + (29300 * 21415 * 18896 * 22903)) + 19844 - 18513) - 21405 * 29601)\n7581 + 1644\n(29501 * 24855 + 703 * 1397)\n18586 - 7619\n(20301 + 9492 - 7915 / 2168)\n((20968 + 610 + 14526 / 2495) - 22903 * 262)\n29395 + 12136\n16531 - 919\n((27810 + 25178 - 21956 - 24237) + (((12098 - 2416 * (((30224 / 6596 - 28178 - 3264) - (21928 - 15947 - (7615 + 12354 + (18380 - 18071 + 8166 * 29251)))) + 28619 - 10021)) * 7607 + 18388) - 11228 + 16041))\n(9168 + 3709 + 25682 + 9524)\n26252 + 10957\n(13617 * 615 - (2922 / 19664 * 18571 + 7155))\n2186 + 8479\n9230 - 31500\n13114 + 1348\n13318 * 17626\n2100 - 23077\n(26543 * 18225 * ((16795 * 6132 + 8185 + 2) + (4494 * 2984 * (21447 * 26174 * ((7247 / 3073 + 3521 + 22861) - 30315 * 26721)))))\n8028 + 21227\n(11820 - 1439 + (4166 + 1071 + 10058 / 1286))\n6518 - 23026\n(24359 + 26525 - 15841 * 17915)\n(15412 - 14106 + (26139 + 4347 / 27213 - 25462))\n(21551 - 11040 + 25021 - 7611)\n9104 - 2729\n29163 - 31407\n15257 - 9799\n16153 - 10085\n6504 - 4706\n21839 - 30449\n((15795 * 20962 - (((24465 * 9012 * 31354 - 13760) / 25978 + 143) * (23067 * 31533 * 28419 * 18761))) * 19155 * 3922)\n972 + 23820\n4998 + 29989\n((5040 + 26438 - (6984 + 20719 + 6768 * 14004)) - 26062 * 1754)\n10654 * 6214\n22396 - 17243\n2304 - 31995\n5217 * 4693\n17745 - 7939\n32384 + 16755\n((30493 + 13885 / 68 * 241) - 30210 + 26927)\n31968 * 23352\n17974 / 8585\n15820 * 11938\n23217 + 10883\n31262 - 10830\n18997 + 23490\n8762 + 25804\n22091 - 3216\n(19354 - 21030 * (6276 + 24149 - 24703 * 7512))\n11749 - 5911\n29129 + 9920\n5562 * 26205\n21839 + 20498\n14091 * 19876\n(18307 - 24919 - 4872 - 27496)\n25345 + 31132\n6450 - 22678\n((2298 - 17453 * 32115 + 29005) * ((32453 / 30316 / 29338 * 11458) / 8924 / 6568))\n24163 - 23458\n(6803 - 15046 + ((1251 * 29670 + ((12004 - 24329 * 30149 - 27477) - 5203 / 6827)) * 29050 / 29612))\n30814 - 22804\n15997 + 20921\n((10215 * 12173 * 12683 + 18053) * 15153 - 21925)\n(19849 + 16657 / 4107 * 23506)\n9464 - 27959\n8769 * 9721\n29530 * 30592\n7058 * 2774\n(21732 + 16882 + 31848 - 3664)\n(9426 + 28780 + ((30901 - 31496 * (((24089 * 13940 * (30808 / 26114 + ((22764 - 5632 - (16587 + 16305 * 14110 * 8342)) * 12261 * 29741))) + 8281 / 25688) * 11141 + 855)) - (((20633 / 8420 - 12806 + 18086) + 13095 - 6832) + 9606 - 8020)))\n8537 * 14963\n5925 + 11942\n30456 - 15458\n10066 + 290\n14291 + 7713\n(12784 / 25755 * 26230 * 20698)\n((((27971 * 6038 - 10275 * 8360) + 10648 * 22275) - 32260 * 30447) - 4384 * 32736)\n(8284 + 21231 * 1579 + 2234)\n22832 / 30765\n15528 + 1842\n7518 - 5787\n((18723 * 14778 * 27129 + 18490) / 1770 * 4874)\n24589 - 9716\n16398 - 17591\n(3753 - 18602 * 20616 / 6715)\n29522 + 9382\n540 + 7491\n((18380 + 9790 - (5587 + 21619 - ((964 * 13608 + 31783 - 12102) + (1263 - 1393 + (26764 * 16721 * 31213 * 12948))))) * 1510 * 16016)\n9151 * 6424\n((7401 + 1627 / 2100 * 28590) - 27609 * 7522)\n24143 / 22321\n(1292 * 17264 - ((1436 - 27340 + 27890 + 25540) * 21043 / 3976))\n16410 / 26029\n22719 - 11234\n5889 + 32635\n28227 / 32071\n17413 + 7432\n14419 / 22928\n28452 - 29123\n7897 + 24605\n4713 - 3366\n((21350 + 7796 - 7143 - 13520) + 6975 - 30302)\n(10902 / 8767 + (10369 - 349 + 2639 - 30417))\n5201 * 17167\n2474 * 7251\n23119 + 14322\n20311 - 23481\n18212 + 20575\n6358 * 11825\n7237 + 217\n9876 + 16842\n8074 + 11925\n(7169 + 20134 * 27313 - 23356)\n12595 / 1231\n(1846 - 13856 * 5123 - 26734)\n20468 * 17144\n15158 + 11116\n11190 * 18019\n23812 * 26069\n22480 - 23740\n19123 * 23945\n((27204 - 14753 / 20045 + 4518) + 14401 + 21751)\n18980 + 22251\n23235 / 28146\n(17745 * 245 + 3154 * 24749)\n15018 - 16473\n22086 / 32071\n((2526 - 32472 * 415 - 8877) - 5088 - 5117)\n24025 * 22475\n23531 / 13172\n(20410 * 30201 + (25093 + 28833 * ((11953 - 22911 * 29925 + 10440) + 30247 * 28616)))\n23853 - 687\n14463 + 3290\n79 - 8596\n21301 + 1214\n21162 * 5568\n(7990 - 32488 + 29957 - 4716)\n31919 + 27552\n14644 * 1766\n27248 + 30090\n(((1848 - 12538 - 20359 / 1407) * (15836 + 20373 * 18518 - 29873)) + 19759 * 23962)\n32306 * 4293\n2344 - 9269\n31221 * 19159\n5003 / 16840\n38 + 24364\n(542 + 19116 - 28807 - 258)\n15672 * 17467\n12628 * 21320\n4518 * 28431\n19538 - 22359\n3784 / 2226\n11606 - 20830\n14928 + 10109\n29085 - 8903\n((30803 - 7055 / 4977 * 13158) + ((5518 * 4299 * (7767 * 13071 * 20274 * 25693)) - 3987 - 18239))\n6213 + 2379\n(9852 - 12821 - 29639 / 10690)\n(30953 / 22846 * 16576 - 28069)\n2652 * 26736\n239 + 10386\n((31352 * 19308 + 5679 + 26519) * 31922 + 29473)\n5874 * 4723\n30136 + 27520\n11833 + 22533\n5876 + 21221\n(32058 - 5412 * (22691 + 26573 * 25499 * 5883))\n8245 * 1431\n11353 + 6432\n(3856 * 25094 + (16790 + 1647 / 7269 - 1358))\n(22056 - 3670 - 26952 * 6587)\n5616 * 22849\n(5669 + 30135 + (30726 * 18125 + (13090 * 18604 + 30614 - 4063)))\n10942 * 10103\n(1089 * 31795 * 49 + 23897)\n3652 - 22799\n8343 - 19708\n30288 - 3808\n27851 + 25969\n4705 + 17639\n((24780 * 28860 - (14070 / 4028 + (11529 - 20404 / 5319 + 31155))) + 3890 - 15269)\n(7814 * 25644 * 12593 - 5035)\n13462 * 22510\n15746 - 14642\n((27375 * 15191 + 14957 - 29344) - (22670 + 32634 * 18527 - 25824))\n((27561 + 9980 * 5868 / 27231) * 27258 * 31266)\n20452 * 888\n((16575 + 14690 * (424 * 8751 - 28240 - 31053)) - ((27018 - 26416 + 26967 + 22302) - 8319 + 12847))\n20820 - 29391\n10394 + 30269\n1178 - 11182\n12704 + 18285\n1372 - 27897\n(6776 - 31398 * 8953 - 22031)\n16861 + 23032\n6994 + 16361\n25632 * 28591\n(2200 * 2722 / 22052 * 6759)\n31650 + 12190\n29558 - 15684\n17883 * 21524\n31778 + 31831\n((15743 - 1966 * 19651 * 4390) + 3480 + 21607)\n(29524 + 18067 - 23425 * 29141)\n17000 / 3279\n31691 + 2905\n(17474 + 27821 * 8503 - 4976)\n24778 * 6462\n(3192 / 19193 - (12847 + 27854 + 25988 + 23810))\n7908 * 20073\n(22686 * 1749 + 11781 * 24374)\n28711 - 25100\n21025 + 21029\n(12256 - 9756 / 19242 / 16279)\n29196 + 10562\n8058 * 3271\n15766 - 28959\n20851 * 18324\n10334 * 3509\n((12711 - 24298 + 32097 + 4384) * 25228 * 14530)\n27655 - 728\n9404 / 17516\n29010 * 10687\n18233 * 13263\n(17547 + 183 * 8773 - 20975)\n(((6129 * 4291 - (13890 + 19303 - ((1695 / 4711 * (4626 - 12815 - (10151 - 25584 * 28424 + 7619))) * 24027 * 13032))) * (25762 + 24543 + 20290 - 14454)) - (3096 * 31483 - (14503 * 13545 - 28158 + 2325)))\n(30894 + 26070 * 14482 + 30209)\n((32713 + 31419 - 13066 * 16110) * 28692 * 31280)\n26573 + 1497\n9870 - 19655\n12402 - 4070\n16417 + 11245\n(2563 * 15228 - 6187 - 3935)\n13030 - 27510\n18029 - 2721\n7358 * 10223\n30734 + 25122\n(15121 - 14817 * 27690 * 2755)\n(425 * 6546 + 28969 * 3204)\n10158 + 28402\n(5269 + 4799 * 28625 * 12364)\n12274 / 15673\n32118 + 17820\n1157 - 4312\n15108 + 18351\n24654 * 12969\n20393 / 17919\n((3242 + 31877 * 1204 * 14157) / 689 + 14049)\n8526 + 16962\n8865 * 26925\n6481 * 21329\n(16345 * 4300 + 26989 - 5389)\n(4227 - 24975 + 27673 + 27048)\n8731 / 1569\n(29581 * 7185 + 4967 - 14183)\n(19035 * 11376 * 25650 - 27362)\n26120 * 17590\n23190 * 8288\n6748 + 25476\n17462 + 4083\n5419 * 28754\n5104 - 22859\n20827 - 24720\n24532 * 26851\n18619 - 12700\n(27893 + 20838 + 9461 * 24285)\n((15315 * 31327 + 7911 * 9527) + 8187 - 11449)\n7083 - 10502\n10681 + 8935\n8280 * 3808\n((((16863 + 27735 / 30171 + 4506) + 17301 + 18242) / 29417 * 7435) * 30043 - 23694)\n6684 * 4792\n23868 - 10632\n25770 - 6978\n(1405 / 6378 - 29667 + 18989)\n6284 + 24374\n(29812 + 16554 * (30814 - 19206 - 4743 / 18332))\n((((19354 * 11505 * (8577 + 14816 + (7143 - 6584 + 24063 / 10752))) + 6263 - 6540) + 4887 + 20684) * 21568 - 12941)\n((16794 * 32201 - 23475 * 25616) - 10617 * 13693)\n21355 * 29425\n((9435 + 519 + 17341 - 6446) - 25339 - 1253)\n(29157 / 6861 * (7275 * 24372 - 12773 - 23409))\n13856 + 2894\n830 + 5144\n24065 * 30393\n11143 - 24884\n(7321 * 24646 * (15850 + 27001 + 16214 * 23574))\n19144 + 7204\n(((1107 + 16653 - 13569 / 19925) / 29842 - 2044) - 14547 - 22209)\n1768 + 1576\n31679 - 21292\n25161 + 17997\n28815 - 7219\n12547 - 5600\n11072 / 8531\n22468 * 20852\n13055 * 4735\n6012 * 5283\n(4168 - 26647 - 14664 * 2174)\n32676 * 6368\n7730 - 29621\n32419 * 4476\n(22659 + 2280 * (23878 * 17958 - 1541 / 12864))\n32182 + 7797\n(8554 * 17444 * 30129 + 14787)\n3595 * 19786\n(21871 * 31258 - (((19818 + 1769 + ((32596 + 5301 - 12162 + 26741) + (26644 - 10670 + 11187 - 4182))) * (16901 / 27112 - 30219 + 31777)) * 16899 - 30321))\n27490 + 10657\n8230 * 11110\n16291 - 9964\n3948 + 1447\n13157 - 24629\n8371 - 26642\n4663 * 16733\n30925 - 6403\n14355 + 8715\n23277 * 18534\n30930 + 4679\n5437 - 20848\n(2641 + 6541 * 18269 - 26975)\n6082 + 2076\n10304 - 1728\n19541 + 234\n20584 * 28930\n(12747 * 1025 * 14052 * 7530)\n10808 - 20765\n(23410 + 31278 * (6151 + 23959 * 26040 / 789))\n839 - 10529\n((22738 * 15483 + 3508 * 28459) * 21130 * 25284)\n15242 * 192\n1439 - 347\n31508 + 11602\n6879 - 661\n29217 + 17476\n15599 / 22069\n711 + 20516\n5697 * 17888\n(1675 * 32286 * 22080 + 32115)\n11484 - 16744\n31856 + 28604\n(12205 - 21746 / 5894 + 12540)\n32042 / 20295\n26609 - 16321\n(((18162 - 838 - 15882 - 10551) - 15012 - 20053) + 25598 * 11037)\n21720 + 23580\n11713 / 23722\n(31464 * 25786 * 14210 - 18085)\n26047 * 4258\n20190 / 6834\n17447 + 20966\n((11030 * 23391 * 3533 + 14540) * (25669 - 15489 * (22516 + 4743 * 28166 - 25024)))\n23963 * 30135\n10612 * 31449\n6150 + 32057\n2914 / 25547\n27478 - 25424\n(19169 + 25028 - 32260 + 270)\n745 * 27333\n24678 + 10346\n((12682 * 16387 - 11870 * 3608) + ((27880 * 12637 + 11400 + 26869) / (1887 + 24083 + 4466 * 20953)))\n27235 * 13145\n14200 + 8077\n15033 + 6194\n19754 + 14600\n(7181 * 7854 - 5936 + 16306)\n22402 - 14827\n(((3927 + 11590 - 8137 * 5018) - 19796 + 17038) * 26249 - 19127)\n9236 * 30564\n8962 - 17842\n(25184 * 3907 - (754 * 26736 * 10160 * 1948))\n2692 * 18452\n16458 * 8953\n937 - 4724\n(8933 + 22455 - (21119 / 30569 * 14486 + 9655))\n28206 - 3124\n30319 - 23749\n21544 + 10077\n26011 * 31310\n(32481 * 3653 - (20669 + 21608 * (15788 - 31679 - 23095 * 25719)))\n16137 + 31142\n(24534 + 25564 + 4348 - 11399)\n27733 - 20666\n((17706 - 8462 - 2154 / 773) / (14023 + 3839 / 23599 + 29914))\n(((32068 * 6530 * (10662 - 4929 + 23901 - 29789)) + 26896 + 13938) * 14460 * 195)\n(25692 * 6920 - 11854 * 74)\n31288 - 20679\n((10928 * 19837 - 10673 - 9599) + 7006 - 16228)\n32217 - 23538\n(((16672 * 13580 * 21059 - 25524) - 5523 - 18872) - (28461 * 1855 * 16321 + 2295))\n804 + 16976\n(11668 - 5124 * 15554 * 13194)\n13103 - 7809\n(13290 + 31988 + 31577 * 22103)\n((15831 + 22345 + 6933 + 264) - (28584 / 320 * 18365 + 23013))\n3821 + 26895\n69 + 15359\n(21114 + 27118 - 28291 - 19130)\n10556 / 1524\n21500 - 26037\n30375 + 2844\n7575 - 9319\n31947 - 28300\n28103 + 5649\n31592 + 32699\n30972 - 6013\n11461 * 8427\n1932 - 31703\n4863 / 19425\n601 * 18041\n5246 * 30397\n(31426 * 31448 + 15311 / 10477)\n(8183 * 30544 - (19875 * 23180 + 10710 - 9147))\n8834 + 28555\n7948 + 24576\n3358 + 23487\n12404 * 22610\n(((8825 + 13388 + 395 - 25798) + 11711 + 25660) - (1775 - 6143 * 21836 * 14981))\n428 * 26495\n17347 + 25017\n27512 / 11050\n9191 - 22694\n5614 / 27267\n(25029 * 18103 * 20467 - 27145)\n(20440 * 32001 * (16935 * 14784 / (16052 * 30626 / 16525 + 10812)))\n26752 + 11644\n1889 - 14943\n22591 * 18951\n22058 - 16661\n(24577 + 29923 * 3029 * 6622)\n((17972 + 27470 * 2875 - 460) + 14535 - 15853)\n356 - 18890\n(21158 + 25035 - ((2215 * 27435 * 7443 / 10246) - ((3987 - 21694 / 25645 + 30589) + 15151 * 10960)))\n99 / 6719\n15351 + 4431\n29735 + 22625\n32675 + 22515\n8679 + 7777\n2730 * 17775\n16887 - 19104\n11387 * 2864\n10043 - 12198\n8068 - 27922\n(10136 + 4720 - (16086 * 909 + 28298 / 30179))\n15917 * 21240\n(10455 + 29089 - 19516 + 31669)\n(16572 * 28565 + (((23073 + 21611 / (18502 + 20952 - 23532 + 28063)) + 32680 * 32344) * 10505 - 772))\n21105 + 3800\n22629 * 19659\n19293 - 13626\n30487 - 5626\n20661 + 13378\n(28158 - 24942 * 29570 - 31643)\n1814 - 8\n16593 / 20086\n11469 - 9571\n3246 + 14844\n18732 - 12718\n14383 + 24873\n25754 / 5261\n10297 + 22617\n(24591 + 3931 + 19366 - 7874)\n30996 * 20215\n(15347 - 32110 + 12569 + 21327)\n18445 * 23727\n4958 * 10158\n18607 * 25928\n25366 / 10028\n18269 * 8323\n18747 + 19518\n1606 + 6505\n4279 + 14173\n13013 * 7654\n27080 - 21411\n(19886 - 14460 - 23393 * 5545)\n(19236 + 25874 - 21928 * 2632)\n19087 * 5073\n(14132 * 1049 * 18234 - 15449)\n(31884 * 24377 * 6460 * 19350)\n2954 - 21515\n(6858 + 24098 - (13405 - 8017 * 14968 + 9772))\n(2911 + 23514 - 9042 - 24136)\n3982 + 10932\n14268 + 31855\n24033 * 11846\n(16499 * 11847 * ((5539 * 16480 - 26779 - 15661) - 8366 * 2789))\n31816 * 6503\n4676 - 8147\n143 * 24806\n20735 - 17906\n16786 + 375\n15878 - 12417\n14242 + 32685\n(24547 * 29167 + 2194 + 17474)\n27875 * 21436\n((((162 * 1960 * (455 + 11746 - 2214 * 13593)) / (17487 * 1493 * 18390 - 4855)) * 12097 - 16900) * (23798 + 510 * 14787 - 25430))\n12604 / 16307\n(8624 + 24016 - (13854 - 24287 + 27829 - 14227))\n24269 / 32514\n2557 - 31111\n27678 - 6083\n11717 + 18887\n15965 + 8867\n31376 * 8796\n27743 * 23458\n(1015 - 30300 * (4306 - 2577 - 8937 + 8741))\n1125 - 26712\n1174 * 22081\n9242 * 17920\n16388 * 31680\n21784 - 21136\n9957 - 15382\n3593 * 14041\n12678 - 18873\n16505 - 10024\n5698 + 18535\n20700 * 15478\n920 + 22790\n14420 * 22237\n12107 + 11403\n21430 + 18800\n9325 * 26309\n28183 - 9752\n2190 - 23382\n19523 + 30851\n(1866 * 30951 * 22303 - 22382)\n4247 - 11078\n(1232 + 18515 * 14479 - 8299)\n22211 - 8316\n(32739 - 22947 * 10005 * 22745)\n11737 * 28653\n28447 + 5023\n26872 + 2941\n(2557 * 4812 * (1770 + 19933 + 12293 + 29681))\n18638 * 19195\n5778 + 26716\n22230 + 11734\n16598 * 20108\n30286 + 5282\n(9611 * 513 * ((6740 + 8634 * (1160 + 20406 - (16563 - 4527 - ((22580 - 22453 + 21106 + 14703) + (12785 + 19763 + (12076 / 20018 + (30199 + 27597 + 20704 * 13503))))))) * 1775 - 25395))\n(27529 * 8457 * 28225 / 15827)\n7312 - 28790\n6769 + 19131\n25419 + 13371\n549 * 20627\n(26644 * 17126 - 15593 + 32131)\n15990 * 22498\n684 + 16460\n21995 * 6991\n(371 / 27120 - 26878 + 28581)\n(13326 + 413 + 1267 - 4944)\n(21246 + 357 - ((4103 * 25541 * 25203 + 21251) + 27004 - 4146))\n11728 * 17214\n319 / 23998\n23070 * 31579\n(19019 * 24801 * 2500 - 11740)\n26366 - 3790\n12660 - 1130\n((12949 + 11645 + (28767 - 1231 * 24617 - 21006)) - 32293 / 21386)\n9065 - 9413\n1096 / 22857\n14056 * 4700\n9295 - 20557\n26142 + 31003\n15717 - 20870\n20968 + 13570\n17599 + 429\n15369 * 26088\n5073 * 19965\n1404 - 25746\n24539 * 6430\n13613 * 32756\n(24833 + 5346 - 32426 + 3856)\n26123 + 23416\n(18947 - 5855 + 29256 - 599)\n20479 - 18081\n4522 + 8800\n25809 + 2455\n16632 - 30619\n7086 + 2919\n2278 - 32214\n(13405 * 12703 + 26928 - 26140)\n(27791 + 14772 + 1559 + 19830)\n4848 * 23253\n1410 / 30666\n17527 * 26253\n30564 + 15118\n(8626 + 26518 - (18621 - 10223 * (12282 + 2580 / 23848 + 6328)))\n451 - 32620\n30144 - 9321\n31899 / 26329\n(3148 * 19923 + 21332 - 3348)\n4349 - 28003\n4115 - 5918\n31332 + 25321\n(3614 + 19108 + 28342 * 7012)\n3320 * 17351\n1600 / 27797\n3626 / 26898\n17434 - 16161\n26913 * 8768\n(13246 + 23579 + (14320 / 7835 + 12803 + 14534))\n1921 + 27693\n((11980 + 18504 - ((12170 - 6015 + 546 + 23630) + 8277 + 15787)) + 537 * 16176)\n15577 * 19102\n9521 - 24035\n10448 - 11871\n15551 * 18719\n18830 + 10365\n31958 * 24568\n1953 * 4579\n15845 + 126\n(12185 * 17065 + 1148 / 1353)\n10363 - 15098\n19806 * 20355\n18118 + 10129\n24610 * 13515\n585 / 22975\n24678 + 14399\n2676 - 11766\n17590 * 25847\n16552 + 23988\n1489 + 17882\n((32331 + 8096 - 23529 + 17376) - 4941 - 18657)\n(23936 - 29849 - 25876 - 14261)\n(23682 / 19848 * 21009 + 27390)\n(16312 + 22647 * 2837 / 10853)\n(31554 - 15017 + 28408 + 26487)\n5633 - 23968\n8697 * 5156\n29884 - 21709\n6306 / 21734\n9842 / 5311\n(3504 * 28257 - 24467 * 20984)\n5189 + 17326\n14650 * 11841\n16049 - 27470\n17670 / 27730\n22293 * 5440\n12949 / 24589\n5928 + 11145\n25882 * 17551\n22155 + 13029\n(26106 + 3886 - (964 + 26010 + 13640 + 20566))\n479 * 4581\n9170 * 13270\n6998 + 25590\n12725 + 15856\n28197 / 25657\n20003 + 8546\n(10525 + 13975 * 8750 * 1259)\n32762 * 10973\n29543 * 27443\n30557 - 18099\n31613 - 6479\n8671 * 14413\n21660 - 18620\n(10741 * 32753 + 12407 * 15271)\n1808 * 4944\n((((17815 * 5424 + 6339 * 17561) + (23648 * 27030 - 23994 + 7522)) * (19640 * 29602 * 19338 + 28110)) / (13639 * 15310 + (((10044 - 26598 * 31429 - 12702) / (2905 + 14404 + (32010 - 15700 * ((1434 - 4330 - 25490 + 30941) * 25784 + 31521)))) + 15002 * 18612)))\n845 + 4511\n8418 + 7190\n(1462 + 18119 * ((27495 * 8053 * 18619 - 19702) - 30816 * 30512))\n15425 * 11069\n14672 + 9297\n18694 * 15572\n(27574 + 23244 + 12920 - 27463)\n((7821 + 14450 + 1966 * 1702) - 9051 * 12134)\n6466 * 32471\n14955 / 20482\n4403 + 5734\n19572 + 12739\n(7234 + 753 + ((5211 * 17650 - 26103 / 23620) + 16947 + 26584))\n11218 * 26778\n28718 + 24611\n32072 + 25471\n7321 + 24895\n31151 * 5230\n9728 + 32705\n(27060 - 22095 * 25833 / 18513)\n72 * 18398\n(22612 + 31474 / 10890 - 2778)\n3960 - 23054\n15532 * 27020\n(28459 * 19811 * 1875 - 4724)\n28622 * 26161\n22610 - 28122\n4721 * 13650\n(1611 * 8912 + 2554 + 7450)\n(29367 * 13573 / 18312 * 10214)\n7226 / 6604\n31594 / 17842\n31654 * 5871\n23098 + 6783\n(6511 - 26998 - 11358 - 26368)\n25266 - 29476\n(4246 - 32407 + (3191 - 6130 * 15358 - 18945))\n(21562 * 32350 + 14385 - 10469)\n23614 - 8858\n21863 + 19633\n1960 - 21762\n24551 + 6281\n(3319 * 9323 * 29906 + 8295)\n28387 * 17494\n7447 * 9018\n24071 / 31548\n30002 - 14179\n27682 + 12359\n(13250 / 17077 * 3154 + 9841)\n((21800 - 15814 * 2308 + 2567) - 29029 * 9685)\n9649 - 5411\n12794 * 26783\n5063 * 4992\n9997 - 15846\n(20168 - 19135 - (30506 - 1557 * 16338 / 7436))\n23081 / 31752\n18710 * 19972\n1943 * 6622\n(27706 + 32093 / 25191 * 860)\n(7501 + 16437 + 22782 + 9783)\n21957 + 4235\n8155 * 4230\n14532 + 6873\n29128 * 508\n23594 - 16833\n19143 * 25952\n22326 * 5410\n(21390 + 28590 + 15463 + 1980)\n(22148 * 19580 + 16470 + 5472)\n16367 + 32587\n30825 * 31518\n4653 * 15404\n1665 + 18884\n((7553 - 25945 * 24794 * 9560) - 10867 + 19033)\n8124 + 4694\n5410 - 15231\n13256 - 18270\n28816 * 16836\n((2604 - 8525 / 15660 * 14706) - 24548 + 2765)\n(16023 * 32152 - (13435 * 16442 - 22803 * 18221))\n15681 - 17451\n((26056 * 25464 * 25966 - 11355) + 23806 * 29907)\n258 * 3058\n(12762 * 15721 + 7662 / 16046)\n19310 - 9578\n28894 - 7966\n10666 - 28212\n29825 - 12204\n30977 * 25481\n32554 * 31556\n(12826 * 19398 * 18365 + 31910)\n(12284 * 14786 - (14982 * 11893 * 21642 + 12870))\n9299 * 27339\n(13420 - 29005 * 19490 - 9303)\n(4644 * 31793 * 6413 - 17907)\n14670 * 24136\n((29727 + 7901 + 28016 * 10083) - 25172 + 12790)\n28164 * 21916\n3799 + 11537\n11087 / 7551\n820 + 22406\n3270 * 19436\n11911 - 7793\n5904 * 11688\n((14029 - 4408 - ((23663 + 28600 - 2910 * 1946) + (9511 / 20360 * (17883 + 16836 + ((25164 * 20533 * 11515 * 12910) + 15285 * 16445))))) - 32722 * 30270)\n8877 * 21833\n5423 * 12930\n1482 + 316\n14638 - 25053\n((32164 - 20176 * 28846 - 9521) * 28731 * 19495)\n18662 - 32332\n310 + 28200\n28860 - 20560\n785 - 16302\n4399 - 23367\n15782 - 2437\n14490 + 19959\n8733 - 5414\n27085 * 2534\n26896 * 4153\n1013 - 7165\n31986 + 4232\n2202 - 14670\n(29781 * 18772 + 24657 * 30945)\n8137 - 30237\n((19328 * 24350 + 2453 + 32731) - ((11773 + 19892 * 21520 * 26241) * (13235 + 15667 * 10644 * 29715)))\n32291 + 28149\n(22255 + 30373 * (11324 - 7055 * ((11144 * 17175 * 570 + 28744) + 23891 / 25957)))\n(5892 / 29391 * 10007 + 18322)\n25905 * 19878\n979 - 5540\n5606 / 25415\n(13598 - 32666 - ((31755 - 18511 * 18780 * 29550) * (6800 / 14787 + (26226 + 18452 - 25383 - 22384))))\n2 + 10050\n28382 + 14858\n(22103 + 17967 * 21049 * 20343)\n(29311 * 13001 - 13755 + 18428)\n2379 + 20706\n(8088 - 14834 + 15234 / 31154)\n27828 - 14796\n2673 + 28663\n(14098 * 32534 - 12483 + 5543)\n6980 / 30696\n32277 * 2507\n(5886 / 27069 * ((6104 + 4595 * (16477 - 31544 + 23102 + 13633)) - 2245 * 9567))\n3121 * 22968\n(8601 + 11039 - 16101 + 20338)\n11422 * 11466\n10952 + 23546\n28261 + 22602\n24025 - 13804\n(1641 - 7995 * 6614 * 27925)\n(5184 * 26375 - 30261 - 21217)\n29840 - 26742\n(28356 * 26308 + 21674 / 12970)\n30449 + 22475\n15529 / 679\n(20718 * 9374 + 18567 - 14614)\n3064 * 32255\n4343 - 17578\n21173 - 17992\n13887 / 6013\n23499 / 2575\n23061 * 13099\n(28913 - 12063 + 26862 + 21110)\n10608 * 28195\n((12729 + 6616 + 12609 + 31069) - 11341 + 8060)\n((((28104 + 6980 + 31214 * 11857) - 12713 * 19180) - 23607 / 16807) * (31597 * 23370 + (24784 - 12348 - 29338 * 11458)))\n25122 - 9327\n6951 + 12438\n29818 - 24337\n29893 - 25105\n23875 / 18326\n25649 - 22515\n30430 * 24701\n32657 - 25552\n26901 * 27453\n20349 + 10682\n27060 - 27204\n3129 / 28953\n(30007 + 11214 - 184 - 3526)\n(7395 - 9941 + 1341 + 22474)\n828 + 29184\n23465 - 11052\n30308 * 11970\n1008 * 25179\n21962 + 13697\n782 + 5523\n12089 * 31086\n(16794 + 13093 / (27137 + 17953 + (8775 - 27587 / 6336 - 27446)))\n8475 + 29002\n(32674 + 216 - 30863 * 27533)\n((26880 + 9354 * ((26035 + 15267 - 18886 * 3439) - ((21083 - 1739 + 3622 - 23119) * (32451 + 28553 - (21738 + 23123 * 6079 - 1244))))) - ((((32746 / 29220 * 9970 * 11759) * 27029 + 28388) * 21810 * 20514) / 24669 - 1040))\n11870 * 26217\n13334 - 20701\n((6893 - 30978 - (19386 - 31918 * 9900 / 18262)) - 25315 + 2156)\n13176 + 25481\n27387 * 15235\n28557 - 28717\n13415 * 6249\n20053 - 24866\n30481 * 25883\n(14379 - 24746 + 16326 * 18279)\n27274 + 11153\n12988 - 21108\n6609 - 32429\n23957 - 20458\n(30574 - 20708 + ((31524 - 9161 * 10447 * 18984) - 11878 / 5905))\n(18839 + 29833 - ((13443 + 30922 / 19358 * 17874) - (13650 / 32237 * 2812 * 23850)))\n(14296 - 27148 * 26926 / 14955)\n24124 * 29251\n20744 * 21237\n9919 + 3056\n3756 + 21734\n28017 * 10961\n338 - 12491\n4933 - 22706\n24431 - 5937\n12189 - 22596\n7041 / 23218\n((27057 * 22826 * 20057 * 23779) * 6578 + 11786)\n12892 - 5214\n12105 - 23132\n17534 - 16077\n28595 + 2114\n(29579 + 14738 / 25140 * 9673)\n2605 - 11173\n(2086 - 3477 - 29358 - 13983)\n826 / 1303\n14583 / 1216\n18396 - 23042\n(23010 - 5718 - 9067 + 21983)\n(((31254 * 1926 - (((5545 + 6323 - ((21525 / 14325 * (476 + 16796 - (1595 * 21980 + ((8246 * 27595 * 22626 - 9264) - 22989 * 1735)))) + 8501 * 25167)) * 29956 + 14177) - 26209 + 29264)) / 4963 * 10423) - (11053 * 11815 - 15868 * 32439))\n(((32466 * 32197 * 27226 * 1321) - 8670 + 21149) / 31187 + 17609)\n15058 + 5871\n(24830 + 21967 + 19596 + 14986)\n(22627 * 2994 * 10605 * 20804)\n(674 - 11150 * 16406 * 19472)\n2301 + 30337\n29417 * 9679\n16097 / 6087\n11847 + 25838\n8283 - 5349\n1796 - 13970\n9363 / 23896\n9867 * 25120\n10433 + 7737\n10187 + 26055\n25488 + 21384\n5298 * 29180\n13722 + 21147\n21174 + 30826\n27979 - 10426\n(7573 + 27264 - 6567 * 11409)\n20730 * 5904\n18880 + 22353\n(12385 - 22939 * (19345 + 31724 * 21665 - 4163))\n19061 + 13089\n2367 + 4478\n27298 * 24145\n((8260 + 28445 + 3912 * 12923) + 31838 * 11376)\n13320 + 14222\n11638 - 18914\n27394 + 26318\n3290 * 20184\n8646 * 14334\n14729 + 23173\n((30710 * 6938 / 22314 + 4193) - 1709 - 10582)\n3439 + 28405\n18663 * 21022\n274 * 4746\n14441 + 12255\n((21 - 19291 - 6158 - 16422) + 30026 / 24826)\n31103 + 7174\n16046 - 773\n(14442 + 7181 + 12396 + 16768)\n25174 + 49\n12519 * 28668\n(10059 / 14647 / 4649 + 26135)\n6702 - 11587\n3832 + 15343\n(30534 / 27145 + 10504 + 28835)\n((23529 - 6581 - 18812 - 27964) * 3787 - 15349)\n19199 - 9427\n11388 * 646\n5685 - 17735\n((((405 - 4558 - 4723 * 3308) + (137 + 27479 - 10551 + 12730)) - 30578 / 16736) - 18627 + 7915)\n(((31634 - 27099 + 16795 - 15594) - (((29865 - 16794 - 10980 + 25331) * (28708 * 3500 - 6218 * 2216)) / 28505 + 2574)) + (6537 * 14511 + 6352 - 16501))\n(17130 * 24061 * 19935 - 4765)\n23833 - 12510\n18779 * 14460\n25739 + 23005\n10446 - 16363\n7140 * 2554\n11428 * 26292\n13621 + 23970\n(((20125 - 6549 + 18733 + 24256) - 2211 + 12607) + 1956 * 8788)\n22622 * 19618\n16757 + 25052\n28460 * 5339\n(16890 - 7222 * 2234 * 19289)\n26909 - 28379\n15376 * 371\n(13554 * 31978 * (5116 - 1804 - 13957 + 30806))\n10372 + 27826\n24916 * 32641\n31950 - 16168\n20986 * 5757\n22725 / 5267\n(32001 - 28789 - ((8831 * 24331 + (12825 * 28010 - 29434 - 28460)) / 19867 * 27423))\n5887 + 22774\n15905 * 19931\n27387 - 19671\n((12390 + 6102 - (27758 + 18343 - (30497 - 7028 * 14118 * 11616))) - 1151 + 10852)\n22899 + 22272\n(12631 + 24353 * 20921 + 6972)\n4696 - 9291\n(12766 - 28591 + 14725 + 12195)\n5479 + 6703\n(5974 * 10706 - (17862 / 1263 * 25836 - 30279))\n13838 * 7020\n29242 - 8217\n4504 * 13688\n(23947 + 32687 / 32373 * 29531)\n4379 + 16992\n9626 - 16061\n18397 + 29015\n25250 + 22344\n(20082 + 11084 * 21194 - 27475)\n(26122 - 9292 + 11815 - 25336)\n(24922 * 23571 * (18034 - 3396 + 25130 * 2648))\n1459 + 388\n(8056 * 25655 * ((26944 - 26557 + 15275 + 15678) * ((15327 / 5453 + 11383 - 28008) * (1524 - 29471 - 32183 * 7517))))\n(1098 - 9028 * 1783 + 12347)\n16847 + 11212\n27124 / 15890\n6761 - 4965\n18835 * 24555\n2104 + 23951\n24691 * 12761\n8799 * 24638\n30087 - 19789\n((4765 - 23682 - 6688 * 23267) + (11076 - 2200 + 10649 - 30311))\n(6258 - 2 * 21380 - 31372)\n4881 - 14898\n32358 * 13537\n24208 * 26212\n(((7034 * 13998 + 24817 * 24473) * 29995 * 14400) - 8613 + 26599)\n6636 - 9448\n24045 + 26439\n29179 * 22970\n16176 + 12119\n(12712 * 7373 - 11589 * 31125)\n(26531 + 12555 * 6642 - 3814)\n(25636 * 32696 - 3392 * 23341)\n22418 * 14155\n(21168 * 26240 * 28712 + 10693)\n23982 * 15097\n2426 * 3685\n((2678 - 25423 * 6496 / 9681) * 13801 * 12890)\n(525 - 7201 * 20431 - 23064)\n701 - 30404\n(21119 * 18222 + ((26958 - 8406 + 20179 - 5987) + 30011 + 16176))\n((18880 + 29905 * 15158 + 14775) + 3182 - 10178)\n(((11874 - 26592 + 11923 / 30259) - 4184 + 23839) + 896 - 29344)\n((27454 + 27360 * 12622 + 9166) - 29076 + 24631)\n15943 + 22322\n32533 + 4429\n25695 * 17773\n19578 * 24490\n29538 - 9646\n24106 * 27955\n27369 + 10268\n15211 - 5358\n3332 - 9002\n11155 + 4742\n(24307 + 15207 + 10163 * 31245)\n27575 + 5364\n1537 * 9246\n29387 - 18321\n336 + 11892\n(2886 + 10846 - 20659 - 20144)\n21799 - 12154\n7203 + 11512\n27161 + 24879\n18249 + 4797\n30442 - 29679\n11709 - 29978\n((31046 + 9122 - (9958 + 12850 + 2044 - 24807)) - 19839 + 28656)\n(23062 + 31459 * 25846 * 5888)\n11049 * 18534\n5862 - 32563\n(11257 * 23311 / 19637 + 19470)\n9707 - 1055\n(7212 - 28243 + 16001 - 15412)\n1023 + 20475\n12016 * 4684\n(22673 - 20094 + 4545 * 9520)\n(26236 + 30837 / 2864 * 1763)\n2543 - 17822\n255 * 1954\n2605 / 17000\n27766 - 3366\n15350 + 31194\n8703 + 18864\n(9852 * 5321 + 6162 - 28622)\n22264 + 32580\n13394 * 16552\n20004 + 3861\n13996 / 17177\n((23789 + 25329 / 1140 + 19355) + 23494 - 15302)\n7797 / 14487\n2471 * 13684\n(2406 * 17487 + (((32421 * 25078 - (6344 * 14358 * 264 * 32211)) + 11261 / 22379) * (26758 * 10784 + 17341 - 6446)))\n22773 + 30665\n858 - 9486\n(((23469 + 8303 * (((16264 * 1590 - 26536 + 8201) / (29728 * 30578 / (168 * 1966 - 29378 + 11821))) - 32622 * 8077)) * (((1308 + 3819 - 11897 * 8964) - (18630 + 6987 - 21478 - 21036)) * 10368 + 12707)) * 31097 + 17125)\n(16546 + 28594 * 5166 + 32245)\n8745 * 23949\n18259 * 3663\n11117 - 30888\n32575 * 30029\n((24374 / 15905 - 27813 * 3295) * 8267 - 28310)\n26454 + 1567\n(1273 * 2002 / (18992 + 14128 * 28485 - 4017))\n12364 * 11880\n(27255 + 30670 * (25721 * 29075 * 21461 - 30082))\n(10629 + 2424 * 26338 + 12158)\n19220 + 11316\n20875 + 24463\n(13569 - 12445 - 12812 * 7982)\n4044 + 16538\n(3856 - 4741 * 23027 - 2416)\n(18731 - 2577 + 20736 / 3878)\n30359 - 5182\n6688 - 17844\n27311 - 22916\n(13847 + 9605 * (5758 + 28947 + ((300 / 31878 + (16104 - 13711 - 16459 - 28169)) + 23790 * 11411)))\n(3504 * 9073 + 15201 * 12199)\n11431 - 16947\n(9303 * 14776 - (3856 - 6538 - (13095 - 28818 / ((21055 * 27527 - (9277 + 29514 + 19140 - 27338)) - 10969 - 5591))))\n7514 * 25114\n14552 - 5289\n8067 * 27719\n312 + 23218\n29722 + 20431\n2715 - 2931\n20200 - 2245\n((((16888 - 4263 * 27355 + 15261) + 454 * 5358) + 27541 * 29061) - 5187 / 18487)\n24449 * 3022\n(22796 * 29831 * 26742 / 20584)\n11593 - 11150\n3135 + 25904\n544 * 1121\n28049 - 20752\n4669 - 19685\n(25144 * 5763 * (14698 - 19622 * 29994 * 18042))\n12499 - 15214\n9255 + 23882\n22471 - 6106\n22698 * 1715\n30087 * 415\n21006 * 22418\n1830 * 16556\n(4497 + 5252 * 13340 / 22688)\n((24885 - 19399 - ((20135 * 2275 - 31577 * 8431) + 31297 - 16208)) - 5058 + 17374)\n19582 - 5282\n30059 * 134\n((28934 - 28607 - 30172 + 6589) * 8590 * 3370)\n((19270 + 8587 + (14499 / 1672 * 21492 - 18016)) - 31883 / 8446)\n(1840 - 27840 + (23139 + 26065 - 17223 - 23088))\n(27780 * 13325 - 14294 + 23130)\n(11426 * 31630 - (30451 * 18131 * ((358 + 5637 - (2629 / 19010 + (605 - 14422 * 10434 - 1305))) - 26437 - 27759)))\n(6166 - 25334 * 28468 / 32524)\n5613 * 6947\n10071 * 2405\n14151 + 9186\n13196 * 27060\n22451 * 28081\n((11259 + 1435 + 21907 * 2418) - (1716 + 26643 * 11452 + 6254))\n12680 - 19976\n((20599 - 9698 + 31985 / 4852) + 2098 - 3358)\n((23657 / 8736 - (7232 - 31958 / 6445 + 2058)) + 6783 - 15329)\n(13068 * 23697 + 11033 + 19662)\n1475 * 3511\n(27817 + 26531 - 16738 * 5032)\n22176 - 18505\n32443 / 14026\n(15137 - 29468 * 32756 * 19295)\n13952 - 12184\n24793 - 18072\n7534 * 9949\n22088 + 5085\n((395 - 25798 * 654 + 11928) * 1511 * 2064)\n6342 + 25495\n((1357 * 31453 * 23862 - 10371) - (6570 + 9205 * 21384 + 25769))\n31325 + 6091\n6958 + 7891\n10972 - 18505\n((12830 * 24502 * 5657 + 14117) - (5869 - 16382 - (18269 + 23960 * 26144 * 29532)))\n4698 - 13500\n1745 * 32077\n(9086 * 23037 * 32278 * 6468)\n6074 + 21648\n23359 + 21429\n5847 * 28971\n31858 * 663\n19483 - 30553\n(974 - 59 / 31892 + 7331)\n3988 * 27910\n17465 - 25627\n8289 - 8336\n4445 - 7818\n10995 - 22994\n9970 - 11074\n7073 * 11028\n28011 * 31816\n4577 - 15229\n28217 * 12243\n9739 + 30750\n2985 / 29630\n26128 - 17954\n24183 - 32740\n15425 * 26070\n15719 - 9380\n32607 - 24075\n20496 - 8678\n(19962 * 14786 - 28988 + 18514)\n5842 * 29945\n13377 - 12607\n13255 - 5346\n23644 - 30339\n11576 - 26896\n21168 + 9599\n((15099 + 10230 + 12611 * 25484) + 25397 - 14604)\n(6863 + 32014 * (12305 / 23629 + (30247 + 21319 * 14477 * 13592)))\n(11470 - 4917 - 30861 * 32745)\n4309 * 31733\n(3847 + 12425 * (26272 - 1140 + 14531 * 27374))\n17344 / 17562\n(6953 * 29424 * 1294 * 23124)\n766 * 5114\n26586 - 11277\n31972 * 4422\n872 + 19147\n1718 - 27239\n4623 + 6734\n29100 * 9406\n(23064 + 26051 - 13912 * 1116)\n1834 - 25919\n16914 + 25517\n18487 + 22865\n3166 * 6601\n9872 * 20389\n29524 - 22899\n8819 - 20468\n24005 + 17676\n30969 + 17382\n29 - 19786\n22590 * 15793\n1903 + 13642\n9457 + 17751\n(16042 - 4792 + 19096 * 17982)\n18226 + 9445\n9149 * 2727\n4560 - 2109\n7412 * 2181\n31579 + 20111\n(1014 + 20714 * 18373 - 13421)\n(25450 * 26963 + (((5840 / 31841 * 27705 * 32729) * 15062 + 23543) - (8693 * 1167 / ((8035 * 6142 / (9697 * 26235 * 25286 / 2681)) * 1617 + 14413))))\n2256 * 22858\n(4483 + 23955 / 26532 * 18656)\n(31391 - 31067 / 31697 * 594)\n6119 * 24342\n27205 - 6984\n18598 * 16236\n(831 - 9276 / 32624 - 28337)\n11939 * 5706\n25280 - 5176\n(25202 * 29466 - (12006 * 25619 + ((28339 - 22047 + 3552 * 12200) + 24894 + 28111)))\n8906 - 30152\n14169 / 25827\n(24616 + 9388 + (2411 - 23203 + (30096 * 30872 - 22872 + 7)))\n2192 * 1783\n7614 * 1295\n20133 - 27877\n14254 - 7374\n(9634 * 17548 * 20601 - 19436)\n24881 - 9360\n(26040 + 18638 * 26570 + 29811)\n28022 * 26380\n(27662 + 18000 / 16986 - 6270)\n(24709 + 12098 + ((25719 * 13378 + (8999 + 21951 * (9432 + 24624 - 11128 + 30383))) * 2759 / 7740))\n6848 + 17924\n32089 - 22056\n(15612 + 24917 * 27558 - 31724)\n(3158 + 31382 * 18370 - 28495)\n28259 - 337\n13968 / 6235\n4631 * 22711\n(18877 * 5471 * 14796 - 15927)\n1898 * 28226\n707 * 16068\n((((8833 * 27581 / (26477 + 10794 - (8288 * 9274 - (4867 * 30611 / 32047 + 23619)))) + (19188 * 1041 * 22391 + 30474)) / ((6120 - 15323 / (5168 - 25424 * (31967 + 6247 + 15527 * 4928))) + 22331 * 28394)) * (15536 + 16032 + 16333 * 1239))\n17542 - 28534\n19193 * 29744\n16426 + 2694\n32554 + 31785\n((1189 - 20138 + (25249 + 15031 / 11463 - 485)) * (4879 - 3954 - 751 + 5887))\n31244 * 10218\n1623 * 7920\n7386 - 7258\n(16333 + 27837 + 1254 / 20356)\n(((2522 - 28272 * (10163 - 21253 * 14666 / 24696)) - 26745 - 17891) * 2988 + 19152)\n12982 - 27127\n(11637 - 24656 - 915 - 7971)\n1240 * 20968\n32091 * 13190\n((21807 * 26762 - 24776 + 25818) * ((5953 + 18272 * (12197 / 13948 * (25357 + 31210 - (1877 / 32059 + 1063 + 2384)))) - 12198 * 289))\n28899 + 13666\n16751 - 18827\n(13102 * 5377 - 16298 + 11671)\n16441 - 1332\n1235 * 53\n696 * 24888\n16673 / 5207\n10541 - 8448\n32666 + 6754\n(17020 + 19898 - 31634 + 19911)\n28157 - 23495\n6535 - 31204\n8475 * 17680\n2940 - 25221\n5817 + 16579\n(9332 - 21800 - (27986 - 21326 * 29058 * 8937))\n((((1661 - 17260 - 23553 * 7423) + 12152 * 2690) + (4096 - 9656 + 29657 * 249)) - 23200 * 26401)\n5278 - 12527\n5968 * 28572\n27517 - 321\n15864 + 20943\n8122 * 31932\n(26201 - 22080 * 9861 + 439)\n119 * 4103\n31424 * 32419\n28645 + 25475\n(24844 + 12639 + (1525 * 20567 + 30361 * 10717))\n2855 * 7210\n16560 - 22092\n(29712 - 19399 / 25051 - 10626)\n5589 + 4966\n14942 * 24844\n(15727 - 7325 - 20797 - 26383)\n19791 + 4453\n27680 * 9708\n14167 * 5121\n32235 - 6619\n12173 + 9700\n(9313 + 19905 + 7204 + 17001)\n27134 * 18884\n8027 * 26171\n(8311 - 26766 / 10898 + 12398)\n1998 * 15471\n14825 - 17626\n14454 * 21617\n13704 - 6100\n(((24428 + 12541 - 738 / 20978) - 21639 - 22120) * 22948 - 21529)\n5961 - 19555\n(19253 / 5915 * (10644 + 22787 * 26754 - 18861))\n(28457 + 12120 + 26129 - 178)\n1894 + 30266\n27866 * 828\n2732 + 15857\n(((31787 + 22566 + 31657 * 31952) / (12733 * 6332 * 842 * 6228)) * 11583 - 22902)\n(20130 + 24634 - (9292 * 1719 - 17222 + 2248))\n1941 * 17206\n912 * 20190\n24649 + 3847\n9722 * 7140\n23683 + 8365\n9478 - 3515\n689 + 9582\n18773 * 14671\n18572 / 24552\n18119 + 18444\n28296 + 23531\n(26361 - 22440 + 17167 * 25481)\n(27060 * 363 + 21671 + 7109)\n11944 - 7164\n12528 * 27598\n5434 + 11503\n10868 - 8124\n2645 * 7799\n1722 * 10976\n(23606 * 11216 + (13129 + 19262 + (18840 - 29932 + (3649 + 19369 + 27754 * 7019))))\n(7703 - 30560 * 23942 + 6599)\n(24728 - 4501 - 27056 + 14484)\n8015 * 2531\n((29888 + 32070 * 32324 - 6578) - (31544 * 22868 + 23258 / 15733))\n6883 + 24013\n19772 * 28410\n1148 - 30509\n19104 - 16729\n6282 - 29807\n18365 * 10533\n8150 + 23345\n(351 - 16906 * 30151 * 26064)\n823 + 19266\n(30837 + 20414 * 28920 * 27923)\n24276 / 11838\n17566 * 30265\n10157 * 7455\n(26604 - 6251 + 747 / 30219)\n18038 / 4783\n(19643 * 15447 - (8425 * 3013 * 11769 - 3604))\n31271 * 18561\n27759 - 599\n28478 * 6783\n14332 * 21031\n(((3788 - 3544 - 28133 * 28674) * 32595 - 2530) + 16712 * 27223)\n(11178 + 6920 + 2541 * 14032)\n20498 - 7024\n12980 - 25451\n14191 + 27507\n14151 + 15512\n5797 - 4791\n10325 + 25538\n18786 + 2580\n31102 * 18414\n10843 + 23554\n25071 * 31730\n(13372 + 6795 - ((32704 + 3222 + 9248 + 30136) - 25007 + 8086))\n(3678 + 20638 * 1011 * 5583)\n17899 - 8228\n(13418 - 1362 - 5235 + 14148)\n2411 * 31001\n18784 / 24548\n31394 * 1263\n29999 + 9166\n(6132 - 4073 - 2028 - 4790)\n7997 * 2312\n4317 + 15358\n26122 * 25170\n(25780 / 7018 * (25111 - 27553 - 8747 / 12692))\n5064 / 16176\n16808 - 19610\n28307 - 31636\n26777 - 13444\n223 - 6826\n3197 - 8883\n16463 * 25142\n5421 * 11069\n21039 - 21571\n15109 + 22095\n5439 + 8019\n25901 / 26123\n19845 - 7844\n17041 + 9487\n28640 / 28419\n14351 + 20068\n16752 + 17102\n((24357 + 31017 + ((4456 * 30118 / 16777 - 2424) * 3978 - 24662)) + 11204 + 2217)\n1066 + 15496\n30671 * 24549\n12922 - 2086\n10529 * 21710\n20972 - 29578\n(31760 * 24687 * 11341 * 26580)\n20324 * 12756\n31661 + 28205\n(18731 - 7736 * 28431 - 21135)\n20917 + 19103\n3406 + 7966\n7534 * 31368\n19871 + 17052\n16838 + 10963\n2359 * 19610\n31432 - 18528\n21441 + 30152\n((17637 - 8361 / (21732 + 982 + 24549 + 4523)) + 25558 * 3919)\n31411 + 11381\n16038 * 24212\n(7775 + 16726 * 7122 * 17869)\n27609 - 19562\n14531 * 12318\n2678 * 4650\n(7169 + 11090 * 20945 * 25443)\n29153 * 20270\n(24337 + 4183 * 19419 - 12133)\n21506 / 15669\n(9232 - 4643 + 2343 - 8961)\n14698 - 13938\n(24629 / 5881 * (21277 / 31193 * 13427 - 9330))\n9686 + 14853\n((4466 + 21943 + (11814 + 1748 + 24824 * 1981)) + 30604 * 7780)\n29393 - 23207\n28236 * 9696\n2400 * 2473\n7264 * 23898\n31706 * 26448\n30535 + 17353\n17097 + 1056\n2334 - 9042\n11357 + 31695\n(((10024 + 24455 - 16763 + 14330) - 13555 * 22913) + 2228 - 10293)\n19132 - 21108\n6395 * 5565\n3996 * 2978\n17585 - 12259\n14158 + 19303\n(1598 + 22546 + (26447 / 6922 - 22753 - 28975))\n23080 / 9730\n(19795 - 14146 * 7185 - 858)\n(24893 - 17123 - 4062 * 18921)\n(7104 + 4975 * ((((13253 - 25859 + (4323 - 18936 * 29866 * 26941)) - 20165 / 26441) - 28710 * 9783) - 12806 - 13874))\n(6520 * 18478 - 21920 + 32607)\n(11772 + 27356 - 10274 * 14626)\n4534 + 29509\n5761 + 10475\n((11821 + 28237 * 28039 - 24336) + 27579 * 22482)\n25582 * 16022\n(25492 - 2859 - (20872 * 22837 * 24619 - 10766))\n(7690 * 23202 * 18395 + 29066)\n28193 - 12334\n23940 - 14163\n(((21721 * 17613 - 3227 / 32556) + 18807 - 23919) + 3502 + 19132)\n14588 - 16541\n25182 - 11297\n13890 * 5626\n22023 - 24580\n16903 + 17668\n18027 * 15080\n4907 - 16269\n19749 - 32524\n26395 + 9617\n30514 - 23237\n26887 / 18871\n(19294 * 21568 * (2860 - 27919 * 3786 * 16819))\n6941 * 23453\n(4866 / 4966 * 18006 - 14417)\n13719 - 30553\n12919 - 19781\n(26161 / 4185 * 24009 * 14066)\n((14065 * 11412 * (8201 / 12317 - 31831 + 22032)) * 15860 * 13136)\n31058 - 4040\n4566 - 17823\n26743 - 18153\n31609 * 28133\n24833 - 8563\n26439 * 30267\n20051 * 12697\n30250 + 2800\n(8962 + 10624 * 4968 + 10135)\n30476 * 31983\n18630 + 10024\n(32567 - 29912 / 6025 + 28970)\n14103 + 1951\n9576 - 30456\n2809 - 25941\n10919 * 24480\n13891 - 29427\n23341 + 20547\n(5996 - 11479 + 24523 + 10332)\n23147 * 28300\n4436 - 19992\n(2742 - 25798 - 28169 + 12898)\n24562 / 10545\n((32697 * 2079 - 16870 + 9132) - 4144 - 2210)\n29797 * 4442\n25775 + 24556\n8457 / 26179\n23494 - 29648\n28749 + 24368\n26717 * 27604\n3030 * 17269\n8029 + 116\n1445 + 10186\n28527 - 28886\n23324 - 4332\n10772 * 23853\n(15683 + 28967 * (30552 * 26911 / 3585 * 6109))\n10771 * 17998\n9461 * 30867\n26580 / 1879\n20792 - 22381\n10642 - 13918\n20973 - 7368\n25827 + 29145\n30186 + 19770\n27515 * 18186\n3210 * 22285\n((((27335 * 22535 / 23874 * 28866) * 28305 - 20914) + (15362 - 13152 - (14981 * 28215 * 22310 + 28425))) - (664 + 4023 / 1836 - 20481))\n102 - 26398\n10395 + 29659\n10139 + 2479\n29296 + 9973\n7720 - 32589\n27250 + 15986\n(16427 + 2124 + ((18761 * 8882 * 22057 / 6973) + 8067 * 14187))\n19926 - 22264\n32328 - 13990\n4686 + 14607\n7780 * 25561\n29452 * 12096\n(9325 - 29896 * (20730 * 30979 + 25523 + 32173))\n11325 - 7512\n31111 - 16552\n19436 - 2136\n8515 * 16266\n1727 + 31835\n21481 + 28642\n((((8674 - 17911 * 29544 + 19815) + (29604 + 1015 * 25372 * 25742)) - 13699 + 26829) * 17900 * 6356)\n3430 - 13526\n26895 - 6402\n10823 / 7036\n10199 + 3708\n16289 + 19849\n(21120 * 28306 / 30743 - 11759)\n3263 - 13842\n22807 - 21374\n27784 * 14240\n7760 + 12716\n27071 + 11630\n701 / 12882\n9965 * 10791\n16018 - 5049\n9910 / 15747\n(14078 * 26662 + 12181 - 3907)\n32742 + 12792\n15343 - 26993\n15945 / 23253\n19343 + 1437\n31851 / 29737\n17383 + 10980\n9340 * 15432\n12929 * 6766\n(31008 * 29275 - (((12603 - 24822 * 15850 + 12346) + (8315 * 22484 - (27504 * 8165 - 10872 + 24063))) * 10262 / 15090))\n1332 - 1667\n15398 + 30389\n30148 * 22937\n14780 + 17453\n31014 * 25555\n14968 - 18077\n14007 + 25043\n(26994 - 28644 * 10841 + 27618)\n23174 - 2298\n20448 * 9384\n11502 - 27050\n27931 - 7509\n4210 * 4437\n5284 * 7007\n((12714 * 5494 - (18875 * 21719 * 21107 - 10725)) * 18572 - 23911)\n9037 + 31000\n16620 * 5894\n21514 + 5598\n2203 * 31104\n1478 + 757\n4420 - 31842\n(615 * 10264 + 10757 - 852)\n13852 - 3532\n18165 - 19466\n22177 - 19858\n20052 * 28692\n(27488 - 18330 * 26626 * 30048)\n9702 - 11384\n(((1988 - 430 - 30156 / 15872) * 830 * 29847) * 14999 - 8494)\n176 - 30432\n(6887 * 13194 - 19750 - 18315)\n17130 - 15028\n13420 - 13619\n18508 * 29569\n(26579 * 8461 * (7535 + 19712 + (21210 - 22921 * (10591 - 6766 + (30664 + 22332 + 14602 * 14473)))))\n19325 - 1675\n5345 - 1477\n29415 + 15127\n6703 * 5668\n((29072 - 8097 - 27082 * 8784) + 135 - 19319)\n31152 + 3665\n24020 - 15481\n5564 + 29952\n(9293 * 29098 / 2286 - 31358)\n4405 + 1186\n(((10388 * 10801 * 30179 - 24843) / 5245 * 12356) - 31398 * 25376)\n25674 + 30233\n(1100 - 3569 - (26905 * 24663 - ((28257 + 5127 + 22641 + 28980) * 16366 - 8108)))\n(3561 + 4651 + (2106 - 27679 - (1429 + 1730 - ((20839 * 12208 + 598 * 29572) * 13025 + 27671))))\n4574 + 30052\n4142 / 13532\n25802 * 27606\n30373 - 320\n25762 * 30656\n7820 * 6975\n(30169 - 11629 * 5608 * 20073)\n(((14638 * 5915 + 21545 - 19746) + (12731 + 8327 - 21002 * 14547)) + 9941 * 19949)\n(11995 * 25773 / 31611 + 5109)\n(19536 * 22080 * 17097 * 716)\n24172 - 11023\n7690 - 8468\n(24533 * 4112 - 13782 * 31225)\n29775 * 2767\n21676 * 8390\n14438 - 13190\n((31108 - 26959 / 16200 + 28520) + 31214 * 12886)\n(9265 - 14362 + (580 * 9981 + (14857 - 19104 * 13530 - 6824)))\n16745 * 9141\n31426 + 26053\n26195 - 19825\n8726 - 26170\n12242 + 13857\n1022 * 11022\n28619 * 25038\n5881 * 23454\n23695 - 32398\n(20761 * 15322 / 23690 * 31935)\n3611 + 12121\n5380 - 14427\n6114 - 24236\n1247 * 25864\n(13887 - 5592 * (4312 + 21597 / 10040 * 11482))\n22785 - 27740\n4308 - 4278\n6481 + 11726\n31022 - 13092\n9047 + 1709\n18909 - 19486\n25210 * 4616\n14501 * 6202\n26522 * 26827\n(13279 + 7629 * 27289 / 17023)\n22024 - 13748\n14501 * 28118\n22594 - 23838\n17687 * 3221\n2403 * 25913\n28165 + 8297\n12311 - 2803\n11448 - 32508\n(28269 * 8013 + 30585 * 21287)\n28783 - 29007\n1881 - 20016\n25905 - 28095\n(16727 - 19269 - 15119 + 29478)\n18756 * 17656\n20541 + 10993\n32543 + 9181\n21998 - 636\n5672 + 22119\n20252 * 31122\n(10820 + 662 * 15881 * 26554)\n13591 + 28392\n22240 - 20233\n29478 - 21869\n((32397 + 19744 - (27301 * 8892 - 29394 * 23494)) - (7903 * 3541 + 23572 - 22308))\n24210 + 19866\n10032 - 11133\n19333 - 28644\n25322 - 31159\n29017 * 351\n23810 * 12700\n1090 * 10977\n19394 + 20257\n24888 - 6006\n30232 * 5265\n11271 * 14902\n((23321 + 9131 - (((21884 * 7343 * 13795 - 1415) - (4426 + 10207 - 30226 * 23508)) + 11730 - 24170)) / 16451 + 19430)\n24559 * 27951\n1124 + 15313\n30854 - 28931\n4922 * 22613\n1729 * 10877\n(5833 - 15992 - (9735 - 4728 - (1139 + 30348 * 14049 - 7464)))\n25115 - 27366\n(((22162 - 7392 * 17380 * 1556) + 7058 * 27892) + 24354 - 6930)\n(25694 + 3678 + (22898 - 12651 * (25472 + 16463 * 6415 + 22387)))\n14347 + 30654\n((32539 + 29490 / 23028 * 17309) + 14921 * 21078)\n20607 * 12279\n15236 - 29023\n9753 * 22149\n3311 * 7566\n15218 / 8102\n((6739 + 21331 - 17175 + 9605) - (4457 * 11328 + 22981 * 9565))\n(25473 * 16081 - 31992 - 1063)\n(15565 - 25420 - 4944 * 21978)\n31334 + 26461\n10581 * 24414\n19135 - 28915\n7730 * 20370\n(17365 + 12878 + 3393 + 12475)\n19761 - 29983\n12059 - 24993\n17970 / 9803\n6267 - 18914\n23087 + 3323\n17021 - 168\n21757 + 17415\n12500 * 21763\n(16280 * 3899 * 25182 * 23786)\n7247 - 3410\n10960 * 29305\n((458 + 3224 * 21735 + 1222) + 16370 * 6141)\n19439 + 18296\n1655 - 9832\n25114 + 23706\n17052 * 7163\n12879 / 28848\n12722 + 8694\n18612 + 12154\n8028 + 32062\n3232 + 17703\n32584 + 13099\n20099 * 26319\n3278 - 15642\n19450 + 21020\n18967 + 16950\n(7414 + 10764 * 29788 - 13047)\n12377 - 27660\n4541 + 8247\n4584 - 9922\n7837 - 28612\n(6876 * 23871 + 30503 * 12159)\n182 * 11073\n10182 + 29\n14636 - 10769\n9411 + 14995\n4998 - 8659\n(15508 / 11393 * 19880 * 21125)\n20121 * 27997\n14617 * 23650\n16163 * 9895\n((10638 + 2214 * (((12963 * 12357 - 10087 / 2331) - 31383 + 27065) - 9917 * 5902)) * 2973 - 27691)\n15375 * 12529\n29265 + 11381\n(17446 - 17597 + (25137 * 22701 - ((30014 + 32738 - 27519 + 19667) + 23797 - 5309)))\n5753 - 3257\n9092 * 1511\n(29740 + 18932 - (13923 + 3680 - (17971 + 30245 * 28792 - 28017)))\n13930 - 766\n(23463 - 11121 - 25430 - 19928)\n16847 * 17522\n32123 - 10071\n(21421 * 11391 - 11908 - 22281)\n22442 * 10028\n27384 - 24499\n10156 + 21425\n7338 * 27686\n20750 + 5689\n(5286 + 26953 + 5347 + 13594)\n(9179 + 6316 + 11059 + 25914)\n35 - 608\n11277 - 15812\n891 - 23134\n18510 - 22786\n25704 * 23636\n24663 * 4043\n23634 - 28834\n4992 - 12282\n28191 + 14060\n14109 / 14496\n(16101 + 19792 * 9254 / 3072)\n17195 + 12684\n944 * 31147\n29586 - 16913\n683 + 23634\n16925 - 2352\n23216 + 26389\n22729 - 23141\n8806 * 16036\n(22625 * 7387 - 19066 - 11355)\n29599 + 24443\n19052 + 30793\n5920 - 10990\n5013 * 26864\n21582 + 26270\n9729 + 20887\n14649 * 27939\n17995 + 3424\n13601 * 15144\n5436 - 25310\n24788 + 13720\n423 * 12056\n29705 + 14972\n21243 * 26951\n2243 - 17427\n9515 * 6783\n28640 * 23670\n((12775 * 22511 + 24858 * 25021) - (13978 + 28179 + 23486 * 31850))\n15863 + 4751\n25126 - 11536\n31573 - 19973\n21982 * 1663\n(25823 - 24191 - (28561 + 31267 - (25539 * 25097 + 30201 + 19407)))\n11847 - 4248\n(((3932 + 17237 - 26637 + 20587) * 31532 - 23153) - 25454 - 21761)\n23603 * 5735\n(9459 - 10037 * 6472 - 16000)\n21139 - 18090\n657 * 27839\n11707 + 9606\n5711 - 18302\n5816 - 30662\n8642 / 21587\n18353 - 10878\n14333 + 3698\n10372 + 22167\n10475 - 458\n5736 + 9369\n8703 * 4376\n((28208 * 7289 * 26655 - 5662) + 24904 * 30328)\n8691 + 13503\n2943 - 4550\n32153 - 27707\n(3060 + 27592 - 13731 + 10245)\n2238 + 1345\n300 * 24468\n22195 - 31140\n(24806 + 9083 * (30043 * 29797 / 3908 - 1865))\n((18121 + 18260 * 25471 * 17865) + 28053 * 4967)\n(32477 * 32040 + 6667 + 9442)\n1499 + 30257\n(((16957 * 25546 - 24942 + 3567) * 12348 + 29790) - 18396 - 30576)\n1961 - 30310\n5259 - 9103\n15883 * 21868\n25984 / 15270\n10524 + 25229\n2014 + 27829\n6709 - 21290\n((16454 * 24775 + 28250 * 5975) - 7787 - 32236)\n2496 - 27659\n9043 + 4607\n(((30098 + 30979 * 3245 + 3227) * 28028 * 12955) + 1836 * 30858)\n(5500 - 29903 - 7342 + 8605)\n25814 - 830\n6738 * 22516\n5438 - 3492\n29069 - 17952\n11474 * 14160\n9871 * 22561\n1975 + 16828\n21828 - 22138\n(26861 * 415 - 29934 - 1031)\n24903 - 29503\n13513 - 10646\n31580 - 11714\n21454 * 26345\n12014 + 9187\n11092 - 8189\n27478 + 8282\n9205 + 16521\n13737 + 2238\n8300 - 22753\n29447 + 28387\n253 / 25338\n4825 / 11437\n28987 - 9305\n17653 * 12073\n20301 - 1031\n16701 - 30425\n(24034 + 9730 + 20121 * 25155)\n12960 + 32630\n6811 + 6518\n11284 - 13203\n(29358 / 12921 + 1783 + 1859)\n(4652 + 20611 * (5302 + 28479 + 13253 * 1128))\n23202 + 12862\n((13683 + 23129 + (4008 - 22710 - 16973 * 31402)) * ((16881 - 25718 + 25701 * 14824) * 27657 * 31773))\n7986 / 26940\n((15994 * 22117 - 9865 + 27838) - 482 * 19353)\n25987 - 5434\n12534 * 5643\n(6324 * 15071 / 25437 + 8321)\n20207 / 4585\n22985 * 28510\n13712 * 202\n(24393 + 22717 + (13783 + 30986 + 7236 * 22018))\n24118 + 20976\n2643 * 28067\n16292 - 27264\n31434 / 17625\n(((23148 + 29973 - ((5523 * 32668 / 24250 - 17630) / 2091 - 7159)) * 6309 + 30505) - 4987 * 18486)\n28299 - 21972\n((24444 * 22030 * 28721 + 2053) + 23783 / 6183)\n(15564 + 5098 / (15574 - 31277 - (22540 * 24047 - ((19011 * 14576 * 14602 - 23752) * ((7377 / 32426 + 24717 - 21917) - 14657 + 13193)))))\n(1326 / 10834 * 5248 - 27425)\n27005 / 25622\n26980 - 8793\n2376 * 24099\n((10229 + 10982 - 19048 + 11393) + 15549 / 11044)\n1221 - 24057\n8841 + 6740\n15818 - 9291\n169 + 10323\n(23650 * 15065 - 14150 + 30112)\n(4545 + 32283 * 7659 - 4576)\n26061 + 20922\n6857 - 1358\n6592 - 10004\n8396 - 13291\n25844 - 13081\n22699 * 30304\n23477 * 28440\n4330 * 3144\n20780 / 9383\n2103 - 1875\n(2491 - 31809 * 125 + 16353)\n17520 - 23905\n17503 / 20203\n1685 * 28075\n10123 + 12902\n(26090 + 12512 / (14195 - 11441 + 29199 + 24799))\n14888 * 32407\n29701 - 8458\n7471 - 10431\n(9776 * 14457 - 21814 * 24062)\n(9562 * 21810 * (26022 + 15228 - (19683 + 16854 * 27500 + 31676)))\n26265 * 17347\n24745 * 22233\n26466 + 30123\n852 * 29027\n(32070 * 32589 - ((14533 - 23965 - 10169 + 19508) + 24381 / 9632))\n(14599 - 32347 + 30675 / 28983)\n((23672 - 21287 / 6644 - 18405) + 12039 + 12458)\n1159 + 556\n4055 - 4179\n(28659 + 17552 + (26166 + 1640 + 2622 / 7973))\n21947 * 10448\n21465 + 31178\n((15316 * 32538 + 13401 + 2144) - 22180 + 12607)\n15671 * 22125\n(((24883 * 14310 * (26778 * 11041 + (31149 - 21648 + 29078 - 23864))) + 19809 + 10920) / 3080 * 29191)\n17420 + 2975\n(29987 + 7293 + (30221 + 15648 * 10697 + 30560))\n(26763 * 8273 + 4149 + 18963)\n6493 + 29595\n14373 - 5063\n((20465 - 6167 * 27036 - 6405) * 16796 + 9429)\n2251 + 24301\n((28114 - 15626 * 29327 / 4815) + 27248 * 11913)\n7636 + 16631\n2559 * 30800\n(12850 + 17345 * (18982 + 12763 + 30356 / 4452))\n30463 + 4346\n(15879 + 14974 * 7766 * 29939)\n20274 - 19303\n1566 * 17175\n1361 + 5243\n19471 - 8533\n12379 + 16916\n30361 - 26006\n29165 * 6932\n6906 - 5229\n((21314 - 17599 * 3337 * 26726) - (7609 * 20608 + 28366 * 29110))\n3478 * 18588\n31087 + 32260\n32495 - 6036\n11398 / 30234\n8533 + 7633\n(21135 + 13963 - 30987 - 6806)\n13569 / 23664\n((14697 - 13762 / 7376 * 25895) + 8743 / 27260)\n11605 * 1891\n(19283 - 32048 * 19075 - 31914)\n21380 / 25729\n(27204 * 19254 + (9060 - 20914 * (4070 * 32112 * 20992 - 2713)))\n16299 + 15077\n2868 - 16367\n13171 - 29603\n(11378 * 27436 + 2537 - 9398)\n24107 * 10438\n(28915 * 1659 - (28059 - 32556 + 24740 + 1262))\n5379 + 22782\n3463 - 26027\n((22134 - 9763 + ((8793 + 11542 * (12878 / 14620 * 14877 / 22868)) + (27284 + 5168 + 32055 * 1089))) * 32250 * 30160)\n31527 * 9658\n27331 - 6848\n13432 - 31803\n1478 / 16142\n28821 + 18445\n32640 / 13102\n30979 * 17795\n(3117 + 467 * (13176 * 32081 * 20533 * 22086))\n(18935 - 28547 - (19365 * 37 * 4644 + 4173))\n20443 + 29748\n27036 - 26270\n2001 + 1196\n22910 - 6690\n(19429 + 15181 - 18628 + 8936)\n24031 - 31843\n(28110 - 5036 + 29469 + 4945)\n101 * 11581\n119 + 4482\n(11306 - 7567 - 26292 - 9655)\n((5755 - 15902 - 17307 + 24074) + 11623 - 3061)\n18805 + 4245\n1268 * 4408\n27682 + 30358\n31444 / 10657\n29192 - 24913\n(1704 - 15388 + 11530 + 5358)\n18238 * 28335\n5507 * 30835\n30283 + 29779\n8351 - 1668\n25061 - 26249\n29068 + 8111\n23130 + 3648\n((9469 - 14075 * 13759 - 26200) - (21658 * 7136 - (((28923 * 575 * 24460 / 30622) * 6995 * 14314) / 8093 - 6000)))\n24646 / 1807\n6957 / 6035\n21242 * 1912\n14850 + 14009\n22104 * 14690\n17044 + 13300\n10773 + 18525\n(17424 * 2968 + (31031 + 4658 + (2135 - 14563 + 22357 - 10348)))\n16825 + 24356\n22124 - 16346\n7797 - 19163\n((401 * 9846 - ((15458 - 19852 * (12394 * 20261 + 26940 / 4231)) + 31650 + 3153)) * 21700 / 31123)\n8398 + 1057\n(14566 + 2772 - 12779 - 8961)\n29754 + 11904\n10919 - 10018\n((22616 + 17173 / 8350 + 14226) + 17194 * 30517)\n29617 - 30630\n2858 - 2348\n5640 / 9388\n27098 * 29757\n24768 * 1304\n18455 * 21015\n4208 - 22271\n27608 + 3641\n29947 / 11066\n24883 * 22329\n25558 + 3551\n13777 * 26802\n21091 - 20813\n(((27141 * 5443 * 1596 * 20552) * 30867 - 18993) - ((((6645 - 14050 * (28802 - 25244 + (14496 * 24902 + 16608 * 25640))) + 24707 * 3643) * (22412 - 9669 + 19100 / 10759)) / 9891 * 30690))\n(6911 * 30171 / 17231 * 14921)\n2548 - 18959\n15537 + 4902\n(17197 + 32627 + 27580 + 25)\n(12198 * 289 * 13480 * 30803)\n27065 + 20537\n(14915 + 10490 * 3721 * 1970)\n31235 - 30886\n3716 + 27120\n30865 - 3575\n(((5447 * 18142 * 29513 - 3225) * 1700 * 27150) + (((10935 - 26800 + 1345 - 30628) * 23067 + 2409) - 18144 * 22073))\n(((4789 + 29008 - 30397 + 5752) / 2133 - 29212) + 7743 - 8384)\n18189 + 79\n3727 * 29520\n(16436 + 27421 + ((17444 + 25611 / (13618 * 30449 * (20325 / 7438 * 3408 * 527))) + 19079 * 2341))\n((26560 + 10309 - 27487 - 1510) - 28903 + 10336)\n(9267 - 6439 - 13842 * 30768)\n4002 - 30163\n29334 + 2864\n(11997 - 22195 + 17156 + 17136)\n14841 * 11537\n20942 + 12524\n(7915 * 2392 * (25305 + 11297 - 27334 + 14251))\n16198 * 5399\n22749 - 9512\n2357 * 7906\n28246 + 8860\n11663 - 22645\n21619 + 24650\n22481 * 32731\n3061 - 4131\n10244 + 5406\n17029 * 22939\n4598 + 1688\n21613 - 16167\n((17535 - 4504 + 28966 + 32247) / 27992 * 14663)\n(29407 - 9228 / 22566 - 21948)\n3630 * 25237\n18466 + 32086\n(31663 + 16647 * 7435 + 18834)\n17373 - 5520\n((3198 + 17501 + 20988 / 26915) + (27021 * 16986 * (14498 / 31419 / 30101 + 14192)))\n30695 - 7400\n31575 - 17453\n13059 + 25797\n19758 - 9108\n5446 - 23570\n22991 * 23915\n(((25191 + 19561 + 22822 - 8213) + 23934 + 20893) - 11787 - 15406)\n(20314 * 28462 / (9229 - 16352 * 28470 + 8299))\n(404 + 30570 * ((11935 + 15359 - 27139 * 32560) * (14927 + 10603 - 8663 - 22495)))\n10476 - 28962\n(28523 * 5292 + 31892 / 7413)\n22644 / 1503\n(31841 - 12753 * 25857 + 16112)\n16475 * 13578\n22822 - 27424\n(23234 * 4259 * 11453 - 27108)\n22660 / 3239\n15830 * 24005\n20969 / 6243\n2790 - 6445\n((26690 + 7331 * 27632 + 4742) - 19633 * 14450)\n(365 * 21143 - ((619 * 27635 * 14875 * 1008) + 22032 + 25382))\n15046 - 15180\n27673 + 12530\n32274 + 22847\n24974 * 12079\n12657 + 25984\n6723 * 7601\n1783 * 3200\n11366 * 6159\n(10751 + 5822 + 30321 * 30539)\n(15414 + 25727 + 14684 - 6912)\n9017 - 15439\n21731 - 28380\n9018 * 21498\n24595 * 4392\n((25552 - 4544 * 4838 - 32493) - 21564 + 17206)\n18506 * 6753\n21145 - 14940\n31687 + 21549\n22166 - 30208\n15273 - 29022\n(6922 + 23573 * (2895 * 11795 + 15026 + 2705))\n27729 + 7675\n31535 * 25214\n7123 / 27040\n11972 + 25613\n3671 * 8344\n(30561 + 2704 * (20725 / 14191 + 495 * 11642))\n3168 * 19247\n16528 * 3706\n7710 - 1303\n27983 + 31647\n20994 + 2647\n(28524 - 24802 * 30138 * 24457)\n15568 / 13531\n14248 - 15290\n19027 + 20317\n(1873 - 7357 / 15664 - 22144)\n15801 * 10532\n(12321 * 2543 + 14321 + 32206)\n(19268 * 20176 * 4787 - 22236)\n(12218 * 5171 + (((28274 - 12357 * 10363 * 18513) / 16120 * 7990) - 1930 * 21614))\n4274 * 16692\n(16998 / 2152 + (9900 - 12373 * (11081 - 26987 + 12009 * 624)))\n(22765 + 2570 + (2940 + 21138 - 32758 + 5662))\n1043 - 6089\n16461 * 28212\n1016 + 32711\n31629 + 8055\n8512 - 834\n(27382 * 20118 - 30069 + 119)\n31905 * 18781\n8422 * 20534\n2688 + 5487\n1629 - 11849\n((15197 - 6924 + 27182 - 1591) * 20622 * 6412)\n13499 + 31725\n8606 - 16028\n26777 * 17372\n13122 * 6857\n18617 * 17959\n(28939 * 32341 + 4995 * 7442)\n(12065 + 11077 - 4381 * 19027)\n23220 + 21961\n14597 + 22696\n(2473 * 10678 - 30344 - 8375)\n16219 - 4923\n(18768 * 8194 + 17866 + 10913)\n18834 * 17881\n12157 + 4804\n14273 + 25400\n(16313 - 31240 + 14901 * 17674)\n22237 * 7111\n(9957 + 9985 * 20421 + 11684)\n25631 - 21196\n(946 / 24320 + (1211 - 2655 / 10738 - 11063))\n8961 * 1674\n30119 * 24262\n32285 * 13330\n(24862 * 27995 + ((20186 + 2037 / 22402 + 1374) + 7983 - 3264))\n5531 - 12939\n15525 * 27766\n5305 * 9211\n5471 - 27906\n24109 + 14056\n((18759 + 26895 + 5391 - 32590) - ((31768 - 5405 - 31946 / 29819) - 7381 - 27993))\n18160 - 1940\n14455 * 7727\n14058 * 27437\n20040 - 4693\n32553 * 30050\n8807 - 7783\n(3234 + 16371 * 27300 + 1610)\n29845 * 13468\n24312 - 4658\n6353 * 229\n170 * 17029\n29461 - 2884\n21600 * 4935\n(19678 * 9060 * 9745 + 24527)\n9375 - 17746\n15377 - 6703\n3242 * 11163\n6940 / 4553\n32046 + 23667\n25836 + 29011\n(890 + 32272 / 27056 + 14484)\n9907 + 5703\n((22293 * 13229 - 15807 - 6565) + 10382 - 11157)\n14693 * 21348\n30407 - 6770\n(7015 - 22880 - 2218 * 18051)\n13854 - 4845\n(8564 + 10493 + 13930 * 24453)\n19126 + 7280\n22638 * 15940\n4353 - 20830\n18786 * 17021\n28561 - 1332\n5866 - 13290\n((((26969 * 21136 / 12193 + 13972) + 15101 * 28381) + (9671 / 29136 + (((12898 * 6280 * 27995 + 9571) + 3899 + 15582) + 5882 * 6401))) * 30952 + 22807)\n((25487 + 27313 * 8246 + 4695) - (14948 * 6159 * 15181 + 15004))\n1774 - 23277\n29977 + 17465\n(25958 - 18813 * (2532 - 2015 - 16958 + 26722))\n23650 - 24358\n(23522 + 31106 - (2665 - 17099 + 17004 / 781))\n13735 - 14092\n3505 - 4261\n(16709 * 17209 * 32391 * 6169)\n(30599 * 31993 + 27225 + 30156)\n15750 - 26162\n19268 + 23649\n14436 - 29214\n(8328 - 4355 - (14057 + 20649 - ((23492 - 2723 + 16099 * 27731) - 12490 * 22529)))\n11473 / 6794\n16993 - 31662\n24741 + 28421\n14079 + 3577\n(21907 + 14403 * 26823 + 3691)\n20710 + 29030\n14745 - 16494\n(8524 + 4151 * 31207 + 17857)\n990 * 31034\n30407 - 16480\n5876 + 18304\n3713 * 5911\n((26420 + 4723 - 17890 - 6814) - 19021 + 10463)\n1395 + 30824\n(13891 * 341 * 13367 * 27070)\n8914 - 1677\n7034 - 5548\n(3754 * 1159 + 15100 + 32524)\n21354 - 12835\n21560 - 8920\n6262 + 20089\n379 * 29399\n11736 * 27042\n30219 + 14339\n4138 - 10187\n29207 - 32416\n(25982 + 25962 - 30627 * 5324)\n16005 + 31010\n24319 - 740\n19720 * 28224\n18936 + 29691\n2494 + 28354\n25636 + 16114\n28333 * 12901\n(21956 * 23442 + (13938 - 9454 - (9683 + 8397 * 13599 * 28805)))\n25290 * 19845\n28503 + 21821\n18658 * 7450\n26007 - 9480\n14123 * 14603\n3672 + 9438\n1472 * 14278\n4711 + 2060\n((29119 + 24420 + 14603 + 24520) * 3439 - 23449)\n(1769 / 2984 + 30329 + 20585)\n6194 * 10318\n(32447 + 907 - 921 * 3109)\n(29202 - 20957 + 26592 * 7269)\n7717 - 2255\n31538 * 32529\n21160 * 11463\n12946 / 1808\n25644 * 18595\n31436 + 11630\n1734 * 11850\n31648 + 12590\n27675 - 32208\n2707 - 23831\n(12856 * 12355 + ((11463 - 1124 - 2978 - 26065) - 25561 - 22510))\n3605 * 9236\n23678 - 3866\n27592 - 4775\n(((12162 + 8256 * 24484 / 10012) - ((24824 * 12191 / (16008 - 8921 * 23638 - 9414)) - ((19901 / 7673 - (16640 + 5871 - (26745 - 11737 - 16570 + 28866))) + (743 * 17030 - 19661 * 14156)))) - ((((14357 + 2644 + 23544 + 28110) * 30475 + 28368) * (11909 * 12959 + 29050 / 6872)) - 26833 + 3769))\n12131 + 7756\n23180 - 6135\n15748 - 11788\n10800 + 28786\n22645 - 10376\n23758 - 14879\n((15564 - 14102 + 14508 + 23759) + 19949 + 24092)\n30003 + 8529\n(19801 - 17011 * (1352 * 8847 * ((9172 - 17042 - (24537 * 32268 + (20055 * 31670 / 9938 / 14061))) / 11467 * 11416)))\n(13321 - 10798 + 26475 + 10312)\n(7259 + 25183 + (7583 - 18361 * 12842 + 31391))\n20671 / 21917\n1326 + 685\n1416 - 21650\n31684 * 30085\n(6675 * 1386 + 6387 - 4261)\n17791 * 30253\n10059 + 21683\n19325 + 18012\n27254 + 21453\n(680 - 30405 * 8028 * 30608)\n18042 + 10130\n9127 - 11224\n17640 - 22424\n18874 + 11852\n14819 * 9840\n(18385 - 31781 * (17711 + 27905 + 25018 * 24290))\n26332 + 9908\n14733 / 29828\n22818 + 8635\n5155 + 4743\n5566 * 1721\n(8226 * 25133 + 10883 * 27196)\n19295 - 28070\n31968 - 6144\n922 + 24147\n23128 * 1862\n24018 - 17076\n(14766 - 18570 * 945 * 31994)\n(13382 * 28230 - 3807 + 11906)\n4505 * 15455\n(6391 - 6408 + 3976 + 3542)\n2624 + 6248\n(23749 * 11027 * 28215 + 11039)\n24613 * 29351\n28999 - 20906\n4452 * 1516\n8771 + 5893\n(5510 - 11148 - (28563 - 28963 * 32279 * 24874))\n6292 + 30436\n1236 * 18479\n22359 + 12402\n14289 / 27067\n31245 * 22323\n(26053 + 32613 - 30823 * 17394)\n(757 * 5160 - 11920 + 4230)\n(20638 - 2087 * 32429 - 14336)\n2448 * 23047\n(9870 * 2098 - 16527 * 18414)\n15920 * 3598\n11861 * 2870\n(28604 / 22420 - 3719 - 9279)\n(18308 + 29523 * 12963 + 1854)\n9752 - 9698\n1662 - 14779\n(7923 - 29747 - 29712 - 9059)\n(((25464 * 30949 + (24046 - 27661 + 32735 - 12928)) + ((29361 * 23072 * 9599 * 27457) * 10649 * 25981)) * 12791 + 26510)\n28644 - 18018\n22534 - 9703\n(17791 + 20253 + (4244 + 23445 * (7302 + 4614 * 25783 * 23310)))\n26091 + 19532\n(30560 + 13102 / (4003 - 21662 - 4453 - 9072))\n29539 * 21126\n((22782 - 8832 + 14616 + 11824) - 27565 + 14556)\n12170 + 28807\n4363 + 25192\n9187 + 9258\n(801 * 16834 - 29208 + 25882)\n8877 * 28151\n(((8455 + 14509 * 25477 * 32692) + (16824 * 986 - 5267 * 30455)) / (1237 * 17612 * ((16411 / 14033 + 19349 - 29760) - (31745 * 61 - 13973 - 31274))))\n6018 * 18847\n(24129 - 22429 - 9599 + 3130)\n(27109 + 21040 + 30547 - 11835)\n30455 / 23638\n8239 + 28288\n12702 - 26656\n(15255 / 3041 - 5196 * 26781)\n(16849 - 24048 * 24725 / 31807)\n(12487 / 15351 + (3277 + 7584 - 24858 * 4831))\n(17081 + 29014 - 18368 + 29642)\n21575 * 10820\n(29178 - 5682 - ((30942 * 6433 * 5188 - 1336) + 4512 + 27561))\n14770 + 26760\n((((1207 / 20900 - 21848 - 15854) / 7555 * 17429) * ((2224 + 4555 - 29121 * 19280) * 32440 * 6106)) * 23301 - 17991)\n23856 / 6915\n(6597 + 3998 - 21869 - 14924)\n(((10832 + 10408 * (31141 - 29299 * 3727 * 4288)) - 20539 - 13086) - ((27690 - 28667 - 1341 + 29929) + 20034 + 16505))\n1941 + 30073\n3542 + 20859\n(24795 + 20869 - 29091 - 29485)\n545 + 11162\n(21434 + 10415 - 32746 * 21961)\n19620 - 20964\n2938 - 27815\n27383 + 29823\n(9573 * 16257 * 27840 + 8998)\n32375 - 3792\n22689 - 7382\n2451 * 3291\n1652 + 5356\n(((12252 + 1154 - 30539 / 16183) * 4725 + 27561) - 31151 * 28003)\n(8417 - 26015 + (17178 + 26886 + 32181 - 20675))\n31314 * 23301\n27021 - 8268\n((17957 / 1029 * (32523 + 25730 + 9217 + 31409)) + ((8663 + 4696 * 26526 + 11299) - 5965 - 1620))\n20910 + 27118\n((16147 - 23344 - 25906 * 21202) / 31159 + 15975)\n(19567 + 1535 * (((22346 * 18098 - ((9289 + 19350 - 2691 - 1307) + ((25122 - 2331 * 19932 - 13700) + 26074 + 28104))) - 28703 + 23943) - 25818 + 19713))\n((16026 - 20807 - (3893 * 2153 - 27936 + 27292)) - 2452 + 9716)\n21829 + 5730\n27556 - 16069\n30301 / 6558\n(1868 * 11830 * 9884 + 19965)\n15764 + 30337\n((((6443 - 15880 * 14370 + 18577) + 22887 - 27607) * 4587 - 30862) - 31875 + 10815)\n14015 + 25020\n18937 - 19408\n3106 - 30394\n23400 * 27281\n5860 - 2148\n17439 * 28431\n8048 * 2452\n8461 - 27649\n(23685 - 13624 + 18854 + 27318)\n23409 / 15322\n(16681 / 6275 - 30024 + 12738)\n28617 - 13930\n16734 - 6405\n13788 - 14966\n24042 - 25728\n(5017 * 26065 + (21022 / 28394 - 24512 - 30620))\n2022 + 11855\n17582 * 19281\n7009 / 26350\n6661 - 872\n25648 + 10178\n((30145 + 30986 + 7231 * 701) * 4392 - 10696)\n5642 - 24156\n(6407 * 13706 + 27434 + 9202)\n7945 - 20048\n17773 / 24324\n27041 - 6120\n2307 + 16919\n(30678 - 1661 - 10864 * 7038)\n21283 - 11568\n28741 / 22694\n14204 + 18128\n32463 * 15422\n22488 - 20904\n12687 * 29054\n(19367 - 5462 - 19313 * 12634)\n10535 - 29256\n21507 - 1244\n32645 * 14775\n26907 - 5008\n(16682 * 20549 + (25918 / 20801 + ((32062 - 8998 + 10904 * 5081) * 29731 / 22268)))\n17457 * 8056\n22216 * 23641\n16519 + 24274\n(11247 * 19877 - 9339 + 28807)\n22763 + 24365\n4141 - 20874\n12030 * 26350\n16798 * 106\n4601 - 12042\n16923 * 27158\n27397 / 15474\n(3840 - 2628 * 24691 - 19322)\n13925 * 7768\n17513 / 30068\n(18802 - 19187 - (21443 * 28092 * 5414 * 7097))\n30588 + 16775\n(3467 - 20472 + 9846 * 7145)\n(989 - 25129 * 8704 - 32653)\n20538 + 15643\n18949 + 25297\n((115 + 26433 + 13788 - 27775) + 3653 - 15208)\n32241 + 12508\n20215 - 30195\n(31898 + 19373 + 1182 * 14227)\n12777 + 25143\n24728 - 5352\n661 + 17450\n15844 / 743\n25563 * 25470\n(31602 - 23972 + 6525 + 12388)\n(11716 + 31527 - 8591 - 25444)\n18391 * 7425\n28206 * 22269\n28815 - 6744\n26367 + 31916\n26443 - 17493\n27319 + 15903\n2620 * 26243\n30807 / 9762\n(9563 * 31666 - 10029 - 3103)\n21245 * 2143\n26969 / 24559\n10658 * 11462\n((29079 + 1233 * ((6753 / 20002 * 17045 - 30550) - 4304 + 8404)) / (6431 - 25986 - 21270 * 14849))\n32703 * 411\n(25632 - 20677 / 23112 + 22868)\n13934 + 5911\n(21250 / 20988 * (7531 + 13078 + 32584 * 13704))\n11202 + 24933\n28638 + 6394\n(3301 * 19826 * 20374 * 5087)\n7007 - 18430\n9061 * 22751\n2130 + 15275\n22627 * 30660\n16525 - 20662\n2880 * 18005\n16667 + 13741\n8530 * 28675\n(26057 + 14427 * 13459 + 16475)\n22818 + 3216\n10326 + 4797\n5988 - 28668\n7959 + 30949\n4348 * 327\n(23425 * 4092 - ((11099 + 14891 - 20375 + 22101) * 25714 * 22494))\n8562 * 9006\n17944 + 21543\n21720 * 11007\n9466 + 24433\n(14712 + 16231 - 10262 - 8054)\n14038 - 4378\n25427 - 20784\n((27218 - 22232 + 27348 + 2372) + 31751 - 30298)\n5129 * 17845\n31688 - 1397\n15413 + 10810\n((28317 + 12623 + 6676 - 18085) * 18990 * 12120)\n26160 - 14276\n(25289 * 16654 + 11214 + 14095)\n(15576 - 13537 - (24341 - 7075 + 2707 * 2646))\n19396 + 6365\n(9740 * 4113 - 30670 - 9474)\n(18737 * 27654 * 31478 / 22486)\n2349 - 5957\n1665 + 20459\n8215 * 5344\n32728 * 1635\n(20095 * 1855 * 19593 + 25932)\n((8635 + 3768 + (2696 * 23403 - 3127 - 26515)) - 28738 - 21716)\n24220 / 9049\n21183 / 504\n(16127 + 13119 + 26628 + 2904)\n((31065 * 20106 * 28427 * 31345) + 12805 + 10875)\n14987 + 12574\n(16922 + 787 + 22393 * 16909)\n4745 + 24561\n16150 * 15271\n5855 * 31287\n30211 + 16250\n32193 - 3813\n3658 - 2457\n15729 + 32150\n18979 * 24269\n16009 - 514\n(10130 - 33 * 25021 - 15104)\n9112 * 17378\n20647 + 30021\n16402 - 13411\n28988 * 23444\n3610 + 14871\n15659 - 21924\n9755 - 26246\n(25755 * 26094 - 23488 + 28086)\n(((26915 - 32728 * 7161 * 330) / (10202 * 25070 * (24914 - 8745 - 14103 * 25923))) * 26349 * 22757)\n25222 - 12381\n21920 - 29223\n6394 - 19524\n19446 - 7287\n22686 * 24146\n10700 / 1642\n17145 - 29543\n27498 - 23622\n23658 - 26618\n((12232 + 23615 + 56 * 31351) * 9799 / 28047)\n30981 / 29182\n19155 - 25288\n15298 + 27923\n17254 + 20724\n723 + 15443\n903 + 17401\n9793 - 32155\n14438 - 6950\n6076 - 13140\n15272 * 1781\n(((7947 * 23885 * ((14215 * 22118 - 23247 * 23) - (11947 - 15294 / ((12098 - 9007 / 31529 * 12652) - 25738 + 4206)))) + 8670 - 516) * 26667 / 11467)\n10253 - 19742\n1823 + 18319\n22486 - 14947\n16765 + 31012\n22359 * 18665\n(29728 - 28069 - 10470 * 737)\n(27728 * 8065 * (24368 - 26526 - 21151 - 8577))\n(13873 - 30207 / 15219 - 16553)\n(30946 * 16718 + 31310 + 10442)\n32320 + 27738\n31497 * 10871\n24797 * 972\n26499 * 8016\n(25496 - 30574 - 8409 * 4136)\n8009 * 21391\n30554 - 32477\n(21972 - 9892 * (26481 * 6320 * 3462 - 16204))\n805 * 19726\n11791 * 29541\n19399 * 11261\n24062 + 26626\n(20864 + 29049 * 29489 - 23139)\n6120 + 9264\n(2319 * 18936 + 8402 * 19063)\n(20415 + 26602 - 15129 * 8458)\n18266 + 30882\n(31650 + 30782 + 29260 - 6537)\n6333 * 9423\n9920 - 25332\n12450 / 20856\n29245 + 17069\n(25545 * 1378 - 13479 - 22775)\n16182 - 31902\n23511 * 30214\n13798 - 7992\n5747 + 5274\n15121 / 1386\n((5283 + 21505 + ((20785 + 29886 + (24374 - 1519 - 9005 - 7783)) * 21004 - 24281)) * 18073 - 12673)\n11551 + 4780\n26766 / 3005\n8636 + 7868\n6775 + 200\n8363 / 14187\n3479 / 7547\n(31779 + 11211 - ((6649 - 11104 * 24701 - 17842) - 11228 + 20366))\n5860 * 28659\n32021 - 2863\n11690 / 24263\n(22867 / 30937 * (13179 - 13719 * 12977 * 5978))\n24138 - 16442\n((22209 - 31181 - 16859 - 27427) + 10441 + 7710)\n(4835 / 30512 * 15346 * 24753)\n15421 - 10623\n13 * 13182\n(25792 - 26141 + (14326 + 11755 + 4027 - 3872))\n22083 * 4556\n7977 * 5384\n(16756 + 20095 + 15498 - 19583)\n27401 + 31588\n24801 - 15331\n17642 - 26601\n25265 + 14996\n10677 - 28694\n((((5992 - 27329 * 7708 * 27635) + 23776 - 6418) + 24626 - 28878) + 32112 * 13153)\n16413 * 12275\n761 * 2100\n3416 * 7003\n(6102 + 25397 + 13814 * 31539)\n6085 - 505\n13613 * 30317\n(29075 + 3227 + (7403 * 12413 * 20192 - 23560))\n24856 * 10986\n(7470 * 5511 + 23443 / 3818)\n6572 - 8755\n31088 * 6793\n29921 + 11607\n31783 * 3684\n19150 - 21275\n(8707 * 16559 * 31131 + 32027)\n11791 + 13074\n(11479 - 25132 * 18528 - 8400)\n20864 - 9556\n26226 * 25607\n7068 + 16839\n9956 * 22135\n27416 - 5535\n8940 * 23932\n19008 - 31730\n19678 - 27849\n(29311 * 28453 - 17959 * 1141)\n24411 + 25211\n26190 * 8390\n(11087 - 7631 - ((8152 * 11815 - 23396 + 355) * ((23988 + 30035 + 139 - 4096) - 20549 * 16543)))\n((104 * 3396 - (17160 - 25866 + 3810 * 282)) - 24615 * 621)\n(7584 + 7396 - 17005 - 12464)\n28906 / 3755\n(3155 + 22068 - (26320 * 17063 - 20230 - 17560))\n(21067 + 29809 - (5679 - 22081 + 23155 + 28479))\n(28279 / 12239 - 22967 * 10810)\n12565 + 11969\n(14146 - 12371 - ((14738 + 7881 * (4555 * 21998 + (28923 - 3996 * (20983 * 31106 * 24451 - 7716)))) * 23350 * 20226))\n(22027 * 8764 + 4608 + 27557)\n22941 - 31286\n31404 - 19180\n9393 * 28351\n26478 + 18295\n30471 - 18192\n2973 - 5673\n15979 / 5366\n(25665 - 3136 + (1652 + 5507 - 23111 - 32541))\n23623 - 22940\n11796 * 5338\n24275 * 25518\n(((28763 * 14995 + (29608 * 25052 + 1497 * 7831)) - 26783 + 30403) - 5024 - 26709)\n11587 + 18547\n3413 / 10938\n19221 * 639\n(29994 - 12759 - 20921 / 20331)\n8436 + 19581\n15600 - 19819\n9327 * 26087\n7660 + 31453\n((9710 + 22194 - 1015 - 3587) * 14499 + 32680)\n12640 - 4484\n(14225 - 10682 - 14153 + 15412)\n17148 / 9971\n31805 + 11003\n(8921 + 197 * 14773 + 3914)\n3628 * 21535\n28985 - 25678\n28983 / 19851\n15490 * 8207\n((20633 - 17873 + 607 - 24859) / 26849 + 9415)\n30698 * 7313\n4310 + 23257\n(13973 - 26791 - 13892 - 3129)\n29367 + 11542\n25507 * 5240\n25385 * 24460\n12027 * 24957\n(22684 * 8695 - 16949 + 7751)\n315 + 8166\n14705 * 29\n((801 - 27116 + 1872 + 2020) + 7919 + 4007)\n6907 - 27574\n5244 * 18803\n21189 * 21893\n7058 * 31970\n27671 + 15986\n571 * 3790\n4458 * 32110\n(3000 + 13398 - 16718 + 21092)\n538 + 15498\n30593 + 8509\n6546 - 20774\n14655 * 3776\n27782 + 3871\n17492 - 18094\n17373 * 26079\n26127 * 15269\n17332 - 3940\n(4078 + 1995 * 22488 + 13088)\n32219 - 30147\n9188 - 8431\n27254 + 2607\n10761 + 3994\n17341 - 24572\n(7023 / 10449 - 19678 / 186)\n(((((27948 * 18779 * 3690 / 16552) + 32425 - 27885) - 4123 + 19967) - 25968 + 22377) * (9828 * 10432 - 17746 + 3178))\n25502 - 22754\n(14534 - 3028 + (26251 - 19133 - 7920 * 32105))\n(9466 + 29884 - 28352 * 5093)\n32217 - 17504\n27389 - 11141\n(15978 * 29270 / 5880 - 20209)\n(14982 - 11002 / 29189 * 26639)\n(21770 - 6886 * (20059 * 2925 + 25795 / 29113))\n28817 + 5712\n30122 - 4736\n23519 * 22919\n9582 - 3899\n28189 + 31558\n16101 * 10532\n15414 * 5359\n19080 - 32384\n6310 / 8665\n(23351 / 106 + 19535 + 25992)\n32129 - 21165\n(90 - 24994 * 5302 + 3966)\n15725 - 8165\n15736 * 7014\n20347 - 23431\n27802 * 18733\n23044 * 31049\n8890 - 23218\n11991 * 6777\n(((2230 - 4131 - 6469 * 31423) - 20111 - 3079) * 23131 + 23678)\n(7257 + 1916 + 7891 * 17282)\n12729 * 6275\n1307 * 20204\n25228 + 4775\n4084 - 18362\n(17764 * 30289 - 12497 - 24950)\n27431 - 26573\n20984 * 4782\n(6348 * 8689 + 13914 - 30898)\n11233 - 9048\n20973 - 3951\n32521 - 13209\n8852 - 31182\n20652 - 13426\n6318 * 9000\n3069 * 24763\n20574 + 4561\n5045 * 1820\n29417 + 22195\n14500 / 1739\n16594 - 30372\n(23590 + 22875 + (30482 * 9680 / 32679 - 1961))\n7473 / 14879\n17105 * 1623\n13302 + 3859\n2678 + 26851\n(6391 * 13809 - 25174 / 19266)\n28362 / 16430\n20844 - 9651\n8434 + 11693\n(8600 * 13640 + (((16155 - 25816 + 12168 * 25894) + 32548 - 28091) / 3405 + 11642))\n13835 * 8328\n21668 - 14702\n21161 + 7305\n(32018 * 31942 + 26396 * 950)\n((3425 - 16437 + (5796 * 23983 * 27046 * 188)) - 26372 - 18981)\n7109 * 17340\n3734 + 20641\n10455 * 8215\n(31230 / 24148 - 29476 * 14296)\n13743 * 22491\n(15362 - 14579 * 7964 - 20138)\n(4696 * 6153 * ((13361 - 27459 / 18022 + 6668) * 5830 * 13395))\n10929 + 27323\n14863 - 26627\n3136 / 4435\n568 + 19054\n11255 - 32133\n226 - 6968\n29585 * 4502\n27900 - 22668\n15091 * 12987\n5913 * 7706\n(19902 * 30789 - 31280 * 13478)\n10594 * 12749\n15709 / 4914\n15912 + 23067\n507 - 12817\n14740 - 18218\n3851 - 16415\n(24941 * 733 + 4594 * 22867)\n(12844 * 11877 + ((1137 * 10879 / 894 - 17451) + 9342 + 23028))\n15633 + 18759\n7836 * 32261\n(24514 * 20229 * 26743 * 691)\n20575 - 3934\n15327 - 17135\n(1732 - 20494 - 27836 * 11331)\n(18888 - 14243 * (6177 + 24407 * (32573 * 22970 - 30996 * 28255)))\n30954 + 16068\n(5069 - 11096 + 4407 * 2270)\n13330 - 29061\n18547 - 23343\n8456 - 12613\n((11613 + 32491 - 24100 + 15805) * 21410 * 22224)\n1096 - 23683\n(6826 - 31359 * 2324 + 1420)\n31660 - 1715\n(7884 * 14280 + (17553 - 11262 * 21672 * 17950))\n(19114 * 28118 * 28556 / 1902)\n14305 + 24377\n22391 + 31031\n12045 / 13402\n1658 + 3917\n9515 - 22\n15124 / 28532\n26500 - 14700\n((1822 + 29342 - 13031 * 17789) - 26532 * 25721)\n8522 * 12593\n((30731 + 21237 * 4072 * 9052) * (30633 * 23268 * 20024 + 28775))\n16444 - 23329\n3312 / 1097\n18188 - 22069\n4907 / 19759\n21867 - 6596\n24182 / 32481\n27 + 23148\n13224 / 26944\n(15124 / 18679 - 25047 - 29581)\n14379 - 22745\n((((15718 - 2040 - 23257 * 9407) * 18474 + 29779) / (29390 - 24777 / 7341 + 1416)) - 6623 * 1728)\n29389 + 30436\n(14841 + 28812 * 26113 * 30746)\n10148 - 12417\n(1693 + 13861 - 15385 + 22371)\n1337 * 18874\n(1438 * 17006 * 8563 * 4112)\n32633 - 2365\n15443 * 12862\n11914 + 2381\n12278 - 16600\n(16845 - 1352 - 857 + 7529)\n((27217 + 25276 * 26329 + 5147) + 22435 + 9937)\n16900 * 29989\n13940 / 17640\n7419 / 4526\n(10469 * 28015 + 24625 - 6529)\n1571 + 15795\n12880 - 26188\n7474 - 6538\n7292 + 30798\n(65 + 18049 * 16717 - 24282)\n63 - 7512\n(28401 + 25917 * 25199 + 28776)\n15833 - 30365\n16549 / 25977\n(11535 - 14410 + 7358 / 8573)\n32334 + 11510\n(16604 * 25315 - 23911 * 13036)\n10775 + 5798\n32120 * 28405\n28514 - 7122\n26407 * 27463\n32338 * 12830\n5972 - 10487\n25666 + 6315\n21936 - 22159\n23806 - 30574\n(8394 - 10517 / 26388 + 22505)\n((17152 - 20244 - 16288 + 6960) - 758 + 29058)\n((30387 + 25050 + ((3024 - 10819 + (14638 * 15637 * 19871 + 14961)) * (15257 + 265 * 29808 * 6530))) * 8088 - 19054)\n32251 + 19456\n8046 / 22880\n25468 + 2161\n27795 + 7261\n17211 * 2202\n(25817 + 16974 - 138 - 27576)\n27733 + 560\n21419 - 32673\n10544 * 8334\n(13246 + 23019 * (15856 * 6679 * 160 + 14057))\n21865 - 16489\n25564 - 21221\n(2587 - 14926 - (17588 * 16241 * 17859 + 10845))\n933 - 8292\n28811 * 25814\n((9575 - 17017 - 23124 + 7812) * 11442 - 17359)\n18144 + 12041\n27427 - 14133\n27557 - 18410\n((23877 + 10648 + 24059 - 23908) / 5751 / 18197)\n(13526 - 32020 * (29703 - 31526 * 5178 + 13021))\n26967 * 751\n28030 / 27942\n(((21929 - 9805 * 22833 * 18321) + 12586 * 29646) * 32067 * 13582)\n(4354 * 24023 - 9009 + 14281)\n13057 + 3289\n(16902 + 3204 + (21839 - 26988 + 13768 - 9550))\n31750 * 22882\n31805 + 18493\n31541 / 2598\n(11691 + 22538 - 30643 + 29208)\n11146 * 13997\n10280 - 25403\n20746 - 1252\n10213 - 18516\n(26858 + 19131 - (15108 / 19892 - (26287 * 29815 - 3307 - 4888)))\n1254 + 20748\n20136 / 24795\n26182 + 30615\n29896 - 23054\n17020 - 17468\n18106 - 4829\n2995 * 7953\n23014 * 6034\n2470 - 8548\n14157 * 15584\n5738 / 14297\n26647 - 12458\n8172 * 6849\n10874 * 17729\n(24696 - 24630 * 15413 + 4718)\n12638 - 11023\n13638 + 13597\n(27955 + 26062 / 29013 + 12141)\n(19013 + 27181 / 32398 - 14106)\n(4635 - 28868 + ((3204 * 13516 / 7887 - 7151) + 22784 * 20440))\n21597 - 6998\n26165 + 28567\n29657 * 15606\n((1680 - 5793 - ((17013 + 1403 * 2630 + 29853) + 3528 + 28841)) - 28102 * 3137)\n18082 - 22967\n28329 + 22507\n8979 + 2173\n15550 / 7158\n25793 + 7987\n(24154 - 20131 - 31365 - 28804)\n31318 / 30636\n(26360 * 10880 - 29670 - 5264)\n15650 * 27242\n15904 - 9758\n13222 + 28160\n((16475 + 3144 + 30401 + 25541) * (25288 / 30006 + 1148 - 18276))\n21749 + 8370\n12758 - 1302\n(7734 * 18357 + (23170 / 4686 + 2756 * 12976))\n21750 * 19106\n20417 / 27500\n(29596 - 16640 * 12863 / 14849)\n15208 + 20445\n1804 * 15471\n((11445 * 20279 + 16889 + 12213) * (22113 * 27028 * 16699 - 14051))\n27959 * 17160\n5130 - 15693\n(31207 - 5868 * 31987 * 31537)\n8435 + 23728\n2199 / 30970\n10202 + 17527\n12962 - 15235\n27961 - 18621\n(((8746 / 28919 / 31215 - 28998) * (9477 + 21038 + 29803 * 25409)) + 23761 - 17284)\n(3330 * 30098 * 8843 - 24927)\n31984 + 1900\n(6147 / 27637 * (23540 * 23791 * 6118 * 14442))\n3933 * 11427\n16797 / 31213\n5720 / 5778\n28513 / 10918\n9380 * 17036\n14521 - 22799\n(12370 + 3552 - ((19997 * 32493 + 24229 + 25558) - (18548 - 19624 + 2779 * 27877)))\n((19595 * 1768 * (32518 - 28972 / (24900 - 7582 * ((30248 * 5329 + 391 - 31329) * 12909 + 29241)))) + 9633 / 25292)\n17944 + 5632\n21929 * 20949\n1801 * 13614\n22091 - 12267\n(30575 + 28054 + 18106 + 5417)\n15652 - 1687\n27074 * 1073\n26114 + 25749\n29977 * 19806\n611 * 20638\n((22341 / 31655 - 11267 * 26714) + 18199 / 10252)\n29162 * 32765\n(21495 - 30316 * (17837 + 2761 / ((30866 * 23823 - 2505 + 28978) * 20941 + 27901)))\n26593 + 4367\n28515 + 3913\n25023 + 25703\n15490 / 27455\n27162 * 27100\n11695 * 25685\n7217 * 12937\n13668 + 29381\n30003 * 26398\n1847 * 23200\n(78 * 20099 - 12564 * 12776)\n20780 - 10925\n(((26184 * 8022 + 4728 * 430) - 11301 - 25729) * 22139 * 13320)\n(9905 * 13247 * (21639 + 30860 / 29296 * 5474))\n18647 / 6573\n(2956 / 14862 + (6640 - 31250 - 8519 * 11156))\n12262 * 22954\n5732 - 23787\n8996 - 32109\n30675 - 454\n25140 + 19079\n10337 * 11990\n6820 - 36\n(((8434 - 6753 - (21998 * 28416 * 4262 + 4295)) + 17909 * 2877) * (6540 + 9513 + 22892 - 9431))\n18253 - 18733\n7999 * 24815\n(26140 / 13558 * 28666 - 25969)\n28720 + 11953\n1461 / 29955\n5267 / 2843\n(14607 - 9485 - 32319 * 25466)\n19850 * 25785\n(4502 * 8912 * 10920 - 12775)\n7912 - 15641\n12492 / 23932\n2660 - 14226\n4743 * 9615\n31350 + 26505\n15909 + 32724\n15227 + 2168\n15128 * 29209\n17436 - 23170\n3030 * 12172\n(19833 + 20268 * (14617 + 2645 - 11011 + 17311))\n4785 - 7728\n15082 * 12922\n(16176 / 5284 * 23040 * 25440)\n32040 * 23780\n(457 / 6270 + 24182 * 24313)\n(6494 * 5255 * 10366 - 11779)\n27594 * 17707\n15080 + 26608\n17238 * 14785\n7540 + 3501\n12879 + 23107\n18167 * 31001\n1657 - 14800\n(13542 * 13050 * (22861 - 18314 - (25963 - 28548 / 27869 + 30883)))\n21043 + 11702\n8311 + 25976\n(28438 + 8319 + (32477 * 9173 - (17717 * 6763 * 8144 + 26954)))\n((31475 + 14701 - 6536 * 10254) + 15634 - 3306)\n7284 + 9728\n3999 * 724\n17821 + 16683\n((31600 + 8161 * 11186 * 6514) - 5271 - 16618)\n13913 * 3766\n(20487 + 2105 + 29195 - 26531)\n(7895 * 10818 - (20296 + 13736 / (32466 - 9308 - 20106 + 19005)))\n6988 - 4617\n27042 - 17731\n116 + 23521\n9223 + 30230\n25235 - 20872\n16392 + 25358\n5094 + 9849\n(4758 * 7251 - 27521 + 29518)\n25202 - 3763\n2316 / 32730\n23434 + 12222\n14830 + 17854\n5397 / 26363\n10474 + 10039\n15826 / 20845\n27012 * 30502\n(25385 - 22845 - 13522 + 17863)\n(11063 - 26054 - (19641 - 10400 * 3254 - 17762))\n26513 + 11425\n15658 * 1997\n(1793 + 6247 - 29671 * 9125)\n((6558 + 4710 - 26548 * 13187) - 26944 * 13896)\n32496 * 22947\n2412 - 19908\n23971 - 25555\n(32044 + 10546 * 29443 + 12524)\n20508 * 21339\n21930 / 28582\n936 - 28501\n11185 + 1513\n(22893 - 30920 - 19497 * 27932)\n7116 * 22122\n15909 - 7514\n32229 * 1820\n(13685 + 21395 * 8376 - 14278)\n(13 + 10903 - 217 / 536)\n29933 * 27172\n19085 / 3009\n27255 + 16546\n(6352 - 11961 * 5538 - 18796)\n14838 * 9463\n13606 - 16892\n6382 + 23491\n25235 + 10770\n(321 + 24122 - (21409 - 28647 - 20761 - 7481))\n4280 * 30847\n(6866 - 28557 * 5806 - 28891)\n(17175 * 8958 / 16003 + 29432)\n29888 * 4991\n(4471 - 4540 * 21017 - 3333)\n((1422 + 3414 + 29784 + 12250) - (26939 + 16611 - 5419 - 19632))\n16615 + 5542\n21304 + 566\n13505 * 13682\n(8566 - 1608 - 18377 * 4913)\n(19159 + 8229 + 17618 + 25240)\n28152 + 29187\n((17930 - 23744 * 3522 + 2526) * 13192 * 17648)\n21651 * 12360\n14110 * 20529\n21917 - 14858\n23000 * 10649\n9601 / 30605\n(21644 - 7746 + 2765 + 9296)\n4950 - 30010\n1748 - 20432\n(233 * 13364 * 18089 + 13828)\n8891 + 20602\n13091 / 12236\n4957 - 5440\n22865 + 29988\n13732 * 27867\n5271 - 26782\n((15004 - 20545 * ((21167 - 11326 - 15258 - 22520) * 29191 + 23696)) - 23996 + 28988)\n25842 - 12081\n28380 / 24390\n32744 + 9041\n28081 * 3154\n(25891 * 27046 + 31858 + 20260)\n30261 * 29933\n(14437 * 3163 + (10088 + 18577 / (9714 + 17414 + 12638 + 12518)))\n27970 * 9229\n9148 * 5518\n9914 / 31357\n2678 + 11173\n2259 - 20909\n(6252 / 9387 + (32368 - 7775 * (23153 + 7616 - 22627 * 6607)))\n25178 + 13552\n24137 + 31282\n1527 / 30358\n31391 * 29908\n19560 + 23934\n(((21221 * 19510 + 24196 / 23176) - 4666 - 22537) + (((26795 / 11538 + 22605 - 12586) * 17289 * 2721) * (((31732 + 16905 + (8352 * 24320 - 10285 - 15504)) + 3708 + 19988) + 16505 - 29397)))\n6719 / 23933\n((6342 * 7139 / ((1014 * 28484 / 10791 * 29148) + 28529 / 13800)) + 430 + 13080)\n31227 + 7000\n23733 + 21415\n29219 / 20810\n24916 + 22581\n(4256 - 2548 + 23881 + 22152)\n8872 / 28764\n10532 + 23850\n(21753 * 12611 - 31151 * 3045)\n26158 * 27751\n27779 - 27118\n21634 - 5822\n6856 * 17287\n3532 - 6598\n(8967 * 3913 + 22598 - 24983)\n((12723 * 6752 + (12765 + 25112 * (8409 - 1253 + (902 * 18179 * 23328 * 23660)))) + (13363 * 10553 * (25109 + 1989 * 23555 - 30578)))\n(18368 * 1112 - 13699 / 5896)\n25647 + 929\n18596 * 24216\n16790 - 1309\n23722 - 30005\n(9677 * 12850 - (14220 * 10357 - 24189 * 19528))\n12539 * 27303\n(24652 - 9716 + 30005 / 21343)\n((((19317 * 25637 - 13967 * 13717) * 24959 + 31628) * ((27393 * 30905 + 24461 * 6523) + ((22579 - 25452 - 24742 * 11089) / 2650 + 4356))) - 11924 + 28699)\n230 + 10273\n(((27221 * 9594 + 22962 - 13479) * 26904 * 25070) + 9419 - 20212)\n23716 + 22718\n250 * 28258\n(28809 + 9411 - (28143 + 8502 + 2005 - 2178))\n18356 + 23925\n((25996 - 10224 - 15132 * 24670) * 776 * 25835)\n15235 * 3405\n22311 + 17739\n3499 * 2213\n(18102 * 16280 + 11252 + 10501)\n2326 - 5813\n12356 * 11053\n11771 * 28809\n18883 + 26975\n28407 + 18492\n27223 - 32325\n((7608 - 6297 * 2254 - 6682) * 14707 - 5752)\n17252 + 1029\n(14783 * 32250 + 29139 + 32046)\n(10451 + 31248 + (5538 - 3617 * (4122 * 8721 - 1658 + 12734)))\n4133 - 21066\n(22396 * 21659 - 12325 * 25187)\n1197 + 26260\n2326 * 15030\n10969 - 3228\n18439 / 21513\n(7395 + 8824 + ((31913 / 10118 * 22051 + 15069) + 30393 / 17407))\n5162 * 8171\n4752 + 16424\n7310 * 12837\n8040 + 26731\n(28303 * 21569 * (26170 * 8772 - 30257 - 21563))\n7449 + 24614\n18697 + 32622\n(10144 * 18341 + 24501 - 26293)\n268 + 17605\n(578 + 18597 / 6601 - 24362)\n(25981 - 8403 * 30995 * 86)\n21631 + 24191\n397 * 11799\n10923 + 17192\n(3866 - 5054 + 311 - 27476)\n((503 + 18309 + 5492 - 14459) + 10523 - 28216)\n8533 + 8159\n27102 * 8366\n12856 / 27235\n12821 - 27432\n2581 + 32405\n29673 - 13961\n(8882 * 19568 * 12996 - 3792)\n(19332 + 31597 * 5984 - 23743)\n3102 - 14126\n31092 * 27274\n25436 + 15628\n13203 - 2358\n22545 - 15448\n4931 - 29790\n(14271 * 2992 - 11760 + 8165)\n23729 + 26974\n(6928 * 12864 - 30226 + 31539)\n15754 * 22183\n31917 - 20676\n22051 * 27242\n30379 - 3809\n(19901 + 359 + 21820 / 20445)\n19217 / 7950\n21344 + 30873\n(32144 + 25340 * 23743 - 4398)\n(22674 + 15199 * 26933 + 20724)\n9033 * 30419\n13892 + 30411\n15582 / 12066\n20310 - 12983\n16174 / 22185\n25182 - 29883\n7825 - 24291\n2964 / 14439\n(9195 + 1555 + 25873 - 26939)\n((11726 - 257 + 32115 - 19308) * (27812 - 21669 + 29128 * 15944))\n946 + 2612\n23626 * 17579\n(29425 * 9255 - 4694 - 19445)\n15206 - 28939\n14656 * 19843\n((17361 + 3485 + 9744 + 13248) + 25973 + 760)\n(27780 * 10325 * ((14174 * 8234 / 737 * 14303) * ((15974 - 4624 * (13615 + 3107 - 6630 - 10787)) * (19887 + 13745 - 29900 * 19445))))\n28203 - 5684\n12120 - 17399\n13291 - 4041\n29174 - 21778\n20954 * 6580\n25331 - 26094\n(24678 * 16753 - 20799 / 20684)\n150 + 9140\n9997 - 6083\n24048 - 19483\n8819 - 4852\n26980 - 23708\n10242 + 21440\n((22718 - 1527 + ((2800 + 30016 + (19881 + 1519 - 859 + 18327)) - 4069 * 17665)) + 14158 + 21774)\n30959 + 13359\n7183 - 17073\n(2862 + 27193 * 31622 - 14414)\n10898 - 4842\n17930 - 27529\n(15883 + 23760 - 19522 + 30602)\n24221 * 16700\n32167 + 5191\n30352 / 17249\n27183 * 26074\n16617 + 27993\n11243 * 30109\n9258 * 15023\n18279 + 13226\n(6330 * 6270 - 19708 * 3607)\n(12059 - 1642 + 5313 - 6238)\n32649 * 6438\n10426 - 21066\n12050 - 922\n6067 * 23685\n15039 - 11457\n9362 * 24859\n3616 - 22347\n5412 * 12098\n27116 - 3855\n25625 + 26029\n17516 - 30836\n(32322 + 20262 - 14105 * 28939)\n((8032 - 29456 - 3737 * 29729) - 18572 * 22338)\n16222 + 15374\n(6891 * 15356 * (32582 + 3176 / (16825 + 4403 - (18180 - 5450 - (16404 + 26946 - 19271 / 9197)))))\n19944 * 19233\n24888 + 10087\n17867 * 32143\n21306 + 21192\n26650 * 21305\n(3896 + 13267 - ((31504 + 21989 + (27393 + 5684 + 2561 * 31360)) - 7069 + 13710))\n15700 * 14951\n(26699 + 12154 + 3255 - 31662)\n(25143 * 25266 * 4996 / 24777)\n14564 + 14758\n27174 - 3730\n(26774 - 24713 * 28544 - 28283)\n30988 - 12755\n32637 * 12988\n3441 - 20160\n(13779 - 25300 / 27198 - 13892)\n19460 * 25470\n16920 * 30512\n32567 - 17126\n7303 * 22947\n28288 + 13309\n(25192 * 27050 - 8263 + 4004)\n15557 * 12048\n319 + 22901\n2932 - 26936\n((20447 + 31335 * 13043 * 18083) + 3392 - 431)\n(5503 * 12165 - 25172 * 28183)\n((20104 - 5525 + 21117 + 4422) + 3239 - 19452)\n21480 * 17617\n31874 / 2693\n19758 * 28965\n(20838 + 1191 * (30528 + 19790 * 22391 * 5495))\n966 + 953\n14194 * 25762\n(27189 + 15464 - 21358 * 1365)\n17366 - 12790\n15990 + 32582\n(5840 - 10583 + 3425 - 6312)\n17420 * 18167\n3028 + 19457\n19789 - 15825\n((17733 - 3548 + 19610 / 22027) + (14273 + 16843 + 12276 + 19225))\n24687 + 27013\n25811 * 11038\n5120 + 26605\n((31358 + 135 - 1859 / 4074) + 31424 + 22162)\n4610 + 5245\n(((32047 / 22604 * 10675 * 28498) - 16164 + 23861) / 16903 - 6988)\n282 + 27816\n30078 * 32288\n19642 - 32058\n((2499 + 17769 / 10913 / 30330) * 568 * 31950)\n15668 + 5206\n((((24616 - 23116 + 2601 + 27735) - 2422 - 5285) - 22046 - 28031) * 24866 + 20929)\n24512 * 31524\n22789 * 3783\n3983 * 28175\n((2174 - 25669 + (15848 + 29032 / (3722 + 6784 * 31058 * 16958))) + 32663 - 6311)\n8460 - 15972\n22907 + 32559\n13512 * 9839\n12058 * 14584\n15380 + 5349\n25244 * 20373\n(26278 + 2489 + 5379 - 25650)\n7299 * 1557\n31334 * 26680\n14621 * 30229\n13487 + 18039\n25944 + 11229\n17659 * 143\n(22975 + 4161 / 25612 + 23679)\n23336 * 29946\n(22273 + 19589 / 28816 * 27254)\n27958 + 16016\n((18805 * 9809 - ((13796 + 4683 + 18041 - 5823) * 30775 * 23723)) * (4221 * 7653 - (12810 * 25846 * 8406 + 25263)))\n8764 + 27272\n19597 / 21591\n4111 + 2193\n9997 - 26207\n4364 + 17272\n28476 + 1924\n(5696 - 23768 - 6037 * 13555)\n(1095 * 8182 * (((23635 * 6886 + 17040 - 21062) * ((((5546 / 5974 * (14056 - 20283 - (8969 + 3986 - (19437 * 24154 * 5749 - 7768)))) / (2172 - 32285 * 31238 + 12220)) - 7598 - 9457) - 565 - 16794)) - (21357 + 17589 - 12802 + 30483)))\n(27374 * 12487 + 6184 * 9614)\n7719 * 5048\n27873 - 21309\n(23603 - 23679 - 24439 * 31068)\n(21311 * 9958 * 27939 * 14709)\n15934 + 6977\n6081 * 25971\n18366 * 6376\n(22977 * 1504 * 16359 + 492)\n3446 + 7500\n(3287 - 8986 * 26437 - 24049)\n30692 - 14709\n7421 - 20493\n((19935 + 1852 * 27794 * 10725) - 2547 + 29568)\n21725 + 27490\n471 - 6143\n26702 + 29578\n13903 + 25500\n7108 / 8873\n((2807 * 26979 + 31921 * 31545) + (12548 - 12828 - 31895 * 14537))\n13282 - 21134\n5337 * 21878\n3184 * 14029\n31064 + 22853\n5110 - 12346\n14800 + 32354\n339 * 4058\n1269 + 6245\n12510 - 21829\n22367 - 2541\n((5985 + 5057 + 320 - 22043) + (17723 - 20132 - 20884 * 24616))\n(30493 - 20626 + (19517 * 9727 * (16696 - 23156 + 14833 * 31654)))\n(8711 * 12397 - 10622 + 14666)\n19591 + 24526\n17584 * 14492\n17848 * 14982\n7805 + 26255\n21103 * 15502\n21382 * 8098\n19342 + 14395\n20590 + 3505\n9592 + 15265\n(4161 - 83 + (17426 * 28527 - ((7273 + 24511 / 20252 * 939) + 8630 + 3376)))\n((107 - 7852 - 32108 + 18992) - 8031 / 20698)\n(28855 + 19065 / 6823 - 13254)\n19766 * 26148\n27061 * 31963\n17057 - 10428\n21223 - 9039\n32670 - 13872\n10775 / 4051\n1486 * 4247\n((13314 * 3788 - 29756 - 8896) - 12622 - 10104)\n17694 + 19629\n15348 + 7001\n21005 + 29364\n(7455 + 13205 + 28135 / 11601)\n17508 + 14190\n31282 * 32162\n(27850 * 21316 - 23003 * 14596)\n345 * 31456\n25461 + 25462\n11512 - 3439\n16201 * 24633\n3989 - 11477\n18523 - 19201\n12370 * 29224\n26820 * 16493\n15163 + 28435\n4136 / 30444\n((8246 + 30265 * 17921 - 5429) / 23471 + 23925)\n15520 + 20843\n(3036 * 15152 * 4485 + 11176)\n(6422 - 23468 - (5825 + 23676 - 11825 - 19496))\n10465 * 25289\n3531 - 20083\n(32438 - 11311 - 17176 + 23524)\n26307 - 25422\n22728 - 24370\n20985 * 17980\n24402 * 30306\n20923 * 26682\n30987 - 3964\n12667 + 19337\n12454 + 31419\n19529 + 5595\n21398 - 4556\n(16221 / 29627 + 3533 / 10018)\n27455 * 17379\n32577 - 14873\n23284 + 22288\n(7594 * 5825 + 1870 + 21720)\n31516 * 20889\n3993 + 3302\n(28859 - 1638 * (25412 + 27987 * 13481 - 4876))\n12283 - 4932\n25682 + 29616\n562 * 13785\n22392 - 32493\n6637 / 9595\n(3760 - 22814 * (6033 * 8286 + 32080 - 15106))\n((480 - 17282 * 3042 * 2164) - 27894 * 1338)\n31487 + 18496\n23836 - 19210\n1952 + 25687\n735 * 17183\n12121 + 23948\n29643 * 8863\n10749 + 14685\n31811 * 28684\n11056 - 14504\n(25388 + 29787 + (((11422 * 7939 / 2759 + 3769) * 13828 - 8353) + 25713 * 22550))\n32714 * 23669\n30251 * 19580\n1162 - 27447\n(21928 + 11363 + 25166 + 16472)\n(3567 - 23313 + 390 / 8515)\n25128 + 22876\n6610 * 12398\n31035 * 9978\n(6449 - 367 / 28813 * 1475)\n(11467 - 18403 - 18156 + 27247)\n27020 - 2124\n10673 + 5144\n30743 - 21997\n(25628 * 9395 - 5616 / 16180)\n27552 - 3320\n(26229 - 18378 - 31302 - 2906)\n(6557 * 15554 + 9293 + 10332)\n(18687 * 1892 + 27194 * 19224)\n29615 * 4772\n(24533 + 21464 + 17652 - 22034)\n20658 / 10068\n14389 - 1714\n31366 * 16063\n425 + 26450\n26656 - 182\n24001 - 8026\n117 * 13608\n8631 - 1519\n((27897 + 7149 + ((13960 + 2052 * 19584 - 13554) * ((29752 + 569 - 11220 / 18757) * (7710 / 11624 + 9153 / 24871)))) * 28720 * 26488)\n(5477 - 25177 + 13483 - 5344)\n20263 + 21847\n29362 + 26030\n(12196 / 6631 - (23311 + 3860 - 15824 - 32478))\n26619 * 21506\n8582 / 12477\n20498 - 16104\n13791 - 21309\n9772 - 6584\n26878 - 16456\n27116 + 23968\n((5054 - 19718 * (25804 * 22782 + 32391 + 7611)) + 32602 + 4130)\n15365 + 2361\n5205 * 32072\n6292 * 26362\n7914 * 25073\n11364 * 3013\n((25119 - 17114 * 24982 + 22128) * (11466 + 12772 * 12052 / 30327))\n19189 / 31089\n8272 - 26344\n18009 + 19157\n11923 - 23222\n(8143 + 5148 + 21030 + 26326)\n30536 * 15775\n21059 + 24349\n30089 + 16728\n8951 + 13000\n18396 * 2999\n((13611 * 17109 * (((16599 - 28389 * 2996 * 15068) + (30979 + 9658 + 11717 - 14840)) * 9551 + 17294)) * (9316 + 24201 - 28434 - 9933))\n1500 - 14635\n27531 + 14586\n16712 * 27271\n12483 - 28153\n3810 + 29056\n(30112 / 30619 * 25818 * 16693)\n1657 * 20668\n8717 - 10350\n3100 * 12889\n(29202 * 19951 / 25124 - 401)\n4715 + 16782\n22458 + 16496\n26501 / 30050\n200 / 15658\n13640 - 17033\n13638 * 30355\n2656 / 3555\n23816 * 31065\n27492 - 29273\n15985 - 25634\n(15026 + 2705 - 12311 - 712)\n(8796 / 22798 + 12817 / 28647)\n(10243 + 30467 * (9248 * 2720 * 20096 * 6211))\n(15528 - 2523 / (13115 * 3307 + (22810 - 584 * 12169 + 7825)))\n11845 - 13437\n9944 * 18580\n8078 - 13666\n30222 / 18519\n29181 * 11556\n(14404 * 31692 - 10770 * 7887)\n23008 + 11445\n11251 - 22141\n(2979 + 31878 - 30357 + 27465)\n10129 - 29123\n(31027 * 12985 / (9164 * 9545 + 24773 - 11681))\n24307 / 895\n7546 - 9807\n16566 - 29743\n((12959 - 3405 - 25333 + 3852) + 28460 - 1731)\n27026 / 4366\n(26271 + 6785 - 26679 * 12904)\n31899 - 23998\n14838 * 11549\n4130 / 22908\n21330 * 14778\n(20927 * 29805 + ((22053 - 20634 * 29019 - 15258) * 6814 + 1438))\n22762 + 16381\n12359 * 750\n14032 + 13435\n((12802 * 23477 + 8565 * 29444) / 6430 + 71)\n4627 - 18536\n31550 - 27685\n14956 * 32692\n20824 - 10225\n25919 + 25986\n(24030 * 5569 / 12824 + 32093)\n7742 * 10740\n5140 - 11585\n12539 + 25526\n13116 * 1602\n(4005 - 12292 * 642 * 28478)\n32083 * 25730\n26735 - 6255\n16830 + 20712\n(((7886 + 22266 * 29979 - 6288) + ((29606 - 5449 * 1591 - 5293) - 29098 - 14431)) + (19792 * 12188 + 27835 * 29582))\n9228 - 14951\n11901 - 18834\n27356 + 16894\n((22686 - 5707 + 12223 - 11575) * 10346 * 29098)\n11360 * 8599\n6194 * 3199\n5780 + 24826\n((17321 - 5072 * 27990 + 16695) + (11198 * 23697 * 915 / 29997))\n((29873 + 24557 * 5698 * 18620) + 29026 - 25265)\n1425 + 7825\n((5780 * 3642 * 8421 * 26100) - 3021 * 19681)\n(17414 * 20744 / 18344 + 13490)\n7941 / 3653\n15084 - 11317\n26352 * 24830\n28104 * 27929\n16895 * 9076\n25088 - 12514\n((15743 - 20746 * 21396 + 11411) - 10835 * 25317)\n12656 - 1289\n22649 + 10707\n(27058 + 16846 + 9636 - 27462)\n4923 * 22427\n7633 - 22792\n8497 - 856\n(((5441 * 15106 - 18269 + 25329) + (((22602 * 2492 * ((16504 * 19186 * 9431 / 2162) - 4498 + 6939)) + 28924 * 15283) - (11018 * 7590 - 2182 - 30402))) * 29920 - 14753)\n(12792 * 32680 + 19515 + 20130)\n21435 * 23942\n16375 + 9670\n2155 + 26375\n(22342 + 3082 * 11101 * 5995)\n((15895 + 22724 - 29310 + 20876) + 24147 * 15957)\n29798 - 32109\n22324 + 18152\n10683 + 14151\n(24382 - 25117 - (1320 - 14701 * 19200 * 29612))\n28108 + 224\n28517 / 24480\n11797 * 22678\n16135 + 8695\n10031 - 17731\n9138 + 14699\n((1753 * 8039 * 6109 - 26077) - (30747 + 23627 + 5492 * 13982))\n15050 * 20274\n4215 - 31996\n((10471 * 12660 - 9930 - 4493) - (14174 - 27553 - 19750 * 4872))\n14431 + 29450\n((25416 + 13287 - ((13922 * 5241 + (29560 - 1666 * 398 * 32144)) - 13521 + 858)) - 14350 + 13432)\n28344 + 9424\n(32020 + 14093 * 14982 * 5239)\n((1738 * 31950 - 13111 - 25978) + 32285 - 28480)\n26000 + 14918\n22530 - 11745\n(17554 + 17534 + 20105 * 8124)\n31685 + 31382\n25119 * 19781\n((3952 + 31002 + 10128 + 23754) + 23578 - 13279)\n20447 * 3022\n31986 - 15105\n4524 * 11738\n29334 + 6248\n17260 * 3836\n2964 - 10697\n3695 - 25936\n4715 * 32152\n(10025 - 17676 / 14050 / 16344)\n(27886 + 12738 + (11544 - 25688 + 30941 + 3297))\n17967 - 5812\n(7734 - 5808 * (1281 - 13007 * (30011 + 15706 + ((2442 * 17223 - 12532 * 17146) + 23674 * 21751))))\n(20406 - 9639 + 31933 - 28755)\n30238 - 29210\n4767 * 13887\n(28189 * 17392 - 8400 * 30487)\n9555 - 5709\n16224 - 23521\n2389 + 30301\n(12722 - 30954 * ((10421 - 17003 - 7680 - 30466) * 12179 + 28248))\n15609 + 25657\n30874 + 28454\n19962 * 17628\n28235 - 20402\n25257 - 21790\n5093 * 26690\n21532 - 5295\n27874 * 14424\n11242 + 27330\n4759 - 5045\n17460 * 12265\n18343 / 3649\n(1696 * 13733 + (3152 * 22678 - 13408 * 27087))\n20985 + 25624\n9011 - 19261\n30398 / 1165\n(6184 * 29806 - 8106 - 15662)\n8957 + 3192\n17004 * 21803\n(15333 * 15430 + 28944 - 19606)\n(12883 + 29180 + 18672 - 31936)\n24483 + 5565\n28572 * 21796\n(21858 * 26058 - (12205 / 22858 * 26518 * 22575))\n25465 - 10094\n9906 / 28689\n(5890 * 30266 + 17002 - 9199)\n7729 - 14537\n15920 - 23464\n8382 + 22154\n24154 * 11511\n32024 - 9735\n25187 / 8580\n((19318 * 12953 - 25290 / 19670) + 27749 - 17059)\n(((12317 * 32710 + 3013 - 25701) + (2522 + 15484 - (2766 * 26099 + (15590 * 25325 - 23821 * 32538)))) - (18919 - 29858 / 3932 - 1109))\n29715 - 13118\n((15232 + 27507 + 16673 / 3819) - (23725 * 5347 * 28056 + 15731))\n3227 / 10659\n((7688 - 22473 * 3841 + 20954) * (3354 - 30799 + ((6085 * 2424 - 30335 + 733) - ((19583 - 11506 * 13442 - 8149) - (31914 - 27682 + ((24186 + 11280 + 19332 * 19702) + 10494 - 25378))))))\n6058 - 5107\n(29133 / 9374 - 31182 + 9486)\n6559 * 29423\n((24059 + 16001 + 9497 * 20534) / 29651 - 19071)\n8390 + 6674\n3869 - 30438\n6155 + 27819\n13727 * 21623\n(((29647 * 25777 - 18207 * 11036) + (1372 * 22029 / 15468 - 25363)) + 19734 + 32710)\n904 - 27429\n15792 + 4652\n8376 - 28597\n((26924 * 29644 - 24925 * 18473) + (30043 - 10376 * (9363 + 6014 + 16391 / 7573)))\n((29058 - 25992 - 6870 * 25773) + 12967 - 1157)\n(17409 - 15107 / 27775 - 11204)\n16752 * 13010\n20665 - 3641\n23319 - 17628\n(22362 * 27483 * 9156 + 3724)\n(5668 * 20747 - 31786 - 29718)\n11681 - 7348\n(12513 - 16237 + 24967 - 27752)\n(5624 * 5480 * 26315 / 8894)\n10185 - 19521\n25989 * 8812\n((6852 + 14478 * 31554 + 6707) - 11357 * 12522)\n9884 * 31243\n(20083 + 1872 - 29365 * 19527)\n26524 * 23011\n18287 * 8102\n(14717 * 11301 * 2231 - 20106)\n896 / 16380\n23672 + 24481\n6627 * 4101\n22707 * 18159\n10676 + 29040\n((30275 * 13608 * 1577 * 25849) - (((13635 * 26370 - 31615 - 2943) + (27530 + 11306 - 15729 - 6439)) + 7161 + 16065))\n26951 * 2286\n21132 * 29759\n16817 + 11403\n17950 + 12979\n20718 + 11324\n9539 + 25083\n11935 / 3628\n27120 - 7886\n12577 + 13140\n(29605 - 29420 + 15311 + 18718)\n(15604 - 24422 + 19537 * 24461)\n10706 + 11224\n(5812 * 28780 + 13737 * 6427)\n21590 * 22908\n14074 / 24087\n12281 - 27517\n6293 * 13889\n31121 - 31351\n9768 + 32359\n30470 - 8889\n18768 * 27499\n26633 / 4710\n(13431 + 1221 * 3891 + 20320)\n29388 + 14413\n2039 + 950\n31820 + 4632\n14245 + 14612\n11551 - 31387\n13290 - 26447\n25575 * 17383\n(18043 * 6382 + 5901 * 5947)\n12614 - 8047\n11239 * 13731\n12267 + 21726\n4851 + 29211\n13308 / 7556\n32107 / 23565\n((14624 * 23180 - 10682 - 12645) + 525 * 2143)\n11799 + 5362\n28381 - 19872\n((25532 * 1378 - 17614 / 31422) - 9551 + 14379)\n20332 * 139\n(22350 + 3014 + 9109 * 3345)\n1140 + 12243\n((9941 - 16809 * (((18550 + 12226 + 19595 - 16995) - 20994 * 28461) + 25045 * 17849)) - 22636 - 29181)\n26365 - 28896\n31468 + 13644\n12269 - 15713\n17125 - 10005\n(6972 + 659 * 16612 - 16504)\n(16150 * 31354 * 26703 - 29347)\n(28249 * 2728 * 20139 + 21759)\n13018 - 14550\n22519 * 2146\n20365 + 11362\n5951 * 11275\n16731 - 503\n(14073 * 1469 / (5206 * 2561 * 14309 - 11860))\n26519 - 14624\n2446 + 20357\n30396 * 30435\n((29442 + 13662 * (603 + 12577 + (18963 + 17717 + (2950 * 3726 - ((3357 / 16122 - 26703 / 31617) * (4520 - 15335 * 15143 + 30226)))))) * 21201 - 19108)\n5883 - 6361\n18038 * 2211\n((9610 + 17782 * 29221 * 32486) + ((10343 - 30769 - 31648 * 30728) / (11485 + 24342 - 11903 * 15143)))\n(1081 - 21975 * 25745 * 28066)\n20195 * 8403\n32609 + 14593\n12553 - 16258\n28866 + 19230\n25051 - 6351\n31085 - 12035\n20032 / 213\n17425 - 22674\n9646 * 24382\n(31601 / 11644 / 29332 + 7970)\n25261 - 11758\n18565 + 28418\n(30007 - 31018 - 13321 + 26482)\n30095 / 17696\n(4089 - 16276 * ((16276 - 16601 / 10540 + 32206) + 10133 + 10645))\n(2800 + 3027 - 27177 + 12696)\n(206 / 23225 * (30245 * 1858 + 9704 / 10187))\n(3029 * 5997 + (18241 + 29375 * 13653 + 8095))\n(4094 - 24539 + 25146 - 27357)\n3904 * 29279\n1239 * 15536\n28374 - 4219\n(8087 / 23559 * (16560 * 4354 - 32632 - 19852))\n(29643 - 15184 + 24788 + 23115)\n((21331 + 8358 * 23568 * 31686) + 21716 + 9)\n5468 * 32595\n22273 * 32150\n(28407 - 28051 - 7797 - 9888)\n13564 - 2503\n29765 - 4709\n26551 - 9202\n(4938 * 4454 * 20863 + 10770)\n(3842 + 15429 * 31632 * 13041)\n20806 + 28078\n22304 + 17087\n3129 * 5690\n24313 + 15310\n11440 - 18243\n15872 * 13882\n19527 + 27262\n14260 - 23396\n14671 * 30926\n9301 + 16062\n15493 / 28550\n996 - 5195\n20257 - 17686\n(14022 - 1778 + (30167 * 4339 - 3763 * 32445))\n25662 * 22731\n16154 + 6029\n(29701 / 27798 + 31316 - 7731)\n16962 * 14640\n(31834 + 28388 + 5367 - 20186)\n((24127 * 22059 * (24699 * 13352 - 1241 - 22370)) - (14009 / 29375 - 13750 + 390))\n(11665 - 10436 - (23383 + 16510 + 25313 / 25619))\n23641 + 28920\n11599 - 29180\n5544 - 622\n32630 + 11225\n30075 - 14683\n(23131 + 13532 + (7778 + 13578 * 4086 * 767))\n14114 - 26962\n((((13434 * 20691 + 26472 * 10560) * 15480 + 2377) + 12468 + 16721) - (25746 / 26500 - 19867 * 24812))\n(27684 * 5228 - 11314 / 31746)\n((26658 + 18479 * 20186 - 1237) - 23906 * 16159)\n6405 * 31692\n20537 + 13427\n9553 + 22619\n3825 + 22836\n30726 + 20712\n(5844 * 17263 * 27730 - 25611)\n7330 + 3482\n29759 - 30895\n31684 + 6300\n28991 * 23395\n4520 * 1736\n4384 - 14085\n(24181 * 17811 + 31592 - 26633)\n(22906 + 15783 - 16892 - 20915)\n(29949 - 29071 + ((16498 / 8926 - 22799 + 13480) + 26302 * 24758))\n32533 - 2689\n21441 + 3662\n(12264 - 23436 / 32125 - 19436)\n2661 + 20920\n(12974 * 21607 - 18179 / 16041)\n(20538 - 20139 - 3451 - 14044)\n896 + 28491\n22014 * 28250\n2942 * 1557\n11982 + 8398\n19091 * 15033\n13706 * 8022\n((18617 + 17307 - 27579 - 10322) / 5238 * 2036)\n(((1594 * 25382 - 20986 + 14111) + 4169 * 13056) + 779 * 9334)\n20964 - 433\n2506 - 27702\n(21751 * 2053 - 5602 * 31347)\n(4240 + 30851 - 14395 - 25261)\n(26900 - 22346 - (27048 / 4365 + (24447 + 8146 * 28565 + 17584)))\n29631 * 19379\n847 * 23267\n11783 + 32179\n523 - 161\n6567 * 6695\n27251 + 27468\n27532 + 15045\n21905 - 12396\n6694 - 4599\n11988 * 24326\n21673 * 9402\n18450 - 8114\n5207 - 22647\n16568 - 32452\n6841 * 28020\n((4891 + 10084 + 16145 + 5774) + 14433 / 30286)\n27161 - 31508\n12162 + 29426\n10720 - 32710\n18925 - 29072\n(13585 + 29975 - 6455 - 1448)\n22373 + 17200\n30335 * 3760\n19952 - 29818\n4164 - 16490\n15924 * 7292\n(26028 / 9011 + 20672 - 10555)\n24648 + 8651\n(27089 * 22143 / (((27250 + 540 - (12666 - 4678 - (19694 / 10110 + 1888 * 16393))) + (((((1338 + 13490 + 12114 - 18125) + (31872 + 4783 + 20092 + 31558)) / 14236 * 8715) - 4847 + 4234) * (21295 - 21648 - ((10262 / 16321 - (25366 * 27161 - 8350 + 23008)) * 19195 - 12712)))) + ((27527 - 11162 - (26346 - 21958 - 28482 * 30443)) + 18408 + 5396)))\n17692 * 8923\n27576 + 5931\n(8102 * 10627 + (21948 + 13211 - 370 + 18860))\n(30623 + 32654 * 19006 - 19170)\n19985 * 521\n4819 + 22274\n(9106 + 30043 * (28765 * 14444 - 26594 - 6129))\n((30309 - 29661 + 27720 * 27211) + 2125 + 31965)\n7029 - 16295\n5614 - 366\n((13081 * 9672 - (10350 / 27949 - 22056 * 6605)) - (21608 + 10688 * (865 * 13807 - 15666 + 1868)))\n1664 - 23597\n21298 - 9139\n13100 * 25938\n17886 - 30154\n19598 - 15080\n8653 * 21187\n(((((14568 * 29304 - (18029 + 19561 + 17413 * 28722)) - 8294 - 1823) - 30079 / 3870) * 16437 + 4113) * 23442 + 1632)\n((((6548 - 31989 * (23105 - 5880 * 11296 * 3232)) + (31531 - 22668 - 2233 - 21516)) + 9935 - 4912) / 24115 / 30152)\n4173 + 14742\n32540 * 22754\n(11374 - 29455 - 12947 + 18475)\n10713 + 32755\n16045 - 17035\n15354 * 15297\n((1892 * 24891 * 2202 - 24648) + 16509 * 19567)\n29593 + 20831\n26368 - 32162\n(14725 + 32415 + (((20015 + 29195 - 23520 - 23174) - 10897 + 1889) * 9940 + 14655))\n1814 - 3660\n22208 * 5245\n113 + 6402\n15914 / 8238\n17515 * 10163\n21289 - 30364\n2751 / 28767\n(8172 - 29562 + (12421 / 14041 * ((30028 + 26444 - ((11436 + 26398 - 29328 * 17004) - (23519 * 7975 + (6293 + 25817 + 12432 - 22603)))) + (4313 - 10162 * 5455 * 24513))))\n1035 - 27205\n1332 + 22593\n(28061 + 27098 + 8677 + 22684)\n29469 * 20257\n32556 + 27664\n11150 - 27884\n((15707 + 30988 * 7004 * 11530) - 24294 + 30670)\n29433 - 23915\n((14680 + 21569 / 26046 * 32598) - 10271 - 20209)\n(25158 + 15576 * (12886 - 242 - (20774 + 30940 * 3222 - 4767)))\n12016 * 17287\n575 * 31357\n(22475 - 21704 * (6163 * 24733 - 1239 * 30259))\n30126 + 15319\n(13505 - 28561 + ((19701 + 29635 * (26779 / 23996 + 31180 * 4645)) * (8656 + 5792 * 28674 - 32389)))\n(21982 + 20295 / ((11722 * 14191 - 17248 * 3451) + 31578 - 11599))\n23904 * 22071\n16430 - 14660\n(3979 * 23792 - (20039 * 14202 * 17399 * 12602))\n29119 - 6218\n25943 + 30733\n10973 / 12534\n(21647 * 25008 * (23991 * 28988 / 5790 * 924))\n((178 + 9364 - 26538 - 23401) - (12671 * 9954 - 888 - 21345))\n(11983 / 24097 - 31095 + 20752)\n7916 - 23163\n18497 + 23959\n(22563 + 8292 + 1800 - 3311)\n(((((3928 - 24668 / 19279 - 23810) - ((9772 + 9368 + 12136 - 31774) - 22483 * 19397)) + 1625 + 1792) * (20901 - 26455 * (26164 + 23892 * 16301 + 15298))) + 11864 * 15564)\n23743 - 4325\n7224 / 31173\n(5319 + 281 + 5132 * 30067)\n(14362 + 16316 - 1560 - 15848)\n7401 + 15432\n28503 - 29732\n6593 - 4066\n(28554 - 28329 * 8016 + 27305)\n13147 + 16293\n17532 * 20654\n(12226 - 2297 * (22982 - 28932 + 4453 - 5828))\n(((32534 - 13428 - 6327 + 31773) * (1720 + 30894 - 30763 * 29194)) / 3112 - 11139)\n18594 * 6429\n25459 - 2578\n5521 - 30794\n(10939 * 4405 - 9875 - 28165)\n1631 * 29626\n20363 / 9332\n9835 * 4203\n24226 + 21773\n4178 + 27512\n4513 - 15200\n(25848 * 6657 - 30266 * 9525)\n(7259 - 9948 + 22667 - 28213)\n(24684 * 26711 + 581 * 2236)\n31383 - 20107\n15077 / 12566\n27960 * 25427\n(12346 + 24164 * 25660 + 25230)\n((((19683 - 27359 - 22392 * 7106) * 32665 - 28661) - ((((5437 + 18432 * 9307 * 5444) + 31245 - 30200) - 24191 + 10648) - 18730 + 21324)) / 13277 + 32397)\n1131 - 25737\n1364 + 18412\n((31537 + 7075 * (13779 - 28982 - 2424 - 12510)) - 24961 * 21416)\n6672 * 30064\n(28689 * 6887 * 17307 - 20857)\n3373 - 1252\n(31739 * 585 * 17494 - 1453)\n((3164 - 18781 / 4015 + 18462) + 7241 - 27681)\n10946 + 13014\n20887 - 12426\n(23398 * 28599 * 21464 - 25980)\n24731 / 31285\n24896 * 9948\n30348 / 16284\n17782 + 2946\n25793 - 22612\n13238 + 15392\n18681 + 11238\n5548 * 29196\n13258 / 16118\n728 * 10377\n13033 + 8834\n24523 * 19964\n(17338 - 1652 * 16587 - 20522)\n7895 / 9764\n(22304 / 6191 - 14369 * 10062)\n6928 * 13276\n1671 - 27957\n1143 - 21243\n22814 * 5315\n22576 * 21182\n7110 + 28418\n(7285 - 412 * 16409 * 30896)\n15663 + 26595\n9654 * 26610\n6078 + 14773\n9951 - 51\n(7663 - 22038 + 19265 - 51)\n26957 - 12391\n24946 * 27583\n28194 + 16596\n3843 * 30312\n(9912 * 24562 - ((31824 * 20024 + 27641 * 27500) - 32088 * 31102))\n((11029 - 28383 + ((18333 * 30898 + (10674 * 4442 - 18680 * 26189)) / (16825 + 8334 + 16335 - 31308))) * 29575 - 17796)\n4577 * 3457\n21745 + 3751\n16990 - 18085\n22429 * 3230\n(3208 / 16969 + 30388 + 5415)\n11506 + 4126\n((23602 + 25140 - 16837 * 18373) * (13719 - 29104 * 30487 + 14075))\n21623 + 10907\n16632 + 31849\n(31495 - 32221 * 10681 * 25022)\n11663 / 12553\n29359 - 17199\n27557 - 30586\n7503 - 31189\n21616 / 32078\n16430 + 5188\n9875 - 2933\n9052 + 14670\n24763 * 10693\n19514 / 11825\n5605 / 30487\n17007 - 24420\n7382 + 29041\n25657 * 13258\n(1544 + 727 + 21045 * 11109)\n(4366 - 8660 * 26315 - 25138)\n6257 + 28680\n7964 - 22644\n18674 - 2419\n(23806 * 524 * 18604 * 11140)\n11013 - 11287\n26044 + 8593\n4211 + 27189\n983 - 7236\n537 * 2582\n2125 + 29851\n4955 * 24833\n12269 + 25306\n37 * 973\n6055 + 29919\n(8944 - 1911 + (11972 * 32573 * ((285 * 2243 - 18228 * 14050) - 32340 + 1301)))\n(24691 - 9253 + 4957 + 20593)\n4606 - 12099\n21931 - 15886\n25817 - 24575\n20174 * 6510\n(11989 * 9189 * (25468 + 28647 - 30112 * 7142))\n2722 + 3856\n24373 - 32745\n25619 * 24556\n21470 * 23622\n5012 - 9371\n27166 * 20977\n(1071 + 5780 + (20236 - 30725 * 17564 * 29374))\n27670 + 11435\n29077 * 32478\n18126 + 8983\n26333 - 9773\n1372 - 14765\n25451 - 19006\n24113 - 5310\n4628 * 32625\n31005 * 20809\n(29732 + 20148 + (23411 / 4658 + (15363 - 31520 * 10774 / 5084)))\n10403 + 27527\n((17217 * 25575 - 27423 - 10333) * 20186 * 30056)\n6801 * 19318\n25930 * 24173\n17999 * 30537\n25410 * 541\n1914 * 9502\n20825 - 9421\n7640 + 29636\n30525 + 24649\n27739 + 15851\n12979 + 10293\n((8562 + 7419 - 8086 + 22182) + 4073 + 21419)\n28300 - 14426\n6659 * 29240\n28384 - 14539\n10804 + 5984\n20668 * 29820\n9705 + 28554\n21721 - 27705\n7394 - 25302\n((8244 + 15802 + 993 * 27845) * (26969 * 3215 / 20017 * 13317))\n162 * 29616\n4797 * 26767\n((499 / 23061 + 4051 / 17323) - ((23978 - 18166 * ((32178 * 9575 - 28565 / 5297) * 20824 + 16971)) + 29840 * 6195))\n(2890 + 21964 - 16936 - 28671)\n9394 + 32639\n13012 - 7317\n14074 * 23582\n27974 + 232\n7904 * 23736\n31288 * 14299\n((21902 * 7046 * 6598 - 6318) - 1292 - 1086)\n14713 * 26862\n28808 + 27771\n11852 * 20029\n4878 - 25147\n21144 - 21782\n17251 * 766\n28425 + 15923\n12254 - 25106\n((17567 + 21184 + 4734 - 26711) + 20038 * 14501)\n4287 - 8374\n13978 * 29094\n12314 - 16329\n20464 * 4857\n5584 - 5423\n8993 + 20977\n12094 * 18746\n21966 * 12798\n28990 * 5515\n(28780 - 21505 + 25425 + 27933)\n8332 + 23322\n(2501 - 1693 - 31865 - 21118)\n((((29582 * 25616 + 29643 * 12818) / 23719 + 20595) * 15830 + 2343) - 56 * 20334)\n25420 - 28084\n248 - 14355\n6151 + 23814\n13298 - 9560\n12282 * 5205\n6935 / 23662\n28475 + 11654\n6873 + 17533\n(14001 * 27769 - 17252 * 25345)\n7024 + 32036\n(14534 / 27566 - 334 * 9661)\n(31324 + 15254 * 6462 + 10100)\n(5897 - 27279 * 12795 + 21684)\n20849 * 28952\n26386 / 23506\n18438 * 26249\n1521 + 5279\n3189 * 30088\n(22090 * 15113 + (14500 / 27676 + (30359 * 10469 * 25701 - 22400)))\n22301 - 13146\n(13321 * 30711 - 9819 + 25031)\n((496 - 17655 / 2719 + 20042) / 5457 - 23475)\n22220 + 30937\n27900 * 29068\n(28986 - 25456 - 29593 + 17807)\n31557 * 19027\n32568 + 21330\n((27551 - 29679 * 30610 + 13694) - 31498 + 27086)\n12484 - 26986\n(4096 + 13498 / (3349 * 12085 + 26844 + 764))\n(29476 * 14296 / 5404 * 32619)\n25988 / 14421\n21291 + 20012\n1133 * 28972\n(30347 * 13242 - 2985 * 3976)\n22665 + 12741\n10154 * 30928\n(29898 + 9897 + 12654 - 25232)\n11073 * 14815\n(10149 + 3640 - 29512 + 31879)\n21595 + 28825\n7115 - 24464\n(14937 * 3093 + (18730 - 6700 + (14123 - 19874 * (((19211 + 9839 * (9546 * 1274 + (4517 * 18686 - 9278 * 22396))) + 2094 * 23489) + ((5294 - 4838 * 7985 + 28050) - 11908 + 14491)))))\n14432 - 5157\n11405 - 3500\n(32201 + 31569 - (25993 - 32688 * 17220 + 16063))\n29189 - 27853\n31629 + 20030\n5796 * 26312\n10884 * 8995\n20897 / 15795\n10240 + 3975\n((25688 - 3270 * 31805 - 24338) - 6087 / 23095)\n28825 - 17289\n1449 * 14976\n1652 * 16303\n18860 - 778\n11360 * 23452\n(17489 - 23289 + 4514 / 22069)\n25108 + 4001\n16773 * 9008\n(3689 * 18732 * 15644 + 25524)\n11238 * 28579\n23081 - 27389\n3381 * 12646\n28396 * 32271\n7674 + 7603\n18480 * 17108\n28257 / 26761\n16239 + 20319\n4010 + 10020\n32606 + 5877\n6434 + 19342\n20759 * 27187\n(10146 / 13496 * 599 * 11811)\n5182 - 18092\n7557 * 6319\n20026 + 7851\n14884 - 30543\n14789 * 30210\n15092 - 16393\n(28019 + 10934 * 23360 - 8746)\n2772 + 31799\n20371 * 4692\n900 / 26388\n23238 * 25532\n(23691 + 4736 + 26317 / 3810)\n(4316 - 12370 / 28837 + 14938)\n10986 + 29390\n(14123 + 27165 - 8607 * 9113)\n16407 * 6912\n6869 + 3156\n30342 + 12125\n10747 + 16481\n(21195 + 17407 + 25436 + 28314)\n6666 - 5321\n(15502 * 14524 * 18748 * 18169)\n32752 * 13328\n25850 * 26850\n23689 + 22999\n(10937 * 20935 * 9063 / 6970)\n16748 - 29499\n(11402 * 19226 + 9201 * 18344)\n31685 + 23977\n8582 + 18696\n20788 + 1678\n7616 * 11839\n(14211 * 22457 + 25096 * 31583)\n32006 * 3991\n6990 - 21485\n30073 * 17955\n21480 + 13648\n20284 + 31418\n13272 - 11898\n11867 - 30698\n17936 + 8256\n7991 * 2066\n27272 + 32052\n(20847 - 29663 - (809 * 27495 * 14498 - 9026))\n17664 - 3305\n((4156 - 5581 - 22978 / 28410) * 2728 - 30427)\n(((24965 + 5699 - 8317 - 2673) - 2246 + 17001) * (15099 + 2402 + 25294 * 2844))\n17095 * 19160\n3906 - 8770\n(5208 - 32291 - 13697 / 21203)\n(6939 - 23618 * (29241 * 26791 - ((14222 - 16965 * 20793 - 21469) + 16791 + 17373)))\n19436 * 32557\n(2880 - 1417 + 9622 - 30466)\n(29709 - 1800 * 9104 - 29831)\n17714 * 10250\n27931 * 27627\n16136 + 25531\n(8755 - 7273 * 20038 / 5948)\n12198 * 16046\n19090 + 3868\n14134 - 14348\n20310 + 10507\n5584 - 9865\n3368 + 10098\n29780 - 14922\n32169 - 6885\n(5267 - 32642 + 6697 * 8539)\n18666 - 15684\n31356 / 4896\n22438 * 26253\n30235 + 26518\n5532 * 20642\n(((10014 + 27674 * 20725 - 26264) / 15056 + 23643) - 22909 * 25116)\n((10298 - 4742 - (((2532 + 4462 - (24282 * 31874 - 29213 - 19412)) - 20170 * 21550) - 13423 / 9321)) / 19389 * 26004)\n4644 - 14689\n(22612 - 20014 - 30707 + 9549)\n31340 * 28495\n15285 * 12814\n31358 * 27369\n17196 * 11281\n(((12548 + 25060 + 9723 + 11159) - 31022 - 22504) * 15489 * 31362)\n(5046 + 7970 * 471 + 3293)\n21575 * 27611\n24068 * 2637\n((1845 - 17270 * 3647 + 29801) / 21782 * 8517)\n(14573 / 15093 + (30116 - 16004 * 14796 - 23696))\n27317 * 16795\n20015 * 15045\n6193 * 11835\n(17295 * 18861 / 5103 - 6082)\n28771 + 13257\n31755 * 21847\n25820 + 23623\n29571 + 17905\n(26132 - 14691 + 21005 + 10387)\n13119 / 30177\n13618 - 15603\n(16869 + 24770 - 4168 * 8153)\n16895 + 13494\n(14589 * 11375 + ((26385 - 9129 - 22085 * 19545) - 32259 + 6860))\n30786 + 29563\n22688 * 14253\n5455 * 7487\n24416 * 18421\n23737 + 290\n3868 - 8682\n(8714 - 13151 - 24810 / 11147)\n22218 + 22327\n21971 + 17347\n7283 - 1020\n(3061 * 29903 + 32541 - 23120)\n10024 * 515\n10162 - 17563\n"
  },
  {
    "path": "misc/packcc/benchmark/inputs/json.json",
    "content": "[\n  {\n    \"_id\": \"616eeee5c9331980bba69fd7\",\n    \"index\": 0,\n    \"guid\": \"dd7edd5a-8213-4392-8a65-26587da4e267\",\n    \"isActive\": false,\n    \"balance\": \"$3,794.91\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Clarice Baird\",\n    \"gender\": \"female\",\n    \"company\": \"POLARIA\",\n    \"email\": \"claricebaird@polaria.com\",\n    \"phone\": \"+1 (808) 557-3724\",\n    \"address\": \"779 Glenwood Road, Brookfield, Alaska, 222\",\n    \"about\": \"Eiusmod commodo dolore eiusmod ea fugiat aliquip ea excepteur nulla velit sint. Enim excepteur ipsum nulla voluptate id ut occaecat adipisicing nostrud est culpa. Minim minim cillum id dolor.\\r\\n\",\n    \"registered\": \"2014-12-20T06:44:14 -01:00\",\n    \"latitude\": -5.955038,\n    \"longitude\": 141.128292,\n    \"tags\": [\n      \"minim\",\n      \"ut\",\n      \"dolor\",\n      \"dolor\",\n      \"et\",\n      \"exercitation\",\n      \"sint\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Isabel Moreno\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Gina Wise\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Riley Hobbs\"\n      }\n    ],\n    \"greeting\": \"Hello, Clarice Baird! You have 7 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5d1d8ff24671ed601\",\n    \"index\": 1,\n    \"guid\": \"4746c522-3de7-4c7e-b384-3ab41ea9947d\",\n    \"isActive\": true,\n    \"balance\": \"$1,455.02\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 20,\n    \"eyeColor\": \"green\",\n    \"name\": \"Hallie Copeland\",\n    \"gender\": \"female\",\n    \"company\": \"HANDSHAKE\",\n    \"email\": \"halliecopeland@handshake.com\",\n    \"phone\": \"+1 (840) 497-3083\",\n    \"address\": \"762 Lancaster Avenue, Taycheedah, Missouri, 5596\",\n    \"about\": \"Voluptate adipisicing do officia labore sint et mollit occaecat excepteur pariatur. Eiusmod eu nulla laboris elit id elit quis. Lorem consectetur sint cupidatat commodo nisi officia officia irure esse reprehenderit aliqua labore qui aliqua. Elit veniam commodo dolore do ullamco. Culpa fugiat nostrud velit occaecat anim excepteur ipsum.\\r\\n\",\n    \"registered\": \"2016-10-07T09:12:56 -02:00\",\n    \"latitude\": -5.300461,\n    \"longitude\": -146.509029,\n    \"tags\": [\n      \"eu\",\n      \"amet\",\n      \"do\",\n      \"labore\",\n      \"eiusmod\",\n      \"ut\",\n      \"voluptate\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Janis Kim\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Tanya Riddle\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Betsy Acevedo\"\n      }\n    ],\n    \"greeting\": \"Hello, Hallie Copeland! You have 9 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5ccddcf53eaef3c8e\",\n    \"index\": 2,\n    \"guid\": \"c8d038fb-7a95-49e0-87f8-3c11bf802095\",\n    \"isActive\": true,\n    \"balance\": \"$1,210.23\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"green\",\n    \"name\": \"Cline Johnston\",\n    \"gender\": \"male\",\n    \"company\": \"ARCTIQ\",\n    \"email\": \"clinejohnston@arctiq.com\",\n    \"phone\": \"+1 (979) 476-3073\",\n    \"address\": \"510 Tilden Avenue, Rodman, Hawaii, 2767\",\n    \"about\": \"Eu cupidatat quis amet proident nostrud. Sunt non id cupidatat aliqua. Anim magna proident dolor et aliqua aliquip ad dolor. Quis deserunt occaecat excepteur nulla nostrud tempor ex minim esse veniam non. Cupidatat veniam sit nostrud Lorem amet.\\r\\n\",\n    \"registered\": \"2019-08-16T02:49:13 -02:00\",\n    \"latitude\": 34.306099,\n    \"longitude\": 34.55533,\n    \"tags\": [\n      \"quis\",\n      \"aute\",\n      \"proident\",\n      \"est\",\n      \"magna\",\n      \"ea\",\n      \"ipsum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Sally Cohen\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Mccoy Horton\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Brittney Sanchez\"\n      }\n    ],\n    \"greeting\": \"Hello, Cline Johnston! You have 2 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5d49b6b47a66a7d51\",\n    \"index\": 3,\n    \"guid\": \"9285aa3a-2bd1-4b4c-9bd5-c57edc91f25b\",\n    \"isActive\": false,\n    \"balance\": \"$2,140.08\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 32,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Jefferson Melendez\",\n    \"gender\": \"male\",\n    \"company\": \"MANGELICA\",\n    \"email\": \"jeffersonmelendez@mangelica.com\",\n    \"phone\": \"+1 (959) 419-3121\",\n    \"address\": \"134 Schenck Street, Dola, Ohio, 6034\",\n    \"about\": \"Enim fugiat ipsum incididunt ad. Enim incididunt veniam proident magna labore est culpa sunt elit consectetur eu reprehenderit ad. Ad reprehenderit sunt voluptate excepteur. Reprehenderit veniam eiusmod fugiat duis amet id. Ea commodo ut reprehenderit laborum est ad excepteur deserunt culpa est culpa. Nisi nostrud nostrud ipsum laborum eu et cupidatat commodo est nostrud laborum in sint nisi.\\r\\n\",\n    \"registered\": \"2018-04-22T10:27:57 -02:00\",\n    \"latitude\": -35.226816,\n    \"longitude\": 6.744672,\n    \"tags\": [\n      \"tempor\",\n      \"do\",\n      \"deserunt\",\n      \"ipsum\",\n      \"adipisicing\",\n      \"elit\",\n      \"qui\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Ada Newman\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Sweeney Horn\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Vang Thornton\"\n      }\n    ],\n    \"greeting\": \"Hello, Jefferson Melendez! You have 8 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee51a539522d1f8b2a3\",\n    \"index\": 4,\n    \"guid\": \"eee02632-debf-4202-b496-5eec6ee1ae42\",\n    \"isActive\": true,\n    \"balance\": \"$3,073.01\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"green\",\n    \"name\": \"Arlene Delgado\",\n    \"gender\": \"female\",\n    \"company\": \"SURELOGIC\",\n    \"email\": \"arlenedelgado@surelogic.com\",\n    \"phone\": \"+1 (951) 471-3144\",\n    \"address\": \"663 Irwin Street, Bowden, Federated States Of Micronesia, 981\",\n    \"about\": \"Culpa cillum et do ipsum reprehenderit reprehenderit cupidatat. Proident incididunt deserunt id quis ex enim occaecat commodo elit sunt ex. Officia pariatur non anim commodo adipisicing anim sint in occaecat. Nulla ullamco consectetur culpa ea est officia occaecat mollit. Fugiat pariatur duis nisi velit ad laborum et sit cillum adipisicing. Excepteur laborum voluptate qui veniam do nisi laboris ullamco commodo. Eu culpa laboris elit eu est elit mollit minim qui ullamco Lorem tempor.\\r\\n\",\n    \"registered\": \"2016-06-07T09:05:55 -02:00\",\n    \"latitude\": -77.781086,\n    \"longitude\": -70.272973,\n    \"tags\": [\n      \"enim\",\n      \"Lorem\",\n      \"tempor\",\n      \"proident\",\n      \"ipsum\",\n      \"et\",\n      \"commodo\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Garrett Salazar\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Patsy Sheppard\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Barton Fitzpatrick\"\n      }\n    ],\n    \"greeting\": \"Hello, Arlene Delgado! You have 3 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5761c19ca200930c2\",\n    \"index\": 5,\n    \"guid\": \"e3173561-c964-4ce3-9031-fef090bf39c7\",\n    \"isActive\": false,\n    \"balance\": \"$3,659.57\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"green\",\n    \"name\": \"Juliette Aguilar\",\n    \"gender\": \"female\",\n    \"company\": \"PLASMOS\",\n    \"email\": \"julietteaguilar@plasmos.com\",\n    \"phone\": \"+1 (889) 443-2823\",\n    \"address\": \"302 Oliver Street, Belmont, New Hampshire, 5216\",\n    \"about\": \"Deserunt occaecat commodo ut duis culpa et. Veniam elit enim et quis exercitation amet eiusmod. Incididunt cupidatat id nisi pariatur tempor id aute id aliquip. Nulla anim elit voluptate ea. Sint consequat officia et voluptate id ipsum eiusmod amet anim. Amet consequat aliqua commodo aute. Culpa adipisicing reprehenderit tempor ipsum duis ex elit ex ad exercitation anim ut.\\r\\n\",\n    \"registered\": \"2017-08-25T01:55:52 -02:00\",\n    \"latitude\": 57.466829,\n    \"longitude\": 61.902854,\n    \"tags\": [\n      \"aute\",\n      \"labore\",\n      \"velit\",\n      \"consequat\",\n      \"pariatur\",\n      \"ullamco\",\n      \"dolore\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Wiggins Mosley\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Estrada Valenzuela\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Lula Roach\"\n      }\n    ],\n    \"greeting\": \"Hello, Juliette Aguilar! You have 8 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee56d86d12fd8230ffb\",\n    \"index\": 6,\n    \"guid\": \"cd6253c9-cec5-466e-a7ce-d98f49e45018\",\n    \"isActive\": true,\n    \"balance\": \"$2,268.43\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 35,\n    \"eyeColor\": \"green\",\n    \"name\": \"Francis Paul\",\n    \"gender\": \"female\",\n    \"company\": \"CEPRENE\",\n    \"email\": \"francispaul@ceprene.com\",\n    \"phone\": \"+1 (942) 570-3940\",\n    \"address\": \"485 Etna Street, Williamson, Utah, 7895\",\n    \"about\": \"Pariatur Lorem ea occaecat fugiat. Veniam officia commodo et tempor. Officia consectetur commodo ex voluptate pariatur et. Voluptate culpa velit duis in qui laborum nulla proident.\\r\\n\",\n    \"registered\": \"2020-11-12T06:48:54 -01:00\",\n    \"latitude\": 17.454265,\n    \"longitude\": 8.271245,\n    \"tags\": [\n      \"voluptate\",\n      \"tempor\",\n      \"ullamco\",\n      \"consectetur\",\n      \"aliqua\",\n      \"enim\",\n      \"commodo\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Kristine Solis\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Arline Miles\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Ruth Stephenson\"\n      }\n    ],\n    \"greeting\": \"Hello, Francis Paul! You have 7 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee59c0477b1dc135828\",\n    \"index\": 7,\n    \"guid\": \"c17440f7-4101-4801-93fe-b3ee35a7b8b9\",\n    \"isActive\": true,\n    \"balance\": \"$3,147.76\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 26,\n    \"eyeColor\": \"green\",\n    \"name\": \"Blair Berg\",\n    \"gender\": \"male\",\n    \"company\": \"CIPROMOX\",\n    \"email\": \"blairberg@cipromox.com\",\n    \"phone\": \"+1 (846) 453-2614\",\n    \"address\": \"326 Gardner Avenue, Roy, Pennsylvania, 7209\",\n    \"about\": \"Anim veniam ad consectetur veniam adipisicing id nostrud laboris ex nostrud labore nulla mollit reprehenderit. Voluptate ipsum do proident est nostrud aliquip pariatur. Laboris dolore mollit voluptate et voluptate. Exercitation nostrud id aliquip consequat incididunt. Aliquip minim anim irure minim magna. Do sint ex proident duis in voluptate do mollit consectetur velit dolore.\\r\\n\",\n    \"registered\": \"2017-06-27T01:49:08 -02:00\",\n    \"latitude\": -8.431681,\n    \"longitude\": -21.257797,\n    \"tags\": [\n      \"ex\",\n      \"cupidatat\",\n      \"tempor\",\n      \"velit\",\n      \"minim\",\n      \"laboris\",\n      \"est\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Mcgee Campbell\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Lucile Sosa\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Gordon Cain\"\n      }\n    ],\n    \"greeting\": \"Hello, Blair Berg! You have 2 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee54acdeaecc644cc02\",\n    \"index\": 8,\n    \"guid\": \"74f51de7-67ab-483f-be70-13075a30ae6e\",\n    \"isActive\": true,\n    \"balance\": \"$1,045.30\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Bethany Olson\",\n    \"gender\": \"female\",\n    \"company\": \"ANOCHA\",\n    \"email\": \"bethanyolson@anocha.com\",\n    \"phone\": \"+1 (961) 543-3707\",\n    \"address\": \"776 Centre Street, Harmon, North Dakota, 7125\",\n    \"about\": \"Aute ad culpa do laboris labore duis ipsum ullamco. Consectetur est reprehenderit qui id ad irure velit consequat pariatur nostrud ipsum labore duis. Lorem ullamco Lorem nisi ut. Veniam amet laboris ex ullamco ad aliquip minim mollit nostrud consequat laboris dolor. Quis pariatur aliquip non cupidatat duis fugiat non deserunt.\\r\\n\",\n    \"registered\": \"2017-08-26T01:28:10 -02:00\",\n    \"latitude\": -71.324721,\n    \"longitude\": -152.980103,\n    \"tags\": [\n      \"laboris\",\n      \"nisi\",\n      \"incididunt\",\n      \"proident\",\n      \"mollit\",\n      \"magna\",\n      \"ut\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Penny Lloyd\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Boone Soto\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Allison Dotson\"\n      }\n    ],\n    \"greeting\": \"Hello, Bethany Olson! You have 7 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5ef28786dc61ea595\",\n    \"index\": 9,\n    \"guid\": \"becc89d2-4ba6-4526-bafb-d6910f247f41\",\n    \"isActive\": false,\n    \"balance\": \"$2,504.46\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"green\",\n    \"name\": \"Hicks Cortez\",\n    \"gender\": \"male\",\n    \"company\": \"ORGANICA\",\n    \"email\": \"hickscortez@organica.com\",\n    \"phone\": \"+1 (880) 498-3909\",\n    \"address\": \"516 Jefferson Avenue, Talpa, Delaware, 8239\",\n    \"about\": \"Veniam do veniam ea ea sit ex nostrud pariatur incididunt laboris. Irure enim nisi quis aute do dolor quis id. Enim dolore nulla proident commodo laboris excepteur.\\r\\n\",\n    \"registered\": \"2019-12-01T03:57:30 -01:00\",\n    \"latitude\": -13.629896,\n    \"longitude\": 172.978206,\n    \"tags\": [\n      \"amet\",\n      \"nulla\",\n      \"ex\",\n      \"in\",\n      \"duis\",\n      \"dolore\",\n      \"dolor\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Willa Mckenzie\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Clements Mullen\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Corine Rosario\"\n      }\n    ],\n    \"greeting\": \"Hello, Hicks Cortez! You have 9 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee50fc5d292c74321aa\",\n    \"index\": 10,\n    \"guid\": \"86305716-9d23-47a5-8fd5-c8eeb7896888\",\n    \"isActive\": true,\n    \"balance\": \"$1,801.76\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 20,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Jensen Mckinney\",\n    \"gender\": \"male\",\n    \"company\": \"TRASOLA\",\n    \"email\": \"jensenmckinney@trasola.com\",\n    \"phone\": \"+1 (989) 586-2257\",\n    \"address\": \"546 Jackson Street, Chalfant, Nevada, 8968\",\n    \"about\": \"Culpa eu dolore deserunt anim Lorem amet excepteur. Ipsum ipsum laborum mollit sunt ullamco voluptate. Irure quis duis incididunt voluptate do duis magna laboris officia voluptate adipisicing dolore. Id anim fugiat dolore amet et. Nulla voluptate amet labore ut qui ea est fugiat voluptate non ea dolore laborum.\\r\\n\",\n    \"registered\": \"2020-02-25T07:28:01 -01:00\",\n    \"latitude\": -10.182114,\n    \"longitude\": 142.280862,\n    \"tags\": [\n      \"labore\",\n      \"aliqua\",\n      \"laboris\",\n      \"ex\",\n      \"do\",\n      \"do\",\n      \"duis\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Wilson Bridges\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Frankie Kline\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Carly Hopper\"\n      }\n    ],\n    \"greeting\": \"Hello, Jensen Mckinney! You have 7 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee53616c7f4c2287899\",\n    \"index\": 11,\n    \"guid\": \"e8ad6c51-2b04-4668-89eb-fac420d5391b\",\n    \"isActive\": false,\n    \"balance\": \"$2,258.93\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 20,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Beulah Mcgowan\",\n    \"gender\": \"female\",\n    \"company\": \"GOGOL\",\n    \"email\": \"beulahmcgowan@gogol.com\",\n    \"phone\": \"+1 (830) 494-2145\",\n    \"address\": \"502 Clinton Avenue, Sunwest, Montana, 6438\",\n    \"about\": \"Minim adipisicing ipsum cupidatat laborum dolor. Aliqua aliquip qui mollit non. Dolor duis nisi ullamco culpa excepteur veniam. Ex ullamco dolore non Lorem qui voluptate id ipsum in cupidatat. Cupidatat aute ipsum minim sint ad. Excepteur pariatur excepteur commodo reprehenderit ex excepteur eu ex laboris veniam ad pariatur. Laborum ullamco ullamco cupidatat commodo.\\r\\n\",\n    \"registered\": \"2019-01-17T06:37:26 -01:00\",\n    \"latitude\": -11.197451,\n    \"longitude\": -175.656933,\n    \"tags\": [\n      \"do\",\n      \"veniam\",\n      \"culpa\",\n      \"voluptate\",\n      \"magna\",\n      \"esse\",\n      \"esse\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Brianna Hebert\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Deanne Petty\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Brock Barker\"\n      }\n    ],\n    \"greeting\": \"Hello, Beulah Mcgowan! You have 5 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee56d6f4acf1e31553d\",\n    \"index\": 12,\n    \"guid\": \"6ce1383e-1afb-43a7-aea7-1dc2821a3220\",\n    \"isActive\": false,\n    \"balance\": \"$2,247.57\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 20,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Johnston Mitchell\",\n    \"gender\": \"male\",\n    \"company\": \"INTERGEEK\",\n    \"email\": \"johnstonmitchell@intergeek.com\",\n    \"phone\": \"+1 (979) 427-2619\",\n    \"address\": \"777 Scott Avenue, Yorklyn, Arizona, 5818\",\n    \"about\": \"Incididunt et irure irure ex Lorem. Dolor amet ad sit exercitation esse aliqua aliquip dolor ex irure nisi fugiat amet. Nisi occaecat pariatur veniam ipsum laboris ullamco duis aute culpa.\\r\\n\",\n    \"registered\": \"2018-01-05T10:05:41 -01:00\",\n    \"latitude\": -58.304026,\n    \"longitude\": -124.843976,\n    \"tags\": [\n      \"irure\",\n      \"proident\",\n      \"ullamco\",\n      \"culpa\",\n      \"voluptate\",\n      \"ad\",\n      \"et\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Fry Barron\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Wade Wallace\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Milagros Mann\"\n      }\n    ],\n    \"greeting\": \"Hello, Johnston Mitchell! You have 4 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee569fee5e2afcd918a\",\n    \"index\": 13,\n    \"guid\": \"92922f2b-a20e-42f1-b725-ee8267fed652\",\n    \"isActive\": false,\n    \"balance\": \"$3,977.25\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 35,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Barbara Marsh\",\n    \"gender\": \"female\",\n    \"company\": \"GINKLE\",\n    \"email\": \"barbaramarsh@ginkle.com\",\n    \"phone\": \"+1 (813) 599-2377\",\n    \"address\": \"734 Boynton Place, Klondike, Massachusetts, 8432\",\n    \"about\": \"Est eiusmod ea ea occaecat voluptate sunt mollit fugiat minim veniam. Commodo in ea adipisicing mollit excepteur labore ex dolor Lorem aute. Sunt ipsum ipsum Lorem dolore laborum. Ipsum do labore nisi officia ex sint consequat nisi aliquip culpa. Enim ut elit pariatur labore laboris qui ex tempor Lorem amet ea velit amet.\\r\\n\",\n    \"registered\": \"2019-03-07T06:20:54 -01:00\",\n    \"latitude\": -17.787105,\n    \"longitude\": 56.264694,\n    \"tags\": [\n      \"consequat\",\n      \"occaecat\",\n      \"eiusmod\",\n      \"enim\",\n      \"sit\",\n      \"magna\",\n      \"magna\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Wyatt Juarez\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Jo Houston\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Macias Wilson\"\n      }\n    ],\n    \"greeting\": \"Hello, Barbara Marsh! You have 10 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5a69f048b040973a3\",\n    \"index\": 14,\n    \"guid\": \"3922bd3d-125d-44ad-a3f6-d2a90b57ff12\",\n    \"isActive\": false,\n    \"balance\": \"$2,783.09\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 35,\n    \"eyeColor\": \"green\",\n    \"name\": \"White Bradshaw\",\n    \"gender\": \"male\",\n    \"company\": \"COLLAIRE\",\n    \"email\": \"whitebradshaw@collaire.com\",\n    \"phone\": \"+1 (868) 457-2491\",\n    \"address\": \"492 Lawn Court, Diaperville, Maryland, 8728\",\n    \"about\": \"Consequat dolor proident elit cupidatat non qui. Laboris enim anim culpa minim velit culpa anim pariatur et in ex sunt. Ea nulla consectetur labore voluptate officia velit in incididunt aliquip est. Cupidatat consectetur voluptate nisi consectetur nostrud aliqua irure elit consequat adipisicing culpa. Fugiat magna pariatur ea non nulla Lorem quis. Excepteur velit ipsum pariatur reprehenderit anim laborum consectetur ut laborum.\\r\\n\",\n    \"registered\": \"2021-06-13T10:42:46 -02:00\",\n    \"latitude\": 43.841024,\n    \"longitude\": 23.382462,\n    \"tags\": [\n      \"sint\",\n      \"ex\",\n      \"consectetur\",\n      \"nisi\",\n      \"ea\",\n      \"do\",\n      \"laboris\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Hilda Rivera\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Durham Henderson\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Allyson Villarreal\"\n      }\n    ],\n    \"greeting\": \"Hello, White Bradshaw! You have 9 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee52a6ae7743e693925\",\n    \"index\": 15,\n    \"guid\": \"84f5d014-ea4c-490f-802f-43b56a836990\",\n    \"isActive\": false,\n    \"balance\": \"$3,027.09\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 22,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Corina Manning\",\n    \"gender\": \"female\",\n    \"company\": \"COMVENE\",\n    \"email\": \"corinamanning@comvene.com\",\n    \"phone\": \"+1 (968) 407-3561\",\n    \"address\": \"803 Boerum Street, Holtville, Florida, 9083\",\n    \"about\": \"Sint ullamco sint occaecat cupidatat voluptate aliquip ex. In duis labore magna occaecat eu ullamco ipsum quis. Et cillum ea laboris reprehenderit ullamco veniam irure qui dolor sit. Veniam laboris incididunt dolor elit ut consequat sunt consequat. Lorem aute consectetur velit qui Lorem. Officia ipsum voluptate nisi duis incididunt do aute est. Anim est dolore sint occaecat occaecat ipsum ipsum sint cupidatat deserunt labore aliquip.\\r\\n\",\n    \"registered\": \"2021-02-26T05:17:49 -01:00\",\n    \"latitude\": -17.963342,\n    \"longitude\": 19.421553,\n    \"tags\": [\n      \"adipisicing\",\n      \"deserunt\",\n      \"id\",\n      \"ea\",\n      \"occaecat\",\n      \"excepteur\",\n      \"ipsum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Vilma Wilkins\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Russo Joyner\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Angelina Mcknight\"\n      }\n    ],\n    \"greeting\": \"Hello, Corina Manning! You have 6 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5a294e3ba90586c0e\",\n    \"index\": 16,\n    \"guid\": \"4e38f395-56cc-4296-9c04-8ab8c12ef16c\",\n    \"isActive\": false,\n    \"balance\": \"$3,226.52\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"green\",\n    \"name\": \"Cochran Gordon\",\n    \"gender\": \"male\",\n    \"company\": \"OPPORTECH\",\n    \"email\": \"cochrangordon@opportech.com\",\n    \"phone\": \"+1 (919) 554-3842\",\n    \"address\": \"828 Moultrie Street, Harrison, Washington, 6207\",\n    \"about\": \"Aute pariatur quis magna qui voluptate sit irure aliquip ipsum eiusmod veniam ipsum et. Sint minim in cupidatat ea commodo deserunt labore cillum sint commodo consectetur aute. Nostrud sit sint laboris mollit amet excepteur Lorem. Aliquip culpa elit ullamco ex irure. Dolor mollit nostrud ullamco et et commodo excepteur. Nostrud amet excepteur Lorem anim.\\r\\n\",\n    \"registered\": \"2014-09-18T07:24:45 -02:00\",\n    \"latitude\": 2.953595,\n    \"longitude\": -97.068344,\n    \"tags\": [\n      \"elit\",\n      \"cupidatat\",\n      \"id\",\n      \"fugiat\",\n      \"ipsum\",\n      \"reprehenderit\",\n      \"eiusmod\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Josefa Howe\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Lavonne Cunningham\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Wendy Bishop\"\n      }\n    ],\n    \"greeting\": \"Hello, Cochran Gordon! You have 5 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5db9e50e59b2091d3\",\n    \"index\": 17,\n    \"guid\": \"3c676c90-702c-4a0f-baf3-4b039907c96d\",\n    \"isActive\": true,\n    \"balance\": \"$2,671.37\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Ramsey Schneider\",\n    \"gender\": \"male\",\n    \"company\": \"ZAGGLES\",\n    \"email\": \"ramseyschneider@zaggles.com\",\n    \"phone\": \"+1 (908) 555-3356\",\n    \"address\": \"865 Seagate Terrace, Jardine, Virginia, 9062\",\n    \"about\": \"Excepteur proident aliqua sint cupidatat sunt Lorem ad eiusmod consequat ad. Et pariatur est nisi enim amet reprehenderit non anim sit tempor excepteur. Anim qui excepteur labore nisi. Sit amet anim quis nostrud occaecat magna exercitation dolor. Officia irure ad id proident ea ad incididunt laborum cillum sunt aliqua deserunt nisi officia. Lorem veniam magna et culpa do.\\r\\n\",\n    \"registered\": \"2014-10-24T07:42:27 -02:00\",\n    \"latitude\": -58.510909,\n    \"longitude\": -149.031468,\n    \"tags\": [\n      \"ea\",\n      \"veniam\",\n      \"minim\",\n      \"excepteur\",\n      \"reprehenderit\",\n      \"quis\",\n      \"nulla\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Acevedo Whitaker\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Love William\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Pauline French\"\n      }\n    ],\n    \"greeting\": \"Hello, Ramsey Schneider! You have 6 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5c9ce2a29759ebba7\",\n    \"index\": 18,\n    \"guid\": \"4fe2e4b4-5060-4f26-bdcb-a08b56ac52d1\",\n    \"isActive\": false,\n    \"balance\": \"$1,291.53\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Bauer Salas\",\n    \"gender\": \"male\",\n    \"company\": \"HYDROCOM\",\n    \"email\": \"bauersalas@hydrocom.com\",\n    \"phone\": \"+1 (858) 486-2282\",\n    \"address\": \"411 Harwood Place, Groveville, Oklahoma, 5301\",\n    \"about\": \"Officia ut esse non mollit nostrud reprehenderit consectetur adipisicing eu exercitation Lorem. Minim elit aute labore ullamco labore sunt esse quis mollit do. Id fugiat do consectetur mollit ex. Tempor laboris do ipsum irure.\\r\\n\",\n    \"registered\": \"2017-02-09T12:53:20 -01:00\",\n    \"latitude\": -39.56287,\n    \"longitude\": -34.355224,\n    \"tags\": [\n      \"aliquip\",\n      \"consequat\",\n      \"elit\",\n      \"deserunt\",\n      \"ex\",\n      \"tempor\",\n      \"excepteur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Holmes Bradley\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Thornton Mercado\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Latasha Newton\"\n      }\n    ],\n    \"greeting\": \"Hello, Bauer Salas! You have 3 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee51fd77ffeb8c34a15\",\n    \"index\": 19,\n    \"guid\": \"a0c3b4e5-fb37-4cd0-988c-6f27eccc7aca\",\n    \"isActive\": true,\n    \"balance\": \"$1,114.41\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 28,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Cherie Guzman\",\n    \"gender\": \"female\",\n    \"company\": \"KATAKANA\",\n    \"email\": \"cherieguzman@katakana.com\",\n    \"phone\": \"+1 (871) 580-3809\",\n    \"address\": \"564 Banker Street, Advance, Mississippi, 1396\",\n    \"about\": \"Non duis sunt sunt minim incididunt sit proident magna commodo in. Consequat ut id reprehenderit nulla non elit in consequat. Incididunt proident laborum eu eu culpa deserunt aute. Labore proident aute Lorem culpa fugiat do sint veniam occaecat consequat laborum fugiat commodo sint. Id cillum quis duis consequat. Incididunt enim pariatur nostrud culpa ipsum tempor anim eu voluptate ullamco sint cillum.\\r\\n\",\n    \"registered\": \"2021-08-06T12:53:43 -02:00\",\n    \"latitude\": 5.34241,\n    \"longitude\": -30.290634,\n    \"tags\": [\n      \"cillum\",\n      \"et\",\n      \"nisi\",\n      \"irure\",\n      \"qui\",\n      \"veniam\",\n      \"ex\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Giles Burch\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Mcmillan Stone\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Cantu Clay\"\n      }\n    ],\n    \"greeting\": \"Hello, Cherie Guzman! You have 9 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee55d213d8fb8971a0b\",\n    \"index\": 20,\n    \"guid\": \"dad3f662-b8c5-4810-80aa-0cee3fc34ad1\",\n    \"isActive\": false,\n    \"balance\": \"$3,548.71\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 33,\n    \"eyeColor\": \"green\",\n    \"name\": \"Benton Luna\",\n    \"gender\": \"male\",\n    \"company\": \"CAPSCREEN\",\n    \"email\": \"bentonluna@capscreen.com\",\n    \"phone\": \"+1 (924) 503-2544\",\n    \"address\": \"154 Hill Street, Zeba, Wisconsin, 1926\",\n    \"about\": \"Fugiat mollit nostrud culpa dolor ut reprehenderit aliquip ea. Qui cupidatat ad laboris labore est do dolor excepteur occaecat esse fugiat. Consectetur sit sit veniam tempor exercitation. Amet sint eu voluptate ex deserunt laboris. Ut non qui qui commodo. Nulla voluptate elit pariatur veniam irure aliqua minim eu sit velit sunt sint quis laborum.\\r\\n\",\n    \"registered\": \"2018-05-19T07:40:58 -02:00\",\n    \"latitude\": 61.397626,\n    \"longitude\": -65.76991,\n    \"tags\": [\n      \"enim\",\n      \"reprehenderit\",\n      \"culpa\",\n      \"dolore\",\n      \"amet\",\n      \"commodo\",\n      \"occaecat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Finley Elliott\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Erma Santiago\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Mcintyre Ford\"\n      }\n    ],\n    \"greeting\": \"Hello, Benton Luna! You have 7 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee563ae3239fb9b342b\",\n    \"index\": 21,\n    \"guid\": \"ae5a339f-3597-4c1f-8608-1f8c41267376\",\n    \"isActive\": false,\n    \"balance\": \"$2,551.88\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Miriam Trevino\",\n    \"gender\": \"female\",\n    \"company\": \"TERAPRENE\",\n    \"email\": \"miriamtrevino@teraprene.com\",\n    \"phone\": \"+1 (976) 521-3741\",\n    \"address\": \"712 National Drive, Bayview, South Dakota, 156\",\n    \"about\": \"Occaecat officia minim reprehenderit exercitation. Aute eu excepteur eiusmod ut laborum. Qui adipisicing magna quis eiusmod.\\r\\n\",\n    \"registered\": \"2016-07-10T04:48:52 -02:00\",\n    \"latitude\": 64.72301,\n    \"longitude\": 168.577287,\n    \"tags\": [\n      \"ea\",\n      \"ullamco\",\n      \"magna\",\n      \"exercitation\",\n      \"enim\",\n      \"et\",\n      \"aliqua\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Good Ruiz\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Merrill Palmer\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Herring Gray\"\n      }\n    ],\n    \"greeting\": \"Hello, Miriam Trevino! You have 5 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee55ca2ad181c87c67a\",\n    \"index\": 22,\n    \"guid\": \"c29532e9-ab22-4c67-9062-dc92d6c65d63\",\n    \"isActive\": false,\n    \"balance\": \"$2,335.23\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"green\",\n    \"name\": \"Rosario Kennedy\",\n    \"gender\": \"female\",\n    \"company\": \"NSPIRE\",\n    \"email\": \"rosariokennedy@nspire.com\",\n    \"phone\": \"+1 (947) 432-2392\",\n    \"address\": \"999 Walker Court, Dowling, Georgia, 5185\",\n    \"about\": \"Deserunt nisi exercitation laboris aliqua velit nisi. Aute consequat ex culpa aliqua et anim do duis. Veniam aliqua id consequat irure quis sunt.\\r\\n\",\n    \"registered\": \"2016-12-31T05:02:51 -01:00\",\n    \"latitude\": -73.171515,\n    \"longitude\": 102.274378,\n    \"tags\": [\n      \"cupidatat\",\n      \"officia\",\n      \"ex\",\n      \"et\",\n      \"fugiat\",\n      \"dolore\",\n      \"laboris\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Jordan Nelson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Benita Macias\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Emerson Guthrie\"\n      }\n    ],\n    \"greeting\": \"Hello, Rosario Kennedy! You have 7 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5caffd3a636a08103\",\n    \"index\": 23,\n    \"guid\": \"70b8d6cb-5b6f-44fb-ba83-83cd63705314\",\n    \"isActive\": true,\n    \"balance\": \"$2,917.43\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 33,\n    \"eyeColor\": \"green\",\n    \"name\": \"Harriet Cervantes\",\n    \"gender\": \"female\",\n    \"company\": \"RAMEON\",\n    \"email\": \"harrietcervantes@rameon.com\",\n    \"phone\": \"+1 (836) 471-2195\",\n    \"address\": \"189 Irving Place, Bloomington, Connecticut, 6306\",\n    \"about\": \"Ea sunt sint esse cillum dolore excepteur non consectetur ad. Mollit amet dolor sint duis ut consequat tempor culpa commodo aute aliqua. Exercitation consequat velit dolore minim consequat nisi sunt velit enim anim ad. Fugiat Lorem ex non do nulla exercitation dolor quis esse consequat incididunt incididunt mollit. Irure consectetur elit ea quis do labore culpa laboris ullamco nulla exercitation.\\r\\n\",\n    \"registered\": \"2019-09-08T03:14:11 -02:00\",\n    \"latitude\": 62.000937,\n    \"longitude\": 65.481082,\n    \"tags\": [\n      \"ipsum\",\n      \"ullamco\",\n      \"nulla\",\n      \"id\",\n      \"consectetur\",\n      \"est\",\n      \"amet\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Armstrong Byrd\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Pacheco Pollard\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Eugenia Petersen\"\n      }\n    ],\n    \"greeting\": \"Hello, Harriet Cervantes! You have 5 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5fec6905076146ea8\",\n    \"index\": 24,\n    \"guid\": \"d20b39d6-8e87-4777-845b-f1ed9062cf12\",\n    \"isActive\": false,\n    \"balance\": \"$1,720.20\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Alexis Sweet\",\n    \"gender\": \"female\",\n    \"company\": \"VISALIA\",\n    \"email\": \"alexissweet@visalia.com\",\n    \"phone\": \"+1 (872) 556-2882\",\n    \"address\": \"206 Schermerhorn Street, Wintersburg, West Virginia, 6132\",\n    \"about\": \"Aliquip ut id in sint duis aliquip tempor mollit. Labore mollit ea sit aliquip proident aute id proident reprehenderit nulla Lorem non. In culpa in aliquip cillum veniam duis aliquip ad nostrud aute ea. Labore commodo exercitation veniam velit ullamco. Laborum occaecat aliquip ut commodo voluptate deserunt officia deserunt Lorem aute adipisicing magna magna laborum. Irure cupidatat tempor exercitation tempor laboris eiusmod consequat veniam eu esse eiusmod eiusmod.\\r\\n\",\n    \"registered\": \"2014-05-13T09:28:41 -02:00\",\n    \"latitude\": 4.011056,\n    \"longitude\": 118.205224,\n    \"tags\": [\n      \"et\",\n      \"aliquip\",\n      \"duis\",\n      \"laboris\",\n      \"laboris\",\n      \"amet\",\n      \"amet\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Tammie Meyer\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Roman Mendoza\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Norris Burt\"\n      }\n    ],\n    \"greeting\": \"Hello, Alexis Sweet! You have 3 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee58ef47bf590026601\",\n    \"index\": 25,\n    \"guid\": \"a78eb54a-2335-42a5-870a-8dabf4ea78aa\",\n    \"isActive\": true,\n    \"balance\": \"$1,905.58\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 23,\n    \"eyeColor\": \"green\",\n    \"name\": \"Beryl Holmes\",\n    \"gender\": \"female\",\n    \"company\": \"FIBRODYNE\",\n    \"email\": \"berylholmes@fibrodyne.com\",\n    \"phone\": \"+1 (901) 489-3595\",\n    \"address\": \"371 Balfour Place, Teasdale, Marshall Islands, 2201\",\n    \"about\": \"Esse cupidatat dolore eu aliqua. Dolor et occaecat incididunt do sint. Sint laborum magna consectetur duis proident nulla irure non ut eiusmod enim esse sit. Velit ad laborum do eu. Reprehenderit non ipsum mollit sint commodo quis voluptate in. Id mollit ullamco consectetur excepteur ex qui dolore dolor aute nostrud velit nostrud amet irure. Laboris magna dolore veniam eiusmod.\\r\\n\",\n    \"registered\": \"2020-02-19T09:41:48 -01:00\",\n    \"latitude\": -89.975486,\n    \"longitude\": 77.541182,\n    \"tags\": [\n      \"proident\",\n      \"occaecat\",\n      \"laboris\",\n      \"eiusmod\",\n      \"quis\",\n      \"do\",\n      \"et\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Bridges Brooks\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Hannah Shannon\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Melisa Fletcher\"\n      }\n    ],\n    \"greeting\": \"Hello, Beryl Holmes! You have 8 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee50d4a87fd5ee83247\",\n    \"index\": 26,\n    \"guid\": \"dbb21e25-5d8b-40ca-a4f3-7406eb1f59a4\",\n    \"isActive\": false,\n    \"balance\": \"$2,275.10\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 30,\n    \"eyeColor\": \"green\",\n    \"name\": \"Hampton Garner\",\n    \"gender\": \"male\",\n    \"company\": \"FUTURITY\",\n    \"email\": \"hamptongarner@futurity.com\",\n    \"phone\": \"+1 (897) 569-2980\",\n    \"address\": \"608 Court Street, Kent, Arkansas, 9950\",\n    \"about\": \"Cupidatat esse pariatur non duis tempor esse ea. Laborum aliquip tempor culpa nulla consequat voluptate cupidatat proident do ut do. Et cupidatat ut mollit excepteur ad magna. Ea enim qui exercitation ullamco mollit incididunt eu commodo aliqua eiusmod et amet nisi non.\\r\\n\",\n    \"registered\": \"2018-08-20T07:51:12 -02:00\",\n    \"latitude\": -72.371189,\n    \"longitude\": -75.08946,\n    \"tags\": [\n      \"nostrud\",\n      \"quis\",\n      \"esse\",\n      \"labore\",\n      \"pariatur\",\n      \"ea\",\n      \"sit\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Lucy Fisher\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Cannon Rivers\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Lindsey Colon\"\n      }\n    ],\n    \"greeting\": \"Hello, Hampton Garner! You have 1 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee511b73484c3e36b18\",\n    \"index\": 27,\n    \"guid\": \"04798deb-a874-4132-b377-e09d47632e1c\",\n    \"isActive\": true,\n    \"balance\": \"$3,552.43\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"green\",\n    \"name\": \"Celina Johns\",\n    \"gender\": \"female\",\n    \"company\": \"COMTOURS\",\n    \"email\": \"celinajohns@comtours.com\",\n    \"phone\": \"+1 (919) 484-2480\",\n    \"address\": \"883 Ashford Street, Saticoy, Oregon, 4667\",\n    \"about\": \"Ex consectetur nisi tempor anim est dolor est. Sit mollit proident nostrud sint cillum ad nisi consectetur aliquip incididunt nisi ea dolore officia. Fugiat occaecat minim laborum velit eu irure. Qui tempor ut eiusmod laborum cillum proident dolore aliqua laboris commodo exercitation Lorem mollit est. Culpa magna tempor duis cupidatat duis aliquip. Veniam dolor commodo duis laborum quis.\\r\\n\",\n    \"registered\": \"2017-01-13T09:19:15 -01:00\",\n    \"latitude\": 26.506106,\n    \"longitude\": 166.328553,\n    \"tags\": [\n      \"nisi\",\n      \"do\",\n      \"culpa\",\n      \"Lorem\",\n      \"aliquip\",\n      \"Lorem\",\n      \"adipisicing\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Nunez Freeman\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Coleen Patton\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Welch Mills\"\n      }\n    ],\n    \"greeting\": \"Hello, Celina Johns! You have 6 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5bf048655c2e53328\",\n    \"index\": 28,\n    \"guid\": \"02666bb1-80da-4b43-b114-61eea5b291ce\",\n    \"isActive\": true,\n    \"balance\": \"$3,233.90\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 22,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Hendrix Monroe\",\n    \"gender\": \"male\",\n    \"company\": \"ORBEAN\",\n    \"email\": \"hendrixmonroe@orbean.com\",\n    \"phone\": \"+1 (853) 563-2653\",\n    \"address\": \"618 Quentin Street, Mooresburg, Puerto Rico, 6091\",\n    \"about\": \"Officia adipisicing ex voluptate mollit culpa nisi velit laboris nisi. Et aliqua in mollit velit anim aute labore. Nisi id Lorem do proident duis laboris ea. Id exercitation enim pariatur proident culpa enim exercitation exercitation dolor est ad voluptate. Proident irure reprehenderit consectetur voluptate ea officia excepteur. Aliqua ullamco do in commodo sint magna magna ex sint culpa voluptate cupidatat sit dolor. Qui ut occaecat esse exercitation.\\r\\n\",\n    \"registered\": \"2020-09-01T11:56:23 -02:00\",\n    \"latitude\": -78.793525,\n    \"longitude\": 114.977976,\n    \"tags\": [\n      \"ipsum\",\n      \"aliquip\",\n      \"magna\",\n      \"dolor\",\n      \"veniam\",\n      \"tempor\",\n      \"laboris\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Heather Potter\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Joanne Rosa\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Carolina Garrison\"\n      }\n    ],\n    \"greeting\": \"Hello, Hendrix Monroe! You have 4 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee54baf7e744e51dad9\",\n    \"index\": 29,\n    \"guid\": \"3f9f9d6e-da28-401e-a606-bbf5251ce38d\",\n    \"isActive\": false,\n    \"balance\": \"$1,550.72\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Black Reid\",\n    \"gender\": \"male\",\n    \"company\": \"NEUROCELL\",\n    \"email\": \"blackreid@neurocell.com\",\n    \"phone\": \"+1 (910) 525-2563\",\n    \"address\": \"925 Tompkins Place, Vicksburg, Idaho, 1574\",\n    \"about\": \"Magna proident proident sunt duis. Est incididunt sit incididunt ut eu Lorem nisi sint eiusmod esse officia incididunt exercitation enim. Pariatur commodo velit qui ipsum ullamco nulla. Est dolor mollit minim amet aliqua excepteur esse velit nulla aliquip labore fugiat ex ullamco. Aute ipsum sit veniam est minim duis elit dolore sunt nulla sunt.\\r\\n\",\n    \"registered\": \"2015-12-13T07:16:39 -01:00\",\n    \"latitude\": -54.537678,\n    \"longitude\": 107.957571,\n    \"tags\": [\n      \"aliqua\",\n      \"pariatur\",\n      \"est\",\n      \"nisi\",\n      \"adipisicing\",\n      \"dolor\",\n      \"fugiat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Joyce Lucas\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Roxanne Pate\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Winnie Yates\"\n      }\n    ],\n    \"greeting\": \"Hello, Black Reid! You have 10 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5df64007f20643ae7\",\n    \"index\": 30,\n    \"guid\": \"64ae68a8-dee2-443a-81db-03a99b63ab84\",\n    \"isActive\": false,\n    \"balance\": \"$3,986.64\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"green\",\n    \"name\": \"Mason Pierce\",\n    \"gender\": \"male\",\n    \"company\": \"REMOTION\",\n    \"email\": \"masonpierce@remotion.com\",\n    \"phone\": \"+1 (817) 422-3872\",\n    \"address\": \"760 Melrose Street, Sanborn, New Mexico, 3484\",\n    \"about\": \"Nulla voluptate consequat aliquip excepteur eu. Occaecat irure exercitation quis labore veniam ea enim ullamco esse excepteur labore. Velit est incididunt duis qui et eiusmod nulla sit dolor culpa. Duis velit laboris proident veniam amet dolore exercitation anim. Ipsum cillum pariatur cillum velit. Occaecat occaecat Lorem magna occaecat exercitation dolore sint sint. Excepteur ex sint quis consequat ullamco adipisicing laborum Lorem sunt ea quis non.\\r\\n\",\n    \"registered\": \"2017-06-05T05:39:46 -02:00\",\n    \"latitude\": 50.544792,\n    \"longitude\": -161.516331,\n    \"tags\": [\n      \"eu\",\n      \"ullamco\",\n      \"nisi\",\n      \"eiusmod\",\n      \"enim\",\n      \"proident\",\n      \"cillum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Alta Benson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Blackwell Chapman\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Herrera Oliver\"\n      }\n    ],\n    \"greeting\": \"Hello, Mason Pierce! You have 4 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5b8304aafdd8be1aa\",\n    \"index\": 31,\n    \"guid\": \"1f761267-ec0e-4f31-a66a-b984121858a6\",\n    \"isActive\": false,\n    \"balance\": \"$2,018.19\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 37,\n    \"eyeColor\": \"green\",\n    \"name\": \"Madge Sloan\",\n    \"gender\": \"female\",\n    \"company\": \"GALLAXIA\",\n    \"email\": \"madgesloan@gallaxia.com\",\n    \"phone\": \"+1 (849) 456-2573\",\n    \"address\": \"261 Lombardy Street, Gambrills, Minnesota, 5509\",\n    \"about\": \"Aliqua in deserunt ex occaecat. Laboris ullamco Lorem cupidatat incididunt non amet Lorem adipisicing qui labore. Ea et voluptate pariatur excepteur nostrud laboris. Excepteur ad nulla aute nostrud commodo occaecat nostrud tempor cillum in occaecat occaecat et. Voluptate et fugiat voluptate aliquip nisi ea veniam fugiat nulla ut dolore consectetur exercitation. Ea quis et laboris ex amet.\\r\\n\",\n    \"registered\": \"2018-06-21T11:39:57 -02:00\",\n    \"latitude\": 1.190471,\n    \"longitude\": 41.557569,\n    \"tags\": [\n      \"velit\",\n      \"qui\",\n      \"dolore\",\n      \"amet\",\n      \"ipsum\",\n      \"duis\",\n      \"et\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Ware Fuentes\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Hoover Boone\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Morse Cline\"\n      }\n    ],\n    \"greeting\": \"Hello, Madge Sloan! You have 6 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee50afe4dcb59b2f31d\",\n    \"index\": 32,\n    \"guid\": \"56bc1708-fc97-4b09-b85f-1f51422f9ccc\",\n    \"isActive\": true,\n    \"balance\": \"$3,008.31\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 37,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Phelps Sampson\",\n    \"gender\": \"male\",\n    \"company\": \"GLEAMINK\",\n    \"email\": \"phelpssampson@gleamink.com\",\n    \"phone\": \"+1 (841) 589-2176\",\n    \"address\": \"828 Fleet Place, Belvoir, Iowa, 4957\",\n    \"about\": \"Aliqua exercitation dolor qui laboris exercitation aliqua mollit eu ad dolor tempor. Sint ipsum ipsum cillum commodo elit. Pariatur ad veniam elit pariatur consectetur consectetur cupidatat occaecat ullamco anim deserunt aliqua tempor. Veniam mollit anim ex eiusmod. Consectetur veniam deserunt qui sunt elit.\\r\\n\",\n    \"registered\": \"2017-10-22T04:09:39 -02:00\",\n    \"latitude\": 30.261509,\n    \"longitude\": -87.056284,\n    \"tags\": [\n      \"officia\",\n      \"eiusmod\",\n      \"et\",\n      \"in\",\n      \"laborum\",\n      \"proident\",\n      \"cillum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Cooley Gilliam\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Woods Nunez\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Monroe Fleming\"\n      }\n    ],\n    \"greeting\": \"Hello, Phelps Sampson! You have 1 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee55b63b1ce9129c995\",\n    \"index\": 33,\n    \"guid\": \"e18edf1f-256c-41ae-bec0-bb29deb3f2f4\",\n    \"isActive\": true,\n    \"balance\": \"$3,927.59\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Dona Bryant\",\n    \"gender\": \"female\",\n    \"company\": \"EBIDCO\",\n    \"email\": \"donabryant@ebidco.com\",\n    \"phone\": \"+1 (918) 432-2629\",\n    \"address\": \"426 Ferris Street, Snyderville, Maine, 6928\",\n    \"about\": \"Do irure consequat aliqua pariatur cillum exercitation est occaecat. Duis qui irure ipsum anim aute. Laborum consequat nostrud id amet. Laboris esse aute cillum veniam commodo incididunt reprehenderit. In nisi Lorem deserunt sint commodo sint minim. Incididunt dolore Lorem est in cillum aute id nostrud anim sit.\\r\\n\",\n    \"registered\": \"2014-09-27T06:14:41 -02:00\",\n    \"latitude\": 46.864891,\n    \"longitude\": 37.935244,\n    \"tags\": [\n      \"et\",\n      \"minim\",\n      \"occaecat\",\n      \"elit\",\n      \"sint\",\n      \"occaecat\",\n      \"adipisicing\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Parks Henson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Paige Macdonald\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Sharlene Holcomb\"\n      }\n    ],\n    \"greeting\": \"Hello, Dona Bryant! You have 4 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5cdb24ff15c82ab59\",\n    \"index\": 34,\n    \"guid\": \"b2430d4b-b21d-4f3e-8866-7cc7400438a7\",\n    \"isActive\": false,\n    \"balance\": \"$3,606.97\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"green\",\n    \"name\": \"James Foreman\",\n    \"gender\": \"female\",\n    \"company\": \"QUINTITY\",\n    \"email\": \"jamesforeman@quintity.com\",\n    \"phone\": \"+1 (941) 440-3649\",\n    \"address\": \"944 Vandalia Avenue, Rosburg, Tennessee, 3115\",\n    \"about\": \"Voluptate velit magna aute qui mollit consectetur. Elit esse enim exercitation incididunt ullamco eu qui. Ipsum deserunt irure commodo duis dolor reprehenderit nulla proident. Esse sit deserunt nisi culpa amet cupidatat minim dolor magna exercitation. Dolor occaecat ea dolor eiusmod ut voluptate. Non excepteur enim do culpa et aliqua aute consectetur cillum mollit minim tempor.\\r\\n\",\n    \"registered\": \"2020-01-14T07:30:18 -01:00\",\n    \"latitude\": -79.798076,\n    \"longitude\": 174.697346,\n    \"tags\": [\n      \"nulla\",\n      \"incididunt\",\n      \"et\",\n      \"occaecat\",\n      \"non\",\n      \"amet\",\n      \"ex\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Joanna Peters\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Santana Stewart\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Atkins Farmer\"\n      }\n    ],\n    \"greeting\": \"Hello, James Foreman! You have 10 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee535121cb09b60c94b\",\n    \"index\": 35,\n    \"guid\": \"888471d3-29bb-46ed-8397-b06ea2b11266\",\n    \"isActive\": false,\n    \"balance\": \"$1,190.56\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 37,\n    \"eyeColor\": \"green\",\n    \"name\": \"Solis Spence\",\n    \"gender\": \"male\",\n    \"company\": \"STEELFAB\",\n    \"email\": \"solisspence@steelfab.com\",\n    \"phone\": \"+1 (830) 527-2151\",\n    \"address\": \"700 Bryant Street, Magnolia, Palau, 1515\",\n    \"about\": \"Sit mollit magna aute ut id eu commodo culpa aliqua consequat. Nisi do aliqua do est Lorem occaecat tempor consequat aliquip eiusmod. Ullamco ad sit anim excepteur irure exercitation sint ipsum culpa consequat fugiat incididunt adipisicing.\\r\\n\",\n    \"registered\": \"2021-01-11T10:18:43 -01:00\",\n    \"latitude\": 41.499253,\n    \"longitude\": -70.499437,\n    \"tags\": [\n      \"cupidatat\",\n      \"ut\",\n      \"pariatur\",\n      \"ad\",\n      \"excepteur\",\n      \"dolore\",\n      \"eiusmod\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Burks Garcia\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Celia Murray\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Morgan Griffin\"\n      }\n    ],\n    \"greeting\": \"Hello, Solis Spence! You have 6 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee504c87f311e12851b\",\n    \"index\": 36,\n    \"guid\": \"b87f4bff-bb35-429d-81fb-81551c141326\",\n    \"isActive\": true,\n    \"balance\": \"$1,030.03\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"green\",\n    \"name\": \"Stewart Cox\",\n    \"gender\": \"male\",\n    \"company\": \"APPLIDEC\",\n    \"email\": \"stewartcox@applidec.com\",\n    \"phone\": \"+1 (885) 591-2206\",\n    \"address\": \"495 Wolcott Street, Blanco, Kansas, 6801\",\n    \"about\": \"Consectetur magna nisi sunt aute ut. Labore ipsum dolore incididunt cillum minim pariatur ullamco consectetur consectetur ex amet. Ut esse mollit proident labore. Id incididunt velit ullamco ipsum sit laborum consectetur amet amet sint qui. Sint Lorem voluptate ad in.\\r\\n\",\n    \"registered\": \"2020-08-14T12:57:19 -02:00\",\n    \"latitude\": -77.958293,\n    \"longitude\": -99.88448,\n    \"tags\": [\n      \"anim\",\n      \"est\",\n      \"ad\",\n      \"amet\",\n      \"ipsum\",\n      \"aute\",\n      \"non\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Hawkins Holland\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Howe Christian\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Pierce England\"\n      }\n    ],\n    \"greeting\": \"Hello, Stewart Cox! You have 3 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee551d05d5e9ea2aea8\",\n    \"index\": 37,\n    \"guid\": \"2297d1bc-c3bc-45c0-82c6-58918f377292\",\n    \"isActive\": true,\n    \"balance\": \"$3,991.68\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 20,\n    \"eyeColor\": \"green\",\n    \"name\": \"Scott Carlson\",\n    \"gender\": \"male\",\n    \"company\": \"MEDIFAX\",\n    \"email\": \"scottcarlson@medifax.com\",\n    \"phone\": \"+1 (872) 487-2122\",\n    \"address\": \"861 Maple Avenue, Jenkinsville, American Samoa, 430\",\n    \"about\": \"Nulla eu aute sunt Lorem. Dolore nostrud est culpa cillum id ut non nulla consequat quis adipisicing non amet dolore. Cupidatat consectetur nostrud non magna ex elit duis dolore et ex proident reprehenderit. Cupidatat dolore magna officia consequat sint nisi. Dolor anim minim elit ad velit enim et.\\r\\n\",\n    \"registered\": \"2016-04-11T02:29:16 -02:00\",\n    \"latitude\": -57.14206,\n    \"longitude\": 166.771713,\n    \"tags\": [\n      \"nisi\",\n      \"est\",\n      \"nulla\",\n      \"amet\",\n      \"elit\",\n      \"commodo\",\n      \"id\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Cooper Rodgers\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Hobbs Lyons\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Bishop Osborn\"\n      }\n    ],\n    \"greeting\": \"Hello, Scott Carlson! You have 5 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5b0e4061dbb179abe\",\n    \"index\": 38,\n    \"guid\": \"07358e1c-d47f-45b6-a27c-562ee0b1da6c\",\n    \"isActive\": true,\n    \"balance\": \"$2,060.98\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 20,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Lorrie Duke\",\n    \"gender\": \"female\",\n    \"company\": \"ERSUM\",\n    \"email\": \"lorrieduke@ersum.com\",\n    \"phone\": \"+1 (908) 470-2882\",\n    \"address\": \"125 Elm Place, Indio, South Carolina, 9794\",\n    \"about\": \"Dolor exercitation dolore excepteur ut labore ipsum anim laboris pariatur consequat ut deserunt. Irure exercitation eu sunt ad ipsum voluptate sint voluptate nostrud et cillum mollit dolore. Sunt eu voluptate consectetur irure laborum mollit tempor. Incididunt dolor cupidatat est cupidatat laborum ex magna cillum reprehenderit. Incididunt laborum ea culpa tempor.\\r\\n\",\n    \"registered\": \"2018-12-19T03:12:31 -01:00\",\n    \"latitude\": -51.868334,\n    \"longitude\": 168.685644,\n    \"tags\": [\n      \"sit\",\n      \"mollit\",\n      \"id\",\n      \"fugiat\",\n      \"est\",\n      \"qui\",\n      \"eiusmod\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Valentine Mcmahon\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Brenda Moody\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Isabelle Bauer\"\n      }\n    ],\n    \"greeting\": \"Hello, Lorrie Duke! You have 1 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5f7e7af4f05459329\",\n    \"index\": 39,\n    \"guid\": \"1a554877-11db-4475-9587-6fa8d590f2d1\",\n    \"isActive\": true,\n    \"balance\": \"$3,266.49\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 32,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Travis Wagner\",\n    \"gender\": \"male\",\n    \"company\": \"KOFFEE\",\n    \"email\": \"traviswagner@koffee.com\",\n    \"phone\": \"+1 (820) 504-2983\",\n    \"address\": \"395 Garland Court, Sisquoc, Indiana, 4195\",\n    \"about\": \"Excepteur do sint reprehenderit tempor tempor ut ex cupidatat occaecat in. Et amet labore et est. Quis elit aute ullamco deserunt enim elit veniam. Nulla sint qui excepteur esse consectetur.\\r\\n\",\n    \"registered\": \"2019-10-28T03:57:10 -01:00\",\n    \"latitude\": -84.379131,\n    \"longitude\": -0.742789,\n    \"tags\": [\n      \"adipisicing\",\n      \"cillum\",\n      \"Lorem\",\n      \"sint\",\n      \"sunt\",\n      \"incididunt\",\n      \"est\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Baker Lindsay\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Lambert Crawford\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Gilliam Garrett\"\n      }\n    ],\n    \"greeting\": \"Hello, Travis Wagner! You have 4 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5240ea84b61bc4a76\",\n    \"index\": 40,\n    \"guid\": \"c2fdc61e-ba5b-42e8-bc94-204cf93dd757\",\n    \"isActive\": true,\n    \"balance\": \"$2,184.82\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 26,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Buchanan Dillon\",\n    \"gender\": \"male\",\n    \"company\": \"ENDIPINE\",\n    \"email\": \"buchanandillon@endipine.com\",\n    \"phone\": \"+1 (826) 594-2282\",\n    \"address\": \"964 Ruby Street, Wells, District Of Columbia, 2246\",\n    \"about\": \"Aliqua mollit laboris reprehenderit laboris et consectetur amet ullamco pariatur. Laborum tempor enim dolore consectetur excepteur mollit quis voluptate elit. Culpa ad qui magna consequat dolore incididunt cillum magna aliquip duis aliquip cillum irure amet.\\r\\n\",\n    \"registered\": \"2021-01-06T01:32:39 -01:00\",\n    \"latitude\": 60.155664,\n    \"longitude\": -106.658835,\n    \"tags\": [\n      \"qui\",\n      \"nisi\",\n      \"excepteur\",\n      \"nostrud\",\n      \"anim\",\n      \"cupidatat\",\n      \"fugiat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Mccall Noel\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Turner Barlow\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Shannon Carey\"\n      }\n    ],\n    \"greeting\": \"Hello, Buchanan Dillon! You have 7 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5febf6ecbdb248c49\",\n    \"index\": 41,\n    \"guid\": \"46b45b3b-ba2f-4d84-bbb9-f06147e5aee4\",\n    \"isActive\": true,\n    \"balance\": \"$1,050.75\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Terry Wyatt\",\n    \"gender\": \"female\",\n    \"company\": \"FLOTONIC\",\n    \"email\": \"terrywyatt@flotonic.com\",\n    \"phone\": \"+1 (901) 428-2800\",\n    \"address\": \"785 Sedgwick Place, Hamilton, Wyoming, 6047\",\n    \"about\": \"Sint incididunt aliquip id Lorem consequat enim id incididunt veniam ex nisi culpa. Labore enim elit labore voluptate adipisicing magna excepteur nulla. Ea ea laboris nisi incididunt sunt consectetur minim dolor ea sunt laboris adipisicing. Ad Lorem aute nostrud ullamco pariatur culpa fugiat. Excepteur officia laborum in nulla.\\r\\n\",\n    \"registered\": \"2021-05-17T07:53:43 -02:00\",\n    \"latitude\": 21.95598,\n    \"longitude\": -49.266936,\n    \"tags\": [\n      \"anim\",\n      \"velit\",\n      \"sunt\",\n      \"est\",\n      \"reprehenderit\",\n      \"pariatur\",\n      \"consequat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Julia Morgan\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Powell Finch\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Raquel Norton\"\n      }\n    ],\n    \"greeting\": \"Hello, Terry Wyatt! You have 2 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee510bba4e8044c15e4\",\n    \"index\": 42,\n    \"guid\": \"c1891db9-927c-4c85-af33-f3d9cb2c656b\",\n    \"isActive\": true,\n    \"balance\": \"$3,195.20\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"green\",\n    \"name\": \"Todd Irwin\",\n    \"gender\": \"male\",\n    \"company\": \"QUANTALIA\",\n    \"email\": \"toddirwin@quantalia.com\",\n    \"phone\": \"+1 (838) 520-2586\",\n    \"address\": \"829 Lynch Street, Goldfield, Texas, 1303\",\n    \"about\": \"Irure nisi aliqua excepteur cillum culpa adipisicing tempor esse laborum minim mollit minim Lorem deserunt. Nisi do ullamco ut incididunt in proident reprehenderit irure commodo. Tempor culpa consequat duis pariatur id esse excepteur do pariatur do enim. Excepteur eu adipisicing sit cillum ex minim commodo nostrud. Qui anim quis eu elit in fugiat cupidatat deserunt. Minim adipisicing voluptate adipisicing excepteur ipsum anim. Voluptate aliquip pariatur eiusmod amet exercitation reprehenderit ex aliqua officia velit veniam non id ipsum.\\r\\n\",\n    \"registered\": \"2015-05-10T01:00:09 -02:00\",\n    \"latitude\": 1.149855,\n    \"longitude\": -74.439245,\n    \"tags\": [\n      \"cupidatat\",\n      \"amet\",\n      \"nostrud\",\n      \"in\",\n      \"commodo\",\n      \"dolor\",\n      \"in\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Hensley Stevenson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Erna Holden\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Jeannette Bennett\"\n      }\n    ],\n    \"greeting\": \"Hello, Todd Irwin! You have 7 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee59b75013b263b44c0\",\n    \"index\": 43,\n    \"guid\": \"12d2f185-2ae7-4575-b767-e4b97969a9f6\",\n    \"isActive\": false,\n    \"balance\": \"$1,926.98\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 34,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Sosa Greene\",\n    \"gender\": \"male\",\n    \"company\": \"BRAINCLIP\",\n    \"email\": \"sosagreene@brainclip.com\",\n    \"phone\": \"+1 (889) 437-2909\",\n    \"address\": \"853 Moffat Street, Sharon, Rhode Island, 6236\",\n    \"about\": \"Sit non esse cillum laboris duis sit elit excepteur. Nulla occaecat proident voluptate in. Labore proident sint excepteur nisi.\\r\\n\",\n    \"registered\": \"2015-06-15T01:43:42 -02:00\",\n    \"latitude\": -79.172877,\n    \"longitude\": -118.724698,\n    \"tags\": [\n      \"voluptate\",\n      \"mollit\",\n      \"labore\",\n      \"excepteur\",\n      \"Lorem\",\n      \"id\",\n      \"eu\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Charity Hancock\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Lynnette Rocha\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Bettye Rice\"\n      }\n    ],\n    \"greeting\": \"Hello, Sosa Greene! You have 4 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5d054ad3d3cac9ca3\",\n    \"index\": 44,\n    \"guid\": \"19b6577e-ecf0-44e9-a7f8-a5a240f8c1d0\",\n    \"isActive\": false,\n    \"balance\": \"$3,612.86\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 23,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Phyllis Stanton\",\n    \"gender\": \"female\",\n    \"company\": \"SUPREMIA\",\n    \"email\": \"phyllisstanton@supremia.com\",\n    \"phone\": \"+1 (961) 567-2908\",\n    \"address\": \"978 Prospect Place, Tonopah, Louisiana, 3309\",\n    \"about\": \"Tempor irure velit nisi nisi culpa reprehenderit veniam. Occaecat sit dolore duis qui commodo. Deserunt ipsum cillum aute quis elit proident nostrud ut culpa fugiat dolore veniam duis est. Esse qui anim tempor nisi nulla eu Lorem Lorem non. Qui in ipsum do occaecat. Culpa eiusmod do sit dolor anim do aliqua commodo irure veniam culpa ex.\\r\\n\",\n    \"registered\": \"2015-02-15T12:19:34 -01:00\",\n    \"latitude\": 65.254596,\n    \"longitude\": -158.948696,\n    \"tags\": [\n      \"occaecat\",\n      \"nulla\",\n      \"aliquip\",\n      \"pariatur\",\n      \"adipisicing\",\n      \"eiusmod\",\n      \"aliqua\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Katina Kelley\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Trina Decker\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Yesenia Morse\"\n      }\n    ],\n    \"greeting\": \"Hello, Phyllis Stanton! You have 5 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee54a738590c00d6f6c\",\n    \"index\": 45,\n    \"guid\": \"6f784ac9-e607-4d54-9825-8917078c9f4d\",\n    \"isActive\": false,\n    \"balance\": \"$2,127.03\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 20,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Earlene Simon\",\n    \"gender\": \"female\",\n    \"company\": \"RECRISYS\",\n    \"email\": \"earlenesimon@recrisys.com\",\n    \"phone\": \"+1 (831) 576-3334\",\n    \"address\": \"513 Willoughby Avenue, Woodburn, Illinois, 8907\",\n    \"about\": \"Eu tempor occaecat occaecat eu excepteur. Nostrud eu quis proident elit elit reprehenderit velit Lorem magna ullamco sunt. Culpa anim sunt qui consectetur dolor aliquip esse sunt ullamco laborum velit do.\\r\\n\",\n    \"registered\": \"2015-08-18T03:31:15 -02:00\",\n    \"latitude\": 29.413032,\n    \"longitude\": -133.192246,\n    \"tags\": [\n      \"officia\",\n      \"elit\",\n      \"officia\",\n      \"nulla\",\n      \"nisi\",\n      \"sint\",\n      \"irure\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Fitzgerald Vaughan\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Colette Sherman\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Guerrero Glenn\"\n      }\n    ],\n    \"greeting\": \"Hello, Earlene Simon! You have 1 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5dc31908e0d70383a\",\n    \"index\": 46,\n    \"guid\": \"8ce3cbf6-c1d0-4a16-a9e8-77350d24e633\",\n    \"isActive\": true,\n    \"balance\": \"$2,970.73\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 23,\n    \"eyeColor\": \"green\",\n    \"name\": \"Byers Lynch\",\n    \"gender\": \"male\",\n    \"company\": \"HOUSEDOWN\",\n    \"email\": \"byerslynch@housedown.com\",\n    \"phone\": \"+1 (950) 599-3248\",\n    \"address\": \"160 Billings Place, Templeton, Guam, 9434\",\n    \"about\": \"Nostrud nostrud officia aute aliquip proident. Velit commodo exercitation tempor tempor sint et in deserunt magna irure velit velit consequat. Incididunt ea labore mollit sint officia dolore veniam officia. Deserunt ipsum ex Lorem aliqua fugiat aliqua. Duis ea aliqua eiusmod cillum laborum magna.\\r\\n\",\n    \"registered\": \"2019-12-01T08:09:46 -01:00\",\n    \"latitude\": -59.562845,\n    \"longitude\": 72.12822,\n    \"tags\": [\n      \"voluptate\",\n      \"deserunt\",\n      \"elit\",\n      \"do\",\n      \"officia\",\n      \"occaecat\",\n      \"Lorem\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Kramer Kinney\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Dawn Pearson\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Nichole Duffy\"\n      }\n    ],\n    \"greeting\": \"Hello, Byers Lynch! You have 1 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee59ea33052eb3f3a98\",\n    \"index\": 47,\n    \"guid\": \"46c948fd-7040-40dd-b304-1f4956347276\",\n    \"isActive\": true,\n    \"balance\": \"$1,869.34\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Morin Roth\",\n    \"gender\": \"male\",\n    \"company\": \"SONGBIRD\",\n    \"email\": \"morinroth@songbird.com\",\n    \"phone\": \"+1 (841) 553-2216\",\n    \"address\": \"632 Crown Street, Hilltop, New York, 1684\",\n    \"about\": \"Et dolor eu duis laborum ut exercitation amet. Duis dolor eu aliqua velit tempor sunt consequat. Amet cupidatat laborum fugiat cillum sunt ullamco pariatur adipisicing eu ullamco aliquip tempor. Nisi irure irure exercitation ad nulla. Officia do dolor cillum nulla ex laboris.\\r\\n\",\n    \"registered\": \"2017-10-08T07:03:09 -02:00\",\n    \"latitude\": -42.285548,\n    \"longitude\": 2.559845,\n    \"tags\": [\n      \"pariatur\",\n      \"mollit\",\n      \"sint\",\n      \"adipisicing\",\n      \"eiusmod\",\n      \"in\",\n      \"exercitation\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Downs Jefferson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Casey Berger\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Woodard Reeves\"\n      }\n    ],\n    \"greeting\": \"Hello, Morin Roth! You have 4 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5ec78fa21af709610\",\n    \"index\": 48,\n    \"guid\": \"bfa99a20-9473-48f1-83b0-c3212e7ba773\",\n    \"isActive\": false,\n    \"balance\": \"$1,911.55\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"green\",\n    \"name\": \"Marsh Robertson\",\n    \"gender\": \"male\",\n    \"company\": \"OATFARM\",\n    \"email\": \"marshrobertson@oatfarm.com\",\n    \"phone\": \"+1 (880) 493-3836\",\n    \"address\": \"322 Clifford Place, Brogan, Colorado, 323\",\n    \"about\": \"Cillum cupidatat deserunt proident consectetur velit Lorem duis qui veniam ad ea voluptate nisi est. Labore ullamco excepteur quis nostrud elit incididunt esse sunt. Exercitation minim proident veniam reprehenderit nulla tempor laborum enim ut. Excepteur reprehenderit cillum mollit adipisicing eu esse incididunt adipisicing. Minim dolor dolor consequat sunt deserunt id sunt qui eu ipsum sit elit. Exercitation commodo Lorem eu aliquip adipisicing laborum. Ipsum magna pariatur laborum excepteur velit aute dolor mollit.\\r\\n\",\n    \"registered\": \"2019-04-10T05:12:27 -02:00\",\n    \"latitude\": -23.391903,\n    \"longitude\": 119.968307,\n    \"tags\": [\n      \"pariatur\",\n      \"nisi\",\n      \"non\",\n      \"proident\",\n      \"ea\",\n      \"ipsum\",\n      \"cillum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Ballard Watkins\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Gomez Kirby\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Owens Rowland\"\n      }\n    ],\n    \"greeting\": \"Hello, Marsh Robertson! You have 2 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee58fef70f3f6a3945e\",\n    \"index\": 49,\n    \"guid\": \"08682987-0de7-49ce-8874-27eeb1d65fe4\",\n    \"isActive\": true,\n    \"balance\": \"$1,548.47\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Candice Clayton\",\n    \"gender\": \"female\",\n    \"company\": \"SQUISH\",\n    \"email\": \"candiceclayton@squish.com\",\n    \"phone\": \"+1 (852) 570-3839\",\n    \"address\": \"475 Irving Street, Munjor, Michigan, 4000\",\n    \"about\": \"Anim aliqua elit dolor nulla magna. Sunt eu duis Lorem quis labore adipisicing ad irure quis anim ea velit deserunt ut. Aliquip pariatur excepteur ipsum aliqua sunt dolor consequat excepteur laboris mollit. Ex sint do ullamco fugiat sint irure velit enim tempor et voluptate reprehenderit in. Adipisicing Lorem sit in ullamco officia tempor elit consectetur ullamco enim commodo.\\r\\n\",\n    \"registered\": \"2016-10-02T07:11:35 -02:00\",\n    \"latitude\": -28.313052,\n    \"longitude\": -115.536943,\n    \"tags\": [\n      \"commodo\",\n      \"esse\",\n      \"cupidatat\",\n      \"excepteur\",\n      \"proident\",\n      \"eu\",\n      \"enim\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Elva Wilcox\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Francesca Wright\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Humphrey Harvey\"\n      }\n    ],\n    \"greeting\": \"Hello, Candice Clayton! You have 2 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee560bf998ce7115b87\",\n    \"index\": 50,\n    \"guid\": \"ac04a0f6-d028-413d-b605-ff98bec9252c\",\n    \"isActive\": true,\n    \"balance\": \"$3,219.76\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 38,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Miller Hicks\",\n    \"gender\": \"male\",\n    \"company\": \"ZENTHALL\",\n    \"email\": \"millerhicks@zenthall.com\",\n    \"phone\": \"+1 (969) 474-2875\",\n    \"address\": \"810 Orient Avenue, Chicopee, Vermont, 4275\",\n    \"about\": \"Cupidatat aute exercitation pariatur officia mollit minim quis non esse adipisicing ea magna exercitation tempor. Minim eiusmod minim irure deserunt aute velit aute dolore ut. Veniam pariatur dolore officia pariatur amet minim ut dolore adipisicing ipsum deserunt occaecat. Aliqua ut laboris nostrud aliqua ut commodo incididunt exercitation reprehenderit. Exercitation consectetur ex voluptate magna excepteur Lorem minim eiusmod ex voluptate fugiat sit mollit.\\r\\n\",\n    \"registered\": \"2017-02-19T07:43:32 -01:00\",\n    \"latitude\": -47.475337,\n    \"longitude\": 27.342601,\n    \"tags\": [\n      \"duis\",\n      \"aute\",\n      \"sit\",\n      \"deserunt\",\n      \"commodo\",\n      \"ex\",\n      \"quis\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Deloris Good\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Hall Hood\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Victoria Howell\"\n      }\n    ],\n    \"greeting\": \"Hello, Miller Hicks! You have 8 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee57688a97ad05b55bf\",\n    \"index\": 51,\n    \"guid\": \"ea98d473-6042-4feb-bfa5-15251453c39f\",\n    \"isActive\": false,\n    \"balance\": \"$1,331.35\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 28,\n    \"eyeColor\": \"green\",\n    \"name\": \"Alma Cantrell\",\n    \"gender\": \"female\",\n    \"company\": \"ASSISTIX\",\n    \"email\": \"almacantrell@assistix.com\",\n    \"phone\": \"+1 (933) 486-3825\",\n    \"address\": \"507 Clara Street, Beaulieu, New Jersey, 2645\",\n    \"about\": \"Quis sint consectetur nostrud ex Lorem sit ex. Pariatur do pariatur veniam do pariatur do proident elit mollit occaecat laboris quis. Aute adipisicing consectetur nisi excepteur.\\r\\n\",\n    \"registered\": \"2016-10-04T10:01:19 -02:00\",\n    \"latitude\": 78.534712,\n    \"longitude\": -58.175918,\n    \"tags\": [\n      \"fugiat\",\n      \"ex\",\n      \"adipisicing\",\n      \"mollit\",\n      \"consectetur\",\n      \"dolor\",\n      \"consectetur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Bradley Dunn\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Griffith Mathis\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Eliza Sykes\"\n      }\n    ],\n    \"greeting\": \"Hello, Alma Cantrell! You have 2 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5a384030e97cade91\",\n    \"index\": 52,\n    \"guid\": \"77c21bae-a235-4604-bc0a-99c24ea18715\",\n    \"isActive\": true,\n    \"balance\": \"$3,365.66\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 31,\n    \"eyeColor\": \"green\",\n    \"name\": \"Christi Goodman\",\n    \"gender\": \"female\",\n    \"company\": \"INRT\",\n    \"email\": \"christigoodman@inrt.com\",\n    \"phone\": \"+1 (988) 524-2396\",\n    \"address\": \"771 Harman Street, Cannondale, Nebraska, 7033\",\n    \"about\": \"Quis eiusmod laborum labore dolore Lorem id deserunt qui commodo ad ipsum. Do exercitation commodo minim ipsum reprehenderit consectetur duis incididunt ea laborum et commodo occaecat tempor. Ipsum aliquip deserunt anim in. Voluptate ex qui nulla consequat ad occaecat voluptate id mollit est esse.\\r\\n\",\n    \"registered\": \"2018-12-15T07:15:02 -01:00\",\n    \"latitude\": 79.208702,\n    \"longitude\": 120.663466,\n    \"tags\": [\n      \"fugiat\",\n      \"fugiat\",\n      \"voluptate\",\n      \"duis\",\n      \"nisi\",\n      \"ut\",\n      \"id\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Matthews Gibbs\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Avery Buck\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Melinda Gill\"\n      }\n    ],\n    \"greeting\": \"Hello, Christi Goodman! You have 1 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee50db39859ed9f88cc\",\n    \"index\": 53,\n    \"guid\": \"80fe502a-9afd-47b0-92ed-5192fec82bee\",\n    \"isActive\": true,\n    \"balance\": \"$1,928.18\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 26,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Marietta Caldwell\",\n    \"gender\": \"female\",\n    \"company\": \"SPACEWAX\",\n    \"email\": \"mariettacaldwell@spacewax.com\",\n    \"phone\": \"+1 (945) 417-2530\",\n    \"address\": \"961 Stockholm Street, Greenfields, North Carolina, 7787\",\n    \"about\": \"Lorem cupidatat cillum aute cupidatat cupidatat. Dolore velit eiusmod ut magna ex proident ex eiusmod non sunt nostrud. Sunt sunt anim eiusmod cupidatat aliqua ut dolor. Est qui culpa sint eiusmod minim laborum consectetur cillum aute ipsum anim sit. Esse culpa officia laboris non excepteur. Id eiusmod fugiat veniam veniam. Excepteur minim occaecat excepteur amet quis nisi irure elit.\\r\\n\",\n    \"registered\": \"2015-12-08T07:15:30 -01:00\",\n    \"latitude\": -70.547153,\n    \"longitude\": -172.745286,\n    \"tags\": [\n      \"ut\",\n      \"id\",\n      \"dolore\",\n      \"cupidatat\",\n      \"id\",\n      \"dolore\",\n      \"anim\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Catherine Cook\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Sparks Chambers\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Casandra Donaldson\"\n      }\n    ],\n    \"greeting\": \"Hello, Marietta Caldwell! You have 10 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee56c53561dec7d9e97\",\n    \"index\": 54,\n    \"guid\": \"51801c1d-c0bc-41ad-9288-08b9cf8147fe\",\n    \"isActive\": true,\n    \"balance\": \"$3,438.20\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 30,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Jolene Browning\",\n    \"gender\": \"female\",\n    \"company\": \"OVOLO\",\n    \"email\": \"jolenebrowning@ovolo.com\",\n    \"phone\": \"+1 (989) 416-2660\",\n    \"address\": \"678 Dahill Road, Spokane, California, 7793\",\n    \"about\": \"Deserunt amet Lorem sit irure. Amet enim officia elit irure quis. Pariatur laborum eiusmod mollit ea id esse aliqua sit deserunt sit nostrud dolore aliqua deserunt. Cupidatat voluptate consectetur duis commodo aliquip fugiat ut ullamco sunt id aliquip. Sit ad amet cupidatat veniam est cillum commodo aute ut.\\r\\n\",\n    \"registered\": \"2014-08-16T05:13:51 -02:00\",\n    \"latitude\": -49.030484,\n    \"longitude\": -28.034224,\n    \"tags\": [\n      \"adipisicing\",\n      \"culpa\",\n      \"in\",\n      \"esse\",\n      \"tempor\",\n      \"nostrud\",\n      \"cillum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Ellis Tanner\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Sloan Meyers\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Cruz Huff\"\n      }\n    ],\n    \"greeting\": \"Hello, Jolene Browning! You have 1 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5688dbd3bef42eca4\",\n    \"index\": 55,\n    \"guid\": \"a11d0cf2-6691-4ef8-ab6e-be0de1a44b7f\",\n    \"isActive\": false,\n    \"balance\": \"$1,298.41\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"green\",\n    \"name\": \"Meyer Brock\",\n    \"gender\": \"male\",\n    \"company\": \"KAGE\",\n    \"email\": \"meyerbrock@kage.com\",\n    \"phone\": \"+1 (943) 461-2183\",\n    \"address\": \"693 Highland Boulevard, Ryderwood, Virgin Islands, 7050\",\n    \"about\": \"Exercitation qui dolore amet magna in duis qui ut laboris sit consectetur in magna. Pariatur eu culpa aliqua irure culpa quis non aliqua. Fugiat do enim commodo ut ullamco ut aute officia. Culpa ullamco consectetur exercitation irure voluptate ullamco proident. Ea et velit duis ad anim excepteur voluptate ex commodo nulla laboris commodo labore consequat. Duis ea mollit amet ullamco in commodo et ea mollit labore quis consequat aute sunt.\\r\\n\",\n    \"registered\": \"2015-05-01T05:09:40 -02:00\",\n    \"latitude\": 15.801415,\n    \"longitude\": 118.939294,\n    \"tags\": [\n      \"id\",\n      \"et\",\n      \"officia\",\n      \"aliqua\",\n      \"laborum\",\n      \"adipisicing\",\n      \"tempor\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Velez Phillips\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Crystal Albert\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Riggs Mayo\"\n      }\n    ],\n    \"greeting\": \"Hello, Meyer Brock! You have 3 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee55af4976e78f1c87c\",\n    \"index\": 56,\n    \"guid\": \"9e592b60-565e-4971-b067-e5c8933ff4a0\",\n    \"isActive\": true,\n    \"balance\": \"$2,744.17\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Rivas Franklin\",\n    \"gender\": \"male\",\n    \"company\": \"KIGGLE\",\n    \"email\": \"rivasfranklin@kiggle.com\",\n    \"phone\": \"+1 (912) 449-3489\",\n    \"address\": \"777 Dorset Street, Welda, Kentucky, 3267\",\n    \"about\": \"Voluptate irure irure sunt officia nisi est non pariatur deserunt eu aute enim veniam enim. Non veniam incididunt ullamco nostrud qui sunt qui fugiat exercitation consectetur esse culpa sit. Esse ullamco cillum magna cillum cillum eu ipsum ea irure commodo Lorem ex sit. Ea minim ipsum culpa est aute nisi irure commodo.\\r\\n\",\n    \"registered\": \"2014-02-25T07:31:23 -01:00\",\n    \"latitude\": -87.409714,\n    \"longitude\": 83.183101,\n    \"tags\": [\n      \"in\",\n      \"aliquip\",\n      \"duis\",\n      \"laborum\",\n      \"occaecat\",\n      \"nostrud\",\n      \"culpa\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Debbie Wolf\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Alice Velez\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Earnestine Hall\"\n      }\n    ],\n    \"greeting\": \"Hello, Rivas Franklin! You have 8 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee598d94cb9e82df264\",\n    \"index\": 57,\n    \"guid\": \"83fa6573-1aaa-43ee-997b-67f83847b64d\",\n    \"isActive\": true,\n    \"balance\": \"$3,829.17\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 30,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Lara Suarez\",\n    \"gender\": \"female\",\n    \"company\": \"TEMORAK\",\n    \"email\": \"larasuarez@temorak.com\",\n    \"phone\": \"+1 (863) 548-2380\",\n    \"address\": \"343 Highland Avenue, Idamay, Alabama, 9118\",\n    \"about\": \"Consequat nostrud excepteur incididunt amet culpa sunt cillum tempor commodo aute eiusmod. Lorem deserunt incididunt id aute ad Lorem velit. Adipisicing ad cupidatat eiusmod commodo cillum velit pariatur laborum do. Amet adipisicing mollit adipisicing ea cillum adipisicing duis mollit enim duis amet mollit. Id ut aliqua ipsum esse ex officia laborum exercitation consequat ad velit. Aliqua consectetur minim excepteur id do eu do excepteur. Ex consequat non elit consectetur et occaecat.\\r\\n\",\n    \"registered\": \"2020-07-23T10:23:47 -02:00\",\n    \"latitude\": -31.975016,\n    \"longitude\": -127.408851,\n    \"tags\": [\n      \"est\",\n      \"tempor\",\n      \"do\",\n      \"ullamco\",\n      \"proident\",\n      \"consequat\",\n      \"ullamco\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Sheri Ortega\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Fay Lynn\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Kasey Thomas\"\n      }\n    ],\n    \"greeting\": \"Hello, Lara Suarez! You have 2 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5661e5c7e9e95e239\",\n    \"index\": 58,\n    \"guid\": \"39be01c4-2eee-426b-992d-e088f764ae93\",\n    \"isActive\": true,\n    \"balance\": \"$3,437.69\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 36,\n    \"eyeColor\": \"green\",\n    \"name\": \"Imelda Mack\",\n    \"gender\": \"female\",\n    \"company\": \"GENMEX\",\n    \"email\": \"imeldamack@genmex.com\",\n    \"phone\": \"+1 (984) 576-3751\",\n    \"address\": \"747 Goodwin Place, Condon, Alaska, 5532\",\n    \"about\": \"Tempor culpa ullamco exercitation ex non pariatur deserunt cillum ex cillum incididunt laborum enim nulla. Lorem nostrud officia ipsum nulla elit velit nulla consequat quis minim mollit Lorem ut tempor. Ipsum exercitation tempor excepteur laborum adipisicing tempor consequat sit magna exercitation nisi.\\r\\n\",\n    \"registered\": \"2016-03-27T05:03:24 -02:00\",\n    \"latitude\": -19.710835,\n    \"longitude\": 152.16424,\n    \"tags\": [\n      \"dolore\",\n      \"ad\",\n      \"fugiat\",\n      \"veniam\",\n      \"occaecat\",\n      \"sit\",\n      \"ea\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Velma Rasmussen\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"John Austin\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Meredith Mckee\"\n      }\n    ],\n    \"greeting\": \"Hello, Imelda Mack! You have 10 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee56b8a2155ed38db7d\",\n    \"index\": 59,\n    \"guid\": \"e15fd3f0-17b8-4039-b5de-95a66eae9eb5\",\n    \"isActive\": false,\n    \"balance\": \"$2,947.08\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Daniels Carver\",\n    \"gender\": \"male\",\n    \"company\": \"STELAECOR\",\n    \"email\": \"danielscarver@stelaecor.com\",\n    \"phone\": \"+1 (950) 599-2404\",\n    \"address\": \"448 Ash Street, Fresno, Missouri, 1774\",\n    \"about\": \"Pariatur quis eu aute quis. Ad veniam laboris ea ex nostrud Lorem consectetur anim nulla exercitation. Dolor nostrud do pariatur consectetur eu quis ex laboris pariatur incididunt irure aliqua. Id pariatur sint incididunt qui quis enim Lorem nostrud aliqua labore labore. Et magna veniam et ipsum occaecat cillum.\\r\\n\",\n    \"registered\": \"2014-05-09T07:22:48 -02:00\",\n    \"latitude\": 31.070703,\n    \"longitude\": 68.089875,\n    \"tags\": [\n      \"sit\",\n      \"veniam\",\n      \"eiusmod\",\n      \"et\",\n      \"enim\",\n      \"magna\",\n      \"nisi\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Maryann Brewer\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Amelia Mccarthy\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Campos Raymond\"\n      }\n    ],\n    \"greeting\": \"Hello, Daniels Carver! You have 1 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5566bb4e1cdc50266\",\n    \"index\": 60,\n    \"guid\": \"980f9e93-01b2-4931-9083-5f2ee498b0c7\",\n    \"isActive\": true,\n    \"balance\": \"$2,524.10\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"green\",\n    \"name\": \"Erica Heath\",\n    \"gender\": \"female\",\n    \"company\": \"ZOGAK\",\n    \"email\": \"ericaheath@zogak.com\",\n    \"phone\": \"+1 (809) 511-3798\",\n    \"address\": \"682 Grove Place, Smock, Hawaii, 9605\",\n    \"about\": \"Sit aliquip proident officia sunt consequat anim ullamco cupidatat ipsum deserunt Lorem ea ullamco. Sunt aliquip eu velit do laboris tempor aliquip ut eu enim pariatur laborum occaecat. Consequat cillum id dolor culpa. Laboris adipisicing irure esse mollit. Labore proident ad consequat dolore veniam labore nostrud pariatur ex consectetur consequat veniam adipisicing enim.\\r\\n\",\n    \"registered\": \"2020-03-12T03:22:33 -01:00\",\n    \"latitude\": -6.031862,\n    \"longitude\": -27.133879,\n    \"tags\": [\n      \"adipisicing\",\n      \"eu\",\n      \"aute\",\n      \"sunt\",\n      \"et\",\n      \"irure\",\n      \"quis\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Ruby Morris\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Langley Espinoza\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Amber Knox\"\n      }\n    ],\n    \"greeting\": \"Hello, Erica Heath! You have 6 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5c8ff9e56fd292de9\",\n    \"index\": 61,\n    \"guid\": \"0069850e-ef43-4445-a49e-bf8a43553e2c\",\n    \"isActive\": true,\n    \"balance\": \"$3,972.66\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"green\",\n    \"name\": \"Bush Quinn\",\n    \"gender\": \"male\",\n    \"company\": \"SKYPLEX\",\n    \"email\": \"bushquinn@skyplex.com\",\n    \"phone\": \"+1 (846) 551-3843\",\n    \"address\": \"304 Carroll Street, Dellview, Ohio, 640\",\n    \"about\": \"Ad id dolor occaecat enim voluptate ex esse cillum adipisicing mollit. Occaecat esse in anim adipisicing deserunt nulla voluptate laboris. Anim cupidatat ea ullamco labore mollit ad duis sunt fugiat proident sit occaecat. Veniam voluptate sunt anim sit laboris est cupidatat enim fugiat exercitation Lorem. Id laborum nulla do eu id ut pariatur quis veniam. Labore quis voluptate veniam sunt sunt esse anim quis eu minim deserunt consequat. Deserunt laborum eiusmod labore anim est in occaecat veniam dolore velit.\\r\\n\",\n    \"registered\": \"2018-03-16T10:35:26 -01:00\",\n    \"latitude\": 81.278949,\n    \"longitude\": -135.73624,\n    \"tags\": [\n      \"dolore\",\n      \"velit\",\n      \"amet\",\n      \"consectetur\",\n      \"fugiat\",\n      \"deserunt\",\n      \"proident\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Gillespie Mcconnell\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Tamra Warren\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Mueller Bates\"\n      }\n    ],\n    \"greeting\": \"Hello, Bush Quinn! You have 6 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee575e5ba14e6103202\",\n    \"index\": 62,\n    \"guid\": \"44dc32a2-c73c-4956-a826-fdf71c6058ea\",\n    \"isActive\": false,\n    \"balance\": \"$3,960.50\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 26,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Melissa Snow\",\n    \"gender\": \"female\",\n    \"company\": \"ECRATER\",\n    \"email\": \"melissasnow@ecrater.com\",\n    \"phone\": \"+1 (828) 454-3847\",\n    \"address\": \"927 Lincoln Terrace, Ironton, Federated States Of Micronesia, 1637\",\n    \"about\": \"Consequat adipisicing fugiat id magna aute nulla magna consectetur pariatur aute irure adipisicing occaecat. Voluptate amet ex aliqua magna ullamco anim reprehenderit. Ipsum dolore laboris elit mollit. Anim officia fugiat enim excepteur minim in eu laborum cillum reprehenderit pariatur. Quis consectetur velit mollit et consectetur eiusmod adipisicing cillum sint.\\r\\n\",\n    \"registered\": \"2017-10-11T05:15:51 -02:00\",\n    \"latitude\": -31.512761,\n    \"longitude\": 56.381299,\n    \"tags\": [\n      \"dolore\",\n      \"fugiat\",\n      \"sunt\",\n      \"in\",\n      \"reprehenderit\",\n      \"ullamco\",\n      \"voluptate\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Kristina Lewis\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Patrick Greer\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Tessa Riley\"\n      }\n    ],\n    \"greeting\": \"Hello, Melissa Snow! You have 5 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5a6348436d4b8e3aa\",\n    \"index\": 63,\n    \"guid\": \"accdd887-fb3f-4431-87d1-7e6fed5e3fc0\",\n    \"isActive\": false,\n    \"balance\": \"$1,645.44\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"green\",\n    \"name\": \"Berta Parsons\",\n    \"gender\": \"female\",\n    \"company\": \"BIOSPAN\",\n    \"email\": \"bertaparsons@biospan.com\",\n    \"phone\": \"+1 (930) 568-2991\",\n    \"address\": \"289 Willoughby Street, Barronett, New Hampshire, 6831\",\n    \"about\": \"Cupidatat dolor sunt commodo eiusmod veniam aliqua occaecat aliquip irure est culpa. Reprehenderit anim ut ad tempor. Ullamco ut dolor sint Lorem aliquip amet ea velit ullamco minim est commodo et. In occaecat nostrud voluptate aliqua sunt duis culpa aute. Exercitation ut eiusmod do incididunt anim cillum.\\r\\n\",\n    \"registered\": \"2017-05-19T10:26:14 -02:00\",\n    \"latitude\": -8.706386,\n    \"longitude\": 34.863032,\n    \"tags\": [\n      \"aliquip\",\n      \"aliquip\",\n      \"aute\",\n      \"est\",\n      \"incididunt\",\n      \"dolor\",\n      \"quis\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Figueroa Willis\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Ortega Chang\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Elena Leach\"\n      }\n    ],\n    \"greeting\": \"Hello, Berta Parsons! You have 8 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5a91304e4f0e3d4d0\",\n    \"index\": 64,\n    \"guid\": \"f3c85339-2374-4f53-98a8-522b1da48644\",\n    \"isActive\": true,\n    \"balance\": \"$3,712.36\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 37,\n    \"eyeColor\": \"green\",\n    \"name\": \"Delgado Vincent\",\n    \"gender\": \"male\",\n    \"company\": \"GRAINSPOT\",\n    \"email\": \"delgadovincent@grainspot.com\",\n    \"phone\": \"+1 (861) 486-2612\",\n    \"address\": \"846 Bokee Court, Springdale, Utah, 2407\",\n    \"about\": \"Occaecat irure irure nisi quis laboris nulla officia quis ullamco ad pariatur ut. Non sunt nisi do cupidatat in ex nulla ut veniam amet. Dolor officia aliquip sunt excepteur mollit magna tempor irure consequat. Cupidatat eiusmod incididunt magna esse id eu tempor. Exercitation non non eu ipsum mollit non elit. Nulla ea ipsum et quis.\\r\\n\",\n    \"registered\": \"2017-10-06T02:51:38 -02:00\",\n    \"latitude\": -0.758576,\n    \"longitude\": -14.711748,\n    \"tags\": [\n      \"ipsum\",\n      \"enim\",\n      \"ipsum\",\n      \"qui\",\n      \"quis\",\n      \"nulla\",\n      \"quis\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Rutledge Arnold\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Fulton Gilbert\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Letha Hughes\"\n      }\n    ],\n    \"greeting\": \"Hello, Delgado Vincent! You have 2 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5b5199e5643998a3d\",\n    \"index\": 65,\n    \"guid\": \"f69b5d62-fd18-43de-97ad-587df7095c59\",\n    \"isActive\": false,\n    \"balance\": \"$1,912.60\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 31,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Fisher Love\",\n    \"gender\": \"male\",\n    \"company\": \"GENMY\",\n    \"email\": \"fisherlove@genmy.com\",\n    \"phone\": \"+1 (904) 458-2710\",\n    \"address\": \"713 Java Street, Linwood, Pennsylvania, 7612\",\n    \"about\": \"Eu consequat minim ut enim esse aute cillum reprehenderit eu magna eu nisi do. Dolor nostrud in magna culpa ea aliquip. Tempor non ipsum aliquip quis aute deserunt consequat incididunt tempor qui culpa magna enim. Enim sit enim nisi ea sunt minim. Ad culpa consequat anim et. Minim excepteur sit fugiat pariatur nisi veniam sunt est aute. Eiusmod sint culpa ipsum sunt ipsum.\\r\\n\",\n    \"registered\": \"2016-11-09T12:00:26 -01:00\",\n    \"latitude\": -9.245969,\n    \"longitude\": 85.988556,\n    \"tags\": [\n      \"est\",\n      \"incididunt\",\n      \"sunt\",\n      \"eiusmod\",\n      \"elit\",\n      \"sunt\",\n      \"ad\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Hudson Slater\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Mullen Hernandez\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Mclean Alston\"\n      }\n    ],\n    \"greeting\": \"Hello, Fisher Love! You have 5 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee50ae252fe1bf85e84\",\n    \"index\": 66,\n    \"guid\": \"bb5c8988-07ac-4f71-abda-cf2a7f409b3c\",\n    \"isActive\": false,\n    \"balance\": \"$3,549.60\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Jerri Leblanc\",\n    \"gender\": \"female\",\n    \"company\": \"BIOHAB\",\n    \"email\": \"jerrileblanc@biohab.com\",\n    \"phone\": \"+1 (898) 560-3924\",\n    \"address\": \"926 Stryker Court, Sparkill, North Dakota, 6900\",\n    \"about\": \"Pariatur ullamco consectetur in labore nisi qui nisi ea veniam amet deserunt do ea. Est Lorem fugiat incididunt dolore tempor labore. Anim excepteur ullamco aute esse laboris elit consectetur laborum do.\\r\\n\",\n    \"registered\": \"2016-05-05T10:51:22 -02:00\",\n    \"latitude\": -11.414042,\n    \"longitude\": 12.354026,\n    \"tags\": [\n      \"eiusmod\",\n      \"veniam\",\n      \"consectetur\",\n      \"officia\",\n      \"ex\",\n      \"mollit\",\n      \"ex\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Yvette Gutierrez\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Tammi Gallegos\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Drake Hale\"\n      }\n    ],\n    \"greeting\": \"Hello, Jerri Leblanc! You have 7 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee54bbee9728857dfbe\",\n    \"index\": 67,\n    \"guid\": \"e310f814-983f-4dc9-b9fe-44002d66e577\",\n    \"isActive\": true,\n    \"balance\": \"$2,722.47\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 36,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Myrtle Sellers\",\n    \"gender\": \"female\",\n    \"company\": \"AVIT\",\n    \"email\": \"myrtlesellers@avit.com\",\n    \"phone\": \"+1 (922) 529-3743\",\n    \"address\": \"577 Hendrix Street, Stollings, Delaware, 9800\",\n    \"about\": \"Anim incididunt occaecat minim dolor sunt sit eiusmod velit. Incididunt ea laboris consequat fugiat occaecat dolore veniam ullamco sunt. Irure excepteur reprehenderit consectetur est sint ullamco dolor culpa dolor occaecat. Labore ut reprehenderit incididunt nulla id nostrud nisi tempor esse. Elit occaecat adipisicing dolor fugiat minim amet cupidatat veniam do enim. Eu non adipisicing quis nulla ut culpa veniam eiusmod elit ea ea. Dolor enim ipsum ut dolor.\\r\\n\",\n    \"registered\": \"2017-09-25T05:56:16 -02:00\",\n    \"latitude\": -55.474082,\n    \"longitude\": 152.176123,\n    \"tags\": [\n      \"ea\",\n      \"dolor\",\n      \"ex\",\n      \"nostrud\",\n      \"ullamco\",\n      \"nostrud\",\n      \"voluptate\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Bird Christensen\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Roseann Franco\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Shepard Summers\"\n      }\n    ],\n    \"greeting\": \"Hello, Myrtle Sellers! You have 2 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5488a7883e3795b64\",\n    \"index\": 68,\n    \"guid\": \"0d5240b7-609a-4121-b5c8-5d0826e73769\",\n    \"isActive\": false,\n    \"balance\": \"$3,109.32\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Muriel Puckett\",\n    \"gender\": \"female\",\n    \"company\": \"VETRON\",\n    \"email\": \"murielpuckett@vetron.com\",\n    \"phone\": \"+1 (950) 494-2441\",\n    \"address\": \"265 Hegeman Avenue, Brenton, Nevada, 964\",\n    \"about\": \"Non nulla enim velit occaecat velit reprehenderit sit esse fugiat elit nulla elit cupidatat amet. Culpa amet dolor reprehenderit Lorem voluptate quis esse nostrud sint nostrud amet. Labore proident amet esse aute in veniam laborum cupidatat nostrud in nisi in. Labore quis aliquip duis non voluptate cillum commodo consectetur. Adipisicing do tempor exercitation pariatur excepteur irure consequat duis. Fugiat officia aliquip fugiat voluptate duis eiusmod enim proident occaecat reprehenderit duis officia.\\r\\n\",\n    \"registered\": \"2020-06-29T12:54:13 -02:00\",\n    \"latitude\": -49.834776,\n    \"longitude\": -34.116946,\n    \"tags\": [\n      \"anim\",\n      \"sit\",\n      \"deserunt\",\n      \"amet\",\n      \"cupidatat\",\n      \"fugiat\",\n      \"sint\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Maureen Mueller\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Merle Parrish\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Brewer Garza\"\n      }\n    ],\n    \"greeting\": \"Hello, Muriel Puckett! You have 4 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee51cd9bee0b10046f7\",\n    \"index\": 69,\n    \"guid\": \"247fc5d6-ec87-4264-9dba-2cb8fa205893\",\n    \"isActive\": false,\n    \"balance\": \"$3,414.00\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Marshall Whitney\",\n    \"gender\": \"male\",\n    \"company\": \"FLYBOYZ\",\n    \"email\": \"marshallwhitney@flyboyz.com\",\n    \"phone\": \"+1 (837) 448-3769\",\n    \"address\": \"336 Dewitt Avenue, Ballico, Montana, 285\",\n    \"about\": \"Aute irure irure dolore enim dolor qui deserunt irure amet. Magna dolore consequat nulla ea amet dolor voluptate officia nisi et. Voluptate nostrud veniam et cillum proident deserunt.\\r\\n\",\n    \"registered\": \"2015-08-18T06:31:54 -02:00\",\n    \"latitude\": -36.503593,\n    \"longitude\": -4.989295,\n    \"tags\": [\n      \"nostrud\",\n      \"id\",\n      \"proident\",\n      \"aute\",\n      \"non\",\n      \"nisi\",\n      \"aute\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Katelyn Glass\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Jill Todd\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Horton Savage\"\n      }\n    ],\n    \"greeting\": \"Hello, Marshall Whitney! You have 5 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5e4cd9807868e1e5a\",\n    \"index\": 70,\n    \"guid\": \"683e4a85-9822-46f6-81f2-f42d4d23b1ab\",\n    \"isActive\": true,\n    \"balance\": \"$2,481.34\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 23,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Bonita Bowers\",\n    \"gender\": \"female\",\n    \"company\": \"GONKLE\",\n    \"email\": \"bonitabowers@gonkle.com\",\n    \"phone\": \"+1 (845) 538-2621\",\n    \"address\": \"916 Beaver Street, Yogaville, Arizona, 3599\",\n    \"about\": \"Tempor eu non Lorem officia nostrud eu esse. Sint commodo qui dolore ullamco non duis sunt dolore proident officia Lorem. Excepteur adipisicing fugiat mollit sit mollit ullamco nostrud esse consectetur. Labore adipisicing anim in cupidatat tempor incididunt pariatur anim. Ad minim elit amet ex ullamco pariatur incididunt esse labore duis. Do irure consectetur consectetur commodo commodo deserunt mollit cupidatat sint anim et irure.\\r\\n\",\n    \"registered\": \"2018-01-06T08:36:22 -01:00\",\n    \"latitude\": 42.190219,\n    \"longitude\": 73.222527,\n    \"tags\": [\n      \"ut\",\n      \"exercitation\",\n      \"sunt\",\n      \"cupidatat\",\n      \"veniam\",\n      \"magna\",\n      \"enim\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Kayla Graham\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Douglas Bullock\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Leanne Snyder\"\n      }\n    ],\n    \"greeting\": \"Hello, Bonita Bowers! You have 7 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5e5e5856723ee6c92\",\n    \"index\": 71,\n    \"guid\": \"1acbaf68-1c32-4485-8658-44f04b6d0e94\",\n    \"isActive\": false,\n    \"balance\": \"$2,195.76\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 36,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Chang Frank\",\n    \"gender\": \"male\",\n    \"company\": \"QOT\",\n    \"email\": \"changfrank@qot.com\",\n    \"phone\": \"+1 (988) 488-2931\",\n    \"address\": \"989 Newport Street, Coldiron, Massachusetts, 7981\",\n    \"about\": \"Do aliquip occaecat do duis veniam proident consequat ad et voluptate reprehenderit nulla. Aliquip ad elit velit excepteur nisi sunt. Adipisicing laborum reprehenderit in proident. Dolore in sit occaecat consequat velit. Culpa proident ex enim fugiat eiusmod consequat pariatur cillum nulla irure do sunt.\\r\\n\",\n    \"registered\": \"2016-09-26T05:49:23 -02:00\",\n    \"latitude\": -85.52177,\n    \"longitude\": -102.815192,\n    \"tags\": [\n      \"nulla\",\n      \"ea\",\n      \"culpa\",\n      \"non\",\n      \"nisi\",\n      \"nostrud\",\n      \"elit\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"French Gillespie\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Valenzuela Horne\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Lyons Smith\"\n      }\n    ],\n    \"greeting\": \"Hello, Chang Frank! You have 6 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee54de6173856f76449\",\n    \"index\": 72,\n    \"guid\": \"596244b0-2cd9-46c9-ba71-1b3b41bf97b8\",\n    \"isActive\": false,\n    \"balance\": \"$3,746.97\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"blue\",\n    \"name\": \"April Schmidt\",\n    \"gender\": \"female\",\n    \"company\": \"DEVILTOE\",\n    \"email\": \"aprilschmidt@deviltoe.com\",\n    \"phone\": \"+1 (948) 453-2579\",\n    \"address\": \"979 Campus Place, Orason, Maryland, 401\",\n    \"about\": \"Velit incididunt labore nulla nostrud eu non cillum velit. Cupidatat aute Lorem nisi adipisicing qui mollit dolor nostrud sunt aute sit. Voluptate aliquip esse Lorem labore ex velit aliquip irure pariatur consequat nostrud aute id eiusmod.\\r\\n\",\n    \"registered\": \"2015-05-08T03:59:24 -02:00\",\n    \"latitude\": -39.956306,\n    \"longitude\": -16.730671,\n    \"tags\": [\n      \"laborum\",\n      \"nostrud\",\n      \"do\",\n      \"Lorem\",\n      \"id\",\n      \"dolor\",\n      \"nulla\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Elba Robinson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Lottie Nicholson\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Mable Durham\"\n      }\n    ],\n    \"greeting\": \"Hello, April Schmidt! You have 5 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee58a16e0b97deba3e0\",\n    \"index\": 73,\n    \"guid\": \"d0099fb6-5552-4a3c-8e28-6a4a1b2e7e5c\",\n    \"isActive\": true,\n    \"balance\": \"$1,205.48\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Nieves Brady\",\n    \"gender\": \"male\",\n    \"company\": \"GUSHKOOL\",\n    \"email\": \"nievesbrady@gushkool.com\",\n    \"phone\": \"+1 (810) 592-2550\",\n    \"address\": \"550 Lake Place, Morningside, Florida, 6574\",\n    \"about\": \"Do Lorem minim anim esse in duis labore ullamco incididunt. Minim qui dolor laborum do sint sunt nisi cillum enim. Ullamco ad ea sit ex laborum excepteur nulla laboris dolore et. Proident do ex elit anim ullamco eu consectetur duis cupidatat fugiat. Mollit cupidatat ea esse esse excepteur ipsum irure eiusmod tempor excepteur irure cillum consectetur ea. Enim irure id et ipsum tempor. Veniam dolore velit non eiusmod dolor do adipisicing nostrud.\\r\\n\",\n    \"registered\": \"2017-02-22T05:23:29 -01:00\",\n    \"latitude\": -17.780885,\n    \"longitude\": 109.581405,\n    \"tags\": [\n      \"non\",\n      \"ad\",\n      \"consectetur\",\n      \"incididunt\",\n      \"fugiat\",\n      \"minim\",\n      \"deserunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Roberta Martinez\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Cameron Stafford\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Sanford Wong\"\n      }\n    ],\n    \"greeting\": \"Hello, Nieves Brady! You have 10 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5e42408a624f51aa5\",\n    \"index\": 74,\n    \"guid\": \"b6622f51-5632-4b61-9c25-d0c00faef236\",\n    \"isActive\": false,\n    \"balance\": \"$3,187.05\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 35,\n    \"eyeColor\": \"green\",\n    \"name\": \"Simon Benjamin\",\n    \"gender\": \"male\",\n    \"company\": \"XANIDE\",\n    \"email\": \"simonbenjamin@xanide.com\",\n    \"phone\": \"+1 (828) 526-2879\",\n    \"address\": \"440 Krier Place, Lookingglass, Washington, 2248\",\n    \"about\": \"Dolore consequat voluptate exercitation tempor. Aute amet labore ut occaecat aliquip elit sunt officia Lorem officia et amet proident. Mollit ea excepteur consequat aliqua. Excepteur duis aliqua magna veniam occaecat mollit culpa ex ipsum enim do et. Amet ullamco consequat velit ipsum proident sint aliquip eu elit dolore fugiat.\\r\\n\",\n    \"registered\": \"2019-06-26T06:58:26 -02:00\",\n    \"latitude\": 47.27387,\n    \"longitude\": 93.247992,\n    \"tags\": [\n      \"esse\",\n      \"adipisicing\",\n      \"labore\",\n      \"ad\",\n      \"tempor\",\n      \"aliquip\",\n      \"est\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Olsen Price\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Sanders Odonnell\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Jimenez Castaneda\"\n      }\n    ],\n    \"greeting\": \"Hello, Simon Benjamin! You have 3 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee56fcd74e494e45c1c\",\n    \"index\": 75,\n    \"guid\": \"4f2feabb-380a-464b-8401-d045ab85ef79\",\n    \"isActive\": true,\n    \"balance\": \"$3,927.33\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 38,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Fox Harding\",\n    \"gender\": \"male\",\n    \"company\": \"MONDICIL\",\n    \"email\": \"foxharding@mondicil.com\",\n    \"phone\": \"+1 (882) 473-3031\",\n    \"address\": \"215 Pioneer Street, Kirk, Virginia, 6835\",\n    \"about\": \"Laborum eiusmod ex sit esse fugiat pariatur dolor tempor aliquip. Non culpa sit occaecat cillum eu amet velit cillum dolore nisi adipisicing labore pariatur. Esse consectetur ullamco aute esse.\\r\\n\",\n    \"registered\": \"2021-09-15T05:35:33 -02:00\",\n    \"latitude\": 35.706083,\n    \"longitude\": -130.293843,\n    \"tags\": [\n      \"Lorem\",\n      \"eu\",\n      \"ex\",\n      \"aliquip\",\n      \"aliquip\",\n      \"incididunt\",\n      \"adipisicing\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Strickland Walker\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Jordan Ellison\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Kimberly Chaney\"\n      }\n    ],\n    \"greeting\": \"Hello, Fox Harding! You have 8 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee59f219a3f643812d1\",\n    \"index\": 76,\n    \"guid\": \"ee011715-e9c5-41ec-a293-cf9cc1646a5a\",\n    \"isActive\": false,\n    \"balance\": \"$3,780.73\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Medina Contreras\",\n    \"gender\": \"male\",\n    \"company\": \"ISOLOGICS\",\n    \"email\": \"medinacontreras@isologics.com\",\n    \"phone\": \"+1 (877) 457-2039\",\n    \"address\": \"532 Brigham Street, Utting, Oklahoma, 5493\",\n    \"about\": \"Voluptate ullamco proident labore esse mollit eu commodo id fugiat veniam sunt proident sunt. Et voluptate commodo amet elit esse amet exercitation ea. Enim ad labore reprehenderit est occaecat id culpa deserunt incididunt deserunt ex non Lorem laboris. Sunt nulla exercitation ex occaecat elit dolor laboris occaecat.\\r\\n\",\n    \"registered\": \"2018-01-30T02:13:15 -01:00\",\n    \"latitude\": 10.048385,\n    \"longitude\": -3.787903,\n    \"tags\": [\n      \"ex\",\n      \"esse\",\n      \"velit\",\n      \"esse\",\n      \"proident\",\n      \"ullamco\",\n      \"minim\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Cheri Burns\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Workman Gallagher\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Knight Long\"\n      }\n    ],\n    \"greeting\": \"Hello, Medina Contreras! You have 1 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee55b417adf49c0624d\",\n    \"index\": 77,\n    \"guid\": \"afb34e70-1dd9-4c0d-a6ac-6a619d59fd19\",\n    \"isActive\": false,\n    \"balance\": \"$1,291.65\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 34,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Bernice Lancaster\",\n    \"gender\": \"female\",\n    \"company\": \"EYEWAX\",\n    \"email\": \"bernicelancaster@eyewax.com\",\n    \"phone\": \"+1 (831) 533-2075\",\n    \"address\": \"242 Grattan Street, Thornport, Mississippi, 6895\",\n    \"about\": \"Enim deserunt eu nostrud minim nostrud ad amet et nostrud mollit elit. Magna occaecat amet magna veniam consectetur ullamco consectetur. Qui duis dolor adipisicing occaecat duis velit nulla consequat. Tempor incididunt deserunt cillum laboris occaecat minim id. Labore Lorem labore esse exercitation ullamco exercitation eu eu.\\r\\n\",\n    \"registered\": \"2017-10-06T12:38:57 -02:00\",\n    \"latitude\": -17.721689,\n    \"longitude\": -129.444642,\n    \"tags\": [\n      \"velit\",\n      \"in\",\n      \"voluptate\",\n      \"nisi\",\n      \"adipisicing\",\n      \"cupidatat\",\n      \"id\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Young Wooten\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Kris Stark\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Gregory Avery\"\n      }\n    ],\n    \"greeting\": \"Hello, Bernice Lancaster! You have 3 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5c57dca9e8bcb4b3c\",\n    \"index\": 78,\n    \"guid\": \"9cf2f752-420c-4df6-9e5b-863de6f6ce12\",\n    \"isActive\": false,\n    \"balance\": \"$1,974.70\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 38,\n    \"eyeColor\": \"green\",\n    \"name\": \"Weaver Beasley\",\n    \"gender\": \"male\",\n    \"company\": \"TELEQUIET\",\n    \"email\": \"weaverbeasley@telequiet.com\",\n    \"phone\": \"+1 (976) 426-2956\",\n    \"address\": \"492 Lott Street, Snowville, Wisconsin, 3924\",\n    \"about\": \"Magna pariatur exercitation laborum cillum occaecat velit deserunt. Dolore nulla eu nulla ea pariatur non culpa eiusmod fugiat dolor laborum. Et sunt ad deserunt et aute laborum voluptate velit quis cupidatat nisi aliqua. Culpa ad sit est consequat ad excepteur anim.\\r\\n\",\n    \"registered\": \"2018-08-18T09:29:43 -02:00\",\n    \"latitude\": 89.801313,\n    \"longitude\": 152.979749,\n    \"tags\": [\n      \"dolore\",\n      \"non\",\n      \"incididunt\",\n      \"sint\",\n      \"incididunt\",\n      \"aute\",\n      \"adipisicing\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Rosales Salinas\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Williamson Haley\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Angeline Klein\"\n      }\n    ],\n    \"greeting\": \"Hello, Weaver Beasley! You have 5 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee58745a42fafd7da82\",\n    \"index\": 79,\n    \"guid\": \"3f63c05f-b732-4e0a-9897-92368eef4fa6\",\n    \"isActive\": true,\n    \"balance\": \"$3,325.06\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 31,\n    \"eyeColor\": \"green\",\n    \"name\": \"Judy Montgomery\",\n    \"gender\": \"female\",\n    \"company\": \"PERKLE\",\n    \"email\": \"judymontgomery@perkle.com\",\n    \"phone\": \"+1 (941) 492-3110\",\n    \"address\": \"403 Sands Street, Greensburg, South Dakota, 8782\",\n    \"about\": \"Dolor officia non id nulla exercitation fugiat nostrud. Incididunt ea eiusmod minim qui nostrud fugiat cillum labore id occaecat. Incididunt deserunt id et fugiat anim.\\r\\n\",\n    \"registered\": \"2015-05-26T06:05:56 -02:00\",\n    \"latitude\": 56.199209,\n    \"longitude\": 168.124642,\n    \"tags\": [\n      \"occaecat\",\n      \"id\",\n      \"exercitation\",\n      \"culpa\",\n      \"consectetur\",\n      \"sit\",\n      \"enim\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Owen Mclaughlin\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Mcfadden Bowen\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Page Leon\"\n      }\n    ],\n    \"greeting\": \"Hello, Judy Montgomery! You have 4 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5a7640d651ba0e2c6\",\n    \"index\": 80,\n    \"guid\": \"46c7961e-8157-4f03-9b6a-25d9ea0b3247\",\n    \"isActive\": false,\n    \"balance\": \"$1,478.12\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 26,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Georgina Shaffer\",\n    \"gender\": \"female\",\n    \"company\": \"MOLTONIC\",\n    \"email\": \"georginashaffer@moltonic.com\",\n    \"phone\": \"+1 (889) 570-2861\",\n    \"address\": \"444 Hale Avenue, Weogufka, Georgia, 8315\",\n    \"about\": \"Veniam mollit esse mollit do non labore aute labore. Duis cillum duis aliqua do. Pariatur irure sit veniam laborum amet duis adipisicing sunt do id aute minim aliquip. Eiusmod ut pariatur id minim ea et dolor aliqua. Nostrud ad qui ad fugiat dolor tempor duis nisi ullamco labore sint Lorem. Consectetur id laborum proident enim incididunt excepteur aliqua esse voluptate tempor. Excepteur dolore nostrud irure officia pariatur eu nostrud ex et.\\r\\n\",\n    \"registered\": \"2021-03-03T07:43:43 -01:00\",\n    \"latitude\": -34.619149,\n    \"longitude\": 100.204642,\n    \"tags\": [\n      \"proident\",\n      \"anim\",\n      \"laboris\",\n      \"culpa\",\n      \"anim\",\n      \"esse\",\n      \"consequat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Johanna Richard\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Herman Casey\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Small Erickson\"\n      }\n    ],\n    \"greeting\": \"Hello, Georgina Shaffer! You have 5 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5fff9a59515fe658d\",\n    \"index\": 81,\n    \"guid\": \"c9598dd8-28bc-4a13-bcec-08b2a36d0dd3\",\n    \"isActive\": true,\n    \"balance\": \"$2,060.91\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 26,\n    \"eyeColor\": \"green\",\n    \"name\": \"Faye Winters\",\n    \"gender\": \"female\",\n    \"company\": \"CENTREXIN\",\n    \"email\": \"fayewinters@centrexin.com\",\n    \"phone\": \"+1 (980) 450-3689\",\n    \"address\": \"532 Albee Square, Orick, Connecticut, 8869\",\n    \"about\": \"Eu et est non ut voluptate cillum occaecat ipsum occaecat consequat adipisicing ipsum dolor. Cupidatat labore ad quis elit minim cillum laborum ea. Reprehenderit labore magna magna culpa amet ullamco nostrud veniam cillum mollit Lorem ullamco ut enim. Do incididunt nulla proident elit esse occaecat. Laboris ea occaecat anim dolore. Sunt deserunt ad occaecat reprehenderit occaecat incididunt velit amet esse. Qui deserunt tempor consectetur esse dolor enim nulla.\\r\\n\",\n    \"registered\": \"2014-07-06T08:30:31 -02:00\",\n    \"latitude\": -28.703521,\n    \"longitude\": 83.875078,\n    \"tags\": [\n      \"dolore\",\n      \"in\",\n      \"proident\",\n      \"consequat\",\n      \"ipsum\",\n      \"veniam\",\n      \"et\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Catalina Weaver\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Neva George\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Bryant Coleman\"\n      }\n    ],\n    \"greeting\": \"Hello, Faye Winters! You have 10 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5de6257ee1a5d39c8\",\n    \"index\": 82,\n    \"guid\": \"fe7ba2a2-1006-45c9-9266-74cf48ff96a8\",\n    \"isActive\": true,\n    \"balance\": \"$2,599.20\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Cohen Knight\",\n    \"gender\": \"male\",\n    \"company\": \"ACUMENTOR\",\n    \"email\": \"cohenknight@acumentor.com\",\n    \"phone\": \"+1 (952) 538-2105\",\n    \"address\": \"558 Canton Court, Winchester, West Virginia, 9458\",\n    \"about\": \"Commodo occaecat ad sunt laborum laboris duis ipsum elit dolore irure. Tempor nisi ex amet aliqua elit enim cillum magna magna laboris. Nisi esse in et sunt duis irure enim. Ad mollit fugiat ex sit occaecat duis in veniam. Adipisicing voluptate deserunt tempor deserunt voluptate. Sint dolor enim eiusmod qui commodo mollit elit magna dolore velit.\\r\\n\",\n    \"registered\": \"2017-06-09T03:09:55 -02:00\",\n    \"latitude\": -22.960099,\n    \"longitude\": 116.764669,\n    \"tags\": [\n      \"fugiat\",\n      \"sint\",\n      \"commodo\",\n      \"dolor\",\n      \"est\",\n      \"ut\",\n      \"pariatur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Webb Morrison\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Walton Mccray\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Green Russell\"\n      }\n    ],\n    \"greeting\": \"Hello, Cohen Knight! You have 5 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee59413e1010491ee60\",\n    \"index\": 83,\n    \"guid\": \"e779fe8b-9bd1-4e9b-9c6e-12643d921609\",\n    \"isActive\": false,\n    \"balance\": \"$2,511.90\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 36,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Barrera Madden\",\n    \"gender\": \"male\",\n    \"company\": \"SARASONIC\",\n    \"email\": \"barreramadden@sarasonic.com\",\n    \"phone\": \"+1 (804) 430-3819\",\n    \"address\": \"266 Ralph Avenue, Ernstville, Marshall Islands, 3976\",\n    \"about\": \"Eu reprehenderit quis laboris elit culpa culpa reprehenderit occaecat. Pariatur esse do proident nulla Lorem dolore eiusmod non eiusmod adipisicing. Ullamco voluptate ipsum aliqua officia commodo nostrud irure. In aliqua incididunt excepteur nostrud voluptate aliqua proident deserunt reprehenderit minim ex quis veniam. Consequat ea adipisicing nulla magna do minim consequat ad.\\r\\n\",\n    \"registered\": \"2016-12-19T06:20:02 -01:00\",\n    \"latitude\": -53.604349,\n    \"longitude\": 18.920039,\n    \"tags\": [\n      \"veniam\",\n      \"consectetur\",\n      \"laborum\",\n      \"laboris\",\n      \"adipisicing\",\n      \"velit\",\n      \"ipsum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"William Burton\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Mcknight Hickman\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Hamilton Flores\"\n      }\n    ],\n    \"greeting\": \"Hello, Barrera Madden! You have 1 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5601516e45042a486\",\n    \"index\": 84,\n    \"guid\": \"2d67cf5b-871d-41a1-990b-4eb3529f7acc\",\n    \"isActive\": true,\n    \"balance\": \"$2,056.88\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 30,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Letitia Gomez\",\n    \"gender\": \"female\",\n    \"company\": \"MEDALERT\",\n    \"email\": \"letitiagomez@medalert.com\",\n    \"phone\": \"+1 (987) 479-3111\",\n    \"address\": \"608 Williamsburg Street, Kipp, Arkansas, 4908\",\n    \"about\": \"Reprehenderit est deserunt pariatur ut exercitation nulla proident qui incididunt exercitation magna aliquip. Adipisicing magna ipsum sit consequat occaecat ut eu eu ullamco velit commodo nostrud. Officia tempor Lorem ipsum pariatur non velit labore incididunt fugiat qui quis. Esse labore ipsum veniam commodo dolore aliquip non elit consectetur adipisicing voluptate magna aliquip elit.\\r\\n\",\n    \"registered\": \"2015-10-25T04:07:20 -01:00\",\n    \"latitude\": -80.11144,\n    \"longitude\": 46.031795,\n    \"tags\": [\n      \"quis\",\n      \"enim\",\n      \"aliqua\",\n      \"aliquip\",\n      \"tempor\",\n      \"consectetur\",\n      \"irure\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Hahn Head\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Edwina Logan\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Jennings Le\"\n      }\n    ],\n    \"greeting\": \"Hello, Letitia Gomez! You have 8 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee53c18157c9e254e9e\",\n    \"index\": 85,\n    \"guid\": \"fb798a9c-64c9-48bd-97c5-c9ea3e059797\",\n    \"isActive\": false,\n    \"balance\": \"$2,736.39\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 28,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Kane Mcintyre\",\n    \"gender\": \"male\",\n    \"company\": \"CALCULA\",\n    \"email\": \"kanemcintyre@calcula.com\",\n    \"phone\": \"+1 (859) 435-3999\",\n    \"address\": \"563 Manhattan Court, Bellamy, Oregon, 9957\",\n    \"about\": \"Quis esse dolore fugiat sint officia. Est cupidatat aliquip mollit elit id amet sit. Mollit quis Lorem elit nostrud esse esse enim est eu irure adipisicing incididunt. Est exercitation officia occaecat do laborum ex amet proident duis amet ea ad. Do est officia eu amet velit magna do ut do.\\r\\n\",\n    \"registered\": \"2014-05-27T02:39:52 -02:00\",\n    \"latitude\": -46.804805,\n    \"longitude\": 132.115786,\n    \"tags\": [\n      \"cupidatat\",\n      \"voluptate\",\n      \"mollit\",\n      \"ad\",\n      \"excepteur\",\n      \"consectetur\",\n      \"id\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Ilene Conway\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Tucker Weber\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Leola Preston\"\n      }\n    ],\n    \"greeting\": \"Hello, Kane Mcintyre! You have 4 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5c61a52d4a9df7c4b\",\n    \"index\": 86,\n    \"guid\": \"e44b6c5b-ec64-4346-8892-544df046ad57\",\n    \"isActive\": true,\n    \"balance\": \"$3,886.52\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"green\",\n    \"name\": \"Witt Cooper\",\n    \"gender\": \"male\",\n    \"company\": \"RUBADUB\",\n    \"email\": \"wittcooper@rubadub.com\",\n    \"phone\": \"+1 (822) 524-3659\",\n    \"address\": \"651 Oriental Court, Gorst, Puerto Rico, 1547\",\n    \"about\": \"Velit laborum nostrud sint cupidatat pariatur labore sint proident. Est anim ex est dolore dolor. Deserunt sunt sit enim velit anim proident veniam enim reprehenderit pariatur consequat culpa. Lorem exercitation anim incididunt duis exercitation anim minim ipsum dolore id sunt ad enim. Laboris officia enim sint incididunt exercitation pariatur cupidatat aute Lorem Lorem pariatur. Ut non aliqua commodo dolor anim. Nisi deserunt eu eiusmod nisi nulla occaecat dolore commodo qui reprehenderit laboris.\\r\\n\",\n    \"registered\": \"2017-06-12T06:44:17 -02:00\",\n    \"latitude\": 48.003669,\n    \"longitude\": 82.759369,\n    \"tags\": [\n      \"ullamco\",\n      \"eiusmod\",\n      \"elit\",\n      \"aliqua\",\n      \"id\",\n      \"aute\",\n      \"aliquip\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Patty Santos\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Ward Diaz\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Lacy Acosta\"\n      }\n    ],\n    \"greeting\": \"Hello, Witt Cooper! You have 5 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee50ae03f090be506ec\",\n    \"index\": 87,\n    \"guid\": \"63b4465e-291c-4f02-ae82-d385cbac9a83\",\n    \"isActive\": false,\n    \"balance\": \"$3,324.57\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 32,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Rosetta Dominguez\",\n    \"gender\": \"female\",\n    \"company\": \"ZIALACTIC\",\n    \"email\": \"rosettadominguez@zialactic.com\",\n    \"phone\": \"+1 (815) 463-2658\",\n    \"address\": \"255 Neptune Court, Worton, Idaho, 8506\",\n    \"about\": \"Consectetur ipsum voluptate sint aliqua. Ea do do ut eiusmod minim laborum nostrud aliquip dolore quis. Proident irure aliqua veniam magna in Lorem adipisicing sunt nisi ut aliquip nostrud cillum. Deserunt deserunt ut laborum id deserunt ea velit ad velit. Aliquip aute eu excepteur commodo pariatur velit ad culpa eu ut veniam nulla. Dolore magna in aliquip fugiat nisi ullamco quis.\\r\\n\",\n    \"registered\": \"2016-02-04T06:03:44 -01:00\",\n    \"latitude\": -50.23274,\n    \"longitude\": 5.595989,\n    \"tags\": [\n      \"nostrud\",\n      \"velit\",\n      \"dolor\",\n      \"aute\",\n      \"enim\",\n      \"dolore\",\n      \"tempor\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Nora Strickland\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Avila Vinson\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Yates Jimenez\"\n      }\n    ],\n    \"greeting\": \"Hello, Rosetta Dominguez! You have 5 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee51f2cf2d86c839226\",\n    \"index\": 88,\n    \"guid\": \"fff4d7f6-c98e-4ea7-81c8-fa78cce883a3\",\n    \"isActive\": false,\n    \"balance\": \"$1,135.65\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"green\",\n    \"name\": \"Sanchez Dejesus\",\n    \"gender\": \"male\",\n    \"company\": \"MAGNAFONE\",\n    \"email\": \"sanchezdejesus@magnafone.com\",\n    \"phone\": \"+1 (996) 442-2836\",\n    \"address\": \"274 Sackman Street, Grantville, New Mexico, 2719\",\n    \"about\": \"Cupidatat tempor adipisicing ea amet elit nulla. Laboris pariatur excepteur adipisicing in in esse Lorem cillum magna adipisicing occaecat sint do excepteur. Velit ex laboris reprehenderit nostrud qui nulla quis et magna dolore Lorem. Occaecat voluptate quis est est qui eiusmod cillum mollit nisi.\\r\\n\",\n    \"registered\": \"2020-07-18T07:07:56 -02:00\",\n    \"latitude\": -52.386326,\n    \"longitude\": 77.613358,\n    \"tags\": [\n      \"tempor\",\n      \"nisi\",\n      \"non\",\n      \"ea\",\n      \"pariatur\",\n      \"deserunt\",\n      \"excepteur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Newman Lowery\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Sherrie Moses\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Schmidt Humphrey\"\n      }\n    ],\n    \"greeting\": \"Hello, Sanchez Dejesus! You have 6 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5fbf395f69add3b2a\",\n    \"index\": 89,\n    \"guid\": \"9197a8fb-4edf-4c30-836e-4a6d9259e2d3\",\n    \"isActive\": true,\n    \"balance\": \"$2,386.91\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Zimmerman Barnett\",\n    \"gender\": \"male\",\n    \"company\": \"COGENTRY\",\n    \"email\": \"zimmermanbarnett@cogentry.com\",\n    \"phone\": \"+1 (973) 479-2787\",\n    \"address\": \"720 Adelphi Street, Evergreen, Minnesota, 3195\",\n    \"about\": \"Exercitation magna cillum aliqua ipsum non eiusmod sit amet consequat. Dolor adipisicing reprehenderit ad elit nulla elit cupidatat esse. Nostrud est esse eu aliqua.\\r\\n\",\n    \"registered\": \"2015-02-04T12:00:42 -01:00\",\n    \"latitude\": -54.731182,\n    \"longitude\": 73.839997,\n    \"tags\": [\n      \"consectetur\",\n      \"esse\",\n      \"laborum\",\n      \"eu\",\n      \"mollit\",\n      \"pariatur\",\n      \"pariatur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Evans Bartlett\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Graciela Sutton\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Manuela Buckley\"\n      }\n    ],\n    \"greeting\": \"Hello, Zimmerman Barnett! You have 8 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee59fbc0b26a9772d9d\",\n    \"index\": 90,\n    \"guid\": \"b49ee567-0dcb-404b-aef5-11778393d05c\",\n    \"isActive\": true,\n    \"balance\": \"$1,128.60\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Burt Griffith\",\n    \"gender\": \"male\",\n    \"company\": \"NAVIR\",\n    \"email\": \"burtgriffith@navir.com\",\n    \"phone\": \"+1 (895) 405-3234\",\n    \"address\": \"445 Broome Street, Newry, Iowa, 9577\",\n    \"about\": \"Ex nisi nostrud irure sint anim aliquip irure ullamco labore nisi enim. Ipsum ea exercitation reprehenderit officia non reprehenderit esse reprehenderit. Excepteur consectetur do occaecat voluptate nulla excepteur aute ipsum sit occaecat veniam est culpa. Voluptate labore adipisicing aliqua ipsum ex velit ex. Laborum eiusmod elit est deserunt proident do cillum magna nisi. Irure esse exercitation cillum commodo exercitation incididunt. Quis duis amet reprehenderit exercitation ea proident magna aliqua culpa.\\r\\n\",\n    \"registered\": \"2016-07-21T09:32:28 -02:00\",\n    \"latitude\": 38.804136,\n    \"longitude\": -43.085181,\n    \"tags\": [\n      \"aute\",\n      \"id\",\n      \"nulla\",\n      \"minim\",\n      \"in\",\n      \"cillum\",\n      \"cupidatat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Weiss Parks\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Mills Tillman\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Frank Battle\"\n      }\n    ],\n    \"greeting\": \"Hello, Burt Griffith! You have 1 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee575c9138dcef6cc81\",\n    \"index\": 91,\n    \"guid\": \"6563360e-e81d-4584-8355-5d3053ac3705\",\n    \"isActive\": true,\n    \"balance\": \"$3,159.26\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 22,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Guy Hull\",\n    \"gender\": \"male\",\n    \"company\": \"CENTREE\",\n    \"email\": \"guyhull@centree.com\",\n    \"phone\": \"+1 (991) 420-3183\",\n    \"address\": \"376 Meserole Avenue, Lindisfarne, Maine, 7382\",\n    \"about\": \"Cupidatat id aute Lorem culpa qui aute tempor velit. Lorem nostrud ad nisi est elit occaecat sint commodo enim pariatur adipisicing est cupidatat do. Eu voluptate quis nulla culpa minim ex elit amet in fugiat. Qui anim qui culpa id excepteur voluptate quis aliquip exercitation duis nulla reprehenderit esse. Incididunt exercitation veniam reprehenderit minim.\\r\\n\",\n    \"registered\": \"2018-12-19T03:20:32 -01:00\",\n    \"latitude\": -19.844991,\n    \"longitude\": 81.78538,\n    \"tags\": [\n      \"culpa\",\n      \"occaecat\",\n      \"exercitation\",\n      \"do\",\n      \"qui\",\n      \"laboris\",\n      \"aliquip\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Donna Webster\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Doris Haney\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Callahan Russo\"\n      }\n    ],\n    \"greeting\": \"Hello, Guy Hull! You have 10 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee504e9fcff8c70b60e\",\n    \"index\": 92,\n    \"guid\": \"fd6af655-6657-406b-a23d-53110c9cf95d\",\n    \"isActive\": true,\n    \"balance\": \"$3,014.49\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Hanson Collier\",\n    \"gender\": \"male\",\n    \"company\": \"DIGIGENE\",\n    \"email\": \"hansoncollier@digigene.com\",\n    \"phone\": \"+1 (923) 430-2739\",\n    \"address\": \"770 Jerome Street, Bourg, Tennessee, 3339\",\n    \"about\": \"Consectetur et eiusmod tempor dolore et do enim dolor irure non nisi laborum commodo. Labore laborum sunt labore laborum quis anim in. Nostrud commodo sit ullamco labore laborum ea sit ea dolor nulla. Nostrud tempor enim eu eu excepteur commodo deserunt pariatur non ullamco.\\r\\n\",\n    \"registered\": \"2017-05-09T08:43:25 -02:00\",\n    \"latitude\": -33.003299,\n    \"longitude\": 152.665408,\n    \"tags\": [\n      \"nulla\",\n      \"eiusmod\",\n      \"occaecat\",\n      \"elit\",\n      \"tempor\",\n      \"velit\",\n      \"nostrud\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Ewing Sims\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Best Wells\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Elma Bentley\"\n      }\n    ],\n    \"greeting\": \"Hello, Hanson Collier! You have 9 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5896c587582655f0f\",\n    \"index\": 93,\n    \"guid\": \"5ad8579b-1c09-4bba-b3fa-e32d66e873bc\",\n    \"isActive\": false,\n    \"balance\": \"$3,147.76\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Celeste Valencia\",\n    \"gender\": \"female\",\n    \"company\": \"INTERODEO\",\n    \"email\": \"celestevalencia@interodeo.com\",\n    \"phone\": \"+1 (920) 502-3800\",\n    \"address\": \"705 Cumberland Walk, Galesville, Palau, 6893\",\n    \"about\": \"Ullamco sunt nisi cupidatat exercitation dolor consequat voluptate do quis reprehenderit veniam. Voluptate amet laboris aliqua ad. Consequat ullamco nostrud do commodo. Est veniam laboris labore aute adipisicing nostrud anim tempor cillum tempor amet.\\r\\n\",\n    \"registered\": \"2016-05-23T10:27:52 -02:00\",\n    \"latitude\": 5.941732,\n    \"longitude\": 40.384341,\n    \"tags\": [\n      \"ex\",\n      \"anim\",\n      \"in\",\n      \"consequat\",\n      \"sit\",\n      \"amet\",\n      \"incididunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Foley Maxwell\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Hardin Carney\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Imogene Larsen\"\n      }\n    ],\n    \"greeting\": \"Hello, Celeste Valencia! You have 2 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee592e5ec83c83124c5\",\n    \"index\": 94,\n    \"guid\": \"34e0221b-f9d3-48bc-b531-d74f4e93cd1d\",\n    \"isActive\": false,\n    \"balance\": \"$2,024.37\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"green\",\n    \"name\": \"Harvey Branch\",\n    \"gender\": \"male\",\n    \"company\": \"ENDIPIN\",\n    \"email\": \"harveybranch@endipin.com\",\n    \"phone\": \"+1 (818) 482-2914\",\n    \"address\": \"481 Carlton Avenue, Dubois, Kansas, 4340\",\n    \"about\": \"Dolore adipisicing cupidatat deserunt irure eu. Ad quis magna aliquip ad amet eiusmod cillum. Tempor culpa non laborum id tempor ea mollit fugiat ullamco. Sunt enim aute incididunt et tempor ex sit elit cillum anim magna aliquip elit irure. Nisi labore culpa dolor proident cupidatat dolore do reprehenderit et esse in. Ipsum magna esse consectetur cupidatat exercitation. Incididunt sint veniam excepteur aliqua enim quis nisi magna aliqua exercitation in ut nisi mollit.\\r\\n\",\n    \"registered\": \"2014-06-21T05:14:50 -02:00\",\n    \"latitude\": 77.561294,\n    \"longitude\": 112.942251,\n    \"tags\": [\n      \"sint\",\n      \"dolor\",\n      \"aliquip\",\n      \"ullamco\",\n      \"Lorem\",\n      \"veniam\",\n      \"amet\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Patricia Herman\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Violet Woodard\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Aguilar Bean\"\n      }\n    ],\n    \"greeting\": \"Hello, Harvey Branch! You have 1 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5324676ddff7be548\",\n    \"index\": 95,\n    \"guid\": \"f7a97aa9-df39-409d-a4d1-ec3114a8542d\",\n    \"isActive\": false,\n    \"balance\": \"$1,259.84\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Huber Woods\",\n    \"gender\": \"male\",\n    \"company\": \"BEZAL\",\n    \"email\": \"huberwoods@bezal.com\",\n    \"phone\": \"+1 (896) 448-2629\",\n    \"address\": \"266 Karweg Place, Comptche, American Samoa, 4929\",\n    \"about\": \"Id ex non magna deserunt consequat enim ea ea ipsum laborum et et sunt enim. Voluptate mollit reprehenderit nisi ullamco labore officia eiusmod dolor mollit. Excepteur exercitation et exercitation ullamco nulla dolore esse. Est nulla dolore ipsum eiusmod nostrud. Consequat duis adipisicing elit incididunt deserunt non.\\r\\n\",\n    \"registered\": \"2016-01-12T06:16:46 -01:00\",\n    \"latitude\": 51.474235,\n    \"longitude\": -80.500097,\n    \"tags\": [\n      \"magna\",\n      \"sunt\",\n      \"ex\",\n      \"ullamco\",\n      \"nulla\",\n      \"proident\",\n      \"velit\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Juana Montoya\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Judith Day\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Franks Ramsey\"\n      }\n    ],\n    \"greeting\": \"Hello, Huber Woods! You have 2 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee56b7bc7cbb0baafd5\",\n    \"index\": 96,\n    \"guid\": \"bbd56fca-faf5-4f4a-9360-3454afae5c74\",\n    \"isActive\": true,\n    \"balance\": \"$3,122.67\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 38,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Susanne Simmons\",\n    \"gender\": \"female\",\n    \"company\": \"QUAILCOM\",\n    \"email\": \"susannesimmons@quailcom.com\",\n    \"phone\": \"+1 (825) 410-2659\",\n    \"address\": \"305 Bridge Street, Gila, South Carolina, 6751\",\n    \"about\": \"Veniam ut dolore sit aliquip et minim qui aliqua mollit ut. Tempor tempor esse sit magna laborum irure quis ad ad fugiat duis ea nulla. Ea ex et ullamco aliquip id amet anim consectetur incididunt irure sunt. Sit adipisicing duis ea nulla nisi excepteur reprehenderit consectetur laboris nisi duis exercitation laboris. Magna elit cupidatat occaecat ad.\\r\\n\",\n    \"registered\": \"2021-09-09T05:19:15 -02:00\",\n    \"latitude\": -85.449409,\n    \"longitude\": 77.309044,\n    \"tags\": [\n      \"voluptate\",\n      \"ipsum\",\n      \"sunt\",\n      \"cupidatat\",\n      \"consectetur\",\n      \"est\",\n      \"non\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Chan Underwood\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Mcclure Callahan\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Miranda Joyce\"\n      }\n    ],\n    \"greeting\": \"Hello, Susanne Simmons! You have 4 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee579be768295851f70\",\n    \"index\": 97,\n    \"guid\": \"e9a2b0fe-8f62-433d-bd41-1da1935c7a59\",\n    \"isActive\": true,\n    \"balance\": \"$3,573.15\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 30,\n    \"eyeColor\": \"green\",\n    \"name\": \"Felicia Shields\",\n    \"gender\": \"female\",\n    \"company\": \"SCENTY\",\n    \"email\": \"feliciashields@scenty.com\",\n    \"phone\": \"+1 (935) 547-2066\",\n    \"address\": \"347 Dennett Place, Oneida, Indiana, 7023\",\n    \"about\": \"Quis exercitation nulla minim anim eu. Voluptate commodo officia ad magna commodo sunt incididunt incididunt in ex pariatur. Lorem laborum dolore deserunt amet ea non minim laborum. Pariatur consectetur elit labore pariatur aute esse veniam anim qui culpa consectetur veniam. Dolore minim aliqua ex anim dolor. Nostrud ex reprehenderit officia sit et esse nostrud exercitation.\\r\\n\",\n    \"registered\": \"2016-01-10T12:31:35 -01:00\",\n    \"latitude\": 26.281283,\n    \"longitude\": 113.533668,\n    \"tags\": [\n      \"velit\",\n      \"et\",\n      \"eiusmod\",\n      \"do\",\n      \"laborum\",\n      \"fugiat\",\n      \"enim\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Cleveland Mcneil\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Curtis Gamble\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Morales Martin\"\n      }\n    ],\n    \"greeting\": \"Hello, Felicia Shields! You have 9 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee53e5dd235e8053c37\",\n    \"index\": 98,\n    \"guid\": \"8e221fd2-c515-4284-9fd4-a7775df1f2b4\",\n    \"isActive\": true,\n    \"balance\": \"$2,692.55\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 30,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Mann Olsen\",\n    \"gender\": \"male\",\n    \"company\": \"COMTEST\",\n    \"email\": \"mannolsen@comtest.com\",\n    \"phone\": \"+1 (999) 536-3881\",\n    \"address\": \"532 Underhill Avenue, Layhill, District Of Columbia, 4860\",\n    \"about\": \"Duis enim voluptate ea minim occaecat tempor non non dolore eiusmod nisi magna. Tempor labore minim consequat esse nostrud qui nisi deserunt dolore nostrud aute ut proident. Aliqua quis mollit non consequat mollit fugiat mollit officia sunt.\\r\\n\",\n    \"registered\": \"2017-10-08T01:26:57 -02:00\",\n    \"latitude\": 75.253375,\n    \"longitude\": -3.856333,\n    \"tags\": [\n      \"exercitation\",\n      \"dolor\",\n      \"mollit\",\n      \"ipsum\",\n      \"ullamco\",\n      \"consequat\",\n      \"ex\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Lane Cote\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Day Shelton\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Mcfarland Vang\"\n      }\n    ],\n    \"greeting\": \"Hello, Mann Olsen! You have 1 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee59e9d3672b44a73c9\",\n    \"index\": 99,\n    \"guid\": \"aab2ebbf-b55b-49aa-9b09-2bcf008cc4a3\",\n    \"isActive\": false,\n    \"balance\": \"$3,809.99\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 33,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Moore Charles\",\n    \"gender\": \"male\",\n    \"company\": \"LINGOAGE\",\n    \"email\": \"moorecharles@lingoage.com\",\n    \"phone\": \"+1 (928) 515-3795\",\n    \"address\": \"679 Falmouth Street, Sattley, Wyoming, 5050\",\n    \"about\": \"Amet eiusmod minim sit sunt nisi ex adipisicing duis id adipisicing sint. Irure qui dolor officia adipisicing laborum enim et eiusmod proident quis nisi eiusmod in irure. Esse voluptate proident labore sunt deserunt occaecat laboris non veniam qui irure minim elit.\\r\\n\",\n    \"registered\": \"2020-06-22T05:09:59 -02:00\",\n    \"latitude\": -78.970897,\n    \"longitude\": 156.447467,\n    \"tags\": [\n      \"sint\",\n      \"magna\",\n      \"nostrud\",\n      \"duis\",\n      \"velit\",\n      \"nulla\",\n      \"consequat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Greer Workman\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Thomas Mclean\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Faith Morrow\"\n      }\n    ],\n    \"greeting\": \"Hello, Moore Charles! You have 5 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee542c1a13a9a5bd8a4\",\n    \"index\": 100,\n    \"guid\": \"2e9f9a53-5cb0-48f7-95e6-2ee8c714b01e\",\n    \"isActive\": false,\n    \"balance\": \"$3,211.40\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Fanny Hooper\",\n    \"gender\": \"female\",\n    \"company\": \"EXOSWITCH\",\n    \"email\": \"fannyhooper@exoswitch.com\",\n    \"phone\": \"+1 (805) 443-2141\",\n    \"address\": \"800 Diamond Street, Dunlo, Texas, 6239\",\n    \"about\": \"Sit amet velit adipisicing irure do culpa exercitation ipsum consectetur ut ullamco sint dolore do. Pariatur nostrud duis reprehenderit deserunt est tempor mollit. Labore nisi sit consequat esse Lorem elit sit voluptate irure est sit. Tempor dolor consequat non aliquip cillum excepteur nisi laboris.\\r\\n\",\n    \"registered\": \"2014-12-11T11:58:48 -01:00\",\n    \"latitude\": -18.659487,\n    \"longitude\": -169.077468,\n    \"tags\": [\n      \"veniam\",\n      \"nostrud\",\n      \"ipsum\",\n      \"est\",\n      \"in\",\n      \"qui\",\n      \"fugiat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Waller Guerra\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Susana Sears\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Augusta Hardy\"\n      }\n    ],\n    \"greeting\": \"Hello, Fanny Hooper! You have 6 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5fe75862454c9af36\",\n    \"index\": 101,\n    \"guid\": \"43f72c32-48f0-4c56-ab4e-ca9e6d365954\",\n    \"isActive\": false,\n    \"balance\": \"$2,862.90\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 22,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Burns Doyle\",\n    \"gender\": \"male\",\n    \"company\": \"ACCIDENCY\",\n    \"email\": \"burnsdoyle@accidency.com\",\n    \"phone\": \"+1 (872) 505-2075\",\n    \"address\": \"518 Vine Street, Day, Rhode Island, 9169\",\n    \"about\": \"Veniam ut deserunt sit aliquip fugiat sunt velit id pariatur eiusmod adipisicing ut deserunt. Laboris quis do ad ad ex nulla. Aliquip commodo id velit elit reprehenderit ad Lorem adipisicing aliquip anim incididunt anim Lorem. Reprehenderit minim enim est velit ad nulla eu est quis adipisicing ex irure sint. Nulla dolore consequat fugiat qui pariatur est in cillum amet id esse. Voluptate et ex nisi aliqua.\\r\\n\",\n    \"registered\": \"2018-07-24T01:37:19 -02:00\",\n    \"latitude\": 63.416847,\n    \"longitude\": 168.31002,\n    \"tags\": [\n      \"ipsum\",\n      \"voluptate\",\n      \"est\",\n      \"nisi\",\n      \"Lorem\",\n      \"cupidatat\",\n      \"irure\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Warner Cannon\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Diann Hamilton\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Cassie Brennan\"\n      }\n    ],\n    \"greeting\": \"Hello, Burns Doyle! You have 6 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5ff778e41a61cb3c2\",\n    \"index\": 102,\n    \"guid\": \"53c08287-83e5-446f-82be-e1f15c36c33c\",\n    \"isActive\": true,\n    \"balance\": \"$1,762.98\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Kristen Cruz\",\n    \"gender\": \"female\",\n    \"company\": \"EMOLTRA\",\n    \"email\": \"kristencruz@emoltra.com\",\n    \"phone\": \"+1 (811) 503-3184\",\n    \"address\": \"460 Seba Avenue, Craig, Louisiana, 6458\",\n    \"about\": \"Aute nulla incididunt aute non culpa tempor. Officia cillum incididunt enim quis qui minim non laborum ad. Ad excepteur pariatur in in adipisicing nisi esse. Duis consequat ipsum velit sint consectetur non do ad velit duis. Ad laboris sit sint qui ad duis.\\r\\n\",\n    \"registered\": \"2018-09-22T03:23:54 -02:00\",\n    \"latitude\": -3.598782,\n    \"longitude\": -157.623,\n    \"tags\": [\n      \"adipisicing\",\n      \"incididunt\",\n      \"Lorem\",\n      \"ad\",\n      \"consequat\",\n      \"excepteur\",\n      \"esse\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Colon Cabrera\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Reilly Hogan\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Baxter Pitts\"\n      }\n    ],\n    \"greeting\": \"Hello, Kristen Cruz! You have 1 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee58978c913fd05de17\",\n    \"index\": 103,\n    \"guid\": \"56ce0615-4cb0-4fbf-b1fb-3dc253fa84ef\",\n    \"isActive\": true,\n    \"balance\": \"$3,448.36\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 31,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Carmen Merritt\",\n    \"gender\": \"female\",\n    \"company\": \"NEWCUBE\",\n    \"email\": \"carmenmerritt@newcube.com\",\n    \"phone\": \"+1 (947) 497-3698\",\n    \"address\": \"732 Pilling Street, Macdona, Illinois, 7468\",\n    \"about\": \"Aute non cillum ad sunt qui incididunt nulla et mollit mollit. Nostrud officia laborum tempor quis deserunt aute duis nostrud cillum consectetur. Aute magna officia magna minim dolor ipsum non est Lorem dolore. Labore dolore laboris qui officia. Proident irure aliqua occaecat eu nisi cupidatat excepteur dolor amet nostrud sint consectetur quis.\\r\\n\",\n    \"registered\": \"2017-11-28T04:52:57 -01:00\",\n    \"latitude\": 36.670108,\n    \"longitude\": -173.405707,\n    \"tags\": [\n      \"ex\",\n      \"tempor\",\n      \"labore\",\n      \"nostrud\",\n      \"ex\",\n      \"occaecat\",\n      \"ut\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Rios Davenport\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Berg Burks\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Jennifer Roberts\"\n      }\n    ],\n    \"greeting\": \"Hello, Carmen Merritt! You have 1 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5fee688c4e4c84984\",\n    \"index\": 104,\n    \"guid\": \"048dcbfa-6a51-40e1-85fd-8705b6641a10\",\n    \"isActive\": true,\n    \"balance\": \"$3,726.61\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 36,\n    \"eyeColor\": \"green\",\n    \"name\": \"Sarah Mccarty\",\n    \"gender\": \"female\",\n    \"company\": \"ENOMEN\",\n    \"email\": \"sarahmccarty@enomen.com\",\n    \"phone\": \"+1 (816) 595-3452\",\n    \"address\": \"861 Tech Place, Allensworth, Guam, 2509\",\n    \"about\": \"Velit aute est sit nisi quis excepteur consectetur sint elit veniam ad anim. Nulla sint ut est tempor velit dolor. Voluptate magna quis ut id excepteur deserunt excepteur id officia.\\r\\n\",\n    \"registered\": \"2016-07-17T07:11:27 -02:00\",\n    \"latitude\": 31.270807,\n    \"longitude\": 106.572456,\n    \"tags\": [\n      \"aliquip\",\n      \"voluptate\",\n      \"deserunt\",\n      \"eiusmod\",\n      \"officia\",\n      \"sunt\",\n      \"est\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Helene Delacruz\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Lang Vega\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Nichols Jarvis\"\n      }\n    ],\n    \"greeting\": \"Hello, Sarah Mccarty! You have 4 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5b24846b1bfddb800\",\n    \"index\": 105,\n    \"guid\": \"ead72d6a-52ff-452f-8ebb-5d732ccf53ff\",\n    \"isActive\": false,\n    \"balance\": \"$1,796.53\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 30,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Albert Singleton\",\n    \"gender\": \"male\",\n    \"company\": \"JASPER\",\n    \"email\": \"albertsingleton@jasper.com\",\n    \"phone\": \"+1 (944) 442-2620\",\n    \"address\": \"281 Utica Avenue, Concho, New York, 5728\",\n    \"about\": \"Amet tempor culpa aute nisi nisi et ad enim minim tempor excepteur quis dolore. Non commodo nisi mollit occaecat. Et in nostrud eiusmod anim magna magna ex in nostrud nostrud sint. Consequat incididunt cillum proident sunt. Duis fugiat reprehenderit labore laborum proident exercitation consectetur tempor elit culpa nulla consequat voluptate proident. Eiusmod cillum fugiat tempor irure voluptate minim culpa labore mollit ex nostrud veniam sunt.\\r\\n\",\n    \"registered\": \"2019-06-16T10:41:09 -02:00\",\n    \"latitude\": -56.50538,\n    \"longitude\": 123.835799,\n    \"tags\": [\n      \"pariatur\",\n      \"velit\",\n      \"qui\",\n      \"veniam\",\n      \"occaecat\",\n      \"deserunt\",\n      \"deserunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Angelique Williamson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Rollins Allen\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Eunice Roberson\"\n      }\n    ],\n    \"greeting\": \"Hello, Albert Singleton! You have 6 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5a512597622f8405c\",\n    \"index\": 106,\n    \"guid\": \"29bd21fe-bb3e-42f0-82e8-1a4cc8eb4782\",\n    \"isActive\": false,\n    \"balance\": \"$2,399.49\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 28,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Darla Cummings\",\n    \"gender\": \"female\",\n    \"company\": \"EXOPLODE\",\n    \"email\": \"darlacummings@exoplode.com\",\n    \"phone\": \"+1 (809) 466-2125\",\n    \"address\": \"355 Morton Street, Florence, Colorado, 7993\",\n    \"about\": \"Cillum eu aliqua in sunt pariatur aute est culpa cupidatat aliquip amet et et ad. Minim non ipsum Lorem occaecat mollit ad deserunt in. Ad aute veniam nulla ut fugiat nisi ex adipisicing.\\r\\n\",\n    \"registered\": \"2017-02-20T12:58:33 -01:00\",\n    \"latitude\": -50.399431,\n    \"longitude\": 1.746477,\n    \"tags\": [\n      \"culpa\",\n      \"nostrud\",\n      \"reprehenderit\",\n      \"voluptate\",\n      \"qui\",\n      \"ex\",\n      \"quis\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Lourdes Sandoval\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Teresa Bender\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"House Guy\"\n      }\n    ],\n    \"greeting\": \"Hello, Darla Cummings! You have 10 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5646a712e42e42d54\",\n    \"index\": 107,\n    \"guid\": \"8ed48af3-9867-42da-9f11-6e71b9fcdfc7\",\n    \"isActive\": true,\n    \"balance\": \"$1,877.89\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Mayo Chavez\",\n    \"gender\": \"male\",\n    \"company\": \"IMAGEFLOW\",\n    \"email\": \"mayochavez@imageflow.com\",\n    \"phone\": \"+1 (897) 517-3214\",\n    \"address\": \"524 Garden Street, Elliston, Michigan, 5221\",\n    \"about\": \"Ad veniam veniam aliqua officia minim magna. Ullamco minim labore in consequat aliquip aute consequat do ex enim est minim quis Lorem. Ea nostrud proident incididunt labore ut. Sit esse ad nostrud exercitation consectetur et exercitation nisi do nostrud. Nisi fugiat sint sunt eu sit. Sint adipisicing reprehenderit do sit commodo quis duis qui nisi anim elit.\\r\\n\",\n    \"registered\": \"2018-01-14T05:52:16 -01:00\",\n    \"latitude\": -73.533217,\n    \"longitude\": 83.232772,\n    \"tags\": [\n      \"ullamco\",\n      \"quis\",\n      \"veniam\",\n      \"non\",\n      \"anim\",\n      \"laborum\",\n      \"cupidatat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Therese Knapp\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"York Randall\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Agnes Perez\"\n      }\n    ],\n    \"greeting\": \"Hello, Mayo Chavez! You have 10 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5f4e4b3ca1015a2e6\",\n    \"index\": 108,\n    \"guid\": \"0f187167-29f8-41a7-9da9-701e4b75007f\",\n    \"isActive\": false,\n    \"balance\": \"$2,346.21\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Moon Grimes\",\n    \"gender\": \"male\",\n    \"company\": \"EVENTEX\",\n    \"email\": \"moongrimes@eventex.com\",\n    \"phone\": \"+1 (878) 427-2258\",\n    \"address\": \"400 Hamilton Walk, Caroline, Vermont, 6144\",\n    \"about\": \"Officia ut laboris ipsum qui officia laborum. Incididunt ex ad nulla consectetur deserunt. Ea fugiat adipisicing sint ea irure ad voluptate dolor qui dolore commodo labore. Enim elit cillum ut esse do sunt. Dolore laboris cillum ut aliqua id in id non officia in consequat anim duis. Et sit incididunt nostrud enim aute proident amet occaecat officia Lorem aute aute pariatur.\\r\\n\",\n    \"registered\": \"2021-06-04T05:52:41 -02:00\",\n    \"latitude\": -16.977217,\n    \"longitude\": 90.202875,\n    \"tags\": [\n      \"cupidatat\",\n      \"aute\",\n      \"laboris\",\n      \"proident\",\n      \"excepteur\",\n      \"elit\",\n      \"aliqua\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Jasmine Mccullough\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Della Campos\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Savage Burnett\"\n      }\n    ],\n    \"greeting\": \"Hello, Moon Grimes! You have 9 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5dc91e2cd0ccd66c6\",\n    \"index\": 109,\n    \"guid\": \"738ae92a-28cb-4f10-8dcb-a036cfac0d9e\",\n    \"isActive\": false,\n    \"balance\": \"$2,367.15\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 26,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Griffin Richardson\",\n    \"gender\": \"male\",\n    \"company\": \"ARTIQ\",\n    \"email\": \"griffinrichardson@artiq.com\",\n    \"phone\": \"+1 (896) 501-2597\",\n    \"address\": \"552 Celeste Court, Limestone, New Jersey, 282\",\n    \"about\": \"Ea officia quis aliqua dolor. Voluptate dolor qui tempor quis esse veniam non aliquip sunt mollit aute tempor. Non Lorem occaecat amet excepteur ipsum officia ipsum fugiat ad incididunt occaecat reprehenderit et. Do in id tempor consequat.\\r\\n\",\n    \"registered\": \"2021-04-27T08:03:39 -02:00\",\n    \"latitude\": -19.972379,\n    \"longitude\": 20.444188,\n    \"tags\": [\n      \"in\",\n      \"magna\",\n      \"amet\",\n      \"consequat\",\n      \"amet\",\n      \"exercitation\",\n      \"qui\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Peggy Santana\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Stella Bond\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Serena Tran\"\n      }\n    ],\n    \"greeting\": \"Hello, Griffin Richardson! You have 7 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee56ba17ed837db4866\",\n    \"index\": 110,\n    \"guid\": \"f789eb81-63a5-4229-8c09-aff43d65ee29\",\n    \"isActive\": true,\n    \"balance\": \"$1,639.00\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 28,\n    \"eyeColor\": \"green\",\n    \"name\": \"Carlene Evans\",\n    \"gender\": \"female\",\n    \"company\": \"BALOOBA\",\n    \"email\": \"carleneevans@balooba.com\",\n    \"phone\": \"+1 (801) 479-2236\",\n    \"address\": \"219 Kenmore Terrace, Dawn, Nebraska, 3489\",\n    \"about\": \"Ipsum magna laborum incididunt consequat laborum aute anim magna id aliquip Lorem pariatur pariatur. Ad deserunt ipsum tempor ut dolore deserunt ad aute cupidatat minim enim mollit veniam. In sit ut reprehenderit ad id ut in enim qui. Nisi ea tempor id pariatur ullamco.\\r\\n\",\n    \"registered\": \"2015-02-07T03:57:54 -01:00\",\n    \"latitude\": -14.520093,\n    \"longitude\": 67.229928,\n    \"tags\": [\n      \"excepteur\",\n      \"do\",\n      \"laborum\",\n      \"minim\",\n      \"aliquip\",\n      \"qui\",\n      \"sint\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Harrison Hinton\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Sasha Mcclure\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"May Oneill\"\n      }\n    ],\n    \"greeting\": \"Hello, Carlene Evans! You have 8 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5693fc5bb2e3e9102\",\n    \"index\": 111,\n    \"guid\": \"a8256fbc-0c8d-4a63-8a06-d424a4531dbc\",\n    \"isActive\": false,\n    \"balance\": \"$1,770.66\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 32,\n    \"eyeColor\": \"green\",\n    \"name\": \"Tracey Goodwin\",\n    \"gender\": \"female\",\n    \"company\": \"ANARCO\",\n    \"email\": \"traceygoodwin@anarco.com\",\n    \"phone\": \"+1 (895) 506-3994\",\n    \"address\": \"852 Bath Avenue, Neahkahnie, North Carolina, 546\",\n    \"about\": \"Aute aliqua reprehenderit exercitation non commodo nostrud nostrud nisi magna. Adipisicing amet esse magna aliquip sit dolor eu. Incididunt est dolor exercitation nostrud do aliqua veniam commodo minim. Enim officia reprehenderit ut sunt. Dolore nulla mollit nostrud cupidatat amet do culpa pariatur dolor dolore deserunt cupidatat.\\r\\n\",\n    \"registered\": \"2020-01-24T12:09:40 -01:00\",\n    \"latitude\": -8.860506,\n    \"longitude\": -124.993792,\n    \"tags\": [\n      \"adipisicing\",\n      \"et\",\n      \"proident\",\n      \"cillum\",\n      \"duis\",\n      \"mollit\",\n      \"non\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Lucas Eaton\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Christy Shepherd\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Brittany Ware\"\n      }\n    ],\n    \"greeting\": \"Hello, Tracey Goodwin! You have 7 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee598277596428abcaa\",\n    \"index\": 112,\n    \"guid\": \"5fe8db13-a665-4a85-893f-9f7949761da9\",\n    \"isActive\": false,\n    \"balance\": \"$1,381.51\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Concetta Talley\",\n    \"gender\": \"female\",\n    \"company\": \"PRIMORDIA\",\n    \"email\": \"concettatalley@primordia.com\",\n    \"phone\": \"+1 (833) 464-3057\",\n    \"address\": \"708 Verona Place, Rosewood, California, 9664\",\n    \"about\": \"Deserunt sit ea consectetur sunt voluptate eiusmod sit do magna in magna. Aliquip consequat proident dolor enim. Anim excepteur laboris velit aliqua aute sit. Culpa mollit Lorem deserunt amet ut duis nulla velit ea. Duis voluptate labore exercitation occaecat. Aliqua nisi cillum velit ut eu in.\\r\\n\",\n    \"registered\": \"2016-06-11T01:52:50 -02:00\",\n    \"latitude\": 2.891685,\n    \"longitude\": -146.243358,\n    \"tags\": [\n      \"laboris\",\n      \"ullamco\",\n      \"consectetur\",\n      \"ipsum\",\n      \"ex\",\n      \"do\",\n      \"cillum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"England Howard\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Kathleen Matthews\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Herminia Cleveland\"\n      }\n    ],\n    \"greeting\": \"Hello, Concetta Talley! You have 6 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5a308124c877dd354\",\n    \"index\": 113,\n    \"guid\": \"6e965ad6-ae69-4570-adfc-76b12a7061e6\",\n    \"isActive\": true,\n    \"balance\": \"$2,182.02\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 37,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Misty Nieves\",\n    \"gender\": \"female\",\n    \"company\": \"KNOWLYSIS\",\n    \"email\": \"mistynieves@knowlysis.com\",\n    \"phone\": \"+1 (973) 426-2333\",\n    \"address\": \"284 Seaview Court, Coalmont, Virgin Islands, 4581\",\n    \"about\": \"Ullamco nisi tempor veniam nulla tempor irure incididunt voluptate Lorem labore et duis sit id. Aute adipisicing consectetur deserunt magna anim enim non non dolor non in irure. Consectetur irure officia culpa laboris. Magna sint aliquip velit magna ad.\\r\\n\",\n    \"registered\": \"2017-04-07T05:20:24 -02:00\",\n    \"latitude\": -89.27099,\n    \"longitude\": -51.65054,\n    \"tags\": [\n      \"Lorem\",\n      \"veniam\",\n      \"labore\",\n      \"commodo\",\n      \"eiusmod\",\n      \"aliqua\",\n      \"pariatur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Mayra Yang\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Kristie Trujillo\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Melton Bruce\"\n      }\n    ],\n    \"greeting\": \"Hello, Misty Nieves! You have 10 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5a7c3133806960204\",\n    \"index\": 114,\n    \"guid\": \"402ab5d2-3ce9-43e0-9090-2faed8749301\",\n    \"isActive\": false,\n    \"balance\": \"$1,154.54\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 22,\n    \"eyeColor\": \"green\",\n    \"name\": \"Jana Hurst\",\n    \"gender\": \"female\",\n    \"company\": \"CUIZINE\",\n    \"email\": \"janahurst@cuizine.com\",\n    \"phone\": \"+1 (828) 537-3567\",\n    \"address\": \"965 Baltic Street, Kempton, Kentucky, 3125\",\n    \"about\": \"Occaecat ea duis proident commodo nostrud tempor anim. Ad cillum magna esse cillum ut nostrud veniam id elit cillum quis occaecat. Sit fugiat dolore Lorem minim nisi occaecat. Ad ea esse labore ut veniam dolor dolore tempor amet incididunt fugiat fugiat nulla. Veniam do consequat excepteur sint reprehenderit magna do sint ad commodo irure laboris sunt. Ut ut Lorem id consectetur ut in nisi ex Lorem. Laborum mollit fugiat laboris magna culpa eu reprehenderit ex commodo eu irure dolore irure.\\r\\n\",\n    \"registered\": \"2014-03-04T08:49:46 -01:00\",\n    \"latitude\": -2.153494,\n    \"longitude\": 28.964035,\n    \"tags\": [\n      \"ea\",\n      \"cupidatat\",\n      \"dolor\",\n      \"labore\",\n      \"et\",\n      \"officia\",\n      \"esse\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Pollard Williams\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Noemi Bailey\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Crane Gould\"\n      }\n    ],\n    \"greeting\": \"Hello, Jana Hurst! You have 7 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee58419e33a2e4071c6\",\n    \"index\": 115,\n    \"guid\": \"15cb2af5-013a-4c3e-8cb5-e00ec62d6b23\",\n    \"isActive\": false,\n    \"balance\": \"$2,929.10\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 36,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Davenport Jacobs\",\n    \"gender\": \"male\",\n    \"company\": \"VIASIA\",\n    \"email\": \"davenportjacobs@viasia.com\",\n    \"phone\": \"+1 (834) 426-2243\",\n    \"address\": \"807 Croton Loop, Chumuckla, Alabama, 9359\",\n    \"about\": \"Elit Lorem nulla consequat do ex ipsum culpa ut aute mollit veniam magna in laborum. Ipsum elit in eiusmod cillum. Ex voluptate aliqua Lorem minim est dolor nisi aute ad anim officia Lorem consequat. Laborum velit velit adipisicing nostrud amet aliquip velit. Fugiat enim ipsum qui velit non laborum quis minim aute qui veniam.\\r\\n\",\n    \"registered\": \"2016-03-30T10:16:18 -02:00\",\n    \"latitude\": 45.568938,\n    \"longitude\": 151.524098,\n    \"tags\": [\n      \"deserunt\",\n      \"non\",\n      \"quis\",\n      \"nisi\",\n      \"id\",\n      \"ut\",\n      \"ad\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Kaufman Meadows\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Sherman Townsend\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Jeanie Walton\"\n      }\n    ],\n    \"greeting\": \"Hello, Davenport Jacobs! You have 10 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee57297824b72767410\",\n    \"index\": 116,\n    \"guid\": \"012ab9cc-2a05-46f9-8066-c6b5261135e9\",\n    \"isActive\": true,\n    \"balance\": \"$2,075.74\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"green\",\n    \"name\": \"Villarreal Watson\",\n    \"gender\": \"male\",\n    \"company\": \"SKINSERVE\",\n    \"email\": \"villarrealwatson@skinserve.com\",\n    \"phone\": \"+1 (988) 545-2746\",\n    \"address\": \"204 Butler Street, Seymour, Alaska, 8598\",\n    \"about\": \"Reprehenderit ipsum dolor eu do aliquip esse duis sit. Sit excepteur anim ea laborum occaecat sunt minim ut. Nisi fugiat ullamco et eiusmod aute ipsum duis ipsum non qui. Officia nulla id laborum et ex exercitation. Ut Lorem voluptate id exercitation ad dolore.\\r\\n\",\n    \"registered\": \"2019-10-29T08:13:49 -01:00\",\n    \"latitude\": 66.95015,\n    \"longitude\": -110.723078,\n    \"tags\": [\n      \"Lorem\",\n      \"irure\",\n      \"veniam\",\n      \"minim\",\n      \"deserunt\",\n      \"consectetur\",\n      \"ea\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Whitfield Pacheco\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Ava Hendrix\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Pansy Armstrong\"\n      }\n    ],\n    \"greeting\": \"Hello, Villarreal Watson! You have 2 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5a1804e5cf5c8a2da\",\n    \"index\": 117,\n    \"guid\": \"7d96956e-8021-4805-83af-f46eae774ed8\",\n    \"isActive\": false,\n    \"balance\": \"$3,506.71\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Key Witt\",\n    \"gender\": \"male\",\n    \"company\": \"RETRACK\",\n    \"email\": \"keywitt@retrack.com\",\n    \"phone\": \"+1 (997) 549-3121\",\n    \"address\": \"560 Howard Place, Naomi, Missouri, 1851\",\n    \"about\": \"Tempor dolor adipisicing elit anim ipsum pariatur excepteur minim magna ut ea eiusmod enim et. Commodo sunt minim eu tempor in pariatur do sit sit ea voluptate duis nisi anim. Commodo magna voluptate enim duis enim pariatur sunt Lorem ea amet reprehenderit velit. Esse in consectetur anim nostrud deserunt.\\r\\n\",\n    \"registered\": \"2021-08-14T05:58:02 -02:00\",\n    \"latitude\": 84.717684,\n    \"longitude\": 58.624277,\n    \"tags\": [\n      \"ut\",\n      \"velit\",\n      \"dolore\",\n      \"nulla\",\n      \"veniam\",\n      \"est\",\n      \"incididunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Benson Atkinson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Mooney Justice\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Madeline Simpson\"\n      }\n    ],\n    \"greeting\": \"Hello, Key Witt! You have 10 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee523f1a061a19a746a\",\n    \"index\": 118,\n    \"guid\": \"8c0f8ef4-1252-41fa-b2ca-43cfc3faecb4\",\n    \"isActive\": true,\n    \"balance\": \"$3,394.22\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 35,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Reyna Hess\",\n    \"gender\": \"female\",\n    \"company\": \"SENMAO\",\n    \"email\": \"reynahess@senmao.com\",\n    \"phone\": \"+1 (968) 556-2373\",\n    \"address\": \"464 Bliss Terrace, Rose, Hawaii, 5301\",\n    \"about\": \"Velit qui commodo in ad eu nostrud. Et proident ipsum esse minim ut labore id laboris non. Exercitation dolor ex in aute aute voluptate laboris non. Dolor duis id enim veniam duis enim adipisicing quis esse. Occaecat elit veniam nisi id labore.\\r\\n\",\n    \"registered\": \"2016-01-13T04:22:55 -01:00\",\n    \"latitude\": 89.970629,\n    \"longitude\": -73.826497,\n    \"tags\": [\n      \"ex\",\n      \"aliqua\",\n      \"occaecat\",\n      \"mollit\",\n      \"tempor\",\n      \"deserunt\",\n      \"aliqua\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Bessie Blankenship\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Price Wynn\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Pate Mcdonald\"\n      }\n    ],\n    \"greeting\": \"Hello, Reyna Hess! You have 5 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee51204288e04108b36\",\n    \"index\": 119,\n    \"guid\": \"8f68e29f-b1ca-4a72-9ced-b3bb765c940e\",\n    \"isActive\": false,\n    \"balance\": \"$3,703.63\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 28,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Little Harris\",\n    \"gender\": \"male\",\n    \"company\": \"ASSISTIA\",\n    \"email\": \"littleharris@assistia.com\",\n    \"phone\": \"+1 (855) 410-3519\",\n    \"address\": \"860 Monroe Street, Brazos, Ohio, 9182\",\n    \"about\": \"Sunt cillum non Lorem irure dolor commodo duis aliquip velit. Dolor consequat laboris id tempor pariatur eu aute Lorem laborum eiusmod ipsum. Et nisi esse sit velit incididunt est non aute officia esse cupidatat sint aliquip. Pariatur laborum proident exercitation veniam est velit irure reprehenderit magna anim fugiat. Incididunt occaecat ex ex id laboris Lorem laborum ipsum enim aute nulla. Fugiat qui aute consectetur magna ea exercitation. Id sunt ex elit eiusmod reprehenderit sunt voluptate labore occaecat esse magna cupidatat amet.\\r\\n\",\n    \"registered\": \"2017-07-21T12:07:11 -02:00\",\n    \"latitude\": -14.944496,\n    \"longitude\": 69.076653,\n    \"tags\": [\n      \"in\",\n      \"duis\",\n      \"in\",\n      \"aliqua\",\n      \"ullamco\",\n      \"aliqua\",\n      \"tempor\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Mcdaniel Drake\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Glass Odom\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Greta Henry\"\n      }\n    ],\n    \"greeting\": \"Hello, Little Harris! You have 6 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5368f1985841bd63e\",\n    \"index\": 120,\n    \"guid\": \"6be4dcaf-3903-416d-b30e-7433e5e18f87\",\n    \"isActive\": true,\n    \"balance\": \"$2,863.43\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Burch Sargent\",\n    \"gender\": \"male\",\n    \"company\": \"LYRICHORD\",\n    \"email\": \"burchsargent@lyrichord.com\",\n    \"phone\": \"+1 (832) 421-2723\",\n    \"address\": \"651 Logan Street, Cherokee, Federated States Of Micronesia, 7175\",\n    \"about\": \"Sit et aliquip ad nostrud amet eiusmod. Voluptate nisi commodo consectetur nulla pariatur laborum Lorem quis ea. Minim consectetur sint enim mollit eu eu esse incididunt labore dolor ad. Tempor commodo officia magna eu elit dolor ipsum adipisicing veniam. Laborum qui cupidatat tempor eu adipisicing Lorem ullamco officia do nulla. Ut nulla irure veniam minim ad enim irure aliquip amet nostrud. Veniam ex cupidatat do minim sint.\\r\\n\",\n    \"registered\": \"2021-04-19T12:03:54 -02:00\",\n    \"latitude\": 24.397213,\n    \"longitude\": 128.277616,\n    \"tags\": [\n      \"aliqua\",\n      \"laboris\",\n      \"culpa\",\n      \"commodo\",\n      \"id\",\n      \"veniam\",\n      \"exercitation\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Magdalena Dodson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Louisa Mcbride\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Marjorie Douglas\"\n      }\n    ],\n    \"greeting\": \"Hello, Burch Sargent! You have 8 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5f1c5804b47fdd710\",\n    \"index\": 121,\n    \"guid\": \"f88f3284-015f-4d80-baf8-3601efa9603a\",\n    \"isActive\": false,\n    \"balance\": \"$1,727.12\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 23,\n    \"eyeColor\": \"green\",\n    \"name\": \"Shanna Jennings\",\n    \"gender\": \"female\",\n    \"company\": \"DANJA\",\n    \"email\": \"shannajennings@danja.com\",\n    \"phone\": \"+1 (998) 567-3816\",\n    \"address\": \"736 Harrison Avenue, Ferney, New Hampshire, 6444\",\n    \"about\": \"Aliquip cillum et irure excepteur mollit amet excepteur voluptate enim sit. Dolore commodo minim incididunt occaecat non. Enim pariatur qui aute quis commodo mollit exercitation labore consequat. Veniam Lorem do deserunt enim in excepteur. Excepteur magna non et in et consectetur irure cillum.\\r\\n\",\n    \"registered\": \"2016-03-21T08:56:43 -01:00\",\n    \"latitude\": -33.174549,\n    \"longitude\": 175.502597,\n    \"tags\": [\n      \"excepteur\",\n      \"aute\",\n      \"ea\",\n      \"non\",\n      \"ut\",\n      \"culpa\",\n      \"enim\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Glenna Mcguire\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Bruce Ayers\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Loraine Rutledge\"\n      }\n    ],\n    \"greeting\": \"Hello, Shanna Jennings! You have 5 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee55b8d496ef84e3b49\",\n    \"index\": 122,\n    \"guid\": \"6f8c48b8-fcf7-4ea2-b131-ba6c215b1b9d\",\n    \"isActive\": false,\n    \"balance\": \"$3,478.45\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"green\",\n    \"name\": \"Hull Gay\",\n    \"gender\": \"male\",\n    \"company\": \"GOKO\",\n    \"email\": \"hullgay@goko.com\",\n    \"phone\": \"+1 (960) 515-2406\",\n    \"address\": \"154 Catherine Street, Gouglersville, Utah, 3057\",\n    \"about\": \"Anim dolore id enim ipsum laboris pariatur cupidatat. Velit dolor fugiat commodo nisi eu enim eiusmod cupidatat ex est eu consequat labore. Ex cillum nostrud dolor officia qui.\\r\\n\",\n    \"registered\": \"2015-01-18T06:51:50 -01:00\",\n    \"latitude\": -3.326571,\n    \"longitude\": 6.706675,\n    \"tags\": [\n      \"veniam\",\n      \"amet\",\n      \"ea\",\n      \"ullamco\",\n      \"officia\",\n      \"proident\",\n      \"nulla\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Oneill Webb\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Goff Moss\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Lois Bowman\"\n      }\n    ],\n    \"greeting\": \"Hello, Hull Gay! You have 10 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee50bc2862d3a72074d\",\n    \"index\": 123,\n    \"guid\": \"39e76b7d-cf55-46c2-987b-41d36de59cac\",\n    \"isActive\": true,\n    \"balance\": \"$1,046.69\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 36,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Lancaster Langley\",\n    \"gender\": \"male\",\n    \"company\": \"ESCHOIR\",\n    \"email\": \"lancasterlangley@eschoir.com\",\n    \"phone\": \"+1 (802) 454-3255\",\n    \"address\": \"673 Woods Place, Waterloo, Pennsylvania, 6059\",\n    \"about\": \"Ex tempor do culpa ut ullamco enim laborum esse nostrud consectetur. Duis culpa ea commodo enim. Aliqua exercitation velit nisi do culpa sunt quis labore laboris dolore qui sit labore cillum. Anim fugiat laborum reprehenderit mollit tempor pariatur irure elit incididunt esse do. Duis enim consequat eu aliqua commodo pariatur officia et. Aute sint do in deserunt ex reprehenderit.\\r\\n\",\n    \"registered\": \"2020-03-06T01:51:07 -01:00\",\n    \"latitude\": 61.468845,\n    \"longitude\": 79.399766,\n    \"tags\": [\n      \"officia\",\n      \"fugiat\",\n      \"aute\",\n      \"voluptate\",\n      \"incididunt\",\n      \"laboris\",\n      \"duis\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Vargas Marshall\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Ayers Frazier\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Harding Farrell\"\n      }\n    ],\n    \"greeting\": \"Hello, Lancaster Langley! You have 3 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5d357af8dfbf142d8\",\n    \"index\": 124,\n    \"guid\": \"f0e805b1-a888-4d21-b19c-414bd4395ef7\",\n    \"isActive\": false,\n    \"balance\": \"$2,441.11\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Brady Jensen\",\n    \"gender\": \"male\",\n    \"company\": \"ASSURITY\",\n    \"email\": \"bradyjensen@assurity.com\",\n    \"phone\": \"+1 (991) 443-3956\",\n    \"address\": \"421 Norwood Avenue, Katonah, North Dakota, 7158\",\n    \"about\": \"Dolore sit nulla cillum ipsum labore eiusmod ullamco irure dolor velit. Voluptate fugiat ex quis ex magna est amet do veniam laboris eiusmod nulla. Veniam eiusmod ea et magna duis Lorem minim. Officia cillum laborum enim anim ea dolore veniam cupidatat amet culpa. Laborum minim eu qui elit elit officia id. Dolore elit et magna est laboris pariatur. Nisi dolore ea nostrud fugiat do cupidatat ullamco fugiat.\\r\\n\",\n    \"registered\": \"2020-10-30T12:18:37 -01:00\",\n    \"latitude\": 84.411873,\n    \"longitude\": 45.44738,\n    \"tags\": [\n      \"esse\",\n      \"nulla\",\n      \"anim\",\n      \"culpa\",\n      \"dolore\",\n      \"nisi\",\n      \"sunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Kelli Nolan\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Soto Oconnor\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Dale Watts\"\n      }\n    ],\n    \"greeting\": \"Hello, Brady Jensen! You have 3 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5345a52e9c6029fbe\",\n    \"index\": 125,\n    \"guid\": \"7e20f6b3-5f35-4447-a15f-aaed93bf70cc\",\n    \"isActive\": false,\n    \"balance\": \"$2,543.84\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 36,\n    \"eyeColor\": \"green\",\n    \"name\": \"Suzette Prince\",\n    \"gender\": \"female\",\n    \"company\": \"OPTIQUE\",\n    \"email\": \"suzetteprince@optique.com\",\n    \"phone\": \"+1 (912) 466-3676\",\n    \"address\": \"276 Lloyd Street, Rivers, Delaware, 7210\",\n    \"about\": \"Laborum ipsum nostrud ea id enim et veniam ex fugiat. Anim do enim irure aliqua anim adipisicing occaecat ea laboris duis ea. Aliquip anim voluptate tempor magna irure laboris culpa aliqua duis et aliqua sunt veniam cupidatat. Quis consectetur cupidatat in mollit velit ad quis incididunt velit culpa qui nisi proident culpa. Nostrud mollit ullamco consequat labore laboris laborum duis elit do id elit. Commodo cupidatat id officia adipisicing anim. Voluptate nisi elit proident nostrud aliqua quis eiusmod do nulla aliqua.\\r\\n\",\n    \"registered\": \"2017-07-08T12:06:37 -02:00\",\n    \"latitude\": -27.095244,\n    \"longitude\": -2.456461,\n    \"tags\": [\n      \"aute\",\n      \"do\",\n      \"est\",\n      \"occaecat\",\n      \"occaecat\",\n      \"nulla\",\n      \"excepteur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Chapman Burris\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Nona Frye\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Moody Bush\"\n      }\n    ],\n    \"greeting\": \"Hello, Suzette Prince! You have 10 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5916a7939844201f9\",\n    \"index\": 126,\n    \"guid\": \"00c8baba-608b-4483-bb86-a0cad75db673\",\n    \"isActive\": false,\n    \"balance\": \"$3,274.41\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Carey Best\",\n    \"gender\": \"female\",\n    \"company\": \"FROSNEX\",\n    \"email\": \"careybest@frosnex.com\",\n    \"phone\": \"+1 (944) 545-3332\",\n    \"address\": \"582 Schenck Place, Hasty, Nevada, 6195\",\n    \"about\": \"Consectetur enim magna dolore aliquip excepteur sint. Eu dolore do laboris dolor occaecat culpa. Adipisicing exercitation nulla officia esse nulla. Adipisicing voluptate cupidatat cupidatat id. Aliquip eu ad amet dolor aute pariatur mollit irure tempor anim ipsum duis occaecat. Duis excepteur adipisicing occaecat sit sit qui dolor labore commodo cupidatat duis.\\r\\n\",\n    \"registered\": \"2017-07-26T06:37:33 -02:00\",\n    \"latitude\": 11.191285,\n    \"longitude\": -47.664887,\n    \"tags\": [\n      \"culpa\",\n      \"nulla\",\n      \"veniam\",\n      \"exercitation\",\n      \"ea\",\n      \"proident\",\n      \"occaecat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Kenya Ferrell\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Nancy White\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Debora Floyd\"\n      }\n    ],\n    \"greeting\": \"Hello, Carey Best! You have 2 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5a0bdc2880cf01ee9\",\n    \"index\": 127,\n    \"guid\": \"765f484b-8e73-4731-a05e-1bc8d05eeba3\",\n    \"isActive\": true,\n    \"balance\": \"$2,645.68\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"green\",\n    \"name\": \"Dixon Baxter\",\n    \"gender\": \"male\",\n    \"company\": \"LUNCHPAD\",\n    \"email\": \"dixonbaxter@lunchpad.com\",\n    \"phone\": \"+1 (954) 413-2958\",\n    \"address\": \"757 Oceanview Avenue, Tuskahoma, Montana, 4014\",\n    \"about\": \"Eu tempor minim nisi veniam adipisicing pariatur adipisicing reprehenderit non. Pariatur aliqua nostrud aliqua aliquip aliqua officia deserunt fugiat quis laborum dolore. Duis mollit cupidatat reprehenderit fugiat voluptate cillum anim consequat consectetur nisi eiusmod. Ad in et nisi exercitation enim pariatur ullamco.\\r\\n\",\n    \"registered\": \"2017-09-09T05:38:33 -02:00\",\n    \"latitude\": -57.733934,\n    \"longitude\": 118.386419,\n    \"tags\": [\n      \"do\",\n      \"eu\",\n      \"laborum\",\n      \"adipisicing\",\n      \"eiusmod\",\n      \"aliqua\",\n      \"enim\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Evangeline Conrad\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Stone House\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Charlene Hoffman\"\n      }\n    ],\n    \"greeting\": \"Hello, Dixon Baxter! You have 4 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee55caa11f9ec247384\",\n    \"index\": 128,\n    \"guid\": \"ceb44e85-56ca-474e-96a6-689002201e18\",\n    \"isActive\": true,\n    \"balance\": \"$2,132.56\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"green\",\n    \"name\": \"Blankenship Nash\",\n    \"gender\": \"male\",\n    \"company\": \"ANDRYX\",\n    \"email\": \"blankenshipnash@andryx.com\",\n    \"phone\": \"+1 (831) 572-2357\",\n    \"address\": \"277 Caton Avenue, Salix, Arizona, 3182\",\n    \"about\": \"Elit ipsum proident cillum aliqua dolor aute dolore aliquip. Consectetur officia amet dolore aute. Dolore deserunt ipsum non do occaecat pariatur ipsum excepteur eu nulla.\\r\\n\",\n    \"registered\": \"2019-11-11T09:37:57 -01:00\",\n    \"latitude\": -42.029524,\n    \"longitude\": -14.476765,\n    \"tags\": [\n      \"labore\",\n      \"magna\",\n      \"anim\",\n      \"ex\",\n      \"commodo\",\n      \"do\",\n      \"fugiat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Marquita Michael\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Nicholson Fields\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Bailey Green\"\n      }\n    ],\n    \"greeting\": \"Hello, Blankenship Nash! You have 7 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5329d0ced30c84919\",\n    \"index\": 129,\n    \"guid\": \"aca5c979-6e75-4e8b-a638-3979e5f5be78\",\n    \"isActive\": false,\n    \"balance\": \"$1,664.09\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 28,\n    \"eyeColor\": \"green\",\n    \"name\": \"Whitehead Craft\",\n    \"gender\": \"male\",\n    \"company\": \"PODUNK\",\n    \"email\": \"whiteheadcraft@podunk.com\",\n    \"phone\": \"+1 (884) 449-3303\",\n    \"address\": \"368 Batchelder Street, Grahamtown, Massachusetts, 8975\",\n    \"about\": \"Magna magna mollit voluptate sint in quis ut. Ad ea aute anim deserunt nulla ut exercitation reprehenderit aute. Tempor deserunt aute non sit proident pariatur et ullamco commodo incididunt ipsum nostrud laboris minim. Aliquip fugiat laboris cupidatat ad deserunt aliqua incididunt. Magna eiusmod excepteur dolor culpa laborum fugiat deserunt. Ex anim enim consectetur ut cillum do. Ex dolore Lorem magna aliqua.\\r\\n\",\n    \"registered\": \"2020-12-19T10:37:45 -01:00\",\n    \"latitude\": -71.80012,\n    \"longitude\": -81.217559,\n    \"tags\": [\n      \"pariatur\",\n      \"ad\",\n      \"aute\",\n      \"excepteur\",\n      \"non\",\n      \"incididunt\",\n      \"elit\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Jewell Alvarez\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Leonor Beck\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Tanisha Dixon\"\n      }\n    ],\n    \"greeting\": \"Hello, Whitehead Craft! You have 10 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee52eadb551f73a8c39\",\n    \"index\": 130,\n    \"guid\": \"3942aab1-dafa-4e54-a1bc-c4c0c864c5d5\",\n    \"isActive\": true,\n    \"balance\": \"$1,251.20\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 35,\n    \"eyeColor\": \"green\",\n    \"name\": \"Sonya Mays\",\n    \"gender\": \"female\",\n    \"company\": \"QIAO\",\n    \"email\": \"sonyamays@qiao.com\",\n    \"phone\": \"+1 (991) 430-3418\",\n    \"address\": \"216 Beekman Place, Tivoli, Maryland, 9536\",\n    \"about\": \"Ex adipisicing elit id nostrud voluptate id. Duis consectetur dolor ullamco magna sint eiusmod velit id laborum consectetur veniam sunt sint. Nulla ad quis fugiat amet. Esse deserunt non eu in excepteur et exercitation duis ut. Excepteur excepteur aute quis ipsum aliqua ea consectetur laborum.\\r\\n\",\n    \"registered\": \"2017-09-18T09:31:43 -02:00\",\n    \"latitude\": 76.178321,\n    \"longitude\": 101.490556,\n    \"tags\": [\n      \"voluptate\",\n      \"qui\",\n      \"ullamco\",\n      \"proident\",\n      \"duis\",\n      \"qui\",\n      \"velit\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Lawrence Munoz\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Salas Blevins\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Spencer Peterson\"\n      }\n    ],\n    \"greeting\": \"Hello, Sonya Mays! You have 8 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5273a8945ceafaac5\",\n    \"index\": 131,\n    \"guid\": \"ce07f84e-46c5-47b1-bd76-41058feec972\",\n    \"isActive\": true,\n    \"balance\": \"$2,224.07\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Daniel Molina\",\n    \"gender\": \"male\",\n    \"company\": \"KAGGLE\",\n    \"email\": \"danielmolina@kaggle.com\",\n    \"phone\": \"+1 (878) 567-2850\",\n    \"address\": \"668 Gunther Place, Moscow, Florida, 9909\",\n    \"about\": \"Non duis ullamco veniam tempor ea aliquip elit elit dolore voluptate. Nostrud adipisicing aliqua cupidatat consectetur velit. Et occaecat cillum commodo nisi duis minim elit. Enim ea ut irure nulla Lorem aliqua duis. Sint magna non pariatur qui voluptate id anim mollit.\\r\\n\",\n    \"registered\": \"2020-07-10T07:52:41 -02:00\",\n    \"latitude\": -32.009865,\n    \"longitude\": -115.605585,\n    \"tags\": [\n      \"irure\",\n      \"voluptate\",\n      \"mollit\",\n      \"elit\",\n      \"laborum\",\n      \"id\",\n      \"duis\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Gay Weeks\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Richard Park\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Saundra Davis\"\n      }\n    ],\n    \"greeting\": \"Hello, Daniel Molina! You have 7 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5e0fdd021cad6ca87\",\n    \"index\": 132,\n    \"guid\": \"abc13b82-fff6-42c9-9197-f726d2189af4\",\n    \"isActive\": false,\n    \"balance\": \"$3,341.78\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 33,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Dianne Vaughn\",\n    \"gender\": \"female\",\n    \"company\": \"OLUCORE\",\n    \"email\": \"diannevaughn@olucore.com\",\n    \"phone\": \"+1 (829) 551-2838\",\n    \"address\": \"908 Gaylord Drive, Morriston, Washington, 6753\",\n    \"about\": \"Laborum incididunt enim Lorem officia qui pariatur nulla velit incididunt dolore sunt. Deserunt duis adipisicing deserunt laborum consequat et adipisicing ex amet ut nostrud. Mollit exercitation nisi dolor occaecat sit et ut deserunt aliqua ea nulla. Incididunt ullamco incididunt est dolor proident nostrud officia non excepteur duis est tempor velit adipisicing. Ipsum anim Lorem aliquip cillum culpa. Eiusmod ea sit culpa veniam pariatur exercitation consequat proident enim ea deserunt velit nulla voluptate. In veniam enim ex commodo esse ullamco.\\r\\n\",\n    \"registered\": \"2014-01-23T12:52:01 -01:00\",\n    \"latitude\": -54.84605,\n    \"longitude\": 96.85212,\n    \"tags\": [\n      \"nulla\",\n      \"cillum\",\n      \"non\",\n      \"excepteur\",\n      \"labore\",\n      \"voluptate\",\n      \"excepteur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Elaine Pope\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Fern York\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Snyder Kidd\"\n      }\n    ],\n    \"greeting\": \"Hello, Dianne Vaughn! You have 1 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5cd56ed53be10231c\",\n    \"index\": 133,\n    \"guid\": \"46d08cb1-76eb-4a31-ba15-e8acab5d34a9\",\n    \"isActive\": true,\n    \"balance\": \"$1,395.71\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"green\",\n    \"name\": \"Jackson Terrell\",\n    \"gender\": \"male\",\n    \"company\": \"GEEKETRON\",\n    \"email\": \"jacksonterrell@geeketron.com\",\n    \"phone\": \"+1 (855) 597-3544\",\n    \"address\": \"150 Navy Walk, Hayden, Virginia, 6685\",\n    \"about\": \"Esse irure adipisicing deserunt cupidatat consequat consectetur minim magna cupidatat exercitation veniam. Irure quis adipisicing esse tempor est nostrud aute consequat quis commodo. Dolor duis labore labore tempor ea. Nostrud consectetur laboris elit cupidatat. Aliqua laborum Lorem ipsum voluptate aute tempor velit consequat id eu exercitation. Anim cillum consequat excepteur aute amet ea ex eu amet aliqua ad. Laboris irure ipsum duis id velit commodo duis.\\r\\n\",\n    \"registered\": \"2017-09-08T06:13:19 -02:00\",\n    \"latitude\": -51.412111,\n    \"longitude\": 97.093973,\n    \"tags\": [\n      \"duis\",\n      \"minim\",\n      \"nisi\",\n      \"officia\",\n      \"id\",\n      \"sunt\",\n      \"magna\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Garza Hudson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Marisol Sweeney\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Leila Hines\"\n      }\n    ],\n    \"greeting\": \"Hello, Jackson Terrell! You have 7 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee50d70020e8c3059bf\",\n    \"index\": 134,\n    \"guid\": \"71800905-d84f-4ea5-b149-24c79bca0e1f\",\n    \"isActive\": false,\n    \"balance\": \"$1,276.62\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 28,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Hutchinson Bird\",\n    \"gender\": \"male\",\n    \"company\": \"BOVIS\",\n    \"email\": \"hutchinsonbird@bovis.com\",\n    \"phone\": \"+1 (801) 502-2174\",\n    \"address\": \"957 Hanson Place, Urie, Oklahoma, 4672\",\n    \"about\": \"Culpa exercitation Lorem ipsum fugiat dolore quis nostrud occaecat voluptate ea ut consequat sint. Incididunt nulla ad fugiat commodo et minim sit adipisicing minim dolor consequat adipisicing. Aliquip quis aute irure nostrud occaecat deserunt duis excepteur consequat occaecat. Proident mollit anim nostrud incididunt aliquip non occaecat magna ullamco ullamco exercitation tempor.\\r\\n\",\n    \"registered\": \"2014-06-23T02:46:14 -02:00\",\n    \"latitude\": 24.063605,\n    \"longitude\": 74.892816,\n    \"tags\": [\n      \"consectetur\",\n      \"Lorem\",\n      \"et\",\n      \"ea\",\n      \"consequat\",\n      \"amet\",\n      \"occaecat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Hester Swanson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Wanda Hammond\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Hansen Becker\"\n      }\n    ],\n    \"greeting\": \"Hello, Hutchinson Bird! You have 6 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee50b0bd5558ff54bc0\",\n    \"index\": 135,\n    \"guid\": \"77a64389-6f3c-43d0-a67c-4dfc4a81193f\",\n    \"isActive\": false,\n    \"balance\": \"$3,708.44\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 22,\n    \"eyeColor\": \"green\",\n    \"name\": \"Tina Mayer\",\n    \"gender\": \"female\",\n    \"company\": \"GLASSTEP\",\n    \"email\": \"tinamayer@glasstep.com\",\n    \"phone\": \"+1 (827) 581-3004\",\n    \"address\": \"734 Forest Place, Curtice, Mississippi, 5989\",\n    \"about\": \"Proident excepteur laboris veniam fugiat sunt. Occaecat et esse ut ullamco nostrud consectetur. Tempor eu sunt ipsum aliquip ullamco ullamco veniam. Tempor occaecat in elit velit aute dolor excepteur sint Lorem commodo Lorem. Occaecat veniam velit labore laborum amet non. Consequat aliquip labore esse elit non sint magna Lorem. Laborum ut deserunt Lorem voluptate nostrud commodo ex.\\r\\n\",\n    \"registered\": \"2015-04-30T03:44:32 -02:00\",\n    \"latitude\": -6.471737,\n    \"longitude\": 165.607896,\n    \"tags\": [\n      \"in\",\n      \"ullamco\",\n      \"cillum\",\n      \"est\",\n      \"et\",\n      \"exercitation\",\n      \"nostrud\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Lidia Combs\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Wheeler Mason\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Meadows Clark\"\n      }\n    ],\n    \"greeting\": \"Hello, Tina Mayer! You have 1 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee511869f2129f874d9\",\n    \"index\": 136,\n    \"guid\": \"445544ae-4227-4282-9565-e1ad0bcec2b7\",\n    \"isActive\": true,\n    \"balance\": \"$1,980.14\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"green\",\n    \"name\": \"Bradshaw Orr\",\n    \"gender\": \"male\",\n    \"company\": \"LUNCHPOD\",\n    \"email\": \"bradshaworr@lunchpod.com\",\n    \"phone\": \"+1 (947) 478-2346\",\n    \"address\": \"393 Schweikerts Walk, Leland, Wisconsin, 2277\",\n    \"about\": \"Sint anim incididunt dolor qui ea labore sint sit labore eu magna do ad id. Deserunt fugiat consectetur culpa Lorem ea. Consequat exercitation ex excepteur sint esse adipisicing est ad officia laborum culpa. Sit incididunt aute aute pariatur excepteur amet ut. Id nulla quis magna amet. Eu esse nulla excepteur id voluptate labore.\\r\\n\",\n    \"registered\": \"2020-03-10T06:45:52 -01:00\",\n    \"latitude\": -42.041629,\n    \"longitude\": 7.181755,\n    \"tags\": [\n      \"et\",\n      \"fugiat\",\n      \"consequat\",\n      \"nulla\",\n      \"aliqua\",\n      \"exercitation\",\n      \"culpa\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Alvarez Wall\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Hopper Noble\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Bowen Jacobson\"\n      }\n    ],\n    \"greeting\": \"Hello, Bradshaw Orr! You have 1 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee55896739b8d8c208b\",\n    \"index\": 137,\n    \"guid\": \"52b38cbd-f26a-4834-9495-a0585aaed600\",\n    \"isActive\": true,\n    \"balance\": \"$2,624.49\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"green\",\n    \"name\": \"Mclaughlin Payne\",\n    \"gender\": \"male\",\n    \"company\": \"POLARIUM\",\n    \"email\": \"mclaughlinpayne@polarium.com\",\n    \"phone\": \"+1 (852) 577-2298\",\n    \"address\": \"560 Huntington Street, Kenmar, South Dakota, 7453\",\n    \"about\": \"Ad exercitation nostrud nostrud incididunt duis ea fugiat ut. Aliqua laboris reprehenderit laboris ullamco aute ipsum do mollit dolor mollit. Ipsum exercitation Lorem officia est.\\r\\n\",\n    \"registered\": \"2018-08-04T06:59:01 -02:00\",\n    \"latitude\": -87.070733,\n    \"longitude\": 171.921934,\n    \"tags\": [\n      \"nulla\",\n      \"dolor\",\n      \"incididunt\",\n      \"fugiat\",\n      \"occaecat\",\n      \"sint\",\n      \"veniam\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Rosalind Fischer\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Gonzales Pena\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Holly Cooley\"\n      }\n    ],\n    \"greeting\": \"Hello, Mclaughlin Payne! You have 1 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5d4c95273cd532c67\",\n    \"index\": 138,\n    \"guid\": \"1306b585-c6e2-4ea5-b8db-6a9cbba6c2a9\",\n    \"isActive\": false,\n    \"balance\": \"$2,554.00\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Joan Patel\",\n    \"gender\": \"female\",\n    \"company\": \"ZOARERE\",\n    \"email\": \"joanpatel@zoarere.com\",\n    \"phone\": \"+1 (878) 493-2911\",\n    \"address\": \"699 Tampa Court, Lowgap, Georgia, 3085\",\n    \"about\": \"Est pariatur excepteur elit qui aute. Fugiat dolore fugiat eu est exercitation incididunt culpa in anim cupidatat. Consectetur anim laborum est in pariatur laborum quis ea qui. Duis incididunt aliqua cupidatat amet irure irure. Deserunt culpa adipisicing do do sint aliquip esse sit mollit consequat eu aute.\\r\\n\",\n    \"registered\": \"2017-04-05T03:38:03 -02:00\",\n    \"latitude\": 80.685279,\n    \"longitude\": 121.95229,\n    \"tags\": [\n      \"aliqua\",\n      \"minim\",\n      \"excepteur\",\n      \"non\",\n      \"quis\",\n      \"proident\",\n      \"nulla\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Knapp Huber\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Summers Norman\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Hilary Cobb\"\n      }\n    ],\n    \"greeting\": \"Hello, Joan Patel! You have 6 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5e4a64e411764d9fc\",\n    \"index\": 139,\n    \"guid\": \"3bb63a04-2fa0-42d8-83ec-3da66984e4b6\",\n    \"isActive\": true,\n    \"balance\": \"$3,500.73\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 22,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Angelia Ayala\",\n    \"gender\": \"female\",\n    \"company\": \"UNDERTAP\",\n    \"email\": \"angeliaayala@undertap.com\",\n    \"phone\": \"+1 (825) 534-3045\",\n    \"address\": \"642 Williams Avenue, Levant, Connecticut, 7915\",\n    \"about\": \"Incididunt cupidatat amet sit deserunt cillum eu id ut aliquip veniam ex. Ex dolore aute voluptate pariatur ullamco sit ex culpa sunt quis eu Lorem quis cillum. Deserunt est Lorem fugiat consequat ex. Quis irure dolore amet ea.\\r\\n\",\n    \"registered\": \"2020-03-30T11:38:00 -02:00\",\n    \"latitude\": 47.572523,\n    \"longitude\": -17.213238,\n    \"tags\": [\n      \"aute\",\n      \"mollit\",\n      \"est\",\n      \"pariatur\",\n      \"mollit\",\n      \"sit\",\n      \"ad\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Rice Saunders\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Morrow Kerr\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Graves Ferguson\"\n      }\n    ],\n    \"greeting\": \"Hello, Angelia Ayala! You have 3 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee568f5e18c55dd729d\",\n    \"index\": 140,\n    \"guid\": \"abba673d-8e92-4d2f-a477-8a16733762f0\",\n    \"isActive\": false,\n    \"balance\": \"$1,772.98\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 33,\n    \"eyeColor\": \"green\",\n    \"name\": \"Julie Gregory\",\n    \"gender\": \"female\",\n    \"company\": \"BARKARAMA\",\n    \"email\": \"juliegregory@barkarama.com\",\n    \"phone\": \"+1 (933) 526-3060\",\n    \"address\": \"676 Jamison Lane, Logan, West Virginia, 1580\",\n    \"about\": \"Aute occaecat consectetur est ea adipisicing Lorem enim nulla esse. Lorem velit aliqua aliqua officia qui ut cupidatat magna aliqua laboris do. Incididunt veniam sunt ipsum fugiat nostrud voluptate aliquip ut consectetur est nulla laborum. Mollit ex ipsum tempor ea sint cillum velit excepteur laboris laborum. Cupidatat et ullamco qui nulla anim est deserunt officia incididunt adipisicing. Ipsum esse magna non minim eiusmod pariatur quis in deserunt ea officia anim.\\r\\n\",\n    \"registered\": \"2020-01-19T05:25:09 -01:00\",\n    \"latitude\": 86.222509,\n    \"longitude\": -75.637503,\n    \"tags\": [\n      \"ut\",\n      \"in\",\n      \"irure\",\n      \"cupidatat\",\n      \"labore\",\n      \"deserunt\",\n      \"eu\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Maura Dalton\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"English Duncan\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Erickson Harrison\"\n      }\n    ],\n    \"greeting\": \"Hello, Julie Gregory! You have 2 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee59006e4721facc8e6\",\n    \"index\": 141,\n    \"guid\": \"4a902a14-3a79-41c7-8382-3a185ad8856b\",\n    \"isActive\": false,\n    \"balance\": \"$3,222.41\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 23,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Whitney Hopkins\",\n    \"gender\": \"male\",\n    \"company\": \"KNEEDLES\",\n    \"email\": \"whitneyhopkins@kneedles.com\",\n    \"phone\": \"+1 (835) 502-3489\",\n    \"address\": \"524 Opal Court, Lydia, Marshall Islands, 6384\",\n    \"about\": \"Exercitation commodo mollit elit ex nisi Lorem. Cupidatat amet ea nostrud ut nulla amet enim id veniam. Aute dolore eu officia eiusmod exercitation.\\r\\n\",\n    \"registered\": \"2021-07-20T08:11:24 -02:00\",\n    \"latitude\": 56.887021,\n    \"longitude\": -67.375011,\n    \"tags\": [\n      \"nulla\",\n      \"occaecat\",\n      \"amet\",\n      \"non\",\n      \"anim\",\n      \"pariatur\",\n      \"qui\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Meghan Andrews\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Rivera Mendez\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Osborn Clarke\"\n      }\n    ],\n    \"greeting\": \"Hello, Whitney Hopkins! You have 9 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5de17996ed3b91c83\",\n    \"index\": 142,\n    \"guid\": \"0fa08791-166e-4d9e-9745-c7478fcf2dfa\",\n    \"isActive\": false,\n    \"balance\": \"$2,058.93\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 30,\n    \"eyeColor\": \"green\",\n    \"name\": \"Stefanie Keller\",\n    \"gender\": \"female\",\n    \"company\": \"GEOLOGIX\",\n    \"email\": \"stefaniekeller@geologix.com\",\n    \"phone\": \"+1 (913) 457-2079\",\n    \"address\": \"679 Fiske Place, Roeville, Arkansas, 681\",\n    \"about\": \"Aliqua minim est fugiat reprehenderit culpa mollit duis exercitation nisi ipsum duis elit. Nisi commodo reprehenderit veniam Lorem ea ea ad in magna. Aliquip enim velit officia et adipisicing dolore esse dolor culpa excepteur consequat.\\r\\n\",\n    \"registered\": \"2015-07-22T01:24:30 -02:00\",\n    \"latitude\": 5.157128,\n    \"longitude\": 145.674648,\n    \"tags\": [\n      \"minim\",\n      \"nostrud\",\n      \"occaecat\",\n      \"in\",\n      \"elit\",\n      \"deserunt\",\n      \"deserunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Gonzalez Alexander\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Wilder Tyson\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"May Oneal\"\n      }\n    ],\n    \"greeting\": \"Hello, Stefanie Keller! You have 7 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5c89ad8ce70bbc058\",\n    \"index\": 143,\n    \"guid\": \"39dd474d-e0f7-4b73-a55a-496396b15907\",\n    \"isActive\": false,\n    \"balance\": \"$1,108.27\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"green\",\n    \"name\": \"Mejia Chandler\",\n    \"gender\": \"male\",\n    \"company\": \"ROBOID\",\n    \"email\": \"mejiachandler@roboid.com\",\n    \"phone\": \"+1 (889) 554-2646\",\n    \"address\": \"934 Borinquen Pl, Lorraine, Oregon, 4077\",\n    \"about\": \"Quis qui deserunt occaecat sit ullamco amet aute. Minim tempor do magna consequat duis sit est. Elit ea reprehenderit sint cupidatat sint. Eu officia dolor nisi duis velit duis. Occaecat in anim magna non cupidatat.\\r\\n\",\n    \"registered\": \"2017-12-21T07:30:32 -01:00\",\n    \"latitude\": -1.703122,\n    \"longitude\": 60.029912,\n    \"tags\": [\n      \"laboris\",\n      \"Lorem\",\n      \"nulla\",\n      \"ut\",\n      \"ipsum\",\n      \"pariatur\",\n      \"sint\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Massey Hyde\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Dejesus Carrillo\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Townsend Bernard\"\n      }\n    ],\n    \"greeting\": \"Hello, Mejia Chandler! You have 4 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5ce3254b3ba192b75\",\n    \"index\": 144,\n    \"guid\": \"6e85d355-2ae9-4f93-8e18-e84a3170c4d4\",\n    \"isActive\": true,\n    \"balance\": \"$2,402.41\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Mcbride Grant\",\n    \"gender\": \"male\",\n    \"company\": \"EXIAND\",\n    \"email\": \"mcbridegrant@exiand.com\",\n    \"phone\": \"+1 (903) 429-2310\",\n    \"address\": \"348 Love Lane, Emerald, Puerto Rico, 8170\",\n    \"about\": \"Ad adipisicing pariatur ad mollit officia ullamco. Nisi voluptate consectetur proident pariatur elit magna amet id anim laborum consequat Lorem exercitation. Fugiat cillum ea qui irure ullamco. Reprehenderit nulla ad fugiat qui id ut officia. Esse in nostrud ad anim ea duis aliquip sint non deserunt do labore.\\r\\n\",\n    \"registered\": \"2015-07-12T04:33:10 -02:00\",\n    \"latitude\": 16.862902,\n    \"longitude\": 99.406674,\n    \"tags\": [\n      \"laboris\",\n      \"dolore\",\n      \"eiusmod\",\n      \"aute\",\n      \"duis\",\n      \"mollit\",\n      \"amet\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Shauna Neal\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Stephenson Bolton\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Boyle Sharp\"\n      }\n    ],\n    \"greeting\": \"Hello, Mcbride Grant! You have 10 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee563739ff83dd1e7b9\",\n    \"index\": 145,\n    \"guid\": \"962de10d-1f51-424d-a954-7ed1c9a79503\",\n    \"isActive\": true,\n    \"balance\": \"$3,244.25\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Cortez Jordan\",\n    \"gender\": \"male\",\n    \"company\": \"STRALUM\",\n    \"email\": \"cortezjordan@stralum.com\",\n    \"phone\": \"+1 (946) 572-2308\",\n    \"address\": \"101 Eastern Parkway, Vale, Idaho, 4685\",\n    \"about\": \"Commodo reprehenderit aliqua in officia magna in velit laborum velit esse ex ex velit ut. Mollit voluptate ipsum incididunt pariatur esse quis. Sit minim aute deserunt duis et veniam enim sunt ea anim. Cupidatat sint pariatur cupidatat officia sit ullamco dolor do incididunt veniam sint. Esse labore ex in quis dolore aliquip do excepteur consequat fugiat veniam consectetur. Occaecat aliquip aliquip ut adipisicing.\\r\\n\",\n    \"registered\": \"2021-07-24T03:01:06 -02:00\",\n    \"latitude\": -63.499608,\n    \"longitude\": -55.554063,\n    \"tags\": [\n      \"excepteur\",\n      \"sint\",\n      \"sit\",\n      \"ad\",\n      \"eiusmod\",\n      \"commodo\",\n      \"cillum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Gena Barrera\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Cantrell Dennis\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Leah Vance\"\n      }\n    ],\n    \"greeting\": \"Hello, Cortez Jordan! You have 1 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5bbaa13e4fd7b7234\",\n    \"index\": 146,\n    \"guid\": \"5120a479-4579-49db-b82d-edecca11244e\",\n    \"isActive\": true,\n    \"balance\": \"$1,183.79\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Charmaine Galloway\",\n    \"gender\": \"female\",\n    \"company\": \"COMCUR\",\n    \"email\": \"charmainegalloway@comcur.com\",\n    \"phone\": \"+1 (999) 430-3192\",\n    \"address\": \"633 Anthony Street, Woodlands, New Mexico, 2548\",\n    \"about\": \"Laboris quis fugiat voluptate velit ut sunt amet proident pariatur officia. Ex mollit quis adipisicing exercitation veniam duis incididunt commodo duis. Aliquip consequat consequat do aliqua aliquip labore minim dolore voluptate laborum. Officia incididunt sunt laboris cupidatat culpa ea. Aute mollit mollit aute ea pariatur non occaecat adipisicing anim. Adipisicing eu proident irure ea pariatur irure magna Lorem cupidatat.\\r\\n\",\n    \"registered\": \"2015-09-23T11:21:35 -02:00\",\n    \"latitude\": -55.427803,\n    \"longitude\": 42.686073,\n    \"tags\": [\n      \"elit\",\n      \"minim\",\n      \"pariatur\",\n      \"non\",\n      \"ex\",\n      \"eiusmod\",\n      \"aliqua\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Navarro Whitley\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Tillman Rogers\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Ida Miranda\"\n      }\n    ],\n    \"greeting\": \"Hello, Charmaine Galloway! You have 1 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee59e5a2485138b15a7\",\n    \"index\": 147,\n    \"guid\": \"5690e9d2-9bb5-47a0-803e-8cdf7862293e\",\n    \"isActive\": false,\n    \"balance\": \"$3,227.62\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 38,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Tabatha Blanchard\",\n    \"gender\": \"female\",\n    \"company\": \"PANZENT\",\n    \"email\": \"tabathablanchard@panzent.com\",\n    \"phone\": \"+1 (919) 517-3855\",\n    \"address\": \"902 Erasmus Street, Gulf, Minnesota, 7789\",\n    \"about\": \"Aliquip qui qui irure esse ea deserunt eu officia dolor. Ipsum ea reprehenderit est labore excepteur occaecat ex quis do. Qui commodo magna adipisicing pariatur ea excepteur dolor reprehenderit proident aliqua elit eu enim. Nostrud consequat pariatur sunt cupidatat in duis nulla aute incididunt sint aliquip sunt. Sit irure consequat laborum elit adipisicing ea. Aliqua est fugiat nostrud veniam adipisicing ex ad cillum exercitation sit magna. Velit dolore labore aute pariatur tempor cillum anim.\\r\\n\",\n    \"registered\": \"2020-03-13T08:59:20 -01:00\",\n    \"latitude\": 72.599314,\n    \"longitude\": -53.05635,\n    \"tags\": [\n      \"voluptate\",\n      \"eu\",\n      \"elit\",\n      \"Lorem\",\n      \"reprehenderit\",\n      \"cillum\",\n      \"qui\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Katharine Gonzalez\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Justine Mccormick\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Lauri Wilkinson\"\n      }\n    ],\n    \"greeting\": \"Hello, Tabatha Blanchard! You have 5 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee534a3cf4ebc973f69\",\n    \"index\": 148,\n    \"guid\": \"f2bb7b5a-c27a-4159-9beb-33c737794637\",\n    \"isActive\": false,\n    \"balance\": \"$2,106.74\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 23,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Stafford Lara\",\n    \"gender\": \"male\",\n    \"company\": \"HOTCAKES\",\n    \"email\": \"staffordlara@hotcakes.com\",\n    \"phone\": \"+1 (840) 412-2196\",\n    \"address\": \"808 Fenimore Street, Lupton, Iowa, 1852\",\n    \"about\": \"Proident nisi excepteur ad anim eu voluptate adipisicing. Amet sit magna id pariatur esse enim deserunt commodo voluptate est incididunt ea velit. Consequat do quis incididunt aute magna duis aliqua id nulla voluptate mollit reprehenderit voluptate id. Ad excepteur id incididunt aute elit sunt occaecat proident laboris anim occaecat ut. In do sit est et. Lorem ex mollit voluptate aliqua.\\r\\n\",\n    \"registered\": \"2018-08-23T09:47:29 -02:00\",\n    \"latitude\": -6.492601,\n    \"longitude\": -133.833141,\n    \"tags\": [\n      \"ea\",\n      \"nisi\",\n      \"ipsum\",\n      \"non\",\n      \"incididunt\",\n      \"magna\",\n      \"laboris\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Grace Strong\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Christian Carson\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Mercado Nichols\"\n      }\n    ],\n    \"greeting\": \"Hello, Stafford Lara! You have 1 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee56828aca8860ebea9\",\n    \"index\": 149,\n    \"guid\": \"d013b34a-f79d-49a4-94a6-20a66eec6b57\",\n    \"isActive\": true,\n    \"balance\": \"$1,893.56\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"green\",\n    \"name\": \"Booker Abbott\",\n    \"gender\": \"male\",\n    \"company\": \"BITTOR\",\n    \"email\": \"bookerabbott@bittor.com\",\n    \"phone\": \"+1 (864) 530-3193\",\n    \"address\": \"443 Cooper Street, Fredericktown, Maine, 4345\",\n    \"about\": \"Labore consectetur magna commodo anim proident enim sunt culpa amet proident pariatur incididunt in. Pariatur cillum nostrud cupidatat magna esse anim id anim sunt. Irure ullamco cillum officia aute occaecat est ipsum sint laboris duis incididunt mollit consectetur. Ea laboris sint dolor sint sint nulla reprehenderit nisi pariatur. Incididunt cillum consequat nulla est voluptate ipsum duis labore minim irure enim nulla nisi.\\r\\n\",\n    \"registered\": \"2015-04-26T08:21:07 -02:00\",\n    \"latitude\": 79.003769,\n    \"longitude\": 118.973225,\n    \"tags\": [\n      \"excepteur\",\n      \"excepteur\",\n      \"ut\",\n      \"sint\",\n      \"enim\",\n      \"ad\",\n      \"adipisicing\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Beverley Sharpe\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Farrell Reilly\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Rachel Ball\"\n      }\n    ],\n    \"greeting\": \"Hello, Booker Abbott! You have 2 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5c7615228af5d4ae6\",\n    \"index\": 150,\n    \"guid\": \"dd3e5f83-10a1-4af5-ab05-4cb1f1641fb2\",\n    \"isActive\": true,\n    \"balance\": \"$2,205.43\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 22,\n    \"eyeColor\": \"green\",\n    \"name\": \"Ray Daniels\",\n    \"gender\": \"male\",\n    \"company\": \"RECRITUBE\",\n    \"email\": \"raydaniels@recritube.com\",\n    \"phone\": \"+1 (812) 567-3470\",\n    \"address\": \"143 Perry Terrace, Tedrow, Tennessee, 9587\",\n    \"about\": \"Ut consectetur consectetur in consectetur nostrud cupidatat aute sunt ut est. Officia pariatur adipisicing culpa dolor. Ipsum culpa in tempor ipsum occaecat aliquip qui ut sint qui est Lorem dolor. Et ut nostrud tempor sit consectetur labore duis. Ad amet aliquip est est.\\r\\n\",\n    \"registered\": \"2017-07-06T05:39:55 -02:00\",\n    \"latitude\": -19.375801,\n    \"longitude\": 42.704824,\n    \"tags\": [\n      \"dolor\",\n      \"eiusmod\",\n      \"consequat\",\n      \"dolore\",\n      \"ea\",\n      \"voluptate\",\n      \"nisi\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Briggs Larson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Maggie Fox\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Lenore Giles\"\n      }\n    ],\n    \"greeting\": \"Hello, Ray Daniels! You have 6 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee544b08024347a2af5\",\n    \"index\": 151,\n    \"guid\": \"75dc9a80-3f0c-4e9e-83ef-344c9f20e848\",\n    \"isActive\": true,\n    \"balance\": \"$3,739.95\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Wolfe Gilmore\",\n    \"gender\": \"male\",\n    \"company\": \"PROFLEX\",\n    \"email\": \"wolfegilmore@proflex.com\",\n    \"phone\": \"+1 (987) 459-2290\",\n    \"address\": \"663 Albemarle Terrace, Loveland, Palau, 6629\",\n    \"about\": \"Consequat laboris reprehenderit elit veniam laboris adipisicing elit amet. Sint magna minim laboris aliqua. Veniam amet consequat excepteur est labore culpa ea veniam. Et voluptate reprehenderit sit sunt. Occaecat elit cillum elit et elit magna consectetur cupidatat mollit consequat excepteur incididunt.\\r\\n\",\n    \"registered\": \"2020-02-23T08:48:58 -01:00\",\n    \"latitude\": -50.156098,\n    \"longitude\": 126.585424,\n    \"tags\": [\n      \"non\",\n      \"mollit\",\n      \"minim\",\n      \"ipsum\",\n      \"non\",\n      \"ut\",\n      \"adipisicing\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Karen Powers\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Hatfield Moon\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Angela Osborne\"\n      }\n    ],\n    \"greeting\": \"Hello, Wolfe Gilmore! You have 6 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5deb9985bd13c7fe3\",\n    \"index\": 152,\n    \"guid\": \"13e88d2e-6295-46ee-b640-7e7f985745fa\",\n    \"isActive\": true,\n    \"balance\": \"$1,643.71\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"green\",\n    \"name\": \"Lesley Bright\",\n    \"gender\": \"female\",\n    \"company\": \"LUDAK\",\n    \"email\": \"lesleybright@ludak.com\",\n    \"phone\": \"+1 (984) 594-2201\",\n    \"address\": \"446 Commerce Street, Blairstown, Kansas, 5802\",\n    \"about\": \"Eiusmod ea pariatur nostrud adipisicing tempor amet voluptate. Occaecat non dolor et aute labore pariatur officia pariatur cupidatat velit laboris veniam esse reprehenderit. Duis sint velit qui velit reprehenderit enim magna deserunt pariatur pariatur. Velit aliqua velit ad elit veniam aute sint aliquip duis officia ullamco non sunt. Commodo labore culpa veniam ipsum.\\r\\n\",\n    \"registered\": \"2016-09-22T09:17:26 -02:00\",\n    \"latitude\": -25.928367,\n    \"longitude\": -113.94637,\n    \"tags\": [\n      \"in\",\n      \"laborum\",\n      \"sunt\",\n      \"irure\",\n      \"fugiat\",\n      \"aliqua\",\n      \"dolor\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Ines Stout\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Alba Hardin\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Rose Lindsey\"\n      }\n    ],\n    \"greeting\": \"Hello, Lesley Bright! You have 7 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5f7c0939ef0f26379\",\n    \"index\": 153,\n    \"guid\": \"72a6e308-5694-4e6d-84a1-957cfe2d0a5d\",\n    \"isActive\": true,\n    \"balance\": \"$1,963.83\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 37,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Roy Hodges\",\n    \"gender\": \"male\",\n    \"company\": \"QUIZKA\",\n    \"email\": \"royhodges@quizka.com\",\n    \"phone\": \"+1 (939) 593-2568\",\n    \"address\": \"218 Veranda Place, Columbus, American Samoa, 6702\",\n    \"about\": \"Do amet officia ex enim veniam aliqua ex laborum sunt. Ex ipsum aliqua ex id. Et commodo adipisicing deserunt culpa nulla consequat id dolore.\\r\\n\",\n    \"registered\": \"2019-11-24T02:00:58 -01:00\",\n    \"latitude\": 86.760482,\n    \"longitude\": -52.686767,\n    \"tags\": [\n      \"id\",\n      \"aliqua\",\n      \"commodo\",\n      \"tempor\",\n      \"aliquip\",\n      \"magna\",\n      \"aliquip\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Camille Cross\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Walls Bass\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Finch Booth\"\n      }\n    ],\n    \"greeting\": \"Hello, Roy Hodges! You have 9 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee54d3bdfa4044157b6\",\n    \"index\": 154,\n    \"guid\": \"f84e0bd8-8474-4e6d-b19c-4e08321863da\",\n    \"isActive\": true,\n    \"balance\": \"$3,424.59\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 28,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Shelton Dale\",\n    \"gender\": \"male\",\n    \"company\": \"OPTICON\",\n    \"email\": \"sheltondale@opticon.com\",\n    \"phone\": \"+1 (886) 578-2696\",\n    \"address\": \"706 Hausman Street, Elrama, South Carolina, 5946\",\n    \"about\": \"Aliqua mollit do consequat veniam sunt est aute aliquip do Lorem eiusmod aliquip mollit in. Anim elit est esse id culpa nisi laboris. Magna ea mollit fugiat nostrud ex pariatur commodo proident dolore. Adipisicing nostrud velit eu sunt pariatur.\\r\\n\",\n    \"registered\": \"2014-02-12T02:22:15 -01:00\",\n    \"latitude\": 64.193976,\n    \"longitude\": -155.392223,\n    \"tags\": [\n      \"ex\",\n      \"in\",\n      \"enim\",\n      \"consequat\",\n      \"dolor\",\n      \"commodo\",\n      \"ex\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Murphy Richards\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Chen Knowles\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Horn Fowler\"\n      }\n    ],\n    \"greeting\": \"Hello, Shelton Dale! You have 7 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee568b7dd399a68be8f\",\n    \"index\": 155,\n    \"guid\": \"764c766d-bfb3-4bba-9ff5-c5dfa650b86c\",\n    \"isActive\": false,\n    \"balance\": \"$2,170.52\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 32,\n    \"eyeColor\": \"green\",\n    \"name\": \"Noelle Lawson\",\n    \"gender\": \"female\",\n    \"company\": \"PLUTORQUE\",\n    \"email\": \"noellelawson@plutorque.com\",\n    \"phone\": \"+1 (920) 537-3676\",\n    \"address\": \"995 Bassett Avenue, Delco, Indiana, 8632\",\n    \"about\": \"Minim commodo mollit ullamco cillum laboris eu do ex voluptate dolor ut sit. Et magna sit ea enim officia adipisicing sint sit consectetur et deserunt amet. Dolor consectetur incididunt nostrud cillum voluptate veniam sunt tempor dolor exercitation. Sint sint fugiat duis esse officia et exercitation Lorem aliquip. Laborum eu cupidatat eu duis deserunt eiusmod do amet in do nisi culpa consectetur duis. Consequat aliquip velit magna sunt.\\r\\n\",\n    \"registered\": \"2020-12-20T12:30:13 -01:00\",\n    \"latitude\": 47.156984,\n    \"longitude\": 97.702827,\n    \"tags\": [\n      \"ullamco\",\n      \"aute\",\n      \"deserunt\",\n      \"incididunt\",\n      \"incididunt\",\n      \"ea\",\n      \"sint\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Camacho Daugherty\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Naomi Hubbard\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Alford Curtis\"\n      }\n    ],\n    \"greeting\": \"Hello, Noelle Lawson! You have 9 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee585cd13143c464e5a\",\n    \"index\": 156,\n    \"guid\": \"97b242a7-b91c-49e0-a10c-5913ba32bc8e\",\n    \"isActive\": true,\n    \"balance\": \"$1,224.49\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 36,\n    \"eyeColor\": \"green\",\n    \"name\": \"Diana Ross\",\n    \"gender\": \"female\",\n    \"company\": \"BOLAX\",\n    \"email\": \"dianaross@bolax.com\",\n    \"phone\": \"+1 (953) 406-3048\",\n    \"address\": \"320 Sumpter Street, Frystown, District Of Columbia, 3971\",\n    \"about\": \"Nisi voluptate labore laborum nulla proident adipisicing pariatur consectetur qui minim nostrud adipisicing enim. Laboris commodo culpa sit enim do laborum ullamco in nostrud officia minim exercitation. Lorem officia irure deserunt Lorem ullamco laborum. Ullamco pariatur sint do qui proident commodo reprehenderit excepteur officia ad. Non ut reprehenderit id culpa non.\\r\\n\",\n    \"registered\": \"2016-09-11T04:00:33 -02:00\",\n    \"latitude\": -87.832113,\n    \"longitude\": -114.083214,\n    \"tags\": [\n      \"et\",\n      \"cillum\",\n      \"cupidatat\",\n      \"esse\",\n      \"et\",\n      \"velit\",\n      \"excepteur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Natasha Washington\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Bianca Franks\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Cotton Mooney\"\n      }\n    ],\n    \"greeting\": \"Hello, Diana Ross! You have 5 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5f7a84cd176af9561\",\n    \"index\": 157,\n    \"guid\": \"bab074ec-94fb-4ec9-8e51-69d7ac448bd5\",\n    \"isActive\": true,\n    \"balance\": \"$2,078.98\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Dorothy Barber\",\n    \"gender\": \"female\",\n    \"company\": \"PAWNAGRA\",\n    \"email\": \"dorothybarber@pawnagra.com\",\n    \"phone\": \"+1 (806) 426-3153\",\n    \"address\": \"668 Hall Street, Blandburg, Wyoming, 6429\",\n    \"about\": \"Amet elit laboris mollit pariatur laborum laboris. Voluptate occaecat duis laboris sit voluptate elit commodo tempor labore qui sint. Pariatur mollit tempor qui enim Lorem nulla incididunt in est dolor.\\r\\n\",\n    \"registered\": \"2017-07-22T06:15:59 -02:00\",\n    \"latitude\": -35.167258,\n    \"longitude\": -139.549021,\n    \"tags\": [\n      \"ullamco\",\n      \"eiusmod\",\n      \"occaecat\",\n      \"eu\",\n      \"officia\",\n      \"eu\",\n      \"do\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Rhoda Livingston\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Freda Nielsen\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Lana Crosby\"\n      }\n    ],\n    \"greeting\": \"Hello, Dorothy Barber! You have 5 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee58d574b232cf827cb\",\n    \"index\": 158,\n    \"guid\": \"d9a2c7f5-178a-4de2-8aba-9ff429e8a38d\",\n    \"isActive\": true,\n    \"balance\": \"$2,412.25\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Rebekah Boyer\",\n    \"gender\": \"female\",\n    \"company\": \"FRANSCENE\",\n    \"email\": \"rebekahboyer@franscene.com\",\n    \"phone\": \"+1 (976) 553-2552\",\n    \"address\": \"896 Dahlgreen Place, Waterview, Texas, 4309\",\n    \"about\": \"Cupidatat nisi culpa nulla non aute culpa sit laboris adipisicing sunt tempor. Ut laboris anim nulla incididunt cillum sint aute eiusmod dolor cillum. Culpa dolor est elit proident occaecat nisi sint veniam amet. Incididunt aliqua do ad nulla in anim cupidatat dolor voluptate non incididunt. Laborum cillum sint deserunt ipsum aliqua ad nulla non velit reprehenderit laborum. Est fugiat consectetur nulla Lorem aliqua Lorem est. Irure ea consectetur aliqua ex dolore aliqua Lorem sit ut fugiat.\\r\\n\",\n    \"registered\": \"2015-11-08T11:53:36 -01:00\",\n    \"latitude\": 2.941026,\n    \"longitude\": 89.814006,\n    \"tags\": [\n      \"aute\",\n      \"quis\",\n      \"id\",\n      \"minim\",\n      \"anim\",\n      \"velit\",\n      \"tempor\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Mcguire Pace\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Tiffany Davidson\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Toni Coffey\"\n      }\n    ],\n    \"greeting\": \"Hello, Rebekah Boyer! You have 3 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee535c02f25600dbd83\",\n    \"index\": 159,\n    \"guid\": \"4bc995ae-f379-4a34-8f2f-d7804a90868d\",\n    \"isActive\": true,\n    \"balance\": \"$1,024.93\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Macdonald Patrick\",\n    \"gender\": \"male\",\n    \"company\": \"BLUPLANET\",\n    \"email\": \"macdonaldpatrick@bluplanet.com\",\n    \"phone\": \"+1 (901) 422-2518\",\n    \"address\": \"536 Amboy Street, Carrizo, Rhode Island, 3229\",\n    \"about\": \"Excepteur tempor tempor veniam pariatur fugiat incididunt sint elit in aute commodo et magna ea. Esse labore officia ex ut excepteur deserunt duis nostrud ut dolore ipsum mollit Lorem. Irure laboris est occaecat tempor non nulla ipsum. Cillum eu quis esse incididunt exercitation laborum veniam sunt. Veniam anim fugiat consectetur excepteur ad id labore. Et fugiat tempor dolor cillum dolor amet sit fugiat et. Quis consectetur irure officia non sit elit.\\r\\n\",\n    \"registered\": \"2016-02-10T02:49:55 -01:00\",\n    \"latitude\": 39.579377,\n    \"longitude\": -107.563672,\n    \"tags\": [\n      \"deserunt\",\n      \"culpa\",\n      \"Lorem\",\n      \"fugiat\",\n      \"mollit\",\n      \"irure\",\n      \"velit\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Palmer Farley\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Wood Alvarado\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Wynn Stephens\"\n      }\n    ],\n    \"greeting\": \"Hello, Macdonald Patrick! You have 3 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee521aac761d4a370ac\",\n    \"index\": 160,\n    \"guid\": \"37c650f1-2dcc-4873-a7fd-fd6f447e366e\",\n    \"isActive\": true,\n    \"balance\": \"$1,529.76\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"green\",\n    \"name\": \"Carmella Foley\",\n    \"gender\": \"female\",\n    \"company\": \"ZENSOR\",\n    \"email\": \"carmellafoley@zensor.com\",\n    \"phone\": \"+1 (881) 481-3309\",\n    \"address\": \"125 Auburn Place, Islandia, Louisiana, 2331\",\n    \"about\": \"Cillum anim eu fugiat ut ex ipsum esse et culpa cupidatat voluptate id. Sit culpa nulla labore enim duis consequat adipisicing veniam. Fugiat non incididunt nostrud occaecat. Enim nulla incididunt magna culpa in est Lorem ullamco. Aliqua deserunt aliquip mollit nostrud dolor adipisicing cupidatat pariatur sint eiusmod quis. Occaecat cupidatat sit fugiat non consectetur pariatur consequat enim reprehenderit duis. Culpa officia pariatur eu pariatur cillum non pariatur quis culpa sint magna irure.\\r\\n\",\n    \"registered\": \"2020-12-25T01:30:53 -01:00\",\n    \"latitude\": 55.689273,\n    \"longitude\": -145.256245,\n    \"tags\": [\n      \"laboris\",\n      \"Lorem\",\n      \"non\",\n      \"aute\",\n      \"occaecat\",\n      \"duis\",\n      \"cillum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Bridget Lambert\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Rowena Walsh\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Matilda Moran\"\n      }\n    ],\n    \"greeting\": \"Hello, Carmella Foley! You have 2 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5e1950f39972d92dc\",\n    \"index\": 161,\n    \"guid\": \"b7009167-7f1a-46ab-92f5-f3a9caa1fff6\",\n    \"isActive\": false,\n    \"balance\": \"$3,913.46\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 38,\n    \"eyeColor\": \"green\",\n    \"name\": \"James Dunlap\",\n    \"gender\": \"male\",\n    \"company\": \"ZILLAN\",\n    \"email\": \"jamesdunlap@zillan.com\",\n    \"phone\": \"+1 (865) 534-3153\",\n    \"address\": \"181 Tompkins Avenue, Wyoming, Illinois, 8889\",\n    \"about\": \"Laboris enim nulla reprehenderit mollit esse in. Pariatur ut nulla pariatur do esse culpa qui veniam ea est ad. Anim laboris veniam elit incididunt aliquip occaecat magna aliquip sunt voluptate. Adipisicing nostrud est amet quis reprehenderit ex esse pariatur. Ea consequat nisi deserunt adipisicing. Laboris anim in sint amet eiusmod incididunt cillum sint exercitation. Do aute quis in laborum qui commodo adipisicing occaecat.\\r\\n\",\n    \"registered\": \"2017-03-14T11:37:37 -01:00\",\n    \"latitude\": 27.714567,\n    \"longitude\": -20.490501,\n    \"tags\": [\n      \"occaecat\",\n      \"eiusmod\",\n      \"mollit\",\n      \"Lorem\",\n      \"reprehenderit\",\n      \"eu\",\n      \"pariatur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Elise Solomon\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Marguerite Moore\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Ashley Buchanan\"\n      }\n    ],\n    \"greeting\": \"Hello, James Dunlap! You have 8 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5c27c96ad56f126f1\",\n    \"index\": 162,\n    \"guid\": \"f7090d9e-083a-452a-a98d-13a43d5e0a56\",\n    \"isActive\": false,\n    \"balance\": \"$1,371.28\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"green\",\n    \"name\": \"Edwards Mathews\",\n    \"gender\": \"male\",\n    \"company\": \"EZENTIA\",\n    \"email\": \"edwardsmathews@ezentia.com\",\n    \"phone\": \"+1 (815) 445-3533\",\n    \"address\": \"696 Debevoise Street, Wollochet, Guam, 1752\",\n    \"about\": \"Deserunt commodo consectetur velit culpa velit enim nulla culpa. Sit ad cillum ipsum commodo enim esse labore nulla in sit cupidatat cupidatat proident. Eu non laboris cupidatat sint. Laborum qui commodo consequat in incididunt dolore occaecat voluptate non nisi est magna do. Exercitation ullamco adipisicing aliquip magna veniam et in laborum in cillum officia. In sunt eiusmod anim eu qui nostrud proident adipisicing qui tempor laboris ut laborum. Sunt elit Lorem amet mollit exercitation labore amet reprehenderit minim quis ullamco do in.\\r\\n\",\n    \"registered\": \"2017-09-17T11:16:52 -02:00\",\n    \"latitude\": -49.841093,\n    \"longitude\": 179.143357,\n    \"tags\": [\n      \"veniam\",\n      \"quis\",\n      \"do\",\n      \"do\",\n      \"dolore\",\n      \"elit\",\n      \"cupidatat\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Mckenzie Sparks\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Britt Hendricks\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Bradford Castro\"\n      }\n    ],\n    \"greeting\": \"Hello, Edwards Mathews! You have 2 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee56cb6b0a8f6d1bed7\",\n    \"index\": 163,\n    \"guid\": \"80b59ece-1750-43e1-af48-c97fecea477c\",\n    \"isActive\": true,\n    \"balance\": \"$1,947.21\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Olson Bell\",\n    \"gender\": \"male\",\n    \"company\": \"FIREWAX\",\n    \"email\": \"olsonbell@firewax.com\",\n    \"phone\": \"+1 (905) 464-3563\",\n    \"address\": \"861 Commercial Street, Leming, New York, 3414\",\n    \"about\": \"Sit esse sint Lorem sint nostrud quis in est. Qui nostrud ex velit sit commodo fugiat elit aliqua ad voluptate. Laborum enim eiusmod qui irure magna dolor aliqua deserunt.\\r\\n\",\n    \"registered\": \"2019-01-12T09:55:30 -01:00\",\n    \"latitude\": 77.532459,\n    \"longitude\": 58.901133,\n    \"tags\": [\n      \"velit\",\n      \"laborum\",\n      \"exercitation\",\n      \"sit\",\n      \"ut\",\n      \"fugiat\",\n      \"eu\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Dunlap Guerrero\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Haney Reyes\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Mccarthy Daniel\"\n      }\n    ],\n    \"greeting\": \"Hello, Olson Bell! You have 3 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5a43ea1672e052b71\",\n    \"index\": 164,\n    \"guid\": \"70aa8322-8b1d-4b9b-9116-e6cf355f0ba9\",\n    \"isActive\": false,\n    \"balance\": \"$2,714.39\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 34,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Guadalupe Hanson\",\n    \"gender\": \"female\",\n    \"company\": \"IDEGO\",\n    \"email\": \"guadalupehanson@idego.com\",\n    \"phone\": \"+1 (922) 420-2096\",\n    \"address\": \"985 Bayview Avenue, Haena, Colorado, 3841\",\n    \"about\": \"Reprehenderit qui nostrud consequat laborum minim qui et. Sunt magna in enim laboris. Laboris dolor elit duis aliqua. Ex occaecat ullamco laboris sint quis ullamco voluptate consectetur.\\r\\n\",\n    \"registered\": \"2018-08-03T06:20:50 -02:00\",\n    \"latitude\": -50.279993,\n    \"longitude\": 99.11661,\n    \"tags\": [\n      \"mollit\",\n      \"officia\",\n      \"adipisicing\",\n      \"veniam\",\n      \"ullamco\",\n      \"irure\",\n      \"reprehenderit\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Audra Travis\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Grimes Hampton\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Ingram Wiley\"\n      }\n    ],\n    \"greeting\": \"Hello, Guadalupe Hanson! You have 4 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee537ef82e78fa4f286\",\n    \"index\": 165,\n    \"guid\": \"043c1605-47b1-418d-a168-4a2546e8fe1f\",\n    \"isActive\": true,\n    \"balance\": \"$2,769.31\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Mitzi Robles\",\n    \"gender\": \"female\",\n    \"company\": \"PORTICO\",\n    \"email\": \"mitzirobles@portico.com\",\n    \"phone\": \"+1 (979) 505-3161\",\n    \"address\": \"622 Henry Street, Leola, Michigan, 2464\",\n    \"about\": \"Id incididunt irure exercitation magna ut exercitation qui dolore cupidatat laborum eiusmod labore. Eu labore do mollit enim aliqua eu deserunt non proident nostrud cillum pariatur Lorem. Elit minim consequat sint sint. Ullamco exercitation dolor reprehenderit ad est adipisicing excepteur.\\r\\n\",\n    \"registered\": \"2016-04-03T09:39:14 -02:00\",\n    \"latitude\": 41.121775,\n    \"longitude\": 48.537868,\n    \"tags\": [\n      \"minim\",\n      \"pariatur\",\n      \"et\",\n      \"aliqua\",\n      \"cupidatat\",\n      \"elit\",\n      \"magna\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Luella Kane\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Barnett Holman\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Brooks Young\"\n      }\n    ],\n    \"greeting\": \"Hello, Mitzi Robles! You have 4 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5c78277888b039051\",\n    \"index\": 166,\n    \"guid\": \"f06f640c-a155-4ba9-9f74-149b4fca7046\",\n    \"isActive\": true,\n    \"balance\": \"$2,446.50\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Flossie Steele\",\n    \"gender\": \"female\",\n    \"company\": \"NAXDIS\",\n    \"email\": \"flossiesteele@naxdis.com\",\n    \"phone\": \"+1 (868) 557-3107\",\n    \"address\": \"940 Ross Street, Nicholson, Vermont, 8668\",\n    \"about\": \"Quis amet anim officia nisi sit nulla excepteur minim magna commodo. Voluptate sunt cillum magna proident. Et officia nisi cupidatat quis voluptate ad labore velit irure eu.\\r\\n\",\n    \"registered\": \"2014-01-17T09:05:08 -01:00\",\n    \"latitude\": -15.526407,\n    \"longitude\": -105.072326,\n    \"tags\": [\n      \"exercitation\",\n      \"occaecat\",\n      \"ad\",\n      \"commodo\",\n      \"voluptate\",\n      \"occaecat\",\n      \"voluptate\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Rosemary Lott\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Carroll Flynn\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Salazar Glover\"\n      }\n    ],\n    \"greeting\": \"Hello, Flossie Steele! You have 2 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee571243be34c02ee14\",\n    \"index\": 167,\n    \"guid\": \"3d25fce3-caf1-4cc2-ba33-9447d0cd0f2d\",\n    \"isActive\": true,\n    \"balance\": \"$1,011.36\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 33,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Susie Bradford\",\n    \"gender\": \"female\",\n    \"company\": \"RADIANTIX\",\n    \"email\": \"susiebradford@radiantix.com\",\n    \"phone\": \"+1 (860) 513-3324\",\n    \"address\": \"975 Heyward Street, Websterville, New Jersey, 3172\",\n    \"about\": \"Sit aliquip eu aliquip dolor pariatur consectetur consequat eiusmod commodo nulla aliqua veniam. Mollit adipisicing consectetur sint veniam irure cillum ipsum esse occaecat. Dolore incididunt ea duis in non ea labore sunt. Ipsum irure ad reprehenderit anim nostrud velit. Ea duis proident sit laboris sunt anim sit. Officia labore culpa eiusmod non magna incididunt aliqua duis veniam et duis. Aliqua reprehenderit sint sit id mollit.\\r\\n\",\n    \"registered\": \"2018-12-25T02:18:38 -01:00\",\n    \"latitude\": 88.659453,\n    \"longitude\": 121.981182,\n    \"tags\": [\n      \"cillum\",\n      \"deserunt\",\n      \"magna\",\n      \"nisi\",\n      \"esse\",\n      \"elit\",\n      \"pariatur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Emily Ratliff\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Rasmussen Nguyen\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Peters Serrano\"\n      }\n    ],\n    \"greeting\": \"Hello, Susie Bradford! You have 10 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5475d05f9f106f335\",\n    \"index\": 168,\n    \"guid\": \"79e55e9e-1e49-4f2f-bfcb-15ce51e408a6\",\n    \"isActive\": false,\n    \"balance\": \"$2,513.42\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Hooper Huffman\",\n    \"gender\": \"male\",\n    \"company\": \"TERRASYS\",\n    \"email\": \"hooperhuffman@terrasys.com\",\n    \"phone\": \"+1 (948) 526-3104\",\n    \"address\": \"761 Hunts Lane, Herbster, Nebraska, 647\",\n    \"about\": \"Tempor excepteur aute do qui officia aute aliquip officia exercitation ullamco. Quis quis ad cupidatat aute. Mollit voluptate qui non exercitation officia nisi quis officia adipisicing cillum laboris ipsum culpa labore. Cillum ea minim mollit aliqua eiusmod.\\r\\n\",\n    \"registered\": \"2014-11-10T05:07:55 -01:00\",\n    \"latitude\": 8.36954,\n    \"longitude\": 84.490621,\n    \"tags\": [\n      \"adipisicing\",\n      \"ad\",\n      \"et\",\n      \"non\",\n      \"laboris\",\n      \"ut\",\n      \"consectetur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Heath Stein\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Bonner Craig\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Hartman Poole\"\n      }\n    ],\n    \"greeting\": \"Hello, Hooper Huffman! You have 3 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee51ecd0492051f3108\",\n    \"index\": 169,\n    \"guid\": \"b5abe7ac-552a-4bc5-a2d8-6c1485b86563\",\n    \"isActive\": false,\n    \"balance\": \"$2,531.67\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 35,\n    \"eyeColor\": \"green\",\n    \"name\": \"Duran Norris\",\n    \"gender\": \"male\",\n    \"company\": \"DIGIQUE\",\n    \"email\": \"durannorris@digique.com\",\n    \"phone\": \"+1 (848) 550-2430\",\n    \"address\": \"709 Nolans Lane, Austinburg, North Carolina, 6627\",\n    \"about\": \"Non excepteur Lorem id aliqua. Amet id dolore eiusmod commodo duis tempor consequat exercitation consequat aute laboris irure tempor. Cillum culpa est cillum ea deserunt incididunt nostrud dolore et magna excepteur nisi sunt. Proident consectetur non dolor commodo qui mollit do deserunt ipsum quis ullamco ullamco nisi. Nulla cillum sit ea minim qui eiusmod culpa ullamco excepteur adipisicing sit ea elit. Labore velit tempor consectetur officia anim.\\r\\n\",\n    \"registered\": \"2021-03-07T02:04:57 -01:00\",\n    \"latitude\": 51.515949,\n    \"longitude\": 141.937642,\n    \"tags\": [\n      \"consectetur\",\n      \"eiusmod\",\n      \"ullamco\",\n      \"ullamco\",\n      \"consequat\",\n      \"qui\",\n      \"officia\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Veronica Cash\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Robertson Cardenas\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Gallegos Hoover\"\n      }\n    ],\n    \"greeting\": \"Hello, Duran Norris! You have 3 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee538ae4398f3a752e4\",\n    \"index\": 170,\n    \"guid\": \"c9b71c2f-9074-4d84-b518-44d113c24ba7\",\n    \"isActive\": false,\n    \"balance\": \"$2,485.82\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 38,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Burnett Ray\",\n    \"gender\": \"male\",\n    \"company\": \"EWEVILLE\",\n    \"email\": \"burnettray@eweville.com\",\n    \"phone\": \"+1 (880) 571-2528\",\n    \"address\": \"252 Irvington Place, Connerton, California, 9809\",\n    \"about\": \"Laborum reprehenderit nisi laborum sint consectetur duis. Enim cillum occaecat reprehenderit deserunt id eu consequat ex tempor mollit pariatur eiusmod. Excepteur culpa in id non aliqua sunt anim officia minim cillum aliqua ut. Dolore est elit amet ea elit pariatur ullamco eu ea elit ut enim. Amet cupidatat ullamco ullamco consequat tempor tempor consectetur laborum cillum aliquip irure.\\r\\n\",\n    \"registered\": \"2021-07-20T03:36:54 -02:00\",\n    \"latitude\": -67.490123,\n    \"longitude\": -25.91264,\n    \"tags\": [\n      \"anim\",\n      \"ad\",\n      \"in\",\n      \"exercitation\",\n      \"laboris\",\n      \"velit\",\n      \"deserunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Elliott Pittman\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Ross Mcdowell\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Kidd Holloway\"\n      }\n    ],\n    \"greeting\": \"Hello, Burnett Ray! You have 2 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee526ff9d49277a1b51\",\n    \"index\": 171,\n    \"guid\": \"e8972060-6a5a-4472-bc70-7c511817fa84\",\n    \"isActive\": true,\n    \"balance\": \"$2,223.93\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 37,\n    \"eyeColor\": \"green\",\n    \"name\": \"Gallagher Taylor\",\n    \"gender\": \"male\",\n    \"company\": \"CONFERIA\",\n    \"email\": \"gallaghertaylor@conferia.com\",\n    \"phone\": \"+1 (909) 435-2081\",\n    \"address\": \"484 King Street, Eastvale, Virgin Islands, 5943\",\n    \"about\": \"Aute aliquip reprehenderit cillum consequat fugiat labore cupidatat elit ipsum culpa dolor mollit. Laborum aliqua esse sint aute magna amet consectetur. Consectetur aute sunt ullamco deserunt pariatur Lorem elit in aliqua mollit.\\r\\n\",\n    \"registered\": \"2015-06-23T08:57:48 -02:00\",\n    \"latitude\": -26.979724,\n    \"longitude\": 8.410674,\n    \"tags\": [\n      \"eu\",\n      \"minim\",\n      \"aute\",\n      \"consequat\",\n      \"id\",\n      \"ex\",\n      \"reprehenderit\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Patrice Rodriguez\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Lorene Rich\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Kerry Castillo\"\n      }\n    ],\n    \"greeting\": \"Hello, Gallagher Taylor! You have 6 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5f9a0cd83d22d336e\",\n    \"index\": 172,\n    \"guid\": \"07cd35da-ca68-4bcd-8c6b-050d69b28090\",\n    \"isActive\": true,\n    \"balance\": \"$3,724.58\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Suzanne Gardner\",\n    \"gender\": \"female\",\n    \"company\": \"SOPRANO\",\n    \"email\": \"suzannegardner@soprano.com\",\n    \"phone\": \"+1 (926) 537-3588\",\n    \"address\": \"371 Montgomery Street, Escondida, Kentucky, 9992\",\n    \"about\": \"Sunt officia reprehenderit excepteur nisi. Dolor sint laborum enim ea velit sit mollit proident. Occaecat nisi velit officia irure ipsum. Nulla occaecat velit ullamco dolore. Esse elit irure irure commodo ipsum dolor nisi. Esse sunt commodo labore eiusmod enim adipisicing Lorem occaecat in aliquip nulla ipsum dolore.\\r\\n\",\n    \"registered\": \"2017-09-24T04:25:10 -02:00\",\n    \"latitude\": 80.234674,\n    \"longitude\": -147.398861,\n    \"tags\": [\n      \"et\",\n      \"voluptate\",\n      \"consequat\",\n      \"amet\",\n      \"ea\",\n      \"ipsum\",\n      \"sunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Bertha Shaw\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Le Emerson\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Nikki Harmon\"\n      }\n    ],\n    \"greeting\": \"Hello, Suzanne Gardner! You have 2 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5aeb3f04d95077025\",\n    \"index\": 173,\n    \"guid\": \"729de9a1-ea32-4b23-ba0a-497ead9af111\",\n    \"isActive\": false,\n    \"balance\": \"$1,093.72\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 31,\n    \"eyeColor\": \"green\",\n    \"name\": \"Ivy Romero\",\n    \"gender\": \"female\",\n    \"company\": \"ZENSUS\",\n    \"email\": \"ivyromero@zensus.com\",\n    \"phone\": \"+1 (959) 463-3847\",\n    \"address\": \"334 Metropolitan Avenue, Bowmansville, Alabama, 745\",\n    \"about\": \"Laboris consectetur cupidatat dolor laborum id consectetur exercitation ullamco aliquip anim Lorem. Velit exercitation fugiat irure et consectetur ad est id sint laborum sit laboris. Est voluptate cupidatat minim veniam cillum dolor. Irure pariatur velit nostrud esse aliqua quis aliquip fugiat nisi quis velit ullamco do.\\r\\n\",\n    \"registered\": \"2014-07-31T02:31:56 -02:00\",\n    \"latitude\": -73.477096,\n    \"longitude\": 121.203782,\n    \"tags\": [\n      \"aliquip\",\n      \"elit\",\n      \"ipsum\",\n      \"deserunt\",\n      \"culpa\",\n      \"esse\",\n      \"nulla\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Cunningham Silva\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Maryellen Walters\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Donovan Oneil\"\n      }\n    ],\n    \"greeting\": \"Hello, Ivy Romero! You have 3 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5ac06dd071153999d\",\n    \"index\": 174,\n    \"guid\": \"33ea2930-9fe7-4fd9-8615-9c0f4b36c168\",\n    \"isActive\": true,\n    \"balance\": \"$3,363.20\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 22,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Doyle Schultz\",\n    \"gender\": \"male\",\n    \"company\": \"COASH\",\n    \"email\": \"doyleschultz@coash.com\",\n    \"phone\": \"+1 (988) 483-3834\",\n    \"address\": \"840 Revere Place, Johnsonburg, Alaska, 1955\",\n    \"about\": \"Labore sint exercitation tempor enim laboris adipisicing elit ex deserunt ex sit. Nulla consequat incididunt mollit elit adipisicing voluptate elit mollit. Proident ullamco eiusmod enim tempor laborum et aliqua proident enim veniam magna ipsum occaecat Lorem. Ea reprehenderit minim tempor nisi ea eu occaecat Lorem veniam duis occaecat. Laborum voluptate dolor irure aliquip ut ipsum deserunt dolor fugiat adipisicing. Anim id eiusmod aute occaecat mollit aute ullamco ut in velit aliqua dolor commodo.\\r\\n\",\n    \"registered\": \"2015-12-17T03:08:39 -01:00\",\n    \"latitude\": -59.007671,\n    \"longitude\": -92.012459,\n    \"tags\": [\n      \"reprehenderit\",\n      \"aliqua\",\n      \"laboris\",\n      \"aliquip\",\n      \"voluptate\",\n      \"et\",\n      \"ad\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Mcmahon Levy\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Houston Bray\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Reynolds Ashley\"\n      }\n    ],\n    \"greeting\": \"Hello, Doyle Schultz! You have 8 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee514eabefa72035b92\",\n    \"index\": 175,\n    \"guid\": \"c09013d9-bfe2-4097-969a-eba9b533ac0d\",\n    \"isActive\": false,\n    \"balance\": \"$1,218.63\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 35,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Billie Mcclain\",\n    \"gender\": \"female\",\n    \"company\": \"ZILLA\",\n    \"email\": \"billiemcclain@zilla.com\",\n    \"phone\": \"+1 (939) 441-3854\",\n    \"address\": \"778 Narrows Avenue, Westmoreland, Missouri, 9993\",\n    \"about\": \"Ea do irure elit in ad consequat id et culpa qui commodo. Laborum sint laborum exercitation in dolore ex excepteur incididunt quis. Exercitation elit qui duis cillum. Exercitation culpa consectetur elit ex elit ut. Est ut duis qui nisi.\\r\\n\",\n    \"registered\": \"2018-10-27T07:58:53 -02:00\",\n    \"latitude\": -67.117324,\n    \"longitude\": -5.343014,\n    \"tags\": [\n      \"enim\",\n      \"dolor\",\n      \"irure\",\n      \"deserunt\",\n      \"in\",\n      \"duis\",\n      \"nostrud\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Perez Wiggins\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Bernard Britt\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Kerri Goff\"\n      }\n    ],\n    \"greeting\": \"Hello, Billie Mcclain! You have 8 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee50b1baebcdfe5b33b\",\n    \"index\": 176,\n    \"guid\": \"635d98fc-1c55-49d7-a039-11f6ae43c43a\",\n    \"isActive\": true,\n    \"balance\": \"$3,481.37\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 23,\n    \"eyeColor\": \"green\",\n    \"name\": \"Cynthia Blackwell\",\n    \"gender\": \"female\",\n    \"company\": \"ZIORE\",\n    \"email\": \"cynthiablackwell@ziore.com\",\n    \"phone\": \"+1 (822) 498-3944\",\n    \"address\": \"353 Rapelye Street, Swartzville, Hawaii, 2739\",\n    \"about\": \"Qui minim laboris dolor mollit ullamco nostrud eu ex dolore incididunt laborum dolor ex est. Non incididunt dolor voluptate ad eiusmod non esse do sint in laboris. Consectetur Lorem est cillum exercitation ad enim sint elit occaecat proident. Ullamco exercitation voluptate ipsum tempor do laboris fugiat fugiat. Esse ipsum nostrud qui laboris amet qui nulla et. Aliqua do nisi velit mollit. Nostrud reprehenderit eu laborum fugiat exercitation nulla consequat qui labore ad laboris.\\r\\n\",\n    \"registered\": \"2021-03-20T07:25:21 -01:00\",\n    \"latitude\": 71.504273,\n    \"longitude\": -48.503466,\n    \"tags\": [\n      \"laboris\",\n      \"magna\",\n      \"pariatur\",\n      \"Lorem\",\n      \"excepteur\",\n      \"laborum\",\n      \"aute\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Holden Sexton\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Josefina Padilla\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Minnie Benton\"\n      }\n    ],\n    \"greeting\": \"Hello, Cynthia Blackwell! You have 8 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5385828fcb8785678\",\n    \"index\": 177,\n    \"guid\": \"f0563d7b-952c-4ee4-9f0a-adea7806f90a\",\n    \"isActive\": false,\n    \"balance\": \"$2,476.24\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 29,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Nolan Marks\",\n    \"gender\": \"male\",\n    \"company\": \"COSMETEX\",\n    \"email\": \"nolanmarks@cosmetex.com\",\n    \"phone\": \"+1 (871) 576-2760\",\n    \"address\": \"749 Melba Court, Coleville, Ohio, 2692\",\n    \"about\": \"Eu mollit fugiat commodo occaecat reprehenderit laborum aliqua. Officia dolor dolore fugiat adipisicing cillum. Laboris quis commodo fugiat consequat ipsum eiusmod. Ex labore incididunt proident cillum reprehenderit enim est ad cupidatat do do nostrud enim. Aute ex id Lorem excepteur officia culpa culpa in velit et cillum exercitation.\\r\\n\",\n    \"registered\": \"2015-01-01T12:33:58 -01:00\",\n    \"latitude\": 15.751578,\n    \"longitude\": 161.774895,\n    \"tags\": [\n      \"id\",\n      \"culpa\",\n      \"duis\",\n      \"exercitation\",\n      \"culpa\",\n      \"duis\",\n      \"ipsum\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Araceli Frederick\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Dominguez Shepard\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Heidi Navarro\"\n      }\n    ],\n    \"greeting\": \"Hello, Nolan Marks! You have 7 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5e370e9ac53105b94\",\n    \"index\": 178,\n    \"guid\": \"1a6b6cbd-fb10-4ef4-b8b7-b408625a0df3\",\n    \"isActive\": true,\n    \"balance\": \"$2,766.91\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Freeman Cooke\",\n    \"gender\": \"male\",\n    \"company\": \"TROPOLIS\",\n    \"email\": \"freemancooke@tropolis.com\",\n    \"phone\": \"+1 (845) 432-3747\",\n    \"address\": \"425 Pacific Street, Innsbrook, Federated States Of Micronesia, 9072\",\n    \"about\": \"Elit mollit ipsum sit qui non. Culpa aute sint laborum esse est excepteur laborum sunt dolor sunt irure duis. Tempor officia reprehenderit aliquip ex eu ipsum culpa est tempor qui. Anim reprehenderit ex commodo consequat qui duis Lorem consectetur anim ad. Velit in excepteur voluptate excepteur magna veniam ullamco labore proident qui incididunt. Incididunt incididunt non enim cillum. Dolore elit commodo et deserunt laborum tempor veniam irure officia.\\r\\n\",\n    \"registered\": \"2021-01-30T08:50:33 -01:00\",\n    \"latitude\": 28.412115,\n    \"longitude\": 79.74984,\n    \"tags\": [\n      \"consectetur\",\n      \"qui\",\n      \"amet\",\n      \"sint\",\n      \"culpa\",\n      \"est\",\n      \"aliqua\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Robles Cherry\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Natalia Lawrence\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Cox Barr\"\n      }\n    ],\n    \"greeting\": \"Hello, Freeman Cooke! You have 3 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee536f826534ccaf41f\",\n    \"index\": 179,\n    \"guid\": \"3375cf5d-3e40-46aa-8660-e8b74e4dbbda\",\n    \"isActive\": true,\n    \"balance\": \"$3,699.35\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 34,\n    \"eyeColor\": \"green\",\n    \"name\": \"Margret Burke\",\n    \"gender\": \"female\",\n    \"company\": \"XURBAN\",\n    \"email\": \"margretburke@xurban.com\",\n    \"phone\": \"+1 (969) 436-2690\",\n    \"address\": \"853 Brightwater Court, Grazierville, New Hampshire, 5404\",\n    \"about\": \"Laborum aute nulla occaecat nostrud laborum aliqua est minim ad esse est. Nostrud duis sint consequat cillum non duis commodo qui. Occaecat qui culpa anim aliqua quis ex voluptate et anim Lorem. Lorem est nostrud aliqua sint sint. Officia irure proident occaecat esse et consequat amet deserunt dolore cillum labore magna ullamco duis. Non excepteur est qui in excepteur Lorem non quis irure id do non.\\r\\n\",\n    \"registered\": \"2018-09-08T09:52:09 -02:00\",\n    \"latitude\": 5.739404,\n    \"longitude\": 134.947077,\n    \"tags\": [\n      \"officia\",\n      \"commodo\",\n      \"deserunt\",\n      \"in\",\n      \"laboris\",\n      \"id\",\n      \"eu\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Joseph Whitfield\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Ofelia Hewitt\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Alfreda Hurley\"\n      }\n    ],\n    \"greeting\": \"Hello, Margret Burke! You have 3 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee51703591fd4b016b5\",\n    \"index\": 180,\n    \"guid\": \"0c99e474-1559-4ea7-9a0b-1bcd1bfc3c4c\",\n    \"isActive\": true,\n    \"balance\": \"$3,647.91\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 34,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Rowland Key\",\n    \"gender\": \"male\",\n    \"company\": \"DAIDO\",\n    \"email\": \"rowlandkey@daido.com\",\n    \"phone\": \"+1 (949) 480-3748\",\n    \"address\": \"323 Brevoort Place, Sunriver, Utah, 124\",\n    \"about\": \"Cupidatat sit sunt ea cupidatat duis ut sunt elit minim sunt sunt amet. Nulla anim qui labore laborum et mollit nostrud laboris esse. Consequat consequat officia aliqua proident cillum id dolore quis deserunt nostrud ea. Laborum consequat incididunt anim irure velit minim ad anim magna officia fugiat officia. Laborum sit culpa deserunt minim adipisicing non excepteur mollit velit laborum cillum fugiat. Mollit cillum duis magna esse fugiat cillum duis minim velit dolor aliquip laborum.\\r\\n\",\n    \"registered\": \"2021-08-17T08:53:42 -02:00\",\n    \"latitude\": 49.784989,\n    \"longitude\": 60.020825,\n    \"tags\": [\n      \"reprehenderit\",\n      \"anim\",\n      \"nostrud\",\n      \"laboris\",\n      \"eiusmod\",\n      \"Lorem\",\n      \"veniam\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Lawson May\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Paula Dillard\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Juanita Jackson\"\n      }\n    ],\n    \"greeting\": \"Hello, Rowland Key! You have 10 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5c406f01543349201\",\n    \"index\": 181,\n    \"guid\": \"6eec5374-b78e-4026-b2b7-a36f60e8c1db\",\n    \"isActive\": false,\n    \"balance\": \"$1,462.75\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 30,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Martin Adams\",\n    \"gender\": \"male\",\n    \"company\": \"CORPULSE\",\n    \"email\": \"martinadams@corpulse.com\",\n    \"phone\": \"+1 (928) 462-3937\",\n    \"address\": \"378 Rockwell Place, Brule, Pennsylvania, 6830\",\n    \"about\": \"Ipsum ea minim sunt culpa eu duis consectetur minim velit officia exercitation est culpa commodo. Magna eu veniam amet dolor enim. Cupidatat magna eiusmod enim duis non ea dolor velit. Dolore cupidatat qui velit aute ut irure eiusmod aute velit deserunt excepteur. Reprehenderit eiusmod ipsum proident sunt laborum incididunt Lorem exercitation id et excepteur dolor. Cupidatat deserunt nostrud duis fugiat amet sit fugiat. Id nisi est sint minim fugiat elit id duis aliquip laborum officia amet dolor qui.\\r\\n\",\n    \"registered\": \"2017-01-11T10:02:22 -01:00\",\n    \"latitude\": 26.755958,\n    \"longitude\": -72.794358,\n    \"tags\": [\n      \"adipisicing\",\n      \"ut\",\n      \"aliquip\",\n      \"consequat\",\n      \"pariatur\",\n      \"eiusmod\",\n      \"ex\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Caroline Reese\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Potter Weiss\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Beatriz Conner\"\n      }\n    ],\n    \"greeting\": \"Hello, Martin Adams! You have 8 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5d4416ad8cb407f09\",\n    \"index\": 182,\n    \"guid\": \"3da24f84-21e4-4155-aa2a-c35ccdded1c0\",\n    \"isActive\": true,\n    \"balance\": \"$2,610.71\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 38,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Josie Tate\",\n    \"gender\": \"female\",\n    \"company\": \"GREEKER\",\n    \"email\": \"josietate@greeker.com\",\n    \"phone\": \"+1 (938) 447-2928\",\n    \"address\": \"346 Canal Avenue, Cutter, North Dakota, 1151\",\n    \"about\": \"Ex amet ad ex sint tempor occaecat. Voluptate sint nostrud qui aliquip amet. Aliqua velit voluptate laboris laboris occaecat officia. Proident minim eu elit ipsum labore incididunt.\\r\\n\",\n    \"registered\": \"2016-06-14T09:43:00 -02:00\",\n    \"latitude\": 68.979018,\n    \"longitude\": 161.867892,\n    \"tags\": [\n      \"enim\",\n      \"consectetur\",\n      \"dolore\",\n      \"sunt\",\n      \"commodo\",\n      \"laborum\",\n      \"aliquip\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Mcdowell Jones\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Sofia Finley\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Reid Byers\"\n      }\n    ],\n    \"greeting\": \"Hello, Josie Tate! You have 3 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5a95a7f9102521b83\",\n    \"index\": 183,\n    \"guid\": \"d7df7483-d192-4da6-90c4-a871be3d1845\",\n    \"isActive\": true,\n    \"balance\": \"$3,599.04\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Katie Mcfarland\",\n    \"gender\": \"female\",\n    \"company\": \"ZENSURE\",\n    \"email\": \"katiemcfarland@zensure.com\",\n    \"phone\": \"+1 (936) 480-3070\",\n    \"address\": \"635 Adams Street, Kenwood, Delaware, 2234\",\n    \"about\": \"Aliqua amet nulla aliquip fugiat velit irure culpa laboris. Velit veniam aliqua incididunt adipisicing in sunt enim anim culpa mollit. Officia dolor dolor eiusmod ex eu ea labore. Deserunt duis amet veniam ipsum anim incididunt qui laborum eiusmod laboris occaecat.\\r\\n\",\n    \"registered\": \"2021-09-28T07:52:55 -02:00\",\n    \"latitude\": 79.716579,\n    \"longitude\": 114.161419,\n    \"tags\": [\n      \"qui\",\n      \"ut\",\n      \"Lorem\",\n      \"voluptate\",\n      \"incididunt\",\n      \"mollit\",\n      \"pariatur\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Amie Pruitt\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Terry Gibson\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Maritza Perkins\"\n      }\n    ],\n    \"greeting\": \"Hello, Katie Mcfarland! You have 3 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5479b2f9b515d61ae\",\n    \"index\": 184,\n    \"guid\": \"dd149989-31dd-4b6a-b319-38256fb87364\",\n    \"isActive\": true,\n    \"balance\": \"$1,948.15\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Velasquez Herring\",\n    \"gender\": \"male\",\n    \"company\": \"QUILK\",\n    \"email\": \"velasquezherring@quilk.com\",\n    \"phone\": \"+1 (893) 405-3872\",\n    \"address\": \"318 Nevins Street, Abiquiu, Nevada, 5283\",\n    \"about\": \"Velit culpa ut officia id proident exercitation. Incididunt laborum esse sunt quis reprehenderit cillum adipisicing. Culpa sunt amet ex culpa consequat et labore incididunt esse est.\\r\\n\",\n    \"registered\": \"2015-01-09T10:43:24 -01:00\",\n    \"latitude\": -42.638841,\n    \"longitude\": 50.378183,\n    \"tags\": [\n      \"proident\",\n      \"labore\",\n      \"aute\",\n      \"ut\",\n      \"sunt\",\n      \"eiusmod\",\n      \"et\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Park Francis\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Phoebe Dickerson\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Barlow Pickett\"\n      }\n    ],\n    \"greeting\": \"Hello, Velasquez Herring! You have 3 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee55ec1c08bd5ea9d7e\",\n    \"index\": 185,\n    \"guid\": \"1bb73050-9d92-4090-a21b-fb07f14b8a94\",\n    \"isActive\": false,\n    \"balance\": \"$2,631.78\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"green\",\n    \"name\": \"Annabelle Forbes\",\n    \"gender\": \"female\",\n    \"company\": \"DIGIAL\",\n    \"email\": \"annabelleforbes@digial.com\",\n    \"phone\": \"+1 (961) 419-2904\",\n    \"address\": \"538 Oxford Street, Hanover, Montana, 2981\",\n    \"about\": \"Excepteur nulla deserunt est do non officia. Pariatur velit veniam sint exercitation laboris amet ipsum aute pariatur. Esse ad cupidatat deserunt amet ad aliquip veniam.\\r\\n\",\n    \"registered\": \"2017-05-03T05:48:08 -02:00\",\n    \"latitude\": -32.506727,\n    \"longitude\": 73.237161,\n    \"tags\": [\n      \"sint\",\n      \"proident\",\n      \"nulla\",\n      \"nostrud\",\n      \"nostrud\",\n      \"deserunt\",\n      \"id\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Barnes Mccall\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Sylvia Mccoy\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Murray Higgins\"\n      }\n    ],\n    \"greeting\": \"Hello, Annabelle Forbes! You have 6 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee519d3994fa42035b3\",\n    \"index\": 186,\n    \"guid\": \"216b152c-b290-403e-bd84-4f5dd6eaea85\",\n    \"isActive\": false,\n    \"balance\": \"$3,413.79\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 35,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Underwood Mcleod\",\n    \"gender\": \"male\",\n    \"company\": \"NETILITY\",\n    \"email\": \"underwoodmcleod@netility.com\",\n    \"phone\": \"+1 (966) 595-3474\",\n    \"address\": \"687 Boardwalk , Sardis, Arizona, 157\",\n    \"about\": \"Reprehenderit veniam pariatur eiusmod dolore aliqua aliqua. Excepteur id aute officia esse ex. Irure aliqua dolore nulla id amet excepteur Lorem occaecat reprehenderit qui in nulla velit.\\r\\n\",\n    \"registered\": \"2020-04-23T06:13:25 -02:00\",\n    \"latitude\": 69.512941,\n    \"longitude\": -24.381398,\n    \"tags\": [\n      \"nostrud\",\n      \"adipisicing\",\n      \"amet\",\n      \"eiusmod\",\n      \"ipsum\",\n      \"aute\",\n      \"incididunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Rowe Everett\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Janelle Estes\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Farmer Valentine\"\n      }\n    ],\n    \"greeting\": \"Hello, Underwood Mcleod! You have 9 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee5480d27f6da7f9029\",\n    \"index\": 187,\n    \"guid\": \"9e70f44c-9794-4e92-9eae-10b3d469929e\",\n    \"isActive\": false,\n    \"balance\": \"$1,207.48\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 40,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Weeks Marquez\",\n    \"gender\": \"male\",\n    \"company\": \"DIGIPRINT\",\n    \"email\": \"weeksmarquez@digiprint.com\",\n    \"phone\": \"+1 (998) 466-2001\",\n    \"address\": \"266 Ocean Avenue, Jeff, Massachusetts, 3696\",\n    \"about\": \"Excepteur dolor exercitation et amet sunt eiusmod duis consectetur adipisicing cupidatat labore. Amet veniam nisi qui adipisicing deserunt id reprehenderit quis. Aliquip et anim id eu elit consequat eiusmod dolor in culpa. Eiusmod nulla id voluptate velit qui exercitation qui proident exercitation incididunt ea excepteur. Labore consectetur ullamco sit nulla. Adipisicing ut fugiat ipsum nulla commodo cupidatat ex. Aliquip aute culpa duis elit.\\r\\n\",\n    \"registered\": \"2019-03-26T01:36:53 -01:00\",\n    \"latitude\": 34.46401,\n    \"longitude\": -84.92845,\n    \"tags\": [\n      \"incididunt\",\n      \"qui\",\n      \"velit\",\n      \"commodo\",\n      \"cupidatat\",\n      \"laboris\",\n      \"sint\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Talley Reed\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Preston David\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Alisha Tyler\"\n      }\n    ],\n    \"greeting\": \"Hello, Weeks Marquez! You have 1 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5501571da92a9fb20\",\n    \"index\": 188,\n    \"guid\": \"f2ae4f60-45f9-47db-81bf-733aaa3cc0d2\",\n    \"isActive\": false,\n    \"balance\": \"$2,546.05\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 24,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Freida Lowe\",\n    \"gender\": \"female\",\n    \"company\": \"PLASTO\",\n    \"email\": \"freidalowe@plasto.com\",\n    \"phone\": \"+1 (872) 410-3030\",\n    \"address\": \"810 Dunham Place, Emison, Maryland, 788\",\n    \"about\": \"Qui proident ea reprehenderit culpa aute sint et officia anim do adipisicing Lorem Lorem. Laboris reprehenderit quis laboris adipisicing. Minim id voluptate incididunt culpa eiusmod et laboris. Nisi amet in do proident sit incididunt tempor esse. Ut consectetur aliquip mollit consequat ex anim laboris. Pariatur duis cillum commodo voluptate nulla ea pariatur exercitation veniam. Excepteur cupidatat cillum Lorem dolor aute laboris.\\r\\n\",\n    \"registered\": \"2019-01-18T05:16:28 -01:00\",\n    \"latitude\": -30.465874,\n    \"longitude\": 41.428646,\n    \"tags\": [\n      \"pariatur\",\n      \"proident\",\n      \"amet\",\n      \"do\",\n      \"quis\",\n      \"proident\",\n      \"officia\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Watts Conley\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Frederick Whitehead\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Louella Booker\"\n      }\n    ],\n    \"greeting\": \"Hello, Freida Lowe! You have 3 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee589ff52469cf1a971\",\n    \"index\": 189,\n    \"guid\": \"5f582990-d296-4a2d-8a44-be0bfd04492c\",\n    \"isActive\": true,\n    \"balance\": \"$3,548.74\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Snow Buckner\",\n    \"gender\": \"male\",\n    \"company\": \"DIGIRANG\",\n    \"email\": \"snowbuckner@digirang.com\",\n    \"phone\": \"+1 (874) 447-3630\",\n    \"address\": \"142 Midwood Street, Abrams, Florida, 1957\",\n    \"about\": \"Reprehenderit anim eu sit nostrud ut labore ad esse exercitation nisi dolor sint commodo. Aliqua anim mollit tempor sit proident proident pariatur Lorem elit. Sint laborum aute duis minim. Nisi dolor esse est enim qui aute dolor. Est ad cupidatat culpa ex fugiat est consequat ad eiusmod. Duis voluptate occaecat ullamco sint. Dolor est reprehenderit nostrud anim elit laborum pariatur aute adipisicing cillum proident dolor.\\r\\n\",\n    \"registered\": \"2018-04-29T12:53:56 -02:00\",\n    \"latitude\": -50.925581,\n    \"longitude\": -152.924382,\n    \"tags\": [\n      \"labore\",\n      \"irure\",\n      \"ullamco\",\n      \"labore\",\n      \"cillum\",\n      \"eiusmod\",\n      \"aliqua\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Silvia Porter\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Thelma Rosales\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Tamika Morales\"\n      }\n    ],\n    \"greeting\": \"Hello, Snow Buckner! You have 7 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee519ce5a1c019e15a3\",\n    \"index\": 190,\n    \"guid\": \"f9d94d39-f17e-4201-adbc-60e2772d8ed7\",\n    \"isActive\": false,\n    \"balance\": \"$3,716.16\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 32,\n    \"eyeColor\": \"green\",\n    \"name\": \"Olive Wood\",\n    \"gender\": \"female\",\n    \"company\": \"SONIQUE\",\n    \"email\": \"olivewood@sonique.com\",\n    \"phone\": \"+1 (904) 445-3806\",\n    \"address\": \"118 Bainbridge Street, Newcastle, Washington, 5600\",\n    \"about\": \"Do nulla tempor dolore et excepteur anim tempor nostrud ipsum. Aute nostrud enim exercitation elit veniam aute Lorem. Sunt duis voluptate nisi elit mollit et do nostrud elit anim pariatur adipisicing incididunt. Eiusmod nulla nostrud consequat incididunt qui ad nulla dolore veniam sunt velit officia ad. Ad velit amet cupidatat in ad occaecat.\\r\\n\",\n    \"registered\": \"2014-07-16T06:21:27 -02:00\",\n    \"latitude\": 57.237106,\n    \"longitude\": -79.252817,\n    \"tags\": [\n      \"occaecat\",\n      \"incididunt\",\n      \"do\",\n      \"sit\",\n      \"veniam\",\n      \"enim\",\n      \"est\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Hughes Stevens\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Higgins Adkins\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Laura Mercer\"\n      }\n    ],\n    \"greeting\": \"Hello, Olive Wood! You have 7 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5dee040a602f428c1\",\n    \"index\": 191,\n    \"guid\": \"c3bf584f-ffb2-4f61-8f68-ae0ba14d9a2c\",\n    \"isActive\": true,\n    \"balance\": \"$1,770.68\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Clark Obrien\",\n    \"gender\": \"male\",\n    \"company\": \"SLAX\",\n    \"email\": \"clarkobrien@slax.com\",\n    \"phone\": \"+1 (954) 457-3809\",\n    \"address\": \"969 Harbor Lane, Clay, Virginia, 180\",\n    \"about\": \"Amet esse sunt ex in nisi. Dolore dolore laborum culpa mollit culpa fugiat reprehenderit ex ea nulla elit. Commodo id deserunt cupidatat dolore aliqua nulla in culpa pariatur proident aute id minim culpa.\\r\\n\",\n    \"registered\": \"2018-02-02T12:35:06 -01:00\",\n    \"latitude\": -17.229035,\n    \"longitude\": 99.502623,\n    \"tags\": [\n      \"consectetur\",\n      \"consectetur\",\n      \"ullamco\",\n      \"reprehenderit\",\n      \"non\",\n      \"pariatur\",\n      \"duis\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Decker Tucker\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Laurel Little\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Angel Vazquez\"\n      }\n    ],\n    \"greeting\": \"Hello, Clark Obrien! You have 5 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee53eb3d612e8440c28\",\n    \"index\": 192,\n    \"guid\": \"4efe5f47-f152-425b-a4aa-c8ff402898b6\",\n    \"isActive\": true,\n    \"balance\": \"$1,160.16\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 21,\n    \"eyeColor\": \"green\",\n    \"name\": \"Petersen Landry\",\n    \"gender\": \"male\",\n    \"company\": \"BUNGA\",\n    \"email\": \"petersenlandry@bunga.com\",\n    \"phone\": \"+1 (948) 431-3897\",\n    \"address\": \"239 Mayfair Drive, Glendale, Oklahoma, 2717\",\n    \"about\": \"Proident mollit Lorem commodo fugiat duis officia anim sint ut velit occaecat esse aliqua. Incididunt ut non pariatur eu proident ea occaecat veniam excepteur. Non cillum non minim ullamco occaecat qui excepteur sint exercitation ut pariatur voluptate non. Dolore dolore esse non voluptate commodo sint non reprehenderit esse eu.\\r\\n\",\n    \"registered\": \"2020-09-08T03:16:07 -02:00\",\n    \"latitude\": -20.682819,\n    \"longitude\": 146.076896,\n    \"tags\": [\n      \"aute\",\n      \"exercitation\",\n      \"non\",\n      \"eu\",\n      \"enim\",\n      \"qui\",\n      \"velit\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Doreen Hutchinson\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Watson Barton\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Rita Mejia\"\n      }\n    ],\n    \"greeting\": \"Hello, Petersen Landry! You have 5 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5ad015538a90435d4\",\n    \"index\": 193,\n    \"guid\": \"987667ab-941b-49ab-a59a-e53da8c74ae7\",\n    \"isActive\": true,\n    \"balance\": \"$3,147.39\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 25,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Adeline Patterson\",\n    \"gender\": \"female\",\n    \"company\": \"ENTALITY\",\n    \"email\": \"adelinepatterson@entality.com\",\n    \"phone\": \"+1 (887) 474-2539\",\n    \"address\": \"548 Benson Avenue, Malo, Mississippi, 8937\",\n    \"about\": \"Nulla sunt est qui aliquip ut eiusmod velit esse. Duis cupidatat qui nostrud sint mollit veniam nulla cillum laborum. Minim pariatur nisi ea consequat labore ipsum quis laboris fugiat. Aliquip commodo cillum laborum ex minim sunt sint commodo consequat ut sunt amet est occaecat. Occaecat non ut ad sit elit occaecat laboris culpa Lorem aute aliquip culpa in.\\r\\n\",\n    \"registered\": \"2019-07-04T07:31:49 -02:00\",\n    \"latitude\": 25.737567,\n    \"longitude\": 150.633802,\n    \"tags\": [\n      \"quis\",\n      \"consequat\",\n      \"id\",\n      \"enim\",\n      \"occaecat\",\n      \"dolor\",\n      \"nisi\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Cherry Stokes\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Madden Cotton\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Robin Dean\"\n      }\n    ],\n    \"greeting\": \"Hello, Adeline Patterson! You have 1 unread messages.\",\n    \"favoriteFruit\": \"strawberry\"\n  },\n  {\n    \"_id\": \"616eeee516ccdfda4ab4c71b\",\n    \"index\": 194,\n    \"guid\": \"d275e7e4-fedc-4b60-ad16-95986230c7ee\",\n    \"isActive\": true,\n    \"balance\": \"$3,716.32\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 34,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Sandoval Carter\",\n    \"gender\": \"male\",\n    \"company\": \"GEEKKO\",\n    \"email\": \"sandovalcarter@geekko.com\",\n    \"phone\": \"+1 (862) 532-3993\",\n    \"address\": \"375 Bergen Court, Lopezo, Wisconsin, 8079\",\n    \"about\": \"Magna enim est velit veniam reprehenderit esse cupidatat cupidatat ipsum ad. Pariatur commodo magna aliquip voluptate enim. Ex fugiat officia quis et. Cillum esse consectetur fugiat mollit cillum consectetur sint ex. Fugiat tempor id ullamco anim amet culpa id ea ut aute commodo dolore tempor eiusmod.\\r\\n\",\n    \"registered\": \"2019-01-31T03:02:07 -01:00\",\n    \"latitude\": -89.254177,\n    \"longitude\": 57.507808,\n    \"tags\": [\n      \"velit\",\n      \"laborum\",\n      \"Lorem\",\n      \"Lorem\",\n      \"commodo\",\n      \"excepteur\",\n      \"duis\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Kim Church\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Leticia Pugh\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Shirley Maynard\"\n      }\n    ],\n    \"greeting\": \"Hello, Sandoval Carter! You have 3 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee580731f0d0258baad\",\n    \"index\": 195,\n    \"guid\": \"6df94b5f-c7c6-46ed-9ee9-373916c7bdee\",\n    \"isActive\": false,\n    \"balance\": \"$2,970.18\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 39,\n    \"eyeColor\": \"green\",\n    \"name\": \"Clay Mcmillan\",\n    \"gender\": \"male\",\n    \"company\": \"STEELTAB\",\n    \"email\": \"claymcmillan@steeltab.com\",\n    \"phone\": \"+1 (832) 487-3960\",\n    \"address\": \"360 Junius Street, Mayfair, South Dakota, 6507\",\n    \"about\": \"Ea magna tempor nulla commodo. Deserunt ex eiusmod consectetur officia ipsum aliquip eu. Incididunt esse nostrud tempor tempor ullamco aliqua officia nulla cillum consequat nisi reprehenderit consectetur amet. Est labore anim reprehenderit nulla esse esse irure minim occaecat.\\r\\n\",\n    \"registered\": \"2014-10-04T06:02:07 -02:00\",\n    \"latitude\": -58.892437,\n    \"longitude\": -141.808041,\n    \"tags\": [\n      \"velit\",\n      \"ex\",\n      \"sit\",\n      \"voluptate\",\n      \"pariatur\",\n      \"culpa\",\n      \"deserunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Kathy Peck\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Middleton Joseph\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Shelley Fernandez\"\n      }\n    ],\n    \"greeting\": \"Hello, Clay Mcmillan! You have 1 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee50ba1e50a969e00b9\",\n    \"index\": 196,\n    \"guid\": \"4c34f739-c61a-442a-bb62-1da863649931\",\n    \"isActive\": true,\n    \"balance\": \"$3,077.59\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 38,\n    \"eyeColor\": \"green\",\n    \"name\": \"Branch Chase\",\n    \"gender\": \"male\",\n    \"company\": \"DIGINETIC\",\n    \"email\": \"branchchase@diginetic.com\",\n    \"phone\": \"+1 (843) 462-3629\",\n    \"address\": \"442 Newel Street, Tilden, Georgia, 1782\",\n    \"about\": \"Culpa consectetur duis dolore mollit proident velit ipsum ex id occaecat consequat. Anim est irure incididunt eu non dolor ea irure et. Aliqua voluptate officia sit amet voluptate ea incididunt culpa laboris adipisicing anim excepteur voluptate qui. Occaecat exercitation anim duis culpa et non dolor.\\r\\n\",\n    \"registered\": \"2015-03-08T04:58:20 -01:00\",\n    \"latitude\": -0.692459,\n    \"longitude\": 11.851837,\n    \"tags\": [\n      \"do\",\n      \"et\",\n      \"aliquip\",\n      \"consequat\",\n      \"consequat\",\n      \"est\",\n      \"ut\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Carole Compton\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Manning Rodriquez\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Deidre Hill\"\n      }\n    ],\n    \"greeting\": \"Hello, Branch Chase! You have 9 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee5468565b47781602b\",\n    \"index\": 197,\n    \"guid\": \"edba7486-da4f-4572-8c4e-1669eb6c48ff\",\n    \"isActive\": true,\n    \"balance\": \"$3,714.40\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 30,\n    \"eyeColor\": \"brown\",\n    \"name\": \"Noble Spencer\",\n    \"gender\": \"male\",\n    \"company\": \"BLANET\",\n    \"email\": \"noblespencer@blanet.com\",\n    \"phone\": \"+1 (991) 487-2284\",\n    \"address\": \"411 Applegate Court, Why, Connecticut, 7344\",\n    \"about\": \"Proident incididunt Lorem ipsum minim nisi culpa. Aute irure laboris incididunt eiusmod sit mollit nisi elit nulla. Ut excepteur ut laborum cupidatat. Non in exercitation laborum proident pariatur consectetur nostrud et officia. Id fugiat non sunt consequat tempor deserunt mollit laborum reprehenderit aute ex laborum dolor duis. Deserunt proident cupidatat dolore commodo culpa veniam ex nisi dolor do sunt pariatur aliqua. In ex ullamco sunt fugiat.\\r\\n\",\n    \"registered\": \"2019-06-01T09:11:37 -02:00\",\n    \"latitude\": -6.339032,\n    \"longitude\": 7.267724,\n    \"tags\": [\n      \"magna\",\n      \"ut\",\n      \"do\",\n      \"ut\",\n      \"officia\",\n      \"esse\",\n      \"ea\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Marie Gaines\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Janell Aguirre\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Alissa West\"\n      }\n    ],\n    \"greeting\": \"Hello, Noble Spencer! You have 4 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  },\n  {\n    \"_id\": \"616eeee5a2d0077c4911f556\",\n    \"index\": 198,\n    \"guid\": \"dee72d60-4aab-4e07-ba22-9b26181b2c01\",\n    \"isActive\": false,\n    \"balance\": \"$1,199.25\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 36,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Luisa Baker\",\n    \"gender\": \"female\",\n    \"company\": \"ZOSIS\",\n    \"email\": \"luisabaker@zosis.com\",\n    \"phone\": \"+1 (800) 474-2680\",\n    \"address\": \"317 Cozine Avenue, Laurelton, West Virginia, 2633\",\n    \"about\": \"Velit eu ex nisi laboris. Proident dolor cillum nulla tempor nisi voluptate mollit labore anim excepteur. Est occaecat cillum deserunt est aliquip elit ex consectetur labore. Commodo enim eu excepteur nostrud officia consequat aliqua quis sit proident sit cupidatat.\\r\\n\",\n    \"registered\": \"2015-10-06T07:18:36 -02:00\",\n    \"latitude\": 6.395792,\n    \"longitude\": -133.28126,\n    \"tags\": [\n      \"adipisicing\",\n      \"do\",\n      \"consectetur\",\n      \"sit\",\n      \"aliquip\",\n      \"sint\",\n      \"deserunt\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Jody Baldwin\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Deana Barry\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Jaclyn Anderson\"\n      }\n    ],\n    \"greeting\": \"Hello, Luisa Baker! You have 2 unread messages.\",\n    \"favoriteFruit\": \"banana\"\n  },\n  {\n    \"_id\": \"616eeee55db3fd71d8fadcb8\",\n    \"index\": 199,\n    \"guid\": \"bc5950ea-01ab-4ab1-9e96-1771936b453a\",\n    \"isActive\": true,\n    \"balance\": \"$1,265.22\",\n    \"picture\": \"http://placehold.it/32x32\",\n    \"age\": 27,\n    \"eyeColor\": \"blue\",\n    \"name\": \"Kelly Golden\",\n    \"gender\": \"male\",\n    \"company\": \"MACRONAUT\",\n    \"email\": \"kellygolden@macronaut.com\",\n    \"phone\": \"+1 (914) 524-3436\",\n    \"address\": \"780 Pooles Lane, Maybell, Marshall Islands, 4481\",\n    \"about\": \"Fugiat pariatur sit magna mollit sunt. Incididunt consectetur magna irure anim. Commodo sunt do est sit in Lorem excepteur voluptate fugiat eiusmod duis aute esse. Fugiat nisi aliquip ea minim. Sunt eiusmod ex ex ipsum sit elit et laboris labore excepteur commodo.\\r\\n\",\n    \"registered\": \"2017-08-11T03:14:35 -02:00\",\n    \"latitude\": -72.17515,\n    \"longitude\": 92.503238,\n    \"tags\": [\n      \"laborum\",\n      \"velit\",\n      \"est\",\n      \"elit\",\n      \"excepteur\",\n      \"et\",\n      \"nostrud\"\n    ],\n    \"friends\": [\n      {\n        \"id\": 0,\n        \"name\": \"Becker Rollins\"\n      },\n      {\n        \"id\": 1,\n        \"name\": \"Curry Mcfadden\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Henderson Delaney\"\n      }\n    ],\n    \"greeting\": \"Hello, Kelly Golden! You have 3 unread messages.\",\n    \"favoriteFruit\": \"apple\"\n  }\n]\n"
  },
  {
    "path": "misc/packcc/benchmark/inputs/kotlin.kt",
    "content": "/*\n * Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.\n * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.\n */\n\npackage org.jetbrains.kotlin.renderer\n\nimport org.jetbrains.kotlin.builtins.*\nimport org.jetbrains.kotlin.descriptors.*\nimport org.jetbrains.kotlin.descriptors.annotations.Annotated\nimport org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor\nimport org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget\nimport org.jetbrains.kotlin.name.FqName\nimport org.jetbrains.kotlin.name.FqNameUnsafe\nimport org.jetbrains.kotlin.name.Name\nimport org.jetbrains.kotlin.name.SpecialNames\nimport org.jetbrains.kotlin.resolve.DescriptorUtils\nimport org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject\nimport org.jetbrains.kotlin.resolve.constants.AnnotationValue\nimport org.jetbrains.kotlin.resolve.constants.ArrayValue\nimport org.jetbrains.kotlin.resolve.constants.ConstantValue\nimport org.jetbrains.kotlin.resolve.constants.KClassValue\nimport org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass\nimport org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue\nimport org.jetbrains.kotlin.types.*\nimport org.jetbrains.kotlin.types.ErrorUtils.UninferredParameterTypeConstructor\nimport org.jetbrains.kotlin.types.TypeUtils.CANT_INFER_FUNCTION_PARAM_TYPE\nimport java.util.*\n\ninternal class DescriptorRendererImpl(\n    val options: DescriptorRendererOptionsImpl\n) : DescriptorRenderer(), DescriptorRendererOptions by options/* this gives access to options without qualifier */ {\n    init {\n        assert(options.isLocked)\n    }\n\n    private val functionTypeAnnotationsRenderer: DescriptorRendererImpl by lazy {\n        withOptions {\n            excludedTypeAnnotationClasses += listOf(StandardNames.FqNames.extensionFunctionType)\n            annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.ALWAYS_PARENTHESIZED\n        } as DescriptorRendererImpl\n    }\n\n    /* FORMATTING */\n    private fun renderKeyword(keyword: String): String = when (textFormat) {\n        RenderingFormat.PLAIN -> keyword\n        RenderingFormat.HTML -> if (boldOnlyForNamesInHtml) keyword else \"<b>$keyword</b>\"\n    }\n\n    private fun renderError(keyword: String): String = when (textFormat) {\n        RenderingFormat.PLAIN -> keyword\n        RenderingFormat.HTML -> \"<font color=red><b>$keyword</b></font>\"\n    }\n\n    private fun escape(string: String) = textFormat.escape(string)\n\n    private fun lt() = escape(\"<\")\n    private fun gt() = escape(\">\")\n\n    private fun arrow(): String = when (textFormat) {\n        RenderingFormat.PLAIN -> escape(\"->\")\n        RenderingFormat.HTML -> \"&rarr;\"\n    }\n\n    override fun renderMessage(message: String): String = when (textFormat) {\n        RenderingFormat.PLAIN -> message\n        RenderingFormat.HTML -> \"<i>$message</i>\"\n    }\n\n    /* NAMES RENDERING */\n    override fun renderName(name: Name, rootRenderedElement: Boolean): String {\n        val escaped = escape(name.render())\n        return if (boldOnlyForNamesInHtml && textFormat == RenderingFormat.HTML && rootRenderedElement) {\n            \"<b>$escaped</b>\"\n        } else\n            escaped\n    }\n\n    private fun renderName(descriptor: DeclarationDescriptor, builder: StringBuilder, rootRenderedElement: Boolean) {\n        builder.append(renderName(descriptor.name, rootRenderedElement))\n    }\n\n    private fun renderCompanionObjectName(descriptor: DeclarationDescriptor, builder: StringBuilder) {\n        if (renderCompanionObjectName) {\n            if (startFromName) {\n                builder.append(\"companion object\")\n            }\n            renderSpaceIfNeeded(builder)\n            val containingDeclaration = descriptor.containingDeclaration\n            if (containingDeclaration != null) {\n                builder.append(\"of \")\n                builder.append(renderName(containingDeclaration.name, false))\n            }\n        }\n        if (verbose || descriptor.name != SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) {\n            if (!startFromName) renderSpaceIfNeeded(builder)\n            builder.append(renderName(descriptor.name, true))\n        }\n    }\n\n    override fun renderFqName(fqName: FqNameUnsafe) = renderFqName(fqName.pathSegments())\n\n    private fun renderFqName(pathSegments: List<Name>) = escape(org.jetbrains.kotlin.renderer.renderFqName(pathSegments))\n\n    override fun renderClassifierName(klass: ClassifierDescriptor): String = if (ErrorUtils.isError(klass)) {\n        klass.typeConstructor.toString()\n    } else\n        classifierNamePolicy.renderClassifier(klass, this)\n\n    /* TYPES RENDERING */\n    override fun renderType(type: KotlinType): String = buildString {\n        renderNormalizedType(typeNormalizer(type))\n    }\n\n    private fun StringBuilder.renderNormalizedType(type: KotlinType) {\n        val abbreviated = type.unwrap() as? AbbreviatedType\n        if (abbreviated != null) {\n            if (renderTypeExpansions) {\n                renderNormalizedTypeAsIs(abbreviated.expandedType)\n            } else {\n                // TODO nullability is lost for abbreviated type?\n                renderNormalizedTypeAsIs(abbreviated.abbreviation)\n                if (renderUnabbreviatedType) {\n                    renderAbbreviatedTypeExpansion(abbreviated)\n                }\n            }\n            return\n        }\n\n        renderNormalizedTypeAsIs(type)\n    }\n\n    private fun StringBuilder.renderAbbreviatedTypeExpansion(abbreviated: AbbreviatedType) {\n        if (textFormat == RenderingFormat.HTML) {\n            append(\"<font color=\\\"808080\\\"><i>\")\n        }\n        append(\" /* = \")\n        renderNormalizedTypeAsIs(abbreviated.expandedType)\n        append(\" */\")\n        if (textFormat == RenderingFormat.HTML) {\n            append(\"</i></font>\")\n        }\n    }\n\n    private fun StringBuilder.renderNormalizedTypeAsIs(type: KotlinType) {\n        if (type is WrappedType && debugMode && !type.isComputed()) {\n            append(\"<Not computed yet>\")\n            return\n        }\n        when (val unwrappedType = type.unwrap()) {\n            is FlexibleType -> append(unwrappedType.render(this@DescriptorRendererImpl, this@DescriptorRendererImpl))\n            is SimpleType -> renderSimpleType(unwrappedType)\n        }\n    }\n\n    private fun StringBuilder.renderSimpleType(type: SimpleType) {\n        if (type == CANT_INFER_FUNCTION_PARAM_TYPE || TypeUtils.isDontCarePlaceholder(type)) {\n            append(\"???\")\n            return\n        }\n        if (ErrorUtils.isUninferredParameter(type)) {\n            if (uninferredTypeParameterAsName) {\n                append(renderError((type.constructor as UninferredParameterTypeConstructor).typeParameterDescriptor.name.toString()))\n            } else {\n                append(\"???\")\n            }\n            return\n        }\n\n        if (type.isError) {\n            renderDefaultType(type)\n            return\n        }\n        if (shouldRenderAsPrettyFunctionType(type)) {\n            renderFunctionType(type)\n        } else {\n            renderDefaultType(type)\n        }\n    }\n\n    private fun shouldRenderAsPrettyFunctionType(type: KotlinType): Boolean {\n        return type.isBuiltinFunctionalType && type.arguments.none { it.isStarProjection }\n    }\n\n    override fun renderFlexibleType(lowerRendered: String, upperRendered: String, builtIns: KotlinBuiltIns): String {\n        if (differsOnlyInNullability(lowerRendered, upperRendered)) {\n            if (upperRendered.startsWith(\"(\")) {\n                // the case of complex type, e.g. (() -> Unit)?\n                return \"($lowerRendered)!\"\n            }\n            return \"$lowerRendered!\"\n        }\n\n        val kotlinCollectionsPrefix = classifierNamePolicy.renderClassifier(builtIns.collection, this).substringBefore(\"Collection\")\n        val mutablePrefix = \"Mutable\"\n        // java.util.List<Foo> -> (Mutable)List<Foo!>!\n        val simpleCollection = replacePrefixes(\n            lowerRendered,\n            kotlinCollectionsPrefix + mutablePrefix,\n            upperRendered,\n            kotlinCollectionsPrefix,\n            \"$kotlinCollectionsPrefix($mutablePrefix)\"\n        )\n        if (simpleCollection != null) return simpleCollection\n        // java.util.Map.Entry<Foo, Bar> -> (Mutable)Map.(Mutable)Entry<Foo!, Bar!>!\n        val mutableEntry = replacePrefixes(\n            lowerRendered,\n            kotlinCollectionsPrefix + \"MutableMap.MutableEntry\",\n            upperRendered,\n            kotlinCollectionsPrefix + \"Map.Entry\",\n            \"$kotlinCollectionsPrefix(Mutable)Map.(Mutable)Entry\"\n        )\n        if (mutableEntry != null) return mutableEntry\n\n        val kotlinPrefix = classifierNamePolicy.renderClassifier(builtIns.array, this).substringBefore(\"Array\")\n        // Foo[] -> Array<(out) Foo!>!\n        val array = replacePrefixes(\n            lowerRendered,\n            kotlinPrefix + escape(\"Array<\"),\n            upperRendered,\n            kotlinPrefix + escape(\"Array<out \"),\n            kotlinPrefix + escape(\"Array<(out) \")\n        )\n        if (array != null) return array\n\n        return \"($lowerRendered..$upperRendered)\"\n    }\n\n    override fun renderTypeArguments(typeArguments: List<TypeProjection>): String = if (typeArguments.isEmpty()) \"\"\n    else buildString {\n        append(lt())\n        this.appendTypeProjections(typeArguments)\n        append(gt())\n    }\n\n    private fun StringBuilder.renderDefaultType(type: KotlinType) {\n        this.renderAnnotations(type)\n\n        if (type.isError) {\n            if (type is UnresolvedType && presentableUnresolvedTypes) {\n                append(type.presentableName)\n            } else {\n                if (type is ErrorType && !informativeErrorType) {\n                    append(type.presentableName)\n                } else {\n                    append(type.constructor.toString()) // Debug name of an error type is more informative\n                }\n            }\n            append(renderTypeArguments(type.arguments))\n        } else {\n            renderTypeConstructorAndArguments(type)\n        }\n\n        if (type.isMarkedNullable) {\n            append(\"?\")\n        }\n\n        if (type.isDefinitelyNotNullType) {\n            append(\"!!\")\n        }\n    }\n\n    private fun StringBuilder.renderTypeConstructorAndArguments(\n        type: KotlinType,\n        typeConstructor: TypeConstructor = type.constructor\n    ) {\n        val possiblyInnerType = type.buildPossiblyInnerType()\n        if (possiblyInnerType == null) {\n            append(renderTypeConstructor(typeConstructor))\n            append(renderTypeArguments(type.arguments))\n            return\n        }\n\n        renderPossiblyInnerType(possiblyInnerType)\n    }\n\n    private fun StringBuilder.renderPossiblyInnerType(possiblyInnerType: PossiblyInnerType) {\n        possiblyInnerType.outerType?.let {\n            renderPossiblyInnerType(it)\n            append('.')\n            append(renderName(possiblyInnerType.classifierDescriptor.name, false))\n        } ?: append(renderTypeConstructor(possiblyInnerType.classifierDescriptor.typeConstructor))\n\n        append(renderTypeArguments(possiblyInnerType.arguments))\n    }\n\n    override fun renderTypeConstructor(typeConstructor: TypeConstructor): String = when (val cd = typeConstructor.declarationDescriptor) {\n        is TypeParameterDescriptor, is ClassDescriptor, is TypeAliasDescriptor -> renderClassifierName(cd)\n        null -> typeConstructor.toString()\n        else -> error(\"Unexpected classifier: \" + cd::class.java)\n    }\n\n    override fun renderTypeProjection(typeProjection: TypeProjection) = buildString {\n        appendTypeProjections(listOf(typeProjection))\n    }\n\n    private fun StringBuilder.appendTypeProjections(typeProjections: List<TypeProjection>) {\n        typeProjections.joinTo(this, \", \") {\n            if (it.isStarProjection) {\n                \"*\"\n            } else {\n                val type = renderType(it.type)\n                if (it.projectionKind == Variance.INVARIANT) type else \"${it.projectionKind} $type\"\n            }\n        }\n    }\n\n    private fun StringBuilder.renderFunctionType(type: KotlinType) {\n        val lengthBefore = length\n        // we need special renderer to skip @ExtensionFunctionType\n        with(functionTypeAnnotationsRenderer) {\n            renderAnnotations(type)\n        }\n        val hasAnnotations = length != lengthBefore\n\n        val isSuspend = type.isSuspendFunctionType\n        val isNullable = type.isMarkedNullable\n        val receiverType = type.getReceiverTypeFromFunctionType()\n\n        val needParenthesis = isNullable || (hasAnnotations && receiverType != null)\n        if (needParenthesis) {\n            if (isSuspend) {\n                insert(lengthBefore, '(')\n            } else {\n                if (hasAnnotations) {\n                    assert(last() == ' ')\n                    if (get(lastIndex - 1) != ')') {\n                        // last annotation rendered without parenthesis - need to add them otherwise parsing will be incorrect\n                        insert(lastIndex, \"()\")\n                    }\n                }\n\n                append(\"(\")\n            }\n        }\n\n        renderModifier(this, isSuspend, \"suspend\")\n\n        if (receiverType != null) {\n            val surroundReceiver = shouldRenderAsPrettyFunctionType(receiverType) && !receiverType.isMarkedNullable ||\n                    receiverType.hasModifiersOrAnnotations()\n            if (surroundReceiver) {\n                append(\"(\")\n            }\n            renderNormalizedType(receiverType)\n            if (surroundReceiver) {\n                append(\")\")\n            }\n            append(\".\")\n        }\n\n        append(\"(\")\n\n        val parameterTypes = type.getValueParameterTypesFromFunctionType()\n        for ((index, typeProjection) in parameterTypes.withIndex()) {\n            if (index > 0) append(\", \")\n\n            val name = if (parameterNamesInFunctionalTypes) typeProjection.type.extractParameterNameFromFunctionTypeArgument() else null\n            if (name != null) {\n                append(renderName(name, false))\n                append(\": \")\n            }\n\n            append(renderTypeProjection(typeProjection))\n        }\n\n        append(\") \").append(arrow()).append(\" \")\n        renderNormalizedType(type.getReturnTypeFromFunctionType())\n\n        if (needParenthesis) append(\")\")\n\n        if (isNullable) append(\"?\")\n    }\n\n    private fun KotlinType.hasModifiersOrAnnotations() =\n        isSuspendFunctionType || !annotations.isEmpty()\n\n    /* METHODS FOR ALL KINDS OF DESCRIPTORS */\n    private fun StringBuilder.appendDefinedIn(descriptor: DeclarationDescriptor) {\n        if (descriptor is PackageFragmentDescriptor || descriptor is PackageViewDescriptor) {\n            return\n        }\n        if (descriptor is ModuleDescriptor) {\n            append(\" is a module\")\n            return\n        }\n\n        val containingDeclaration = descriptor.containingDeclaration\n        if (containingDeclaration != null && containingDeclaration !is ModuleDescriptor) {\n            append(\" \").append(renderMessage(\"defined in\")).append(\" \")\n            val fqName = DescriptorUtils.getFqName(containingDeclaration)\n            append(if (fqName.isRoot) \"root package\" else renderFqName(fqName))\n\n            if (withSourceFileForTopLevel &&\n                containingDeclaration is PackageFragmentDescriptor &&\n                descriptor is DeclarationDescriptorWithSource\n            ) {\n                descriptor.source.containingFile.name?.let { sourceFileName ->\n                    append(\" \").append(renderMessage(\"in file\")).append(\" \").append(sourceFileName)\n                }\n            }\n        }\n    }\n\n    private fun StringBuilder.renderAnnotations(annotated: Annotated, target: AnnotationUseSiteTarget? = null) {\n        if (DescriptorRendererModifier.ANNOTATIONS !in modifiers) return\n\n        val excluded = if (annotated is KotlinType) excludedTypeAnnotationClasses else excludedAnnotationClasses\n\n        val annotationFilter = annotationFilter\n        for (annotation in annotated.annotations) {\n            if (annotation.fqName !in excluded\n                && !annotation.isParameterName()\n                && (annotationFilter == null || annotationFilter(annotation))\n            ) {\n                append(renderAnnotation(annotation, target))\n                if (eachAnnotationOnNewLine) {\n                    appendLine()\n                } else {\n                    append(\" \")\n                }\n            }\n        }\n    }\n\n    private fun AnnotationDescriptor.isParameterName(): Boolean {\n        return fqName == StandardNames.FqNames.parameterName\n    }\n\n    override fun renderAnnotation(annotation: AnnotationDescriptor, target: AnnotationUseSiteTarget?): String {\n        return buildString {\n            append('@')\n            if (target != null) {\n                append(target.renderName + \":\")\n            }\n            val annotationType = annotation.type\n            append(renderType(annotationType))\n\n            if (includeAnnotationArguments) {\n                val arguments = renderAndSortAnnotationArguments(annotation)\n                if (includeEmptyAnnotationArguments || arguments.isNotEmpty()) {\n                    arguments.joinTo(this, \", \", \"(\", \")\")\n                }\n            }\n\n            if (verbose && (annotationType.isError || annotationType.constructor.declarationDescriptor is NotFoundClasses.MockClassDescriptor)) {\n                append(\" /* annotation class not found */\")\n            }\n        }\n    }\n\n    private fun renderAndSortAnnotationArguments(descriptor: AnnotationDescriptor): List<String> {\n        val allValueArguments = descriptor.allValueArguments\n        val classDescriptor = if (renderDefaultAnnotationArguments) descriptor.annotationClass else null\n        val parameterDescriptorsWithDefaultValue = classDescriptor?.unsubstitutedPrimaryConstructor?.valueParameters\n            ?.filter { it.declaresDefaultValue() }\n            ?.map { it.name }\n            .orEmpty()\n        val defaultList = parameterDescriptorsWithDefaultValue.filter { it !in allValueArguments }.map { \"${it.asString()} = ...\" }\n        val argumentList = allValueArguments.entries\n            .map { (name, value) ->\n                \"${name.asString()} = ${if (name !in parameterDescriptorsWithDefaultValue) renderConstant(value) else \"...\"}\"\n            }\n        return (defaultList + argumentList).sorted()\n    }\n\n    private fun renderConstant(value: ConstantValue<*>): String {\n        return when (value) {\n            is ArrayValue -> value.value.joinToString(\", \", \"{\", \"}\") { renderConstant(it) }\n            is AnnotationValue -> renderAnnotation(value.value).removePrefix(\"@\")\n            is KClassValue -> when (val classValue = value.value) {\n                is KClassValue.Value.LocalClass -> \"${classValue.type}::class\"\n                is KClassValue.Value.NormalClass -> {\n                    var type = classValue.classId.asSingleFqName().asString()\n                    repeat(classValue.arrayDimensions) { type = \"kotlin.Array<$type>\" }\n                    \"$type::class\"\n                }\n            }\n            else -> value.toString()\n        }\n    }\n\n    private fun renderVisibility(visibility: DescriptorVisibility, builder: StringBuilder): Boolean {\n        @Suppress(\"NAME_SHADOWING\")\n        var visibility = visibility\n        if (DescriptorRendererModifier.VISIBILITY !in modifiers) return false\n        if (normalizedVisibilities) {\n            visibility = visibility.normalize()\n        }\n        if (!renderDefaultVisibility && visibility == DescriptorVisibilities.DEFAULT_VISIBILITY) return false\n        builder.append(renderKeyword(visibility.internalDisplayName)).append(\" \")\n        return true\n    }\n\n    private fun renderModality(modality: Modality, builder: StringBuilder, defaultModality: Modality) {\n        if (!renderDefaultModality && modality == defaultModality) return\n        renderModifier(builder, DescriptorRendererModifier.MODALITY in modifiers, modality.name.toLowerCase())\n    }\n\n    private fun MemberDescriptor.implicitModalityWithoutExtensions(): Modality {\n        if (this is ClassDescriptor) {\n            return if (kind == ClassKind.INTERFACE) Modality.ABSTRACT else Modality.FINAL\n        }\n        val containingClassDescriptor = containingDeclaration as? ClassDescriptor ?: return Modality.FINAL\n        if (this !is CallableMemberDescriptor) return Modality.FINAL\n        if (this.overriddenDescriptors.isNotEmpty()) {\n            if (containingClassDescriptor.modality != Modality.FINAL) return Modality.OPEN\n        }\n        return if (containingClassDescriptor.kind == ClassKind.INTERFACE && this.visibility != DescriptorVisibilities.PRIVATE) {\n            if (this.modality == Modality.ABSTRACT) Modality.ABSTRACT else Modality.OPEN\n        } else\n            Modality.FINAL\n    }\n\n    private fun renderModalityForCallable(callable: CallableMemberDescriptor, builder: StringBuilder) {\n        if (!DescriptorUtils.isTopLevelDeclaration(callable) || callable.modality != Modality.FINAL) {\n            if (overrideRenderingPolicy == OverrideRenderingPolicy.RENDER_OVERRIDE && callable.modality == Modality.OPEN &&\n                overridesSomething(callable)\n            ) {\n                return\n            }\n            renderModality(callable.modality, builder, callable.implicitModalityWithoutExtensions())\n        }\n    }\n\n    private fun renderOverride(callableMember: CallableMemberDescriptor, builder: StringBuilder) {\n        if (DescriptorRendererModifier.OVERRIDE !in modifiers) return\n        if (overridesSomething(callableMember)) {\n            if (overrideRenderingPolicy != OverrideRenderingPolicy.RENDER_OPEN) {\n                renderModifier(builder, true, \"override\")\n                if (verbose) {\n                    builder.append(\"/*\").append(callableMember.overriddenDescriptors.size).append(\"*/ \")\n                }\n            }\n        }\n    }\n\n    private fun renderMemberKind(callableMember: CallableMemberDescriptor, builder: StringBuilder) {\n        if (DescriptorRendererModifier.MEMBER_KIND !in modifiers) return\n        if (verbose && callableMember.kind != CallableMemberDescriptor.Kind.DECLARATION) {\n            builder.append(\"/*\").append(callableMember.kind.name.toLowerCase()).append(\"*/ \")\n        }\n    }\n\n    private fun renderModifier(builder: StringBuilder, value: Boolean, modifier: String) {\n        if (value) {\n            builder.append(renderKeyword(modifier))\n            builder.append(\" \")\n        }\n    }\n\n    private fun renderMemberModifiers(descriptor: MemberDescriptor, builder: StringBuilder) {\n        renderModifier(builder, descriptor.isExternal, \"external\")\n        renderModifier(builder, DescriptorRendererModifier.EXPECT in modifiers && descriptor.isExpect, \"expect\")\n        renderModifier(builder, DescriptorRendererModifier.ACTUAL in modifiers && descriptor.isActual, \"actual\")\n    }\n\n    private fun renderAdditionalModifiers(functionDescriptor: FunctionDescriptor, builder: StringBuilder) {\n        val isOperator =\n            functionDescriptor.isOperator && (functionDescriptor.overriddenDescriptors.none { it.isOperator } || alwaysRenderModifiers)\n        val isInfix =\n            functionDescriptor.isInfix && (functionDescriptor.overriddenDescriptors.none { it.isInfix } || alwaysRenderModifiers)\n\n        renderModifier(builder, functionDescriptor.isTailrec, \"tailrec\")\n        renderSuspendModifier(functionDescriptor, builder)\n        renderModifier(builder, functionDescriptor.isInline, \"inline\")\n        renderModifier(builder, isInfix, \"infix\")\n        renderModifier(builder, isOperator, \"operator\")\n    }\n\n    private fun renderSuspendModifier(functionDescriptor: FunctionDescriptor, builder: StringBuilder) {\n        renderModifier(builder, functionDescriptor.isSuspend, \"suspend\")\n    }\n\n    override fun render(declarationDescriptor: DeclarationDescriptor): String {\n        return buildString {\n            declarationDescriptor.accept(RenderDeclarationDescriptorVisitor(), this)\n\n            if (withDefinedIn) {\n                appendDefinedIn(declarationDescriptor)\n            }\n        }\n    }\n\n\n    /* TYPE PARAMETERS */\n    private fun renderTypeParameter(typeParameter: TypeParameterDescriptor, builder: StringBuilder, topLevel: Boolean) {\n        if (topLevel) {\n            builder.append(lt())\n        }\n\n        if (verbose) {\n            builder.append(\"/*\").append(typeParameter.index).append(\"*/ \")\n        }\n\n        renderModifier(builder, typeParameter.isReified, \"reified\")\n        val variance = typeParameter.variance.label\n        renderModifier(builder, variance.isNotEmpty(), variance)\n\n        builder.renderAnnotations(typeParameter)\n\n        renderName(typeParameter, builder, topLevel)\n        val upperBoundsCount = typeParameter.upperBounds.size\n        if ((upperBoundsCount > 1 && !topLevel) || upperBoundsCount == 1) {\n            val upperBound = typeParameter.upperBounds.iterator().next()\n            if (!KotlinBuiltIns.isDefaultBound(upperBound)) {\n                builder.append(\" : \").append(renderType(upperBound))\n            }\n        } else if (topLevel) {\n            var first = true\n            for (upperBound in typeParameter.upperBounds) {\n                if (KotlinBuiltIns.isDefaultBound(upperBound)) {\n                    continue\n                }\n                if (first) {\n                    builder.append(\" : \")\n                } else {\n                    builder.append(\" & \")\n                }\n                builder.append(renderType(upperBound))\n                first = false\n            }\n        } else {\n            // rendered with \"where\"\n        }\n\n        if (topLevel) {\n            builder.append(gt())\n        }\n    }\n\n    private fun renderTypeParameters(typeParameters: List<TypeParameterDescriptor>, builder: StringBuilder, withSpace: Boolean) {\n        if (withoutTypeParameters) return\n\n        if (typeParameters.isNotEmpty()) {\n            builder.append(lt())\n            renderTypeParameterList(builder, typeParameters)\n            builder.append(gt())\n            if (withSpace) {\n                builder.append(\" \")\n            }\n        }\n    }\n\n    private fun renderTypeParameterList(builder: StringBuilder, typeParameters: List<TypeParameterDescriptor>) {\n        val iterator = typeParameters.iterator()\n        while (iterator.hasNext()) {\n            val typeParameterDescriptor = iterator.next()\n            renderTypeParameter(typeParameterDescriptor, builder, false)\n            if (iterator.hasNext()) {\n                builder.append(\", \")\n            }\n        }\n    }\n\n    /* FUNCTIONS */\n    private fun renderFunction(function: FunctionDescriptor, builder: StringBuilder) {\n        if (!startFromName) {\n            if (!startFromDeclarationKeyword) {\n                builder.renderAnnotations(function)\n                renderVisibility(function.visibility, builder)\n                renderModalityForCallable(function, builder)\n\n                if (includeAdditionalModifiers) {\n                    renderMemberModifiers(function, builder)\n                }\n\n                renderOverride(function, builder)\n\n                if (includeAdditionalModifiers) {\n                    renderAdditionalModifiers(function, builder)\n                } else {\n                    renderSuspendModifier(function, builder)\n                }\n\n                renderMemberKind(function, builder)\n\n                if (verbose) {\n                    if (function.isHiddenToOvercomeSignatureClash) {\n                        builder.append(\"/*isHiddenToOvercomeSignatureClash*/ \")\n                    }\n\n                    if (function.isHiddenForResolutionEverywhereBesideSupercalls) {\n                        builder.append(\"/*isHiddenForResolutionEverywhereBesideSupercalls*/ \")\n                    }\n                }\n            }\n\n            builder.append(renderKeyword(\"fun\")).append(\" \")\n            renderTypeParameters(function.typeParameters, builder, true)\n            renderReceiver(function, builder)\n        }\n\n        renderName(function, builder, true)\n\n        renderValueParameters(function.valueParameters, function.hasSynthesizedParameterNames(), builder)\n\n        renderReceiverAfterName(function, builder)\n\n        val returnType = function.returnType\n        if (!withoutReturnType && (unitReturnType || (returnType == null || !KotlinBuiltIns.isUnit(returnType)))) {\n            builder.append(\": \").append(if (returnType == null) \"[NULL]\" else renderType(returnType))\n        }\n\n        renderWhereSuffix(function.typeParameters, builder)\n    }\n\n    private fun renderReceiverAfterName(callableDescriptor: CallableDescriptor, builder: StringBuilder) {\n        if (!receiverAfterName) return\n\n        val receiver = callableDescriptor.extensionReceiverParameter\n        if (receiver != null) {\n            builder.append(\" on \").append(renderType(receiver.type))\n        }\n    }\n\n    private fun renderReceiver(callableDescriptor: CallableDescriptor, builder: StringBuilder) {\n        val receiver = callableDescriptor.extensionReceiverParameter\n        if (receiver != null) {\n            builder.renderAnnotations(receiver, AnnotationUseSiteTarget.RECEIVER)\n\n            val type = receiver.type\n            var result = renderType(type)\n            if (shouldRenderAsPrettyFunctionType(type) && !TypeUtils.isNullableType(type)) {\n                result = \"($result)\"\n            }\n            builder.append(result).append(\".\")\n        }\n    }\n\n    private fun renderConstructor(constructor: ConstructorDescriptor, builder: StringBuilder) {\n        builder.renderAnnotations(constructor)\n        val visibilityRendered = (options.renderDefaultVisibility || constructor.constructedClass.modality != Modality.SEALED)\n                && renderVisibility(constructor.visibility, builder)\n        renderMemberKind(constructor, builder)\n\n        val constructorKeywordRendered = renderConstructorKeyword || !constructor.isPrimary || visibilityRendered\n        if (constructorKeywordRendered) {\n            builder.append(renderKeyword(\"constructor\"))\n        }\n        val classDescriptor = constructor.containingDeclaration\n        if (secondaryConstructorsAsPrimary) {\n            if (constructorKeywordRendered) {\n                builder.append(\" \")\n            }\n            renderName(classDescriptor, builder, true)\n            renderTypeParameters(constructor.typeParameters, builder, false)\n        }\n\n        renderValueParameters(constructor.valueParameters, constructor.hasSynthesizedParameterNames(), builder)\n\n        if (renderConstructorDelegation && !constructor.isPrimary && classDescriptor is ClassDescriptor) {\n            val primaryConstructor = classDescriptor.unsubstitutedPrimaryConstructor\n            if (primaryConstructor != null) {\n                val parametersWithoutDefault = primaryConstructor.valueParameters.filter {\n                    !it.declaresDefaultValue() && it.varargElementType == null\n                }\n                if (parametersWithoutDefault.isNotEmpty()) {\n                    builder.append(\" : \").append(renderKeyword(\"this\"))\n                    builder.append(parametersWithoutDefault.joinToString(prefix = \"(\", postfix = \")\", separator = \", \") { \"\" })\n                }\n            }\n        }\n\n        if (secondaryConstructorsAsPrimary) {\n            renderWhereSuffix(constructor.typeParameters, builder)\n        }\n    }\n\n    private fun renderWhereSuffix(typeParameters: List<TypeParameterDescriptor>, builder: StringBuilder) {\n        if (withoutTypeParameters) return\n\n        val upperBoundStrings = ArrayList<String>(0)\n\n        for (typeParameter in typeParameters) {\n            typeParameter.upperBounds\n                .drop(1) // first parameter is rendered by renderTypeParameter\n                .mapTo(upperBoundStrings) { renderName(typeParameter.name, false) + \" : \" + renderType(it) }\n        }\n\n        if (upperBoundStrings.isNotEmpty()) {\n            builder.append(\" \").append(renderKeyword(\"where\")).append(\" \")\n            upperBoundStrings.joinTo(builder, \", \")\n        }\n    }\n\n    override fun renderValueParameters(parameters: Collection<ValueParameterDescriptor>, synthesizedParameterNames: Boolean) = buildString {\n        renderValueParameters(parameters, synthesizedParameterNames, this)\n    }\n\n    private fun renderValueParameters(\n        parameters: Collection<ValueParameterDescriptor>,\n        synthesizedParameterNames: Boolean,\n        builder: StringBuilder\n    ) {\n        val includeNames = shouldRenderParameterNames(synthesizedParameterNames)\n        val parameterCount = parameters.size\n        valueParametersHandler.appendBeforeValueParameters(parameterCount, builder)\n        for ((index, parameter) in parameters.withIndex()) {\n            valueParametersHandler.appendBeforeValueParameter(parameter, index, parameterCount, builder)\n            renderValueParameter(parameter, includeNames, builder, false)\n            valueParametersHandler.appendAfterValueParameter(parameter, index, parameterCount, builder)\n        }\n        valueParametersHandler.appendAfterValueParameters(parameterCount, builder)\n    }\n\n    private fun shouldRenderParameterNames(synthesizedParameterNames: Boolean): Boolean = when (parameterNameRenderingPolicy) {\n        ParameterNameRenderingPolicy.ALL -> true\n        ParameterNameRenderingPolicy.ONLY_NON_SYNTHESIZED -> !synthesizedParameterNames\n        ParameterNameRenderingPolicy.NONE -> false\n    }\n\n    /* VARIABLES */\n    private fun renderValueParameter(\n        valueParameter: ValueParameterDescriptor,\n        includeName: Boolean,\n        builder: StringBuilder,\n        topLevel: Boolean\n    ) {\n        if (topLevel) {\n            builder.append(renderKeyword(\"value-parameter\")).append(\" \")\n        }\n\n        if (verbose) {\n            builder.append(\"/*\").append(valueParameter.index).append(\"*/ \")\n        }\n\n        builder.renderAnnotations(valueParameter)\n        renderModifier(builder, valueParameter.isCrossinline, \"crossinline\")\n        renderModifier(builder, valueParameter.isNoinline, \"noinline\")\n\n        val isPrimaryConstructor = renderPrimaryConstructorParametersAsProperties &&\n                (valueParameter.containingDeclaration as? ClassConstructorDescriptor)?.isPrimary == true\n        if (isPrimaryConstructor) {\n            renderModifier(builder, actualPropertiesInPrimaryConstructor, \"actual\")\n        }\n\n        renderVariable(valueParameter, includeName, builder, topLevel, isPrimaryConstructor)\n\n        val withDefaultValue =\n            defaultParameterValueRenderer != null &&\n                    (if (debugMode) valueParameter.declaresDefaultValue() else valueParameter.declaresOrInheritsDefaultValue())\n        if (withDefaultValue) {\n            builder.append(\" = ${defaultParameterValueRenderer!!(valueParameter)}\")\n        }\n    }\n\n    private fun renderValVarPrefix(variable: VariableDescriptor, builder: StringBuilder, isInPrimaryConstructor: Boolean = false) {\n        if (isInPrimaryConstructor || variable !is ValueParameterDescriptor) {\n            builder.append(renderKeyword(if (variable.isVar) \"var\" else \"val\")).append(\" \")\n        }\n    }\n\n    private fun renderVariable(\n        variable: VariableDescriptor,\n        includeName: Boolean,\n        builder: StringBuilder,\n        topLevel: Boolean,\n        isInPrimaryConstructor: Boolean = false\n    ) {\n        val realType = variable.type\n\n        val varargElementType = (variable as? ValueParameterDescriptor)?.varargElementType\n        val typeToRender = varargElementType ?: realType\n        renderModifier(builder, varargElementType != null, \"vararg\")\n\n        if (isInPrimaryConstructor || topLevel && !startFromName) {\n            renderValVarPrefix(variable, builder, isInPrimaryConstructor)\n        }\n\n        if (includeName) {\n            renderName(variable, builder, topLevel)\n            builder.append(\": \")\n        }\n\n        builder.append(renderType(typeToRender))\n\n        renderInitializer(variable, builder)\n\n        if (verbose && varargElementType != null) {\n            builder.append(\" /*\").append(renderType(realType)).append(\"*/\")\n        }\n    }\n\n    private fun renderProperty(property: PropertyDescriptor, builder: StringBuilder) {\n        if (!startFromName) {\n            if (!startFromDeclarationKeyword) {\n                renderPropertyAnnotations(property, builder)\n                renderVisibility(property.visibility, builder)\n                renderModifier(builder, DescriptorRendererModifier.CONST in modifiers && property.isConst, \"const\")\n                renderMemberModifiers(property, builder)\n                renderModalityForCallable(property, builder)\n                renderOverride(property, builder)\n                renderModifier(builder, DescriptorRendererModifier.LATEINIT in modifiers && property.isLateInit, \"lateinit\")\n                renderMemberKind(property, builder)\n            }\n            renderValVarPrefix(property, builder)\n            renderTypeParameters(property.typeParameters, builder, true)\n            renderReceiver(property, builder)\n        }\n\n        renderName(property, builder, true)\n        builder.append(\": \").append(renderType(property.type))\n\n        renderReceiverAfterName(property, builder)\n\n        renderInitializer(property, builder)\n\n        renderWhereSuffix(property.typeParameters, builder)\n    }\n\n    private fun renderPropertyAnnotations(property: PropertyDescriptor, builder: StringBuilder) {\n        if (DescriptorRendererModifier.ANNOTATIONS !in modifiers) return\n\n        builder.renderAnnotations(property)\n\n        property.backingField?.let { builder.renderAnnotations(it, AnnotationUseSiteTarget.FIELD) }\n        property.delegateField?.let { builder.renderAnnotations(it, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD) }\n\n        if (propertyAccessorRenderingPolicy == PropertyAccessorRenderingPolicy.NONE) {\n            property.getter?.let {\n                builder.renderAnnotations(it, AnnotationUseSiteTarget.PROPERTY_GETTER)\n            }\n            property.setter?.let { setter ->\n                setter.let {\n                    builder.renderAnnotations(it, AnnotationUseSiteTarget.PROPERTY_SETTER)\n                }\n                setter.valueParameters.single().let {\n                    builder.renderAnnotations(it, AnnotationUseSiteTarget.SETTER_PARAMETER)\n                }\n            }\n        }\n    }\n\n    private fun renderInitializer(variable: VariableDescriptor, builder: StringBuilder) {\n        if (includePropertyConstant) {\n            variable.compileTimeInitializer?.let { constant ->\n                builder.append(\" = \").append(escape(renderConstant(constant)))\n            }\n        }\n    }\n\n    private fun renderTypeAlias(typeAlias: TypeAliasDescriptor, builder: StringBuilder) {\n        builder.renderAnnotations(typeAlias)\n        renderVisibility(typeAlias.visibility, builder)\n        renderMemberModifiers(typeAlias, builder)\n        builder.append(renderKeyword(\"typealias\")).append(\" \")\n        renderName(typeAlias, builder, true)\n\n        renderTypeParameters(typeAlias.declaredTypeParameters, builder, false)\n        renderCapturedTypeParametersIfRequired(typeAlias, builder)\n\n        builder.append(\" = \").append(renderType(typeAlias.underlyingType))\n    }\n\n    private fun renderCapturedTypeParametersIfRequired(classifier: ClassifierDescriptorWithTypeParameters, builder: StringBuilder) {\n        val typeParameters = classifier.declaredTypeParameters\n        val typeConstructorParameters = classifier.typeConstructor.parameters\n\n        if (verbose && classifier.isInner && typeConstructorParameters.size > typeParameters.size) {\n            builder.append(\" /*captured type parameters: \")\n            renderTypeParameterList(builder, typeConstructorParameters.subList(typeParameters.size, typeConstructorParameters.size))\n            builder.append(\"*/\")\n        }\n    }\n\n    /* CLASSES */\n    private fun renderClass(klass: ClassDescriptor, builder: StringBuilder) {\n        val isEnumEntry = klass.kind == ClassKind.ENUM_ENTRY\n\n        if (!startFromName) {\n            builder.renderAnnotations(klass)\n            if (!isEnumEntry) {\n                renderVisibility(klass.visibility, builder)\n            }\n            if (!(klass.kind == ClassKind.INTERFACE && klass.modality == Modality.ABSTRACT ||\n                        klass.kind.isSingleton && klass.modality == Modality.FINAL)\n            ) {\n                renderModality(klass.modality, builder, klass.implicitModalityWithoutExtensions())\n            }\n            renderMemberModifiers(klass, builder)\n            renderModifier(builder, DescriptorRendererModifier.INNER in modifiers && klass.isInner, \"inner\")\n            renderModifier(builder, DescriptorRendererModifier.DATA in modifiers && klass.isData, \"data\")\n            renderModifier(builder, DescriptorRendererModifier.INLINE in modifiers && klass.isInline, \"inline\")\n            renderModifier(builder, DescriptorRendererModifier.FUN in modifiers && klass.isFun, \"fun\")\n            renderClassKindPrefix(klass, builder)\n        }\n\n        if (!isCompanionObject(klass)) {\n            if (!startFromName) renderSpaceIfNeeded(builder)\n            renderName(klass, builder, true)\n        } else {\n            renderCompanionObjectName(klass, builder)\n        }\n\n        if (isEnumEntry) return\n\n        val typeParameters = klass.declaredTypeParameters\n        renderTypeParameters(typeParameters, builder, false)\n        renderCapturedTypeParametersIfRequired(klass, builder)\n\n        if (!klass.kind.isSingleton && classWithPrimaryConstructor) {\n            val primaryConstructor = klass.unsubstitutedPrimaryConstructor\n            if (primaryConstructor != null) {\n                builder.append(\" \")\n                builder.renderAnnotations(primaryConstructor)\n                renderVisibility(primaryConstructor.visibility, builder)\n                builder.append(renderKeyword(\"constructor\"))\n                renderValueParameters(primaryConstructor.valueParameters, primaryConstructor.hasSynthesizedParameterNames(), builder)\n            }\n        }\n\n        renderSuperTypes(klass, builder)\n        renderWhereSuffix(typeParameters, builder)\n    }\n\n    private fun renderSuperTypes(klass: ClassDescriptor, builder: StringBuilder) {\n        if (withoutSuperTypes) return\n\n        if (KotlinBuiltIns.isNothing(klass.defaultType)) return\n\n        val supertypes = klass.typeConstructor.supertypes\n        if (supertypes.isEmpty() || supertypes.size == 1 && KotlinBuiltIns.isAnyOrNullableAny(supertypes.iterator().next())) return\n\n        renderSpaceIfNeeded(builder)\n        builder.append(\": \")\n        supertypes.joinTo(builder, \", \") { renderType(it) }\n    }\n\n    private fun renderClassKindPrefix(klass: ClassDescriptor, builder: StringBuilder) {\n        builder.append(renderKeyword(getClassifierKindPrefix(klass)))\n    }\n\n\n    /* OTHER */\n    private fun renderPackageView(packageView: PackageViewDescriptor, builder: StringBuilder) {\n        renderPackageHeader(packageView.fqName, \"package\", builder)\n        if (debugMode) {\n            builder.append(\" in context of \")\n            renderName(packageView.module, builder, false)\n        }\n    }\n\n    private fun renderPackageFragment(fragment: PackageFragmentDescriptor, builder: StringBuilder) {\n        renderPackageHeader(fragment.fqName, \"package-fragment\", builder)\n        if (debugMode) {\n            builder.append(\" in \")\n            renderName(fragment.containingDeclaration, builder, false)\n        }\n    }\n\n    private fun renderPackageHeader(fqName: FqName, fragmentOrView: String, builder: StringBuilder) {\n        builder.append(renderKeyword(fragmentOrView))\n        val fqNameString = renderFqName(fqName.toUnsafe())\n        if (fqNameString.isNotEmpty()) {\n            builder.append(\" \")\n            builder.append(fqNameString)\n        }\n    }\n\n    private fun renderAccessorModifiers(descriptor: PropertyAccessorDescriptor, builder: StringBuilder) {\n        renderMemberModifiers(descriptor, builder)\n    }\n\n    /* STUPID DISPATCH-ONLY VISITOR */\n    private inner class RenderDeclarationDescriptorVisitor : DeclarationDescriptorVisitor<Unit, StringBuilder> {\n        override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor, builder: StringBuilder) {\n            renderValueParameter(descriptor, true, builder, true)\n        }\n\n        override fun visitVariableDescriptor(descriptor: VariableDescriptor, builder: StringBuilder) {\n            renderVariable(descriptor, true, builder, true)\n        }\n\n        override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, builder: StringBuilder) {\n            renderProperty(descriptor, builder)\n        }\n\n        override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, builder: StringBuilder) {\n            visitPropertyAccessorDescriptor(descriptor, builder, \"getter\")\n        }\n\n        override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, builder: StringBuilder) {\n            visitPropertyAccessorDescriptor(descriptor, builder, \"setter\")\n        }\n\n        private fun visitPropertyAccessorDescriptor(descriptor: PropertyAccessorDescriptor, builder: StringBuilder, kind: String) {\n            when (propertyAccessorRenderingPolicy) {\n                PropertyAccessorRenderingPolicy.PRETTY -> {\n                    renderAccessorModifiers(descriptor, builder)\n                    builder.append(\"$kind for \")\n                    renderProperty(descriptor.correspondingProperty, builder)\n                }\n                PropertyAccessorRenderingPolicy.DEBUG -> {\n                    visitFunctionDescriptor(descriptor, builder)\n                }\n                PropertyAccessorRenderingPolicy.NONE -> {\n                }\n            }\n        }\n\n        override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, builder: StringBuilder) {\n            renderFunction(descriptor, builder)\n        }\n\n        override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor, builder: StringBuilder) {\n            builder.append(descriptor.name) // renders <this>\n        }\n\n        override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, builder: StringBuilder) {\n            renderConstructor(constructorDescriptor, builder)\n        }\n\n        override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor, builder: StringBuilder) {\n            renderTypeParameter(descriptor, builder, true)\n        }\n\n        override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, builder: StringBuilder) {\n            renderPackageFragment(descriptor, builder)\n        }\n\n        override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor, builder: StringBuilder) {\n            renderPackageView(descriptor, builder)\n        }\n\n        override fun visitModuleDeclaration(descriptor: ModuleDescriptor, builder: StringBuilder) {\n            renderName(descriptor, builder, true)\n        }\n\n        override fun visitScriptDescriptor(scriptDescriptor: ScriptDescriptor, builder: StringBuilder) {\n            visitClassDescriptor(scriptDescriptor, builder)\n        }\n\n        override fun visitClassDescriptor(descriptor: ClassDescriptor, builder: StringBuilder) {\n            renderClass(descriptor, builder)\n        }\n\n        override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, builder: StringBuilder) {\n            renderTypeAlias(descriptor, builder)\n        }\n    }\n\n    private fun renderSpaceIfNeeded(builder: StringBuilder) {\n        val length = builder.length\n        if (length == 0 || builder[length - 1] != ' ') {\n            builder.append(' ')\n        }\n    }\n\n    private fun replacePrefixes(\n        lowerRendered: String,\n        lowerPrefix: String,\n        upperRendered: String,\n        upperPrefix: String,\n        foldedPrefix: String\n    ): String? {\n        if (lowerRendered.startsWith(lowerPrefix) && upperRendered.startsWith(upperPrefix)) {\n            val lowerWithoutPrefix = lowerRendered.substring(lowerPrefix.length)\n            val upperWithoutPrefix = upperRendered.substring(upperPrefix.length)\n            val flexibleCollectionName = foldedPrefix + lowerWithoutPrefix\n\n            if (lowerWithoutPrefix == upperWithoutPrefix) return flexibleCollectionName\n\n            if (differsOnlyInNullability(lowerWithoutPrefix, upperWithoutPrefix)) {\n                return \"$flexibleCollectionName!\"\n            }\n        }\n        return null\n    }\n\n    private fun differsOnlyInNullability(lower: String, upper: String) =\n        lower == upper.replace(\"?\", \"\") || upper.endsWith(\"?\") && (\"$lower?\") == upper || \"($lower)?\" == upper\n\n    private fun overridesSomething(callable: CallableMemberDescriptor) = !callable.overriddenDescriptors.isEmpty()\n}\n"
  },
  {
    "path": "misc/packcc/build/clang/Makefile",
    "content": "CC=clang\nCFLAGS_D=-std=gnu89 -fsigned-char -Wall -Wextra -Wno-unused-parameter -Wno-overlength-strings -pedantic -O0 -g2\nCFLAGS_R=-std=gnu89 -fsigned-char -Wall -Wextra -Wno-unused-parameter -Wno-overlength-strings -pedantic -O2 -DNDEBUG\nLDFLAGS_D=\nLDFLAGS_R=\n\nROOTDIR=../..\nSRCDIR=$(ROOTDIR)/src\nTESTDIR=$(ROOTDIR)/tests\nEXDIR=$(ROOTDIR)/examples\nTMPDIR_D=debug/tmp\nTMPDIR_R=release/tmp\nBINDIR_D=debug/bin\nBINDIR_R=release/bin\n\nEXAMPLES:=$(patsubst $(EXDIR)/%.peg,examples/%,$(wildcard $(EXDIR)/*.peg))\n\nBINS= \\\n  $(BINDIR_D)/packcc \\\n  $(BINDIR_R)/packcc \\\n  $(patsubst %,$(BINDIR_D)/%,$(EXAMPLES)) \\\n  $(patsubst %,$(BINDIR_R)/%,$(EXAMPLES))\nSRCS= \\\n  $(patsubst %,$(TMPDIR_D)/%.c,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_D)/%.h,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_R)/%.c,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_R)/%.h,$(EXAMPLES))\n\n.PHONY: all check clean\n\n.SECONDARY: $(SRCS)\n\nall: $(BINS)\n\n$(BINDIR_D)/packcc: $(SRCDIR)/packcc.c\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -o $@ $< $(LDFLAGS_D)\n\n$(BINDIR_R)/packcc: $(SRCDIR)/packcc.c\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -o $@ $< $(LDFLAGS_R)\n\n$(BINDIR_D)/examples/%: $(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -I. -o $@ $< $(LDFLAGS_D)\n\n$(BINDIR_R)/examples/%: $(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -I. -o $@ $< $(LDFLAGS_R)\n\n$(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h: $(EXDIR)/%.peg $(BINDIR_D)/packcc\n\tmkdir -p $(dir $@) && $(BINDIR_D)/packcc -o $(basename $@) $<\n\n$(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h: $(EXDIR)/%.peg $(BINDIR_R)/packcc\n\tmkdir -p $(dir $@) && $(BINDIR_R)/packcc -o $(basename $@) $<\n\ncheck: $(BINDIR_D)/packcc $(BINDIR_R)/packcc\n\t@echo \"== Debug Version ==\"   && PACKCC=$$PWD/$(BINDIR_D)/packcc CC=\"$(CC) $(CFLAGS_D)\" $(TESTDIR)/test.sh\n\t@echo \"== Release Version ==\" && PACKCC=$$PWD/$(BINDIR_R)/packcc CC=\"$(CC) $(CFLAGS_R)\" $(TESTDIR)/test.sh\n\nclean:\n\trm -f $(BINS) $(SRCS)\n"
  },
  {
    "path": "misc/packcc/build/gcc/Makefile",
    "content": "CC=gcc\nCFLAGS_D=-std=gnu89 -fsigned-char -Wall -Wextra -Wno-unused-parameter -Wno-overlength-strings -pedantic -O0 -g2\nCFLAGS_R=-std=gnu89 -fsigned-char -Wall -Wextra -Wno-unused-parameter -Wno-overlength-strings -pedantic -O2 -DNDEBUG\nLDFLAGS_D=\nLDFLAGS_R=\n\nROOTDIR=../..\nSRCDIR=$(ROOTDIR)/src\nTESTDIR=$(ROOTDIR)/tests\nEXDIR=$(ROOTDIR)/examples\nTMPDIR_D=debug/tmp\nTMPDIR_R=release/tmp\nBINDIR_D=debug/bin\nBINDIR_R=release/bin\n\nEXAMPLES:=$(patsubst $(EXDIR)/%.peg,examples/%,$(wildcard $(EXDIR)/*.peg))\n\nBINS= \\\n  $(BINDIR_D)/packcc \\\n  $(BINDIR_R)/packcc \\\n  $(patsubst %,$(BINDIR_D)/%,$(EXAMPLES)) \\\n  $(patsubst %,$(BINDIR_R)/%,$(EXAMPLES))\nSRCS= \\\n  $(patsubst %,$(TMPDIR_D)/%.c,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_D)/%.h,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_R)/%.c,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_R)/%.h,$(EXAMPLES))\n\n.PHONY: all check clean\n\n.SECONDARY: $(SRCS)\n\nall: $(BINS)\n\n$(BINDIR_D)/packcc: $(SRCDIR)/packcc.c\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -o $@ $< $(LDFLAGS_D)\n\n$(BINDIR_R)/packcc: $(SRCDIR)/packcc.c\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -o $@ $< $(LDFLAGS_R)\n\n$(BINDIR_D)/examples/%: $(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -I. -o $@ $< $(LDFLAGS_D)\n\n$(BINDIR_R)/examples/%: $(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -I. -o $@ $< $(LDFLAGS_R)\n\n$(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h: $(EXDIR)/%.peg $(BINDIR_D)/packcc\n\tmkdir -p $(dir $@) && $(BINDIR_D)/packcc -o $(basename $@) $<\n\n$(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h: $(EXDIR)/%.peg $(BINDIR_R)/packcc\n\tmkdir -p $(dir $@) && $(BINDIR_R)/packcc -o $(basename $@) $<\n\ncheck: $(BINDIR_D)/packcc $(BINDIR_R)/packcc\n\t@echo \"== Debug Version ==\"   && PACKCC=$$PWD/$(BINDIR_D)/packcc CC=\"$(CC) $(CFLAGS_D)\" $(TESTDIR)/test.sh\n\t@echo \"== Release Version ==\" && PACKCC=$$PWD/$(BINDIR_R)/packcc CC=\"$(CC) $(CFLAGS_R)\" $(TESTDIR)/test.sh\n\nclean:\n\trm -f $(BINS) $(SRCS)\n"
  },
  {
    "path": "misc/packcc/build/mingw-clang/Makefile",
    "content": "CC=clang\nCFLAGS_D=-std=gnu89 -Wall -Wextra -Wno-unused-parameter -Wno-overlength-strings -Wno-long-long -Wno-format -pedantic -O0 -g2\nCFLAGS_R=-std=gnu89 -Wall -Wextra -Wno-unused-parameter -Wno-overlength-strings -Wno-long-long -Wno-format -pedantic -O2 -DNDEBUG\nLDFLAGS_D=\nLDFLAGS_R=\n\nROOTDIR=../..\nSRCDIR=$(ROOTDIR)/src\nTESTDIR=$(ROOTDIR)/tests\nEXDIR=$(ROOTDIR)/examples\nTMPDIR_D=debug/tmp\nTMPDIR_R=release/tmp\nBINDIR_D=debug/bin\nBINDIR_R=release/bin\n\nEXAMPLES:=$(patsubst $(EXDIR)/%.peg,examples/%,$(wildcard $(EXDIR)/*.peg))\n\nBINS= \\\n  $(BINDIR_D)/packcc \\\n  $(BINDIR_R)/packcc \\\n  $(patsubst %,$(BINDIR_D)/%,$(EXAMPLES)) \\\n  $(patsubst %,$(BINDIR_R)/%,$(EXAMPLES))\nSRCS= \\\n  $(patsubst %,$(TMPDIR_D)/%.c,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_D)/%.h,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_R)/%.c,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_R)/%.h,$(EXAMPLES))\n\n.PHONY: all check clean\n\n.SECONDARY: $(SRCS)\n\nall: $(BINS)\n\n$(BINDIR_D)/packcc: $(SRCDIR)/packcc.c\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -o $@ $< $(LDFLAGS_D)\n\n$(BINDIR_R)/packcc: $(SRCDIR)/packcc.c\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -o $@ $< $(LDFLAGS_R)\n\n$(BINDIR_D)/examples/%: $(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -I. -o $@ $< $(LDFLAGS_D)\n\n$(BINDIR_R)/examples/%: $(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -I. -o $@ $< $(LDFLAGS_R)\n\n$(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h: $(EXDIR)/%.peg $(BINDIR_D)/packcc\n\tmkdir -p $(dir $@) && $(BINDIR_D)/packcc -o $(basename $@) $<\n\n$(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h: $(EXDIR)/%.peg $(BINDIR_R)/packcc\n\tmkdir -p $(dir $@) && $(BINDIR_R)/packcc -o $(basename $@) $<\n\ncheck: $(BINDIR_D)/packcc $(BINDIR_R)/packcc\n\t@echo \"== Debug Version ==\"   && PACKCC=$$PWD/$(BINDIR_D)/packcc CC=\"$(CC) $(CFLAGS_D)\" $(TESTDIR)/test.sh\n\t@echo \"== Release Version ==\" && PACKCC=$$PWD/$(BINDIR_R)/packcc CC=\"$(CC) $(CFLAGS_R)\" $(TESTDIR)/test.sh\n\nclean:\n\trm -f $(BINS) $(SRCS)\n"
  },
  {
    "path": "misc/packcc/build/mingw-gcc/Makefile",
    "content": "CC=gcc\nCFLAGS_D=-std=gnu89 -Wall -Wextra -Wno-unused-parameter -Wno-overlength-strings -Wno-long-long -Wno-format -pedantic -O0 -g2\nCFLAGS_R=-std=gnu89 -Wall -Wextra -Wno-unused-parameter -Wno-overlength-strings -Wno-long-long -Wno-format -pedantic -O2 -DNDEBUG\nLDFLAGS_D=\nLDFLAGS_R=\n\nROOTDIR=../..\nSRCDIR=$(ROOTDIR)/src\nTESTDIR=$(ROOTDIR)/tests\nEXDIR=$(ROOTDIR)/examples\nTMPDIR_D=debug/tmp\nTMPDIR_R=release/tmp\nBINDIR_D=debug/bin\nBINDIR_R=release/bin\n\nEXAMPLES:=$(patsubst $(EXDIR)/%.peg,examples/%,$(wildcard $(EXDIR)/*.peg))\n\nBINS= \\\n  $(BINDIR_D)/packcc \\\n  $(BINDIR_R)/packcc \\\n  $(patsubst %,$(BINDIR_D)/%,$(EXAMPLES)) \\\n  $(patsubst %,$(BINDIR_R)/%,$(EXAMPLES))\nSRCS= \\\n  $(patsubst %,$(TMPDIR_D)/%.c,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_D)/%.h,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_R)/%.c,$(EXAMPLES)) \\\n  $(patsubst %,$(TMPDIR_R)/%.h,$(EXAMPLES))\n\n.PHONY: all check clean\n\n.SECONDARY: $(SRCS)\n\nall: $(BINS)\n\n$(BINDIR_D)/packcc: $(SRCDIR)/packcc.c\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -o $@ $< $(LDFLAGS_D)\n\n$(BINDIR_R)/packcc: $(SRCDIR)/packcc.c\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -o $@ $< $(LDFLAGS_R)\n\n$(BINDIR_D)/examples/%: $(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_D) -I. -o $@ $< $(LDFLAGS_D)\n\n$(BINDIR_R)/examples/%: $(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h\n\tmkdir -p $(dir $@) && $(CC) $(CFLAGS_R) -I. -o $@ $< $(LDFLAGS_R)\n\n$(TMPDIR_D)/examples/%.c $(TMPDIR_D)/examples/%.h: $(EXDIR)/%.peg $(BINDIR_D)/packcc\n\tmkdir -p $(dir $@) && $(BINDIR_D)/packcc -o $(basename $@) $<\n\n$(TMPDIR_R)/examples/%.c $(TMPDIR_R)/examples/%.h: $(EXDIR)/%.peg $(BINDIR_R)/packcc\n\tmkdir -p $(dir $@) && $(BINDIR_R)/packcc -o $(basename $@) $<\n\ncheck: $(BINDIR_D)/packcc $(BINDIR_R)/packcc\n\t@echo \"== Debug Version ==\"   && PACKCC=$$PWD/$(BINDIR_D)/packcc CC=\"$(CC) $(CFLAGS_D)\" $(TESTDIR)/test.sh\n\t@echo \"== Release Version ==\" && PACKCC=$$PWD/$(BINDIR_R)/packcc CC=\"$(CC) $(CFLAGS_R)\" $(TESTDIR)/test.sh\n\nclean:\n\trm -f $(BINS) $(SRCS)\n"
  },
  {
    "path": "misc/packcc/build/msvc/examples/calc/calc.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <CustomBuild Include=\"..\\..\\..\\..\\examples\\calc.peg\">\r\n      <FileType>Document</FileType>\r\n      <Outputs Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(ProjectDir)tmp\\$(PlatformTarget)\\$(Configuration)\\%(Filename).c;%(Outputs)</Outputs>\r\n      <LinkObjects Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</LinkObjects>\r\n      <OutputItemType Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">ClCompile</OutputItemType>\r\n      <TreatOutputAsContent Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</TreatOutputAsContent>\r\n      <Outputs Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(ProjectDir)tmp\\$(PlatformTarget)\\$(Configuration)\\%(Filename).c;%(Outputs)</Outputs>\r\n      <LinkObjects Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkObjects>\r\n      <OutputItemType Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">ClCompile</OutputItemType>\r\n      <TreatOutputAsContent Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">true</TreatOutputAsContent>\r\n      <Outputs Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(ProjectDir)tmp\\$(PlatformTarget)\\$(Configuration)\\%(Filename).c;%(Outputs)</Outputs>\r\n      <LinkObjects Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</LinkObjects>\r\n      <OutputItemType Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">ClCompile</OutputItemType>\r\n      <TreatOutputAsContent Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</TreatOutputAsContent>\r\n      <Outputs Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(ProjectDir)tmp\\$(PlatformTarget)\\$(Configuration)\\%(Filename).c;%(Outputs)</Outputs>\r\n      <LinkObjects Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkObjects>\r\n      <OutputItemType Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">ClCompile</OutputItemType>\r\n      <TreatOutputAsContent Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">true</TreatOutputAsContent>\r\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</ExcludedFromBuild>\r\n      <DeploymentContent Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</DeploymentContent>\r\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</ExcludedFromBuild>\r\n      <DeploymentContent Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</DeploymentContent>\r\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</ExcludedFromBuild>\r\n      <DeploymentContent Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</DeploymentContent>\r\n      <ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</ExcludedFromBuild>\r\n      <DeploymentContent Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</DeploymentContent>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(SolutionDir)$(PlatformTarget)\\$(Configuration)\\packcc -o tmp\\$(PlatformTarget)\\$(Configuration)\\%(Filename) %(FullPath)</Command>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(SolutionDir)$(PlatformTarget)\\$(Configuration)\\packcc -o tmp\\$(PlatformTarget)\\$(Configuration)\\%(Filename) %(FullPath)</Command>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(SolutionDir)$(PlatformTarget)\\$(Configuration)\\packcc -o tmp\\$(PlatformTarget)\\$(Configuration)\\%(Filename) %(FullPath)</Command>\r\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">$(SolutionDir)$(PlatformTarget)\\$(Configuration)\\packcc -o tmp\\$(PlatformTarget)\\$(Configuration)\\%(Filename) %(FullPath)</Command>\r\n    </CustomBuild>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Globals\">\r\n    <VCProjectVersion>16.0</VCProjectVersion>\r\n    <ProjectGuid>{5EB5881F-0182-4E32-A3E8-6940E5016770}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>calc</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\r\n    <ProjectName>calc</ProjectName>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(ProjectDir)$(PlatformTarget)\\$(Configuration)\\</OutDir>\r\n    <IntDir>$(PlatformTarget)\\$(Configuration)\\</IntDir>\r\n    <TargetName>$(ProjectName)</TargetName>\r\n    <IncludePath>.\\;$(IncludePath)</IncludePath>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(ProjectDir)$(PlatformTarget)\\$(Configuration)\\</OutDir>\r\n    <IntDir>$(PlatformTarget)\\$(Configuration)\\</IntDir>\r\n    <TargetName>$(ProjectName)</TargetName>\r\n    <IncludePath>.\\;$(IncludePath)</IncludePath>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(ProjectDir)$(PlatformTarget)\\$(Configuration)\\</OutDir>\r\n    <IntDir>$(PlatformTarget)\\$(Configuration)\\</IntDir>\r\n    <TargetName>$(ProjectName)</TargetName>\r\n    <IncludePath>.\\;$(IncludePath)</IncludePath>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(ProjectDir)$(PlatformTarget)\\$(Configuration)\\</OutDir>\r\n    <IntDir>$(PlatformTarget)\\$(Configuration)\\</IntDir>\r\n    <TargetName>$(ProjectName)</TargetName>\r\n    <IncludePath>.\\;$(IncludePath)</IncludePath>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <DisableSpecificWarnings>4090;4100;4456;26450;26451</DisableSpecificWarnings>\r\n      <Optimization>Disabled</Optimization>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <DisableSpecificWarnings>4090;4100;4456;26450;26451</DisableSpecificWarnings>\r\n      <Optimization>Disabled</Optimization>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n    <PreBuildEvent>\r\n      <Command>\r\n      </Command>\r\n    </PreBuildEvent>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <DisableSpecificWarnings>4090;4100;4456;26450;26451</DisableSpecificWarnings>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <DisableSpecificWarnings>4090;4100;4456;26450;26451</DisableSpecificWarnings>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n</Project>"
  },
  {
    "path": "misc/packcc/build/msvc/examples/calc/calc.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <CustomBuild Include=\"..\\..\\..\\..\\examples\\calc.peg\">\r\n      <Filter>Source Files</Filter>\r\n    </CustomBuild>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "misc/packcc/build/msvc/examples/calc/calc.vcxproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"Current\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup />\r\n</Project>"
  },
  {
    "path": "misc/packcc/build/msvc/msvc.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 16\r\nVisualStudioVersion = 16.0.29209.62\r\nMinimumVisualStudioVersion = 10.0.40219.1\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"packcc\", \"packcc.vcxproj\", \"{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}\"\r\nEndProject\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"calc\", \"examples\\calc\\calc.vcxproj\", \"{5EB5881F-0182-4E32-A3E8-6940E5016770}\"\r\n\tProjectSection(ProjectDependencies) = postProject\r\n\t\t{9A1A5538-7127-4B2F-9C82-3282A69F3C9C} = {9A1A5538-7127-4B2F-9C82-3282A69F3C9C}\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"examples\", \"examples\", \"{16C15CF5-EA71-4DEB-A758-CC52E0CA2558}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|x64 = Debug|x64\r\n\t\tDebug|x86 = Debug|x86\r\n\t\tRelease|x64 = Release|x64\r\n\t\tRelease|x86 = Release|x86\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Release|x64.Build.0 = Release|x64\r\n\t\t{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}.Release|x86.Build.0 = Release|Win32\r\n\t\t{5EB5881F-0182-4E32-A3E8-6940E5016770}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{5EB5881F-0182-4E32-A3E8-6940E5016770}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{5EB5881F-0182-4E32-A3E8-6940E5016770}.Debug|x86.ActiveCfg = Debug|Win32\r\n\t\t{5EB5881F-0182-4E32-A3E8-6940E5016770}.Debug|x86.Build.0 = Debug|Win32\r\n\t\t{5EB5881F-0182-4E32-A3E8-6940E5016770}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{5EB5881F-0182-4E32-A3E8-6940E5016770}.Release|x64.Build.0 = Release|x64\r\n\t\t{5EB5881F-0182-4E32-A3E8-6940E5016770}.Release|x86.ActiveCfg = Release|Win32\r\n\t\t{5EB5881F-0182-4E32-A3E8-6940E5016770}.Release|x86.Build.0 = Release|Win32\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\n\tGlobalSection(NestedProjects) = preSolution\r\n\t\t{5EB5881F-0182-4E32-A3E8-6940E5016770} = {16C15CF5-EA71-4DEB-A758-CC52E0CA2558}\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n\t\tSolutionGuid = {BD6C24C6-47A2-40C5-87E8-F72C92F9D5FF}\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "misc/packcc/build/msvc/packcc.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Globals\">\r\n    <VCProjectVersion>16.0</VCProjectVersion>\r\n    <ProjectGuid>{9A1A5538-7127-4B2F-9C82-3282A69F3C9C}</ProjectGuid>\r\n    <Keyword>Win32Proj</Keyword>\r\n    <RootNamespace>packcc</RootNamespace>\r\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>true</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <UseDebugLibraries>false</UseDebugLibraries>\r\n    <PlatformToolset>v142</PlatformToolset>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"Shared\">\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(PlatformTarget)\\$(Configuration)\\</OutDir>\r\n    <IntDir>$(PlatformTarget)\\$(Configuration)\\</IntDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <LinkIncremental>true</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(PlatformTarget)\\$(Configuration)\\</OutDir>\r\n    <IntDir>$(PlatformTarget)\\$(Configuration)\\</IntDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(PlatformTarget)\\$(Configuration)\\</OutDir>\r\n    <IntDir>$(PlatformTarget)\\$(Configuration)\\</IntDir>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <LinkIncremental>false</LinkIncremental>\r\n    <OutDir>$(SolutionDir)$(PlatformTarget)\\$(Configuration)\\</OutDir>\r\n    <IntDir>$(PlatformTarget)\\$(Configuration)\\</IntDir>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <DisableSpecificWarnings>4090;4100;4456;26450;26451</DisableSpecificWarnings>\r\n      <Optimization>Disabled</Optimization>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r\n      <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <DisableSpecificWarnings>4090;4100;4456;26450;26451</DisableSpecificWarnings>\r\n      <Optimization>Disabled</Optimization>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r\n      <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <DisableSpecificWarnings>4090;4100;4456;26450;26451</DisableSpecificWarnings>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r\n      <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <ClCompile>\r\n      <WarningLevel>Level4</WarningLevel>\r\n      <DisableSpecificWarnings>4090;4100;4456;26450;26451</DisableSpecificWarnings>\r\n      <Optimization>MaxSpeed</Optimization>\r\n      <FunctionLevelLinking>true</FunctionLevelLinking>\r\n      <IntrinsicFunctions>true</IntrinsicFunctions>\r\n      <SDLCheck>true</SDLCheck>\r\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <ConformanceMode>true</ConformanceMode>\r\n      <DisableLanguageExtensions>true</DisableLanguageExtensions>\r\n      <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>\r\n    </ClCompile>\r\n    <Link>\r\n      <SubSystem>Console</SubSystem>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"..\\..\\src\\packcc.c\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n</Project>"
  },
  {
    "path": "misc/packcc/build/msvc/packcc.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"..\\..\\src\\packcc.c\">\r\n      <Filter>Source Files</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "misc/packcc/build/msvc/packcc.vcxproj.user",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"Current\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup />\r\n</Project>"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/.gitignore",
    "content": "/build/\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.2)\n\nproject(ast)\n\nset(PACKCC packcc CACHE FILEPATH \"Specify file path of packcc command.\")\n\nadd_custom_command(\n    OUTPUT parser.c parser.h\n    COMMAND ${PACKCC} ARGS -o parser ${CMAKE_CURRENT_SOURCE_DIR}/parser.peg\n    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/parser.peg\n    VERBATIM\n)\n\nadd_executable(ast main.c parser.c system.c utility.c)\n\ntarget_compile_features(ast PRIVATE c_std_99)\ntarget_include_directories(ast BEFORE PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/README.md",
    "content": "# AST Builder for Tiny-C #\n\n## Overview ##\n\nThis example builds an AST (abstract syntax tree) from an input source file\nwritten in [Tiny-C](http://www.iro.umontreal.ca/~felipe/IFT2030-Automne2002/Complements/tinyc.c) with some extension shown below,\nand prints the AST in the standard output.\nIf there are syntax errors, it shows them with line and column numbers.\n\n__Extension:__\n- Supports all arithmetic, logical and bitwise operators,\n- Accepts octal and hexadecimal integers,\n- Permits uppercase letters, number letters, and underscores in an identifier,\n- Accepts `'\\v'` and `'\\f'` as white-spaces,\n- Supports comment blocks.\n\nThis example is placed in the public domain!\nSo, you can use it freely without noticing the copyright of the original author.\n\n## How to compile this example ##\n\n### For Unix-like OS ###\n\nYou can get the executable by executing the following commands:\n\n```\ncd /path/to/this_directory\nmkdir build\ncd build\ncmake -DPACKCC=/path/to/packcc ..\nmake\n```\n\nHere, `/path/to/this_directory` represents the path name of this directory,\nand `/path/to/packcc` represents the path name of `packcc` command.\nIf `packcc` command is installed in one of the directories specified in the environment variable `PATH`,\nthe option `-DPACKCC=/path/to/packcc` is not necessary.\n\nThe executable `ast` will be created in the directory `build`.\n\n### For Windows ###\n\n#### Using Visual Studio ####\n\nYou must have [Build Tools for Visual Studio](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019) installed in your system.\nYou can get the executable by executing the following commands using 'Developer Command Prompt for VS 2019' or 'Developer PowerShell for VS 2019':\n\n```\ncd \\path\\to\\this_directory\nmkdir build\ncd build\ncmake -DPACKCC=\\path\\to\\packcc ..\nMSBuild ALL_BUILD.vcxproj\n```\n\nHere, `\\path\\to\\this_directory` represents the path name of this directory,\nand `\\path\\to\\packcc` represents the path name of `packcc` command.\nIf `packcc` command is installed in one of the directories specified in the environment variable `PATH`,\nthe option `-DPACKCC=\\path\\to\\packcc` is not necessary.\n\nThe executable `ast.exe` will be created in the directory `build\\Debug`.\n\n#### Using MinGW-w64 ####\n\nYou can get the executable by executing the following commands:\n\n```\ncd /path/to/this_directory\nmkdir build\ncd build\ncmake -G \"MSYS Makefiles\" -DPACKCC=/path/to/packcc ..\nmake\n```\n\nHere, `/path/to/this_directory` represents the path name of this directory,\nand `/path/to/packcc` represents the path name of `packcc` command.\nIf `packcc` command is installed in one of the directories specified in the environment variable `PATH`,\nthe option `-DPACKCC=/path/to/packcc` is not necessary.\n\nThe executable `ast.exe` will be created in the directory `build`.\n\n## How to run this example ##\n\nExample input source files are prepared in [`inputs`](inputs) directory.\nMost of these are taken from [grammars-v4](https://github.com/antlr/grammars-v4/) repository of [ANTLR project](https://github.com/antlr/) with thanks.\n\nHere, it is assumed that you are in the directory `build`.\nIf you want to print out the AST of the input source file [`inputs/example2.c`](inputs/example2.c), execute the following command:\n\n```\n./ast ../inputs/example2.c\n```\n\nYou will see the output below:\n\n```\nSTATEMENT_LIST: arity = 1\n  STATEMENT_LIST: arity = 3\n    OPERATOR_ASSIGN: arity = 2\n      IDENTIFIER: line = 2, column = 3, value = 'i'\n      INTEGER_DEC: line = 2, column = 5, value = '125'\n    OPERATOR_ASSIGN: arity = 2\n      IDENTIFIER: line = 2, column = 10, value = 'j'\n      INTEGER_DEC: line = 2, column = 12, value = '100'\n    STATEMENT_WHILE: arity = 2\n      OPERATOR_SUB: arity = 2\n        IDENTIFIER: line = 2, column = 24, value = 'i'\n        IDENTIFIER: line = 2, column = 26, value = 'j'\n      STATEMENT_IF_ELSE: arity = 3\n        OPERATOR_LT: arity = 2\n          IDENTIFIER: line = 2, column = 33, value = 'i'\n          IDENTIFIER: line = 2, column = 35, value = 'j'\n        OPERATOR_ASSIGN: arity = 2\n          IDENTIFIER: line = 2, column = 38, value = 'j'\n          OPERATOR_SUB: arity = 2\n            IDENTIFIER: line = 2, column = 40, value = 'j'\n            IDENTIFIER: line = 2, column = 42, value = 'i'\n        OPERATOR_ASSIGN: arity = 2\n          IDENTIFIER: line = 2, column = 50, value = 'i'\n          OPERATOR_SUB: arity = 2\n            IDENTIFIER: line = 2, column = 52, value = 'i'\n            IDENTIFIER: line = 2, column = 54, value = 'j'\n```\n\nIf there are errors in the input source file, this example reports up to 4 errors at a time.\nYou can see this behavior by the following command using [`inputs/erroneous1.c`](inputs/erroneous1.c):\n\n```\n./ast ../inputs/erroneous1.c\n```\n\nYou will see the error messages below:\n\n```\nERROR: line 6, column 5: Unexpected token 'do'\nERROR: line 7, column 5: Statement missing after 'do'\nERROR: line 4, column 5: 'else' without corresponding 'if'\nERROR: line 3, column 5: 'else' without corresponding 'if'\n```\n\nNote that the multiple error recognition of this example is not sophisticated.\nTo improve it, you have to design elaborate grammar rules for error skipping to detect next multiple errors naturally.\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/inputs/erroneous1.c",
    "content": "/* This code has multiple errors for testing. */\n\n    else\n    else\n    if\n    do\n    do\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/inputs/example1.c",
    "content": "/* https://github.com/antlr/grammars-v4/blob/master/tinyc/examples/example1.c */\n{ i=1; while (i<100) i=i+i; }\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/inputs/example2.c",
    "content": "/* https://github.com/antlr/grammars-v4/blob/master/tinyc/examples/example2.c */\n{ i=125; j=100; while (i-j) if (i<j) j=j-i; else i=i-j; }\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/inputs/example3.c",
    "content": "/* https://github.com/antlr/grammars-v4/blob/master/tinyc/examples/example3.c */\n{ i=1; do i=i+10; while (i<50); }\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/inputs/example4.c",
    "content": "/* https://github.com/antlr/grammars-v4/blob/master/tinyc/examples/example4.c */\n{ i=1; while ((i=i+10)<50) ; }\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/inputs/example5.c",
    "content": "/* https://github.com/antlr/grammars-v4/blob/master/tinyc/examples/example5.c */\n{ i=7; if (i<5) x=1; if (i<10) y=2; }\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/main.c",
    "content": "/*\n * This code is hereby placed in the public domain.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\n * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"system.h\"\n#include \"parser.h\"\n\n#include <stdio.h>\n\nint main(int argc, char **argv) {\n    if (argc > 2) {\n        fprintf(stderr, \"ERROR: Too many arguments\\n\");\n        return 1; /* usage error */\n    }\n    const char *path = (argc > 1) ? argv[1] : NULL;\n    int ret = 0;\n    system_t system;\n    parser_context_t *parser = NULL;\n    if (setjmp(system.jmp) == 0) {\n        system__initialize(&system);\n        system__open_source_file(&system, path);\n        parser = parser_create(&system);\n        ast_node_t *ast;\n        const int b = parser_parse(parser, &ast);\n        if (system.source.ecount > 0) longjmp(system.jmp, 1); /* never returns */\n        if (b) {\n            ret = 10; /* internal error */\n            fprintf(stderr, \"FATAL: Internal error\\n\");\n                /* <-- input text remaining due to incompleteness of the grammar */\n        }\n        else {\n            system__dump_ast(&system, ast);\n        }\n    }\n    else {\n        ret = 2; /* error during parsing */\n    }\n    parser_destroy(parser);\n    system__finalize(&system); /* all system resources are freed */\n    return ret;\n}\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/parser.peg",
    "content": "# This code is hereby placed in the public domain.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\n# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\n# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n%prefix \"parser\"\n\n%value \"ast_node_t *\"\n%auxil \"system_t *\"\n\n%header {\n#include \"system.h\"\n}\n\n%source {\n#define PCC_ERROR(auxil) system__handle_syntax_error(auxil, SYNTAX_ERROR_UNKNOWN, range__void()) /* <-- caused by incompleteness of the grammar */\n#define PCC_GETCHAR(auxil) system__read_source_file(auxil)\n#define PCC_MALLOC(auxil, size) system__allocate_memory(auxil, size)\n#define PCC_REALLOC(auxil, ptr, size) system__reallocate_memory(auxil, ptr, size)\n#define PCC_FREE(auxil, ptr) system__deallocate_memory(auxil, ptr)\n}\n\nprogram\n   <- _ l:statement_list _ end_of_file\n    {\n        $$ = l;\n    }\n    / _ end_of_file\n    {\n        $$ = system__create_ast_node_variadic(auxil, AST_NODE_TYPE_STATEMENT_LIST, range__new($0s, $0e));\n    }\n\nstatement_list\n   <- s:statement _ l:statement_list\n    {\n        $$ = l;\n        $$->range = range__new($0s, $0e);\n        ast_node__prepend_child($$, s);\n    }\n    / s:statement\n    {\n        $$ = system__create_ast_node_variadic(auxil, AST_NODE_TYPE_STATEMENT_LIST, range__new($0s, $0e));\n        ast_node__prepend_child($$, s);\n    }\n\nstatement\n   <- kw_if _ e:expression_in_parentheses _ s:statement _ kw_else _ t:statement\n    {\n        $$ = system__create_ast_node_ternary(auxil, AST_NODE_TYPE_STATEMENT_IF_ELSE, range__new($0s, $0e), e, s, t);\n    }\n    / kw_if _ e:expression_in_parentheses _ s:statement\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_STATEMENT_IF, range__new($0s, $0e), e, s);\n    }\n    / kw_while _ e:expression_in_parentheses _ s:statement\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_STATEMENT_WHILE, range__new($0s, $0e), e, s);\n    }\n    / kw_do _ s:statement _ kw_while _ e:expression_in_parentheses _ ';'\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_STATEMENT_DO_WHILE, range__new($0s, $0e), e, s);\n    }\n    / '{' _ l:statement_list _ '}'\n    {\n        $$ = l;\n    }\n    / '{' _ '}'\n    {\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_STATEMENT_VOID, range__new($0s, $0e));\n    }\n    / e:expression _ ';'\n    {\n        $$ = e;\n    }\n    / ';'\n    {\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_STATEMENT_VOID, range__new($0s, $0e));\n    }\n    ## error handling ##\n    / kw_if _ e:expression_in_parentheses _ s:statement _ kw_else\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_ELSE_WITHOUT_STATEMENT, range__new($0s, $0e));\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_ERROR_SKIP_IF_2, range__new($0s, $0e), e, s);\n    }\n    / kw_if _ e:expression_in_parentheses\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_IF_WITHOUT_STATEMENT, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP_IF_1, range__new($0s, $0e), e);\n    }\n    / kw_if\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_IF_WITHOUT_CONDITION, range__new($0s, $0e));\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_ERROR_SKIP_IF_0, range__new($0s, $0e));\n    }\n    / kw_else _ s:statement\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_LONE_ELSE, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP_ELSE_1, range__new($0s, $0e), s);\n    }\n    / kw_else\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_LONE_ELSE, range__new($0s, $0e));\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_ERROR_SKIP_ELSE_0, range__new($0s, $0e));\n    }\n    / kw_while _ e:expression_in_parentheses\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_WHILE_WITHOUT_STATEMENT, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP_WHILE_1, range__new($0s, $0e), e);\n    }\n    / kw_while\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_WHILE_WITHOUT_CONDITION, range__new($0s, $0e));\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_ERROR_SKIP_WHILE_0, range__new($0s, $0e));\n    }\n    / kw_do _ s:statement _ kw_while _ e:expression_in_parentheses\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_NO_ENDING_SEMICOLON, range__new($0s, $0e));\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_ERROR_SKIP_DO_2, range__new($0s, $0e), s, e);\n    }\n    / kw_do _ s:statement _ kw_while\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_WHILE_WITHOUT_STATEMENT, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP_DO_1, range__new($0s, $0e), s);\n    }\n    / kw_do _ s:statement\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_DO_WITHOUT_WHILE, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP_DO_1, range__new($0s, $0e), s);\n    }\n    / kw_do\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_DO_WITHOUT_STATEMENT, range__new($0s, $0e));\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_ERROR_SKIP_DO_0, range__new($0s, $0e));\n    }\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_in_parentheses\n   <- '(' _ e:expression _ ')'\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression\n   <- l:expression _ ',' _ e:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_COMMA, range__new($0s, $0e), l, e);\n    }\n    / e:expression_assignment\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_assignment\n   <- e:expression_condition _ '&=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN_AND, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition _ '|=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN_OR, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition _ '^=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN_XOR, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition _ '+=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN_ADD, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition _ '-=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN_SUB, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition _ '*=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN_MUL, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition _ '/=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN_DIV, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition _ '%=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN_MOD, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition _ '<<=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN_SHL, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition _ '>>=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN_SHR, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition _ '=' _ r:expression_assignment\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ASSIGN, range__new($0s, $0e), e, r);\n    }\n    / e:expression_condition\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_condition\n   <- e:expression_or2 _ '?' _ l:expression _ ':' _ r:expression_condition\n    {\n        $$ = system__create_ast_node_ternary(auxil, AST_NODE_TYPE_OPERATOR_COND, range__new($0s, $0e), e, l, r);\n    }\n    / e:expression_or2\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_or2\n   <- l:expression_or2 _ '||' _ e:expression_and2\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_OR2, range__new($0s, $0e), l, e);\n    }\n    / e:expression_and2\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_and2\n   <- l:expression_and2 _ '&&' _ e:expression_or\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_AND2, range__new($0s, $0e), l, e);\n    }\n    / e:expression_or\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_or\n   <- l:expression_or _ '|' _ e:expression_xor\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_OR, range__new($0s, $0e), l, e);\n    }\n    / e:expression_xor\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_xor\n   <- l:expression_xor _ '^' _ e:expression_and\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_XOR, range__new($0s, $0e), l, e);\n    }\n    / e:expression_and\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_and\n   <- l:expression_and _ '&' _ e:expression_equality\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_AND, range__new($0s, $0e), l, e);\n    }\n    / e:expression_equality\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_equality\n   <- l:expression_equality _ '==' _ e:expression_relation\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_EQ, range__new($0s, $0e), l, e);\n    }\n    / l:expression_equality _ '!=' _ e:expression_relation\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_NE, range__new($0s, $0e), l, e);\n    }\n    / e:expression_relation\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_relation\n   <- l:expression_relation _ '<=' _ e:expression_shift\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_LE, range__new($0s, $0e), l, e);\n    }\n    / l:expression_relation _ '>=' _ e:expression_shift\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_GE, range__new($0s, $0e), l, e);\n    }\n    / l:expression_relation _ '<' _ e:expression_shift\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_LT, range__new($0s, $0e), l, e);\n    }\n    / l:expression_relation _ '>' _ e:expression_shift\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_GT, range__new($0s, $0e), l, e);\n    }\n    / e:expression_shift\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_shift\n   <- l:expression_shift _ '<<' _ e:expression_addition\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_SHL, range__new($0s, $0e), l, e);\n    }\n    / l:expression_shift _ '>>' _ e:expression_addition\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_SHR, range__new($0s, $0e), l, e);\n    }\n    / e:expression_addition\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_addition\n   <- l:expression_addition _ '+' _ e:expression_multiplication\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_ADD, range__new($0s, $0e), l, e);\n    }\n    / l:expression_addition _ '-' _ e:expression_multiplication\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_SUB, range__new($0s, $0e), l, e);\n    }\n    / e:expression_multiplication\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_multiplication\n   <- l:expression_multiplication _ '*' _ e:expression_unary\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_MUL, range__new($0s, $0e), l, e);\n    }\n    / l:expression_multiplication _ '/' _ e:expression_unary\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_DIV, range__new($0s, $0e), l, e);\n    }\n    / l:expression_multiplication _ '%' _ e:expression_unary\n    {\n        $$ = system__create_ast_node_binary(auxil, AST_NODE_TYPE_OPERATOR_MOD, range__new($0s, $0e), l, e);\n    }\n    / e:expression_unary\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_unary\n   <- '++' _ e:expression_unary\n    {\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_OPERATOR_INC, range__new($0s, $0e), e);\n    }\n    / '--' _ e:expression_unary\n    {\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_OPERATOR_DEC, range__new($0s, $0e), e);\n    }\n    / '+' _ e:expression_unary\n    {\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_OPERATOR_PLUS, range__new($0s, $0e), e);\n    }\n    / '-' _ e:expression_unary\n    {\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_OPERATOR_MINUS, range__new($0s, $0e), e);\n    }\n    / '!' _ e:expression_unary\n    {\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_OPERATOR_NOT, range__new($0s, $0e), e);\n    }\n    / '~' _ e:expression_unary\n    {\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_OPERATOR_INV, range__new($0s, $0e), e);\n    }\n    / e:expression_postfix\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_postfix\n   <- e:expression_postfix _ '++'\n    {\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_OPERATOR_POST_INC, range__new($0s, $0e), e);\n    }\n    / e:expression_postfix _ '--'\n    {\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_OPERATOR_POST_DEC, range__new($0s, $0e), e);\n    }\n    / e:expression_primary\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nexpression_primary\n   <- e:identifier\n    {\n        $$ = e;\n    }\n    / e:integer\n    {\n        $$ = e;\n    }\n    / '(' _ e:expression _ ')'\n    {\n        $$ = e;\n    }\n    ## error handling ##\n    / e:error_skip\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNEXPECTED_TOKEN, range__new($0s, $0e));\n        $$ = system__create_ast_node_unary(auxil, AST_NODE_TYPE_ERROR_SKIP, range__new($0s, $0e), e);\n    }\n\nerror_skip\n   <- '{' l:statement_list '}'?\n    {\n        $$ = l;\n    }\n    / '(' e:expression ')'?\n    {\n        $$ = e;\n    }\n    / '[' e:expression ']'?\n    {\n        $$ = e;\n    }\n    / (L/D)+\n    {\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_UNEXPECTED_TOKEN, range__new($0s, $0e));\n    }\n    / !_ .\n    {\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_UNEXPECTED_TOKEN, range__new($0s, $0e));\n    }\n\nidentifier\n   <- !keyword L(L/D)*\n    {\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_IDENTIFIER, range__new($0s, $0e));\n    }\n\ninteger\n   <- '0'[xX]X+\n    {\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_INTEGER_HEX, range__new($0s, $0e));\n    }\n    / '0'O+\n    {\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_INTEGER_OCT, range__new($0s, $0e));\n    }\n    / !'0' D+\n    {\n        $$ = system__create_ast_node_terminal(auxil, AST_NODE_TYPE_INTEGER_DEC, range__new($0s, $0e));\n    }\n\nkeyword\n   <- kw_if\n    / kw_else\n    / kw_do\n    / kw_while\n\nkw_if    <- 'if'    !(L/D)\nkw_else  <- 'else'  !(L/D)\nkw_do    <- 'do'    !(L/D)\nkw_while <- 'while' !(L/D)\n\nO <- [0-7]\nD <- [0-9]\nX <- [0-9a-fA-F]\nL <- [a-zA-Z_]\n\n_ <- ( space / comment )*\ncomment\n   <- '/*' ( !'*/' . )* '*/'\n    ## error handling ##\n    / '/*' ( !'*/' . )*\n    {\n        system__handle_syntax_error(auxil, SYNTAX_ERROR_UNCLOSED_COMMENT_BLOCK, range__new($0s, $0e));\n    }\nspace <- blank / end_of_line\nblank <- [ \\t\\v\\f]\nend_of_line <- '\\r\\n' / '\\n' / '\\r'\nend_of_file <- !.\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/system.c",
    "content": "/*\n * This code is hereby placed in the public domain.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\n * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifdef _MSC_VER\n#undef _CRT_SECURE_NO_WARNINGS\n#define _CRT_SECURE_NO_WARNINGS /* suppress the warning of fopen() use */\n#endif /* _MSC_VER */\n\n#include \"system.h\"\n\n#include <stdlib.h>\n\n#ifndef ERROR_MAX\n#define ERROR_MAX 4 /* the maximum number of errors displayed at a time */\n#endif\n\nstatic void append_text_character_(system_t *obj, char c) {\n    const size_t n = obj->source.text.n;\n    if (!char_array__resize(&(obj->source.text), n + 1)) {\n        fprintf(stderr, \"FATAL: Out of memory\\n\");\n        longjmp(obj->jmp, 1); /* never returns */\n    }\n    obj->source.text.p[n] = (char)c;\n}\n\nstatic void append_line_head_(system_t *obj, size_t h) {\n    const size_t n = obj->source.line.n;\n    if (!size_t_array__resize(&(obj->source.line), n + 1)) {\n        fprintf(stderr, \"FATAL: Out of memory\\n\");\n        longjmp(obj->jmp, 1); /* never returns */\n    }\n    obj->source.line.p[n] = h;\n}\n\nstatic size_t count_characters_(const char *buf, size_t start, size_t end) {\n    /* UTF-8 multibyte character support but without checking UTF-8 validity */\n    size_t n = 0, i = start;\n    while (i < end) {\n        const int c = (int)(unsigned char)buf[i];\n        if (c == 0) break;\n        n++;\n        i += (c < 0x80) ? 1 : ((c & 0xe0) == 0xc0) ? 2 : ((c & 0xf0) == 0xe0) ? 3 : ((c & 0xf8) == 0xf0) ? 4 : /* invalid code */ 1;\n    }\n    return n;\n}\n\nstatic void compute_line_and_column_(system_t *obj, size_t pos, size_t *line, size_t *column) {\n    size_t i;\n    for (i = 1; i < obj->source.line.n; i++) {\n        if (pos < obj->source.line.p[i]) break;\n    }\n    if (line) *line = i;\n    if (column) *column = count_characters_(obj->source.text.p, obj->source.line.p[i - 1], pos) + 1;\n}\n\nvoid system__initialize(system_t *obj) {\n    obj->source.path = NULL;\n    obj->source.file = NULL;\n    char_array__initialize(&(obj->source.text));\n    size_t_array__initialize(&(obj->source.line));\n    obj->source.ecount = 0;\n    obj->managed.first = NULL;\n    obj->managed.last = NULL;\n    append_line_head_(obj, 0);\n}\n\nvoid system__finalize(system_t *obj) {\n    if (obj->source.file != NULL && obj->source.file != stdin) fclose(obj->source.file);\n    char_array__finalize(&(obj->source.text));\n    size_t_array__finalize(&(obj->source.line));\n    system__destroy_all_ast_nodes(obj);\n}\n\nvoid *system__allocate_memory(system_t *obj, size_t size) {\n    void *const p = malloc(size);\n    if (p == NULL) {\n        fprintf(stderr, \"FATAL: Out of memory\\n\");\n        longjmp(obj->jmp, 1); /* never returns */\n    }\n    return p;\n}\n\nvoid *system__reallocate_memory(system_t *obj, void *ptr, size_t size) {\n    void *const p = realloc(ptr, size);\n    if (p == NULL) {\n        fprintf(stderr, \"FATAL: Out of memory\\n\");\n        longjmp(obj->jmp, 1); /* never returns */\n    }\n    return p;\n}\n\nvoid system__deallocate_memory(system_t *obj, void *ptr) {\n    free(ptr);\n}\n\nvoid system__open_source_file(system_t *obj, const char *path) {\n    if (path != NULL) {\n        FILE *const f = fopen(path, \"rt\");\n        if (f == NULL) {\n            fprintf(stderr, \"FATAL: Cannot open file '%s'\\n\", path);\n            longjmp(obj->jmp, 1); /* never returns */\n        }\n        obj->source.path = path;\n        obj->source.file = f;\n    }\n    else {\n        obj->source.path = NULL;\n        obj->source.file = stdin;\n    }\n}\n\nvoid system__close_source_file(system_t *obj) {\n    if (obj->source.file != NULL && obj->source.file != stdin) {\n        if (fclose(obj->source.file) == EOF) {\n            fprintf(stderr, \"FATAL: Error occurred while closing file '%s'\\n\", obj->source.path);\n            longjmp(obj->jmp, 1); /* never returns */\n        }\n    }\n    obj->source.path = NULL;\n    obj->source.file = NULL;\n}\n\nint system__read_source_file(system_t *obj) {\n    const int c = fgetc(obj->source.file);\n    if (c != EOF) {\n        append_text_character_(obj, (char)c);\n        if (c == '\\r') {\n            append_line_head_(obj, obj->source.text.n);\n        }\n        else if (c == '\\n') {\n            if (obj->source.text.n >= 2 && obj->source.text.p[obj->source.text.n - 2] == '\\r') {\n                obj->source.line.p[obj->source.line.n - 1] = obj->source.text.n;\n            }\n            else {\n                append_line_head_(obj, obj->source.text.n);\n            }\n        }\n    }\n    else {\n        if (ferror(obj->source.file)) {\n            if (obj->source.path != NULL) {\n                fprintf(stderr, \"FATAL: Error occurred while reading file '%s'\\n\", obj->source.path);\n            }\n            else {\n                fprintf(stderr, \"FATAL: Error occurred while reading standard input\\n\");\n            }\n            longjmp(obj->jmp, 1); /* never returns */\n        }\n    }\n    return c;\n}\n\nstatic ast_node_t *create_ast_node_(system_t *obj, ast_node_type_t type, range_t range) {\n    ast_node_t *const node = (ast_node_t *)system__allocate_memory(obj, sizeof(ast_node_t));\n    node->type = type;\n    node->range = range;\n    node->arity = 0;\n    node->parent = NULL;\n    node->sibling.prev = NULL;\n    node->sibling.next = NULL;\n    node->child.first = NULL;\n    node->child.last = NULL;\n    node->system = obj;\n    if (obj->managed.last != NULL) {\n        node->managed.prev = obj->managed.last;\n        node->managed.next = NULL;\n        obj->managed.last = node;\n        if (node->managed.prev != NULL) {\n            node->managed.prev->managed.next = node;\n        }\n        else {\n            obj->managed.first = node;\n        }\n    }\n    else {\n        node->managed.prev = NULL;\n        node->managed.next = NULL;\n        obj->managed.first = node;\n        obj->managed.last = node;\n    }\n    return node;\n}\n\nast_node_t *system__create_ast_node_terminal(system_t *obj, ast_node_type_t type, range_t range) {\n    return create_ast_node_(obj, type, range);\n}\n\nast_node_t *system__create_ast_node_unary(system_t *obj, ast_node_type_t type, range_t range, ast_node_t *node1) {\n    if (node1 == NULL) {\n        fprintf(stderr, \"FATAL: Internal error\\n\");\n        longjmp(obj->jmp, 1); /* never returns */\n    }\n    ast_node_t *const node = create_ast_node_(obj, type, range);\n    ast_node__append_child(node, node1);\n    return node;\n}\n\nast_node_t *system__create_ast_node_binary(system_t *obj, ast_node_type_t type, range_t range, ast_node_t *node1, ast_node_t *node2) {\n    if (node1 == NULL || node2 == NULL) {\n        fprintf(stderr, \"FATAL: Internal error\\n\");\n        longjmp(obj->jmp, 1); /* never returns */\n    }\n    ast_node_t *const node = create_ast_node_(obj, type, range);\n    ast_node__append_child(node, node1);\n    ast_node__append_child(node, node2);\n    return node;\n}\n\nast_node_t *system__create_ast_node_ternary(system_t *obj, ast_node_type_t type, range_t range, ast_node_t *node1, ast_node_t *node2, ast_node_t *node3) {\n    if (node1 == NULL || node2 == NULL || node3 == NULL) {\n        fprintf(stderr, \"FATAL: Internal error\\n\");\n        longjmp(obj->jmp, 1); /* never returns */\n    }\n    ast_node_t *const node = create_ast_node_(obj, type, range);\n    ast_node__append_child(node, node1);\n    ast_node__append_child(node, node2);\n    ast_node__append_child(node, node3);\n    return node;\n}\n\nast_node_t *system__create_ast_node_variadic(system_t *obj, ast_node_type_t type, range_t range) {\n    return create_ast_node_(obj, type, range);\n}\n\nvoid system__destroy_all_ast_nodes(system_t *obj) {\n    while (obj->managed.first != NULL) {\n        ast_node__destroy(obj->managed.first);\n    }\n}\n\nvoid ast_node__prepend_child(ast_node_t *obj, ast_node_t *node) {\n    if (node == NULL) return; /* just ignored */\n    if (node->parent != NULL) {\n        if (node->sibling.prev != NULL) {\n            node->sibling.prev->sibling.next = node->sibling.next;\n        }\n        else {\n            node->parent->child.first = node->sibling.next;\n        }\n        if (node->sibling.next != NULL) {\n            node->sibling.next->sibling.prev = node->sibling.prev;\n        }\n        else {\n            node->parent->child.last = node->sibling.prev;\n        }\n        node->parent->arity--;\n    }\n    node->parent = obj;\n    if (obj->child.first != NULL) {\n        obj->child.first->sibling.prev = node;\n        node->sibling.next = obj->child.first;\n        node->sibling.prev = NULL;\n        obj->child.first = node;\n    }\n    else {\n        node->sibling.next = NULL;\n        node->sibling.prev = NULL;\n        obj->child.first = node;\n        obj->child.last = node;\n    }\n    obj->arity++;\n}\n\nvoid ast_node__append_child(ast_node_t *obj, ast_node_t *node) {\n    if (node == NULL) return; /* just ignored */\n    if (node->parent != NULL) {\n        if (node->sibling.prev != NULL) {\n            node->sibling.prev->sibling.next = node->sibling.next;\n        }\n        else {\n            node->parent->child.first = node->sibling.next;\n        }\n        if (node->sibling.next != NULL) {\n            node->sibling.next->sibling.prev = node->sibling.prev;\n        }\n        else {\n            node->parent->child.last = node->sibling.prev;\n        }\n        node->parent->arity--;\n    }\n    node->parent = obj;\n    if (obj->child.last != NULL) {\n        obj->child.last->sibling.next = node;\n        node->sibling.prev = obj->child.last;\n        node->sibling.next = NULL;\n        obj->child.last = node;\n    }\n    else {\n        node->sibling.prev = NULL;\n        node->sibling.next = NULL;\n        obj->child.last = node;\n        obj->child.first = node;\n    }\n    obj->arity++;\n}\n\nvoid ast_node__destroy(ast_node_t *obj) {\n    if (obj->parent != NULL) {\n        if (obj->sibling.prev != NULL) {\n            obj->sibling.prev->sibling.next = obj->sibling.next;\n        }\n        else {\n            obj->parent->child.first = obj->sibling.next;\n        }\n        if (obj->sibling.next != NULL) {\n            obj->sibling.next->sibling.prev = obj->sibling.prev;\n        }\n        else {\n            obj->parent->child.last = obj->sibling.prev;\n        }\n        obj->parent->arity--;\n    }\n    while (obj->child.first != NULL) {\n        ast_node_t *const child = obj->child.first;\n        obj->child.first = child->sibling.next;\n        child->sibling.next = NULL;\n        child->sibling.prev = NULL;\n        child->parent = NULL;\n    }\n    {\n        if (obj->managed.prev != NULL) {\n            obj->managed.prev->managed.next = obj->managed.next;\n        }\n        else {\n            obj->system->managed.first = obj->managed.next;\n        }\n        if (obj->managed.next != NULL) {\n            obj->managed.next->managed.prev = obj->managed.prev;\n        }\n        else {\n            obj->system->managed.last = obj->managed.prev;\n        }\n    }\n    system__deallocate_memory(obj->system, obj);\n}\n\nvoid system__handle_syntax_error(system_t *obj, syntax_error_t error, range_t range) {\n    size_t line, col;\n    compute_line_and_column_(obj, range.min, &line, &col);\n    obj->source.ecount++;\n    switch (error) {\n    case SYNTAX_ERROR_IF_WITHOUT_CONDITION:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Condition missing after 'if'\\n\", line, col);\n        break;\n    case SYNTAX_ERROR_IF_WITHOUT_STATEMENT:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Statement missing after 'if' condition\\n\", line, col);\n        break;\n    case SYNTAX_ERROR_ELSE_WITHOUT_STATEMENT:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Statement missing after 'else'\\n\", line, col);\n        break;\n    case SYNTAX_ERROR_LONE_ELSE:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: 'else' without corresponding 'if'\\n\", line, col);\n        break;\n    case SYNTAX_ERROR_WHILE_WITHOUT_CONDITION:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Condition missing after 'while'\\n\", line, col);\n        break;\n    case SYNTAX_ERROR_WHILE_WITHOUT_STATEMENT:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Statement missing after 'while' condition\\n\", line, col);\n        break;\n    case SYNTAX_ERROR_DO_WITHOUT_STATEMENT:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Statement missing after 'do'\\n\", line, col);\n        break;\n    case SYNTAX_ERROR_DO_WITHOUT_WHILE:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: 'while' missing after 'do' statement\\n\", line, col);\n        break;\n    case SYNTAX_ERROR_NO_ENDING_SEMICOLON:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Ending semicolon missing\\n\", line, col);\n        break;\n    case SYNTAX_ERROR_UNCLOSED_COMMENT_BLOCK:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Unclosed comment block\\n\", line, col);\n        break;\n    case SYNTAX_ERROR_UNEXPECTED_TOKEN:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Unexpected token '%.*s'\\n\", line, col, (int)(range.max - range.min), obj->source.text.p + range.min);\n        break;\n    case SYNTAX_ERROR_UNKNOWN:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Unknown error\\n\", line, col);\n        break;\n    default:\n        fprintf(stderr, \"ERROR: line %zu, column %zu: Undefined internal error\\n\", line, col);\n    }\n    if (obj->source.ecount >= ERROR_MAX) longjmp(obj->jmp, 1); /* never returns */\n}\n\nstatic void dump_ast_(system_t *obj, ast_node_t *node, int level) {\n    const char *type = \"UNKNOWN\";\n    switch (node->type) {\n    case AST_NODE_TYPE_IDENTIFIER:          type = \"IDENTIFIER\";          break;\n    case AST_NODE_TYPE_INTEGER_DEC:         type = \"INTEGER_DEC\";         break;\n    case AST_NODE_TYPE_INTEGER_OCT:         type = \"INTEGER_OCT\";         break;\n    case AST_NODE_TYPE_INTEGER_HEX:         type = \"INTEGER_HEX\";         break;\n    case AST_NODE_TYPE_OPERATOR_PLUS:       type = \"OPERATOR_PLUS\";       break;\n    case AST_NODE_TYPE_OPERATOR_MINUS:      type = \"OPERATOR_MINUS\";      break;\n    case AST_NODE_TYPE_OPERATOR_INV:        type = \"OPERATOR_INV\";        break;\n    case AST_NODE_TYPE_OPERATOR_NOT:        type = \"OPERATOR_NOT\";        break;\n    case AST_NODE_TYPE_OPERATOR_INC:        type = \"OPERATOR_INC\";        break;\n    case AST_NODE_TYPE_OPERATOR_DEC:        type = \"OPERATOR_DEC\";        break;\n    case AST_NODE_TYPE_OPERATOR_POST_INC:   type = \"OPERATOR_POST_INC\";   break;\n    case AST_NODE_TYPE_OPERATOR_POST_DEC:   type = \"OPERATOR_POST_DEC\";   break;\n    case AST_NODE_TYPE_OPERATOR_ADD:        type = \"OPERATOR_ADD\";        break;\n    case AST_NODE_TYPE_OPERATOR_SUB:        type = \"OPERATOR_SUB\";        break;\n    case AST_NODE_TYPE_OPERATOR_MUL:        type = \"OPERATOR_MUL\";        break;\n    case AST_NODE_TYPE_OPERATOR_DIV:        type = \"OPERATOR_DIV\";        break;\n    case AST_NODE_TYPE_OPERATOR_MOD:        type = \"OPERATOR_MOD\";        break;\n    case AST_NODE_TYPE_OPERATOR_AND:        type = \"OPERATOR_AND\";        break;\n    case AST_NODE_TYPE_OPERATOR_AND2:       type = \"OPERATOR_AND2\";       break;\n    case AST_NODE_TYPE_OPERATOR_OR:         type = \"OPERATOR_OR\";         break;\n    case AST_NODE_TYPE_OPERATOR_OR2:        type = \"OPERATOR_OR2\";        break;\n    case AST_NODE_TYPE_OPERATOR_XOR:        type = \"OPERATOR_XOR\";        break;\n    case AST_NODE_TYPE_OPERATOR_SHL:        type = \"OPERATOR_SHL\";        break;\n    case AST_NODE_TYPE_OPERATOR_SHR:        type = \"OPERATOR_SHR\";        break;\n    case AST_NODE_TYPE_OPERATOR_EQ:         type = \"OPERATOR_EQ\";         break;\n    case AST_NODE_TYPE_OPERATOR_NE:         type = \"OPERATOR_NE\";         break;\n    case AST_NODE_TYPE_OPERATOR_LT:         type = \"OPERATOR_LT\";         break;\n    case AST_NODE_TYPE_OPERATOR_LE:         type = \"OPERATOR_LE\";         break;\n    case AST_NODE_TYPE_OPERATOR_GT:         type = \"OPERATOR_GT\";         break;\n    case AST_NODE_TYPE_OPERATOR_GE:         type = \"OPERATOR_GE\";         break;\n    case AST_NODE_TYPE_OPERATOR_COND:       type = \"OPERATOR_COND\";       break;\n    case AST_NODE_TYPE_OPERATOR_COMMA:      type = \"OPERATOR_COMMA\";      break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN:     type = \"OPERATOR_ASSIGN\";     break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN_ADD: type = \"OPERATOR_ASSIGN_ADD\"; break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN_SUB: type = \"OPERATOR_ASSIGN_SUB\"; break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN_MUL: type = \"OPERATOR_ASSIGN_MUL\"; break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN_DIV: type = \"OPERATOR_ASSIGN_DIV\"; break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN_MOD: type = \"OPERATOR_ASSIGN_MOD\"; break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN_AND: type = \"OPERATOR_ASSIGN_AND\"; break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN_OR:  type = \"OPERATOR_ASSIGN_OR\";  break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN_XOR: type = \"OPERATOR_ASSIGN_XOR\"; break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN_SHL: type = \"OPERATOR_ASSIGN_SHL\"; break;\n    case AST_NODE_TYPE_OPERATOR_ASSIGN_SHR: type = \"OPERATOR_ASSIGN_SHR\"; break;\n    case AST_NODE_TYPE_STATEMENT_VOID:      type = \"STATEMENT_VOID\";      break;\n    case AST_NODE_TYPE_STATEMENT_IF:        type = \"STATEMENT_IF\";        break;\n    case AST_NODE_TYPE_STATEMENT_IF_ELSE:   type = \"STATEMENT_IF_ELSE\";   break;\n    case AST_NODE_TYPE_STATEMENT_WHILE:     type = \"STATEMENT_WHILE\";     break;\n    case AST_NODE_TYPE_STATEMENT_DO_WHILE:  type = \"STATEMENT_DO_WHILE\";  break;\n    case AST_NODE_TYPE_STATEMENT_LIST:      type = \"STATEMENT_LIST\";      break;\n    case AST_NODE_TYPE_ERROR_SKIP:          type = \"ERROR_SKIP\";          break;\n    case AST_NODE_TYPE_ERROR_SKIP_IF_0:     type = \"ERROR_SKIP_IF_0\";     break;\n    case AST_NODE_TYPE_ERROR_SKIP_IF_1:     type = \"ERROR_SKIP_IF_1\";     break;\n    case AST_NODE_TYPE_ERROR_SKIP_IF_2:     type = \"ERROR_SKIP_IF_2\";     break;\n    case AST_NODE_TYPE_ERROR_SKIP_ELSE_0:   type = \"ERROR_SKIP_ELSE_0\";   break;\n    case AST_NODE_TYPE_ERROR_SKIP_ELSE_1:   type = \"ERROR_SKIP_ELSE_1\";   break;\n    case AST_NODE_TYPE_ERROR_SKIP_DO_0:     type = \"ERROR_SKIP_DO_0\";     break;\n    case AST_NODE_TYPE_ERROR_SKIP_DO_1:     type = \"ERROR_SKIP_DO_1\";     break;\n    case AST_NODE_TYPE_ERROR_SKIP_DO_2:     type = \"ERROR_SKIP_DO_2\";     break;\n    case AST_NODE_TYPE_ERROR_SKIP_WHILE_0:  type = \"ERROR_SKIP_WHILE_0\";  break;\n    case AST_NODE_TYPE_ERROR_SKIP_WHILE_1:  type = \"ERROR_SKIP_WHILE_1\";  break;\n    case AST_NODE_TYPE_UNEXPECTED_TOKEN:    type = \"UNEXPECTED_TOKEN\";    break;\n    default: break;\n    }\n    if (node->arity > 0 || node->type == AST_NODE_TYPE_STATEMENT_LIST) {\n        printf(\"%*s%s: arity = %zu\\n\", 2 * level, \"\", type, node->arity);\n        for (ast_node_t *p = node->child.first; p != NULL; p = p->sibling.next) {\n            dump_ast_(obj, p, level + 1);\n        }\n    }\n    else {\n        size_t line, col;\n        compute_line_and_column_(obj, node->range.min, &line, &col);\n        printf(\n            \"%*s%s: line = %zu, column = %zu, value = '%.*s'\\n\",\n            2 * level, \"\", type, line, col,\n            (int)(node->range.max - node->range.min), obj->source.text.p + node->range.min\n        );\n    }\n}\n\nvoid system__dump_ast(system_t *obj, ast_node_t *root) {\n    dump_ast_(obj, root, 0);\n}\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/system.h",
    "content": "/*\n * This code is hereby placed in the public domain.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\n * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef INCLUDED_SYSTEM_H\n#define INCLUDED_SYSTEM_H\n\n#include \"utility.h\"\n\n#include <stdio.h>\n#include <setjmp.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef struct system_tag system_t;\ntypedef struct ast_node_tag ast_node_t;\n\ntypedef enum ast_node_type_tag {\n    AST_NODE_TYPE_IDENTIFIER,\n    AST_NODE_TYPE_INTEGER_DEC,\n    AST_NODE_TYPE_INTEGER_OCT,\n    AST_NODE_TYPE_INTEGER_HEX,\n    AST_NODE_TYPE_OPERATOR_PLUS,\n    AST_NODE_TYPE_OPERATOR_MINUS,\n    AST_NODE_TYPE_OPERATOR_INV,\n    AST_NODE_TYPE_OPERATOR_NOT,\n    AST_NODE_TYPE_OPERATOR_INC,\n    AST_NODE_TYPE_OPERATOR_DEC,\n    AST_NODE_TYPE_OPERATOR_POST_INC,\n    AST_NODE_TYPE_OPERATOR_POST_DEC,\n    AST_NODE_TYPE_OPERATOR_ADD,\n    AST_NODE_TYPE_OPERATOR_SUB,\n    AST_NODE_TYPE_OPERATOR_MUL,\n    AST_NODE_TYPE_OPERATOR_DIV,\n    AST_NODE_TYPE_OPERATOR_MOD,\n    AST_NODE_TYPE_OPERATOR_AND,\n    AST_NODE_TYPE_OPERATOR_AND2,\n    AST_NODE_TYPE_OPERATOR_OR,\n    AST_NODE_TYPE_OPERATOR_OR2,\n    AST_NODE_TYPE_OPERATOR_XOR,\n    AST_NODE_TYPE_OPERATOR_SHL,\n    AST_NODE_TYPE_OPERATOR_SHR,\n    AST_NODE_TYPE_OPERATOR_EQ,\n    AST_NODE_TYPE_OPERATOR_NE,\n    AST_NODE_TYPE_OPERATOR_LT,\n    AST_NODE_TYPE_OPERATOR_LE,\n    AST_NODE_TYPE_OPERATOR_GT,\n    AST_NODE_TYPE_OPERATOR_GE,\n    AST_NODE_TYPE_OPERATOR_COND,\n    AST_NODE_TYPE_OPERATOR_COMMA,\n    AST_NODE_TYPE_OPERATOR_ASSIGN,\n    AST_NODE_TYPE_OPERATOR_ASSIGN_ADD,\n    AST_NODE_TYPE_OPERATOR_ASSIGN_SUB,\n    AST_NODE_TYPE_OPERATOR_ASSIGN_MUL,\n    AST_NODE_TYPE_OPERATOR_ASSIGN_DIV,\n    AST_NODE_TYPE_OPERATOR_ASSIGN_MOD,\n    AST_NODE_TYPE_OPERATOR_ASSIGN_AND,\n    AST_NODE_TYPE_OPERATOR_ASSIGN_OR,\n    AST_NODE_TYPE_OPERATOR_ASSIGN_XOR,\n    AST_NODE_TYPE_OPERATOR_ASSIGN_SHL,\n    AST_NODE_TYPE_OPERATOR_ASSIGN_SHR,\n    AST_NODE_TYPE_STATEMENT_VOID,\n    AST_NODE_TYPE_STATEMENT_IF,\n    AST_NODE_TYPE_STATEMENT_IF_ELSE,\n    AST_NODE_TYPE_STATEMENT_WHILE,\n    AST_NODE_TYPE_STATEMENT_DO_WHILE,\n    AST_NODE_TYPE_STATEMENT_LIST,\n    AST_NODE_TYPE_ERROR_SKIP,\n    AST_NODE_TYPE_ERROR_SKIP_IF_0,\n    AST_NODE_TYPE_ERROR_SKIP_IF_1,\n    AST_NODE_TYPE_ERROR_SKIP_IF_2,\n    AST_NODE_TYPE_ERROR_SKIP_ELSE_0,\n    AST_NODE_TYPE_ERROR_SKIP_ELSE_1,\n    AST_NODE_TYPE_ERROR_SKIP_DO_0,\n    AST_NODE_TYPE_ERROR_SKIP_DO_1,\n    AST_NODE_TYPE_ERROR_SKIP_DO_2,\n    AST_NODE_TYPE_ERROR_SKIP_WHILE_0,\n    AST_NODE_TYPE_ERROR_SKIP_WHILE_1,\n    AST_NODE_TYPE_UNEXPECTED_TOKEN\n} ast_node_type_t;\n\nstruct ast_node_tag {\n    ast_node_type_t type; /* the AST node type */\n    range_t range; /* the byte range in the source text */\n    size_t arity; /* the number of the child AST nodes */\n    ast_node_t *parent; /* the parent AST node */\n    struct ast_node_sibling_tag {\n        ast_node_t *prev; /* the previous sibling AST node */\n        ast_node_t *next; /* the next sibling AST node */\n    } sibling;\n    struct ast_node_child_tag {\n        ast_node_t *first; /* the first child AST node */\n        ast_node_t *last; /* the last child AST node */\n    } child;\n    system_t *system; /* the system that manages this AST node */\n    struct ast_node_managed_tag {\n        ast_node_t *prev; /* the previous AST node managed by the same system */\n        ast_node_t *next; /* the next AST node managed by the same system */\n    } managed;\n};\n\ntypedef enum syntax_error_tag {\n    SYNTAX_ERROR_IF_WITHOUT_CONDITION,\n    SYNTAX_ERROR_IF_WITHOUT_STATEMENT,\n    SYNTAX_ERROR_ELSE_WITHOUT_STATEMENT,\n    SYNTAX_ERROR_LONE_ELSE,\n    SYNTAX_ERROR_WHILE_WITHOUT_CONDITION,\n    SYNTAX_ERROR_WHILE_WITHOUT_STATEMENT,\n    SYNTAX_ERROR_DO_WITHOUT_STATEMENT,\n    SYNTAX_ERROR_DO_WITHOUT_WHILE,\n    SYNTAX_ERROR_NO_ENDING_SEMICOLON,\n    SYNTAX_ERROR_UNCLOSED_COMMENT_BLOCK,\n    SYNTAX_ERROR_UNEXPECTED_TOKEN,\n    SYNTAX_ERROR_UNKNOWN\n} syntax_error_t;\n\nstruct system_tag {\n    struct system_input_tag {\n        const char *path; /* the source file path */\n        FILE *file; /* the source file pointer */\n        char_array_t text; /* the source text */\n        size_t_array_t line; /* the byte positions of the line head in the source text */\n        size_t ecount; /* the error count */\n    } source;\n    struct system_managed_tag {\n        ast_node_t *first; /* the first managed AST node */\n        ast_node_t *last; /* the last managed AST node */\n    } managed;\n    jmp_buf jmp;\n};\n\nvoid system__initialize(system_t *obj);\nvoid system__finalize(system_t *obj);\n\nvoid *system__allocate_memory(system_t *obj, size_t size);\nvoid *system__reallocate_memory(system_t *obj, void *ptr, size_t size);\nvoid system__deallocate_memory(system_t *obj, void *ptr);\n\nvoid system__open_source_file(system_t *obj, const char *path); /* the standard input if path == NULL */\nvoid system__close_source_file(system_t *obj);\nint system__read_source_file(system_t *obj);\n\nvoid system__handle_syntax_error(system_t *obj, syntax_error_t error, range_t range);\n\nast_node_t *system__create_ast_node_terminal(system_t *obj, ast_node_type_t type, range_t range);\nast_node_t *system__create_ast_node_unary(system_t *obj, ast_node_type_t type, range_t range, ast_node_t *node1);\nast_node_t *system__create_ast_node_binary(system_t *obj, ast_node_type_t type, range_t range, ast_node_t *node1, ast_node_t *node2);\nast_node_t *system__create_ast_node_ternary(system_t *obj, ast_node_type_t type, range_t range, ast_node_t *node1, ast_node_t *node2, ast_node_t *node3);\nast_node_t *system__create_ast_node_variadic(system_t *obj, ast_node_type_t type, range_t range);\n\nvoid system__destroy_all_ast_nodes(system_t *obj);\n\nvoid system__dump_ast(system_t *obj, ast_node_t *root);\n\nvoid ast_node__prepend_child(ast_node_t *obj, ast_node_t *node);\nvoid ast_node__append_child(ast_node_t *obj, ast_node_t *node);\nvoid ast_node__destroy(ast_node_t *obj);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* !INCLUDED_SYSTEM_H */\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/utility.c",
    "content": "/*\n * This code is hereby placed in the public domain.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\n * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"utility.h\"\n\n#include <stdlib.h>\n\n#ifndef CHAR_ARRAY_MIN\n#define CHAR_ARRAY_MIN 256 /* the minimum number of char_array_t elements to be allocated */\n#endif\n\n#ifndef SIZE_T_ARRAY_MIN\n#define SIZE_T_ARRAY_MIN 16 /* the minimum number of size_t_array_t elements to be allocated */\n#endif\n\nvoid char_array__initialize(char_array_t *obj) {\n    obj->m = 0;\n    obj->n = 0;\n    obj->p = NULL;\n}\n\nvoid char_array__finalize(char_array_t *obj) {\n    free(obj->p);\n}\n\nbool_t char_array__resize(char_array_t *obj, size_t size) {\n    if (obj->m < size) {\n        size_t m = obj->m;\n        if (m == 0) m = CHAR_ARRAY_MIN;\n        while (m < size && m != 0) m <<= 1;\n        if (m == 0) m = size; /* in case of shift overflow */\n        char *const p = (char *)realloc(obj->p, m);\n        if (p == NULL) return BOOL_FALSE;\n        obj->p = p;\n        obj->m = m;\n    }\n    obj->n = size;\n    return BOOL_TRUE;\n}\n\nvoid size_t_array__initialize(size_t_array_t *obj) {\n    obj->m = 0;\n    obj->n = 0;\n    obj->p = NULL;\n}\n\nvoid size_t_array__finalize(size_t_array_t *obj) {\n    free(obj->p);\n}\n\nbool_t size_t_array__resize(size_t_array_t *obj, size_t size) {\n    if (obj->m < size) {\n        size_t m = obj->m;\n        if (m == 0) m = SIZE_T_ARRAY_MIN;\n        while (m < size && m != 0) m <<= 1;\n        if (m == 0) m = size; /* in case of shift overflow */\n        size_t *const p = (size_t *)realloc(obj->p, sizeof(size_t) * m);\n        if (p == NULL) return BOOL_FALSE;\n        obj->p = p;\n        obj->m = m;\n    }\n    obj->n = size;\n    return BOOL_TRUE;\n}\n"
  },
  {
    "path": "misc/packcc/examples/ast-tinyc/utility.h",
    "content": "/*\n * This code is hereby placed in the public domain.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\n * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#ifndef INCLUDED_UTILITY_H\n#define INCLUDED_UTILITY_H\n\n#include <stddef.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef enum bool_tag {\n    BOOL_FALSE = 0,\n    BOOL_TRUE\n} bool_t;\n\ntypedef struct range_tag {\n    size_t min; /* the start position (inclusive) */\n    size_t max; /* the end position (exclusive) */\n} range_t;\n\ntypedef struct char_array_tag {\n    size_t m; /* the allocated length */\n    size_t n; /* the actual length */\n    char *p; /* the buffer */\n} char_array_t;\n\ntypedef struct size_t_array_tag {\n    size_t m; /* the allocated length */\n    size_t n; /* the actual length */\n    size_t *p; /* the buffer */\n} size_t_array_t;\n\nvoid char_array__initialize(char_array_t *obj);\nvoid char_array__finalize(char_array_t *obj);\nbool_t char_array__resize(char_array_t *obj, size_t size);\n\nvoid size_t_array__initialize(size_t_array_t *obj);\nvoid size_t_array__finalize(size_t_array_t *obj);\nbool_t size_t_array__resize(size_t_array_t *obj, size_t size);\n\n#ifdef __cplusplus\n}\n#endif\n\ninline static range_t range__void(void) {\n    const range_t obj = { 0, 0 };\n    return obj;\n}\n\ninline static range_t range__new(size_t min, size_t max) {\n    const range_t obj = { min, max };\n    return obj;\n}\n\n#endif /* !INCLUDED_UTILITY_H */\n"
  },
  {
    "path": "misc/packcc/examples/calc.peg",
    "content": "# This code is hereby placed in the public domain.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\n# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\n# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n%prefix \"calc\"\n\n%source {\n#include <stdio.h>\n#include <stdlib.h>\n}\n\nstatement <- _ e:expression _ EOL { printf(\"answer=%d\\n\", e); }\n           / ( !EOL . )* EOL      { printf(\"error\\n\"); }\n\nexpression <- e:term { $$ = e; }\n\nterm <- l:term _ '+' _ r:factor { $$ = l + r; }\n      / l:term _ '-' _ r:factor { $$ = l - r; }\n      / e:factor                { $$ = e; }\n\nfactor <- l:factor _ '*' _ r:unary { $$ = l * r; }\n        / l:factor _ '/' _ r:unary { $$ = l / r; }\n        / e:unary                  { $$ = e; }\n\nunary <- '+' _ e:unary { $$ = +e; }\n       / '-' _ e:unary { $$ = -e; }\n       / e:primary     { $$ = e; }\n\nprimary <- < [0-9]+ >               { $$ = atoi($1); }\n         / '(' _ e:expression _ ')' { $$ = e; }\n\n_      <- [ \\t]*\nEOL    <- '\\n' / '\\r\\n' / '\\r' / ';'\n\n%%\nint main() {\n    calc_context_t *ctx = calc_create(NULL);\n    while (calc_parse(ctx, NULL));\n    calc_destroy(ctx);\n    return 0;\n}\n"
  },
  {
    "path": "misc/packcc/src/packcc.c",
    "content": "/*\n * PackCC: a packrat parser generator for C.\n *\n * Copyright (c) 2014, 2019-2022 Arihiro Yoshida. All rights reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/*\n * The algorithm is based on the paper \"Packrat Parsers Can Support Left Recursion\"\n * authored by A. Warth, J. R. Douglass, and T. Millstein.\n *\n * The specification is determined by referring to peg/leg developed by Ian Piumarta.\n */\n\n#ifdef _MSC_VER\n#define _CRT_SECURE_NO_WARNINGS\n#ifdef _DEBUG\n#define _CRTDBG_MAP_ALLOC\n#include <crtdbg.h>\n#endif\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdarg.h>\n#include <string.h>\n#include <limits.h>\n#include <assert.h>\n\n#ifndef _MSC_VER\n#if defined __GNUC__ && defined _WIN32 /* MinGW */\n#ifndef PCC_USE_SYSTEM_STRNLEN\n#define strnlen(str, maxlen) strnlen_(str, maxlen)\nstatic size_t strnlen_(const char *str, size_t maxlen) {\n    size_t i;\n    for (i = 0; i < maxlen && str[i]; i++);\n    return i;\n}\n#endif /* !PCC_USE_SYSTEM_STRNLEN */\n#endif /* defined __GNUC__ && defined _WIN32 */\n#endif /* !_MSC_VER */\n\n#ifdef _MSC_VER\n#define snprintf _snprintf\n#define vsnprintf _vsnprintf\n#define unlink _unlink\n#else\n#include <unistd.h> /* for unlink() */\n#endif\n\n#if !defined __has_attribute || defined _MSC_VER\n#define __attribute__(x)\n#endif\n\n#undef TRUE  /* to avoid macro definition conflicts with the system header file of IBM AIX */\n#undef FALSE\n\n#define VERSION \"1.8.0\"\n\n#ifndef BUFFER_MIN_SIZE\n#define BUFFER_MIN_SIZE 256\n#endif\n#ifndef ARRAY_MIN_SIZE\n#define ARRAY_MIN_SIZE 2\n#endif\n\n#define VOID_VALUE (~(size_t)0)\n\n#ifdef _WIN64 /* 64-bit Windows including MSVC and MinGW-w64 */\n#define FMT_LU \"%llu\"\ntypedef unsigned long long ulong_t;\n/* NOTE: \"%llu\" and \"long long\" are not C89-compliant, but they are required to deal with a 64-bit integer value in 64-bit Windows. */\n#else\n#define FMT_LU \"%lu\"\ntypedef unsigned long ulong_t;\n#endif\n/* FMT_LU and ulong_t are used to print size_t values safely (ex. printf(FMT_LU \"\\n\", (ulong_t)value);) */\n/* NOTE: Neither \"%z\" nor <inttypes.h> is used since PackCC complies with the C89 standard as much as possible. */\n\ntypedef enum bool_tag {\n    FALSE = 0,\n    TRUE\n} bool_t;\n\ntypedef struct stream_tag {\n    FILE *file;       /* the stream; just a reference */\n    const char *name; /* the file name */\n    size_t line;      /* the current line number (0-based); line counting is disabled if VOID_VALUE */\n} stream_t;\n\ntypedef struct char_array_tag {\n    char *buf;\n    size_t max;\n    size_t len;\n} char_array_t;\n\ntypedef struct code_block_tag {\n    char *text;\n    size_t len;\n    size_t line;\n    size_t col;\n} code_block_t;\n\ntypedef struct code_block_array_tag {\n    code_block_t *buf;\n    size_t max;\n    size_t len;\n} code_block_array_t;\n\ntypedef enum node_type_tag {\n    NODE_RULE = 0,\n    NODE_REFERENCE,\n    NODE_STRING,\n    NODE_CHARCLASS,\n    NODE_QUANTITY,\n    NODE_PREDICATE,\n    NODE_SEQUENCE,\n    NODE_ALTERNATE,\n    NODE_CAPTURE,\n    NODE_EXPAND,\n    NODE_ACTION,\n    NODE_ERROR\n} node_type_t;\n\ntypedef struct node_tag node_t;\n\ntypedef struct node_array_tag {\n    node_t **buf;\n    size_t max;\n    size_t len;\n} node_array_t;\n\ntypedef struct node_const_array_tag {\n    const node_t **buf;\n    size_t max;\n    size_t len;\n} node_const_array_t;\n\ntypedef struct node_hash_table_tag {\n    const node_t **buf;\n    size_t max;\n    size_t mod;\n} node_hash_table_t;\n\ntypedef struct node_rule_tag {\n    char *name;\n    node_t *expr;\n    int ref; /* mutable */\n    node_const_array_t vars;\n    node_const_array_t capts;\n    node_const_array_t codes;\n    size_t line;\n    size_t col;\n} node_rule_t;\n\ntypedef struct node_reference_tag {\n    char *var; /* NULL if no variable name */\n    size_t index;\n    char *name;\n    const node_t *rule;\n    size_t line;\n    size_t col;\n} node_reference_t;\n\ntypedef struct node_string_tag {\n    char *value;\n} node_string_t;\n\ntypedef struct node_charclass_tag {\n    char *value; /* NULL means any character */\n} node_charclass_t;\n\ntypedef struct node_quantity_tag {\n    int min;\n    int max;\n    node_t *expr;\n} node_quantity_t;\n\ntypedef struct node_predicate_tag {\n    bool_t neg;\n    node_t *expr;\n} node_predicate_t;\n\ntypedef struct node_sequence_tag {\n    node_array_t nodes;\n} node_sequence_t;\n\ntypedef struct node_alternate_tag {\n    node_array_t nodes;\n} node_alternate_t;\n\ntypedef struct node_capture_tag {\n    node_t *expr;\n    size_t index;\n} node_capture_t;\n\ntypedef struct node_expand_tag {\n    size_t index;\n    size_t line;\n    size_t col;\n} node_expand_t;\n\ntypedef struct node_action_tag {\n    code_block_t code;\n    size_t index;\n    node_const_array_t vars;\n    node_const_array_t capts;\n} node_action_t;\n\ntypedef struct node_error_tag {\n    node_t *expr;\n    code_block_t code;\n    size_t index;\n    node_const_array_t vars;\n    node_const_array_t capts;\n} node_error_t;\n\ntypedef union node_data_tag {\n    node_rule_t      rule;\n    node_reference_t reference;\n    node_string_t    string;\n    node_charclass_t charclass;\n    node_quantity_t  quantity;\n    node_predicate_t predicate;\n    node_sequence_t  sequence;\n    node_alternate_t alternate;\n    node_capture_t   capture;\n    node_expand_t    expand;\n    node_action_t    action;\n    node_error_t     error;\n} node_data_t;\n\nstruct node_tag {\n    node_type_t type;\n    node_data_t data;\n};\n\ntypedef struct options_tag {\n    bool_t ascii; /* UTF-8 support is disabled if true  */\n    bool_t lines; /* #line directives are output if true */\n    bool_t debug; /* debug information is output if true */\n} options_t;\n\ntypedef enum code_flag_tag {\n    CODE_FLAG__NONE = 0,\n    CODE_FLAG__UTF8_CHARCLASS_USED = 1\n} code_flag_t;\n\ntypedef struct context_tag {\n    char *iname;  /* the path name of the PEG file being parsed */\n    char *sname;  /* the path name of the C source file being generated */\n    char *hname;  /* the path name of the C header file being generated */\n    FILE *ifile;  /* the input stream of the PEG file */\n    char *hid;    /* the macro name for the include guard of the C header file */\n    char *vtype;  /* the type name of the data output by the parsing API function (NULL means the default) */\n    char *atype;  /* the type name of the user-defined data passed to the parser creation API function (NULL means the default) */\n    char *prefix; /* the prefix of the API function names (NULL means the default) */\n    options_t opts;      /* the options */\n    code_flag_t flags;   /* the bitwise flags to control code generation; updated during PEG parsing */\n    size_t errnum;       /* the current number of PEG parsing errors */\n    size_t linenum;      /* the current line number (0-based) */\n    size_t charnum;      /* the number of characters in the current line that are already flushed (0-based, UTF-8 support if not disabled) */\n    size_t linepos;      /* the beginning position in the PEG file of the current line */\n    size_t bufpos;       /* the position in the PEG file of the first character currently buffered */\n    size_t bufcur;       /* the current parsing position in the character buffer */\n    char_array_t buffer; /* the character buffer */\n    node_array_t rules;  /* the PEG rules */\n    node_hash_table_t rulehash; /* the hash table to accelerate access of desired PEG rules */\n    code_block_array_t esource; /* the code blocks from %earlysource and %earlycommon directives to be added into the generated source file */\n    code_block_array_t eheader; /* the code blocks from %earlyheader and %earlycommon directives to be added into the generated header file */\n    code_block_array_t source;  /* the code blocks from %source and %common directives to be added into the generated source file */\n    code_block_array_t header;  /* the code blocks from %header and %common directives to be added into the generated header file */\n} context_t;\n\ntypedef struct generate_tag {\n    stream_t *stream;\n    const node_t *rule;\n    int label;\n    bool_t ascii;\n} generate_t;\n\ntypedef enum string_flag_tag {\n    STRING_FLAG__NONE = 0,\n    STRING_FLAG__NOTEMPTY = 1,\n    STRING_FLAG__NOTVOID = 2,\n    STRING_FLAG__IDENTIFIER = 4\n} string_flag_t;\n\ntypedef enum code_reach_tag {\n    CODE_REACH__BOTH = 0,\n    CODE_REACH__ALWAYS_SUCCEED = 1,\n    CODE_REACH__ALWAYS_FAIL = -1\n} code_reach_t;\n\nstatic const char *g_cmdname = \"packcc\"; /* replaced later with actual one */\n\n__attribute__((format(printf, 1, 2)))\nstatic int print_error(const char *format, ...) {\n    int n;\n    va_list a;\n    va_start(a, format);\n    n = fprintf(stderr, \"%s: \", g_cmdname);\n    if (n >= 0) {\n        const int k = vfprintf(stderr, format, a);\n        if (k < 0) n = k; else n += k;\n    }\n    va_end(a);\n    return n;\n}\n\nstatic FILE *fopen_rb_e(const char *path) {\n    FILE *const f = fopen(path, \"rb\");\n    if (f == NULL) {\n        print_error(\"Cannot open file '%s' to read\\n\", path);\n        exit(2);\n    }\n    return f;\n}\n\nstatic FILE *fopen_wt_e(const char *path) {\n    FILE *const f = fopen(path, \"wt\");\n    if (f == NULL) {\n        print_error(\"Cannot open file '%s' to write\\n\", path);\n        exit(2);\n    }\n    return f;\n}\n\nstatic int fclose_e(FILE *stream) {\n    const int r = fclose(stream);\n    if (r == EOF) {\n        print_error(\"File closing error\\n\");\n        exit(2);\n    }\n    return r;\n}\n\nstatic int fgetc_e(FILE *stream) {\n    const int c = fgetc(stream);\n    if (c == EOF && ferror(stream)) {\n        print_error(\"File read error\\n\");\n        exit(2);\n    }\n    return c;\n}\n\nstatic void *malloc_e(size_t size) {\n    void *const p = malloc(size);\n    if (p == NULL) {\n        print_error(\"Out of memory\\n\");\n        exit(3);\n    }\n    return p;\n}\n\nstatic void *realloc_e(void *ptr, size_t size) {\n    void *const p = realloc(ptr, size);\n    if (p == NULL) {\n        print_error(\"Out of memory\\n\");\n        exit(3);\n    }\n    return p;\n}\n\nstatic char *strdup_e(const char *str) {\n    const size_t m = strlen(str);\n    char *const s = (char *)malloc_e(m + 1);\n    memcpy(s, str, m);\n    s[m] = '\\0';\n    return s;\n}\n\nstatic char *strndup_e(const char *str, size_t len) {\n    const size_t m = strnlen(str, len);\n    char *const s = (char *)malloc_e(m + 1);\n    memcpy(s, str, m);\n    s[m] = '\\0';\n    return s;\n}\n\nstatic size_t string_to_size_t(const char *str) {\n#define N (~(size_t)0 / 10)\n#define M (~(size_t)0 - 10 * N)\n    size_t n = 0, i, k;\n    for (i = 0; str[i]; i++) {\n        const char c = str[i];\n        if (c < '0' || c > '9') return VOID_VALUE;\n        k = (size_t)(c - '0');\n        if (n >= N && k > M) return VOID_VALUE; /* overflow */\n        n = k + 10 * n;\n    }\n    return n;\n#undef N\n#undef M\n}\n\nstatic size_t find_first_trailing_space(const char *str, size_t start, size_t end, size_t *next) {\n    size_t j = start, i;\n    for (i = start; i < end; i++) {\n        switch (str[i]) {\n        case ' ':\n        case '\\v':\n        case '\\f':\n        case '\\t':\n            continue;\n        case '\\n':\n            if (next) *next = i + 1;\n            return j;\n        case '\\r':\n            if (i + 1 < end && str[i + 1] == '\\n') i++;\n            if (next) *next = i + 1;\n            return j;\n        default:\n            j = i + 1;\n        }\n    }\n    if (next) *next = end;\n    return j;\n}\n\nstatic size_t count_indent_spaces(const char *str, size_t start, size_t end, size_t *next) {\n    size_t n = 0, i;\n    for (i = start; i < end; i++) {\n        switch (str[i]) {\n        case ' ':\n        case '\\v':\n        case '\\f':\n            n++;\n            break;\n        case '\\t':\n            n = (n + 8) & ~7;\n            break;\n        default:\n            if (next) *next = i;\n            return n;\n        }\n    }\n    if (next) *next = end;\n    return n;\n}\n\nstatic bool_t is_filled_string(const char *str) {\n    size_t i;\n    for (i = 0; str[i]; i++) {\n        if (\n            str[i] != ' '  &&\n            str[i] != '\\v' &&\n            str[i] != '\\f' &&\n            str[i] != '\\t' &&\n            str[i] != '\\n' &&\n            str[i] != '\\r'\n        ) return TRUE;\n    }\n    return FALSE;\n}\n\nstatic bool_t is_identifier_string(const char *str) {\n    size_t i;\n    if (!(\n        (str[0] >= 'a' && str[0] <= 'z') ||\n        (str[0] >= 'A' && str[0] <= 'Z') ||\n        str[0] == '_'\n    )) return FALSE;\n    for (i = 1; str[i]; i++) {\n        if (!(\n            (str[i] >= 'a' && str[i] <= 'z') ||\n            (str[i] >= 'A' && str[i] <= 'Z') ||\n            (str[i] >= '0' && str[i] <= '9') ||\n            str[i] == '_'\n        )) return FALSE;\n    }\n    return TRUE;\n}\n\nstatic bool_t is_pointer_type(const char *str) {\n    const size_t n = strlen(str);\n    return (n > 0 && str[n - 1] == '*') ? TRUE : FALSE;\n}\n\nstatic bool_t is_valid_utf8_string(const char *str) {\n    int k = 0, n = 0, u = 0;\n    size_t i;\n    for (i = 0; str[i]; i++) {\n        const int c = (int)(unsigned char)str[i];\n        switch (k) {\n        case 0:\n            if (c >= 0x80) {\n                if ((c & 0xe0) == 0xc0) {\n                    u = c & 0x1f;\n                    n = k = 1;\n                }\n                else if ((c & 0xf0) == 0xe0) {\n                    u = c & 0x0f;\n                    n = k = 2;\n                }\n                else if ((c & 0xf8) == 0xf0) {\n                    u = c & 0x07;\n                    n = k = 3;\n                }\n                else {\n                    return FALSE;\n                }\n            }\n            break;\n        case 1:\n        case 2:\n        case 3:\n            if ((c & 0xc0) == 0x80) {\n                u <<= 6;\n                u |= c & 0x3f;\n                k--;\n                if (k == 0) {\n                    switch (n) {\n                    case 1:\n                        if (u < 0x80) return FALSE;\n                        break;\n                    case 2:\n                        if (u < 0x800) return FALSE;\n                        break;\n                    case 3:\n                        if (u < 0x10000 || u > 0x10ffff) return FALSE;\n                        break;\n                    default:\n                        assert(((void)\"unexpected control flow\", 0));\n                        return FALSE; /* never reached */\n                    }\n                    u = 0;\n                    n = 0;\n                }\n            }\n            else {\n                return FALSE;\n            }\n            break;\n        default:\n            assert(((void)\"unexpected control flow\", 0));\n            return FALSE; /* never reached */\n        }\n    }\n    return (k == 0) ? TRUE : FALSE;\n}\n\nstatic size_t utf8_to_utf32(const char *seq, int *out) { /* without checking UTF-8 validity */\n    const int c = (int)(unsigned char)seq[0];\n    const size_t n =\n        (c == 0) ? 0 : (c < 0x80) ? 1 :\n        ((c & 0xe0) == 0xc0) ? 2 :\n        ((c & 0xf0) == 0xe0) ? 3 :\n        ((c & 0xf8) == 0xf0) ? 4 : 1;\n    int u = 0;\n    switch (n) {\n    case 0:\n    case 1:\n        u = c;\n        break;\n    case 2:\n        u = ((c & 0x1f) << 6) |\n            ((int)(unsigned char)seq[1] & 0x3f);\n        break;\n    case 3:\n        u = ((c & 0x0f) << 12) |\n            (((int)(unsigned char)seq[1] & 0x3f) << 6) |\n            (seq[1] ? ((int)(unsigned char)seq[2] & 0x3f) : 0);\n        break;\n    default:\n        u = ((c & 0x07) << 18) |\n            (((int)(unsigned char)seq[1] & 0x3f) << 12) |\n            (seq[1] ? (((int)(unsigned char)seq[2] & 0x3f) << 6) : 0) |\n            (seq[2] ? ((int)(unsigned char)seq[3] & 0x3f) : 0);\n    }\n    if (out) *out = u;\n    return n;\n}\n\nstatic bool_t unescape_string(char *str, bool_t cls) { /* cls: TRUE if used for character class matching */\n    bool_t b = TRUE;\n    size_t i, j;\n    for (j = 0, i = 0; str[i]; i++) {\n        if (str[i] == '\\\\') {\n            i++;\n            switch (str[i]) {\n            case '\\0': str[j++] = '\\\\'; str[j] = '\\0'; return FALSE;\n            case '\\'': str[j++] = '\\''; break;\n            case '\\\"': str[j++] = '\\\"'; break;\n            case '0': str[j++] = '\\x00'; break;\n            case 'a': str[j++] = '\\x07'; break;\n            case 'b': str[j++] = '\\x08'; break;\n            case 'f': str[j++] = '\\x0c'; break;\n            case 'n': str[j++] = '\\x0a'; break;\n            case 'r': str[j++] = '\\x0d'; break;\n            case 't': str[j++] = '\\x09'; break;\n            case 'v': str[j++] = '\\x0b'; break;\n            case 'x':\n                {\n                    char s = 0, c;\n                    size_t k;\n                    for (k = 0; k < 2; k++) {\n                        char d;\n                        c = str[i + k + 1];\n                        d = (c >= '0' && c <= '9') ? c - '0' :\n                            (c >= 'a' && c <= 'f') ? c - 'a' + 10 :\n                            (c >= 'A' && c <= 'F') ? c - 'A' + 10 : -1;\n                        if (d < 0) break;\n                        s = (s << 4) | d;\n                    }\n                    if (k < 2) {\n                        const size_t l = i + k;\n                        str[j++] = '\\\\'; str[j++] = 'x';\n                        while (i <= l) str[j++] = str[++i];\n                        if (c == '\\0') return FALSE;\n                        b = FALSE;\n                        continue;\n                    }\n                    str[j++] = s;\n                    i += 2;\n                }\n                break;\n            case 'u':\n                {\n                    int s = 0, t = 0;\n                    char c;\n                    size_t k;\n                    for (k = 0; k < 4; k++) {\n                        char d;\n                        c = str[i + k + 1];\n                        d = (c >= '0' && c <= '9') ? c - '0' :\n                            (c >= 'a' && c <= 'f') ? c - 'a' + 10 :\n                            (c >= 'A' && c <= 'F') ? c - 'A' + 10 : -1;\n                        if (d < 0) break;\n                        s = (s << 4) | d;\n                    }\n                    if (k < 4 || (s & 0xfc00) == 0xdc00) { /* invalid character or invalid surrogate code point */\n                        const size_t l = i + k;\n                        str[j++] = '\\\\'; str[j++] = 'u';\n                        while (i <= l) str[j++] = str[++i];\n                        if (c == '\\0') return FALSE;\n                        b = FALSE;\n                        continue;\n                    }\n                    if ((s & 0xfc00) == 0xd800) { /* surrogate pair */\n                        for (k = 4; k < 10; k++) {\n                            c = str[i + k + 1];\n                            if (k == 4) {\n                                if (c != '\\\\') break;\n                            }\n                            else if (k == 5) {\n                                if (c != 'u') break;\n                            }\n                            else {\n                                const char d =\n                                    (c >= '0' && c <= '9') ? c - '0' :\n                                    (c >= 'a' && c <= 'f') ? c - 'a' + 10 :\n                                    (c >= 'A' && c <= 'F') ? c - 'A' + 10 : -1;\n                                if (d < 0) break;\n                                t = (t << 4) | d;\n                            }\n                        }\n                        if (k < 10 || (t & 0xfc00) != 0xdc00) { /* invalid character or invalid surrogate code point */\n                            const size_t l = i + 4; /* NOTE: Not i + k to redo with recovery. */\n                            str[j++] = '\\\\'; str[j++] = 'u';\n                            while (i <= l) str[j++] = str[++i];\n                            b = FALSE;\n                            continue;\n                        }\n                    }\n                    {\n                        const int u = t ? ((((s & 0x03ff) + 0x0040) << 10) | (t & 0x03ff)) : s;\n                        if (u < 0x0080) {\n                            str[j++] = (char)u;\n                        }\n                        else if (u < 0x0800) {\n                            str[j++] = (char)(0xc0 | (u >> 6));\n                            str[j++] = (char)(0x80 | (u & 0x3f));\n                        }\n                        else if (u < 0x010000) {\n                            str[j++] = (char)(0xe0 | (u >> 12));\n                            str[j++] = (char)(0x80 | ((u >> 6) & 0x3f));\n                            str[j++] = (char)(0x80 | (u & 0x3f));\n                        }\n                        else if (u < 0x110000) {\n                            str[j++] = (char)(0xf0 | (u >> 18));\n                            str[j++] = (char)(0x80 | ((u >> 12) & 0x3f));\n                            str[j++] = (char)(0x80 | ((u >>  6) & 0x3f));\n                            str[j++] = (char)(0x80 | (u & 0x3f));\n                        }\n                        else { /* never reached theoretically; in case */\n                            const size_t l = i + 10;\n                            str[j++] = '\\\\'; str[j++] = 'u';\n                            while (i <= l) str[j++] = str[++i];\n                            b = FALSE;\n                            continue;\n                        }\n                    }\n                    i += t ? 10 : 4;\n                }\n                break;\n            case '\\n': break;\n            case '\\r': if (str[i + 1] == '\\n') i++; break;\n            case '\\\\':\n                if (cls) str[j++] = '\\\\'; /* left for character class matching (ex. considering [\\^\\]\\\\]) */\n                str[j++] = '\\\\';\n                break;\n            default: str[j++] = '\\\\'; str[j++] = str[i];\n            }\n        }\n        else {\n            str[j++] = str[i];\n        }\n    }\n    str[j] = '\\0';\n    return b;\n}\n\nstatic const char *escape_character(char ch, char (*buf)[5]) {\n    switch (ch) {\n    case '\\x00': strncpy(*buf, \"\\\\0\", 5); break;\n    case '\\x07': strncpy(*buf, \"\\\\a\", 5); break;\n    case '\\x08': strncpy(*buf, \"\\\\b\", 5); break;\n    case '\\x0c': strncpy(*buf, \"\\\\f\", 5); break;\n    case '\\x0a': strncpy(*buf, \"\\\\n\", 5); break;\n    case '\\x0d': strncpy(*buf, \"\\\\r\", 5); break;\n    case '\\x09': strncpy(*buf, \"\\\\t\", 5); break;\n    case '\\x0b': strncpy(*buf, \"\\\\v\", 5); break;\n    case '\\\\':  strncpy(*buf, \"\\\\\\\\\", 5); break;\n    case '\\'':  strncpy(*buf, \"\\\\\\'\", 5); break;\n    case '\\\"':  strncpy(*buf, \"\\\\\\\"\", 5); break;\n    default:\n        if (ch >= '\\x20' && ch < '\\x7f')\n            snprintf(*buf, 5, \"%c\", ch);\n        else\n            snprintf(*buf, 5, \"\\\\x%02x\", (int)(unsigned char)ch);\n    }\n    (*buf)[4] = '\\0';\n    return *buf;\n}\n\nstatic void remove_leading_blanks(char *str) {\n    size_t i, j;\n    for (i = 0; str[i]; i++) {\n        if (\n            str[i] != ' '  &&\n            str[i] != '\\v' &&\n            str[i] != '\\f' &&\n            str[i] != '\\t' &&\n            str[i] != '\\n' &&\n            str[i] != '\\r'\n        ) break;\n    }\n    for (j = 0; str[i]; i++) {\n        str[j++] = str[i];\n    }\n    str[j] = '\\0';\n}\n\nstatic void remove_trailing_blanks(char *str) {\n    size_t i, j;\n    for (j = 0, i = 0; str[i]; i++) {\n        if (\n            str[i] != ' '  &&\n            str[i] != '\\v' &&\n            str[i] != '\\f' &&\n            str[i] != '\\t' &&\n            str[i] != '\\n' &&\n            str[i] != '\\r'\n        ) j = i + 1;\n    }\n    str[j] = '\\0';\n}\n\nstatic size_t find_trailing_blanks(const char *str) {\n    size_t i, j;\n    for (j = 0, i = 0; str[i]; i++) {\n        if (\n            str[i] != ' '  &&\n            str[i] != '\\v' &&\n            str[i] != '\\f' &&\n            str[i] != '\\t' &&\n            str[i] != '\\n' &&\n            str[i] != '\\r'\n        ) j = i + 1;\n    }\n    return j;\n}\n\nstatic size_t count_characters(const char *str, size_t start, size_t end) {\n    /* UTF-8 multibyte character support but without checking UTF-8 validity */\n    size_t n = 0, i = start;\n    while (i < end) {\n        const int c = (int)(unsigned char)str[i];\n        if (c == 0) break;\n        n++;\n        i += (c < 0x80) ? 1 : ((c & 0xe0) == 0xc0) ? 2 : ((c & 0xf0) == 0xe0) ? 3 : ((c & 0xf8) == 0xf0) ? 4 : /* invalid code */ 1;\n    }\n    return n;\n}\n\nstatic void make_header_identifier(char *str) {\n    size_t i;\n    for (i = 0; str[i]; i++) {\n        str[i] =\n            ((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= '0' && str[i] <= '9')) ? str[i] :\n            (str[i] >= 'a' && str[i] <= 'z') ? str[i] - 'a' + 'A' : '_';\n    }\n}\n\nstatic stream_t stream__wrap(FILE *file, const char *name, size_t line) {\n    stream_t s;\n    s.file = file;\n    s.name = name;\n    s.line = line;\n    return s;\n}\n\nstatic int stream__putc(stream_t *stream, int c) {\n    const int r = fputc(c, stream->file);\n    if (r == EOF) {\n        print_error(\"File write error\\n\");\n        exit(2);\n    }\n    if (stream->line != VOID_VALUE) {\n        if (c == '\\n') stream->line++;\n    }\n    return r;\n}\n\nstatic int stream__puts(stream_t *stream, const char *s) {\n    const int r = fputs(s, stream->file);\n    if (r == EOF) {\n        print_error(\"File write error\\n\");\n        exit(2);\n    }\n    if (stream->line != VOID_VALUE) {\n        size_t i = 0;\n        for (i = 0; s[i]; i++) {\n            if (s[i] == '\\n') stream->line++;\n        }\n    }\n    return r;\n}\n\n__attribute__((format(printf, 2, 3)))\nstatic int stream__printf(stream_t *stream, const char *format, ...) {\n    if (stream->line != VOID_VALUE) {\n#define M 1024\n        char s[M], *p = NULL;\n        int n = 0;\n        size_t l = 0;\n        {\n            va_list a;\n            va_start(a, format);\n            n = vsnprintf(NULL, 0, format, a);\n            va_end(a);\n            if (n < 0) {\n                print_error(\"Internal error\\n\");\n                exit(2);\n            }\n            l = (size_t)n + 1;\n        }\n        p = (l > M) ? (char *)malloc_e(l) : s;\n        {\n            va_list a;\n            va_start(a, format);\n            n = vsnprintf(p, l, format, a);\n            va_end(a);\n            if (n < 0 || (size_t)n >= l) {\n                print_error(\"Internal error\\n\");\n                exit(2);\n            }\n        }\n        stream__puts(stream, p);\n        if (p != s) free(p);\n        return n;\n#undef M\n    }\n    else {\n        int n;\n        va_list a;\n        va_start(a, format);\n        n = vfprintf(stream->file, format, a);\n        va_end(a);\n        if (n < 0) {\n            print_error(\"File write error\\n\");\n            exit(2);\n        }\n        return n;\n    }\n}\n\nstatic void stream__write_characters(stream_t *stream, char ch, size_t len) {\n    size_t i;\n    if (len == VOID_VALUE) return; /* for safety */\n    for (i = 0; i < len; i++) stream__putc(stream, ch);\n}\n\nstatic void stream__write_text(stream_t *stream, const char *ptr, size_t len) {\n    size_t i;\n    if (len == VOID_VALUE) return; /* for safety */\n    for (i = 0; i < len; i++) {\n        if (ptr[i] == '\\r') {\n            if (i + 1 < len && ptr[i + 1] == '\\n') i++;\n            stream__putc(stream, '\\n');\n        }\n        else {\n            stream__putc(stream, ptr[i]);\n        }\n    }\n}\n\nstatic void stream__write_escaped_string(stream_t *stream, const char *ptr, size_t len) {\n    char s[5];\n    size_t i;\n    if (len == VOID_VALUE) return; /* for safety */\n    for (i = 0; i < len; i++) {\n        stream__puts(stream, escape_character(ptr[i], &s));\n    }\n}\n\nstatic void stream__write_line_directive(stream_t *stream, const char *fname, size_t lineno) {\n    stream__printf(stream, \"#line \" FMT_LU \" \\\"\", (ulong_t)(lineno + 1));\n    stream__write_escaped_string(stream, fname, strlen(fname));\n    stream__puts(stream, \"\\\"\\n\");\n}\n\nstatic void stream__write_code_block(stream_t *stream, const char *ptr, size_t len, size_t indent, const char *fname, size_t lineno) {\n    bool_t b = FALSE;\n    size_t i, j, k;\n    if (len == VOID_VALUE) return; /* for safety */\n    j = find_first_trailing_space(ptr, 0, len, &k);\n    for (i = 0; i < j; i++) {\n        if (\n            ptr[i] != ' '  &&\n            ptr[i] != '\\v' &&\n            ptr[i] != '\\f' &&\n            ptr[i] != '\\t'\n        ) break;\n    }\n    if (i < j) {\n        if (stream->line != VOID_VALUE)\n            stream__write_line_directive(stream, fname, lineno);\n        if (ptr[i] != '#')\n            stream__write_characters(stream, ' ', indent);\n        stream__write_text(stream, ptr + i, j - i);\n        stream__putc(stream, '\\n');\n        b = TRUE;\n    }\n    else {\n        lineno++;\n    }\n    if (k < len) {\n        size_t m = VOID_VALUE;\n        size_t h;\n        for (i = k; i < len; i = h) {\n            j = find_first_trailing_space(ptr, i, len, &h);\n            if (i < j) {\n                if (stream->line != VOID_VALUE && !b)\n                    stream__write_line_directive(stream, fname, lineno);\n                if (ptr[i] != '#') {\n                    const size_t l = count_indent_spaces(ptr, i, j, NULL);\n                    if (m == VOID_VALUE || m > l) m = l;\n                }\n                b = TRUE;\n            }\n            else {\n                if (!b) {\n                    k = h;\n                    lineno++;\n                }\n            }\n        }\n        for (i = k; i < len; i = h) {\n            j = find_first_trailing_space(ptr, i, len, &h);\n            if (i < j) {\n                const size_t l = count_indent_spaces(ptr, i, j, &i);\n                if (ptr[i] != '#') {\n                    assert(m != VOID_VALUE); /* m must have a valid value */\n                    assert(l >= m);\n                    stream__write_characters(stream, ' ', l - m + indent);\n                }\n                stream__write_text(stream, ptr + i, j - i);\n                stream__putc(stream, '\\n');\n                b = TRUE;\n            }\n            else if (h < len) {\n                stream__putc(stream, '\\n');\n            }\n        }\n    }\n    if (stream->line != VOID_VALUE && b)\n        stream__write_line_directive(stream, stream->name, stream->line);\n}\n\nstatic const char *extract_filename(const char *path) {\n    size_t i = strlen(path);\n    while (i > 0) {\n        i--;\n        if (path[i] == '/' || path[i] == '\\\\' || path[i] == ':') return path + i + 1;\n    }\n    return path;\n}\n\nstatic const char *extract_fileext(const char *path) {\n    const size_t n = strlen(path);\n    size_t i = n;\n    while (i > 0) {\n        i--;\n        if (path[i] == '/' || path[i] == '\\\\' || path[i] == ':') break;\n        if (path[i] == '.') return path + i;\n    }\n    return path + n;\n}\n\nstatic char *replace_fileext(const char *path, const char *ext) {\n    const char *const p = extract_fileext(path);\n    const size_t m = p - path;\n    const size_t n = strlen(ext);\n    char *const s = (char *)malloc_e(m + n + 2);\n    memcpy(s, path, m);\n    s[m] = '.';\n    memcpy(s + m + 1, ext, n + 1);\n    return s;\n}\n\nstatic char *add_fileext(const char *path, const char *ext) {\n    const size_t m = strlen(path);\n    const size_t n = strlen(ext);\n    char *const s = (char *)malloc_e(m + n + 2);\n    memcpy(s, path, m);\n    s[m] = '.';\n    memcpy(s + m + 1, ext, n + 1);\n    return s;\n}\n\nstatic size_t hash_string(const char *str) {\n    size_t i, h = 0;\n    for (i = 0; str[i]; i++) {\n        h = h * 31 + str[i];\n    }\n    return h;\n}\n\nstatic size_t populate_bits(size_t x) {\n    x |= x >>  1;\n    x |= x >>  2;\n    x |= x >>  4;\n    x |= x >>  8;\n    x |= x >> 16;\n#if (defined __SIZEOF_SIZE_T__ && __SIZEOF_SIZE_T__ == 8) /* gcc or clang */ || defined _WIN64 /* MSVC */\n    x |= x >> 32;\n#endif\n    return x;\n}\n\nstatic size_t column_number(const context_t *ctx) { /* 0-based */\n    assert(ctx->bufpos + ctx->bufcur >= ctx->linepos);\n    if (ctx->opts.ascii)\n        return ctx->charnum + ctx->bufcur - ((ctx->linepos > ctx->bufpos) ? ctx->linepos - ctx->bufpos : 0);\n    else\n        return ctx->charnum + count_characters(ctx->buffer.buf, (ctx->linepos > ctx->bufpos) ? ctx->linepos - ctx->bufpos : 0, ctx->bufcur);\n}\n\nstatic void char_array__init(char_array_t *array) {\n    array->len = 0;\n    array->max = 0;\n    array->buf = NULL;\n}\n\nstatic void char_array__add(char_array_t *array, char ch) {\n    if (array->max <= array->len) {\n        const size_t n = array->len + 1;\n        size_t m = array->max;\n        if (m == 0) m = BUFFER_MIN_SIZE;\n        while (m < n && m != 0) m <<= 1;\n        if (m == 0) m = n; /* in case of shift overflow */\n        array->buf = (char *)realloc_e(array->buf, m);\n        array->max = m;\n    }\n    array->buf[array->len++] = ch;\n}\n\nstatic void char_array__term(char_array_t *array) {\n    free(array->buf);\n}\n\nstatic void code_block__init(code_block_t *code) {\n    code->text = NULL;\n    code->len = 0;\n    code->line = VOID_VALUE;\n    code->col = VOID_VALUE;\n}\n\nstatic void code_block__term(code_block_t *code) {\n    free(code->text);\n}\n\nstatic void code_block_array__init(code_block_array_t *array) {\n    array->len = 0;\n    array->max = 0;\n    array->buf = NULL;\n}\n\nstatic code_block_t *code_block_array__create_entry(code_block_array_t *array) {\n    if (array->max <= array->len) {\n        const size_t n = array->len + 1;\n        size_t m = array->max;\n        if (m == 0) m = ARRAY_MIN_SIZE;\n        while (m < n && m != 0) m <<= 1;\n        if (m == 0) m = n; /* in case of shift overflow */\n        array->buf = (code_block_t *)realloc_e(array->buf, sizeof(code_block_t) * m);\n        array->max = m;\n    }\n    code_block__init(&array->buf[array->len]);\n    return &array->buf[array->len++];\n}\n\nstatic void code_block_array__term(code_block_array_t *array) {\n    while (array->len > 0) {\n        array->len--;\n        code_block__term(&array->buf[array->len]);\n    }\n    free(array->buf);\n}\n\nstatic void node_array__init(node_array_t *array) {\n    array->len = 0;\n    array->max = 0;\n    array->buf = NULL;\n}\n\nstatic void node_array__add(node_array_t *array, node_t *node) {\n    if (array->max <= array->len) {\n        const size_t n = array->len + 1;\n        size_t m = array->max;\n        if (m == 0) m = ARRAY_MIN_SIZE;\n        while (m < n && m != 0) m <<= 1;\n        if (m == 0) m = n; /* in case of shift overflow */\n        array->buf = (node_t **)realloc_e(array->buf, sizeof(node_t *) * m);\n        array->max = m;\n    }\n    array->buf[array->len++] = node;\n}\n\nstatic void destroy_node(node_t *node);\n\nstatic void node_array__term(node_array_t *array) {\n    while (array->len > 0) {\n        array->len--;\n        destroy_node(array->buf[array->len]);\n    }\n    free(array->buf);\n}\n\nstatic void node_const_array__init(node_const_array_t *array) {\n    array->len = 0;\n    array->max = 0;\n    array->buf = NULL;\n}\n\nstatic void node_const_array__add(node_const_array_t *array, const node_t *node) {\n    if (array->max <= array->len) {\n        const size_t n = array->len + 1;\n        size_t m = array->max;\n        if (m == 0) m = ARRAY_MIN_SIZE;\n        while (m < n && m != 0) m <<= 1;\n        if (m == 0) m = n; /* in case of shift overflow */\n        array->buf = (const node_t **)realloc_e((node_t **)array->buf, sizeof(const node_t *) * m);\n        array->max = m;\n    }\n    array->buf[array->len++] = node;\n}\n\nstatic void node_const_array__clear(node_const_array_t *array) {\n    array->len = 0;\n}\n\nstatic void node_const_array__copy(node_const_array_t *array, const node_const_array_t *src) {\n    size_t i;\n    node_const_array__clear(array);\n    for (i = 0; i < src->len; i++) {\n        node_const_array__add(array, src->buf[i]);\n    }\n}\n\nstatic void node_const_array__term(node_const_array_t *array) {\n    free((node_t **)array->buf);\n}\n\nstatic context_t *create_context(const char *iname, const char *oname, const options_t *opts) {\n    context_t *const ctx = (context_t *)malloc_e(sizeof(context_t));\n    ctx->iname = strdup_e((iname && iname[0]) ? iname : \"-\");\n    ctx->sname = (oname && oname[0]) ? add_fileext(oname, \"c\") : replace_fileext(ctx->iname, \"c\");\n    ctx->hname = (oname && oname[0]) ? add_fileext(oname, \"h\") : replace_fileext(ctx->iname, \"h\");\n    ctx->ifile = (iname && iname[0]) ? fopen_rb_e(ctx->iname) : stdin;\n    ctx->hid = strdup_e(ctx->hname); make_header_identifier(ctx->hid);\n    ctx->vtype = NULL;\n    ctx->atype = NULL;\n    ctx->prefix = NULL;\n    ctx->opts = *opts;\n    ctx->flags = CODE_FLAG__NONE;\n    ctx->errnum = 0;\n    ctx->linenum = 0;\n    ctx->charnum = 0;\n    ctx->linepos = 0;\n    ctx->bufpos = 0;\n    ctx->bufcur = 0;\n    char_array__init(&ctx->buffer);\n    node_array__init(&ctx->rules);\n    ctx->rulehash.mod = 0;\n    ctx->rulehash.max = 0;\n    ctx->rulehash.buf = NULL;\n    code_block_array__init(&ctx->esource);\n    code_block_array__init(&ctx->eheader);\n    code_block_array__init(&ctx->source);\n    code_block_array__init(&ctx->header);\n    return ctx;\n}\n\nstatic node_t *create_node(node_type_t type) {\n    node_t *const node = (node_t *)malloc_e(sizeof(node_t));\n    node->type = type;\n    switch (node->type) {\n    case NODE_RULE:\n        node->data.rule.name = NULL;\n        node->data.rule.expr = NULL;\n        node->data.rule.ref = 0;\n        node_const_array__init(&node->data.rule.vars);\n        node_const_array__init(&node->data.rule.capts);\n        node_const_array__init(&node->data.rule.codes);\n        node->data.rule.line = VOID_VALUE;\n        node->data.rule.col = VOID_VALUE;\n        break;\n    case NODE_REFERENCE:\n        node->data.reference.var = NULL;\n        node->data.reference.index = VOID_VALUE;\n        node->data.reference.name = NULL;\n        node->data.reference.rule = NULL;\n        node->data.reference.line = VOID_VALUE;\n        node->data.reference.col = VOID_VALUE;\n        break;\n    case NODE_STRING:\n        node->data.string.value = NULL;\n        break;\n    case NODE_CHARCLASS:\n        node->data.charclass.value = NULL;\n        break;\n    case NODE_QUANTITY:\n        node->data.quantity.min = node->data.quantity.max = 0;\n        node->data.quantity.expr = NULL;\n        break;\n    case NODE_PREDICATE:\n        node->data.predicate.neg = FALSE;\n        node->data.predicate.expr = NULL;\n        break;\n    case NODE_SEQUENCE:\n        node_array__init(&node->data.sequence.nodes);\n        break;\n    case NODE_ALTERNATE:\n        node_array__init(&node->data.alternate.nodes);\n        break;\n    case NODE_CAPTURE:\n        node->data.capture.expr = NULL;\n        node->data.capture.index = VOID_VALUE;\n        break;\n    case NODE_EXPAND:\n        node->data.expand.index = VOID_VALUE;\n        node->data.expand.line = VOID_VALUE;\n        node->data.expand.col = VOID_VALUE;\n        break;\n    case NODE_ACTION:\n        code_block__init(&node->data.action.code);\n        node->data.action.index = VOID_VALUE;\n        node_const_array__init(&node->data.action.vars);\n        node_const_array__init(&node->data.action.capts);\n        break;\n    case NODE_ERROR:\n        node->data.error.expr = NULL;\n        code_block__init(&node->data.error.code);\n        node->data.error.index = VOID_VALUE;\n        node_const_array__init(&node->data.error.vars);\n        node_const_array__init(&node->data.error.capts);\n        break;\n    default:\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    }\n    return node;\n}\n\nstatic void destroy_node(node_t *node) {\n    if (node == NULL) return;\n    switch (node->type) {\n    case NODE_RULE:\n        node_const_array__term(&node->data.rule.codes);\n        node_const_array__term(&node->data.rule.capts);\n        node_const_array__term(&node->data.rule.vars);\n        destroy_node(node->data.rule.expr);\n        free(node->data.rule.name);\n        break;\n    case NODE_REFERENCE:\n        free(node->data.reference.name);\n        free(node->data.reference.var);\n        break;\n    case NODE_STRING:\n        free(node->data.string.value);\n        break;\n    case NODE_CHARCLASS:\n        free(node->data.charclass.value);\n        break;\n    case NODE_QUANTITY:\n        destroy_node(node->data.quantity.expr);\n        break;\n    case NODE_PREDICATE:\n        destroy_node(node->data.predicate.expr);\n        break;\n    case NODE_SEQUENCE:\n        node_array__term(&node->data.sequence.nodes);\n        break;\n    case NODE_ALTERNATE:\n        node_array__term(&node->data.alternate.nodes);\n        break;\n    case NODE_CAPTURE:\n        destroy_node(node->data.capture.expr);\n        break;\n    case NODE_EXPAND:\n        break;\n    case NODE_ACTION:\n        node_const_array__term(&node->data.action.capts);\n        node_const_array__term(&node->data.action.vars);\n        code_block__term(&node->data.action.code);\n        break;\n    case NODE_ERROR:\n        node_const_array__term(&node->data.error.capts);\n        node_const_array__term(&node->data.error.vars);\n        code_block__term(&node->data.error.code);\n        destroy_node(node->data.error.expr);\n        break;\n    default:\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    }\n    free(node);\n}\n\nstatic void destroy_context(context_t *ctx) {\n    if (ctx == NULL) return;\n    code_block_array__term(&ctx->header);\n    code_block_array__term(&ctx->source);\n    code_block_array__term(&ctx->eheader);\n    code_block_array__term(&ctx->esource);\n    free((node_t **)ctx->rulehash.buf);\n    node_array__term(&ctx->rules);\n    char_array__term(&ctx->buffer);\n    free(ctx->prefix);\n    free(ctx->atype);\n    free(ctx->vtype);\n    free(ctx->hid);\n    fclose_e(ctx->ifile);\n    free(ctx->hname);\n    free(ctx->sname);\n    free(ctx->iname);\n    free(ctx);\n}\n\nstatic void make_rulehash(context_t *ctx) {\n    size_t i, j;\n    ctx->rulehash.mod = populate_bits(ctx->rules.len * 4);\n    ctx->rulehash.max = ctx->rulehash.mod + 1;\n    ctx->rulehash.buf = (const node_t **)realloc_e((node_t **)ctx->rulehash.buf, sizeof(const node_t *) * ctx->rulehash.max);\n    for (i = 0; i < ctx->rulehash.max; i++) {\n        ctx->rulehash.buf[i] = NULL;\n    }\n    for (i = 0; i < ctx->rules.len; i++) {\n        assert(ctx->rules.buf[i]->type == NODE_RULE);\n        j = hash_string(ctx->rules.buf[i]->data.rule.name) & ctx->rulehash.mod;\n        while (ctx->rulehash.buf[j] != NULL) {\n            if (strcmp(ctx->rules.buf[i]->data.rule.name, ctx->rulehash.buf[j]->data.rule.name) == 0) {\n                assert(ctx->rules.buf[i]->data.rule.ref == 0);\n                assert(ctx->rulehash.buf[j]->data.rule.ref == 0);\n                ctx->rules.buf[i]->data.rule.ref = -1;\n                goto EXCEPTION;\n            }\n            j = (j + 1) & ctx->rulehash.mod;\n        }\n        ctx->rulehash.buf[j] = ctx->rules.buf[i];\n\n    EXCEPTION:;\n    }\n}\n\nstatic const node_t *lookup_rulehash(const context_t *ctx, const char *name) {\n    size_t j = hash_string(name) & ctx->rulehash.mod;\n    while (ctx->rulehash.buf[j] != NULL && strcmp(name, ctx->rulehash.buf[j]->data.rule.name) != 0) {\n        j = (j + 1) & ctx->rulehash.mod;\n    }\n    return (ctx->rulehash.buf[j] != NULL) ? ctx->rulehash.buf[j] : NULL;\n}\n\nstatic void link_references(context_t *ctx, node_t *node) {\n    if (node == NULL) return;\n    switch (node->type) {\n    case NODE_RULE:\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    case NODE_REFERENCE:\n        node->data.reference.rule = lookup_rulehash(ctx, node->data.reference.name);\n        if (node->data.reference.rule == NULL) {\n            print_error(\"%s:\" FMT_LU \":\" FMT_LU \": No definition of rule '%s'\\n\",\n                ctx->iname, (ulong_t)(node->data.reference.line + 1), (ulong_t)(node->data.reference.col + 1),\n                node->data.reference.name);\n            ctx->errnum++;\n        }\n        else {\n            assert(node->data.reference.rule->type == NODE_RULE);\n            ((node_t *)node->data.reference.rule)->data.rule.ref++;\n        }\n        break;\n    case NODE_STRING:\n        break;\n    case NODE_CHARCLASS:\n        break;\n    case NODE_QUANTITY:\n        link_references(ctx, node->data.quantity.expr);\n        break;\n    case NODE_PREDICATE:\n        link_references(ctx, node->data.predicate.expr);\n        break;\n    case NODE_SEQUENCE:\n        {\n            size_t i;\n            for (i = 0; i < node->data.sequence.nodes.len; i++) {\n                link_references(ctx, node->data.sequence.nodes.buf[i]);\n            }\n        }\n        break;\n    case NODE_ALTERNATE:\n        {\n            size_t i;\n            for (i = 0; i < node->data.alternate.nodes.len; i++) {\n                link_references(ctx, node->data.alternate.nodes.buf[i]);\n            }\n        }\n        break;\n    case NODE_CAPTURE:\n        link_references(ctx, node->data.capture.expr);\n        break;\n    case NODE_EXPAND:\n        break;\n    case NODE_ACTION:\n        break;\n    case NODE_ERROR:\n        link_references(ctx, node->data.error.expr);\n        break;\n    default:\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    }\n}\n\nstatic void verify_variables(context_t *ctx, node_t *node, node_const_array_t *vars) {\n    node_const_array_t a;\n    const bool_t b = (vars == NULL) ? TRUE : FALSE;\n    if (node == NULL) return;\n    if (b) {\n        node_const_array__init(&a);\n        vars = &a;\n    }\n    switch (node->type) {\n    case NODE_RULE:\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    case NODE_REFERENCE:\n        if (node->data.reference.index != VOID_VALUE) {\n            size_t i;\n            for (i = 0; i < vars->len; i++) {\n                assert(vars->buf[i]->type == NODE_REFERENCE);\n                if (node->data.reference.index == vars->buf[i]->data.reference.index) break;\n            }\n            if (i == vars->len) node_const_array__add(vars, node);\n        }\n        break;\n    case NODE_STRING:\n        break;\n    case NODE_CHARCLASS:\n        break;\n    case NODE_QUANTITY:\n        verify_variables(ctx, node->data.quantity.expr, vars);\n        break;\n    case NODE_PREDICATE:\n        verify_variables(ctx, node->data.predicate.expr, vars);\n        break;\n    case NODE_SEQUENCE:\n        {\n            size_t i;\n            for (i = 0; i < node->data.sequence.nodes.len; i++) {\n                verify_variables(ctx, node->data.sequence.nodes.buf[i], vars);\n            }\n        }\n        break;\n    case NODE_ALTERNATE:\n        {\n            size_t i, j, k, m = vars->len;\n            node_const_array_t v;\n            node_const_array__init(&v);\n            node_const_array__copy(&v, vars);\n            for (i = 0; i < node->data.alternate.nodes.len; i++) {\n                v.len = m;\n                verify_variables(ctx, node->data.alternate.nodes.buf[i], &v);\n                for (j = m; j < v.len; j++) {\n                    for (k = m; k < vars->len; k++) {\n                        if (v.buf[j]->data.reference.index == vars->buf[k]->data.reference.index) break;\n                    }\n                    if (k == vars->len) node_const_array__add(vars, v.buf[j]);\n                }\n            }\n            node_const_array__term(&v);\n        }\n        break;\n    case NODE_CAPTURE:\n        verify_variables(ctx, node->data.capture.expr, vars);\n        break;\n    case NODE_EXPAND:\n        break;\n    case NODE_ACTION:\n        node_const_array__copy(&node->data.action.vars, vars);\n        break;\n    case NODE_ERROR:\n        node_const_array__copy(&node->data.error.vars, vars);\n        verify_variables(ctx, node->data.error.expr, vars);\n        break;\n    default:\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    }\n    if (b) {\n        node_const_array__term(&a);\n    }\n}\n\nstatic void verify_captures(context_t *ctx, node_t *node, node_const_array_t *capts) {\n    node_const_array_t a;\n    const bool_t b = (capts == NULL) ? TRUE : FALSE;\n    if (node == NULL) return;\n    if (b) {\n        node_const_array__init(&a);\n        capts = &a;\n    }\n    switch (node->type) {\n    case NODE_RULE:\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    case NODE_REFERENCE:\n        break;\n    case NODE_STRING:\n        break;\n    case NODE_CHARCLASS:\n        break;\n    case NODE_QUANTITY:\n        verify_captures(ctx, node->data.quantity.expr, capts);\n        break;\n    case NODE_PREDICATE:\n        verify_captures(ctx, node->data.predicate.expr, capts);\n        break;\n    case NODE_SEQUENCE:\n        {\n            size_t i;\n            for (i = 0; i < node->data.sequence.nodes.len; i++) {\n                verify_captures(ctx, node->data.sequence.nodes.buf[i], capts);\n            }\n        }\n        break;\n    case NODE_ALTERNATE:\n        {\n            size_t i, j, m = capts->len;\n            node_const_array_t v;\n            node_const_array__init(&v);\n            node_const_array__copy(&v, capts);\n            for (i = 0; i < node->data.alternate.nodes.len; i++) {\n                v.len = m;\n                verify_captures(ctx, node->data.alternate.nodes.buf[i], &v);\n                for (j = m; j < v.len; j++) {\n                    node_const_array__add(capts, v.buf[j]);\n                }\n            }\n            node_const_array__term(&v);\n        }\n        break;\n    case NODE_CAPTURE:\n        verify_captures(ctx, node->data.capture.expr, capts);\n        node_const_array__add(capts, node);\n        break;\n    case NODE_EXPAND:\n        {\n            size_t i;\n            for (i = 0; i < capts->len; i++) {\n                assert(capts->buf[i]->type == NODE_CAPTURE);\n                if (node->data.expand.index == capts->buf[i]->data.capture.index) break;\n            }\n            if (i >= capts->len && node->data.expand.index != VOID_VALUE) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Capture \" FMT_LU \" not available at this position\\n\",\n                    ctx->iname, (ulong_t)(node->data.expand.line + 1), (ulong_t)(node->data.expand.col + 1), (ulong_t)(node->data.expand.index + 1));\n                ctx->errnum++;\n            }\n        }\n        break;\n    case NODE_ACTION:\n        node_const_array__copy(&node->data.action.capts, capts);\n        break;\n    case NODE_ERROR:\n        node_const_array__copy(&node->data.error.capts, capts);\n        verify_captures(ctx, node->data.error.expr, capts);\n        break;\n    default:\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    }\n    if (b) {\n        node_const_array__term(&a);\n    }\n}\n\nstatic void dump_escaped_string(const char *str) {\n    char s[5];\n    if (str == NULL) {\n        fprintf(stdout, \"null\");\n        return;\n    }\n    while (*str) {\n        fprintf(stdout, \"%s\", escape_character(*str++, &s));\n    }\n}\n\nstatic void dump_integer_value(size_t value) {\n    if (value == VOID_VALUE) {\n        fprintf(stdout, \"void\");\n    }\n    else {\n        fprintf(stdout, FMT_LU, (ulong_t)value);\n    }\n}\n\nstatic void dump_node(context_t *ctx, const node_t *node, const int indent) {\n    if (node == NULL) return;\n    switch (node->type) {\n    case NODE_RULE:\n        fprintf(stdout, \"%*sRule(name:'%s', ref:%d, vars.len:\" FMT_LU \", capts.len:\" FMT_LU \", codes.len:\" FMT_LU \") {\\n\",\n            indent, \"\", node->data.rule.name, node->data.rule.ref,\n            (ulong_t)node->data.rule.vars.len, (ulong_t)node->data.rule.capts.len, (ulong_t)node->data.rule.codes.len);\n        dump_node(ctx, node->data.rule.expr, indent + 2);\n        fprintf(stdout, \"%*s}\\n\", indent, \"\");\n        break;\n    case NODE_REFERENCE:\n        fprintf(stdout, \"%*sReference(var:'%s', index:\", indent, \"\", node->data.reference.var);\n        dump_integer_value(node->data.reference.index);\n        fprintf(stdout, \", name:'%s', rule:'%s')\\n\", node->data.reference.name,\n            (node->data.reference.rule) ? node->data.reference.rule->data.rule.name : NULL);\n        break;\n    case NODE_STRING:\n        fprintf(stdout, \"%*sString(value:'\", indent, \"\");\n        dump_escaped_string(node->data.string.value);\n        fprintf(stdout, \"')\\n\");\n        break;\n    case NODE_CHARCLASS:\n        fprintf(stdout, \"%*sCharclass(value:'\", indent, \"\");\n        dump_escaped_string(node->data.charclass.value);\n        fprintf(stdout, \"')\\n\");\n        break;\n    case NODE_QUANTITY:\n        fprintf(stdout, \"%*sQuantity(min:%d, max:%d) {\\n\", indent, \"\", node->data.quantity.min, node->data.quantity.max);\n        dump_node(ctx, node->data.quantity.expr, indent + 2);\n        fprintf(stdout, \"%*s}\\n\", indent, \"\");\n        break;\n    case NODE_PREDICATE:\n        fprintf(stdout, \"%*sPredicate(neg:%d) {\\n\", indent, \"\", node->data.predicate.neg);\n        dump_node(ctx, node->data.predicate.expr, indent + 2);\n        fprintf(stdout, \"%*s}\\n\", indent, \"\");\n        break;\n    case NODE_SEQUENCE:\n        fprintf(stdout, \"%*sSequence(max:\" FMT_LU \", len:\" FMT_LU \") {\\n\",\n            indent, \"\", (ulong_t)node->data.sequence.nodes.max, (ulong_t)node->data.sequence.nodes.len);\n        {\n            size_t i;\n            for (i = 0; i < node->data.sequence.nodes.len; i++) {\n                dump_node(ctx, node->data.sequence.nodes.buf[i], indent + 2);\n            }\n        }\n        fprintf(stdout, \"%*s}\\n\", indent, \"\");\n        break;\n    case NODE_ALTERNATE:\n        fprintf(stdout, \"%*sAlternate(max:\" FMT_LU \", len:\" FMT_LU \") {\\n\",\n            indent, \"\", (ulong_t)node->data.alternate.nodes.max, (ulong_t)node->data.alternate.nodes.len);\n        {\n            size_t i;\n            for (i = 0; i < node->data.alternate.nodes.len; i++) {\n                dump_node(ctx, node->data.alternate.nodes.buf[i], indent + 2);\n            }\n        }\n        fprintf(stdout, \"%*s}\\n\", indent, \"\");\n        break;\n    case NODE_CAPTURE:\n        fprintf(stdout, \"%*sCapture(index:\", indent, \"\");\n        dump_integer_value(node->data.capture.index);\n        fprintf(stdout, \") {\\n\");\n        dump_node(ctx, node->data.capture.expr, indent + 2);\n        fprintf(stdout, \"%*s}\\n\", indent, \"\");\n        break;\n    case NODE_EXPAND:\n        fprintf(stdout, \"%*sExpand(index:\", indent, \"\");\n        dump_integer_value(node->data.expand.index);\n        fprintf(stdout, \")\\n\");\n        break;\n    case NODE_ACTION:\n        fprintf(stdout, \"%*sAction(index:\", indent, \"\");\n        dump_integer_value(node->data.action.index);\n        fprintf(stdout, \", code:{\");\n        dump_escaped_string(node->data.action.code.text);\n        fprintf(stdout, \"}, vars:\");\n        if (node->data.action.vars.len + node->data.action.capts.len > 0) {\n            size_t i;\n            fprintf(stdout, \"\\n\");\n            for (i = 0; i < node->data.action.vars.len; i++) {\n                fprintf(stdout, \"%*s'%s'\\n\", indent + 2, \"\", node->data.action.vars.buf[i]->data.reference.var);\n            }\n            for (i = 0; i < node->data.action.capts.len; i++) {\n                fprintf(stdout, \"%*s$\" FMT_LU \"\\n\", indent + 2, \"\", (ulong_t)(node->data.action.capts.buf[i]->data.capture.index + 1));\n            }\n            fprintf(stdout, \"%*s)\\n\", indent, \"\");\n        }\n        else {\n            fprintf(stdout, \"none)\\n\");\n        }\n        break;\n    case NODE_ERROR:\n        fprintf(stdout, \"%*sError(index:\", indent, \"\");\n        dump_integer_value(node->data.error.index);\n        fprintf(stdout, \", code:{\");\n        dump_escaped_string(node->data.error.code.text);\n        fprintf(stdout, \"}, vars:\\n\");\n        {\n            size_t i;\n            for (i = 0; i < node->data.error.vars.len; i++) {\n                fprintf(stdout, \"%*s'%s'\\n\", indent + 2, \"\", node->data.error.vars.buf[i]->data.reference.var);\n            }\n            for (i = 0; i < node->data.error.capts.len; i++) {\n                fprintf(stdout, \"%*s$\" FMT_LU \"\\n\", indent + 2, \"\", (ulong_t)(node->data.error.capts.buf[i]->data.capture.index + 1));\n            }\n        }\n        fprintf(stdout, \"%*s) {\\n\", indent, \"\");\n        dump_node(ctx, node->data.error.expr, indent + 2);\n        fprintf(stdout, \"%*s}\\n\", indent, \"\");\n        break;\n    default:\n        print_error(\"%*sInternal error [%d]\\n\", indent, \"\", __LINE__);\n        exit(-1);\n    }\n}\n\nstatic size_t refill_buffer(context_t *ctx, size_t num) {\n    if (ctx->buffer.len >= ctx->bufcur + num) return ctx->buffer.len - ctx->bufcur;\n    while (ctx->buffer.len < ctx->bufcur + num) {\n        const int c = fgetc_e(ctx->ifile);\n        if (c == EOF) break;\n        char_array__add(&ctx->buffer, (char)c);\n    }\n    return ctx->buffer.len - ctx->bufcur;\n}\n\nstatic void commit_buffer(context_t *ctx) {\n    assert(ctx->buffer.len >= ctx->bufcur);\n    if (ctx->linepos < ctx->bufpos + ctx->bufcur)\n        ctx->charnum += ctx->opts.ascii ? ctx->bufcur : count_characters(ctx->buffer.buf, 0, ctx->bufcur);\n    memmove(ctx->buffer.buf, ctx->buffer.buf + ctx->bufcur, ctx->buffer.len - ctx->bufcur);\n    ctx->buffer.len -= ctx->bufcur;\n    ctx->bufpos += ctx->bufcur;\n    ctx->bufcur = 0;\n}\n\nstatic bool_t match_eof(context_t *ctx) {\n    return (refill_buffer(ctx, 1) < 1) ? TRUE : FALSE;\n}\n\nstatic bool_t match_eol(context_t *ctx) {\n    if (refill_buffer(ctx, 1) >= 1) {\n        switch (ctx->buffer.buf[ctx->bufcur]) {\n        case '\\n':\n            ctx->bufcur++;\n            ctx->linenum++;\n            ctx->charnum = 0;\n            ctx->linepos = ctx->bufpos + ctx->bufcur;\n            return TRUE;\n        case '\\r':\n            ctx->bufcur++;\n            if (refill_buffer(ctx, 1) >= 1) {\n                if (ctx->buffer.buf[ctx->bufcur] == '\\n') ctx->bufcur++;\n            }\n            ctx->linenum++;\n            ctx->charnum = 0;\n            ctx->linepos = ctx->bufpos + ctx->bufcur;\n            return TRUE;\n        }\n    }\n    return FALSE;\n}\n\nstatic bool_t match_character(context_t *ctx, char ch) {\n    if (refill_buffer(ctx, 1) >= 1) {\n        if (ctx->buffer.buf[ctx->bufcur] == ch) {\n            ctx->bufcur++;\n            return TRUE;\n        }\n    }\n    return FALSE;\n}\n\nstatic bool_t match_character_range(context_t *ctx, char min, char max) {\n    if (refill_buffer(ctx, 1) >= 1) {\n        const char c = ctx->buffer.buf[ctx->bufcur];\n        if (c >= min && c <= max) {\n            ctx->bufcur++;\n            return TRUE;\n        }\n    }\n    return FALSE;\n}\n\nstatic bool_t match_character_set(context_t *ctx, const char *chs) {\n    if (refill_buffer(ctx, 1) >= 1) {\n        const char c = ctx->buffer.buf[ctx->bufcur];\n        size_t i;\n        for (i = 0; chs[i]; i++) {\n            if (c == chs[i]) {\n                ctx->bufcur++;\n                return TRUE;\n            }\n        }\n    }\n    return FALSE;\n}\n\nstatic bool_t match_character_any(context_t *ctx) {\n    if (refill_buffer(ctx, 1) >= 1) {\n        ctx->bufcur++;\n        return TRUE;\n    }\n    return FALSE;\n}\n\nstatic bool_t match_string(context_t *ctx, const char *str) {\n    const size_t n = strlen(str);\n    if (refill_buffer(ctx, n) >= n) {\n        if (strncmp(ctx->buffer.buf + ctx->bufcur, str, n) == 0) {\n            ctx->bufcur += n;\n            return TRUE;\n        }\n    }\n    return FALSE;\n}\n\nstatic bool_t match_blank(context_t *ctx) {\n    return match_character_set(ctx, \" \\t\\v\\f\");\n}\n\nstatic bool_t match_section_line_(context_t *ctx, const char *head) {\n    if (match_string(ctx, head)) {\n        while (!match_eol(ctx) && !match_eof(ctx)) match_character_any(ctx);\n        return TRUE;\n    }\n    return FALSE;\n}\n\nstatic bool_t match_section_line_continuable_(context_t *ctx, const char *head) {\n    if (match_string(ctx, head)) {\n        while (!match_eof(ctx)) {\n            const size_t p = ctx->bufcur;\n            if (match_eol(ctx)) {\n                if (ctx->buffer.buf[p - 1] != '\\\\') break;\n            }\n            else {\n                match_character_any(ctx);\n            }\n        }\n        return TRUE;\n    }\n    return FALSE;\n}\n\nstatic bool_t match_section_block_(context_t *ctx, const char *left, const char *right, const char *name) {\n    const size_t l = ctx->linenum;\n    const size_t m = column_number(ctx);\n    if (match_string(ctx, left)) {\n        while (!match_string(ctx, right)) {\n            if (match_eof(ctx)) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Premature EOF in %s\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1), name);\n                ctx->errnum++;\n                break;\n            }\n            if (!match_eol(ctx)) match_character_any(ctx);\n        }\n        return TRUE;\n    }\n    return FALSE;\n}\n\nstatic bool_t match_quotation_(context_t *ctx, const char *left, const char *right, const char *name) {\n    const size_t l = ctx->linenum;\n    const size_t m = column_number(ctx);\n    if (match_string(ctx, left)) {\n        while (!match_string(ctx, right)) {\n            if (match_eof(ctx)) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Premature EOF in %s\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1), name);\n                ctx->errnum++;\n                break;\n            }\n            if (match_character(ctx, '\\\\')) {\n                if (!match_eol(ctx)) match_character_any(ctx);\n            }\n            else {\n                if (match_eol(ctx)) {\n                    print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Premature EOL in %s\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1), name);\n                    ctx->errnum++;\n                    break;\n                }\n                match_character_any(ctx);\n            }\n        }\n        return TRUE;\n    }\n    return FALSE;\n}\n\nstatic bool_t match_directive_c(context_t *ctx) {\n    return match_section_line_continuable_(ctx, \"#\");\n}\n\nstatic bool_t match_comment(context_t *ctx) {\n    return match_section_line_(ctx, \"#\");\n}\n\nstatic bool_t match_comment_c(context_t *ctx) {\n    return match_section_block_(ctx, \"/*\", \"*/\", \"C comment\");\n}\n\nstatic bool_t match_comment_cxx(context_t *ctx) {\n    return match_section_line_(ctx, \"//\");\n}\n\nstatic bool_t match_quotation_single(context_t *ctx) {\n    return match_quotation_(ctx, \"\\'\", \"\\'\", \"single quotation\");\n}\n\nstatic bool_t match_quotation_double(context_t *ctx) {\n    return match_quotation_(ctx, \"\\\"\", \"\\\"\", \"double quotation\");\n}\n\nstatic bool_t match_character_class(context_t *ctx) {\n    return match_quotation_(ctx, \"[\", \"]\", \"character class\");\n}\n\nstatic bool_t match_spaces(context_t *ctx) {\n    size_t n = 0;\n    while (match_blank(ctx) || match_eol(ctx) || match_comment(ctx)) n++;\n    return (n > 0) ? TRUE : FALSE;\n}\n\nstatic bool_t match_number(context_t *ctx) {\n    if (match_character_range(ctx, '0', '9')) {\n        while (match_character_range(ctx, '0', '9'));\n        return TRUE;\n    }\n    return FALSE;\n}\n\nstatic bool_t match_identifier(context_t *ctx) {\n    if (\n        match_character_range(ctx, 'a', 'z') ||\n        match_character_range(ctx, 'A', 'Z') ||\n        match_character(ctx, '_')\n    ) {\n        while (\n            match_character_range(ctx, 'a', 'z') ||\n            match_character_range(ctx, 'A', 'Z') ||\n            match_character_range(ctx, '0', '9') ||\n            match_character(ctx, '_')\n        );\n        return TRUE;\n    }\n    return FALSE;\n}\n\nstatic bool_t match_code_block(context_t *ctx) {\n    const size_t l = ctx->linenum;\n    const size_t m = column_number(ctx);\n    if (match_character(ctx, '{')) {\n        int d = 1;\n        for (;;) {\n            if (match_eof(ctx)) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Premature EOF in code block\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1));\n                ctx->errnum++;\n                break;\n            }\n            if (\n                match_directive_c(ctx) ||\n                match_comment_c(ctx) ||\n                match_comment_cxx(ctx) ||\n                match_quotation_single(ctx) ||\n                match_quotation_double(ctx)\n            ) continue;\n            if (match_character(ctx, '{')) {\n                d++;\n            }\n            else if (match_character(ctx, '}')) {\n                d--;\n                if (d == 0) break;\n            }\n            else {\n                if (!match_eol(ctx)) {\n                    if (match_character(ctx, '$')) {\n                        ctx->buffer.buf[ctx->bufcur - 1] = '_';\n                    }\n                    else {\n                        match_character_any(ctx);\n                    }\n                }\n            }\n        }\n        return TRUE;\n    }\n    return FALSE;\n}\n\nstatic bool_t match_footer_start(context_t *ctx) {\n    return match_string(ctx, \"%%\");\n}\n\nstatic node_t *parse_expression(context_t *ctx, node_t *rule);\n\nstatic node_t *parse_primary(context_t *ctx, node_t *rule) {\n    const size_t p = ctx->bufcur;\n    const size_t l = ctx->linenum;\n    const size_t m = column_number(ctx);\n    const size_t n = ctx->charnum;\n    const size_t o = ctx->linepos;\n    node_t *n_p = NULL;\n    if (match_identifier(ctx)) {\n        const size_t q = ctx->bufcur;\n        size_t r = VOID_VALUE, s = VOID_VALUE;\n        match_spaces(ctx);\n        if (match_character(ctx, ':')) {\n            match_spaces(ctx);\n            r = ctx->bufcur;\n            if (!match_identifier(ctx)) goto EXCEPTION;\n            s = ctx->bufcur;\n            match_spaces(ctx);\n        }\n        if (match_string(ctx, \"<-\")) goto EXCEPTION;\n        n_p = create_node(NODE_REFERENCE);\n        if (r == VOID_VALUE) {\n            assert(q >= p);\n            n_p->data.reference.var = NULL;\n            n_p->data.reference.index = VOID_VALUE;\n            n_p->data.reference.name = strndup_e(ctx->buffer.buf + p, q - p);\n        }\n        else {\n            assert(s != VOID_VALUE); /* s should have a valid value when r has a valid value */\n            assert(q >= p);\n            n_p->data.reference.var = strndup_e(ctx->buffer.buf + p, q - p);\n            if (n_p->data.reference.var[0] == '_') {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Leading underscore in variable name '%s'\\n\",\n                    ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1), n_p->data.reference.var);\n                ctx->errnum++;\n            }\n            {\n                size_t i;\n                for (i = 0; i < rule->data.rule.vars.len; i++) {\n                    assert(rule->data.rule.vars.buf[i]->type == NODE_REFERENCE);\n                    if (strcmp(n_p->data.reference.var, rule->data.rule.vars.buf[i]->data.reference.var) == 0) break;\n                }\n                if (i == rule->data.rule.vars.len) node_const_array__add(&rule->data.rule.vars, n_p);\n                n_p->data.reference.index = i;\n            }\n            assert(s >= r);\n            n_p->data.reference.name = strndup_e(ctx->buffer.buf + r, s - r);\n        }\n        n_p->data.reference.line = l;\n        n_p->data.reference.col = m;\n    }\n    else if (match_character(ctx, '(')) {\n        match_spaces(ctx);\n        n_p = parse_expression(ctx, rule);\n        if (n_p == NULL) goto EXCEPTION;\n        if (!match_character(ctx, ')')) goto EXCEPTION;\n        match_spaces(ctx);\n    }\n    else if (match_character(ctx, '<')) {\n        match_spaces(ctx);\n        n_p = create_node(NODE_CAPTURE);\n        n_p->data.capture.index = rule->data.rule.capts.len;\n        node_const_array__add(&rule->data.rule.capts, n_p);\n        n_p->data.capture.expr = parse_expression(ctx, rule);\n        if (n_p->data.capture.expr == NULL || !match_character(ctx, '>')) {\n            rule->data.rule.capts.len = n_p->data.capture.index;\n            goto EXCEPTION;\n        }\n        match_spaces(ctx);\n    }\n    else if (match_character(ctx, '$')) {\n        size_t p;\n        match_spaces(ctx);\n        p = ctx->bufcur;\n        if (match_number(ctx)) {\n            const size_t q = ctx->bufcur;\n            char *s;\n            match_spaces(ctx);\n            n_p = create_node(NODE_EXPAND);\n            assert(q >= p);\n            s = strndup_e(ctx->buffer.buf + p, q - p);\n            n_p->data.expand.index = string_to_size_t(s);\n            if (n_p->data.expand.index == VOID_VALUE) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Invalid unsigned number '%s'\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1), s);\n                ctx->errnum++;\n            }\n            else if (n_p->data.expand.index == 0) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": 0 not allowed\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1));\n                ctx->errnum++;\n            }\n            else if (s[0] == '0') {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": 0-prefixed number not allowed\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1));\n                ctx->errnum++;\n                n_p->data.expand.index = 0;\n            }\n            free(s);\n            if (n_p->data.expand.index > 0 && n_p->data.expand.index != VOID_VALUE) {\n                n_p->data.expand.index--;\n                n_p->data.expand.line = l;\n                n_p->data.expand.col = m;\n            }\n        }\n        else {\n            goto EXCEPTION;\n        }\n    }\n    else if (match_character(ctx, '.')) {\n        match_spaces(ctx);\n        n_p = create_node(NODE_CHARCLASS);\n        n_p->data.charclass.value = NULL;\n        if (!ctx->opts.ascii) {\n            ctx->flags |= CODE_FLAG__UTF8_CHARCLASS_USED;\n        }\n    }\n    else if (match_character_class(ctx)) {\n        const size_t q = ctx->bufcur;\n        match_spaces(ctx);\n        n_p = create_node(NODE_CHARCLASS);\n        n_p->data.charclass.value = strndup_e(ctx->buffer.buf + p + 1, q - p - 2);\n        if (!unescape_string(n_p->data.charclass.value, TRUE)) {\n            print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Illegal escape sequence\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1));\n            ctx->errnum++;\n        }\n        if (!ctx->opts.ascii && !is_valid_utf8_string(n_p->data.charclass.value)) {\n            print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Invalid UTF-8 string\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1));\n            ctx->errnum++;\n        }\n        if (!ctx->opts.ascii && n_p->data.charclass.value[0] != '\\0') {\n            ctx->flags |= CODE_FLAG__UTF8_CHARCLASS_USED;\n        }\n    }\n    else if (match_quotation_single(ctx) || match_quotation_double(ctx)) {\n        const size_t q = ctx->bufcur;\n        match_spaces(ctx);\n        n_p = create_node(NODE_STRING);\n        n_p->data.string.value = strndup_e(ctx->buffer.buf + p + 1, q - p - 2);\n        if (!unescape_string(n_p->data.string.value, FALSE)) {\n            print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Illegal escape sequence\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1));\n            ctx->errnum++;\n        }\n        if (!ctx->opts.ascii && !is_valid_utf8_string(n_p->data.string.value)) {\n            print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Invalid UTF-8 string\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1));\n            ctx->errnum++;\n        }\n    }\n    else if (match_code_block(ctx)) {\n        const size_t q = ctx->bufcur;\n        match_spaces(ctx);\n        n_p = create_node(NODE_ACTION);\n        n_p->data.action.code.text = strndup_e(ctx->buffer.buf + p + 1, q - p - 2);\n        n_p->data.action.code.len = find_trailing_blanks(n_p->data.action.code.text);\n        n_p->data.action.code.line = l;\n        n_p->data.action.code.col = m;\n        n_p->data.action.index = rule->data.rule.codes.len;\n        node_const_array__add(&rule->data.rule.codes, n_p);\n    }\n    else {\n        goto EXCEPTION;\n    }\n    return n_p;\n\nEXCEPTION:;\n    destroy_node(n_p);\n    ctx->bufcur = p;\n    ctx->linenum = l;\n    ctx->charnum = n;\n    ctx->linepos = o;\n    return NULL;\n}\n\nstatic node_t *parse_term(context_t *ctx, node_t *rule) {\n    const size_t p = ctx->bufcur;\n    const size_t l = ctx->linenum;\n    const size_t n = ctx->charnum;\n    const size_t o = ctx->linepos;\n    node_t *n_p = NULL;\n    node_t *n_q = NULL;\n    node_t *n_r = NULL;\n    node_t *n_t = NULL;\n    const char t = match_character(ctx, '&') ? '&' : match_character(ctx, '!') ? '!' : '\\0';\n    if (t) match_spaces(ctx);\n    n_p = parse_primary(ctx, rule);\n    if (n_p == NULL) goto EXCEPTION;\n    if (match_character(ctx, '*')) {\n        match_spaces(ctx);\n        n_q = create_node(NODE_QUANTITY);\n        n_q->data.quantity.min = 0;\n        n_q->data.quantity.max = -1;\n        n_q->data.quantity.expr = n_p;\n    }\n    else if (match_character(ctx, '+')) {\n        match_spaces(ctx);\n        n_q = create_node(NODE_QUANTITY);\n        n_q->data.quantity.min = 1;\n        n_q->data.quantity.max = -1;\n        n_q->data.quantity.expr = n_p;\n    }\n    else if (match_character(ctx, '?')) {\n        match_spaces(ctx);\n        n_q = create_node(NODE_QUANTITY);\n        n_q->data.quantity.min = 0;\n        n_q->data.quantity.max = 1;\n        n_q->data.quantity.expr = n_p;\n    }\n    else {\n        n_q = n_p;\n    }\n    switch (t) {\n    case '&':\n        n_r = create_node(NODE_PREDICATE);\n        n_r->data.predicate.neg = FALSE;\n        n_r->data.predicate.expr = n_q;\n        break;\n    case '!':\n        n_r = create_node(NODE_PREDICATE);\n        n_r->data.predicate.neg = TRUE;\n        n_r->data.predicate.expr = n_q;\n        break;\n    default:\n        n_r = n_q;\n    }\n    if (match_character(ctx, '~')) {\n        size_t p, l, m;\n        match_spaces(ctx);\n        p = ctx->bufcur;\n        l = ctx->linenum;\n        m = column_number(ctx);\n        if (match_code_block(ctx)) {\n            const size_t q = ctx->bufcur;\n            match_spaces(ctx);\n            n_t = create_node(NODE_ERROR);\n            n_t->data.error.expr = n_r;\n            n_t->data.error.code.text = strndup_e(ctx->buffer.buf + p + 1, q - p - 2);\n            n_t->data.error.code.len = find_trailing_blanks(n_t->data.error.code.text);\n            n_t->data.error.code.line = l;\n            n_t->data.error.code.col = m;\n            n_t->data.error.index = rule->data.rule.codes.len;\n            node_const_array__add(&rule->data.rule.codes, n_t);\n        }\n        else {\n            goto EXCEPTION;\n        }\n    }\n    else {\n        n_t = n_r;\n    }\n    return n_t;\n\nEXCEPTION:;\n    destroy_node(n_r);\n    ctx->bufcur = p;\n    ctx->linenum = l;\n    ctx->charnum = n;\n    ctx->linepos = o;\n    return NULL;\n}\n\nstatic node_t *parse_sequence(context_t *ctx, node_t *rule) {\n    const size_t p = ctx->bufcur;\n    const size_t l = ctx->linenum;\n    const size_t n = ctx->charnum;\n    const size_t o = ctx->linepos;\n    node_array_t *a_t = NULL;\n    node_t *n_t = NULL;\n    node_t *n_u = NULL;\n    node_t *n_s = NULL;\n    n_t = parse_term(ctx, rule);\n    if (n_t == NULL) goto EXCEPTION;\n    n_u = parse_term(ctx, rule);\n    if (n_u != NULL) {\n        n_s = create_node(NODE_SEQUENCE);\n        a_t = &n_s->data.sequence.nodes;\n        node_array__add(a_t, n_t);\n        node_array__add(a_t, n_u);\n        while ((n_t = parse_term(ctx, rule)) != NULL) {\n            node_array__add(a_t, n_t);\n        }\n    }\n    else {\n        n_s = n_t;\n    }\n    return n_s;\n\nEXCEPTION:;\n    ctx->bufcur = p;\n    ctx->linenum = l;\n    ctx->charnum = n;\n    ctx->linepos = o;\n    return NULL;\n}\n\nstatic node_t *parse_expression(context_t *ctx, node_t *rule) {\n    const size_t p = ctx->bufcur;\n    const size_t l = ctx->linenum;\n    const size_t n = ctx->charnum;\n    const size_t o = ctx->linepos;\n    size_t q;\n    node_array_t *a_s = NULL;\n    node_t *n_s = NULL;\n    node_t *n_e = NULL;\n    n_s = parse_sequence(ctx, rule);\n    if (n_s == NULL) goto EXCEPTION;\n    q = ctx->bufcur;\n    if (match_character(ctx, '/')) {\n        ctx->bufcur = q;\n        n_e = create_node(NODE_ALTERNATE);\n        a_s = &n_e->data.alternate.nodes;\n        node_array__add(a_s, n_s);\n        while (match_character(ctx, '/')) {\n            match_spaces(ctx);\n            n_s = parse_sequence(ctx, rule);\n            if (n_s == NULL) goto EXCEPTION;\n            node_array__add(a_s, n_s);\n        }\n    }\n    else {\n        n_e = n_s;\n    }\n    return n_e;\n\nEXCEPTION:;\n    destroy_node(n_e);\n    ctx->bufcur = p;\n    ctx->linenum = l;\n    ctx->charnum = n;\n    ctx->linepos = o;\n    return NULL;\n}\n\nstatic node_t *parse_rule(context_t *ctx) {\n    const size_t p = ctx->bufcur;\n    const size_t l = ctx->linenum;\n    const size_t m = column_number(ctx);\n    const size_t n = ctx->charnum;\n    const size_t o = ctx->linepos;\n    size_t q;\n    node_t *n_r = NULL;\n    if (!match_identifier(ctx)) goto EXCEPTION;\n    q = ctx->bufcur;\n    match_spaces(ctx);\n    if (!match_string(ctx, \"<-\")) goto EXCEPTION;\n    match_spaces(ctx);\n    n_r = create_node(NODE_RULE);\n    n_r->data.rule.expr = parse_expression(ctx, n_r);\n    if (n_r->data.rule.expr == NULL) goto EXCEPTION;\n    assert(q >= p);\n    n_r->data.rule.name = strndup_e(ctx->buffer.buf + p, q - p);\n    n_r->data.rule.line = l;\n    n_r->data.rule.col = m;\n    return n_r;\n\nEXCEPTION:;\n    destroy_node(n_r);\n    ctx->bufcur = p;\n    ctx->linenum = l;\n    ctx->charnum = n;\n    ctx->linepos = o;\n    return NULL;\n}\n\nstatic const char *get_value_type(context_t *ctx) {\n    return (ctx->vtype && ctx->vtype[0]) ? ctx->vtype : \"int\";\n}\n\nstatic const char *get_auxil_type(context_t *ctx) {\n    return (ctx->atype && ctx->atype[0]) ? ctx->atype : \"void *\";\n}\n\nstatic const char *get_prefix(context_t *ctx) {\n    return (ctx->prefix && ctx->prefix[0]) ? ctx->prefix : \"pcc\";\n}\n\nstatic void dump_options(context_t *ctx) {\n    fprintf(stdout, \"value_type: '%s'\\n\", get_value_type(ctx));\n    fprintf(stdout, \"auxil_type: '%s'\\n\", get_auxil_type(ctx));\n    fprintf(stdout, \"prefix: '%s'\\n\", get_prefix(ctx));\n}\n\nstatic bool_t parse_directive_include_(context_t *ctx, const char *name, code_block_array_t *output1, code_block_array_t *output2) {\n    if (!match_string(ctx, name)) return FALSE;\n    match_spaces(ctx);\n    {\n        const size_t p = ctx->bufcur;\n        const size_t l = ctx->linenum;\n        const size_t m = column_number(ctx);\n        if (match_code_block(ctx)) {\n            const size_t q = ctx->bufcur;\n            match_spaces(ctx);\n            if (output1 != NULL) {\n                code_block_t *c = code_block_array__create_entry(output1);\n                c->text = strndup_e(ctx->buffer.buf + p + 1, q - p - 2);\n                c->len = q - p - 2;\n                c->line = l;\n                c->col = m;\n            }\n            if (output2 != NULL) {\n                code_block_t *c = code_block_array__create_entry(output2);\n                c->text = strndup_e(ctx->buffer.buf + p + 1, q - p - 2);\n                c->len = q - p - 2;\n                c->line = l;\n                c->col = m;\n            }\n        }\n        else {\n            print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Illegal %s syntax\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1), name);\n            ctx->errnum++;\n        }\n    }\n    return TRUE;\n}\n\nstatic bool_t parse_directive_string_(context_t *ctx, const char *name, char **output, string_flag_t mode) {\n    const size_t l = ctx->linenum;\n    const size_t m = column_number(ctx);\n    if (!match_string(ctx, name)) return FALSE;\n    match_spaces(ctx);\n    {\n        char *s = NULL;\n        const size_t p = ctx->bufcur;\n        const size_t lv = ctx->linenum;\n        const size_t mv = column_number(ctx);\n        size_t q;\n        if (match_quotation_single(ctx) || match_quotation_double(ctx)) {\n            q = ctx->bufcur;\n            match_spaces(ctx);\n            s = strndup_e(ctx->buffer.buf + p + 1, q - p - 2);\n            if (!unescape_string(s, FALSE)) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Illegal escape sequence\\n\", ctx->iname, (ulong_t)(lv + 1), (ulong_t)(mv + 1));\n                ctx->errnum++;\n            }\n        }\n        else {\n            print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Illegal %s syntax\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1), name);\n            ctx->errnum++;\n        }\n        if (s != NULL) {\n            string_flag_t f = STRING_FLAG__NONE;\n            bool_t b = TRUE;\n            remove_leading_blanks(s);\n            remove_trailing_blanks(s);\n            assert((mode & ~7) == 0);\n            if ((mode & STRING_FLAG__NOTEMPTY) && !is_filled_string(s)) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Empty string\\n\", ctx->iname, (ulong_t)(lv + 1), (ulong_t)(mv + 1));\n                ctx->errnum++;\n                f |= STRING_FLAG__NOTEMPTY;\n            }\n            if ((mode & STRING_FLAG__NOTVOID) && strcmp(s, \"void\") == 0) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": 'void' not allowed\\n\", ctx->iname, (ulong_t)(lv + 1), (ulong_t)(mv + 1));\n                ctx->errnum++;\n                f |= STRING_FLAG__NOTVOID;\n            }\n            if ((mode & STRING_FLAG__IDENTIFIER) && !is_identifier_string(s)) {\n                if (!(f & STRING_FLAG__NOTEMPTY)) {\n                    print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Invalid identifier\\n\", ctx->iname, (ulong_t)(lv + 1), (ulong_t)(mv + 1));\n                    ctx->errnum++;\n                }\n                f |= STRING_FLAG__IDENTIFIER;\n            }\n            if (*output != NULL) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Multiple %s definition\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1), name);\n                ctx->errnum++;\n                b = FALSE;\n            }\n            if (f == STRING_FLAG__NONE && b) {\n                *output = s;\n            }\n            else {\n                free(s); s = NULL;\n            }\n        }\n    }\n    return TRUE;\n}\n\nstatic bool_t parse(context_t *ctx) {\n    {\n        bool_t b = TRUE;\n        match_spaces(ctx);\n        for (;;) {\n            size_t l, m, n, o;\n            if (match_eof(ctx) || match_footer_start(ctx)) break;\n            l = ctx->linenum;\n            m = column_number(ctx);\n            n = ctx->charnum;\n            o = ctx->linepos;\n            if (\n                parse_directive_include_(ctx, \"%earlysource\", &ctx->esource, NULL) ||\n                parse_directive_include_(ctx, \"%earlyheader\", &ctx->eheader, NULL) ||\n                parse_directive_include_(ctx, \"%earlycommon\", &ctx->esource, &ctx->eheader) ||\n                parse_directive_include_(ctx, \"%source\", &ctx->source, NULL) ||\n                parse_directive_include_(ctx, \"%header\", &ctx->header, NULL) ||\n                parse_directive_include_(ctx, \"%common\", &ctx->source, &ctx->header) ||\n                parse_directive_string_(ctx, \"%value\", &ctx->vtype, STRING_FLAG__NOTEMPTY | STRING_FLAG__NOTVOID) ||\n                parse_directive_string_(ctx, \"%auxil\", &ctx->atype, STRING_FLAG__NOTEMPTY | STRING_FLAG__NOTVOID) ||\n                parse_directive_string_(ctx, \"%prefix\", &ctx->prefix, STRING_FLAG__NOTEMPTY | STRING_FLAG__IDENTIFIER)\n            ) {\n                b = TRUE;\n            }\n            else if (match_character(ctx, '%')) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Invalid directive\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1));\n                ctx->errnum++;\n                match_identifier(ctx);\n                match_spaces(ctx);\n                b = TRUE;\n            }\n            else {\n                node_t *const n_r = parse_rule(ctx);\n                if (n_r == NULL) {\n                    if (b) {\n                        print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Illegal rule syntax\\n\", ctx->iname, (ulong_t)(l + 1), (ulong_t)(m + 1));\n                        ctx->errnum++;\n                        b = FALSE;\n                    }\n                    ctx->linenum = l;\n                    ctx->charnum = n;\n                    ctx->linepos = o;\n                    if (!match_identifier(ctx) && !match_spaces(ctx)) match_character_any(ctx);\n                    continue;\n                }\n                node_array__add(&ctx->rules, n_r);\n                b = TRUE;\n            }\n            commit_buffer(ctx);\n        }\n        commit_buffer(ctx);\n    }\n    {\n        size_t i;\n        make_rulehash(ctx);\n        for (i = 0; i < ctx->rules.len; i++) {\n            link_references(ctx, ctx->rules.buf[i]->data.rule.expr);\n        }\n        for (i = 1; i < ctx->rules.len; i++) {\n            if (ctx->rules.buf[i]->data.rule.ref == 0) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Never used rule '%s'\\n\",\n                    ctx->iname,\n                    (ulong_t)(ctx->rules.buf[i]->data.rule.line + 1), (ulong_t)(ctx->rules.buf[i]->data.rule.col + 1),\n                    ctx->rules.buf[i]->data.rule.name);\n                ctx->errnum++;\n            }\n            else if (ctx->rules.buf[i]->data.rule.ref < 0) {\n                print_error(\"%s:\" FMT_LU \":\" FMT_LU \": Multiple definition of rule '%s'\\n\",\n                    ctx->iname,\n                    (ulong_t)(ctx->rules.buf[i]->data.rule.line + 1), (ulong_t)(ctx->rules.buf[i]->data.rule.col + 1),\n                    ctx->rules.buf[i]->data.rule.name);\n                ctx->errnum++;\n            }\n        }\n    }\n    {\n        size_t i;\n        for (i = 0; i < ctx->rules.len; i++) {\n            verify_variables(ctx, ctx->rules.buf[i]->data.rule.expr, NULL);\n            verify_captures(ctx, ctx->rules.buf[i]->data.rule.expr, NULL);\n        }\n    }\n    if (ctx->opts.debug) {\n        size_t i;\n        for (i = 0; i < ctx->rules.len; i++) {\n            dump_node(ctx, ctx->rules.buf[i], 0);\n        }\n        dump_options(ctx);\n    }\n    return (ctx->errnum == 0) ? TRUE : FALSE;\n}\n\nstatic code_reach_t generate_matching_string_code(generate_t *gen, const char *value, int onfail, size_t indent, bool_t bare) {\n    const size_t n = (value != NULL) ? strlen(value) : 0;\n    if (n > 0) {\n        char s[5];\n        if (n > 1) {\n            size_t i;\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"if (\\n\");\n            stream__write_characters(gen->stream, ' ', indent + 4);\n            stream__printf(gen->stream, \"pcc_refill_buffer(ctx, \" FMT_LU \") < \" FMT_LU \" ||\\n\", (ulong_t)n, (ulong_t)n);\n            for (i = 0; i < n - 1; i++) {\n                stream__write_characters(gen->stream, ' ', indent + 4);\n                stream__printf(gen->stream, \"(ctx->buffer.buf + ctx->cur)[\" FMT_LU \"] != '%s' ||\\n\", (ulong_t)i, escape_character(value[i], &s));\n            }\n            stream__write_characters(gen->stream, ' ', indent + 4);\n            stream__printf(gen->stream, \"(ctx->buffer.buf + ctx->cur)[\" FMT_LU \"] != '%s'\\n\", (ulong_t)i, escape_character(value[i], &s));\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \") goto L%04d;\\n\", onfail);\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"ctx->cur += \" FMT_LU \";\\n\", (ulong_t)n);\n            return CODE_REACH__BOTH;\n        }\n        else {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"if (\\n\");\n            stream__write_characters(gen->stream, ' ', indent + 4);\n            stream__puts(gen->stream, \"pcc_refill_buffer(ctx, 1) < 1 ||\\n\");\n            stream__write_characters(gen->stream, ' ', indent + 4);\n            stream__printf(gen->stream, \"ctx->buffer.buf[ctx->cur] != '%s'\\n\", escape_character(value[0], &s));\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \") goto L%04d;\\n\", onfail);\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"ctx->cur++;\\n\");\n            return CODE_REACH__BOTH;\n        }\n    }\n    else {\n        /* no code to generate */\n        return CODE_REACH__ALWAYS_SUCCEED;\n    }\n}\n\nstatic code_reach_t generate_matching_charclass_code(generate_t *gen, const char *value, int onfail, size_t indent, bool_t bare) {\n    assert(gen->ascii);\n    if (value != NULL) {\n        const size_t n = strlen(value);\n        if (n > 0) {\n            char s[5], t[5];\n            if (n > 1) {\n                const bool_t a = (value[0] == '^') ? TRUE : FALSE;\n                size_t i = a ? 1 : 0;\n                if (i + 1 == n) { /* fulfilled only if a == TRUE */\n                    stream__write_characters(gen->stream, ' ', indent);\n                    stream__puts(gen->stream, \"if (\\n\");\n                    stream__write_characters(gen->stream, ' ', indent + 4);\n                    stream__puts(gen->stream, \"pcc_refill_buffer(ctx, 1) < 1 ||\\n\");\n                    stream__write_characters(gen->stream, ' ', indent + 4);\n                    stream__printf(gen->stream, \"ctx->buffer.buf[ctx->cur] == '%s'\\n\", escape_character(value[i], &s));\n                    stream__write_characters(gen->stream, ' ', indent);\n                    stream__printf(gen->stream, \") goto L%04d;\\n\", onfail);\n                    stream__write_characters(gen->stream, ' ', indent);\n                    stream__puts(gen->stream, \"ctx->cur++;\\n\");\n                    return CODE_REACH__BOTH;\n                }\n                else {\n                    if (!bare) {\n                        stream__write_characters(gen->stream, ' ', indent);\n                        stream__puts(gen->stream, \"{\\n\");\n                        indent += 4;\n                    }\n                    stream__write_characters(gen->stream, ' ', indent);\n                    stream__puts(gen->stream, \"char c;\\n\");\n                    stream__write_characters(gen->stream, ' ', indent);\n                    stream__printf(gen->stream, \"if (pcc_refill_buffer(ctx, 1) < 1) goto L%04d;\\n\", onfail);\n                    stream__write_characters(gen->stream, ' ', indent);\n                    stream__puts(gen->stream, \"c = ctx->buffer.buf[ctx->cur];\\n\");\n                    if (i + 3 == n && value[i] != '\\\\' && value[i + 1] == '-') {\n                        stream__write_characters(gen->stream, ' ', indent);\n                        stream__printf(gen->stream,\n                            a ? \"if (c >= '%s' && c <= '%s') goto L%04d;\\n\"\n                              : \"if (!(c >= '%s' && c <= '%s')) goto L%04d;\\n\",\n                            escape_character(value[i], &s), escape_character(value[i + 2], &t), onfail);\n                    }\n                    else {\n                        stream__write_characters(gen->stream, ' ', indent);\n                        stream__puts(gen->stream, a ? \"if (\\n\" : \"if (!(\\n\");\n                        for (; i < n; i++) {\n                            stream__write_characters(gen->stream, ' ', indent + 4);\n                            if (value[i] == '\\\\' && i + 1 < n) i++;\n                            if (i + 2 < n && value[i + 1] == '-') {\n                                stream__printf(gen->stream, \"(c >= '%s' && c <= '%s')%s\\n\",\n                                    escape_character(value[i], &s), escape_character(value[i + 2], &t), (i + 3 == n) ? \"\" : \" ||\");\n                                i += 2;\n                            }\n                            else {\n                                stream__printf(gen->stream, \"c == '%s'%s\\n\",\n                                    escape_character(value[i], &s), (i + 1 == n) ? \"\" : \" ||\");\n                            }\n                        }\n                        stream__write_characters(gen->stream, ' ', indent);\n                        stream__printf(gen->stream, a ? \") goto L%04d;\\n\" : \")) goto L%04d;\\n\", onfail);\n                    }\n                    stream__write_characters(gen->stream, ' ', indent);\n                    stream__puts(gen->stream, \"ctx->cur++;\\n\");\n                    if (!bare) {\n                        indent -= 4;\n                        stream__write_characters(gen->stream, ' ', indent);\n                        stream__puts(gen->stream, \"}\\n\");\n                    }\n                    return CODE_REACH__BOTH;\n                }\n            }\n            else {\n                stream__write_characters(gen->stream, ' ', indent);\n                stream__puts(gen->stream, \"if (\\n\");\n                stream__write_characters(gen->stream, ' ', indent + 4);\n                stream__puts(gen->stream, \"pcc_refill_buffer(ctx, 1) < 1 ||\\n\");\n                stream__write_characters(gen->stream, ' ', indent + 4);\n                stream__printf(gen->stream, \"ctx->buffer.buf[ctx->cur] != '%s'\\n\", escape_character(value[0], &s));\n                stream__write_characters(gen->stream, ' ', indent);\n                stream__printf(gen->stream, \") goto L%04d;\\n\", onfail);\n                stream__write_characters(gen->stream, ' ', indent);\n                stream__puts(gen->stream, \"ctx->cur++;\\n\");\n                return CODE_REACH__BOTH;\n            }\n        }\n        else {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"goto L%04d;\\n\", onfail);\n            return CODE_REACH__ALWAYS_FAIL;\n        }\n    }\n    else {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__printf(gen->stream, \"if (pcc_refill_buffer(ctx, 1) < 1) goto L%04d;\\n\", onfail);\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"ctx->cur++;\\n\");\n        return CODE_REACH__BOTH;\n    }\n}\n\nstatic code_reach_t generate_matching_utf8_charclass_code(generate_t *gen, const char *value, int onfail, size_t indent, bool_t bare) {\n    const size_t n = (value != NULL) ? strlen(value) : 0;\n    if (value == NULL || n > 0) {\n        const bool_t a = (n > 0 && value[0] == '^') ? TRUE : FALSE;\n        size_t i = a ? 1 : 0;\n        if (!bare) {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"{\\n\");\n            indent += 4;\n        }\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"int u;\\n\");\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"const size_t n = pcc_get_char_as_utf32(ctx, &u);\\n\");\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__printf(gen->stream, \"if (n == 0) goto L%04d;\\n\", onfail);\n        if (value != NULL && !(a && n == 1)) { /* not '.' or '[^]' */\n            int u0 = 0;\n            bool_t r = FALSE;\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, a ? \"if (\\n\" : \"if (!(\\n\");\n            while (i < n) {\n                int u = 0;\n                if (value[i] == '\\\\' && i + 1 < n) i++;\n                i += utf8_to_utf32(value + i, &u);\n                if (r) { /* character range */\n                    stream__write_characters(gen->stream, ' ', indent + 4);\n                    stream__printf(gen->stream, \"(u >= 0x%06x && u <= 0x%06x)%s\\n\", u0, u, (i < n) ? \" ||\" : \"\");\n                    u0 = 0;\n                    r = FALSE;\n                }\n                else if (\n                    value[i] != '-' ||\n                    i == n - 1 /* the individual '-' character is valid when it is at the first or the last position */\n                ) { /* single character */\n                    stream__write_characters(gen->stream, ' ', indent + 4);\n                    stream__printf(gen->stream, \"u == 0x%06x%s\\n\", u, (i < n) ? \" ||\" : \"\");\n                    u0 = 0;\n                    r = FALSE;\n                }\n                else {\n                    assert(value[i] == '-');\n                    i++;\n                    u0 = u;\n                    r = TRUE;\n                }\n            }\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, a ? \") goto L%04d;\\n\" : \")) goto L%04d;\\n\", onfail);\n        }\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"ctx->cur += n;\\n\");\n        if (!bare) {\n            indent -= 4;\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"}\\n\");\n        }\n        return CODE_REACH__BOTH;\n    }\n    else {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__printf(gen->stream, \"goto L%04d;\\n\", onfail);\n        return CODE_REACH__ALWAYS_FAIL;\n    }\n}\n\nstatic code_reach_t generate_code(generate_t *gen, const node_t *node, int onfail, size_t indent, bool_t bare);\n\nstatic code_reach_t generate_quantifying_code(generate_t *gen, const node_t *expr, int min, int max, int onfail, size_t indent, bool_t bare) {\n    if (max > 1 || max < 0) {\n        code_reach_t r;\n        if (!bare) {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"{\\n\");\n            indent += 4;\n        }\n        if (min > 0) {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"const size_t p0 = ctx->cur;\\n\");\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"const size_t n0 = chunk->thunks.len;\\n\");\n        }\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"int i;\\n\");\n        stream__write_characters(gen->stream, ' ', indent);\n        if (max < 0)\n            stream__puts(gen->stream, \"for (i = 0;; i++) {\\n\");\n        else\n            stream__printf(gen->stream, \"for (i = 0; i < %d; i++) {\\n\", max);\n        stream__write_characters(gen->stream, ' ', indent + 4);\n        stream__puts(gen->stream, \"const size_t p = ctx->cur;\\n\");\n        stream__write_characters(gen->stream, ' ', indent + 4);\n        stream__puts(gen->stream, \"const size_t n = chunk->thunks.len;\\n\");\n        {\n            const int l = ++gen->label;\n            r = generate_code(gen, expr, l, indent + 4, FALSE);\n            stream__write_characters(gen->stream, ' ', indent + 4);\n            stream__puts(gen->stream, \"if (ctx->cur == p) break;\\n\");\n            if (r != CODE_REACH__ALWAYS_SUCCEED) {\n                stream__write_characters(gen->stream, ' ', indent + 4);\n                stream__puts(gen->stream, \"continue;\\n\");\n                stream__write_characters(gen->stream, ' ', indent);\n                stream__printf(gen->stream, \"L%04d:;\\n\", l);\n                stream__write_characters(gen->stream, ' ', indent + 4);\n                stream__puts(gen->stream, \"ctx->cur = p;\\n\");\n                stream__write_characters(gen->stream, ' ', indent + 4);\n                stream__puts(gen->stream, \"pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n);\\n\");\n                stream__write_characters(gen->stream, ' ', indent + 4);\n                stream__puts(gen->stream, \"break;\\n\");\n            }\n        }\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"}\\n\");\n        if (min > 0) {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"if (i < %d) {\\n\", min);\n            stream__write_characters(gen->stream, ' ', indent + 4);\n            stream__puts(gen->stream, \"ctx->cur = p0;\\n\");\n            stream__write_characters(gen->stream, ' ', indent + 4);\n            stream__puts(gen->stream, \"pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n0);\\n\");\n            stream__write_characters(gen->stream, ' ', indent + 4);\n            stream__printf(gen->stream, \"goto L%04d;\\n\", onfail);\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"}\\n\");\n        }\n        if (!bare) {\n            indent -= 4;\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"}\\n\");\n        }\n        return (min > 0) ? ((r == CODE_REACH__ALWAYS_FAIL) ? CODE_REACH__ALWAYS_FAIL : CODE_REACH__BOTH) : CODE_REACH__ALWAYS_SUCCEED;\n    }\n    else if (max == 1) {\n        if (min > 0) {\n            return generate_code(gen, expr, onfail, indent, bare);\n        }\n        else {\n            if (!bare) {\n                stream__write_characters(gen->stream, ' ', indent);\n                stream__puts(gen->stream, \"{\\n\");\n                indent += 4;\n            }\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"MARK_VAR_AS_USED\\n\");\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"const size_t p = ctx->cur;\\n\");\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"MARK_VAR_AS_USED\\n\");\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"const size_t n = chunk->thunks.len;\\n\");\n            {\n                const int l = ++gen->label;\n                if (generate_code(gen, expr, l, indent, FALSE) != CODE_REACH__ALWAYS_SUCCEED) {\n                    const int m = ++gen->label;\n                    stream__write_characters(gen->stream, ' ', indent);\n                    stream__printf(gen->stream, \"goto L%04d;\\n\", m);\n                    if (indent > 4) stream__write_characters(gen->stream, ' ', indent - 4);\n                    stream__printf(gen->stream, \"L%04d:;\\n\", l);\n                    stream__write_characters(gen->stream, ' ', indent);\n                    stream__puts(gen->stream, \"ctx->cur = p;\\n\");\n                    stream__write_characters(gen->stream, ' ', indent);\n                    stream__puts(gen->stream, \"pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n);\\n\");\n                    if (indent > 4) stream__write_characters(gen->stream, ' ', indent - 4);\n                    stream__printf(gen->stream, \"L%04d:;\\n\", m);\n                }\n            }\n            if (!bare) {\n                indent -= 4;\n                stream__write_characters(gen->stream, ' ', indent);\n                stream__puts(gen->stream, \"}\\n\");\n            }\n            return CODE_REACH__ALWAYS_SUCCEED;\n        }\n    }\n    else {\n        /* no code to generate */\n        return CODE_REACH__ALWAYS_SUCCEED;\n    }\n}\n\nstatic code_reach_t generate_predicating_code(generate_t *gen, const node_t *expr, bool_t neg, int onfail, size_t indent, bool_t bare) {\n    code_reach_t r;\n    if (!bare) {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"{\\n\");\n        indent += 4;\n    }\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__puts(gen->stream, \"const size_t p = ctx->cur;\\n\");\n    if (neg) {\n        const int l = ++gen->label;\n        r = generate_code(gen, expr, l, indent, FALSE);\n        if (r != CODE_REACH__ALWAYS_FAIL) {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"ctx->cur = p;\\n\");\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"goto L%04d;\\n\", onfail);\n        }\n        if (r != CODE_REACH__ALWAYS_SUCCEED) {\n            if (indent > 4) stream__write_characters(gen->stream, ' ', indent - 4);\n            stream__printf(gen->stream, \"L%04d:;\\n\", l);\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"ctx->cur = p;\\n\");\n        }\n        switch (r) {\n        case CODE_REACH__ALWAYS_SUCCEED: r = CODE_REACH__ALWAYS_FAIL; break;\n        case CODE_REACH__ALWAYS_FAIL: r = CODE_REACH__ALWAYS_SUCCEED; break;\n        case CODE_REACH__BOTH: break;\n        }\n    }\n    else {\n        const int l = ++gen->label;\n        const int m = ++gen->label;\n        r = generate_code(gen, expr, l, indent, FALSE);\n        if (r != CODE_REACH__ALWAYS_FAIL) {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"ctx->cur = p;\\n\");\n        }\n        if (r == CODE_REACH__BOTH) {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"goto L%04d;\\n\", m);\n        }\n        if (r != CODE_REACH__ALWAYS_SUCCEED) {\n            if (indent > 4) stream__write_characters(gen->stream, ' ', indent - 4);\n            stream__printf(gen->stream, \"L%04d:;\\n\", l);\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__puts(gen->stream, \"ctx->cur = p;\\n\");\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"goto L%04d;\\n\", onfail);\n        }\n        if (r == CODE_REACH__BOTH) {\n            if (indent > 4) stream__write_characters(gen->stream, ' ', indent - 4);\n            stream__printf(gen->stream, \"L%04d:;\\n\", m);\n        }\n    }\n    if (!bare) {\n        indent -= 4;\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"}\\n\");\n    }\n    return r;\n}\n\nstatic code_reach_t generate_sequential_code(generate_t *gen, const node_array_t *nodes, int onfail, size_t indent, bool_t bare) {\n    bool_t b = FALSE;\n    size_t i;\n    for (i = 0; i < nodes->len; i++) {\n        switch (generate_code(gen, nodes->buf[i], onfail, indent, FALSE)) {\n        case CODE_REACH__ALWAYS_FAIL:\n            if (i + 1 < nodes->len) {\n                stream__write_characters(gen->stream, ' ', indent);\n                stream__puts(gen->stream, \"/* unreachable codes omitted */\\n\");\n            }\n            return CODE_REACH__ALWAYS_FAIL;\n        case CODE_REACH__ALWAYS_SUCCEED:\n            break;\n        default:\n            b = TRUE;\n        }\n    }\n    return b ? CODE_REACH__BOTH : CODE_REACH__ALWAYS_SUCCEED;\n}\n\nstatic code_reach_t generate_alternative_code(generate_t *gen, const node_array_t *nodes, int onfail, size_t indent, bool_t bare) {\n    bool_t b = FALSE;\n    int m = ++gen->label;\n    size_t i;\n    if (!bare) {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"{\\n\");\n        indent += 4;\n    }\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__puts(gen->stream, \"MARK_VAR_AS_USED\\n\");\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__puts(gen->stream, \"const size_t p = ctx->cur;\\n\");\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__puts(gen->stream, \"MARK_VAR_AS_USED\\n\");\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__puts(gen->stream, \"const size_t n = chunk->thunks.len;\\n\");\n    for (i = 0; i < nodes->len; i++) {\n        const bool_t c = (i + 1 < nodes->len) ? TRUE : FALSE;\n        const int l = ++gen->label;\n        switch (generate_code(gen, nodes->buf[i], l, indent, FALSE)) {\n        case CODE_REACH__ALWAYS_SUCCEED:\n            if (c) {\n                stream__write_characters(gen->stream, ' ', indent);\n                stream__puts(gen->stream, \"/* unreachable codes omitted */\\n\");\n            }\n            if (b) {\n                if (indent > 4) stream__write_characters(gen->stream, ' ', indent - 4);\n                stream__printf(gen->stream, \"L%04d:;\\n\", m);\n            }\n            if (!bare) {\n                indent -= 4;\n                stream__write_characters(gen->stream, ' ', indent);\n                stream__puts(gen->stream, \"}\\n\");\n            }\n            return CODE_REACH__ALWAYS_SUCCEED;\n        case CODE_REACH__ALWAYS_FAIL:\n            break;\n        default:\n            b = TRUE;\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"goto L%04d;\\n\", m);\n        }\n        if (indent > 4) stream__write_characters(gen->stream, ' ', indent - 4);\n        stream__printf(gen->stream, \"L%04d:;\\n\", l);\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"ctx->cur = p;\\n\");\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n);\\n\");\n        if (!c) {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"goto L%04d;\\n\", onfail);\n        }\n    }\n    if (b) {\n        if (indent > 4) stream__write_characters(gen->stream, ' ', indent - 4);\n        stream__printf(gen->stream, \"L%04d:;\\n\", m);\n    }\n    if (!bare) {\n        indent -= 4;\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"}\\n\");\n    }\n    return b ? CODE_REACH__BOTH : CODE_REACH__ALWAYS_FAIL;\n}\n\nstatic code_reach_t generate_capturing_code(generate_t *gen, const node_t *expr, size_t index, int onfail, size_t indent, bool_t bare) {\n    code_reach_t r;\n    if (!bare) {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"{\\n\");\n        indent += 4;\n    }\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__puts(gen->stream, \"const size_t p = ctx->cur;\\n\");\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__puts(gen->stream, \"size_t q;\\n\");\n    r = generate_code(gen, expr, onfail, indent, FALSE);\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__puts(gen->stream, \"q = ctx->cur;\\n\");\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__printf(gen->stream, \"chunk->capts.buf[\" FMT_LU \"].range.start = p;\\n\", (ulong_t)index);\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__printf(gen->stream, \"chunk->capts.buf[\" FMT_LU \"].range.end = q;\\n\", (ulong_t)index);\n    if (!bare) {\n        indent -= 4;\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"}\\n\");\n    }\n    return r;\n}\n\nstatic code_reach_t generate_expanding_code(generate_t *gen, size_t index, int onfail, size_t indent, bool_t bare) {\n    if (!bare) {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"{\\n\");\n        indent += 4;\n    }\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__printf(gen->stream,\n        \"const size_t n = chunk->capts.buf[\" FMT_LU \"].range.end - chunk->capts.buf[\" FMT_LU \"].range.start;\\n\", (ulong_t)index, (ulong_t)index);\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__printf(gen->stream, \"if (pcc_refill_buffer(ctx, n) < n) goto L%04d;\\n\", onfail);\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__puts(gen->stream, \"if (n > 0) {\\n\");\n    stream__write_characters(gen->stream, ' ', indent + 4);\n    stream__puts(gen->stream, \"const char *const p = ctx->buffer.buf + ctx->cur;\\n\");\n    stream__write_characters(gen->stream, ' ', indent + 4);\n    stream__printf(gen->stream, \"const char *const q = ctx->buffer.buf + chunk->capts.buf[\" FMT_LU \"].range.start;\\n\", (ulong_t)index);\n    stream__write_characters(gen->stream, ' ', indent + 4);\n    stream__puts(gen->stream, \"size_t i;\\n\");\n    stream__write_characters(gen->stream, ' ', indent + 4);\n    stream__puts(gen->stream, \"for (i = 0; i < n; i++) {\\n\");\n    stream__write_characters(gen->stream, ' ', indent + 8);\n    stream__printf(gen->stream, \"if (p[i] != q[i]) goto L%04d;\\n\", onfail);\n    stream__write_characters(gen->stream, ' ', indent + 4);\n    stream__puts(gen->stream, \"}\\n\");\n    stream__write_characters(gen->stream, ' ', indent + 4);\n    stream__puts(gen->stream, \"ctx->cur += n;\\n\");\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__puts(gen->stream, \"}\\n\");\n    if (!bare) {\n        indent -= 4;\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"}\\n\");\n    }\n    return CODE_REACH__BOTH;\n}\n\nstatic code_reach_t generate_thunking_action_code(\n    generate_t *gen, size_t index, const node_const_array_t *vars, const node_const_array_t *capts, bool_t error, int onfail, size_t indent, bool_t bare\n) {\n    assert(gen->rule->type == NODE_RULE);\n    if (!bare) {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"{\\n\");\n        indent += 4;\n    }\n    if (error) {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"pcc_value_t null;\\n\");\n    }\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__printf(gen->stream, \"pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_%s_\" FMT_LU \", \" FMT_LU \", \" FMT_LU \");\\n\",\n        gen->rule->data.rule.name, (ulong_t)index, (ulong_t)gen->rule->data.rule.vars.len, (ulong_t)gen->rule->data.rule.capts.len);\n    {\n        size_t i;\n        for (i = 0; i < vars->len; i++) {\n            assert(vars->buf[i]->type == NODE_REFERENCE);\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"thunk->data.leaf.values.buf[\" FMT_LU \"] = &(chunk->values.buf[\" FMT_LU \"]);\\n\",\n                (ulong_t)vars->buf[i]->data.reference.index, (ulong_t)vars->buf[i]->data.reference.index);\n        }\n        for (i = 0; i < capts->len; i++) {\n            assert(capts->buf[i]->type == NODE_CAPTURE);\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"thunk->data.leaf.capts.buf[\" FMT_LU \"] = &(chunk->capts.buf[\" FMT_LU \"]);\\n\",\n                (ulong_t)capts->buf[i]->data.capture.index, (ulong_t)capts->buf[i]->data.capture.index);\n        }\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"thunk->data.leaf.capt0.range.start = chunk->pos;\\n\");\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"thunk->data.leaf.capt0.range.end = ctx->cur;\\n\");\n    }\n    if (error) {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"memset(&null, 0, sizeof(pcc_value_t)); /* in case */\\n\");\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"thunk->data.leaf.action(ctx, thunk, &null);\\n\");\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"pcc_thunk__destroy(ctx->auxil, thunk);\\n\");\n    }\n    else {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"pcc_thunk_array__add(ctx->auxil, &chunk->thunks, thunk);\\n\");\n    }\n    if (!bare) {\n        indent -= 4;\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"}\\n\");\n    }\n    return CODE_REACH__ALWAYS_SUCCEED;\n}\n\nstatic code_reach_t generate_thunking_error_code(\n    generate_t *gen, const node_t *expr, size_t index, const node_const_array_t *vars, const node_const_array_t *capts, int onfail, size_t indent, bool_t bare\n) {\n    code_reach_t r;\n    const int l = ++gen->label;\n    const int m = ++gen->label;\n    assert(gen->rule->type == NODE_RULE);\n    if (!bare) {\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"{\\n\");\n        indent += 4;\n    }\n    r = generate_code(gen, expr, l, indent, TRUE);\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__printf(gen->stream, \"goto L%04d;\\n\", m);\n    if (indent > 4) stream__write_characters(gen->stream, ' ', indent - 4);\n    stream__printf(gen->stream, \"L%04d:;\\n\", l);\n    generate_thunking_action_code(gen, index, vars, capts, TRUE, l, indent, FALSE);\n    stream__write_characters(gen->stream, ' ', indent);\n    stream__printf(gen->stream, \"goto L%04d;\\n\", onfail);\n    if (indent > 4) stream__write_characters(gen->stream, ' ', indent - 4);\n    stream__printf(gen->stream, \"L%04d:;\\n\", m);\n    if (!bare) {\n        indent -= 4;\n        stream__write_characters(gen->stream, ' ', indent);\n        stream__puts(gen->stream, \"}\\n\");\n    }\n    return r;\n}\n\nstatic code_reach_t generate_code(generate_t *gen, const node_t *node, int onfail, size_t indent, bool_t bare) {\n    if (node == NULL) {\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    }\n    switch (node->type) {\n    case NODE_RULE:\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    case NODE_REFERENCE:\n        if (node->data.reference.index != VOID_VALUE) {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"if (!pcc_apply_rule(ctx, pcc_evaluate_rule_%s, &chunk->thunks, &(chunk->values.buf[\" FMT_LU \"]))) goto L%04d;\\n\",\n                node->data.reference.name, (ulong_t)node->data.reference.index, onfail);\n        }\n        else {\n            stream__write_characters(gen->stream, ' ', indent);\n            stream__printf(gen->stream, \"if (!pcc_apply_rule(ctx, pcc_evaluate_rule_%s, &chunk->thunks, NULL)) goto L%04d;\\n\",\n                node->data.reference.name, onfail);\n        }\n        return CODE_REACH__BOTH;\n    case NODE_STRING:\n        return generate_matching_string_code(gen, node->data.string.value, onfail, indent, bare);\n    case NODE_CHARCLASS:\n        return gen->ascii ?\n               generate_matching_charclass_code(gen, node->data.charclass.value, onfail, indent, bare) :\n               generate_matching_utf8_charclass_code(gen, node->data.charclass.value, onfail, indent, bare);\n    case NODE_QUANTITY:\n        return generate_quantifying_code(gen, node->data.quantity.expr, node->data.quantity.min, node->data.quantity.max, onfail, indent, bare);\n    case NODE_PREDICATE:\n        return generate_predicating_code(gen, node->data.predicate.expr, node->data.predicate.neg, onfail, indent, bare);\n    case NODE_SEQUENCE:\n        return generate_sequential_code(gen, &node->data.sequence.nodes, onfail, indent, bare);\n    case NODE_ALTERNATE:\n        return generate_alternative_code(gen, &node->data.alternate.nodes, onfail, indent, bare);\n    case NODE_CAPTURE:\n        return generate_capturing_code(gen, node->data.capture.expr, node->data.capture.index, onfail, indent, bare);\n    case NODE_EXPAND:\n        return generate_expanding_code(gen, node->data.expand.index, onfail, indent, bare);\n    case NODE_ACTION:\n        return generate_thunking_action_code(\n            gen, node->data.action.index, &node->data.action.vars, &node->data.action.capts, FALSE, onfail, indent, bare\n        );\n    case NODE_ERROR:\n        return generate_thunking_error_code(\n            gen, node->data.error.expr, node->data.error.index, &node->data.error.vars, &node->data.error.capts, onfail, indent, bare\n        );\n    default:\n        print_error(\"Internal error [%d]\\n\", __LINE__);\n        exit(-1);\n    }\n}\n\nstatic bool_t generate(context_t *ctx) {\n    const char *const vt = get_value_type(ctx);\n    const char *const at = get_auxil_type(ctx);\n    const bool_t vp = is_pointer_type(vt);\n    const bool_t ap = is_pointer_type(at);\n    stream_t sstream = stream__wrap(fopen_wt_e(ctx->sname), ctx->sname, ctx->opts.lines ? 0 : VOID_VALUE);\n    stream_t hstream = stream__wrap(fopen_wt_e(ctx->hname), ctx->hname, ctx->opts.lines ? 0 : VOID_VALUE);\n    stream__printf(&sstream, \"/* A packrat parser generated by PackCC %s */\\n\\n\", VERSION);\n    stream__printf(&hstream, \"/* A packrat parser generated by PackCC %s */\\n\\n\", VERSION);\n    {\n        {\n            size_t i;\n            for (i = 0; i < ctx->eheader.len; i++) {\n                stream__write_code_block(&hstream, ctx->eheader.buf[i].text, ctx->eheader.buf[i].len, 0, ctx->iname, ctx->eheader.buf[i].line);\n            }\n        }\n        if (ctx->eheader.len > 0) stream__puts(&hstream, \"\\n\");\n        stream__printf(\n            &hstream,\n            \"#ifndef PCC_INCLUDED_%s\\n\"\n            \"#define PCC_INCLUDED_%s\\n\"\n            \"\\n\",\n            ctx->hid, ctx->hid\n        );\n        {\n            size_t i;\n            for (i = 0; i < ctx->header.len; i++) {\n                stream__write_code_block(&hstream, ctx->header.buf[i].text, ctx->header.buf[i].len, 0, ctx->iname, ctx->header.buf[i].line);\n            }\n        }\n    }\n    {\n        {\n            size_t i;\n            for (i = 0; i < ctx->esource.len; i++) {\n                stream__write_code_block(&sstream, ctx->esource.buf[i].text, ctx->esource.buf[i].len, 0, ctx->iname, ctx->esource.buf[i].line);\n            }\n        }\n        if (ctx->esource.len > 0) stream__puts(&sstream, \"\\n\");\n        stream__puts(\n            &sstream,\n            \"#ifdef _MSC_VER\\n\"\n            \"#undef _CRT_SECURE_NO_WARNINGS\\n\"\n            \"#define _CRT_SECURE_NO_WARNINGS\\n\"\n            \"#endif /* _MSC_VER */\\n\"\n            \"#include <stdio.h>\\n\"\n            \"#include <stdlib.h>\\n\"\n            \"#include <string.h>\\n\"\n            \"\\n\"\n            \"#ifndef _MSC_VER\\n\"\n            \"#if defined __GNUC__ && defined _WIN32 /* MinGW */\\n\"\n            \"#ifndef PCC_USE_SYSTEM_STRNLEN\\n\"\n            \"#define strnlen(str, maxlen) pcc_strnlen(str, maxlen)\\n\"\n            \"static size_t pcc_strnlen(const char *str, size_t maxlen) {\\n\"\n            \"    size_t i;\\n\"\n            \"    for (i = 0; i < maxlen && str[i]; i++);\\n\"\n            \"    return i;\\n\"\n            \"}\\n\"\n            \"#endif /* !PCC_USE_SYSTEM_STRNLEN */\\n\"\n            \"#endif /* defined __GNUC__ && defined _WIN32 */\\n\"\n            \"#endif /* !_MSC_VER */\\n\"\n            \"\\n\"\n        );\n        stream__printf(\n            &sstream,\n            \"#include \\\"%s\\\"\\n\"\n            \"\\n\",\n            ctx->hname\n        );\n        {\n            size_t i;\n            for (i = 0; i < ctx->source.len; i++) {\n                stream__write_code_block(&sstream, ctx->source.buf[i].text, ctx->source.buf[i].len, 0, ctx->iname, ctx->source.buf[i].line);\n            }\n        }\n    }\n    {\n        stream__puts(\n            &sstream,\n            \"#if !defined __has_attribute || defined _MSC_VER\\n\"\n            \"#define __attribute__(x)\\n\"\n            \"#endif\\n\"\n            \"\\n\"\n            \"#ifdef _MSC_VER\\n\"\n            \"#define MARK_FUNC_AS_USED __pragma(warning(suppress:4505))\\n\"\n            \"#else\\n\"\n            \"#define MARK_FUNC_AS_USED __attribute__((__unused__))\\n\"\n            \"#endif\\n\"\n            \"\\n\"\n            \"#ifdef _MSC_VER\\n\"\n            \"#define MARK_VAR_AS_USED __pragma(warning(suppress:4189))\\n\"\n            \"#else\\n\"\n            \"#define MARK_VAR_AS_USED __attribute__((__unused__))\\n\"\n            \"#endif\\n\"\n            \"\\n\"\n            \"#ifndef PCC_BUFFER_MIN_SIZE\\n\"\n            \"#define PCC_BUFFER_MIN_SIZE 256\\n\"\n            \"#endif /* !PCC_BUFFER_MIN_SIZE */\\n\"\n            \"\\n\"\n            \"#ifndef PCC_ARRAY_MIN_SIZE\\n\"\n            \"#define PCC_ARRAY_MIN_SIZE 2\\n\"\n            \"#endif /* !PCC_ARRAY_MIN_SIZE */\\n\"\n            \"\\n\"\n            \"#ifndef PCC_POOL_MIN_SIZE\\n\"\n            \"#define PCC_POOL_MIN_SIZE 65536\\n\"\n            \"#endif /* !PCC_POOL_MIN_SIZE */\\n\"\n            \"\\n\"\n            \"#define PCC_DBG_EVALUATE 0\\n\"\n            \"#define PCC_DBG_MATCH    1\\n\"\n            \"#define PCC_DBG_NOMATCH  2\\n\"\n            \"\\n\"\n            \"#define PCC_VOID_VALUE (~(size_t)0)\\n\"\n            \"\\n\"\n            \"typedef enum pcc_bool_tag {\\n\"\n            \"    PCC_FALSE = 0,\\n\"\n            \"    PCC_TRUE\\n\"\n            \"} pcc_bool_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_char_array_tag {\\n\"\n            \"    char *buf;\\n\"\n            \"    size_t max;\\n\"\n            \"    size_t len;\\n\"\n            \"} pcc_char_array_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_range_tag {\\n\"\n            \"    size_t start;\\n\"\n            \"    size_t end;\\n\"\n            \"} pcc_range_t;\\n\"\n            \"\\n\"\n        );\n        stream__printf(\n            &sstream,\n            \"typedef %s%spcc_value_t;\\n\"\n            \"\\n\",\n            vt, vp ? \"\" : \" \"\n        );\n        stream__printf(\n            &sstream,\n            \"typedef %s%spcc_auxil_t;\\n\"\n            \"\\n\",\n            at, ap ? \"\" : \" \"\n        );\n        if (strcmp(get_prefix(ctx), \"pcc\") != 0) {\n            stream__printf(\n                &sstream,\n                \"typedef %s_context_t pcc_context_t;\\n\"\n                \"\\n\",\n                get_prefix(ctx)\n            );\n        }\n        stream__puts(\n            &sstream,\n            \"typedef struct pcc_value_table_tag {\\n\"\n            \"    pcc_value_t *buf;\\n\"\n            \"    size_t max;\\n\"\n            \"    size_t len;\\n\"\n            \"} pcc_value_table_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_value_refer_table_tag {\\n\"\n            \"    pcc_value_t **buf;\\n\"\n            \"    size_t max;\\n\"\n            \"    size_t len;\\n\"\n            \"} pcc_value_refer_table_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_capture_tag {\\n\"\n            \"    pcc_range_t range;\\n\"\n            \"    char *string; /* mutable */\\n\"\n            \"} pcc_capture_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_capture_table_tag {\\n\"\n            \"    pcc_capture_t *buf;\\n\"\n            \"    size_t max;\\n\"\n            \"    size_t len;\\n\"\n            \"} pcc_capture_table_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_capture_const_table_tag {\\n\"\n            \"    const pcc_capture_t **buf;\\n\"\n            \"    size_t max;\\n\"\n            \"    size_t len;\\n\"\n            \"} pcc_capture_const_table_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_thunk_tag pcc_thunk_t;\\n\"\n            \"typedef struct pcc_thunk_array_tag pcc_thunk_array_t;\\n\"\n            \"\\n\"\n            \"typedef void (*pcc_action_t)(pcc_context_t *, pcc_thunk_t *, pcc_value_t *);\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"typedef enum pcc_thunk_type_tag {\\n\"\n            \"    PCC_THUNK_LEAF,\\n\"\n            \"    PCC_THUNK_NODE\\n\"\n            \"} pcc_thunk_type_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_thunk_leaf_tag {\\n\"\n            \"    pcc_value_refer_table_t values;\\n\"\n            \"    pcc_capture_const_table_t capts;\\n\"\n            \"    pcc_capture_t capt0;\\n\"\n            \"    pcc_action_t action;\\n\"\n            \"} pcc_thunk_leaf_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_thunk_node_tag {\\n\"\n            \"    const pcc_thunk_array_t *thunks; /* just a reference */\\n\"\n            \"    pcc_value_t *value; /* just a reference */\\n\"\n            \"} pcc_thunk_node_t;\\n\"\n            \"\\n\"\n            \"typedef union pcc_thunk_data_tag {\\n\"\n            \"    pcc_thunk_leaf_t leaf;\\n\"\n            \"    pcc_thunk_node_t node;\\n\"\n            \"} pcc_thunk_data_t;\\n\"\n            \"\\n\"\n            \"struct pcc_thunk_tag {\\n\"\n            \"    pcc_thunk_type_t type;\\n\"\n            \"    pcc_thunk_data_t data;\\n\"\n            \"};\\n\"\n            \"\\n\"\n            \"struct pcc_thunk_array_tag {\\n\"\n            \"    pcc_thunk_t **buf;\\n\"\n            \"    size_t max;\\n\"\n            \"    size_t len;\\n\"\n            \"};\\n\"\n            \"\\n\"\n            \"typedef struct pcc_thunk_chunk_tag {\\n\"\n            \"    pcc_value_table_t values;\\n\"\n            \"    pcc_capture_table_t capts;\\n\"\n            \"    pcc_thunk_array_t thunks;\\n\"\n            \"    size_t pos; /* the starting position in the character buffer */\\n\"\n            \"} pcc_thunk_chunk_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_lr_entry_tag pcc_lr_entry_t;\\n\"\n            \"\\n\"\n            \"typedef enum pcc_lr_answer_type_tag {\\n\"\n            \"    PCC_LR_ANSWER_LR,\\n\"\n            \"    PCC_LR_ANSWER_CHUNK\\n\"\n            \"} pcc_lr_answer_type_t;\\n\"\n            \"\\n\"\n            \"typedef union pcc_lr_answer_data_tag {\\n\"\n            \"    pcc_lr_entry_t *lr;\\n\"\n            \"    pcc_thunk_chunk_t *chunk;\\n\"\n            \"} pcc_lr_answer_data_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_lr_answer_tag pcc_lr_answer_t;\\n\"\n            \"\\n\"\n            \"struct pcc_lr_answer_tag {\\n\"\n            \"    pcc_lr_answer_type_t type;\\n\"\n            \"    pcc_lr_answer_data_t data;\\n\"\n            \"    size_t pos; /* the absolute position in the input */\\n\"\n            \"    pcc_lr_answer_t *hold;\\n\"\n            \"};\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"typedef pcc_thunk_chunk_t *(*pcc_rule_t)(pcc_context_t *);\\n\"\n            \"\\n\"\n            \"typedef struct pcc_rule_set_tag {\\n\"\n            \"    pcc_rule_t *buf;\\n\"\n            \"    size_t max;\\n\"\n            \"    size_t len;\\n\"\n            \"} pcc_rule_set_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_lr_head_tag pcc_lr_head_t;\\n\"\n            \"\\n\"\n            \"struct pcc_lr_head_tag {\\n\"\n            \"    pcc_rule_t rule;\\n\"\n            \"    pcc_rule_set_t invol;\\n\"\n            \"    pcc_rule_set_t eval;\\n\"\n            \"    pcc_lr_head_t *hold;\\n\"\n            \"};\\n\"\n            \"\\n\"\n            \"typedef struct pcc_lr_memo_tag {\\n\"\n            \"    pcc_rule_t rule;\\n\"\n            \"    pcc_lr_answer_t *answer;\\n\"\n            \"} pcc_lr_memo_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_lr_memo_map_tag {\\n\"\n            \"    pcc_lr_memo_t *buf;\\n\"\n            \"    size_t max;\\n\"\n            \"    size_t len;\\n\"\n            \"} pcc_lr_memo_map_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_lr_table_entry_tag {\\n\"\n            \"    pcc_lr_head_t *head; /* just a reference */\\n\"\n            \"    pcc_lr_memo_map_t memos;\\n\"\n            \"    pcc_lr_answer_t *hold_a;\\n\"\n            \"    pcc_lr_head_t *hold_h;\\n\"\n            \"} pcc_lr_table_entry_t;\\n\"\n            \"\\n\"\n            \"typedef struct pcc_lr_table_tag {\\n\"\n            \"    pcc_lr_table_entry_t **buf;\\n\"\n            \"    size_t max;\\n\"\n            \"    size_t len;\\n\"\n            \"    size_t ofs;\\n\"\n            \"} pcc_lr_table_t;\\n\"\n            \"\\n\"\n            \"struct pcc_lr_entry_tag {\\n\"\n            \"    pcc_rule_t rule;\\n\"\n            \"    pcc_thunk_chunk_t *seed; /* just a reference */\\n\"\n            \"    pcc_lr_head_t *head; /* just a reference */\\n\"\n            \"};\\n\"\n            \"\\n\"\n            \"typedef struct pcc_lr_stack_tag {\\n\"\n            \"    pcc_lr_entry_t **buf;\\n\"\n            \"    size_t max;\\n\"\n            \"    size_t len;\\n\"\n            \"} pcc_lr_stack_t;\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"typedef struct pcc_memory_entry_tag pcc_memory_entry_t;\\n\"\n            \"typedef struct pcc_memory_pool_tag pcc_memory_pool_t;\\n\"\n            \"\\n\"\n            \"struct pcc_memory_entry_tag {\\n\"\n            \"    pcc_memory_entry_t *next;\\n\"\n            \"};\\n\"\n            \"\\n\"\n            \"struct pcc_memory_pool_tag {\\n\"\n            \"    pcc_memory_pool_t *next;\\n\"\n            \"    size_t allocated;\\n\"\n            \"    size_t unused;\\n\"\n            \"};\\n\"\n            \"\\n\"\n            \"typedef struct pcc_memory_recycler_tag {\\n\"\n            \"    pcc_memory_pool_t *pool_list;\\n\"\n            \"    pcc_memory_entry_t *entry_list;\\n\"\n            \"    size_t element_size;\\n\"\n            \"} pcc_memory_recycler_t;\\n\"\n            \"\\n\"\n        );\n        stream__printf(\n            &sstream,\n            \"struct %s_context_tag {\\n\"\n            \"    size_t pos; /* the position in the input of the first character currently buffered */\\n\"\n            \"    size_t cur; /* the current parsing position in the character buffer */\\n\"\n            \"    size_t level;\\n\"\n            \"    pcc_char_array_t buffer;\\n\"\n            \"    pcc_lr_table_t lrtable;\\n\"\n            \"    pcc_lr_stack_t lrstack;\\n\"\n            \"    pcc_thunk_array_t thunks;\\n\"\n            \"    pcc_auxil_t auxil;\\n\"\n            \"    pcc_memory_recycler_t thunk_chunk_recycler;\\n\"\n            \"    pcc_memory_recycler_t lr_head_recycler;\\n\"\n            \"    pcc_memory_recycler_t lr_answer_recycler;\\n\"\n            \"};\\n\"\n            \"\\n\",\n            get_prefix(ctx)\n        );\n        stream__puts(\n            &sstream,\n            \"#ifndef PCC_ERROR\\n\"\n            \"#define PCC_ERROR(auxil) pcc_error()\\n\"\n            \"MARK_FUNC_AS_USED\\n\"\n            \"static void pcc_error(void) {\\n\"\n            \"    fprintf(stderr, \\\"Syntax error\\\\n\\\");\\n\"\n            \"    exit(1);\\n\"\n            \"}\\n\"\n            \"#endif /* !PCC_ERROR */\\n\"\n            \"\\n\"\n            \"#ifndef PCC_GETCHAR\\n\"\n            \"#define PCC_GETCHAR(auxil) getchar()\\n\"\n            \"#endif /* !PCC_GETCHAR */\\n\"\n            \"\\n\"\n            \"#ifndef PCC_MALLOC\\n\"\n            \"#define PCC_MALLOC(auxil, size) pcc_malloc_e(size)\\n\"\n            \"static void *pcc_malloc_e(size_t size) {\\n\"\n            \"    void *const p = malloc(size);\\n\"\n            \"    if (p == NULL) {\\n\"\n            \"        fprintf(stderr, \\\"Out of memory\\\\n\\\");\\n\"\n            \"        exit(1);\\n\"\n            \"    }\\n\"\n            \"    return p;\\n\"\n            \"}\\n\"\n            \"#endif /* !PCC_MALLOC */\\n\"\n            \"\\n\"\n            \"#ifndef PCC_REALLOC\\n\"\n            \"#define PCC_REALLOC(auxil, ptr, size) pcc_realloc_e(ptr, size)\\n\"\n            \"static void *pcc_realloc_e(void *ptr, size_t size) {\\n\"\n            \"    void *const p = realloc(ptr, size);\\n\"\n            \"    if (p == NULL) {\\n\"\n            \"        fprintf(stderr, \\\"Out of memory\\\\n\\\");\\n\"\n            \"        exit(1);\\n\"\n            \"    }\\n\"\n            \"    return p;\\n\"\n            \"}\\n\"\n            \"#endif /* !PCC_REALLOC */\\n\"\n            \"\\n\"\n            \"#ifndef PCC_FREE\\n\"\n            \"#define PCC_FREE(auxil, ptr) free(ptr)\\n\"\n            \"#endif /* !PCC_FREE */\\n\"\n            \"\\n\"\n            \"#ifndef PCC_DEBUG\\n\"\n            \"#define PCC_DEBUG(auxil, event, rule, level, pos, buffer, length) ((void)0)\\n\"\n            \"#endif /* !PCC_DEBUG */\\n\"\n            \"\\n\"\n            \"static char *pcc_strndup_e(pcc_auxil_t auxil, const char *str, size_t len) {\\n\"\n            \"    const size_t m = strnlen(str, len);\\n\"\n            \"    char *const s = (char *)PCC_MALLOC(auxil, m + 1);\\n\"\n            \"    memcpy(s, str, m);\\n\"\n            \"    s[m] = '\\\\0';\\n\"\n            \"    return s;\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_char_array__init(pcc_auxil_t auxil, pcc_char_array_t *array) {\\n\"\n            \"    array->len = 0;\\n\"\n            \"    array->max = 0;\\n\"\n            \"    array->buf = NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_char_array__add(pcc_auxil_t auxil, pcc_char_array_t *array, char ch) {\\n\"\n            \"    if (array->max <= array->len) {\\n\"\n            \"        const size_t n = array->len + 1;\\n\"\n            \"        size_t m = array->max;\\n\"\n            \"        if (m == 0) m = PCC_BUFFER_MIN_SIZE;\\n\"\n            \"        while (m < n && m != 0) m <<= 1;\\n\"\n            \"        if (m == 0) m = n;\\n\"\n            \"        array->buf = (char *)PCC_REALLOC(auxil, array->buf, m);\\n\"\n            \"        array->max = m;\\n\"\n            \"    }\\n\"\n            \"    array->buf[array->len++] = ch;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_char_array__term(pcc_auxil_t auxil, pcc_char_array_t *array) {\\n\"\n            \"    PCC_FREE(auxil, array->buf);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_value_table__init(pcc_auxil_t auxil, pcc_value_table_t *table) {\\n\"\n            \"    table->len = 0;\\n\"\n            \"    table->max = 0;\\n\"\n            \"    table->buf = NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"MARK_FUNC_AS_USED\\n\"\n            \"static void pcc_value_table__resize(pcc_auxil_t auxil, pcc_value_table_t *table, size_t len) {\\n\"\n            \"    if (table->max < len) {\\n\"\n            \"        size_t m = table->max;\\n\"\n            \"        if (m == 0) m = PCC_ARRAY_MIN_SIZE;\\n\"\n            \"        while (m < len && m != 0) m <<= 1;\\n\"\n            \"        if (m == 0) m = len;\\n\"\n            \"        table->buf = (pcc_value_t *)PCC_REALLOC(auxil, table->buf, sizeof(pcc_value_t) * m);\\n\"\n            \"        table->max = m;\\n\"\n            \"    }\\n\"\n            \"    table->len = len;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"MARK_FUNC_AS_USED\\n\"\n            \"static void pcc_value_table__clear(pcc_auxil_t auxil, pcc_value_table_t *table) {\\n\"\n            \"    memset(table->buf, 0, sizeof(pcc_value_t) * table->len);\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_value_table__term(pcc_auxil_t auxil, pcc_value_table_t *table) {\\n\"\n            \"    PCC_FREE(auxil, table->buf);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_value_refer_table__init(pcc_auxil_t auxil, pcc_value_refer_table_t *table) {\\n\"\n            \"    table->len = 0;\\n\"\n            \"    table->max = 0;\\n\"\n            \"    table->buf = NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_value_refer_table__resize(pcc_auxil_t auxil, pcc_value_refer_table_t *table, size_t len) {\\n\"\n            \"    size_t i;\\n\"\n            \"    if (table->max < len) {\\n\"\n            \"        size_t m = table->max;\\n\"\n            \"        if (m == 0) m = PCC_ARRAY_MIN_SIZE;\\n\"\n            \"        while (m < len && m != 0) m <<= 1;\\n\"\n            \"        if (m == 0) m = len;\\n\"\n            \"        table->buf = (pcc_value_t **)PCC_REALLOC(auxil, table->buf, sizeof(pcc_value_t *) * m);\\n\"\n            \"        table->max = m;\\n\"\n            \"    }\\n\"\n            \"    for (i = table->len; i < len; i++) table->buf[i] = NULL;\\n\"\n            \"    table->len = len;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_value_refer_table__term(pcc_auxil_t auxil, pcc_value_refer_table_t *table) {\\n\"\n            \"    PCC_FREE(auxil, table->buf);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_capture_table__init(pcc_auxil_t auxil, pcc_capture_table_t *table) {\\n\"\n            \"    table->len = 0;\\n\"\n            \"    table->max = 0;\\n\"\n            \"    table->buf = NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"MARK_FUNC_AS_USED\\n\"\n            \"static void pcc_capture_table__resize(pcc_auxil_t auxil, pcc_capture_table_t *table, size_t len) {\\n\"\n            \"    size_t i;\\n\"\n            \"    for (i = len; i < table->len; i++) PCC_FREE(auxil, table->buf[i].string);\\n\"\n            \"    if (table->max < len) {\\n\"\n            \"        size_t m = table->max;\\n\"\n            \"        if (m == 0) m = PCC_ARRAY_MIN_SIZE;\\n\"\n            \"        while (m < len && m != 0) m <<= 1;\\n\"\n            \"        if (m == 0) m = len;\\n\"\n            \"        table->buf = (pcc_capture_t *)PCC_REALLOC(auxil, table->buf, sizeof(pcc_capture_t) * m);\\n\"\n            \"        table->max = m;\\n\"\n            \"    }\\n\"\n            \"    for (i = table->len; i < len; i++) {\\n\"\n            \"        table->buf[i].range.start = 0;\\n\"\n            \"        table->buf[i].range.end = 0;\\n\"\n            \"        table->buf[i].string = NULL;\\n\"\n            \"    }\\n\"\n            \"    table->len = len;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_capture_table__term(pcc_auxil_t auxil, pcc_capture_table_t *table) {\\n\"\n            \"    while (table->len > 0) {\\n\"\n            \"        table->len--;\\n\"\n            \"        PCC_FREE(auxil, table->buf[table->len].string);\\n\"\n            \"    }\\n\"\n            \"    PCC_FREE(auxil, table->buf);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_capture_const_table__init(pcc_auxil_t auxil, pcc_capture_const_table_t *table) {\\n\"\n            \"    table->len = 0;\\n\"\n            \"    table->max = 0;\\n\"\n            \"    table->buf = NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_capture_const_table__resize(pcc_auxil_t auxil, pcc_capture_const_table_t *table, size_t len) {\\n\"\n            \"    size_t i;\\n\"\n            \"    if (table->max < len) {\\n\"\n            \"        size_t m = table->max;\\n\"\n            \"        if (m == 0) m = PCC_ARRAY_MIN_SIZE;\\n\"\n            \"        while (m < len && m != 0) m <<= 1;\\n\"\n            \"        if (m == 0) m = len;\\n\"\n            \"        table->buf = (const pcc_capture_t **)PCC_REALLOC(auxil, (pcc_capture_t **)table->buf, sizeof(const pcc_capture_t *) * m);\\n\"\n            \"        table->max = m;\\n\"\n            \"    }\\n\"\n            \"    for (i = table->len; i < len; i++) table->buf[i] = NULL;\\n\"\n            \"    table->len = len;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_capture_const_table__term(pcc_auxil_t auxil, pcc_capture_const_table_t *table) {\\n\"\n            \"    PCC_FREE(auxil, (void *)table->buf);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"MARK_FUNC_AS_USED\\n\"\n            \"static pcc_thunk_t *pcc_thunk__create_leaf(pcc_auxil_t auxil, pcc_action_t action, size_t valuec, size_t captc) {\\n\"\n            \"    pcc_thunk_t *const thunk = (pcc_thunk_t *)PCC_MALLOC(auxil, sizeof(pcc_thunk_t));\\n\"\n            \"    thunk->type = PCC_THUNK_LEAF;\\n\"\n            \"    pcc_value_refer_table__init(auxil, &thunk->data.leaf.values);\\n\"\n            \"    pcc_value_refer_table__resize(auxil, &thunk->data.leaf.values, valuec);\\n\"\n            \"    pcc_capture_const_table__init(auxil, &thunk->data.leaf.capts);\\n\"\n            \"    pcc_capture_const_table__resize(auxil, &thunk->data.leaf.capts, captc);\\n\"\n            \"    thunk->data.leaf.capt0.range.start = 0;\\n\"\n            \"    thunk->data.leaf.capt0.range.end = 0;\\n\"\n            \"    thunk->data.leaf.capt0.string = NULL;\\n\"\n            \"    thunk->data.leaf.action = action;\\n\"\n            \"    return thunk;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static pcc_thunk_t *pcc_thunk__create_node(pcc_auxil_t auxil, const pcc_thunk_array_t *thunks, pcc_value_t *value) {\\n\"\n            \"    pcc_thunk_t *const thunk = (pcc_thunk_t *)PCC_MALLOC(auxil, sizeof(pcc_thunk_t));\\n\"\n            \"    thunk->type = PCC_THUNK_NODE;\\n\"\n            \"    thunk->data.node.thunks = thunks;\\n\"\n            \"    thunk->data.node.value = value;\\n\"\n            \"    return thunk;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_thunk__destroy(pcc_auxil_t auxil, pcc_thunk_t *thunk) {\\n\"\n            \"    if (thunk == NULL) return;\\n\"\n            \"    switch (thunk->type) {\\n\"\n            \"    case PCC_THUNK_LEAF:\\n\"\n            \"        PCC_FREE(auxil, thunk->data.leaf.capt0.string);\\n\"\n            \"        pcc_capture_const_table__term(auxil, &thunk->data.leaf.capts);\\n\"\n            \"        pcc_value_refer_table__term(auxil, &thunk->data.leaf.values);\\n\"\n            \"        break;\\n\"\n            \"    case PCC_THUNK_NODE:\\n\"\n            \"        break;\\n\"\n            \"    default: /* unknown */\\n\"\n            \"        break;\\n\"\n            \"    }\\n\"\n            \"    PCC_FREE(auxil, thunk);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_thunk_array__init(pcc_auxil_t auxil, pcc_thunk_array_t *array) {\\n\"\n            \"    array->len = 0;\\n\"\n            \"    array->max = 0;\\n\"\n            \"    array->buf = NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_thunk_array__add(pcc_auxil_t auxil, pcc_thunk_array_t *array, pcc_thunk_t *thunk) {\\n\"\n            \"    if (array->max <= array->len) {\\n\"\n            \"        const size_t n = array->len + 1;\\n\"\n            \"        size_t m = array->max;\\n\"\n            \"        if (m == 0) m = PCC_ARRAY_MIN_SIZE;\\n\"\n            \"        while (m < n && m != 0) m <<= 1;\\n\"\n            \"        if (m == 0) m = n;\\n\"\n            \"        array->buf = (pcc_thunk_t **)PCC_REALLOC(auxil, array->buf, sizeof(pcc_thunk_t *) * m);\\n\"\n            \"        array->max = m;\\n\"\n            \"    }\\n\"\n            \"    array->buf[array->len++] = thunk;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_thunk_array__revert(pcc_auxil_t auxil, pcc_thunk_array_t *array, size_t len) {\\n\"\n            \"    while (array->len > len) {\\n\"\n            \"        array->len--;\\n\"\n            \"        pcc_thunk__destroy(auxil, array->buf[array->len]);\\n\"\n            \"    }\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_thunk_array__term(pcc_auxil_t auxil, pcc_thunk_array_t *array) {\\n\"\n            \"    while (array->len > 0) {\\n\"\n            \"        array->len--;\\n\"\n            \"        pcc_thunk__destroy(auxil, array->buf[array->len]);\\n\"\n            \"    }\\n\"\n            \"    PCC_FREE(auxil, array->buf);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_memory_recycler__init(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler, size_t element_size) {\\n\"\n            \"    recycler->pool_list = NULL;\\n\"\n            \"    recycler->entry_list = NULL;\\n\"\n            \"    recycler->element_size = element_size;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void *pcc_memory_recycler__supply(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler) {\\n\"\n            \"    if (recycler->entry_list) {\\n\"\n            \"        pcc_memory_entry_t *const tmp = recycler->entry_list;\\n\"\n            \"        recycler->entry_list = tmp->next;\\n\"\n            \"        return tmp;\\n\"\n            \"    }\\n\"\n            \"    if (!recycler->pool_list || recycler->pool_list->unused == 0) {\\n\"\n            \"        size_t size = PCC_POOL_MIN_SIZE;\\n\"\n            \"        if (recycler->pool_list) {\\n\"\n            \"            size = recycler->pool_list->allocated << 1;\\n\"\n            \"            if (size == 0) size = recycler->pool_list->allocated;\\n\"\n            \"        }\\n\"\n            \"        {\\n\"\n            \"            pcc_memory_pool_t *const pool = (pcc_memory_pool_t *)PCC_MALLOC(\\n\"\n            \"                auxil, sizeof(pcc_memory_pool_t) + recycler->element_size * size\\n\"\n            \"            );\\n\"\n            \"            pool->allocated = size;\\n\"\n            \"            pool->unused = size;\\n\"\n            \"            pool->next = recycler->pool_list;\\n\"\n            \"            recycler->pool_list = pool;\\n\"\n            \"        }\\n\"\n            \"    }\\n\"\n            \"    recycler->pool_list->unused--;\\n\"\n            \"    return (char *)recycler->pool_list + sizeof(pcc_memory_pool_t) + recycler->element_size * recycler->pool_list->unused;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_memory_recycler__recycle(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler, void *ptr) {\\n\"\n            \"    pcc_memory_entry_t *const tmp = (pcc_memory_entry_t *)ptr;\\n\"\n            \"    tmp->next = recycler->entry_list;\\n\"\n            \"    recycler->entry_list = tmp;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_memory_recycler__term(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler) {\\n\"\n            \"    while (recycler->pool_list) {\\n\"\n            \"        pcc_memory_pool_t *const tmp = recycler->pool_list;\\n\"\n            \"        recycler->pool_list = tmp->next;\\n\"\n            \"        PCC_FREE(auxil, tmp);\\n\"\n            \"    }\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"MARK_FUNC_AS_USED\\n\"\n            \"static pcc_thunk_chunk_t *pcc_thunk_chunk__create(pcc_context_t *ctx) {\\n\"\n            \"    pcc_thunk_chunk_t *const chunk = (pcc_thunk_chunk_t *)pcc_memory_recycler__supply(ctx->auxil, &ctx->thunk_chunk_recycler);\\n\"\n            \"    pcc_value_table__init(ctx->auxil, &chunk->values);\\n\"\n            \"    pcc_capture_table__init(ctx->auxil, &chunk->capts);\\n\"\n            \"    pcc_thunk_array__init(ctx->auxil, &chunk->thunks);\\n\"\n            \"    chunk->pos = 0;\\n\"\n            \"    return chunk;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_thunk_chunk__destroy(pcc_context_t *ctx, pcc_thunk_chunk_t *chunk) {\\n\"\n            \"    if (chunk == NULL) return;\\n\"\n            \"    pcc_thunk_array__term(ctx->auxil, &chunk->thunks);\\n\"\n            \"    pcc_capture_table__term(ctx->auxil, &chunk->capts);\\n\"\n            \"    pcc_value_table__term(ctx->auxil, &chunk->values);\\n\"\n            \"    pcc_memory_recycler__recycle(ctx->auxil, &ctx->thunk_chunk_recycler, chunk);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_rule_set__init(pcc_auxil_t auxil, pcc_rule_set_t *set) {\\n\"\n            \"    set->len = 0;\\n\"\n            \"    set->max = 0;\\n\"\n            \"    set->buf = NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static size_t pcc_rule_set__index(pcc_auxil_t auxil, const pcc_rule_set_t *set, pcc_rule_t rule) {\\n\"\n            \"    size_t i;\\n\"\n            \"    for (i = 0; i < set->len; i++) {\\n\"\n            \"        if (set->buf[i] == rule) return i;\\n\"\n            \"    }\\n\"\n            \"    return PCC_VOID_VALUE;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static pcc_bool_t pcc_rule_set__add(pcc_auxil_t auxil, pcc_rule_set_t *set, pcc_rule_t rule) {\\n\"\n            \"    const size_t i = pcc_rule_set__index(auxil, set, rule);\\n\"\n            \"    if (i != PCC_VOID_VALUE) return PCC_FALSE;\\n\"\n            \"    if (set->max <= set->len) {\\n\"\n            \"        const size_t n = set->len + 1;\\n\"\n            \"        size_t m = set->max;\\n\"\n            \"        if (m == 0) m = PCC_ARRAY_MIN_SIZE;\\n\"\n            \"        while (m < n && m != 0) m <<= 1;\\n\"\n            \"        if (m == 0) m = n;\\n\"\n            \"        set->buf = (pcc_rule_t *)PCC_REALLOC(auxil, set->buf, sizeof(pcc_rule_t) * m);\\n\"\n            \"        set->max = m;\\n\"\n            \"    }\\n\"\n            \"    set->buf[set->len++] = rule;\\n\"\n            \"    return PCC_TRUE;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static pcc_bool_t pcc_rule_set__remove(pcc_auxil_t auxil, pcc_rule_set_t *set, pcc_rule_t rule) {\\n\"\n            \"    const size_t i = pcc_rule_set__index(auxil, set, rule);\\n\"\n            \"    if (i == PCC_VOID_VALUE) return PCC_FALSE;\\n\"\n            \"    memmove(set->buf + i, set->buf + (i + 1), sizeof(pcc_rule_t) * (set->len - (i + 1)));\\n\"\n            \"    return PCC_TRUE;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_rule_set__clear(pcc_auxil_t auxil, pcc_rule_set_t *set) {\\n\"\n            \"    set->len = 0;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_rule_set__copy(pcc_auxil_t auxil, pcc_rule_set_t *set, const pcc_rule_set_t *src) {\\n\"\n            \"    size_t i;\\n\"\n            \"    pcc_rule_set__clear(auxil, set);\\n\"\n            \"    for (i = 0; i < src->len; i++) {\\n\"\n            \"        pcc_rule_set__add(auxil, set, src->buf[i]);\\n\"\n            \"    }\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_rule_set__term(pcc_auxil_t auxil, pcc_rule_set_t *set) {\\n\"\n            \"    PCC_FREE(auxil, set->buf);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static pcc_lr_head_t *pcc_lr_head__create(pcc_context_t *ctx, pcc_rule_t rule) {\\n\"\n            \"    pcc_lr_head_t *const head = (pcc_lr_head_t *)pcc_memory_recycler__supply(ctx->auxil, &ctx->lr_head_recycler);\\n\"\n            \"    head->rule = rule;\\n\"\n            \"    pcc_rule_set__init(ctx->auxil, &head->invol);\\n\"\n            \"    pcc_rule_set__init(ctx->auxil, &head->eval);\\n\"\n            \"    head->hold = NULL;\\n\"\n            \"    return head;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_head__destroy(pcc_context_t *ctx, pcc_lr_head_t *head) {\\n\"\n            \"    if (head == NULL) return;\\n\"\n            \"    pcc_lr_head__destroy(ctx, head->hold);\\n\"\n            \"    pcc_rule_set__term(ctx->auxil, &head->eval);\\n\"\n            \"    pcc_rule_set__term(ctx->auxil, &head->invol);\\n\"\n            \"    pcc_memory_recycler__recycle(ctx->auxil, &ctx->lr_head_recycler, head);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_lr_entry__destroy(pcc_auxil_t auxil, pcc_lr_entry_t *lr);\\n\"\n            \"\\n\"\n            \"static pcc_lr_answer_t *pcc_lr_answer__create(pcc_context_t *ctx, pcc_lr_answer_type_t type, size_t pos) {\\n\"\n            \"    pcc_lr_answer_t *answer = (pcc_lr_answer_t *)pcc_memory_recycler__supply(ctx->auxil, &ctx->lr_answer_recycler);\\n\"\n            \"    answer->type = type;\\n\"\n            \"    answer->pos = pos;\\n\"\n            \"    answer->hold = NULL;\\n\"\n            \"    switch (answer->type) {\\n\"\n            \"    case PCC_LR_ANSWER_LR:\\n\"\n            \"        answer->data.lr = NULL;\\n\"\n            \"        break;\\n\"\n            \"    case PCC_LR_ANSWER_CHUNK:\\n\"\n            \"        answer->data.chunk = NULL;\\n\"\n            \"        break;\\n\"\n            \"    default: /* unknown */\\n\"\n            \"        PCC_FREE(ctx->auxil, answer);\\n\"\n            \"        answer = NULL;\\n\"\n            \"    }\\n\"\n            \"    return answer;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_answer__set_chunk(pcc_context_t *ctx, pcc_lr_answer_t *answer, pcc_thunk_chunk_t *chunk) {\\n\"\n            \"    pcc_lr_answer_t *const a = pcc_lr_answer__create(ctx, answer->type, answer->pos);\\n\"\n            \"    switch (answer->type) {\\n\"\n            \"    case PCC_LR_ANSWER_LR:\\n\"\n            \"        a->data.lr = answer->data.lr;\\n\"\n            \"        break;\\n\"\n            \"    case PCC_LR_ANSWER_CHUNK:\\n\"\n            \"        a->data.chunk = answer->data.chunk;\\n\"\n            \"        break;\\n\"\n            \"    default: /* unknown */\\n\"\n            \"        break;\\n\"\n            \"    }\\n\"\n            \"    a->hold = answer->hold;\\n\"\n            \"    answer->hold = a;\\n\"\n            \"    answer->type = PCC_LR_ANSWER_CHUNK;\\n\"\n            \"    answer->data.chunk = chunk;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_answer__destroy(pcc_context_t *ctx, pcc_lr_answer_t *answer) {\\n\"\n            \"    while (answer != NULL) {\\n\"\n            \"        pcc_lr_answer_t *const a = answer->hold;\\n\"\n            \"        switch (answer->type) {\\n\"\n            \"        case PCC_LR_ANSWER_LR:\\n\"\n            \"            pcc_lr_entry__destroy(ctx->auxil, answer->data.lr);\\n\"\n            \"            break;\\n\"\n            \"        case PCC_LR_ANSWER_CHUNK:\\n\"\n            \"            pcc_thunk_chunk__destroy(ctx, answer->data.chunk);\\n\"\n            \"            break;\\n\"\n            \"        default: /* unknown */\\n\"\n            \"            break;\\n\"\n            \"        }\\n\"\n            \"        pcc_memory_recycler__recycle(ctx->auxil, &ctx->lr_answer_recycler, answer);\\n\"\n            \"        answer = a;\\n\"\n            \"    }\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_lr_memo_map__init(pcc_auxil_t auxil, pcc_lr_memo_map_t *map) {\\n\"\n            \"    map->len = 0;\\n\"\n            \"    map->max = 0;\\n\"\n            \"    map->buf = NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static size_t pcc_lr_memo_map__index(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule) {\\n\"\n            \"    size_t i;\\n\"\n            \"    for (i = 0; i < map->len; i++) {\\n\"\n            \"        if (map->buf[i].rule == rule) return i;\\n\"\n            \"    }\\n\"\n            \"    return PCC_VOID_VALUE;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_memo_map__put(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule, pcc_lr_answer_t *answer) {\\n\"\n            \"    const size_t i = pcc_lr_memo_map__index(ctx, map, rule);\\n\"\n            \"    if (i != PCC_VOID_VALUE) {\\n\"\n            \"        pcc_lr_answer__destroy(ctx, map->buf[i].answer);\\n\"\n            \"        map->buf[i].answer = answer;\\n\"\n            \"    }\\n\"\n            \"    else {\\n\"\n            \"        if (map->max <= map->len) {\\n\"\n            \"            const size_t n = map->len + 1;\\n\"\n            \"            size_t m = map->max;\\n\"\n            \"            if (m == 0) m = PCC_ARRAY_MIN_SIZE;\\n\"\n            \"            while (m < n && m != 0) m <<= 1;\\n\"\n            \"            if (m == 0) m = n;\\n\"\n            \"            map->buf = (pcc_lr_memo_t *)PCC_REALLOC(ctx->auxil, map->buf, sizeof(pcc_lr_memo_t) * m);\\n\"\n            \"            map->max = m;\\n\"\n            \"        }\\n\"\n            \"        map->buf[map->len].rule = rule;\\n\"\n            \"        map->buf[map->len].answer = answer;\\n\"\n            \"        map->len++;\\n\"\n            \"    }\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static pcc_lr_answer_t *pcc_lr_memo_map__get(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule) {\\n\"\n            \"    const size_t i = pcc_lr_memo_map__index(ctx, map, rule);\\n\"\n            \"    return (i != PCC_VOID_VALUE) ? map->buf[i].answer : NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_memo_map__term(pcc_context_t *ctx, pcc_lr_memo_map_t *map) {\\n\"\n            \"    while (map->len > 0) {\\n\"\n            \"        map->len--;\\n\"\n            \"        pcc_lr_answer__destroy(ctx, map->buf[map->len].answer);\\n\"\n            \"    }\\n\"\n            \"    PCC_FREE(ctx->auxil, map->buf);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static pcc_lr_table_entry_t *pcc_lr_table_entry__create(pcc_context_t *ctx) {\\n\"\n            \"    pcc_lr_table_entry_t *const entry = (pcc_lr_table_entry_t *)PCC_MALLOC(ctx->auxil, sizeof(pcc_lr_table_entry_t));\\n\"\n            \"    entry->head = NULL;\\n\"\n            \"    pcc_lr_memo_map__init(ctx->auxil, &entry->memos);\\n\"\n            \"    entry->hold_a = NULL;\\n\"\n            \"    entry->hold_h = NULL;\\n\"\n            \"    return entry;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_table_entry__destroy(pcc_context_t *ctx, pcc_lr_table_entry_t *entry) {\\n\"\n            \"    if (entry == NULL) return;\\n\"\n            \"    pcc_lr_head__destroy(ctx, entry->hold_h);\\n\"\n            \"    pcc_lr_answer__destroy(ctx, entry->hold_a);\\n\"\n            \"    pcc_lr_memo_map__term(ctx, &entry->memos);\\n\"\n            \"    PCC_FREE(ctx->auxil, entry);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_lr_table__init(pcc_auxil_t auxil, pcc_lr_table_t *table) {\\n\"\n            \"    table->ofs = 0;\\n\"\n            \"    table->len = 0;\\n\"\n            \"    table->max = 0;\\n\"\n            \"    table->buf = NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_table__resize(pcc_context_t *ctx, pcc_lr_table_t *table, size_t len) {\\n\"\n            \"    size_t i;\\n\"\n            \"    for (i = len; i < table->len; i++) pcc_lr_table_entry__destroy(ctx, table->buf[i]);\\n\"\n            \"    if (table->max < len) {\\n\"\n            \"        size_t m = table->max;\\n\"\n            \"        if (m == 0) m = PCC_ARRAY_MIN_SIZE;\\n\"\n            \"        while (m < len && m != 0) m <<= 1;\\n\"\n            \"        if (m == 0) m = len;\\n\"\n            \"        table->buf = (pcc_lr_table_entry_t **)PCC_REALLOC(ctx->auxil, table->buf, sizeof(pcc_lr_table_entry_t *) * m);\\n\"\n            \"        table->max = m;\\n\"\n            \"    }\\n\"\n            \"    for (i = table->len; i < len; i++) table->buf[i] = NULL;\\n\"\n            \"    table->len = len;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_table__set_head(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_lr_head_t *head) {\\n\"\n            \"    index += table->ofs;\\n\"\n            \"    if (index >= table->len) pcc_lr_table__resize(ctx, table, index + 1);\\n\"\n            \"    if (table->buf[index] == NULL) table->buf[index] = pcc_lr_table_entry__create(ctx);\\n\"\n            \"    table->buf[index]->head = head;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_table__hold_head(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_lr_head_t *head) {\\n\"\n            \"    index += table->ofs;\\n\"\n            \"    if (index >= table->len) pcc_lr_table__resize(ctx, table, index + 1);\\n\"\n            \"    if (table->buf[index] == NULL) table->buf[index] = pcc_lr_table_entry__create(ctx);\\n\"\n            \"    head->hold = table->buf[index]->hold_h;\\n\"\n            \"    table->buf[index]->hold_h = head;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_table__set_answer(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_rule_t rule, pcc_lr_answer_t *answer) {\\n\"\n            \"    index += table->ofs;\\n\"\n            \"    if (index >= table->len) pcc_lr_table__resize(ctx, table, index + 1);\\n\"\n            \"    if (table->buf[index] == NULL) table->buf[index] = pcc_lr_table_entry__create(ctx);\\n\"\n            \"    pcc_lr_memo_map__put(ctx, &table->buf[index]->memos, rule, answer);\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_table__hold_answer(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_lr_answer_t *answer) {\\n\"\n            \"    index += table->ofs;\\n\"\n            \"    if (index >= table->len) pcc_lr_table__resize(ctx, table, index + 1);\\n\"\n            \"    if (table->buf[index] == NULL) table->buf[index] = pcc_lr_table_entry__create(ctx);\\n\"\n            \"    answer->hold = table->buf[index]->hold_a;\\n\"\n            \"    table->buf[index]->hold_a = answer;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static pcc_lr_head_t *pcc_lr_table__get_head(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index) {\\n\"\n            \"    index += table->ofs;\\n\"\n            \"    if (index >= table->len || table->buf[index] == NULL) return NULL;\\n\"\n            \"    return table->buf[index]->head;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static pcc_lr_answer_t *pcc_lr_table__get_answer(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_rule_t rule) {\\n\"\n            \"    index += table->ofs;\\n\"\n            \"    if (index >= table->len || table->buf[index] == NULL) return NULL;\\n\"\n            \"    return pcc_lr_memo_map__get(ctx, &table->buf[index]->memos, rule);\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_table__shift(pcc_context_t *ctx, pcc_lr_table_t *table, size_t count) {\\n\"\n            \"    size_t i;\\n\"\n            \"    if (count > table->len - table->ofs) count = table->len - table->ofs;\\n\"\n            \"    for (i = 0; i < count; i++) pcc_lr_table_entry__destroy(ctx, table->buf[table->ofs++]);\\n\"\n            \"    if (table->ofs > (table->max >> 1)) {\\n\"\n            \"        memmove(table->buf, table->buf + table->ofs, sizeof(pcc_lr_table_entry_t *) * (table->len - table->ofs));\\n\"\n            \"        table->len -= table->ofs;\\n\"\n            \"        table->ofs = 0;\\n\"\n            \"    }\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_table__term(pcc_context_t *ctx, pcc_lr_table_t *table) {\\n\"\n            \"    while (table->len > table->ofs) {\\n\"\n            \"        table->len--;\\n\"\n            \"        pcc_lr_table_entry__destroy(ctx, table->buf[table->len]);\\n\"\n            \"    }\\n\"\n            \"    PCC_FREE(ctx->auxil, table->buf);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static pcc_lr_entry_t *pcc_lr_entry__create(pcc_auxil_t auxil, pcc_rule_t rule) {\\n\"\n            \"    pcc_lr_entry_t *const lr = (pcc_lr_entry_t *)PCC_MALLOC(auxil, sizeof(pcc_lr_entry_t));\\n\"\n            \"    lr->rule = rule;\\n\"\n            \"    lr->seed = NULL;\\n\"\n            \"    lr->head = NULL;\\n\"\n            \"    return lr;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_entry__destroy(pcc_auxil_t auxil, pcc_lr_entry_t *lr) {\\n\"\n            \"    PCC_FREE(auxil, lr);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_lr_stack__init(pcc_auxil_t auxil, pcc_lr_stack_t *stack) {\\n\"\n            \"    stack->len = 0;\\n\"\n            \"    stack->max = 0;\\n\"\n            \"    stack->buf = NULL;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_stack__push(pcc_auxil_t auxil, pcc_lr_stack_t *stack, pcc_lr_entry_t *lr) {\\n\"\n            \"    if (stack->max <= stack->len) {\\n\"\n            \"        const size_t n = stack->len + 1;\\n\"\n            \"        size_t m = stack->max;\\n\"\n            \"        if (m == 0) m = PCC_ARRAY_MIN_SIZE;\\n\"\n            \"        while (m < n && m != 0) m <<= 1;\\n\"\n            \"        if (m == 0) m = n;\\n\"\n            \"        stack->buf = (pcc_lr_entry_t **)PCC_REALLOC(auxil, stack->buf, sizeof(pcc_lr_entry_t *) * m);\\n\"\n            \"        stack->max = m;\\n\"\n            \"    }\\n\"\n            \"    stack->buf[stack->len++] = lr;\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static pcc_lr_entry_t *pcc_lr_stack__pop(pcc_auxil_t auxil, pcc_lr_stack_t *stack) {\\n\"\n            \"    return stack->buf[--stack->len];\\n\"\n            \"}\\n\"\n            \"\\n\"\n            \"static void pcc_lr_stack__term(pcc_auxil_t auxil, pcc_lr_stack_t *stack) {\\n\"\n            \"    PCC_FREE(auxil, stack->buf);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static pcc_context_t *pcc_context__create(pcc_auxil_t auxil) {\\n\"\n            \"    pcc_context_t *const ctx = (pcc_context_t *)PCC_MALLOC(auxil, sizeof(pcc_context_t));\\n\"\n            \"    ctx->pos = 0;\\n\"\n            \"    ctx->cur = 0;\\n\"\n            \"    ctx->level = 0;\\n\"\n            \"    pcc_char_array__init(auxil, &ctx->buffer);\\n\"\n            \"    pcc_lr_table__init(auxil, &ctx->lrtable);\\n\"\n            \"    pcc_lr_stack__init(auxil, &ctx->lrstack);\\n\"\n            \"    pcc_thunk_array__init(auxil, &ctx->thunks);\\n\"\n            \"    pcc_memory_recycler__init(auxil, &ctx->thunk_chunk_recycler, sizeof(pcc_thunk_chunk_t));\\n\"\n            \"    pcc_memory_recycler__init(auxil, &ctx->lr_head_recycler, sizeof(pcc_lr_head_t));\\n\"\n            \"    pcc_memory_recycler__init(auxil, &ctx->lr_answer_recycler, sizeof(pcc_lr_answer_t));\\n\"\n            \"    ctx->auxil = auxil;\\n\"\n            \"    return ctx;\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static void pcc_context__destroy(pcc_context_t *ctx) {\\n\"\n            \"    if (ctx == NULL) return;\\n\"\n            \"    pcc_thunk_array__term(ctx->auxil, &ctx->thunks);\\n\"\n            \"    pcc_lr_stack__term(ctx->auxil, &ctx->lrstack);\\n\"\n            \"    pcc_lr_table__term(ctx, &ctx->lrtable);\\n\"\n            \"    pcc_char_array__term(ctx->auxil, &ctx->buffer);\\n\"\n            \"    pcc_memory_recycler__term(ctx->auxil, &ctx->thunk_chunk_recycler);\\n\"\n            \"    pcc_memory_recycler__term(ctx->auxil, &ctx->lr_head_recycler);\\n\"\n            \"    pcc_memory_recycler__term(ctx->auxil, &ctx->lr_answer_recycler);\\n\"\n            \"    PCC_FREE(ctx->auxil, ctx);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"static size_t pcc_refill_buffer(pcc_context_t *ctx, size_t num) {\\n\"\n            \"    if (ctx->buffer.len >= ctx->cur + num) return ctx->buffer.len - ctx->cur;\\n\"\n            \"    while (ctx->buffer.len < ctx->cur + num) {\\n\"\n            \"        const int c = PCC_GETCHAR(ctx->auxil);\\n\"\n            \"        if (c < 0) break;\\n\"\n            \"        pcc_char_array__add(ctx->auxil, &ctx->buffer, (char)c);\\n\"\n            \"    }\\n\"\n            \"    return ctx->buffer.len - ctx->cur;\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"MARK_FUNC_AS_USED\\n\"\n            \"static void pcc_commit_buffer(pcc_context_t *ctx) {\\n\"\n            \"    memmove(ctx->buffer.buf, ctx->buffer.buf + ctx->cur, ctx->buffer.len - ctx->cur);\\n\"\n            \"    ctx->buffer.len -= ctx->cur;\\n\"\n            \"    ctx->pos += ctx->cur;\\n\"\n            \"    pcc_lr_table__shift(ctx, &ctx->lrtable, ctx->cur);\\n\"\n            \"    ctx->cur = 0;\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"MARK_FUNC_AS_USED\\n\"\n            \"static const char *pcc_get_capture_string(pcc_context_t *ctx, const pcc_capture_t *capt) {\\n\"\n            \"    if (capt->string == NULL)\\n\"\n            \"        ((pcc_capture_t *)capt)->string =\\n\"\n            \"            pcc_strndup_e(ctx->auxil, ctx->buffer.buf + capt->range.start, capt->range.end - capt->range.start);\\n\"\n            \"    return capt->string;\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        if (ctx->flags & CODE_FLAG__UTF8_CHARCLASS_USED) {\n            stream__puts(\n                &sstream,\n                \"static size_t pcc_get_char_as_utf32(pcc_context_t *ctx, int *out) { /* with checking UTF-8 validity */\\n\"\n                \"    int c, u;\\n\"\n                \"    size_t n;\\n\"\n                \"    if (pcc_refill_buffer(ctx, 1) < 1) return 0;\\n\"\n                \"    c = (int)(unsigned char)ctx->buffer.buf[ctx->cur];\\n\"\n                \"    n = (c < 0x80) ? 1 :\\n\"\n                \"        ((c & 0xe0) == 0xc0) ? 2 :\\n\"\n                \"        ((c & 0xf0) == 0xe0) ? 3 :\\n\"\n                \"        ((c & 0xf8) == 0xf0) ? 4 : 0;\\n\"\n                \"    if (n < 1) return 0;\\n\"\n                \"    if (pcc_refill_buffer(ctx, n) < n) return 0;\\n\"\n                \"    switch (n) {\\n\"\n                \"    case 1:\\n\"\n                \"        u = c;\\n\"\n                \"        break;\\n\"\n                \"    case 2:\\n\"\n                \"        u = c & 0x1f;\\n\"\n                \"        c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 1];\\n\"\n                \"        if ((c & 0xc0) != 0x80) return 0;\\n\"\n                \"        u <<= 6; u |= c & 0x3f;\\n\"\n                \"        if (u < 0x80) return 0;\\n\"\n                \"        break;\\n\"\n                \"    case 3:\\n\"\n                \"        u = c & 0x0f;\\n\"\n                \"        c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 1];\\n\"\n                \"        if ((c & 0xc0) != 0x80) return 0;\\n\"\n                \"        u <<= 6; u |= c & 0x3f;\\n\"\n                \"        c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 2];\\n\"\n                \"        if ((c & 0xc0) != 0x80) return 0;\\n\"\n                \"        u <<= 6; u |= c & 0x3f;\\n\"\n                \"        if (u < 0x800) return 0;\\n\"\n                \"        break;\\n\"\n                \"    case 4:\\n\"\n                \"        u = c & 0x07;\\n\"\n                \"        c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 1];\\n\"\n                \"        if ((c & 0xc0) != 0x80) return 0;\\n\"\n                \"        u <<= 6; u |= c & 0x3f;\\n\"\n                \"        c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 2];\\n\"\n                \"        if ((c & 0xc0) != 0x80) return 0;\\n\"\n                \"        u <<= 6; u |= c & 0x3f;\\n\"\n                \"        c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 3];\\n\"\n                \"        if ((c & 0xc0) != 0x80) return 0;\\n\"\n                \"        u <<= 6; u |= c & 0x3f;\\n\"\n                \"        if (u < 0x10000 || u > 0x10ffff) return 0;\\n\"\n                \"        break;\\n\"\n                \"    default:\\n\"\n                \"        return 0;\\n\"\n                \"    }\\n\"\n                \"    if (out) *out = u;\\n\"\n                \"    return n;\\n\"\n                \"}\\n\"\n                \"\\n\"\n            );\n        }\n        stream__puts(\n            &sstream,\n            \"MARK_FUNC_AS_USED\\n\"\n            \"static pcc_bool_t pcc_apply_rule(pcc_context_t *ctx, pcc_rule_t rule, pcc_thunk_array_t *thunks, pcc_value_t *value) {\\n\"\n            \"    static pcc_value_t null;\\n\"\n            \"    pcc_thunk_chunk_t *c = NULL;\\n\"\n            \"    const size_t p = ctx->pos + ctx->cur;\\n\"\n            \"    pcc_bool_t b = PCC_TRUE;\\n\"\n            \"    pcc_lr_answer_t *a = pcc_lr_table__get_answer(ctx, &ctx->lrtable, p, rule);\\n\"\n            \"    pcc_lr_head_t *h = pcc_lr_table__get_head(ctx, &ctx->lrtable, p);\\n\"\n            \"    if (h != NULL) {\\n\"\n            \"        if (a == NULL && rule != h->rule && pcc_rule_set__index(ctx->auxil, &h->invol, rule) == PCC_VOID_VALUE) {\\n\"\n            \"            b = PCC_FALSE;\\n\"\n            \"            c = NULL;\\n\"\n            \"        }\\n\"\n            \"        else if (pcc_rule_set__remove(ctx->auxil, &h->eval, rule)) {\\n\"\n            \"            b = PCC_FALSE;\\n\"\n            \"            c = rule(ctx);\\n\"\n            \"            a = pcc_lr_answer__create(ctx, PCC_LR_ANSWER_CHUNK, ctx->pos + ctx->cur);\\n\"\n            \"            a->data.chunk = c;\\n\"\n            \"            pcc_lr_table__hold_answer(ctx, &ctx->lrtable, p, a);\\n\"\n            \"        }\\n\"\n            \"    }\\n\"\n            \"    if (b) {\\n\"\n            \"        if (a != NULL) {\\n\"\n            \"            ctx->cur = a->pos - ctx->pos;\\n\"\n            \"            switch (a->type) {\\n\"\n            \"            case PCC_LR_ANSWER_LR:\\n\"\n            \"                if (a->data.lr->head == NULL) {\\n\"\n            \"                    a->data.lr->head = pcc_lr_head__create(ctx, rule);\\n\"\n            \"                    pcc_lr_table__hold_head(ctx, &ctx->lrtable, p, a->data.lr->head);\\n\"\n            \"                }\\n\"\n            \"                {\\n\"\n            \"                    size_t i = ctx->lrstack.len;\\n\"\n            \"                    while (i > 0) {\\n\"\n            \"                        i--;\\n\"\n            \"                        if (ctx->lrstack.buf[i]->head == a->data.lr->head) break;\\n\"\n            \"                        ctx->lrstack.buf[i]->head = a->data.lr->head;\\n\"\n            \"                        pcc_rule_set__add(ctx->auxil, &a->data.lr->head->invol, ctx->lrstack.buf[i]->rule);\\n\"\n            \"                    }\\n\"\n            \"                }\\n\"\n            \"                c = a->data.lr->seed;\\n\"\n            \"                break;\\n\"\n            \"            case PCC_LR_ANSWER_CHUNK:\\n\"\n            \"                c = a->data.chunk;\\n\"\n            \"                break;\\n\"\n            \"            default: /* unknown */\\n\"\n            \"                break;\\n\"\n            \"            }\\n\"\n            \"        }\\n\"\n            \"        else {\\n\"\n            \"            pcc_lr_entry_t *const e = pcc_lr_entry__create(ctx->auxil, rule);\\n\"\n            \"            pcc_lr_stack__push(ctx->auxil, &ctx->lrstack, e);\\n\"\n            \"            a = pcc_lr_answer__create(ctx, PCC_LR_ANSWER_LR, p);\\n\"\n            \"            a->data.lr = e;\\n\"\n            \"            pcc_lr_table__set_answer(ctx, &ctx->lrtable, p, rule, a);\\n\"\n            \"            c = rule(ctx);\\n\"\n            \"            pcc_lr_stack__pop(ctx->auxil, &ctx->lrstack);\\n\"\n            \"            a->pos = ctx->pos + ctx->cur;\\n\"\n            \"            if (e->head == NULL) {\\n\"\n            \"                pcc_lr_answer__set_chunk(ctx, a, c);\\n\"\n            \"            }\\n\"\n            \"            else {\\n\"\n            \"                e->seed = c;\\n\"\n            \"                h = a->data.lr->head;\\n\"\n            \"                if (h->rule != rule) {\\n\"\n            \"                    c = a->data.lr->seed;\\n\"\n            \"                    a = pcc_lr_answer__create(ctx, PCC_LR_ANSWER_CHUNK, ctx->pos + ctx->cur);\\n\"\n            \"                    a->data.chunk = c;\\n\"\n            \"                    pcc_lr_table__hold_answer(ctx, &ctx->lrtable, p, a);\\n\"\n            \"                }\\n\"\n            \"                else {\\n\"\n            \"                    pcc_lr_answer__set_chunk(ctx, a, a->data.lr->seed);\\n\"\n            \"                    if (a->data.chunk == NULL) {\\n\"\n            \"                        c = NULL;\\n\"\n            \"                    }\\n\"\n            \"                    else {\\n\"\n            \"                        pcc_lr_table__set_head(ctx, &ctx->lrtable, p, h);\\n\"\n            \"                        for (;;) {\\n\"\n            \"                            ctx->cur = p - ctx->pos;\\n\"\n            \"                            pcc_rule_set__copy(ctx->auxil, &h->eval, &h->invol);\\n\"\n            \"                            c = rule(ctx);\\n\"\n            \"                            if (c == NULL || ctx->pos + ctx->cur <= a->pos) break;\\n\"\n            \"                            pcc_lr_answer__set_chunk(ctx, a, c);\\n\"\n            \"                            a->pos = ctx->pos + ctx->cur;\\n\"\n            \"                        }\\n\"\n            \"                        pcc_thunk_chunk__destroy(ctx, c);\\n\"\n            \"                        pcc_lr_table__set_head(ctx, &ctx->lrtable, p, NULL);\\n\"\n            \"                        ctx->cur = a->pos - ctx->pos;\\n\"\n            \"                        c = a->data.chunk;\\n\"\n            \"                    }\\n\"\n            \"                }\\n\"\n            \"            }\\n\"\n            \"        }\\n\"\n            \"    }\\n\"\n            \"    if (c == NULL) return PCC_FALSE;\\n\"\n            \"    if (value == NULL) value = &null;\\n\"\n            \"    memset(value, 0, sizeof(pcc_value_t)); /* in case */\\n\"\n            \"    pcc_thunk_array__add(ctx->auxil, thunks, pcc_thunk__create_node(ctx->auxil, &c->thunks, value));\\n\"\n            \"    return PCC_TRUE;\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__puts(\n            &sstream,\n            \"MARK_FUNC_AS_USED\\n\"\n            \"static void pcc_do_action(pcc_context_t *ctx, const pcc_thunk_array_t *thunks, pcc_value_t *value) {\\n\"\n            \"    size_t i;\\n\"\n            \"    for (i = 0; i < thunks->len; i++) {\\n\"\n            \"        pcc_thunk_t *const thunk = thunks->buf[i];\\n\"\n            \"        switch (thunk->type) {\\n\"\n            \"        case PCC_THUNK_LEAF:\\n\"\n            \"            thunk->data.leaf.action(ctx, thunk, value);\\n\"\n            \"            break;\\n\"\n            \"        case PCC_THUNK_NODE:\\n\"\n            \"            pcc_do_action(ctx, thunk->data.node.thunks, thunk->data.node.value);\\n\"\n            \"            break;\\n\"\n            \"        default: /* unknown */\\n\"\n            \"            break;\\n\"\n            \"        }\\n\"\n            \"    }\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        {\n            size_t i, j, k;\n            for (i = 0; i < ctx->rules.len; i++) {\n                const node_rule_t *const r = &ctx->rules.buf[i]->data.rule;\n                for (j = 0; j < r->codes.len; j++) {\n                    const code_block_t *b;\n                    size_t d;\n                    const node_const_array_t *v, *c;\n                    switch (r->codes.buf[j]->type) {\n                    case NODE_ACTION:\n                        b = &r->codes.buf[j]->data.action.code;\n                        d = r->codes.buf[j]->data.action.index;\n                        v = &r->codes.buf[j]->data.action.vars;\n                        c = &r->codes.buf[j]->data.action.capts;\n                        break;\n                    case NODE_ERROR:\n                        b = &r->codes.buf[j]->data.error.code;\n                        d = r->codes.buf[j]->data.error.index;\n                        v = &r->codes.buf[j]->data.error.vars;\n                        c = &r->codes.buf[j]->data.error.capts;\n                        break;\n                    default:\n                        print_error(\"Internal error [%d]\\n\", __LINE__);\n                        exit(-1);\n                    }\n                    stream__printf(\n                        &sstream,\n                        \"static void pcc_action_%s_\" FMT_LU \"(%s_context_t *__pcc_ctx, pcc_thunk_t *__pcc_in, pcc_value_t *__pcc_out) {\\n\",\n                        r->name, (ulong_t)d, get_prefix(ctx)\n                    );\n                    stream__puts(\n                        &sstream,\n                        \"#define auxil (__pcc_ctx->auxil)\\n\"\n                        \"#define __ (*__pcc_out)\\n\"\n                    );\n                    k = 0;\n                    while (k < v->len) {\n                        assert(v->buf[k]->type == NODE_REFERENCE);\n                        stream__printf(\n                            &sstream,\n                            \"#define %s (*__pcc_in->data.leaf.values.buf[\" FMT_LU \"])\\n\",\n                            v->buf[k]->data.reference.var, (ulong_t)v->buf[k]->data.reference.index\n                        );\n                        k++;\n                    }\n                    stream__puts(\n                        &sstream,\n                        \"#define _0 pcc_get_capture_string(__pcc_ctx, &__pcc_in->data.leaf.capt0)\\n\"\n                        \"#define _0s ((const size_t)(__pcc_ctx->pos + __pcc_in->data.leaf.capt0.range.start))\\n\"\n                        \"#define _0e ((const size_t)(__pcc_ctx->pos + __pcc_in->data.leaf.capt0.range.end))\\n\"\n                    );\n                    k = 0;\n                    while (k < c->len) {\n                        assert(c->buf[k]->type == NODE_CAPTURE);\n                        stream__printf(\n                            &sstream,\n                            \"#define _\" FMT_LU \" pcc_get_capture_string(__pcc_ctx, __pcc_in->data.leaf.capts.buf[\" FMT_LU \"])\\n\",\n                            (ulong_t)(c->buf[k]->data.capture.index + 1), (ulong_t)c->buf[k]->data.capture.index\n                        );\n                        stream__printf(\n                            &sstream,\n                            \"#define _\" FMT_LU \"s ((const size_t)(__pcc_ctx->pos + __pcc_in->data.leaf.capts.buf[\" FMT_LU \"]->range.start))\\n\",\n                            (ulong_t)(c->buf[k]->data.capture.index + 1), (ulong_t)c->buf[k]->data.capture.index\n                        );\n                        stream__printf(\n                            &sstream,\n                            \"#define _\" FMT_LU \"e ((const size_t)(__pcc_ctx->pos + __pcc_in->data.leaf.capts.buf[\" FMT_LU \"]->range.end))\\n\",\n                            (ulong_t)(c->buf[k]->data.capture.index + 1), (ulong_t)c->buf[k]->data.capture.index\n                        );\n                        k++;\n                    }\n                    stream__write_code_block(&sstream, b->text, b->len, 4, ctx->iname, b->line);\n                    k = c->len;\n                    while (k > 0) {\n                        k--;\n                        assert(c->buf[k]->type == NODE_CAPTURE);\n                        stream__printf(\n                            &sstream,\n                            \"#undef _\" FMT_LU \"e\\n\",\n                            (ulong_t)(c->buf[k]->data.capture.index + 1)\n                        );\n                        stream__printf(\n                            &sstream,\n                            \"#undef _\" FMT_LU \"s\\n\",\n                            (ulong_t)(c->buf[k]->data.capture.index + 1)\n                        );\n                        stream__printf(\n                            &sstream,\n                            \"#undef _\" FMT_LU \"\\n\",\n                            (ulong_t)(c->buf[k]->data.capture.index + 1)\n                        );\n                    }\n                    stream__puts(\n                        &sstream,\n                        \"#undef _0e\\n\"\n                        \"#undef _0s\\n\"\n                        \"#undef _0\\n\"\n                    );\n                    k = v->len;\n                    while (k > 0) {\n                        k--;\n                        assert(v->buf[k]->type == NODE_REFERENCE);\n                        stream__printf(\n                            &sstream,\n                            \"#undef %s\\n\",\n                            v->buf[k]->data.reference.var\n                        );\n                    }\n                    stream__puts(\n                        &sstream,\n                        \"#undef __\\n\"\n                        \"#undef auxil\\n\"\n                    );\n                    stream__puts(\n                        &sstream,\n                        \"}\\n\"\n                        \"\\n\"\n                    );\n                }\n            }\n        }\n        {\n            size_t i;\n            for (i = 0; i < ctx->rules.len; i++) {\n                stream__printf(\n                    &sstream,\n                    \"static pcc_thunk_chunk_t *pcc_evaluate_rule_%s(pcc_context_t *ctx);\\n\",\n                    ctx->rules.buf[i]->data.rule.name\n                );\n            }\n            stream__puts(\n                &sstream,\n                \"\\n\"\n            );\n            for (i = 0; i < ctx->rules.len; i++) {\n                code_reach_t r;\n                generate_t g;\n                g.stream = &sstream;\n                g.rule = ctx->rules.buf[i];\n                g.label = 0;\n                g.ascii = ctx->opts.ascii;\n                stream__printf(\n                    &sstream,\n                    \"static pcc_thunk_chunk_t *pcc_evaluate_rule_%s(pcc_context_t *ctx) {\\n\",\n                    ctx->rules.buf[i]->data.rule.name\n                );\n                stream__printf(\n                    &sstream,\n                    \"    pcc_thunk_chunk_t *const chunk = pcc_thunk_chunk__create(ctx);\\n\"\n                    \"    chunk->pos = ctx->cur;\\n\"\n                    \"    PCC_DEBUG(ctx->auxil, PCC_DBG_EVALUATE, \\\"%s\\\", ctx->level, chunk->pos, (ctx->buffer.buf + chunk->pos), (ctx->buffer.len - chunk->pos));\\n\"\n                    \"    ctx->level++;\\n\",\n                    ctx->rules.buf[i]->data.rule.name\n                );\n                if (ctx->rules.buf[i]->data.rule.capts.len > 0) {\n                    stream__printf(\n                        &sstream,\n                        \"    pcc_capture_table__resize(ctx->auxil, &chunk->capts, \" FMT_LU \");\\n\",\n                        (ulong_t)ctx->rules.buf[i]->data.rule.capts.len\n                    );\n                }\n                if (ctx->rules.buf[i]->data.rule.vars.len > 0) {\n                    stream__printf(\n                        &sstream,\n                        \"    pcc_value_table__resize(ctx->auxil, &chunk->values, \" FMT_LU \");\\n\",\n                        (ulong_t)ctx->rules.buf[i]->data.rule.vars.len\n                    );\n                    stream__puts(\n                        &sstream,\n                        \"    pcc_value_table__clear(ctx->auxil, &chunk->values);\\n\"\n                    );\n                }\n                r = generate_code(&g, ctx->rules.buf[i]->data.rule.expr, 0, 4, FALSE);\n                stream__printf(\n                    &sstream,\n                    \"    ctx->level--;\\n\"\n                    \"    PCC_DEBUG(ctx->auxil, PCC_DBG_MATCH, \\\"%s\\\", ctx->level, chunk->pos, (ctx->buffer.buf + chunk->pos), (ctx->cur - chunk->pos));\\n\"\n                    \"    return chunk;\\n\",\n                    ctx->rules.buf[i]->data.rule.name\n                );\n                if (r != CODE_REACH__ALWAYS_SUCCEED) {\n                    stream__printf(\n                        &sstream,\n                        \"L0000:;\\n\"\n                        \"    ctx->level--;\\n\"\n                        \"    PCC_DEBUG(ctx->auxil, PCC_DBG_NOMATCH, \\\"%s\\\", ctx->level, chunk->pos, (ctx->buffer.buf + chunk->pos), (ctx->cur - chunk->pos));\\n\"\n                        \"    pcc_thunk_chunk__destroy(ctx, chunk);\\n\"\n                        \"    return NULL;\\n\",\n                        ctx->rules.buf[i]->data.rule.name\n                    );\n                }\n                stream__puts(\n                    &sstream,\n                    \"}\\n\"\n                    \"\\n\"\n                );\n            }\n        }\n        stream__printf(\n            &sstream,\n            \"%s_context_t *%s_create(%s%sauxil) {\\n\",\n            get_prefix(ctx), get_prefix(ctx),\n            at, ap ? \"\" : \" \"\n        );\n        stream__puts(\n            &sstream,\n            \"    return pcc_context__create(auxil);\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__printf(\n            &sstream,\n            \"int %s_parse(%s_context_t *ctx, %s%s*ret) {\\n\",\n            get_prefix(ctx), get_prefix(ctx),\n            vt, vp ? \"\" : \" \"\n        );\n        if (ctx->rules.len > 0) {\n            stream__printf(\n                &sstream,\n                \"    if (pcc_apply_rule(ctx, pcc_evaluate_rule_%s, &ctx->thunks, ret))\\n\",\n                ctx->rules.buf[0]->data.rule.name\n            );\n            stream__puts(\n                &sstream,\n                \"        pcc_do_action(ctx, &ctx->thunks, ret);\\n\"\n                \"    else\\n\"\n                \"        PCC_ERROR(ctx->auxil);\\n\"\n                \"    pcc_commit_buffer(ctx);\\n\"\n            );\n        }\n        stream__puts(\n            &sstream,\n            \"    pcc_thunk_array__revert(ctx->auxil, &ctx->thunks, 0);\\n\"\n            \"    return pcc_refill_buffer(ctx, 1) >= 1;\\n\"\n            \"}\\n\"\n            \"\\n\"\n        );\n        stream__printf(\n            &sstream,\n            \"void %s_destroy(%s_context_t *ctx) {\\n\",\n            get_prefix(ctx), get_prefix(ctx)\n        );\n        stream__puts(\n            &sstream,\n            \"    pcc_context__destroy(ctx);\\n\"\n            \"}\\n\"\n        );\n    }\n    {\n        stream__puts(\n            &hstream,\n            \"#ifdef __cplusplus\\n\"\n            \"extern \\\"C\\\" {\\n\"\n            \"#endif\\n\"\n            \"\\n\"\n        );\n        stream__printf(\n            &hstream,\n            \"typedef struct %s_context_tag %s_context_t;\\n\"\n            \"\\n\",\n            get_prefix(ctx), get_prefix(ctx)\n        );\n        stream__printf(\n            &hstream,\n            \"%s_context_t *%s_create(%s%sauxil);\\n\",\n            get_prefix(ctx), get_prefix(ctx),\n            at, ap ? \"\" : \" \"\n        );\n        stream__printf(\n            &hstream,\n            \"int %s_parse(%s_context_t *ctx, %s%s*ret);\\n\",\n            get_prefix(ctx), get_prefix(ctx),\n            vt, vp ? \"\" : \" \"\n        );\n        stream__printf(\n            &hstream,\n            \"void %s_destroy(%s_context_t *ctx);\\n\",\n            get_prefix(ctx), get_prefix(ctx)\n        );\n        stream__puts(\n            &hstream,\n            \"\\n\"\n            \"#ifdef __cplusplus\\n\"\n            \"}\\n\"\n            \"#endif\\n\"\n        );\n        stream__printf(\n            &hstream,\n            \"\\n\"\n            \"#endif /* !PCC_INCLUDED_%s */\\n\",\n            ctx->hid\n        );\n    }\n    {\n        match_eol(ctx);\n        if (!match_eof(ctx)) stream__putc(&sstream, '\\n');\n        commit_buffer(ctx);\n        if (ctx->opts.lines && !match_eof(ctx))\n            stream__write_line_directive(&sstream, ctx->iname, ctx->linenum);\n        while (refill_buffer(ctx, ctx->buffer.max) > 0) {\n            const size_t n = ctx->buffer.len;\n            stream__write_text(&sstream, ctx->buffer.buf, (n > 0 && ctx->buffer.buf[n - 1] == '\\r') ? n - 1 : n);\n            ctx->bufcur = n;\n            commit_buffer(ctx);\n        }\n    }\n    fclose_e(hstream.file);\n    fclose_e(sstream.file);\n    if (ctx->errnum) {\n        unlink(ctx->hname);\n        unlink(ctx->sname);\n        return FALSE;\n    }\n    return TRUE;\n}\n\nstatic void print_version(FILE *output) {\n    fprintf(output, \"%s version %s\\n\", g_cmdname, VERSION);\n    fprintf(output, \"Copyright (c) 2014, 2019-2022 Arihiro Yoshida. All rights reserved.\\n\");\n}\n\nstatic void print_usage(FILE *output) {\n    fprintf(output, \"Usage: %s [OPTIONS] [FILE]\\n\", g_cmdname);\n    fprintf(output, \"Generates a packrat parser for C.\\n\");\n    fprintf(output, \"\\n\");\n    fprintf(output, \"  -o BASENAME    specify a base name of output source and header files\\n\");\n    fprintf(output, \"  -a, --ascii    disable UTF-8 support\\n\");\n    fprintf(output, \"  -l, --lines    add #line directives\\n\");\n    fprintf(output, \"  -d, --debug    with debug information\\n\");\n    fprintf(output, \"  -h, --help     print this help message and exit\\n\");\n    fprintf(output, \"  -v, --version  print the version and exit\\n\");\n}\n\nint main(int argc, char **argv) {\n    const char *iname = NULL;\n    const char *oname = NULL;\n    options_t opts;\n    opts.ascii = FALSE;\n    opts.lines = FALSE;\n    opts.debug = FALSE;\n#ifdef _MSC_VER\n#ifdef _DEBUG\n    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);\n    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);\n    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);\n#endif\n#endif\n    g_cmdname = extract_filename(argv[0]);\n    {\n        const char *fname = NULL;\n        const char *opt_o = NULL;\n        bool_t opt_a = FALSE;\n        bool_t opt_l = FALSE;\n        bool_t opt_d = FALSE;\n        bool_t opt_h = FALSE;\n        bool_t opt_v = FALSE;\n        int i;\n        for (i = 1; i < argc; i++) {\n            if (argv[i][0] != '-') {\n                break;\n            }\n            else if (strcmp(argv[i], \"--\") == 0) {\n                i++; break;\n            }\n            else if (argv[i][1] == 'o') {\n                const char *const o = (argv[i][2] != '\\0') ? argv[i] + 2 : (++i < argc) ?  argv[i] : NULL;\n                if (o == NULL) {\n                    print_error(\"Output base name missing\\n\");\n                    fprintf(stderr, \"\\n\");\n                    print_usage(stderr);\n                    exit(1);\n                }\n                if (opt_o != NULL) {\n                    print_error(\"Extra output base name '%s'\\n\", o);\n                    fprintf(stderr, \"\\n\");\n                    print_usage(stderr);\n                    exit(1);\n                }\n                opt_o = o;\n            }\n            else if (strcmp(argv[i], \"-a\") == 0 || strcmp(argv[i], \"--ascii\") == 0) {\n                opt_a = TRUE;\n            }\n            else if (strcmp(argv[i], \"-l\") == 0 || strcmp(argv[i], \"--lines\") == 0) {\n                opt_l = TRUE;\n            }\n            else if (strcmp(argv[i], \"-d\") == 0 || strcmp(argv[i], \"--debug\") == 0) {\n                opt_d = TRUE;\n            }\n            else if (strcmp(argv[i], \"-h\") == 0 || strcmp(argv[i], \"--help\") == 0) {\n                opt_h = TRUE;\n            }\n            else if (strcmp(argv[i], \"-v\") == 0 || strcmp(argv[i], \"--version\") == 0) {\n                opt_v = TRUE;\n            }\n            else {\n                print_error(\"Invalid option '%s'\\n\", argv[i]);\n                fprintf(stderr, \"\\n\");\n                print_usage(stderr);\n                exit(1);\n            }\n        }\n        switch (argc - i) {\n        case 0:\n            break;\n        case 1:\n            fname = argv[i];\n            break;\n        default:\n            print_error(\"Multiple input files\\n\");\n            fprintf(stderr, \"\\n\");\n            print_usage(stderr);\n            exit(1);\n        }\n        if (opt_h || opt_v) {\n            if (opt_v) print_version(stdout);\n            if (opt_v && opt_h) fprintf(stdout, \"\\n\");\n            if (opt_h) print_usage(stdout);\n            exit(0);\n        }\n        iname = (fname != NULL && fname[0] != '\\0') ? fname : NULL;\n        oname = (opt_o != NULL && opt_o[0] != '\\0') ? opt_o : NULL;\n        opts.ascii = opt_a;\n        opts.lines = opt_l;\n        opts.debug = opt_d;\n    }\n    {\n        context_t *const ctx = create_context(iname, oname, &opts);\n        const int b = parse(ctx) && generate(ctx);\n        destroy_context(ctx);\n        if (!b) exit(10);\n    }\n    return 0;\n}\n"
  },
  {
    "path": "misc/pull-libreadtags.sh",
    "content": "#!/bin/sh\n\n# Update to the latest packcc\n#\n# Copyright (C) 2020 Universal Ctags Team\n# License: GPL 2 or later\n\ncd $(git rev-parse --show-toplevel)\ngit subtree pull --prefix libreadtags https://github.com/universal-ctags/libreadtags.git master --squash\n"
  },
  {
    "path": "misc/pull-packcc.sh",
    "content": "#!/bin/sh\n\n# Update to the latest packcc\n#\n# Copyright (C) 2019 Universal Ctags Team\n# License: GPL 2 or later\n\ncd $(git rev-parse --show-toplevel)\ngit subtree pull --prefix misc/packcc https://github.com/arithy/packcc.git master --squash\n"
  },
  {
    "path": "misc/readtags.supp",
    "content": "# Usage: valgrind --suppressions=readtags.supp  --leak-check=full --show-leak-kinds=all ./readtags ...  > /dev/null\n# The output with --gen-suppressions=all option can be used as a base for writing a suppress file.\n{\n   <intern>\n   Memcheck:Leak\n   match-leak-kinds: reachable\n   fun:malloc\n   fun:eMalloc\n   fun:intern\n   ...\n}\n{\n   <es:obarray_intern/strdup>\n   Memcheck:Leak\n   match-leak-kinds: reachable\n   fun:malloc\n   fun:strdup\n   fun:es_obarray_intern\n   fun:fill_list\n   fun:es_read_from_string\n   fun:compileExpression\n   fun:parseOptions\n   fun:main\n}\n{\n   <es:obarray_intern/object_new>\n   Memcheck:Leak\n   match-leak-kinds: reachable\n   fun:calloc\n   fun:es_object_new\n   fun:es_obarray_intern\n   fun:fill_list\n   fun:es_read_from_string\n   fun:compileExpression\n   fun:parseOptions\n   fun:main\n}\n{\n   <es:dsl_define/strdup>\n   Memcheck:Leak\n   match-leak-kinds: reachable\n   fun:malloc\n   fun:strdup\n   fun:es_obarray_intern\n   fun:dsl_define\n   fun:dsl_init\n   fun:initialize\n   ...\n}\n{\n   <es:dsl_define/es_object_new>\n   Memcheck:Leak\n   match-leak-kinds: reachable\n   fun:calloc\n   fun:es_object_new\n   fun:es_obarray_intern\n   fun:dsl_define\n   fun:dsl_init\n   fun:initialize\n   ...\n}\n{\n   <es:dsl_define/calloc>\n   Memcheck:Leak\n   match-leak-kinds: reachable\n   fun:calloc\n   fun:dsl_define\n   fun:dsl_init\n   fun:initialize\n   ...\n}\n{\n   <es_boolean_new>\n   Memcheck:Leak\n   match-leak-kinds: reachable\n   fun:calloc\n   fun:es_object_new\n   fun:es_boolean_new\n   ...\n}\n{\n   <sorter/predefinition:es_integer_new>\n   Memcheck:Leak\n   match-leak-kinds: reachable\n   fun:calloc\n   fun:es_object_new\n   fun:es_integer_new\n   fun:initialize\n   fun:s_compile\n   fun:compileExpression\n   fun:parseOptions\n   fun:main\n}\n"
  },
  {
    "path": "misc/review",
    "content": "#!/bin/bash\n#\n# review - Review the diff between expected output and actual output in Units\n#\n# Copyright (C) 2016 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\nprint_help()\n{\n    echo Usage:\n    printf \"\t%-20s %-30s %s\\n\" \"$0\" \"help|--help|-h\" \"show this message\"\n    printf \"\t%-20s %-30s %s\\n\" \"$0\" \"[list] [-b]\" \"list failed Units and Tmain\"\n    help_list\n    printf \"\t%-20s %-30s %s\\n\" \"$0\" \"inspect [-b]\" \"inspect difference interactively\"\n    help_inspect\n    exit $1\n}\n\nis_known_bug()\n{\n    [[ $1 == *.b ]]\n    return $?\n}\n\ndo_list ()\n{\n    local d\n    local n\n    local a\n    local including_known_bugs\n\n    for a in \"$@\"; do\n\tcase $a in\n\t    (-b)\n\t\tincluding_known_bugs=-b\n\t\t;;\n\t    (-*)\n\t\techo \"unknown option: ${a}\" 1>&2\n\t\texit 1\n\t\t;;\n\t    (*)\n\t\techo \"unexpected argument ${a}\" 1>&2\n\t\texit 1\n\t\t;;\n\tesac\n    done\n\n    for d in $(find Units -name \"DIFF.tmp\"); do\n\tn=$(dirname \"$d\")\n\tif (( ! is_known_bug $(basename \"$n\") ) || [[ -n ${including_known_bugs} ]] ) \\\n\t       && [[ -e \"$n\"/expected.tags ]]; then\n\t    echo ${n}\n\tfi\n    done\n\n    for d in $(find Tmain -name \"*-diff.txt\"); do\n\tn=$(dirname \"$d\")\n\techo ${n}\n    done | sort -u\n}\n\nhelp_list()\n{\n    printf \"\t%-20s %-30s %s\\n\" \"\" \"-b\" \"list .b (known bug) marked cases\"\n}\n\ndiff_post_processor()\n{\n    local cmd=cat\n\n    if which colordiff > /dev/null 2>&1; then\n\tcmd=colordiff\n    elif which pygmentize > /dev/null 2>&1; then\n\tcmd=\"pygmentize -l diff\"\n    fi\n\n    $cmd\n}\n\nunits_inspect_cmd_accept ()\n{\n    local from=./Units/$1/FILTERED.tmp\n    local to=./Units/$1/expected.tags\n    local r\n\n    if [[ ! -e \"${from}\" ]]; then\n\techo \"./Units/$1/FILTERED.tmp is not found\" 1>&2\n\techo \"Remove DIFF.tmp?\"\n\tread -p \"[Y/n] \"\n\tif [[ \"$REPLY\" == Y ]]; then\n\t    rm ./Units/$t/DIFF.tmp\n\t    echo \"Removed: DIFF.tmp\"\n\t    r=1\n\telse\n\t    echo \"Kept: DIFF.tmp\"\n\t    r=0\n\tfi\n\treturn $r\n    fi\n\n    echo \"Do you really want do following shell command?\"\n    echo\n    echo \"   mv \\\"$from\\\"\" '\\'\n    echo \"      \\\"$to\\\" \"\n    echo\n    read -p \"[Y/n] \"\n\n    if [[ \"$REPLY\" == Y ]]; then\n\tmv \"$from\" \"$to\"\n\techo \"Renamed: $from => $to\"\n\tr=0\n\n\techo \"Remove DIFF.tmp, too?\"\n\tread -p \"[Y/n] \"\n\tif [[ \"$REPLY\" == Y ]]; then\n\t    rm ./Units/$t/DIFF.tmp\n\t    echo \"Removed: DIFF.tmp\"\n\telse\n\t    echo \"Kept: DIFF.tmp\"\n\tfi\n    else\n\techo \"Aborted\"\n\tr=1\n    fi\n\n    return $r\n}\n\nunits_inspect_cmd_skip ()\n{\n    echo \"SKIPPING $1\" 1>&2\n}\n\nunits_inspect_cmd_show_generic ()\n{\n    local tcase=$1\n    local file=$2\n    shift 2\n    local f=./Units/${tcase}/${file}\n\n    if [[ -r \"$f\" ]]; then\n\t\"$@\" \"$f\"\n    else\n\techo \"No $f\" 1>&2\n    fi\n    echo '---'\n    echo '# ' \"$f\"\n}\n\nunits_inspect_cmd_show_diff ()\n{\n    units_inspect_cmd_show_generic $1 DIFF.tmp cat | diff_post_processor\n}\n\nunits_inspect_show_args_ctags ()\n{\n    units_inspect_cmd_show_generic $1 args.ctags cat\n}\n\npygmentize_or_cat ()\n{\n    # It seems that pygmentize ignores the empty lines at the head of input.\n    if [ -z \"$(head -1 $1)\" ]; then\n\tcat -n $1\n    elif which pygmentize > /dev/null 2>&1; then\n\tpygmentize -O \"style=colorful,linenos=1\" $1 2>/dev/null || cat -n $1\n    else\n\tcat -n $1\n    fi\n}\n\nunits_inspect_show_input ()\n{\n    local tcase=$1\n\n    units_inspect_cmd_show_generic $tcase $(basename ./Units/${tcase}/input.*) pygmentize_or_cat\n}\n\n# See https://stackoverflow.com/questions/65533232/bash-extglob-pattern-matching-breaks-when-enclosed-in-a-function\nshopt -s extglob\nunits_inspect_show_expected_tags ()\n{\n    local tcase=$1\n\n    (\n\tshopt -s extglob\n\tunits_inspect_cmd_show_generic $tcase $(basename ./Units/${tcase}/expected.tags?(-*)) \"cat\" \"-n\"\n    )\n}\nshopt -u extglob\n\ninspect_cmd_quit ()\n{\n    echo \"BYE\" 1>&2\n    exit 0\n}\n\ninspect_cmd_unknown()\n{\n    echo \"unknown command: $REPLY\" 1>&2\n    echo \"Just return to show menu\" 1>&2\n}\n\nhelp_inspect ()\n{\n    printf \"\t%-20s %-30s %s\\n\" \"\" \"-b\" \"inspect .b (known bug) marked cases\"\n}\n\ndo_units_inspect()\n{\n    local next=0\n    local r\n    local t=$1\n\n    select r in '<a>ccept' '<s>kip (or <n>)' '<S>hell' '<d>iff' 'show args.<c>tags' 'show <i>nput' '<e>xpected tags' '<q>uit'; do\n\tcase $r-$REPLY in\n\t    (\"<a>ccept\"-*|-a)\n\t\tif units_inspect_cmd_accept \"$t\"; then\n\t\t    next=1\n\t\tfi\n\t\t;;\n\t    (\"<s>kip (or <n>)\"-*|-s|-!|-skip|-n|-next)\n\t\tunits_inspect_cmd_skip \"$t\"\n\t\tnext=1\n\t\t;;\n\t    (\"<S>hell\"-*|-S)\n\t\tinspect_cmd_shell Units \"$t\"\n\t\t;;\n\t    (\"<d>iff\"-*|-d|-=|-diff)\n\t\tunits_inspect_cmd_show_diff \"$t\"\n\t\t;;\n\t    (\"<q>uit\"-*|-q|-quit)\n\t\tinspect_cmd_quit\n\t\t;;\n\t    (\"show args.<c>tags\"-*|-c|-A|-args.ctags)\n\t\tunits_inspect_show_args_ctags \"$t\"\n\t\t;;\n\t    (\"show <i>nput\"-*|-i|-input)\n\t\tunits_inspect_show_input \"$t\"\n\t\t;;\n\t    (\"<e>xpected tags\"-*|-e|-expected.tags)\n\t\tunits_inspect_show_expected_tags \"$t\"\n\t\t;;\n\t    (*)\n\t\tinspect_cmd_unknown\n\t\t;;\n\tesac\n\tif [[ $next == 1 ]]; then\n\t    break\n\tfi\n    done\n}\n\nfunction inspect_cmd_shell\n{\n    local prefix=$1\n    local t=$2\n\n    (\n\tcd $prefix/$t\n\tPS1=\"review> \" bash\n    )\n}\n\nfunction tmain_inspect_run\n{\n    local t=$1\n    make tmain UNITS=$(basename $t .d)\n}\n\n\ntmain_inspect_cmd_show_diff_generic()\n{\n    local prefix=$1\n    local t=$2\n    local c=$3\n    cat $prefix/$t/$c-diff.txt | diff_post_processor\n}\n\ntmain_inspect_cmd_show_diff_all()\n{\n    local prefix=$1\n    local t=$2\n    local c\n\n    for c in stdout stderr exit; do\n\tif [[ -e \"$prefix/$t/$c-diff.txt\" ]]; then\n\t    echo '### ' \"$c\"\n\t    tmain_inspect_cmd_show_diff_generic \"$prefix\" \"$t\" \"$c\"\n\tfi\n    done\n}\n\ntmain_inspect_cmd_accept()\n{\n    local prefix=$1\n    local t=$2\n    local c\n    for c in stdout stderr exit; do\n\tif [[ -e \"$prefix/$t/$c-diff.txt\" ]]; then\n\t    mv \"$prefix/$t/$c-actual.txt\" \"$prefix/$t/$c-expected.txt\"\n\t    rm \"$prefix/$t/$c-diff.txt\"\n\tfi\n    done\n}\n\ndo_tmain_inspect()\n{\n    local next=0\n    local r\n    local t=$1\n\n    select r in '<n>ext' '<d>iff' '<a>ccept' '<S>hell' '<R>un' '<q>uit'; do\n\tcase $r-$REPLY in\n\t    (\"<n>ext\"-*|-n)\n\t\tnext=1\n\t\t;;\n\t    (\"<d>iff\"-*|-d|-=|-diff)\n\t\ttmain_inspect_cmd_show_diff_all Tmain \"$t\"\n\t\t;;\n\t    (\"<S>hell\"-*|-S)\n\t\tinspect_cmd_shell Tmain \"$t\"\n\t\t;;\n\t    (\"<a>ccept\"-*|-a)\n\t\tif tmain_inspect_cmd_accept Tmain \"$t\"; then\n\t\t    next=1\n\t\tfi\n\t\t;;\n\t    (\"<R>un\"-*|-R)\n\t\ttmain_inspect_run \"$t\"\n\t\t;;\n\t    (\"<q>uit\"-*|-q|-quit)\n\t\tinspect_cmd_quit\n\t\t;;\n\tesac\n\tif [[ $next == 1 ]]; then\n\t    break\n\tfi\n    done\n}\n\ncount ()\n{\n    echo $#\n}\n\ndo_inspect ()\n{\n    local a\n    local t0\n    local t\n    local including_known_bugs\n\n    for a in \"$@\"; do\n\tcase $a in\n\t    (-b)\n\t\tincluding_known_bugs=-b\n\t\t;;\n\t    (-*)\n\t\techo \"unknown option: ${a}\" 1>&2\n\t\texit 1\n\t\t;;\n\t    (*)\n\t\techo \"unexpected argument ${a}\" 1>&2\n\t\texit 1\n\t\t;;\n\tesac\n    done\n\n    local T=$(do_list ${including_known_bugs});\n    local total=$(count $T)\n    local i=1\n    for t0 in $T; do\n\tPS3=\"[$i/$total [ $t0 ]]? \"\n\ti=$(( i + 1 ))\n\tt=${t0#Units/}\n\tt=${t#Tmain/}\n\n\tif [[ \"$t0\" =~ ^Units ]]; then\n\t    do_units_inspect \"$t\"\n\telse\n\t    do_tmain_inspect \"$t\"\n\tfi\n    done\n}\n\nmain ()\n{\n    local action\n\n    while [[ $# -gt 0 ]]; do\n\tcase $1 in\n\t    (help|--help|-h)\n\t\tprint_help 0\n\t\t;;\n\t    (list)\n\t\taction=$1\n\t\tshift\n\t\tbreak\n\t\t;;\n\t    (inspect)\n\t\taction=$1\n\t\tshift\n\t\tbreak\n\t\t;;\n\t    (*)\n\t\tprint_help 1 1>&2\n\t\t;;\n\tesac\n    done\n\n    if  [[ -z \"$action\" ]]; then\n\taction=inspect\n    fi\n\n    if ! [[ -d ./Units ]]; then\n\techo \"$0: cannot find ./Units directory\" 1>&2\n\texit 1\n    fi\n\n    if ! [[ -d ./Tmain ]]; then\n\techo \"$0: cannot find ./Tmain directory\" 1>&2\n\texit 1\n    fi\n\n    do_${action} \"$@\"\n}\n\nmain \"$@\"\n"
  },
  {
    "path": "misc/roundtrip",
    "content": "#!/bin/sh\n#\n#   Copyright (C) 2014 Masatake YAMATO\n#\n#   This program is free software; you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation; either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nset -e\n\n# Avoid trouble with weird bytes on non-C locales\nexport LC_ALL=C\n\nREADTAGS=${1:-./readtags}\nUNITS=${2:-./Units}\nshift 2\n\nMINITRIP=\nwhile [ $# -gt 0 ]; do\n    case $1 in\n\t--minitrip)\n\t    MINITRIP=minitrip\n\t    ;;\n\t*)\n\t    echo \"Unexpected argument: $1\" 1>&2\n\t    exit 1\n\t    ;;\n    esac\n    shift\ndone\n\ns=0\n\nif ! [ -f \"${READTAGS}\" ]; then\n    echo \"No such file: ${READTAGS}\" 1>&2\n    exit 1\nfi\n\nif ! [ -x \"${READTAGS}\" ]; then\n    echo \"Not an executable: ${READTAGS}\" 1>&2\n    exit 1\nfi\n\nif ! [ -x \"${UNITS}\" ]; then\n    echo \"Not such directory: ${UNITS}\" 1>&2\n    exit 1\nfi\n\n\n# Expand CTags escape sequences (and keep the original, too)\n# See docs/format.rst\nexpandEscapeSequences()\n{\n    sed -e '\n# early out if there is no escape sequence (common case)\n/\\\\/!b\n\n# loop until we handled all occurrences of \\.\n# as it is not possible to do all replacements at once and we need not to\n# ever use the result of an replacement to perform another one, use two\n# reserved placeholders.\n:again\n    s/\\\\/__BACKSLASH__/\n    s/__BACKSLASH__\\\\/__LITBACKSLASH__/;\tt again\n    s/__BACKSLASH__t/\t/;\t\t\tt again\n    s/__BACKSLASH__r/'\"$(printf '\\r')\"'/;\tt again\n    s/__BACKSLASH__n/\\\n/;\t\t\t\t\t\tt again\n    s/__BACKSLASH__a/\u0007/;\t\t\tt again\n    s/__BACKSLASH__b/'\"$(printf '\\b')\"'/;\tt again\n    s/__BACKSLASH__v/\u000b/;\t\t\tt again\n    s/__BACKSLASH__f/\f/;\t\t\tt again\n    s/__BACKSLASH__x01/\u0001/;\t\t\tt again\n    s/__BACKSLASH__x02/\u0002/;\t\t\tt again\n    s/__BACKSLASH__x03/\u0003/;\t\t\tt again\n    s/__BACKSLASH__x04/\u0004/;\t\t\tt again\n    s/__BACKSLASH__x05/\u0005/;\t\t\tt again\n    s/__BACKSLASH__x06/\u0006/;\t\t\tt again\n    s/__BACKSLASH__x07/\u0007/;\t\t\tt again\n    s/__BACKSLASH__x08/\b/;\t\t\tt again\n    s/__BACKSLASH__x09/\t/;\t\t\tt again\n    s/__BACKSLASH__x0[aA]/\\\n/;\t\t\t\t\t\tt again\n    s/__BACKSLASH__x0[bB]/\u000b/;\t\t\tt again\n    s/__BACKSLASH__x0[cC]/\f/;\t\t\tt again\n    s/__BACKSLASH__x0[dD]/'\"$(printf '\\r')\"'/;\tt again\n    s/__BACKSLASH__x0[eE]/\u000e/;\t\t\tt again\n    s/__BACKSLASH__x0[fF]/\u000f/;\t\t\tt again\n    s/__BACKSLASH__x10/\u0010/;\t\t\tt again\n    s/__BACKSLASH__x11/\u0011/;\t\t\tt again\n    s/__BACKSLASH__x12/\u0012/;\t\t\tt again\n    s/__BACKSLASH__x13/\u0013/;\t\t\tt again\n    s/__BACKSLASH__x14/\u0014/;\t\t\tt again\n    s/__BACKSLASH__x15/\u0015/;\t\t\tt again\n    s/__BACKSLASH__x16/\u0016/;\t\t\tt again\n    s/__BACKSLASH__x17/\u0017/;\t\t\tt again\n    s/__BACKSLASH__x18/\u0018/;\t\t\tt again\n    s/__BACKSLASH__x19/\u0019/;\t\t\tt again\n    s/__BACKSLASH__x1[aA]/\u001a/;\t\t\tt again\n    s/__BACKSLASH__x1[bB]/\u001b/;\t\t\tt again\n    s/__BACKSLASH__x1[cC]/\u001c/;\t\t\tt again\n    s/__BACKSLASH__x1[dD]/\u001d/;\t\t\tt again\n    s/__BACKSLASH__x1[eE]/\u001e/;\t\t\tt again\n    s/__BACKSLASH__x1[fF]/\u001f/;\t\t\tt again\n    s/__BACKSLASH__x21/!/;\t\t\tt again\n    s/__BACKSLASH__x20/ /;\t\t\tt again\n    s/__BACKSLASH__x7[fF]//;\t\t\tt again\n    /\\\\/b again\n\n# replace lonely \"\\\"es\ns/__BACKSLASH__/\\\\/g\n# replace literal \"\\\"es (\"\\\\\" from the input)\ns/__LITBACKSLASH__/\\\\/g\n'\n}\n\n# disable path expansion, because we don't need it and it's applied on the\n# result of the commands used to loop on, and we don't want that.\nset -f\n# remove space from IFS as it's valid in tag names\nOLD_IFS=\"$IFS\"\nIFS='\n'\n\nntagfiles=0\nntrips=0\ntagfiles=$(find \"$UNITS\" -name expected.tags)\nfor tags in $tagfiles; do\n    ntagfiles=$(expr $ntagfiles + 1)\n    dir=$(dirname \"$tags\")\n    if [ -n \"$MINITRIP\" -a ! -e \"$dir/$MINITRIP\" ]; then\n\tcontinue\n    fi\n    ntrips=$(expr $ntrips + 1)\n\n    tagnames=$(sed -e 's/^\\([^\t]*\\)\t.*/\\1/' \"$tags\")\n    for name in $tagnames; do\n\t# Yes, there is a reason for this craziness.  We need to properly\n\t# handle embedded newlines (expanded from \"\\n\"), including trailing\n\t# ones the shell would strip automatically.  To work around this, we\n\t# add a dummy character at the end to inhibit stripping, and then\n\t# remove it, plus the extra newline, using variable substitutions.\n\t# Note: we use \"printf '%s\\n'\" instead of \"echo\" because Dash's \"echo\"\n\t# unconditionally expands some sequences, like \"\\t\" and alike.\n\tt=\"$(printf '%s\\n' \"$name\" | expandEscapeSequences; printf _)\"\n\tt=\"${t%\n_}\"\n\tif [ 1 -gt $(\"${READTAGS}\" -t \"$tags\" - \"$t\" | wc -l) ]; then\n\t    printf 'FAILED: \"%s\" -t \"%s\" - \"%s\"\\n' \"${READTAGS}\" \"$tags\" \"$t\"\n\t    printf '\tThe raw tag name was \"%s\"\\n' \"$name\"\n\t    s=1\n\tfi\n    done\ndone\n\nIFS=\"$OLD_IFS\"\n\nnote=\nif [ -n \"$MINITRIP\" ]; then\n    note=\"[$MINITRIP]\"\nfi\nprintf \"%s/%s%s...%d\\n\" \"$ntrips\" \"$ntagfiles\" \"$note\" \"$s\"\n\nexit $s\n"
  },
  {
    "path": "misc/src-check",
    "content": "#!/bin/sh\n#\n#   Copyright (C) 2014 Masatake YAMATO\n#\n#   This program is free software; you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation; either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nCTAGS=./ctags\n\nline()\n{\n    local i\n    for i in $(seq 72); do\n\techo -n -e -\n    done\n    echo\n}\n\nheader()\n{\n    echo\n    echo \"$1\"\n    line\n\n}\n\ncheck_include_general_h_first()\n{\n    local f\n    local l\n    local i=0\n\n    header \"Check whether general.h is included first: $1\"\n    # Added -maxdepth 1 to skip parsers/cxx\n    for f in $(find $1 -maxdepth 1 -name '*.c'); do\n\tif grep -a -q -e '^#[[:space:]]*include' $f; then\n\t    l=$()\n\t    if ! ( grep -a -e '^#[[:space:]]*include' $f | head -1 | grep -q \"general.h\" ); then\n\t\ti=$(expr $i + 1)\n\t\techo \"$f: general.h should be included FIRST\" 2>&1\n\t    fi\n\tfi\n    done\n\n    return $i\n}\n\ncheck_name_cpp_macro()\n{\n    local dir=$1\n    local r=0\n    local n\n\n    header \"Check whether '_' is not used as ctags own macro name\"\n    for f in $(find $dir -name '*.[ch]' | grep -v portable-dirent_p.h); do\n\tif ${CTAGS} --language-force=C -x --_xformat='%F:%N' --kinds-C=d -o - $f | grep -q '.*:_.*H'; then\n\t    for n in $(${CTAGS} --language-force=C -x --_xformat='%N' --kinds-C=d -o - $f | grep  '^_.*H'); do\n\t\techo \"#\" $n\n\t\techo sed -i \\\"\"s|$n|CTAGS_$(echo $dir | tr a-z A-Z)_${n#_}|g\\\"\" $f\n\t    done\n\t   r=1\n\tfi\n    done\n    return $r\n}\n\ncheck_vStringCatS_usage()\n{\n    local i=0\n\n    header \"Check wrong vStringCatS usage(use vStringPut instead): $1\"\n    for f in $(find $1 -name '*.c'); do\n\tif grep -H -a -e 'vStringCatS[[:space:]]*(.*,[[:space:]]*\".\"[[:space:]]*)' $f; then\n\t    i=$(expr $i + 1)\n\telif grep -H -a -e 'vStringCatS[[:space:]]*(.*,[[:space:]]*\"\\\\.\"[[:space:]]*)' $f; then\n\t    i=$(expr $i + 1)\n\tfi\n    done\n\n    return $i\n}\n\ncheck_eof_chars_in_vcxproj()\n{\n    local r=4\n    local f\n\n    # *.vcxproj* should not have the last CRLF.\n    for f in win32/ctags_vs2013.vcxproj.in win32/ctags_vs2013.vcxproj.filters.in \\\n             win32/ctags_vs2013.vcxproj    win32/ctags_vs2013.vcxproj.filters; do\n\theader \"Check the EOF characters of $f\"\n\tlocal s=$(od -t c  -j $(expr $(stat -c %s $f) - 1) $f)\n\tif echo \"$s\" | grep -q '>$'; then\n\t    r=$(expr $r - 1)\n\telse\n\t    echo \"unexpected chars: $s\"\n\tfi\n    done\n\n    return $r\n}\n\nmain()\n{\n    local i=0\n\n    if ! [ -d ./main ]; then\n\techo \"cannot find ./main\"\n\treturn 2\n    fi\n\n    if ! [ -d ./parsers ]; then\n\techo \"cannot find ./parsers\"\n\treturn 2\n    fi\n\n    if ! check_include_general_h_first main; then\n\ti=$(expr $i + 1)\n\techo \"failed\"\n    else\n\techo \"ok\"\n    fi\n\n    if ! check_include_general_h_first parsers; then\n\ti=$(expr $i + 1)\n\techo \"failed\"\n    else\n\techo \"ok\"\n    fi\n\n    if ! check_name_cpp_macro main; then\n\ti=$(expr $i + 1)\n\techo \"failed\"\n    else\n\techo \"ok\"\n    fi\n\n    if ! check_name_cpp_macro parsers; then\n\ti=$(expr $i + 1)\n\techo \"failed\"\n    else\n\techo \"ok\"\n    fi\n\n    if ! check_vStringCatS_usage main; then\n\ti=$(expr $i + 1)\n\techo \"failed\"\n    else\n\techo \"ok\"\n    fi\n\n    if ! check_vStringCatS_usage parsers; then\n\ti=$(expr $i + 1)\n\techo \"failed\"\n    else\n\techo \"ok\"\n    fi\n\n    if ! check_eof_chars_in_vcxproj; then\n\ti=$(expr $i + 1)\n\techo \"failed\"\n    else\n\techo \"ok\"\n    fi\n\n    return $i\n}\n\nmain \"$@\"\nexit $?\n"
  },
  {
    "path": "misc/tinst",
    "content": "#!/bin/sh\n#\n#   Copyright (C) 2014 Masatake YAMATO\n#\n#   This program is free software; you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation; either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nTINST_ROOT=\n\nERROR ()\n{\n    local status=$1\n    local msg=$2\n    shift 2\n    echo \"$msg\" 1>&2\n    exit $status\n}\n\nMSG_title()\n{\n    printf '%-70s' \"${1}\"\n}\n\nMSG_passed()\n{\n    echo passed\n}\n\nMSG_failed()\n{\n    echo failed\n}\n\nMSG_done()\n{\n    echo done\n}\n\n\nT_existing()\n{\n    local f=$1\n    shift\n    local op\n    local r=0\n\n    for op in \"$@\"; do\n\tcase \"$op\" in\n\t    -d)\n\t\tMSG_title \"The existence of $f as a directory\"\n\t\t;;\t    \n\t    -f)\n\t\tMSG_title \"The existence of $f as an file\"\n\t\t;;\n\t    -r)\n\t\tMSG_title \"The read mode of $f\"\n\t\t;;\n\t    -x)\n\t\tMSG_title \"The existence of $f as an executable\"\n\t\t;;\n\t    *)\n\t\tMSG_title \"The existence of $f with $op operator\"\n\t\t;;\n\tesac\n\tif [ $op ${TINST_ROOT}/$f ]; then\n\t    MSG_passed\n\telse\n\t    MSG_failed\n\t    r=$(( r + 1 ))\n\tfi\n    done\n    return ${r}\n}\n\nprepare()\n{\n    local srcdir=$1\n    local root=$2\n\n\n    MSG_title \"Preparing installation tests\"\n    \n    if ! [ -e ${srcdir}/configure ]; then\n\tERROR 2 \"cannot find configure script\"\n    fi\n\n    mkdir -p \"$root\"\n\n    if ! [ -d \"$root\" ]; then\n\tERROR 2 \"failed in directory creation: $roo\"\n    fi\n\n    rm Makefile\n\n    if ! ${srcdir}/configure --prefix=$root > /dev/null; then\n\tERROR 2 \"failed in running configure script $root\"\n    fi\n\n    if ! [ -e Makefile ]; then\n\tERROR 2 \"cannot find Makefile\"\n    fi\n\n    if ! make > /dev/null; then\n\tERROR 2 \"failed in building ctags\"\n    fi\n\n    if ! make install > /dev/null; then\n\tERROR 2 \"failed in installing ctags\"\n    fi    \n\n    MSG_done\n    return 0\n}\n\ncleanup()\n{\n    MSG_title \"Cleanup installation tests\"\n    MSG_done\n    return 0\n}\n\ncheck()\n{\n    T_existing /bin/ctags -f -x\n    T_existing /bin/readtags -f -x\n\n    T_existing /share/man/man1/ctags.1 -f -r\n}\n\nmain()\n{\n    local srcdir\n    local root\n    local status\n\n    if [ $# = 2 ]; then\n\tsrcdir=$1\n\troot=$2\n\tshift 2\n    else\n\tERROR 2 \"A installation root must be given as the first argument\"\n    fi\n    \n    prepare \"${srcdir}\" \"${root}\"\n\n    TINST_ROOT=${root}\n    check\n    status=$?\n\n    cleanup \"${root}\"\n\n    return $status\n}\n\nmain \"$@\"\n"
  },
  {
    "path": "misc/tlib",
    "content": "#!/bin/sh\n#\n# tlib - testing libctags.a via mini-geany\n#\n# Copyright (C) 2019 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\nset -e\n\nMINI_GEANY=$1\nexpected=$2\nactual=$3\nVG=$4\n\nVALGRIND=\nif test \"${VG}\" = 1; then\n   VALGRIND=\"valgrind --leak-check=full\"\nfi\n\n${VALGRIND} ${MINI_GEANY} > ${actual}\necho \"${VALGRIND} ${MINI_GEANY} output:\"\ncat ${actual}\nN=$(sed -n -e 's/^The total number of parsers is: \\([0-9]*\\)$/\\1/p' ${actual})\n\ntest \"$N\" -gt 0\n\nsed -i -e '/^The total number of parsers is: [0-9]*$/d' ${actual}\n\necho \"comparing with expected output:\"\ndiff -uN --strip-trailing-cr ${expected} ${actual} && rm ${actual}\n\nexit $?\n"
  },
  {
    "path": "misc/txt2cstr",
    "content": "#!/usr/bin/env perl\n#\n# txt2cstr - a tool converting a text file into char[].\n#\n# Copyright (C) 2021 Masatake YAMATO\n# Copyright (C) 2021 Red Hat Inc.\n#\n\nuse File::Basename;\n\nsub show_help {\n    print<<EOF;\nUsage:\n\t$0 --help\n\t$0 INPUT.txt > OUTPUT.c\nEOF\n}\n\nsub convert {\n    my $input = $_[0];\n    my $name  = basename $input;\n\n    $name =~ s/\\.[a-z]+$//g;\n\n    open(INPUT, \"< \" . $input) or die(\"faild to open \" . $input);\n\n    print \"const char ctags$name []=\\n\";\n    while (<INPUT>) {\n\tchop;\n\t$_ =~ s/\\\\/\\\\\\\\/g;\n\t$_ =~ s/\\\"/\\\\\\\"/g;\n\tprint '\"' . \"$_\" . '\\\\n\"' . \"\\n\";\n    }\n    print \";\\n\";\n\n    close (INPUT);\n}\n\nsub main {\n    my $input;\n\n    for (@_) {\n\tif ( ($_ eq '-h') || ($_ eq '--help') ) {\n\t    show_help;\n\t    exit 0;\n\t} elsif ( /^-.*/ ) {\n\t    die \"unrecongnized option: $_\";\n\t} else {\n\t    if ($input) {\n\t\tdie \"Don't specify more than 1 input file: @_\";\n\t    }\n\t    $input=$_;\n\t}\n    }\n\n    unless ($input) {\n\tdie \"No input file given\";\n    }\n\n    convert $input;\n    0;\n}\n\nmain @ARGV;\n\n# txt2cstr ends here\n"
  },
  {
    "path": "misc/units",
    "content": "#!/bin/sh\n#\n###################################################################\n# Use units.py instead of this shell script.\n# Only minor parts of this script are still used.\n###################################################################\n#\n# units - Units test harness for ctags\n#\n# Copyright (C) 2014 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\nif test -n \"${ZSH_VERSION+set}\"; then\n    set -o SH_WORD_SPLIT\n    set +o NOMATCH\nfi\n\n#\n# Global Parameters\n#\nSHELL=/bin/sh\nCTAGS=./ctags\nREADTAGS=./readtags\nWITH_TIMEOUT=\nWITH_VALGRIND=\nCOLORIZED_OUTPUT=yes\n[ -f /dev/stdout ] && COLORIZED_OUTPUT=no\nCATEGORIES=\nUNITS=\nLANGUAGES=\nPRETENSE_OPTS=\nRUN_SHRINK=\nQUIET=\nSHOW_DIFF_OUTPUT=\nVALIDATORS=\n\n#\n# Internal variables and constants\n#\n_CMDLINE=\n_CMDLINE_FOR_SHRINKING=\n_PREPERE_ENV=\n_FEATURE_LIST=\nreadonly _DEFAULT_CATEGORY=ROOT\nreadonly _TIMEOUT_EXIT=124\nreadonly _VG_TIMEOUT_FACTOR=10\nreadonly _VALGRIND_EXIT=58\nreadonly _BASH_INTERRUPT_EXIT=59\nreadonly _LINE_SPLITTER=$(if type dos2unix > /dev/null 2>&1; then echo \"dos2unix\"; else echo \"cat\"; fi)\nreadonly _STDERR_OUTPUT_NAME=\"STDERR.tmp\"\nreadonly _DIFF_OUTPUT_NAME=\"DIFF.tmp\"\nreadonly _NOISE_REPORT_MAX_COLUMN=50\nreadonly _VALIDATION_EXIT_INVALID=2\nreadonly _NOOP_VALIDATOR=\"NONE\"\nreadonly _KNOWN_INVALIDATION_VALIDATOR=\"KNOWN-INVALIDATION\"\nif stat --help >/dev/null 2>&1; then\n    readonly _FSIZE=\"stat -c %s\" # GNU coreutils\nelse\n    readonly _FSIZE=\"stat -f %z\" # BSD based OSes including macOS\nfi\n\n_RUNNABLE_VALIDATORS=\n_UNAVAILABLE_VALIDATORS=\n\n#\n# Result files and results\n#\nreadonly R_PASSED=\"_PASSED.result\"\nreadonly R_FIXED=\"_FIXED.result\"\nreadonly R_FAILED_BY_STATUS=\"_FAILED_BY_STATUS.result\"\nreadonly R_FAILED_BY_DIFF=\"_FAILED_BY_DIFF.result\"\nreadonly R_SKIPPED_BY_FEATURES=\"_SKIPPED_BY_FEATURES.result\"\nreadonly R_SKIPPED_BY_LANGUAGES=\"_SKIPPED_BY_LANGUAGES.result\"\nreadonly R_SKIPPED_BY_ILOOP=\"_SKIPPED_BY_ILOOP.result\"\nreadonly R_KNOWN_BUGS=\"_KNOWN_BUGS.result\"\nreadonly R_FAILED_BY_TIMEED_OUT=\"_FAILED_BY_TIMEED_OUT.result\"\nreadonly R_BROKEN_ARGS_CTAGS=\"_BROKEN_ARGS_CTAGS.result\"\nreadonly R_VALGRIND=\"_VALGRIND.result\"\nL_PASSED=\nL_FIXED=\nL_FAILED_BY_STATUS=\nL_FAILED_BY_DIFF=\nL_SKIPPED_BY_FEATURES=\nL_SKIPPED_BY_LANGUAGES=\nL_SKIPPED_BY_ILOOP=\nL_KNOWN_BUGS=\nL_FAILED_BY_TIMEED_OUT=\nL_BROKEN_ARGS_CTAGS=\nL_VALGRIND=\n\nV_VALID=0\nV_INVALID=0\nV_SKIP_VALIDATOR_UNAVAILABLE=0\nV_SKIP_KNOWN_INVALIDATION=0\n\n#\n# TODO\n#\n#  * write new class 'r' (category directory) to units.rst.\n#  * write new class 'v' (skip the checking by valgrind) to units.rst.\n#\naction_help ()\n{\n    cat <<EOF\nUsage:\n\t$(help_help)\n\n\t$(help_run)\n\n\t$(help_clean)\n\n\t$(help_fuzz)\n\n\t$(help_shrink)\n\n\t$(help_noise)\n\n\t$(help_tmain)\n\n\t$(help_chop)\n\n\t$(help_validate_input)\n\n\t$(help_clean_tmain)\nEOF\n}\n\nhelp_help()\n{\n    echo \"$0 help|--help\"\n}\n\nERROR ()\n{\n    local status_=\"$1\"\n    local msg=\"$2\"\n    shift 2\n    echo \"$msg\" 1>&2\n    exit $status_\n}\n\nline()\n{\n    local c=${1:--}\n    local no_newline=\"${2}\"\n    local i=0\n    while [ $i -lt 60 ]; do\n\tprintf \"%c\" \"$c\"\n\ti=$(( i + 1 ))\n    done\n\n    if ! [ \"${no_newline}\" = \"--no-newline\" ]; then\n\techo\n    fi\n}\n\ncount_list ()\n{\n    echo $#\n}\n\nmember_p ()\n{\n    local elt=\"$1\"\n    shift\n    local x\n\n    for x in \"$@\"; do\n\tif [ \"$x\" = \"$elt\" ]; then\n\t    return 0\n\tfi\n    done\n\n    return 1\n}\n\nclean_tcase ()\n{\n    local d=\"$1\"\n    local bundles=\"$2\"\n    local b\n\n    if [ -d \"$d\" ]; then\n\tif [ -f \"${bundles}\" ]; then\n\t    while read b; do\n\t\trm -rf \"${b}\"\n\t    done < \"${bundles}\"\n\t    rm ${bundles}\n\tfi\n\trm -f \"$d\"/*.tmp \"$d\"/*.TMP\n    fi\n}\n\ncheck_availability()\n{\n    local cmd=\"$1\"\n    shift\n    type \"${cmd}\" > /dev/null 2>&1 || ERROR 1 \"${cmd} command is not available\"\n}\n\ncheck_units ()\n{\n    local name=\"$1\"\n    local category=\"$2\"\n    shift 2\n    local u\n\n    for u in \"$@\"; do\n\tif echo \"${u}\" | grep -q /; then\n\t    if [ \"${u%/*}\" = \"${category}\" ] && [ \"${u#*/}\" = \"${name}\" ]; then\n\t\treturn 0\n\t    fi\n\telif [ \"${u}\" = \"${name}\" ]; then\n\t    return 0\n\tfi\n    done\n    return 1\n}\n\ninit_features()\n{\n    _FEATURE_LIST=$( ${CTAGS} --quiet --options=NONE \\\n\t\t\t      --list-features --with-list-header=no \\\n\t\t\t      2> /dev/null \\\n\t\t| \"${_LINE_SPLITTER}\" \\\n\t\t| cut -f 1 -d ' ')\n}\n\ncheck_features()\n{\n    local flag=\"$1\"\n    local ffile\n    local feature\n\n    if [ \"${flag}\" = \"-f\" ]; then\n\tffile=\"$2\"\n    elif [ \"${flag}\" = \"-e\" ]; then\n\tfeature=\"$2\"\n    fi\n    shift 2\n\n    local f\n    local found\n    local found_unexpectedly\n    local expected;\n\n\n    for expected in $([ -f \"$ffile\" ] && cat \"$ffile\") ${feature}; do\n\t    found=no\n\t    found_unexpectedly=no\n\t    for f in ${_FEATURE_LIST} ; do\n\t\t[ \"$expected\" = \"$f\" ] && found=yes\n\t\t[ \"$expected\" = '!'\"$f\" ] && found_unexpectedly=yes\n\t    done\n\t    if [ \"${found_unexpectedly}\" = yes ]; then\n\t\techo \"$expected\"\n\t\treturn 1\n\t    elif ! [ \"$found\" = yes ]; then\n\t\techo \"$expected\"\n\t\treturn 1\n\t    fi\n    done\n\n    return 0\n}\n\ncheck_languages()\n{\n    local lfile=\"$1\"\n    shift\n\n    local l\n    local found\n    local expected;\n\n\n    #\n    # TODO: consider the value of LANGUAGES\n    #\n    while read expected; do\n\t    found=no\n\t    for l in $( ${_CMDLINE} --list-languages 2>/dev/null | \"${_LINE_SPLITTER}\" |sed -e 's/ //' ); do\n\t\t[ \"$expected\" = \"$l\" ] && found=yes\n\t    done\n\t    if ! [ \"$found\" = yes ]; then\n\t\techo \"$expected\"\n\t\treturn 1\n\t    fi\n    done < \"$lfile\"\n\n    return 0\n}\n\ndecorate ()\n{\n    local decorator=\"$1\"\n    local msg=\"$2\"\n\n    case \"$decorator\" in\n\tred)    decorator=31 ;;\n\tgreen)  decorator=32 ;;\n\tyellow) decorator=33 ;;\n\t*) ERROR 1 \"INTERNAL ERROR: wrong run_result function: $f\"\n    esac\n\n    if [ \"${COLORIZED_OUTPUT}\" = 'yes' ]; then\n\tprintf '%b\\n' \"\\033[${decorator}m${msg}\\033[39m\"\n    else\n\tprintf '%b\\n' \"${msg}\"\n    fi\n}\n\nrun_result ()\n{\n    local result_type=\"$1\"\n    local msg=\"$2\"\n    local output=\"$3\"\n    shift 3\n    local f=\"run_result_${result_type}\"\n    local tmp\n\n    type \"$f\" > /dev/null 2>&1 || ERROR 1 \\\n\t\"${msg}INTERNAL ERROR: wrong run_result function: $f\"\n\n    \"$f\" \"${msg}\" \"$@\"\n\n    tmp=\"${COLORIZED_OUTPUT}\"\n    COLORIZED_OUTPUT=no\n    \"$f\" \"${msg}\" \"$@\" > \"${output}\"\n    COLORIZED_OUTPUT=\"${tmp}\"\n}\n\nrun_result_skip ()\n{\n    local msg=\"$1\"\n    shift 1\n\n    if [ -n \"$1\" ]; then\n\tprintf '%b%b\\n' \"${msg}\" $(decorate yellow \"skipped\")\" ($1)\"\n    else\n\tprintf '%b%b\\n' \"${msg}\" $(decorate yellow \"skipped\")\n    fi\n}\n\nrun_result_error ()\n{\n    local msg=\"$1\"\n    shift 1\n\n    if [ ! -n \"$1\" ]; then\n\tprintf '%b%b\\n' \"${msg}\" $(decorate red \"failed\")\n    else\n\tprintf '%b%b\\n' \"${msg}\" $(decorate red \"failed\")\" ($1)\"\n    fi\n}\n\nrun_result_ok ()\n{\n    local msg=\"$1\"\n    shift 1\n\n    if [ ! -n \"$1\" ]; then\n\tprintf '%b%b\\n' \"${msg}\" $(decorate green \"passed\")\n    else\n\tprintf '%b%b\\n' \"${msg}\" $(decorate green \"passed\")\" ($1)\"\n    fi\n}\n\nrun_result_known_error ()\n{\n    local msg=\"$1\"\n    shift 1\n\n    printf '%b%b\\n' \"${msg}\" $(decorate yellow \"failed\")\" (KNOWN bug)\"\n}\n\nrun_shrink ()\n{\n    local cmdline_template=\"$1\"\n    local input=\"$2\"\n    local output=\"$3\"\n    local lang=\"$4\"\n    shift 4\n\n    echo \"Shrinking ${input} as ${lang}\"\n    shrink_main \"${cmdline_template}\" \"${input}\" \"${output}\"  1 yes\n}\n\n# filters out the directory prefix in a ctags input\nctags_basename_filter_regex='s%\\(^[^\t]\\{1,\\}\t\\)\\(/\\{0,1\\}\\([^/\t]\\{1,\\}/\\)*\\)%\\1%'\nctags_basename_filter()\n{\n    sed \"${ctags_basename_filter_regex}\"\n}\n\n# About \"input\" in the expression, see units.py.\netags_basename_filter_regex='s%.*\\/\\(input[-._][[:print:]]\\{1,\\}\\),\\([0-9]\\{1,\\}$\\)%\\1,\\2%'\netags_basename_filter()\n{\n    sed \"${etags_basename_filter_regex}\"\n}\n\nxref_basename_filter_regex='s%\\(.*[[:digit:]]\\{1,\\} \\)\\([^ ]\\{1,\\}[^ ]\\{1,\\}\\)/\\([^ ].\\{1,\\}.\\{1,\\}$\\)%\\1\\3%'\nxref_basename_filter()\n{\n    sed \"${xref_basename_filter_regex}\"\n}\n\njson_basename_filter_regex='s%\\(\"path\": \\)\"[^\"]\\{1,\\}/\\([^/\"]\\{1,\\}\\)\"%\\1\"\\2\"%'\njson_basename_filter()\n{\n    sed \"${json_basename_filter_regex}\"\n}\n\nrun_record_cmdline ()\n{\n    local ffilter=\"$1\"\n    local ocmdline=\"$2\"\n\n    printf \"%s\\n%s \\\\\\\\\\n| %s \\\\\\\\\\n| %s\\n\"  \\\n\t\"${_PREPERE_ENV}\" \\\n\t\"${_CMDLINE}\" \\\n\t\"sed '${tags_basename_filter_regex}'\" \\\n\t\"${ffilter}\" \\\n\t> \"${ocmdline}\"\n}\n\n#\n# All files and directories other than input.*, expected.tags,\n# args.ctags, README*, features, languages, and filters under srcdir\n# are copied to builddir. These copied files are called bundles.\n#\nprepare_bundles ()\n{\n    local from=$1\n    local to=$2\n    local obundles=$3\n    local src\n    local dist\n\n    for src in ${from}/*; do\n\tif [ \"${from}\"'/*' = \"${src}\" ]; then\n\t    break\n\tfi\n\tcase \"${src##*/}\" in\n\t    input.*)\n\t\tcontinue\n\t\t;;\n\t    expected.tags*)\n\t\tcontinue\n\t\t;;\n\t    README*)\n\t\tcontinue\n\t\t;;\n\t    features|languages|filters)\n\t\tcontinue\n\t\t;;\n\t    args.ctags)\n\t\tcontinue\n\t\t;;\n\t    *)\n\t\tdist=\"${to}/${src##*/}\"\n\t\tif ! cp -a \"${src}\" \"${to}\"; then\n\t\t    ERROR 1 \"failure in copying bundle file \\\"${src}\\\" to \\\"${to}\\\"\"\n\t\telse\n\t\t    echo ${dist} >> ${obundles}\n\t\tfi\n\t\t;;\n\tesac\n    done\n}\n\ndireq ()\n{\n    [ \"$(cd ${1} && pwd)\" = \"$(cd ${2} && pwd)\" ]\n    return $?\n}\n\nanon_normalize ()\n{\n    local ctags=$1\n    local input_actual\n\n    if [ -n \"$2\" ]; then\n\tinput_actual=$2\n\tshift 2\n\n\t# TODO: \"Units\" should not be hardcoded.\n\tlocal input_expected=\"./Units${input_actual#*/Units}\"\n\n\tlocal actual=$(${CTAGS} --quiet --options=NONE --_anonhash=\"${input_actual}\")\n\tlocal expected=$(${CTAGS} --quiet --options=NONE --_anonhash=\"${input_expected}\")\n\n\tsed -e s/${actual}/${expected}/g | anon_normalize \"${ctags}\" \"$@\"\n    else\n\tcat\n    fi\n}\n\nrun_tcase ()\n{\n    local input=\"$1\"\n    local t=\"$2\"\n    local name=\"$3\"\n    local class=\"$4\"\n    local category=\"$5\"\n    local build_t=\"$6\"\n    shift 6\n    # The rest of arguments ($@) are extra inputs\n\n    # I violate the naming convention of build_* to reduce typing\n    local o=${build_t}\n\n    local fargs=\"$t/args.ctags\"\n    local ffeatures=\"$t/features\"\n    local flanguages=\"$t/languages\"\n    local ffilter=\"$t/filter\"\n\n    #\n    # tags-e if for etags output(-e). TAGS is good\n    # suffix but foo.tags and foo.TAGS may be the same on Windows.\n    # tags-x is for cross reference output(-x).\n    # tags-json is for json output.\n    #\n    # fexpected must be set even if none of\n    # expected.{tags,tags-e,tags-x,tags-json} exits.\n    #\n    local fexpected=\"$t/expected.tags\"\n    local output_type=ctags\n    local output_label=\n    local output_tflag=\n    local output_feature=\n    local output_lang_extras=\n\n    if [ -f \"$t/expected.tags\" ]; then\n\t:\n    elif [ -f \"$t/expected.tags-e\" ]; then\n\tfexpected=$t/expected.tags-e\n\toutput_type=etags\n\toutput_label=/${output_type}\n\toutput_tflag=\"-e  --tag-relative=no\"\n    elif [ -f \"$t/expected.tags-x\" ]; then\n\tfexpected=$t/expected.tags-x\n\toutput_type=xref\n\toutput_label=/${output_type}\n\toutput_tflag=-x\n    elif [ -f \"$t/expected.tags-json\" ]; then\n\tfexpected=$t/expected.tags-json\n\toutput_type=json\n\toutput_label=/${output_type}\n\toutput_tflag=\"--output-format=json\"\n\toutput_feature=json\n    fi\n\n    if [ $# -gt 0 ]; then\n\toutput_lang_extras=\" (multi inputs)\"\n    fi\n\n    [ -x \"$ffilter\" ] || ffilter=cat\n\n    #\n    # All generated file must have suffix \".tmp\".\n    #\n    local ostderr=\"$o/${_STDERR_OUTPUT_NAME}\"\n    local orawout=\"$o/RAWOUT.tmp\"\n    local ofiltered=\"$o/FILTERED.tmp\"\n    local odiff=\"$o/${_DIFF_OUTPUT_NAME}\"\n    local ocmdline=\"$o/CMDLINE.tmp\"\n    local ovalgrind=\"$o/VALGRIND.tmp\"\n    local oresult=\"$o/RESULT.tmp\"\n    local oshrink_template=\"$o/SHRINK-%s.tmp\"\n    local obundles=\"$o/BUNDLES\"\n    local oshrink\n\n    local guessed_lang\n    local guessed_lang_no_slash\n    local cmdline_template\n    local timeout_value\n    local tmp\n    local msg\n\n    local broke_args_ctags\n\n    #\n    # Filtered by UNIT\n    #\n    if [ -n \"${UNITS}\" ]; then\n\tcheck_units \"${name}\" \"${category}\" ${UNITS} || return 1\n    fi\n\n    #\n    # Build _CMDLINE\n    #\n    _CMDLINE=\"${CTAGS} --verbose --options=NONE --fields=-T $PRETENSE_OPTS --optlib-dir=+$t/optlib -o -\"\n    [ -f \"${fargs}\" ] && _CMDLINE=\"${_CMDLINE} --options=${fargs}\"\n\n    if [ -f \"${fargs}\" ] && ! ${_CMDLINE} --_force-quit=0 > /dev/null 2>&1; then\n\tbroke_args_ctags=1\n    fi\n\n    #\n    # Filtered by LANGUAGES\n    #\n    guessed_lang=$( ${_CMDLINE} --print-language \"$input\" 2>/dev/null | sed -n 's/^.*: //p')\n    if [ -n \"${LANGUAGES}\" ]; then\n\tmember_p \"${guessed_lang}\" ${LANGUAGES} || return 1\n    fi\n    guessed_lang_no_slash=$(echo \"${guessed_lang}\" | tr '/' '-')\n    oshrink=$(printf \"${oshrink_template}\" \"${guessed_lang_no_slash}\")\n\n    clean_tcase \"${o}\" \"${obundles}\"\n    mkdir -p \"${o}\"\n    if ! direq \"${o}\" \"${t}\"; then\n\tprepare_bundles ${t} ${o} \"${obundles}\"\n    fi\n\n\n    msg=$(printf '%-60s' \"Testing ${name} as ${guessed_lang}${output_lang_extras}${output_label}\")\n\n    if tmp=$( ( [ -n \"${output_feature}\" ] && ! check_features -e \"${output_feature}\" ) ||\n\t      ( [ -f \"${ffeatures}\" ] && ! check_features -f \"${ffeatures}\" ) ); then\n\techo \"${category}/${name}\" >> ${R_SKIPPED_BY_FEATURES}\n\tcase \"${tmp}\" in\n\t    !*) run_result skip \"${msg}\" \"${oresult}\" \"unwanted feature \\\"${tmp#?}\\\" is available\";;\n\t    *)  run_result skip \"${msg}\" \"${oresult}\" \"required feature \\\"${tmp}\\\" is not available\";;\n\tesac\n\treturn 1\n    elif [ -f \"${flanguages}\" ] && ! tmp=$(check_languages \"${flanguages}\"); then\n\techo \"${category}/${name}\" >> ${R_SKIPPED_BY_LANGUAGES}\n\trun_result skip \"${msg}\" \"${oresult}\" \"required language parser \\\"$tmp\\\" is not available\"\n\treturn 1\n    elif [ \"$WITH_TIMEOUT\" = 0 ] && [ \"${class}\" = 'i' ]; then\n\techo \"${category}/${name}\" >> ${R_SKIPPED_BY_ILOOP}\n\trun_result skip \"${msg}\" \"${oresult}\" \"may cause an infinite loop\"\n\treturn 1\n    elif [ \"$broke_args_ctags\" = 1 ]; then\n\trun_result error \"${msg}\" '/dev/null' \"broken args.ctags?\"\n\techo \"${category}/${name}/\" >> ${R_BROKEN_ARGS_CTAGS}\n\treturn 1\n    fi\n\n    cmdline_template=\"${_CMDLINE} --language-force=${guessed_lang} %s > /dev/null 2>&1\"\n    _CMDLINE=\"${_CMDLINE} ${output_tflag} ${input} $@\"\n\n    timeout_value=$WITH_TIMEOUT\n    if [ \"$WITH_VALGRIND\" = yes ]; then\n\t_CMDLINE=\"valgrind --leak-check=full --error-exitcode=${_VALGRIND_EXIT} --log-file=${ovalgrind} ${_CMDLINE}\"\n\ttimeout_value=$(( timeout_value * ${_VG_TIMEOUT_FACTOR} ))\n    fi\n\n    if ! [ \"$timeout_value\" = 0 ]; then\n\t_CMDLINE=\"timeout $timeout_value ${_CMDLINE}\"\n    fi\n\n    {\n\t(\n\t    #\n\t    # When a launched process is exited abnormally, the parent shell reports it\n\t    # to stderr: See j_strsignal function call in wait_for in bash-4.2/nojobs.c.\n\t    # This becomes noise; close the stderr of subshell.\n\t    #\n\t    exec  2>&-;\n\t    #\n\t    # The original bug report(#1100 by @techee):\n\t    # --------------------------------------------------------------------------\n\t    # When running\n\t    #\n\t    #     make units VG=1\n\t    #\n\t    # one cannot stop its execution by pressing Ctrl+C and\n\t    # there doesn't seem to be any way (except for looking at\n\t    # processes which run and killing them) to stop its\n\t    # execution.\n\t    #\n\t    trap \"exit ${_BASH_INTERRUPT_EXIT}\" INT;\n\t    ${_CMDLINE} 2> \"${ostderr}\" > \"${orawout}\"\n\t)\n\ttmp=\"$?\"\n\trun_record_cmdline \"${ffilter}\" \"${ocmdline}\"\n    }\n    if [ \"$tmp\" != 0 ]; then\n\tif [ \"${tmp}\" = \"${_BASH_INTERRUPT_EXIT}\" ]; then\n\t    ERROR 1 \"The execution is interrupted\"\n\telif ! [ \"$WITH_TIMEOUT\" = 0 ] && [ \"${tmp}\" = \"${_TIMEOUT_EXIT}\" ]; then\n\t    echo \"${category}/${name}\" >> ${R_FAILED_BY_TIMEED_OUT}\n\t    run_result error \"${msg}\" \"${oresult}\" \"TIMED OUT\"\n\t    run_record_cmdline \"${ffilter}\" \"${ocmdline}\"\n\t    [ \"${RUN_SHRINK}\" = 'yes' ] \\\n\t\t&& [ $# -eq 0 ] \\\n\t\t&& run_shrink \"${cmdline_template}\" \"${input}\" \"${oshrink}\" \"${guessed_lang}\"\n\t    return 1\n\telif [ \"$WITH_VALGRIND\" = 'yes' ] && [ \"${tmp}\" = \"${_VALGRIND_EXIT}\" ] && ! [ \"${class}\" = v ]; then\n\t    echo \"${category}/${name}\" >> ${R_VALGRIND}\n\t    run_result error \"${msg}\" \"${oresult}\" \"valgrind-error\"\n\t    run_record_cmdline \"${ffilter}\" \"${ocmdline}\"\n\t    return 1\n\telif [ \"$class\" = 'b' ]; then\n\t    echo \"${category}/${name}\" >> ${R_KNOWN_BUGS}\n\t    run_result known_error \"${msg}\" \"${oresult}\"\n\t    run_record_cmdline \"${ffilter}\" \"${ocmdline}\"\n\t    [ \"${RUN_SHRINK}\" = 'yes' ] \\\n\t\t&& [ $# -eq 0 ] \\\n\t\t&& run_shrink \"${cmdline_template}\" \"${input}\" \"${oshrink}\" \"${guessed_lang}\"\n\t    return 0\n\telse\n\t    echo \"${category}/${name}\" >> ${R_FAILED_BY_STATUS}\n\t    run_result error \"${msg}\" \"${oresult}\" \"unexpected exit status: $tmp\"\n\t    run_record_cmdline \"${ffilter}\" \"${ocmdline}\"\n\t    [ \"${RUN_SHRINK}\" = 'yes' ] \\\n\t\t&& [ $# -eq 0 ] \\\n\t\t&& run_shrink \"${cmdline_template}\" \"${input}\" \"${oshrink}\" \"${guessed_lang}\"\n\t    return 1\n\tfi\n    elif [ \"$WITH_VALGRIND\" = 'yes' ] && [ \"$class\" = 'v' ]; then\n\techo \"${category}/${name}\" >> ${R_FIXED}\n    fi\n\n    if ! [ -f \"${fexpected}\" ]; then\n\tclean_tcase \"${o}\" \"${obundles}\"\n\tif [ \"$class\" = 'b' ]; then\n\t    echo \"${category}/${name}\" >> ${R_FIXED}\n\telif [ \"$class\" = 'i' ]; then\n\t    echo \"${category}/${name}\" >> ${R_FIXED}\n\tfi\n\techo \"${category}/${name}\" >> ${R_PASSED}\n\trun_result ok \"${msg}\" '/dev/null' \"\\\"expected.tags*\\\" not found\"\n\treturn 0\n    fi\n\n    ${output_type}_basename_filter < \"${orawout}\" | \\\n\tanon_normalize \"${CTAGS}\" \"${input}\" \"$@\" | \\\n\t$ffilter > \"${ofiltered}\"\n\n    {\n\tdiff -U 0 -I '^!_TAG' --strip-trailing-cr \"${fexpected}\" \"${ofiltered}\" > \"${odiff}\"\n\ttmp=\"$?\"\n    }\n    if [ \"${tmp}\" = 0 ]; then\n\tclean_tcase \"${o}\" \"${obundles}\"\n\tif [ \"${class}\" = 'b' ]; then\n\t    echo \"${category}/${name}\" >> ${R_FIXED}\n\telif ! [ \"$WITH_TIMEOUT\" = 0 ] && [ \"${class}\" = 'i' ]; then\n\t    echo \"${category}/${name}\" >> ${R_FIXED}\n\tfi\n\n\techo \"${category}/${name}\" >> ${R_PASSED}\n\trun_result ok \"${msg}\" '/dev/null'\n\treturn 0\n    else\n\tif [ \"${class}\" = 'b' ]; then\n\t    echo \"${category}/${name}\" >> ${R_KNOWN_BUGS}\n\t    run_result known_error \"${msg}\" \"${oresult}\"\n\t    run_record_cmdline \"${ffilter}\" \"${ocmdline}\"\n\t    return 0\n\telse\n\t    echo \"${category}/${name}\" >> ${R_FAILED_BY_DIFF}\n\t    run_result error \"${msg}\" \"${oresult}\" \"unexpected output\"\n\t    run_record_cmdline \"${ffilter}\" \"${ocmdline}\"\n\t    return 1\n\tfi\n    fi\n}\n\n\nfailure_in_globing ()\n{\n    # skip if globing failed, also ignore backup files\n    case $1 in\n        *\\~)  return 0 ;;\n        *\\**) return 0 ;;\n         *)   return 1 ;;\n     esac\n}\n\nrun_dir ()\n{\n    local category=\"$1\"\n    local base_dir=\"$2\"\n    local build_base_dir=\"$3\"\n    shift 3\n\n    local tcase_dir\n    local build_tcase_dir\n    local input\n    local name\n    local dname\n    local class\n\n    local extra_tmp\n    local extra_inputs\n\n    #\n    # Filtered by CATEGORIES\n    #\n    if [ -n \"$CATEGORIES\" ] && ! member_p \"${category}\" $CATEGORIES; then\n\treturn 1\n    fi\n\n    echo\n    echo \"Category: $category\"\n    line\n    for input in ${base_dir}/*.[dbtiv]/input.*; do\n\tif failure_in_globing \"$input\"; then\n\t    continue\n\tfi\n\n\tdname=$(dirname $input)\n\textra_inputs=$(for extra_tmp in $dname/input[-_][0-9].* \\\n\t\t\t\t\t$dname/input[-_][0-9][-_]*.* ; do\n\t    if failure_in_globing \"$extra_tmp\"; then\n\t\tcontinue\n\t    fi\n\t    echo \"$extra_tmp\"\n\tdone | sort)\n\n\ttcase_dir=\"${input%/input.*}\"\n\tbuild_tcase_dir=\"${build_base_dir}/${tcase_dir#${base_dir}/}\"\n\tname=\"${tcase_dir%.[dbtiv]}\"\n\tname=\"${name##*/}\"\n\tclass=\"${tcase_dir#*${name}.}\"\n\t# Run this in parallel\n\trun_tcase \"${input}\" \"${tcase_dir}\" \"${name}\" \"${class}\" \"${category}\" \"${build_tcase_dir}\" ${extra_inputs} &\n    done\n    wait\n\n    return 0\n}\n\nrun_show_diff_output ()\n{\n    local units_dir=\"$1\"\n    local t=\"$2\"\n\n    printf \"\t\"\n    line .\n    sed -e 's/^.*$/\t&/' ${units_dir}/${t}.*/${_DIFF_OUTPUT_NAME}\n    echo\n}\n\nrun_show_stderr_output ()\n{\n    local units_dir=\"$1\"\n    local t=\"$2\"\n\n    printf \"\t\"\n    line .\n    sed -e 's/^.*$/\t&/' ${units_dir}/${t}.*/${_STDERR_OUTPUT_NAME} | tail -50\n    echo\n}\n\nrun_summary ()\n{\n    local build_dir=\"${1}\"\n    local t\n\n    echo\n    echo \"Summary (see CMDLINE.tmp to reproduce without test harness)\"\n    line\n\n    printf '  %-40s' \"#passed:\"\n    L_PASSED=$([ -f $R_PASSED ] && cat $R_PASSED)\n    count_list $L_PASSED\n\n    printf '  %-40s' \"#FIXED:\"\n    L_FIXED=$([ -f $R_FIXED ] && cat $R_FIXED)\n    count_list $L_FIXED\n    for t in $L_FIXED; do\n\techo \"\t${t#${_DEFAULT_CATEGORY}/}\"\n    done\n\n    printf '  %-40s' \"#FAILED (broken args.ctags?):\"\n    L_BROKEN_ARGS_CTAGS=$([ -f $R_BROKEN_ARGS_CTAGS ] && cat $R_BROKEN_ARGS_CTAGS)\n    count_list $L_BROKEN_ARGS_CTAGS\n    for t in $L_BROKEN_ARGS_CTAGS; do\n\techo \"\t${t#${_DEFAULT_CATEGORY}/}\"\n    done\n\n    printf '  %-40s' \"#FAILED (unexpected-exit-status):\"\n    L_FAILED_BY_STATUS=$([ -f $R_FAILED_BY_STATUS ] && cat $R_FAILED_BY_STATUS)\n    count_list $L_FAILED_BY_STATUS\n    for t in $L_FAILED_BY_STATUS; do\n\techo \"\t${t#${_DEFAULT_CATEGORY}/}\"\n\tif [ \"${SHOW_DIFF_OUTPUT}\" = yes ]; then\n\t    run_show_stderr_output \"${build_dir}\" \"${t#${_DEFAULT_CATEGORY}/}\"\n\tfi\n    done\n\n    printf '  %-40s' \"#FAILED (unexpected-output):\"\n    L_FAILED_BY_DIFF=$([ -f $R_FAILED_BY_DIFF ] && cat $R_FAILED_BY_DIFF)\n    count_list $L_FAILED_BY_DIFF\n    for t in $L_FAILED_BY_DIFF; do\n\techo \"\t${t#${_DEFAULT_CATEGORY}/}\"\n\tif [ \"${SHOW_DIFF_OUTPUT}\" = yes ]; then\n\t    run_show_stderr_output \"${build_dir}\" \"${t#${_DEFAULT_CATEGORY}/}\"\n\t    run_show_diff_output \"${build_dir}\" \"${t#${_DEFAULT_CATEGORY}/}\"\n\tfi\n    done\n\n    if ! [ \"$WITH_TIMEOUT\" = 0 ]; then\n\tprintf '  %-40s' \"#TIMED-OUT (${WITH_TIMEOUT}s)\"\n\tL_FAILED_BY_TIMEED_OUT=$([ -f $R_FAILED_BY_TIMEED_OUT ] && cat $R_FAILED_BY_TIMEED_OUT)\n\tcount_list $L_FAILED_BY_TIMEED_OUT\n\tfor t in $L_FAILED_BY_TIMEED_OUT; do\n\t    echo \"\t${t#${_DEFAULT_CATEGORY}/}\"\n\tdone\n    fi\n\n    printf '  %-40s' \"#skipped (features):\"\n    L_SKIPPED_BY_FEATURES=$([ -f $R_SKIPPED_BY_FEATURES ] && cat $R_SKIPPED_BY_FEATURES)\n    count_list $L_SKIPPED_BY_FEATURES\n    for t in $L_SKIPPED_BY_FEATURES; do\n\techo \"\t${t#${_DEFAULT_CATEGORY}/}\"\n    done\n\n    printf '  %-40s' \"#skipped (languages):\"\n    L_SKIPPED_BY_LANGUAGES=$([ -f $R_SKIPPED_BY_LANGUAGES ] && cat $R_SKIPPED_BY_LANGUAGES)\n    count_list $L_SKIPPED_BY_LANGUAGES\n    for t in $L_SKIPPED_BY_LANGUAGES; do\n\techo \"\t${t#${_DEFAULT_CATEGORY}/}\"\n    done\n\n    if [ \"$WITH_TIMEOUT\" = 0 ]; then\n\tprintf '  %-40s' \"#skipped (infinite-loop):\"\n\tL_SKIPPED_BY_ILOOP=$([ -f $R_SKIPPED_BY_ILOOP ] && cat $R_SKIPPED_BY_ILOOP)\n\tcount_list $L_SKIPPED_BY_ILOOP\n\tfor t in $L_SKIPPED_BY_ILOOP; do\n\t    echo \"\t${t#${_DEFAULT_CATEGORY}/}\"\n\tdone\n    fi\n\n    printf '  %-40s' \"#known-bugs:\"\n    L_KNOWN_BUGS=$([ -f $R_KNOWN_BUGS ] && cat $R_KNOWN_BUGS)\n    count_list $L_KNOWN_BUGS\n    for t in $L_KNOWN_BUGS; do\n\techo \"\t${t#${_DEFAULT_CATEGORY}/}\"\n    done\n\n    if [ \"$WITH_VALGRIND\" = yes ]; then\n\tprintf '  %-40s' \"#valgrind-error:\"\n\tL_VALGRIND=$([ -f $R_VALGRIND ] && cat $R_VALGRIND)\n\tcount_list $L_VALGRIND\n\tfor t in $L_VALGRIND; do\n\t    echo \"\t${t#${_DEFAULT_CATEGORY}/}\"\n\tdone\n    fi\n}\n\nmake_pretense_map ()\n{\n    local ifs=$IFS\n    local p\n    local r\n\n    IFS=,\n    for p in $1; do\n\tnewlang=${p%/*}\n\toldlang=${p#*/}\n\n\tif [ -z \"$newlang\" ]; then\n\t    ERROR 1 \"newlang part of --pretend option arg is empty\"\n\tfi\n\tif [ -z \"$oldlang\" ]; then\n\t    ERROR 1 \"oldlang part of --pretend option arg is empty\"\n\tfi\n\n\tr=\"$r --_pretend-$newlang=$oldlang\"\n    done\n    IFS=$ifs\n    echo $r\n}\n\ndelete_result_files ()\n{\n    rm -f ${R_PASSED} ${R_FIXED} ${R_FAILED_BY_STATUS} ${R_FAILED_BY_DIFF} \\\n\t${R_SKIPPED_BY_FEATURES} ${R_SKIPPED_BY_LANGUAGES} \\\n\t${R_SKIPPED_BY_ILOOP} ${R_KNOWN_BUGS} ${R_FAILED_BY_TIMEED_OUT} \\\n\t${R_BROKEN_ARGS_CTAGS}\n}\n\naction_run ()\n{\n    local action=\"$1\"\n    shift\n\n    local units_dir\n    local build_dir\n    local d\n    local build_d\n    local category\n\n    local c\n\n    while [ $# -gt 0 ]; do\n\tcase $1 in\n\t    --ctags)\n\t\tshift\n\t\tCTAGS=\"$1\"\n\t\tshift\n\t\t;;\n\t    --ctags=*)\n\t\tCTAGS=\"${1#--ctags=}\"\n\t\tshift\n\t\t;;\n\t    --categories)\n\t\tshift\n\t\tfor c in $(echo \"$1\" | tr ',' ' '); do\n\t\t    if [ \"$c\" = \"ROOT\" ]; then\n\t\t\tCATEGORIES=\"$CATEGORIES ROOT\"\n\t\t    else\n\t\t\tCATEGORIES=\"$CATEGORIES ${c%.r}.r\"\n\t\t    fi\n\t\tdone\n\t\tshift\n\t\t;;\n\t    --categories=*)\n\t\tfor c in $(echo \"${1#--categories=}\" | tr ',' ' '); do\n\t\t    if [ \"$c\" = \"ROOT\" ]; then\n\t\t\tCATEGORIES=\"$CATEGORIES ROOT\"\n\t\t    else\n\t\t\tCATEGORIES=\"$CATEGORIES ${c%.r}.r\"\n\t\t    fi\n\t\tdone\n\t\tshift\n\t\t;;\n\t    --units)\n\t\tshift\n\t\tUNITS=$(echo \"$1\" | tr ',' ' ')\n\t\tshift\n\t\t;;\n\t    --units=*)\n\t\tUNITS=$(echo \"${1#--units=}\" | tr ',' ' ')\n\t\tshift\n\t\t;;\n\t    --languages)\n\t\tshift\n\t\tLANGUAGES=$(echo \"${1}\" | tr ',' ' ')\n\t\tshift\n\t\t;;\n\t    --languages=*)\n\t\tLANGUAGES=$(echo \"${1#--languages=}\" | tr ',' ' ')\n\t\tshift\n\t\t;;\n\t    --with-timeout)\n\t\tshift\n\t\tWITH_TIMEOUT=\"$1\"\n\t\tshift\n\t\t;;\n\t    --with-timeout=*)\n\t\tWITH_TIMEOUT=\"${1#--with-timeout=}\"\n\t\tshift\n\t\t;;\n\t    --with-valgrind)\n\t\tshift\n\t\tWITH_VALGRIND=yes\n\t\t;;\n\t    --colorized-output)\n\t\tshift\n\t\tCOLORIZED_OUTPUT=\"$1\"\n\t\tshift\n\t\t;;\n\t    --colorized-output=*)\n\t\tCOLORIZED_OUTPUT=\"${1#--colorized-output=}\"\n\t\tshift\n\t\t;;\n\t    --run-shrink)\n\t\tRUN_SHRINK=yes\n\t\tshift\n\t\t;;\n\t    --show-diff-output)\n\t\tSHOW_DIFF_OUTPUT=yes\n\t\tshift\n\t\t;;\n\t    --with-pretense-map)\n\t\tshift\n\t\tPRETENSE_OPTS=$(make_pretense_map \"$1\")\n\t\tshift\n\t\t;;\n\t    --with-pretense-map=*)\n\t\tPRETENSE_OPTS=$(make_pretense_map \"${1#--with-pretense-map=}\")\n\t\tshift\n\t\t;;\n\t    -*)\n\t\tERROR 1 \"unknown option \\\"${1}\\\" for ${action} action\"\n\t\t;;\n\t    *)\n\t\tunits_dir=\"$1\"\n\t\tshift\n\t\tbuild_dir=\"${1:-${units_dir}}\"\n\t\tshift\n\t\tbreak\n\t\t;;\n\tesac\n    done\n\n    if [ $# -gt 0 ]; then\n\tERROR 1 \"too many arguments for ${action} action: $*\"\n    elif [ -z \"$units_dir\" ]; then\n\tERROR 1 \"UNITS_DIR parameter is not given in ${action} action\"\n    fi\n\n    if ! [ -d \"$units_dir\" ]; then\n\tERROR 1 \"No such directory: ${units_dir}\"\n    fi\n\n    case \"${build_dir}\" in\n\t/*) ;;\n\t*) build_dir=$(pwd)/${build_dir} ;;\n    esac\n\n    if ! [ -d \"$build_dir\" ]; then\n\tERROR 1 \"No such directory(build_dir): ${build_dir}\"\n    fi\n\n    if ! [ -f \"${CTAGS}\" ]; then\n\tERROR 1 \"no such file: ${CTAGS}\"\n    elif ! [ -e \"${CTAGS}\" ]; then\n\tERROR 1 \"${CTAGS} is not an executable file\"\n    fi\n\n    if ! ( [ \"${COLORIZED_OUTPUT}\" = 'yes' ] || [ \"${COLORIZED_OUTPUT}\" = 'no' ] ); then\n\tERROR 1 \"unexpected option argument for --colorized-output: ${COLORIZED_OUTPUT}\"\n    fi\n\n    : ${WITH_TIMEOUT:=0}\n    [ \"$WITH_TIMEOUT\" = 0 ] || check_availability timeout\n    [ \"$WITH_VALGRIND\" = 'yes' ] && check_availability valgrind\n    [ \"$MSYSTEM\" != '' ] && check_availability dos2unix\n    check_availability grep\n    check_availability diff\n    init_features\n\n    delete_result_files\n\n    category=\"${_DEFAULT_CATEGORY}\"\n    if [ -z \"$CATEGORIES\" ] \\\n\t|| ( [ -n \"$CATEGORIES\" ] && member_p \"${category}\" $CATEGORIES ); then\n\trun_dir \"${category}\" \"${units_dir}\" \"${build_dir}\"\n    fi\n\n    for d in ${units_dir}/*.r; do\n\t[ -d \"$d\" ] || continue\n\tcategory=\"${d##*/}\"\n\tbuild_d=${build_dir}/${category}\n\trun_dir \"${category}\" \"$d\" \"${build_d}\"\n    done\n\n    run_summary \"${build_dir}\"\n    delete_result_files\n\n    if [ -n \"${L_FAILED_BY_STATUS}\" ] ||\n\t   [ -n \"${L_FAILED_BY_DIFF}\" ] ||\n\t   [ -n \"${L_FAILED_BY_TIMEED_OUT}\" ] ||\n\t   [ -n \"${L_BROKEN_ARGS_CTAGS}\" ]; then\n\treturn 1\n    else\n\treturn 0\n    fi\n}\n\nhelp_run ()\n{\ncat <<EOF\n$0 run [OPTIONS] UNITS-DIR\n\n\t   Run all tests case under UNITS-DIR.\n\n\t   OPTIONS:\n\t\t--ctags CTAGS: ctags executable file for testing\n\t\t--categories CATEGORY1[,CATEGORY2,...]: run only CATEGORY* related cases.\n\t\t\t\t\t\t\tCategory selection is done in upper\n\t\t\t\t\t\t\tlayer than unit selection. This\n\t\t\t\t\t\t\tmeans even if a unit is specified\n\t\t\t\t\t\t\twith --units, it can be ignored\n\t\t\t\t\t\t\tis a category the units doesn't\n\t\t\t\t\t\t\tbelong to is specified with\n\t\t\t\t\t\t\t--categories option.\n\t\t--colorized-output yes|no: print the result in color.\n\t\t--skip NAME: skip the case NAME (TODO: NOT IMPLEMENTED YET)\n\t\t--languages PARSER1[,PARSER2,...]: run only PARSER* related cases.\n\t\t--units UNITS1[,UNITS2,...]: run only UNIT(S).\n\t\t--with-timeout DURATION: run a test case under timeout\n\t\t\t\t\t command with SECOND.\n\t\t\t\t\t 0 means no timeout(default).\n\t\t--with-valgrind: run a test case under valgrind\n\t\t\t       If this option given, DURATION is changed to\n\t\t\t       DURATION := DURATION * ${_VG_TIMEOUT_FACTOR}\n\t\t--show-diff-output: show diff output for failed test cases in the summary.\n\t\t--with-pretense-map=NEWLANG0/OLDLANG0[,...]: make NEWLANG parser pretend\n\t\t\t\t\t\t\t     OLDLANG.\nEOF\n}\n\naction_clean ()\n{\n    local action=\"$1\"\n    shift\n\n    local units_dir=$1\n    shift\n\n    local bundles\n    local b\n\n    if [ $# -gt 0 ]; then\n\tERROR 1 \"too many arguments for ${action} action: $*\"\n    elif [ -z \"$units_dir\" ]; then\n\tERROR 1 \"UNITS_DIR parameter is not given in ${action} action\"\n    fi\n\n    if ! [ -d \"$units_dir\" ]; then\n\tERROR 0 \"No such directory: ${units_dir}\"\n    fi\n\n    check_availability find\n    check_availability rm\n\n    for bundles in $(find \"$units_dir\" -name \"BUNDLES\"); do\n\twhile read b; do\n\t    rm -rf \"${b}\"\n\tdone < ${bundles}\n\trm ${bundles}\n    done\n\n    rm -f $(find \"$units_dir\" -name '*.tmp')\n    rm -f $(find \"$units_dir\" -name '*.TMP')\n    return 0\n}\n\nhelp_clean ()\n{\ncat <<EOF\n$0 clean UNITS-DIR\n\n\t   Clean all files created during units testing\nEOF\n\n}\n\nshrink_prepare ()\n{\n    local output=\"$1\"\n    local input=\"$2\"\n    local start=\"$3\"\n    local len=\"$4\"\n\n\n    dd bs=1 count=\"${len}\" skip=\"${start}\" < \"${input}\" 2>/dev/null > \"${output}\"\n}\n\nshrink_test ()\n{\n    local cmdline=\"$1\"\n    local input=\"$2\"\n    local start=\"$3\"\n    local len=\"$4\"\n    local output=\"$5\"\n    local r\n    local msg\n\n    shrink_prepare \"${output}\" \"${input}\" \"${start}\" \"${len}\"\n    [ \"${QUIET}\" = 'yes' ] || printf \"[%-5u %6u]...\" \"${start}\" $(( start + len )) 1>&2\n    eval \"${cmdline}\" > /dev/null 2>&1\n    r=\"$?\"\n    if [ \"$r\" -eq 0 ]; then\n\tmsg='ok'\n    elif [ \"$r\" -eq \"${_TIMEOUT_EXIT}\" ]; then\n\tmsg='timeout'\n    else\n\tmsg='failed'\n    fi\n    [ \"${QUIET}\" = 'yes' ] || printf \"%s(%u)\\n\" \"$msg\" \"$r\" 1>&2\n    return $r\n}\n\nshrink_bisect ()\n{\n    local cmdline=\"$1\"\n    local input=\"$2\"\n    local len=\"$3\"\n    local output=\"$4\"\n\n    local end\n    local start\n    local step\n    local delta\n\n    local failed\n    local successful\n\n    end=\"${len}\"\n    failed=\"${len}\"\n    successful=0\n\n    step=0\n    while true; do\n\tdelta=$((len >> (step + 1)))\n\tif [ \"${delta}\" -eq 0 ]; then\n\t    delta=1\n\tfi\n\tif shrink_test \"${cmdline}\" \"${input}\" 0 \"${end}\" \"${output}\"; then\n\t    successful=\"${end}\"\n\t    if [ $(( end + 1 )) -eq \"${failed}\" ]; then\n\t\tend=\"${failed}\"\n\t\tbreak\n\t    else\n\t\tend=$((end + delta))\n\t    fi\n\telse\n\t    failed=\"$end\"\n\t    if [ $(( successful + 1 )) -eq \"${end}\" ]; then\n\t\tbreak\n\t    else\n\t\tend=$((end - delta))\n\t    fi\n\tfi\n\tstep=$((step + 1 ))\n    done\n\n    len=\"${end}\"\n    start=0\n    failed=0\n    successful=\"${end}\"\n    step=0\n    while true; do\n\tdelta=$((len >> (step + 1)))\n\tif [ \"${delta}\" -eq 0 ]; then\n\t    delta=1\n\tfi\n\tif shrink_test \"${cmdline}\" \"${input}\" \"${start}\" $((end - start)) \"${output}\"; then\n\t    successful=\"${start}\"\n\t    if [ $(( start - 1 )) -eq \"${failed}\" ]; then\n\t\tstart=$((start - 1))\n\t\tbreak\n\t    else\n\t\tstart=$((start - delta))\n\t    fi\n\telse\n\t    failed=\"${start}\"\n\t    if [ $((successful - 1)) -eq \"${start}\" ]; then\n\t\tbreak\n\t    else\n\t\tstart=$((start + delta))\n\t    fi\n\tfi\n\tstep=$((step + 1))\n    done\n\n    len=$((end - start))\n    shrink_prepare \"${output}\" \"${input}\" \"${start}\" \"${len}\"\n    [ \"${QUIET}\" = 'yes' ] || echo \"Minimal badinput: ${output}\"\n    [ \"${QUIET}\" = 'yes' ] || line .\n    cat \"${output}\"\n    echo\n\n    return 0\n}\n\nshrink_main ()\n{\n    local cmdline_template=\"$1\"\n    local cmdline\n    local input=\"$2\"\n    local len\n    local output=\"$3\"\n    local duration=\"$4\"\n    local foreground=\"$5\"\n\n    if ! [ -f \"${input}\" ]; then\n\tERROR 1 \"No such file: ${input}\"\n    elif ! [ -r \"${input}\" ]; then\n\tERROR 1 \"Cannot read a file: ${input}\"\n    fi\n\n    if ! cat < /dev/null > \"${output}\"; then\n\tERROR 1 \"Cannot modify a file: ${output}\"\n    fi\n\n    cmdline=$(printf \"${cmdline_template}\" \"${output}\")\n    if [ -n \"${duration}\" ] && ! [ \"${duration}\" -eq 0 ]; then\n\tif [ \"${foreground}\" = 'yes' ]; then\n\t    cmdline=\"timeout --foreground ${duration} ${cmdline}\"\n\telse\n\t    cmdline=\"timeout ${duration} ${cmdline}\"\n\tfi\n    fi\n\n    len=$(${_FSIZE} \"${input}\")\n\n    if shrink_test \"${cmdline}\" \"${input}\" 0 \"${len}\" \"${output}\"; then\n\tprintf \"the target command line exits normally against the original input\\n\" 1>&2\n\treturn 1\n    fi\n\n    if ! shrink_test \"${cmdline}\" \"${input}\" 0 0 \"${output}\"; then\n\tprintf \"the target command line exits abnormally against the empty input\\n\" 1>&2\n\treturn 1\n    fi\n\n    shrink_bisect \"${cmdline}\" \"${input}\" \"${len}\" \"${output}\"\n}\n\naction_shrink ()\n{\n    local action=\"$1\"\n    shift\n\n    local cmdline_template\n    local input\n    local output\n\n    local timeout\n    local duration\n    local foreground\n\n\n    while [ $# -gt 0 ]; do\n\tcase $1 in\n\t    --timeout)\n\t\tshift\n\t\tduration=$1\n\t\tshift\n\t\t;;\n\t    --timeout=*)\n\t\tduration=\"${1#--timeout=}\"\n\t\tshift\n\t\t;;\n\t    --foreground)\n\t\tforeground=yes\n\t\tshift\n\t\t;;\n\t    --quiet)\n\t\tQUIET=yes\n\t\tshift\n\t\t;;\n\t    -*)\n\t\tERROR 1 \"unknown option \\\"${1}\\\" for ${action} action\"\n\t\t;;\n\t    *)\n\t\tbreak\n\t\t;;\n\t    esac\n    done\n\n    if [ $# -lt 3 ]; then\n\tERROR 1 \"too few arguments for ${action} action: $*\"\n    elif [ $# -gt 3 ]; then\n\tERROR 1 \"too many arguments for ${action} action: $*\"\n    fi\n\n    if [ -n \"${foreground}\" ] && [ -z \"${duration}\" ]; then\n\tERROR 1 \"--foreground option is meaningful only if --timeout option is specified.\"\n    fi\n\n    cmdline_template=$1\n    input=$2\n    output=$3\n    shift 3\n\n    shrink_main \"${cmdline_template}\" \"${input}\" \"${output}\" ${duration} ${foreground}\n    return $?\n}\n\nhelp_shrink ()\n{\ncat <<EOF\n$0 shrink [OPTIONS] CMD_TEMPLATE INPUT OUTPUT\n\n\t   Shrink the input while the execution of CMD_TEMPLATE is failed\n\t   and find minimal unwanted input.\n\n\t   OPTIONS:\n\t\t--timeout N: Run CMD under timeout command with duration N\n\t\t--foreground: add --foreground option to timeout command.\n\t\t\t      can be used with --timeout option.\n\t   EXAMPLES:\n\t\tmisc/units shrink \"u-ctags -o - %s\" original-input.js  /tmp/anyname.js\nEOF\n}\n#action_shrink shrink --timeout=1 --foreground \"./a.out  < %s\" input.txt output.txt\n\nfuzz_shrink ()\n{\n    local cmdline_template=\"$1\"\n    local input=\"$2\"\n    local output=\"$3\"\n    local lang=\"$4\"\n    shift 4\n\n    [ \"${QUIET}\" = 'yes' ] || {\n\techo \"Shrinking ${input} as ${lang}\"\n\tline .\n    }\n    shrink_main \"${cmdline_template}\" \"${input}\" \"${output}\"  1 yes\n}\n\nfuzz_lang_file ()\n{\n    local lang=\"$1\"\n    local file=\"$2\"\n    shift 2\n    local r\n\n    local dir=\"${file%/*}\"\n    local ovalgrind=\"${dir}/VALGRIND-${lang}.tmp\"\n    local ocmdline=\"${dir}/CMDLINE-${lang}.tmp\"\n    local oshrink=\"${dir}/SHRINK-${lang}.tmp\"\n\n    local cmdline\n    local cmdline_for_shirking\n\n    rm -f \"${ovalgrind}\" \"${ocmdline}\" \"${oshrink}\"\n\n\n    if [ \"${WITH_VALGRIND}\" = 'yes' ]; then\n\tcmdline=$( printf \"${_CMDLINE} --language-force=${lang} ${file}\" \"${ovalgrind}\" )\n    else\n\tcmdline=\"${_CMDLINE} --language-force=${lang} ${file}\"\n\n    fi\n    cmdline_for_shirking=\"${_CMDLINE_FOR_SHRINKING} --language-force=${lang} %s\"\n\n\n    [ \"${QUIET}\" = 'yes' ] || printf \".\"\n    echo \"${cmdline}\" > \"${ocmdline}\"\n    ${cmdline} > /dev/null\n    r=$?\n\n    case $r in\n\t0)\n\t    rm -f \"${ovalgrind}\" \"${ocmdline}\"\n\t    return 0\n\t    ;;\n\t${_TIMEOUT_EXIT})\n\t    [ \"${QUIET}\" = 'yes' ] || echo\n\t    printf '%-40s' \"[timeout $lang]\"\n\t    echo \"$f\"\n\t    [ \"${RUN_SHRINK}\" = 'yes' ] && fuzz_shrink \"${cmdline_for_shirking}\" \"${file}\" \"${oshrink}\" \"${lang}\"\n\t    return 1\n\t    ;;\n\t${_VALGRIND_EXIT})\n\t    [ \"${QUIET}\" = 'yes' ] || echo\n\t    printf '%-40s' \"[valgrind-error $lang]\"\n\t    echo \"$f\"\n\t    return 1\n\t    ;;\n\t*)\n\t    [ \"${QUIET}\" = 'yes' ] || echo\n\t    printf '%-40s' \"[unexpected-status($r) $lang]\"\n\t    echo \"$f\"\n\t    [ \"${RUN_SHRINK}\" = 'yes' ] && fuzz_shrink \"${cmdline_for_shirking}\" \"${file}\" \"${oshrink}\" \"${lang}\"\n\t    return 1\n\t    ;;\n    esac\n\n    return $r\n}\n\nfuzz_lang ()\n{\n    local lang=\"$1\"\n    local dir=\"$2\"\n    shift 2\n    local f\n    local r=0\n\n    [ \"${QUIET}\" = 'yes' ] || printf '%-60s\\n' \"Semi-fuzzing (${lang})\"\n    for f in $(find \"${dir}\" -type f -name 'input.*'); do\n\tif ! fuzz_lang_file \"${lang}\" \"${f}\"; then\n\t    r=1\n\t    break\n\tfi\n    done\n    [ \"${QUIET}\" = 'yes' ] || echo\n    return $r\n}\n\naction_fuzz ()\n{\n    action_fuzz_common fuzz_lang \"$@\"\n}\n\naction_fuzz_common ()\n{\n    local fn=\"$1\"\n    local action=\"$2\"\n    shift 2\n\n    local units_dir\n    local cmdline\n    local lang\n    local r\n\n    while [ $# -gt 0 ]; do\n\tcase $1 in\n\t    --ctags)\n\t\tshift\n\t\tCTAGS=\"$1\"\n\t\tshift\n\t\t;;\n\t    --ctags=*)\n\t\tCTAGS=\"${1#--ctags=}\"\n\t\tshift\n\t\t;;\n\t    --languages)\n\t\tshift\n\t\tLANGUAGES=$(echo \"${1}\" | tr ',' ' ')\n\t\tshift\n\t\t;;\n\t    --languages=*)\n\t\tLANGUAGES=$(echo \"${1#--languages=}\" | tr ',' ' ')\n\t\tshift\n\t\t;;\n\t    --quiet)\n\t\tQUIET=yes\n\t\tshift\n\t\t;;\n\t    --with-timeout)\n\t\tshift\n\t\tWITH_TIMEOUT=\"$1\"\n\t\tshift\n\t\t;;\n\t    --with-timeout=*)\n\t\tWITH_TIMEOUT=\"${1#--with-timeout=}\"\n\t\tshift\n\t\t;;\n\t    --with-valgrind)\n\t\tshift\n\t\tWITH_VALGRIND=yes\n\t\t;;\n\t    --colorized-output)\n\t\tshift\n\t\tCOLORIZED_OUTPUT=\"$1\"\n\t\tshift\n\t\t;;\n\t    --colorized-output=*)\n\t\tCOLORIZED_OUTPUT=\"${1#--colorized-output=}\"\n\t\tshift\n\t\t;;\n\t    --run-shrink)\n\t\tRUN_SHRINK=yes\n\t\tshift\n\t\t;;\n\t    -*)\n\t\tERROR 1 \"unknown option \\\"${1}\\\" for ${action} action\"\n\t\t;;\n\t    *)\n\t\tunits_dir=\"$1\"\n\t\tshift\n\t\tbreak;\n\t\t;;\n\tesac\n    done\n\n    if [ $# -gt 0 ]; then\n\tERROR 1 \"too many arguments for ${action} action: $*\"\n    elif [ -z \"$units_dir\" ]; then\n\tERROR 1 \"UNITS_DIR parameter is not given in ${action} action\"\n    fi\n\n    if ! [ -d \"$units_dir\" ]; then\n\tERROR 0 \"No such directory: ${units_dir}\"\n    fi\n\n    if ! [ -f \"${CTAGS}\" ]; then\n\tERROR 1 \"no such file: ${CTAGS}\"\n    elif ! [ -e \"${CTAGS}\" ]; then\n\tERROR 1 \"${CTAGS} is not an executable file\"\n    fi\n\n    if ! ( [ \"${COLORIZED_OUTPUT}\" = 'yes' ] || [ \"${COLORIZED_OUTPUT}\" = 'no' ] ); then\n\tERROR 1 \"unexpected option argument for --colorized-output: ${COLORIZED_OUTPUT}\"\n    fi\n\n    : ${WITH_TIMEOUT:=2}\n    [ \"$WITH_TIMEOUT\" = 0 ] || check_availability timeout\n    [ \"$WITH_VALGRIND\" = 'yes' ] && check_availability valgrind\n    check_availability find\n\n    cmdline=\"${CTAGS} --quiet --options=NONE --kinds-all=* --fields=*\"\n    _CMDLINE=\"${cmdline} -G -o - \"\n    _CMDLINE_FOR_SHRINKING=\"${_CMDLINE}\"\n    if [ \"$WITH_VALGRIND\" = yes ]; then\n\t_CMDLINE=\"valgrind --leak-check=full --error-exitcode=${_VALGRIND_EXIT} --log-file=%s ${_CMDLINE}\"\n\tWITH_TIMEOUT=$(( WITH_TIMEOUT * ${_VG_TIMEOUT_FACTOR} ))\n    fi\n\n    if ! [ \"$WITH_TIMEOUT\" = 0 ]; then\n\t_CMDLINE=\"timeout --foreground $WITH_TIMEOUT ${_CMDLINE}\"\n\t_CMDLINE_FOR_SHRINKING=\"timeout --foreground 1 ${_CMDLINE_FOR_SHRINKING}\"\n    fi\n\n    for lang in $( ${cmdline} --list-languages 2>/dev/null | \"${_LINE_SPLITTER}\" |sed -e 's/ //' ) ; do\n\tif [ -n \"${LANGUAGES}\" ] && ! member_p \"${lang}\" ${LANGUAGES}; then\n\t    continue\n\tfi\n\t\"${fn}\" \"${lang}\" \"${units_dir}\"\n\tr=$?\n    done\n\n    return $r\n}\n\nhelp_fuzz ()\n{\ncat <<EOF\n$0 fuzz [OPTIONS] UNITS-DIR\n\n\t   Run all tests case under UNITS-DIR.\n\n\t   OPTIONS:\n\t\t--ctags CTAGS: ctags executable file for testing\n\t\t--languages PARSER1[,PARSER2,...]: run only PARSER* related cases\n\t\t--quiet: don't print dots as passed test cases.\n\t\t--with-timeout DURATION: run a test case under timeout\n\t\t\t\t\t command with SECOND.\n\t\t\t\t\t 0 means no timeout.\n\t\t\t\t\t default is 1.\n\t\t--with-valgrind: run a test case under valgrind\n\t\t\t       If this option given, DURATION is changed to\n\t\t\t       DURATION := DURATION * ${_VG_TIMEOUT_FACTOR}\nEOF\n}\n\nnoise_reduce ()\n{\n    local input=\"$1\"\n    local len=\"$2\"\n    local pos=\"$3\"\n    shift 3\n\n    dd bs=1 count=$pos skip=0 if=\"$input\"\n    dd bs=1 count=$(( len - pos - 1 )) skip=$(( pos + 1 )) if=\"$input\"\n}\n\nnoise_inject ()\n{\n    local input=\"$1\"\n    local len=\"$2\"\n    local pos=\"$3\"\n    local c=\"$4\"\n    shift 4\n\n    dd bs=1 count=$pos skip=0 if=\"$input\"\n    printf \"%c\" \"$c\"\n    dd bs=1 count=$(( len - pos )) skip=$pos if=\"$input\"\n}\n\nnoise_report_line ()\n{\n    local pos=\"$1\"\n    local len=\"$2\"\n    local status_=\"$3\"\n    local how=\"$4\"\n\n    local progress_offset=$(( pos % _NOISE_REPORT_MAX_COLUMN ))\n    local nspace\n\n\n    if [ $((pos + 1)) -eq \"${len}\" ] || [ $status_ -gt 0 ]; then\n\tnspace=0\n\twhile [ $nspace -lt $(( _NOISE_REPORT_MAX_COLUMN - progress_offset - 1)) ]; do\n\t    printf ' '\n\t    nspace=$((nspace + 1))\n\tdone\n\tprintf \" %s %d/%d\" \"${how}\" \"$pos\" \"${len}\"\n    fi\n}\n\nnoise_lang_file_noisespec ()\n{\n    local input=\"$1\"\n    local len=\"$2\"\n    local pos=\"$3\"\n    local c=\"$4\"\n    local genfn=\"$5\"\n    local lang=\"$6\"\n    local how=\"$7\"\n    shift 7\n\n    local msg\n    if [ \"${how}\" = + ]; then\n\tmsg=INJECTED\n\thow=\"${how}${c}\"\n    else\n\tmsg=REDUCED\n\thow=\"${how} \"\n    fi\n\n    local dir=\"${input%/*}\"\n    local onoised=$(printf \"%s/NOISE-INPUT-%s-%s-%d.tmp\" \"${dir}\" \"${msg}\" \"$pos\" \\'$c)\n    local ocmdline=$(printf \"%s/NOISE-CMDLINE-%s-%s-%d.tmp\" \"${dir}\" \"${msg}\" \"$pos\" \\'$c)\n    local ovalgrind=$(printf \"%s/NOISE-VALGRIND-%s-%s-%d.tmp\" \"${dir}\" \"${msg}\" \"$pos\" \\'$c)\n    local oshrink=$(printf \"%s/NOISE-SHRINK-%s-%s-%d.tmp\" \"${dir}\" \"${msg}\" \"$pos\" \\'$c)\n\n    local cmdline\n    local cmdline_for_shirking\n    local progress_offset\n    local r\n\n    rm -f \"${ocmdline}\" \"${ovalgrind}\" \"${onoised}\" \"${oshrink}\"\n    if [ \"${WITH_VALGRIND}\" = 'yes' ]; then\n\tcmdline=$( printf \"${_CMDLINE} --language-force=${lang} ${onoised}\" \"${ovalgrind}\" )\n\telse\n\tcmdline=\"${_CMDLINE} --language-force=${lang} ${onoised}\"\n    fi\n    cmdline_for_shirking=\"${_CMDLINE_FOR_SHRINKING} --language-force=${lang} %s\"\n\n    \"${genfn}\" \"${input}\" \"${len}\" \"$pos\" \"$c\" > \"$onoised\"  2> /dev/null\n\n    progress_offset=$(( pos % _NOISE_REPORT_MAX_COLUMN ))\n    if [ \"${progress_offset}\" -eq 0 ]; then\n\t[ $pos -gt 0 ] && printf \" %s %d/%d\" \"${how}\" \"$pos\" \"${len}\"\n\techo\n    fi\n\n    echo \"${cmdline}\" > \"${ocmdline}\"\n    ( exec 2>&-; ${cmdline} 2> /dev/null > /dev/null )\n    r=$?\n    case $r in\n\t    0)\n\t    printf 'o'\n\t    noise_report_line \"${pos}\" \"${len}\" \"${r}\" \"${how}\"\n\t    rm \"${onoised}\"\n\t    rm -f \"${ovalgrind}\" \"${ocmdline}\"\n\t    ;;\n\t${_TIMEOUT_EXIT})\n\t    printf \"T\"\n\t    noise_report_line \"${pos}\" \"${len}\" \"${r}\" \"${how}\"\n\t    printf '\\n%-20s\\n' \"[timeout $lang]\" \"$onoised\"\n\t    [ \"${RUN_SHRINK}\" = 'yes' ] && fuzz_shrink \"${cmdline_for_shirking}\" \"${onoised}\" \"${oshrink}\" \"${lang}\"\n\t    ;;\n\t${_VALGRIND_EXIT})\n\t    printf \"V\"\n\t    noise_report_line \"${pos}\" \"${len}\" \"${r}\" \"${how}\"\n\t    printf '\\n%-20s %s\\n' \"[valgrind-error $lang]\" \"$onoised\"\n\t    ;;\n\t*)\n\t    printf \"!\"\n\t    noise_report_line \"${pos}\" \"${len}\" \"${r}\" \"${how}\"\n\t    printf '\\n%-20s %s\\n' \"[unexpected-status($r) $lang]\" \"$onoised\"\n\t    [ \"${RUN_SHRINK}\" = 'yes' ] && fuzz_shrink \"${cmdline_for_shirking}\" \"${onoised}\" \"${oshrink}\" \"${lang}\"\n\t    ;;\n    esac\n    return $r\n}\n\nnoise_lang_file ()\n{\n    local lang=\"$1\"\n    local input=\"$2\"\n    shift 2\n\n\n    local cmdline\n    local cmdline_for_shirking\n    local len=$(${_FSIZE} \"${input}\")\n    local r\n    local i\n    local c\n    local guessed_lang\n\n    guessed_lang=$( ${_CMDLINE_FOR_SHRINKING} --print-language \"${input}\" 2>/dev/null | sed -n 's/^.*: //p')\n    if [ \"${lang}\" !=  \"${guessed_lang}\" ]; then\n\treturn 0\n    fi\n\n    i=0\n    c='!'\n    echo \"Testing cases derived from: ${input}\"\n    line '.' --no-newline\n    while [ \"$i\" -lt \"$len\" ]; do\n\tif noise_lang_file_noisespec \"${input}\" \"${len}\" \"$i\" \"$c\" noise_reduce \"${lang}\" -; then\n\t    i=$(( i + 1 ))\n\telse\n\t    echo\n\t    return 1\n\tfi\n    done\n\n    for c in 'a' '0'\t\t\t\t\t\t\\\n\t'!' '@' '#' '$' '%' '^' '&' '*' '(' ')' '-' '=' '_'\t\\\n\t'+' '|'  '[' ']' '{' '}' '\\' ';' \"'\" ':' '\"' ',' '.'    \\\n\t'/' '<' '>' '?' '`' '~'; do\n\ti=0\n\twhile [ \"$i\" -lt \"$len\" ]; do\n\t    if noise_lang_file_noisespec \"${input}\" \"${len}\" \"$i\" \"$c\" noise_inject \"${lang}\" +; then\n\t\ti=$(( i + 1 ))\n\t    else\n\t\techo\n\t\treturn 1\n\t    fi\n\tdone\n    done\n    echo\n    return 0\n}\n\nnoise_lang ()\n{\n    local lang=\"$1\"\n    local dir=\"$2\"\n    shift 2\n    local f\n    local r\n    printf '%-60s\\n' \"Noised-fuzzing (${lang})\"\n    line '-'\n\n    r=0\n    for f in $(find \"${dir}\" -type f -name 'input.*'); do\n\tif ! noise_lang_file \"${lang}\" \"${f}\"; then\n\t    r=1\n\t    break\n\tfi\n    done\n    echo\n    return $r\n}\n\naction_noise ()\n{\n    action_fuzz_common noise_lang \"$@\"\n}\n\nhelp_noise ()\n{\ncat <<EOF\n$0 noise [OPTIONS] UNITS-DIR\n\n\t   Run all tests case for LANGUAGE with \"noise\" for\n\t   finding unexpected behavior like entering an\n\t   infinite loop.\n\t   Here \"noise\" means removing one byte from\n\t   somewhere file position of the original test case;\n\t   or adding something one byte to\n\t   somewhere file position of the original test case.\n\n\t   OPTIONS:\n\t\t--ctags CTAGS: ctags executable file for testing\n\t\t--languages PARSER1[,PARSER2,...]: run only PARSER* related cases\n\t\t--quiet: don't print dots as passed test cases.\n\t\t--with-timeout DURATION: run a test case under timeout\n\t\t\t\t\t command with SECOND.\n\t\t\t\t\t 0 means no timeout.\n\t\t\t\t\t default is 1.\n\t\t--with-valgrind: run a test case under valgrind\n\t\t\t       If this option given, DURATION is changed to\n\t\t\t       DURATION := DURATION * ${_VG_TIMEOUT_FACTOR}\nEOF\n}\n\n\ntmain_compare_result()\n{\n    local build_topdir=$1\n    local f\n\n    for f in ${build_topdir}/*/*-diff.txt; do\n\tif [ -f \"$f\" ]; then\n\t    echo \"$f\"\n\t    echo\n\t    cat \"$f\" | sed -e 's|.*|\t&|'\n\t    echo\n\tfi\n    done\n    if [ -f ${build_topdir}/*/gdb-backtrace.txt ]; then\n\tcat ${build_topdir}/*/gdb-backtrace.txt\n    fi\n}\n\ntmain_compare()\n{\n    local subdir=$1\n    local build_subdir=$2\n    local aspect=$3\n    local generated\n    local msg\n\n    msg=$(printf '%-60s' \"${aspect}\")\n    generated=${build_subdir}/${aspect}-diff.txt\n    if diff -U 0 --strip-trailing-cr \\\n\t    ${subdir}/${aspect}-expected.txt \\\n\t    ${build_subdir}/${aspect}-actual.txt \\\n\t    > ${generated} 2>&1; then\n\trun_result ok \"${msg}\" '/dev/null'\n\trm ${generated}\n\treturn 0\n    else\n\trun_result error \"${msg}\" '/dev/null' \"diff: ${generated}\"\n\treturn 1\n    fi\n}\n\nfailed_git_marker ()\n{\n    local f=$1\n    local l\n\n    if type \"git\" > /dev/null 2>&1; then\n\tl=$(git ls-files -- \"$f\")\n\tif [ -z \"$l\" ]; then\n\t    echo '<G>'\n\tfi\n    fi\n}\n\nis_crashed ()\n{\n    local f=$1\n\n    grep -q -i \"core dump\" \"$f\"\n}\n\nprint_backtraces()\n{\n    local ctags_exe=$1\n    shift 1\n\n    local coref\n    for coref in \"$@\"; do\n\tif [ -f \"${coref}\" ]; then\n\t    gdb \"${ctags_exe}\" -c \"${coref}\" -ex where -batch\n\telse\n\t    echo \"no such file: ${coref}\"\n\tfi\n    done\n}\n\nCODE_FOR_IGNORING_THIS_TMAIN_TEST=77\ntmain_run ()\n{\n    local topdir=$1\n    local build_topdir=$2\n    shift 2\n    local units=\"$@\"\n\n    local subdir\n    local basedir\n\n    local test_name\n    local r_failed=\"_failed.result\"\n    local failed\n    local f\n\n    local aspect\n    local engine\n\n    local r\n    local a\n    local status_=0\n    local msg\n\n    local need_rearrange\n\n    if ! [ $(basename \"${CTAGS}\") = 'ctags' ]; then\n\tneed_rearrange=yes\n    fi\n\n    rm -f ${r_failed}\n    basedir=$(pwd)\n    for subdir in ${topdir}/*.d; do\n\tif [ \"${subdir}\" = ${topdir}/'*.d' ]; then\n\t    return 1\n\tfi\n\n\ttest_name=$(basename ${subdir} .d)\n\n\tif [ -n \"${units}\" ] && ! member_p \"${test_name}\" ${units}; then\n\t    continue\n\tfi\n\n\tbuild_subdir=${build_topdir}/$(basename ${subdir})\n\tif ! mkdir -p ${build_subdir}; then\n\t    return 1\n\tfi\n\n\t# Run this block in parallel\n\t(\n\t    rm -f ${build_subdir}/*-actual.txt\n\n\t    msg=\"\\nTesting ${test_name}\"\n\t    msg=\"${msg}\\n$(line '-')\"\n\t    (\n\t\tcd ${subdir}\n\t\t${SHELL} run.sh \\\n\t\t\t ${basedir}/${CTAGS} \\\n\t\t\t ${build_subdir} \\\n\t\t\t ${basedir}/${READTAGS}\n\t    ) > ${build_subdir}/stdout-actual.txt 2> ${build_subdir}/stderr-actual.txt\n\t    r=$?\n\t    echo $r > ${build_subdir}/exit-actual.txt\n\n\t    if [ -n \"${need_rearrange}\" ]; then\n\t\tsed -i -e 's|^'$(basename \"${CTAGS}\")':|ctags:|' ${build_subdir}/stderr-actual.txt\n\t    fi\n\n\t    if [ $r = $CODE_FOR_IGNORING_THIS_TMAIN_TEST ]; then\n\t\tmsg=\"${msg}\\n$(run_result skip \"\" '/dev/null' \"$(cat ${build_subdir}/stdout-actual.txt)\")\"\n\t\tfor a in ${build_subdir}/*-actual.txt; do\n\t\t    if [ -f \"$a\" ]; then\n\t\t\trm $a\n\t\t    fi\n\t\tdone\n\t\tprintf \"%b\\n\" \"${msg}\"\n\t\texit\n\t    fi\n\n\t    if [ -f ${build_subdir}/tags ]; then\n\t\tmv ${build_subdir}/tags ${build_subdir}/tags-actual.txt\n\t    fi\n\t    for aspect in stdout stderr exit tags; do\n\t\tif [ -f ${subdir}/${aspect}-expected.txt ]; then\n\t\t    engine=compare\n\t\t    msg=\"${msg}\\n$(tmain_${engine} ${subdir} ${build_subdir} ${aspect})\"\n\t\t    if [ $? -eq 0 ]; then\n\t\t\trm ${build_subdir}/${aspect}-actual.txt\n\t\t    else\n\t\t\techo \"${test_name}/${aspect}-${engine}$(failed_git_marker ${subdir}/${aspect}-expected.txt)\" >> ${r_failed}\n\t\t\tif [ ${aspect} = stderr ] &&\n\t\t\t       is_crashed ${build_subdir}/${aspect}-actual.txt &&\n\t\t\t       type \"gdb\" > /dev/null 2>&1; then\n\t\t\t    print_backtraces \"${basedir}/${CTAGS}\" \\\n\t\t\t\t\t     ${build_subdir}/core* \\\n\t\t\t\t\t     > ${build_subdir}/gdb-backtrace.txt\n\t\t\tfi\n\t\t    fi\n\t\telif [ -f ${build_subdir}/${aspect}-actual.txt ]; then\n\t\t    rm ${build_subdir}/${aspect}-actual.txt\n\t\tfi\n\t    done\n\n\t    printf \"%b\\n\" \"${msg}\"\n\t) &\n    done\n    wait\n\n    if [ -f \"${r_failed}\" ]; then\n\tstatus_=1\n\techo\n\techo Failed tests\n\tline '='\n\tfailed=$(cat ${r_failed})\n\tfor f in ${failed}; do\n\t    echo $f | sed -e 's|<G>| (not committed/cached yet)|'\n\tdone\n\techo\n\n\tif [ \"${SHOW_DIFF_OUTPUT}\" = yes ]; then\n\t    engine=compare\n\t    echo Detail \"[$engine]\"\n\t    line '-'\n\t    tmain_${engine}_result ${build_topdir}\n\tfi\n\trm ${r_failed}\n    fi\n\n    return $status_\n}\n\naction_tmain ()\n{\n    local action=\"$1\"\n    shift\n    local tmain_dir\n    local build_dir\n\n    while [ $# -gt 0 ]; do\n\tcase $1 in\n\t    --ctags)\n\t\tshift\n\t\tCTAGS=\"$1\"\n\t\tshift\n\t\t;;\n\t    --ctags=*)\n\t\tCTAGS=\"${1#--ctags=}\"\n\t\tshift\n\t\t;;\n\t    --colorized-output)\n\t\tshift\n\t\tCOLORIZED_OUTPUT=\"$1\"\n\t\tshift\n\t\t;;\n\t    --colorized-output=*)\n\t\tCOLORIZED_OUTPUT=\"${1#--colorized-output=}\"\n\t\tshift\n\t\t;;\n\t    --with-valgrind)\n\t\tshift\n\t\tWITH_VALGRIND=yes\n\t\t;;\n\t    --show-diff-output)\n\t\tSHOW_DIFF_OUTPUT=yes\n\t\tshift\n\t\t;;\n\t    --readtags=*)\n\t\tREADTAGS=\"${1#--readtags=}\"\n\t\tshift\n\t\t;;\n\t    --units)\n\t\tshift\n\t\tUNITS=$(echo \"$1\" | tr ',' ' ')\n\t\tshift\n\t\t;;\n\t    --units=*)\n\t\tUNITS=$(echo \"${1#--units=}\" | tr ',' ' ')\n\t\tshift\n\t\t;;\n\t    -*)\n\t\tERROR 1 \"unknown option \\\"${1}\\\" for ${action} action\"\n\t\t;;\n\t    *)\n\t\ttmain_dir=\"$1\"\n\t\tshift\n\t\tbuild_dir=${1:-${tmain_dir}}\n\t\tif [ -n \"$1\" ]; then\n\t\t    shift\n\t\tfi\n\t\tbreak\n\t\t;;\n\tesac\n    done\n\n    if [ $# -gt 0 ]; then\n\tERROR 1 \"too many arguments for ${action} action: $*\"\n    elif [ -z \"$tmain_dir\" ]; then\n\tERROR 1 \"TMAIN_DIR parameter is not given in ${action} action\"\n    fi\n\n    if ! [ -d \"$tmain_dir\" ]; then\n\tERROR 1 \"No such directory(tmain_dir): ${tmain_dir}\"\n    fi\n\n    case \"${build_dir}\" in\n\t/*) ;;\n\t*) build_dir=$(pwd)/${build_dir} ;;\n    esac\n    if ! [ -d \"$build_dir\" ]; then\n\tERROR 1 \"No such directory(build_dir): ${build_dir}\"\n    fi\n\n    if ! [ -f \"${CTAGS}\" ]; then\n\tERROR 1 \"no such file: ${CTAGS}\"\n    elif ! [ -e \"${CTAGS}\" ]; then\n\tERROR 1 \"${CTAGS} is not an executable file\"\n    fi\n\n    if ! ( [ \"${COLORIZED_OUTPUT}\" = 'yes' ] || [ \"${COLORIZED_OUTPUT}\" = 'no' ] ); then\n\tERROR 1 \"unexpected option argument for --colorized-output: ${COLORIZED_OUTPUT}\"\n    fi\n\n    check_availability awk\n    check_availability diff\n\n    tmain_run ${tmain_dir} ${build_dir} ${UNITS}\n    return $?\n}\n\nhelp_tmain ()\n{\n    cat <<EOF\n$0 tmain [OPTIONS] TMAIN-DIR [BUILD-DIR]\n\n\t   Run tests for main part of ctags.\n\t   If BUILD-DIR is not given, TMAIN-DIR is reused as BUILD-DIR.\n\n\t   OPTIONS:\n\n\t\t--ctags CTAGS: ctags executable file for testing\n\t\t--colorized-output yes|no: print the result in color.\n\t\t--with-valgrind: (not implemented) run a test case under valgrind\n\t\t--show-diff-output: (not implemented)show diff output for failed test cases in the summary.\n\t\t--units UNITS1[,UNITS2,...]: run only Tmain/UNIT*.d (.d is not needed)\nEOF\n}\n\naction_clean_tmain()\n{\n    local action=\"$1\"\n    shift\n\n    local tmain_dir=$1\n    shift\n\n    if [ $# -gt 0 ]; then\n\tERROR 1 \"too many arguments for ${action} action: $*\"\n    elif [ -z \"$tmain_dir\" ]; then\n\tERROR 1 \"TMAIN_DIR parameter is not given in ${action} action\"\n    fi\n\n    if ! [ -d \"$tmain_dir\" ]; then\n\tERROR 1 \"No such directory: ${tmain_dir}\"\n    fi\n\n    check_availability find\n    check_availability rm\n\n    local object\n    local type\n    for object in stdout stderr exit tags; do\n\tfor type in actual diff; do\n\t    rm -f $(find \"$tmain_dir\" -name ${object}-${type}.txt)\n\t    rm -f $(find \"$tmain_dir\" -name gdb-backtrace.txt)\n\tdone\n    done\n    return 0\n}\n\nhelp_clean_tmain ()\n{\n    cat <<EOF\n$0 clean_tmain TMAIN-DIR\n\n\t   Clean all files created during tmain testing\nEOF\n\n}\n\nhelp_chop ()\n{\n    cat <<EOF\n$0 chop|slap [OPTIONS] UNITS-DIR\n\n\t   OPTIONS:\n\n\t\t--ctags CTAGS: ctags executable file for testing\n\t\t--languages PARSER1[,PARSER2,...]: run only PARSER* related cases\n\t\t--quiet: don't print dots as passed test cases.\n\t\t--with-timeout DURATION: run a test case under timeout\n\t\t\t\t\t command with SECOND.\n\t\t\t\t\t 0 means no timeout.\n\t\t\t\t\t default is 1.\n\t\t--with-valgrind: run a test case under valgrind\n\t\t\t       If this option given, DURATION is changed to\n\t\t\t       DURATION := DURATION * ${_VG_TIMEOUT_FACTOR}\nEOF\n}\n\naction_chop ()\n{\n    if [ \"$1\" = \"chop\" ]; then\n\taction_fuzz_common chop_lang \"$@\"\n    else\n\taction_fuzz_common slap_lang \"$@\"\n    fi\n}\n\nchop_lang()\n{\n    chop_lang_common \"tail\" \"$@\"\n}\n\nslap_lang()\n{\n    chop_lang_common \"head\" \"$@\"\n}\n\nchop_lang_common ()\n{\n    local endpoint=$1\n    shift 1\n\n    local lang=\"$1\"\n    local dir=\"$2\"\n    shift 2\n    local f\n    local r\n\n    printf '%-60s\\n' \"Fuzzing by truncating input from ${endpoint} (${lang})\"\n    line '-'\n\n    r=0\n    for f in $(find \"${dir}\" -type f -name 'input.*'); do\n\tif ! chop_lang_file \"$1\" \"${lang}\" \"${f}\"; then\n\t    r=1\n\t    break\n\tfi\n    done\n    echo\n    return $r\n}\n\nchop_lang_file ()\n{\n    local endpoint=$1\n    shift 1\n\n    local lang=\"$1\"\n    local input=\"$2\"\n    shift 2\n\n    local r\n    local cmdline\n    local cmdline_for_shirking\n    local len=$(${_FSIZE} \"${input}\")\n\n    local guessed_lang\n    guessed_lang=$( ${_CMDLINE_FOR_SHRINKING} --print-language \"${input}\" 2>/dev/null | sed -n 's/^.*: //p')\n    if [ \"${lang}\" !=  \"${guessed_lang}\" ]; then\n\treturn 0\n    fi\n\n    i=0\n    echo \"Testing cases derived from: ${input}\"\n    line '.' --no-newline\n\n    r=0\n    while [ \"$i\" -lt \"$len\" ]; do\n\tif chop_lang_file_chopspec \"${endpoint}\" \"${input}\" \"${len}\" \"$i\" \"${lang}\"; then\n\t    i=$(( i + 1 ))\n\telse\n\t    r=1\n\t    break\n\tfi\n    done\n    echo\n    return $r\n}\n\nchop()\n{\n    local endpoint=$1\n    local input=$2\n    local pos=$3\n    local len=$4\n\n    if [ \"${endpoint}\" = \"tail\" ]; then\n\tdd if=$input bs=1 count=$pos\n    else\n\tdd if=$input bs=1 count=$((len - pos)) skip=$pos\n    fi\n}\n\nchop_lang_file_chopspec()\n{\n    local endpoint=$1\n    shift 1\n\n    local input=\"$1\"\n    local len=\"$2\"\n    local pos=\"$3\"\n    local lang=\"$4\"\n    shift 4\n\n    local dir=\"${input%/*}\"\n    local ochopped=$(printf \"%s/CHOP-INPUT-%s.tmp\" \"${dir}\" \"$pos\")\n    local ocmdline=$(printf \"%s/CHOP-CMDLINE-%s.tmp\" \"${dir}\" \"$pos\")\n    local ovalgrind=$(printf \"%s/CHOP-VALGRIND-%s.tmp\" \"${dir}\" \"$pos\")\n    local oshrink=$(printf \"%s/CHOP-SHRINK-%s.tmp\" \"${dir}\" \"$pos\")\n\n    local cmdline\n    local cmdline_for_shirking\n    local progress_offset\n    local r\n\n    rm -f \"${ocmdline}\" \"${ovalgrind}\" \"${ochopped}\" \"${oshrink}\"\n\n    if [ \"${WITH_VALGRIND}\" = 'yes' ]; then\n\tcmdline=$( printf \"${_CMDLINE} --language-force=${lang} ${ochopped}\" \"${ovalgrind}\" )\n    else\n\tcmdline=\"${_CMDLINE} --language-force=${lang} ${ochopped}\"\n    fi\n    cmdline_for_shirking=\"${_CMDLINE_FOR_SHRINKING} --language-force=${lang} %s\"\n\n    chop \"${endpoint}\" \"${input}\" \"${pos}\" \"${len}\" > \"$ochopped\"  2> /dev/null\n\n    progress_offset=$(( pos % _NOISE_REPORT_MAX_COLUMN ))\n    if [ \"${progress_offset}\" -eq 0 ]; then\n\t[ $pos -gt 0 ] && printf \" %d/%d\" \"$pos\" \"${len}\"\n\techo\n    fi\n\n    echo \"${cmdline}\" > \"${ocmdline}\"\n    ( exec 2>&-; ${cmdline} 2> /dev/null > /dev/null )\n    r=$?\n    case $r in\n\t0)\n\t    printf 'o'\n\t    noise_report_line \"${pos}\" \"${len}\" \"${r}\" \"\"\n\t    rm \"${ochopped}\"\n\t    rm -f \"${ovalgrind}\" \"${ocmdline}\"\n\t    ;;\n\t${_TIMEOUT_EXIT})\n\t    printf \"T\"\n\t    noise_report_line \"${pos}\" \"${len}\" \"${r}\" \"\"\n\t    printf '\\n%-20s\\n' \"[timeout $lang]\" \"$ochopped\"\n\t    [ \"${RUN_SHRINK}\" = 'yes' ] && fuzz_shrink \"${cmdline_for_shirking}\" \"${ochopped}\" \"${oshrink}\" \"${lang}\"\n\t    ;;\n\t${_VALGRIND_EXIT})\n\t    printf \"V\"\n\t    noise_report_line \"${pos}\" \"${len}\" \"${r}\" \"\"\n\t    printf '\\n%-20s %s\\n' \"[valgrind-error $lang]\" \"$ochopped\"\n\t    ;;\n\t*)\n\t    printf \"!\"\n\t    noise_report_line \"${pos}\" \"${len}\" \"${r}\" \"\"\n\t    printf '\\n%-20s %s\\n' \"[unexpected-status($r) $lang]\" \"$ochopped\"\n\t    [ \"${RUN_SHRINK}\" = 'yes' ] && fuzz_shrink \"${cmdline_for_shirking}\" \"${ochopped}\" \"${oshrink}\" \"${lang}\"\n\t    ;;\n    esac\n    return $r\n}\n\nhelp_validate_input ()\n{\n    cat <<EOF\n$0 validate-input [OPTIONS] UNITS-DIR VALIDATORS-DIR\n\n\tValidate the input files (only for the test cases specifying validators.)\n\n\tOPTIONS:\n\t\t--validators=validator[,...]: Validate test cases specifying\n\t\t\t\t\t    given validators.\n\t\t--colorized-output: yes|no: print the result in color.\n\t\t--categories CATEGORY1[,CATEGORY2,...]: run only CATEGORY* related cases.\nEOF\n}\n\nhas_validator_acceptable_name ()\n{\n    local validator=$1\n    if [ -z \"${validator}\" ]; then\n\treturn 1\n    fi\n\n    echo \"${validator}\" | grep -q \"^[-a-zA-Z+#0-9]\\+$\"\n}\n\nis_validator_runnable ()\n{\n    local v=$1\n    local d=$2\n    shift 2\n\n    \"$d/\"validator-\"$v\" is_runnable unused $d\n}\n\nupdate_validator_list ()\n{\n    local type=$1\n    local v=$2\n\n    case $type in\n\trunnable)\n\t    if ! member_p \"$v\" ${_RUNNABLE_VALIDATORS}; then\n\t\t_RUNNABLE_VALIDATORS=\"${_RUNNABLE_VALIDATORS} $v\"\n\t    fi\n\t    ;;\n\tunavailable)\n\t    if ! member_p \"$v\" ${_UNAVAILABLE_VALIDATORS}; then\n\t\t_UNAVAILABLE_VALIDATORS=\"${_UNAVAILABLE_VALIDATORS} $v\"\n\t    fi\n\t    ;;\n\t*)\n\t    ERROR 1 \"INTERNAL ERROR: wrong validator list type: ${type}\"\n\t    ;;\n    esac\n}\n\n#\n# Whether a validator can be run or not.\n#\n# This runs \"is_runnable\" subcommand of the validator.\n#\nvalidate_validator ()\n{\n    local v=$1\n    local validators_dir=$2\n    local make_error=$3\n\n    if member_p \"$v\" ${_RUNNABLE_VALIDATORS}; then\n\treturn 0\n    elif member_p \"$v\" ${_UNAVAILABLE_VALIDATORS}; then\n\treturn 1\n    fi\n\n    if ! has_validator_acceptable_name \"$v\"; then\n\tif [ \"${make_error}\" = \"error\" ]; then\n\t    ERROR 1 \"Unacceptable validator name: $v\"\n\telse\n\t    update_validator_list unavailable \"$v\"\n\t    return 1\n\tfi\n    elif ! [ -f \"${validators_dir}/validator-$v\" ]; then\n\tif [ \"${make_error}\" = \"error\" ]; then\n\t    ERROR 1 \"No such validator: $v (${validators_dir}/validator-$v)\"\n\telse\n\t    update_validator_list unavailable \"$v\"\n\t    return 1\n\tfi\n    elif ! [ -x \"${validators_dir}/validator-$v\" ]; then\n\tif [ \"$make_error\" = \"error\" ]; then\n\t    ERROR 1 \"Not executable: $v (${validators_dir}/validator-$v)\"\n\telse\n\t    update_validator_list unavailable \"$v\"\n\t    return 1\n\tfi\n    elif ! is_validator_runnable \"$v\" \"${validators_dir}\"; then\n\tif [ \"${make_error}\" = \"error\" ]; then\n\t    ERROR 1 \"$v (${validators_dir}/validator-$v) is not ready to run\"\n\telse\n\t    update_validator_list unavailable \"$v\"\n\t    return 1\n\tfi\n    fi\n\n    update_validator_list runnable \"$v\"\n    return 0\n}\n\n#\n# Choose a validator suitable for the current context.\n#\n# Return value\n# 0: The caller should run echo'ed validator.\n#\n# 1: The caller should skip the input. It means\n#    - the suitable validator is not listed in VALIDATORS, or\n#    - no expected.tags and no validator file exist.\n#    The caller doesn't have to update any validation counters.\n# 2: The caller should skip the input and update the unavailable\n#    counter.\n#\nresolve_validator ()\n{\n    local validator_file=$1\n    local default_validator=$2\n    local has_expected_tags=$3\n    local validators_dir=$4\n\n    shift 4\n\n    local candidate_validator\n    local local_validator\n\n    if [ -r \"$validator_file\" ]; then\n\tlocal_validator=$(cat \"${validator_file}\" | grep -v '#')\n\tif [ -z \"${local_validator}\" ]; then\n\t    ERROR 1 \"Empty validator specfile: ${local_validator}\"\n\telse\n\t    candidate_validator=${local_validator}\n\tfi\n    elif [ \"$has_expected_tags\" = no ]; then\n\treturn 1\n    else\n\tcandidate_validator=${default_validator}\n    fi\n\n    if [ -z \"${candidate_validator}\" ]; then\n\treturn 2\n    elif [ -z \"${VALIDATORS}\" ] || member_p \"${candidate_validator}\" ${VALIDATORS}; then\n\techo \"${candidate_validator}\"\n\tif validate_validator \"${candidate_validator}\" \"${validators_dir}\" noerror; then\n\t    return 0\n\telse\n\t    return 2\n\tfi\n    else\n\treturn 1\n    fi\n}\n\n#\n# Report the result of validation for INPUT with decoration\n# The validation result counters are updated here.\n#\nvalidate_report_one ()\n{\n    local input=$1\n    local validator=$2\n    local status=$3\n    shift 3\n\n    if [ \"${validator}\" = \"${_NOOP_VALIDATOR}\" ]; then\n\treturn\n    fi\n\n    local i=$(basename $input)\n    local d=$(basename $(dirname $input))\n\n    printf '%-65s' \"$d/$i with ${validator}\"\n    case \"${status}\" in\n\tvalid)\n\t    if [ \"${validator}\" = \"${_KNOWN_INVALIDATION_VALIDATOR}\" ]; then\n\t\tprintf '%b\\n' $(decorate yellow \"known-invalidation\")\n\t\tV_SKIP_KNOWN_INVALIDATION=$(( V_SKIP_KNOWN_INVALIDATION + 1 ))\n\t    else\n\t\tprintf '%b\\n' $(decorate green \"valid\")\n\t\tV_VALID=$(( V_VALID + 1))\n\t    fi\n\t    ;;\n\tinvalid)\n\t    printf '%b\\n' $(decorate red \"invalid\")\n\t    V_INVALID=$(( V_INVALID + 1))\n\t    ;;\n\tunavailable)\n\t    printf '%b\\n' $(decorate yellow \"unavailable\")\n\t    V_SKIP_VALIDATOR_UNAVAILABLE=$(( V_SKIP_VALIDATOR_UNAVAILABLE + 1))\n\t    ;;\n\t*)\n\t    ERROR 1 \"INTERNAL ERROR: wrong validation status: ${status}\"\n\t    ;;\n    esac\n}\n\n#\n# Run a validator for the given input\n#\n# This runs \"validate\" subcommand of the validator.\n#\nvalidate_file ()\n{\n    local input=$1\n    local validator=$2\n    local validators_dir=$3\n    shift 3\n\n    ${validators_dir}/validator-${validator} validate $input ${validators_dir}\n    return $?\n}\n\n#\n# Validate input files under *.[dbtiv].\n#\nvalidate_dir ()\n{\n    local base_dir=$1\n    local default_validator=$2\n    local validators_dir=$3\n    shift 3\n\n    local f\n    local t\n\n    local v0 s0 inputs0\n    local v s inputs\n\n    #\n    # No expected.tags* implies the input is invalid.\n    # We don't have to run any validator as far as no\n    # ./validator explicitly is given.\n    #\n    local has_expected_tags=no\n    for f in \"${base_dir}\"/expected.tags*; do\n\t[ -r \"$f\" ] || continue\n\tfailure_in_globing \"$f\" && continue\n\thas_expected_tags=yes\n\tbreak\n    done\n\n    # A validator specified in ./validator is used for validating ./input.foo.\n    # It will be used for validating ./input[-_]*.foo, too if ./validator[-_]*.\n    # doesn't exit.\n    inputs0=$(for f in \"${base_dir}\"/input.*; do\n\t\t  [ -r \"$f\" ] || continue\n\t\t  failure_in_globing \"$f\" && continue\n\t\t  echo $f\n\t      done | sort)\n    v0=$(resolve_validator \"${base_dir}\"/validator \\\n\t\t\t  \"${default_validator}\" \\\n\t\t\t  \"${has_expected_tags}\" \\\n\t\t\t  \"${validators_dir}\")\n    s0=$?\n\n    case \"$s0\" in\n\t0)\n\t    update_validator_list runnable \"$v0\"\n\t    for f in $inputs0; do\n\t\tif validate_file \"$f\" \"$v0\" \"${validators_dir}\"; then\n\t\t    validate_report_one \"$f\" \"$v0\" valid\n\t\telse\n\t\t    validate_report_one \"$f\" \"$v0\" invalid\n\t\tfi\n\t    done\n\t    default_validator=$v0\n\t    ;;\n\t1)\n\t    # no action needed\n\t    ;;\n\t2)\n\t    update_validator_list unavailable \"$v0\"\n\t    for f in $inputs0; do\n\t\tvalidate_report_one \"$f\" \"$v0\" unavailable\n\t    done\n\t    default_validator=\n\t    ;;\n    esac\n\n    inputs=$(for f in \"${base_dir}\"/input[-_][0-9].* \\\n\t\t      \"${base_dir}\"/input[-_][0-9][-_]*.*; do\n\t\t [ -r \"$f\" ] || continue\n\t\t failure_in_globing \"$f\" && continue\n\t\t echo $f\n\t     done | sort)\n\n    for f in $inputs; do\n\tt=$(basename $f)\n\tt=${t#input}; t=${t%.*}\n\tv=$(resolve_validator \"${base_dir}\"/validator\"$t\" \\\n\t\t\t     \"$default_validator\" \\\n\t\t\t     \"$has_expected_tags\" \\\n\t\t\t     \"$validators_dir\")\n\ts=$?\n\tcase \"$s\" in\n\t    0)\n\t\tupdate_validator_list runnable \"$v0\"\n\t\tif validate_file \"$f\" \"$v\" \"${validators_dir}\"; then\n\t\t    validate_report_one \"$f\" \"$v\" valid\n\t\telse\n\t\t    validate_report_one \"$f\" \"$v\" invalid\n\t\tfi\n\t\t;;\n\t    1)\n\t\t# no action needed\n\t\t;;\n\t    2)\n\t\tupdate_validator_list unavailable \"$v0\"\n\t\tvalidate_report_one \"$f\" \"$v\" unavailable\n\t\t;;\n\tesac\n    done\n}\n\n#\n# Validate input files under *.r.\n#\nvalidate_category ()\n{\n    local category=$1\n    local base_dir=$2\n    local validators_dir=$3\n    shift 3\n\n    local d\n    local default_validator=${_NOOP_VALIDATOR}\n\n    #\n    # Filtered by CATEGORIES\n    #\n    if [ -n \"$CATEGORIES\" ] && ! member_p \"${category}\" $CATEGORIES; then\n\treturn 1\n    fi\n    echo\n    echo \"Category: ${category}\"\n    line\n\n    if [ -r \"${base_dir}/validator\" ]; then\n\tdefault_validator=$(cat \"${base_dir}/validator\" | grep -v '#')\n\tif [ -z \"${default_validator}\" ]; then\n\t    ERROR 1 \"Empty validator specfile (in ${base_dir}/validator)\"\n\tfi\n\n\tvalidate_validator \"${default_validator}\" \"${validators_dir}\" noerror\n    fi\n\n    for d in \"${base_dir}\"/*.[dbtiv]; do\n\t[ -d \"$d\" ] || continue\n\tvalidate_dir \"$d\" \"${default_validator}\" \"${validators_dir}\"\n    done\n}\n\n#\n# Report the summary of validations\n#\nvalidate_summary ()\n{\n    echo\n    echo \"Summary\"\n    line\n\n    printf '  %-40s' \"#valid:\"\n    printf '%b\\n' $(decorate green \"${V_VALID}\")\n\n    printf '  %-40s' \"#invalid:\"\n    if [ \"${V_INVALID}\" = 0 ]; then\n\techo \"${V_INVALID}\"\n    else\n\tprintf '%b\\n' $(decorate red \"${V_INVALID}\")\n    fi\n\n    printf '  %-40s' \"#skipped (known invalidation)\"\n    if [ \"${V_SKIP_KNOWN_INVALIDATION}\" = 0 ]; then\n\techo 0\n    else\n\tprintf '%b\\n' $(decorate yellow \"${V_SKIP_KNOWN_INVALIDATION}\")\n    fi\n\n    printf '  %-40s' \"#skipped (validator unavailable)\"\n    if [ \"${V_SKIP_VALIDATOR_UNAVAILABLE}\" = 0 ]; then\n\techo 0\n    else\n\tlocal u\n\tprintf '%b\\n' $(decorate yellow \"${V_SKIP_VALIDATOR_UNAVAILABLE}\")\n\n\techo\n\techo \"Unavailable validators\"\n\tline\n\tfor u in ${_UNAVAILABLE_VALIDATORS}; do\n\t    echo \"\t$u\"\n\tdone\n    fi\n\n    if [ \"${V_INVALID}\" = 0 ]; then\n\treturn 0\n    else\n\treturn \"${_VALIDATION_EXIT_INVALID}\"\n    fi\n}\n\naction_validate_input ()\n{\n    local action=$1\n    shift\n\n    local units_dir\n    local validators_dir\n    local validators\n\n    local v\n    local d\n\n    while [ $# -gt 0 ]; do\n\tcase $1 in\n\t    --validators)\n\t\tshift\n\t\tvalidators=$1\n\t\tshift\n\t\t;;\n\t    --validators=*)\n\t\tvalidators=${1#--validators=}\n\t\tshift\n\t\t;;\n\t    --colorized-output)\n\t\tshift\n\t\tCOLORIZED_OUTPUT=$1\n\t\tshift\n\t\t;;\n\t    --colorized-output=*)\n\t\tCOLORIZED_OUTPUT=${1#--colorized-output=}\n\t\tshift\n\t\t;;\n\t    --categories)\n\t\tshift\n\t\tfor c in $(echo \"$1\" | tr ',' ' '); do\n\t\t    if [ \"$c\" = \"ROOT\" ]; then\n\t\t\tCATEGORIES=\"$CATEGORIES ROOT\"\n\t\t    else\n\t\t\tCATEGORIES=\"$CATEGORIES ${c%.r}.r\"\n\t\t    fi\n\t\tdone\n\t\tshift\n\t\t;;\n\t    --categories=*)\n\t\tfor c in $(echo \"${1#--categories=}\" | tr ',' ' '); do\n\t\t    if [ \"$c\" = \"ROOT\" ]; then\n\t\t\tCATEGORIES=\"$CATEGORIES ROOT\"\n\t\t    else\n\t\t\tCATEGORIES=\"$CATEGORIES ${c%.r}.r\"\n\t\t    fi\n\t\tdone\n\t\tshift\n\t\t;;\n\t    -*)\n\t\tERROR 1 \"unknown option \\\"${1}\\\" for ${action} action\"\n\t\t;;\n\t    *)\n\t\tunits_dir=$1\n\t\tshift\n\t\tvalidators_dir=$1\n\t\tshift\n\t\tbreak;\n\t\t;;\n\tesac\n    done\n\n    if [ $# -gt 0 ]; then\n\tERROR 1 \"too many arguments for ${action} action: $*\"\n    elif [ -z \"${units_dir}\" ]; then\n\tERROR 1 \"UNITS_DIR parameter is not given in ${action} action\"\n    elif [ -z \"${validators_dir}\" ]; then\n\tERROR 1 \"VALIDATORS_DIR parameter is not given in ${action} action\"\n    fi\n\n    if ! [ -d \"${units_dir}\" ]; then\n\tERROR 1 \"No such directory: ${units_dir}\"\n    elif ! [ -d \"${validators_dir}\" ]; then\n\tERROR 1 \"No such directory: ${units_dir}\"\n    fi\n\n    if ! ( [ \"${COLORIZED_OUTPUT}\" = 'yes' ] || [ \"${COLORIZED_OUTPUT}\" = 'no' ] ); then\n\tERROR 1 \"unexpected option argument for --colorized-output: ${COLORIZED_OUTPUT}\"\n    fi\n\n    if [ -n \"${validators}\" ]; then\n\tVALIDATORS=$(echo \"${validators}\" | tr ',' ' ')\n\tfor v in ${VALIDATORS}; do\n\t    validate_validator \"$v\" \"${validators_dir}\" error\n\tdone\n    fi\n\n    for d in ${units_dir}/*.r; do\n\t[ -d \"$d\" ] || continue\n\tcategory=${d##*/}\n\tvalidate_category \"${category}\" \"$d\" \"${validators_dir}\"\n    done\n\n    echo\n    echo \"Category: ${_DEFAULT_CATEGORY}\"\n    line\n    for d in ${units_dir}/*.[dbtiv]; do\n\t[ -d \"$d\" ] || continue\n\tvalidate_dir \"$d\" \"${_NOOP_VALIDATOR}\" \"$validators_dir\"\n    done\n\n    validate_summary\n    return $?\n}\n\n# * Avoid issues between sed and the locale settings by overriding it using\n#   LC_ALL, which takes precedence over all other locale configurations:\n#   https://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html\n#\n# * Avoid unexpected pathname conversion on MSYS2.\n#   https://github.com/msys2/msys2/wiki/Porting#filesystem-namespaces\nprepare_environment ()\n{\n    _PREPERE_ENV=$(cat <<'EOF'\nLC_ALL=\"C\"; export LC_ALL\nMSYS2_ARG_CONV_EXCL='--regex-;--_scopesep' export MSYS2_ARG_CONV_EXCL\nEOF\n)\n    eval ${_PREPERE_ENV}\n}\n\nmain ()\n{\n    if [ $# = 0 ]; then\n\taction_help 1>&2\n\texit 1\n    fi\n\n    case $1 in\n\thelp|-h|--help)\n\t    action_help\n\t    return 0\n\t    ;;\n\trun)\n\t    action_run \"$@\"\n\t    return $?\n\t    ;;\n\tclean)\n\t    action_clean \"$@\"\n\t    return $?\n\t    ;;\n\tfuzz)\n\t    action_fuzz \"$@\"\n\t    return $?\n\t    ;;\n\tnoise)\n\t    action_noise \"$@\"\n\t    return $?\n\t    ;;\n\ttmain)\n\t    action_tmain \"$@\"\n\t    return $?\n\t    ;;\n\tclean-tmain)\n\t    action_clean_tmain \"$@\"\n\t    return $?\n\t    ;;\n\tshrink)\n\t    action_shrink \"$@\"\n\t    return $?\n\t    ;;\n\tchop)\n\t    action_chop \"$@\"\n\t    return $?\n\t    ;;\n\tslap)\n\t    action_chop \"$@\"\n\t    return $?\n\t    ;;\n\tvalidate-input)\n\t    action_validate_input \"$@\"\n\t    return $?\n\t    ;;\n\t*)\n\t    ERROR 1 \"unknown action: $1\"\n\t    ;;\n    esac\n}\n\nprepare_environment\nmain \"$@\"\nexit $?\n"
  },
  {
    "path": "misc/units.py",
    "content": "#!/usr/bin/env python3\n\n#\n# units.py - Units test harness for ctags\n#\n# Copyright (C) 2019 Ken Takata\n# (Based on \"units\" written by Masatake YAMATO.)\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#\n# Python 3.5 or later is required.\n# On Windows, unix-like shell (e.g. bash) and some unix tools (sed,\n# diff, etc.) are needed.\n#\n\nimport time     # for debugging\nimport argparse\nimport filecmp\nimport glob\nimport io\nimport os\nimport platform\nimport queue\nimport re\nimport shutil\nimport stat\nimport subprocess\nimport sys\nimport threading\n\n#\n# Global Parameters\n#\nSHELL = '/bin/sh'\nCTAGS = './ctags'\nREADTAGS = './readtags'\nOPTSCRIPT = './optscript'\nWITH_TIMEOUT = 0\nWITH_VALGRIND = False\nCOLORIZED_OUTPUT = True\nCATEGORIES = []\nUNITS = []\nLANGUAGES = []\nPRETENSE_OPTS = ''\nRUN_SHRINK = False\nSHOW_DIFF_OUTPUT = False\nNUM_WORKER_THREADS = 4\nDIFF_U_NUM = 0\n\n#\n# Internal variables and constants\n#\n_FEATURE_LIST = []\n_PREPERE_ENV = ''\n_DEFAULT_CATEGORY = 'ROOT'\n_TIMEOUT_EXIT = 124\n_VG_TIMEOUT_FACTOR = 10\n_VALGRIND_EXIT = 58\n_STDERR_OUTPUT_NAME = 'STDERR.tmp'\n_DIFF_OUTPUT_NAME = 'DIFF.tmp'\n_VALGRIND_OUTPUT_NAME = 'VALGRIND.tmp'\n\n#\n# Results\n#\nL_PASSED = []\nL_FIXED = []\nL_FAILED_BY_STATUS = []\nL_FAILED_BY_DIFF = []\nL_SKIPPED_BY_FEATURES = []\nL_SKIPPED_BY_LANGUAGES = []\nL_SKIPPED_BY_ILOOP = []\nL_KNOWN_BUGS = []\nL_FAILED_BY_TIMEED_OUT = []\nL_BROKEN_ARGS_CTAGS = []\nL_VALGRIND = []\nTMAIN_STATUS = True\nTMAIN_FAILED = []\n\ndef remove_prefix(string, prefix):\n    if string.startswith(prefix):\n        return string[len(prefix):]\n    else:\n        return string\n\ndef is_cygwin():\n    system = platform.system()\n    return system.startswith('CYGWIN_NT') or system.startswith('MINGW32_NT')\n\ndef isabs(path):\n    if is_cygwin():\n        import ntpath\n        if ntpath.isabs(path):\n            return True\n    return os.path.isabs(path)\n\ndef action_help(parser, action, *args):\n    parser.print_help()\n    return 0\n\ndef error_exit(status, msg):\n    print(msg, file=sys.stderr)\n    sys.exit(status)\n\ndef line(*args, file=sys.stdout):\n    if len(args) > 0:\n        ch = args[0]\n    else:\n        ch = '-'\n    print(ch * 60, file=file)\n\ndef remove_readonly(func, path, _):\n    # Clear the readonly bit and reattempt the removal\n    os.chmod(path, stat.S_IWRITE | stat.S_IREAD)\n    dname = os.path.dirname(path)\n    os.chmod(dname, os.stat(dname).st_mode | stat.S_IWRITE)\n    func(path)\n\ndef clean_bundles(bundles):\n    if not os.path.isfile(bundles):\n        return\n    with open(bundles, 'r') as f:\n        for fn in f.read().splitlines():\n            if os.path.isdir(fn):\n                shutil.rmtree(fn, onerror=remove_readonly)\n            elif os.path.isfile(fn):\n                os.remove(fn)\n    os.remove(bundles)\n\ndef clean_tcase(d, bundles):\n    if os.path.isdir(d):\n        clean_bundles(bundles)\n        for fn in glob.glob(d + '/*.tmp'):\n            os.remove(fn)\n        for fn in glob.glob(d + '/*.TMP'):\n            os.remove(fn)\n\ndef check_availability(cmd):\n    if not shutil.which(cmd):\n        error_exit(1, cmd + ' command is not available')\n\ndef check_units(name, category):\n    if len(UNITS) == 0:\n        return True\n\n    for u in UNITS:\n        ret = re.match(r'(.+)/(.+)', u)\n        if ret:\n            if ret.group(1, 2) == (category, name):\n                return True\n        elif u == name:\n            return True\n    return False\n\ndef init_features():\n    global _FEATURE_LIST\n    ret = subprocess.run([CTAGS, '--quiet', '--options=NONE', '--list-features', '--with-list=no'],\n            stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\n    _FEATURE_LIST = re.sub(r'(?m)^([^ ]+).*$', r'\\1',\n            ret.stdout.decode('utf-8')).splitlines()\n\ndef check_features(feature, ffile):\n    features = []\n    if feature:\n        features = [feature]\n    elif os.path.isfile(ffile):\n        with open(ffile, 'r') as f:\n            features = f.read().splitlines()\n\n    for expected in features:\n        if expected == '':\n            continue\n        found = False\n        found_unexpectedly = False\n        if expected[0] == '!':\n            if expected[1:] in _FEATURE_LIST:\n                found_unexpectedly = True\n        else:\n            if expected in _FEATURE_LIST:\n                found = True\n        if found_unexpectedly:\n            return (False, expected)\n        elif not found:\n            return (False, expected)\n    return (True, '')\n\ndef check_languages(cmdline, lfile):\n    if not os.path.isfile(lfile):\n        return (True, '')\n\n    ret = subprocess.run(cmdline + ['--list-languages'],\n            stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\n    langs = ret.stdout.decode('utf-8').splitlines()\n\n    with open(lfile, 'r') as f:\n        for expected in f.read().splitlines():\n            found = False\n            if expected in langs:\n                found = True\n            if not found:\n                return (False, expected)\n    return (True, '')\n\ndef decorate(decorator, msg, colorized):\n    if decorator == 'red':\n        num = '31'\n    elif decorator == 'green':\n        num = '32'\n    elif decorator == 'yellow':\n        num = '33'\n    else:\n        error_exit(1, 'INTERNAL ERROR: wrong run_result function')\n\n    if colorized:\n        return \"\\x1b[\" + num + 'm' + msg + \"\\x1b[m\"\n    else:\n        return msg\n\ndef run_result(result_type, msg, output, *args, file=sys.stdout):\n    func_dict = {\n            'skip': run_result_skip,\n            'internal-error': run_result_internal_error,\n            'error': run_result_error,\n            'ok': run_result_ok,\n            'known_error': run_result_known_error,\n            }\n\n    func_dict[result_type](msg, file, COLORIZED_OUTPUT, *args)\n    file.flush()\n    if output:\n        with open(output, 'w') as f:\n            func_dict[result_type](msg, f, False, *args)\n\ndef run_result_skip(msg, f, colorized, *args):\n    s = msg + decorate('yellow', 'skipped', colorized)\n    if len(args) > 0:\n        s += ' (' + args[0] + ')'\n    print(s, file=f)\n\ndef run_result_internal_error(msg, f, colorized, *args):\n    s = msg + decorate('red', 'INTERNAL-ERROR', colorized)\n    if len(args) > 0:\n        s += ' (' + args[0] + ')'\n    print(s, file=f)\n\ndef run_result_error(msg, f, colorized, *args):\n    s = msg + decorate('red', 'failed', colorized)\n    if len(args) > 0:\n        s += ' (' + args[0] + ')'\n    print(s, file=f)\n\ndef run_result_ok(msg, f, colorized, *args):\n    s = msg + decorate('green', 'passed', colorized)\n    if len(args) > 0:\n        s += ' (' + args[0] + ')'\n    print(s, file=f)\n\ndef run_result_known_error(msg, f, colorized, *args):\n    s = msg + decorate('yellow', 'failed', colorized) + ' (KNOWN bug)'\n    print(s, file=f)\n\ndef run_shrink(cmdline_template, finput, foutput, lang):\n    script = sys.argv[0]\n    script = os.path.splitext(script)[0]   # remove '.py'\n\n    print('Shrinking ' + finput + ' as ' + lang)\n    # fallback to the shell script version\n    subprocess.run([SHELL, script, 'shrink',\n        '--timeout=1', '--foreground',\n        cmdline_template, finput, foutput])\n\n# return a filter for normalizing the basename\n#\n# If internal is True, return a pair of [pattern, replacement],\n# otherwise return a list of command line arguments.\ndef basename_filter(internal, output_type):\n    filters_external = {\n            'ctags': r's%\\(^[^\\t]\\{1,\\}\\t\\)\\(/\\{0,1\\}\\([^/\\t]\\{1,\\}/\\)*\\)%\\\\1%',\n            # \"input\" in the expresion is for finding input file names in the TAGS file.\n            # RAWOUT.tmp:\n            #\n            #   ./Units/parser-ada.r/ada-etags-suffix.d/input_0.adb,238\n            #   package body Input_0 is   ^?Input_0/b^A1,0\n            #\n            # With the original expression, both \"./Units/parser-ada.r/ada-etags-suffix.d/\"\n            # and \"package body Input_0 is   Input_0/' are deleted.\n            # FILTERED.tmp:\n            #\n            # input_0.adb,238\n            # b^A1,0\n            #\n            # Adding \"input\" ot the expression is for deleting only the former one and for\n            # skpping the later one.\n            #\n            # FIXME: if \"input\" is included as a substring of tag entry names, filtering\n            # with this expression makes the test fail.\n            'etags': r's%.*\\/\\(input[-._][[:print:]]\\{1,\\}\\),\\([0-9]\\{1,\\}$\\)%\\\\1,\\\\2%',\n            'xref': r's%\\(.*[[:digit:]]\\{1,\\} \\)\\([^ ]\\{1,\\}[^ ]\\{1,\\}\\)/\\([^ ].\\{1,\\}.\\{1,\\}$\\)%\\\\1\\\\3%',\n            'json': r's%\\(\"path\": \\)\"[^\"]\\{1,\\}/\\([^/\"]\\{1,\\}\\)\"%\\\\1\"\\\\2\"%',\n            }\n    filters_internal = {\n            'ctags': [r'(^[^\\t]+\\t)(/?([^/\\t]+/)*)', r'\\1'],\n            # See above comments about \"input\".\n            'etags': [r'.*/(input[-._]\\S+),([0-9]+$)', r'\\1,\\2'],\n            'xref': [r'(.*\\d+ )([^ ]+[^ ]+)/([^ ].+.+$)', r'\\1\\3'],\n            'json': [r'(\"path\": )\"[^\"]+/([^/\"]+)\"', r'\\1\"\\2\"'],\n            }\n    if internal:\n        return filters_internal[output_type]\n    else:\n        return ['sed', '-e', filters_external[output_type]]\n\n# convert a command line list to a command line string\ndef join_cmdline(cmdline):\n    # surround with '' if an argument includes spaces or '\\'\n    # TODO: use more robust way\n    return ' '.join(\"'\" + x + \"'\" if (' ' in x) or ('\\\\' in x) else x\n        for x in cmdline)\n\ndef run_record_cmdline(cmdline, ffilter, ocmdline, output_type):\n    with open(ocmdline, 'w') as f:\n        print(\"%s\\n%s \\\\\\n| %s \\\\\\n| %s\\n\" % (\n            _PREPERE_ENV,\n            join_cmdline(cmdline),\n            join_cmdline(basename_filter(False, output_type)),\n            ffilter), file=f)\n\ndef prepare_bundles(frm, to, obundles):\n    for src in glob.glob(frm + '/*'):\n        fn = os.path.basename(src)\n        if fn.startswith('input.'):\n            continue\n        elif fn.startswith('expected.tags'):\n            continue\n        elif fn.startswith('README'):\n            continue\n        elif fn in ['features', 'languages', 'filters']:\n            continue\n        elif fn == 'args.ctags':\n            continue\n        else:\n            dist = to + '/' + fn\n            if os.path.isdir(src):\n                shutil.copytree(src, dist, copy_function=shutil.copyfile)\n            else:\n                shutil.copyfile(src, dist)\n            with open(obundles, 'a') as f:\n                print(dist, file=f)\n\ndef anon_normalize_sub(internal, ctags, input_actual, *args):\n    # TODO: \"Units\" should not be hardcoded.\n    input_expected = './Units' + re.sub(r'^.*?/Units', r'', input_actual, count=1)\n\n    ret = subprocess.run([CTAGS, '--quiet', '--options=NONE', '--_anonhash=' + input_actual],\n            stdout=subprocess.PIPE)\n    actual = ret.stdout.decode('utf-8').splitlines()[0]\n    ret = subprocess.run([CTAGS, '--quiet', '--options=NONE', '--_anonhash=' + input_expected],\n            stdout=subprocess.PIPE)\n    expected = ret.stdout.decode('utf-8').splitlines()[0]\n\n    if internal:\n        retlist = [[actual, expected]]\n    else:\n        retlist = ['-e', 's/' + actual + '/' + expected + '/g']\n    if len(args) > 0:\n        return retlist + anon_normalize_sub(internal, ctags, *args)\n    else:\n        return retlist\n\ndef is_anon_normalize_needed(rawout):\n    with open(rawout, 'r', errors='ignore') as f:\n        if re.search(r'[0-9a-f]{8}', f.read()):\n            return True\n    return False\n\n# return a list of filters for normalizing anonhash\n#\n# If internal is True, return a list of pairs of [pattern, replacement],\n# otherwise return a list of command line arguments.\ndef anon_normalize(internal, rawout, ctags, input_actual, *args):\n    if is_anon_normalize_needed(rawout):\n        return anon_normalize_sub(internal, ctags, input_actual, *args)\n    else:\n        return []\n\ndef run_filter(finput, foutput, base_filter, anon_filters):\n    pat1 = [re.compile(base_filter[0]), base_filter[1]]\n    pat2 = [(re.compile(p[0]), p[1]) for p in anon_filters]\n    with open(finput, 'r', errors='surrogateescape') as fin, \\\n            open(foutput, 'w', errors='surrogateescape', newline='\\n') as fout:\n        for l in fin:\n            l = pat1[0].sub(pat1[1], l, 1)\n            for p in pat2:\n                l = p[0].sub(p[1], l)\n            print(l, end='', file=fout)\n\ndef guess_lang(cmdline, finput):\n    ret = subprocess.run(cmdline + ['--print-language', finput],\n            stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\n    return re.sub(r'^.*: ', r'',\n            ret.stdout.decode('utf-8').replace(\"\\r\\n\", \"\\n\").replace(\"\\n\", ''))\n\ndef guess_lang_from_log(log):\n    with open(log, 'r', encoding='utf-8', errors='ignore') as f:\n        for l in f:\n            ret = re.match('OPENING.* as (.*) language .*file ', l)\n            if ret:\n                return ret.group(1)\n    return ''\n\ndef run_tcase(finput, t, name, tclass, category, build_t, extra_inputs):\n    global L_PASSED\n    global L_FIXED\n    global L_FAILED_BY_STATUS\n    global L_FAILED_BY_DIFF\n    global L_SKIPPED_BY_FEATURES\n    global L_SKIPPED_BY_LANGUAGES\n    global L_SKIPPED_BY_ILOOP\n    global L_KNOWN_BUGS\n    global L_FAILED_BY_TIMEED_OUT\n    global L_BROKEN_ARGS_CTAGS\n    global L_VALGRIND\n\n    o = build_t\n\n    fargs = t + '/args.ctags'\n    ffeatures = t + '/features'\n    flanguages = t + '/languages'\n    ffilter = t + '/filter'\n\n    fexpected = t + '/expected.tags'\n    output_type = 'ctags'\n    output_label = ''\n    output_tflag = []\n    output_feature = ''\n    output_lang_extras = ''\n\n    if os.path.isfile(fexpected):\n        pass\n    elif os.path.isfile(t + '/expected.tags-e'):\n        fexpected = t + '/expected.tags-e'\n        output_type = 'etags'\n        output_label = '/' + output_type\n        output_tflag = ['-e', '--tag-relative=no']\n    elif os.path.isfile(t + '/expected.tags-x'):\n        fexpected = t + '/expected.tags-x'\n        output_type = 'xref'\n        output_label = '/' + output_type\n        output_tflag = ['-x']\n    elif os.path.isfile(t + '/expected.tags-json'):\n        fexpected = t + '/expected.tags-json'\n        output_type = 'json'\n        output_label = '/' + output_type\n        output_tflag = ['--output-format=json']\n        output_feature = 'json'\n\n    if len(extra_inputs) > 0:\n        output_lang_extras = ' (multi inputs)'\n\n    if not shutil.which(ffilter):\n        if os.name == 'nt':\n            if not os.path.isfile(ffilter):\n                ffilter = 'cat'\n        else:\n            ffilter = 'cat'\n\n    ostderr = o + '/' + _STDERR_OUTPUT_NAME\n    orawout = o + '/RAWOUT.tmp'\n    ofiltered = o + '/FILTERED.tmp'\n    odiff = o + '/' + _DIFF_OUTPUT_NAME\n    ocmdline = o + '/CMDLINE.tmp'\n    ovalgrind = o + '/' + _VALGRIND_OUTPUT_NAME\n    oresult = o + '/RESULT.tmp'\n    oshrink_template = o + '/SHRINK-%s.tmp'\n    obundles = o + '/BUNDLES'\n\n    broken_args_ctags = False\n\n    #\n    # Filtered by UNIT\n    #\n    if not check_units(name, category):\n        return False\n\n    #\n    # Build cmdline\n    #\n    cmdline = [CTAGS, '--verbose', '--options=NONE', '--fields=-T']\n    if PRETENSE_OPTS != '':\n        cmdline += [PRETENSE_OPTS]\n    cmdline += ['--optlib-dir=+' + t + '/optlib', '-o', '-']\n    if os.path.isfile(fargs):\n        cmdline += ['--options=' + fargs]\n        ret = subprocess.run(cmdline + ['--_force-quit=0'],\n                stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n        if ret.returncode != 0:\n            broken_args_ctags = True\n\n    #\n    # make a backup (basedcmdline) of cmdline.  basedcmdline is used\n    # as a command line template for running shrinker.  basedcmdline\n    # should not include the name of the input file name.  The\n    # shrinker makes a another cmdline by applying a real input file\n    # name to the template.  On the other hand, cmdline is\n    # destructively updated by appending input file name in this\n    # function. The file name should not be included in the cmdline\n    # template.\n    #\n    # To avoid the updating in this function propagating to\n    # basecmdline, we copy the cmdline here.\n    #\n    basecmdline = cmdline[:]\n\n    #\n    # Filtered by LANGUAGES\n    #\n    guessed_lang = None\n    if len(LANGUAGES) > 0:\n        guessed_lang = guess_lang(basecmdline, finput)\n        # If the args.ctags is broken, ctags cannot guess the language.\n        # In that case, we don't skip this test case.\n        # So we can raise an error.\n        if not broken_args_ctags \\\n           and not guessed_lang in LANGUAGES:\n            return False\n\n    clean_tcase(o, obundles)\n    os.makedirs(o, exist_ok=True)\n    if not os.path.samefile(o, t):\n        prepare_bundles(t, o, obundles)\n\n\n    # helper function for building some strings based on guessed_lang\n    def build_strings(guessed_lang):\n        return ('%-59s ' % ('Testing ' + name + ' as ' + guessed_lang + output_lang_extras + output_label),\n                join_cmdline(basecmdline) + ' --language-force=' + guessed_lang + ' %s > /dev/null 2>&1',\n                oshrink_template % (guessed_lang.replace('/', '-')))\n\n    (tmp, feat) = check_features(output_feature, ffeatures)\n    if not tmp:\n        if not guessed_lang:\n            guessed_lang = guess_lang(basecmdline, finput)\n        msg = build_strings(guessed_lang)[0]\n        L_SKIPPED_BY_FEATURES += [category + '/' + name]\n        if feat.startswith('!'):\n            run_result('skip', msg, oresult, 'unwanted feature \"' + feat[1:] + '\" is available')\n        else:\n            run_result('skip', msg, oresult, 'required feature \"' + feat + '\" is not available')\n        return False\n    (tmp, lang) = check_languages(basecmdline, flanguages)\n    if not tmp:\n        if not guessed_lang:\n            guessed_lang = guess_lang(basecmdline, finput)\n        msg = build_strings(guessed_lang)[0]\n        L_SKIPPED_BY_LANGUAGES += [category + '/' + name]\n        run_result('skip', msg, oresult, 'required language parser \"' + lang + '\" is not available')\n        return False\n    if WITH_TIMEOUT == 0 and tclass == 'i':\n        if not guessed_lang:\n            guessed_lang = guess_lang(basecmdline, finput)\n        msg = build_strings(guessed_lang)[0]\n        L_SKIPPED_BY_ILOOP += [category + '/' + name]\n        run_result('skip', msg, oresult, 'may cause an infinite loop')\n        return False\n    if broken_args_ctags:\n        if not guessed_lang:\n            guessed_lang = guess_lang(basecmdline, finput)\n        msg = build_strings(guessed_lang)[0]\n        L_BROKEN_ARGS_CTAGS += [category + '/' + name]\n        run_result('error', msg, None, 'broken args.ctags?')\n        return False\n\n    cmdline += output_tflag + [finput]\n    if len(extra_inputs) > 0:\n        cmdline += extra_inputs\n\n    timeout_value = WITH_TIMEOUT\n    if WITH_VALGRIND:\n        cmdline = ['valgrind', '--leak-check=full', '--track-origins=yes',\n                   '--error-exitcode=' + str(_VALGRIND_EXIT), '--log-file=' + ovalgrind] + cmdline\n        timeout_value *= _VG_TIMEOUT_FACTOR\n    if timeout_value == 0:\n        timeout_value = None\n\n    start = time.time()\n    try:\n        with open(orawout, 'wb') as fo, \\\n                open(ostderr, 'wb') as fe:\n            ret = subprocess.run(cmdline, stdout=fo, stderr=fe,\n                    timeout=timeout_value)\n        run_record_cmdline(cmdline, ffilter, ocmdline, output_type)\n    except subprocess.TimeoutExpired:\n        if not guessed_lang:\n            guessed_lang = guess_lang(basecmdline, finput)\n        (msg, cmdline_template, oshrink) = build_strings(guessed_lang)\n        L_FAILED_BY_TIMEED_OUT += [category + '/' + name]\n        run_result('error', msg, oresult, 'TIMED OUT')\n        run_record_cmdline(cmdline, ffilter, ocmdline, output_type)\n        if RUN_SHRINK and len(extra_inputs) == 0:\n            run_shrink(cmdline_template, finput, oshrink, guessed_lang)\n        return False\n    #print('execute time: %f' % (time.time() - start))\n\n    guessed_lang = guess_lang_from_log(ostderr)\n    (msg, cmdline_template, oshrink) = build_strings(guessed_lang)\n\n    if ret.returncode != 0:\n        if WITH_VALGRIND and ret.returncode == _VALGRIND_EXIT and \\\n                tclass != 'v':\n            L_VALGRIND += [category + '/' + name]\n            run_result('error', msg, oresult, 'valgrind-error')\n            run_record_cmdline(cmdline, ffilter, ocmdline, output_type)\n            return False\n        elif tclass == 'b':\n            L_KNOWN_BUGS += [category + '/' + name]\n            run_result('known_error', msg, oresult)\n            run_record_cmdline(cmdline, ffilter, ocmdline, output_type)\n            if RUN_SHRINK and len(extra_inputs) == 0:\n                run_shrink(cmdline_template, finput, oshrink, guessed_lang)\n            return True\n        else:\n            L_FAILED_BY_STATUS += [category + '/' + name]\n            run_result('error', msg, oresult, 'unexpected exit status: ' + str(ret.returncode))\n            run_record_cmdline(cmdline, ffilter, ocmdline, output_type)\n            if RUN_SHRINK and len(extra_inputs) == 0:\n                run_shrink(cmdline_template, finput, oshrink, guessed_lang)\n            return False\n    elif WITH_VALGRIND and tclass == 'v':\n        L_FIXED += [category + '/' + name]\n\n    if not os.path.isfile(fexpected):\n        clean_tcase(o, obundles)\n        if tclass == 'b':\n            L_FIXED += [category + '/' + name]\n        elif tclass == 'i':\n            L_FIXED += [category + '/' + name]\n\n        L_PASSED += [category + '/' + name]\n        run_result('ok', msg, None, '\"expected.tags*\" not found')\n        return True\n\n    start = time.time()\n    if ffilter != 'cat':\n        # Use external filter\n        filter_cmd = basename_filter(False, output_type) + \\\n                anon_normalize(False, orawout, CTAGS, finput, *extra_inputs) + \\\n                ['<', orawout]\n        filter_cmd += ['|', ffilter]\n        filter_cmd += ['>', ofiltered]\n        #print(filter_cmd)\n        subprocess.run([SHELL, '-c', join_cmdline(filter_cmd)])\n    else:\n        # Use internal filter\n        run_filter(orawout, ofiltered, basename_filter(True, output_type),\n                anon_normalize(True, orawout, CTAGS, finput, *extra_inputs))\n    #print('filter time: %f' % (time.time() - start))\n\n    start = time.time()\n    if filecmp.cmp(fexpected, ofiltered):\n        ret.returncode = 0\n    else:\n        with open(odiff, 'wb') as f:\n            ret = subprocess.run(['diff', '-U', str(DIFF_U_NUM),\n                '-I', '^!_TAG', '--strip-trailing-cr', fexpected, ofiltered],\n                stdout=f)\n    #print('diff time: %f' % (time.time() - start))\n\n    if ret.returncode == 0:\n        clean_tcase(o, obundles)\n        if tclass == 'b':\n            L_FIXED += [category + '/' + name]\n        elif WITH_TIMEOUT != 0 and tclass == 'i':\n            L_FIXED += [category + '/' + name]\n\n        L_PASSED += [category + '/' + name]\n        run_result('ok', msg, None)\n        return True\n    else:\n        if tclass == 'b':\n            L_KNOWN_BUGS += [category + '/' + name]\n            run_result('known_error', msg, oresult)\n            run_record_cmdline(cmdline, ffilter, ocmdline, output_type)\n            return True\n        else:\n            L_FAILED_BY_DIFF += [category + '/' + name]\n            run_result('error', msg, oresult, 'unexpected output')\n            run_record_cmdline(cmdline, ffilter, ocmdline, output_type)\n            return False\n\ndef create_thread_queue(func):\n    q = queue.Queue()\n    threads = []\n    for i in range(NUM_WORKER_THREADS):\n        t = threading.Thread(target=worker, args=(func, q), daemon=True)\n        t.start()\n        threads.append(t)\n    return (q, threads)\n\ndef worker(func, q):\n    while True:\n        item = q.get()\n        if item is None:\n            break\n        try:\n            func(*item)\n        except:\n            import traceback\n            traceback.print_exc()\n        q.task_done()\n\ndef join_workers(q, threads):\n    # block until all tasks are done\n    try:\n        q.join()\n    except KeyboardInterrupt:\n        # empty the queue\n        while True:\n            try:\n                q.get_nowait()\n            except queue.Empty:\n                break\n        # try to stop workers\n        for i in range(NUM_WORKER_THREADS):\n            q.put(None)\n        for t in threads:\n            t.join(timeout=2)\n        # exit regardless that workers are stopped\n        sys.exit(1)\n\n    # stop workers\n    for i in range(NUM_WORKER_THREADS):\n        q.put(None)\n    for t in threads:\n        t.join()\n\ndef accepted_file(fname):\n    # Ignore backup files\n    return not fname.endswith('~')\n\ndef run_dir(category, base_dir, build_base_dir):\n    #\n    # Filtered by CATEGORIES\n    #\n    if len(CATEGORIES) > 0 and not category in CATEGORIES:\n        return False\n\n    print(\"\\nCategory: \" + category)\n    line()\n\n    (q, threads) = create_thread_queue(run_tcase)\n\n    for finput in glob.glob(base_dir + '/*.[dbtiv]/input.*'):\n        finput = finput.replace('\\\\', '/')  # for Windows\n        if not accepted_file(finput):\n            continue\n\n        dname = os.path.dirname(finput)\n        extra_inputs = sorted(map(lambda x: x.replace('\\\\', '/'), # for Windows\n            filter(accepted_file,\n                glob.glob(dname + '/input[-_][0-9].*') +\n                glob.glob(dname + '/input[-_][0-9][-_]*.*')\n            )))\n\n        tcase_dir = dname\n        build_tcase_dir = build_base_dir + remove_prefix(tcase_dir, base_dir)\n        ret = re.match(r'^.*/(.*)\\.([dbtiv])$', tcase_dir)\n        (name, tclass) = ret.group(1, 2)\n        q.put((finput, tcase_dir, name, tclass, category, build_tcase_dir, extra_inputs))\n\n    join_workers(q, threads)\n\ndef run_show_diff_output(units_dir, t):\n    print(\"\\t\", end='')\n    line('.')\n    for fn in glob.glob(units_dir + '/' + t + '.*/' + _DIFF_OUTPUT_NAME):\n        with open(fn, 'r') as f:\n            for l in f:\n                print(\"\\t\" + l, end='')\n    print()\n\ndef run_show_stderr_output(units_dir, t):\n    print(\"\\t\", end='')\n    line('.')\n    for fn in glob.glob(units_dir + '/' + t + '.*/' + _STDERR_OUTPUT_NAME):\n        with open(fn, 'r') as f:\n            lines = f.readlines()\n            for l in lines[-50:]:\n                print(\"\\t\" + l, end='')\n    print()\n\ndef run_show_valgrind_output(units_dir, t):\n    print(\"\\t\", end='')\n    line('.')\n    for fn in glob.glob(units_dir + '/' + t + '.*/' + _VALGRIND_OUTPUT_NAME):\n        with open(fn, 'r') as f:\n            for l in f:\n                print(\"\\t\" + l, end='')\n    print()\n\ndef run_summary(build_dir):\n    print()\n    print('Summary (see CMDLINE.tmp to reproduce without test harness)')\n    line()\n\n    fmt = '  %-40s%d'\n    print(fmt % ('#passed:', len(L_PASSED)))\n\n    print(fmt % ('#FIXED:', len(L_FIXED)))\n    for t in L_FIXED:\n        print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n\n    print(fmt % ('#FAILED (broken args.ctags?):', len(L_BROKEN_ARGS_CTAGS)))\n    for t in L_BROKEN_ARGS_CTAGS:\n        print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n\n    print(fmt % ('#FAILED (unexpected-exit-status):', len(L_FAILED_BY_STATUS)))\n    for t in L_FAILED_BY_STATUS:\n        print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n        if SHOW_DIFF_OUTPUT:\n            run_show_stderr_output(build_dir, remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n\n    print(fmt % ('#FAILED (unexpected-output):', len(L_FAILED_BY_DIFF)))\n    for t in L_FAILED_BY_DIFF:\n        print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n        if SHOW_DIFF_OUTPUT:\n            run_show_stderr_output(build_dir, remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n            run_show_diff_output(build_dir, remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n\n    if WITH_TIMEOUT != 0:\n        print(fmt % ('#TIMED-OUT (' + str(WITH_TIMEOUT) + 's):', len(L_FAILED_BY_TIMEED_OUT)))\n        for t in L_FAILED_BY_TIMEED_OUT:\n            print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n\n    print(fmt % ('#skipped (features):', len(L_SKIPPED_BY_FEATURES)))\n    for t in L_SKIPPED_BY_FEATURES:\n        print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n\n    print(fmt % ('#skipped (languages):', len(L_SKIPPED_BY_LANGUAGES)))\n    for t in L_SKIPPED_BY_LANGUAGES:\n        print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n\n    if WITH_TIMEOUT == 0:\n        print(fmt % ('#skipped (infinite-loop):', len(L_SKIPPED_BY_ILOOP)))\n        for t in L_SKIPPED_BY_ILOOP:\n            print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n\n    print(fmt % ('#known-bugs:', len(L_KNOWN_BUGS)))\n    for t in L_KNOWN_BUGS:\n        print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n\n    if WITH_VALGRIND:\n        print(fmt % ('#valgrind-error:', len(L_VALGRIND)))\n        for t in L_VALGRIND:\n            print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n        if SHOW_DIFF_OUTPUT:\n            print(fmt % ('##valgrind-error:', len(L_VALGRIND)))\n            for t in L_VALGRIND:\n                print(\"\\t\" + remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n                run_show_valgrind_output(build_dir, remove_prefix(t, _DEFAULT_CATEGORY + '/'))\n\ndef make_pretense_map(arg):\n    r = ''\n    for p in arg.split(','):\n        ret = re.match(r'(.*)/(.*)', p)\n        if not ret:\n            error_exit(1, 'wrong format of --_pretend option arg')\n\n        (newlang, oldlang) = ret.group(1, 2)\n        if newlang == '':\n            error_exit(1, 'newlang part of --_pretend option arg is empty')\n        if oldlang == '':\n            error_exit(1, 'oldlang part of --_pretend option arg is empty')\n\n        r += ' --_pretend-' + newlang + '=' + oldlang\n\n    return r\n\ndef action_run(parser, action, *args):\n    global CATEGORIES\n    global CTAGS\n    global UNITS\n    global LANGUAGES\n    global WITH_TIMEOUT\n    global WITH_VALGRIND\n    global COLORIZED_OUTPUT\n    global RUN_SHRINK\n    global SHOW_DIFF_OUTPUT\n    global PRETENSE_OPTS\n    global NUM_WORKER_THREADS\n    global SHELL\n\n    parser.add_argument('--categories', metavar='CATEGORY1[,CATEGORY2,...]',\n            help='run only CATEGORY* related cases.')\n    parser.add_argument('--ctags',\n            help='ctags executable file for testing')\n    parser.add_argument('--units', metavar='UNITS1[,UNITS2,...]',\n            help='run only UNIT(S).')\n    parser.add_argument('--languages', metavar='PARSER1[,PARSER2,...]',\n            help='run only PARSER* related cases.')\n    parser.add_argument('--with-timeout', type=int, default=0,\n            metavar='DURATION',\n            help='run a test case with specified timeout in seconds. 0 means no timeout (default).')\n    parser.add_argument('--with-valgrind', action='store_true', default=False,\n            help='run a test case under valgrind')\n    parser.add_argument('--colorized-output', choices=['yes', 'no'],\n            default='yes' if len(os.environ.get('NO_COLOR', \"\")) == 0 else 'no',\n            help='print the result in color.')\n    parser.add_argument('--run-shrink', action='store_true', default=False,\n            help='(TODO: NOT IMPLEMENTED YET)')\n    parser.add_argument('--show-diff-output', action='store_true', default=False,\n            help='show diff output (and valgrind errors) for failed test cases in the summary.')\n    parser.add_argument('--with-pretense-map',\n            metavar='NEWLANG0/OLDLANG0[,...]',\n            help='make NEWLANG parser pretend OLDLANG.')\n    parser.add_argument('--threads', type=int, default=NUM_WORKER_THREADS,\n            help='number of worker threads')\n    parser.add_argument('--shell',\n            help='shell to be used.')\n    parser.add_argument('units_dir',\n            help='Units directory.')\n    parser.add_argument('build_dir', nargs='?', default='',\n            help='Build directory. If not given, units_dir is used.')\n\n    res = parser.parse_args(args)\n    if res.categories:\n        CATEGORIES = [x if x == 'ROOT' or x.endswith('.r') else x + '.r'\n                for x in res.categories.split(',')]\n    if res.ctags:\n        CTAGS = res.ctags\n    if res.units:\n        UNITS = res.units.split(',')\n    if res.languages:\n        LANGUAGES = res.languages.split(',')\n    WITH_TIMEOUT = res.with_timeout\n    WITH_VALGRIND = res.with_valgrind\n    COLORIZED_OUTPUT = (res.colorized_output == 'yes')\n    RUN_SHRINK = res.run_shrink\n    SHOW_DIFF_OUTPUT = res.show_diff_output\n    if res.with_pretense_map:\n        PRETENSE_OPTS = make_pretense_map(res.with_pretense_map)\n    NUM_WORKER_THREADS = res.threads\n    if res.shell:\n        SHELL = res.shell\n    if res.build_dir == '':\n        res.build_dir = res.units_dir\n\n    if WITH_VALGRIND:\n        check_availability('valgrind')\n    check_availability('diff')\n    init_features()\n\n    if isabs(res.build_dir):\n        build_dir = res.build_dir\n    else:\n        build_dir = os.path.realpath(res.build_dir)\n\n    category = _DEFAULT_CATEGORY\n    if len(CATEGORIES) == 0 or (category in CATEGORIES):\n        run_dir(category, res.units_dir, build_dir)\n\n    for d in glob.glob(res.units_dir + '/*.r'):\n        d = d.replace('\\\\', '/')    # for Windows\n        if not os.path.isdir(d):\n            continue\n        category = os.path.basename(d)\n        build_d = res.build_dir + '/' + category\n        run_dir(category, d, build_d)\n\n    run_summary(build_dir)\n\n    if L_FAILED_BY_STATUS or L_FAILED_BY_DIFF or \\\n            L_FAILED_BY_TIMEED_OUT or L_BROKEN_ARGS_CTAGS or \\\n            L_VALGRIND:\n        return 1\n    else:\n        return 0\n\ndef action_clean(parser, action, *args):\n    parser.add_argument('units_dir',\n            help='Build directory for units testing.')\n\n    res = parser.parse_args(args)\n    units_dir = res.units_dir\n\n    if not os.path.isdir(units_dir):\n        error_exit(0, 'No such directory: ' + units_dir)\n\n    for bundles in glob.glob(units_dir + '/**/BUNDLES', recursive=True):\n        clean_bundles(bundles)\n\n    for fn in glob.glob(units_dir + '/**/*.tmp', recursive=True):\n        os.remove(fn)\n    for fn in glob.glob(units_dir + '/**/*.TMP', recursive=True):\n        os.remove(fn)\n    return 0\n\ndef tmain_compare_result(build_topdir):\n    for fn in glob.glob(build_topdir + '/*/*-diff.txt'):\n        print(fn)\n        print()\n        with open(fn, 'r', errors='replace') as f:\n            for l in f:\n                print(\"\\t\" + l, end='')\n        print()\n\n    for fn in glob.glob(build_topdir + '/*/gdb-backtrace.txt'):\n        with open(fn, 'r', errors='replace') as f:\n            for l in f:\n                print(\"\\t\" + l, end='')\n\ndef tmain_compare(subdir, build_subdir, aspect, file):\n    msg = '%-59s ' % (aspect)\n    generated = build_subdir + '/' + aspect + '-diff.txt'\n    actual = build_subdir + '/' + aspect + '-actual.txt'\n    expected = subdir + '/' + aspect + '-expected.txt'\n    if os.path.isfile(actual) and os.path.isfile(expected) and \\\n            filecmp.cmp(actual, expected):\n        run_result('ok', msg, None, file=file)\n        # When successful, remove files generated in the last\n        # failure to make the directory clean.\n        # Unlike other generated files like gdb-backtrace.txt\n        # misc/review script looks at the -diff.txt file.\n        # Therefore we handle -diff.txt specially here.\n        if os.path.isfile(generated):\n            os.remove(generated)\n        return True\n    else:\n        with open(generated, 'wb') as f:\n            subprocess.run(['diff', '-U',\n                str(DIFF_U_NUM), '--strip-trailing-cr',\n                expected, actual],\n                stdout=f, stderr=subprocess.STDOUT)\n        run_result('error', msg, None, 'diff: ' + generated, file=file)\n        return False\n\ndef failed_git_marker(fn):\n    if shutil.which('git'):\n        ret = subprocess.run(['git', 'ls-files', '--', fn],\n            stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)\n        if ret.returncode == 0 and ret.stdout == b'':\n            return '<G>'\n    return ''\n\ndef is_crashed(fn):\n    with open(fn, 'r') as f:\n        if 'core dump' in f.read():\n            return True\n    return False\n\ndef print_backtraces(ctags_exe, cores, fn):\n    with open(fn, 'wb') as f:\n        for coref in cores:\n            subprocess.run(['gdb', ctags_exe, '-c', coref, '-ex', 'where', '-batch'],\n                stdout=f, stderr=subprocess.DEVNULL)\n\ndef tmain_sub(test_name, basedir, subdir, build_subdir):\n    global TMAIN_STATUS\n    global TMAIN_FAILED\n\n    CODE_FOR_IGNORING_THIS_TMAIN_TEST = 77\n    CODE_FOR_INTERNAL_ERROR_THIS_TMAIN_TEST = 76\n\n    os.makedirs(build_subdir, exist_ok=True)\n\n    for fn in glob.glob(build_subdir + '/*-actual.txt'):\n        os.remove(fn)\n\n    strbuf = io.StringIO()\n    print(\"\\nTesting \" + test_name, file=strbuf)\n    line('-', file=strbuf)\n\n    if isabs(CTAGS):\n        ctags_path = CTAGS\n    else:\n        ctags_path = os.path.join(basedir, CTAGS)\n\n    if isabs(READTAGS):\n        readtags_path = READTAGS\n    else:\n        readtags_path = os.path.join(basedir, READTAGS)\n\n    if isabs(OPTSCRIPT):\n        optscript_path = OPTSCRIPT\n    else:\n        optscript_path = os.path.join(basedir, OPTSCRIPT)\n\n    start = time.time()\n    ret = subprocess.run([SHELL, 'run.sh',\n            ctags_path,\n            build_subdir,\n            readtags_path,\n            optscript_path],\n            cwd=subdir,\n            stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    #print('execute time: %f' % (time.time() - start), file=strbuf)\n\n    encoding = 'utf-8'\n    try:\n        stdout = ret.stdout.decode(encoding).replace(\"\\r\\n\", \"\\n\")\n    except UnicodeError:\n        encoding = 'iso-8859-1'\n        stdout = ret.stdout.decode(encoding).replace(\"\\r\\n\", \"\\n\")\n    stderr = ret.stderr.decode('utf-8').replace(\"\\r\\n\", \"\\n\")\n    if os.path.basename(CTAGS) != 'ctags':\n        # program name needs to be canonicalized\n        stderr = re.sub('(?m)^' + os.path.basename(CTAGS) + ':', 'ctags:', stderr)\n\n    if ret.returncode == CODE_FOR_IGNORING_THIS_TMAIN_TEST:\n        run_result('skip', '', None, stdout.replace(\"\\n\", ''), file=strbuf)\n        print(strbuf.getvalue(), end='')\n        sys.stdout.flush()\n        strbuf.close()\n        return True\n    if ret.returncode == CODE_FOR_INTERNAL_ERROR_THIS_TMAIN_TEST:\n        internal_error_msg = stdout.replace(\"\\n\", '')\n        TMAIN_FAILED += [test_name + '/' + 'internal-error: ' + internal_error_msg]\n        TMAIN_STATUS = False\n        run_result('internal-error', '', None, internal_error_msg, file=strbuf)\n        print(strbuf.getvalue(), end='')\n        sys.stdout.flush()\n        strbuf.close()\n        return True\n\n    with open(build_subdir + '/exit-actual.txt', 'w', newline='\\n') as f:\n        print(ret.returncode, file=f)\n    with open(build_subdir + '/stdout-actual.txt', 'w', newline='\\n', encoding=encoding) as f:\n        print(stdout, end='', file=f)\n    with open(build_subdir + '/stderr-actual.txt', 'w', newline='\\n') as f:\n        print(stderr, end='', file=f)\n\n    if os.path.isfile(build_subdir + '/tags'):\n        os.rename(build_subdir + '/tags', build_subdir + '/tags-actual.txt')\n\n    for aspect in ['stdout', 'stderr', 'exit', 'tags']:\n        expected_txt = subdir + '/' + aspect + '-expected.txt'\n        actual_txt = build_subdir + '/' + aspect + '-actual.txt'\n        if os.path.isfile(expected_txt):\n            if tmain_compare(subdir, build_subdir, aspect, strbuf):\n                os.remove(actual_txt)\n            else:\n                TMAIN_FAILED += [test_name + '/' + aspect + '-compare' +\n                        failed_git_marker(expected_txt)]\n                TMAIN_STATUS = False\n                if aspect == 'stderr' and \\\n                        is_crashed(actual_txt) and \\\n                        shutil.which('gdb'):\n                    print_backtraces(ctags_path,\n                            glob.glob(build_subdir + '/core*'),\n                            build_subdir + '/gdb-backtrace.txt')\n        elif os.path.isfile(actual_txt):\n            os.remove(actual_txt)\n\n    print(strbuf.getvalue(), end='')\n    sys.stdout.flush()\n    strbuf.close()\n    return True\n\ndef tmain_run(topdir, build_topdir, units):\n    global TMAIN_STATUS\n\n    TMAIN_STATUS = True\n\n    (q, threads) = create_thread_queue(tmain_sub)\n\n    basedir = os.getcwd()\n    for subdir in glob.glob(topdir + '/*.d'):\n        test_name = os.path.basename(subdir)[:-2]\n\n        if len(units) > 0 and not test_name in units:\n            continue\n\n        build_subdir = build_topdir + '/' + os.path.basename(subdir)\n        q.put((test_name, basedir, subdir, build_subdir))\n\n    join_workers(q, threads)\n\n    print()\n    if not TMAIN_STATUS:\n        print('Failed tests')\n        line('=')\n        for f in TMAIN_FAILED:\n            print(re.sub('<G>', ' (not committed/cached yet)', f))\n        print()\n\n        if SHOW_DIFF_OUTPUT:\n            print('Detail [compare]')\n            line('-')\n            tmain_compare_result(build_topdir)\n\n    return TMAIN_STATUS\n\ndef action_tmain(parser, action, *args):\n    global CTAGS\n    global COLORIZED_OUTPUT\n    global WITH_VALGRIND\n    global SHOW_DIFF_OUTPUT\n    global READTAGS\n    global OPTSCRIPT\n    global UNITS\n    global NUM_WORKER_THREADS\n    global SHELL\n\n    parser.add_argument('--ctags',\n            help='ctags executable file for testing')\n    parser.add_argument('--colorized-output', choices=['yes', 'no'], default='yes',\n            help='print the result in color.')\n    parser.add_argument('--with-valgrind', action='store_true', default=False,\n            help='(not implemented) run a test case under valgrind')\n    parser.add_argument('--show-diff-output', action='store_true', default=False,\n            help='how diff output for failed test cases in the summary.')\n    parser.add_argument('--readtags',\n            help='readtags executable file for testing')\n    parser.add_argument('--optscript',\n            help='optscript executable file for testing')\n    parser.add_argument('--units', metavar='UNITS1[,UNITS2,...]',\n            help='run only Tmain/UNIT*.d (.d is not needed)')\n    parser.add_argument('--threads', type=int, default=NUM_WORKER_THREADS,\n            help='number of worker threads')\n    parser.add_argument('--shell',\n            help='shell to be used.')\n    parser.add_argument('tmain_dir',\n            help='Tmain directory.')\n    parser.add_argument('build_dir', nargs='?', default='',\n            help='Build directory. If not given, tmain_dir is used.')\n\n    res = parser.parse_args(args)\n    if res.ctags:\n        CTAGS = res.ctags\n    COLORIZED_OUTPUT = (res.colorized_output == 'yes')\n    WITH_VALGRIND = res.with_valgrind\n    SHOW_DIFF_OUTPUT = res.show_diff_output\n    if res.readtags:\n        READTAGS = res.readtags\n    if res.optscript:\n        OPTSCRIPT = res.optscript\n    if res.units:\n        UNITS = res.units.split(',')\n    NUM_WORKER_THREADS = res.threads\n    if res.shell:\n        SHELL = res.shell\n    if res.build_dir == '':\n        res.build_dir = res.tmain_dir\n\n    #check_availability('awk')\n    check_availability('diff')\n\n    if isabs(res.build_dir):\n        build_dir = res.build_dir\n    else:\n        build_dir = os.path.realpath(res.build_dir)\n\n    ret = tmain_run(res.tmain_dir, build_dir, UNITS)\n    if ret:\n        return 0\n    else:\n        return 1\n\ndef action_clean_tmain(parser, action, *args):\n    parser.add_argument('tmain_dir',\n            help='Build directory for tmain testing.')\n\n    res = parser.parse_args(args)\n    tmain_dir = res.tmain_dir\n\n    if not os.path.isdir(tmain_dir):\n        error_exit(0, 'No such directory: ' + tmain_dir)\n\n    for obj in ['stdout', 'stderr', 'exit', 'tags']:\n        for typ in ['actual', 'diff']:\n            for fn in glob.glob(tmain_dir + '/**/' + obj + '-' + typ + '.txt', recursive=True):\n                os.remove(fn)\n    for fn in glob.glob(tmain_dir + '/**/gdb-backtrace.txt', recursive=True):\n        os.remove(fn)\n    return 0\n\ndef prepare_environment():\n    global _PREPERE_ENV\n\n    os.environ['LC_ALL'] = 'C'\n    os.environ['MSYS2_ARG_CONV_EXCL'] = '--regex-;--_scopesep;--exclude;--exclude-exception'\n\n    _PREPERE_ENV = \"\"\"LC_ALL=\"C\"; export LC_ALL\nMSYS2_ARG_CONV_EXCL='--regex-;--_scopesep;--exclude;--exclude-exception'; export MSYS2_ARG_CONV_EXCL\n\"\"\"\n\n# enable ANSI escape sequences on Windows 10 1511 (10.0.10586) or later\ndef enable_esc_sequence():\n    if os.name != 'nt':\n        return\n\n    import ctypes\n\n    kernel32 = ctypes.windll.kernel32\n\n    ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4\n    STD_OUTPUT_HANDLE = -11\n\n    out = kernel32.GetStdHandle(STD_OUTPUT_HANDLE)\n    mode = ctypes.c_ulong()\n    if kernel32.GetConsoleMode(out, ctypes.byref(mode)):\n        kernel32.SetConsoleMode(out,\n                mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING)\n\ndef main():\n    prepare_environment()\n    enable_esc_sequence()\n\n    parser = argparse.ArgumentParser(\n            description='Units test harness for ctags.')\n    subparsers = parser.add_subparsers(dest='action', metavar='ACTION')\n    cmdmap = {}\n    cmdmap['run'] = [action_run,\n            subparsers.add_parser('run', aliases=['units'],\n                description='Run all tests case under units_dir.',\n                help='Run all tests case')]\n    cmdmap['units'] = cmdmap['run']\n    cmdmap['clean'] = [action_clean,\n            subparsers.add_parser('clean',\n                description='Clean all files created during units testing.',\n                help='Clean all files created during units testing')]\n    cmdmap['tmain'] = [action_tmain,\n            subparsers.add_parser('tmain',\n                description='Run tests for main part of ctags.',\n                help='Run tests for main part of ctags')]\n    cmdmap['clean-tmain'] = [action_clean_tmain,\n            subparsers.add_parser('clean-tmain',\n                description='Clean all files created during tmain testing.',\n                help='Clean all files created during tmain testing')]\n    subparsers.add_parser('help',\n            help='show this help message and exit')\n    cmdmap['help'] = [action_help, parser]\n\n    if len(sys.argv) < 2:\n        parser.print_help()\n        sys.exit(1)\n\n    res = parser.parse_args(sys.argv[1:2])\n    (func, subparser) = cmdmap[res.action]\n    sys.exit(func(subparser, *sys.argv[1:]))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "misc/validators/g++-common.sh",
    "content": "#!/bin/sh\n#\n# g++-common.sh - common code used in validator-cxx*\n#\n#  Copyright (c) 2022, Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n\naction=$1\ninput=$2\nSTD=$3\nshift 3\n\ncase \"$action\" in\n    is_runnable)\n\t\tcommand -v g++ > /dev/null 2>&1\n\t\texit $?\n\t\t;;\n    validate)\n\t\tg++ -fsyntax-only -std=${STD} \"$@\" \"$input\" > /dev/null\n\t\texit $?\n\t;;\n\t*)\n\t\techo \"$0: unknown action: $action\" >&2\n\t\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/gfortran-common.sh",
    "content": "#!/bin/sh\n#\n# gfortran-common.sh - common code used in validator-fortran*\n#\n#  Copyright (c) 2024, Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n\naction=$1\ninput=$2\nshift 2\n\ncase \"$action\" in\n    is_runnable)\n\t\tcommand -v gfortran > /dev/null 2>&1\n\t\texit $?\n\t;;\n    validate)\n\t\tgfortran -fsyntax-only \"$@\" \"$input\" > /dev/null\n\t\texit $?\n\t;;\n\t*)\n\t\techo \"$0: unknown action: $action\" >&2\n\t\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/tsc-common.sh",
    "content": "#!/bin/sh\n#\n# tsc-common.sh - common code used in validator-tsc*\n#\n#  Copyright (c) 2026, Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\naction=$1\ninput=$2\nTARGET=$3\nshift 3\n\ncase \"$action\" in\n    is_runnable)\n\t\tcommand -v tsc > /dev/null 2>&1\n\t\texit $?\n\t;;\n    validate)\n\t\ttsc --noEmit \"$input\" --target $TARGET > /dev/null\n\t\texit $?\n\t;;\n\t*)\n\t\techo \"$0: unknown action: $action\" >&2\n\t\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-KNOWN-INVALIDATION",
    "content": "#!/bin/sh\nexit 0\n"
  },
  {
    "path": "misc/validators/validator-NONE",
    "content": "#!/bin/sh\nexit 0\n"
  },
  {
    "path": "misc/validators/validator-c",
    "content": "#!/bin/sh\n#\n# validator-c --- validating C input files\n#\n#  Copyright (c) 2022, Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\naction=$1\ninput=$2\n\ncase \"$action\" in\n    is_runnable)\n\tcommand -v gcc > /dev/null 2>&1\n\texit $?\n\t;;\n    validate)\n\tgcc -fsyntax-only \"$input\" > /dev/null\n\texit $?\n\t;;\n    *)\n\techo \"$0: unknown action: $action\" >&2\n\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-cxx03",
    "content": "#!/bin/sh\n. \"$3\"/g++-common.sh \"$1\" \"$2\" c++03\n"
  },
  {
    "path": "misc/validators/validator-cxx11",
    "content": "#!/bin/sh\n. \"$3\"/g++-common.sh \"$1\" \"$2\" c++11\n"
  },
  {
    "path": "misc/validators/validator-cxx17",
    "content": "#!/bin/sh\n. \"$3\"/g++-common.sh \"$1\" \"$2\" c++17\n"
  },
  {
    "path": "misc/validators/validator-cxx20+module",
    "content": "#!/bin/sh\n. \"$3\"/g++-common.sh \"$1\" \"$2\" c++20 -fmodules-ts -c\n"
  },
  {
    "path": "misc/validators/validator-fortran+dollar-ok",
    "content": "#!/bin/sh\n. \"$3\"/gfortran-common.sh \"$1\" \"$2\" -fdollar-ok\n"
  },
  {
    "path": "misc/validators/validator-gnat",
    "content": "#!/bin/sh\n#\n# validator-gnat --- validating Ada input files\n#\n#  Copyright (c) 2025, Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\naction=$1\ninput=$2\n\ncase \"$action\" in\n    is_runnable)\n\tcommand -v gnat > /dev/null 2>&1\n\texit $?\n\t;;\n    validate)\n\tgnat compile -gnats \"$input\" > /dev/null 2>&1\n\texit $?\n\t;;\n    *)\n\techo \"$0: unknown action: $action\" >&2\n\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-go",
    "content": "#!/bin/sh\n#\n# validator-go - validating go input files with go command\n#\n#  Copyright (c) 2026, Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\naction=$1\ninput=$2\ncase \"$action\" in\n    is_runnable)\n\tcommand -v go > /dev/null 2>&1\n\texit $?\n\t;;\n    validate)\n\tgo build -o /dev/null \"$input\"\n\texit $?\n\t;;\n    *)\n\techo \"$0: unknown action: $action\" >&2\n\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-jq",
    "content": "#!/bin/sh\n#\n# validator-jq - validating json input files\n#\n#  Copyright (c) 2018, Red Hat, Inc.\n#  Copyright (c) 2018, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n#\n# jq command line is derived from\n#\n# https://github.com/universal-ctags/ctags/pull/1909/commits/234540f2cc8faf711aaa1ac28b84aca133625797\n#\n# , chainge in a pull request submitted by @ahakanbaba.\n#\naction=$1\ninput=$2\ncase \"$action\" in\n    is_runnable)\n\tcommand -v jq > /dev/null 2>&1\n\texit $?\n\t;;\n    validate)\n\tjq . \"$input\" > /dev/null\n\texit $?\n\t;;\n    *)\n\techo \"$0: unknown action: $action\" >&2\n\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-node",
    "content": "#!/bin/sh\n#\n# validator-node - validating JavaScript input files with node\n#\n#  Copyright (c) 2022, Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\naction=$1\ninput=$2\ncase \"$action\" in\n    is_runnable)\n\tcommand -v node > /dev/null 2>&1\n\texit $?\n\t;;\n    validate)\n\tnode --check \"$input\" > /dev/null\n\texit $?\n\t;;\n    *)\n\techo \"$0: unknown action: $action\" >&2\n\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-puppet",
    "content": "#!/bin/sh\n#\n# validator-puppet - validating puppetManifest input files\n#\n#  Copyright (c) 2018, Hakan Baba\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n#\n# NOTE about puppet version\n# ------------------------------------------------------------------------\n# This driver script does not specify the used puppet\n# version. Instead, puppet version will depend on the platform\n# runtime. As a result, you may see some warnings on some platforms\n# even tough the validation has passed.\n#\n# As of writing this comment, puppet5 is becoming popular. In #1909,\n# @ahakanbaba has fixed much of test cases to be valid puppet5\n# files. Even tough that PR exists, we are still sticking with puppet4\n# in our automated tests. One of our test platforms is Fedora28 and\n# its distribution has puppet4 at this time. As the note about\n# warnings above mentions, in validation runs using puppet4 you may\n# see the following Errors prompts that do not fail the validation.\n#\n#     puppet-simpleselector.d/input.pp with puppet                     valid\n#     Error: Could not write report for e22e2d5d26ca.ec2.internal at \\\n#     /var/lib/puppet/reports/e22e2d5d26ca.ec2.internal/201810241144.yaml: \\\n#     undefined method `split' for :ensure:Symbol\n#     Error: Could not send report: undefined method `split' for :ensure:Symbol\n#     ...\n#\n# So ideally, we should specify the version of puppet used\n# in this script. @ahakanbaba shows the way to do so in #1926.\n# However, because I (@masatake) don't want to take much time to write\n# portable puppet validator, I keep this script as is.\n#\naction=$1\ninput=$2\ncase \"$action\" in\n    is_runnable)\n\tcommand -v puppet > /dev/null 2>&1\n\texit $?\n\t;;\n    validate)\n\tpuppet apply --noop \"$input\" > /dev/null\n\texit $?\n\t;;\n    *)\n\techo \"$0: unknown action: $action\" >&2\n\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-python",
    "content": "#!/bin/sh\n#\n# validator-python --- validating Python input files\n#\n#  Copyright (c) 2025, Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\nPYTHON=${PYTHON:-python}\naction=$1\ninput=$2\n\ncase \"$action\" in\n    is_runnable)\n\tcommand -v \"${PYTHON}\" > /dev/null 2>&1\n\texit $?\n\t;;\n    validate)\n\t\"${PYTHON}\" -m py_compile \"$input\"\n\ts=$?\n\td=$(dirname \"$input\")\n\tb=$(basename \"$input\" .py)\n\trm \"$d\"/__pycache__/\"$b\"*pyc\n\trmdir \"$d\"/__pycache__\n\texit $s\n\t;;\n    *)\n\techo \"$0: unknown action: $action\" >&2\n\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-ruby",
    "content": "#!/bin/sh\n#\n# validator-ruby - validating Ruby input files with ruby\n#\n#  Copyright (c) 2022 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\naction=$1\ninput=$2\ncase \"$action\" in\n    is_runnable)\n\tcommand -v ruby > /dev/null 2>&1\n\texit $?\n\t;;\n    validate)\n\truby -c \"$input\" > /dev/null\n\texit $?\n\t;;\n    *)\n\techo \"$0: unknown action: $action\" >&2\n\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-svlint",
    "content": "#!/bin/sh\n#\n# validator-svlint - validating Verilog/SystemVerilog input files with svlint\n#   https://github.com/dalance/svlint\n#\n#  Copyright (c) 2023 Hiroo HAYASHI\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\naction=$1\ninput=\"$2\"\ncmd=svlint\nflags=\"--ignore-include\"\ncase \"$action\" in\n    is_runnable)\n\tcommand -v $cmd > /dev/null 2>&1\n\texit $?\n\t;;\n    validate)\n\t$cmd $flags \"$input\" > /dev/null\n\texit $?\n\t;;\n    *)\n\techo \"$0: unknown action: $action\" >&2\n\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-swipl",
    "content": "#!/bin/sh\n#\n# validator-swipl - validating Prolog input files with swipl\n#\n#  Copyright (c) 2025 Masatake YAMATO\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\naction=$1\ninput=\"$2\"\ncmd=swipl\nflags=\"--on-error=status -g halt.\"\ncase \"$action\" in\n    is_runnable)\n\tcommand -v $cmd > /dev/null 2>&1\n\texit $?\n\t;;\n    validate)\n\t$cmd $flags \"$input\" > /dev/null\n\texit $?\n\t;;\n    *)\n\techo \"$0: unknown action: $action\" >&2\n\texit 1\n\t;;\nesac\n"
  },
  {
    "path": "misc/validators/validator-tsc",
    "content": "#!/bin/sh\n. \"$3\"/tsc-common.sh \"$1\" \"$2\" es5\n"
  },
  {
    "path": "misc/validators/validator-tsc-es2015",
    "content": "#!/bin/sh\n. \"$3\"/tsc-common.sh \"$1\" \"$2\" es2015\n"
  },
  {
    "path": "misc/visit-version-info.bash",
    "content": "#!/bin/bash\n\nG()\n{\n    local f=$1\n    shift\n\n    local p\n\n    echo '***' $f '***'\n    for p in \"$@\"; do\n\tgrep -h '\\<'\"$p\"'\\>' \"$f\"\n    done\n}\n\nG configure.ac AC_INIT \nG main/ctags.h PROGRAM_VERSION PROGRAM_COPYRIGHT OUTPUT_VERSION_CURRENT OUTPUT_VERSION_AGE\nG win32/ctags.rc FILEVERSION FILEVERSION FileVersion LegalCopyright LegalCopyright\nG win32/ctags.exe.manifest assemblyIdentity\nG win32/config_mvc.h PACKAGE_STRING PACKAGE_VERSION VERSION\nG win32/config_mingw.h PACKAGE_STRING PACKAGE_VERSION VERSION\nG misc/git-tag-maybe.sh BASE\nG NEWS.rst 'Changes in '\n"
  },
  {
    "path": "mk_mingw.mak",
    "content": "# Makefile for Universal Ctags under Win32 with MinGW compiler\n\nOBJEXT = o\ninclude source.mak\n\nGNULIB_OBJS = $(MINGW_GNULIB_SRCS:.c=.$(OBJEXT))\n\nCFLAGS = -Wall -std=gnu99\nCOMMON_DEFINES =\nDEFINES = $(COMMON_DEFINES) -DHAVE_CONFIG_H -DHAVE_PACKCC\nINCLUDES = -I. -Ignulib -Ilibreadtags -iquote parsers -iquote main -iquote dsl\nCC = gcc\nWINDRES = windres\nOPTLIB2C = ./misc/optlib2c\nPACKCC   = ./packcc.exe\nRES_OBJ = win32/ctags.res.o\nEXTRA_OBJS  =\nEXTRA_OBJS += $(GNULIB_OBJS)\nEXTRA_OBJS += $(WIN32_OBJS)\nEXTRA_OBJS += $(PEG_OBJS)\nEXTRA_OBJS += $(RES_OBJ)\nALL_OBJS   += $(EXTRA_OBJS)\nALL_LIB_OBJS += $(EXTRA_OBJS)\nVPATH = . ./gnulib ./main ./parsers ./optlib ./extra-cmds ./libreadtags ./win32\n\nifeq (yes, $(WITH_ICONV))\nDEFINES += -DHAVE_ICONV\nLIBS += -liconv\nendif\nifeq (yes, $(WITH_PCRE2))\nCFLAGS += -DHAVE_LIBPCRE2=1 $(shell pkg-config --cflags libpcre2-8)\nLIBS += $(shell pkg-config --libs libpcre2-8)\nPARSER_SRCS += $(PCRE2_SRCS)\nPARSER_HEADS += $(PCRE2_HEADS)\nendif\nifeq (yes, $(WITH_YAML))\nCFLAGS += -DHAVE_LIBYAML=1 $(shell pkg-config --cflags yaml-0.1)\nLIBS += $(shell pkg-config --libs yaml-0.1)\nPARSER_SRCS += $(YAML_SRCS)\nPARSER_HEADS += $(YAML_HEADS)\nendif\nifeq (yes, $(WITH_XML))\nCFLAGS += -DHAVE_LIBXML=1 $(shell pkg-config --cflags libxml-2.0)\nLIBS += $(shell pkg-config --libs libxml-2.0)\nPARSER_SRCS += $(XML_SRCS)\nPARSER_HEADS += $(XML_HEADS)\nendif\nifeq (yes, $(WITH_JSON))\nCFLAGS += -DHAVE_JANSSON=1 $(shell pkg-config --cflags jansson)\nLIBS += $(shell pkg-config --libs jansson)\nendif\n\nifdef DEBUG\nDEFINES += -DDEBUG\nOPT = -g\nelse\nOPT = -O4 -Os -fexpensive-optimizations\nLDFLAGS = -s\nendif\n\n.SUFFIXES: .c .o .ctags .peg\n\n#\n# Silent/verbose commands\n#\n# when V is not set the output of commands is omitted or simplified\n#\nV\t ?= 0\nCC_FOR_PACKCC ?= $(CC)\n\nSILENT   = $(SILENT_$(V))\nSILENT_0 = @\nSILENT_1 =\n\nV_CC\t = $(V_CC_$(V))\nV_CC_0\t = @echo [CC] $@;\nV_CC_1\t =\n\nV_OPTLIB2C   = $(V_OPTLIB2C_$(V))\nV_OPTLIB2C_0 = @echo [OPTLIB2C] $@;\nV_OPTLIB2C_1 =\n\nV_PACKCC   = $(V_PACKCC_$(V))\nV_PACKCC_0 = @echo [PACKCC] $@;\nV_PACKCC_1 =\n\nV_WINDRES   = $(V_WINDRES_$(V))\nV_WINDRES_0 = @echo [WINDRES] $@;\nV_WINDRES_1 =\n\n\n.c.o:\n\t$(V_CC) $(CC) -c $(OPT) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<\n\n%.c: %.ctags $(OPTLIB2C)\n\t$(V_OPTLIB2C) $(OPTLIB2C) $< > $@\n\npeg/%.c peg/%.h: peg/%.peg $(PACKCC)\n\t$(V_PACKCC) $(PACKCC) $<\n\nall: copy_gnulib_heads $(PACKCC) ctags.exe readtags.exe optscript.exe utiltest.exe\n\nctags: ctags.exe\n\n$(PACKCC_OBJ): $(PACKCC_SRC)\n\t$(V_CC) $(CC_FOR_PACKCC) -c $(OPT) $(CFLAGS) $(COMMON_DEFINES) -o $@ $<\n\n$(PACKCC): $(PACKCC_OBJ)\n\t$(V_CC) $(CC_FOR_PACKCC) $(OPT) -o $@ $^\n\nctags.exe: $(ALL_OBJS) $(ALL_HEADS) $(PEG_HEADS) $(PEG_EXTRA_HEADS) $(MINGW_GNULIB_HEADS) $(WIN32_HEADS)\n\t$(V_CC) $(CC) $(OPT) $(CFLAGS) $(LDFLAGS) $(DEFINES) $(INCLUDES) -o $@ $(ALL_OBJS) $(LIBS)\n\n$(RES_OBJ): win32/ctags.rc win32/ctags.exe.manifest win32/resource.h\n\t$(V_WINDRES) $(WINDRES) -o $@ -O coff $<\n\nextra-cmds/%.o: extra-cmds/%.c\n\t$(V_CC) $(CC) -c $(OPT) $(CFLAGS) $(INCLUDES) -o $@ $<\nlibreadtags/%.o: libreadtags/%.c $(UTIL_HEADS)\n\t$(V_CC) $(CC) -c $(OPT) $(CFLAGS) -Ilibreadtags $(INCLUDES) -DHAVE_CTAGS_INLINE_H -o $@ $<\n\nreadtags.exe: $(READTAGS_OBJS) $(READTAGS_HEADS) $(UTIL_OBJS) $(UTIL_HEADS) $(READTAGS_DSL_OBJS) $(READTAGS_DSL_HEADS) $(GNULIB_OBJS) $(MINGW_GNULIB_HEADS)\n\t$(V_CC) $(CC) $(OPT) -o $@ $(READTAGS_OBJS) $(UTIL_OBJS) $(READTAGS_DSL_OBJS) $(GNULIB_OBJS) $(LIBS)\n\noptscript.exe: $(ALL_LIB_OBJS) $(OPTSCRIPT_OBJS) $(ALL_LIB_HEADS) $(OPTSCRIPT_DSL_HEADS) $(WIN32_HEADS)\n\t$(V_CC) $(CC) $(OPT) $(CFLAGS) $(LDFLAGS) $(DEFINES) $(INCLUDES) -o $@ $(ALL_LIB_OBJS) $(OPTSCRIPT_OBJS) $(LIBS)\n\nutiltest.exe: $(UTIL_OBJS) $(UTIL_HEAD) $(UTILTEST_OBJS) $(UTILTEST_HEADS)\n\t$(V_CC) $(CC) $(OPT) $(CFLAGS) $(LDFLAGS) -o $@ $(UTIL_OBJS) $(UTILTEST_OBJS)\n\ncopy_gnulib_heads:\n\tcp win32/config_mingw.h config.h\n\tcp win32/gnulib_h/langinfo.h win32/gnulib_h/locale.h win32/gnulib_h/unistd.h win32/gnulib_h/fnmatch.h win32/gnulib_h/string.h win32/gnulib_h/wchar.h gnulib\n\nclean:\n\t$(SILENT) echo Cleaning\n\t$(SILENT) rm -f ctags.exe readtags.exe optscript.exe $(PACKCC)\n\t$(SILENT) rm -f tags\n\t$(SILENT) rm -f main/*.o optlib/*.o parsers/*.o parsers/cxx/*.o gnulib/*.o misc/packcc/*.o peg/*.o extra-cmds/*.o libreadtags/*.o dsl/*.o win32/*.o win32/mkstemp/*.o\n\t$(SILENT) rm -f config.h gnulib/langinfo.h gnulib/locale.h gnulib/unistd.h gnulib/fnmatch.h gnulib/string.h gnulib/wchar.h\n"
  },
  {
    "path": "mk_mvc.mak",
    "content": "#\n# Makefile for Win32 using Microsoft Visual Studio 2013\n#\n# To use from the command line:\n# 1. From the Start Menu \"Visual Studio 2013\" -> \"Visual Studio Tools\" -> \"VS2013 x86 Native Tools Command Prompt\"\n# 2. In the command prompt that opens goto the directory containing the sources\n# 3. Execute: nmake -f mk_mvc.mak\n#\n\nOBJEXT = obj\ninclude source.mak\n\nCOMMON_DEFINES =\nDEFINES = $(COMMON_DEFINES) -DHAVE_REPOINFO_H -DHAVE_PACKCC\nINCLUDES = -I. -Ignulib -Imain -Iparsers -Ilibreadtags -Idsl\nOPT = /O2 /WX /Zc:preprocessor\nLOPT = /FORCE:MULTIPLE\nPACKCC = packcc.exe\nGNULIB_OBJS = $(MVC_GNULIB_SRCS:.c=.obj)\nWIN32_OBJS = $(WIN32_SRCS:.c=.obj)\nPEG_OBJS = $(PEG_SRCS:.c=.obj)\nPACKCC_OBJ = $(PACKCC_SRC:.c=.obj)\nRES_OBJ = win32/ctags.res\nEXTRA_OBJS = $(GNULIB_OBJS) $(WIN32_OBJS) $(PEG_OBJS) $(RES_OBJ)\nALL_OBJS = $(ALL_SRCS:.c=.obj) $(EXTRA_OBJS)\nALL_LIB_OBJS = $(ALL_LIB_SRCS:.c=.obj) $(EXTRA_OBJS)\nREADTAGS_OBJS = $(READTAGS_SRCS:.c=.obj)\nUTIL_OBJS = $(UTIL_SRCS:.c=.obj)\nREADTAGS_DSL_OBJS = $(READTAGS_DSL_SRCS:.c=.obj)\nOPTSCRIPT_OBJS = $(OPTSCRIPT_SRCS:.c=.obj)\nUTILTEST_OBJS = $(UTILTEST_SRCS:.c=.obj)\n\n!if \"$(WITH_ICONV)\" == \"yes\"\nDEFINES = $(DEFINES) -DHAVE_ICONV\nLIBS = $(LIBS) /libpath:$(ICONV_DIR)/lib iconv.lib\nINCLUDES = $(INCLUDES) -I$(ICONV_DIR)/include\n!endif\n\n!ifdef DEBUG\nDEFINES = $(DEFINES) -DDEBUG\nPDB = yes\n!endif\n\n!ifdef PDB\nOPT = $(OPT) /Zi\nPDBFLAG = /debug\n!else\nPDBFLAG =\n!endif\n\n# Generate repoinfo.h.\n!if [win32\\gen-repoinfo.bat $(REPOINFO_HEADS)]\n!endif\n\n.SUFFIXES: .peg\n\n{main}.c{main}.obj::\n\t$(CC) $(OPT) $(DEFINES) $(INCLUDES) /Fomain\\ /c $<\n{optlib}.c{optlib}.obj::\n\t$(CC) $(OPT) $(DEFINES) $(INCLUDES) /Fooptlib\\ /c $<\n{parsers}.c{parsers}.obj::\n\t$(CC) $(OPT) $(DEFINES) $(INCLUDES) /Foparsers\\ /c $<\n{parsers\\cxx}.c{parsers\\cxx}.obj::\n\t$(CC) $(OPT) $(DEFINES) $(INCLUDES) /Foparsers\\cxx\\ /c $<\n{extra-cmds}.c{extra-cmds}.obj::\n\t$(CC) $(OPT) $(DEFINES) $(INCLUDES) /Foextra-cmds\\ /c $<\n{libreadtags}.c{libreadtags}.obj::\n\t$(CC) $(OPT) $(DEFINES) -DHAVE_CTAGS_INLINE_H $(INCLUDES) /Folibreadtags\\ /c $<\n{dsl}.c{dsl}.obj::\n\t$(CC) $(OPT) $(DEFINES) $(INCLUDES) /Fodsl\\ /c $<\n{win32\\mkstemp}.c{win32\\mkstemp}.obj::\n\t$(CC) $(OPT) $(DEFINES) $(INCLUDES) /Fowin32\\mkstemp\\ /c $<\n{peg}.peg{peg}.c::\n\t$(PACKCC) $<\n{peg}.c{peg}.obj::\n\t$(CC) $(OPT) $(DEFINES) $(INCLUDES) /Fopeg\\ /c $<\n{gnulib}.c{gnulib}.obj::\n\t$(CC) $(OPT) $(DEFINES) $(INCLUDES) /Fognulib\\ /c $<\n{gnulib\\malloc}.c{gnulib\\malloc}.obj::\n\t$(CC) $(OPT) $(DEFINES) $(INCLUDES) /Fognulib\\malloc\\ /c $<\n\nall: copy_gnulib_heads $(PACKCC) ctags.exe readtags.exe optscript.exe utiltest.exe\n\nctags: ctags.exe\n\nctags.exe: $(ALL_OBJS) $(ALL_HEADS) $(PEG_HEADS) $(PEG_EXTRA_HEADS) $(MVC_GNULIB_HEADS) $(WIN32_HEADS) $(REPOINFO_HEADS)\n\t$(CC) $(OPT) /Fe$@ $(ALL_OBJS) /link setargv.obj $(LOPT) $(LIBS) $(PDBFLAG)\n\nreadtags.exe: $(READTAGS_OBJS) $(READTAGS_HEADS) $(UTIL_OBJS) $(UTIL_HEADS) $(READTAGS_DSL_OBJS) $(READTAGS_DSL_HEADS) $(GNULIB_OBJS) $(MVC_GNULIB_HEADS) $(WIN32_HEADS) $(WIN32_OBJS)\n\t$(CC) $(OPT) /Fe$@ $(READTAGS_OBJS) $(READTAGS_DSL_OBJS) $(UTIL_OBJS) $(GNULIB_OBJS) $(WIN32_OBJS) /link setargv.obj $(LOPT) $(PDBFLAG)\n\noptscript.exe: $(ALL_LIB_OBJS) $(OPTSCRIPT_OBJS) $(ALL_LIB_HEADS) $(OPTSCRIPT_DSL_HEADS) $(WIN32_HEADS)\n\t$(CC) $(OPT) /Fe$@ $(ALL_LIB_OBJS) $(OPTSCRIPT_OBJS) /link setargv.obj $(LOPT) $(LIBS)\n\nutiltest.exe: $(UTIL_OBJS) $(UTIL_HEADS) $(UTILTEST_OBJS) $(UTILTEST_HEADS) $(WIN32_HEADS)\n\t$(CC) $(OPT) /Fe$@ $(UTIL_OBJS) $(UTILTEST_OBJS) $(WIN32_OBJS) /link setargv.obj $(LOPT)\n\n$(PACKCC_OBJ): $(PACKCC_SRC)\n\t$(CC) /c $(OPT) /Fo$@ $(INCLUDES) $(COMMON_DEFINES) $(PACKCC_SRC)\n\n$(PACKCC): $(PACKCC_OBJ)\n\t$(CC) $(OPT) /Fe$@ $(PACKCC_OBJ) /link setargv.obj $(LOPT) $(PDBFLAG)\n\nmain\\repoinfo.obj: main\\repoinfo.c main\\repoinfo.h\n\ninclude win32/peg_rule.mak\n\n$(RES_OBJ): win32/ctags.rc win32/ctags.exe.manifest win32/resource.h\n\t$(RC) /nologo /l 0x409 /Fo$@ $*.rc\n\ncopy_gnulib_heads:\n\tcopy win32\\config_mvc.h config.h\n\tcopy win32\\gnulib_h\\langinfo.h gnulib\n\tcopy win32\\gnulib_h\\fnmatch.h gnulib\n\nclean:\n\t- del *.obj main\\*.obj optlib\\*.obj parsers\\*.obj parsers\\cxx\\*.obj gnulib\\*.obj misc\\packcc\\*.obj peg\\*.obj extra-cmds\\*.obj libreadtags\\*.obj dsl\\*.obj win32\\mkstemp\\*.obj win32\\*.res main\\repoinfo.h\n\t- del ctags.exe readtags.exe optscript.exe $(PACKCC)\n\t- del tags\n\t- del config.h gnulib\\langinfo.h gnulib\\fnmatch.h gnulib\\*.obj gnulib\\malloc\\*.obj\n"
  },
  {
    "path": "old-docs/EXTENDING.html",
    "content": "<html>\n<head>\n<title>Exuberant Ctags: Adding support for a new language</title>\n</head>\n<body>\n\n<h1>How to Add Support for a New Language to Exuberant Ctags</h1>\n\n<p>\n<b>Exuberant Ctags</b> has been designed to make it very easy to add your own\ncustom language parser. As an exercise, let us assume that I want to add\nsupport for my new language, <em>Swine</em>, the successor to Perl (i.e. Perl\nbefore Swine &lt;wince&gt;). This language consists of simple definitions of\nlabels in the form \"<code>def my_label</code>\". Let us now examine the various\nways to do this.\n</p>\n\n<h2>Operational background</h2>\n\n<p>\nAs ctags considers each file name, it tries to determine the language of the\nfile by applying the following three tests in order: if the file extension has\nbeen mapped to a language, if the file name matches a shell pattern mapped to\na language, and finally if the file is executable and its first line specifies\nan interpreter using the Unix-style \"#!\" specification (if supported on the\nplatform). If a language was identified, the file is opened and then the\nappropriate language parser is called to operate on the currently open file.\nThe parser parses through the file and whenever it finds some interesting\ntoken, calls a function to define a tag entry.\n</p>\n\n<h2>Creating a user-defined language</h2>\n\n<p>\nThe quickest and easiest way to do this is by defining a new language using\nthe program options. In order to have Swine support available every time I\nstart ctags, I will place the following lines into the file\n<code>$HOME/.ctags</code>, which is read in every time ctags starts:\n\n<code>\n<pre>\n  --langdef=swine\n  --langmap=swine:.swn\n  --regex-swine=/^def[ \\t]*([a-zA-Z0-9_]+)/\\1/d,definition/\n</pre>\n</code>\nThe first line defines the new language, the second maps a file extension to\nit, and the third defines a regular expression to identify a language\ndefinition and generate a tag file entry for it.\n</p>\n\n<h2>Integrating a new language parser</h2>\n\n<p>\nNow suppose that I want to truly integrate compiled-in support for Swine into\nctags. First, I create a new module, <code>swine.c</code>, and add one\nexternally visible function to it, <code>extern parserDefinition\n*SwineParser(void)</code>, and add its name to the table in\n<code>parsers.h</code>. The job of this parser definition function is to\ncreate an instance of the <code>parserDefinition</code> structure (using\n<code>parserNew()</code>) and populate it with information defining how files\nof this language are recognized, what kinds of tags it can locate, and the\nfunction used to invoke the parser on the currently open file.\n</p>\n\n<p>\nThe structure <code>parserDefinition</code> allows assignment of the following\nfields:\n\n<code>\n<pre>\n  const char *name;               /* name of language */\n  kindOption *kinds;              /* tag kinds handled by parser */\n  unsigned int kindCount;         /* size of `kinds' list */\n  const char *const *extensions;  /* list of default extensions */\n  const char *const *patterns;    /* list of default file name patterns */\n  parserInitialize initialize;    /* initialization routine, if needed */\n  simpleParser parser;            /* simple parser (common case) */\n  rescanParser parser2;           /* rescanning parser (unusual case) */\n  boolean regex;                  /* is this a regex parser? */\n</pre>\n</code>\n</p>\n\n<p>\nThe <code>name</code> field must be set to a non-empty string. Also, unless\n<code>regex</code> is set true (see below), either <code>parser</code> or\n<code>parser2</code> must set to point to a parsing routine which will\ngenerate the tag entries. All other fields are optional.\n\n<p>\nNow all that is left is to implement the parser. In order to do its job, the\nparser should read the file stream using using one of the two I/O interfaces:\neither the character-oriented <code>fileGetc()</code>, or the line-oriented\n<code>fileReadLine()</code>. When using <code>fileGetc()</code>, the parser\ncan put back a character using <code>fileUngetc()</code>. How our Swine parser\nactually parses the contents of the file is entirely up to the writer of the\nparser--it can be as crude or elegant as desired. You will note a variety of\nexamples from the most complex (c.c) to the simplest (make.c).\n</p>\n\n<p>\nWhen the Swine parser identifies an interesting token for which it wants to\nadd a tag to the tag file, it should create a <code>tagEntryInfo</code>\nstructure and initialize it by calling <code>initTagEntry()</code>, which\ninitializes defaults and fills information about the current line number and\nthe file position of the beginning of the line. After filling in information\ndefining the current entry (and possibly overriding the file position or other\ndefaults), the parser passes this structure to <code>makeTagEntry()</code>.\n</p>\n\n<p>\nInstead of writing a character-oriented parser, it may be possible to specify\nregular expressions which define the tags. In this case, instead of defining a\nparsing function, <code>SwineParser()</code>, sets <code>regex</code> to true,\nand points <code>initialize</code> to a function which calls\n<code>addTagRegex()</code> to install the regular expressions which define its\ntags. The regular expressions thus installed are compared against each line \nof the input file and generate a specified tag when matched. It is usually\nmuch easier to write a regex-based parser, although they can be slower (one\nparser example was 4 times slower). Whether the speed difference matters to\nyou depends upon how much code you have to parse. It is probably a good\nstrategy to implement a regex-based parser first, and if it is too slow for\nyou, then invest the time and effort to write a character-based parser.\n</p>\n\n<p>\nA regex-based parser is inherently line-oriented (i.e. the entire tag must be\nrecognizable from looking at a single line) and context-insensitive (i.e the\ngeneration of the tag is entirely based upon when the regular expression\nmatches a single line). However, a regex-based callback mechanism is also\navailable, installed via the function <code>addCallbackRegex()</code>. This\nallows a specified function to be invoked whenever a specific regular\nexpression is matched. This allows a character-oriented parser to operate\nbased upon context of what happened on a previous line (e.g. the start or end\nof a multi-line comment). Note that regex callbacks are called just before the\nfirst character of that line can is read via either <code>fileGetc()</code> or\nusing <code>fileGetc()</code>. The effect of this is that before either of\nthese routines return, a callback routine may be invoked because the line\nmatched a regex callback. A callback function to be installed is defined by\nthese types:\n\n<code>\n<pre>\n  typedef void (*regexCallback) (const char *line, const regexMatch *matches, unsigned int count);\n\n  typedef struct {\n      size_t start;   /* character index in line where match starts */\n      size_t length;  /* length of match */\n  } regexMatch;\n</pre>\n</code>\n</p>\n\n<p>\nThe callback function is passed the line matching the regular expression and\nan array of <code>count</code> structures defining the subexpression matches\nof the regular expression, starting from \\0 (the entire line).\n</p>\n\n<p>\nLastly, be sure to add your the name of the file containing your parser (e.g.\nswine.c) to the macro <code>SOURCES</code> in the file <code>source.mak</code>\nand an entry for the object file to the macro <code>OBJECTS</code> in the same\nfile, so that your new module will be compiled into the program.\n</p>\n\n<p>\nIn case you have some problems run <code>ctags --verbose</code> to see if the\nextensions or patterns you defined for your language conflict with other\nlanguages.\n</p>\n\n<p>\nThis is all there is to it. All other details are specific to the parser and\nhow it wants to do its job. There are some support functions which can take\ncare of some commonly needed parsing tasks, such as keyword table lookups (see\nkeyword.c), which you can make use of if desired (examples of its use can be\nfound in c.c, eiffel.c, and fortran.c). Almost everything is already taken care\nof automatically for you by the infrastructure.  Writing the actual parsing\nalgorithm is the hardest part, but is not constrained by any need to conform\nto anything in ctags other than that mentioned above.\n</p>\n\n<p>\nThere are several different approaches used in the parsers inside <b>Exuberant\nCtags</b> and you can browse through these as examples of how to go about\ncreating your own.\n</p>\n\n<h2>Examples</h2>\n\n<p>\nBelow you will find several example parsers demonstrating most of the\nfacilities available. These include three alternative implementations\nof a Swine parser, which generate tags for lines beginning with\n\"<code>def</code>\" followed by some name.\n</p>\n\n<code>\n<pre>\n/***************************************************************************\n * swine.c\n * Character-based parser for Swine definitions\n **************************************************************************/\n/* INCLUDE FILES */\n#include \"general.h\"    /* always include first */\n\n#include &lt;string.h&gt;     /* to declare strxxx() functions */\n#include &lt;ctype.h&gt;      /* to define isxxx() macros */\n\n#include \"parse.h\"      /* always include */\n#include \"read.h\"       /* to define file fileReadLine() */\n\n/* DATA DEFINITIONS */\ntypedef enum eSwineKinds {\n    K_DEFINE\n} swineKind;\n\nstatic kindOption SwineKinds [] = {\n    { TRUE, 'd', \"definition\", \"pig definition\" }\n};\n\n/* FUNCTION DEFINITIONS */\n\nstatic void findSwineTags (void)\n{\n    vString *name = vStringNew ();\n    const unsigned char *line;\n\n    while ((line = fileReadLine ()) != NULL)\n    {\n        /* Look for a line beginning with \"def\" followed by name */\n        if (strncmp ((const char*) line, \"def\", (size_t) 3) == 0  &amp;&amp;\n            isspace (line [3]))\n        {\n            const unsigned char *cp = line + 4;\n            while (isspace (*cp))\n                ++cp;\n            while (isalnum (*cp)  ||  *cp == '_')\n            {\n                vStringPut (name, *cp);\n                ++cp;\n            }\n            makeSimpleTag (name, SwineKinds, K_DEFINE);\n            vStringClear (name);\n        }\n    }\n    vStringDelete (name);\n}\n\n/* Create parser definition stucture */\nextern parserDefinition* SwineParser (void)\n{\n    static const char *const extensions [] = { \"swn\", NULL };\n    parserDefinition* def = parserNew (\"Swine\");\n    def-&gt;kinds      = SwineKinds;\n    def-&gt;kindCount  = KIND_COUNT (SwineKinds);\n    def-&gt;extensions = extensions;\n    def-&gt;parser     = findSwineTags;\n    return def;\n}\n</pre>\n</code>\n\n<p>\n<pre>\n<code>\n/***************************************************************************\n * swine.c\n * Regex-based parser for Swine\n **************************************************************************/\n/* INCLUDE FILES */\n#include \"general.h\"    /* always include first */\n#include \"parse.h\"      /* always include */\n\n/* FUNCTION DEFINITIONS */\n\nstatic void installSwineRegex (const langType language)\n{\n    addTagRegex (language, \"^def[ \\t]*([a-zA-Z0-9_]+)\", \"\\\\1\", \"d,definition\", NULL);\n}\n\n/* Create parser definition stucture */\nextern parserDefinition* SwineParser (void)\n{\n    static const char *const extensions [] = { \"swn\", NULL };\n    parserDefinition* def = parserNew (\"Swine\");\n    def-&gt;patterns   = patterns;\n    def-&gt;extensions = extensions;\n    def-&gt;initialize = installSwineRegex;\n    def-&gt;regex      = TRUE;\n    return def;\n}\n</code>\n</pre>\n\n<p>\n<pre>\n/***************************************************************************\n * swine.c\n * Regex callback-based parser for Swine definitions\n **************************************************************************/\n/* INCLUDE FILES */\n#include \"general.h\"    /* always include first */\n\n#include \"parse.h\"      /* always include */\n#include \"read.h\"       /* to define file fileReadLine() */\n\n/* DATA DEFINITIONS */\ntypedef enum eSwineKinds {\n    K_DEFINE\n} swineKind;\n\nstatic kindOption SwineKinds [] = {\n    { TRUE, 'd', \"definition\", \"pig definition\" }\n};\n\n/* FUNCTION DEFINITIONS */\n\nstatic void definition (const char *const line, const regexMatch *const matches,\n                       const unsigned int count)\n{\n    if (count &gt; 1)    /* should always be true per regex */\n    {\n        vString *const name = vStringNew ();\n        vStringNCopyS (name, line + matches [1].start, matches [1].length);\n        makeSimpleTag (name, SwineKinds, K_DEFINE);\n    }\n}\n\nstatic void findSwineTags (void)\n{\n    while (fileReadLine () != NULL)\n        ;  /* don't need to do anything here since callback is sufficient */\n}\n\nstatic void installSwine (const langType language)\n{\n    addCallbackRegex (language, \"^def[ \\t]+([a-zA-Z0-9_]+)\", NULL, definition);\n}\n\n/* Create parser definition stucture */\nextern parserDefinition* SwineParser (void)\n{\n    static const char *const extensions [] = { \"swn\", NULL };\n    parserDefinition* def = parserNew (\"Swine\");\n    def-&gt;kinds      = SwineKinds;\n    def-&gt;kindCount  = COUNT_ARRAY (SwineKinds);\n    def-&gt;extensions = extensions;\n    def-&gt;parser     = findSwineTags;\n    def-&gt;initialize = installSwine;\n    return def;\n}\n</pre>\n\n<p>\n<pre>\n/***************************************************************************\n * make.c\n * Regex-based parser for makefile macros\n **************************************************************************/\n/* INCLUDE FILES */\n#include \"general.h\"    /* always include first */\n#include \"parse.h\"      /* always include */\n\n/* FUNCTION DEFINITIONS */\n\nstatic void installMakefileRegex (const langType language)\n{\n    addTagRegex (language, \"(^|[ \\t])([A-Z0-9_]+)[ \\t]*:?=\", \"\\\\2\", \"m,macro\", \"i\");\n}\n\n/* Create parser definition stucture */\nextern parserDefinition* MakefileParser (void)\n{\n    static const char *const patterns [] = { \"[Mm]akefile\", NULL };\n    static const char *const extensions [] = { \"mak\", NULL };\n    parserDefinition* const def = parserNew (\"Makefile\");\n    def-&gt;patterns   = patterns;\n    def-&gt;extensions = extensions;\n    def-&gt;initialize = installMakefileRegex;\n    def-&gt;regex      = TRUE;\n    return def;\n}\n</pre>\n\n</body>\n</html>\n"
  },
  {
    "path": "old-docs/FAQ",
    "content": "vberthoux@users.sourceforge.netFrequently Asked Questions\n==========================\n\n    * 1.  Why do you call it \"Exuberant Ctags\"?\n    * 2.  Why doesn't my editor work with these tag files?\n    * 3.  What are these strange bits of text beginning with ;\"?\n    * 4.  Why doesn't XEmacs' Speedbar module work with Exuberant Ctags?\n    * 5.  Why doesn't Xemacs correctly locate the tag in the source file?\n    * 6.  Why doesn't NEdit correctly locate the tag in the source file?\n    * 7.  Why can't I jump to \"class::member\"?\n    * 8.  How can I avoid having to specify my favorite option every time?\n    * 9.  Why do I end up on the wrong line when I jump to a tag?\n    * 10.  How do I jump to the tag I want instead of the wrong one by the\n           same name?\n    * 11.  What is \"Vim\"?\n    * 12.  How can I locate all references to a specific function or variable?\n    * 13.  Why does appending tags to a tag file tag so long?\n    * 14.  How do I get regex support for Win32?\n    * 15.  How should I set up tag files for a multi-level directory hierarchy?\n\n  ----------------------------------------------------------------------\n1.  Why do you call it \"Exuberant Ctags\"?\n\nBecause one of the meanings of the word \"exuberant\" is:\n\n    exuberant : produced in extreme abundance : PLENTIFUL syn see PROFUSE\n\nCompare the tag file produced by Exuberant Ctags with that produced by any\nother ctags and you will see how appropriate the name is.\n\n  ----------------------------------------------------------------------\n2.  Why doesn't my editor work with these tag files?\n\n3.  What are these strange bits of text beginning with ;\" which follow\n    many of the lines in the tag file?\n\nThese are \"extension flags\". They are added in order to provide extra\ninformation about the tag that may be utilized by the editor in order to\nmore intelligently handle tags. They are appended to the EX command part of\nthe tag line in a manner that provides backwards compatibility with existing\nimplementations of the Vi editor. The semicolon is an EX command separator\nand the double quote begins an EX comment. Thus, the extension flags appear\nas an EX comment and should be ignored by the editor when it processes the\nEX command.\n\nSome non-vi editors, however, implement only the bare minimum of EX commands\nin order to process the search command or line number in the third field of\nthe tag file. If you encounter this problem, use the option \"--format=1\" to\ngenerate a tag file without these extensions (remember that you can set the\nCTAGS environment variable to any default arguments you wish to supply). Then\nask the supplier of your editor to implement handling of this feature of EX\ncommands.\n\n  ----------------------------------------------------------------------\n4.  Why doesn't XEmacs' Speedbar module work with Exuberant Ctags?\n\nThe default command line switches used by XEmacs for \"etags\" are not\ncompatible with Exuberant Ctags options. By default, Exuberant Ctags installs\na symbolic link, \"etags\", pointing to the ctags executable. When Exuberant\nCtags is started with the name \"etags\", it produces Emacs-style tag files by\ndefault.\n\nTo fix this, add the following lines to your .emacs file, replacing the path\nto \"etags\" with the path where the symbolic link was installed.\n\n(autoload 'speedbar \"speedbar\")\n(setq speedbar-fetch-etags-command \"/usr/local/bin/etags\"\n      speedbar-fetch-etags-arguments '(\"-f\" \"-\"))\n\n  ----------------------------------------------------------------------\n5.  Why doesn't Xemacs correctly locate the tag in the source file?\n\nThis has been observed with version 20.3. It seems that when Xemacs searches\nfor a tag, it searches using the tag name instead of the search string located\nin the TAGS file. This is a bug in Xemacs and does not occur in the GNU\nversion of Emacs.\n\n  ----------------------------------------------------------------------\n6.  Why doesn't NEdit correctly locate the tag in the source file?\n\nVersions of NEdit prior to 5.1 did not support the extended tag file format\ngenerated by Exuberant Ctags by default. Either upgrade to version 5.1 or\nspecify the option \"--format=1\" when running ctags to output the old tag file\nformat.\n\n  ----------------------------------------------------------------------\n7.  Why can't I jump to \"class::member\"?\n\nBecause, by default, ctags only generates tags for the separate identifiers\nfound in the source files. If you specify the --extra=+q option, then\nctags will also generate a second, class-qualified tag for each class member\n(data and function/method) in the form class::member for C++, and in the form\nclass.method for Eiffel and Java.\n\n  ----------------------------------------------------------------------\n8.  How can I avoid having to specify my favorite option every time?\n\nEither by setting the environment variable CTAGS to your custom\noptions, or putting them into a .ctags file in your home directory.\n\n  ----------------------------------------------------------------------\n9.  Why do I end up on the wrong line when I jump to a tag?\n\nBy default, ctags encodes the line number in the file where macro (#define)\ntags are found. This was done to remain compatible with the original UNIX\nversion of ctags. If you change the file containing the tag without\nrebuilding the tag file, the location of tag in the tag file may no longer\nmatch the current location.\n\nIn order to avoid this problem, you can specify the option \"--excmd=p\",\nwhich causes ctags to use a search pattern to locate macro tags. I have\nnever uncovered the reason why the original UNIX ctags used line numbers\nexclusively for macro tags, but have so far resisted changing the default\nbehaviour of Exuberant Ctags to behave differently.\n\n  ----------------------------------------------------------------------\n10.  How do I jump to the tag I want instead of the wrong one by the\n     same name?\n\nA tag file is simple a list of tag names and where to find them. If there\nare duplicate entries, you often end up going to the wrong one because the\ntag file is sorted and your editor locates the first one in the tag file.\n\nStandard Vi provides no facilities to alter this behavior. However, Vim\nhas some nice features to minimize this problem, primarly by examining all\nmatches and choosing the best one under the circumstances. Vim also provides\ncommands which allow for selection of the desired matching tag.\n\n  ----------------------------------------------------------------------\n11.  What is \"Vim\"?\n\nVim is a vi-compatible editor available as source and compilable for any\nplatform. Yeah, I know the first reaction is to shy away from this. But you\nwill never regret getting it, and you will become greatly attached to its\nfeatures, which you can learn gradually. I would be willing to say that it\nis the best vi-clone available within 4 light-years of Alpha Centauri. It\nworks (nearly) exactly like standard vi, but provides some incredibly useful\nextensions (some of which I have participated in designing with the author).\nMost Linux distributions have adopted Vim as its standard vi.\n\n  ----------------------------------------------------------------------\n12.  How can I locate all references to a specific function or variable?\n\nThere are several packages already available which provide this capability.\nNamely, these are: GLOBAL source code tag system, GNU id-utils, cscope,\nand cflow. As of this writing, they can be found in the following locations:\n\nGLOBAL:    http://www.gnu.org/software/global\nid-utils:  http://www.gnu.org/software/idutils/idutils.html\ncscope:    http://cscope.sourceforge.net\ncflow:     ftp://www.ibiblio.org/pub/Linux/devel/lang/c\n\n  ----------------------------------------------------------------------\n13.  Why does appending tags to a tag file tag so long?\n\nSometimes, in an attempt to build a global tag file for all source files in\na large source tree of many directories, someone will make an attempt to run\nctags in append (-a) mode on every directory in the hierarchy. Each time\nctags is invoked, its default behavior is to sort the tag file once the tags\nfor that execution have been added. As the cumulative tag file grows, the sort\ntime increases arithmetically.\n\nThe best way to avoid this problem (and the most efficient) is to make\nuse of the --recurse (or -R) option of ctags by executing the following\ncommand in the root of the directory hierarchy (thus running ctags only once):\n\n        ctags -R\n\nIf you really insist on running ctags separately on each directory, you can\navoid the sort pass each time by specifying the option \"--sort=no\". Once the\ntag file is completely built, use the sort command to manually sort the\nfinal tag file, or let the final invocation of ctags sort the file.\n\n  ----------------------------------------------------------------------\n14.  How do I get regex support for Win32?\n\nYou need to download the GNU regex package for Win32 from the following\nlocation:\n\n    http://people.delphiforums.com/gjc/gnu_regex.html\n\nThen point the makefile macro, REGEX_DIR, found in mk_mvc.mak and mk_bc5.mak,\nto the directory created by extracting this archive.\n\n  ----------------------------------------------------------------------\n15.  How should I set up tag files for a multi-level directory hierarchy?\n\nThere are a few ways of approaching this:\n\n1.  A local tag file in each directory containing only the tags for source\n    files in that directory.\n\n2.  One single big, global tag file present in the root directory of your\n    hierarchy, containing all tags present in all source files in the\n    hierarchy.\n\n3.  A local tag file in each directory containing only the tags for source\n    files in that directory, in addition to one single global tag file\n    present in the root directory of your hierarchy, containing all\n    non-static tags present in all source files in the hierarchy.\n\n4.  A local tag file in each directory of the hierarchy, each one\n    containing all tags present in source files in that directory and all\n    non-static tags in every directory below it (note that this implies\n    also having one big tag file in the root directory of the hierarchy).\n\nEach of these approaches has its own set of advantages and disadvantages,\ndepending upon your particular conditions. Which approach is deemed best\ndepends upon the following factors:\n\nA.  The ability of your editor to use multiple tag files.\n\n    If your editor cannot make use of multiple tag files (original vi\n    implementations could not), then one large tag file is the only way to\n    go if you ever desire to jump to tags located in other directories. If\n    you never need to jump to tags in another directory (i.e. the source\n    in each directory is entirely self-contained), then a local tag file\n    in each directory will fit your needs.\n\nB.  The time is takes for your editor to look up a tag in the tag file.\n\n    The significance of this factor depends upon the size of your source\n    tree and on whether the source files are located on a local or remote\n    file system. For source and tag files located on a local file system,\n    looking up a tag is not as big a hit as one might first imagine, since\n    vi implementations typically perform a binary search on a sorted tag\n    file. This may or may not be true for the editor you use. For files\n    located on a remote file system, reading a large file is an expensive\n    operation.\n\nC.  Whether or not you expect the source code to change and the time it\n    takes to rebuild a tag file to account for changes to the source code.\n\n    While Exuberant Ctags is particularly fast in scanning source code\n    (around 1-2 MB/sec), a large project may still result in objectionable\n    delays if one wishes to keep their tag file(s) up to date on a\n    frequent basis, or if the files are located on a remote file system.\n\nD.  The presence of duplicate tags in the source code and the ability to\n    handle them.\n\n    The impact of this factor is influenced by the following three issues:\n\n    1.  How common are duplicate tags in your project?\n\n    2.  Does your editor provide any facilities for dealing with duplicate\n        tags?\n\n        While standard vi does not, many modern vi implementations, such\n        as Vim have good facilities for selecting the desired match from\n        the list of duplicates. If your editor does not support duplicate\n        tags, then it will typically send you to only one of them, whether\n        or not that is the one you wanted (and not even notifying you that\n        there are other potential matches).\n\n    3.  What is the significance of duplicate tags?\n\n        For example, if you have two tags of the same name from entirely\n        isolated software components, jumping first to the match found\n        in component B while working in component A may be entirely\n        misleading, distracting or inconvenient (to keep having to choose\n        which one if your editor provides you with a list of matches).\n        However, if you have two tags of the same name for parallel builds\n        (say two initialization routines for different hosts), you may\n        always want to specify which one you want.\n\nOf the approaches listed above, I tend to favor Approach 3. My editor of\nchoice is Vim, which provides a rich set of features for handling multiple\ntag files, which partly influences my choice. If you are working with\nsource files on a remote file system, then I would recommend either\nApproach 3 or Approach 4, depending upon the hit when reading the global\ntag file.\n\nThe advantages of Approach 3 are many (assuming that your editor has\nthe ability to support both multiple tag files and duplicate tags). All\nlookups of tag located in the currect directory are fast and the local\ntag file can be quickly and easily regenerated in one second or less\n(I have even mapped a keystroke to do this easily). A lookup of a\n(necessarily non-static) tag found in another directory fails a lookup in\nthe local tag file, but is found in the global tag file, which satisfies\nall cross-directory lookups. The global tag file can be automatically\nregenerated periodically with a cron job (and perhaps the local tag files\nalso).\n\nNow I give an example of how you would implement Approach 3. Means of\nimplementing the other approaches can be performed in a similar manner.\n\nHere is a visual representation of an example directory hierarchy:\n\nproject\n  `-----misccomp\n  |       `...\n  `-----sysint\n          `-----client\n          |       `-----hdrs\n          |       `-----lib\n          |       `-----src\n          |       `-----test\n          `-----common\n          |       `-----hdrs\n          |       `-----lib\n          |       `-----src\n          |       `-----test\n          `-----server\n                  `-----hdrs\n                  `-----lib\n                  `-----src\n                  `-----test\n\nHere is a recommended solution (conceptually) to build the tag files:\n\n1.  Within each of the leaf nodes (i.e. hdrs, lib, src, test) build a tag\n    file using \"ctags *.[ch]\". This can be easily be done for the whole\n    hierarchy by making a shell script, call it \"dirtags\", containing the\n    following lines:\n\n        #!/bin/sh\n\tcd $1\n\tctags *\n\n    Now execute the following command:\n\n        find * -type d -exec dirtags {} \\;\n\n    These tag files are trivial (and extremely quick) to rebuild while\n    making changes within a directory. The following Vim key mapping is\n    quite useful to rebuild the tag file in the directory of the current\n    source file:\n\n        :nmap ,t :!(cd %:p:h;ctags *.[ch])&<CR><CR>\n\n2.  Build the global tag file:\n\n        cd ~/project\n        ctags --file-scope=no -R\n\n    thus constructing a tag file containing only non-static tags for all\n    source files in all descendent directories.\n\n3.  Configure your editor to read the local tag file first, then consult\n    the global tag file when not found in the local tag file. In Vim,\n    this is done as follows:\n\n        :set tags=./tags,tags,~/project/tags\n\nIf you wish to implement Approach 4, you would need to replace the\n\"dirtags\" script of step 1 with the following:\n\n        #!/bin/sh\n\tcd $1\n\tctags *\n\t# Now append the non-static tags from descendent directories\n\tfind * -type d -prune -print | ctags -aR --file-scope=no -L-\n\nAnd replace the configuration of step 3 with this:\n\n        :set tags=./tags;$HOME,tags\n\nAs a caveat, it should be noted that step 2 builds a global tag file whose\nfile names will be relative to the directory in which the global tag file\nis being built. This takes advantage of the Vim 'tagrelative' option,\nwhich causes the path to be interpreted a relative to the location of the\ntag file instead of the current directory. For standard vi, which always\ninterprets the paths as relative to the current directory, we need to\nbuild the global tag file with absolute path names. This can be\naccomplished by replacing step 2 with the following:\n\n        cd ~/project\n\tctags --file-scope=no -R `pwd`\n\n--\n"
  },
  {
    "path": "old-docs/INSTALL",
    "content": "Custom Installation\n===================\n\nThese installation instructions are for Unix or Unix-like platforms (or at\nleast, those platforms which are able to run a Bourne shell script). If you\nare attempting to install Exuberant Ctags on some other platform, see the file\nINSTALL.oth.\n\nIf you are not familiar with using the configure scripts generated by GNU\nautoconf, read the \"Basic Installation\" section below; then return here.\nThe configure script in this package supports the following custom options:\n\n  --disable-etags               By default, \"make install\" will install one\n                                binary, \"ctags\", one man page, \"ctags.1\", and\n                                create links to these two files by the names\n                                \"etags\" and \"etags.1\". If you do not want to\n                                install the \"etags\" links, use this option.\n\n  --disable-extended-format     Ctags now appends \"extension flags\" to the\n                                end of each tag entry in a manner which is\n                                backwards with original Vi implementation\n                                (they are placed into an EX comment). This\n                                can be disabled via use of the ctags --format\n                                option. This configure option changes the\n                                default behavior of ctags to disable use of\n                                these extension flags (i.e. use the original\n                                tag file format).\n\n  --disable-external-sort       Use this option to force use of an internal\n                                sort algorithm. On UNIX-like systems, ctags\n                                uses the sort utility of the operating system\n                                by default because it is more memory efficient.\n\n  --enable-custom-config=FILE   Defines a custom option configuration file to\n                                establish site-wide defaults. Ctags will read\n                                the following files at startup for options:\n                                /etc/ctags.conf, /usr/local/etc/ctags.conf,\n                                $HOME/.ctags, and .ctags. If you need a\n                                different file, set this option to the full\n                                path name of the file you want to be read, and\n                                it will be read immediately before reading\n                                $HOME/.ctags.\n\n  --enable-macro-patterns       By default, line numbers are used in the tag\n                                file for #define objects, in order to remain\n                                compatible with the original UNIX ctags. This\n                                option will make the default use patterns.\n\n  --enable-maintainer-mode      Creates a special GNU-specific version of the\n                                makefile which is used to maintain Exuberant\n                                Ctags.\n\n  --enable-tmpdir=DIR           When the library function mkstemp() is\n                                available, this option allows specifying the\n                                default directory to use for temporary files\n                                generated by ctags. This default can be\n                                changed at run time by setting the environment\n                                variable TMPDIR.\n\nIf you wish to change the name of the installed files, edit the makefile\nproduced by the configure script (\"Makefile\") before performing the \"make\ninstall\" step. There are two lines at the top of the file where the names of\nthe installed files may be customized.\n\n\nBasic Installation\n==================\n\n   These are generic installation instructions.\n\n   The `configure' shell script attempts to guess correct values for\nvarious system-dependent variables used during compilation.  It uses\nthose values to create a `Makefile' in each directory of the package.\nIt may also create one or more `.h' files containing system-dependent\ndefinitions.  Finally, it creates a shell script `config.status' that\nyou can run in the future to recreate the current configuration, a file\n`config.cache' that saves the results of its tests to speed up\nreconfiguring, and a file `config.log' containing compiler output\n(useful mainly for debugging `configure').\n\n   If you need to do unusual things to compile the package, please try\nto figure out how `configure' could check whether to do them, and mail\ndiffs or instructions to the address given in the `README' so they can\nbe considered for the next release.  If at some point `config.cache'\ncontains results you don't want to keep, you may remove or edit it.\n\n   The file `configure.in' is used to create `configure' by a program\ncalled `autoconf'.  You only need `configure.in' if you want to change\nit or regenerate `configure' using a newer version of `autoconf'.\n\nThe simplest way to compile this package is:\n\n  1. `cd' to the directory containing the package's source code and type\n     `./configure' to configure the package for your system.  If you're\n     using `csh' on an old version of System V, you might need to type\n     `sh ./configure' instead to prevent `csh' from trying to execute\n     `configure' itself.\n\n     Running `configure' takes awhile.  While running, it prints some\n     messages telling which features it is checking for.\n\n  2. Type `make' to compile the package.\n\n  3. Optionally, type `make check' to run any self-tests that come with\n     the package.\n\n  4. Type `make install' to install the programs and any data files and\n     documentation.\n\n  5. You can remove the program binaries and object files from the\n     source code directory by typing `make clean'.  To also remove the\n     files that `configure' created (so you can compile the package for\n     a different kind of computer), type `make distclean'.\n\nCompilers and Options\n=====================\n\n   Some systems require unusual options for compilation or linking that\nthe `configure' script does not know about.  You can give `configure'\ninitial values for variables by setting them in the environment.  Using\na Bourne-compatible shell, you can do that on the command line like\nthis:\n     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure\n\nOr on systems that have the `env' program, you can do it like this:\n     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure\n\nCompiling For Multiple Architectures\n====================================\n\n   You can compile the package for more than one kind of computer at the\nsame time, by placing the object files for each architecture in their\nown directory.  To do this, you must use a version of `make' that\nsupports the `VPATH' variable, such as GNU `make'.  `cd' to the\ndirectory where you want the object files and executables to go and run\nthe `configure' script.  `configure' automatically checks for the\nsource code in the directory that `configure' is in and in `..'.\n\n   If you have to use a `make' that does not supports the `VPATH'\nvariable, you have to compile the package for one architecture at a time\nin the source code directory.  After you have installed the package for\none architecture, use `make distclean' before reconfiguring for another\narchitecture.\n\nInstallation Names\n==================\n\n   By default, `make install' will install the package's files in\n`/usr/local/bin', `/usr/local/man', etc.  You can specify an\ninstallation prefix other than `/usr/local' by giving `configure' the\noption `--prefix=PATH'.\n\n   You can specify separate installation prefixes for\narchitecture-specific files and architecture-independent files.  If you\ngive `configure' the option `--exec-prefix=PATH', the package will use\nPATH as the prefix for installing programs and libraries.\nDocumentation and other data files will still use the regular prefix.\n\n   In addition, if you use an unusual directory layout you can give\noptions like `--bindir=PATH' to specify different values for particular\nkinds of files.  Run `configure --help' for a list of the directories\nyou can set and what kinds of files go in them.\n\nOptional Features\n=================\n\n   Some packages pay attention to `--enable-FEATURE' options to\n`configure', where FEATURE indicates an optional part of the package.\nThey may also pay attention to `--with-PACKAGE' options, where PACKAGE\nis something like `gnu-as' or `x' (for the X Window System).  The\n`README' should mention any `--enable-' and `--with-' options that the\npackage recognizes.\n\nSharing Defaults\n================\n\n   If you want to set default values for `configure' scripts to share,\nyou can create a site shell script called `config.site' that gives\ndefault values for variables like `CC', `cache_file', and `prefix'.\n`configure' looks for `PREFIX/share/config.site' if it exists, then\n`PREFIX/etc/config.site' if it exists.  Or, you can set the\n`CONFIG_SITE' environment variable to the location of the site script.\nA warning: not all `configure' scripts look for a site script.\n\nOperation Controls\n==================\n\n   `configure' recognizes the following options to control how it\noperates.\n\n`--cache-file=FILE'\n     Use and save the results of the tests in FILE instead of\n     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for\n     debugging `configure'.\n\n`--help'\n     Print a summary of the options to `configure', and exit.\n\n`--quiet'\n`--silent'\n`-q'\n     Do not print messages saying which checks are being made.  To\n     suppress all normal output, redirect it to `/dev/null' (any error\n     messages will still be shown).\n\n`--srcdir=DIR'\n     Look for the package's source code in directory DIR.  Usually\n     `configure' can determine that directory automatically.\n\n`--version'\n     Print the version of Autoconf used to generate the `configure'\n     script, and exit.\n\n`configure' also accepts some other, not widely useful, options.\n\n"
  },
  {
    "path": "old-docs/INSTALL.oth",
    "content": "If you are attempting to install Exuberant Ctags on a Unix-like platform\n(one that can at least run a Bourne shell script) see the file INSTALL.\n\nInstallation Notes\n==================\n\nFor non-Unix platforms, simple makefiles are provided:\n\n    mk_mingw.mak  For Win32 using MinGW\n    mk_mvc.mak    For Win32 using Microsoft Visual C++\n"
  },
  {
    "path": "old-docs/MAINTAINERS",
    "content": "The following individuals are registered as developers for the maintenance of\nExuberant Ctags. They are listed by their SourgeForge username and by the\nTo send email to any one of them, send it to <username@users.sourceforge.net>.\n\nCtags           SourgeForge     Full\nParser          username        Name\n----------      -----------     -----\nAnt             dfishburn       David Fishburn\nAWK             jkoshy          Joseph Koshy\nBasic           elias           Elias Pschernig\nC#              elliotth        Elliott Hughes\nDosBatch        dfishburn       David Fishburn\nFlex            dfishburn       David Fishburn\nJava            elliotth        Elliott Hughes\nJavaScript      dfishburn       David Fishburn\nMATlAB          dfishburn       David Fishburn\nObjective-C     aeruder         Andrew Ruder\nOCaml           vberthoux       Vincent Berthoux\nPerl            perlguy0        Dmitri Tikhonov\nPHP             jafl            John Lindal\nPython          elias           Elias Pschernig\nRuby            elliotth        Elliott Hughes\nSML             jkoshy          Joseph Koshy\nSQL             dfishburn       David Fishburn\nTeX             dfishburn       David Fishburn\nVim             dfishburn       David Fishburn\nAll else        dhiebert        Darren Hiebert\n\nHow To Build & Test Like A Maintainer\n=====================================\n\nPrerequisites\n-------------\n\n  Debian/Ubuntu:\n\n    sudo apt-get install build-essential subversion autoconf\n\n  Mac OS:\n\n    Install the Xcode developer tools, available here:\n    http://developer.apple.com/tools/download/\n\n  Fedora:\n\n    yum install subversion autoheader autoconf\n\n  Windows:\n\n    Install Cygwin plus its Subversion and GNU Make packages.\n\nBuilding\n--------\n\n  First time:\n\n    git clone git://github.com/universal-ctags/ctags.git\n    cd ctags\n    autoheader\n    autoconf\n    ./configure --enable-maintainer-mode\n    make -j\n\n  Later:\n\n    cd ctags\n    git pull\n    make -j\n\nTesting\n-------\n\n  cd ctags\n  make units\n"
  },
  {
    "path": "old-docs/NEWS.exuberant",
    "content": "Current Version: @VERSION@\n\nctags-@VERSION@ (@DATE@)\n* Added support for code loaded by AutoLoader and SelfLoader [Perl].\n* Fixed parsing of inline docs: support encoding POD word [Perl].\n* Added support for constants declared via hash reference [Perl].\n* Added support for new \"attached\" and \"detachable\" keywords [Eiffel].\n* Fixed parsing of comments after import statements and other tags, contributed by Huandari Lopez to Geany [Python].\n* Fixed PHP parser to ignore keywords inside comments [PHP, Bug #1795926].\n* Fixed regular expressions for Ant so they won't span multiple tags [Ant].\n* Fixed infinite loop with malformed Makefiles, contributed by Martin Dorey [Make, Bug #2959889].\n* Fixed Verilog parameter parsing, contributed by Nicolas Vincent [Verilog, Patch #2747828].\n* Fixed error when parsing empty file [OCaml].\n* Fixed problem detecting function definitions using circumflexes for MS.NET managed types. [C++]\n* Fixed bug caused by use of strlen() where strings overlapped.\n* Enabled Large File System support. [Bug #3062068]\n\nctags-5.8 (09 Jul 2009)\n* Removed \".ml\" as a Lisp extension (now OCaml) [Lisp].\n* Added support for Ant language, contributed by David Fishburn.\n* Added support for DOS Batch language, contributed by David Fishburn.\n* Added support for Flex (Adobe) language, contributed by David Fishburn.\n* Added support for MATLAB language, contributed by David Fishburn.\n* Added support for Objective Camel (OCaml), provided by Vincent Berthoux [Patch #2738723].\n* Added support for TeX language, contributed by David Fishburn.\n* Added support for VHDL language, contributed by Nicolas Vincent [Bug #1943306].\n* Added support for Pyrex/Cython declarations [Python].\n* Added support for \"v\" kind, for variables [Python].\n* Added support for class and member variables [PHP, Bug #1037086].\n* Added support for recent enhancements to Eiffel language [Eiffel].\n* Added support for ASP classes, contributed by Zendhi Nagao; changes meaning of 'c' kind flag [ASP].\n* Added regex support when compiling with MinGW. Gnu regex module now included in all distributions.\n* Fixed detection of triple strings inside other strings [Python, Bug #1988130].\n* Fixed an endless loop with comments in triple strings [Python, Bug #1988027].\n* Fixed bug where functions were sometimes seen as methods [Python, Bug #1988026].\n* Fixed parsing of method parameter annotations, fix contributed by Paolo \"blaisorblade\" Giarrusso [Java, Bug #2049723, #2117073].\n* Fixed parsing of global scope qualifiers in base class lists [C++, Bug #1799343].\n* Fixed bug where namespace members were given kinds corresponding to globals [C++, Bug #1924919, #1575055].\n* Fixed parsing of \"else\" [C#, Bug #1830344].\n* Fixed parsing of derived enums [C#, Bug #1515910].\n* Fixed parsing of \"foreach\" [C#, Bug #1830343].\n* Fixed parsing of simple generic classes [C#, Bug #1515910].\n* Fixed bug with detecting identifiers inside variables [Python, Bug #1809024].\n* Fixed bug with detecting identifiers at the start of variables [Python, Bug #1856363].\n* Fixed parsing of triple single-quoted multi-line strings [Python, Bug #1906062].\n* Changed to newer version of autoconf, changing configure.in to configure.ac.\n\nctags-5.7 (04 Sep 2007)\n* Added support for DIM AS [Freebasic, Bug #1741778].\n* Added support for arbitrary nesting depth [Python, Bug #1684786, Debian bug #409078].\n* Added support for verbatim string literals [C#, Bug #1515910].\n* Added support for .ctags as well as ctags.cnf on Windows [Bug #1246506].\n* Added support for non-extern, non-static functions returning wchar_t, contributed by Aaron Peromsik [C++, Patch #1458930].\n* Added support for numerous revision control systems including Bazaar and Mercurial [Bug #1472894].\n* Added support for enums [Java, Bug #1730485, Bug #1517143, Patch #1027395, Patch #1528507].\n* Added support for multiple-level namespace declarations [C#].\n* Added .svn to list of directories ignored during recursion (--recurse).\n* Added support for BlitzBasic, PureBasic and FreeBasic [FR #1100506].\n* Added support for interfaces and static/public/protected/private functions [PHP].\n* Added support for 'package' keyword [Perl].\n* Added support for multi-line subroutine, package, and constant definitions [Perl].\n* Added support for optional subroutine declarations [Perl].\n* Added support for formats [Perl].\n* Added support for new convert keyword [Eiffel].\n* Added optional tags for forward variable declarations (e.g. 'struct C;') [C, C++].\n* Changed parsing of option input file (-L) to strip trailing white space.\n* Ignore comments mixed into definitions and declarations [Perl].\n* Fixed detecting labels with whitespace after label name [Perl, Bug #1752361]\n* Fixed parsing of generic classes/interfaces [Java, Bug #1447756].\n* Fixed misidentification of fully qualified function calls as labels [Perl].\n* Fixed parsing of inner classes [Python, Bug #1411963].\n* Fixed line continuation [Python, Bug #928001, Patch #819471].\n* Fixed parsing of annotations [Java, Bug #1691412].\n* Fixed block-comment parsing [Verilog, Patch #1458042, Bugs #960316, #1111214, #1606569, #1615060].\n* Fixed typo in man page [Debian bug #366412].\n* Fixed missing chunk of text in man page and over-use of hyphens in UTF-8 locales [Debian bug #271323].\n* Fixed parsing of ` as a method name [Ruby].\n* Fixed parsing of keywords in string literals [Ruby, Bug #1742588].\n* Fixed potential segmentation violation [Bug #1672834, Bug #1222926].\n* Fixed parsing of destructors with whitespace after the '~' [C++, Bug #1585745].\n* Fixed default access of unions to be public [C++, Bug #1548443].\n* Fixed various memory leaks, mostly contributed by Dmitry Antipov.\n* Fixed parsing of `define [Verilog, Bug #961001].\n* Fixed crashes involving '/' [Verilog, Bug #1743330].\n* Fixed compilation problem on MinGW [Bug #1517424].\n* Fixed generation of HTML-formatted man page [Bug #1645864].\n* Fixed recognition of Python scripts having '#!/usr/bin/python' as first line [Bug #1764148].\n* Fixed parsing of Fortran comment-to-end-of-line with no newline before EOF [Debian bug #432872].\n* Fixed parsing of << [C/C++, Bugs #1020715, #1093123, #1770479, #1770607].\n* Fixed parsing of fully-qualified type names [Java, Bug #814263].\n* Fixed handling of lone carriage-return characters in file [Bug #1773926].\n\nctags-5.6 (Mon May 29 2006)\n* Reformatted code for independence of tab stop setting.\n* Changed default configuration to disable installation of etags links.\n* Changed --langmap to first unmap each supplied extension from other languages.\n* Added support for ASP constants [ASP, Patch #961842].\n* Added support for GNU make extensions [Make].\n* Added .mk as extension recognized as a make language file [Make].\n* Added missing help for list-maps options [Bug #1201826].\n* Added new extension field \"typeref\" [thanks to Bram Moolenaar].\n* Extended functionality of Ruby parser with patch from Elliott Hughes [Ruby].\n* Fixed creation of TAGS file with etags-include but no files [Bug #941233].\n* Fixed problem reading last line of list file (-L) without final newline.\n* Fixed infinite loop that could occur on files without final newline [C, Java].\n* Fixed incorrect tag for first field of table [SQL].\n* Fixed missing tags for functions beginning with underscore [Sh].\n* Fixed missing tags for functions with variable arg list [C, Bug #1201689].\n* Fixed parsing problem with parentheses in argument list [C, Bug #1085585].\n* Fixed problem in preprocessor directive handling [C, Bug #1086609].\n\nctags-5.5.4 (Thu Mar 25 2004)\n* Fixed broken -R option.\n\nctags-5.5.3 (Sun Mar 14 2004)\n* Removed forgotten debug statement [Bug #811704].\n* Added support for Perl labels.\n* Added support for Perl \"use constant\" [Perl, Patch #853704, Feature Request\n  #710017].\n* Added support for package qualification of tags, removing useless \"package\"\n  tag kind [Perl, Feature Request #448887].\n* Added support for \"and\" keyword [SML, Bug #816636].\n* Added support for variables [PHP].\n* Fixed problem destroying tag file with certain info options [Bug #845502].\n* Fixed portability problem [DJGPP].\n* Fixed problem of double characters in signature field [C, Bug #852368].\n* Fixed problem manifested by errant preprocessor conditionals [Bug #839162].\n* Fixed incorrect line address in tag file for SQL tags [SQL, Bug #823000].\n* Fixed incorrect recognition of POD paragraph [Perl, Bug #842077].\n* Fixed spurious tags for for C++ member templtates [C++, Bug #849591].\n* Fixed missing tags related to template specializations [C++, Bug #872494].\n* Fixed spurious local tags for statements following labels [C].\n* Fixed missing tags for certain scoped functions [Vim].\n* Fixed infinite loop in Fortran parser.\n* Fixed missing tags for certain initializers [Fortran, Bug #877956].\n* Fixed problem with comment line after continuation character [Fortran,\n  Bug #858165].\n\nctags-5.5.2 (Wed Sep 17 2003)\n* Added tags for local variables for C-based languages [C/C++/C#/Java/Vera,\n  Feature Request #449503].\n* Fixed compilation problem due to type change made to accomodate change of\n  return type of _findfirst() in VisualStudio.Net [Win32, Bug #775789].\n* Fixed problems with certain bit fields.\n\nctags-5.5.1 (Wed Jul 30 2003)\n* Changed supported tag kinds for Verilog parser during overhaul.\n* Restored exit of program after --help, --license, and --version options [Bug\n  #717311, #751240].\n* Removed inclusion of general.h (GPL) from readtags.c (public domain).\n* Added support for tags for labels [PL/SQL].\n* Added support for tags for constant definitions [PHP].\n* Fixed redundant parsing of configuration file [Windows, Bug #768814].\n* Fixed missing tags for definitions spanning lines [Verilog, Bug #762027].\n* Fixed compilation error for uncommon hosts.\n* Fixed missing tags for Korn shell specific function definitions. [Sh,\n  Bug #769184]\n* Fixed missing tags when semicolon separator appears [Fortran, Bug #734933].\n* Fixed missing tags when endsubroutine keyword appears [Fortran, Bug #726712].\n* Fixed problem with fixed-form line continuation following comment [Fortran,\n  Bug #726875].\n* Fixed missing tags for nested blocks [PL/SQL, Bug #722501].\n* Fixed missing tags for function typedefs [C].\n* Fixed inability to map empty extension when path contained dot [Bug #742689].\n\nctags-5.5 (Tue Apr 1 2003)\n* Changed kind indicator for methods from 'f' to 'm' [Tcl].\n* Changed tags within interfaces to be disabled by default (like prototypes in\n  C/C++) [Fortran].\n* Removed explicit descriptions of individual --<LANG>-types options from\n  --help output. See new --list-languages and --list-kinds options.\n* Removed explicit list of supported languages and supported tag kinds and\n  mapping patterns from man page. See new --list-languages, --list-kinds, and\n  --list-maps options.\n* Renamed --<LANG>-types option to --<LANG>-kinds (still accepts old name).\n* Added --list-kinds option.\n* Added --list-maps option.\n* Added --list-languages option.\n* Added support for dimensioned variables, contributed by Simon Bohlin [ASP].\n* Added support for C# language.\n* Added support for Erlang language, contributed by Brent Fulgham.\n* Added support for HTML language files.\n* Added support for JavaScript language files.\n* Added support for SML (Standard ML) language, contributed by Venkatesh Prasad.\n* Added mapping for .plx to Perl.\n* Added tags for autocommand groups [Vim, Patch #664685].\n* Added support for numerous language extensions [Fortran].\n* Added '$', 'D', and 'd' in column 1 as comment characters [Fortran].\n* Added special handling of --options=NONE to disable automatic reading of\n  options from configuration files or environment.\n* Added check for case-insensitive filenames to configure.\n* Fixed problem with lower case <SID> tag [Vim, Bug #657327].\n* Fixed problem recognizing indented code [Vim, Patch #664685].\n* Fixed problem with infinite loop in certain comments [PL/SQL, Bug #629115].\n* Fixed problem of incorrect extension field [C, Bug #639639].\n* Fixed problem of empty scoping extension field [C, Bug #639644].\n* Fixed missing tags for functions split across lines [PHP, Bug #681824].\n* Fixed missing tags for nested subprograms using 'contains' [Fortran,\n  Bug #670433].\n* Fixed missing tags when variable has same name as keyword [Fortran].\n* Fixed spurious tag when an array-spec occurs within an entity-decl [Fortran].\n* Fixed mishandling of multiline raw strings [Python, Bug #699171].\n* Fixed missing scope extension field on namespaces [C++, C#, Bug #665086].\n* Fixed several bugs causing missed tags [Fortran].\n* Fixed problem with --langmap option preventing clearing of map [Bug #688442].\n* Fixed recognition of Unicode-8 characters [Java].\n* Fixed man page errors and omissions.\n* Fixed bug in readFieldValue() in readtags library.\n* Fixed bug in option parsing in readtags command-line program.\n* Fixed portability problems with DJGPP [Bug #692569].\n* Fixed portability problems with Cygwin.\n\nctags-5.4 (Thu Oct 17 2002)\n* Improved ability for tagsOpen() in readtags library to report failure to\n  open tag file, adding new fields to tagFileInfo structure.\n* Improved Cobol support to include data, files, groups, and sections [Cobol].\n* Added '$' a valid character for C identifier [VMS].\n* Added support for recording routine argument declarations for C-like\n  languages. See the --fields option and man page section TAG FILE FORMAT for\n  more information [C, C++, Java].\n* Added class and method support to TCL parser [TCL].\n* Added support for PL/SQL language.\n* Added support for Vera language, inspired by Dave Eggum [Vera].\n* Fixed problem terminating Perl POD block [Perl, Bug #612621].\n* Fixed problem re whitespace preceding subprogram name [Pascal, Bug #612019].\n* Fixed problem with leading spaces before instruction [TCL, Bug #615928].\n* Fixed problem with double precision functions [Fortran, Bug #620288].\n* Fixed inverted test causing TMPDIR to be used for temporary files when\n  ctags is setuid instead of when not setuid [Bug #623713].\n\nctags-5.3.1 (Thu Sep 12 2002)\n* Renamed tagsSetSorted() to tagsSetSortType() and \"sorted\" member of\n  tagFileInfo structure of readtags library to \"sort\".\n* Added new function, tagsFirst() to readtags library.\n* Fixed incorrect tag kinds [Verilog].\n* Fixed null tags for unnamed BLOCK DATA statements [Fortran].\n* Fixed missing tags for function preceded by \"<SID>\" [Vim].\n* Fixed missing tags for equate statements not in column 1 [Asm, Bug #538629].\n* Fixed Ruby parser (why didn't the compiler report my screw-up?) [Ruby].\n\nctags-5.3 (Wed Jul 17 2002)\n* Allowed --etags-include option without input files.\n* Changed Asm parser to back to C-based parser to remove redundant tags,\n  and extending its support for more variants [Asm].\n* Changed to using _tempnam() to create temporary files on Windows, allowing\n  \"TMP\" environment variable to set temporary directory.\n* Changed the -x output to match that of traditional ctags when the --format=1\n  option is supplied. The new format was also changed slightly to conform more\n  closely to the original format, with the addition of the extra tag type field.\n* Added support for Verilog language, submitted by Nam SungHyun.\n* Added support for RISC OS platform, contributed by Andrew Wingate.\n* Added support for \"#pragma weak\", generating macro tags for weak symbols [C].\n* Added support for mixins and class methods to Ruby parser, submitted by\n  Matthias Veit [Ruby].\n* Added support to ctags and readtags library for case-folded sorting of tag\n  files, submitted by Flemming Madsen.\n* Added identification of class methods [Python].\n* Fixed portability problems [Bugs #541997, #571240].\n* Fixed bug in configure script [Solaris, Bug #542966].\n* Fixed invalid package name tags [Perl, Bug #535068].\n* Fixed failure to output relative paths into etags TAGS files on Win32\n  [Bug #568365].\n* Fixed incorrect line address in cases of line continuation [Fortran].\n* Fixed missing tags for certain cases of invalid syntax [C].\n* Fixed missing tags in Fortran with HPF extensions [Fortran, Bug #565813].\n* Fixed spurious tag for clients portion of feature clause when following\n  an empty feature clause [Eiffel].\n\nctags-5.2.3 (Sun Feb 24 2002)\n* Fixed portability problem in makefile [Solaris, FreeBSD].\n* Fixed infinite loop for certain cases of invalid syntax [Eiffel].\n* Changed Asm parser to regex, extending its support for more variants [Asm].\n\nctags-5.2.2 (Sat Feb 16 2002)\n* Fixed spurious tags following empty feature clause [Eiffel].\n* Fixed missing tags for classes specifying generic creation routine [Eiffel].\n* Fixed missing tags when label not followed by white space [YACC].\n* Fixed for portability [Solaris, MacOS X].\n* Added support for type reference tool [Eiffel].\n\nctags-5.2.1 (Sun Jan 20 2002)\n* Portability fixes [Mingw32].\n* Added \"RCS\" and \"CVS\" to list of directories excluded by default.\n* Fixed missing tags for function pointers declared const or volatile\n  [C, Bug #503764].\n\nctags-5.2 (Sun Dec 23 2001)\n* Portability fixes [HP-UX, Solaris, VMS, OS/2].\n* Made code compilable by a C++ compiler.\n* Changed reading of option files to ignore blank lines.\n* Changed and enhanced interface to readtags library (see readtags.h).\n* Changed from using addLanguageRegex() to addTagRegex() in regex-based\n  parsers.\n* Added support for Lua language, submitted by Max Ischenko.\n* Added instructions to man page on using tags with NEdit.\n* Added setargv.obj to link for wildcard expansion [MSVC].\n* Added capability to have regex invoke a callback in a regex parser.\n* Fixed regex tag problem which left newlines in back-references.\n* Fixed missing class-qualified tags [Eiffel].\n* Fixed spurious tags for entries in final indexing clause [Eiffel].\n* Fixed problem with invalid filenames in preprocessor line directives.\n* Fixed bug parsing scoped variables (e.g. \"b:variable\") [Vim, Bug #487608].\n* Fixed problem compiling readtags.c on some hosts.\n* Fixed memory overwrite problem in readtags library.\n\nctags-5.1 (Tue Nov 06 2001)\n* Changed name of option configuration files for MSDOS, MSWindows, and OS/2.\n* Changed regex support to enforce REG_NEWLINE. This fixes problem where the\n  newline character was explicity being matched by user patterns [Bug #431477].\n* Added new public domain library for reading tag files (see readtags.h).\n* Added support for variables and namespaces, provided by Jay Glanville [Vim].\n* Added report of non-options in option configuration files and CTAGS\n  environment variable.\n* Added support for YACC language, submitted by Nick Hibma [YACC].\n* Added support for Perl packages, submitted by Nick Hibma [Perl].\n* Added '$' as valid identifier character for DEC C compiler [VMS, Bug #425147].\n* Added compilation date and time to --version output.\n* Added configure check for HP-UX to determine if ANSI options needed [HP-UX].\n* Removed tags for forward class/struct declarations [C/C++, Bug #432563].\n* Eliminated ;\" separator from end of tag line when no extension fields are\n  present.\n* Fixed segmentation violation for some Lisp files [Lisp].\n* Fixed segmentation violation occurring when file referenced in #line\n  directive was from an unknown language.\n* Fixed loss of sync when parsing bit fields named with C++ reserved word [C].\n* Fixed compilation problem on gcc-2.7.2.\n* Fixed problem parsing verbatim strings [Eiffel].\n* Fixed problem with PHP references [PHP].\n* Fixed handling of Perl __DATA__ sections [Perl].\n* Fixed problem resulting from white space in tag name due to regex name\n  specifier.\n* Fixed double reading of $HOME/.ctags when current directory is $HOME.\n* Fixed problem reading option configuration files using CR-LF newlines.\n* Fixed problem preventing output control over tag kinds of regex patterns\n  [Bug #429869]\n* Fixed incorrect parsing of Vim functions with ':' modifiers [Bug #466517].\n\nctags-5.0.1 (Sun Apr 15 2001)\n* Fixed problem checking recursive links [SunOS 4.x].\n* Improved security on hosts where mkstemp() is not available.\n\nctags-5.0 (Sun Mar 18 2001)\n* Restructured code to simplify support for new language parsers.\n* Changed source code to use ANSI-style function definitions.\n* Changed scope-qualified tag entries to omit enumeration name [C/C++].\n* Changed reading of files supplied to -I option to read one token per line.\n* Changed reading of option files to read one argument per line.\n* Changed default extension fields, now controlled by new option --fields.\n* Changed detection of etags invocation to accept any name containing \"etags\".\n* Removed -p option, which only caused confusion and is rendered obsolete by\n  the change immediately above.\n* Removed 'A' flag to the --c-types, --eiffel-types, and --java-types\n  options, replacing its functionality with the new --fields option.\n* Removed 'C' flag to the --c-types, --eiffel-types, and --java-types\n  options, replacing its functionality with the new --extra option.\n* Deprecated -i option, which was long ago replaced with the --c-types option.\n* Deprecated --file-tags option, now incorporated into new --extra option.\n* Deprecated --kind-long option, now incorporated into new --fields option.\n* Renamed --lang[uage] option to --language-force.\n* Renamed makefiles for non-Unix platforms.\n* Improved parsing of assembly language files [Asm].\n* Improved parsing of Fortran language files, adding new tag kinds [Fortran].\n* Added documentation explaining how to extend ctags with new parsers.\n* Added support for regular expressions, using either Posix or Gnu interface.\n* Added support for mapping file names to languages using shell patterns.\n* Added support for ASP scripts, submitted by Patrick Dehne [ASP].\n* Added support for Makefiles [Make].\n* Added support for Pascal language [Pascal].\n* Added support for PHP scripts, submitted by Jesus Castagnetto [PHP].\n* Added support for REXX language [REXX], based on submission by Alexaner Mai.\n* Added support for Ruby, submitted by Thaddeus Covert [Ruby].\n* Added support for S-Lang, submitted by Francesc Rocher [SLang].\n* Added support for Macintosh platform using MPW (by Maarten Hekkelman).\n* Added .tk as recognized extension [Tcl].\n* Added .cp and .hp as C++ extensions [C++].\n* Added .zsh as shell script extension [Sh].\n* Added support for trigraphs for C-based languages [C/C++].\n* Added language recognition for shell scripts using \"#!/usr/bin/env command\".\n* Added check for recursive directory links.\n* Added support for \"[\" form of verbatim strings [Eiffel].\n* Added --exclude option to exclude directories while recursing.\n* Added --fields option to specify extension fields to include in output.\n* Added --extra option to allow control over extra tags.\n* Added --regex-<LANG> option to define language-specific regular expressions.\n* Added --<LANG>-types options for all supported languages.\n* Added --langdef option to define new languages to be parsed with regex.\n* Added --languages option to restrict set of languages scanned for tags.\n* Added --tag-relative option to make file paths recorded in tag file relative\n  to location of tag file itself instead of the current working directory when\n  file arguments are specified using relative paths.\n* Added restriction of permissions of created temporary files when mkstemp()\n  is not available for security.\n* Reimplemented line directive handling to work for all languages.\n* Fixed tag generation for packages [Java].\n* Fixed Lisp parser [Lisp].\n* Fixed Mingw32 port [Win32].\n* Fixed bug in procedure name parsing [Tcl].\n* Fixed bug resulting in wrong column being checked for paragraphs [Cobol].\n* Fixed bug in language dispatch for executable \"#!\" scripts [Unix].\n* Fixed bugs resulting in incorrect scope entries in tag file [C++/Java].\n* Fixed warning caused by reinstallation of etags link [Unix].\n* Fixed destruction of existing tag file when no files supplied on invocation.\n* Fixed problem in Makefile.in which prevented configuring and building in\n  non-source directory. Also changed Makefile.in to generate and use correct\n  object and executable file extensions when run on Win32.\n\nctags-4.0.3 (Sun Jul 16 2000)\n* Fixed compiler warnings [Amiga].\n* Fixed problem in configure.in causing struct stat st_ino member test to fail.\n* Fixed problem with TAGS entries for files using DOS-style (CR-LF) new lines.\n* Improved algorithm for locating Perl functions and skipping pods.\n* Improved algorithm for locating shell functions [Sh].\n* Renamed Makefile.amiga to Makefile.manx [Amiga].\n* Added Makefile.sas for SAS C compiler [Amiga].\n* Updated Makefile.qdos [QDOS].\n* Improved support for DECC compiler [VAX].\n\nctags-4.0.2 (Mon Jul 10 2000)\n* Now silently ignore -w option for backwards compatibility with SVR4 ctags.\n* Fixed bug resulting in no extension flags when using --kind-long option.\n\nctags-4.0.1 (Wed Jun 28 2000)\n* Fixed segmentation violation when using --file-tags.\n\nctags-4.0 (Thu Jun 22 2000)\n* Fixed infinite loop on certain syntactically invalid class constructs [C++].\n* Fixed problem of incorrect tags for some pure virtual functions [C++].\n* Fixed inability to clear all tag types when using --c-types= (all languages).\n* Fixed problem of arguments to parameterized class being reported as\n  ancestors in the \"inherits\" extension flag.\n* Fixed missed tags for typedef-ed function pointers having a PROTO((a,b))\n  style argument list.\n* Fixed missing file tags for referenced files when using --line-directives\n  option [C/C++].\n* Fixed failure to recognize drive-qualified file name as a file name when\n  supplied as argument to -I option [Win32].\n* Fixed problem with missing comma in \"inherits\" extension flag [Java].\n* Fixed problem with incorrect or redundant parents listed for \"inherits\"\n  extension flag [Java].\n* Added check to avoid recursive symbolic links to directories.\n* Added warning message for -i option, which is deprecated and being dropped.\n* Added support for Assembler, COBOL, LISP, PERL, and Scheme, taken from Gnu\n  etags.\n* Added support for AWK, Bourne/Korn/Z Shell, Python, TCL, and Vim scripts.\n* Added support for the BETA language, submitted by Erik Corry.\n* Added ability to determine language from interpreter specified in first line\n  of executable files if they are not recognized by their extension.\n* Added --options option.\n* Added ability to specify files having no extension with -h and --langmap\n  options.\n* Added compile time option to separate path components with a unix-style path\n  separator for sharing tag file across platforms, enabled by defining the\n  label UNIX_PATH_SEPARATOR [Win32].\n* Fixed portability issues [VMS].\n\nctags-3.5.2 (Mon Apr 24 2000)\n* Fixed problem preventing Emacs-style tags from being written to stdout.\n\nctags-3.5.1 (Sun Apr 23 2000)\n* Fixed infinite loop in writing Emacs-style TAGS file on platforms using\n  tmpnam() instead of mkstemp() [Win32].\n* Fixed minor problems in Borland makefiles [Win32].\n* Fixed compiler warning [DJGPP].\n\nctags-3.5 (Fri Apr 14 2000)\n* Fixed core dump when including access field in tag file [Java].\n* Fixed failure to identify end of statement for block statements [Java].\n* Fixed bug with lone \"end\" in feature adaptation part of inheritance clause\n  [Eiffel].\n* Fixed problem preventing const functions from being recognized as pure\n  virtual [C/C++].\n* Fixed problem with no tags found after certain macro calls [C/C++].\n* Fixed bug in descrip.mms build file [VMS].\n* Changed to use mkstemp() (when available) to create temporary files for\n  security reasons and allow configuring default temporary directory, and to\n  override this directory at run-time by setting TMPDIR environment variable.\n* Added support for extracting inheritance information into new \"inherits\"\n  extension flag [C++, Java].\n* Added Makefile.bc5 for Borland C++ version 5.5 compiler (free version).\n* Added new question to FAQ regarding Xemacs.\n* Updated FAQ regarding new release of NEdit.\n* Renamed Borland 3.1 makefile from Makefile.bcc to Makefile.bc3.\n* Renamed Microsoft Visual C++ makefile from Makefile.w32 to Makefile.mvc.\n\nctags-3.4 (Thu Jan 13 2000)\n* Fixed sorting problems when LC_ALL environment variable was set to foreign\n  locale (not fixed by previous release).\n* Fixed nested scoping reported in extension flags and class-qualified tags.\n* Eliminated generation of class-qualified tag entries when --c-types=+C\n  option is in effect but scope is empty (e.g. \"::main\").\n* Added support for default access of class members in Java.\n* Added new extension flag \"implementation\", which indicates if a routine or\n  class is virtual or abstract.\n* Minor changes for OS/2 compilation.\n\nctags-3.3.3 (Thu Dec 16 1999)\n* Changed how input is read for -L and --filter options to permit file names\n  containing spaces (see man page).\n* Fixed scope recorded for C++ class elements, especially in namespaces.\n* Fixed spurious tag generated for MODULE PROCEDURE in interfaces [Fortran].\n* Fixed sorting problems when LC_ALL environment variable was set to foreign\n  locale.\n* Fixed crash on Windows when compiled with Mingw32 gcc compiler.\n* Fixed compilation problems on Cray.\n\nctags-3.3.2 (Fri Sep 24 1999)\n* Fixed compile problem on AIX 4.1.\n* Improved recovery from syntax error [Fortran].\n* Changed name of configure option (now --enable-custom-config).\n* Changed Makefile.bcc to optimize for space, since code size exceeded 64KB.\n\nctags-3.3.1 (Mon Sep 20 1999)\n* Fixed segmentation violation occurring when directory recursion was selected.\n* Fixed misleading message when out of memory during internal sort.\n\nctags-3.3 (Fri Sep 17 1999)\n* Fixed missing class-qualified tags [Java].\n* Fixed missing tag for functions having function pointer argument [C].\n* Fixed parsing of conversion functions [C++].\n* Added missing space following \"operator\" keyword to the tag names generated\n  for function call operators [C++].\n* Fixed string parsing to retry file as free source form upon EOF [Fortran].\n* Fixed missing tags following comments [Fortran].\n* Fixed missing labels for free source form [Fortran].\n* Removed 72 character limit for fixed form source lines, since many compilers\n  relax this limit and it is commonly taken advantage of. This was sometimes\n  causing fixed form source to be parsed as free form source [Fortran].\n* Changed misleading message when file could not be accessed.\n* Changed behavior of --verbose option to display option processing.\n* Changed -I option to permit clearing the token list with \"-I-\".\n* Changed --lang option to accept new \"auto\" parameter.\n* Changed --langmap option to accept new \"default\" parameter.\n* Changed --eiffel-types option to accept new 'C' flag to generate\n  class-qualified tags.\n* Changed -h option to accept new \"default\" parameter.\n* Changed option processing. Most options may now appear anywhere on the\n  command line, affecting only those files which follow them.\n* Added ability to specify default options in any of the files /etc/ctags.conf,\n  /usr/local/etc/ctags.conf, $HOME/.ctags, .ctags, and one optional file,\n  which can be supplied at configure time.\n* Added --filter option.\n* Added --filter-terminator option.\n\nctags-3.2.4 (Thu Jul 01 1999)\n* Changed name of macro in Makefile.in to avoid being overriden by CTAGS\n  environment variable.\n\nctags-3.2.3 (Mon Jun 21 1999)\n* Small portability change for EMX compiler on OS/2.\n* Slight change to W32 and BCC makefiles.\n\nctags-3.2.2 (Sat May 29 1999)\n* Fixed endless error loop in the case of unreadable file.\n* Fixed redundant include entries in TAGS file when using --etags-include.\n\nctags-3.2.1 (Wed May 09 1999)\n* Fixed problem reading -I token list from file.\n* Fixed with \"using\" declarations which corrupted tag file [C++].\n* Fixed configure.in to more reliably recognize existing prototypes.\n* Added ability to ignore preprocessor directives in Fortran files.\n* Added support for egcs/MingW32 compiler [Win32].\n\nctags-3.2 (Wed Mar 03 1999)\n* Fixed spurious tags related to export specifiers of feature clauses [Eiffel].\n* Fixed problem with template in ctor-initialer [C++].\n* Fixed typo causing compiler error [MSVC].\n* Extended -I option to allow token replacement [thanks to Flemming Madsen].\n* Added --etags-include option to support TAGS file includes.\n* Added support for QDOS [thanks to Thierry Godefroy].\n\nctags-3.1.2 (Tue Jan 26 1999)\n* Changed extension flags to eliminate space between label and value to remain\n  true to the intent of the agreement on the extended format made with editor\n  authors.\n* Added --links option to permit ignoring symbolic links.\n* Fixed missing tags upon ANSI style variable function argument lists.\n* Fixed missing tags for methods with fully qualified type names in argument\n  list [Java].\n* Fixed double tags generated for enumerators followed by comma.\n* Fixed missing path prefix for -p option [Win 95/NT].\n\nctags-3.1 (Wed Jan 20 1999)\n* Changed -h and -langmap options to accept a plus sign as the first character\n  of their arguments to indicate that arguments should be added to current.\n* Changed default for member tags to 'on' [C/C++].\n* Changed default for local entities to 'off' [Eiffel].\n* Added tags for forward class/struct/union/enum declarations when using\n  -c-types=+x [C/C++].\n* Fixed memory overwrite bug causing general protection fault [Win 95/NT].\n* Fixed missing tags for methods with throws clause [Java].\n* Fixed bad tags generated for null macro names [C].\n* Fixed spurious tag for features and entities of BIT type [Eiffel].\n* Fixed spurious tags when local entity declaration list was empty [Eiffel].\n* Fixed missing tags for contructors and destructors [C++].\n* Fixed failure to recognize function when declaration for first argument\n  was of template type [C++].\n\nctags-3.0.3 (Mon Dec 21 1998)\n* Fixed mistake made in previous version which caused macro tags to be missed.\n* Fixed parsing of --langmap option.\n\nctags-3.0.2 (Mon Dec 21 1998)\n* Added tags for names undefined with #undef [C/C++].\n* Added tags for renamed features (Eiffel).\n* Improved Emacs-style tag file contents (per Ian Zimmerman).\n* Fixed problem handling deferred, external, once, obsolete features in Eiffel.\n* Fixed porting problem [OSF1 V4.0].\n\nctags-3.0.1 (Sat Dec 12 1998)\n* Fixed problem with certain macros and functions with no declared return type.\n* Fixed problem causing endless loop on MSDOS/Win32 by restoring use of binary\n  mode on opening of source files.\n* Fixed porting problems [SunOS 4.1.x and MSVC++ 5.0].\n\nctags-3.0 (Sun Dec 06 1998)\n* Added support for the Eiffel language (everyone should learn Eiffel).\n* Added support for the Fortran language.\n* Added --c-types option to specify tag types to be included for C/C++.\n* Added --eiffel-types option to specify tag types to be included for Eiffel.\n* Added --fortran-types option to specify tag types to be included for Fortran.\n* Added --file-scope option to place verbose tag description into tag file.\n* Added --file-tags option to place tags for source file names into tag file.\n* Added --java-types option to specify tag types to be included for Java.\n* Added --kind-long option to place verbose tag description into tag file.\n* Added --linedirectives option to enable processing of #line directives so\n  that running ctags on preprocessor output can generate line numbers and file\n  names which correspond to the original source files.\n* Added -V option to enable verbose message for each file considered.\n* Added special handling for macros of form \"INIT(= value)\".\n* Added ability to suffix an ignored identifier (-I option) with the '+'\n  character, thus instructing ctags to also ignore any argument list which\n  may follow the identifier.\n* Changed the -i option, moving Java language options to the new --java-types\n  option. The -i option is now deprecated in favor of the new language\n  specific tag type options.\n* Changed behavior of handling of ignored identifiers (-I option) to still\n  generate a tag for any macro definition for that identifier.\n* Changed handling of -h option so that include files are no longer assumed to\n  be C++ files.\n* Changed tags for operators to always precede the operator with the string\n  \"operator \", thus making it consistent for all operators. [C++]\n* Changed C/C++ parsing, catching many more tricky constructs.\n* Changed extension flags to place a space between the label and the value for\n  readability.\n* Fixed core dump which occurred when using -iF (now --file-tags) together\n  with -e (etags) on a zero-length file.\n* Fixed missing or incorrect tags for conversions operators or operator \"()\".\n* Fixed incorrect parent class in extension flags for type declarations of the\n  form \"class Bar { OtherClass::sometype foo; }\".\n* Fixed missing tags for \"friend\" and \"static\" prototypes in header files.\n* Fixed problem of external \"sort\" reporting locale not available on HPUX.\n* Fixed -p option.\n* Fixed VMS support. It should now work for any source file type.\n\nctags-2.3.2 (Wed Sep 09 1998)\n* Fixed -h option; broken since version 1.7, yet only just reported.\n\nctags-2.3.1 (Sun Aug 30 1998)\n* Fixed improper handling of derived structs.\n* Fixed wrong class name tag when a nested-name-specifier was present in class\n  declaration.\n* Added parent information into tag extension flags for data structures to\n  match that already present for members.\n* Add missing documentation for --langmap option in the --help output.\n* Eliminated compiler warning [gcc 2.8.1].\n\nctags-2.3 (Thu Aug 20 1998)\n* Eliminated compiler warnings [SGI MIPSpro].\n\nctags-2.2.7 (Mon Aug 17 1998)\n* Fixed porting problem [Borland C++].\n\nctags-2.2.6 (Wed Aug 12 1998)\n* Fixed core dump encountered on some platforms when the CTAGS environment\n  variable was set but empty.\n* Fixed porting problem [MSVC].\n* Added directory recursion support for Amiga.\n\nctags-2.2.3 (Sun Aug 02 1998)\nctags-2.2.2 (Fri Jul 24 1998)\n* Fixed porting problems [AIX, HP-UX, OSF/1, SunOS, MSVC].\n\nctags-2.2.1 (Fri Jul 24 1998)\n* Now uses a default directory name of \".\" when using -R or --recurse option\n  (e.g. \"ctags -R\" is equivalent to \"ctags -R .\").\n* Directories named \"SCCS\" are skipped when using the -R or --recurse option\n  under Unix.\n* Fixed porting problems [HP-UX, IRIX, SunOS, MSDOS/Windows].\n\nctags-2.2 (Mon Jul 20 1998)\n* Added the --recurse and -R options to allow recursing into directories.\n  This allows running ctags on an entire source directory tree using the\n  single command \"ctags -R <dir>\". Currently, this option is only supported on\n  UNIX, MSDOS, Windows 95/NT, and OS/2. Other platforms will have to wait.\n* Changed writing of Emacs-style TAGS file to binary mode [MSDOS/Windows].\n* Fixed porting problems [HP-UX, OSF/1].\n\nctags-2.1.1 (Mon Jul 06 1998)\n* Changed -h option to allow only periods to separate extensions.\n* Added the --langmap option to allow overriding the default associations\n  between source language and file extension.\n* Added configuration check and code work-around for putenv() prototypes\n  missing the const from the argument declaration [IRIX 5.2 and CRAY J90].\n* Added makefile for VMS.\n* Fixed porting problem [HP-UX].\n\nctags-2.1 (Wed Jul 01 1998)\n* Added Java support.\n* Eliminated the --keywords option introduced in the 2.0.4, replacing it with\n  automatic detection of the language (i.e. recognized keywords) based upon\n  the file extension.\n* Added the --lang option for manually overriding the automatic selection of\n  the language.\n* Added new flag 'i' to the -i option to allow generating tags for Java\n  interfaces.\n* Added new flag 'n' to the -i option to allow generating tags for C++\n  namespaces.\n* Added new flag 'x' to the -i option to allow generating tags for extern\n  variable declarations.\n* Added new extension flags, \"private\", \"protected\", and \"public\", which\n  indicate the visibility of class members when it can be determined.\n* Changed behavior of flag 'C' of the -i option to add tags of form\n  \"class.member\" for Java.\n* Changed how files on command line are handled. Ctags will now only scan\n  those files whose extensions it knows about unless the --lang option is\n  specified. This allows running ctags on all files in a directory without\n  having to be specific (e.g. \"ctags *\").\n* Removed support for duplicate tag warnings and the -w and -W options. These\n  options are silently ignored for now.\n\nctags-2.0.4 (Sat May 23 1998)\n* Added sorting time to the output of the --totals option.\n* Added the --keywords option to allow restricting the recognized\n  declaration keywords in order to handle legacy source code which uses\n  newer keywords for variable and parameter names.\n* Ignore list now also applies to macro tags.\n* /dev/stdout now properly handled as parameter to -f/-o option.\n* Fixed problem handling an operator definition in C++ when white space\n  appeared between the \"operator\" keyword and the operator (e.g. \"=\").\n* Fixed handling of non-symbolic operators (e.g. \"new\", \"delete\", etc.).\n* Fixed sort order problem for some locale settings.\n* Fixed segmentation violation when using ignore list (-I) on SunOS 4.x.\n* Fixed a segmentation violation caused by a stack overwrite when testing a\n  particular kind of non-standard tag file format.\n\nctags-2.0.3 (Sun Mar 12 1998)\n* Added configure check for \"strip\" program.\n* Added new flag 'C' to the -i option to allow adding extra tags to the tag\n  file in the form \"class::member\" for class methods and members.\n\nctags-2.0.2 (Wed Feb 25 1998)\n* Added stripping of installed binary for \"install\" target.\n\nctags-2.0.1 (Thu Feb 19 1998)\n* Added support for C++.\n* Added new flag 'F' to the -i option to allow adding an extra tag for the\n  basename of each source file supplied to ctags. This provides the ability to\n  jump to a source file in Vi using \":tag file.c\".\n* Added new flag 'm' to generate tags for class, structure, and union members\n  (disabled by default).\n* Added several new flags to the -i option to allow finer specification of\n  which types of tags to include/exclude.\n* Added \".hh\" extension to the default list of files recognized as header\n  files.\n* Added explicit handling of special gcc construct __attribute((..)),\n  which could lead to incorrect tag generation.\n* Added configure option --disable-extended-format to allow building ctags\n  with the extended format disabled by default.\n* Added configure option --enable-macro-patterns to change the default\n  behavior of ctags to generate patterns instead of line numbers for macro\n  (define) tags.\n* Changed configure option --enable-internal-sort to --disable-external-sort.\n* Changed makefile for OS/2.\n* Removed support for the -d, -t and -T options which had been deprecated\n  for some time.\n* Removed ANNOUNCE file in distribution, consolidating it with the README\n  file.\n* Replaced CHANGES file with NEWS for more GNU-like standard distribution.\n* Improved the detection of macros of the type generated by Microsoft Visual C\n  when generating source code. These caused subsequent statements to fail to\n  have tags generated for them. Still not bullet proof, though.\n* Fixed a problem which prevented the use of / as a path separator under MSDOS\n  and Win 95/NT.\n* Fixed problem of blank lines occuring in the tag file.\n* Fixed recognition of declarations with parentheses.\n* Fixed problem of missing tags for objects within extern \"C\" blocks.\n* Fixed problem in source file counts when using --totals option.\n* Extended the length of tag type field in -x output to be more verbose.\n* Fixed option initialization error which caused static tags to be excluded.\n\nctags-1.7 (Mon Oct 13 1997)\n* Tag files now use a new extended format which is backwards compatible with\n  existing Vi implementations, yet provides extended information which can be\n  used by supporting editors.\n* Added documentation pseudo-tags (e.g. !_TAG_FILE_FORMAT) to tag file.\n* Added the --excmd option as alternative to the -n and -N options.\n* Added the --format option to allow forcing the old-style tag file format.\n* Added the --if0 to control how \"#if 0\" branches are handled.\n* Added the --sort option as alternative to -u option.\n* Added the --totals option to print statistics of tag generation.\n* Added the --version option.\n* Improved handling of preprocessor conditionals.\n* Code within an #if 0 is now never scanned for non-macro tags by default\n  since tags within that code could conceivably be overridden by more\n  desirable tags in the #else branch to follow. Macro tags in these branches\n  are always included.\n* Fixed problem which could leave invalid tag entries in tag file when an\n  internal re-scan of a source file occurred.\n* Fixed problem with internal sort mechanism when appending tags to existing\n  file.\n* Changed external sort command to filter out duplicate identical tags lines\n  (including the pattern) unless warnings for duplicate tags are enabled.\n* Added data to emacs style tag entries to more closely match that produced by\n  the GNU etags.\n* Removed fixed limits on maximum tag line length.\n* Correction to Amiga makefile.\n* Improvements to Win32 portability with changes to Makefile.w32.\n\nctags-1.6 (Tue May 13 1997)\n* Now using GNU autoconf to permit automatic host configuration.\n* Added the -e option to generate Emacs style tag files\n* Added ETAGS environment variable to be used when -e option is in effect.\n* Added the -p option to supply a default path for source files.\n* Fixed problem of incorrect line numbers in tag file when form feeds and\n  vertical tabs occured in the source file.\n* Fixed problem preventing ignoring of identifiers specified via the -I option\n  when the identifiers were followed by a parameter list in the source code.\n* Changed the search patterns generated for #define macros when using -N\n  option. It now includes the character following the name (or \"$\" if end of\n  line) instead of the \"\\>\" used previously. Some editors did not support this\n  metacharacter for tag searches.\n* Removed -u (unique) flag from sort command line invocation to retain exactly\n  indentical tag patterns in the same file. This is in preparation for editor\n  support of duplicate tags.\n* Fixed problem resulting in no tags generated following a function-like\n  macro reference outside of a function block.\n* Fixed problem of no tags generated for typedef for function or function\n  pointer.\n* Fixed problem of no tags generated after encountering strange function\n  declarations (e.g. \"foo(params) saywhat (void);\")\n\nctags-1.5 (Sat Oct 5 1996)\n* Added generation of tags for objects inside C++ extern blocks (e.g.\n  'extern \"C\" {...}' construct).\n* Added generation of tags for function definitions inside brace-enclosed\n  (\"{}\") blocks, since function definitions are allowed inside classes and\n  extern blocks.\n* Added the -N option to force patterns to be used for all tags (including\n  macro tags).\n* Changed the search patterns generated for macro definitions to be terminated\n  with \"\\>\", which allows the pattern to still match even when the #define\n  line beyond the macro name is changed.\n* Fixed problem resulting in no tags generated for files containing a\n  function-like macro, such as 'MODULE_ID(\"$Id\")', even when ignoring the\n  keyword. This also fixed a problem that caused tags to be missed for\n  initialized function pointer definitions.\n* Redirected error messages to stdout for MSDOS version.\n\nctags-1.4 (Sun Aug 18 1996)\n* Added recursive parsing of class/struct/enum blocks to look for\n  class/struct/enum tags and enumeration values.\n* Added the -I option to specify keywords to ignore in the source files.\n* Fixed problem resulting in no tag generated when declaring a pointer const\n  or volatile.\n* Fixed problem resulting in no tag generated for comma terminated function\n  declarations.\n\nctags-1.3 (Sun Jun 16 1996)\n* Fixed problem problem which caused \"struct tag;\" to be misinterpreted as a\n  variable definition.\n* Added the -n option to use line numbers in the tag file instead of patterns.\n* Added the -? option as an alternative for the --help option.\n\nctags-1.2 (Wed Jun 5 1996)\n* Fixed a problem caused by an unitialized variable.\n\nctags-1.1 (Tue Jun 4 1996)\n* Fixed problem reading parameter list to the -h option.\n\nctags-1.0a (Mon Jun 3 1996)\n* Added ctags.lsm to distribution\n\nctags-1.0 (Fri May 31 1996)\n* First public release.\n\nvim:tw=78\n"
  },
  {
    "path": "old-docs/README.exuberant",
    "content": "Exuberant Ctags\n===============\nAuthor: Darren Hiebert <dhiebert at users.sourceforge.net>\n        http://ctags.sourceforge.net\n        Instant Messaging:\n          Yahoo! ID     : dbhiebert\n          AIM ScreenName: darrenhiebert\n\nExuberant Ctags is a multilanguage reimplementation of the much-underused\nctags(1) program and is intended to be the mother of all ctags programs. It\ngenerates indexes of source code definitions which are used by a number of\neditors and tools. The motivation which drove the development of Exuberant\nCtags was the need for a ctags program which supported generation of tags\nfor all possible C language constructs (which no other ctags offers), and\nbecause most were easily fooled by a number of preprocessor contructs.\n\n\nExuberant Ctags offers the following features:\n\n1.  It supports the following languages: Assembler, AWK, ASP, BETA,\n    Bourne/Korn/Z Shell, C, C++, C#, COBOL, Eiffel, Erlang, Fortran, Java, Lisp,\n    Lua, Makefile, Objective-C, Pascal, Perl, PHP, PL/SQL, Python, REXX, Ruby,\n    Scheme, S-Lang, SML (Standard ML), Tcl, Vera, Verilog, VHDL, Vim,\n    and YACC.\n\n2.  It is capable of generating tags for virtually all C language constructs.\n\n3.  It is very robust in parsing code. In particular, the C/C++ parser is\n    far less easily fooled by code containing #if preprocessor conditional\n    constructs, using a conditional path selection algorithm to resolve\n    complicated situations, and a fall-back algorithm when this one fails.\n\n4.  Supports output of Emacs-style TAGS files (i.e. \"etags\").\n\n5.  User-defined languages, using Posix regular expressions.\n\n6.  Supports UNIX, MSDOS, Windows 95/98/NT/2000/XP, OS/2, QNX, Amiga, QDOS,\n    RISC OS, VMS, Macintosh, and Cray. Some pre-compiled binaries are\n    available on the web site.\n\n\nVisit the Exuberant Ctags web site:\n\n    http://ctags.sourceforge.net\n\n\nWhich brings us to the most obvious question:\n\n  Q: Why is it called \"Exuberant\" ctags?\n  A: Because one of the meanings of the word is:\n\n     exuberant : produced in extreme abundance : PLENTIFUL syn see PROFUSE\n\nCompare the tag file produced by Exuberant Ctags with that produced by any\nother ctags and you will see how appropriate the name is.\n\n\nThis source code is distributed according to the terms of the GNU General\nPublic License. It is provided on an as-is basis and no responsibility is\naccepted for its failure to perform as expected. It is worth at least as\nmuch as you paid for it!\n\nExuberant Ctags was originally derived from and inspired by the ctags\nprogram by Steve Kirkendall (kirkenda@cs.pdx.edu) that comes with the Elvis\nvi clone (though almost none of the original code remains). This, too, is\nfreely available.\n\nPlease report any problems you find. The two problems I expect to be most\nlikely are either a tag which you expected but is missing, or a tag created\nin error (shouldn't really be a tag). Please include a sample of code (the\ndefinition) for the object which misbehaves.\n\n--\nvim:tw=76:sw=4:et:\n"
  },
  {
    "path": "old-docs/index.html",
    "content": "<!doctype html public/li\"-//W3C//DTD HTML 4.0 Transitional//EN\">\n<html>\n<head>\n   <meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\">\n   <meta NAME=\"GENERATOR\" CONTENT=\"Mozilla/4.03 [en] (X11; I; Linux 2.0.1.31 i586) [Netscape]\">\n    <meta NAME=\"author\" CONTENT=\"Darren Hiebert\">\n    <meta NAME=\"description\" CONTENT=\"Distribution site for Exuberant Ctags.\">\n    <meta NAME=\"keywords\" CONTENT=\"Darren Hiebert Exuberant Ctags\">\n   <title>Exuberant Ctags</title>\n</head>\n<!--\n<body BGCOLOR=\"#B0B0B0\" TEXT=\"#000000\" ALINK=\"#0000FF\" VLINK=\"#551A8B\">\n-->\n\n<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#1F00FF\" alink=\"#FF0000\" vlink=\"#9900DD\">\n\n<table align=center border=0 cellpadding=2 cellspacing=2 width=\"100%\">\n\n<!--header-->\n  <tr>\n    <td colspan=2>\n      <center>\n        <img src=ctags.png align=middle alt=\"Exuberant Ctags\" width=368 height=100>\n      </center>\n    </td>\n  </tr>\n  <tr>\n    <td colspan=2>\n      <div align=\"right\">\n        <em>\n          <font size=\"+1\">\n            A multilanguage implementation of Ctags<br>\n          </font>\n        </em>\n      </div>\n    </td>\n  </tr>\n  <tr>\n    <td bgcolor=\"#ffffff\" colspan=2 width=100 height=1>&nbsp;</td>\n  </tr>\n<!-- end header -->\n\n  <tr>\n\n<!-- left frame -->\n    <td valign=\"top\">\n      <table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"100%\">\n        <tr><td>\n          <table cellspacing=\"0\" width=\"100%\">\n            <tr bgcolor=\"#99ccff\"><td><strong>About</strong></td></tr>\n            <tr bgcolor=\"#FFFFBB\"><td NOWRAP><dl>\n              <li><a href=\"whatis.html\">What is ctags?</a></li>\n              <li><a href=\"desire.html\">Unique features</a></li>\n              <li><a href=\"languages.html\">Supported languages</a></li>\n              <li><a href=\"tools.html\">Supporting tools</a></li>\n              <li><a href=\"quotes.html\">Exuberant user feedback</a></li>\n            </dl> </td></tr>\n          </table>\n        </td></tr>\n\n        <tr><td>\n          <table cellspacing=\"0\" width=\"100%\">\n            <tr bgcolor=\"#99ccff\"><td><strong>Documentation</strong></td></tr>\n            <tr bgcolor=\"#FFFFBB\"><td><dl>\n              <li><a href=\"ctags.html\">Manual</a></li>\n              <li><a href=\"faq.html\">FAQ</a></li>\n              <li><a href=\"news.html\">Change Notes</a></li>\n              <li><a href=\"FORMAT\">Tag file format</a></li>\n              <li><a href=\"http://www.delorie.com/gnu/docs/regex/regex_toc.html\">GNU regex</a></li>\n            </dl></td></tr>\n          </table>\n        </td></tr>\n\n        <tr><td>\n          <table cellspacing=\"0\" width=\"100%\">\n            <tr bgcolor=\"#99ccff\"><td><strong>Download</strong></td></tr>\n            <tr bgcolor=\"#FFFFBB\"><td><dl>\n              <li><a href=\"http://sourceforge.net/project/showfiles.php?group_id=6556\">\n                Releases\n              </a></li>\n            </dl></td></tr>\n          </table>\n        </td></tr>\n\n        <tr><td>\n          <table cellspacing=\"0\" width=\"100%\">\n            <tr bgcolor=\"#99ccff\"><td><strong>Development</strong></td></tr>\n            <tr bgcolor=\"#FFFFBB\"><td><dl>\n              <li><a href=\"EXTENDING.html\">\n                Adding support for a new language\n              </a></li>\n              <li><a href=\"tool_support.html\">\n                Adding tag file support to a software tool\n              </a></li>\n            </dl></td></tr>\n          </table>\n        </td></tr>\n\n        <tr><td>\n          <table cellspacing=\"0\" width=\"100%\">\n            <tr bgcolor=\"#99ccff\"><td><strong>Support</strong></td></tr>\n            <tr bgcolor=\"#FFFFBB\"><td><dl>\n              <li><a href=\"http://sourceforge.net/projects/ctags\">\n                SourceForge project page\n              </a></li>\n              <li><a href=\"http://sourceforge.net/tracker/?group_id=6556&amp;atid=106556\">\n                Report a bug (requires SourceForge account)\n              </a></li>\n              <li><a href=\"http://freshmeat.net/articles/view/149\">\n                How to Report Bugs Effectively\n              </a></li>\n              <li><a href=\"http://sourceforge.net/mail/?group_id=6556\">\n                Mailing lists\n              </a></li>\n              <li><a href=\"http://sourceforge.net/sendmessage.php?touser=38016\">\n                Email the author\n              </a></li>\n              <li><a href=\"http://www.polarhome.com/ctags/\">\n                Ctags on VMS\n              </a></li>\n              </dl>\n              <dl>\n                <dt>Please take a moment to rate ctags:</dt>\n                <dd><a href=\"http://freshmeat.net/rate/2502\">Freshmeat</a></dd>\n                <dd><a href=\"http://www.icewalkers.com/app_vote.php3?id=1032\">\n                  IceWalkers</a>\n                </dd>\n            </dl></td></tr>\n          </table>\n        </td></tr>\n\n        <tr><td>\n        <hr>\n          Ctags is hosted at<br>\n          <center>\n          <a href=\"http://sourceforge.net\">\n          <img src=\"http://sourceforge.net/sflogo.php?group_id=6556&amp;type=1\" width=\"88\" height=\"31\" border=\"0\" alt=\"SourceForge Logo\"></a>\n          </center>\n        </td></tr>\n\n      </table>\n    </td>\n<!-- end of left frame -->\n\n<!-- right frame -->\n    <td bgcolor=\"white\" valign=\"top\" width=\"100%\">\n      <hr>\n      <p>\n      <a href=\"http://www.m-w.com/cgi-bin/dictionary?exuberant\">\n        <strong>ex·u·ber·ant</strong>\n      </a>\n      : produced in extreme abundance :\n      PLENTIFUL&nbsp;&nbsp;<strong>synonym</strong> see PROFUSE\n      </p>\n\n      <ul>\n        <li>Used in at least 50\n            <a href=\"countries.html\">countries</a>\n            in all 7 continents <i>(including Antarctica!)</i>\n        <li>\n          Supports 41 <a href=\"languages.html\">programming languages</a>\n        </li>\n        <li>Featured in the book,\n          <a href=\"http://www.oreilly.com/catalog/vi6/chapter/ch08.html#ch08_05.htm\">\n          <em>Learning the vi Editor</em></a>, a title in the\n          <a href=\"http://www.oreilly.com\">O'Reilly</a> series\n        </li>\n        <li>Covered in the March 2001 issue of <u>C++ Users Journal</u>,\n          <a href=\"http://www.ddj.com/cpp/184401358\">\n            \"Navigating Linux Source Code\"\n          </a>\n        </li>\n        <li>\n          <a href=\"lg18-wkndmech.html\">Praised</a> in the <em>Weekend Mechanic</em> column of the June 1997 issue of Linux Gazette\n        </li>\n        <li>\n          <a href=\"http://perlbuzz.com/2007/09/ctags-57-improves-perl-support.html\">Praised</a> in <em>Perl Buzz</em>\n        </li>\n        <li>Freely available under the terms of the\n          <a href=\"http://www.gnu.org/copyleft/gpl.html\">GNU General Public License</a>\n        </li>\n        <li>Included in major Linux distributions</li>\n      </ul>\n\n      <hr>\n      <br>\n\n      <strong>\n        Version @VERSION@ [<em><font COLOR=\"#FF0000\">@DATE@</font></em>]\n      </strong>\n\n      <br>\n      <br>\n      <table BORDER>\n        <tr>\n          <td><STRONG>Contents</STRONG></td>\n          <td><STRONG>Package</STRONG></td>\n        </tr>\n        <tr>\n          <td>Source only distribution (gzipped)</td>\n          <td><A HREF=\"http://prdownloads.sourceforge.net/ctags/ctags-@VERSION@.tar.gz\">ctags-@VERSION@.tar.gz</A>&nbsp;</td>\n        </tr>\n        <tr>\n          <td ALIGN=LEFT>Source RPM</td>\n          <td><A HREF=\"http://prdownloads.sourceforge.net/ctags/ctags-@VERSION@-1.src.rpm\">ctags-@VERSION@-1.src.rpm</A>&nbsp;</td>\n        </tr>\n        <tr>\n          <td ALIGN=LEFT>Fedora 10 binary RPM (glibc-2.9)</td>\n          <td><A HREF=\"http://prdownloads.sourceforge.net/ctags/ctags-@VERSION@-1.i386.rpm\">ctags-@VERSION@-1.i386.rpm</A>&nbsp;</td>\n        </tr>\n        <tr>\n          <td>Source and binary for Windows 98/NT/2000/XP</td>\n          <td><A HREF=\"http://prdownloads.sourceforge.net/ctags/ctags@DOS_VERSION@.zip\">ctags@DOS_VERSION@.zip</A></td>\n        </tr>\n      </table>\n    </td>\n<!-- end of right frame -->\n\n  </tr>\n</table>\n\n\n</body>\n</html>\n<!-- vim:set et ts=2 sts=2 sw=2: -->\n"
  },
  {
    "path": "old-docs/website/.cvsignore",
    "content": "index.html\nnews.html\nctags.html\nEXTENDING.html\n"
  },
  {
    "path": "old-docs/website/FORMAT",
    "content": "Proposal for extended Vi tags file format\n=========================================\n\nVersion: 0.06 DRAFT\n   Date: 1998 Feb 8\n Author: Bram Moolenaar <Bram at vim.org>\n    and: Darren Hiebert <dhiebert at users.sourceforge.net>\n\n\n1. Introduction\n---------------\n\nThe file format for the \"tags\" file, as used by Vi and many of its\ndescendants, has limited capabilities.\n\nThis additional functionality is desired:\n\n1. Static or local tags.\n   The scope of these tags is the file where they are defined.  The same tag\n   can appear in several files, without really being a duplicate.\n2. Duplicate tags.\n   Allow the same tag to occur more then once.  They can be located in\n   a different file and/or have a different command.\n3. Support for C++.\n   A tag is not only specified by its name, but also by the context (the\n   class name).\n4. Future extension.\n   When even more additional functionality is desired, it must be possible to\n   add this later, whithout breaking programs that don't support it.\n\n\n2. From proposal to standard\n----------------------------\n\nTo make this proposal into a standard for tags files, it needs to be supported\nby most people working on versions of Vi, ctags, etc..  Currently this\nstandard is supported by:\n\nDarren Hiebert <dhiebert at users.sourceforge.net>   Exuberant ctags\nBram Moolenaar <Bram at vim.org>                     Vim (Vi IMproved)\n\nThese have been or will be asked to support this standard:\n\nNvi\t\tKeith Bostic <bostic at bsdi.com>\nVile\t\tTom E. Dickey <dickey at clark.net>\nNEdit\t\tMark Edel <edel at ltx.com>\nCRiSP\t\tPaul Fox <fox at crisp.demon.co.uk>\nLemmy           James Iuliano <jai at accessone.com>\nZeus            Jussi Jumppanen <jussij at ca.com.au>\nElvis\t\tSteve Kirkendall <kirkenda at cs.pdx.edu>\nFTE             Marko Macek <Marko.Macek at snet.fri.uni-lj.si>\n\n\n3. Backwards compatibility\n--------------------------\n\nA tags file that is generated in the new format should still be usable by Vi.\nThis makes it possible to distribute tags files that are usable by all\nversions and descendants of Vi.\n\nThis restricts the format to what Vi can handle.  The format is:\n\n1. The tags file is a list of lines, each line in the format:\n\n\t{tagname}<Tab>{tagfile}<Tab>{tagaddress}\n\n   {tagname}\tAny identifier, not containing white space..\n   <Tab>\tExactly one TAB character (although many versions of Vi can\n\t\thandle any amount of white space).\n   {tagfile}\tThe name of the file where {tagname} is defined, relative to\n   \t\tthe current directory (or location of the tags file?).\n   {tagaddress}\tAny Ex command.  When executed, it behaves like 'magic' was\n\t\tnot set.\n\n2. The tags file is sorted on {tagname}.  This allows for a binary search in\n   the file.\n\n3. Duplicate tags are allowed, but which one is actually used is\n   unpredictable (because of the binary search).\n\nThe best way to add extra text to the line for the new functionality, without\nbreaking it for Vi, is to put a comment in the {tagaddress}.  This gives the\nfreedom to use any text, and should work in any traditional Vi implementation.\n\nFor example, when the old tags file contains:\n\n\tmain\tmain.c\t/^main(argc, argv)$/\n\tDEBUG\tdefines.c\t89\n\nThe new lines can be:\n\n\tmain\tmain.c\t/^main(argc, argv)$/;\"any additional text\n\tDEBUG\tdefines.c\t89;\"any additional text\n\nNote that the ';' is required to put the cursor in the right line, and then\nthe '\"' is recognized as the start of a comment.\n\nFor Posix compliant Vi versions this will NOT work, since only a line number\nor a search command is recognized.  I hope Posix can be adjusted.  Nvi suffers\nfrom this.\n\n\n4. Security\n-----------\n\nVi allows the use of any Ex command in a tags file.  This has the potential of\na trojan horse security leak.\n\nThe proposal is to allow only Ex commands that position the cursor in a single\nfile.  Other commands, like editing another file, quitting the editor,\nchanging a file or writing a file, are not allowed.  It is therefore logical\nto call the command a tagaddress.\n\nSpecifically, these two Ex commands are allowed:\n- A decimal line number.\n\t89\n- A search command.  It is a regular expression pattern, as used by Vi,\n  enclosed in // or ??.\n\t/^int c;$/\n\t?main()?\n\nThere are two combinations possible:\n- Concatenation of the above, with ';' in between.  The meaning is that the\n  first line number or search command is used, the cursor is positioned in\n  that line, and then the second search command is used (a line number would\n  not be useful).  This can be done multiple times.  This is useful when the\n  information in a single line is not unique, and the search needs to start\n  in a specified line.\n\t/struct xyz {/;/int count;/\n\t389;/struct foo/;/char *s;/\n- A trailing comment can be added, starting with ';\"' (two characters:\n  semi-colon and double-quote).  This is used below.\n\t89;\" foo bar\n\nThis might be extended in the future.  What is currently missing is a way to\nposition the cursor in a certain column.\n\n\n5. Goals\n--------\n\nNow the usage of the comment text has to be defined.  The following is aimed\nat:\n\n1. Keep the text short, because:\n   - The line length that Vi can handle is limited to 512 characters.\n   - Tags files can contain thousands of tags.  I have seen tags files of\n     several Mbytes.\n   - More text makes searching slower.\n2. Keep the text readable, because:\n   - It is often necessary to check the output of a new ctags program.\n   - Be able to edit the file by hand.\n   - Make it easier to write a program to produce or parse the file.\n3. Don't use special characters, because:\n   - It should be possible to treat a tags file like any normal text file.\n\n\n6. Proposal\n-----------\n\nUse a comment after the {tagaddress} field.  The format would be:\n\n\t{tagname}<Tab>{tagfile}<Tab>{tagaddress}[;\"<Tab>{tagfield}..]\n\n   {tagname}\tAny identifier, not containing white space..\n   <Tab>\tExactly one TAB character (although many versions of Vi can\n\t\thandle any amount of white space).\n   {tagfile}\tThe name of the file where {tagname} is defined, relative to\n   \t\tthe current directory (or location of the tags file?).\n   {tagaddress}\tAny Ex command.  When executed, it behaves like 'magic' was\n\t\tnot set.  It may be restricted to a line number or a search\n\t\tpattern (Posix).\nOptionally:\n   ;\"\t\tsemicolon + doublequote: Ends the tagaddress in way that looks\n\t\tlike the start of a comment to Vi.\n   {tagfield}\tSee below. \n\nA tagfield has a name, a colon, and a value: \"name:value\".\n- The name consist only out of alphabetical characters.  Upper and lower case\n  are allowed.  Lower case is recommended.  Case matters (\"kind:\" and \"Kind:\n  are different tagfields).\n- The value may be empty.\n  It cannot contain a <Tab>.\n  When a value contains a \"\\t\", this stands for a <Tab>.\n  When a value contains a \"\\r\", this stands for a <CR>.\n  When a value contains a \"\\n\", this stands for a <NL>.\n  When a value contains a \"\\\\\", this stands for a single '\\' character.\n  Other use of the backslash character is reserved for future expansion.\n  Warning: When a tagfield value holds an MS-DOS file name, the backslashes\n  must be doubled!\n\n\nProposed tagfield names:\n\nFIELD-NAME\tDESCRIPTION\n\narity\t\tNumber of arguments for a function tag.\n\nclass\t\tName of the class for which this tag is a member or method.\n\nenum\t\tName of the enumeration in which this tag is an enumerator.\n\nfile\t\tStatic (local) tag, with a scope of the specified file.  When\n\t\tthe value is empty, {tagfile} is used.\n\nfunction\tFunction in which this tag is defined.  Useful for local\n\t\tvariables (and functions).  When functions nest (e.g., in\n\t\tPascal), the function names are concatenated, separated with\n\t\t'/', so it looks like a path.\n\nkind\t\tKind of tag.  The value depends on the language.  For C and\n\t\tC++ these kinds are recommended:\n\t\tc\tclass name\n\t\td\tdefine (from #define XXX)\n\t\te\tenumerator\n\t\tf\tfunction or method name\n\t\tF\tfile name\n\t\tg\tenumeration name\n\t\tm\tmember (of structure or class data)\n\t\tp\tfunction prototype\n\t\ts\tstructure name\n\t\tt\ttypedef\n\t\tu\tunion name\n\t\tv\tvariable\n\t\tWhen this field is omitted, the kind of tag is undefined.\n\nstruct\t\tName of the struct in which this tag is a member.\n\nunion\t\tName of the union in which this tag is a member.\n\n\nNote that these are mostly for C and C++.  When tags programs are written for\nother languages, this list should be extended to include the used field names.\nThis will help users to be independent of the tags program used.\n\nExamples:\n\n\tasdf\tsub.cc\t/^asdf()$/;\"\tnew_field:some\\svalue\tfile:\n\tfoo_t\tsub.h\t/^typedef foo_t$/;\"\tkind:t\n\tfunc3\tsub.p\t/^func3()$/;\"\tfunction:/func1/func2\tfile:\n\tgetflag\tsub.c\t/^getflag(arg)$/;\"\tkind:f\tfile:\n\tinc\tsub.cc\t/^inc()$/;\"\tfile: class:PipeBuf\n\n\nThe name of the \"kind:\" field can be omitted.  This is to reduce the size of\nthe tags file by about 15%.  A program reading the tags file can recognize the\n\"kind:\" field by the missing ':'.  Examples:\n\n\tfoo_t\tsub.h\t/^typedef foo_t$/;\"\tt\n\tgetflag\tsub.c\t/^getflag(arg)$/;\"\tf\tfile:\n\n\nAdditional remarks:\n- When a tagfield appears twice in a tag line, only the last one is used.\n\n\nNote about line separators:\n\nVi traditionally runs on Unix systems, where the line separator is a single\nlinefeed character <NL>.  On MS-DOS and compatible systems <CR><NL> is the\nstandard line separator.  To increase portability, this line separator is also\nsupported.\n\nOn the Macintosh a single <CR> is used for line separator.  Supporting this on\nUnix systems causes problems, because most fgets() implementation don't see\nthe <CR> as a line separator.  Therefore the support for a <CR> as line\nseparator is limited to the Macintosh.\n\nSummary:\nline separator\tgenerated on\t\taccepted on\n<LF>\t\tUnix\t\t\tUnix, MS-DOS, Macintosh\n<CR>\t\tMacintosh\t\tMacintosh\n<CR><LF>\tMS-DOS\t\t\tUnix, MS-DOS, Macintosh\n\nThe characters <CR> and <LF> cannot be used inside a tag line.  This is not\nmentioned elsewhere (because it's obvious).\n\n\nNote about white space:\n\nVi allowed any white space to separate the tagname from the tagfile, and the\nfilename from the tagaddress.  This would need to be allowed for backwards\ncompatibility.  However, all known programs that generate tags use a single\n<Tab> to separate fields.\n\nThere is a problem for using file names with embedded white space in the\ntagfile field.  To work around this, the same special characters could be used\nas in the new fields, for example \"\\s\".  But, unfortunately, in MS-DOS the\nbackslash character is used to separate file names.  The file name\n\"c:\\vim\\sap\" contains \"\\s\", but this is not a <Space>.  The number of\nbackslashes could be doubled, but that will add a lot of characters, and make\nparsing the tags file slower and clumsy.\n\nTo avoid these problems, we will only allow a <Tab> to separate fields, and\nnot support a file name or tagname that contains a <Tab> character.  This\nmeans that we are not 100% Vi compatible.  However, there is no known tags\nprogram that uses something else than a <Tab> to separate the fields.  Only\nwhen a user typed the tags file himself, or made his own program to generate a\ntags file, we could run into problems.  To solve this, the tags file should be\nfiltered, to replace the arbitrary white space with a single <Tab>.  This Vi\ncommand can be used:\n\n\t:%s/^\\([^ ^I]*\\)[ ^I]*\\([^ ^I]*\\)[ ^I]*/\\1^I\\2^I/\n\n(replace ^I with a real <Tab>).\n\n\nTAG FILE INFORMATION:\n\nPsuedo-tag lines can be used to encode information into the tag file regarding\ndetails about its content (e.g. have the tags been sorted?, are the optional\ntagfields present?), and regarding the program used to generate the tag file.\nThis information can be used both to optimize use of the tag file (e.g.\nenable/disable binary searching) and provide general information (what version\nof the generator was used).\n\nThe names of the tags used in these lines may be suitably chosen to ensure\nthat when sorted, they will always be located near the first lines of the tag\nfile.  The use of \"!_TAG_\" is recommended.  Note that a rare tag like \"!\" \ncan sort to before these lines.  The program reading the tags file should be\nsmart enough to skip over these tags.\n\nThe lines described below have been chosen to convey a select set of\ninformation.\n\nTag lines providing information about the content of the tag file:\n\n!_TAG_FILE_FORMAT\t{version-number}\t/optional comment/\n!_TAG_FILE_SORTED\t{0|1}\t\t\t/0=unsorted, 1=sorted/\n\nThe {version-number} used in the tag file format line reserves the value of\n\"1\" for tag files complying with the original UNIX vi/ctags format, and\nreserves the value \"2\" for tag files complying with this proposal. This value\nmay be used to determine if the extended features described in this proposal\nare present.\n\nTag lines providing information about the program used to generate the tag\nfile, and provided solely for documentation purposes:\n\n!_TAG_PROGRAM_AUTHOR\t{author-name}\t/{email-address}/\n!_TAG_PROGRAM_NAME\t{program-name}\t/optional comment/\n!_TAG_PROGRAM_URL\t{URL}\t/optional comment/\n!_TAG_PROGRAM_VERSION\t{version-id}\t/optional comment/\n\n\n[End Of Document]\n"
  },
  {
    "path": "old-docs/website/countries.html",
    "content": "<html>\n<head>\n<title>Exuberant Ctags: Country List</title>\n</head>\n<body>\n\n<h1>Countries Where Exuberant Ctags is Used</h1>\n\n<ol>\n<li><pre>Argentina [AR]</pre></li>\n<li><pre>Australia [AU]</pre></li>\n<li><pre>Austria [AT]</pre></li>\n<li><pre>Belarus [BY]</pre></li>\n<li><pre>Belgium [BE]</pre></li>\n<li><pre>Brazil [BR]</pre></li>\n<li><pre>Brunei [BN]</pre></li>\n<li><pre>Canada [CA]</pre></li>\n<li><pre>China [CN]</pre></li>\n<li><pre>Cyprus [CY]</pre></li>\n<li><pre>Czech Republic [CZ]</pre></li>\n<li><pre>Denmark [DK]</pre></li>\n<li><pre>Estonia [EE]</pre></li>\n<li><pre>Finland [FI]</pre></li>\n<li><pre>France [FR]</pre></li>\n<li><pre>Germany [DE]</pre></li>\n<li><pre>Greece [GR]</pre></li>\n<li><pre>Hong Kong [HK]</pre></li>\n<li><pre>Hungary [HU]</pre></li>\n<li><pre>Iceland [IS]</pre></li>\n<li><pre>India [IN]</pre></li>\n<li><pre>Ireland [IE]</pre></li>\n<li><pre>Israel [IL]</pre></li>\n<li><pre>Italy [IT]</pre></li>\n<li><pre>Japan [JP]</pre></li>\n<li><pre>Korea [KR]</pre></li>\n<li><pre>Lithuania [LT]</pre></li>\n<li><pre>Luxembourg [LU]</pre></li>\n<li><pre>Malaysia [MY]</pre></li>\n<li><pre>Netherlands [NL]</pre></li>\n<li><pre>New Zealand [NZ]</pre></li>\n<li><pre>Norway [NO]</pre></li>\n<li><pre>Peru [PE]</pre></li>\n<li><pre>Poland [PL]</pre></li>\n<li><pre>Portugal [PT]</pre></li>\n<li><pre>Romania [RO]</pre></li>\n<li><pre>Russian Federation [RU]</pre></li>\n<li><pre>Singapore [SG]</pre></li>\n<li><pre>Slovenia [SI]</pre></li>\n<li><pre>South Africa [ZA]</pre></li>\n<li><pre>Soviet Union [SU]</pre></li>\n<li><pre>Spain [ES]</pre></li>\n<li><pre>Sri Lanka [LK]</pre></li>\n<li><pre>Sweden [SE]</pre></li>\n<li><pre>Switzerland [CH]</pre></li>\n<li><pre>Turkey [TR]</pre></li>\n<li><pre>Ukraine [UA]</pre></li>\n<li><pre>United Kingdom [UK]</pre></li>\n<li><pre>United States [US]</pre></li>\n<li><pre>Vietnam [VN]</pre></li>\n</ol>\n\n<hr>\n<a href=\"http:index.html\">Back to <strong>Exuberant Ctags</strong></a>\n\n</body>\n</html>\n"
  },
  {
    "path": "old-docs/website/desire.html",
    "content": "<html>\n<head>\n<title>Exuberant Ctags: Why?</title>\n</head>\n<body>\n\n<h1>What makes this implementation of ctags desirable?</h1>\n\n<ol>\n\n<p>\n<li>\nSupports <a href=\"languages.html\">many programming languages</a>.\n</li>\n</p>\n\n<p>\n<li>It is capable of generating tags for <strong><em>all</em></strong> types\n    of C/C++ language tags, including all of the following:\n    <p>\n    <menu>\n    <li type=disk>class names\n    <li type=disk>macro definitions\n    <li type=disk>enumeration names\n    <li type=disk>enumerators\n    <li type=disk>function definitions\n    <li type=disk>function prototypes/declarations\n    <li type=disk>class, interface, struct, and union data members\n    <li type=disk>structure names\n    <li type=disk>typedefs\n    <li type=disk>union names\n    <li type=disk>variables (definitions and external declarations)\n    </menu>\n</li>\n</p>\n\n<p>\n<li>It is far less easily fooled by C code containing <code>#if</code>\n    preprocessor conditional constructs, using a conditional path selection\n    algorithm to resolve complicated choices, and a fall-back algorithm when\n    this one fails.\n</li>\n</p>\n\n<p>\n<li>Supports user-defined languages, using regular expressions.\n</li>\n</p>\n\n<p>\n<li>Supports output of Emacs-style TAGS files.\n</li>\n</p>\n\n<p>\n<li>Can also be used to print out a list of selected objects found in source\n    files.\n</li>\n</p>\n\n<p>\n<li>Compiles on UNIX, MSDOS, Windows 95/98/NT, OS/2, QNX, Amiga, QDOS, VMS,\n    Macintosh, and Cray.\n</li>\n</p>\n\n</ol>\n\n<hr>\n<a href=\"http:index.html\">Back to <strong>Exuberant Ctags</strong></a>\n\n</body>\n</html>\n"
  },
  {
    "path": "old-docs/website/faq.html",
    "content": "<html>\n<head>\n<meta HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\">\n<title>Exuberant Ctags FAQ</title>\n</head>\n<body>\n\n<h1>Exuberant Ctags FAQ</h1>\n\n<ul>\n <li><a href=\"#1\">\n    1.  Why do you call it <strong><em>Exuberant Ctags</em></strong>?\n    </a>\n <li><a href=\"#2\">\n    2.  Why doesn't my editor work with these tag files?\n    </a>\n <li><a href=\"#3\">\n    3.  What are these strange bits of text beginning with <code>;\"</code>?\n    </a>\n <li><a href=\"#4\">\n    4.  Why doesn't XEmacs' Speedbar module work with <strong><em>Exuberant\n    Ctags</em></strong>?\n    </a>\n <li><a href=\"#5\">\n    5.  Why doesn't XEmacs correctly locate the tag in the source file?\n    </a>\n <li><a href=\"#6\">\n    6.  Why doesn't NEdit correctly locate the tag in the source file?\n    </a>\n <li><a href=\"#7\">\n    7.  Why can't I jump to <code>class::member</code>?\n    </a>\n <li><a href=\"#8\">\n    8.  How can I avoid having to specify my favorite option every time?\n    </a>\n <li><a href=\"#9\">\n    9.  Why do I end up on the wrong line when I jump to a tag?\n    </a>\n <li><a href=\"#10\">\n    10.  How do I jump to the tag I want instead of the wrong one by the same name?\n    </a>\n <li><a href=\"#11\">\n    11.  What is <strong>Vim</strong>?\n    </a>\n <li><a href=\"#12\">\n    12.  How can I locate all references to a specific function or variable?\n    </a>\n <li><a href=\"#13\">\n    13.  Why does appending tags to a tag file tag so long?\n    </a>\n <li><a href=\"#14\">\n    14.  How do I get regex support for Win32?\n    </a>\n <li><a href=\"#15\">\n    15.  How should I set up tag files for a multi-level directory hierarchy?\n    </a>\n</ul>\n\n<hr>\n<h2>\n<a name=\"1\">\n1.  Why do you call it <strong><em>Exuberant Ctags</em></strong>?\n</a>\n</h2>\n\nBecause one of the meanings of the word <em>exuberant</em> is:\n<ul>\n<B>ex·u·ber·ant</B> : produced in extreme abundance\n: <FONT SIZE=-1>PLENTIFUL</FONT>&nbsp;&nbsp;\n<B><I>synonym</I></B> see <FONT SIZE=-1>PROFUSE</FONT>\n</ul>\n\nCompare the tag file produced by <strong><em>Exuberant Ctags</em></strong>\nwith that produced by any other ctags and you will see how appropriate the\nname is.\n\n<hr>\n<h2>\n<a name=\"2\">\n2.  Why doesn't my editor work with these tag files?\n</a>\n</h2>\n\n<h2>\n<a name=\"3\">\n3.  What are these strange bits of text beginning with <code>;\"</code> which\nfollow many of the lines in the tag file?\n</a>\n</h2>\n\nThese are \"extension flags\". They are added in order to provide extra\ninformation about the tag that may be utilized by the editor in order to\nmore intelligently handle tags. They are appended to the EX command part of\nthe tag line in a manner that provides backwards compatibility with existing\nimplementations of the Vi editor. The semicolon is an EX command separator\nand the double quote begins an EX comment. Thus, the extension flags appear\nas an EX comment and should be ignored by the editor when it processes the\nEX command.\n<p>\nSome non-vi editors, however, implement only the bare minimum of EX commands\nin order to process the search command or line number in the third field of\nthe tag file. If you encounter this problem, use the option\n<code>--format=1</code> to generate a tag file without these extensions\n(remember that you can set the <code>CTAGS</code> environment variable to any\ndefault arguments you wish to supply). Then ask the supplier of your editor to\nimplement handling of this feature of EX commands.\n<p>\n\n<hr>\n<h2>\n<a name=\"4\">\n4.  Why doesn't XEmacs' Speedbar module work with <strong><em>Exuberant\nCtags</em></strong>?\n</a>\n</h2>\n\nThe default command line switches used by XEmacs for <i>etags</i> are not\ncompatible with <strong><em>Exuberant Ctags</em></strong> options. By default,\n<strong><em>Exuberant Ctags</em></strong> installs a symbolic link, \"etags\",\npointing to the ctags executable. When <strong><em>Exuberant\nCtags</em></strong> is started with the name \"etags\", it produces Emacs-style\ntag files by default.\n<p>\nTo fix this, add the following lines to your .emacs file, replacing the path\nto <i>etags</i> with the path where the symbolic link was installed.\n<p>\n\n<code>\n<pre>\n(autoload 'speedbar \"speedbar\")\n(setq speedbar-fetch-etags-command \"/usr/local/bin/etags\"\n      speedbar-fetch-etags-arguments '(\"-f\" \"-\"))\n</pre>\n</code>\n\n<hr>\n<h2>\n<a name=\"5\">\n5.  Why doesn't XEmacs correctly locate the tag in the source file?\n</a>\n</h2>\n\nThis has been observed with version 20.3. It seems that when XEmacs searches\nfor a tag, it searches using the tag name instead of the search string located\nin the TAGS file. This is a bug in XEmacs and does not occur in the GNU\nversion of Emacs. This has been reported to be corrected as of version 21.4.16.\n\n<hr>\n<h2>\n<a name=\"6\">\n6.  Why doesn't NEdit correctly locate the tag in the source file?\n</a>\n</h2>\n\nVersions of <a href=\"http://nedit.org\">NEdit</a> prior to 5.1 did not support\nthe extended tag file format generated by <strong><em>Exuberant\nCtags</em></strong> by default. Either upgrade to version 5.1 or specify the\noption <code>--format=1</code> when running ctags to output the old tag file\nformat.\n<p>\n\n<hr>\n<h2>\n<a name=\"7\">\n7.  Why can't I jump to <code>class::member</code>?\n</a>\n</h2>\n\nBecause, by default, ctags only generates tags for the separate identifiers\nfound in the source files. If you specify the <code>--extra=+q</code>\noption, then ctags will also generate a second, class-qualified tag for each\nclass member (data and function/method) in the form <code>class::member</code>\nfor C++, and in the form <code>class.method</code> for Eiffel and Java.\n<p>\n\n<hr>\n<h2>\n<a name=\"8\">\n8.  How can I avoid having to specify my favorite option every time?\n</a>\n</h2>\n\nEither by setting the environment variable CTAGS</code> to your custom\noptions, or putting them into a <code>.ctags</code> file in your home\ndirectory.\n<p>\n\n<hr>\n<h2>\n<a name=\"9\">\n9.  Why do I end up on the wrong line when I jump to a tag?\n</a>\n</h2>\n\nBy default, ctags encodes the line number in the file where macro (#define)\ntags are found. This was done to remain compatible with the original UNIX\nversion of ctags. If you change the file containing the tag without\nrebuilding the tag file, the location of tag in the tag file may no longer\nmatch the current location.\n<p>\n\nIn order to avoid this problem, you can specify the option\n<code>--excmd=p</code>, which causes ctags to use a search pattern to locate\nmacro tags. I have never uncovered the reason why the original UNIX ctags used\nline numbers exclusively for macro tags, but have so far resisted changing the\ndefault behaviour of <strong><em>Exuberant Ctags</em></strong> to behave\ndifferently.\n<p>\n\n<hr>\n<h2>\n<a name=\"10\">\n10.  How do I jump to the tag I want instead of the wrong one by the same name?\n</a>\n</h2>\n\nA tag file is simple a list of tag names and where to find them. If there\nare duplicate entries, you often end up going to the wrong one because the\ntag file is sorted and your editor locates the first one in the tag file.\n<p>\n\nStandard Vi provides no facilities to alter this behavior. However, Vim\nhas some nice features to minimize this problem, primarly by examining all\nmatches and choosing the best one under the circumstances. Vim also provides\ncommands which allow for selection of the desired matching tag.\n<p>\n\n<hr>\n<h2>\n<a name=\"11\">\n11.  What is <strong>Vim</strong>?\n</a>\n</h2>\n\nVim is a vi-compatible editor available as source and compilable for any\nplatform. Yeah, I know the first reaction is to shy away from this. But you\nwill never regret getting it, and you will become greatly attached to its\nfeatures, which you can learn gradually. I would be willing to say that it\nis the best vi-clone available within 4 light-years of Alpha Centauri. It\nworks (nearly) exactly like standard vi, but provides some incredibly useful\nextensions (some of which I have participated in designing with the author).\nMost Linux distributions have adopted Vim as its standard vi.\n<p>\n\n<hr>\n<h2>\n<a name=\"12\">\n12.  How can I locate all references to a specific function or variable?\n</a>\n</h2>\n\nThere are several packages already available which provide this capability.\nAs of this writing, they are:\n\n<ul>\n<li><a href=\"http://www.gnu.org/software/global\">GLOBAL source code tag system</a>\n<li><a href=\"http://www.gnu.org/software/idutils/idutils.html\">GNU id-utils</a>\n<li><a href=\"http://cscope.sourceforge.net\">cscope</a>\n<li><a href=\"ftp://www.ibiblio.org/pub/Linux/devel/lang/c\">cflow</a>\n</ul>\n\n<hr>\n<h2>\n<a name=\"13\">\n13.  Why does appending tags to a tag file tag so long?\n</a>\n</h2>\n\nSometimes, in an attempt to build a global tag file for all source files in\na large source tree of many directories, someone will make an attempt to run\nctags in append (-a) mode on every directory in the hierarchy. Each time\nctags is invoked, its default behavior is to sort the tag file once the tags\nfor that pass have been added. As the cumulative tag file grows, the sort\ntime increases exponentially.\n<p>\n\nThe best way to avoid this problem (and the most efficient) is to make\nuse of the --recurse (or -R) option of ctags by executing the following\ncommand in the root of the directory hierarchy (thus running ctags only once):\n<p>\n\n<code>\n<pre>\n        ctags -R\n</pre>\n</code>\n\nIf you really insist on running ctags separately on each directory, you can\navoid the sort pass each time by specifying the option <code>--sort=no</code>.\nOnce the tag file is completely built, use the sort command to manually sort\nthe final tag file, or let the final invocation of ctags sort the file.\n<p>\n\n<hr>\n<h2>\n<a name=\"14\">\n14.  How do I get regex support for Win32?\n</a>\n</h2>\n\nYou need to download the GNU regex package for Win32 from the following\nlocation:\n\n<blockquote>\n    <a href=\"http://people.delphiforums.com/gjc/gnu_regex.html\">\n    http://people.delphiforums.com/gjc/gnu_regex.html</a>\n</blockquote>\n\nThen point the makefile macro, REGEX_DIR, found in mk_mvc.mak and mk_bc5.mak,\nto the directory created by extracting this archive.\n\n<hr>\n<h2>\n<a name=\"15\">\n15.  How should I set up tag files for a multi-level directory hierarchy?\n</a>\n</h2>\n\nThere are a few ways of approaching this:\n<p>\n\n<ol>\n<li>A local tag file in each directory containing only the tags for source\n    files in that directory.\n\n<li>One single big, global tag file present in the root directory of your\n    hierarchy, containing all tags present in all source files in the\n    hierarchy.\n\n<li>A local tag file in each directory containing only the tags for source\n    files in that directory, in addition to one single global tag file\n    present in the root directory of your hierarchy, containing all\n    non-static tags present in all source files in the hierarchy.\n\n<li>A local tag file in each directory of the hierarchy, each one\n    containing all tags present in source files in that directory and all\n    non-static tags in every directory below it (note that this implies\n    also having one big tag file in the root directory of the hierarchy).\n</ol>\n\nEach of these approaches has its own set of advantages disadvantages,\ndepending upon your particular conditions. Which approach is deemed best\ndepends upon the following factors:\n<p>\n\n<ol type=A>\n<li>The ability of your editor to use multiple tag files.\n    <p>\n\n    If your editor cannot make use of multiple tag files (original vi\n    implementations could not), then one large tag file is the only way to\n    go if you ever desire to jump to tags located in other directories. If\n    you never need to jump to tags in another directory (i.e. the source\n    in each directory is entirely self-contained), then a local tag file\n    in each directory will fit your needs.\n    <p>\n\n<li>The time is takes for your editor to look up a tag in the tag file.\n    <p>\n\n    The significance of this factor depends upon the size of your source\n    tree and on whether the source files are located on a local or remote\n    file system. For source and tag files located on a local file system,\n    looking up a tag is not as big a hit as one might first imagine, since\n    vi implementations typically perform a binary search on a sorted tag\n    file. This may or may not be true for the editor you use. For files\n    located on a remote file system, reading a large file is an expensive\n    operation.\n    <p>\n\n<li>Whether or not you expect the source code to change and the time it\n    takes to rebuild a tag file to account for changes to the source code.\n    <p>\n\n    While <strong><em>Exuberant Ctags</em></strong> is particularly fast in\n    scanning source code (around 1-2 MB/sec), a large project may still result\n    in objectionable delays if one wishes to keep their tag file(s) up to date\n    on a frequent basis, or if the files are located on a remote file system.\n    <p>\n\n<li>The presence of duplicate tags in the source code and the ability to\n    handle them. The impact of this factor is influenced by the following\n    three issues:\n    <p>\n\n    1.  How common are duplicate tags in your project?\n\t<p>\n\n    2.  Does your editor provide any facilities for dealing with duplicate\n        tags?\n\t<p>\n\n        While standard vi does not, many modern vi implementations, such\n        as Vim have good facilities for selecting the desired match from\n        the list of duplicates. If your editor does not support duplicate\n        tags, then it will typically send you to only one of them, whether\n        or not that is the one you wanted (and not even notifying you that\n        there are other potential matches).\n\t<p>\n\n    3.  What is the significance of duplicate tags?\n\t<p>\n\n        For example, if you have two tags of the same name from entirely\n        isolated software components, jumping first to the match found\n        in component B while working in component A may be entirely\n        misleading, distracting or inconvenient (to keep having to choose\n        which one if your editor provides you with a list of matches).\n        However, if you have two tags of the same name for parallel builds\n        (say two initialization routines for different hosts), you may\n        always want to specify which one you want.\n</ol>\n\nOf the approaches listed above, I tend to favor Approach 3. My editor of\nchoice is Vim, which provides a rich set of features for handling multiple\ntag files, which partly influences my choice. If you are working with\nsource files on a remote file system, then I would recommend either\nApproach 3 or Approach 4, depending upon the hit when reading the global\ntag file.\n<p>\n\nThe advantages of Approach 3 are many (assuming that your editor has\nthe ability to support both multiple tag files and duplicate tags). All\nlookups of tag located in the currect directory are fast and the local\ntag file can be quickly and easily regenerated in one second or less\n(I have even mapped a keystroke to do this easily). A lookup of a\n(necessarily non-static) tag found in another directory fails a lookup in\nthe local tag file, but is found in the global tag file, which satisfies\nall cross-directory lookups. The global tag file can be automatically\nregenerated periodically with a cron job (and perhaps the local tag files\nalso).\n<p>\n\nNow I give an example of how you would implement Approach 3. Means of\nimplementing the other approaches can be performed in a similar manner.\n<p>\n\nHere is a visual representation of an example directory hierarchy:\n<p>\n\n<code>\n<pre>\nproject\n  `-----misccomp\n  |       `...\n  `-----sysint\n          `-----client\n          |       `-----hdrs\n          |       `-----lib\n          |       `-----src\n          |       `-----test\n          `-----common\n          |       `-----hdrs\n          |       `-----lib\n          |       `-----src\n          |       `-----test\n          `-----server\n                  `-----hdrs\n                  `-----lib\n                  `-----src\n                  `-----test\n</pre>\n</code>\n\nHere is a recommended solution (conceptually) to build the tag files:\n<p>\n\n<ol>\n<li>Within each of the leaf nodes (i.e. hdrs, lib, src, test) build a tag\n    file using \"ctags *.[ch]\". This can be easily be done for the whole\n    hierarchy by making a shell script, call it \"dirtags\", containing the\n    following lines:\n\n<code>\n<pre>\n        #!/bin/sh\n\tcd $1\n\tctags *\n</pre>\n</code>\n\n    Now execute the following command:\n\n<code>\n<pre>\n        find * -type d -exec dirtags {} \\;\n</pre>\n</code>\n\n    These tag files are trivial (and extremely quick) to rebuild while\n    making changes within a directory. The following Vim key mapping is\n    quite useful to rebuild the tag file in the directory of the current\n    source file:\n\n<code>\n<pre>\n        :nmap ,t :!(cd %:p:h;ctags *.[ch])&<CR><CR>\n</pre>\n</code>\n\n<li>Build the global tag file:\n\n<code>\n<pre>\n        cd ~/project\n        ctags --file-scope=no -R\n</pre>\n</code>\n\n    thus constructing a tag file containing only non-static tags for all\n    source files in all descendent directories.\n\n<li>Configure your editor to read the local tag file first, then consult\n    the global tag file when not found in the local tag file. In Vim,\n    this is done as follows:\n\n        :set tags=./tags,tags,~/project/tags\n\n</ol>\n\nIf you wish to implement Approach 4, you would need to replace the\n\"dirtags\" script of step 1 with the following:\n<p>\n\n<code>\n<pre>\n        #!/bin/sh\n\tcd $1\n\tctags *\n\t# Now append the non-static tags from descendent directories\n\tfind * -type d -prune -print | ctags -aR --file-scope=no -L-\n</pre>\n</code>\n\nAnd replace the configuration of step 3 with this:\n<p>\n\n<code>\n<pre>\n        :set tags=./tags,./../tags,./../../tags,./../../../tags,tags\n</pre>\n</code>\n\nAs a caveat, it should be noted that step 2 builds a global tag file whose\nfile names will be relative to the directory in which the global tag file\nis being built. This takes advantage of the Vim 'tagrelative' option,\nwhich causes the path to be interpreted a relative to the location of the\ntag file instead of the current directory. For standard vi, which always\ninterprets the paths as relative to the current directory, we need to\nbuild the global tag file with absolute path names. This can be\naccomplished by replacing step 2 with the following:\n<p>\n\n<code>\n<pre>\n        cd ~/project\n\tctags --file-scope=no -R `pwd`\n</pre>\n</code>\n\n<p>\n<hr>\n<a href=\"http:index.html\">Back to <strong>Exuberant Ctags</strong></a>\n\n</body>\n</html>\n"
  },
  {
    "path": "old-docs/website/gpl.html",
    "content": "<html>\n<head>\n<title>The GNU General Public License</title>\n</head>\n<body bgcolor=\"#C0C0C0\">\n\n<center>\n<h1>The GNU General Public License\n</h1>\n</center>\n</p>\n<center>\n<h2><a name=\"v2\"><font face=\"arial, helvetica\">\nVersion 2, June 1991\n</font></a>\n</h2>\n</center>\n<address>\n&copy; Copyright 1989, 1991\n<a href=\"http://www.fsf.org/fsf/fsf.html\">Free Software Foundation</a>, Inc.\n\n<br>\n59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n</address>\n<p>\nEveryone is permitted to copy and distribute verbatim copies\nof this license document, but changing it is not allowed.\n\n<h3>\n<center>\n\t\t\t    Preamble\n</center>\n</h3>\n<p>\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Library General Public License instead.)  You can apply it to\nyour programs, too.\n<p>\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n<p>\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n<p>\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n<p>\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n<p>\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n<p>\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n<p>\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n<p>\n<h3>\n<center>\n\t\t    GNU GENERAL PUBLIC LICENSE\n<br>\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n</center>\n</h3>\n<p>\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n<p>\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n<p>\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n<p>\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n<p>\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n<p>\n<ol type=\"a\">\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n<p>\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n<p>\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n</ol>\n<p>\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n<p>\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n<p>\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n<p>\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n<p>\n<ol type=\"a\">\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n<p>\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n<p>\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n</ol>\n<p>\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n<p>\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n<p>\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n<p>\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n<p>\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n<p>\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n<p>\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n<p>\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n<p>\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n<p>\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n<p>\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n<p>\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n<p>\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n<p>\n<h3>\n<center>\n\t\t\t    NO WARRANTY\n</center>\n</h3>\n<p>\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n<p>\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n<p>\n\t\t     END OF TERMS AND CONDITIONS\n<p>\n\t    How to Apply These Terms to Your New Programs\n<p>\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n<p>\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n<p>\n<samp>\n<ol>\n    &lt;one line to give the program's name and a brief idea of what it does.&gt;\n    <br>\n    Copyright (C) 19yy  &lt;name of author&gt;\n<p>\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n<p>\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n<p>\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n<p>\n</ol>\n</samp>\n\nAlso add information on how to contact you by electronic and paper mail.\n<p>\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n<p>\n<samp>\n<ol>\n    Gnomovision version 69, Copyright (C) 19yy name of author\n<br>\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n<br>\n    This is free software, and you are welcome to redistribute it\n<br>\n    under certain conditions; type `show c' for details.\n</ol>\n</samp>\n<p>\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n<p>\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n<p>\n<samp>\n<ol>\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  <br>\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n<p>\n  &lt;signature of Ty Coon&gt;, 1 April 1989\n  <br>\n  Ty Coon, President of Vice\n</ol>\n</samp>\n<p>\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General\nPublic License instead of this License.\n<p>\n\n</body>\n</html>\n"
  },
  {
    "path": "old-docs/website/languages.html",
    "content": "<html>\n<head>\n<title>Languages Supported by Exuberant Ctags</title>\n</head>\n<body>\n\n<h3>\nLanguages Supported by Exuberant Ctags:\n</h3>\n<ol>\n  <li>Ant</li>\n  <li>Assembler</li>\n  <li>ASP</li>\n  <li>Awk</li>\n  <li>BASIC</li>\n  <li>BETA</li>\n  <li>C</li>\n  <li>C++</li>\n  <li>C#</li>\n  <li>COBOL</li>\n  <li>DOS Batch</li>\n  <li>Eiffel</li>\n  <li>Erlang</li>\n  <li>Flex</li>\n  <li>Fortran</li>\n  <li>HTML</li>\n  <li>Java</li>\n  <li>JavaScript</li>\n  <li>Lisp</li>\n  <li>Lua</li>\n  <li>Make</li>\n  <li>MATLAB</li>\n  <li>Objective Caml</li>\n  <li>Pascal</li>\n  <li>Perl</li>\n  <li>PHP</li>\n  <li>PL/SQL</li>\n  <li>Python (Pyrex/Cython)</li>\n  <li>REXX</li>\n  <li>Ruby</li>\n  <li>Scheme</li>\n  <li>Shell scripts (Bourne/Korn/Z)</li>\n  <li>S-Lang</li>\n  <li>SML (Standard ML)</li>\n  <li>Tcl</li>\n  <li>TeX</li>\n  <li>Vera</li>\n  <li>Verilog</li>\n  <li>VHDL</li>\n  <li>Vim</li>\n  <li>YACC</li>\n</ol>\n\n<hr>\n<a href=\"http:index.html\">Back to <strong>Exuberant Ctags</strong></a>\n\n</body>\n</html>\n<!-- vim:set et ts=2 sts=2 sw=2: -->\n"
  },
  {
    "path": "old-docs/website/lg18-wkndmech.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Draft//EN\">\n<HTML>\n<HEAD><TITLE>Linux Weekend Mechanic - June 1997</TITLE></HEAD>\n\n<BODY BGCOLOR=#FFFFFF>\n\n<CENTER>\n<H2>\n<a href=\"http://www.linuxgazette.com/issue18/wkndmech.html\">Published</a>\nin the <A HREF=\"http://www.linuxgazette.com/issue18/lg_toc18.html\">June 1997</A>\nIssue of the <A HREF=\"http://www.linuxgazette.com\">Linux Gazette<SMALL><SUP>TM</SUP></SMALL></A></H2>\n<FONT SIZE=\"2\"><B>\nCopyright &copy; 1997 John M. Fisk &lt;fiskjm@ctrvax.vanderbilt.edu&gt;<BR>\nThe Linux Gazette is Copyright &copy; 1997 <A HREF=\"http://www.ssc.com/\">\nSpecialized Systems Consultants Inc.</A>\n</B></FONT>\n</CENTER>\n\n<BR />\n<HR>\n<P>\n\nI've been using <B>Exuberant Ctags, version 1.5, by Darren Hiebert</B> for the\npast little bit now and really like this a lot.  As the name implies, it does\na pretty thorough job of scouring your source files for all sorts of useful\nstuff -- function declarations, typedefs, enum's, variable declarations, macro\ndefinitions, enum/struct/union tags, external function prototypes, and so\nforth.  It continues on in the time honored tradition of providing a bazillion\noptions, but not to fear:  it's default behavior is sane and savvy and\nprovides a very nice OOBE*.\n</P>\n\n<P>\n<I>*(Out Of Box Experience)</I>\n</P>\n\n<P>\n...This one is definitely worth having.\n</P>\n\n<P>\n<hr>\n<a href=\"http:index.html\">Back to <strong>Exuberant Ctags</strong></a>\n\n</BODY>\n</HTML>\n"
  },
  {
    "path": "old-docs/website/quotes.html",
    "content": "<html>\n<head>\n<title>Exuberant Ctags: Feedback</title>\n</head>\n<body>\n\n<h1>Exuberant Ctags User Feedback</h1>\n\n<ul>\n\n<li><b><i>23 Jul 2004</i></b>\n    <p>\n    Exuberant ctags is incredible!  It is making my life so much easier.  I\n    told my friends about it and they love it too. \n    </p>\n    <p>\n    Thank-you!\n    </p>\n</li>\n\n<li><b><i>11 Jan 2004</i></b>\n    <p>\n    I've been extending support for the D programming language (you gave me a\n    diff a while back) and going over this code its the cleanest C-code I've\n    ever seen!  Adding support is a breeze , they should use this code to\n    teach :).  Mas limpio amigo.\n    </p>\n</li>\n\n<li><b><i>13 Aug 2003</i></b>\n    <p>\n    I want to thank you for the support and also say that your ctags is a very\n    good tool. I haven't seen any other similiar free software yet that's\n    nearly as clean and useful for this problem.\n    </p>\n</li>\n\n<li><b><i>20 Mar 2003</i></b>\n    <p>\n    Ctags is great and i've been using it for years in c/c++ projects.\n    </p>\n</li>\n\n<li><b><i>17 Mar 2003</i></b>\n    <p>\n     Every since I have started working on a large C++ application\n     (over 600 src files) I have become a devoted user of ctags.\n    </p>\n</li>\n\n<li><b><i>30 Jan 2003</i></b>\n    <p>\n    Hi Darren, congratulations on ctags!  It's a wonderful tool. \n    </p>\n</li>\n\n<li><b><i>14 Nov 2002</i></b>\n    <p>\n    I am using ctags in my development since a long time. And I am addicted to\n    its use.\n    </p>\n</li>\n\n<li><b><i>13 Nov 2002</i></b>\n    <p>\n    Thank you for writing ctags! Ever since I started using ctags together\n    with vim a couple of weeks ago to keep track of the sources we're writing,\n    it's become nearly indispensable. Instead of grepping through sources to\n    find where subroutines are defined, I can just double-click on an\n    identifier and jump to the right place. Then Ctrl+T takes me back to where\n    I was.\n    </p>\n\n    <p>\n    All this only possible because of tags files... and ctags is configurable\n    enough that it can parse not only C but also such things as JAM screens in\n    ASCII format or our programs' message file format. And because the source\n    was available, I could hack it to recognise the brand of Fortran that is\n    in use in the legacy code we maintain... the default Fortran mode didn't\n    work (probably because of extensions in the implementation).\n    </p>\n</li>\n\n<li><b><i>23 Sep 2002</i></b>\n    <p>\n    Thanks for the fix - very quick!!  Ctags is a great tool, and the support\n    is impressive :)\n    </p>\n</li>\n\n<li><b><i>28 Aug 2002</i></b>\n    <p>\n    Thank you (and all those who helped you) for a wonderful\n    program.  I have used it _many_ times to navigate through c/c++\n    code (using vim) and was very pleased to learn today that it\n    supports python code too (if only I had learned this 3 years ago\n    ... oh well <g>).\n    </p>\n</li>\n\n<li><b><i>2 Mar 2002</i></b>\n    <p>\n    Great work on ctags, I use it everyday and is an invaluable tool to a \n    programmer.\n    </p>\n</li>\n\n<li><b><i>14 Nov 2001</i></b>\n    <p>\n    I really like the Exuberant Ctags program.  We [are] all indebted to\n    Darren Hiebert for providing us with such a fine program.\n    </p>\n</li>\n\n<li><b><i>5 Nov 2001</i></b>\n    <p>\n    CTags is great. I use it all the time now, and I\n    have no idea how I got by without it before.\n    </p>\n</li>\n\n<li><b><i>3 Nov 2001</i></b>\n    <p>\n    First of all, let me thank you for Exuberant Ctags.  I use this on a daily \n    basis and couldn't imagine life without it.\n    </p>\n</li>\n\n<li><b><i>23 Oct 2001</i></b>\n    <p>\n    Hello!  I've been a devout user of ctags for the\n    past 4 years - thanks for a great program!\n    </p>\n</li>\n\n<li><b><i>7 Jul 2001</i></b>\n    <p>\n    Ctags is an absolutely amazing program now thanks to you.\n    </p>\n    <p>[<i>Australia</i>]</p>\n</li>\n\n<li><b><i>22 Jun 2001</i></b>\n    <p>\n    Your Ctags is by far the best ctags around.\n    </p>\n</li>\n\n<li><b><i>29 May 2001</i></b>\n    <p>\n    Hi, I just wanted to let you know how much I appreciate your ctags\n    implementation. I have used it for a few months now, and I can safely say\n    it rocks! I have introduced it to everyone at work, and we're all ecstatic\n    about it. People use it for Java, ASP, JavaScript and SQL development.\n    Thanks to the ingenious plug-and-play support for adding parsers, I had no\n    trouble adding parsers for JavaScript and SQL....\n    </p>\n    <p>\n    CTags is now one of the programs I could not survive without, so once\n    again, a big thank you!\n    </p>\n    <p>[<i>Norway</i>]</p>\n</li>\n\n<li><b><i>15 Apr 2001</i></b>\n    <p>\n    BTW very impressive tool - I started using it with vim at work after\n    seeing the 5.0 announcement and have found it a \"must have\".\n    </p>\n    <p>[<i>United Kingdom</i>]</p>\n</li>\n\n<li><b><i>27 Feb 2001</i></b>\n    <p>\n    I want to thank you again for ctags.  It keeps getting better and better;\n    I get so used to the development environment made possible by tags in our\n    C source, it's a blessing to be able to use the same habits whether it's\n    C, perl, shell, or whatever.\n    </p>\n\n<li><b><i>2 Feb 2001</i></b>\n    <p>\n    Couldn't live w/o ctags. I don't know how I went so long without it.\n    </p>\n\n<li><b><i>26 Sep 2000</i></b>\n    <p>\n    In a new job and new to Unix, I was afraid I would have to write my own\n    source analysis tools. Disappointed that the default version of ctags failed\n    to properly identify the oddly formatted function definitions in my source I\n    was thrilled to find your Exuberant Ctags! The clouds have parted and the\n    sun is peeking through.\n    </p>\n\n    <p>\n    Thank you for your kind contribution to the free software library. Know that\n    your work continues to make my life a little easier. I appreciate this.\n    </p>\n\n    <p>\n    May lady luck shine on you.\n    </p>\n\n<li><b><i>18 Aug 2000</i></b>\n    <p>\n    Hi,\n    </p>\n\n    <p>\n    you mention on your web site that you've had no reports of your program\n    being used in Antarctica, guess what?\n    </p>\n\n    <p>\n    I work for the British Antarctic Survey on software which runs a\n    scientific radar system down at Halley (76 south, 26 west), Antarctica.\n    The radar is controlled by a huge and complex system called Radops, on top\n    of the QNX operating system.\n    </p>\n\n    <p>\n    Basically ctags makes writing new software and maintaining the system much\n    easier, thanks.  I had previously relied on a horrible system of scripts\n    to find function definitions.\n    </p>\n    <p>[<i>Antarctica</i>]</p>\n\n<li><b><i>4 Jul 2000</i></b>\n    <p>\n    Thank U for the fact to support Python in ctags.\n    </p>\n    <p>\n    Recently I was puzzled in the case that I can't use ctags in python old\n    version.\n    </p>\n    <p>\n    When I visited your site, I got the bright hope!!\n    </p>\n    <p>\n    I'm the fan of CTAGS!!\n    </p>\n    <p>\n    May the force with U.\n    </p>\n    <p>[<i>Korea</i>]</p>\n</li>\n\n<li><b><i>23 Jun 2000</i></b>\n    <p>\n    I've been a VIM user for years (and a VI user for a long time), and\n    finally today I decided to play w/ the ctags that came w/ my RedHat\n    6.1 installation, and I was impressed to say the least, I kicked\n    myself for not using it before. \n    </p>\n\n    <p>\n    Then I found out (on Freshmeat.net) that there was a new version (4.0)\n    with some more languages supported. Downloaded it, compiled and tested\n    it w/ some awk and python code, worked great. And as I am a PHP-head,\n    I stole some of the code from the awk and the python files and made a\n    file to process php classes and functions, nothing revolutionary, but\n    it works. \n    </p>\n\n    <p>\n    Your code is clear, so even a dumb programmer like me could figure out\n    what was going on, modified the appropriate files, and got the\n    modified ctags working in under half and hour. I am including the\n    \"<code>diff -c</code>\" files so you can patch your code.\n    </p>\n\n    <p>\n    When I get some more time to play w/ ctags (downloaded at 2:50am, it\n    is 3:30am now), I'll add more to the <code>php.c</code> so it'll recognize\n    methods, variable definitions, etc.\n    </p>\n\n    <p>\n    Great tool man!\n    </p>\n</li>\n\n<li><b><i>12 Jun 2000</i></b>\n    <p>\n    First, LOVE ctags!!!\n    Now that I've buttered you up ... just kidding ... I LOVE ctags! ;-)\n    </p>\n</li>\n\n<li><b><i>05 Jun 2000</i></b>\n    <p>\n    First, thanx for producing the useful CTAGS tool.  My colleagues and I use\n    it all the time, and it comes in very handy when reviewing software source\n    files that have been written by others.\n    </p>\n</li>\n\n<li><b><i>16 May 2000</i></b>\n    <p>\n    First let me thank you (over and over again) for the Exuberant ctags\n    you've written for the variety of platforms.\n    </p>\n</li>\n\n<li><b><i>10 May 2000</i></b>\n    <p>\n    Thank you for the wonderful ctags program. I'm using it\n    for a parser I'm writing that works with C/C++ code....\n    </p>\n    <p>\n    PS. I know you've heard this several times also, but your\n    code is really easy to read, and makes the whole process of\n    understanding so much... nicer. Thanks again.\n    </p>\n</li>\n\n<li><b><i>10 Apr 2000</i></b>\n    <p>\n    Thanks for doing such a wonderful job; this ctags is *FAR* superior to the\n    stock one that came with the system (HP-UX).\n    </p>\n</li>\n\n<li><b><i>02 Feb 2000</i></b>\n    <p>\n    Exuberant ctags is just what I have been looking for for ages - I have\n    been trying to do it all in Perl (albeit wrongly no doubt with numerous\n    regex's) but I must say ctags is spot on!\n    </p>\n</li>\n\n<li><b><i>26 Jan 2000</i></b>\n    <p>\n    I've been looking at your code, and I'm very impressed, and I'm not easily\n    impressed.\n    </p>\n</li>\n\n<li><b><i>13 Jan 2000</i></b>\n    <p>\n    Your ctags utility allows for much better software engineering practices -\n    and without being tied to the heavyweight utilities provided by compiler\n    manufacturers. We will be using ctags as a major component for our C++\n    build process. It now allows us to define error and message enumerators on\n    a per-class basis rather than as a global resource. Also, many thanks for\n    your very prompt attention in the whole area of technical support.\n    </p>\n    <p>[<i>United Kingdom</i>]</p>\n</li>\n\n<li><b><i>08 Dec 1999</i></b>\n    <p>\n    Thank you very much for taking on the task of looking after ctags. It is\n    really very much appreciated. My company are planning on using ctags for\n    many of our software maintenance and development tasks. After all this\n    </p>\n    <p>[<i>United Kingdom</i>]</p>\n</li>\n\n<li><b><i>07 Dec 1999</i></b>\n    <p>\n    I've been using Exuberant Ctags for awhile now.  It's really great,\n    useful program.  I've integrated tag-hyperlinking into my editor, and\n    I'm now addicted to tags.  I've written my own tags programs for\n    various assembly languages (simple to parse) using Perl.  \n    </p>\n</li>\n\n<li><b><i>15 Sep 1999</i></b>\n    <p>\n    We wish to take this opportunity to thank you for support. ctags has\n    revolutionary changed our way of developing our models.\n    </p>\n    <p>[<i>United Kingdom</i>]</p>\n</li>\n\n<li><b><i>09 Sep 1999</i></b>\n    <p>\n    Vim is shipping with Darren Hiebert's excellent Exuberant Ctags :)\n    ...this is a thing of great beauty that we can't live without round here.\n    </p>\n    <p>[<i>United Kingdom</i>]</p>\n</li>\n\n<li><b><i>12 Jul 1999</i></b>\n    <p>\n    I really like your implementation of ctags, it works really well and \n    your code is very clean. \n    </p>\n</li>\n\n<li><b><i>07 Jul 1999</i></b>\n    <p>\n    Hi Darren, let me congratulate you for this excellent tool.\n    </p>\n    <p>[<i>Germany</i>]</p>\n</li>\n\n<li><b><i>14 Jun 1999</i></b>\n    <p>\n    Many thanks for making the ctags package freely available. Its a \n    great package. I particularly like the C++ support. I'm working on \n    a telecommunications system with approximately 150 C++ classes. \n    Being able to immediately get to the definition of C++ items \n    easily and quickly via ctags makes work a joyful experience.\n    </p>\n</li>\n\n<li><b><i>19 Mar 1999</i></b>\n    <p>\n    I use your ctags here at work, and wanted to thank you for writing such a\n    nice software package.  I like it so much more than the normal ctags\n    program.... Thank you so much for writing such a great package!\n    </p>\n</li>\n\n<li><b><i>05 Mar 1999</i></b>\n    <p>\n    I am just glad that such great software is avaiable out there.  Most ctags\n    on Unix simply blow chunks!  Yours is absoulutely fantastic and has saved\n    me numerous hours of wasted time. I have even managed to get the project\n    managament here to make it sort of a standard, though it had to be\n    installed as vtags so it would not confuse the curmudgeons still using the\n    broken ctags that comes with the system.  When used with vim, it works\n    absolutely fantastic.  I hope I am not gushing here. :)\n    </p>\n</li>\n\n<li><b><i>27 Jan 1999</i></b>\n    <p>\n    Looks like nothing can spoil my ctags pleasure now\n    </p>\n</li>\n\n<li><b><i>21 Dec 1998</i></b>\n    <p>\n    Exuberant Ctags is a great tool indeed!\n    </p>\n    <p>[<i>Germany</i>]</p>\n</li>\n\n<li><b><i>11 Dec 1998</i></b>\n    <p>\n    In better news, I'm trying to convert all the developers here (30+) to use \n    ctags-3.0. Just finding enumeration fields will probably be enough for any\n    of us to switch!\n    </p>\n</li>\n\n<li><b><i>18 Nov 1998</i></b>\n    <p>\n    Hi....\n    </p>\n    <p>\n    Thank you very much for your quick reply\n    and detail explanation.\n    </p>\n    <p>\n    Since I received your mail I have spent time to make simple shell\n    script which should be executed in root hierarchy in project, create 2\n    files ( one for making \"tags\" in root hierarchy and subdirectories\n    previously listed, the other is \".vimrc\" file for setting VIM to update\n    necessary \"tags\" files when program source file is saved ), and making\n    symbolic link of .vimrc to each subdirectories. It's simple for veteran,\n    As for me, novice in shell script, It's an excellent accomplishment.\n    </p>\n    <p>\n    I used to think before that the internet is for someone who find\n    sexual things and for someone who earns money by less productive way.\n    But I am changing my mind by someone like you who use internet to make\n    better world. Thank you again.....\n    </p>\n    <p>[<i>Korea</i>]</p>\n</li>\n\n<li><b><i>23 Oct 1998</i></b>\n    <p>\n    First off, I would like to thank you for creating Exuberant Ctags.  This \n    program completely kicks ass, if you'll pardon me for saying so.  :)\n    </p>\n</li>\n\n<li><b><i>20 Oct 1998</i></b>\n    <p>\n    Well done on producing a very decent version of ctags. I use it at work\n    and at home and find it very useful for navigating moderately sized\n    projects. Thanks!\n    </p>\n</li>\n\n<li><b><i>25 Sep 1998</i></b>\n    <p>\n    Thanks for Exuberant Ctags - it is quite an improvement over ctags,\n    even gnu ctags.  \n    </p>\n</li>\n\n<li><b><i>24 Sep 1998</i></b>\n    <p>\n    I just spent the last few days integrating your Ctags program into our\n    build environment here.  On NT, Visual C++'s browse files don't work\n    because our project is too large.  So, I wrote a plug-in for Visual Studio\n    to use a tags file instead.  We are traditionally a Unix house and use\n    tags elsewhere.  Anyway, Ctags goes through our source in about 8 minutes\n    and generates a 20meg+ tags file (with lots of options turned off).\n    That's pretty impressive speed and thoroughness.\n    <p>\n    </p>\n    Thanks a lot for creating a great tool!\n    </p>\n</li>\n\n<li><b><i>17 Sep 1998</i></b>\n    <p>\n    Your ctags program is extremely useful and a key part of my development\n    environment.  Thank you for writing it. I'm sure it will live a loooong\n    life.\n    </p>\n</li>\n\n<li><b><i>26 Aug 1998</i></b>\n    <p>\n    Thanks for your great piece of software.  It has saved me the headache of\n    creating my own little C++ parser for a Microsoft Visual Studio addin I\n    was writing.\n    </p>\n</li>\n\n<li><b><i>24 Aug 1998</i></b>\n    <p>\n    I love your ctags program and I've gotten all my co-workers to love it too.\n    </p>\n</li>\n\n<li><b><i>24 Aug 1998</i></b>\n    <p>\n    Just to add my voice to the chorus of happy exuberant ctags users: it's\n    just great. \n    </p>\n    <p>[<i>Luxembourg</i>]</p>\n</li>\n\n<li><b><i>05 Aug 1998</i></b>\n    <p>\n    I am using your ctags for Java -- & it's is a great convenience! \n    ...This really is a great help for working in Java.\n    </p>\n    <p>[<i>Denmark</i>]</p>\n</li>\n\n<li><b><i>05 Aug 1998</i></b>\n    <p>\n    I very much appreciate what you have done for all of us with exuberant\n    Ctags!\n    </p>\n</li>\n\n<li><b><i>23 Jul 1998</i></b>\n    <p>\n    I'm using your WONDERFULL program ctags (Verison 2.2).\n    </p>\n    <p>[<i>Germany</i>]</p>\n</li>\n\n<li><b><i>21 Jul 1998</i></b>\n    <p>\n    Brilliant brilliant brilliant, thanks very much... Now a truly\n    indispensable piece of software. Thanks for the perfect companion for Vim.\n    </p>\n    <p>[<i>Australia</i>]</p>\n</li>\n\n<li><b><i>10 Jul 1998</i></b>\n    <p>\n    Again, ec21 is great, especially the C++ support.  Keep up the good work.\n    </p>\n</li>\n\n<li><b><i>02 Jul 1998</i></b>\n    <p>\n    You did an excellent job in producing this product, and you deserve *much*\n    thanks for it.\n    </p>\n</li>\n\n<li><b><i>01 Jul 1998</i></b>\n    </p>\n    ...the best ctags program in the world!\n    <p>\n</li>\n\n<li><b><i>15 Jun 1998</i></b>\n    <p>\n    Great product!  I'm trying to get others in my group to use this with vim.\n    </p>\n</li>\n\n<li><b><i>14 May 1998</i></b>\n    <p>\n    First of all, let me congratulate you on the terrific 2.0 release of \n    ctags with C++ support.\n    </p>\n</li>\n\n<li><b><i>05 May 1998</i></b>\n    <p>\n    I love the program.  It has the process of \"figuring out\" code much easier.\n    </p>\n</li>\n\n<li><b><i>03 May 1998</i></b>\n    <p>\n    I have just completed the task of changing Zeus [Win95 editor] to\n    support for your new tag file format and I have to say that I am very\n    impressed with your ctags.exe program. In fact it is just amazing!\n    </p>\n    <p>[<i>Australia</i>]</p>\n</li>\n\n<li><b><i>14 Mar 1998</i></b>\n    <p>\n    I would like to congradulate you on your implementation of Exuberant Ctags.\n    </p>\n    <p>\n    I have added master tag files for everything in /usr/include and I have\n    a cron job to build master tag files for the linux kernel(which makes for \n    highly productive hack sessions when you have nearly the entire kernel\n    at your fingertips). I often wonder how I got along for so many years \n    without it! In fact, I have converted users of the dreaded Microsoft(tm)\n    MSDEV(tm) IDE(probably a TM here too) to VIM-5.0 for NT(tm) along with\n    your implmentation of ctags because it was easier for them to navigate\n    around the code!\n    </p>\n    <p>\n    Now, whenever I use a ctags that isn't yours, I feel crippled in my ability\n    to write good code quickly. I love your enhancments to it.\n    </p>\n    <p>\n    Please keep up the good work! The world needs people like you. \n    </p>\n    <p>\n    [<i>And later...</i>]\n    </p>\n    <p>\n    I love the fact that if one really hates some piece of software, they\n    can get third party stuff written by people like you that are ten times\n    better than the original product.\n    ...Anyway. Once again, I thank you for writing such a valuable piece\n    of art, and that is really what it is.\n    </p>\n</li>\n\n<li><b><i>12 Mar 1998</i></b>\n    <p>\n    I just wanted to let you know that I have been looking for a program\n    just like ctags.... Definitely a service to the programming community!\n    </p>\n</li>\n\n<li><b><i>23 Jan 1998</i></b>\n    <p>\n    Thank you very much for writing Exuberant Ctags. It has been extremely\n    useful! \n    </p>\n</li>\n\n<li><b><i>04 Jan 1998</i></b>\n    <p>\n    I'm another enthusiastic fan of your exuberant ctags package; nice work! \n    I use it to streamline all of my C programming.  I'm addicted ;-). \n    </p>\n</li>\n\n<li><b><i>03 Dec 1997</i></b>\n    <p>\n    I just want to let you know that I really like your version of ctags.\n    I downloaded it about 6 months ago (probably need to update my copy)\n    and have been using it alot.\n    Thanks for the good work!\n    </p>\n</li>\n\n<li><b><i>12 Sep 1997</i></b>\n    <p>\n    I love your ctags program and have used it for about a year now and think\n    the additions are great.\n    </p>\n</li>\n\n<li><b><i>06 Jul 1997</i></b>\n    <p>\n    I've made heavy use of your Exuberant Ctags program this spring for my\n    Software Engineering and Data Structures courses at school -- coupled with\n    VIM this is a truly fantastic combo that saved my... er, *gluteus m.* on\n    several occasions!  Thanks SO much for a truly great program.\n    </p>\n</li>\n\n<li><b><i>11 Jun 1997</i></b>\n    <p>\n    Thanks for your GREAT work on ctags.\n    </p>\n    <p>[<i>Germany</i>]</p>\n</li>\n\n<li><b><i>27 May 1997</i></b>\n    <p>\n    Subject: exuberant ctags rocks!\n    </p>\n    <p>\n    ...gnu ctags didn't know squat about variables, structures, enums... etc.\n    </p>\n    <p>\n    After doing a search on the web for 'ctags' I found your\n    extended ctags.  What a lifesaver.  This thing does almost\n    everything a person could ask for.\n    </p>\n    <p>\n    It rocks, it rocks, it rocks.\n    </p>\n</li>\n\n<li><b><i>21 Apr 1997</i></b>\n    <p>\n    Hello.  One of my users told me about your ctags package.  They tell me\n    its great stuff.\n    </p>\n</li>\n\n<li><b><i>27 Mar 1997</i></b>\n    <p>\n    I've just begun using your ctags program and it is indeed wonderful!\n    </p>\n</li>\n\n<li><b><i>19 Feb 1997</i></b>\n    <p>\n    Wow!\n    </p>\n    <p>\n    I've been a vi/vim/ctags user for about 12 years now. Most of\n    those 12 years I've been frustrated by various tags generators and\n    wished someone would combine all the different features into a single\n    program. And have it work. I've never found the time/energy to tackle\n    that one (I've tackled enough other extracurricular programming). But,\n    now you've done it! And in a big way!\n    </p>\n    <p>\n    Hats off, I bow to you and send many grateful thanks.\n    </p>\n</li>\n\n<li><b><i>02 Oct 1996</i></b>\n    <p>\n    <code>main() { int i; for(i=0;i<10;i++) printf(\"WOWWOW\\n\");}</code>\n    </p>\n    <p>\n    Your new ctags is very very excellent.  Usually if I want to insert the\n    <code>enum</code>'ed variable into tags file, I always had to\n    \"<code>grep/awk/grep/awk/grep/awk/</code>\", then \"<code>:%!sort</code>\"\n    in vi... a lot of trouble to me.  Furthermore, it can give me all the\n    global variables, how excellent your package is!  And another thing.. is\n    If a source file is something like this,\n    <code>typedef void (*func_t)(const char **b, int c);</code>\n    Then other ctags gives me a very very strange results to me, on the\n    contrary your ctags gives me exact results.\n    </p>\n    <p>\n    I only downloaded your package about 2 hours ago, so there must be a lot\n    of new improvement that I didn't find out yet.\n    </p>\n    <p>\n    Thank you\n    </p>\n    <p>[<i>Korea</i>]</p>\n</li>\n\n<li><b><i>13 Aug 1996</i></b>\n    <p>\n    ...your ctags and your advice have and will save me countless hours\n    hunting down defines, functions, etc. Koodos for the effort and keep up\n    the good work.\n    </p>\n</li>\n\n<li><b><i>06 Aug 1996</i></b>\n    <p>\n    I've downloaded your ctags- it is great!!!  I have been pulling my hair\n    out trying to figure out how to do some of this.  The macros and extern'ed\n    functions are very, very helpful.  Also, I'd like to complement your on\n    your coding style: very consistent and fairly easy to read.  It definitely\n    shows when a software developer feels pride in their work.\n    </p>\n</li>\n\n<li><b><i>29 May 1996</i></b>\n    <p>\n    I use `ctags' on ugly source codes thus your version is very helpful.\n    Thank you!\n    </p>\n    <p>[<i>Russia</i>]</p>\n</li>\n\n<li><b><i>22 May 1996</i></b>\n    <p>\n    My initial impression (after 5 minutes use) is that it works better than\n    the solaris ctags. Excellent tool!\n    </p>\n    <p>[<i>United Kingdom</i>]</p>\n</li>\n\n<li><b><i>21 May 1996</i></b>\n    <p>\n    Been a long time ctags user. Love your improvements.\n    </p>\n</li>\n\n<li><b><i>10 May 1996</i></b>\n    <p>\n    I'm using ctags-0.31 and I'm quite happy with it.\n    </p>\n    <p>[<i>Finland</i>]</p>\n</li>\n\n<li><b><i>25 Apr 1996</i></b>\n    <p>\n    People will want to get Vim just because it includes such a fine ctags\n    program!\n    </p>\n    <p>[<i>Netherlands</i>]</p>\n</li>\n\n<li><b><i>17 Apr 1996</i></b>\n    <p>\n    I want to thank and congratulate you for ctags. \n    </p>\n    <p>[<i>Germany</i>]</p>\n</li>\n\n<li><b><i>16 Apr 1996</i></b>\n    <p>\n    Glad to see a major improvement of the (already) best ctags.\n    </p>\n    <p>[<i>Germany</i>]</p>\n</li>\n\n<li><b><i>02 Apr 1996</i></b>\n    <p>\n    First let me thank you for the ctags program. It handles finding of tags\n    better than every other ctags I've used so far.\n    </p>\n    <p>[<i>Germany</i>]</p>\n</li>\n\n<li><b><i>02 Apr 1996</i></b>\n    <p>\n    Wow!  I've just tried this out, and despite being the very first beta\n    release of this program, it already seems to be the best ctags program\n    I've seen.  Up to now I have been using the ctags that came with elvis,\n    and I've just compared the output \"tags\" files.\n    </p>\n    <p>\n    The elvis ctags had lots of little tags for things that shouldn't have had\n    tags (e.g. \"<code>if</code>\", \"<code>return</code>\", \"<code>TRUE</code>\",\n    etc.), but this new ctags doesn't produce tags for those.  It does find\n    several tags though that the elvis ctags could not (e.g.\n    \"<code>insstr</code>\" in the vim code!).\n    </p>\n    <p>\n    [<i>And later...</i>]\n    <p>\n    Wow!  All the bugs I reported last time have been fixed :-)  It does\n    indeed seem very robust now.  Well done!\n    </p>\n    <p>[<i>Australia</i>]</p>\n</li>\n\n</ul>\n\n<p><hr>\n<a href=\"http:index.html\">Back to <strong>Exuberant Ctags</strong></a>\n\n</body>\n</html>\n"
  },
  {
    "path": "old-docs/website/tool_support.html",
    "content": "<html>\n<head>\n<title>Exuberant Ctags: Addiing Tag File Support to Software Tools</title>\n</head>\n<body>\n\n<h1>How to Add Tag File Support to Software Tools</h1>\n\n<p>\n<strong>Exuberant Ctags</strong> now includes a library to easily add tag file\nsupport to software tools, such as editors. The distributed makefile contains\na target for library object file, <code>readtags.o</code>, and a demonstration\nprogram for the library, <code>readtags</code>.\n</p>\n\n<p>\nThe functions provided by this library are intended to provide tag file\nsupport to a software tool. The tag lookups provided are sufficiently fast\nenough to permit opening a sorted tag file, searching for a matching tag, then\nclosing the tag file each time a tag is looked up (search times are on the\norder of hundreths of a second, even for huge tag files). This is the\nrecommended use of this library for most tool applications. Adhering to this\napproach permits a user to regenerate a tag file at will without the tool\nneeding to detect and resynchronize with changes to the tag file. Even for an\nunsorted 24MB tag file, tag searches take about one second on my 650 MHz\nAthlon Linux machine.\n</p>\n\n<p>\nThe interface to the library is documented in the include file\n<code>readtags.h</code>. For an example implementation, see the function\n<code>findTag()</code> in the conditionally compiled portion of the source\nfile <code>readtags.c</code>.\n</p>\n\n<p>\nTo facilitate widespread support of tag files, the readtags library is\nreleased in the public domain, allowing its use in even commercial\napplications.\n</p>\n\n</body>\n</html>\n"
  },
  {
    "path": "old-docs/website/tools.html",
    "content": "<html>\n<head>\n<title>Editors and Tools Supporting CTAGS</title>\n</head>\n<body>\n\n<center>\n<h1>Editors and Tools Supporting CTAGS</h1>\n</center>\n\n<h2>Editors</h2>\n<ul>\n  <li>\n    <h3>Vi-style editors</h3>\n    <ul>\n      <li><a href=\"http://www.vim.org\">\n          Vim</a>, the official editor of <strong>Exuberant Ctags</strong></li>\n      <li><a href=\"http://www.clark.net/pub/dickey/vile/vile.html\">Vile</a></li>\n      <li><a href=\"http://www.softwareonline.org/lemmy.html\">Lemmy</a>,\n          a <strong>vi</strong> clone [Windows 95/NT].</li>\n      <li><a href=\"http://www.ibiblio.org/pub/Linux/apps/editors/vi\">\n          Other <strong>vi</strong> clones</a></li>\n    </ul>\n  </li>\n  <li>\n    <h3>Other editors</h3>\n    <ul>\n      <li><a href=\"http://www.boxersoftware.com\">Boxer</a> [Windows]</li>\n      <li><a href=\"http://www.crisp.com\">CRiSP</a> [Unix, Windows]</li>\n      <li><a href=\"http://www.gnu.org/software/emacs/emacs.html\">Emacs</a></li>\n      <li><a href=\"http://software.jessies.org/evergreen/\">Evergreen</a> [Unix, Windows, Mac OS X]</li>\n      <li><a href=\"http://fte.sourceforge.net\">FTE (Folding Text Editor)</a> [Unix, Windows, MSDOS, OS/2]</li>\n      <li><a href=\"http://www.stambouliote.de/projects/gedit_plugins.html\">gedit plugins</a> [Linux]</li>\n      <li><a href=\"http://space.mit.edu/~davis/jed\">JED</a> [Unix, VMS, MSDOS, OS/2, BeOS, QNX, Windows]</li>\n      <li><a href=\"http://www.jedit.org\">jEdit</a> [Unix, Windows, OS/2, MacOS]</li>\n      <li><a href=\"http://towo.net/mined/\">Mined</a> [Unix, DOS/Windows]</li>\n      <li><a href=\"http://nedit.org\">NEdit (Nirvana Edit)</a>, a GUI editor [Unix with Motif]</li>\n      <li><a href=\"http://setedit.sourceforge.net/\">SETEdit</a> [Unix, Windows, DOS, QNX]</li>\n      <li><a href=\"http://www.semware.com\">TSE (The SemWare Editor)</a> [Windows]</li>\n      <li><a href=\"http://www.ultraedit.com/\">UltraEdit</a> [Windows]</li>\n      <li><a href=\"http://pages.infinit.net/micbel/\">WorkSpace</a> [QNX]</li>\n      <li><a href=\"http://www.interlog.com/~bwt/\">X2</a> [Unix, Windows]</li>\n      <li><a href=\"http://www.vedit.com/\">VEDIT</a> [Unix, Windows]</li>\n      <li><a href=\"http://www.xemacs.org/\">XEmacs</a> [Unix, Windows]</li>\n      <li><a href=\"http://www.zeusedit.com\">Zeus for Windows</a></li>\n    </ul>\n  </li>\n</ul>\n\n<h2>Tools</h2>\n<ul>\n  <li><a href=\"http://www.barebones.com/products/bbedit/index.shtml\">BBEdit8</a> [Mac]</li>\n  <li><a href=\"http://www.newplanetsoftware.com/jcc/\">Code Crusader</a></li>\n  <li><a href=\"http://www.newplanetsoftware.com/medic/\">Code Medic</a></li>\n  <li><a href=\"http://users.pandora.be/bdr/pub/cshow\">CShow (greps C functions out of source code)</a></li>\n  <li><a href=\"http://code.google.com/p/dwoop/\">Dreamweaver IDE</a> [Windows]</li>\n  <li><a href=\"http://www.rarlab.com\">FAR</a> [Win32]</li>\n  <li><a href=\"http://www.iua.upf.es/~mdeboer/fltk/flIDE.html\">flIDE</a> [Unix]</li>\n  <li><a href=\"http://guisearch.sourceforge.net\">GUISearch</a> [Unix]</li>\n  <li><a href=\"http://www.jimbrooks.org/web/hypersrc/hypersrc.html\">hypersrc</a> [Unix]</li>\n  <li><a href=\"http://icomplete.sourceforge.net\">IComplete</a></li>\n  <li><a href=\"http://www.pietrobo.com/projects/IDEntify\">IDEntify</a> [Unix]</li>\n  <li><a href=\"http://insenvim.sourceforge.net\">Intellisense plugin for Vim</a></li>\n  <li><a href=\"http://sourceforge.net/projects/lxr\">lxr</a> [Linux]</li>\n  <li><a href=\"http://www.opensolaris.org/os/project/opengrok/\">OpenGrok</a>[Solaris]</li>\n  <li><a href=\"http://workspacewhiz.com\">Workspace Whiz!</a> [Win32]</li>\n  <li><a href=\"http://www.objectcentral.com/vide.htm\">VIDE (V Integrated Development Environment</a> [Unix and Windows 9x/NT]</li>\n</ul>\n\n<hr>\n<a href=\"http:index.html\">Back to <strong>Exuberant Ctags</strong></a>\n\n</body>\n</html>\n<!-- vim:set et ts=2 sts=2 sw=2: -->\n"
  },
  {
    "path": "old-docs/website/whatis.html",
    "content": "<html>\n<head>\n<title>What is Ctags?</title>\n</head>\n<body>\n\n<h1>What is ctags?</h1>\n\n<p>\n<strong>Ctags</strong> generates an index (or <i>tag</i>) file of language\nobjects found in source files that allows these items to be quickly and easily\nlocated by a text editor or other utility. A <i>tag</i> signifies a language\nobject for which an index entry is available (or, alternatively, the index\nentry created for that object).\n</p>\n\n<p>\nTag generation is supported for <a href=\"languages.html\">these programming languages</a>.\n</p>\n\n<p>\nA list of editors and tools utilizing tag files may be found <a\nhref=\"tools.html\">here</a>.\n</p>\n\n<hr>\n<a href=\"http:index.html\">Back to <strong>Exuberant Ctags</strong></a>\n\n</body>\n</html>\n"
  },
  {
    "path": "optlib/cmake.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/cmake.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeCMakeParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"variable\");\n\taddLanguageRegexTable (language, \"variableScoped\");\n\taddLanguageRegexTable (language, \"function\");\n\taddLanguageRegexTable (language, \"macro\");\n\taddLanguageRegexTable (language, \"target\");\n\taddLanguageRegexTable (language, \"option\");\n\taddLanguageRegexTable (language, \"project\");\n\taddLanguageRegexTable (language, \"commentBegin\");\n\taddLanguageRegexTable (language, \"commentMultiline\");\n\taddLanguageRegexTable (language, \"skipComment\");\n\taddLanguageRegexTable (language, \"skipWhiteSpace\");\n\taddLanguageRegexTable (language, \"skipToName\");\n\taddLanguageRegexTable (language, \"nextToken\");\n\taddLanguageRegexTable (language, \"inFunction\");\n\taddLanguageRegexTable (language, \"inVariable\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^sSfFmMaAoOpP# \\t\\n][^ #\\t\\n]*[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^set[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=variable}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^function[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=function}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^macro[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=macro}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^add_(custom_target|executable|library)[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=target}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^option[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=option}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^project[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=project}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^ \\t\\n]+[ \\t\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"variable\",\n\t                               \"^([A-Za-z0-9_.-]+)[ \\t\\n\\\\)]+\",\n\t                               \"\\\\1\", \"v\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"variable\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"variable\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"variable\",\n\t                               \"^([A-Za-z0-9_.-]+)(#)\",\n\t                               \"\\\\1\", \"v\", \"{tleave}{_advanceTo=2start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"variableScoped\",\n\t                               \"^[A-Za-z0-9_.-]+[# \\t\\n\\\\)]\",\n\t                               \"\", \"\", \"{tjump=inVariable}{_advanceTo=0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"variableScoped\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"variableScoped\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"function\",\n\t                               \"^([A-Za-z_][A-Za-z0-9_]*)([# \\t\\n\\\\)])\",\n\t                               \"\\\\1\", \"f\", \"{_advanceTo=2start}{tjump=inFunction}{scope=push}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"function\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"function\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macro\",\n\t                               \"^([A-Za-z_][A-Za-z0-9_]*)[ \\t\\n\\\\)]+\",\n\t                               \"\\\\1\", \"m\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macro\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macro\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macro\",\n\t                               \"^([A-Za-z_][A-Za-z0-9_]*)(#)\",\n\t                               \"\\\\1\", \"m\", \"{tleave}{_advanceTo=2start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"target\",\n\t                               \"^([A-Za-z0-9_.-]+)[ \\t\\n\\\\)]+\",\n\t                               \"\\\\1\", \"t\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"target\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"target\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"target\",\n\t                               \"^([A-Za-z0-9_.-]+)(#)\",\n\t                               \"\\\\1\", \"t\", \"{tleave}{_advanceTo=2start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"option\",\n\t                               \"^([A-Za-z0-9_.-]+)[ \\t\\n\\\\)]+\",\n\t                               \"\\\\1\", \"D\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"option\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"option\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"option\",\n\t                               \"^([A-Za-z0-9_.-]+)(#)\",\n\t                               \"\\\\1\", \"D\", \"{tleave}{_advanceTo=2start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"project\",\n\t                               \"^([A-Za-z0-9_.-]+)([# \\t\\n\\\\)])\",\n\t                               \"\\\\1\", \"p\", \"{tleave}{_advanceTo=2start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"project\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"project\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"commentBegin\",\n\t                               \"^\\\\[\\\\[\",\n\t                               \"\", \"\", \"{tjump=commentMultiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"commentBegin\",\n\t                               \"^[^\\n]*[ \\t\\n]*\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"commentMultiline\",\n\t                               \"^\\\\]\\\\][ \\t\\n]*\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"commentMultiline\",\n\t                               \"^.[^]]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipComment\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipWhiteSpace\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToName\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToName\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"nextToken\",\n\t                               \"^[^ \\t\\n]+[ \\t\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inFunction\",\n\t                               \"^([^eEsSfFmMaAoO# \\t\\n]|[eE][^nN]|[eE][nN][^dD]|[eE][nN][dD][^fF#])[^ #\\t\\n]*[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inFunction\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=commentBegin}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inFunction\",\n\t                               \"^set[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=variableScoped}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inFunction\",\n\t                               \"^function[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=function}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inFunction\",\n\t                               \"^macro[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=macro}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inFunction\",\n\t                               \"^endfunction[ \\t]*\\\\([^)]*\\\\)\",\n\t                               \"\", \"\", \"{icase}{tleave}{scope=pop}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inFunction\",\n\t                               \"^add_(custom_target|executable|library)[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=target}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inFunction\",\n\t                               \"^option[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{icase}{tenter=option}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inFunction\",\n\t                               \"^[^ \\t\\n]+[ \\t\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inFunction\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inVariable\",\n\t                               \"^[^\\\")]+((\\\"(\\\\\\\\\\\"|[^\\\"])*\\\")([^\\\")]+(\\\"(\\\\\\\\\\\"|[^\\\"])*\\\"))*)[ \\t\\n]PARENT_SCOPE[# \\t\\n)]\",\n\t                               \"\", \"\", \"{tjump=variable}{_advanceTo=0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inVariable\",\n\t                               \"^([A-Za-z0-9_.-]+)[ \\t\\n\\\\)]+\",\n\t                               \"\\\\1\", \"v\", \"{tleave}{scope=ref}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"inVariable\",\n\t                               \"^([A-Za-z0-9_.-]+)(#)\",\n\t                               \"\\\\1\", \"v\", \"{tleave}{scope=ref}{_advanceTo=2start}\", NULL);\n}\n\nextern parserDefinition* CMakeParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"cmake\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\t\"CMakeLists.txt\",\n\t\tNULL\n\t};\n\n\tstatic kindDefinition CMakeKindTable [] = {\n\t\t{\n\t\t  true, 'f', \"function\", \"functions\",\n\t\t},\n\t\t{\n\t\t  true, 'm', \"macro\", \"macros\",\n\t\t},\n\t\t{\n\t\t  true, 't', \"target\", \"targets\",\n\t\t},\n\t\t{\n\t\t  true, 'v', \"variable\", \"variable definitions\",\n\t\t},\n\t\t{\n\t\t  true, 'D', \"option\", \"options specified with -D\",\n\t\t},\n\t\t{\n\t\t  true, 'p', \"project\", \"projects\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"CMake\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = CMakeKindTable;\n\tdef->kindCount     = ARRAY_SIZE(CMakeKindTable);\n\tdef->initialize    = initializeCMakeParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/cmake.ctags",
    "content": "#\n#  cmake.ctags --- multitable regex parser for CMake's files\n#\n#  Copyright (c) 2018, 128 Technology, Inc.\n#\n#  Author: Hadriel Kaplan (hadrielk@yahoo.com)\n#\n#  This source code is released for free distribution under the terms of the\n#  GNU General Public License version 2 or (at your option) any later version.\n#\n#\n# Overview:\n#\n#  This universal-ctags optlib option file defines the parser for tagging\n#  CMake files. It supports tagging the following:\n#\n#    - cmake function and macro names\n#    - build target, executable, and library target names\n#    - cmake variables and options\n#    - cmake project names\n#\n# Caveats:\n#\n#  Names that are ${} references to variables are not tagged.\n#\n#  For example, given the following:\n#\n#    set(PROJECT_NAME_STR ${PROJECT_NAME})\n#    add_executable( ${PROJECT_NAME_STR} ... )\n#    add_custom_target( ${PROJECT_NAME_STR}_tests ... )\n#    add_library( sharedlib ... )\n#\n#  the variable 'PROJECT_NAME_STR' and target 'sharedlib' will both be tagged,\n#  but the other targets will not be.\n#\n#\n# References:\n#\n# - https://cmake.org/cmake/help/latest/manual/cmake-language.7.html\n#\n\n--langdef=CMake\n--map-CMake=+.cmake\n--map-CMake=+(CMakeLists.txt)\n\n#\n# Kinds\n#\n--kinddef-CMake=f,function,functions\n--kinddef-CMake=m,macro,macros\n--kinddef-CMake=t,target,targets\n--kinddef-CMake=v,variable,variable definitions\n--kinddef-CMake=D,option,options specified with -D\n--kinddef-CMake=p,project,projects\n\n#\n# Tables\n#\n--_tabledef-CMake=main\n--_tabledef-CMake=variable\n--_tabledef-CMake=variableScoped\n--_tabledef-CMake=function\n--_tabledef-CMake=macro\n--_tabledef-CMake=target\n--_tabledef-CMake=option\n--_tabledef-CMake=project\n\n#\n# comment\n#\n--_tabledef-CMake=commentBegin\n--_tabledef-CMake=commentMultiline\n\n--_mtable-regex-CMake=commentBegin/\\[\\[//{tjump=commentMultiline}\n--_mtable-regex-CMake=commentBegin/[^\\n]*[ \\t\\n]*//{tleave}\n\n--_mtable-regex-CMake=commentMultiline/\\]\\][ \\t\\n]*//{tleave}\n--_mtable-regex-CMake=commentMultiline/.[^]]*//\n\n--_tabledef-CMake=skipComment\n--_mtable-regex-CMake=skipComment/#//{tenter=commentBegin}\n\n#\n# Utilities\n#\n--_tabledef-CMake=skipWhiteSpace\n--_tabledef-CMake=skipToName\n--_tabledef-CMake=nextToken\n\n--_mtable-regex-CMake=skipWhiteSpace/[ \\t\\n]+//\n\n--_mtable-extend-CMake=skipToName+skipWhiteSpace\n--_mtable-extend-CMake=skipToName+skipComment\n\n--_mtable-regex-CMake=nextToken/[^ \\t\\n]+[ \\t\\n]*//\n\n#\n# main\n#\n# This first regex entry may seem odd - it's purely for improving performance, by\n# matching tokens with leading characters that could not possibly match a later regex,\n# and just skipping the whole token (and trailing whitespace). This one regex line\n# improved performance by an order of magnitude.\n--_mtable-regex-CMake=main/[^sSfFmMaAoOpP# \\t\\n][^ #\\t\\n]*[ \\t\\n]+//\n--_mtable-extend-CMake=main+skipComment\n--_mtable-regex-CMake=main/set[ \\t]*\\(//{icase}{tenter=variable}\n--_mtable-regex-CMake=main/function[ \\t]*\\(//{icase}{tenter=function}\n--_mtable-regex-CMake=main/macro[ \\t]*\\(//{icase}{tenter=macro}\n--_mtable-regex-CMake=main/add_(custom_target|executable|library)[ \\t]*\\(//{icase}{tenter=target}\n--_mtable-regex-CMake=main/option[ \\t]*\\(//{icase}{tenter=option}\n--_mtable-regex-CMake=main/project[ \\t]*\\(//{icase}{tenter=project}\n--_mtable-extend-CMake=main+nextToken\n--_mtable-extend-CMake=main+skipWhiteSpace\n\n#\n# For performance reasons, this is a separate table from 'main', mostly to avoid\n# matching tokens starting with 'e' in the main table - such tokens are very\n# common in CMake, due to 'endif()' and such\n#\n--_tabledef-CMake=inFunction\n--_mtable-regex-CMake=inFunction/([^eEsSfFmMaAoO# \\t\\n]|[eE][^nN]|[eE][nN][^dD]|[eE][nN][dD][^fF#])[^ #\\t\\n]*[ \\t\\n]+//\n--_mtable-extend-CMake=inFunction+skipComment\n--_mtable-regex-CMake=inFunction/set[ \\t]*\\(//{icase}{tenter=variableScoped}\n--_mtable-regex-CMake=inFunction/function[ \\t]*\\(//{icase}{tenter=function}\n--_mtable-regex-CMake=inFunction/macro[ \\t]*\\(//{icase}{tenter=macro}\n--_mtable-regex-CMake=inFunction/endfunction[ \\t]*\\([^)]*\\)//{icase}{tleave}{scope=pop}\n--_mtable-regex-CMake=inFunction/add_(custom_target|executable|library)[ \\t]*\\(//{icase}{tenter=target}\n--_mtable-regex-CMake=inFunction/option[ \\t]*\\(//{icase}{tenter=option}\n--_mtable-extend-CMake=inFunction+nextToken\n--_mtable-extend-CMake=inFunction+skipWhiteSpace\n\n#\n# Each of the following basically work the same way, and only differ in the\n# exact pattern allowed to be their name, and the Kind they add. Note that they\n# capture a required trailing '[ \\t\\n\\)]' or '#', to verify the full name token\n# matched the name's pattern, but then we advanceTo=2start for the next round,\n# so that we don't go past a potential '#' comment token but instead match it\n# again in the main table as a comment. The odds of a comment '#' immediately\n# following the name is very low, so we split it into its own check and do it\n# last in each table - this improves real-world performance ~10%, because in\n# the common case we can capture the whitespace at the same time as the name,\n# and not have to skip it again in the 'main' table.\n#\n\n#\n# variable\n#\n--_mtable-regex-CMake=variable/([A-Za-z0-9_.-]+)[ \\t\\n\\)]+/\\1/v/{tleave}\n--_mtable-extend-CMake=variable+skipToName\n--_mtable-regex-CMake=variable/([A-Za-z0-9_.-]+)(#)/\\1/v/{tleave}{_advanceTo=2start}\n\n# when a variable is defined inside a function, we reference its scope unless it\n# has a PARENT_SCOPE argument; unfortunately the regex for this can backtrack a\n# lot and the current ctags regex engine doesn't do lazy or atomic/possessive\n# captures to avoid it, but in practice this should be ok\n--_tabledef-CMake=inVariable\n--_mtable-regex-CMake=inVariable/[^\")]+((\"(\\\\\"|[^\"])*\")([^\")]+(\"(\\\\\"|[^\"])*\"))*)[ \\t\\n]PARENT_SCOPE[# \\t\\n)]//{tjump=variable}{_advanceTo=0start}\n--_mtable-regex-CMake=inVariable/([A-Za-z0-9_.-]+)[ \\t\\n\\)]+/\\1/v/{tleave}{scope=ref}\n--_mtable-regex-CMake=inVariable/([A-Za-z0-9_.-]+)(#)/\\1/v/{tleave}{scope=ref}{_advanceTo=2start}\n\n--_mtable-regex-CMake=variableScoped/[A-Za-z0-9_.-]+[# \\t\\n\\)]//{tjump=inVariable}{_advanceTo=0start}\n--_mtable-extend-CMake=variableScoped+skipToName\n\n\n#\n# function\n#\n--_mtable-regex-CMake=function/([A-Za-z_][A-Za-z0-9_]*)([# \\t\\n\\)])/\\1/f/{_advanceTo=2start}{tjump=inFunction}{scope=push}\n--_mtable-extend-CMake=function+skipToName\n\n#\n# macro: unlike functions, technically macros don't create scopes for any\n# variables set in them - the scope is whatever it is when the macro is invoked.\n# So we're not going to push a scope nor go into the 'inFunction' table.\n#\n--_mtable-regex-CMake=macro/([A-Za-z_][A-Za-z0-9_]*)[ \\t\\n\\)]+/\\1/m/{tleave}\n--_mtable-extend-CMake=macro+skipToName\n--_mtable-regex-CMake=macro/([A-Za-z_][A-Za-z0-9_]*)(#)/\\1/m/{tleave}{_advanceTo=2start}\n\n#\n# target\n#\n--_mtable-regex-CMake=target/([A-Za-z0-9_.-]+)[ \\t\\n\\)]+/\\1/t/{tleave}\n--_mtable-extend-CMake=target+skipToName\n--_mtable-regex-CMake=target/([A-Za-z0-9_.-]+)(#)/\\1/t/{tleave}{_advanceTo=2start}\n\n#\n# option\n#\n--_mtable-regex-CMake=option/([A-Za-z0-9_.-]+)[ \\t\\n\\)]+/\\1/D/{tleave}\n--_mtable-extend-CMake=option+skipToName\n--_mtable-regex-CMake=option/([A-Za-z0-9_.-]+)(#)/\\1/D/{tleave}{_advanceTo=2start}\n\n#\n# project\n#\n--_mtable-regex-CMake=project/([A-Za-z0-9_.-]+)([# \\t\\n\\)])/\\1/p/{tleave}{_advanceTo=2start}\n--_mtable-extend-CMake=project+skipToName\n"
  },
  {
    "path": "optlib/ctags-optlib.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/ctags-optlib.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeCtagsParser (const langType language CTAGS_ATTR_UNUSED)\n{\n}\n\nextern parserDefinition* CtagsParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"ctags\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition CtagsKindTable [] = {\n\t\t{\n\t\t  true, 'l', \"langdef\", \"language definitions\",\n\t\t},\n\t\t{\n\t\t  true, 'k', \"kind\", \"kind definitions\",\n\t\t},\n\t};\n\tstatic tagRegexTable CtagsTagRegexTable [] = {\n\t\t{\"^--langdef=([^ \\t]+)$\", \"\\\\1\",\n\t\t\"l\", \"{scope=set}\", NULL, false},\n\t\t{\"^--regex-[^=]+=.*/.,(.+)/.*\", \"\\\\1\",\n\t\t\"k\", \"{scope=ref}\", NULL, false},\n\t\t{\"^--kinddef-[^=]+=.,([^,]+),.*\", \"\\\\1\",\n\t\t\"k\", \"{scope=ref}\", NULL, false},\n\t};\n\n\n\tparserDefinition* const def = parserNew (\"Ctags\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = CtagsKindTable;\n\tdef->kindCount     = ARRAY_SIZE(CtagsKindTable);\n\tdef->tagRegexTable = CtagsTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(CtagsTagRegexTable);\n\tdef->initialize    = initializeCtagsParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/ctags-optlib.ctags",
    "content": "#\n#\n#  Copyright (c) 2014, Red Hat, Inc.\n#  Copyright (c) 2014, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n#\n--langdef=Ctags\n--map-Ctags=+.ctags\n--kinddef-Ctags=l,langdef,language definitions\n--kinddef-Ctags=k,kind,kind definitions\n--regex-Ctags=/^--langdef=([^ \\t]+)$/\\1/l/{scope=set}\n--regex-Ctags=/^--regex-[^=]+=.*\\/.,(.+)\\/.*/\\1/k/{scope=ref}\n--regex-Ctags=/^--kinddef-[^=]+=.,([^,]+),.*/\\1/k/{scope=ref}\n"
  },
  {
    "path": "optlib/elixir.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/elixir.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeElixirParser (const langType language CTAGS_ATTR_UNUSED)\n{\n}\n\nextern parserDefinition* ElixirParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"ex\",\n\t\t\"exs\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition ElixirKindTable [] = {\n\t\t{\n\t\t  true, 'p', \"protocol\", \"protocols (defprotocol...)\",\n\t\t},\n\t\t{\n\t\t  true, 'm', \"module\", \"modules (defmodule ...)\",\n\t\t},\n\t\t{\n\t\t  true, 'f', \"function\", \"functions (def ...)\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"callback\", \"callbacks (defcallback ...)\",\n\t\t},\n\t\t{\n\t\t  true, 'd', \"delegate\", \"delegates (defdelegate ...)\",\n\t\t},\n\t\t{\n\t\t  true, 'e', \"exception\", \"exceptions (defexception ...)\",\n\t\t},\n\t\t{\n\t\t  true, 'g', \"guard\", \"guards (defguard ...)\",\n\t\t},\n\t\t{\n\t\t  true, 'i', \"implementation\", \"implementations (defimpl ...)\",\n\t\t},\n\t\t{\n\t\t  true, 'a', \"macro\", \"macros (defmacro ...)\",\n\t\t},\n\t\t{\n\t\t  true, 'o', \"operator\", \"operators (e.g. \\\"defmacro a <<< b\\\")\",\n\t\t},\n\t\t{\n\t\t  true, 'r', \"record\", \"records (defrecord...)\",\n\t\t},\n\t\t{\n\t\t  true, 't', \"test\", \"tests (test ...)\",\n\t\t},\n\t\t{\n\t\t  true, 'y', \"type\", \"types (@type ...)\",\n\t\t},\n\t};\n\tstatic tagRegexTable ElixirTagRegexTable [] = {\n\t\t{\"^[ \\t]*defprotocol[ \\t]+([A-Z][a-zA-Z0-9_]*\\\\.)*([A-Z][a-zA-Z0-9_?!]*)\", \"\\\\2\",\n\t\t\"p\", \"{scope=set}\", NULL, false},\n\t\t{\"^[ \\t]*defmodule[ \\t]+([A-Z][a-zA-Z0-9_]*\\\\.)*([A-Z][a-zA-Z0-9_?!]*)\", \"\\\\2\",\n\t\t\"m\", \"{scope=set}\", NULL, false},\n\t\t{\"^[ \\t]*def((p?)|macro(p?))[ \\t]+([a-zA-Z0-9_?!]+)[ \\t]+([\\\\|\\\\^/&<>~.=!*+-]{1,3}|and|or|in|(not( +in)?)|when)[ \\t]+[a-zA-Z0-9_?!]\", \"\\\\5\",\n\t\t\"o\", \"{scope=ref}{exclusive}\", NULL, false},\n\t\t{\"^[ \\t]*def[ \\t]+([a-z_][a-zA-Z0-9_?!]*)\", \"\\\\1\",\n\t\t\"f\", \"{scope=ref}{{. (public) access:}}\", NULL, false},\n\t\t{\"^[ \\t]*defp[ \\t]+([a-z_][a-zA-Z0-9_?!]*)\", \"\\\\1\",\n\t\t\"f\", \"{scope=ref}{{. (private) access:}}\", NULL, false},\n\t\t{\"^[ \\t]*(@|def)callback[ \\t]+([a-z_][a-zA-Z0-9_?!]*)\", \"\\\\2\",\n\t\t\"c\", \"{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*defdelegate[ \\t]+([a-z_][a-zA-Z0-9_?!]*)\", \"\\\\1\",\n\t\t\"d\", \"{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*defexception[ \\t]+([A-Z][a-zA-Z0-9_]*\\\\.)*([A-Z][a-zA-Z0-9_?!]*)\", \"\\\\2\",\n\t\t\"e\", \"{scope=ref}{exclusive}\", NULL, false},\n\t\t{\"^[ \\t]*defexception[ \\t]+\", \"\",\n\t\t\"\", \"{exclusive}\"\n\t\t\"{{\\n\"\n\t\t\"    _scopetop {\\n\"\n\t\t\"        dup :kind /module eq {\\n\"\n\t\t\"            dup\\n\"\n\t\t\"            :name /exception _tag _commit exch scope:\\n\"\n\t\t\"        } if\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL, false},\n\t\t{\"^[ \\t]*defguard[ \\t]+(is_[a-zA-Z0-9_?!]+)\", \"\\\\1\",\n\t\t\"g\", \"{scope=ref}{{. (public) access:}}\", NULL, false},\n\t\t{\"^[ \\t]*defguardp[ \\t]+(is_[a-zA-Z0-9_?!]+)\", \"\\\\1\",\n\t\t\"g\", \"{scope=ref}{{. (private) access:}}\", NULL, false},\n\t\t{\"^[ \\t]*defimpl[ \\t]+([A-Z][a-zA-Z0-9_]*\\\\.)*([A-Z][a-zA-Z0-9_?!]*)\", \"\\\\2\",\n\t\t\"i\", \"{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*defmacro[ \\t]+([a-z_][a-zA-Z0-9_?!]*)(.[^\\\\|\\\\^/&<>~.=!*+-]+)\", \"\\\\1\",\n\t\t\"a\", \"{scope=ref}{{. (public) access:}}\", NULL, false},\n\t\t{\"^[ \\t]*defmacrop[ \\t]+([a-z_][a-zA-Z0-9_?!]*)(.[^\\\\|\\\\^/&<>~.=!*+-]+)\", \"\\\\1\",\n\t\t\"a\", \"{scope=ref}{{. (private) access:}}\", NULL, false},\n\t\t{\"^[ \\t]*Record\\\\.defrecord[ \\t(]+:([a-zA-Z0-9_]+)(\\\\)?)\", \"\\\\1\",\n\t\t\"r\", \"{scope=ref}{{. (public) access:}}\", NULL, false},\n\t\t{\"^[ \\t]*Record\\\\.defrecordp[ \\t(]+:([a-zA-Z0-9_]+)(\\\\)?)\", \"\\\\1\",\n\t\t\"r\", \"{scope=ref}{{. (private) access:}}\", NULL, false},\n\t\t{\"^[ \\t]*test[ \\t(]+\\\"([a-z_][a-zA-Z0-9_?! ]*)\\\"*(\\\\)?)[ \\t]*do\", \"\\\\1\",\n\t\t\"t\", \"{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*@(type|opaque)[ \\t]+([a-z_][a-zA-Z0-9_?!]*)\", \"\\\\2\",\n\t\t\"y\", \"{scope=ref}{{. (public) access:}}\", NULL, false},\n\t\t{\"^[ \\t]*@typep[ \\t]+([a-z_][a-zA-Z0-9_?!]*)\", \"\\\\1\",\n\t\t\"y\", \"{scope=ref}{{. (private) access:}}\", NULL, false},\n\t};\n\n\n\tparserDefinition* const def = parserNew (\"Elixir\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = ElixirKindTable;\n\tdef->kindCount     = ARRAY_SIZE(ElixirKindTable);\n\tdef->tagRegexTable = ElixirTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(ElixirTagRegexTable);\n\tdef->initialize    = initializeElixirParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/elixir.ctags",
    "content": "#\n# This is free and unencumbered software released into the public domain.\n#\n# Anyone is free to copy, modify, publish, use, compile, sell, or\n# distribute this software, either in source code form or as a compiled\n# binary, for any purpose, commercial or non-commercial, and by any\n# means.\n#\n# In jurisdictions that recognize copyright laws, the author or authors\n# of this software dedicate any and all copyright interest in the\n# software to the public domain. We make this dedication for the benefit\n# of the public at large and to the detriment of our heirs and\n# successors. We intend this dedication to be an overt act of\n# relinquishment in perpetuity of all present and future rights to this\n# software under copyright law.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n#\n# For more information, please refer to <http://unlicense.org>\n#\n\n#\n# WHEN FIXING A BUG OF THIS PARSER, WORK WITH THE UPSTREAM PROJECT.\n#\n\n#\n# This file is imported from https://github.com/mmorearty/elixir-ctags\n# by Masatake YAMATO <yamato@redhat.com> with some modifications.\n# See https://github.com/mmorearty/elixir-ctags/issues/5 and\n# https://github.com/universal-ctags/ctags/issues/1758#issuecomment-391692762.\n# @dylan-chong and @FredrikAugust realized this u-ctags integration.\n#\n\n#\n# * Put the original LICENSE file as the header of the .ctags.\n# * Use --map= option instead of --langmap because optlib2c doesn't handle\n#   --langmap option.\n# * Define kinds explicitly with --kinddef-<LANG> option.\n# * Remove backslashes before double quotes chars in the regex pattern for\n#  \"test\".\n# * Use singular forms for kind names.\n#\n\n--langdef=Elixir\n\n--map-Elixir=+.ex\n--map-Elixir=+.exs\n\n--kinddef-Elixir=p,protocol,protocols (defprotocol...)\n--kinddef-Elixir=m,module,modules (defmodule ...)\n--kinddef-Elixir=f,function,functions (def ...)\n--kinddef-Elixir=c,callback,callbacks (defcallback ...)\n--kinddef-Elixir=d,delegate,delegates (defdelegate ...)\n--kinddef-Elixir=e,exception,exceptions (defexception ...)\n--kinddef-Elixir=g,guard,guards (defguard ...)\n--kinddef-Elixir=i,implementation,implementations (defimpl ...)\n--kinddef-Elixir=a,macro,macros (defmacro ...)\n--kinddef-Elixir=o,operator,operators (e.g. \"defmacro a <<< b\")\n--kinddef-Elixir=r,record,records (defrecord...)\n--kinddef-Elixir=t,test,tests (test ...)\n--kinddef-Elixir=y,type,types (@type ...)\n\n--regex-Elixir=/^[ \\t]*defprotocol[ \\t]+([A-Z][a-zA-Z0-9_]*\\.)*([A-Z][a-zA-Z0-9_?!]*)/\\2/p/{scope=set}\n--regex-Elixir=/^[ \\t]*defmodule[ \\t]+([A-Z][a-zA-Z0-9_]*\\.)*([A-Z][a-zA-Z0-9_?!]*)/\\2/m/{scope=set}\n--regex-Elixir=/^[ \\t]*def((p?)|macro(p?))[ \\t]+([a-zA-Z0-9_?!]+)[ \\t]+([\\|\\^\\/&<>~.=!*+-]{1,3}|and|or|in|(not( +in)?)|when)[ \\t]+[a-zA-Z0-9_?!]/\\5/o/{scope=ref}{exclusive}\n--regex-Elixir=/^[ \\t]*def[ \\t]+([a-z_][a-zA-Z0-9_?!]*)/\\1/f/{scope=ref}{{. (public) access:}}\n--regex-Elixir=/^[ \\t]*defp[ \\t]+([a-z_][a-zA-Z0-9_?!]*)/\\1/f/{scope=ref}{{. (private) access:}}\n--regex-Elixir=/^[ \\t]*(@|def)callback[ \\t]+([a-z_][a-zA-Z0-9_?!]*)/\\2/c/{scope=ref}\n--regex-Elixir=/^[ \\t]*defdelegate[ \\t]+([a-z_][a-zA-Z0-9_?!]*)/\\1/d/{scope=ref}\n--regex-Elixir=/^[ \\t]*defexception[ \\t]+([A-Z][a-zA-Z0-9_]*\\.)*([A-Z][a-zA-Z0-9_?!]*)/\\2/e/{scope=ref}{exclusive}\n--regex-Elixir=/^[ \\t]*defexception[ \\t]+//{exclusive}{{\n    _scopetop {\n        dup :kind /module eq {\n            dup\n            :name /exception _tag _commit exch scope:\n        } if\n    } if\n}}\n--regex-Elixir=/^[ \\t]*defguard[ \\t]+(is_[a-zA-Z0-9_?!]+)/\\1/g/{scope=ref}{{. (public) access:}}\n--regex-Elixir=/^[ \\t]*defguardp[ \\t]+(is_[a-zA-Z0-9_?!]+)/\\1/g/{scope=ref}{{. (private) access:}}\n--regex-Elixir=/^[ \\t]*defimpl[ \\t]+([A-Z][a-zA-Z0-9_]*\\.)*([A-Z][a-zA-Z0-9_?!]*)/\\2/i/{scope=ref}\n--regex-Elixir=/^[ \\t]*defmacro[ \\t]+([a-z_][a-zA-Z0-9_?!]*)(.[^\\|\\^\\/&<>~.=!*+-]+)/\\1/a/{scope=ref}{{. (public) access:}}\n--regex-Elixir=/^[ \\t]*defmacrop[ \\t]+([a-z_][a-zA-Z0-9_?!]*)(.[^\\|\\^\\/&<>~.=!*+-]+)/\\1/a/{scope=ref}{{. (private) access:}}\n--regex-Elixir=/^[ \\t]*Record\\.defrecord[ \\t(]+:([a-zA-Z0-9_]+)(\\)?)/\\1/r/{scope=ref}{{. (public) access:}}\n--regex-Elixir=/^[ \\t]*Record\\.defrecordp[ \\t(]+:([a-zA-Z0-9_]+)(\\)?)/\\1/r/{scope=ref}{{. (private) access:}}\n--regex-Elixir=/^[ \\t]*test[ \\t(]+\"([a-z_][a-zA-Z0-9_?! ]*)\"*(\\)?)[ \\t]*do/\\1/t/{scope=ref}\n--regex-Elixir=/^[ \\t]*@(type|opaque)[ \\t]+([a-z_][a-zA-Z0-9_?!]*)/\\2/y/{scope=ref}{{. (public) access:}}\n--regex-Elixir=/^[ \\t]*@typep[ \\t]+([a-z_][a-zA-Z0-9_?!]*)/\\1/y/{scope=ref}{{. (private) access:}}\n"
  },
  {
    "path": "optlib/forth.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/forth.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n#include \"selectors.h\"\n\n\nstatic void initializeForthParser (const langType language CTAGS_ATTR_UNUSED)\n{\n}\n\nextern parserDefinition* ForthParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"fth\",\n\t\t\"forth\",\n\t\t\"fs\",\n\t\t\"4th\",\n\t\t\"f\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition ForthKindTable [] = {\n\t\t{\n\t\t  true, 'w', \"word\", \"words\",\n\t\t},\n\t\t{\n\t\t  true, 'v', \"variable\", \"variables\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"constant\", \"constants\",\n\t\t},\n\t};\n\tstatic tagRegexTable ForthTagRegexTable [] = {\n\t\t{\"^[[:space:]]*\\\\\\\\.*\", \"\",\n\t\t\"\", \"{exclusive}\", NULL, false},\n\t\t{\"^:[[:space:]]+([^[:space:]]+)\", \"\\\\1\",\n\t\t\"w\", \"{exclusive}\", NULL, false},\n\t\t{\"^variable[[:space:]]+([^[:space:]]+)\", \"\\\\1\",\n\t\t\"v\", \"{exclusive}{icase}\", NULL, false},\n\t\t{\"^[[:alnum:]]+[[:space:]]+constant[[:space:]]+([^[:space:]]+)\", \"\\\\1\",\n\t\t\"c\", \"{exclusive}{icase}\", NULL, false},\n\t};\n\n\tstatic selectLanguage selectors[] = { selectFortranOrForthByForthMarker, NULL };\n\n\tparserDefinition* const def = parserNew (\"Forth\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->selectLanguage= selectors;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->kindTable     = ForthKindTable;\n\tdef->kindCount     = ARRAY_SIZE(ForthKindTable);\n\tdef->tagRegexTable = ForthTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(ForthTagRegexTable);\n\tdef->initialize    = initializeForthParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/forth.ctags",
    "content": "#\n#  Copyright (c) 2023, Eric Forgeot\n#  Copyright (c) 2023, Masatake YAMATO\n#\n#  This source code is released for free distribution under the terms of the\n#  GNU General Public License version 2 or (at your opinion) any later version.\n#\n#  This module contains functions for generating tags for Forth files\n#  https://www.forth.com/starting-forth/1-forth-stacks-dictionary/\n#\n--langdef=Forth\n--map-Forth=+.fth\n--map-Forth=+.forth\n--map-Forth=+.fs\n--map-Forth=+.4th\n\n--map-Forth=+.f\n--__selector-Forth=selectFortranOrForthByForthMarker\n\n--kinddef-Forth=w,word,words\n--kinddef-Forth=v,variable,variables\n--kinddef-Forth=c,constant,constants\n\n--regex-Forth=/^[[:space:]]*\\\\.*//{exclusive}\n--regex-Forth=/^:[[:space:]]+([^[:space:]]+)/\\1/w/{exclusive}\n--regex-Forth=/^variable[[:space:]]+([^[:space:]]+)/\\1/v/{exclusive}{icase}\n--regex-Forth=/^[[:alnum:]]+[[:space:]]+constant[[:space:]]+([^[:space:]]+)/\\1/c/{exclusive}{icase}\n"
  },
  {
    "path": "optlib/gdbinit.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/gdbinit.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeGdbinitParser (const langType language CTAGS_ATTR_UNUSED)\n{\n}\n\nextern parserDefinition* GdbinitParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"gdb\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\t\".gdbinit\",\n\t\tNULL\n\t};\n\n\tstatic kindDefinition GdbinitKindTable [] = {\n\t\t{\n\t\t  true, 'd', \"definition\", \"definitions\",\n\t\t},\n\t\t{\n\t\t  false, 'D', \"document\", \"documents\",\n\t\t},\n\t\t{\n\t\t  true, 't', \"toplevelVariable\", \"toplevel variables\",\n\t\t},\n\t\t{\n\t\t  false, 'l', \"localVariable\", \"local variables\",\n\t\t},\n\t};\n\tstatic tagRegexTable GdbinitTagRegexTable [] = {\n\t\t{\"^#.*\", \"\",\n\t\t\"\", \"{exclusive}\", NULL, false},\n\t\t{\"^define[[:space:]]+([^[:space:]]+)$\", \"\\\\1\",\n\t\t\"d\", NULL, NULL, false},\n\t\t{\"^document[[:space:]]+([^[:space:]]+)$\", \"\\\\1\",\n\t\t\"D\", NULL, NULL, false},\n\t\t{\"^set[[:space:]]+\\\\$([a-zA-Z0-9_]+)[[:space:]]*=\", \"\\\\1\",\n\t\t\"t\", NULL, NULL, false},\n\t\t{\"^[[:space:]]+set[[:space:]]+\\\\$([a-zA-Z0-9_]+)[[:space:]]*=\", \"\\\\1\",\n\t\t\"l\", NULL, NULL, false},\n\t};\n\n\n\tparserDefinition* const def = parserNew (\"Gdbinit\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->kindTable     = GdbinitKindTable;\n\tdef->kindCount     = ARRAY_SIZE(GdbinitKindTable);\n\tdef->tagRegexTable = GdbinitTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(GdbinitTagRegexTable);\n\tdef->initialize    = initializeGdbinitParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/gdbinit.ctags",
    "content": "#\n#\n#  Copyright (c) 2015, Red Hat, Inc.\n#  Copyright (c) 2015, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n#\n--langdef=Gdbinit\n--map-Gdbinit=+(.gdbinit)\n--map-Gdbinit=+.gdb\n--kinddef-Gdbinit=d,definition,definitions\n--kinddef-Gdbinit=D,document,documents\n--kinddef-Gdbinit=t,toplevelVariable,toplevel variables\n--kinddef-Gdbinit=l,localVariable,local variables\n\n##\n## Ignore comments\n##\n--regex-Gdbinit=/^#.*//{exclusive}\n\n##\n## define\n##\n--regex-Gdbinit=/^define[[:space:]]+([^[:space:]]+)$/\\1/d/\n\n##\n## document\n##\n--regex-Gdbinit=/^document[[:space:]]+([^[:space:]]+)$/\\1/D/\n--kinds-Gdbinit=-D\n\n##\n## set $...\n##\n--regex-Gdbinit=/^set[[:space:]]+\\$([a-zA-Z0-9_]+)[[:space:]]*=/\\1/t/\n\n##\n## __...set $...\n##\n--regex-Gdbinit=/^[[:space:]]+set[[:space:]]+\\$([a-zA-Z0-9_]+)[[:space:]]*=/\\1/l/\n--kinds-Gdbinit=-l\n"
  },
  {
    "path": "optlib/gomod.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/gomod.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeGoModParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"main\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^module[ \\t]+([^ \\t\\n]+)([\\n]|)\",\n\t                               \"\\\\1\", \"m\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^\\n]*[\\n]\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* GoModParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\t\"go.mod\",\n\t\tNULL\n\t};\n\n\tstatic kindDefinition GoModKindTable [] = {\n\t\t{\n\t\t  true, 'm', \"module\", \"modules\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"GoMod\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->kindTable     = GoModKindTable;\n\tdef->kindCount     = ARRAY_SIZE(GoModKindTable);\n\tdef->initialize    = initializeGoModParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/gomod.ctags",
    "content": "#\n#  Copyright (c) 2025, Red Hat, Inc.\n#  Copyright (c) 2025, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n# Reference:\n#  https://go.dev/doc/modules/gomod-ref\n#\n--langdef=GoMod\n--map-GoMod=+(go.mod)\n--kinddef-GoMod=m,module,modules\n\n--_tabledef-GoMod=main\n--_mtable-regex-GoMod=main/module[ \\t]+([^ \\t\\n]+)([\\n]|)/\\1/m/\n--_mtable-regex-GoMod=main/[^\\n]*[\\n]//\n--_mtable-regex-GoMod=main/.//\n"
  },
  {
    "path": "optlib/gperf.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/gperf.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeGPerfParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"codeinc\");\n\taddLanguageRegexTable (language, \"keywordsec\");\n\taddLanguageRegexTable (language, \"functions\");\n\taddLanguageRegexTable (language, \"structdec\");\n\taddLanguageRegexTable (language, \"struct\");\n\taddLanguageRegexTable (language, \"structbody\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^%\\\\{\",\n\t                               \"\", \"\", \"{tjump=codeinc}{_guest=C,0end,}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^struct[ \\t]\",\n\t                               \"\", \"\", \"{_guest=C,0start,}{tenter=struct}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^%%\",\n\t                               \"\", \"\", \"{tjump=keywordsec}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^%define[ \\t]+(hash-function-name|lookup-function-name|class-name|string-pool-name)[ \\t]+([_a-zA-Z:][_a-zA-Z:0-9]*)[^\\n]*\\n\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"  \\\\2\\n\"\n\t\t\"  << (hash-function-name)   /hfunc\\n\"\n\t\t\"     (lookup-function-name) /lfunc\\n\"\n\t\t\"     (class-name)           /class\\n\"\n\t\t\"     (string-pool-name)     /strpool >> \\\\1 get\\n\"\n\t\t\"  @2\\n\"\n\t\t\"  _tag _commit pop\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^\\n]*\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^[^*]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^\\\\*/\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"codeinc\",\n\t                               \"^[^%]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"codeinc\",\n\t                               \"^%\\\\}\",\n\t                               \"\", \"\", \"{tjump=structdec}{_guest=,,0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"codeinc\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"keywordsec\",\n\t                               \"^%%\",\n\t                               \"\", \"\", \"{tjump=functions}{_guest=C,0end,}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"keywordsec\",\n\t                               \"^#[^\\n]*\\n?\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"keywordsec\",\n\t                               \"^([^\\n,]+)[^\\n]*\\n?\",\n\t                               \"\\\\1\", \"k\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"keywordsec\",\n\t                               \"^[^\\n]*\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"functions\",\n\t                               \"^.+\",\n\t                               \"\", \"\", \"{_guest=,,0end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"structdec\",\n\t                               \"^struct[ \\t]\",\n\t                               \"\", \"\", \"{_guest=C,0start,}{tenter=struct}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"structdec\",\n\t                               \"^%%\",\n\t                               \"\", \"\", \"{tjump=keywordsec}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"structdec\",\n\t                               \"^%define[ \\t]+(hash-function-name|lookup-function-name|class-name|string-pool-name)[ \\t]+([_a-zA-Z:][_a-zA-Z:0-9]*)[^\\n]*\\n\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"  \\\\2\\n\"\n\t\t\"  << (hash-function-name)   /hfunc\\n\"\n\t\t\"     (lookup-function-name) /lfunc\\n\"\n\t\t\"     (class-name)           /class\\n\"\n\t\t\"     (string-pool-name)     /strpool >> \\\\1 get\\n\"\n\t\t\"  @2\\n\"\n\t\t\"  _tag _commit pop\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"structdec\",\n\t                               \"^[^\\n]*\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"struct\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=structbody}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"struct\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"struct\",\n\t                               \"^;\",\n\t                               \"\", \"\", \"{tleave}{_guest=,,0end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"struct\",\n\t                               \"^%\",\n\t                               \"\", \"\", \"{tleave}{_guest=,,0end}{_advanceTo=0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"struct\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"structbody\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"structbody\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=structbody}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"structbody\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"structbody\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* GPerfParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"perf\",\n\t\t\"gperf\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition GPerfKindTable [] = {\n\t\t{\n\t\t  true, 'k', \"keyword\", \"keywords\",\n\t\t},\n\t\t{\n\t\t  true, 'h', \"hfunc\", \"hash function names\",\n\t\t},\n\t\t{\n\t\t  true, 'l', \"lfunc\", \"lookup function names\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"class\", \"class names\",\n\t\t},\n\t\t{\n\t\t  true, 's', \"strpool\", \"string pool names\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"GPerf\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = GPerfKindTable;\n\tdef->kindCount     = ARRAY_SIZE(GPerfKindTable);\n\tdef->initialize    = initializeGPerfParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/gperf.ctags",
    "content": "#\n# gperf.ctags --- multitable regex parser for gperf input\n#\n# Copyright (c) 2022, Red Hat, Inc.\n# Copyright (c) 2022, Masatake YAMATO\n#\n# Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n# Reference:\n#\n# - https://www.gnu.org/software/gperf/manual/gperf.html\n#\n\n--langdef=GPerf\n\n#\n# Map definitions\n#\n--map-GPerf=+.perf\n--map-GPerf=+.gperf\n\n#\n# Kind definitions\n#\n--kinddef-GPerf=k,keyword,keywords\n--kinddef-GPerf=h,hfunc,hash function names\n--kinddef-GPerf=l,lfunc,lookup function names\n--kinddef-GPerf=c,class,class names\n--kinddef-GPerf=s,strpool,string pool names\n\n#\n# Table declarations\n#\n--_tabledef-GPerf=main\n--_tabledef-GPerf=comment\n--_tabledef-GPerf=codeinc\n--_tabledef-GPerf=keywordsec\n--_tabledef-GPerf=functions\n--_tabledef-GPerf=structdec\n\n#\n# Table definitions\n#\n--_mtable-regex-GPerf=comment/[^*]+//\n--_mtable-regex-GPerf=comment/\\*\\///{tleave}\n--_mtable-regex-GPerf=comment/.//\n\n#\n# codeinc:\n# - run the C parser on the area %{ ... %}\n#\n--_mtable-regex-GPerf=codeinc/[^%]+//\n--_mtable-regex-GPerf=codeinc/%\\}//{tjump=structdec}{_guest=,,0start}\n--_mtable-regex-GPerf=codeinc/.//\n\n#\n# structdec:\n# - run the C parser on the area %} struct ...; %%\n# - extract %define ... used in the area %} ...; %%\n#\n--_tabledef-GPerf=struct\n--_tabledef-GPerf=structbody\n\n--_mtable-regex-GPerf=structdec/struct[ \\t]//{_guest=C,0start,}{tenter=struct}\n--_mtable-regex-GPerf=structdec/%%//{tjump=keywordsec}\n--_mtable-regex-GPerf=structdec/%define[ \\t]+(hash-function-name|lookup-function-name|class-name|string-pool-name)[ \\t]+([_a-zA-Z:][_a-zA-Z:0-9]*)[^\\n]*\\n//{{\n  \\2\n  << (hash-function-name)   /hfunc\n     (lookup-function-name) /lfunc\n     (class-name)           /class\n     (string-pool-name)     /strpool >> \\1 get\n  @2\n  _tag _commit pop\n}}\n--_mtable-regex-GPerf=structdec/[^\\n]*\\n//\n\n--_mtable-regex-GPerf=struct/\\{//{tenter=structbody}\n--_mtable-regex-GPerf=struct/\\/\\*//{tenter=comment}\n--_mtable-regex-GPerf=struct/;//{tleave}{_guest=,,0end}\n--_mtable-regex-GPerf=struct/%//{tleave}{_guest=,,0end}{_advanceTo=0start}\n--_mtable-regex-GPerf=struct/.//\n\n--_mtable-regex-GPerf=structbody/\\}//{tleave}\n--_mtable-regex-GPerf=structbody/\\{//{tenter=structbody}\n--_mtable-regex-GPerf=structbody/\\/\\*//{tenter=comment}\n--_mtable-regex-GPerf=structbody/.//\n\n#\n# keywordsec:\n# - extract keywords defined in %% ... %%\n#\n--_mtable-regex-GPerf=keywordsec/%%//{tjump=functions}{_guest=C,0end,}\n--_mtable-regex-GPerf=keywordsec/^#[^\\n]*\\n?//\n--_mtable-regex-GPerf=keywordsec/([^\\n,]+)[^\\n]*\\n?/\\1/k/\n--_mtable-regex-GPerf=keywordsec/[^\\n]*\\n//\n\n#\n# functions:\n# - run the C parser on the area %% ... EOF\n#\n--_mtable-regex-GPerf=functions/.+//{_guest=,,0end}\n\n#\n# main:\n#\n--_mtable-regex-GPerf=main/\\/\\*//{tenter=comment}\n--_mtable-regex-GPerf=main/%\\{//{tjump=codeinc}{_guest=C,0end,}\n--_mtable-extend-GPerf=main+structdec\n"
  },
  {
    "path": "optlib/iPythonCell.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/iPythonCell.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n#include \"subparser.h\"\n\n\nstatic void initializeIPythonCellParser (const langType language CTAGS_ATTR_UNUSED)\n{\n}\n\nextern parserDefinition* IPythonCellParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition IPythonCellKindTable [] = {\n\t\t{\n\t\t  true, 'c', \"cell\", \"cells\",\n\t\t},\n\t};\n\tstatic xtagDefinition IPythonCellXtagTable [] = {\n\t\t{\n\t\t  .enabled     = false,\n\t\t  .name        = \"doubleSharps\",\n\t\t  .description = \"Include cells starting from ##\",\n\t\t},\n\t};\n\tstatic tagRegexTable IPythonCellTagRegexTable [] = {\n\t\t{\"^[ \\t]*(# ?%%|# <codecell>)[ \\t]*(.*[^ \\t])$\", \"\\\\2\",\n\t\t\"c\", \"{exclusive}\", NULL, false},\n\t\t{\"^[ \\t]*##[ \\t]*(.*[^ \\t])$\", \"\\\\1\",\n\t\t\"c\", \"{_extra=doubleSharps}{exclusive}\", NULL, false},\n\t};\n\n\tstatic subparser IPythonCellSubparser = {\n\t\t.direction = SUBPARSER_BASE_RUNS_SUB,\n\t};\n\tstatic parserDependency IPythonCellDependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Python\", &IPythonCellSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"IPythonCell\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->kindTable     = IPythonCellKindTable;\n\tdef->kindCount     = ARRAY_SIZE(IPythonCellKindTable);\n\tdef->xtagTable     = IPythonCellXtagTable;\n\tdef->xtagCount     = ARRAY_SIZE(IPythonCellXtagTable);\n\tdef->tagRegexTable = IPythonCellTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(IPythonCellTagRegexTable);\n\tdef->dependencies    = IPythonCellDependencies;\n\tdef->dependencyCount = ARRAY_SIZE(IPythonCellDependencies);\n\tdef->initialize    = initializeIPythonCellParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/iPythonCell.ctags",
    "content": "#\n#  iPythonCell.ctags --- a parser for python with IPythonCell comments\n#\n#  Copyright (c) 2021 Masatake YAMATO\n#  Copyright (c) 2021 Red Hat, Inc.\n#\n#  This source code is released for free distribution under the terms of the\n#  GNU General Public License version 2 or (at your option) any later version.\n#\n# References:\n#\n# - https://github.com/hanschen/vim-ipython-cell\n#\n# `##' cell format is disabled by default because it can cause too much\n# false-positive tagging. Use `--extras-IPythonCell=+{doubleSharps}'\n# to enable it.\n#\n--langdef=IPythonCell{base=Python}\n--kinddef-IPythonCell=c,cell,cells\n--_extradef-IPythonCell=doubleSharps,Include cells starting from ##\n\n--regex-IPythonCell=/^[ \\t]*(# ?%%|# <codecell>)[ \\t]*(.*[^ \\t])$/\\2/c/{exclusive}\n--regex-IPythonCell=/^[ \\t]*##[ \\t]*(.*[^ \\t])$/\\1/c/{_extra=doubleSharps}{exclusive}\n"
  },
  {
    "path": "optlib/inko.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/inko.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeInkoParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"toplevel\");\n\taddLanguageRegexTable (language, \"class\");\n\taddLanguageRegexTable (language, \"trait\");\n\taddLanguageRegexTable (language, \"method\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"impl\");\n\taddLanguageRegexTable (language, \"let\");\n\taddLanguageRegexTable (language, \"sstring\");\n\taddLanguageRegexTable (language, \"dstring\");\n\taddLanguageRegexTable (language, \"tstring\");\n\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=sstring}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dstring}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^`\",\n\t                               \"\", \"\", \"{tenter=tstring}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[[:blank:]]*class[[:blank:]]+\",\n\t                               \"\", \"\", \"{tenter=class}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[[:blank:]]*trait[[:blank:]]+\",\n\t                               \"\", \"\", \"{tenter=trait}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[[:blank:]]*def[[:blank:]]+\",\n\t                               \"\", \"\", \"{tenter=method}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[[:blank:]]*impl[[:blank:]]+\",\n\t                               \"\", \"\", \"{tenter=impl}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[[:blank:]]*let[[:blank:]]+\",\n\t                               \"\", \"\", \"{tenter=let}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{placeholder}{scope=push}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{scope=pop}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^(@[a-zA-Z0-9_]+):\",\n\t                               \"\\\\1\", \"a\", \"{scope=ref}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"class\",\n\t                               \"^([A-Z][a-zA-Z0-9_?]*)[^{]*\",\n\t                               \"\\\\1\", \"o\", \"{scope=push}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"class\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"class\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"trait\",\n\t                               \"^([A-Z][a-zA-Z0-9_?]*)[^{]*\",\n\t                               \"\\\\1\", \"t\", \"{scope=push}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"trait\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"trait\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"method\",\n\t                               \"^([a-zA-Z0-9_?]+|\\\\[\\\\]=?|\\\\^|&|\\\\||\\\\*|\\\\+|\\\\-|/|>>|<<|%)\",\n\t                               \"\\\\1\", \"m\", \"{scope=push}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"method\",\n\t                               \"^\\\\{|\\n\",\n\t                               \"\", \"\", \"{scope=pop}{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"method\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^\\n\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"impl\",\n\t                               \"^([A-Z][a-zA-Z0-9_?]*)[[:blank:]]+for[[:blank:]]+([A-Z][a-zA-Z0-9_?]*)[^{]*\",\n\t                               \"\\\\2\", \"r\", \"{scope=push}{_field=implements:\\\\1}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"impl\",\n\t                               \"^([A-Z][a-zA-Z0-9_?]*)[^{]*\",\n\t                               \"\\\\1\", \"r\", \"{scope=push}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"impl\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"impl\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"let\",\n\t                               \"^([A-Z][a-zA-Z0-9_]+)\",\n\t                               \"\\\\1\", \"c\", \"{scope=ref}{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"sstring\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"sstring\",\n\t                               \"^\\\\\\\\'\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"sstring\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dstring\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dstring\",\n\t                               \"^\\\\\\\\\\\"\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dstring\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"tstring\",\n\t                               \"^`\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"tstring\",\n\t                               \"^\\\\\\\\`\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"tstring\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* InkoParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"inko\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition InkoKindTable [] = {\n\t\t{\n\t\t  true, 'o', \"class\", \"Class definition\",\n\t\t},\n\t\t{\n\t\t  true, 'm', \"method\", \"Method definition\",\n\t\t},\n\t\t{\n\t\t  true, 't', \"trait\", \"Trait definition\",\n\t\t},\n\t\t{\n\t\t  true, 'a', \"attribute\", \"Attribute definition\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"constant\", \"Constant definition\",\n\t\t},\n\t\t{\n\t\t  true, 'r', \"reopen\", \"Reopen class\",\n\t\t},\n\t};\n\tstatic fieldDefinition InkoFieldTable [] = {\n\t\t{\n\t\t  .enabled     = true,\n\t\t  .name        = \"implements\",\n\t\t  .description = \"Trait being implemented\",\n\t\t  .dataType = FIELDTYPE_SCRIPTABLE|FIELDTYPE_STRING,\n\t\t  .isValueAvailable = isValueAvailableGeneric,\n\t\t  .getValueObject = getFieldValueGeneric,\n\t\t  .setValueObject = setFieldValueGeneric,\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"Inko\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = InkoKindTable;\n\tdef->kindCount     = ARRAY_SIZE(InkoKindTable);\n\tdef->fieldTable    = InkoFieldTable;\n\tdef->fieldCount    = ARRAY_SIZE(InkoFieldTable);\n\tdef->initialize    = initializeInkoParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/inko.ctags",
    "content": "# inko.ctags --- regex parser for the Inko programming language\n# (https://inko-lang.org/)\n#\n#  Copyright (c) 2019, Yorick Peterse\n#\n#  Author: Yorick Peterse <yorick@yorickpeterse.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n\n--langdef=Inko\n--map-Inko=+.inko\n--kinddef-Inko=o,class,Class definition\n--kinddef-Inko=m,method,Method definition\n--kinddef-Inko=t,trait,Trait definition\n--kinddef-Inko=a,attribute,Attribute definition\n--kinddef-Inko=c,constant,Constant definition\n--kinddef-Inko=r,reopen,Reopen class\n\n--_fielddef-Inko=implements,Trait being implemented{datatype=str}\n\n--fields-Inko=+{implements}\n\n--_tabledef-Inko=toplevel\n--_tabledef-Inko=class\n--_tabledef-Inko=trait\n--_tabledef-Inko=method\n--_tabledef-Inko=comment\n--_tabledef-Inko=impl\n--_tabledef-Inko=let\n--_tabledef-Inko=sstring\n--_tabledef-Inko=dstring\n--_tabledef-Inko=tstring\n\n# Handle and ignore the bodies of strings\n--_mtable-regex-Inko=toplevel/'//{tenter=sstring}\n--_mtable-regex-Inko=toplevel/\"//{tenter=dstring}\n--_mtable-regex-Inko=toplevel/`//{tenter=tstring}\n\n--_mtable-regex-Inko=sstring/'//{tleave}\n--_mtable-regex-Inko=sstring/\\\\'//\n--_mtable-regex-Inko=sstring/.//\n\n--_mtable-regex-Inko=dstring/\"//{tleave}\n--_mtable-regex-Inko=dstring/\\\\\"//\n--_mtable-regex-Inko=dstring/.//\n\n--_mtable-regex-Inko=tstring/`//{tleave}\n--_mtable-regex-Inko=tstring/\\\\`//\n--_mtable-regex-Inko=tstring/.//\n\n--_mtable-regex-Inko=toplevel/#//{tenter=comment}\n--_mtable-regex-Inko=toplevel/[[:blank:]]*class[[:blank:]]+//{tenter=class}\n--_mtable-regex-Inko=toplevel/[[:blank:]]*trait[[:blank:]]+//{tenter=trait}\n--_mtable-regex-Inko=toplevel/[[:blank:]]*def[[:blank:]]+//{tenter=method}\n--_mtable-regex-Inko=toplevel/[[:blank:]]*impl[[:blank:]]+//{tenter=impl}\n--_mtable-regex-Inko=toplevel/[[:blank:]]*let[[:blank:]]+//{tenter=let}\n--_mtable-regex-Inko=toplevel/\\{//{placeholder}{scope=push}\n--_mtable-regex-Inko=toplevel/\\}//{scope=pop}\n--_mtable-regex-Inko=toplevel/(@[a-zA-Z0-9_]+):/\\1/a/{scope=ref}\n--_mtable-regex-Inko=toplevel/.//\n\n--_mtable-regex-Inko=class/([A-Z][a-zA-Z0-9_?]*)[^{]*/\\1/o/{scope=push}\n--_mtable-regex-Inko=class/\\{//{tleave}\n--_mtable-regex-Inko=class/.//\n\n--_mtable-regex-Inko=trait/([A-Z][a-zA-Z0-9_?]*)[^{]*/\\1/t/{scope=push}\n--_mtable-regex-Inko=trait/\\{//{tleave}\n--_mtable-regex-Inko=trait/.//\n\n--_mtable-regex-Inko=method/([a-zA-Z0-9_?]+|\\[\\]=?|\\^|&|\\||\\*|\\+|\\-|\\/|>>|<<|%)/\\1/m/{scope=push}\n--_mtable-regex-Inko=method/\\{|\\n//{scope=pop}{tleave}\n--_mtable-regex-Inko=method/.//\n\n--_mtable-regex-Inko=impl/([A-Z][a-zA-Z0-9_?]*)[[:blank:]]+for[[:blank:]]+([A-Z][a-zA-Z0-9_?]*)[^{]*/\\2/r/{scope=push}{_field=implements:\\1}\n--_mtable-regex-Inko=impl/([A-Z][a-zA-Z0-9_?]*)[^{]*/\\1/r/{scope=push}\n--_mtable-regex-Inko=impl/\\{//{tleave}\n--_mtable-regex-Inko=impl/.//\n\n--_mtable-regex-Inko=let/([A-Z][a-zA-Z0-9_]+)/\\1/c/{scope=ref}{tleave}\n\n--_mtable-regex-Inko=comment/\\n//{tleave}\n--_mtable-regex-Inko=comment/.//\n"
  },
  {
    "path": "optlib/kconfig.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/kconfig.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\ntypedef enum {\n\tK_CONFIG,\n\tK_MENU,\n\tK_MAINMENU,\n\tK_KCONFIG,\n\tK_CHOICE,\n\tK_VARIABLE,\n} KconfigKind;\n\n\nstatic void initializeKconfigParser (const langType language CTAGS_ATTR_UNUSED)\n{\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_SEQUEL,\n\t\t\"{{   {\\n\"\n\t\t\"      count 0 gt {\\n\"\n\t\t\"         % ...tag:int\\n\"\n\t\t\"         . :line end:\\n\"\n\t\t\"      } {\\n\"\n\t\t\"         exit\\n\"\n\t\t\"      } ifelse\\n\"\n\t\t\"   } loop\\n\"\n\t\t\"}}\");\n}\n\nextern parserDefinition* KconfigParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\t\"Kconfig*\",\n\t\tNULL\n\t};\n\n\tstatic roleDefinition KconfigKconfigRoleTable [] = {\n\t\t{\n\t\t  true, \"source\", \"kconfig file loaded with source directive\",\n\t\t},\n\t};\n\tstatic kindDefinition KconfigKindTable [] = {\n\t\t{\n\t\t  true, 'c', \"config\", \"configs\",\n\t\t},\n\t\t{\n\t\t  true, 'm', \"menu\", \"menus\",\n\t\t},\n\t\t{\n\t\t  true, 'M', \"mainMenu\", \"the main menu\",\n\t\t},\n\t\t{\n\t\t  true, 'k', \"kconfig\", \"kconfig file\",\n\t\t  ATTACH_ROLES(KconfigKconfigRoleTable),\n\t\t},\n\t\t{\n\t\t  true, 'C', \"choice\", \"choices\",\n\t\t},\n\t\t{\n\t\t  true, 'v', \"variable\", \"macro variables\",\n\t\t  .version = 1,\n\t\t},\n\t};\n\tstatic xtagDefinition KconfigXtagTable [] = {\n\t\t{\n\t\t  .enabled     = true,\n\t\t  .name        = \"configPrefixed\",\n\t\t  .description = \"prepend CONFIG_ to config names\",\n\t\t},\n\t};\n\tstatic tagRegexTable KconfigTagRegexTable [] = {\n\t\t{\"^[ \\t]*#.*$\", \"\",\n\t\t\"\", \"{placeholder}\", NULL, false},\n\t\t{\"^[ \\t]*(menu)?config[ \\t]+([A-Za-z0-9_]+)[ \\t]*(#.*)?$\", \"\\\\2\",\n\t\t\"c\", \"{scope=ref}\"\n\t\t\"{{\\n\"\n\t\t\"   count 0 gt {\\n\"\n\t\t\"      . :line 1 gt {\\n\"\n\t\t\"        dup . :line 1 sub end:\\n\"\n\t\t\"      } if\\n\"\n\t\t\"      clear\\n\"\n\t\t\"   } if\\n\"\n\t\t\"   .\\n\"\n\t\t\"}}\", NULL, false},\n\t\t{\"^[ \\t]*(def_)?(bool|boolean|hex|int|string|tristate)\\\\>\", \"\",\n\t\t\"\", \"{exclusive}\"\n\t\t\"{{\\n\"\n\t\t\"   count 0 gt {\\n\"\n\t\t\"         dup :typeref {\\n\"\n\t\t\"            pop\\n\"\n\t\t\"            % already the field is filled. Do nothing.\\n\"\n\t\t\"         } {\\n\"\n\t\t\"            dup \\\\2 typeref:\\n\"\n\t\t\"         } ifelse\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL, false},\n\t\t{\"^[ \\t]*(menu)?config[ \\t]+([A-Za-z0-9_]+)[ \\t]*(#.*)?$\", \"CONFIG_\\\\2\",\n\t\t\"c\", \"{scope=ref}{_extra=configPrefixed}\", NULL, false},\n\t\t{\"^[ \\t]*(menu)?config[ \\t]+([A-Za-z0-9_]+)[ \\t]*(#.*)?$\", \"CONFIG_\\\\2_MODULE\",\n\t\t\"c\", \"{scope=ref}{_extra=configPrefixed}{exclusive}\", NULL, false},\n\t\t{\"^[ \\t]*menu[ \\t]+\\\"([^\\\"]+)\\\"[ \\t]*(#.*)?$\", \"\\\\1\",\n\t\t\"m\", \"{scope=push}{exclusive}\", NULL, false},\n\t\t{\"^[ \\t]*(endmenu)[ \\t]*(#.*)?$\", \"\",\n\t\t\"\", \"{scope=pop}{placeholder}{exclusive}\"\n\t\t\"{{\\n\"\n\t\t\"   {\\n\"\n\t\t\"      count 0 gt {\\n\"\n\t\t\"         _scopetop {\\n\"\n\t\t\"            % ... config:tag scope:tag\\n\"\n\t\t\"            1 index\\n\"\n\t\t\"            % ... config:tag scope:tag config:tag\\n\"\n\t\t\"            :line exch\\n\"\n\t\t\"            :line\\n\"\n\t\t\"            % ... config:tag config-line:int scope-line:int\\n\"\n\t\t\"            gt {\\n\"\n\t\t\"               % ... config:tag\\n\"\n\t\t\"               @1 _matchloc2line dup 1 gt {1 sub} if\\n\"\n\t\t\"               % ... config:tag endline:int\\n\"\n\t\t\"               end:\\n\"\n\t\t\"               % ...\\n\"\n\t\t\"            } {\\n\"\n\t\t\"               % ... config:tag\\n\"\n\t\t\"               exit\\n\"\n\t\t\"            }  ifelse\\n\"\n\t\t\"         } if\\n\"\n\t\t\"      } {\\n\"\n\t\t\"         exit\\n\"\n\t\t\"      } ifelse\\n\"\n\t\t\"   } loop\\n\"\n\t\t\"}}\", NULL, false},\n\t\t{\"^[ \\t]*source[ \\t]+\\\"?([^\\\"]+)\\\"?[ \\t]*(#.*)?$\", \"\\\\1\",\n\t\t\"k\", \"{_role=source}{exclusive}{scope=ref}\"\n\t\t\"{{\\n\"\n\t\t\"   count 0 gt {\\n\"\n\t\t\"      . :line 1 gt {\\n\"\n\t\t\"        dup . :line 1 sub end:\\n\"\n\t\t\"      } if\\n\"\n\t\t\"      clear\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL, false},\n\t\t{\"^[ \\t]*choice[ \\t]+([A-Za-z0-9_]+)[ \\t]*(#.*)?$\", \"\\\\1\",\n\t\t\"C\", \"{scope=push}{exclusive}\"\n\t\t\"{{\\n\"\n\t\t\"   count 0 gt {\\n\"\n\t\t\"      . :line 1 gt {\\n\"\n\t\t\"        dup . :line 1 sub end:\\n\"\n\t\t\"      } if\\n\"\n\t\t\"      clear\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL, false},\n\t\t{\"^[ \\t]*choice[ \\t]*(#.*)?$\", \"\",\n\t\t\"C\", \"{_anonymous=choice}{scope=push}{exclusive}\"\n\t\t\"{{\\n\"\n\t\t\"   count 0 gt {\\n\"\n\t\t\"      . :line 1 gt {\\n\"\n\t\t\"        dup . :line 1 sub end:\\n\"\n\t\t\"      } if\\n\"\n\t\t\"      clear\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL, false},\n\t\t{\"^[ \\t]*prompt[ \\t]+\\\"([^\\\"]+)\\\"[ \\t]*(#.*|if)?\", \"\",\n\t\t\"\", \"{exclusive}\"\n\t\t\"{{\\n\"\n\t\t\"   _scopetop {\\n\"\n\t\t\"      dup :kind /choice eq {\\n\"\n\t\t\"         dup :extras {\\n\"\n\t\t\"            /anonymous _amember {\\n\"\n\t\t\"               % This is an anonymous tag that kind is choice.\\n\"\n\t\t\"               % Throw it away.\\n\"\n\t\t\"               _markplaceholder\\n\"\n\t\t\"               _scopepop\\n\"\n\t\t\"               % Make a new one with the prompt.\\n\"\n\t\t\"               \\\\1 /choice @1 _tag _commit _scopepush\\n\"\n\t\t\"            } {\\n\"\n\t\t\"               % This is not an anonymous tag.\\n\"\n\t\t\"               pop\\n\"\n\t\t\"            } ifelse\\n\"\n\t\t\"         } {\\n\"\n\t\t\"            % This is not an extra tag.\\n\"\n\t\t\"            pop\\n\"\n\t\t\"         } ifelse\\n\"\n\t\t\"       } {\\n\"\n\t\t\"          % This is not a choice.\\n\"\n\t\t\"          pop\\n\"\n\t\t\"       } ifelse\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL, false},\n\t\t{\"^[ \\t]*(endchoice)[ \\t]*(#.*)?$\", \"\",\n\t\t\"\", \"{scope=pop}{placeholder}{exclusive}\"\n\t\t\"{{\\n\"\n\t\t\"   {\\n\"\n\t\t\"      count 0 gt {\\n\"\n\t\t\"         _scopetop {\\n\"\n\t\t\"            % ... config:tag scope:tag\\n\"\n\t\t\"            1 index\\n\"\n\t\t\"            % ... config:tag scope:tag config:tag\\n\"\n\t\t\"            :line exch\\n\"\n\t\t\"            :line\\n\"\n\t\t\"            % ... config:tag config-line:int scope-line:int\\n\"\n\t\t\"            gt {\\n\"\n\t\t\"               % ... config:tag\\n\"\n\t\t\"               @1 _matchloc2line dup 1 gt {1 sub} if\\n\"\n\t\t\"               % ... config:tag endline:int\\n\"\n\t\t\"               end:\\n\"\n\t\t\"               % ...\\n\"\n\t\t\"            } {\\n\"\n\t\t\"               % ... config:tag\\n\"\n\t\t\"               exit\\n\"\n\t\t\"            }  ifelse\\n\"\n\t\t\"         } if\\n\"\n\t\t\"      } {\\n\"\n\t\t\"         exit\\n\"\n\t\t\"      } ifelse\\n\"\n\t\t\"   } loop\\n\"\n\t\t\"}}\", NULL, false},\n\t\t{\"^[ \\t]*mainmenu[ \\t]+\\\"([^\\\"]+)\\\"[ \\t]*(#.*)?$\", \"\\\\1\",\n\t\t\"M\", \"{exclusive}\", NULL, false},\n\t\t{\"^([-a-zA-Z0-9_$]+)[ \\t]*:?=\", \"\\\\1\",\n\t\t\"v\", \"{exclusive}\", NULL, false},\n\t};\n\n\n\tparserDefinition* const def = parserNew (\"Kconfig\");\n\n\tdef->versionCurrent= 1;\n\tdef->versionAge    = 1;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = KconfigKindTable;\n\tdef->kindCount     = ARRAY_SIZE(KconfigKindTable);\n\tdef->xtagTable     = KconfigXtagTable;\n\tdef->xtagCount     = ARRAY_SIZE(KconfigXtagTable);\n\tdef->tagRegexTable = KconfigTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(KconfigTagRegexTable);\n\tdef->defaultScopeSeparator = \"\\\"\\\"\";\n\tdef->initialize    = initializeKconfigParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/kconfig.ctags",
    "content": "#\n#  Copyright (c) 2020, Maxime Chretien <maxime.chretien@bootlin.com>\n#\n#  This source code is released for free distribution under the terms of the\n#  GNU General Public License version 2 or (at your option) any later version.\n#\n#  This module contains functions for generating tags for the Kconfig language\n#\n#  Reference\n#     https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html\n#     https://www.kernel.org/doc/html/latest/kbuild/kconfig-macro-language.html\n#\n#\n#  This parser was originally written in C as proplosed in #2553 by Maxime.\n#  Masatake converted it to an optlib file.\n#\n\n--langdef=Kconfig{version=1.1}\n--map-Kconfig=+(Kconfig*)\n\n--kinddef-Kconfig=c,config,configs\n--kinddef-Kconfig=m,menu,menus\n--kinddef-Kconfig=M,mainMenu,the main menu\n--kinddef-Kconfig=k,kconfig,kconfig file\n--kinddef-Kconfig=C,choice,choices\n--kinddef-Kconfig=v,variable,macro variables{version=1}\n\n--_roledef-Kconfig.{kconfig}=source,kconfig file loaded with source directive\n\n# Menus can be nested. Combine the parent menu and its child with \"\".\n--_scopesep-Kconfig=*/*:\"\"\n\n#\n# The next extra is useful for jumpping from\n#\n#    #ifdef CONFIG_FOO\n#    ...\n#\n# in C code.\n#\n# Masatake proposed this extra to linux-kbuild ML and it was\n# merged as\n# ----------------------------------------------------------------------\n# commit e838db685fcfd2e9a0548ffc5cb9447e6c3c11be\n# Author: Masatake YAMATO <jet@gyve.org>\n# Date:   Thu Jun 22 12:21:20 2006 +0900\n#\n#    kbuild: adding symbols in Kconfig and defconfig to TAGS\n#\n--_extradef-Kconfig=configPrefixed,prepend CONFIG_ to config names\n--extras-Kconfig=+{configPrefixed}\n\n# Fill end: field of the tags remaining on the stack.\n--_sequel-Kconfg={{\n   {\n      count 0 gt {\n         % ...tag:int\n         . :line end:\n      } {\n         exit\n      } ifelse\n   } loop\n}}\n\n# skip the comment lines.\n--regex-Kconfig=/^[ \\t]*#.*$//{placeholder}\n\n--regex-Kconfig=/^[ \\t]*(menu)?config[ \\t]+([A-Za-z0-9_]+)[ \\t]*(#.*)?$/\\2/c/{scope=ref}{{\n   count 0 gt {\n      . :line 1 gt {\n        dup . :line 1 sub end:\n      } if\n      clear\n   } if\n   .\n}}\n--regex-Kconfig=/^[ \\t]*(def_)?(bool|boolean|hex|int|string|tristate)\\>///{exclusive}{{\n   count 0 gt {\n         dup :typeref {\n            pop\n            % already the field is filled. Do nothing.\n         } {\n            dup \\2 typeref:\n         } ifelse\n   } if\n}}\n--regex-Kconfig=/^[ \\t]*(menu)?config[ \\t]+([A-Za-z0-9_]+)[ \\t]*(#.*)?$/CONFIG_\\2/c/{scope=ref}{_extra=configPrefixed}\n--regex-Kconfig=/^[ \\t]*(menu)?config[ \\t]+([A-Za-z0-9_]+)[ \\t]*(#.*)?$/CONFIG_\\2_MODULE/c/{scope=ref}{_extra=configPrefixed}{exclusive}\n\n--regex-Kconfig=/^[ \\t]*menu[ \\t]+\"([^\"]+)\"[ \\t]*(#.*)?$/\\1/m/{scope=push}{exclusive}\n--regex-Kconfig=/^[ \\t]*(endmenu)[ \\t]*(#.*)?$//{scope=pop}{placeholder}{exclusive}{{\n   {\n      count 0 gt {\n         _scopetop {\n            % ... config:tag scope:tag\n            1 index\n            % ... config:tag scope:tag config:tag\n            :line exch\n            :line\n            % ... config:tag config-line:int scope-line:int\n            gt {\n               % ... config:tag\n               @1 _matchloc2line dup 1 gt {1 sub} if\n               % ... config:tag endline:int\n               end:\n               % ...\n            } {\n               % ... config:tag\n               exit\n            }  ifelse\n         } if\n      } {\n         exit\n      } ifelse\n   } loop\n}}\n\n# Qemu's Kconfig does't use double quotes\n--regex-Kconfig=/^[ \\t]*source[ \\t]+\"?([^\"]+)\"?[ \\t]*(#.*)?$/\\1/k/{_role=source}{exclusive}{scope=ref}{{\n   count 0 gt {\n      . :line 1 gt {\n        dup . :line 1 sub end:\n      } if\n      clear\n   } if\n}}\n\n--regex-Kconfig=/^[ \\t]*choice[ \\t]+([A-Za-z0-9_]+)[ \\t]*(#.*)?$/\\1/C/{scope=push}{exclusive}{{\n   count 0 gt {\n      . :line 1 gt {\n        dup . :line 1 sub end:\n      } if\n      clear\n   } if\n}}\n--regex-Kconfig=/^[ \\t]*choice[ \\t]*(#.*)?$//C/{_anonymous=choice}{scope=push}{exclusive}{{\n   count 0 gt {\n      . :line 1 gt {\n        dup . :line 1 sub end:\n      } if\n      clear\n   } if\n}}\n--regex-Kconfig=/^[ \\t]*prompt[ \\t]+\"([^\"]+)\"[ \\t]*(#.*|if)?//{exclusive}{{\n   _scopetop {\n      dup :kind /choice eq {\n         dup :extras {\n            /anonymous _amember {\n               % This is an anonymous tag that kind is choice.\n               % Throw it away.\n               _markplaceholder\n               _scopepop\n               % Make a new one with the prompt.\n               \\1 /choice @1 _tag _commit _scopepush\n            } {\n               % This is not an anonymous tag.\n               pop\n            } ifelse\n         } {\n            % This is not an extra tag.\n            pop\n         } ifelse\n       } {\n          % This is not a choice.\n          pop\n       } ifelse\n   } if\n}}\n--regex-Kconfig=/^[ \\t]*(endchoice)[ \\t]*(#.*)?$//{scope=pop}{placeholder}{exclusive}{{\n   {\n      count 0 gt {\n         _scopetop {\n            % ... config:tag scope:tag\n            1 index\n            % ... config:tag scope:tag config:tag\n            :line exch\n            :line\n            % ... config:tag config-line:int scope-line:int\n            gt {\n               % ... config:tag\n               @1 _matchloc2line dup 1 gt {1 sub} if\n               % ... config:tag endline:int\n               end:\n               % ...\n            } {\n               % ... config:tag\n               exit\n            }  ifelse\n         } if\n      } {\n         exit\n      } ifelse\n   } loop\n}}\n\n--regex-Kconfig=/^[ \\t]*mainmenu[ \\t]+\"([^\"]+)\"[ \\t]*(#.*)?$/\\1/M/{exclusive}\n\n--regex-Kconfig=/^([-a-zA-Z0-9_$]+)[ \\t]*:?=/\\1/v/{exclusive}\n"
  },
  {
    "path": "optlib/lex.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/lex.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n#include \"selectors.h\"\n\n\nstatic void initializeLEXParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"codeblock\");\n\taddLanguageRegexTable (language, \"rulesec\");\n\taddLanguageRegexTable (language, \"usercode\");\n\taddLanguageRegexTable (language, \"cond\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^%[sx][ \\t]+\",\n\t                               \"\", \"\", \"{tenter=cond}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^%(top)?\\\\{\",\n\t                               \"\", \"\", \"{tenter=codeblock}{_guest=C,0end,}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^%%\",\n\t                               \"\", \"\", \"{tjump=rulesec}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^([a-zA-Z_][-a-zA-Z0-9_]*)[^\\n]+\\n\",\n\t                               \"\\\\1\", \"r\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^\\n]*\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^[^*]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^\\\\*/\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"codeblock\",\n\t                               \"^[^%]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"codeblock\",\n\t                               \"^%\\\\}\",\n\t                               \"\", \"\", \"{tleave}{_guest=,,0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"codeblock\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rulesec\",\n\t                               \"^[^%<]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rulesec\",\n\t                               \"^%%\",\n\t                               \"\", \"\", \"{tjump=usercode}{_guest=C,0end,}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rulesec\",\n\t                               \"^<([_a-zA-Z][_a-zA-Z0-9]*)>[ \\t]*\\\\{[ \\t]*\\n\",\n\t                               \"\\\\1\", \"c\", \"{_role=grouping}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rulesec\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"usercode\",\n\t                               \"^.+\",\n\t                               \"\", \"\", \"{_guest=,,0end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cond\",\n\t                               \"^([_a-zA-Z][_a-zA-Z0-9]*)[ \\t]*\",\n\t                               \"\\\\1\", \"c\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cond\",\n\t                               \"^\\n\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cond\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* LEXParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"lex\",\n\t\t\"l\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic roleDefinition LEXCondRoleTable [] = {\n\t\t{\n\t\t  true, \"grouping\", \" conditions used for grouping of start or exclusive condition rules\",\n\t\t  .version = 1,\n\t\t},\n\t};\n\tstatic kindDefinition LEXKindTable [] = {\n\t\t{\n\t\t  true, 'r', \"regex\", \"named regular expression\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"cond\", \"definition of start or exclusive condition\",\n\t\t  ATTACH_ROLES(LEXCondRoleTable),\n\t\t},\n\t};\n\tstatic selectLanguage selectors[] = { selectLispOrLEXByLEXMarker, NULL };\n\n\tparserDefinition* const def = parserNew (\"LEX\");\n\n\tdef->versionCurrent= 1;\n\tdef->versionAge    = 1;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->selectLanguage= selectors;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->kindTable     = LEXKindTable;\n\tdef->kindCount     = ARRAY_SIZE(LEXKindTable);\n\tdef->initialize    = initializeLEXParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/lex.ctags",
    "content": "#\n# lex.ctags --- multitable regex parser for lex/flex input\n#\n# Copyright (c) 2021, Red Hat, Inc.\n# Copyright (c) 2021, Masatake YAMATO\n#\n# Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n# Reference:\n#\n# - https://github.com/westes/flex/blob/master/doc/flex.texi\n#\n\n--langdef=LEX{version=1.1}\n\n#\n# Map definitions\n#\n--map-LEX=+.lex\n\n# Lisp parser also expects \".l\" file extension.\n--map-LEX=+.l\n--__selector-LEX=selectLispOrLEXByLEXMarker\n\n\n#\n# Kind definitions\n#\n\n--kinddef-LEX=r,regex,named regular expression\n--kinddef-LEX=c,cond,definition of start or exclusive condition\n--_roledef-LEX.{cond}=grouping, conditions used for grouping of start or exclusive condition rules{version=1}\n\n#\n# Table declarations\n#\n\n--_tabledef-LEX=main\n--_tabledef-LEX=comment\n--_tabledef-LEX=codeblock\n--_tabledef-LEX=rulesec\n--_tabledef-LEX=usercode\n--_tabledef-LEX=cond\n\n#\n# Table definitions\n#\n--_mtable-regex-LEX=comment/[^*]+//\n--_mtable-regex-LEX=comment/\\*\\///{tleave}\n--_mtable-regex-LEX=comment/.//\n\n--_mtable-regex-LEX=codeblock/[^%]+//\n--_mtable-regex-LEX=codeblock/%\\}//{tleave}{_guest=,,0start}\n--_mtable-regex-LEX=codeblock/.//\n\n--_mtable-regex-LEX=rulesec/[^%<]+//\n--_mtable-regex-LEX=rulesec/%%//{tjump=usercode}{_guest=C,0end,}\n--_mtable-regex-LEX=rulesec/<([_a-zA-Z][_a-zA-Z0-9]*)>[ \\t]*\\{[ \\t]*\\n/\\1/c/{_role=grouping}\n--_mtable-regex-LEX=rulesec/.//\n\n--_mtable-regex-LEX=usercode/.+//{_guest=,,0end}\n\n--_mtable-regex-LEX=cond/([_a-zA-Z][_a-zA-Z0-9]*)[ \\t]*/\\1/c/\n--_mtable-regex-LEX=cond/\\n//{tleave}\n--_mtable-regex-LEX=cond/.//\n\n--_mtable-regex-LEX=main/\\/\\*//{tenter=comment}\n--_mtable-regex-LEX=main/%[sx][ \\t]+//{tenter=cond}\n--_mtable-regex-LEX=main/%(top)?\\{//{tenter=codeblock}{_guest=C,0end,}\n--_mtable-regex-LEX=main/%%//{tjump=rulesec}\n--_mtable-regex-LEX=main/([a-zA-Z_][-a-zA-Z0-9_]*)[^\\n]+\\n/\\1/r/\n--_mtable-regex-LEX=main/[^\\n]*\\n//\n"
  },
  {
    "path": "optlib/man.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/man.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\ntypedef enum {\n\tK_TITLE,\n\tK_SECTION,\n\tK_SUBSECTION,\n} ManKind;\n\n\nstatic void initializeManParser (const langType language)\n{\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE,\n\t\t\"{{    % adjustment:int FILL-END-OF-SCOPE -\\n\"\n\t\t\"    %\\n\"\n\t\t\"    % Note: The group 1 of a regex matching is assumed.\\n\"\n\t\t\"    %       An entry on the scope stack is assumed.\\n\"\n\t\t\"    /fill-end-of-scope {\\n\"\n\t\t\"         _scopetop pop exch\\n\"\n\t\t\"         % scope-top:int adjustment:int\\n\"\n\t\t\"         @1 _matchloc2line exch\\n\"\n\t\t\"         % scope-top:int line adjustment:int\\n\"\n\t\t\"         2 copy gt {\\n\"\n\t\t\"             sub end:\\n\"\n\t\t\"         } {\\n\"\n\t\t\"             pop pop pop\\n\"\n\t\t\"         } ifelse\\n\"\n\t\t\"    } def\\n\"\n\t\t\"    % adjustment:int /replace HEADING-ACTION -\\n\"\n\t\t\"    % /push HEADING-ACTION -\\n\"\n\t\t\"    /heading-action {\\n\"\n\t\t\"        /replace eq {\\n\"\n\t\t\"             %\\n\"\n\t\t\"             % Before removing the tag at the top of the scope stack,\\n\"\n\t\t\"             % fill the end field of the tag.\\n\"\n\t\t\"             %\\n\"\n\t\t\"             % input0.man\\n\"\n\t\t\"             % ----------------------------------------------------\\n\"\n\t\t\"             %   .SH SEC1\\n\"\n\t\t\"             %   ...\\n\"\n\t\t\"             %E: This is the end of the SEC1.\\n\"\n\t\t\"             %   .SH\\n\"\n\t\t\"             %C: SEC2\\n\"\n\t\t\"             %\\n\"\n\t\t\"             % ----------------------------------------------------\\n\"\n\t\t\"             %\\n\"\n\t\t\"             % C represents the current input line. The parser must\\n\"\n\t\t\"             % fill the end field of \\\"SEC1\\\", the tag at the top,\\n\"\n\t\t\"             % with the line number of E.\\n\"\n\t\t\"             %\\n\"\n\t\t\"             %    E = C - 2\\n\"\n\t\t\"             %\\n\"\n\t\t\"             % input1.man\\n\"\n\t\t\"             % ----------------------------------------------------\\n\"\n\t\t\"             %   .SH SEC3\\n\"\n\t\t\"             %   ...\\n\"\n\t\t\"             %E: This is the end of the SEC1.\\n\"\n\t\t\"             %C:  .SH SEC4\\n\"\n\t\t\"             %\\n\"\n\t\t\"             % ----------------------------------------------------\\n\"\n\t\t\"             %\\n\"\n\t\t\"             % In this case\\n\"\n\t\t\"             %\\n\"\n\t\t\"             %    E = C - 1\\n\"\n\t\t\"             %\\n\"\n\t\t\"             % The offset for the adjustment depends on the conctxt.\\n\"\n\t\t\"             %\\n\"\n\t\t\"             fill-end-of-scope\\n\"\n\t\t\"             _scopepop\\n\"\n\t\t\"        } if\\n\"\n\t\t\"\\n\"\n\t\t\"        _scopetop {\\n\"\n\t\t\"            . exch scope:\\n\"\n\t\t\"        } if\\n\"\n\t\t\"        . _scopepush\\n\"\n\t\t\"    } def\\n\"\n\t\t\"}}\");\n\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"section\");\n\taddLanguageRegexTable (language, \"sectionheading\");\n\taddLanguageRegexTable (language, \"subsection\");\n\taddLanguageRegexTable (language, \"subsectionheading\");\n\taddLanguageRegexTable (language, \"EOF\");\n\taddLanguageRegexTable (language, \"SKIP\");\n\taddLanguageRegexTable (language, \"REST\");\n\taddLanguageRegexTable (language, \"GUARD\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^([^\\n.]|\\\\.[^\\nst])[^\\n]*\\n\",\n\t                               \"\", \"\", \"{icase}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\.TH[\\t ]+\\\"([^\\\"]+)\\\"[^\\n]*\\n\",\n\t                               \"\\\\1\", \"t\", \"{icase}{scope=set}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\.TH[\\t ]+([^\\t \\n]+)[^\\n]*\\n\",\n\t                               \"\\\\1\", \"t\", \"{icase}{scope=set}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\.SH[\\t ]+\\\"([^\\\"\\n]+)\\\"[^\\n]*\\n\",\n\t                               \"\\\\1\", \"s\", \"{icase}{scope=push}{tenter=section}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\.SH[\\t ]+([^\\n]+)\\n\",\n\t                               \"\\\\1\", \"s\", \"{icase}{scope=push}{tenter=section}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\.SH[\\t ]*\\n\",\n\t                               \"\", \"\", \"{icase}{tenter=sectionheading}\"\n\t\t\"{{\\n\"\n\t\t\"    /push\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^\\n]*\\n|[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{scope=clear}{tquit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^([^\\n.]|\\\\.[^\\nst])[^\\n]*\\n\",\n\t                               \"\", \"\", \"{icase}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^\\\\.SH[\\t ]+\\\"([^\\\"\\n]+)\\\"[^\\n]*\\n\",\n\t                               \"\\\\1\", \"s\", \"{icase}{scope=replace}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^\\\\.SH[\\t ]+([^\\n]+)\\n\",\n\t                               \"\\\\1\", \"s\", \"{icase}{scope=replace}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^(\\\\.SH)[\\t ]*\\n\",\n\t                               \"\", \"\", \"{icase}{tjump=sectionheading}\"\n\t\t\"{{\\n\"\n\t\t\"    2 /replace\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^\\\\.SS[\\t ]+\\\"([^\\\"\\n]+)\\\"[^\\n]*\\n\",\n\t                               \"\\\\1\", \"S\", \"{icase}{scope=push}{tenter=subsection}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^\\\\.SS[\\t ]+([^\\n]+)\\n\",\n\t                               \"\\\\1\", \"S\", \"{icase}{scope=push}{tenter=subsection}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^\\\\.SS[\\t ]*\\n\",\n\t                               \"\", \"\", \"{icase}{tenter=subsectionheading}\"\n\t\t\"{{\\n\"\n\t\t\"    /push\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^[^\\n]*\\n|[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{scope=clear}{tquit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"sectionheading\",\n\t                               \"^[ \\t]*([^\\n]+)\\n\",\n\t                               \"\\\\1\", \"s\", \"{tjump=section}\"\n\t\t\"{{\\n\"\n\t\t\"    heading-action\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"sectionheading\",\n\t                               \"^[^\\n]*\\n|[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"sectionheading\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{scope=clear}{tquit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"subsection\",\n\t                               \"^([^\\n.]|\\\\.[^\\nst])[^\\n]*\\n\",\n\t                               \"\", \"\", \"{icase}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"subsection\",\n\t                               \"^\\\\.SS[\\t ]+\\\"([^\\\"\\n]+)\\\"[^\\n]*\\n\",\n\t                               \"\\\\1\", \"S\", \"{icase}{scope=replace}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"subsection\",\n\t                               \"^\\\\.SS[\\t ]+([^\\n]+)\\n\",\n\t                               \"\\\\1\", \"S\", \"{icase}{scope=replace}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"subsection\",\n\t                               \"^\\\\.SS[\\t ]*\\n\",\n\t                               \"\", \"\", \"{icase}{tjump=subsectionheading}\"\n\t\t\"{{\\n\"\n\t\t\"    2 /replace\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"subsection\",\n\t                               \"^(\\\\.SH)\",\n\t                               \"\", \"\", \"{icase}{_advanceTo=0start}{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"    1 fill-end-of-scope\\n\"\n\t\t\"    _scopepop\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"subsection\",\n\t                               \"^[^\\n]*\\n|[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"subsection\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{scope=clear}{tquit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"subsectionheading\",\n\t                               \"^[ \\t]*([^\\n]+)\\n\",\n\t                               \"\\\\1\", \"S\", \"{tjump=subsection}\"\n\t\t\"{{\\n\"\n\t\t\"    heading-action\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"subsectionheading\",\n\t                               \"^[^\\n]*\\n|[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"subsectionheading\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{scope=clear}{tquit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"EOF\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{scope=clear}{tquit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"SKIP\",\n\t                               \"^[^\\n]*\\n|[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"REST\",\n\t                               \"^[^\\n]*\\n|[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"REST\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{scope=clear}{tquit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"GUARD\",\n\t                               \"^([^\\n.]|\\\\.[^\\nst])[^\\n]*\\n\",\n\t                               \"\", \"\", \"{icase}\", NULL);\n}\n\nextern parserDefinition* ManParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"man\",\n\t\t\"1\",\n\t\t\"2\",\n\t\t\"3\",\n\t\t\"4\",\n\t\t\"5\",\n\t\t\"6\",\n\t\t\"7\",\n\t\t\"8\",\n\t\t\"9\",\n\t\t\"3pm\",\n\t\t\"3stap\",\n\t\t\"7stap\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition ManKindTable [] = {\n\t\t{\n\t\t  true, 't', \"title\", \"titles\",\n\t\t},\n\t\t{\n\t\t  true, 's', \"section\", \"sections\",\n\t\t},\n\t\t{\n\t\t  true, 'S', \"subsection\", \"sub sections\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"Man\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = ManKindTable;\n\tdef->kindCount     = ARRAY_SIZE(ManKindTable);\n\tdef->defaultScopeSeparator = \"\\\"\\\"\";\n\tdef->initialize    = initializeManParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/man.ctags",
    "content": "#\n#\n#  Copyright (c) 2016, Red Hat, Inc.\n#  Copyright (c) 2016, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n#\n--langdef=Man\n--map-Man=+.man\n--map-Man=+.1\n--map-Man=+.2\n--map-Man=+.3\n--map-Man=+.4\n--map-Man=+.5\n--map-Man=+.6\n--map-Man=+.7\n--map-Man=+.8\n--map-Man=+.9\n\n# For perl modules\n--map-Man=+.3pm\n\n# For systemtap\n--map-Man=+.3stap\n--map-Man=+.7stap\n\n--kinddef-Man=t,title,titles\n--kinddef-Man=s,section,sections\n--kinddef-Man=S,subsection,sub sections\n\n--_scopesep-Man=*/*:\"\"\n\n--_tabledef-Man=main\n--_tabledef-Man=section\n--_tabledef-Man=sectionheading\n--_tabledef-Man=subsection\n--_tabledef-Man=subsectionheading\n\n--_prelude-Man={{\n    % adjustment:int FILL-END-OF-SCOPE -\n    %\n    % Note: The group 1 of a regex matching is assumed.\n    %       An entry on the scope stack is assumed.\n    /fill-end-of-scope {\n         _scopetop pop exch\n         % scope-top:int adjustment:int\n         @1 _matchloc2line exch\n         % scope-top:int line adjustment:int\n         2 copy gt {\n             sub end:\n         } {\n             pop pop pop\n         } ifelse\n    } def\n    % adjustment:int /replace HEADING-ACTION -\n    % /push HEADING-ACTION -\n    /heading-action {\n        /replace eq {\n             %\n             % Before removing the tag at the top of the scope stack,\n             % fill the end field of the tag.\n             %\n             % input0.man\n             % ----------------------------------------------------\n             %   .SH SEC1\n             %   ...\n             %E: This is the end of the SEC1.\n             %   .SH\n             %C: SEC2\n             %\n             % ----------------------------------------------------\n             %\n             % C represents the current input line. The parser must\n             % fill the end field of \"SEC1\", the tag at the top,\n             % with the line number of E.\n             %\n             %    E = C - 2\n             %\n             % input1.man\n             % ----------------------------------------------------\n             %   .SH SEC3\n             %   ...\n             %E: This is the end of the SEC1.\n             %C:  .SH SEC4\n             %\n             % ----------------------------------------------------\n             %\n             % In this case\n             %\n             %    E = C - 1\n             %\n             % The offset for the adjustment depends on the conctxt.\n             %\n             fill-end-of-scope\n             _scopepop\n        } if\n\n        _scopetop {\n            . exch scope:\n        } if\n        . _scopepush\n    } def\n}}\n\n--_tabledef-Man=EOF\n--_tabledef-Man=SKIP\n--_tabledef-Man=REST\n--_tabledef-Man=GUARD\n\n#\n# helper tables\n#\n--_mtable-regex-Man=GUARD/([^\\n.]|\\.[^\\nst])[^\\n]*\\n//{icase}\n--_mtable-regex-Man=SKIP/[^\\n]*\\n|[^\\n]+//\n--_mtable-regex-Man=EOF///{scope=clear}{tquit}\n--_mtable-extend-Man=REST+SKIP\n--_mtable-extend-Man=REST+EOF\n\n#\n# main table\n#\n--_mtable-extend-Man=main+GUARD\n--_mtable-regex-Man=main/\\.TH[\\t ]+\"([^\"]+)\"[^\\n]*\\n/\\1/t/{icase}{scope=set}\n--_mtable-regex-Man=main/\\.TH[\\t ]+([^\\t \\n]+)[^\\n]*\\n/\\1/t/{icase}{scope=set}\n--_mtable-regex-Man=main/\\.SH[\\t ]+\"([^\"\\n]+)\"[^\\n]*\\n/\\1/s/{icase}{scope=push}{tenter=section}\n--_mtable-regex-Man=main/\\.SH[\\t ]+([^\\n]+)\\n/\\1/s/{icase}{scope=push}{tenter=section}\n--_mtable-regex-Man=main/\\.SH[\\t ]*\\n//{icase}{tenter=sectionheading}{{\n    /push\n}}\n--_mtable-extend-Man=main+REST\n\n#\n# section table\n#\n--_mtable-extend-Man=section+GUARD\n--_mtable-regex-Man=section/\\.SH[\\t ]+\"([^\"\\n]+)\"[^\\n]*\\n/\\1/s/{icase}{scope=replace}\n--_mtable-regex-Man=section/\\.SH[\\t ]+([^\\n]+)\\n/\\1/s/{icase}{scope=replace}\n--_mtable-regex-Man=section/(\\.SH)[\\t ]*\\n//{icase}{tjump=sectionheading}{{\n    2 /replace\n}}\n--_mtable-regex-Man=section/\\.SS[\\t ]+\"([^\"\\n]+)\"[^\\n]*\\n/\\1/S/{icase}{scope=push}{tenter=subsection}\n--_mtable-regex-Man=section/\\.SS[\\t ]+([^\\n]+)\\n/\\1/S/{icase}{scope=push}{tenter=subsection}\n--_mtable-regex-Man=section/\\.SS[\\t ]*\\n//{icase}{tenter=subsectionheading}{{\n    /push\n}}\n--_mtable-extend-Man=section+REST\n\n#\n# sectionheading\n#\n--_mtable-regex-Man=sectionheading/[ \\t]*([^\\n]+)\\n/\\1/s/{tjump=section}{{\n    heading-action\n}}\n--_mtable-extend-Man=sectionheading+REST\n\n#\n# subsection\n#\n--_mtable-extend-Man=subsection+GUARD\n--_mtable-regex-Man=subsection/\\.SS[\\t ]+\"([^\"\\n]+)\"[^\\n]*\\n/\\1/S/{icase}{scope=replace}\n--_mtable-regex-Man=subsection/\\.SS[\\t ]+([^\\n]+)\\n/\\1/S/{icase}{scope=replace}\n--_mtable-regex-Man=subsection/\\.SS[\\t ]*\\n//{icase}{tjump=subsectionheading}{{\n    2 /replace\n}}\n--_mtable-regex-Man=subsection/(\\.SH)///{icase}{_advanceTo=0start}{tleave}{{\n    1 fill-end-of-scope\n    _scopepop\n}}\n--_mtable-extend-Man=subsection+REST\n\n#\n# subsectionheading\n#\n--_mtable-regex-Man=subsectionheading/[ \\t]*([^\\n]+)\\n/\\1/S/{tjump=subsection}{{\n    heading-action\n}}\n--_mtable-extend-Man=subsectionheading+REST\n"
  },
  {
    "path": "optlib/meson.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/meson.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeMesonParser (const langType language)\n{\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE,\n\t\t\"{{    /lastvar false def\\n\"\n\t\t\"    /cfgdict 5 dict def\\n\"\n\t\t\"}}\");\n\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"mline_string\");\n\taddLanguageRegexTable (language, \"string\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"skipPair\");\n\taddLanguageRegexTable (language, \"common\");\n\taddLanguageRegexTable (language, \"skipToArgEnd\");\n\taddLanguageRegexTable (language, \"configBody\");\n\taddLanguageRegexTable (language, \"configElt\");\n\taddLanguageRegexTable (language, \"configValue\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^([a-zA-Z_][a-zA-Z_0-9]*)[ \\t\\n]*=([^=]|$)\",\n\t                               \"\\\\1\", \"V\", \"{_advanceTo=2start}\"\n\t\t\"{{\\n\"\n\t\t\"   /lastvar . def\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^project[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"P\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^subdir[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"S\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^test[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"t\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^'''\",\n\t                               \"\", \"\", \"{tenter=mline_string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[[({]\",\n\t                               \"\", \"\", \"{tenter=skipPair}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^([a-zA-Z_][a-zA-Z0-9_]*)\\\\.(set(_quoted|10)?)[ \\t\\n]*\\\\('([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"   cfgdict \\\\1 known {\\n\"\n\t\t\"      \\\\4 /cfgvar @4 _tag _commit\\n\"\n\t\t\"      cfgdict \\\\1 get scope:\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[df-hkm-qt-z][a-zA-Z0-9_]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^(jar|executable|shared_module|(both_|shared_|static_)?library)[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\3\", \"B\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^custom_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"c\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^(alias|run)_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\2\", \"r\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^benchmark[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"b\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^import[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"m\", \"{tenter=skipToArgEnd}{_role=imported}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^(configuration_data)[ \\t\\n]*\\\\([ \\t\\n]*\",\n\t                               \"\", \"\", \"{tenter=configBody}\"\n\t\t\"{{\\n\"\n\t\t\"   lastvar false ne {\\n\"\n\t\t\"      lastvar :name\\n\"\n\t\t\"      /cfgdata\\n\"\n\t\t\"      lastvar _tagloc\\n\"\n\t\t\"      _tag _commit\\n\"\n\t\t\"\\n\"\n\t\t\"      % Keep the newly created /cfgdata tag on the stack\\n\"\n\t\t\"      % till leaving /configBody table.\\n\"\n\t\t\"      dup\\n\"\n\t\t\"\\n\"\n\t\t\"      cfgdict lastvar :name 3 -1 roll put\\n\"\n\t\t\"\\n\"\n\t\t\"      % Don't emit the tag for the original variable.\\n\"\n\t\t\"      lastvar _markplaceholder\\n\"\n\t\t\"      /lastvar false def\\n\"\n\t\t\"   } {\\n\"\n\t\t\"      % Looks broken input. There is no left side for the configuration_data(...).\\n\"\n\t\t\"      % Push a dummy tag.\\n\"\n\t\t\"      (cfg) /cfgdata _anongen /cfgdata @1 _tag _commit\\n\"\n\t\t\"      dup /anonymous _markextra\\n\"\n\t\t\"   } ifelse\\n\"\n\t\t\"   % The configElt table refers to the cork index pushed by this table\\n\"\n\t\t\"   % for filling the scope of cfgvar/C tags.\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mline_string\",\n\t                               \"^'''\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mline_string\",\n\t                               \"^[^']+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mline_string\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"string\",\n\t                               \"^[^\\\\\\\\']+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"string\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"string\",\n\t                               \"^\\\\\\\\.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"string\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^\\n\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^[])}]\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^'''\",\n\t                               \"\", \"\", \"{tenter=mline_string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^[[({]\",\n\t                               \"\", \"\", \"{tenter=skipPair}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^([a-zA-Z_][a-zA-Z0-9_]*)\\\\.(set(_quoted|10)?)[ \\t\\n]*\\\\('([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"   cfgdict \\\\1 known {\\n\"\n\t\t\"      \\\\4 /cfgvar @4 _tag _commit\\n\"\n\t\t\"      cfgdict \\\\1 get scope:\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^[df-hkm-qt-z][a-zA-Z0-9_]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^(jar|executable|shared_module|(both_|shared_|static_)?library)[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\3\", \"B\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^custom_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"c\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^(alias|run)_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\2\", \"r\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^benchmark[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"b\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^import[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"m\", \"{tenter=skipToArgEnd}{_role=imported}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^(configuration_data)[ \\t\\n]*\\\\([ \\t\\n]*\",\n\t                               \"\", \"\", \"{tenter=configBody}\"\n\t\t\"{{\\n\"\n\t\t\"   lastvar false ne {\\n\"\n\t\t\"      lastvar :name\\n\"\n\t\t\"      /cfgdata\\n\"\n\t\t\"      lastvar _tagloc\\n\"\n\t\t\"      _tag _commit\\n\"\n\t\t\"\\n\"\n\t\t\"      % Keep the newly created /cfgdata tag on the stack\\n\"\n\t\t\"      % till leaving /configBody table.\\n\"\n\t\t\"      dup\\n\"\n\t\t\"\\n\"\n\t\t\"      cfgdict lastvar :name 3 -1 roll put\\n\"\n\t\t\"\\n\"\n\t\t\"      % Don't emit the tag for the original variable.\\n\"\n\t\t\"      lastvar _markplaceholder\\n\"\n\t\t\"      /lastvar false def\\n\"\n\t\t\"   } {\\n\"\n\t\t\"      % Looks broken input. There is no left side for the configuration_data(...).\\n\"\n\t\t\"      % Push a dummy tag.\\n\"\n\t\t\"      (cfg) /cfgdata _anongen /cfgdata @1 _tag _commit\\n\"\n\t\t\"      dup /anonymous _markextra\\n\"\n\t\t\"   } ifelse\\n\"\n\t\t\"   % The configElt table refers to the cork index pushed by this table\\n\"\n\t\t\"   % for filling the scope of cfgvar/C tags.\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipPair\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^'''\",\n\t                               \"\", \"\", \"{tenter=mline_string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^[[({]\",\n\t                               \"\", \"\", \"{tenter=skipPair}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^([a-zA-Z_][a-zA-Z0-9_]*)\\\\.(set(_quoted|10)?)[ \\t\\n]*\\\\('([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"   cfgdict \\\\1 known {\\n\"\n\t\t\"      \\\\4 /cfgvar @4 _tag _commit\\n\"\n\t\t\"      cfgdict \\\\1 get scope:\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^[df-hkm-qt-z][a-zA-Z0-9_]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^(jar|executable|shared_module|(both_|shared_|static_)?library)[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\3\", \"B\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^custom_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"c\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^(alias|run)_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\2\", \"r\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^benchmark[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"b\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^import[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"m\", \"{tenter=skipToArgEnd}{_role=imported}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"common\",\n\t                               \"^(configuration_data)[ \\t\\n]*\\\\([ \\t\\n]*\",\n\t                               \"\", \"\", \"{tenter=configBody}\"\n\t\t\"{{\\n\"\n\t\t\"   lastvar false ne {\\n\"\n\t\t\"      lastvar :name\\n\"\n\t\t\"      /cfgdata\\n\"\n\t\t\"      lastvar _tagloc\\n\"\n\t\t\"      _tag _commit\\n\"\n\t\t\"\\n\"\n\t\t\"      % Keep the newly created /cfgdata tag on the stack\\n\"\n\t\t\"      % till leaving /configBody table.\\n\"\n\t\t\"      dup\\n\"\n\t\t\"\\n\"\n\t\t\"      cfgdict lastvar :name 3 -1 roll put\\n\"\n\t\t\"\\n\"\n\t\t\"      % Don't emit the tag for the original variable.\\n\"\n\t\t\"      lastvar _markplaceholder\\n\"\n\t\t\"      /lastvar false def\\n\"\n\t\t\"   } {\\n\"\n\t\t\"      % Looks broken input. There is no left side for the configuration_data(...).\\n\"\n\t\t\"      % Push a dummy tag.\\n\"\n\t\t\"      (cfg) /cfgdata _anongen /cfgdata @1 _tag _commit\\n\"\n\t\t\"      dup /anonymous _markextra\\n\"\n\t\t\"   } ifelse\\n\"\n\t\t\"   % The configElt table refers to the cork index pushed by this table\\n\"\n\t\t\"   % for filling the scope of cfgvar/C tags.\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^[])}]\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^'''\",\n\t                               \"\", \"\", \"{tenter=mline_string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^[[({]\",\n\t                               \"\", \"\", \"{tenter=skipPair}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^([a-zA-Z_][a-zA-Z0-9_]*)\\\\.(set(_quoted|10)?)[ \\t\\n]*\\\\('([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"   cfgdict \\\\1 known {\\n\"\n\t\t\"      \\\\4 /cfgvar @4 _tag _commit\\n\"\n\t\t\"      cfgdict \\\\1 get scope:\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^[df-hkm-qt-z][a-zA-Z0-9_]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^(jar|executable|shared_module|(both_|shared_|static_)?library)[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\3\", \"B\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^custom_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"c\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^(alias|run)_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\2\", \"r\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^benchmark[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"b\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^import[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"m\", \"{tenter=skipToArgEnd}{_role=imported}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^(configuration_data)[ \\t\\n]*\\\\([ \\t\\n]*\",\n\t                               \"\", \"\", \"{tenter=configBody}\"\n\t\t\"{{\\n\"\n\t\t\"   lastvar false ne {\\n\"\n\t\t\"      lastvar :name\\n\"\n\t\t\"      /cfgdata\\n\"\n\t\t\"      lastvar _tagloc\\n\"\n\t\t\"      _tag _commit\\n\"\n\t\t\"\\n\"\n\t\t\"      % Keep the newly created /cfgdata tag on the stack\\n\"\n\t\t\"      % till leaving /configBody table.\\n\"\n\t\t\"      dup\\n\"\n\t\t\"\\n\"\n\t\t\"      cfgdict lastvar :name 3 -1 roll put\\n\"\n\t\t\"\\n\"\n\t\t\"      % Don't emit the tag for the original variable.\\n\"\n\t\t\"      lastvar _markplaceholder\\n\"\n\t\t\"      /lastvar false def\\n\"\n\t\t\"   } {\\n\"\n\t\t\"      % Looks broken input. There is no left side for the configuration_data(...).\\n\"\n\t\t\"      % Push a dummy tag.\\n\"\n\t\t\"      (cfg) /cfgdata _anongen /cfgdata @1 _tag _commit\\n\"\n\t\t\"      dup /anonymous _markextra\\n\"\n\t\t\"   } ifelse\\n\"\n\t\t\"   % The configElt table refers to the cork index pushed by this table\\n\"\n\t\t\"   % for filling the scope of cfgvar/C tags.\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipToArgEnd\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=configElt}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^\\\\)\",\n\t                               \"\", \"\", \"{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"    pop\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^'''\",\n\t                               \"\", \"\", \"{tenter=mline_string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^[[({]\",\n\t                               \"\", \"\", \"{tenter=skipPair}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^([a-zA-Z_][a-zA-Z0-9_]*)\\\\.(set(_quoted|10)?)[ \\t\\n]*\\\\('([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"   cfgdict \\\\1 known {\\n\"\n\t\t\"      \\\\4 /cfgvar @4 _tag _commit\\n\"\n\t\t\"      cfgdict \\\\1 get scope:\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^[df-hkm-qt-z][a-zA-Z0-9_]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^(jar|executable|shared_module|(both_|shared_|static_)?library)[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\3\", \"B\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^custom_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"c\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^(alias|run)_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\2\", \"r\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^benchmark[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"b\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^import[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"m\", \"{tenter=skipToArgEnd}{_role=imported}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configBody\",\n\t                               \"^(configuration_data)[ \\t\\n]*\\\\([ \\t\\n]*\",\n\t                               \"\", \"\", \"{tenter=configBody}\"\n\t\t\"{{\\n\"\n\t\t\"   lastvar false ne {\\n\"\n\t\t\"      lastvar :name\\n\"\n\t\t\"      /cfgdata\\n\"\n\t\t\"      lastvar _tagloc\\n\"\n\t\t\"      _tag _commit\\n\"\n\t\t\"\\n\"\n\t\t\"      % Keep the newly created /cfgdata tag on the stack\\n\"\n\t\t\"      % till leaving /configBody table.\\n\"\n\t\t\"      dup\\n\"\n\t\t\"\\n\"\n\t\t\"      cfgdict lastvar :name 3 -1 roll put\\n\"\n\t\t\"\\n\"\n\t\t\"      % Don't emit the tag for the original variable.\\n\"\n\t\t\"      lastvar _markplaceholder\\n\"\n\t\t\"      /lastvar false def\\n\"\n\t\t\"   } {\\n\"\n\t\t\"      % Looks broken input. There is no left side for the configuration_data(...).\\n\"\n\t\t\"      % Push a dummy tag.\\n\"\n\t\t\"      (cfg) /cfgdata _anongen /cfgdata @1 _tag _commit\\n\"\n\t\t\"      dup /anonymous _markextra\\n\"\n\t\t\"   } ifelse\\n\"\n\t\t\"   % The configElt table refers to the cork index pushed by this table\\n\"\n\t\t\"   % for filling the scope of cfgvar/C tags.\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^'([^']+)'[ \\t\\n]*:\",\n\t                               \"\\\\1\", \"C\", \"{tenter=configValue}\"\n\t\t\"{{\\n\"\n\t\t\"    count 1 ge {\\n\"\n\t\t\"       dup . exch scope:\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^'''\",\n\t                               \"\", \"\", \"{tenter=mline_string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^[[({]\",\n\t                               \"\", \"\", \"{tenter=skipPair}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^([a-zA-Z_][a-zA-Z0-9_]*)\\\\.(set(_quoted|10)?)[ \\t\\n]*\\\\('([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"   cfgdict \\\\1 known {\\n\"\n\t\t\"      \\\\4 /cfgvar @4 _tag _commit\\n\"\n\t\t\"      cfgdict \\\\1 get scope:\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^[df-hkm-qt-z][a-zA-Z0-9_]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^(jar|executable|shared_module|(both_|shared_|static_)?library)[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\3\", \"B\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^custom_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"c\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^(alias|run)_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\2\", \"r\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^benchmark[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"b\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^import[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"m\", \"{tenter=skipToArgEnd}{_role=imported}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configElt\",\n\t                               \"^(configuration_data)[ \\t\\n]*\\\\([ \\t\\n]*\",\n\t                               \"\", \"\", \"{tenter=configBody}\"\n\t\t\"{{\\n\"\n\t\t\"   lastvar false ne {\\n\"\n\t\t\"      lastvar :name\\n\"\n\t\t\"      /cfgdata\\n\"\n\t\t\"      lastvar _tagloc\\n\"\n\t\t\"      _tag _commit\\n\"\n\t\t\"\\n\"\n\t\t\"      % Keep the newly created /cfgdata tag on the stack\\n\"\n\t\t\"      % till leaving /configBody table.\\n\"\n\t\t\"      dup\\n\"\n\t\t\"\\n\"\n\t\t\"      cfgdict lastvar :name 3 -1 roll put\\n\"\n\t\t\"\\n\"\n\t\t\"      % Don't emit the tag for the original variable.\\n\"\n\t\t\"      lastvar _markplaceholder\\n\"\n\t\t\"      /lastvar false def\\n\"\n\t\t\"   } {\\n\"\n\t\t\"      % Looks broken input. There is no left side for the configuration_data(...).\\n\"\n\t\t\"      % Push a dummy tag.\\n\"\n\t\t\"      (cfg) /cfgdata _anongen /cfgdata @1 _tag _commit\\n\"\n\t\t\"      dup /anonymous _markextra\\n\"\n\t\t\"   } ifelse\\n\"\n\t\t\"   % The configElt table refers to the cork index pushed by this table\\n\"\n\t\t\"   % for filling the scope of cfgvar/C tags.\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^,\",\n\t                               \"\", \"\", \"{tjump=configElt}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{_advanceTo=0start}{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^[])}]\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^'''\",\n\t                               \"\", \"\", \"{tenter=mline_string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=string}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^[[({]\",\n\t                               \"\", \"\", \"{tenter=skipPair}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^([a-zA-Z_][a-zA-Z0-9_]*)\\\\.(set(_quoted|10)?)[ \\t\\n]*\\\\('([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"   cfgdict \\\\1 known {\\n\"\n\t\t\"      \\\\4 /cfgvar @4 _tag _commit\\n\"\n\t\t\"      cfgdict \\\\1 get scope:\\n\"\n\t\t\"   } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^[df-hkm-qt-z][a-zA-Z0-9_]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^(jar|executable|shared_module|(both_|shared_|static_)?library)[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\3\", \"B\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^custom_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"c\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^(alias|run)_target[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\2\", \"r\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^benchmark[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"b\", \"{tenter=skipToArgEnd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^import[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*\",\n\t                               \"\\\\1\", \"m\", \"{tenter=skipToArgEnd}{_role=imported}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^(configuration_data)[ \\t\\n]*\\\\([ \\t\\n]*\",\n\t                               \"\", \"\", \"{tenter=configBody}\"\n\t\t\"{{\\n\"\n\t\t\"   lastvar false ne {\\n\"\n\t\t\"      lastvar :name\\n\"\n\t\t\"      /cfgdata\\n\"\n\t\t\"      lastvar _tagloc\\n\"\n\t\t\"      _tag _commit\\n\"\n\t\t\"\\n\"\n\t\t\"      % Keep the newly created /cfgdata tag on the stack\\n\"\n\t\t\"      % till leaving /configBody table.\\n\"\n\t\t\"      dup\\n\"\n\t\t\"\\n\"\n\t\t\"      cfgdict lastvar :name 3 -1 roll put\\n\"\n\t\t\"\\n\"\n\t\t\"      % Don't emit the tag for the original variable.\\n\"\n\t\t\"      lastvar _markplaceholder\\n\"\n\t\t\"      /lastvar false def\\n\"\n\t\t\"   } {\\n\"\n\t\t\"      % Looks broken input. There is no left side for the configuration_data(...).\\n\"\n\t\t\"      % Push a dummy tag.\\n\"\n\t\t\"      (cfg) /cfgdata _anongen /cfgdata @1 _tag _commit\\n\"\n\t\t\"      dup /anonymous _markextra\\n\"\n\t\t\"   } ifelse\\n\"\n\t\t\"   % The configElt table refers to the cork index pushed by this table\\n\"\n\t\t\"   % for filling the scope of cfgvar/C tags.\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"configValue\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* MesonParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\t\"meson.build\",\n\t\tNULL\n\t};\n\n\tstatic roleDefinition MesonModuleRoleTable [] = {\n\t\t{\n\t\t  true, \"imported\", \"imported\",\n\t\t},\n\t};\n\tstatic kindDefinition MesonKindTable [] = {\n\t\t{\n\t\t  true, 'P', \"project\", \"projects\",\n\t\t},\n\t\t{\n\t\t  true, 'V', \"variable\", \"variables\",\n\t\t},\n\t\t{\n\t\t  true, 'S', \"subdir\", \"subdirs\",\n\t\t},\n\t\t{\n\t\t  true, 'B', \"build\", \"build targets\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"custom\", \"custom targets\",\n\t\t},\n\t\t{\n\t\t  true, 't', \"test\", \"tests\",\n\t\t},\n\t\t{\n\t\t  true, 'b', \"benchmark\", \"benchmark targets\",\n\t\t},\n\t\t{\n\t\t  true, 'r', \"run\", \"run targets\",\n\t\t},\n\t\t{\n\t\t  true, 'm', \"module\", \"modules\",\n\t\t  ATTACH_ROLES(MesonModuleRoleTable),\n\t\t},\n\t\t{\n\t\t  true, 'D', \"cfgdata\", \"configuration data objects\",\n\t\t  .version = 1,\n\t\t},\n\t\t{\n\t\t  true, 'C', \"cfgvar\", \"configuration variables\",\n\t\t  .version = 1,\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"Meson\");\n\n\tdef->versionCurrent= 1;\n\tdef->versionAge    = 1;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = MesonKindTable;\n\tdef->kindCount     = ARRAY_SIZE(MesonKindTable);\n\tdef->initialize    = initializeMesonParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/meson.ctags",
    "content": "#\n#  meson.ctags --- multitable regex parser for meson.build files\n#\n#  Copyright (c) 2020 Masatake YAMATO\n#  Copyright (c) 2020 Red Hat, Inc.\n#\n#  This source code is released for free distribution under the terms of the\n#  GNU General Public License version 2 or (at your option) any later version.\n#\n# References:\n#\n# - https://mesonbuild.com/Syntax.html\n#\n\n--langdef=Meson{version=1.1}\n--map-Meson=+(meson.build)\n\n#\n# Kind definitions\n#\n--kinddef-Meson=P,project,projects\n--kinddef-Meson=V,variable,variables\n--kinddef-Meson=S,subdir,subdirs\n--kinddef-Meson=B,build,build targets\n--kinddef-Meson=c,custom,custom targets\n--kinddef-Meson=t,test,tests\n--kinddef-Meson=b,benchmark,benchmark targets\n--kinddef-Meson=r,run,run targets\n--kinddef-Meson=m,module,modules\n--kinddef-Meson=D,cfgdata,configuration data objects{version=1}\n--kinddef-Meson=C,cfgvar,configuration variables{version=1}\n\n#\n# Role definitions\n#\n--_roledef-Meson.{module}=imported,imported\n\n#\n# Tables declaration\n#\n--_tabledef-Meson=main\n--_tabledef-Meson=mline_string\n--_tabledef-Meson=string\n--_tabledef-Meson=comment\n--_tabledef-Meson=skipPair\n--_tabledef-Meson=common\n--_tabledef-Meson=skipToArgEnd\n--_tabledef-Meson=configBody\n--_tabledef-Meson=configElt\n--_tabledef-Meson=configValue\n\n--_prelude-Meson={{\n    /lastvar false def\n    /cfgdict 5 dict def\n}}\n\n#\n# Tables definitions\n#\n--_mtable-regex-Meson=comment/[^\\n]+//\n--_mtable-regex-Meson=comment/\\n//{tleave}\n\n--_mtable-regex-Meson=string/[^\\\\']+//\n--_mtable-regex-Meson=string/'//{tleave}\n--_mtable-regex-Meson=string/\\\\.//\n--_mtable-regex-Meson=string/.//\n\n--_mtable-regex-Meson=mline_string/'''//{tleave}\n--_mtable-regex-Meson=mline_string/[^']+//\n--_mtable-regex-Meson=mline_string/.//\n\n--_mtable-regex-Meson=common/[ \\t\\n]+//\n--_mtable-regex-Meson=common/#//{tenter=comment}\n--_mtable-regex-Meson=common/'''//{tenter=mline_string}\n--_mtable-regex-Meson=common/'//{tenter=string}\n--_mtable-regex-Meson=common/[[({]//{tenter=skipPair}\n--_mtable-regex-Meson=common/([a-zA-Z_][a-zA-Z0-9_]*)\\.(set(_quoted|10)?)[ \\t\\n]*\\('([^']*[^\\\\])'[ \\t\\n]*//{{\n   cfgdict \\1 known {\n      \\4 /cfgvar @4 _tag _commit\n      cfgdict \\1 get scope:\n   } if\n}}\n\n#\n# Skip an unintersting token for optimization\n# ./ctags -o -  /home/yamato/backup/var/util-linux/util-linux-2.41.devel-232-07aac-dirty/meson.build > /dev/null 2> /tmp/logf  0.46s user 0.01s system 97% cpu 0.483 total\n# => ./ctags -o -  /home/yamato/backup/var/util-linux/util-linux-2.41.devel-232-07aac-dirty/meson.build > /dev/null 2> /tmp/logf  0.19s user 0.01s system 97% cpu 0.209 total\n#\n--_mtable-regex-Meson=common/[df-hkm-qt-z][a-zA-Z0-9_]*//\n\n--_mtable-regex-Meson=common/(jar|executable|shared_module|(both_|shared_|static_)?library)[ \\t\\n]*\\([ \\t\\n]*'([^']*[^\\\\])'[ \\t\\n]*/\\3/B/{tenter=skipToArgEnd}\n--_mtable-regex-Meson=common/custom_target[ \\t\\n]*\\([ \\t\\n]*'([^']*[^\\\\])'[ \\t\\n]*/\\1/c/{tenter=skipToArgEnd}\n--_mtable-regex-Meson=common/(alias|run)_target[ \\t\\n]*\\([ \\t\\n]*'([^']*[^\\\\])'[ \\t\\n]*/\\2/r/{tenter=skipToArgEnd}\n--_mtable-regex-Meson=common/benchmark[ \\t\\n]*\\([ \\t\\n]*'([^']*[^\\\\])'[ \\t\\n]*/\\1/b/{tenter=skipToArgEnd}\n--_mtable-regex-Meson=common/import[ \\t\\n]*\\([ \\t\\n]*'([^']*[^\\\\])'[ \\t\\n]*/\\1/m/{tenter=skipToArgEnd}{_role=imported}\n\n--_mtable-regex-Meson=common/(configuration_data)[ \\t\\n]*\\([ \\t\\n]*//{tenter=configBody}{{\n   lastvar false ne {\n      lastvar :name\n      /cfgdata\n      lastvar _tagloc\n      _tag _commit\n\n      % Keep the newly created /cfgdata tag on the stack\n      % till leaving /configBody table.\n      dup\n\n      cfgdict lastvar :name 3 -1 roll put\n\n      % Don't emit the tag for the original variable.\n      lastvar _markplaceholder\n      /lastvar false def\n   } {\n      % Looks broken input. There is no left side for the configuration_data(...).\n      % Push a dummy tag.\n      (cfg) /cfgdata _anongen /cfgdata @1 _tag _commit\n      dup /anonymous _markextra\n   } ifelse\n   % The configElt table refers to the cork index pushed by this table\n   % for filling the scope of cfgvar/C tags.\n}}\n\n--_mtable-regex-Meson=skipPair/[])}]//{tleave}\n--_mtable-extend-Meson=skipPair+common\n--_mtable-regex-Meson=skipPair/.//\n\n--_mtable-extend-Meson=skipToArgEnd+skipPair\n\n--_mtable-regex-Meson=configBody/\\{//{tenter=configElt}\n--_mtable-regex-Meson=configBody/\\)//{tleave}{{\n    pop\n}}\n--_mtable-extend-Meson=configBody+common\n\n--_mtable-regex-Meson=configElt/'([^']+)'[ \\t\\n]*:/\\1/C/{tenter=configValue}{{\n    count 1 ge {\n       dup . exch scope:\n    } if\n}}\n--_mtable-regex-Meson=configElt/\\}//{tleave}\n--_mtable-extend-Meson=configElt+common\n\n--_mtable-regex-Meson=configValue/,//{tjump=configElt}\n--_mtable-regex-Meson=configValue/\\}//{_advanceTo=0start}{tleave}\n--_mtable-extend-Meson=configValue+skipToArgEnd\n\n--_mtable-regex-Meson=main/([a-zA-Z_][a-zA-Z_0-9]*)[ \\t\\n]*=([^=]|$)/\\1/V/{_advanceTo=2start}{{\n   /lastvar . def\n}}\n--_mtable-regex-Meson=main/project[ \\t\\n]*\\([ \\t\\n]*'([^']*[^\\\\])'[ \\t\\n]*/\\1/P/{tenter=skipToArgEnd}\n--_mtable-regex-Meson=main/subdir[ \\t\\n]*\\([ \\t\\n]*'([^']*[^\\\\])'[ \\t\\n]*/\\1/S/{tenter=skipToArgEnd}\n--_mtable-regex-Meson=main/test[ \\t\\n]*\\([ \\t\\n]*'([^']*[^\\\\])'[ \\t\\n]*/\\1/t/{tenter=skipToArgEnd}\n--_mtable-extend-Meson=main+common\n--_mtable-regex-Meson=main/.//\n"
  },
  {
    "path": "optlib/mesonOptions.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/mesonOptions.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeMesonOptionsParser (const langType language CTAGS_ATTR_UNUSED)\n{\n}\n\nextern parserDefinition* MesonOptionsParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\t\"meson_options.txt\",\n\t\tNULL\n\t};\n\n\tstatic kindDefinition MesonOptionsKindTable [] = {\n\t\t{\n\t\t  true, 's', \"string\", \"strings\",\n\t\t},\n\t\t{\n\t\t  true, 'b', \"boolean\", \"booleans\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"combo\", \"combos\",\n\t\t},\n\t\t{\n\t\t  true, 'i', \"integer\", \"integers\",\n\t\t},\n\t\t{\n\t\t  true, 'a', \"array\", \"arrays\",\n\t\t},\n\t\t{\n\t\t  true, 'f', \"feature\", \"features\",\n\t\t},\n\t};\n\tstatic tagRegexTable MesonOptionsTagRegexTable [] = {\n\t\t{\"^option[ \\t\\n]*\\\\([ \\t\\n]*'([^']*[^\\\\\\\\])'[ \\t\\n]*,[ \\t\\n]*type[ \\t\\n]*:[ \\t\\n]*'([a-z]+)'\", \"\",\n\t\t\"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    % \\\\1 points a tag name.\\n\"\n\t\t\"    \\\\1\\n\"\n\t\t\"    % \\\\2 may point a kind. This must be converted to a name from a string.\\n\"\n\t\t\"    \\\\2 cvn\\n\"\n\t\t\"    % Push the start position of the group 1.\\n\"\n\t\t\"    @1\\n\"\n\t\t\"    % To skip an unexpected kind name, _tag is wrapped with stopped.\\n\"\n\t\t\"    { _tag } stopped {\\n\"\n\t\t\"        % Unexpected kind. Clear the stack.\\n\"\n\t\t\"        pop pop pop\\n\"\n\t\t\"    } {\\n\"\n\t\t\"        _commit pop\\n\"\n\t\t\"    } ifelse\\n\"\n\t\t\"}}\", NULL, true},\n\t};\n\n\n\tparserDefinition* const def = parserNew (\"MesonOptions\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = MesonOptionsKindTable;\n\tdef->kindCount     = ARRAY_SIZE(MesonOptionsKindTable);\n\tdef->tagRegexTable = MesonOptionsTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(MesonOptionsTagRegexTable);\n\tdef->initialize    = initializeMesonOptionsParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/mesonOptions.ctags",
    "content": "#\n#  mesonOptions.ctags --- multitable regex parser for meson_options files\n#\n#  Copyright (c) 2021 Masatake YAMATO\n#  Copyright (c) 2021 Red Hat, Inc.\n#\n#  This source code is released for free distribution under the terms of the\n#  GNU General Public License version 2 or (at your option) any later version.\n#\n#  This parser is one of testbed of optscript.\n#\n# References:\n#\n# - https://mesonbuild.com/Build-options.html\n#\n# TODO:\n#\n# - capture choice items\n#\n--langdef=MesonOptions\n--map-MesonOptions=+(meson_options.txt)\n\n--kinddef-MesonOptions=s,string,strings\n--kinddef-MesonOptions=b,boolean,booleans\n--kinddef-MesonOptions=c,combo,combos\n--kinddef-MesonOptions=i,integer,integers\n--kinddef-MesonOptions=a,array,arrays\n--kinddef-MesonOptions=f,feature,features\n\n--mline-regex-MesonOptions=/^option[ \\t\\n]*\\([ \\t\\n]*'([^']*[^\\\\])'[ \\t\\n]*,[ \\t\\n]*type[ \\t\\n]*:[ \\t\\n]*'([a-z]+)'//{{\n    % \\1 points a tag name.\n    \\1\n    % \\2 may point a kind. This must be converted to a name from a string.\n    \\2 cvn\n    % Push the start position of the group 1.\n    @1\n    % To skip an unexpected kind name, _tag is wrapped with stopped.\n    { _tag } stopped {\n        % Unexpected kind. Clear the stack.\n        pop pop pop\n    } {\n        _commit pop\n    } ifelse\n}}\n"
  },
  {
    "path": "optlib/nftables.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/nftables.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeNftablesParser (const langType language CTAGS_ATTR_UNUSED)\n{\n}\n\nextern parserDefinition* NftablesParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"nft\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic roleDefinition NftablesFamilyRoleTable [] = {\n\t\t{\n\t\t  false, \"referenced\", \"referenced somehow\",\n\t\t},\n\t};\n\tstatic roleDefinition NftablesRulesetRoleTable [] = {\n\t\t{\n\t\t  true, \"included\", \"included ruleset\",\n\t\t},\n\t};\n\tstatic kindDefinition NftablesKindTable [] = {\n\t\t{\n\t\t  true, 'f', \"family\", \"families\",\n\t\t  ATTACH_ROLES(NftablesFamilyRoleTable),\n\t\t},\n\t\t{\n\t\t  true, 'h', \"hook\", \"hooks\",\n\t\t},\n\t\t{\n\t\t  true, 't', \"table\", \"tables\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"chain\", \"chains\",\n\t\t},\n\t\t{\n\t\t  true, 's', \"set\", \"sets\",\n\t\t},\n\t\t{\n\t\t  true, 'm', \"map\", \"maps\",\n\t\t},\n\t\t{\n\t\t  true, 'D', \"definition\", \"definitions\",\n\t\t},\n\t\t{\n\t\t  true, 'R', \"ruleset\", \"rulesets\",\n\t\t  ATTACH_ROLES(NftablesRulesetRoleTable),\n\t\t},\n\t\t{\n\t\t  true, 'H', \"ctherlper\", \"connection tracking helpers\",\n\t\t},\n\t\t{\n\t\t  true, 'E', \"ctexpectation\", \"connection tracking expectations\",\n\t\t},\n\t\t{\n\t\t  true, 'T', \"cttimeout\", \"connection tracking timeout\",\n\t\t},\n\t\t{\n\t\t  true, 'S', \"secmark\", \"secmarks\",\n\t\t},\n\t\t{\n\t\t  true, 'W', \"flowtable\", \"flowtables\",\n\t\t},\n\t\t{\n\t\t  true, 'P', \"synproxy\", \"synproxies\",\n\t\t},\n\t\t{\n\t\t  true, 'C', \"counter\", \"counters\",\n\t\t},\n\t\t{\n\t\t  true, 'l', \"limit\", \"limits\",\n\t\t},\n\t\t{\n\t\t  true, 'Q', \"quota\", \"quotas\",\n\t\t},\n\t};\n\tstatic tagRegexTable NftablesTagRegexTable [] = {\n\t\t{\"^[ \\t]*#\", \"\",\n\t\t\"\", \"{exclusive}\", NULL, false},\n\t\t{\"^[ \\t]*family[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"f\", \"{exclusive}{scope=set}\", NULL, false},\n\t\t{\"^[ \\t]*hook[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"h\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*table[ \\t]+([-a-zA-Z0-9_]+)[ \\t]+([a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\",\n\t\t\"\", \"{exclusive}\"\n\t\t\"{{\\n\"\n\t\t\"   \\\\1 /family /referenced _reftag _commit\\n\"\n\t\t\"   \\\\2 /table _tag _commit dup 3 -1 roll scope:\\n\"\n\t\t\"   _scopeset\\n\"\n\t\t\"}}\", NULL, false},\n\t\t{\"^[ \\t]*table[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"t\", \"{exclusive}{scope=set}\", NULL, false},\n\t\t{\"^[ \\t]*chain[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"c\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*set[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"s\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*map[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"m\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*define[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*=\", \"\\\\1\",\n\t\t\"D\", \"{exclusive}\", NULL, false},\n\t\t{\"^[ \\t]*include[ \\t]+\\\"([^\\\"]+)\\\"\", \"\\\\1\",\n\t\t\"R\", \"{exclusive}{_role=included}\", NULL, false},\n\t\t{\"^[ \\t]*ct[ \\t]+helper[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"H\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*ct[ \\t]+expectation[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"E\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*ct[ \\t]+timeout[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"T\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*secmark[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"S\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*flowtable[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"W\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*synproxy[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"P\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*counter[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"C\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*limit[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"L\", \"{exclusive}{scope=ref}\", NULL, false},\n\t\t{\"^[ \\t]*quota[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\\\{\", \"\\\\1\",\n\t\t\"Q\", \"{exclusive}{scope=ref}\", NULL, false},\n\t};\n\n\n\tparserDefinition* const def = parserNew (\"Nftables\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = NftablesKindTable;\n\tdef->kindCount     = ARRAY_SIZE(NftablesKindTable);\n\tdef->tagRegexTable = NftablesTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(NftablesTagRegexTable);\n\tdef->initialize    = initializeNftablesParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/nftables.ctags",
    "content": "#\n#  nftables.ctags --- regex parser for the output of nft command\n#\n#  Copyright (c) 2025, Red Hat, Inc.\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n--langdef=Nftables\n--map-Nftables=+.nft\n\n#\n# Kind and role definitions\n#\n--kinddef-Nftables=f,family,families\n--_roledef-Nftables.f=referenced,referenced somehow\n--roles-Nftables.f=-{referenced}\n--kinddef-Nftables=h,hook,hooks\n\n--kinddef-Nftables=t,table,tables\n--kinddef-Nftables=c,chain,chains\n\n--kinddef-Nftables=s,set,sets\n--kinddef-Nftables=m,map,maps\n\n--kinddef-Nftables=D,definition,definitions\n--kinddef-Nftables=R,ruleset,rulesets\n--_roledef-Nftables.{ruleset}=included,included ruleset\n\n--kinddef-Nftables=H,ctherlper,connection tracking helpers\n--kinddef-Nftables=E,ctexpectation,connection tracking expectations\n--kinddef-Nftables=T,cttimeout,connection tracking timeout\n\n--kinddef-Nftables=S,secmark,secmarks\n\n--kinddef-Nftables=W,flowtable,flowtables\n\n--kinddef-Nftables=P,synproxy,synproxies\n\n--kinddef-Nftables=C,counter,counters\n--kinddef-Nftables=l,limit,limits\n--kinddef-Nftables=Q,quota,quotas\n\n#\n# Regex patterns\n#\n--regex-Nftables=/^[ \\t]*#//{exclusive}\n\n# Patterns for parsing the output for \"nft list hooks\"\n--regex-Nftables=/^[ \\t]*family[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/f/{exclusive}{scope=set}\n--regex-Nftables=/^[ \\t]*hook[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/h/{exclusive}{scope=ref}\n\n--regex-Nftables=/^[ \\t]*table[ \\t]+([-a-zA-Z0-9_]+)[ \\t]+([a-zA-Z0-9_]+)[ \\t]*\\{//{exclusive}{{\n   \\1 /family /referenced _reftag _commit\n   \\2 /table _tag _commit dup 3 -1 roll scope:\n   _scopeset\n}}\n--regex-Nftables=/^[ \\t]*table[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/t/{exclusive}{scope=set}\n--regex-Nftables=/^[ \\t]*chain[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/c/{exclusive}{scope=ref}\n\n--regex-Nftables=/^[ \\t]*set[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/s/{exclusive}{scope=ref}\n--regex-Nftables=/^[ \\t]*map[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/m/{exclusive}{scope=ref}\n--regex-Nftables=/^[ \\t]*define[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*=/\\1/D/{exclusive}\n--regex-Nftables=/^[ \\t]*include[ \\t]+\"([^\"]+)\"/\\1/R/{exclusive}{_role=included}\n\n--regex-Nftables=/^[ \\t]*ct[ \\t]+helper[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/H/{exclusive}{scope=ref}\n--regex-Nftables=/^[ \\t]*ct[ \\t]+expectation[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/E/{exclusive}{scope=ref}\n--regex-Nftables=/^[ \\t]*ct[ \\t]+timeout[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/T/{exclusive}{scope=ref}\n\n--regex-Nftables=/^[ \\t]*secmark[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/S/{exclusive}{scope=ref}\n\n--regex-Nftables=/^[ \\t]*flowtable[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/W/{exclusive}{scope=ref}\n\n--regex-Nftables=/^[ \\t]*synproxy[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/P/{exclusive}{scope=ref}\n\n--regex-Nftables=/^[ \\t]*counter[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/C/{exclusive}{scope=ref}\n--regex-Nftables=/^[ \\t]*limit[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/L/{exclusive}{scope=ref}\n--regex-Nftables=/^[ \\t]*quota[ \\t]+([-a-zA-Z0-9_]+)[ \\t]*\\{/\\1/Q/{exclusive}{scope=ref}\n"
  },
  {
    "path": "optlib/org.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/org.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeOrgParser (const langType language)\n{\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE,\n\t\t\"{{    /kindTable [\\n\"\n\t\t\"        /part\\n\"\n\t\t\"        /chapter\\n\"\n\t\t\"        /section\\n\"\n\t\t\"        /subsection\\n\"\n\t\t\"        /subsubsection\\n\"\n\t\t\"        /paragraph\\n\"\n\t\t\"        /subparagraph\\n\"\n\t\t\"    ] def\\n\"\n\t\t\"}}\");\n\n\taddLanguageRegexTable (language, \"toplevel\");\n\taddLanguageRegexTable (language, \"srcblock\");\n\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[^#*<]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^#\\\\+begin_src[ ]+([a-zA-Z0-9][-#+a-zA-Z0-9]*)\",\n\t                               \"\", \"\", \"{tenter=srcblock}{_guest=\\\\1,0end,}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^#\\\\+(NAME|name):[[:blank:]]+([[:graph:][:blank:]]+)([\\n])?\",\n\t                               \"\\\\2\", \"d\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^#[^\\n]*\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^(\\\\*{1,7})[ \\t]+([[:graph:][:blank:]]+)([\\n])?\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\2 kindTable \\\\1 length 1 sub get @2 _tag _commit pop\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^<<([^>]+)>>\",\n\t                               \"\\\\1\", \"d\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"srcblock\",\n\t                               \"^[^#]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"srcblock\",\n\t                               \"^#\\\\+end_src\",\n\t                               \"\", \"\", \"{tleave}{_guest=,,0end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"srcblock\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* OrgParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"org\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition OrgKindTable [] = {\n\t\t{\n\t\t  true, 'd', \"definition\", \"definitions\",\n\t\t},\n\t\t{\n\t\t  true, 'p', \"part\", \"parts\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"chapter\", \"chapters\",\n\t\t},\n\t\t{\n\t\t  true, 's', \"section\", \"sections\",\n\t\t},\n\t\t{\n\t\t  true, 'u', \"subsection\", \"subsections\",\n\t\t},\n\t\t{\n\t\t  true, 'b', \"subsubsection\", \"subsubsections\",\n\t\t},\n\t\t{\n\t\t  true, 'P', \"paragraph\", \"paragraphs\",\n\t\t},\n\t\t{\n\t\t  true, 'G', \"subparagraph\", \"subparagraphs\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"Org\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = OrgKindTable;\n\tdef->kindCount     = ARRAY_SIZE(OrgKindTable);\n\tdef->initialize    = initializeOrgParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/org.ctags",
    "content": "#  org.ctags regex parser for org-mode files\n#  Copyright (c) 2022 Universite Rennes 2\n#  Copyright (c) 2022 Pierre-Andre CORNILLON\n#\n##  Author: Pierre-Andre Cornillon pierre-andre.cornillon@univ-rennes2.fr\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n#  References:\n#  - https://orgmode.org/\n#\n--langdef=Org\n--map-Org=+.org\n# definitions\n--kinddef-Org=d,definition,definitions\n--kinddef-Org=p,part,parts\n--kinddef-Org=c,chapter,chapters\n--kinddef-Org=s,section,sections\n--kinddef-Org=u,subsection,subsections\n--kinddef-Org=b,subsubsection,subsubsections\n--kinddef-Org=P,paragraph,paragraphs\n--kinddef-Org=G,subparagraph,subparagraphs\n# definition of levels\n--_tabledef-Org=toplevel\n--_tabledef-Org=srcblock\n\n--_prelude-Org={{\n    /kindTable [\n        /part\n        /chapter\n        /section\n        /subsection\n        /subsubsection\n        /paragraph\n        /subparagraph\n    ] def\n}}\n\n################################\n# beginning of toplevel\n################################\n--_mtable-regex-Org=toplevel/[^#*<]+//\n# if encounter a src block do language identify languge and defer\n--_mtable-regex-Org=toplevel/#\\+begin_src[ ]+([a-zA-Z0-9][-#+a-zA-Z0-9]*)//{tenter=srcblock}{_guest=\\1,0end,}\n# labels\n--_mtable-regex-Org=toplevel/#\\+(NAME|name):[[:blank:]]+([[:graph:][:blank:]]+)([\\n])?/\\2/d/\n# skip #...\n--_mtable-regex-Org=toplevel/#[^\\n]*\\n//\n# sections stuff\n--_mtable-regex-Org=toplevel/(\\*{1,7})[ \\t]+([[:graph:][:blank:]]+)([\\n])?//{{\n    \\2 kindTable \\1 length 1 sub get @2 _tag _commit pop\n}}\n# labels\n--_mtable-regex-Org=toplevel/<<([^>]+)>>/\\1/d/\n## else do nothing (end of toplevel)\n--_mtable-regex-Org=toplevel/.//\n\n################################\n# beginning of src block\n################################\n# if end of src block exit\n--_mtable-regex-Org=srcblock/[^#]+//\n--_mtable-regex-Org=srcblock/#\\+end_src//{tleave}{_guest=,,0end}\n# else do nothing\n--_mtable-regex-Org=srcblock/.//\n"
  },
  {
    "path": "optlib/passwd.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/passwd.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializePasswdParser (const langType language CTAGS_ATTR_UNUSED)\n{\n}\n\nextern parserDefinition* PasswdParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\t\"passwd\",\n\t\tNULL\n\t};\n\n\tstatic kindDefinition PasswdKindTable [] = {\n\t\t{\n\t\t  true, 'u', \"username\", \"user names\",\n\t\t},\n\t};\n\tstatic fieldDefinition PasswdFieldTable [] = {\n\t\t{\n\t\t  .enabled     = true,\n\t\t  .name        = \"home\",\n\t\t  .description = \"home directory\",\n\t\t  .dataType = FIELDTYPE_SCRIPTABLE|FIELDTYPE_STRING,\n\t\t  .isValueAvailable = isValueAvailableGeneric,\n\t\t  .getValueObject = getFieldValueGeneric,\n\t\t  .setValueObject = setFieldValueGeneric,\n\t\t},\n\t\t{\n\t\t  .enabled     = true,\n\t\t  .name        = \"shell\",\n\t\t  .description = \"login shell\",\n\t\t  .dataType = FIELDTYPE_SCRIPTABLE|FIELDTYPE_STRING,\n\t\t  .isValueAvailable = isValueAvailableGeneric,\n\t\t  .getValueObject = getFieldValueGeneric,\n\t\t  .setValueObject = setFieldValueGeneric,\n\t\t},\n\t};\n\tstatic tagRegexTable PasswdTagRegexTable [] = {\n\t\t{\"^([^:]+):([^:]+):([^:]+):([^:]+):([^:]*):([^:]+):([^:]+)\", \"\\\\1\",\n\t\t\"u\", \"{_field=home:\\\\6}{_field=shell:\\\\7}\", NULL, false},\n\t};\n\n\n\tparserDefinition* const def = parserNew (\"Passwd\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->kindTable     = PasswdKindTable;\n\tdef->kindCount     = ARRAY_SIZE(PasswdKindTable);\n\tdef->fieldTable    = PasswdFieldTable;\n\tdef->fieldCount    = ARRAY_SIZE(PasswdFieldTable);\n\tdef->tagRegexTable = PasswdTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(PasswdTagRegexTable);\n\tdef->initialize    = initializePasswdParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/passwd.ctags",
    "content": "#\n#  Copyright (c) 2016, 2017 Red Hat, Inc.\n#  Copyright (c) 2016, 2017 Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n\n#\n# This optlib is a testbed for --_fielddef option and _field regex flag.\n#\n\n--langdef=Passwd\n--map-Passwd=+(passwd)\n--kinddef-Passwd=u,username,user names\n--_fielddef-Passwd=home,home directory{datatype=str}\n--_fielddef-Passwd=shell,login shell{datatype=str}\n--fields-Passwd=+{home}\n--fields-Passwd=+{shell}\n--regex-Passwd=/^([^:]+):([^:]+):([^:]+):([^:]+):([^:]*):([^:]+):([^:]+)/\\1/u/{_field=home:\\6}{_field=shell:\\7}\n"
  },
  {
    "path": "optlib/pkgConfig.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/pkgConfig.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializePkgConfigParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"dep\");\n\taddLanguageRegexTable (language, \"rightside\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^([-a-zA-Z0-9_.]+)[\\t ]*=[^\\n]*\",\n\t                               \"\\\\1\", \"v\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^Name:[\\t ]*([^\\n]+)\",\n\t                               \"\\\\1\", \"N\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    % Name: ... is a display name. Not a package name.\\n\"\n\t\t\"    . :input\\n\"\n\t\t\"    ?/ _strrchr {\\n\"\n\t\t\"        1 add dup\\n\"\n\t\t\"        . :input length\\n\"\n\t\t\"        exch sub 0 string _copyinterval\\n\"\n\t\t\"    } if\\n\"\n\t\t\"    (.pc) _strrstr {\\n\"\n\t\t\"        % (pkgname.pc) offset\\n\"\n\t\t\"        0 exch 0 string _copyinterval /pkg @1 _tag _commit\\n\"\n\t\t\"        /PkgConfig.guessedFromFileName _markextra\\n\"\n\t\t\"    } {\\n\"\n\t\t\"        pop\\n\"\n\t\t\"    } ifelse\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^Requires(\\\\.private)?:[\\t ]*\",\n\t                               \"\", \"\", \"{tenter=dep}\"\n\t\t\"{{\\n\"\n\t\t\"    /required\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^Provides:[\\t ]*\",\n\t                               \"\", \"\", \"{tenter=dep}\"\n\t\t\"{{\\n\"\n\t\t\"    /provided\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^Conflicts:[\\t ]*\",\n\t                               \"\", \"\", \"{tenter=dep}\"\n\t\t\"{{\\n\"\n\t\t\"    /conflicted\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^\\n]+|[\\n]\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dep\",\n\t                               \"^([^[:space:]=<>!]+)[ \\t]*\",\n\t                               \"\\\\1\", \"p\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    dup . exch _assignrole\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dep\",\n\t                               \"^(=|<=?|>=?|!=)[\\t ]*\",\n\t                               \"\", \"\", \"{tenter=rightside}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dep\",\n\t                               \"^[\\n]\",\n\t                               \"\", \"\", \"{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"    pop\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dep\",\n\t                               \"^[^\\n]\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rightside\",\n\t                               \"^([^[:space:],]+)\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rightside\",\n\t                               \"^[ \\t,]\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rightside\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"{_advanceTo=0start}{tleave}\", NULL);\n}\n\nextern parserDefinition* PkgConfigParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"pc\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic roleDefinition PkgConfigPkgRoleTable [] = {\n\t\t{\n\t\t  true, \"required\", \"required\",\n\t\t},\n\t\t{\n\t\t  true, \"provided\", \"provided\",\n\t\t},\n\t\t{\n\t\t  true, \"conflicted\", \"conflicted\",\n\t\t},\n\t};\n\tstatic kindDefinition PkgConfigKindTable [] = {\n\t\t{\n\t\t  true, 'N', \"name\", \"display names\",\n\t\t},\n\t\t{\n\t\t  true, 'p', \"pkg\", \"packages\",\n\t\t  ATTACH_ROLES(PkgConfigPkgRoleTable),\n\t\t},\n\t\t{\n\t\t  true, 'v', \"var\", \"variabels\",\n\t\t},\n\t};\n\tstatic xtagDefinition PkgConfigXtagTable [] = {\n\t\t{\n\t\t  .enabled     = true,\n\t\t  .name        = \"guessedFromFileName\",\n\t\t  .description = \"the guessed package name of the .pc file\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"PkgConfig\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = PkgConfigKindTable;\n\tdef->kindCount     = ARRAY_SIZE(PkgConfigKindTable);\n\tdef->xtagTable     = PkgConfigXtagTable;\n\tdef->xtagCount     = ARRAY_SIZE(PkgConfigXtagTable);\n\tdef->initialize    = initializePkgConfigParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/pkgConfig.ctags",
    "content": "#\n#\n#  Copyright (c) 2023, Red Hat, Inc.\n#  Copyright (c) 2023, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n# This module extracts headers of pkg-config file.\n#\n# References:\n# - https://gitlab.freedesktop.org/pkg-config/pkg-config/-/blob/master/pkg-config.1?ref_type=heads\n# - https://people.freedesktop.org/~dbn/pkg-config-guide.html#writing\n# - https://github.com/pkgconf/pkgconf/blob/master/man/pc.5\n#\n--langdef=PkgConfig\n--map-PkgConfig=+.pc\n\n--kinddef-PkgConfig=N,name,display names\n--kinddef-PkgConfig=p,pkg,packages\n--_roledef-PkgConfig.{pkg}=required,required\n--_roledef-PkgConfig.{pkg}=provided,provided\n--_roledef-PkgConfig.{pkg}=conflicted,conflicted\n--kinddef-PkgConfig=v,var,variabels\n\n--_extradef-PkgConfig=guessedFromFileName,the guessed package name of the .pc file\n--extras-PkgConfig=+{guessedFromFileName}\n\n--_tabledef-PkgConfig=main\n--_tabledef-PkgConfig=dep\n--_tabledef-PkgConfig=rightside\n\n--_mtable-regex-PkgConfig=main/([-a-zA-Z0-9_.]+)[\\t ]*=[^\\n]*/\\1/v/\n--_mtable-regex-PkgConfig=main/Name:[\\t ]*([^\\n]+)/\\1/N/{{\n    % Name: ... is a display name. Not a package name.\n    . :input\n    ?/ _strrchr {\n        1 add dup\n        . :input length\n        exch sub 0 string _copyinterval\n    } if\n    (.pc) _strrstr {\n        % (pkgname.pc) offset\n        0 exch 0 string _copyinterval /pkg @1 _tag _commit\n        /PkgConfig.guessedFromFileName _markextra\n    } {\n        pop\n    } ifelse\n}}\n--_mtable-regex-PkgConfig=main/Requires(\\.private)?:[\\t ]*//{tenter=dep}{{\n    /required\n}}\n--_mtable-regex-PkgConfig=main/Provides:[\\t ]*//{tenter=dep}{{\n    /provided\n}}\n--_mtable-regex-PkgConfig=main/Conflicts:[\\t ]*//{tenter=dep}{{\n    /conflicted\n}}\n--_mtable-regex-PkgConfig=main/[^\\n]+|[\\n]//\n\n#\n# Dependencies\n#\n--_mtable-regex-PkgConfig=dep/([^[:space:]=<>!]+)[ \\t]*/\\1/p/{{\n    dup . exch _assignrole\n}}\n--_mtable-regex-PkgConfig=dep/(=|<=?|>=?|!=)[\\t ]*//{tenter=rightside}\n--_mtable-regex-PkgConfig=dep/[\\n]//{tleave}{{\n    pop\n}}\n--_mtable-regex-PkgConfig=dep/[^\\n]//\n\n--_mtable-regex-PkgConfig=rightside/([^[:space:],]+)//\n--_mtable-regex-PkgConfig=rightside/[ \\t,]//{tleave}\n--_mtable-regex-PkgConfig=rightside/.//{_advanceTo=0start}{tleave}\n"
  },
  {
    "path": "optlib/pod.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/pod.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\ntypedef enum {\n\tK_CHAPTER,\n\tK_SECTION,\n\tK_SUBSECTION,\n\tK_SUBSUBSECTION,\n} PodKind;\n\n\nstatic void initializePodParser (const langType language CTAGS_ATTR_UNUSED)\n{\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE,\n\t\t\"{{    /kindTable [\\n\"\n\t\t\"        /chapter /section /subsection /subsubsection\\n\"\n\t\t\"    ] def\\n\"\n\t\t\"\\n\"\n\t\t\"    % numstr:str TOLEVEL int\\n\"\n\t\t\"    /tolevel {\\n\"\n\t\t\"        0 get ?1 sub\\n\"\n\t\t\"    } def\\n\"\n\t\t\"\\n\"\n\t\t\"    % cork:int DEPTHFORCORK depth:int\\n\"\n\t\t\"    /depthForCork {\\n\"\n\t\t\"        :kind kindTable exch _aindex pop\\n\"\n\t\t\"    } def\\n\"\n\t\t\"\\n\"\n\t\t\"    % endline:int goal:int scopePopUpTo -\\n\"\n\t\t\"    /scopePopUpTo\\n\"\n\t\t\"    {\\n\"\n\t\t\"        {\\n\"\n\t\t\"            _scopetop {\\n\"\n\t\t\"                dup\\n\"\n\t\t\"                % endline goal scope scope\\n\"\n\t\t\"                depthForCork 2 index ge {\\n\"\n\t\t\"                    % endline goal scope\\n\"\n\t\t\"                    2 index end:\\n\"\n\t\t\"                    _scopepop\\n\"\n\t\t\"                } {\\n\"\n\t\t\"                    pop\\n\"\n\t\t\"                    exit\\n\"\n\t\t\"                } ifelse\\n\"\n\t\t\"            } {\\n\"\n\t\t\"                exit\\n\"\n\t\t\"            } ifelse\\n\"\n\t\t\"        } loop\\n\"\n\t\t\"        pop\\n\"\n\t\t\"        pop\\n\"\n\t\t\"    } def\\n\"\n\t\t\"}}\");\n}\n\nextern parserDefinition* PodParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"pod\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition PodKindTable [] = {\n\t\t{\n\t\t  true, 'c', \"chapter\", \"chapters\",\n\t\t},\n\t\t{\n\t\t  true, 's', \"section\", \"sections\",\n\t\t},\n\t\t{\n\t\t  true, 'S', \"subsection\", \"subsections\",\n\t\t},\n\t\t{\n\t\t  true, 't', \"subsubsection\", \"subsubsections\",\n\t\t},\n\t};\n\tstatic tagRegexTable PodTagRegexTable [] = {\n\t\t{\"^=head([1-4])[ \\t]+(.+)\", \"\",\n\t\t\"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\2\\n\"\n\t\t\"    kindTable \\\\1 tolevel get\\n\"\n\t\t\"    @2\\n\"\n\t\t\"    _tag _commit\\n\"\n\t\t\"    dup :line 1 sub \\\\1 tolevel scopePopUpTo\\n\"\n\t\t\"    _scopetop {\\n\"\n\t\t\"        1 index exch scope: _scopepush\\n\"\n\t\t\"    } {\\n\"\n\t\t\"        _scopepush\\n\"\n\t\t\"    } ifelse\\n\"\n\t\t\"}}\", NULL, false},\n\t};\n\n\n\tparserDefinition* const def = parserNew (\"Pod\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = PodKindTable;\n\tdef->kindCount     = ARRAY_SIZE(PodKindTable);\n\tdef->tagRegexTable = PodTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(PodTagRegexTable);\n\tdef->defaultScopeSeparator = \"\\\"\\\"\";\n\tdef->initialize    = initializePodParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/pod.ctags",
    "content": "#\n#\n#  Copyright (c) 2016, Red Hat, Inc.\n#  Copyright (c) 2016, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n# This module extracts headers of Pod file.\n#\n# References:\n# - https://perldoc.perl.org/perlpod\n# - https://perldoc.perl.org/perlpodspec\n#\n--langdef=Pod\n--map-Pod=+.pod\n\n--kinddef-Pod=c,chapter,chapters\n--kinddef-Pod=s,section,sections\n--kinddef-Pod=S,subsection,subsections\n--kinddef-Pod=t,subsubsection,subsubsections\n\n# Separator definitions must come after kind definitions.\n# This is the limitation of optlib2c.\n--_scopesep-Pod=*/*:\"\"\n\n--_prelude-Pod={{\n    /kindTable [\n        /chapter /section /subsection /subsubsection\n    ] def\n\n    % numstr:str TOLEVEL int\n    /tolevel {\n        0 get ?1 sub\n    } def\n\n    % cork:int DEPTHFORCORK depth:int\n    /depthForCork {\n        :kind kindTable exch _aindex pop\n    } def\n\n    % endline:int goal:int scopePopUpTo -\n    /scopePopUpTo\n    {\n        {\n            _scopetop {\n                dup\n                % endline goal scope scope\n                depthForCork 2 index ge {\n                    % endline goal scope\n                    2 index end:\n                    _scopepop\n                } {\n                    pop\n                    exit\n                } ifelse\n            } {\n                exit\n            } ifelse\n        } loop\n        pop\n        pop\n    } def\n}}\n\n--regex-Pod=/^=head([1-4])[ \\t]+(.+)//{{\n    \\2\n    kindTable \\1 tolevel get\n    @2\n    _tag _commit\n    dup :line 1 sub \\1 tolevel scopePopUpTo\n    _scopetop {\n        1 index exch scope: _scopepush\n    } {\n        _scopepush\n    } ifelse\n}}\n"
  },
  {
    "path": "optlib/puppetManifest.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/puppetManifest.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\ntypedef enum {\n\tK_CLASS,\n\tK_DEFINITION,\n\tK_NODE,\n\tK_RESOURCE,\n\tK_VARIABLE,\n\tK_PARAM,\n\tK_VRESOURCE,\n\tK_TYPE,\n} PuppetManifestKind;\n\n\nstatic void initializePuppetManifestParser (const langType language)\n{\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE,\n\t\t\"{{    % spec:dict<num,kind> TRYMAKETAG tag:int true\\n\"\n\t\t\"    % spec:dict<num,kind> TRYMAKETAG false\\n\"\n\t\t\"    /trymaketag {\\n\"\n\t\t\"        {\\n\"\n\t\t\"            {\\n\"\n\t\t\"                1 index _matchstr {\\n\"\n\t\t\"                    % key value str\\n\"\n\t\t\"                    3 -1 roll\\n\"\n\t\t\"                    % value str key\\n\"\n\t\t\"                    _matchloc\\n\"\n\t\t\"                    % value str loc\\n\"\n\t\t\"                    3 -1 roll exch\\n\"\n\t\t\"                    % str value loc\\n\"\n\t\t\"                    _tag _commit\\n\"\n\t\t\"                    stop\\n\"\n\t\t\"                } {\\n\"\n\t\t\"                    pop pop\\n\"\n\t\t\"                } ifelse\\n\"\n\t\t\"            } forall\\n\"\n\t\t\"         } stopped\\n\"\n\t\t\"    } def\\n\"\n\t\t\"}}\");\n\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"separator\");\n\taddLanguageRegexTable (language, \"any\");\n\taddLanguageRegexTable (language, \"ignoreWhiteSpace\");\n\taddLanguageRegexTable (language, \"end\");\n\taddLanguageRegexTable (language, \"endWithPop\");\n\taddLanguageRegexTable (language, \"ssliteral\");\n\taddLanguageRegexTable (language, \"dsliteral\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"blockStart\");\n\taddLanguageRegexTable (language, \"blockHead\");\n\taddLanguageRegexTable (language, \"blockHeadPopAtLast\");\n\taddLanguageRegexTable (language, \"block\");\n\taddLanguageRegexTable (language, \"classStart\");\n\taddLanguageRegexTable (language, \"resourceBlock\");\n\taddLanguageRegexTable (language, \"skipLiteral\");\n\taddLanguageRegexTable (language, \"skipBlock\");\n\taddLanguageRegexTable (language, \"skipArray\");\n\taddLanguageRegexTable (language, \"skipArgs\");\n\taddLanguageRegexTable (language, \"skipCollector\");\n\taddLanguageRegexTable (language, \"signature\");\n\taddLanguageRegexTable (language, \"skipDefaultValue\");\n\taddLanguageRegexTable (language, \"var\");\n\taddLanguageRegexTable (language, \"defineStart\");\n\taddLanguageRegexTable (language, \"caseStart\");\n\taddLanguageRegexTable (language, \"ifStart\");\n\taddLanguageRegexTable (language, \"nodeStart\");\n\taddLanguageRegexTable (language, \"typeStart\");\n\taddLanguageRegexTable (language, \"comment_multiline\");\n\taddLanguageRegexTable (language, \"comment_oneline\");\n\taddLanguageRegexTable (language, \"resourceName\");\n\taddLanguageRegexTable (language, \"resourceNameInArray\");\n\taddLanguageRegexTable (language, \"resourceBody\");\n\taddLanguageRegexTable (language, \"resourceArray\");\n\taddLanguageRegexTable (language, \"resourceCollector\");\n\taddLanguageRegexTable (language, \"varexpr\");\n\taddLanguageRegexTable (language, \"caseBlock\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^<<?\\\\|\",\n\t                               \"\", \"\", \"{tenter=skipCollector}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\$\",\n\t                               \"\", \"\", \"{tenter=var}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^(@)?(::[a-zA-Z0-9:_]+|[a-zA-Z][a-zA-Z0-9:_]*)[ \\t\\n]*\\\\{\",\n\t                               \"\", \"\", \"{tenter=resourceBlock}\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\1 _isstring {\\n\"\n\t\t\"       /vresource\\n\"\n\t\t\"    } {\\n\"\n\t\t\"       /resource\\n\"\n\t\t\"    } ifelse \\\\2 true\\n\"\n\t\t\"    % kind:name type:string true\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^class[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=classStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^define[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=defineStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^case[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=caseStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^(if|elsif|else|unless)[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=ifStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^node[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=nodeStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^type[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=typeStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\$\",\n\t                               \"\", \"\", \"{tenter=var}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\(\",\n\t                               \"\", \"\", \"{tenter=skipArgs}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=skipBlock}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"{tenter=separator}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"separator\",\n\t                               \"^[a-zA-Z0-9]\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"separator\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"any\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ignoreWhiteSpace\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"end\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"endWithPop\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{tleave}{scope=pop}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ssliteral\",\n\t                               \"^[^']*'\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ssliteral\",\n\t                               \"^[^']+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dsliteral\",\n\t                               \"^[^\\\"]*\\\"\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dsliteral\",\n\t                               \"^[^\\\"]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockStart\",\n\t                               \"^(@)?(::[a-zA-Z0-9:_]+|[a-zA-Z][a-zA-Z0-9:_]*)[ \\t\\n]*\\\\{\",\n\t                               \"\", \"\", \"{tenter=resourceBlock}\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\1 _isstring {\\n\"\n\t\t\"       /vresource\\n\"\n\t\t\"    } {\\n\"\n\t\t\"       /resource\\n\"\n\t\t\"    } ifelse \\\\2 true\\n\"\n\t\t\"    % kind:name type:string true\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockStart\",\n\t                               \"^class[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=classStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockStart\",\n\t                               \"^define[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=defineStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockStart\",\n\t                               \"^case[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=caseStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockStart\",\n\t                               \"^(if|elsif|else|unless)[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=ifStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockStart\",\n\t                               \"^node[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=nodeStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockStart\",\n\t                               \"^type[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=typeStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockStart\",\n\t                               \"^\\\\$\",\n\t                               \"\", \"\", \"{tenter=var}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHead\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHead\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHead\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHead\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=block,end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHead\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHeadPopAtLast\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHeadPopAtLast\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHeadPopAtLast\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=block,endWithPop}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHeadPopAtLast\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHeadPopAtLast\",\n\t                               \"^inherits[ \\t\\n]+(::[a-z][_a-zA-Z0-9:]*|[a-z][_a-zA-Z0-9:]*)[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    _scopetop {\\n\"\n\t\t\"        dup :kind /class eq {\\n\"\n\t\t\"           \\\\1 inherits:\\n\"\n\t\t\"        } {\\n\"\n\t\t\"           pop\\n\"\n\t\t\"        } ifelse\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"blockHeadPopAtLast\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^(@)?(::[a-zA-Z0-9:_]+|[a-zA-Z][a-zA-Z0-9:_]*)[ \\t\\n]*\\\\{\",\n\t                               \"\", \"\", \"{tenter=resourceBlock}\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\1 _isstring {\\n\"\n\t\t\"       /vresource\\n\"\n\t\t\"    } {\\n\"\n\t\t\"       /resource\\n\"\n\t\t\"    } ifelse \\\\2 true\\n\"\n\t\t\"    % kind:name type:string true\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^class[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=classStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^define[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=defineStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^case[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=caseStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^(if|elsif|else|unless)[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=ifStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^node[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=nodeStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^type[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=typeStart}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^\\\\$\",\n\t                               \"\", \"\", \"{tenter=var}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^<<?\\\\|\",\n\t                               \"\", \"\", \"{tenter=skipCollector}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^;?[ \\t\\n]*\\\\}\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^;\",\n\t                               \"\", \"\", \"{tjump=resourceBlock}{scope=pop}\"\n\t\t\"{{\\n\"\n\t\t\"    false\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^:\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=block}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"block\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"{tenter=separator}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"classStart\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"classStart\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"classStart\",\n\t                               \"^(::[a-z][_a-zA-Z0-9:]*|[a-z][_a-zA-Z0-9:]*)[ \\t\\n]*(\\\\(|\\\\{|inherits[ \\t\\n]+(::[a-z][_a-zA-Z0-9:]*|[a-z][_a-zA-Z0-9:]*))[ \\t\\n]*\",\n\t                               \"\\\\1\", \"c\", \"{scope=push}\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\3 _isstring {\\n\"\n\t\t\"        . exch inherits:\\n\"\n\t\t\"        /blockHead /endWithPop _tentercont\\n\"\n\t\t\"    } {\\n\"\n\t\t\"        \\\\2 0 get ?( eq {\\n\"\n\t\t\"            % for gathering signature\\n\"\n\t\t\"            mark ?(\\n\"\n\t\t\"            % {tenter=signature,blockHeadPopAtLast}\\n\"\n\t\t\"            /signature /blockHeadPopAtLast _tentercont\\n\"\n\t\t\"        } {\\n\"\n\t\t\"            @2 _advanceto\\n\"\n\t\t\"            /blockHead /endWithPop _tentercont\\n\"\n\t\t\"        } ifelse\\n\"\n\t\t\"    } ifelse\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBlock\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBlock\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"    { pop pop } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBlock\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=resourceName}{_advanceTo=0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBlock\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=resourceName}{_advanceTo=0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBlock\",\n\t                               \"^\\\\[\",\n\t                               \"\", \"\", \"{tenter=resourceArray}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBlock\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=block}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBlock\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBlock\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBlock\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"{tenter=resourceBody}{scope=push}{placeholder}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipLiteral\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipLiteral\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipBlock\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipBlock\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipBlock\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipBlock\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipBlock\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=skipBlock}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipBlock\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipBlock\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArray\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArray\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArray\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArray\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArray\",\n\t                               \"^\\\\[\",\n\t                               \"\", \"\", \"{tenter=skipArray}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArray\",\n\t                               \"^\\\\]\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArray\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArgs\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArgs\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArgs\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArgs\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArgs\",\n\t                               \"^\\\\(\",\n\t                               \"\", \"\", \"{tenter=skipArgs}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArgs\",\n\t                               \"^\\\\)\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipArgs\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipCollector\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipCollector\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipCollector\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipCollector\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipCollector\",\n\t                               \"^<<?\\\\|\",\n\t                               \"\", \"\", \"{tenter=skipCollector}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipCollector\",\n\t                               \"^\\\\|>>?\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipCollector\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"signature\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"signature\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"signature\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"signature\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"signature\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"signature\",\n\t                               \"^\\\\)\",\n\t                               \"\", \"\", \"{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"    %\\n\"\n\t\t\"    % fill signature\\n\"\n\t\t\"    %\\n\"\n\t\t\"    dup ?, eq { pop } if\\n\"\n\t\t\"    ?) _buildstring _scopetop {\\n\"\n\t\t\"        exch signature:\\n\"\n\t\t\"    } {\\n\"\n\t\t\"        % something wrong\\n\"\n\t\t\"        pop\\n\"\n\t\t\"    } ifelse\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"signature\",\n\t                               \"^\\\\$([a-zA-Z][_a-zA-Z0-9:]*)[ \\t]*([=,])[ \\t]*\",\n\t                               \"\\\\1\", \"p\", \"{scope=ref}\"\n\t\t\"{{\\n\"\n\t\t\"    % push the name of parameter for filling the signature field of definition\\n\"\n\t\t\"    \\\\2 0 get ?= eq {\\n\"\n\t\t\"       /skipDefaultValue _tenter\\n\"\n\t\t\"    } if\\n\"\n\t\t\"    ?$ \\\\1 ?,\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"signature\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipDefaultValue\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipDefaultValue\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipDefaultValue\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipDefaultValue\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipDefaultValue\",\n\t                               \"^\\\\[\",\n\t                               \"\", \"\", \"{tenter=skipArray}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipDefaultValue\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=skipBlock}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipDefaultValue\",\n\t                               \"^\\\\(\",\n\t                               \"\", \"\", \"{tenter=skipArgs}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipDefaultValue\",\n\t                               \"^,\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipDefaultValue\",\n\t                               \"^\\\\)\",\n\t                               \"\", \"\", \"{tleave}{_advanceTo=0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipDefaultValue\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"var\",\n\t                               \"^(::[a-zA-Z0-9_:]+|[a-zA-Z_][a-zA-Z0-9_:]*)[ \\t\\n]*=\",\n\t                               \"\\\\1\", \"v\", \"{tenter=varexpr,end}\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\1 0 get ?: eq not {\\n\"\n\t\t\"       . _scoperef\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"defineStart\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"defineStart\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"defineStart\",\n\t                               \"^([a-z][_a-zA-Z0-9:]*)[ \\n\\t]*([({])\",\n\t                               \"\\\\1\", \"d\", \"{scope=push}\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\2 0 get ?( eq {\\n\"\n\t\t\"       % for gathering signature\\n\"\n\t\t\"       mark ?(\\n\"\n\t\t\"       % {tenter=signature,blockHeadPopAtLast}\\n\"\n\t\t\"       /signature /blockHeadPopAtLast _tentercont\\n\"\n\t\t\"    } {\\n\"\n\t\t\"       /block /endWithPop _tentercont\\n\"\n\t\t\"    } ifelse\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseStart\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseStart\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseStart\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseStart\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=caseBlock}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseStart\",\n\t                               \"^}\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseStart\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ifStart\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ifStart\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ifStart\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ifStart\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ifStart\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ifStart\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=block,end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ifStart\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"nodeStart\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"nodeStart\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"nodeStart\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"nodeStart\",\n\t                               \"^'([^']+)'\",\n\t                               \"\\\\1\", \"n\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"nodeStart\",\n\t                               \"^\\\"([^\\\"]+)\\\"\",\n\t                               \"\\\\1\", \"n\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"nodeStart\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=block,end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"nodeStart\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"typeStart\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"typeStart\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"typeStart\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"typeStart\",\n\t                               \"^([a-zA-Z][a-zA-Z0-9]*::[a-zA-Z][a-zA-Z0-9]+)[ \\t\\n]*=[ \\t\\n]*\",\n\t                               \"\\\\1\", \"t\", \"{tenter=varexpr,end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"typeStart\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment_multiline\",\n\t                               \"^\\\\*/\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment_multiline\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment_oneline\",\n\t                               \"^\\n\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment_oneline\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceName\",\n\t                               \"^'([^']+)'|\\\"([^\\\"]+)\\\"\",\n\t                               \"\", \"\", \"{tenter=resourceBody,end}\"\n\t\t\"{{\\n\"\n\t\t\"    dup {\\n\"\n\t\t\"        1 index (typename) exch [ 3 1 roll ]\\n\"\n\t\t\"        % kind:name type:string true [ (typename) type:string ]\\n\"\n\t\t\"        <<\\n\"\n\t\t\"        4 index\\n\"\n\t\t\"        % kind:name type:string true [ (typename) type:string ] << kind:name\\n\"\n\t\t\"        1 exch dup 2 exch\\n\"\n\t\t\"        >>\\n\"\n\t\t\"        % kind:name type:string true [ (typename) type:string ] << 1 kind:name 2 kind:name >>\\n\"\n\t\t\"        trymaketag\\n\"\n\t\t\"        % kind:name type:string true [ (typename) type:string ] tag:int true %\\n\"\n\t\t\"        % kind:name type:string true [ (typename) type:string ] false\\n\"\n\t\t\"        {\\n\"\n\t\t\"            dup _scopepush\\n\"\n\t\t\"            exch typeref:\\n\"\n\t\t\"        } {\\n\"\n\t\t\"            pop\\n\"\n\t\t\"        } ifelse\\n\"\n\t\t\"    } {\\n\"\n\t\t\"        << 1 /resource 2 /resource >> trymaketag {\\n\"\n\t\t\"           _scopepush\\n\"\n\t\t\"        } if\\n\"\n\t\t\"    } ifelse\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceName\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{tquit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceNameInArray\",\n\t                               \"^'([^']+)'|\\\"([^\\\"]+)\\\"\",\n\t                               \"\", \"\", \"{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"    dup {\\n\"\n\t\t\"        % do the same as resourceName\\n\"\n\t\t\"        1 index (typename) exch [ 3 1 roll ]\\n\"\n\t\t\"        << 4 index 1 exch dup 2 exch >> trymaketag\\n\"\n\t\t\"        {\\n\"\n\t\t\"            dup _scoperef\\n\"\n\t\t\"            exch typeref:\\n\"\n\t\t\"        } {\\n\"\n\t\t\"            pop\\n\"\n\t\t\"        } ifelse\\n\"\n\t\t\"\\n\"\n\t\t\"    } {\\n\"\n\t\t\"        << 1 /resource 2 /resource >> trymaketag {\\n\"\n\t\t\"           _scoperef\\n\"\n\t\t\"        } if\\n\"\n\t\t\"    } ifelse\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceNameInArray\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{tquit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBody\",\n\t                               \"^[^/#{'\\\";}<]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBody\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBody\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBody\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}{_advanceTo=0start}{scope=pop}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBody\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=skipBlock}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBody\",\n\t                               \"^;\",\n\t                               \"\", \"\", \"{tleave}{scope=pop}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBody\",\n\t                               \"^<<?\\\\|\",\n\t                               \"\", \"\", \"{tenter=skipCollector}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBody\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBody\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceBody\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceArray\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceArray\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceArray\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceArray\",\n\t                               \"^['\\\"]\",\n\t                               \"\", \"\", \"{tenter=resourceNameInArray}{_advanceTo=0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceArray\",\n\t                               \"^\\\\]\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"resourceArray\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral,end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral,end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^\\\\[\",\n\t                               \"\", \"\", \"{tenter=skipArray,end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=skipBlock,end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^\\\\(\",\n\t                               \"\", \"\", \"{tenter=skipArgs,end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^\\\\$[a-zA-Z:][0-9a-zA-Z:]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^[0-9]+(\\\\.[0-9]+(e([+-][0-9]+)))?\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^[a-zA-Z0-9:][0-9a-zA-Z:]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^[ \\t]\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^\\n\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"varexpr\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseBlock\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseBlock\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseBlock\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseBlock\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseBlock\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseBlock\",\n\t                               \"^:\",\n\t                               \"\", \"\", \"{tenter=blockHead}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseBlock\",\n\t                               \"^}\",\n\t                               \"\", \"\", \"{tleave}{_advanceTo=0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"caseBlock\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* PuppetManifestParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"pp\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic scopeSeparator PuppetManifestClassSeparators [] = {\n\t\t{ KIND_GHOST_INDEX, \"::\" },\n\t};\n\n\tstatic kindDefinition PuppetManifestKindTable [] = {\n\t\t{\n\t\t  true, 'c', \"class\", \"classes\",\n\t\t  ATTACH_SEPARATORS(PuppetManifestClassSeparators),\n\t\t},\n\t\t{\n\t\t  true, 'd', \"definition\", \"definitions\",\n\t\t},\n\t\t{\n\t\t  true, 'n', \"node\", \"nodes\",\n\t\t},\n\t\t{\n\t\t  true, 'r', \"resource\", \"resources\",\n\t\t},\n\t\t{\n\t\t  true, 'v', \"variable\", \"variables\",\n\t\t},\n\t\t{\n\t\t  true, 'p', \"param\", \"parameters\",\n\t\t},\n\t\t{\n\t\t  true, 'V', \"vresource\", \"virtual resources\",\n\t\t},\n\t\t{\n\t\t  true, 't', \"type\", \"type aliases\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"PuppetManifest\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = PuppetManifestKindTable;\n\tdef->kindCount     = ARRAY_SIZE(PuppetManifestKindTable);\n\tdef->requestAutomaticFQTag = true;\n\tdef->defaultScopeSeparator = \"::\";\n\tdef->initialize    = initializePuppetManifestParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/puppetManifest.ctags",
    "content": "#\n# puppetManifest.ctags --- multitable regex parser for Puppet's manifest file\n#\n#  Copyright (c) 2017, Red Hat, Inc.\n#  Copyright (c) 2017, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n#\n# References:\n#\n# - https://github.com/puppetlabs/puppet-specifications/blob/master/language/intro.md\n# - https://docs.puppet.com/puppet/5.1/lang_visual_index.html\n#\n--langdef=PuppetManifest{_autoFQTag}\n--map-PuppetManifest=+.pp\n\n#\n# Kinds\n#\n--kinddef-PuppetManifest=c,class,classes\n--kinddef-PuppetManifest=d,definition,definitions\n--kinddef-PuppetManifest=n,node,nodes\n--kinddef-PuppetManifest=r,resource,resources\n--kinddef-PuppetManifest=v,variable,variables\n--kinddef-PuppetManifest=p,param,parameters\n--kinddef-PuppetManifest=V,vresource,virtual resources\n--kinddef-PuppetManifest=t,type,type aliases\n\n#\n# Separators\n#\n--_scopesep-PuppetManifest=/c:::\n--_scopesep-PuppetManifest=*/*:::\n\n#\n# Prelude\n#\n--_prelude-PuppetManifest={{\n    % spec:dict<num,kind> TRYMAKETAG tag:int true\n    % spec:dict<num,kind> TRYMAKETAG false\n    /trymaketag {\n        {\n            {\n                1 index _matchstr {\n                    % key value str\n                    3 -1 roll\n                    % value str key\n                    _matchloc\n                    % value str loc\n                    3 -1 roll exch\n                    % str value loc\n                    _tag _commit\n                    stop\n                } {\n                    pop pop\n                } ifelse\n            } forall\n         } stopped\n    } def\n}}\n\n#\n# Tables\n#\n--_tabledef-PuppetManifest=main\n--_tabledef-PuppetManifest=separator\n--_tabledef-PuppetManifest=any\n--_tabledef-PuppetManifest=ignoreWhiteSpace\n--_tabledef-PuppetManifest=end\n--_tabledef-PuppetManifest=endWithPop\n\n--_tabledef-PuppetManifest=ssliteral\n--_tabledef-PuppetManifest=dsliteral\n\n--_tabledef-PuppetManifest=comment\n\n--_tabledef-PuppetManifest=blockStart\n--_tabledef-PuppetManifest=blockHead\n--_tabledef-PuppetManifest=blockHeadPopAtLast\n--_tabledef-PuppetManifest=block\n\n--_tabledef-PuppetManifest=classStart\n#--_tabledef-PuppetManifest=resourceBlock{args=end}\n--_tabledef-PuppetManifest=resourceBlock\n\n--_tabledef-PuppetManifest=skipLiteral\n--_tabledef-PuppetManifest=skipBlock\n--_tabledef-PuppetManifest=skipArray\n--_tabledef-PuppetManifest=skipArgs\n--_tabledef-PuppetManifest=skipCollector\n\n--_tabledef-PuppetManifest=signature\n--_tabledef-PuppetManifest=skipDefaultValue\n\n--_tabledef-PuppetManifest=var\n\n--_tabledef-PuppetManifest=defineStart\n--_tabledef-PuppetManifest=caseStart\n--_tabledef-PuppetManifest=ifStart\n\n--_tabledef-PuppetManifest=nodeStart\n\n--_tabledef-PuppetManifest=typeStart\n\n#\n# Utilities\n#\n--_mtable-regex-PuppetManifest=separator/[a-zA-Z0-9]//\n--_mtable-regex-PuppetManifest=separator///{tleave}\n\n--_mtable-regex-PuppetManifest=any/.//\n--_mtable-regex-PuppetManifest=ignoreWhiteSpace/[ \\t\\n]+//\n--_mtable-regex-PuppetManifest=end///{tleave}\n--_mtable-regex-PuppetManifest=endWithPop///{tleave}{scope=pop}\n\n--_mtable-regex-PuppetManifest=ssliteral/[^']*'//{tleave}\n--_mtable-regex-PuppetManifest=ssliteral/[^']+//\n--_mtable-regex-PuppetManifest=dsliteral/[^\"]*\"//{tleave}\n--_mtable-regex-PuppetManifest=dsliteral/[^\"]+//\n\n#\n# comment\n#\n--_tabledef-PuppetManifest=comment_multiline\n--_tabledef-PuppetManifest=comment_oneline\n--_mtable-regex-PuppetManifest=comment/\\/\\*//{tenter=comment_multiline}\n--_mtable-regex-PuppetManifest=comment/\\#//{tenter=comment_oneline}\n--_mtable-regex-PuppetManifest=comment_multiline/\\*\\///{tleave}\n--_mtable-extend-PuppetManifest=comment_multiline+any\n--_mtable-regex-PuppetManifest=comment_oneline/\\n//{tleave}\n--_mtable-extend-PuppetManifest=comment_oneline+any\n\n#\n# skipLiteral\n#\n--_mtable-regex-PuppetManifest=skipLiteral/'//{tenter=ssliteral}\n--_mtable-regex-PuppetManifest=skipLiteral/\"//{tenter=dsliteral}\n\n#\n# skipBlock\n#\n--_mtable-extend-PuppetManifest=skipBlock+comment\n--_mtable-extend-PuppetManifest=skipBlock+skipLiteral\n--_mtable-regex-PuppetManifest=skipBlock/\\{//{tenter=skipBlock}\n--_mtable-regex-PuppetManifest=skipBlock/\\}//{tleave}\n--_mtable-extend-PuppetManifest=skipBlock+any\n\n#\n# skipArray\n#\n--_mtable-extend-PuppetManifest=skipArray+comment\n--_mtable-extend-PuppetManifest=skipArray+skipLiteral\n--_mtable-regex-PuppetManifest=skipArray/\\[//{tenter=skipArray}\n--_mtable-regex-PuppetManifest=skipArray/\\]//{tleave}\n--_mtable-extend-PuppetManifest=skipArray+any\n\n#\n# skipArgs\n#\n--_mtable-extend-PuppetManifest=skipArgs+comment\n--_mtable-extend-PuppetManifest=skipArgs+skipLiteral\n--_mtable-regex-PuppetManifest=skipArgs/\\(//{tenter=skipArgs}\n--_mtable-regex-PuppetManifest=skipArgs/\\)//{tleave}\n--_mtable-extend-PuppetManifest=skipArgs+any\n\n#\n# signature\n#\n--_mtable-extend-PuppetManifest=signature+comment\n--_mtable-extend-PuppetManifest=signature+skipLiteral\n--_mtable-extend-PuppetManifest=signature+ignoreWhiteSpace\n--_mtable-regex-PuppetManifest=signature/\\)//{tleave}{{\n    %\n    % fill signature\n    %\n    dup ?, eq { pop } if\n    ?) _buildstring _scopetop {\n        exch signature:\n    } {\n        % something wrong\n        pop\n    } ifelse\n}}\n--_mtable-regex-PuppetManifest=signature/\\$([a-zA-Z][_a-zA-Z0-9:]*)[ \\t]*([=,])[ \\t]*/\\1/p/{scope=ref}{{\n    % push the name of parameter for filling the signature field of definition\n    \\2 0 get ?= eq {\n       /skipDefaultValue _tenter\n    } if\n    ?$ \\1 ?,\n}}\n--_mtable-extend-PuppetManifest=signature+any\n\n#\n# skipDefaultValue\n#\n--_mtable-extend-PuppetManifest=skipDefaultValue+comment\n--_mtable-extend-PuppetManifest=skipDefaultValue+skipLiteral\n--_mtable-regex-PuppetManifest=skipDefaultValue/\\[//{tenter=skipArray}\n--_mtable-regex-PuppetManifest=skipDefaultValue/\\{//{tenter=skipBlock}\n--_mtable-regex-PuppetManifest=skipDefaultValue/\\(//{tenter=skipArgs}\n--_mtable-regex-PuppetManifest=skipDefaultValue/,//{tleave}\n--_mtable-regex-PuppetManifest=skipDefaultValue/\\)//{tleave}{_advanceTo=0start}\n--_mtable-extend-PuppetManifest=skipDefaultValue+any\n\n#\n# skipCollector\n#\n--_mtable-extend-PuppetManifest=skipCollector+comment\n--_mtable-extend-PuppetManifest=skipCollector+skipLiteral\n--_mtable-regex-PuppetManifest=skipCollector/<<?\\|//{tenter=skipCollector}\n--_mtable-regex-PuppetManifest=skipCollector/\\|>>?//{tleave}\n--_mtable-extend-PuppetManifest=skipCollector+any\n\n\n\n#\n# block\n#\n--_mtable-regex-PuppetManifest=blockStart/(@)?(::[a-zA-Z0-9:_]+|[a-zA-Z][a-zA-Z0-9:_]*)[ \\t\\n]*\\{//{tenter=resourceBlock}{{\n    \\1 _isstring {\n       /vresource\n    } {\n       /resource\n    } ifelse \\2 true\n    % kind:name type:string true\n}}\n--_mtable-regex-PuppetManifest=blockStart/class[ \\t\\n]+//{tenter=classStart}\n--_mtable-regex-PuppetManifest=blockStart/define[ \\t\\n]+//{tenter=defineStart}\n--_mtable-regex-PuppetManifest=blockStart/case[ \\t\\n]+//{tenter=caseStart}\n--_mtable-regex-PuppetManifest=blockStart/(if|elsif|else|unless)[ \\t\\n]+//{tenter=ifStart}\n--_mtable-regex-PuppetManifest=blockStart/node[ \\t\\n]+//{tenter=nodeStart}\n--_mtable-regex-PuppetManifest=blockStart/type[ \\t\\n]+//{tenter=typeStart}\n--_mtable-regex-PuppetManifest=blockStart/\\$//{tenter=var}\n\n\n--_mtable-extend-PuppetManifest=blockHead+comment\n--_mtable-extend-PuppetManifest=blockHead+ignoreWhiteSpace\n--_mtable-regex-PuppetManifest=blockHead/\\{//{tenter=block,end}\n--_mtable-extend-PuppetManifest=blockHead+any\n\n--_mtable-extend-PuppetManifest=blockHeadPopAtLast+comment\n--_mtable-regex-PuppetManifest=blockHeadPopAtLast/\\{//{tenter=block,endWithPop}\n--_mtable-extend-PuppetManifest=blockHeadPopAtLast+ignoreWhiteSpace\n--_mtable-regex-PuppetManifest=blockHeadPopAtLast/inherits[ \\t\\n]+(::[a-z][_a-zA-Z0-9:]*|[a-z][_a-zA-Z0-9:]*)[ \\t\\n]*//{{\n    _scopetop {\n        dup :kind /class eq {\n           \\1 inherits:\n        } {\n           pop\n        } ifelse\n    } if\n}}\n--_mtable-extend-PuppetManifest=blockHeadPopAtLast+any\n\n--_mtable-extend-PuppetManifest=block+ignoreWhiteSpace\n--_mtable-extend-PuppetManifest=block+blockStart\n--_mtable-regex-PuppetManifest=block/<<?\\|//{tenter=skipCollector}\n\n# Following stack manipulation for handling following input.\n# A {\n#     \"a\": b => c;\n#     \"d\": e => f;\n# }\n# B {\n#     \"g\": h => i;\n#     \"j\": k => k /* THIS COMMENT CANNOT BE IGNORED WELL */\n# }\n--_mtable-regex-PuppetManifest=block/;?[ \\t\\n]*\\}//{tleave}\n--_mtable-regex-PuppetManifest=block/;//{tjump=resourceBlock}{scope=pop}{{\n    false\n}}\n#--_mtable-regex-PuppetManifest=block/;//{tleave}{scope=pop}\n--_mtable-regex-PuppetManifest=block/://\n--_mtable-extend-PuppetManifest=block+comment\n--_mtable-extend-PuppetManifest=block+skipLiteral\n--_mtable-regex-PuppetManifest=block/\\{//{tenter=block}\n--_mtable-regex-PuppetManifest=block/.//{tenter=separator}\n\n#\n# main\n#\n--_mtable-extend-PuppetManifest=main+comment\n--_mtable-extend-PuppetManifest=main+ignoreWhiteSpace\n--_mtable-extend-PuppetManifest=main+skipLiteral\n--_mtable-regex-PuppetManifest=main/<<?\\|//{tenter=skipCollector}\n--_mtable-regex-PuppetManifest=main/\\$//{tenter=var}\n--_mtable-extend-PuppetManifest=main+blockStart\n--_mtable-regex-PuppetManifest=main/\\(//{tenter=skipArgs}\n--_mtable-regex-PuppetManifest=main/\\{//{tenter=skipBlock}\n--_mtable-regex-PuppetManifest=main/.//{tenter=separator}\n\n#\n# class\n--_mtable-extend-PuppetManifest=classStart+comment\n--_mtable-regex-PuppetManifest=classStart/(::[a-z][_a-zA-Z0-9:]*|[a-z][_a-zA-Z0-9:]*)[ \\t\\n]*(\\(|\\{|inherits[ \\t\\n]+(::[a-z][_a-zA-Z0-9:]*|[a-z][_a-zA-Z0-9:]*))[ \\t\\n]*/\\1/c/{scope=push}{{\n    \\3 _isstring {\n        . exch inherits:\n        /blockHead /endWithPop _tentercont\n    } {\n        \\2 0 get ?( eq {\n            % for gathering signature\n            mark ?(\n            % {tenter=signature,blockHeadPopAtLast}\n            /signature /blockHeadPopAtLast _tentercont\n        } {\n            @2 _advanceto\n            /blockHead /endWithPop _tentercont\n        } ifelse\n    } ifelse\n}}\n\n#\n# resource\n#\n--_tabledef-PuppetManifest=resourceName\n--_tabledef-PuppetManifest=resourceNameInArray\n--_tabledef-PuppetManifest=resourceBody\n--_tabledef-PuppetManifest=resourceArray\n--_tabledef-PuppetManifest=resourceCollector\n\n# resourceBlock expects data on optscript:\n#\n# false RESOURCEBLOCK -\n# kind:name type:string true RESOURCEBLOCK -\n#\n--_mtable-extend-PuppetManifest=resourceBlock+ignoreWhiteSpace\n--_mtable-regex-PuppetManifest=resourceBlock/\\}//{tleave}{{\n    { pop pop } if\n}}\n--_mtable-regex-PuppetManifest=resourceBlock/'//{tenter=resourceName}{_advanceTo=0start}\n--_mtable-regex-PuppetManifest=resourceBlock/\"//{tenter=resourceName}{_advanceTo=0start}\n--_mtable-regex-PuppetManifest=resourceBlock/\\[//{tenter=resourceArray}\n--_mtable-regex-PuppetManifest=resourceBlock/\\{//{tenter=block}\n--_mtable-extend-PuppetManifest=resourceBlock+comment\n--_mtable-regex-PuppetManifest=resourceBlock/.//{tenter=resourceBody}{scope=push}{placeholder}\n\n# resourceName expects data on optscript:\n#\n# false RESOURCENAME false\n# kind:name type:string true RESOURCENAME kind:name type:string true\n#\n--_mtable-regex-PuppetManifest=resourceName/'([^']+)'|\"([^\"]+)\"//{tenter=resourceBody,end}{{\n    dup {\n        1 index (typename) exch [ 3 1 roll ]\n        % kind:name type:string true [ (typename) type:string ]\n        <<\n        4 index\n        % kind:name type:string true [ (typename) type:string ] << kind:name\n        1 exch dup 2 exch\n        >>\n        % kind:name type:string true [ (typename) type:string ] << 1 kind:name 2 kind:name >>\n        trymaketag\n        % kind:name type:string true [ (typename) type:string ] tag:int true %\n        % kind:name type:string true [ (typename) type:string ] false\n        {\n            dup _scopepush\n            exch typeref:\n        } {\n            pop\n        } ifelse\n    } {\n        << 1 /resource 2 /resource >> trymaketag {\n           _scopepush\n        } if\n    } ifelse\n}}\n--_mtable-regex-PuppetManifest=resourceName///{tquit}\n\n# resourceNameInArray expects data on optscript:\n#\n# false RESOURCENAMEINARRAY false\n# kind:name type:string true RESOURCENAMEINARRAY kind:name type:string true\n#\n--_mtable-regex-PuppetManifest=resourceNameInArray/'([^']+)'|\"([^\"]+)\"///{tleave}{{\n    dup {\n        % do the same as resourceName\n        1 index (typename) exch [ 3 1 roll ]\n        << 4 index 1 exch dup 2 exch >> trymaketag\n        {\n            dup _scoperef\n            exch typeref:\n        } {\n            pop\n        } ifelse\n\n    } {\n        << 1 /resource 2 /resource >> trymaketag {\n           _scoperef\n        } if\n    } ifelse\n}}\n--_mtable-regex-PuppetManifest=resourceNameInArray////{tquit}\n\n# --_mtable-extend-PuppetManifest=resourceBody+ignoreWhiteSpace\n#\n# Next pattern is just for optimization.\n#\n--_mtable-regex-PuppetManifest=resourceBody/[^\\/#{'\";}<]+//\n--_mtable-regex-PuppetManifest=resourceBody/'//{tenter=ssliteral}\n--_mtable-regex-PuppetManifest=resourceBody/\"//{tenter=dsliteral}\n--_mtable-regex-PuppetManifest=resourceBody/\\}//{tleave}{_advanceTo=0start}{scope=pop}\n--_mtable-regex-PuppetManifest=resourceBody/\\{//{tenter=skipBlock}\n--_mtable-regex-PuppetManifest=resourceBody/;//{tleave}{scope=pop}\n--_mtable-regex-PuppetManifest=resourceBody/<<?\\|//{tenter=skipCollector}\n--_mtable-extend-PuppetManifest=resourceBody+comment\n--_mtable-extend-PuppetManifest=resourceBody+any\n\n--_mtable-extend-PuppetManifest=resourceArray+comment\n--_mtable-extend-PuppetManifest=resourceArray+ignoreWhiteSpace\n--_mtable-regex-PuppetManifest=resourceArray/['\"]//{tenter=resourceNameInArray}{_advanceTo=0start}\n--_mtable-regex-PuppetManifest=resourceArray/\\]//{tleave}\n--_mtable-extend-PuppetManifest=resourceArray+any\n\n#\n# var\n#\n--_tabledef-PuppetManifest=varexpr\n--_mtable-regex-PuppetManifest=var/(::[a-zA-Z0-9_:]+|[a-zA-Z_][a-zA-Z0-9_:]*)[ \\t\\n]*=/\\1/v/{tenter=varexpr,end}{{\n    \\1 0 get ?: eq not {\n       . _scoperef\n    } if\n}}\n\n--_mtable-extend-PuppetManifest=varexpr+comment\n--_mtable-regex-PuppetManifest=varexpr/'//{tenter=ssliteral,end}\n--_mtable-regex-PuppetManifest=varexpr/\"//{tenter=dsliteral,end}\n--_mtable-regex-PuppetManifest=varexpr/\\[//{tenter=skipArray,end}\n--_mtable-regex-PuppetManifest=varexpr/\\{//{tenter=skipBlock,end}\n--_mtable-regex-PuppetManifest=varexpr/\\(//{tenter=skipArgs,end}\n--_mtable-regex-PuppetManifest=varexpr/\\$[a-zA-Z:][0-9a-zA-Z:]*//\n--_mtable-regex-PuppetManifest=varexpr/[0-9]+(\\.[0-9]+(e([+-][0-9]+)))?//\n--_mtable-regex-PuppetManifest=varexpr/[a-zA-Z0-9:][0-9a-zA-Z:]*//\n--_mtable-regex-PuppetManifest=varexpr/[ \\t]//\n--_mtable-regex-PuppetManifest=varexpr/\\n//{tleave}\n--_mtable-extend-PuppetManifest=varexpr+any\n\n#\n# define\n#\n--_mtable-extend-PuppetManifest=defineStart+comment\n--_mtable-regex-PuppetManifest=defineStart/([a-z][_a-zA-Z0-9:]*)[ \\n\\t]*([({])/\\1/d/{scope=push}{{\n    \\2 0 get ?( eq {\n       % for gathering signature\n       mark ?(\n       % {tenter=signature,blockHeadPopAtLast}\n       /signature /blockHeadPopAtLast _tentercont\n    } {\n       /block /endWithPop _tentercont\n    } ifelse\n}}\n\n#\n# case\n#\n--_tabledef-PuppetManifest=caseBlock\n\n--_mtable-extend-PuppetManifest=caseStart+comment\n--_mtable-extend-PuppetManifest=caseStart+ignoreWhiteSpace\n--_mtable-regex-PuppetManifest=caseStart/\\{//{tenter=caseBlock}\n--_mtable-regex-PuppetManifest=caseStart/}//{tleave}\n--_mtable-extend-PuppetManifest=caseStart+any\n\n--_mtable-extend-PuppetManifest=caseBlock+comment\n--_mtable-extend-PuppetManifest=caseBlock+ignoreWhiteSpace\n--_mtable-extend-PuppetManifest=caseBlock+skipLiteral\n--_mtable-regex-PuppetManifest=caseBlock/://{tenter=blockHead}\n--_mtable-regex-PuppetManifest=caseBlock/}//{tleave}{_advanceTo=0start}\n--_mtable-extend-PuppetManifest=caseBlock+any\n\n#\n# if/elsif/else\n#\n--_mtable-extend-PuppetManifest=ifStart+comment\n--_mtable-extend-PuppetManifest=ifStart+ignoreWhiteSpace\n--_mtable-extend-PuppetManifest=ifStart+skipLiteral\n--_mtable-regex-PuppetManifest=ifStart/\\{//{tenter=block,end}\n--_mtable-extend-PuppetManifest=ifStart+any\n\n#\n# node\n#\n--_mtable-extend-PuppetManifest=nodeStart+comment\n--_mtable-extend-PuppetManifest=nodeStart+ignoreWhiteSpace\n--_mtable-regex-PuppetManifest=nodeStart/'([^']+)'/\\1/n/\n--_mtable-regex-PuppetManifest=nodeStart/\"([^\"]+)\"/\\1/n/\n--_mtable-regex-PuppetManifest=nodeStart/\\{///{tenter=block,end}\n--_mtable-extend-PuppetManifest=nodeStart+any\n\n#\n# type\n#\n--_mtable-extend-PuppetManifest=typeStart+comment\n--_mtable-extend-PuppetManifest=typeStart+ignoreWhiteSpace\n--_mtable-regex-PuppetManifest=typeStart/([a-zA-Z][a-zA-Z0-9]*::[a-zA-Z][a-zA-Z0-9]+)[ \\t\\n]*=[ \\t\\n]*/\\1/t/{tenter=varexpr,end}\n--_mtable-extend-PuppetManifest=typeStart+any\n"
  },
  {
    "path": "optlib/qemuhx.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/qemuhx.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n#include \"selectors.h\"\n\n\nstatic void initializeQemuHXParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"toplevel\");\n\taddLanguageRegexTable (language, \"skiplines\");\n\taddLanguageRegexTable (language, \"qmp\");\n\taddLanguageRegexTable (language, \"texi\");\n\taddLanguageRegexTable (language, \"rst\");\n\taddLanguageRegexTable (language, \"cmd\");\n\taddLanguageRegexTable (language, \"cmd0\");\n\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^HXCOMM[^\\n]*[\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^SQMP[[:space:]]+\",\n\t                               \"\", \"\", \"{tenter=qmp}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^STEXI[\\n]*\",\n\t                               \"\", \"\", \"{tenter=texi}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^SRST[^\\n]*[\\n]*\",\n\t                               \"\", \"\", \"{tenter=rst}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[ \\t]*DEF\\\\(\\\"([^\\\"\\n]+)\\\"[^\\n]*[\\n]\",\n\t                               \"\\\\1\", \"c\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[ \\t]*\\\\{[ \\t]*[\\n]+\",\n\t                               \"\", \"\", \"{tenter=cmd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[^\\n]+[\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skiplines\",\n\t                               \"^[^\\n]+[\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skiplines\",\n\t                               \"^[\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skiplines\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"qmp\",\n\t                               \"^EQMP[^\\n]*[\\n]*\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"qmp\",\n\t                               \"^([-a-z_0-9A-Z]+)[[:space:]]---[^\\n]*[\\n]\",\n\t                               \"\\\\1\", \"q\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    /QemuHX.funcmap _extraenabled {\\n\"\n\t\t\"        % make an extra tag for \\\"n-a-m-e\\\":\\n\"\n\t\t\"        % make string: qmp_n-a-m-e\\n\"\n\t\t\"        mark (qmp_) . :name _buildstring\\n\"\n\t\t\"        % replace - with _: qmp_n_a_m_e\\n\"\n\t\t\"        dup (-_) _tr!\\n\"\n\t\t\"        . :kind . _tagloc _tag\\n\"\n\t\t\"        _commit\\n\"\n\t\t\"        /QemuHX.funcmap _markextra\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"qmp\",\n\t                               \"^[^\\n]+[\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"qmp\",\n\t                               \"^[\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"qmp\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"texi\",\n\t                               \"^ETEXI[\\n]*\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"texi\",\n\t                               \"^@item[[:space:]]{1,}([-.a-z_0-9A-Z]{1,})[^\\n]*[\\n]*\",\n\t                               \"\\\\1\", \"i\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"texi\",\n\t                               \"^[^\\n]+[\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"texi\",\n\t                               \"^[\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"texi\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rst\",\n\t                               \"^ERST[^\\n]*[\\n]*\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rst\",\n\t                               \"^[^\\n]+[\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rst\",\n\t                               \"^[\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rst\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd\",\n\t                               \"^[ \\t]*(SQMP)[\\n]*\",\n\t                               \"\", \"\", \"{tleave}{_advanceTo=1start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd\",\n\t                               \"^[ \\t]*(STEXI)[\\n]*\",\n\t                               \"\", \"\", \"{tleave}{_advanceTo=1start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd\",\n\t                               \"^[ \\t]*(SRST)[^\\n]*[\\n]*\",\n\t                               \"\", \"\", \"{tleave}{_advanceTo=1start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd\",\n\t                               \"^[ \\t]*\\\\}[ \\t]*,[ \\t]*[\\n]*\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd\",\n\t                               \"^[ \\t]*DEF\\\\(\\\"([^\\\"\\n]+)\\\"[^\\n]*[\\n]\",\n\t                               \"\\\\1\", \"c\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd\",\n\t                               \"^[ \\t]*\\\\.name[ \\t]*=[ \\t]*\\\"\",\n\t                               \"\", \"\", \"{tenter=cmd0}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd\",\n\t                               \"^[^\\n]+[\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd\",\n\t                               \"^[\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd0\",\n\t                               \"^([^|\\n]+)\\\\|\",\n\t                               \"\\\\1\", \"c\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd0\",\n\t                               \"^([^\\\"\\n]+)\\\"[^\\n]*[\\n]\",\n\t                               \"\\\\1\", \"c\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd0\",\n\t                               \"^[^\\n]+[\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd0\",\n\t                               \"^[\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cmd0\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* QemuHXParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"hx\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition QemuHXKindTable [] = {\n\t\t{\n\t\t  true, 'q', \"qmp\", \"QEMU Management Protocol dispatch table entries\",\n\t\t},\n\t\t{\n\t\t  true, 'i', \"infoitem\", \"item in texinfo doc\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"commands\", \"name member in HMPCommand struct\",\n\t\t  .version = 1,\n\t\t},\n\t};\n\tstatic xtagDefinition QemuHXXtagTable [] = {\n\t\t{\n\t\t  .enabled     = true,\n\t\t  .name        = \"funcmap\",\n\t\t  .description = \"Include mapping SQMP to C function name\",\n\t\t},\n\t};\n\tstatic selectLanguage selectors[] = { selectHaxeOrQemuHXByCommentMarker, NULL };\n\n\tparserDefinition* const def = parserNew (\"QemuHX\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->selectLanguage= selectors;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = QemuHXKindTable;\n\tdef->kindCount     = ARRAY_SIZE(QemuHXKindTable);\n\tdef->xtagTable     = QemuHXXtagTable;\n\tdef->xtagCount     = ARRAY_SIZE(QemuHXXtagTable);\n\tdef->initialize    = initializeQemuHXParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/qemuhx.ctags",
    "content": "#\n#  Copyright (c) 2017, 2021, Red Hat, Inc.\n#  Copyright (c) 2017, 2021, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n#\n# `hxtool' is a tool used in QEMU build process.\n# It converts an input file to both a C header file code and Texinfo document.\n#\n# `.hx' is the suffix for the tool.\n#\n# This optlib is a testbed for --_extradef option and `extra' regex long flag.\n# This optlib is a testbed for optscript.\n#\n\n--langdef=QemuHX\n--kinddef-QemuHX=q,qmp,QEMU Management Protocol dispatch table entries\n--kinddef-QemuHX=i,infoitem,item in texinfo doc\n--kinddef-QemuHX=c,commands,name member in HMPCommand struct{version=1}\n\n--map-QemuHX=+.hx\n--__selector-QemuHX=selectHaxeOrQemuHXByCommentMarker\n--_extradef-QemuHX=funcmap,Include mapping SQMP to C function name\n--extras-QemuHX=+{funcmap}\n\n--_tabledef-QemuHX=toplevel\n--_tabledef-QemuHX=skiplines\n\n--_tabledef-QemuHX=qmp\n--_tabledef-QemuHX=texi\n--_tabledef-QemuHX=rst\n--_tabledef-QemuHX=cmd\n--_tabledef-QemuHX=cmd0\n\n--_mtable-regex-QemuHX=skiplines/[^\\n]+[\\n]*//\n--_mtable-regex-QemuHX=skiplines/[\\n]+//\n--_mtable-regex-QemuHX=skiplines/.//\n\n--_mtable-regex-QemuHX=toplevel/HXCOMM[^\\n]*[\\n]*//\n--_mtable-regex-QemuHX=toplevel/SQMP[[:space:]]+//{tenter=qmp}\n--_mtable-regex-QemuHX=toplevel/STEXI[\\n]*//{tenter=texi}\n--_mtable-regex-QemuHX=toplevel/SRST[^\\n]*[\\n]*//{tenter=rst}\n--_mtable-regex-QemuHX=toplevel/[ \\t]*DEF\\(\"([^\"\\n]+)\"[^\\n]*[\\n]/\\1/c/\n--_mtable-regex-QemuHX=toplevel/[ \\t]*\\{[ \\t]*[\\n]+//{tenter=cmd}\n--_mtable-extend-QemuHX=toplevel+skiplines\n\n--_mtable-regex-QemuHX=qmp/EQMP[^\\n]*[\\n]*//{tleave}\n--_mtable-regex-QemuHX=qmp/([-a-z_0-9A-Z]+)[[:space:]]---[^\\n]*[\\n]/\\1/q/{{\n    /QemuHX.funcmap _extraenabled {\n        % make an extra tag for \"n-a-m-e\":\n        % make string: qmp_n-a-m-e\n        mark (qmp_) . :name _buildstring\n        % replace - with _: qmp_n_a_m_e\n        dup (-_) _tr!\n        . :kind . _tagloc _tag\n        _commit\n        /QemuHX.funcmap _markextra\n    } if\n}}\n--_mtable-extend-QemuHX=qmp+skiplines\n\n--_mtable-regex-QemuHX=texi/ETEXI[\\n]*//{tleave}\n--_mtable-regex-QemuHX=texi/@item[[:space:]]{1,}([-.a-z_0-9A-Z]{1,})[^\\n]*[\\n]*/\\1/i/\n--_mtable-extend-QemuHX=texi+skiplines\n\n--_mtable-regex-QemuHX=rst/ERST[^\\n]*[\\n]*//{tleave}\n--_mtable-extend-QemuHX=rst+skiplines\n\n--_mtable-regex-QemuHX=cmd/[ \\t]*(SQMP)[\\n]*//{tleave}{_advanceTo=1start}\n--_mtable-regex-QemuHX=cmd/[ \\t]*(STEXI)[\\n]*//{tleave}{_advanceTo=1start}\n--_mtable-regex-QemuHX=cmd/[ \\t]*(SRST)[^\\n]*[\\n]*//{tleave}{_advanceTo=1start}\n--_mtable-regex-QemuHX=cmd/[ \\t]*\\}[ \\t]*,[ \\t]*[\\n]*//{tleave}\n--_mtable-regex-QemuHX=cmd/[ \\t]*DEF\\(\"([^\"\\n]+)\"[^\\n]*[\\n]/\\1/c/\n--_mtable-regex-QemuHX=cmd/[ \\t]*\\.name[ \\t]*=[ \\t]*\"//{tenter=cmd0}\n--_mtable-extend-QemuHX=cmd+skiplines\n\n--_mtable-regex-QemuHX=cmd0/([^|\\n]+)\\|/\\1/c/\n--_mtable-regex-QemuHX=cmd0/([^\"\\n]+)\"[^\\n]*[\\n]/\\1/c/{tleave}\n--_mtable-extend-QemuHX=cmd0+skiplines\n"
  },
  {
    "path": "optlib/rdoc.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/rdoc.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\ntypedef enum {\n\tK_L1HEADER,\n\tK_L2HEADER,\n\tK_L3HEADER,\n\tK_L4HEADER,\n\tK_L5HEADER,\n\tK_L6HEADER,\n} RDocKind;\n\n\nstatic void initializeRDocParser (const langType language CTAGS_ATTR_UNUSED)\n{\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE,\n\t\t\"{{    /kindTable [\\n\"\n\t\t\"        /L1Header /L2Header /L3Header /L4Header /L5Header /L6Header\\n\"\n\t\t\"    ] def\\n\"\n\t\t\"\\n\"\n\t\t\"    /depthForCork {\\n\"\n\t\t\"        :kind kindTable exch _aindex pop\\n\"\n\t\t\"    } def\\n\"\n\t\t\"    /depthForStr {\\n\"\n\t\t\"        length 1 sub\\n\"\n\t\t\"    } def\\n\"\n\t\t\"\\n\"\n\t\t\"    % endline:int goal:int scopePopUpTo -\\n\"\n\t\t\"    /scopePopUpTo\\n\"\n\t\t\"    {\\n\"\n\t\t\"        {\\n\"\n\t\t\"            _scopetop {\\n\"\n\t\t\"                dup\\n\"\n\t\t\"                % endline goal scope scope\\n\"\n\t\t\"                depthForCork 2 index depthForStr ge {\\n\"\n\t\t\"                    % endline goal scope\\n\"\n\t\t\"                    2 index end:\\n\"\n\t\t\"                    _scopepop\\n\"\n\t\t\"                } {\\n\"\n\t\t\"                    pop\\n\"\n\t\t\"                    exit\\n\"\n\t\t\"                } ifelse\\n\"\n\t\t\"            } {\\n\"\n\t\t\"                exit\\n\"\n\t\t\"            } ifelse\\n\"\n\t\t\"        } loop\\n\"\n\t\t\"        pop\\n\"\n\t\t\"        pop\\n\"\n\t\t\"    } def\\n\"\n\t\t\"}}\");\n}\n\nextern parserDefinition* RDocParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"rdoc\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition RDocKindTable [] = {\n\t\t{\n\t\t  true, 'h', \"L1Header\", \" Level 1 headers\",\n\t\t},\n\t\t{\n\t\t  true, 'i', \"L2Header\", \" Level 2 headers\",\n\t\t},\n\t\t{\n\t\t  true, 'j', \"L3Header\", \" Level 3 headers\",\n\t\t},\n\t\t{\n\t\t  true, 'k', \"L4Header\", \" Level 4 headers\",\n\t\t},\n\t\t{\n\t\t  true, 'l', \"L5Header\", \" Level 5 headers\",\n\t\t},\n\t\t{\n\t\t  true, 'm', \"L6Header\", \" Level 6 headers\",\n\t\t},\n\t};\n\tstatic tagRegexTable RDocTagRegexTable [] = {\n\t\t{\"^(?:#[ \\t])*(={1,6})[ \\t]*([^=].*)[ \\t]*$\", \"\",\n\t\t\"\", \"{pcre2}\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\1 length kindTable length le {\\n\"\n\t\t\"        \\\\2\\n\"\n\t\t\"        kindTable \\\\1 length 1 sub get\\n\"\n\t\t\"        @2\\n\"\n\t\t\"        _tag _commit\\n\"\n\t\t\"        dup :line 1 sub \\\\1 scopePopUpTo\\n\"\n\t\t\"        _scopetop {\\n\"\n\t\t\"            1 index exch scope: _scopepush\\n\"\n\t\t\"        } {\\n\"\n\t\t\"            _scopepush\\n\"\n\t\t\"        } ifelse\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL, false},\n\t};\n\n\n\tparserDefinition* const def = parserNew (\"RDoc\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = RDocKindTable;\n\tdef->kindCount     = ARRAY_SIZE(RDocKindTable);\n\tdef->tagRegexTable = RDocTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(RDocTagRegexTable);\n\tdef->defaultScopeSeparator = \"\\\"\\\"\";\n\tdef->initialize    = initializeRDocParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/rdoc.ctags",
    "content": "#\n#  Copyright (c) 2022, Red Hat, Inc.\n#  Copyright (c) 2022, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n# This parser extracts headers written in the RDoc Markup explained in\n# https://ruby.github.io/rdoc/RDoc/Markup.html#class-RDoc::Markup-label-RDoc+Markup+Reference\n#\n--langdef=RDoc\n--map-RDoc=+.rdoc\n\n--kinddef-RDoc=h,L1Header, Level 1 headers\n--kinddef-RDoc=i,L2Header, Level 2 headers\n--kinddef-RDoc=j,L3Header, Level 3 headers\n--kinddef-RDoc=k,L4Header, Level 4 headers\n--kinddef-RDoc=l,L5Header, Level 5 headers\n--kinddef-RDoc=m,L6Header, Level 6 headers\n\n# Separator definitions must come after kind definitions.\n# This is the limitation of optlib2c.\n--_scopesep-RDoc=*/*:\"\"\n\n--_prelude-RDoc={{\n    /kindTable [\n        /L1Header /L2Header /L3Header /L4Header /L5Header /L6Header\n    ] def\n\n    /depthForCork {\n        :kind kindTable exch _aindex pop\n    } def\n    /depthForStr {\n        length 1 sub\n    } def\n\n    % endline:int goal:int scopePopUpTo -\n    /scopePopUpTo\n    {\n        {\n            _scopetop {\n                dup\n                % endline goal scope scope\n                depthForCork 2 index depthForStr ge {\n                    % endline goal scope\n                    2 index end:\n                    _scopepop\n                } {\n                    pop\n                    exit\n                } ifelse\n            } {\n                exit\n            } ifelse\n        } loop\n        pop\n        pop\n    } def\n}}\n\n--regex-RDoc=/^(?:#[ \\t])*(={1,6})[ \\t]*([^=].*)[ \\t]*$//{pcre2}{{\n    \\1 length kindTable length le {\n        \\2\n        kindTable \\1 length 1 sub get\n        @2\n        _tag _commit\n        dup :line 1 sub \\1 scopePopUpTo\n        _scopetop {\n            1 index exch scope: _scopepush\n        } {\n            _scopepush\n        } ifelse\n    } if\n}}\n"
  },
  {
    "path": "optlib/rpmMacros.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/rpmMacros.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeRpmMacrosParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"contline\");\n\taddLanguageRegexTable (language, \"mbody\");\n\taddLanguageRegexTable (language, \"mbody0\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^%([_a-zA-Z0-9]+)(\\\\([^)]*\\\\))*[^{\\n\\\\\\\\]*([\\n]|[\\\\\\\\][\\n]|[{]|[\\\\\\\\])\",\n\t                               \"\\\\1\", \"m\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\2 false ne {\\n\"\n\t\t\"       . \\\\2 signature:\\n\"\n\t\t\"    } if\\n\"\n\t\t\"    \\\\3 ({) eq {\\n\"\n\t\t\"        .\\n\"\n\t\t\"        /mbody _tenter\\n\"\n\t\t\"    } if\\n\"\n\t\t\"    \\\\3 (\\\\\\\\\\\\n) eq {\\n\"\n\t\t\"        .\\n\"\n\t\t\"        /contline _tenter\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^[\\n]\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"contline\",\n\t                               \"^(\\n)\",\n\t                               \"\", \"\", \"{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"   @1 end:\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"contline\",\n\t                               \"^[^\\n]*([^\\n])\\n?\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    \\\\1 (\\\\\\\\) eq not {\\n\"\n\t\t\"       1@ end:\\n\"\n\t\t\"       _tleave\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mbody\",\n\t                               \"^([^\\\\\\\\{}#]+)\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mbody\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mbody\",\n\t                               \"^([{])\",\n\t                               \"\", \"\", \"{tenter=mbody0}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mbody\",\n\t                               \"^([}])\",\n\t                               \"\", \"\", \"{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"    dup :line @1 _matchloc2line eq {\\n\"\n\t\t\"        pop\\n\"\n\t\t\"    } {\\n\"\n\t\t\"        @1 end:\\n\"\n\t\t\"    } ifelse\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mbody\",\n\t                               \"^\\\\\\\\.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mbody0\",\n\t                               \"^[^\\\\\\\\{}#]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mbody0\",\n\t                               \"^[{]\",\n\t                               \"\", \"\", \"{tenter=mbody0}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mbody0\",\n\t                               \"^#\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mbody0\",\n\t                               \"^\\\\\\\\.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"mbody0\",\n\t                               \"^([}])\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n}\n\nextern parserDefinition* RpmMacrosParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic const struct rExprSrc rexprs [] = {\n\t\t{\n\t\t  .expr = \"(.*/)?macros\\\\.d/macros\\\\.([^/]+)$\",\n\t\t  .iCase = false,\n\t\t},\n\t\tREXPR_LAST_ENTRY\n\t};\n\n\tstatic kindDefinition RpmMacrosKindTable [] = {\n\t\t{\n\t\t  true, 'm', \"macro\", \"macros\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"RpmMacros\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->rexprs        = rexprs;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = RpmMacrosKindTable;\n\tdef->kindCount     = ARRAY_SIZE(RpmMacrosKindTable);\n\tdef->initialize    = initializeRpmMacrosParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/rpmMacros.ctags",
    "content": "#\n#  rpmMacros.ctags --- multitable regex parser for /usr/lib/rpm/macros files\n#\n#  Copyright (c) 2021 Masatake YAMATO\n#  Copyright (c) 2021 Red Hat, Inc.\n#\n#  This source code is released for free distribution under the terms of the\n#  GNU General Public License version 2 or (at your option) any later version.\n#\n# References:\n#\n# - https://rpm.org/user_doc/macros.html\n#\n# TODO:\n#\n# - Run Lua parser as a subparser\n#\n--langdef=RpmMacros\n\n--map-RpmMacros=+%(.*/)?macros\\.d/macros\\.([^/]+)$%\n\n--kinddef-RpmMacros=m,macro,macros\n\n--_tabledef-RpmMacros=main\n--_tabledef-RpmMacros=comment\n--_tabledef-RpmMacros=contline\n--_tabledef-RpmMacros=mbody\n--_tabledef-RpmMacros=mbody0\n\n--_mtable-regex-RpmMacros=comment/[^\\n]+//\n--_mtable-regex-RpmMacros=comment/[\\n]//{tleave}\n\n--_mtable-regex-RpmMacros=mbody0/[^\\\\{}#]+//\n--_mtable-regex-RpmMacros=mbody0/[{]//{tenter=mbody0}\n--_mtable-regex-RpmMacros=mbody0/#//{tenter=comment}\n--_mtable-regex-RpmMacros=mbody0/\\\\.//\n--_mtable-regex-RpmMacros=mbody0/([}])//{tleave}\n\n--_mtable-regex-RpmMacros=mbody/([^\\\\{}#]+)//\n--_mtable-regex-RpmMacros=mbody/#//{tenter=comment}\n--_mtable-regex-RpmMacros=mbody/([{])//{tenter=mbody0}\n--_mtable-regex-RpmMacros=mbody/([}])//{tleave}{{\n    dup :line @1 _matchloc2line eq {\n        pop\n    } {\n        @1 end:\n    } ifelse\n}}\n--_mtable-regex-RpmMacros=mbody/\\\\.//\n\n--_mtable-regex-RpmMacros=main/#//{tenter=comment}\n--_mtable-regex-RpmMacros=main/%([_a-zA-Z0-9]+)(\\([^)]*\\))*[^{\\n\\\\]*([\\n]|[\\\\][\\n]|[{]|[\\\\])/\\1/m/{{\n    \\2 false ne {\n       . \\2 signature:\n    } if\n    \\3 ({) eq {\n        .\n        /mbody _tenter\n    } if\n    \\3 (\\\\\\n) eq {\n        .\n        /contline _tenter\n    } if\n}}\n--_mtable-regex-RpmMacros=main/.//\n\n--_mtable-regex-RpmMacros=contline/(\\n)//{tleave}{{\n   @1 end:\n}}\n--_mtable-regex-RpmMacros=contline/^[^\\n]*([^\\n])\\n?///{{\n    \\1 (\\\\) eq not {\n       1@ end:\n       _tleave\n    } if\n}}\n"
  },
  {
    "path": "optlib/scdoc.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/scdoc.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\ntypedef enum {\n\tK_TITLE,\n\tK_SECTION,\n\tK_SUBSECTION,\n} ScdocKind;\n\n\nstatic void initializeScdocParser (const langType language)\n{\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_SEQUEL,\n\t\t\"{{    clear\\n\"\n\t\t\"}}\");\n\n\taddLanguageRegexTable (language, \"init\");\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"section\");\n\taddLanguageRegexTable (language, \"fini\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"skipline\");\n\n\taddLanguageTagMultiTableRegex (language, \"init\",\n\t                               \"^;([^\\n]*[\\n]|[^\\n]+)\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"init\",\n\t                               \"^([^\\\\( ]+)\\\\([^\\n]*[\\n]?\",\n\t                               \"\\\\1\", \"t\", \"{scope=push}{tenter=main}\"\n\t\t\"{{\\n\"\n\t\t\"   .\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"init\",\n\t                               \"^[^\\n]*\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"init\",\n\t                               \"^[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^##([^\\n]*\\n|[^\\n]+)\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^#[ \\t]*([^\\n]+)[ ]*[\\n]?\",\n\t                               \"\\\\1\", \"s\", \"{scope=push}{tenter=section}\"\n\t\t\"{{\\n\"\n\t\t\"   count 2 eq { @1 _matchloc2line 1 sub end: } if\\n\"\n\t\t\"   .\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^\\n]*\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^()\",\n\t                               \"\", \"\", \"{scope=pop}{_advanceTo=0start}{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^##[ \\t]*([^\\n]+)[ ]*[\\n]?\",\n\t                               \"\\\\1\", \"S\", \"{scope=ref}\"\n\t\t\"{{\\n\"\n\t\t\"   count 3 eq { @1 _matchloc2line 1 sub end: } if\\n\"\n\t\t\"   .\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^#[ \\t]*([^\\n]+)[ ]*[\\n]?\",\n\t                               \"\", \"\", \"{scope=pop}{_advanceTo=0start}{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"   count 3 eq { @1 _matchloc2line 1 sub end: } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^[^\\n]*\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"section\",\n\t                               \"^()\",\n\t                               \"\", \"\", \"{scope=pop}{_advanceTo=0start}{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"   count 3 eq { @1 _matchloc2line end: } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^;([^\\n]*[\\n]|[^\\n]+)\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipline\",\n\t                               \"^[^\\n]*\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipline\",\n\t                               \"^[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* ScdocParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"scd\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition ScdocKindTable [] = {\n\t\t{\n\t\t  true, 't', \"title\", \"titles\",\n\t\t},\n\t\t{\n\t\t  true, 's', \"section\", \"sections\",\n\t\t},\n\t\t{\n\t\t  true, 'S', \"subsection\", \"sub sections\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"Scdoc\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = ScdocKindTable;\n\tdef->kindCount     = ARRAY_SIZE(ScdocKindTable);\n\tdef->defaultScopeSeparator = \"\\\"\\\"\";\n\tdef->initialize    = initializeScdocParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/scdoc.ctags",
    "content": "#\n#  Copyright (c) 2025, Red Hat, Inc.\n#  Copyright (c) 2025, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n# Reference:\n#  https://git.sr.ht/~sircmpwn/scdoc\n#  https://git.sr.ht/~sircmpwn/scdoc/tree/master/item/scdoc.5.scd\n#\n--langdef=Scdoc\n--map-Scdoc=+.scd\n\n--kinddef-Scdoc=t,title,titles\n--kinddef-Scdoc=s,section,sections\n--kinddef-Scdoc=S,subsection,sub sections\n\n--_scopesep-Scdoc=*/*:\"\"\n\n--_tabledef-Scdoc=init\n--_tabledef-Scdoc=main\n--_tabledef-Scdoc=section\n--_tabledef-Scdoc=fini\n--_tabledef-Scdoc=comment\n--_tabledef-Scdoc=skipline\n\n--_sequel-Scdoc={{\n    clear\n}}\n\n#\n# comment\n#\n--_mtable-regex-Scdoc=comment/;([^\\n]*[\\n]|[^\\n]+)//\n\n#\n# skipline\n#\n--_mtable-regex-Scdoc=skipline/[^\\n]*\\n//\n--_mtable-regex-Scdoc=skipline/[^\\n]+//\n\n#\n# init\n#\n--_mtable-extend-Scdoc=init+comment\n--_mtable-regex-Scdoc=init/([^\\( ]+)\\([^\\n]*[\\n]?/\\1/t/{scope=push}{tenter=main}{{\n   .\n}}\n--_mtable-extend-Scdoc=init+skipline\n\n#\n# main\n#\n--_mtable-regex-Scdoc=main/##([^\\n]*\\n|[^\\n]+)//\n--_mtable-regex-Scdoc=main/#[ \\t]*([^\\n]+)[ ]*[\\n]?/\\1/s/{scope=push}{tenter=section}{{\n   count 2 eq { @1 _matchloc2line 1 sub end: } if\n   .\n}}\n--_mtable-extend-Scdoc=main+skipline\n# EOF\n--_mtable-regex-Scdoc=main/()//{scope=pop}{_advanceTo=0start}{tleave}\n\n#\n# section\n#\n--_mtable-regex-Scdoc=section/##[ \\t]*([^\\n]+)[ ]*[\\n]?/\\1/S/{scope=ref}{{\n   count 3 eq { @1 _matchloc2line 1 sub end: } if\n   .\n}}\n--_mtable-regex-Scdoc=section/#[ \\t]*([^\\n]+)[ ]*[\\n]?//{scope=pop}{_advanceTo=0start}{tleave}{{\n   count 3 eq { @1 _matchloc2line 1 sub end: } if\n}}\n--_mtable-extend-Scdoc=section+skipline\n# EOF\n--_mtable-regex-Scdoc=section/()//{scope=pop}{_advanceTo=0start}{tleave}{{\n   count 3 eq { @1 _matchloc2line end: } if\n}}\n"
  },
  {
    "path": "optlib/scss.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/scss.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeSCSSParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"toplevel\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"interp\");\n\taddLanguageRegexTable (language, \"args\");\n\taddLanguageRegexTable (language, \"map\");\n\taddLanguageRegexTable (language, \"strs\");\n\taddLanguageRegexTable (language, \"strd\");\n\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^//[^\\n]*\\n?\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^#\\\\{\",\n\t                               \"\", \"\", \"{tenter=interp}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=strs}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=strd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[ \\t]([A-Za-z0-9_-]+)[ \\t]*:[^\\n]*\\n?\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^@mixin[ \\t]+([A-Za-z0-9_-]+)\",\n\t                               \"\\\\1\", \"m\", \"{tenter=args}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^@function[ \\t]+([A-Za-z0-9_-]+)\",\n\t                               \"\\\\1\", \"f\", \"{tenter=args}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^@each[ \\t]+\\\\$([A-Za-z0-9_-]+)[ \\t]in[ \\t]+\",\n\t                               \"\\\\1\", \"v\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^@for[ \\t]+\\\\$([A-Za-z0-9_-]+)[ \\t]from[ \\t]+.*[ \\t]+(to|through)[ \\t]+[^{]+\",\n\t                               \"\\\\1\", \"v\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^@use[ \\t]+[\\\"']([^\\\"']+)[\\\"']([ \\t]+as[ \\t]+([A-Za-z0-9_-]+|\\\\*))?\",\n\t                               \"\\\\1\", \"M\", \"{_role=used}\"\n\t\t\"{{\\n\"\n\t\t\"   \\\\2 false eq {\\n\"\n\t\t\"      \\\\1 (/) _strrstr {\\n\"\n\t\t\"         % Extract the last component in the module name:\\n\"\n\t\t\"         % module-name offset\\n\"\n\t\t\"         1 add dup \\\\1 length exch sub\\n\"\n\t\t\"         % module-name offset' count\\n\"\n\t\t\"         0 string\\n\"\n\t\t\"         % module-name offset' count namespace-string\\n\"\n\t\t\"         _copyinterval\\n\"\n\t\t\"         dup length 0 gt {\\n\"\n\t\t\"            /namespace @1 _tag _commit \\\\1 SCSS.module:\\n\"\n\t\t\"         } {\\n\"\n\t\t\"            clear\\n\"\n\t\t\"         } ifelse\\n\"\n\t\t\"      } {\\n\"\n\t\t\"         % Extract the module name as a namespace.\\n\"\n\t\t\"         \\\\1 /namespace @1 _tag _commit \\\\1 SCSS.module:\\n\"\n\t\t\"      } ifelse\\n\"\n\t\t\"   } {\\n\"\n\t\t\"     % \\\"as *\\\" doesn't make a namespace.\\n\"\n\t\t\"      \\\\3 (*) ne {\\n\"\n\t\t\"         \\\\3 /namespace @3 _tag _commit \\\\1 SCSS.module:\\n\"\n\t\t\"      } if\\n\"\n\t\t\"   } ifelse\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^@[^\\n]+\\n?\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^:[^{;]+;\\n?\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^:[^\\n;{]+\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^::?([A-Za-z0-9_-]+)[ \\t]*[,({]\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^:[^\\n{]+[;{]\\n?\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^\\\\$([A-Za-z0-9_-]+)[ \\t]*:[ \\t]*\\\\(\",\n\t                               \"\\\\1\", \"v\", \"{tenter=map}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^\\\\$([A-Za-z0-9_-]+)[ \\t]*:[^\\n]*\\n?\",\n\t                               \"\\\\1\", \"v\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[.]([A-Za-z0-9_-]+)\",\n\t                               \"\\\\1\", \"c\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^%([A-Za-z0-9_-]+)\",\n\t                               \"\\\\1\", \"P\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^#([A-Za-z0-9_-]+)\",\n\t                               \"\\\\1\", \"i\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^\\\\*/\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"interp\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"interp\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"args\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"args\",\n\t                               \"^#\\\\{\",\n\t                               \"\", \"\", \"{tenter=interp}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"args\",\n\t                               \"^\\\\$([A-Za-z0-9_-]+)[ \\t]*(:([ \\t]*\\\\$)?|[,)])\",\n\t                               \"\\\\1\", \"z\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"args\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"map\",\n\t                               \"^//[^\\n]*\\n?\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"map\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"map\",\n\t                               \"^#\\\\{\",\n\t                               \"\", \"\", \"{tenter=interp}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"map\",\n\t                               \"^\\\\)\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"map\",\n\t                               \"^([A-Za-z0-9_-]+)[ \\t]*:\",\n\t                               \"\\\\1\", \"v\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"map\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=strs}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"map\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=strd}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"map\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"strs\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"strs\",\n\t                               \"^#\\\\{\",\n\t                               \"\", \"\", \"{tenter=interp}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"strs\",\n\t                               \"^[^'#\\\\\\\\]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"strs\",\n\t                               \"^\\\\\\\\?.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"strd\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"strd\",\n\t                               \"^#\\\\{\",\n\t                               \"\", \"\", \"{tenter=interp}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"strd\",\n\t                               \"^[^\\\"#\\\\\\\\]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"strd\",\n\t                               \"^\\\\\\\\?.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* SCSSParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"scss\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic roleDefinition SCSSModuleRoleTable [] = {\n\t\t{\n\t\t  true, \"used\", \"used\",\n\t\t  .version = 1,\n\t\t},\n\t};\n\tstatic kindDefinition SCSSKindTable [] = {\n\t\t{\n\t\t  true, 'm', \"mixin\", \"mixins\",\n\t\t},\n\t\t{\n\t\t  true, 'f', \"function\", \"functions\",\n\t\t},\n\t\t{\n\t\t  true, 'v', \"variable\", \"variables\",\n\t\t},\n\t\t{\n\t\t  true, 'c', \"class\", \"classes\",\n\t\t},\n\t\t{\n\t\t  true, 'P', \"placeholder\", \"placeholder classes\",\n\t\t},\n\t\t{\n\t\t  true, 'i', \"id\", \"identities\",\n\t\t},\n\t\t{\n\t\t  true, 'z', \"parameter\", \"function parameters\",\n\t\t},\n\t\t{\n\t\t  true, 'n', \"namespace\", \"namespaces\",\n\t\t  .version = 1,\n\t\t},\n\t\t{\n\t\t  true, 'M', \"module\", \"modules\",\n\t\t  ATTACH_ROLES(SCSSModuleRoleTable),\n\t\t  .version = 1,\n\t\t},\n\t};\n\tstatic fieldDefinition SCSSFieldTable [] = {\n\t\t{\n\t\t  .enabled     = true,\n\t\t  .name        = \"module\",\n\t\t  .description = \"the name of module behind the namespace\",\n\t\t  .dataType = FIELDTYPE_SCRIPTABLE|FIELDTYPE_STRING,\n\t\t  .isValueAvailable = isValueAvailableGeneric,\n\t\t  .getValueObject = getFieldValueGeneric,\n\t\t  .setValueObject = setFieldValueGeneric,\n\t\t  .version     = 1,\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"SCSS\");\n\n\tdef->versionCurrent= 1;\n\tdef->versionAge    = 1;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = SCSSKindTable;\n\tdef->kindCount     = ARRAY_SIZE(SCSSKindTable);\n\tdef->fieldTable    = SCSSFieldTable;\n\tdef->fieldCount    = ARRAY_SIZE(SCSSFieldTable);\n\tdef->initialize    = initializeSCSSParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/scss.ctags",
    "content": "#\n## This one is derrived from https://gist.githubusercontent.com/Roy-Orbison/71bc81f488f85adaeacfb76a7967eda0/raw/5eed9f1ef75c0921123651d419b3944a155f438f/scss.ctags\n#\n# Copyright 2019 Roy-Orbison\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n#\n# Reference:\n#\n# - https://sass-lang.com/documentation/\n#\n--langdef=SCSS{version=1.1}\n--map-SCSS=+.scss\n\n--kinddef-SCSS=m,mixin,mixins\n--kinddef-SCSS=f,function,functions\n--kinddef-SCSS=v,variable,variables\n--kinddef-SCSS=c,class,classes\n--kinddef-SCSS=P,placeholder,placeholder classes\n--kinddef-SCSS=i,id,identities\n# --kinddef-SCSS=p,pseudo,pseudos\n--kinddef-SCSS=z,parameter,function parameters\n--kinddef-SCSS=n,namespace,namespaces{version=1}\n--kinddef-SCSS=M,module,modules{version=1}\n--_roledef-SCSS.{module}=used,used{version=1}\n\n--_fielddef-SCSS=module,the name of module behind the namespace{datatype=str}{version=1}\n--fields-SCSS=+{module}\n\n--_tabledef-SCSS=toplevel\n--_tabledef-SCSS=comment\n--_tabledef-SCSS=interp\n--_tabledef-SCSS=args\n--_tabledef-SCSS=map\n--_tabledef-SCSS=strs\n--_tabledef-SCSS=strd\n\n--_mtable-regex-SCSS=toplevel/\\/\\/[^\\n]*\\n?//\n--_mtable-regex-SCSS=toplevel/\\/\\*//{tenter=comment}\n--_mtable-regex-SCSS=toplevel/#\\{//{tenter=interp}\n--_mtable-regex-SCSS=toplevel/'///{tenter=strs}\n--_mtable-regex-SCSS=toplevel/\"///{tenter=strd}\n--_mtable-regex-SCSS=toplevel/[ \\t]([A-Za-z0-9_-]+)[ \\t]*:[^\\n]*\\n?//\n--_mtable-regex-SCSS=toplevel/@mixin[ \\t]+([A-Za-z0-9_-]+)/\\1/m/{tenter=args}\n--_mtable-regex-SCSS=toplevel/@function[ \\t]+([A-Za-z0-9_-]+)/\\1/f/{tenter=args}\n--_mtable-regex-SCSS=toplevel/@each[ \\t]+\\$([A-Za-z0-9_-]+)[ \\t]in[ \\t]+/\\1/v/\n--_mtable-regex-SCSS=toplevel/@for[ \\t]+\\$([A-Za-z0-9_-]+)[ \\t]from[ \\t]+.*[ \\t]+(to|through)[ \\t]+[^{]+/\\1/v/\n--_mtable-regex-SCSS=toplevel/@use[ \\t]+[\"']([^\"']+)[\"']([ \\t]+as[ \\t]+([A-Za-z0-9_-]+|\\*))?/\\1/M/{_role=used}{{\n   \\2 false eq {\n      \\1 (/) _strrstr {\n         % Extract the last component in the module name:\n         % module-name offset\n         1 add dup \\1 length exch sub\n         % module-name offset' count\n         0 string\n         % module-name offset' count namespace-string\n         _copyinterval\n         dup length 0 gt {\n            /namespace @1 _tag _commit \\1 SCSS.module:\n         } {\n            clear\n         } ifelse\n      } {\n         % Extract the module name as a namespace.\n         \\1 /namespace @1 _tag _commit \\1 SCSS.module:\n      } ifelse\n   } {\n     % \"as *\" doesn't make a namespace.\n      \\3 (*) ne {\n         \\3 /namespace @3 _tag _commit \\1 SCSS.module:\n      } if\n   } ifelse\n}}\n--_mtable-regex-SCSS=toplevel/@[^\\n]+\\n?//\n--_mtable-regex-SCSS=toplevel/:[^{;]+;\\n?//\n--_mtable-regex-SCSS=toplevel/:[^\\n;{]+\\n//\n# --_mtable-regex-SCSS=toplevel/::?([A-Za-z0-9_-]+)[ \\t]*[,({]/\\1/p/\n--_mtable-regex-SCSS=toplevel/::?([A-Za-z0-9_-]+)[ \\t]*[,({]//\n--_mtable-regex-SCSS=toplevel/:[^\\n{]+[;{]\\n?//\n--_mtable-regex-SCSS=toplevel/\\$([A-Za-z0-9_-]+)[ \\t]*:[ \\t]*\\(/\\1/v/{tenter=map}\n--_mtable-regex-SCSS=toplevel/\\$([A-Za-z0-9_-]+)[ \\t]*:[^\\n]*\\n?/\\1/v/\n--_mtable-regex-SCSS=toplevel/[.]([A-Za-z0-9_-]+)/\\1/c/\n--_mtable-regex-SCSS=toplevel/%([A-Za-z0-9_-]+)/\\1/P/\n--_mtable-regex-SCSS=toplevel/#([A-Za-z0-9_-]+)/\\1/i/\n--_mtable-regex-SCSS=toplevel/.//\n--_mtable-regex-SCSS=comment/\\*\\///{tleave}\n--_mtable-regex-SCSS=comment/.//\n--_mtable-regex-SCSS=interp/\\}//{tleave}\n--_mtable-regex-SCSS=interp/.//\n--_mtable-regex-SCSS=args/\\{//{tleave}\n--_mtable-regex-SCSS=args/#\\{//{tenter=interp}\n--_mtable-regex-SCSS=args/\\$([A-Za-z0-9_-]+)[ \\t]*(:([ \\t]*\\$)?|[,)])/\\1/z/\n--_mtable-regex-SCSS=args/.//\n--_mtable-regex-SCSS=map/\\/\\/[^\\n]*\\n?//\n--_mtable-regex-SCSS=map/\\/\\*//{tenter=comment}\n--_mtable-regex-SCSS=map/#\\{//{tenter=interp}\n--_mtable-regex-SCSS=map/\\)//{tleave}\n--_mtable-regex-SCSS=map/([A-Za-z0-9_-]+)[ \\t]*:/\\1/v/\n--_mtable-regex-SCSS=map/'///{tenter=strs}\n--_mtable-regex-SCSS=map/\"///{tenter=strd}\n--_mtable-regex-SCSS=map/.//\n--_mtable-regex-SCSS=strs/'///{tleave}\n--_mtable-regex-SCSS=strs/#\\{//{tenter=interp}\n--_mtable-regex-SCSS=strs/[^'#\\\\]+//\n--_mtable-regex-SCSS=strs/\\\\?.//\n--_mtable-regex-SCSS=strd/\"///{tleave}\n--_mtable-regex-SCSS=strd/#\\{//{tenter=interp}\n--_mtable-regex-SCSS=strd/[^\"#\\\\]+//\n--_mtable-regex-SCSS=strd/\\\\?.//\n"
  },
  {
    "path": "optlib/selinux-type-enforcement.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/selinux-type-enforcement.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeSELinuxTypeEnforcementParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"typedef\");\n\taddLanguageRegexTable (language, \"alias\");\n\taddLanguageRegexTable (language, \"compoundalias\");\n\taddLanguageRegexTable (language, \"lit\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^#[^\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[[:space:]]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^`\",\n\t                               \"\", \"\", \"{tenter=lit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^pmtarbgu[:space:]][a-zA-Z0-9_]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^policy_module\\\\([[:blank:]]*([^,[:space:]\\\\)]+)[^\\\\)]*\\\\)\",\n\t                               \"\\\\1\", \"m\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^module[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;\",\n\t                               \"\\\\1\", \"m\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^type[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*\",\n\t                               \"\\\\1\", \"t\", \"{tenter=typedef}\"\n\t\t\"{{\\n\"\n\t\t\"   .\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^typealias[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*\",\n\t                               \"\\\\1\", \"t\", \"{_role=aliased}{tenter=typedef}\"\n\t\t\"{{\\n\"\n\t\t\"   .\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^attribute[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;\",\n\t                               \"\\\\1\", \"T\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^role[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;\",\n\t                               \"\\\\1\", \"r\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^attribute_role[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;\",\n\t                               \"\\\\1\", \"R\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^bool[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;\",\n\t                               \"\\\\1\", \"b\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^gen_(tunable|bool)\\\\([[:blank:]]*([^,[:space:]\\\\)]+)[^\\\\)]*\\\\)\",\n\t                               \"\\\\2\", \"b\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^user[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;\",\n\t                               \"\\\\1\", \"u\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^gen_user\\\\([[:blank:]]*([^,[:space:]\\\\)]+)[^\\\\)]*\\\\)\",\n\t                               \"\\\\1\", \"u\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"typedef\",\n\t                               \"^[[:space:]]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"typedef\",\n\t                               \"^alias[[:space:]]+\",\n\t                               \"\", \"\", \"{tenter=alias}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"typedef\",\n\t                               \"^;\",\n\t                               \"\", \"\", \"{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"   pop\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"typedef\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"alias\",\n\t                               \"^[[:space:]]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"alias\",\n\t                               \"^([a-zA-Z0-9_]+)[[:space:]]*\",\n\t                               \"\\\\1\", \"a\", \"{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"   dup :name . exch [ (type) 3 -1 roll ] typeref:\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"alias\",\n\t                               \"^\\\\{[[:space:]]*\",\n\t                               \"\", \"\", \"{tenter=compoundalias}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"alias\",\n\t                               \"^\\\\}[[:space:]]*\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"alias\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"compoundalias\",\n\t                               \"^[[:space:]]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"compoundalias\",\n\t                               \"^([a-zA-Z0-9_]+)[[:space:]]*\",\n\t                               \"\\\\1\", \"a\", \"\"\n\t\t\"{{\\n\"\n\t\t\"   dup :name . exch [ (type) 3 -1 roll ] typeref:\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"compoundalias\",\n\t                               \"^\\\\}[[:space:]]*\",\n\t                               \"\", \"\", \"{tleave}{_advanceTo=0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"compoundalias\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"lit\",\n\t                               \"^[^'`]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"lit\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"lit\",\n\t                               \"^`\",\n\t                               \"\", \"\", \"{tenter=lit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"lit\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* SELinuxTypeEnforcementParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"te\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic roleDefinition SELinuxTypeEnforcementTypeRoleTable [] = {\n\t\t{\n\t\t  true, \"aliased\", \"aliased\",\n\t\t},\n\t};\n\tstatic kindDefinition SELinuxTypeEnforcementKindTable [] = {\n\t\t{\n\t\t  true, 'm', \"module\", \"policy modules\",\n\t\t},\n\t\t{\n\t\t  true, 't', \"type\", \"types\",\n\t\t  ATTACH_ROLES(SELinuxTypeEnforcementTypeRoleTable),\n\t\t},\n\t\t{\n\t\t  true, 'a', \"alias\", \"type aliases\",\n\t\t},\n\t\t{\n\t\t  true, 'T', \"attr\", \"type attributes\",\n\t\t},\n\t\t{\n\t\t  true, 'r', \"role\", \"roles\",\n\t\t},\n\t\t{\n\t\t  true, 'R', \"rattr\", \"role attributes\",\n\t\t},\n\t\t{\n\t\t  true, 'b', \"tunable\", \"tunables\",\n\t\t},\n\t\t{\n\t\t  true, 'u', \"user\", \"users\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"SELinuxTypeEnforcement\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = SELinuxTypeEnforcementKindTable;\n\tdef->kindCount     = ARRAY_SIZE(SELinuxTypeEnforcementKindTable);\n\tdef->initialize    = initializeSELinuxTypeEnforcementParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/selinux-type-enforcement.ctags",
    "content": "#\n#  Copyright (c) 2025 Red Hat, Inc.\n#  Copyright (c) 2025 Masatake YAMATO\n#\n#  This source code is released for free distribution under the terms of the\n#  GNU General Public License version 2 or (at your opinion) any later version.\n#\n#  This module contains functions for generating tags for *.te files in SELinux policy definitions:\n#\n#  https://github.com/SELinuxProject/selinux-notebook/blob/main/src/kernel_policy_language.md#kernel-policy-language\n#\n--langdef=SELinuxTypeEnforcement\n--map-SELinuxTypeEnforcement=+.te\n\n--kinddef-SELinuxTypeEnforcement=m,module,policy modules\n--kinddef-SELinuxTypeEnforcement=t,type,types\n--kinddef-SELinuxTypeEnforcement=a,alias,type aliases\n--kinddef-SELinuxTypeEnforcement=T,attr,type attributes\n--kinddef-SELinuxTypeEnforcement=r,role,roles\n--kinddef-SELinuxTypeEnforcement=R,rattr,role attributes\n--kinddef-SELinuxTypeEnforcement=b,tunable,tunables\n--kinddef-SELinuxTypeEnforcement=u,user,users\n# TODO: sensitivity, category, sid, class\n\n--_roledef-SELinuxTypeEnforcement.{type}=aliased,aliased\n\n--_tabledef-SELinuxTypeEnforcement=main\n--_tabledef-SELinuxTypeEnforcement=typedef\n--_tabledef-SELinuxTypeEnforcement=alias\n--_tabledef-SELinuxTypeEnforcement=compoundalias\n--_tabledef-SELinuxTypeEnforcement=lit\n\n#\n# main\n#\n--_mtable-regex-SELinuxTypeEnforcement=main/#[^\\n]*//\n--_mtable-regex-SELinuxTypeEnforcement=main/[[:space:]]+//\n--_mtable-regex-SELinuxTypeEnforcement=main/`//{tenter=lit}\n--_mtable-regex-SELinuxTypeEnforcement=main/[^pmtarbgu[:space:]][a-zA-Z0-9_]*//\n\n--_mtable-regex-SELinuxTypeEnforcement=main/policy_module\\([[:blank:]]*([^,[:space:]\\)]+)[^\\)]*\\)/\\1/m/\n--_mtable-regex-SELinuxTypeEnforcement=main/module[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;/\\1/m/\n\n--_mtable-regex-SELinuxTypeEnforcement=main/type[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*/\\1/t/{tenter=typedef}{{\n   .\n}}\n--_mtable-regex-SELinuxTypeEnforcement=main/typealias[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*/\\1/t/{_role=aliased}{tenter=typedef}{{\n   .\n}}\n--_mtable-regex-SELinuxTypeEnforcement=main/attribute[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;/\\1/T/\n\n--_mtable-regex-SELinuxTypeEnforcement=main/role[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;/\\1/r/\n--_mtable-regex-SELinuxTypeEnforcement=main/attribute_role[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;/\\1/R/\n\n--_mtable-regex-SELinuxTypeEnforcement=main/bool[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;/\\1/b/\n--_mtable-regex-SELinuxTypeEnforcement=main/gen_(tunable|bool)\\([[:blank:]]*([^,[:space:]\\)]+)[^\\)]*\\)/\\2/b/\n\n--_mtable-regex-SELinuxTypeEnforcement=main/user[[:blank:]]+([a-zA-Z0-9_]+)[[:blank:]]*[^;]*;/\\1/u/\n--_mtable-regex-SELinuxTypeEnforcement=main/gen_user\\([[:blank:]]*([^,[:space:]\\)]+)[^\\)]*\\)/\\1/u/\n\n--_mtable-regex-SELinuxTypeEnforcement=main/.//\n\n#\n# typedef\n#\n--_mtable-regex-SELinuxTypeEnforcement=typedef/[[:space:]]+//\n--_mtable-regex-SELinuxTypeEnforcement=typedef/alias[[:space:]]+//{tenter=alias}\n--_mtable-regex-SELinuxTypeEnforcement=typedef/;//{tleave}{{\n   pop\n}}\n--_mtable-regex-SELinuxTypeEnforcement=typedef/.//\n\n#\n# alias\n#\n--_mtable-regex-SELinuxTypeEnforcement=alias/[[:space:]]+//\n--_mtable-regex-SELinuxTypeEnforcement=alias/([a-zA-Z0-9_]+)[[:space:]]*/\\1/a/{tleave}{{\n   dup :name . exch [ (type) 3 -1 roll ] typeref:\n}}\n--_mtable-regex-SELinuxTypeEnforcement=alias/\\{[[:space:]]*//{tenter=compoundalias}\n--_mtable-regex-SELinuxTypeEnforcement=alias/\\}[[:space:]]*//{tleave}\n--_mtable-regex-SELinuxTypeEnforcement=alias/.//\n\n#\n# compoundalias\n#\n--_mtable-regex-SELinuxTypeEnforcement=compoundalias/[[:space:]]+//\n--_mtable-regex-SELinuxTypeEnforcement=compoundalias/([a-zA-Z0-9_]+)[[:space:]]*/\\1/a/{{\n   dup :name . exch [ (type) 3 -1 roll ] typeref:\n}}\n--_mtable-regex-SELinuxTypeEnforcement=compoundalias/\\}[[:space:]]*//{tleave}{_advanceTo=0start}\n--_mtable-regex-SELinuxTypeEnforcement=compoundalias/.//\n\n#\n# lit\n#\n--_mtable-regex-SELinuxTypeEnforcement=lit/[^'`]+//\n--_mtable-regex-SELinuxTypeEnforcement=lit/'//{tleave}\n--_mtable-regex-SELinuxTypeEnforcement=lit/`//{tenter=lit}\n--_mtable-regex-SELinuxTypeEnforcement=lit/.//\n"
  },
  {
    "path": "optlib/systemtap.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/systemtap.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeSystemTapParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"main\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"any\");\n\taddLanguageRegexTable (language, \"skipWhiteSpace\");\n\taddLanguageRegexTable (language, \"skipLiteral\");\n\taddLanguageRegexTable (language, \"ssliteral\");\n\taddLanguageRegexTable (language, \"dsliteral\");\n\taddLanguageRegexTable (language, \"arraysize\");\n\taddLanguageRegexTable (language, \"stmtend\");\n\taddLanguageRegexTable (language, \"probe\");\n\taddLanguageRegexTable (language, \"probeBody\");\n\taddLanguageRegexTable (language, \"probeStmt\");\n\taddLanguageRegexTable (language, \"func\");\n\taddLanguageRegexTable (language, \"funcSig\");\n\taddLanguageRegexTable (language, \"funcBody\");\n\taddLanguageRegexTable (language, \"funcStmt\");\n\taddLanguageRegexTable (language, \"cfuncStmt\");\n\taddLanguageRegexTable (language, \"vars\");\n\taddLanguageRegexTable (language, \"macro\");\n\taddLanguageRegexTable (language, \"macroSig\");\n\taddLanguageRegexTable (language, \"macroBody\");\n\taddLanguageRegexTable (language, \"macroStmt\");\n\taddLanguageRegexTable (language, \"comment_multiline\");\n\taddLanguageRegexTable (language, \"comment_oneline\");\n\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^[^#/'\\\"pfg@%]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^probe[[:space:]]+\",\n\t                               \"\", \"\", \"{tenter=probe}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^@define[[:space:]]+\",\n\t                               \"\", \"\", \"{tenter=macro}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^function[[:space:]]+\",\n\t                               \"\", \"\", \"{tenter=func}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^global[[:space:]]+\",\n\t                               \"\", \"\", \"{tenter=vars}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^(%\\\\{)\",\n\t                               \"\", \"\", \"{tenter=cfuncStmt}\"\n\t\t\"{{\\n\"\n\t\t\"    1@ true\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^%\\\\(\",\n\t                               \"\", \"\", \"{tenter=cfuncStmt}\"\n\t\t\"{{\\n\"\n\t\t\"    false\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"main\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"any\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipWhiteSpace\",\n\t                               \"^[ \\t\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipLiteral\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"skipLiteral\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ssliteral\",\n\t                               \"^[^']*'\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"ssliteral\",\n\t                               \"^[^']+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dsliteral\",\n\t                               \"^[^\\\"\\\\\\\\]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dsliteral\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"dsliteral\",\n\t                               \"^\\\\\\\\.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"arraysize\",\n\t                               \"^[^]/#]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"arraysize\",\n\t                               \"^]\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"arraysize\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"stmtend\",\n\t                               \"^\",\n\t                               \"\", \"\", \"{tleave}{scope=pop}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probe\",\n\t                               \"^([[:alpha:]_][[:alnum:]_.]*)[[:space:]]*\\\\+?=[[:space:]]*\",\n\t                               \"\\\\1\", \"p\", \"{tenter=probeBody}{scope=push}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probe\",\n\t                               \"^([[:alpha:]_][[:alnum:]_.]*)[[:space:]]*\",\n\t                               \"\\\\1\", \"p\", \"{_role=attached}{tenter=probeBody}{scope=push}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeBody\",\n\t                               \"^[^\\\\{/#'\\\"]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeBody\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=probeStmt,stmtend}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeBody\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeBody\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeBody\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeBody\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeBody\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeBody\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeStmt\",\n\t                               \"^[^\\\\{\\\\}/#'\\\"]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeStmt\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeStmt\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeStmt\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeStmt\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=probeStmt}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeStmt\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeStmt\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeStmt\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"probeStmt\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"func\",\n\t                               \"^([[:alpha:]_][[:alnum:]_]*)(:([[:alpha:]_][[:alnum:]_]*))?[[:space:]]*\\\\(\",\n\t                               \"\\\\1\", \"f\", \"{tenter=funcSig,funcBody}{scope=push}\"\n\t\t\"{{\\n\"\n\t\t\"  \\\\3 false ne {\\n\"\n\t\t\"     . \\\\3 typeref:\\n\"\n\t\t\"  } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcSig\",\n\t                               \"^[^)/]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcSig\",\n\t                               \"^\\\\)(:[0-9]+)?\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcSig\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcSig\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcSig\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcSig\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcBody\",\n\t                               \"^[^\\\\{%'\\\"#]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcBody\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=funcStmt,stmtend}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcBody\",\n\t                               \"^(%\\\\{)\",\n\t                               \"\", \"\", \"{tenter=cfuncStmt,stmtend}\"\n\t\t\"{{\\n\"\n\t\t\"    1@ true\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcBody\",\n\t                               \"^%\\\\(\",\n\t                               \"\", \"\", \"{tenter=cfuncStmt,stmtend}\"\n\t\t\"{{\\n\"\n\t\t\"    false\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcBody\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcBody\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcBody\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcBody\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^[^%/#'\\\"\\\\{\\\\}]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^(%\\\\{)\",\n\t                               \"\", \"\", \"{tenter=cfuncStmt}\"\n\t\t\"{{\\n\"\n\t\t\"    1@ true\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^%\\\\(\",\n\t                               \"\", \"\", \"{tenter=cfuncStmt}\"\n\t\t\"{{\\n\"\n\t\t\"    false\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=funcStmt}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"funcStmt\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^[^%/#'\\\"]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^%\\\\)\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^(%\\\\})\",\n\t                               \"\", \"\", \"{tleave}\"\n\t\t\"{{\\n\"\n\t\t\"    {\\n\"\n\t\t\"        % TODO: If the function name of SystemTap side can be passed to\\n\"\n\t\t\"        % the C code area, running C parser is meaningfully.\\n\"\n\t\t\"        % However, we have not implemented such a feature yet.\\n\"\n\t\t\"        (CPreProcessor) exch @1 _makepromise { pop } if\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^(%\\\\{)\",\n\t                               \"\", \"\", \"{tenter=cfuncStmt}\"\n\t\t\"{{\\n\"\n\t\t\"    1@ true\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^%\\\\(\",\n\t                               \"\", \"\", \"{tenter=cfuncStmt}\"\n\t\t\"{{\\n\"\n\t\t\"    false\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cfuncStmt\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"vars\",\n\t                               \"^([[:alpha:]_][[:alnum:]_]*)%?\",\n\t                               \"\\\\1\", \"v\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"vars\",\n\t                               \"^[\\n]\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"vars\",\n\t                               \"^,[[:space:]]*\",\n\t                               \"\", \"\", \"{tjump=vars}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"vars\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"vars\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"vars\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"vars\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"vars\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"vars\",\n\t                               \"^\\\\[\",\n\t                               \"\", \"\", \"{tenter=arraysize}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"vars\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macro\",\n\t                               \"^([[:alpha:]_][[:alnum:]_]*)[[:space:]]*\\\\(\",\n\t                               \"\\\\1\", \"m\", \"{tenter=macroSig,macroBody}{scope=push}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macro\",\n\t                               \"^([[:alpha:]_][[:alnum:]_]*)[[:space:]]*\",\n\t                               \"\\\\1\", \"m\", \"{tenter=macroBody,stmtend}{scope=push}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroSig\",\n\t                               \"^[^#/)]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroSig\",\n\t                               \"^\\\\)\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroSig\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroSig\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroSig\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroSig\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroBody\",\n\t                               \"^[^%#/)]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroBody\",\n\t                               \"^%\\\\(\",\n\t                               \"\", \"\", \"{tenter=macroStmt,stmtend}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroBody\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroBody\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroBody\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroBody\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroStmt\",\n\t                               \"^[^#/%'\\\"]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroStmt\",\n\t                               \"^%\\\\)\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroStmt\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=dsliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroStmt\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=ssliteral}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroStmt\",\n\t                               \"^\\\\#\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroStmt\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment_multiline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroStmt\",\n\t                               \"^//\",\n\t                               \"\", \"\", \"{tenter=comment_oneline}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroStmt\",\n\t                               \"^%\\\\(\",\n\t                               \"\", \"\", \"{tenter=macroStmt}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"macroStmt\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment_multiline\",\n\t                               \"^[^*]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment_multiline\",\n\t                               \"^\\\\*/\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment_multiline\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment_oneline\",\n\t                               \"^[^\\n]*\\n\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment_oneline\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* SystemTapParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"stp\",\n\t\t\"stpm\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\t\"stap\",\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic roleDefinition SystemTapProbeRoleTable [] = {\n\t\t{\n\t\t  true, \"attached\", \"attached by code for probing\",\n\t\t  .version = 1,\n\t\t},\n\t};\n\tstatic kindDefinition SystemTapKindTable [] = {\n\t\t{\n\t\t  true, 'p', \"probe\", \"probe aliases\",\n\t\t  ATTACH_ROLES(SystemTapProbeRoleTable),\n\t\t},\n\t\t{\n\t\t  true, 'f', \"function\", \"functions\",\n\t\t},\n\t\t{\n\t\t  true, 'v', \"variable\", \"variables\",\n\t\t},\n\t\t{\n\t\t  true, 'm', \"macro\", \"macros\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"SystemTap\");\n\n\tdef->versionCurrent= 1;\n\tdef->versionAge    = 1;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = SystemTapKindTable;\n\tdef->kindCount     = ARRAY_SIZE(SystemTapKindTable);\n\tdef->initialize    = initializeSystemTapParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/systemtap.ctags",
    "content": "#\n# systemtap.ctags --- multitable regex parser for SystemTap script file\n#\n#  Copyright (c) 2018, Red Hat, Inc.\n#  Copyright (c) 2018, Masatake YAMATO\n#\n#  Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n#\n# References:\n#\n# - https://sourceware.org/systemtap/langref/\n#\n--langdef=SystemTap{version=1.1}\n--map-SystemTap=+.stp\n--map-SystemTap=+.stpm\n--alias-SystemTap=+stap\n\n--kinddef-SystemTap=p,probe,probe aliases\n--_roledef-SystemTap.{probe}=attached,attached by code for probing{version=1}\n--kinddef-SystemTap=f,function,functions\n--kinddef-SystemTap=v,variable,variables\n--kinddef-SystemTap=m,macro,macros\n\n--_tabledef-SystemTap=main\n--_tabledef-SystemTap=comment\n--_tabledef-SystemTap=any\n--_tabledef-SystemTap=skipWhiteSpace\n--_tabledef-SystemTap=skipLiteral\n--_tabledef-SystemTap=ssliteral\n--_tabledef-SystemTap=dsliteral\n--_tabledef-SystemTap=arraysize\n\n--_tabledef-SystemTap=stmtend\n\n--_tabledef-SystemTap=probe\n--_tabledef-SystemTap=probeBody\n--_tabledef-SystemTap=probeStmt\n\n--_tabledef-SystemTap=func\n--_tabledef-SystemTap=funcSig\n--_tabledef-SystemTap=funcBody\n--_tabledef-SystemTap=funcStmt\n--_tabledef-SystemTap=cfuncStmt\n\n--_tabledef-SystemTap=vars\n\n--_tabledef-SystemTap=macro\n--_tabledef-SystemTap=macroSig\n--_tabledef-SystemTap=macroBody\n--_tabledef-SystemTap=macroStmt\n\n#\n# Utilities\n#\n--_mtable-regex-SystemTap=any/.//\n--_mtable-regex-SystemTap=skipWhiteSpace/[ \\t\\n]+//\n--_mtable-regex-SystemTap=skipLiteral/\"//{tenter=dsliteral}\n--_mtable-regex-SystemTap=skipLiteral/'//{tenter=ssliteral}\n--_mtable-regex-SystemTap=ssliteral/[^']*'//{tleave}\n--_mtable-regex-SystemTap=ssliteral/[^']+//\n--_mtable-regex-SystemTap=dsliteral/[^\"\\\\]+//\n--_mtable-regex-SystemTap=dsliteral/\"//{tleave}\n--_mtable-regex-SystemTap=dsliteral/\\\\.//\n--_mtable-regex-SystemTap=stmtend///{tleave}{scope=pop}\n--_mtable-regex-SystemTap=arraysize/[^]\\/#]+//\n--_mtable-regex-SystemTap=arraysize/]//{tleave}\n--_mtable-extend-SystemTap=arraysize+comment\n--_mtable-extend-SystemTap=arraysize+any\n\n#\n# comment\n#\n--_tabledef-SystemTap=comment_multiline\n--_tabledef-SystemTap=comment_oneline\n--_mtable-regex-SystemTap=comment/\\#//{tenter=comment_oneline}\n--_mtable-regex-SystemTap=comment/\\/\\*//{tenter=comment_multiline}\n--_mtable-regex-SystemTap=comment/\\/\\///{tenter=comment_oneline}\n\n--_mtable-regex-SystemTap=comment_multiline/[^*]+//\n--_mtable-regex-SystemTap=comment_multiline/\\*\\///{tleave}\n--_mtable-extend-SystemTap=comment_multiline+any\n\n--_mtable-regex-SystemTap=comment_oneline/[^\\n]*\\n//{tleave}\n--_mtable-extend-SystemTap=comment_oneline+any\n\n#\n# main\n#\n--_mtable-regex-SystemTap=main/[^#\\/'\"pfg@%]+//\n--_mtable-regex-SystemTap=main/probe[[:space:]]+//{tenter=probe}\n--_mtable-extend-SystemTap=main+comment\n--_mtable-regex-SystemTap=main/@define[[:space:]]+//{tenter=macro}\n--_mtable-regex-SystemTap=main/function[[:space:]]+//{tenter=func}\n--_mtable-regex-SystemTap=main/global[[:space:]]+//{tenter=vars}\n--_mtable-regex-SystemTap=main/(%\\{)//{tenter=cfuncStmt}{{\n    1@ true\n}}\n--_mtable-regex-SystemTap=main/%\\(//{tenter=cfuncStmt}{{\n    false\n}}\n--_mtable-extend-SystemTap=main+any\n\n#\n# probe\n#\n--_mtable-regex-SystemTap=probe/([[:alpha:]_][[:alnum:]_.]*)[[:space:]]*\\+?=[[:space:]]*/\\1/p/{tenter=probeBody}{scope=push}\n\n# This \"push\" is dummy.\n--_mtable-regex-SystemTap=probe/([[:alpha:]_][[:alnum:]_.]*)[[:space:]]*/\\1/p/{_role=attached}{tenter=probeBody}{scope=push}\n\n#\n# probeBody\n#\n--_mtable-regex-SystemTap=probeBody/[^\\{\\/#'\"]+//\n--_mtable-regex-SystemTap=probeBody/\\{//{tenter=probeStmt,stmtend}\n--_mtable-extend-SystemTap=probeBody+skipLiteral\n--_mtable-extend-SystemTap=probeBody+comment\n--_mtable-extend-SystemTap=probeBody+any\n\n#\n# probeStmt\n#\n--_mtable-regex-SystemTap=probeStmt/[^\\{\\}\\/#'\"]+//\n--_mtable-regex-SystemTap=probeStmt/\\}//{tleave}\n--_mtable-extend-SystemTap=probeStmt+skipLiteral\n--_mtable-regex-SystemTap=probeStmt/\\{//{tenter=probeStmt}\n--_mtable-extend-SystemTap=probeStmt+comment\n--_mtable-extend-SystemTap=probeStmt+any\n\n#\n# func\n#\n\n--_mtable-regex-SystemTap=func/([[:alpha:]_][[:alnum:]_]*)(:([[:alpha:]_][[:alnum:]_]*))?[[:space:]]*\\(/\\1/f/{tenter=funcSig,funcBody}{scope=push}{{\n  \\3 false ne {\n     . \\3 typeref:\n  } if\n}}\n\n# TODO: capture parameters\n# TODO: fill the signature field of the current function.\n--_mtable-regex-SystemTap=funcSig/[^)\\/]+//\n--_mtable-regex-SystemTap=funcSig/\\)(:[0-9]+)?//{tleave}\n--_mtable-extend-SystemTap=funcSig+comment\n--_mtable-extend-SystemTap=funcSig+any\n\n--_mtable-regex-SystemTap=funcBody/[^\\{%'\"#]+//\n--_mtable-regex-SystemTap=funcBody/\\{//{tenter=funcStmt,stmtend}\n--_mtable-regex-SystemTap=funcBody/(%\\{)//{tenter=cfuncStmt,stmtend}{{\n    1@ true\n}}\n--_mtable-regex-SystemTap=funcBody/%\\(//{tenter=cfuncStmt,stmtend}{{\n    false\n}}\n--_mtable-extend-SystemTap=funcBody+comment\n--_mtable-extend-SystemTap=funcBody+any\n\n#\n# funcStmt and cfuncStmt\n#\n--_mtable-regex-SystemTap=funcStmt/[^%\\/#'\"\\{\\}]+//\n--_mtable-regex-SystemTap=funcStmt/\\}//{tleave}\n--_mtable-extend-SystemTap=funcStmt+skipLiteral\n--_mtable-extend-SystemTap=funcStmt+comment\n--_mtable-regex-SystemTap=funcStmt/(%\\{)//{tenter=cfuncStmt}{{\n    1@ true\n}}\n--_mtable-regex-SystemTap=funcStmt/%\\(//{tenter=cfuncStmt}{{\n    false\n}}\n--_mtable-regex-SystemTap=funcStmt/\\{//{tenter=funcStmt}\n--_mtable-extend-SystemTap=funcStmt+any\n\n--_mtable-regex-SystemTap=cfuncStmt/[^%\\/#'\"]+//\n--_mtable-extend-SystemTap=cfuncStmt+comment\n--_mtable-extend-SystemTap=cfuncStmt+skipLiteral\n--_mtable-regex-SystemTap=cfuncStmt/%\\)//{tleave}\n--_mtable-regex-SystemTap=cfuncStmt/(%\\})//{tleave}{{\n    {\n        % TODO: If the function name of SystemTap side can be passed to\n        % the C code area, running C parser is meaningfully.\n        % However, we have not implemented such a feature yet.\n        (CPreProcessor) exch @1 _makepromise { pop } if\n    } if\n}}\n--_mtable-regex-SystemTap=cfuncStmt/(%\\{)//{tenter=cfuncStmt}{{\n    1@ true\n}}\n--_mtable-regex-SystemTap=cfuncStmt/%\\(//{tenter=cfuncStmt}{{\n    false\n}}\n--_mtable-extend-SystemTap=cfuncStmt+any\n\n#\n# vars\n#\n--_mtable-regex-SystemTap=vars/([[:alpha:]_][[:alnum:]_]*)%?/\\1/v/\n--_mtable-regex-SystemTap=vars/[\\n]//{tleave}\n--_mtable-regex-SystemTap=vars/,[[:space:]]*//{tjump=vars}\n--_mtable-extend-SystemTap=vars+comment\n--_mtable-extend-SystemTap=vars+skipLiteral\n--_mtable-regex-SystemTap=vars/\\[//{tenter=arraysize}\n--_mtable-extend-SystemTap=vars+any\n\n#\n# macro\n#\n--_mtable-regex-SystemTap=macro/([[:alpha:]_][[:alnum:]_]*)[[:space:]]*\\(/\\1/m/{tenter=macroSig,macroBody}{scope=push}\n--_mtable-regex-SystemTap=macro/([[:alpha:]_][[:alnum:]_]*)[[:space:]]*/\\1/m/{tenter=macroBody,stmtend}{scope=push}\n\n# TODO: capture parameters\n--_mtable-regex-SystemTap=macroSig/[^#\\/)]+//\n--_mtable-regex-SystemTap=macroSig/\\)//{tleave}\n--_mtable-extend-SystemTap=macroSig+comment\n--_mtable-extend-SystemTap=macroSig+any\n\n\n--_mtable-regex-SystemTap=macroBody/[^%#\\/)]+//\n--_mtable-regex-SystemTap=macroBody/%\\(//{tenter=macroStmt,stmtend}\n--_mtable-extend-SystemTap=macroBody+comment\n--_mtable-extend-SystemTap=macroBody+any\n\n--_mtable-regex-SystemTap=macroStmt/[^#\\/%'\"]+//\n--_mtable-regex-SystemTap=macroStmt/%\\)//{tleave}\n--_mtable-extend-SystemTap=macroStmt+skipLiteral\n--_mtable-extend-SystemTap=macroStmt+comment\n--_mtable-regex-SystemTap=macroStmt/%\\(//{tenter=macroStmt}\n--_mtable-extend-SystemTap=macroStmt+any\n"
  },
  {
    "path": "optlib/terraform.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/terraform.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeTerraformParser (const langType language)\n{\n\n\taddLanguageRegexTable (language, \"toplevel\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"locals\");\n\taddLanguageRegexTable (language, \"multicomment\");\n\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^(\\\\#|//)\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=multicomment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^locals[[:space:]]*\\\\{\",\n\t                               \"\", \"\", \"{tenter=locals}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^resource[[:space:]]\\\"([^\\\"]+)\\\"[[:space:]]\\\"([^\\\"]+)\\\"\",\n\t                               \"\\\\2\", \"r\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^data[[:space:]]\\\"([^\\\"]+)\\\"[[:space:]]\\\"([^\\\"]+)\\\"\",\n\t                               \"\\\\2\", \"d\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^variable[[:space:]]\\\"([^\\\"]+)\\\"\",\n\t                               \"\\\\1\", \"v\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^provider[[:space:]]\\\"([^\\\"]+)\\\"\",\n\t                               \"\\\\1\", \"p\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^module[[:space:]]\\\"([^\\\"]+)\\\"\",\n\t                               \"\\\\1\", \"m\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^output[[:space:]]\\\"([^\\\"]+)\\\"\",\n\t                               \"\\\\1\", \"o\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^[^\\n]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^\\n\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"locals\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"locals\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=locals}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"locals\",\n\t                               \"^(\\\\#|//)\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"locals\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=multicomment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"locals\",\n\t                               \"^([a-z0-9_]+)+[[:space:]]*=[[:space:]]+\",\n\t                               \"\\\\1\", \"l\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"locals\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"multicomment\",\n\t                               \"^\\\\*/\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"multicomment\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* TerraformParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"tf\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic roleDefinition TerraformVariableRoleTable [] = {\n\t\t{\n\t\t  true, \"assigned\", \"assigned in Variable Definitions (.tfvars) files\",\n\t\t},\n\t};\n\tstatic kindDefinition TerraformKindTable [] = {\n\t\t{\n\t\t  true, 'r', \"resource\", \"resources\",\n\t\t},\n\t\t{\n\t\t  true, 'd', \"data\", \"data\",\n\t\t},\n\t\t{\n\t\t  true, 'v', \"variable\", \"variables\",\n\t\t  ATTACH_ROLES(TerraformVariableRoleTable),\n\t\t},\n\t\t{\n\t\t  true, 'p', \"provider\", \"providers\",\n\t\t},\n\t\t{\n\t\t  true, 'm', \"module\", \"modules\",\n\t\t},\n\t\t{\n\t\t  true, 'o', \"output\", \"output\",\n\t\t},\n\t\t{\n\t\t  true, 'l', \"local\", \"locals\",\n\t\t  .version = 1,\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"Terraform\");\n\n\tdef->versionCurrent= 1;\n\tdef->versionAge    = 1;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->kindTable     = TerraformKindTable;\n\tdef->kindCount     = ARRAY_SIZE(TerraformKindTable);\n\tdef->initialize    = initializeTerraformParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/terraform.ctags",
    "content": "#\n# terraform.ctags: regex parse for Terraform (HCL).\n#\n# Copyright (c) 2021, Julio Tain Sueiras\n# Copyright (c) 2021, Antony Southworth\n#\n# Antony Southworth adapted Julio's code to Universal Ctags.\n#\n# This source code is released for free distribution under the terms of the\n# GNU General Public License version 2 or (at your option) any later version.\n#\n# Derived from `vim-terraform-completion`:\n#   - https://github.com/juliosueiras/vim-terraform-completion/blob/master/ctags/terraform.ctags\n#\n# About the language:\n#   - https://developer.hashicorp.com/terraform/language/syntax/configuration\n#\n# There ctags regex were re-implemented into multi-table regex to support\n# multi-line comments and locals blocks\n#\n# Changed the name from `terraform` to `tf` so vim will recognise it properly based\n# on file extension (*.tf).\n#\n# .tfvars files relates code are moved to TerraformVariables parser.\n#\n--langdef=Terraform{version=1.1}\n\n--map-Terraform=+.tf\n\n--kinddef-Terraform=r,resource,resources\n--kinddef-Terraform=d,data,data\n\n--kinddef-Terraform=v,variable,variables\n# See https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files\n--_roledef-Terraform.v=assigned,assigned in Variable Definitions (.tfvars) files\n\n--kinddef-Terraform=p,provider,providers\n--kinddef-Terraform=m,module,modules\n--kinddef-Terraform=o,output,output\n--kinddef-Terraform=l,local,locals{version=1}\n\n\n--_tabledef-Terraform=toplevel\n--_tabledef-Terraform=comment\n--_tabledef-Terraform=locals\n--_tabledef-Terraform=multicomment\n\n\n--_mtable-regex-Terraform=toplevel/(\\#|\\/\\/)//{tenter=comment}\n--_mtable-regex-Terraform=toplevel/\\/\\*//{tenter=multicomment}\n--_mtable-regex-Terraform=toplevel/locals[[:space:]]*\\{//{tenter=locals}\n--_mtable-regex-Terraform=toplevel/^resource[[:space:]]\"([^\"]+)\"[[:space:]]\"([^\"]+)\"/\\2/r/\n--_mtable-regex-Terraform=toplevel/^data[[:space:]]\"([^\"]+)\"[[:space:]]\"([^\"]+)\"/\\2/d/\n--_mtable-regex-Terraform=toplevel/^variable[[:space:]]\"([^\"]+)\"/\\1/v/\n--_mtable-regex-Terraform=toplevel/^provider[[:space:]]\"([^\"]+)\"/\\1/p/\n--_mtable-regex-Terraform=toplevel/^module[[:space:]]\"([^\"]+)\"/\\1/m/\n--_mtable-regex-Terraform=toplevel/^output[[:space:]]\"([^\"]+)\"/\\1/o/\n--_mtable-regex-Terraform=toplevel/.//\n\n--_mtable-regex-Terraform=comment/[^\\n]+//\n--_mtable-regex-Terraform=comment/\\n//{tleave}\n--_mtable-regex-Terraform=comment/.//\n\n--_mtable-regex-Terraform=multicomment/\\*\\///{tleave}\n--_mtable-regex-Terraform=multicomment/.//\n\n--_mtable-regex-Terraform=locals/\\}//{tleave}\n--_mtable-regex-Terraform=locals/\\{//{tenter=locals}\n--_mtable-regex-Terraform=locals/(\\#|\\/\\/)//{tenter=comment}\n--_mtable-regex-Terraform=locals/\\/\\*//{tenter=multicomment}\n--_mtable-regex-Terraform=locals/([a-z0-9_]+)+[[:space:]]*=[[:space:]]+/\\1/l/\n--_mtable-regex-Terraform=locals/.//\n"
  },
  {
    "path": "optlib/terraformvariables.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/terraformvariables.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n#include \"dependency.h\"\n\n\nstatic void initializeTerraformVariablesParser (const langType language CTAGS_ATTR_UNUSED)\n{\n}\n\nextern parserDefinition* TerraformVariablesParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"tfvars\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic tagRegexTable TerraformVariablesTagRegexTable [] = {\n\t\t{\"^([a-z0-9_]+)[[:space:]]*=\", \"\\\\1\",\n\t\t\"v\", \"{_role=assigned}{_language=Terraform}\", NULL, false},\n\t};\n\n\tstatic parserDependency TerraformVariablesDependencies [] = {\n\t\t[0] = { DEPTYPE_FOREIGNER, \"Terraform\", NULL },\n\t};\n\n\tparserDefinition* const def = parserNew (\"TerraformVariables\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->tagRegexTable = TerraformVariablesTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(TerraformVariablesTagRegexTable);\n\tdef->dependencies    = TerraformVariablesDependencies;\n\tdef->dependencyCount = ARRAY_SIZE(TerraformVariablesDependencies);\n\tdef->initialize    = initializeTerraformVariablesParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/terraformvariables.ctags",
    "content": "#\n#  Copyright (c) 2021, Julio Tain Sueiras\n#  Copyright (c) 2023 Masatake YAMATO\n#  Copyright (c) 2023 Red Hat, Inc.\n#\n#  This source code is released for free distribution under the terms of the\n#  GNU General Public License version 2 or (at your option) any later version.\n#\n#  The regex pattern is derrived from\n#  - https://github.com/juliosueiras/vim-terraform-completion/blob/master/ctags/terraform.ctags\n#\n#  This module contains functions to extract language objects for Terraform from\n#  Terraform Variable Definitions (.tfvars) files.\n#  See: https://developer.hashicorp.com/terraform/language/values/variables#variable-definitions-tfvars-files\n#\n--langdef=TerraformVariables{_foreignLanguage=Terraform}\n\n--map-TerraformVariables=+.tfvars\n\n--regex-TerraformVariables=/^([a-z0-9_]+)[[:space:]]*=/\\1/v/{_role=assigned}{_language=Terraform}\n"
  },
  {
    "path": "optlib/yacc.c",
    "content": "/*\n * Generated by ./misc/optlib2c from optlib/yacc.ctags, Don't edit this manually.\n */\n#include \"general.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"xtag.h\"\n\n\nstatic void initializeYACCParser (const langType language)\n{\n\taddLanguageOptscriptToHook (language, SCRIPT_HOOK_PRELUDE,\n\t\t\"{{    /token-type false def\\n\"\n\t\t\"    /type-dict 57 dict def\\n\"\n\t\t\"}}\");\n\n\taddLanguageRegexTable (language, \"toplevel\");\n\taddLanguageRegexTable (language, \"comment\");\n\taddLanguageRegexTable (language, \"cPrologue\");\n\taddLanguageRegexTable (language, \"cCode\");\n\taddLanguageRegexTable (language, \"grammar\");\n\taddLanguageRegexTable (language, \"cEpilogue\");\n\taddLanguageRegexTable (language, \"token\");\n\taddLanguageRegexTable (language, \"cUnion\");\n\taddLanguageRegexTable (language, \"cString\");\n\taddLanguageRegexTable (language, \"iString\");\n\taddLanguageRegexTable (language, \"rule\");\n\taddLanguageRegexTable (language, \"cActionCommon\");\n\taddLanguageRegexTable (language, \"cAction\");\n\taddLanguageRegexTable (language, \"type\");\n\taddLanguageRegexTable (language, \"cCharlit\");\n\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^%token[ \\t\\n]+\",\n\t                               \"\", \"\", \"{tenter=token}\"\n\t\t\"{{\\n\"\n\t\t\"    /token-type false def\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^%(union)[^\\\\{]*\\\\{\",\n\t                               \"\", \"\", \"{tenter=cUnion}{_guest=C,1start,}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^%(code[^\\\\{]*)?\\\\{\",\n\t                               \"\", \"\", \"{tenter=cCode}{_guest=C,0end,}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^%(type|nterm)[ \\n\\t]*\",\n\t                               \"\", \"\", \"{tenter=type}\"\n\t\t\"{{\\n\"\n\t\t\"    /token-type false def\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^%%\",\n\t                               \"\", \"\", \"{tjump=grammar}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"toplevel\",\n\t                               \"^[^\\n]*\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^[^*]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^\\\\*/\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"comment\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cPrologue\",\n\t                               \"^[^%]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cPrologue\",\n\t                               \"^%\\\\}\",\n\t                               \"\", \"\", \"{tleave}{_guest=,,0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cPrologue\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCode\",\n\t                               \"^[^\\\"/\\\\{\\\\}]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCode\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=cString}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCode\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=cCharlit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCode\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCode\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=cAction}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCode\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}{_guest=,,0start}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCode\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"grammar\",\n\t                               \"^%%\",\n\t                               \"\", \"\", \"{tjump=cEpilogue}{_guest=C,0end,}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"grammar\",\n\t                               \"^([a-zA-Z_.][-a-zA-Z_.0-9]+)[ \\t\\n]*:[ \\t\\n]*\",\n\t                               \"\\\\1\", \"l\", \"{tenter=rule}\"\n\t\t\"{{\\n\"\n\t\t\"    type-dict \\\\1 known {\\n\"\n\t\t\"        type-dict \\\\1 get . exch typeref:\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"grammar\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cEpilogue\",\n\t                               \"^.+\",\n\t                               \"\", \"\", \"{_guest=,,0end}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"token\",\n\t                               \"^N?_[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{tenter=iString}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"token\",\n\t                               \"^([_a-zA-Z][_a-zA-Z0-9]*)[ \\t\\n]*\",\n\t                               \"\\\\1\", \"t\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    token-type false ne {\\n\"\n\t\t\"        . token-type typeref:\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"token\",\n\t                               \"^<[ \\t]*([_a-zA-Z][_a-zA-Z0-9 *]*)[ \\t]*>[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    /token-type \\\\1 def\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"token\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=cString}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"token\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=cCharlit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"token\",\n\t                               \"^-?[ \\t\\n]*(0x)?[0-9]+[ \\t\\n]*\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"token\",\n\t                               \"^%\",\n\t                               \"\", \"\", \"{tleave}{_advanceTo=0start}\"\n\t\t\"{{\\n\"\n\t\t\"    /token-type false def\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"token\",\n\t                               \"^.|\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cUnion\",\n\t                               \"^[^\\\"/\\\\{\\\\}]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cUnion\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=cString}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cUnion\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=cCharlit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cUnion\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cUnion\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=cAction}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cUnion\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}{_guest=,,0end}{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cString\",\n\t                               \"^[^\\\\\\\\\\\"]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cString\",\n\t                               \"^\\\\\\\\.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cString\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"iString\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=cString}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"iString\",\n\t                               \"^\\\\)\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"iString\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rule\",\n\t                               \"^[^\\\\{;]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rule\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=cAction}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rule\",\n\t                               \"^;\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"rule\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cActionCommon\",\n\t                               \"^[^\\\"/\\\\{\\\\}]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cActionCommon\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=cString}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cActionCommon\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=cCharlit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cActionCommon\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cActionCommon\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=cAction}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cAction\",\n\t                               \"^[^\\\"/\\\\{\\\\}]+\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cAction\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=cString}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cAction\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=cCharlit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cAction\",\n\t                               \"^/\\\\*\",\n\t                               \"\", \"\", \"{tenter=comment}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cAction\",\n\t                               \"^\\\\{\",\n\t                               \"\", \"\", \"{tenter=cAction}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cAction\",\n\t                               \"^\\\\}\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"type\",\n\t                               \"^N?_[ \\t]*\\\\(\",\n\t                               \"\", \"\", \"{tenter=iString}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"type\",\n\t                               \"^([_a-zA-Z][_a-zA-Z0-9]*)[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    token-type false ne {\\n\"\n\t\t\"        type-dict \\\\1 token-type put\\n\"\n\t\t\"    } if\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"type\",\n\t                               \"^<[ \\t]*([_a-zA-Z][_a-zA-Z0-9 *]*)[ \\t]*>[ \\t\\n]*\",\n\t                               \"\", \"\", \"\"\n\t\t\"{{\\n\"\n\t\t\"    /token-type \\\\1 def\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"type\",\n\t                               \"^\\\"\",\n\t                               \"\", \"\", \"{tenter=cString}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"type\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tenter=cCharlit}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"type\",\n\t                               \"^%\",\n\t                               \"\", \"\", \"{tleave}{_advanceTo=0start}\"\n\t\t\"{{\\n\"\n\t\t\"    /token-type false def\\n\"\n\t\t\"}}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"type\",\n\t                               \"^.|\\n\",\n\t                               \"\", \"\", \"\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCharlit\",\n\t                               \"^[^\\\\\\\\]'\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCharlit\",\n\t                               \"^\\\\\\\\.'\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCharlit\",\n\t                               \"^'\",\n\t                               \"\", \"\", \"{tleave}\", NULL);\n\taddLanguageTagMultiTableRegex (language, \"cCharlit\",\n\t                               \"^.\",\n\t                               \"\", \"\", \"\", NULL);\n}\n\nextern parserDefinition* YACCParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"y\",\n\t\tNULL\n\t};\n\n\tstatic const char *const aliases [] = {\n\t\tNULL\n\t};\n\n\tstatic const char *const patterns [] = {\n\t\tNULL\n\t};\n\n\tstatic kindDefinition YACCKindTable [] = {\n\t\t{\n\t\t  true, 't', \"token\", \"tokens\",\n\t\t},\n\t\t{\n\t\t  true, 'l', \"label\", \"labels\",\n\t\t},\n\t};\n\n\tparserDefinition* const def = parserNew (\"YACC\");\n\n\tdef->versionCurrent= 0;\n\tdef->versionAge    = 0;\n\tdef->enabled       = true;\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->aliases       = aliases;\n\tdef->method        = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->useCork       = CORK_QUEUE;\n\tdef->kindTable     = YACCKindTable;\n\tdef->kindCount     = ARRAY_SIZE(YACCKindTable);\n\tdef->initialize    = initializeYACCParser;\n\n\treturn def;\n}\n"
  },
  {
    "path": "optlib/yacc.ctags",
    "content": "#\n# yacc.ctags --- multitable regex parser for yacc/bison input\n#\n# Copyright (c) 2001-2002, Nick Hibma <n_hibma@van-laarhoven.org>\n# Copyright (c) 2021, Red Hat, Inc.\n# Copyright (c) 2021, Masatake YAMATO\n#\n# Author: Masatake YAMATO <yamato@redhat.com>\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License\n# as published by the Free Software Foundation; either version 2\n# of the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n# USA.\n#\n# The original version of this parser is written in C (+ regex patterns).\n#\n# References:\n#\n# - https://www.gnu.org/software/bison/manual/html_node/Grammar-File.html\n#\n\n--langdef=YACC\n--map-YACC=+.y\n\n#\n# Kind definitions\n#\n\n--kinddef-YACC=t,token,tokens\n--kinddef-YACC=l,label,labels\n\n#\n#\n#\n--_prelude-YACC={{\n    /token-type false def\n    /type-dict 57 dict def\n}}\n\n#\n# Tables declaration\n#\n\n--_tabledef-YACC=toplevel\n--_tabledef-YACC=comment\n--_tabledef-YACC=cPrologue\n--_tabledef-YACC=cCode\n--_tabledef-YACC=grammar\n--_tabledef-YACC=cEpilogue\n--_tabledef-YACC=token\n--_tabledef-YACC=cUnion\n--_tabledef-YACC=cString\n--_tabledef-YACC=iString\n--_tabledef-YACC=rule\n--_tabledef-YACC=cActionCommon\n--_tabledef-YACC=cAction\n--_tabledef-YACC=type\n--_tabledef-YACC=cCharlit\n\n#\n# Tables definitions\n#\n--_mtable-regex-YACC=comment/[^*]+//\n--_mtable-regex-YACC=comment/\\*\\///{tleave}\n--_mtable-regex-YACC=comment/.//\n\n--_mtable-regex-YACC=cPrologue/[^%]+//\n--_mtable-regex-YACC=cPrologue/%\\}//{tleave}{_guest=,,0start}\n--_mtable-regex-YACC=cPrologue/.//\n\n--_mtable-regex-YACC=cActionCommon/[^\"\\/\\{\\}]+//\n--_mtable-regex-YACC=cActionCommon/\"//{tenter=cString}\n--_mtable-regex-YACC=cActionCommon/'//{tenter=cCharlit}\n--_mtable-regex-YACC=cActionCommon/\\/\\*//{tenter=comment}\n--_mtable-regex-YACC=cActionCommon/\\{//{tenter=cAction}\n\n--_mtable-extend-YACC=cAction+cActionCommon\n--_mtable-regex-YACC=cAction/\\}//{tleave}\n\n--_mtable-extend-YACC=cCode+cActionCommon\n--_mtable-regex-YACC=cCode/\\}//{tleave}{_guest=,,0start}\n--_mtable-regex-YACC=cCode/.//\n\n--_mtable-regex-YACC=rule/[^\\{;]+//\n--_mtable-regex-YACC=rule/\\{//{tenter=cAction}\n--_mtable-regex-YACC=rule/;//{tleave}\n--_mtable-regex-YACC=rule/.//\n\n--_mtable-regex-YACC=grammar/%%//{tjump=cEpilogue}{_guest=C,0end,}\n--_mtable-regex-YACC=grammar/([a-zA-Z_.][-a-zA-Z_.0-9]+)[ \\t\\n]*:[ \\t\\n]*/\\1/l/{tenter=rule}{{\n    type-dict \\1 known {\n        type-dict \\1 get . exch typeref:\n    } if\n}}\n--_mtable-regex-YACC=grammar/.//\n\n--_mtable-regex-YACC=cEpilogue/.+//{_guest=,,0end}\n\n--_mtable-regex-YACC=cString/[^\\\\\"]+//\n--_mtable-regex-YACC=cString/\\\\.//\n--_mtable-regex-YACC=cString/\"//{tleave}\n\n--_mtable-regex-YACC=cCharlit/[^\\\\]'//{tleave}\n--_mtable-regex-YACC=cCharlit/\\\\.'//{tleave}\n--_mtable-regex-YACC=cCharlit/'//{tleave}\n--_mtable-regex-YACC=cCharlit/.//\n\n--_mtable-regex-YACC=iString/\"//{tenter=cString}\n--_mtable-regex-YACC=iString/\\)//{tleave}\n--_mtable-regex-YACC=iString/.//\n\n#\n# %token TAG? ( ID NUMBER? STRING? )+ ( TAG ( ID NUMBER? STRING? )+ )*\n# TODO: %left  TAG? ( ID NUMBER?)+ ( TAG ( ID NUMBER? )+ )*\n#       The directives %precedence, %right and %nonassoc behave like\n#       %left.\n#\n--_mtable-regex-YACC=token/N?_[ \\t]*\\(//{tenter=iString}\n--_mtable-regex-YACC=token/([_a-zA-Z][_a-zA-Z0-9]*)[ \\t\\n]*/\\1/t/{{\n    token-type false ne {\n        . token-type typeref:\n    } if\n}}\n# TODO condense multiple whitespaces in type name\n--_mtable-regex-YACC=token/<[ \\t]*([_a-zA-Z][_a-zA-Z0-9 *]*)[ \\t]*>[ \\t\\n]*//{{\n    /token-type \\1 def\n}}\n--_mtable-regex-YACC=token/\"//{tenter=cString}\n--_mtable-regex-YACC=token/'//{tenter=cCharlit}\n--_mtable-regex-YACC=token/-?[ \\t\\n]*(0x)?[0-9]+[ \\t\\n]*//\n--_mtable-regex-YACC=token/%//{tleave}{_advanceTo=0start}{{\n    /token-type false def\n}}\n--_mtable-regex-YACC=token/.|\\n//\n\n--_mtable-extend-YACC=cUnion+cActionCommon\n--_mtable-regex-YACC=cUnion/\\}//{tleave}{_guest=,,0end}{tleave}\n\n#\n# %type  TAG? ( ID | CHAR | STRING )+ ( TAG ( ID | CHAR | STRING )+ )*\n# %nterm TAG? ID+ ( TAG ID+ )*\n#\n--_mtable-regex-YACC=type/N?_[ \\t]*\\(//{tenter=iString}\n--_mtable-regex-YACC=type/([_a-zA-Z][_a-zA-Z0-9]*)[ \\t\\n]*//{{\n    token-type false ne {\n        type-dict \\1 token-type put\n    } if\n}}\n--_mtable-regex-YACC=type/<[ \\t]*([_a-zA-Z][_a-zA-Z0-9 *]*)[ \\t]*>[ \\t\\n]*//{{\n    /token-type \\1 def\n}}\n--_mtable-regex-YACC=type/\"//{tenter=cString}\n--_mtable-regex-YACC=type/'//{tenter=cCharlit}\n--_mtable-regex-YACC=type/%//{tleave}{_advanceTo=0start}{{\n    /token-type false def\n}}\n--_mtable-regex-YACC=type/.|\\n//\n\n--_mtable-regex-YACC=toplevel/\\/\\*//{tenter=comment}\n--_mtable-regex-YACC=toplevel/%token[ \\t\\n]+//{tenter=token}{{\n    /token-type false def\n}}\n--_mtable-regex-YACC=toplevel/%(union)[^\\{]*\\{//{tenter=cUnion}{_guest=C,1start,}\n--_mtable-regex-YACC=toplevel/%(code[^\\{]*)?\\{//{tenter=cCode}{_guest=C,0end,}\n--_mtable-regex-YACC=toplevel/%(type|nterm)[ \\n\\t]*//{tenter=type}{{\n    /token-type false def\n}}\n\n--_mtable-regex-YACC=toplevel/%%//{tjump=grammar}\n--_mtable-regex-YACC=toplevel/[^\\n]*\\n//\n\n# TODO: %initial-action skip?\n#\n# -- Directive: %defines DEFINES-FILE\n#     Same as above, but save in the file DEFINES-FILE.\n#  -- Directive: %language \"LANGUAGE\"\n#  -- Directive: %output \"FILE\"\n#     Generate the parser implementation in FILE.\n"
  },
  {
    "path": "parsers/Makefile",
    "content": "all:\n.SUFFIXES:\n.SUFFIXES: .c .o\n\n.c.o:\n\t$(MAKE) -C .. parsers/$@\n%:\n\t$(MAKE) -C .. $@\n"
  },
  {
    "path": "parsers/abaqus.c",
    "content": "/*\n *   Copyright (c) 2013, Baptiste Pierrat\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your opinion) any later version.\n *\n *   This module contains functions for generating tags for source files\n *   for Abaqus inp files (https://en.wikipedia.org/wiki/Abaqus).\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include <ctype.h>\n#include <string.h>\n\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"routines.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_PART,\n\tK_ASSEMBLY,\n\tK_STEP\n} AbaqusKind;\n\nstatic kindDefinition AbaqusKinds[] = {\n     { true, 'p', \"part\",     \"Parts\" },\n     { true, 'a', \"assembly\", \"Assembly\" },\n     { true, 's', \"step\",     \"Steps\" }\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic int getWord(const char *ref, const char **ptr)\n{\n\tconst char *p = *ptr;\n\n\twhile ((*ref != '\\0') && (*p != '\\0') &&\n\t       (tolower((unsigned char) *ref) == tolower((unsigned char) *p)))\n\t\tref++, p++;\n\n\tif (*ref) return false;\n\n\t*ptr = p;\n\treturn true;\n}\n\n\nstatic void createTag(AbaqusKind kind, const char *buf)\n{\n\tvString *name;\n\n\tif (*buf == '\\0') return;\n\n\tbuf = strstr(buf, \"=\");\n\tif (buf == NULL) return;\n\n\tbuf += 1;\n\n\tif (*buf == '\\0') return;\n\n\tname = vStringNew();\n\n\tdo\n\t{\n\t\tvStringPut(name, *buf);\n\t\t++buf;\n\t} while ((*buf != '\\0') && (*buf != ','));\n\tmakeSimpleTag(name, kind);\n\tvStringDelete(name);\n}\n\n\nstatic void findAbaqusTags(void)\n{\n\tconst char *line;\n\n\twhile ((line = (const char*)readLineFromInputFile()) != NULL)\n\t{\n\t\tconst char *cp = line;\n\n\t\tfor (; *cp != '\\0'; cp++)\n\t\t{\n\t\t\tif (*cp == '*')\n\t\t\t{\n\t\t\t\tcp++;\n\n\t\t\t\t/* Parts*/\n\t\t\t\tif (getWord(\"part\", &cp))\n\t\t\t\t{\n\t\t\t\t\tcreateTag(K_PART, cp);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t/* Assembly */\n\t\t\t\tif (getWord(\"assembly\", &cp))\n\t\t\t\t{\n\t\t\t\t\tcreateTag(K_ASSEMBLY, cp);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t/* Steps */\n\t\t\t\tif (getWord(\"step\", &cp))\n\t\t\t\t{\n\t\t\t\t\tcreateTag(K_STEP, cp);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n\nextern parserDefinition* AbaqusParser (void)\n{\n\tstatic const char *const extensions [] = { \"inp\", NULL };\n\tparserDefinition * def = parserNew (\"Abaqus\");\n\tdef->kindTable  = AbaqusKinds;\n\tdef->kindCount  = ARRAY_SIZE (AbaqusKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findAbaqusTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/abc.c",
    "content": "/*\n*   Copyright (c) 2009, Eric Forgeot\n*\n*   Based on work by Jon Strait\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your opinion) any later version.\n*\n*   This module contains functions for generating tags for Abc files\n*   (https://en.wikipedia.org/wiki/ABC_notation).\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include <ctype.h>\n#include <string.h>\n\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"routines.h\"\n#include \"entry.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\n\ntypedef enum {\n   K_SECTION,\n} AbcKind;\n\nstatic kindDefinition AbcKinds[] = {\n\t{ true, 's', \"section\", \"sections\" },\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void findAbcTags (void)\n{\n\tvString *name = vStringNew();\n\tconst unsigned char *line;\n\n\twhile ((line = readLineFromInputFile()) != NULL)\n\t{\n\t\tif (line[0] == 'T') {\n\t\t\tvStringCatS(name, \" / \");\n\t\t\tvStringCatS(name, (const char *) line);\n\t\t\tmakeSimpleTag(name, K_SECTION);\n\t\t}\n\t\telse {\n\t\t\tvStringClear (name);\n\t\t\tif (! isspace(*line))\n\t\t\t\tvStringCatS(name, (const char*) line);\n\t\t}\n\t}\n\tvStringDelete (name);\n}\n\nextern parserDefinition* AbcParser (void)\n{\n\tstatic const char *const patterns [] = { \"*.abc\", NULL };\n\tstatic const char *const extensions [] = { \"abc\", NULL };\n\tparserDefinition* const def = parserNew (\"Abc\");\n\n\tdef->kindTable = AbcKinds;\n\tdef->kindCount = ARRAY_SIZE (AbcKinds);\n\tdef->patterns = patterns;\n\tdef->extensions = extensions;\n\tdef->parser = findAbcTags;\n\treturn def;\n}\n\n"
  },
  {
    "path": "parsers/ada.c",
    "content": "/* File:          Ada.c\n * Description:   Enables extended Ada parsing support in Exuberant Ctags\n * Version:       0.6\n * Date:          October 26, 2006\n * Author:        A. Aaron Cornelius (ADotAaronDotCorneliusAtgmailDotcom)\n * License:       GPL-2\n *\n * Installation:\n * You must have the Exuberant Ctags source to install this parser.  Once you\n * have the source, place this file into the directory with the rest of the\n * ctags source.  After ada.c is in the correct directory you need to make the\n * following changes so that the ada parser is included when you compile and\n * install ctags:\n *\n * to file source.mak add the line\n *   ada.c \\\n *\n * after\n * SOURCES = \\\n *\n * then add the line\n *   ada.$(OBJECT) \\\n *\n * after\n * OBJECTS = \\\n *\n * to file parsers.h add the line\n *     AdaParser, \\\n *\n * after\n * #define PARSER_LIST \\\n *\n * Then compile and install ctags as normal (usually: './configure', './make',\n * './make install').\n *\n * Changelog:\n *\n * 11/02/2006 - Completed implementation of file scope info and qualified tags\n *              information gathering.\n * 11/02/2006 - Added recognition of private flag in a token for file scope\n *              checking purposes.\n * 10/27/2006 - Added full package scope name when --extra=+q is set.\n * 10/27/2006 - Fixed file scope setting, and added check to verify that tags\n *              with file scope should be included in the tag file.\n * 10/26/2006 - Fixed error which caused infinite loop when parsing some\n *              files.\n * 0.5 - Bugfixes\n * 10/20/2006 - Cleaned up freeAdaTokenList.\n * 10/20/2006 - Fixed error in freeAdaToken that caused the child token lists\n *              to become corrupted when \"separate\" tokens were deleted.\n * 0.4 - Third Revision - 09/25/2006\n * 09/25/2006 - Fixed error in newAdaToken which could cause an error on some\n *              systems when a separate token (which is temporary) gets\n *              created.\n * 09/25/2006 - Change matchFilePos initialization in the findAdaTags\n *              function.\n * 0.3 - Second Revision\n * 06/02/2006 - Added missing EOF checks to prevent infinite loops in the case\n *              of an incomplete Ada (or non-Ada) file being parsed.\n * 06/02/2006 - Added Copyright notice.\n * 0.2 - First Revision\n * 05/26/2006 - Fixed an error where tagging the proper scope of something\n *              declared in an anonymous block or anonymous loop was not\n *              working properly.\n * 05/26/2006 - Fixed an error capturing the name of a 'separate' tag.\n * 05/26/2006 - Fixed the cmp() function so that it finds matches correctly.\n * 05/26/2006 - Fixed some spelling errors.\n * 05/26/2006 - Added explicit skipping of use and with clauses.\n * 0.1 - Initial Release\n *\n * Future Changes:\n * TODO: Add inheritance information?\n * TODO: Add signature gathering?\n *\n * Copyright (C) 2006 A. Aaron Cornelius\n *\n * This program is free software; you can redistribute it and/or\n * modify it under the terms of the GNU General Public License\n * as published by the Free Software Foundation; either version 2\n * of the License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n * USA.\n *\n * References:\n * - https://ada-lang.io/docs/arm\n * - https://www.adahome.com/rm95/\n * - https://cui.unige.ch/isi/bnf/Ada95/BNFindex.html\n */\n\n#include \"general.h\"    /* always include first */\n\n#include <string.h>     /* to declare strxxx() functions */\n#include <ctype.h>      /* to define isxxx() macros */\n\n#include \"parse.h\"      /* always include */\n#include \"read.h\"       /* to define file readLineFromInputFile() */\n#include \"entry.h\"      /* for the tag entry manipulation */\n#include \"routines.h\"   /* for generic malloc/realloc/free routines */\n#include \"debug.h\"      /* for Assert */\n#include \"xtag.h\"\n#include \"trace.h\"\n\n\nstatic bool eof_reached;\n\ntypedef enum eAdaParseMode\n{\n\tADA_ROOT,\n\tADA_DECLARATIONS,\n\tADA_CODE,\n\tADA_EXCEPTIONS,\n\tADA_GENERIC\n} adaParseMode;\n\ntypedef enum eAdaKinds\n{\n\tADA_KIND_UNDEFINED = KIND_GHOST_INDEX,  /* for default/initialization values */\n\tADA_KIND_PACKAGE_SPEC,\n\tADA_KIND_PACKAGE,\n\tADA_KIND_TYPE_SPEC,\n\tADA_KIND_TYPE,\n\tADA_KIND_SUBTYPE_SPEC,\n\tADA_KIND_SUBTYPE,\n\tADA_KIND_RECORD_COMPONENT,\n\tADA_KIND_ENUM_LITERAL,\n\tADA_KIND_VARIABLE_SPEC,\n\tADA_KIND_VARIABLE,\n\tADA_KIND_FORMAL,\n\tADA_KIND_CONSTANT,\n\tADA_KIND_EXCEPTION,\n\tADA_KIND_SUBPROGRAM_SPEC,\n\tADA_KIND_SUBPROGRAM,\n\tADA_KIND_TASK_SPEC,\n\tADA_KIND_TASK,\n\tADA_KIND_PROTECTED_SPEC,\n\tADA_KIND_PROTECTED,\n\tADA_KIND_ENTRY_SPEC,\n\tADA_KIND_ENTRY,\n\tADA_KIND_LABEL,\n\tADA_KIND_IDENTIFIER,\n\tADA_KIND_AUTOMATIC_VARIABLE,\n\tADA_KIND_ANONYMOUS,      /* for non-identified loops and blocks */\n\tADA_KIND_COUNT            /* must be last */\n} adaKind;\n\ntypedef enum {\n\tADA_PACKAGE_SUBUNIT,\n} adaPackageRole;\n\nstatic roleDefinition AdaPackageRoles [] = {\n\t{ true, \"subunit\",\n\t  \"package name referenced in separate()\" },\n};\n\nstatic kindDefinition AdaKinds[] =\n{\n\t{ true,   'P', \"packspec\",    \"package specifications\" },\n\t{ true,   'p', \"package\",     \"packages\",\n\t  .referenceOnly = false, ATTACH_ROLES(AdaPackageRoles) },\n\t{ false,  'T', \"typespec\",    \"type specifications\" },\n\t{ true,   't', \"type\",        \"types\" },\n\t{ false,  'U', \"subspec\",     \"subtype specifications\" },\n\t{ true,   'u', \"subtype\",     \"subtypes\" },\n\t{ true,   'c', \"component\",   \"record type components\" },\n\t{ true,   'l', \"literal\",     \"enum type literals\" },\n\t{ false,  'V', \"varspec\",     \"variable specifications\" },\n\t{ true,   'v', \"variable\",    \"variables\" },\n\t{ true,   'f', \"formal\",      \"generic formal parameters\" },\n\t{ true,   'n', \"constant\",    \"constants\" },\n\t{ true,   'x', \"exception\",   \"user defined exceptions\" },\n\t{ true,   'R', \"subprogspec\", \"subprogram specifications\" },\n\t{ true,   'r', \"subprogram\",  \"subprograms\" },\n\t{ true,   'K', \"taskspec\",    \"task specifications\" },\n\t{ true,   'k', \"task\",        \"tasks\" },\n\t{ true,   'O', \"protectspec\", \"protected data specifications\" },\n\t{ true,   'o', \"protected\",   \"protected data\" },\n\t{ false,  'E', \"entryspec\",   \"task/protected data entry specifications\" },\n\t{ true,   'e', \"entry\",       \"task/protected data entries\" },\n\t{ true,   'b', \"label\",       \"labels\" },\n\t{ true,   'i', \"identifier\",  \"loop/declare identifiers\"},\n\t{ false,  'a', \"autovar\",     \"automatic variables\" },\n\t{ false,  'y', \"anon\",        \"loops and blocks with no identifier\" },\n};\n\ntypedef struct sAdaTokenList\n{\n\tint numTokens;\n\tstruct sAdaTokenInfo *head;\n\tstruct sAdaTokenInfo *tail;\n} adaTokenList;\n\ntypedef struct sAdaTokenInfo\n{\n\tadaKind kind;\n\tbool isSpec;\n\tbool isPrivate;\n\tchar *name;\n\ttagEntryInfo tag;\n\tstruct sAdaTokenInfo *parent;\n\tstruct sAdaTokenInfo *prev;\n\tstruct sAdaTokenInfo *next;\n\tadaTokenList children;\n} adaTokenInfo;\n\ntypedef enum eAdaKeywords\n{\n\tADA_KEYWORD_ACCEPT,\n\tADA_KEYWORD_BEGIN,\n\tADA_KEYWORD_BODY,\n\tADA_KEYWORD_CASE,\n\tADA_KEYWORD_CONSTANT,\n\tADA_KEYWORD_DECLARE,\n\tADA_KEYWORD_DO,\n\tADA_KEYWORD_ELSE,\n\tADA_KEYWORD_ELSIF,\n\tADA_KEYWORD_END,\n\tADA_KEYWORD_ENTRY,\n\tADA_KEYWORD_EXCEPTION,\n\tADA_KEYWORD_FOR,\n\tADA_KEYWORD_FUNCTION,\n\tADA_KEYWORD_GENERIC,\n\tADA_KEYWORD_IF,\n\tADA_KEYWORD_IN,\n\tADA_KEYWORD_IS,\n\tADA_KEYWORD_LOOP,\n\tADA_KEYWORD_NEW,\n\tADA_KEYWORD_NOT,\n\tADA_KEYWORD_OR,\n\tADA_KEYWORD_OVERRIDING,\t\t/* Ada 2005 */\n\tADA_KEYWORD_PACKAGE,\n\tADA_KEYWORD_PRAGMA,\n\tADA_KEYWORD_PRIVATE,\n\tADA_KEYWORD_PROCEDURE,\n\tADA_KEYWORD_PROTECTED,\n\tADA_KEYWORD_RECORD,\n\tADA_KEYWORD_RENAMES,\n\tADA_KEYWORD_SELECT,\n\tADA_KEYWORD_SEPARATE,\n\tADA_KEYWORD_SUBTYPE,\n\tADA_KEYWORD_TASK,\n\tADA_KEYWORD_THEN,\n\tADA_KEYWORD_TYPE,\n\tADA_KEYWORD_UNTIL,\n\tADA_KEYWORD_USE,\n\tADA_KEYWORD_WHEN,\n\tADA_KEYWORD_WHILE,\n\tADA_KEYWORD_WITH\n} adaKeyword;\n\nstatic const char *AdaKeywords[] =\n{\n\t\"accept\",\n\t\"begin\",\n\t\"body\",\n\t\"case\",\n\t\"constant\",\n\t\"declare\",\n\t\"do\",\n\t\"else\",\n\t\"elsif\",\n\t\"end\",\n\t\"entry\",\n\t\"exception\",\n\t\"for\",\n\t\"function\",\n\t\"generic\",\n\t\"if\",\n\t\"in\",\n\t\"is\",\n\t\"loop\",\n\t\"new\",\n\t\"not\",\n\t\"or\",\n\t\"overriding\",\n\t\"package\",\n\t\"pragma\",\n\t\"private\",\n\t\"procedure\",\n\t\"protected\",\n\t\"record\",\n\t\"renames\",\n\t\"select\",\n\t\"separate\",\n\t\"subtype\",\n\t\"task\",\n\t\"then\",\n\t\"type\",\n\t\"until\",\n\t\"use\",\n\t\"when\",\n\t\"while\",\n\t\"with\"\n};\n\n\n/* variables for managing the input string, position as well as input line\n * number and position */\nstatic const char *line;\nstatic int lineLen;\nstatic int pos;\nstatic unsigned long matchLineNum;\nstatic MIOPos matchFilePos;\n\n/* utility functions */\nstatic void makeSpec (adaKind *kind);\n\n/* prototypes of functions for manipulating the Ada tokens */\nstatic adaTokenInfo *newAdaToken (const char *name, int len,\n\t\t\t\t\t\t\t\t  adaKind kind, bool isSpec,\n\t\t\t\t\t\t\t\t  adaTokenInfo *parent);\nstatic adaTokenInfo *newAdaTokenFull (const char *name, int len,\n\t\t\t\t\t\t\t\t\t  adaKind kind, int role, bool isSpec,\n\t\t\t\t\t\t\t\t\t  adaTokenInfo *parent);\nstatic void freeAdaToken (adaTokenList *list, adaTokenInfo *token);\nstatic void appendAdaToken (adaTokenInfo *parent, adaTokenInfo *token);\n\n/* token list processing function prototypes */\nstatic void initAdaTokenList (adaTokenList *list);\nstatic void freeAdaTokenList (adaTokenList *list);\nstatic void appendAdaTokenList (adaTokenInfo *parent, adaTokenList *children);\n\n/* prototypes of functions for moving through the DEFINED text */\nstatic void readNewLine (void);\nstatic void movePos (int amount);\nstatic bool cmp (const char *buf, int len, const char *match);\nstatic bool adaCmp (const char *match);\nstatic bool adaKeywordCmp (adaKeyword keyword);\nstatic void skipUntilWhiteSpace (void);\nstatic void skipWhiteSpace (void);\nstatic void skipComments (void);\nstatic void skipCommentsAndStringLiteral (void);\nstatic void skipPast (const char *past);\nstatic void skipPastKeyword (adaKeyword keyword);\nstatic void skipPastWord (void);\n\ntypedef bool (* skipCompFn) (void *data);\nstatic void skipPastLambda (skipCompFn cmpfn, void *data);\n\n#ifdef DO_TRACING\nstatic void dumpLine (void);\nstatic void dumpMode (adaParseMode mode);\nstatic void dumpToken (adaTokenInfo *token);\nstatic void dumpTokenList (adaTokenList *list);\nstatic void dumpKind (adaKind kind);\n#endif\n\nstruct cmpKeywordOrWordDataElt\n{\n\tenum eltType\n\t{\n\t\tELT_KEYWORD,\n\t\tELT_WORD,\n\t} type;\n\tunion\n\t{\n\t\tadaKeyword keyword;\n\t\tconst char* word;\n\t} u;\n};\nstatic struct cmpKeywordOrWordDataElt *skipPastKeywordOrWord (struct cmpKeywordOrWordDataElt * elt,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  int count);\n\n/* prototypes of functions for parsing the high-level Ada constructs */\nstatic adaTokenInfo *adaParseBlock (adaTokenInfo *parent, adaKind kind);\nstatic adaTokenInfo *adaParseSubprogram (adaTokenInfo *parent, adaKind kind);\nstatic adaTokenInfo *adaParseType (adaTokenInfo *parent, adaKind kind);\nstatic adaTokenInfo *adaParseVariables (adaTokenInfo *parent, adaKind kind);\nstatic adaTokenInfo *adaParseLoopVar (adaTokenInfo *parent);\nstatic adaTokenInfo *adaParse (adaParseMode mode, adaTokenInfo *parent);\n\n/* prototypes of the functions used by ctags */\nstatic void storeAdaTags (adaTokenInfo *token, const char *parentScope);\nstatic void findAdaTags (void);\n\nstatic void makeSpec (adaKind *kind)\n{\n\tswitch (*kind)\n\t{\n\tcase ADA_KIND_PACKAGE:\n\t\t*kind = ADA_KIND_PACKAGE_SPEC;\n\t\tbreak;\n\n\tcase ADA_KIND_TYPE:\n\t\t*kind = ADA_KIND_TYPE_SPEC;\n\t\tbreak;\n\n\tcase ADA_KIND_SUBTYPE:\n\t\t*kind = ADA_KIND_SUBTYPE_SPEC;\n\t\tbreak;\n\n\tcase ADA_KIND_VARIABLE:\n\t\t*kind = ADA_KIND_VARIABLE_SPEC;\n\t\tbreak;\n\n\tcase ADA_KIND_SUBPROGRAM:\n\t\t*kind = ADA_KIND_SUBPROGRAM_SPEC;\n\t\tbreak;\n\n\tcase ADA_KIND_TASK:\n\t\t*kind = ADA_KIND_TASK_SPEC;\n\t\tbreak;\n\n\tcase ADA_KIND_PROTECTED:\n\t\t*kind = ADA_KIND_PROTECTED_SPEC;\n\t\tbreak;\n\n\tcase ADA_KIND_ENTRY:\n\t\t*kind = ADA_KIND_ENTRY_SPEC;\n\t\tbreak;\n\n\tdefault:\n\t\t*kind = ADA_KIND_UNDEFINED;\n\t\tbreak;\n\t}\n}\n\nstatic adaTokenInfo *newAdaTokenFull (const char *name, int len, adaKind kind, int role,\n\t\t\t\t\t\t\t\t\t  bool isSpec, adaTokenInfo *parent)\n{\n\tchar *tmpName = NULL;\n\tadaTokenInfo *token = xMalloc (1, adaTokenInfo);\n\n\ttoken->name = NULL;\n\n\tif (name != NULL && len != 0)\n\t{\n\t\ttmpName = xMalloc (len + 1, char);\n\t\tstrncpy (tmpName, name, len);\n\t\ttmpName[len] = '\\0';\n\t}\n\n\t/* init the tag */\n\tinitTagEntry (&token->tag, tmpName, ADA_KIND_UNDEFINED);\n\n\ttoken->kind = kind;\n\ttoken->isSpec = isSpec;\n\ttoken->isPrivate = false;\n\n\t/* set the token data */\n\ttoken->name = tmpName;\n\ttoken->parent = parent;\n\n\t/* Now set the file scope for this tag.  A tag has file scope if its direct\n\t * parent is a package/subprogram/protected/task spec, or if it it's parent\n\t * is UNDEFINED (a 'root' token), and if this is not in a 'private' section\n\t * of that spec. */\n\tif ((parent != NULL) && (parent->isPrivate == false) &&\n\t\t((parent->kind == ADA_KIND_UNDEFINED) ||\n\t\t (parent->kind == ADA_KIND_PACKAGE && isRoleAssigned(&parent->tag, ADA_PACKAGE_SUBUNIT)) ||\n\t\t ((parent->isSpec == true) && ((parent->kind == ADA_KIND_PACKAGE) ||\n\t\t\t\t\t\t\t\t\t   (parent->kind == ADA_KIND_SUBPROGRAM) ||\n\t\t\t\t\t\t\t\t\t   (parent->kind == ADA_KIND_PROTECTED) ||\n\t\t\t\t\t\t\t\t\t   (parent->kind == ADA_KIND_TASK)))))\n\t{\n\t\ttoken->tag.isFileScope = false;\n\t}\n\telse\n\t{\n\t\tmarkTagExtraBit (&token->tag, XTAG_FILE_SCOPE);\n\t\ttoken->tag.isFileScope = true;\n\t}\n\n\t/* add the kind info - unless this is a SEPARATE kind, in which case keep\n\t * them blank because they get filled in later. */\n\tif (kind > ADA_KIND_UNDEFINED)\n\t{\n\t\ttoken->tag.kindIndex = kind;\n\t\tif (role != ROLE_DEFINITION_INDEX)\n\t\t\tassignRole(&token->tag, role);\n\t}\n\telse\n\t{\n\t\ttoken->tag.kindIndex = KIND_GHOST_INDEX;\n\t}\n\n\t/* setup the parent and children pointers */\n\tinitAdaTokenList (&token->children);\n\tappendAdaToken (parent, token);\n\n\treturn token;\n}\n\nstatic adaTokenInfo *newAdaToken (const char *name, int len, adaKind kind,\n\t\t\t\t\t\t\t\t  bool isSpec, adaTokenInfo *parent)\n{\n\treturn newAdaTokenFull (name, len, kind, ROLE_DEFINITION_INDEX, isSpec, parent);\n}\n\nstatic void freeAdaToken (adaTokenList *list, adaTokenInfo *token)\n{\n\tif (token != NULL)\n\t{\n\t\tif (token->name != NULL)\n\t\t{\n\t\t\teFree ((void *) token->name);\n\t\t\ttoken->name = NULL;\n\t\t}\n\n\t\t/* before we delete this token, clean up it's children */\n\t\tfreeAdaTokenList (&token->children);\n\n\t\t/* move the next token in the list to this token's spot */\n\t\tif (token->prev != NULL)\n\t\t{\n\t\t\ttoken->prev->next = token->next;\n\t\t}\n\t\telse if (list != NULL)\n\t\t{\n\t\t\t/* Token to remove is head in list as 'token->prev == NULL' */\n\t\t\tAssert (token->prev == NULL);\n\t\t\tlist->head = token->next;\n\t\t}\n\n\t\t/* move the previous token in the list to this token's spot */\n\t\tif (token->next != NULL)\n\t\t{\n\t\t\ttoken->next->prev = token->prev;\n\t\t}\n\t\telse if (list != NULL)\n\t\t{\n\t\t\t/* Token to remove is tail of list as 'token->next == NULL') */\n\t\t\tAssert (token->next == NULL);\n\t\t\tlist->tail = token->prev;\n\t\t}\n\n\t\t/* decrement the list count */\n\t\tif (list != NULL)\n\t\t{\n\t\t\tlist->numTokens--;\n\t\t}\n\n\t\t/* now that this node has had everything hanging off of it rearranged,\n\t\t * delete this node */\n\t\teFree (token);\n\t}\n}\n\nstatic void appendAdaToken (adaTokenInfo *parent, adaTokenInfo *token)\n{\n\t/* if the parent or newChild is NULL there is nothing to be done */\n\tif (parent != NULL && token != NULL)\n\t{\n\t\t/* we just need to add this to the list and set a parent pointer */\n\t\tparent->children.numTokens++;\n\t\ttoken->parent = parent;\n\t\ttoken->prev = parent->children.tail;\n\t\ttoken->next = NULL;\n\n\t\tif (parent->children.tail != NULL)\n\t\t{\n\t\t\tparent->children.tail->next = token;\n\t\t}\n\n\t\t/* the token that was just added always becomes the last token int the\n\t\t * list */\n\t\tparent->children.tail = token;\n\n\t\tif (parent->children.head == NULL)\n\t\t{\n\t\t\tparent->children.head = token;\n\t\t}\n\t}\n}\n\nstatic void initAdaTokenList (adaTokenList *list)\n{\n\tif (list != NULL)\n\t{\n\t\tlist->numTokens = 0;\n\t\tlist->head = NULL;\n\t\tlist->tail = NULL;\n\t}\n}\n\nstatic void freeAdaTokenList (adaTokenList *list)\n{\n\tif (list != NULL)\n\t{\n\t\twhile (list->head != NULL)\n\t\t{\n\t\t\tfreeAdaToken (list, list->head);\n\t\t}\n\t}\n}\n\nstatic void appendAdaTokenList (adaTokenInfo *parent, adaTokenList *children)\n{\n\tadaTokenInfo *tmp = NULL;\n\n\tif (parent != NULL && children != NULL)\n\t{\n\t\twhile (children->head != NULL)\n\t\t{\n\t\t\ttmp = children->head->next;\n\t\t\tappendAdaToken (parent, children->head);\n\n\t\t\t/* we just need to worry about setting the head pointer properly during\n\t\t\t * the list iteration.  The node's pointers will get set properly by the\n\t\t\t * appendAdaToken () function */\n\t\t\tchildren->head = tmp;\n\t\t}\n\n\t\t/* now that we have added all nodes from the children list to the parent\n\t\t * node, zero out the children list */\n\t\tinitAdaTokenList (children);\n\t}\n}\n\nstatic void readNewLine (void)\n{\n\twhile (true)\n\t{\n\t\tline = (const char *) readLineFromInputFile ();\n\t\tpos = 0;\n\n\t\tif (line == NULL)\n\t\t{\n\t\t\tlineLen = 0;\n\t\t\teof_reached = true;\n\t\t\treturn;\n\t\t}\n\n\t\tlineLen = strlen (line);\n\n\t\tif (lineLen > 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nstatic void movePos (int amount)\n{\n\tpos += amount;\n\tif (!eof_reached && pos >= lineLen)\n\t{\n\t\treadNewLine ();\n\t}\n}\n\n/* a macro for checking for comments... This isn't the same as the check in\n * cmp () because comments don't have to have whitespace or separation-type\n * characters following the \"--\" */\n#define isAdaComment(buf, pos, len)\t\t\t\t\t\t\t\t\t\t\\\n\t(((pos) == 0 || (!isalnum ((unsigned char) (buf)[(pos) - 1]) &&\t\t\\\n\t                 (buf)[(pos) - 1] != '_')) &&\t\t\t\t\t\t\\\n\t (pos) < (len) &&\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t strncasecmp (&(buf)[(pos)], \"--\", strlen (\"--\")) == 0)\n#define isAdaStringLiteral(buf, pos, len)\t\t\\\n\t(((pos) < (len)) && ((buf)[(pos)] == '\"'))\n#define isAdaCharLiteral(buf, pos, len)\t\t\t\t\\\n\t(((pos) < (len - 2)) && ((buf)[(pos)] == '\\'')\t\\\n\t && ((buf)[(pos + 2)] == '\\''))\n\n\nstatic bool cmp (const char *buf, int len, const char *match)\n{\n\tbool status = false;\n\tint matchLen;\n\n\t/* if we are trying to match nothing, that is always true */\n\tif (match == NULL)\n\t{\n\t\treturn true;\n\t}\n\n\t/* first check to see if the buffer is empty, if it is, return false */\n\tif (buf == NULL)\n\t{\n\t\treturn status;\n\t}\n\n\tmatchLen = strlen (match);\n\n\t/* A match only happens the number of chars in the matching string match,\n\t * and whitespace follows... Which means we also must check to see if the\n\t * end of the line is after the matching string.  Also check for some\n\t * separation characters such as (, ), :, or ; */\n\tif ((strncasecmp (buf, match, matchLen) == 0) &&\n\t\t(matchLen == len ||\n\t\t (matchLen < len &&\n\t\t  (isspace ((unsigned char) buf[matchLen]) || buf[matchLen] == '(' ||\n\t\t   buf[matchLen] == ')' || buf[matchLen] == ':' ||\n\t\t   buf[matchLen] == ';'))))\n\t{\n\t\tstatus = true;\n\t}\n\n\treturn status;\n}\n\nstatic bool adaCmp (const char *match)\n{\n\tbool status = false;\n\n\t/* first check to see if line is empty */\n\tif (line == NULL)\n\t{\n\t\teof_reached = true;\n\t\treturn status;\n\t}\n\n\tstatus = cmp (&line[pos], lineLen - pos, match);\n\n\t/* if we match, increment the position pointer */\n\tif (status == true && match != NULL)\n\t{\n\t\tmatchLineNum = getInputLineNumber ();\n\t\tmatchFilePos = getInputFilePosition ();\n\n\t\tmovePos ((strlen (match)));\n\t}\n\n\treturn status;\n}\n\n/* just a version of adaCmp that is a bit more optimized for keywords */\nstatic bool adaKeywordCmp (adaKeyword keyword)\n{\n\tbool status = false;\n\n\t/* first check to see if line is empty, if it is */\n\tif (line == NULL)\n\t{\n\t\teof_reached = true;\n\t\treturn status;\n\t}\n\n\tstatus = cmp (&line[pos], lineLen - pos, AdaKeywords[keyword]);\n\n\t/* if we match, increment the position pointer */\n\tif (status == true)\n\t{\n\t\tmatchLineNum = getInputLineNumber ();\n\t\tmatchFilePos = getInputFilePosition ();\n\n\t\tmovePos ((strlen (AdaKeywords[keyword])));\n\t}\n\n\treturn status;\n}\n\nstatic void skipUntilWhiteSpace (void)\n{\n\t/* first check for a comment line, because this would cause the isspace\n\t * check to be true immediately */\n\tskipComments ();\n\n\twhile (!eof_reached && !isspace ((unsigned char) line[pos]))\n\t{\n\t\t/* don't use movePos () because if we read in a new line with this function\n\t\t * we need to stop */\n\t\tpos++;\n\n\t\t/* the newline counts as whitespace so read in the newline and return\n\t\t * immediately */\n\t\tif (pos >= lineLen)\n\t\t{\n\t\t\tline = (const char *) readLineFromInputFile ();\n\t\t\tpos = 0;\n\n\t\t\tif (line == NULL)\n\t\t\t{\n\t\t\t\tlineLen = 0;\n\t\t\t\teof_reached = true;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlineLen = strlen (line);\n\n\t\t\treturn;\n\t\t}\n\n\t\t/* now check for comments here */\n\t\tskipComments ();\n\t}\n}\n\nstatic void skipWhiteSpace (void)\n{\n\t/* first check for a comment line, because this would cause the isspace\n\t * check to fail immediately */\n\tskipComments ();\n\n\twhile (!eof_reached && isspace ((unsigned char) line[pos]))\n\t{\n\t\tmovePos (1);\n\n\t\t/* now check for comments here */\n\t\tskipComments ();\n\t}\n}\n\nstatic void skipComments (void)\n{\n\twhile (!eof_reached && isAdaComment (line, pos, lineLen))\n\t{\n\t\treadNewLine ();\n\t}\n}\n\n/* Return true if skipped over a string literal (or char literal).\n * Return false if no string literal (nor char literal) is found. */\nstatic bool skipStringLiteral (void)\n{\n\tif (!eof_reached && isAdaStringLiteral (line, pos, lineLen))\n\t{\n\t\tdo {\n\t\t\tmovePos (1);\n\t\t} while (!eof_reached && !isAdaStringLiteral (line, pos, lineLen));\n\n\t\t/* Go to the next char of \" */\n\t\tmovePos (1);\n\n\t\treturn true;\n\t}\n\telse if (!eof_reached && isAdaCharLiteral (line, pos, lineLen))\n\t{\n\t\tmovePos (3);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic void skipCommentsAndStringLiteral (void)\n{\n\twhile (true)\n\t{\n\t\tskipComments ();\n\t\tif (!skipStringLiteral ())\n\t\t\tbreak;\n\t}\n}\n\nstatic void skipPast (const char *past)\n{\n\t/* first check for a comment line, because this would cause the isspace\n\t * check to fail immediately */\n\tskipCommentsAndStringLiteral ();\n\n\t/* now look for the keyword */\n\twhile (!eof_reached && !adaCmp (past))\n\t{\n\t\tmovePos (1);\n\n\t\t/* now check for comments here */\n\t\tskipCommentsAndStringLiteral ();\n\t}\n}\n\nstatic void skipPastKeyword (adaKeyword keyword)\n{\n\t/* first check for a comment line, because this would cause the isspace\n\t * check to fail immediately */\n\tskipComments ();\n\n\t/* now look for the keyword */\n\twhile (!eof_reached && !adaKeywordCmp (keyword))\n\t{\n\t\tmovePos (1);\n\n\t\t/* now check for comments here */\n\t\tskipComments ();\n\t}\n}\n\nstatic void skipPastWord (void)\n{\n\t/* first check for a comment line, because this would cause the isspace\n\t * check to fail immediately */\n\tskipComments ();\n\n\t/* now increment until we hit a non-word character... Specifically,\n\t * whitespace, '(', ')', ':', and ';' */\n\twhile (!eof_reached && !isspace ((unsigned char) line[pos]) &&\n\t\t   line[pos] != '(' && line[pos] != ')' && line[pos] != ':' &&\n\t\t   line[pos] != ';')\n\t{\n\t\t/* don't use movePos () because if we read in a new line with this function\n\t\t * we need to stop */\n\t\tpos++;\n\n\t\t/* the newline counts as whitespace so read in the newline and return\n\t\t * immediately */\n\t\tif (pos >= lineLen)\n\t\t{\n\t\t\tline = (const char *) readLineFromInputFile ();\n\t\t\tpos = 0;\n\n\t\t\tif (line == NULL)\n\t\t\t{\n\t\t\t\tlineLen = 0;\n\t\t\t\teof_reached = true;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlineLen = strlen (line);\n\n\t\t\treturn;\n\t\t}\n\n\t\t/* now check for comments here */\n\t\tskipComments ();\n\t}\n}\n\nstatic void skipPastLambda (skipCompFn cmpfn, void *data)\n{\n\t/* first check for a comment line, because this would cause the isspace\n\t * check to fail immediately */\n\tskipCommentsAndStringLiteral ();\n\n\t/* now call the predicate */\n\twhile (!eof_reached && !cmpfn (data))\n\t{\n\t\tmovePos (1);\n\n\t\t/* now check for comments here */\n\t\tskipCommentsAndStringLiteral ();\n\t}\n}\n\nstruct cmpKeywordOrWordData\n{\n\tstruct cmpKeywordOrWordDataElt *found;\n\tint count;\n\tstruct cmpKeywordOrWordDataElt *elt;\n};\n\nstatic bool cmpKeywordOrWord (void *data)\n{\n\tstruct cmpKeywordOrWordData *cmdData = data;\n\n\tcmdData->found = NULL;\n\tfor (int i = 0; i < cmdData->count; i++)\n\t{\n\t\tif (cmdData->elt[i].type == ELT_KEYWORD)\n\t\t{\n\t\t\tif (adaKeywordCmp (cmdData->elt[i].u.keyword))\n\t\t\t{\n\t\t\t\tcmdData->found = cmdData->elt + i;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\telse if (cmdData->elt[i].type == ELT_WORD)\n\t\t{\n\t\t\tif (adaCmp (cmdData->elt[i].u.word))\n\t\t\t{\n\t\t\t\tcmdData->found = cmdData->elt + i;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tAssertNotReached ();\n\t}\n\treturn false;\n}\n\nstatic struct cmpKeywordOrWordDataElt *skipPastKeywordOrWord (struct cmpKeywordOrWordDataElt * elt,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  int count)\n{\n\tstruct cmpKeywordOrWordData data = {\n\t\t.found = NULL,\n\t\t.count = count,\n\t\t.elt = elt\n\t};\n\tskipPastLambda (cmpKeywordOrWord, &data);\n\treturn data.found;\n}\n\nstatic adaTokenInfo *adaParseBlock (adaTokenInfo *parent, adaKind kind)\n{\n\tint i;\n\tadaTokenInfo *token;\n\tbool isSpec = true;\n\n\tskipWhiteSpace ();\n\n\t/* if the next word is body, this is not a package spec */\n\tif (adaKeywordCmp (ADA_KEYWORD_BODY))\n\t{\n\t\tisSpec = false;\n\t}\n\t/* if the next word is \"type\" then this has to be a task or protected spec */\n\telse if (adaKeywordCmp (ADA_KEYWORD_TYPE) &&\n\t\t\t (kind != ADA_KIND_PROTECTED && kind != ADA_KIND_TASK))\n\t{\n\t\t/* if this failed to validate then we should just fail */\n\t\treturn NULL;\n\t}\n\tskipWhiteSpace ();\n\n\t/* we are at the start of what should be the tag now... But we have to get\n\t * it's length.  So loop until we hit whitespace, init the counter to 1\n\t * since we know that the current position is not whitespace */\n\tfor (i = 1; (pos + i) < lineLen &&\n\t            !isspace ((unsigned char) line[pos + i]) &&\n\t            line[pos + i] != '(' && line[pos + i] != ';'; i++);\n\n\t/* we have reached the tag of the package, so create the tag */\n\ttoken = newAdaToken (&line[pos], i, kind, isSpec, parent);\n\n\tmovePos (i);\n\tskipWhiteSpace ();\n\n\t/* task and protected types are allowed to have discriminants */\n\tif (!eof_reached && line[pos] == '(')\n\t{\n\t\twhile (!eof_reached && line[pos] != ')')\n\t\t{\n\t\t\tmovePos (1);\n\t\t\tadaParseVariables (token, ADA_KIND_AUTOMATIC_VARIABLE);\n\t\t}\n\t\tmovePos (1);\n\t}\n\n\t/* we must parse until we hit the \"is\" string to reach the end of\n\t * this package declaration, or a \"renames\" keyword */\n\twhile (token != NULL)\n\t{\n\t\tskipWhiteSpace ();\n\n\t\tif (adaKeywordCmp (ADA_KEYWORD_IS))\n\t\t{\n\t\t\tskipWhiteSpace ();\n\n\t\t\tif (adaKeywordCmp (ADA_KEYWORD_SEPARATE))\n\t\t\t{\n\t\t\t\t/* if the next word is the keyword \"separate\", don't create the tag\n\t\t\t\t * since it will be defined elsewhere */\n\t\t\t\tfreeAdaToken (&parent->children, token);\n\t\t\t\ttoken = NULL;\n\n\t\t\t\t/* move past the \";\" ending this declaration */\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_NEW))\n\t\t\t{\n\t\t\t\tstruct cmpKeywordOrWordDataElt *elt;\n\n\t\t\t\telt = skipPastKeywordOrWord ((struct cmpKeywordOrWordDataElt []) {{\n\t\t\t\t\t\t\t.type = ELT_KEYWORD,\n\t\t\t\t\t\t\t.u.keyword = ADA_KEYWORD_WITH,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t.type = ELT_WORD,\n\t\t\t\t\t\t\t.u.word = \";\",\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 2);\n\n\t\t\t\tif (elt && elt->type == ELT_KEYWORD)\n\t\t\t\t\tadaParse (ADA_DECLARATIONS, token);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tadaParse (ADA_DECLARATIONS, token);\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\t\telse if (adaKeywordCmp (ADA_KEYWORD_RENAMES))\n\t\t{\n\t\t\tskipPast (\";\");\n\t\t\tbreak;\n\t\t}\n\t\telse if (adaCmp (\";\"))\n\t\t{\n\t\t\ttoken->isSpec = true;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* nothing found, move to the next word */\n\t\t\tskipUntilWhiteSpace ();\n\t\t}\n\n\t\tif (eof_reached)\n\t\t{\n\t\t\tfreeAdaToken (&parent->children, token);\n\t\t\ttoken = NULL;\n\t\t}\n\t}\n\n\treturn token;\n}\n\nstatic adaTokenInfo *adaParseSubprogram (adaTokenInfo *parent, adaKind kind)\n{\n\tint i;\n\tadaTokenInfo *token;\n\tadaTokenInfo *tmpToken = NULL;\n\n\tskipWhiteSpace ();\n\n\t/* we are at the start of what should be the tag now... But we have to get\n\t * it's length.  So loop until we hit whitespace or the beginning of the\n\t * parameter list.  Init the counter to 1 * since we know that the current\n\t * position is not whitespace */\n\tfor (i = 1; (pos + i) < lineLen &&\n\t            !isspace ((unsigned char) line[pos + i]) &&\n\t            line[pos + i] != '(' && line[pos + i] != ';'; i++);\n\n\t/* we have reached the tag of the subprogram, so create the tag... Init the\n\t * isSpec flag to false and we will adjust it when we see if there is an\n\t * \"is\", \"do\" or a \";\" following the tag */\n\ttoken = newAdaToken (&line[pos], i, kind, false, parent);\n\n\t/* move the line position */\n\tmovePos (i);\n\tskipWhiteSpace ();\n\n\t/* if we find a '(' grab any parameters */\n\tif (!eof_reached && line[pos] == '(' && token != NULL)\n\t{\n\t\twhile (!eof_reached && line[pos] != ')')\n\t\t{\n\t\t\tmovePos (1);\n\t\t\ttmpToken = adaParseVariables (token, ADA_KIND_AUTOMATIC_VARIABLE);\n\t\t}\n\t\tmovePos (1);\n\n\t\t/* check to see if anything was received... If this is an entry this may\n\t\t * have a 'discriminant' and not have any parameters in the first\n\t\t * parenthesis pair, so check again if this was the case*/\n\t\tif (kind == ADA_KIND_ENTRY && tmpToken == NULL)\n\t\t{\n\t\t\t/* skip any existing whitespace and see if there is a second parenthesis\n\t\t\t * pair */\n\t\t\tskipWhiteSpace ();\n\n\t\t\tif (!eof_reached && line[pos] == '(')\n\t\t\t{\n\t\t\t\twhile (!eof_reached && line[pos] != ')')\n\t\t\t\t{\n\t\t\t\t\tmovePos (1);\n\t\t\t\t\tadaParseVariables (token, ADA_KIND_AUTOMATIC_VARIABLE);\n\t\t\t\t}\n\t\t\t\tmovePos (1);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* loop infinitely until we hit a \"is\", \"do\" or \";\", this will skip over\n\t * the returns keyword, returned-type for functions as well as any one of a\n\t * myriad of keyword qualifiers */\n\twhile (!eof_reached && token != NULL)\n\t{\n\t\tskipWhiteSpace ();\n\n\t\tif (adaKeywordCmp (ADA_KEYWORD_IS))\n\t\t{\n\t\t\tskipWhiteSpace ();\n\n\t\t\tif (adaKeywordCmp (ADA_KEYWORD_SEPARATE))\n\t\t\t{\n\t\t\t\t/* if the next word is the keyword \"separate\", don't create the tag\n\t\t\t\t * since it will be defined elsewhere */\n\t\t\t\tfreeAdaToken (&parent->children, token);\n\t\t\t\ttoken = NULL;\n\n\t\t\t\t/* move past the \";\" ending this declaration */\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_NEW))\n\t\t\t{\n\t\t\t\t/* if this is a \"new\" something then no need to parse */\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\t\t\telse if (!eof_reached && line[pos] == '(')\n\t\t\t{\n\t\t\t\t/* '(' is the starter of an expression function. */\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tadaParse (ADA_DECLARATIONS, token);\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\t\telse if (adaKeywordCmp (ADA_KEYWORD_RENAMES))\n\t\t{\n\t\t\tskipPast (\";\");\n\t\t\tbreak;\n\t\t}\n\t\telse if (adaKeywordCmp (ADA_KEYWORD_DO))\n\t\t{\n\t\t\t/* do is the keyword for the beginning of a task entry */\n\t\t\tadaParse (ADA_CODE, token);\n\t\t\tbreak;\n\t\t}\n\t\telse if (adaCmp (\";\"))\n\t\t{\n\t\t\t/* this is just a spec then, so set the flag in the token */\n\t\t\ttoken->isSpec = true;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* nothing found, move to the next word */\n\t\t\tmovePos (1); /* make sure to advance even if we aren't actually on a word */\n\t\t\tskipPastWord ();\n\t\t}\n\t}\n\n\treturn token;\n}\n\nstatic adaTokenInfo *adaParseType (adaTokenInfo *parent, adaKind kind)\n{\n\tint i;\n\tadaTokenInfo *token = NULL;\n\n\tskipWhiteSpace ();\n\n\t/* get the name of the type */\n\tfor (i = 1; (pos + i) < lineLen &&\n\t            !isspace ((unsigned char) line[pos + i]) &&\n\t            line[pos + i] != '(' && line[pos + i] != ';'; i++);\n\n\ttoken = newAdaToken (&line[pos], i, kind, false, parent);\n\n\tmovePos (i);\n\tskipWhiteSpace ();\n\n\tif (!eof_reached && line[pos] == '(')\n\t{\n\t\t/* in this case there is a discriminant to this type, gather the\n\t\t * variables */\n\t\twhile (!eof_reached && line[pos] != ')')\n\t\t{\n\t\t\tmovePos (1);\n\t\t\tadaParseVariables (token, ADA_KIND_AUTOMATIC_VARIABLE);\n\t\t}\n\t\tmovePos (1);\n\t\tskipWhiteSpace ();\n\t}\n\n\t/* check to see what is next, if it is not \"is\" then just skip to the end of\n\t * the statement and register this as a 'spec' */\n\tif (adaKeywordCmp (ADA_KEYWORD_IS))\n\t{\n\t\tskipWhiteSpace ();\n\t\t/* check to see if this may be a record or an enumeration */\n\t\tif (!eof_reached && line[pos] == '(')\n\t\t{\n\t\t\tmovePos (1);\n\t\t\tadaParseVariables (token, ADA_KIND_ENUM_LITERAL);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Parsing following form here.\n\t\t\t *\n\t\t\t * A. type foo is record ...;\n\t\t\t * B. type foo is new bar with record ...;\n\t\t\t * C. type foo is new bar;\n\t\t\t */\n\t\t\tif (adaKeywordCmp (ADA_KEYWORD_NEW))\n\t\t\t{\n\t\t\t\t/* B and C */\n\t\t\t\tstruct cmpKeywordOrWordDataElt *elt;\n\t\t\t\telt = skipPastKeywordOrWord ((struct cmpKeywordOrWordDataElt []) {{\n\t\t\t\t\t\t\t.type = ELT_KEYWORD,\n\t\t\t\t\t\t\t.u.keyword = ADA_KEYWORD_WITH,\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t.type = ELT_WORD,\n\t\t\t\t\t\t\t.u.word = \";\",\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 2);\n\t\t\t\tif (elt && elt->type == ELT_WORD)\n\t\t\t\t{\n\t\t\t\t\t/* C */\n\t\t\t\t\treturn token;\n\t\t\t\t}\n\n\t\t\t\t/* B */\n\t\t\t\tskipWhiteSpace ();\n\t\t\t}\n\t\t\tif (adaKeywordCmp (ADA_KEYWORD_RECORD))\n\t\t\t{\n\t\t\t\t/* A and B */\n\t\t\t\t/* until we hit \"end record\" we need to gather type variables */\n\t\t\t\twhile (!eof_reached)\n\t\t\t\t{\n\t\t\t\t\tskipWhiteSpace ();\n\n\t\t\t\t\tif (adaKeywordCmp (ADA_KEYWORD_END))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipWhiteSpace ();\n\t\t\t\t\t\tif (adaKeywordCmp (ADA_KEYWORD_RECORD))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tskipPast (\";\");\n\t\t\t\t\t}\n\t\t\t\t\t/* handle variant types */\n\t\t\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_CASE))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipPastKeyword (ADA_KEYWORD_IS);\n\t\t\t\t\t}\n\t\t\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_WHEN))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipPast (\"=>\");\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tadaParseVariables (token, ADA_KIND_RECORD_COMPONENT);\n\t\t\t\t\t\tskipPast (\";\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\ttoken->isSpec = true;\n\t}\n\n\tskipPast (\";\");\n\n\treturn token;\n}\n\nstatic adaTokenInfo *adaParseVariables (adaTokenInfo *parent, adaKind kind)\n{\n\t/* variables for keeping track of tags */\n\tint varEndPos = -1;\n\tint tokenStart = -1;\n\tadaTokenInfo *token = NULL;\n\n\t/* buffer management variables */\n\tint i = 0;\n\tint bufPos = 0;\n\tint bufLen = 0;\n\tchar *buf = NULL;\n\n\t/* file and line position variables */\n\tunsigned long int lineNum;\n\tint filePosIndex = 0;\n\tint filePosSize = 32;\n\tMIOPos *filePos = xMalloc (filePosSize, MIOPos);\n\n\t/* skip any preliminary whitespace or comments */\n\tskipWhiteSpace ();\n\tskipComments ();\n\n\t/* before we start reading input save the current line number and file\n\t * position, so we can reconstruct the correct line & file position for any\n\t * tags we create */\n\tlineNum = getInputLineNumber ();\n\tfilePos[filePosIndex] = getInputFilePosition ();\n\n\t/* setup local buffer... Since we may have to read a few lines to verify\n\t * that this is a proper variable declaration, and still make a token for\n\t * each variable, add one to the allocated string to account for a '\\0' */\n\tbufLen = lineLen - pos;\n\tbuf = xMalloc (bufLen + 1, char);\n\tmemcpy ((void *) buf, (void *) &line[pos], bufLen);\n\n\t/* don't increase bufLen to include the NULL char so that strlen (buf) and\n\t * bufLen match */\n\tbuf[bufLen] = '\\0';\n\n\twhile (!eof_reached)\n\t{\n\t\t/* make sure that we don't count anything in a comment as being valid to\n\t\t * parse */\n\t\tif (isAdaComment (buf, bufPos, bufLen))\n\t\t{\n\t\t\t/* move bufPos to the end of this 'line' so a new line of input is\n\t\t\t * read */\n\t\t\tbufPos = bufLen - 1;\n\n\t\t\t/* if tokenStart is not -2 then we may be trying to track the type\n\t\t\t * of this variable declaration, so set tokenStart to -1 so that the\n\t\t\t * tracking can start over */\n\t\t\tif (tokenStart != -2)\n\t\t\t{\n\t\t\t\ttokenStart = -1;\n\t\t\t}\n\t\t}\n\t\t/* we have to keep track of any () pairs that may be in the variable\n\t\t * declarations.  And then quit if we hit a ';' the real end ')', or also\n\t\t * a variable initialization... Once we hit := then we have hit the end of\n\t\t * the variable declaration */\n\t\telse if (buf[bufPos] == '(')\n\t\t{\n\t\t\ti++;\n\t\t}\n\t\telse if (buf[bufPos] == ')')\n\t\t{\n\t\t\tif (i == 0)\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\t\telse if (buf[bufPos] == ';' ||\n\t\t\t\t ((bufPos + 1) < bufLen &&\n\t\t\t\t  (strncasecmp (&buf[bufPos], \":=\", strlen (\":=\")) == 0 ||\n\t\t\t\t   strncasecmp (&buf[bufPos], \"=>\", strlen (\"=>\")) == 0)))\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\t/* if we found the : keep track of where we found it */\n\t\telse if (buf[bufPos] == ':' &&\n\t\t\t\t (bufPos + 1 >= bufLen || buf[bufPos + 1] != '='))\n\t\t{\n\t\t\tvarEndPos = bufPos;\n\t\t}\n\t\t/* if we have the position of the ':' find out what the next word is,\n\t\t * because if it \"constant\" or \"exception\" then we must tag this slightly\n\t\t * differently, But only check this for normal variables */\n\t\telse if (kind == ADA_KIND_VARIABLE && varEndPos != -1 &&\n\t\t\t\t !isspace ((unsigned char) buf[bufPos]) && tokenStart == -1)\n\t\t{\n\t\t\ttokenStart = bufPos;\n\t\t}\n\t\telse if (kind == ADA_KIND_VARIABLE && varEndPos != -1 && tokenStart >= 0 &&\n\t\t\t\t ((bufPos + 1) >= bufLen ||\n\t\t\t\t  isspace ((unsigned char) buf[bufPos + 1]) ||\n\t\t\t\t  buf[bufPos + 1] == ';'))\n\t\t{\n\t\t\tif (cmp (&buf[tokenStart], bufLen - tokenStart,\n\t\t\t\t\t AdaKeywords[ADA_KEYWORD_CONSTANT]) == true)\n\t\t\t{\n\t\t\t\tkind = ADA_KIND_CONSTANT;\n\t\t\t}\n\t\t\telse if (cmp (&buf[tokenStart], bufLen - tokenStart,\n\t\t\t\t\t\t  AdaKeywords[ADA_KEYWORD_EXCEPTION]) == true)\n\t\t\t{\n\t\t\t\tkind = ADA_KIND_EXCEPTION;\n\t\t\t}\n\n\t\t\t/* set tokenStart to -2 to prevent any more words from being checked */\n\t\t\ttokenStart = -2;\n\t\t}\n\n\t\tbufPos++;\n\n\t\t/* if we just incremented beyond the length of the current buffer, we need\n\t\t * to read in a new line */\n\t\tif (!eof_reached && bufPos >= bufLen)\n\t\t{\n\t\t\treadNewLine ();\n\n\t\t\t/* store the new file position for the start of this line */\n\t\t\tfilePosIndex++;\n\t\t\twhile (filePosIndex >= filePosSize)\n\t\t\t{\n\t\t\t\tfilePosSize *= 2;\n\t\t\t\tfilePos = xRealloc (filePos, filePosSize, MIOPos);\n\t\t\t}\n\t\t\tfilePos[filePosIndex] = getInputFilePosition ();\n\n\t\t\t/* increment bufLen and bufPos now so that they jump past the NULL\n\t\t\t * character in the buffer */\n\t\t\tbufLen++;\n\t\t\tbufPos++;\n\n\t\t\t/* allocate space and store this into our buffer */\n\t\t\tbufLen += lineLen;\n\t\t\tbuf = xRealloc (buf, bufLen + 1, char);\n\t\t\tmemcpy ((void *) &buf[bufPos], (void *) line, lineLen);\n\t\t\tbuf[bufLen] = '\\0';\n\t\t}\n\t}\n\n\t/* There is a special case if we are gathering enumeration values and we hit\n\t * a ')', that is allowed so we need to move varEndPos to where the ')' is */\n\tif (kind == ADA_KIND_ENUM_LITERAL && buf[bufPos] == ')' && varEndPos == -1)\n\t{\n\t\tvarEndPos = bufPos;\n\t}\n\n\t/* so we found a : or ;... If it is a : go back through the buffer and\n\t * create a token for each word skipping over all whitespace and commas\n\t * until the : is hit*/\n\tif (varEndPos != -1)\n\t{\n\t\t/* there should be no whitespace at the beginning, so tokenStart is\n\t\t * initialized to 0 */\n\t\ttokenStart = 0;\n\n\t\t/* before we start set the filePosIndex back to 0 so we can go through the\n\t\t * file position table as the read line number increases */\n\t\tfilePosIndex = 0;\n\n\t\tfor (i = 0; i < varEndPos; i++)\n\t\t{\n\t\t\t/* skip comments which are '--' unless we are in a word */\n\t\t\tif (isAdaComment (buf, i, varEndPos))\n\t\t\t{\n\t\t\t\t/* move i past the '\\0' that we put at the end of each line stored in\n\t\t\t\t * buf */\n\t\t\t\tfor ( ; i < varEndPos && buf[i] != '\\0'; i++);\n\t\t\t}\n\t\t\telse if (tokenStart != -1 && (isspace ((unsigned char) buf[i]) ||\n\t\t\t                              buf[i] == ',' || buf[i] == '\\0'))\n\t\t\t{\n\t\t\t\t/* only store the word if it is not an in/out keyword */\n\t\t\t\tif (!cmp (&buf[tokenStart], varEndPos, \"in\") &&\n\t\t\t\t\t!cmp (&buf[tokenStart], varEndPos, \"out\"))\n\t\t\t\t{\n\t\t\t\t\ttoken = newAdaToken (&buf[tokenStart], i - tokenStart,\n\t\t\t\t\t\t\t\t\t\t kind, false, parent);\n\n\t\t\t\t\t/* now set the proper line and file position counts for this\n\t\t\t\t\t * new token */\n\t\t\t\t\tupdateTagLine (&token->tag, lineNum + filePosIndex,\n\t\t\t\t\t\t\t\t   filePos[filePosIndex]);\n\t\t\t\t}\n\t\t\t\ttokenStart = -1;\n\t\t\t}\n\t\t\telse if (tokenStart == -1 && !(isspace ((unsigned char) buf[i]) ||\n\t\t\t                               buf[i] == ',' || buf[i] == '\\0'))\n\t\t\t{\n\t\t\t\t/* only set the tokenStart for non-newline characters */\n\t\t\t\ttokenStart = i;\n\t\t\t}\n\n\t\t\t/* after we are finished with this line, move the file position */\n\t\t\tif (buf[i] == '\\0')\n\t\t\t{\n\t\t\t\tfilePosIndex++;\n\t\t\t}\n\t\t}\n\n\t\t/* if token start was 'started' then we should store the last token */\n\t\tif (tokenStart != -1)\n\t\t{\n\t\t\ttoken = newAdaToken (&buf[tokenStart], i - tokenStart,\n\t\t\t\t\t\t\t\t kind, false, parent);\n\n\t\t\t/* now set the proper line and file position counts for this\n\t\t\t * new token */\n\t\t\tupdateTagLine (&token->tag, lineNum + filePosIndex,\n\t\t\t\t\t\t   filePos[filePosIndex]);\n\t\t}\n\t}\n\n\t/* now get the pos variable to point to the correct place in line where we\n\t * left off in our temp buf, and free our temporary buffer.  This is a\n\t * little different than most buf position moves.  It gets the distance from\n\t * the current buf position to the end of the buffer, which is also the\n\t * distance from where pos should be wrt the end of the variable\n\t * definition */\n\tmovePos ((lineLen - (bufLen - bufPos)) - pos);\n\teFree ((void *) buf);\n\teFree ((void *) filePos);\n\n\treturn token;\n}\n\nstatic adaTokenInfo *adaParseLoopVar (adaTokenInfo *parent)\n{\n\tint i;\n\tadaTokenInfo *token = NULL;\n\n\tskipWhiteSpace ();\n\tfor (i = 1; (pos + i) < lineLen &&\n\t            !isspace ((unsigned char) line[pos + i]); i++);\n\ttoken = newAdaToken (&line[pos], i, ADA_KIND_AUTOMATIC_VARIABLE, false,\n\t\t\t\t\t\t parent);\n\tmovePos (i);\n\n\t/* now skip to the end of the loop declaration */\n\tskipPastKeyword (ADA_KEYWORD_LOOP);\n\n\treturn token;\n}\n\nstatic adaTokenInfo *adaParse (adaParseMode mode, adaTokenInfo *parent)\n{\n\tint i;\n\tadaTokenInfo genericParamsRoot;\n\tadaTokenInfo *token = NULL;\n\n\tinitAdaTokenList (&genericParamsRoot.children);\n\n\t/* if we hit the end of the file, line will be NULL and our skip and match\n\t * functions will hit this jump buffer with eof_reached */\n\twhile (!eof_reached)\n\t{\n\t\t/* find the next place to start */\n\t\tskipWhiteSpace ();\n\n\t\t/* check some universal things to check for first */\n\t\tif (eof_reached)\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\telse if (isAdaComment (line, pos, lineLen))\n\t\t{\n\t\t\treadNewLine ();\n\t\t\tcontinue;\n\t\t}\n\t\telse if (adaKeywordCmp (ADA_KEYWORD_PRAGMA) ||\n\t\t\t\t ((mode != ADA_GENERIC) && adaKeywordCmp (ADA_KEYWORD_WITH)) ||\n\t\t\t\t adaKeywordCmp (ADA_KEYWORD_USE))\n\t\t{\n\t\t\t/* set the token to NULL so we accidentally don't pick up something\n\t\t\t * from earlier\n\t\t\t * Do not skip lines having 'with' when 'mode == ADA_GENERIC'\n\t\t\t * this to intercept 'formal subprograms' of a generic declaration.\n\t\t\t * see: ARM 12.1(22) */\n\t\t\tskipPast (\";\");\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* check for tags based on our current mode */\n\t\tswitch (mode)\n\t\t{\n\t\tcase ADA_ROOT:\n\t\t\tif (adaKeywordCmp (ADA_KEYWORD_PACKAGE))\n\t\t\t{\n\t\t\t\ttoken = adaParseBlock (parent, ADA_KIND_PACKAGE);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_PROCEDURE) ||\n\t\t\t\t\t adaKeywordCmp (ADA_KEYWORD_FUNCTION))\n\t\t\t{\n\t\t\t\ttoken = adaParseSubprogram (parent, ADA_KIND_SUBPROGRAM);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_TASK))\n\t\t\t{\n\t\t\t\ttoken = adaParseBlock (parent, ADA_KIND_TASK);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_PROTECTED))\n\t\t\t{\n\t\t\t\ttoken = adaParseBlock (parent, ADA_KIND_PROTECTED);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_GENERIC))\n\t\t\t{\n\t\t\t\t/* if we have hit a generic declaration, go to the generic section\n\t\t\t\t * and collect the formal parameters */\n\t\t\t\tmode = ADA_GENERIC;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_SEPARATE))\n\t\t\t{\n\t\t\t\t/* skip any possible whitespace */\n\t\t\t\tskipWhiteSpace ();\n\n\t\t\t\t/* skip over the \"(\" until we hit the tag */\n\t\t\t\tif (!eof_reached && line[pos] == '(')\n\t\t\t\t{\n\t\t\t\t\tmovePos (1);\n\t\t\t\t\tskipWhiteSpace ();\n\n\t\t\t\t\t/* get length of tag */\n\t\t\t\t\tfor (i = 1; (pos + i) < lineLen && line[pos + i] != ')' &&\n\t\t\t\t\t\t\t !isspace ((unsigned char) line[pos + i]); i++);\n\n\t\t\t\t\t/* the original comment before we introduced reference tags:\n\t\t\t\t\t * -----------------------------------------------------------------\n\t\t\t\t\t * if this is a separate declaration, all it really does is create\n\t\t\t\t\t * a false high level token for everything in this file to belong\n\t\t\t\t\t * to... But we don't know what kind it is, so we declare it as\n\t\t\t\t\t * ADA_KIND_SEPARATE, which will cause it not to be placed in\n\t\t\t\t\t * the tag file, and the item in this file will be printed as\n\t\t\t\t\t * separate:<name> instead of package:<name> or whatever the\n\t\t\t\t\t * parent kind really is (assuming the ctags option will be on\n\t\t\t\t\t * for printing such info to the tag file)\n\t\t\t\t\t * -----------------------------------------------------------------\n\t\t\t\t\t * Now we have reference tags. So we can use ADA_KIND_PACKAGE as kind.\n\t\t\t\t\t */\n\t\t\t\t\ttoken = newAdaTokenFull (&line[pos], i, ADA_KIND_PACKAGE, ADA_PACKAGE_SUBUNIT,\n\t\t\t\t\t\t\t\t\t\t\t false, parent);\n\n\t\t\t\t\t/* since this is a false top-level token, set parent to be\n\t\t\t\t\t * token */\n\t\t\t\t\tparent = token;\n\t\t\t\t\ttoken = NULL;\n\n\t\t\t\t\t/* skip past the ')' */\n\t\t\t\t\tskipPast (\")\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* move to the end of this statement */\n\t\t\t\t\tskipPast (\";\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* otherwise, nothing was found so just skip until the end of this\n\t\t\t\t * unknown statement... It's most likely just a use or with\n\t\t\t\t * clause.  Also set token to NULL so we don't attempt anything\n\t\t\t\t * incorrect */\n\t\t\t\ttoken = NULL;\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\n\t\t\t/* check to see if we succeeded in creating our token */\n\t\t\tif (token != NULL)\n\t\t\t{\n\t\t\t\t/* if any generic params have been gathered, attach them to\n\t\t\t\t * token */\n\t\t\t\tappendAdaTokenList (token, &genericParamsRoot.children);\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\tcase ADA_GENERIC:\n\t\t\t/* if we are processing a generic block, make up some temp children\n\t\t\t * which we will later attach to the root of the real\n\t\t\t * procedure/package/whatever the formal parameters are for */\n\t\t\tif (adaKeywordCmp (ADA_KEYWORD_PACKAGE))\n\t\t\t{\n\t\t\t\ttoken = adaParseBlock (parent, ADA_KIND_PACKAGE);\n\n\t\t\t\t/* The above 'adaParseBlock' has read the end of a 'generic package declaration',\n\t\t\t\t * reset the mode back to the original mode.\n\t\t\t\t * see: ARM 12.1(24) */\n\t\t\t\tAssert (parent);\n\t\t\t\tmode = (parent->parent)? ADA_DECLARATIONS: ADA_ROOT;\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_PROCEDURE) ||\n\t\t\t\t\t adaKeywordCmp (ADA_KEYWORD_FUNCTION))\n\t\t\t{\n\t\t\t\ttoken = adaParseSubprogram (parent, ADA_KIND_SUBPROGRAM);\n\n\t\t\t\t/* The above 'adaParseBlock' as read the end of a 'generic function/procedure declaration',\n\t\t\t\t * reset the mode back to the original mode.\n\t\t\t\t * see: ARM 12.1(21/22) */\n\t\t\t\tAssert (parent);\n\t\t\t\tmode = (parent->parent)? ADA_DECLARATIONS: ADA_ROOT;\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_TASK))\n\t\t\t{\n\t\t\t\ttoken = adaParseBlock (parent, ADA_KIND_TASK);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_PROTECTED))\n\t\t\t{\n\t\t\t\ttoken = adaParseBlock (parent, ADA_KIND_PROTECTED);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_TYPE))\n\t\t\t{\n\t\t\t\tskipWhiteSpace ();\n\n\t\t\t\t/* get length of tag */\n\t\t\t\tfor (i = 1; (pos + i) < lineLen &&\n\t\t\t\t            !isspace ((unsigned char) line[pos + i]) &&\n\t\t\t\t            line[pos + i] != '(' && line[pos + i] != ';'; i++);\n\n\t\t\t\tappendAdaToken (&genericParamsRoot,\n\t\t\t\t\t\t\t\tnewAdaToken (&line[pos], i, ADA_KIND_FORMAL, false,\n\t\t\t\t\t\t\t\t\t\t\t NULL));\n\n\t\t\t\t/* skip to the end of this formal type declaration */\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_WITH))\n\t\t\t{\n\t\t\t\tskipWhiteSpace ();\n\t\t\t\t/* skip over the function/procedure keyword, it doesn't matter for\n\t\t\t\t * now */\n\t\t\t\tskipUntilWhiteSpace ();\n\t\t\t\tskipWhiteSpace ();\n\n\t\t\t\t/* get length of tag */\n\t\t\t\tfor (i = 1; (pos + i) < lineLen &&\n\t\t\t\t            !isspace ((unsigned char) line[pos + i]) &&\n\t\t\t\t            line[pos + i] != '(' && line[pos + i] != ';'; i++);\n\n\t\t\t\tappendAdaToken (&genericParamsRoot,\n\t\t\t\t\t\t\t\tnewAdaToken (&line[pos], i, ADA_KIND_FORMAL, false,\n\t\t\t\t\t\t\t\t\t\t\t NULL));\n\n\t\t\t\t/* increment the position */\n\t\t\t\tmovePos (i);\n\n\t\t\t\t/* now gather the parameters to this subprogram */\n\t\t\t\tif (!eof_reached && line[pos] == '(')\n\t\t\t\t{\n\t\t\t\t\twhile (!eof_reached && line[pos] != ')')\n\t\t\t\t\t{\n\t\t\t\t\t\tmovePos (1);\n\t\t\t\t\t\tadaParseVariables (genericParamsRoot.children.tail,\n\t\t\t\t\t\t\t\t\t\t   ADA_KIND_AUTOMATIC_VARIABLE);\n\t\t\t\t\t}\n\t\t\t\t\tmovePos (1);\n\t\t\t\t}\n\n\t\t\t\t/* skip to the end of this formal type declaration */\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* otherwise, nothing was found so just skip until the end of this\n\t\t\t\t * unknown statement... It's most likely just a use or with\n\t\t\t\t * clause.  Also set token to NULL so we don't attempt anything\n\t\t\t\t * incorrect */\n\t\t\t\ttoken = NULL;\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\n\t\t\t/* check to see if we succeeded in creating our token */\n\t\t\tif (token != NULL)\n\t\t\t{\n\t\t\t\t/* if any generic params have been gathered, attach them to\n\t\t\t\t * token. */\n\t\t\t\tappendAdaTokenList (token, &genericParamsRoot.children);\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\tcase ADA_DECLARATIONS:\n\t\t\tif (adaKeywordCmp (ADA_KEYWORD_PACKAGE))\n\t\t\t{\n\t\t\t\ttoken = adaParseBlock (parent, ADA_KIND_PACKAGE);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_PROCEDURE) ||\n\t\t\t\t\t adaKeywordCmp (ADA_KEYWORD_FUNCTION))\n\t\t\t{\n\t\t\t\ttoken = adaParseSubprogram (parent, ADA_KIND_SUBPROGRAM);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_TASK))\n\t\t\t{\n\t\t\t\ttoken = adaParseBlock (parent, ADA_KIND_TASK);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_PROTECTED))\n\t\t\t{\n\t\t\t\ttoken = adaParseBlock (parent, ADA_KIND_PROTECTED);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_GENERIC))\n\t\t\t{\n\t\t\t\t/* if we have hit a generic declaration, go to the generic section\n\t\t\t\t * and collect the formal parameters */\n\t\t\t\tmode = ADA_GENERIC;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_TYPE))\n\t\t\t{\n\t\t\t\ttoken = adaParseType (parent, ADA_KIND_TYPE);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_SUBTYPE))\n\t\t\t{\n\t\t\t\ttoken = adaParseType (parent, ADA_KIND_SUBTYPE);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_BEGIN))\n\t\t\t{\n\t\t\t\tmode = ADA_CODE;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_FOR))\n\t\t\t{\n\t\t\t\t/* if we hit a \"for\" statement it is defining implementation details\n\t\t\t\t * for a specific type/variable/subprogram/etc...  So we should just\n\t\t\t\t * skip it, so skip the tag, then we need to see if there is a\n\t\t\t\t * 'record' keyword... If there is we must skip past the\n\t\t\t\t * 'end record;' statement.  First skip past the tag */\n\t\t\t\tskipPastKeyword (ADA_KEYWORD_USE);\n\t\t\t\tskipWhiteSpace ();\n\n\t\t\t\tif (adaKeywordCmp (ADA_KEYWORD_RECORD))\n\t\t\t\t{\n\t\t\t\t\t/* now skip to the next \"record\" keyword, which should be the end\n\t\t\t\t\t * of this use statement */\n\t\t\t\t\tskipPastKeyword (ADA_KEYWORD_RECORD);\n\t\t\t\t}\n\n\t\t\t\t/* lastly, skip past the end \";\" */\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_END))\n\t\t\t{\n\t\t\t\t/* if we have hit an end then we must see if the next word matches\n\t\t\t\t * the parent token's name.  If it does we hit the end of whatever\n\t\t\t\t * sort of block construct we were processing and we must\n\t\t\t\t * return */\n\t\t\t\tskipWhiteSpace ();\n\t\t\t\tif (adaCmp (parent->name))\n\t\t\t\t{\n\t\t\t\t\tskipPast (\";\");\n\n\t\t\t\t\t/* return the token */\n\t\t\t\t\tfreeAdaTokenList (&genericParamsRoot.children);\n\t\t\t\t\treturn token;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* set the token to NULL so we accidentally don't pick up something\n\t\t\t\t\t * from earlier */\n\t\t\t\t\ttoken = NULL;\n\t\t\t\t\tskipPast (\";\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_ENTRY))\n\t\t\t{\n\t\t\t\ttoken = adaParseSubprogram (parent, ADA_KIND_ENTRY);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_PRIVATE))\n\t\t\t{\n\t\t\t\t/* if this is a private declaration then we need to set the global\n\t\t\t\t * file spec flag and then skip whitespace to get to the next bit of\n\t\t\t\t * code to parse. */\n\t\t\t\tif (parent != NULL)\n\t\t\t\t{\n\t\t\t\t\tparent->isPrivate = true;\n\t\t\t\t}\n\n\t\t\t\tskipWhiteSpace ();\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_OVERRIDING)\n\t\t\t\t\t || adaKeywordCmp (ADA_KEYWORD_NOT))\n\t\t\t{\n\t\t\t\t/* Do nothing, just ignore these keywords. */\n\t\t\t\t;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* if nothing else matched this is probably a variable, constant\n\t\t\t\t * or exception declaration */\n\t\t\t\ttoken = adaParseVariables (parent, ADA_KIND_VARIABLE);\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\n\t\t\t/* check to see if we succeeded in creating our token */\n\t\t\tif (token != NULL)\n\t\t\t{\n\t\t\t\t/* if this is one of the root-type tokens... Do some extra\n\t\t\t\t * processing */\n\t\t\t\tif (token->kind == ADA_KIND_PACKAGE ||\n\t\t\t\t\ttoken->kind == ADA_KIND_SUBPROGRAM ||\n\t\t\t\t\ttoken->kind == ADA_KIND_TASK ||\n\t\t\t\t\ttoken->kind == ADA_KIND_PROTECTED)\n\t\t\t\t{\n\t\t\t\t\t/* if any generic params have been gathered, attach them to\n\t\t\t\t\t * token */\n\t\t\t\t\tappendAdaTokenList (token, &genericParamsRoot.children);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase ADA_CODE:\n\t\t\tif (adaKeywordCmp (ADA_KEYWORD_DECLARE))\n\t\t\t{\n\t\t\t\t/* if we are starting a declare block here, and not down at the\n\t\t\t\t * identifier definition then make an anonymous token to track the\n\t\t\t\t * data in this block */\n\t\t\t\ttoken = newAdaToken (NULL, 0, ADA_KIND_ANONYMOUS, false, parent);\n\n\t\t\t\t/* save the correct starting line */\n\t\t\t\tupdateTagLine (&token->tag, matchLineNum, matchFilePos);\n\n\t\t\t\tadaParse (ADA_DECLARATIONS, token);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_BEGIN))\n\t\t\t{\n\t\t\t\t/* if we are starting a code block here, and not down at the\n\t\t\t\t * identifier definition then make an anonymous token to track the\n\t\t\t\t * data in this block, if this was part of a proper LABEL:\n\t\t\t\t * declare/begin/end block then the parent would already be a label\n\t\t\t\t * and this begin statement would have been found while in the\n\t\t\t\t * ADA_DECLARATIONS parsing section  */\n\t\t\t\ttoken = newAdaToken (NULL, 0, ADA_KIND_ANONYMOUS, false, parent);\n\n\t\t\t\t/* save the correct starting line */\n\t\t\t\tupdateTagLine (&token->tag, matchLineNum, matchFilePos);\n\n\t\t\t\tadaParse (ADA_CODE, token);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_EXCEPTION))\n\t\t\t{\n\t\t\t\tmode = ADA_EXCEPTIONS;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_END))\n\t\t\t{\n\t\t\t\t/* if we have hit an end then we must see if the next word matches\n\t\t\t\t * the parent token's name.  If it does we hit the end of whatever\n\t\t\t\t * sort of block construct we were processing and we must\n\t\t\t\t * return */\n\t\t\t\tskipWhiteSpace ();\n\n#ifdef DO_TRACING\n\t\t\t\tif (isLanguageTraced (getInputLanguage ()))\n\t\t\t\t{\n\t\t\t\t\tdumpTokenList (&genericParamsRoot.children);\n\t\t\t\t\tdumpToken (parent);\n\t\t\t\t}\n#endif\n\n\t\t\t\tif (adaCmp (\"if\") || adaCmp (\"case\"))\n\t\t\t\t{\n\t\t\t\t\t/* TODO: \"select\" */\n\t\t\t\t\tskipPast (\";\");\n\t\t\t\t}\n\t\t\t\telse if (adaCmp (parent->name))\n\t\t\t\t{\n\t\t\t\t\tskipPast (\";\");\n\n\t\t\t\t\t/* return the token */\n\t\t\t\t\tfreeAdaTokenList (&genericParamsRoot.children);\n\t\t\t\t\treturn token;\n\t\t\t\t}\n\t\t\t\telse if (parent->kind == ADA_KIND_SUBPROGRAM && adaCmp (\";\"))\n\t\t\t\t{\n\t\t\t\t\t/* The designator after end is optional in subprogram body.\n\t\t\t\t\t * https://cui.unige.ch/isi/bnf/Ada95/subprogram_body.html */\n\n\t\t\t\t\t/* return the token */\n\t\t\t\t\tfreeAdaTokenList (&genericParamsRoot.children);\n\t\t\t\t\treturn token;\n\t\t\t\t}\n\t\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_LOOP))\n\t\t\t\t{\n\t\t\t\t\t/* a loop with an identifier has this syntax:\n\t\t\t\t\t * \"end loop <ident>;\" */\n\t\t\t\t\tskipWhiteSpace ();\n\n\t\t\t\t\t/* now check for the parent loop's name */\n\t\t\t\t\tif (adaCmp (parent->name))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipPast (\";\");\n\n\t\t\t\t\t\t/* return the token */\n\t\t\t\t\t\tfreeAdaTokenList (&genericParamsRoot.children);\n\t\t\t\t\t\treturn token;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* otherwise, nothing was found so just skip until the end of\n\t\t\t\t\t * this statement */\n\t\t\t\t\tskipPast (\";\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_ACCEPT))\n\t\t\t{\n\t\t\t\tadaParseSubprogram (parent, ADA_KIND_ENTRY);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_FOR))\n\t\t\t{\n\t\t\t\t/* if this is a for loop, then we may need to pick up the\n\t\t\t\t * automatic loop iterator, But... The loop variable is only\n\t\t\t\t * available within the loop itself so make an anonymous label\n\t\t\t\t * parent for this loop var to be parsed in */\n\t\t\t\ttoken = newAdaToken (AdaKeywords[ADA_KEYWORD_LOOP],\n\t\t\t\t\t\t\t\t\t strlen (AdaKeywords[ADA_KEYWORD_LOOP]),\n\t\t\t\t\t\t\t\t\t ADA_KIND_ANONYMOUS, false, parent);\n\t\t\t\tadaParseLoopVar (token);\n\t\t\t\tadaParse (ADA_CODE, token);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_WHILE))\n\t\t\t{\n\t\t\t\ttoken = newAdaToken (AdaKeywords[ADA_KEYWORD_LOOP],\n\t\t\t\t\t\t\t\t\t strlen (AdaKeywords[ADA_KEYWORD_LOOP]),\n\t\t\t\t\t\t\t\t\t ADA_KIND_ANONYMOUS, false, parent);\n\n\t\t\t\t/* skip past the while loop declaration and parse the loop body */\n\t\t\t\tskipPastKeyword (ADA_KEYWORD_LOOP);\n\t\t\t\tskipWhiteSpace ();\n\t\t\t\tadaParse (ADA_CODE, token);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_LOOP))\n\t\t\t{\n\t\t\t\ttoken = newAdaToken (AdaKeywords[ADA_KEYWORD_LOOP],\n\t\t\t\t\t\t\t\t\t strlen (AdaKeywords[ADA_KEYWORD_LOOP]),\n\t\t\t\t\t\t\t\t\t ADA_KIND_ANONYMOUS, false, parent);\n\n\t\t\t\t/* save the correct starting line */\n\t\t\t\tupdateTagLine (&token->tag, matchLineNum, matchFilePos);\n\n\t\t\t\t/* parse the loop body */\n\t\t\t\tskipWhiteSpace ();\n\t\t\t\tadaParse (ADA_CODE, token);\n\t\t\t}\n\t\t\telse if (line != NULL &&\n\t\t\t\t\t strncasecmp (&line[pos], \"<<\", strlen (\"<<\")) == 0)\n\t\t\t{\n\t\t\t\tmovePos (strlen (\"<<\"));\n\n\t\t\t\t/* if the first chars are <<, find the ending >> and if we do that\n\t\t\t\t * then store the label tag, start i at strlen of \"<<\" plus 1\n\t\t\t\t * because we don't want to move the real pos until we know for\n\t\t\t\t * sure this is a label */\n\t\t\t\tfor (i = 1; (pos + i) < lineLen &&\n\t\t\t\t\t\t strncasecmp (&line[pos + i], \">>\", strlen (\">>\")) != 0;\n\t\t\t\t\t i++);\n\n\t\t\t\t/* if we didn't increment to the end of the line, a match was\n\t\t\t\t * found, if we didn't just fall through */\n\t\t\t\tif ((pos + i) < lineLen)\n\t\t\t\t{\n\t\t\t\t\tnewAdaToken (&line[pos], i, ADA_KIND_LABEL, false, parent);\n\t\t\t\t\tskipPast (\">>\");\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* we need to check for a few special case keywords that might cause\n\t\t\t * the simple ; ending statement checks to fail, first the simple\n\t\t\t * one word keywords and then the start <stuff> end statements */\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_SELECT) ||\n\t\t\t\t\t adaKeywordCmp (ADA_KEYWORD_OR) ||\n\t\t\t\t\t adaKeywordCmp (ADA_KEYWORD_ELSE))\n\t\t\t{\n\t\t\t\tskipWhiteSpace ();\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_IF) ||\n\t\t\t\t\t adaKeywordCmp (ADA_KEYWORD_ELSIF))\n\t\t\t{\n\t\t\t\tskipPastKeyword (ADA_KEYWORD_THEN);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_CASE))\n\t\t\t{\n\t\t\t\tskipPastKeyword (ADA_KEYWORD_IS);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_WHEN))\n\t\t\t{\n\t\t\t\tskipPast (\"=>\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tint i_end;\n\t\t\t\t/* set token to NULL so we don't accidentally not find an identifier,\n\t\t\t\t * But then fall through to the != NULL check */\n\t\t\t\ttoken = NULL;\n\n\t\t\t\t/* there is a possibility that this may be a loop or block\n\t\t\t\t * identifier, so check for a <random_word>[ ]?: statement */\n\t\t\t\tfor (i = 1; (pos + i) < lineLen; i++)\n\t\t\t\t\tif (!(isalnum ((unsigned char) line[pos + i]) ||\n\t\t\t\t\t      line[pos + i] == '_'))\n\t\t\t\t\t\tbreak;\n\t\t\t\ti_end = i;\t\t/* Records the end of identifier. */\n\n\t\t\t\t/* Skip whitespaces between the identifier and ':' */\n\t\t\t\tfor (; (pos + i) < lineLen; i++)\n\t\t\t\t\tif (!isspace((unsigned char)(line[pos + i])))\n\t\t\t\t\t\tbreak;\n\n\t\t\t\tif ((pos + i) < lineLen\n\t\t\t\t\t&& (line[pos + i] == ':')\n\t\t\t\t\t&& (\n\t\t\t\t\t\t((pos + i + 1) == lineLen)\n\t\t\t\t\t\t|| (line[pos + i + 1] != '=')\n\t\t\t\t\t\t))\n\t\t\t\t\ttoken = newAdaToken (&line[pos], i_end, ADA_KIND_IDENTIFIER, false,\n\t\t\t\t\t\t\t\t\t\t parent);\n\n\t\t\t\t/* if we created a token, we found an identifier.  Now check for a\n\t\t\t\t * declare or begin statement to see if we need to start parsing\n\t\t\t\t * the following code like a root-style token would */\n\t\t\t\tif (token != NULL)\n\t\t\t\t{\n\t\t\t\t\t/* if something was found, reset the position variable and try to\n\t\t\t\t\t * find the next item */\n\t\t\t\t\tmovePos (i + 1);\n\t\t\t\t\tskipWhiteSpace ();\n\n\t\t\t\t\tif (adaKeywordCmp (ADA_KEYWORD_DECLARE))\n\t\t\t\t\t{\n\t\t\t\t\t\tadaParse (ADA_DECLARATIONS, token);\n\t\t\t\t\t}\n\t\t\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_BEGIN))\n\t\t\t\t\t{\n\t\t\t\t\t\tadaParse (ADA_CODE, token);\n\t\t\t\t\t}\n\t\t\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_FOR))\n\t\t\t\t\t{\n\t\t\t\t\t\t/* just grab the automatic loop variable, and then parse the\n\t\t\t\t\t\t * loop (it may have something to tag which will be a 'child'\n\t\t\t\t\t\t * of the loop) */\n\t\t\t\t\t\tadaParseLoopVar (token);\n\t\t\t\t\t\tadaParse (ADA_CODE, token);\n\t\t\t\t\t}\n\t\t\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_WHILE))\n\t\t\t\t\t{\n\t\t\t\t\t\t/* skip to the loop keyword */\n\t\t\t\t\t\tskipPastKeyword (ADA_KEYWORD_LOOP);\n\t\t\t\t\t\tskipWhiteSpace ();\n\n\t\t\t\t\t\t/* parse the loop (it may have something to tag which will be\n\t\t\t\t\t\t * a 'child' of the loop) */\n\t\t\t\t\t\tadaParse (ADA_CODE, token);\n\t\t\t\t\t}\n\t\t\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_LOOP))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipWhiteSpace ();\n\n\t\t\t\t\t\t/* parse the loop (it may have something to tag which will be\n\t\t\t\t\t\t * a 'child' of the loop) */\n\t\t\t\t\t\tadaParse (ADA_CODE, token);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t/* otherwise, nothing was found so this is not a valid\n\t\t\t\t\t\t * identifier, delete it */\n\t\t\t\t\t\tfreeAdaToken (&parent->children, token);\n\t\t\t\t\t\ttoken = NULL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* since nothing was found, simply skip to the end of this\n\t\t\t\t\t * statement */\n\t\t\t\t\tskipPast (\";\");\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* else... No keyword tag fields found, look for others such as\n\t\t\t * loop and declare identifiers labels or just skip over this\n\t\t\t * line */\n\n\t\t\tbreak;\n\n\t\tcase ADA_EXCEPTIONS:\n\t\t\tif (adaKeywordCmp (ADA_KEYWORD_PRAGMA))\n\t\t\t{\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_WHEN))\n\t\t\t{\n\t\t\t\tskipWhiteSpace ();\n\t\t\t\ttoken = adaParseVariables (parent, ADA_KIND_AUTOMATIC_VARIABLE);\n\t\t\t}\n\t\t\telse if (adaKeywordCmp (ADA_KEYWORD_END))\n\t\t\t{\n\t\t\t\t/* if we have hit an end then we must see if the next word matches\n\t\t\t\t * the parent token's name.  If it does we hit the end of whatever\n\t\t\t\t * sort of block construct we were processing and we must\n\t\t\t\t * return */\n\t\t\t\tskipWhiteSpace ();\n\t\t\t\tif (adaCmp (parent->name))\n\t\t\t\t{\n\t\t\t\t\tskipPast (\";\");\n\n\t\t\t\t\t/* return the token */\n\t\t\t\t\tfreeAdaTokenList (&genericParamsRoot.children);\n\t\t\t\t\treturn token;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* otherwise, nothing was found so just skip until the end of\n\t\t\t\t\t * this statement */\n\t\t\t\t\tskipPast (\";\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* otherwise, nothing was found so just skip until the end of\n\t\t\t\t * this statement */\n\t\t\t\tskipPast (\";\");\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tAssert (0);\n\t\t}\n\t}\n\n\tfreeAdaTokenList (&genericParamsRoot.children);\n\treturn token;\n}\n\nstatic void storeAdaTags (adaTokenInfo *token, const char *parentScope)\n{\n\tchar *currentScope = NULL;\n\tadaTokenInfo *tmp = NULL;\n\n\tAssert (token);\n\n\t/* do a spec transition if necessary */\n\tif (token->isSpec == true)\n\t{\n\t\tmakeSpec (&token->kind);\n\n\t\tif (token->kind != ADA_KIND_UNDEFINED)\n\t\t{\n\t\t\ttoken->tag.kindIndex = token->kind;\n\t\t}\n\t}\n\n\t/* fill in the scope data */\n\tif (token->parent != NULL)\n\t{\n\t\tif (token->parent->kind != ADA_KIND_UNDEFINED)\n\t\t{\n\t\t\ttoken->tag.extensionFields.scopeKindIndex = token->parent->kind;\n\t\t\ttoken->tag.extensionFields.scopeName = token->parent->name;\n\t\t}\n\t}\n\n\t/* one check before we try to make a tag... If this is an anonymous\n\t * declare block then it's name is empty.  Give it one */\n\tif (token->kind == ADA_KIND_ANONYMOUS && token->name == NULL)\n\t{\n\t\ttoken->name = (char *) AdaKeywords[ADA_KEYWORD_DECLARE];\n\t\ttoken->tag.name = AdaKeywords[ADA_KEYWORD_DECLARE];\n\t}\n\n\t/* Now 'make' tags that have their options set, But only make anonymous\n\t * tags if they have children tags.  Also, don't make this tag if the file\n\t * scope flag is not set and this tag is a file scope tag. */\n\tif ((token->kind > ADA_KIND_UNDEFINED) && (token->kind < ADA_KIND_COUNT) &&\n\t\t(AdaKinds[token->kind].enabled == true) &&\n\t\t(token->name != NULL) &&\n\t\t((token->kind == ADA_KIND_ANONYMOUS && token->children.head != NULL) ||\n\t\t token->kind != ADA_KIND_ANONYMOUS) &&\n\t\t((isXtagEnabled (XTAG_FILE_SCOPE) == true) ||\n\t\t ((isXtagEnabled (XTAG_FILE_SCOPE) == false) &&\n\t\t  (token->tag.isFileScope == false))))\n\t{\n\t\tmakeTagEntry (&token->tag);\n\n\t\t/* before making the tag, if the --extra=+q flag is set we should create\n\t\t * an extra entry which is the full parent.tag name.  But only do this if\n\t\t * the parentScope flag is not NULL, and this token is not of a limited\n\t\t * scope type such as a record component, enum literal, label, etc. */\n\t\tif ((isXtagEnabled (XTAG_QUALIFIED_TAGS) == true) &&\n\t\t\t(token->kind != ADA_KIND_RECORD_COMPONENT) &&\n\t\t\t(token->kind != ADA_KIND_ENUM_LITERAL) &&\n\t\t\t(token->kind != ADA_KIND_FORMAL) &&\n\t\t\t(token->kind != ADA_KIND_LABEL) &&\n\t\t\t(token->kind != ADA_KIND_IDENTIFIER) &&\n\t\t\t(token->kind != ADA_KIND_AUTOMATIC_VARIABLE) &&\n\t\t\t(token->kind != ADA_KIND_ANONYMOUS))\n\t\t{\n\t\t\tif (parentScope != NULL)\n\t\t\t{\n\t\t\t\t/* first create our new scope which is the parent scope + '.' + the\n\t\t\t\t * current tag name. */\n\t\t\t\tsize_t parentScope_len = strlen (parentScope);\n\t\t\t\tsize_t name_len = strlen (token->name);\n\t\t\t\tcurrentScope = xMalloc (parentScope_len + name_len + 2, char);\n\t\t\t\tmemcpy (currentScope, parentScope, parentScope_len);\n\t\t\t\tcurrentScope[parentScope_len] = '.';\n\t\t\t\tmemcpy (&currentScope[parentScope_len + 1], token->name, name_len);\n\t\t\t\tcurrentScope[parentScope_len + 1 + name_len] = '\\0';\n\n\t\t\t\ttoken->tag.name = currentScope;\n\t\t\t\tmarkTagExtraBit (&token->tag, XTAG_QUALIFIED_TAGS);\n\t\t\t\tmakeTagEntry (&token->tag);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* if the parent scope is null then the current token does not have\n\t\t\t\t * a parent tag to prepend onto the current scope.  Therefore, just\n\t\t\t\t * setup the current scope as a copy of the current tag name, but make\n\t\t\t\t * no extra entry. */\n\t\t\t\tcurrentScope = token->name;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* now make the child tags */\n\ttmp = token->children.head;\n\twhile (tmp != NULL)\n\t{\n\t\tstoreAdaTags (tmp, currentScope);\n\t\ttmp = tmp->next;\n\t}\n\n\t/* we have to clear out the declare name here or else it may cause issues\n\t * when we try to process it's children, and when we try to free the token\n\t * data */\n\tif (token->kind == ADA_KIND_ANONYMOUS &&\n\t\tstrncasecmp (token->name, AdaKeywords[ADA_KEYWORD_DECLARE],\n\t\t\t\t\t strlen (AdaKeywords[ADA_KEYWORD_DECLARE])) == 0)\n\t{\n\t\ttoken->name = NULL;\n\t\ttoken->tag.name = NULL;\n\t}\n\n\tif ((currentScope != NULL) && (currentScope != token->name))\n\t{\n\t\teFree ((void *) currentScope);\n\t}\n}\n\n#ifdef DO_TRACING\nCTAGS_ATTR_UNUSED\nstatic void dumpLine (void)\n{\n\tfprintf (stderr, \"line: %s\\n\", line? &line[pos]: \"\");\n}\n\nCTAGS_ATTR_UNUSED\nstatic void dumpMode (adaParseMode mode)\n{\n#define caseMode(M) case ADA_##M: fprintf (stderr, \"mode: %s\\n\", STRINGIFY (M)); break\n\tswitch (mode) {\n\t\tcaseMode (ROOT);\n\t\tcaseMode (DECLARATIONS);\n\t\tcaseMode (CODE);\n\t\tcaseMode (EXCEPTIONS);\n\t\tcaseMode (GENERIC);\n#undef caseMode\n\tdefault: fputs(\"mode: UNKNOWN\\n\", stderr); break;\n\t};\n}\n\nCTAGS_ATTR_UNUSED\nstatic void dumpTokenList (adaTokenList *list)\n{\n\tfprintf (stderr, \"list: [%p\\n\", list);\n\n\tif (list != NULL)\n\t{\n\t\tfprintf (stderr, \"numTokens: %d\\n\", list->numTokens);\n\n\t\tadaTokenInfo *tmp = list->head;\n\t\twhile (tmp)\n\t\t{\n\t\t\tdumpToken (tmp);\n\t\t\ttmp = tmp->next;\n\t\t}\n\t}\n\n\tfprintf (stderr, \"%p]\\n\", list);\n}\n\nCTAGS_ATTR_UNUSED\nstatic void dumpToken (adaTokenInfo *token)\n{\n\tfprintf (stderr, \"token: [%p\\n\", token);\n\tif (token != NULL)\n\t{\n\t\tif (token->name != NULL)\n\t\t\tfprintf (stderr, \"name: %s\\n\", token->name);\n\t\tdumpKind (token->kind);\n\t\tdumpTokenList (&token->children);\n\t}\n\tfprintf (stderr, \"%p]\\n\", token);\n}\n\nCTAGS_ATTR_UNUSED\nstatic void dumpKind (adaKind kind)\n{\n\tfprintf (stderr, \"kind: %s\\n\",\n\t\t\t\t (0 <= kind && kind < ADA_KIND_COUNT)\n\t\t\t\t ? AdaKinds[kind].name\n\t\t\t\t : \"?\");\n}\n#endif\n\n/* main parse function */\nstatic void findAdaTags (void)\n{\n\tadaTokenInfo root;\n\tadaTokenInfo *tmp;\n\n\t/* init all global data now */\n\teof_reached = false;\n\tline = NULL;\n\tpos = 0;\n\tmatchLineNum = 0;\n\n\t/* cannot just set matchFilePos to 0 because the fpos_t is not a simple\n\t * integer on all systems. */\n\tmatchFilePos = getInputFilePosition ();\n\n\t/* init the root tag */\n\troot.kind = ADA_KIND_UNDEFINED;\n\troot.isSpec = false;\n\troot.name = NULL;\n\troot.parent = NULL;\n\troot.isPrivate = false;\n\tinitAdaTokenList (&root.children);\n\n\t/* read in the first line */\n\treadNewLine ();\n\tif (eof_reached)\n\t\tgoto out;\n\n\t/* tokenize entire file */\n\twhile (!eof_reached && adaParse (ADA_ROOT, &root) != NULL);\n\n\t/* store tags */\n\ttmp = root.children.head;\n\twhile (tmp != NULL)\n\t{\n\t\tstoreAdaTags (tmp, NULL);\n\t\ttmp = tmp->next;\n\t}\n\n out:\n\t/* clean up tokens */\n\tfreeAdaTokenList (&root.children);\n}\n\n/* parser definition function */\nextern parserDefinition* AdaParser (void)\n{\n\tstatic const char *const extensions[] = { \"adb\", \"ads\", \"Ada\", \"ada\", NULL };\n\tparserDefinition* def = parserNew (\"Ada\");\n\tdef->kindTable = AdaKinds;\n\tdef->kindCount = ADA_KIND_COUNT;\n\tdef->extensions = extensions;\n\tdef->parser = findAdaTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/ansibleplaybook.c",
    "content": "/*\n*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n\n#include \"general.h\"\t/* must always come first */\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"x-yaml.h\"\n#include \"parse.h\"\n#include \"subparser.h\"\n\ntypedef enum {\n\tK_PLAY\n} ansiblePlaybookKind;\n\nstatic kindDefinition AnsiblePlaybookKinds [] = {\n\t{ true,  'p', \"play\", \"plays\" },\n};\n\nstruct sAnsiblePlaybookSubparser {\n\tyamlSubparser yaml;\n\tint nameIndex;\n};\n\nstatic tagYpathTable ypathTables [] = {\n\t{ \"*/name\",\n\t  YPATH_DSTAT_LAST_VALUE, K_PLAY, },\n};\n\nstatic void\nfindAnsiblePlaybookTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nstatic void inputStart(subparser *s)\n{\n\t((struct sAnsiblePlaybookSubparser*)s)->nameIndex = CORK_NIL;\n}\n\nstatic void makeTagEntryCallbackViaYpath(yamlSubparser *s, int corkIndex)\n{\n\t/* a mapping in a sequence */\n\tif (ypathGetTypeStackDepth(s) == 2)\n\t\t((struct sAnsiblePlaybookSubparser *)s)->nameIndex = corkIndex;\n}\n\nstatic void leaveBlockCallback(yamlSubparser *s, yaml_token_t *token)\n{\n\tstruct sAnsiblePlaybookSubparser *ansible = (struct sAnsiblePlaybookSubparser *)s;\n\n\tif (token\n\t\t&& ansible->nameIndex != CORK_NIL\n\t\t&& ypathGetTypeStackDepth(s) == 2)\n\t{\n\t\ttagEntryInfo *tag = getEntryInCorkQueue (ansible->nameIndex);\n\t\tif (tag)\n\t\t\tattachYamlPosition (tag, token, true);\n\t\tansible->nameIndex = CORK_NIL;\n\t}\n}\n\nextern parserDefinition* AnsiblePlaybookParser (void)\n{\n\tstatic struct sAnsiblePlaybookSubparser ansiblePlaybookSubparser = {\n\t\t.yaml = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t\t\t.inputStart = inputStart,\n\t\t\t},\n\t\t\t.ypathTables = ypathTables,\n\t\t\t.ypathTableCount = ARRAY_SIZE (ypathTables),\n\t\t\t.leaveBlockNotify = leaveBlockCallback,\n\t\t\t.makeTagEntryNotifyViaYpath = makeTagEntryCallbackViaYpath,\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t{ DEPTYPE_SUBPARSER, \"Yaml\", &ansiblePlaybookSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"AnsiblePlaybook\");\n\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable         = AnsiblePlaybookKinds;\n\tdef->kindCount     = ARRAY_SIZE (AnsiblePlaybookKinds);\n\tdef->parser        = findAnsiblePlaybookTags;\n\treturn def;\n}\n\n/* vi:set tabstop=4 shiftwidth=4: */\n"
  },
  {
    "path": "parsers/ant.c",
    "content": "/*\n*   Copyright (c) 2008, David Fishburn\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Ant language files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#ifdef HAVE_LIBXML\n#include \"read.h\"\n#include \"selectors.h\"\n#include \"x-xml.h\"\n#endif\n\n#ifdef HAVE_LIBXML\n/*\n*   FUNCTION PROTOTYPES\n*/\nstatic void antFindTagsUnderProject (xmlNode *node,\n\t\t\t\t     const char *xpath,\n\t\t\t\t     const struct sTagXpathRecurSpec *spec,\n\t\t\t\t     xmlXPathContext *ctx,\n\t\t\t\t     void *userData);\nstatic void antFindTagsUnderTask (xmlNode *node,\n\t\t\t\t  const char *xpath,\n\t\t\t\t  const struct sTagXpathRecurSpec *spec,\n\t\t\t\t  xmlXPathContext *ctx,\n\t\t\t\t  void *userData);\nstatic void makeTagForProjectName (xmlNode *node,\n\t\t\t\t   const char *xpath,\n\t\t\t\t   const struct sTagXpathMakeTagSpec *spec,\n\t\t\t\t   struct sTagEntryInfo *tag,\n\t\t\t\t   void *userData);\nstatic void makeTagForTargetName (xmlNode *node,\n\t\t\t\t  const char *xpath,\n\t\t\t\t  const struct sTagXpathMakeTagSpec *spec,\n\t\t\t\t  struct sTagEntryInfo *tag,\n\t\t\t\t  void *userData);\nstatic void makeTagWithScope (xmlNode *node,\n\t\t\t\t  const char *xpath,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec,\n\t\t\t      struct sTagEntryInfo *tag,\n\t\t\t      void *userData);\n#endif\n\n#ifdef HAVE_LIBXML\ntypedef enum {\n\tK_PROJECT, K_TARGET, K_PROPERTY, K_IMPORT,\n} antKind;\n\ntypedef enum {\n\tR_IMPORT_GENERIC,\n} antAntfileRole;\n\nstatic roleDefinition AntAntfileRoles [] = {\n        { true, \"imported\", \"imported\" },\n};\n\nstatic kindDefinition AntKinds [] = {\n\t{ true,  'p', \"project\",  \"projects\"   },\n\t{ true,  't', \"target\",   \"targets\"    },\n\t{ true,  'P', \"property\", \"properties(global)\" },\n\t{ true,  'i', \"antfile\",  \"antfiles\",\n\t  .referenceOnly = true, ATTACH_ROLES(AntAntfileRoles)},\n};\n\nenum antXpathTable {\n\tTABLE_MAIN, TABLE_PROJECT, TABLE_MAIN_NAME, TABLE_TARGET_NAME,\n};\n\nstatic tagXpathTable antXpathMainTable [] = {\n\t{ \"///project\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec= { antFindTagsUnderProject } }\n\t},\n};\n\nstatic tagXpathTable antXpathProjectTable [] = {\n\t{ \"target\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec= { antFindTagsUnderTask, TABLE_TARGET_NAME } }\n\t},\n\t{ \"property/@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_PROPERTY, ROLE_DEFINITION_INDEX,\n\t\t\t     makeTagWithScope } }\n\t},\n\t{ \"import/@file\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_IMPORT, R_IMPORT_GENERIC,\n\t\t\t     makeTagWithScope } }\n\t},\n};\n\nstatic tagXpathTable antXpathMainNameTable [] = {\n\t{ \"@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_PROJECT, ROLE_DEFINITION_INDEX,\n\t\t\t     makeTagForProjectName } }\n\t},\n};\n\nstatic tagXpathTable antXpathTargetNameTable [] = {\n\t{ \"@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_TARGET, ROLE_DEFINITION_INDEX,\n\t\t\t     makeTagForTargetName} }\n\t},\n};\n\nstatic tagXpathTableTable antXpathTableTable[] = {\n\t[TABLE_MAIN]        = { ARRAY_AND_SIZE (antXpathMainTable)       },\n\t[TABLE_PROJECT]     = { ARRAY_AND_SIZE (antXpathProjectTable)    },\n\t[TABLE_MAIN_NAME]   = { ARRAY_AND_SIZE (antXpathMainNameTable)   },\n\t[TABLE_TARGET_NAME] = { ARRAY_AND_SIZE (antXpathTargetNameTable) },\n};\n\n#else\nstatic tagRegexTable antTagRegexTable [] = {\n\t{\"^[ \\t]*<[ \\t]*project[^>]+name=\\\"([^\\\"]+)\\\".*\", \"\\\\1\",\n\t \"p,project,projects\", NULL},\n\t{\"^[ \\t]*<[ \\t]*target[^>]+name=\\\"([^\\\"]+)\\\".*\", \"\\\\1\",\n\t \"t,target,targets\", NULL},\n\t{\"^[ \\t]*<[ \\t]*property[^>]+name=\\\"([^\\\"]+)\\\".*\", \"\\\\1\",\n\t \"P,property,property\", NULL},\n};\n#endif\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n#ifdef HAVE_LIBXML\n\nstatic void\nantFindTagsUnderProject (xmlNode *node,\n\t\t\t const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t const struct sTagXpathRecurSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t xmlXPathContext *ctx,\n\t\t\t void *userData CTAGS_ATTR_UNUSED)\n{\n\tint corkIndex = CORK_NIL;\n\n\tfindXMLTags (ctx, node, TABLE_MAIN_NAME, &corkIndex);\n\tfindXMLTags (ctx, node, TABLE_PROJECT, &corkIndex);\n}\n\nstatic void antFindTagsUnderTask (xmlNode *node,\n\t\t\t\t  const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\t  const struct sTagXpathRecurSpec *spec,\n\t\t\t\t  xmlXPathContext *ctx,\n\t\t\t\t  void *userData)\n{\n\tint corkIndex = *(int *)userData;\n\n\tfindXMLTags (ctx, node, spec->nextTable, &corkIndex);\n}\n\nstatic void makeTagForProjectName (xmlNode *node CTAGS_ATTR_UNUSED,\n\t\t\t\t   const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\t   const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t\t   struct sTagEntryInfo *tag,\n\t\t\t\t   void *userData)\n{\n\tint *corkIndex = userData;\n\n\t*corkIndex = makeTagEntry (tag);\n}\n\nstatic void makeTagForTargetName (xmlNode *node CTAGS_ATTR_UNUSED,\n\t\t\t\t  const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\t  const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t\t  struct sTagEntryInfo *tag,\n\t\t\t\t  void *userData)\n{\n\tint *corkIndex = (int *)userData;\n\tint parentIndex = *corkIndex;\n\n\ttag->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;\n\ttag->extensionFields.scopeName  = NULL;\n\ttag->extensionFields.scopeIndex = parentIndex;\n\n\t*corkIndex = makeTagEntry (tag);\n}\n\nstatic void makeTagWithScope (xmlNode *node CTAGS_ATTR_UNUSED,\n\t\t\t      const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t      struct sTagEntryInfo *tag,\n\t\t\t      void *userData)\n{\n\ttag->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;\n\ttag->extensionFields.scopeName  = NULL;\n\ttag->extensionFields.scopeIndex = *(int *)userData;\n\n\tmakeTagEntry (tag);\n}\n\nstatic void\nfindAntTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic void\nrunXPathEngine(xmlSubparser *s,\n\t\t\t   xmlXPathContext *ctx, xmlNode *root)\n{\n\tfindXMLTags (ctx, root, TABLE_MAIN, NULL);\n}\n\nstatic xmlSubparser antSubparser = {\n\t.subparser = {\n\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t},\n\t.runXPathEngine = runXPathEngine,\n};\n#endif\n\nextern parserDefinition* AntParser (void)\n{\n\tstatic const char *const extensions [] = { \"build.xml\", \"ant\",\n#ifdef HAVE_LIBXML\n\t\t\t\t/* libxml based selector is needed to select a\n\t\t\t\t * proper concrete xml parser.*/\n\t\t\t\t\t\t   \"xml\",\n#endif\n\t\t\t\t\t\t   NULL };\n\tstatic const char *const patterns [] = { \"build.xml\", NULL };\n\tparserDefinition* const def = parserNew (\"Ant\");\n#ifdef HAVE_LIBXML\n\tstatic selectLanguage selectors[] = { selectByXpathFileSpec, NULL };\n\tstatic xpathFileSpec xpathFileSpecs[] = {\n\t\t/* See http://ant.apache.org/faq.html#dtd */\n\t\t{\n\t\t\t.rootElementName = \"project\",\n\t\t\t.nameInDTD       = \"\",\n\t\t\t.externalID      = \"\",\n\t\t\t.systemID        = \"\",\n\t\t\t.rootNSPrefix    = \"\",\n\t\t\t.rootNSHref      = \"\",\n\t\t},\n\t\t{\n\t\t\t.rootElementName = \"project\",\n\t\t\t.nameInDTD       = \"project\",\n\t\t\t.externalID      = \"\",\n\t\t\t.systemID        = \"\",\n\t\t\t.rootNSPrefix    = \"\",\n\t\t\t.rootNSHref      = \"\",\n\t\t}\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"XML\", &antSubparser },\n\t};\n#endif\n\tdef->extensions = extensions;\n\tdef->patterns = patterns;\n#ifdef HAVE_LIBXML\n\tdef->kindTable = AntKinds;\n\tdef->kindCount = ARRAY_SIZE (AntKinds);\n\tdef->parser = findAntTags;\n\tdef->tagXpathTableTable = antXpathTableTable;\n\tdef->tagXpathTableCount = ARRAY_SIZE (antXpathTableTable);\n\tdef->useCork = CORK_QUEUE;\n\tdef->selectLanguage = selectors;\n\tdef->xpathFileSpecs = xpathFileSpecs;\n\tdef->xpathFileSpecCount = ARRAY_SIZE (xpathFileSpecs);\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n#else\n\tdef->tagRegexTable = antTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE (antTagRegexTable);\n\tdef->method     = METHOD_NOT_CRAFTED|METHOD_REGEX;\n#endif\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/asciidoc.c",
    "content": "/*\n *\n *  Copyright (c) 2007-2011, Nick Treleaven\n * \tCopyright (c) 2012, Lex Trotman\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n * This module contains functions for generating tags for asciidoc files.\n *\n * Based on Rest code by Nick Treleaven, see rest.c\n *\n * This code was ported from geany git commit 40396a3 at:\n *   https://github.com/geany/geany/blob/master/ctags/parsers/asciidoc.c\n * with the changes in geany's PR #1263, with some changes to work in uctags.\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n\n#include <ctype.h>\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"utf8_str.h\"\n#include \"nestlevel.h\"\n#include \"routines.h\"\n\n/*\n *   DATA DEFINITIONS\n */\ntypedef enum {\n\tK_CHAPTER = 0,\n\tK_SECTION,\n\tK_SUBSECTION,\n\tK_SUBSUBSECTION,\n\tK_LEVEL4SECTION,\n\t/* level-5 section not in here because it only works for one-line */\n\tSECTION_COUNT, /* this is the same as level-5 kind number */\n\tK_ANCHOR\n} asciidocKind;\n\n/*\n * The following kind letters are based on the markdown parser kinds,\n * and thus different than geany's.\n */\nstatic kindDefinition AsciidocKinds[] = {\n\t{ true, 'c', \"chapter\",       \"chapters\"},\n\t{ true, 's', \"section\",       \"sections\" },\n\t{ true, 'S', \"subsection\",    \"level 2 sections\" },\n\t{ true, 't', \"subsubsection\", \"level 3 sections\" },\n\t{ true, 'T', \"l4subsection\",  \"level 4 sections\" },\n\t{ true, 'u', \"l5subsection\",  \"level 5 sections\" },\n\t{ true, 'a', \"anchor\",        \"anchors\" }\n};\n\nstatic char kindchars[SECTION_COUNT]={ '=', '-', '~', '^', '+' };\n\nstatic NestingLevels *nestingLevels = NULL;\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic NestingLevel *getNestingLevel(const int kind)\n{\n\tNestingLevel *nl;\n\ttagEntryInfo *e;\n\n\twhile (1)\n\t{\n\t\tnl = nestingLevelsGetCurrent(nestingLevels);\n\t\te = getEntryOfNestingLevel (nl);\n\t\tif ((nl && (e == NULL)) || (e && (e->kindIndex >= kind)))\n\t\t\tnestingLevelsPop(nestingLevels);\n\t\telse\n\t\t\tbreak;\n\t}\n\treturn nl;\n}\n\nstatic int makeAsciidocTag (const vString* const name, const int kind, const bool two_line)\n{\n\tconst NestingLevel *const nl = getNestingLevel(kind);\n\tint r = CORK_NIL;\n\n\tif (vStringLength (name) > 0)\n\t{\n\t\ttagEntryInfo *parent = getEntryOfNestingLevel (nl);\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry (&e, vStringValue (name), kind);\n\n\t\tif (two_line)\n\t\t{\n\t\t\t/* we want the line before the '---' underline chars */\n\t\t\tAssert (e.lineNumber > 1);\n\t\t\tif (e.lineNumber > 1)\n\t\t\t{\n\t\t\t\tunsigned long lineNumber = e.lineNumber - 1;\n\t\t\t\tupdateTagLine (&e, lineNumber,\n\t\t\t\t\t\t\t   getInputFilePositionForLine(lineNumber));\n\t\t\t}\n\t\t}\n\n\t\tif (parent && (parent->kindIndex < kind))\n\t\t{\n\t\t\t/*\n\t\t\t * This doesn't use Cork, but in this case I think this is better,\n\t\t\t * because Cork would record the scopes of all parents in the chain\n\t\t\t * which is weird for text section identifiers, and also this is\n\t\t\t * what the rst.c reStructuredText parser does.\n\t\t\t */\n\t\t\te.extensionFields.scopeKindIndex = parent->kindIndex;\n\t\t\te.extensionFields.scopeName = parent->name;\n\t\t}\n\n\t\tr = makeTagEntry (&e);\n\t}\n\treturn r;\n}\n\nstatic int makeSectionAsciidocTag (const vString* const name, const int kind, const bool two_line)\n{\n\tint r = makeAsciidocTag(name, kind, two_line);\n\tnestingLevelsPush(nestingLevels, r);\n\treturn r;\n}\n\n\nstatic int get_kind(char c)\n{\n\tint i;\n\n\tfor (i = 0; i < SECTION_COUNT; i++)\n\t{\n\t\tif (kindchars[i] == c)\n\t\t\treturn i;\n\t}\n\treturn -1;\n}\n\n\nstatic bool is_anchor(const unsigned char *line)\n{\n\t/* must be at least \"[#a]\" */\n\treturn line[0] == '[' && (line[1] == '#' || line[1] == '[');\n}\n\nstatic int capture_anchor(const unsigned char *const orig, int* captured_len)\n{\n\tvString *name = vStringNew ();\n\tint r = CORK_NIL;\n\tconst bool shorthand = orig[1] == '#' ? true : false;\n\tbool is_valid = false;\n\tbool seen_comma = false;\n\tconst unsigned char *line = orig;\n\n\tAssert (line[0] == '[');\n\tAssert (line[1] == '#' || line[1] == '[');\n\n\tif (captured_len) *captured_len = 0;\n\n\tline += 2;\n\n\twhile (*line != '\\0')\n\t{\n\t\tif (*line == ']')\n\t\t{\n\t\t\tif (shorthand || line[1] == ']')\n\t\t\t{\n\t\t\t\tis_valid = true;\n\t\t\t\tif (shorthand) line++;\n\t\t\t\telse line += 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* otherwise it's not the end, keep going */\n\t\t}\n\n\t\tif (*line == ',')\n\t\t\tseen_comma = true;\n\n\t\tif (!seen_comma)\n\t\t\tvStringPut (name, *line);\n\n\t\tline++;\n\t}\n\n\tif (is_valid && vStringLength (name) != 0)\n\t{\n\t\tr = makeAsciidocTag (name, K_ANCHOR, false);\n\n\t\tif (captured_len)\n\t\t{\n\t\t\t*captured_len = line - orig;\n\t\t}\n\t}\n\n\tvStringDelete (name);\n\treturn r;\n}\n\n\n/* skips any leading anchor(s) in a one-line title, generating tags for them */\nstatic int process_leading_anchors(const unsigned char *const begin)\n{\n\tint captured_len = 0;\n\tconst unsigned char *current = begin;\n\n\twhile (is_anchor(current) && capture_anchor(current, &captured_len) != CORK_NIL)\n\t{\n\t\t/* minimum is \"[#a]\" */\n\t\tAssert (captured_len >= 4);\n\t\tcurrent += captured_len;\n\t\twhile (isspace(*current)) ++current;\n\t}\n\n\treturn current - begin;\n}\n\nstatic int process_trailing_anchor(const unsigned char *const begin,\n\t\t\t\t\t\t\t\t   const unsigned char *const end)\n{\n\tint captured_len = 0;\n\tconst unsigned char *found = NULL;\n\n\t/* minimum is \"[#a]\" */\n\tif (*end == ']' && (end - begin) >= 4)\n\t{\n\t\tfound = (const unsigned char*) strrchr((const char*) begin , '[');\n\t\tif (found && ((end - found) >= 4))\n\t\t{\n\t\t\t/* see if it's not shorthand [#a] but instead [[a]] */\n\t\t\tif (end[-1] == ']' && found > begin && found[-1] == '[')\n\t\t\t\t--found;\n\n\t\t\tif (is_anchor (found))\n\t\t\t\tcapture_anchor(found, &captured_len);\n\t\t}\n\t}\n\n\treturn captured_len;\n}\n\nstatic void process_name(vString *const name, const int kind,\n\t\t\t\t\t\t const unsigned char *line, const int line_len)\n{\n\tint start = kind + 1;\n\tint end = line_len - 1;\n\n\tAssert (kind >= 0 && kind < K_ANCHOR);\n\tAssert (line_len > start);\n\n\tvStringClear(name);\n\n\twhile (line[end] == line[0]) --end;\n\twhile (isspace(line[start])) ++start;\n\twhile (isspace(line[end])) --end;\n\n\tif (start < end)\n\t{\n\t\t/* pop nesting levels, so that anchors get the parent's scope */\n\t\tgetNestingLevel(kind);\n\t\tend -= process_trailing_anchor(line + start, line + end);\n\t\tstart += process_leading_anchors(line + start);\n\t}\n\n\twhile (isspace(line[end])) --end;\n\n\tif (start <= end)\n\t\tvStringNCatS(name, (const char*)(&(line[start])), end - start + 1);\n}\n\nstatic void findAsciidocTags(void)\n{\n\tvString *name = vStringNew();\n\tconst unsigned char *line;\n\tunsigned char in_block = '\\0';  /* holds the block marking char or \\0 if not in block */\n\n\tnestingLevels = nestingLevelsNew(0);\n\n\twhile ((line = readLineFromInputFile()) != NULL)\n\t{\n\t\tif (is_anchor (line))\n\t\t{\n\t\t\tif (capture_anchor (line, NULL) != CORK_NIL)\n\t\t\t{\n\t\t\t\tvStringClear (name);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tint line_len = strlen((const char*) line);\n\t\tint name_len_bytes = vStringLength(name);\n\t\tint name_len = utf8_strlen(vStringValue(name), name_len_bytes);\n\n\t\t/* if the name doesn't look like UTF-8, assume one-byte charset */\n\t\tif (name_len < 0) name_len = name_len_bytes;\n\n\t\t/* if its a title underline, or a delimited block marking character */\n\t\tif (line[0] == '=' || line[0] == '-' || line[0] == '~' ||\n\t\t\tline[0] == '^' || line[0] == '+' || line[0] == '.' ||\n\t\t\tline[0] == '*' || line[0] == '_' || line[0] == '/')\n\t\t{\n\t\t\tint n_same;\n\t\t\tfor (n_same = 1; line[n_same] == line[0]; ++n_same);\n\n\t\t\t/* is it a two line title or a delimited block */\n\t\t\tif (n_same == line_len)\n\t\t\t{\n\t\t\t\t/* if in a block, can't be block start or title, look for block end */\n\t\t\t\tif (in_block)\n\t\t\t\t{\n\t\t\t\t\tif (line[0] == in_block) in_block = '\\0';\n\t\t\t\t}\n\n\t\t\t\t/* if its a =_~^+ and the same length +-2 as the line before then its a title */\n\t\t\t\t/* (except in the special case its a -- open block start line) */\n\t\t\t\telse if ((line[0] == '=' || line[0] == '-' || line[0] == '~' ||\n\t\t\t\t\t\t\tline[0] == '^' || line[0] == '+') &&\n\t\t\t\t\t\tline_len <= name_len + 2 && line_len >= name_len - 2 &&\n\t\t\t\t\t\t!(line_len == 2 && line[0] == '-'))\n\t\t\t\t{\n\t\t\t\t\tint kind = get_kind((char)(line[0]));\n\t\t\t\t\tif (kind >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tmakeSectionAsciidocTag(name, kind, true);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* else if its 4 or more /+-.*_= (plus the -- special case) its a block start */\n\t\t\t\telse if (((line[0] == '/' || line[0] == '+' || line[0] == '-' ||\n\t\t\t\t\t\t   line[0] == '.' || line[0] == '*' || line[0] == '_' ||\n\t\t\t\t\t\t   line[0] == '=') && line_len >= 4 )\n\t\t\t\t\t\t || (line[0] == '-' && line_len == 2))\n\t\t\t\t{\n\t\t\t\t\tin_block = line[0];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* otherwise is it a one line title */\n\t\t\telse if (line[0] == '=' && n_same <= 6 && isspace(line[n_same]) &&\n\t\t\t\t\t!in_block)\n\t\t\t{\n\t\t\t\tint kind = n_same - 1;\n\t\t\t\tprocess_name(name, kind, line, line_len);\n\t\t\t\tmakeSectionAsciidocTag(name, kind, false);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tvStringClear(name);\n\t\tif (! isspace(*line))\n\t\t\tvStringCatS(name, (const char*) line);\n\t}\n\tvStringDelete(name);\n\tnestingLevelsFree(nestingLevels);\n}\n\nextern parserDefinition* AsciidocParser (void)\n{\n\tstatic const char *const patterns [] = { \"*.asc\", \"*.adoc\", \"*.asciidoc\", NULL };\n\tstatic const char *const extensions [] = { \"asc\", \"adoc\", \"asciidoc\", NULL };\n\n\tparserDefinition* const def = parserNew (\"Asciidoc\");\n\n\tdef->kindTable = AsciidocKinds;\n\tdef->kindCount = ARRAY_SIZE (AsciidocKinds);\n\tdef->patterns = patterns;\n\tdef->extensions = extensions;\n\tdef->parser = findAsciidocTags;\n\t/* do we even need to use Cork? */\n\tdef->useCork = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/asm.c",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for assembly language\n*   files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"x-cpreprocessor.h\"\n#include \"debug.h\"\n#include \"dependency.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"param.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"trace.h\"\n#include \"vstring.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef enum {\n\tK_PSUEDO_FOREIGN_LD_SCRIPT_SYMBOL = -4,\n\tK_PSUEDO_FOREIGN_LD_SCRIPT_SECTION = -3,\n\tK_PSUEDO_MACRO_END = -2,\n\tK_NONE = -1, K_DEFINE, K_LABEL, K_MACRO, K_TYPE,\n\tK_PARAM,\n} AsmKind;\n\ntypedef enum {\n\tOP_UNDEFINED = -1,\n\tOP_ALIGN,\n\tOP_COLON_EQUAL,\n\tOP_END,\n\tOP_ENDM,\n\tOP_ENDMACRO,\n\tOP_ENDP,\n\tOP_ENDS,\n\tOP_EQU,\n\tOP_EQUAL,\n\tOP_GLOBAL,\n\tOP_LABEL,\n\tOP_MACRO,\n\tOP_PROC,\n\tOP_RECORD,\n\tOP_SECTIONS,\n\tOP_SECTION,\n\tOP_SET,\n\tOP_STRUCT,\n\tOP_LAST\n} opKeyword;\n\ntypedef struct {\n\topKeyword keyword;\n\tAsmKind kind;\n} opKind;\n\ntypedef enum {\n\tF_PROPERTIES,\n} asmField;\n\nstatic fieldDefinition AsmFields[] = {\n\t{ .name = \"properties\",\n\t  .description = \"properties (req, vararg for parameters)\",\n\t  .enabled = true },\n};\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic langType Lang_asm;\nstatic langType Lang_ldscript;\n\nstatic kindDefinition AsmKinds [] = {\n\t{ true, 'd', \"define\", \"defines\" },\n\t{ true, 'l', \"label\",  \"labels\"  },\n\t{ true, 'm', \"macro\",  \"macros\"  },\n\t{ true, 't', \"type\",   \"types (structs and records)\"   },\n\t{ false,'z', \"parameter\", \"parameters for a macro\" },\n};\n\nstatic const keywordTable AsmKeywords [] = {\n\t{ \"align\",    OP_ALIGN       },\n\t{ \"endmacro\", OP_ENDMACRO    },\n\t{ \"endm\",     OP_ENDM        },\n\t{ \"end\",      OP_END         },\n\t{ \"endp\",     OP_ENDP        },\n\t{ \"ends\",     OP_ENDS        },\n\t{ \"equ\",      OP_EQU         },\n\t{ \"global\",   OP_GLOBAL      },\n\t{ \"globl\",    OP_GLOBAL      },\n\t{ \"label\",    OP_LABEL       },\n\t{ \"macro\",    OP_MACRO       },\n\t{ \":=\",       OP_COLON_EQUAL },\n\t{ \"=\",        OP_EQUAL       },\n\t{ \"proc\",     OP_PROC        },\n\t{ \"record\",   OP_RECORD      },\n\t{ \"sections\", OP_SECTIONS    },\n\n\t/* These are used in GNU as. */\n\t{ \"section\",  OP_SECTION     },\n\t{ \"equiv\",    OP_EQU         },\n\t{ \"eqv\",      OP_EQU         },\n\n\t{ \"set\",      OP_SET         },\n\t{ \"struct\",   OP_STRUCT      }\n};\n\nstatic const opKind OpKinds [] = {\n\t/* must be ordered same as opKeyword enumeration */\n\t{ OP_ALIGN,       K_NONE   },\n\t{ OP_COLON_EQUAL, K_DEFINE },\n\t{ OP_END,         K_NONE   },\n\t{ OP_ENDM,        K_PSUEDO_MACRO_END },\n\t{ OP_ENDMACRO,    K_NONE   },\n\t{ OP_ENDP,        K_NONE   },\n\t{ OP_ENDS,        K_NONE   },\n\t{ OP_EQU,         K_DEFINE },\n\t{ OP_EQUAL,       K_DEFINE },\n\t{ OP_GLOBAL,      K_PSUEDO_FOREIGN_LD_SCRIPT_SYMBOL },\n\t{ OP_LABEL,       K_LABEL  },\n\t{ OP_MACRO,       K_MACRO  },\n\t{ OP_PROC,        K_LABEL  },\n\t{ OP_RECORD,      K_TYPE   },\n\t{ OP_SECTIONS,    K_NONE   },\n\t{ OP_SECTION,     K_PSUEDO_FOREIGN_LD_SCRIPT_SECTION },\n\t{ OP_SET,         K_DEFINE },\n\t{ OP_STRUCT,      K_TYPE   }\n};\n\n#define DEFAULT_COMMENT_CHARS_BOL \";*@\"\nstatic const char defaultCommentCharAtBOL [] = DEFAULT_COMMENT_CHARS_BOL;\nstatic const char *commentCharsAtBOL = defaultCommentCharAtBOL;\n\n#define DEFAULT_COMMENT_CHARS_MOL \"\"\nstatic const char defaultCommentCharInMOL [] = DEFAULT_COMMENT_CHARS_MOL;\nstatic const char *commentCharsInMOL = defaultCommentCharInMOL;\n\n#define DEFAULT_EXTRA_LINESEP_CHARS \"\"\nstatic const char defaultExtraLinesepChars [] = DEFAULT_EXTRA_LINESEP_CHARS;\nstatic const char *extraLinesepChars = defaultExtraLinesepChars;\n\nstatic bool useCPreProcessor = true;\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nstatic opKeyword analyzeOperator (const vString *const op)\n{\n\tvString *keyword = vStringNew ();\n\topKeyword result;\n\n\tvStringCopyToLower (keyword, op);\n\tresult = (opKeyword) lookupKeyword (vStringValue (keyword), Lang_asm);\n\tvStringDelete (keyword);\n\treturn result;\n}\n\nstatic bool isInitialSymbolCharacter (int c)\n{\n\treturn (bool) (c != '\\0' && (isalpha (c) || strchr (\"_$\", c) != NULL));\n}\n\nstatic bool isSymbolCharacter (int c)\n{\n\t/* '?' character is allowed in AMD 29K family */\n\treturn (bool) (c != '\\0' && (isalnum (c) || strchr (\"_$?\", c) != NULL));\n}\n\nstatic AsmKind operatorKind (\n\t\tconst vString *const operator,\n\t\tbool *const found)\n{\n\tAsmKind result = K_NONE;\n\tconst opKeyword kw = analyzeOperator (operator);\n\t*found = (bool) (kw != OP_UNDEFINED);\n\tif (*found)\n\t{\n\t\tresult = OpKinds [kw].kind;\n\t\tAssert (OpKinds [kw].keyword == kw);\n\t}\n\treturn result;\n}\n\n/*  We must check for \"DB\", \"DB.L\", \"DCB.W\" (68000)\n */\nstatic bool isDefineOperator (const vString *const operator)\n{\n\tconst unsigned char *const op =\n\t\t(unsigned char*) vStringValue (operator);\n\tconst size_t length = vStringLength (operator);\n\tconst bool result = (bool) (length > 0  &&\n\t\ttoupper (*op) == 'D'  &&\n\t\t(length == 2 ||\n\t\t (length == 4  &&  (int) op [2] == '.') ||\n\t\t (length == 5  &&  (int) op [3] == '.')));\n\treturn result;\n}\n\nstatic int makeTagForLdScript (const char * name, int kind, int *scope, bool useCpp)\n{\n\ttagEntryInfo e;\n\n\tif (kind == K_PSUEDO_FOREIGN_LD_SCRIPT_SYMBOL)\n\t{\n\t\tstatic kindDefinition * kdef = NULL;\n\t\tif(kdef == NULL)\n\t\t\tkdef = getLanguageKindForName (Lang_ldscript, \"symbol\");\n\t\tif(kdef == NULL)\n\t\t\treturn CORK_NIL;\n\n\t\tinitForeignTagEntry(&e, name, Lang_ldscript, kdef->id);\n\t\te.extensionFields.scopeIndex = *scope;\n\t\tif (useCpp)\n\t\t\tupdateTagLine (&e, cppGetInputLineNumber (), cppGetInputFilePosition());\n\t\treturn makeTagEntry (&e);\n\t}\n\telse\n\t{\n\t\tstatic kindDefinition * kdef = NULL;\n\t\tif(kdef == NULL)\n\t\t\tkdef = getLanguageKindForName (Lang_ldscript, \"inputSection\");\n\t\tif(kdef == NULL)\n\t\t\treturn CORK_NIL;\n\n\t\tstatic roleDefinition *rdef = NULL;\n\t\tif(rdef == NULL)\n\t\t\trdef = getLanguageRoleForName (Lang_ldscript, kdef->id, \"destination\");\n\t\tif (rdef == NULL)\n\t\t\treturn CORK_NIL;\n\n\t\tinitForeignRefTagEntry(&e, name, Lang_ldscript, kdef->id, rdef->id);\n\t\tif (useCpp)\n\t\t\tupdateTagLine (&e, cppGetInputLineNumber (), cppGetInputFilePosition());\n\t\t*scope = makeTagEntry (&e);\n\t\treturn *scope;\n\t}\n}\n\nstatic int makeAsmSimpleTag (const vString *const name,\n\t\t\t\t\t\t\t AsmKind kind,\n\t\t\t\t\t\t\t bool useCpp)\n{\n\ttagEntryInfo e;\n\tinitTagEntry (&e, vStringValue (name), kind);\n\tif (useCpp)\n\t\tupdateTagLine (&e, cppGetInputLineNumber (), cppGetInputFilePosition());\n\treturn makeTagEntry (&e);\n}\n\nstatic int makeAsmTag (\n\t\tconst vString *const name,\n\t\tconst vString *const operator,\n\t\tconst bool labelCandidate,\n\t\tconst bool nameFollows,\n\t\tconst bool directive,\n\t\tint *sectionScope,\n\t\tint *macroScope,\n\t\tbool useCpp)\n{\n\tint r = CORK_NIL;\n\n\tif (vStringLength (name) > 0)\n\t{\n\t\tbool found = false;\n\t\tAsmKind kind = directive? K_NONE: operatorKind (operator, &found);\n\n\t\tif (found)\n\t\t{\n\t\t\tif (kind > K_NONE)\n\t\t\t\tr = makeAsmSimpleTag (name, kind, useCpp);\n\t\t}\n\t\telse if (isDefineOperator (operator))\n\t\t{\n\t\t\tif (! nameFollows)\n\t\t\t\tr = makeAsmSimpleTag (name, K_DEFINE, useCpp);\n\t\t}\n\t\telse if (labelCandidate)\n\t\t{\n\t\t\toperatorKind (name, &found);\n\t\t\tif (! found)\n\t\t\t{\n\t\t\t\tr = makeAsmSimpleTag (name, K_LABEL, useCpp);\n\t\t\t}\n\t\t}\n\t\telse if (directive)\n\t\t{\n\t\t\tbool found_dummy;\n\t\t\tconst AsmKind kind_for_directive = operatorKind (name, &found_dummy);\n\t\t\ttagEntryInfo *macro_tag;\n\n\t\t\tswitch (kind_for_directive)\n\t\t\t{\n\t\t\tcase K_NONE:\n\t\t\t\tbreak;\n\t\t\tcase K_MACRO:\n\t\t\t\tif (!vStringIsEmpty (operator))\n\t\t\t\t{\n\t\t\t\t\tr = makeAsmSimpleTag (operator, kind_for_directive, useCpp);\n\t\t\t\t\tmacro_tag = getEntryInCorkQueue (r);\n\t\t\t\t\tif (macro_tag)\n\t\t\t\t\t{\n\t\t\t\t\t\tmacro_tag->extensionFields.scopeIndex = *macroScope;\n\t\t\t\t\t\tregisterEntry (r);\n\t\t\t\t\t\t*macroScope = r;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase K_PSUEDO_MACRO_END:\n\t\t\t\tmacro_tag = getEntryInCorkQueue (*macroScope);\n\t\t\t\tif (macro_tag)\n\t\t\t\t{\n\t\t\t\t\tsetTagEndLine (macro_tag,\n\t\t\t\t\t\t\t\t   useCpp? cppGetInputLineNumber (): getInputLineNumber ());\n\t\t\t\t\t*macroScope = macro_tag->extensionFields.scopeIndex;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase K_PSUEDO_FOREIGN_LD_SCRIPT_SYMBOL:\n\t\t\tcase K_PSUEDO_FOREIGN_LD_SCRIPT_SECTION:\n\t\t\t\tif (!vStringIsEmpty (operator))\n\t\t\t\t\tr = makeTagForLdScript (vStringValue (operator),\n\t\t\t\t\t\t\t\t\t\t\tkind_for_directive, sectionScope, useCpp);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (!vStringIsEmpty (operator))\n\t\t\t\t\tr = makeAsmSimpleTag (operator, kind_for_directive, useCpp);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn r;\n}\n\nstatic const unsigned char *readSymbol (\n\t\tconst unsigned char *const start,\n\t\tvString *const sym)\n{\n\tconst unsigned char *cp = start;\n\tvStringClear (sym);\n\tif (isInitialSymbolCharacter (*cp))\n\t{\n\t\twhile (isSymbolCharacter (*cp))\n\t\t{\n\t\t\tvStringPut (sym, *cp);\n\t\t\t++cp;\n\t\t}\n\t}\n\treturn cp;\n}\n\nstatic const unsigned char *readOperator (\n\t\tconst unsigned char *const start,\n\t\tvString *const operator)\n{\n\tconst unsigned char *cp = start;\n\tvStringClear (operator);\n\twhile (*cp != '\\0'  &&  ! isspace (*cp) && *cp != ',')\n\t{\n\t\tvStringPut (operator, *cp);\n\t\t++cp;\n\t}\n\treturn cp;\n}\n\nstatic bool collectCppMacroArguments (ptrArray *args)\n{\n\tvString *s = vStringNew ();\n\tint c;\n\tunsigned long ln = cppGetInputLineNumber ();\n\tMIOPos pos = cppGetInputFilePosition ();\n\tint depth = 1;\n\n\tdo\n\t{\n\t\tif (s && vStringLength (s) == 1)\n\t\t{\n\t\t\tln = cppGetInputLineNumber ();\n\t\t\tpos = cppGetInputFilePosition ();\n\t\t}\n\t\tc = cppGetc ();\n\n\t\tif (c == EOF)\n\t\t\tbreak;\n\t\telse if (c == ')')\n\t\t{\n\t\t\tdepth--;\n\t\t\tif (depth == 0)\n\t\t\t{\n\t\t\t\tvStringStripTrailing(s);\n\t\t\t\tcppMacroArg *a = cppMacroArgNew (vStringDeleteUnwrap (s), true,\n\t\t\t\t\t\t\t\t\t\t\t\t ln, pos);\n\t\t\t\tptrArrayAdd (args, a);\n\t\t\t\ts = NULL;\n\t\t\t}\n\t\t\telse\n\t\t\t\tvStringPut (s, c);\n\t\t}\n\t\telse if (c == '(')\n\t\t{\n\t\t\tdepth++;\n\t\t\tvStringPut (s, c);\n\t\t}\n\t\telse if (c == ',')\n\t\t{\n\t\t\tvStringStripTrailing(s);\n\t\t\tcppMacroArg *a = cppMacroArgNew (vStringDeleteUnwrap (s), true,\n\t\t\t\t\t\t\t\t\t\t\t ln, pos);\n\t\t\tptrArrayAdd (args, a);\n\t\t\ts = vStringNew ();\n\t\t}\n\t\telse if (c == CPP_STRING_SYMBOL || c == CPP_CHAR_SYMBOL)\n\t\t\tvStringPut (s, ' ');\n\t\telse if (isspace(c))\n\t\t{\n\t\t\tif (!vStringIsEmpty (s) &&\n\t\t\t\t!isspace ((unsigned char)vStringLast (s)))\n\t\t\t\tvStringPut (s, ' ');\n\t\t}\n\t\telse\n\t\t\tvStringPut (s, c);\n\t}\n\twhile (depth > 0);\n\n\tvStringDelete (s);\t\t\t/* NULL is acceptable. */\n\n\tif (depth > 0)\n\t\tTRACE_PRINT(\"unbalanced argument list\");\n\n\treturn (depth > 0)? false: true;\n}\n\nstatic bool expandCppMacro (cppMacroInfo *macroInfo,\n\t\t\t\t\t\t\tunsigned long lineNumber, MIOPos filePosition)\n{\n\tptrArray *args = NULL;\n\n\tif (macroInfo->hasParameterList)\n\t{\n\t\tint c;\n\n\t\twhile (1)\n\t\t{\n\t\t\tc = cppGetc ();\n\t\t\tif (c == CPP_STRING_SYMBOL || c == CPP_CHAR_SYMBOL || !isspace (c))\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (c != '(')\n\t\t{\n\t\t\tcppUngetc (c);\n\t\t\treturn false;\n\t\t}\n\n\t\targs = ptrArrayNew (cppMacroArgDelete);\n\t\tif (!collectCppMacroArguments (args))\n\t\t{\n\t\t\t/* The input stream is already corrupted.\n\t\t\t * It is hard to recover. */\n\t\t\tptrArrayDelete (args);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t{\n\t\tcppMacroTokens *tokens = cppExpandMacro (macroInfo, args,\n\t\t\t\t\t\t\t\t\t\t\t\t lineNumber, filePosition);\n\t\tcppUngetMacroTokens (tokens);\n\t}\n\n\tptrArrayDelete (args);\t\t/* NULL is acceptable. */\n\treturn true;\n}\n\nstatic void truncateLastIdetifier (vString *line, vString *identifier)\n{\n\tAssert (vStringLength (line) >= vStringLength (identifier));\n\tsize_t len = vStringLength (line) - vStringLength (identifier);\n\tAssert (strcmp (vStringValue (line) + len,\n\t\t\t\t\tvStringValue (identifier)) == 0);\n\tvStringTruncate (line, len);\n}\n\nstatic bool processCppMacroX (vString *identifier, int lastChar, vString *line)\n{\n\tTRACE_ENTER();\n\n\tif (cppUngetBufferSize() >= CPP_MAXIMUM_UNGET_BUFFER_SIZE_FOR_MACRO_REPLACEMENTS)\n\t{\n\t\tTRACE_LEAVE_TEXT (\"Ungetbuffer overflow when processing \\\"%s\\\": %d\",\n\t\t\t\t\t\t  vStringValue (identifier), cppUngetBufferSize());\n\t\treturn false;\n\t}\n\n\tbool r = false;\n\tcppMacroInfo *macroInfo = cppFindMacro (vStringValue (identifier));\n\n\tif (!macroInfo)\n\t\tgoto out;\n\n\tif (macroInfo->useCount >= CPP_MAXIMUM_MACRO_USE_COUNT)\n\t{\n\t\tTRACE_PRINT (\"Overly uesd macro %s<%p> useCount: %d (> %d)\",\n\t\t\t\t\t vStringValue (identifier), macroInfo, macroInfo->useCount,\n\t\t\t\t\t CPP_MAXIMUM_MACRO_USE_COUNT);\n\t\tgoto out;\n\t}\n\n\tif (lastChar != EOF)\n\t\tcppUngetc (lastChar);\n\n\tTRACE_PRINT(\"Macro expansion: %s<%p>%s\", macroInfo->name,\n\t\t\t\tmacroInfo, macroInfo->hasParameterList? \"(...)\": \"\");\n\n\tif (!macroInfo->replacements)\n\t\tgoto out;\n\n\tr = expandCppMacro (macroInfo,\n\t\t\t\t\t\tcppGetInputLineNumber (), cppGetInputFilePosition ());\n\n out:\n\tif (r)\n\t\ttruncateLastIdetifier (line, identifier);\n\n\tvStringClear (identifier);\n\n\tTRACE_LEAVE();\n\treturn r;\n}\n\n/* If a section name is built with a macro expansion, the following\n * strings may appear in parts of the string.\n * - \\param\n * - \\()\n * - \\@\n */\nstatic bool isCharInMarcoParamref(char c)\n{\n\treturn (c == '\\\\' || c == '(' || c == ')'  || c == '@')? true: false;\n}\n\nstatic bool isEligibleAsSectionName (const vString *str)\n{\n\tchar *c = vStringValue(str);\n\twhile (*c)\n\t{\n\t\tif (!(isalnum(((unsigned char)*c))\n\t\t\t  || (*c == '.')\n\t\t\t  || (*c == '-')\n\t\t\t  || (*c == '_')\n\t\t\t  || isCharInMarcoParamref(*c)))\n\t\t\treturn false;\n\t\tc++;\n\t}\n\treturn true;\n}\n\nstatic const unsigned char *readLineViaCpp (const char *commentChars)\n{\n\tstatic vString *line;\n\tint c;\n\tbool truncation = false;\n\n\tline = vStringNewOrClear (line);\n\n\tvString *identifier = vStringNew ();\n\n cont:\n\twhile ((c = cppGetc()) != EOF)\n\t{\n\t\tif (c == CPP_STRING_SYMBOL || c == CPP_CHAR_SYMBOL)\n\t\t{\n\t\t\t/* c == CHAR_SYMBOL is subtle condition.\n\t\t\t * If the last char of IDENTIFIER is [0-9a-f],\n\t\t\t * cppGetc() never returns CHAR_SYMBOL to\n\t\t\t * Handle c++14 digit separator.\n\t\t\t */\n\t\t\tif (!vStringIsEmpty (identifier)\n\t\t\t\t&& processCppMacroX (identifier, ' ', line))\n\t\t\t\tcontinue;\n\n\t\t\t/* We cannot store these values to vString\n\t\t\t * Store a whitespace as a dummy value for them, but...\n\t\t\t */\n\t\t\tif (!truncation)\n\t\t\t{\n\t\t\t\tvStringPut (line, ' ');\n\n\t\t\t\t/* Quoted from the info document of Gas:\n\t\t\t\t   -------------------------------------\n\t\t\t\t   For ELF targets, the assembler supports another type of '.section'\n\t\t\t\t   directive for compatibility with the Solaris assembler:\n\n\t\t\t\t   .section \"NAME\"[, FLAGS...]\n\t\t\t\t   -------------------------------------\n\n\t\t\t\t   If we replace \"...\" with ' ' here, we can lost the name\n\t\t\t\t   of the section. */\n\t\t\t\tconst vString *str = cppGetLastCharOrStringContents();\n\t\t\t\tif (str)\n\t\t\t\t{\n\t\t\t\t\tconst char *section = strrstr (vStringValue (line), \".section\");\n\t\t\t\t\tif (section && isEligibleAsSectionName(str))\n\t\t\t\t\t{\n\t\t\t\t\t\tsection += strlen(\".section\");\n\t\t\t\t\t\twhile (isspace((unsigned char)*section))\n\t\t\t\t\t\t\tsection++;\n\t\t\t\t\t\tif (*section == '\\0')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvStringCat (line, str);\n\t\t\t\t\t\t\tvStringPut (line, ' ');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (c == '\\n' || (extraLinesepChars[0] != '\\0'\n\t\t\t\t\t\t\t   && strchr (extraLinesepChars, c) != NULL))\n\t\t{\n\t\t\tif (!vStringIsEmpty (identifier)\n\t\t\t\t&& processCppMacroX (identifier, c, line))\n\t\t\t\tcontinue;\n\t\t\tbreak;\n\t\t}\n\t\telse if ((vStringIsEmpty (identifier) && (isalpha (c) || c == '_'))\n\t\t\t\t|| (!vStringIsEmpty (identifier) && (isalnum (c) || c == '_')))\n\t\t{\n\t\t\tvStringPut (identifier, c);\n\t\t\tif (!truncation)\n\t\t\t\tvStringPut (line, c);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (!vStringIsEmpty (identifier)\n\t\t\t\t&& processCppMacroX (identifier, c, line))\n\t\t\t\tcontinue;\n\n\t\t\tif (truncation == false && commentChars[0] && strchr (commentChars, c))\n\t\t\t\ttruncation = true;\n\n\t\t\tif (!truncation)\n\t\t\t\tvStringPut (line, c);\n\t\t}\n\t}\n\n\tif (c == EOF\n\t\t&& !vStringIsEmpty(identifier)\n\t\t&& processCppMacroX (identifier, EOF, line))\n\t\tgoto cont;\n\n\tvStringDelete (identifier);\n\n\tTRACE_PRINT(\"line: %s\\n\", vStringValue (line));\n\n\tif ((vStringLength (line) == 0) && (c == EOF))\n\t\treturn NULL;\n\telse\n\t\treturn (unsigned char *)vStringValue (line);\n}\n\nstatic const unsigned char *readLineNoCpp (const char *commentChars)\n{\n\tstatic vString *line;\n\tint c;\n\tbool truncation = false;\n\n\tline = vStringNewOrClear (line);\n\n\twhile ((c = getcFromInputFile ()) != EOF)\n\t{\n\t\tif (c == '\\n' || (extraLinesepChars[0] != '\\0'\n\t\t\t\t\t\t  && strchr (extraLinesepChars, c) != NULL))\n\t\t\tbreak;\n\t\telse\n\t\t{\n\t\t\tif (truncation == false && commentChars[0] && strchr (commentChars, c))\n\t\t\t\ttruncation = true;\n\n\t\t\tif (!truncation)\n\t\t\t\tvStringPut (line, c);\n\t\t}\n\t}\n\tif ((vStringLength (line) == 0) && (c == EOF))\n\t\treturn NULL;\n\telse\n\t\treturn (unsigned char *)vStringValue (line);\n}\n\nstatic const unsigned char *asmReadLineFromInputFile (const char *commentChars, bool useCpp)\n{\n\tif (useCpp)\n\t\treturn readLineViaCpp (commentChars);\n\telse\n\t\treturn readLineNoCpp (commentChars);\n}\n\nstatic void readMacroParameters (int index, tagEntryInfo *e, const unsigned char *cp,\n\t\t\t\t\t\t\t\t bool useCpp)\n{\n\tvString *name = vStringNew ();\n\tvString *signature = vStringNew ();\n\tint nth = 0;\n\n\tif (*cp == ',')\n\t\t++cp;\n\n\twhile (*cp)\n\t{\n\t\tconst unsigned char *tmp;\n\t\ttagEntryInfo *e = NULL;\n\n\t\twhile (isspace (*cp))\n\t\t\t++cp;\n\n\t\ttmp = cp;\n\t\tcp = readSymbol (cp, name);\n\t\tif (cp == tmp)\n\t\t\tbreak;\n\n\t\t{\n\t\t\tint r = makeAsmSimpleTag (name, K_PARAM, useCpp);\n\t\t\te = getEntryInCorkQueue (r);\n\t\t\tif (e)\n\t\t\t{\n\t\t\t\te->extensionFields.scopeIndex = index;\n\t\t\t\te->extensionFields.nth = nth++;\n\t\t\t}\n\t\t\tif (vStringLength (signature) > 0 && vStringLast (signature) != ' ')\n\t\t\t\tvStringPut (signature, ' ');\n\t\t\tvStringCat (signature, name);\n\t\t}\n\n\t\tif (*cp == ':')\n\t\t{\n\t\t\tcp++;\n\t\t\tif (strncmp((const char *)cp, \"req\" ,3) == 0)\n\t\t\t{\n\t\t\t\tcp += 3;\n\t\t\t\tif (e)\n\t\t\t\t\tattachParserField (e, AsmFields[F_PROPERTIES].ftype,\n\t\t\t\t\t\t\t\t\t   \"req\");\n\t\t\t\tvStringCatS (signature, \":req\");\n\t\t\t}\n\t\t\telse if (strncmp((const char *)cp, \"vararg\", 6) == 0)\n\t\t\t{\n\t\t\t\tcp += 6;\n\t\t\t\tif (e)\n\t\t\t\t\tattachParserField (e, AsmFields[F_PROPERTIES].ftype,\n\t\t\t\t\t\t\t\t\t   \"vararg\");\n\t\t\t\tvStringCatS (signature, \":vararg\");\n\t\t\t}\n\t\t\tcp = (const unsigned char *)strpbrk ((const char *)cp , \" \\t,=\");\n\t\t\tif (cp == NULL)\n\t\t\t\tbreak;\n\t\t}\n\t\tif (*cp == '=')\n\t\t{\n\t\t\tconst unsigned char *start = cp;\n\t\t\tcp = (const unsigned char *)strpbrk ((const char *)cp , \" \\t,\");\n\n\t\t\tif (cp)\n\t\t\t\tvStringNCatS (signature, (const char *)start, cp - start);\n\t\t\telse\n\t\t\t{\n\t\t\t\tvStringCatS (signature, (const char *)start);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\twhile (isspace (*cp))\n\t\t\t++cp;\n\n\t\tif (*cp == ',')\n\t\t\tcp++;\n\t}\n\n\tif (vStringLength (signature) > 0)\n\t{\n\t\te->extensionFields.signature = vStringDeleteUnwrap (signature);\n\t\tsignature = NULL;\n\t}\n\tvStringDelete (signature);\t/* NULL is acceptable. */\n\tvStringDelete (name);\n}\n\nstatic void findAsmTagsCommon (bool useCpp)\n{\n\tvString *name = vStringNew ();\n\tvString *operator = vStringNew ();\n\tconst unsigned char *line;\n\n\tif (useCpp)\n\t\tcppInit (false, false, false, false,\n\t\t\t\t KIND_GHOST_INDEX, 0, 0, KIND_GHOST_INDEX, KIND_GHOST_INDEX, 0, 0,\n\t\t\t\t FIELD_UNKNOWN);\n\n\tint sectionScope = CORK_NIL;\n\tint macroScope = CORK_NIL;\n\n\t while ((line = asmReadLineFromInputFile (commentCharsInMOL, useCpp)) != NULL)\n\t {\n\t\tconst unsigned char *cp = line;\n\t\tbool labelCandidate = (bool) (! isspace (*cp));\n\t\tbool nameFollows = false;\n\t\tbool directive = false;\n\t\tconst bool isComment = (bool)\n\t\t\t\t(*cp != '\\0' && strchr (commentCharsAtBOL, *cp) != NULL);\n\n\t\t/* skip comments */\n\t\tif (isComment)\n\t\t\tcontinue;\n\n\t\t/* skip white space */\n\t\twhile (isspace (*cp))\n\t\t\t++cp;\n\n\t\t/* read symbol */\n\t\tif (*cp == '.')\n\t\t{\n\t\t\tdirective = true;\n\t\t\tlabelCandidate = false;\n\t\t\t++cp;\n\t\t}\n\n\t\tcp = readSymbol (cp, name);\n\t\tif (vStringLength (name) > 0)\n\t\t{\n\t\t\tif (*cp == ':')\n\t\t\t{\n\t\t\t\tlabelCandidate = true;\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\telse if (anyKindEntryInScope (CORK_NIL,\n\t\t\t\t\t\t\t\t\t\t  vStringValue (name),\n\t\t\t\t\t\t\t\t\t\t  K_MACRO, true))\n\t\t\t\tlabelCandidate = false;\n\t\t}\n\n\t\tif (! isspace (*cp)  &&  *cp != '\\0')\n\t\t\tcontinue;\n\n\t\t/* skip white space */\n\t\twhile (isspace (*cp))\n\t\t\t++cp;\n\n\t\t/* skip leading dot */\n#if 0\n\t\tif (*cp == '.')\n\t\t\t++cp;\n#endif\n\n\t\tcp = readOperator (cp, operator);\n\n\t\t/* attempt second read of symbol */\n\t\tif (vStringLength (name) == 0)\n\t\t{\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tcp = readSymbol (cp, name);\n\t\t\tnameFollows = true;\n\t\t}\n\t\tint r = makeAsmTag (name, operator, labelCandidate, nameFollows, directive,\n\t\t\t\t\t\t\t&sectionScope, &macroScope, useCpp);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\t\tif (e && e->langType == Lang_asm\n\t\t\t&& e->kindIndex == K_MACRO && isRoleAssigned(e, ROLE_DEFINITION_INDEX))\n\t\t\treadMacroParameters (r, e, cp, useCpp);\n\t}\n\n\tif (useCpp)\n\t\tcppTerminate ();\n\n\tvStringDelete (name);\n\tvStringDelete (operator);\n}\n\nstatic void findAsmTags (void)\n{\n\tfindAsmTagsCommon (useCPreProcessor);\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_asm = language;\n}\n\n/* dummy definition to allow/require an extra semicolon */\n#define END_DEF(sfx) typedef int ctags_dummy_int_type_ignore_me_##sfx\n\n#define defineCommentCharSetter(PREPOS, POS)\t\t\t\t\t\t\t\\\n\tstatic bool asmSetCommentChars##PREPOS##POS (const langType language CTAGS_ATTR_UNUSED, \\\n\t\t\t\t\t\t\t\t\t\t\t\t const char *optname CTAGS_ATTR_UNUSED, const char *arg) \\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (commentChars##PREPOS##POS != defaultCommentChar##PREPOS##POS) \\\n\t\t\teFree ((void *)commentChars##PREPOS##POS);\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (arg && (arg[0] != '\\0'))\t\t\t\t\t\t\t\t\t\\\n\t\t\tcommentChars##PREPOS##POS = eStrdup (arg);\t\t\t\t\t\\\n\t\telse\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tcommentChars##PREPOS##POS = defaultCommentChar##PREPOS##POS; \\\n\t\treturn true;\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t} END_DEF(asmSetCommentChars##PREPOS##POS)\n\ndefineCommentCharSetter(At, BOL);\ndefineCommentCharSetter(In, MOL);\n\nstatic bool asmSetExtraLinesepChars(const langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\tconst char *optname CTAGS_ATTR_UNUSED, const char *arg)\n{\n\tif (extraLinesepChars != defaultExtraLinesepChars)\n\t\teFree ((void *)extraLinesepChars);\n\n\tif (arg && (arg[0] != '\\0'))\n\t\textraLinesepChars = eStrdup (arg);\n\telse\n\t\textraLinesepChars = defaultExtraLinesepChars;\n\n\treturn true;\n}\n\nstatic bool setUseCPreProcessor(const langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\tconst char *name, const char *arg)\n{\n\tuseCPreProcessor = paramParserBool (arg, useCPreProcessor,\n\t\t\t\t\t\t\t\t\t\tname, \"parameter\");\n\treturn true;\n}\n\nstatic paramDefinition AsmParams [] = {\n\t{\n\t\t.name = \"commentCharsAtBOL\",\n\t\t.desc = \"line comment chraracters at the beginning of line ([\" DEFAULT_COMMENT_CHARS_BOL \"])\",\n\t\t.handleParam = asmSetCommentCharsAtBOL,\n\t},\n\t{\n\t\t.name = \"commentCharsInMOL\",\n\t\t.desc = \"line comment chraracters in the beginning of line ([\" DEFAULT_COMMENT_CHARS_MOL \"])\",\n\t\t.handleParam = asmSetCommentCharsInMOL,\n\t},\n\t{\n\t\t.name = \"extraLinesepChars\",\n\t\t.desc = \"extra characters used as a line separator ([])\",\n\t\t.handleParam = asmSetExtraLinesepChars,\n\t},\n\t{\n\t\t.name = \"useCPreProcessor\",\n\t\t.desc = \"run CPreProcessor parser for extracting macro definitions ([true] or false)\",\n\t\t.handleParam = setUseCPreProcessor,\n\t},\n};\n\nextern parserDefinition* AsmParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"asm\", \"ASM\", \"s\", \"S\", NULL\n\t};\n\tstatic const char *const patterns [] = {\n\t\t\"*.A51\",\n\t\t\"*.29[kK]\",\n\t\t\"*.[68][68][kKsSxX]\",\n\t\t\"*.[xX][68][68]\",\n\t\tNULL\n\t};\n\tstatic selectLanguage selectors[] = { selectByArrowOfR, NULL };\n\n\tstatic parserDependency dependencies [] = {\n\t\t{ DEPTYPE_FOREIGNER, \"LdScript\", &Lang_ldscript },\n\t};\n\n\tparserDefinition* def = parserNew (\"Asm\");\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 0;\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\tdef->kindTable      = AsmKinds;\n\tdef->kindCount  = ARRAY_SIZE (AsmKinds);\n\tdef->extensions = extensions;\n\tdef->patterns   = patterns;\n\tdef->parser     = findAsmTags;\n\tdef->initialize = initialize;\n\tdef->keywordTable = AsmKeywords;\n\tdef->keywordCount = ARRAY_SIZE (AsmKeywords);\n\tdef->selectLanguage = selectors;\n\tdef->useCork = CORK_QUEUE | CORK_SYMTAB;\n\tdef->fieldTable = AsmFields;\n\tdef->fieldCount = ARRAY_SIZE (AsmFields);\n\n\tdef->paramTable = AsmParams;\n\tdef->paramCount = ARRAY_SIZE(AsmParams);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/asp.c",
    "content": "/*\n*   Copyright (c) 2000, Patrick Dehne <patrick@steidle.net>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for the ASP (Active\n*   Server Pages) web page scripting language.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_CONST, K_CLASS, K_FUNCTION, K_SUB, K_DIM\n} aspKind;\n\nstatic kindDefinition AspKinds [] = {\n\t{ true, 'd', \"constant\",   \"constants\"},\n\t{ true, 'c', \"class\",      \"classes\"},\n\t{ true, 'f', \"function\",   \"functions\"},\n\t{ true, 's', \"subroutine\", \"subroutines\"},\n\t{ true, 'v', \"variable\",   \"variables\"}\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void findAspTags (void)\n{\n\tvString *name = vStringNew ();\n\tconst unsigned char *line;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char *cp = line;\n\n\t\twhile (*cp != '\\0')\n\t\t{\n\t\t\t/* jump over whitespace */\n\t\t\twhile (isspace (*cp))\n\t\t\t\tcp++;\n\n\t\t\t/* jump over strings */\n\t\t\tif (*cp == '\"')\n\t\t\t{\n\t\t\t\tcp++;\n\t\t\t\twhile (*cp!='\"' && *cp!='\\0')\n\t\t\t\t\tcp++;\n\t\t\t}\n\n\t\t\t/* jump over comments */\n\t\t\telse if (*cp == '\\'')\n\t\t\t\tbreak;\n\n\t\t\t/* jump over end function/sub lines */\n\t\t\telse if (strncasecmp ((const char*) cp, \"end\", (size_t) 3)== 0)\n\t\t\t{\n\t\t\t\tcp += 3;\n\t\t\t\tif (isspace (*cp))\n\t\t\t\t{\n\t\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t\t++cp;\n\n\t\t\t\t\tif (strncasecmp ((const char*) cp, \"function\", (size_t) 8) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tcp+=8;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\telse if (strncasecmp ((const char*) cp, \"sub\", (size_t) 3) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tcp+=3;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* jump over exit function/sub lines */\n\t\t\telse if (strncasecmp ((const char*) cp, \"exit\", (size_t) 4)==0)\n\t\t\t{\n\t\t\t\tcp += 4;\n\t\t\t\tif (isspace (*cp))\n\t\t\t\t{\n\t\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t\t++cp;\n\n\t\t\t\t\tif (strncasecmp ((const char*) cp, \"function\", (size_t) 8) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tcp+=8;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\telse if (strncasecmp ((const char*) cp, \"sub\", (size_t) 3) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tcp+=3;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* class member? */\n\t\t\telse if (strncasecmp ((const char*) cp, \"public\", (size_t) 6) == 0)\n\t\t\t{\n\t\t\t\tcp += 6;\n\t\t\t\tif (isspace (*cp))\n\t\t\t\t{\n\t\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t\t++cp;\n\t\t\t\t\tif (strncasecmp ((const char*) cp, \"function\", (size_t) 8) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tcp+=8;\n\t\t\t\t\t    while (isspace (*cp))\n\t\t\t\t\t\t    ++cp;\n\t\t\t\t\t    while (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t    {\n\t\t\t\t\t\t    vStringPut (name, *cp);\n\t\t\t\t\t\t    ++cp;\n\t\t\t\t\t    }\n\t\t\t\t\t    makeSimpleTag (name, K_FUNCTION);\n\t\t\t\t\t    vStringClear (name);\n\t\t\t\t\t}\n\t\t\t\t\telse if (strncasecmp ((const char*) cp, \"sub\", (size_t) 3) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tcp+=3;\n\t\t\t\t\t    while (isspace (*cp))\n\t\t\t\t\t\t    ++cp;\n\t\t\t\t\t    while (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t    {\n\t\t\t\t\t\t    vStringPut (name, *cp);\n\t\t\t\t\t\t    ++cp;\n\t\t\t\t\t    }\n\t\t\t\t\t    makeSimpleTag (name, K_SUB);\n\t\t\t\t\t    vStringClear (name);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t    while (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t    {\n\t\t\t\t\t\t    vStringPut (name, *cp);\n\t\t\t\t\t\t    ++cp;\n\t\t\t\t\t    }\n\t\t\t\t\t    makeSimpleTag (name, K_DIM);\n\t\t\t\t\t    vStringClear (name);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (strncasecmp ((const char*) cp, \"private\", (size_t) 7) == 0)\n\t\t\t{\n\t\t\t\tcp += 7;\n\t\t\t\tif (isspace (*cp))\n\t\t\t\t{\n\t\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t\t++cp;\n\t\t\t\t\tif (strncasecmp ((const char*) cp, \"function\", (size_t) 8) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tcp+=8;\n\t\t\t\t\t    while (isspace (*cp))\n\t\t\t\t\t\t    ++cp;\n\t\t\t\t\t    while (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t    {\n\t\t\t\t\t\t    vStringPut (name, *cp);\n\t\t\t\t\t\t    ++cp;\n\t\t\t\t\t    }\n\t\t\t\t\t    makeSimpleTag (name, K_FUNCTION);\n\t\t\t\t\t    vStringClear (name);\n\t\t\t\t\t}\n\t\t\t\t\telse if (strncasecmp ((const char*) cp, \"sub\", (size_t) 3) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tcp+=3;\n\t\t\t\t\t    while (isspace (*cp))\n\t\t\t\t\t\t    ++cp;\n\t\t\t\t\t    while (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t    {\n\t\t\t\t\t\t    vStringPut (name, *cp);\n\t\t\t\t\t\t    ++cp;\n\t\t\t\t\t    }\n\t\t\t\t\t    makeSimpleTag (name, K_SUB);\n\t\t\t\t\t    vStringClear (name);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t    while (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t    {\n\t\t\t\t\t\t    vStringPut (name, *cp);\n\t\t\t\t\t\t    ++cp;\n\t\t\t\t\t    }\n\t\t\t\t\t    makeSimpleTag (name, K_DIM);\n\t\t\t\t\t    vStringClear (name);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* function? */\n\t\t\telse if (strncasecmp ((const char*) cp, \"function\", (size_t) 8) == 0)\n\t\t\t{\n\t\t\t\tcp += 8;\n\n\t\t\t\tif (isspace (*cp))\n\t\t\t\t{\n\t\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t\t++cp;\n\t\t\t\t\twhile (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t\t\t++cp;\n\t\t\t\t\t}\n\t\t\t\t\tmakeSimpleTag (name, K_FUNCTION);\n\t\t\t\t\tvStringClear (name);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* sub? */\n\t\t\telse if (strncasecmp ((const char*) cp, \"sub\", (size_t) 3) == 0)\n\t\t\t{\n\t\t\t\tcp += 3;\n\t\t\t\tif (isspace (*cp))\n\t\t\t\t{\n\t\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t\t++cp;\n\t\t\t\t\twhile (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t\t\t++cp;\n\t\t\t\t\t}\n\t\t\t\t\tmakeSimpleTag (name, K_SUB);\n\t\t\t\t\tvStringClear (name);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* dim variable? */\n\t\t\telse if (strncasecmp ((const char*) cp, \"dim\", (size_t) 3) == 0)\n\t\t\t{\n\t\t\t\tcp += 3;\n\t\t\t\tif (isspace (*cp))\n\t\t\t\t{\n\t\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t\t++cp;\n\t\t\t\t\twhile (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t\t\t++cp;\n\t\t\t\t\t}\n\t\t\t\t\tmakeSimpleTag (name, K_DIM);\n\t\t\t\t\tvStringClear (name);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* class declaration? */\n\t\t\telse if (strncasecmp ((const char*) cp, \"class\", (size_t) 5) == 0)\n\t\t\t{\n\t\t\t\tcp += 5;\n\t\t\t\tif (isspace (*cp))\n\t\t\t\t{\n\t\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t\t++cp;\n\t\t\t\t\twhile (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t\t\t++cp;\n\t\t\t\t\t}\n\t\t\t\t\tmakeSimpleTag (name, K_CLASS);\n\t\t\t\t\tvStringClear (name);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* const declaration? */\n\t\t\telse if (strncasecmp ((const char*) cp, \"const\", (size_t) 5) == 0)\n\t\t\t{\n\t\t\t\tcp += 5;\n\t\t\t\tif (isspace (*cp))\n\t\t\t\t{\n\t\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t\t++cp;\n\t\t\t\t\twhile (isalnum (*cp)  ||  *cp == '_')\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t\t\t++cp;\n\t\t\t\t\t}\n\t\t\t\t\tmakeSimpleTag (name, K_CONST);\n\t\t\t\t\tvStringClear (name);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* nothing relevant */\n\t\t\telse if (*cp != '\\0')\n\t\t\t\tcp++;\n\t\t}\n\t}\n\tvStringDelete (name);\n}\n\nextern parserDefinition* AspParser (void)\n{\n\tstatic const char *const extensions [] = { \"asp\", \"asa\", NULL };\n\tparserDefinition* def = parserNew (\"Asp\");\n\tdef->kindTable      = AspKinds;\n\tdef->kindCount  = ARRAY_SIZE (AspKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findAspTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/autoconf.c",
    "content": "/*\n *   Copyright (c) 2011, Colomban Wendling <colomban@geany.org>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for Autoconf files.\n */\n\n#include \"general.h\"\t/* must always come first */\n\n#include <string.h>\n\n#include \"x-autoconf.h\"\n#include \"x-m4.h\"\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"read.h\"\n#include \"keyword.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n\n\nstatic roleDefinition AutoconfOptwithRoles [] = {\n\t{ true, \"cmdline\", \"specified in a configure command line\" },\n};\n\nstatic roleDefinition AutoconfOptenableRoles [] = {\n\t{ true, \"cmdline\", \"specified in a configure command line\" },\n};\n\nstatic kindDefinition AutoconfKinds[] = {\n\t{ true, 'p', \"package\", \"packages\" },\n\t{ true, 't', \"template\", \"templates\" },\n\t{ true, 'm', \"macro\", \"autoconf macros\" },\n\t{ true, 'w', \"optwith\", \"options specified with --with-...\",\n\t  .referenceOnly = false, ATTACH_ROLES(AutoconfOptwithRoles)},\n\t{ true, 'e', \"optenable\", \"options specified with --enable-...\",\n\t  .referenceOnly = false, ATTACH_ROLES(AutoconfOptenableRoles)},\n\t{ true, 's', \"subst\", \"substitution keys\"},\n\t{ true, 'c', \"condition\", \"automake conditions\" },\n\t{ true, 'd', \"definition\", \"definitions\" },\n};\n\ntypedef enum {\n\tKEYWORD_init,\n\tKEYWORD_template,\n\tKEYWORD_defun,\n\tKEYWORD_argwith,\n\tKEYWORD_argenable,\n\tKEYWORD_subst,\n\tKEYWORD_conditional,\n\tKEYWORD_define,\n} autoconfKeywordId;\n\nstatic const keywordTable autoconfKeywordTable[] = {\n\t{ \"AC_INIT\",            KEYWORD_init, },\n\t{ \"AH_TEMPLATE\",        KEYWORD_template, },\n\t{ \"AC_DEFUN\",           KEYWORD_defun, },\n\t{ \"AC_DEFUN_ONCE\",      KEYWORD_defun, },\n\t{ \"AC_ARG_WITH\",        KEYWORD_argwith, },\n\t{ \"AC_ARG_ENABLE\",      KEYWORD_argenable, },\n\t{ \"AC_SUBST\",           KEYWORD_subst, },\n\t{ \"AM_CONDITIONAL\",     KEYWORD_conditional, },\n\t{ \"AC_DEFINE\",          KEYWORD_define, },\n\t{ \"AC_DEFINE_UNQUOTED\", KEYWORD_define, },\n};\n\nstatic bool doesLineCommentStart (m4Subparser *m4 CTAGS_ATTR_UNUSED, int c, const char* token CTAGS_ATTR_UNUSED)\n{\n\treturn (c == '#');\n}\n\nstatic bool doesStringLiteralStart (m4Subparser *m4 CTAGS_ATTR_UNUSED, int c CTAGS_ATTR_UNUSED)\n{\n\t// return (c == '\"') || (c == '\\'') || (c == '`');\n\treturn false;\n}\n\nstatic bool doesWantToParseInsideQuotes (m4Subparser *m4 CTAGS_ATTR_UNUSED, intArray *indexStack CTAGS_ATTR_UNUSED)\n{\n\treturn true;\n}\n\nstatic bool probeLanguage (m4Subparser *m4 CTAGS_ATTR_UNUSED, const char* token)\n{\n\treturn strncmp (token, \"m4_\", 3) == 0\n\t\t|| strncmp (token, \"AC_\", 3) == 0\n\t\t|| strncmp (token, \"AM_\", 3) == 0\n\t\t|| strncmp (token, \"AS_\", 3) == 0\n\t\t|| strncmp (token, \"AH_\", 3) == 0\n\t\t;\n}\n\nstatic int makeAutoconfTag (int kind)\n{\n\tint index = CORK_NIL;\n\tvString * name;\n\n\tname = vStringNew();\n\treadM4MacroArgument(name);\n\tif (vStringLength (name) > 0)\n\t{\n\t\ttagEntryInfo e;\n\t\tinitTagEntry (&e, vStringValue(name), kind);\n\t\tindex = makeTagEntry(&e);\n\t}\n\tvStringDelete (name);\n\n\treturn index;\n}\n\nstatic int newMacroCallback (m4Subparser *m4 CTAGS_ATTR_UNUSED, const char* token)\n{\n\tint keyword;\n\tint index = CORK_NIL;\n\n\tkeyword = lookupKeyword (token, getInputLanguage ());\n\n\t/* TODO:\n\t   AH_VERBATIM\n\t */\n\tswitch (keyword)\n\t{\n\tcase KEYWORD_NONE:\n\t\tbreak;\n\tcase KEYWORD_init:\n\t\tindex = makeAutoconfTag (AUTOCONF_PACKAGE_KIND);\n\t\tbreak;\n\tcase KEYWORD_template:\n\t\tindex = makeAutoconfTag (AUTOCONF_TEMPLATE_KIND);\n\t\tbreak;\n\tcase KEYWORD_defun:\n\t\tindex = makeAutoconfTag (AUTOCONF_MACRO_KIND);\n\t\tbreak;\n\tcase KEYWORD_argwith:\n\t\tindex = makeAutoconfTag (AUTOCONF_OPTWITH_KIND);\n\t\tbreak;\n\tcase KEYWORD_argenable:\n\t\tindex = makeAutoconfTag (AUTOCONF_OPTENABLE_KIND);\n\t\tbreak;\n\tcase KEYWORD_subst:\n\t\tindex = makeAutoconfTag (AUTOCONF_SUBST_KIND);\n\t\tbreak;\n\tcase KEYWORD_conditional:\n\t\tindex = makeAutoconfTag (AUTOCONF_CONDITION_KIND);\n\t\tbreak;\n\tcase KEYWORD_define:\n\t\tindex = makeAutoconfTag (AUTOCONF_DEFINITION_KIND);\n\t\tbreak;\n\tdefault:\n\t\tAssertNotReached ();\n\t}\n\treturn index;\n}\n\nstatic void exclusiveSubparserChosenCallback (subparser *s CTAGS_ATTR_UNUSED, void *data CTAGS_ATTR_UNUSED)\n{\n\tsetM4Quotes ('[', ']');\n}\n\nstatic void findAutoconfTags(void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* AutoconfParser (void)\n{\n\tstatic const char *const patterns [] = { \"configure.in\", NULL };\n\tstatic const char *const extensions [] = { \"ac\", NULL };\n\tparserDefinition* const def = parserNew(\"Autoconf\");\n\n\tstatic m4Subparser autoconfSubparser = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t\t.exclusiveSubparserChosenNotify = exclusiveSubparserChosenCallback,\n\t\t},\n\t\t.probeLanguage  = probeLanguage,\n\t\t.newMacroNotify = newMacroCallback,\n\t\t.doesLineCommentStart = doesLineCommentStart,\n\t\t.doesStringLiteralStart = doesStringLiteralStart,\n\t\t.doesWantToParseInsideQuotes = doesWantToParseInsideQuotes,\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"M4\", &autoconfSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = AutoconfKinds;\n\tdef->kindCount = ARRAY_SIZE(AutoconfKinds);\n\tdef->patterns = patterns;\n\tdef->extensions = extensions;\n\tdef->parser = findAutoconfTags;\n\tdef->useCork = CORK_QUEUE;\n\n\tdef->keywordTable = autoconfKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (autoconfKeywordTable);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/autoit.c",
    "content": "/*\n*   Copyright (c) 2017, Alexey Olenich\n*   Copyright (c) 2018, Colomban Wendling <colomban@geany.org>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for AutoIt functions.\n*   Homepage             https://www.autoitscript.com/site/autoit/\n*   Online Documentation https://www.autoitscript.com/autoit3/docs/\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"parse.h\"\n#include \"entry.h\"\n#include \"nestlevel.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_FUNCTION,\n\tK_REGION,\n\tK_GLOBALVAR,\n\tK_LOCALVAR,\n\tK_SCRIPT,\n} AutoItKind;\n\ntypedef enum {\n\tR_INCLUDE_SYSTEM,\n\tR_INCLUDE_LOCAL,\n} AutoItIncludeRole;\n\ntypedef enum {\n\tF_PROPERTIES,\n} AutoItField;\n\nstatic roleDefinition AutoItIncludeRoles [] = {\n\t{ true, \"system\", \"system include\" },\n\t{ true, \"local\", \"local include\" },\n};\n\nstatic kindDefinition AutoItKinds [] = {\n\t{ true, 'f', \"func\", \"functions\" },\n\t{ true, 'r', \"region\", \"regions\" },\n\t{ true, 'g', \"global\", \"global variables\" },\n\t{ true, 'l', \"local\", \"local variables\" },\n\t{ true, 'S', \"script\", \"included scripts\",\n\t  .referenceOnly = true, ATTACH_ROLES (AutoItIncludeRoles) },\n};\n\nstatic fieldDefinition AutoItFields [] = {\n\t{\n\t\t.name = \"properties\",\n\t\t.description = \"properties (static, volatile, ...)\",\n\t\t.enabled = false,\n\t},\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n/* it's unclear what *is* an identifier character, so maybe we're too strict */\nstatic bool isIdentChar (int c)\n{\n\treturn isalnum (c) || c == '_';\n}\n\nstatic bool match (const unsigned char *line, const char *word,\n                   const unsigned char **positionAfter)\n{\n\tsize_t len = strlen (word);\n\tbool matched = (strncasecmp ((const char*) line, word, len) == 0 &&\n\t                ! isIdentChar (line[len]));\n\n\tif (matched && positionAfter)\n\t\t*positionAfter = line + len;\n\n\treturn matched;\n}\n\nstatic int makeAutoItTag (const NestingLevels *const nls,\n                          const vString* const name,\n                          const int kindIndex,\n                          const vString *const signature)\n{\n\tint r = CORK_NIL;\n\n\tif (isInputLanguageKindEnabled(kindIndex) && name != NULL && vStringLength (name) > 0)\n\t{\n\t\tNestingLevel *nl = nestingLevelsGetCurrent (nls);\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry (&e, vStringValue (name), kindIndex);\n\n\t\tif (nl)\n\t\t\te.extensionFields.scopeIndex = nl->corkIndex;\n\t\tif (signature)\n\t\t\te.extensionFields.signature = vStringValue (signature);\n\n\t\tr = makeTagEntry (&e);\n\t}\n\n\treturn r;\n}\n\nstatic int makeSimpleAutoItTag (const NestingLevels *const nls,\n                                const vString* const name,\n                                const int kindIndex)\n{\n\treturn makeAutoItTag (nls, name, kindIndex, NULL);\n}\n\nstatic void setEndLine (const NestingLevels *const nls)\n{\n\tNestingLevel *nl = nestingLevelsGetCurrent (nls);\n\n\tif (nl)\n\t\tsetTagEndLineToCorkEntry (nl->corkIndex,\n\t\t\t\t\t\t\t\t  getInputLineNumber ());\n}\n\nstatic void skipSpaces (const unsigned char **p)\n{\n\twhile (isspace (**p))\n\t\t++(*p);\n}\n\n/* parses after a \"func\" keyword */\nstatic int parseFunc (const unsigned char *p, NestingLevels *nls)\n{\n\tint k = CORK_NIL;\n\tvString *name = vStringNew ();\n\n\tskipSpaces (&p);\n\twhile (isIdentChar (*p))\n\t{\n\t\tvStringPut (name, *p);\n\t\t++p;\n\t}\n\tskipSpaces (&p);\n\tif (*p == '(' && (vStringLength (name) > 0))\n\t{\n\t\tvString *signature = vStringNew ();\n\n\t\tdo\n\t\t\tvStringPut (signature, *p);\n\t\twhile (*p != ')' && *p++);\n\n\t\tk = makeAutoItTag (nls, name, K_FUNCTION, signature);\n\t\tnestingLevelsPush (nls, k);\n\t\tvStringDelete (signature);\n\t}\n\n\tvStringDelete (name);\n\n\treturn k;\n}\n\nstatic void findAutoItTags (void)\n{\n\tvString *name = vStringNew ();\n\tconst unsigned char *line;\n\tNestingLevels *nls = nestingLevelsNew (0);\n\tunsigned int commentDepth = 0;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char* p = line;\n\t\tif (p [0] == '#')\n\t\t{\n\t\t\tp++;\n\t\t\tif (match (p, \"cs\", NULL) || match (p, \"comments-start\", NULL))\n\t\t\t\tcommentDepth++;\n\t\t\telse if (commentDepth > 0)\n\t\t\t{\n\t\t\t\tif (match (p, \"ce\", NULL) || match (p, \"comments-end\", NULL))\n\t\t\t\t\tcommentDepth--;\n\t\t\t}\n\t\t\telse if (match (p, \"region\", &p))\n\t\t\t{\n\t\t\t\tskipSpaces (&p);\n\n\t\t\t\tif (*p != '\\0')\n\t\t\t\t{\n\t\t\t\t\tint k;\n\n\t\t\t\t\tvStringCatS (name, (const char *) p);\n\t\t\t\t\tk = makeSimpleAutoItTag (nls, name, K_REGION);\n\t\t\t\t\tnestingLevelsPush (nls, k);\n\t\t\t\t\tvStringClear (name);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (nls->n > 0 && match (p, \"endregion\", NULL))\n\t\t\t{\n\t\t\t\tsetEndLine (nls);\n\t\t\t\tnestingLevelsPop (nls);\n\t\t\t}\n\t\t\telse if (match (p, \"include\", &p))\n\t\t\t{\n\t\t\t\tskipSpaces (&p);\n\t\t\t\tif (*p == '<' || *p == '\"')\n\t\t\t\t{\n\t\t\t\t\tconst AutoItIncludeRole role = (*p == '<')\n\t\t\t\t\t\t? R_INCLUDE_SYSTEM\n\t\t\t\t\t\t: R_INCLUDE_LOCAL;\n\n\t\t\t\t\t++p;\n\t\t\t\t\twhile (*p != '\\0' && *p != '>' && *p != '\"')\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (name, *p);\n\t\t\t\t\t\t++p;\n\t\t\t\t\t}\n\t\t\t\t\tif (vStringLength(name) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tmakeSimpleRefTag (name, K_SCRIPT, role);\n\t\t\t\t\t\tvStringClear (name);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (commentDepth == 0)\n\t\t{\n\t\t\tbool isGlobal = false;\n\t\t\tbool isStatic = false;\n\n\t\t\t/* skip white space */\n\t\t\tskipSpaces (&p);\n\t\t\tif (*p == ';')\n\t\t\t\t/* ignore single-line comments */;\n\t\t\telse if (match (p, \"volatile\", &p))\n\t\t\t{\n\t\t\t\tskipSpaces (&p);\n\t\t\t\tif (match (p, \"func\", &p))\n\t\t\t\t{\n\t\t\t\t\tint k = parseFunc (p, nls);\n\t\t\t\t\tif (k != CORK_NIL)\n\t\t\t\t\t\tattachParserFieldToCorkEntry (k, AutoItFields[F_PROPERTIES].ftype, \"volatile\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (match (p, \"func\", &p))\n\t\t\t\tparseFunc (p, nls);\n\t\t\telse if (nls->n > 0 && match (p, \"endfunc\", NULL))\n\t\t\t{\n\t\t\t\tsetEndLine (nls);\n\t\t\t\tnestingLevelsPop (nls);\n\t\t\t}\n\t\t\telse if ((isStatic = match (p, \"static\", &p)) ||\n\t\t\t         (isGlobal = match (p, \"global\", &p)) ||\n\t\t\t         match (p, \"local\", &p))\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * variable-identifier ::= \"$[a-zA-Z_0-9]+\"\n\t\t\t\t * scope-modifier ::= \"Local\" | \"Global\"\n\t\t\t\t * variable-declaration ::= \"Static\" [scope-modifier] variable-identifier\n\t\t\t\t *                          scope-modifier [\"Static\" | \"Const\"] variable-identifier\n\t\t\t\t */\n\t\t\t\tskipSpaces (&p);\n\t\t\t\tif (isStatic)\n\t\t\t\t{\n\t\t\t\t\t/* skip optional modifiers */\n\t\t\t\t\tif ((isGlobal = match (p, \"global\", &p)) ||\n\t\t\t\t\t    match (p, \"local\", &p))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipSpaces (&p);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ((isStatic = match (p, \"static\", &p)))\n\t\t\t\t\tskipSpaces (&p);\n\t\t\t\telse if (match (p, \"const\", &p))\n\t\t\t\t\tskipSpaces (&p);\n\t\t\t\tif (*p == '$')\n\t\t\t\t{\n\t\t\t\t\tp++;\n\t\t\t\t\twhile (isIdentChar (*p))\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (name, *p);\n\t\t\t\t\t\t++p;\n\t\t\t\t\t}\n\t\t\t\t\tif (vStringLength(name) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tint k = makeSimpleAutoItTag (nls, name, isGlobal ? K_GLOBALVAR : K_LOCALVAR);\n\t\t\t\t\t\tif (k != CORK_NIL && isStatic)\n\t\t\t\t\t\t\tattachParserFieldToCorkEntry (k, AutoItFields[F_PROPERTIES].ftype, \"static\");\n\t\t\t\t\t}\n\t\t\t\t\tvStringClear (name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvStringDelete (name);\n\tnestingLevelsFree (nls);\n}\n\nparserDefinition *AutoItParser (void)\n{\n\tstatic char const *extensions[] = { \"au3\", \"AU3\", \"aU3\", \"Au3\", NULL };\n\tparserDefinition* def = parserNew (\"AutoIt\");\n\tdef->kindTable      = AutoItKinds;\n\tdef->kindCount  = ARRAY_SIZE (AutoItKinds);\n\tdef->fieldTable = AutoItFields;\n\tdef->fieldCount = ARRAY_SIZE (AutoItFields);\n\tdef->extensions = extensions;\n\tdef->parser     = findAutoItTags;\n\tdef->useCork    = CORK_QUEUE;\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 0;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/automake.c",
    "content": "/*\n*   Copyright (c) 2000-2005, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for makefiles.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <ctype.h>\n\n#include \"x-make.h\"\n\n#include \"entry.h\"\n#include \"htable.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"subparser.h\"\n\n\ntypedef enum {\n\tK_AM_DIR,\n\tK_AM_PROGRAM,\n\tK_AM_MAN,\n\tK_AM_LTLIBRARY,\n\tK_AM_LIBRARY,\n\tK_AM_SCRIPT,\n\tK_AM_DATA,\n\tK_AM_CONDITION,\n\tK_AM_SUBDIR,\n\tK_AM_PSEUDODIR,\n} makeAMKind;\n\ntypedef enum {\n\tR_AM_DIR_PROGRAMS,\n\tR_AM_DIR_MANS,\n\tR_AM_DIR_LTLIBRARIES,\n\tR_AM_DIR_LIBRARIES,\n\tR_AM_DIR_SCRIPTS,\n\tR_AM_DIR_DATA,\n} makeAMDirectoryRole;\n\n#define DIR_ROLES \\\n\t{ true, \"program\",   \"directory for PROGRAMS primary\" },\t\\\n\t{ true, \"man\",       \"directory for MANS primary\" },\t\t\\\n\t{ true, \"ltlibrary\", \"directory for LTLIBRARIES primary\"},\t\\\n\t{ true, \"library\",   \"directory for LIBRARIES primary\"},\t\\\n\t{ true, \"script\",    \"directory for SCRIPTS primary\"},\t\t\\\n\t{ true, \"data\",      \"directory for DATA primary\"},\n\nstatic roleDefinition AutomakeDirectoryRoles [] = {\n\tDIR_ROLES\n};\n\nstatic roleDefinition AutomakePseudodirRoles [] = {\n\tDIR_ROLES\n};\n\ntypedef enum {\n\tR_AM_CONDITION_BRANCHED,\n} makeAMConditionRole;\n\nstatic roleDefinition AutomakeConditionRoles [] = {\n\t{ true, \"branched\",  \"used for branching\" },\n};\n\nstatic scopeSeparator AutomakeSeparators [] = {\n\t{ K_AM_DIR        , \"/\" },\n};\n\nstatic kindDefinition AutomakeKinds [] = {\n\t{ true, 'd', \"directory\", \"directories\",\n\t  .referenceOnly = false, ATTACH_ROLES(AutomakeDirectoryRoles)},\n\t{ true, 'P', \"program\",   \"programs\",\n\t  ATTACH_SEPARATORS(AutomakeSeparators) },\n\t{ true, 'M', \"man\",       \"manuals\",\n\t  ATTACH_SEPARATORS(AutomakeSeparators) },\n\t{ true, 'T', \"ltlibrary\", \"ltlibraries\",\n\t  ATTACH_SEPARATORS(AutomakeSeparators) },\n\t{ true, 'L', \"library\",   \"libraries\",\n\t  ATTACH_SEPARATORS(AutomakeSeparators) },\n\t{ true, 'S', \"script\",    \"scripts\",\n\t  ATTACH_SEPARATORS(AutomakeSeparators) },\n\t{ true, 'D', \"data\",      \"datum\",\n\t  ATTACH_SEPARATORS(AutomakeSeparators) },\n\t{ true, 'c', \"condition\", \"conditions\",\n\t  .referenceOnly = true, ATTACH_ROLES(AutomakeConditionRoles) },\n\t{ true, 's', \"subdir\", \"subdirs\" },\n\t{ false,'p', \"pseudodir\", \"placeholder for EXTRA_, noinst_, and _check_ prefixed primaries (internal use)\",\n\t  .referenceOnly = true, ATTACH_ROLES(AutomakePseudodirRoles),\n\t  .version = 1 },\n};\n\ntypedef enum {\n\tX_CANONICALIZED_NAME,\n} automakeXtag;\n\nstatic xtagDefinition AutomakeXtagTable [] = {\n\t{\n\t\t.enabled = true,\n\t\t.name = \"canonicalizedName\",\n\t\t.description = \"Include canonicalized object name like libctags_a\",\n\t\t.version = 1\n\t},\n};\n\nstruct sPrefix {\n\tconst char* substr;\n\tsize_t len;\n};\n\nstruct sAutomakeSubparser {\n\tmakeSubparser make;\n\n\thashTable* directories;\n\tint index;\n\tbool in_subdirs;\n};\n\n\nstatic bool has_prefix0 (const char *name, const struct sPrefix *prefix)\n{\n\tif (strncmp (prefix->substr, name, prefix->len) == 0)\n\t\treturn false;\n\telse\n\t\treturn true;\n}\n\nstatic size_t has_prefix (const char *name, const struct sPrefix *prefixlist)\n{\n\tfor (int i = 0; prefixlist[i].substr; i++)\n\t{\n\t\tif (has_prefix0 (name, prefixlist + i) == false)\n\t\t\treturn prefixlist [i].len;\n\t}\n\treturn 0;\n}\n\nstatic int lookupAutomakeDirectory (hashTable* directories,  vString *const name)\n{\n\tint *i = hashTableGetItem (directories,  vStringValue (name));\n\n\tif (i)\n\t\treturn *i;\n\telse\n\t\treturn CORK_NIL;\n}\n\nstatic void addAutomakeDirectory (hashTable* directories, vString *const name, int corkIndex)\n{\n\tchar * k = vStringStrdup (name);\n\tint  * i = xMalloc (1, int);\n\n\t*i = corkIndex;\n\n\thashTablePutItem (directories, k, i);\n}\n\nstatic const char *skipPrefix(const char *name)\n{\n\tsize_t prefix_len;\n\n\t/* Drop \"dist_\" in \"dist_data_DATA\" */\n\tstatic const struct sPrefix obj_prefixlist [] = {\n\t\t{ \"dist_\",    5 },\n\t\t{ \"nodist_\",  7 },\n\t\t{ \"nobase_\",  7 },\n\t\t{ \"notrans_\", 8 },\n\t\t{ NULL,       0 },\n\t};\n\twhile ((prefix_len = has_prefix(name, obj_prefixlist)))\n\t\tname += prefix_len;\n\t/* => data_DATA */\n\n\treturn name;\n}\n\nstatic bool automakeMakeTag (struct sAutomakeSubparser* automake,\n\t\t\t\t\t\t\t const char* name, size_t len,\n\t\t\t\t\t\t\t const char* suffix, size_t suffix_len,\n\t\t\t\t\t\t\t bool appending,\n\t\t\t\t\t\t\t int kindex, int rindex)\n{\n\tconst char* tail;\n\tvString *subname;\n\n\tsuffix_len = strlen (suffix);\n\tif (len < suffix_len)\n\t\treturn false;\n\n\ttail = name + len - suffix_len;\n\tif (strcmp (tail, suffix))\n\t\treturn false;\n\n\tsubname = vStringNewNInit(name, len - suffix_len);\n\n\tif (rindex == ROLE_DEFINITION_INDEX)\n\t{\n\t\tautomake->index = makeSimpleTag (subname, kindex);\n\t\taddAutomakeDirectory (automake->directories, subname, automake->index);\n\t}\n\telse\n\t{\n\t\tbool pseudodir = false;\n\t\tif (strcmp(vStringValue (subname), \"EXTRA\") == 0\n\t\t\t|| strcmp(vStringValue (subname), \"noinst\") == 0\n\t\t\t|| strcmp(vStringValue (subname), \"check\") == 0)\n\t\t{\n\t\t\tpseudodir = true;\n\t\t\tif (kindex == K_AM_DIR)\n\t\t\t\tkindex = K_AM_PSEUDODIR;\n\t\t}\n\n\t\tautomake->index = CORK_NIL;\n\t\tif (appending || pseudodir)\n\t\t\tautomake->index = lookupAutomakeDirectory (automake->directories, subname);\n\n\t\tif ((!appending) || (automake->index == CORK_NIL))\n\t\t{\n\t\t\tautomake->index = makeSimpleRefTag (subname, kindex, rindex);\n\t\t\tif ((automake->index != CORK_NIL) && pseudodir)\n\t\t\t\taddAutomakeDirectory (automake->directories, subname, automake->index);\n\t\t}\n\t}\n\n\tvStringDelete (subname);\n\treturn true;\n}\n\nstatic void canonicalizeName (vString *dst, const char *name)\n{\n\twhile (*name)\n\t{\n\t\tif (isalnum ((unsigned char) *name) ||\n\t\t\t*name == '_' || *name == '@')\n\t\t\tvStringPut (dst, *name);\n\t\telse\n\t\t\tvStringPut (dst, '_');\n\t\tname++;\n\t}\n}\n\nstatic void makeCanonicalizedTag (tagEntryInfo *e, const char *name)\n{\n\tvString *xname = vStringNew ();\n\n\tcanonicalizeName (xname, name);\n\te->name = vStringValue (xname);\n\tif (strcmp(e->name, name))\n\t{\n\t\tmakeTagEntry (e);\n\t\tmarkTagExtraBit (e, AutomakeXtagTable[X_CANONICALIZED_NAME].xtype);\n\t}\n\tvStringDelete (xname);\n}\n\nstatic void valueCallback (makeSubparser *make, char *name)\n{\n\tstruct sAutomakeSubparser *automake = (struct sAutomakeSubparser *)make;\n\tint p = automake->index;\n\ttagEntryInfo *parent;\n\tint k;\n\ttagEntryInfo elt;\n\n\tparent = getEntryInCorkQueue (p);\n\tif (parent && (parent->kindIndex == K_AM_DIR || parent->kindIndex == K_AM_PSEUDODIR)\n\t    && (parent->extensionFields.roleBits))\n\t{\n\t\tint roleIndex;\n\t\tfor (roleIndex = 0; roleIndex < ARRAY_SIZE(AutomakeDirectoryRoles); roleIndex++)\n\t\t\tif (parent->extensionFields.roleBits & ((roleBitsType)1) << roleIndex)\n\t\t\t\tbreak;\n\n\t\tk = K_AM_PROGRAM + roleIndex;\n\t\tinitTagEntry (&elt, name, k);\n\t\telt.extensionFields.scopeIndex = p;\n\t\tmakeTagEntry (&elt);\n\n\t\tif (isXtagEnabled (AutomakeXtagTable[X_CANONICALIZED_NAME].xtype)\n\t\t\t&& (k == K_AM_PROGRAM || k == K_AM_LTLIBRARY || k == K_AM_LIBRARY))\n\t\t\tmakeCanonicalizedTag (&elt, name);\n\t}\n\telse if (automake->in_subdirs)\n\t{\n\t\tinitTagEntry (&elt, name, K_AM_SUBDIR);\n\t\tmakeTagEntry (&elt);\n\t}\n}\n\nstatic void refCondtionAM (vString *directive)\n{\n\tmakeSimpleRefTag (directive,\n\t\t\t  K_AM_CONDITION, R_AM_CONDITION_BRANCHED);\n}\n\nstatic int nextChar (void)\n{\n\tint c = getcFromInputFile ();\n\tif (c == '\\\\')\n\t{\n\t\tc = getcFromInputFile ();\n\t\tif (c == '\\n')\n\t\t\tc = nextChar ();\n\t}\n\treturn c;\n}\n\nstatic int skipToNonWhite (int c)\n{\n\twhile (c != '\\n' && isspace (c))\n\t\tc = nextChar ();\n\treturn c;\n}\n\nstatic void directiveCallback (makeSubparser *make CTAGS_ATTR_UNUSED, char *directive)\n{\n\tint c;\n\tif (! strcmp (directive, \"if\"))\n\t{\n\t\tvString *condition = vStringNew ();\n\n\t\tc = skipToNonWhite (nextChar ());\n\t\twhile (c != EOF && c != '\\n')\n\t\t{\n\t\t\t/* the operator for negation should not be\n\t\t\t   part of the condition name. */\n\t\t\tif (c != '!')\n\t\t\t\tvStringPut (condition, c);\n\t\t\tc = nextChar ();\n\t\t}\n\t\tif (c == '\\n')\n\t\t\tungetcToInputFile (c);\n\t\tvStringStripTrailing (condition);\n\t\tif (vStringLength (condition) > 0 )\n\t\t\trefCondtionAM (condition);\n\t\tvStringDelete (condition);\n\t}\n}\n\nstatic void newMacroCallback (makeSubparser *make, char* name, bool with_define_directive,\n\t\t\t\t\t\t\t  bool appending, int scopeIndex CTAGS_ATTR_UNUSED)\n{\n\tstruct sAutomakeSubparser *automake = (struct sAutomakeSubparser *)make;\n\n\tautomake->index = CORK_NIL;\n\tautomake->in_subdirs = false;\n\n\tif (with_define_directive)\n\t\treturn;\n\n\tif (strcmp (name, \"SUBDIRS\") == 0)\n\t{\n\t\tautomake->in_subdirs = true;\n\t\treturn;\n\t}\n\n\tsize_t len = strlen (name);\n\tif (automakeMakeTag (automake,\n\t\t\t\t\t\t name, len, \"dir\", 3, appending,\n\t\t\t\t\t\t K_AM_DIR, ROLE_DEFINITION_INDEX))\n\t\treturn;\n\n\tconst char *trimmed_name = skipPrefix (name);\n\tif (trimmed_name != name)\n\t\tlen = strlen (trimmed_name);\n\n#define S(X) X, strlen(X)\n\t(void)(0\n\t       || automakeMakeTag (automake,\n\t\t\t\t\t\t\t   trimmed_name, len, S(\"_PROGRAMS\"),\n\t\t\t\t\t\t\t   appending, K_AM_DIR, R_AM_DIR_PROGRAMS)\n\t       || automakeMakeTag (automake,\n\t\t\t\t\t\t\t   trimmed_name, len, S(\"_MANS\"),\n\t\t\t\t\t\t\t   appending, K_AM_DIR, R_AM_DIR_MANS)\n\t       || automakeMakeTag (automake,\n\t\t\t\t\t\t\t   trimmed_name, len, S(\"_LTLIBRARIES\"), appending,\n\t\t\t\t\t\t\t   K_AM_DIR, R_AM_DIR_LTLIBRARIES)\n\t       || automakeMakeTag (automake,\n\t\t\t\t\t\t\t   trimmed_name, len, S(\"_LIBRARIES\"), appending,\n\t\t\t\t\t\t\t   K_AM_DIR, R_AM_DIR_LIBRARIES)\n\t       || automakeMakeTag (automake,\n\t\t\t\t\t\t\t   trimmed_name, len, S(\"_SCRIPTS\"), appending,\n\t\t\t\t\t\t\t   K_AM_DIR, R_AM_DIR_SCRIPTS)\n\t       || automakeMakeTag  (automake,\n\t\t\t\t\t\t\t\ttrimmed_name, len, S(\"_DATA\"), appending,\n\t\t\t\t\t\t\t\tK_AM_DIR, R_AM_DIR_DATA)\n\t\t);\n#undef S\n}\n\nstatic void inputStart (subparser *s)\n{\n\tstruct sAutomakeSubparser *automake = (struct sAutomakeSubparser*)s;\n\n\tautomake->directories = hashTableNew (11, hashCstrhash, hashCstreq, eFree, eFree);\n\tautomake->index = CORK_NIL;\n\tautomake->in_subdirs = false;\n}\n\nstatic void inputEnd (subparser *s)\n{\n\tstruct sAutomakeSubparser *automake = (struct sAutomakeSubparser*)s;\n\n\thashTableDelete (automake->directories);\n\tautomake->directories = NULL;\n}\n\nstatic void findAutomakeTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* AutomakeParser (void)\n{\n\tstatic const char *const extensions [] = { \"am\", NULL };\n\tstatic const char *const patterns [] = { \"Makefile.am\", \"GNUmakefile.am\", NULL };\n\tstatic const char *const aliases [] = { \"makefile-automake\", NULL };\n\n\tstatic struct sAutomakeSubparser automakeSubparser = {\n\t\t.make = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t\t\t.inputStart = inputStart,\n\t\t\t\t.inputEnd = inputEnd,\n\t\t\t},\n\t\t\t.valueNotify = valueCallback,\n\t\t\t.directiveNotify = directiveCallback,\n\t\t\t.newMacroNotify = newMacroCallback,\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Make\", &automakeSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"Automake\");\n\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE(dependencies);\n\tdef->kindTable      = AutomakeKinds;\n\tdef->kindCount  = ARRAY_SIZE (AutomakeKinds);\n\tdef->extensions = extensions;\n\tdef->patterns   = patterns;\n\tdef->aliases    = aliases;\n\tdef->parser     = findAutomakeTags;\n\tdef->xtagTable = AutomakeXtagTable;\n\tdef->xtagCount = ARRAY_SIZE (AutomakeXtagTable);\n\tdef->useCork    = CORK_QUEUE;\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/awk.c",
    "content": "/*\n *   Copyright (c) 2000-2002, Darren Hiebert\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for AWK functions.\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n/*\n *   DATA DEFINITIONS\n */\ntypedef enum eAwkKinds {\n\tK_FUNCTION\n} awkKind;\n\nstatic kindDefinition AwkKinds [] = {\n\t{ true, 'f', \"function\", \"functions\" }\n};\n\n/*\n *   FUNCTION DEFINITIONS\n */\n\nstatic void findAwkTags (void)\n{\n\tvString *name = vStringNew ();\n\tconst unsigned char *line;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\twhile (isspace (*line))\n\t\t\t++line;\n\n\t\tif (strncmp ((const char *) line, \"function\", (size_t) 8) == 0  &&\n\t\t\tisspace (line [8]))\n\t\t{\n\t\t\tconst unsigned char *cp = line + 8;\n\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\t\t\twhile (isalnum (*cp)  ||  *cp == '_')\n\t\t\t{\n\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tif (*cp == '(')\n\t\t\t\tmakeSimpleTag (name, K_FUNCTION);\n\t\t\tvStringClear (name);\n\t\t\tif (*cp != '\\0')\n\t\t\t\t++cp;\n\t\t}\n\t}\n\tvStringDelete (name);\n}\n\nextern parserDefinition *AwkParser (void)\n{\n\tstatic const char *const extensions [] = { \"awk\", \"gawk\", \"mawk\", NULL };\n\tstatic const char *const aliases [] = { \"gawk\", \"mawk\", NULL };\n\tparserDefinition *def = parserNew (\"Awk\");\n\tdef->kindTable  = AwkKinds;\n\tdef->kindCount  = ARRAY_SIZE (AwkKinds);\n\tdef->extensions = extensions;\n\tdef->aliases    = aliases;\n\tdef->parser     = findAwkTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/basic.c",
    "content": "/*\n *   Copyright (c) 2000-2006, Darren Hiebert, Elias Pschernig\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for BlitzBasic\n *   (BlitzMax), PureBasic and FreeBasic language files. For now, this is kept\n *   quite simple - but feel free to ask for more things added any time -\n *   patches are of course most welcome.\n *\n *   FreeBasic:\n *   - https://www.freebasic.net/wiki/DocToc\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\" /* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"trace.h\"\n#include \"vstring.h\"\n\n/*\n *   DATA DEFINITIONS\n */\ntypedef enum {\n\tK_CONST,\n\tK_FUNCTION,\n\tK_LABEL,\n\tK_TYPE,\n\tK_VARIABLE,\n\tK_ENUM,\n\tK_NAMESPACE,\n} BasicKind;\n\ntypedef enum {\n\tBASIC_FUNCTION_DECL,\n} basciFunctionRole;\n\nstatic roleDefinition BasicFunctionRoles [] = {\n\t{ true, \"decl\", \"declared\" },\n};\n\nstatic kindDefinition BasicKinds[] = {\n\t{true, 'c', \"constant\", \"constants\"},\n\t{true, 'f', \"function\", \"functions\",\n\t .referenceOnly = false, ATTACH_ROLES(BasicFunctionRoles)},\n\t{true, 'l', \"label\", \"labels\"},\n\t{true, 't', \"type\", \"types\"},\n\t{true, 'v', \"variable\", \"variables\"},\n\t{true, 'g', \"enum\", \"enumerations\"},\n\t{true, 'n', \"namespace\", \"namespace\"},\n};\n\n/* To force to trigger bugs, we make the orders of\n * enum eKeywordID and BasicKind different. */\nenum eKeywordID {\n\tKEYWORD_ENUM,\n\tKEYWORD_CONST,\n\tKEYWORD_FUNCTION,\n\tKEYWORD_LABEL,\n\tKEYWORD_TYPE,\n\tKEYWORD_VARIABLE,\n\tKEYWORD_NAMESPACE,\n\tKEYWORD_END,\n\tKEYWORD_ACCESS,\n\tKEYWORD_DECLARE,\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\nstatic const keywordTable BasicKeywordTable[] = {\n\t/* freebasic */\n\t{\"const\", KEYWORD_CONST},\n\t{\"dim\", KEYWORD_VARIABLE},\n\t{\"common\", KEYWORD_VARIABLE},\n\t{\"function\", KEYWORD_FUNCTION},\n\t{\"sub\", KEYWORD_FUNCTION},\n\t{\"private\", KEYWORD_ACCESS},\n\t{\"public\", KEYWORD_ACCESS},\n\t{\"property\", KEYWORD_FUNCTION},\n\t{\"constructor\", KEYWORD_FUNCTION},\n\t{\"destructor\", KEYWORD_FUNCTION},\n\t{\"type\", KEYWORD_TYPE},\n\t{\"enum\", KEYWORD_ENUM},\n\t{\"namespace\", KEYWORD_NAMESPACE},\n\t{\"end\", KEYWORD_END},\n\t{\"declare\", KEYWORD_DECLARE},\n\n\t/* blitzbasic, purebasic */\n\t{\"global\", KEYWORD_VARIABLE},\n\n\t/* purebasic */\n\t{\"newlist\", KEYWORD_VARIABLE},\n\t{\"procedure\", KEYWORD_FUNCTION},\n\t{\"interface\", KEYWORD_TYPE},\n\t{\"structure\", KEYWORD_TYPE},\n};\n\nstruct BasicKeywordAttr {\n\tint kind;\n} keywordAttrs [] = {\n\t[KEYWORD_ENUM]  = {\n\t\t.kind = K_ENUM,\n\t},\n\t[KEYWORD_CONST] = {\n\t\t.kind = K_CONST,\n\t},\n\t[KEYWORD_FUNCTION] = {\n\t\t.kind = K_FUNCTION,\n\t},\n\t[KEYWORD_LABEL] = {\n\t\t.kind = K_LABEL,\n\t},\n\t[KEYWORD_TYPE] = {\n\t\t.kind = K_TYPE,\n\t},\n\t[KEYWORD_VARIABLE] = {\n\t\t.kind = K_VARIABLE,\n\t},\n\t[KEYWORD_NAMESPACE] = {\n\t\t.kind = K_NAMESPACE,\n\t},\n\t[KEYWORD_END] = {\n\t\t.kind = KIND_GHOST_INDEX,\n\t},\n\t[KEYWORD_ACCESS] = {\n\t\t.kind = KIND_GHOST_INDEX,\n\t},\n\t[KEYWORD_DECLARE] = {\n\t\t.kind = KIND_GHOST_INDEX,\n\t},\n};\n\nstruct matchState {\n\tconst char *access;\n\tbool end;\n\tbool declaration;\n};\n\nstatic int currentScope;\n/*\n *   FUNCTION DEFINITIONS\n */\n\nstatic void pushScope (int corkIndex)\n{\n#ifdef DEBUG\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\tTRACE_PRINT (\"scope push: %s<%d>\", e? e->name: \"-\", corkIndex);\n#endif\n\tcurrentScope = corkIndex;\n}\n\nstatic void popScope (void)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (currentScope);\n#ifdef DEBUG\n\tTRACE_PRINT (\"scope pop: %s<%d>\", e? e->name: \"-\", currentScope);\n#endif\n\tif (e)\n\t{\n\t\tsetTagEndLine (e, getInputLineNumber());\n\t\tcurrentScope = e->extensionFields.scopeIndex;\n\t}\n\telse\n\t\tcurrentScope = CORK_NIL;\n}\n\nstatic void updateScope (int corkIndex, int kindIndex, int keywordId)\n{\n\tif (corkIndex != CORK_NIL && kindIndex == K_NAMESPACE)\n\t\tpushScope (corkIndex);\n\telse if (corkIndex == CORK_NIL && kindIndex == K_NAMESPACE)\n\t\tpopScope ();\n}\n\nstatic int keywordToKind (keywordId keywordId)\n{\n\tif (keywordId == KEYWORD_NONE)\n\t\treturn KIND_GHOST_INDEX;\n\treturn keywordAttrs [keywordId].kind;\n}\n\nstatic const char *skipToMatching (char begin, char end, const char *pos)\n{\n\tint counter = 1;\n\tpos++;\n\twhile (*pos && counter > 0)\n\t{\n\t\tif (*pos == end)\n\t\t\tcounter--;\n\t\telse if (*pos == begin)\n\t\t\tcounter++;\n\t\telse if (*pos == '\"')\n\t\t\tpos = skipToMatching ('\"', '\"', pos) - 1;\n\t\tpos++;\n\t}\n\treturn pos;\n}\n\nstatic const char *nextPos (const char *pos)\n{\n\tif (*pos == '\\0')\n\t\treturn pos;\n\n\tpos++;\n\tswitch (*pos)\n\t{\n\t\tcase '(':\n\t\t\tpos = skipToMatching ('(', ')', pos);\n\t\t\tbreak;\n\t\tcase '\"':\n\t\t\tpos = skipToMatching ('\"', '\"', pos);\n\t\t\tbreak;\n\t}\n\treturn pos;\n}\n\nstatic bool isIdentChar (int c)\n{\n\treturn c && !isspace (c) && c != '(' && c != ',' && c != '=';\n}\n\nstatic int makeBasicRefTag (vString *name, int kindIndex, int roleIndex)\n{\n\tint r = makeSimpleRefTag (name, kindIndex, roleIndex);\n\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\tif (e)\n\t\te->extensionFields.scopeIndex = currentScope;\n\treturn r;\n}\n\nstatic int makeBasicTag (vString *name, int kindIndex)\n{\n\treturn makeBasicRefTag (name, kindIndex, ROLE_DEFINITION_INDEX);\n}\n\n/* Match the name of a dim or const starting at pos. */\nstatic void extract_dim (char const *pos, BasicKind kind)\n{\n\tvString *name = vStringNew ();\n\n\tif (strncasecmp (pos, \"shared\", 6) == 0)\n\t\tpos += 6; /* skip keyword \"shared\" */\n\n\twhile (isspace ((unsigned char) *pos))\n\t\tpos++;\n\n\t/* capture \"dim as String str\" */\n\tif (strncasecmp (pos, \"as\", 2) == 0)\n\t{\n\t\t\tpos += 2; /* skip keyword \"as\" */\n\n\t\twhile (isspace ((unsigned char) *pos))\n\t\t\tpos++;\n\t\twhile (!isspace ((unsigned char) *pos) && *pos) /* skip next part which is a type */\n\t\t\tpos++;\n\t\twhile (isspace ((unsigned char) *pos))\n\t\t\tpos++;\n\t\t/* now we are at the name */\n\t}\n\t/* capture \"dim as foo ptr bar\" */\n\tif (strncasecmp (pos, \"ptr\", 3) == 0 && isspace((unsigned char) *(pos+3)))\n\t{\n\t\tpos += 3; /* skip keyword \"ptr\" */\n\t\twhile (isspace ((unsigned char) *pos))\n\t\t\tpos++;\n\t}\n\t/*\tcapture \"dim as string * 4096 chunk\" */\n\tif (strncmp (pos, \"*\", 1) == 0)\n\t{\n\t\tpos += 1; /* skip \"*\" */\n\t\twhile (isspace ((unsigned char) *pos) || isdigit((unsigned char) *pos) ||\n\t\t       ispunct((unsigned char) *pos))\n\t\t\tpos++;\n\t}\n\n\tfor (; isIdentChar ((unsigned char) *pos); pos++)\n\t\tvStringPut (name, *pos);\n\tmakeBasicTag (name, kind);\n\n\t/* if the line contains a ',', we have multiple declarations */\n\twhile (*pos && strchr (pos, ','))\n\t{\n\t\t/* skip all we don't need(e.g. \"..., new_array(5), \" we skip \"(5)\") */\n\t\twhile (*pos != ',' && *pos != '\\'' && *pos)\n\t\t\tpos = nextPos (pos);\n\n\t\tif (*pos == '\\'')\n\t\t\tbreak; /* break if we are in a comment */\n\n\t\twhile (isspace ((unsigned char) *pos) || *pos == ',')\n\t\t\tpos++;\n\n\t\tif (*pos == '\\'')\n\t\t\tbreak; /* break if we are in a comment */\n\n\t\tvStringClear (name);\n\t\tfor (; isIdentChar ((unsigned char) *pos); pos++)\n\t\t\tvStringPut (name, *pos);\n\t\tmakeBasicTag (name, kind);\n\t}\n\n\tvStringDelete (name);\n}\n\n/* Match the name of a tag (function, variable, type, ...) starting at pos. */\nstatic int extract_name (char const *pos, BasicKind kind, struct matchState *state)\n{\n\tint r = CORK_NIL;\n\tvString *name = vStringNew ();\n\tfor (; isIdentChar ((unsigned char) *pos); pos++)\n\t\tvStringPut (name, *pos);\n\tif (state && state->declaration)\n\t{\n\t\tif (kind == K_FUNCTION)\n\t\t\tr = makeBasicRefTag (name, kind, BASIC_FUNCTION_DECL);\n\t}\n\telse\n\t\tr = makeBasicTag (name, kind);\n\tvStringDelete (name);\n\n\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\tif (e && state && state->access)\n\t\te->extensionFields.access = eStrdup (state->access);\n\n\treturn r;\n}\n\n/* Match a keyword starting at p (case insensitive). */\nstatic void match_state_reset (struct matchState *state)\n{\n\tstate->access = NULL;\n\tstate->end = false;\n\tstate->declaration =false;\n}\n\nstatic bool match_keyword (const char **cp, vString *buf,\n\t\t\t\t\t\t   struct matchState *state)\n{\n\tconst char *p;\n\n\tfor (p = *cp; *p != '\\0' && !isspace((unsigned char)*p); p++)\n\t{\n\t\tint c = tolower ((unsigned char)*p);\n\t\tvStringPut (buf, c);\n\t}\n\n\tint kw = lookupKeyword (vStringValue (buf), getInputLanguage ());\n\tif (kw == KEYWORD_NONE)\n\t\treturn false;\n\n\tconst char *old_p = p;\n\twhile (isspace ((unsigned char) *p))\n\t\tp++;\n\n\tif (kw == KEYWORD_ACCESS)\n\t{\n\t\tstate->access = vStringValue(buf)[1] == 'r'? \"private\": \"public\";\n\t\t*cp = p;\n\t\treturn true;\n\t}\n\telse if (kw == KEYWORD_END)\n\t{\n\t\tstate->end = true;\n\t\t*cp = p;\n\t\treturn true;\n\t}\n\telse if (kw == KEYWORD_DECLARE)\n\t{\n\t\tstate->declaration = true;\n\t\t*cp = p;\n\t\treturn true;\n\t}\n\n\tint kind = keywordToKind (kw);\n\tint index = CORK_NIL;\n\tif (!state->end)\n\t{\n\t\t/* create tags only if there is some space between the keyword and the identifier */\n\t\tif (kind != KIND_GHOST_INDEX && old_p == p)\n\t\t\treturn false;\n\n\t\tif (kind == K_VARIABLE)\n\t\t\textract_dim (p, kind); /* extract_dim adds the found tag(s) */\n\t\telse\n\t\t\tindex = extract_name (p, kind, state);\n\t}\n\n\tupdateScope (index, kind, kw);\n\n\treturn false;\n}\n\n/* Match a \"label:\" style label. */\nstatic void match_colon_label (char const *p)\n{\n\tchar const *end = p + strlen (p) - 1;\n\twhile (isspace ((unsigned char) *end))\n\t\tend--;\n\tif (*end == ':')\n\t{\n\t\tvString *name = vStringNewNInit (p, end - p);\n\t\tmakeBasicTag (name, K_LABEL);\n\t\tvStringDelete (name);\n\t}\n}\n\n/* Match a \".label\" style label. */\nstatic void match_dot_label (char const *p)\n{\n\textract_name (p + 1, K_LABEL, NULL);\n}\n\nstatic void findBasicTags (void)\n{\n\tconst char *line;\n\n\tcurrentScope = CORK_NIL;\n\tvString *buf = vStringNew ();\n\n\twhile ((line = (const char *) readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst char *p = line;\n\n\t\twhile (isspace ((unsigned char) *p))\n\t\t\tp++;\n\n\t\t/* Empty line? */\n\t\tif (!*p)\n\t\t\tcontinue;\n\n\t\t/* REM comment? */\n\t\tif (strncasecmp (p, \"REM\", 3) == 0  &&\n\t\t\t(isspace ((unsigned char) *(p + 3)) || *(p + 3) == '\\0'))\n\t\t\tcontinue;\n\n\t\t/* Single-quote comment? */\n\t\tif (*p == '\\'')\n\t\t\tcontinue;\n\n\t\t/* In Basic, keywords always are at the start of the line. */\n\t\tstruct matchState state;\n\t\tmatch_state_reset (&state);\n\t\tdo\n\t\t\tvStringClear (buf);\n\t\twhile (match_keyword (&p, buf, &state));\n\n\n\t\t/* Is it a label? */\n\t\tif (*p == '.')\n\t\t\tmatch_dot_label (p);\n\t\telse\n\t\t\tmatch_colon_label (p);\n\t}\n\tvStringDelete (buf);\n}\n\nparserDefinition *BasicParser (void)\n{\n\tstatic char const *extensions[] = { \"bas\", \"bi\", \"bm\", \"bb\", \"pb\", NULL };\n\tparserDefinition *def = parserNew (\"Basic\");\n\tdef->kindTable = BasicKinds;\n\tdef->kindCount = ARRAY_SIZE (BasicKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findBasicTags;\n\tdef->keywordTable = BasicKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (BasicKeywordTable);\n\tdef->useCork = CORK_QUEUE;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/bats.c",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Bats scripts.\n*\n*   Reference:\n*   https://bats-core.readthedocs.io/en/stable/writing-tests.html\n*\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"x-sh.h\"\n\n#include <ctype.h>\n\n\nstruct sBatsSubparser {\n\tshSubparser sh;\n\tint kind;\n\tint role;\n};\n\n\ntypedef enum {\n\tR_SCRIPT_LOADED,\n} batsScriptRole;\n\nstatic roleDefinition BatsScriptRoles [] = {\n\t{ true, \"loaded\", \"script loaed with \\\"load\\\" command\" },\n};\n\ntypedef enum  {\n\tK_TEST,\n\tK_SCRIPT,\n} batsKind;\n\nstatic kindDefinition BatsKinds[] = {\n\t{ true, 't', \"test\", \"test cases\", },\n\t{ true, 'S', \"script\", \"scripts\",\n\t  .referenceOnly = true, ATTACH_ROLES(BatsScriptRoles)},\n};\n\n\nstatic void inputStart (subparser *s)\n{\n\tstruct sBatsSubparser *bats = (struct sBatsSubparser*)s;\n\n\tbats->kind = KIND_GHOST_INDEX;\n\tbats->role = ROLE_DEFINITION_INDEX;\n}\n\nstatic int lineNotify (shSubparser *s, const unsigned char *cp)\n{\n\tstruct sBatsSubparser *bats = (struct sBatsSubparser*)s;\n\n\tif (cp[0] == '@' &&\n\t\tcp[1] == 't' &&\n\t\tcp[2] == 'e' &&\n\t\tcp[3] == 's' &&\n\t\tcp[4] == 't' &&\n\t\tisspace(cp[5]))\n\t{\n\t\tbats->kind = K_TEST;\n\t\tbats->role = ROLE_DEFINITION_INDEX;\n\t\treturn 5;\n\t}\n\telse if (cp[0] == 'l' &&\n\t\t\t cp[1] == 'o' &&\n\t\t\t cp[2] == 'a' &&\n\t\t\t cp[3] == 'd' &&\n\t\t\t isspace(cp[4]))\n\t{\n\t\tbats->kind = K_SCRIPT;\n\t\tbats->role = R_SCRIPT_LOADED;\n\t\treturn 4;\n\t}\n\treturn 0;\n}\n\nstatic int readDString (const unsigned char *cp, vString *name)\n{\n\tconst unsigned char *initial = cp;\n\tbool escape = false;\n\n\twhile (*cp)\n\t{\n\t\tif (escape)\n\t\t{\n\t\t\tif (!(*cp == '\\\\' || *cp == '\"'))\n\t\t\t\tvStringPut(name, '\\\\');\n\t\t\tvStringPut(name, *cp);\n\t\t\tescape = false;\n\t\t}\n\t\telse if (*cp == '\\\\')\n\t\t\tescape = true;\n\t\telse if (*cp == '\"')\n\t\t\tbreak;\n\t\telse\n\t\t\tvStringPut(name, *cp);\n\t\tcp++;\n\t}\n\n\treturn cp - initial;\n}\n\nstatic int readSString (const unsigned char *cp, vString *name)\n{\n\tconst unsigned char *initial = cp;\n\n\twhile (*cp)\n\t{\n\t\tif (*cp == '\\'')\n\t\t\tbreak;\n\t\tvStringPut(name, *cp);\n\t\tcp++;\n\t}\n\n\treturn cp - initial;\n}\n\nstatic int readToken(const unsigned char *cp, vString *name)\n{\n\tconst unsigned char *initial = cp;\n\tbool escape = false;\n\n\twhile (*cp)\n\t{\n\t\tif (escape)\n\t\t{\n\t\t\tvStringPut(name, *cp);\n\t\t\tescape = false;\n\t\t}\n\t\telse if (*cp == '\\\\')\n\t\t\tescape = true;\n\t\telse if (isspace(*cp)\n\t\t\t\t || *cp == ';'\n\t\t\t\t || *cp == '|'\n\t\t\t\t || *cp == '&'\n\t\t\t\t || *cp == '>'\n\t\t\t\t || *cp == '<')\n\t\t\tbreak;\n\t\telse\n\t\t\tvStringPut(name, *cp);\n\t\tcp++;\n\t}\n\n\treturn cp - initial;\n}\n\nstatic int extractName (shSubparser *s, const unsigned char *cp,\n\t\t\t\t\t\tvString *name)\n{\n\tint n;\n\n\tif (*cp == '\"')\n\t\tn = readDString(cp + 1, name);\n\telse if (*cp == '\\'')\n\t\tn = readSString(cp + 1, name);\n\telse\n\t\tn = readToken(cp, name);\n\n\treturn n;\n}\n\nstatic int makeTag (shSubparser *s, vString *name)\n{\n\tint r;\n\tstruct sBatsSubparser *bats = (struct sBatsSubparser*)s;\n\n\tAssert(bats->kind != KIND_GHOST_INDEX);\n\tr = makeSimpleRefTag(name, bats->kind, bats->role);\n\tbats->kind = KIND_GHOST_INDEX;\n\tbats->role = ROLE_DEFINITION_INDEX;\n\n\treturn r;\n}\n\nstatic struct sBatsSubparser batsSubparser = {\n\t.sh = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t\t.inputStart = inputStart,\n\t\t},\n\t\t.lineNotify  = lineNotify,\n\t\t.extractName = extractName,\n\t\t.makeTag     = makeTag,\n\t},\n};\n\nstatic void findBatsTags(void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* BatsParser (void)\n{\n\tstatic const char *const extensions [] = { \"bats\", NULL };\n\tparserDefinition* const def = parserNew(\"Bats\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Sh\", &batsSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = BatsKinds;\n\tdef->kindCount = ARRAY_SIZE(BatsKinds);\n\n\tdef->extensions = extensions;\n\tdef->parser = findBatsTags;\n\tdef->useCork = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/beta.c",
    "content": "/*\n*   Copyright (c) 1999-2000, Mjølner Informatics\n*\n*   Written by Erik Corry <corry@mjolner.dk>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for BETA language\n*   files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n/*\n*   MACROS\n*/\n#define isbident(c) (identarray [(unsigned char) (c)])\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_FRAGMENT, K_PATTERN, K_SLOT, K_VIRTUAL\n} betaKind;\n\nstatic kindDefinition BetaKinds [] = {\n\t{ true,  'f', \"fragment\", \"fragment definitions\"},\n\t{ false, 'p', \"pattern\",  \"all patterns\"},\n\t{ true,  's', \"slot\",     \"slots (fragment uses)\"},\n\t{ true,  'v', \"virtual\",  \"patterns (virtual or rebound)\"}\n};\n\n/* [A-Z_a-z0-9] */\nstatic const char identarray [256] = {\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0-15  */\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 16-31 */\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 32-47    !\"#$%&'()*+'-./ */\n1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 48-63   0123456789:;<=>? */\n0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 64-79   @ABCDEFGHIJKLMNO */\n1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  /* 80-95   PQRSTUVWXYZ [\\]^_ */\n0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 96-111  `abcdefghijklmno */\n1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  /* 112-127  pqrstuvwxyz{|}~ */\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 128-  */\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* -255  */\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void makeBetaTag (const char* const name, const betaKind kind)\n{\n\tif (BetaKinds [kind].enabled)\n\t{\n\t\ttagEntryInfo e;\n\t\tinitTagEntry (&e, name, kind);\n\t\tmakeTagEntry (&e);\n\t}\n}\n\nstatic void findBetaTags (void)\n{\n\tvString *line = vStringNew ();\n\tbool incomment = false;\n\tbool inquote = false;\n\tbool dovirtuals = BetaKinds [K_VIRTUAL].enabled;\n\tbool dopatterns = BetaKinds [K_PATTERN].enabled;\n\n\tint c;\n\tdo\n\t{\n\t\tbool foundfragmenthere = false;\n\t\t/* find fragment definition (line that starts and ends with --) */\n\t\tint last;\n\t\tint first;\n\n\t\tvStringClear (line);\n\n\t\twhile ((c = getcFromInputFile ()) != EOF && c != '\\n' && c != '\\r')\n\t\t\tvStringPut (line, c);\n\n\t\tlast = vStringLength (line) - 1;\n\t\tfirst = 0;\n\t\t/* skip white space at start and end of line */\n\t\twhile (last > 0 && isspace ((unsigned char) vStringChar (line, last)))\n\t\t\tlast--;\n\t\twhile (first < last &&\n\t\t       isspace ((unsigned char) vStringChar (line, first)))\n\t\t\tfirst++;\n\t\t/* if line still has a reasonable length and ... */\n\t\tif (last - first > 4 &&\n\t\t\t(vStringChar (line, first)     == '-' &&\n\t\t\t vStringChar (line, first + 1) == '-' &&\n\t\t\t vStringChar (line, last)      == '-' &&\n\t\t\t vStringChar (line, last - 1)  == '-'))\n\t\t{\n\t\t\tif (!incomment && !inquote)\n\t\t\t{\n\t\t\t\tfoundfragmenthere = true;\n\t\t\t\t/* skip past -- and whitespace.  Also skip back past 'dopart'\n\t\t\t\t   or 'attributes' to the :.  We have to do this because there\n\t\t\t\t   is no sensible way to include whitespace in a ctags token\n\t\t\t\t   so the conventional space after the ':' would mess us up */\n\t\t\t\tlast -= 2;\n\t\t\t\tfirst += 2;\n\t\t\t\twhile (last && vStringChar (line, last) != ':') last--;\n\t\t\t\twhile (last &&\n\t\t\t\t       (isspace ((unsigned char) vStringChar (line, last-1))))\n\t\t\t\t\tlast--;\n\t\t\t\twhile (first < last &&\n\t\t\t\t\t   (isspace ((unsigned char) vStringChar (line, first)) ||\n\t\t\t\t\t\tvStringChar (line, first) == '-'))\n\t\t\t\t\tfirst++;\n\t\t\t\t/* If there's anything left it is a fragment title */\n\t\t\t\tif (first < last - 1)\n\t\t\t\t{\n\t\t\t\t\tvStringChar (line, last) = 0;\n\t\t\t\t\tif (strcasecmp (\"LIB\", vStringValue (line) + first) &&\n\t\t\t\t\t\tstrcasecmp (\"PROGRAM\", vStringValue (line) + first))\n\t\t\t\t\t{\n\t\t\t\t\t\tmakeBetaTag (vStringValue (line) + first, K_FRAGMENT);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tint pos = 0;\n\t\t\tint len = vStringLength (line);\n\t\t\tif (inquote) goto stringtext;\n\t\t\tif (incomment) goto commenttext;\n\t\tprogramtext:\n\t\t\tfor ( ; pos < len; pos++)\n\t\t\t{\n\t\t\t\tif (vStringChar (line, pos) == '\\'')\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t\tinquote = true;\n\t\t\t\t\tgoto stringtext;\n\t\t\t\t}\n\t\t\t\tif (vStringChar (line, pos) == '{')\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t\tincomment = true;\n\t\t\t\t\tgoto commenttext;\n\t\t\t\t}\n\t\t\t\tif (vStringChar (line, pos) == '(' && pos < len - 1 &&\n\t\t\t\t\tvStringChar (line, pos+1) == '*')\n\t\t\t\t{\n\t\t\t\t\tpos +=2;\n\t\t\t\t\tincomment = true;\n\t\t\t\t\tgoto commenttext;\n\t\t\t\t}\n\t\t\t\t/*\n\t\t\t\t * SLOT definition looks like this:\n\t\t\t\t * <<SLOT nameofslot: dopart>>\n\t\t\t\t * or\n\t\t\t\t * <<SLOT nameofslot: descriptor>>\n\t\t\t\t */\n\t\t\t\tif (!foundfragmenthere &&\n\t\t\t\t\tvStringChar (line, pos) == '<' &&\n\t\t\t\t\tpos+1 < len &&\n\t\t\t\t\tvStringChar (line, pos+1) == '<' &&\n\t\t\t\t\tstrstr (vStringValue (line) + pos, \">>\"))\n\t\t\t\t{\n\t\t\t\t\t/* Found slot name, get start and end */\n\t\t\t\t\tint eoname;\n\t\t\t\t\tchar c2;\n\t\t\t\t\tpos += 2; /* skip past << */\n\t\t\t\t\t/* skip past space before SLOT */\n\t\t\t\t\twhile (pos < len &&\n\t\t\t\t\t       isspace ((unsigned char) vStringChar (line, pos)))\n\t\t\t\t\t\tpos++;\n\t\t\t\t\t/* skip past SLOT */\n\t\t\t\t\tif (pos+4 <= len &&\n\t\t\t\t\t\t!strncasecmp (vStringValue(line) + pos, \"SLOT\", (size_t)4))\n\t\t\t\t\t\tpos += 4;\n\t\t\t\t\t/* skip past space after SLOT */\n\t\t\t\t\twhile (pos < len &&\n\t\t\t\t\t       isspace ((unsigned char) vStringChar (line, pos)))\n\t\t\t\t\t\tpos++;\n\t\t\t\t\teoname = pos;\n\t\t\t\t\t/* skip to end of name */\n\t\t\t\t\twhile (eoname < len &&\n\t\t\t\t\t\t\t(c2 = vStringChar (line, eoname)) != '>' &&\n\t\t\t\t\t\t\tc2 != ':' &&\n\t\t\t\t\t\t\t!isspace ((unsigned char) c2))\n\t\t\t\t\t\teoname++;\n\t\t\t\t\tif (eoname < len)\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringChar (line, eoname) = 0;\n\t\t\t\t\t\tif (strcasecmp (\"LIB\", vStringValue (line) + pos) &&\n\t\t\t\t\t\t\tstrcasecmp (\"PROGRAM\", vStringValue (line) + pos) &&\n\t\t\t\t\t\t\tstrcasecmp (\"SLOT\", vStringValue (line) + pos))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmakeBetaTag (vStringValue (line) + pos, K_SLOT);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (eoname+1 < len) {\n\t\t\t\t\t\tpos = eoname + 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpos = len;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t/* Only patterns that are virtual, extensions of virtuals or\n\t\t\t\t * final bindings are normally included so as not to overload\n\t             * totally.\n\t\t\t\t * That means one of the forms name:: name:< or name::<\n\t\t\t\t */\n\t\t\t\tif (!foundfragmenthere &&\n\t\t\t\t\tvStringChar (line, pos) == ':' &&\n\t                (dopatterns ||\n\t\t\t\t\t (dovirtuals &&\n\t\t\t\t\t  (vStringChar (line, pos+1) == ':' ||\n\t\t\t\t\t   vStringChar (line, pos+1) == '<')\n\t\t\t\t\t )\n\t\t\t\t\t)\n\t               )\n\t\t\t\t{\n\t\t\t\t\t/* Found pattern name, get start and end */\n\t\t\t\t\tint eoname = pos;\n\t\t\t\t\tint soname;\n\t\t\t\t\twhile (eoname &&\n\t\t\t\t\t       isspace ((unsigned char) vStringChar (line, eoname-1)))\n\t\t\t\t\t\teoname--;\n\t\t\t\tfoundanothername:\n\t\t\t\t\t/* terminate right after name */\n\t\t\t\t\tvStringChar (line, eoname) = 0;\n\t\t\t\t\tsoname = eoname;\n\t\t\t\t\twhile (soname &&\n\t\t\t\t\t\tisbident (vStringChar (line, soname-1)))\n\t\t\t\t\t{\n\t\t\t\t\t\tsoname--;\n\t\t\t\t\t}\n\t\t\t\t\tif (soname != eoname)\n\t\t\t\t\t{\n\t\t\t\t\t\tmakeBetaTag (vStringValue (line) + soname, K_PATTERN);\n\t\t\t\t\t\t/* scan back past white space */\n\t\t\t\t\t\twhile (soname &&\n\t\t\t\t\t\t       isspace ((unsigned char) vStringChar (line, soname-1)))\n\t\t\t\t\t\t\tsoname--;\n\t\t\t\t\t\tif (soname && vStringChar (line, soname-1) == ',')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* we found a new pattern name before comma */\n\t\t\t\t\t\t\teoname = soname;\n\t\t\t\t\t\t\tgoto foundanothername;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tgoto endofline;\n\t\tcommenttext:\n\t\t\tfor ( ; pos < len; pos++)\n\t\t\t{\n\t\t\t\tif (vStringChar (line, pos) == '*' && pos < len - 1 &&\n\t\t\t\t\tvStringChar (line, pos+1) == ')')\n\t\t\t\t{\n\t\t\t\t\tpos += 2;\n\t\t\t\t\tincomment = false;\n\t\t\t\t\tgoto programtext;\n\t\t\t\t}\n\t\t\t\tif (vStringChar (line, pos) == '}')\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t\tincomment = false;\n\t\t\t\t\tgoto programtext;\n\t\t\t\t}\n\t\t\t}\n\t\t\tgoto endofline;\n\t\tstringtext:\n\t\t\tfor ( ; pos < len; pos++)\n\t\t\t{\n\t\t\t\tif (vStringChar (line, pos) == '\\\\')\n\t\t\t\t{\n\t\t\t\t\tif (pos < len - 1) pos++;\n\t\t\t\t}\n\t\t\t\telse if (vStringChar (line, pos) == '\\'')\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t\t/* support obsolete '' syntax */\n\t\t\t\t\tif (pos < len && vStringChar (line, pos) == '\\'')\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tinquote = false;\n\t\t\t\t\tgoto programtext;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tendofline:\n\t\tinquote = false;  /* This shouldn't really make a difference */\n\t} while (c != EOF);\n\tvStringDelete (line);\n}\n\nextern parserDefinition* BetaParser (void)\n{\n\tstatic const char *const extensions [] = { \"bet\", NULL };\n\tparserDefinition* def = parserNew (\"BETA\");\n\tdef->kindTable      = BetaKinds;\n\tdef->kindCount  = ARRAY_SIZE (BetaKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findBetaTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/biblatex.c",
    "content": "/*\n *   Copyright (c) 2023, Masatake YAMATO\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for BibLaTeX source files\n *   https://ftp.yz.yamagata-u.ac.jp/pub/CTAN/macros/latex/contrib/biblatex/doc/biblatex.pdf\n *\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"  /* must always come first */\n\n#include \"x-bibtex.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n\n/*\n *   DATA DECLARATIONS\n */\nstruct bibLaTeXSubparser {\n\tbibTexSubparser bib;\n};\n\nenum BibLaTeXKind {\n\tK_ARTWORK,\n\tK_AUDIO,\n\tK_BIBNOTE,\n\tK_BOOKINBOOK,\n\tK_BOOKLET,\n\tK_COLLECTION,\n\tK_COMMENTARY,\n\tK_DATASET,\n\tK_IMAGE,\n\tK_INTERFERENCE,\n\tK_JURISDICTION,\n\tK_LEGISLATION,\n\tK_LEGAL,\n\tK_LETTER,\n\tK_MOVIE,\n\tK_MUSIC,\n\tK_MVBOOK,\n\tK_MVCOLLECTION,\n\tK_MVPROCEEDINGS,\n\tK_MVREFERENCE,\n\tK_ONLINE,\n\tK_PATENT,\n\tK_PERFORMANCE,\n\tK_PERIODICAL,\n\tK_REFERENCE,\n\tK_REPORT,\n\tK_REVIEW,\n\tK_SET,\n\tK_SOFTWARE,\n\tK_STANDARD,\n\tK_SUPPBOOK,\n\tK_SUPPCOLLECTION,\n\tK_SUPPPERIODICAL,\n\tK_THESIS,\n\tK_VIDEO,\n\tK_XDATA,\n};\n\n/*\n *\tDATA DEFINITIONS\n */\nstatic kindDefinition BibLaTeXKinds[] = {\n\t{ true, 'A', \"artwork\", \"artworks\"  },\n\t{ true, 'B', \"audio\", \"audios\"  },\n\t{ true, 'C', \"bibnote\", \"bibnotes\"  },\n\t{ true, 'D', \"bookinbook\", \"bookinbooks\"  },\n\t{ true, 'E', \"Booklet\", \"Booklets\"  },\n\t/* F is for reserved in main. */\n\t{ true, 'G', \"collection\", \"collections\"  },\n\t{ true, 'H', \"commentary\", \"commentarys\"  },\n\t{ true, 'I', \"dataset\", \"datasets\"  },\n\t{ true, 'J', \"image\", \"images\"  },\n\t{ true, 'K', \"interference\", \"interferences\"  },\n\t{ true, 'L', \"jurisdiction\", \"jurisdictions\"  },\n\t{ true, 'M', \"legislation\", \"legislations\"  },\n\t{ true, 'N', \"legal\", \"legals\"  },\n\t{ true, 'O', \"letter\", \"letters\"  },\n\t{ true, 'P', \"movie\", \"movies\"  },\n\t{ true, 'Q', \"music\", \"musics\"  },\n\t{ true, 'R', \"mvbook\", \"mvbooks\"  },\n\t{ true, 'S', \"mvcollection\", \"mvcollections\"  },\n\t{ true, 'T', \"mvproceedings\", \"mvproceedings\"  },\n\t{ true, 'U', \"mvreference\", \"mvreferences\"  },\n\t{ true, 'V', \"online\", \"onlines\"  },\n\t{ true, 'W', \"patent\", \"patents\"  },\n\t/* X, Y, Z are reserved. */\n\t/* a, b, c, d, e, f are reserved for custom[a-f]. */\n\t{ true, 'g', \"performance\", \"performances\"  },\n\t{ true, 'h', \"periodical\", \"periodicals\"  },\n\t{ true, 'i', \"reference\", \"references\"  },\n\t{ true, 'j', \"report\", \"reports\"  },\n\t{ true, 'k', \"review\", \"reviews\"  },\n\t{ true, 'l', \"set\", \"sets\"  },\n\t{ true, 'm', \"software\", \"software\"  },\n\t{ true, 'n', \"standard\", \"standards\"  },\n\t{ true, 'o', \"suppbook\", \"suppbooks\"  },\n\t{ true, 'p', \"suppcollection\", \"suppcollections\"  },\n\t{ true, 'q', \"suppperiodical\", \"suppperiodicals\"  },\n\t{ true, 'r', \"thesis\", \"thesis\"  },\n\t{ true, 's', \"video\", \"videos\"  },\n\t{ true, 't', \"xdata\", \"xdatas\"  },\n\t/* x, y, z are reserved. */\n};\n\nstatic const keywordTable BibLaTeXTable [] = {\n\t{ \"artwork\", K_ARTWORK },\n\t{ \"audio\", K_AUDIO },\n\t{ \"bibnote\", K_BIBNOTE },\n\t{ \"bookinbook\", K_BOOKINBOOK },\n\t{ \"Booklet\", K_BOOKLET },\n\t{ \"collection\", K_COLLECTION },\n\t{ \"commentary\", K_COMMENTARY },\n\t{ \"dataset\", K_DATASET },\n\t{ \"image\", K_IMAGE },\n\t{ \"interference\", K_INTERFERENCE },\n\t{ \"jurisdiction\", K_JURISDICTION },\n\t{ \"legislation\", K_LEGISLATION },\n\t{ \"legal\", K_LEGAL },\n\t{ \"letter\", K_LETTER },\n\t{ \"movie\", K_MOVIE },\n\t{ \"music\", K_MUSIC },\n\t{ \"mvbook\", K_MVBOOK },\n\t{ \"mvcollection\", K_MVCOLLECTION },\n\t{ \"mvproceedings\", K_MVPROCEEDINGS },\n\t{ \"mvreference\", K_MVREFERENCE },\n\t{ \"online\", K_ONLINE },\n\t{ \"patent\", K_PATENT },\n\t{ \"performance\", K_PERFORMANCE },\n\t{ \"periodical\", K_PERIODICAL },\n\t{ \"reference\", K_REFERENCE },\n\t{ \"report\", K_REPORT },\n\t{ \"review\", K_REVIEW },\n\t{ \"set\", K_SET },\n\t{ \"software\", K_SOFTWARE },\n\t{ \"standard\", K_STANDARD },\n\t{ \"suppbook\", K_SUPPBOOK },\n\t{ \"suppcollection\", K_SUPPCOLLECTION },\n\t{ \"suppperiodical\", K_SUPPPERIODICAL },\n\t{ \"thesis\", K_THESIS },\n\t{ \"video\", K_VIDEO },\n\t{ \"xdata\", K_XDATA },\n};\n\nstatic langType Lang_biblatex;\n\n/*\n *\t FUNCTION DEFINITIONS\n */\nstatic int isKeywordForTagging (bibTexSubparser *bibtex,\n\t\t\t\t\t\t\t\tconst char *string)\n{\n\tint kind = lookupKeyword (string, Lang_biblatex);\n\tif (kind == KEYWORD_NONE)\n\t\treturn KIND_GHOST_INDEX;\n\treturn kind;\n}\n\nstatic void findBibLaTeXTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic struct bibLaTeXSubparser bibLaTeXSubparser = {\n\t.bib = {\n\t\t.subparser = {\n\t\t\t.direction  = SUBPARSER_BI_DIRECTION,\n\t\t},\n\t\t.isKeywordForTagging = isKeywordForTagging,\n\t},\n};\n\nstatic void initialize (const langType language)\n{\n\tLang_biblatex = language;\n}\n\nextern parserDefinition* BibLaTeXParser (void)\n{\n\tparserDefinition* const def = parserNew(\"BibLaTeX\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"BibTeX\", &bibLaTeXSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->keywordTable = BibLaTeXTable;\n\tdef->keywordCount = ARRAY_SIZE (BibLaTeXTable);\n\n\tdef->kindTable = BibLaTeXKinds;\n\tdef->kindCount = ARRAY_SIZE(BibLaTeXKinds);\n\n\tdef->parser = findBibLaTeXTags;\n\tdef->initialize = initialize;\n\n\treturn def;\n}\n\n/*\n(defconst biblatex-kinds '(\n\t(\"artwork\")\n\t(\"audio\")\n\t(\"bibnote\")\n\t(\"bookinbook\")\n\t(\"Booklet\")\n\t(\"collection\")\n\t(\"commentary\")\n\t(\"dataset\")\n\t(\"image\")\n\t(\"interference\")\n\t(\"jurisdiction\")\n\t(\"legislation\")\n\t(\"legal\")\n\t(\"letter\")\n\t(\"movie\")\n\t(\"music\")\n\t(\"mvbook\")\n\t(\"mvcollection\")\n\t(\"mvproceedings\" . t)\n\t(\"mvreference\")\n\t(\"online\")\n\t(\"patent\")\n\t(\"performance\")\n\t(\"periodical\")\n\t(\"reference\")\n\t(\"report\")\n\t(\"review\")\n\t(\"set\")\n\t(\"software\" . t)\n\t(\"standard\")\n\t(\"suppbook\")\n\t(\"suppcollection\")\n\t(\"suppperiodical\")\n\t(\"thesis\")\n\t(\"video\")\n\t(\"xdata\")))\n(mapc (lambda (x)\n\t   ;(insert (format \"\tK_%s,\\n\" (upcase (car x))))\n\t   ;(insert (format \"\t{ true, '', \\\"%s\\\", \\\"%s\\\"  },\\n\" (car x) (if (cdr x) (car x) (concat (car x) \"s\"))))\n\t   (insert (format \"\t{ \\\"%s\\\", K_%s },\\n\" (car x) (upcase (car x))))\n\t)\n biblatex-kinds)\n*/\n"
  },
  {
    "path": "parsers/bibtex.c",
    "content": "/*\n *\t Copyright (c) 2008, David Fishburn\n *\t Copyright (c) 2012, Jan Larres\n *\t Copyright (c) 2019, Mirco Schönfeld\n *\n *\t This source code is released for free distribution under the terms of the\n *\t GNU General Public License version 2 or (at your option) any later version.\n *\n *\t This module contains functions for generating identifiers of entries of Bibtex language files.\n *\n *\t BibTex language \"reference\":\n *\t\t https://en.wikipedia.org/wiki/BibTeX\n */\n\n/*\n *\t INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n#include <ctype.h>\t/* to define isalpha () */\n#include <string.h>\n\n#include \"debug.h\"\n#include \"x-bibtex.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n/*\n *\t MACROS\n */\n#define isType(token,t)\t\t(bool) ((token)->type == (t))\n#define isKeyword(token,k)\t(bool) ((token)->keyword == (k))\n#define isIdentChar(c) \\\n\t(isalpha (c) || isdigit (c) || (c) == '_' || (c) == '-' || (c) == '+' || (c) == ':' || (c) == '.' || (c) == '/')\n\n/*\n *\t DATA DECLARATIONS\n */\n\n/*\n * Used to specify type of keyword.\n */\nenum eKeywordId {\n\tKEYWORD_article,\n\tKEYWORD_book,\n\tKEYWORD_booklet,\n\tKEYWORD_conference,\n\tKEYWORD_inbook,\n\tKEYWORD_incollection,\n\tKEYWORD_inproceedings,\n\tKEYWORD_manual,\n\tKEYWORD_mastersthesis,\n\tKEYWORD_misc,\n\tKEYWORD_phdthesis,\n\tKEYWORD_proceedings,\n\tKEYWORD_string,\n\tKEYWORD_techreport,\n\tKEYWORD_unpublished\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\nenum eTokenType {\n\t/* 0..255 are the byte's value.  Some are named for convenience */\n\tTOKEN_OPEN_CURLY = '{',\n\t/* above is special types */\n\tTOKEN_UNDEFINED = 256,\n\tTOKEN_KEYWORD,\n\tTOKEN_IDENTIFIER\n};\ntypedef int tokenType;\n\ntypedef struct sTokenInfo {\n\ttokenType\t\ttype;\n\tkeywordId\t\tkeyword;\n\tvString *\t\tstring;\n\tunsigned long \tlineNumber;\n\tMIOPos \t\t\tfilePosition;\n} tokenInfo;\n\n/*\n *\tDATA DEFINITIONS\n */\n\nstatic langType Lang_bib;\n\ntypedef enum {\n\tBIBTAG_ARTICLE,\n\tBIBTAG_BOOK,\n\tBIBTAG_BOOKLET,\n\tBIBTAG_CONFERENCE,\n\tBIBTAG_INBOOK,\n\tBIBTAG_INCOLLECTION,\n\tBIBTAG_INPROCEEDINGS,\n\tBIBTAG_MANUAL,\n\tBIBTAG_MASTERSTHESIS,\n\tBIBTAG_MISC,\n\tBIBTAG_PHDTHESIS,\n\tBIBTAG_PROCEEDINGS,\n\tBIBTAG_STRING,\n\tBIBTAG_TECHREPORT,\n\tBIBTAG_UNPUBLISHED,\n\tBIBTAG_COUNT\n} bibKind;\n\nstatic kindDefinition BibKinds [] = {\n\t{ true,  'a', \"article\",\t\t\t\t\"article\"\t\t\t\t},\n\t{ true,  'b', \"book\",\t\t\t\t\t\t\"book\"\t\t\t\t\t},\n\t{ true,  'B', \"booklet\",\t\t\t\t\"booklet\"\t\t\t\t},\n\t{ true,  'c', \"conference\",\t\t\t\"conference\"\t\t},\n\t{ true,  'i', \"inbook\",\t\t\t\t\t\"inbook\"\t\t\t\t},\n\t{ true,  'I', \"incollection\",\t\t\"incollection\"\t},\n\t{ true,  'j', \"inproceedings\",\t\"inproceedings\"\t},\n\t{ true,  'm', \"manual\",\t\t\t\t\t\"manual\"\t\t\t\t},\n\t{ true,  'M', \"mastersthesis\",\t\"mastersthesis\"\t},\n\t{ true,  'n', \"misc\",\t\t\t\t\t\t\"misc\"\t\t\t\t\t},\n\t{ true,  'p', \"phdthesis\",\t\t\t\"phdthesis\"\t\t\t},\n\t{ true,  'P', \"proceedings\",\t\t\"proceedings\"\t\t},\n\t{ true,  's', \"string\",\t\t\t\t\t\"string\"\t\t\t\t},\n\t{ true,  't', \"techreport\",\t\t\t\"techreport\"\t\t},\n\t{ true,  'u', \"unpublished\",\t\t\"unpublished\"\t\t}\n};\n\nstatic const keywordTable BibKeywordTable [] = {\n\t/* keyword\t\t\t  keyword ID */\n\t{ \"article\",\t    KEYWORD_article\t\t\t\t},\n\t{ \"book\",\t        KEYWORD_book\t\t\t\t  },\n\t{ \"booklet\",\t    KEYWORD_booklet\t\t\t\t},\n\t{ \"conference\",\t  KEYWORD_conference\t\t},\n\t{ \"inbook\",\t      KEYWORD_inbook\t\t\t\t},\n\t{ \"incollection\",\tKEYWORD_incollection\t},\n\t{ \"inproceedings\",KEYWORD_inproceedings\t},\n\t{ \"manual\",\t      KEYWORD_manual\t\t\t\t},\n\t{ \"mastersthesis\",KEYWORD_mastersthesis\t},\n\t{ \"misc\",\t        KEYWORD_misc\t\t\t\t  },\n\t{ \"phdthesis\",\t  KEYWORD_phdthesis\t\t\t},\n\t{ \"proceedings\",\tKEYWORD_proceedings\t\t},\n\t{ \"string\",\t\t\t\tKEYWORD_string\t\t\t\t},\n\t{ \"techreport\",\t  KEYWORD_techreport\t\t},\n\t{ \"unpublished\",\tKEYWORD_unpublished\t\t}\n};\n\n/*\n *\t FUNCTION DEFINITIONS\n */\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->string\t\t= vStringNew ();\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\treturn token;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tvStringDelete (token->string);\n\teFree (token);\n}\n\n/*\n *\t Tag generation functions\n */\nstatic void makeBibTag (tokenInfo *const token, bibKind kind)\n{\n\tconst char *const name = vStringValue (token->string);\n\ttagEntryInfo e;\n\tinitTagEntry (&e, name, kind);\n\n\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\n\tmakeTagEntry (&e);\n}\n\n/*\n *\t Parsing functions\n */\n\n/*\n *\tRead a C identifier beginning with \"firstChar\" and places it into\n *\t\"name\".\n */\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tAssert (isIdentChar (c));\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (c != EOF && isIdentChar (c));\n\tif (c != EOF)\n\t\tungetcToInputFile (c);\t\t/* unget non-identifier character */\n}\n\nstatic bool readToken (tokenInfo *const token)\n{\n\tint c;\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t}\n\twhile (c == '\\t' || c == ' ' || c == '\\n');\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\ttoken->type = (unsigned char) c;\n\tswitch (c)\n\t{\n\t\tcase EOF: return false;\n\n\t\tcase '@':\n\t\t\t\t\t/*\n\t\t\t\t\t * All Bib entries start with an at symbol.\n\t\t\t\t\t * Check if the next character is an alpha character\n\t\t\t\t\t * else it is not a potential tex tag.\n\t\t\t\t\t */\n\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t\tif (! isalpha (c))\n\t\t\t\t\t  ungetcToInputFile (c);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (token->string, '@');\n\t\t\t\t\t\tparseIdentifier (token->string, c);\n\t\t\t\t\t\ttoken->keyword = lookupCaseKeyword (vStringValue (token->string) + 1, Lang_bib);\n\t\t\t\t\t\tif (isKeyword (token, KEYWORD_NONE))\n\t\t\t\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\tcase '%':\n\t\t\t\t\tskipToCharacterInInputFile ('\\n'); /* % are single line comments */\n\t\t\t\t\tgoto getNextChar;\n\t\t\t\t\tbreak;\n\t\tdefault:\n\t\t\t\t\tif (isIdentChar (c))\n\t\t\t\t\t{\n\t\t\t\t\t\tparseIdentifier (token->string, c);\n\t\t\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t}\n\treturn true;\n}\n\nstatic void copyToken (tokenInfo *const dest, tokenInfo *const src)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tdest->keyword = src->keyword;\n\tvStringCopy (dest->string, src->string);\n}\n\n/*\n *\t Scanning functions\n */\n\nstatic bool parseTag (tokenInfo *const token, bool foreignKeyword, int kind)\n{\n\ttokenInfo *\tconst name = newToken ();\n\tvString *\t\tcurrentid;\n\tbool\t\t\t\teof = false;\n\n\tcurrentid = vStringNew ();\n\t/*\n\t * Bib entries are of these formats:\n\t *   @article{identifier,\n\t *   author=\"John Doe\"}\n\t *\n\t * When a keyword is found, loop through all words up to\n\t * a comma brace for the tag name.\n\t *\n\t */\n\tif (isType (token, TOKEN_KEYWORD) || foreignKeyword)\n\t{\n\t\tcopyToken (name, token);\n\t\tif (!readToken (token))\n\t\t{\n\t\t\teof = true;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tif (!readToken (token))\n\t\t{\n\t\t\teof = true;\n\t\t\tgoto out;\n\t\t}\n\t\tif (isType (token, TOKEN_IDENTIFIER)){\n\t\t\tvStringCat (currentid, token->string);\n\t\t\tvStringStripTrailing (currentid);\n\t\t\tif (vStringLength (currentid) > 0)\n\t\t\t{\n\t\t\t\tvStringCopy (name->string, currentid);\n\t\t\t\tmakeBibTag (name, kind);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{ // should find an identifier for bib item at first place\n\t\t\teof = true;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n out:\n\tdeleteToken (name);\n\tvStringDelete (currentid);\n\treturn eof;\n}\n\nstatic bool mayParseTokenInSubparser (tokenInfo *const token)\n{\n\tbool eof = false;\n\tsubparser *sub;\n\n\tif (*vStringValue (token->string) != '@')\n\t\treturn eof;\n\n\tforeachSubparser (sub, true)\n\t{\n\t\tbibTexSubparser *bibsub = (bibTexSubparser *)sub;\n\t\tif (bibsub->isKeywordForTagging)\n\t\t{\n\t\t\tint kind;\n\t\t\tenterSubparser (sub);\n\t\t\tkind = bibsub->isKeywordForTagging (bibsub,\n\t\t\t\t\t\t\t\t\t\t\t\tvStringValue (token->string) + 1);\n\t\t\tif (kind != KIND_GHOST_INDEX)\n\t\t\t\teof = parseTag (token, true, kind);\n\t\t\tleaveSubparser ();\n\t\t\tif (kind != KIND_GHOST_INDEX)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn eof;\n}\n\nstatic void parseBibFile (tokenInfo *const token)\n{\n\tbool eof = false;\n\n\tdo\n\t{\n\t\tif (!readToken (token))\n\t\t\tbreak;\n\n\t\tbibKind kind = KIND_GHOST_INDEX;;\n\n\t\tif (isType (token, TOKEN_KEYWORD))\n\t\t{\n\t\t\tswitch (token->keyword)\n\t\t\t{\n\t\t\t\tcase KEYWORD_article:\n\t\t\t\t\tkind = BIBTAG_ARTICLE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_book:\n\t\t\t\t\tkind = BIBTAG_BOOK;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_booklet:\n\t\t\t\t\tkind = BIBTAG_BOOKLET;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_conference:\n\t\t\t\t\tkind = BIBTAG_CONFERENCE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_inbook:\n\t\t\t\t\tkind = BIBTAG_INBOOK;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_incollection:\n\t\t\t\t\tkind = BIBTAG_INCOLLECTION;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_inproceedings:\n\t\t\t\t\tkind = BIBTAG_INPROCEEDINGS;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_manual:\n\t\t\t\t\tkind = BIBTAG_MANUAL;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_mastersthesis:\n\t\t\t\t\tkind = BIBTAG_MASTERSTHESIS;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_misc:\n\t\t\t\t\tkind = BIBTAG_MISC;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_phdthesis:\n\t\t\t\t\tkind = BIBTAG_PHDTHESIS;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_proceedings:\n\t\t\t\t\tkind = BIBTAG_PROCEEDINGS;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_string:\n\t\t\t\t\tkind = BIBTAG_STRING;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_techreport:\n\t\t\t\t\tkind = BIBTAG_TECHREPORT;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_unpublished:\n\t\t\t\t\tkind = BIBTAG_UNPUBLISHED;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (kind != KIND_GHOST_INDEX)\n\t\t\teof = parseTag (token, false, kind);\n\t\telse\n\t\t\teof = mayParseTokenInSubparser(token);\n\n\t} while (!eof);\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_bib = language;\n}\n\nstatic void findBibTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\tparseBibFile (token);\n\n\tdeleteToken (token);\n}\n\n/* Create parser definition structure */\nextern parserDefinition* BibtexParser (void)\n{\n\tAssert (ARRAY_SIZE (BibKinds) == BIBTAG_COUNT);\n\tstatic const char *const extensions [] = { \"bib\", NULL };\n\tparserDefinition *const def = parserNew (\"BibTeX\");\n\tdef->extensions = extensions;\n\t/*\n\t * New definitions for parsing instead of regex\n\t */\n\tdef->kindTable\t\t= BibKinds;\n\tdef->kindCount\t\t= ARRAY_SIZE (BibKinds);\n\tdef->parser\t\t\t\t= findBibTags;\n\tdef->initialize\t\t= initialize;\n\tdef->keywordTable\t= BibKeywordTable;\n\tdef->keywordCount\t= ARRAY_SIZE (BibKeywordTable);\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/c-based.c",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C#, D and Java\n*   source files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"        /* must always come first */\n\n#include <string.h>\n#include <setjmp.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"x-cpreprocessor.h\"\n#include \"keyword.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"xtag.h\"\n\n/*\n*   MACROS\n*/\n\n#define activeToken(st)     ((st)->token [(int) (st)->tokenIndex])\n#define parentDecl(st)      ((st)->parent == NULL ? \\\n                            DECL_NONE : (st)->parent->declaration)\n#define isType(token,t)     (bool) ((token)->type == (t))\n#define insideEnumBody(st)  ((st)->parent == NULL ? false : \\\n                            (bool) ((st)->parent->declaration == DECL_ENUM))\n#define insideAnnotationBody(st)  ((st)->parent == NULL ? false : \\\n\t\t\t\t\t\t\t\t  (bool) ((st)->parent->declaration == DECL_ANNOTATION))\n\n#define isOneOf(c,s)        (bool) (strchr ((s), (c)) != NULL)\n\n#define isHighChar(c)       ((c) != EOF && (unsigned int)(c) >= 0xc0 && \\\n\t\t\t\t\t\t\t               (unsigned int)(c) <= 0xff)\n\n/*\n*   DATA DECLARATIONS\n*/\n\nenum { NumTokens = 3 };\n\ntypedef enum eException {\n\tExceptionNone, ExceptionEOF, ExceptionFormattingError,\n\tExceptionBraceFormattingError\n} exception_t;\n\n/*  Used to specify type of keyword.\n */\nenum eKeywordId {\n\tKEYWORD_ALIAS, KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT,\n\tKEYWORD_BOOLEAN, KEYWORD_BYTE,\n\tKEYWORD_CASE, KEYWORD_CATCH, KEYWORD_CHAR, KEYWORD_CLASS, KEYWORD_CONST,\n\tKEYWORD_DEFAULT, KEYWORD_DELEGATE, KEYWORD_DELETE, KEYWORD_DO,\n\tKEYWORD_DOUBLE,\n\tKEYWORD_ELSE, KEYWORD_ENUM, KEYWORD_EXPLICIT, KEYWORD_EXTERN,\n\tKEYWORD_EXTENDS, KEYWORD_EVENT,\n\tKEYWORD_FINAL, KEYWORD_FLOAT, KEYWORD_FOR, KEYWORD_FOREACH,\n\tKEYWORD_FRIEND, KEYWORD_FUNCTION,\n\tKEYWORD_GOTO,\n\tKEYWORD_IF, KEYWORD_IMMUTABLE, KEYWORD_IMPLEMENTS, KEYWORD_IMPORT,\n\tKEYWORD_INLINE, KEYWORD_INT,\n\tKEYWORD_INOUT, KEYWORD_INTERFACE,\n\tKEYWORD_INTERNAL,\n\tKEYWORD_LONG,\n\tKEYWORD_MUTABLE,\n\tKEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NATIVE,\n\tKEYWORD_OPERATOR, KEYWORD_OVERRIDE,\n\tKEYWORD_PACKAGE, KEYWORD_PRIVATE,\n\tKEYWORD_PROTECTED, KEYWORD_PUBLIC,\n\tKEYWORD_REGISTER, KEYWORD_RETURN, KEYWORD_SHARED,\n\tKEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STRING,\n\tKEYWORD_STRUCT, KEYWORD_SWITCH, KEYWORD_SYNCHRONIZED,\n\tKEYWORD_TEMPLATE, KEYWORD_THIS, KEYWORD_THROW,\n\tKEYWORD_THROWS, KEYWORD_TRANSIENT,\n\tKEYWORD_TRY, KEYWORD_TYPEDEF, KEYWORD_TYPENAME,\n\tKEYWORD_UINT, KEYWORD_ULONG, KEYWORD_UNION, KEYWORD_UNSIGNED, KEYWORD_USHORT,\n\tKEYWORD_USING,\n\tKEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE,\n\tKEYWORD_WCHAR_T, KEYWORD_WHILE,\n\tKEYWORD_ALIGN, KEYWORD_ASM, KEYWORD_ASSERT, KEYWORD_AUTO,\n\tKEYWORD_BODY, KEYWORD_BOOL, KEYWORD_BREAK, KEYWORD_CAST,\n\tKEYWORD_CDOUBLE, KEYWORD_CENT, KEYWORD_CFLOAT, KEYWORD_CONTINUE,\n\tKEYWORD_CREAL, KEYWORD_DCHAR, KEYWORD_DEBUG,\n\tKEYWORD_DEPRECATED, KEYWORD_EXPORT, KEYWORD_FALSE, KEYWORD_FINALLY,\n\tKEYWORD_FOREACH_REVERSE, KEYWORD_IDOUBLE, KEYWORD_IFLOAT,\n\tKEYWORD_IN, KEYWORD_INVARIANT, KEYWORD_IREAL, KEYWORD_IS,\n\tKEYWORD_LAZY, KEYWORD_MIXIN, KEYWORD_MODULE, KEYWORD_NULL,\n\tKEYWORD_OUT, KEYWORD_PRAGMA, KEYWORD_REAL, KEYWORD_SCOPE,\n\tKEYWORD_SUPER, KEYWORD_TRUE, KEYWORD_TYPEID, KEYWORD_TYPEOF,\n\tKEYWORD_UBYTE, KEYWORD_UCENT, KEYWORD_UNITTEST, KEYWORD_VERSION,\n\tKEYWORD_WCHAR, KEYWORD_WITH\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\n/*  Used to determine whether keyword is valid for the current language and\n *  what its ID is.\n */\ntypedef struct sKeywordDesc {\n\tconst char *name;\n\tkeywordId id;\n\tshort isValid [6]; /* indicates languages for which kw is valid */\n} keywordDesc;\n\n/*  Used for reporting the type of object parsed by nextToken ().\n */\ntypedef enum eTokenType {\n\tTOKEN_NONE,          /* none */\n\tTOKEN_ARGS,          /* a parenthetical pair and its contents */\n\tTOKEN_BRACE_CLOSE,\n\tTOKEN_BRACE_OPEN,\n\tTOKEN_COLON,         /* the colon character */\n\tTOKEN_COMMA,         /* the comma character */\n\tTOKEN_DOUBLE_COLON,  /* double colon indicates nested-name-specifier */\n\tTOKEN_KEYWORD,\n\tTOKEN_NAME,          /* an unknown name */\n\tTOKEN_PACKAGE,       /* a Java package name */\n\tTOKEN_PAREN_NAME,    /* a single name in parentheses */\n\tTOKEN_SEMICOLON,     /* the semicolon character */\n\tTOKEN_SPEC,          /* a storage class specifier, qualifier, type, etc. */\n\tTOKEN_COUNT\n} tokenType;\n\n/*  This describes the scoping of the current statement.\n */\ntypedef enum eTagScope {\n\tSCOPE_GLOBAL,        /* no storage class specified */\n\tSCOPE_STATIC,        /* static storage class */\n\tSCOPE_EXTERN,        /* external storage class */\n\tSCOPE_FRIEND,        /* declares access only */\n\tSCOPE_TYPEDEF,       /* scoping depends upon context */\n\tSCOPE_COUNT\n} tagScope;\n\ntypedef enum eDeclaration {\n\tDECL_NONE,\n\tDECL_BASE,           /* base type (default) */\n\tDECL_CLASS,\n\tDECL_ENUM,\n\tDECL_EVENT,\n\tDECL_FUNCTION,\n\tDECL_FUNCTION_TEMPLATE, /* D-only */\n\tDECL_IGNORE,         /* non-taggable \"declaration\" */\n\tDECL_INTERFACE,\n\tDECL_MIXIN,\n\tDECL_NAMESPACE,\n\tDECL_PACKAGE,\n\tDECL_PACKAGEREF,\n\tDECL_PRIVATE,\n\tDECL_PROTECTED,\n\tDECL_PUBLIC,\n\tDECL_STRUCT,\n\tDECL_TEMPLATE,       /* D-only */\n\tDECL_UNION,\n\tDECL_USING,\n\tDECL_VERSION,        /* D conditional compile */\n\tDECL_ANNOTATION,     /* Java annotation */\n\tDECL_COUNT\n} declType;\n\ntypedef enum eVisibilityType {\n\tACCESS_UNDEFINED,\n\tACCESS_PRIVATE,\n\tACCESS_PROTECTED,\n\tACCESS_PUBLIC,\n\tACCESS_DEFAULT,      /* Java-specific */\n\tACCESS_COUNT\n} accessType;\n\n/*  Information about the parent class of a member (if any).\n */\ntypedef struct sMemberInfo {\n\taccessType access;           /* access of current statement */\n\taccessType accessDefault;    /* access default for current statement */\n} memberInfo;\n\ntypedef struct sTokenInfo {\n\ttokenType     type;\n\tkeywordId     keyword;\n\tvString*      name;          /* the name of the token */\n\tunsigned long lineNumber;    /* line number of tag */\n\tMIOPos        filePosition;  /* file position of line containing name */\n} tokenInfo;\n\ntypedef enum eImplementation {\n\tIMP_DEFAULT,\n\tIMP_ABSTRACT,\n\tIMP_VIRTUAL,\n\tIMP_PURE_VIRTUAL,\n\tIMP_COUNT\n} impType;\n\n/*  Describes the statement currently undergoing analysis.\n */\ntypedef struct sStatementInfo {\n\ttagScope\tscope;\n\tdeclType\tdeclaration;    /* specifier associated with TOKEN_SPEC */\n\tbool\t\tgotName;        /* was a name parsed yet? */\n\tbool\t\thaveQualifyingName;  /* do we have a name we are considering? */\n\tbool\t\tgotParenName;   /* was a name inside parentheses parsed yet? */\n\tbool\t\tgotArgs;        /* was a list of parameters parsed yet? */\n\tbool\t\tisPointer;      /* is 'name' a pointer? */\n\tbool     inFunction;     /* are we inside of a function? */\n\tbool\t\tassignment;     /* have we handled an '='? */\n\tbool\t\tnotVariable;    /* has a variable declaration been disqualified ? */\n\timpType\t\timplementation; /* abstract or concrete implementation? */\n\tunsigned int tokenIndex;    /* currently active token */\n\ttokenInfo*\ttoken [(int) NumTokens];\n\ttokenInfo*\tcontext;        /* accumulated scope of current statement */\n\ttokenInfo*\tblockName;      /* name of current block */\n\tmemberInfo\tmember;         /* information regarding parent class/struct */\n\tvString*\tparentClasses;  /* parent classes */\n\tstruct sStatementInfo *parent;  /* statement we are nested within */\n} statementInfo;\n\n/*  Describes the type of tag being generated.\n */\ntypedef enum eTagType {\n\tTAG_UNDEFINED,\n\tTAG_CLASS,       /* class name */\n\tTAG_ENUM,        /* enumeration name */\n\tTAG_ENUMERATOR,  /* enumerator (enumeration value) */\n\tTAG_EVENT,       /* event */\n\tTAG_FIELD,       /* field (Java) */\n\tTAG_FUNCTION,    /* function definition */\n\tTAG_INTERFACE,   /* interface declaration */\n\tTAG_LOCAL,       /* local variable definition */\n\tTAG_MEMBER,      /* structure, class or interface member */\n\tTAG_METHOD,      /* method declaration */\n\tTAG_MIXIN, \t\t /* D mixin */\n\tTAG_NAMESPACE,   /* namespace name */\n\tTAG_PACKAGE,     /* package name / D module name */\n\tTAG_PACKAGEREF,\t /* referenced package name */\n\tTAG_PROPERTY,    /* property name */\n\tTAG_PROTOTYPE,   /* function prototype or declaration */\n\tTAG_STRUCT,      /* structure name */\n\tTAG_TYPEDEF,     /* typedef name / D alias name */\n\tTAG_TEMPLATE,    /* D template name */\n\tTAG_UNION,       /* union name */\n\tTAG_VARIABLE,    /* variable definition */\n\tTAG_EXTERN_VAR,  /* external variable declaration */\n\tTAG_VERSION, \t /* conditional template compilation */\n\tTAG_LABEL,\t /* goto label */\n\tTAG_ANNOTATION,  /* Java annotation definition */\n\tTAG_COUNT        /* must be last */\n} tagType;\n\ntypedef struct sParenInfo {\n\tbool isPointer;\n\tbool isParamList;\n\tbool isNameCandidate;\n\tbool invalidContents;\n\tbool nestedArgs;\n\tunsigned int parameterCount;\n} parenInfo;\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic jmp_buf Exception;\n\nstatic langType Lang_csharp;\nstatic langType Lang_d;\nstatic langType Lang_java;\nstatic vString *Signature;\nstatic bool CollectingSignature;\n\n/* Number used to uniquely identify anonymous structs and unions. */\nstatic int AnonymousID = 0;\n\n#define COMMONK_UNDEFINED -1\n\n\ntypedef enum {\n\tCSK_UNDEFINED = COMMONK_UNDEFINED,\n\tCSK_CLASS, CSK_DEFINE, CSK_ENUMERATOR, CSK_EVENT, CSK_FIELD,\n\tCSK_ENUMERATION, CSK_INTERFACE, CSK_LOCAL, CSK_METHOD,\n\tCSK_NAMESPACE, CSK_PROPERTY, CSK_STRUCT, CSK_TYPEDEF\n} csharpKind;\n\nstatic kindDefinition CsharpKinds [] = {\n\t{ true,  'c', \"class\",      \"classes\"},\n\t{ true,  'd', \"macro\",      \"macro definitions\"},\n\t{ true,  'e', \"enumerator\", \"enumerators (values inside an enumeration)\"},\n\t{ true,  'E', \"event\",      \"events\"},\n\t{ true,  'f', \"field\",      \"fields\"},\n\t{ true,  'g', \"enum\",       \"enumeration names\"},\n\t{ true,  'i', \"interface\",  \"interfaces\"},\n\t{ false, 'l', \"local\",      \"local variables\"},\n\t{ true,  'm', \"method\",     \"methods\"},\n\t{ true,  'n', \"namespace\",  \"namespaces\"},\n\t{ true,  'p', \"property\",   \"properties\"},\n\t{ true,  's', \"struct\",     \"structure names\"},\n\t{ true,  't', \"typedef\",    \"typedefs\"},\n};\n\ntypedef enum\n{\n\tDK_UNDEFINED = COMMONK_UNDEFINED,\n\tDK_ALIAS, DK_CLASS, DK_ENUMERATION, DK_ENUMERATOR, DK_EXTERN_VARIABLE, DK_FUNCTION,\n\tDK_INTERFACE, DK_LOCAL, DK_MEMBER, DK_MIXIN, DK_MODULE, DK_NAMESPACE,\n\tDK_PROTOTYPE, DK_STRUCT, DK_TEMPLATE, DK_UNION,\n\tDK_VARIABLE, DK_VERSION\n} dKind;\n\nstatic kindDefinition DKinds [] = {\n\t{ true,  'a', \"alias\",      \"aliases\"},\n\t{ true,  'c', \"class\",      \"classes\"},\n\t{ true,  'g', \"enum\",       \"enumeration names\"},\n\t{ true,  'e', \"enumerator\", \"enumerators (values inside an enumeration)\"},\n\t{ false, 'x', \"externvar\",  \"external variable declarations\"},\n\t{ true,  'f', \"function\",   \"function definitions\"},\n\t{ true,  'i', \"interface\",  \"interfaces\"},\n\t{ false, 'l', \"local\",      \"local variables\"},\n\t{ true,  'm', \"member\",     \"class, struct, and union members\"},\n\t{ true,  'X', \"mixin\",      \"mixins\"},\n\t{ true,  'M', \"module\",     \"modules\"},\n\t{ true,  'n', \"namespace\",  \"namespaces\"},\n\t{ false, 'p', \"prototype\",  \"function prototypes\"},\n\t{ true,  's', \"struct\",     \"structure names\"},\n\t{ true,  'T', \"template\",   \"templates\"},\n\t{ true,  'u', \"union\",      \"union names\"},\n\t{ true,  'v', \"variable\",   \"variable definitions\"},\n\t{ true,  'V', \"version\",    \"version statements\"}\n};\n\n/* Used to index into the JavaKinds table. */\ntypedef enum {\n\tJAVAR_PACKAGE_IMPORTED,\n} javaPackageRole;\n\nstatic roleDefinition JavaPackageRoles [] = {\n\t{ true, \"imported\", \"imported package\"},\n};\n\ntypedef enum {\n\tJK_UNDEFINED = COMMONK_UNDEFINED,\n\tJK_ANNOTATION, JK_CLASS, JK_ENUM_CONSTANT, JK_FIELD, JK_ENUM, JK_INTERFACE,\n\tJK_LOCAL, JK_METHOD, JK_PACKAGE, JK_ACCESS, JK_CLASS_PREFIX\n} javaKind;\n\nstatic kindDefinition JavaKinds [] = {\n\t{ true,  'a', \"annotation\",    \"annotation declarations\" },\n\t{ true,  'c', \"class\",         \"classes\"},\n\t{ true,  'e', \"enumConstant\",  \"enum constants\"},\n\t{ true,  'f', \"field\",         \"fields\"},\n\t{ true,  'g', \"enum\",          \"enum types\"},\n\t{ true,  'i', \"interface\",     \"interfaces\"},\n\t{ false, 'l', \"local\",         \"local variables\"},\n\t{ true,  'm', \"method\",        \"methods\"},\n\t{ true,  'p', \"package\",       \"packages\",\n\t  .referenceOnly = false, ATTACH_ROLES(JavaPackageRoles)},\n};\n\nstatic const keywordDesc KeywordTable [] = {\n     /*                                                 D       */\n     /*                                              C# | Java  */\n     /*                                              |  |   |   */\n     /* keyword           keyword ID                 |  |       */\n     { \"__attribute__\",   KEYWORD_ATTRIBUTE,       { 1, 1, 0 } },\n     { \"abstract\",        KEYWORD_ABSTRACT,        { 1, 1, 1 } },\n     { \"alias\",           KEYWORD_ALIAS,           { 0, 1, 0 } },\n     { \"align\",           KEYWORD_ALIGN,           { 0, 1, 0 } },\n     { \"asm\",             KEYWORD_ASM,             { 0, 1, 0 } },\n     { \"assert\",          KEYWORD_ASSERT,          { 0, 1, 0 } },\n     { \"auto\",            KEYWORD_AUTO,            { 0, 1, 0 } },\n     { \"body\",            KEYWORD_BODY,            { 0, 1, 0 } },\n     { \"bool\",            KEYWORD_BOOL,            { 0, 1, 0 } },\n     { \"boolean\",         KEYWORD_BOOLEAN,         { 0, 0, 1 } },\n     { \"break\",           KEYWORD_BREAK,           { 0, 1, 0 } },\n     { \"byte\",            KEYWORD_BYTE,            { 0, 1, 1 } },\n     { \"case\",            KEYWORD_CASE,            { 1, 1, 1 } },\n     { \"cast\",            KEYWORD_CAST,            { 0, 1, 0 } },\n     { \"catch\",           KEYWORD_CATCH,           { 1, 1, 1 } },\n     { \"cdouble\",         KEYWORD_CDOUBLE,         { 0, 1, 0 } },\n     { \"cent\",            KEYWORD_CENT,            { 0, 1, 0 } },\n     { \"cfloat\",          KEYWORD_CFLOAT,          { 0, 1, 0 } },\n     { \"char\",            KEYWORD_CHAR,            { 1, 1, 1 } },\n     { \"class\",           KEYWORD_CLASS,           { 1, 1, 1 } },\n     { \"const\",           KEYWORD_CONST,           { 1, 1, 1 } },\n     { \"continue\",        KEYWORD_CONTINUE,        { 0, 1, 0 } },\n     { \"creal\",           KEYWORD_CREAL,           { 0, 1, 0 } },\n     { \"dchar\",           KEYWORD_DCHAR,           { 0, 1, 0 } },\n     { \"debug\",           KEYWORD_DEBUG,           { 0, 1, 0 } },\n     { \"default\",         KEYWORD_DEFAULT,         { 1, 1, 1 } },\n     { \"delegate\",        KEYWORD_DELEGATE,        { 1, 1, 0 } },\n     { \"delete\",          KEYWORD_DELETE,          { 0, 1, 0 } },\n     { \"deprecated\",      KEYWORD_DEPRECATED,      { 0, 1, 0 } },\n     { \"do\",              KEYWORD_DO,              { 1, 1, 1 } },\n     { \"double\",          KEYWORD_DOUBLE,          { 1, 1, 1 } },\n     { \"else\",            KEYWORD_ELSE,            { 1, 1, 1 } },\n     { \"enum\",            KEYWORD_ENUM,            { 1, 1, 1 } },\n     { \"event\",           KEYWORD_EVENT,           { 1, 0, 0 } },\n     { \"explicit\",        KEYWORD_EXPLICIT,        { 1, 1, 0 } },\n     { \"export\",          KEYWORD_EXPORT,          { 0, 1, 0 } },\n     { \"extends\",         KEYWORD_EXTENDS,         { 0, 0, 1 } },\n     { \"extern\",          KEYWORD_EXTERN,          { 1, 1, 0 } },\n     { \"false\",           KEYWORD_FALSE,           { 0, 1, 0 } },\n     { \"final\",           KEYWORD_FINAL,           { 0, 1, 1 } },\n     { \"finally\",         KEYWORD_FINALLY,         { 0, 1, 0 } },\n     { \"float\",           KEYWORD_FLOAT,           { 1, 1, 1 } },\n     { \"for\",             KEYWORD_FOR,             { 1, 1, 1 } },\n     { \"foreach\",         KEYWORD_FOREACH,         { 1, 1, 0 } },\n     { \"foreach_reverse\", KEYWORD_FOREACH_REVERSE, { 0, 1, 0 } },\n     { \"friend\",          KEYWORD_FRIEND,          { 0, 1, 0 } },\n     { \"function\",        KEYWORD_FUNCTION,        { 0, 1, 0 } },\n     { \"goto\",            KEYWORD_GOTO,            { 1, 1, 1 } },\n     { \"idouble\",         KEYWORD_IDOUBLE,         { 0, 1, 0 } },\n     { \"if\",              KEYWORD_IF,              { 1, 1, 1 } },\n     { \"ifloat\",          KEYWORD_IFLOAT,          { 0, 1, 0 } },\n     { \"immutable\",       KEYWORD_IMMUTABLE,       { 0, 1, 0 } },\n     { \"implements\",      KEYWORD_IMPLEMENTS,      { 0, 0, 1 } },\n     { \"import\",          KEYWORD_IMPORT,          { 0, 1, 1 } },\n     { \"in\",              KEYWORD_IN,              { 0, 1, 0 } },\n     { \"inline\",          KEYWORD_INLINE,          { 0, 1, 0 } },\n     { \"inout\",           KEYWORD_INOUT,           { 0, 1, 0 } },\n     { \"int\",             KEYWORD_INT,             { 1, 1, 1 } },\n     { \"interface\",       KEYWORD_INTERFACE,       { 1, 1, 1 } },\n     { \"internal\",        KEYWORD_INTERNAL,        { 1, 0, 0 } },\n     { \"invariant\",       KEYWORD_INVARIANT,       { 0, 1, 0 } },\n     { \"ireal\",           KEYWORD_IREAL,           { 0, 1, 0 } },\n     { \"is\",              KEYWORD_IS,              { 0, 1, 0 } },\n     { \"lazy\",            KEYWORD_LAZY,            { 0, 1, 0 } },\n     { \"long\",            KEYWORD_LONG,            { 1, 1, 1 } },\n     { \"mixin\",           KEYWORD_MIXIN,           { 0, 1, 0 } },\n     { \"module\",          KEYWORD_MODULE,          { 0, 1, 0 } },\n     { \"mutable\",         KEYWORD_MUTABLE,         { 0, 1, 0 } },\n     { \"namespace\",       KEYWORD_NAMESPACE,       { 1, 1, 0 } },\n     { \"native\",          KEYWORD_NATIVE,          { 0, 0, 1 } },\n     { \"new\",             KEYWORD_NEW,             { 1, 1, 1 } },\n     { \"null\",            KEYWORD_NULL,            { 0, 1, 0 } },\n     { \"operator\",        KEYWORD_OPERATOR,        { 1, 1, 0 } },\n     { \"out\",             KEYWORD_OUT,             { 0, 1, 0 } },\n     { \"override\",        KEYWORD_OVERRIDE,        { 1, 1, 0 } },\n     { \"package\",         KEYWORD_PACKAGE,         { 0, 1, 1 } },\n     { \"pragma\",          KEYWORD_PRAGMA,          { 0, 1, 0 } },\n     { \"private\",         KEYWORD_PRIVATE,         { 1, 1, 1 } },\n     { \"protected\",       KEYWORD_PROTECTED,       { 1, 1, 1 } },\n     { \"public\",          KEYWORD_PUBLIC,          { 1, 1, 1 } },\n     { \"real\",            KEYWORD_REAL,            { 0, 1, 0 } },\n     { \"register\",        KEYWORD_REGISTER,        { 0, 1, 0 } },\n     { \"return\",          KEYWORD_RETURN,          { 1, 1, 1 } },\n     { \"scope\",           KEYWORD_SCOPE,           { 0, 1, 0 } },\n     { \"shared\",          KEYWORD_SHARED,          { 0, 1, 0 } },\n     { \"short\",           KEYWORD_SHORT,           { 1, 1, 1 } },\n     { \"signed\",          KEYWORD_SIGNED,          { 0, 1, 0 } },\n     { \"static\",          KEYWORD_STATIC,          { 1, 1, 1 } },\n     { \"string\",          KEYWORD_STRING,          { 1, 0, 0 } },\n     { \"struct\",          KEYWORD_STRUCT,          { 1, 1, 0 } },\n     { \"super\",           KEYWORD_SUPER,           { 0, 1, 0 } },\n     { \"switch\",          KEYWORD_SWITCH,          { 1, 1, 1 } },\n     { \"synchronized\",    KEYWORD_SYNCHRONIZED,    { 0, 1, 1 } },\n     { \"template\",        KEYWORD_TEMPLATE,        { 0, 1, 0 } },\n     { \"this\",            KEYWORD_THIS,            { 1, 0, 1 } },\n     { \"throw\",           KEYWORD_THROW,           { 1, 1, 1 } },\n     { \"throws\",          KEYWORD_THROWS,          { 0, 0, 1 } },\n     { \"transient\",       KEYWORD_TRANSIENT,       { 0, 0, 1 } },\n     { \"true\",            KEYWORD_TRUE,            { 0, 1, 0 } },\n     { \"try\",             KEYWORD_TRY,             { 1, 1, 0 } },\n     { \"typedef\",         KEYWORD_TYPEDEF,         { 1, 1, 0 } },\n     { \"typeid\",          KEYWORD_TYPEID,          { 0, 1, 0 } },\n     { \"typename\",        KEYWORD_TYPENAME,        { 0, 1, 0 } },\n     { \"typeof\",          KEYWORD_TYPEOF,          { 0, 1, 0 } },\n     { \"ubyte\",           KEYWORD_UBYTE,           { 0, 1, 0 } },\n     { \"ucent\",           KEYWORD_UCENT,           { 0, 1, 0 } },\n     { \"uint\",            KEYWORD_UINT,            { 1, 1, 0 } },\n     { \"ulong\",           KEYWORD_ULONG,           { 1, 1, 0 } },\n     { \"union\",           KEYWORD_UNION,           { 0, 1, 0 } },\n     { \"unittest\",        KEYWORD_UNITTEST,        { 0, 1, 0 } },\n     { \"unsigned\",        KEYWORD_UNSIGNED,        { 1, 1, 0 } },\n     { \"ushort\",          KEYWORD_USHORT,          { 1, 1, 0 } },\n     { \"using\",           KEYWORD_USING,           { 1, 1, 0 } },\n     { \"version\",         KEYWORD_VERSION,         { 0, 1, 0 } },\n     { \"virtual\",         KEYWORD_VIRTUAL,         { 1, 1, 0 } },\n     { \"void\",            KEYWORD_VOID,            { 1, 1, 1 } },\n     { \"volatile\",        KEYWORD_VOLATILE,        { 1, 1, 1 } },\n     { \"wchar\",           KEYWORD_WCHAR,           { 0, 1, 0 } },\n     { \"wchar_t\",         KEYWORD_WCHAR_T,         { 1, 0, 0 } },\n     { \"while\",           KEYWORD_WHILE,           { 1, 1, 1 } },\n     { \"with\",            KEYWORD_WITH,            { 0, 1, 0 } },\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nstatic void createTags (const unsigned int nestLevel, statementInfo *const parent);\nstatic void parseAtMarkStyleAnnotation (statementInfo *const st);\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n/*\n*   Token management\n*/\n\nstatic void initToken (tokenInfo* const token)\n{\n\ttoken->type\t\t\t= TOKEN_NONE;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->lineNumber\t= getInputLineNumber ();\n\ttoken->filePosition\t= getInputFilePosition ();\n\tvStringClear (token->name);\n}\n\nstatic void advanceToken (statementInfo* const st)\n{\n\tif (st->tokenIndex >= (unsigned int) NumTokens - 1)\n\t\tst->tokenIndex = 0;\n\telse\n\t\t++st->tokenIndex;\n\tinitToken (st->token [st->tokenIndex]);\n}\n\nstatic tokenInfo *prevToken (const statementInfo *const st, unsigned int n)\n{\n\tunsigned int tokenIndex;\n\tunsigned int num = (unsigned int) NumTokens;\n\tAssert (n < num);\n\ttokenIndex = (st->tokenIndex + num - n) % num;\n\treturn st->token [tokenIndex];\n}\n\nstatic void setToken (statementInfo *const st, const tokenType type)\n{\n\ttokenInfo *token;\n\ttoken = activeToken (st);\n\tinitToken (token);\n\ttoken->type = type;\n}\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\ttoken->name = vStringNew ();\n\tinitToken (token);\n\treturn token;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tif (token != NULL)\n\t{\n\t\tvStringDelete (token->name);\n\t\teFree (token);\n\t}\n}\n\nstatic const char *accessString (const accessType access)\n{\n\tstatic const char *const names [] = {\n\t\t\"?\", \"private\", \"protected\", \"public\", \"default\"\n\t};\n\tAssert (ARRAY_SIZE (names) == ACCESS_COUNT);\n\tAssert ((int) access < ACCESS_COUNT);\n\treturn names [(int) access];\n}\n\nstatic const char *implementationString (const impType imp)\n{\n\tstatic const char *const names [] ={\n\t\t\"?\", \"abstract\", \"virtual\", \"pure virtual\"\n\t};\n\tAssert (ARRAY_SIZE (names) == IMP_COUNT);\n\tAssert ((int) imp < IMP_COUNT);\n\treturn names [(int) imp];\n}\n\n/*\n*   Debugging functions\n*/\n\n#ifdef DEBUG\n\n#define boolString(c)   ((c) ? \"true\" : \"false\")\n\nstatic const char *tokenString (const tokenType type)\n{\n\tstatic const char *const names [] = {\n\t\t\"none\", \"args\", \"}\", \"{\", \"colon\", \"comma\", \"double colon\", \"keyword\",\n\t\t\"name\", \"package\", \"paren-name\", \"semicolon\", \"specifier\"\n\t};\n\tAssert (ARRAY_SIZE (names) == TOKEN_COUNT);\n\tAssert ((int) type < TOKEN_COUNT);\n\treturn names [(int) type];\n}\n\nstatic const char *scopeString (const tagScope scope)\n{\n\tstatic const char *const names [] = {\n\t\t\"global\", \"static\", \"extern\", \"friend\", \"typedef\"\n\t};\n\tAssert (ARRAY_SIZE (names) == SCOPE_COUNT);\n\tAssert ((int) scope < SCOPE_COUNT);\n\treturn names [(int) scope];\n}\n\nstatic const char *declString (const declType declaration)\n{\n\tstatic const char *const names [] = {\n\t\t\"?\", \"base\", \"class\", \"enum\", \"event\", \"function\", \"function template\",\n\t\t\"ignore\", \"interface\", \"mixin\", \"namespace\", \"package\", \"package ref\",\n\t\t\"private\", \"protected\", \"public\", \"struct\", \"template\",\n\t\t\"union\", \"using\", \"version\", \"annotation\"\n\t};\n\tAssert (ARRAY_SIZE (names) == DECL_COUNT);\n\tAssert ((int) declaration < DECL_COUNT);\n\treturn names [(int) declaration];\n}\n\nstatic const char *keywordString (const keywordId keyword)\n{\n\tconst size_t count = ARRAY_SIZE (KeywordTable);\n\tconst char *name = \"none\";\n\tsize_t i;\n\tfor (i = 0  ;  i < count  ;  ++i)\n\t{\n\t\tconst keywordDesc *p = &KeywordTable [i];\n\t\tif (p->id == keyword)\n\t\t{\n\t\t\tname = p->name;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn name;\n}\n\nstatic void CTAGS_ATTR_UNUSED pt (tokenInfo *const token)\n{\n\tif (isType (token, TOKEN_NAME))\n\t\tprintf (\"type: %-12s: %-13s   line: %lu\\n\",\n\t\t\ttokenString (token->type), vStringValue (token->name),\n\t\t\ttoken->lineNumber);\n\telse if (isType (token, TOKEN_KEYWORD))\n\t\tprintf (\"type: %-12s: %-13s   line: %lu\\n\",\n\t\t\ttokenString (token->type), keywordString (token->keyword),\n\t\t\ttoken->lineNumber);\n\telse\n\t\tprintf (\"type: %-12s                  line: %lu\\n\",\n\t\t\ttokenString (token->type), token->lineNumber);\n}\n\nstatic void CTAGS_ATTR_UNUSED ps (statementInfo *const st)\n{\n#define P\t\"[%-7u]\"\n\tstatic unsigned int id = 0;\n\tunsigned int i;\n\tprintf (P\"scope: %s   decl: %s   gotName: %s   gotParenName: %s\\n\", id,\n\t\tscopeString (st->scope), declString (st->declaration),\n\t\tboolString (st->gotName), boolString (st->gotParenName));\n\tprintf (P\"haveQualifyingName: %s\\n\", id, boolString (st->haveQualifyingName));\n\tprintf (P\"access: %s   default: %s\\n\", id, accessString (st->member.access),\n\t\taccessString (st->member.accessDefault));\n\tprintf (P\"token  : \", id);\n\tpt (activeToken (st));\n\tfor (i = 1  ;  i < (unsigned int) NumTokens  ;  ++i)\n\t{\n\t\tprintf (P\"prev %u : \", id, i);\n\t\tpt (prevToken (st, i));\n\t}\n\tprintf (P\"context: \", id);\n\tpt (st->context);\n\tid++;\n#undef P\n}\n\n#endif\n\n/*\n*   Statement management\n*/\n\nstatic bool isContextualKeyword (const tokenInfo *const token)\n{\n\tbool result;\n\tswitch (token->keyword)\n\t{\n\t\tcase KEYWORD_CLASS:\n\t\tcase KEYWORD_ENUM:\n\t\tcase KEYWORD_INTERFACE:\n\t\tcase KEYWORD_NAMESPACE:\n\t\tcase KEYWORD_STRUCT:\n\t\tcase KEYWORD_UNION:\n\t\tcase KEYWORD_VERSION:\n\t\tcase KEYWORD_TEMPLATE:\n\t\t\tresult = true;\n\t\t\tbreak;\n\n\t\tdefault: result = false; break;\n\t}\n\treturn result;\n}\n\nstatic bool isContextualStatement (const statementInfo *const st)\n{\n\tbool result = false;\n\tif (st != NULL) switch (st->declaration)\n\t{\n\t\tcase DECL_CLASS:\n\t\tcase DECL_ENUM:\n\t\tcase DECL_INTERFACE:\n\t\tcase DECL_NAMESPACE:\n\t\tcase DECL_PRIVATE:\n\t\tcase DECL_PROTECTED:\n\t\tcase DECL_PUBLIC:\n\t\tcase DECL_STRUCT:\n\t\tcase DECL_UNION:\n\t\tcase DECL_TEMPLATE:\n\t\tcase DECL_ANNOTATION:\n\t\t\tresult = true;\n\t\t\tbreak;\n\n\t\tdefault: result = false; break;\n\t}\n\treturn result;\n}\n\nstatic bool isMember (const statementInfo *const st)\n{\n\tbool result;\n\tif (isType (st->context, TOKEN_NAME))\n\t\tresult = true;\n\telse\n\t\tresult = (bool)\n\t\t\t(st->parent != NULL && isContextualStatement (st->parent));\n\treturn result;\n}\n\nstatic void initMemberInfo (statementInfo *const st)\n{\n\taccessType accessDefault = ACCESS_UNDEFINED;\n\tif (st->parent != NULL) switch (st->parent->declaration)\n\t{\n\t\tcase DECL_PRIVATE:\n\t\t\taccessDefault = ACCESS_PRIVATE;\n\t\t\tbreak;\n\t\tcase DECL_PROTECTED:\n\t\t\taccessDefault = ACCESS_PROTECTED;\n\t\t\tbreak;\n\t\tcase DECL_PUBLIC:\n\t\t\taccessDefault = ACCESS_PUBLIC;\n\t\t\tbreak;\n\t\tcase DECL_ENUM:\n\t\t\taccessDefault = (isInputLanguage (Lang_java) ? ACCESS_PUBLIC : ACCESS_UNDEFINED);\n\t\t\tbreak;\n\t\tcase DECL_NAMESPACE:\n\t\t\taccessDefault = ACCESS_UNDEFINED;\n\t\t\tbreak;\n\n\t\tcase DECL_CLASS:\n\t\t\tif (isInputLanguage (Lang_java))\n\t\t\t\taccessDefault = ACCESS_DEFAULT;\n\t\t\telse if (isInputLanguage (Lang_d))\n\t\t\t\taccessDefault = ACCESS_PUBLIC;\n\t\t\telse\n\t\t\t\taccessDefault = ACCESS_PRIVATE;\n\t\t\tbreak;\n\n\t\tcase DECL_INTERFACE:\n\t\tcase DECL_STRUCT:\n\t\tcase DECL_UNION:\n\t\tcase DECL_ANNOTATION:\n\t\t\taccessDefault = ACCESS_PUBLIC;\n\t\t\tbreak;\n\n\t\tdefault: break;\n\t}\n\tst->member.accessDefault = accessDefault;\n\tst->member.access\t\t = accessDefault;\n}\n\nstatic void reinitStatement (statementInfo *const st, const bool partial)\n{\n\tunsigned int i;\n\n\tif (! partial)\n\t{\n\t\tst->scope = SCOPE_GLOBAL;\n\t\tif (isContextualStatement (st->parent))\n\t\t\tst->declaration = DECL_BASE;\n\t\telse\n\t\t\tst->declaration = DECL_NONE;\n\t}\n\tst->gotParenName\t= false;\n\tst->isPointer\t\t= false;\n\tst->inFunction\t\t= false;\n\tst->assignment\t\t= false;\n\tst->notVariable\t\t= false;\n\tst->implementation\t= IMP_DEFAULT;\n\tst->gotArgs\t\t\t= false;\n\tst->gotName\t\t\t= false;\n\tst->haveQualifyingName = false;\n\tst->tokenIndex\t\t= 0;\n\n\tif (st->parent != NULL)\n\t\tst->inFunction = st->parent->inFunction;\n\n\tfor (i = 0  ;  i < (unsigned int) NumTokens  ;  ++i)\n\t\tinitToken (st->token [i]);\n\n\tinitToken (st->context);\n\n\t/*\tKeep the block name, so that a variable following after a comma will\n\t *\tstill have the structure name.\n\t */\n\tif (! partial)\n\t\tinitToken (st->blockName);\n\n\tvStringClear (st->parentClasses);\n\n\t/*  Init member info.\n\t */\n\tif (! partial)\n\t\tst->member.access = st->member.accessDefault;\n}\n\nstatic void initStatement (statementInfo *const st, statementInfo *const parent)\n{\n\tst->parent = parent;\n\tinitMemberInfo (st);\n\treinitStatement (st, false);\n}\n\n/*\n*   Tag generation functions\n*/\n#define csharpTagKind(type) csharpTagKindFull(type, true)\n#define csharpTagKindNoAssert(type) csharpTagKindFull(type, false)\nstatic csharpKind csharpTagKindFull (const tagType type, const bool with_assert)\n{\n\tcsharpKind result = CSK_UNDEFINED;\n\tswitch (type)\n\t{\n\t\tcase TAG_CLASS:      result = CSK_CLASS;           break;\n\t\tcase TAG_ENUM:       result = CSK_ENUMERATION;     break;\n\t\tcase TAG_ENUMERATOR: result = CSK_ENUMERATOR;      break;\n\t\tcase TAG_EVENT:      result = CSK_EVENT;           break;\n\t\tcase TAG_FIELD:      result = CSK_FIELD ;          break;\n\t\tcase TAG_INTERFACE:  result = CSK_INTERFACE;       break;\n\t\tcase TAG_LOCAL:      result = CSK_LOCAL;           break;\n\t\tcase TAG_METHOD:     result = CSK_METHOD;          break;\n\t\tcase TAG_NAMESPACE:  result = CSK_NAMESPACE;       break;\n\t\tcase TAG_PROPERTY:   result = CSK_PROPERTY;        break;\n\t\tcase TAG_STRUCT:     result = CSK_STRUCT;          break;\n\t\tcase TAG_TYPEDEF:    result = CSK_TYPEDEF;         break;\n\n\t\tdefault: if (with_assert) Assert (\"Bad C# tag type\" == NULL); break;\n\t}\n\treturn result;\n}\n\n#define javaTagKind(type) javaTagKindFull(type, true)\n#define javaTagKindNoAssert(type) javaTagKindFull(type, false)\nstatic javaKind javaTagKindFull (const tagType type, bool with_assert)\n{\n\tjavaKind result = JK_UNDEFINED;\n\tswitch (type)\n\t{\n\t\tcase TAG_CLASS:      result = JK_CLASS;         break;\n\t\tcase TAG_ENUM:       result = JK_ENUM;          break;\n\t\tcase TAG_ENUMERATOR: result = JK_ENUM_CONSTANT; break;\n\t\tcase TAG_FIELD:      result = JK_FIELD;         break;\n\t\tcase TAG_INTERFACE:  result = JK_INTERFACE;     break;\n\t\tcase TAG_LOCAL:      result = JK_LOCAL;         break;\n\t\tcase TAG_METHOD:     result = JK_METHOD;        break;\n\t\tcase TAG_PACKAGE:    /* Fall through */\n\t\tcase TAG_PACKAGEREF: result = JK_PACKAGE;       break;\n\t\tcase TAG_ANNOTATION: result = JK_ANNOTATION;     break;\n\n\t\tdefault: if (with_assert) Assert (\"Bad Java tag type\" == NULL); break;\n\t}\n\treturn result;\n}\n\n#define dTagKind(type) dTagKindFull(type, true)\n#define dTagKindNoAssert(type) dTagKindFull(type, false)\nstatic dKind dTagKindFull (const tagType type, bool with_assert)\n{\n\tdKind result = DK_UNDEFINED;\n\tswitch (type)\n\t{\n\t\tcase TAG_TYPEDEF:    result = DK_ALIAS;           break;\n\t\tcase TAG_CLASS:      result = DK_CLASS;           break;\n\t\tcase TAG_ENUM:       result = DK_ENUMERATION;     break;\n\t\tcase TAG_ENUMERATOR: result = DK_ENUMERATOR;      break;\n\t\tcase TAG_EXTERN_VAR: result = DK_EXTERN_VARIABLE; break;\n\t\tcase TAG_FUNCTION:   result = DK_FUNCTION;        break;\n\t\tcase TAG_INTERFACE:  result = DK_INTERFACE;       break;\n\t\tcase TAG_LOCAL:      result = DK_LOCAL;           break;\n\t\tcase TAG_MEMBER:     result = DK_MEMBER;          break;\n\t\tcase TAG_MIXIN:      result = DK_MIXIN;           break;\n\t\tcase TAG_PACKAGE:    result = DK_MODULE;          break;\n\t\tcase TAG_NAMESPACE:  result = DK_NAMESPACE;       break;\n\t\tcase TAG_PROTOTYPE:  result = DK_PROTOTYPE;       break;\n\t\tcase TAG_STRUCT:     result = DK_STRUCT;          break;\n\t\tcase TAG_TEMPLATE:   result = DK_TEMPLATE;        break;\n\t\tcase TAG_UNION:      result = DK_UNION;           break;\n\t\tcase TAG_VARIABLE:   result = DK_VARIABLE;        break;\n\t\tcase TAG_VERSION:    result = DK_VERSION;         break;\n\n\t\tdefault: if (with_assert) Assert (\"Bad D tag type\" == NULL); break;\n\t}\n\treturn result;\n}\n\nstatic int kindIndexForType (const tagType type)\n{\n\tint result = 0;\n\tif (isInputLanguage (Lang_csharp))\n\t\tresult = csharpTagKind (type);\n\telse if (isInputLanguage (Lang_java))\n\t\tresult = javaTagKind (type);\n\telse if (isInputLanguage (Lang_d))\n\t\tresult = dTagKind (type);\n\treturn result;\n}\n\nstatic int roleForType (const tagType type)\n{\n\tint result;\n\n\tresult = ROLE_DEFINITION_INDEX;\n\tif (isInputLanguage (Lang_java))\n\t{\n\t\tif (type == TAG_PACKAGEREF)\n\t\t\tresult = JAVAR_PACKAGE_IMPORTED;\n\t}\n\n\treturn result;\n}\n\nstatic const char *tagName (const tagType type)\n{\n\tconst char* result = NULL;\n\tif (isInputLanguage (Lang_csharp))\n\t\tresult = CsharpKinds [csharpTagKind (type)].name;\n\telse if (isInputLanguage (Lang_java))\n\t\tresult = JavaKinds [javaTagKind (type)].name;\n\telse if (isInputLanguage (Lang_d))\n\t\tresult = DKinds [dTagKind (type)].name;\n\treturn result;\n}\n\nstatic bool includeTag (const tagType type, const bool isFileScope)\n{\n\tbool result;\n\tint k = COMMONK_UNDEFINED;\n\n\tif (isFileScope && !isXtagEnabled(XTAG_FILE_SCOPE))\n\t\treturn false;\n\telse if (isInputLanguage (Lang_csharp))\n\t\tk = csharpTagKindNoAssert (type);\n\telse if (isInputLanguage (Lang_java))\n\t\tk = javaTagKindNoAssert (type);\n\telse if (isInputLanguage (Lang_d))\n\t\tk = dTagKindNoAssert (type);\n\n\tif (k == COMMONK_UNDEFINED)\n\t\tresult = false;\n\telse\n\t\tresult = isInputLanguageKindEnabled (k);\n\n\treturn result;\n}\n\nstatic tagType declToTagType (const declType declaration)\n{\n\ttagType type = TAG_UNDEFINED;\n\n\tswitch (declaration)\n\t{\n\t\tcase DECL_CLASS:        type = TAG_CLASS;       break;\n\t\tcase DECL_ENUM:         type = TAG_ENUM;        break;\n\t\tcase DECL_EVENT:        type = TAG_EVENT;       break;\n\t\tcase DECL_FUNCTION:     type = TAG_FUNCTION;    break;\n\t\tcase DECL_FUNCTION_TEMPLATE: type = TAG_FUNCTION; break;\n\t\tcase DECL_INTERFACE:    type = TAG_INTERFACE;   break;\n\t\tcase DECL_NAMESPACE:    type = TAG_NAMESPACE;   break;\n\t\tcase DECL_PRIVATE:      type = TAG_CLASS;       break;\n\t\tcase DECL_PROTECTED:    type = TAG_CLASS;       break;\n\t\tcase DECL_PUBLIC:       type = TAG_CLASS;       break;\n\t\tcase DECL_TEMPLATE: \ttype = TAG_TEMPLATE; \tbreak;\n\t\tcase DECL_STRUCT:       type = TAG_STRUCT;      break;\n\t\tcase DECL_UNION:        type = TAG_UNION;       break;\n\t\tcase DECL_VERSION: \t\ttype = TAG_VERSION; \tbreak;\n\t\tcase DECL_ANNOTATION:   type = TAG_ANNOTATION;  break;\n\n\t\tdefault: Assert (\"Unexpected declaration\" == NULL); break;\n\t}\n\treturn type;\n}\n\nstatic const char* accessField (const statementInfo *const st)\n{\n\tconst char* result = NULL;\n\tif (st->member.access != ACCESS_UNDEFINED)\n\t\tresult = accessString (st->member.access);\n\treturn result;\n}\n\nstatic void addContextSeparator (vString *const scope)\n{\n\tvStringPut (scope, '.');\n}\n\nstatic void addOtherFields (tagEntryInfo* const tag, const tagType type,\n\t\t\t\t\t\t\tconst statementInfo *const st,\n\t\t\t\t\t\t\tvString *const scope, vString *const typeRef)\n{\n\t/*  For selected tag types, append an extension flag designating the\n\t *  parent object in which the tag is defined.\n\t */\n\tswitch (type)\n\t{\n\t\tdefault: break;\n\n\t\tcase TAG_FUNCTION:\n\t\tcase TAG_TEMPLATE:\n\t\tcase TAG_METHOD:\n\t\tcase TAG_PROTOTYPE:\n\t\t\tif (vStringLength (Signature) > 0)\n\t\t\t\ttag->extensionFields.signature = vStringValue (Signature);\n\t\tcase TAG_CLASS:\n\t\tcase TAG_ENUM:\n\t\tcase TAG_ENUMERATOR:\n\t\tcase TAG_EVENT:\n\t\tcase TAG_FIELD:\n\t\tcase TAG_INTERFACE:\n\t\tcase TAG_MEMBER:\n\t\tcase TAG_NAMESPACE:\n\t\tcase TAG_PROPERTY:\n\t\tcase TAG_STRUCT:\n\t\tcase TAG_TYPEDEF:\n\t\tcase TAG_UNION:\n\t\tcase TAG_ANNOTATION:\n\t\t\tif (vStringLength (scope) > 0  &&\n\t\t\t\t(isMember (st) || st->parent->declaration == DECL_NAMESPACE))\n\t\t\t{\n\t\t\t\ttagType ptype;\n\n\t\t\t\tif (isType (st->context, TOKEN_NAME))\n\t\t\t\t{\n\t\t\t\t\ttag->extensionFields.scopeKindIndex = kindIndexForType (TAG_CLASS);\n\t\t\t\t\ttag->extensionFields.scopeName = vStringValue (scope);\n\t\t\t\t}\n\t\t\t\telse if ((ptype = declToTagType (parentDecl (st))) &&\n\t\t\t\t\t includeTag (ptype, isXtagEnabled(XTAG_FILE_SCOPE)))\n\t\t\t\t{\n\t\t\t\t\ttag->extensionFields.scopeKindIndex = kindIndexForType (ptype);\n\t\t\t\t\ttag->extensionFields.scopeName = vStringValue (scope);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ((type == TAG_CLASS  ||  type == TAG_INTERFACE  ||\n\t\t\t\t type == TAG_STRUCT || type == TAG_ANNOTATION) && vStringLength (st->parentClasses) > 0)\n\t\t\t{\n\n\t\t\t\ttag->extensionFields.inheritance =\n\t\t\t\t\t\tvStringValue (st->parentClasses);\n\t\t\t}\n\t\t\tif (st->implementation != IMP_DEFAULT)\n\t\t\t{\n\t\t\t\ttag->extensionFields.implementation =\n\t\t\t\t\t\timplementationString (st->implementation);\n\t\t\t}\n\t\t\tif (isMember (st))\n\t\t\t{\n\t\t\t\ttag->extensionFields.access = accessField (st);\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\t/* Add typename info, type of the tag and name of struct/union/etc. */\n\tif ((type == TAG_TYPEDEF || type == TAG_VARIABLE || type == TAG_MEMBER)\n\t\t\t&& isContextualStatement(st))\n\t{\n\t\tchar *p;\n\n\t\ttag->extensionFields.typeRef [0] =\n\t\t\t\t\t\ttagName (declToTagType (st->declaration));\n\t\tp = vStringValue (st->blockName->name);\n\n\t\t/*  If there was no {} block get the name from the token before the\n\t\t *  name (current token is ';' or ',', previous token is the name).\n\t\t */\n\t\tif (p == NULL || *p == '\\0')\n\t\t{\n\t\t\ttokenInfo *const prev2 = prevToken (st, 2);\n\t\t\tif (isType (prev2, TOKEN_NAME))\n\t\t\t\tp = vStringValue (prev2->name);\n\t\t}\n\n\t\t/* Prepend the scope name if there is one. */\n\t\tif (vStringLength (scope) > 0)\n\t\t{\n\t\t\tvStringCopy(typeRef, scope);\n\t\t\taddContextSeparator (typeRef);\n\t\t\tvStringCatS(typeRef, p);\n\t\t\tp = vStringValue (typeRef);\n\t\t}\n\t\ttag->extensionFields.typeRef [1] = p;\n\t}\n}\n\nstatic bool findScopeHierarchy (vString *const string, const statementInfo *const st)\n{\n\tbool found = false;\n\n\tvStringClear (string);\n\n\tif (isType (st->context, TOKEN_NAME))\n\t{\n\t\tvStringCopy (string, st->context->name);\n\t\tfound = true;\n\t}\n\n\tif (st->parent != NULL)\n\t{\n\t\tvString *temp = vStringNew ();\n\t\tconst statementInfo *s;\n\t\tfor (s = st->parent  ;  s != NULL  ;  s = s->parent)\n\t\t{\n\t\t\tif (isContextualStatement (s) ||\n\t\t\t\ts->declaration == DECL_NAMESPACE)\n\t\t\t{\n\t\t\t\tif (s->declaration == DECL_PRIVATE ||\n\t\t\t\t\ts->declaration == DECL_PROTECTED ||\n\t\t\t\t\ts->declaration == DECL_PUBLIC)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfound = true;\n\t\t\t\tvStringCopy (temp, string);\n\t\t\t\tvStringClear (string);\n\t\t\t\tif (isType (s->blockName, TOKEN_NAME))\n\t\t\t\t{\n\t\t\t\t\tif (isType (s->context, TOKEN_NAME) &&\n\t\t\t\t\t    vStringLength (s->context->name) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringCat (string, s->context->name);\n\t\t\t\t\t\taddContextSeparator (string);\n\t\t\t\t\t}\n\t\t\t\t\tvStringCat (string, s->blockName->name);\n\t\t\t\t\tif (vStringLength (temp) > 0)\n\t\t\t\t\t\taddContextSeparator (string);\n\t\t\t\t\tvStringCat (string, temp);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* Information for building scope string\n\t\t\t\t\t   is lacking. Maybe input is broken. */\n\t\t\t\t\tfound = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvStringDelete (temp);\n\t}\n\treturn found;\n}\n\nstatic void makeExtraTagEntry (const tagType type, tagEntryInfo *const e,\n\t\t\t\t\t\t\t   vString *const scope)\n{\n\tif (isXtagEnabled(XTAG_QUALIFIED_TAGS)  &&\n\t\tscope != NULL  &&  vStringLength (scope) > 0)\n\t{\n\t\tvString *const scopedName = vStringNew ();\n\n\t\tif (type != TAG_ENUMERATOR)\n\t\t\tvStringCopy (scopedName, scope);\n\t\telse\n\t\t{\n\t\t\t/* remove last component (i.e. enumeration name) from scope */\n\t\t\tconst char* const sc = vStringValue (scope);\n\t\t\tconst char* colon = strrchr (sc, ':');\n\t\t\tif (colon != NULL)\n\t\t\t{\n\t\t\t\twhile (*colon == ':'  &&  colon > sc)\n\t\t\t\t\t--colon;\n\t\t\t\tvStringNCopy (scopedName, scope, colon + 1 - sc);\n\t\t\t}\n\t\t}\n\t\tif (vStringLength (scopedName) > 0)\n\t\t{\n\t\t\taddContextSeparator (scopedName);\n\t\t\tvStringCatS (scopedName, e->name);\n\t\t\te->name = vStringValue (scopedName);\n\t\t\tmarkTagExtraBit (e, XTAG_QUALIFIED_TAGS);\n\t\t\tmakeTagEntry (e);\n\t\t}\n\t\tvStringDelete (scopedName);\n\t}\n}\n\nstatic int makeTag (const tokenInfo *const token,\n\t\t\t\t\t const statementInfo *const st,\n\t\t\t\t\t bool isFileScope, const tagType type)\n{\n\tint corkIndex = CORK_NIL;\n\t/*  Nothing is really of file scope when it appears in a header file.\n\t */\n\tisFileScope = (bool) (isFileScope && ! isInputHeaderFile ());\n\n\tif (isType (token, TOKEN_NAME)  &&  vStringLength (token->name) > 0  &&\n\t\tincludeTag (type, isFileScope))\n\t{\n\t\tvString *scope;\n\t\tvString *typeRef;\n\t\tbool isScopeBuilt;\n\t\t/* Use \"typeRef\" to store the typename from addOtherFields() until\n\t\t * it's used in makeTagEntry().\n\t\t */\n\t\ttagEntryInfo e;\n\t\tint kind;\n\t\tint role;\n\n\t\trole = roleForType (type);\n\t\tif (! (role == ROLE_DEFINITION_INDEX || isXtagEnabled (XTAG_REFERENCE_TAGS)))\n\t\t\treturn CORK_NIL;\n\n\t\tscope  = vStringNew ();\n\t\ttypeRef = vStringNew ();\n\n\t\tkind  = kindIndexForType(type);\n\t\tif (role == ROLE_DEFINITION_INDEX)\n\t\t\tinitTagEntry (&e, vStringValue (token->name), kind);\n\t\telse\n\t\t\tinitRefTagEntry (&e, vStringValue (token->name), kind, role);\n\n\t\tupdateTagLine (&e, token->lineNumber,  token->filePosition);\n\t\te.isFileScope\t= isFileScope;\n\t\tif (e.isFileScope)\n\t\t\tmarkTagExtraBit (&e, XTAG_FILE_SCOPE);\n\n\t\tisScopeBuilt = findScopeHierarchy (scope, st);\n\t\taddOtherFields (&e, type, st, scope, typeRef);\n\n\t\tcorkIndex = makeTagEntry (&e);\n\t\tif (isScopeBuilt)\n\t\t\tmakeExtraTagEntry (type, &e, scope);\n\t\tvStringDelete (scope);\n\t\tvStringDelete (typeRef);\n\t}\n\treturn corkIndex;\n}\n\nstatic bool isValidTypeSpecifier (const declType declaration)\n{\n\tbool result;\n\tswitch (declaration)\n\t{\n\t\tcase DECL_BASE:\n\t\tcase DECL_CLASS:\n\t\tcase DECL_ENUM:\n\t\tcase DECL_EVENT:\n\t\tcase DECL_STRUCT:\n\t\tcase DECL_UNION:\n\t\tcase DECL_ANNOTATION:\n\t\t\tresult = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tresult = false;\n\t\t\tbreak;\n\t}\n\treturn result;\n}\n\nstatic int qualifyEnumeratorTag (const statementInfo *const st,\n\t\t\t\t\t\t\t\t const tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\tif (isType (nameToken, TOKEN_NAME))\n\t\tcorkIndex = makeTag (nameToken, st, true, TAG_ENUMERATOR);\n\treturn corkIndex;\n}\n\nstatic int qualifyFunctionTag (const statementInfo *const st,\n\t\t\t\t\t\t\t\tconst tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\tif (isType (nameToken, TOKEN_NAME))\n\t{\n\t\ttagType type;\n\t\tconst bool isFileScope =\n\t\t\t\t\t\t(bool) (st->member.access == ACCESS_PRIVATE ||\n\t\t\t\t\t\t(!isMember (st)  &&  st->scope == SCOPE_STATIC));\n\t\tif (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp))\n\t\t\ttype = TAG_METHOD;\n\t\telse\n\t\t\ttype = TAG_FUNCTION;\n\t\tcorkIndex = makeTag (nameToken, st, isFileScope, type);\n\t}\n\treturn corkIndex;\n}\n\nstatic int qualifyFunctionDeclTag (const statementInfo *const st,\n\t\t\t\t\t\t\t\t\tconst tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\tif (! isType (nameToken, TOKEN_NAME))\n\t\t;\n\telse if (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp))\n\t\tcorkIndex = qualifyFunctionTag (st, nameToken);\n\telse if (st->scope == SCOPE_TYPEDEF)\n\t\tcorkIndex = makeTag (nameToken, st, true, TAG_TYPEDEF);\n\telse if (isValidTypeSpecifier (st->declaration) && ! isInputLanguage (Lang_csharp))\n\t\tcorkIndex = makeTag (nameToken, st, true, TAG_PROTOTYPE);\n\treturn corkIndex;\n}\n\nstatic int qualifyCompoundTag (const statementInfo *const st,\n\t\t\t\t\t\t\t\tconst tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\tif (isType (nameToken, TOKEN_NAME))\n\t{\n\t\tconst tagType type = declToTagType (st->declaration);\n\t\tconst bool fileScoped = (bool)\n\t\t\t\t(!(isInputLanguage (Lang_java) ||\n\t\t\t\t   isInputLanguage (Lang_csharp)));\n\n\t\tif (type != TAG_UNDEFINED)\n\t\t\tcorkIndex = makeTag (nameToken, st, fileScoped, type);\n\t}\n\treturn corkIndex;\n}\n\nstatic int qualifyBlockTag (statementInfo *const st,\n\t\t\t\t\t\t\t const tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\tswitch (st->declaration)\n\t{\n\n\t\tcase DECL_CLASS:\n\t\tcase DECL_ENUM:\n\t\tcase DECL_INTERFACE:\n\t\tcase DECL_NAMESPACE:\n\t\tcase DECL_STRUCT:\n\t\tcase DECL_UNION:\n\t\tcase DECL_TEMPLATE:\n\t\tcase DECL_VERSION:\n\t\tcase DECL_ANNOTATION:\n\t\t\tcorkIndex = qualifyCompoundTag (st, nameToken);\n\t\t\tbreak;\n\t\tdefault: break;\n\t}\n\treturn corkIndex;\n}\n\nstatic int qualifyVariableTag (const statementInfo *const st,\n\t\t\t\t\t\t\t\tconst tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\t/*\tWe have to watch that we do not interpret a declaration of the\n\t *\tform \"struct tag;\" as a variable definition. In such a case, the\n\t *\ttoken preceding the name will be a keyword.\n\t */\n\tif (! isType (nameToken, TOKEN_NAME))\n\t\t;\n\telse if (st->scope == SCOPE_TYPEDEF)\n\t\tcorkIndex = makeTag (nameToken, st, true, TAG_TYPEDEF);\n\telse if (st->declaration == DECL_EVENT)\n\t\tcorkIndex = makeTag (nameToken, st, (bool) (st->member.access == ACCESS_PRIVATE),\n\t\t\t\t\t\t\t TAG_EVENT);\n\telse if (st->declaration == DECL_PACKAGE)\n\t\tcorkIndex = makeTag (nameToken, st, false, TAG_PACKAGE);\n\telse if (st->declaration == DECL_PACKAGEREF)\n\t\tcorkIndex = makeTag (nameToken, st, false, TAG_PACKAGEREF);\n\telse if (st->declaration == DECL_USING && st->assignment)\n\t\tcorkIndex = makeTag (nameToken, st, true, TAG_TYPEDEF);\n\telse if (isValidTypeSpecifier (st->declaration))\n\t{\n\t\tif (st->notVariable)\n\t\t\t;\n\t\telse if (isMember (st))\n\t\t{\n\t\t\tif (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp))\n\t\t\t\tcorkIndex = makeTag (nameToken, st,\n\t\t\t\t\t\t\t\t\t (bool) (st->member.access == ACCESS_PRIVATE), TAG_FIELD);\n\t\t\telse if (st->scope == SCOPE_GLOBAL  ||  st->scope == SCOPE_STATIC)\n\t\t\t\tcorkIndex = makeTag (nameToken, st, true, TAG_MEMBER);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (st->scope == SCOPE_EXTERN  ||  ! st->haveQualifyingName)\n\t\t\t\tcorkIndex = makeTag (nameToken, st, false, TAG_EXTERN_VAR);\n\t\t\telse if (st->inFunction)\n\t\t\t\tcorkIndex = makeTag (nameToken, st, (bool) (st->scope == SCOPE_STATIC),\n\t\t\t\t\t\t\t\t\t TAG_LOCAL);\n\t\t\telse\n\t\t\t\tcorkIndex = makeTag (nameToken, st, (bool) (st->scope == SCOPE_STATIC),\n\t\t\t\t\t\t\t\t\t TAG_VARIABLE);\n\t\t}\n\t}\n\treturn corkIndex;\n}\n\n/*\n*   Parsing functions\n*/\n\nstatic int skipToOneOf (const char *const chars)\n{\n\tint c;\n\tdo\n\t\tc = cppGetc ();\n\twhile (c != EOF  &&  c != '\\0'  &&  strchr (chars, c) == NULL);\n\treturn c;\n}\n\n/*  Skip to the next non-white character.\n */\nstatic int skipToNonWhite (void)\n{\n\tbool found = false;\n\tint c;\n\n#if 0\n\tdo\n\t\tc = cppGetc ();\n\twhile (cppIsspace (c));\n#else\n\twhile (1)\n\t{\n\t\tc = cppGetc ();\n\t\tif (cppIsspace (c))\n\t\t\tfound = true;\n\t\telse\n\t\t\tbreak;\n\t}\n\tif (CollectingSignature && found)\n\t\tvStringPut (Signature, ' ');\n#endif\n\n\treturn c;\n}\n\n/*  Skips to the next brace in column 1. This is intended for cases where\n *  preprocessor constructs result in unbalanced braces.\n */\nstatic void skipToFormattedBraceMatch (void)\n{\n\tint c, next;\n\n\tc = cppGetc ();\n\tnext = cppGetc ();\n\twhile (c != EOF  &&  (c != '\\n'  ||  next != '}'))\n\t{\n\t\tc = next;\n\t\tnext = cppGetc ();\n\t}\n}\n\n/*  Skip to the matching character indicated by the pair string. If skipping\n *  to a matching brace and any brace is found within a different level of a\n *  #if conditional statement while brace formatting is in effect, we skip to\n *  the brace matched by its formatting. It is assumed that we have already\n *  read the character which starts the group (i.e. the first character of\n *  \"pair\").\n */\nstatic void skipToMatch (const char *const pair)\n{\n\tconst bool braceMatching = (bool) (strcmp (\"{}\", pair) == 0);\n\tconst bool braceFormatting = (bool) (cppIsBraceFormat () && braceMatching);\n\tconst unsigned int initialLevel = cppGetDirectiveNestLevel ();\n\tconst int begin = pair [0], end = pair [1];\n\tconst unsigned long inputLineNumber = getInputLineNumber ();\n\tint matchLevel = 1;\n\tint c = '\\0';\n\n\twhile (matchLevel > 0  &&  (c = skipToNonWhite ()) != EOF)\n\t{\n\t\tif (CollectingSignature)\n\t\t\tcppVStringPut (Signature, c);\n\n\t\tif (c == begin)\n\t\t{\n\t\t\t++matchLevel;\n\t\t\tif (braceFormatting  &&  cppGetDirectiveNestLevel () != initialLevel)\n\t\t\t{\n\t\t\t\tskipToFormattedBraceMatch ();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if (c == end)\n\t\t{\n\t\t\t--matchLevel;\n\t\t\tif (braceFormatting  &&  cppGetDirectiveNestLevel () != initialLevel)\n\t\t\t{\n\t\t\t\tskipToFormattedBraceMatch ();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif (c == EOF)\n\t{\n\t\tverbose (\"%s: failed to find match for '%c' at line %lu\\n\",\n\t\t\t\tgetInputFileName (), begin, inputLineNumber);\n\t\tif (braceMatching)\n\t\t\tlongjmp (Exception, (int) ExceptionBraceFormattingError);\n\t\telse\n\t\t\tlongjmp (Exception, (int) ExceptionFormattingError);\n\t}\n}\n\nstatic void skipParens (void)\n{\n\tconst int c = skipToNonWhite ();\n\n\tif (c == '(')\n\t\tskipToMatch (\"()\");\n\telse\n\t\tcppUngetc (c);\n}\n\nstatic void skipBraces (void)\n{\n\tconst int c = skipToNonWhite ();\n\n\tif (c == '{')\n\t\tskipToMatch (\"{}\");\n\telse\n\t\tcppUngetc (c);\n}\n\nstatic keywordId analyzeKeyword (const char *const name)\n{\n\tconst keywordId id = (keywordId) lookupKeyword (name, getInputLanguage ());\n\treturn id;\n}\n\nstatic void analyzeIdentifier (tokenInfo *const token)\n{\n\tconst char * name = vStringValue (token->name);\n\n\tif(!name)\n\t{\n\t\tinitToken(token);\n\t\treturn;\n\t}\n\n\ttoken->keyword = analyzeKeyword (name);\n\n\tif (token->keyword == KEYWORD_NONE)\n\t\ttoken->type = TOKEN_NAME;\n\telse\n\t\ttoken->type = TOKEN_KEYWORD;\n}\n\nstatic void readIdentifier (tokenInfo *const token, const int firstChar)\n{\n\tvString *const name = token->name;\n\tint c = firstChar;\n\tbool first = true;\n\n\tinitToken (token);\n\n\tdo\n\t{\n\t\tcppVStringPut (name, c);\n\t\tif (CollectingSignature)\n\t\t{\n\t\t\tif (!first)\n\t\t\t\tcppVStringPut (Signature, c);\n\t\t\tfirst = false;\n\t\t}\n\t\tc = cppGetc ();\n\t} while (cppIsident (c) || ((isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp)) && (isHighChar (c) || c == '.')));\n\tcppUngetc (c);        /* unget non-identifier character */\n\n\tanalyzeIdentifier (token);\n}\n\nstatic void readPackageName (tokenInfo *const token, const int firstChar, bool allowWildCard)\n{\n\tvString *const name = token->name;\n\tint c = firstChar;\n\n\tinitToken (token);\n\n\twhile (cppIsident (c)  || (allowWildCard && (c == '*')) ||  c == '.')\n\t{\n\t\tvStringPut (name, c);\n\t\tc = cppGetc ();\n\t}\n\tcppUngetc (c);        /* unget non-package character */\n}\n\nstatic void readPackageOrNamespace (statementInfo *const st, const declType declaration, bool allowWildCard)\n{\n\tst->declaration = declaration;\n\n\tif (declaration == DECL_NAMESPACE && !isInputLanguage (Lang_csharp))\n\t{\n\t\t/* Namespace is specified one level at a time. */\n\t\treturn;\n\t}\n\telse\n\t{\n\t\t/* In C#, a namespace can also be specified like a Java package name. */\n\t\ttokenInfo *const token = activeToken (st);\n\t\tAssert (isType (token, TOKEN_KEYWORD));\n\t\treadPackageName (token, skipToNonWhite (), allowWildCard);\n\t\ttoken->type = TOKEN_NAME;\n\t\tst->gotName = true;\n\t\tst->haveQualifyingName = true;\n\t}\n}\n\nstatic void readVersionName (tokenInfo *const token, const int firstChar)\n{\n\tvString *const name = token->name;\n\tint c = firstChar;\n\n\tinitToken (token);\n\n\twhile (cppIsident (c))\n\t{\n\t\tvStringPut (name, c);\n\t\tc = cppGetc ();\n\t}\n    cppGetc ();\n}\n\nstatic void readVersion (statementInfo *const st)\n{\n    tokenInfo *const token = activeToken (st);\n\tAssert (isType (token, TOKEN_KEYWORD));\n    skipToNonWhite ();\n\treadVersionName (token, cppGetc ());\n\ttoken->type = TOKEN_NAME;\n\tst->declaration = DECL_VERSION;\n\tst->gotName = true;\n\tst->haveQualifyingName = true;\n}\n\nstatic void processName (statementInfo *const st)\n{\n\tAssert (isType (activeToken (st), TOKEN_NAME));\n\tif (st->gotName  &&  st->declaration == DECL_NONE)\n\t\tst->declaration = DECL_BASE;\n\tst->gotName = true;\n\tst->haveQualifyingName = true;\n}\n\nstatic void readOperator (statementInfo *const st)\n{\n\tconst char *const acceptable = \"+-*/%^&|~!=<>,[]\";\n\tconst tokenInfo* const prev = prevToken (st,1);\n\ttokenInfo *const token = activeToken (st);\n\tvString *const name = token->name;\n\tint c = skipToNonWhite ();\n\n\t/*  When we arrive here, we have the keyword \"operator\" in 'name'.\n\t */\n\tif (isType (prev, TOKEN_KEYWORD) && (prev->keyword == KEYWORD_ENUM ||\n\t\t prev->keyword == KEYWORD_STRUCT || prev->keyword == KEYWORD_UNION))\n\t\t;        /* ignore \"operator\" keyword if preceded by these keywords */\n\telse if (c == '(')\n\t{\n\t\t/*  Verify whether this is a valid function call (i.e. \"()\") operator.\n\t\t */\n\t\tif (cppGetc () == ')')\n\t\t{\n\t\t\tvStringPut (name, ' ');  /* always separate operator from keyword */\n\t\t\tc = skipToNonWhite ();\n\t\t\tif (c == '(')\n\t\t\t\tvStringCatS (name, \"()\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tskipToMatch (\"()\");\n\t\t\tc = cppGetc ();\n\t\t}\n\t}\n\telse if (cppIsident1 (c))\n\t{\n\t\t/*  Handle \"new\" and \"delete\" operators, and conversion functions\n\t\t *  (per 13.3.1.1.2 [2] of the C++ spec).\n\t\t */\n\t\tbool whiteSpace = true;  /* default causes insertion of space */\n\t\tdo\n\t\t{\n\t\t\tif (cppIsspace (c))\n\t\t\t\twhiteSpace = true;\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (whiteSpace)\n\t\t\t\t{\n\t\t\t\t\tvStringPut (name, ' ');\n\t\t\t\t\twhiteSpace = false;\n\t\t\t\t}\n\t\t\t\tcppVStringPut (name, c);\n\t\t\t}\n\t\t\tc = cppGetc ();\n\t\t} while (! isOneOf (c, \"(;\")  &&  c != EOF);\n\t}\n\telse if (isOneOf (c, acceptable))\n\t{\n\t\tvStringPut (name, ' ');  /* always separate operator from keyword */\n\t\tdo\n\t\t{\n\t\t\tvStringPut (name, c);\t/* acceptable are all ascii */\n\t\t\tc = cppGetc ();\n\t\t} while (isOneOf (c, acceptable));\n\t}\n\n\tcppUngetc (c);\n\n\ttoken->type\t= TOKEN_NAME;\n\ttoken->keyword = KEYWORD_NONE;\n\tprocessName (st);\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const src)\n{\n\tdest->type         = src->type;\n\tdest->keyword      = src->keyword;\n\tdest->filePosition = src->filePosition;\n\tdest->lineNumber   = src->lineNumber;\n\tvStringCopy (dest->name, src->name);\n}\n\nstatic void setAccess (statementInfo *const st, const accessType access)\n{\n\tif (isInputLanguage (Lang_d))\n\t{\n\t\tint c = skipToNonWhite ();\n\n\t\tif (c == '{')\n\t\t{\n\t\t\tswitch(access)\n\t\t\t{\n\t\t\t\tcase ACCESS_PRIVATE:\n\t\t\t\t\tst->declaration = DECL_PRIVATE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ACCESS_PUBLIC:\n\t\t\t\t\tst->declaration = DECL_PUBLIC;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ACCESS_PROTECTED:\n\t\t\t\t\tst->declaration = DECL_PROTECTED;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tst->member.access = access;\n\t\t\tcppUngetc (c);\n\t\t}\n\t\telse if (c == ':')\n\t\t{\n\t\t\treinitStatement (st, false);\n\t\t\tst->member.accessDefault = access;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcppUngetc (c);\n\t\t}\n\t}\n\n\tif (isMember (st))\n\t{\n\t\tif (isInputLanguage (Lang_d))\n\t\t{\n\t\t\tif (st->parent != NULL &&\n\t\t\t\t(st->parent->declaration == DECL_PRIVATE ||\n\t\t\t\tst->parent->declaration == DECL_PROTECTED ||\n\t\t\t\tst->parent->declaration == DECL_PUBLIC))\n\t\t\t{\n\t\t\t\tst->member.access = st->parent->member.access;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tst->member.access = access;\n\t}\n}\n\nstatic void discardTypeList (tokenInfo *const token)\n{\n\tint c = skipToNonWhite ();\n\twhile (cppIsident1 (c))\n\t{\n\t\treadIdentifier (token, c);\n\t\tc = skipToNonWhite ();\n\t\tif (c == '.'  ||  c == ',')\n\t\t\tc = skipToNonWhite ();\n\t}\n\tcppUngetc (c);\n}\n\nstatic void addParentClass (statementInfo *const st, tokenInfo *const token)\n{\n\tif (vStringLength (token->name) > 0  &&\n\t\tvStringLength (st->parentClasses) > 0)\n\t{\n\t\tvStringPut (st->parentClasses, ',');\n\t}\n\tvStringCat (st->parentClasses, token->name);\n}\n\nstatic void readParents (statementInfo *const st, const int qualifier)\n{\n\ttokenInfo *const token = newToken ();\n\ttokenInfo *const parent = newToken ();\n\tint c;\n\n\tdo\n\t{\n\t\tc = skipToNonWhite ();\n\t\tif (cppIsident1 (c))\n\t\t{\n\t\t\treadIdentifier (token, c);\n\t\t\tif (isType (token, TOKEN_NAME))\n\t\t\t\tvStringCat (parent->name, token->name);\n\t\t\telse\n\t\t\t{\n\t\t\t\taddParentClass (st, parent);\n\t\t\t\tinitToken (parent);\n\t\t\t}\n\t\t}\n\t\telse if (c == qualifier)\n\t\t\tvStringPut (parent->name, c);\n\t\telse if (c == '<')\n\t\t\tskipToMatch (\"<>\");\n\t\telse if (isType (token, TOKEN_NAME))\n\t\t{\n\t\t\taddParentClass (st, parent);\n\t\t\tinitToken (parent);\n\t\t}\n\t} while (c != '{'  &&  c != EOF);\n\tcppUngetc (c);\n\tdeleteToken (parent);\n\tdeleteToken (token);\n}\n\nstatic void skipStatement (statementInfo *const st)\n{\n\tst->declaration = DECL_IGNORE;\n\tskipToOneOf (\";\");\n}\n\nstatic void processAnnotation (statementInfo *const st)\n{\n\tst->declaration = DECL_ANNOTATION;\n}\n\nstatic void processInterface (statementInfo *const st)\n{\n\tst->declaration = DECL_INTERFACE;\n}\n\nstatic void checkIsClassEnum (statementInfo *const st, const declType decl)\n{\n\tst->declaration = decl;\n}\n\nstatic void processToken (tokenInfo *const token, statementInfo *const st)\n{\n\tswitch ((int)token->keyword)        /* is it a reserved word? */\n\t{\n\t\tdefault: break;\n\n\t\tcase KEYWORD_NONE:      processName (st);                       break;\n\t\tcase KEYWORD_ABSTRACT:  st->implementation = IMP_ABSTRACT;      break;\n\t\tcase KEYWORD_ATTRIBUTE: skipParens (); initToken (token);       break;\n\t\tcase KEYWORD_CATCH:     skipParens (); skipBraces ();           break;\n\t\tcase KEYWORD_CHAR:      st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_CLASS:     checkIsClassEnum (st, DECL_CLASS);      break;\n\t\tcase KEYWORD_IMMUTABLE:\n\t\tcase KEYWORD_INOUT:\n\t\tcase KEYWORD_SHARED:\n\t\t\tif (!isInputLanguage (Lang_d))\n\t\t\t\tbreak;\n\t\tcase KEYWORD_CONST:\n\t\t\tst->declaration = DECL_BASE;\n\t\t\tif (isInputLanguage (Lang_d))\n\t\t\t\tskipParens ();\n\t\t\tbreak;\n\t\tcase KEYWORD_DOUBLE:    st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_ENUM:      st->declaration = DECL_ENUM;            break;\n\t\tcase KEYWORD_EXTENDS:   readParents (st, '.');\n\t\t                        setToken (st, TOKEN_NONE);              break;\n\t\tcase KEYWORD_FLOAT:     st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_FUNCTION:  st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_FRIEND:    st->scope       = SCOPE_FRIEND;         break;\n\t\tcase KEYWORD_GOTO:      skipStatement (st);                     break;\n\t\tcase KEYWORD_IMPLEMENTS:readParents (st, '.');\n\t\t                        setToken (st, TOKEN_NONE);              break;\n\t\tcase KEYWORD_IMPORT:\n\t\t\tif (isInputLanguage (Lang_java))\n\t\t\t\treadPackageOrNamespace (st, DECL_PACKAGEREF, true);\n\t\t\telse\n\t\t\t\tskipStatement (st);\n\t\t\tbreak;\n\t\tcase KEYWORD_INT:       st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_INTERFACE: processInterface (st);                  break;\n\t\tcase KEYWORD_LONG:      st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_OPERATOR:  readOperator (st);                      break;\n\t\tcase KEYWORD_MIXIN:     st->declaration = DECL_MIXIN;           break;\n\t\tcase KEYWORD_PRIVATE:   setAccess (st, ACCESS_PRIVATE);         break;\n\t\tcase KEYWORD_PROTECTED: setAccess (st, ACCESS_PROTECTED);       break;\n\t\tcase KEYWORD_PUBLIC:    setAccess (st, ACCESS_PUBLIC);          break;\n\t\tcase KEYWORD_RETURN:    skipStatement (st);                     break;\n\t\tcase KEYWORD_SHORT:     st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_SIGNED:    st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_STRING:    st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_STRUCT:    checkIsClassEnum (st, DECL_STRUCT);     break;\n\t\tcase KEYWORD_THROWS:    discardTypeList (token);                break;\n\t\tcase KEYWORD_UNION:     st->declaration = DECL_UNION;           break;\n\t\tcase KEYWORD_UNSIGNED:  st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_USING:     st->declaration = DECL_USING;           break;\n\t\tcase KEYWORD_VOID:      st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_VOLATILE:  st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_VERSION:   readVersion(st);                        break;\n\t\tcase KEYWORD_VIRTUAL:   st->implementation = IMP_VIRTUAL;       break;\n\t\tcase KEYWORD_WCHAR_T:   st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_TEMPLATE:\n\t\t\tif (isInputLanguage (Lang_d))\n\t\t\t\tst->declaration = DECL_TEMPLATE;\n\t\t\tbreak;\n\t\tcase KEYWORD_NAMESPACE: readPackageOrNamespace (st, DECL_NAMESPACE, false); break;\n\t\tcase KEYWORD_MODULE:\n\t\tcase KEYWORD_PACKAGE:   readPackageOrNamespace (st, DECL_PACKAGE, false);   break;\n\n\t\tcase KEYWORD_EVENT:\n\t\t\tif (isInputLanguage (Lang_csharp))\n\t\t\t\tst->declaration = DECL_EVENT;\n\t\t\tbreak;\n\n\t\tcase KEYWORD_ALIAS:\n\t\tcase KEYWORD_TYPEDEF:\n\t\t\treinitStatement (st, false);\n\t\t\tst->scope = SCOPE_TYPEDEF;\n\t\t\tbreak;\n\n\t\tcase KEYWORD_EXTERN:\n\t\t\tif (! isInputLanguage (Lang_csharp) || !st->gotName)\n\t\t\t{\n\t\t\t\treinitStatement (st, false);\n\t\t\t\tst->scope = SCOPE_EXTERN;\n\t\t\t\tst->declaration = DECL_BASE;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase KEYWORD_STATIC:\n\t\t\tif (! (isInputLanguage (Lang_java) || isInputLanguage (Lang_csharp)))\n\t\t\t{\n\t\t\t\treinitStatement (st, false);\n\t\t\t\tst->scope = SCOPE_STATIC;\n\t\t\t\tst->declaration = DECL_BASE;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase KEYWORD_FOR:\n\t\tcase KEYWORD_FOREACH:\n\t\tcase KEYWORD_IF:\n\t\tcase KEYWORD_SWITCH:\n\t\tcase KEYWORD_WHILE:\n\t\t{\n\t\t\tint c = skipToNonWhite ();\n\t\t\tif (c == '(')\n\t\t\t\tskipToMatch (\"()\");\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/*\n*   Parenthesis handling functions\n*/\n\nstatic void restartStatement (statementInfo *const st)\n{\n\ttokenInfo *const save = newToken ();\n\ttokenInfo *token = activeToken (st);\n\n\tcopyToken (save, token);\n\tDebugStatement ( if (debug (DEBUG_PARSE)) printf (\"<ES>\");)\n\treinitStatement (st, false);\n\ttoken = activeToken (st);\n\tcopyToken (token, save);\n\tdeleteToken (save);\n\tprocessToken (token, st);\n}\n\n/*  Skips over a mem-initializer-list of a ctor-initializer, defined as:\n *\n *  mem-initializer-list:\n *    mem-initializer, mem-initializer-list\n *\n *  mem-initializer:\n *    [::] [nested-name-spec] class-name (...)\n *    identifier\n */\nstatic void skipMemIntializerList (tokenInfo *const token)\n{\n\tint c;\n\n\tdo\n\t{\n\t\tc = skipToNonWhite ();\n\t\twhile (cppIsident1 (c)  ||  c == ':')\n\t\t{\n\t\t\tif (c != ':')\n\t\t\t\treadIdentifier (token, c);\n\t\t\tc = skipToNonWhite ();\n\t\t}\n\t\tif (c == '<')\n\t\t{\n\t\t\tskipToMatch (\"<>\");\n\t\t\tc = skipToNonWhite ();\n\t\t}\n\t\tif (c == '(')\n\t\t{\n\t\t\tskipToMatch (\"()\");\n\t\t\tc = skipToNonWhite ();\n\t\t}\n\t} while (c == ',');\n\tcppUngetc (c);\n}\n\n/*  Skips over characters following the parameter list.\n *  Originally written for C++, may contain unnecessary stuff.\n *\n *  C#:\n *    public C(double x) : base(x) {}\n */\nstatic bool skipPostArgumentStuff (\n\t\tstatementInfo *const st, parenInfo *const info)\n{\n\ttokenInfo *const token = activeToken (st);\n\tunsigned int parameters = info->parameterCount;\n\tunsigned int elementCount = 0;\n\tbool restart = false;\n\tbool end = false;\n\tint c = skipToNonWhite ();\n\n\tdo\n\t{\n\t\tswitch (c)\n\t\t{\n\t\tcase ')':                               break;\n\t\tcase ':': skipMemIntializerList (token);break;  /* ctor-initializer */\n\t\tcase '[': skipToMatch (\"[]\");           break;\n\t\tcase '=': cppUngetc (c); end = true;    break;\n\t\tcase '{': cppUngetc (c); end = true;    break;\n\t\tcase '}': cppUngetc (c); end = true;    break;\n\n\t\tcase '(':\n\t\t\tif (elementCount > 0)\n\t\t\t\t++elementCount;\n\t\t\tskipToMatch (\"()\");\n\t\t\tbreak;\n\n\t\tcase ';':\n\t\t\tif (parameters == 0  ||  elementCount < 2)\n\t\t\t{\n\t\t\t\tcppUngetc (c);\n\t\t\t\tend = true;\n\t\t\t}\n\t\t\telse if (--parameters == 0)\n\t\t\t\tend = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tif (cppIsident1 (c))\n\t\t\t{\n\t\t\t\treadIdentifier (token, c);\n\t\t\t\tswitch (token->keyword)\n\t\t\t\t{\n\t\t\t\tcase KEYWORD_ATTRIBUTE: skipParens ();  break;\n\t\t\t\tcase KEYWORD_THROW:     skipParens ();  break;\n\t\t\t\tcase KEYWORD_IF: // D template constraint\n\t\t\t\t// D contract expressions\n\t\t\t\tcase KEYWORD_IN:\n\t\t\t\tcase KEYWORD_OUT:\n\t\t\t\t\tif (isInputLanguage (Lang_d))\n\t\t\t\t\t\tskipParens ();\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_TRY:                       break;\n\n\t\t\t\tcase KEYWORD_CONST:\n\t\t\t\tcase KEYWORD_IMMUTABLE:\n\t\t\t\tcase KEYWORD_INOUT:\n\t\t\t\tcase KEYWORD_SHARED:\n\t\t\t\tcase KEYWORD_VOLATILE:\n\t\t\t\t\tif (vStringLength (Signature) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (Signature, ' ');\n\t\t\t\t\t\tvStringCat (Signature, token->name);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_ALIAS:\n\t\t\t\tcase KEYWORD_CATCH:\n\t\t\t\tcase KEYWORD_CLASS:\n\t\t\t\tcase KEYWORD_EXPLICIT:\n\t\t\t\tcase KEYWORD_EXTERN:\n\t\t\t\tcase KEYWORD_FRIEND:\n\t\t\t\tcase KEYWORD_INLINE:\n\t\t\t\tcase KEYWORD_MUTABLE:\n\t\t\t\tcase KEYWORD_NAMESPACE:\n\t\t\t\tcase KEYWORD_NEW:\n\t\t\t\tcase KEYWORD_OPERATOR:\n\t\t\t\tcase KEYWORD_OVERRIDE:\n\t\t\t\tcase KEYWORD_PRIVATE:\n\t\t\t\tcase KEYWORD_PROTECTED:\n\t\t\t\tcase KEYWORD_PUBLIC:\n\t\t\t\tcase KEYWORD_STATIC:\n\t\t\t\tcase KEYWORD_TEMPLATE:\n\t\t\t\tcase KEYWORD_TYPEDEF:\n\t\t\t\tcase KEYWORD_TYPENAME:\n\t\t\t\tcase KEYWORD_USING:\n\t\t\t\tcase KEYWORD_VIRTUAL:\n\t\t\t\t\t/* Never allowed within parameter declarations. */\n\t\t\t\t\trestart = true;\n\t\t\t\t\tend = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tif (isType (token, TOKEN_NONE))\n\t\t\t\t\t\t;\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t/*  If we encounter any other identifier immediately\n\t\t\t\t\t\t *  following an empty parameter list, this is almost\n\t\t\t\t\t\t *  certainly one of those Microsoft macro \"thingies\"\n\t\t\t\t\t\t *  that the automatic source code generation sticks\n\t\t\t\t\t\t *  in. Terminate the current statement.\n\t\t\t\t\t\t */\n\t\t\t\t\t\trestart = true;\n\t\t\t\t\t\tend = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (isInputLanguage (Lang_d) && c == '@')\n\t\t\t{\n\t\t\t\tparseAtMarkStyleAnnotation (st);\n\t\t\t}\n\t\t}\n\t\tif (! end)\n\t\t{\n\t\t\tc = skipToNonWhite ();\n\t\t\tif (c == EOF)\n\t\t\t\tend = true;\n\t\t}\n\t} while (! end);\n\n\tif (restart)\n\t\trestartStatement (st);\n\telse\n\t\tsetToken (st, TOKEN_NONE);\n\n\treturn (bool) (c != EOF);\n}\n\nstatic void skipJavaThrows (statementInfo *const st)\n{\n\ttokenInfo *const token = activeToken (st);\n\tint c = skipToNonWhite ();\n\n\tif (cppIsident1 (c))\n\t{\n\t\treadIdentifier (token, c);\n\t\tif (token->keyword == KEYWORD_THROWS)\n\t\t{\n\t\t\tdo\n\t\t\t{\n\t\t\t\tc = skipToNonWhite ();\n\t\t\t\tif (cppIsident1 (c))\n\t\t\t\t{\n\t\t\t\t\treadIdentifier (token, c);\n\t\t\t\t\tc = skipToNonWhite ();\n\t\t\t\t}\n\t\t\t} while (c == '.'  ||  c == ',');\n\t\t}\n\t}\n\tcppUngetc (c);\n\tsetToken (st, TOKEN_NONE);\n}\n\nstatic void analyzePostParens (statementInfo *const st, parenInfo *const info)\n{\n\tconst unsigned long inputLineNumber = getInputLineNumber ();\n\tint c = skipToNonWhite ();\n\n\tcppUngetc (c);\n\tif (isOneOf (c, \"{;,=\"))\n\t\t;\n\telse if (isInputLanguage (Lang_java))\n\t{\n\t\tif (!insideAnnotationBody(st))\n\t\t{\n\t\t\tskipJavaThrows (st);\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (! skipPostArgumentStuff (st, info))\n\t\t{\n\t\t\tverbose (\n\t\t\t\t\"%s: confusing argument declarations beginning at line %lu\\n\",\n\t\t\t\tgetInputFileName (), inputLineNumber);\n\t\t\tlongjmp (Exception, (int) ExceptionFormattingError);\n\t\t}\n\t}\n}\n\nstatic bool languageSupportsGenerics (void)\n{\n\treturn (bool) (isInputLanguage (Lang_csharp) || isInputLanguage (Lang_java));\n}\n\nstatic void processAngleBracket (void)\n{\n\tint c = cppGetc ();\n\tif (c == '>')\n\t{\n\t\t/* already found match for template */\n\t}\n\telse if (languageSupportsGenerics () && c != '<' && c != '=')\n\t{\n\t\t/* this is a template */\n\t\tcppUngetc (c);\n\t\tskipToMatch (\"<>\");\n\t}\n\telse if (c == '<')\n\t{\n\t\t/* skip \"<<\" or \"<<=\". */\n\t\tc = cppGetc ();\n\t\tif (c != '=')\n\t\t{\n\t\t\tcppUngetc (c);\n\t\t}\n\t}\n\telse\n\t{\n\t\tcppUngetc (c);\n\t}\n}\n\nstatic void parseAtMarkStyleAnnotation (statementInfo *const st)\n{\n\t/*\n\t * @Override\n\t * @Target(ElementType.METHOD)\n\t * @SuppressWarnings(value = \"unchecked\")\n\t *\n\t * But watch out for \"@interface\"!\n\t */\n\ttokenInfo *const token = activeToken (st);\n\n\tint c = skipToNonWhite ();\n\tif (cppIsident1 (c))\n\t\treadIdentifier (token, c);\n\telse\n\t\tcppUngetc (c); // D allows: @ ( ArgumentList )\n\n\tif (token->keyword == KEYWORD_INTERFACE)\n\t{\n\t\t/* Oops. This was actually \"@interface\" defining a new annotation. */\n\t\tprocessAnnotation(st);\n\t}\n\telse\n\t{\n\t\t/* Bug #1691412: skip any annotation arguments. */\n\t\tskipParens ();\n\t}\n}\n\nstatic int parseParens (statementInfo *const st, parenInfo *const info)\n{\n\ttokenInfo *const token = activeToken (st);\n\tunsigned int depth = 1;\n\tbool firstChar = true;\n\tint nextChar = '\\0';\n\n\tCollectingSignature = true;\n\tvStringClear (Signature);\n\tvStringPut (Signature, '(');\n\tinfo->parameterCount = 1;\n\tdo\n\t{\n\t\tint c = skipToNonWhite ();\n\n\t\tcppVStringPut (Signature, c);\n\t\tswitch (c)\n\t\t{\n\t\t\tcase '^':\n\t\t\t\tbreak;\n\n\t\t\tcase '&':\n\t\t\tcase '*':\n\t\t\t\tinfo->isPointer = true;\n\t\t\t\tinitToken (token);\n\t\t\t\tbreak;\n\n\t\t\tcase ':':\n\t\t\t\tbreak;\n\n\t\t\tcase '.':\n\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\tc = cppGetc ();\n\t\t\t\tif (c != '.')\n\t\t\t\t\tcppUngetc (c);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tc = cppGetc ();\n\t\t\t\t\tif (c != '.')\n\t\t\t\t\t\tcppUngetc (c);\n\t\t\t\t\telse\n\t\t\t\t\t\tvStringCatS (Signature, \"...\"); /* variable arg list */\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase ',':\n\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\tbreak;\n\n\t\t\tcase '=':\n\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\tif (firstChar)\n\t\t\t\t{\n\t\t\t\t\tinfo->isParamList = false;\n\t\t\t\t\tdepth = 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase '[':\n\t\t\t\tskipToMatch (\"[]\");\n\t\t\t\tbreak;\n\n\t\t\tcase '<':\n\t\t\t\tprocessAngleBracket ();\n\t\t\t\tbreak;\n\n\t\t\tcase ')':\n\t\t\t\tif (firstChar)\n\t\t\t\t\tinfo->parameterCount = 0;\n\t\t\t\t--depth;\n\t\t\t\tbreak;\n\n\t\t\tcase '(':\n\t\t\t\tif (firstChar)\n\t\t\t\t{\n\t\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\t\tcppUngetc (c);\n\t\t\t\t\tvStringClear (Signature);\n\t\t\t\t\tdepth = 0;\n\t\t\t\t\tvStringChop (Signature);\n\t\t\t\t}\n\t\t\t\telse if (isType (token, TOKEN_PAREN_NAME))\n\t\t\t\t{\n\t\t\t\t\tc = skipToNonWhite ();\n\t\t\t\t\tif (c == '*')        /* check for function pointer */\n\t\t\t\t\t{\n\t\t\t\t\t\tskipToMatch (\"()\");\n\t\t\t\t\t\tc = skipToNonWhite ();\n\t\t\t\t\t\tif (c == '(')\n\t\t\t\t\t\t\tskipToMatch (\"()\");\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tcppUngetc (c);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcppUngetc (c);\n\t\t\t\t\t\tcppUngetc ('(');\n\t\t\t\t\t\tinfo->nestedArgs = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\t++depth;\n\t\t\t\tbreak;\n\n\t\t\tcase '?':\n\t\t\t\tif (isInputLanguage (Lang_csharp))\n\t\t\t\t{\n\t\t\t\t\t/* C# uses '?' at the end of type name for\n\t\t\t\t\t * representing nullable parameter. */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t/* FALLTHROUGH */\n\t\t\tdefault:\n\t\t\t\tif (c == '@' && (isInputLanguage (Lang_d) || isInputLanguage (Lang_java)))\n\t\t\t\t{\n\t\t\t\t\tparseAtMarkStyleAnnotation (st);\n\t\t\t\t}\n\t\t\t\telse if (isInputLanguage (Lang_d) && c == '!')\n\t\t\t\t{\t/* template instantiation */\n\t\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\t}\n\t\t\t\telse if (cppIsident1 (c))\n\t\t\t\t{\n\t\t\t\t\treadIdentifier (token, c);\n\t\t\t\t\tif (isType (token, TOKEN_NAME)  &&  info->isNameCandidate)\n\t\t\t\t\t\ttoken->type = TOKEN_PAREN_NAME;\n\t\t\t\t\telse if (isType (token, TOKEN_KEYWORD))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (token->keyword != KEYWORD_CONST &&\n\t\t\t\t\t\t\ttoken->keyword != KEYWORD_IMMUTABLE &&\n\t\t\t\t\t\t\ttoken->keyword != KEYWORD_INOUT &&\n\t\t\t\t\t\t\ttoken->keyword != KEYWORD_SHARED &&\n\t\t\t\t\t\t\ttoken->keyword != KEYWORD_VOLATILE)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tinfo->isParamList     = false;\n\t\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\t\tinfo->invalidContents = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\tfirstChar = false;\n\t} while (! info->nestedArgs  &&  depth > 0  &&  info->isNameCandidate);\n\n\tif (! info->nestedArgs) while (depth > 0)\n\t{\n\t\tskipToMatch (\"()\");\n\t\t--depth;\n\t}\n\n\tif (! info->isNameCandidate)\n\t\tinitToken (token);\n\n\tCollectingSignature = false;\n\treturn nextChar;\n}\n\nstatic void initParenInfo (parenInfo *const info)\n{\n\tinfo->isPointer\t\t\t\t= false;\n\tinfo->isParamList\t\t\t= true;\n\tinfo->isNameCandidate\t\t= true;\n\tinfo->invalidContents\t\t= false;\n\tinfo->nestedArgs\t\t\t= false;\n\tinfo->parameterCount\t\t= 0;\n}\n\nstatic void analyzeParens (statementInfo *const st)\n{\n\ttokenInfo *const prev = prevToken (st, 1);\n\n\tif (st->inFunction && !st->assignment)\n\t\tst->notVariable = true;\n\n\tif (! isType (prev, TOKEN_NONE))  /* in case of ignored enclosing macros */\n\t{\n\t\ttokenInfo *const token = activeToken (st);\n\t\tparenInfo info;\n\t\tint c;\n\n\t\tinitParenInfo (&info);\n\t\tparseParens (st, &info);\n\t\tc = skipToNonWhite ();\n\t\tcppUngetc (c);\n\t\tif (info.invalidContents)\n\t\t{\n\t\t\t/* FIXME: This breaks parsing of variable instantiations that have\n\t\t\t   constants as parameters: Type var(0) or Type var(\"...\"). */\n\t\t\treinitStatement (st, false);\n\t\t}\n\t\telse if (info.isNameCandidate  &&  isType (token, TOKEN_PAREN_NAME)  &&\n\t\t\t\t ! st->gotParenName  &&\n\t\t\t\t (! info.isParamList || ! st->haveQualifyingName  ||\n\t\t\t\t  c == '('  ||\n\t\t\t\t  (c == '='  &&  st->implementation != IMP_VIRTUAL) ||\n\t\t\t\t  (st->declaration == DECL_NONE  &&  isOneOf (c, \",;\"))))\n\t\t{\n\t\t\ttoken->type = TOKEN_NAME;\n\t\t\tprocessName (st);\n\t\t\tst->gotParenName = true;\n\t\t\tif (! (c == '('  &&  info.nestedArgs))\n\t\t\t\tst->isPointer = info.isPointer;\n\t\t\tif (isInputLanguage(Lang_d) && c == '(' && isType (prev, TOKEN_NAME))\n\t\t\t{\n\t\t\t\tst->declaration = DECL_FUNCTION_TEMPLATE;\n\t\t\t\tcopyToken (st->blockName, prev);\n\t\t\t}\n\t\t}\n\t\telse if (! st->gotArgs  &&  info.isParamList)\n\t\t{\n\t\t\tst->gotArgs = true;\n\t\t\tsetToken (st, TOKEN_ARGS);\n\t\t\tadvanceToken (st);\n\t\t\tif (st->scope != SCOPE_TYPEDEF)\n\t\t\t\tanalyzePostParens (st, &info);\n\t\t}\n\t\telse\n\t\t\tsetToken (st, TOKEN_NONE);\n\t}\n}\n\n/*\n*   Token parsing functions\n*/\n\nstatic void addContext (statementInfo *const st, const tokenInfo* const token)\n{\n\tif (isType (token, TOKEN_NAME))\n\t{\n\t\tvStringJoin (st->context->name, '.', token->name);\n\t\tst->context->type = TOKEN_NAME;\n\t}\n}\n\nstatic bool inheritingDeclaration (declType decl)\n{\n\t/* enum base types */\n\tif (decl == DECL_ENUM)\n\t{\n\t\treturn (bool) (isInputLanguage (Lang_csharp) || isInputLanguage (Lang_d));\n\t}\n\treturn (bool) (\n\t\tdecl == DECL_CLASS ||\n\t\tdecl == DECL_STRUCT ||\n\t\tdecl == DECL_INTERFACE);\n}\n\nstatic void processColon (statementInfo *const st)\n{\n\tint c = skipToNonWhite ();\n\tconst bool doubleColon = (bool) (c == ':');\n\n\tif (doubleColon)\n\t{\n\t\tsetToken (st, TOKEN_DOUBLE_COLON);\n\t\tst->haveQualifyingName = false;\n\t}\n\telse\n\t{\n\t\tcppUngetc (c);\n\t\tif ((isInputLanguage (Lang_csharp) || isInputLanguage (Lang_d))  &&\n\t\t\tinheritingDeclaration (st->declaration))\n\t\t{\n\t\t\treadParents (st, ':');\n\t\t}\n\t\telse if (parentDecl (st) == DECL_STRUCT)\n\t\t{\n\t\t\tc = skipToOneOf (\",;\");\n\t\t\tif (c == ',')\n\t\t\t\tsetToken (st, TOKEN_COMMA);\n\t\t\telse if (c == ';')\n\t\t\t\tsetToken (st, TOKEN_SEMICOLON);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tconst tokenInfo *const prev  = prevToken (st, 1);\n\t\t\tconst tokenInfo *const prev2 = prevToken (st, 2);\n\t\t\tif (prev->keyword == KEYWORD_DEFAULT ||\n\t\t\t\tprev2->keyword == KEYWORD_CASE)\n\t\t\t{\n\t\t\t\treinitStatement (st, false);\n\t\t\t}\n\t\t\telse if (st->parent != NULL)\n\t\t\t{\n\t\t\t\tif (prevToken (st->parent, 1)->keyword != KEYWORD_SWITCH)\n\t\t\t\t\tmakeTag (prev, st, false, TAG_LABEL);\n\t\t\t\treinitStatement (st, false);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/*  Skips over any initializing value which may follow an '=' character in a\n *  variable definition.\n */\nstatic int skipInitializer (statementInfo *const st)\n{\n\tbool done = false;\n\tint c;\n\n\twhile (! done)\n\t{\n\t\tc = skipToNonWhite ();\n\n\t\tif (c == EOF)\n\t\t\tlongjmp (Exception, (int) ExceptionFormattingError);\n\t\telse switch (c)\n\t\t{\n\t\t\tcase ',':\n\t\t\tcase ';': done = true; break;\n\n\t\t\tcase '0':\n\t\t\t\tif (st->implementation == IMP_VIRTUAL)\n\t\t\t\t\tst->implementation = IMP_PURE_VIRTUAL;\n\t\t\t\tbreak;\n\n\t\t\tcase '[': skipToMatch (\"[]\"); break;\n\t\t\tcase '(': skipToMatch (\"()\"); break;\n\t\t\tcase '{': skipToMatch (\"{}\"); break;\n\t\t\tcase '<': processAngleBracket(); break;\n\n\t\t\tcase '}':\n\t\t\t\tif (insideEnumBody (st))\n\t\t\t\t\tdone = true;\n\t\t\t\telse if (! cppIsBraceFormat ())\n\t\t\t\t{\n\t\t\t\t\tverbose (\"%s: unexpected closing brace at line %lu\\n\",\n\t\t\t\t\t\t\tgetInputFileName (), getInputLineNumber ());\n\t\t\t\t\tlongjmp (Exception, (int) ExceptionBraceFormattingError);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault: break;\n\t\t}\n\t}\n\treturn c;\n}\n\nstatic void processInitializer (statementInfo *const st)\n{\n\tconst bool inEnumBody = insideEnumBody (st);\n\tint c = cppGetc ();\n\n\tif (c != '=')\n\t{\n\t\tcppUngetc (c);\n\t\tc = skipInitializer (st);\n\t\tst->assignment = true;\n\t\tif (c == ';')\n\t\t\tsetToken (st, TOKEN_SEMICOLON);\n\t\telse if (c == ',')\n\t\t\tsetToken (st, TOKEN_COMMA);\n\t\telse if (c == '}'  &&  inEnumBody)\n\t\t{\n\t\t\tcppUngetc (c);\n\t\t\tsetToken (st, TOKEN_COMMA);\n\t\t}\n\t\tif (st->scope == SCOPE_EXTERN)\n\t\t\tst->scope = SCOPE_GLOBAL;\n\t}\n}\n\nstatic void parseIdentifier (statementInfo *const st, const int c)\n{\n\ttokenInfo *const token = activeToken (st);\n\n\treadIdentifier (token, c);\n\tif (! isType (token, TOKEN_NONE))\n\t\tprocessToken (token, st);\n}\n\nstatic void parseGeneralToken (statementInfo *const st, const int c)\n{\n\tconst tokenInfo *const prev = prevToken (st, 1);\n\n\tif (cppIsident1 (c) || (isInputLanguage (Lang_java) && isHighChar (c)))\n\t{\n\n\t\tparseIdentifier (st, c);\n\t\tif (isType (st->context, TOKEN_NAME) &&\n\t\t\tisType (activeToken (st), TOKEN_NAME) && isType (prev, TOKEN_NAME))\n\t\t{\n\t\t\tinitToken (st->context);\n\t\t}\n\t}\n\telse if (c == '.' || c == '-')\n\t{\n\t\tif (! st->assignment)\n\t\t\tst->notVariable = true;\n\t\tif (c == '-')\n\t\t{\n\t\t\tint c2 = cppGetc ();\n\t\t\tif (c2 != '>')\n\t\t\t\tcppUngetc (c2);\n\t\t}\n\t}\n\telse if (c == '!' || c == '>')\n\t{\n\t\tint c2 = cppGetc ();\n\t\tif (c2 != '=')\n\t\t\tcppUngetc (c2);\n\t}\n\telse if (c == '@' && (isInputLanguage (Lang_d) || isInputLanguage (Lang_java)))\n\t{\n\t\tparseAtMarkStyleAnnotation (st);\n\t}\n\telse if (c == CPP_STRING_SYMBOL)\n\t{\n\t\tsetToken(st, TOKEN_NONE);\n\t}\n}\n\n/*  Reads characters from the pre-processor and assembles tokens, setting\n *  the current statement state.\n */\nstatic void nextToken (statementInfo *const st)\n{\n\ttokenInfo *token;\n\tdo\n\t{\n\t\tint c = skipToNonWhite ();\n\t\tswitch (c)\n\t\t{\n\t\t\tcase EOF: longjmp (Exception, (int) ExceptionEOF);  break;\n\t\t\tcase '(': analyzeParens (st);                       break;\n\t\t\tcase '<': processAngleBracket ();                   break;\n\t\t\tcase '*': st->haveQualifyingName = false;           break;\n\t\t\tcase ',': setToken (st, TOKEN_COMMA);               break;\n\t\t\tcase ':': processColon (st);                        break;\n\t\t\tcase ';': setToken (st, TOKEN_SEMICOLON);           break;\n\t\t\tcase '=': processInitializer (st);                  break;\n\t\t\tcase '[': skipToMatch (\"[]\");                       break;\n\t\t\tcase '{': setToken (st, TOKEN_BRACE_OPEN);          break;\n\t\t\tcase '}': setToken (st, TOKEN_BRACE_CLOSE);         break;\n\t\t\tcase '!':\n\t\t\t\tif (isInputLanguage (Lang_d))\n\t\t\t\t{\n\t\t\t\t\tc = skipToNonWhite ();\n\t\t\t\t\tif (c == '(')\n\t\t\t\t\t{\n\t\t\t\t\t\t// template instance with parameter list\n\t\t\t\t\t\tskipToMatch(\"()\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault:  parseGeneralToken (st, c);                break;\n\t\t}\n\t\ttoken = activeToken (st);\n\t} while (isType (token, TOKEN_NONE));\n}\n\n/*\n*   Scanning support functions\n*/\n\nstatic statementInfo *CurrentStatement = NULL;\n\nstatic statementInfo *newStatement (statementInfo *const parent)\n{\n\tstatementInfo *const st = xMalloc (1, statementInfo);\n\tunsigned int i;\n\n\tfor (i = 0  ;  i < (unsigned int) NumTokens  ;  ++i)\n\t\tst->token [i] = newToken ();\n\n\tst->context = newToken ();\n\tst->blockName = newToken ();\n\tst->parentClasses = vStringNew ();\n\n\tinitStatement (st, parent);\n\tCurrentStatement = st;\n\n\treturn st;\n}\n\nstatic void deleteStatement (void)\n{\n\tstatementInfo *const st = CurrentStatement;\n\tstatementInfo *const parent = st->parent;\n\tunsigned int i;\n\n\tfor (i = 0  ;  i < (unsigned int) NumTokens  ;  ++i)\n\t{\n\t\tdeleteToken (st->token [i]);       st->token [i] = NULL;\n\t}\n\tdeleteToken (st->blockName);           st->blockName = NULL;\n\tdeleteToken (st->context);             st->context = NULL;\n\tvStringDelete (st->parentClasses);     st->parentClasses = NULL;\n\teFree (st);\n\tCurrentStatement = parent;\n}\n\nstatic void deleteAllStatements (void)\n{\n\twhile (CurrentStatement != NULL)\n\t\tdeleteStatement ();\n}\n\nstatic bool isStatementEnd (const statementInfo *const st)\n{\n\tconst tokenInfo *const token = activeToken (st);\n\tbool isEnd;\n\n\tif (isType (token, TOKEN_SEMICOLON))\n\t\tisEnd = true;\n\telse if (isType (token, TOKEN_BRACE_CLOSE))\n\t\t/* Java, C# and D do not require semicolons to end a block.\n\t\t */\n\t\tisEnd = true;\n\telse\n\t\tisEnd = false;\n\n\treturn isEnd;\n}\n\nstatic void checkStatementEnd (statementInfo *const st, int corkIndex)\n{\n\tconst tokenInfo *const token = activeToken (st);\n\n\tsetTagEndLineToCorkEntry (corkIndex, token->lineNumber);\n\n\tif (isType (token, TOKEN_COMMA))\n\t\treinitStatement (st, true);\n\telse if (isStatementEnd (st))\n\t{\n\t\tDebugStatement ( if (debug (DEBUG_PARSE)) printf (\"<ES>\"); )\n\t\treinitStatement (st, false);\n\t\tcppEndStatement ();\n\t}\n\telse\n\t{\n\t\tcppBeginStatement ();\n\t\tadvanceToken (st);\n\t}\n}\n\nstatic void nest (statementInfo *const st, const unsigned int nestLevel)\n{\n\tswitch (st->declaration)\n\t{\n\t\tcase DECL_TEMPLATE:\n\t\tcase DECL_VERSION:\n\t\t\tst->inFunction = false;\n\t\tcase DECL_CLASS:\n\t\tcase DECL_ENUM:\n\t\tcase DECL_INTERFACE:\n\t\tcase DECL_NAMESPACE:\n\t\tcase DECL_PRIVATE:\n\t\tcase DECL_PROTECTED:\n\t\tcase DECL_PUBLIC:\n\t\tcase DECL_STRUCT:\n\t\tcase DECL_UNION:\n\t\tcase DECL_ANNOTATION:\n\t\t\tcreateTags (nestLevel, st);\n\t\t\tbreak;\n\n\t\tcase DECL_FUNCTION:\n\t\t\tst->inFunction = true;\n\t\t\t/* fall through */\n\t\tdefault:\n\t\t\tif (includeTag (TAG_LOCAL, false) || includeTag (TAG_LABEL, false))\n\t\t\t\tcreateTags (nestLevel, st);\n\t\t\telse\n\t\t\t\tskipToMatch (\"{}\");\n\t\t\tbreak;\n\t}\n\tadvanceToken (st);\n\tsetToken (st, TOKEN_BRACE_CLOSE);\n}\n\nstatic int tagCheck (statementInfo *const st)\n{\n\tconst tokenInfo *const token = activeToken (st);\n\tconst tokenInfo *const prev  = prevToken (st, 1);\n\tconst tokenInfo *const prev2 = prevToken (st, 2);\n\tint corkIndex = CORK_NIL;\n\n\tswitch (token->type)\n\t{\n\t\tcase TOKEN_NAME:\n\t\t\tif (insideEnumBody (st))\n\t\t\t\tcorkIndex = qualifyEnumeratorTag (st, token);\n\t\t\tif (st->declaration == DECL_MIXIN)\n\t\t\t\tcorkIndex = makeTag (token, st, false, TAG_MIXIN);\n\t\t\tbreak;\n#if 0\n\t\tcase TOKEN_PACKAGE:\n\t\t\tif (st->haveQualifyingName)\n\t\t\t\tcorkIndex = makeTag (token, st, false, TAG_PACKAGE);\n\t\t\tbreak;\n#endif\n\t\tcase TOKEN_BRACE_OPEN:\n\t\t\tif (isType (prev, TOKEN_ARGS))\n\t\t\t{\n\t\t\t\tif (st->declaration == DECL_FUNCTION_TEMPLATE)\n\t\t\t\t{\n\t\t\t\t\tcorkIndex = qualifyFunctionTag (st, st->blockName);\n\t\t\t\t}\n\t\t\t\telse if (st->haveQualifyingName)\n\t\t\t\t{\n\t\t\t\t\tif (isType (prev2, TOKEN_NAME))\n\t\t\t\t\t\tcopyToken (st->blockName, prev2);\n\n\t\t\t\t\t/* D declaration templates */\n\t\t\t\t\tif (isInputLanguage (Lang_d) &&\n\t\t\t\t\t\t(st->declaration == DECL_CLASS || st->declaration == DECL_STRUCT ||\n\t\t\t\t\t\tst->declaration == DECL_INTERFACE || st->declaration == DECL_UNION ||\n\t\t\t\t\t\tst->declaration == DECL_TEMPLATE))\n\t\t\t\t\t\tcorkIndex = qualifyBlockTag (st, prev2);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tst->declaration = DECL_FUNCTION;\n\t\t\t\t\t\tcorkIndex = qualifyFunctionTag (st, prev2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (isContextualStatement (st) ||\n\t\t\t\t\tst->declaration == DECL_VERSION)\n\t\t\t{\n\t\t\t\tconst tokenInfo *name_token = prev;\n\n\t\t\t\tif (isType (name_token, TOKEN_NAME))\n\t\t\t\t\tcopyToken (st->blockName, name_token);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/*  For an anonymous struct or union we use a unique ID\n\t\t\t\t\t *  a number, so that the members can be found.\n\t\t\t\t\t */\n\t\t\t\t\tchar buf [20];  /* length of \"_anon\" + digits  + null */\n\t\t\t\t\tsprintf (buf, \"__anon%d\", ++AnonymousID);\n\t\t\t\t\tvStringCopyS (st->blockName->name, buf);\n\t\t\t\t\tst->blockName->type = TOKEN_NAME;\n\t\t\t\t\tst->blockName->keyword = KEYWORD_NONE;\n\t\t\t\t}\n\t\t\t\tcorkIndex = qualifyBlockTag (st, name_token);\n\t\t\t}\n\t\t\telse if (isInputLanguage (Lang_csharp))\n\t\t\t\tcorkIndex = makeTag (prev, st, false, TAG_PROPERTY);\n\t\t\tbreak;\n\n\t\tcase TOKEN_KEYWORD:\n\t\t\tif (token->keyword == KEYWORD_DEFAULT && isType(prev, TOKEN_ARGS) && insideAnnotationBody(st))\n\t\t\t{\n\t\t\t\tcorkIndex = qualifyFunctionDeclTag(st, prev2);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase TOKEN_SEMICOLON:\n\t\tcase TOKEN_COMMA:\n\t\t\tif (insideEnumBody (st))\n\t\t\t\t;\n\t\t\telse if (isType (prev, TOKEN_NAME))\n\t\t\t{\n\t\t\t\tif (isContextualKeyword (prev2))\n\t\t\t\t\tcorkIndex = makeTag (prev, st, true, TAG_EXTERN_VAR);\n\t\t\t\telse\n\t\t\t\t\tcorkIndex = qualifyVariableTag (st, prev);\n\t\t\t}\n\t\t\telse if (isType (prev, TOKEN_ARGS)  &&  isType (prev2, TOKEN_NAME))\n\t\t\t{\n\t\t\t\tif (st->isPointer || st->inFunction)\n\t\t\t\t{\n\t\t\t\t\t/* If it looks like a pointer or we are in a function body then\n\t\t\t\t\t   it's far more likely to be a variable. */\n\t\t\t\t\tcorkIndex = qualifyVariableTag (st, prev2);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tcorkIndex = qualifyFunctionDeclTag (st, prev2);\n\t\t\t}\n\t\t\tif (isInputLanguage (Lang_java) && token->type == TOKEN_SEMICOLON && insideEnumBody (st))\n\t\t\t{\n\t\t\t\t/* In Java, after an initial enum-like part,\n\t\t\t\t * a semicolon introduces a class-like part.\n\t\t\t\t * See Bug #1730485 for the full rationale. */\n\t\t\t\tst->parent->declaration = DECL_CLASS;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault: break;\n\t}\n\n\treturn corkIndex;\n}\n\n/*  Parses the current file and decides whether to write out and tags that\n *  are discovered.\n */\nstatic void createTags (const unsigned int nestLevel,\n\t\t\t\t\t\tstatementInfo *const parent)\n{\n\tstatementInfo *const st = newStatement (parent);\n\n\tDebugStatement ( if (nestLevel > 0) debugParseNest (true, nestLevel); )\n\twhile (true)\n\t{\n\t\ttokenInfo *token;\n\n\t\tnextToken (st);\n\t\ttoken = activeToken (st);\n\t\tif (isType (token, TOKEN_BRACE_CLOSE))\n\t\t{\n\t\t\tif (nestLevel > 0)\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t{\n\t\t\t\tverbose (\"%s: unexpected closing brace at line %lu\\n\",\n\t\t\t\t\t\tgetInputFileName (), getInputLineNumber ());\n\t\t\t\tlongjmp (Exception, (int) ExceptionBraceFormattingError);\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_DOUBLE_COLON))\n\t\t{\n\t\t\taddContext (st, prevToken (st, 1));\n\t\t\tadvanceToken (st);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tint corkIndex = tagCheck (st);\n\t\t\tif (isType (token, TOKEN_BRACE_OPEN))\n\t\t\t\tnest (st, nestLevel + 1);\n\t\t\tcheckStatementEnd (st, corkIndex);\n\t\t}\n\t}\n\tdeleteStatement ();\n\tDebugStatement ( if (nestLevel > 0) debugParseNest (false, nestLevel - 1); )\n}\n\nstatic rescanReason findCTags (const unsigned int passCount)\n{\n\texception_t exception;\n\trescanReason rescan;\n\tint kind_for_define = KIND_GHOST_INDEX;\n\tint kind_for_header = KIND_GHOST_INDEX;\n\tint kind_for_param  = KIND_GHOST_INDEX;\n\tint role_for_macro_undef = ROLE_DEFINITION_INDEX;\n\tint role_for_macro_condition = ROLE_DEFINITION_INDEX;\n\tint role_for_header_system   = ROLE_DEFINITION_INDEX;\n\tint role_for_header_local   = ROLE_DEFINITION_INDEX;\n\n\tAssert (passCount < 3);\n\n\tAnonymousID = 0;\n\n\tcppInit ((bool) (passCount > 1), isInputLanguage (Lang_csharp), false,\n\t\t false,\n\t\t kind_for_define, role_for_macro_undef, role_for_macro_condition, kind_for_param,\n\t\t kind_for_header, role_for_header_system, role_for_header_local,\n\t\t FIELD_UNKNOWN);\n\n\tSignature = vStringNew ();\n\n\texception = (exception_t) setjmp (Exception);\n\trescan = RESCAN_NONE;\n\tif (exception == ExceptionNone)\n\t\tcreateTags (0, NULL);\n\telse\n\t{\n\t\tdeleteAllStatements ();\n\t\tif (exception == ExceptionBraceFormattingError  &&  passCount == 1)\n\t\t{\n\t\t\trescan = RESCAN_FAILED;\n\t\t\tverbose (\"%s: retrying file with fallback brace matching algorithm\\n\",\n\t\t\t\t\tgetInputFileName ());\n\t\t}\n\t}\n\tvStringDelete (Signature);\n\tcppTerminate ();\n\treturn rescan;\n}\n\nstatic void buildKeywordHash (const langType language, unsigned int idx)\n{\n\tconst size_t count = ARRAY_SIZE (KeywordTable);\n\tsize_t i;\n\tfor (i = 0  ;  i < count  ;  ++i)\n\t{\n\t\tconst keywordDesc* const p = &KeywordTable [i];\n\t\tif (p->isValid [idx])\n\t\t\taddKeyword (p->name, language, (int) p->id);\n\t}\n}\n\nstatic void initializeCsharpParser (const langType language)\n{\n\tLang_csharp = language;\n\tbuildKeywordHash (language, 0);\n}\n\nstatic void initializeDParser (const langType language)\n{\n\tLang_d = language;\n\tbuildKeywordHash (language, 1);\n}\n\n\nstatic void initializeJavaParser (const langType language)\n{\n\tLang_java = language;\n\tbuildKeywordHash (language, 2);\n}\n\nextern parserDefinition* DParser (void)\n{\n\tstatic const char *const extensions [] = { \"d\", \"di\", NULL };\n\tparserDefinition* def = parserNew (\"D\");\n\tdef->kindTable      = DKinds;\n\tdef->kindCount  = ARRAY_SIZE (DKinds);\n\tdef->extensions = extensions;\n\tdef->parser2    = findCTags;\n\tdef->initialize = initializeDParser;\n\t// end: field is not tested.\n\n\t/* cpreprocessor wants corkQueue. */\n\tdef->useCork    = CORK_QUEUE;\n\treturn def;\n}\n\nextern parserDefinition* CsharpParser (void)\n{\n\tstatic const char *const extensions [] = { \"cs\", NULL };\n\tstatic const char *const aliases [] = { \"csharp\", NULL };\n\tparserDefinition* def = parserNew (\"C#\");\n\tdef->kindTable      = CsharpKinds;\n\tdef->kindCount  = ARRAY_SIZE (CsharpKinds);\n\tdef->extensions = extensions;\n\tdef->aliases    = aliases;\n\tdef->parser2    = findCTags;\n\tdef->initialize = initializeCsharpParser;\n\t// end: field is not tested.\n\n\t/* cpreprocessor wants corkQueue. */\n\tdef->useCork    = CORK_QUEUE;\n\treturn def;\n}\n\nextern parserDefinition* JavaParser (void)\n{\n\tstatic const char *const extensions [] = { \"java\", NULL };\n\tparserDefinition* def = parserNew (\"Java\");\n\tdef->kindTable      = JavaKinds;\n\tdef->kindCount  = ARRAY_SIZE (JavaKinds);\n\tdef->extensions = extensions;\n\tdef->parser2    = findCTags;\n\tdef->initialize = initializeJavaParser;\n\tdef->useCork    = CORK_QUEUE;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/cargo.c",
    "content": "/*\n*   Copyright (c) 2024, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Cargo.toml file.\n*\n*   - ref. https://doc.rust-lang.org/cargo/index.html\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"x-toml.h\"\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"read.h\"\n#include \"parse.h\"\n#include \"subparser.h\"\n\n#include <string.h>\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef enum {\n\tK_PACKAGE,\n#if 0\n\tK_CRATE,\n#endif\n} CargoKind;\n\nstatic kindDefinition CargoKinds[] = {\n\t{true, 'p', \"package\", \"packages\"},\n#if 0\n\t{true, 'c', \"crate\", \"crates\"},\n#endif\n};\n\nstruct sCargoSubparser {\n\ttomlSubparser toml;\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nstatic void valueCallback (tomlSubparser *sub, const char *value, long offset, int corkIndex)\n{\n\tif (value[0] == '\\0' || (value[0] == '\"' && value[1] == '\"'))\n\t\treturn;\n\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\tif (e && strcmp(e->name, \"name\") == 0\n\t\t&& e->extensionFields.scopeIndex != CORK_NIL)\n\t{\n\t\ttagEntryInfo *parent = getEntryInCorkQueue(e->extensionFields.scopeIndex);\n\t\tif (parent && strcmp(parent->name, \"package\") == 0\n\t\t\t&& parent->extensionFields.scopeIndex == CORK_NIL)\n\t\t{\n\t\t\ttagEntryInfo pe;\n\t\t\tunsigned long lineNumber = getInputLineNumberForFileOffset(offset);\n\t\t\tMIOPos filePosition = getInputFilePositionForLine (lineNumber);\n\n\t\t\t/* Dropping double quote chars. */\n\t\t\tvString *package = vStringNewInit (*value == '\"'? value + 1: value);\n\t\t\tif (*value == '\"')\n\t\t\t\tvStringChop (package);\n\n\t\t\tinitTagEntry (&pe, vStringValue (package), K_PACKAGE);\n\t\t\tupdateTagLine (&pe, lineNumber, filePosition);\n\n\t\t\tmakeTagEntry (&pe);\n\n\t\t\tvStringDelete (package);\n\t\t}\n\t}\n}\n\n#if 0\nstatic void makeTagEntryCallback(subparser *s, const tagEntryInfo *tag, int corkIndex)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\tif (e && e->extensionFields.scopeIndex != CORK_NIL && e->kindIndex == TOML_K_QKEY)\n\t{\n\t\ttagEntryInfo *pe = getEntryInCorkQueue (e->extensionFields.scopeIndex);\n\t\tif (pe && pe->extensionFields.scopeIndex == CORK_NIL)\n\t\t{\n\t\t\tif (strcmp(pe->name, \"dependencies\") == 0)\n\t\t\t\t;\n\t\t\ttagEntryInfo ce;\n\n\t\t\tinitTagEntry (&ce, e->name, K_CRATE);\n\t\t\tce.lineNumber = e->lineNumber;\n\t\t\tce.filePosition = e->filePosition;\n\n\t\t\tmakeTagEntry (&ce);\n\t\t}\n\t}\n}\n#endif\n\nstatic void findCargoTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* CargoParser (void)\n{\n\tstatic const char *const patterns [] = { \"Cargo.toml\", NULL };\n\n\tstatic struct sCargoSubparser cargoSubparser = {\n\t\t.toml = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n#if 0\n\t\t\t\t.makeTagEntryNotify = makeTagEntryCallback,\n#endif\n\t\t\t},\n\t\t\t.valueNotify = valueCallback,\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"TOML\", &cargoSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"Cargo\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE(dependencies);\n\tdef->kindTable = CargoKinds;\n\tdef->kindCount  = ARRAY_SIZE (CargoKinds);\n\tdef->patterns   = patterns;\n\tdef->parser     = findCargoTags;\n\tdef->useCork    = CORK_QUEUE;\n\n\tdef->enabled = false;\t\t/* The base parser, TOML parser doesn't work well. */\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/clojure.c",
    "content": "/**\n *   Copyright (c) 2015, Miloslav Nenadál <nenadalm@gmail.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains code for generating tags for the Clojure language.\n */\n\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"parse.h\"\n\n#include \"x-lisp.h\"\n\n#include <ctype.h>\n#include <string.h>\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_UNKNOWN,\n\tK_FUNCTION,\n\tK_NAMESPACE,\n\tK_MACRO,\n} clojureKind;\n\ntypedef enum {\n\tF_DEFINER,\n} clojureField;\n\nstatic fieldDefinition ClojureFields[] = {\n\t{ .name = \"definer\",\n\t  .description = \"the name of the function or macro that defines the unknown/Y-kind object\",\n\t  .enabled = true,\n\t  .version = 1 },\n};\n\nstatic kindDefinition ClojureKinds[] = {\n\t{ true, 'Y', \"unknown\", \"unknown type of definitions\",\n\t  .version = 1 },\n\t{ true, 'f', \"function\", \"functions\" },\n\t{ true, 'n', \"namespace\", \"namespaces\" },\n\t{ true, 'm', \"macro\", \"macros\",\n\t  .version = 2 },\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nstatic struct lispIsDefResult clojure_is_def (struct lispDialect *dialect CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\t\t  const unsigned char *strp)\n{\n\tstruct lispIsDefResult r = { .is_def = false, .kind = KIND_GHOST_INDEX, };\n\tconst unsigned char *input = strp + 1;\n\n#define EQN(input, expect) (strncmp((const char *)(input), (expect), sizeof(expect) - 1) == 0 \\\n\t\t\t\t\t\t\t&& (isspace ((input)[sizeof(expect) - 1])))\n\n\tif (EQN(input, \"ns\"))\n\t{\n\t\tr.is_def = true;\n\t\tr.kind = K_NAMESPACE;\n\t}\n\telse if (EQN(input, \"defn\"))\n\t{\n\t\tr.is_def = true;\n\t\tr.kind = K_FUNCTION;\n\t}\n\telse if (EQN(input, \"defmacro\"))\n\t{\n\t\tr.is_def = true;\n\t\tr.kind = K_MACRO;\n\t}\n\n#undef EQN\n\n\treturn r;\n}\n\nstatic int clojure_hint2kind (struct lispKindHint *hint, const char *namespace)\n{\n\tif (namespace[0] != '\\0'\n\t\t&& strcmp (namespace, \"clojure.core/\") != 0)\n\t\treturn K_UNKNOWN;\n\n\treturn hint->isDefResult.kind;\n}\n\nconst unsigned char* clojure_skip_metadata (const unsigned char *dbp)\n{\n\twhile (1)\n\t{\n\t\tif (*dbp == '^')\n\t\t{\n\t\t\tdbp++;\n\t\t\tif (*dbp == '{')\n\t\t\t{\n\t\t\t\t/* skipping an arraymap */\n\t\t\t\tfor (; *dbp != '\\0' && *dbp != '}'; dbp++)\n\t\t\t\t\t;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* skip a keyword or a symbol */\n\t\t\t\tfor (; *dbp != '\\0' && !isspace((unsigned char)*dbp); dbp++)\n\t\t\t\t\t;\n\t\t\t}\n\n\t\t\tif (*dbp == '\\0')\n\t\t\t\tbreak;\n\n\t\t\tdbp++;\n\t\t\twhile (isspace ((unsigned char)*dbp))\n\t\t\t\tdbp++;\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\n\treturn dbp;\n}\n\nstatic int clojure_get_it (struct lispDialect *dialect,\n\t\t\t\t\t\t   vString *const name, const unsigned char *dbp, struct lispKindHint *kind_hint,\n\t\t\t\t\t\t   const char *namespace)\n{\n\tdbp = clojure_skip_metadata (dbp);\n\tint index = lispGetIt (dialect, name, dbp, kind_hint, namespace);\n\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\n\tif (!e)\n\t\treturn CORK_NIL;\n\n\tif (e->kindIndex == K_NAMESPACE)\n\t\tdialect->scope = index;\n\telse\n\t\te->extensionFields.scopeIndex = dialect->scope;\n\n\treturn index;\n}\n\nstatic void findClojureTags (void)\n{\n\tstruct lispDialect clojure_dialect = {\n\t\t.definer2kind = clojure_hint2kind,\n\t\t.case_insensitive = false,\n\t\t.namespace_sep = '/',\n\t\t.unknown_kind = K_UNKNOWN,\n\t\t.definer_field = ClojureFields + F_DEFINER,\n\t\t.skip_initial_spaces = true,\n\t\t.is_def = clojure_is_def,\n\t\t.get_it = clojure_get_it,\n\t\t.scope = CORK_NIL,\n\t};\n\n\tfindLispTagsCommon (&clojure_dialect);\n}\n\nextern parserDefinition *ClojureParser (void)\n{\n\tstatic const char *const extensions[] = {\n\t\t\"clj\", \"cljs\", \"cljc\", NULL\n\t};\n\tstatic const char *const aliases[] = {\n\t\tNULL\n\t};\n\n\tparserDefinition *def = parserNew (\"Clojure\");\n\tdef->kindTable = ClojureKinds;\n\tdef->kindCount = ARRAY_SIZE (ClojureKinds);\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->parser = findClojureTags;\n\tdef->useCork = CORK_QUEUE;\n\tdef->versionCurrent = 1; /* Set 2 when releasing 6.3.0 */\n\tdef->versionAge = 1; /* Set 2 when releasing 6.3.0 */\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/cobol.c",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for COBOL language\n*   files.\n*/\n\n/* Some references:\n * - https://www.cs.vu.nl/grammarware/browsable/cobol/\n * - https://www.cs.vu.nl/grammarware/browsable/vs-cobol-ii/\n * - https://open-cobol.sourceforge.io/guides/grammar.pdf\n * - http://mapage.noos.fr/~bpinon/a_cobol_parser.htm\n * - https://en.wikipedia.org/wiki/COBOL\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"nestlevel.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n\ntypedef enum {\n\tK_FILE,\n\tK_GROUP,\n\tK_PROGRAM,\n\tK_SECTION,\n\tK_DIVISION,\n\tK_PARAGRAPH,\n\tK_DATA,\n\tK_SOURCEFILE,\n} cobolKind;\n\ntypedef enum {\n\tCOBOL_SOURCEFILE_COPIED,\n} cobolSourcefileRole;\n\nstatic roleDefinition CobolSourcefileRoles [] = {\n\t{ true, \"copied\", \"copied in source file\" },\n};\n\nstatic kindDefinition CobolKinds[] = {\n\t{ true, 'f', \"fd\", \"file descriptions (FD, SD, RD)\" },\n\t{ true, 'g', \"group\", \"group items\" },\n\t{ true, 'P', \"program\", \"program ids\" },\n\t{ true, 's', \"section\", \"sections\" },\n\t{ true, 'D', \"division\", \"divisions\" },\n\t{ true, 'p', \"paragraph\", \"paragraphs\" },\n\t{ true, 'd', \"data\", \"data items\"      },\n\t{ true, 'S', \"sourcefile\", \"source code file\",\n\t  .referenceOnly = true, ATTACH_ROLES(CobolSourcefileRoles)},\n};\n\nstatic langType Lang_cobol;\n\nenum {\n\tKEYWORD_FD,\n\tKEYWORD_SD,\n\tKEYWORD_RD,\n\tKEYWORD_SECTION,\n\tKEYWORD_DIVISION,\n\tKEYWORD_CONTINUE,\n\tKEYWORD_END_EXEC,\n\tKEYWORD_FILLER,\n\tKEYWORD_BLANK,\n\tKEYWORD_OCCURS,\n\tKEYWORD_IS,\n\tKEYWORD_JUST,\n\tKEYWORD_PIC,\n\tKEYWORD_REDEFINES,\n\tKEYWORD_RENAMES,\n\tKEYWORD_SIGN,\n\tKEYWORD_SYNC,\n\tKEYWORD_USAGE,\n\tKEYWORD_VALUE,\n\tKEYWORD_PROGRAM_ID,\n\tKEYWORD_EXIT,\n\tKEYWORD_COPY,\n};\n\nstatic const keywordTable cobolKeywordTable[] = {\n#define DEFINE_KEYWORD(n) { #n, KEYWORD_##n }\n\tDEFINE_KEYWORD (FD),\n\tDEFINE_KEYWORD (SD),\n\tDEFINE_KEYWORD (RD),\n\tDEFINE_KEYWORD (SECTION),\n\tDEFINE_KEYWORD (DIVISION),\n\tDEFINE_KEYWORD (CONTINUE),\n\t{ \"END-EXEC\", KEYWORD_END_EXEC },\n\tDEFINE_KEYWORD (EXIT),\n\tDEFINE_KEYWORD (FILLER),\n\tDEFINE_KEYWORD (BLANK),\n\tDEFINE_KEYWORD (OCCURS),\n\tDEFINE_KEYWORD (IS),\n\tDEFINE_KEYWORD (JUST),\n\tDEFINE_KEYWORD (PIC),\n\t{ \"PICTURE\", KEYWORD_PIC },\n\tDEFINE_KEYWORD (REDEFINES),\n\tDEFINE_KEYWORD (RENAMES),\n\tDEFINE_KEYWORD (SIGN),\n\tDEFINE_KEYWORD (SYNC),\n\tDEFINE_KEYWORD (USAGE),\n\tDEFINE_KEYWORD (VALUE),\n\t{ \"VALUES\", KEYWORD_VALUE },\n\t{ \"PROGRAM-ID\", KEYWORD_PROGRAM_ID },\n\tDEFINE_KEYWORD (COPY),\n};\n\n#define INDICATOR_COLUMN 7\n#define PROGRAM_NAME_AREA_COLUMN 73\n\n#define isIdentifierChar(c) (isalnum(c) || (c) == '-')\n#define isQuote(c) ((c) == '\\'' || (c) == '\"')\n\ntypedef enum {\n\t/* Fixed: program starts at column 8, ends at column 72 */\n\tFORMAT_FIXED\t= 0x1,\n\t/* Free: program starts at column 1, no specific end */\n\tFORMAT_FREE\t\t= 0x2,\n\t/* Variable: program starts at column 8, no specific end */\n\tFORMAT_VARIABLE\t= FORMAT_FIXED | FORMAT_FREE\n} CobolFormat;\n\nstatic struct {\n\tvString *line;\n\tunsigned long int lineNumber;\n\tMIOPos filePosition;\n\tconst char *nextLine;\n\tCobolFormat format;\n} CblInputState;\n\nstatic void cblppInit (const CobolFormat format)\n{\n\tCblInputState.line = vStringNew ();\n\tCblInputState.lineNumber = 0;\n\tCblInputState.nextLine = NULL;\n\tCblInputState.format = format;\n}\n\nstatic void cblppDeinit (void)\n{\n\tvStringDelete (CblInputState.line);\n}\n\nstatic const char *cblppGetColumn (const char *line,\n\t\t\t\t\t\t\t\t   const unsigned int column)\n{\n\tunsigned int col = 0;\n\n\tfor (; *line; line++)\n\t{\n\t\tcol += (*line == '\\t') ? 8 : 1;\n\t\tif (col >= column)\n\t\t\treturn line;\n\t}\n\n\treturn NULL;\n}\n\nstatic void cblppAppendLine (vString *buffer,\n\t\t\t\t\t\t\t const char *line)\n{\n\tif (CblInputState.format & FORMAT_FIXED)\n\t{\n\t\tconst char *indicator = cblppGetColumn (line, INDICATOR_COLUMN);\n\n\t\tif (indicator && *indicator && *indicator != '*' && *indicator != '/')\n\t\t{\n\t\t\tconst char *lineStart = indicator + 1;\n\t\t\tconst char *lineEnd = cblppGetColumn (line, PROGRAM_NAME_AREA_COLUMN);\n\n\t\t\tif (*indicator == '-')\n\t\t\t{\n\t\t\t\tvStringStripTrailing (buffer);\n\t\t\t\twhile (isspace ((unsigned char) *lineStart))\n\t\t\t\t\tlineStart++;\n\t\t\t}\n\n\t\t\tif (CblInputState.format == FORMAT_FIXED)\n\t\t\t\tvStringNCatS (buffer, lineStart, lineEnd - lineStart);\n\t\t\telse\n\t\t\t\tvStringCatS (buffer, lineStart);\n\t\t}\n\t}\n\telse if (line[0] != '*' && line[0] != '/')\n\t\tvStringCatS (buffer, line);\n}\n\n/* TODO: skip *> comments */\nstatic const char *cblppGetLine (void)\n{\n\tconst char *line;\n\n\tif (CblInputState.nextLine)\n\t{\n\t\tline = CblInputState.nextLine;\n\t\tCblInputState.nextLine = NULL;\n\t}\n\telse\n\t\tline = (const char *) readLineFromInputFile ();\n\n\tCblInputState.lineNumber = getInputLineNumber ();\n\tCblInputState.filePosition = getInputFilePosition ();\n\n\tif (!line)\n\t\treturn NULL;\n\n\tvStringClear (CblInputState.line);\n\tcblppAppendLine (CblInputState.line, line);\n\n\t/* check for continuation lines */\n\tif (CblInputState.format & FORMAT_FIXED)\n\t{\n\t\twhile (true)\n\t\t{\n\t\t\tconst char *indicator;\n\t\t\tline = (const char *) readLineFromInputFile ();\n\t\t\tif (! line)\n\t\t\t\tbreak;\n\t\t\tindicator = cblppGetColumn (line, INDICATOR_COLUMN);\n\t\t\tif (indicator && *indicator == '-')\n\t\t\t\tcblppAppendLine (CblInputState.line, line);\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\n\t\tCblInputState.nextLine = line;\n\t}\n\n\treturn vStringValue (CblInputState.line);\n}\n\nstatic void initCOBOLRefTagEntry (tagEntryInfo *e, const char *name,\n\t\t\t\t\t\t\t\t  const cobolKind kind, const int role)\n{\n\tinitRefTagEntry (e, name, kind, role);\n\tupdateTagLine (e, CblInputState.lineNumber, CblInputState.filePosition);\n}\n\nstatic void initCOBOLTagEntry (tagEntryInfo *e, const char *name, const cobolKind kind)\n{\n\tinitCOBOLRefTagEntry (e, name, kind, ROLE_DEFINITION_INDEX);\n}\n\nstatic int makeCOBOLRefTag (const char *name, const cobolKind kind, const int role)\n{\n\tif (CobolKinds[kind].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitCOBOLRefTagEntry (&e, name, kind, role);\n\n\t\treturn makeTagEntry (&e);\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic int makeCOBOLTag (const char *name, const cobolKind kind)\n{\n\treturn makeCOBOLRefTag (name, kind, ROLE_DEFINITION_INDEX);\n}\n\n#define CBL_NL(nl) (*((unsigned int *) (nestingLevelGetUserData (nl))))\n\nstatic NestingLevel *popNestingLevelsToLevelNumber (NestingLevels *levels, const unsigned int levelNumber)\n{\n\tNestingLevel *nl;\n\n\twhile (true)\n\t{\n\t\tnl = nestingLevelsGetCurrent (levels);\n\t\tif (! nl || CBL_NL (nl) < levelNumber)\n\t\t\tbreak;\n\t\tnestingLevelsPop (levels);\n\t}\n\n\treturn nl;\n}\n\nstatic bool isNumeric (const char *nptr, unsigned long int *num)\n{\n\tchar *endptr;\n\tunsigned long int v;\n\n\tv = strtoul (nptr, &endptr, 10);\n\tif (nptr != endptr && *endptr == 0)\n\t{\n\t\tif (num)\n\t\t\t*num = v;\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic void findCOBOLTags (const CobolFormat format)\n{\n\tNestingLevels *levels;\n\tconst char *line;\n\n\tcblppInit (format);\n\n\tlevels = nestingLevelsNew (sizeof (unsigned int));\n\n\twhile ((line = cblppGetLine ()) != NULL)\n\t{\n\t\tchar word[64];\n\t\tint keyword;\n\t\tunsigned long int levelNumber;\n\n#define READ_WHILE(word, cond) \\\n\tdo { \\\n\t\tunsigned int i; \\\n\t\tfor (i = 0; i < (ARRAY_SIZE (word) - 1) && *line && (cond); line++) \\\n\t\t\tword[i++] = *line; \\\n\t\tword[i] = 0; \\\n\t} while (0)\n#define READ_LITERAL(word) \\\n\tdo { \\\n\t\tconst char READ_LITERAL__q = isQuote (*line) ? *line++ : 0; \\\n\t\tREAD_WHILE (word, (READ_LITERAL__q && READ_LITERAL__q != *line) || \\\n\t\t                   isIdentifierChar ((unsigned char) *line)); \\\n\t\tif (READ_LITERAL__q && READ_LITERAL__q == *line) \\\n\t\t\tline++; \\\n\t\tkeyword = lookupCaseKeyword (word, Lang_cobol); \\\n\t} while (0)\n#define READ_WORD(word, keyword) \\\n\tdo { \\\n\t\tREAD_WHILE (word, isIdentifierChar ((unsigned char) *line)); \\\n\t\tkeyword = lookupCaseKeyword (word, Lang_cobol); \\\n\t} while (0)\n#define READ_KEYWORD(keyword) \\\n\tdo { \\\n\t\tchar READ_KEYWORD__word[64]; \\\n\t\tREAD_WORD (READ_KEYWORD__word, keyword); \\\n\t} while (0)\n#define SKIP_SPACES() \\\n\tdo { while (isspace ((unsigned char) *line)) line++; } while (0)\n\n\t\tSKIP_SPACES ();\n\t\tREAD_WORD (word, keyword);\n\t\tSKIP_SPACES ();\n\n\t\tswitch (keyword)\n\t\t{\n\t\tcase KEYWORD_FD:\n\t\tcase KEYWORD_SD:\n\t\tcase KEYWORD_RD:\n\t\t\tREAD_WORD (word, keyword);\n\t\t\tSKIP_SPACES ();\n\t\t\tif (*word && *line == '.')\n\t\t\t\tmakeCOBOLTag (word, K_FILE);\n\t\t\tbreak;\n\n\t\tcase KEYWORD_PROGRAM_ID:\n\t\t\tif (*line == '.')\n\t\t\t{\n\t\t\t\tline++;\n\t\t\t\tSKIP_SPACES ();\n\t\t\t}\n\t\t\tREAD_LITERAL (word);\n\t\t\tif (*word)\n\t\t\t\tmakeCOBOLTag (word, K_PROGRAM);\n\t\t\tbreak;\n\n\t\tcase KEYWORD_COPY:\n\t\t\tREAD_WORD (word, keyword); // FIXME: also allow LITERAL\n\t\t\tif (*word)\n\t\t\t\tmakeCOBOLRefTag (word, K_SOURCEFILE, COBOL_SOURCEFILE_COPIED);\n\t\t\tbreak;\n\n\t\tcase KEYWORD_CONTINUE:\n\t\tcase KEYWORD_END_EXEC:\n\t\tcase KEYWORD_EXIT:\n\t\tcase KEYWORD_FILLER:\n\t\t\t/* nothing, just ignore those in following cases */;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tif (isNumeric (word, &levelNumber))\n\t\t\t{\n\t\t\t\tREAD_WORD (word, keyword);\n\t\t\t\tSKIP_SPACES ();\n\n\t\t\t\tif (*word && keyword != KEYWORD_FILLER)\n\t\t\t\t{\n\t\t\t\t\tint kind = KIND_GHOST_INDEX;\n\n\t\t\t\t\tif (*line == '.')\n\t\t\t\t\t\tkind = K_GROUP;\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tint keyword2;\n\n\t\t\t\t\t\tREAD_KEYWORD (keyword2);\n\t\t\t\t\t\tswitch (keyword2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\tcase KEYWORD_BLANK:\n\t\t\t\t\t\tcase KEYWORD_OCCURS:\n\t\t\t\t\t\tcase KEYWORD_IS:\n\t\t\t\t\t\tcase KEYWORD_JUST:\n\t\t\t\t\t\tcase KEYWORD_PIC:\n\t\t\t\t\t\tcase KEYWORD_REDEFINES:\n\t\t\t\t\t\tcase KEYWORD_RENAMES:\n\t\t\t\t\t\tcase KEYWORD_SIGN:\n\t\t\t\t\t\tcase KEYWORD_SYNC:\n\t\t\t\t\t\tcase KEYWORD_USAGE:\n\t\t\t\t\t\tcase KEYWORD_VALUE:\n\t\t\t\t\t\t\tkind = K_DATA;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (kind != KIND_GHOST_INDEX)\n\t\t\t\t\t{\n\t\t\t\t\t\tNestingLevel *nl;\n\t\t\t\t\t\ttagEntryInfo entry;\n\t\t\t\t\t\tint r;\n\t\t\t\t\t\tunsigned int nestingLevelNumber;\n\n\t\t\t\t\t\t/* for nesting purposes, level 77 is identical to 1,\n\t\t\t\t\t\t * and 66 to 2 */\n\t\t\t\t\t\tswitch (levelNumber)\n\t\t\t\t\t\t{\n\t\t\t\t\t\tdefault: nestingLevelNumber = levelNumber; break;\n\t\t\t\t\t\tcase 77: nestingLevelNumber = 1; break;\n\t\t\t\t\t\tcase 66: nestingLevelNumber = 2; break;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tnl = popNestingLevelsToLevelNumber (levels, nestingLevelNumber);\n\t\t\t\t\t\tinitCOBOLTagEntry (&entry, word, kind);\n\t\t\t\t\t\tif (nl && CBL_NL (nl) < nestingLevelNumber)\n\t\t\t\t\t\t\tentry.extensionFields.scopeIndex = nl->corkIndex;\n\t\t\t\t\t\tr = makeTagEntry (&entry);\n\t\t\t\t\t\tif (levelNumber < 50 /* exclude special levels */)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnl = nestingLevelsPush (levels, r);\n\t\t\t\t\t\t\tCBL_NL (nl) = levelNumber;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (*word && *line == '.')\n\t\t\t\tmakeCOBOLTag (word, K_PARAGRAPH);\n\t\t\telse\n\t\t\t{\n\t\t\t\tint keyword2;\n\n\t\t\t\tREAD_KEYWORD (keyword2);\n\t\t\t\tSKIP_SPACES ();\n\n\t\t\t\tif (keyword2 == KEYWORD_DIVISION && *line == '.')\n\t\t\t\t\tmakeCOBOLTag (word, K_DIVISION);\n\t\t\t\telse if (keyword2 == KEYWORD_SECTION && *line == '.')\n\t\t\t\t\tmakeCOBOLTag (word, K_SECTION);\n\t\t\t}\n\t\t}\n\t}\n\n\tnestingLevelsFree (levels);\n\tcblppDeinit ();\n}\n\nstatic void findCOBOLFixedTags (void)\n{\n\tfindCOBOLTags (FORMAT_FIXED);\n}\n\nstatic void findCOBOLFreeTags (void)\n{\n\tfindCOBOLTags (FORMAT_FREE);\n}\n\nstatic void findCOBOLVariableTags (void)\n{\n\tfindCOBOLTags (FORMAT_VARIABLE);\n}\n\nstatic void initializeCobolParser (langType language)\n{\n\tLang_cobol = language;\n}\n\nstatic parserDefinition* commonCobolParserDefinition (const char *name,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  simpleParser parser)\n{\n\tparserDefinition* def = parserNew (name);\n\tdef->initialize = initializeCobolParser;\n\tdef->parser = parser;\n\tdef->kindTable = CobolKinds;\n\tdef->kindCount = ARRAY_SIZE(CobolKinds);\n\tdef->keywordTable = cobolKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE(cobolKeywordTable);\n\tdef->useCork = CORK_QUEUE;\n\treturn def;\n}\n\nextern parserDefinition* CobolParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\t\"cbl\", \"cob\", \"CBL\", \"COB\", NULL };\n\tparserDefinition* def = commonCobolParserDefinition (\"Cobol\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t findCOBOLFixedTags);\n\tdef->extensions = extensions;\n\treturn def;\n}\n\nextern parserDefinition* CobolFreeParser (void)\n{\n\treturn commonCobolParserDefinition (\"CobolFree\", findCOBOLFreeTags);\n}\n\nextern parserDefinition* CobolVariableParser (void)\n{\n\treturn commonCobolParserDefinition (\"CobolVariable\", findCOBOLVariableTags);\n}\n"
  },
  {
    "path": "parsers/cpreprocessor.c",
    "content": "/*\n*   Copyright (c) 1996-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains the high level input read functions (preprocessor\n*   directives are handled within this level).\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"htable.h\"\n#include \"x-cpreprocessor.h\"\n#include \"kind.h\"\n#include \"options.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"param.h\"\n#include \"parse.h\"\n#include \"promise.h\"\n#include \"xtag.h\"\n\n#include \"cxx/cxx_debug.h\"\n\n/*\n*   MACROS\n*/\n#define stringMatch(s1,s2)\t\t(strcmp (s1,s2) == 0)\n#define isspacetab(c)\t\t\t((c) == SPACE || (c) == TAB)\n\n/*\n*   DATA DECLARATIONS\n*/\nenum eCppCharacters {\n\t/* white space characters */\n\tSPACE         = ' ',\n\tNEWLINE       = '\\n',\n\tCRETURN       = '\\r',\n\tFORMFEED      = '\\f',\n\tTAB           = '\\t',\n\tVTAB          = '\\v',\n\n\t/* some hard to read characters */\n\tDOUBLE_QUOTE  = '\"',\n\tSINGLE_QUOTE  = '\\'',\n\tBACKSLASH     = '\\\\',\n\n\t/* symbolic representations, above 0xFF not to conflict with any byte */\n\tSTRING_SYMBOL = CPP_STRING_SYMBOL,\n\tCHAR_SYMBOL   = CPP_CHAR_SYMBOL\n};\n\ntypedef enum { COMMENT_NONE, COMMENT_C, COMMENT_CPLUS, COMMENT_D } Comment;\n\nenum eCppLimits {\n\tMaxCppNestingLevel = 20,\n\tMaxDirectiveName = 10\n};\n\n/* For tracking __ASSEMBLER__ area. */\nenum eIfSubstate {\n\tIF_IF,\n\tIF_IFDEF,\n\tIF_IFNDEF,\n\tIF_ELSE,\n\tIF_ELIF,\n\tIF_ENDIF,\n};\n\nstruct asmAreaInfo {\n\tenum eIfSubstate ifSubstate;\n\tunsigned long line;\n};\n\n/*  Defines the one nesting level of a preprocessor conditional.\n */\ntypedef struct sConditionalInfo {\n\tbool ignoreAllBranches;  /* ignoring parent conditional branch */\n\tbool singleBranch;       /* choose only one branch */\n\tbool branchChosen;       /* branch already selected */\n\tbool ignoring;           /* current ignore state */\n\tint enterExternalParserBlockNestLevel;          /* the parser state when entering this conditional: used only by cxx */\n\n\t/* tracking __ASSEMBLER__ area */\n\tstruct asmAreaInfo asmArea;\n} conditionalInfo;\n\nenum eState {\n\tDRCTV_NONE,    /* no known directive - ignore to end of line */\n\tDRCTV_DEFINE,  /* \"#define\" encountered */\n\tDRCTV_HASH,    /* initial '#' read; determine directive */\n\tDRCTV_IF,      /* \"#if\" or \"#ifdef\" encountered */\n\tDRCTV_ELIF,    /* \"#elif\" encountered */\n\tDRCTV_PRAGMA,  /* #pragma encountered */\n\tDRCTV_UNDEF,   /* \"#undef\" encountered */\n\tDRCTV_INCLUDE, /* \"#include\" encountered */\n};\n\n/*  Defines the current state of the pre-processor.\n */\ntypedef struct sUngetBuffer {\n\tunsigned char *buffer;\t  /* memory buffer for unget characters */\n\tint size;\t\t/* the current unget buffer size */\n\tunsigned char *pointer;\t  /* the current unget char: points in the\n\t\t\t\t\t\t   middle of the buffer */\n\tint dataSize;\t\t/* the number of valid unget characters\n\t\t\t\t\t\t   in the buffer */\n\tunsigned long lineNumber;\n\tMIOPos filePosition;\n\tcppMacroInfo *macro;\n} ungetBuffer;\n\ntypedef struct sCppState {\n\tlangType lang;\n\tlangType clientLang;\n\n\tungetBuffer  *ungetBuffer;\n\tptrArray *ungetBufferStack;\n\n\t/* the contents of the last SYMBOL_CHAR or SYMBOL_STRING */\n\tvString * charOrStringContents;\n\n\tbool resolveRequired;     /* must resolve if/else/elif/endif branch */\n\tbool hasAtLiteralStrings; /* supports @\"c:\\\" strings */\n\tbool hasCxxRawLiteralStrings; /* supports R\"xxx(...)xxx\" strings */\n\tbool hasSingleQuoteLiteralNumbers; /* supports vera number literals:\n\t\t\t\t\t\t 'h..., 'o..., 'd..., and 'b... */\n\n\tbool useClientLangDefineMacroKindIndex;\n\tint defineMacroKindIndex;\n\tint macroUndefRoleIndex;\n\tint macroConditionRoleIndex;\n\n\tbool useClientLangMacroParamKindIndex;\n\tint macroParamKindIndex;\n\n\tbool useClientLangHeaderKindIndex;\n\tint headerKindIndex;\n\tint headerSystemRoleIndex;\n\tint headerLocalRoleIndex;\n\n\tint macrodefFieldIndex;\n\n\tstruct sDirective {\n\t\tenum eState state;       /* current directive being processed */\n\t\tenum eIfSubstate ifsubstate; /* For tracking __ASSEMBLER__.\n\t\t\t\t\t\t\t\t\t  * assigned only when state == DICTV_IF */\n\t\tbool\taccept;          /* is a directive syntactically permitted? */\n\t\tvString * name;          /* macro name */\n\t\tunsigned int nestLevel;  /* level 0 is not used */\n\t\tconditionalInfo ifdef [MaxCppNestingLevel];\n\t} directive;\n\n\tcppMacroInfo * macroInUse;\n\thashTable * fileMacroTable;\n\n} cppState;\n\n#define CPP_MACRO_REPLACEMENT_FLAG_VARARGS 1\n#define CPP_MACRO_REPLACEMENT_FLAG_STRINGIFY 2\n\nstruct sCppMacroReplacementPartInfo {\n\tint parameterIndex; /* -1 if this part is a constant */\n\tint flags;\n\tvString * constant; /* not NULL only if parameterIndex != -1 */\n\tstruct sCppMacroReplacementPartInfo * next;\n};\n\nstruct sCppMacroArg {\n\tconst char *str;\n\tunsigned long lineNumber;\n\tMIOPos filePosition;\n\tbool free_str;\n};\n\nstruct sCppMacroTokens {\n\tptrArray *tarray;\n\tcppMacroInfo *macro;\n};\n\ntypedef struct sCppMacroToken {\n\tconst char *str;\n\tunsigned long lineNumber;\n\tMIOPos filePosition;\n} cppMacroToken;\n\ntypedef enum {\n\tCPREPRO_MACRO_KIND_UNDEF_ROLE,\n\tCPREPRO_MACRO_KIND_CONDITION_ROLE,\n} cPreProMacroRole;\n\nstatic roleDefinition CPREPROMacroRoles [] = {\n\tRoleTemplateUndef,\n\tRoleTemplateCondition,\n};\n\n\ntypedef enum {\n\tCPREPRO_HEADER_KIND_SYSTEM_ROLE,\n\tCPREPRO_HEADER_KIND_LOCAL_ROLE,\n} cPreProHeaderRole;\n\nstatic roleDefinition CPREPROHeaderRoles [] = {\n\tRoleTemplateSystem,\n\tRoleTemplateLocal,\n};\n\n\nstatic kindDefinition CPreProKinds [] = {\n\t{ true,  'd', \"macro\",      \"macro definitions\",\n\t  .referenceOnly = false, ATTACH_ROLES(CPREPROMacroRoles)},\n\t{ true, 'h', \"header\",     \"included header files\",\n\t  .referenceOnly = true, ATTACH_ROLES(CPREPROHeaderRoles)},\n\t{ false, 'D', \"parameter\", \"macro parameters\", },\n};\n\ntypedef enum {\n\tF_MACRODEF,\n\tCOUNT_FIELD\n} cPreProField;\n\nstatic fieldDefinition CPreProFields[COUNT_FIELD] = {\n\t{ .name = \"macrodef\",\n\t  .description = \"macro definition\",\n\t  .enabled = false },\n};\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic bool doesExaminCodeWithInIf0Branch;\nstatic bool doesExpandMacros;\n\n/*\n* CXX parser state. This is stored at the beginning of a conditional.\n* If at the exit of the conditional the state is changed then we assume\n* that no further branches should be followed.\n*/\nstatic int externalParserBlockNestLevel;\n\n\n/*  Use brace formatting to detect end of block.\n */\nstatic bool BraceFormat = false;\n\nextern void cppPushExternalParserBlock(void)\n{\n\texternalParserBlockNestLevel++;\n}\n\nextern void cppPopExternalParserBlock(void)\n{\n\texternalParserBlockNestLevel--;\n}\n\n\nstatic cppState Cpp = {\n\t.lang = LANG_IGNORE,\n\t.clientLang = LANG_IGNORE,\n\t.ungetBuffer = NULL,\n\t.ungetBufferStack = NULL,\n\t.charOrStringContents = NULL,\n\t.resolveRequired = false,\n\t.hasAtLiteralStrings = false,\n\t.hasCxxRawLiteralStrings = false,\n\t.hasSingleQuoteLiteralNumbers = false,\n\t.useClientLangDefineMacroKindIndex = false,\n\t.defineMacroKindIndex = CPREPRO_MACRO,\n\t.macroUndefRoleIndex = CPREPRO_MACRO_KIND_UNDEF_ROLE,\n\t.macroConditionRoleIndex = CPREPRO_MACRO_KIND_CONDITION_ROLE,\n\t.useClientLangMacroParamKindIndex = false,\n\t.macroParamKindIndex = CPREPRO_PARAM,\n\t.useClientLangHeaderKindIndex = false,\n\t.headerKindIndex = CPREPRO_HEADER,\n\t.headerSystemRoleIndex = CPREPRO_HEADER_KIND_SYSTEM_ROLE,\n\t.headerLocalRoleIndex = CPREPRO_HEADER_KIND_LOCAL_ROLE,\n\t.macrodefFieldIndex = FIELD_UNKNOWN,\n\t.directive = {\n\t\t.state = DRCTV_NONE,\n\t\t.accept = false,\n\t\t.name = NULL,\n\t\t.nestLevel = 0,\n\t\t.ifdef = {\n\t\t\t{\n\t\t\t\t.ignoreAllBranches = false,\n\t\t\t\t.singleBranch = false,\n\t\t\t\t.branchChosen = false,\n\t\t\t\t.ignoring = false,\n\t\t\t}\n\t\t}\n\t}  /* directive */\n};\n\n/*\n*   FUNCTION DECLARATIONS\n*/\n\nstatic hashTable *makeMacroTable (void);\nstatic cppMacroInfo * saveMacro(hashTable *table, const char * macro);\n\nstatic void cppMacroTokensDelete (cppMacroTokens *tokens);\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nextern bool cppIsBraceFormat (void)\n{\n\treturn BraceFormat;\n}\n\nextern unsigned int cppGetDirectiveNestLevel (void)\n{\n\treturn Cpp.directive.nestLevel;\n}\n\nstatic ungetBuffer *ungetBufferNew  (unsigned long lineNumber,\n\t\t\t\t\t\t\t\t\t MIOPos filePosition,\n\t\t\t\t\t\t\t\t\t cppMacroInfo *macro)\n{\n\tungetBuffer *ub = xCalloc (1, ungetBuffer);\n\tub->lineNumber = lineNumber;\n\tub->filePosition = filePosition;\n\tub->macro = macro;\n\treturn ub;\n}\n\nstatic void ungetBufferDelete (ungetBuffer *ub)\n{\n\tif (!ub)\n\t\treturn;\n\n\tif (ub->buffer)\n\t{\n\t\teFree (ub->buffer);\n\t\tub->buffer = NULL;\n\t}\n\n\teFree (ub);\n}\n\nstatic void cppInitCommon(langType clientLang,\n\t\t     const bool state, const bool hasAtLiteralStrings,\n\t\t     const bool hasCxxRawLiteralStrings,\n\t\t     const bool hasSingleQuoteLiteralNumbers,\n\t\t     int defineMacroKindIndex,\n\t\t     int macroUndefRoleIndex,\n\t\t     int macroConditionRoleIndex,\n\t\t     int macroParamKindIndex,\n\t\t     int headerKindIndex,\n\t\t     int headerSystemRoleIndex, int headerLocalRoleIndex,\n\t\t     int macrodefFieldIndex)\n{\n\tBraceFormat = state;\n\n\tCXX_DEBUG_PRINT(\"cppInit: brace format is %d\",BraceFormat);\n\n\texternalParserBlockNestLevel = 0;\n\n\tif (Cpp.lang == LANG_IGNORE)\n\t{\n\t\tlangType t;\n\n\t\tt = getNamedLanguage (\"CPreProcessor\", 0);\n\t\tinitializeParser (t);\n\t}\n\n\tCpp.clientLang = clientLang;\n\tCpp.ungetBuffer = NULL;\n\tCpp.ungetBufferStack = ptrArrayNew ((ptrArrayDeleteFunc)ungetBufferDelete);\n\n\tCXX_DEBUG_ASSERT(!Cpp.charOrStringContents,\"This string should be null when CPP is not initialized\");\n\tCpp.charOrStringContents = vStringNew();\n\n\tCpp.resolveRequired = false;\n\tCpp.hasAtLiteralStrings = hasAtLiteralStrings;\n\tCpp.hasCxxRawLiteralStrings = hasCxxRawLiteralStrings;\n\tCpp.hasSingleQuoteLiteralNumbers = hasSingleQuoteLiteralNumbers;\n\n\tif (defineMacroKindIndex != KIND_GHOST_INDEX)\n\t{\n\t\tCpp.defineMacroKindIndex = defineMacroKindIndex;\n\t\tCpp.useClientLangDefineMacroKindIndex = true;\n\n\t\tCpp.macroUndefRoleIndex = macroUndefRoleIndex;\n\t\tCpp.macroConditionRoleIndex = macroConditionRoleIndex;\n\t\tCpp.macrodefFieldIndex = macrodefFieldIndex;\n\t}\n\telse\n\t{\n\t\tCpp.defineMacroKindIndex = CPREPRO_MACRO;\n\t\tCpp.useClientLangDefineMacroKindIndex = false;\n\n\t\tCpp.macroUndefRoleIndex = CPREPRO_MACRO_KIND_UNDEF_ROLE;\n\t\tCpp.macroConditionRoleIndex = CPREPRO_MACRO_KIND_CONDITION_ROLE;\n\t\tCpp.macrodefFieldIndex = CPreProFields [F_MACRODEF].ftype;\n\t}\n\n\tif (macroParamKindIndex != KIND_GHOST_INDEX)\n\t{\n\t\tCpp.macroParamKindIndex = macroParamKindIndex;\n\t\tCpp.useClientLangMacroParamKindIndex = true;\n\t}\n\telse\n\t{\n\t\tCpp.macroParamKindIndex = CPREPRO_PARAM;\n\t\tCpp.useClientLangMacroParamKindIndex = false;\n\t}\n\n\tif (headerKindIndex != KIND_GHOST_INDEX)\n\t{\n\t\tCpp.headerKindIndex = headerKindIndex;\n\t\tCpp.useClientLangHeaderKindIndex = true;\n\n\t\tCpp.headerSystemRoleIndex = headerSystemRoleIndex;\n\t\tCpp.headerLocalRoleIndex =  headerLocalRoleIndex;\n\t}\n\telse\n\t{\n\t\tCpp.headerKindIndex = CPREPRO_HEADER;\n\t\tCpp.useClientLangHeaderKindIndex = false;\n\n\t\tCpp.headerSystemRoleIndex = CPREPRO_HEADER_KIND_SYSTEM_ROLE;\n\t\tCpp.headerLocalRoleIndex = CPREPRO_HEADER_KIND_LOCAL_ROLE;\n\t}\n\n\tCpp.directive.state     = DRCTV_NONE;\n\tCpp.directive.accept    = true;\n\tCpp.directive.nestLevel = 0;\n\n\tCpp.directive.ifdef [0].ignoreAllBranches = false;\n\tCpp.directive.ifdef [0].singleBranch = false;\n\tCpp.directive.ifdef [0].branchChosen = false;\n\tCpp.directive.ifdef [0].ignoring     = false;\n\n\tCpp.directive.name = vStringNewOrClear (Cpp.directive.name);\n\n\tCpp.macroInUse = NULL;\n\tCpp.fileMacroTable =\n\t\t(doesExpandMacros\n\t\t && isFieldEnabled (FIELD_SIGNATURE)\n\t\t && isFieldEnabled (Cpp.macrodefFieldIndex)\n\t\t && (getLanguageCorkUsage ((clientLang == LANG_IGNORE)\n\t\t\t\t\t\t\t\t   ? Cpp.lang\n\t\t\t\t\t\t\t\t   : clientLang) & CORK_SYMTAB))\n\t\t? makeMacroTable ()\n\t\t: NULL;\n}\n\nextern void cppInit (const bool state, const bool hasAtLiteralStrings,\n\t\t     const bool hasCxxRawLiteralStrings,\n\t\t     const bool hasSingleQuoteLiteralNumbers,\n\t\t     int defineMacroKindIndex,\n\t\t     int macroUndefRoleIndex,\n\t\t     int macroConditionRoleIndex,\n\t\t     int macroParamKindIndex,\n\t\t     int headerKindIndex,\n\t\t     int headerSystemRoleIndex, int headerLocalRoleIndex,\n\t\t     int macrodefFieldIndex)\n{\n\tlangType client = getInputLanguage ();\n\n\tcppInitCommon (client, state, hasAtLiteralStrings,\n\t\t\t\t   hasCxxRawLiteralStrings, hasSingleQuoteLiteralNumbers,\n\t\t\t\t   defineMacroKindIndex, macroUndefRoleIndex, macroConditionRoleIndex,\n\t\t\t\t   macroParamKindIndex,\n\t\t\t\t   headerKindIndex, headerSystemRoleIndex, headerLocalRoleIndex,\n\t\t\t\t   macrodefFieldIndex);\n}\n\nstatic void cppClearMacroInUse (cppMacroInfo **pM)\n{\n\tfor (cppMacroInfo *p = *pM; p; p = p->next)\n\t{\n\t\tCXX_DEBUG_PRINT(\"Macro <%p> clear useCount: %d -> 0\", p, p->useCount);\n\t\tp->useCount = 0;\n\t}\n\t*pM = NULL;\n}\n\nextern void cppTerminate (void)\n{\n\tif (Cpp.directive.name != NULL)\n\t{\n\t\tvStringDelete (Cpp.directive.name);\n\t\tCpp.directive.name = NULL;\n\t}\n\n\tungetBufferDelete (Cpp.ungetBuffer); /* NULL is acceptable */\n\tCpp.ungetBuffer = NULL;\n\tptrArrayDelete (Cpp.ungetBufferStack);\n\tCpp.ungetBufferStack = NULL;\n\n\tif(Cpp.charOrStringContents)\n\t{\n\t\tvStringDelete(Cpp.charOrStringContents);\n\t\tCpp.charOrStringContents = NULL;\n\t}\n\n\tCpp.clientLang = LANG_IGNORE;\n\n\tcppClearMacroInUse (&Cpp.macroInUse);\n\n\tif (Cpp.fileMacroTable)\n\t{\n\t\thashTableDelete (Cpp.fileMacroTable);\n\t\tCpp.fileMacroTable = NULL;\n\t}\n}\n\nextern void cppBeginStatement (void)\n{\n\tCpp.resolveRequired = true;\n}\n\nextern void cppEndStatement (void)\n{\n\tCpp.resolveRequired = false;\n}\n\n/*\n*   Scanning functions\n*\n*   This section handles preprocessor directives.  It strips out all\n*   directives and may emit a tag for #define directives.\n*/\n\n/*  This puts a character back into the input queue for the input File. */\nstatic void ungetBufferUngetc (ungetBuffer *ungetBuffer, const int c, vString *charOrStringContents)\n{\n\tif (c == STRING_SYMBOL || c == CHAR_SYMBOL)\n\t{\n\t\tAssert(charOrStringContents != NULL);\n\t\tcppUngetc(c == STRING_SYMBOL ? '\"' : '\\'');\n\t\tcppUngetString(vStringValue(charOrStringContents), vStringLength(charOrStringContents));\n\t\tcppUngetc(c == STRING_SYMBOL ? '\"' : '\\'');\n\t\tvStringClear(charOrStringContents);\n\t\treturn;\n\t}\n\telse if (c == EOF)\n\t{\n\t\treturn;\n\t}\n\n\tAssert((unsigned int)c <= 0xff);\n\tunsigned char u = (unsigned char)c;\n\n\tif(!ungetBuffer->pointer)\n\t{\n\t\t// no unget data\n\t\tif(!ungetBuffer->buffer)\n\t\t{\n\t\t\tungetBuffer->buffer = eMalloc(8 * sizeof(*(ungetBuffer->buffer)));\n\t\t\tungetBuffer->size = 8;\n\t\t}\n\t\tAssert(ungetBuffer->size > 0);\n\t\tungetBuffer->pointer = ungetBuffer->buffer + ungetBuffer->size - 1;\n\t\t*(ungetBuffer->pointer) = u;\n\t\tungetBuffer->dataSize = 1;\n\t\treturn;\n\t}\n\n\t// Already have some unget data in the buffer. Must prepend.\n\tAssert(ungetBuffer->buffer);\n\tAssert(ungetBuffer->size > 0);\n\tAssert(ungetBuffer->dataSize > 0);\n\tAssert(ungetBuffer->pointer >= ungetBuffer->buffer);\n\n\tif(ungetBuffer->pointer == ungetBuffer->buffer)\n\t{\n\t\tungetBuffer->size += 8;\n\t\tunsigned char * tmp = eMalloc(ungetBuffer->size * sizeof(*(ungetBuffer->buffer)));\n\t\tmemcpy(tmp+8,ungetBuffer->pointer,ungetBuffer->dataSize * sizeof(*(ungetBuffer->buffer)));\n\t\teFree(ungetBuffer->buffer);\n\t\tungetBuffer->buffer = tmp;\n\t\tungetBuffer->pointer = tmp + 7;\n\t} else {\n\t\tungetBuffer->pointer--;\n\t}\n\n\t*(ungetBuffer->pointer) = u;\n\tungetBuffer->dataSize++;\n}\n\nstatic int ungetBufferSize (ungetBuffer *ungetBuffer)\n{\n\treturn ungetBuffer->size;\n}\n\nstatic void ungetBufferUngetString(ungetBuffer *ungetBuffer, const char * string, int len)\n{\n\tif(!string)\n\t\treturn;\n\tif(len < 1)\n\t\treturn;\n\n\tif(!ungetBuffer->pointer)\n\t{\n\t\t// no unget data\n\t\tif(!ungetBuffer->buffer)\n\t\t{\n\t\t\tungetBuffer->size = 8 + len;\n\t\t\tungetBuffer->buffer = eMalloc(ungetBuffer->size * sizeof(*(ungetBuffer->buffer)));\n\t\t} else if(ungetBuffer->size < len)\n\t\t{\n\t\t\tungetBuffer->size = 8 + len;\n\t\t\tungetBuffer->buffer = eRealloc(ungetBuffer->buffer,\n\t\t\t\t\t\t\t\t\t\t   ungetBuffer->size * sizeof(*(ungetBuffer->buffer)));\n\t\t}\n\t\tungetBuffer->pointer = ungetBuffer->buffer + ungetBuffer->size - len;\n\t} else {\n\t\t// Already have some unget data in the buffer. Must prepend.\n\t\tAssert(ungetBuffer->buffer);\n\t\tAssert(ungetBuffer->size > 0);\n\t\tAssert(ungetBuffer->dataSize > 0);\n\t\tAssert(ungetBuffer->pointer >= ungetBuffer->buffer);\n\n\t\tif(ungetBuffer->size < (ungetBuffer->dataSize + len))\n\t\t{\n\t\t\tungetBuffer->size = 8 + len + ungetBuffer->dataSize;\n\t\t\tunsigned char * tmp = eMalloc(ungetBuffer->size * sizeof(*(ungetBuffer->buffer)));\n\t\t\tmemcpy(tmp + 8 + len,ungetBuffer->pointer,ungetBuffer->dataSize * sizeof(*(ungetBuffer->buffer)));\n\t\t\teFree(ungetBuffer->buffer);\n\t\t\tungetBuffer->buffer = tmp;\n\t\t\tungetBuffer->pointer = tmp + 8;\n\t\t} else {\n\t\t\tungetBuffer->pointer -= len;\n\t\t\tAssert(ungetBuffer->pointer >= ungetBuffer->buffer);\n\t\t}\n\t}\n\n\tunsigned char* p = ungetBuffer->pointer;\n\tconst char * s = string;\n\tconst char * e = string + len;\n\n\twhile(s < e)\n\t\t*p++ = (unsigned char)(*s++);\n\n\tungetBuffer->dataSize += len;\n}\n\nstatic int ungetBufferGetcFromUngetBuffer (ungetBuffer *ungetBuffer)\n{\n\tif(ungetBuffer->pointer)\n\t{\n\t\tAssert(ungetBuffer->buffer);\n\t\tAssert(ungetBuffer->size > 0);\n\t\tAssert(ungetBuffer->dataSize > 0);\n\n\t\tint c = *(ungetBuffer->pointer);\n\t\tungetBuffer->dataSize--;\n\t\tif(ungetBuffer->dataSize > 0)\n\t\t\tungetBuffer->pointer++;\n\t\telse\n\t\t\tungetBuffer->pointer = NULL;\n\t\treturn c;\n\t}\n\treturn EOF;\n}\n\nextern void cppUngetc (const int c)\n{\n\tif (Cpp.ungetBuffer == NULL)\n\t\tCpp.ungetBuffer = ungetBufferNew (getInputLineNumber(),\n\t\t\t\t\t\t\t\t\t\t  getInputFilePosition(),\n\t\t\t\t\t\t\t\t\t\t  NULL);\n\tungetBufferUngetc (Cpp.ungetBuffer , c, Cpp.charOrStringContents);\n}\n\nextern int cppUngetBufferSize(void)\n{\n\tif (Cpp.ungetBuffer == NULL)\n\t\treturn 0;\n\n\tint size = ungetBufferSize (Cpp.ungetBuffer);\n\tfor (size_t i = 0; i < ptrArrayCount (Cpp.ungetBufferStack); i++)\n\t{\n\t\tungetBuffer *ub = ptrArrayItem (Cpp.ungetBufferStack, i);\n\t\ti += ungetBufferSize (ub);\n\t}\n\treturn size;\n}\n\n/*  This puts an entire string back into the input queue for the input File. */\nextern void cppUngetString(const char * string, int len)\n{\n\tif (Cpp.ungetBuffer == NULL)\n\t\tCpp.ungetBuffer = ungetBufferNew (getInputLineNumber(),\n\t\t\t\t\t\t\t\t\t\t  getInputFilePosition(),\n\t\t\t\t\t\t\t\t\t\t  NULL);\n\tungetBufferUngetString (Cpp.ungetBuffer, string, len);\n}\n\nextern void cppUngetMacroTokens (cppMacroTokens *tokens)\n{\n\tAssert (tokens);\n\n\tcppMacroInfo *macro = tokens->macro;\n\n\tif (macro->useCount == 0)\n\t{\n\t\tcppMacroInfo *m = Cpp.macroInUse;\n\t\tCpp.macroInUse = macro;\n\t\tmacro->next = m;\n\t}\n\tmacro->useCount++;\n\n\tCXX_DEBUG_PRINT(\"Macro <%p> increment useCount: %d->%d\", macro,\n\t\t\t\t\t(macro->useCount - 1), macro->useCount);\n\n\tptrArray *a = tokens->tarray;\n\tif (ptrArrayIsEmpty (a))\n\t{\n\t\tcppMacroTokensDelete (tokens);\n\t\treturn;\n\t}\n\n\tif (Cpp.ungetBuffer)\n\t{\n\t\tptrArrayAdd(Cpp.ungetBufferStack, Cpp.ungetBuffer);\n\t\tCpp.ungetBuffer = NULL;\n\t}\n\n\tfor(size_t i = ptrArrayCount (a); i > 0; i--)\n\t{\n\t\tcppMacroToken *t = ptrArrayItem (a, i - 1);\n\t\tungetBuffer *ub = ungetBufferNew(t->lineNumber, t->filePosition,\n\t\t\t\t\t\t\t\t\t\t macro);\n\t\tungetBufferUngetString (ub, t->str, strlen (t->str));\n\t\tptrArrayAdd(Cpp.ungetBufferStack, ub);\n\t}\n\n\tif (!ptrArrayIsEmpty (Cpp.ungetBufferStack))\n\t\tCpp.ungetBuffer = ptrArrayRemoveLast (Cpp.ungetBufferStack);\n\tcppMacroTokensDelete (tokens);\n}\n\nstatic int cppGetcFromUngetBufferOrFile(void)\n{\n retry:\n\tif (Cpp.ungetBuffer)\n\t{\n\t\tint c = ungetBufferGetcFromUngetBuffer (Cpp.ungetBuffer);\n\t\tif (c != EOF)\n\t\t\treturn c;\n\n\t\tungetBufferDelete (Cpp.ungetBuffer);\n\t\tCpp.ungetBuffer = NULL;\n\t\tif (!ptrArrayIsEmpty (Cpp.ungetBufferStack))\n\t\t{\n\t\t\tCpp.ungetBuffer = ptrArrayRemoveLast (Cpp.ungetBufferStack);\n\t\t\tgoto retry;\n\t\t}\n\t}\n\n\t/* Or */\n\n\tif (Cpp.macroInUse)\n\t\tcppClearMacroInUse (&Cpp.macroInUse);\n\treturn getcFromInputFile();\n}\n\nextern unsigned long cppGetInputLineNumber (void)\n{\n\tif (Cpp.ungetBuffer)\n\t\treturn Cpp.ungetBuffer->lineNumber;\n\treturn getInputLineNumber();\n}\n\nextern MIOPos cppGetInputFilePosition (void)\n{\n\tif (Cpp.ungetBuffer)\n\t\treturn Cpp.ungetBuffer->filePosition;\n\treturn getInputFilePosition();\n}\n\n\n/*  Reads a directive, whose first character is given by \"c\", into \"name\".\n */\nstatic bool readDirective (int c, char *const name, unsigned int maxLength)\n{\n\tunsigned int i;\n\n\tfor (i = 0  ;  i < maxLength - 1  ;  ++i)\n\t{\n\t\tif (i > 0)\n\t\t{\n\t\t\tc = cppGetcFromUngetBufferOrFile ();\n\t\t\tif (c == EOF  ||  ! isalpha (c))\n\t\t\t{\n\t\t\t\tcppUngetc (c);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tname [i] = c;\n\t}\n\tname [i] = '\\0';  /* null terminate */\n\n\treturn (bool) isspacetab (c);\n}\n\n/*  Reads an identifier, whose first character is given by \"c\", into \"tag\",\n *  together with the file location and corresponding line number.\n */\nstatic void readIdentifier (int c, vString *const name)\n{\n\tvStringClear (name);\n\tdo\n\t{\n\t\tvStringPut (name, c);\n\t\tc = cppGetcFromUngetBufferOrFile ();\n\t} while (c != EOF  && cppIsident (c));\n\tcppUngetc (c);\n}\n\nstatic void readFilename (int c, vString *const name)\n{\n\tint c_end = (c == '<')? '>': '\"';\n\n\tvStringClear (name);\n\n\twhile (c = cppGetcFromUngetBufferOrFile (), (c != EOF && c != c_end && c != '\\n'))\n\t\tvStringPut (name, c);\n}\n\nstatic conditionalInfo *currentConditional (void)\n{\n\treturn &Cpp.directive.ifdef [Cpp.directive.nestLevel];\n}\n\nstatic bool isIgnore (void)\n{\n\treturn Cpp.directive.ifdef [Cpp.directive.nestLevel].ignoring;\n}\n\nstatic bool setIgnore (const bool ignore)\n{\n\treturn Cpp.directive.ifdef [Cpp.directive.nestLevel].ignoring = ignore;\n}\n\nstatic bool isIgnoreBranch (void)\n{\n\tconditionalInfo *const ifdef = currentConditional ();\n\n\t/*  Force a single branch if an incomplete statement is discovered\n\t *  en route. This may have allowed earlier branches containing complete\n\t *  statements to be followed, but we must follow no further branches.\n\t */\n\n\t/*\n\t* CXX: Force a single branch if the external parser (cxx) block nest level at the beginning\n\t* of this conditional is not equal to the current block nest level (at exit of the first branch).\n\t*\n\t* Follow both branches example: (same state at enter and exit)\n\t*\n\t* #if something\n\t*     xxxxx;\n\t* #else\n\t*     yyyy;\n\t* #endif\n\t*\n\t* Follow single branch example: (different block level at enter and exit)\n\t*\n\t*    if {\n\t* #if something\n    *    } else x;\n\t* #else\n\t*    }\n\t* #endif\n\t*/\n\n\tif (\n\t\t\t(Cpp.resolveRequired || (ifdef->enterExternalParserBlockNestLevel != externalParserBlockNestLevel)) &&\n\t\t\t(!BraceFormat)\n\t\t)\n\t{\n\t\tCXX_DEBUG_PRINT(\"Choosing single branch\");\n\t\tifdef->singleBranch = true;\n\t}\n\n\t/*  We will ignore this branch in the following cases:\n\t *\n\t *  1.  We are ignoring all branches (conditional was within an ignored\n\t *        branch of the parent conditional)\n\t *  2.  A branch has already been chosen and either of:\n\t *      a.  A statement was incomplete upon entering the conditional\n\t *      b.  A statement is incomplete upon encountering a branch\n\t */\n\treturn (bool) (ifdef->ignoreAllBranches ||\n\t\t\t\t\t (ifdef->branchChosen  &&  ifdef->singleBranch));\n}\n\nstatic void chooseBranch (void)\n{\n\tif (! BraceFormat)\n\t{\n\t\tconditionalInfo *const ifdef = currentConditional ();\n\n\t\tifdef->branchChosen = (bool) (ifdef->singleBranch ||\n\t\t\t\t\t\t\t\t\t\tCpp.resolveRequired);\n\t}\n}\n\n/*  Pushes one nesting level for an #if directive, indicating whether or not\n *  the branch should be ignored and whether a branch has already been chosen.\n */\nstatic bool pushConditional (const bool firstBranchChosen)\n{\n\tconst bool ignoreAllBranches = isIgnore ();  /* current ignore */\n\tbool ignoreBranch = false;\n\n\tif (Cpp.directive.nestLevel < (unsigned int) MaxCppNestingLevel - 1)\n\t{\n\t\tconditionalInfo *ifdef;\n\n\t\t++Cpp.directive.nestLevel;\n\t\tifdef = currentConditional ();\n\n\t\t/*  We take a snapshot of whether there is an incomplete statement in\n\t\t *  progress upon encountering the preprocessor conditional. If so,\n\t\t *  then we will flag that only a single branch of the conditional\n\t\t *  should be followed.\n\t\t */\n\t\tifdef->ignoreAllBranches = ignoreAllBranches;\n\t\tifdef->singleBranch      = Cpp.resolveRequired;\n\t\tifdef->branchChosen      = firstBranchChosen;\n\t\tifdef->ignoring = (bool) (ignoreAllBranches || (\n\t\t\t\t! firstBranchChosen  &&  ! BraceFormat  &&\n\t\t\t\t(ifdef->singleBranch || !doesExaminCodeWithInIf0Branch)));\n\t\tifdef->enterExternalParserBlockNestLevel = externalParserBlockNestLevel;\n\t\tifdef->asmArea.line = 0;\n\t\tignoreBranch = ifdef->ignoring;\n\t}\n\treturn ignoreBranch;\n}\n\n/*  Pops one nesting level for an #endif directive.\n */\nstatic bool popConditional (void)\n{\n\tif (Cpp.directive.nestLevel > 0)\n\t\t--Cpp.directive.nestLevel;\n\n\treturn isIgnore ();\n}\n\nstatic bool doesCPreProRunAsStandaloneParser (int kind)\n{\n\tif (kind == CPREPRO_HEADER)\n\t\treturn !Cpp.useClientLangDefineMacroKindIndex;\n\telse if (kind == CPREPRO_MACRO)\n\t\treturn !Cpp.useClientLangHeaderKindIndex;\n\telse if (kind == CPREPRO_PARAM)\n\t\treturn !Cpp.useClientLangMacroParamKindIndex;\n\telse\n\t{\n\t\tAssertNotReached();\n\t\treturn true;\n\t}\n}\n\nstatic int makeDefineTag (const char *const name, const char* const signature, bool undef)\n{\n\tbool standing_alone = doesCPreProRunAsStandaloneParser(CPREPRO_MACRO);\n\tlangType lang = standing_alone ? Cpp.lang: Cpp.clientLang;\n\tconst bool isFileScope = (bool) (! isInputHeaderFile ());\n\n\tif (!isLanguageEnabled (lang))\n\t\t\treturn CORK_NIL;\n\n\tAssert (Cpp.defineMacroKindIndex != KIND_GHOST_INDEX);\n\n\tif (isFileScope && !isXtagEnabled(XTAG_FILE_SCOPE))\n\t\treturn CORK_NIL;\n\n\tif (undef && (Cpp.macroUndefRoleIndex == ROLE_DEFINITION_INDEX))\n\t\treturn CORK_NIL;\n\n\tif (! isLanguageKindEnabled (lang,\n\t\t\t\t\t\t\t\t Cpp.defineMacroKindIndex))\n\t\treturn CORK_NIL;\n\n\tif (\n\t\t/* condition for definition tag */\n\t\t(!undef)\n\t\t|| /* condition for reference tag */\n\t\t(undef && isXtagEnabled(XTAG_REFERENCE_TAGS) &&\n\t\t isLanguageRoleEnabled(lang, Cpp.defineMacroKindIndex,\n\t\t\t\t\t\t\t   Cpp.macroUndefRoleIndex)))\n\t{\n\t\ttagEntryInfo e;\n\t\tint r;\n\n\t\tif (standing_alone)\n\t\t\tpushLanguage (Cpp.lang);\n\n\t\tif (undef)\n\t\t\tinitRefTagEntry (&e, name, Cpp.defineMacroKindIndex,\n\t\t\t\t\t\t\t Cpp.macroUndefRoleIndex);\n\t\telse\n\t\t\tinitTagEntry (&e, name, Cpp.defineMacroKindIndex);\n\t\te.isFileScope  = isFileScope;\n\t\tif (isFileScope)\n\t\t\tmarkTagExtraBit (&e, XTAG_FILE_SCOPE);\n\t\te.truncateLineAfterTag = true;\n\t\te.extensionFields.signature = signature;\n\n\t\tr = makeTagEntry (&e);\n\n\t\tif (standing_alone)\n\t\t\tpopLanguage ();\n\n\t\treturn r;\n\t}\n\treturn CORK_NIL;\n}\n\nstatic void makeIncludeTag (const char *const name, bool systemHeader)\n{\n\tbool standing_alone = doesCPreProRunAsStandaloneParser(CPREPRO_HEADER);\n\tlangType lang = standing_alone ? Cpp.lang: Cpp.clientLang;\n\ttagEntryInfo e;\n\tint role_index;\n\n\tif (!isLanguageEnabled (lang))\n\t\treturn;\n\n\tAssert (Cpp.headerKindIndex != KIND_GHOST_INDEX);\n\n\trole_index = systemHeader? Cpp.headerSystemRoleIndex: Cpp.headerLocalRoleIndex;\n\tif (role_index == ROLE_DEFINITION_INDEX)\n\t\treturn;\n\n\tif (!isXtagEnabled (XTAG_REFERENCE_TAGS))\n\t\treturn;\n\n\tif (!isLanguageKindEnabled(lang, Cpp.headerKindIndex))\n\t\treturn;\n\n\tif (isLanguageRoleEnabled(lang, Cpp.headerKindIndex, role_index))\n\t{\n\t\tif (standing_alone)\n\t\t\tpushLanguage (Cpp.lang);\n\n\t\tinitRefTagEntry (&e, name, Cpp.headerKindIndex, role_index);\n\t\te.isFileScope  = false;\n\t\te.truncateLineAfterTag = true;\n\t\tmakeTagEntry (&e);\n\n\t\tif (standing_alone)\n\t\t\tpopLanguage ();\n\t}\n}\n\nstatic int makeParamTag (vString *name, short nth, bool placeholder)\n{\n\tbool standing_alone = doesCPreProRunAsStandaloneParser(CPREPRO_MACRO);\n\n\tAssert (Cpp.macroParamKindIndex != KIND_GHOST_INDEX);\n\n\tif (standing_alone)\n\t\tpushLanguage (Cpp.lang);\n\n\ttagEntryInfo e;\n\tinitTagEntry (&e, vStringValue (name), Cpp.macroParamKindIndex);\n\tupdateTagLine (&e, cppGetInputLineNumber (), cppGetInputFilePosition ());\n\te.extensionFields.nth = nth;\n\tif (placeholder)\n\t\tmarkTagAsPlaceholder (&e, placeholder);\n\tint r = makeTagEntry(&e);\n\n\tif (standing_alone)\n\t\tpopLanguage ();\n\n\treturn r;\n}\n\nstatic void makeSignatureStringFromParameters (vString * buffer, intArray *parameters)\n{\n\tvStringPut(buffer, '(');\n\tfor (size_t i = 0; i < intArrayCount (parameters); i++)\n\t{\n\t\tint pindex = intArrayItem (parameters, i);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (pindex);\n\t\tif (e)\n\t\t{\n\t\t\tvStringCatS (buffer, e->name);\n\t\t\tvStringPut (buffer, ',');\n\t\t}\n\t}\n\tif (vStringLast (buffer) == ',')\n\t\tvStringChop (buffer);\n\tvStringPut (buffer, ')');\n}\n\nstatic void patchScopeFieldOfParameters(int from, int to, int parentIndex)\n{\n\tfor (int pindex = from; pindex < to; pindex++)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (pindex);\n\t\tif (e)\n\t\t\te->extensionFields.scopeIndex = parentIndex;\n\t}\n}\n\nstatic int directiveDefine (const int c, bool undef)\n{\n\t// FIXME: We could possibly handle the macros here!\n\t//        However we'd need a separate hash table for macros of the current file\n\t//        to avoid breaking the \"global\" ones.\n\n\tint r = CORK_NIL;\n\n\tif (cppIsident1 (c))\n\t{\n\t\treadIdentifier (c, Cpp.directive.name);\n\t\tif (! isIgnore ())\n\t\t{\n\t\t\tunsigned long \tlineNumber = cppGetInputLineNumber ();\n\t\t\tMIOPos filePosition = cppGetInputFilePosition ();\n\t\t\tint p = cppGetcFromUngetBufferOrFile ();\n\t\t\tshort nth = 0;\n\n\t\t\tif (p == '(')\n\t\t\t{\n\t\t\t\tintArray *params = intArrayNew ();\n\t\t\t\tvString *param = vStringNew ();\n\t\t\t\tint param_start = (int)countEntryInCorkQueue();\n\t\t\t\tdo {\n\t\t\t\t\tp = cppGetcFromUngetBufferOrFile ();\n\t\t\t\t\tif (isalnum(p) || p == '_' || p == '$'\n\t\t\t\t\t\t/* Handle variadic macros like (a,...) */\n\t\t\t\t\t\t|| p == '.')\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (param, p);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (vStringLength (param) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tbool gnuext_placeholder = false;\n\t\t\t\t\t\tif (vStringLength (param) > 3\n\t\t\t\t\t\t\t&& strcmp(vStringValue (param) + vStringLength (param) - 3,\n\t\t\t\t\t\t\t\t\t  \"...\")  == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* args... in GNU cpp extension\n\t\t\t\t\t\t\t *\n\t\t\t\t\t\t\t * #define debug(format, args...) fprintf (stderr, format, args)\n\t\t\t\t\t\t\t *\n\t\t\t\t\t\t\t * In this case, args should be tagged. However the signature field\n\t\t\t\t\t\t\t * for debug must be \"(format,args...)\".\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tvString *nodots = vStringNewNInit (vStringValue (param),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   vStringLength (param) - 3);\n\t\t\t\t\t\t\tmakeParamTag (nodots, nth, false);\n\t\t\t\t\t\t\tvStringDelete (nodots);\n\t\t\t\t\t\t\tgnuext_placeholder = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tint r = makeParamTag (param, nth++,\n\t\t\t\t\t\t\t\t\t\t\t  vStringChar(param, 0) == '.'\n\t\t\t\t\t\t\t\t\t\t\t  || gnuext_placeholder);\n\t\t\t\t\t\tintArrayAdd (params, r);\n\t\t\t\t\t\tvStringClear (param);\n\t\t\t\t\t}\n\t\t\t\t\tif (p == '\\\\')\n\t\t\t\t\t\tcppGetcFromUngetBufferOrFile (); /* Throw away the next char */\n\t\t\t\t} while (p != ')' && p != EOF);\n\t\t\t\tvStringDelete (param);\n\n\t\t\t\tint param_end = (int)countEntryInCorkQueue();\n\t\t\t\tif (p == ')')\n\t\t\t\t{\n\t\t\t\t\tvString *signature = vStringNew ();\n\t\t\t\t\tmakeSignatureStringFromParameters (signature, params);\n\t\t\t\t\tr = makeDefineTag (vStringValue (Cpp.directive.name), vStringValue (signature), undef);\n\t\t\t\t\tvStringDelete (signature);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tr = makeDefineTag (vStringValue (Cpp.directive.name), NULL, undef);\n\t\t\t\tintArrayDelete (params);\n\n\t\t\t\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\t\t\t\tif (e)\n\t\t\t\t{\n\t\t\t\t\tupdateTagLine (e, lineNumber, filePosition);\n\t\t\t\t\tpatchScopeFieldOfParameters (param_start, param_end, r);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcppUngetc (p);\n\t\t\t\tr = makeDefineTag (vStringValue (Cpp.directive.name), NULL, undef);\n\t\t\t}\n\t\t}\n\t}\n\tCpp.directive.state = DRCTV_NONE;\n\n\tif (r != CORK_NIL && Cpp.fileMacroTable)\n\t\tregisterEntry (r);\n\treturn r;\n}\n\nstatic void directiveUndef (const int c)\n{\n\tif (isXtagEnabled (XTAG_REFERENCE_TAGS))\n\t{\n\t\tdirectiveDefine (c, true);\n\t}\n\telse\n\t{\n\t\tCpp.directive.state = DRCTV_NONE;\n\t}\n}\n\nstatic void directivePragma (int c)\n{\n\tif (cppIsident1 (c))\n\t{\n\t\treadIdentifier (c, Cpp.directive.name);\n\t\tif (stringMatch (vStringValue (Cpp.directive.name), \"weak\"))\n\t\t{\n\t\t\t/* generate macro tag for weak name */\n\t\t\tdo\n\t\t\t{\n\t\t\t\tc = cppGetcFromUngetBufferOrFile ();\n\t\t\t} while (c == SPACE);\n\t\t\tif (cppIsident1 (c))\n\t\t\t{\n\t\t\t\treadIdentifier (c, Cpp.directive.name);\n\t\t\t\tmakeDefineTag (vStringValue (Cpp.directive.name), NULL, false);\n\t\t\t}\n\t\t}\n\t}\n\tCpp.directive.state = DRCTV_NONE;\n}\n\n/*\n * __ASSEMBLER__ (\"3.7.1 Standard Predefined Macros\" in GNU cpp info),\n * __ASSEMBLY__\t (Used in Linux kernel)\n */\nstatic bool isAssemblerBlock (int c)\n{\n\tif (c != '_')\n\t\treturn false;\n\n\tbool r = false;\n\tvString *cond = vStringNew ();\n\treadIdentifier (c, cond);\n\tif (strcmp (vStringValue (cond), \"__ASSEMBLER__\") == 0\n\t\t|| strcmp (vStringValue (cond), \"__ASSEMBLY__\") == 0)\n\t\tr = true;\n\n\tCXX_DEBUG_PRINT(\"ASSEMBLER[%s]: %s\", r? \"true\": \"false\", vStringValue(cond));\n\n\tsize_t len = vStringLength (cond);\n\t/* Pushing back to the stream.\n\t * The first character is not read in this function.\n\t * So don't touch the character here. */\n\tfor (size_t i = len; i > 1; i--)\n\t{\n\t\tc = vStringChar (cond, i - 1);\n\t\tcppUngetc (c);\n\t}\n\n\tvStringDelete (cond);\n\treturn r;\n}\n\nstatic bool directiveIf (const int c, enum eIfSubstate if_substate)\n{\n\tstatic langType asmLang = LANG_IGNORE;\n\tif (asmLang == LANG_IGNORE)\n\t\tasmLang = getNamedLanguage (\"Asm\", 0);\n\n\tDebugStatement ( const bool ignore0 = isIgnore (); )\n\tbool firstBranchChosen = (bool) (c != '0');\n\tbool assemblerBlock = false;\n\tif (Cpp.clientLang != asmLang && firstBranchChosen)\n\t{\n\t\tassemblerBlock = isAssemblerBlock(c);\n\t\tif (assemblerBlock && if_substate != IF_IFNDEF)\n\t\t\tfirstBranchChosen = false;\n\t}\n\n\tCXX_DEBUG_PRINT(\"firstBranchChosen: %d\", firstBranchChosen);\n\tconst bool ignore = pushConditional (firstBranchChosen);\n\tif (assemblerBlock)\n\t{\n\t\tconditionalInfo *ifdef = currentConditional ();\n\t\tifdef->asmArea.ifSubstate = if_substate;\n\t\tifdef->asmArea.line = cppGetInputLineNumber ();\n\t}\n\n\tCpp.directive.state = DRCTV_NONE;\n\tDebugStatement ( debugCppNest (true, Cpp.directive.nestLevel);\n\t                 if (ignore != ignore0) debugCppIgnore (ignore); )\n\n\treturn ignore;\n}\n\nstatic void directiveElif (const int c)\n{\n\tCpp.directive.state = DRCTV_NONE;\n}\n\nstatic void directiveInclude (const int c)\n{\n\tif (c == '<' || c == '\"')\n\t{\n\t\treadFilename (c, Cpp.directive.name);\n\t\tif ((! isIgnore ()) && vStringLength (Cpp.directive.name))\n\t\t\tmakeIncludeTag (vStringValue (Cpp.directive.name),\n\t\t\t\t\tc == '<');\n\t}\n\tCpp.directive.state = DRCTV_NONE;\n}\n\nstatic void promiseOrPrepareAsm (conditionalInfo *ifdef, enum eIfSubstate currentState)\n{\n\tif (!ifdef->asmArea.line)\n\t\treturn;\n\n\tif (((ifdef->asmArea.ifSubstate == IF_IF || ifdef->asmArea.ifSubstate == IF_IFDEF)\n\t\t && (currentState == IF_ELSE || currentState == IF_ELIF || currentState == IF_ENDIF))\n\t\t|| ((ifdef->asmArea.ifSubstate == IF_ELSE)\n\t\t\t&& (currentState == IF_ENDIF)))\n\t{\n\t\tunsigned long start = ifdef->asmArea.line + 1;\n\t\tunsigned long end = cppGetInputLineNumber ();\n\n\t\tif (start < end)\n\t\t\tmakePromise (\"Asm\", start, 0, end, 0, start);\n\n\t\tifdef->asmArea.line = 0;\n\t}\n\telse if (ifdef->asmArea.ifSubstate == IF_IFNDEF)\n\t{\n\t\tif (currentState == IF_ELIF)\n\t\t\tifdef->asmArea.line = 0;\n\t\telse if (currentState == IF_ELSE)\n\t\t{\n\t\t\tifdef->asmArea.ifSubstate = IF_ELSE;\n\t\t\tifdef->asmArea.line = cppGetInputLineNumber ();\n\t\t}\n\t}\n}\n\nstatic bool directiveHash (const int c)\n{\n\tbool ignore = false;\n\tchar directive [MaxDirectiveName];\n\tDebugStatement ( const bool ignore0 = isIgnore (); )\n\n\treadDirective (c, directive, MaxDirectiveName);\n\tif (stringMatch (directive, \"define\"))\n\t\tCpp.directive.state = DRCTV_DEFINE;\n\telse if (stringMatch (directive, \"include\"))\n\t\tCpp.directive.state = DRCTV_INCLUDE;\n\telse if (stringMatch (directive, \"undef\"))\n\t\tCpp.directive.state = DRCTV_UNDEF;\n\telse if (strncmp (directive, \"if\", (size_t) 2) == 0)\n\t{\n\t\tCpp.directive.state = DRCTV_IF;\n\t\tCpp.directive.ifsubstate = IF_IF;\n\t\tif (directive[2] == 'd')\n\t\t\tCpp.directive.ifsubstate = IF_IFDEF;\n\t\telse if (directive[2] == 'n')\n\t\t\tCpp.directive.ifsubstate = IF_IFNDEF;\n\t}\n\telse if (stringMatch (directive, \"elif\")  ||\n\t\t\tstringMatch (directive, \"else\"))\n\t{\n\t\tenum eIfSubstate s = (directive[2] == 's')? IF_ELSE: IF_ELIF;\n\t\tconditionalInfo *ifdef = currentConditional ();\n\t\tpromiseOrPrepareAsm (ifdef, s);\n\n\t\tignore = setIgnore (isIgnoreBranch ());\n\t\tCXX_DEBUG_PRINT(\"Found #elif or #else: ignore is %d\",ignore);\n\t\tif (! ignore  &&  s == IF_ELSE)\n\t\t\tchooseBranch ();\n\t\tCpp.directive.state = (s == IF_ELIF)? DRCTV_ELIF: DRCTV_NONE;\n\t\tDebugStatement ( if (ignore != ignore0) debugCppIgnore (ignore); )\n\t}\n\telse if (stringMatch (directive, \"endif\"))\n\t{\n\t\tconditionalInfo *ifdef = currentConditional ();\n\t\tpromiseOrPrepareAsm (ifdef, IF_ENDIF);\n\n\t\tDebugStatement ( debugCppNest (false, Cpp.directive.nestLevel); )\n\t\tignore = popConditional ();\n\t\tCpp.directive.state = DRCTV_NONE;\n\t\tDebugStatement ( if (ignore != ignore0) debugCppIgnore (ignore); )\n\t}\n\telse if (stringMatch (directive, \"pragma\"))\n\t\tCpp.directive.state = DRCTV_PRAGMA;\n\telse\n\t\tCpp.directive.state = DRCTV_NONE;\n\n\treturn ignore;\n}\n\n/*  Handles a pre-processor directive whose first character is given by \"c\".\n */\nstatic bool handleDirective (const int c, int *macroCorkIndex, bool *inspect_conidtion)\n{\n\tbool ignore = isIgnore ();\n\n\tswitch (Cpp.directive.state)\n\t{\n\t\tcase DRCTV_NONE:    ignore = isIgnore ();        break;\n\t\tcase DRCTV_DEFINE:\n\t\t\t*macroCorkIndex = directiveDefine (c, false);\n\t\t\tbreak;\n\t\tcase DRCTV_HASH:    ignore = directiveHash (c);  break;\n\t\tcase DRCTV_IF:\n\t\t\tignore = directiveIf (c, Cpp.directive.ifsubstate);\n\t\t\t*inspect_conidtion = true;\n\t\t\tbreak;\n\t\tcase DRCTV_ELIF:\n\t\t\tdirectiveElif (c);\n\t\t\t*inspect_conidtion = true;\n\t\t\tbreak;\n\t\tcase DRCTV_PRAGMA:  directivePragma (c);         break;\n\t\tcase DRCTV_UNDEF:   directiveUndef (c);          break;\n\t\tcase DRCTV_INCLUDE: directiveInclude (c);        break;\n\t}\n\treturn ignore;\n}\n\n/*  Called upon reading of a slash ('/') characters, determines whether a\n *  comment is encountered, and its type.\n */\nstatic Comment isComment (void)\n{\n\tComment comment;\n\tconst int next = cppGetcFromUngetBufferOrFile ();\n\n\tif (next == '*')\n\t\tcomment = COMMENT_C;\n\telse if (next == '/')\n\t\tcomment = COMMENT_CPLUS;\n\telse if (next == '+')\n\t\tcomment = COMMENT_D;\n\telse\n\t{\n\t\tcppUngetc (next);\n\t\tcomment = COMMENT_NONE;\n\t}\n\treturn comment;\n}\n\n/*  Skips over a C style comment. According to ANSI specification a comment\n *  is treated as white space, so we perform this substitution.\n */\nstatic int cppSkipOverCComment (void)\n{\n\tint c = cppGetcFromUngetBufferOrFile ();\n\n\twhile (c != EOF)\n\t{\n\t\tif (c != '*')\n\t\t\tc = cppGetcFromUngetBufferOrFile ();\n\t\telse\n\t\t{\n\t\t\tconst int next = cppGetcFromUngetBufferOrFile ();\n\n\t\t\tif (next != '/')\n\t\t\t\tc = next;\n\t\t\telse\n\t\t\t{\n\t\t\t\tc = SPACE;  /* replace comment with space */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn c;\n}\n\n/*  Skips over a C++ style comment.\n */\nstatic int skipOverCplusComment (void)\n{\n\tint c;\n\n\twhile ((c = cppGetcFromUngetBufferOrFile ()) != EOF)\n\t{\n\t\tif (c == BACKSLASH)\n\t\t\tcppGetcFromUngetBufferOrFile ();  /* throw away next character, too */\n\t\telse if (c == NEWLINE)\n\t\t\tbreak;\n\t}\n\treturn c;\n}\n\n/* Skips over a D style comment.\n * Really we should match nested /+ comments. At least they're less common.\n */\nstatic int skipOverDComment (void)\n{\n\tint c = cppGetcFromUngetBufferOrFile ();\n\n\twhile (c != EOF)\n\t{\n\t\tif (c != '+')\n\t\t\tc = cppGetcFromUngetBufferOrFile ();\n\t\telse\n\t\t{\n\t\t\tconst int next = cppGetcFromUngetBufferOrFile ();\n\n\t\t\tif (next != '/')\n\t\t\t\tc = next;\n\t\t\telse\n\t\t\t{\n\t\t\t\tc = SPACE;  /* replace comment with space */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn c;\n}\n\nextern const vString * cppGetLastCharOrStringContents (void)\n{\n\tCXX_DEBUG_ASSERT(Cpp.charOrStringContents,\"Shouldn't be called when CPP is not initialized\");\n\treturn Cpp.charOrStringContents;\n}\n\n/*  Skips to the end of a string, returning a special character to\n *  symbolically represent a generic string.\n */\nstatic int skipToEndOfString (bool ignoreBackslash)\n{\n\tint c;\n\n\tvStringClear(Cpp.charOrStringContents);\n\n\twhile ((c = cppGetcFromUngetBufferOrFile ()) != EOF)\n\t{\n\t\tif (c == BACKSLASH && ! ignoreBackslash)\n\t\t{\n\t\t\tint c0 = cppGetcFromUngetBufferOrFile ();\n\t\t\tif (c0 == '\\n')\n\t\t\t\tcontinue;\n\t\t\tif (c0 == EOF)\n\t\t\t\tbreak;\n\n\t\t\tif (vStringPutWithLimit (Cpp.charOrStringContents, c, 1024))\n\t\t\t{\n\t\t\t\tif (vStringPutWithLimit (Cpp.charOrStringContents, c0, 1024))\n\t\t\t\t\tcontinue;\n\t\t\t\t/* delete the last back slash at the end of the vstring. */\n\t\t\t\tvStringChop(Cpp.charOrStringContents);\n\t\t\t}\n\t\t}\n\t\telse if (c == DOUBLE_QUOTE)\n\t\t\tbreak;\n\t\telse\n\t\t\t(void)vStringPutWithLimit (Cpp.charOrStringContents, c, 1024);\n\t}\n\treturn STRING_SYMBOL;  /* symbolic representation of string */\n}\n\nstatic int isCxxRawLiteralDelimiterChar (int c)\n{\n\treturn (c != ' ' && c != '\\f' && c != '\\n' && c != '\\r' && c != '\\t' && c != '\\v' &&\n\t        c != '(' && c != ')' && c != '\\\\');\n}\n\nstatic int skipToEndOfCxxRawLiteralString (void)\n{\n\tint c = cppGetcFromUngetBufferOrFile ();\n\n\tif (c != '(' && ! isCxxRawLiteralDelimiterChar (c))\n\t{\n\t\tcppUngetc (c);\n\t\tc = skipToEndOfString (false);\n\t}\n\telse\n\t{\n\t\tchar delim[16];\n\t\tunsigned int delimLen = 0;\n\t\tbool collectDelim = true;\n\n\t\tdo\n\t\t{\n\t\t\tif (collectDelim)\n\t\t\t{\n\t\t\t\tif (isCxxRawLiteralDelimiterChar (c) &&\n\t\t\t\t    delimLen < (sizeof delim / sizeof *delim))\n\t\t\t\t\tdelim[delimLen++] = c;\n\t\t\t\telse\n\t\t\t\t\tcollectDelim = false;\n\t\t\t}\n\t\t\telse if (c == ')')\n\t\t\t{\n\t\t\t\tunsigned int i = 0;\n\n\t\t\t\twhile ((c = cppGetcFromUngetBufferOrFile ()) != EOF && i < delimLen && delim[i] == c)\n\t\t\t\t\ti++;\n\t\t\t\tif (i == delimLen && c == DOUBLE_QUOTE)\n\t\t\t\t\tbreak;\n\t\t\t\telse\n\t\t\t\t\tcppUngetc (c);\n\t\t\t}\n\t\t}\n\t\twhile ((c = cppGetcFromUngetBufferOrFile ()) != EOF);\n\t\tc = STRING_SYMBOL;\n\t}\n\treturn c;\n}\n\n/*  Skips to the end of the three (possibly four) 'c' sequence, returning a\n *  special character to symbolically represent a generic character.\n *  Also detects Vera numbers that include a base specifier (ie. 'b1010).\n */\nstatic int skipToEndOfChar (void)\n{\n\tint c;\n\tint count = 0, veraBase = '\\0';\n\n\tvStringClear(Cpp.charOrStringContents);\n\n\twhile ((c = cppGetcFromUngetBufferOrFile ()) != EOF)\n\t{\n\t    ++count;\n\t\tif (c == BACKSLASH)\n\t\t{\n\t\t\tint c0 = cppGetcFromUngetBufferOrFile ();\n\t\t\tif (c0 == '\\n')\n\t\t\t\tcontinue;\n\t\t\tif (c0 == EOF)\n\t\t\t\tbreak;\n\n\t\t\tif (vStringPutWithLimit (Cpp.charOrStringContents, c, 10))\n\t\t\t{\n\t\t\t\tif (vStringPutWithLimit (Cpp.charOrStringContents, c0, 10))\n\t\t\t\t\tcontinue;\n\t\t\t\t/* delete the last back slash at the end of the vstring.*/\n\t\t\t\tvStringChop(Cpp.charOrStringContents);\n\t\t\t}\n\t\t}\n\t\telse if (c == SINGLE_QUOTE)\n\t\t\tbreak;\n\t\telse if (c == NEWLINE)\n\t\t{\n\t\t\tcppUngetc (c);\n\t\t\tbreak;\n\t\t}\n\t\telse if (Cpp.hasSingleQuoteLiteralNumbers)\n\t\t{\n\t\t\tif (count == 1  &&  strchr (\"DHOB\", toupper (c)) != NULL)\n\t\t\t{\n\t\t\t\tveraBase = c;\n\t\t\t\t(void)vStringPutWithLimit (Cpp.charOrStringContents, c, 10);\n\t\t\t}\n\t\t\telse if (veraBase != '\\0'  &&  ! isalnum (c))\n\t\t\t{\n\t\t\t\tcppUngetc (c);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t\t(void)vStringPutWithLimit (Cpp.charOrStringContents, c, 10);\n\t\t}\n\t\telse\n\t\t\t(void)vStringPutWithLimit (Cpp.charOrStringContents, c, 10);\n\t}\n\treturn CHAR_SYMBOL;  /* symbolic representation of character */\n}\n\nstatic void attachFields (int macroCorkIndex, unsigned long endLine, const char *macrodef)\n{\n\ttagEntryInfo *tag = getEntryInCorkQueue (macroCorkIndex);\n\tif (tag)\n\t{\n\t\tsetTagEndLine (tag, endLine);\n\t\tif (macrodef)\n\t\t\tattachParserField (tag, Cpp.macrodefFieldIndex, macrodef);\n\t}\n}\n\nstatic vString * conditionMayFlush (vString* condition, bool del)\n{\n\tbool standing_alone = doesCPreProRunAsStandaloneParser(CPREPRO_MACRO);\n\n\tif (condition == NULL)\n\t\treturn condition;\n\n\tsize_t len = vStringLength(condition);\n\tif (len > 0\n\t\t&& (! (\n\t\t\t\t(len == 7\n\t\t\t\t && strcmp (vStringValue (condition), \"defined\") == 0)\n\t\t\t   )))\n\t{\n\t\tif (standing_alone)\n\t\t\tpushLanguage (Cpp.lang);\n\n\t\ttagEntryInfo e;\n\t\tinitRefTagEntry (&e, vStringValue (condition),\n\t\t\t\t\t\t Cpp.defineMacroKindIndex, Cpp.macroConditionRoleIndex);\n\t\tupdateTagLine (&e, cppGetInputLineNumber (), cppGetInputFilePosition ());\n\t\tmakeTagEntry (&e);\n\n\t\tif (standing_alone)\n\t\t\tpopLanguage ();\n\t}\n\n\tif (del)\n\t{\n\t\tvStringDelete (condition);\n\t\treturn NULL;\n\t}\n\n\tvStringClear(condition);\n\treturn condition;\n}\n\nstatic void conditionMayPut (vString *condition, int c)\n{\n\tif (condition == NULL)\n\t\treturn;\n\n\tif (vStringLength (condition) > 0\n\t\t|| (!isdigit(c)))\n\t\tvStringPut(condition, c);\n}\n\nextern void cppVStringPut (vString* string, const int c)\n{\n\tif (c <= 0xff)\n\t\tvStringPut (string, c);\n\telse\n\t{\n\t\tchar marker = '\"';\n\t\tswitch (c)\n\t\t{\n\t\t\tcase CHAR_SYMBOL:\n\t\t\t\tmarker = '\\'';\n\t\t\t\t/* Fall through */\n\t\t\tcase STRING_SYMBOL:\n\t\t\t\tvStringPut (string, marker);\n\t\t\t\tvStringCat (string, cppGetLastCharOrStringContents ());\n\t\t\t\tvStringPut (string, marker);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tAssertNotReached();\n\t\t}\n\t}\n}\n\n/*  This function returns the next character, stripping out comments,\n *  C pre-processor directives, and the contents of single and double\n *  quoted strings. In short, strip anything which places a burden upon\n *  the tokenizer.\n */\nextern int cppGetc (void)\n{\n\tbool directive = false;\n\tbool ignore = false;\n\tint c;\n\tint macroCorkIndex = CORK_NIL;\n\tvString *macrodef = NULL;\n\tvString *condition = NULL;\n\n\n\tdo {\nstart_loop:\n\t\tc = cppGetcFromUngetBufferOrFile ();\nprocess:\n\t\tswitch (c)\n\t\t{\n\t\t\tcase EOF:\n\t\t\t\tignore    = false;\n\t\t\t\tdirective = false;\n\t\t\t\tif (macroCorkIndex != CORK_NIL)\n\t\t\t\t{\n\t\t\t\t\tattachFields (macroCorkIndex,\n\t\t\t\t\t\t\t\t  cppGetInputLineNumber(),\n\t\t\t\t\t\t\t\t  macrodef? vStringValue (macrodef): NULL);\n\t\t\t\t\tmacroCorkIndex = CORK_NIL;\n\t\t\t\t}\n\t\t\t\tcondition = conditionMayFlush(condition, true);\n\t\t\t\tbreak;\n\n\t\t\tcase TAB:\n\t\t\tcase SPACE:\n\t\t\t\tif (macrodef && vStringLength (macrodef) > 0\n\t\t\t\t\t&& vStringLast (macrodef) != ' ')\n\t\t\t\t\tvStringPut (macrodef, ' ');\n\t\t\t\tcondition = conditionMayFlush(condition, false);\n\t\t\t\tbreak;  /* ignore most white space */\n\n\t\t\tcase NEWLINE:\n\t\t\t\tif (directive)\n\t\t\t\t\tcondition = conditionMayFlush(condition, true);\n\t\t\t\tif (directive  &&  ! ignore)\n\t\t\t\t{\n\t\t\t\t\tdirective = false;\n\t\t\t\t\tif (macroCorkIndex != CORK_NIL)\n\t\t\t\t\t{\n\t\t\t\t\t\tattachFields (macroCorkIndex,\n\t\t\t\t\t\t\t\t\t  cppGetInputLineNumber(),\n\t\t\t\t\t\t\t\t\t  macrodef? vStringValue (macrodef): NULL);\n\t\t\t\t\t\tmacroCorkIndex = CORK_NIL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tCpp.directive.accept = true;\n\t\t\t\tbreak;\n\n\t\t\tcase DOUBLE_QUOTE:\n\t\t\t\tcondition = conditionMayFlush(condition, false);\n\n\t\t\t\tif (Cpp.directive.state == DRCTV_INCLUDE)\n\t\t\t\t\tgoto enter;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tCpp.directive.accept = false;\n\t\t\t\t\tc = skipToEndOfString (false);\n\t\t\t\t}\n\n\t\t\t\tif (macrodef)\n\t\t\t\t{\n\t\t\t\t\t/* We record the contents of string literal.\n\t\t\t\t\t *\n\t\t\t\t\t */\n\t\t\t\t\tvStringPut (macrodef, '\"');\n\t\t\t\t\tvStringCat (macrodef, Cpp.charOrStringContents);\n\t\t\t\t\tvStringPut (macrodef, '\"');\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase '#':\n\t\t\t\tcondition = conditionMayFlush(condition, false);\n\n\t\t\t\tif (Cpp.directive.accept)\n\t\t\t\t{\n\t\t\t\t\tdirective = true;\n\t\t\t\t\tCpp.directive.state  = DRCTV_HASH;\n\t\t\t\t\tCpp.directive.accept = false;\n\t\t\t\t}\n\t\t\t\tif (macrodef)\n\t\t\t\t\tvStringPut (macrodef, '#');\n\t\t\t\tbreak;\n\n\t\t\tcase SINGLE_QUOTE:\n\t\t\t\tcondition = conditionMayFlush(condition, false);\n\n\t\t\t\tCpp.directive.accept = false;\n\t\t\t\tc = skipToEndOfChar ();\n\n\t\t\t\t/* We assume none may want to know the content of the\n\t\t\t\t * literal; just put ''. */\n\t\t\t\tif (macrodef)\n\t\t\t\t{\n\t\t\t\t\tvStringPut (macrodef, '\\'');\n\t\t\t\t\tvStringCat (macrodef, Cpp.charOrStringContents);\n\t\t\t\t\tvStringPut (macrodef, '\\'');\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase '/':\n\t\t\t{\n\t\t\t\tcondition = conditionMayFlush(condition, false);\n\n\t\t\t\tconst Comment comment = isComment ();\n\n\t\t\t\tif (comment == COMMENT_C)\n\t\t\t\t\tc = cppSkipOverCComment ();\n\t\t\t\telse if (comment == COMMENT_CPLUS)\n\t\t\t\t{\n\t\t\t\t\tc = skipOverCplusComment ();\n\t\t\t\t\tif (c == NEWLINE)\n\t\t\t\t\t\tcppUngetc (c);\n\t\t\t\t}\n\t\t\t\telse if (comment == COMMENT_D)\n\t\t\t\t\tc = skipOverDComment ();\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tCpp.directive.accept = false;\n\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\tvStringPut (macrodef, '/');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase BACKSLASH:\n\t\t\t{\n\t\t\t\tcondition = conditionMayFlush(condition, false);\n\n\t\t\t\tint next = cppGetcFromUngetBufferOrFile ();\n\n\t\t\t\tif (next == NEWLINE)\n\t\t\t\t\tgoto start_loop;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcppUngetc (next);\n\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\tvStringPut (macrodef, '\\\\');\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase '?':\n\t\t\t{\n\t\t\t\tcondition = conditionMayFlush(condition, false);\n\n\t\t\t\tint next = cppGetcFromUngetBufferOrFile ();\n\t\t\t\tif (next != '?')\n\t\t\t\t{\n\t\t\t\t\tcppUngetc (next);\n\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\tvStringPut (macrodef, '?');\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tnext = cppGetcFromUngetBufferOrFile ();\n\t\t\t\t\tswitch (next)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase '(':          c = '[';       break;\n\t\t\t\t\t\tcase ')':          c = ']';       break;\n\t\t\t\t\t\tcase '<':          c = '{';       break;\n\t\t\t\t\t\tcase '>':          c = '}';       break;\n\t\t\t\t\t\tcase '/':          c = BACKSLASH; goto process;\n\t\t\t\t\t\tcase '!':          c = '|';       break;\n\t\t\t\t\t\tcase SINGLE_QUOTE: c = '^';       break;\n\t\t\t\t\t\tcase '-':          c = '~';       break;\n\t\t\t\t\t\tcase '=':          c = '#';       goto process;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tcppUngetc ('?');\n\t\t\t\t\t\t\tcppUngetc (next);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\tvStringPut (macrodef, c);\n\t\t\t\t}\n\t\t\t} break;\n\n\t\t\t/* digraphs:\n\t\t\t * input:  <:  :>  <%  %>  %:  %:%:\n\t\t\t * output: [   ]   {   }   #   ##\n\t\t\t */\n\t\t\tcase '<':\n\t\t\t{\n\t\t\t\tcondition = conditionMayFlush(condition, false);\n\n\t\t\t\t/*\n\t\t\t\t   Quoted from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3237.html:\n\t\t\t\t   ------\n\t\t\t\t   if the next three characters are <:: and the\n\t\t\t\t   subsequent character is neither : nor >, the < is\n\t\t\t\t   treated as a preprocessor token by itself (and not as\n\t\t\t\t   the first character of the alternative token */\n\t\t\t\tint next[3];\n\t\t\t\tnext[0] = cppGetcFromUngetBufferOrFile ();\n\t\t\t\tswitch (next[0])\n\t\t\t\t{\n\t\t\t\t\tcase ':':\n\t\t\t\t\t\tnext[1] = cppGetcFromUngetBufferOrFile ();\n\t\t\t\t\t\tif (next[1] == ':')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnext[2] = cppGetcFromUngetBufferOrFile ();\n\t\t\t\t\t\t\tif (! (next[2] == ':' || next[2] == '>'))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcppUngetc (next[2]);\n\t\t\t\t\t\t\t\tcppUngetc (next[1]);\n\t\t\t\t\t\t\t\tcppUngetc (next[0]);\n\t\t\t\t\t\t\t\tc = '<';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcppUngetc (next[2]);\n\t\t\t\t\t\t\t\tcppUngetc (next[1]);\n\t\t\t\t\t\t\t\tc = '[';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcppUngetc (next[1]);\n\t\t\t\t\t\t\tc = '[';\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '%':\tc = '{'; break;\n\t\t\t\t\tdefault: cppUngetc (next[0]);\n\t\t\t\t}\n\n\t\t\t\tif (macrodef)\n\t\t\t\t\tvStringPut (macrodef, c);\n\n\t\t\t\tgoto enter;\n\t\t\t}\n\t\t\tcase ':':\n\t\t\t{\n\t\t\t\tcondition = conditionMayFlush(condition, false);\n\n\t\t\t\tint next = cppGetcFromUngetBufferOrFile ();\n\t\t\t\tif (next == '>')\n\t\t\t\t\tc = ']';\n\t\t\t\telse\n\t\t\t\t\tcppUngetc (next);\n\n\t\t\t\tif (macrodef)\n\t\t\t\t\tvStringPut (macrodef, c);\n\n\t\t\t\tgoto enter;\n\t\t\t}\n\t\t\tcase '%':\n\t\t\t{\n\t\t\t\tcondition = conditionMayFlush(condition, false);\n\n\t\t\t\tint next = cppGetcFromUngetBufferOrFile ();\n\t\t\t\tswitch (next)\n\t\t\t\t{\n\t\t\t\t\tcase '>':\tc = '}'; break;\n\t\t\t\t\tcase ':':\tc = '#'; goto process;\n\t\t\t\t\tdefault: cppUngetc (next);\n\t\t\t\t}\n\n\t\t\t\tif (macrodef)\n\t\t\t\t\tvStringPut (macrodef, c);\n\n\t\t\t\tgoto enter;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tif (c == '@' && Cpp.hasAtLiteralStrings)\n\t\t\t\t{\n\t\t\t\t\tcondition = conditionMayFlush(condition, false);\n\n\t\t\t\t\tint next = cppGetcFromUngetBufferOrFile ();\n\t\t\t\t\tif (next == DOUBLE_QUOTE)\n\t\t\t\t\t{\n\t\t\t\t\t\tCpp.directive.accept = false;\n\t\t\t\t\t\tc = skipToEndOfString (true);\n\t\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\t\tvStringCatS (macrodef, \"@\\\"\\\"\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcppUngetc (next);\n\t\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\t\tvStringPut (macrodef, '@');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (c == 'R' && Cpp.hasCxxRawLiteralStrings)\n\t\t\t\t{\n\t\t\t\t\tconditionMayPut(condition, c);\n\n\t\t\t\t\t/* OMG!11 HACK!!11  Get the previous character.\n\t\t\t\t\t *\n\t\t\t\t\t * We need to know whether the previous character was an identifier or not,\n\t\t\t\t\t * because \"R\" has to be on its own, not part of an identifier.  This allows\n\t\t\t\t\t * for constructs like:\n\t\t\t\t\t *\n\t\t\t\t\t * \t#define FOUR \"4\"\n\t\t\t\t\t * \tconst char *p = FOUR\"5\";\n\t\t\t\t\t *\n\t\t\t\t\t * which is not a raw literal, but a preprocessor concatenation.\n\t\t\t\t\t *\n\t\t\t\t\t * FIXME: handle\n\t\t\t\t\t *\n\t\t\t\t\t * \tconst char *p = R\\\n\t\t\t\t\t * \t\"xxx(raw)xxx\";\n\t\t\t\t\t *\n\t\t\t\t\t * which is perfectly valid (yet probably very unlikely). */\n\t\t\t\t\tint prev = getNthPrevCFromInputFile (1, '\\0');\n\t\t\t\t\tint prev2 = getNthPrevCFromInputFile (2, '\\0');\n\t\t\t\t\tint prev3 = getNthPrevCFromInputFile (3, '\\0');\n\n\t\t\t\t\tif (! cppIsident (prev) ||\n\t\t\t\t\t    (! cppIsident (prev2) && (prev == 'L' || prev == 'u' || prev == 'U')) ||\n\t\t\t\t\t    (! cppIsident (prev3) && (prev2 == 'u' && prev == '8')))\n\t\t\t\t\t{\n\t\t\t\t\t\tint next = cppGetcFromUngetBufferOrFile ();\n\t\t\t\t\t\tif (next != DOUBLE_QUOTE)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcppUngetc (next);\n\t\t\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\t\t\tvStringPut (macrodef, 'R');\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCpp.directive.accept = false;\n\t\t\t\t\t\t\tc = skipToEndOfCxxRawLiteralString ();\n\n\t\t\t\t\t\t\t/* We assume none may want to know the content of the\n\t\t\t\t\t\t\t * literal; just put \"\". */\n\t\t\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\t\t\tvStringCatS (macrodef, \"\\\"\\\"\");\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\t\tvStringPut (macrodef, 'R');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if(isxdigit(c))\n\t\t\t\t{\n\t\t\t\t\t/* Check for digit separator. If we find it we just skip it */\n\t\t\t\t\tint next = cppGetcFromUngetBufferOrFile();\n\t\t\t\t\tif(next != SINGLE_QUOTE)\n\t\t\t\t\t\tcppUngetc(next);\n\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\tvStringPut (macrodef, c);\n\t\t\t\t\tconditionMayPut(condition, c);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (macrodef)\n\t\t\t\t\t\tvStringPut (macrodef, c);\n\t\t\t\t\tif (isalnum(c) || c == '_')\n\t\t\t\t\t\tconditionMayPut(condition, c);\n\t\t\t\t\telse\n\t\t\t\t\t\tcondition = conditionMayFlush(condition, false);\n\t\t\t\t}\n\t\t\tenter:\n\t\t\t\tCpp.directive.accept = false;\n\t\t\t\tif (directive)\n\t\t\t\t{\n\t\t\t\t\tbool inspect_conidtion = false;\n\t\t\t\t\tignore = handleDirective (c, &macroCorkIndex, &inspect_conidtion);\n\t\t\t\t\tif (Cpp.macrodefFieldIndex != FIELD_UNKNOWN\n\t\t\t\t\t\t&& macroCorkIndex != CORK_NIL\n\t\t\t\t\t\t&& macrodef == NULL)\n\t\t\t\t\t\tmacrodef = vStringNew ();\n\t\t\t\t\tif (condition == NULL\n\t\t\t\t\t\t&& inspect_conidtion)\n\t\t\t\t\t{\n\t\t\t\t\t\tcondition = vStringNew ();\n\t\t\t\t\t\tif (isalpha(c) || c == '_')\n\t\t\t\t\t\t\tconditionMayPut(condition, c);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t} while (directive || ignore);\n\n\tif (macrodef)\n\t\tvStringDelete (macrodef);\n\n\tif (condition)\n\t\tvStringDelete (condition);\n\n\tDebugStatement ( cppDebugPutc (DEBUG_CPP, c); )\n\tDebugStatement ( if (c == NEWLINE)\n\t\t\t\tdebugPrintf (DEBUG_CPP, \"%6ld: \", cppGetInputLineNumber () + 1); )\n\n\treturn c;\n}\n\nstatic void findCppTags (void)\n{\n\tcppInitCommon (Cpp.lang, 0, false, false, false,\n\t\t\t\t   KIND_GHOST_INDEX, 0, 0,\n\t\t\t\t   KIND_GHOST_INDEX,\n\t\t\t\t   KIND_GHOST_INDEX, 0, 0,\n\t\t\t\t   FIELD_UNKNOWN);\n\n\tfindRegexTagsMainloop (cppGetc);\n\n\tcppTerminate ();\n}\n\n\n/*\n *  Token ignore processing\n */\n\nstatic hashTable * cmdlineMacroTable;\n\n\nstatic bool buildMacroInfoFromTagEntry (int corkIndex,\n\t\t\t\t\t\t\t\t\t\ttagEntryInfo * entry,\n\t\t\t\t\t\t\t\t\t\tvoid * data)\n{\n\tcppMacroInfo **info = data;\n\n\tif ((entry->langType == Cpp.clientLang || entry->langType == Cpp.lang)\n\t\t&& entry->kindIndex == Cpp.defineMacroKindIndex\n\t\t&& isRoleAssigned (entry, ROLE_DEFINITION_INDEX))\n\t{\n\t\tvString *macrodef = vStringNewInit (entry->name);\n\t\tif (entry->extensionFields.signature)\n\t\t\tvStringCatS (macrodef, entry->extensionFields.signature);\n\t\tvStringPut (macrodef, '=');\n\n\t\tconst char *val = getParserFieldValueForType (entry, Cpp.macrodefFieldIndex);\n\t\tif (val)\n\t\t\tvStringCatS (macrodef, val);\n\n\t\t*info = saveMacro (Cpp.fileMacroTable, vStringValue (macrodef));\n\t\tvStringDelete (macrodef);\n\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nstatic cppMacroInfo * cppFindMacroFromSymtab (const char *const name)\n{\n\tcppMacroInfo *info = NULL;\n\tforeachEntriesInScope (CORK_NIL, name, buildMacroInfoFromTagEntry, &info);\n\n\treturn info;\n}\n\n/*  Determines whether or not \"name\" should be ignored, per the ignore list.\n */\nextern cppMacroInfo * cppFindMacro (const char *const name)\n{\n\tcppMacroInfo *info;\n\n\tif (cmdlineMacroTable)\n\t{\n\t\tinfo = (cppMacroInfo *)hashTableGetItem (cmdlineMacroTable,(char *)name);\n\t\tif (info)\n\t\t\treturn info;\n\t}\n\n\tif (Cpp.fileMacroTable)\n\t{\n\t\tinfo = (cppMacroInfo *)hashTableGetItem (Cpp.fileMacroTable,(char *)name);\n\t\tif (info)\n\t\t\treturn info;\n\n\t\tinfo = cppFindMacroFromSymtab(name);\n\t\tif (info)\n\t\t\treturn info;\n\t}\n\treturn NULL;\n}\n\nextern cppMacroArg *cppMacroArgNew (const char *str, bool free_str_when_deleting,\n\t\t\t\t\t\t\t\t\tunsigned long lineNumber, MIOPos filePosition)\n{\n\tcppMacroArg *a = xMalloc (1, cppMacroArg);\n\n\ta->str = str;\n\ta->free_str = free_str_when_deleting;\n\ta->lineNumber = lineNumber;\n\ta->filePosition = filePosition;\n\n\treturn a;\n}\n\nextern void cppMacroArgDelete (void *macroArg)\n{\n\tcppMacroArg *a = (cppMacroArg *)macroArg;\n\tif (a->free_str)\n\t\teFree ((void *)a->str);\n\ta->str = NULL;\n\teFree (macroArg);\n}\n\nstatic cppMacroToken *cppMacroTokenNew(unsigned long lineNumber, MIOPos filePosition)\n{\n\tcppMacroToken *t = xMalloc (1, cppMacroToken);\n\tt->str = NULL;\n\tt->lineNumber = lineNumber;\n\tt->filePosition = filePosition;\n\treturn t;\n}\n\nstatic void cppMacroTokenDelete (cppMacroToken *t)\n{\n\tif (t->str)\n\t\teFree ((void *)t->str);\n\tt->str = NULL;\n\teFree (t);\n}\n\nstatic cppMacroTokens *cppMacroTokensNew (cppMacroInfo * macro)\n{\n\tcppMacroTokens *r = xMalloc (1, cppMacroTokens);\n\n\tr->tarray = ptrArrayNew ((ptrArrayDeleteFunc)cppMacroTokenDelete);\n\tr->macro = macro;\n\n\treturn r;\n}\n\nstatic void cppMacroTokensDelete (cppMacroTokens *tokens)\n{\n\tAssert (tokens);\n\n\tptrArrayDelete (tokens->tarray);\n\ttokens->tarray = NULL;\n\teFree (tokens);\n}\n\nextern cppMacroTokens *cppExpandMacro (cppMacroInfo * macro,\n\t\t\t\t\t\t\t\t\t   const ptrArray *args,\n\t\t\t\t\t\t\t\t\t   unsigned long lineNumber,\n\t\t\t\t\t\t\t\t\t   MIOPos filePosition)\n{\n\tif(!macro)\n\t\treturn NULL;\n\n\tif(cppUngetBufferSize () >= CPP_MAXIMUM_UNGET_BUFFER_SIZE_FOR_MACRO_REPLACEMENTS)\n\t{\n\t\tCXX_DEBUG_PRINT (\"Ungetbuffer overflow when processing \\\"%s\\\": %d\",\n\t\t\t\t\t\t macro->name, cppUngetBufferSize());\n\t\treturn NULL;\n\t}\n\n\tif(!macro->replacements)\n\t\treturn NULL;\n\n\tcppMacroTokens *tokens = cppMacroTokensNew (macro);\n\tcppMacroToken *t = cppMacroTokenNew(lineNumber, filePosition);\n\tptrArrayAdd (tokens->tarray, t);\n\n\tvString * vstr = vStringNew();\n\tcppMacroReplacementPartInfo * r = macro->replacements;\n\n\twhile(r)\n\t{\n\t\tif(r->parameterIndex < 0)\n\t\t{\n\t\t\tif(r->constant)\n\t\t\t{\n\t\t\t\t/* We assume the constant parts of the macro definition are\n\t\t\t\t * at the beginning of the current macro expansion. */\n\t\t\t\tt->str = vStringDeleteUnwrap (vstr);\n\n\t\t\t\tt = cppMacroTokenNew(lineNumber, filePosition);\n\t\t\t\tptrArrayAdd (tokens->tarray, t);\n\n\t\t\t\tvstr = vStringNewCopy (r->constant);\n\t\t\t}\n\t\t} else {\n\t\t\tif(args && (r->parameterIndex < ptrArrayCount (args)))\n\t\t\t{\n\t\t\t\tif(r->flags & CPP_MACRO_REPLACEMENT_FLAG_STRINGIFY)\n\t\t\t\t\tvStringPut(vstr,'\"');\n\t\t\t\tt->str = vStringDeleteUnwrap (vstr);\n\n\t\t\t\tcppMacroArg *a = ptrArrayItem (args, r->parameterIndex);\n\t\t\t\tt = cppMacroTokenNew(a->lineNumber, a->filePosition);\n\t\t\t\tptrArrayAdd (tokens->tarray, t);\n\n\t\t\t\tvstr = vStringNewInit(a->str);\n\t\t\t\tif(r->flags & CPP_MACRO_REPLACEMENT_FLAG_VARARGS)\n\t\t\t\t{\n\t\t\t\t\tint idx = r->parameterIndex + 1;\n\t\t\t\t\twhile(idx < ptrArrayCount (args))\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut(vstr,',');\n\t\t\t\t\t\tt->str = vStringDeleteUnwrap (vstr);\n\n\t\t\t\t\t\ta = ptrArrayItem (args, idx);\n\t\t\t\t\t\tt = cppMacroTokenNew(a->lineNumber, a->filePosition);\n\t\t\t\t\t\tptrArrayAdd (tokens->tarray, t);\n\t\t\t\t\t\tvstr = vStringNew();\n\n\t\t\t\t\t\tvStringCatS(vstr, a->str);\n\t\t\t\t\t\tidx++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(r->flags & CPP_MACRO_REPLACEMENT_FLAG_STRINGIFY)\n\t\t\t\t\tvStringPut(vstr,'\"');\n\t\t\t}\n\t\t}\n\n\t\tr = r->next;\n\t}\n\n\tif (t->str == NULL)\n\t\tt->str = vStringDeleteUnwrap (vstr);\n\n\treturn tokens;\n}\n\n#ifdef DEBUG\nextern\n#else\nstatic\n#endif\nvString *cppFlattenMacroTokensToNewString (cppMacroTokens *tokens)\n{\n\tAssert (tokens);\n\n\tvString *vstr = vStringNew ();\n\n\tfor (size_t i = 0; i < ptrArrayCount (tokens->tarray); i++)\n\t{\n\t\tcppMacroToken *t = ptrArrayItem (tokens->tarray, i);\n\t\tvStringCatS (vstr, t->str);\n\t}\n\n\treturn vstr;\n}\n\nextern vString *cppExpandMacroAsNewString(cppMacroInfo * macro, const ptrArray *args)\n{\n\tcppMacroTokens * tokens = cppExpandMacro (macro, args,\n\t\t\t\t\t\t\t\t\t\t\t  cppGetInputLineNumber (),\n\t\t\t\t\t\t\t\t\t\t\t  cppGetInputFilePosition ());\n\tif (!tokens)\n\t\treturn NULL;\n\n\tvString *vstr = cppFlattenMacroTokensToNewString (tokens);\n\tcppMacroTokensDelete (tokens);\n\treturn vstr;\n}\n\nstatic void saveIgnoreToken(const char * ignoreToken)\n{\n\tif(!ignoreToken)\n\t\treturn;\n\n\tAssert (cmdlineMacroTable);\n\n\tconst char * c = ignoreToken;\n\tchar cc = *c;\n\n\tconst char * tokenBegin = c;\n\tconst char * tokenEnd = NULL;\n\tconst char * replacement = NULL;\n\tbool ignoreFollowingParenthesis = false;\n\n\twhile(cc)\n\t{\n\t\tif(cc == '=')\n\t\t{\n\t\t\tif(!tokenEnd)\n\t\t\t\ttokenEnd = c;\n\t\t\tc++;\n\t\t\tif(*c)\n\t\t\t\treplacement = c;\n\t\t\tbreak;\n\t\t}\n\n\t\tif(cc == '+')\n\t\t{\n\t\t\tif(!tokenEnd)\n\t\t\t\ttokenEnd = c;\n\t\t\tignoreFollowingParenthesis = true;\n\t\t}\n\n\t\tc++;\n\t\tcc = *c;\n\t}\n\n\tif(!tokenEnd)\n\t\ttokenEnd = c;\n\n\tif(tokenEnd <= tokenBegin)\n\t\treturn;\n\n\tcppMacroInfo * info = (cppMacroInfo *)eMalloc(sizeof(cppMacroInfo));\n\n\tinfo->hasParameterList = ignoreFollowingParenthesis;\n\tif(replacement)\n\t{\n\t\tcppMacroReplacementPartInfo * rep = \\\n\t\t\t(cppMacroReplacementPartInfo *)eMalloc(sizeof(cppMacroReplacementPartInfo));\n\t\trep->parameterIndex = -1;\n\t\trep->flags = 0;\n\t\trep->constant = vStringNewInit(replacement);\n\t\trep->next = NULL;\n\t\tinfo->replacements = rep;\n\t} else {\n\t\tinfo->replacements = NULL;\n\t}\n\tinfo->useCount = 0;\n\tinfo->next = NULL;\n\tinfo->name = eStrndup(tokenBegin,tokenEnd - tokenBegin);\n\thashTablePutItem(cmdlineMacroTable,info->name,info);\n\n\tverbose (\"    ignore token: %s\\n\", ignoreToken);\n}\n\nstatic cppMacroInfo * saveMacro(hashTable *table, const char * macro)\n{\n\tCXX_DEBUG_ENTER_TEXT(\"Save macro %s\",macro);\n\n\tif(!macro)\n\t\treturn NULL;\n\n\tAssert (table);\n\n\tconst char * c = macro;\n\n\t// skip initial spaces\n\twhile(*c && isspacetab(*c))\n\t\tc++;\n\n\tif(!*c)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Bad empty macro definition\");\n\t\treturn NULL;\n\t}\n\n\tif(!(isalpha((unsigned char) *c) || (*c == '_' || (*c == '$') )))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Macro does not start with an alphanumeric character\");\n\t\treturn NULL; // must be a sequence of letters and digits\n\t}\n\n\tconst char * identifierBegin = c;\n\n\twhile(*c && (isalnum((unsigned char) *c) || (*c == '_') || (*c == '$') ))\n\t\tc++;\n\n\tconst char * identifierEnd = c;\n\n\tCXX_DEBUG_PRINT(\"Macro identifier '%.*s'\",identifierEnd - identifierBegin,identifierBegin);\n\n#define MAX_PARAMS 16\n\n\tconst char * paramBegin[MAX_PARAMS];\n\tconst char * paramEnd[MAX_PARAMS];\n\n\tint iParamCount = 0;\n\n\twhile(*c && isspacetab(*c))\n\t\tc++;\n\n\tcppMacroInfo * info = (cppMacroInfo *)eMalloc(sizeof(cppMacroInfo));\n\tinfo->useCount = 0;\n\tinfo->next = NULL;\n\n\tif(*c == '(')\n\t{\n\t\t// parameter list\n\t\tCXX_DEBUG_PRINT(\"Macro has a parameter list\");\n\n\t\tinfo->hasParameterList = true;\n\n\t\tc++;\n\t\twhile(*c)\n\t\t{\n\t\t\twhile(*c && isspacetab(*c))\n\t\t\t\tc++;\n\n\t\t\tif(*c && (*c != ',') && (*c != ')'))\n\t\t\t{\n\t\t\t\tparamBegin[iParamCount] = c;\n\t\t\t\tc++;\n\t\t\t\twhile(*c && (*c != ',') && (*c != ')') && (!isspacetab(*c)))\n\t\t\t\t\tc++;\n\t\t\t\tparamEnd[iParamCount] = c;\n\n\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\"Macro parameter %d '%.*s'\",\n\t\t\t\t\t\t\tiParamCount,\n\t\t\t\t\t\t\tparamEnd[iParamCount] - paramBegin[iParamCount],\n\t\t\t\t\t\t\tparamBegin[iParamCount]\n\t\t\t\t\t);\n\n\t\t\t\tiParamCount++;\n\t\t\t\tif(iParamCount >= MAX_PARAMS)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\twhile(*c && isspacetab(*c))\n\t\t\t\tc++;\n\n\t\t\tif(*c == ')')\n\t\t\t\tbreak;\n\n\t\t\tif(*c == ',')\n\t\t\t\tc++;\n\t\t}\n\n\t\twhile(*c && (*c != ')'))\n\t\t\tc++;\n\n\t\tif(*c == ')')\n\t\t\tc++;\n\n\t\tCXX_DEBUG_PRINT(\"Got %d parameters\",iParamCount);\n\n\t} else {\n\t\tCXX_DEBUG_PRINT(\"Macro has no parameter list\");\n\t\tinfo->hasParameterList = false;\n\t}\n\n\twhile(*c && isspacetab(*c))\n\t\tc++;\n\n\tinfo->replacements = NULL;\n\n\n\tif(*c == '=')\n\t{\n\t\tCXX_DEBUG_PRINT(\"Macro has a replacement part\");\n\n\t\t// have replacement part\n\t\tc++;\n\n\t\tcppMacroReplacementPartInfo * lastReplacement = NULL;\n\t\tint nextParameterReplacementFlags = 0;\n\n#define ADD_REPLACEMENT_NEW_PART(part) \\\n\t\tdo { \\\n\t\t\tif(lastReplacement) \\\n\t\t\t\tlastReplacement->next = part; \\\n\t\t\telse \\\n\t\t\t\tinfo->replacements = part; \\\n\t\t\tlastReplacement = part; \\\n\t\t} while(0)\n\n#define ADD_CONSTANT_REPLACEMENT_NEW_PART(start,len) \\\n\t\tdo { \\\n\t\t\tcppMacroReplacementPartInfo * rep = \\\n\t\t\t\t(cppMacroReplacementPartInfo *)eMalloc(sizeof(cppMacroReplacementPartInfo)); \\\n\t\t\trep->parameterIndex = -1; \\\n\t\t\trep->flags = 0; \\\n\t\t\trep->constant = vStringNew(); \\\n\t\t\tvStringNCatS(rep->constant,start,len); \\\n\t\t\trep->next = NULL; \\\n\t\t\tCXX_DEBUG_PRINT(\"Constant replacement part: '%s'\",vStringValue(rep->constant)); \\\n\t\t\tADD_REPLACEMENT_NEW_PART(rep); \\\n\t\t} while(0)\n\n#define ADD_CONSTANT_REPLACEMENT(start,len) \\\n\t\tdo { \\\n\t\t\tif(lastReplacement && (lastReplacement->parameterIndex == -1)) \\\n\t\t\t{ \\\n\t\t\t\tvStringNCatS(lastReplacement->constant,start,len); \\\n\t\t\t\tCXX_DEBUG_PRINT( \\\n\t\t\t\t\t\t\"Constant replacement part changed: '%s'\", \\\n\t\t\t\t\t\tvStringValue(lastReplacement->constant) \\\n\t\t\t\t\t); \\\n\t\t\t} else { \\\n\t\t\t\tADD_CONSTANT_REPLACEMENT_NEW_PART(start,len); \\\n\t\t\t} \\\n\t\t} while(0)\n\n\t\t// parse replacements\n\t\tconst char * begin = c;\n\n\t\twhile(*c)\n\t\t{\n\t\t\tif(isalpha((unsigned char) *c) || (*c == '_'))\n\t\t\t{\n\t\t\t\tif(c > begin)\n\t\t\t\t\tADD_CONSTANT_REPLACEMENT(begin,c - begin);\n\n\t\t\t\tconst char * tokenBegin = c;\n\n\t\t\t\twhile(*c && (isalnum((unsigned char) *c) || (*c == '_')))\n\t\t\t\t\tc++;\n\n\t\t\t\t// check if it is a parameter\n\t\t\t\tint tokenLen = c - tokenBegin;\n\n\t\t\t\tCXX_DEBUG_PRINT(\"Check token '%.*s'\",tokenLen,tokenBegin);\n\n\t\t\t\tbool bIsVarArg = (tokenLen == 11) && (strncmp(tokenBegin,\"__VA_ARGS__\",11) == 0);\n\n\t\t\t\tint i = 0;\n\t\t\t\tfor(;i<iParamCount;i++)\n\t\t\t\t{\n\t\t\t\t\tint paramLen = paramEnd[i] - paramBegin[i];\n\n\t\t\t\t\tif(\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t/* #define debug(format, ...) fprintf (stderr, format, __VA_ARGS__) */\n\t\t\t\t\t\t\t\tbIsVarArg &&\n\t\t\t\t\t\t\t\t(paramLen == 3) &&\n\t\t\t\t\t\t\t\t(strncmp(paramBegin[i],\"...\",3) == 0)\n\t\t\t\t\t\t\t) || (\n\t\t\t\t\t\t\t\t/* #define debug(MSG) fputs(MSG, stderr) */\n\t\t\t\t\t\t\t\t(!bIsVarArg) &&\n\t\t\t\t\t\t\t\t(paramLen == tokenLen) &&\n\t\t\t\t\t\t\t\t(strncmp(paramBegin[i],tokenBegin,paramLen) == 0)\n\t\t\t\t\t\t\t) || (\n\t\t\t\t\t\t\t\t/* GNU cpp extension:\n\t\t\t\t\t\t\t\t * #define debug(format, args...) fprintf (stderr, format, args)\n\t\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\t\t(!bIsVarArg) &&\n\t\t\t\t\t\t\t\t(paramLen == tokenLen + 3) &&\n\t\t\t\t\t\t\t\t(strncmp(paramBegin[i] + tokenLen, \"...\", 3) == 0) &&\n\t\t\t\t\t\t\t\t(strncmp(paramBegin[i], tokenBegin, tokenLen) == 0) &&\n\t\t\t\t\t\t\t\t/* Let's have a side effect */\n\t\t\t\t\t\t\t\t(bIsVarArg = true)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// parameter!\n\t\t\t\t\t\tcppMacroReplacementPartInfo * rep = \\\n\t\t\t\t\t\t\t\t(cppMacroReplacementPartInfo *)eMalloc(sizeof(cppMacroReplacementPartInfo));\n\t\t\t\t\t\trep->parameterIndex = i;\n\t\t\t\t\t\trep->flags = nextParameterReplacementFlags |\n\t\t\t\t\t\t\t\t(bIsVarArg ? CPP_MACRO_REPLACEMENT_FLAG_VARARGS : 0);\n\t\t\t\t\t\trep->constant = NULL;\n\t\t\t\t\t\trep->next = NULL;\n\n\t\t\t\t\t\tnextParameterReplacementFlags = 0;\n\n\t\t\t\t\t\tCXX_DEBUG_PRINT(\"Parameter replacement part: %d (vararg %d)\",i,bIsVarArg);\n\n\t\t\t\t\t\tADD_REPLACEMENT_NEW_PART(rep);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(i >= iParamCount)\n\t\t\t\t{\n\t\t\t\t\t// no parameter found\n\t\t\t\t\tADD_CONSTANT_REPLACEMENT(tokenBegin,tokenLen);\n\t\t\t\t}\n\n\t\t\t\tbegin = c;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif((*c == '\"') || (*c == '\\''))\n\t\t\t{\n\t\t\t\t// skip string/char constant\n\t\t\t\tchar term = *c;\n\t\t\t\tc++;\n\t\t\t\twhile(*c)\n\t\t\t\t{\n\t\t\t\t\tif(*c == '\\\\')\n\t\t\t\t\t{\n\t\t\t\t\t\tc++;\n\t\t\t\t\t\tif(*c)\n\t\t\t\t\t\t\tc++;\n\t\t\t\t\t} else if(*c == term)\n\t\t\t\t\t{\n\t\t\t\t\t\tc++;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tc++;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(*c == '#')\n\t\t\t{\n\t\t\t\t// check for token paste/stringification\n\t\t\t\tif(c > begin)\n\t\t\t\t\tADD_CONSTANT_REPLACEMENT(begin,c - begin);\n\n\t\t\t\tc++;\n\t\t\t\tif(*c == '#')\n\t\t\t\t{\n\t\t\t\t\t// token paste\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Found token paste operator\");\n\t\t\t\t\twhile(*c == '#')\n\t\t\t\t\t\tc++;\n\n\t\t\t\t\t// we just skip this part and the following spaces\n\t\t\t\t\twhile(*c && isspacetab(*c))\n\t\t\t\t\t\tc++;\n\n\t\t\t\t\tif(lastReplacement && (lastReplacement->parameterIndex == -1))\n\t\t\t\t\t{\n\t\t\t\t\t\t// trim spaces from the last replacement constant!\n\t\t\t\t\t\tvStringStripTrailing(lastReplacement->constant);\n\t\t\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\t\t\"Last replacement truncated to '%s'\",\n\t\t\t\t\t\t\t\tvStringValue(lastReplacement->constant)\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// stringification\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Found stringification operator\");\n\t\t\t\t\tnextParameterReplacementFlags |= CPP_MACRO_REPLACEMENT_FLAG_STRINGIFY;\n\t\t\t\t}\n\n\t\t\t\tbegin = c;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tc++;\n\t\t}\n\n\t\tif(c > begin)\n\t\t\tADD_CONSTANT_REPLACEMENT(begin,c - begin);\n\t}\n\n\tinfo->name = eStrndup(identifierBegin,identifierEnd - identifierBegin);\n\thashTablePutItem(table,info->name,info);\n\tCXX_DEBUG_LEAVE();\n\n\treturn info;\n}\n\nstatic void freeMacroInfo(cppMacroInfo * info)\n{\n\tif(!info)\n\t\treturn;\n\tcppMacroReplacementPartInfo * pPart = info->replacements;\n\twhile(pPart)\n\t{\n\t\tif(pPart->constant)\n\t\t\tvStringDelete(pPart->constant);\n\t\tcppMacroReplacementPartInfo * pPartToDelete = pPart;\n\t\tpPart = pPart->next;\n\t\teFree(pPartToDelete);\n\t}\n\teFree(info->name);\n\teFree(info);\n}\n\nstatic hashTable *makeMacroTable (void)\n{\n\treturn hashTableNew(\n\t\t1024,\n\t\thashCstrhash,\n\t\thashCstreq,\n\t\tNULL,\t\t\t\t\t/* Keys refers values' name fields. */\n\t\t(void (*)(void *))freeMacroInfo\n\t\t);\n}\n\nstatic void initializeCpp (const langType language)\n{\n\tCpp.lang = language;\n}\n\nstatic void finalizeCpp (const langType language, bool initialized)\n{\n\tif (cmdlineMacroTable)\n\t{\n\t\thashTableDelete (cmdlineMacroTable);\n\t\tcmdlineMacroTable = NULL;\n\t}\n}\n\nstatic bool CpreProExpandMacrosInInput (const langType language CTAGS_ATTR_UNUSED, const char *name, const char *arg)\n{\n\tdoesExpandMacros = paramParserBool (arg, doesExpandMacros,\n\t\t\t\t\t\t\t\t\t\tname, \"parameter\");\n\treturn true;\n}\n\nstatic bool CpreProInstallIgnoreToken (const langType language CTAGS_ATTR_UNUSED, const char *optname CTAGS_ATTR_UNUSED, const char *arg)\n{\n\tif (arg == NULL || arg[0] == '\\0')\n\t{\n\t\tif (cmdlineMacroTable)\n\t\t{\n\t\t\thashTableDelete(cmdlineMacroTable);\n\t\t\tcmdlineMacroTable = NULL;\n\t\t}\n\t\tverbose (\"    clearing list\\n\");\n\t} else {\n\t\tif (!cmdlineMacroTable)\n\t\t\tcmdlineMacroTable = makeMacroTable ();\n\t\tsaveIgnoreToken(arg);\n\t}\n\treturn true;\n}\n\nstatic bool CpreProInstallMacroToken (const langType language CTAGS_ATTR_UNUSED, const char *optname CTAGS_ATTR_UNUSED, const char *arg)\n{\n\tif (arg == NULL || arg[0] == '\\0')\n\t{\n\t\tif (cmdlineMacroTable)\n\t\t{\n\t\t\thashTableDelete(cmdlineMacroTable);\n\t\t\tcmdlineMacroTable = NULL;\n\t\t}\n\t\tverbose (\"    clearing list\\n\");\n\t} else {\n\t\tif (!cmdlineMacroTable)\n\t\t\tcmdlineMacroTable = makeMacroTable ();\n\t\tsaveMacro(cmdlineMacroTable, arg);\n\t}\n\treturn true;\n}\n\nstatic bool CpreProSetIf0 (const langType language CTAGS_ATTR_UNUSED, const char *name, const char *arg)\n{\n\tdoesExaminCodeWithInIf0Branch = paramParserBool (arg, doesExaminCodeWithInIf0Branch,\n\t\t\t\t\t\t\t\t\t\t\t\t\t name, \"parameter\");\n\treturn true;\n}\n\nstatic paramDefinition CpreProParams [] = {\n\t{ .name = \"if0\",\n\t  .desc = \"examine code within \\\"#if 0\\\" branch (true or [false])\",\n\t  .handleParam = CpreProSetIf0,\n\t},\n\t{ .name = \"ignore\",\n\t  .desc = \"a token to be specially handled\",\n\t  .handleParam = CpreProInstallIgnoreToken,\n\t},\n\t{ .name = \"define\",\n\t  .desc = \"define replacement for an identifier (name(params,...)=definition)\",\n\t  .handleParam = CpreProInstallMacroToken,\n\t},\n\t{ .name = \"_expand\",\n\t  .desc = \"expand macros if their definitions are in the current C/C++/CUDA input file (true or [false])\",\n\t  .handleParam = CpreProExpandMacrosInInput,\n\t}\n};\n\nextern parserDefinition* CPreProParser (void)\n{\n\tparserDefinition* const def = parserNew (\"CPreProcessor\");\n\tdef->kindTable      = CPreProKinds;\n\tdef->kindCount  = ARRAY_SIZE (CPreProKinds);\n\tdef->initialize = initializeCpp;\n\tdef->parser     = findCppTags;\n\tdef->finalize   = finalizeCpp;\n\n\tdef->fieldTable = CPreProFields;\n\tdef->fieldCount = ARRAY_SIZE (CPreProFields);\n\n\tdef->paramTable = CpreProParams;\n\tdef->paramCount = ARRAY_SIZE(CpreProParams);\n\n\tdef->useCork = CORK_QUEUE | CORK_SYMTAB;\n\treturn def;\n}\n\n#ifdef DEBUG\nextern void cppDebugPutc (const int level, const int c)\n{\n\tif (debug (level)  &&  c != EOF)\n\t{\n\t\t     if (c == STRING_SYMBOL)  printf (\"\\\"string\\\"\");\n\t\telse if (c == CHAR_SYMBOL)    printf (\"'c'\");\n\t\telse                          putchar (c);\n\n\t\tfflush (stdout);\n\t}\n}\n#endif\n"
  },
  {
    "path": "parsers/css.c",
    "content": "/***************************************************************************\n * css.c\n * Token-based parser for CSS definitions\n * Author - Colomban Wendling <colomban@geany.org>\n * License GPL-2\n **************************************************************************/\n#include \"general.h\"\n\n#include <string.h>\n#include <ctype.h>\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n\n#define isSelectorChar(c) \\\n\t/* attribute selectors are handled separately */ \\\n\t(isalnum (c) || \\\n\t\t(c) == '_' || /* allowed char */ \\\n\t\t(c) == '-' || /* allowed char */ \\\n\t\t(c) == '+' || /* allow all sibling in a single tag */ \\\n\t\t(c) == '>' || /* allow all child in a single tag */ \\\n\t\t(c) == '~' || /* allow general sibling combinator */ \\\n\t\t(c) == '|' || /* allow namespace separator */ \\\n\t\t(c) == '(' || /* allow pseudo-class arguments */ \\\n\t\t(c) == ')' || \\\n\t\t(c) == '.' || /* allow classes and selectors */ \\\n\t\t(c) == ':' || /* allow pseudo classes */ \\\n\t\t(c) == '*' || /* allow globs as P + * */ \\\n\t\t(c) == '#')   /* allow ids */\n\ntypedef enum eCssKinds {\n\tK_CLASS, K_SELECTOR, K_ID\n} cssKind;\n\nstatic kindDefinition CssKinds [] = {\n\t{ true, 'c', \"class\",\t\t\"classes\" },\n\t{ true, 's', \"selector\",\t\"selectors\" },\n\t{ true, 'i', \"id\",\t\t\t\"identities\" }\n};\n\ntypedef enum {\n\t/* any ASCII */\n\tTOKEN_EOF = 257,\n\tTOKEN_SELECTOR,\n\tTOKEN_STRING\n} tokenType;\n\ntypedef struct {\n\ttokenType type;\n\tvString *string;\n} tokenInfo;\n\n\nstatic void parseSelector (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isSelectorChar (c));\n\tungetcToInputFile (c);\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\tint c;\n\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tc = getcFromInputFile ();\n\twhile (isspace (c))\n\t\tc = getcFromInputFile ();\n\n\ttoken->type = c;\n\tswitch (c)\n\t{\n\t\tcase EOF: token->type = TOKEN_EOF; break;\n\n\t\tcase '\\'':\n\t\tcase '\"':\n\t\t{\n\t\t\tconst int delimiter = c;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t\tif (c == '\\\\')\n\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t}\n\t\t\twhile (c != EOF && c != delimiter);\n\t\t\tif (c != EOF)\n\t\t\t\tvStringPut (token->string, c);\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '/': /* maybe comment start */\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d != '*')\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\ttoken->type = c;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\td = getcFromInputFile ();\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tc = d;\n\t\t\t\t\td = getcFromInputFile ();\n\t\t\t\t}\n\t\t\t\twhile (d != EOF && ! (c == '*' && d == '/'));\n\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tif (! isSelectorChar (c))\n\t\t\t{\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\ttoken->type = c;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tparseSelector (token->string, c);\n\t\t\t\ttoken->type = TOKEN_SELECTOR;\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n\n/* sets selector kind in @p kind if found, otherwise don't touches @p kind */\nstatic cssKind classifySelector (const vString *const selector)\n{\n\tsize_t i;\n\n\tfor (i = vStringLength (selector); i > 0; --i)\n\t{\n\t\tchar c = vStringChar (selector, i - 1);\n\t\tif (c == '.')\n\t\t\treturn K_CLASS;\n\t\telse if (c == '#')\n\t\t\treturn K_ID;\n\t}\n\treturn K_SELECTOR;\n}\n\nstatic void findCssTags (void)\n{\n\tbool readNextToken = true;\n\ttokenInfo token;\n\n\ttoken.string = vStringNew ();\n\n\tdo\n\t{\n\t\tif (readNextToken)\n\t\t\treadToken (&token);\n\n\t\treadNextToken = true;\n\n\t\tif (token.type == '@')\n\t\t{ /* At-rules, from the \"@\" to the next block or semicolon */\n\t\t\tbool useContents;\n\t\t\treadToken (&token);\n\t\t\tuseContents = (strcmp (vStringValue (token.string), \"media\") == 0 ||\n\t\t\t\t\t\t   strcmp (vStringValue (token.string), \"supports\") == 0);\n\t\t\twhile (token.type != TOKEN_EOF &&\n\t\t\t\t   token.type != ';' && token.type != '{')\n\t\t\t{\n\t\t\t\treadToken (&token);\n\t\t\t}\n\t\t\t/* HACK: we *eat* the opening '{' for medias and the like so that\n\t\t\t *       the content is parsed as if it was at the root */\n\t\t\treadNextToken = useContents && token.type == '{';\n\t\t}\n\t\telse if (token.type == TOKEN_SELECTOR)\n\t\t{ /* collect selectors and make a tag */\n\t\t\tcssKind kind = K_SELECTOR;\n\t\t\tMIOPos filePosition;\n\t\t\tunsigned long lineNumber;\n\t\t\tvString *selector = vStringNew ();\n\t\t\tdo\n\t\t\t{\n\t\t\t\tvStringJoin (selector, ' ', token.string);\n\n\t\t\t\tkind = classifySelector (token.string);\n\t\t\t\tlineNumber = getInputLineNumber ();\n\t\t\t\tfilePosition = getInputFilePosition ();\n\n\t\t\t\treadToken (&token);\n\n\t\t\t\t/* handle attribute selectors */\n\t\t\t\tif (token.type == '[')\n\t\t\t\t{\n\t\t\t\t\tint depth = 1;\n\t\t\t\t\twhile (depth > 0 && token.type != TOKEN_EOF)\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringCat (selector, token.string);\n\t\t\t\t\t\treadToken (&token);\n\t\t\t\t\t\tif (token.type == '[')\n\t\t\t\t\t\t\tdepth++;\n\t\t\t\t\t\telse if (token.type == ']')\n\t\t\t\t\t\t\tdepth--;\n\t\t\t\t\t}\n\t\t\t\t\tif (token.type != TOKEN_EOF)\n\t\t\t\t\t\tvStringCat (selector, token.string);\n\t\t\t\t\treadToken (&token);\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile (token.type == TOKEN_SELECTOR);\n\t\t\t/* we already consumed the next token, don't read it twice */\n\t\t\treadNextToken = false;\n\n\t\t\tif (CssKinds[kind].enabled)\n\t\t\t{\n\t\t\t\ttagEntryInfo e;\n\t\t\t\tinitTagEntry (&e, vStringValue (selector), kind);\n\n\t\t\t\tupdateTagLine (&e, lineNumber, filePosition);\n\n\t\t\t\tmakeTagEntry (&e);\n\t\t\t}\n\t\t\tvStringDelete (selector);\n\t\t}\n\t\telse if (token.type == '{')\n\t\t{ /* skip over { ... } */\n\t\t\tint depth = 1;\n\t\t\twhile (depth > 0 && token.type != TOKEN_EOF)\n\t\t\t{\n\t\t\t\treadToken (&token);\n\t\t\t\tif (token.type == '{')\n\t\t\t\t\tdepth++;\n\t\t\t\telse if (token.type == '}')\n\t\t\t\t\tdepth--;\n\t\t\t}\n\t\t}\n\t}\n\twhile (token.type != TOKEN_EOF);\n\n\tvStringDelete (token.string);\n}\n\n/* parser definition */\nextern parserDefinition* CssParser (void)\n{\n\tstatic const char *const extensions [] = { \"css\", NULL };\n\tparserDefinition* def = parserNew (\"CSS\");\n\tdef->kindTable      = CssKinds;\n\tdef->kindCount  = ARRAY_SIZE (CssKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findCssTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/cxx/Makefile",
    "content": "all:\n.SUFFIXES:\n.SUFFIXES: .c .o\n\n.c.o:\n\t$(MAKE) -C ../.. parsers/cxx/$@\n%:\n\t$(MAKE) -C ../.. $@\n"
  },
  {
    "path": "parsers/cxx/cxx.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_parser.h\"\n#include \"cxx_scope.h\"\n#include \"cxx_tag.h\"\n\n#include \"dependency.h\"\n#include \"selectors.h\"\n\n//\n// ----------------------------------------------------------------------------\n// Assumptions.\n// ----------------------------------------------------------------------------\n//\n// - Parsing C/C++ is hard. Parsing C/C++ correctly without includes and\n//   without a complete preprocessor is close to impossible in the general\n//   case. Also ctags is not a compiler. This means that our parser must be\n//   a \"guessing\" parser. It's hopeless to try to decode the syntax of the\n//   language down to the last bit.\n//\n// - The input may contain syntax errors. This is because we don't have a full\n//   preprocessor and also because ctags is often used \"online\" in editors,\n//   while the user is typing. ctags should be tolerant and try to do its best\n//   even with syntax errors but:\n//   - Syntax errors that break the scope hierarchy should be detected and tag\n//     emission should probably be stopped. Correct tags in a broken hierarchy\n//     are useless (well, unless the hierarchy itself is ignored by the ctags\n//     user).\n//   - CTags should try to avoid emitting tags which involve syntax errors\n//\n// - There will always be pathologic cases. Don't cry, live with it.\n//\n// ----------------------------------------------------------------------------\n// TODO LIST\n// ----------------------------------------------------------------------------\n//\n// - In case of simple syntax error try to recover:\n//       Skip to the next ; without entering or exiting scopes.\n//       If this can be done then recovery is feasible.\n// - Extension of each block/scope.\n// - Unnamed blocks/scopes?\n// - Handle syntax errors:\n//   - If a special switch is used then stop on detecting a syntax error\n//     (this is useful for code editors that frequently update tags for\n//     single files)\n//   - If the switch is not used then do NOT emit tags for a file on a syntax\n//     error [but do not stop execution of the whole program and continue on\n//     other files]\n//   For this purpose:\n//   - Do not emit tags until the end of the file, if scopes do not match we\n//     either screwed up something or the programmer did\n//     Maybe the cork api can be used for this?\n//\n// Handle variable declarations inside things like while() foreach() FOR() etc..\n//\n// - Friend classes.\n// - Template parameters as field\n// - Template specialisations (another field?)\n// - Forward declarations might become tags\n\n\nparserDefinition * CParser (void)\n{\n\tstatic const char * const extensions [] =\n\t{\n\t\t\"c\",\n\t\tNULL\n\t};\n\n\tstatic selectLanguage selectors[] = { selectByObjectiveCKeywords, NULL };\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_FOREIGNER, \"LdScript\", NULL },\n\t};\n\n\tparserDefinition* def = parserNew(\"C\");\n\n\tdef->kindTable = cxxTagGetCKindDefinitions();\n\tdef->kindCount = cxxTagGetCKindDefinitionCount();\n\tdef->fieldTable = cxxTagGetCFieldDefinitionifiers();\n\tdef->fieldCount = cxxTagGetCFieldDefinitionifierCount();\n\tdef->extensions = extensions;\n\tdef->parser2 = cxxCParserMain;\n\tdef->initialize = cxxCParserInitialize;\n\tdef->finalize = cxxParserCleanup;\n\tdef->selectLanguage = selectors;\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\tdef->useCork = CORK_QUEUE|CORK_SYMTAB; // We use corking to block output until the end of file\n\n\tdef->versionCurrent = 2;\n\tdef->versionAge = 2;\n\n\treturn def;\n}\n\nparserDefinition * CppParser (void)\n{\n\tstatic const char * const extensions [] =\n\t{\n\t\t\"c++\", \"cc\", \"cp\", \"cpp\", \"cxx\",\n\t\t\"h\", \"h++\", \"hh\", \"hp\", \"hpp\", \"hxx\", \"inl\",\n#ifndef CASE_INSENSITIVE_FILENAMES\n\t\t\"C\", \"H\", \"CPP\", \"CXX\",\n#endif\n\t\tNULL\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t{ DEPTYPE_KIND_OWNER, \"C\" },\n\t\t{ DEPTYPE_FOREIGNER, \"LdScript\", NULL },\n\t};\n\n\tstatic selectLanguage selectors[] = { selectByObjectiveCKeywords, NULL };\n\n\tparserDefinition* def = parserNew(\"C++\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\tdef->kindTable = cxxTagGetCPPKindDefinitions();\n\tdef->kindCount = cxxTagGetCPPKindDefinitionCount();\n\tdef->fieldTable = cxxTagGetCPPFieldDefinitionifiers();\n\tdef->fieldCount = cxxTagGetCPPFieldDefinitionifierCount();\n\tdef->extensions = extensions;\n\tdef->parser2 = cxxCppParserMain;\n\tdef->initialize = cxxCppParserInitialize;\n\tdef->finalize = cxxParserCleanup;\n\tdef->selectLanguage = selectors;\n\tdef->useCork = CORK_QUEUE|CORK_SYMTAB; // We use corking to block output until the end of file\n\n\tdef->versionCurrent = 2;\n\tdef->versionAge = 2;\n\n\treturn def;\n}\n\nparserDefinition * CUDAParser (void)\n{\n\tstatic const char * const extensions [] =\n\t{\n\t\t\"cu\", \"cuh\",\n\t\tNULL\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t{ DEPTYPE_KIND_OWNER, \"C\" },\n\t};\n\n\tparserDefinition* def = parserNew(\"CUDA\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\tdef->kindTable = cxxTagGetCUDAKindDefinitions();\n\tdef->kindCount = cxxTagGetCUDAKindDefinitionCount();\n\tdef->fieldTable = cxxTagGetCUDAFieldDefinitionifiers();\n\tdef->fieldCount = cxxTagGetCUDAFieldDefinitionifierCount();\n\tdef->extensions = extensions;\n\tdef->parser2 = cxxCUDAParserMain;\n\tdef->initialize = cxxCUDAParserInitialize;\n\tdef->finalize = cxxParserCleanup;\n\tdef->selectLanguage = NULL;\n\tdef->useCork = CORK_QUEUE|CORK_SYMTAB; // We use corking to block output until the end of file\n\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_debug.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"cxx_debug.h\"\n\n#ifdef CXX_DO_DEBUGGING\n\n#include \"trashbox.h\"\n#include \"cxx_parser_internal.h\"\n#include \"cxx_scope.h\"\n\nstatic void cxxDebugDumpToken0 (CXXToken *pToken,\n\t\t\t\t\t\t\t\tstruct circularRefChecker *pTokenChecker,\n\t\t\t\t\t\t\t\tstruct circularRefChecker *pChainChecker,\n\t\t\t\t\t\t\t\tbool top_level);\n\nstatic void cxxDebugDumpChain0 (CXXTokenChain *pChain,\n\t\t\t\t\t\t\t\tstruct circularRefChecker *pTokenChecker,\n\t\t\t\t\t\t\t\tstruct circularRefChecker *pChainChecker,\n\t\t\t\t\t\t\t\tbool top_level)\n{\n\tint backref;\n\n\tif (top_level)\n\t{\n\t\tdebugIndent ();\n\t\tfprintf (stderr, \"<chain \");\n\t}\n\telse if (pChain == NULL)\n\t{\n\t\tfprintf (stderr, \"NULL\\n\");\n\t\treturn;\n\t}\n\telse\n\t{\n\t\tfprintf (stderr, \"<\");\n\t}\n\n\tbackref = circularRefCheckerCheck (pChainChecker, pChain);\n\tif (backref)\n\t{\n\t\tfprintf (stderr, \"*C#%d>\\n\", backref);\n\t\treturn;\n\t}\n\n\tbackref = circularRefCheckerGetCurrent (pChainChecker);\n\n\tfprintf (stderr, \"[%d %p&C#%d]\\n\", pChain->iCount, pChain, backref);\n\n\tdebugInc();\n\tdebugIndent ();\n\tcxxDebugDumpToken0 (pChain->pHead, pTokenChecker, pChainChecker, false);\n\tdebugDec();\n\n\tdebugIndent ();\n\tfprintf (stderr, \">\\n\");\n}\n\nstatic void cxxDebugDumpToken0 (CXXToken *pToken,\n\t\t\t\t\t\t\t\tstruct circularRefChecker *pTokenChecker,\n\t\t\t\t\t\t\t\tstruct circularRefChecker *pChainChecker,\n\t\t\t\t\t\t\t\tbool top_level)\n{\n\tint backref;\n\n\tif (top_level)\n\t{\n\t\tdebugIndent ();\n\t\tfprintf (stderr, \"<token \");\n\t}\n\telse if (pToken == NULL)\n\t{\n\t\tfprintf (stderr, \"NULL\\n\");\n\t\treturn;\n\t}\n\telse\n\t{\n\t\tfprintf (stderr, \"<\");\n\t}\n\n\tbackref = circularRefCheckerCheck (pTokenChecker, pToken);\n\tif (backref)\n\t{\n\t\tfprintf (stderr, \"*T#%d>\\n\", backref);\n\t\treturn;\n\t}\n\n\tbackref = circularRefCheckerGetCurrent (pTokenChecker);\n\n\tfprintf (stderr, \"\\\"%s\\\": [%s %p &T#%d]\\n\",\n\t\t\t vStringValue (pToken->pszWord),\n\t\t\t cxxDebugTypeDecode (pToken->eType), pToken, backref);\n\n\tdebugIndent ();\n\tfprintf (stderr, \"  chain: \");\n\tdebugInc();\n\tcxxDebugDumpChain0 (pToken->pChain, pTokenChecker, pTokenChecker, false);\n\tdebugDec();\n\n\tdebugIndent ();\n\tfprintf (stderr, \"  next: \");\n\tdebugInc();\n\tcxxDebugDumpToken0 (pToken->pNext, pTokenChecker, pTokenChecker, false);\n\tdebugDec();\n\n\tdebugIndent ();\n\tfprintf (stderr, \"  prev: \");\n\tdebugInc();\n\tcxxDebugDumpToken0 (pToken->pPrev, pTokenChecker, pTokenChecker, false);\n\tdebugDec();\n\n\tdebugIndent ();\n\tfprintf (stderr, \"  sideChain: \");\n\tdebugInc();\n\tcxxDebugDumpChain0 (pToken->pChain, pTokenChecker, pTokenChecker, false);\n\tdebugDec();\n\n\tdebugIndent ();\n\tfprintf (stderr, \">\\n\");\n}\n\ntypedef void (* cxxDebugDumpCommonFunc)(void *,\n\t\t\t\t\t\t\t\t\t\tstruct circularRefChecker *,\n\t\t\t\t\t\t\t\t\t\tstruct circularRefChecker *,\n\t\t\t\t\t\t\t\t\t\tbool);\nstatic void cxxDebugDumpCommon (void *data,\n\t\t\t\t\t\t\t\tvoid (* func)(void *,\n\t\t\t\t\t\t\t\t\t\t\t  struct circularRefChecker *,\n\t\t\t\t\t\t\t\t\t\t\t  struct circularRefChecker *,\n\t\t\t\t\t\t\t\t\t\t\t  bool))\n{\n\tstatic struct circularRefChecker *pTokenChecker;\n\tstatic struct circularRefChecker *pChainChecker;\n\n\tif (!pTokenChecker)\n\t{\n\t\tpTokenChecker = circularRefCheckerNew();\n\t\tDEFAULT_TRASH_BOX(pTokenChecker, (TrashBoxDestroyItemProc)circularRefCheckerDestroy);\n\t}\n\n\tif (!pChainChecker)\n\t{\n\t\tpChainChecker = circularRefCheckerNew();\n\t\tDEFAULT_TRASH_BOX(pChainChecker, (TrashBoxDestroyItemProc)circularRefCheckerDestroy);\n\t}\n\n\tfunc(data, pTokenChecker, pChainChecker, true);\n\n\tcircularRefCheckClear (pTokenChecker);\n\tcircularRefCheckClear (pChainChecker);\n}\n\nvoid cxxDebugDumpToken (CXXToken *pToken)\n{\n\tcxxDebugDumpCommon (pToken, (cxxDebugDumpCommonFunc)cxxDebugDumpToken0);\n}\n\nvoid cxxDebugDumpChain (CXXTokenChain *pChain)\n{\n\tcxxDebugDumpCommon (pChain, (cxxDebugDumpCommonFunc)cxxDebugDumpChain0);\n}\n\nconst char* cxxDebugScopeDecode(enum CXXScopeType scope)\n{\n\tconst char * table[] = {\n\t\t[CXXScopeTypeFunction]  = \"function\",\n\t\t[CXXScopeTypeNamespace] = \"namespace\",\n\t\t[CXXScopeTypeClass] = \"class\",\n\t\t[CXXScopeTypeEnum] = \"enum\",\n\t\t[CXXScopeTypeUnion] = \"union\",\n\t\t[CXXScopeTypeStruct] = \"struct\",\n\t\t[CXXScopeTypeVariable] = \"variable\",\n\t\t[CXXScopeTypePrototype]  = \"prototype\",\n\t\t[CXXScopeTypeTypedef] = \"typedef\",\n\t\t[CXXScopeTypeModule] = \"module\",\n\t};\n\tif (CXXScopeTypeLAST > scope)\n\t\treturn table[scope];\n\telse\n\t\treturn NULL;\n}\n\n#endif\n"
  },
  {
    "path": "parsers/cxx/cxx_debug.h",
    "content": "#ifndef ctags_cxx_debug_h_\n#define ctags_cxx_debug_h_\n/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n#include \"debug.h\"\n#include \"trace.h\"\n#include \"cxx_token.h\"\n#include \"cxx_scope.h\"\n\n#if defined(DO_TRACING)\n\t#define CXX_DO_DEBUGGING\n#endif\n\n#ifdef CXX_DO_DEBUGGING\n\nconst char* cxxDebugTypeDecode(enum CXXTokenType);\nvoid cxxDebugDumpToken (CXXToken *pToken);\nvoid cxxDebugDumpChain (CXXTokenChain *pChain);\nconst char* cxxDebugScopeDecode(enum CXXScopeType);\n\n#define CXX_DEBUG_ENTER() TRACE_ENTER()\n#define CXX_DEBUG_LEAVE() TRACE_LEAVE()\n\n#define CXX_DEBUG_ENTER_TEXT(_szFormat,...) \\\n\tTRACE_ENTER_TEXT(_szFormat,## __VA_ARGS__)\n\n#define CXX_DEBUG_LEAVE_TEXT(_szFormat,...) \\\n\tTRACE_LEAVE_TEXT(_szFormat,## __VA_ARGS__)\n\n#define CXX_DEBUG_PRINT(_szFormat,...) \\\n\tTRACE_PRINT(_szFormat,## __VA_ARGS__)\n\n#define CXX_DEBUG_ASSERT(_condition,_szFormat,...) \\\n\tTRACE_ASSERT(_condition,_szFormat,## __VA_ARGS__)\n\n#define CXX_DEBUG_TOKEN(T)  cxxDebugDumpToken(T)\n#define CXX_DEBUG_CHAIN(C)  cxxDebugDumpChain(C)\n#else //!CXX_DO_DEBUGGING\n\n#define CXX_DEBUG_ENTER() do { } while(0)\n#define CXX_DEBUG_LEAVE() do { } while(0)\n\n#define CXX_DEBUG_ENTER_TEXT(_szFormat,...) do { } while(0)\n#define CXX_DEBUG_LEAVE_TEXT(_szFormat,...) do { } while(0)\n\n#define CXX_DEBUG_PRINT(_szFormat,...) do { } while(0)\n\n#define CXX_DEBUG_ASSERT(_condition,_szFormat,...) do { } while(0)\n\n#define CXX_DEBUG_TOKEN(T) do { } while(0)\n#define CXX_DEBUG_CHAIN(T) do { } while(0)\n#endif //!CXX_DO_DEBUGGING\n\n\n#endif //!ctags_cxx_debug_h_\n"
  },
  {
    "path": "parsers/cxx/cxx_debug_type.c",
    "content": "/* Automatically generated by misc/gencxxtypedumper.sh */\n\n#include \"cxx_token.h\"\n#include \"cxx_debug.h\"\n\n#ifdef CXX_DO_DEBUGGING\nstatic bool append(vString *buf, const char *str, bool appended)\n{\n\tif (appended) vStringPut(buf, ' ');\n\tvStringCatS (buf, str);\n\treturn true;\n}\n\nconst char * cxxDebugTypeDecode (enum CXXTokenType eType)\n{\n\tbool a = false;\n\tstatic vString *buf;\n\tbuf = vStringNewOrClearWithAutoRelease (buf);\n\n\tif (eType & CXXTokenTypeEOF) a = append (buf, \"EOF\", a);\n\tif (eType & CXXTokenTypeIdentifier) a = append (buf, \"Identifier\", a);\n\tif (eType & CXXTokenTypeKeyword) a = append (buf, \"Keyword\", a);\n\tif (eType & CXXTokenTypeNumber) a = append (buf, \"Number\", a);\n\tif (eType & CXXTokenTypeSingleColon) a = append (buf, \"SingleColon\", a);\n\tif (eType & CXXTokenTypeMultipleColons) a = append (buf, \"MultipleColons\", a);\n\tif (eType & CXXTokenTypeSemicolon) a = append (buf, \"Semicolon\", a);\n\tif (eType & CXXTokenTypeComma) a = append (buf, \"Comma\", a);\n\tif (eType & CXXTokenTypeAssignment) a = append (buf, \"Assignment\", a);\n\tif (eType & CXXTokenTypeOperator) a = append (buf, \"Operator\", a);\n\tif (eType & CXXTokenTypeUnknown) a = append (buf, \"Unknown\", a);\n\tif (eType & CXXTokenTypeDotOperator) a = append (buf, \"DotOperator\", a);\n\tif (eType & CXXTokenTypePointerOperator) a = append (buf, \"PointerOperator\", a);\n\tif (eType & CXXTokenTypeStringConstant) a = append (buf, \"StringConstant\", a);\n\tif (eType & CXXTokenTypeStar) a = append (buf, \"Star\", a);\n\tif (eType & CXXTokenTypeAnd) a = append (buf, \"And\", a);\n\tif (eType & CXXTokenTypeMultipleAnds) a = append (buf, \"MultipleAnds\", a);\n\tif (eType & CXXTokenTypeCharacterConstant) a = append (buf, \"CharacterConstant\", a);\n\tif (eType & CXXTokenTypeMultipleDots) a = append (buf, \"MultipleDots\", a);\n\tif (eType & CXXTokenTypeOpeningBracket) a = append (buf, \"OpeningBracket\", a);\n\tif (eType & CXXTokenTypeOpeningParenthesis) a = append (buf, \"OpeningParenthesis\", a);\n\tif (eType & CXXTokenTypeOpeningSquareParenthesis) a = append (buf, \"OpeningSquareParenthesis\", a);\n\tif (eType & CXXTokenTypeSmallerThanSign) a = append (buf, \"SmallerThanSign\", a);\n\tif (eType & CXXTokenTypeClosingBracket) a = append (buf, \"ClosingBracket\", a);\n\tif (eType & CXXTokenTypeClosingParenthesis) a = append (buf, \"ClosingParenthesis\", a);\n\tif (eType & CXXTokenTypeClosingSquareParenthesis) a = append (buf, \"ClosingSquareParenthesis\", a);\n\tif (eType & CXXTokenTypeGreaterThanSign) a = append (buf, \"GreaterThanSign\", a);\n\tif (eType & CXXTokenTypeBracketChain) a = append (buf, \"BracketChain\", a);\n\tif (eType & CXXTokenTypeParenthesisChain) a = append (buf, \"ParenthesisChain\", a);\n\tif (eType & CXXTokenTypeSquareParenthesisChain) a = append (buf, \"SquareParenthesisChain\", a);\n\tif (eType & CXXTokenTypeAngleBracketChain) a = append (buf, \"AngleBracketChain\", a);\n\tif (vStringLength(buf) == 0) vStringCatS(buf, \"REALLY-UNKNOWN\");\n\treturn vStringValue (buf);\n}\n#endif\n"
  },
  {
    "path": "parsers/cxx/cxx_jni.c",
    "content": "/*\n*  Copyright (c) 2025, Red Hat, Inc.\n*   Copyright (c) 2025, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for handling JNI names.\n*/\n\n#include \"general.h\"\n\n#include \"entry.h\"\n\n#include \"cxx_tag.h\"\n#include \"cxx_subparser.h\"\n#include \"cxx_token_chain.h\"\n\n#include <string.h>\n\nstruct sJNISubparser {\n\tstruct sCxxSubparser cxx;\n\tint JNINativeMethodVarIndex;\n};\n\ntypedef enum {\n\tK_METHOD,\n} jniKind;\n\n\nstatic kindDefinition JNIKinds [] = {\n\t{ true, 'm', \"method\", \"methods\" },\n};\n\nstatic langType Lang_C;\nstatic langType Lang_Cxx;\n\nstatic void inputStart(subparser *s)\n{\n\tstruct sJNISubparser *pJNI = (struct sJNISubparser*)s;\n\n\tpJNI->JNINativeMethodVarIndex = CORK_NIL;\n}\n\nstatic void makeTagEntryNotify (subparser *s, const tagEntryInfo *entry, int corkIndex)\n{\n\tif ((entry->langType == Lang_C || entry->langType == Lang_Cxx)\n\t\t&& (entry->kindIndex == CXXTagKindVARIABLE || entry->kindIndex == CXXTagKindLOCAL)\n\t\t&& entry->extensionFields.typeRef[1]\n\t\t&& strstr (entry->extensionFields.typeRef[1],\n\t\t\t\t   \"JNINativeMethod\"))\n\t{\n\t\tstruct sJNISubparser *pJNI = (struct sJNISubparser*)s;\n\t\tpJNI->JNINativeMethodVarIndex = corkIndex;\n\t}\n}\n\nstatic bool wantsVariableBody (struct sCxxSubparser *pSubparser, CXXToken * pEndOfRightSide)\n{\n\t// JNINativeMethod varname [] = { ....\n\t//                         ^\n\t// pEndOfRightSide --------|\n\n\treturn ( cxxTokenTypeIs(pEndOfRightSide,CXXTokenTypeSquareParenthesisChain)\n\t\t\t && pEndOfRightSide->pPrev\n\t\t\t && cxxTokenTypeIs(pEndOfRightSide->pPrev,CXXTokenTypeIdentifier)\n\t\t\t && pEndOfRightSide->pPrev->pPrev\n\t\t\t && cxxTokenTypeIs(pEndOfRightSide->pPrev->pPrev,CXXTokenTypeIdentifier)\n\t\t\t && strcmp(vStringValue(pEndOfRightSide->pPrev->pPrev->pszWord),\"JNINativeMethod\") == 0);\n}\n\nstatic void jniMakeTagEntryForMethod (CXXToken * pToken, int scopeIndex,\n\t\t\t\t\t\t\t\t\t  vString *signature, vString *typeref)\n{\n\ttagEntryInfo tag;\n\n\tconst char *name = vStringValue (pToken->pszWord);\n\n\tif (vStringIsEmpty (pToken->pszWord))\n\t\treturn;\n\n\n\tif (vStringLastSafe (pToken->pszWord) == '\"'\n\t\t&& vStringValue (pToken->pszWord)[0] == '\"')\n\t{\n\t\tif (vStringLength (pToken->pszWord) == 2)\n\t\t\treturn;\n\n\t\t// surgery extracting name from \"name\".\n\t\tname = vStringValue (pToken->pszWord) + 1;\n\t\tvStringTruncate (pToken->pszWord,\n\t\t\t\t\t\t vStringLength (pToken->pszWord) - 1);\n\t}\n\n\tinitTagEntry(&tag, name, K_METHOD);\n\tupdateTagLine (&tag, pToken->iLineNumber, pToken->oFilePosition);\n\ttag.isFileScope = false;\n\n\ttag.extensionFields.scopeIndex = scopeIndex;\n\n\tif (signature)\n\t\ttag.extensionFields.signature = vStringValue (signature);\n\tif (typeref)\n\t{\n\t\ttag.extensionFields.typeRef [0] = \"typename\";\n\t\ttag.extensionFields.typeRef [1] = vStringValue (typeref);\n\t}\n\n\tmakeTagEntry(&tag);\n\n\tif (name != vStringValue (pToken->pszWord))\n\t\tvStringPut (pToken->pszWord, '\"');\n}\n\nstatic vString *extractSignature0 (CXXToken *pSignature, vString *pszSignature)\n{\n\tif (!pSignature)\n\t\treturn pszSignature;\n\n\tif (!cxxTokenTypeIs (pSignature, CXXTokenTypeStringConstant))\n\t\treturn pszSignature;\n\n\tif (!pszSignature)\n\t\tpszSignature = vStringNew ();\n\n\tfor (size_t i = 0; i < vStringLength (pSignature->pszWord); i++)\n\t{\n\t\tchar c = vStringChar (pSignature->pszWord, i);\n\t\tif (c == '\"')\n\t\t\tcontinue;\n\n\t\tvStringPut (pszSignature, c);\n\t}\n\n\treturn extractSignature0 (pSignature->pNext, pszSignature);\n}\n\nstatic vString *extractSignature (CXXToken *pSignature)\n{\n\treturn extractSignature0 (pSignature, NULL);\n}\n\nstatic vString *extractTyperef (vString *pszSignature)\n{\n\tvString *pszTyperef = NULL;\n\tconst char *str = vStringValue (pszSignature);\n\tconst char *t = strrchr (str, ')');\n\n\tif (t && t[1])\n\t{\n\t\tpszTyperef = vStringNewInit (t + 1);\n\t\tsize_t  newlen = vStringLength (pszSignature) - vStringLength (pszTyperef);\n\t\tvStringTruncate (pszSignature, newlen);\n\t}\n\n\treturn pszTyperef;\n}\n\nstatic void parseMethodEntry (CXXToken *pMethod, int iVarCork)\n{\n\twhile (pMethod && !cxxTokenTypeIs (pMethod, CXXTokenTypeStringConstant))\n\t{\n\t\tif (cxxTokenTypeIs (pMethod, CXXTokenTypeComma)\n\t\t\t|| cxxTokenTypeIs (pMethod, CXXTokenTypeClosingBracket))\n\t\t\treturn;\n\n\t\tpMethod = pMethod->pNext;\n\t}\n\tif (!pMethod || !cxxTokenTypeIs (pMethod, CXXTokenTypeStringConstant))\n\t\treturn;\n\n\tCXXToken *pComma = pMethod->pNext;\n\twhile (pComma && !cxxTokenTypeIs (pComma, CXXTokenTypeComma))\n\t\tpComma = pComma->pNext;\n\tif (!pComma || !cxxTokenTypeIs (pComma, CXXTokenTypeComma))\n\t\treturn;\n\n\tCXXToken *pSignature = pComma->pNext;\n\twhile (pSignature && !cxxTokenTypeIs (pSignature, CXXTokenTypeStringConstant))\n\t\tpSignature = pSignature->pNext;\n\tif (!pSignature || !cxxTokenTypeIs (pSignature, CXXTokenTypeStringConstant))\n\t\treturn;\n\n\tvString *pszSignature =extractSignature (pSignature);\n\tif (!pszSignature)\n\t\treturn;\n\n\tif (vStringValue (pszSignature) [0] != '(')\n\t{\n\t\tvStringDelete (pszSignature);\n\t\treturn;\n\t}\n\n\tvString *pszTyperef = extractTyperef (pszSignature);\n\tif (!pszTyperef)\n\t{\n\t\tvStringDelete (pszSignature);\n\t\treturn;\n\t}\n\n\tif (pszSignature && pszTyperef)\n\t\tjniMakeTagEntryForMethod (pMethod, iVarCork,\n\t\t\t\t\t\t\t\t  pszSignature, pszTyperef);\n\n\t/* NULLs are acceptable. */\n\tvStringDelete (pszTyperef);\n\tvStringDelete (pszSignature);\n}\n\nstatic void variableBodyNotify (struct sCxxSubparser *pSubparser, int iVarCork,\n\t\t\t\t\t\t\t\tCXXToken * pStart, CXXToken * pEnd)\n{\n\tstruct sJNISubparser *pJNI = (struct sJNISubparser*)pSubparser;\n\n\tif (iVarCork != pJNI->JNINativeMethodVarIndex)\n\t\treturn;\n\n\tif (!cxxTokenTypeIs (pStart, CXXTokenTypeBracketChain))\n\t\treturn;\n\n\tCXXTokenChain *pTopChain = pStart->pChain;\n\tfor (CXXToken *pT = pTopChain->pHead; pT; pT = pT->pNext)\n\t{\n\t\tif (!cxxTokenTypeIs (pT, CXXTokenTypeBracketChain))\n\t\t\tcontinue;\n\n\t\tCXXTokenChain *pEntryChain = pT->pChain;\n\t\tif (!pEntryChain)\n\t\t\tcontinue;\n\n\t\tCXXToken *pEntryHead = pEntryChain->pHead;\n\t\tif (!pEntryHead)\n\t\t\tcontinue;\n\n\t\tif (pEntryHead->pNext)\n\t\t\tparseMethodEntry (pEntryHead->pNext, iVarCork);\n\t}\n}\n\nstatic void initialize (langType lang)\n{\n\tLang_C = getNamedLanguage (\"C\", 0);\n\tLang_Cxx = getNamedLanguage (\"C++\", 0);\n}\n\nstatic void findJNITags(void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* JNIParser (void)\n{\n\tparserDefinition* const def = parserNew(\"JNI\");\n\n\tstatic struct sJNISubparser jniSubparser = {\n\t\t.cxx = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t\t\t.inputStart = inputStart,\n\t\t\t\t.makeTagEntryNotify = makeTagEntryNotify,\n\t\t\t},\n\t\t\t.wantsVariableBody = wantsVariableBody,\n\t\t\t.variableBodyNotify = variableBodyNotify,\n\t\t},\n\t\t. JNINativeMethodVarIndex = CORK_NIL,\n\t};\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"C++\", &jniSubparser },\n\t\t[1] = { DEPTYPE_SUBPARSER, \"C\", &jniSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = JNIKinds;\n\tdef->kindCount = ARRAY_SIZE(JNIKinds);\n\n\tdef->parser = findJNITags;\n\tdef->initialize = initialize;\n\tdef->useCork = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_keyword.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"cxx_keyword.h\"\n#include \"cxx_parser_internal.h\"\n#include \"cxx_debug.h\"\n\n#include \"keyword.h\"\n\nenum CXXKeywordFlag\n{\n\t// Keywords that in most cases are parts of the name of a type.\n\t// Examples: int, void, const, float, stuff like that\n\tCXXKeywordFlagMayBePartOfTypeName = 1,\n\t// struct, class, union, enum, typename\n\tCXXKeywordIsTypeRefMarker = (1 << 1),\n\t// Stuff that often appears together with a type name\n\t// (for example a function return type or a variable type)\n\t// but is not part of the type itself.\n\t// Examples: virtual, inline, friend, static\n\tCXXKeywordExcludeFromTypeNames = (1 << 2),\n\t// true, false, nullptr\n\tCXXKeywordIsConstant = (1 << 3),\n\t// certain keywords are disabled \"on-the-fly\" to better\n\t// handle C / C++ guessing errors (public, protected, private, namespace etc..)\n\tCXXKeywordIsDisabled = (1 << 4),\n\t// Similar to MayBePartOfTypeName but includes more keywords that are NOT part\n\t// of the type itself. Keywords that do NOT have this flag simply cannot appear\n\t// in a variable declaration.\n\t// Examples: __global__, __host__, restrict, register...\n\tCXXKeywordMayAppearInVariableDeclaration = (1 << 5),\n\t// decltype, __typeof, __typeof__, and typeof\n\tCXXKeywordIsDecltype = (1 << 6),\n\t// keywords making the parsers too complicated; they are dropped in\n\t// cxxParserParseNextToken().\n\t// Examples: __attribute__(), __declspec, ...\n\tCXXKeywordMayDropInTokenizer = (1 << 7),\n};\n\ntypedef struct _CXXKeywordDescriptor\n{\n\tconst char * szName;\n\tunsigned int uLanguages;\n\tunsigned int uFlags;\n} CXXKeywordDescriptor;\n\n\n// This array is indexed by the CXXKeywordType enum\nstatic CXXKeywordDescriptor g_aCXXKeywordTable[] = {\n\t{\n\t\t\"__attribute__\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordMayDropInTokenizer\n\t},\n\t{\n\t\t\"__constant__\",\n\t\tCXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__declspec\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames | CXXKeywordMayDropInTokenizer\n\t},\n\t{\n\t\t\"__device__\",\n\t\tCXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__fastcall\",\n\t\tCXXLanguageCPP\n\t},\n\t{\n\t\t\"__forceinline\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__forceinline__\",\n\t\tCXXLanguageCUDA,\n\t\tCXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__global__\",\n\t\tCXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__host__\",\n\t\tCXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__inline\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__inline__\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__managed__\",\n\t\tCXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__noinline__\",\n\t\tCXXLanguageCUDA,\n\t\tCXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__restrict\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__restrict__\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__shared__\",\n\t\tCXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"__stdcall\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"__thiscall\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"__thread\",\n\t\tCXXLanguageC | CXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames,\n\t},\n\t{\n\t\t\"__typeof\",\n\t\tCXXLanguageC | CXXLanguageCPP,\n\t\tCXXKeywordIsDecltype | CXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"__typeof__\",\n\t\tCXXLanguageC | CXXLanguageCPP,\n\t\tCXXKeywordIsDecltype | CXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"_Alignas\",\n\t\tCXXLanguageC,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordMayDropInTokenizer,\n\t},\n\t{\n\t\t\"_Thread_local\",\n\t\tCXXLanguageC,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames,\n\t},\n\t{\n\t\t\"alignas\",\n\t\tCXXLanguageC | CXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordMayDropInTokenizer,\n\t},\n\t{\n\t\t\"alignof\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t//{ 1, \"and\", 0 },\n\t//{ 1, \"and_eq\", 0 },\n\t{\n\t\t\"asm\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"auto\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t//{ 1, \"bitand\", 0 },\n\t//{ 1, \"bitor\", 0 },\n\t{\n\t\t\"bool\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"break\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"case\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"catch\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"char\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"char16_t\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"char32_t\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"class\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName |\n\t\t\tCXXKeywordIsTypeRefMarker\n\t},\n\t//{ 0, \"compl\", 0 },\n\t{\n\t\t\"concept\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"const\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"consteval\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"constexpr\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"constinit\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"const_cast\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"continue\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"decltype\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordIsDecltype | CXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"default\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"delete\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"do\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"double\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"dynamic_cast\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"else\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"enum\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName |\n\t\t\tCXXKeywordIsTypeRefMarker\n\t},\n\t{\n\t\t\"explicit\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"export\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"extern\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"false\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordIsConstant\n\t},\n\t// this is a keyword only in special contexts (we have a switch to enable/disable it)\n\t{\n\t\t\"final\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"float\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"for\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"friend\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"goto\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"if\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"inline\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"int\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"long\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t/*\n\t{\n\t\t\"module\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t*/\n\t{\n\t\t\"mutable\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration\n\t},\n\t{\n\t\t\"namespace\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"new\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"noexcept\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t//{ 0, \"not\", 0 },\n\t//{ 0, \"not_eq\", 0 },\n\t{\n\t\t\"nullptr\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordIsConstant\n\t},\n\t{\n\t\t\"operator\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t//{ 0, \"or\", 0 },\n\t//{ 0, \"or_eq\", 0 },\n\t// override is a keyword only after function declarators,\n\t// it's easier handling it as identifier\n\t//{ 0, \"override\", 0 },\n\t{\n\t\t\"private\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"protected\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"public\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"register\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration\n\t},\n\t{\n\t\t\"reinterpret_cast\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"requires\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"restrict\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"return\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"short\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"signed\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"sizeof\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"static\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"static_assert\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"static_cast\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"struct\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName |\n\t\t\tCXXKeywordIsTypeRefMarker\n\t},\n\t{\n\t\t\"switch\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"template\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"this\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"thread_local\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"throw\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"true\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordIsConstant\n\t},\n\t{\n\t\t\"try\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"typedef\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t{\n\t\t\"typeid\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"typename\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName |\n\t\t\tCXXKeywordIsTypeRefMarker\n\t},\n\t{\n\t\t\"typeof\",\n\t\tCXXLanguageC | CXXLanguageCPP,\n\t\tCXXKeywordIsDecltype | CXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"union\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName |\n\t\t\tCXXKeywordIsTypeRefMarker\n\t},\n\t{\n\t\t\"unsigned\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"using\",\n\t\tCXXLanguageCPP,\n\t\t0\n\t},\n\t{\n\t\t\"virtual\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordExcludeFromTypeNames\n\t},\n\t{\n\t\t\"void\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"volatile\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\tCXXKeywordMayAppearInVariableDeclaration\n\t},\n\t{\n\t\t\"wchar_t\",\n\t\tCXXLanguageCPP,\n\t\tCXXKeywordMayAppearInVariableDeclaration | CXXKeywordFlagMayBePartOfTypeName\n\t},\n\t{\n\t\t\"while\",\n\t\tCXXLanguageC | CXXLanguageCPP | CXXLanguageCUDA,\n\t\t0\n\t},\n\t//{ 0, \"xor\", 0 },\n\t//{ 0, 1, \"xor_eq\", 0 }\n};\n\nconst char * cxxKeywordName(CXXKeyword eKeywordId)\n{\n\treturn g_aCXXKeywordTable[eKeywordId].szName;\n}\n\nbool cxxKeywordMayBePartOfTypeName(CXXKeyword eKeywordId)\n{\n\treturn g_aCXXKeywordTable[eKeywordId].uFlags &\n\t\t\tCXXKeywordFlagMayBePartOfTypeName;\n}\n\nbool cxxKeywordMayAppearInVariableDeclaration(CXXKeyword eKeywordId)\n{\n\treturn g_aCXXKeywordTable[eKeywordId].uFlags &\n\t\t\tCXXKeywordMayAppearInVariableDeclaration;\n}\n\nbool cxxKeywordIsTypeRefMarker(CXXKeyword eKeywordId)\n{\n\treturn g_aCXXKeywordTable[eKeywordId].uFlags &\n\t\t\tCXXKeywordIsTypeRefMarker;\n}\n\nbool cxxKeywordIsConstant(CXXKeyword eKeywordId)\n{\n\treturn g_aCXXKeywordTable[eKeywordId].uFlags &\n\t\t\tCXXKeywordIsConstant;\n}\n\nbool cxxKeywordIsCPPSpecific(CXXKeyword eKeywordId)\n{\n\treturn g_aCXXKeywordTable[eKeywordId].uLanguages == CXXLanguageCPP;\n}\n\nbool cxxKeywordExcludeFromTypeNames(CXXKeyword eKeywordId)\n{\n\treturn g_aCXXKeywordTable[eKeywordId].uFlags &\n\t\t\tCXXKeywordExcludeFromTypeNames;\n}\n\nbool cxxKeywordIsDisabled(CXXKeyword eKeywordId)\n{\n\treturn g_aCXXKeywordTable[eKeywordId].uFlags &\n\t\t\tCXXKeywordIsDisabled;\n}\n\nbool cxxKeywordIsDecltype(CXXKeyword eKeywordId)\n{\n\treturn g_aCXXKeywordTable[eKeywordId].uFlags &\n\t\t\tCXXKeywordIsDecltype;\n}\n\nbool cxxKeywordMayDropInTokenizer(CXXKeyword eKeywordId)\n{\n\treturn g_aCXXKeywordTable[eKeywordId].uFlags &\n\t\tCXXKeywordMayDropInTokenizer;\n}\n\nbool cxxKeywordEnablePublicProtectedPrivate(bool bEnableIt)\n{\n\tbool bEnabledNow =\n\t\t\t!(g_aCXXKeywordTable[CXXKeywordPUBLIC].uFlags & CXXKeywordIsDisabled);\n\n\tif(bEnabledNow == bEnableIt)\n\t\treturn bEnabledNow;\n\n\tif(bEnableIt)\n\t{\n\t\tCXX_DEBUG_PRINT(\"Enabling public/protected/private keywords\");\n\n\t\tg_aCXXKeywordTable[CXXKeywordPUBLIC].uFlags &= ~CXXKeywordIsDisabled;\n\t\tg_aCXXKeywordTable[CXXKeywordPROTECTED].uFlags &= ~CXXKeywordIsDisabled;\n\t\tg_aCXXKeywordTable[CXXKeywordPRIVATE].uFlags &= ~CXXKeywordIsDisabled;\n\t} else {\n\t\tCXX_DEBUG_PRINT(\"Disabling public/protected/private keywords\");\n\n\t\tg_aCXXKeywordTable[CXXKeywordPUBLIC].uFlags |= CXXKeywordIsDisabled;\n\t\tg_aCXXKeywordTable[CXXKeywordPROTECTED].uFlags |= CXXKeywordIsDisabled;\n\t\tg_aCXXKeywordTable[CXXKeywordPRIVATE].uFlags |= CXXKeywordIsDisabled;\n\t}\n\n\treturn bEnabledNow;\n}\n\nvoid cxxKeywordEnableFinal(bool bEnableIt)\n{\n\tif(bEnableIt)\n\t\tg_aCXXKeywordTable[CXXKeywordFINAL].uFlags &= ~CXXKeywordIsDisabled;\n\telse\n\t\tg_aCXXKeywordTable[CXXKeywordFINAL].uFlags |= CXXKeywordIsDisabled;\n}\n\n\nvoid cxxBuildKeywordHash(const langType eLangType,unsigned int uLanguage)\n{\n\tconst size_t count = sizeof(g_aCXXKeywordTable) / sizeof(CXXKeywordDescriptor);\n\n\tsize_t i;\n\n\tfor(i = 0;i < count;i++)\n\t{\n\t\tconst CXXKeywordDescriptor * p = g_aCXXKeywordTable + i;\n\t\tif(p->uLanguages & uLanguage)\n\t\t\taddKeyword(p->szName,eLangType,i);\n\t}\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_keyword.h",
    "content": "#ifndef ctags_cxx_keyword_h_\n#define ctags_cxx_keyword_h_\n/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n#include \"parse.h\"\n\n// WARNING: There is a table in cxx_keyword.c that must match order in this enum\ntypedef enum _CXXKeyword\n{\n\tCXXKeyword__ATTRIBUTE__, // GCC\n\tCXXKeyword__CONSTANT__, // CUDA\n\tCXXKeyword__DECLSPEC, // Microsoft C/C++\n\tCXXKeyword__DEVICE__, // CUDA\n\tCXXKeyword__FASTCALL, // Microsoft C/C++\n\tCXXKeyword__FORCEINLINE, // Microsoft C/C++\n\tCXXKeyword__FORCEINLINE__, // CUDA\n\tCXXKeyword__GLOBAL__, // CUDA\n\tCXXKeyword__HOST__, // CUDA\n\tCXXKeyword__INLINE, // Microsoft C/C++\n\tCXXKeyword__INLINE__, // GCC\n\tCXXKeyword__MANAGED__, // CUDA\n\tCXXKeyword__NOINLINE__, // CUDA\n\tCXXKeyword__RESTRICT, // Microsoft C/C++\n\tCXXKeyword__RESTRICT__, // CUDA\n\tCXXKeyword__SHARED__, // CUDA\n\tCXXKeyword__STDCALL, // Microsoft C/C++\n\tCXXKeyword__THISCALL, // Microsoft C/C++\n\tCXXKeyword__THREAD, // GCC (https://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html#Thread-Local)\n\tCXXKeyword__TYPEOF, // GCC accepts this.\n\tCXXKeyword__TYPEOF__, // GCC (https://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Typeof.html#Typeof)\n\tCXXKeyword_ALIGNAS, // C11\n\tCXXKeyword_THREAD_LOCAL, // C11\n\tCXXKeywordALIGNAS, // (since C++11, C11 (stdalign.h), C23)\n\tCXXKeywordALIGNOF, // (since C++11)\n\t//CXXKeywordAND,\n\t//CXXKeywordAND_EQ,\n\tCXXKeywordASM,\n\tCXXKeywordAUTO,\n\t//CXXKeywordBITAND,\n\t//CXXKeywordBITOR,\n\tCXXKeywordBOOL,\n\tCXXKeywordBREAK,\n\tCXXKeywordCASE,\n\tCXXKeywordCATCH,\n\tCXXKeywordCHAR,\n\tCXXKeywordCHAR16_T, // (since C++11)\n\tCXXKeywordCHAR32_T, // (since C++11)\n\tCXXKeywordCLASS,\n\t//CXXKeywordCOMPL,\n\tCXXKeywordCONCEPT, // Concepts TS\n\tCXXKeywordCONST,\n\tCXXKeywordCONSTEVAL, // (since C++20)\n\tCXXKeywordCONSTEXPR, // (since C++11)\n\tCXXKeywordCONSTINIT, // (since C++20)\n\tCXXKeywordCONST_CAST,\n\tCXXKeywordCONTINUE,\n\tCXXKeywordDECLTYPE, // (since C++11)\n\tCXXKeywordDEFAULT,\n\tCXXKeywordDELETE,\n\tCXXKeywordDO,\n\tCXXKeywordDOUBLE,\n\tCXXKeywordDYNAMIC_CAST,\n\tCXXKeywordELSE,\n\tCXXKeywordENUM,\n\tCXXKeywordEXPLICIT,\n\tCXXKeywordEXPORT,\n\tCXXKeywordEXTERN,\n\tCXXKeywordFALSE,\n\tCXXKeywordFINAL, // not really a keyword, has meanings in some specific contexts\n\tCXXKeywordFLOAT,\n\tCXXKeywordFOR,\n\tCXXKeywordFRIEND,\n\tCXXKeywordGOTO,\n\tCXXKeywordIF,\n\tCXXKeywordINLINE,\n\tCXXKeywordINT,\n\tCXXKeywordLONG,\n\t// CXXKeywordMODULE,\n\tCXXKeywordMUTABLE,\n\tCXXKeywordNAMESPACE,\n\tCXXKeywordNEW,\n\tCXXKeywordNOEXCEPT, // (since C++11)\n\t//CXXKeywordNOT,\n\t//CXXKeywordNOT_EQ,\n\tCXXKeywordNULLPTR, // (since C++11)\n\tCXXKeywordOPERATOR,\n\t//CXXKeywordOR,\n\t//CXXKeywordOR_EQ,\n\t//CXXKeywordOVERRIDE, // not really a keyword, has meanings in some specific contexts\n\tCXXKeywordPRIVATE,\n\tCXXKeywordPROTECTED,\n\tCXXKeywordPUBLIC,\n\tCXXKeywordREGISTER,\n\tCXXKeywordREINTERPRET_CAST,\n\tCXXKeywordREQUIRES, // (Concepts TS)\n\tCXXKeywordRESTRICT, // C99 extension\n\tCXXKeywordRETURN,\n\tCXXKeywordSHORT,\n\tCXXKeywordSIGNED,\n\tCXXKeywordSIZEOF,\n\tCXXKeywordSTATIC,\n\tCXXKeywordSTATIC_ASSERT, // (since C++11)\n\tCXXKeywordSTATIC_CAST,\n\tCXXKeywordSTRUCT,\n\tCXXKeywordSWITCH,\n\tCXXKeywordTEMPLATE,\n\tCXXKeywordTHIS,\n\tCXXKeywordTHREAD_LOCAL, // (since C++11)\n\tCXXKeywordTHROW,\n\tCXXKeywordTRUE,\n\tCXXKeywordTRY,\n\tCXXKeywordTYPEDEF,\n\tCXXKeywordTYPEID,\n\tCXXKeywordTYPENAME,\n\tCXXKeywordTYPEOF, // GCC (https://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Typeof.html#Typeof)\n\tCXXKeywordUNION,\n\tCXXKeywordUNSIGNED,\n\tCXXKeywordUSING,\n\tCXXKeywordVIRTUAL,\n\tCXXKeywordVOID,\n\tCXXKeywordVOLATILE,\n\tCXXKeywordWCHAR_T,\n\tCXXKeywordWHILE,\n\t//CXXKeywordXOR,\n\t//CXXKeywordXOR_EQ,\n\t// WARNING: There is a table in cxx_keyword.c that must match order in this enumeration\n} CXXKeyword;\n\nbool cxxKeywordIsConstant(CXXKeyword eKeywordId);\nbool cxxKeywordMayBePartOfTypeName(CXXKeyword eKeywordId);\nbool cxxKeywordIsTypeRefMarker(CXXKeyword eKeywordId);\nbool cxxKeywordExcludeFromTypeNames(CXXKeyword eKeywordId);\nbool cxxKeywordMayAppearInVariableDeclaration(CXXKeyword eKeywordId);\nbool cxxKeywordIsCPPSpecific(CXXKeyword eKeywordId);\nbool cxxKeywordIsDecltype(CXXKeyword eKeywordId);\nbool cxxKeywordMayDropInTokenizer(CXXKeyword eKeywordId);\n\n\nconst char * cxxKeywordName(CXXKeyword eKeywordId);\n\n// uLanguage is really CXXLanguage, but we keep it as unsigned int to avoid\n// problems with header inclusions. It works anyway.\nvoid cxxBuildKeywordHash(const langType eLangType,unsigned int uLanguage);\n\n// Keyword enabled/disabled state management.\n//\n// public, protected, private, class, namespace... keywords are C++ only.\n// However when parsing .h files we don't know if they belong to a C program or C++\n// one and thus for safety we parse them as C++. If our guess is wrong then the parser\n// may become confused and in some cases even bail out.\n//\n// For this reason we enable/disable the processing of certain keyword sets\n// in certain contexts.\n\n\n//\n// \"public,protected,private\" keywords\n//\n// In header files we disable processing of such keywords until we either figure\n// out that the file really contains C++ or we start parsing a struct/union.\n//\n// This flag is meaningful only when parsing a .h file as C++ since in C\n// public/protected/private are never keywords and we assume that .cpp files\n// have C++ content (so public/protected/private are always keywords).\n//\n// This function returns the previous state of the public/protected/private keywords\n// enabled flag so it can be easily restored.\nbool cxxKeywordEnablePublicProtectedPrivate(bool bEnableIt);\n\n//\n// \"final\" keyword\n//\n// This is actually special at C++ level: it's a keyword only within a specific part\n// of a class declaration. In other contexts it's not a keyword.\nvoid cxxKeywordEnableFinal(bool bEnableIt);\n\n// Is the specific keyword currently disabled?\nbool cxxKeywordIsDisabled(CXXKeyword eKeywordId);\n\n\n#endif //!ctags_cxx_keyword_h_\n"
  },
  {
    "path": "parsers/cxx/cxx_parser.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_scope.h\"\n#include \"cxx_tag.h\"\n#include \"cxx_subparser_internal.h\"\n\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"../x-cpreprocessor.h\"\n#include \"debug.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n#include \"ptrarray.h\"\n#include \"trashbox.h\"\n\n#include <string.h>\n\n//\n// The global parser state\n//\nCXXParserState g_cxx;\n\n//\n// This is set to false once the parser is run at least one time.\n// Used by cleanup routines.\n//\nbool g_bFirstRun = true;\n\n//\n// Reset parser state:\n// - Clear the token chain\n// - Reset \"seen\" keywords\n//\nvoid cxxParserNewStatementFull(bool bExported)\n{\n\tCXX_DEBUG_PRINT(\"NEW STATE: %d\", bExported);\n\tcxxTokenChainClear(g_cxx.pTokenChain);\n\tif(g_cxx.pTemplateTokenChain)\n\t{\n\t\tcxxTokenChainDestroy(g_cxx.pTemplateTokenChain);\n\t\tg_cxx.pTemplateTokenChain = NULL;\n\t\tg_cxx.oTemplateParameters.uCount = 0;\n\t} else {\n\t\t// we don't care about stale specializations as they\n\t\t// are destroyed wen the base template prefix is extracted\n\t}\n\t// Fixed a memory leak by freeing the specializations here anyway.\n\t// For certain invalid inputs, parseTemplateAngleBracketsToTemplateChain is never called.\n\tif(g_cxx.pTemplateSpecializationTokenChain)\n\t{\n\t\tcxxTokenChainDestroy(g_cxx.pTemplateSpecializationTokenChain);\n\t\tg_cxx.pTemplateSpecializationTokenChain = NULL;\n\t}\n\tg_cxx.uKeywordState = bExported? CXXParserKeywordStateSeenExport: 0;\n\n\t// FIXME: this cpp handling of end/statement is kind of broken:\n\t//        it works only because the moon is in the correct phase.\n\tcppEndStatement();\n}\n\nvoid cxxParserNewStatement(void)\n{\n\tcxxParserNewStatementFull(false);\n}\n\n//\n// Parse a subchain of input delimited by matching pairs selected from\n// [],(),{} and <>.\n//\n// On entry g_cxx.pToken is expected to point to the initial token of the pair,\n// that is one of ([{<. The function will parse input until the matching\n// terminator token is found. Inner parsing is done by\n// cxxParserParseAndCondenseSubchainsUpToOneOf() so this is actually a recursive\n// subchain nesting algorithm.\n//\n// Returns true if it has successfully extracted and \"condensed\" a subchain\n// replacing the current token with a subchain subtree. Returns false if\n// extraction fails for some reason.\n//\n// This function never leaves the token chain in an incoherent state.\n// The current token is always replaced with a subchain tree. If the subchain\n// is broken, its contents are discarded, regardless of the return value.\n//\nbool cxxParserParseAndCondenseCurrentSubchain(\n\t\tunsigned int uInitialSubchainMarkerTypes,\n\t\tbool bAcceptEOF,\n\t\tbool bCanReduceInnerElements\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXXTokenChain * pCurrentChain = g_cxx.pTokenChain;\n\n\tg_cxx.pTokenChain = cxxTokenChainCreate();\n\n\tCXXToken * pInitial = cxxTokenChainTakeLast(pCurrentChain);\n\tcxxTokenChainAppend(g_cxx.pTokenChain,pInitial);\n\n\tCXXToken * pChainToken = cxxTokenCreate();\n\n\tpChainToken->iLineNumber = pInitial->iLineNumber;\n\tpChainToken->oFilePosition = pInitial->oFilePosition;\n\t// see the declaration of CXXTokenType enum.\n\t// Shifting by 8 gives the corresponding chain marker\n\tpChainToken->eType = (enum CXXTokenType)(g_cxx.pToken->eType << 8);\n\tpChainToken->pChain = g_cxx.pTokenChain;\n\tcxxTokenChainAppend(pCurrentChain,pChainToken);\n\n\t// see the declaration of CXXTokenType enum.\n\t// Shifting by 4 gives the corresponding closing token type\n\tenum CXXTokenType eTermType = (enum CXXTokenType)(g_cxx.pToken->eType << 4);\n\n\tunsigned int uTokenTypes = eTermType;\n\tif(bAcceptEOF)\n\t\tuTokenTypes |= CXXTokenTypeEOF;\n\n\tbool bRet = cxxParserParseAndCondenseSubchainsUpToOneOf(\n\t\t\tuTokenTypes,\n\t\t\tuInitialSubchainMarkerTypes,\n\t\t\tbCanReduceInnerElements\n\t\t);\n\n\tif(\n\t\t// Parsing the subchain failed: input is broken\n\t\t(!bRet) ||\n\t\t// Mismatched terminator (i.e EOF was accepted and encountered)\n\t\t(!cxxTokenTypeIs(cxxTokenChainLast(g_cxx.pTokenChain),eTermType))\n\t)\n\t{\n\t\t// Input is probably broken: discard it in any case, so no one\n\t\t// is tempted to parse it later.\n\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Parsing the subchain failed or EOF found. Discarding broken subtree\"\n\t\t\t);\n\n\t\twhile(g_cxx.pTokenChain->iCount > 1)\n\t\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\n\t\t// Fake the terminator\n\t\tCXXToken * pFakeLast = cxxTokenCreate();\n\t\tpFakeLast->iLineNumber = pChainToken->iLineNumber;\n\t\tpFakeLast->oFilePosition = pChainToken->oFilePosition;\n\t\tswitch(eTermType)\n\t\t{\n\t\t\tcase CXXTokenTypeClosingBracket:\n\t\t\t\tvStringPut(pFakeLast->pszWord,'}');\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeClosingParenthesis:\n\t\t\t\tvStringPut(pFakeLast->pszWord,')');\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeClosingSquareParenthesis:\n\t\t\t\tvStringPut(pFakeLast->pszWord,']');\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeGreaterThanSign:\n\t\t\t\tvStringPut(pFakeLast->pszWord,'>');\n\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tCXX_DEBUG_ASSERT(false,\"Unhandled terminator type\");\n\t\t\tbreak;\n\t\t}\n\t\tpFakeLast->eType = eTermType;\n\t\tpFakeLast->pChain = NULL;\n\n\t\tcxxTokenChainAppend(g_cxx.pTokenChain,pFakeLast);\n\t}\n\n\tg_cxx.pTokenChain = pCurrentChain;\n\tg_cxx.pToken = pCurrentChain->pTail;\n\n\tCXX_DEBUG_LEAVE();\n\treturn bRet;\n}\n\n//\n// This function parses input until one of the specified tokens appears.\n// The current token is NOT checked against the specified tokens.\n//\n// The algorithm will also build subchains of matching\n// pairs ([...],(...),<...>,{...}): within the subchain analysis\n// of uTokenTypes is completely disabled. Subchains do nest.\n//\n// Returns true if it stops before EOF or it stops at EOF and CXXTokenTypeEOF\n// is present in uTokenTypes. Returns false in all the other stop conditions\n// and when an unmatched subchain character pair is found (syntax error).\n//\nbool cxxParserParseAndCondenseSubchainsUpToOneOf(\n\t\tunsigned int uTokenTypes,\n\t\tunsigned int uInitialSubchainMarkerTypes,\n\t\tbool bCanReduceInnerElements\n\t)\n{\n\tCXX_DEBUG_ENTER_TEXT(\"Token types = 0x%x(%s), reduce = %d\", uTokenTypes, cxxDebugTypeDecode(uTokenTypes),\n\t\t\t\t\t\t bCanReduceInnerElements);\n\n\tif(!cxxParserParseNextToken())\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Found EOF\");\n\t\treturn (uTokenTypes & CXXTokenTypeEOF); // was already at EOF\n\t}\n\n\t// see the declaration of CXXTokenType enum.\n\t// Shifting by 4 gives the corresponding closing token type\n\tunsigned int uFinalSubchainMarkerTypes = uInitialSubchainMarkerTypes << 4;\n\n\tfor(;;)\n\t{\n\t\t//CXX_DEBUG_PRINT(\n\t\t//\t\t\"Current token is '%s' 0x%x\",\n\t\t//\t\tvStringValue(g_cxx.pToken->pszWord),\n\t\t//\t\tg_cxx.pToken->eType\n\t\t//);\n\n\t\tif(cxxTokenTypeIsOneOf(g_cxx.pToken,uTokenTypes))\n\t\t{\n\t\t\tif (bCanReduceInnerElements)\n\t\t\t\tcxxTokenReduceBackward (g_cxx.pToken);\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\"Got terminator token '%s' 0x%x\",\n\t\t\t\t\tvStringValue(g_cxx.pToken->pszWord),\n\t\t\t\t\tg_cxx.pToken->eType\n\t\t\t\t);\n\t\t\treturn true;\n\t\t}\n\n\t\tif(cxxTokenTypeIsOneOf(g_cxx.pToken,uInitialSubchainMarkerTypes))\n\t\t{\n\t\t\t// subchain\n\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\"Got subchain start token '%s' 0x%x\",\n\t\t\t\t\tvStringValue(g_cxx.pToken->pszWord),\n\t\t\t\t\tg_cxx.pToken->eType\n\t\t\t\t);\n\t\t\tCXXToken * pParenthesis;\n\n\t\t\tif(\n\t\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket) &&\n\t\t\t\tcxxParserCurrentLanguageIsCPP() &&\n\t\t\t\t(pParenthesis = cxxParserOpeningBracketIsLambda())\n\t\t\t)\n\t\t\t{\n\t\t\t\tif(!cxxParserHandleLambda(pParenthesis))\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to handle lambda\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tg_cxx.iNestingLevels++;\n\n\t\t\t\tif(g_cxx.iNestingLevels > CXX_PARSER_MAXIMUM_NESTING_LEVELS)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Nesting level grown too much: something nasty is going on\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tbool bRet = cxxParserParseAndCondenseCurrentSubchain(\n\t\t\t\t\t\tuInitialSubchainMarkerTypes,\n\t\t\t\t\t\t(uTokenTypes & CXXTokenTypeEOF),\n\t\t\t\t\t\tbCanReduceInnerElements\n\t\t\t\t\t);\n\n\t\t\t\tg_cxx.iNestingLevels--;\n\n\t\t\t\tif(!bRet)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\t\"Failed to parse subchain of type 0x%x\",\n\t\t\t\t\t\t\tg_cxx.pToken->eType\n\t\t\t\t\t\t);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(cxxTokenTypeIsOneOf(g_cxx.pToken,uTokenTypes))\n\t\t\t{\n\t\t\t\t// was looking for a subchain\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\"Got terminator subchain token 0x%x\",\n\t\t\t\t\t\tg_cxx.pToken->eType\n\t\t\t\t\t);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif(!cxxParserParseNextToken())\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found EOF(2)\");\n\t\t\t\treturn (uTokenTypes & CXXTokenTypeEOF); // was already at EOF\n\t\t\t}\n\n\t\t\tcontinue; // jump up to avoid checking for mismatched pairs below\n\t\t}\n\n\t\t// Check for mismatched brackets/parentheses\n\t\t// Note that if we were looking for one of [({ then we would have matched\n\t\t// it at the top of the for\n\t\tif(cxxTokenTypeIsOneOf(g_cxx.pToken,uFinalSubchainMarkerTypes))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\"Got mismatched subchain terminator 0x%x\",\n\t\t\t\t\tg_cxx.pToken->eType\n\t\t\t\t);\n\t\t\treturn false; // unmatched: syntax error\n\t\t}\n\n\t\tif(!cxxParserParseNextToken())\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found EOF(3)\");\n\t\t\treturn (uTokenTypes & CXXTokenTypeEOF); // was already at EOF\n\t\t}\n\t}\n\n\t// not reached\n\tCXX_DEBUG_LEAVE_TEXT(\"Internal error\");\n\treturn false;\n}\n\n//\n// This function parses input until one of the specified tokens appears.\n// The current token is NOT checked against the specified tokens.\n//\n// The algorithm will also build subchains of matching pairs ([...],(...),{...}).\n// Within the subchain analysis of uTokenTypes is completely disabled.\n// Subchains do nest.\n//\n// Please note that this function will skip entire scopes (matching {} pairs)\n// unless you pass CXXTokenTypeOpeningBracket to stop at their beginning.\n// This is usually what you want, unless you're really expecting a scope to begin\n// in the current statement.\n//\nbool cxxParserParseUpToOneOf(unsigned int uTokenTypes,\n\t\t\t\t\t\t\t bool bCanReduceInnerElements)\n{\n\treturn cxxParserParseAndCondenseSubchainsUpToOneOf(\n\t\t\tuTokenTypes,\n\t\t\tCXXTokenTypeOpeningBracket |\n\t\t\t\tCXXTokenTypeOpeningParenthesis |\n\t\t\t\tCXXTokenTypeOpeningSquareParenthesis,\n\t\t\tbCanReduceInnerElements\n\t\t);\n}\n\n//\n// Attempts to skip to either a semicolon or an EOF, ignoring anything in between.\n// May be also used to recovery from certain forms of syntax errors.\n// This function works also if the current token is a semicolon or an EOF.\n//\nbool cxxParserSkipToSemicolonOrEOF(void)\n{\n\tif(cxxTokenTypeIsOneOf(g_cxx.pToken,CXXTokenTypeSemicolon | CXXTokenTypeEOF))\n\t\treturn true;\n\n\treturn cxxParserParseUpToOneOf(CXXTokenTypeSemicolon | CXXTokenTypeEOF,\n\t\t\t\t\t\t\t\t   false);\n}\n\n// This has to be called when pointing to a double-colon token\n// or an identifier.\n//\n// It tries to parse a qualified name in the form of ...::A::B::C::D ...\n// and stops at the first token that is not part of such name.\n//\n// Returns false if it doesn't find an identifier after a double-colon\n// or if it finds an EOF. Returns true otherwise.\n//\n// Upon exit the token preceding the current is the last identifier\n// of the qualified name.\nbool cxxParserParseToEndOfQualifedName(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\tg_cxx.pToken,\n\t\t\t\t\tCXXTokenTypeMultipleColons | CXXTokenTypeIdentifier\n\t\t\t\t),\n\t\t\t\"This function should be called when pointing to a double-colon or an identifier\"\n\t\t);\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeIdentifier))\n\t{\n\t\tif(!cxxParserParseNextToken())\n\t\t{\n\t\t\t// syntax error, but we tolerate this\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF in cxxParserParseNextToken\");\n\t\t\treturn false; // EOF\n\t\t}\n\t}\n\n\twhile(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeMultipleColons))\n\t{\n\t\tif(!cxxParserParseNextToken())\n\t\t{\n\t\t\t// syntax error, but we tolerate this\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF in cxxParserParseNextToken\");\n\t\t\treturn false; // EOF\n\t\t}\n\n\t\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeIdentifier))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found no identifier after multiple colons\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif(!cxxParserParseNextToken())\n\t\t{\n\t\t\t// syntax error, but we tolerate this\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF in cxxParserParseNextToken\");\n\t\t\treturn false; // EOF\n\t\t}\n\t}\n\n\tCXX_DEBUG_ASSERT(g_cxx.pToken->pPrev,\"There should be a previous token here\");\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken->pPrev,CXXTokenTypeIdentifier),\n\t\t\t\"The qualified name should end with an identifier\"\n\t\t);\n\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\nvoid cxxParserSetEndLineForTagInCorkQueue(int iCorkQueueIndex,unsigned long lEndLine)\n{\n\tCXX_DEBUG_ASSERT(iCorkQueueIndex > CORK_NIL,\"The cork queue index is not valid\");\n\n\ttagEntryInfo *pTag = getEntryInCorkQueue (iCorkQueueIndex);\n\tif (pTag)\n\t{\n\t\t/* When processing the input data in unget-buffer,\n\t\t * lineNumber > endLine can happen. */\n\t\tif (pTag->lineNumber > lEndLine) {\n\t\t\tCXX_DEBUG_PRINT (\"Reset endline for \\\"%s\\\" starting from %ld (%ld => 0)\",\n\t\t\t\t\t\t\t pTag->name,\n\t\t\t\t\t\t\t pTag->lineNumber,\n\t\t\t\t\t\t\t lEndLine);\n\t\t\tlEndLine = 0;\n\n\t\t}\n\t}\n\tsetTagEndLineToCorkEntry (iCorkQueueIndex, lEndLine);\n}\n\n//\n// Attach the current position of input file as \"end\" field of\n// the specified tag in the cork queue\n//\nvoid cxxParserMarkEndLineForTagInCorkQueue(int iCorkQueueIndex)\n{\n\tcxxParserSetEndLineForTagInCorkQueue(iCorkQueueIndex, cppGetInputLineNumber());\n}\n\n\n// Make sure that the token chain contains only the specified keyword and eventually\n// the \"const\" or \"volatile\" type modifiers.\nstatic void cxxParserCleanupEnumStructClassOrUnionPrefixChain(CXXKeyword eKeyword,CXXToken * pLastToken)\n{\n\tCXXToken * pToken = cxxTokenChainFirst(g_cxx.pTokenChain);\n\twhile(pToken && (pToken != pLastToken))\n\t{\n\t\tif(\n\t\t\t\tcxxTokenTypeIs(pToken,CXXTokenTypeKeyword) &&\n\t\t\t\t(\n\t\t\t\t\t(pToken->eKeyword == eKeyword) ||\n\t\t\t\t\t(pToken->eKeyword == CXXKeywordCONST) ||\n\t\t\t\t\t(pToken->eKeyword == CXXKeywordVOLATILE)\n\t\t\t\t)\n\t\t\t)\n\t\t{\n\t\t\t// keep\n\t\t\tpToken = pToken->pNext;\n\t\t} else {\n\t\t\tCXXToken * pPrev = pToken->pPrev;\n\t\t\tif(pPrev)\n\t\t\t{\n\t\t\t\tcxxTokenChainTake(g_cxx.pTokenChain,pToken);\n\t\t\t\tcxxTokenDestroy(pToken);\n\t\t\t\tpToken = pPrev->pNext;\n\t\t\t} else {\n\t\t\t\tcxxTokenChainDestroyFirst(g_cxx.pTokenChain);\n\t\t\t\tpToken = cxxTokenChainFirst(g_cxx.pTokenChain);\n\t\t\t}\n\t\t}\n\t}\n}\n\n//\n// This is called after a full enum/struct/class/union declaration\n// that ends with a closing bracket.\n//\nstatic bool cxxParserParseEnumStructClassOrUnionFullDeclarationTrailer(\n\t\tunsigned int uKeywordState,\n\t\tCXXKeyword eTagKeyword,\n\t\tconst char * szTypeName\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\n\tcxxTokenChainClear(g_cxx.pTokenChain);\n\n\tCXX_DEBUG_PRINT(\n\t\t\t\"Parse enum/struct/class/union trailer, typename is '%s'\",\n\t\t\tszTypeName\n\t\t);\n\n\tMIOPos oFilePosition = cppGetInputFilePosition();\n\tint iFileLine = cppGetInputLineNumber();\n\tint eMaybeTokenTypeOpeningBracket = (g_cxx.bConfirmedCPPLanguage\n\t\t\t\t\t\t\t\t\t\t ? 0\n\t\t\t\t\t\t\t\t\t\t : CXXTokenTypeOpeningBracket);\n\n\tif(!cxxParserParseUpToOneOf(\n\t\t\tCXXTokenTypeEOF | CXXTokenTypeSemicolon |\n\t\t\t\teMaybeTokenTypeOpeningBracket | CXXTokenTypeAssignment,\n\t\t\tfalse\n\t\t))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to EOF/semicolon\");\n\t\treturn false;\n\t}\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeEOF))\n\t{\n\t\t// It's a syntax error, but we can be tolerant here.\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Got EOF after enum/class/struct/union block\");\n\t\treturn true;\n\t}\n\n\tif(g_cxx.pTokenChain->iCount < 2)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Nothing interesting after enum/class/struct block\");\n\t\treturn true;\n\t}\n\n\t// fake the initial two tokens\n\tCXXToken * pIdentifier = cxxTokenCreate();\n\tpIdentifier->oFilePosition = oFilePosition;\n\tpIdentifier->iLineNumber = iFileLine;\n\tpIdentifier->eType = CXXTokenTypeIdentifier;\n\tpIdentifier->bFollowedBySpace = true;\n\tvStringCatS(pIdentifier->pszWord,szTypeName);\n\tcxxTokenChainPrepend(g_cxx.pTokenChain,pIdentifier);\n\n\tcxxTokenChainPrepend(\n\t\t\tg_cxx.pTokenChain,\n\t\t\tcxxTokenCreateKeyword(iFileLine,oFilePosition,eTagKeyword)\n\t\t);\n\n\tif(uKeywordState & CXXParserKeywordStateSeenConst)\n\t{\n\t\tcxxTokenChainPrepend(\n\t\t\t\tg_cxx.pTokenChain,\n\t\t\t\tcxxTokenCreateKeyword(iFileLine,oFilePosition,CXXKeywordCONST)\n\t\t\t);\n\t}\n\n\tif(uKeywordState & CXXParserKeywordStateSeenVolatile)\n\t{\n\t\tcxxTokenChainPrepend(\n\t\t\t\tg_cxx.pTokenChain,\n\t\t\t\tcxxTokenCreateKeyword(iFileLine,oFilePosition,CXXKeywordVOLATILE)\n\t\t\t);\n\t}\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket))\n\t{\n\t\tCXX_DEBUG_PRINT(\"Found opening bracket: possibly a function declaration?\");\n\n\t\t// Revert keyword states.\n\t\t// Here we assume the following kind of input:\n\t\t//\n\t\t//   static struct S {...} fn (...) { ... }\n\t\t//\n\t\t// To fill properties: field of fn with \"static\", g_cxx.uKeywordState\n\t\t// must be set here.\n\t\t//\n\t\t// See cxxParserEmitFunctionTags.\n\t\t//\n\t\t// NOTE: C++ doesn't accept such kind of input. So we propagate\n\t\t// the state only meaningful in C languages.\n\t\tg_cxx.uKeywordState |= uKeywordState & (0\n\t\t\t| CXXParserKeywordStateSeenStatic\n\t\t\t| CXXParserKeywordStateSeenInline\n\t\t\t| CXXParserKeywordStateSeenExtern\n\t\t\t| CXXParserKeywordStateSeenAttributeDeprecated\n\t\t\t);\n\t\tif(!cxxParserParseBlockHandleOpeningBracket())\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to handle the opening bracket\");\n\t\t\treturn false;\n\t\t}\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Opening bracket handled\");\n\t\treturn true;\n\t}\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeAssignment))\n\t{\n\t\tif(!cxxParserParseUpToOneOf(\n\t\t\t\tCXXTokenTypeEOF | CXXTokenTypeSemicolon,\n\t\t\t\tfalse\n\t\t\t))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to EOF/semicolon\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif(uKeywordState & CXXParserKeywordStateSeenTypedef)\n\t\tcxxParserExtractTypedef(g_cxx.pTokenChain,true,false);\n\telse\n\t{\n\t\t// Revert keyword states.\n\t\t// Here we assume the following kind of input:\n\t\t//\n\t\t//   static struct S {...} s;\n\t\t//\n\t\t// To fill properties: field of s with \"static\", g_cxx.uKeywordState\n\t\t// must be set here.\n\t\tg_cxx.uKeywordState |= uKeywordState & (0\n\t\t\t| CXXParserKeywordStateSeenStatic\n\t\t\t| CXXParserKeywordStateSeenExtern\n\t\t\t| CXXParserKeywordStateSeenMutable\n\t\t\t| CXXParserKeywordStateSeenInline\n\t\t\t| CXXParserKeywordStateSeenAttributeDeprecated\n\t\t\t| CXXParserKeywordStateSeenConstexpr\n\t\t\t| CXXParserKeywordStateSeenConstinit\n\t\t\t| CXXParserKeywordStateSeenThreadLocal\n\t\t\t);\n\t\tcxxParserExtractVariableDeclarations(g_cxx.pTokenChain,0);\n\t}\n\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\nbool cxxParserParseEnum(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tunsigned int uInitialKeywordState = g_cxx.uKeywordState;\n\tint iInitialTokenCount = g_cxx.pTokenChain->iCount;\n\tCXXToken * pLastToken = cxxTokenChainLast(g_cxx.pTokenChain);\n\n\t/*\n\t\tSpec is:\n\t\t\tenum-key attr(optional) identifier(optional) enum-base(optional)\n\t\t\t\t{ enumerator-list(optional) }\t(1)\n\t\t\tenum-key attr(optional) identifier enum-base(optional) ;\n\t\t\t\t(2)\t(since C++11)\n\n\t\t\tenum-key\t-\tone of enum, enum class(since C++11), or enum struct(since C++11)\n\t\t\tattr(C++11)\t-\toptional sequence of any number of attributes\n\t\t\tidentifier\t-\tthe name of the enumeration that's being declared.\n\t\t\t\tIf present, and if this declaration is a re-declaration, it may be preceded by\n\t\t\t\tnested-name-specifier(since C++11): sequence of names and scope-resolution\n\t\t\t\toperators ::, ending with scope-resolution operator. The name can be omitted\n\t\t\t\tonly in unscoped enumeration declarations\n\n\t\t\tenum-base(C++11)\t-\tcolon (:), followed by a type-specifier-seq that names an\n\t\t\t\tintegral type (if it is cv-qualified, qualifications are ignored)\n\t\t\tenumerator-list\t-\tcomma-separated list of enumerator definitions, each of which is\n\t\t\t\teither simply an identifier, which becomes the name of the enumerator, or an\n\t\t\t\tidentifier with an initializer: identifier = constexpr. In either case, the\n\t\t\t\tidentifier can be directly followed by an optional attribute specifier\n\t\t\t\tsequence. (since C++17)\n\t*/\n\n\t// Skip attr and class-head-name\n\tif(!cxxParserParseUpToOneOf(\n\t\t\tCXXTokenTypeEOF | CXXTokenTypeSemicolon | CXXTokenTypeKeyword |\n\t\t\t\tCXXTokenTypeSingleColon | CXXTokenTypeParenthesisChain |\n\t\t\t\tCXXTokenTypeOpeningBracket,\n\t\t\tfalse\n\t\t))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Could not parse enum name\");\n\t\treturn false;\n\t}\n\n\tbool bIsScopedEnum = false; // c++11 scoped enum (enum class | enum struct)\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeKeyword))\n\t{\n\t\t// enum class | enum struct ?\n\t\tif(\n\t\t\t(g_cxx.pToken->eKeyword == CXXKeywordSTRUCT) ||\n\t\t\t(g_cxx.pToken->eKeyword == CXXKeywordCLASS)\n\t\t)\n\t\t{\n\t\t\tbIsScopedEnum = true;\n\t\t}\n\n\t\tif(!cxxParserParseUpToOneOf(\n\t\t\t\tCXXTokenTypeEOF | CXXTokenTypeSemicolon | CXXTokenTypeSingleColon |\n\t\t\t\tCXXTokenTypeParenthesisChain | CXXTokenTypeOpeningBracket,\n\t\t\t\tfalse\n\t\t\t))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Could not parse enum name\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeEOF))\n\t{\n\t\t// tolerate EOF, treat as forward declaration\n\t\tcxxParserNewStatement();\n\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF before enum block: treating as forward declaration\");\n\t\treturn true;\n\t}\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeParenthesisChain))\n\t{\n\t\tif(uInitialKeywordState & CXXParserKeywordStateSeenTypedef)\n\t\t{\n\t\t\tbool bR;\n\t\t\tg_cxx.uKeywordState &= ~CXXParserKeywordStateSeenTypedef;\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found parenthesis after typedef: parsing as generic typedef\");\n\t\t\tbR = cxxParserParseGenericTypedef();\n\t\t\tcxxParserNewStatement();\n\t\t\treturn bR;\n\t\t}\n\t\t// probably a function declaration/prototype\n\t\t// something like enum x func()....\n\t\t// do not clear statement\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Probably a function declaration!\");\n\t\treturn true;\n\t}\n\n\t// If we have found a semicolon then we might be in the special case of KnR function\n\t// declaration. This requires at least 5 tokens and has some additional constraints.\n\t// See cxxParserMaybeParseKnRStyleFunctionDefinition() for more informations.\n\tif(\n\t\t\t// found semicolon\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSemicolon) &&\n\t\t\t// many tokens before the enum keyword\n\t\t\t(iInitialTokenCount > 3) &&\n\t\t\t// C language\n\t\t\tcxxParserCurrentLanguageIsC() &&\n\t\t\t// global scope\n\t\t\tcxxScopeIsGlobal() &&\n\t\t\t// no typedef\n\t\t\t(!(uInitialKeywordState & CXXParserKeywordStateSeenTypedef))\n\t\t)\n\t{\n\t\tCXX_DEBUG_PRINT(\"Maybe KnR function definition\");\n\n\t\tswitch(cxxParserMaybeParseKnRStyleFunctionDefinition())\n\t\t{\n\t\t\tcase 1:\n\t\t\t\t// parser moved forward and started a new statement\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"K&R parser did the job\");\n\t\t\t\treturn true;\n\t\t\tbreak;\n\t\t\tcase 0:\n\t\t\t\t// something else, go ahead\n\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to check for K&R style function definition\");\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif(iInitialTokenCount > 1)\n\t\tcxxParserCleanupEnumStructClassOrUnionPrefixChain(CXXKeywordENUM,pLastToken);\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSemicolon))\n\t{\n\t\tCXX_DEBUG_PRINT(\"Found semicolon, maybe typedef or variable declaration\");\n\n\t\t// scoped enums can't be used to declare variables.\n\t\tif((!bIsScopedEnum) && (g_cxx.pTokenChain->iCount > 3))\n\t\t{\n\t\t\t // [typedef] enum X Y; <-- typedef has been removed!\n\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenTypedef)\n\t\t\t\tcxxParserExtractTypedef(g_cxx.pTokenChain,true,false);\n\t\t\telse\n\t\t\t\tcxxParserExtractVariableDeclarations(g_cxx.pTokenChain,0);\n\t\t}\n\n\t\tcxxParserNewStatement();\n\t\tCXX_DEBUG_LEAVE();\n\t\treturn true;\n\t}\n\n\t// colon or opening bracket\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIsOneOf(g_cxx.pToken,CXXTokenTypeSingleColon | CXXTokenTypeOpeningBracket),\n\t\t\t\"We should be pointing to a : or a {\"\n\t\t);\n\n\t// check if we can extract a class name identifier now\n\tCXXToken * pEnumName = cxxTokenChainLastTokenOfType(\n\t\t\tg_cxx.pTokenChain,\n\t\t\tCXXTokenTypeIdentifier\n\t\t);\n\n\tCXXToken * pTypeBegin; // no need to NULLify, only pTypeEnd matters.\n\tCXXToken * pTypeEnd = NULL;\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSingleColon))\n\t{\n\t\t// skip type\n\t\tCXX_DEBUG_PRINT(\"Single colon, trying to skip type\");\n\n\t\tpTypeBegin = g_cxx.pToken;\n\n\t\tif(!cxxParserParseUpToOneOf(\n\t\t\t\tCXXTokenTypeEOF | CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket,\n\t\t\t\tfalse))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Could not parse enum type\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeEOF))\n\t\t{\n\t\t\t// tolerate EOF, treat as forward declaration\n\t\t\tcxxParserNewStatement();\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF before enum block: can't decode this\");\n\t\t\treturn true;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSemicolon))\n\t\t{\n\t\t\tbool bMember = (cxxScopeGetVariableKind() == CXXTagKindMEMBER);\n\t\t\tif (bMember)\n\t\t\t{\n\t\t\t\t// enum type structure member with bit-width:\n\t\t\t\t// e.g.\n\t\t\t\t//    sturct { enum E m: 2; } v;\n\t\t\t\tCXX_DEBUG_PRINT(\"Found semicolon, member definition with bit-width\");\n\t\t\t\tcxxParserExtractVariableDeclarations(g_cxx.pTokenChain, 0);\n\t\t\t}\n\t\t\tcxxParserNewStatement();\n\t\t\tif (bMember)\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Semicolon before enum block: can't decode this\");\n\t\t\telse\n\t\t\t\tCXX_DEBUG_LEAVE();\n\t\t\treturn true;\n\t\t}\n\n\t\t// certainly opening bracket now.\n\t\tif(g_cxx.pToken->pPrev != pTypeBegin)\n\t\t{\n\t\t\t// there were tokens between the semicolon and the type begin\n\t\t\tpTypeBegin = pTypeBegin->pNext;\n\t\t\tpTypeEnd = g_cxx.pToken->pPrev;\n\t\t}\n\t}\n\n\n\tint iPushedScopes = 0;\n\tbool bAnonymous = false;\n\n\tif(pEnumName)\n\t{\n\t\t// good.\n\t\t// It may be qualified though.\n\t\tif(cxxParserCurrentLanguageIsCPP())\n\t\t{\n\t\t\tCXXToken * pNamespaceBegin = pEnumName;\n\t\t\tCXXToken * pPrev = pEnumName->pPrev;\n\t\t\twhile(pPrev)\n\t\t\t{\n\t\t\t\tif(!cxxTokenTypeIs(pPrev,CXXTokenTypeMultipleColons))\n\t\t\t\t\tbreak;\n\t\t\t\tpPrev = pPrev->pPrev;\n\t\t\t\tif(!pPrev)\n\t\t\t\t\tbreak;\n\t\t\t\tif(!cxxTokenTypeIs(pPrev,CXXTokenTypeIdentifier))\n\t\t\t\t\tbreak;\n\t\t\t\tpNamespaceBegin = pPrev;\n\t\t\t\tpPrev = pPrev->pPrev;\n\t\t\t}\n\n\t\t\twhile(pNamespaceBegin != pEnumName)\n\t\t\t{\n\t\t\t\tCXXToken * pNext = pNamespaceBegin->pNext;\n\t\t\t\tcxxTokenChainTake(g_cxx.pTokenChain,pNamespaceBegin);\n\t\t\t\tif(cxxParserCurrentLanguageIsCPP())\n\t\t\t\t{\n\t\t\t\t\t// FIXME: We don't really know if it's a class!\n\t\t\t\t\tcxxScopePush(pNamespaceBegin,CXXScopeTypeClass,CXXScopeAccessUnknown);\n\t\t\t\t} else {\n\t\t\t\t\t// it's a syntax error, but be tolerant\n\t\t\t\t}\n\t\t\t\tiPushedScopes++;\n\t\t\t\tpNamespaceBegin = pNext->pNext;\n\t\t\t}\n\t\t}\n\n\t\tCXX_DEBUG_PRINT(\"Enum name is %s\",vStringValue(pEnumName->pszWord));\n\t\tcxxTokenChainTake(g_cxx.pTokenChain,pEnumName);\n\t} else {\n\t\tpEnumName = cxxTokenCreateAnonymousIdentifier(CXXTagKindENUM, NULL);\n\t\tbAnonymous = true;\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Enum name is %s (anonymous)\",\n\t\t\t\tvStringValue(pEnumName->pszWord)\n\t\t\t);\n\t}\n\n\n\ttagEntryInfo * tag = cxxTagBegin(CXXTagKindENUM,pEnumName);\n\n\tint iCorkQueueIndex = CORK_NIL;\n\tint iCorkQueueIndexFQ = CORK_NIL;\n\n\tbool bEnumExported = false;\n\tif(tag)\n\t{\n\t\t// FIXME: this is debatable\n\t\ttag->isFileScope = !isInputHeaderFile();\n\n\t\tif (bAnonymous)\n\t\t\tmarkTagExtraBit (tag, XTAG_ANONYMOUS);\n\n\t\tCXXToken * pTypeName = NULL;\n\t\tvString * pszProperties = NULL;\n\n\t\tif(pTypeEnd)\n\t\t{\n\t\t\tCXX_DEBUG_ASSERT(pTypeBegin,\"Type begin should be also set here\");\n\t\t\tpTypeName = cxxTagCheckAndSetTypeField(pTypeBegin,pTypeEnd);\n\t\t}\n\n\n\t\tunsigned int uProperties = 0;\n\t\tif(bIsScopedEnum)\n\t\t\tuProperties |= CXXTagPropertyScopedEnum;\n\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)\n\t\t{\n\t\t\tuProperties |= CXXTagPropertyExport;\n\t\t\tbEnumExported = true;\n\t\t}\n\t\ttag->isFileScope = (bEnumExported || cxxScopeIsExported())\n\t\t\t? 0\n\t\t\t: tag->isFileScope;\n\n\t\tif(uProperties)\n\t\t\tpszProperties = cxxTagSetProperties(uProperties);\n\n\t\tiCorkQueueIndex = cxxTagCommit(&iCorkQueueIndexFQ);\n\t\tcxxTagUseTokenAsPartOfDefTag(iCorkQueueIndex, pEnumName);\n\n\t\tif (pszProperties)\n\t\t\tvStringDelete (pszProperties);\n\n\t\tif(pTypeName)\n\t\t\tcxxTokenDestroy(pTypeName);\n\t}\n\n\tcxxScopePushExported(pEnumName,CXXScopeTypeEnum,CXXScopeAccessPublic, bEnumExported);\n\tiPushedScopes++;\n\n\tvString * pScopeName = cxxScopeGetFullNameAsString();\n\n\t// Special kind of block\n\tfor(;;)\n\t{\n\t\tcxxTokenChainClear(g_cxx.pTokenChain);\n\n\t\tif(!cxxParserParseUpToOneOf(\n\t\t\t\tCXXTokenTypeComma | CXXTokenTypeClosingBracket | CXXTokenTypeEOF,\n\t\t\t\tfalse\n\t\t\t))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse enum contents\");\n\t\t\tif(pScopeName)\n\t\t\t\tvStringDelete(pScopeName);\n\t\t\treturn false;\n\t\t}\n\n\t\tCXXToken * pFirst = cxxTokenChainFirst(g_cxx.pTokenChain);\n\n\t\t// enumerator.\n\t\tif(\n\t\t\t\t(g_cxx.pTokenChain->iCount > 1) &&\n\t\t\t\tcxxTokenTypeIs(pFirst,CXXTokenTypeIdentifier)\n\t\t\t)\n\t\t{\n\t\t\ttag = cxxTagBegin(CXXTagKindENUMERATOR,pFirst);\n\t\t\tif(tag)\n\t\t\t{\n\t\t\t\t// If the enum is export'ed, we consider that its\n\t\t\t\t// enumerators are not limited in a file scope.\n\t\t\t\ttag->isFileScope = !isInputHeaderFile() && !cxxScopeIsExported();\n\n\t\t\t\tcxxTagCommit(NULL);\n\t\t\t}\n\t\t}\n\n\t\tif(cxxTokenTypeIsOneOf(\n\t\t\t\tg_cxx.pToken,\n\t\t\t\tCXXTokenTypeEOF | CXXTokenTypeClosingBracket\n\t\t\t))\n\t\t\tbreak;\n\t}\n\n\tif(iCorkQueueIndex > CORK_NIL)\n\t{\n\t\tcxxParserMarkEndLineForTagInCorkQueue(iCorkQueueIndex);\n\t\tif(iCorkQueueIndexFQ > CORK_NIL)\n\t\t\tcxxParserMarkEndLineForTagInCorkQueue(iCorkQueueIndexFQ);\n\t}\n\n\twhile(iPushedScopes > 0)\n\t{\n\t\tcxxScopePop();\n\t\tiPushedScopes--;\n\t}\n\n\tbool bRet = cxxParserParseEnumStructClassOrUnionFullDeclarationTrailer(\n\t\t\tuInitialKeywordState,\n\t\t\tCXXKeywordENUM,\n\t\t\tvStringValue(pScopeName)\n\t\t);\n\n\tif(pScopeName)\n\t\tvStringDelete(pScopeName);\n\n\tcxxParserNewStatement();\n\tCXX_DEBUG_LEAVE();\n\treturn bRet;\n}\n\nstatic bool cxxParserParseClassStructOrUnionInternal(\n\t\tCXXKeyword eKeyword,\n\t\tunsigned int uTagKind,\n\t\tunsigned int uScopeType\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\n\tunsigned int uInitialKeywordState = g_cxx.uKeywordState;\n\tint iInitialTokenCount = g_cxx.pTokenChain->iCount;\n\tCXXToken * pLastToken = cxxTokenChainLast(g_cxx.pTokenChain);\n\tbool bAnonymous = false;\n\n\t/*\n\t\tSpec is:\n\t\t\tclass-key attr class-head-name base-clause { member-specification }\n\n\t\t\tclass-key\t-\tone of class or struct. The keywords are identical\n\t\t\t\texcept for the default member access and the default base class access.\n\t\t\tattr(C++11)\t-\toptional sequence of any number of attributes,\n\t\t\t\tmay include alignas specifier\n\t\t\tclass-head-name\t-\tthe name of the class that's being defined.\n\t\t\t\tOptionally qualified, optionally followed by keyword final.\n\t\t\t\tThe name may be omitted, in which case the class is unnamed (note\n\t\t\t\tthat unnamed class cannot be final)\n\t\t\tbase-clause\t-\toptional list of one or more parent classes and the\n\t\t\t\tmodel of inheritance used for each (see derived class)\n\t\t\tmember-specification\t-\tlist of access specifiers, member object and\n\t\t\t\tmember function declarations and definitions (see below)\n\t*/\n\n\t// Skip attr and class-head-name\n\n\t// enable \"final\" keyword handling\n\tcxxKeywordEnableFinal(true);\n\n\tunsigned int uTerminatorTypes = CXXTokenTypeEOF | CXXTokenTypeSingleColon |\n\t\t\tCXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket |\n\t\t\tCXXTokenTypeSmallerThanSign | (cxxParserCurrentLanguageIsCPP()? CXXTokenTypeKeyword: 0) |\n\t\t\tCXXTokenTypeParenthesisChain;\n\n\tif(uTagKind != CXXTagCPPKindCLASS)\n\t\tuTerminatorTypes |= CXXTokenTypeAssignment;\n\n\tbool bRet;\n\n\tfor(;;)\n\t{\n\t\tbRet = cxxParserParseUpToOneOf(uTerminatorTypes, false);\n\n\t\tif(!bRet)\n\t\t{\n\t\t\tcxxKeywordEnableFinal(false);\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Could not parse class/struct/union name\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeKeyword))\n\t\t{\n\t\t\t/* The statement declears or defines an operator,\n\t\t\t * not a class, struct not union. */\n\t\t\tif(g_cxx.pToken->eKeyword == CXXKeywordOPERATOR)\n\t\t\t\treturn true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeParenthesisChain) &&\n\t\t\t(\n\t\t\t\t(\n\t\t\t\t\t// struct alignas(n) ...\n\t\t\t\t\tcxxTokenIsKeyword(g_cxx.pToken->pPrev,CXXKeywordALIGNAS)\n\t\t\t\t) || (\n\t\t\t\t\t// things like __builtin_align__(16)\n\t\t\t\t\t!cxxParserTokenChainLooksLikeFunctionParameterList(g_cxx.pToken->pChain,NULL)\n\t\t\t\t)\n\t\t\t)\n\t\t)\n\t\t\tcontinue;\n\n\t\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSmallerThanSign))\n\t\t\tbreak;\n\n\t\t// Probably a template specialisation\n\t\tif(!cxxParserCurrentLanguageIsCPP())\n\t\t{\n\t\t\tcxxKeywordEnableFinal(false);\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Template specialization in C language?\");\n\t\t\treturn false;\n\t\t}\n\n\t\t// template<typename T> struct X<int>\n\t\t// {\n\t\t// }\n\n\t\tif(g_cxx.pTemplateSpecializationTokenChain)\n\t\t{\n\t\t\tcxxTokenChainDestroy(g_cxx.pTemplateSpecializationTokenChain);\n\t\t\tg_cxx.pTemplateSpecializationTokenChain = NULL;\n\t\t}\n\n\t\tg_cxx.pTemplateSpecializationTokenChain = cxxParserParseTemplateAngleBracketsToSeparateChain(false);\n\t\tif(!g_cxx.pTemplateSpecializationTokenChain)\n\t\t{\n\t\t\tcxxKeywordEnableFinal(false);\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Could not parse class/struct/union name\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Once we reached the terminator, \"final\" is not a keyword anymore.\n\tcxxKeywordEnableFinal(false);\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeParenthesisChain))\n\t{\n\t\tif(uInitialKeywordState & CXXParserKeywordStateSeenTypedef)\n\t\t{\n\t\t\tbool bR;\n\t\t\tg_cxx.uKeywordState &= ~CXXParserKeywordStateSeenTypedef;\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found parenthesis after typedef: parsing as generic typedef\");\n\t\t\tbR = cxxParserParseGenericTypedef();\n\t\t\tcxxParserNewStatement();\n\t\t\treturn bR;\n\t\t}\n\n\t\t// probably a function declaration/prototype\n\t\t// something like struct x * func()....\n\t\t// do not clear statement\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Probably a function declaration!\");\n\t\treturn true;\n\t}\n\n\t// If we have found a semicolon then we might be in the special case of KnR function\n\t// declaration. This requires at least 5 tokens and has some additional constraints.\n\t// See cxxParserMaybeParseKnRStyleFunctionDefinition() for more informations.\n\t// FIXME: This block is duplicated in enum\n\tif(\n\t\t\t// found semicolon\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSemicolon) &&\n\t\t\t// many tokens before the enum keyword\n\t\t\t(iInitialTokenCount > 3) &&\n\t\t\t// C language\n\t\t\tcxxParserCurrentLanguageIsC() &&\n\t\t\t// global scope\n\t\t\tcxxScopeIsGlobal() &&\n\t\t\t// no typedef\n\t\t\t(!(uInitialKeywordState & CXXParserKeywordStateSeenTypedef))\n\t\t)\n\t{\n\t\tCXX_DEBUG_PRINT(\"Maybe KnR function definition?\");\n\n\t\tswitch(cxxParserMaybeParseKnRStyleFunctionDefinition())\n\t\t{\n\t\t\tcase 1:\n\t\t\t\t// parser moved forward and started a new statement\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"K&R function definition parser did the job\");\n\t\t\t\treturn true;\n\t\t\tbreak;\n\t\t\tcase 0:\n\t\t\t\t// something else, go ahead\n\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to check for K&R style function definition\");\n\t\t\t\treturn false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif(iInitialTokenCount > 1)\n\t\tcxxParserCleanupEnumStructClassOrUnionPrefixChain(eKeyword,pLastToken);\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSemicolon))\n\t{\n\t\tif(g_cxx.pTokenChain->iCount > 3)\n\t\t{\n\t\t\t// [typedef] struct X Y; <-- typedef has been removed!\n\t\t\tif(uInitialKeywordState & CXXParserKeywordStateSeenTypedef)\n\t\t\t\tcxxParserExtractTypedef(g_cxx.pTokenChain,true,false);\n\t\t\telse if(!(g_cxx.uKeywordState & CXXParserKeywordStateSeenFriend))\n\t\t\t\tcxxParserExtractVariableDeclarations(g_cxx.pTokenChain,0);\n\t\t}\n\n\t\tcxxParserNewStatement();\n\t\tCXX_DEBUG_LEAVE();\n\t\treturn true;\n\t}\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeAssignment))\n\t{\n\t\t// struct X Y = ...;\n\t\tbool bCanExtractVariables = g_cxx.pTokenChain->iCount > 3;\n\n\t\t// Skip the initialization (which almost certainly contains a block)\n\t\tif(!cxxParserParseUpToOneOf(CXXTokenTypeEOF | CXXTokenTypeSemicolon, false))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to EOF/semicolon\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif(bCanExtractVariables)\n\t\t\tcxxParserExtractVariableDeclarations(g_cxx.pTokenChain,0);\n\n\t\tcxxParserNewStatement();\n\t\tCXX_DEBUG_LEAVE();\n\t\treturn true;\n\t}\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeEOF))\n\t{\n\t\t// tolerate EOF, just ignore this\n\t\tcxxParserNewStatement();\n\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF: ignoring\");\n\t\treturn true;\n\t}\n\n\t// semicolon or opening bracket\n\n\t// check if we can extract a class name identifier\n\tCXXToken * pClassName = cxxTokenChainLastTokenOfType(\n\t\t\tg_cxx.pTokenChain,\n\t\t\tCXXTokenTypeIdentifier\n\t\t);\n\n\t// If no identifier has been found we can try some fallbacks.\n\tif(!pClassName)\n\t{\n\t\t// If we're in C++ mode, but C++ language hasn't been confirmed yet,\n\t\t// and there is a C++ specific keyword just before the terminator we found\n\t\t// then we'll try to use it as class/struct/union name.\n\t\tif(\n\t\t\tcxxParserCurrentLanguageIsCPP() &&\n\t\t\t(!g_cxx.bConfirmedCPPLanguage) &&\n\t\t\t(eKeyword != CXXKeywordCLASS) &&\n\t\t\t(g_cxx.pTokenChain->iCount >= 3) &&\n\t\t\tcxxTokenTypeIs(g_cxx.pToken->pPrev,CXXTokenTypeKeyword) &&\n\t\t\tcxxKeywordIsCPPSpecific(g_cxx.pToken->pPrev->eKeyword)\n\t\t)\n\t\t{\n\t\t\tpClassName = g_cxx.pToken->pPrev;\n\t\t\tpClassName->eType = CXXTokenTypeIdentifier;\n\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\"Found no class/struct/union name identifier but there is '%s' which might look good\",\n\t\t\t\t\tvStringValue(pClassName->pszWord)\n\t\t\t\t);\n\t\t}\n\t}\n\n\tint iPushedScopes = 0;\n\n\tif(pClassName)\n\t{\n\t\t// good.\n\t\t// It may be qualified though.\n\t\tCXXToken * pNamespaceBegin = pClassName;\n\t\tCXXToken * pPrev = pClassName->pPrev;\n\t\twhile(pPrev)\n\t\t{\n\t\t\tif(!cxxTokenTypeIs(pPrev,CXXTokenTypeMultipleColons))\n\t\t\t\tbreak;\n\t\t\tpPrev = pPrev->pPrev;\n\t\t\tif(!pPrev)\n\t\t\t\tbreak;\n\t\t\tif(!cxxTokenTypeIs(pPrev,CXXTokenTypeIdentifier))\n\t\t\t\tbreak;\n\t\t\tpNamespaceBegin = pPrev;\n\t\t\tpPrev = pPrev->pPrev;\n\t\t}\n\n\t\twhile(pNamespaceBegin != pClassName)\n\t\t{\n\t\t\tCXXToken * pNext = pNamespaceBegin->pNext;\n\t\t\tcxxTokenChainTake(g_cxx.pTokenChain,pNamespaceBegin);\n\t\t\tif(cxxParserCurrentLanguageIsCPP())\n\t\t\t{\n\t\t\t\t// FIXME: We don't really know if it's a class!\n\t\t\t\tcxxScopePush(pNamespaceBegin,CXXScopeTypeClass,CXXScopeAccessUnknown);\n\t\t\t\tiPushedScopes++;\n\t\t\t} else {\n\t\t\t\t// it's a syntax error, but be tolerant\n\t\t\t\tcxxTokenDestroy(pNamespaceBegin);\n\t\t\t}\n\t\t\tpNamespaceBegin = pNext->pNext;\n\t\t}\n\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Class/struct/union name is %s\",\n\t\t\t\tvStringValue(pClassName->pszWord)\n\t\t\t);\n\t\tcxxTokenChainTake(g_cxx.pTokenChain,pClassName);\n\t} else {\n\t\tpClassName = cxxTokenCreateAnonymousIdentifier(uTagKind, NULL);\n\t\tbAnonymous = true;\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Class/struct/union name is %s (anonymous)\",\n\t\t\t\tvStringValue(pClassName->pszWord)\n\t\t\t);\n\t}\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSingleColon))\n\t{\n\t\t// check for base classes\n\t\tcxxTokenChainClear(g_cxx.pTokenChain);\n\n\t\tif(!cxxParserParseUpToOneOf(\n\t\t\t\tCXXTokenTypeEOF | CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket,\n\t\t\t\tfalse\n\t\t\t))\n\t\t{\n\t\t\tcxxTokenDestroy(pClassName);\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse base class part\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif(cxxTokenTypeIsOneOf(g_cxx.pToken,CXXTokenTypeSemicolon | CXXTokenTypeEOF))\n\t\t{\n\t\t\tcxxTokenDestroy(pClassName);\n\t\t\tcxxParserNewStatement();\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Syntax error: ignoring\");\n\t\t\treturn true;\n\t\t}\n\n\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain); // remove the {\n\t} else {\n\t\tcxxTokenChainClear(g_cxx.pTokenChain);\n\t}\n\n\t// OK. This seems to be a valid class/struct/union declaration.\n\n\tif(\n\t\t\t(uTagKind == CXXTagCPPKindCLASS) &&\n\t\t\t(!g_cxx.bConfirmedCPPLanguage)\n\t\t)\n\t{\n\t\tCXX_DEBUG_PRINT(\"Succeeded in parsing a C++ class: this really seems to be C++\");\n\t\tg_cxx.bConfirmedCPPLanguage = true;\n\t}\n\n\ttagEntryInfo * tag = cxxTagBegin(uTagKind,pClassName);\n\n\tint iCorkQueueIndex = CORK_NIL;\n\tint iCorkQueueIndexFQ = CORK_NIL;\n\n\tbool bGotTemplate = g_cxx.pTemplateTokenChain &&\n\t\t\t(g_cxx.pTemplateTokenChain->iCount > 0) &&\n\t\t\tcxxParserCurrentLanguageIsCPP();\n\tbool bExported = uInitialKeywordState & CXXParserKeywordStateSeenExport;\n\n\tif(tag)\n\t{\n\t\tif (bAnonymous)\n\t\t\tmarkTagExtraBit (tag, XTAG_ANONYMOUS);\n\n\t\tif(g_cxx.pTokenChain->iCount > 0)\n\t\t{\n\t\t\t// Strip inheritance type information\n\t\t\t// FIXME: This could be optional!\n\n\t\t\tCXXToken * t = cxxTokenChainFirst(g_cxx.pTokenChain);\n\t\t\twhile(t)\n\t\t\t{\n\t\t\t\tif(\n\t\t\t\t\tcxxTokenTypeIs(t,CXXTokenTypeKeyword) &&\n\t\t\t\t\t(\n\t\t\t\t\t\t(t->eKeyword == CXXKeywordPUBLIC) ||\n\t\t\t\t\t\t(t->eKeyword == CXXKeywordPROTECTED) ||\n\t\t\t\t\t\t(t->eKeyword == CXXKeywordPRIVATE) ||\n\t\t\t\t\t\t(t->eKeyword == CXXKeywordVIRTUAL)\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tCXXToken * pNext = t->pNext;\n\t\t\t\t\tcxxTokenChainTake(g_cxx.pTokenChain,t);\n\t\t\t\t\tcxxTokenDestroy(t);\n\t\t\t\t\tt = pNext;\n\t\t\t\t} else {\n\t\t\t\t\tt = t->pNext;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(g_cxx.pTokenChain->iCount > 0)\n\t\t\t{\n\t\t\t\tcxxTokenChainCondense(\n\t\t\t\t\t\tg_cxx.pTokenChain,\n\t\t\t\t\t\tCXXTokenChainCondenseNoTrailingSpaces\n\t\t\t\t\t);\n\t\t\t\ttag->extensionFields.inheritance = vStringValue(\n\t\t\t\t\t\tg_cxx.pTokenChain->pHead->pszWord\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif(bGotTemplate)\n\t\t\tcxxTagHandleTemplateFields();\n\n\t\ttag->isFileScope = !isInputHeaderFile();\n\n\t\tunsigned int uProperties = 0;\n\t\tif(bExported)\n\t\t\tuProperties |= CXXTagPropertyExport;\n\t\t// Overwrite the assigned value if the language object is export'ed\n\t\t// directly or indirectly.\n\t\ttag->isFileScope = (bExported || cxxScopeIsExported())\n\t\t\t? 0\n\t\t\t: tag->isFileScope;\n\n\t\tvString * pszProperties = NULL;\n\n\t\tif(uProperties)\n\t\t\tpszProperties = cxxTagSetProperties(uProperties);\n\n\t\tiCorkQueueIndex = cxxTagCommit(&iCorkQueueIndexFQ);\n\t\tcxxTagUseTokenAsPartOfDefTag(iCorkQueueIndex, pClassName);\n\n\t\tvStringDelete (pszProperties); /* NULL is acceptable. */\n\t}\n\n\tcxxScopePushExported(\n\t\t\tpClassName,\n\t\t\tuScopeType,\n\t\t\t(uTagKind == CXXTagCPPKindCLASS) ?\n\t\t\t\tCXXScopeAccessPrivate : CXXScopeAccessPublic,\n\t\t\tbExported\n\t\t);\n\n\tif(\n\t\t\tbGotTemplate &&\n\t\t\tcxxTagKindEnabled(CXXTagCPPKindTEMPLATEPARAM)\n\t\t)\n\t\tcxxParserEmitTemplateParameterTags();\n\n\tvString * pScopeName = cxxScopeGetFullNameAsString();\n\n\tif(!cxxParserParseBlock(true))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse scope\");\n\t\tif(pScopeName)\n\t\t\tvStringDelete(pScopeName);\n\t\treturn false;\n\t}\n\n\tif(iCorkQueueIndex > CORK_NIL)\n\t{\n\t\tcxxParserMarkEndLineForTagInCorkQueue(iCorkQueueIndex);\n\t\tif(iCorkQueueIndexFQ > CORK_NIL)\n\t\t\tcxxParserMarkEndLineForTagInCorkQueue(iCorkQueueIndexFQ);\n\t}\n\n\tiPushedScopes++;\n\twhile(iPushedScopes > 0)\n\t{\n\t\tcxxScopePop();\n\t\tiPushedScopes--;\n\t}\n\n\tbRet = cxxParserParseEnumStructClassOrUnionFullDeclarationTrailer(\n\t\t\tuInitialKeywordState,\n\t\t\teKeyword,\n\t\t\tvStringValue(pScopeName)\n\t\t);\n\n\tif(pScopeName)\n\t\tvStringDelete(pScopeName);\n\n\tcxxParserNewStatement();\n\tCXX_DEBUG_LEAVE();\n\treturn bRet;\n}\n\nbool cxxParserParseClassStructOrUnion(\n\t\tCXXKeyword eKeyword,\n\t\tunsigned int uTagKind,\n\t\tunsigned int uScopeType\n\t)\n{\n\t// Trick for \"smart\" handling of public/protected/private keywords in .h files parsed as C++.\n\t// See the declaration of cxxKeywordEnablePublicProtectedPrivate for more info.\n\n\t// Enable public/protected/private keywords and save the previous state\n\tbool bEnablePublicProtectedPrivateKeywords = cxxKeywordEnablePublicProtectedPrivate(true);\n\n\tbool bRet = cxxParserParseClassStructOrUnionInternal(eKeyword,uTagKind,uScopeType);\n\n\t// If parsing succeeded, we're in C++ mode and the keyword is \"class\" then\n\t// we're fairly certain that the source code is *really* C++.\n\tif(g_cxx.bConfirmedCPPLanguage)\n\t\tbEnablePublicProtectedPrivateKeywords = true; // leave it on for good: we're (almost) sure it's C++\n\n\tcxxKeywordEnablePublicProtectedPrivate(bEnablePublicProtectedPrivateKeywords);\n\n\treturn bRet;\n}\n\n\n//\n// This is called at block level, upon encountering a semicolon, an unbalanced\n// closing bracket or EOF.The current token is something like:\n//   static const char * variable;\n//   int i = ....\n//   const QString & function(whatever) const;\n//   QString szText(\"ascii\");\n//   QString(...)\n//\n// Notable facts:\n//   - several special statements never end up here: this includes class,\n//     struct, union, enum, namespace, typedef, case, try, catch and other\n//     similar stuff.\n//   - the terminator is always at the end. It's either a semicolon, a closing\n//     bracket or an EOF\n//   - the parentheses and brackets are always condensed in subchains\n//     (unless unbalanced).\n//\n//                int __attribute__() function();\n//                                  |          |\n//                             (\"whatever\")  (int var1,type var2)\n//\n//                const char * strings[] = {}\n//                                    |     |\n//                                   [10]  { \"string\",\"string\",.... }\n//\n// This function tries to extract variable declarations and function prototypes.\n//\n// Yes, it's complex: it's because C/C++ is complex.\n//\nvoid cxxParserAnalyzeOtherStatement(void)\n{\n\tCXX_DEBUG_ENTER();\n\n#ifdef CXX_DO_DEBUGGING\n\tvString * pChain = cxxTokenChainJoin(g_cxx.pTokenChain,NULL,0);\n\tCXX_DEBUG_PRINT(\"Analyzing statement '%s'\",vStringValue(pChain));\n\tvStringDelete(pChain);\n#endif\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tg_cxx.pTokenChain->iCount > 0,\n\t\t\t\"There should be at least the terminator here!\"\n\t\t);\n\n\tif(g_cxx.pTokenChain->iCount < 2)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Empty statement\");\n\t\treturn;\n\t}\n\n\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenReturn)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Statement after a return is not interesting\");\n\t\treturn;\n\t}\n\n\t// Everything we can make sense of starts with an identifier or keyword.\n\t// This is usually a type name (eventually decorated by some attributes\n\t// and modifiers) with the notable exception of constructor/destructor\n\t// declarations (which are still identifiers tho).\n\n\tCXXToken * t = cxxTokenChainFirst(g_cxx.pTokenChain);\n\n\tif(!cxxTokenTypeIsOneOf(t,CXXTokenTypeIdentifier | CXXTokenTypeKeyword\n\t\t\t\t\t\t\t| CXXTokenTypeMultipleColons))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Statement does not start with an identifier or keyword\");\n\t\treturn;\n\t}\n\n\tenum CXXScopeType eScopeType = cxxScopeGetType();\n\n\tCXXFunctionSignatureInfo oInfo;\n\n\t// kinda looks like a function or variable instantiation... maybe\n\tif(eScopeType == CXXScopeTypeFunction)\n\t{\n\t\t// prefer variable declarations.\n\t\t// if none found then try function prototype\n\t\tif(cxxParserExtractVariableDeclarations(g_cxx.pTokenChain,0))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found variable declarations\");\n\t\t\treturn;\n\t\t}\n\n\t\t// FIXME: This *COULD* work but we should first rule out the possibility\n\t\t// of simple function calls like func(a). The function signature search\n\t\t// should be far stricter here.\n\n\t\t//if(cxxParserLookForFunctionSignature(g_cxx.pTokenChain,&oInfo,NULL))\n\t\t//\tcxxParserEmitFunctionTags(&oInfo,CXXTagKindPROTOTYPE,0);\n\n\t\tCXX_DEBUG_LEAVE();\n\t\treturn;\n\t}\n\n\t// prefer function.\n\tCXXTypedVariableSet oParamInfo;\n\tconst bool bPrototypeParams = cxxTagKindEnabled(CXXTagKindPROTOTYPE) && cxxTagKindEnabled(CXXTagKindPARAMETER);\ncheck_function_signature:\n\n\tif(\n\t\tcxxParserLookForFunctionSignature(g_cxx.pTokenChain,&oInfo,bPrototypeParams?&oParamInfo:NULL)\n\t\t// Even if we saw \"();\", we cannot say it is a function prototype; a macro expansion can be used to\n\t\t// initialize a top-level variable like:\n\t\t//   #define INIT() 0\n\t\t//   int i = INIT();\"\n\t\t&& ! (oInfo.pTypeEnd && cxxTokenTypeIs(oInfo.pTypeEnd,CXXTokenTypeAssignment))\n\t\t)\n\t{\n\t\tCXX_DEBUG_PRINT(\"Found function prototype\");\n\n\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenFriend)\n\t\t{\n\t\t\t// class X {\n\t\t\t//   friend void aFunction();\n\t\t\t// };\n\t\t\t// 'aFunction' is NOT X::aFunction() and in complex cases we can't figure\n\t\t\t// out its proper scope. Better avoid emitting this one.\n\t\t\tCXX_DEBUG_PRINT(\"But it has been preceded by the 'friend' keyword: this is not a real prototype\");\n\t\t} else {\n\t\t\tint iCorkQueueIndex, iCorkQueueIndexFQ;\n\t\t\tint iScopesPushed = cxxParserEmitFunctionTags(&oInfo,CXXTagKindPROTOTYPE,CXXEmitFunctionTagsPushScopes,&iCorkQueueIndex,&iCorkQueueIndexFQ);\n\t\t\tif (iCorkQueueIndex != CORK_NIL)\n\t\t\t{\n\t\t\t\tCXXToken * t = cxxTokenChainLast(g_cxx.pTokenChain);\n\t\t\t\tcxxParserSetEndLineForTagInCorkQueue (iCorkQueueIndex, t->iLineNumber);\n\t\t\t\tif (iCorkQueueIndexFQ != CORK_NIL)\n\t\t\t\t\tcxxParserSetEndLineForTagInCorkQueue (iCorkQueueIndexFQ, t->iLineNumber);\n\t\t\t}\n\n\t\t\tif(bPrototypeParams)\n\t\t\t\tcxxParserEmitFunctionParameterTags(&oParamInfo);\n\n\t\t\twhile(iScopesPushed > 0)\n\t\t\t{\n\t\t\t\tcxxScopePop();\n\t\t\t\tiScopesPushed--;\n\t\t\t}\n\t\t}\n\n\t\tif(oInfo.pTrailingComma)\n\t\t{\n\t\t\t// got a trailing comma after the function signature.\n\t\t\t// This might be a special case of multiple prototypes in a single declaration.\n\t\t\t//\n\t\t\t//   RetType functionA(...), functionB(...), functionC(...);\n\t\t\t//\n\t\t\t// Let's try to extract also the other declarations.\n\t\t\t//\n\t\t\t// We cannot rely on oInfo.pIdentifierStart after cxxParserEmitFunctionTags()\n\t\t\t// since it has been removed. Manually skip the initial type name.\n\n\t\t\tCXXToken * pBegin = cxxTokenChainFirstTokenNotOfType(\n\t\t\t\t\tg_cxx.pTokenChain,\n\t\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeKeyword\n\t\t\t\t);\n\n\t\t\tCXX_DEBUG_ASSERT(pBegin,\"We should have found a begin token here!\");\n\t\t\tcxxTokenChainDestroyRange(g_cxx.pTokenChain,pBegin,oInfo.pTrailingComma);\n\t\t\tgoto check_function_signature;\n\t\t}\n\n\t\tCXX_DEBUG_LEAVE();\n\t\treturn;\n\t}\n\n\tif(\n\t\tg_cxx.uKeywordState &\n\t\t(\n\t\t\t// Note that since C++-17 inline can be used as a modifier for variables\n\t\t\t// so don't be tempted to put it here.\n\t\t\tCXXParserKeywordStateSeenExplicit |\n\t\t\tCXXParserKeywordStateSeenOperator | CXXParserKeywordStateSeenVirtual\n\t\t)\n\t)\n\t{\n\t\t// must be function!\n\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\"WARNING: Was expecting to find a function prototype \" \\\n\t\t\t\t\t\"but did not find one\"\n\t\t\t);\n\t\treturn;\n\t}\n\n\tcxxParserExtractVariableDeclarations(g_cxx.pTokenChain,0);\n\tCXX_DEBUG_LEAVE_TEXT(\"Nothing else\");\n}\n\n\n// This is called when we encounter a \"public\", \"protected\" or \"private\" keyword\n// that is NOT in the class declaration header line.\nbool cxxParserParseAccessSpecifier(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeKeyword) &&\n\t\t\t(\n\t\t\t\t(g_cxx.pToken->eKeyword == CXXKeywordPUBLIC) ||\n\t\t\t\t(g_cxx.pToken->eKeyword == CXXKeywordPROTECTED) ||\n\t\t\t\t(g_cxx.pToken->eKeyword == CXXKeywordPRIVATE)\n\t\t\t),\n\t\t\t\"This must be called just after parsing public/protected/private\"\n\t\t);\n\n\tunsigned int uExtraType = 0;\n\n\tenum CXXScopeType eScopeType = cxxScopeGetType();\n\n\tstatic ptrArray *pSubparsers;\n\tif (!pSubparsers)\n\t{\n\t\tpSubparsers = ptrArrayNew(NULL);\n\t\tDEFAULT_TRASH_BOX (pSubparsers, ptrArrayDelete);\n\t}\n\n\tif(\n\t\t\t(eScopeType != CXXScopeTypeClass) &&\n\t\t\t(eScopeType != CXXScopeTypeUnion) &&\n\t\t\t(eScopeType != CXXScopeTypeStruct)\n\t\t)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\"Access specified in wrong context (%d)\",\n\t\t\t\teScopeType\n\t\t\t);\n\n\t\tif(!g_cxx.bConfirmedCPPLanguage)\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"C++ is not confirmed and the scope is not right: likely not access specifier\");\n\t\t\tg_cxx.pToken->eType = CXXTokenTypeIdentifier;\n\t\t\treturn true;\n\t\t}\n\n\t\t// this is a syntax error: we're in the wrong scope.\n\t\tCXX_DEBUG_LEAVE_TEXT(\"C++ language is confirmed: bailing out to avoid reporting broken structure\");\n\t\treturn false;\n\t}\n\n\tif(!g_cxx.bConfirmedCPPLanguage)\n\t{\n\t\tif(g_cxx.pToken->pPrev)\n\t\t{\n\t\t\t// ugly, there is something before the public/private/protected keyword.\n\t\t\t// This is likely a type or something else.\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\"C++ is not confirmed and there is something before: likely not access specifier\"\n\t\t\t\t);\n\t\t\tg_cxx.pToken->eType = CXXTokenTypeIdentifier;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tif (cxxSubparserNotifyParseAccessSpecifier (pSubparsers))\n\t\tuExtraType = CXXTokenTypeIdentifier;\n\n\tCXXToken * pInitialToken = g_cxx.pToken;\n\n\t// skip to the next :, without leaving scope.\n findColon:\n\tif(!cxxParserParseUpToOneOf(\n\t\t    uExtraType |\n\t\t\tCXXTokenTypeSingleColon | CXXTokenTypeSemicolon |\n\t\t\t\tCXXTokenTypeClosingBracket | CXXTokenTypeEOF,\n\t\t\tfalse\n\t\t))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to the next ;\");\n\t\tptrArrayClear (pSubparsers);\n\t\treturn false;\n\t}\n\n\tif (uExtraType && cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeIdentifier))\n\t{\n\t\tcxxSubparserNotifyfoundExtraIdentifierAsAccessSpecifier (pSubparsers,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t g_cxx.pToken);\n\t\tgoto findColon;\n\t}\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSingleColon))\n\t{\n\t\tif(!pInitialToken->pPrev)\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"The access specifier was the first token and I have found a colon: this is C++\");\n\t\t\tg_cxx.bConfirmedCPPLanguage = true;\n\t\t}\n\t}\n\n\tswitch(pInitialToken->eKeyword)\n\t{\n\t\tcase CXXKeywordPUBLIC:\n\t\t\tcxxScopeSetAccess(CXXScopeAccessPublic);\n\t\tbreak;\n\t\tcase CXXKeywordPRIVATE:\n\t\t\tcxxScopeSetAccess(CXXScopeAccessPrivate);\n\t\tbreak;\n\t\tcase CXXKeywordPROTECTED:\n\t\t\tcxxScopeSetAccess(CXXScopeAccessProtected);\n\t\tbreak;\n\t\tdefault:\n\t\t\tCXX_DEBUG_ASSERT(false,\"Bad keyword in cxxParserParseAccessSpecifier!\");\n\t\tbreak;\n\t}\n\n\tcxxTokenChainClear(g_cxx.pTokenChain);\n\tptrArrayClear (pSubparsers);\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\nbool cxxParserParseIfForWhileSwitchCatchParenthesis(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeKeyword),\n\t\t\t\"This function should be called only after encountering one of the keywords\"\n\t\t);\n\n\tCXXKeyword eKeyword = g_cxx.pToken->eKeyword;\n\n\tif(!cxxParserParseUpToOneOf(\n\t\t\tCXXTokenTypeParenthesisChain | CXXTokenTypeSemicolon |\n\t\t\t\tCXXTokenTypeOpeningBracket | CXXTokenTypeEOF,\n\t\t\tfalse\n\t\t))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse if/for/while/switch/catch up to parenthesis\");\n\t\treturn false;\n\t}\n\n\tif(cxxTokenTypeIsOneOf(\n\t\t\tg_cxx.pToken,\n\t\t\tCXXTokenTypeEOF | CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket\n\t\t))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\"Found EOF/semicolon/opening bracket while parsing if/for/while/switch/catch\"\n\t\t\t);\n\t\treturn true;\n\t}\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeParenthesisChain),\n\t\t\t\"Expected a parenthesis chain here\"\n\t\t);\n\n\tCXX_DEBUG_PRINT(\"Found if/for/while/switch/catch parenthesis chain\");\n\n\t// Extract variables from the parenthesis chain\n\n\tCXXTokenChain * pChain = g_cxx.pToken->pChain;\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tpChain->iCount >= 2,\n\t\t\t\"The parenthesis chain must have initial and final parenthesis\"\n\t\t);\n\n\t// There are several constructs that can fool the parser here.\n\t//\n\t// The most frequent problems arise with\n\t//\n\t//     if(a & b ...)\n\t//     if(a * b ...)\n\t//     if(a && b ...)\n\t//\n\t// which may or may not be variable declarations, depending on the\n\t// meaning of identifier a.\n\t// Other problems involve balanced operator that resemble templates:\n\t//\n\t//     if(a < b || c > d ...)\n\t//\n\t// Here we attempt to rule out these special cases.\n\n\t// First try the easy \"inclusive\" cases.\n\n\t// catch() always contains variable declarations\n\n\tbool bOkToExtractVariables = eKeyword == CXXKeywordCATCH;\n\n\tif(!bOkToExtractVariables)\n\t{\n\t\t// Another easy one: try parenthesis contents that start with a keyword.\n\t\t//\n\t\t//   if(const std::exception & e)\n\t\t//   if(int i ...\n\t\t//\n\t\tbOkToExtractVariables = cxxTokenTypeIs(\n\t\t\t\tcxxTokenChainAt(pChain,1),\n\t\t\t\tCXXTokenTypeKeyword\n\t\t\t);\n\n\t\tif(!bOkToExtractVariables)\n\t\t{\n\t\t\t// If there is &, && or * then we expect there to be also a = or\n\t\t\t// a semicolon that comes after it.\n\t\t\t// This is not 100% foolproof but works most of the times.\n\n\t\t\tCXXToken * pToken = cxxTokenChainFirstTokenOfType(\n\t\t\t\t\tpChain,\n\t\t\t\t\tCXXTokenTypeAnd | CXXTokenTypeMultipleAnds | CXXTokenTypeStar |\n\t\t\t\t\tCXXTokenTypeSmallerThanSign |\n\t\t\t\t\tCXXTokenTypeAssignment | CXXTokenTypeSemicolon\n\t\t\t\t);\n\n\t\t\tif(pToken)\n\t\t\t{\n\t\t\t\tswitch(pToken->eType)\n\t\t\t\t{\n\t\t\t\t\tcase CXXTokenTypeAnd:\n\t\t\t\t\tcase CXXTokenTypeMultipleAnds:\n\t\t\t\t\tcase CXXTokenTypeStar:\n\t\t\t\t\tcase CXXTokenTypeSmallerThanSign:\n\t\t\t\t\t\t// troublesome cases.\n\t\t\t\t\t\t// Require an assignment or a semicolon to follow\n\t\t\t\t\t\tbOkToExtractVariables = (cxxTokenChainFirstTokenOfType(\n\t\t\t\t\t\t\t\tpChain,\n\t\t\t\t\t\t\t\tCXXTokenTypeAssignment | CXXTokenTypeSemicolon\n\t\t\t\t\t\t\t) ? true : false); // ternary ?: needed because of MSVC\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXTokenTypeAssignment:\n\t\t\t\t\tcase CXXTokenTypeSemicolon:\n\t\t\t\t\t\t// looks ok\n\t\t\t\t\t\tbOkToExtractVariables = true;\n\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// should NOT happen!\n\t\t\t\t\t\tCXX_DEBUG_ASSERT(false,\"Unexpected token type\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// looks ok\n\t\t\t\tbOkToExtractVariables = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tif(bOkToExtractVariables)\n\t{\n\t\t// Kill the initial parenthesis\n\t\tcxxTokenChainDestroyFirst(pChain);\n\t\t// Fake the final semicolon\n\t\tCXXToken * t = cxxTokenChainLast(pChain);\n\t\tt->eType = CXXTokenTypeSemicolon;\n\t\tvStringClear(t->pszWord);\n\t\tvStringPut(t->pszWord,';');\n\n\t\t// and extract variable declarations if possible\n\t\tcxxParserExtractVariableDeclarations(pChain,0);\n\t}\n\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\nstatic rescanReason cxxParserMain(const unsigned int passCount)\n{\n\tcxxScopeClear();\n\tcxxTokenAPINewFile();\n\tcxxParserNewStatement();\n\n\tint kind_for_define = CXXTagKindMACRO;\n\tint kind_for_header = CXXTagKindINCLUDE;\n\tint kind_for_macro_param = CXXTagKindMACROPARAM;\n\tint role_for_macro_undef = CR_MACRO_UNDEF;\n\tint role_for_macro_condition = CR_MACRO_CONDITION;\n\tint role_for_header_system = CR_HEADER_SYSTEM;\n\tint role_for_header_local = CR_HEADER_LOCAL;\n\n\tAssert(passCount < 3);\n\n\tcppInit(\n\t\t\t(bool) (passCount > 1),\n\t\t\tfalse,\n\t\t\ttrue, // raw literals\n\t\t\tfalse,\n\t\t\tkind_for_define,\n\t\t\trole_for_macro_undef,\n\t\t\trole_for_macro_condition,\n\t\t\tkind_for_macro_param,\n\t\t\tkind_for_header,\n\t\t\trole_for_header_system,\n\t\t\trole_for_header_local,\n\t\t\tg_cxx.pFieldOptions[CXXTagFieldMacrodef].ftype\n\t\t);\n\n\tg_cxx.iChar = ' ';\n\n\tg_cxx.iNestingLevels = 0;\n\n\tg_cxx.bInCXX11Attribute = false;\n\n\tbool bRet = cxxParserParseBlock(false);\n\n\tcppTerminate ();\n\n\t// Shut up coveralls: LCOV_EXCL_START\n\tcxxTokenChainClear(g_cxx.pTokenChain);\n\tif(g_cxx.pTemplateTokenChain)\n\t\tcxxTokenChainClear(g_cxx.pTemplateTokenChain);\n\tif(g_cxx.pTemplateSpecializationTokenChain)\n\t\tcxxTokenChainClear(g_cxx.pTemplateSpecializationTokenChain);\n\t// Restart coveralls: LCOV_EXCL_END\n\n\tif(!bRet && (passCount == 1))\n\t{\n\t\tCXX_DEBUG_PRINT(\"Processing failed: trying to rescan\");\n\t\treturn RESCAN_FAILED;\n\t}\n\n\treturn RESCAN_NONE;\n}\n\nrescanReason cxxCParserMain(const unsigned int passCount)\n{\n\tCXX_DEBUG_ENTER();\n\tcxxTagInitForLanguage(g_cxx.eCLangType);\n\n\tg_cxx.bConfirmedCPPLanguage = false;\n\tcxxKeywordEnablePublicProtectedPrivate(false);\n\n\trescanReason r = cxxParserMain(passCount);\n\tCXX_DEBUG_LEAVE();\n\treturn r;\n}\n\nrescanReason cxxCUDAParserMain(const unsigned int passCount)\n{\n\tCXX_DEBUG_ENTER();\n\tcxxTagInitForLanguage(g_cxx.eCUDALangType);\n\n\t// CUDA is C.\n\tg_cxx.bConfirmedCPPLanguage = false;\n\tcxxKeywordEnablePublicProtectedPrivate(false);\n\n\trescanReason r = cxxParserMain(passCount);\n\tCXX_DEBUG_LEAVE();\n\treturn r;\n}\n\nrescanReason cxxCppParserMain(const unsigned int passCount)\n{\n\tCXX_DEBUG_ENTER();\n\tcxxTagInitForLanguage(g_cxx.eCPPLangType);\n\n\t// In header files we disable processing of public/protected/private keywords\n\t// until we either figure out that this is really C++ or we're start parsing\n\t// a struct/union.\n\tg_cxx.bConfirmedCPPLanguage = !isInputHeaderFile();\n\tcxxKeywordEnablePublicProtectedPrivate(g_cxx.bConfirmedCPPLanguage);\n\n\trescanReason r = cxxParserMain(passCount);\n\tcxxParserDestroyCurrentModuleToken();\n\tCXX_DEBUG_LEAVE();\n\treturn r;\n}\n\nstatic void cxxParserFirstInit(void)\n{\n\tmemset(&g_cxx,0,sizeof(CXXParserState));\n\n\tg_cxx.eCLangType = -1;\n\tg_cxx.eCPPLangType = -1;\n\tg_cxx.eCUDALangType = -1;\n\n\tcxxTokenAPIInit();\n\n\tg_cxx.pTokenChain = cxxTokenChainCreate();\n\n\tcxxScopeInit();\n\n\tg_bFirstRun = false;\n}\n\nvoid cxxCUDAParserInitialize(const langType language)\n{\n\tCXX_DEBUG_PRINT(\"Parser initialize for language CUDA\");\n\tif(g_bFirstRun)\n\t\tcxxParserFirstInit();\n\n\tg_cxx.eCUDALangType = language;\n\n\tcxxBuildKeywordHash(language,CXXLanguageCUDA);\n}\n\nvoid cxxCppParserInitialize(const langType language)\n{\n\tCXX_DEBUG_PRINT(\"Parser initialize for language C++\");\n\tif(g_bFirstRun)\n\t\tcxxParserFirstInit();\n\n\tg_cxx.eCPPLangType = language;\n\n\tcxxBuildKeywordHash(language,CXXLanguageCPP);\n}\n\nvoid cxxCParserInitialize(const langType language)\n{\n\tCXX_DEBUG_PRINT(\"Parser initialize for language C\");\n\tif(g_bFirstRun)\n\t\tcxxParserFirstInit();\n\n\tg_cxx.eCLangType = language;\n\n\tcxxBuildKeywordHash(language,CXXLanguageC);\n}\n\nvoid cxxParserCleanup(langType language CTAGS_ATTR_UNUSED,bool initialized CTAGS_ATTR_UNUSED)\n{\n\tif(g_bFirstRun)\n\t\treturn; // didn't run at all\n\n\t// This function is used as finalizer for all the sub-language parsers.\n\t// The next line forces this function to be called only once\n\tg_bFirstRun = true;\n\n\t// Shut up coveralls: LCOV_EXCL_START\n\tif(g_cxx.pUngetToken)\n\t\tcxxTokenDestroy(g_cxx.pUngetToken);\n\tif(g_cxx.pTokenChain)\n\t\tcxxTokenChainDestroy(g_cxx.pTokenChain);\n\tif(g_cxx.pTemplateTokenChain)\n\t\tcxxTokenChainDestroy(g_cxx.pTemplateTokenChain);\n\tif(g_cxx.pTemplateSpecializationTokenChain)\n\t\tcxxTokenChainDestroy(g_cxx.pTemplateSpecializationTokenChain);\n\t// Restart coveralls: LCOV_EXCL_END\n\n\tcxxScopeDone();\n\n\tcxxTokenAPIDone();\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_parser.h",
    "content": "#ifndef ctags_cxx_parser_h_\n#define ctags_cxx_parser_h_\n/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n\n#include \"parse.h\"\n\n// public parser api\nrescanReason cxxCParserMain(const unsigned int passCount);\nrescanReason cxxCppParserMain(const unsigned int passCount);\nrescanReason cxxCUDAParserMain(const unsigned int passCount);\n\nvoid cxxCParserInitialize(const langType language);\nvoid cxxCppParserInitialize(const langType language);\nvoid cxxCUDAParserInitialize(const langType language);\n\nvoid cxxParserCleanup(langType language, bool initialized);\n\n#endif //!ctags_cxx_parser_h_"
  },
  {
    "path": "parsers/cxx/cxx_parser_block.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_scope.h\"\n#include \"cxx_tag.h\"\n#include \"cxx_side_chain.h\"\n\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"../x-cpreprocessor.h\"\n#include \"debug.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n\n#include \"cxx_subparser_internal.h\"\n\n#include <string.h>\n\nstatic bool cxxParserParseBlockFull(bool bExpectClosingBracket, bool bExported);\n\nbool cxxParserParseBlockHandleOpeningBracket(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken, CXXTokenTypeOpeningBracket),\n\t\t\t\"This must be called when pointing at an opening bracket!\"\n\t\t);\n\n\tenum CXXScopeType eScopeType = cxxScopeGetType();\n\tbool bIsCPP = cxxParserCurrentLanguageIsCPP();\n\tCXXToken * pAux;\n\tbool bAssignment = false;\n\n\tif(\n\t\t\t(\n\t\t\t\t// something = {...}\n\t\t\t\t(g_cxx.pToken->pPrev) &&\n\t\t\t\tcxxTokenTypeIs(g_cxx.pToken->pPrev,CXXTokenTypeAssignment) &&\n\t\t\t\t(\n\t\t\t\t\t(eScopeType == CXXScopeTypeFunction) ||\n\t\t\t\t\t(eScopeType == CXXScopeTypeClass)    ||\n\t\t\t\t\t(eScopeType == CXXScopeTypeStruct)   ||\n\t\t\t\t\t(eScopeType == CXXScopeTypeUnion)    ||\n\t\t\t\t\t(eScopeType == CXXScopeTypeNamespace)\n\t\t\t\t)\n\t\t\t\t&& (bAssignment = true)\n\t\t\t) || (\n\t\t\t\tbIsCPP &&\n\t\t\t\t(g_cxx.pToken->pPrev) &&\n\t\t\t\t(\n\t\t\t\t\t(\n\t\t\t\t\t\t// T { arg1, arg2, ... } (1)\n\t\t\t\t\t\t// T object { arg1, arg2, ... } (2)\n\t\t\t\t\t\t// new T { arg1, arg2, ... } (3)\n\t\t\t\t\t\t// Class::Class() : member { arg1, arg2, ... } { (4)\n\t\t\t\t\t\tcxxTokenTypeIs(g_cxx.pToken->pPrev,CXXTokenTypeIdentifier) &&\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t// case 1\n\t\t\t\t\t\t\t(!g_cxx.pToken->pPrev->pPrev) ||\n\t\t\t\t\t\t\t// case 4\n\t\t\t\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\t\t\tg_cxx.pToken->pPrev->pPrev,\n\t\t\t\t\t\t\t\t\tCXXTokenTypeSingleColon | CXXTokenTypeComma\n\t\t\t\t\t\t\t) ||\n\t\t\t\t\t\t\t// cases 1,2,3 but not 4\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t// more parts of typename or maybe the \"new\" keyword before the identifier\n\t\t\t\t\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\t\t\t\tg_cxx.pToken->pPrev->pPrev,\n\t\t\t\t\t\t\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeStar | CXXTokenTypeAnd |\n\t\t\t\t\t\t\t\t\t\tCXXTokenTypeGreaterThanSign | CXXTokenTypeKeyword\n\t\t\t\t\t\t\t\t) &&\n\t\t\t\t\t\t\t\t// but no parenthesis (discard things like bool test() Q_DECL_NO_THROW { ... })\n\t\t\t\t\t\t\t\t(!(pAux = cxxTokenChainPreviousTokenOfType(\n\t\t\t\t\t\t\t\t\t\tg_cxx.pToken->pPrev->pPrev,\n\t\t\t\t\t\t\t\t\t\tCXXTokenTypeParenthesisChain\n\t\t\t\t\t\t\t\t\t))\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\t// \"override\" is handled as identifier since it's a keyword only after function signatures\n\t\t\t\t\t\t(strcmp(vStringValue(g_cxx.pToken->pPrev->pszWord),\"override\") != 0)\n\t\t\t\t\t) || (\n\t\t\t\t\t\t// type var[][][]..[] { ... }\n\t\t\t\t\t\t// (but not '[] { ... }' which is a parameterless lambda)\n\t\t\t\t\t\tcxxTokenTypeIs(g_cxx.pToken->pPrev,CXXTokenTypeSquareParenthesisChain) &&\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tpAux = cxxTokenChainPreviousTokenNotOfType(\n\t\t\t\t\t\t\t\t\tg_cxx.pToken->pPrev,\n\t\t\t\t\t\t\t\t\tCXXTokenTypeSquareParenthesisChain\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\tcxxTokenTypeIs(pAux,CXXTokenTypeIdentifier)\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t) || (\n\t\t\t\t// return { }\n\t\t\t\t(!g_cxx.pToken->pPrev) &&\n\t\t\t\t(g_cxx.uKeywordState & CXXParserKeywordStateSeenReturn)\n\t\t\t)\n\t\t)\n\t{\n\t\tbool bReduce = true;\n\t\t// Give subparsers a chance to inspect inside {} of of `something[] = {}`\n\t\t// if they want.\n\t\tif (bAssignment && g_cxx.pToken->pPrev->pPrev)\n\t\t\tbReduce = !cxxSubparserWantVariableBody (g_cxx.pToken->pPrev->pPrev);\n\n\t\t// array or list-like initialisation\n\n\t\tbool bRet = cxxParserParseAndCondenseCurrentSubchain(\n\t\t\t\tCXXTokenTypeOpeningBracket | CXXTokenTypeOpeningParenthesis |\n\t\t\t\t\tCXXTokenTypeOpeningSquareParenthesis,\n\t\t\t\tfalse,\n\t\t\t\tbReduce\n\t\t\t);\n\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Handled array or list-like initialisation or return\");\n\t\treturn bRet;\n\t}\n\n\t// In C++ mode check for lambdas\n\tCXXToken * pParenthesis;\n\n\tif(\n\t\tbIsCPP &&\n\t\t(pParenthesis = cxxParserOpeningBracketIsLambda())\n\t)\n\t{\n\t\tif(!cxxParserHandleLambda(pParenthesis))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Lambda handling failed\");\n\t\t\treturn false;\n\t\t}\n\n\t\t// Note that here we're leaving the token chain \"alive\" so further parsing can be performed.\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Lambda handling succeeded\");\n\t\treturn true;\n\t}\n\n\tint iScopes;\n\tint iCorkQueueIndex = CORK_NIL;\n\tint iCorkQueueIndexFQ = CORK_NIL;\n\n\tCXXFunctionSignatureInfo oInfo;\n\tbool bExported = false;\n\n\tif(eScopeType != CXXScopeTypeFunction)\n\t{\n\t\t// very likely a function definition\n\t\t// (but may be also a toplevel block, like \"extern \"C\" { ... }\")\n\t\tiScopes = cxxParserExtractFunctionSignatureBeforeOpeningBracket(&oInfo,&iCorkQueueIndex,&iCorkQueueIndexFQ);\n\n\t\t// FIXME: Handle syntax (5) of list initialization:\n\t\t//        Class::Class() : member { arg1, arg2, ... } {...\n\t\tbExported = (g_cxx.uKeywordState & CXXParserKeywordStateSeenExport);\n\t} else {\n\t\t// some kind of other block:\n\t\t// - anonymous block\n\t\t// - block after for(),while(),foreach(),if() and other similar stuff\n\t\t// (note that {}-style initializers have been handled above and thus are excluded)\n\n\t\tiScopes = 0;\n\t}\n\n\tcxxParserNewStatementFull(bExported);\n\n\tif(!cxxParserParseBlockFull(true, bExported))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse nested block\");\n\t\treturn false;\n\t}\n\n\tif(iScopes < 1)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"The block was not a function\");\n\t\treturn true;\n\t}\n\n\tunsigned long uEndPosition = cppGetInputLineNumber();\n\n\t// If the function contained a \"try\" keyword before the opening bracket\n\t// then it's likely to be a function-try-block and should be followed by a catch\n\t// block that is in the same scope.\n\n\tif(oInfo.uFlags & CXXFunctionSignatureInfoFunctionTryBlock)\n\t{\n\t\t// look for the catch blocks.\n\t\tCXX_DEBUG_PRINT(\"The function is a function-try-block: looking for catch blocks\");\n\n\t\tfor(;;)\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"Looking ahead for a catch block...\");\n\n\t\t\tif(!cxxParserParseNextToken())\n\t\t\t\tbreak; // EOF\n\n\t\t\tif(!cxxTokenIsKeyword(g_cxx.pToken,CXXKeywordCATCH))\n\t\t\t{\n\t\t\t\t// No more catches. Unget and exit.\n\t\t\t\tCXX_DEBUG_PRINT(\"No more catch blocks\");\n\t\t\t\tcxxParserUngetCurrentToken();\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// assume it's a catch block.\n\n\t\t\tCXX_DEBUG_PRINT(\"Found catch block\");\n\n\t\t\tif(!cxxParserParseIfForWhileSwitchCatchParenthesis())\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse the catch parenthesis\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// the standard requires a bracket here (catch block is always a compound statement).\n\n\t\t\tcxxParserNewStatement();\n\n\t\t\tif(!cxxParserParseNextToken())\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found EOF while looking for catch() block: playing nice\");\n\t\t\t\tbreak; // EOF (would be a syntax error!)\n\t\t\t}\n\n\t\t\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket))\n\t\t\t{\n\t\t\t\t// Aargh...\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found something unexpected while looking for catch() block: playing nice\");\n\t\t\t\tcxxParserUngetCurrentToken();\n\t\t\t\tbreak; // (would be a syntax error!)\n\t\t\t}\n\n\t\t\tif(!cxxParserParseBlock(true))\n\t\t\t\treturn false;\n\n\t\t\tuEndPosition = cppGetInputLineNumber();\n \t\t}\n \t}\n\n\tif(iCorkQueueIndex > CORK_NIL)\n\t{\n\t\tcxxParserSetEndLineForTagInCorkQueue(iCorkQueueIndex,uEndPosition);\n\t\tif(iCorkQueueIndexFQ > CORK_NIL)\n\t\t\tcxxParserSetEndLineForTagInCorkQueue(iCorkQueueIndexFQ,uEndPosition);\n\t}\n\twhile(iScopes > 0)\n\t{\n\t\tcxxScopePop();\n\t\tiScopes--;\n\t}\n\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\nstatic bool cxxParserParseBlockInternal(bool bExpectClosingBracket, bool bExported)\n{\n\tCXX_DEBUG_ENTER();\n\n\t//char * szScopeName = cxxScopeGetFullName();\n\t//CXX_DEBUG_PRINT(\"Scope name is '%s'\",szScopeName ? szScopeName : \"\");\n\n\tcxxParserNewStatementFull(bExported);\n\n\tif(bExpectClosingBracket)\n\t{\n\t\t// FIXME: this cpp handling is kind of broken:\n\t\t//        it works only because the moon is in the correct phase.\n\t\tcppBeginStatement();\n\t}\n\n\tCXXTokenChain *pSideChain = NULL;\n\tfor(;;)\n\t{\n\t\tif(!cxxParserParseNextToken())\n\t\t{\nfound_eof:\n\t\t\tcxxTokenChainDestroy(pSideChain);\n\t\t\tpSideChain = NULL;\n\n\t\t\tif(bExpectClosingBracket)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\"Syntax error: found EOF in block but a closing \" \\\n\t\t\t\t\t\t\t\"bracket was expected!\"\n\t\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF in main block\");\n\t\t\treturn true; // EOF\n\t\t}\n\t\tcxxSideChainAppendChain(pSideChain,g_cxx.pToken);\n\t\tpSideChain = NULL;\n\nprocess_token:\n\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Token '%s' of type 0x%02x\",\n\t\t\t\tvStringValue(g_cxx.pToken->pszWord),\n\t\t\t\tg_cxx.pToken->eType\n\t\t\t);\n\n\t\tif (cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeIdentifier)\n\t\t\t&& cxxScopeGetType() == CXXScopeTypeClass\n\t\t\t&& cxxSubparserNewIdentifierAsHeadOfMemberNotify(g_cxx.pToken))\n\t\t{\n\t\t\tpSideChain = cxxSideChainEject(g_cxx.pToken);\n\t\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (bExported)\n\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenExport;\n\n\t\tswitch(g_cxx.pToken->eType)\n\t\t{\n\t\t\tcase CXXTokenTypeKeyword:\n\t\t\t{\n\t\t\t\tswitch(g_cxx.pToken->eKeyword)\n\t\t\t\t{\n\t\t\t\t\tcase CXXKeywordNAMESPACE:\n\t\t\t\t\t{\n\t\t\t\t\t\tenum CXXScopeType eScopeType = cxxScopeGetType();\n\n\t\t\t\t\t\tif(\n\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t// toplevel or nested within a namespace\n\t\t\t\t\t\t\t\t\t(eScopeType == CXXScopeTypeNamespace) ||\n\t\t\t\t\t\t\t\t\t// namespace X = Y inside a function\n\t\t\t\t\t\t\t\t\t(eScopeType == CXXScopeTypeFunction)\n\t\t\t\t\t\t\t\t) && (\n\t\t\t\t\t\t\t\t\t// either certainly C++\n\t\t\t\t\t\t\t\t\tg_cxx.bConfirmedCPPLanguage ||\n\t\t\t\t\t\t\t\t\t// or a \"sane\" namespace syntax\n\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t!cxxTokenChainPreviousTokenOfType(\n\t\t\t\t\t\t\t\t\t\t\t\tg_cxx.pToken,\n\t\t\t\t\t\t\t\t\t\t\t\tCXXTokenTypeStar |\n\t\t\t\t\t\t\t\t\t\t\t\tCXXTokenTypeAnd |\n\t\t\t\t\t\t\t\t\t\t\t\tCXXTokenTypeKeyword\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!cxxParserParseNamespace())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse namespace\");\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// If we're pretty sure this is C++ then this is a syntax error.\n\t\t\t\t\t\t\t// If we're not sure (namely when we're in a *.h file) then\n\t\t\t\t\t\t\t// let's try to be flexible: treat the namespace keyword as an identifier.\n\t\t\t\t\t\t\tif(!g_cxx.bConfirmedCPPLanguage)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\t\t\t\"Found namespace in unexpected place, but we're not sure it's really C++ \"\n\t\t\t\t\t\t\t\t\t\"so we'll treat it as an identifier instead\"\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tg_cxx.pToken->eType = CXXTokenTypeIdentifier;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\t\t\"Found namespace in a wrong place: we're probably out of sync\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordTEMPLATE:\n\t\t\t\t\t\tif(\n\t\t\t\t\t\t\t// beginning of the statement\n\t\t\t\t\t\t\t(!g_cxx.pToken->pPrev) ||\n\t\t\t\t\t\t\t// previous token is not \".\" or \"->\", syntax that is found in\n\t\t\t\t\t\t\t//     p.template func<int>();\n\t\t\t\t\t\t\t(!cxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\t\t\tg_cxx.pToken->pPrev,\n\t\t\t\t\t\t\t\t\tCXXTokenTypeDotOperator | CXXTokenTypePointerOperator\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!cxxParserParseTemplatePrefix())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse template\");\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Here we are just after the \"template<parameters>\" prefix.\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Template keyword that is not a prefix\");\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordTYPEDEF:\n\t\t\t\t\t\t// Mark the next declaration as a typedef\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenTypedef;\n\t\t\t\t\t\tcxxTokenChainClear(g_cxx.pTokenChain);\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordENUM:\n\t\t\t\t\t\tif(!cxxParserParseEnum())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse enum\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordCLASS:\n\t\t\t\t\t\tif(\n\t\t\t\t\t\t\t// do not trigger on X<class Y>\n\t\t\t\t\t\t\t(!g_cxx.pToken->pPrev) ||\n\t\t\t\t\t\t\t(!cxxTokenTypeIsOneOf(g_cxx.pToken->pPrev,CXXTokenTypeSmallerThanSign | CXXTokenTypeComma))\n\t\t\t\t\t\t)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!cxxParserParseClassStructOrUnion(CXXKeywordCLASS,CXXTagCPPKindCLASS,CXXScopeTypeClass))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse class/struct/union\");\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordSTRUCT:\n\t\t\t\t\t\tif(\n\t\t\t\t\t\t\t// do not trigger on X<struct Y>\n\t\t\t\t\t\t\t(!g_cxx.pToken->pPrev) ||\n\t\t\t\t\t\t\t(!cxxTokenTypeIsOneOf(g_cxx.pToken->pPrev,CXXTokenTypeSmallerThanSign | CXXTokenTypeComma))\n\t\t\t\t\t\t)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!cxxParserParseClassStructOrUnion(CXXKeywordSTRUCT,CXXTagKindSTRUCT,CXXScopeTypeStruct))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse class/struct/union\");\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordUNION:\n\t\t\t\t\t\tif(\n\t\t\t\t\t\t\t// do not trigger on X<union Y>\n\t\t\t\t\t\t\t(!g_cxx.pToken->pPrev) ||\n\t\t\t\t\t\t\t(!cxxTokenTypeIsOneOf(g_cxx.pToken->pPrev,CXXTokenTypeSmallerThanSign | CXXTokenTypeComma))\n\t\t\t\t\t\t)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!cxxParserParseClassStructOrUnion(CXXKeywordUNION,CXXTagKindUNION,CXXScopeTypeUnion))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse class/struct/union\");\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordPUBLIC:\n\t\t\t\t\tcase CXXKeywordPROTECTED:\n\t\t\t\t\tcase CXXKeywordPRIVATE:\n\t\t\t\t\t\t// Note that the class keyword has its own handler\n\t\t\t\t\t\t// so the only possibility here is an access specifier\n\t\t\t\t\t\tif(!cxxParserParseAccessSpecifier())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse access specifier\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordUSING:\n\t\t\t\t\t\tif(!cxxParserParseUsingClause())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse using clause\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordIF:\n\t\t\t\t\tcase CXXKeywordFOR:\n\t\t\t\t\tcase CXXKeywordWHILE:\n\t\t\t\t\tcase CXXKeywordSWITCH:\n\t\t\t\t\tcase CXXKeywordCATCH:\n\t\t\t\t\t\tif(!cxxParserParseIfForWhileSwitchCatchParenthesis())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse if/for/while/switch/catch parenthesis\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Now we're just before the block that follows the parenthesis.\n\t\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t\t\t// Force the cpp preprocessor to think that we're in the middle of a statement.\n\t\t\t\t\t\tcppBeginStatement();\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordTRY:\n\t\t\t\t\t\t// We parse try in different ways depending on the context.\n\t\t\t\t\t\t// Inside a function, and without preceding tokens it's assumed to be\n\t\t\t\t\t\t// a plain try {} catch {} block. This is easy.\n\t\t\t\t\t\t// Out of a function it's likely to be a function try block:\n\t\t\t\t\t\t//    int f(int n = 2) try { ... } catch { ... }\n\t\t\t\t\t\t// Inside a function but with some preceding tokens it's likely to be a\n\t\t\t\t\t\t// lambda expressed as function-try-block.\n\t\t\t\t\t\t//    auto f() -> void try { ... } catch { ... }\n\t\t\t\t\t\tif((cxxScopeGetType() != CXXScopeTypeFunction) || g_cxx.pToken->pPrev)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCXX_DEBUG_PRINT(\"Found try that looks like a function-try-block\");\n\t\t\t\t\t\t\t// Maybe function-try-block.\n\t\t\t\t\t\t\t// Keep in the chain and continue parsing.\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Fall through.\n\t\t\t\t\tcase CXXKeywordELSE:\n\t\t\t\t\tcase CXXKeywordDO:\n\t\t\t\t\t\t// parse as normal statement/block\n\t\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t\t\t// Force the cpp preprocessor to think that we're in the middle of a statement.\n\t\t\t\t\t\tcppBeginStatement();\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordRETURN:\n\t\t\t\t\t\tif(cxxParserCurrentLanguageIsCPP())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// may be followed by a lambda, otherwise it's not interesting.\n\t\t\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenReturn;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// ignore\n\t\t\t\t\t\t\tif(!cxxParserParseUpToOneOf(CXXTokenTypeSemicolon | CXXTokenTypeEOF,\n\t\t\t\t\t\t\t\t   false))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse return\");\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordCONTINUE:\n\t\t\t\t\tcase CXXKeywordBREAK:\n\t\t\t\t\tcase CXXKeywordGOTO:\n\t\t\t\t\t\t// ignore\n\t\t\t\t\t\tif(!cxxParserParseUpToOneOf(CXXTokenTypeSemicolon | CXXTokenTypeEOF,\n\t\t\t\t\t\t\t   false))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse continue/break/goto\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordTHROW:\n\t\t\t\t\t\t// We ignore whole \"throw expressions\" as they contain nothing useful\n\t\t\t\t\t\t// and may confuse us. We keep \"throw\" when used as exception specification,\n\t\t\t\t\t\t// and this is certainly outside of a function and when the token chain\n\t\t\t\t\t\t// already contains at least a type, an identifier and a parenthesis.\n\t\t\t\t\t\t// This check seems excessive but keep in mind that we deal with\n\t\t\t\t\t\t// broken input and we might also be wrong about the current scope.\n\t\t\t\t\t\tif((cxxScopeGetType() == CXXScopeTypeFunction) || (g_cxx.pTokenChain->iCount < 3))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCXX_DEBUG_PRINT(\"Skipping throw statement\");\n\t\t\t\t\t\t\tif(!cxxParserParseUpToOneOf(CXXTokenTypeSemicolon | CXXTokenTypeEOF,\n\t\t\t\t\t\t\t\t   false))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to skip throw statement\");\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordCASE:\n\t\t\t\t\t\t// ignore\n\t\t\t\t\t\tif(!cxxParserParseUpToOneOf(\n\t\t\t\t\t\t\t\tCXXTokenTypeSemicolon | CXXTokenTypeEOF | CXXTokenTypeSingleColon,\n\t\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse case keyword\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordEXTERN:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenExtern;\n\n\t\t\t\t\t\tpSideChain = cxxSideChainEject(g_cxx.pToken);\n\t\t\t\t\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\n\t\t\t\t\t\tif(!cxxParserParseNextToken())\n\t\t\t\t\t\t\tgoto found_eof;\n\n\t\t\t\t\t\tcxxSideChainAppendChain(pSideChain,g_cxx.pToken);\n\t\t\t\t\t\tpSideChain = NULL;\n\n\t\t\t\t\t\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeStringConstant))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// assume extern \"language\"\n\n\t\t\t\t\t\t\t// Strictly speaking this is a C++ only syntax.\n\t\t\t\t\t\t\t// However we allow it also in C as it doesn't really hurt.\n\n\t\t\t\t\t\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\n\t\t\t\t\t\t\t// Note that extern \"C\" may be followed by a block with declarations\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   extern \"C\" { ... }\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// However in this case the declarations are ALSO definitions\n\t\t\t\t\t\t\t// and extern \"C\" is used only to specify the name mangling mode.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   extern \"C\" int x; <-- a declaration and not a definition\n\t\t\t\t\t\t\t//   extern \"C\" { int x; } <-- a declaration and definition: x IS defined\n\t\t\t\t\t\t\t//                             here and is NOT extern.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// A variable in an extern \"C\" block has to be re-declared extern again\n\t\t\t\t\t\t\t// to be really treated as declaration only.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   extern \"C\" { extern int x; }\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// So in this case we do NOT treat the inner declarations as extern\n\t\t\t\t\t\t\t// and we don't need specific handling code for this case.\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// something else: handle it the normal way\n\t\t\t\t\t\t\tgoto process_token;\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordSTATIC:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenStatic;\n\t\t\t\t\t\tpSideChain = cxxSideChainEject(g_cxx.pToken);\n\t\t\t\t\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordINLINE:\n\t\t\t\t\tcase CXXKeyword__INLINE:\n\t\t\t\t\tcase CXXKeyword__INLINE__:\n\t\t\t\t\tcase CXXKeyword__FORCEINLINE:\n\t\t\t\t\tcase CXXKeyword__FORCEINLINE__:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenInline;\n\t\t\t\t\t\tpSideChain = cxxSideChainEject(g_cxx.pToken);\n\t\t\t\t\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordEXPLICIT:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenExplicit;\n\t\t\t\t\t\tpSideChain = cxxSideChainEject(g_cxx.pToken);\n\t\t\t\t\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordOPERATOR:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenOperator;\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordVIRTUAL:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenVirtual;\n\t\t\t\t\t\tpSideChain = cxxSideChainEject(g_cxx.pToken);\n\t\t\t\t\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordMUTABLE:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenMutable;\n\t\t\t\t\t\tpSideChain = cxxSideChainEject(g_cxx.pToken);\n\t\t\t\t\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordFRIEND:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenFriend;\n\t\t\t\t\tbreak;\n\t\t\t\t\t// \"const\" and \"volatile\" are part of the type. Don't treat them specially\n\t\t\t\t\t// and don't attempt to extract an eventual typedef yet,\n\t\t\t\t\t// as there might be a struct/class/union keyword following.\n\t\t\t\t\tcase CXXKeywordVOLATILE:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenVolatile;\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordCONST:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenConst;\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordCONSTEXPR:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenConstexpr;\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordCONSTEVAL:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenConsteval;\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordCONSTINIT:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenConstinit;\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordTHREAD_LOCAL:\n\t\t\t\t\tcase CXXKeyword__THREAD:\n\t\t\t\t\tcase CXXKeyword_THREAD_LOCAL:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenThreadLocal;\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase CXXKeywordEXPORT:\n\t\t\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenExport;\n\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenTypedef)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tg_cxx.uKeywordState &= ~CXXParserKeywordStateSeenTypedef;\n\t\t\t\t\t\t\tif(!cxxParserParseGenericTypedef())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse generic typedef\");\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeSemicolon:\n\t\t\t{\n\t\t\t\tif(\n\t\t\t\t\t\t(cxxParserCurrentLanguageIsC()) &&\n\t\t\t\t\t\tcxxScopeIsGlobal() &&\n\t\t\t\t\t\t(!(g_cxx.uKeywordState & CXXParserKeywordStateSeenExtern)) &&\n\t\t\t\t\t\t(!(g_cxx.uKeywordState & CXXParserKeywordStateSeenTypedef))\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// Special handling of K&R style function declarations.\n\t\t\t\t\t// We might be in the following situation:\n\t\t\t\t\t//\n\t\t\t\t\t//  type whatever fname(par1,par2) int par1; int par2; {\n\t\t\t\t\t//                                        ^\n\t\t\t\t\t//\n\t\t\t\t\tswitch(cxxParserMaybeParseKnRStyleFunctionDefinition())\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\t// K&R parser did the job and started a new statement\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 0:\n\t\t\t\t\t\t\t// something else\n\t\t\t\t\t\t\tcxxParserAnalyzeOtherStatement();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to check for K&R style function definition\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// K&R style function declarations not allowed here.\n\t\t\t\t\tcxxParserAnalyzeOtherStatement();\n\t\t\t\t}\n\t\t\t\tcxxParserNewStatement();\n\t\t\t}\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeSingleColon:\n\t\t\t{\n\t\t\t\t// label ?\n\t\t\t\tif(\n\t\t\t\t\t\t(g_cxx.pTokenChain->iCount == 2) &&\n\t\t\t\t\t\tcxxTokenTypeIs(\n\t\t\t\t\t\t\t\tcxxTokenChainFirst(g_cxx.pTokenChain),\n\t\t\t\t\t\t\t\tCXXTokenTypeIdentifier\n\t\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tCXXToken * pFirst = cxxTokenChainFirst(g_cxx.pTokenChain);\n\t\t\t\t\t// assume it's label\n\t\t\t\t\ttagEntryInfo * tag = cxxTagBegin(CXXTagKindLABEL,pFirst);\n\n\t\t\t\t\tif(tag)\n\t\t\t\t\t{\n\t\t\t\t\t\ttag->isFileScope = true;\n\t\t\t\t\t\tcxxTagCommit(NULL);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// what is this? (default: and similar things have been handled at keyword level)\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeOpeningBracket:\n\t\t\t\tif(!cxxParserParseBlockHandleOpeningBracket())\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to handle opening bracket\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeClosingBracket:\n\t\t\t\t// scope finished\n\t\t\t\tif(!bExpectClosingBracket)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\"Found unexpected closing bracket: probably preprocessing problem\"\n\t\t\t\t\t);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Closing bracket!\");\n\t\t\t\tcxxParserNewStatement();\n\t\t\t\treturn true;\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeOpeningParenthesis:\n\t\t\tcase CXXTokenTypeOpeningSquareParenthesis:\n\t\t\t\tif(!cxxParserParseAndCondenseCurrentSubchain(\n\t\t\t\t\t\tCXXTokenTypeOpeningBracket | CXXTokenTypeOpeningParenthesis |\n\t\t\t\t\t\t\tCXXTokenTypeOpeningSquareParenthesis,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tfalse\n\t\t\t\t\t))\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Parsing the parenthesis failed\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeEOF))\n\t\t\t\t{\n\t\t\t\t\tif(bExpectClosingBracket)\n\t\t\t\t\t{\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\t\t\"Syntax error: found EOF in block but a closing bracket was expected!\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true; // EOF\n\t\t\t\t}\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeIdentifier:\n\t\t\t\tif(\n\t\t\t\t\t/* Accept only \"export\" as a  preceding token. */\n\t\t\t\t\t(! (g_cxx.uKeywordState & ~CXXParserKeywordStateSeenExport))\n\t\t\t\t\t&& (g_cxx.pToken->pPrev == NULL || cxxTokenIsKeyword(g_cxx.pToken->pPrev, CXXKeywordEXPORT))\n\t\t\t\t\t/* C++ */\n\t\t\t\t\t&& cxxParserCurrentLanguageIsCPP()\n\t\t\t\t\t/* At the toplevel */\n\t\t\t\t\t&& cxxScopeIsGlobal()\n\t\t\t\t\t/* Handle this token as a keyword, not an identifier.  */\n\t\t\t\t\t&& (strcmp(vStringValue(g_cxx.pToken->pszWord), \"module\") == 0)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t/* \"module\" introduced in C++20, can be a keyworkd in limited contexts.\n\t\t\t\t\t * If the parsing is not in the context, the parser should handle it\n\t\t\t\t\t * as an identifier. */\n\t\t\t\t\tif(!cxxParserParseModule())\n\t\t\t\t\t{\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse module\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if(\n\t\t\t\t\t(! (g_cxx.uKeywordState & ~CXXParserKeywordStateSeenExport))\n\t\t\t\t\t&& (g_cxx.pToken->pPrev == NULL || cxxTokenIsKeyword(g_cxx.pToken->pPrev, CXXKeywordEXPORT))\n\t\t\t\t\t&& cxxParserCurrentLanguageIsCPP()\n\t\t\t\t\t&& cxxScopeIsGlobal()\n\t\t\t\t\t&& (strcmp(vStringValue(g_cxx.pToken->pszWord), \"import\") == 0)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tif(!cxxParserParseImport())\n\t\t\t\t\t{\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse import\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if(g_cxx.uKeywordState & CXXParserKeywordStateSeenTypedef)\n\t\t\t\t{\n\t\t\t\t\tg_cxx.uKeywordState &= ~CXXParserKeywordStateSeenTypedef;\n\t\t\t\t\tif(!cxxParserParseGenericTypedef())\n\t\t\t\t\t{\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse generic typedef\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tcxxParserNewStatement();\n\t\t\t\t}\n\t\t\t\telse if (cxxScopeGetType() == CXXScopeTypeClass)\n\t\t\t\t\tcxxSubparserUnknownIdentifierInClassNotify(g_cxx.pToken);\n\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// something else we didn't handle\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tCXX_DEBUG_LEAVE_TEXT(\"WARNING: Not reached\");\n\treturn true;\n}\n\n//\n// This is the toplevel scanning function. It's a forward-only scanner that keeps\n// accumulating tokens in the chain until either a characteristic token is found\n// or the statement ends. When a characteristic token is found it usually enters\n// a specialized scanning routine (e.g for classes, namespaces, structs...).\n// When the statement ends without finding any characteristic token the chain\n// is passed to an analysis routine which does a second scan pass.\n//\nstatic bool cxxParserParseBlockFull(bool bExpectClosingBracket, bool bExported)\n{\n\tg_cxx.iNestingLevels++;\n\tif(g_cxx.iNestingLevels > CXX_PARSER_MAXIMUM_NESTING_LEVELS)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Nesting level grown too much: something nasty is going on\");\n\t\treturn false;\n\t}\n\n\tcxxSubparserNotifyEnterBlock ();\n\n\tcppPushExternalParserBlock();\n\tbool bRet = cxxParserParseBlockInternal(bExpectClosingBracket, bExported);\n\tcppPopExternalParserBlock();\n\n\tcxxSubparserNotifyLeaveBlock ();\n\tg_cxx.iNestingLevels--;\n\n\treturn bRet;\n}\n\nbool cxxParserParseBlock(bool bExpectClosingBracket)\n{\n\treturn cxxParserParseBlockFull(bExpectClosingBracket, false);\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_parser_function.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_scope.h\"\n#include \"cxx_side_chain.h\"\n\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"../x-cpreprocessor.h\"\n#include \"debug.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n#include \"trashbox.h\"\n\n#include <string.h>\n\n//\n// This is called upon encountering a semicolon, when current language is\n// C and we are in global scope.\n//\n// Try to handle the special case of C K&R style function declarations.\n//\n// The possible return values are:\n//   1: The parser has moved forward, the statement has been parsed and cleared.\n//      A K&R function declaration has possibly been extracted (but not necessarily).\n//      Anyway, a new statement has been started.\n//   0: The parser has NOT moved forward and the current statement hasn't been cleared:\n//      other options may be evaluated.\n//  -1: unrecoverable error\n//\nint cxxParserMaybeParseKnRStyleFunctionDefinition(void)\n{\n#ifdef CXX_DO_DEBUGGING\n\tvString * pChain = cxxTokenChainJoin(g_cxx.pTokenChain,NULL,0);\n\tCXX_DEBUG_PRINT(\n\t\t\t\"Looking for K&R-style function in '%s'\",\n\t\t\tvStringValue(pChain)\n\t\t);\n\tvStringDelete(pChain);\n#endif\n\n\t// Check if we are in the following situation:\n\t//\n\t//   type1 function(arg1,arg2,...) type2 arg1; type3 arg2; {\n\t//                                           ^\n\t//                                       we're here\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxParserCurrentLanguageIsC(),\n\t\t\t\"Should be called only when parsing C\"\n\t\t);\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenChainLast(g_cxx.pTokenChain),\n\t\t\t\"At least one token should be there\"\n\t\t);\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(cxxTokenChainLast(g_cxx.pTokenChain),CXXTokenTypeSemicolon),\n\t\t\t\"Only upon encountering a semicolon\"\n\t\t);\n\n\t// The minimum possible case is:\n\t//\n\t//   func(arg) type2 arg;\n\t//\n\t// where (arg) is a condensed parenthesis chain.\n\t// So the minimum number of tokens required is 5: func, (arg), type2, arg, ;\n\tif(g_cxx.pTokenChain->iCount < 5)\n\t\treturn 0; // no way\n\n\t// There must be a parenthesis chain\n\tCXXToken * pParenthesis = cxxTokenChainFirstTokenOfType(\n\t\t\tg_cxx.pTokenChain,\n\t\t\tCXXTokenTypeParenthesisChain\n\t\t);\n\tif(!pParenthesis)\n\t\treturn 0; // no parenthesis chain\n\n\t// The parenthesis chain must have an identifier before it\n\tCXXToken * pIdentifier = pParenthesis->pPrev;\n\tif(!pIdentifier)\n\t\treturn 0;\n\tif(!cxxTokenTypeIs(pIdentifier,CXXTokenTypeIdentifier))\n\t\treturn 0;\n\n\t// And least three tokens after it\n\tCXXToken * x = pParenthesis->pNext;\n\tif(!x)\n\t\treturn 0;\n\tx = x->pNext;\n\tif(!x)\n\t\treturn 0;\n\tx = x->pNext;\n\tif(!x)\n\t\treturn 0;\n\n\t// The tokens following must be only things allowed in a variable declaration\n\tx = cxxTokenChainNextTokenNotOfType(\n\t\t\tpParenthesis,\n\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeKeyword |\n\t\t\t\tCXXTokenTypeSquareParenthesisChain | CXXTokenTypeStar |\n\t\t\t\tCXXTokenTypeComma | CXXTokenTypeSingleColon | CXXTokenTypeNumber\n\t\t);\n\n\tCXX_DEBUG_ASSERT(x,\"There should be at least the terminator here!\");\n\tif(!x)\n\t\treturn 0;\n\n\tif(!cxxTokenTypeIs(x,CXXTokenTypeSemicolon))\n\t\treturn 0; // does not look like a variable declaration.\n\n\tx = cxxTokenChainPreviousTokenNotOfType(\n\t\t\tx,\n\t\t\tCXXTokenTypeSquareParenthesisChain | CXXTokenTypeSingleColon |\n\t\t\t\tCXXTokenTypeNumber\n\t\t);\n\n\tCXX_DEBUG_ASSERT(x,\"We should have found an identifier here\");\n\tif(!x)\n\t\treturn 0;\n\n\tif(!cxxTokenTypeIs(x,CXXTokenTypeIdentifier))\n\t\treturn 0; // does not look like a variable declaration.\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tpParenthesis->pChain,\n\t\t\t\"The parenthesis should be condensed here!\"\n\t\t);\n\n\tCXXTokenChain * pParenthesisTokenChain = g_cxx.pTokenChain;\n\n\tCXXToken * pFirstArgumentToken = pParenthesis->pNext;\n\n\t// Special case inside special case.\n\t// Check if we're at something like func __ARGS(())\n\tif(\n\t\t\t(pParenthesis->pChain->iCount == 3) &&\n\t\t\tcxxTokenTypeIs(\n\t\t\t\t\tcxxTokenChainAt(pParenthesis->pChain,1),\n\t\t\t\t\tCXXTokenTypeParenthesisChain\n\t\t\t\t) &&\n\t\t\t(pIdentifier->pPrev) &&\n\t\t\tcxxTokenTypeIs(pIdentifier->pPrev,CXXTokenTypeIdentifier)\n\t\t)\n\t{\n\t\t// Looks exactly like our special case.\n\t\tpIdentifier = pIdentifier->pPrev;\n\t\tpParenthesisTokenChain = pParenthesis->pChain;\n\t\tpParenthesis = cxxTokenChainAt(pParenthesis->pChain,1);\n\t}\n\n\t// Now check if the contents of the parenthesis chain look like a K&R signature\n\n\t// This is something like identifier,identifier,identifier,...\n\tif(pParenthesis->pChain->iCount < 3)\n\t\treturn 0; // no way\n\n\tx = pParenthesis->pChain->pHead->pNext;\n\tCXX_DEBUG_ASSERT(x,\"We should have found something in the parenthesis chain\");\n\n\tint iParameterCount = 0;\n\tbool bGotMultipleDots = false;\n\n\tfor(;;)\n\t{\n\t\tif(cxxTokenTypeIs(x,CXXTokenTypeIdentifier))\n\t\t\tiParameterCount++;\n\t\telse if(cxxTokenTypeIs(x,CXXTokenTypeMultipleDots))\n\t\t\tbGotMultipleDots = true;\n\t\telse {\n\t\t\t// not valid (note that (void) is not allowed here since we\n\t\t\t// wouldn't have a following variable declaration)\n\t\t\treturn 0;\n\t\t}\n\n\t\tx = x->pNext;\n\t\tCXX_DEBUG_ASSERT(x,\"We should have found at least the closing parenthesis\");\n\t\tif(cxxTokenTypeIs(x,CXXTokenTypeClosingParenthesis))\n\t\t\tbreak;\n\t\tif(bGotMultipleDots)\n\t\t\treturn 0; // not valid\n\t\tif(!cxxTokenTypeIs(x,CXXTokenTypeComma))\n\t\t\treturn 0;\n\t\tx = x->pNext;\n\t\tCXX_DEBUG_ASSERT(x,\"We should have found at least the closing parenthesis\");\n\t}\n\n\tif(iParameterCount < 1)\n\t{\n\t\t// we should have found at least one parameter\n\t\t// (the one that we found before the ;)\n\t\treturn 0;\n\t}\n\n\tcxxTokenChainTake(g_cxx.pTokenChain,pIdentifier);\n\tcxxTokenChainTake(pParenthesisTokenChain,pParenthesis);\n\n\t// remove the whole signature from the chain\n\twhile(g_cxx.pTokenChain->pHead != pFirstArgumentToken)\n\t\tcxxTokenChainDestroyFirst(g_cxx.pTokenChain);\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tg_cxx.pTokenChain->pHead,\n\t\t\t\"We should have the variable declaration in the chain now!\"\n\t\t);\n\n\t// There is exactly one statement in chain now.\n\n\t// Extra here means \"following the first\"\n#define MAX_EXTRA_KNR_PARAMETERS 10\n\n\tCXXToken * aExtraParameterStarts[MAX_EXTRA_KNR_PARAMETERS];\n\tint iExtraStatementsInChain = 0;\n\n\t// From here we should never return 0 as the parser is going to move forward.\n\n\t// Now we should have no more than iParameterCount-1 parameters before\n\t// an opening bracket. There may be less declarations as each one may\n\t// declare multiple variables and C89 supports the implicit \"int\" type rule.\n\t// Note that we parse up to iParameterCount statements (which will be lost\n\t// if we can't find an opening bracket).\n\twhile(iParameterCount > 0)\n\t{\n\t\tCXXToken * pCurrentTail = g_cxx.pTokenChain->pTail;\n\n\t\tif(!cxxParserParseUpToOneOf(\n\t\t\t\tCXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket | CXXTokenTypeEOF,\n\t\t\t\tfalse\n\t\t\t))\n\t\t{\n\t\t\tcxxTokenDestroy(pIdentifier);\n\t\t\tcxxTokenDestroy(pParenthesis);\n\t\t\treturn -1;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeEOF))\n\t\t{\n\t\t\tcxxTokenDestroy(pIdentifier);\n\t\t\tcxxTokenDestroy(pParenthesis);\n\t\t\tcxxParserNewStatement();\n\t\t\treturn 1; // tolerate syntax error\n\t\t}\n\n\t\tif(iExtraStatementsInChain < MAX_EXTRA_KNR_PARAMETERS)\n\t\t{\n\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\tpCurrentTail->pNext,\n\t\t\t\t\t\"We should have parsed an additional statement here\"\n\t\t\t\t);\n\t\t\taExtraParameterStarts[iExtraStatementsInChain] = pCurrentTail->pNext;\n\t\t\tiExtraStatementsInChain++;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket))\n\t\t\tbreak; // gotcha\n\n\t\tiParameterCount--;\n\t}\n\n\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket))\n\t{\n\t\tcxxTokenDestroy(pIdentifier);\n\t\tcxxTokenDestroy(pParenthesis);\n\t\t// Didn't find an opening bracket.\n\t\t// This probably wasn't a K&R style function declaration after all.\n\t\tcxxParserNewStatement();\n\t\treturn 1;\n\t}\n\n\ttagEntryInfo * tag = cxxTagBegin(CXXTagKindFUNCTION,pIdentifier);\n\n\tint iCorkQueueIndex = CORK_NIL;\n\tint iCorkQueueIndexFQ = CORK_NIL;\n\n\tif(tag)\n\t{\n\t\tcxxSideChainScan(pIdentifier->pSideChain);\n\t\tif(pParenthesis->pChain->pTail)\n\t\t{\n\t\t\t// normalize signature\n\t\t\tcxxTokenChainNormalizeTypeNameSpacing(pParenthesis->pChain);\n\t\t\t// make sure we don't emit the trailing space\n\t\t\tpParenthesis->pChain->pTail->bFollowedBySpace = false;\n\t\t}\n\n\t\t// We don't have to consider export'ed status here; the input is written in C!\n\t\ttag->isFileScope = (g_cxx.uKeywordState & CXXParserKeywordStateSeenStatic) &&\n\t\t\t\t!isInputHeaderFile();\n\n\t\tvString * pszSignature = cxxTokenChainJoin(pParenthesis->pChain,NULL,0);\n\n\t\t// FIXME: Return type!\n\t\t// FIXME: Properties?\n\n\t\tif(pszSignature)\n\t\t\ttag->extensionFields.signature = vStringValue(pszSignature);\n\n\t\tiCorkQueueIndex = cxxTagCommit(&iCorkQueueIndexFQ);\n\t\tcxxTagUseTokenAsPartOfDefTag(iCorkQueueIndex, pIdentifier);\n\n\t\tif(pszSignature)\n\t\t\tvStringDelete(pszSignature);\n\t}\n\n\tcxxTokenDestroy(pParenthesis);\n\n\tCXX_DEBUG_PRINT(\n\t\t\t\"Found K&R-style function '%s'\",\n\t\t\tvStringValue(pIdentifier->pszWord)\n\t\t);\n\n\t// We don't have to propagate export'ed status; the input is written in C!\n\tcxxScopePush(pIdentifier,CXXScopeTypeFunction,CXXScopeAccessUnknown);\n\n\t// emit parameters\n\tif(cxxTagKindEnabled(CXXTagKindPARAMETER))\n\t{\n\t\t// The chain contains 1 + iExtraStatementsInChain statements now\n\t\tint iIdx = 0;\n\t\tfor(;;)\n\t\t{\n\t\t\tcxxParserExtractVariableDeclarations(\n\t\t\t\t\tg_cxx.pTokenChain,\n\t\t\t\t\tCXXExtractVariableDeclarationsKnRStyleParameters\n\t\t\t\t);\n\t\t\tif(iIdx >= iExtraStatementsInChain)\n\t\t\t\tbreak;\n\n\t\t\t// kill everything up to the next start\n\t\t\twhile(g_cxx.pTokenChain->pHead != aExtraParameterStarts[iIdx])\n\t\t\t\tcxxTokenChainDestroyFirst(g_cxx.pTokenChain);\n\n\t\t\tiIdx++;\n\t\t}\n\t}\n\n\tcxxParserNewStatement();\n\n\tif(!cxxParserParseBlock(true))\n\t{\n\t\tCXX_DEBUG_PRINT(\"Failed to parse K&R function block\");\n\t\treturn -1;\n\t}\n\n\tif(iCorkQueueIndex > CORK_NIL)\n\t{\n\t\tcxxParserMarkEndLineForTagInCorkQueue(iCorkQueueIndex);\n\t\tif(iCorkQueueIndexFQ > CORK_NIL)\n\t\t\tcxxParserMarkEndLineForTagInCorkQueue(iCorkQueueIndexFQ);\n\t}\n\n\tcxxScopePop();\n\treturn 1;\n}\n\n//\n// This function attempts to verify that the specified chain _looks like_\n// a set of parameters to a function call. It's quite fuzzy and thus not\n// 100% accurate, but it tries to exclude the obvious cases. If it says\n// \"no\" then the specified chain CAN'T be a set of parameters to\n// a function call. If it says \"yes\" then the result has to be considered\n// a guess: the chain *might* be a set of parameters to a function call.\n//\n// This function is used to check both () and {} parenthesis chains.\n//     function(...)\n//     variable(...)\n//     variable{...}\n//\nbool cxxParserTokenChainLooksLikeFunctionCallParameterSet(\n\t\tCXXTokenChain * pChain\n\t)\n{\n\tCXXToken * t = pChain->pHead;\n\tCXXToken * pLast = pChain->pTail;\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIsOneOf(t,CXXTokenTypeOpeningParenthesis | CXXTokenTypeOpeningBracket),\n\t\t\t\"The token chain should start with an opening parenthesis/bracket\"\n\t\t);\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIsOneOf(pLast,CXXTokenTypeClosingParenthesis | CXXTokenTypeClosingBracket),\n\t\t\t\"The token chain should end with an closing parenthesis/bracket\"\n\t\t);\n\n\tunsigned int uTerminator = t->eType << 4;\n\n\t// Dealing with (...) type chain and not {...} one\n\tbool bDealingWithParenthesisChain = (uTerminator == CXXTokenTypeClosingParenthesis);\n\n\tt = t->pNext;\n\n\twhile(t != pLast)\n\t{\n\t\tif(\n\t\t\tbDealingWithParenthesisChain &&\n\t\t\tcxxTokenTypeIsOneOf(t,\n\t\t\t\tCXXTokenTypeNumber | CXXTokenTypeStringConstant |\n\t\t\t\tCXXTokenTypeCharacterConstant | CXXTokenTypePointerOperator |\n\t\t\t\tCXXTokenTypeDotOperator | CXXTokenTypeOperator | CXXTokenTypeMultipleDots\n\t\t\t))\n\t\t{\n\t\t\t// Not allowed in a function signature before an equal sign (which\n\t\t\t// we haven't encountered yet).\n\t\t\t// assume this looks like a function call\n\t\t\treturn true;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeKeyword))\n\t\t{\n\t\t\tif(cxxKeywordMayBePartOfTypeName(t->eKeyword))\n\t\t\t{\n\t\t\t\t// parts of type name (not inside a parenthesis\n\t\t\t\t// which is assumed to be condensed)\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif(\n\t\t\t\tbDealingWithParenthesisChain &&\n\t\t\t\t(\n\t\t\t\t\tcxxKeywordIsConstant(t->eKeyword) ||\n\t\t\t\t\t(t->eKeyword == CXXKeywordNEW)\n\t\t\t\t)\n\t\t\t)\n\t\t\t{\n\t\t\t\t// Not allowed in a function signature before an equal sign (which\n\t\t\t\t// we haven't encountered yet).\n\t\t\t\t// assume this looks like a function call\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif(\n\t\t\t\t\t(t->eKeyword != CXXKeywordNEW) &&\n\t\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\tt->pNext,\n\t\t\t\t\t\t\tCXXTokenTypeKeyword | CXXTokenTypeStar | CXXTokenTypeAnd |\n\t\t\t\t\t\t\t\tCXXTokenTypeMultipleAnds | CXXTokenTypeIdentifier\n\t\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\t// this is something like:\n\t\t\t\t// (int a...\n\t\t\t\t// (void *...\n\t\t\t\t// (unsigned int...\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t} else if(cxxTokenTypeIs(t,CXXTokenTypeIdentifier))\n\t\t{\n\t\t\tif(cxxTokenTypeIsOneOf(t->pNext,CXXTokenTypeKeyword | CXXTokenTypeIdentifier))\n\t\t\t{\n\t\t\t\t// this is something like:\n\t\t\t\t// (a b...\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if(cxxTokenTypeIs(t,CXXTokenTypeGreaterThanSign))\n\t\t{\n\t\t\tif(cxxTokenTypeIsOneOf(\n\t\t\t\t\tt->pNext,\n\t\t\t\t\tCXXTokenTypeAnd | CXXTokenTypeStar |\n\t\t\t\t\t\tCXXTokenTypeMultipleAnds | CXXTokenTypeComma | uTerminator\n\t\t\t\t))\n\t\t\t{\n\t\t\t\t// > &\n\t\t\t\t// > *\n\t\t\t\t// > &&\n\t\t\t\t// >,\n\t\t\t\t// >) or >}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif(cxxTokenTypeIsOneOf(t->pPrev,CXXTokenTypeKeyword))\n\t\t\t{\n\t\t\t\t// int>\n\t\t\t\t//\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if(\n\t\t\t\tcxxTokenTypeIs(t,CXXTokenTypeParenthesisChain) &&\n\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\tt->pPrev,\n\t\t\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeKeyword |\n\t\t\t\t\t\t\tCXXTokenTypeStar | CXXTokenTypeAnd | CXXTokenTypeGreaterThanSign\n\t\t\t\t\t) &&\n\t\t\t\tcxxTokenTypeIs(t->pNext,CXXTokenTypeParenthesisChain) &&\n\t\t\t\tcxxTokenTypeIs(cxxTokenChainAt(t->pChain,1),CXXTokenTypeStar) &&\n\t\t\t\tcxxParserTokenChainLooksLikeFunctionParameterList(t->pNext->pChain,NULL)\n\t\t\t)\n\t\t{\n\t\t\t// looks like a function pointer\n\t\t\t//   someType (*p)(int)\n\t\t\treturn false;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeAssignment))\n\t\t{\n\t\t\t// after an assignment prototypes and constructor\n\t\t\t// declarations may look the same, skip to next comma or end\n\t\t\tt = cxxTokenChainNextTokenOfType(\n\t\t\t\t\tt,\n\t\t\t\t\tuTerminator | CXXTokenTypeComma\n\t\t\t\t);\n\t\t\tCXX_DEBUG_ASSERT(t,\"We should have found the terminator here!\");\n\t\t\tif(cxxTokenTypeIs(t,CXXTokenTypeComma))\n\t\t\t\tt = t->pNext;\n\t\t} else {\n\t\t\tt = t->pNext;\n\t\t}\n\t}\n\n\t// We must assume that it might be...\n\treturn true;\n}\n\n//\n// Try to tell if the specified token chain is valid as a parameter list\n// for a constructor. It's used to check if something like type name(args)\n// belongs to a variable declaration.\n//\n// This is more of a guess for now: tries to exclude trivial cases.\n//\nbool cxxParserTokenChainLooksLikeConstructorParameterSet(\n\t\tCXXTokenChain * pChain\n\t)\n{\n\t// We assume that the chain has a starting parenthesis and an\n\t// ending parenthesis.\n\n\tif(pChain->iCount < 3)\n\t{\n\t\tCXX_DEBUG_ASSERT(\n\t\t\t\tpChain->iCount == 2,\n\t\t\t\t\"This function should be called only on parenthesis and bracket chains\"\n\t\t\t);\n\n\t\tif(cxxTokenTypeIs(cxxTokenChainFirst(pChain),CXXTokenTypeOpeningBracket))\n\t\t{\n\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\tcxxTokenTypeIs(cxxTokenChainLast(pChain),CXXTokenTypeClosingBracket),\n\t\t\t\t\t\"The last token should have been a closing bracket here\"\n\t\t\t\t);\n\t\t\treturn true; // type var {} is valid in C++11\n\t\t}\n\n\t\tCXX_DEBUG_ASSERT(\n\t\t\t\tcxxTokenTypeIs(cxxTokenChainFirst(pChain),CXXTokenTypeOpeningParenthesis),\n\t\t\t\t\"This function should be called only on parenthesis and bracket chains\"\n\t\t\t);\n\n\t\treturn false; // type var() is NOT valid C++\n\t}\n\n\treturn cxxParserTokenChainLooksLikeFunctionCallParameterSet(pChain);\n}\n\n//\n// Check the parenthesis chain and the identifier found by\n// cxxParserLookForFunctionSignature() to determine if its valid for\n// a function signature.\n//\nstatic bool cxxParserLookForFunctionSignatureCheckParenthesisAndIdentifier(\n\t\tCXXToken * pParenthesis,\n\t\tCXXTokenChain * pIdentifierChain,\n\t\tCXXToken * pIdentifierStart,\n\t\tCXXToken * pIdentifierEnd,\n\t\tCXXFunctionSignatureInfo * pInfo,\n\t\tCXXTypedVariableSet * pParamInfo\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tpParenthesis && pIdentifierChain && pIdentifierStart && pIdentifierEnd && pInfo,\n\t\t\t\"All parameters other than `pParamInfo' must be non null here\"\n\t\t);\n\n\t// Even if we have found a parenthesis and proper identifier we still\n\t// continue looping until a termination condition is found.\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(pParenthesis,CXXTokenTypeParenthesisChain),\n\t\t\t\"Must have found a parenthesis chain here\"\n\t\t);\n\n\t// looks almost fine\n\n\tCXXToken * pInner = cxxTokenChainAt(pParenthesis->pChain,1);\n\n\t// Look for the __ARGS(()) macro pattern.\n\tif(\n\t\t\t// nested parentheses\n\t\t\t(pParenthesis->pChain->iCount == 3) &&\n\t\t\tcxxTokenTypeIs(pInner,CXXTokenTypeParenthesisChain) &&\n\t\t\t// FIXME: This actually excludes operator!\n\t\t\tcxxTokenTypeIs(pIdentifierEnd,CXXTokenTypeIdentifier) &&\n\t\t\t// an identifier right before the identifier we found\n\t\t\tpIdentifierEnd->pPrev &&\n\t\t\tcxxTokenTypeIs(pIdentifierEnd->pPrev,CXXTokenTypeIdentifier) &&\n\t\t\tcxxParserTokenChainLooksLikeFunctionParameterList(\n\t\t\t\t\tpInner->pChain,\n\t\t\t\t\tpParamInfo\n\t\t\t\t)\n\t\t)\n\t{\n\t\t// __ARGS() case\n\t\tpInfo->pParenthesisContainerChain = pParenthesis->pChain;\n\t\tpInfo->pIdentifierEnd = pIdentifierEnd->pPrev;\n\t\tpInfo->pIdentifierStart = pInfo->pIdentifierEnd;\n\t\tpInfo->pIdentifierChain = pIdentifierChain;\n\t\tpInfo->pParenthesis = pInner;\n\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Looks like an __ARGS() case parenthesis chain\");\n\t\treturn true;\n\t}\n\n\tif(cxxParserTokenChainLooksLikeFunctionParameterList(\n\t\t\tpParenthesis->pChain,\n\t\t\tpParamInfo\n\t\t))\n\t{\n\t\t// non __ARGS()\n\t\tpInfo->pParenthesisContainerChain = pIdentifierChain;\n\t\tpInfo->pIdentifierStart = pIdentifierStart;\n\t\tpInfo->pIdentifierEnd = pIdentifierEnd;\n\t\tpInfo->pIdentifierChain = pIdentifierChain;\n\t\tpInfo->pParenthesis = pParenthesis;\n\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Looks like valid parenthesis chain\");\n\t\treturn true;\n\t}\n\n\tCXX_DEBUG_LEAVE_TEXT(\"Doesn't look like a valid parenthesis chain\");\n\treturn false;\n}\n\n// If pInfo->pIdentifierStart has the same name as the name of\n// class|enum|union|struct scope, we consider pInfo->pIdentifierStart\n// points a constructor.\nstatic bool cxxParserisConstructor(const char *szFuncname)\n{\n\tif (cxxScopeIsGlobal())\n\t\treturn false;\n\n\tswitch (cxxScopeGetType())\n\t{\n\tcase CXXScopeTypeClass:\n\tcase CXXScopeTypeEnum:\n\tcase CXXScopeTypeUnion:\n\tcase CXXScopeTypeStruct:\n\t\tbreak;\n\tdefault:\n\t\treturn false;\n\t}\n\n\tconst char *szScope = cxxScopeGetName();\n\tconst char *szTmp = strrstr (szScope, szFuncname);\n\n\tif (szTmp == NULL)\n\t\treturn false;\n\n\t/* szFuncname == \"C\", szScope == \"C\" */\n\tif (szTmp == szScope)\n\t\treturn true;\n\n\t/* szFuncname == \"C\", szScope == \"X::C\" */\n\tif (szTmp[-1] == ':')\n\t\treturn true;\n\n\treturn false;\n}\n\nstatic CXXTokenChain * cxxParserLookForFunctionNameOnlyInParenthesis(CXXTokenChain * pChain)\n{\n\tif (pChain->iCount == 3) {\n\t\tCXXToken *pToken = cxxTokenChainAt(pChain,1);\n\n\t\t// It rejects void keyword implicitly to examine the token is an Identifier.\n\t\tif (cxxTokenTypeIs(pToken, CXXTokenTypeIdentifier))\n\t\t\treturn pChain;\n\t\tif (cxxTokenTypeIs(pToken, CXXTokenTypeParenthesisChain))\n\t\t\treturn cxxParserLookForFunctionNameOnlyInParenthesis(pToken->pChain);\n\t} else if (pChain->iCount > 3) {\n\t\tCXXToken *pBegin = cxxTokenChainAt(pChain,1);\n\t\tCXXToken *pTmp = pBegin;\n\t\twhile (pTmp)\n\t\t{\n\t\t\tif (!cxxTokenTypeIsOneOf(pTmp,\n\t\t\t\t\t\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeMultipleColons))\n\t\t\t\tbreak;\n\t\t\tpTmp = pTmp->pNext;\n\t\t}\n\t\tif (pChain->pTail == pTmp)\n\t\t\treturn pChain;\n\t}\n\treturn NULL;\n}\n\nstatic CXXTokenChain * cxxParserLookForFunctionNameInParenthesisFollowedByParameterList(CXXToken * pParenthesis)\n{\n\tCXXToken *pNext = pParenthesis->pNext;\n\n\tif (pNext && cxxTokenTypeIs(pNext, CXXTokenTypeParenthesisChain))\n\t\treturn cxxParserLookForFunctionNameOnlyInParenthesis(pParenthesis->pChain);\n\treturn NULL;\n}\n\n//\n// Look for a function signature in the specified chain.\n//\n// If a proper function signature is found then also standardize the spacing\n// of the identifier so we always get it as \"operator ()\" and never as\n// \"operator() or operator ( ) \".\n//\n// Note that this function does NOT handle the special case of K&R-style\n// declarations.\n//\n// If pParamInfo is not null, it is passed to\n// cxxParserTokenChainLooksLikeFunctionParameterList() which will eventually\n// fill it up.\n//\n//\nbool cxxParserLookForFunctionSignature(\n\t\tCXXTokenChain * pChain,\n\t\tCXXFunctionSignatureInfo * pInfo,\n\t\tCXXTypedVariableSet * pParamInfo\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\n\tif(pChain->iCount < 1)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Chain is empty\");\n\t\treturn false;\n\t}\n\n#ifdef CXX_DO_DEBUGGING\n\tvString * pJoinedChain = cxxTokenChainJoin(pChain,NULL,0);\n\tCXX_DEBUG_PRINT(\n\t\t\t\"Looking for function signature in '%s'\",\n\t\t\tvStringValue(pJoinedChain)\n\t\t);\n\tvStringDelete(pJoinedChain);\n#endif\n\n\tif(pParamInfo)\n\t\tpParamInfo->uCount = 0;\n\n\tCXX_DEBUG_ASSERT(pChain,\"Null chain\");\n\n\tCXXToken * pToken = cxxTokenChainFirst(pChain);\n\n\tpInfo->uFlags = 0;\n\tpInfo->pParenthesis = NULL;\n\tpInfo->pTrailingComma = NULL;\n\tpInfo->pTemplateSpecializationStart = NULL;\n\n\tCXXToken * pIdentifierStart = NULL;\n\tCXXToken * pIdentifierEnd = NULL;\n\tCXXToken * pTopLevelParenthesis = NULL;\n\n\tbool bSkippedAngleBrackets = false;\n\n\t// Strategy:\n\t//\n\t//    Scan the toplevel token chain and look for the first identifier immediately\n\t//    followed by a parenthesis chain that looks like a (possibly empty)\n\t//    list of function parameters.\n\t//\n\t//    Since the identifier may be hidden within a parenthesis chain (and thus NOT be toplevel)\n\t//    we must scan the inner parenthesis chains in a sequence of special cases.\n\t//\n\t//    (Mainly) for this reason this loop first looks for a parenthesis chain (which is always\n\t//    present at toplevel) and then looks for a suitable identifier near or inside it.\n\t//\n\t//    Once we have found a suitable parenthesis-chain/identifier pair we continue\n\t//    scanning until one of { ; EOF : , is found.\n\t//\n\t//    We bail out if anything suspicious is found in the middle of the scan.\n\t//\n\n\twhile(pToken)\n\t{\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Token '%s' of type 0x%02x (%s)\",\n\t\t\t\tvStringValue(pToken->pszWord),\n\t\t\t\tpToken->eType,\n\t\t\t\tcxxDebugTypeDecode(pToken->eType)\n\t\t\t);\n\n\t\t// Check exit conditions first\n\n\t\tif(cxxTokenTypeIsOneOf(\n\t\t\t\tpToken,\n\t\t\t\tCXXTokenTypeOpeningBracket | CXXTokenTypeSemicolon | CXXTokenTypeEOF\n\t\t\t))\n\t\t{\n\t\t\t// reached end\n\t\t\tCXX_DEBUG_PRINT(\"Found opening bracket, semicolon or EOF\");\n\t\t\tbreak;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(pToken,CXXTokenTypeComma))\n\t\t{\n\t\t\t// reached end, but we have a trailing comma.\n\t\t\tpInfo->pTrailingComma = pToken;\n\t\t\tCXX_DEBUG_PRINT(\"Found trailing comma\");\n\t\t\tbreak;\n\t\t}\n\n\t\tif(\n\t\t\tcxxParserCurrentLanguageIsCPP() &&\n\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\tpToken,\n\t\t\t\t\tCXXTokenTypeSingleColon | CXXTokenTypeAssignment |\n\t\t\t\t\t\tCXXTokenTypePointerOperator\n\t\t\t\t)\n\t\t)\n\t\t{\n\t\t\t// With a single colon it might be a constructor.\n\t\t\t// With assignment it might be virtual type func(..) = 0;\n\t\t\t// With a pointer operator it might be trailing return type\n\t\t\tCXX_DEBUG_PRINT(\"Found single colon\");\n\t\t\tbreak;\n\t\t}\n\n\t\t// Check for tokens that should never appear at top level of a function signature\n\n\t\tif(cxxTokenTypeIsOneOf(\n\t\t\t\t\tpToken,\n\t\t\t\t\tCXXTokenTypeOperator | CXXTokenTypePointerOperator |\n\t\t\t\t\t\tCXXTokenTypeBracketChain | CXXTokenTypeStringConstant |\n\t\t\t\t\t\tCXXTokenTypeCharacterConstant | CXXTokenTypeMultipleDots |\n\t\t\t\t\t\tCXXTokenTypeClosingBracket | CXXTokenTypeClosingParenthesis |\n\t\t\t\t\t\tCXXTokenTypeClosingSquareParenthesis\n\t\t\t\t)\n\t\t\t)\n\t\t{\n\t\t\t// Nope.\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found token that should never appear at toplevel of a signature\");\n\t\t\treturn false;\n\t\t}\n\n\t\t// Explicitly skip template-like angle brackets, which are not condensed here and may confuse us\n\n\t\tif(cxxTokenTypeIs(pToken,CXXTokenTypeSmallerThanSign))\n\t\t{\n\t\t\tpToken = cxxTokenChainSkipToEndOfTemplateAngleBracket(pToken);\n\t\t\tif(!pToken)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Couldn't skip past angle bracket chain\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tbSkippedAngleBrackets = true;\n\t\t\tCXX_DEBUG_PRINT(\"Skipped angle bracket chain\");\n\t\t\tgoto next_token;\n\t\t}\n\n\t\t// If we have already found a parenthesis+identifier just continue scanning\n\t\t// until an exit condition is found. Do not look for parenthesis+identifier again.\n\n\t\tif(pInfo->pParenthesis)\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"Already have a proper parenthesis: continuing loop to find terminator\");\n\t\t\tgoto next_token;\n\t\t}\n\n\t\t// Parenthesis+identifier hasn't been found yet, look for it.\n\t\t// Several specialized cases follow.\n\n\t\tif(cxxTokenIsKeyword(pToken,CXXKeywordOPERATOR))\n\t\t{\n\t\t\t// Special case for operator <something> (...), where <something> can be\n\t\t\t// either a simple thing like &, +, =, a keyword or a full fledged type\n\t\t\t// with scoping and template parts.\n\n\t\t\t// void operator = ()\n\t\t\t// int operator + (...)\n\t\t\t// void * operator new[] ()\n\t\t\t// template<typename T> cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine, (Eigen::RowMajor)>() const\n\n\t\t\tCXX_DEBUG_PRINT(\"operator token found: looking for proper identifier\");\n\n\t\t\tpIdentifierStart = pToken;\n\t\t\tpToken = pToken->pNext;\n\n\t\t\twhile(pToken)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\"Candidate token '%s' of type 0x%02x (%s)\",\n\t\t\t\t\t\tvStringValue(pToken->pszWord),\n\t\t\t\t\t\tpToken->eType,\n\t\t\t\t\t\tcxxDebugTypeDecode(pToken->eType)\n\t\t\t\t\t);\n\n\t\t\t\tif(cxxTokenTypeIs(pToken,CXXTokenTypeParenthesisChain))\n\t\t\t\t{\n\t\t\t\t\t// check for operator ()()\n\t\t\t\t\tif(\n\t\t\t\t\t\t\tpToken->pNext &&\n\t\t\t\t\t\t\tcxxTokenTypeIs(pToken->pNext,CXXTokenTypeParenthesisChain)\n\t\t\t\t\t\t)\n\t\t\t\t\t\tpToken = pToken->pNext;\n\n\t\t\t\t\tbreak;\n\t\t\t\t} else if(cxxTokenTypeIs(pToken,CXXTokenTypeKeyword))\n\t\t\t\t{\n\t\t\t\t\tif(\n\t\t\t\t\t\t\t(!cxxTokenIsKeyword(pToken,CXXKeywordNEW)) &&\n\t\t\t\t\t\t\t(!cxxTokenIsKeyword(pToken,CXXKeywordDELETE)) &&\n\t\t\t\t\t\t\t(!cxxKeywordMayBePartOfTypeName(pToken->eKeyword)) &&\n\t\t\t\t\t\t\t(!cxxTokenIsKeyword(pToken,CXXKeywordVOLATILE))\n\t\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Unexpected token after the operator keyword\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} else if(cxxTokenTypeIs(pToken,CXXTokenTypeSmallerThanSign))\n\t\t\t\t{\n\t\t\t\t\tif(pToken->pPrev == pIdentifierStart)\n\t\t\t\t\t{\n\t\t\t\t\t\t// operator <\n\t\t\t\t\t} else if(cxxTokenTypeIs(pToken->pPrev,CXXTokenTypeIdentifier))\n\t\t\t\t\t{\n\t\t\t\t\t\t// assume template, which is generally uncondensed at this level\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Trying to handle uncondensed template\");\n\n\t\t\t\t\t\tpToken = cxxTokenChainSkipToEndOfTemplateAngleBracket(pToken);\n\t\t\t\t\t\tif(!pToken)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to skip to end of template\");\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\t\t\t\tcxxTokenTypeIs(pToken,CXXTokenTypeGreaterThanSign),\n\t\t\t\t\t\t\t\t\"Should have found a >\"\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Unexpected token after the operator keyword\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} else if(cxxTokenTypeIs(pToken,CXXTokenTypeStringConstant)) {\n\t\t\t\t\t// check for operator \"\" _fn ()\n\t\t\t\t\tif (strcmp (vStringValue(pToken->pszWord), \"\\\"\\\"\") != 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Non-empty string after operator\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} else if(!cxxTokenTypeIsOneOf(\n\t\t\t\t\t\tpToken,\n\t\t\t\t\t\tCXXTokenTypeAnd | CXXTokenTypeAssignment |\n\t\t\t\t\t\t\tCXXTokenTypeComma | CXXTokenTypeDotOperator |\n\t\t\t\t\t\t\tCXXTokenTypeAngleBracketChain |\n\t\t\t\t\t\t\tCXXTokenTypeGreaterThanSign | CXXTokenTypeOperator |\n\t\t\t\t\t\t\tCXXTokenTypePointerOperator | CXXTokenTypeSingleColon |\n\t\t\t\t\t\t\tCXXTokenTypeSquareParenthesisChain |\n\t\t\t\t\t\t\tCXXTokenTypeAngleBracketChain | CXXTokenTypeMultipleColons |\n\t\t\t\t\t\t\tCXXTokenTypeStar | CXXTokenTypeMultipleAnds | CXXTokenTypeIdentifier\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Unexpected token after the operator keyword\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tpToken = pToken->pNext;\n\t\t\t}\n\n\t\t\tif(!pToken)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Didn't find a parenthesis subchain after operator keyword\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\tcxxTokenTypeIs(pToken,CXXTokenTypeParenthesisChain),\n\t\t\t\t\t\"Must have found a parenthesis chain here\"\n\t\t\t\t);\n\n\t\t\tpTopLevelParenthesis = pToken;\n\t\t\tpIdentifierEnd = pToken->pPrev;\n\n\t\t\tcxxParserLookForFunctionSignatureCheckParenthesisAndIdentifier(\n\t\t\t\t\tpTopLevelParenthesis,\n\t\t\t\t\tpChain,\n\t\t\t\t\tpIdentifierStart,\n\t\t\t\t\tpIdentifierEnd,\n\t\t\t\t\tpInfo,\n\t\t\t\t\tpParamInfo\n\t\t\t\t);\n\n\t\t\t// Even if the check above failed we have nothing more to do with this token\n\t\t\tgoto next_token;\n\t\t}\n\n\t\t// Now we look only at parenthesis chains\n\n\t\tif(!cxxTokenTypeIs(pToken,CXXTokenTypeParenthesisChain))\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"Not a parenthesis chain: assume this can be skipped\");\n\t\t\tgoto next_token;\n\t\t}\n\n\t\t// parentheses at position 0 are always meaningless for us\n\n\t\tif(!pToken->pPrev)\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"Parenthesis at position 0, meaningless\");\n\t\t\tgoto next_token;\n\t\t}\n\n\t\t// Before considering macros, here we examine (FUNC)(ARGS) sequence like:\n\t\t//\n\t\t//   myType (myFunc0)(args...);\n\t\t//   myType ((myFunc1)(args...);\n\t\t//   myType (myNs::myFunc2)(args...);\n\t\t//\n\t\t{\n\t\t\tCXXTokenChain * pFnameInParenthesis =\n\t\t\t\tcxxParserLookForFunctionNameInParenthesisFollowedByParameterList(pToken);\n\n\t\t\tif (pFnameInParenthesis)\n\t\t\t{\n\t\t\t\t// If the current pToken is at the head of pChain, the following\n\t\t\t\t// code chaining the pChain destructive way doesn't work. */\n\t\t\t\tAssert(pChain->pHead != pToken);\n\n\t\t\t\tint iChainLen = pFnameInParenthesis->iCount;\n\t\t\t\t//       v----------- pFnameHead\n\t\t\t\t// type (ns:f)(...)\n\t\t\t\t//      ^   ^-------- pFnameTail\n\t\t\t\t//       `----------- pToken, pFnameInParenthesis\n\t\t\t\t//\n\t\t\t\tCXXToken * pFnameHead = pFnameInParenthesis->pHead->pNext;\n\t\t\t\tCXXToken * pFnameTail = pFnameInParenthesis->pTail->pPrev;\n\n\t\t\t\t// Remove the name of function including namespace specifier\n\t\t\t\t// from the pFnameInParenthesis; only `(' and `)' remain\n\t\t\t\t// in the chain.\n\t\t\t\tpFnameInParenthesis->pHead->pNext = pFnameInParenthesis->pTail;\n\t\t\t\tpFnameInParenthesis->pTail->pPrev = pFnameInParenthesis->pHead;\n\t\t\t\tpFnameInParenthesis->iCount = 2;\n\n\t\t\t\t// Remove the parenthesis like:\n\t\t\t\t//\n\t\t\t\t//   type (ns::f)(...) => type ns::f(...)\n\t\t\t\t//\n\t\t\t\tcxxTokenReplaceWithTokens(pToken, pFnameHead, pFnameTail);\n\t\t\t\tAssert(pFnameHead->pPrev);\n\t\t\t\tcxxTokenDestroy(pToken);\n\t\t\t\t// And adjust the chain length.\n\t\t\t\tpChain->iCount += (iChainLen - 3);\n\n\t\t\t\t// Restart the process from the name of function:\n\t\t\t\t//   v----------------pToken\n\t\t\t\t//   type ns::f(...)\n\t\t\t\t//        ^-----------pFnameHead\n\t\t\t\t//\n\t\t\t\tpToken = pFnameHead->pPrev;\n\n\t\t\t\tCXX_DEBUG_PRINT(\"Found a function name in parenthesis followed by parameter list\");\n\t\t\t\tgoto next_token;\n\t\t\t}\n\t\t}\n\n\t\tCXX_DEBUG_PRINT(\"Found interesting parenthesis chain: check for identifier\");\n\n\t\t// parentheses at position 1 they are likely to be macro invocations...\n\t\t// but we still handle them in case we find nothing else.\n\n\t\tpTopLevelParenthesis = pToken;\n\n\t\tif(cxxTokenTypeIs(pToken->pPrev,CXXTokenTypeIdentifier))\n\t\t{\n\t\t\t// identifier before\n\n\t\t\t// This is the most common case.\n\n\t\t\tCXX_DEBUG_PRINT(\"Got identifier before parenthesis chain\");\n\n\t\t\tpIdentifierStart = pToken->pPrev;\n\t\t\tpIdentifierEnd = pToken->pPrev;\n\n\t\t\tif(\n\t\t\t\tcxxParserLookForFunctionSignatureCheckParenthesisAndIdentifier(\n\t\t\t\t\t\tpTopLevelParenthesis,\n\t\t\t\t\t\tpChain,\n\t\t\t\t\t\tpIdentifierStart,\n\t\t\t\t\t\tpIdentifierEnd,\n\t\t\t\t\t\tpInfo,\n\t\t\t\t\t\tpParamInfo\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\t// This looks like a good candidate for a function name + parenthesis.\n\t\t\t\t// The scanning process will skip all the following tokens until\n\t\t\t\t// an exit condition is found.\n\t\t\t\t//\n\t\t\t\t// However, there are a couple of very common special cases that is nice to\n\t\t\t\t// handle automatically.\n\t\t\t\t//\n\t\t\t\t// Case 1:\n\t\t\t\t//    MACRO(return_type) function(...)\n\t\t\t\t// Case 2:\n\t\t\t\t//    MACRO(return_type) variable;\n\t\t\t\t//\n\t\t\t\t// These *could* be handled by the user with -D 'MACRO(x) x' but since\n\t\t\t\t// they are quite common we can't expect the user to look up and define\n\t\t\t\t// all macros for a large project. For this reason we use some heuristics\n\t\t\t\t// to handle these special cases automatically.\n\t\t\t\tif(\n\t\t\t\t\t\t// Identifier is the first token of the chain\n\t\t\t\t\t\t(!pIdentifierStart->pPrev) &&\n\t\t\t\t\t\t// The token following the parenthesis is an identifier\n\t\t\t\t\t\tpInfo->pParenthesis->pNext &&\n\t\t\t\t\t\tcxxTokenTypeIs(pInfo->pParenthesis->pNext,CXXTokenTypeIdentifier) &&\n\t\t\t\t\t\t// There is something after the identifier\n\t\t\t\t\t\tpInfo->pParenthesis->pNext->pNext &&\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t// The token following the identifier is again a parenthesis chain\n\t\t\t\t\t\t\tcxxTokenTypeIs(pInfo->pParenthesis->pNext->pNext,CXXTokenTypeParenthesisChain) ||\n\t\t\t\t\t\t\t// The token following the identifier is a semicolon\n\t\t\t\t\t\t\tcxxTokenTypeIs(pInfo->pParenthesis->pNext->pNext,CXXTokenTypeSemicolon)\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\t// The current parenthesis does not contain commas\n\t\t\t\t\t\t// (...maybe this check is too much?)\n\t\t\t\t\t\t(!cxxTokenChainFirstTokenOfType(pInfo->pParenthesis->pChain,CXXTokenTypeComma))\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Found special case of MACRO(return_type) function()/variable\");\n\t\t\t\t\tpInfo->pParenthesis = NULL;\n\t\t\t\t}\n\n\t\t\t\tgoto next_token;\n\t\t\t}\n\n\t\t\t// If the check above failed, try different identifier possibilities\n\t\t\tCXX_DEBUG_PRINT(\"Checks for common case failed: trying other options\");\n\t\t}\n\n\t\tif(\n\t\t\t\t// The previous token is >\n\t\t\t\tcxxTokenTypeIs(pToken->pPrev,CXXTokenTypeGreaterThanSign) &&\n\t\t\t\t// We skipped an additional <...> block in *this* chain\n\t\t\t\tbSkippedAngleBrackets\n\t\t\t)\n\t\t{\n\t\t\t// look for template specialisation\n\t\t\tCXX_DEBUG_PRINT(\"Maybe template specialisation?\");\n\n\t\t\tCXXToken * pSpecBegin = cxxTokenChainSkipBackToStartOfTemplateAngleBracket(\n\t\t\t\t\tpToken->pPrev\n\t\t\t\t);\n\n\t\t\tif(\n\t\t\t\t\tpSpecBegin &&\n\t\t\t\t\tpSpecBegin->pPrev &&\n\t\t\t\t\tcxxTokenTypeIs(pSpecBegin->pPrev,CXXTokenTypeIdentifier) &&\n\t\t\t\t\t(\n\t\t\t\t\t\t// We extracted an initial template<*> token chain\n\t\t\t\t\t\t// (which has been removed from the currently examined chain)\n\t\t\t\t\t\tg_cxx.pTemplateTokenChain ||\n\t\t\t\t\t\t// g_cxx.pTemplateTokenChain is set to null if \"{\" after \"class\" keyword\n\t\t\t\t\t\t// is found. As a result, a constructor with <*> defined in a template\n\t\t\t\t\t\t// class could not be tagged. The next additional condition is for\n\t\t\t\t\t\t// tagging the condition in this situation.\n\t\t\t\t\t\tcxxParserisConstructor(vStringValue(pSpecBegin->pPrev->pszWord))\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\t// template specialisation\n\n\t\t\t\tCXX_DEBUG_PRINT(\"Template specialization looks quite right\");\n\n\t\t\t\tpIdentifierStart = pSpecBegin->pPrev;\n\t\t\t\tpIdentifierEnd = pSpecBegin->pPrev;\n\t\t\t\tpInfo->uFlags |= CXXFunctionSignatureInfoTemplateSpecialization;\n\n\t\t\t\tpInfo->pTemplateSpecializationStart = pSpecBegin;\n\t\t\t\tpInfo->pTemplateSpecializationEnd = pToken->pPrev;\n\n\t\t\t\tif(\n\t\t\t\t\tcxxParserLookForFunctionSignatureCheckParenthesisAndIdentifier(\n\t\t\t\t\t\t\tpTopLevelParenthesis,\n\t\t\t\t\t\t\tpChain,\n\t\t\t\t\t\t\tpIdentifierStart,\n\t\t\t\t\t\t\tpIdentifierEnd,\n\t\t\t\t\t\t\tpInfo,\n\t\t\t\t\t\t\tpParamInfo\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\tgoto next_token;\n\n\t\t\t}\n\n\t\t\tCXX_DEBUG_PRINT(\"Checks for template spec failed: trying other options\");\n\t\t}\n\n\t\tCXXTokenChain * pIdentifierChain;\n\n\t\tif(\n\t\t\t// check for complex parenthesized declarations.\n\t\t\t// Keep functions, discard everything else.\n\t\t\t//\n\t\t\t// Possible cases:\n\t\t\t//    ret type (*baz)(params) <-- function pointer (variable)\n\t\t\t//    ret type (*(baz))(params) <-- function pointer (variable)\n\t\t\t//    ret type (* const (baz))(params) <-- function pointer (variable)\n\t\t\t//    ret type (*baz())() <-- function returning function pointer\n\t\t\t//    ret type (*baz(params))(params) <-- function returning function pointer\n\t\t\t//    ret type (*baz(params)) <-- function returning a pointer\n\t\t\t//    ret type (*baz(params))[2] <-- function returning a pointer to array\n\t\t\t(pIdentifierStart = cxxParserFindFirstPossiblyNestedAndQualifiedIdentifier(\n\t\t\t\t\tpToken->pChain,\n\t\t\t\t\t&pIdentifierChain\n\t\t\t\t))\n\t\t\t)\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\"Got identifier '%s' inside parenthesis chain\",\n\t\t\t\t\tvStringValue(pIdentifierStart->pszWord)\n\t\t\t\t);\n\n\t\t\t// Now pIdentifierStart points at the innermost identifier\n\t\t\t// Check if it's followed by a parameter list\n\t\t\tif(\n\t\t\t\tpIdentifierStart->pNext &&\n\t\t\t\tcxxTokenTypeIs(pIdentifierStart->pNext,CXXTokenTypeParenthesisChain) &&\n\t\t\t\tcxxParserTokenChainLooksLikeFunctionParameterList(\n\t\t\t\t\t\tpIdentifierStart->pNext->pChain,\n\t\t\t\t\t\tNULL\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_PRINT(\"Identifier followed by a parameter-like parenthesis chain\");\n\t\t\t\tpIdentifierEnd = pIdentifierStart;\n\t\t\t\t// correct our guess for parenthesis\n\t\t\t\tpTopLevelParenthesis = pIdentifierStart->pNext;\n\n\t\t\t\tif(\n\t\t\t\t\tcxxParserLookForFunctionSignatureCheckParenthesisAndIdentifier(\n\t\t\t\t\t\t\tpTopLevelParenthesis,\n\t\t\t\t\t\t\tpIdentifierChain,\n\t\t\t\t\t\t\tpIdentifierStart,\n\t\t\t\t\t\t\tpIdentifierEnd,\n\t\t\t\t\t\t\tpInfo,\n\t\t\t\t\t\t\tpParamInfo\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\tgoto next_token;\n\n\t\t\t} else {\n\t\t\t\t// Looks more like a function pointer or something else we can't figure out\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Identifier NOT followed by a parameter-like parenthesis chain\");\n\t\t\t}\n\n\t\t\t// If the check above failed, try different identifier possibilities\n\t\t\tCXX_DEBUG_PRINT(\"Checks for nested () failed: trying other options\");\n\t\t}\n\nnext_token:\n\t\tpToken = pToken->pNext;\n\t}\n\n\tif(!pInfo->pParenthesis)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"No suitable parenthesis chain found\");\n\t\treturn false; // no function, no party\n\t}\n\n\t// parenthesis + identifier has been found, this is a function signature.\n\n\t// Figure out the remaining parameters.\n\n\tCXX_DEBUG_ASSERT(pTopLevelParenthesis,\"This should have been set\");\n\n\tif(pInfo->pIdentifierStart != pInfo->pIdentifierEnd)\n\t{\n\t\t// operator case\n\t\tpInfo->pIdentifierStart->bFollowedBySpace = true; // force proper spacing\n\t\tCXXToken * t = pInfo->pIdentifierStart->pNext;\n\t\twhile(t != pInfo->pIdentifierEnd)\n\t\t{\n\t\t\t// If a keyword or an identifier followed by another keyword\n\t\t\t// or an identifier need a space.\n\t\t\tt->bFollowedBySpace = (\n\t\t\t\t(cxxTokenTypeIsOneOf(t,CXXTokenTypeIdentifier|CXXTokenTypeKeyword))\n\t\t\t\t&& cxxTokenTypeIsOneOf(t->pNext,CXXTokenTypeIdentifier|CXXTokenTypeKeyword)\n\t\t\t\t)\n\t\t\t\t? true\n\t\t\t\t: false;\n\t\t\tt = t->pNext;\n\t\t}\n\t} else {\n\t\t// non operator\n\t\tpInfo->pIdentifierStart->bFollowedBySpace = false; // force proper spacing\n\t}\n\n\tpInfo->pIdentifierEnd->bFollowedBySpace = false; // force proper spacing\n\n\tpInfo->pScopeStart = NULL;\n\n\tif(cxxParserCurrentLanguageIsCPP())\n\t{\n\t\t// Look for scope prefix\n\t\tCXXToken * pAux = pInfo->pIdentifierStart->pPrev;\n\n\t\tCXX_DEBUG_PRINT(\"Looking for scope prefix\");\n\n\t\twhile(pAux)\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\"Token '%s' of type 0x%02x\",\n\t\t\t\t\tvStringValue(pAux->pszWord),\n\t\t\t\t\tpAux->eType\n\t\t\t\t);\n\n\t\t\tif(!cxxTokenTypeIs(pAux,CXXTokenTypeMultipleColons))\n\t\t\t\tbreak;\n\t\t\tpAux = pAux->pPrev;\n\t\t\tif(!pAux)\n\t\t\t\tbreak;\n\t\t\tif(!cxxTokenTypeIs(pAux,CXXTokenTypeIdentifier))\n\t\t\t{\n\t\t\t\t// check for template specialization\n\t\t\t\tif(cxxTokenTypeIs(pAux,CXXTokenTypeGreaterThanSign))\n\t\t\t\t{\n\t\t\t\t\t// might be something like type X<TemplateArg>::func()\n\t\t\t\t\t// (explicit specialization of template<A> class X).\n\t\t\t\t\tCXXToken * pSmallerThan = cxxTokenChainSkipBackToStartOfTemplateAngleBracket(\n\t\t\t\t\t\t\tpAux\n\t\t\t\t\t\t);\n\t\t\t\t\tif(!pSmallerThan)\n\t\t\t\t\t\tbreak; // nope\n\t\t\t\t\tif(!pSmallerThan->pPrev)\n\t\t\t\t\t\tbreak; // nope\n\t\t\t\t\tif(!cxxTokenTypeIs(pSmallerThan->pPrev,CXXTokenTypeIdentifier))\n\t\t\t\t\t\tbreak; // nope\n\t\t\t\t\t// hmm.. probably a template specialisation\n\t\t\t\t\tpAux = pSmallerThan->pPrev;\n\t\t\t\t\tpInfo->uFlags |= CXXFunctionSignatureInfoScopeTemplateSpecialization;\n\t\t\t\t} else if(cxxTokenTypeIs(pAux, CXXTokenTypeAngleBracketChain))\n\t\t\t\t{\n\t\t\t\t\t// same as above, but already condensed (though it should never happen)\n\t\t\t\t\tif(!pAux->pPrev)\n\t\t\t\t\t\tbreak; // nope\n\t\t\t\t\tif(!cxxTokenTypeIs(pAux->pPrev,CXXTokenTypeIdentifier))\n\t\t\t\t\t\tbreak; // nope\n\t\t\t\t\t// hmm.. probably a template specialisation\n\t\t\t\t\tpAux = pAux->pPrev;\n\t\t\t\t\tpInfo->uFlags |= CXXFunctionSignatureInfoScopeTemplateSpecialization;\n\t\t\t\t} else {\n\t\t\t\t\t// no more scope names\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tCXX_DEBUG_PRINT(\"Shifting scope start to '%s'\",vStringValue(pAux->pszWord));\n\n\t\t\tpInfo->pScopeStart = pAux;\n\n\t\t\tpAux = pAux->pPrev;\n\t\t}\n\n\t\tCXX_DEBUG_PRINT(\"Scope prefix search finished\");\n\n\t\t// Look for trailing const and other interesting things that may come after the parenthesis.\n\n\t\tif(pTopLevelParenthesis->pNext)\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\"Top level parenthesis is followed by '%s' (%s)\",\n\t\t\t\t\tvStringValue(pTopLevelParenthesis->pNext->pszWord),\n\t\t\t\t\tcxxDebugTypeDecode(pTopLevelParenthesis->pNext->eType)\n\t\t\t\t);\n\n\t\t\tif(cxxTokenIsKeyword(pTopLevelParenthesis->pNext,CXXKeywordCONST))\n\t\t\t\tpInfo->pSignatureConst = pTopLevelParenthesis->pNext;\n\t\t\telse\n\t\t\t\tpInfo->pSignatureConst = NULL;\n\n\t\t\t// Look for = 0 for \"pure\" modifier\n\t\t\tCXXToken * pAssignment = cxxTokenChainNextTokenOfType(\n\t\t\t\t\tpTopLevelParenthesis,\n\t\t\t\t\tCXXTokenTypeAssignment\n\t\t\t\t);\n\n\t\t\tif(pAssignment && pAssignment->pNext)\n\t\t\t{\n\t\t\t\tif(\n\t\t\t\t\tcxxTokenTypeIs(pAssignment->pNext,CXXTokenTypeNumber) &&\n\t\t\t\t\t(strcmp(vStringValue(pAssignment->pNext->pszWord),\"0\") == 0)\n\t\t\t\t)\n\t\t\t\t\tpInfo->uFlags |= CXXFunctionSignatureInfoPure;\n\t\t\t\telse if(cxxTokenTypeIs(pAssignment->pNext,CXXTokenTypeKeyword))\n\t\t\t\t{\n\t\t\t\t\tif(pAssignment->pNext->eKeyword == CXXKeywordDEFAULT)\n\t\t\t\t\t\tpInfo->uFlags |= CXXFunctionSignatureInfoDefault;\n\t\t\t\t\tif(pAssignment->pNext->eKeyword == CXXKeywordDELETE)\n\t\t\t\t\t\tpInfo->uFlags |= CXXFunctionSignatureInfoDelete;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tCXXToken * pIdentOrKeyword = cxxTokenChainNextTokenOfType(\n\t\t\t\t\tpTopLevelParenthesis,\n\t\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeKeyword\n\t\t\t\t);\n\n\t\t\twhile(pIdentOrKeyword)\n\t\t\t{\n\t\t\t\t// override is a keyword only in specific contexts so we handle it as identifier\n\t\t\t\tif(cxxTokenTypeIs(pIdentOrKeyword,CXXTokenTypeKeyword))\n\t\t\t\t{\n\t\t\t\t\tif(pIdentOrKeyword->eKeyword == CXXKeywordVOLATILE)\n\t\t\t\t\t\tpInfo->uFlags |= CXXFunctionSignatureInfoVolatile;\n\t\t\t\t\telse if(pIdentOrKeyword->eKeyword == CXXKeywordTRY)\n\t\t\t\t\t\tpInfo->uFlags |= CXXFunctionSignatureInfoFunctionTryBlock;\n\t\t\t\t} else {\n\t\t\t\t\t// The \"final\" keyword is actually disabled in most contexts so we handle\n\t\t\t\t\t// it as identifier. \"override is always handled as identifier.\n\t\t\t\t\tif(strcmp(vStringValue(pIdentOrKeyword->pszWord),\"final\") == 0)\n\t\t\t\t\t\tpInfo->uFlags |= CXXFunctionSignatureInfoFinal;\n\t\t\t\t\telse if(strcmp(vStringValue(pIdentOrKeyword->pszWord),\"override\") == 0)\n\t\t\t\t\t\tpInfo->uFlags |= CXXFunctionSignatureInfoOverride;\n\t\t\t\t}\n\n\t\t\t\tpIdentOrKeyword = cxxTokenChainNextTokenOfType(\n\t\t\t\t\t\tpIdentOrKeyword,\n\t\t\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeKeyword\n\t\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tpInfo->pSignatureConst = NULL;\n\t\t}\n\t} else {\n\t\tpInfo->pSignatureConst = NULL;\n\t}\n\n\t// Check return type\n\tif(pInfo->pIdentifierChain != pChain)\n\t{\n\t\t// Nested parentheses. In this case the type name is the whole chain (excluding\n\t\t// the identifier and the signature).\n\t\tCXX_DEBUG_PRINT(\"Nested parentheses, probably a function returning pointers\");\n\t\tpInfo->pTypeStart = cxxTokenChainFirst(pChain);\n\t\tpInfo->pTypeEnd = pToken ? pToken->pPrev : cxxTokenChainLast(pChain);\n\t\tpInfo->bTypeContainsIdentifierScopeAndSignature = true;\n\t} else {\n\t\tpToken = pInfo->pScopeStart ? pInfo->pScopeStart : pInfo->pIdentifierStart;\n\n\t\tif(pToken->pPrev)\n\t\t{\n\t\t\tCXXToken * pParenthesisOrConst = pInfo->pSignatureConst ?\n\t\t\t\t\tpInfo->pSignatureConst : pInfo->pParenthesis;\n\t\t\tif(\n\t\t\t\t\tcxxParserCurrentLanguageIsCPP() &&\n\t\t\t\t\tcxxTokenTypeIs(pToken->pPrev,CXXTokenTypeKeyword) &&\n\t\t\t\t\t(pToken->pPrev->eKeyword == CXXKeywordAUTO) &&\n\t\t\t\t\tpParenthesisOrConst->pNext &&\n\t\t\t\t\tcxxTokenTypeIs(\n\t\t\t\t\t\t\tpParenthesisOrConst->pNext,\n\t\t\t\t\t\t\tCXXTokenTypePointerOperator\n\t\t\t\t\t\t) &&\n\t\t\t\t\tpParenthesisOrConst->pNext->pNext &&\n\t\t\t\t\t(!cxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\tpParenthesisOrConst->pNext->pNext,\n\t\t\t\t\t\t\tCXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket\n\t\t\t\t\t\t))\n\t\t\t\t)\n\t\t\t{\n\t\t\t\t// looks like trailing return type\n\t\t\t\t//   auto f() -> int;\n\t\t\t\t//   auto f() -> int {\n\t\t\t\tpInfo->pTypeStart = pParenthesisOrConst->pNext->pNext;\n\t\t\t\tpInfo->pTypeEnd = pInfo->pTypeStart;\n\t\t\t\twhile(\n\t\t\t\t\tpInfo->pTypeEnd->pNext &&\n\t\t\t\t\t(!cxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\tpInfo->pTypeEnd->pNext,\n\t\t\t\t\t\t\tCXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket\n\t\t\t\t\t\t))\n\t\t\t\t)\n\t\t\t\t\tpInfo->pTypeEnd = pInfo->pTypeEnd->pNext;\n\t\t\t} else {\n\t\t\t\t// probably normal return type\n\t\t\t\tpInfo->pTypeEnd = pToken->pPrev;\n\t\t\t\tpInfo->pTypeStart = cxxTokenChainFirst(pChain);\n\n\t\t\t\t// Handle the common special case of\n\t\t\t\t//\n\t\t\t\t//   MACRO(return_type) function()\n\t\t\t\t//\n\n\t\t\t\tif(\n\t\t\t\t\t\tcxxTokenTypeIs(pInfo->pTypeEnd,CXXTokenTypeParenthesisChain) &&\n\t\t\t\t\t\t(pInfo->pTypeEnd->pChain->iCount >= 3) &&\n\t\t\t\t\t\t(pInfo->pTypeEnd->pPrev == pInfo->pTypeStart) &&\n\t\t\t\t\t\tcxxTokenTypeIs(pInfo->pTypeStart,CXXTokenTypeIdentifier)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Return type seems to be embedded in a macro\");\n\t\t\t\t\tpInfo->pTypeStart = cxxTokenChainFirst(pInfo->pTypeEnd->pChain)->pNext;\n\t\t\t\t\tpInfo->pTypeEnd = cxxTokenChainLast(pInfo->pTypeEnd->pChain)->pPrev;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tpInfo->pTypeEnd = NULL;\n\t\t\tpInfo->pTypeStart = NULL;\n\t\t}\n\t\tpInfo->bTypeContainsIdentifierScopeAndSignature = false;\n\t}\n\n#if 0\n\twhile(\n\t\t\t(pInfo->pTypeStart != pInfo->pTypeEnd) &&\n\t\t\tcxxTokenTypeIs(pInfo->pTypeStart,CXXTokenTypeKeyword) &&\n\t\t\tcxxKeywordExcludeFromTypeNames(pInfo->pTypeStart->eKeyword)\n\t\t)\n\t\tpInfo->pTypeStart = pInfo->pTypeStart->pNext;\n#endif\n\n\tCXX_DEBUG_LEAVE_TEXT(\"Found function signature\");\n\treturn true;\n}\n\n\n//\n// Emit a function tag.\n//\n// WARNING: This function is destructive: it removes the scope and\n// identifier tokens from the chain. It will also move the parenthesis\n// around (but will keep it as it contains the parameter definitions).\n//\n// Returns the number of scopes pushed if CXXEmitFunctionTagsPushScopes\n// is present in uOptions and 0 otherwise.\n//\nint cxxParserEmitFunctionTags(\n\t\tCXXFunctionSignatureInfo * pInfo,\n\t\tunsigned int uTagKind,\n\t\tunsigned int uOptions,\n\t\tint * piCorkQueueIndex,\n\t\tint * piCorkQueueIndexFQ\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\n\tint iScopesPushed = 0;\n\n\tif(piCorkQueueIndex)\n\t\t*piCorkQueueIndex = CORK_NIL;\n\tif(piCorkQueueIndexFQ)\n\t\t*piCorkQueueIndexFQ = CORK_NIL;\n\n\tenum CXXScopeType eOuterScopeType = cxxScopeGetType();\n\n\tbool bPushScopes = uOptions & CXXEmitFunctionTagsPushScopes;\n\n\tCXX_DEBUG_PRINT(\"Scope start is %x, push scope is %d\",pInfo->pScopeStart,bPushScopes);\n\n\t// We'll be removing the scope and identifier, fix type\n\tif(\n\t\tpInfo->pTypeStart &&\n\t\t(\n\t\t\t(pInfo->pTypeStart == pInfo->pScopeStart) ||\n\t\t\t(pInfo->pTypeStart == pInfo->pIdentifierStart)\n\t\t)\n\t)\n\t\tpInfo->pTypeStart = pInfo->pIdentifierEnd->pNext;\n\n\tCXX_DEBUG_ASSERT(pInfo->pTypeEnd != pInfo->pIdentifierEnd,\"The type should never end at identifier\");\n\n\tif(pInfo->pScopeStart)\n\t{\n\t\tif(bPushScopes)\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"There is a scope and we're requested to push scopes\");\n\n\t\t\t// there is a scope\n\t\t\twhile(pInfo->pScopeStart != pInfo->pIdentifierStart)\n\t\t\t{\n\t\t\t\tCXXToken * pScopeId = pInfo->pScopeStart;\n\n\t\t\t\twhile (1)\n\t\t\t\t{\n\t\t\t\t\tpInfo->pScopeStart = cxxTokenChainNextTokenOfType(\n\t\t\t\t\t\tpInfo->pScopeStart,\n\t\t\t\t\t\tCXXTokenTypeMultipleColons|CXXTokenTypeSmallerThanSign);\n\n\t\t\t\t\tCXX_DEBUG_ASSERT(pInfo->pScopeStart,\n\t\t\t\t\t\t\t\t\t \"We could find neither '::' nor '<'\");\n\t\t\t\t\tif (!pInfo->pScopeStart)\n\t\t\t\t\t{\n\t\t\t\t\t\tpInfo->pScopeStart = pInfo->pIdentifierStart;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (cxxTokenTypeIs(pInfo->pScopeStart, CXXTokenTypeMultipleColons))\n\t\t\t\t\t\tbreak;\t// Good!\n\n\t\t\t\t\tif (cxxTokenTypeIs(pInfo->pScopeStart, CXXTokenTypeSmallerThanSign))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Skip the template arguments.\n\t\t\t\t\t\t// Should we add the template arguments to the scope? (FIXME)\n\t\t\t\t\t\tpInfo->pScopeStart = cxxTokenChainSkipToEndOfTemplateAngleBracket(pInfo->pScopeStart);\n\t\t\t\t\t\tCXX_DEBUG_ASSERT(pInfo->pScopeStart,\n\t\t\t\t\t\t\t\t\t\t \"We could not find '>', the end of template argument(s)\");\n\t\t\t\t\t\tif (!pInfo->pScopeStart)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpInfo->pScopeStart = pInfo->pIdentifierStart;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tCXX_DEBUG_ASSERT(pInfo->pScopeStart,\"We should have found a next token here\");\n\n\t\t\t\tpInfo->pScopeStart = pInfo->pScopeStart->pNext;\n\n\t\t\t\tcxxTokenChainDestroyRange(\n\t\t\t\t\t\tpInfo->pIdentifierChain,\n\t\t\t\t\t\tpScopeId->pNext,\n\t\t\t\t\t\tpInfo->pScopeStart->pPrev\n\t\t\t\t\t);\n\n\t\t\t\tcxxTokenChainTake(pInfo->pIdentifierChain,pScopeId);\n\n\n\t\t\t\tCXX_DEBUG_PRINT(\"Pushing scope %s\",vStringValue(pScopeId->pszWord));\n\n\t\t\t\tcxxScopePush(\n\t\t\t\t\t\tpScopeId,\n\t\t\t\t\t\tCXXScopeTypeClass,\n\t\t\t\t\t\t// WARNING: We don't know if it's really a class! (FIXME?)\n\t\t\t\t\t\tCXXScopeAccessUnknown\n\t\t\t\t\t);\n\t\t\t\tiScopesPushed++;\n\t\t\t}\n\t\t} else {\n\t\t\tcxxTokenChainDestroyRange(\n\t\t\t\t\tpInfo->pIdentifierChain,\n\t\t\t\t\tpInfo->pScopeStart,\n\t\t\t\t\tpInfo->pIdentifierStart->pPrev\n\t\t\t\t);\n\t\t}\n\t}\n\n\tCXXToken * pIdentifier = cxxTokenChainExtractRange(\n\t\t\tpInfo->pIdentifierStart,\n\t\t\tpInfo->pIdentifierEnd,\n\t\t\t// proper spacing has been already ensured\n\t\t\t// by cxxParserLookForFunctionSignature()\n\t\t\t0\n\t\t);\n\n\tcxxSideChainCollectInRange(pInfo->pIdentifierStart,pInfo->pIdentifierEnd,pIdentifier);\n\tcxxTokenChainDestroyRange(pInfo->pIdentifierChain,pInfo->pIdentifierStart,pInfo->pIdentifierEnd);\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tpIdentifier,\n\t\t\t\"The identifier should have been non null since the \" \\\n\t\t\t\t\"indices point inside this chain\"\n\t\t);\n\tpIdentifier->eType = CXXTokenTypeIdentifier; // force it\n\n\tCXX_DEBUG_PRINT(\"Identifier is '%s'\",vStringValue(pIdentifier->pszWord));\n\n\ttagEntryInfo * tag;\n\tCXXToken * pSavedScope;\n\n\tif(\n\t\t\t(uTagKind == CXXTagKindFUNCTION) &&\n\t\t\t(g_cxx.uKeywordState & CXXParserKeywordStateSeenFriend) &&\n\t\t\t(!cxxScopeIsGlobal())\n\t\t)\n\t{\n\t\t// When \"friend\" has been seen, and uTagKind == CXXTagKindFUNCTION\n\t\t// the scope we're using is off by one level. This is the \"friend definition\"\n\t\t// trick:\n\t\t//\n\t\t//  class X\n\t\t//  {\n\t\t//   inline friend void y(){ ... }\n\t\t//  }\n\t\t//\n\t\t// Here y() is implicitly defined as a function in the namespace contaning X\n\t\t// (so it is NOT X::y()).\n\n\t\tpSavedScope = cxxScopeTakeTop();\n\t\ttag = cxxTagBegin(uTagKind,pIdentifier);\n\n\t\t// We shouldn't really push back the last scope while the function is being\n\t\t// parsed, but this is hard to do with the current implementation. We would need\n\t\t// to store this scope somewhere and push it back after the body of the function\n\t\t// has been parsed. It can be done, but it's expensive.\n\t\t//\n\t\t// Friend declarations are very rare and are implicitly inlined per C++ standard\n\t\t// so \"sane\" such declarations are short and usually don't have meaningful tags inside.\n\n\t} else {\n\t\tpSavedScope = NULL;\n\t\ttag = cxxTagBegin(uTagKind,pIdentifier);\n\t}\n\n\tbool bGotTemplate = g_cxx.pTemplateTokenChain &&\n\t\t\t\t(g_cxx.pTemplateTokenChain->iCount > 0) &&\n\t\t\t\tcxxParserCurrentLanguageIsCPP();\n\n\tif(tag)\n\t{\n\t\tif(pInfo->pParenthesis->pChain->pTail)\n\t\t{\n\t\t\t// normalize signature\n\t\t\tcxxTokenChainNormalizeTypeNameSpacing(pInfo->pParenthesis->pChain);\n\t\t\t// make sure we don't emit the trailing space\n\t\t\tpInfo->pParenthesis->pChain->pTail->bFollowedBySpace = false;\n\t\t}\n\n\t\tif(uTagKind == CXXTagKindPROTOTYPE)\n\t\t{\n\t\t\ttag->isFileScope = !isInputHeaderFile();\n\t\t} else {\n\t\t\t// function definitions\n\t\t\tif(eOuterScopeType == CXXScopeTypeNamespace)\n\t\t\t{\n\t\t\t\t// in a namespace only static stuff declared in cpp files is file scoped\n\t\t\t\ttag->isFileScope = (\n\t\t\t\t\t\tg_cxx.uKeywordState & CXXParserKeywordStateSeenStatic\n\t\t\t\t\t) && (\n\t\t\t\t\t\t!isInputHeaderFile()\n\t\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// in a class/struct/union file scope stuff is only in cpp files\n\t\t\t\ttag->isFileScope = !isInputHeaderFile();\n\t\t\t}\n\t\t}\n\t\t// Overwrite the assigned value if the language object is export'ed.\n\t\ttag->isFileScope = ((g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)\n\t\t\t\t\t\t\t|| cxxScopeIsExported())\n\t\t\t? 0\n\t\t\t: tag->isFileScope;\n\n\t\tvString * pszSignature = cxxTokenChainJoin(pInfo->pParenthesis->pChain,NULL,0);\n\t\tif(pInfo->pSignatureConst)\n\t\t{\n\t\t\tvStringPut (pszSignature, ' ');\n\t\t\tcxxTokenAppendToString(pszSignature,pInfo->pSignatureConst);\n\t\t}\n\n\t\tCXXToken * pTypeName;\n\n\t\tif(pInfo->pTypeStart)\n\t\t{\n\t\t\tif(pInfo->bTypeContainsIdentifierScopeAndSignature)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_PRINT(\"Type contains identifier and scope\");\n\t\t\t\t// Special case: the type contains the identifier and parenthesis\n\t\t\t\t// (generally things like int (*foo(void))[2] or similar).\n\n\t\t\t\t// Scope and identifier have already been removed.\n\t\t\t\t// Remove the parenthesis, temporarily.\n\t\t\t\tif(pInfo->pTypeStart == pInfo->pParenthesis)\n\t\t\t\t\tpInfo->pTypeStart = pInfo->pParenthesis->pNext;\n\t\t\t\tif(pInfo->pTypeEnd == pInfo->pParenthesis)\n\t\t\t\t\tpInfo->pTypeEnd = pInfo->pParenthesis->pPrev;\n\n\t\t\t\tif(pInfo->pTypeStart && pInfo->pTypeEnd)\n\t\t\t\t{\n\t\t\t\t\tCXXToken * pTokenBeforeParenthesis = pInfo->pParenthesis->pPrev;\n\t\t\t\t\tcxxTokenChainTake(pInfo->pParenthesisContainerChain,pInfo->pParenthesis);\n\n\t\t\t\t\tcxxSideChainCollectInRange(pInfo->pTypeStart,pInfo->pTypeEnd, pIdentifier);\n\t\t\t\t\tpTypeName = cxxTagCheckAndSetTypeField(pInfo->pTypeStart,pInfo->pTypeEnd);\n\n\t\t\t\t\tcxxTokenChainInsertAfter(\n\t\t\t\t\t\t\tpInfo->pParenthesisContainerChain,\n\t\t\t\t\t\t\tpTokenBeforeParenthesis,\n\t\t\t\t\t\t\tpInfo->pParenthesis\n\t\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tpTypeName = NULL;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcxxSideChainCollectInRange(pInfo->pTypeStart,pInfo->pTypeEnd, pIdentifier);\n\t\t\t\tpTypeName = cxxTagCheckAndSetTypeField(pInfo->pTypeStart,pInfo->pTypeEnd);\n\t\t\t}\n\t\t} else {\n\t\t\tpTypeName = NULL;\n\t\t}\n\n\t\tif(pszSignature)\n\t\t\ttag->extensionFields.signature = vStringValue(pszSignature);\n\n\t\tbool bIsEmptyTemplate;\n\n\t\tif(bGotTemplate)\n\t\t{\n\t\t\tbIsEmptyTemplate = g_cxx.pTemplateTokenChain->iCount == 2;\n\n\t\t\tif(pInfo->pTemplateSpecializationStart)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_ASSERT(pInfo->pTemplateSpecializationEnd,\"Bug\");\n\t\t\t\tcxxTokenChainNormalizeTypeNameSpacingInRange(\n\t\t\t\t\t\tpInfo->pTemplateSpecializationStart,\n\t\t\t\t\t\tpInfo->pTemplateSpecializationEnd\n\t\t\t\t\t);\n\t\t\t\t// make sure we don't emit the trailing space\n\t\t\t\tpInfo->pTemplateSpecializationStart->bFollowedBySpace = false;\n\n\t\t\t\tCXXToken * pToken = cxxTokenChainExtractRange(\n\t\t\t\t\t\tpInfo->pTemplateSpecializationStart,\n\t\t\t\t\t\tpInfo->pTemplateSpecializationEnd,\n\t\t\t\t\t\t0\n\t\t\t\t\t);\n\n\t\t\t\t// Tricky. We append it to the specialization chain which will\n\t\t\t\t// be then used by cxxTagHandleTemplateFileds()\n\t\t\t\tif(pToken)\n\t\t\t\t{\n\t\t\t\t\tif(g_cxx.pTemplateSpecializationTokenChain)\n\t\t\t\t\t\tcxxTokenChainClear(g_cxx.pTemplateSpecializationTokenChain);\n\t\t\t\t\telse\n\t\t\t\t\t\tg_cxx.pTemplateSpecializationTokenChain = cxxTokenChainCreate();\n\t\t\t\t\tcxxTokenChainAppend(g_cxx.pTemplateSpecializationTokenChain,pToken);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcxxTagHandleTemplateFields();\n\t\t} else {\n\t\t\tbIsEmptyTemplate = false;\n\t\t}\n\n\t\tvString * pszProperties = NULL;\n\n\t\tif(cxxTagFieldEnabled(CXXTagFieldProperties))\n\t\t{\n\t\t\tunsigned int uProperties = 0;\n\n\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenVirtual)\n\t\t\t\tuProperties |= CXXTagPropertyVirtual;\n\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenStatic)\n\t\t\t\tuProperties |= CXXTagPropertyStatic;\n\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenInline)\n\t\t\t\tuProperties |= CXXTagPropertyInline;\n\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenExplicit)\n\t\t\t\tuProperties |= CXXTagPropertyExplicit; // FIXME: Handle \"CXXTagPropertyConstructor\"?\n\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenExtern)\n\t\t\t\tuProperties |= CXXTagPropertyExtern;\n\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenAttributeDeprecated)\n\t\t\t\tuProperties |= CXXTagPropertyDeprecated;\n\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenConstexpr)\n\t\t\t\tuProperties |= CXXTagPropertyConstexpr;\n\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenConsteval)\n\t\t\t\tuProperties |= CXXTagPropertyConsteval;\n\t\t\t// constinit is not here; it is for variables.\n\t\t\tif(pInfo->pSignatureConst)\n\t\t\t\tuProperties |= CXXTagPropertyConst;\n\t\t\tif(pInfo->uFlags & CXXFunctionSignatureInfoPure)\n\t\t\t\tuProperties |= CXXTagPropertyPure | CXXTagPropertyVirtual;\n\t\t\tif(pInfo->uFlags & CXXFunctionSignatureInfoOverride)\n\t\t\t\tuProperties |= CXXTagPropertyOverride | CXXTagPropertyVirtual;\n\t\t\tif(pInfo->uFlags & CXXFunctionSignatureInfoFinal)\n\t\t\t\tuProperties |= CXXTagPropertyFinal | CXXTagPropertyVirtual;\n\t\t\tif(pInfo->uFlags & CXXFunctionSignatureInfoDefault)\n\t\t\t\tuProperties |= CXXTagPropertyDefault;\n\t\t\tif(pInfo->uFlags & CXXFunctionSignatureInfoDelete)\n\t\t\t\tuProperties |= CXXTagPropertyDelete;\n\t\t\tif(pInfo->uFlags & CXXFunctionSignatureInfoVolatile)\n\t\t\t\tuProperties |= CXXTagPropertyVolatile;\n\t\t\tif(pInfo->uFlags & CXXFunctionSignatureInfoFunctionTryBlock)\n\t\t\t\tuProperties |= CXXTagPropertyFunctionTryBlock;\n\t\t\tif(pInfo->uFlags & CXXFunctionSignatureInfoScopeTemplateSpecialization)\n\t\t\t\tuProperties |= CXXTagPropertyScopeTemplateSpecialization |\n\t\t\t\t\t\t\t\tCXXTagPropertyTemplateSpecialization;\n\t\t\tif((pInfo->uFlags & CXXFunctionSignatureInfoTemplateSpecialization) || bIsEmptyTemplate)\n\t\t\t\tuProperties |= CXXTagPropertyTemplateSpecialization;\n\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)\n\t\t\t\tuProperties |= CXXTagPropertyExport;\n\n\t\t\tpszProperties = cxxTagSetProperties(uProperties);\n\t\t}\n\n\t\tcxxSideChainScan(pIdentifier->pSideChain);\n\n\t\tint iCorkQueueIndex = cxxTagCommit(piCorkQueueIndexFQ);\n\t\tcxxTagUseTokenAsPartOfDefTag(iCorkQueueIndex, pIdentifier);\n\n\t\tif(piCorkQueueIndex)\n\t\t\t*piCorkQueueIndex = iCorkQueueIndex;\n\n\t\tif(pszSignature)\n\t\t\tvStringDelete(pszSignature);\n\n\t\tif(pszProperties)\n\t\t\tvStringDelete(pszProperties);\n\n\t\tif(pTypeName)\n\t\t\tcxxTokenDestroy(pTypeName);\n\t}\n\n\tif(pSavedScope)\n\t\tcxxScopePushTop(pSavedScope);\n\n#ifdef CXX_DO_DEBUGGING\n\tif(tag)\n\t{\n\t\tif(uTagKind == CXXTagKindFUNCTION)\n\t\t\tCXX_DEBUG_PRINT(\"Emitted function '%s'\",vStringValue(pIdentifier->pszWord));\n\t\telse\n\t\t\tCXX_DEBUG_PRINT(\"Emitted prototype '%s'\",vStringValue(pIdentifier->pszWord));\n\t}\n#endif\n\n\tif(bPushScopes)\n\t{\n\t\tcxxScopePush(pIdentifier,\n\t\t\t\t\t (uTagKind == CXXTagKindPROTOTYPE)? CXXScopeTypePrototype: CXXScopeTypeFunction,\n\t\t\t\t\t CXXScopeAccessUnknown);\n\t\tiScopesPushed++;\n\t} else {\n\t\tcxxTokenDestroy(pIdentifier);\n\t}\n\n\tif(\n\t\t\ttag &&\n\t\t\tbGotTemplate &&\n\t\t\tcxxTagKindEnabled(CXXTagCPPKindTEMPLATEPARAM)\n\t\t)\n\t\tcxxParserEmitTemplateParameterTags();\n\n\tCXX_DEBUG_LEAVE();\n\treturn iScopesPushed;\n}\n\n//\n// This is called at block level upon encountering an opening bracket,\n// when we are not in a function. The current block chain almost certainly\n// contains a function signature.\n//\n// This function attempts to extract the function name, emit it as a tag\n// and push all the necessary scopes for the next block. It returns the number\n// of scopes pushed.\n//\n// When the returned number of scopes is 0 then no function has been found.\n//\nint cxxParserExtractFunctionSignatureBeforeOpeningBracket(\n\t\tCXXFunctionSignatureInfo * pInfo,\n\t\tint * piCorkQueueIndex,\n\t\tint * piCorkQueueIndexFQ\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\n#ifdef CXX_DO_DEBUGGING\n\tvString * pChain = cxxTokenChainJoin(g_cxx.pTokenChain,NULL,0);\n\tCXX_DEBUG_PRINT(\"Looking for function in '%s'\",vStringValue(pChain));\n\tvStringDelete(pChain);\n#endif\n\n\t// Note that the token chain ALWAYS contains the final delimiter here.\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tg_cxx.pTokenChain->iCount > 0,\n\t\t\t\"There should be at least the terminator here!\"\n\t\t);\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenChainLast(g_cxx.pTokenChain)->eType == CXXTokenTypeOpeningBracket,\n\t\t\t\"We should have been called when pointing on an opening bracket!\"\n\t\t);\n\n\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\n\tCXXTypedVariableSet oParamInfo;\n\tbool bParams = cxxTagKindEnabled(CXXTagKindPARAMETER);\n\n\tif(!cxxParserLookForFunctionSignature(g_cxx.pTokenChain,pInfo,bParams?&oParamInfo:NULL))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"No parenthesis found: no function\");\n\t\treturn 0;\n\t}\n\n\t// Note that emitting the tag is ok even if 'friend' has been seen,\n\t// but the scope will be adjusted inside cxxParserEmitFunctionTags()\n\n\tint iScopesPushed = cxxParserEmitFunctionTags(\n\t\t\tpInfo,\n\t\t\tCXXTagKindFUNCTION,\n\t\t\tCXXEmitFunctionTagsPushScopes,\n\t\t\tpiCorkQueueIndex,\n\t\t\tpiCorkQueueIndexFQ\n\t\t);\n\n\tif(bParams)\n\t\tcxxParserEmitFunctionParameterTags(&oParamInfo);\n\n\tCXX_DEBUG_LEAVE();\n\treturn iScopesPushed;\n}\n\n// This function *may* change the token chain\nvoid cxxParserEmitFunctionParameterTags(CXXTypedVariableSet * pInfo)\n{\n\t// emit parameters\n\tCXX_DEBUG_ENTER();\n\n\tunsigned int i = 0;\n\twhile(i < pInfo->uCount)\n\t{\n\t\ttagEntryInfo * tag = cxxTagBegin(\n\t\t\t\tCXXTagKindPARAMETER,\n\t\t\t\tpInfo->aIdentifiers[i]\n\t\t\t);\n\n\t\tif(!tag)\n\t\t\tbreak;\n\n\t\tCXXToken * pTypeName;\n\n\t\tif(pInfo->aTypeStarts[i] && pInfo->aTypeEnds[i])\n\t\t{\n\t\t\t// This is tricky.\n\t\t\t// We know that the declaration contains the identifier.\n\t\t\t// We don't want the identifier to appear in the type name.\n\t\t\t// So we have to remove it from the chain (eventually recursively if there\n\t\t\t// are nested parentheses).\n\t\t\t// However the declaration might start or end with the identifier\n\t\t\t// and in that case we would be effectively breaking the type chain.\n\t\t\t// Work around it.\n\n\t\t\tCXXToken * pTypeStart = pInfo->aTypeStarts[i];\n\t\t\tCXXToken * pTypeEnd = pInfo->aTypeEnds[i];\n\n\t\t\tif(pTypeStart != pTypeEnd)\n\t\t\t{\n\t\t\t\tif(pTypeStart == pInfo->aIdentifiers[i])\n\t\t\t\t\tpTypeStart = pTypeStart->pNext;\n\t\t\t\telse if(pTypeEnd == pInfo->aIdentifiers[i])\n\t\t\t\t\tpTypeEnd = pTypeEnd->pPrev;\n\n\t\t\t\tcxxTokenChainTakeRecursive(pInfo->pChain,pInfo->aIdentifiers[i]);\n\n\t\t\t\tpTypeName = cxxTagCheckAndSetTypeField(\n\t\t\t\t\t\tpTypeStart,\n\t\t\t\t\t\tpTypeEnd\n\t\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// The declaration contains only the identifier!\n\t\t\t\tpTypeName = NULL;\n\t\t\t}\n\t\t} else {\n\t\t\tpTypeName = NULL;\n\t\t}\n\n\t\ttag->isFileScope = true;\n\n\t\tif (pInfo->uAnonymous & (0x1u << i))\n\t\t\tmarkTagExtraBit(tag, XTAG_ANONYMOUS);\n\n\t\tcxxTagCommit(NULL);\n\n\t\tif(pTypeName)\n\t\t{\n\t\t\tif (pInfo->uAnonymous & (0x1u << i))\n\t\t\t\tPARSER_TRASH_BOX_TAKE_BACK (pInfo->aIdentifiers[i]);\n\t\t\tcxxTokenDestroy(pInfo->aIdentifiers[i]);\n\t\t\tcxxTokenDestroy(pTypeName);\n\t\t}\n\n\t\ti++;\n\t}\n\tCXX_DEBUG_LEAVE();\n}\n\n\n\n//\n// This function checks if the specified token chain looks like a\n// non K&R style function parameter list, eventually with default arguments\n// and such.\n//\n// If pParamInfo is non NULL then the function will also gather\n// informations about the parameters and store them.\n//\nbool cxxParserTokenChainLooksLikeFunctionParameterList(\n\t\tCXXTokenChain * tc,\n\t\tCXXTypedVariableSet * pParamInfo\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\tCXX_DEBUG_ASSERT(\n\t\t\ttc->iCount >= 2,\n\t\t\t\"At least initial and final parenthesis should be there\"\n\t\t);\n\n\tCXX_DEBUG_ASSERT(\n\t\t\t(cxxTokenChainFirst(tc)->eType == CXXTokenTypeOpeningParenthesis) &&\n\t\t\t(cxxTokenChainLast(tc)->eType == CXXTokenTypeClosingParenthesis),\n\t\t\t\"The first and last token should be parentheses here\"\n\t\t);\n\n\tif(pParamInfo)\n\t{\n\t\tpParamInfo->uCount = 0;\n\t\tpParamInfo->pChain = tc;\n\t}\n\n\tif(tc->iCount == 2)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Empty signature is valid for a function\");\n\t\treturn true;\n\t}\n\n\tCXXToken * t = cxxTokenChainAt(tc,1);\n\n\tbool bIsC = ! (cxxParserCurrentLanguageIsCPP() || cxxParserCurrentLanguageIsCUDA());\n\n\tfor(;;)\n\t{\n\t\t// Check every parameter.\n\t\t//\n\t\t// Possibilities:\n\t\t//\n\t\t//    type variable\n\t\t//    type /* variable omitted */\n\t\t//    type variable[..]\n\t\t//    type variable:bits\n\t\t//    type (*variable)(args)\n\t\t//    type ((*variable)(args))\n\t\t//    <anything of the above> = default <-- C++ only\n\t\t//    ... <-- vararg\n\t\t//\n\n\t\tCXXToken * pStart = t;\n\n\t\t// First token must be identifier/keyword, :: or ...\n\t\tif(!cxxTokenTypeIsOneOf(\n\t\t\t\tt,\n\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeKeyword |\n\t\t\t\t\tCXXTokenTypeMultipleDots | CXXTokenTypeMultipleColons\n\t\t\t))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\"Token '%s' is something that is not a identifier, keyword, :: or ...\",\n\t\t\t\t\tvStringValue(t->pszWord)\n\t\t\t\t);\n\t\t\treturn false;\n\t\t}\n\n#define TOKENS_THAT_SHOULD_NOT_APPEAR_IN_SIGNATURE_BEFORE_ASSIGNMENT \\\n\t\t( \\\n\t\t\tCXXTokenTypePointerOperator | \\\n\t\t\tCXXTokenTypeOperator | \\\n\t\t\tCXXTokenTypeDotOperator | \\\n\t\t\tCXXTokenTypeNumber | \\\n\t\t\tCXXTokenTypeStringConstant | \\\n\t\t\tCXXTokenTypeCharacterConstant | \\\n\t\t\tCXXTokenTypeAngleBracketChain | \\\n\t\t\tCXXTokenTypeSingleColon \\\n\t\t)\n\ntry_again:\n\t\tt = cxxTokenChainNextTokenOfType(\n\t\t\t\tt,\n\t\t\t\tCXXTokenTypeClosingParenthesis | CXXTokenTypeComma |\n\t\t\t\t\tCXXTokenTypeAssignment | CXXTokenTypeSmallerThanSign |\n\t\t\t\t\tCXXTokenTypeGreaterThanSign | CXXTokenTypeParenthesisChain |\n\t\t\t\tTOKENS_THAT_SHOULD_NOT_APPEAR_IN_SIGNATURE_BEFORE_ASSIGNMENT\n\t\t\t);\n\n\t\tCXX_DEBUG_ASSERT(t,\"We should have found the closing parenthesis here\");\n\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeParenthesisChain))\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"Found parenthesis chain\");\n\t\t\t// Either part of function pointer declaration or a very ugly variable decl\n\t\t\t// Examples are:\n\t\t\t//    type (*name)(args)\n\t\t\t//    type ((*name)(args))\n\t\t\t//    type (*name)\n\t\t\t//    type (&name)\n\t\t\t//    type (&name)[something]\n\t\t\t//    ...\n\t\t\t//\n\t\t\t// FIXME: This check should be stricter (?)\n\t\t\tif(\n\t\t\t\t(\n\t\t\t\t\t!cxxTokenChainFirstTokenOfType(\n\t\t\t\t\t\t\tt->pChain,\n\t\t\t\t\t\t\tTOKENS_THAT_SHOULD_NOT_APPEAR_IN_SIGNATURE_BEFORE_ASSIGNMENT\n\t\t\t\t\t\t)\n\t\t\t\t) && (\n\t\t\t\t\tcxxTokenChainFirstTokenOfType(\n\t\t\t\t\t\t\tt->pChain,\n\t\t\t\t\t\t\tCXXTokenTypeStar | CXXTokenTypeAnd\n\t\t\t\t\t\t) || // part of (*name) or (&name)\n\t\t\t\t\tcxxParserTokenChainLooksLikeFunctionParameterList(\n\t\t\t\t\t\t\tt->pChain,\n\t\t\t\t\t\t\tNULL\n\t\t\t\t\t\t) || // (args)\n\t\t\t\t\t!cxxTokenChainFirstTokenNotOfType(\n\t\t\t\t\t\t\tt->pChain,\n\t\t\t\t\t\t\tCXXTokenTypeOpeningParenthesis |\n\t\t\t\t\t\t\t\tCXXTokenTypeParenthesisChain |\n\t\t\t\t\t\t\t\tCXXTokenTypeClosingParenthesis\n\t\t\t\t\t\t) // ((whatever)(whatever))\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tgoto try_again;\n\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\"Found a parenthesis chain that doesn't belong to a function parameters list\"\n\t\t\t\t);\n\t\t\treturn false;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeSmallerThanSign))\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"Maybe template?\");\n\n\t\t\tt = cxxTokenChainSkipToEndOfTemplateAngleBracket(t);\n\n\t\t\tif(!t)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\"Either not a function declaration or unbalanced \" \\\n\t\t\t\t\t\t\t\"template angle brackets\"\n\t\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tgoto try_again;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeGreaterThanSign))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Unbalanced > (a < should have been found before)\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif(cxxTokenTypeIsOneOf(\n\t\t\t\tt,\n\t\t\t\tTOKENS_THAT_SHOULD_NOT_APPEAR_IN_SIGNATURE_BEFORE_ASSIGNMENT\n\t\t\t))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\"Token '%s' is something that doesn't belong to a function \" \\\n\t\t\t\t\t\t\"parameter list\",\n\t\t\t\t\tvStringValue(t->pszWord)\n\t\t\t\t);\n\t\t\treturn false;\n\t\t}\n\n\t\t// closing parenthesis, assignment or comma\n\n\t\tif(pParamInfo && (t->pPrev != pStart))\n\t\t{\n\t\t\t// FIXME: This may break in some special macro cases?\n\t\t\tif(pParamInfo->uCount < CXX_TYPED_VARIABLE_SET_ITEM_COUNT)\n\t\t\t{\n\t\t\t\t// locate identifier\n\n\t\t\t\tCXXToken * pIdentifier = NULL;\n\n\t\t\t\tif(cxxTokenTypeIs(t->pPrev,CXXTokenTypeIdentifier))\n\t\t\t\t{\n\t\t\t\t\t// type var\n\t\t\t\t\tpIdentifier = t->pPrev;\n\t\t\t\t} else if(t->pPrev->pPrev)\n\t\t\t\t{\n\t\t\t\t\tCXXToken *pNonSquareParenthesis = cxxTokenChainPreviousTokenNotOfType(\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\tCXXTokenTypeSquareParenthesisChain\n\t\t\t\t\t\t);\n\n\t\t\t\t\tbool bPrevIsSquareParenthesis = (\n\t\t\t\t\t\t\tpNonSquareParenthesis &&\n\t\t\t\t\t\t\t(pNonSquareParenthesis != t->pPrev)\n\t\t\t\t\t\t);\n\n\t\t\t\t\tif(\n\t\t\t\t\t\tbPrevIsSquareParenthesis &&\n\t\t\t\t\t\tcxxTokenTypeIs(pNonSquareParenthesis,CXXTokenTypeIdentifier)\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// type var[]\n\t\t\t\t\t\t// type var[]...[]\n\t\t\t\t\t\tpIdentifier = pNonSquareParenthesis;\n\t\t\t\t\t} else if(\n\t\t\t\t\t\tbPrevIsSquareParenthesis &&\n\t\t\t\t\t\tcxxTokenTypeIs(pNonSquareParenthesis,CXXTokenTypeParenthesisChain) &&\n\t\t\t\t\t\t(pIdentifier = cxxTokenChainFirstTokenOfType(\n\t\t\t\t\t\t\t\tpNonSquareParenthesis->pChain,\n\t\t\t\t\t\t\t\tCXXTokenTypeIdentifier\n\t\t\t\t\t\t\t))\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// type (...var)[]\n\t\t\t\t\t} else if(\n\t\t\t\t\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeNumber) &&\n\t\t\t\t\t\tcxxTokenTypeIs(t->pPrev->pPrev,CXXTokenTypeIdentifier)\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// type var:bits\n\t\t\t\t\t\tpIdentifier = t->pPrev->pPrev;\n\t\t\t\t\t} else if(\n\t\t\t\t\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeParenthesisChain) &&\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t// type (*name)(args)\n\t\t\t\t\t\t\t\tcxxTokenTypeIs(\n\t\t\t\t\t\t\t\t\t\tt->pPrev->pPrev,\n\t\t\t\t\t\t\t\t\t\tCXXTokenTypeParenthesisChain\n\t\t\t\t\t\t\t\t\t) &&\n\t\t\t\t\t\t\t\t(pIdentifier = cxxTokenChainLastPossiblyNestedTokenOfType(\n\t\t\t\t\t\t\t\t\t\tt->pPrev->pPrev->pChain,\n\t\t\t\t\t\t\t\t\t\tCXXTokenTypeIdentifier, NULL\n\t\t\t\t\t\t\t\t\t)) &&\n\t\t\t\t\t\t\t\tpIdentifier->pPrev &&\n\t\t\t\t\t\t\t\tcxxTokenTypeIs(pIdentifier->pPrev,CXXTokenTypeStar)\n\t\t\t\t\t\t\t) || (\n\t\t\t\t\t\t\t\t// type (*&name)\n\t\t\t\t\t\t\t\t(pIdentifier = cxxTokenChainLastPossiblyNestedTokenOfType(\n\t\t\t\t\t\t\t\t\t\tt->pPrev->pChain,\n\t\t\t\t\t\t\t\t\t\tCXXTokenTypeIdentifier, NULL\n\t\t\t\t\t\t\t\t\t)) &&\n\t\t\t\t\t\t\t\tpIdentifier->pPrev &&\n\t\t\t\t\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\t\t\t\tpIdentifier->pPrev,\n\t\t\t\t\t\t\t\t\t\tCXXTokenTypeStar | CXXTokenTypeAnd\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// type (*ptr)(args)\n\t\t\t\t\t\t// pIdentifier already set above\n\t\t\t\t\t\t// FIXME: Check this better?\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(pIdentifier || isXtagEnabled(XTAG_ANONYMOUS))\n\t\t\t\t{\n\t\t\t\t\tpParamInfo->aTypeStarts[pParamInfo->uCount] = pStart;\n\t\t\t\t\tpParamInfo->aTypeEnds[pParamInfo->uCount] = t->pPrev;\n\t\t\t\t\tpParamInfo->uAnonymous &= ~(0x1u << pParamInfo->uCount);\n\t\t\t\t\tif(!pIdentifier)\n\t\t\t\t\t{\n\t\t\t\t\t\t/* This block handles parameter having no name lie\n\t\t\t\t\t\t *\n\t\t\t\t\t\t *   void f(int *);\n\t\t\t\t\t\t */\n\t\t\t\t\t\tpIdentifier = cxxTokenCreateAnonymousIdentifier(CXXTagKindPARAMETER, NULL);\n\t\t\t\t\t\tpIdentifier->iLineNumber = t->pPrev->iLineNumber;\n\t\t\t\t\t\tpIdentifier->oFilePosition = t->pPrev->oFilePosition;\n\t\t\t\t\t\tpParamInfo->uAnonymous |= (0x1u << pParamInfo->uCount);\n\t\t\t\t\t\tPARSER_TRASH_BOX (pIdentifier, cxxTokenDestroy);\n\t\t\t\t\t}\n\t\t\t\t\tpParamInfo->aIdentifiers[pParamInfo->uCount] = pIdentifier;\n\t\t\t\t\tpParamInfo->uCount++;\n\n#ifdef CXX_DO_DEBUGGING\n\t\t\t\t\tCXXToken * pDecl = cxxTokenChainExtractRange(pStart,t->pPrev,0);\n\t\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\t\"Found parameter '%s' in '%s'\",\n\t\t\t\t\t\t\tvStringValue(pIdentifier->pszWord),\n\t\t\t\t\t\t\tvStringValue(pDecl->pszWord)\n\t\t\t\t\t\t);\n\t\t\t\t\tcxxTokenDestroy(pDecl);\n\t\t\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\t\t\tcxxTokenChainFindToken(pParamInfo->pChain,pStart) >= 0,\n\t\t\t\t\t\t\t\"The start token must be in the chain\"\n\t\t\t\t\t\t);\n\t\t\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\t\t\tcxxTokenChainFindToken(pParamInfo->pChain,t->pPrev) >= 0,\n\t\t\t\t\t\t\t\"The end token must be in the chain\"\n\t\t\t\t\t\t);\n#endif\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpParamInfo = NULL; // reset so condition will be faster to check\n\t\t\t}\n\t\t} else if (pParamInfo\n\t\t\t\t   && (pParamInfo->uCount < CXX_TYPED_VARIABLE_SET_ITEM_COUNT)\n\t\t\t\t   && (!cxxTokenIsKeyword(pStart, CXXKeywordVOID))\n\t\t\t\t   && (!cxxTokenTypeIs(pStart,CXXTokenTypeMultipleDots))\n\t\t\t\t   && isXtagEnabled(XTAG_ANONYMOUS)) {\n\t\t\t/* This block handles parameter having no name like\n\t\t\t *\n\t\t\t *    int f (int);\n\t\t\t *\n\t\t\t * In C language, you will find such a thing in a prototype.\n\t\t\t * In C++ language, you will find it even in a function definition.\n\t\t\t *\n\t\t\t */\n\t\t\tCXXToken * pFakeStart = cxxTokenCopy(pStart);\n\t\t\tCXXToken * pFakeId = cxxTokenCreateAnonymousIdentifier(CXXTagKindPARAMETER, NULL);\n\t\t\tpFakeId->iLineNumber = pStart->iLineNumber;\n\t\t\tpFakeId->oFilePosition = pStart->oFilePosition;\n\n\t\t\tpFakeStart->pNext = pFakeId;\n\t\t\tpFakeId->pPrev = pFakeStart;\n\n\t\t\tpParamInfo->aTypeStarts[pParamInfo->uCount] = pFakeStart;\n\t\t\tpParamInfo->aTypeEnds[pParamInfo->uCount] = pFakeId;\n\t\t\tpParamInfo->aIdentifiers[pParamInfo->uCount] = pFakeId;\n\t\t\tpParamInfo->uAnonymous |= (0x1u << pParamInfo->uCount);\n\t\t\tpParamInfo->uCount++;\n\n\t\t\tPARSER_TRASH_BOX (pFakeStart, cxxTokenDestroy);\n\t\t\tPARSER_TRASH_BOX (pFakeId, cxxTokenDestroy);\n\t\t}\n\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeClosingParenthesis))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found closing parenthesis, it's OK\");\n\t\t\treturn true;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeComma))\n\t\t{\n\t\t\t// ok, go ahead\n\t\t\tCXX_DEBUG_PRINT(\"Found comma\");\n\t\t\tt = t->pNext;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// assignment.\n\t\tif(bIsC)\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\"Found assignment, this doesn't look like valid C function parameter list\"\n\t\t\t\t);\n\t\t\treturn false;\n\t\t}\n\n\t\tCXX_DEBUG_PRINT(\"Found assignment\");\n\n\t\tt = cxxTokenChainNextTokenOfType(t,CXXTokenTypeClosingParenthesis | CXXTokenTypeComma);\n\n\t\tCXX_DEBUG_ASSERT(t,\"We should have found the closing parenthesis here\");\n\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeClosingParenthesis))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found closing parenthesis, it's OK\");\n\t\t\treturn true;\n\t\t}\n\n\t\t// ok, comma\n\t\tt = t->pNext;\n\t}\n\n\t// not reached\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_parser_internal.h",
    "content": "#ifndef ctags_cxx_parser_internal_h_\n#define ctags_cxx_parser_internal_h_\n/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n\n#include \"parse.h\"\n#include \"ptrarray.h\"\n\n#include \"cxx_tag.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n\n//\n// CXX parser internal declarations.\n// This file is included only by cxx_parser_*.c\n//\n\n// CXX parser language. We use a specific enum and not langType\n// since we want to be able to use it in bit fields.\ntypedef enum _CXXLanguage\n{\n\tCXXLanguageC = 1,\n\tCXXLanguageCPP = (1 << 1),\n\tCXXLanguageCUDA = (1 << 2)\n} CXXLanguage;\n\n// cxx_parser_tokenizer.c\nbool cxxParserParseNextToken(void);\nvoid cxxParserUngetCurrentToken(void);\n\n// cxx_parser_lambda.c\nCXXToken * cxxParserOpeningBracketIsLambda(void);\nbool cxxParserHandleLambda(CXXToken * pParenthesis);\n\n// cxx_parser_block.c\nbool cxxParserParseBlock(bool bExpectClosingBracket);\nbool cxxParserParseBlockHandleOpeningBracket(void);\n\nenum CXXExtractVariableDeclarationsFlags\n{\n\t// We are parsing K&R style parameter declarations.\n\tCXXExtractVariableDeclarationsKnRStyleParameters = 1\n};\n\n// cxx_parser_variable.c\nbool cxxParserExtractVariableDeclarations(\n\t\tCXXTokenChain * pChain,\n\t\tunsigned int uFlags\n\t);\n\nCXXToken * cxxParserFindFirstPossiblyNestedAndQualifiedIdentifier(\n\t\tCXXTokenChain * pChain,\n\t\tCXXTokenChain ** pParentChain\n\t);\n\n// cxx_parser_function.c\n\nbool cxxParserTokenChainLooksLikeFunctionCallParameterSet(\n\t\tCXXTokenChain * pChain\n\t);\nbool cxxParserTokenChainLooksLikeConstructorParameterSet(\n\t\tCXXTokenChain * pChain\n\t);\n\ntypedef enum _CXXFunctionSignatureInfoFlag\n{\n\t// Followed by = 0\n\tCXXFunctionSignatureInfoPure = 1,\n\t// Followed by = default\n\tCXXFunctionSignatureInfoDefault = (1 << 1),\n\t// Followed by \"override\"\n\tCXXFunctionSignatureInfoOverride = (1 << 2),\n\t// Followed by \"final\"\n\tCXXFunctionSignatureInfoFinal = (1 << 3),\n\t// Followed by = delete\n\tCXXFunctionSignatureInfoDelete = (1 << 4),\n\t// Followed by volatile\n\tCXXFunctionSignatureInfoVolatile = (1 << 5),\n\t// Is template specialization  a<x>()\n\tCXXFunctionSignatureInfoTemplateSpecialization = (1 << 6),\n\t// Is scope template specialization a<x>::b()\n\t// (implies that this is a template specialization too)\n\tCXXFunctionSignatureInfoScopeTemplateSpecialization = (1 << 7),\n\t// function-try-block: int f() try { ... } catch { ... }\n\tCXXFunctionSignatureInfoFunctionTryBlock = (1 << 8),\n} CXXFunctionSignatureInfoFlag;\n\n//\n// Description of a function signature.\n//\ntypedef struct _CXXFunctionSignatureInfo\n{\n\t// The parenthesis token.\n\t// It is always contained in the chain pointed by pParenthesisContainerChain\n\tCXXToken * pParenthesis;\n\n\t// The token chain that contains the parenthesis above. May or may not\n\t// be the toplevel chain.\n\tCXXTokenChain * pParenthesisContainerChain;\n\n\t// The identifier. It's either a single token (so both pIdentifierStart\n\t// and pIdentifierEnd point to the same token) or multiple tokens starting\n\t// with the \"operator\" keyword. Spacing of the tokens is adjusted.\n\t// The identifier is always contained in the chain pointed by pIdentifierChain.\n\tCXXToken * pIdentifierStart;\n\tCXXToken * pIdentifierEnd;\n\n\t// The chain that pIdentifierStart, pIdentifierEnd and pScopeStart\n\t// belong to. It MAY be a nested chain and it may even be included in the\n\t// range specified by pTypeStart / pTypeEnd below!\n\tCXXTokenChain * pIdentifierChain;\n\n\t// Non-NULL if the signature is followed by the \"const\" keyword\n\tCXXToken * pSignatureConst;\n\n\t// Non-NULL if there is a scope before the identifier.\n\t// The scope ends at pIdentifierStart.\n\t// The scope start is always in the chain pointed by pIdentifierChain.\n\tCXXToken * pScopeStart;\n\n\t// Non-NULL if a return type has been identified.\n\tCXXToken * pTypeStart;\n\tCXXToken * pTypeEnd;\n\t// There are cases in that the type range defined above may\n\t// contain the identifier, scope and signature ranges.\n\t// This happens, for example, with functions returning\n\t// nasty things, like:\n\t//     int (*foo(void))[2]\n\t// It is granted that the scope and identifier are either\n\t// completely included or completely excluded from the type range.\n\tbool bTypeContainsIdentifierScopeAndSignature;\n\n\t// Non-NULL if there is a trailing comma after the function.\n\t// This is used for the special case of multiple prototypes in a single\n\t// declaration:\n\t//     RetType functionA(...), functionB(...);\n\tCXXToken * pTrailingComma;\n\n\t// Template specialization token range, if any.\n\tCXXToken * pTemplateSpecializationStart;\n\tCXXToken * pTemplateSpecializationEnd;\n\n\t// Additional informations\n\tunsigned int uFlags;\n\n} CXXFunctionSignatureInfo;\n\nint cxxParserMaybeParseKnRStyleFunctionDefinition(void);\nint cxxParserExtractFunctionSignatureBeforeOpeningBracket(\n\t\tCXXFunctionSignatureInfo * pInfo,\n\t\tint * piCorkQueueIndex,\n\t\tint * piCorkQueueIndexFQ\n\t);\n\n/* This must be smaller than (sizeof(unsigned int) * 8).\n * See CXXTypedVariableSet::uAnonymous. */\n#define CXX_TYPED_VARIABLE_SET_ITEM_COUNT 24\n\ntypedef struct _CXXTypedVariableSet\n{\n\t// The number of parameters found\n\tunsigned int uCount;\n\n\t// All the tokens are references to the source chain (do not delete)\n\tCXXTokenChain * pChain;\n\t// The initial tokens of the type\n\tCXXToken * aTypeStarts[CXX_TYPED_VARIABLE_SET_ITEM_COUNT];\n\t// The final tokens of the type\n\tCXXToken * aTypeEnds[CXX_TYPED_VARIABLE_SET_ITEM_COUNT];\n\t// The identifier tokens\n\tCXXToken * aIdentifiers[CXX_TYPED_VARIABLE_SET_ITEM_COUNT];\n\n\tunsigned int uAnonymous;\n} CXXTypedVariableSet;\n\nbool cxxParserTokenChainLooksLikeFunctionParameterList(\n\t\tCXXTokenChain * tc,\n\t\tCXXTypedVariableSet * pParamInfo\n\t);\nbool cxxParserLookForFunctionSignature(\n\t\tCXXTokenChain * pChain,\n\t\tCXXFunctionSignatureInfo * pInfo,\n\t\tCXXTypedVariableSet * pParamInfo\n\t);\n\nenum CXXEmitFunctionTagsOptions\n{\n\t// Push the scopes defined by the function\n\tCXXEmitFunctionTagsPushScopes = 1\n};\n\nint cxxParserEmitFunctionTags(\n\t\tCXXFunctionSignatureInfo * pInfo,\n\t\tunsigned int uTagKind,\n\t\tunsigned int uOptions,\n\t\tint * piCorkQueueIndex,\n\t\tint * piCorkQueueIndexFQ\n\t);\n\nvoid cxxParserEmitFunctionParameterTags(CXXTypedVariableSet * pInfo);\n\n// cxx_parser_typedef.c\nbool cxxParserParseGenericTypedef(void);\nvoid cxxParserExtractTypedef(\n\t\tCXXTokenChain * pChain,\n\t\tbool bExpectTerminatorAtEnd,\n\t\tbool bGotTemplate\n\t);\n\n// cxx_parser_namespace.c\nbool cxxParserParseNamespace(void);\n\n// cxx_parser_module.c\nbool cxxParserParseModule(void);\nbool cxxParserParseImport(void);\nvoid cxxParserDestroyCurrentModuleToken(void);\n\n// cxx_parser.c\nvoid cxxParserNewStatementFull(bool bExported);\nvoid cxxParserNewStatement(void);\nbool cxxParserSkipToSemicolonOrEOF(void);\nbool cxxParserParseToEndOfQualifedName(void);\nbool cxxParserParseEnum(void);\nbool cxxParserParseClassStructOrUnion(\n\t\tCXXKeyword eKeyword,\n\t\tunsigned int uTagKind,\n\t\tunsigned int uScopeType\n\t);\nbool cxxParserParseAndCondenseCurrentSubchain(\n\t\tunsigned int uInitialSubchainMarkerTypes,\n\t\tbool bAcceptEOF,\n\t\tbool bCanReduceInnerElements\n\t);\nbool cxxParserParseUpToOneOf(unsigned int uTokenTypes,\n\t\t\t\t\t\t\t bool bCanReduceInnerElements);\nbool cxxParserParseIfForWhileSwitchCatchParenthesis(void);\nbool cxxParserParseTemplatePrefix(void);\nCXXTokenChain * cxxParserParseTemplateAngleBracketsToSeparateChain(bool bCaptureTypeParameters);\nbool cxxParserParseTemplateAngleBracketsToTemplateChain(void);\nvoid cxxParserEmitTemplateParameterTags(void);\nbool cxxParserParseUsingClause(void);\nbool cxxParserParseAccessSpecifier(void);\nvoid cxxParserAnalyzeOtherStatement(void);\nbool cxxParserParseAndCondenseSubchainsUpToOneOf(\n\t\tunsigned int uTokenTypes,\n\t\tunsigned int uInitialSubchainMarkerTypes,\n\t\tbool bCanReduceInnerElements\n\t);\nvoid cxxParserMarkEndLineForTagInCorkQueue(int iCorkQueueIndex);\nvoid cxxParserSetEndLineForTagInCorkQueue(int iCorkQueueIndex,unsigned long lEndLine);\n\ntypedef enum _CXXParserKeywordState\n{\n\t// We are parsing a statement that comes right after\n\t// a typedef keyword (so we're parsing the type being typedef'd).\n\tCXXParserKeywordStateSeenTypedef = 1,\n\t// We are parsing a statement that comes right after\n\t// an inline keyword\n\tCXXParserKeywordStateSeenInline = (1 << 1),\n\t// We are parsing a statement that comes right after\n\t// an extern keyword\n\tCXXParserKeywordStateSeenExtern = (1 << 2),\n\t// We are parsing a statement that comes right after\n\t// a static keyword\n\tCXXParserKeywordStateSeenStatic = (1 << 3),\n\t// an \"explicit\" keyword has been seen\n\tCXXParserKeywordStateSeenExplicit = (1 << 4),\n\t// an \"operator\" keyword has been seen\n\tCXXParserKeywordStateSeenOperator = (1 << 5),\n\t// \"virtual\" has been seen\n\tCXXParserKeywordStateSeenVirtual = (1 << 6),\n\t// \"return\" has been seen\n\tCXXParserKeywordStateSeenReturn = (1 << 7),\n\t// \"mutable\" has been seen\n\tCXXParserKeywordStateSeenMutable = (1 << 8),\n\t// \"const\" has been seen at block level\n\tCXXParserKeywordStateSeenConst = (1 << 9),\n\t// \"volatile\" has been seen at block level\n\tCXXParserKeywordStateSeenVolatile = (1 << 10),\n\t// __attribute__((deprecated)) has been seen\n\tCXXParserKeywordStateSeenAttributeDeprecated = (1 << 11),\n\t// \"friend\" has been seen at block level\n\tCXXParserKeywordStateSeenFriend = (1 << 12),\n\t// \"constexpr\" has been seen\n\tCXXParserKeywordStateSeenConstexpr = (1 << 13),\n\t// \"consteval\" has been seen\n\tCXXParserKeywordStateSeenConsteval = (1 << 14),\n\t// \"constinit\" has been seen\n\tCXXParserKeywordStateSeenConstinit = (1 << 15),\n\t// \"thread_local\" has been seen\n\tCXXParserKeywordStateSeenThreadLocal = (1 << 16),\n\t// \"export\" has been seen\n\tCXXParserKeywordStateSeenExport = (1 << 17),\n} CXXParserKeywordState;\n\n#define CXX_PARSER_MAXIMUM_NESTING_LEVELS 1024\n\ntypedef struct _CXXParserState\n{\n\t// The current language\n\tCXXLanguage eLanguage;\n\n\t// The current language as langType\n\tlangType eLangType;\n\n\t// The identifier of the CPP language, as indicated by ctags core\n\tlangType eCPPLangType;\n\t// The identifier of the C language, as indicated by ctags core\n\tlangType eCLangType;\n\t// The identifier of the CUDA language, as indicated by ctags core\n\tlangType eCUDALangType;\n\n\t// The kind options associated to the current language\n\tkindDefinition * pKindDefinitions;\n\t// The number of kind options, used mainly for checking/debug purposes\n\tunsigned int uKindDefinitionCount;\n\n\t// The fields associated to the current language\n\tfieldDefinition * pFieldOptions;\n\t// The number of field options, used mainly for checking/debug purposes\n\tunsigned int uFieldOptionCount;\n\n\t// The current token chain\n\tCXXTokenChain * pTokenChain;\n\n\t// The last template token chain we found\n\t// This remains valid within the statement, so it can be used slightly\n\t// after the template has been parsed (i.e. in the class coming after)\n\tCXXTokenChain * pTemplateTokenChain;\n\n\t// The last template specialization token chain we found. May be null.\n\t// This pointer, if non null, is valid only if pTemplateTokenChain is non null.\n\tCXXTokenChain * pTemplateSpecializationTokenChain;\n\n\t// The array of CXXToken objects that are found to be template\n\t// type parameters and belong to the pTemplateTokenChain above.\n\t// The validity of this array is tied to the validity of\n\t// pTemplateTokenChain above. If there is no pTemplateTokenChain\n\t// then this array is simply invalid (even if not empty)\n\tCXXTypedVariableSet oTemplateParameters;\n\n\t// The last token we have extracted. This is always pushed to\n\t// the token chain tail (which will take care of deletion)\n\tCXXToken * pToken; // the token chain tail\n\n\t// The parser internally supports a look-ahead of one token.\n\t// It is rarely needed though.\n\t// This is the token that has been \"unget\" from the token chain tail.\n\tCXXToken * pUngetToken;\n\n\t// The last char we have extracted from input\n\tint iChar;\n\n\t// Toplevel keyword state. A combination of CXXParserKeywordState flags.\n\t// Please note that the keywords appearing inside a () subchain are NOT marked.\n\tunsigned int uKeywordState;\n\n\t// This is set to true when we're parsing a *.cpp file (cpp extension!)\n\t// or we're parsing a header but we have encountered valid C++ constructs that\n\t// definitely confirm we're parsing C++.\n\tbool bConfirmedCPPLanguage;\n\n\t// The nesting levels our parser is in.\n\t//\n\t// Note that this is really a kind-of arbitrary measure as the counter\n\t// is increased in certain parser code paths that often lead to recursion.\n\t// It does not necessairly match the real number of stack frames or nested\n\t// brackets/parentheses in the input.\n\t//\n\t// The counter is used to avoid stack overflow when nesting grows too much.\n\t// This usually happens only with erroneous macro usage or broken input.\n\tint iNestingLevels;\n\n\t// The parser parsers CXX11Attribute ([[...]]).\n\t// The function parsing CXX11Attribute doesn't consider\n\t// CXX11Attributes nest like: [[[]]].\n\t// bInCXX11Attribute guards the function being called recursively.\n\tbool bInCXX11Attribute;\n\n} CXXParserState;\n\n\n// defined in cxx_parser.c\nextern CXXParserState g_cxx;\n\n#define cxxParserCurrentLanguageIs(_eLanguage) \\\n\t(g_cxx.eLanguage == _eLanguage)\n\n#define cxxParserCurrentLanguageIsOneOf(_eLanguageMask) \\\n\t(((int)(g_cxx.eLanguage)) & (_eLanguageMask))\n\n#define cxxParserCurrentLanguageIsCPP() \\\n\tcxxParserCurrentLanguageIs(CXXLanguageCPP)\n\n#define cxxParserCurrentLanguageIsC() \\\n\tcxxParserCurrentLanguageIs(CXXLanguageC)\n\n#define cxxParserCurrentLanguageIsCUDA() \\\n\tcxxParserCurrentLanguageIs(CXXLanguageCUDA)\n\n#endif //!ctags_cxx_parser_internal_h_\n"
  },
  {
    "path": "parsers/cxx/cxx_parser_lambda.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_scope.h\"\n#include \"cxx_tag.h\"\n\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"../x-cpreprocessor.h\"\n#include \"debug.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n\n#include <string.h>\n\n//\n// This has to be called when pointing at an opening bracket.\n// Returns NULL if it does not look to be a lambda invocation.\n// Otherwise it returns the parameter parenthesis token or the\n// capture list square parenthesis token if the lambda is\n// parameterless.\n//\nCXXToken * cxxParserOpeningBracketIsLambda(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\t// Lambda syntax variants:\n\t//\n\t// 1) [ capture-list ] ( params ) mutable(opt) exception attr -> ret { body }\n\t// 2) [ capture-list ] ( params ) -> ret { body }\n\t// 3) [ capture-list ] ( params ) { body }\n\t// 4) [ capture-list ] { body }\n\n\t// Similar, but not lambda:\n\t//\n\t// 5) type var[] { ... }\n\t// 6) operator [] ( params ) { ... }\n\n\tCXX_DEBUG_ASSERT(cxxParserCurrentLanguageIsCPP(),\"C++ only\");\n\n\tCXXToken * t = g_cxx.pToken->pPrev;\n\n\tif(!t)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Not a lambda: no token before bracket\");\n\t\treturn NULL; // not a lambda\n\t}\n\n\t// Check simple cases first\n\n\t// case 4?\n\tif(cxxTokenTypeIs(t,CXXTokenTypeSquareParenthesisChain))\n\t{\n\t\tif(\n\t\t\tt->pPrev &&\n\t\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeIdentifier)\n\t\t)\n\t\t{\n\t\t\t// case 5\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Not a lambda: looks like type var[] { ... }\");\n\t\t\treturn NULL;\n\t\t}\n\n\t\t// very likely parameterless lambda\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Likely a parameterless lambda\");\n\t\treturn t;\n\t}\n\n\t// case 3?\n\tif(cxxTokenTypeIs(t,CXXTokenTypeParenthesisChain))\n\t{\n\t\tt = t->pPrev;\n\t\tif(!t)\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Not a lambda: nothing before ()\");\n\t\t\treturn NULL; // can't be\n\t\t}\n\n\t\tif(!cxxTokenTypeIs(t,CXXTokenTypeSquareParenthesisChain))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Not a lambda: no [] before ()\");\n\t\t\treturn NULL; // can't be\n\t\t}\n\n\t\tif(\n\t\t\tt->pPrev &&\n\t\t\t// namely: operator [], operator new[], operator delete[]\n\t\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeKeyword)\n\t\t)\n\t\t{\n\t\t\t// case 6\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Not a lambda: keyword before []\");\n\t\t\treturn NULL;\n\t\t}\n\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Looks like a lambda with parameters\");\n\t\treturn t->pNext;\n\t}\n\n\t// Handle the harder cases.\n\t// Look backwards for the square parenthesis chain, but stop at\n\t// tokens that shouldn't be present between the bracket and the\n\t// parenthesis.\n\tt = cxxTokenChainPreviousTokenOfType(\n\t\t\tt,\n\t\t\tCXXTokenTypeSquareParenthesisChain |\n\t\t\tCXXTokenTypeBracketChain |\n\t\t\tCXXTokenTypeAssignment |\n\t\t\tCXXTokenTypeOperator\n\t\t);\n\n\tif(!t)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Not a lambda: no []\");\n\t\treturn NULL;\n\t}\n\n\tif(!cxxTokenTypeIs(t,CXXTokenTypeSquareParenthesisChain))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Not a lambda: no [] before assignment or operator\");\n\t\treturn NULL;\n\t}\n\n\tif(\n\t\tt->pPrev &&\n\t\t// namely: operator [], operator new[], operator delete[]\n\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeKeyword)\n\t)\n\t{\n\t\t// case 6\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Not a lambda: keyword before []\");\n\t\treturn NULL;\n\t}\n\n\tt = t->pNext;\n\n\tif(cxxTokenTypeIs(t,CXXTokenTypeParenthesisChain))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Looks like a lambda (got () after [])\");\n\t\treturn t;\n\t}\n\n\tCXX_DEBUG_LEAVE_TEXT(\"Not a lambda: no () after []\");\n\treturn NULL;\n}\n\n// In case of a parameterless lambda (that has no parenthesis) the parameter\n// is the capture list token.\nbool cxxParserHandleLambda(CXXToken * pParenthesis)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(cxxParserCurrentLanguageIsCPP(),\"C++ only\");\n\n\tCXXToken * pIdentifier = cxxTokenCreateAnonymousIdentifier(CXXTagKindFUNCTION, NULL);\n\n\tCXXTokenChain * pSave = g_cxx.pTokenChain;\n\tCXXTokenChain * pNew = cxxTokenChainCreate();\n\tg_cxx.pTokenChain = pNew;\n\n\ttagEntryInfo * tag = cxxTagBegin(CXXTagKindFUNCTION,pIdentifier);\n\n\tCXXToken * pAfterParenthesis = pParenthesis ? pParenthesis->pNext : NULL;\n\n\tCXXToken * pCaptureList = NULL;\n\n\tif(pParenthesis)\n\t{\n\t\tif(cxxTokenTypeIs(pParenthesis,CXXTokenTypeSquareParenthesisChain))\n\t\t{\n\t\t\t// form (4) of lambda (see cxxParserOpeningBracketIsLambda()).\n\t\t\tpCaptureList = pParenthesis;\n\t\t} else if(\n\t\t\tpParenthesis->pPrev &&\n\t\t\tcxxTokenTypeIs(pParenthesis->pPrev,CXXTokenTypeSquareParenthesisChain)\n\t\t)\n\t\t{\n\t\t\t// other forms of lambda (see cxxParserOpeningBracketIsLambda()).\n\t\t\tpCaptureList = pParenthesis->pPrev;\n\t\t}\n\t}\n\n\tif(\n\t\tpAfterParenthesis &&\n\t\tcxxTokenTypeIs(pAfterParenthesis,CXXTokenTypeKeyword) &&\n\t\t(pAfterParenthesis->eKeyword == CXXKeywordCONST)\n\t)\n\t\tpAfterParenthesis = pAfterParenthesis->pNext;\n\n\tCXXToken * pTypeStart = NULL;\n\tCXXToken * pTypeEnd;\n\n\tif(\n\t\t\tpAfterParenthesis &&\n\t\t\tcxxTokenTypeIs(pAfterParenthesis,CXXTokenTypePointerOperator) &&\n\t\t\tpAfterParenthesis->pNext &&\n\t\t\t!cxxTokenTypeIs(pAfterParenthesis->pNext,CXXTokenTypeOpeningBracket)\n\t\t)\n\t{\n\t\tpTypeStart = pAfterParenthesis->pNext;\n\t\tpTypeEnd = pTypeStart;\n\t\twhile(\n\t\t\t\tpTypeEnd->pNext &&\n\t\t\t\t(!cxxTokenTypeIs(pTypeEnd->pNext,CXXTokenTypeOpeningBracket))\n\t\t\t)\n\t\t\tpTypeEnd = pTypeEnd->pNext;\n\n#if 0\n\t\twhile(\n\t\t\t\t(pTypeStart != pTypeEnd) &&\n\t\t\t\tcxxTokenTypeIs(pTypeStart,CXXTokenTypeKeyword) &&\n\t\t\t\tcxxKeywordExcludeFromTypeNames(pTypeStart->eKeyword)\n\t\t\t)\n\t\t\tpTypeStart = pTypeStart->pNext;\n#endif\n\t}\n\n\tint iCorkQueueIndex = CORK_NIL;\n\tint iCorkQueueIndexFQ = CORK_NIL;\n\n\tif(tag)\n\t{\n\t\ttag->isFileScope = true;\n\n\t\tCXXToken * pTypeName;\n\n\t\tmarkTagExtraBit (tag, XTAG_ANONYMOUS);\n\n\t\tif(pTypeStart)\n\t\t\tpTypeName = cxxTagCheckAndSetTypeField(pTypeStart,pTypeEnd);\n\t\telse\n\t\t\tpTypeName = NULL;\n\n\t\tif(pCaptureList && cxxTagFieldEnabled(CXXTagCPPFieldLambdaCaptureList))\n\t\t{\n\t\t\tCXX_DEBUG_ASSERT(pCaptureList->pChain,\"The capture list must be a chain\");\n\t\t\tcxxTokenChainCondense(pCaptureList->pChain,0);\n\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\tcxxTokenChainFirst(pCaptureList->pChain),\n\t\t\t\t\t\"Condensation should have created a single token in the chain\"\n\t\t\t\t);\n\t\t\tcxxTagSetField(\n\t\t\t\t\tCXXTagCPPFieldLambdaCaptureList,\n\t\t\t\t\tvStringValue(cxxTokenChainFirst(pCaptureList->pChain)->pszWord),\n\t\t\t\t\tfalse\n\t\t\t\t);\n\t\t}\n\n\t\t// FIXME: Properties?\n\n\t\tvString * pszSignature = NULL;\n\t\tif(cxxTokenTypeIs(pParenthesis,CXXTokenTypeParenthesisChain))\n\t\t\tpszSignature = cxxTokenChainJoin(pParenthesis->pChain,NULL,0);\n\n\t\tif(pszSignature)\n\t\t\ttag->extensionFields.signature = vStringValue(pszSignature);\n\n\t\tiCorkQueueIndex = cxxTagCommit(&iCorkQueueIndexFQ);\n\t\tcxxTagUseTokenAsPartOfDefTag(iCorkQueueIndex, pIdentifier);\n\n\t\tif(pTypeName)\n\t\t\tcxxTokenDestroy(pTypeName);\n\n\t\tif(pszSignature)\n\t\t\tvStringDelete(pszSignature);\n\t}\n\n\tcxxScopePush(\n\t\t\tpIdentifier,\n\t\t\tCXXScopeTypeFunction,\n\t\t\tCXXScopeAccessUnknown\n\t\t);\n\n\tif(\n\t\tpParenthesis &&\n\t\tcxxTokenTypeIs(pParenthesis,CXXTokenTypeParenthesisChain) &&\n\t\tcxxTagKindEnabled(CXXTagKindPARAMETER)\n\t)\n\t{\n\t\tCXXTypedVariableSet oParamInfo;\n\t\tif(cxxParserTokenChainLooksLikeFunctionParameterList(\n\t\t\t\tpParenthesis->pChain,&oParamInfo\n\t\t\t))\n\t\t\tcxxParserEmitFunctionParameterTags(&oParamInfo);\n\t}\n\n\tbool bRet = cxxParserParseBlock(true);\n\n\tif(iCorkQueueIndex > CORK_NIL)\n\t{\n\t\tcxxParserMarkEndLineForTagInCorkQueue(iCorkQueueIndex);\n\t\tif(iCorkQueueIndexFQ > CORK_NIL)\n\t\t\tcxxParserMarkEndLineForTagInCorkQueue(iCorkQueueIndexFQ);\n\t}\n\n\tcxxScopePop();\n\n\tpNew = g_cxx.pTokenChain; // May have been destroyed and re-created\n\n\tg_cxx.pTokenChain = pSave;\n\tg_cxx.pToken = pSave->pTail;\n\n\t// change the type of token so following parsing code is not confused too much\n\tg_cxx.pToken->eType = CXXTokenTypeAngleBracketChain;\n\tg_cxx.pToken->pChain = pNew;\n\n\tcxxTokenChainClear(pNew);\n\n\tCXXToken * t = cxxTokenCreate();\n\tt->eType = CXXTokenTypeOpeningBracket;\n\tvStringPut (t->pszWord, '{');\n\tcxxTokenChainAppend(pNew,t);\n\n\tt = cxxTokenCreate();\n\tt->eType = CXXTokenTypeClosingBracket;\n\tvStringPut (t->pszWord, '}');\n\tcxxTokenChainAppend(pNew,t);\n\n\tCXX_DEBUG_LEAVE();\n\treturn bRet;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_parser_module.c",
    "content": "/*\n*   Copyright (c) 2024, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*\n* Reference:\n* - https://en.cppreference.com/w/cpp/language/modules\n*/\n\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_scope.h\"\n\n#include \"../x-cpreprocessor.h\"\n\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"read.h\"\n#include \"trashbox.h\"\n\nstatic CXXToken * pCurrentModuleToken;\n\nstatic void cxxParserSetCurrentModuleToken(CXXToken * pMod)\n{\n\tif (pCurrentModuleToken)\n\t\tcxxTokenDestroy(pCurrentModuleToken);\n\tpCurrentModuleToken = pMod;\n}\n\nvoid cxxParserDestroyCurrentModuleToken(void)\n{\n\tcxxParserSetCurrentModuleToken(NULL);\n}\n\n\nstatic CXXToken * cxxTokenModuleTokenCreate(CXXToken *pBegin, CXXToken *pEnd)\n{\n\tCXXToken * pRet = cxxTokenCopy(pBegin);\n\n\tif (pBegin != pEnd)\n\t{\n\t\tvString * pszRest = cxxTokenChainJoinRange(pBegin->pNext, pEnd, \"\",\n\t\t\t\t\t\t\t\t\t\t\t\t   CXXTokenChainJoinNoTrailingSpaces);\n\t\tvStringCat(pRet->pszWord, pszRest);\n\t\tvStringDelete(pszRest);\n\t}\n\n\treturn pRet;\n}\n\nbool cxxParserParseModule(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tunsigned int uProperties = 0;\n\n\tif(cxxTagFieldEnabled(CXXTagFieldProperties))\n\t{\n\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)\n\t\t\tuProperties |= CXXTagPropertyExport;\n\t}\n\n\tcxxParserNewStatement();\n\n\tif(!cxxParserParseUpToOneOf(\n\t\t\tCXXTokenTypeSemicolon | CXXTokenTypeEOF,\n\t\t\tfalse\n\t\t))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to the next ;\");\n\t\treturn false;\n\t}\n\n\tCXXToken * pFirst = cxxTokenChainFirst(g_cxx.pTokenChain);\n\tif (cxxTokenTypeIsOneOf(pFirst, CXXTokenTypeSemicolon | CXXTokenTypeEOF))\n\t{\n\t\tCXXToken * pMod = cxxTokenCreateAnonymousIdentifier(CXXTagCPPKindMODULE, \"__gmod_\");\n\t\ttagEntryInfo * tag = cxxTagBegin(CXXTagCPPKindMODULE,pMod);\n\t\tif (tag)\n\t\t\tcxxTagCommit(NULL);\n\t\tcxxTokenDestroy(pMod);\n\t}\n\telse if (cxxTokenTypeIs(pFirst, CXXTokenTypeSingleColon)\n\t\t&& pFirst->pNext && cxxTokenIsKeyword(pFirst->pNext, CXXKeywordPRIVATE))\n\t{\n\t\tCXXToken * pPart = pFirst->pNext;\n\t\tif (pCurrentModuleToken)\n\t\t{\n\t\t\tCXXToken *pMod = cxxTokenCopy(pCurrentModuleToken);\n\t\t\tcxxScopePush(pMod, CXXScopeTypeModule, CXXScopeAccessUnknown);\n\t\t}\n\n\t\ttagEntryInfo * tag = cxxTagBegin(CXXTagCPPKindPARTITION,pPart);\n\t\tif (tag)\n\t\t\tcxxTagCommit(NULL);\n\t\t/* export is never set to the private partition. */\n\n\t\tif (pCurrentModuleToken)\n\t\t\tcxxScopePop();\n\t}\n\telse if (cxxTokenTypeIs(pFirst, CXXTokenTypeIdentifier))\n\t{\n\t\tCXXToken * pModBegin = pFirst;\n\t\tCXXToken * pSep = cxxTokenChainNextTokenOfType(pModBegin,\n\t\t\t\t\t\t\t\t\t\t\t\t\t   CXXTokenTypeSingleColon\n\t\t\t\t\t\t\t\t\t\t\t\t\t   | CXXTokenTypeSemicolon\n\t\t\t\t\t\t\t\t\t\t\t\t\t   | CXXTokenTypeEOF);\n\t\tbool bHasPart = (cxxTokenTypeIs(pSep, CXXTokenTypeSingleColon)\n\t\t\t\t\t\t && pSep->pNext && cxxTokenTypeIs(pSep->pNext, CXXTokenTypeIdentifier)\n\t\t\t\t\t\t && g_cxx.pToken->pPrev && g_cxx.pToken->pPrev != pSep);\n\n\t\tCXXToken * pMod = NULL;\n\t\t{\n\t\t\tpMod = cxxTokenModuleTokenCreate(pModBegin, pSep->pPrev);\n\t\t\ttagEntryInfo * tag = cxxRefTagBegin(CXXTagCPPKindMODULE,\n\t\t\t\t\t\t\t\t\t\t\t\tbHasPart? CXXTagMODULERolePartOwner: ROLE_DEFINITION_INDEX,\n\t\t\t\t\t\t\t\t\t\t\t\tpMod);\n\t\t\tif (tag)\n\t\t\t{\n\t\t\t\tvString * pszProperties = (!bHasPart && uProperties) ? cxxTagSetProperties(uProperties) : NULL;\n\n\t\t\t\tcxxTagCommit(NULL);\n\t\t\t\tcxxParserSetCurrentModuleToken(cxxTokenCopy(pMod));\n\t\t\t\tcxxScopePush(pMod, CXXScopeTypeModule, CXXScopeAccessUnknown);\n\t\t\t\tvStringDelete(pszProperties); /* NULL is acceptable. */\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcxxParserSetCurrentModuleToken(pMod);\n\t\t\t\tpMod = NULL;\n\t\t\t}\n\t\t}\n\n\t\tif (pMod && bHasPart)\n\t\t{\n\t\t\tCXXToken * pPart = cxxTokenModuleTokenCreate(pSep->pNext, g_cxx.pToken->pPrev);\n\n\t\t\ttagEntryInfo * tag = cxxTagBegin(CXXTagCPPKindPARTITION,pPart);\n\t\t\tif (tag)\n\t\t\t{\n\t\t\t\tvString * pszProperties = uProperties ? cxxTagSetProperties(uProperties) : NULL;\n\n\t\t\t\tcxxTagCommit(NULL);\n\t\t\t\tvStringDelete(pszProperties); /* NULL is acceptable */\n\t\t\t}\n\t\t\tcxxTokenDestroy(pPart);\n\t\t}\n\n\t\tif (pMod)\n\t\t\tcxxScopePop();\n\t}\n\n\tcxxTokenChainClear(g_cxx.pTokenChain);\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\nbool cxxParserParseImport(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tunsigned int uProperties = 0;\n\n\tif(cxxTagFieldEnabled(CXXTagFieldProperties))\n\t{\n\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)\n\t\t\tuProperties |= CXXTagPropertyExport;\n\t}\n\n\tcxxParserNewStatement();\n\n\tif(!cxxParserParseUpToOneOf(\n\t\t\tCXXTokenTypeSemicolon | CXXTokenTypeEOF,\n\t\t\tfalse\n\t\t))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to the next ;\");\n\t\treturn false;\n\t}\n\n\tCXXToken *pFirst = cxxTokenChainFirst(g_cxx.pTokenChain);\n\tif (cxxTokenTypeIs(pFirst, CXXTokenTypeSmallerThanSign))\n\t{\n\t\tif (pFirst->pNext == NULL\n\t\t\t||  cxxTokenTypeIsOneOf(pFirst->pNext, CXXTokenTypeGreaterThanSign\n\t\t\t\t\t\t\t\t\t| CXXTokenTypeSemicolon\n\t\t\t\t\t\t\t\t\t| CXXTokenTypeEOF))\n\t\t{\n\t\t\tcxxTokenChainClear(g_cxx.pTokenChain);\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Cannot find > on the chain\");\n\t\t\treturn true;\n\t\t}\n\n\t\tCXXToken * pHeaderBegin = pFirst->pNext;\n\t\tCXXToken * pSep = cxxTokenChainNextTokenOfType(pHeaderBegin,\n\t\t\t\t\t\t\t\t\t\t\t\t\t   CXXTokenTypeGreaterThanSign\n\t\t\t\t\t\t\t\t\t\t\t\t\t   | CXXTokenTypeSemicolon\n\t\t\t\t\t\t\t\t\t\t\t\t\t   | CXXTokenTypeEOF);\n\t\tCXX_DEBUG_ASSERT(pSep,\"Cannot find the end of header file\");\n\t\tCXX_DEBUG_ASSERT(pSep != pHeaderBegin, \"Unexpected empty header file\");\n\n\t\tCXXToken * pHeader = cxxTokenModuleTokenCreate(pHeaderBegin, pSep->pPrev);\n\t\ttagEntryInfo * tag = cxxRefTagBegin(CXXTagKindINCLUDE,CR_HEADER_SYSTEM,pHeader);\n\t\tif (tag)\n\t\t{\n\t\t\tassignRole(tag, CXXR_HEADER_IMPORTED);\n\t\t\tif (uProperties & CXXTagPropertyExport)\n\t\t\t\tassignRole(tag, CXXR_HEADER_EXPORTED);\n\t\t\tcxxTagCommit(NULL);\n\t\t}\n\t\tcxxTokenDestroy(pHeader);\n\t}\n\telse if (cxxTokenTypeIs(pFirst, CXXTokenTypeStringConstant))\n\t{\n\t\tconst vString *pHName = cppGetLastCharOrStringContents();\n\t\tif (!pHName || vStringIsEmpty(pHName))\n\t\t{\n\t\t\tcxxTokenChainClear(g_cxx.pTokenChain);\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Empty header name\");\n\t\t\treturn true;\n\t\t}\n\n\t\tvStringCopy(pFirst->pszWord, pHName);\n\t\tCXXToken *pHeader = pFirst;\n\n\t\ttagEntryInfo * tag = cxxRefTagBegin(CXXTagKindINCLUDE,CR_HEADER_LOCAL,pHeader);\n\t\tif (tag)\n\t\t{\n\t\t\tassignRole(tag, CXXR_HEADER_IMPORTED);\n\t\t\tif (uProperties & CXXTagPropertyExport)\n\t\t\t\tassignRole(tag, CXXR_HEADER_EXPORTED);\n\t\t\tcxxTagCommit(NULL);\n\t\t}\n\t}\n\telse if (cxxTokenTypeIs(pFirst, CXXTokenTypeSingleColon))\n\t{\n\t\tCXXToken * pPartBegin = pFirst->pNext;\n\n\t\tif (pPartBegin == NULL\n\t\t\t|| pPartBegin == g_cxx.pToken\n\t\t\t|| cxxTokenTypeIsOneOf(pPartBegin, CXXTokenTypeSemicolon\n\t\t\t\t\t\t\t\t   | CXXTokenTypeEOF))\n\t\t{\n\t\t\tcxxTokenChainClear(g_cxx.pTokenChain);\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Empty partition name\");\n\t\t\treturn true;\n\t\t}\n\n\t\tCXXToken * pPart = cxxTokenModuleTokenCreate(pPartBegin, g_cxx.pToken->pPrev);\n\t\tif (pCurrentModuleToken)\n\t\t{\n\t\t\tCXXToken *pMod = cxxTokenCopy(pCurrentModuleToken);\n\t\t\tcxxScopePush(pMod, CXXScopeTypeModule, CXXScopeAccessUnknown);\n\t\t}\n\n\t\ttagEntryInfo * tag = cxxRefTagBegin(CXXTagCPPKindPARTITION,CXXTagPARTITIONRoleImported,pPart);\n\t\tif (tag)\n\t\t{\n\t\t\tvString * pszProperties = uProperties ? cxxTagSetProperties(uProperties) : NULL;\n\t\t\tcxxTagCommit(NULL);\n\t\t\tvStringDelete(pszProperties); /* NULL is acceptable. */\n\t\t}\n\t\tcxxTokenDestroy(pPart);\n\n\t\tif (pCurrentModuleToken)\n\t\t\tcxxScopePop();\n\t}\n\telse if (cxxTokenTypeIsOneOf(pFirst, CXXTokenTypeIdentifier))\n\t{\n\t\tCXXToken *pModBegin = pFirst;\n\t\tCXXToken * pSep = cxxTokenChainNextTokenOfType(pModBegin,\n\t\t\t\t\t\t\t\t\t\t\t\t\t   CXXTokenTypeSingleColon\n\t\t\t\t\t\t\t\t\t\t\t\t\t   | CXXTokenTypeSemicolon\n\t\t\t\t\t\t\t\t\t\t\t\t\t   | CXXTokenTypeEOF);\n\t\tbool bHasPart = (cxxTokenTypeIs(pSep, CXXTokenTypeSingleColon)\n\t\t\t\t\t\t && pSep->pNext && cxxTokenTypeIs(pSep->pNext, CXXTokenTypeIdentifier)\n\t\t\t\t\t\t && g_cxx.pToken->pPrev && g_cxx.pToken->pPrev != pSep);\n\n\t\tCXXToken * pMod = NULL;\n\t\t{\n\t\t\tpMod = cxxTokenModuleTokenCreate(pModBegin, pSep->pPrev);\n\t\t\ttagEntryInfo * tag = cxxRefTagBegin(CXXTagCPPKindMODULE,\n\t\t\t\t\t\t\t\t\t\t\t\tbHasPart? CXXTagMODULERolePartOwner: CXXTagMODULERoleImported,\n\t\t\t\t\t\t\t\t\t\t\t\tpMod);\n\t\t\tif (tag)\n\t\t\t{\n\t\t\t\tvString * pszProperties = (!bHasPart && uProperties) ? cxxTagSetProperties(uProperties) : NULL;\n\n\t\t\t\tcxxTagCommit(NULL);\n\t\t\t\tcxxScopePush(pMod, CXXScopeTypeModule, CXXScopeAccessUnknown);\n\t\t\t\tvStringDelete(pszProperties); /* NULL is acceptable. */\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcxxTokenDestroy(pMod);\n\t\t\t\tpMod = NULL;\n\t\t\t}\n\t\t}\n\n\t\tif (pMod && bHasPart)\n\t\t{\n\t\t\tCXXToken * pPart = cxxTokenModuleTokenCreate(pSep->pNext, g_cxx.pToken->pPrev);\n\n\t\t\ttagEntryInfo * tag = cxxRefTagBegin(CXXTagCPPKindPARTITION,\n\t\t\t\t\t\t\t\t\t\t\t\tCXXTagPARTITIONRoleImported, pPart);\n\t\t\tif (tag)\n\t\t\t{\n\t\t\t\tvString * pszProperties = uProperties ? cxxTagSetProperties(uProperties) : NULL;\n\n\t\t\t\tcxxTagCommit(NULL);\n\t\t\t\tvStringDelete(pszProperties); /* NULL is acceptable */\n\t\t\t}\n\t\t\tcxxTokenDestroy(pPart);\n\t\t}\n\n\t\tif (pMod)\n\t\t\tcxxScopePop();\n\t}\n\n\tcxxTokenChainClear(g_cxx.pTokenChain);\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_parser_namespace.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_scope.h\"\n\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"../x-cpreprocessor.h\"\n#include \"debug.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n\n\n#define MAX_NESTED_NAMESPACES 16\n\n\nbool cxxParserParseNamespace(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(cxxParserCurrentLanguageIsCPP(),\"This should be called only in C++\");\n\n\t/*\n\t\tSpec is:\n\n\t\t\tnamespace ns_name { declarations }\t(1)\n\t\t\tinline namespace ns_name { declarations }\t(2)\t(since C++11)\n\t\t\tnamespace { declarations }\t(3)\n\t\t\tnamespace name = qualified-namespace ;\t(7)\n\t\t\tnamespace ns_name::name\t{ (8)\t(since C++17)\n\n\t\tNote that the using clauses have their own parsing routine and do not end up here.\n\t*/\n\n\t// namespace <X> {\n\t// namespace <X>::<Y>::<Z> {\n\t// namespace <X>::<Y>::<Z>;\n\t// namespace <X>;\n\t// namespace;\n\n\tunsigned int uProperties = 0;\n\tbool bExported = g_cxx.uKeywordState & CXXParserKeywordStateSeenExport;\n\n\tif(cxxTagFieldEnabled(CXXTagFieldProperties))\n\t{\n\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenInline)\n\t\t\tuProperties |= CXXTagPropertyInline;\n\t\tif(bExported)\n\t\t\tuProperties |= CXXTagPropertyExport;\n\t}\n\n\tcxxParserNewStatement(); // always a new statement\n\tcppBeginStatement(); // but we're in the middle of it\n\n\tint iScopeCount = 0;\n\n\tint i;\n\n\tstruct { int leafnm, fqnm; } aCorkQueueIndices[MAX_NESTED_NAMESPACES];\n\tfor(i=0;i<MAX_NESTED_NAMESPACES;i++)\n\t{\n\t\taCorkQueueIndices[i].leafnm = CORK_NIL;\n\t\taCorkQueueIndices[i].fqnm   = CORK_NIL;\n\t}\n\n\tif(!cxxParserParseNextToken())\n\t{\n\t\t// syntax error, but we tolerate this\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Implicit EOF in cxxParserParseNextToken\");\n\t\treturn true; // EOF\n\t}\n\n\tif(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeIdentifier))\n\t{\n\t\t// OK, check next token to see what's coming after\n\n\t\tCXX_DEBUG_PRINT(\"Got identifier %s\",g_cxx.pToken->pszWord->buffer);\n\n\t\tCXXToken * pFirstIdentifier = g_cxx.pToken;\n\t\tCXXToken * pLastIdentifier = g_cxx.pToken;\n\n\t\tif(!cxxParserParseNextToken())\n\t\t{\n\t\t\t// syntax error, but we tolerate this\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF in cxxParserParseNextToken\");\n\t\t\treturn true; // EOF\n\t\t}\n\n\t\tswitch(g_cxx.pToken->eType)\n\t\t{\n\t\t\tcase CXXTokenTypeAssignment:\n\t\t\t{\n\t\t\t\t// probably namespace alias\n\t\t\t\tCXX_DEBUG_PRINT(\"Found assignment\");\n\n\t\t\t\tif(!cxxParserParseNextToken())\n\t\t\t\t{\n\t\t\t\t\t// syntax error, but we tolerate this\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF in cxxParserParseNextToken\");\n\t\t\t\t\treturn true; // EOF\n\t\t\t\t}\n\n\t\t\t\tif(!cxxTokenTypeIsOneOf(\n\t\t\t\t\t\tg_cxx.pToken,\n\t\t\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeMultipleColons\n\t\t\t\t\t))\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Some kind of syntax error here\");\n\t\t\t\t\treturn cxxParserSkipToSemicolonOrEOF();\n\t\t\t\t}\n\n\t\t\t\tCXXToken * pAlias = pFirstIdentifier;\n\t\t\t\tpFirstIdentifier = g_cxx.pToken;\n\n\t\t\t\tif(!cxxParserParseToEndOfQualifedName())\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse the aliased name\");\n\t\t\t\t\treturn cxxParserSkipToSemicolonOrEOF();\n\t\t\t\t}\n\n\t\t\t\tpLastIdentifier = g_cxx.pToken->pPrev;\n\n\t\t\t\ttagEntryInfo * tag = cxxTagBegin(CXXTagCPPKindALIAS,pAlias);\n\n\t\t\t\tif(tag)\n\t\t\t\t{\n\t\t\t\t\t// This is highly questionable but well.. it's how old ctags did, so we do.\n\t\t\t\t\ttag->isFileScope = !isInputHeaderFile() && !bExported && !cxxScopeIsExported();\n\n\t\t\t\t\tvString * pszProperties = NULL;\n\t\t\t\t\tif(uProperties)\n\t\t\t\t\t\tpszProperties = cxxTagSetProperties(uProperties);\n\n\t\t\t\t\tCXXToken * pAliasedName = cxxTokenChainExtractRange(\n\t\t\t\t\t\t\tpFirstIdentifier,\n\t\t\t\t\t\t\tpLastIdentifier,\n\t\t\t\t\t\t\tCXXTokenChainExtractRangeNoTrailingSpaces\n\t\t\t\t\t\t);\n\n\t\t\t\t\tcxxTagSetField(\n\t\t\t\t\t\t\tCXXTagCPPFieldAliasedName,\n\t\t\t\t\t\t\tvStringValue(pAliasedName->pszWord),\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t);\n\n\t\t\t\t\tcxxTagCommit(NULL);\n\n\t\t\t\t\tvStringDelete (pszProperties); /* NULL is acceptable.  */\n\t\t\t\t\tcxxTokenDestroy(pAliasedName);\n\t\t\t\t}\n\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Finished parsing namespace alias\");\n\t\t\t\treturn cxxParserSkipToSemicolonOrEOF();\n\t\t\t}\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeMultipleColons:\n\t\t\t\t// multi-namespace\n\t\t\t\tCXX_DEBUG_PRINT(\"Found multiple colons\");\n\n\t\t\t\tif(!cxxParserParseToEndOfQualifedName())\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse the namespace name\");\n\t\t\t\t\treturn cxxParserSkipToSemicolonOrEOF();\n\t\t\t\t}\n\n\t\t\t\tpLastIdentifier = g_cxx.pToken->pPrev;\n\n\t\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\t\tpFirstIdentifier != pLastIdentifier,\n\t\t\t\t\t\t\"We expected multiple identifiers here\"\n\t\t\t\t\t);\n\n\t\t\t\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket))\n\t\t\t\t{\n\t\t\t\t\tif(!cxxParserParseUpToOneOf(\n\t\t\t\t\t\t\tCXXTokenTypeOpeningBracket | CXXTokenTypeSemicolon | CXXTokenTypeEOF,\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t))\n\t\t\t\t\t{\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to an opening bracket\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket))\n\t\t\t\t\t{\n\t\t\t\t\t\t// tolerate syntax error\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found semicolon/EOF just after namespace declaration\");\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeOpeningBracket:\n\t\t\t\t// single name namespace\n\t\t\t\tCXX_DEBUG_PRINT(\"Found opening bracket\");\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeSemicolon:\n\t\t\t\t// tolerate syntax error\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found semicolon just after namespace declaration\");\n\t\t\t\treturn true;\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeIdentifier:\n\t\t\t\t// Probably some kind of macro\n\t\t\t\tif(!cxxParserParseUpToOneOf(\n\t\t\t\t\t\tCXXTokenTypeOpeningBracket | CXXTokenTypeSemicolon | CXXTokenTypeEOF,\n\t\t\t\t\t\tfalse\n\t\t\t\t\t))\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to an opening bracket\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket))\n\t\t\t\t{\n\t\t\t\t\t// tolerate syntax error\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found semicolon/EOF just after namespace declaration\");\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Some kind of syntax error here\");\n\t\t\t\treturn cxxParserSkipToSemicolonOrEOF();\n\t\t\tbreak;\n\t\t}\n\n\t\tCXX_DEBUG_ASSERT(\n\t\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket),\n\t\t\t\t\"Should have an opening bracket here!\"\n\t\t\t);\n\n\t\tCXX_DEBUG_PRINT(\"Found regular namespace start\");\n\n\t\tCXXToken * t = pFirstIdentifier;\n\n\t\twhile(t)\n\t\t{\n\t\t\ttagEntryInfo * tag = cxxTagBegin(CXXTagCPPKindNAMESPACE,t);\n\n\t\t\tif(tag)\n\t\t\t{\n\t\t\t\t// This is highly questionable but well.. it's how old ctags did, so we do.\n\t\t\t\ttag->isFileScope = !isInputHeaderFile() && !bExported && !cxxScopeIsExported();\n\n\t\t\t\tvString * pszProperties = uProperties ? cxxTagSetProperties(uProperties) : NULL;\n\n\t\t\t\tint iCorkQueueIndexFQ;\n\t\t\t\tint iCorkQueueIndex = cxxTagCommit(&iCorkQueueIndexFQ);\n\t\t\t\tif(iScopeCount < MAX_NESTED_NAMESPACES)\n\t\t\t\t{\n\t\t\t\t\taCorkQueueIndices[iScopeCount].leafnm = iCorkQueueIndex;\n\t\t\t\t\taCorkQueueIndices[iScopeCount].fqnm   = iCorkQueueIndexFQ;\n\t\t\t\t}\n\n\t\t\t\tif(pszProperties)\n\t\t\t\t\tvStringDelete(pszProperties);\n\t\t\t}\n\n\t\t\tCXXToken * pNext = (t == pLastIdentifier) ? NULL : t->pNext->pNext;\n\n\t\t\tcxxTokenChainTake(g_cxx.pTokenChain,t);\n\n\t\t\tcxxScopePushExported(\n\t\t\t\t\tt,\n\t\t\t\t\tCXXScopeTypeNamespace,\n\t\t\t\t\tCXXScopeAccessUnknown,\n\t\t\t\t\tbExported\n\t\t\t\t);\n\n\t\t\tiScopeCount++;\n\n\t\t\tt = pNext;\n\t\t}\n\n\t} else if(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket))\n\t{\n\t\t// anonymous namespace\n\t\tCXX_DEBUG_PRINT(\"Found anonymous namespace start\");\n\n\t\tCXXToken * t = cxxTokenCreateAnonymousIdentifier(CXXTagCPPKindNAMESPACE, NULL);\n\t\ttagEntryInfo * tag = cxxTagBegin(CXXTagCPPKindNAMESPACE,t);\n\t\tif(tag)\n\t\t{\n\t\t\ttag->isFileScope = !isInputHeaderFile();\n\t\t\t// We don't have to consider \"export\" keyword here because an object having\n\t\t\t// no name is not exportable.\n\n\t\t\tmarkTagExtraBit (tag, XTAG_ANONYMOUS);\n\n\t\t\tvString * pszProperties = uProperties ? cxxTagSetProperties(uProperties) : NULL;\n\n\t\t\tint iCorkQueueIndexFQ;\n\t\t\taCorkQueueIndices[0].leafnm = cxxTagCommit(&iCorkQueueIndexFQ);\n\t\t\taCorkQueueIndices[0].fqnm   = iCorkQueueIndexFQ;\n\n\t\t\tif(pszProperties)\n\t\t\t\tvStringDelete(pszProperties);\n\t\t}\n\t\tcxxScopePush(t,CXXScopeTypeNamespace,CXXScopeAccessUnknown);\n\n\t\tiScopeCount++;\n\n\t} else {\n\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Some kind of syntax error after namespace declaration\");\n\t\treturn cxxParserSkipToSemicolonOrEOF();\n\t}\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningBracket),\n\t\t\t\"Should have an opening bracket here!\"\n\t\t);\n\n\tif(!g_cxx.bConfirmedCPPLanguage)\n\t{\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Succeeded in parsing a C++ namespace: this really seems to be C++\"\n\t\t\t);\n\t\tg_cxx.bConfirmedCPPLanguage = true;\n\t}\n\n\t// Here we certainly got an opening bracket: namespace block\n\n\tif(!cxxParserParseBlock(true))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse namespace block\");\n\t\treturn false;\n\t}\n\n\twhile(iScopeCount > 0)\n\t{\n\t\tcxxScopePop();\n\t\tiScopeCount--;\n\n\t\tif(iScopeCount < MAX_NESTED_NAMESPACES)\n    {\n\t\t\tif(aCorkQueueIndices[iScopeCount].leafnm > CORK_NIL)\n\t\t\t\tcxxParserMarkEndLineForTagInCorkQueue(aCorkQueueIndices[iScopeCount].leafnm);\n\t\t\tif(aCorkQueueIndices[iScopeCount].fqnm > CORK_NIL)\n\t\t\t\tcxxParserMarkEndLineForTagInCorkQueue(aCorkQueueIndices[iScopeCount].fqnm);\n    }\n\t}\n\n\tCXX_DEBUG_LEAVE_TEXT(\"Finished parsing namespace\");\n\treturn true;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_parser_template.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_scope.h\"\n\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"../x-cpreprocessor.h\"\n#include \"debug.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n#include \"strlist.h\"\n\n#include <string.h>\n\ntypedef enum _CXXParserParseTemplateAngleBracketsResult\n{\n\t// Succeeded parsing the template angle bracket, everything looks fine\n\tCXXParserParseTemplateAngleBracketsSucceeded,\n\t// Succeeded, but the parsing was unbalanced and was terminated by an 'unexpected' condition\n\t// that detected the end of the template. If this is function has been called\n\t// from an upper template parsing level, the caller should exit too.\n\tCXXParserParseTemplateAngleBracketsFinishedPrematurely,\n\t// Failed miserably, continuing parsing is not possible\n\tCXXParserParseTemplateAngleBracketsFailed,\n\t// Failed miserably, but it may be possible to continue parsing\n\tCXXParserParseTemplateAngleBracketsFailedRecoverable\n} CXXParserParseTemplateAngleBracketsResult;\n\n\nstatic bool cxxTemplateTokenCheckIsNonTypeAndCompareWord(const CXXToken *t,void * szWord)\n{\n\t// To be non type the token must NOT be preceded by class/struct/union\n\tif(!t->pPrev)\n\t\treturn false;\n\tif(cxxTokenTypeIs(t->pPrev,CXXTokenTypeKeyword))\n\t{\n\t\tif(cxxKeywordIsTypeRefMarker(t->pPrev->eKeyword))\n\t\t\treturn false; // preceded by a type ref marker\n\n\t\t// otherwise it's probably something like \"int\"\n\t}\n\tconst char * w = (const char *)szWord;\n\treturn strcmp(vStringValue(t->pszWord),w) == 0;\n}\n\nstatic bool cxxTokenIsPresentInTemplateParametersAsNonType(CXXToken * t)\n{\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIsOneOf(t,CXXTokenTypeIdentifier),\n\t\t\t\"Token must be identifier\"\n\t\t);\n\n\tfor(unsigned int u=0;u<g_cxx.oTemplateParameters.uCount;u++)\n\t{\n\t\tif(\n\t\t\tcxxTemplateTokenCheckIsNonTypeAndCompareWord(\n\t\t\t\t\tt,\n\t\t\t\t\tvStringValue(g_cxx.oTemplateParameters.aIdentifiers[u]->pszWord)\n\t\t\t\t)\n\t\t\t)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic bool cxxTemplateTokenCheckIsTypeAndCompareWord(const CXXToken * t,void * szWord)\n{\n\t// To be non type the token must be preceded by class/struct/union\n\tif(!t->pPrev)\n\t\treturn false;\n\tif(!cxxTokenTypeIs(t->pPrev,CXXTokenTypeKeyword))\n\t\treturn false;\n\tif(!cxxKeywordIsTypeRefMarker(t->pPrev->eKeyword))\n\t\treturn false;\n\tconst char * w = (const char *)szWord;\n\treturn strcmp(vStringValue(t->pszWord),w) == 0;\n}\n\nstatic bool cxxTokenIsPresentInTemplateParametersAsType(CXXToken * t)\n{\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIsOneOf(t,CXXTokenTypeIdentifier),\n\t\t\t\"Token must be identifier\"\n\t\t);\n\n\tfor(unsigned int u=0;u<g_cxx.oTemplateParameters.uCount;u++)\n\t{\n\t\tif(\n\t\t\tcxxTemplateTokenCheckIsTypeAndCompareWord(\n\t\t\t\t\tt,\n\t\t\t\t\tvStringValue(g_cxx.oTemplateParameters.aIdentifiers[u]->pszWord)\n\t\t\t\t)\n\t\t\t)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n// Attempt to capture a template parameter that is between the\n// specified tokens. pBeforeParameter points to the first token\n// of the parameter (just after < or ,). pAfterParameter points\n// somewhere after the end of the parameter, usually to the next\n// , or > but it may happen that it points to an unbalanced >\n// because of broken input or because we screwed up parsing a bit.\nstatic void cxxParserParseTemplateAngleBracketsCaptureTypeParameter(\n\t\tCXXToken * pParameterStart,\n\t\tCXXToken * pAfterParameter\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\n\tif(g_cxx.oTemplateParameters.uCount >= CXX_TYPED_VARIABLE_SET_ITEM_COUNT)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"No space for more parameters\");\n\t\treturn;\n\t}\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tpParameterStart &&\n\t\t\tpParameterStart->pPrev &&\n\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\tpParameterStart->pPrev,\n\t\t\t\t\tCXXTokenTypeSmallerThanSign | CXXTokenTypeComma\n\t\t\t\t),\n\t\t\t\"pParameterStart should point to the parameter start\"\n\t\t);\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tpAfterParameter &&\n\t\t\tpAfterParameter->pPrev &&\n\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\tpAfterParameter,\n\t\t\t\t\tCXXTokenTypeGreaterThanSign | CXXTokenTypeComma\n\t\t\t\t),\n\t\t\t\"pAfterParameter should point after the parameter\"\n\t\t);\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tpParameterStart != pAfterParameter,\n\t\t\t\"The tokens should not be the same\"\n\t\t);\n\n\t// We're OK with:\n\t//\n\t// typename X\n\t// class X\n\t// int X\n\t// unsigned int X\n\t// typeName * X\n\t// typeName X\n\t// typeName ...X\n\t//\n\t// but not\n\t//\n\t// typename boost::enable_if...\n\t//\n\n\tif(pParameterStart->pNext == g_cxx.pToken)\n\t{\n\t\t// Only one token in the parameter. Can't be.\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Single parameter token\");\n\t\treturn;\n\t}\n\n\t// Straegy: run to the first , > or =.\n\n\tCXXToken * t = pParameterStart;\n\n\tfor(;;)\n\t{\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Token '%s' [%s]\",\n\t\t\t\tvStringValue(t->pszWord),\n\t\t\t\tcxxDebugTypeDecode(t->eType)\n\t\t\t);\n\n\t\tif(cxxTokenTypeIsOneOf(\n\t\t\t\tt,\n\t\t\t\tCXXTokenTypeComma | CXXTokenTypeGreaterThanSign |\n\t\t\t\tCXXTokenTypeAssignment\n\t\t\t))\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"Found terminator, stopping\");\n\t\t\tbreak;\n\t\t}\n\n\t\tif(!((\n\t\t\t\tcxxTokenTypeIs(t,CXXTokenTypeKeyword) &&\n\t\t\t\tcxxKeywordMayBePartOfTypeName(t->eKeyword)\n\t\t\t) || (\n\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\tt,\n\t\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeStar |\n\t\t\t\t\tCXXTokenTypeAnd | CXXTokenTypeMultipleAnds |\n\t\t\t\t\tCXXTokenTypeMultipleDots\n\t\t\t\t)\n\t\t\t)))\n\t\t{\n\t\t\t// something we don't like\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"This is something we don't like\");\n\t\t\treturn;\n\t\t}\n\n\t\tt = t->pNext;\n\t}\n\n\tif(!cxxTokenTypeIs(t->pPrev,CXXTokenTypeIdentifier))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"The previous token is not an identifier\");\n\t\treturn; // bad\n\t}\n\n\tCXX_DEBUG_PRINT(\n\t\t\t\"Adding %s to template parameters\",\n\t\t\tvStringValue(t->pPrev->pszWord)\n\t\t);\n\n\tunsigned int c = g_cxx.oTemplateParameters.uCount;\n\n\tg_cxx.oTemplateParameters.aIdentifiers[c] = t->pPrev;\n\tg_cxx.oTemplateParameters.aTypeStarts[c] = pParameterStart;\n\tg_cxx.oTemplateParameters.aTypeEnds[c] = t->pPrev->pPrev;\n\n\tg_cxx.oTemplateParameters.uCount++;\n\n\tCXX_DEBUG_LEAVE();\n}\n\n\n//\n// Parses the <parameters> part of a template specification.\n// Here we are pointing at the initial <.\n//\nstatic CXXParserParseTemplateAngleBracketsResult\ncxxParserParseTemplateAngleBracketsInternal(bool bCaptureTypeParameters,int iNestedTemplateLevel)\n{\n\tCXX_DEBUG_ENTER();\n\n\t// Here we have the big problem of <> characters which may be\n\t// template argument delimiters, less than/greater than operators,\n\t// shift left/right operators.\n\t//\n\t// A well written code will have parentheses around all the ambiguous cases.\n\t// We handle that and we permit any kind of syntax inside a parenthesis.\n\t//\n\t// Without parentheses we still try to handle the << and >> shift operator cases:\n\t// - << is always recognized as shift operator\n\t// - >> is recognized as shift unless it's non-nested. This is what C++11\n\t//   spec says and theoretically it should be also pseudo-compatible with C++03\n\t//   which treats this case as a syntax error.\n\t//\n\t// The 'less-than' and 'greater-than' operators are hopeless in the general\n\t// case: gcc is smart enough to figure them out by looking at the identifiers\n\t// around but without proper state (include headers, macro expansion, full type\n\t// database etc) we simply can't do the same. However, we try to recover if we\n\t// figure out we (or the programmer?) screwed up.\n\t// For 'greater-than' operators, the first non-nested operator is taken as the\n\t// end of the template parameter list rather than a 'greater-than' operator.\n\t// Treating non-nested operators differently is a syntax error at least since C++03\n\t// onwards according to https://en.cppreference.com/w/cpp/language/template_parameters.\n\t//\n\t// Like gcc, if this function knows identifiers in a template prefix more,\n\t// the quality of parsing becomes better.\n\t// Introducing `pslTypeParams` is the first step to know identifiers.\n\t// pslTypeParams list keeps all type parameters introduced in templated prefixes.\n\t// When deciding whether \">>\" is an end marker of template prefixes or a shift\n\t// operator, this function looks up pslTypeParams list.\n\t// If this function can find A of \"A >>\" in the list, we can say \">>\" is not an\n\t// operator.\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(cxxTokenChainLast(g_cxx.pTokenChain),CXXTokenTypeSmallerThanSign),\n\t\t\t\"We should be pointing at the opening angle bracket here\"\n\t\t);\n\n\tint iNestedAngleBracketLevel = 1;\n\n\t// This points to the token before the current parameter start: < or a comma.\n\tCXXToken * pBeforeParameterStart = g_cxx.pToken;\n\n\tfor(;;)\n\t{\n\t\t// Within parentheses everything is permitted.\n\t\tif(!cxxParserParseAndCondenseSubchainsUpToOneOf(\n\t\t\t\tCXXTokenTypeGreaterThanSign | CXXTokenTypeSmallerThanSign |\n\t\t\t\t\tCXXTokenTypeOpeningBracket | CXXTokenTypeSemicolon |\n\t\t\t\t\tCXXTokenTypeComma | CXXTokenTypeEOF | CXXTokenTypeKeyword,\n\t\t\t\tCXXTokenTypeOpeningParenthesis |\n\t\t\t\t\tCXXTokenTypeOpeningSquareParenthesis,\n\t\t\t\tfalse\n\t\t\t))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to '<>{EOF'\");\n\t\t\treturn CXXParserParseTemplateAngleBracketsFailed;\n\t\t}\n\n\t\t// note that g_cxx.pToken->pPrev here is always non null.\n\n\t\tswitch(g_cxx.pToken->eType)\n\t\t{\n\t\t\tcase CXXTokenTypeComma:\n\t\t\t\tif(\n\t\t\t\t\tbCaptureTypeParameters &&\n\t\t\t\t\t(iNestedTemplateLevel == 0) &&\n\t\t\t\t\t(iNestedAngleBracketLevel == 1) &&\n\t\t\t\t\t(pBeforeParameterStart->pNext != g_cxx.pToken)\n\t\t\t\t)\n\t\t\t\t\tcxxParserParseTemplateAngleBracketsCaptureTypeParameter(\n\t\t\t\t\t\t\tpBeforeParameterStart->pNext,\n\t\t\t\t\t\t\tg_cxx.pToken\n\t\t\t\t\t\t);\n\n\t\t\t\tif(iNestedAngleBracketLevel == 1)\n\t\t\t\t\tpBeforeParameterStart = g_cxx.pToken;\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeSmallerThanSign:\n\t\t\t{\n\t\t\t\t// blah <\n\n\t\t\t\tCXXToken * pSmallerThan = g_cxx.pToken;\n\n\t\t\t\tif(!cxxParserParseNextToken())\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Syntax error, but tolerate it at this level\");\n\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailedRecoverable;\n\t\t\t\t}\n\n\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\"< followed by token '%s' of type 0x%02x (%s)\",\n\t\t\t\t\t\tvStringValue(g_cxx.pToken->pszWord),\n\t\t\t\t\t\tg_cxx.pToken->eType,\n\t\t\t\t\t\tcxxDebugTypeDecode(g_cxx.pToken->eType)\n\t\t\t\t\t);\n\n\t\t\t\t// Check less than operator for the special conditions\n\t\t\t\t// we can be sure of:\n\t\t\t\t//    ... 1 < whatever ...\n\t\t\t\t//    ... typeParam < 1 ... where ident is a type parameter\n\t\t\t\t// The other cases can't be handled safely. We expect the user\n\t\t\t\t// to use parentheses.\n\t\t\t\tif(\n\t\t\t\t\t// ... 1 < whatever ...\n\t\t\t\t\tcxxTokenTypeIs(pSmallerThan->pPrev,CXXTokenTypeNumber) ||\n\t\t\t\t\t// ... nonTypeParam < whatever ...\n\t\t\t\t\t(\n\t\t\t\t\t\tcxxTokenTypeIsOneOf(pSmallerThan->pPrev,CXXTokenTypeIdentifier) &&\n\t\t\t\t\t\tcxxTokenIsPresentInTemplateParametersAsNonType(pSmallerThan->pPrev)\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Treating < as less-than operator\");\n\n\t\t\t\t} else {\n\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Increasing angle bracket level by one\");\n\t\t\t\t\tiNestedAngleBracketLevel++;\n\t\t\t\t}\n\n\t\t\t\tif(cxxTokenTypeIsOneOf(\n\t\t\t\t\t\tg_cxx.pToken,\n\t\t\t\t\t\tCXXTokenTypeOpeningParenthesis |\n\t\t\t\t\t\t\tCXXTokenTypeOpeningSquareParenthesis\n\t\t\t\t\t))\n\t\t\t\t{\n\t\t\t\t\t// would need to be condensed: unget and try again above\n\t\t\t\t\tcxxParserUngetCurrentToken();\n\t\t\t\t}\n\n\t\t\t\t// anything else is OK\n\t\t\t}\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeGreaterThanSign:\n\t\t\t{\n\t\t\t\t// > : is it a part of a shift operator?\n\n\t\t\t\tbool bFirstFollowedBySpace = g_cxx.pToken->bFollowedBySpace;\n\n\t\t\t\tint iGreaterThanCount = 1;\n\n\t\t\t\t// Here we skip all of the greater than signs we find\n\t\t\t\t// up to the number we need to exit the template, but at least three.\n\t\t\t\t// The minimum of three means that in the following loop we skip\n\t\t\t\t// at least two greater than signs AND at least another token.\n\n\t\t\t\tint iMaxGreaterThanCount = iNestedAngleBracketLevel;\n\t\t\t\tif(iMaxGreaterThanCount < 3)\n\t\t\t\t\tiMaxGreaterThanCount = 3;\n\n\t\t\t\twhile(iGreaterThanCount < iMaxGreaterThanCount)\n\t\t\t\t{\n\t\t\t\t\tif(!cxxParserParseNextToken())\n\t\t\t\t\t{\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Syntax error, but tolerate it at this level\");\n\t\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailedRecoverable;\n\t\t\t\t\t}\n\n\t\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\t\"> followed by token '%s' of type 0x%02x (%s)\",\n\t\t\t\t\t\t\tvStringValue(g_cxx.pToken->pszWord),\n\t\t\t\t\t\t\tg_cxx.pToken->eType,\n\t\t\t\t\t\t\tcxxDebugTypeDecode(g_cxx.pToken->eType)\n\t\t\t\t\t\t);\n\n\t\t\t\t\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeGreaterThanSign))\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tiGreaterThanCount++;\n\t\t\t\t}\n\n\t\t\t\tCXX_DEBUG_PRINT(\"Found %d greater-than signs\",iGreaterThanCount);\n\n\t\t\t\t// We do not check for the greater than operator, as it is only valid\n\t\t\t\t// inside parentheses in a template parameter list (see i#3388).\n\n\t\t\t\t// check right shift operator: a bit broader conditions\n\t\t\t\tif(\n\t\t\t\t\t(\n\t\t\t\t\t\t(!bFirstFollowedBySpace) &&\n\t\t\t\t\t\t(iGreaterThanCount == 2)\n\t\t\t\t\t) && (\n\t\t\t\t\t\t// whatever op 2 [C++03 allows this without parens]\n\t\t\t\t\t\t// whatever op (...) [C++03 allows this without parens]\n\t\t\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\t\tg_cxx.pToken,\n\t\t\t\t\t\t\t\tCXXTokenTypeNumber | CXXTokenTypeOpeningParenthesis\n\t\t\t\t\t\t\t) ||\n\t\t\t\t\t\t// whatever op nonTypeParameter [C++03 allows this without parens]\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeIdentifier) &&\n\t\t\t\t\t\t\tcxxTokenIsPresentInTemplateParametersAsNonType(g_cxx.pToken)\n\t\t\t\t\t\t) ||\n\t\t\t\t\t\t// a broader condition that kind-of-works at top level\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t// topmost template nesting level\n\t\t\t\t\t\t\t(iNestedTemplateLevel == 0) &&\n\t\t\t\t\t\t\t// Only one level of angle brackets.\n\t\t\t\t\t\t\t// This means that:\n\t\t\t\t\t\t\t// - >> has one angle bracket too much to exit the template\n\t\t\t\t\t\t\t// - we have screwed up the parsing of an opening angle bracket\n\t\t\t\t\t\t\t// In the first case it's very likely that we're over a shift\n\t\t\t\t\t\t\t// operator. In the other case we're screwed anyway.\n\t\t\t\t\t\t\t(iNestedAngleBracketLevel == 1) &&\n\t\t\t\t\t\t\t// identifier on the right that is not clearly identified as type\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeIdentifier) &&\n\t\t\t\t\t\t\t\t(!cxxTokenIsPresentInTemplateParametersAsType(g_cxx.pToken))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Treating as right shift operator\");\n\t\t\t\t\tif(cxxTokenTypeIsOneOf(g_cxx.pToken,CXXTokenTypeOpeningParenthesis))\n\t\t\t\t\t\tcxxParserUngetCurrentToken(); // needs to be condensed\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif(!cxxTokenTypeIsOneOf(g_cxx.pToken,CXXTokenTypeGreaterThanSign))\n\t\t\t\t{\n\t\t\t\t\t// The loop above stopped because of a non > token.\n\t\t\t\t\tCXX_DEBUG_ASSERT(iGreaterThanCount < iMaxGreaterThanCount,\"Bug\");\n\n\t\t\t\t\t// Handle gracefully some special cases\n\t\t\t\t\tif(\n\t\t\t\t\t\t\tcxxTokenIsNonConstantKeyword(g_cxx.pToken) ||\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeIdentifier) &&\n\t\t\t\t\t\t\t\tcxxTokenIsPresentInTemplateParametersAsType(g_cxx.pToken)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// We found something like\n\t\t\t\t\t\t//   ... > void ...\n\t\t\t\t\t\t//   ... > static ...\n\t\t\t\t\t\t//   ... > typeParameter ...\n\t\t\t\t\t\t// The part on the right of > does not seem to be a constant\n\t\t\t\t\t\t// so this is not a comparison.\n\t\t\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\t\t\"Found '> %s': assuming end of template\",\n\t\t\t\t\t\t\t\tvStringValue(g_cxx.pToken->pszWord)\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tcxxParserUngetCurrentToken();\n\n\t\t\t\t\t\tif(\n\t\t\t\t\t\t\tbCaptureTypeParameters &&\n\t\t\t\t\t\t\t(iNestedTemplateLevel == 0) &&\n\t\t\t\t\t\t\t(pBeforeParameterStart->pNext != g_cxx.pToken)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\tcxxParserParseTemplateAngleBracketsCaptureTypeParameter(\n\t\t\t\t\t\t\t\t\tpBeforeParameterStart->pNext,\n\t\t\t\t\t\t\t\t\tg_cxx.pToken\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif(iGreaterThanCount > iNestedAngleBracketLevel)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Most likely explanation:\n\t\t\t\t\t\t\t// We screwed up the parsing of the template.\n\t\t\t\t\t\t\t// However we can still attempt to emit a symbol here.\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found (broken) end of template\");\n\t\t\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsFinishedPrematurely;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found end of template\");\n\t\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsSucceeded;\n\t\t\t\t\t}\n\n\t\t\t\t\tcxxParserUngetCurrentToken();\n\t\t\t\t}\n\n\t\t\t\twhile(iGreaterThanCount > iNestedAngleBracketLevel)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Going back one >\");\n\t\t\t\t\tiGreaterThanCount--;\n\t\t\t\t\tcxxParserUngetCurrentToken();\n\t\t\t\t}\n\n\t\t\t\tCXX_DEBUG_PRINT(\"Decreasing angle bracket level by %d\",iGreaterThanCount);\n\t\t\t\tiNestedAngleBracketLevel -= iGreaterThanCount;\n\n\t\t\t\tif(iNestedAngleBracketLevel == 0)\n\t\t\t\t{\n\t\t\t\t\tif(\n\t\t\t\t\t\tbCaptureTypeParameters &&\n\t\t\t\t\t\t(iNestedTemplateLevel == 0) &&\n\t\t\t\t\t\t(pBeforeParameterStart->pNext != g_cxx.pToken)\n\t\t\t\t\t)\n\t\t\t\t\t\tcxxParserParseTemplateAngleBracketsCaptureTypeParameter(\n\t\t\t\t\t\t\t\tpBeforeParameterStart->pNext,\n\t\t\t\t\t\t\t\tg_cxx.pToken\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found end of template\");\n\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsSucceeded;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeKeyword:\n\n\t\t\t\tif(cxxTokenIsKeyword(g_cxx.pToken,CXXKeywordTEMPLATE))\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Found nested template keyword\");\n\n\t\t\t\t\t// nested nastiness.\n\t\t\t\t\tif(!cxxParserParseNextToken())\n\t\t\t\t\t{\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Syntax error, but tolerate it at this level\");\n\t\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailedRecoverable;\n\t\t\t\t\t}\n\n\t\t\t\t\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSmallerThanSign))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(!cxxTokenTypeIs(g_cxx.pToken->pPrev->pPrev,CXXTokenTypeMultipleColons))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// aaargh...\n\t\t\t\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\t\t\t\"Found unexpected token '%s' of type 0x%02x\",\n\t\t\t\t\t\t\t\t\tvStringValue(g_cxx.pToken->pszWord),\n\t\t\t\t\t\t\t\t\tg_cxx.pToken->eType\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"No smaller than sign after template keyword\");\n\t\t\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailed;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// Possibly X::template Something<Y,Z> disambiguation syntax.\n\t\t\t\t\t\t// See https://en.cppreference.com/w/cpp/language/dependent_name\n\t\t\t\t\t\t//\n\t\t\t\t\t\tCXX_DEBUG_PRINT(\"But it's not followed by a < and has leading ::\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch(\n\t\t\t\t\t\t\tcxxParserParseTemplateAngleBracketsInternal(\n\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\tiNestedTemplateLevel+1\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase CXXParserParseTemplateAngleBracketsFailed:\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Nested template parsing failed\");\n\t\t\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailed;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase CXXParserParseTemplateAngleBracketsFailedRecoverable:\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Nested template parsing recovered\");\n\t\t\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailedRecoverable;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase CXXParserParseTemplateAngleBracketsFinishedPrematurely:\n\t\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Nested template finished prematurely\");\n\t\t\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsFinishedPrematurely;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase CXXParserParseTemplateAngleBracketsSucceeded:\n\t\t\t\t\t\t\t// ok\n\t\t\t\t\t\t\tCXX_DEBUG_PRINT(\"Nested template parsing succeeded\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tCXX_DEBUG_ASSERT(false,\"Should never end up here\");\n\t\t\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailed;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// other keyword\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeEOF:\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Syntax error, but tolerate it at this level\");\n\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailedRecoverable;\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeSemicolon:\n\t\t\t\tcxxParserNewStatement();\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Broken template arguments, attempting to continue\");\n\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailedRecoverable;\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeOpeningBracket:\n\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\"Found opening bracket: either syntax error or we screwed up parsing \" \\\n\t\t\t\t\t\t\t\"the template parameters (some kind of ugly C++11 syntax?), \" \\\n\t\t\t\t\t\t\t\"but we try to recover...\"\n\t\t\t\t\t);\n\t\t\t\t// skip the whole bracketed part.\n\t\t\t\tif(!cxxParserParseUpToOneOf(CXXTokenTypeClosingBracket | CXXTokenTypeEOF, false))\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to '}EOF'\");\n\t\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailed;\n\t\t\t\t}\n\t\t\t\tcxxParserNewStatement();\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Broken template arguments recovery complete\");\n\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailedRecoverable;\n\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tCXX_DEBUG_ASSERT(false,\"Found unexpected token type 0x%02x\",g_cxx.pToken->eType);\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found unexpected token type 0x%02x\",g_cxx.pToken->eType);\n\t\t\t\treturn CXXParserParseTemplateAngleBracketsFailed;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// never reached\n\tCXX_DEBUG_LEAVE_TEXT(\"This should be never reached!\");\n\treturn CXXParserParseTemplateAngleBracketsFailed;\n}\n\n//\n// Parses the <parameters> part of a template specification.\n// Here we are pointing at the initial <.\n//\nstatic bool cxxParserParseTemplateAngleBrackets(bool bCaptureTypeParameters)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXXParserParseTemplateAngleBracketsResult r;\n\tr = cxxParserParseTemplateAngleBracketsInternal(bCaptureTypeParameters,0);\n\n\tswitch(r)\n\t{\n\t\tcase CXXParserParseTemplateAngleBracketsFailed:\n\t\t\tCXX_DEBUG_LEAVE();\n\t\t\treturn false;\n\t\tbreak;\n\t\t// TODO: We could signal failure+recovery to upper levels\n\t\t//       so the caller could take recovery actions too.\n\t\t//case CXXParserParseTemplateAngleBracketsFailedRecoverable:\n\t\t//case CXXParserParseTemplateAngleBracketsFinishedPrematurely:\n\t\t//case CXXParserParseTemplateAngleBracketsSucceeded:\n\t\tdefault:\n\t\t\tCXX_DEBUG_LEAVE();\n\t\t\treturn true;\n\t\tbreak;\n\t}\n\tCXX_DEBUG_ASSERT(false,\"Never here\");\n}\n\nCXXTokenChain * cxxParserParseTemplateAngleBracketsToSeparateChain(bool bCaptureTypeParameters)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(cxxParserCurrentLanguageIsCPP(),\"This should be called only in C++\");\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(cxxTokenChainLast(g_cxx.pTokenChain),CXXTokenTypeSmallerThanSign),\n\t\t\t\"We should be pointing at the opening angle bracket here\"\n\t\t);\n\n\tCXXTokenChain * pOut = cxxTokenChainCreate();\n\tcxxTokenChainAppend(pOut,cxxTokenChainTakeLast(g_cxx.pTokenChain));\n\n\tCXXTokenChain * pSave = g_cxx.pTokenChain;\n\tg_cxx.pTokenChain = pOut;\n\n\tbool bRet = cxxParserParseTemplateAngleBrackets(bCaptureTypeParameters);\n\n\tg_cxx.pTokenChain = pSave;\n\n\tif(!bRet)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse angle brackets\");\n\t\tcxxTokenChainDestroy(pOut);\n\t\treturn NULL;\n\t}\n\n\tCXX_DEBUG_LEAVE();\n\treturn pOut;\n}\n\n//\n// Parses the template angle brackets and puts it in g_cxx.pTemplateTokenChain.\n// Also captures he template type parameters in g_cxx.pTemplateParameters.\n//\nbool cxxParserParseTemplateAngleBracketsToTemplateChain(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tg_cxx.oTemplateParameters.uCount = 0;\n\n\tCXXTokenChain * pOut = cxxParserParseTemplateAngleBracketsToSeparateChain(true);\n\n\tif(!pOut)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse angle brackets\");\n\t\treturn false;\n\t}\n\n\tif(g_cxx.pTemplateTokenChain)\n\t\tcxxTokenChainDestroy(g_cxx.pTemplateTokenChain);\n\n\tg_cxx.pTemplateTokenChain = pOut;\n\n\tg_cxx.oTemplateParameters.pChain = pOut;\n\n\t// make sure we have no stale specializations\n\t// (note that specializations always come AFTER the main template)\n\tif(g_cxx.pTemplateSpecializationTokenChain)\n\t{\n\t\tcxxTokenChainDestroy(g_cxx.pTemplateSpecializationTokenChain);\n\t\tg_cxx.pTemplateSpecializationTokenChain = NULL;\n\t}\n\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\n//\n// Parses a template<anything> prefix.\n// The parsed template parameter definition is stored in a separate token chain.\n//\nbool cxxParserParseTemplatePrefix(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(cxxParserCurrentLanguageIsCPP(),\"This should be called only in C++\");\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(cxxTokenChainLast(g_cxx.pTokenChain),CXXTokenTypeKeyword),\n\t\t\t\"We should be pointing at the template keyword here\"\n\t\t);\n\n\tcxxTokenChainDestroyLast(g_cxx.pTokenChain); // kill the template keyword\n\n\tif(!cxxParserParseUpToOneOf(\n\t\t\tCXXTokenTypeSmallerThanSign | CXXTokenTypeEOF | CXXTokenTypeSemicolon,\n\t\t\tfalse\n\t\t))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to the < sign\");\n\t\treturn false;\n\t}\n\n\tif(cxxTokenTypeIsOneOf(g_cxx.pToken,CXXTokenTypeEOF | CXXTokenTypeSemicolon))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Found EOF or semicolon: assuming this is unparseable\");\n\t\tcxxParserNewStatement();\n\t\treturn true; // tolerate syntax error\n\t}\n\n\tbool bRet = cxxParserParseTemplateAngleBracketsToTemplateChain();\n\n\tCXX_DEBUG_LEAVE();\n\treturn bRet;\n}\n\nvoid cxxParserEmitTemplateParameterTags(void)\n{\n\tCXX_DEBUG_ASSERT(\n\t\t\tg_cxx.pTemplateTokenChain &&\n\t\t\t(g_cxx.pTemplateTokenChain->iCount > 0) &&\n\t\t\tcxxParserCurrentLanguageIsCPP() &&\n\t\t\tcxxTagKindEnabled(CXXTagCPPKindTEMPLATEPARAM),\n\t\t\t\"Template existence must be checked before calling this function\"\n\t\t);\n\n\tunsigned int c = g_cxx.oTemplateParameters.uCount;\n\n\tfor(unsigned int i=0;i<c;i++)\n\t{\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Emitting template param tag for '%s'\",\n\t\t\t\tvStringValue(g_cxx.oTemplateParameters.aIdentifiers[i]->pszWord)\n\t\t\t);\n\n\t\ttagEntryInfo * tag = cxxTagBegin(\n\t\t\t\tCXXTagCPPKindTEMPLATEPARAM,\n\t\t\t\tg_cxx.oTemplateParameters.aIdentifiers[i]\n\t\t\t);\n\n\t\tif(!tag)\n\t\t\tcontinue;\n\n\t\tCXXToken * pTypeToken = cxxTagCheckAndSetTypeField(\n\t\t\t\tg_cxx.oTemplateParameters.aTypeStarts[i],\n\t\t\t\tg_cxx.oTemplateParameters.aTypeEnds[i]\n\t\t\t);\n\n\t\tcxxTagCommit(NULL);\n\t\tif (pTypeToken)\n\t\t\tcxxTokenDestroy(pTypeToken);\n\t}\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_parser_tokenizer.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"../x-cpreprocessor.h\"\n#include \"debug.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n#include \"options.h\"\n\n#include <string.h>\n\n#define UINFO(c) (((c) < 0x80 && (c) >= 0) ? g_aCharTable[c].uType : 0)\n\nstatic void cxxParserSkipToNonWhiteSpace(void)\n{\n\twhile(cppIsspace(g_cxx.iChar))\n\t\tg_cxx.iChar = cppGetc();\n}\n\nenum CXXCharType\n{\n\t// Start of an identifier a-z A-Z _ and ~ since\n\t// it's part of the destructor name\n\tCXXCharTypeStartOfIdentifier = 1,\n\t// Part of identifier a-z a-Z 0-9 _\n\tCXXCharTypePartOfIdentifier = (1 << 1),\n\t// A decimal digit\n\tCXXCharTypeDecimalDigit = (1 << 2),\n\t// A hexadecimal digit\n\tCXXCharTypeHexadecimalDigit = (1 << 3),\n\t// Hex digits x X u U l L and .\n\tCXXCharTypeValidInNumber = (1 << 4),\n\t// A named single char token.\n\tCXXCharTypeNamedSingleCharToken = (1 << 5),\n\t// A named single or repeated char token.\n\tCXXCharTypeNamedSingleOrRepeatedCharToken = (1 << 6),\n\t// An operator (we merge them)\n\tCXXCharTypeOperator = (1 << 7),\n\t// Full custom handling. Mostly operators or brackets.\n\tCXXCharTypeCustomHandling = (1 << 8)\n};\n\ntypedef struct _CXXCharTypeData\n{\n\tunsigned int uType;\n\tunsigned int uSingleTokenType;\n\tunsigned int uMultiTokenType;\n} CXXCharTypeData;\n\n\nstatic CXXCharTypeData g_aCharTable[128] =\n{\n\t// 000 (0x00) NUL\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 001 (0x01) SOH\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 002 (0x02) STX\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 003 (0x03) ETX\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 004 (0x04) EOT\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 005 (0x05) ENQ\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 006 (0x06) ACK\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 007 (0x07) BEL\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 008 (0x08) BS\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 009 (0x09) '\\t' HT\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 010 (0x0a) '\\n' LF\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 011 (0x0b) '\\v' VT\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 012 (0x0c) FF\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 013 (0x0d) '\\r' CR\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 014 (0x0e) 'SO'\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 015 (0x0f) 'SI'\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 016 (0x10) DLE\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 017 (0x11) DC1\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 018 (0x12) DC2\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 019 (0x13) DC3\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 020 (0x14) DC4\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 021 (0x15) NAK\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 022 (0x16) SYN\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 023 (0x17) ETB\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 024 (0x18) CAN\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 025 (0x19) EM\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 026 (0x1a) SUB\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 027 (0x1b) ESC\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 028 (0x1c) FS\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 029 (0x1d) GS\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 030 (0x1e) RS\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 031 (0x1f) US\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 032 (0x20) ' '\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 033 (0x21) '!'\n\t{\n\t\tCXXCharTypeOperator,\n\t\t0 ,\n\t\t0\n\t},\n\t// 034 (0x22) '\"'\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 035 (0x23) '#'\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 036 (0x24) '$'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0,\n\t\t0\n\t},\n\t// 037 (0x25) '%'\n\t{\n\t\tCXXCharTypeOperator,\n\t\t0 ,\n\t\t0\n\t},\n\t// 038 (0x26) '&'\n\t{\n\t\tCXXCharTypeNamedSingleOrRepeatedCharToken,\n\t\tCXXTokenTypeAnd,\n\t\tCXXTokenTypeMultipleAnds\n\t},\n\t// 039 (0x27) '''\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 040 (0x28) '('\n\t{\n\t\tCXXCharTypeNamedSingleCharToken,\n\t\tCXXTokenTypeOpeningParenthesis,\n\t\t0\n\t},\n\t// 041 (0x29) ')'\n\t{\n\t\tCXXCharTypeNamedSingleCharToken,\n\t\tCXXTokenTypeClosingParenthesis,\n\t\t0\n\t},\n\t// 042 (0x2a) '*'\n\t{\n\t\tCXXCharTypeNamedSingleCharToken,\n\t\tCXXTokenTypeStar,\n\t\t0\n\t},\n\t// 043 (0x2b) '+'\n\t{\n\t\tCXXCharTypeOperator,\n\t\t0 ,\n\t\t0\n\t},\n\t// 044 (0x2c) ','\n\t{\n\t\tCXXCharTypeNamedSingleCharToken,\n\t\tCXXTokenTypeComma,\n\t\t0\n\t},\n\t// 045 (0x2d) '-'\n\t{\n\t\tCXXCharTypeOperator,\n\t\t0 ,\n\t\t0\n\t},\n\t// 046 (0x2e) '.'\n\t{\n\t\tCXXCharTypeValidInNumber | CXXCharTypeNamedSingleOrRepeatedCharToken,\n\t\tCXXTokenTypeDotOperator,\n\t\tCXXTokenTypeMultipleDots\n\t},\n\t// 047 (0x2f) '/'\n\t{\n\t\tCXXCharTypeOperator,\n\t\t0 ,\n\t\t0\n\t},\n\t// 048 (0x30) '0'\n\t{\n\t\tCXXCharTypePartOfIdentifier | CXXCharTypeDecimalDigit |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 049 (0x31) '1'\n\t{\n\t\tCXXCharTypePartOfIdentifier | CXXCharTypeDecimalDigit |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 050 (0x32) '2'\n\t{\n\t\tCXXCharTypePartOfIdentifier | CXXCharTypeDecimalDigit |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 051 (0x33) '3'\n\t{\n\t\tCXXCharTypePartOfIdentifier | CXXCharTypeDecimalDigit |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 052 (0x34) '4'\n\t{\n\t\tCXXCharTypePartOfIdentifier | CXXCharTypeDecimalDigit |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 053 (0x35) '5'\n\t{\n\t\tCXXCharTypePartOfIdentifier | CXXCharTypeDecimalDigit |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 054 (0x36) '6'\n\t{\n\t\tCXXCharTypePartOfIdentifier | CXXCharTypeDecimalDigit |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 055 (0x37) '7'\n\t{\n\t\tCXXCharTypePartOfIdentifier | CXXCharTypeDecimalDigit |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 056 (0x38) '8'\n\t{\n\t\tCXXCharTypePartOfIdentifier | CXXCharTypeDecimalDigit |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 057 (0x39) '9'\n\t{\n\t\tCXXCharTypePartOfIdentifier | CXXCharTypeDecimalDigit |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 058 (0x3a) ':'\n\t{\n\t\tCXXCharTypeNamedSingleOrRepeatedCharToken,\n\t\tCXXTokenTypeSingleColon,\n\t\tCXXTokenTypeMultipleColons\n\t},\n\t// 059 (0x3b) ';'\n\t{\n\t\tCXXCharTypeNamedSingleCharToken,\n\t\tCXXTokenTypeSemicolon,\n\t\t0\n\t},\n\t// 060 (0x3c) '<'\n\t{\n\t\tCXXCharTypeCustomHandling,\n\t\tCXXTokenTypeSmallerThanSign,\n\t\t0\n\t},\n\t// 061 (0x3d) '='\n\t{\n\t\tCXXCharTypeOperator | CXXCharTypeNamedSingleOrRepeatedCharToken,\n\t\tCXXTokenTypeAssignment,\n\t\tCXXTokenTypeOperator\n\t},\n\t// 062 (0x3e) '>' // We never merge two >>\n\t{\n\t\tCXXCharTypeNamedSingleCharToken,\n\t\tCXXTokenTypeGreaterThanSign,\n\t\t0\n\t},\n\t// 063 (0x3f) '?'\n\t{\n\t\tCXXCharTypeOperator,\n\t\t0 ,\n\t\t0\n\t},\n\t// 064 (0x40) '@'\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 065 (0x41) 'A'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 066 (0x42) 'B'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 067 (0x43) 'C'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 068 (0x44) 'D'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 069 (0x45) 'E'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 070 (0x46) 'F'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 071 (0x47) 'G'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 072 (0x48) 'H'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 073 (0x49) 'I'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 074 (0x4a) 'J'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 075 (0x4b) 'K'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 076 (0x4c) 'L'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 077 (0x4d) 'M'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 078 (0x4e) 'N'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 079 (0x4f) 'O'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 080 (0x50) 'P'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 081 (0x51) 'Q'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0,\n\t\t0\n\t},\n\t// 082 (0x52) 'R'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 083 (0x53) 'S'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 084 (0x54) 'T'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 085 (0x55) 'U'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 086 (0x56) 'V'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 087 (0x57) 'W'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 088 (0x58) 'X'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 089 (0x59) 'Y'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 090 (0x5a) 'Z'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 091 (0x5b) '['\n\t{\n\t\tCXXCharTypeCustomHandling,\n\t\tCXXTokenTypeOpeningSquareParenthesis,\n\t\t0\n\t},\n\t// 092 (0x5c) '\\'\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 093 (0x5d) ']'\n\t{\n\t\tCXXCharTypeNamedSingleCharToken,\n\t\tCXXTokenTypeClosingSquareParenthesis,\n\t\t0\n\t},\n\t// 094 (0x5e) '^'\n\t{\n\t\tCXXCharTypeOperator,\n\t\t0,\n\t\t0\n\t},\n\t// 095 (0x5f) '_'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 096 (0x60) '`'\n\t{\n\t\t0,\n\t\t0,\n\t\t0\n\t},\n\t// 097 (0x61) 'a'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0,\n\t\t0\n\t},\n\t// 098 (0x62) 'b'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 099 (0x63) 'c'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 100 (0x64) 'd'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 101 (0x65) 'e'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 102 (0x66) 'f'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeHexadecimalDigit | CXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 103 (0x67) 'g'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 104 (0x68) 'h'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 105 (0x69) 'i'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 106 (0x6a) 'j'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 107 (0x6b) 'k'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 108 (0x6c) 'l'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 109 (0x6d) 'm'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 110 (0x6e) 'n'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 111 (0x6f) 'o'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 112 (0x70) 'p'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 113 (0x71) 'q'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 114 (0x72) 'r'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 115 (0x73) 's'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 116 (0x74) 't'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 117 (0x75) 'u'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 118 (0x76) 'v'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 119 (0x77) 'w'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 120 (0x78) 'x'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier |\n\t\t\tCXXCharTypeValidInNumber,\n\t\t0 ,\n\t\t0\n\t},\n\t// 121 (0x79) 'y'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 122 (0x7a) 'z'\n\t{\n\t\tCXXCharTypeStartOfIdentifier | CXXCharTypePartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 123 (0x7b) '{'\n\t{\n\t\tCXXCharTypeNamedSingleCharToken,\n\t\tCXXTokenTypeOpeningBracket,\n\t\t0\n\t},\n\t// 124 (0x7c) '|'\n\t{\n\t\tCXXCharTypeOperator,\n\t\t0 ,\n\t\t0\n\t},\n\t// 125 (0x7d) '}'\n\t{\n\t\tCXXCharTypeNamedSingleCharToken,\n\t\tCXXTokenTypeClosingBracket,\n\t\t0\n\t},\n\t// 126 (0x7e) '~'\n\t{\n\t\tCXXCharTypeStartOfIdentifier,\n\t\t0 ,\n\t\t0\n\t},\n\t// 127 (0x7f)\n\t{ 0, 0, 0 }\n};\n\n// Parse the contents of an attribute chain.\n// The input is the innermost chain of __attribute__((...)) or [[...]]\nstatic void cxxParserAnalyzeAttributeChain(CXXTokenChain * pChain)\n{\n\tCXXToken * pToken = cxxTokenChainFirst(pChain);\n\n\twhile(pToken)\n\t{\n\t\tif(cxxTokenTypeIs(pToken,CXXTokenTypeIdentifier))\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"Analyzing attribute %s\",vStringValue(pToken->pszWord));\n\t\t\tif(\n\t\t\t\t\t(strcmp(vStringValue(pToken->pszWord),\"always_inline\") == 0) ||\n\t\t\t\t\t(strcmp(vStringValue(pToken->pszWord),\"__always_inline__\") == 0)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_PRINT(\"Found attribute 'always_inline'\");\n\t\t\t\t// assume \"inline\" has been seen.\n\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenInline;\n\t\t\t} else if(\n\t\t\t\t\t(strcmp(vStringValue(pToken->pszWord),\"deprecated\") == 0) ||\n\t\t\t\t\t(strcmp(vStringValue(pToken->pszWord),\"__deprecated__\") == 0)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_PRINT(\"Found attribute 'deprecated'\");\n\t\t\t\t// assume \"inline\" has been seen.\n\t\t\t\tg_cxx.uKeywordState |= CXXParserKeywordStateSeenAttributeDeprecated;\n\t\t\t}\n\t\t}\n\n\t\tpToken = pToken->pNext;\n\t}\n}\n\n//\n// The __attribute__((...)) sequence complicates parsing quite a lot.\n// For this reason we attempt to \"hide\" it from the rest of the parser\n// at tokenizer level. However, we will not kill it. For extracting interesting\n// information from the sequence in upper layers, attach the token chain\n// built from the sequence to the token AROUND the sequence.\n// In this function, we call the token \"attributes owner\" token.\n// CXXToken::pSideChain is the member for attaching.\n//\n// Returns false if it finds an EOF. This is an important invariant required by\n// cxxParserParseNextToken(), the only caller.\n//\nstatic bool cxxParserParseNextTokenCondenseAttribute(void)\n{\n\t// Since cxxParserParseNextToken() returns false only when it has found\n\t// an EOF, this function must do the same.\n\t// This means that any broken input must be discarded here.\n\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeKeyword) &&\n\t\t\t(cxxKeywordMayDropInTokenizer(g_cxx.pToken->eKeyword)),\n\t\t\t\"This function should be called only after we have parsed __attribute__ or __declspec\"\n\t\t);\n\n\tCXXToken * pAttrHead = cxxTokenChainTakeLast(g_cxx.pTokenChain);\n\n\t// And go ahead.\n\n\tif(!cxxParserParseNextToken())\n\t{\n\t\tcxxTokenDestroy(pAttrHead);\n\t\tCXX_DEBUG_LEAVE_TEXT(\"No next token after __attribute__\");\n\t\treturn false;\n\t}\n\n\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningParenthesis))\n\t{\n\t\tcxxTokenDestroy(pAttrHead);\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Something that is not an opening parenthesis\");\n\t\treturn true;\n\t}\n\n\t// Do NOT accept EOF as a valid terminator as it implies broken input.\n\tif(!cxxParserParseAndCondenseCurrentSubchain(\n\t\t\tCXXTokenTypeOpeningParenthesis |\n\t\t\t\tCXXTokenTypeOpeningSquareParenthesis |\n\t\t\t\tCXXTokenTypeOpeningBracket,\n\t\t\tfalse,\n\t\t\tfalse\n\t\t))\n\t{\n\t\t// Parsing and/or condensation of the subchain failed. This implies broken\n\t\t// input (mismatched parenthesis/bracket, early EOF).\n\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse subchains. The input is broken...\");\n\n\t\tcxxTokenDestroy(pAttrHead);\n\n\t\t// However our invariant (see comment at the beginning of the function)\n\t\t// forbids us to return false if we didn't find an EOF. So we attempt\n\t\t// to resume parsing anyway. If there is an EOF, cxxParserParseNextToken()\n\t\t// will report it.\n\n\t\t// Kill the token chain\n\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\n\t\treturn cxxParserParseNextToken();\n\t}\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeParenthesisChain),\n\t\t\t\"Should have a parenthesis chain as last token!\"\n\t\t);\n\n\t// Try to make sense of certain kinds of __attribute__.\n\t// the proper syntax is __attribute__(()), so look at the inner chain\n\n\tCXXToken * pInner = cxxTokenChainFirst(g_cxx.pToken->pChain);\n\tif(pInner)\n\t{\n\t\tif(pInner->pNext && cxxTokenTypeIs(pInner->pNext,CXXTokenTypeParenthesisChain))\n\t\t\tcxxParserAnalyzeAttributeChain(pInner->pNext->pChain);\n\t}\n\n\tCXXToken * pAttrArgs = cxxTokenChainTakeLast(g_cxx.pTokenChain);\n\tCXXToken * pAttrOwner = cxxTokenChainLast(g_cxx.pTokenChain);\n\n\t// And finally extract yet another token.\n\tbool bRet = cxxParserParseNextToken();\n\n\tif(pAttrOwner == NULL\n\t   || cxxTokenTypeIs(pAttrOwner, CXXTokenTypeComma)) {\n\t\t// If __attribute__ was at the beginning of the chain,\n\t\t// we cannot attach the __attribute__ side chain to\n\t\t// the previous token.\n\t\t// In that case, we attach the side chain to the\n\t\t// next token.\n\t\tpAttrOwner = g_cxx.pToken;\n\t} else {\n\t\t// Look up a previous identifier token.\n\t\tCXXToken * p = cxxTokenChainPreviousTokenOfType(pAttrOwner,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tCXXTokenTypeIdentifier);\n\t\tif(p)\n\t\t\tpAttrOwner = p;\n\t}\n\n\tif(pAttrOwner)\n\t{\n\t\tif(!pAttrOwner->pSideChain)\n\t\t\tpAttrOwner->pSideChain = cxxTokenChainCreate();\n\t\tcxxTokenChainAppend(pAttrOwner->pSideChain, pAttrHead);\n\t\tcxxTokenChainAppend(pAttrOwner->pSideChain, pAttrArgs);\n#if 0\n\t\tfprintf(stderr, \"pAttrOwner(%s#%d): \",\n\t\t\t\tpAttrOwner == g_cxx.pToken? \"next\": \"prev\",\n\t\t\t\tpAttrOwner->iLineNumber);\n\t\tCXX_DEBUG_TOKEN(pAttrOwner);\n\t\tfprintf(stderr, \"Side chain: \");\n\t\tif(pAttrOwner->pSideChain)\n\t\t\tCXX_DEBUG_CHAIN(pAttrOwner->pSideChain);\n\t\telse\n\t\t\tCXX_DEBUG_PRINT(\"NULL\\n\");\n#endif\n\t}\n\n\tCXX_DEBUG_LEAVE();\n\treturn bRet;\n}\n\n//\n// We handle the attribute [[...]] sequence introduced in c++11 in the same way\n// as __attribute__((...)). We move it out of the parser's way as it complicates parsing.\n//\n// Returns false if it finds an EOF. This is an important invariant required by\n// cxxParserParseNextToken(), the only caller.\n//\nstatic bool cxxParserParseNextTokenCondenseCXX11Attribute(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken, CXXTokenTypeOpeningSquareParenthesis),\n\t\t\t\"This function should be called only after we have parsed [\"\n\t\t);\n\n\tg_cxx.bInCXX11Attribute = true;\n\n\t// Input stream: [[...\n\t//   If the syntax is correct then this is an attribute sequence [[foo]]\n\t//\n\t// g_cxx.pToken points the first '['.\n\t// g_cxx.iChar points the second '['.\n\t//\n\t// A caller calls this function only when the second '[' is found.\n\n\tif(!cxxParserParseAndCondenseCurrentSubchain(\n\t\t\tCXXTokenTypeOpeningParenthesis |\n\t\t\t\tCXXTokenTypeOpeningSquareParenthesis |\n\t\t\t\tCXXTokenTypeOpeningBracket,\n\t\t\tfalse,\n\t\t\tfalse\n\t\t))\n\t{\n\t\t// Parsing and/or condensation of the subchain failed. This implies broken\n\t\t// input (mismatched parenthesis/bracket, early EOF).\n\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse subchains. The input is broken...\");\n\n\t\t// However our invariant\n\t\t// forbids us to return false if we didn't find an EOF. So we attempt\n\t\t// to resume parsing anyway. If there is an EOF, cxxParserParseNextToken()\n\t\t// will report it.\n\n\t\t// Kill the token chain\n\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\n\t\tg_cxx.bInCXX11Attribute = false;\n\t\treturn cxxParserParseNextToken();\n\t}\n\n\t// Now the current token should be replaced by a square parenthesis chain\n\t// that contains another square parenthesis chain.\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSquareParenthesisChain),\n\t\t\t\"Should have a parenthesis chain as last token!\"\n\t\t);\n\tCXX_DEBUG_ASSERT(\n\t\t\t// at least [ + [*] + ]\n\t\t\t(g_cxx.pToken->pChain->iCount >= 3) &&\n\t\t\tcxxTokenTypeIs(\n\t\t\t\t\tcxxTokenChainAt(g_cxx.pToken->pChain,1),\n\t\t\t\t\tCXXTokenTypeSquareParenthesisChain\n\t\t\t\t),\n\t\t\t\"Should have a nested parenthesis chain inside the last token!\"\n\t\t);\n\n\tcxxParserAnalyzeAttributeChain(\n\t\t\tcxxTokenChainAt(g_cxx.pToken->pChain,1)->pChain\n\t\t);\n\n\t// Now just kill it.\n\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\n\t// And finally extract yet another token.\n\tg_cxx.bInCXX11Attribute = false;\n\tbool bRet = cxxParserParseNextToken();\n\n\tCXX_DEBUG_LEAVE();\n\treturn bRet;\n}\n\n// A macro token was encountered and it expects a parameter list.\n// The routine has to check if there is a following parenthesis\n// and eventually skip it but it MUST NOT parse the next token\n// if it is not a parenthesis. This is because the macro token\n// may have a replacement and is that one that has to be returned\n// back to the caller from cxxParserParseNextToken().\nstatic bool cxxParserParseNextTokenSkipMacroParenthesis(CXXToken ** ppChain)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(ppChain,\"ppChain should not be null here\");\n\n\tcxxParserSkipToNonWhiteSpace();\n\n\tif(g_cxx.iChar != '(')\n\t{\n\t\t*ppChain = NULL;\n\t\tCXX_DEBUG_LEAVE_TEXT(\"No macro parenthesis\");\n\t\treturn true; // no parenthesis\n\t}\n\n\tif(!cxxParserParseNextToken())\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"No next token after ignored identifier\");\n\t\treturn false;\n\t}\n\n\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningParenthesis))\n\t{\n\t\tCXX_DEBUG_ASSERT(false,\"Should have found an open parenthesis token here!\");\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Internal error\");\n\t\treturn false;\n\t}\n\n\tif(!cxxParserParseAndCondenseCurrentSubchain(\n\t\t\tCXXTokenTypeOpeningParenthesis,\n\t\t\tfalse,\n\t\t\tfalse\n\t\t))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse and condense subchains\");\n\t\treturn false;\n\t}\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeParenthesisChain),\n\t\t\t\"Should have a parenthesis chain as last token!\"\n\t\t);\n\n\t// Now just kill the chain.\n\t*ppChain = cxxTokenChainTakeLast(g_cxx.pTokenChain);\n\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\nstatic void cxxParserParseNextTokenApplyReplacement(\n\t\tcppMacroInfo * pInfo,\n\t\tCXXToken * pParameterChainToken,\n\t\tint iMacroLineNumber,\n\t\tMIOPos oMacroFilePosition\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\n\tCXX_DEBUG_ASSERT(pInfo,\"Info must be not null\");\n\tCXX_DEBUG_ASSERT(pInfo->replacements,\"There should be a replacement\");\n\n\tif(!pInfo->hasParameterList)\n\t{\n\t\tCXX_DEBUG_ASSERT(!pParameterChainToken,\"This shouldn't have been extracted\");\n\t}\n\n\tCXXTokenChain *pParameters = NULL;\n\tptrArray *pMacroArgs = NULL;\n\n\tif(pInfo->hasParameterList && pParameterChainToken && (pParameterChainToken->pChain->iCount >= 3))\n\t{\n\t\t// kill parenthesis\n\t\tcxxTokenChainDestroyFirst(pParameterChainToken->pChain);\n\t\tcxxTokenChainDestroyLast(pParameterChainToken->pChain);\n\n\t\tpParameters = cxxTokenChainSplitOnComma(\n\t\t\t\tpParameterChainToken->pChain\n\t\t\t);\n\n\t\tpMacroArgs = ptrArrayNew(cppMacroArgDelete);\n\n\t\tCXXToken * pParam = cxxTokenChainFirst(pParameters);\n\t\twhile(pParam)\n\t\t{\n\t\t\tcppMacroArg *pArg = cppMacroArgNew(vStringValue(pParam->pszWord),\n\t\t\t\t\t\t\t\t\t\t\t   false,\n\t\t\t\t\t\t\t\t\t\t\t   pParam->iLineNumber,\n\t\t\t\t\t\t\t\t\t\t\t   pParam->oFilePosition);\n\t\t\tptrArrayAdd(pMacroArgs, pArg);\n\t\t\tpParam = pParam->pNext;\n\t\t}\n\t}\n\n\tcppMacroTokens *pMacroTokens = cppExpandMacro(pInfo, pMacroArgs,\n\t\t\t\t\t\t\t\t\t\t\t\t  (unsigned long)iMacroLineNumber,\n\t\t\t\t\t\t\t\t\t\t\t\t  oMacroFilePosition);\n\tptrArrayDelete(pMacroArgs);\t// NULL is acceptable.\n\tif(pParameters)\n\t\tcxxTokenChainDestroy(pParameters);\n\n#ifdef CXX_DO_DEBUGGING\n\t{\n\t\tvString *pReplacement = cppFlattenMacroTokensToNewString (pMacroTokens);\n\t\tCXX_DEBUG_PRINT(\"Applying complex replacement '%s'\", vStringValue(pReplacement));\n\t\tvStringDelete (pReplacement);\n\t}\n#endif\n\n\tcppUngetMacroTokens(pMacroTokens);\n\n\tCXX_DEBUG_LEAVE();\n}\n\nvoid cxxParserUngetCurrentToken(void)\n{\n\tCXX_DEBUG_ASSERT(\n\t\t\tg_cxx.pToken &&\n\t\t\tg_cxx.pTokenChain &&\n\t\t\t(g_cxx.pTokenChain->iCount > 0),\n\t\t\t\"There should be at least one token to unget\"\n\t\t);\n\n\tif(g_cxx.pUngetToken)\n\t{\n\t\tif(g_cxx.pUngetToken->bFollowedBySpace)\n\t\t\tcppUngetc(' ');\n\t\tcppUngetString(vStringValue(g_cxx.pUngetToken->pszWord),vStringLength(g_cxx.pUngetToken->pszWord));\n\t\tcxxTokenDestroy(g_cxx.pUngetToken);\n\t}\n\n\tg_cxx.pUngetToken = cxxTokenChainTakeLast(g_cxx.pTokenChain);\n\n\tCXX_DEBUG_ASSERT(g_cxx.pUngetToken == g_cxx.pToken,\"Oops.. ungot a token that was not the chain tail\");\n\n\tg_cxx.pToken = cxxTokenChainLast(g_cxx.pTokenChain);\n}\n\n\n#define CXX_PARSER_MAXIMUM_TOKEN_CHAIN_SIZE 16384\n\n// Returns false if it finds an EOF. Returns true otherwise.\n//\n// In some special cases this function may parse more than one token,\n// however only a single token will always be returned.\nbool cxxParserParseNextToken(void)\n{\n\t// The token chain should not be allowed to grow arbitrarily large.\n\t// The token structures are quite big and it's easy to grow up to\n\t// 5-6GB or memory usage. However this limit should be large enough\n\t// to accommodate all the reasonable statements that could have some\n\t// information in them. This includes multiple function prototypes\n\t// in a single statement (ImageMagick has some examples) but probably\n\t// does NOT include large data tables.\n\tint iInitialTokenChainSize = g_cxx.pTokenChain->iCount;\n\tif(iInitialTokenChainSize >= CXX_PARSER_MAXIMUM_TOKEN_CHAIN_SIZE)\n\t\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\n\tif(g_cxx.pUngetToken)\n\t{\n\t\t// got some tokens in the unget chain.\n\t\tcxxTokenChainAppend(g_cxx.pTokenChain,g_cxx.pUngetToken);\n\n\t\tg_cxx.pToken = g_cxx.pUngetToken;\n\n\t\tg_cxx.pUngetToken = NULL;\n\n\t\treturn !cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeEOF);\n\t}\n\n\tCXXToken * t = cxxTokenCreate();\n\n\tcxxTokenChainAppend(g_cxx.pTokenChain,t);\n\n\tg_cxx.pToken = t;\n\n\tcxxParserSkipToNonWhiteSpace();\n\n\t// FIXME: this cpp handling is kind of broken:\n\t// it works only because the moon is in the correct phase.\n\tcppBeginStatement();\n\n\t// This must be done after getting char from input\n\tt->iLineNumber = cppGetInputLineNumber();\n\tt->oFilePosition = cppGetInputFilePosition();\n\n\tif(g_cxx.iChar == EOF)\n\t{\n\t\tt->eType = CXXTokenTypeEOF;\n\t\tt->bFollowedBySpace = false;\n\t\treturn false;\n\t}\n\n\tunsigned int uInfo = UINFO(g_cxx.iChar);\n\n\t//fprintf(stderr,\"Char %c %02x info %u\\n\",g_cxx.iChar,g_cxx.iChar,uInfo);\n\n\tif(uInfo & CXXCharTypeStartOfIdentifier)\n\t{\n\t\t// word\n\t\tt->eType = CXXTokenTypeIdentifier;\n\t\tt->bFollowedBySpace = false;\n\n\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\n\t\t// special case for tile, which may actually be an operator\n\t\tif(g_cxx.iChar == '~')\n\t\t{\n\t\t\t// may be followed by space!\n\t\t\tg_cxx.iChar = cppGetc();\n\t\t\tif(cppIsspace(g_cxx.iChar))\n\t\t\t{\n\t\t\t\tt->bFollowedBySpace = true;\n\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\twhile(cppIsspace(g_cxx.iChar))\n\t\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t}\n\n\t\t\t// non space\n\t\t\tuInfo = UINFO(g_cxx.iChar);\n\t\t\tif(!(uInfo & CXXCharTypeStartOfIdentifier))\n\t\t\t{\n\t\t\t\t// this is not an identifier after all\n\t\t\t\tt->eType = CXXTokenTypeOperator;\n\t\t\t\tif((!t->bFollowedBySpace) && g_cxx.iChar == '=')\n\t\t\t\t{\n\t\t\t\t\t// make ~= single token so it's not handled as\n\t\t\t\t\t// a separate assignment\n\t\t\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} else {\n\t\t\tg_cxx.iChar = cppGetc();\n\t\t}\n\n\t\tfor(;;)\n\t\t{\n\t\t\tuInfo = UINFO(g_cxx.iChar);\n\t\t\tif(!(uInfo & CXXCharTypePartOfIdentifier))\n\t\t\t\tbreak;\n\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t\tg_cxx.iChar = cppGetc();\n\t\t}\n\n\t\tint iCXXKeyword = lookupKeyword(t->pszWord->buffer,g_cxx.eLangType);\n\t\tif(iCXXKeyword >= 0)\n\t\t{\n\t\t\tif(cxxKeywordIsDisabled((CXXKeyword)iCXXKeyword))\n\t\t\t{\n\t\t\t\tt->eType = CXXTokenTypeIdentifier;\n\t\t\t} else {\n\n\t\t\t\tt->eType = CXXTokenTypeKeyword;\n\t\t\t\tt->eKeyword = (CXXKeyword)iCXXKeyword;\n\n\n\t\t\t\tif(cxxKeywordMayDropInTokenizer(iCXXKeyword))\n\t\t\t\t{\n\t\t\t\t\t// special handling for __attribute__ and __declspec\n\t\t\t\t\treturn cxxParserParseNextTokenCondenseAttribute();\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\n\t\t\tcppMacroInfo * pMacro = cppFindMacro(vStringValue(t->pszWord));\n\t\t\tint iMacroLineNumber = t->iLineNumber;\n\t\t\tMIOPos oMacroFilePosition = t->oFilePosition;\n\n#ifdef DEBUG\n\t\t\tif(pMacro && (pMacro->useCount >= CPP_MAXIMUM_MACRO_USE_COUNT))\n\t\t\t{\n\t\t\t\t/* If the macro is overly used, report it here. */\n\t\t\t\tCXX_DEBUG_PRINT(\"Overly uesd macro %s <%p> useCount: %d (> %d)\",\n\t\t\t\t\t\t\t\tpMacro->name,\n\t\t\t\t\t\t\t\tpMacro, pMacro->useCount,\n\t\t\t\t\t\t\t\tCPP_MAXIMUM_MACRO_USE_COUNT);\n\t\t\t}\n#endif\n\n\t\t\tif(pMacro && (pMacro->useCount < CPP_MAXIMUM_MACRO_USE_COUNT))\n\t\t\t{\n\t\t\t\tCXX_DEBUG_PRINT(\"Macro %s <%p> useCount: %d\", pMacro->name,\n\t\t\t\t\t\t\t\tpMacro, pMacro->useCount);\n\n\t\t\t\t/* `t' is at the end of g_cxx.pTokenChain. */\n\t\t\t\tcxxTokenChainTakeLast(g_cxx.pTokenChain);\n\n\t\t\t\tCXXToken * pParameterChain = NULL;\n\n\t\t\t\tif(pMacro->hasParameterList)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Macro has parameter list\");\n\t\t\t\t\tif(!cxxParserParseNextTokenSkipMacroParenthesis(&pParameterChain)) {\n\t\t\t\t\t\tcxxTokenDestroy(t);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* The macro definition requires argument(s).\n\t\t\t\t\t * However, the parser cannot find '(' just after the macro token (`t')\n\t\t\t\t\t * on the current input stream.\n\t\t\t\t\t *\n\t\t\t\t\t * e.g.\n\t\t\t\t\t *\n\t\t\t\t\t *   // the macro definition\n\t\t\t\t\t *   -D't(x)=(x+1)'\n\t\t\t\t\t *\n\t\t\t\t\t *   // input stream\n\t\t\t\t\t *   int t;\n\t\t\t\t\t * -------^ no '('.\n\t\t\t\t\t *\n\t\t\t\t\t * In this case we should expand nothing. Just extract token `t'\n\t\t\t\t\t * as is; just append `t' to g_cxx.pTokenChain. and return the\n\t\t\t\t\t * control.\n\t\t\t\t\t */\n\t\t\t\t\tif (pParameterChain == NULL) {\n\t\t\t\t\t\tCXX_DEBUG_PRINT(\"Macro definition requires argument(s) but we cannot find them\");\n\t\t\t\t\t\tcxxTokenChainAppend(g_cxx.pTokenChain, t);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcxxTokenDestroy(t);\n\n\n\t\t\t\t// This is used to avoid infinite recursion in substitution\n\t\t\t\t// (things like -D foo=foo or similar)\n\n\t\t\t\tif(pMacro->replacements)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_PRINT(\"The token has replacements: applying\");\n\n\t\t\t\t\tif(\n\t\t\t\t\t\t// Exclude possible cases of recursive macro expansion that\n\t\t\t\t\t\t// causes level nesting\n\t\t\t\t\t\t//    -D'x=y(x)'\n\t\t\t\t\t\t(g_cxx.iNestingLevels < CXX_PARSER_MAXIMUM_NESTING_LEVELS) &&\n\t\t\t\t\t\t// Exclude possible cases of recursive macro expansion that\n\t\t\t\t\t\t// causes a single token chain to grow too big\n\t\t\t\t\t\t//    -D'x=y.x'\n\t\t\t\t\t\t(iInitialTokenChainSize < CXX_PARSER_MAXIMUM_TOKEN_CHAIN_SIZE) &&\n\t\t\t\t\t\t// Detect other cases of nasty macro expansion that cause\n\t\t\t\t\t\t// the unget buffer to grow fast (but the token chain to grow slowly)\n\t\t\t\t\t\t//    -D'p=a' -D'a=p+p'\n\t\t\t\t\t\t(cppUngetBufferSize() < CPP_MAXIMUM_UNGET_BUFFER_SIZE_FOR_MACRO_REPLACEMENTS)\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// unget last char\n\t\t\t\t\t\tcppUngetc(g_cxx.iChar);\n\t\t\t\t\t\t// unget the replacement\n\t\t\t\t\t\tcxxParserParseNextTokenApplyReplacement(\n\t\t\t\t\t\t\t\tpMacro,\n\t\t\t\t\t\t\t\tpParameterChain,\n\t\t\t\t\t\t\t\tiMacroLineNumber,\n\t\t\t\t\t\t\t\toMacroFilePosition\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Possibly a recursive macro\n\t\t\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\t\t\"Token has replacement but either nesting level is too \"\n\t\t\t\t\t\t\t\t\"big (%d), the token chain (%d) or the unget buffer (%d) \"\n\t\t\t\t\t\t\t\t\"have grown too large\",\n\t\t\t\t\t\t\t\tg_cxx.iNestingLevels,\n\t\t\t\t\t\t\t\tg_cxx.pTokenChain->iCount,\n\t\t\t\t\t\t\t\tcppUngetBufferSize()\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif(pParameterChain)\n\t\t\t\t\tcxxTokenDestroy(pParameterChain);\n\n\t\t\t\tg_cxx.iNestingLevels++;\n\t\t\t\t// Have no token to return: parse it\n\t\t\t\tCXX_DEBUG_PRINT(\"Parse inner token\");\n\t\t\t\tbool bRet = cxxParserParseNextToken();\n\t\t\t\tCXX_DEBUG_PRINT(\"Parsed inner token: %s type %d\",g_cxx.pToken->pszWord->buffer,g_cxx.pToken->eType);\n\t\t\t\tg_cxx.iNestingLevels--;\n\t\t\t\treturn bRet;\n\t\t\t}\n\t\t}\n\n\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\n\t\treturn true;\n\t}\n\n\tif(g_cxx.iChar == '-')\n\t{\n\t\t// special case for pointer\n\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\tg_cxx.iChar = cppGetc();\n\t\tif(g_cxx.iChar == '>')\n\t\t{\n\t\t\tt->eType = CXXTokenTypePointerOperator;\n\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t\tg_cxx.iChar = cppGetc();\n\t\t} else {\n\t\t\tt->eType = CXXTokenTypeOperator;\n\t\t\tif(g_cxx.iChar == '-')\n\t\t\t{\n\t\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t}\n\t\t}\n\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\treturn true;\n\t}\n\n#if 0\n\t// As long as we use cppGetc() we don't need this\n\n\tif(g_cxx.iChar == '\"')\n\t{\n\t\t// special case for strings\n\t\tt->eType = CXXTokenTypeStringConstant;\n\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t// We don't even care of storing the other chars: we don't need\n\t\t// them for parsing\n\t\t// FIXME: We might need them in signature:() tag.. maybe add\n\t\t// them up to a certain length only?\n\t\tfor(;;)\n\t\t{\n\t\t\tg_cxx.iChar = cppGetc();\n\t\t\tif(g_cxx.iChar == EOF)\n\t\t\t{\n\t\t\t\tt->bFollowedBySpace = false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(g_cxx.iChar == '\\\\')\n\t\t\t{\n\t\t\t\t// escape\n\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\tif(g_cxx.iChar == EOF)\n\t\t\t\t{\n\t\t\t\t\tt->bFollowedBySpace = false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else if(g_cxx.iChar == '\"')\n\t\t\t{\n\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\treturn true;\n\t}\n#else\n\tif(g_cxx.iChar == CPP_STRING_SYMBOL)\n\t{\n\t\tt->eType = CXXTokenTypeStringConstant;\n\t\tcppVStringPut(t->pszWord,g_cxx.iChar);\n\t\tg_cxx.iChar = cppGetc();\n\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\treturn true;\n\t}\n#endif\n\n#if 0\n\t// As long as we use cppGetc() we don't need this\n\tif(g_cxx.iChar == '\\'')\n\t{\n\t\t// special case for strings\n\t\tt->eType = CXXTokenTypeCharacterConstant;\n\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t// We don't even care storing the other chars: we don't\n\t\t// need them for parsing\n\t\tfor(;;)\n\t\t{\n\t\t\tg_cxx.iChar = cppGetc();\n\t\t\tif(g_cxx.iChar == EOF)\n\t\t\t{\n\t\t\t\tt->bFollowedBySpace = false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(g_cxx.iChar == '\\\\')\n\t\t\t{\n\t\t\t\t// escape\n\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\tif(g_cxx.iChar == EOF)\n\t\t\t\t{\n\t\t\t\t\tt->bFollowedBySpace = false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else if(g_cxx.iChar == '\\'')\n\t\t\t{\n\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\treturn true;\n\t}\n#else\n\tif(g_cxx.iChar == CPP_CHAR_SYMBOL)\n\t{\n\t\tt->eType = CXXTokenTypeCharacterConstant;\n\t\tcppVStringPut(t->pszWord,g_cxx.iChar);\n\t\tg_cxx.iChar = cppGetc();\n\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\treturn true;\n\t}\n#endif\n\n\tif(uInfo & CXXCharTypeDecimalDigit)\n\t{\n\t\t// number\n\t\tt->eType = CXXTokenTypeNumber;\n\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\n\t\tfor(;;)\n\t\t{\n\t\t\tg_cxx.iChar = cppGetc();\n\t\t\tuInfo = UINFO(g_cxx.iChar);\n\t\t\tif(!(uInfo & CXXCharTypeValidInNumber))\n\t\t\t\tbreak;\n\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t}\n\n\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\treturn true;\n\t}\n\n\tif(uInfo & CXXCharTypeNamedSingleOrRepeatedCharToken)\n\t{\n\t\tt->eType = g_aCharTable[g_cxx.iChar].uSingleTokenType;\n\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\tint iChar = g_cxx.iChar;\n\t\tg_cxx.iChar = cppGetc();\n\t\tif(g_cxx.iChar == iChar)\n\t\t{\n\t\t\tt->eType = g_aCharTable[g_cxx.iChar].uMultiTokenType;\n\t\t\t// We could signal a syntax error with more than two colons\n\t\t\t// or equal signs...but we're tolerant\n\t\t\tdo {\n\t\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t} while(g_cxx.iChar == iChar);\n\t\t}\n\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\treturn true;\n\t}\n\n\tif(uInfo & CXXCharTypeCustomHandling)\n\t{\n\t\tt->eType = g_aCharTable[g_cxx.iChar].uSingleTokenType;\n\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\tg_cxx.iChar = cppGetc();\n\t\tswitch(t->eType)\n\t\t{\n\t\t\tcase CXXTokenTypeSmallerThanSign:\n\t\t\t\t// The < sign is used in templates and is problematic if parsed incorrectly.\n\t\t\t\t// We must exctract only the valid operator types: <, <<, <<=, <= <=>\n\t\t\t\tswitch(g_cxx.iChar)\n\t\t\t\t{\n\t\t\t\t\tcase '<':\n\t\t\t\t\t\t// <<\n\t\t\t\t\t\tt->eType = CXXTokenTypeOperator;\n\t\t\t\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\t\t\tif(g_cxx.iChar == '=')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// <<=\n\t\t\t\t\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t\t\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase '=':\n\t\t\t\t\t\t// <=\n\t\t\t\t\t\tt->eType = CXXTokenTypeOperator;\n\t\t\t\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\t\t\tif(g_cxx.iChar == '>')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// <=>\n\t\t\t\t\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t\t\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// fall down\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeOpeningSquareParenthesis:\n\t\t\t\t// special handling for [[ attribute ]] which can appear almost anywhere\n\t\t\t\t// in the source code and is kind of annoying for the parser.\n\n\t\t\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\n\t\t\t\tif(t->bFollowedBySpace)\n\t\t\t\t{\n\t\t\t\t\t// The tokens can be separated by a space, at least according to gcc.\n\t\t\t\t\tdo {\n\t\t\t\t\t\tg_cxx.iChar = cppGetc();\n\t\t\t\t\t} while(cppIsspace(g_cxx.iChar));\n\t\t\t\t}\n\n\t\t\t\tif(g_cxx.iChar == '[' && !g_cxx.bInCXX11Attribute)\n\t\t\t\t\treturn cxxParserParseNextTokenCondenseCXX11Attribute();\n\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tCXX_DEBUG_ASSERT(false,\"There should be a custom handler for this token type\");\n\t\t\t\t// treat as single token type in non debug builds\n\t\t\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\t\tbreak;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tif(uInfo & CXXCharTypeNamedSingleCharToken)\n\t{\n\t\tt->eType = g_aCharTable[g_cxx.iChar].uSingleTokenType;\n\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\tg_cxx.iChar = cppGetc();\n\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\treturn true;\n\t}\n\n\tif(uInfo & CXXCharTypeOperator)\n\t{\n\t\tt->eType = CXXTokenTypeOperator;\n\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\tg_cxx.iChar = cppGetc();\n\t\tuInfo = UINFO(g_cxx.iChar);\n\t\twhile(uInfo & CXXCharTypeOperator)\n\t\t{\n\t\t\tvStringPut(t->pszWord,g_cxx.iChar);\n\t\t\tg_cxx.iChar = cppGetc();\n\t\t\tuInfo = UINFO(g_cxx.iChar);\n\t\t}\n\t\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\t\treturn true;\n\t}\n\n\tt->eType = CXXTokenTypeUnknown;\n\tcppVStringPut(t->pszWord,g_cxx.iChar);\n\tg_cxx.iChar = cppGetc();\n\tt->bFollowedBySpace = cppIsspace(g_cxx.iChar);\n\n\treturn true;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_parser_typedef.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_scope.h\"\n\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"debug.h\"\n#include \"read.h\"\n\n//\n// This is used to pre-parse non struct/class/union/enum typedefs.\n// Please note that struct/class/union/enum has its own pre-parsing routine.\n//\nbool cxxParserParseGenericTypedef(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tfor(;;)\n\t{\n\t\tif(!cxxParserParseUpToOneOf(\n\t\t\t\tCXXTokenTypeSemicolon | CXXTokenTypeEOF |\n\t\t\t\tCXXTokenTypeClosingBracket | CXXTokenTypeKeyword,\n\t\t\t\tfalse\n\t\t\t))\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse fast statement\");\n\t\t\treturn false;\n\t\t}\n\n\t\t// This fixes bug reported by Emil Rojas in 2002.\n\t\t// Though it's quite debatable if we really *should* do this.\n\t\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeKeyword))\n\t\t{\n\t\t\t// not a keyword\n\t\t\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSemicolon))\n\t\t\t{\n\t\t\t\t// not semicolon\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found EOF/closing bracket at typedef\");\n\t\t\t\treturn true; // EOF\n\t\t\t}\n\t\t\t// semicolon: exit\n\t\t\tbreak;\n\t\t}\n\n\t\t// keyword\n\t\tif(\n\t\t\t(g_cxx.pToken->eKeyword == CXXKeywordEXTERN) ||\n\t\t\t(g_cxx.pToken->eKeyword == CXXKeywordTYPEDEF) ||\n\t\t\t(g_cxx.pToken->eKeyword == CXXKeywordSTATIC)\n\t\t)\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found a terminating keyword inside typedef\");\n\t\t\treturn true; // treat as semicolon but don't dare to emit a tag\n\t\t}\n\t}\n\n\tcxxParserExtractTypedef(g_cxx.pTokenChain,true,false);\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\n//\n// This function attempts to extract a typedef from the\n// specified chain.\n// The typedef keyword should already have been removed (!)\n// The function expects a terminator to be present at the end\n// unless bExpectTerminatorAtEnd is set to false\n// The token chain may be condensed/destroyed upon exit.\n//\n// Samples:\n//    [typedef] int x;\n//        x = int\n//\n//    [typedef] struct y x;\n//        x = struct y\n//\n//    [typedef] some complex type x, *y, **z;\n//        x = some complex type\n//        y = some complex type *\n//        z = some complex type **\n//\n//    [typedef] int x[2];\n//        x = int[2]\n//\n//    [typedef] int (*x)[2];\n//        x = int (*)[2] <-- pointer to an array of two integers\n//\n//    [typedef] int *x[2];\n//        x = int * [2] <-- array of two pointers to integer\n//\n//    [typedef] int (*x)(void);\n//        x = int (*)(void) <--- function pointer\n//\n//    [typedef] int (x)(void)\n//        x = int ()(void) <--- function type (not a pointer!)\n//\n//    [typedef] int x(void)\n//        x = int ()(void) <--- still function type\n//\n//    [typedef] int (MACRO *x)(void);\n//        x = int (MACRO *)(void) <--- function pointer\n//    (WINAPI is an example of MACRO.)\n//\n//    [typedef] int (MACRO x)(void)\n//        x = int (MACRO)(void) <--- function type (not a pointer!)\n//    (WINAPI is an example of MACRO.)\n//\n//    [typedef] int ((x))(void)\n//        x = int ()(void) <--- same as above\n//\n//    [typedef] int (*(*x)(int))[2];\n//        x = int (*(*)(int))[2] <-- which is a function pointer taking an int and\n//                                   returning a pointer to an array of two integers...\n//\n//    [typedef] blah (*x(k (*)(y *)))(z *);\n//        x = blah (*(k (*)(y *)))(z *) <-- which is a function (!not a function pointer!)\n//                                   taking a function pointer A as argument and returning\n//                                   a function pointer B. A = k (*)(y *)\n//                                   and B = blah (*)(z *)\n//\n// Note that not all syntaxes involving parentheses are valid.\n// Examples of what is NOT valid:\n//\n//    [typedef] unsigned (int)(*x)()\n//    [typedef] int[] x;\n//\n// So:\n//  - if there is an identifier at the end, we use that\n//  - if there are round parentheses then the identifier seems to be the first\n//    one found in the nested parentheses chain\n//  - if there are no round parentheses then the identifier is the last one\n//    found in the toplevel chain\n//\n// In case of multiple declarations it seems that only the first part with identifiers\n// and keywords is kept across types.\n// Ex:\n//    [typedef] int (*int2ptr)[2], baz;\n//        int2ptr = int (*)[2]\n//        baz     = int\n//\nvoid cxxParserExtractTypedef(\n\t\tCXXTokenChain * pChain,\n\t\tbool bExpectTerminatorAtEnd,\n\t\tbool bGotTemplate\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\n#ifdef CXX_DO_DEBUGGING\n\tvString * pX = cxxTokenChainJoin(pChain,NULL,0);\n\tCXX_DEBUG_PRINT(\"Extracting typedef from '%s'\",vStringValue(pX));\n\tvStringDelete(pX);\n#endif\n\n\t// At least something like\n\t//   a b;\n\n\tif(pChain->iCount < (bExpectTerminatorAtEnd ? 3 : 2))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Not enough tokens for a type definition\");\n\t\treturn;\n\t}\n\n\tunsigned int uProperties = 0;\n\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)\n\t\tuProperties |= CXXTagPropertyExport;\n\n\tCXXToken * t;\n\n\tif(bExpectTerminatorAtEnd)\n\t{\n\t\tt = cxxTokenChainLast(pChain);\n\t\tCXX_DEBUG_ASSERT(\n\t\t\t\tcxxTokenTypeIs(t,CXXTokenTypeSemicolon),\n\t\t\t\t\"The terminator should be present here\"\n\t\t\t);\n\t\tcxxTokenChainDestroyLast(pChain);\n\t}\n\n\t// There may be multiple typedefs inside a single declaration.\n\n\t// [typedef] x y, *z;\n\t//   -> y is x\n\t//   -> z is x *\n\n\t// The angle brackets are not necessarily condensed in chains here\n\t// since we were parsing a generic statement which expected less-than\n\t// and greater-than operators to be present. We need to take care of that.\n\n\twhile(pChain->iCount >= 2)\n\t{\n\t\t//\n\t\t// Skip either to a comma or to the end, but keep track of the first parenthesis.\n\t\t//\n\n\t\tt = cxxTokenChainFirst(pChain);\n\n\t\tCXX_DEBUG_ASSERT(t,\"There should be a token here!\");\n\n\t\tCXXToken * pFirstParenthesis = NULL;\n\t\tint iSearchTypes = CXXTokenTypeComma | CXXTokenTypeSmallerThanSign |\n\t\t\t\t\t\t\t\tCXXTokenTypeParenthesisChain;\n\t\tCXXToken * pComma;\n\nskip_to_comma_or_end:\n\n\t\tpComma = cxxTokenChainNextTokenOfType(t,iSearchTypes);\n\n\t\tif(pComma)\n\t\t{\n\t\t\t// , < or (\n\t\t\tif(cxxTokenTypeIs(pComma,CXXTokenTypeSmallerThanSign))\n\t\t\t{\n\t\t\t\tCXX_DEBUG_PRINT(\"Found angle bracket, trying to skip it\");\n\n\t\t\t\tt = cxxTokenChainSkipToEndOfTemplateAngleBracket(pComma);\n\t\t\t\tif(!t)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Mismatched < sign inside typedef: giving up on it\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// and go ahead\n\t\t\t\tgoto skip_to_comma_or_end;\n\t\t\t}\n\n\t\t\tif(cxxTokenTypeIs(pComma,CXXTokenTypeParenthesisChain))\n\t\t\t{\n\t\t\t\t// We keep track only of the first one\n\t\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\t\t!pFirstParenthesis,\n\t\t\t\t\t\t\"We should have stopped only at the first parenthesis\"\n\t\t\t\t\t);\n\n\t\t\t\tiSearchTypes &= ~CXXTokenTypeParenthesisChain;\n\t\t\t\tpFirstParenthesis = pComma;\n\t\t\t\t// and go ahead\n\t\t\t\tgoto skip_to_comma_or_end;\n\t\t\t}\n\n\t\t\tCXX_DEBUG_ASSERT(cxxTokenTypeIs(pComma,CXXTokenTypeComma),\"Oops, expected a comma!\");\n\n\t\t\t// Really a comma!\n\t\t\tCXX_DEBUG_PRINT(\"Found comma\");\n\n\t\t\tif((!pComma->pPrev) || (!pComma->pPrev->pPrev))\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found comma but not enough tokens before it\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tt = pComma->pPrev;\n\t\t} else {\n\t\t\tCXX_DEBUG_PRINT(\"Found no comma, pointing at end of declaration\");\n\n\t\t\tt = cxxTokenChainLast(pChain);\n\t\t}\n\n\t\tCXX_DEBUG_ASSERT(t,\"We should have found a token here!\");\n\n\t\t//\n\t\t// Now look for the identifier\n\t\t//\n\t\tCXXTokenChain * pTParentChain;\n\t\tCXXToken * pLookupStart = t;\n\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeIdentifier))\n\t\t{\n\t\t\t// Use the identifier at end, whatever comes before\n\t\t\tCXX_DEBUG_PRINT(\"Identifier seems to be at end: %s\",vStringValue(t->pszWord));\n\t\t\tpTParentChain = pChain;\n\t\t} else if(pFirstParenthesis)\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"Identifier not at end, but got parenthesis chain\");\n\t\t\t//\n\t\t\t// Possibly function pointer or function type definition.\n\t\t\t//\n\t\t\t//    typedef blah (*(foo))(baz)\n\t\t\t//    typedef blah (*foo)(baz)\n\t\t\t//    typedef blah (*foo)[...]\n\t\t\t//    typedef blah (foo)(baz)\n\t\t\t//    typedef blah ((foo))(baz)\n\t\t\t//    typedef blah foo(baz)\n\t\t\t//\n\t\t\t// So we have two cases: either there are at least two parentheses at the\n\t\t\t// top level or there is only one. If there are at least two then\n\t\t\t// we expect foo we want to capture to be at the end of the first nested\n\t\t\t// parenthesis chain. If there is only one then we expect it to be the\n\t\t\t// last identifier before the parenthesis.\n\t\t\t//\n\t\t\tif(\n\t\t\t\t\tpFirstParenthesis->pNext &&\n\t\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\tpFirstParenthesis->pNext,\n\t\t\t\t\t\t\tCXXTokenTypeParenthesisChain |\n\t\t\t\t\t\t\t\tCXXTokenTypeSquareParenthesisChain\n\t\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_PRINT(\"There are two parenthesis chains. Looking in the first one\");\n\t\t\t\tt = cxxTokenChainLastPossiblyNestedTokenOfType(\n\t\t\t\t\t\tpFirstParenthesis->pChain,\n\t\t\t\t\t\tCXXTokenTypeIdentifier,\n\t\t\t\t\t\t&pTParentChain\n\t\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tCXX_DEBUG_PRINT(\"There is one parenthesis chain. Looking just before\");\n\n\t\t\t\tif(\n\t\t\t\t\tpFirstParenthesis->pPrev &&\n\t\t\t\t\tcxxTokenTypeIs(pFirstParenthesis->pPrev,CXXTokenTypeIdentifier)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// Nasty \"typedef blah foo(baz)\" case.\n\t\t\t\t\tt = pFirstParenthesis->pPrev;\n\n\t\t\t\t\t// Let's have a consistent typeref too. We correct user\n\t\t\t\t\t// input so it becomes \"typedef blah (foo)(baz)\".\n\n\t\t\t\t\tpTParentChain = cxxTokenChainCreate();\n\n\t\t\t\t\tCXXToken * par = cxxTokenCreate();\n\t\t\t\t\tpar->eType = CXXTokenTypeOpeningParenthesis;\n\t\t\t\t\tpar->iLineNumber = t->iLineNumber;\n\t\t\t\t\tpar->oFilePosition = t->oFilePosition;\n\t\t\t\t\tvStringPut(par->pszWord,'(');\n\t\t\t\t\tpar->pChain = NULL;\n\t\t\t\t\tcxxTokenChainAppend(pTParentChain,par);\n\n\t\t\t\t\tpar = cxxTokenCreate();\n\t\t\t\t\tpar->eType = CXXTokenTypeIdentifier;\n\t\t\t\t\tpar->iLineNumber = t->iLineNumber;\n\t\t\t\t\tpar->oFilePosition = t->oFilePosition;\n\t\t\t\t\tvStringCopy(par->pszWord,t->pszWord);\n\t\t\t\t\tpar->pChain = NULL;\n\t\t\t\t\tcxxTokenChainAppend(pTParentChain,par);\n\n\t\t\t\t\tt->eType = CXXTokenTypeParenthesisChain;\n\t\t\t\t\tt->pChain = pTParentChain;\n\t\t\t\t\tvStringClear(t->pszWord);\n\n\t\t\t\t\tpFirstParenthesis = t;\n\t\t\t\t\tt = par;\n\n\t\t\t\t\tpar = cxxTokenCreate();\n\t\t\t\t\tpar->eType = CXXTokenTypeClosingParenthesis;\n\t\t\t\t\tpar->iLineNumber = t->iLineNumber;\n\t\t\t\t\tpar->oFilePosition = t->oFilePosition;\n\t\t\t\t\tvStringPut(par->pszWord,')');\n\t\t\t\t\tpar->pChain = NULL;\n\t\t\t\t\tcxxTokenChainAppend(pTParentChain,par);\n\n\t\t\t\t} else {\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Parenthesis but no identifier: no clue\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// just scan backwards to the last identifier\n\t\t\tCXX_DEBUG_PRINT(\"No identifier and no parenthesis chain, trying to scan backwards\");\n\t\t\tpTParentChain = pChain;\n\t\t\tt = cxxTokenChainPreviousTokenOfType(t,CXXTokenTypeIdentifier);\n\t\t}\n\n\t\tif(!t)\n\t\t{\n\t\t\t// Not found yet.\n\t\t\t// If we're in C++ mode but we haven't confirmed that the language is really C++\n\t\t\t// then we might try to look for a C++ identifier here.\n\t\t\tif(\n\t\t\t\tcxxParserCurrentLanguageIsCPP() &&\n\t\t\t\t(!g_cxx.bConfirmedCPPLanguage) &&\n\t\t\t\tcxxTokenTypeIs(pLookupStart,CXXTokenTypeKeyword) &&\n\t\t\t\tcxxKeywordIsCPPSpecific(pLookupStart->eKeyword)\n\t\t\t)\n\t\t\t{\n\t\t\t\t// treat as identifier\n\t\t\t\tpLookupStart->eType = CXXTokenTypeIdentifier;\n\t\t\t\tt = pLookupStart;\n\t\t\t}\n\n\t\t\tif(!t)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Didn't find an identifier: something nasty is going on\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\ttagEntryInfo * tag = cxxTagBegin(CXXTagKindTYPEDEF,t);\n\n\t\tif(tag)\n\t\t{\n\t\t\tCXXToken * pTypeName = NULL;\n\n\t\t\tcxxTokenChainTake(pTParentChain,t);\n\n\t\t\t// Avoid emitting typerefs for strange things like\n\t\t\t//  typedef MACRO(stuff,stuff) X;\n\t\t\t// or parsing errors we might make in ugly cases like\n\t\t\t//  typedef WHATEVER struct x { ... } y;\n\t\t\tif(\n\t\t\t\t\t(pTParentChain == pChain) && // not function pointer (see above)\n\t\t\t\t\t(\n\t\t\t\t\t\tpComma ?\n\t\t\t\t\t\t\tcxxTokenChainPreviousTokenOfType(\n\t\t\t\t\t\t\t\t\tpComma,\n\t\t\t\t\t\t\t\t\tCXXTokenTypeParenthesisChain | CXXTokenTypeAngleBracketChain\n\t\t\t\t\t\t\t\t) :\n\t\t\t\t\t\t\tcxxTokenChainLastTokenOfType(\n\t\t\t\t\t\t\t\t\tpChain,\n\t\t\t\t\t\t\t\t\tCXXTokenTypeParenthesisChain | CXXTokenTypeAngleBracketChain\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\"Wild parenthesis in type definition: not emitting typeref\"\n\t\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// other kind of typeref, use typename here.\n\t\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\t\tpChain->iCount > 0,\n\t\t\t\t\t\t\"There should be at least another token here!\"\n\t\t\t\t\t);\n\n\t\t\t\tpTypeName = cxxTagCheckAndSetTypeField(\n\t\t\t\t\t\t\tcxxTokenChainFirst(pChain),\n\t\t\t\t\t\t\tpComma ? pComma->pPrev : cxxTokenChainLast(pChain)\n\t\t\t\t\t\t);\n\t\t\t}\n\n\t\t\ttag->isFileScope = !isInputHeaderFile()\n\t\t\t\t&& !(uProperties & CXXTagPropertyExport)\n\t\t\t\t&& !cxxScopeIsExported();\n\n\t\t\tif(bGotTemplate)\n\t\t\t\tcxxTagHandleTemplateFields();\n\n\t\t\tvString *pszProperties = NULL;\n\t\t\tif(uProperties)\n\t\t\t\tpszProperties = cxxTagSetProperties(uProperties);\n\n\t\t\tint iCorkQueueIndex = cxxTagCommit(NULL);\n\t\t\tcxxTagUseTokenAsPartOfDefTag(iCorkQueueIndex, t);\n\n\t\t\tvStringDelete(pszProperties); /* NULL is acceptable. */\n\n\t\t\tif (\n\t\t\t\t\tbGotTemplate &&\n\t\t\t\t\tcxxTagKindEnabled(CXXTagCPPKindTEMPLATEPARAM)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\tcxxScopePush(t,CXXScopeTypeTypedef,CXXScopeAccessUnknown);\n\t\t\t\tcxxParserEmitTemplateParameterTags();\n\t\t\t\tcxxScopePop();\n\t\t\t} else {\n\t\t\t\tcxxTokenDestroy(t);\n\t\t\t}\n\t\t\tif(pTypeName)\n\t\t\t\tcxxTokenDestroy(pTypeName);\n\t\t}\n\n\t\tif(!pComma)\n\t\t\tbreak;\n\n\t\t// We must kill anything up to either an identifier, a keyword (type) or > which is\n\t\t// assumed to be part of a template.\n\n\t\twhile(\n\t\t\t\tpComma->pPrev &&\n\t\t\t\t(\n\t\t\t\t\t!cxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\tpComma->pPrev,\n\t\t\t\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeKeyword |\n\t\t\t\t\t\t\tCXXTokenTypeGreaterThanSign | CXXTokenTypeAngleBracketChain\n\t\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t)\n\t\t{\n\t\t\tCXXToken * pAux = pComma->pPrev;\n\t\t\tcxxTokenChainTake(pChain,pAux);\n\t\t\tcxxTokenDestroy(pAux);\n\t\t}\n\n\t\t// got a comma.\n\t\tcxxTokenChainTake(pChain,pComma);\n\t\tcxxTokenDestroy(pComma);\n\t}\n\n\tCXX_DEBUG_LEAVE();\n\treturn;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_parser_using.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_scope.h\"\n\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"read.h\"\n#include \"trashbox.h\"\n\nbool cxxParserParseUsingClause(void)\n{\n\tCXX_DEBUG_ENTER();\n\n\tunsigned int uInitialKeywordState = g_cxx.uKeywordState;\n\n\t// using-directives for namespaces and using-declarations\n\t// for namespace members\n\t// using-declarations for class members\n\t// type alias and alias template declaration (since C++11)\n\n\t// using namespace ns_name;\t(5)\t// whole namespace\n\t// using ns_name::name;\t(6)\t // only symbol name\n\t// using B::g; // inside class, using method g from base class B\n\t// using identifier attr(optional) = type-id ; <-- equivalent to a typedef!\n\n\tcxxTokenChainClear(g_cxx.pTokenChain);\n\n\t// skip to the next ; without leaving scope.\n\tif(!cxxParserParseUpToOneOf(\n\t\t\tCXXTokenTypeSemicolon | CXXTokenTypeClosingBracket | CXXTokenTypeEOF,\n\t\t\tfalse\n\t\t))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to parse up to the next ;\");\n\t\treturn false;\n\t}\n\n\tif(!cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeSemicolon))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"This is a syntax error but we tolerate it\");\n\t\treturn true;\n\t}\n\n\tcxxTokenChainDestroyLast(g_cxx.pTokenChain);\n\n\tif(g_cxx.pTokenChain->iCount < 1)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"This is a syntax error but we tolerate it\");\n\t\treturn true;\n\t}\n\n\tCXXToken * pAssignment = cxxTokenChainFirstTokenOfType(\n\t\t\tg_cxx.pTokenChain,\n\t\t\tCXXTokenTypeAssignment\n\t\t);\n\n\tif(pAssignment)\n\t{\n\t\tCXXToken * pFirst = cxxTokenChainFirst(g_cxx.pTokenChain);\n\t\tbool bGotTemplate = g_cxx.pTemplateTokenChain &&\n\t\t\t(g_cxx.pTemplateTokenChain->iCount > 0) &&\n\t\t\tcxxParserCurrentLanguageIsCPP();\n\n\t\tif(cxxTokenTypeIs(pFirst,CXXTokenTypeIdentifier))\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\"Found using clause '%s' which defines a type\",\n\t\t\t\t\tvStringValue(pFirst->pszWord)\n\t\t\t\t);\n\n\t\t\t// It's a typedef. Reorder the tokens in the chain\n\t\t\t// so it really looks like a typedef\n\t\t\t// and pass it to the specialized extraction routine\n\t\t\tcxxTokenChainTake(g_cxx.pTokenChain,pFirst);\n\n\t\t\twhile(cxxTokenChainFirst(g_cxx.pTokenChain) != pAssignment)\n\t\t\t\tcxxTokenChainDestroyFirst(g_cxx.pTokenChain);\n\t\t\t// kill assignment itself\n\t\t\tcxxTokenChainDestroyFirst(g_cxx.pTokenChain);\n\n\t\t\t// in typedefs it's at the end\n\t\t\tcxxTokenChainAppend(g_cxx.pTokenChain,pFirst);\n\n\t\t\tcxxParserExtractTypedef(g_cxx.pTokenChain,false,bGotTemplate);\n\t\t}\n\t} else {\n\t\tCXX_DEBUG_ASSERT(\n\t\t\t\tg_cxx.pTokenChain->iCount > 0,\n\t\t\t\t\"The token chain should be non empty at this point\"\n\t\t\t);\n\n\t\tCXXToken * t = cxxTokenChainFirst(g_cxx.pTokenChain);\n\n\t\tbool bUsingNamespace = false;\n\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeKeyword))\n\t\t{\n\t\t\tif(t->eKeyword == CXXKeywordNAMESPACE)\n\t\t\t{\n\t\t\t\tbUsingNamespace = true;\n\t\t\t\tcxxTokenChainDestroyFirst(g_cxx.pTokenChain);\n\t\t\t} else if(t->eKeyword == CXXKeywordTYPENAME)\n\t\t\t{\n\t\t\t\tcxxTokenChainDestroyFirst(g_cxx.pTokenChain);\n\t\t\t}\n\t\t}\n\n\t\tif(g_cxx.pTokenChain->iCount > 0)\n\t\t{\n\t\t\ttagEntryInfo * tag = NULL;\n\n\t\t\tif(bUsingNamespace)\n\t\t\t{\n\t\t\t\tcxxTokenChainCondense(g_cxx.pTokenChain,0);\n\n\t\t\t\tt = cxxTokenChainFirst(g_cxx.pTokenChain);\n\t\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\t\tt,\n\t\t\t\t\t\t\"Condensation of a non empty chain should produce a token!\"\n\t\t\t\t\t);\n\n\n\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\"Found using clause '%s' which extends scope\",\n\t\t\t\t\t\tvStringValue(t->pszWord)\n\t\t\t\t\t);\n\t\t\t\ttag = cxxTagBegin(CXXTagCPPKindUSING,t);\n\t\t\t} else {\n\n\t\t\t\tt = cxxTokenChainLast(g_cxx.pTokenChain);\n\n\t\t\t\tif (cxxTokenTypeIs(t,CXXTokenTypeIdentifier)) {\n\t\t\t\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\t\t\"Found using clause '%s' which imports a name\",\n\t\t\t\t\t\tvStringValue(t->pszWord)\n\t\t\t\t\t\t);\n\t\t\t\t\ttag = cxxTagBegin(CXXTagCPPKindNAME,t);\n\t\t\t\t} else {\n\t\t\t\t\tCXXToken * pOp = cxxTokenChainFirstKeyword(\n\t\t\t\t\t\tg_cxx.pTokenChain,\n\t\t\t\t\t\tCXXKeywordOPERATOR\n\t\t\t\t\t\t);\n\n\t\t\t\t\tif (pOp) {\n\t\t\t\t\t\tvString *pOpStr = cxxTokenChainJoinRange (pOp, t, \" \",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  CXXTokenChainJoinNoTrailingSpaces);\n\t\t\t\t\t\tPARSER_TRASH_BOX(pOpStr, vStringDelete);\n\t\t\t\t\t\tCXXToken * pOpToken = cxxTokenCopy(pOp);\n\t\t\t\t\t\tPARSER_TRASH_BOX(pOpToken, cxxTokenDestroy);\n\t\t\t\t\t\tvStringCopy(pOpToken->pszWord, pOpStr);\n\t\t\t\t\t\ttag = cxxTagBegin(CXXTagCPPKindNAME,pOpToken);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// FIXME: We need something like \"nameref:<condensed>\" here!\n\t\t\t}\n\n\t\t\tif(tag)\n\t\t\t{\n\t\t\t\ttag->isFileScope = (cxxScopeGetType() == CXXScopeTypeNamespace) &&\n\t\t\t\t\t\t\t(!isInputHeaderFile());\n\n\t\t\t\tbool bExported = uInitialKeywordState & CXXParserKeywordStateSeenExport;\n\t\t\t\tunsigned int uProperties = 0;\n\t\t\t\tif(bExported)\n\t\t\t\t\tuProperties |= CXXTagPropertyExport;\n\t\t\t\ttag->isFileScope = bExported || cxxScopeIsExported()\n\t\t\t\t\t? 0\n\t\t\t\t\t: tag->isFileScope;\n\t\t\t\tvString * pszProperties = NULL;\n\n\t\t\t\tif(uProperties)\n\t\t\t\t\tpszProperties = cxxTagSetProperties(uProperties);\n\n\t\t\t\tcxxTagCommit(NULL);\n\n\t\t\t\tvStringDelete (pszProperties);\n\t\t\t}\n\t\t}\n\t}\n\n\tif(!g_cxx.bConfirmedCPPLanguage)\n\t{\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Succeeded in parsing C++ using: this really seems to be C++\"\n\t\t\t);\n\t\tg_cxx.bConfirmedCPPLanguage = true;\n\t}\n\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_parser_variable.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_parser.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_token.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_scope.h\"\n#include \"cxx_side_chain.h\"\n#include \"cxx_subparser_internal.h\"\n\n#include \"vstring.h\"\n#include \"read.h\"\n\n\nstatic CXXToken * cxxParserVardefInParenthesis (CXXToken *pToken, int depth);\n\n//\n// This is used to find the first identifier in stuff like\n//\n//    ret type (*variable)(params)\n//    ret type (* const (variable[4]))(params)\n//    ret type (*baz)(params) <-- function pointer (variable)\n//    ret type (*(baz))(params) <-- function pointer (variable)\n//    ret type (* const (baz))(params) <-- function pointer (variable)\n//    ret type (*baz())() <-- function returning function pointer\n//    ret type (*baz(params))(params) <-- function returning function pointer\n//    ret type (*baz(params)) <-- function returning a pointer\n//    ret type (*baz(params))[2] <-- function returning a pointer to array\n//\nCXXToken * cxxParserFindFirstPossiblyNestedAndQualifiedIdentifier(\n\t\tCXXTokenChain * pChain,\n\t\tCXXTokenChain ** pParentChain\n\t)\n{\n\tCXXToken * pId = cxxTokenChainFirstPossiblyNestedTokenOfType(\n\t\t\tpChain,\n\t\t\tCXXTokenTypeIdentifier,\n\t\t\tpParentChain\n\t\t);\n\n\tif(!pId)\n\t\treturn NULL;\n\n\tif(!cxxParserCurrentLanguageIsCPP())\n\t\treturn pId;\n\n\t// In the case of CPP we also handle qualifications.\n\n\tif(!pId->pNext)\n\t\treturn pId;\n\n\tif(!cxxTokenTypeIs(pId->pNext,CXXTokenTypeMultipleColons))\n\t\treturn pId;\n\n\t// identifier:: ...\n\n\t// Look for the LAST identifier in the same chain.\n\t// baz::foo::something <--\n\n\treturn cxxTokenChainNextTokenOfType(pId,CXXTokenTypeIdentifier);\n}\n\n//\n// Attempt to extract variable declarations from the chain.\n// Returns true if at least one variable was extracted.\n// Returns false if a variable declaration could not be identified.\n//\n// Recognized variable declarations are of the following kinds:\n//\n//   type var;\n//   type var1,var2;\n//   type var[];\n//   type var(constructor args);\n//   type var{list initializer};\n//   type var = ...;\n//   type (*ident)();\n//   type (var[]); <--   type (var); is also valid in C syntax.\n//   type *(var);        However, it is handled as macro expansion.\n//   type var:bits;\n//   type var: range declaration <-- (FIXME: this is only inside for!)\n//   very complex type with modifiers() namespace::namespace::var = ...;\n//   type<with template> namespace::var[] = {\n//   type var<T> = ...;\n//   type var<T>[] = ...;\n//   ...\n//\n// Assumptions:\n//  - there is a terminator at the end: either ; or {\n//\n// Notes:\n// - Be aware that if this function returns true then the pChain very likely has been modified\n//   (partially destroyed) as part of the type extraction algorithm.\n//   If the function returns false the chain has not been modified (and\n//   to extract something else from it).\n//\n// - This function is quite tricky.\n//\nbool cxxParserExtractVariableDeclarations(CXXTokenChain * pChain,unsigned int uFlags)\n{\n\tint iCorkIndex = CORK_NIL;\n\tint iCorkIndexFQ = CORK_NIL;\n\n\tCXX_DEBUG_ENTER();\n\n\tif(pChain->iCount < 1)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Chain is empty\");\n\t\treturn false;\n\t}\n\n#ifdef CXX_DO_DEBUGGING\n\tvString * pJoinedChain = cxxTokenChainJoin(pChain,NULL,0);\n\tCXX_DEBUG_PRINT(\n\t\t\t\"Looking for variable declarations in '%s'\",\n\t\t\tvStringValue(pJoinedChain)\n\t\t);\n\tvStringDelete(pJoinedChain);\n#endif\n\n\t//\n\t// Strategy:\n\t//   - verify that the chain starts with an identifier or keyword (always present)\n\t//   - run to one of : ; [] () {} = ,\n\t//   - ensure that the previous token is an identifier (except for special cases)\n\t//   - go back to skip the eventual scope\n\t//   - ensure that there is a leading type\n\t//   - if we are at : [], () or {} then run to the next ; = or ,\n\t//   - once we have determined that a variable declaration is there\n\t//     modify the chain to contain only the type name\n\t//   - emit variable tag\n\t//   - if we are at , then check if there are more declarations\n\t//\n\n\tCXXToken * t = cxxTokenChainFirst(pChain);\n\n\tenum CXXScopeType eScopeType = cxxScopeGetType();\n\n\tCXX_DEBUG_ASSERT(t,\"There should be an initial token here\");\n\n\tif(!cxxTokenTypeIsOneOf(t,CXXTokenTypeIdentifier | CXXTokenTypeKeyword))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Statement does not start with identifier or keyword\");\n\t\treturn false;\n\t}\n\n\t// Only keywords that can appear in a variable declaration.\n\t//\n\t// TODO?: We might add this check also on the other tokens here\n\t//        However it's unclear if it would provide some advantages\n\t//        It would certainly be a small overhead.\n\tif(\n\t\t\tcxxTokenTypeIs(t,CXXTokenTypeKeyword) &&\n\t\t\t(!cxxKeywordMayAppearInVariableDeclaration(t->eKeyword))\n\t\t)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Initial keyword can't appear in a variable declaration\");\n\t\treturn false;\n\t}\n\n\n\t// For tracking a specialization in a variable template\n\tCXXToken * pTemplateSpecializationStart = NULL, * pTemplateSpecializationEnd = NULL;\n\tbool bGotVariable = false;\n\t// Loop over the whole statement.\n\n\twhile(t)\n\t{\n\t\t// Scan up to a notable token: ()[]{}=,;:{\n\n\t\twhile(t)\n\t\t{\n\t\t\tif(cxxTokenTypeIsOneOf(\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tCXXTokenTypeSingleColon | CXXTokenTypeParenthesisChain |\n\t\t\t\t\t\t\tCXXTokenTypeSquareParenthesisChain | CXXTokenTypeBracketChain |\n\t\t\t\t\t\t\tCXXTokenTypeAssignment | CXXTokenTypeComma |\n\t\t\t\t\t\t\tCXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket\n\t\t\t\t\t))\n\t\t\t{\n\t\t\t\t// Notable token reached.\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif(\n\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tCXXTokenTypeOperator | CXXTokenTypeMultipleAnds |\n\t\t\t\t\t\t\tCXXTokenTypePointerOperator | CXXTokenTypeStringConstant |\n\t\t\t\t\t\t\tCXXTokenTypeAngleBracketChain | CXXTokenTypeCharacterConstant |\n\t\t\t\t\t\t\tCXXTokenTypeMultipleDots | CXXTokenTypeClosingBracket |\n\t\t\t\t\t\t\tCXXTokenTypeClosingParenthesis | CXXTokenTypeClosingSquareParenthesis |\n\t\t\t\t\t\t\tCXXTokenTypeGreaterThanSign\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\t// Something that should not appear in a variable declaration\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\"Found token '%s' of type 0x%02x that should \" \\\n\t\t\t\t\t\t\t\"not appear in the initial part of a variable declaration\",\n\t\t\t\t\t\tvStringValue(t->pszWord),\n\t\t\t\t\t\tt->eType\n\t\t\t\t\t);\n\t\t\t\treturn bGotVariable;\n\t\t\t}\n\n\t\t\tif(cxxTokenTypeIs(t, CXXTokenTypeSmallerThanSign))\n\t\t\t{\n\t\t\t\tpTemplateSpecializationStart = t;\n\t\t\t\t// Must be part of template type name (so properly balanced).\n\t\t\t\tt = cxxTokenChainSkipToEndOfTemplateAngleBracket(t);\n\t\t\t\tif(!t)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Failed to skip past angle bracket chain\");\n\t\t\t\t\treturn bGotVariable;\n\t\t\t\t}\n\t\t\t\tpTemplateSpecializationEnd = t;\n\t\t\t}\n\n\t\t\tt = t->pNext;\n\t\t}\n\n\t\t// Notable token reached?\n\n\t\tif(!t)\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Nothing interesting here\");\n\t\t\treturn bGotVariable;\n\t\t}\n\n\t\tCXXToken * pEndScanningAttrs = t;\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Found notable token '%s' of type 0x%02x(%s)\",\n\t\t\t\tvStringValue(t->pszWord),\n\t\t\t\tt->eType,\n\t\t\t\tcxxDebugTypeDecode(t->eType)\n\t\t\t);\n\n\t\t// Now before the notable token there MUST be an identifier\n\t\t// (eventually hidden in a parenthesis chain) and also a typename.\n\t\tif(!t->pPrev)\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Nothing interesting before notable token\");\n\t\t\treturn bGotVariable;\n\t\t}\n\n\t\tCXXToken * pIdentifier = NULL;\n\t\tCXXToken * pTokenBefore = NULL;\n\t\tbool bSpecializedAsVarTemplate = false;\n\n\t\t// If we have to continue scanning we'll remove the tokens from here\n\t\t// so they don't end up being part of the type name.\n\t\t// If this is set to NULL then it means that we cannot determine properly\n\t\t// what to remove and we should stop scanning after the current variable.\n\t\tCXXToken * pRemoveStart = t;\n\n\t\tswitch(t->eType)\n\t\t{\n\t\t\tcase CXXTokenTypeParenthesisChain:\n\n\t\t\t\t// At a parenthesis chain we need some additional checks.\n\t\t\t\tif(\n\t\t\t\t\t\t// check for function pointers or nasty arrays\n\t\t\t\t\t\t// Possible cases:\n\t\t\t\t\t\t//    ret type (*variable)(params)\n\t\t\t\t\t\t//    ret type (* const (variable[4]))(params)\n\t\t\t\t\t\tt->pNext &&\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tcxxTokenTypeIs(t->pNext,CXXTokenTypeParenthesisChain) &&\n\t\t\t\t\t\t\t\tcxxParserTokenChainLooksLikeFunctionParameterList(\n\t\t\t\t\t\t\t\t\t\tt->pNext->pChain,\n\t\t\t\t\t\t\t\t\t\tNULL\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) ||\n\t\t\t\t\t\t\tcxxTokenTypeIs(t->pNext,CXXTokenTypeSquareParenthesisChain)\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\t(pIdentifier = cxxParserFindFirstPossiblyNestedAndQualifiedIdentifier(\n\t\t\t\t\t\t\t\tt->pChain,\n\t\t\t\t\t\t\t\tNULL\n\t\t\t\t\t\t\t)) &&\n\t\t\t\t\t\t// Discard function declarations with function return types\n\t\t\t\t\t\t// like void (*A(B))(C);\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(!pIdentifier->pNext) ||\n\t\t\t\t\t\t\t(!cxxTokenTypeIs(pIdentifier->pNext,CXXTokenTypeParenthesisChain))\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// A function pointer.\n\t\t\t\t\t// There are two parentheses, skip the second too.\n\t\t\t\t\tpTokenBefore = t->pPrev;\n\t\t\t\t\tt = t->pNext->pNext;\n\t\t\t\t\tpRemoveStart = t;\n\t\t\t\t\tgoto got_identifier;\n\t\t\t\t}\n\n\t\t\t\tif(\n\t\t\t\t\t\t(t->pChain->iCount == 3) &&\n\t\t\t\t\t\tcxxTokenTypeIs(\n\t\t\t\t\t\t\t\tcxxTokenChainAt(t->pChain,1),\n\t\t\t\t\t\t\t\tCXXTokenTypeParenthesisChain\n\t\t\t\t\t\t\t) &&\n\t\t\t\t\t\tt->pPrev &&\n\t\t\t\t\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeIdentifier) &&\n\t\t\t\t\t\tt->pPrev->pPrev &&\n\t\t\t\t\t\tcxxTokenTypeIs(t->pPrev->pPrev,CXXTokenTypeIdentifier)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Parenthesis seems to define an __ARGS style prototype\");\n\t\t\t\t\treturn bGotVariable;\n\t\t\t\t}\n\n\t\t\t\tif(\n\t\t\t\t\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeIdentifier) &&\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(eScopeType == CXXScopeTypeNamespace) ||\n\t\t\t\t\t\t\t(eScopeType == CXXScopeTypeFunction)\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\tcxxParserCurrentLanguageIsCPP() &&\n\t\t\t\t\t\tcxxParserTokenChainLooksLikeConstructorParameterSet(t->pChain)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// ok, *might* be variable instantiation\n\t\t\t\t\tpIdentifier = t->pPrev;\n\t\t\t\t\tpTokenBefore = pIdentifier->pPrev;\n\t\t\t\t\tgoto got_identifier;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t\t// Variable declaration in parenthesis.\n\t\t\t\t\t\t// We handle only cases that are clearly variable declarations.\n\t\t\t\t\t\t// We leave alone the stuff that may also be a function call.\n\t\t\t\t\t\t//   type *(var)\n\t\t\t\t\t\t//   type &(var)\n\t\t\t\t\t\t//   type const (var)\n\t\t\t\t\t\t//   type (var[])\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tcxxTokenTypeIsOneOf(t->pPrev,CXXTokenTypeStar | CXXTokenTypeAnd) ||\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeKeyword) &&\n\t\t\t\t\t\t\t\tcxxKeywordMayBePartOfTypeName(t->pPrev->eKeyword) &&\n\t\t\t\t\t\t\t\t// but not decltype(var)!\n\t\t\t\t\t\t\t\t!cxxKeywordIsDecltype(t->pPrev->eKeyword)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t// Inspect the inside parenthesis\n\t\t\t\t\t\t\tpIdentifier = cxxParserVardefInParenthesis(cxxTokenChainFirst(t->pChain), 0)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Parenthesis seems to surround a variable definition\");\n\t\t\t\t\tpTokenBefore = t->pPrev;\n\t\t\t\t\tt = t->pNext;\n\t\t\t\t\tgoto got_identifier;\n\t\t\t\t}\n\n\t\t\t\tif(\n\t\t\t\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeKeyword) &&\n\t\t\t\t\tcxxKeywordIsDecltype(t->pPrev->eKeyword) &&\n\t\t\t\t\tt->pNext\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// part of typename -> skip ahead\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Parenthesis follows decltype(), skipping\");\n\t\t\t\t\tt = t->pNext;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"No recognizable parenthesis form for a variable\");\n\t\t\t\treturn bGotVariable;\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeBracketChain:\n\t\t\t\tif(\n\t\t\t\t\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeIdentifier) &&\n\t\t\t\t\t\tcxxParserCurrentLanguageIsCPP() &&\n\t\t\t\t\t\tcxxParserTokenChainLooksLikeConstructorParameterSet(t->pChain)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// ok, *might* be new C++ style variable initialization\n\t\t\t\t\tpIdentifier = t->pPrev;\n\t\t\t\t\tpTokenBefore = pIdentifier->pPrev;\n\t\t\t\t\tgoto got_identifier;\n\t\t\t\t}\n\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Bracket chain that doesn't look like a C++ var init\");\n\t\t\t\treturn bGotVariable;\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeSingleColon:\n\t\t\t\t// check for bitfield\n\t\t\t\tif(\n\t\t\t\t\t\tt->pNext &&\n\t\t\t\t\t\tcxxTokenTypeIsOneOf(t->pNext,CXXTokenTypeNumber | CXXTokenTypeIdentifier)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// ok, looks like a bit field\n\t\t\t\t\tif(\n\t\t\t\t\t\t\tcxxTokenTypeIs(t->pNext,CXXTokenTypeNumber) &&\n\t\t\t\t\t\t\tt->pNext->pNext &&\n\t\t\t\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\t\t\tt->pNext->pNext,\n\t\t\t\t\t\t\t\t\tCXXTokenTypeComma | CXXTokenTypeSemicolon |\n\t\t\t\t\t\t\t\t\tCXXTokenTypeAssignment\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\t// keep bitfield width specification as part of type\n\t\t\t\t\t\tpIdentifier = t->pPrev;\n\t\t\t\t\t\tpTokenBefore = pIdentifier->pPrev;\n\t\t\t\t\t\tt = t->pNext->pNext;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Too complex: strip width specification (the best we can do)\n\t\t\t\t\t\tpIdentifier = t->pPrev;\n\t\t\t\t\t\tpTokenBefore = pIdentifier->pPrev;\n\t\t\t\t\t}\n\n\t\t\t\t\tgoto got_identifier;\n\n\t\t\t\t}\n\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Single colon that doesn't look like a bit field\");\n\t\t\t\treturn bGotVariable;\n\t\t\tbreak;\n\t\t\tcase CXXTokenTypeSquareParenthesisChain:\n\t\t\t\t// check for array\n\t\t\t\t// Keep the array specifier as part of type\n\n\t\t\t\t//         pTemplateSpecializationStart\n\t\t\t\t//         | pTemplateSpecializationEnd\n\t\t\t\t// --------V-V\n\t\t\t\t// type var<T>[] = ...\n\t\t\t\t// -----------^------- t\n\t\t\t\tif (t->pPrev && t->pPrev == pTemplateSpecializationEnd)\n\t\t\t\t\tbSpecializedAsVarTemplate = true;\n\n\t\t\t\tpIdentifier = bSpecializedAsVarTemplate\n\t\t\t\t\t? pTemplateSpecializationStart->pPrev\n\t\t\t\t\t: t->pPrev;\n\t\t\t\tpTokenBefore = pIdentifier->pPrev;\n\n\t\t\t\twhile(t->pNext && cxxTokenTypeIs(t->pNext,CXXTokenTypeSquareParenthesisChain))\n\t\t\t\t\tt = t->pNext;\n\n\t\t\t\tif(!t->pNext)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"No token after []\");\n\t\t\t\t\treturn bGotVariable;\n\t\t\t\t}\n\n\t\t\t\t// skip identifies attached to the array as attributes\n\t\t\t\twhile(t->pNext && cxxTokenTypeIs(t->pNext, CXXTokenTypeIdentifier))\n\t\t\t\t{\n\t\t\t\t\tt = t->pNext;\n\t\t\t\t\t// skip macro argument(s)\n\t\t\t\t\tif (t->pNext && cxxTokenTypeIs(t->pNext, CXXTokenTypeParenthesisChain))\n\t\t\t\t\t\tt = t->pNext;\n\t\t\t\t}\n\n\t\t\t\tif (!t->pNext)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"No token after attribute(s) attached to []\");\n\t\t\t\t\treturn bGotVariable;\n\t\t\t\t}\n\n\t\t\t\tif(!cxxTokenTypeIsOneOf(\n\t\t\t\t\t\t\tt->pNext,\n\t\t\t\t\t\t\tCXXTokenTypeComma | CXXTokenTypeSemicolon |\n\t\t\t\t\t\t\tCXXTokenTypeAssignment | CXXTokenTypeBracketChain\n\t\t\t\t\t\t\t))\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"No comma, semicolon, = or {} after [] (\\\"%s\\\", %s)\",\n\t\t\t\t\t\t\t\tvStringValue (t->pNext->pszWord),\n\t\t\t\t\t\t\t\tcxxDebugTypeDecode (t->pNext->eType));\n\t\t\t\t\treturn bGotVariable;\n\t\t\t\t}\n\n\t\t\t\tt = t->pNext;\n\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t//         pTemplateSpecializationStart\n\t\t\t\t//         | pTemplateSpecializationEnd\n\t\t\t\t// --------V-V\n\t\t\t\t// type var<T> = ...\n\t\t\t\t// ------------^------ t\n\n\t\t\t\tif (t->pPrev && t->pPrev == pTemplateSpecializationEnd)\n\t\t\t\t\tbSpecializedAsVarTemplate = true;\n\n\t\t\t\t// Must be identifier\n\t\t\t\tif (bSpecializedAsVarTemplate &&\n\t\t\t\t\t!cxxTokenTypeIs(pTemplateSpecializationStart->pPrev, CXXTokenTypeIdentifier))\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"No identifier before the <> specializer\");\n\t\t\t\t\treturn bGotVariable;\n\t\t\t\t}\n\t\t\t\telse if (!bSpecializedAsVarTemplate &&\n\t\t\t\t\t\t !cxxTokenTypeIs(t->pPrev, CXXTokenTypeIdentifier))\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"No identifier before the notable token\");\n\t\t\t\t\treturn bGotVariable;\n\t\t\t\t}\n\n\t\t\t\tpIdentifier = bSpecializedAsVarTemplate\n\t\t\t\t\t? pTemplateSpecializationStart->pPrev\n\t\t\t\t\t: t->pPrev;\n\t\t\t\tpTokenBefore = pIdentifier->pPrev;\n\n\t\t\t\t// Skip the specializer.\n\t\t\t\t// When extracting the typeref for the variable, the specializer\n\t\t\t\t// becomes noise.\n\t\t\t\tif (bSpecializedAsVarTemplate)\n\t\t\t\t\tt = pTemplateSpecializationEnd->pNext;\n\n\t\t\t\t// The final states:\n\t\t\t\t// pTokenBefore\n\t\t\t\t// |    pIdentifier\n\t\t\t\t// V    V\n\t\t\t\t// type var ... =\n\t\t\t\t// -------------^- t\n\t\t\tbreak;\n\t\t}\n\n\t\tif (bSpecializedAsVarTemplate) {\n\t\t\tpTemplateSpecializationEnd->bFollowedBySpace = false;\n\t\t\tCXXToken * pTemplateSpecialization = cxxTokenChainExtractRange(\n\t\t\t\tpTemplateSpecializationStart,\n\t\t\t\tpTemplateSpecializationEnd,\n\t\t\t\t0\n\t\t\t\t);\n\t\t\tif(g_cxx.pTemplateSpecializationTokenChain)\n\t\t\t\tcxxTokenChainClear(g_cxx.pTemplateSpecializationTokenChain);\n\t\t\telse\n\t\t\t\tg_cxx.pTemplateSpecializationTokenChain = cxxTokenChainCreate();\n\t\t\tcxxTokenChainAppend(g_cxx.pTemplateSpecializationTokenChain,\n\t\t\t\t\t\t\t\tpTemplateSpecialization);\n\t\t\tcxxTokenChainDestroyRange(pChain,\n\t\t\t\t\t\t\t\t\t  pTemplateSpecializationStart,\n\t\t\t\t\t\t\t\t\t  pTemplateSpecializationEnd);\n\t\t\tpTemplateSpecializationStart = pTemplateSpecializationEnd = NULL;\n\t\t}\n\ngot_identifier:\n\t\tCXX_DEBUG_ASSERT(pIdentifier,\"We should have found an identifier here\");\n\n\t\tif(!pTokenBefore)\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Identifier not preceded by a type\");\n\t\t\t// Here we can handle yet another one of the gazillion of special cases.\n\t\t\t//\n\t\t\t//    MACRO(whatever) variable;\n\t\t\t//\n\t\t\tif(\n\t\t\t\t\tcxxTokenTypeIs(t,CXXTokenTypeParenthesisChain) &&\n\t\t\t\t\tt->pNext &&\n\t\t\t\t\tcxxTokenTypeIs(t->pNext,CXXTokenTypeIdentifier) &&\n\t\t\t\t\tt->pNext->pNext &&\n\t\t\t\t\tcxxTokenTypeIs(t->pNext->pNext,CXXTokenTypeSemicolon)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_PRINT(\"Looks like the 'MACRO(whatever) variable;' special case\");\n\t\t\t\tpIdentifier = t->pNext;\n\t\t\t\tpTokenBefore = t;\n\t\t\t\tt = t->pNext->pNext;\n\t\t\t} else {\n\t\t\t\treturn bGotVariable;\n\t\t\t}\n\t\t}\n\n\t\tCXXToken * pScopeEnd = pTokenBefore->pNext;\n\t\tCXXToken * pScopeStart = NULL;\n\n\t\t// Skip back to the beginning of the scope, if any\n\t\twhile(cxxTokenTypeIs(pTokenBefore, CXXTokenTypeMultipleColons))\n\t\t{\n\t\t\tif(!cxxParserCurrentLanguageIsCPP())\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Syntax error: found multiple colons in C language\");\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tpTokenBefore = pTokenBefore->pPrev;\n\t\t\tif(!pTokenBefore)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\"Identifier preceded by multiple colons \" \\\n\t\t\t\t\t\t\t\"but not preceded by a type\"\n\t\t\t\t\t);\n\t\t\t\treturn bGotVariable;\n\t\t\t}\n\n\t\t\tif(cxxTokenTypeIs(pTokenBefore,CXXTokenTypeGreaterThanSign))\n\t\t\t{\n\t\t\t\tCXXToken * pAux = cxxTokenChainSkipBackToStartOfTemplateAngleBracket(pTokenBefore);\n\t\t\t\tif((!pAux) || (!pAux->pPrev))\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\t\"Identifier preceded by multiple colons \" \\\n\t\t\t\t\t\t\t\t\"and by a >, but failed to skip back to starting <\"\n\t\t\t\t\t\t);\n\t\t\t\t\treturn bGotVariable;\n\t\t\t\t}\n\n\t\t\t\tpTokenBefore = pAux->pPrev;\n\t\t\t}\n\n\t\t\tif(!cxxTokenTypeIs(pTokenBefore,CXXTokenTypeIdentifier))\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\"Identifier preceded by multiple colons \" \\\n\t\t\t\t\t\t\t\"with probable syntax error\"\n\t\t\t\t\t);\n\t\t\t\treturn bGotVariable;\n\t\t\t}\n\n\t\t\tpScopeStart = pTokenBefore;\n\n\t\t\tpTokenBefore = pTokenBefore->pPrev;\n\t\t\tif(!pTokenBefore)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\"Identifier preceded by multiple colons \" \\\n\t\t\t\t\t\t\t\"but not preceded by a type\"\n\t\t\t\t\t);\n\t\t\t\treturn bGotVariable;\n\t\t\t}\n\t\t}\n\n\t\tif(!bGotVariable)\n\t\t{\n\t\t\t// now pTokenBefore should be part of a type (either the variable type or return\n\t\t\t// type of a function in case of a function pointer)\n\t\t\tif(!cxxTokenTypeIsOneOf(\n\t\t\t\t\tpTokenBefore,\n\t\t\t\t\tCXXTokenTypeIdentifier | CXXTokenTypeKeyword |\n\t\t\t\t\t\tCXXTokenTypeStar | CXXTokenTypeAnd\n\t\t\t\t))\n\t\t\t{\n\t\t\t\tif(cxxTokenTypeIs(pTokenBefore,CXXTokenTypeGreaterThanSign))\n\t\t\t\t{\n\t\t\t\t\t// the < > must be balanced\n\t\t\t\t\tCXXToken * t2 = pTokenBefore->pPrev;\n\t\t\t\t\tint iLevel = 1;\n\t\t\t\t\twhile(t2)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(cxxTokenTypeIs(t2,CXXTokenTypeGreaterThanSign))\n\t\t\t\t\t\t\tiLevel++;\n\t\t\t\t\t\telse if(cxxTokenTypeIs(t2,CXXTokenTypeSmallerThanSign))\n\t\t\t\t\t\t\tiLevel--;\n\t\t\t\t\t\tt2 = t2->pPrev;\n\t\t\t\t\t}\n\t\t\t\t\tif(iLevel != 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\t\t\"The > token is unbalanced and does not \" \\\n\t\t\t\t\t\t\t\t\t\"seem to be part of type name\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn bGotVariable;\n\t\t\t\t\t}\n\t\t\t\t} else if(\n\t\t\t\t\t\t// Possibly one of:\n\t\t\t\t\t\t//   MACRO(whatever) variable;\n\t\t\t\t\t\t//   decltype(whatever) variable;\n\t\t\t\t\t\t//   __typeof(whatever) variable;\n\t\t\t\t\t\t//   __typeof__(whatever) variable;\n\t\t\t\t\t\t//   typeof(whatever) variable;\n\t\t\t\t\t\tcxxTokenTypeIs(pTokenBefore,CXXTokenTypeParenthesisChain) &&\n\t\t\t\t\t\tpTokenBefore->pPrev &&\n\t\t\t\t\t\t(!pTokenBefore->pPrev->pPrev ||\n\t\t\t\t\t\t (\n\t\t\t\t\t\t\t cxxTokenTypeIs(pTokenBefore->pPrev->pPrev,CXXTokenTypeKeyword) &&\n\t\t\t\t\t\t\t cxxKeywordMayAppearInVariableDeclaration(pTokenBefore->pPrev->pPrev->eKeyword)\n\t\t\t\t\t\t )\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t// macro\n\t\t\t\t\t\t\tcxxTokenTypeIs(pTokenBefore->pPrev,CXXTokenTypeIdentifier) ||\n\t\t\t\t\t\t\t// decltype or typeof\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tcxxTokenTypeIs(pTokenBefore->pPrev,CXXTokenTypeKeyword) &&\n\t\t\t\t\t\t\t\tcxxKeywordIsDecltype(pTokenBefore->pPrev->eKeyword)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_PRINT(\"Type seems to be hidden in a macro or defined by decltype\");\n\t\t\t\t} else {\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\n\t\t\t\t\t\t\t\"Token '%s' of type 0x%02x does not seem \" \\\n\t\t\t\t\t\t\t\t\"to be part of type name\",\n\t\t\t\t\t\t\tvStringValue(pTokenBefore->pszWord),\n\t\t\t\t\t\t\tpTokenBefore->eType\n\t\t\t\t\t\t);\n\t\t\t\t\treturn bGotVariable;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbGotVariable = true;\n\t\t}\n\n\t\t// Goodie. We have an identifier and almost certainly a type here.\n\n\t\t// From now on we start destroying the chain: mark the return value as true\n\t\t// so nobody else will try to extract stuff from it\n\n\t\tint iScopesPushed = 0;\n\n\t\tif(pScopeStart)\n\t\t{\n\t\t\t// Push the scopes and remove them from the chain so they are not in the way\n\t\t\twhile(pScopeStart != pScopeEnd)\n\t\t\t{\n\t\t\t\t// This is the scope id START. It might contain\n\t\t\t\t// also other tokens like in ...::A<B>::...\n\n\t\t\t\tCXXToken * pPartEnd = cxxTokenChainNextTokenOfType(\n\t\t\t\t\t\tpScopeStart,\n\t\t\t\t\t\tCXXTokenTypeMultipleColons\n\t\t\t\t\t);\n\t\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\t\tpPartEnd,\n\t\t\t\t\t\t\"We should have found multiple colons here!\"\n\t\t\t\t\t);\n\t\t\t\tCXX_DEBUG_ASSERT(\n\t\t\t\t\t\tpPartEnd->pPrev,\n\t\t\t\t\t\t\"And there should be a previous token too\"\n\t\t\t\t\t);\n\n\t\t\t\tCXXToken * pScopeId = cxxTokenChainExtractRange(pScopeStart,pPartEnd->pPrev,0);\n\t\t\t\tcxxScopePush(\n\t\t\t\t\t\tpScopeId,\n\t\t\t\t\t\tCXXScopeTypeClass,\n\t\t\t\t\t\t// WARNING: We don't know if it's really a class! (FIXME?)\n\t\t\t\t\t\tCXXScopeAccessUnknown\n\t\t\t\t\t);\n\n\t\t\t\tCXXToken * pAux = pPartEnd->pNext;\n\n\t\t\t\tcxxTokenChainDestroyRange(pChain,pScopeStart,pPartEnd);\n\n\t\t\t\tpScopeStart = pAux;\n\n\t\t\t\tiScopesPushed++;\n\t\t\t}\n\t\t}\n\n\t\tCXX_DEBUG_ASSERT(t != pIdentifier,\"This should not happen\");\n\n\t\t// remove the identifier\n\t\tcxxTokenChainTakeRecursive(pChain,pIdentifier);\n\n\t\tbool bGotTemplate = g_cxx.pTemplateTokenChain &&\n\t\t\t\t(g_cxx.pTemplateTokenChain->iCount > 0) &&\n\t\t\t\tcxxParserCurrentLanguageIsCPP();\n\n\t\tbool bKnRStyleParameters =\n\t\t\t\t(uFlags & CXXExtractVariableDeclarationsKnRStyleParameters);\n\n\t\ttagEntryInfo * tag = cxxTagBegin(\n\t\t\t\tbKnRStyleParameters ?\n\t\t\t\t\tCXXTagKindPARAMETER :\n\t\t\t\t\t((g_cxx.uKeywordState & CXXParserKeywordStateSeenExtern) ?\n\t\t\t\t\t\t\tCXXTagKindEXTERNVAR : cxxScopeGetVariableKind()),\n\t\t\t\tpIdentifier\n\t\t\t);\n\n\t\tif(tag)\n\t\t{\n\t\t\t// Fix square parentheses: if they contain something that is not a numeric\n\t\t\t// constant then empty them up\n\t\t\tCXXToken * pPartOfType = t->pPrev; // identifier has been removed\n\t\t\tCXX_DEBUG_ASSERT(pPartOfType,\"There should be a part of type name here\");\n\n\t\t\twhile(pPartOfType && cxxTokenTypeIs(pPartOfType,CXXTokenTypeSquareParenthesisChain))\n\t\t\t{\n\t\t\t\tCXXTokenChain * pAuxChain = pPartOfType->pChain;\n\n\t\t\t\tif(pAuxChain->iCount > 2)\n\t\t\t\t{\n\t\t\t\t\tif(\n\t\t\t\t\t\t(pAuxChain->iCount > 3) ||\n\t\t\t\t\t\t(!cxxTokenTypeIs(cxxTokenChainAt(pAuxChain,1),CXXTokenTypeNumber))\n\t\t\t\t\t)\n\t\t\t\t\t{\n\t\t\t\t\t\tcxxTokenChainDestroyRange(\n\t\t\t\t\t\t\t\tpAuxChain,\n\t\t\t\t\t\t\t\tcxxTokenChainFirst(pAuxChain)->pNext,\n\t\t\t\t\t\t\t\tcxxTokenChainLast(pAuxChain)->pPrev\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpPartOfType = pPartOfType->pPrev;\n\t\t\t}\n\n\t\t\t// anything that remains is part of type\n\t\t\tCXXToken * pTypeToken = cxxTagCheckAndSetTypeField(cxxTokenChainFirst(pChain),t->pPrev);\n\n\t\t\ttag->isFileScope = bKnRStyleParameters ?\n\t\t\t\t\ttrue :\n\t\t\t\t\t(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(eScopeType == CXXScopeTypeNamespace) &&\n\t\t\t\t\t\t\t(g_cxx.uKeywordState & CXXParserKeywordStateSeenStatic) &&\n\t\t\t\t\t\t\t(!(g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)) &&\n\t\t\t\t\t\t\t(!cxxScopeIsExported()) &&\n\t\t\t\t\t\t\t(!isInputHeaderFile())\n\t\t\t\t\t\t) ||\n\t\t\t\t\t\t// locals are always hidden\n\t\t\t\t\t\t(eScopeType == CXXScopeTypeFunction) ||\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(eScopeType != CXXScopeTypeNamespace) &&\n\t\t\t\t\t\t\t(eScopeType != CXXScopeTypeFunction) &&\n\t\t\t\t\t\t\t(!(g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)) &&\n\t\t\t\t\t\t\t(!cxxScopeIsExported()) &&\n\t\t\t\t\t\t\t(!isInputHeaderFile())\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\n\t\t\tvString * pszProperties = NULL;\n\n\t\t\tif(cxxTagFieldEnabled(CXXTagFieldProperties))\n\t\t\t{\n\t\t\t\tunsigned int uProperties = 0;\n\n\t\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenStatic)\n\t\t\t\t\tuProperties |= CXXTagPropertyStatic;\n\t\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenExtern)\n\t\t\t\t\tuProperties |= CXXTagPropertyExtern;\n\t\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenMutable)\n\t\t\t\t\tuProperties |= CXXTagPropertyMutable;\n\t\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenInline)\n\t\t\t\t\tuProperties |= CXXTagPropertyInline;\n\t\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenAttributeDeprecated)\n\t\t\t\t\tuProperties |= CXXTagPropertyDeprecated;\n\t\t\t\t// Volatile is part of the type, so we don't mark it as a property\n\t\t\t\t//if(g_cxx.uKeywordState & CXXParserKeywordStateSeenVolatile)\n\t\t\t\t//\tuProperties |= CXXTagPropertyVolatile;\n\t\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenConstexpr)\n\t\t\t\t\tuProperties |= CXXTagPropertyConstexpr;\n\t\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenConstinit)\n\t\t\t\t\tuProperties |= CXXTagPropertyConstinit;\n\t\t\t\t// consteval is not here; it is for functions.\n\t\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenThreadLocal)\n\t\t\t\t\tuProperties |= CXXTagPropertyThreadLocal;\n\t\t\t\tif(g_cxx.uKeywordState & CXXParserKeywordStateSeenExport)\n\t\t\t\t\tuProperties |= CXXTagPropertyExport;\n\t\t\t\tif(bSpecializedAsVarTemplate)\n\t\t\t\t\tuProperties |= CXXTagPropertyTemplateSpecialization;\n\n\t\t\t\tpszProperties = cxxTagSetProperties(uProperties);\n\t\t\t}\n\n\t\t\tif(bGotTemplate)\n\t\t\t\tcxxTagHandleTemplateFields();\n\n\t\t\tcxxSideChainCollectInRange(cxxTokenChainFirst(pChain), pEndScanningAttrs,\n\t\t\t\t\t\t\t\t\t   pIdentifier);\n\t\t\tcxxSideChainScan(pIdentifier->pSideChain);\n\n\t\t\tiCorkIndex = cxxTagCommit(&iCorkIndexFQ);\n\t\t\tcxxTagUseTokenAsPartOfDefTag(iCorkIndexFQ, pIdentifier);\n\n\t\t\tif(pTypeToken)\n\t\t\t\tcxxTokenDestroy(pTypeToken);\n\t\t\tif(pszProperties)\n\t\t\t\tvStringDelete(pszProperties);\n\t\t}\n\n\t\tif(\n\t\t\t\tbGotTemplate &&\n\t\t\t\tcxxTagKindEnabled(CXXTagCPPKindTEMPLATEPARAM)\n\t\t\t)\n\t\t{\n\t\t\tcxxScopePush(pIdentifier,CXXScopeTypeVariable,CXXScopeAccessPublic);\n\t\t\t// We don't have to propagate the exported status to language objects\n\t\t\t// under a variable.\n\n\t\t\tcxxParserEmitTemplateParameterTags();\n\t\t\tcxxScopePop();\n\t\t} else {\n\t\t\tcxxTokenDestroy(pIdentifier);\n\t\t}\n\n\t\twhile(iScopesPushed > 0)\n\t\t{\n\t\t\tcxxScopePop();\n\t\t\tiScopesPushed--;\n\t\t}\n\n\t\tif(!t)\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Nothing more\");\n\t\t\treturn bGotVariable;\n\t\t}\n\n\t\tif(!cxxTokenTypeIsOneOf(\n\t\t\t\tt,\n\t\t\t\tCXXTokenTypeComma | CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket\n\t\t\t))\n\t\t{\n\t\t\t// look for it, but also check for \"<\" signs: these usually indicate an uncondensed\n\t\t\t// template. We give up on them as they are too complicated in this context.\n\t\t\t// It's rather unlikely to have multiple declarations with templates after the first one\n\t\t\tt = cxxTokenChainNextTokenOfType(\n\t\t\t\t\tt,\n\t\t\t\t\tCXXTokenTypeComma | CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket |\n\t\t\t\t\tCXXTokenTypeSmallerThanSign\n\t\t\t\t);\n\t\t\tif(!t)\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Didn't find a comma, semicolon or {\");\n\t\t\t\treturn bGotVariable;\n\t\t\t}\n\t\t\tif(cxxTokenTypeIs(t,CXXTokenTypeSmallerThanSign))\n\t\t\t{\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Found '<': probably a template on the right side of declaration\");\n\t\t\t\treturn bGotVariable;\n\t\t\t}\n\t\t}\n\n\t\tif(cxxTokenTypeIsOneOf(t,CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket))\n\t\t{\n\t\t\tif (iCorkIndex != CORK_NIL)\n\t\t\t{\n\t\t\t\tcxxParserSetEndLineForTagInCorkQueue (iCorkIndex, t->iLineNumber);\n\t\t\t\tcxxSubparserNotifyVariableBodyMaybe (iCorkIndex, t);\n\t\t\t\tiCorkIndex = CORK_NIL;\n\t\t\t\tif(iCorkIndexFQ != CORK_NIL)\n\t\t\t\t{\n\t\t\t\t\tcxxParserSetEndLineForTagInCorkQueue (iCorkIndexFQ, t->iLineNumber);\n\t\t\t\t\tiCorkIndexFQ = CORK_NIL;\n\t\t\t\t}\n\t\t\t}\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Noting else\");\n\t\t\treturn bGotVariable;\n\t\t}\n\n\t\t// Comma. Might have other declarations here.\n\t\tif (iCorkIndex != CORK_NIL)\n\t\t{\n\t\t\tcxxParserSetEndLineForTagInCorkQueue (iCorkIndex, t->iLineNumber);\n\t\t\tiCorkIndex = CORK_NIL;\n\t\t\tif(iCorkIndexFQ != CORK_NIL)\n\t\t\t{\n\t\t\t\tcxxParserSetEndLineForTagInCorkQueue (iCorkIndexFQ, t->iLineNumber);\n\t\t\t\tiCorkIndexFQ = CORK_NIL;\n\t\t\t}\n\t\t}\n\n\t\tCXX_DEBUG_PRINT(\"At a comma, might have other declarations here\");\n\n\t\tt = t->pNext;\n\n\t\tCXX_DEBUG_ASSERT(t,\"There should be something after the comma here!\");\n\n\t\tif(!pRemoveStart)\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Could not properly fix type name for next token: stopping here\");\n\t\t\treturn bGotVariable;\n\t\t}\n\n\t\t// *, &, && and similar stuff do not \"propagate\" to the next type\n\t\twhile(\n\t\t\t\tpRemoveStart->pPrev &&\n\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\tpRemoveStart->pPrev,\n\t\t\t\t\t\tCXXTokenTypeStar | CXXTokenTypeAnd |\n\t\t\t\t\t\tCXXTokenTypeMultipleAnds | CXXTokenTypeSquareParenthesisChain\n\t\t\t\t\t)\n\t\t\t)\n\t\t\tpRemoveStart = pRemoveStart->pPrev;\n\n\t\tcxxTokenChainDestroyRange(pChain,pRemoveStart,t->pPrev);\n\t}\n\n\tCXX_DEBUG_LEAVE_TEXT(\"Reached end\");\n\treturn bGotVariable;\n}\n\nstatic bool isConstVolatileOrStar (CXXToken *t, void *data)\n{\n\tif (cxxTokenTypeIs (t, CXXTokenTypeStar))\n\t\treturn true;\n\n\tif (cxxTokenTypeIs (t, CXXTokenTypeKeyword) &&\n\t\t((t->eKeyword == CXXKeywordCONST) ||\n\t\t (t->eKeyword == CXXKeywordVOLATILE)))\n\t\treturn true;\n\n\treturn false;\n}\n\nstatic CXXToken * cxxParserVardefInParenthesis (CXXToken *pToken, int depth)\n{\n\t// ( const volatile * foo [] ) <- ended with CXXTokenTypeSquareParenthesisChain\n\t// ( const volatile * foo ) <- ended with CXXTokenTypeClosingParenthesis\n\t// ((const volatile * foo)) <- depth > 0\n\n\tCXXToken *t;\n\n\tt = cxxTokenChainNextTokenNotOfGeneric (pToken, isConstVolatileOrStar, NULL);\n\tif (!t)\n\t\treturn NULL;\n\n\tif (cxxTokenTypeIs(t, CXXTokenTypeParenthesisChain))\n\t\treturn cxxParserVardefInParenthesis (cxxTokenChainFirst(t->pChain),\n\t\t\t\t\t\t\t\t\t\t   depth + 1);\n\telse if (cxxTokenTypeIs (t, CXXTokenTypeIdentifier) &&\n\t\t\t ((t->pNext &&\n\t\t\t   (cxxTokenTypeIsOneOf (t->pNext,\n\t\t\t\t\t\t\t\t\t CXXTokenTypeSquareParenthesisChain | CXXTokenTypeClosingParenthesis)))||\n\t\t\t  (t->pNext && depth > 0)))\n\t\treturn t;\n\treturn NULL;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_qtmoc.c",
    "content": "/*\n *  Copyright (c) 2017, Red Hat, Inc.\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for handling Qt Moc tokens\n*/\n\n#include \"general.h\"\n\n#include \"types.h\"\n\n#include \"debug.h\"\n#include \"cxx_debug.h\"\n\n#include \"cxx_scope.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"cxx_subparser.h\"\n\n#include \"keyword.h\"\n#include \"read.h\"\n\n#include <string.h>\n\n\ntypedef enum {\n\tK_SLOT,\n\tK_SIGNAL,\n\tK_PROPERTY,\n} qtMocKind;\n\nstatic kindDefinition QtMocKinds [] = {\n\t{ true, 's', \"slot\", \"slots\" },\n\t{ true, 'S', \"signal\", \"signals\" },\n\t{ true, 'p', \"property\", \"properties\" },\n};\n\nenum {\n\tKEYWORD_QOBJECT,\n\tKEYWORD_SIGNALS,\n\tKEYWORD_SLOTS,\n\tKEYWORD_PROPERTY,\n};\n\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\nstatic const keywordTable QtMocKeywordTable[] = {\n\t/* keyword\t\t\tkeyword ID */\n\t{ \"Q_OBJECT\",\tKEYWORD_QOBJECT  },\n\t{ \"Q_SIGNALS\",\tKEYWORD_SIGNALS\t },\n\t{ \"signals\",\tKEYWORD_SIGNALS\t },\n\t{ \"Q_SLOTS\",\tKEYWORD_SLOTS\t },\n\t{ \"slots\",\t\tKEYWORD_SLOTS\t },\n\t{ \"Q_PROPERTY\", KEYWORD_PROPERTY },\n};\n\nenum QtMocMemberMarker\n{\n\tQtMocMemberMarkerNone = 0,\n\tQtMocMemberMarkerSlot,\n\tQtMocMemberMarkerSignal,\n};\n\nstruct sQtMocSubparser {\n\tstruct sCxxSubparser cxx;\n\tint iBlockDepth;\n\tint iDepthOfQtClass;\n\tenum QtMocMemberMarker eMemberMarker;\n};\n\nstatic langType Lang_QtMoc;\n\nstatic bool cxxParserSkipToClosingParenthesisOrEOF(void)\n{\n\tif(cxxTokenTypeIsOneOf(g_cxx.pToken,CXXTokenTypeClosingParenthesis | CXXTokenTypeEOF))\n\t\treturn true;\n\n\treturn cxxParserParseUpToOneOf(CXXTokenTypeClosingParenthesis | CXXTokenTypeEOF,\n\t\t\t\t\t\t\t\t   false);\n}\n\nstatic void qtMocMakeTagForProperty (CXXToken * pToken, const char *pszType)\n{\n\ttagEntryInfo tag;\n\n\tinitTagEntry(&tag,\n\t\t\t\t vStringValue(pToken->pszWord),\n\t\t\t\t K_PROPERTY);\n\tupdateTagLine (&tag, pToken->iLineNumber, pToken->oFilePosition);\n\ttag.isFileScope = false;\n\n\tif(!cxxScopeIsGlobal())\n\t{\n\t\ttag.extensionFields.scopeLangType = getNamedLanguage (\"C++\", 0); /* ??? */\n\t\ttag.extensionFields.scopeKindIndex = cxxScopeGetKind();\n\t\ttag.extensionFields.scopeName = cxxScopeGetFullName();\n\t}\n\n\ttag.extensionFields.typeRef[0] = \"typename\";\n\ttag.extensionFields.typeRef[1] = pszType;\n\n\tmakeTagEntry(&tag);\n}\n\nstatic bool qtMocParseProperty(void)\n{\n\tchar *pszPropType;\n\n\tCXX_DEBUG_ENTER();\n\n\tif(!cxxParserParseNextToken())\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF in cxxParserParseNextToken\");\n\t\treturn false;\n\t}\n\tif (!cxxTokenTypeIs(g_cxx.pToken, CXXTokenTypeOpeningParenthesis))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Found no Opening Parenthesis after Q_PROPERTY\");\n\t\treturn false;\n\t}\n\n\tif (!cxxParserParseNextToken())\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF in cxxParserParseNextToken\");\n\t\treturn false;\n\t}\n\tif (!(cxxTokenTypeIs(g_cxx.pToken, CXXTokenTypeIdentifier)\n\t\t  || (cxxTokenTypeIs(g_cxx.pToken, CXXTokenTypeKeyword)\n\t\t\t  && cxxKeywordMayBePartOfTypeName (g_cxx.pToken->eKeyword))))\n\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Found no identifier after Q_PROPERTY(\");\n\n\t\tcxxParserSkipToClosingParenthesisOrEOF ();\n\t\treturn false;\n\t}\n\n\tpszPropType = vStringStrdup (g_cxx.pToken->pszWord);\n\tif(!cxxParserParseNextToken())\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"EOF in cxxParserParseNextToken\");\n\t\teFree (pszPropType);\n\t\treturn false;\n\t}\n\n\tif (!cxxTokenTypeIs(g_cxx.pToken, CXXTokenTypeIdentifier))\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Found no identifier after Q_PROPERTY(%s\", pszPropType);\n\t\tcxxParserSkipToClosingParenthesisOrEOF ();\n\t\teFree (pszPropType);\n\t\treturn false;\n\t}\n\n\tqtMocMakeTagForProperty (g_cxx.pToken, pszPropType);\n\n\teFree (pszPropType);\n\tcxxParserSkipToClosingParenthesisOrEOF ();\n\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\nstatic void inputStart(subparser *s)\n{\n\tstruct sQtMocSubparser *pQtMoc = (struct sQtMocSubparser*)s;\n\n\tpQtMoc->iBlockDepth = 0;\n\tpQtMoc->iDepthOfQtClass = 0;\n\tpQtMoc->eMemberMarker = QtMocMemberMarkerNone;\n}\n\nstatic void makeTagEntryNotify (subparser *s, const tagEntryInfo *entry, int corkIndex)\n{\n\tstruct sQtMocSubparser *pQtMoc = (struct sQtMocSubparser*)s;\n\n\tif (pQtMoc->iDepthOfQtClass == 0)\n\t\treturn;\n\n\tif ((pQtMoc->eMemberMarker != QtMocMemberMarkerNone) &&\n\t\tentry->kindIndex == CXXTagKindPROTOTYPE)\n\t{\n\t\ttagEntryInfo parasiteTag = *entry;\n\t\tparasiteTag.langType = getInputLanguage ();\n\t\tparasiteTag.kindIndex = (pQtMoc->eMemberMarker == QtMocMemberMarkerSlot)\n\t\t\t? K_SLOT\n\t\t\t: K_SIGNAL;\n\n\t\tparasiteTag.extensionFields.scopeLangType = entry->langType;\n\t\tmakeTagEntry (&parasiteTag);\n\t}\n}\n\nstatic void enterBlockNotify (struct sCxxSubparser *pSubparser)\n{\n\tstruct sQtMocSubparser *pQtMoc = (struct sQtMocSubparser *)pSubparser;\n\n\tpQtMoc->iBlockDepth++;\n}\n\nstatic void leaveBlockNotify (struct sCxxSubparser *pSubparser)\n{\n\tstruct sQtMocSubparser *pQtMoc = (struct sQtMocSubparser *)pSubparser;\n\n\tif (pQtMoc->iDepthOfQtClass == pQtMoc->iBlockDepth)\n\t\tpQtMoc->iDepthOfQtClass = 0;\n\n\tpQtMoc->iBlockDepth--;\n}\n\nstatic bool newIdentifierAsHeadOfMemberNotify (struct sCxxSubparser *pSubparser,\n\t\t\t\t\t\t\t\t\t\t\t   CXXToken *pToken)\n{\n\tstruct sQtMocSubparser *pQtMoc = (struct sQtMocSubparser *)pSubparser;\n\tkeywordId keyword = lookupKeyword (vStringValue (pToken->pszWord), Lang_QtMoc);\n\n\tif (keyword == KEYWORD_QOBJECT)\n\t{\n\t\tif (pQtMoc->iDepthOfQtClass == 0)\n\t\t\tpQtMoc->iDepthOfQtClass = pQtMoc->iBlockDepth;\n\t\tCXX_DEBUG_PRINT(\"Found \\\"Q_OBJECT\\\" Qt Object Marker in depth: %d\",\n\t\t\t\t\t\tpQtMoc->iDepthOfQtClass);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic bool unknownIdentifierInClassNotify (struct sCxxSubparser *pSubparser,\n\t\t\t\t\t\t\t\t\t\t\tCXXToken *pToken)\n{\n\tstruct sQtMocSubparser *pQtMoc = (struct sQtMocSubparser *)pSubparser;\n\n\tif (pQtMoc->iDepthOfQtClass == 0)\n\t\treturn false;\n\n\tkeywordId keyword = lookupKeyword (vStringValue (pToken->pszWord), Lang_QtMoc);\n\n\tswitch (keyword)\n\t{\n\tcase KEYWORD_SIGNALS:\n\t\tCXX_DEBUG_PRINT(\"Found \\\"signals\\\" QtMoc Keyword\");\n\t\tpToken->eType = CXXTokenTypeKeyword;\n\t\tpToken->eKeyword = CXXKeywordPUBLIC;\n\t\tcxxParserParseAccessSpecifier();\n\t\tpQtMoc->eMemberMarker = QtMocMemberMarkerSignal;\n\t\treturn true;\n\tcase KEYWORD_SLOTS:\n\t\tCXX_DEBUG_PRINT(\"Found \\\"slots\\\" QtMoc Keyword\");\n\t\tpToken->eType = CXXTokenTypeKeyword;\n\t\tg_cxx.pToken->eKeyword = CXXKeywordPUBLIC; /* ??? */\n\t\tcxxParserParseAccessSpecifier();\n\t\tpQtMoc->eMemberMarker = QtMocMemberMarkerSlot;\n\t\treturn true;\n\tcase KEYWORD_PROPERTY:\n\t\tCXX_DEBUG_PRINT(\"Found \\\"Q_PROPERTY\\\" QtMoc Keyword\");\n\t\tqtMocParseProperty ();\n\t\treturn true;\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn false;\n}\n\nstatic bool parseAccessSpecifierNotify(struct sCxxSubparser *pSubparser)\n{\n\tstruct sQtMocSubparser *pQtMoc = (struct sQtMocSubparser *)pSubparser;\n\n\tif (pQtMoc->iBlockDepth > 0)\n\t{\n\t\tCXX_DEBUG_PRINT(\"Reset QtMoc member marker state\");\n\t\tpQtMoc->eMemberMarker = QtMocMemberMarkerNone;\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic void foundExtraIdentifierAsAccessSpecifier(struct sCxxSubparser *pSubparser,\n\t\t\t\t\t\t\t\t\t\t\t\t  CXXToken *pToken)\n{\n\tstruct sQtMocSubparser *pQtMoc = (struct sQtMocSubparser *)pSubparser;\n\tkeywordId keyword = lookupKeyword (vStringValue (pToken->pszWord), Lang_QtMoc);\n\n\tif (keyword == KEYWORD_SLOTS)\n\t{\n\t\tCXX_DEBUG_PRINT(\"Found \\\"slots\\\" QtMoc Keyword\");\n\t\tpQtMoc->eMemberMarker = QtMocMemberMarkerSlot;\n\t}\n}\n\nstatic void findQtMocTags(void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nstatic void initialize (langType lang)\n{\n\tLang_QtMoc = lang;\n}\n\nextern parserDefinition* QtMocParser (void)\n{\n\tparserDefinition* const def = parserNew(\"QtMoc\");\n\n\tstatic struct sQtMocSubparser qtMocSubparser = {\n\t\t.cxx = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t\t\t.inputStart = inputStart,\n\t\t\t\t.makeTagEntryNotify = makeTagEntryNotify,\n\t\t\t},\n\t\t\t.enterBlockNotify = enterBlockNotify,\n\t\t\t.leaveBlockNotify = leaveBlockNotify,\n\t\t\t.newIdentifierAsHeadOfMemberNotify = newIdentifierAsHeadOfMemberNotify,\n\t\t\t.unknownIdentifierInClassNotify = unknownIdentifierInClassNotify,\n\t\t\t.parseAccessSpecifierNotify = parseAccessSpecifierNotify,\n\t\t\t.foundExtraIdentifierAsAccessSpecifier = foundExtraIdentifierAsAccessSpecifier,\n\t\t}\n\t\t/* The rest fields are initialized in inputStart(). */\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"C++\", &qtMocSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = QtMocKinds;\n\tdef->kindCount = ARRAY_SIZE(QtMocKinds);\n\n\tdef->keywordTable = QtMocKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (QtMocKeywordTable);\n\n\tdef->parser = findQtMocTags;\n\tdef->initialize = initialize;\n\tdef->useCork = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_scope.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"cxx_scope.h\"\n\n#include \"vstring.h\"\n#include \"debug.h\"\n\n#include \"cxx_tag.h\"\n#include \"cxx_debug.h\"\n#include \"cxx_token_chain.h\"\n\n#ifdef CXX_DO_DEBUGGING\n#include \"cxx_parser_internal.h\"\n#endif\n\n// The tokens defining current scope\nstatic CXXTokenChain * g_pScope = NULL;\nstatic vString * g_szScopeName = NULL;\nstatic bool g_bScopeNameDirty = true;\n\nvoid cxxScopeInit(void)\n{\n\tg_pScope = cxxTokenChainCreate();\n}\n\nvoid cxxScopeDone(void)\n{\n\tcxxTokenChainDestroy(g_pScope);\n\tif(g_szScopeName)\n\t{\n\t\tvStringDelete(g_szScopeName);\n\t\tg_szScopeName = NULL;\n\t}\n}\n\nvoid cxxScopeClear(void)\n{\n\tif(g_pScope)\n\t\tcxxTokenChainClear(g_pScope);\n\tif(g_szScopeName)\n\t{\n\t\tvStringDelete(g_szScopeName);\n\t\tg_szScopeName = NULL;\n\t}\n}\n\nbool cxxScopeIsGlobal(void)\n{\n\treturn (g_pScope->iCount < 1);\n}\n\nbool cxxScopeIsExported(void)\n{\n\tif (g_pScope->pTail)\n\t\treturn g_pScope->pTail->bInternalScopeExported;\n\treturn false;\n}\n\nenum CXXScopeType cxxScopeGetType(void)\n{\n\tif(g_pScope->iCount < 1)\n\t\treturn CXXScopeTypeNamespace;\n\treturn (enum CXXScopeType)g_pScope->pTail->uInternalScopeType;\n}\n\nunsigned int cxxScopeGetVariableKind(void)\n{\n\tswitch(cxxScopeGetType())\n\t{\n\t\tcase CXXScopeTypeClass:\n\t\tcase CXXScopeTypeUnion:\n\t\tcase CXXScopeTypeStruct:\n\t\t\treturn CXXTagKindMEMBER;\n\t\tbreak;\n\t\tcase CXXScopeTypeFunction:\n\t\t\treturn CXXTagKindLOCAL;\n\t\tbreak;\n\t\t//case CXXScopeTypePrototype:\n\t\t//case CXXScopeTypeNamespace:\n\t\t//case CXXScopeTypeEnum:\n\t\tdefault:\n\t\t\t// fall down\n\t\tbreak;\n\t}\n\treturn CXXTagKindVARIABLE;\n}\n\n\nunsigned int cxxScopeGetKind(void)\n{\n\tCXX_DEBUG_ASSERT(g_pScope->iCount >= 0,\"Must not be called in global scope\");\n\n\tswitch(g_pScope->pTail->uInternalScopeType)\n\t{\n\t\tcase CXXScopeTypeNamespace:\n\t\t\tCXX_DEBUG_ASSERT(cxxParserCurrentLanguageIsCPP(),\"C++ only\");\n\t\t\treturn CXXTagCPPKindNAMESPACE;\n\t\tcase CXXScopeTypeClass:\n\t\t\tCXX_DEBUG_ASSERT(cxxParserCurrentLanguageIsCPP(),\"C++ only\");\n\t\t\treturn CXXTagCPPKindCLASS;\n\t\tcase CXXScopeTypeEnum:\n\t\t\treturn CXXTagKindENUM;\n\t\tcase CXXScopeTypeFunction:\n\t\t\treturn CXXTagKindFUNCTION;\n\t\tcase CXXScopeTypePrototype:\n\t\t\treturn CXXTagKindPROTOTYPE;\n\t\tcase CXXScopeTypeStruct:\n\t\t\treturn CXXTagKindSTRUCT;\n\t\tcase CXXScopeTypeUnion:\n\t\t\treturn CXXTagKindUNION;\n\t\tcase CXXScopeTypeVariable:\n\t\t\treturn CXXTagKindVARIABLE;\n\t\tcase CXXScopeTypeTypedef:\n\t\t\treturn CXXTagKindTYPEDEF;\n\t\tcase CXXScopeTypeModule:\n\t\t\treturn CXXTagCPPKindMODULE;\n\t\tdefault:\n\t\t\tCXX_DEBUG_ASSERT(false,\"Unhandled scope type!\");\n\t\t\tbreak;\n\t}\n\n\treturn CXXTagKindFUNCTION;\n}\n\n\nenum CXXScopeAccess cxxScopeGetAccess(void)\n{\n\tif(g_pScope->iCount < 1)\n\t\treturn CXXScopeAccessUnknown;\n\treturn (enum CXXScopeAccess)g_pScope->pTail->uInternalScopeAccess;\n}\n\nconst char * cxxScopeGetName(void)\n{\n\tif(g_pScope->iCount < 1)\n\t\treturn NULL;\n\treturn vStringValue(g_pScope->pTail->pszWord);\n}\n\nint cxxScopeGetDefTag(void)\n{\n\tif(g_pScope->iCount < 1)\n\t\treturn CORK_NIL;\n\treturn g_pScope->pTail->iCorkIndex;\n}\n\nint cxxScopeGetSize(void)\n{\n\treturn g_pScope->iCount;\n}\n\nconst char * cxxScopeGetFullName(void)\n{\n\tif(!g_bScopeNameDirty)\n\t\treturn g_szScopeName ? vStringValue(g_szScopeName): NULL;\n\n\tif(g_pScope->iCount < 1)\n\t{\n\t\tg_bScopeNameDirty = false;\n\t\treturn NULL;\n\t}\n\n\tg_szScopeName = vStringNewOrClear(g_szScopeName);\n\n\tcxxTokenChainJoinInString(\n\t\t\tg_pScope,\n\t\t\tg_szScopeName,\n\t\t\t\"::\",\n\t\t\tCXXTokenChainJoinNoTrailingSpaces\n\t\t);\n\n\tg_bScopeNameDirty = false;\n\treturn vStringValue(g_szScopeName);\n}\n\nvString * cxxScopeGetFullNameAsString(void)\n{\n\tvString * ret;\n\n\tif(!g_bScopeNameDirty)\n\t{\n\t\tret = g_szScopeName;\n\t\tg_szScopeName = NULL;\n\t\tg_bScopeNameDirty = true;\n\t\treturn ret;\n\t}\n\n\tif(g_pScope->iCount < 1)\n\t\treturn NULL;\n\n\tg_szScopeName = vStringNewOrClear(g_szScopeName);\n\n\tcxxTokenChainJoinInString(\n\t\t\tg_pScope,\n\t\t\tg_szScopeName,\n\t\t\t\"::\",\n\t\t\tCXXTokenChainJoinNoTrailingSpaces\n\t\t);\n\n\tret = g_szScopeName;\n\tg_szScopeName = NULL;\n\treturn ret;\n}\n\nvString * cxxScopeGetFullNameExceptLastComponentAsString(void)\n{\n\tif(g_pScope->iCount < 2)\n\t\treturn NULL;\n\n\treturn cxxTokenChainJoinRange(\n\t\t\tg_pScope->pHead,\n\t\t\tg_pScope->pTail->pPrev,\n\t\t\t\"::\",\n\t\t\tCXXTokenChainJoinNoTrailingSpaces\n\t\t);\n}\n\n\nvoid cxxScopeSetAccess(enum CXXScopeAccess eAccess)\n{\n\tif(g_pScope->iCount < 1)\n\t\treturn; // warning?\n\tg_pScope->pTail->uInternalScopeAccess = (unsigned char)eAccess;\n}\n\nvoid cxxScopePushTop(CXXToken * t)\n{\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(t, CXXTokenTypeIdentifier),\n\t\t\t\"The scope name must be an identifier\"\n\t\t);\n\tCXX_DEBUG_ASSERT(\n\t\t\tt->pszWord,\n\t\t\t\"The scope name should have a text\"\n\t\t);\n\n\t// Inherit the export'ed status from the parent scope.\n\t// You can override the inherited status with cxxScopePushExported().\n\tif (g_pScope->pTail && g_pScope->pTail->bInternalScopeExported)\n\t\tt->bInternalScopeExported = true;\n\n\tcxxTokenChainAppend(g_pScope,t);\n\tg_bScopeNameDirty = true;\n\n#ifdef CXX_DO_DEBUGGING\n\tconst char * szScopeName = cxxScopeGetFullName();\n\n\tCXX_DEBUG_PRINT(\"Pushed scope: '%s'\",szScopeName ? szScopeName : \"\");\n#endif\n}\n\nCXXToken * cxxScopeTakeTop(void)\n{\n\tCXX_DEBUG_ASSERT(\n\t\t\tg_pScope->iCount > 0,\n\t\t\t\"When popping as scope there must be a scope to pop\"\n\t\t);\n\n\tCXXToken * t = cxxTokenChainTakeLast(g_pScope);\n\tg_bScopeNameDirty = true;\n\n#ifdef CXX_DO_DEBUGGING\n\tconst char * szScopeName = cxxScopeGetFullName();\n\n\tCXX_DEBUG_PRINT(\"Popped scope: '%s'\",szScopeName ? szScopeName : \"\");\n#endif\n\treturn t;\n}\n\nvoid cxxScopePush(\n\t\tCXXToken * t,\n\t\tenum CXXScopeType eScopeType,\n\t\tenum CXXScopeAccess eInitialAccess\n\t)\n{\n\tt->uInternalScopeType = (unsigned char)eScopeType;\n\tt->uInternalScopeAccess = (unsigned char)eInitialAccess;\n\tcxxScopePushTop(t);\n}\n\nvoid cxxScopePushExported(\n\t\tCXXToken * t,\n\t\tenum CXXScopeType eScopeType,\n\t\tenum CXXScopeAccess eInitialAccess,\n\t\tbool exported\n\t)\n{\n\tcxxScopePush(t, eScopeType, eInitialAccess);\n\t// Overrite the default value inherited from the parent scope.\n\tt->bInternalScopeExported = exported;\n}\n\nvoid cxxScopePop(void)\n{\n\tcxxTokenDestroy(cxxScopeTakeTop());\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_scope.h",
    "content": "#ifndef ctags_cxx_scope_h_\n#define ctags_cxx_scope_h_\n/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n\n#include \"cxx_token.h\"\n\nenum CXXScopeAccess\n{\n\tCXXScopeAccessUnknown,\n\tCXXScopeAccessPublic,\n\tCXXScopeAccessPrivate,\n\tCXXScopeAccessProtected\n};\n\nenum CXXScopeType\n{\n\tCXXScopeTypeFunction,\n\tCXXScopeTypeNamespace,\n\tCXXScopeTypeClass,\n\tCXXScopeTypeEnum,\n\tCXXScopeTypeUnion,\n\tCXXScopeTypeStruct,\n\tCXXScopeTypeVariable, // template variables, mainly\n\tCXXScopeTypePrototype,\n\tCXXScopeTypeTypedef,  // template variables used in \"using A = B<T>\"\n\tCXXScopeTypeModule,\t  // Just for filling the scope field of partitions\n\tCXXScopeTypeLAST\n};\n\nvoid cxxScopeInit(void);\nvoid cxxScopeDone(void);\nvoid cxxScopeClear(void);\n\n// Returns the full current scope name or NULL if there\n// is no scope currently.\nconst char * cxxScopeGetFullName(void);\n\n// Returns the current scope name of NULL if there is no\n// scope currently. This name does not include namespaces so\n// it is always a single identifier.\nconst char * cxxScopeGetName(void);\n\n// Return the corkIndex of the token representing currently scope.\n// This can be CORK_NIL.\nint cxxScopeGetDefTag(void);\n\n// Return the number of components of the scope name.\nint cxxScopeGetSize(void);\n\n// Returns the current scope name or NULL if there is no scope\n// currently. Ownership of the string is transferred.\nvString * cxxScopeGetFullNameAsString(void);\n\n// Returns the current scope name with the exception of the\n// last component or NULL if there is either no scope or there\n// are less than two components. Ownership of the string is transferred.\nvString * cxxScopeGetFullNameExceptLastComponentAsString(void);\n\nenum CXXScopeType cxxScopeGetType(void);\n// Returns the current scope kind\nunsigned int cxxScopeGetKind(void);\nunsigned int cxxScopeGetVariableKind(void);\nenum CXXScopeAccess cxxScopeGetAccess(void);\n// Are we in global scope?\nbool cxxScopeIsGlobal(void);\n\nbool cxxScopeIsExported(void);\n\n// Add a token to the scope chain. The token ownership is transferred.\nvoid cxxScopePush(\n\t\tCXXToken * t,\n\t\tenum CXXScopeType eScopeType,\n\t\tenum CXXScopeAccess eInitialAccess\n\t);\nvoid cxxScopePushExported(\n\t\tCXXToken * t,\n\t\tenum CXXScopeType eScopeType,\n\t\tenum CXXScopeAccess eInitialAccess,\n\t\tbool exported\n\t);\nvoid cxxScopeSetAccess(enum CXXScopeAccess eAccess);\n// Remove the last token from the scope chain\nvoid cxxScopePop(void);\n\n// Special management: pop one scope level but keep it so it can be pushed back\nCXXToken * cxxScopeTakeTop(void);\n// Special management: push back a scope taken earlier via cxxScopeTakeTop()\nvoid cxxScopePushTop(CXXToken * t);\n\n#endif //!ctags_cxx_scope_h_\n"
  },
  {
    "path": "parsers/cxx/cxx_side_chain.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for extracting information __attribute__\n*   lists.\n*/\n#include \"cxx_side_chain.h\"\n\n#include \"cxx_debug.h\"\n#include \"cxx_tag.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"entry.h\"\n\nstatic const CXXToken *cxxExtractFirstArgumentInAttrs(const CXXToken * pToken)\n{\n\tpToken = pToken->pNext;\n\n\tif(!pToken)\n\t\treturn NULL;\n\tif(!pToken->pChain)\n\t\treturn NULL;\n\n\tpToken = pToken->pChain->pHead;\n\tif(!pToken)\n\t\treturn NULL;\n\n\tif(!cxxTokenTypeIs(pToken,CXXTokenTypeOpeningParenthesis))\n\t\treturn NULL;\n\n\tpToken = pToken->pNext;\n\tif(!pToken)\n\t\treturn NULL;\n\n\tif(!cxxTokenTypeIs(pToken,CXXTokenTypeStringConstant))\n\t\treturn NULL;\n\n\treturn pToken;\n}\n\nstatic void cxxScanAttrExtractSection(const CXXToken * pToken)\n{\n\tconst CXXToken *pArgToken = cxxExtractFirstArgumentInAttrs(pToken);\n\n\tif(pArgToken == NULL)\n\t\treturn;\n\n\tAssert(vStringLength(pArgToken->pszWord));\n\n\tvStringChop(pArgToken->pszWord);\n\tcxxTagSetField(CXXTagFieldSection, vStringValue(pArgToken->pszWord)+1, true);\n\n\ttagEntryInfo e;\n\tstatic langType lang = LANG_AUTO;\n\n\tif(lang == LANG_AUTO)\n\t\tlang = getNamedLanguage(\"LdScript\", 0);\n\tif(lang == LANG_IGNORE)\n\t\tgoto out;\n\n\tstatic kindDefinition * kdef = NULL;\n\tif(kdef == NULL)\n\t\tkdef = getLanguageKindForName (lang, \"inputSection\");\n\tif(kdef == NULL)\n\t\tgoto out;\n\n\tstatic roleDefinition *rdef = NULL;\n\tif(rdef == NULL)\n\t\trdef = getLanguageRoleForName (lang, kdef->id, \"destination\");\n\tif(rdef == NULL)\n\t\tgoto out;\n\n\tinitForeignRefTagEntry(&e, vStringValue(pArgToken->pszWord)+1,\n\t\t\t\t\t\t   lang, kdef->id, rdef->id);\n\tmakeTagEntry(&e);\n\n out:\n\tvStringPut(pArgToken->pszWord, '\"');\n}\n\nstatic void cxxScanAttrExtractAlias(const CXXToken * pToken)\n{\n\tconst CXXToken *pArgToken = cxxExtractFirstArgumentInAttrs(pToken);\n\tif(pArgToken == NULL)\n\t\treturn;\n\n\tAssert(vStringLength(pArgToken->pszWord));\n\n\t// Remve doubule quote characters surrounding the constant string.\n\tvStringChop(pArgToken->pszWord);\n\tcxxTagSetField(CXXTagFieldAlias, vStringValue(pArgToken->pszWord)+1, true);\n\n\ttagEntryInfo e;\n\tstatic langType lang = LANG_AUTO;\n\n\tif(lang == LANG_AUTO)\n\t\tlang = getNamedLanguage(\"LdScript\", 0);\n\tif(lang == LANG_IGNORE)\n\t\tgoto out;\n\n\tstatic kindDefinition * kdef = NULL;\n\tif(kdef == NULL)\n\t\tkdef = getLanguageKindForName (lang, \"symbol\");\n\tif(kdef == NULL)\n\t\tgoto out;\n\n\tstatic roleDefinition *rdef = NULL;\n\tif(rdef == NULL)\n\t\trdef = getLanguageRoleForName (lang, kdef->id, \"aliased\");\n\tif(rdef == NULL)\n\t\tgoto out;\n\n\tinitForeignRefTagEntry(&e, vStringValue(pArgToken->pszWord)+1,\n\t\t\t\t\t\t   lang, kdef->id, rdef->id);\n\tmakeTagEntry(&e);\n\n out:\n\tvStringPut(pArgToken->pszWord, '\"');\n}\n\nstatic void cxxScanAttributes(const CXXTokenChain * pAttrChain)\n{\n\tif(pAttrChain == NULL)\n\t\treturn;\n\n\tCXXToken * t = pAttrChain->pHead;\n\tbool bSection = false;\n\tbool bAlias = false;\n\n\tif((cxxParserCurrentLanguageIsC() || cxxParserCurrentLanguageIsCPP()))\n\t{\n\t\tbSection = cxxTagFieldEnabled(CXXTagFieldSection);\n\t\tbAlias = cxxTagFieldEnabled(CXXTagFieldAlias);\n\t}\n\n\twhile(t)\n\t{\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeParenthesisChain)\n\t\t   && t->pChain && t->pChain->pHead)\n\t\t{\n\t\t\tif(bSection)\n\t\t\t{\n\t\t\t\tCXXToken * s = cxxTokenChainNextIdentifier(t->pChain->pHead, \"section\");\n\t\t\t\tif(!s)\n\t\t\t\t\ts = cxxTokenChainNextIdentifier(t->pChain->pHead, \"__section__\");\n\t\t\t\tif(s)\n\t\t\t\t\tcxxScanAttrExtractSection(s);\n\t\t\t}\n\t\t\tif(bAlias)\n\t\t\t{\n\t\t\t\tCXXToken * s = cxxTokenChainNextIdentifier(t->pChain->pHead, \"alias\");\n\t\t\t\tif(s)\n\t\t\t\t\tcxxScanAttrExtractAlias(s);\n\t\t\t}\n\t\t}\n\t\tif(t == pAttrChain->pTail)\n\t\t\tbreak;\n\t\tt = t->pNext;\n\t}\n}\n\nvoid cxxSideChainScan(const CXXTokenChain * pSideChain)\n{\n\tbool bAttr = false;\n\tif(pSideChain == NULL)\n\t\treturn;\n\n\tCXXToken * t = pSideChain->pHead;\n\twhile(t)\n\t{\n\t\tif(bAttr)\n\t\t{\n\t\t\tbAttr = false;\n\t\t\tif(cxxTokenTypeIs(t,CXXTokenTypeParenthesisChain))\n\t\t\t\tcxxScanAttributes(t->pChain);\n\t\t}\n\t\tif(cxxTokenIsKeyword(t,CXXKeyword__ATTRIBUTE__))\n\t\t\tbAttr = true;\n\n\t\tif(t == pSideChain->pTail)\n\t\t\tbreak;\n\t\tt = t->pNext;\n\t}\n}\n\nvoid cxxSideChainCollectInRange(CXXToken *pStart, CXXToken *pEnd, CXXToken * pDest)\n{\n\tdo\n\t{\n\t\tif(pStart != pDest)\n\t\t\tcxxSideChainAppend(pStart, pDest);\n\t\tif(pStart == pEnd)\n\t\t\tbreak;\n\t\tpStart = pStart->pNext;\n\t}\n\twhile(true);\n}\n\nvoid cxxSideChainAppendChain(CXXTokenChain * pSideChain, CXXToken * dest)\n{\n\tif(!pSideChain)\n\t\treturn;\n\n\tif(dest->pSideChain)\n\t{\n\t\tcxxTokenChainAppendEntries(pSideChain, dest->pSideChain);\n\t\tcxxTokenChainDestroy(pSideChain);\n\t} else\n\t\tdest->pSideChain = pSideChain;\n}\n\nvoid cxxSideChainAppend(CXXToken * src, CXXToken * dest)\n{\n\tcxxSideChainAppendChain(src->pSideChain, dest);\n\tsrc->pSideChain = NULL;\n}\n\nCXXTokenChain * cxxSideChainEject(CXXToken * pToken)\n{\n\tif(!pToken)\n\t\treturn NULL;\n\n\tCXXTokenChain *pSideChain = pToken->pSideChain;\n\tpToken->pSideChain = NULL;\n\treturn pSideChain;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_side_chain.h",
    "content": "#ifndef ctags_cxx_side_chain_h_\n#define ctags_cxx_side_chain_h_\n/*\n*   Copyright (c) 2020-2022 Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for extracting information __attribute__\n*   lists.\n*/\n\n#include \"general.h\"\n\n#include \"cxx_token_chain.h\"\n\n// cxxSideChainScan and cxxSideChainScanInRange are assumed to be called\n// after calling cxxTagBegin and before calling cxxTagCommit.\n// cxxSideChainScan scans PSIDECHAIN where __attribute__ sequence are stored\n// to find something interesting.\nvoid cxxSideChainScan(const CXXTokenChain * pSideChain);\n\n// Collect all side chanins in token between PSTART to PEND, and append them to\n// the side chain of PDEST.\nvoid cxxSideChainCollectInRange(CXXToken *pStart, CXXToken *pEnd, CXXToken * pDest);\n\nvoid cxxSideChainAppend(CXXToken * src, CXXToken * dest);\nvoid cxxSideChainAppendChain(CXXTokenChain * pSideChain, CXXToken * dest);\n\n// Return the side chain of PTOKEN, and fill NULL the side chain member of PTOKEN.\nCXXTokenChain * cxxSideChainEject(CXXToken * pToken);\n\n#endif //!ctags_cxx_side_chain_h_\n"
  },
  {
    "path": "parsers/cxx/cxx_subparser.c",
    "content": "/*\n*   Copyright (c) 2017, Red Hat, Inc.\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n\n#include \"cxx_subparser_internal.h\"\n#include \"cxx_token_chain.h\"\n\n\nbool cxxSubparserNotifyParseAccessSpecifier (ptrArray *pSubparsers)\n{\n\tbool bR = false;\n\tsubparser *pSubparser;\n\n\tforeachSubparser (pSubparser, false)\n\t{\n\t\tcxxSubparser *pS = (cxxSubparser *)pSubparser;\n\t\tif (pS->parseAccessSpecifierNotify)\n\t\t{\n\t\t\tenterSubparser(pSubparser);\n\t\t\tif (pS->parseAccessSpecifierNotify (pS))\n\t\t\t{\n\t\t\t\tptrArrayAdd(pSubparsers, pS);\n\t\t\t\tbR = true;\n\t\t\t}\n\t\t\tleaveSubparser();\n\t\t}\n\t}\n\treturn bR;\n}\n\nvoid cxxSubparserNotifyfoundExtraIdentifierAsAccessSpecifier(ptrArray *pSubparsers,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t CXXToken *pToken)\n{\n\tunsigned int c = ptrArrayCount(pSubparsers);\n\tfor (unsigned int i = 0; i < c; i++)\n\t{\n\t\tcxxSubparser *pS = ptrArrayItem (pSubparsers, i);\n\t\tif (pS->foundExtraIdentifierAsAccessSpecifier)\n\t\t{\n\t\t\tenterSubparser((subparser*)pS);\n\t\t\tpS->foundExtraIdentifierAsAccessSpecifier(pS, pToken);\n\t\t\tleaveSubparser();\n\t\t}\n\t}\n}\n\nbool cxxSubparserNewIdentifierAsHeadOfMemberNotify(CXXToken *pToken)\n{\n\tsubparser *pSubparser;\n\tbool handled = false;\n\n\tforeachSubparser (pSubparser, false)\n\t{\n\t\tcxxSubparser *pS = (cxxSubparser *)pSubparser;\n\t\tif (pS->newIdentifierAsHeadOfMemberNotify)\n\t\t{\n\t\t\tenterSubparser(pSubparser);\n\t\t\tif (pS->newIdentifierAsHeadOfMemberNotify (pS, pToken))\n\t\t\t\thandled = true;\n\t\t\tleaveSubparser();\n\t\t\tif (handled)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treturn handled;\n}\n\nvoid cxxSubparserUnknownIdentifierInClassNotify(CXXToken *pToken)\n{\n\tsubparser *pSubparser;\n\tbool handled = false;\n\n\tforeachSubparser (pSubparser, false)\n\t{\n\t\tcxxSubparser *pS = (cxxSubparser *)pSubparser;\n\t\tif (pS->unknownIdentifierInClassNotify)\n\t\t{\n\t\t\tenterSubparser(pSubparser);\n\t\t\tif (pS->unknownIdentifierInClassNotify (pS, pToken))\n\t\t\t\thandled = true;\n\t\t\tleaveSubparser();\n\t\t\tif (handled)\n\t\t\t\tbreak;\n\t\t}\n\n\t}\n}\n\nvoid cxxSubparserNotifyEnterBlock (void)\n{\n\tsubparser *pSubparser;\n\tforeachSubparser (pSubparser, false)\n\t{\n\t\tcxxSubparser *pS = (cxxSubparser *)pSubparser;\n\t\tif (pS->enterBlockNotify)\n\t\t{\n\t\t\tenterSubparser(pSubparser);\n\t\t\tpS->enterBlockNotify (pS);\n\t\t\tleaveSubparser();\n\t\t}\n\t}\n}\n\nvoid cxxSubparserNotifyLeaveBlock (void)\n{\n\tsubparser *pSubparser;\n\tforeachSubparser (pSubparser, false)\n\t{\n\t\tcxxSubparser *pS = (cxxSubparser *)pSubparser;\n\t\tif (pS->leaveBlockNotify)\n\t\t{\n\t\t\tenterSubparser(pSubparser);\n\t\t\tpS->leaveBlockNotify (pS);\n\t\t\tleaveSubparser();\n\t\t}\n\t}\n}\n\nbool cxxSubparserWantVariableBody (CXXToken * pEndOfRightSide)\n{\n\tbool bR = false;\n\tsubparser *pSubparser;\n\n\tforeachSubparser (pSubparser, false)\n\t{\n\t\tif (bR)\n\t\t\tcontinue;\n\n\t\tcxxSubparser *pS = (cxxSubparser *)pSubparser;\n\t\tif (pS->wantsVariableBody)\n\t\t{\n\t\t\tenterSubparser(pSubparser);\n\t\t\tif (pS->wantsVariableBody (pS, pEndOfRightSide))\n\t\t\t\tbR = true;\n\t\t\tleaveSubparser();\n\t\t}\n\t}\n\treturn bR;\n}\n\nvoid cxxSubparserNotifyVariableBodyMaybe (int iVarCork, CXXToken * pEnd)\n{\n\tCXXToken * pStart = NULL;\n\n\n\tif (!cxxTokenTypeIs(pEnd ,CXXTokenTypeSemicolon))\n\t\treturn;\n\n\tfor (CXXToken * pT = pEnd->pPrev; pT; pT = pT->pPrev)\n\t{\n\t\tif (cxxTokenTypeIs(pT, CXXTokenTypeAssignment))\n\t\t{\n\t\t\tpStart = pT->pNext;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (pStart)\n\t{\n\t\tif (pStart == pEnd)\n\t\t\treturn;\n\n\t\tsubparser *pSubparser;\n\t\tforeachSubparser (pSubparser, false)\n\t\t{\n\t\t\tcxxSubparser *pS = (cxxSubparser *)pSubparser;\n\t\t\tif (pS->variableBodyNotify)\n\t\t\t{\n\t\t\t\tenterSubparser(pSubparser);\n\t\t\t\tpS->variableBodyNotify (pS, iVarCork, pStart, pEnd);\n\t\t\t\tleaveSubparser();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_subparser.h",
    "content": "#ifndef ctags_cxx_subparser_h_\n#define ctags_cxx_subparser_h_\n/*\n *  Copyright (c) 2017, Red Hat, Inc.\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n\n#include \"subparser.h\"\n\n#include \"cxx_token.h\"\n\n\ntypedef struct sCxxSubparser cxxSubparser;\nstruct sCxxSubparser {\n\tsubparser subparser;\n\n\tvoid (* enterBlockNotify) (struct sCxxSubparser *pSubparser);\n\tvoid (* leaveBlockNotify) (struct sCxxSubparser *pSubparser);\n\n\t/* Return true if the base parser should delete the token. */\n\tbool (* newIdentifierAsHeadOfMemberNotify) (struct sCxxSubparser *pSubparser,\n\t\t\t\t\t\t\t\t\t\t\t  CXXToken * pToken);\n\n\t/* Return true if the subparser consumes the token and the base\n\t   parser should not call the other subparsers. */\n\tbool (* unknownIdentifierInClassNotify) (struct sCxxSubparser *pSubparser,\n\t\t\t\t\t\t\t\t\t\t\t CXXToken * pToken);\n\n\t/* Return true from parseAccessSpecifierNotify () if a subparser\n\t   has an interest in extra identifier in place where an access\n\t   specifier is written. The token holding the extra identifier\n\t   has passed via foundExtraIdentifierAsAccessSpecifier method. */\n\tbool (* parseAccessSpecifierNotify) (struct sCxxSubparser *pSubparser);\n\tvoid (* foundExtraIdentifierAsAccessSpecifier) (struct sCxxSubparser *pSubparser,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCXXToken * pToken);\n\tbool (* wantsVariableBody) (struct sCxxSubparser *pSubparser, CXXToken * pEndOfRightSide);\n\tvoid (* variableBodyNotify) (struct sCxxSubparser *pSubparser, int iVarCork,\n\t\t\t\t\t\t\t\t CXXToken * pStart, CXXToken * pEnd);\n};\n\n#endif //!ctags_cxx_subparser_h_\n"
  },
  {
    "path": "parsers/cxx/cxx_subparser_internal.h",
    "content": "#ifndef ctags_cxx_subparser_interanl_h_\n#define ctags_cxx_subparser_interanl_h_\n/*\n*   Copyright (c) 2017, Red Hat, Inc.\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n\n#include \"cxx_subparser.h\"\n#include \"ptrarray.h\"\n\nbool cxxSubparserNotifyParseAccessSpecifier (ptrArray *pSubparsers);\nvoid cxxSubparserNotifyfoundExtraIdentifierAsAccessSpecifier(ptrArray *pSubparsers,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t CXXToken *pToken);\n\nbool cxxSubparserNewIdentifierAsHeadOfMemberNotify(CXXToken *pToken);\nvoid cxxSubparserUnknownIdentifierInClassNotify(CXXToken *pToken);\nvoid cxxSubparserNotifyEnterBlock (void);\nvoid cxxSubparserNotifyLeaveBlock (void);\n\nbool cxxSubparserWantVariableBody (CXXToken * pEndOfRightSide);\nvoid cxxSubparserNotifyVariableBodyMaybe (int iVarCork, CXXToken * pEnd);\n\n#endif //!ctags_cxx_subparser_interanl_h_\n"
  },
  {
    "path": "parsers/cxx/cxx_tag.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n#include \"cxx_tag.h\"\n\n#include \"cxx_scope.h\"\n#include \"cxx_debug.h\"\n#include \"cxx_token_chain.h\"\n#include \"cxx_parser_internal.h\"\n\n#include \"entry.h\"\n#include \"../x-cpreprocessor.h\"\n#include \"routines.h\"\n#include \"trashbox.h\"\n#include \"xtag.h\"\n\n#define CXX_COMMON_MACRO_ROLES(__langPrefix) \\\n\tstatic roleDefinition __langPrefix##MacroRoles [] = { \\\n\t\tRoleTemplateUndef, \\\n\t\tRoleTemplateCondition, \\\n\t}\n\nCXX_COMMON_MACRO_ROLES(C);\nCXX_COMMON_MACRO_ROLES(CXX);\nCXX_COMMON_MACRO_ROLES(CUDA);\n\n#define CXX_COMMON_HEADER_ROLES(__langPrefix) \\\n\tstatic roleDefinition __langPrefix##HeaderRoles [] = { \\\n\t\tRoleTemplateSystem, \\\n\t\tRoleTemplateLocal, \\\n\t}\n\nCXX_COMMON_HEADER_ROLES(C);\nstatic roleDefinition CXXHeaderRoles [] = {\n\t\tRoleTemplateSystem,\n\t\tRoleTemplateLocal,\n\t\t{ true, \"imported\", \"imported with \\\"imported ...\\\"\",\n\t\t  .version = 2 },\n\t\t{ true, \"exported\", \"exported with \\\"exported imported ...\\\"\",\n\t\t  .version = 2 },\n};\nCXX_COMMON_HEADER_ROLES(CUDA);\n\n/* Currently V parser wants these items. */\n#define RoleTemplateForeignDecl(V) { true, \"foreigndecl\", \"declared in foreign languages\", .version = V }\n#define RoleTemplateForeignCall(V) { true, \"foreigncall\", \"called in foreign languages\", .version = V }\n\n#define CXX_COMMON_FUNCTION_ROLES(__langPrefix) \\\n\tstatic roleDefinition __langPrefix##FunctionRoles [] = { \\\n\t\tRoleTemplateForeignDecl(1),\t\t\t\t\t\t\t \\\n\t\tRoleTemplateForeignCall(2),\t\t\t\t\t\t\t \\\n\t}\n\nCXX_COMMON_FUNCTION_ROLES(C);\n\n#define CXX_COMMON_STRUCT_ROLES(__langPrefix) \\\n\tstatic roleDefinition __langPrefix##StructRoles [] = { \\\n\t\tRoleTemplateForeignDecl(1), \\\n\t}\n\nCXX_COMMON_STRUCT_ROLES(C);\n\nstatic roleDefinition CXXModuleRoles [] = {\n\n\t{ true, \"partOwner\", \"used for specifying a partition\",\n\t  .version = 2 },\n\t{ true, \"imported\", \"imported with \\\"imported ...\\\"\",\n\t  .version = 2 },\n};\n\nstatic roleDefinition CXXPartitionRoles [] = {\n\t{ true, \"imported\", \"imported with \\\"imported ...\\\"\",\n\t  .version = 2 },\n};\n\n#define CXX_COMMON_KINDS(_langPrefix, _szMemberDescription, _syncWith, FUNC_ROLES, STRUCT_ROLES) \\\n\t{ true,  'd', \"macro\",      \"macro definitions\", \\\n\t\t\t.referenceOnly = false, ATTACH_ROLES(_langPrefix##MacroRoles), .syncWith = _syncWith \\\n\t}, \\\n\t{ true,  'e', \"enumerator\", \"enumerators (values inside an enumeration)\", .syncWith = _syncWith }, \\\n\t{ true,  'f', \"function\",   \"function definitions\", \\\n\t\t\t.referenceOnly = false, FUNC_ROLES, .syncWith = _syncWith }, \\\n\t{ true,  'g', \"enum\",       \"enumeration names\", .syncWith = _syncWith },\t\t\\\n\t{ true, 'h', \"header\",     \"included header files\", \\\n\t\t\t.referenceOnly = true,  ATTACH_ROLES(_langPrefix##HeaderRoles), .syncWith = _syncWith \\\n\t}, \\\n\t{ false, 'l', \"local\",      \"local variables\", .syncWith = _syncWith },   \\\n\t{ true,  'm', \"member\",     _szMemberDescription, .syncWith = _syncWith },\t\\\n\t{ false, 'p', \"prototype\",  \"function prototypes\", .syncWith = _syncWith },\t\t\\\n\t{ true,  's', \"struct\",     \"structure names\", \\\n\t\t\t.referenceOnly = false, STRUCT_ROLES, .syncWith = _syncWith }, \\\n\t{ true,  't', \"typedef\",    \"typedefs\", .syncWith = _syncWith },\t\t\t\\\n\t{ true,  'u', \"union\",      \"union names\", .syncWith = _syncWith },\t\t\t\\\n\t{ true,  'v', \"variable\",   \"variable definitions\", .syncWith = _syncWith },\t\t\\\n\t{ false, 'x', \"externvar\",  \"external and forward variable declarations\", .syncWith = _syncWith }, \\\n\t{ false, 'z', \"parameter\",  \"function parameters inside function or prototype definitions\", .syncWith = _syncWith }, \\\n\t{ false, 'L', \"label\",      \"goto labels\", .syncWith = _syncWith }, \\\n\t{ false, 'D', \"macroparam\", \"parameters inside macro definitions\", .syncWith = _syncWith }\n\nstatic kindDefinition g_aCXXCKinds [] = {\n\t/* All other than LANG_AUTO are ignored.\n\t   LANG_IGNORE is specified as a just placeholder for the macro,\n\t   and is not needed. */\n\tCXX_COMMON_KINDS(C,\"struct, and union members\", LANG_IGNORE, ATTACH_ROLES(CFunctionRoles), ATTACH_ROLES(CStructRoles))\n};\n\nstatic kindDefinition g_aCXXCPPKinds [] = {\n\tCXX_COMMON_KINDS(CXX,\"class, struct, and union members\", LANG_AUTO, .nRoles = 0, .nRoles = 0),\n\t{ true,  'c', \"class\",      \"classes\" },\n\t{ true,  'n', \"namespace\",  \"namespaces\" },\n\t{ false, 'A', \"alias\",      \"namespace aliases\" },\n\t{ false, 'N', \"name\",       \"names imported via using scope::symbol\" },\n\t{ false, 'U', \"using\",      \"using namespace statements\" },\n\t{ false, 'Z', \"tparam\",     \"template parameters\" },\n\t{ true,  'M', \"module\",     \"modules\",\n\t\t\t.referenceOnly = false, ATTACH_ROLES(CXXModuleRoles),\n\t\t\t.version = 2 },\n\t{ true,  'P', \"partition\",  \"partitions\",\n\t\t\t.referenceOnly = false, ATTACH_ROLES(CXXPartitionRoles),\n\t\t\t.version = 2 },\n};\n\nstatic kindDefinition g_aCXXCUDAKinds [] = {\n\tCXX_COMMON_KINDS(CUDA,\"struct, and union members\", LANG_IGNORE, .nRoles = 0, .nRoles = 0)\n};\n\nstatic const char * g_aCXXAccessStrings [] = {\n\tNULL,\n\t\"public\",\n\t\"private\",\n\t\"protected\",\n};\n\n#define CXX_COMMON_FIELDS \\\n\t{ \\\n\t\t.name = \"properties\", \\\n\t\t.description = \"properties (static, inline, mutable, export,...)\", \\\n\t\t.enabled = false \\\n\t}, { \\\n\t\t.name = \"macrodef\", \\\n\t\t.description = \"macro definition\", \\\n\t\t\t.enabled = false \\\n\t}, { \\\n\t\t.name = \"section\", \\\n\t\t.description = \"the place where the object is placed\", \\\n\t\t.enabled = false, \\\n\t\t.version = 1 \\\n\t}, { \\\n\t\t.name = \"alias\", \\\n\t\t.description = \"the name of the alias target specified in __attribute__((alias(...)))\", \\\n\t\t.enabled = false, \\\n\t\t.version = 1 \\\n\t}\n\nstatic fieldDefinition g_aCXXCFields [] = {\n\tCXX_COMMON_FIELDS\n};\n\nstatic fieldDefinition g_aCXXCPPFields [] = {\n\tCXX_COMMON_FIELDS,\n\t{\n\t\t.name = \"template\",\n\t\t.description = \"template parameters\",\n\t\t.enabled = false,\n\t},\n\t{\n\t\t.name = \"captures\",\n\t\t.description = \"lambda capture list\",\n\t\t.enabled = false\n\t},\n\t{\n\t\t.name = \"name\",\n\t\t.description = \"aliased names\",\n\t\t.enabled = true\n\t},\n\t{\n\t\t.name = \"specialization\",\n\t\t.description = \"template specialization parameters\",\n\t\t.enabled = false,\n\t},\n};\n\nstatic fieldDefinition g_aCXXCUDAFields [] = {\n\tCXX_COMMON_FIELDS\n};\n\nvoid cxxTagInitForLanguage(langType eLangType)\n{\n\tg_cxx.eLangType = eLangType;\n\n\tif(g_cxx.eLangType == g_cxx.eCLangType)\n\t{\n\t\tg_cxx.eLanguage = CXXLanguageC;\n\t\tg_cxx.pKindDefinitions = g_aCXXCKinds;\n\t\tg_cxx.uKindDefinitionCount = sizeof(g_aCXXCKinds) / sizeof(kindDefinition);\n\t\tg_cxx.pFieldOptions = g_aCXXCFields;\n\t\tg_cxx.uFieldOptionCount = sizeof(g_aCXXCFields) / sizeof(fieldDefinition);\n\t} else if(g_cxx.eLangType == g_cxx.eCPPLangType)\n\t{\n\t\tg_cxx.eLanguage = CXXLanguageCPP;\n\t\tg_cxx.pKindDefinitions = g_aCXXCPPKinds;\n\t\tg_cxx.uKindDefinitionCount = sizeof(g_aCXXCPPKinds) / sizeof(kindDefinition);\n\t\tg_cxx.pFieldOptions = g_aCXXCPPFields;\n\t\tg_cxx.uFieldOptionCount = sizeof(g_aCXXCPPFields) / sizeof(fieldDefinition);\n\t} else if(g_cxx.eLangType == g_cxx.eCUDALangType)\n\t{\n\t\tg_cxx.eLanguage = CXXLanguageCUDA;\n\t\tg_cxx.pKindDefinitions = g_aCXXCUDAKinds;\n\t\tg_cxx.uKindDefinitionCount = sizeof(g_aCXXCUDAKinds) / sizeof(kindDefinition);\n\t\tg_cxx.pFieldOptions = g_aCXXCUDAFields;\n\t\tg_cxx.uFieldOptionCount = sizeof(g_aCXXCUDAFields) / sizeof(fieldDefinition);\n\t} else {\n\t\tCXX_DEBUG_ASSERT(false,\"Invalid language passed to cxxTagInitForLanguage()\");\n\t}\n}\n\nkindDefinition * cxxTagGetCKindDefinitions(void)\n{\n\treturn g_aCXXCKinds;\n}\n\nint cxxTagGetCKindDefinitionCount(void)\n{\n\treturn sizeof(g_aCXXCKinds) / sizeof(kindDefinition);\n}\n\nkindDefinition * cxxTagGetCUDAKindDefinitions(void)\n{\n\treturn g_aCXXCUDAKinds;\n}\n\nint cxxTagGetCUDAKindDefinitionCount(void)\n{\n\treturn sizeof(g_aCXXCUDAKinds) / sizeof(kindDefinition);\n}\n\nkindDefinition * cxxTagGetCPPKindDefinitions(void)\n{\n\treturn g_aCXXCPPKinds;\n}\n\nint cxxTagGetCPPKindDefinitionCount(void)\n{\n\treturn sizeof(g_aCXXCPPKinds) / sizeof(kindDefinition);\n}\n\nbool cxxTagKindEnabled(unsigned int uKind)\n{\n\tCXX_DEBUG_ASSERT(\n\t\t\tuKind < g_cxx.uKindDefinitionCount,\n\t\t\t\"The kind must be associated to the current language!\"\n\t\t);\n\treturn g_cxx.pKindDefinitions[uKind].enabled;\n}\n\nbool cxxTagRoleEnabled(unsigned int uKind, int iRole)\n{\n\tif(!cxxTagKindEnabled(uKind))\n\t\treturn true;\n\tif(iRole == ROLE_DEFINITION_INDEX)\n\t\treturn true;\n\n\tCXX_DEBUG_ASSERT(\n\t\t(ROLE_DEFINITION_INDEX < iRole\n\t\t && iRole < g_cxx.pKindDefinitions[uKind].nRoles),\n\t\t\"The role must be associated to the kind (%u)\", uKind\n\t\t);\n\treturn g_cxx.pKindDefinitions[uKind].roles[iRole].enabled;\n}\n\nfieldDefinition * cxxTagGetCPPFieldDefinitionifiers(void)\n{\n\treturn g_aCXXCPPFields;\n}\n\nint cxxTagGetCPPFieldDefinitionifierCount(void)\n{\n\treturn sizeof(g_aCXXCPPFields) / sizeof(fieldDefinition);\n}\n\nfieldDefinition * cxxTagGetCUDAFieldDefinitionifiers(void)\n{\n\treturn g_aCXXCUDAFields;\n}\n\nint cxxTagGetCUDAFieldDefinitionifierCount(void)\n{\n\treturn sizeof(g_aCXXCUDAFields) / sizeof(fieldDefinition);\n}\n\nfieldDefinition * cxxTagGetCFieldDefinitionifiers(void)\n{\n\treturn g_aCXXCFields;\n}\n\nint cxxTagGetCFieldDefinitionifierCount(void)\n{\n\treturn sizeof(g_aCXXCFields) / sizeof(fieldDefinition);\n}\n\nbool cxxTagFieldEnabled(unsigned int uField)\n{\n\tCXX_DEBUG_ASSERT(\n\t\t\tuField < g_cxx.uFieldOptionCount,\n\t\t\t\"The field must be associated to the current language!\"\n\t\t);\n\treturn g_cxx.pFieldOptions[uField].enabled;\n}\n\n\nstatic tagEntryInfo g_oCXXTag;\n\nvoid cxxTagUseTokenAsPartOfDefTag(int iCorkIndex, CXXToken * pToken)\n{\n\tAssert (pToken->iCorkIndex == CORK_NIL);\n\tpToken->iCorkIndex = iCorkIndex;\n}\n\nvoid cxxTagUseTokensInRangeAsPartOfDefTags(int iCorkIndex, CXXToken * pFrom, CXXToken * pTo)\n{\n\tcxxTagUseTokenAsPartOfDefTag(iCorkIndex, pFrom);\n\twhile (pFrom != pTo)\n\t{\n\t\tpFrom = pFrom->pNext;\n\t\tcxxTagUseTokenAsPartOfDefTag(iCorkIndex, pFrom);\n\t}\n}\n\nstatic short cxxTagLookBackLastNth(langType iLangType, int iScopeIndex, unsigned int uKind)\n{\n\tfor (size_t uCount = countEntryInCorkQueue (); uCount > (CORK_NIL + 1); uCount--)\n\t{\n\t\tint iCorkIndex = (int)(uCount - 1);\n\t\ttagEntryInfo *pTag = getEntryInCorkQueue(iCorkIndex);\n\t\tif (iCorkIndex == iScopeIndex)\n\t\t\treturn 0;\n\t\telse if (pTag->extensionFields.scopeIndex == iScopeIndex\n\t\t\t\t && pTag->langType == iLangType\n\t\t\t\t && pTag->kindIndex == uKind)\n\t\t{\n\t\t\treturn pTag->extensionFields.nth + (\n\t\t\t\t/* Over-wrapped; if the value is too large for sizeof(nth),\n\t\t\t\t * Don't increment more. */\n\t\t\t\t((short)(pTag->extensionFields.nth + 1) > 0)\n\t\t\t\t? 1\n\t\t\t\t: 0\n\t\t\t\t);\n\t\t}\n\t}\n\treturn NO_NTH_FIELD;\n}\n\ntagEntryInfo * cxxRefTagBegin(unsigned int uKind, int iRole, CXXToken * pToken)\n{\n\tkindDefinition * pKindDefinitions = g_cxx.pKindDefinitions;\n\n\tif(!pKindDefinitions[uKind].enabled)\n\t{\n\t\t//CXX_DEBUG_PRINT(\"Tag kind %s is not enabled\",g_aCXXKinds[eKind].name);\n\t\treturn NULL;\n\t}\n\n\tinitRefTagEntry(\n\t\t\t&g_oCXXTag,\n\t\t\tvStringValue(pToken->pszWord),\n\t\t\tuKind,\n\t\t\tiRole\n\t\t);\n\n\tupdateTagLine (&g_oCXXTag, pToken->iLineNumber, pToken->oFilePosition);\n\tg_oCXXTag.isFileScope = false;\n\n\tif(!cxxScopeIsGlobal())\n\t{\n\t\t// scopeKindIndex and scopeName are used for printing the scope field\n\t\t// in a tags file.\n\t\tg_oCXXTag.extensionFields.scopeKindIndex = cxxScopeGetKind();\n\t\tg_oCXXTag.extensionFields.scopeName = cxxScopeGetFullName();\n\t\t// scopeIndex is used in the parser internally.\n\t\tg_oCXXTag.extensionFields.scopeIndex = cxxScopeGetDefTag();\n\t\tif (isFieldEnabled(FIELD_NTH) && g_oCXXTag.extensionFields.scopeIndex != CORK_NIL)\n\t\t{\n\t\t\tif (uKind == CXXTagKindMEMBER || uKind == CXXTagKindENUMERATOR\n\t\t\t\t|| uKind == CXXTagKindPARAMETER || uKind == CXXTagCPPKindTEMPLATEPARAM)\n\t\t\t\tg_oCXXTag.extensionFields.nth = cxxTagLookBackLastNth(g_oCXXTag.langType,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  g_oCXXTag.extensionFields.scopeIndex,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  uKind);\n\t\t}\n\t}\n\n\t// FIXME: meaning of \"is file scope\" is quite debatable...\n\tg_oCXXTag.extensionFields.access = g_aCXXAccessStrings[cxxScopeGetAccess()];\n\n\treturn &g_oCXXTag;\n}\n\ntagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken)\n{\n\treturn cxxRefTagBegin(uKind, ROLE_DEFINITION_INDEX, pToken);\n}\n\nvString * cxxTagSetProperties(unsigned int uProperties)\n{\n\tif(uProperties == 0)\n\t\treturn NULL;\n\n\tif(!cxxTagFieldEnabled(CXXTagFieldProperties))\n\t\treturn NULL;\n\n\tvString * pszProperties = vStringNew();\n\n\tbool bFirst = true;\n\n#define ADD_PROPERTY(_szProperty) \\\n\tdo { \\\n\t\tif(bFirst) \\\n\t\t\tbFirst = false; \\\n\t\telse \\\n\t\t\tvStringPut(pszProperties,','); \\\n\t\tvStringCatS(pszProperties,_szProperty); \\\n\t} while(0)\n\n\tif(uProperties & CXXTagPropertyConst)\n\t\tADD_PROPERTY(\"const\");\n\tif(uProperties & CXXTagPropertyDefault)\n\t\tADD_PROPERTY(\"default\");\n\tif(uProperties & CXXTagPropertyDelete)\n\t\tADD_PROPERTY(\"delete\");\n\tif(uProperties & CXXTagPropertyExplicit)\n\t\tADD_PROPERTY(\"explicit\");\n\tif(uProperties & CXXTagPropertyExtern)\n\t\tADD_PROPERTY(\"extern\");\n\tif(uProperties & CXXTagPropertyFinal)\n\t\tADD_PROPERTY(\"final\");\n\tif(uProperties & CXXTagPropertyInline)\n\t\tADD_PROPERTY(\"inline\");\n\tif(uProperties & CXXTagPropertyMutable)\n\t\tADD_PROPERTY(\"mutable\");\n\tif(uProperties & CXXTagPropertyOverride)\n\t\tADD_PROPERTY(\"override\");\n\tif(uProperties & CXXTagPropertyPure)\n\t\tADD_PROPERTY(\"pure\");\n\tif(uProperties & CXXTagPropertyScopeTemplateSpecialization)\n\t\tADD_PROPERTY(\"scopespecialization\");\n\tif(uProperties & CXXTagPropertyStatic)\n\t\tADD_PROPERTY(\"static\");\n\tif(uProperties & CXXTagPropertyTemplateSpecialization)\n\t\tADD_PROPERTY(\"specialization\");\n\tif(uProperties & CXXTagPropertyVirtual)\n\t\tADD_PROPERTY(\"virtual\");\n\tif(uProperties & CXXTagPropertyVolatile)\n\t\tADD_PROPERTY(\"volatile\");\n\tif(uProperties & CXXTagPropertyDeprecated)\n\t\tADD_PROPERTY(\"deprecated\");\n\tif(uProperties & CXXTagPropertyScopedEnum)\n\t\tADD_PROPERTY(\"scopedenum\");\n\tif(uProperties & CXXTagPropertyFunctionTryBlock)\n\t\tADD_PROPERTY(\"fntryblock\");\n\tif (uProperties & CXXTagPropertyConstexpr)\n\t\tADD_PROPERTY(\"constexpr\");\n\tif (uProperties & CXXTagPropertyConsteval)\n\t\tADD_PROPERTY(\"consteval\");\n\tif (uProperties & CXXTagPropertyConstinit)\n\t\tADD_PROPERTY(\"constinit\");\n\tif (uProperties & CXXTagPropertyThreadLocal)\n\t\tADD_PROPERTY(\"thread_local\");\n\tif (uProperties & CXXTagPropertyExport)\n\t\tADD_PROPERTY(\"export\");\n\n\tcxxTagSetField(CXXTagFieldProperties,vStringValue(pszProperties),false);\n\n\treturn pszProperties;\n}\n\nstatic bool cxxTagCheckTypeField(\n\t\tCXXToken * pTypeStart,\n\t\tCXXToken * pTypeEnd\n\t)\n{\n\tCXX_DEBUG_ENTER();\n\tif(!pTypeStart || !pTypeEnd)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"One of the pointers is NULL\");\n\t\treturn false;\n\t}\n\n\tint iTotalCount = 0;\n\tint iParenthesisCount = 0;\n\tint iIdentifierOrKeywordCount = 0;\n\tint iConsecutiveIdentifiers = 0;\n\n\twhile(pTypeStart)\n\t{\n\t\tiTotalCount++;\n\t\tif(iTotalCount > 30)\n\t\t{\n\t\t\tCXX_DEBUG_LEAVE_TEXT(\"The chain is really too long to be a type name\");\n\t\t\treturn false;\n\t\t}\n\n\t\tif(cxxTokenTypeIs(pTypeStart,CXXTokenTypeIdentifier))\n\t\t{\n\t\t\tiConsecutiveIdentifiers++;\n\t\t\tiIdentifierOrKeywordCount++;\n\t\t\tif(iConsecutiveIdentifiers > 4)\n\t\t\t{\n\t\t\t\t// Probably many macros inside. Too many.\n\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Too many consecutive identifiers for a type name\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\tiConsecutiveIdentifiers = 0;\n\n\t\t\tif(cxxTokenTypeIs(pTypeStart,CXXTokenTypeParenthesisChain))\n\t\t\t{\n\t\t\t\tiParenthesisCount++;\n\t\t\t\tif(iParenthesisCount > 3)\n\t\t\t\t{\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Too many non-nested parentheses for a type name\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif(\n\t\t\t\t\t(iTotalCount > 1) &&\n\t\t\t\t\tcxxTokenTypeIs(pTypeStart->pPrev,CXXTokenTypeIdentifier) &&\n\t\t\t\t\tpTypeStart != pTypeEnd &&\n\t\t\t\t\tpTypeStart->pNext &&\n\t\t\t\t\tcxxTokenTypeIs(pTypeStart->pNext,CXXTokenTypeIdentifier)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\t// identifier () identifier\n\t\t\t\t\t// Looks suspicious, might be macros gathered by mistake\n\t\t\t\t\tCXX_DEBUG_LEAVE_TEXT(\"Identifier-parenthesis-identifier pattern: looks suspicious\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else if(cxxTokenTypeIs(pTypeStart,CXXTokenTypeKeyword))\n\t\t\t{\n\t\t\t\tiIdentifierOrKeywordCount++;\n\t\t\t}\n\t\t}\n\n\t\tif(pTypeStart == pTypeEnd)\n\t\t\tbreak;\n\n\t\tpTypeStart = pTypeStart->pNext;\n\t}\n\n\tif(iIdentifierOrKeywordCount < 1)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Type does not seem to contains identifiers or keywords, can't be a type name\");\n\t\treturn false;\n\t}\n\n\tif(!pTypeStart)\n\t{\n\t\tCXX_DEBUG_LEAVE_TEXT(\"Type tokens do not belong to the same chain!\");\n\t\treturn false;\n\t}\n\n\tCXX_DEBUG_LEAVE();\n\treturn true;\n}\n\nCXXToken * cxxTagCheckAndSetTypeField(\n\t\tCXXToken * pTypeStart,\n\t\tCXXToken * pTypeEnd\n\t)\n{\n\tCXX_DEBUG_ASSERT(pTypeStart,\"Non null type start is expected here\");\n\tCXX_DEBUG_ASSERT(pTypeEnd,\"Non null type end is expected here\");\n\n\tconst char * szTypeRef0;\n\n\t// \"typename\" is debatable since it's not really\n\t// allowed by C++ for unqualified types. However I haven't been able\n\t// to come up with something better... so \"typename\" it is for now.\n\n\t// FIXME: The typeRef forma with two fields should be dropped.\n\t//        It has been created with specific use cases in mind\n\t//        and we are pushing it way beyond them.\n\t//        We should have a plain \"type\" field instead.\n\n\tstatic const char * szTypename = \"typename\";\n\tstatic const char * szMeta = \"meta\"; // for type template arguments\n\n\t// Filter out initial keywords that need to be excluded from typenames\n\tfor(;;)\n\t{\n\t\tif(!cxxTokenTypeIs(pTypeStart,CXXTokenTypeKeyword))\n\t\t\tbreak;\n\t\tif(!cxxKeywordExcludeFromTypeNames(pTypeStart->eKeyword))\n\t\t\tbreak;\n\t\t// must be excluded\n\t\tif(pTypeStart == pTypeEnd)\n\t\t{\n\t\t\tCXX_DEBUG_PRINT(\"Type name composed only of ignored keywords\");\n\t\t\treturn NULL; // only excluded keywords\n\t\t}\n\t\tpTypeStart = pTypeStart->pNext;\n\t}\n\n\tif(pTypeStart != pTypeEnd)\n\t{\n\t\t// Note that this does not work for types like \"const enum X\"\n\t\t// But that's not backward compatible anyway, so we live with it.\n\t\tif(\n\t\t\t\tcxxTokenTypeIs(pTypeStart,CXXTokenTypeKeyword) &&\n\t\t\t\tcxxKeywordIsTypeRefMarker(pTypeStart->eKeyword)\n\t\t\t)\n\t\t{\n\t\t\tszTypeRef0 = cxxKeywordName(pTypeStart->eKeyword);\n\t\t\tpTypeStart = pTypeStart->pNext;\n\t\t} else {\n\t\t\tszTypeRef0 = szTypename;\n\t\t}\n\t} else {\n\t\tif(\n\t\t\t\tcxxTokenTypeIs(pTypeStart,CXXTokenTypeKeyword) &&\n\t\t\t\tcxxKeywordIsTypeRefMarker(pTypeStart->eKeyword)\n\t\t\t)\n\t\t{\n\t\t\t// A lone \"typename\", \"class\", \"struct\" or similar.\n\t\t\t// This almost certainly comes from a template.\n\t\t\tszTypeRef0 = szMeta;\n\t\t} else {\n\t\t\tszTypeRef0 = szTypename;\n\t\t}\n\t}\n\n\tif(!cxxTagCheckTypeField(pTypeStart,pTypeEnd))\n\t{\n\t\tCXX_DEBUG_PRINT(\"Type name looks suspicious: refusing to emit it\");\n\t\treturn NULL;\n\t}\n\n\tcxxTokenChainNormalizeTypeNameSpacingInRange(pTypeStart,pTypeEnd);\n\tCXXToken * pTypeName = cxxTokenChainExtractRangeFilterTypeName(pTypeStart,pTypeEnd);\n\n\tif(!pTypeName)\n\t{\n\t\tCXX_DEBUG_PRINT(\"Can't extract type name\");\n\t\treturn NULL;\n\t}\n\n\tCXX_DEBUG_PRINT(\"Type name is '%s'\",vStringValue(pTypeName->pszWord));\n\n\tg_oCXXTag.extensionFields.typeRef[0] = szTypeRef0;\n\tg_oCXXTag.extensionFields.typeRef[1] = vStringValue(pTypeName->pszWord);\n\n\treturn pTypeName;\n}\n\nvoid cxxTagSetField(unsigned int uField,const char * szValue,bool bCopyValue)\n{\n\tCXX_DEBUG_ASSERT(\n\t\t\tuField < g_cxx.uFieldOptionCount,\n\t\t\t\"The field must be associated to the current language!\"\n\t\t);\n\n\tif(!g_cxx.pFieldOptions[uField].enabled)\n\t\treturn;\n\n\t/* If we make a copy for the value, the copy must be freed after\n\t * calling cxxTagCommit() for g_oCXXTag. The parser trash box\n\t * allows us to delay freeing the copy. */\n\tattachParserField(&g_oCXXTag,g_cxx.pFieldOptions[uField].ftype,\n\t\t\t\t\t  bCopyValue?parserTrashBoxPut(eStrdup(szValue),eFree):szValue);\n}\n\nvoid cxxTagSetCorkQueueField(\n\t\tint iIndex,\n\t\tunsigned int uField,\n\t\tconst char * szValue\n\t)\n{\n\tCXX_DEBUG_ASSERT(\n\t\t\tuField < g_cxx.uFieldOptionCount,\n\t\t\t\"The field must be associated to the current language!\"\n\t\t);\n\n\tCXX_DEBUG_ASSERT(g_cxx.pFieldOptions[uField].enabled,\"The field must be enabled!\");\n\n\tattachParserFieldToCorkEntry(iIndex,g_cxx.pFieldOptions[uField].ftype,szValue);\n}\n\nvoid cxxTagHandleTemplateFields()\n{\n\tCXX_DEBUG_ASSERT(\n\t\tg_cxx.pTemplateTokenChain &&\n\t\t(g_cxx.pTemplateTokenChain->iCount > 0) &&\n\t\tcxxParserCurrentLanguageIsCPP(),\n\t\t\"Template existence must be checked before calling this function\"\n\t);\n\n\tif(cxxTagFieldEnabled(CXXTagCPPFieldTemplate))\n\t{\n\t\tcxxTokenChainNormalizeTypeNameSpacing(g_cxx.pTemplateTokenChain);\n\n\t\tCXXToken * t = cxxTokenChainCondenseIntoToken(g_cxx.pTemplateTokenChain,0);\n\n\t\tif(t)\n\t\t{\n\t\t\tcxxTagSetField(\n\t\t\t\t\tCXXTagCPPFieldTemplate,\n\t\t\t\t\tvStringValue(t->pszWord),\n\t\t\t\t\ttrue\n\t\t\t\t);\n\n\t\t\tcxxTokenDestroy(t);\n\t\t}\n\t}\n\n\tif(\n\t\t\tg_cxx.pTemplateSpecializationTokenChain &&\n\t\t\tcxxTagFieldEnabled(CXXTagCPPFieldTemplateSpecialization)\n\t\t)\n\t{\n\t\tcxxTokenChainNormalizeTypeNameSpacing(g_cxx.pTemplateSpecializationTokenChain);\n\n\t\tCXXToken * tx = cxxTokenChainCondenseIntoToken(g_cxx.pTemplateSpecializationTokenChain,0);\n\n\t\tif(tx)\n\t\t{\n\t\t\tcxxTagSetField(\n\t\t\t\t\tCXXTagCPPFieldTemplateSpecialization,\n\t\t\t\t\tvStringValue(tx->pszWord),\n\t\t\t\t\ttrue\n\t\t\t\t);\n\n\t\t\tcxxTokenDestroy(tx);\n\t\t}\n\t}\n\n}\n\nint cxxTagCommit(int *piCorkQueueIndexFQ)\n{\n\tif(piCorkQueueIndexFQ)\n\t\t*piCorkQueueIndexFQ = CORK_NIL;\n\n\tif(g_oCXXTag.isFileScope)\n\t{\n\t\tif(!isXtagEnabled(XTAG_FILE_SCOPE))\n\t\t\treturn CORK_NIL;\n\n\t\tmarkTagExtraBit(&g_oCXXTag,XTAG_FILE_SCOPE);\n\t}\n\n#ifdef CXX_DO_DEBUGGING\n\tCXX_DEBUG_PRINT(\n\t\t\t\"Emitting tag for symbol '%s', kind '%s', line %d\",\n\t\t\tg_oCXXTag.name,\n\t\t\tgetLanguageKindName(g_oCXXTag.langType, g_oCXXTag.kindIndex),\n\t\t\tg_oCXXTag.lineNumber\n\t\t);\n\tif(\n\t\t\tg_oCXXTag.extensionFields.typeRef[0] &&\n\t\t\tg_oCXXTag.extensionFields.typeRef[1]\n\t\t)\n\t\tCXX_DEBUG_PRINT(\n\t\t\t\t\"Tag has typeref %s %s\",\n\t\t\t\tg_oCXXTag.extensionFields.typeRef[0],\n\t\t\t\tg_oCXXTag.extensionFields.typeRef[1]\n\t\t\t);\n#endif\n\n\tint iCorkQueueIndex = makeTagEntry(&g_oCXXTag);\n\tif (iCorkQueueIndex != CORK_NIL)\n\t\tregisterEntry(iCorkQueueIndex);\n\n\t// Handle --extra=+q\n\tif(!isXtagEnabled(XTAG_QUALIFIED_TAGS))\n\t\treturn iCorkQueueIndex;\n\n\tmarkTagExtraBit(&g_oCXXTag,XTAG_QUALIFIED_TAGS);\n\n\tif(!g_oCXXTag.extensionFields.scopeName)\n\t\treturn iCorkQueueIndex;\n\n\t// WARNING: The following code assumes that the scope\n\t// didn't change between cxxTagBegin() and cxxTagCommit().\n\n\tenum CXXScopeType eScopeType = cxxScopeGetType();\n\n\tif(eScopeType == CXXScopeTypeFunction || eScopeType == CXXScopeTypePrototype)\n\t{\n\t\t// old ctags didn't do this, and --extra=+q is mainly\n\t\t// for backward compatibility so...\n\t\treturn iCorkQueueIndex;\n\t}\n\n\t// Same tag. Only the name changes.\n\n\tvString * x;\n\n\tif(eScopeType == CXXScopeTypeEnum)\n\t{\n\t\t// If the scope kind is enumeration then we need to remove the\n\t\t// last scope part. This is what old ctags did.\n\t\tif(cxxScopeGetSize() < 2)\n\t\t\treturn CORK_NIL; // toplevel enum\n\n\t\tx = cxxScopeGetFullNameExceptLastComponentAsString();\n\t\tCXX_DEBUG_ASSERT(x,\"Scope with size >= 2 should have returned a value here\");\n\t} else {\n\t\tx = vStringNewInit(g_oCXXTag.extensionFields.scopeName);\n\t}\n\n\tvStringCatS(x, (eScopeType == CXXScopeTypeModule)? \":\": \"::\");\n\tvStringCatS(x,g_oCXXTag.name);\n\n\tg_oCXXTag.name = vStringValue(x);\n\n\tCXX_DEBUG_PRINT(\n\t\t\t\"Emitting extra tag for symbol '%s', kind '%s', line %d\",\n\t\t\tg_oCXXTag.name,\n\t\t\tgetLanguageKindName(g_oCXXTag.langType, g_oCXXTag.kindIndex),\n\t\t\tg_oCXXTag.lineNumber\n\t\t);\n\n\tint iCorkQueueIndexFQ = makeTagEntry(&g_oCXXTag);\n\tif(piCorkQueueIndexFQ)\n\t\t*piCorkQueueIndexFQ = iCorkQueueIndexFQ;\n\n\tvStringDelete(x);\n\n\treturn iCorkQueueIndex;\n}\n\nvoid cxxTag(unsigned int uKind,CXXToken * pToken)\n{\n\tif(cxxTagBegin(uKind,pToken) != NULL)\n\t\tcxxTagCommit(NULL);\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_tag.h",
    "content": "#ifndef _cxxTag_h_\n#define _cxxTag_h_\n/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n\n#include \"kind.h\"\n#include \"entry.h\"\n\n#include \"cxx_token.h\"\n\n// Tag kinds common to all (sub)languages this parser supports\nenum CXXTagCommonKind\n{\n\tCXXTagKindMACRO,\n\tCXXTagKindENUMERATOR,\n\tCXXTagKindFUNCTION,\n\tCXXTagKindENUM,\n\tCXXTagKindINCLUDE,\n\tCXXTagKindLOCAL,\n\tCXXTagKindMEMBER,\n\tCXXTagKindPROTOTYPE,\n\tCXXTagKindSTRUCT,\n\tCXXTagKindTYPEDEF,\n\tCXXTagKindUNION,\n\tCXXTagKindVARIABLE,\n\tCXXTagKindEXTERNVAR,\n\tCXXTagKindPARAMETER,\n\tCXXTagKindLABEL,\n\tCXXTagKindMACROPARAM,\n\n\tCXXTagCommonKindCount\n};\n\n// Tags specific to the CPP language.\nenum CXXTagCPPKind\n{\n\tCXXTagCPPKindCLASS = CXXTagCommonKindCount,\n\tCXXTagCPPKindNAMESPACE,\n\tCXXTagCPPKindALIAS,\n\tCXXTagCPPKindNAME,\n\tCXXTagCPPKindUSING,\n\tCXXTagCPPKindTEMPLATEPARAM,\n\tCXXTagCPPKindMODULE,\n\tCXXTagCPPKindPARTITION,\n};\n\n// The fields common to all (sub)languages this parser supports.\nenum CXXTagCommonField\n{\n\tCXXTagFieldProperties,\n\tCXXTagFieldMacrodef,\n\tCXXTagFieldSection,\n\tCXXTagFieldAlias,\n\n\tCXXTagCommonFieldCount\n};\n\n// The fields specific to the CPP language.\nenum CXXTagCPPField\n{\n\tCXXTagCPPFieldTemplate = CXXTagCommonFieldCount,\n\tCXXTagCPPFieldLambdaCaptureList,\n\tCXXTagCPPFieldAliasedName,\n\tCXXTagCPPFieldTemplateSpecialization\n};\n\n\nfieldDefinition * cxxTagGetCPPFieldDefinitionifiers(void);\nint cxxTagGetCPPFieldDefinitionifierCount(void);\n\nfieldDefinition * cxxTagGetCUDAFieldDefinitionifiers(void);\nint cxxTagGetCUDAFieldDefinitionifierCount(void);\n\nfieldDefinition * cxxTagGetCFieldDefinitionifiers(void);\nint cxxTagGetCFieldDefinitionifierCount(void);\n\nbool cxxTagFieldEnabled(unsigned int uField);\n\nkindDefinition * cxxTagGetCKindDefinitions(void);\nint cxxTagGetCKindDefinitionCount(void);\n\nkindDefinition * cxxTagGetCUDAKindDefinitions(void);\nint cxxTagGetCUDAKindDefinitionCount(void);\n\nkindDefinition * cxxTagGetCPPKindDefinitions(void);\nint cxxTagGetCPPKindDefinitionCount(void);\n\n// Returns true if the specified tag kind is enabled in the current language\nbool cxxTagKindEnabled(unsigned int uTagKind);\n\n// Returns true if the specified tag role is enabled in the current language\nbool cxxTagRoleEnabled(unsigned int uTagKind, int iTagRole);\n\n// Begin composing a tag. The tag kind must correspond to the current language.\n// Returns NULL if the tag should *not* be included in the output\n// or the tag entry info that can be filled up with extension fields.\n// Must be followed by cxxTagCommit() if it returns a non-NULL value.\n// The pToken ownership is NOT transferred.\ntagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken);\ntagEntryInfo * cxxRefTagBegin(unsigned int uKind, int iRole, CXXToken * pToken);\n\n// Set the type of the current tag from the specified token sequence\n// (which must belong to the same chain!).\n// Before setting the type this function will check that the specified\n// range of tokens looks reasonable for a type name and if it looks\n// suspicious will refuse to emit it.\n// If the type is effectively set then the return value is a token that must\n// be destroyed after cxxTagCommit() has been called.\nCXXToken * cxxTagCheckAndSetTypeField(\n\t\tCXXToken * pTypeStart,\n\t\tCXXToken * pTypeEnd\n\t);\n\ntypedef enum _CXXTagProperty\n{\n\t// Function is virtual\n\tCXXTagPropertyVirtual = 1,\n\t// Function/variable is static\n\tCXXTagPropertyStatic = (1 << 1),\n\t// Function is inline\n\tCXXTagPropertyInline = (1 << 2),\n\t// Function is explicit\n\tCXXTagPropertyExplicit = (1 << 3),\n\t// Function/variable is extern\n\tCXXTagPropertyExtern = (1 << 4),\n\t// Function is const\n\tCXXTagPropertyConst = (1 << 5),\n\t// Function is pure virtual\n\tCXXTagPropertyPure = (1 << 6),\n\t// Function is marked as override\n\tCXXTagPropertyOverride = (1 << 7),\n\t// Function is marked as default\n\tCXXTagPropertyDefault = (1 << 8),\n\t// Function is marked as final\n\tCXXTagPropertyFinal = (1 << 9),\n\t// Function is marked as delete\n\tCXXTagPropertyDelete = (1 << 10),\n\t// Variable is marked as mutable\n\t// (C++ treats \"mutable\" as storage class)\n\tCXXTagPropertyMutable = (1 << 11),\n\t// Function (note: NOT variable) is marked as volatile as in \"int a() volatile\"\n\t// (Because for variables it's treated as part of type)\n\tCXXTagPropertyVolatile = (1 << 12),\n\t// Template specialization a<x>()\n\tCXXTagPropertyTemplateSpecialization = (1 << 13),\n\t// Template specialization of scope a<x>::b() (which implies TemplateSpec too)\n\tCXXTagPropertyScopeTemplateSpecialization = (1 << 14),\n\t// __attribute__((deprecated)) has been seen\n\tCXXTagPropertyDeprecated = (1 << 15),\n\t// scoped enum (C++11)\n\tCXXTagPropertyScopedEnum = (1 << 16),\n\t// function-try-block: int f() try { ... } catch { ... }\n\tCXXTagPropertyFunctionTryBlock = (1 << 17),\n\t// constexpr has been seen.\n\tCXXTagPropertyConstexpr = (1 << 18),\n\t// consteval has been seen.\n\tCXXTagPropertyConsteval = (1 << 19),\n\t// constinit has been seen.\n\tCXXTagPropertyConstinit = (1 << 20),\n\t// thread_local has been seen.\n\tCXXTagPropertyThreadLocal = (1 << 21),\n\t// export has been seen,\n\tCXXTagPropertyExport = (1 << 22),\n} CXXTagProperty;\n\n// Set the modifiers field of the tag.\n// Returns a string that you must destroy after the call to cxxTagCommit()\n// or NULL if the modifiers weren't set for some reason (no modifiers, field\n// not enabled or similar...)\nvString * cxxTagSetProperties(unsigned int uProperties);\n\n// Set a parser-local field.\n// If bCopyValue is set to false then szValue is not copied and it must\n// persist in memory until cxxTagCommit() is called.\n// If bCopyValue is set to true then szValue is copied and it can be\n// safely destroyed before cxxTagCommit() is called.\n// bCopyValue == false is faster: use it whenever possible.\nvoid cxxTagSetField(unsigned int uField,const char * szValue,bool bCopyValue);\n\n// Set a parser-local CPP field for a tag in cork queue.\n// The szValue pointer is copied.\n// Make sure that the field is enabled before calling this function.\nvoid cxxTagSetCorkQueueField(\n\t\tint iIndex,\n\t\tunsigned int uField,\n\t\tconst char * szValue\n\t);\n\n// Handle the template-related parts of the tag (class, function, variable)\nvoid cxxTagHandleTemplateFields(void);\n\n// Commit the composed tag. Must follow a successful cxxTagBegin() call.\n// Returns the index of the tag in the cork queue.\nint cxxTagCommit(int *piCorkQueueIndexFQ);\n\n// Same as cxxTagBegin() eventually followed by cxxTagCommit()\nvoid cxxTag(unsigned int uKind,CXXToken * pToken);\n\ntypedef enum {\n\tCR_MACRO_UNDEF,\n\tCR_MACRO_CONDITION,\n} cMacroRole;\n\ntypedef enum {\n\tCR_HEADER_SYSTEM,\n\tCR_HEADER_LOCAL,\n} cHeaderRole;\n\ntypedef enum {\n\tCXXR_HEADER_IMPORTED = CR_HEADER_LOCAL + 1,\n\tCXXR_HEADER_EXPORTED\n} cxxHeaderRole;\n\ntypedef enum {\n\tCXXTagFUNCTIONRoleFOREIGNDECL,\n\tCXXTagFUNCTIONRoleFOREIGNCALL,\n} CXXTagCFunctionRole;\n\ntypedef enum {\n\tCXXTagSTRUCTRoleFOREIGNDECL,\n} CXXTagCStructRole;\n\ntypedef enum {\n\tCXXTagMODULERolePartOwner,\n\tCXXTagMODULERoleImported,\n} cxxModuleRole;\n\ntypedef enum {\n\tCXXTagPARTITIONRoleImported,\n} cxxPartitionRole;\n\n// Initialize the parser state for the specified language.\n// Must be called before attempting to access the kind options.\nvoid cxxTagInitForLanguage(langType eLangType);\n\n// Functions for filling iCorkIndex field of tokens.\nvoid cxxTagUseTokensInRangeAsPartOfDefTags(int iCorkIndex, CXXToken * pFrom, CXXToken * pTo);\nvoid cxxTagUseTokenAsPartOfDefTag(int iCorkIndex, CXXToken * pToken);\n#endif //!_cxxTag_h_\n"
  },
  {
    "path": "parsers/cxx/cxx_token.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"cxx_token.h\"\n\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"read.h\"\n#include \"objpool.h\"\n#include \"../x-cpreprocessor.h\"\n\n#include \"cxx_token_chain.h\"\n#include \"cxx_debug.h\"\n#include \"cxx_keyword.h\"\n#include \"cxx_tag.h\"\n\n#define CXX_TOKEN_POOL_MAXIMUM_SIZE 8192\n\nstatic objPool * g_pTokenPool = NULL;\n\nvoid cxxTokenForceDestroy(CXXToken * t);\n\nstatic CXXToken *createToken(void *createArg CTAGS_ATTR_UNUSED)\n{\n\tCXXToken *t = xMalloc(1, CXXToken);\n\t// we almost always want a string, and since this token\n\t// is being reused..well.. we always want it\n\tt->pszWord = vStringNew();\n\tt->iCorkIndex = CORK_NIL;\n\tt->pSideChain = NULL;\n\treturn t;\n}\n\nstatic void deleteToken(CXXToken *token)\n{\n\tcxxTokenChainDestroy(token->pSideChain);\n\tvStringDelete(token->pszWord);\n\teFree(token);\n}\n\nstatic void clearToken(CXXToken *t)\n{\n\tCXX_DEBUG_ASSERT(t->pszWord,\"The string shouldn't have been destroyed\");\n\n\t// this won't actually release memory (but we're taking care\n\t// to do not create very large strings)\n\tvStringClear(t->pszWord);\n\n\tt->bFollowedBySpace = false;\n\n\tt->pChain = NULL;\n\tt->pNext = NULL;\n\tt->pPrev = NULL;\n\n\tt->iCorkIndex = CORK_NIL;\n\n\tif(t->pSideChain)\n\t{\n\t\tcxxTokenChainDestroy(t->pSideChain);\n\t\tt->pSideChain = NULL;\n\t}\n\n\tt->bInternalScopeExported = 0;\n}\n\nvoid cxxTokenAPIInit(void)\n{\n\tg_pTokenPool = objPoolNew(CXX_TOKEN_POOL_MAXIMUM_SIZE,\n\t\t(objPoolCreateFunc)createToken, (objPoolDeleteFunc)deleteToken,\n\t\t(objPoolClearFunc)clearToken,\n\t\tNULL);\n}\n\nvoid cxxTokenAPINewFile(void)\n{\n\t/* Stub */\n}\n\nvoid cxxTokenAPIDone(void)\n{\n\tobjPoolDelete (g_pTokenPool);\n}\n\nCXXToken * cxxTokenCreate(void)\n{\n\treturn objPoolGet (g_pTokenPool);\n}\n\nvoid cxxTokenDestroy(CXXToken * t)\n{\n\tif(!t)\n\t\treturn;\n\n\tif(t->pChain)\n\t{\n\t\tcxxTokenChainDestroy(t->pChain);\n\t\tt->pChain = NULL;\n\t}\n\n\tobjPoolPut (g_pTokenPool, t);\n}\n\nvoid cxxTokenForceDestroy(CXXToken * t)\n{\n\tif(!t)\n\t\treturn;\n\n\tif(t->pChain)\n\t{\n\t\tcxxTokenChainDestroy(t->pChain);\n\t\tt->pChain = NULL;\n\t}\n\n\tCXX_DEBUG_ASSERT(t->pszWord,\"There should be a word here\");\n\n\tvStringDelete(t->pszWord);\n\n\teFree(t);\n}\n\nCXXToken * cxxTokenCopy(CXXToken * pToken)\n{\n\tCXXToken * pRetToken = cxxTokenCreate();\n\tpRetToken->iLineNumber = pToken->iLineNumber;\n\tpRetToken->oFilePosition = pToken->oFilePosition;\n\tpRetToken->eType = pToken->eType;\n\tpRetToken->eKeyword = pToken->eKeyword;\n\tpRetToken->bFollowedBySpace = pToken->bFollowedBySpace;\n\tvStringCat(pRetToken->pszWord,pToken->pszWord);\n\tpRetToken->iCorkIndex = pToken->iCorkIndex;\n\n\treturn pRetToken;\n}\n\nvoid cxxTokenReplace(CXXToken *pOriginal, CXXToken *pNew)\n{\n\tcxxTokenReplaceWithTokens(pOriginal, pNew, pNew);\n}\n\nCXXToken * cxxTokenReplaceWithTokens(CXXToken *pOriginal,\n\t\t\t\t\t\t\t\t\t CXXToken *pHead, CXXToken *pTail)\n{\n\tpTail->pNext = pOriginal->pNext;\n\tif (pOriginal->pNext)\n\t\tpOriginal->pNext->pPrev = pTail;\n\tpOriginal->pNext = NULL;\n\n\tpHead->pPrev = pOriginal->pPrev;\n\tif (pOriginal->pPrev)\n\t\tpOriginal->pPrev->pNext = pHead;\n\tpOriginal->pPrev = NULL;\n\n\treturn pHead;\n}\n\nCXXToken * cxxTokenReplaceWithTokensInChain(CXXToken *pOriginal,\n\t\t\t\t\t\t\t\t\t\t\tCXXTokenChain *pChain)\n{\n\tCXXToken * pHead = pChain->pHead;\n\tCXXToken * pTail = pChain->pTail;\n\tcxxTokenChainInit(pChain);\n\n\treturn cxxTokenReplaceWithTokens(pOriginal, pHead, pTail);\n}\n\nCXXToken * cxxTokenCreateKeyword(int iLineNumber,MIOPos oFilePosition,CXXKeyword eKeyword)\n{\n\tCXXToken * pToken = cxxTokenCreate();\n\tpToken->iLineNumber = iLineNumber;\n\tpToken->oFilePosition = oFilePosition;\n\tpToken->eType = CXXTokenTypeKeyword;\n\tpToken->eKeyword = eKeyword;\n\tpToken->bFollowedBySpace = true;\n\tvStringCatS(pToken->pszWord,cxxKeywordName(eKeyword));\n\n\treturn pToken;\n}\n\n\nCXXToken * cxxTokenCreateAnonymousIdentifier(unsigned int uTagKind, const char *szPrefix)\n{\n\tCXXToken * t = cxxTokenCreate();\n\n\tanonGenerate (t->pszWord, szPrefix? szPrefix: \"__anon\", uTagKind);\n\tt->eType = CXXTokenTypeIdentifier;\n\tt->bFollowedBySpace = true;\n\tt->iLineNumber = cppGetInputLineNumber();\n\tt->oFilePosition = cppGetInputFilePosition();\n\n\treturn t;\n}\n\nvoid cxxTokenAppendToString(vString * s,CXXToken * t)\n{\n\tswitch(t->eType)\n\t{\n\t\tcase CXXTokenTypeParenthesisChain:\n\t\tcase CXXTokenTypeSquareParenthesisChain:\n\t\tcase CXXTokenTypeBracketChain:\n\t\tcase CXXTokenTypeAngleBracketChain:\n\t\t\tCXX_DEBUG_ASSERT(t->pChain,\"This token should have a nested chain!\");\n\t\t\tcxxTokenChainJoinInString(t->pChain,s,NULL,0);\n\t\tbreak;\n\t\tdefault:\n\t\t\tvStringCat(s,t->pszWord);\n\t\tbreak;\n\t}\n}\n\nvoid cxxTokenReduceBackward (CXXToken *pStart)\n{\n\tenum CXXTokenType eSentinelType = pStart->eType >> 4;\n\tCXXToken *pTmp = pStart->pPrev;\n\tCXXToken *pReducingCandidate;\n\n\twhile (pTmp && (!cxxTokenTypeIsOneOf (pTmp, eSentinelType)))\n\t{\n\t\tpReducingCandidate = pTmp;\n\t\tpTmp = pTmp->pPrev;\n\t\tpTmp->pNext = pReducingCandidate->pNext;\n\t\tpReducingCandidate->pNext->pPrev = pTmp;\n\t\tCXX_DEBUG_PRINT(\"reduce inner token: %p\",pReducingCandidate);\n\t\tcxxTokenDestroy (pReducingCandidate);\n\t}\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_token.h",
    "content": "#ifndef ctags_cxx_token_h_\n#define ctags_cxx_token_h_\n/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n#include \"mio.h\"\n#include \"vstring.h\"\n\n#include \"cxx_keyword.h\"\n\n// We assume that the compiler is capable of generating 32 bit wide enums\n// This is used as enumeration but also as mask in several functions.\n//\n// DON'T FORGET TO RUN misc/gencxxtypedumper.sh after updating the elements.\n//\nenum CXXTokenType\n{\n\tCXXTokenTypeEOF = 1,\n\tCXXTokenTypeIdentifier = (1 << 1),\n\tCXXTokenTypeKeyword = (1 << 2),\n\tCXXTokenTypeNumber = (1 << 3),\n\tCXXTokenTypeSingleColon = (1 << 4),\n\tCXXTokenTypeMultipleColons = (1 << 5),\n\tCXXTokenTypeSemicolon = (1 << 6),\n\tCXXTokenTypeComma = (1 << 7), // ,\n\tCXXTokenTypeAssignment = (1 << 8), // =\n\tCXXTokenTypeOperator = (1 << 9), // != == += ++ -= -- / whatever\n\tCXXTokenTypeUnknown = (1 << 10),\n\tCXXTokenTypeDotOperator = (1 << 11), // .\n\tCXXTokenTypePointerOperator = (1 << 12), // ->\n\tCXXTokenTypeStringConstant = (1 << 13),\n\tCXXTokenTypeStar = (1 << 14), // *\n\tCXXTokenTypeAnd = (1 << 15), // &\n\tCXXTokenTypeMultipleAnds = (1 << 16), // &&\n\tCXXTokenTypeCharacterConstant = (1 << 17),\n\tCXXTokenTypeMultipleDots = (1 << 18), // ...\n\n\t// These must come in pairs. Note that the opening\n\t// tokens can be shifted by 4 to get the matching closing\n\t// tokens can be shifted by 8 to get the matching subchain marker below\n\tCXXTokenTypeOpeningBracket = (1 << 19), // {\n\tCXXTokenTypeOpeningParenthesis = (1 << 20), // (\n\tCXXTokenTypeOpeningSquareParenthesis = (1 << 21), // [\n\tCXXTokenTypeSmallerThanSign = (1 << 22), // <\n\n\tCXXTokenTypeClosingBracket = (1 << 23), // }\n\tCXXTokenTypeClosingParenthesis = (1 << 24), // )\n\tCXXTokenTypeClosingSquareParenthesis = (1 << 25), // ]\n\tCXXTokenTypeGreaterThanSign = (1 << 26), // >\n\n\t// Subchains (caution: read the comment above about CXXTokenTypeOpeningBracket)\n\tCXXTokenTypeBracketChain = (1 << 27), // {...}\n\tCXXTokenTypeParenthesisChain = (1 << 28), // (...)\n\tCXXTokenTypeSquareParenthesisChain = (1 << 29), // [...]\n\tCXXTokenTypeAngleBracketChain = (1 << 30), // <...>\n};\n\n// Forward decl\ntypedef struct _CXXTokenChain CXXTokenChain;\n\n\n\ntypedef struct _CXXToken\n{\n\tenum CXXTokenType eType;\n\tvString * pszWord;\n\tCXXKeyword eKeyword;\n\tCXXTokenChain * pChain; // this is NOT the parent chain!\n\tunsigned int bFollowedBySpace: 1;\n\tunsigned int bInternalScopeExported: 1;\n\n\tint iLineNumber;\n\tMIOPos oFilePosition;\n\n\tstruct _CXXToken * pNext;\n\tstruct _CXXToken * pPrev;\n\n\t// These (and above) uInternalScope members are used by the scope management\n\t// functions to store scope information. Only cxxScope* functions can make\n\t// sense of it. In other contexts these are simply left\n\t// uninitialized and must be treated as undefined.\n\tunsigned char uInternalScopeType;\n\tunsigned char uInternalScopeAccess;\n\n\tint iCorkIndex;\n\n\t// The member keeps tokens started from __attribute__ and __declspec.\n\tCXXTokenChain * pSideChain;\n} CXXToken;\n\nCXXToken * cxxTokenCreate(void);\nvoid cxxTokenDestroy(CXXToken * t);\n\n// A shortcut for quickly creating a fake token.\nCXXToken * cxxTokenCopy(CXXToken *pToken);\n\n\n// Replace pOriginal with pNew.\nvoid cxxTokenReplace(CXXToken *pOriginal, CXXToken *pNew);\n\nCXXToken * cxxTokenReplaceWithTokens(CXXToken *pOriginal,\n\t\t\t\t\t\t\t\t\t CXXToken *pHead,\n\t\t\t\t\t\t\t\t\t CXXToken *pTail);\n// Replace pOriginal with tokens in pChain.\n// Returns the first token of the tokens.\nCXXToken * cxxTokenReplaceWithTokensInChain(CXXToken *pOriginal,\n\t\t\t\t\t\t\t\t\t\t\tCXXTokenChain *pChain);\n\n// A shortcut for quickly creating keyword tokens.\nCXXToken * cxxTokenCreateKeyword(int iLineNumber,MIOPos oFilePosition,CXXKeyword eKeyword);\n\nCXXToken * cxxTokenCreateAnonymousIdentifier(unsigned int uTagKind,\n\t\t\t\t\t\t\t\t\t\t\t const char *szPrefix);\n\n#define cxxTokenTypeIsOneOf(_pToken,_uTypes) (_pToken->eType & (_uTypes))\n#define cxxTokenTypeIs(_pToken,_eType) (_pToken->eType == _eType)\n#define cxxTokenIsKeyword(_pToken,_eKeyword) \\\n\t\t( \\\n\t\t\t(_pToken->eType == CXXTokenTypeKeyword) && \\\n\t\t\t(_pToken->eKeyword == _eKeyword) \\\n\t\t)\n#define cxxTokenIsNonConstantKeyword(_pToken) \\\n\t\t( \\\n\t\t\tcxxTokenTypeIs(_pToken,CXXTokenTypeKeyword) && \\\n\t\t\t(!cxxKeywordIsConstant(_pToken->eKeyword)) \\\n\t\t)\n\n// FIXME: Bad argument order\nvoid cxxTokenAppendToString(vString * s,CXXToken * t);\n\nvoid cxxTokenAPIInit(void);\nvoid cxxTokenAPINewFile(void);\nvoid cxxTokenAPIDone(void);\n\nvoid cxxTokenReduceBackward (CXXToken *pStart);\n\n#endif //!ctags_cxx_token_h_\n"
  },
  {
    "path": "parsers/cxx/cxx_token_chain.c",
    "content": "/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"cxx_token_chain.h\"\n\n#include \"cxx_debug.h\"\n\n#include \"vstring.h\"\n#include \"debug.h\"\n#include \"routines.h\"\n\n#include <string.h>\n\nvoid cxxTokenChainInit(CXXTokenChain * tc)\n{\n\tAssert(tc);\n\ttc->pHead = NULL;\n\ttc->pTail = NULL;\n\ttc->iCount = 0;\n}\n\nCXXTokenChain * cxxTokenChainCreate(void)\n{\n\tCXXTokenChain * tc = xMalloc(1, CXXTokenChain);\n\tcxxTokenChainInit(tc);\n\treturn tc;\n}\n\nvoid cxxTokenChainDestroy(CXXTokenChain * tc)\n{\n\tCXXToken * t;\n\tCXXToken * t2;\n\n\tif(!tc)\n\t\treturn;\n\n\tt = tc->pHead;\n\twhile(t)\n\t{\n\t\tt2 = t->pNext;\n\t\tcxxTokenDestroy(t);\n\t\tt = t2;\n\t}\n\n\teFree(tc);\n}\n\nCXXToken * cxxTokenChainTakeFirst(CXXTokenChain * tc)\n{\n\tCXXToken * t;\n\n\tif(!tc)\n\t\treturn NULL;\n\tif(!tc->pHead)\n\t\treturn NULL;\n\n\tt = tc->pHead;\n\tif(t == tc->pTail)\n\t{\n\t\ttc->pHead = NULL;\n\t\ttc->pTail = NULL;\n\t\ttc->iCount = 0;\n\t\treturn t;\n\t}\n\n\ttc->iCount--;\n\tAssert(tc->iCount >= 0);\n\tAssert(t->pNext);\n\n\tt->pNext->pPrev = NULL;\n\ttc->pHead = t->pNext;\n\n\treturn t;\n}\n\nCXXToken * cxxTokenChainTakeLast(CXXTokenChain * tc)\n{\n\tCXXToken * t;\n\n\tif(!tc)\n\t\treturn NULL;\n\tif(!tc->pTail)\n\t\treturn NULL;\n\n\tt = tc->pTail;\n\tif(t == tc->pHead)\n\t{\n\t\ttc->pHead = NULL;\n\t\ttc->pTail = NULL;\n\t\ttc->iCount = 0;\n\t\treturn t;\n\t}\n\n\ttc->iCount--;\n\tAssert(tc->iCount >= 0);\n\n\tt->pPrev->pNext = NULL;\n\ttc->pTail = t->pPrev;\n\n\treturn t;\n}\n\nvoid cxxTokenChainTake(CXXTokenChain * tc,CXXToken * t)\n{\n\tif(!tc)\n\t\treturn;\n\tif(!tc->pHead)\n\t\treturn;\n\n\t/*\n\tDebug with this:\n\n\tCXXToken * t2 = tc->pHead;\n\twhile(t2 && (t2 != t))\n\t\tt2 = t2->pNext;\n\n\tAssert(t2);\n\t*/\n\n\tif(t == tc->pHead)\n\t{\n\t\tcxxTokenChainTakeFirst(tc);\n\t\treturn;\n\t}\n\n\tif(t == tc->pTail)\n\t{\n\t\tcxxTokenChainTakeLast(tc);\n\t\treturn;\n\t}\n\n\t// in the middle\n\n\tCXXToken * n = t->pNext;\n\tCXXToken * p = t->pPrev;\n\n\tn->pPrev = p;\n\tp->pNext = n;\n\n\ttc->iCount--;\n\n\tAssert(tc->iCount > 1);\n}\n\nbool cxxTokenChainTakeRecursive(CXXTokenChain * tc,CXXToken * t)\n{\n\tif(!tc)\n\t\treturn false;\n\n\tCXXToken * aux = tc->pHead;\n\twhile(aux)\n\t{\n\t\tif(t == aux)\n\t\t{\n\t\t\tcxxTokenChainTake(tc,aux);\n\t\t\treturn true;\n\t\t}\n\n\t\tif(cxxTokenTypeIsOneOf(\n\t\t\t\taux,\n\t\t\t\tCXXTokenTypeParenthesisChain | CXXTokenTypeAngleBracketChain |\n\t\t\t\t\tCXXTokenTypeSquareParenthesisChain | CXXTokenTypeBracketChain\n\t\t\t))\n\t\t{\n\t\t\tif(cxxTokenChainTakeRecursive(aux->pChain,t))\n\t\t\t\treturn true;\n\t\t}\n\n\t\taux = aux->pNext;\n\t}\n\n\treturn false;\n}\n\n#if 0\nCXXToken * cxxTokenChainTakeAt(CXXTokenChain * tc,int index)\n{\n\tif(!tc)\n\t\treturn NULL;\n\tCXXToken * token = cxxTokenChainAt(tc,index);\n\tif(!token)\n\t\treturn NULL;\n\tcxxTokenChainTake(tc,token);\n\treturn token;\n}\n#endif\n\nvoid cxxTokenChainClear(CXXTokenChain * tc)\n{\n\tCXXToken * t;\n\n\tif(!tc)\n\t\treturn;\n\n\tif(tc->iCount < 1)\n\t\treturn;\n\n\twhile((t = cxxTokenChainTakeFirst(tc)))\n\t\tcxxTokenDestroy(t);\n\n\n\tAssert(tc->iCount == 0);\n\tAssert(tc->pHead == NULL);\n\tAssert(tc->pTail == NULL);\n}\n\nvoid cxxTokenChainInsertAfter(CXXTokenChain * tc,CXXToken * before,CXXToken * t)\n{\n\tif(!before)\n\t{\n\t\tcxxTokenChainPrepend(tc,t);\n\t\treturn;\n\t}\n\n\tif(!before->pNext)\n\t{\n\t\tcxxTokenChainAppend(tc,t);\n\t\treturn;\n\t}\n\n\tt->pNext = before->pNext;\n\tt->pPrev = before;\n\tbefore->pNext = t;\n\tt->pNext->pPrev = t;\n}\n\nvoid cxxTokenChainAppend(CXXTokenChain * tc,CXXToken * t)\n{\n\ttc->iCount++;\n\n\tif(!tc->pTail)\n\t{\n\t\ttc->pHead = t;\n\t\ttc->pTail = t;\n\t\tt->pPrev = NULL;\n\t\tt->pNext = NULL;\n\t\treturn;\n\t}\n\n\tt->pPrev = tc->pTail;\n\tt->pNext = NULL;\n\n\ttc->pTail->pNext = t;\n\ttc->pTail = t;\n}\n\nvoid cxxTokenChainPrepend(CXXTokenChain * tc,CXXToken * t)\n{\n\ttc->iCount++;\n\n\tif(!tc->pHead)\n\t{\n\t\ttc->pHead = t;\n\t\ttc->pTail = t;\n\t\tt->pPrev = NULL;\n\t\tt->pNext = NULL;\n\t\treturn;\n\t}\n\n\tt->pNext = tc->pHead;\n\tt->pPrev = NULL;\n\n\ttc->pHead->pPrev = t;\n\ttc->pHead = t;\n}\n\nvoid cxxTokenChainJoinRangeInString(\n\t\tCXXToken * from,\n\t\tCXXToken * to,\n\t\tvString * s,\n\t\tconst char * szSeparator,\n\t\tunsigned int uFlags\n\t)\n{\n\tif(!from)\n\t\treturn;\n\n\tCXXToken * t = from;\n\n\tcxxTokenAppendToString(s,t);\n\n\tif((!(uFlags & CXXTokenChainJoinNoTrailingSpaces)) && t->bFollowedBySpace)\n\t\tvStringPut (s, ' ');\n\n\twhile(t && (t != to))\n\t{\n\t\tt = t->pNext;\n\t\tif(!t)\n\t\t\treturn;\n\n\t\tif(szSeparator)\n\t\t\tvStringCatS(s,szSeparator);\n\n\t\tcxxTokenAppendToString(s,t);\n\n\t\tif(\n\t\t\t\t(!(uFlags & CXXTokenChainJoinNoTrailingSpaces)) &&\n\t\t\t\tt->bFollowedBySpace\n\t\t\t)\n\t\t\tvStringPut (s, ' ');\n\t}\n}\n\nvString * cxxTokenChainJoinRange(\n\t\tCXXToken * from,\n\t\tCXXToken * to,\n\t\tconst char * szSeparator,\n\t\tunsigned int uFlags\n\t)\n{\n\tif(!from)\n\t\treturn NULL;\n\n\tvString * s = vStringNew();\n\n\tcxxTokenChainJoinRangeInString(from,to,s,szSeparator,uFlags);\n\n\treturn s;\n}\n\nvoid cxxTokenChainJoinInString(\n\t\tCXXTokenChain * tc,\n\t\tvString * s,\n\t\tconst char * szSeparator,\n\t\tunsigned int uFlags\n\t)\n{\n\tif(!tc)\n\t\treturn;\n\n\tif(tc->iCount == 0)\n\t\treturn;\n\n\tCXXToken * t = tc->pHead;\n\n\tcxxTokenAppendToString(s,t);\n\n\tif(\n\t\t\t(!(uFlags & CXXTokenChainJoinNoTrailingSpaces)) &&\n\t\t\tt->bFollowedBySpace\n\t\t)\n\t\tvStringPut (s, ' ');\n\n\tt = t->pNext;\n\twhile(t)\n\t{\n\t\tif(szSeparator)\n\t\t\tvStringCatS(s,szSeparator);\n\n\t\tcxxTokenAppendToString(s,t);\n\n\t\tif(\n\t\t\t\t(!(uFlags & CXXTokenChainJoinNoTrailingSpaces)) &&\n\t\t\t\tt->bFollowedBySpace\n\t\t\t)\n\t\t\tvStringPut (s, ' ');\n\n\t\tt = t->pNext;\n\t}\n}\n\n\nvString * cxxTokenChainJoin(\n\t\tCXXTokenChain * tc,\n\t\tconst char * szSeparator,\n\t\tunsigned int uFlags\n\t)\n{\n\tif(!tc)\n\t\treturn NULL;\n\n\tif(tc->iCount == 0)\n\t\treturn NULL;\n\n\tvString * s = vStringNew();\n\n\tcxxTokenChainJoinInString(tc,s,szSeparator,uFlags);\n\n\treturn s;\n}\n\nvoid cxxTokenChainAppendEntries(CXXTokenChain * src, CXXTokenChain * dest)\n{\n\tCXXToken * pDestLast = cxxTokenChainLast(dest);\n\tCXXToken * pSrcFirst = cxxTokenChainFirst(src);\n\n\tpDestLast->pNext = pSrcFirst;\n\tpSrcFirst->pPrev = pDestLast;\n\n\tdest->iCount += src->iCount;\n\tdest->pTail = src->pTail;\n\n\tsrc->iCount = 0;\n\tsrc->pHead = NULL;\n\tsrc->pTail = NULL;\n}\n\n#if 0\n// currently unused\nvoid cxxTokenChainMoveEntries(CXXTokenChain * src,CXXTokenChain * dest)\n{\n\tif(dest->iCount > 0)\n\t\tcxxTokenChainClear(dest);\n\n\tdest->iCount = src->iCount;\n\tdest->pHead = src->pHead;\n\tdest->pTail = src->pTail;\n\n\tsrc->iCount = 0;\n\tsrc->pHead = NULL;\n\tsrc->pTail = NULL;\n}\n\nvoid cxxTokenChainMoveEntryRange(\n\t\tCXXTokenChain * src,\n\t\tCXXToken * start,\n\t\tCXXToken * end,\n\t\tCXXTokenChain * dest\n\t)\n{\n\tif(!src || !dest || !start || !end)\n\t\treturn;\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenChainFindToken(src,start) >= 0,\n\t\t\t\"The start token must be in the source chain!\"\n\t\t);\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenChainFindToken(src,end) >= 0,\n\t\t\t\"The end token must be in the source chain!\"\n\t\t);\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenChainFindToken(src,start) <= cxxTokenChainFindToken(src,end),\n\t\t\t\"The start token must come before the end token\"\n\t\t);\n\n\t// FIXME: We could have a more efficient version of this\n\tCXXToken * t = start;\n\tfor(;;)\n\t{\n\t\tCXXToken * next = t->pNext;\n\n\t\tcxxTokenChainTake(src,t);\n\t\tcxxTokenChainAppend(dest,t);\n\n\t\tif(t == end)\n\t\t\tbreak;\n\n\t\tt = next;\n\t}\n}\n#endif\n\nstatic CXXToken * cxxTokenCreatePlaceholder(CXXToken * pToken)\n{\n\tCXXToken * pPlaceholder = cxxTokenCreate();\n\n\tpPlaceholder->iLineNumber = pToken->iLineNumber;\n\tpPlaceholder->oFilePosition = pToken->oFilePosition;\n\tpPlaceholder->eType = CXXTokenTypeUnknown;\n\n\treturn pPlaceholder;\n}\n\nCXXTokenChain * cxxTokenChainSplitOnComma(CXXTokenChain * tc)\n{\n\tif(!tc)\n\t\treturn NULL;\n\n\tCXXTokenChain * pRet = cxxTokenChainCreate();\n\n\tCXXToken * pToken = cxxTokenChainFirst(tc);\n\n\tif(!pToken)\n\t\treturn pRet;\n\n\tCXXToken * pStart = pToken;\n\n\twhile(pStart && pToken->pNext)\n\t{\n\t\tCXXToken * pNew = NULL;\n\n\t\tif (cxxTokenTypeIs(pToken,CXXTokenTypeComma))\n\t\t{\n\t\t\t// If nothing is passed as an argument like\n\t\t\t//\n\t\t\t// macro(,b),\n\t\t\t// macro(a,), or\n\t\t\t// macro(,)\n\t\t\t//\n\t\t\t// , we must inject a dummy token to the chain.\n\t\t\tpNew = cxxTokenCreatePlaceholder(pToken);\n\t\t\t// we will not update pToken in this case.\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile(pToken->pNext && (!cxxTokenTypeIs(pToken->pNext,CXXTokenTypeComma)))\n\t\t\t\tpToken = pToken->pNext;\n\n\t\t\tpNew = cxxTokenChainExtractRange(pStart,pToken,0);\n\t\t\tpToken = pToken->pNext; // comma or nothing\n\t\t}\n\t\tif(pNew)\n\t\t\tcxxTokenChainAppend(pRet,pNew);\n\n\t\tif(pToken)\n\t\t\tpToken = pToken->pNext; // after comma\n\t\tpStart = pToken;\n\t}\n\n\tif(pStart)\n\t{\n\t\t// finished without comma\n\t\tCXXToken * pNew = cxxTokenChainExtractRange(pStart,cxxTokenChainLast(tc),0);\n\t\tif(pNew)\n\t\t\tcxxTokenChainAppend(pRet,pNew);\n\t}\n\n\treturn pRet;\n}\n\nCXXToken * cxxTokenChainCondenseIntoToken(CXXTokenChain * tc,unsigned int uFlags)\n{\n\tif(!tc)\n\t\treturn NULL;\n\n\tCXXToken * t = tc->pHead;\n\tif(!t)\n\t\treturn NULL;\n\n\tCXXToken * pCondensed = cxxTokenCreate();\n\n\tpCondensed->eType = CXXTokenTypeUnknown;\n\tpCondensed->iLineNumber = t->iLineNumber;\n\tpCondensed->oFilePosition = t->oFilePosition;\n\n\twhile(t)\n\t{\n\t\tcxxTokenAppendToString(pCondensed->pszWord,t);\n\n\t\tif(\n\t\t\t\t(!(uFlags & CXXTokenChainCondenseNoTrailingSpaces)) &&\n\t\t\t\tt->bFollowedBySpace\n\t\t\t)\n\t\t\tvStringPut (pCondensed->pszWord, ' ');\n\n\t\tpCondensed->bFollowedBySpace = t->bFollowedBySpace;\n\n\t\tt = t->pNext;\n\t}\n\n\treturn pCondensed;\n}\n\nvoid cxxTokenChainCondense(CXXTokenChain * tc,unsigned int uFlags)\n{\n\tCXXToken * pCondensed = cxxTokenChainCondenseIntoToken(tc,uFlags);\n\tif(!pCondensed)\n\t\treturn;\n\n\tcxxTokenChainClear(tc);\n\n\tcxxTokenChainAppend(tc,pCondensed);\n}\n\nCXXToken * cxxTokenChainAt(CXXTokenChain * tc,int index)\n{\n\tif(!tc)\n\t\treturn NULL;\n\tif(index < 0)\n\t\treturn NULL;\n\tif(index >= tc->iCount)\n\t\treturn NULL;\n\tCXXToken * pToken = tc->pHead;\n\twhile(pToken && index)\n\t{\n\t\tindex--;\n\t\tpToken = pToken->pNext;\n\t}\n\n\treturn pToken;\n}\n\nCXXToken * cxxTokenChainSkipToEndOfTemplateAngleBracket(CXXToken * t)\n{\n\tif(!t)\n\t\treturn NULL;\n\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(t,CXXTokenTypeSmallerThanSign),\n\t\t\t\"This function must be called when pointing to a <\"\n\t\t);\n\n\tint iLevel = 1;\n\tt = t->pNext;\n\twhile(t)\n\t{\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeSmallerThanSign))\n\t\t{\n\t\t\tiLevel++;\n\t\t} else if(cxxTokenTypeIs(t,CXXTokenTypeGreaterThanSign))\n\t\t{\n\t\t\tif(iLevel == 1)\n\t\t\t\treturn t;\n\t\t\tiLevel--;\n\t\t}\n\t\tt = t->pNext;\n\t}\n\t// invalid\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainSkipBackToStartOfTemplateAngleBracket(CXXToken * t)\n{\n\tif(!t)\n\t\treturn NULL;\n\tCXX_DEBUG_ASSERT(\n\t\t\tcxxTokenTypeIs(t, CXXTokenTypeGreaterThanSign),\n\t\t\t\"This function must be called when pointing to a >\"\n\t\t);\n\tint iLevel = 1;\n\tt = t->pPrev;\n\twhile(t)\n\t{\n\t\tif(cxxTokenTypeIs(t,CXXTokenTypeGreaterThanSign))\n\t\t{\n\t\t\tiLevel++;\n\t\t} else if(cxxTokenTypeIs(t,CXXTokenTypeSmallerThanSign))\n\t\t{\n\t\t\tif(iLevel == 1)\n\t\t\t\treturn t;\n\t\t\tiLevel--;\n\t\t}\n\t\tt = t->pPrev;\n\t}\n\t// invalid\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainFirstTokenOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes\n\t)\n{\n\tif(!tc)\n\t\treturn NULL;\n\tCXXToken * t = tc->pHead;\n\twhile(t)\n\t{\n\t\tif(cxxTokenTypeIsOneOf(t, uTokenTypes))\n\t\t\treturn t;\n\t\tt = t->pNext;\n\t}\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainNextTokenOfType(\n\t\tCXXToken * t,\n\t\tunsigned int uTokenTypes\n\t)\n{\n\tif(!t)\n\t\treturn NULL;\n\tt = t->pNext;\n\twhile(t)\n\t{\n\t\tif(cxxTokenTypeIsOneOf(t, uTokenTypes))\n\t\t\treturn t;\n\t\tt = t->pNext;\n\t}\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainPreviousTokenOfType(\n\t\tCXXToken * t,\n\t\tunsigned int uTokenTypes\n\t)\n{\n\tif(!t)\n\t\treturn NULL;\n\tt = t->pPrev;\n\twhile(t)\n\t{\n\t\tif(cxxTokenTypeIsOneOf(t, uTokenTypes))\n\t\t\treturn t;\n\t\tt = t->pPrev;\n\t}\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainPreviousTokenNotOfType(\n\t\tCXXToken * t,\n\t\tunsigned int uTokenTypes\n\t)\n{\n\tif(!t)\n\t\treturn NULL;\n\tt = t->pPrev;\n\twhile(t)\n\t{\n\t\tif(!(cxxTokenTypeIsOneOf(t, uTokenTypes)))\n\t\t\treturn t;\n\t\tt = t->pPrev;\n\t}\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainLastTokenOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes\n\t)\n{\n\tif(!tc)\n\t\treturn NULL;\n\tCXXToken * t = tc->pTail;\n\twhile(t)\n\t{\n\t\tif(cxxTokenTypeIsOneOf(t, uTokenTypes))\n\t\t\treturn t;\n\t\tt = t->pPrev;\n\t}\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainLastPossiblyNestedTokenOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes,\n\t\tCXXTokenChain ** ppParentChain\n\t)\n{\n\tif(!tc)\n\t\treturn NULL;\n\tCXXToken * t = tc->pTail;\n\twhile(t)\n\t{\n\t\tif(cxxTokenTypeIsOneOf(t, uTokenTypes))\n\t\t{\n\t\t\tif(ppParentChain)\n\t\t\t\t*ppParentChain = tc;\n\t\t\treturn t;\n\t\t}\n\t\tif(cxxTokenTypeIs(t, CXXTokenTypeParenthesisChain))\n\t\t{\n\t\t\tCXXToken * tmp = cxxTokenChainLastPossiblyNestedTokenOfType(\n\t\t\t\t\tt->pChain,\n\t\t\t\t\tuTokenTypes,\n\t\t\t\t\tppParentChain\n\t\t\t\t);\n\t\t\tif(tmp)\n\t\t\t\treturn tmp;\n\t\t}\n\t\tt = t->pPrev;\n\t}\n\treturn NULL;\n\n}\n\nCXXToken * cxxTokenChainFirstPossiblyNestedTokenOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes,\n\t\tCXXTokenChain ** ppParentChain\n\t)\n{\n\tif(!tc)\n\t\treturn NULL;\n\tCXXToken * t = tc->pHead;\n\twhile(t)\n\t{\n\t\tif(cxxTokenTypeIsOneOf(t, uTokenTypes))\n\t\t{\n\t\t\tif(ppParentChain)\n\t\t\t\t*ppParentChain = tc;\n\t\t\treturn t;\n\t\t}\n\t\tif(cxxTokenTypeIs(t, CXXTokenTypeParenthesisChain))\n\t\t{\n\t\t\tCXXToken * tmp = cxxTokenChainFirstPossiblyNestedTokenOfType(\n\t\t\t\t\tt->pChain,\n\t\t\t\t\tuTokenTypes,\n\t\t\t\t\tppParentChain\n\t\t\t\t);\n\t\t\tif(tmp)\n\t\t\t\treturn tmp; // ppParentChain is already set\n\t\t}\n\t\tt = t->pNext;\n\t}\n\treturn NULL;\n\n}\n\n\nCXXToken * cxxTokenChainFirstTokenNotOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes\n\t)\n{\n\tif(!tc)\n\t\treturn NULL;\n\tCXXToken * t = tc->pHead;\n\twhile(t)\n\t{\n\t\tif(!(cxxTokenTypeIsOneOf(t, uTokenTypes)))\n\t\t\treturn t;\n\t\tt = t->pNext;\n\t}\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainNextTokenNotOfGeneric(\n\t\tCXXToken * t,\n\t\tbool (* predicator) (CXXToken *, void *),\n\t\tvoid *data\n\t)\n{\n\tif(!t)\n\t\treturn NULL;\n\tt = t->pNext;\n\twhile(t)\n\t{\n\t\tif(!predicator (t, data))\n\t\t\treturn t;\n\t\tt = t->pNext;\n\t}\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainNextTokenNotOfType(\n\t\tCXXToken * t,\n\t\tunsigned int uTokenTypes\n\t)\n{\n\tif(!t)\n\t\treturn NULL;\n\tt = t->pNext;\n\twhile(t)\n\t{\n\t\tif(!(cxxTokenTypeIsOneOf(t, uTokenTypes)))\n\t\t\treturn t;\n\t\tt = t->pNext;\n\t}\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainLastTokenNotOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes\n\t)\n{\n\tif(!tc)\n\t\treturn NULL;\n\tCXXToken * t = tc->pTail;\n\twhile(t)\n\t{\n\t\tif(!(cxxTokenTypeIsOneOf(t, uTokenTypes)))\n\t\t\treturn t;\n\t\tt = t->pPrev;\n\t}\n\treturn NULL;\n}\n\n\nint cxxTokenChainFindToken(\n\t\tCXXTokenChain * tc,\n\t\tCXXToken * t\n\t)\n{\n\tif(!tc)\n\t\treturn -1;\n\tif(tc->iCount < 1)\n\t\treturn -1;\n\n\tCXXToken * pToken = tc->pHead;\n\tint idx = 0;\n\twhile(pToken)\n\t{\n\t\tif(pToken == t)\n\t\t\treturn idx;\n\t\tidx++;\n\t\tpToken = pToken->pNext;\n\t}\n\n\treturn -1;\n}\n\nCXXToken * cxxTokenChainPreviousKeyword(\n\t\tCXXToken * from,\n\t\tCXXKeyword eKeyword\n\t)\n{\n\tif(!from)\n\t\treturn NULL;\n\n\tCXXToken * t = from->pPrev;\n\twhile(t)\n\t{\n\t\tif(cxxTokenIsKeyword(t,eKeyword))\n\t\t\treturn t;\n\t\tt = t->pPrev;\n\t}\n\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainNextKeyword(\n\t\tCXXToken * from,\n\t\tCXXKeyword eKeyword\n\t)\n{\n\tif(!from)\n\t\treturn NULL;\n\n\tCXXToken * t = from->pNext;\n\twhile(t)\n\t{\n\t\tif(cxxTokenIsKeyword(t,eKeyword))\n\t\t\treturn t;\n\t\tt = t->pNext;\n\t}\n\n\treturn NULL;\n}\n\nint cxxTokenChainFirstKeywordIndex(\n\t\tCXXTokenChain * tc,\n\t\tCXXKeyword eKeyword\n\t)\n{\n\tif(!tc)\n\t\treturn -1;\n\tif(tc->iCount < 1)\n\t\treturn -1;\n\n\tCXXToken * pToken = tc->pHead;\n\tint idx = 0;\n\twhile(pToken)\n\t{\n\t\tif(cxxTokenIsKeyword(pToken,eKeyword))\n\t\t\treturn idx;\n\t\tidx++;\n\t\tpToken = pToken->pNext;\n\t}\n\n\treturn -1;\n}\n\n// This is working code but it's unused and coveralls complains.. sigh.\n// Remove the #if above if needed.\nCXXToken * cxxTokenChainFirstKeyword(\n\t\tCXXTokenChain * tc,\n\t\tCXXKeyword eKeyword\n\t)\n{\n\tif(!tc)\n\t\treturn NULL;\n\tif(tc->iCount < 1)\n\t\treturn NULL;\n\n\tCXXToken * pToken = tc->pHead;\n\twhile(pToken)\n\t{\n\t\tif(cxxTokenIsKeyword(pToken,eKeyword))\n\t\t\treturn pToken;\n\t\tpToken = pToken->pNext;\n\t}\n\n\treturn NULL;\n}\n\nCXXToken * cxxTokenChainNextIdentifier(\n\t\tCXXToken * from,\n\t\tconst char * szIdentifier\n\t)\n{\n\tif(!from)\n\t\treturn NULL;\n\n\tCXXToken * t = from->pNext;\n\twhile(t)\n\t{\n\t\tif(\n\t\t\tcxxTokenTypeIs(t,CXXTokenTypeIdentifier) &&\n\t\t\t(strcmp(vStringValue(t->pszWord),szIdentifier) == 0)\n\t\t)\n\t\t\treturn t;\n\t\tt = t->pNext;\n\t}\n\n\treturn NULL;\n}\n\nvoid cxxTokenChainDestroyRange(CXXTokenChain * pChain,CXXToken * from,CXXToken * to)\n{\n\tif(!from || !to)\n\t\treturn;\n\tCXX_DEBUG_ASSERT(from,\"Bad from pointer passed to cxxTokenChainDestroyRange\");\n\tCXX_DEBUG_ASSERT(to,\"Bad to pointer passed to cxxTokenChainDestroyRange\");\n\n\tfor(;;)\n\t{\n\t\tCXXToken * next = from->pNext;\n\t\tcxxTokenChainTake(pChain,from);\n\t\tcxxTokenDestroy(from);\n\t\tif(from == to) // may be compared even if invalid\n\t\t\treturn;\n\t\tfrom = next;\n\t\tCXX_DEBUG_ASSERT(from,\"Should NOT have found chain termination here\");\n\t}\n}\n\n\nCXXToken * cxxTokenChainExtractRange(\n\t\tCXXToken * from,\n\t\tCXXToken * to,\n\t\tunsigned int uFlags\n\t)\n{\n\tif(!from)\n\t\treturn NULL;\n\n\tCXXToken * pToken = from;\n\n\tCXXToken * pRet = cxxTokenCreate();\n\tpRet->iLineNumber = pToken->iLineNumber;\n\tpRet->oFilePosition = pToken->oFilePosition;\n\tpRet->eType = pToken->eType;\n\n\tcxxTokenAppendToString(pRet->pszWord,pToken);\n\tif(\n\t\t\t(!(uFlags & CXXTokenChainExtractRangeNoTrailingSpaces)) &&\n\t\t\tpToken->bFollowedBySpace\n\t\t)\n\t\tvStringPut (pRet->pszWord, ' ');\n\tpRet->bFollowedBySpace = pToken->bFollowedBySpace;\n\n\twhile(pToken != to)\n\t{\n\t\tpToken = pToken->pNext;\n\t\tif(!pToken)\n\t\t\treturn pRet;\n\t\tcxxTokenAppendToString(pRet->pszWord,pToken);\n\t\tif(\n\t\t\t\t(!(uFlags & CXXTokenChainExtractRangeNoTrailingSpaces)) &&\n\t\t\t\tpToken->bFollowedBySpace\n\t\t\t)\n\t\t\tvStringPut (pRet->pszWord, ' ');\n\t\tpRet->bFollowedBySpace = pToken->bFollowedBySpace;\n\t}\n\n\treturn pRet;\n}\n\nCXXToken * cxxTokenChainExtractRangeFilterTypeName(\n\t\tCXXToken * from,\n\t\tCXXToken * to\n\t)\n{\n\tif(!from)\n\t\treturn NULL;\n\n\tCXXToken * pToken = from;\n\tfor(;;)\n\t{\n\t\tif(!cxxTokenTypeIs(pToken,CXXTokenTypeKeyword))\n\t\t\tbreak;\n\t\tif(!cxxKeywordExcludeFromTypeNames(pToken->eKeyword))\n\t\t\tbreak;\n\t\t// must be excluded\n\t\tif(pToken == to)\n\t\t\treturn NULL; // only excluded keywords\n\t\tpToken = pToken->pNext;\n\t\tif(!pToken)\n\t\t\treturn NULL; // ... bug?\n\t}\n\n\t// Got at least one non-excluded keyword\n\tCXXToken * pRet = cxxTokenCreate();\n\tpRet->iLineNumber = pToken->iLineNumber;\n\tpRet->oFilePosition = pToken->oFilePosition;\n\tpRet->eType = pToken->eType;\n\n\tcxxTokenAppendToString(pRet->pszWord,pToken);\n\tif(pToken->bFollowedBySpace)\n\t\tvStringPut (pRet->pszWord, ' ');\n\tpRet->bFollowedBySpace = pToken->bFollowedBySpace;\n\n\twhile(pToken != to)\n\t{\n\t\tpToken = pToken->pNext;\n\t\tif(!pToken)\n\t\t\treturn pRet; // ... bug?\n\n\t\tfor(;;)\n\t\t{\n\t\t\tif(!cxxTokenTypeIs(pToken,CXXTokenTypeKeyword))\n\t\t\t\tbreak;\n\t\t\tif(!cxxKeywordExcludeFromTypeNames(pToken->eKeyword))\n\t\t\t\tbreak;\n\t\t\t// must be excluded\n\t\t\tif(pToken == to)\n\t\t\t\treturn pRet;\n\t\t\tpToken = pToken->pNext;\n\t\t\tif(!pToken)\n\t\t\t\treturn pRet; // ... bug?\n\t\t}\n\n\t\tcxxTokenAppendToString(pRet->pszWord,pToken);\n\t\tif(pToken->bFollowedBySpace)\n\t\t\tvStringPut (pRet->pszWord, ' ');\n\t\tpRet->bFollowedBySpace = pToken->bFollowedBySpace;\n\t}\n\n\treturn pRet;\n}\n\n\nCXXToken * cxxTokenChainExtractIndexRange(\n\t\tCXXTokenChain * tc,\n\t\tint iFirstIndex,\n\t\tint iLastIndex,\n\t\tunsigned int uFlags\n\t)\n{\n\tif(!tc)\n\t\treturn NULL;\n\tif(iFirstIndex < 0)\n\t\treturn NULL;\n\tif(iFirstIndex >= tc->iCount)\n\t\treturn NULL;\n\n\tCXXToken * pToken = tc->pHead;\n\tint idx = 0;\n\twhile(pToken && (idx < iFirstIndex))\n\t{\n\t\tidx++;\n\t\tpToken = pToken->pNext;\n\t}\n\n\tif(!pToken)\n\t\treturn NULL;\n\n\tCXXToken * pRet = cxxTokenCreate();\n\tpRet->iLineNumber = pToken->iLineNumber;\n\tpRet->oFilePosition = pToken->oFilePosition;\n\tpRet->eType = pToken->eType;\n\n\tcxxTokenAppendToString(pRet->pszWord,pToken);\n\tif(\n\t\t\t(!(uFlags & CXXTokenChainExtractRangeNoTrailingSpaces)) &&\n\t\t\tpToken->bFollowedBySpace\n\t\t)\n\t\tvStringPut (pRet->pszWord, ' ');\n\tpRet->bFollowedBySpace = pToken->bFollowedBySpace;\n\n\twhile(idx < iLastIndex)\n\t{\n\t\tpToken = pToken->pNext;\n\t\tif(!pToken)\n\t\t\treturn pRet;\n\t\tcxxTokenAppendToString(pRet->pszWord,pToken);\n\t\tif(\n\t\t\t\t(!(uFlags & CXXTokenChainExtractRangeNoTrailingSpaces)) &&\n\t\t\t\tpToken->bFollowedBySpace\n\t\t\t)\n\t\t\tvStringPut (pRet->pszWord, ' ');\n\t\tpRet->bFollowedBySpace = pToken->bFollowedBySpace;\n\t\tidx++;\n\t}\n\n\treturn pRet;\n}\n\nvoid cxxTokenChainNormalizeTypeNameSpacing(CXXTokenChain * pChain)\n{\n\tif(!pChain)\n\t\treturn;\n\n\tif(pChain->iCount < 1)\n\t\treturn;\n\n\tcxxTokenChainNormalizeTypeNameSpacingInRange(pChain->pHead,pChain->pTail);\n}\n\nvoid cxxTokenChainNormalizeTypeNameSpacingInRange(CXXToken * pFrom,CXXToken * pTo)\n{\n\tif(!pFrom || !pTo)\n\t\treturn;\n\n\t// Goals:\n\n\t// int\n\t// unsigned short int\n\t// int *\n\t// unsigned short int **\n\t// const Class &\n\t// Class &&\n\t// int (*)(type &,type *)\n\t// unsigned short int[3];\n\t// ClassA<ClassB<type *,type>> <-- fixme: not sure about the trailing >>\n\t// Class<Something> (*)(type[])\n\t// decltype(something)\n\n\tCXXToken * t = pFrom;\n\n\tfor(;;)\n\t{\n\t\tif(cxxTokenTypeIsOneOf(\n\t\t\t\tt,\n\t\t\t\tCXXTokenTypeParenthesisChain | CXXTokenTypeSquareParenthesisChain\n\t\t\t))\n\t\t{\n\t\t\t// decltype(a) const\n\t\t\t// -----------^\n\t\t\t// In this case, a space is needed.\n\t\t\tbool bFollowedBySpace = (\n\t\t\t\t\tt->pPrev &&\n\t\t\t\t\tcxxTokenTypeIs(t->pPrev,CXXTokenTypeKeyword) &&\n\t\t\t\t\tcxxKeywordIsDecltype(t->pPrev->eKeyword)\n\t\t\t\t);\n\t\t\tcxxTokenChainNormalizeTypeNameSpacing(t->pChain);\n\t\t\tt->bFollowedBySpace = bFollowedBySpace;\n\t\t} else if(cxxTokenTypeIs(t,CXXTokenTypeKeyword))\n\t\t{\n\t\t\tt->bFollowedBySpace = t->pNext &&\n\t\t\t\t(!cxxKeywordIsDecltype(t->eKeyword)) &&\n\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\tt->pNext,\n\t\t\t\t\t\tCXXTokenTypeParenthesisChain | CXXTokenTypeIdentifier |\n\t\t\t\t\t\t\tCXXTokenTypeKeyword | CXXTokenTypeStar |\n\t\t\t\t\t\t\tCXXTokenTypeAnd | CXXTokenTypeMultipleAnds\n\t\t\t\t\t);\n\t\t} else if(cxxTokenTypeIsOneOf(t,\n\t\t\t\t\tCXXTokenTypeIdentifier |\n\t\t\t\t\t\tCXXTokenTypeGreaterThanSign |\n\t\t\t\t\t\tCXXTokenTypeAnd | CXXTokenTypeMultipleAnds\n\t\t\t\t))\n\t\t{\n\t\t\tt->bFollowedBySpace = t->pNext &&\n\t\t\t\tcxxTokenTypeIsOneOf(\n\t\t\t\t\t\tt->pNext,\n\t\t\t\t\t\tCXXTokenTypeParenthesisChain | CXXTokenTypeIdentifier |\n\t\t\t\t\t\t\tCXXTokenTypeKeyword | CXXTokenTypeStar |\n\t\t\t\t\t\t\tCXXTokenTypeAnd | CXXTokenTypeMultipleAnds\n\t\t\t\t\t);\n\t\t} else if(cxxTokenTypeIs(t,CXXTokenTypeStar))\n\t\t{\n\t\t\tt->bFollowedBySpace = t->pNext &&\n\t\t\t\t(!cxxTokenTypeIsOneOf(\n\t\t\t\t\t\tt->pNext,\n\t\t\t\t\t\tCXXTokenTypeStar | CXXTokenTypeComma |\n\t\t\t\t\t\t\tCXXTokenTypeClosingParenthesis\n\t\t\t\t\t));\n\t\t} else {\n\t\t\tt->bFollowedBySpace = false;\n\t\t}\n\n\t\tif(t == pTo)\n\t\t\tbreak;\n\n\t\tt = t->pNext;\n\t}\n\n\t// Finally the chain has no space at end\n\tpTo->bFollowedBySpace = false;\n}\n"
  },
  {
    "path": "parsers/cxx/cxx_token_chain.h",
    "content": "#ifndef ctags_cxx_token_chain_h_\n#define ctags_cxx_token_chain_h_\n/*\n*   Copyright (c) 2016, Szymon Tomasz Stefanek\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning C++ source files\n*/\n\n#include \"general.h\"\n\n#include \"cxx_token.h\"\n#include \"cxx_keyword.h\"\n\nstruct _CXXTokenChain\n{\n\tCXXToken * pHead;\n\tCXXToken * pTail;\n\tint iCount;\n};\n\n// The struct is typedef'd in cxx_token.h\n// typedef struct _CXXTokenChain CXXTokenChain;\n\nCXXTokenChain * cxxTokenChainCreate(void);\nvoid cxxTokenChainDestroy(CXXTokenChain * tc);\n\n// Note: you don't need to call this after cxxTokenChainCreate().\nvoid cxxTokenChainInit(CXXTokenChain * tc);\n\nvoid cxxTokenChainClear(CXXTokenChain * tc);\n\n// Find a specified token and return its index\nint cxxTokenChainFindToken(CXXTokenChain * tc,CXXToken * t);\n\n// Find the first token with one of the specified types\nCXXToken * cxxTokenChainFirstTokenOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes\n\t);\n\n// Find the first token with one of the specified types that comes\n// after the specified token\nCXXToken * cxxTokenChainNextTokenOfType(\n\t\tCXXToken * t,\n\t\tunsigned int uTokenTypes\n\t);\n\n// Find the first token with one of the specified types that comes\n// before the specified token\nCXXToken * cxxTokenChainPreviousTokenOfType(\n\t\tCXXToken * t,\n\t\tunsigned int uTokenTypes\n\t);\n\n// Find the first token with that is not one of the specified types\n// that comes before the specified token\nCXXToken * cxxTokenChainPreviousTokenNotOfType(\n\t\tCXXToken * t,\n\t\tunsigned int uTokenTypes\n\t);\n\n// Find the last token with one of the specified types\nCXXToken * cxxTokenChainLastTokenOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes\n\t);\n\n// Find the last token with one of the specified types. Look also\n// in nested () chains (only (), not [], {}...)\nCXXToken * cxxTokenChainLastPossiblyNestedTokenOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes,\n\t\tCXXTokenChain ** ppParentChain\n\t);\n\n// Find the first token with one of the specified types. Look also\n// in nested () chains (only (), not [], {}...)\nCXXToken * cxxTokenChainFirstPossiblyNestedTokenOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes,\n\t\tCXXTokenChain ** ppParentChain\n\t);\n\n// Find the first token with type that is not one of the specified types\nCXXToken * cxxTokenChainFirstTokenNotOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes\n\t);\n\n\n// Find the first token with type that is not accepted by PREDICATOR.\n// PREDICATOR returns true when a token is acceptable.\nCXXToken * cxxTokenChainNextTokenNotOfGeneric(\n\t\tCXXToken * t,\n\t\tbool (* predicator) (CXXToken *, void *),\n\t\tvoid *data\n\t);\n\n// Find the first token with type that is not one of the specified types\n// that comes after the specified token\nCXXToken * cxxTokenChainNextTokenNotOfType(\n\t\tCXXToken * t,\n\t\tunsigned int uTokenTypes\n\t);\n\n// Find the last token with type that is not one of the specified types\nCXXToken * cxxTokenChainLastTokenNotOfType(\n\t\tCXXTokenChain * tc,\n\t\tunsigned int uTokenTypes\n\t);\n\n// Specialized function to skip from a < to the matching > (used for\n// templates). Nested <> pairs are skipped properly.\n// Parenthesis chains are assumed to be condensed.\n// Note that the function stops at the ending > and not past it.\nCXXToken * cxxTokenChainSkipToEndOfTemplateAngleBracket(\n\t\tCXXToken * t\n\t);\n\n// Specialized function to skip back from a > to the matching < (used for\n// templates). Nested <> pairs are skipped properly.\n// Parenthesis chains are assumed to be condensed.\n// Note that the function stops at the initial < and not past it.\nCXXToken * cxxTokenChainSkipBackToStartOfTemplateAngleBracket(\n\t\tCXXToken * t\n\t);\n\n#define cxxTokenChainFirst(tc) (tc ? tc->pHead : NULL)\n#define cxxTokenChainLast(tc) (tc ? tc->pTail : NULL)\n\nCXXToken * cxxTokenChainAt(CXXTokenChain * tc,int index);\n\nCXXToken * cxxTokenChainTakeFirst(CXXTokenChain * tc);\nCXXToken * cxxTokenChainTakeLast(CXXTokenChain * tc);\n#if 0\nCXXToken * cxxTokenChainTakeAt(CXXTokenChain * tc,int index);\n#endif\nvoid cxxTokenChainTake(CXXTokenChain * tc,CXXToken * t);\nbool cxxTokenChainTakeRecursive(CXXTokenChain * tc,CXXToken * t);\n\n// Destroy the last token\n#define cxxTokenChainDestroyLast(tc) \\\n\t\tcxxTokenDestroy(cxxTokenChainTakeLast(tc))\n\n// Destroy the first token\n#define cxxTokenChainDestroyFirst(tc) \\\n\t\tcxxTokenDestroy(cxxTokenChainTakeFirst(tc))\n\nvoid cxxTokenChainDestroyRange(CXXTokenChain * pChain,CXXToken * from,CXXToken * to);\n\nvoid cxxTokenChainAppend(CXXTokenChain * tc,CXXToken * t);\nvoid cxxTokenChainPrepend(CXXTokenChain * tc,CXXToken * t);\nvoid cxxTokenChainInsertAfter(CXXTokenChain * tc,CXXToken * before,CXXToken * t);\n\n// Move tokens in SRC to the end of DEST.\n// Unlike cxxTokenChainMoveEntries, cxxTokenChainAppendEntries keeps\n// tokens in DEST.\n// SRC becomes empty.\nvoid cxxTokenChainAppendEntries(CXXTokenChain * src, CXXTokenChain * dest);\n\n#if 0\n// currently unused\nvoid cxxTokenChainMoveEntries(\n\t\tCXXTokenChain * src,\n\t\tCXXTokenChain * dest\n\t);\n\nvoid cxxTokenChainMoveEntryRange(\n\t\tCXXTokenChain * src,\n\t\tCXXToken * start,\n\t\tCXXToken * end,\n\t\tCXXTokenChain * dest\n\t);\n#endif\n\nenum CXXTokenChainJoinFlags\n{\n\t// Do not add trailing spaces for entries that are followed by space\n\tCXXTokenChainJoinNoTrailingSpaces = 1\n};\n\nvoid cxxTokenChainJoinInString(\n\t\tCXXTokenChain * tc,\n\t\tvString * s,\n\t\tconst char * szSeparator,\n\t\tunsigned int uFlags\n\t);\nvString * cxxTokenChainJoin(\n\t\tCXXTokenChain * tc,\n\t\tconst char * szSeparator,\n\t\tunsigned int uFlags\n\t);\n\nvoid cxxTokenChainJoinRangeInString(\n\t\tCXXToken * from,\n\t\tCXXToken * to,\n\t\tvString * s,\n\t\tconst char * szSeparator,\n\t\tunsigned int uFlags\n\t);\nvString * cxxTokenChainJoinRange(\n\t\tCXXToken * from,\n\t\tCXXToken * to,\n\t\tconst char * szSeparator,\n\t\tunsigned int uFlags\n\t);\n\n// Treat the token chain tc as a comma separated sequence\n// of items (something, blah foo, 1 2 3 4 5, ...)\n// Create a token chain that contains tokens corresponding\n// to each item (i.e, \"something\", \"blah foo\", \"1 2 3 4 5\").\n// Please note that the returned chain may be empty!\nCXXTokenChain * cxxTokenChainSplitOnComma(CXXTokenChain * tc);\n\n\nenum CXXTokenChainCondenseFlags\n{\n\t// Do not add trailing spaces for entries that are followed by space\n\tCXXTokenChainCondenseNoTrailingSpaces = 1\n};\n\nCXXToken * cxxTokenChainCondenseIntoToken(CXXTokenChain * tc,unsigned int uFlags);\nvoid cxxTokenChainCondense(CXXTokenChain * tc,unsigned int uFlags);\n\n\nenum CXXTokenChainExtractRangeFlags\n{\n\tCXXTokenChainExtractRangeNoTrailingSpaces = 1\n};\n\nCXXToken * cxxTokenChainExtractRange(\n\t\tCXXToken * from,\n\t\tCXXToken * to,\n\t\tunsigned int uFlags\n\t);\n\nCXXToken * cxxTokenChainExtractRangeFilterTypeName(\n\t\tCXXToken * from,\n\t\tCXXToken * to\n\t);\n\nCXXToken * cxxTokenChainExtractIndexRange(\n\t\tCXXTokenChain * tc,\n\t\tint iFirstIndex,\n\t\tint iLastIndex,\n\t\tunsigned int uFlags\n\t);\n\nCXXToken * cxxTokenChainPreviousKeyword(\n\t\tCXXToken * from,\n\t\tCXXKeyword eKeyword\n\t);\n\nCXXToken * cxxTokenChainNextKeyword(\n\t\tCXXToken * from,\n\t\tCXXKeyword eKeyword\n\t);\n\nCXXToken * cxxTokenChainNextIdentifier(\n\t\tCXXToken * from,\n\t\tconst char * szIdentifier\n\t);\n\nint cxxTokenChainFirstKeywordIndex(\n\t\tCXXTokenChain * tc,\n\t\tCXXKeyword eKeyword\n\t);\n\nCXXToken * cxxTokenChainFirstKeyword(\n\t\tCXXTokenChain * tc,\n\t\tCXXKeyword eKeyword\n\t);\n\n// Assuming that pChain contains a type name, attempt to normalize the\n// spacing within the whole chain.\n//\n// Please note that this will work also for entire function signatures\n// (since type names can contain function pointers which have signatures)\nvoid cxxTokenChainNormalizeTypeNameSpacing(\n\t\tCXXTokenChain * pChain\n\t);\nvoid cxxTokenChainNormalizeTypeNameSpacingInRange(\n\t\tCXXToken * pFrom,\n\t\tCXXToken * pTo\n\t);\n\n#endif //!ctags_cxx_token_chain_h_\n"
  },
  {
    "path": "parsers/d-rust.h",
    "content": "/* Automatically generated by misc/debuggen/rust.sh */\n\n#ifndef CTAGS_PARSER_DEBUG_RUST_H\n#define CTAGS_PARSER_DEBUG_RUST_H\n\n#ifdef DO_TRACING\n#include \"vstring.h\"\n\nstatic const char *decodeTokenType(enum eTokenType e)\n{ /* Generated by misc/enumstr.sh with cmdline:\n     misc/enumstr.sh ./parsers/rust.c eTokenType decodeTokenType TOKEN_  */\n\tswitch (e)\n\t{\n\t\tcase     TOKEN_WHITESPACE: return \"WHITESPACE\";\n\t\tcase         TOKEN_STRING: return \"STRING\";\n\t\tcase          TOKEN_IDENT: return \"IDENT\";\n\t\tcase         TOKEN_LSHIFT: return \"LSHIFT\";\n\t\tcase         TOKEN_RSHIFT: return \"RSHIFT\";\n\t\tcase         TOKEN_RARROW: return \"RARROW\";\n\t\tcase            TOKEN_EOF: return \"EOF\";\n\t\tdefault:                   return \"UNKNOWN\";\n\t}\n}\n\n\n#endif /* DO_TRACING */\n#endif /* CTAGS_PARSER_DEBUG_RUST_H */\n"
  },
  {
    "path": "parsers/d-typescript.h",
    "content": "/* Automatically generated by misc/debuggen/typescript.sh */\n\n#ifndef CTAGS_PARSER_DEBUG_TYPESCRIPT_H\n#define CTAGS_PARSER_DEBUG_TYPESCRIPT_H\n\n#ifdef DO_TRACING\n#include \"vstring.h\"\n\nstatic const char *decodeTokenType(enum eTokenType e)\n{ /* Generated by misc/enumstr.sh with cmdline:\n     misc/enumstr.sh ./parsers/typescript.c eTokenType decodeTokenType TOKEN_  */\n\tswitch (e)\n\t{\n\t\tcase      TOKEN_UNDEFINED: return \"UNDEFINED\";\n\t\tcase            TOKEN_EOF: return \"EOF\";\n\t\tcase      TOKEN_CHARACTER: return \"CHARACTER\";\n\t\tcase      TOKEN_SEMICOLON: return \"SEMICOLON\";\n\t\tcase          TOKEN_COLON: return \"COLON\";\n\t\tcase  TOKEN_QUESTION_MARK: return \"QUESTION_MARK\";\n\t\tcase          TOKEN_COMMA: return \"COMMA\";\n\t\tcase        TOKEN_KEYWORD: return \"KEYWORD\";\n\t\tcase     TOKEN_IDENTIFIER: return \"IDENTIFIER\";\n\t\tcase         TOKEN_STRING: return \"STRING\";\n\t\tcase        TOKEN_GENERIC: return \"GENERIC\";\n\t\tcase         TOKEN_PERIOD: return \"PERIOD\";\n\t\tcase     TOKEN_OPEN_CURLY: return \"OPEN_CURLY\";\n\t\tcase    TOKEN_CLOSE_CURLY: return \"CLOSE_CURLY\";\n\t\tcase     TOKEN_OPEN_PAREN: return \"OPEN_PAREN\";\n\t\tcase    TOKEN_CLOSE_PAREN: return \"CLOSE_PAREN\";\n\t\tcase    TOKEN_OPEN_SQUARE: return \"OPEN_SQUARE\";\n\t\tcase   TOKEN_CLOSE_SQUARE: return \"CLOSE_SQUARE\";\n\t\tcase     TOKEN_EQUAL_SIGN: return \"EQUAL_SIGN\";\n\t\tcase           TOKEN_STAR: return \"STAR\";\n\t\tcase             TOKEN_NL: return \"NL\";\n\t\tcase  TOKEN_COMMENT_BLOCK: return \"COMMENT_BLOCK\";\n\t\tcase         TOKEN_PARENS: return \"PARENS\";\n\t\tcase        TOKEN_SQUARES: return \"SQUARES\";\n\t\tcase        TOKEN_CURLIES: return \"CURLIES\";\n\t\tcase           TOKEN_PIPE: return \"PIPE\";\n\t\tcase      TOKEN_AMPERSAND: return \"AMPERSAND\";\n\t\tcase          TOKEN_ARROW: return \"ARROW\";\n\t\tcase         TOKEN_NUMBER: return \"NUMBER\";\n\t\tcase             TOKEN_AT: return \"AT\";\n\t\tcase          TOKEN_MINUS: return \"MINUS\";\n\t\tcase           TOKEN_PLUS: return \"PLUS\";\n\t\tcase           TOKEN_BANG: return \"BANG\";\n\t\tcase            TOKEN_DIV: return \"DIV\";\n\t\tcase          TOKEN_POWER: return \"POWER\";\n\t\tcase        TOKEN_GREATER: return \"GREATER\";\n\t\tcase          TOKEN_LOWER: return \"LOWER\";\n\t\tdefault:                   return \"UNKNOWN\";\n\t}\n}\n\nstatic const char *decodeKeywordId(enum eKeywordId e)\n{ /* Generated by misc/enumstr.sh with cmdline:\n     misc/enumstr.sh ./parsers/typescript.c eKeywordId decodeKeywordId KEYWORD_  */\n\tswitch (e)\n\t{\n\t\tcase           KEYWORD_as: return \"as\";\n\t\tcase        KEYWORD_async: return \"async\";\n\t\tcase        KEYWORD_await: return \"await\";\n\t\tcase        KEYWORD_class: return \"class\";\n\t\tcase  KEYWORD_constructor: return \"constructor\";\n\t\tcase        KEYWORD_const: return \"const\";\n\t\tcase         KEYWORD_enum: return \"enum\";\n\t\tcase      KEYWORD_extends: return \"extends\";\n\t\tcase          KEYWORD_for: return \"for\";\n\t\tcase     KEYWORD_function: return \"function\";\n\t\tcase   KEYWORD_instanceof: return \"instanceof\";\n\t\tcase           KEYWORD_in: return \"in\";\n\t\tcase    KEYWORD_interface: return \"interface\";\n\t\tcase   KEYWORD_implements: return \"implements\";\n\t\tcase          KEYWORD_let: return \"let\";\n\t\tcase    KEYWORD_namespace: return \"namespace\";\n\t\tcase          KEYWORD_new: return \"new\";\n\t\tcase           KEYWORD_of: return \"of\";\n\t\tcase      KEYWORD_private: return \"private\";\n\t\tcase    KEYWORD_protected: return \"protected\";\n\t\tcase       KEYWORD_public: return \"public\";\n\t\tcase       KEYWORD_return: return \"return\";\n\t\tcase     KEYWORD_readonly: return \"readonly\";\n\t\tcase       KEYWORD_static: return \"static\";\n\t\tcase         KEYWORD_this: return \"this\";\n\t\tcase         KEYWORD_type: return \"type\";\n\t\tcase       KEYWORD_typeof: return \"typeof\";\n\t\tcase          KEYWORD_var: return \"var\";\n\t\tcase        KEYWORD_while: return \"while\";\n\t\tdefault:                   return \"UNKNOWN\";\n\t}\n}\n\nstatic const char *decodeToken (const tokenInfo *t)\n{\n\tstatic vString *buf;\n\tbuf = vStringNewOrClearWithAutoRelease (buf);\n\tvStringCopyS (buf, \"type: \");\n\tvStringCatS (buf, decodeTokenType (t->type));\n\tif (t->type == TOKEN_KEYWORD)\n\t{\n\t\tvStringCatS (buf, \", keyword: \");\n\t\tvStringCatS (buf, decodeKeywordId (t->keyword));\n\t}\n\treturn vStringValue (buf);\n}\n\n\n#endif /* DO_TRACING */\n#endif /* CTAGS_PARSER_DEBUG_TYPESCRIPT_H */\n"
  },
  {
    "path": "parsers/dbus-introspect.c",
    "content": "/*\n*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for\n*   <!DOCTYPE node PUBLIC\n*             \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n*             \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n*   and\n*\n*\t<!DOCTYPE node PUBLIC\n*             \"-//freedesktop//DTD D-BUS Introspection 0.1//EN\"\n*             \"http://www.freedesktop.org/software/dbus/introspection.dtd\">\n**\n*/\n\n#include \"general.h\"\t/* must always come first */\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"x-xml.h\"\n\n#include <string.h>\n\n\ntypedef enum {\n\tK_ARG, K_INTERFACE, K_METHOD, K_SIGNAL, K_PROPERTY, K_NODE,\n} dbusIntrospectKind;\n\nstatic kindDefinition DbusIntrospectKinds [] = {\n\t{ true,  'a', \"arg\",       \"arguments\"  },\n\t{ true,  'i', \"interface\", \"interfaces\" },\n\t{ true,  'm', \"method\",    \"methods\"    },\n\t{ true,  's', \"signal\",    \"signals\"    },\n\t{ true,  'p', \"property\",  \"properties\" },\n\t{ true,  'n', \"node\",      \"nodes\"      },\n};\n\nstatic void dbusIntrospectFindTagsUnderMain (xmlNode *node,\n\t\t\t\t\t\t  const char *xpath,\n\t\t\t\t\t\t  const struct sTagXpathRecurSpec *spec,\n\t\t\t\t\t\t  xmlXPathContext *ctx,\n\t\t\t\t\t\t  void *userData);\nstatic void makeTagForMainName (xmlNode *node,\n\t\t\t\t     const char *xpath,\n\t\t\t\t     const struct sTagXpathMakeTagSpec *spec,\n\t\t\t\t     struct sTagEntryInfo *tag,\n\t\t\t\t     void *userData);\nstatic void makeTagWithScope (xmlNode *node,\n\t\t\t      const char *xpath,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec,\n\t\t\t      struct sTagEntryInfo *tag,\n\t\t\t      void *userData);\nstatic int decideKindForMainName (xmlNode *node,\n\t\t\t\t  const char *xpath,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec,\n\t\t\t      void *userData);\n\nstruct dbusIntrospectData {\n\tint scopeIndex;\n\tint kindForName;\n};\n\nstatic tagXpathTable dbusIntrospectXpathArgTable [] = {\n\t{ \"arg\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { dbusIntrospectFindTagsUnderMain,\n\t\t\t\t\t   -1 } },\n\t},\n};\n\nenum dbusIntrospectXpathTable {\n\tTABLE_ROOT, TABLE_MAIN, TABLE_INTERFACE, TABLE_MAIN_NAME, TABLE_ARG,\n};\n\nstatic tagXpathTable dbusIntrospectXpathInterfaceTable [] = {\n\t{ \"method\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { dbusIntrospectFindTagsUnderMain,\n\t\t\t\t\t   TABLE_ARG, } }\n\t},\n\t{ \"signal\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { dbusIntrospectFindTagsUnderMain,\n\t\t\t\t\t   TABLE_ARG, } }\n\t},\n\t{ \"property/@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_PROPERTY, ROLE_DEFINITION_INDEX,\n\t\t\t\t\t\t makeTagWithScope, } }\n\t},\n};\n\nstatic tagXpathTable dbusIntrospectXpathMainTable [] = {\n\t{ \"interface\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { dbusIntrospectFindTagsUnderMain,\n\t\t\t\t\t   TABLE_INTERFACE, } }\n\t},\n\t{ \"node\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { dbusIntrospectFindTagsUnderMain,\n\t\t\t\t\t   TABLE_MAIN, } }\n\t},\n};\n\nstatic tagXpathTable dbusIntrospectXpathMainNameTable [] = {\n\t{ \"@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { KIND_GHOST_INDEX, ROLE_DEFINITION_INDEX,\n\t\t\t     makeTagForMainName,\n\t\t\t     decideKindForMainName } }\n\t},\n};\n\nstatic tagXpathTable dbusIntrospectXpathRootTable [] = {\n\t{ \"/node\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { dbusIntrospectFindTagsUnderMain,\n\t\t\t\t\t   TABLE_MAIN, } }\n\t},\n};\n\nstatic tagXpathTableTable dbusIntrospectXpathTableTable[] = {\n\t[TABLE_ROOT]      = { ARRAY_AND_SIZE (dbusIntrospectXpathRootTable)     },\n\t[TABLE_MAIN]      = { ARRAY_AND_SIZE (dbusIntrospectXpathMainTable)     },\n\t[TABLE_INTERFACE] = { ARRAY_AND_SIZE (dbusIntrospectXpathInterfaceTable)},\n\t[TABLE_MAIN_NAME] = { ARRAY_AND_SIZE (dbusIntrospectXpathMainNameTable) },\n\t[TABLE_ARG]       = { ARRAY_AND_SIZE (dbusIntrospectXpathArgTable)      },\n};\n\nstatic void dbusIntrospectFindTagsUnderMain (xmlNode *node,\n\t\t\t\t\t\t  const char *xpath,\n\t\t\t\t\t\t  const struct sTagXpathRecurSpec *spec,\n\t\t\t\t\t\t  xmlXPathContext *ctx,\n\t\t\t\t\t\t  void *userData)\n{\n\tstruct dbusIntrospectData *data = userData;\n\tint scopeIndex = data->scopeIndex;\n\n\tif (!strcmp(xpath, \"interface\"))\n\t\tdata->kindForName = K_INTERFACE;\n\telse if (!strcmp (xpath, \"method\"))\n\t\tdata->kindForName = K_METHOD;\n\telse if (!strcmp (xpath, \"signal\"))\n\t\tdata->kindForName = K_SIGNAL;\n\telse if (!strcmp (xpath, \"arg\"))\n\t\tdata->kindForName = K_ARG;\n\telse\n\t\tdata->kindForName = K_NODE;\n\n\tfindXMLTags (ctx, node, TABLE_MAIN_NAME, data);\n\tif (spec->nextTable >= 0)\n\t\tfindXMLTags (ctx, node, spec->nextTable, data);\n\tdata->scopeIndex = scopeIndex;\n}\n\nstatic void makeTagWithScope (xmlNode *node CTAGS_ATTR_UNUSED,\n\t\t\t      const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t      struct sTagEntryInfo *tag,\n\t\t\t      void *userData)\n{\n\tstruct dbusIntrospectData *data = userData;\n\n\ttag->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;\n\ttag->extensionFields.scopeName  = NULL;\n\ttag->extensionFields.scopeIndex = data->scopeIndex;\n\n\tmakeTagEntry (tag);\n}\n\nstatic void makeTagForMainName (xmlNode *node CTAGS_ATTR_UNUSED,\n\t\t\t\t     const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\t     const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t\t     struct sTagEntryInfo *tag,\n\t\t\t\t     void *userData)\n{\n\tstruct dbusIntrospectData *data = userData;\n\n\ttag->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;\n\ttag->extensionFields.scopeName  = NULL;\n\ttag->extensionFields.scopeIndex = data->scopeIndex;\n\n\tdata->scopeIndex = makeTagEntry (tag);\n}\n\nstatic int decideKindForMainName (xmlNode *node CTAGS_ATTR_UNUSED,\n\t\t\t      const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t      void *userData)\n{\n\treturn ((struct dbusIntrospectData *)userData)->kindForName;\n}\n\nstatic void\nfindDbusIntrospectTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic void\nrunXPathEngine(xmlSubparser *s,\n\t\t\t   xmlXPathContext *ctx, xmlNode *root)\n{\n\tstruct dbusIntrospectData data = {\n\t\t.scopeIndex = CORK_NIL,\n\t\t.kindForName = KIND_GHOST_INDEX,\n\t};\n\tfindXMLTags (ctx, root, TABLE_ROOT, &data);\n}\n\nstatic xmlSubparser dbusIntrospectSubparser = {\n\t.subparser = {\n\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t},\n\t.runXPathEngine = runXPathEngine,\n};\n\nextern parserDefinition*\nDbusIntrospectParser (void)\n{\n\tstatic const char *const extensions [] = { \"xml\", NULL };\n\tparserDefinition* const def = parserNew (\"DBusIntrospect\");\n\tstatic selectLanguage selectors[] = { selectByXpathFileSpec, NULL };\n\n\tstatic xpathFileSpec xpathFileSpecs[] = {\n\t\t{\n\t\t\t/* <!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n\t\t\t   \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n\t\t\t   <node ... */\n\t\t\t.externalID = \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\",\n\t\t\t.systemID   = \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\",\n\t\t},\n\t\t{\n\t\t\t.externalID = \"-//freedesktop//DTD D-BUS Introspection 0.1//EN\",\n\t\t\t.systemID = \"http://www.freedesktop.org/software/dbus/introspection.dtd\",\n\t\t},\n\t\t/* TODO: the following rule is too strong; parsers may conflicts each other\n\t\t * when we implement more xpath based parsers. */\n\t\t{\n\t\t\t.rootElementName = \"node\",\n\t\t\t.nameInDTD       = \"\",\n\t\t\t.externalID      = \"\",\n\t\t\t.systemID        = \"\",\n\t\t\t.rootNSPrefix    = \"\",\n\t\t\t.rootNSHref      = \"\",\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"XML\", &dbusIntrospectSubparser },\n\t};\n\tdef->kindTable         = DbusIntrospectKinds;\n\tdef->kindCount     = ARRAY_SIZE (DbusIntrospectKinds);\n\tdef->extensions    = extensions;\n\tdef->parser        = findDbusIntrospectTags;\n\tdef->tagXpathTableTable = dbusIntrospectXpathTableTable;\n\tdef->tagXpathTableCount = ARRAY_SIZE (dbusIntrospectXpathTableTable);\n\tdef->useCork = CORK_QUEUE;\n\tdef->selectLanguage = selectors;\n\tdef->xpathFileSpecs = xpathFileSpecs;\n\tdef->xpathFileSpecCount = ARRAY_SIZE (xpathFileSpecs);\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/dbus-service.c",
    "content": "/*\n*\n*   Copyright (c) 2015, Red Hat, Inc.\n*   Copyright (c) 2015, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"x-iniconf.h\"\n#include \"x-systemdunit.h\"\n#include \"parse.h\"\n#include \"selectors.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_NAME,\n} dbusServiceKind;\n\nstatic kindDefinition DbusServiceKinds [] = {\n\t{ true, 'n', \"name\", \"names\" },\n};\n\nstatic langType Lang_systemdunit;\n\nstatic void newDataCallback (iniconfSubparser *s CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t const char *section, const char *key, const char *value)\n{\n\tif (section && key && strcmp (section, \"D-BUS Service\") == 0)\n\t{\n\t\ttagEntryInfo e;\n\t\tif (strcmp (key, \"Name\") == 0)\n\t\t{\n\t\t\tinitTagEntry (&e, value, K_NAME);\n\t\t\tmakeTagEntry (&e);\n\t\t}\n\t\telse if (strcmp (key, \"SystemdService\") == 0)\n\t\t{\n\t\t\tinitForeignRefTagEntry(&e, value, Lang_systemdunit,\n\t\t\t\t\t\t\t\t   SYSTEMD_UNIT_KIND, SYSTEMD_UNIT_FOREIGNLANG_ROLE);\n\t\t\tmakeTagEntry (&e);\n\t\t}\n\t\t/* TODO: Exec, User */\n\t}\n}\n\nstatic void findDbusServiceTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* DbusServiceParser (void)\n{\n\tstatic const char *const extensions [] = { \"service\", NULL };\n\tstatic iniconfSubparser dbusServiceSubparser = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t},\n\t\t.newDataNotify = newDataCallback,\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Iniconf\", &dbusServiceSubparser },\n\t\t[1] = { DEPTYPE_FOREIGNER, \"SystemdUnit\", &Lang_systemdunit },\n\t};\n\n\tstatic selectLanguage selectors[] = {\n\t\tselectByDBusServiceAndSystemdUnitSectionNames,\n\t\tNULL\n\t};\n\n\tparserDefinition* const def = parserNew (\"DBusService\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE(dependencies);\n\tdef->kindTable      = DbusServiceKinds;\n\tdef->kindCount  = ARRAY_SIZE (DbusServiceKinds);\n\tdef->extensions = extensions;\n\tdef->selectLanguage = selectors;\n\tdef->parser     = findDbusServiceTags;\n\tdef->useCork    = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/diff.c",
    "content": "/*\n*\n*   Copyright (c) 2000-2001, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for diff files (based on Sh parser).\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include <ctype.h>\n#include <string.h>\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_MODIFIED_FILE,\n\tK_NEW_FILE,\n\tK_DELETED_FILE,\n\tK_HUNK,\n} diffKind;\n\nstatic kindDefinition DiffKinds [] = {\n\t{ true, 'm', \"modifiedFile\",  \"modified files\"},\n\t{ true, 'n', \"newFile\",       \"newly created files\"},\n\t{ true, 'd', \"deletedFile\",   \"deleted files\"},\n\t{ true, 'h', \"hunk\",          \"hunks\"},\n};\n\nenum {\n\tDIFF_DELIM_MINUS = 0,\n\tDIFF_DELIM_PLUS\n};\n\nstatic const char *DiffDelims[2] = {\n\t\"--- \",\n\t\"+++ \"\n};\n\nstatic const char *HunkDelim[2] = {\n\t\"@@ \",\n\t\" @@\",\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic const unsigned char *stripAbsolute (const unsigned char *filename)\n{\n\tconst unsigned char *tmp;\n\n\t/* strip any absolute path */\n\tif (*filename == '/' || *filename == '\\\\')\n\t{\n\t\tbool skipSlash = true;\n\n\t\ttmp = (const unsigned char*) strrchr ((const char*) filename,  '/');\n\t\tif (tmp == NULL)\n\t\t{\t/* if no / is contained try \\ in case of a Windows filename */\n\t\t\ttmp = (const unsigned char*) strrchr ((const char*) filename, '\\\\');\n\t\t\tif (tmp == NULL)\n\t\t\t{\t/* last fallback, probably the filename doesn't contain a path, so take it */\n\t\t\t\ttmp = filename;\n\t\t\t\tskipSlash = false;\n\t\t\t}\n\t\t}\n\n\t\t/* skip the leading slash or backslash */\n\t\tif (skipSlash)\n\t\t\ttmp++;\n\t}\n\telse\n\t\ttmp = filename;\n\n\treturn tmp;\n}\n\nstatic int parseHunk (const unsigned char* cp, vString *hunk, int scope_index)\n{\n\t/*\n\t   example input: @@ -0,0 +1,134 @@\n\t   expected output: -0,0 +1,134\n\t*/\n\n\tconst char *next_delim;\n\tconst char *start, *end;\n\tconst char *c;\n\tint i = CORK_NIL;\n\n\tcp += 3;\n\tstart = (const char*)cp;\n\n\tif (*start != '-')\n\t\treturn i;\n\n\tnext_delim = strstr ((const char*)cp, HunkDelim[1]);\n\tif ((next_delim == NULL)\n\t    || (! (start < next_delim )))\n\t\treturn i;\n\tend = next_delim;\n\tif (! ( '0' <= *( end - 1 ) && *( end - 1 ) <= '9'))\n\t\treturn i;\n\tfor (c = start; c < end; c++)\n\t\tif (*c == '\\t')\n\t\t\treturn i;\n\tvStringNCopyS (hunk, start, end - start);\n\ti = makeSimpleTag (hunk, K_HUNK);\n\ttagEntryInfo *e =  getEntryInCorkQueue (i);\n\tif (e && scope_index > CORK_NIL)\n\t\te->extensionFields.scopeIndex = scope_index;\n\treturn i;\n}\n\nstatic void markTheLastTagAsDeletedFile (int scope_index)\n{\n\ttagEntryInfo *e =  getEntryInCorkQueue (scope_index);\n\n\tif (e)\n\t\te->kindIndex = K_DELETED_FILE;\n}\n\nstatic void findDiffTags (void)\n{\n\tvString *filename = vStringNew ();\n\tvString *hunk = vStringNew ();\n\tconst unsigned char *line, *tmp;\n\tint delim = DIFF_DELIM_MINUS;\n\tdiffKind kind;\n\tint scope_index = CORK_NIL;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char* cp = line;\n\n\t\tif (strncmp ((const char*) cp, DiffDelims[delim], 4u) == 0)\n\t\t{\n\t\t\tscope_index = CORK_NIL;\n\t\t\tcp += 4;\n\t\t\tif (isspace (*cp)) continue;\n\t\t\t/* when original filename is /dev/null use the new one instead */\n\t\t\tif (delim == DIFF_DELIM_MINUS &&\n\t\t\t\tstrncmp ((const char*) cp, \"/dev/null\", 9u) == 0 &&\n\t\t\t\t(cp[9] == 0 || isspace (cp[9])))\n\t\t\t{\n\t\t\t\tdelim = DIFF_DELIM_PLUS;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttmp = stripAbsolute (cp);\n\n\t\t\tif (tmp != NULL)\n\t\t\t{\n\t\t\t\twhile (! isspace(*tmp) && *tmp != '\\0')\n\t\t\t\t{\n\t\t\t\t\tvStringPut(filename, *tmp);\n\t\t\t\t\ttmp++;\n\t\t\t\t}\n\n\t\t\t\tif (delim == DIFF_DELIM_PLUS)\n\t\t\t\t\tkind = K_NEW_FILE;\n\t\t\t\telse\n\t\t\t\t\tkind = K_MODIFIED_FILE;\n\t\t\t\tscope_index = makeSimpleTag (filename, kind);\n\t\t\t\tvStringClear (filename);\n\t\t\t}\n\n\t\t\t/* restore default delim */\n\t\t\tdelim = DIFF_DELIM_MINUS;\n\t\t}\n\t\telse if ((scope_index > CORK_NIL)\n\t\t\t && (strncmp ((const char*) cp, DiffDelims[1], 4u) == 0))\n\t\t{\n\t\t\tcp += 4;\n\t\t\tif (isspace (*cp)) continue;\n\t\t\t/* when modified filename is /dev/null, the original name is deleted. */\n\t\t\tif (strncmp ((const char*) cp, \"/dev/null\", 9u) == 0 &&\n\t\t\t    (cp[9] == 0 || isspace (cp[9])))\n\t\t\t\tmarkTheLastTagAsDeletedFile (scope_index);\n\t\t}\n\t\telse if (strncmp ((const char*) cp, HunkDelim[0], 3u) == 0)\n\t\t{\n\t\t\tif (parseHunk (cp, hunk, scope_index) != CORK_NIL)\n\t\t\t\tvStringClear (hunk);\n\t\t}\n\t}\n\tvStringDelete (hunk);\n\tvStringDelete (filename);\n}\n\nextern parserDefinition* DiffParser (void)\n{\n\tstatic const char *const extensions [] = { \"diff\", \"patch\", NULL };\n\tparserDefinition* const def = parserNew (\"Diff\");\n\tdef->kindTable      = DiffKinds;\n\tdef->kindCount  = ARRAY_SIZE (DiffKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findDiffTags;\n\tdef->useCork    = CORK_QUEUE;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/dosbatch.c",
    "content": "/*\r\n*   Copyright (c) 2009, David Fishburn\r\n*\r\n*   This source code is released for free distribution under the terms of the\r\n*   GNU General Public License version 2 or (at your option) any later version.\r\n*\r\n*   This module contains functions for generating tags for DOS Batch language files.\r\n*/\r\n\r\n/*\r\n*   INCLUDE FILES\r\n*/\r\n#include \"general.h\"  /* must always come first */\r\n\r\n#include <string.h>\r\n#include \"parse.h\"\r\n#include \"routines.h\"\r\n#include \"selectors.h\"\r\n\r\nstatic tagRegexTable dosTagRegexTable [] = {\r\n\t{\"^:([A-Za-z_0-9]+)\", \"\\\\1\",\r\n\t \"l,label,labels\", NULL},\r\n\t{\"set[ \\t]+([A-Za-z_0-9]+)[ \\t]*=\", \"\\\\1\",\r\n\t \"v,variable,variables\", NULL},\r\n};\r\n\r\n/*\r\n*   FUNCTION DEFINITIONS\r\n*/\r\n\r\nextern parserDefinition* DosBatchParser (void)\r\n{\r\n\tstatic const char *const extensions [] = { \"bat\", \"cmd\", NULL };\r\n\tparserDefinition* const def = parserNew (\"DosBatch\");\r\n\tstatic selectLanguage selectors[] = { selectByRexxCommentAndDosbatchLabelPrefix,\r\n\t\t\t\t\t      NULL };\r\n\r\n\tdef->extensions = extensions;\r\n\tdef->tagRegexTable = dosTagRegexTable;\r\n\tdef->tagRegexCount = ARRAY_SIZE (dosTagRegexTable);\r\n\tdef->method     = METHOD_NOT_CRAFTED|METHOD_REGEX;\r\n\tdef->selectLanguage = selectors;\r\n\treturn def;\r\n}\r\n"
  },
  {
    "path": "parsers/dtd.c",
    "content": "/*\n *   Copyright (c) 2016, Masatake YAMATO\n *   Copyright (c) 2016, Red Hat, Inc.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for DTD, data type\n *   definition explained in https://www.w3.org/TR/REC-xml/#sec-physical-struct\n *\n */\n\n#include \"general.h\"\n#include \"tokeninfo.h\"\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"xtag.h\"\n\n\nstatic scopeSeparator DtdParameterEntrySeparators [] = {\n\t{ KIND_WILDCARD_INDEX, \"/%\" },\n};\n\nstatic scopeSeparator DtdAttSeparators [] = {\n\t{ KIND_WILDCARD_INDEX, \"/@\" },\n};\n\ntypedef enum {\n\tDTD_PARAMETER_ENTITY_ELEMENT_NAME,\n\tDTD_PARAMETER_ENTITY_CONDITION,\n\tDTD_PARAMETER_ENTITY_PART_OF_ATT_DEF,\n} dtdEntityRole;\n\nstatic roleDefinition DtdEntityRoles [] = {\n\t{ true, \"elementName\", \"element names\" },\n\t{ true, \"condition\",    \"conditions\" },\n\t{ true, \"partOfAttDef\", \"part of attribute definition\" },\n};\n\ntypedef enum {\n\tDTD_ELEMENT_ATT_OWNER,\n} dtdElementRole;\n\nstatic roleDefinition DtdElementRoles [] = {\n\t{ true, \"attOwner\", \"attributes owner\" },\n};\n\ntypedef enum {\n\tK_ENTITY,\n\tK_PARAMETER_ENTITY,\n\t// K_EXTERNAL_ENTITY,\n\t// K_UNPARSED_ENTITY,\n\tK_ELEMENT,\n\tK_ATTRIBUTE,\n\tK_NOTATION,\n} dtdKind;\n\nstatic kindDefinition DtdKinds [] = {\n\t{ true, 'E', \"entity\",    \"entities\" },\n\t{ true, 'p', \"parameterEntity\", \"parameter entities\",\n\t  .referenceOnly = false, ATTACH_ROLES(DtdEntityRoles),\n\t  ATTACH_SEPARATORS(DtdParameterEntrySeparators),\n\t},\n\t// { true, 'X', \"externalEntity\", \"external entities\" },\n\t// { true, 'U', \"unparsedEntity\", \"unparsed entities\" },\n\t{ true, 'e', \"element\",   \"elements\",\n\t  .referenceOnly = false, ATTACH_ROLES(DtdElementRoles) },\n\t{ true, 'a', \"attribute\", \"attributes\",\n\t  ATTACH_SEPARATORS(DtdAttSeparators), },\n\t{ true, 'n', \"notation\", \"notations\" },\n\n};\n\nenum {\n\tKEYWORD_ENTITY,\n\tKEYWORD_ELEMENT,\n\tKEYWORD_ATTLIST,\n\tKEYWORD_INCLUDE,\n\tKEYWORD_IGNORE,\n\t// KEYWORD_PUBLIC,\n\t// KEYWORD_SYSTEM,\n\tKEYWORD_NOTATION,\n\tKEYWORD_FIXED,\n\tKEYWORD_ATTR_TYPES,\n\tKEYWORD_ATTR_DEFAULT_DECLS,\n};\n\ntypedef int keywordId;\n\nstatic const keywordTable DtdKeywordTable[] = {\n\t{ \"ENTITY\",    KEYWORD_ENTITY   },\n\t{ \"ELEMENT\",   KEYWORD_ELEMENT  },\n\t{ \"ATTLIST\",   KEYWORD_ATTLIST },\n\t{ \"INCLUDE\",   KEYWORD_INCLUDE  },\n\t{ \"IGNORE\",    KEYWORD_IGNORE   },\n\t// { \"PUBLIC\",    KEYWORD_PUBLIC   },\n\t// { \"SYSTEM\",    KEYWORD_SYSTEM   },\n\t{ \"NOTATION\",  KEYWORD_NOTATION },\n\t{ \"FIXED\",     KEYWORD_FIXED    },\n\t{ \"CDATA\",     KEYWORD_ATTR_TYPES },\n\t{ \"ID\",        KEYWORD_ATTR_TYPES },\n\t{ \"IDREF\",     KEYWORD_ATTR_TYPES },\n\t{ \"IDREFS\",    KEYWORD_ATTR_TYPES },\n\t{ \"ENTITIES\",  KEYWORD_ATTR_TYPES },\n\t{ \"NMTOKEN\",   KEYWORD_ATTR_TYPES },\n\t{ \"NMTOKENS\",  KEYWORD_ATTR_TYPES },\n\t{ \"REQUIRED\",  KEYWORD_ATTR_DEFAULT_DECLS },\n\t{ \"IMPLIED\",   KEYWORD_ATTR_DEFAULT_DECLS },\n};\n\nenum eTokenType {\n\t/* 0..255 are the byte's value */\n\tTOKEN_CLOSE = '>',\n\tTOKEN_EOF = 256,\n\tTOKEN_UNDEFINED,\n\tTOKEN_KEYWORD,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_OPEN,\t\t\t\t\t/* <! */\n\tTOKEN_STRING,\n};\n\nstatic void readToken (tokenInfo *const token, void *data CTAGS_ATTR_UNUSED);\nstatic void clearToken (tokenInfo *token);\nstatic void copyToken (tokenInfo *dest, tokenInfo *src, void *data CTAGS_ATTR_UNUSED);\n\ntypedef struct sDtdToken {\n\ttokenInfo base;\n\tint scopeIndex;\n} dtdToken;\n\n#define DTD(TOKEN) ((dtdToken *)TOKEN)\n\nstatic struct tokenInfoClass dtdTokenInfoClass = {\n\t.nPreAlloc = 16,\n\t.typeForUndefined = TOKEN_UNDEFINED,\n\t.keywordNone      = KEYWORD_NONE,\n\t.typeForKeyword   = TOKEN_KEYWORD,\n\t.typeForEOF       = TOKEN_EOF,\n\t.extraSpace       = sizeof (dtdToken) - sizeof (tokenInfo),\n\t.read             = readToken,\n\t.clear            = clearToken,\n\t.copy             = copyToken,\n};\n\nstatic langType Lang_dtd;\n\n#define isIdentifierChar(c) (isalnum (c) || c == '-' || c == '_' || c == '.' \\\n\t\t\t\t\t\t\t || c == ':')\n\nstatic tokenInfo *newDtdToken (void)\n{\n\treturn newToken (&dtdTokenInfoClass);\n}\n\nstatic void clearToken (tokenInfo *token)\n{\n\tDTD (token)->scopeIndex = CORK_NIL;\n}\n\nstatic void copyToken (tokenInfo *dest, tokenInfo *src, void *data CTAGS_ATTR_UNUSED)\n{\n\tDTD (dest)->scopeIndex = DTD (src)->scopeIndex;\n}\n\nstatic void readToken (tokenInfo *const token, void *data CTAGS_ATTR_UNUSED)\n{\n\tint c, c0;\n\n\ttoken->type\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\n retry:\n\tdo {\n\t\tc = getcFromInputFile ();\n\t} while (c == ' ' || c == '\\t' || c == '\\f' || c == '\\n');\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tswitch (c)\n\t{\n\tcase EOF:\n\t\ttoken->type = TOKEN_EOF;\n\t\tbreak;\n\tcase ';':\n\tcase '&':\n\tcase '%':\n\tcase '>':\n\tcase '#':\n\tcase '?':\n\tcase '[':\n\tcase ']':\n\tcase '|':\n\tcase ',':\n\tcase '(':\n\tcase ')':\n\tcase '+':\n\t\ttoken->type = c;\n\t\tbreak;\n\tcase '<':\n\t\tc0 = getcFromInputFile();\n\t\tif (c0 == '!')\n\t\t{\n\t\t\ttoken->type = TOKEN_OPEN;\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tungetcToInputFile (c0);\n\t\t\ttoken->type = c;\n\t\t\tbreak;\n\t\t}\n\tcase '-':\n\t\tc0 = getcFromInputFile();\n\t\tif (c0 == '-')\n\t\t{\n\t\t\tint c1, c2;\n\n\t\t\twhile ( (c1 = getcFromInputFile()) != EOF )\n\t\t\t{\n\t\t\t\tif (c1 == '-')\n\t\t\t\t{\n\t\t\t\t\tc2 = getcFromInputFile();\n\t\t\t\t\tif (c2 == '-' || c2 == EOF)\n\t\t\t\t\t\tgoto retry;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tungetcToInputFile (c0);\n\t\t\ttoken->type = c;\n\t\t}\n\t\tbreak;\n\tcase '\"':\n\tcase '\\'':\n\t\ttoken->type = TOKEN_STRING;\n\t\twhile ((c0 = getcFromInputFile ()))\n\t\t{\n\t\t\tif (c0 == EOF || c0 == c)\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t\ttokenPutc(token, c0);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tif (isIdentifierChar(c))\n\t\t{\n\t\t\ttokenPutc(token, c);\n\t\t\twhile ((c = getcFromInputFile ()))\n\t\t\t{\n\t\t\t\tif (isIdentifierChar(c))\n\t\t\t\t\ttokenPutc(token, c);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tungetcToInputFile (c);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttoken->keyword = lookupKeyword (vStringValue (token->string),\n\t\t\t\t\t\t\t\t\t\t\tLang_dtd);\n\t\t\tif (token->keyword == KEYWORD_NONE)\n\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\telse\n\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\n\t\t}\n\t\telse\n\t\t\ttoken->type = c;\n\t\tbreak;\n\t}\n}\n\nstatic int makeDtdTagMaybe (tagEntryInfo *const e, tokenInfo *const token,\n\t\t\t\t\t\t\tint kind, int role)\n{\n\tif (role == ROLE_DEFINITION_INDEX)\n\t{\n\t\tif (! DtdKinds[kind].enabled)\n\t\t\treturn CORK_NIL;\n\t}\n\telse if (! (isXtagEnabled (XTAG_REFERENCE_TAGS)\n\t\t\t\t&& DtdKinds[kind].roles[role].enabled))\n\t\treturn CORK_NIL;\n\n\tinitRefTagEntry (e, tokenString (token),\n\t\t\t\t\t kind,\n\t\t\t\t\t role);\n\tupdateTagLine (e, token->lineNumber, token->filePosition);\n\te->extensionFields.scopeIndex = DTD (token)->scopeIndex;\n\n\treturn makeTagEntry (e);\n}\n\nstatic void backpatchEndField (int index, unsigned long lineNumber)\n{\n\tsetTagEndLineToCorkEntry (index, lineNumber);\n}\n\nstatic void parseEntity (tokenInfo *const token)\n{\n\ttagEntryInfo e;\n\tint index = CORK_NIL;\n\n\ttokenRead (token);\n\tif (token->type == '%')\n\t{\n\t\ttokenRead (token);\n\t\tif (tokenIsType(token, IDENTIFIER))\n\t\t\tindex = makeDtdTagMaybe (&e, token,\n\t\t\t\t\t\t\t\t\t K_PARAMETER_ENTITY, ROLE_DEFINITION_INDEX);\n\t}\n\telse if (tokenIsType(token, IDENTIFIER))\n\t\tindex = makeDtdTagMaybe (&e, token,\n\t\t\t\t\t\t\t\t K_ENTITY, ROLE_DEFINITION_INDEX);\n\n\tif (tokenSkipToType (token, TOKEN_CLOSE) && (index != CORK_NIL))\n\t\tbackpatchEndField (index, token->lineNumber);\n}\n\nstatic tokenInfo *parserParameterEntityRef (tokenInfo *const token)\n{\n\ttokenRead (token);\n\tif (tokenIsType(token, IDENTIFIER))\n\t{\n\t\ttokenInfo * identifier = newTokenByCopying (token);\n\n\t\ttokenRead (token);\n\n\t\tif (token->type == ';')\n\t\t\treturn identifier;\n\t\telse\n\t\t{\n\t\t\ttokenDelete (identifier);\n\t\t\treturn NULL;\n\t\t}\n\t}\n\treturn NULL;\n}\n\nstatic void parseElement (tokenInfo *const token, bool skipToClose)\n{\n\ttagEntryInfo e;\n\tint original_index;\n\n\tif (skipToClose)\n\t\toriginal_index = (int)countEntryInCorkQueue ();\n\n\ttokenRead (token);\n\tif (token->type == '%')\n\t{\n\t\ttokenInfo * identifier = parserParameterEntityRef (token);\n\t\tif (identifier)\n\t\t{\n\t\t\tmakeDtdTagMaybe (&e, identifier,\n\t\t\t\t\t\t\t K_PARAMETER_ENTITY,\n\t\t\t\t\t\t\t DTD_PARAMETER_ENTITY_ELEMENT_NAME);\n\t\t\ttokenDelete (identifier);\n\t\t}\n\t}\n\telse if (tokenIsType(token, IDENTIFIER))\n\t\tmakeDtdTagMaybe (&e, token, K_ELEMENT, ROLE_DEFINITION_INDEX);\n\telse if (token->type == '(')\n\t{\n\t\tdo {\n\t\t\tparseElement (token, false);\n\t\t} while ((!tokenIsEOF (token))\n\t\t\t\t && (token->type != ')'));\n\t}\n\n\tif (skipToClose)\n\t{\n\t\tint current_index = (int)countEntryInCorkQueue ();\n\t\tif (tokenSkipToType (token, TOKEN_CLOSE)\n\t\t\t&& (current_index > original_index))\n\t\t{\n\t\t\tfor (int index = original_index; index < current_index; index++)\n\t\t\t\tbackpatchEndField (index, token->lineNumber);\n\t\t}\n\t}\n}\n\nstatic void parseAttDefs (tokenInfo *const token)\n{\n\t/*  [53]   \tAttDef\t   ::=   \tS Name S AttType S DefaultDecl */\n\n\tdo {\n\t\ttokenRead (token);\n\n\t\t/* Name */\n\t\tif (tokenIsType(token, IDENTIFIER))\n\t\t{\n\t\t\ttagEntryInfo e;\n\t\t\tmakeDtdTagMaybe (&e, token,\n\t\t\t\t\t\t\t K_ATTRIBUTE, ROLE_DEFINITION_INDEX);\n\t\t}\n\t\telse if (tokenIsKeyword(token, ATTR_TYPES)\n\t\t\t\t || tokenIsKeyword(token, ENTITY))\n\t\t\t/* AttType -> just consuming */\n\t\t\t;\n\t\telse if (tokenIsKeyword(token, NOTATION))\n\t\t{\n\t\t\t/* AttType -> just consuming */\n\t\t\ttokenRead (token);\n\t\t\tif (token->type == '(')\n\t\t\t\ttokenSkipToType (token, ')');\n\t\t}\n\t\telse if (token->type == '(')\n\t\t{\n\t\t\t/* AttType, TODO: Enumerated members can be tagged. */\n\t\t\ttokenSkipToType (token, ')');\n\t\t}\n\t\telse if (token->type == '#')\n\t\t{\n\t\t\t/* DefaultDecl */\n\t\t\ttokenRead (token);\n\t\t\tif (tokenIsKeyword(token, FIXED))\n\t\t\t\ttokenRead (token);\n\t\t\telse if (tokenIsKeyword(token, ATTR_DEFAULT_DECLS))\n\t\t\t{\n\t\t\t\t/* Just consuming */\n\t\t\t}\n\t\t}\n\t\telse if (tokenIsType (token, STRING))\n\t\t\t;\t\t\t\t\t/* DefaultDecl -> Just consuming */\n\t\telse if (token->type == '%')\n\t\t{\n\t\t\ttokenInfo * identifier = parserParameterEntityRef (token);\n\t\t\tif (identifier)\n\t\t\t{\n\t\t\t\ttagEntryInfo e;\n\t\t\t\tmakeDtdTagMaybe (&e, identifier,\n\t\t\t\t\t\t\t\t K_PARAMETER_ENTITY,\n\t\t\t\t\t\t\t\t DTD_PARAMETER_ENTITY_PART_OF_ATT_DEF);\n\t\t\t\ttokenDelete (identifier);\n\t\t\t}\n\t\t}\n\t\telse if (tokenIsType(token, CLOSE))\n\t\t{\n\t\t\tDTD (token)->scopeIndex = CORK_NIL;\n\t\t\ttokenUnread (token);\n\t\t\tbreak;\n\t\t}\n\t} while (!tokenIsEOF (token));\n}\n\nstatic void parseAttlist (tokenInfo *const token)\n{\n\ttagEntryInfo e;\n\tint index = CORK_NIL;\n\n\ttokenRead (token);\n\tif (token->type == '%')\n\t{\n\t\ttokenRead (token);\n\t\tif (tokenIsType(token, IDENTIFIER))\n\t\t{\n\t\t\ttokenInfo * identifier = parserParameterEntityRef (token);\n\t\t\tif (identifier)\n\t\t\t{\n\t\t\t\tindex = makeDtdTagMaybe (&e, identifier,\n\t\t\t\t\t\t\t\t\t\t K_ENTITY,\n\t\t\t\t\t\t\t\t\t\t DTD_PARAMETER_ENTITY_ELEMENT_NAME);\n\t\t\t\ttokenDelete (identifier);\n\n\t\t\t\tDTD (token)->scopeIndex = index;\n\t\t\t\tparseAttDefs (token);\n\t\t\t\tDTD (token)->scopeIndex = CORK_NIL;\n\t\t\t}\n\t\t}\n\t}\n\telse if (tokenIsType(token, IDENTIFIER))\n\t{\n\t\ttokenInfo * element = newTokenByCopying (token);\n\n\t\tindex = makeDtdTagMaybe (&e, element,\n\t\t\t\t\t\t\t\t K_ELEMENT, DTD_ELEMENT_ATT_OWNER);\n\t\ttokenDelete (element);\n\n\t\tDTD (token)->scopeIndex = index;\n\t\tparseAttDefs (token);\n\t\tDTD (token)->scopeIndex = CORK_NIL;\n\t}\n\n\ttokenSkipToType (token, TOKEN_CLOSE);\n\tbackpatchEndField (index, token->lineNumber);\n}\n\nstatic void parseNotation (tokenInfo *const token)\n{\n\tint index = CORK_NIL;\n\ttagEntryInfo e;\n\n\ttokenRead (token);\n\tif (tokenIsType(token, IDENTIFIER))\n\t\tindex = makeDtdTagMaybe (&e, token,\n\t\t\t\t\t\t\t\t K_NOTATION, ROLE_DEFINITION_INDEX);\n\n\ttokenSkipToType (token, TOKEN_CLOSE);\n\tbackpatchEndField (index, token->lineNumber);\n}\n\n\nstatic void parseSection (tokenInfo *const token);\n\nstatic void parseDtdTag1 (tokenInfo *const token)\n{\n\tif (tokenIsType(token, OPEN))\n\t{\n\t\ttokenRead (token);\n\t\tif (tokenIsKeyword (token, ELEMENT))\n\t\t\tparseElement(token, true);\n\t\telse if (tokenIsKeyword (token, ATTLIST))\n\t\t\tparseAttlist(token);\n\t\telse if (tokenIsKeyword (token, ENTITY))\n\t\t\tparseEntity(token);\n\t\telse if (tokenIsKeyword (token, NOTATION))\n\t\t\tparseNotation(token);\n\t\telse if (token->type == '[')\n\t\t{\n\t\t\ttokenRead (token);\n\t\t\tparseSection (token);\n\t\t\ttokenSkipToType (token, ']');\n\t\t}\n\t\telse if (!tokenIsType(token, CLOSE))\n\t\t\ttokenSkipToType (token, TOKEN_CLOSE);\n\t}\n}\n\nstatic void parseSection (tokenInfo *const token)\n{\n\tif (tokenIsKeyword(token, IGNORE))\n\t\ttokenSkipToType (token, ']');\n\telse\n\t{\n\t\tif (tokenIsKeyword (token, INCLUDE))\n\t\t{\n\t\t\ttokenRead (token);\n\t\t\tif (token->type == '[')\n\t\t\t{\n\t\t\t\tdo {\n\t\t\t\t\ttokenRead (token);\n\t\t\t\t} while ((!tokenIsEOF (token))\n\t\t\t\t\t\t && (token->type != ']'));\n\t\t\t}\n\t\t}\n\t\telse if (token->type == '%')\n\t\t{\n\t\t\ttokenInfo *const condition = parserParameterEntityRef (token);\n\t\t\tif (condition)\n\t\t\t{\n\t\t\t\ttagEntryInfo e;\n\t\t\t\tint index = makeDtdTagMaybe (&e, condition,\n\t\t\t\t\t\t\t\t\t\t\t K_PARAMETER_ENTITY,\n\t\t\t\t\t\t\t\t\t\t\t DTD_PARAMETER_ENTITY_CONDITION);\n\t\t\t\ttokenDelete (condition);\n\t\t\t\ttokenRead (token);\n\t\t\t\tif (token->type == '[')\n\t\t\t\t{\n\t\t\t\t\tdo {\n\t\t\t\t\t\ttokenRead (token);\n\t\t\t\t\t\tparseDtdTag1 (token);\n\t\t\t\t\t} while ((!tokenIsEOF (token))\n\t\t\t\t\t\t\t && (token->type != ']'));\n\t\t\t\t\tif (token->type== ']')\n\t\t\t\t\t\tbackpatchEndField (index, token->lineNumber);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void findDtdTags (void)\n{\n\ttokenInfo *const token = newDtdToken ();\n\n\tdo {\n\t\ttokenRead (token);\n\t\tparseDtdTag1 (token);\n\t} while (!tokenIsEOF (token));\n\n\ttokenDelete (token);\n\n\tflashTokenBacklog (&dtdTokenInfoClass);\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_dtd = language;\n}\n\nextern parserDefinition* DtdParser (void)\n{\n\tparserDefinition* def = parserNew (\"DTD\");\n\n\t/* File name patters are picked from Linux kernel. */\n\tstatic const char *const extensions [] = {\n\t\t\"dtd\",\n\t\t\"mod\",\n\t\tNULL\n\t};\n\n\tdef->initialize = initialize;\n\tdef->parser     = findDtdTags;\n\n\tdef->kindTable      = DtdKinds;\n\tdef->kindCount  = ARRAY_SIZE (DtdKinds);\n\tdef->extensions = extensions;\n\n\tdef->keywordTable = DtdKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (DtdKeywordTable);\n\n\tdef->useCork    = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/dts.c",
    "content": "/*\n*   Copyright (c) 2015, André Rivotti Casimiro <andre.r.casimiro@gmail.com>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for DTS language files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\n#include \"x-cpreprocessor.h\"\n#include \"field.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n\nstatic tagRegexTable dtsTagRegexTable [] = {\n\t/* phandle = <0x00> */\n\t{\"^[ \\t]*phandle[ \\t]+=[ \\t]+<(0x[a-fA-F0-9]+)>\", \"\\\\1\",\n\t \"p,phandler,phandlers\", \"{scope=ref}\"},\n\n\t/* label: */\n\t{\"^[ \\t]*([a-zA-Z][a-zA-Z0-9_]*)[ \\t]*:\", \"\\\\1\",\n\t \"l,label,labels\", \"{scope=push}\"},\n\n\t/* extras for tracking scopes  */\n\t{\"^[ \\t]*([a-zA-Z][a-zA-Z0-9_]*)[ \\t]*\\\\{\", \"\",\n\t \"\", \"{scope=push}{placeholder}\"},\n\t{\"\\\\}[ \\t]*;\", \"\",\n\t \"\", \"{scope=pop}{exclusive}\"},\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nstatic void runCppGetc (void)\n{\n\tcppInit (false, false, false, false,\n\t\t\t KIND_GHOST_INDEX, 0, 0,\n\t\t\t KIND_GHOST_INDEX,\n\t\t\t KIND_GHOST_INDEX, 0, 0,\n\t\t\t FIELD_UNKNOWN);\n\n\tfindRegexTagsMainloop (cppGetc);\n\n\tcppTerminate ();\n}\n\nextern parserDefinition* DTSParser (void)\n{\n\tstatic const char *const extensions [] = { \"dts\", \"dtsi\", NULL };\n\tparserDefinition* const def = parserNew (\"DTS\");\n\tdef->extensions = extensions;\n\tdef->parser     = runCppGetc;\n\tdef->tagRegexTable = dtsTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE (dtsTagRegexTable);\n\tdef->method     = METHOD_REGEX;\n\tdef->requestAutomaticFQTag = true;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/eiffel.c",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Eiffel language\n*   files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <limits.h>\n#include <ctype.h>  /* to define tolower () */\n\n#include \"debug.h\"\n#include \"keyword.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"xtag.h\"\n\n/*\n*   MACROS\n*/\n#define isident(c)            (isalnum(c) || (c) == '_')\n#define isFreeOperatorChar(c) ((c) == '@' || (c) == '#' || \\\n                               (c) == '|' || (c) == '&')\n#define isType(token,t)       (bool) ((token)->type == (t))\n#define isKeyword(token,k)    (bool) ((token)->keyword == (k))\n\n/*\n*   DATA DECLARATIONS\n*/\n\n/*  Used to specify type of keyword.\n */\nenum eKeywordId {\n\tKEYWORD_across,\n\tKEYWORD_alias,\n\tKEYWORD_all,\n\tKEYWORD_and,\n\tKEYWORD_as,\n\tKEYWORD_assign,\n\tKEYWORD_attached,\n\tKEYWORD_attribute,\n\tKEYWORD_check,\n\tKEYWORD_class,\n\tKEYWORD_convert,\n\tKEYWORD_create,\n\tKEYWORD_creation,\n\tKEYWORD_Current,\n\tKEYWORD_debug,\n\tKEYWORD_deferred,\n\tKEYWORD_detachable,\n\tKEYWORD_do,\n\tKEYWORD_else,\n\tKEYWORD_elseif,\n\tKEYWORD_end,\n\tKEYWORD_ensure,\n\tKEYWORD_expanded,\n\tKEYWORD_export,\n\tKEYWORD_external,\n\tKEYWORD_false,\n\tKEYWORD_feature,\n\tKEYWORD_from,\n\tKEYWORD_frozen,\n\tKEYWORD_if,\n\tKEYWORD_implies,\n\tKEYWORD_infix,\n\tKEYWORD_inherit,\n\tKEYWORD_inspect,\n\tKEYWORD_invariant,\n\tKEYWORD_is,\n\tKEYWORD_like,\n\tKEYWORD_local,\n\tKEYWORD_loop,\n\tKEYWORD_not,\n\tKEYWORD_note,\n\tKEYWORD_obsolete,\n\tKEYWORD_old,\n\tKEYWORD_once,\n\tKEYWORD_or,\n\tKEYWORD_prefix,\n\tKEYWORD_redefine,\n\tKEYWORD_rename,\n\tKEYWORD_require,\n\tKEYWORD_rescue,\n\tKEYWORD_Result,\n\tKEYWORD_retry,\n\tKEYWORD_select,\n\tKEYWORD_separate,\n\tKEYWORD_strip,\n\tKEYWORD_then,\n\tKEYWORD_true,\n\tKEYWORD_undefine,\n\tKEYWORD_unique,\n\tKEYWORD_until,\n\tKEYWORD_variant,\n\tKEYWORD_when,\n\tKEYWORD_xor\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum eTokenType {\n\tTOKEN_EOF,\n\tTOKEN_UNDEFINED,\n\tTOKEN_BANG,\n\tTOKEN_CHARACTER,\n\tTOKEN_CLOSE_BRACE,\n\tTOKEN_CLOSE_BRACKET,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_COLON,\n\tTOKEN_COMMA,\n\tTOKEN_CONSTRAINT,\n\tTOKEN_DOT,\n\tTOKEN_DOLLAR,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_KEYWORD,\n\tTOKEN_NUMERIC,\n\tTOKEN_OPEN_BRACE,\n\tTOKEN_OPEN_BRACKET,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_OPERATOR,\n\tTOKEN_QUESTION,\n\tTOKEN_SEMICOLON,\n\tTOKEN_STRING,\n\tTOKEN_TILDE\n} tokenType;\n\ntypedef struct sTokenInfo {\n\ttokenType type;\n\tkeywordId keyword;\n\tbool   isExported;\n\tvString*  string;\n\tvString*  className;\n\tvString*  featureName;\n} tokenInfo;\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic langType Lang_eiffel;\n\ntypedef enum {\n\tEKIND_CLASS, EKIND_FEATURE, EKIND_LOCAL, EKIND_QUALIFIED_TAGS\n} eiffelKind;\n\nstatic kindDefinition EiffelKinds [] = {\n\t{ true,  'c', \"class\",   \"classes\"},\n\t{ true,  'f', \"feature\", \"features\"},\n\t{ false, 'l', \"local\",   \"local entities\"}\n};\n\nstatic const keywordTable EiffelKeywordTable [] = {\n\t/* keyword          keyword ID */\n\t{ \"across\",         KEYWORD_across     },\n\t{ \"alias\",          KEYWORD_alias      },\n\t{ \"all\",            KEYWORD_all        },\n\t{ \"and\",            KEYWORD_and        },\n\t{ \"as\",             KEYWORD_as         },\n\t{ \"assign\",         KEYWORD_assign     },\n\t{ \"attached\",       KEYWORD_attached   },\n\t{ \"attribute\",      KEYWORD_attribute  },\n\t{ \"check\",          KEYWORD_check      },\n\t{ \"class\",          KEYWORD_class      },\n\t{ \"convert\",        KEYWORD_convert    },\n\t{ \"create\",         KEYWORD_create     },\n\t{ \"creation\",       KEYWORD_creation   },\n\t{ \"current\",        KEYWORD_Current    },\n\t{ \"debug\",          KEYWORD_debug      },\n\t{ \"deferred\",       KEYWORD_deferred   },\n\t{ \"detachable\",     KEYWORD_detachable },\n\t{ \"do\",             KEYWORD_do         },\n\t{ \"else\",           KEYWORD_else       },\n\t{ \"elseif\",         KEYWORD_elseif     },\n\t{ \"end\",            KEYWORD_end        },\n\t{ \"ensure\",         KEYWORD_ensure     },\n\t{ \"expanded\",       KEYWORD_expanded   },\n\t{ \"export\",         KEYWORD_export     },\n\t{ \"external\",       KEYWORD_external   },\n\t{ \"false\",          KEYWORD_false      },\n\t{ \"feature\",        KEYWORD_feature    },\n\t{ \"from\",           KEYWORD_from       },\n\t{ \"frozen\",         KEYWORD_frozen     },\n\t{ \"if\",             KEYWORD_if         },\n\t{ \"implies\",        KEYWORD_implies    },\n\t{ \"indexing\",       KEYWORD_note       },\n\t{ \"infix\",          KEYWORD_infix      },\n\t{ \"inherit\",        KEYWORD_inherit    },\n\t{ \"insert\",         KEYWORD_inherit    },\n\t{ \"inspect\",        KEYWORD_inspect    },\n\t{ \"invariant\",      KEYWORD_invariant  },\n\t{ \"is\",             KEYWORD_is         },\n\t{ \"like\",           KEYWORD_like       },\n\t{ \"local\",          KEYWORD_local      },\n\t{ \"loop\",           KEYWORD_loop       },\n\t{ \"not\",            KEYWORD_not        },\n\t{ \"note\",           KEYWORD_note       },\n\t{ \"obsolete\",       KEYWORD_obsolete   },\n\t{ \"old\",            KEYWORD_old        },\n\t{ \"once\",           KEYWORD_once       },\n\t{ \"or\",             KEYWORD_or         },\n\t{ \"prefix\",         KEYWORD_prefix     },\n\t{ \"redefine\",       KEYWORD_redefine   },\n\t{ \"rename\",         KEYWORD_rename     },\n\t{ \"require\",        KEYWORD_require    },\n\t{ \"rescue\",         KEYWORD_rescue     },\n\t{ \"result\",         KEYWORD_Result     },\n\t{ \"retry\",          KEYWORD_retry      },\n\t{ \"select\",         KEYWORD_select     },\n\t{ \"separate\",       KEYWORD_separate   },\n\t{ \"strip\",          KEYWORD_strip      },\n\t{ \"then\",           KEYWORD_then       },\n\t{ \"true\",           KEYWORD_true       },\n\t{ \"undefine\",       KEYWORD_undefine   },\n\t{ \"unique\",         KEYWORD_unique     },\n\t{ \"until\",          KEYWORD_until      },\n\t{ \"variant\",        KEYWORD_variant    },\n\t{ \"when\",           KEYWORD_when       },\n\t{ \"xor\",            KEYWORD_xor        }\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n/*\n*   Tag generation functions\n*/\n\nstatic void makeEiffelClassTag (tokenInfo *const token)\n{\n\tif (EiffelKinds [EKIND_CLASS].enabled)\n\t{\n\t\tconst char *const name = vStringValue (token->string);\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry (&e, name, EKIND_CLASS);\n\n\t\tmakeTagEntry (&e);\n\t}\n\tvStringCopy (token->className, token->string);\n}\n\nstatic void makeEiffelFeatureTag (tokenInfo *const token)\n{\n\tif (EiffelKinds [EKIND_FEATURE].enabled  &&\n\t\t(token->isExported  ||  isXtagEnabled(XTAG_FILE_SCOPE)))\n\t{\n\t\tconst char *const name = vStringValue (token->string);\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry (&e, name, EKIND_FEATURE);\n\n\t\te.isFileScope = (bool) (! token->isExported);\n\t\tif (e.isFileScope)\n\t\t\tmarkTagExtraBit (&e, XTAG_FILE_SCOPE);\n\t\te.extensionFields.scopeKindIndex = EKIND_CLASS;\n\t\te.extensionFields.scopeName = vStringValue (token->className);\n\n\t\tmakeTagEntry (&e);\n\n\t\tif (isXtagEnabled(XTAG_QUALIFIED_TAGS))\n\t\t{\n\t\t\tvString* qualified = vStringNewInit (vStringValue (token->className));\n\t\t\tvStringPut (qualified, '.');\n\t\t\tvStringCat (qualified, token->string);\n\t\t\te.name = vStringValue (qualified);\n\t\t\tmarkTagExtraBit (&e, XTAG_QUALIFIED_TAGS);\n\t\t\tmakeTagEntry (&e);\n\t\t\tvStringDelete (qualified);\n\t\t}\n\t}\n\tvStringCopy (token->featureName, token->string);\n}\n\nstatic void makeEiffelLocalTag (tokenInfo *const token)\n{\n\tif (EiffelKinds [EKIND_LOCAL].enabled && isXtagEnabled(XTAG_FILE_SCOPE))\n\t{\n\t\tconst char *const name = vStringValue (token->string);\n\t\tvString* scope = vStringNew ();\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry (&e, name, EKIND_LOCAL);\n\n\t\te.isFileScope = true;\n\t\tmarkTagExtraBit (&e, XTAG_FILE_SCOPE);\n\n\t\tvStringCopy (scope, token->className);\n\t\tvStringPut (scope, '.');\n\t\tvStringCat (scope, token->featureName);\n\n\t\te.extensionFields.scopeKindIndex = EKIND_FEATURE;\n\t\te.extensionFields.scopeName = vStringValue (scope);\n\n\t\tmakeTagEntry (&e);\n\t\tvStringDelete (scope);\n\t}\n}\n\n/*\n*   Parsing functions\n*/\n\nstatic int skipToCharacter (const int c)\n{\n\tint d;\n\n\tdo\n\t{\n\t\td = getcFromInputFile ();\n\t} while (d != EOF  &&  d != c);\n\n\treturn d;\n}\n\n/*  If a numeric is passed in 'c', this is used as the first digit of the\n *  numeric being parsed.\n */\nstatic vString *parseInteger (int c)\n{\n\tvString *string = vStringNew ();\n\n\tif (c == '\\0')\n\t\tc = getcFromInputFile ();\n\tif (c == '-')\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t}\n\telse if (! isdigit (c))\n\t\tc = getcFromInputFile ();\n\twhile (c != EOF  &&  (isdigit (c)  ||  c == '_'))\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t}\n\tungetcToInputFile (c);\n\n\treturn string;\n}\n\nstatic vString *parseNumeric (int c)\n{\n\tvString *string = vStringNew ();\n\tvString *integer = parseInteger (c);\n\tvStringCopy (string, integer);\n\tvStringDelete (integer);\n\n\tc = getcFromInputFile ();\n\tif (c == '.')\n\t{\n\t\tinteger = parseInteger ('\\0');\n\t\tvStringPut (string, c);\n\t\tvStringCat (string, integer);\n\t\tvStringDelete (integer);\n\t\tc = getcFromInputFile ();\n\t}\n\tif (tolower (c) == 'e')\n\t{\n\t\tinteger = parseInteger ('\\0');\n\t\tvStringPut (string, c);\n\t\tvStringCat (string, integer);\n\t\tvStringDelete (integer);\n\t}\n\telse if (!isspace (c))\n\t\tungetcToInputFile (c);\n\n\treturn string;\n}\n\nstatic int parseEscapedCharacter (void)\n{\n\tint d = '\\0';\n\tint c = getcFromInputFile ();\n\n\tswitch (c)\n\t{\n\t\tcase 'A':  d = '@';   break;\n\t\tcase 'B':  d = '\\b';  break;\n\t\tcase 'C':  d = '^';   break;\n\t\tcase 'D':  d = '$';   break;\n\t\tcase 'F':  d = '\\f';  break;\n\t\tcase 'H':  d = '\\\\';  break;\n\t\tcase 'L':  d = '~';   break;\n\t\tcase 'N':  d = '\\n';  break;\n\t\tcase 'Q':  d = '`';   break;\n\t\tcase 'R':  d = '\\r';  break;\n\t\tcase 'S':  d = '#';   break;\n\t\tcase 'T':  d = '\\t';  break;\n\t\tcase 'U':  d = '\\0';  break;\n\t\tcase 'V':  d = '|';   break;\n\t\tcase '%':  d = '%';   break;\n\t\tcase '\\'': d = '\\'';  break;\n\t\tcase '\"':  d = '\"';   break;\n\t\tcase '(':  d = '[';   break;\n\t\tcase ')':  d = ']';   break;\n\t\tcase '<':  d = '{';   break;\n\t\tcase '>':  d = '}';   break;\n\n\t\tcase '\\n': skipToCharacter ('%'); break;\n\n\t\tcase '/':\n\t\t{\n\t\t\tvString *string = parseInteger ('\\0');\n\t\t\tconst char *value = vStringValue (string);\n\t\t\tconst unsigned long ascii = atol (value);\n\t\t\tvStringDelete (string);\n\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == '/'  &&  ascii < 256)\n\t\t\t\td = ascii;\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault: break;\n\t}\n\treturn d;\n}\n\nstatic int parseCharacter (void)\n{\n\tint c = getcFromInputFile ();\n\tint result = c;\n\n\tif (c == '%')\n\t\tresult = parseEscapedCharacter ();\n\n\tc = getcFromInputFile ();\n\tif (c != '\\'')\n\t\tskipToCharacter ('\\n');\n\n\treturn result;\n}\n\nstatic void parseString (vString *const string)\n{\n\tbool verbatim = false;\n\tbool align = false;\n\tbool end = false;\n\tvString *verbatimCloser = vStringNew ();\n\tvString *lastLine = vStringNew ();\n\tint prev = '\\0';\n\tint c;\n\n\twhile (! end)\n\t{\n\t\tc = getcFromInputFile ();\n\t\tif (c == EOF)\n\t\t\tend = true;\n\t\telse if (c == '\"')\n\t\t{\n\t\t\tif (! verbatim)\n\t\t\t\tend = true;\n\t\t\telse\n\t\t\t\tend = (bool) (strcmp (vStringValue (lastLine),\n\t\t\t\t                         vStringValue (verbatimCloser)) == 0);\n\t\t}\n\t\telse if (c == '\\n')\n\t\t{\n\t\t\tif (verbatim)\n\t\t\t\tvStringClear (lastLine);\n\t\t\tif (prev == '[' /* ||  prev == '{' */)\n\t\t\t{\n\t\t\t\tverbatim = true;\n\t\t\t\tvStringClear (verbatimCloser);\n\t\t\t\tvStringClear (lastLine);\n\t\t\t\tif (prev == '{')\n\t\t\t\t\tvStringPut (verbatimCloser, '}');\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvStringPut (verbatimCloser, ']');\n\t\t\t\t\talign = true;\n\t\t\t\t}\n\t\t\t\tvStringNCat (verbatimCloser, string, vStringLength (string) - 1);\n\t\t\t\tvStringClear (string);\n\t\t\t}\n\t\t\tif (verbatim && align)\n\t\t\t{\n\t\t\t\tdo\n\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\twhile (isspace (c));\n\t\t\t}\n\t\t}\n\t\telse if (c == '%')\n\t\t\tc = parseEscapedCharacter ();\n\t\tif (! end)\n\t\t{\n\t\t\tvStringPut (string, c);\n\t\t\tif (verbatim)\n\t\t\t\tvStringPut (lastLine, c);\n\t\t\tprev = c;\n\t\t}\n\t}\n\tvStringDelete (lastLine);\n\tvStringDelete (verbatimCloser);\n}\n\n/*  Read a C identifier beginning with \"firstChar\" and places it into \"name\".\n */\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isident (c));\n\n\tif (!isspace (c))\n\t\tungetcToInputFile (c);  /* unget non-identifier character */\n}\n\nstatic void parseFreeOperator (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (c > ' ');\n\n\tif (!isspace (c))\n\t\tungetcToInputFile (c);  /* unget non-identifier character */\n}\n\nstatic void copyToken (tokenInfo* dst, const tokenInfo *src)\n{\n\tdst->type       = src->type;\n\tdst->keyword    = src->keyword;\n\tdst->isExported = src->isExported;\n\n\tvStringCopy (dst->string, src->string);\n\tvStringCopy (dst->className, src->className);\n\tvStringCopy (dst->featureName, src->featureName);\n}\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->isExported\t= true;\n\n\ttoken->string = vStringNew ();\n\ttoken->className = vStringNew ();\n\ttoken->featureName = vStringNew ();\n\n\treturn token;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tvStringDelete (token->string);\n\tvStringDelete (token->className);\n\tvStringDelete (token->featureName);\n\n\teFree (token);\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\tint c;\n\n\ttoken->type    = TOKEN_UNDEFINED;\n\ttoken->keyword = KEYWORD_NONE;\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tdo\n\t\tc = getcFromInputFile ();\n\twhile (c == '\\t'  ||  c == ' '  ||  c == '\\n');\n\n\tswitch (c)\n\t{\n\t\tcase EOF:  token->type = TOKEN_EOF;                break;\n\t\tcase ';':  token->type = TOKEN_SEMICOLON;          break;\n\t\tcase '!':  token->type = TOKEN_BANG;               break;\n\t\tcase '}':  token->type = TOKEN_CLOSE_BRACE;        break;\n\t\tcase ']':  token->type = TOKEN_CLOSE_BRACKET;      break;\n\t\tcase ')':  token->type = TOKEN_CLOSE_PAREN;        break;\n\t\tcase ',':  token->type = TOKEN_COMMA;              break;\n\t\tcase '$':  token->type = TOKEN_DOLLAR;             break;\n\t\tcase '.':  token->type = TOKEN_DOT;                break;\n\t\tcase '{':  token->type = TOKEN_OPEN_BRACE;         break;\n\t\tcase '[':  token->type = TOKEN_OPEN_BRACKET;       break;\n\t\tcase '(':  token->type = TOKEN_OPEN_PAREN;         break;\n\t\tcase '~':  token->type = TOKEN_TILDE;              break;\n\n\n\t\tcase '+':\n\t\tcase '*':\n\t\tcase '^':\n\t\tcase '=':  token->type = TOKEN_OPERATOR;           break;\n\n\t\tcase '-':\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == '>')\n\t\t\t\ttoken->type = TOKEN_CONSTRAINT;\n\t\t\telse if (c == '-')  /* is this the start of a comment? */\n\t\t\t{\n\t\t\t\tskipToCharacter ('\\n');\n\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!isspace (c))\n\t\t\t\t\tungetcToInputFile (c);\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase '?':\n\t\tcase ':':\n\t\t{\n\t\t\tint c2 = getcFromInputFile ();\n\t\t\tif (c2 == '=')\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!isspace (c2))\n\t\t\t\t\tungetcToInputFile (c2);\n\t\t\t\tif (c == ':')\n\t\t\t\t\ttoken->type = TOKEN_COLON;\n\t\t\t\telse\n\t\t\t\t\ttoken->type = TOKEN_QUESTION;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '<':\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c != '='  &&  c != '>'  &&  !isspace (c))\n\t\t\t\tungetcToInputFile (c);\n\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\tbreak;\n\n\t\tcase '>':\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c != '='  &&  c != '>'  &&  !isspace (c))\n\t\t\t\tungetcToInputFile (c);\n\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\tbreak;\n\n\t\tcase '/':\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c != '/'  &&  c != '='  &&  !isspace (c))\n\t\t\t\tungetcToInputFile (c);\n\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\tbreak;\n\n\t\tcase '\\\\':\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c != '\\\\'  &&  !isspace (c))\n\t\t\t\tungetcToInputFile (c);\n\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\tbreak;\n\n\t\tcase '\"':\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tparseString (token->string);\n\t\t\tbreak;\n\n\t\tcase '\\'':\n\t\t\ttoken->type = TOKEN_CHARACTER;\n\t\t\tparseCharacter ();\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tif (isalpha (c))\n\t\t\t{\n\t\t\t\tparseIdentifier (token->string, c);\n\t\t\t\ttoken->keyword = lookupCaseKeyword (vStringValue (token->string), Lang_eiffel);\n\t\t\t\tif (isKeyword (token, KEYWORD_NONE))\n\t\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\telse\n\t\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t\t}\n\t\t\telse if (isdigit (c))\n\t\t\t{\n\t\t\t\tvString* numeric = parseNumeric (c);\n\t\t\t\tvStringCat (token->string, numeric);\n\t\t\t\tvStringDelete (numeric);\n\t\t\t\ttoken->type = TOKEN_NUMERIC;\n\t\t\t}\n\t\t\telse if (isFreeOperatorChar (c))\n\t\t\t{\n\t\t\t\tparseFreeOperator (token->string, c);\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\t}\n\t\t\telse\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\tbreak;\n\t}\n}\n\n/*\n*   Scanning functions\n*/\n\nstatic bool isIdentifierMatch (\n\t\tconst tokenInfo *const token, const char *const name)\n{\n\treturn (bool) (isType (token, TOKEN_IDENTIFIER)  &&\n\t\tstrcasecmp (vStringValue (token->string), name) == 0);\n}\n\nstatic bool findToken (tokenInfo *const token, const tokenType type)\n{\n\twhile (! isType (token, type) && ! isType (token, TOKEN_EOF))\n\t\treadToken (token);\n\treturn isType (token, type);\n}\n\nstatic bool findKeyword (tokenInfo *const token, const keywordId keyword)\n{\n\twhile (! isKeyword (token, keyword) && ! isType (token, TOKEN_EOF))\n\t\treadToken (token);\n\treturn isKeyword (token, keyword);\n}\n\nstatic bool parseType (tokenInfo *const token);\n\nstatic void parseGeneric (tokenInfo *const token, bool declaration CTAGS_ATTR_UNUSED)\n{\n\tunsigned int depth = 0;\n\n\tAssert (isType (token, TOKEN_OPEN_BRACKET));\n\tdo\n\t{\n\t\tif (isType (token, TOKEN_OPEN_BRACKET))\n\t\t{\n\t\t\t++depth;\n\t\t\treadToken (token);\n\t\t}\n\t\telse if (isType (token, TOKEN_CLOSE_BRACKET))\n\t\t{\n\t\t\t--depth;\n\t\t\treadToken (token);\n\t\t}\n\t\telse\n\t\t\tparseType (token);\n\t} while (depth > 0 && ! isType (token, TOKEN_EOF));\n}\n\nstatic bool parseType (tokenInfo *const token)\n{\n\ttokenInfo* const id = newToken ();\n\tcopyToken (id, token);\n\treadToken (token);\n\tif (isType (token, TOKEN_COLON))  /* check for \"{entity: TYPE}\" */\n\t{\n\t\treadToken (id);\n\t\treadToken (token);\n\t}\n\tif (isKeyword (id, KEYWORD_like))\n\t{\n\t\tif (isType (token, TOKEN_IDENTIFIER) ||\n\t\t\t\tisKeyword (token, KEYWORD_Current))\n\t\t\treadToken (token);\n\t}\n\telse\n\t{\n\t\tif (isKeyword (id, KEYWORD_attached) ||\n\t\t    isKeyword (id, KEYWORD_detachable) ||\n\t\t    isKeyword (id, KEYWORD_expanded))\n\t\t{\n\t\t\tcopyToken (id, token);\n\t\t\treadToken (token);\n\t\t}\n\t\tif (isType (id, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tif (isType (token, TOKEN_OPEN_BRACKET))\n\t\t\t\tparseGeneric (token, false);\n\t\t\telse if ((strcmp (\"BIT\", vStringValue (id->string)) == 0))\n\t\t\t\treadToken (token);  /* read token after number of bits */\n\t\t}\n\t}\n\tdeleteToken (id);\n\treturn true;\n}\n\nstatic void parseEntityType (tokenInfo *const token)\n{\n\tAssert (isType (token, TOKEN_COLON));\n\treadToken (token);\n\n\tif (isType (token, TOKEN_BANG) || isType (token, TOKEN_QUESTION))\n\t\treadToken (token);  /* skip over '!' or '?' */\n\tparseType (token);\n}\n\nstatic void parseLocal (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_local));\n\treadToken (token);\n\n\t/*  Check keyword first in case local clause is empty\n\t */\n\twhile (! isKeyword (token, KEYWORD_do)  &&\n\t\t   ! isKeyword (token, KEYWORD_once) &&\n\t\t   ! isKeyword (token, KEYWORD_attribute) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\tmakeEiffelLocalTag (token);\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_COLON))\n\t\t\tparseEntityType (token);\n\t}\n}\n\nstatic void findFeatureEnd (tokenInfo *const token)\n{\n\tbool isFound = isKeyword (token, KEYWORD_is);\n\tif (isFound)\n\t\treadToken (token);\n\tswitch (token->keyword)\n\t{\n\t\tcase KEYWORD_attribute:\n\t\tcase KEYWORD_deferred:\n\t\tcase KEYWORD_do:\n\t\tcase KEYWORD_external:\n\t\tcase KEYWORD_local:\n\t\tcase KEYWORD_note:\n\t\tcase KEYWORD_obsolete:\n\t\tcase KEYWORD_once:\n\t\tcase KEYWORD_require:\n\t\t{\n\t\t\tint depth = 1;\n\n\t\t\twhile (depth > 0 && ! isType (token, TOKEN_EOF))\n\t\t\t{\n\t\t\t\tswitch (token->keyword)\n\t\t\t\t{\n\t\t\t\t\tcase KEYWORD_check:\n\t\t\t\t\tcase KEYWORD_debug:\n\t\t\t\t\tcase KEYWORD_from:\n\t\t\t\t\tcase KEYWORD_across:\n\t\t\t\t\tcase KEYWORD_if:\n\t\t\t\t\tcase KEYWORD_inspect:\n\t\t\t\t\t\t++depth;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_local:\n\t\t\t\t\t\tparseLocal (token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_end:\n\t\t\t\t\t\t--depth;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\t/* is this a manifest constant? */\n\t\t\tif (isFound || isType (token, TOKEN_OPERATOR)) {\n\t\t\t\tif (isType (token, TOKEN_OPERATOR))\n\t\t\t\t\treadToken (token);\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n\nstatic bool readFeatureName (tokenInfo *const token)\n{\n\tbool isFeatureName = false;\n\n\tif (isKeyword (token, KEYWORD_frozen))\n\t\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t\tisFeatureName = true;\n\telse if (isKeyword (token, KEYWORD_assign))  /* legacy code */\n\t\tisFeatureName = true;\n\telse if (isKeyword (token, KEYWORD_infix)  ||\n\t\t\tisKeyword (token, KEYWORD_prefix))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_STRING))\n\t\t\tisFeatureName = true;\n\t}\n\treturn isFeatureName;\n}\n\nstatic void parseArguments (tokenInfo *const token)\n{\n\tif (findToken (token, TOKEN_CLOSE_PAREN))\n\t\treadToken (token);\n}\n\nstatic bool parseFeature (tokenInfo *const token)\n{\n\tbool found = false;\n\twhile (readFeatureName (token))\n\t{\n\t\tfound = true;\n\t\tmakeEiffelFeatureTag (token);\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t\treadToken (token);\n\t}\n\tif (found)\n\t{\n\t\tif (isKeyword (token, KEYWORD_alias)) {\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_STRING))\n\t\t\t\tmakeEiffelFeatureTag (token);\n\t\t\treadToken (token);\n\t\t}\n\t\tif (isType (token, TOKEN_OPEN_PAREN))  /* arguments? */\n\t\t\tparseArguments (token);\n\t\tif (isType (token, TOKEN_COLON))       /* a query? */\n\t\t\tparseEntityType (token);\n\t\tif (isKeyword (token, KEYWORD_assign))\n\t\t{\n\t\t\treadToken (token);\n\t\t\treadToken (token);\n\t\t}\n\t\tif (isKeyword (token, KEYWORD_obsolete))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_STRING))\n\t\t\t\treadToken (token);\n\t\t}\n\t\tfindFeatureEnd (token);\n\t}\n\treturn found;\n}\n\nstatic void parseExport (tokenInfo *const token)\n{\n\ttoken->isExported = true;\n\treadToken (token);\n\tif (isType (token, TOKEN_OPEN_BRACE))\n\t{\n\t\ttoken->isExported = false;\n\t\twhile (! isType (token, TOKEN_CLOSE_BRACE) &&\n\t\t       ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\ttoken->isExported |= !isIdentifierMatch (token, \"NONE\");\n\t\t\treadToken (token);\n\t\t}\n\t\treadToken (token);\n\t}\n}\n\nstatic void parseFeatureClauses (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_feature));\n\tdo\n\t{\n\t\tif (isKeyword (token, KEYWORD_feature))\n\t\t\tparseExport (token);\n\t\tif (! isKeyword (token, KEYWORD_feature) &&\n\t\t\t! isKeyword (token, KEYWORD_invariant) &&\n\t\t\t! isKeyword (token, KEYWORD_note))\n\t\t{\n\t\t\tif (! parseFeature (token))\n\t\t\t\treadToken (token);\n\t\t}\n\t} while (! isKeyword (token, KEYWORD_end) &&\n\t\t\t ! isKeyword (token, KEYWORD_invariant) &&\n\t\t\t ! isKeyword (token, KEYWORD_note) &&\n\t\t\t ! isType (token, TOKEN_EOF));\n}\n\nstatic void parseRename (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_rename));\n\tdo {\n\t\treadToken (token);\n\t\tif (readFeatureName (token))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isKeyword (token, KEYWORD_as))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (readFeatureName (token))\n\t\t\t\t{\n\t\t\t\t\tmakeEiffelFeatureTag (token);  /* renamed feature */\n\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} while (isType (token, TOKEN_COMMA));\n}\n\nstatic void parseInherit (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_inherit));\n\treadToken (token);\n\twhile (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\tparseType (token);\n\t\tif (isType (token, TOKEN_KEYWORD))\n\t\t{\n\t\t\tswitch (token->keyword)  /* check for feature adaptation */\n\t\t\t{\n\t\t\t\tcase KEYWORD_rename:\n\t\t\t\t\tparseRename (token);\n\t\t\t\tcase KEYWORD_export:\n\t\t\t\tcase KEYWORD_undefine:\n\t\t\t\tcase KEYWORD_redefine:\n\t\t\t\tcase KEYWORD_select:\n\t\t\t\t\tif (findKeyword (token, KEYWORD_end))\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase KEYWORD_end:\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault: break;\n\t\t\t}\n\t\t}\n\t\tif (isType (token, TOKEN_SEMICOLON))\n\t\t\treadToken (token);\n\t}\n}\n\nstatic void parseConvert (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_convert));\n\tdo\n\t{\n\t\treadToken (token);\n\t\tif (! isType (token, TOKEN_IDENTIFIER))\n\t\t\tbreak;\n\t\telse if (isType (token, TOKEN_OPEN_PAREN))\n\t\t{\n\t\t\twhile (! isType (token, TOKEN_CLOSE_PAREN) &&\n\t\t\t       ! isType (token, TOKEN_EOF))\n\t\t\t\treadToken (token);\n\t\t}\n\t\telse if (isType (token, TOKEN_COLON))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (! isType (token, TOKEN_OPEN_BRACE))\n\t\t\t\tbreak;\n\t\t\telse while (! isType (token, TOKEN_CLOSE_BRACE))\n\t\t\t\treadToken (token);\n\t\t}\n\t} while (isType (token, TOKEN_COMMA));\n}\n\nstatic void parseClass (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_class));\n\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\tmakeEiffelClassTag (token);\n\t\treadToken (token);\n\t}\n\n\tdo\n\t{\n\t\tif (isType (token, TOKEN_OPEN_BRACKET))\n\t\t\tparseGeneric (token, true);\n\t\telse if (! isType (token, TOKEN_KEYWORD))\n\t\t\treadToken (token);\n\t\telse switch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_inherit:  parseInherit (token);        break;\n\t\t\tcase KEYWORD_feature:  parseFeatureClauses (token); break;\n\t\t\tcase KEYWORD_convert:  parseConvert (token);        break;\n\t\t\tdefault:               readToken (token);           break;\n\t\t}\n\t} while (! isKeyword (token, KEYWORD_end) &&\n\t         ! isType (token, TOKEN_EOF));\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_eiffel = language;\n}\n\nstatic void findEiffelTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\twhile (findKeyword (token, KEYWORD_class))\n\t\tparseClass (token);\n\tdeleteToken (token);\n}\n\nextern parserDefinition* EiffelParser (void)\n{\n\tstatic const char *const extensions [] = { \"e\", NULL };\n\tparserDefinition* def = parserNew (\"Eiffel\");\n\tdef->kindTable      = EiffelKinds;\n\tdef->kindCount  = ARRAY_SIZE (EiffelKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findEiffelTags;\n\tdef->initialize = initialize;\n\tdef->keywordTable = EiffelKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (EiffelKeywordTable);\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/erlang.c",
    "content": "/*\n*   Copyright (c) 2003, Brent Fulgham <bfulgham@debian.org>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Erlang language\n*   files.  Some of the parsing constructs are based on the Emacs 'etags'\n*   program by Francesco Potori <pot@gnu.org>\n*/\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"read.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_MACRO, K_FUNCTION, K_MODULE, K_RECORD, K_TYPE\n} erlangKind;\n\nstatic kindDefinition ErlangKinds[] = {\n\t{true, 'd', \"macro\",    \"macro definitions\"},\n\t{true, 'f', \"function\", \"functions\"},\n\t{true, 'm', \"module\",   \"modules\"},\n\t{true, 'r', \"record\",   \"record definitions\"},\n\t{true, 't', \"type\",     \"type definitions\"},\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n/* tagEntryInfo and vString should be preinitialized/preallocated but not\n * necessary. If successful you will find class name in vString\n */\n\nstatic bool isIdentifierFirstCharacter (int c)\n{\n\treturn (bool) (isalpha (c));\n}\n\nstatic bool isIdentifierCharacter (int c)\n{\n\treturn (bool) (isalnum (c) || c == '_' || c == ':');\n}\n\nstatic const unsigned char *skipSpace (const unsigned char *cp)\n{\n\twhile (isspace (*cp))\n\t\t++cp;\n\treturn cp;\n}\n\nstatic const unsigned char *parseIdentifier (\n\t\tconst unsigned char *cp, vString *const identifier)\n{\n\tvStringClear (identifier);\n\twhile (isIdentifierCharacter (*cp))\n\t{\n\t\tvStringPut (identifier, *cp);\n\t\t++cp;\n\t}\n\treturn cp;\n}\n\nstatic void makeMemberTag (\n\t\tvString *const identifier, erlangKind kind, vString *const module)\n{\n\tif (ErlangKinds [kind].enabled  &&  vStringLength (identifier) > 0)\n\t{\n\t\ttagEntryInfo tag;\n\t\tinitTagEntry (&tag, vStringValue (identifier), kind);\n\n\t\tif (module != NULL  &&  vStringLength (module) > 0)\n\t\t{\n\t\t\ttag.extensionFields.scopeKindIndex = K_MODULE;\n\t\t\ttag.extensionFields.scopeName = vStringValue (module);\n\t\t}\n\t\tmakeTagEntry (&tag);\n\t}\n}\n\nstatic void parseModuleTag (const unsigned char *cp, vString *const module)\n{\n\tvString *const identifier = vStringNew ();\n\tparseIdentifier (cp, identifier);\n\tmakeSimpleTag (identifier, K_MODULE);\n\n\t/* All further entries go in the new module */\n\tvStringCopy (module, identifier);\n\tvStringDelete (identifier);\n}\n\nstatic void parseSimpleTag (const unsigned char *cp, erlangKind kind)\n{\n\tvString *const identifier = vStringNew ();\n\tparseIdentifier (cp, identifier);\n\tmakeSimpleTag (identifier, kind);\n\tvStringDelete (identifier);\n}\n\nstatic void parseFunctionTag (const unsigned char *cp, vString *const module)\n{\n\tvString *const identifier = vStringNew ();\n\tparseIdentifier (cp, identifier);\n\tmakeMemberTag (identifier, K_FUNCTION, module);\n\tvStringDelete (identifier);\n}\n\n/*\n * Directives are of the form:\n * -module(foo)\n * -define(foo, bar)\n * -record(graph, {vtab = notable, cyclic = true}).\n * -type some_type() :: any().\n * -opaque some_opaque_type() :: any().\n */\nstatic void parseDirective (const unsigned char *cp, vString *const module)\n{\n\t/*\n\t * A directive will be either a record definition or a directive.\n\t * Record definitions are handled separately\n\t */\n\tvString *const directive = vStringNew ();\n\tcp = parseIdentifier (cp, directive);\n\tcp = skipSpace (cp);\n\tif (*cp == '(')\n\t\t++cp;\n\n\tconst char *const drtv = vStringValue (directive);\n\tif (strcmp (drtv, \"record\") == 0)\n\t\tparseSimpleTag (cp, K_RECORD);\n\telse if (strcmp (drtv, \"define\") == 0)\n\t\tparseSimpleTag (cp, K_MACRO);\n\telse if (strcmp (drtv, \"type\") == 0)\n\t\tparseSimpleTag (cp, K_TYPE);\n\telse if (strcmp (drtv, \"opaque\") == 0)\n\t\tparseSimpleTag (cp, K_TYPE);\n\telse if (strcmp (drtv, \"module\") == 0)\n\t\tparseModuleTag (cp, module);\n\t/* Otherwise, it was an import, export, etc. */\n\n\tvStringDelete (directive);\n}\n\nstatic void findErlangTags (void)\n{\n\tvString *const module = vStringNew ();\n\tconst unsigned char *line;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char *cp = line;\n\n\t\tif (*cp == '%')  /* skip initial comment */\n\t\t\tcontinue;\n\t\tif (*cp == '\"')  /* strings sometimes start in column one */\n\t\t\tcontinue;\n\n\t\tif ( *cp == '-')\n\t\t{\n\t\t\t++cp;  /* Move off of the '-' */\n\t\t\tparseDirective(cp, module);\n\t\t}\n\t\telse if (isIdentifierFirstCharacter (*cp))\n\t\t\tparseFunctionTag (cp, module);\n\t}\n\tvStringDelete (module);\n}\n\nextern parserDefinition *ErlangParser (void)\n{\n\tstatic const char *const extensions[] = { \"erl\", \"ERL\", \"hrl\", \"HRL\", NULL };\n\tparserDefinition *def = parserNew (\"Erlang\");\n\tdef->kindTable = ErlangKinds;\n\tdef->kindCount = ARRAY_SIZE (ErlangKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findErlangTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/falcon.c",
    "content": "/*\n * Copyright (c) 2011, 2012 Steven Oliver <oliver.steven@gmail.com>\n *\n * This source code is released for free distribution under the terms of the\n * GNU General Public License version 2 or (at your option) any later version.\n *\n * This module contains functions for generating tags for Falcon language\n * files.\n */\n\n\n/*\n * INCLUDE FILES\n */\n#include \"general.h\"\n\n#include <string.h>\n#include <ctype.h>\n\n#include \"read.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n\n/*\n * Data Definitions\n */\ntypedef enum eFalconKinds {\n    K_CLASS,\n    K_FUNCTION,\n    K_MEMBER,\n    K_VARIABLE,\n    K_NAMESPACE\n} falconKind;\n\nstatic kindDefinition FalconKinds [] = {\n    {true, 'c', \"class\",     \"classes\" },\n    {true, 'f', \"function\",  \"functions\"},\n    {true, 'm', \"member\",    \"class members\"},\n    {true, 'v', \"variable\",  \"variables\"},\n    {true, 'i', \"namespace\", \"imports\"}\n};\n\n/*\n * Function Definitions\n */\n\nstatic bool isIdentifierChar (int c)\n{\n    return (bool) (isalnum (c));\n}\n\nstatic const unsigned char *skipSpace (const unsigned char *cp)\n{\n    while (isspace (*cp))\n        ++cp;\n\n    return cp;\n}\n\n/*\n * Main parsing function\n */\n\nstatic void findFalconTags (void)\n{\n    vString *name = vStringNew ();\n    const unsigned char *line;\n\n    while ((line = readLineFromInputFile ()) != NULL)\n    {\n        const unsigned char *cp = line;\n\n        // Skip lines starting with # which in falcon\n        // would only be the \"crunch bang\" statement\n        if (*cp == '#')\n            continue;\n\n        if (strncmp ((const char*) cp, \"function\", (size_t) 8) == 0)\n        {\n            cp += 8;\n            cp = skipSpace (cp);\n\n            while (isIdentifierChar (*cp))\n            {\n                vStringPut (name, *cp);\n                ++cp;\n            }\n            makeSimpleTag (name, K_FUNCTION);\n            vStringClear (name);\n        }\n        else if (strncmp ((const char*) cp, \"class\", (size_t) 5) == 0)\n        {\n            cp += 5;\n            cp = skipSpace (cp);\n\n            while (isIdentifierChar (*cp))\n            {\n                vStringPut (name, *cp);\n                ++cp;\n            }\n            makeSimpleTag (name, K_CLASS);\n            vStringClear (name);\n        }\n        else if (strncmp ((const char*) cp, \"load\", (size_t) 4) == 0)\n        {\n            cp += 4;\n            cp = skipSpace (cp);\n\n            while (isIdentifierChar (*cp))\n            {\n                vStringPut (name, *cp);\n                ++cp;\n            }\n            makeSimpleTag (name, K_NAMESPACE);\n            vStringClear (name);\n        }\n        else if (strncmp ((const char*) cp, \"import from\", (size_t) 11) == 0)\n        {\n            cp += 12;\n            cp = skipSpace (cp);\n\n            while (isIdentifierChar (*cp))\n            {\n                vStringPut (name, *cp);\n                ++cp;\n            }\n            makeSimpleTag (name, K_NAMESPACE);\n            vStringClear (name);\n        }\n    }\n    vStringDelete (name);\n}\n\n/*\n * Parser definition structure\n */\nextern parserDefinition* FalconParser (void)\n{\n    static const char *const extensions [] = { \"fal\", \"ftd\", NULL };\n    parserDefinition *def = parserNew (\"Falcon\");\n    def->kindTable  = FalconKinds;\n    def->kindCount  = ARRAY_SIZE (FalconKinds);\n    def->extensions = extensions;\n    def->parser     = findFalconTags;\n    return def;\n}\n"
  },
  {
    "path": "parsers/flex.c",
    "content": "/*\n *\t Copyright (c) 2008, David Fishburn\n *\n *\t This source code is released for free distribution under the terms of the\n *\t GNU General Public License version 2 or (at your option) any later version.\n *\n *\t This module contains functions for generating tags for Adobe languages.\n *\t There are a number of different ones, but this will begin with:\n *\t     Flex\n *\t         MXML files (*.mMacromedia XML)\n *\t         ActionScript files (*.as)\n *\n *\t The ActionScript code was copied from the JavaScript parser, with some\n *\t adaptations e.g. for classes and type specifiers.\n *\n *\t Flex 3 language reference\n *\t\t http://livedocs.adobe.com/flex/3/langref/index.html\n * \t\t https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/language-elements.html\n * \t\t https://www.adobe.com/devnet/actionscript/learning/as3-fundamentals/packages.html\n */\n\n/*\n *\t INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n#include <ctype.h>\t/* to define isalpha () */\n#ifdef DEBUG\n#include <stdio.h>\n#endif\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"strlist.h\"\n\n/*\n *\t MACROS\n */\n#define isType(token,t)\t\t(bool) ((token)->type == (t))\n#define isKeyword(token,k)\t(bool) ((token)->keyword == (k))\n#define isEOF(token) (isType ((token), TOKEN_EOF))\n#define isIdentChar(c) \\\n\t(isalpha (c) || isdigit (c) || (c) == '$' || \\\n\t\t(c) == '@' || (c) == '_' || (c) == '#' || \\\n\t\t(c) >= 0x80)\n\n/*\n *\t DATA DECLARATIONS\n */\n\n/*\n * Tracks class and function names already created\n */\nstatic stringList *ClassNames;\nstatic stringList *FunctionNames;\n\n/*\tUsed to specify type of keyword.\n*/\nenum eKeywordId {\n\tKEYWORD_function,\n\tKEYWORD_capital_function,\n\tKEYWORD_object,\n\tKEYWORD_capital_object,\n\tKEYWORD_prototype,\n\tKEYWORD_var,\n\tKEYWORD_const,\n\tKEYWORD_new,\n\tKEYWORD_this,\n\tKEYWORD_for,\n\tKEYWORD_while,\n\tKEYWORD_do,\n\tKEYWORD_if,\n\tKEYWORD_else,\n\tKEYWORD_switch,\n\tKEYWORD_try,\n\tKEYWORD_catch,\n\tKEYWORD_finally,\n\tKEYWORD_return,\n\tKEYWORD_public,\n\tKEYWORD_private,\n\tKEYWORD_protected,\n\tKEYWORD_internal,\n\tKEYWORD_final,\n\tKEYWORD_native,\n\tKEYWORD_dynamic,\n\tKEYWORD_class,\n\tKEYWORD_interface,\n\tKEYWORD_package,\n\tKEYWORD_extends,\n\tKEYWORD_static,\n\tKEYWORD_implements,\n\tKEYWORD_get,\n\tKEYWORD_set,\n\tKEYWORD_import,\n\tKEYWORD_id,\n\tKEYWORD_name,\n\tKEYWORD_script,\n\tKEYWORD_cdata,\n\tKEYWORD_mx,\n\tKEYWORD_fx,\n\tKEYWORD_override\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum eTokenType {\n\tTOKEN_UNDEFINED,\n\tTOKEN_EOF,\n\tTOKEN_CHARACTER,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_SEMICOLON,\n\tTOKEN_COLON,\n\tTOKEN_COMMA,\n\tTOKEN_KEYWORD,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n\tTOKEN_PERIOD,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_EQUAL_SIGN,\n\tTOKEN_EXCLAMATION,\n\tTOKEN_FORWARD_SLASH,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_OPEN_MXML,\n\tTOKEN_CLOSE_MXML,\n\tTOKEN_CLOSE_SGML,\n\tTOKEN_LESS_THAN,\n\tTOKEN_GREATER_THAN,\n\tTOKEN_QUESTION_MARK,\n\tTOKEN_OPEN_NAMESPACE,\n\tTOKEN_POSTFIX_OPERATOR,\n\tTOKEN_STAR,\n\tTOKEN_BINARY_OPERATOR\n} tokenType;\n\ntypedef struct sTokenInfo {\n\ttokenType\t\ttype;\n\tkeywordId\t\tkeyword;\n\tvString *\t\tstring;\n\tvString *\t\tscope;\n\tunsigned long \tlineNumber;\n\tMIOPos \t\t\tfilePosition;\n\tint\t\t\t\tnestLevel;\n\tbool\t\t\tignoreTag;\n\tbool\t\t\tisClass;\n} tokenInfo;\n\n/*\n *\tDATA DEFINITIONS\n */\nstatic tokenType LastTokenType;\nstatic tokenInfo *NextToken;\n\nstatic langType Lang_flex;\n\ntypedef enum {\n\tFLEXTAG_FUNCTION,\n\tFLEXTAG_CLASS,\n\tFLEXTAG_INTERFACE,\n\tFLEXTAG_PACKAGE,\n\tFLEXTAG_METHOD,\n\tFLEXTAG_PROPERTY,\n\tFLEXTAG_VARIABLE,\n\tFLEXTAG_LOCALVAR,\n\tFLEXTAG_CONST,\n\tFLEXTAG_IMPORT,\n\tFLEXTAG_MXTAG,\n\tFLEXTAG_COUNT\n} flexKind;\n\ntypedef enum {\n\tFLEX_IMPORT_ROLE_IMPORTED,\n} flexImportRole;\n\nstatic roleDefinition FlexImportRoles [] = {\n\t{ true, \"import\", \"imports\" },\n};\n\nstatic kindDefinition FlexKinds [] = {\n\t{ true,  'f', \"function\",\t  \"functions\"\t\t   },\n\t{ true,  'c', \"class\",\t\t  \"classes\"\t\t\t   },\n\t{ true,  'i', \"interface\",\t  \"interfaces\"\t\t   },\n\t{ true,  'P', \"package\",\t  \"packages\"\t\t   },\n\t{ true,  'm', \"method\",\t\t  \"methods\"\t\t\t   },\n\t{ true,  'p', \"property\",\t  \"properties\"\t\t   },\n\t{ true,  'v', \"variable\",\t  \"global variables\"   },\n\t{ false, 'l', \"localvar\",\t  \"local variables\"   },\n\t{ true,  'C', \"constant\",\t  \"constants\"\t\t   },\n\t{ true,  'I', \"import\",\t\t  \"imports\",\n\t  .referenceOnly = true, ATTACH_ROLES (FlexImportRoles) },\n\t{ true,  'x', \"mxtag\",\t\t  \"mxtags\" \t\t\t   }\n};\n\n/*\tUsed to determine whether keyword is valid for the token language and\n *\twhat its ID is.\n */\nstatic const keywordTable FlexKeywordTable [] = {\n\t/* keyword\t\tkeyword ID */\n\t{ \"function\",\tKEYWORD_function\t\t\t},\n\t{ \"Function\",\tKEYWORD_capital_function\t},\n\t{ \"object\",\t\tKEYWORD_object\t\t\t\t},\n\t{ \"Object\",\t\tKEYWORD_capital_object\t\t},\n\t{ \"prototype\",\tKEYWORD_prototype\t\t\t},\n\t{ \"var\",\t\tKEYWORD_var\t\t\t\t\t},\n\t{ \"const\",\t\tKEYWORD_const\t\t\t\t},\n\t{ \"new\",\t\tKEYWORD_new\t\t\t\t\t},\n\t{ \"this\",\t\tKEYWORD_this\t\t\t\t},\n\t{ \"for\",\t\tKEYWORD_for\t\t\t\t\t},\n\t{ \"while\",\t\tKEYWORD_while\t\t\t\t},\n\t{ \"do\",\t\t\tKEYWORD_do\t\t\t\t\t},\n\t{ \"if\",\t\t\tKEYWORD_if\t\t\t\t\t},\n\t{ \"else\",\t\tKEYWORD_else\t\t\t\t},\n\t{ \"switch\",\t\tKEYWORD_switch\t\t\t\t},\n\t{ \"try\",\t\tKEYWORD_try\t\t\t\t\t},\n\t{ \"catch\",\t\tKEYWORD_catch\t\t\t\t},\n\t{ \"finally\",\tKEYWORD_finally\t\t\t\t},\n\t{ \"return\",\t\tKEYWORD_return\t\t\t\t},\n\t{ \"public\",\t\tKEYWORD_public\t\t\t\t},\n\t{ \"private\",\tKEYWORD_private\t\t\t\t},\n\t{ \"protected\",\tKEYWORD_protected\t\t\t},\n\t{ \"internal\",\tKEYWORD_internal\t\t\t},\n\t{ \"final\",\t\tKEYWORD_final\t\t\t\t},\n\t{ \"native\",\t\tKEYWORD_native\t\t\t\t},\n\t{ \"dynamic\",\tKEYWORD_dynamic\t\t\t\t},\n\t{ \"class\",\t\tKEYWORD_class\t\t\t\t},\n\t{ \"interface\",\tKEYWORD_interface\t\t\t},\n\t{ \"package\",\tKEYWORD_package\t\t\t\t},\n\t{ \"extends\",\tKEYWORD_extends\t\t\t\t},\n\t{ \"static\",\t\tKEYWORD_static\t\t\t\t},\n\t{ \"implements\",\tKEYWORD_implements\t\t\t},\n\t{ \"get\",\t\tKEYWORD_get\t\t\t\t\t},\n\t{ \"set\",\t\tKEYWORD_set\t\t\t\t\t},\n\t{ \"import\",\t\tKEYWORD_import\t\t\t\t},\n\t{ \"id\",\t\t\tKEYWORD_id\t\t\t\t\t},\n\t{ \"name\",\t\tKEYWORD_name\t\t\t\t},\n\t{ \"script\",\t\tKEYWORD_script\t\t\t\t},\n\t{ \"cdata\",\t\tKEYWORD_cdata\t\t\t\t},\n\t{ \"mx\",\t\t\tKEYWORD_mx\t\t\t\t\t},\n\t{ \"fx\",\t\t\tKEYWORD_fx\t\t\t\t\t},\n\t{ \"override\",\tKEYWORD_override\t\t\t}\n};\n\n/*\n *\t FUNCTION DEFINITIONS\n */\n\n/* Recursive functions */\nstatic void parseFunction (tokenInfo *const token);\nstatic bool parseBlock (tokenInfo *const token, const vString *const parentScope);\nstatic bool parseLine (tokenInfo *const token);\nstatic bool parseActionScript (tokenInfo *const token, bool readNext);\nstatic bool parseMXML (tokenInfo *const token);\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->string\t\t= vStringNew ();\n\ttoken->scope\t\t= vStringNew ();\n\ttoken->nestLevel\t= 0;\n\ttoken->isClass\t\t= false;\n\ttoken->ignoreTag\t= false;\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\treturn token;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tvStringDelete (token->string);\n\tvStringDelete (token->scope);\n\teFree (token);\n}\n\nstatic void copyToken (tokenInfo *const dest, tokenInfo *const src,\n                       bool const include_non_read_info)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tdest->keyword = src->keyword;\n\tdest->isClass = src->isClass;\n\tvStringCopy(dest->string, src->string);\n\tif (include_non_read_info)\n\t{\n\t\tdest->nestLevel = src->nestLevel;\n\t\tvStringCopy(dest->scope, src->scope);\n\t}\n}\n\n/*\n *\t Tag generation functions\n */\n\nstatic vString *buildQualifiedName (const tokenInfo *const token)\n{\n\tvString *qualified = vStringNew ();\n\n\tif (vStringLength (token->scope) > 0)\n\t{\n\t\tvStringCopy (qualified, token->scope);\n\t\tvStringPut (qualified, '.');\n\t}\n\tvStringCat (qualified, token->string);\n\n\treturn qualified;\n}\n\nstatic void makeConstTag (tokenInfo *const token, const flexKind kind)\n{\n\tif (FlexKinds [kind].enabled && ! token->ignoreTag )\n\t{\n\t\tconst char *const name = vStringValue (token->string);\n\t\ttagEntryInfo e;\n\t\tint role = ROLE_DEFINITION_INDEX;\n\n\t\tif (kind == FLEXTAG_IMPORT)\n\t\t\trole = FLEX_IMPORT_ROLE_IMPORTED;\n\n\t\tinitRefTagEntry (&e, name, kind, role);\n\n\t\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\n\t\tif ( vStringLength(token->scope) > 0 )\n\t\t{\n\t\t\t/* FIXME: proper parent type */\n\t\t\tflexKind parent_kind = FLEXTAG_CLASS;\n\n\t\t\t/*\n\t\t\t * If we're creating a function (and not a method),\n\t\t\t * guess we're inside another function\n\t\t\t */\n\t\t\tif (kind == FLEXTAG_FUNCTION)\n\t\t\t\tparent_kind = FLEXTAG_FUNCTION;\n\t\t\t/* mxtags can only be nested inside other mxtags */\n\t\t\telse if (kind == FLEXTAG_MXTAG)\n\t\t\t\tparent_kind = kind;\n\n\t\t\te.extensionFields.scopeKindIndex = parent_kind;\n\t\t\te.extensionFields.scopeName = vStringValue (token->scope);\n\t\t}\n\n\t\tmakeTagEntry (&e);\n\n\t\t/* make qualified tags for compatibility if requested */\n\t\tif (isXtagEnabled (XTAG_QUALIFIED_TAGS))\n\t\t{\n\t\t\tvString *qualified = buildQualifiedName (token);\n\n\t\t\tmarkTagExtraBit (&e, XTAG_QUALIFIED_TAGS);\n\t\t\te.name = vStringValue (qualified);\n\t\t\tmakeTagEntry (&e);\n\t\t\tvStringDelete (qualified);\n\t\t}\n\t}\n}\n\nstatic void makeFlexTag (tokenInfo *const token, flexKind kind)\n{\n\tif (FlexKinds [kind].enabled && ! token->ignoreTag )\n\t{\n\tDebugStatement (\n\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t, \"\\n makeFlexTag start: token isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t, token->isClass\n\t\t\t\t, vStringValue(token->scope)\n\t\t\t\t, vStringValue(token->string)\n\t\t\t\t);\n\t\t\t);\n\t\tif (kind == FLEXTAG_FUNCTION && token->isClass )\n\t\t{\n\t\t\tkind = FLEXTAG_METHOD;\n\t\t}\n\t\tmakeConstTag (token, kind);\n\t}\n}\n\nstatic void makeClassTag (tokenInfo *const token)\n{\n\tif ( ! token->ignoreTag )\n\t{\n\t\tvString *fulltag = buildQualifiedName (token);\n\n\t\tif ( ! stringListHas(ClassNames, vStringValue (fulltag)) )\n\t\t{\n\t\t\tstringListAdd (ClassNames, vStringNewCopy (fulltag));\n\t\t\tmakeFlexTag (token, FLEXTAG_CLASS);\n\t\t}\n\t\tvStringDelete (fulltag);\n\t}\n}\n\nstatic void makeMXTag (tokenInfo *const token)\n{\n\tif ( ! token->ignoreTag )\n\t{\n\t\tmakeFlexTag (token, FLEXTAG_MXTAG);\n\t}\n}\n\nstatic void makeFunctionTag (tokenInfo *const token)\n{\n\tif ( ! token->ignoreTag )\n\t{\n\t\tvString *fulltag = buildQualifiedName (token);\n\n\t\tif ( ! stringListHas(FunctionNames, vStringValue (fulltag)) )\n\t\t{\n\t\t\tstringListAdd (FunctionNames, vStringNewCopy (fulltag));\n\t\t\tmakeFlexTag (token, FLEXTAG_FUNCTION);\n\t\t}\n\t\tvStringDelete (fulltag);\n\t}\n}\n\n/*\n *\t Parsing functions\n */\n\nstatic void parseString (vString *const string, const int delimiter)\n{\n\tbool end = false;\n\twhile (! end)\n\t{\n\t\tint c = getcFromInputFile ();\n\t\tif (c == EOF)\n\t\t\tend = true;\n\t\telse if (c == '\\\\')\n\t\t{\n\t\t\tc = getcFromInputFile(); /* This maybe a ' or \". */\n\t\t\tvStringPut(string, c);\n\t\t}\n\t\telse if (c == delimiter)\n\t\t\tend = true;\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\n/*\tRead a C identifier beginning with \"firstChar\" and places it into\n *\t\"name\".\n */\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tAssert (isIdentChar (c));\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isIdentChar (c));\n\tungetcToInputFile (c);\t\t/* unget non-identifier character */\n}\n\nstatic void readTokenFull (tokenInfo *const token, bool include_newlines)\n{\n\tint c;\n\tbool newline_encountered = false;\n\n\t/* if we've got a token held back, emit it */\n\tif (NextToken)\n\t{\n\t\tcopyToken (token, NextToken, false);\n\t\tdeleteToken (NextToken);\n\t\tNextToken = NULL;\n\t\treturn;\n\t}\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\ngetNextChar:\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\tif (include_newlines && (c == '\\r' || c == '\\n'))\n\t\t\tnewline_encountered = true;\n\t}\n\twhile (c == '\\t' || c == ' ' || c == '\\r' || c == '\\n');\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tswitch (c)\n\t{\n\t\tcase EOF: token->type = TOKEN_EOF;\t\t\t\t\tbreak;\n\t\tcase '(': token->type = TOKEN_OPEN_PAREN;\t\t\tbreak;\n\t\tcase ')': token->type = TOKEN_CLOSE_PAREN;\t\t\tbreak;\n\t\tcase ';': token->type = TOKEN_SEMICOLON;\t\t\tbreak;\n\t\tcase ',': token->type = TOKEN_COMMA;\t\t\t\tbreak;\n\t\tcase '.': token->type = TOKEN_PERIOD;\t\t\t\tbreak;\n\t\tcase ':': token->type = TOKEN_COLON;\t\t\t\tbreak;\n\t\tcase '{': token->type = TOKEN_OPEN_CURLY;\t\t\tbreak;\n\t\tcase '}': token->type = TOKEN_CLOSE_CURLY;\t\t\tbreak;\n\t\tcase '=': token->type = TOKEN_EQUAL_SIGN;\t\t\tbreak;\n\t\tcase '[': token->type = TOKEN_OPEN_SQUARE;\t\t\tbreak;\n\t\tcase ']': token->type = TOKEN_CLOSE_SQUARE;\t\t\tbreak;\n\t\tcase '?': token->type = TOKEN_QUESTION_MARK;\t\tbreak;\n\n\t\tcase '+':\n\t\tcase '-':\n\t\t\t{\n\t\t\t\tint d = getcFromInputFile ();\n\t\t\t\tif (d == c) /* ++ or -- */\n\t\t\t\t\ttoken->type = TOKEN_POSTFIX_OPERATOR;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\t\ttoken->type = TOKEN_BINARY_OPERATOR;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\tcase '*':\n\t\t\ttoken->type = TOKEN_STAR;\n\t\t\tbreak;\n\t\tcase '%':\n\t\tcase '^':\n\t\tcase '|':\n\t\tcase '&':\n\t\t\ttoken->type = TOKEN_BINARY_OPERATOR;\n\t\t\tbreak;\n\n\t\tcase '\\'':\n\t\tcase '\"':\n\t\t\t\t  token->type = TOKEN_STRING;\n\t\t\t\t  parseString (token->string, c);\n\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t  break;\n\n\t\tcase '\\\\':\n\t\t\t\t  c = getcFromInputFile ();\n\t\t\t\t  if (c != '\\\\'  && c != '\"'  &&  !isspace (c))\n\t\t\t\t\t  ungetcToInputFile (c);\n\t\t\t\t  token->type = TOKEN_CHARACTER;\n\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t  break;\n\n\t\tcase '/':\n\t\t\t\t  {\n\t\t\t\t\t  int d = getcFromInputFile ();\n\t\t\t\t\t  if ( (d != '*') &&\t\t/* is this the start of a comment? */\n\t\t\t\t\t\t\t  (d != '/') &&\t\t/* is a one line comment? */\n\t\t\t\t\t\t\t  (d != '>') )\t\t/* is this a close XML tag? */\n\t\t\t\t\t  {\n\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t\t  token->type = TOKEN_FORWARD_SLASH;\n\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t  }\n\t\t\t\t\t  else\n\t\t\t\t\t  {\n\t\t\t\t\t\t  if (d == '*')\n\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t  skipToCharacterInInputFile2('*', '/');\n\t\t\t\t\t\t\t  goto getNextChar;\n\t\t\t\t\t\t  }\n\t\t\t\t\t\t  else if (d == '/')\t/* is this the start of a comment?  */\n\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t  skipToCharacterInInputFile ('\\n');\n\t\t\t\t\t\t\t  /* if we care about newlines, put it back so it is seen */\n\t\t\t\t\t\t\t  if (include_newlines)\n\t\t\t\t\t\t\t\t  ungetcToInputFile ('\\n');\n\t\t\t\t\t\t\t  goto getNextChar;\n\t\t\t\t\t\t  }\n\t\t\t\t\t\t  else if (d == '>')\t/* is this the start of a comment?  */\n\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t  token->type = TOKEN_CLOSE_SGML;\n\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t  }\n\t\t\t\t\t  }\n\t\t\t\t\t  break;\n\t\t\t\t  }\n\n\t\tcase '<':\n\t\t\t\t  {\n\t\t\t\t\t  /*\n\t\t\t\t\t   * An XML comment looks like this\n\t\t\t\t\t   *   <!-- anything over multiple lines -->\n\t\t\t\t\t   */\n\t\t\t\t\t  int d = getcFromInputFile ();\n\n\t\t\t\t\t  if ( (d != '!' )  && \t\t/* is this the start of a comment? */\n\t\t\t\t\t       (d != '/' )  &&\t \t/* is this the start of a closing mx tag */\n\t\t\t\t\t       (d != 'm' )  &&  \t/* is this the start of a mx tag */\n\t\t\t\t\t       (d != 'f' )  &&  \t/* is this the start of a fx tag */\n\t\t\t\t\t       (d != 's' )    ) \t/* is this the start of a spark tag */\n\t\t\t\t\t  {\n\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t\t  token->type = TOKEN_LESS_THAN;\n\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t  break;\n\t\t\t\t\t  }\n\t\t\t\t\t  else\n\t\t\t\t\t  {\n\t\t\t\t\t\t  if (d == '!')\n\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t  int e = getcFromInputFile ();\n\t\t\t\t\t\t\t  if ( e != '-' ) \t\t/* is this the start of a comment? */\n\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t  ungetcToInputFile (e);\n\t\t\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t\t\t\t  token->type = TOKEN_LESS_THAN;\n\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t  if (e == '-')\n\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t  int f = getcFromInputFile ();\n\t\t\t\t\t\t\t\t\t  if ( f != '-' ) \t\t/* is this the start of a comment? */\n\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (f);\n\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (e);\n\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t\t\t\t\t\t  token->type = TOKEN_LESS_THAN;\n\t\t\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t  if (f == '-')\n\t\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t\t  do\n\t\t\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t\t\t  skipToCharacterInInputFile ('-');\n\t\t\t\t\t\t\t\t\t\t\t\t  c = getcFromInputFile ();\n\t\t\t\t\t\t\t\t\t\t\t\t  if (c == '-')\n\t\t\t\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t\t\t\t  d = getcFromInputFile ();\n\t\t\t\t\t\t\t\t\t\t\t\t\t  if (d == '>')\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (c);\n\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (c);\n\t\t\t\t\t\t\t\t\t\t\t  } while (c != EOF && c != '\\0');\n\t\t\t\t\t\t\t\t\t\t\t  goto getNextChar;\n\t\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t  }\n\t\t\t\t\t\t  else if (d == 'm' || d == 'f' || d == 's' )\n\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t  int e = getcFromInputFile ();\n\t\t\t\t\t\t\t  if ( (d == 'm' || d == 'f') && e != 'x' ) \t\t/* continuing an mx or fx tag */\n\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t  ungetcToInputFile (e);\n\t\t\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t\t\t\t  token->type = TOKEN_LESS_THAN;\n\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t  if ( (d == 'm' || d == 'f') && e == 'x' )\n\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t  int f = getcFromInputFile ();\n\t\t\t\t\t\t\t\t\t  if ( f != ':' ) \t\t/* start of the tag */\n\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (f);\n\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (e);\n\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t\t\t\t\t\t  token->type = TOKEN_LESS_THAN;\n\t\t\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t  token->type = TOKEN_OPEN_MXML;\n\t\t\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t  if ( d == 's' && e == ':')    /* continuing a spark tag */\n\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t  token->type = TOKEN_OPEN_MXML;\n\t\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t  ungetcToInputFile (e);\n\t\t\t\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t\t\t\t\t  token->type = TOKEN_LESS_THAN;\n\t\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t  }\n\t\t\t\t\t\t  else if (d == '/')\n\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t  int e = getcFromInputFile ();\n\t\t\t\t\t\t\t  if ( !(e == 'm' || e == 'f' || e == 's' ))\n\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t  ungetcToInputFile (e);\n\t\t\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t\t\t\t  token->type = TOKEN_LESS_THAN;\n\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t  int f = getcFromInputFile ();\n\t\t\t\t\t\t\t\t  if ( (e == 'm' || e == 'f') && f != 'x' ) \t\t/* continuing an mx or fx tag */\n\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t  ungetcToInputFile (f);\n\t\t\t\t\t\t\t\t\t  ungetcToInputFile (e);\n\t\t\t\t\t\t\t\t\t  token->type = TOKEN_LESS_THAN;\n\t\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t  if (f == 'x')\n\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t  int g = getcFromInputFile ();\n\t\t\t\t\t\t\t\t\t\t  if ( g != ':' ) \t\t/* is this the start of a comment? */\n\t\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (g);\n\t\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (f);\n\t\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (e);\n\t\t\t\t\t\t\t\t\t\t\t  token->type = TOKEN_LESS_THAN;\n\t\t\t\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t\t  token->type = TOKEN_CLOSE_MXML;\n\t\t\t\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t\t  if ( e == 's' && f == ':')    /* continuing a spark tag */\n\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t  token->type = TOKEN_CLOSE_MXML;\n\t\t\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (f);\n\t\t\t\t\t\t\t\t\t\t  ungetcToInputFile (e);\n\t\t\t\t\t\t\t\t\t\t  token->type = TOKEN_LESS_THAN;\n\t\t\t\t\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t\t\t\t\t\t  break;\n\t\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t  }\n\t\t\t\t\t  }\n\t\t\t\t\t  break;\n\t\t\t\t  }\n\n\t\tcase '>':\n\t\t\t\t  token->type = TOKEN_GREATER_THAN;\n\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t  break;\n\n\t\tcase '!':\n\t\t\t\t  token->type = TOKEN_EXCLAMATION;\n\t\t\t\t  /*token->lineNumber = getInputLineNumber ();\n\t\t\t\t  token->filePosition = getInputFilePosition ();*/\n\t\t\t\t  break;\n\n\t\tdefault:\n\t\t\t\t  if (! isIdentChar (c))\n\t\t\t\t\t  token->type = TOKEN_UNDEFINED;\n\t\t\t\t  else\n\t\t\t\t  {\n\t\t\t\t\t  parseIdentifier (token->string, c);\n\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t  token->keyword = lookupCaseKeyword (vStringValue (token->string), Lang_flex);\n\t\t\t\t\t  if (isKeyword (token, KEYWORD_NONE))\n\t\t\t\t\t\t  token->type = TOKEN_IDENTIFIER;\n\t\t\t\t\t  else\n\t\t\t\t\t\t  token->type = TOKEN_KEYWORD;\n\t\t\t\t  }\n\t\t\t\t  break;\n\t}\n\n\tif (include_newlines && newline_encountered)\n\t{\n\t\t/* This isn't strictly correct per the standard, but following the\n\t\t * real rules means understanding all statements, and that's not\n\t\t * what the parser currently does.  What we do here is a guess, by\n\t\t * avoiding inserting semicolons that would make the statement on\n\t\t * the left or right obviously invalid.  Hopefully this should not\n\t\t * have false negatives (e.g. should not miss insertion of a semicolon)\n\t\t * but might have false positives (e.g. it will wrongfully emit a\n\t\t * semicolon sometimes, i.e. for the newline in \"foo\\n(bar)\").\n\t\t * This should however be mostly harmless as we only deal with\n\t\t * newlines in specific situations where we know a false positive\n\t\t * wouldn't hurt too bad. */\n\n\t\t/* these already end a statement, so no need to duplicate it */\n\t\t#define IS_STMT_SEPARATOR(t) ((t) == TOKEN_SEMICOLON    || \\\n\t\t                              (t) == TOKEN_EOF          || \\\n\t\t                              (t) == TOKEN_COMMA        || \\\n\t\t                              (t) == TOKEN_OPEN_CURLY)\n\t\t/* these cannot be the start or end of a statement */\n\t\t#define IS_BINARY_OPERATOR(t) ((t) == TOKEN_EQUAL_SIGN      || \\\n\t\t                               (t) == TOKEN_COLON           || \\\n\t\t                               (t) == TOKEN_PERIOD          || \\\n\t\t                               (t) == TOKEN_STAR            || \\\n\t\t                               (t) == TOKEN_FORWARD_SLASH   || \\\n\t\t                               (t) == TOKEN_QUESTION_MARK   || \\\n\t\t                               (t) == TOKEN_LESS_THAN       || \\\n\t\t                               (t) == TOKEN_GREATER_THAN    || \\\n\t\t                               (t) == TOKEN_BINARY_OPERATOR)\n\n\t\tif (! IS_STMT_SEPARATOR(LastTokenType) &&\n\t\t    ! IS_STMT_SEPARATOR(token->type) &&\n\t\t    ! IS_BINARY_OPERATOR(LastTokenType) &&\n\t\t    ! IS_BINARY_OPERATOR(token->type) &&\n\t\t    /* these cannot be followed by a semicolon */\n\t\t    ! (LastTokenType == TOKEN_OPEN_PAREN ||\n\t\t       LastTokenType == TOKEN_OPEN_SQUARE))\n\t\t{\n\t\t\t/* hold the token... */\n\t\t\tAssert (NextToken == NULL);\n\t\t\tNextToken = newToken ();\n\t\t\tcopyToken (NextToken, token, false);\n\n\t\t\t/* ...and emit a semicolon instead */\n\t\t\ttoken->type\t\t= TOKEN_SEMICOLON;\n\t\t\ttoken->keyword\t= KEYWORD_NONE;\n\t\t\tvStringClear (token->string);\n\t\t}\n\n\t\t#undef IS_STMT_SEPARATOR\n\t\t#undef IS_BINARY_OPERATOR\n\t}\n\n\tLastTokenType = token->type;\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\treadTokenFull (token, false);\n}\n\n/*\n *\t Token parsing functions\n */\n\nstatic void skipArgumentList (tokenInfo *const token, bool include_newlines)\n{\n\tint nest_level = 0;\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\t/* arguments? */\n\t{\n\t\tnest_level++;\n\t\twhile (nest_level > 0 && ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\tnest_level++;\n\t\t\telse if (isType (token, TOKEN_CLOSE_PAREN))\n\t\t\t\tnest_level--;\n\t\t}\n\t\treadTokenFull (token, include_newlines);\n\t}\n}\n\nstatic void skipArrayList (tokenInfo *const token, bool include_newlines)\n{\n\tint nest_level = 0;\n\n\t/*\n\t * Handle square brackets\n\t *\t var name[1]\n\t * So we must check for nested open and closing square brackets\n\t */\n\n\tif (isType (token, TOKEN_OPEN_SQUARE))\t/* arguments? */\n\t{\n\t\tnest_level++;\n\t\twhile (nest_level > 0 && ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\tnest_level++;\n\t\t\telse if (isType (token, TOKEN_CLOSE_SQUARE))\n\t\t\t\tnest_level--;\n\t\t}\n\t\treadTokenFull (token, include_newlines);\n\t}\n}\n\nstatic void addContext (tokenInfo* const parent, const tokenInfo* const child)\n{\n\tvStringJoin (parent->string, '.', child->string);\n}\n\nstatic void addToScope (tokenInfo* const token, const vString* const extra)\n{\n\tvStringJoin (token->scope, '.', extra);\n}\n\n/*\n *\t Scanning functions\n */\n\nstatic bool findCmdTerm (tokenInfo *const token, bool include_newlines,\n\t\t\t\t\t\t bool include_commas)\n{\n\t/*\n\t * Read until we find either a semicolon or closing brace.\n\t * Any nested braces will be handled within.\n\t */\n\twhile (! isType (token, TOKEN_SEMICOLON) &&\n\t\t   ! isType (token, TOKEN_CLOSE_CURLY) &&\n\t\t   ! (include_commas && isType (token, TOKEN_COMMA)) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\t/* Handle nested blocks */\n\t\tif ( isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tparseBlock (token, NULL);\n\t\t\treadTokenFull (token, include_newlines);\n\t\t}\n\t\telse if ( isType (token, TOKEN_OPEN_PAREN) )\n\t\t{\n\t\t\tskipArgumentList(token, include_newlines);\n\t\t}\n\t\telse if ( isType (token, TOKEN_OPEN_SQUARE) )\n\t\t{\n\t\t\tskipArrayList(token, include_newlines);\n\t\t}\n\t\telse\n\t\t{\n\t\t\treadTokenFull (token, include_newlines);\n\t\t}\n\t}\n\n\treturn isType (token, TOKEN_SEMICOLON);\n}\n\nstatic void parseSwitch (tokenInfo *const token)\n{\n\t/*\n\t * switch (expression) {\n\t * case value1:\n\t *\t   statement;\n\t *\t   break;\n\t * case value2:\n\t *\t   statement;\n\t *\t   break;\n\t * default : statement;\n\t * }\n\t */\n\n\treadToken (token);\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tskipArgumentList(token, false);\n\t}\n\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tparseBlock (token, NULL);\n\t}\n}\n\nstatic bool parseLoop (tokenInfo *const token)\n{\n\t/*\n\t * Handles these statements\n\t *\t   for (x=0; x<3; x++)\n\t *\t\t   document.write(\"This text is repeated three times<br>\");\n\t *\n\t *\t   for (x=0; x<3; x++)\n\t *\t   {\n\t *\t\t   document.write(\"This text is repeated three times<br>\");\n\t *\t   }\n\t *\n\t *\t   while (number<5){\n\t *\t\t   document.write(number+\"<br>\");\n\t *\t\t   number++;\n\t *\t   }\n\t *\n\t *\t   do{\n\t *\t\t   document.write(number+\"<br>\");\n\t *\t\t   number++;\n\t *\t   }\n\t *\t   while (number<5);\n\t */\n\tbool is_terminated = true;\n\n\tif (isKeyword (token, KEYWORD_for) || isKeyword (token, KEYWORD_while))\n\t{\n\t\treadToken(token);\n\n\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t{\n\t\t\tskipArgumentList(token, false);\n\t\t}\n\n\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tparseBlock (token, NULL);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tis_terminated = parseLine(token);\n\t\t}\n\t}\n\telse if (isKeyword (token, KEYWORD_do))\n\t{\n\t\treadToken(token);\n\n\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tparseBlock (token, NULL);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tis_terminated = parseLine(token);\n\t\t}\n\n\t\tif (is_terminated)\n\t\t\treadToken(token);\n\n\t\tif (isKeyword (token, KEYWORD_while))\n\t\t{\n\t\t\treadToken(token);\n\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t{\n\t\t\t\tskipArgumentList(token, true);\n\t\t\t}\n\t\t\tif (! isType (token, TOKEN_SEMICOLON))\n\t\t\t{\n\t\t\t\t/* oddly enough, `do {} while (0) var foo = 42` is perfectly\n\t\t\t\t * valid AS, so explicitly handle the remaining of the line\n\t\t\t\t * for the sake of the root scope handling (as parseActionScript()\n\t\t\t\t * always advances a token not to ever get stuck) */\n\t\t\t\tis_terminated = parseLine(token);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn is_terminated;\n}\n\nstatic bool parseIf (tokenInfo *const token)\n{\n\tbool read_next_token = true;\n\t/*\n\t * If statements have two forms\n\t *\t   if ( ... )\n\t *\t\t   one line;\n\t *\n\t *\t   if ( ... )\n\t *\t\t  statement;\n\t *\t   else\n\t *\t\t  statement\n\t *\n\t *\t   if ( ... ) {\n\t *\t\t  multiple;\n\t *\t\t  statements;\n\t *\t   }\n\t *\n\t *\n\t *\t   if ( ... ) {\n\t *\t\t  return elem\n\t *\t   }\n\t *\n\t *     This example if correctly written, but the\n\t *     else contains only 1 statement without a terminator\n\t *     since the function finishes with the closing brace.\n\t *\n     *     function a(flag){\n     *         if(flag)\n     *             test(1);\n     *         else\n     *             test(2)\n     *     }\n\t *\n\t * TODO:  Deal with statements that can optional end\n\t *\t\t  without a semi-colon.  Currently this messes up\n\t *\t\t  the parsing of blocks.\n\t *\t\t  Need to somehow detect this has happened, and either\n\t *\t\t  backup a token, or skip reading the next token if\n\t *\t\t  that is possible from all code locations.\n\t *\n\t */\n\n\treadToken (token);\n\n\tif (isKeyword (token, KEYWORD_if))\n\t{\n\t\t/*\n\t\t * Check for an \"else if\" and consume the \"if\"\n\t\t */\n\t\treadToken (token);\n\t}\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tskipArgumentList(token, false);\n\t}\n\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tparseBlock (token, NULL);\n\t}\n\telse\n\t{\n\t\t/* The next token should only be read if this statement had its own\n\t\t * terminator */\n\t\tread_next_token = findCmdTerm (token, true, false);\n\t}\n\treturn read_next_token;\n}\n\nstatic bool parseImport (tokenInfo *const token)\n{\n\tif (! isKeyword (token, KEYWORD_import))\n\t\treturn false;\n\n\treadToken (token);\n\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\ttokenInfo *const name = newToken ();\n\n\t\tcopyToken (name, token, true);\n\t\treadToken (token);\n\t\twhile (isType (token, TOKEN_PERIOD))\n\t\t{\n\t\t\tvStringPut (name->string, '.');\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\tvStringCat (name->string, token->string);\n\t\t\telse if (isType (token, TOKEN_STAR))\n\t\t\t\tvStringPut (name->string, '*');\n\t\t\tif (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_STAR))\n\t\t\t\treadToken (token);\n\t\t}\n\n\t\tmakeFlexTag (name, FLEXTAG_IMPORT);\n\t\tdeleteToken (name);\n\t}\n\n\treturn isType (token, TOKEN_SEMICOLON);\n}\n\nstatic void parseFunction (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\tflexKind kind = FLEXTAG_FUNCTION;\n\n\t/*\n\t * This deals with these formats\n     *     private static function ioErrorHandler( event:IOErrorEvent ):void {\n     *     public function get prop():String {}\n     *     public function set prop(param:String):void {}\n\t */\n\n\tif ( isKeyword(token, KEYWORD_function) )\n\t{\n\t\treadToken (token);\n\t}\n\n\t/* getter and setter */\n\tif (isKeyword (token, KEYWORD_get) ||\n\t\tisKeyword (token, KEYWORD_set))\n\t{\n\t\tkind = FLEXTAG_PROPERTY;\n\t\treadToken (token);\n\t}\n\n\tcopyToken (name, token, true);\n\t/* Add scope in case this is an INNER function\n\taddToScope(name, token->scope);\n\t*/\n\n\tDebugStatement (\n\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t, \"\\n parseFunction: token isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t, token->isClass\n\t\t\t\t, vStringValue(token->scope)\n\t\t\t\t, vStringValue(token->string)\n\t\t\t\t);\n\t\t\t);\n\tDebugStatement (\n\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t, \"\\n parseFunction: name isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t, name->isClass\n\t\t\t\t, vStringValue(name->scope)\n\t\t\t\t, vStringValue(name->string)\n\t\t\t\t);\n\t\t\t);\n\n\treadToken (token);\n\n\tif ( isType (token, TOKEN_OPEN_PAREN) )\n\t\tskipArgumentList(token, false);\n\n\tif ( isType (token, TOKEN_COLON) )\n\t{\n\t\t/*\n\t\t *   function fname ():ReturnType\n\t\t */\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\treadToken (token);\n\t}\n\n\tif ( isType (token, TOKEN_OPEN_CURLY) )\n\t{\n\t\tDebugStatement (\n\t\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t\t, \"\\n parseFunction end: name isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t\t, name->isClass\n\t\t\t\t\t, vStringValue(name->scope)\n\t\t\t\t\t, vStringValue(name->string)\n\t\t\t\t\t);\n\t\t\t\t);\n\t\tparseBlock (token, name->string);\n\t\tDebugStatement (\n\t\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t\t, \"\\n parseFunction end2: token isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t\t, token->isClass\n\t\t\t\t\t, vStringValue(token->scope)\n\t\t\t\t\t, vStringValue(token->string)\n\t\t\t\t\t);\n\t\t\t\t);\n\t\tDebugStatement (\n\t\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t\t, \"\\n parseFunction end2: token isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t\t, token->isClass\n\t\t\t\t\t, vStringValue(token->scope)\n\t\t\t\t\t, vStringValue(token->string)\n\t\t\t\t\t);\n\t\t\t\t);\n\t\tDebugStatement (\n\t\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t\t, \"\\n parseFunction end3: name isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t\t, name->isClass\n\t\t\t\t\t, vStringValue(name->scope)\n\t\t\t\t\t, vStringValue(name->string)\n\t\t\t\t\t);\n\t\t\t\t);\n\t\tif (kind == FLEXTAG_FUNCTION)\n\t\t\tmakeFunctionTag (name);\n\t\telse\n\t\t\tmakeFlexTag (name, kind);\n\t}\n\n\tfindCmdTerm (token, false, false);\n\n\tdeleteToken (name);\n}\n\n/* Parses a block surrounded by curly braces.\n * @p parentScope is the scope name for this block, or NULL for unnamed scopes */\nstatic bool parseBlock (tokenInfo *const token, const vString *const parentScope)\n{\n\tbool read_next_token = true;\n\tvString * saveScope = vStringNew ();\n\n\tvStringCopy (saveScope, token->scope);\n\tif (parentScope)\n\t{\n\t\taddToScope (token, parentScope);\n\t\ttoken->nestLevel++;\n\t}\n\n\tDebugStatement (\n\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t, \"\\n parseBlock start: token isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t, token->isClass\n\t\t\t\t, vStringValue(token->scope)\n\t\t\t\t, vStringValue(token->string)\n\t\t\t\t);\n\t\t\t);\n\t/*\n\t * Make this routine a bit more forgiving.\n\t * If called on an open_curly advance it\n\t */\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\treadToken(token);\n\n\tif (! isType (token, TOKEN_CLOSE_CURLY))\n\t{\n\t\t/*\n\t\t * Read until we find the closing brace,\n\t\t * any nested braces will be handled within\n\t\t */\n\t\tdo\n\t\t{\n\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\t/* Handle nested blocks */\n\t\t\t\tparseBlock (token, NULL);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * It is possible for a line to have no terminator\n\t\t\t\t * if the following line is a closing brace.\n\t\t\t\t * parseLine will detect this case and indicate\n\t\t\t\t * whether we should read an additional token.\n\t\t\t\t */\n\t\t\t\tread_next_token = parseLine (token);\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * Always read a new token unless we find a statement without\n\t\t\t * a ending terminator\n\t\t\t */\n\t\t\tif( read_next_token )\n\t\t\t\treadToken(token);\n\n\t\t\t/*\n\t\t\t * If we find a statement without a terminator consider the\n\t\t\t * block finished, otherwise the stack will be off by one.\n\t\t\t */\n\t\t} while (! isType (token, TOKEN_EOF) &&\n\t\t\t\t ! isType (token, TOKEN_CLOSE_CURLY) && read_next_token);\n\t}\n\n\tvStringCopy(token->scope, saveScope);\n\tvStringDelete(saveScope);\n\tif (parentScope)\n\t\ttoken->nestLevel--;\n\n\tDebugStatement (\n\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t, \"\\n parseBlock end: token isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t, token->isClass\n\t\t\t\t, vStringValue(token->scope)\n\t\t\t\t, vStringValue(token->string)\n\t\t\t\t);\n\t\t\t);\n\treturn false;\n}\n\nstatic void parseMethods (tokenInfo *const token, const tokenInfo *const class)\n{\n\ttokenInfo *const name = newToken ();\n\tvString *saveScope = vStringNew ();\n\n\tvStringCopy (saveScope, token->scope);\n\taddToScope (token, class->string);\n\n\t/*\n\t * This deals with these formats\n\t *\t   validProperty  : 2,\n\t *\t   validMethod    : function(a,b) {}\n\t *\t   'validMethod2' : function(a,b) {}\n     *     container.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false}\n\t */\n\n\tdo\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_CLOSE_CURLY))\n\t\t{\n\t\t\tgoto cleanUp;\n\t\t}\n\n\t\tif (isType (token, TOKEN_STRING) || isKeyword(token, KEYWORD_NONE))\n\t\t{\n\t\t\tcopyToken (name, token, true);\n\n\t\t\treadToken (token);\n\t\t\tif ( isType (token, TOKEN_COLON) )\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif ( isKeyword (token, KEYWORD_function) )\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif ( isType (token, TOKEN_OPEN_PAREN) )\n\t\t\t\t\t{\n\t\t\t\t\t\tskipArgumentList(token, false);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t\t\t{\n\t\t\t\t\t\tmakeFlexTag (name, FLEXTAG_METHOD);\n\t\t\t\t\t\tparseBlock (token, name->string);\n\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * Read to the closing curly, check next\n\t\t\t\t\t\t * token, if a comma, we must loop again\n\t\t\t\t\t\t */\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t\tmakeFlexTag (name, FLEXTAG_PROPERTY);\n\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * Read the next token, if a comma\n\t\t\t\t\t\t * we must loop again\n\t\t\t\t\t\t */\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} while ( isType(token, TOKEN_COMMA));\n\n\tfindCmdTerm (token, false, false);\n\ncleanUp:\n\tvStringCopy (token->scope, saveScope);\n\tvStringDelete (saveScope);\n\tdeleteToken (name);\n}\n\nstatic bool parseVar (tokenInfo *const token, bool is_public)\n{\n\ttokenInfo *const name = newToken ();\n\tbool is_terminated = true;\n\tflexKind kind = is_public ? FLEXTAG_VARIABLE : FLEXTAG_LOCALVAR;\n\n\t/*\n\t * Variables are defined as:\n\t *     private static var lastFaultMessage:Date = new Date( 0 );\n\t *     private static var webRequests:ArrayCollection = new ArrayCollection();\n\t */\n\n\tif ( isKeyword(token, KEYWORD_var) )\n\t{\n\t\treadToken(token);\n\t}\n\telse if (isKeyword(token, KEYWORD_const))\n\t{\n\t\tkind = FLEXTAG_CONST;\n\t\treadToken(token);\n\t}\n\n\t/* Variable name */\n\tcopyToken (name, token, true);\n\treadToken(token);\n\n\tif ( isType (token, TOKEN_COLON) )\n\t{\n\t\t/*\n\t\t *   var vname ():DataType = new Date();\n\t\t *   var vname ():DataType;\n\t\t */\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\treadToken (token);\n\t}\n\n\tis_terminated = findCmdTerm (token, true, false);\n\n\tif ( isType (token, TOKEN_SEMICOLON) )\n\t{\n\t\tmakeFlexTag (name, kind);\n\t}\n\n\tdeleteToken (name);\n\n\treturn is_terminated;\n}\n\nstatic void parsePackage (tokenInfo *const token)\n{\n\ttokenInfo *name = NULL;\n\n\tif (isKeyword (token, KEYWORD_package))\n\t\treadToken(token);\n\n\t/* name is optional and can be qualified */\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\tname = newToken ();\n\t\tcopyToken (name, token, true);\n\t\treadToken (token);\n\n\t\twhile (isType (token, TOKEN_PERIOD))\n\t\t{\n\t\t\tvStringPut (name->string, '.');\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t{\n\t\t\t\tvStringCat (name->string, token->string);\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tif (name)\n\t\t\tmakeFlexTag (name, FLEXTAG_PACKAGE);\n\t\tparseBlock (token, name ? name->string : NULL);\n\t}\n\n\tif (name)\n\t\tdeleteToken (name);\n}\n\nstatic bool parseClass (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\tbool saveIsClass = token->isClass;\n\n\t/*\n\t * Variables are defined as:\n\t *     private static var lastFaultMessage:Date = new Date( 0 );\n\t *     private static var webRequests:ArrayCollection = new ArrayCollection();\n\t */\n\n\tif ( isKeyword(token, KEYWORD_class) )\n\t{\n\t\treadToken(token);\n\t}\n\n\ttoken->isClass = true;\n\t/* Class name */\n\tcopyToken (name, token, true);\n\treadToken(token);\n\n\tDebugStatement (\n\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t, \"\\n parseClass start: token isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t, token->isClass\n\t\t\t\t, vStringValue(token->scope)\n\t\t\t\t, vStringValue(token->string)\n\t\t\t\t);\n\t\t\t);\n\n\tif (isKeyword (token, KEYWORD_extends))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\treadToken (token);\n\t}\n\n\tif (isKeyword (token, KEYWORD_implements))\n\t{\n\t\tdo\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\treadToken (token);\n\t\t}\n\t\twhile (isType (token, TOKEN_COMMA));\n\t}\n\n\tif ( isType (token, TOKEN_OPEN_CURLY) )\n\t{\n\t\tmakeClassTag (name);\n\t\tparseBlock (token, name->string);\n\t}\n\n\tDebugStatement (\n\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t, \"\\n parseClass end: token isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t, token->isClass\n\t\t\t\t, vStringValue(token->scope)\n\t\t\t\t, vStringValue(token->string)\n\t\t\t\t);\n\t\t\t);\n\ttoken->isClass = saveIsClass;\n\tdeleteToken (name);\n\n\treturn true;\n}\n\nstatic void parseInterface (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\tbool saveIsClass = token->isClass;\n\n\tif (isKeyword(token, KEYWORD_interface))\n\t\treadToken(token);\n\n\ttoken->isClass = true;\n\t/* interface name */\n\tcopyToken (name, token, true);\n\treadToken (token);\n\n\t/* interfaces can extend multiple interfaces */\n\tif (isKeyword (token, KEYWORD_extends))\n\t{\n\t\tdo\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\treadToken (token);\n\t\t}\n\t\twhile (isType (token, TOKEN_COMMA));\n\t}\n\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tmakeFlexTag (name, FLEXTAG_INTERFACE);\n\t\tparseBlock (token, name->string);\n\t}\n\n\ttoken->isClass = saveIsClass;\n\tdeleteToken (name);\n}\n\nstatic bool parseStatement (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\ttokenInfo *const secondary_name = newToken ();\n\tvString * saveScope = vStringNew ();\n\tbool is_public = false;\n\tbool is_class = false;\n\tbool is_terminated = true;\n\tbool is_global = false;\n\t/* bool is_prototype = false; */\n\tvString *\tfulltag;\n\n\tvStringCopy (saveScope, token->scope);\n\tDebugStatement (\n\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t, \"\\n parseStatement: token isClass:%d  scope:%s  name:%s\\n\"\n\t\t\t\t, token->isClass\n\t\t\t\t, vStringValue(token->scope)\n\t\t\t\t, vStringValue(token->string)\n\t\t\t\t);\n\t\t\t);\n\t/*\n\t * Functions can be named or unnamed.\n\t * This deals with these formats:\n\t * Function\n\t *\t   validFunctionOne = function(a,b) {}\n\t *\t   testlib.validFunctionFive = function(a,b) {}\n\t *\t   var innerThree = function(a,b) {}\n\t *\t   var innerFour = (a,b) {}\n\t *\t   var D2 = secondary_fcn_name(a,b) {}\n\t *\t   var D3 = new Function(\"a\", \"b\", \"return a+b;\");\n\t * Class\n\t *\t   testlib.extras.ValidClassOne = function(a,b) {\n\t *\t\t   this.a = a;\n\t *\t   }\n\t * Class Methods\n\t *\t   testlib.extras.ValidClassOne.prototype = {\n\t *\t\t   'validMethodOne' : function(a,b) {},\n\t *\t\t   'validMethodTwo' : function(a,b) {}\n\t *\t   }\n     *     ValidClassTwo = function ()\n     *     {\n     *         this.validMethodThree = function() {}\n     *         // unnamed method\n     *         this.validMethodFour = () {}\n     *     }\n\t *\t   Database.prototype.validMethodThree = Database_getTodaysDate;\n\t */\n\n\t/* skip attributes */\n\twhile (isKeyword (token, KEYWORD_public) ||\n\t       isKeyword (token, KEYWORD_protected) ||\n\t       isKeyword (token, KEYWORD_private) ||\n\t       isKeyword (token, KEYWORD_override) ||\n\t       isKeyword (token, KEYWORD_static) ||\n\t       isKeyword (token, KEYWORD_internal) ||\n\t       isKeyword (token, KEYWORD_native) ||\n\t       isKeyword (token, KEYWORD_dynamic) ||\n\t       isKeyword (token, KEYWORD_final))\n\t{\n\t\tif (isKeyword(token, KEYWORD_public))\n\t\t\tis_public = true;\n\n\t\treadToken (token);\n\t}\n\n\tif (isType(token, TOKEN_KEYWORD))\n\t{\n\t\tswitch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_for:\n\t\t\tcase KEYWORD_while:\n\t\t\tcase KEYWORD_do:\n\t\t\t\tis_terminated = parseLoop (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_if:\n\t\t\tcase KEYWORD_else:\n\t\t\tcase KEYWORD_try:\n\t\t\tcase KEYWORD_catch:\n\t\t\tcase KEYWORD_finally:\n\t\t\t\t/* Common semantics */\n\t\t\t\tis_terminated = parseIf (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_switch:\n\t\t\t\tparseSwitch (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_package:\n\t\t\t\tparsePackage (token);\n\t\t\t\tgoto cleanUp;\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_class:\n\t\t\t\tparseClass (token);\n\t\t\t\tgoto cleanUp;\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_interface:\n\t\t\t\tparseInterface (token);\n\t\t\t\tgoto cleanUp;\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_function:\n\t\t\t\tparseFunction (token);\n\t\t\t\tgoto cleanUp;\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_var:\n\t\t\tcase KEYWORD_const:\n\t\t\t\tis_terminated = parseVar (token, is_public);\n\t\t\t\tgoto cleanUp;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treadToken(token);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\nnextVar:\n\tcopyToken (name, token, true);\n\n\twhile (! isType (token, TOKEN_CLOSE_CURLY) &&\n\t       ! isType (token, TOKEN_SEMICOLON)   &&\n\t       ! isType (token, TOKEN_EQUAL_SIGN)  &&\n\t       ! isType (token, TOKEN_COMMA)       &&\n\t       ! isType (token, TOKEN_EOF))\n\t{\n\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\tparseBlock (token, NULL);\n\n\t\t/* Potentially the name of the function */\n\t\tif (isType (token, TOKEN_PERIOD))\n\t\t{\n\t\t\t/*\n\t\t\t * Cannot be a global variable is it has dot references in the name\n\t\t\t */\n\t\t\tis_global = false;\n\t\t\t/* Assume it's an assignment to a global name (e.g. a class) using\n\t\t\t * its fully qualified name, so strip the scope.\n\t\t\t * FIXME: resolve the scope so we can make more than an assumption. */\n\t\t\tvStringClear (token->scope);\n\t\t\tvStringClear (name->scope);\n\t\t\tdo\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (! isType(token, TOKEN_KEYWORD))\n\t\t\t\t{\n\t\t\t\t\tif ( is_class )\n\t\t\t\t\t{\n\t\t\t\t\t\taddToScope(token, name->string);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\taddContext (name, token);\n\n\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t\telse if ( isKeyword(token, KEYWORD_prototype) )\n\t\t\t\t{\n\t\t\t\t\t/*\n\t\t\t\t\t * When we reach the \"prototype\" tag, we infer:\n\t\t\t\t\t *     \"BindAgent\" is a class\n\t\t\t\t\t *     \"build\"     is a method\n\t\t\t\t\t *\n\t\t\t\t\t * function BindAgent( repeatableIdName, newParentIdName ) {\n\t\t\t\t\t * }\n\t\t\t\t\t *\n\t\t\t\t\t * CASE 1\n\t\t\t\t\t * Specified function name: \"build\"\n\t\t\t\t\t *     BindAgent.prototype.build = function( mode ) {\n\t\t\t\t\t *     \t  ignore everything within this function\n\t\t\t\t\t *     }\n\t\t\t\t\t *\n\t\t\t\t\t * CASE 2\n\t\t\t\t\t * Prototype listing\n\t\t\t\t\t *     ValidClassOne.prototype = {\n\t\t\t\t\t *         'validMethodOne' : function(a,b) {},\n\t\t\t\t\t *         'validMethodTwo' : function(a,b) {}\n\t\t\t\t\t *     }\n\t\t\t\t\t *\n\t\t\t\t\t */\n\t\t\t\t\tmakeClassTag (name);\n\t\t\t\t\tis_class = true;\n\t\t\t\t\t/* is_prototype = true; */\n\n\t\t\t\t\t/*\n\t\t\t\t\t * There should a \".function_name\" next.\n\t\t\t\t\t */\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isType (token, TOKEN_PERIOD))\n\t\t\t\t\t{\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * Handle CASE 1\n\t\t\t\t\t\t */\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tif (! isType(token, TOKEN_KEYWORD))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taddToScope(token, name->string);\n\n\t\t\t\t\t\t\tmakeFlexTag (token, FLEXTAG_METHOD);\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t * We can read until the end of the block / statement.\n\t\t\t\t\t\t\t * We need to correctly parse any nested blocks, but\n\t\t\t\t\t\t\t * we do NOT want to create any tags based on what is\n\t\t\t\t\t\t\t * within the blocks.\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\ttoken->ignoreTag = true;\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t * Find to the end of the statement\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tfindCmdTerm (token, false, false);\n\t\t\t\t\t\t\ttoken->ignoreTag = false;\n\t\t\t\t\t\t\tis_terminated = true;\n\t\t\t\t\t\t\tgoto cleanUp;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (isType (token, TOKEN_EQUAL_SIGN))\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t * Handle CASE 2\n\t\t\t\t\t\t\t *\n\t\t\t\t\t\t\t * Creates tags for each of these class methods\n\t\t\t\t\t\t\t *     ValidClassOne.prototype = {\n\t\t\t\t\t\t\t *         'validMethodOne' : function(a,b) {},\n\t\t\t\t\t\t\t *         'validMethodTwo' : function(a,b) {}\n\t\t\t\t\t\t\t *     }\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tparseMethods(token, name);\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t * Find to the end of the statement\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tfindCmdTerm (token, false, false);\n\t\t\t\t\t\t\ttoken->ignoreTag = false;\n\t\t\t\t\t\t\tis_terminated = true;\n\t\t\t\t\t\t\tgoto cleanUp;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\treadToken (token);\n\t\t\t} while (isType (token, TOKEN_PERIOD));\n\t\t}\n\t\telse\n\t\t\treadTokenFull (token, true);\n\n\t\tif ( isType (token, TOKEN_OPEN_PAREN) )\n\t\t\tskipArgumentList(token, false);\n\n\t\tif ( isType (token, TOKEN_COLON) )\n\t\t{\n\t\t\t/*\n\t\t\t * Functions are of this form:\n\t\t\t *   function fname ():ReturnType {\n\t\t\t */\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\treadToken (token);\n\t\t}\n\n\t\tif ( isType (token, TOKEN_OPEN_SQUARE) )\n\t\t\tskipArrayList(token, false);\n\t}\n\n\tif ( isType (token, TOKEN_CLOSE_CURLY) )\n\t{\n\t\t/*\n\t\t * Reaching this section without having\n\t\t * processed an open curly brace indicates\n\t\t * the statement is most likely not terminated.\n\t\t */\n\t\tis_terminated = false;\n\t\tgoto cleanUp;\n\t}\n\n\tif ( isType (token, TOKEN_SEMICOLON) ||\n\t     isType (token, TOKEN_EOF) ||\n\t     isType (token, TOKEN_COMMA) )\n\t{\n\t\t/*\n\t\t * Only create variables for global scope\n\t\t */\n\t\tif ( token->nestLevel == 0 && is_global )\n\t\t{\n\t\t\t/*\n\t\t\t * Handles this syntax:\n\t\t\t *\t   var g_var2;\n\t\t\t */\n\t\t\tmakeFlexTag (name, FLEXTAG_VARIABLE);\n\t\t}\n\t\t/*\n\t\t * Statement has ended.\n\t\t * This deals with calls to functions, like:\n\t\t *     alert(..);\n\t\t */\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tgoto nextVar;\n\t\t}\n\t\tgoto cleanUp;\n\t}\n\n\tif ( isType (token, TOKEN_EQUAL_SIGN) )\n\t{\n\t\treadToken (token);\n\n\t\tif ( isKeyword (token, KEYWORD_function) )\n\t\t{\n\t\t\treadToken (token);\n\n\t\t\tif (! isType (token, TOKEN_KEYWORD) &&\n\t\t\t\t! isType (token, TOKEN_OPEN_PAREN))\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * Functions of this format:\n\t\t\t\t *\t   var D2A = function theAdd(a, b)\n\t\t\t\t *\t   {\n\t\t\t\t *\t\t  return a+b;\n\t\t\t\t *\t   }\n\t\t\t\t * Are really two separate defined functions and\n\t\t\t\t * can be referenced in two ways:\n\t\t\t\t *\t   alert( D2A(1,2) );\t\t\t  // produces 3\n\t\t\t\t *\t   alert( theAdd(1,2) );\t\t  // also produces 3\n\t\t\t\t * So it must have two tags:\n\t\t\t\t *\t   D2A\n\t\t\t\t *\t   theAdd\n\t\t\t\t * Save the reference to the name for later use, once\n\t\t\t\t * we have established this is a valid function we will\n\t\t\t\t * create the secondary reference to it.\n\t\t\t\t */\n\t\t\t\tcopyToken (secondary_name, token, true);\n\t\t\t\treadToken (token);\n\t\t\t}\n\n\t\t\tif ( isType (token, TOKEN_OPEN_PAREN) )\n\t\t\t\tskipArgumentList(token, false);\n\n\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * This will be either a function or a class.\n\t\t\t\t * We can only determine this by checking the body\n\t\t\t\t * of the function.  If we find a \"this.\" we know\n\t\t\t\t * it is a class, otherwise it is a function.\n\t\t\t\t */\n\t\t\t\tif ( token->isClass )\n\t\t\t\t{\n\t\t\t\t\tmakeFlexTag (name, FLEXTAG_METHOD);\n\t\t\t\t\tif ( vStringLength(secondary_name->string) > 0 )\n\t\t\t\t\t\tmakeFunctionTag (secondary_name);\n\t\t\t\t\tparseBlock (token, name->string);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tparseBlock (token, name->string);\n\t\t\t\t\tmakeFunctionTag (name);\n\n\t\t\t\t\tif ( vStringLength(secondary_name->string) > 0 )\n\t\t\t\t\t\tmakeFunctionTag (secondary_name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_PAREN))\n\t\t{\n\t\t\t/*\n\t\t\t * Handle nameless functions\n\t\t\t *     this.method_name = () {}\n\t\t\t */\n\t\t\tskipArgumentList(token, false);\n\n\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * Nameless functions are only setup as methods.\n\t\t\t\t */\n\t\t\t\tmakeFlexTag (name, FLEXTAG_METHOD);\n\t\t\t\tparseBlock (token, name->string);\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\t/*\n\t\t\t * Creates tags for each of these class methods\n\t\t\t *     ValidClassOne.prototype = {\n\t\t\t *         'validMethodOne' : function(a,b) {},\n\t\t\t *         'validMethodTwo' : function(a,b) {}\n\t\t\t *     }\n\t\t\t */\n\t\t\tparseMethods(token, name);\n\t\t\t/* Here we should be at the end of the block, on the close curly.\n\t\t\t * If so, read the next token not to confuse that close curly with\n\t\t\t * the end of the current statement. */\n\t\t\tif (isType (token, TOKEN_CLOSE_CURLY))\n\t\t\t{\n\t\t\t\treadTokenFull(token, true);\n\t\t\t\tis_terminated = isType (token, TOKEN_SEMICOLON);\n\t\t\t}\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_new))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif ( isKeyword (token, KEYWORD_function) ||\n\t\t\t\t\tisKeyword (token, KEYWORD_capital_function) ||\n\t\t\t\t\tisKeyword (token, KEYWORD_object) ||\n\t\t\t\t\tisKeyword (token, KEYWORD_capital_object) )\n\t\t\t{\n\t\t\t\tif ( isKeyword (token, KEYWORD_object) ||\n\t\t\t\t\t\tisKeyword (token, KEYWORD_capital_object) )\n\t\t\t\t\tis_class = true;\n\n\t\t\t\treadToken (token);\n\t\t\t\tif ( isType (token, TOKEN_OPEN_PAREN) )\n\t\t\t\t\tskipArgumentList(token, true);\n\n\t\t\t\tif (isType (token, TOKEN_SEMICOLON))\n\t\t\t\t{\n\t\t\t\t\tif ( token->nestLevel == 0 )\n\t\t\t\t\t{\n\t\t\t\t\t\tif ( is_class )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmakeClassTag (name);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tmakeFunctionTag (name);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (isType (token, TOKEN_CLOSE_CURLY))\n\t\t\t\t\tis_terminated = false;\n\t\t\t}\n\t\t}\n\t\telse if (! isType (token, TOKEN_KEYWORD))\n\t\t{\n\t\t\t/*\n\t\t\t * Only create variables for global scope\n\t\t\t */\n\t\t\tif ( token->nestLevel == 0 && is_global )\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * A pointer can be created to the function.\n\t\t\t\t * If we recognize the function/class name ignore the variable.\n\t\t\t\t * This format looks identical to a variable definition.\n\t\t\t\t * A variable defined outside of a block is considered\n\t\t\t\t * a global variable:\n\t\t\t\t *\t   var g_var1 = 1;\n\t\t\t\t *\t   var g_var2;\n\t\t\t\t * This is not a global variable:\n\t\t\t\t *\t   var g_var = function;\n\t\t\t\t * This is a global variable:\n\t\t\t\t *\t   var g_var = different_var_name;\n\t\t\t\t */\n\t\t\t\tfulltag = vStringNew ();\n\t\t\t\tif (vStringLength (token->scope) > 0)\n\t\t\t\t{\n\t\t\t\t\tvStringCopy(fulltag, token->scope);\n\t\t\t\t\tvStringPut (fulltag, '.');\n\t\t\t\t\tvStringCat (fulltag, token->string);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvStringCopy(fulltag, token->string);\n\t\t\t\t}\n\t\t\t\tif ( ! stringListHas(FunctionNames, vStringValue (fulltag)) &&\n\t\t\t\t\t\t! stringListHas(ClassNames, vStringValue (fulltag)) )\n\t\t\t\t{\n\t\t\t\t\tmakeFlexTag (name, FLEXTAG_VARIABLE);\n\t\t\t\t}\n\t\t\t\tvStringDelete (fulltag);\n\t\t\t}\n\t\t}\n\t}\n\t/* if we aren't already at the cmd end, advance to it and check whether\n\t * the statement was terminated */\n\tif (! isType (token, TOKEN_CLOSE_CURLY) &&\n\t    ! isType (token, TOKEN_SEMICOLON))\n\t{\n\t\t/*\n\t\t * Statements can be optionally terminated in the case of\n\t\t * statement prior to a close curly brace as in the\n\t\t * document.write line below:\n\t\t *\n\t\t * function checkForUpdate() {\n\t\t *\t   if( 1==1 ) {\n\t\t *\t\t   document.write(\"hello from checkForUpdate<br>\")\n\t\t *\t   }\n\t\t *\t   return 1;\n\t\t * }\n\t\t */\n\t\tis_terminated = findCmdTerm (token, true, true);\n\t\t/* if we're at a comma, try and read a second var */\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tgoto nextVar;\n\t\t}\n\t}\n\ncleanUp:\n\tvStringCopy(token->scope, saveScope);\n\tdeleteToken (name);\n\tdeleteToken (secondary_name);\n\tvStringDelete(saveScope);\n\n\treturn is_terminated;\n}\n\nstatic bool parseLine (tokenInfo *const token)\n{\n\tbool is_terminated = true;\n\t/*\n\t * Detect the common statements, if, while, for, do, ...\n\t * This is necessary since the last statement within a block \"{}\"\n\t * can be optionally terminated.\n\t *\n\t * If the statement is not terminated, we need to tell\n\t * the calling routine to prevent reading an additional token\n\t * looking for the end of the statement.\n\t */\n\n\tif (isType(token, TOKEN_KEYWORD))\n\t{\n\t\tswitch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_for:\n\t\t\tcase KEYWORD_while:\n\t\t\tcase KEYWORD_do:\n\t\t\t\tis_terminated = parseLoop (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_if:\n\t\t\tcase KEYWORD_else:\n\t\t\tcase KEYWORD_try:\n\t\t\tcase KEYWORD_catch:\n\t\t\tcase KEYWORD_finally:\n\t\t\t\t/* Common semantics */\n\t\t\t\tis_terminated = parseIf (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_switch:\n\t\t\t\tparseSwitch (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_return:\n\t\t\t\treadToken (token);\n\t\t\t\tis_terminated = parseLine (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_function:\n\t\t\t\tparseFunction (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_import:\n\t\t\t\tis_terminated = parseImport (token);\n\t\t\t\t/* to properly support unterminated imports at top level,\n\t\t\t\t * recurse here because parseActionScript() will *always*\n\t\t\t\t * advance to avoid ever getting stuck. */\n\t\t\t\tif (! is_terminated)\n\t\t\t\t\treturn parseLine (token);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tis_terminated = parseStatement (token);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\telse\n\t{\n\t\t/*\n\t\t * Special case where single line statements may not be\n\t\t * SEMICOLON terminated.  parseBlock needs to know this\n\t\t * so that it does not read the next token.\n\t\t */\n\t\tis_terminated = parseStatement (token);\n\t}\n\treturn is_terminated;\n}\n\nstatic bool parseCDATA (tokenInfo *const token)\n{\n\tif (isType (token, TOKEN_LESS_THAN))\n\t{\n\t\t/*\n\t\t * Handle these tags\n\t\t * <![CDATA[\n\t\t *    ...\n\t\t * ]]>\n\t\t */\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_EXCLAMATION))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (isKeyword (token, KEYWORD_cdata))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t{\n\t\t\t\t\t\tparseActionScript (token, true);\n\t\t\t\t\t\tif (isType (token, TOKEN_CLOSE_SQUARE))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t\tif (isType (token, TOKEN_CLOSE_SQUARE))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tparseActionScript (token, false);\n\t}\n\treturn true;\n}\n\nstatic bool parseNamespace (tokenInfo *const token)\n{\n\t/*\n\t * If we have found a <, we know it is not a TOKEN_OPEN_MXML\n\t * but it could potentially be a different namespace.\n\t * This means it will also have a closing tag, which will\n\t * mess up the parser if we do not properly recurse\n\t * through these tags.\n\t */\n\n\tif (isType (token, TOKEN_LESS_THAN))\n\t{\n\t\treadToken (token);\n\t}\n\n\t/*\n\t * Check if we have reached a other namespace tag\n\t *   <views:Object ... />\n\t * or\n\t *   <views:Object ... >\n\t *   </views:Object>\n\t */\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_COLON))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif ( ! isType (token, TOKEN_IDENTIFIER))\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\telse\n\t{\n\t\treturn true;\n\t}\n\n\t/*\n\t * Confirmed we are inside a namespace tag, so\n\t * process it until the close tag.\n\t *\n\t * But also check for new tags, which will either\n\t * be recursive namespaces or MXML tags\n\t */\n\tdo\n\t{\n\t\tif (isType (token, TOKEN_LESS_THAN))\n\t\t{\n\t\t\tparseNamespace (token);\n\t\t\treadToken (token);\n\t\t}\n\t\tif (isType (token, TOKEN_OPEN_MXML))\n\t\t{\n\t\t\tparseMXML (token);\n\t\t}\n\t\telse\n\t\t{\n\t\t\treadToken (token);\n\t\t}\n\t} while (! (isType (token, TOKEN_CLOSE_SGML) ||\n\t\t    isType (token, TOKEN_CLOSE_MXML) ||\n\t\t    isEOF (token)) );\n\treturn true;\n}\n\nstatic bool parseMXML (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\ttokenInfo *const type = newToken ();\n\tbool inside_attributes = true;\n\t/*\n\t * Detect the common statements, if, while, for, do, ...\n\t * This is necessary since the last statement within a block \"{}\"\n\t * can be optionally terminated.\n\t *\n\t * If the statement is not terminated, we need to tell\n\t * the calling routine to prevent reading an additional token\n\t * looking for the end of the statement.\n\t */\n\n\treadToken (token);\n\n\tif (isKeyword (token, KEYWORD_script))\n\t{\n\t\t/*\n\t\t * These tags can be of this form:\n\t\t * <mx:Script src=\"filename.as\" />\n\t\t */\n\t\tdo\n\t\t{\n\t\t\treadToken (token);\n\t\t} while (! (isType (token, TOKEN_CLOSE_SGML)   ||\n\t\t\t    isType (token, TOKEN_CLOSE_MXML)   ||\n\t\t\t    isType (token, TOKEN_GREATER_THAN) ||\n\t\t\t    isEOF (token)) );\n\n\t\tif (isType (token, TOKEN_CLOSE_MXML))\n\t\t{\n\t\t\t/*\n\t\t\t * We have found a </mx:type> tag\n\t\t\t * Finish reading the \"type\" and \">\"\n\t\t\t */\n\t\t\treadToken (token);\n\t\t\treadToken (token);\n\t\t\tgoto cleanUp;\n\t\t}\n\t\tif (isType (token, TOKEN_CLOSE_SGML))\n\t\t{\n\t\t\t/*\n\t\t\t * We have found a <mx:Script src=\"filename.as\" />\n\t\t\t */\n\t\t\tgoto cleanUp;\n\t\t}\n\n\t\t/*\n\t\t * This is a beginning of an embedded script.\n\t\t * These typically are of this format:\n\t\t *    <mx:Script>\n\t\t *        <![CDATA[\n\t\t *        ... ActionScript ...\n\t\t *        ]]>\n\t\t *    </mx:Script>\n\t\t */\n\t\treadToken (token);\n\t\tparseCDATA (token);\n\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_CLOSE_MXML))\n\t\t{\n\t\t\t/*\n\t\t\t * We have found a </mx:type> tag\n\t\t\t * Finish reading the \"type\" and \">\"\n\t\t\t */\n\t\t\treadToken (token);\n\t\t\treadToken (token);\n\t\t}\n\t\tgoto cleanUp;\n\t}\n\n\tcopyToken (type, token, true);\n\n\treadToken (token);\n\tdo\n\t{\n\t\tif (isType (token, TOKEN_GREATER_THAN))\n\t\t{\n\t\t\tinside_attributes = false;\n\t\t}\n\t\tif (isType (token, TOKEN_LESS_THAN))\n\t\t{\n\t\t\tparseNamespace (token);\n\t\t\treadToken (token);\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_MXML))\n\t\t{\n\t\t\tparseMXML (token);\n\t\t\treadToken (token);\n\t\t}\n\t\telse if (inside_attributes && (isKeyword (token, KEYWORD_id) || isKeyword (token, KEYWORD_name)))\n\t\t{\n\t\t\tif (vStringLength(name->string) == 0 )\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * If we have already created the tag based on either \"name\"\n\t\t\t\t * or \"id\" do not do it again.\n\t\t\t\t */\n\t\t\t\treadToken (token);\n\t\t\t\treadToken (token);\n\n\t\t\t\tcopyToken (name, token, true);\n\t\t\t\taddToScope (name, type->string);\n\t\t\t\tmakeMXTag (name);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\treadToken (token);\n\t\t}\n\t} while (! (isType (token, TOKEN_CLOSE_SGML) ||\n\t\t    isType (token, TOKEN_CLOSE_MXML) ||\n\t\t    isEOF (token)) );\n\n\tif (isType (token, TOKEN_CLOSE_MXML))\n\t{\n\t\t/*\n\t\t * We have found a </mx:type> tag\n\t\t * Finish reading the \"type\" and \">\"\n\t\t */\n\t\treadToken (token);\n\t\treadToken (token);\n\t}\n\ncleanUp:\n\tdeleteToken (name);\n\tdeleteToken (type);\n\treturn true;\n}\n\nstatic bool parseActionScript (tokenInfo *const token, bool readNext)\n{\n\tLastTokenType = TOKEN_UNDEFINED;\n\n\tdo\n\t{\n\t\tif (! readNext)\n\t\t\treadNext = true;\n\t\telse\n\t\t\treadToken (token);\n\n\t\tif (isType (token, TOKEN_LESS_THAN))\n\t\t{\n\t\t\t/*\n\t\t\t * Handle these tags\n\t\t\t * <![CDATA[\n\t\t\t *    ...\n\t\t\t * ]]>\n\t\t\t */\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_EQUAL_SIGN))\n\t\t\t{\n\t\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isKeyword (token, KEYWORD_cdata))\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isType (token, TOKEN_CLOSE_SQUARE))\n\t\t{\n\t\t\t/*\n\t\t\t * Handle these tags\n\t\t\t * <![CDATA[\n\t\t\t *    ...\n\t\t\t * ]]>\n\t\t\t */\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_CLOSE_SQUARE))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (isType (token, TOKEN_GREATER_THAN))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_CLOSE_MXML))\n\t\t{\n\t\t\t/*\n\t\t\t * Read the Script> tags\n\t\t\t */\n\t\t\treadToken (token);\n\t\t\treadToken (token);\n\t\t\treturn true;\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_MXML))\n\t\t{\n\t\t\tparseMXML (token);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tparseLine (token);\n\t\t}\n\t} while (!isEOF (token));\n\treturn true;\n}\n\nstatic void parseFlexFile (tokenInfo *const token)\n{\n\tdo\n\t{\n\t\treadToken (token);\n\n\t\tif (isType (token, TOKEN_OPEN_MXML))\n\t\t{\n\t\t\tparseMXML (token);\n\t\t}\n\t\telse if (isType (token, TOKEN_LESS_THAN))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_QUESTION_MARK))\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * <?xml version=\"1.0\" encoding=\"utf-8\"?>\n\t\t\t\t */\n\t\t\t\treadToken (token);\n\t\t\t\twhile (! (isType (token, TOKEN_QUESTION_MARK) || isEOF (token)))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\telse if (isKeyword (token, KEYWORD_NONE))\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * This is a simple XML tag, read until the closing statement\n\t\t\t\t * <something .... >\n\t\t\t\t * </something>\n\t\t\t\t */\n\t\t\t\treadToken (token);\n\t\t\t\twhile (! (isType (token, TOKEN_GREATER_THAN) || isEOF (token)))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tparseActionScript (token, false);\n\t\t}\n\t} while (!isEOF (token));\n}\n\nstatic void initialize (const langType language)\n{\n\tAssert (ARRAY_SIZE (FlexKinds) == FLEXTAG_COUNT);\n\tLang_flex = language;\n}\n\nstatic void findFlexTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\tNextToken = NULL;\n\tClassNames = stringListNew ();\n\tFunctionNames = stringListNew ();\n\n\tparseFlexFile (token);\n\n\tstringListDelete (ClassNames);\n\tstringListDelete (FunctionNames);\n\tClassNames = NULL;\n\tFunctionNames = NULL;\n\tdeleteToken (token);\n}\n\n/* Create parser definition structure */\nextern parserDefinition* FlexParser (void)\n{\n\tstatic const char *const extensions [] = { \"as\", \"mxml\", NULL };\n\tparserDefinition *const def = parserNew (\"Flex\");\n\tdef->extensions = extensions;\n\t/*\n\t * New definitions for parsing instead of regex\n\t */\n\tdef->kindTable\t= FlexKinds;\n\tdef->kindCount\t= ARRAY_SIZE (FlexKinds);\n\tdef->parser\t\t= findFlexTags;\n\tdef->initialize = initialize;\n\tdef->keywordTable = FlexKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (FlexKeywordTable);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/fortran.c",
    "content": "/*\n*   Copyright (c) 1998-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Fortran language\n*   files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <limits.h>\n#include <ctype.h>  /* to define tolower () */\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n\n/*\n*   MACROS\n*/\n#define isident(c)              (isalnum(c) || (c) == '_' || (c) == '$')\n#define isBlank(c)              (bool) (c == ' ' || c == '\\t')\n#define isType(token,t)         (bool) ((token)->type == (t))\n#define isKeyword(token,k)      (bool) ((token)->keyword == (k))\n#define isSecondaryKeyword(token,k)  (bool) ((token)->secondary == NULL ? \\\n\tfalse : (token)->secondary->keyword == (k))\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef enum eFortranPass {\n\tINIT_PASS = 1,\n\tPASS_FIXED_FORM = INIT_PASS,\n\tPASS_FREE_FORM,\n\tMAX_PASS = PASS_FREE_FORM\n} fortranPass;\n\n/*  Used to designate type of line read in fixed source form.\n */\ntypedef enum eFortranLineType {\n\tLTYPE_UNDETERMINED,\n\tLTYPE_INVALID,\n\tLTYPE_COMMENT,\n\tLTYPE_CONTINUATION,\n\tLTYPE_EOF,\n\tLTYPE_INITIAL,\n\tLTYPE_SHORT\n} lineType;\n\n/*  Used to specify type of keyword.\n */\nenum eKeywordId {\n\tKEYWORD_abstract,\n\tKEYWORD_allocatable,\n\tKEYWORD_assignment,\n\tKEYWORD_associate,\n\tKEYWORD_automatic,\n\tKEYWORD_bind,\n\tKEYWORD_block,\n\tKEYWORD_byte,\n\tKEYWORD_cexternal,\n\tKEYWORD_cglobal,\n\tKEYWORD_class,\n\tKEYWORD_character,\n\tKEYWORD_codimension,\n\tKEYWORD_common,\n\tKEYWORD_complex,\n\tKEYWORD_contains,\n\tKEYWORD_data,\n\tKEYWORD_deferred,\n\tKEYWORD_dimension,\n\tKEYWORD_dllexport,\n\tKEYWORD_dllimport,\n\tKEYWORD_do,\n\tKEYWORD_double,\n\tKEYWORD_elemental,\n\tKEYWORD_end,\n\tKEYWORD_entry,\n\tKEYWORD_enum,\n\tKEYWORD_enumerator,\n\tKEYWORD_equivalence,\n\tKEYWORD_extends,\n\tKEYWORD_external,\n\tKEYWORD_final,\n\tKEYWORD_forall,\n\tKEYWORD_format,\n\tKEYWORD_function,\n\tKEYWORD_generic,\n\tKEYWORD_if,\n\tKEYWORD_implicit,\n\tKEYWORD_import,\n\tKEYWORD_include,\n\tKEYWORD_inline,\n\tKEYWORD_integer,\n\tKEYWORD_intent,\n\tKEYWORD_interface,\n\tKEYWORD_intrinsic,\n\tKEYWORD_kind,\n\tKEYWORD_len,\n\tKEYWORD_logical,\n\tKEYWORD_map,\n\tKEYWORD_module,\n\tKEYWORD_namelist,\n\tKEYWORD_non_overridable,\n\tKEYWORD_nopass,\n\tKEYWORD_operator,\n\tKEYWORD_optional,\n\tKEYWORD_parameter,\n\tKEYWORD_pascal,\n\tKEYWORD_pass,\n\tKEYWORD_pexternal,\n\tKEYWORD_pglobal,\n\tKEYWORD_pointer,\n\tKEYWORD_precision,\n\tKEYWORD_private,\n\tKEYWORD_procedure,\n\tKEYWORD_program,\n\tKEYWORD_protected,\n\tKEYWORD_public,\n\tKEYWORD_pure,\n\tKEYWORD_real,\n\tKEYWORD_record,\n\tKEYWORD_recursive,\n\tKEYWORD_save,\n\tKEYWORD_select,\n\tKEYWORD_sequence,\n\tKEYWORD_static,\n\tKEYWORD_stdcall,\n\tKEYWORD_structure,\n\tKEYWORD_submodule,\n\tKEYWORD_subroutine,\n\tKEYWORD_target,\n\tKEYWORD_then,\n\tKEYWORD_type,\n\tKEYWORD_union,\n\tKEYWORD_use,\n\tKEYWORD_value,\n\tKEYWORD_virtual,\n\tKEYWORD_volatile,\n\tKEYWORD_where,\n\tKEYWORD_while\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum eTokenType {\n\tTOKEN_UNDEFINED,\n\tTOKEN_EOF,\n\tTOKEN_COMMA,\n\tTOKEN_DOUBLE_COLON,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_KEYWORD,\n\tTOKEN_LABEL,\n\tTOKEN_NUMERIC,\n\tTOKEN_OPERATOR,\n\tTOKEN_PAREN_CLOSE,\n\tTOKEN_PAREN_OPEN,\n\tTOKEN_SQUARE_OPEN,\n\tTOKEN_SQUARE_CLOSE,\n\tTOKEN_PERCENT,\n\tTOKEN_STATEMENT_END,\n\tTOKEN_STRING,\n\tTOKEN_COLON,\n} tokenType;\n\ntypedef enum eTagType {\n\tTAG_UNDEFINED = -1,\n\tTAG_BLOCK_DATA,\n\tTAG_COMMON_BLOCK,\n\tTAG_ENTRY_POINT,\n\tTAG_ENUM,\n\tTAG_FUNCTION,\n\tTAG_INTERFACE,\n\tTAG_COMPONENT,\n\tTAG_LABEL,\n\tTAG_LOCAL,\n\tTAG_MODULE,\n\tTAG_METHOD,\n\tTAG_NAMELIST,\n\tTAG_ENUMERATOR,\n\tTAG_PROGRAM,\n\tTAG_PROTOTYPE,\n\tTAG_SUBROUTINE,\n\tTAG_DERIVED_TYPE,\n\tTAG_VARIABLE,\n\tTAG_SUBMODULE,\n\tTAG_COUNT  /* must be last */\n} tagType;\n\ntypedef enum eImplementation {\n\tIMP_DEFAULT,\n\tIMP_ABSTRACT,\n\tIMP_DEFERRED,\n\tIMP_NON_OVERRIDABLE,\n\tIMP_COUNT\n} impType;\n\ntypedef struct sTokenInfo {\n\ttokenType type;\n\tkeywordId keyword;\n\ttagType tag;\n\tvString* string;\n\tvString* parentType;\n\tvString* signature;\n\timpType implementation;\n\tbool isMethod;\n\tstruct sTokenInfo *secondary;\n\tunsigned long lineNumber;\n\tMIOPos filePosition;\n\tbool anonymous;\n} tokenInfo;\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic langType Lang_fortran;\nstatic int Ungetc;\n\nstatic fortranPass currentPass;\n#define inFreeSourceForm  ((currentPass) == PASS_FREE_FORM)\n#define inFixedSourceForm ((currentPass) == PASS_FIXED_FORM)\n\n/* State used only in FixedSourceForm pass */\nstatic struct {\n\tunsigned int column;\n\tbool freeSourceFormFound;\n} Fixed;\n\n/* State used only in FreeSourceForm pass */\nstatic struct {\n\tbool newline;\n} Free;\n\n/* indexed by tagType */\nstatic kindDefinition FortranKinds [] = {\n\t{ true,  'b', \"blockData\",  \"block data\"},\n\t{ true,  'c', \"common\",     \"common blocks\"},\n\t{ true,  'e', \"entry\",      \"entry points\"},\n\t{ true,  'E', \"enum\",       \"enumerations\"},\n\t{ true,  'f', \"function\",   \"functions\"},\n\t{ true,  'i', \"interface\",  \"interface contents, generic names, and operators\"},\n\t{ true,  'k', \"component\",  \"type and structure components\"},\n\t{ true,  'l', \"label\",      \"labels\"},\n\t{ false, 'L', \"local\",      \"local, common block, and namelist variables\"},\n\t{ true,  'm', \"module\",     \"modules\"},\n\t{ true,  'M', \"method\",     \"type bound procedures\"},\n\t{ true,  'n', \"namelist\",   \"namelists\"},\n\t{ true,  'N', \"enumerator\", \"enumeration values\"},\n\t{ true,  'p', \"program\",    \"programs\"},\n\t{ false, 'P', \"prototype\",  \"subprogram prototypes\"},\n\t{ true,  's', \"subroutine\", \"subroutines\"},\n\t{ true,  't', \"type\",       \"derived types and structures\"},\n\t{ true,  'v', \"variable\",   \"program (global) and module variables\"},\n\t{ true,  'S', \"submodule\",  \"submodules\"},\n};\n\n/* For definitions of Fortran 77 with extensions:\n * http://www.fortran.com/fortran/F77_std/rjcnf0001.html\n * http://scienide.uwaterloo.ca/MIPSpro7/007-2362-004/sgi_html/index.html\n *\n * For the Compaq Fortran Reference Manual:\n * http://h18009.www1.hp.com/fortran/docs/lrm/dflrm.htm\n */\n\nstatic const keywordTable FortranKeywordTable [] = {\n\t/* keyword          keyword ID */\n\t{ \"abstract\",       KEYWORD_abstract     },\n\t{ \"allocatable\",    KEYWORD_allocatable  },\n\t{ \"assignment\",     KEYWORD_assignment   },\n\t{ \"associate\",      KEYWORD_associate    },\n\t{ \"automatic\",      KEYWORD_automatic    },\n\t{ \"bind\",           KEYWORD_bind         },\n\t{ \"block\",          KEYWORD_block        },\n\t{ \"byte\",           KEYWORD_byte         },\n\t{ \"cexternal\",      KEYWORD_cexternal    },\n\t{ \"cglobal\",        KEYWORD_cglobal      },\n\t{ \"class\",          KEYWORD_class        },\n\t{ \"character\",      KEYWORD_character    },\n\t{ \"codimension\",    KEYWORD_codimension  },\n\t{ \"common\",         KEYWORD_common       },\n\t{ \"complex\",        KEYWORD_complex      },\n\t{ \"contains\",       KEYWORD_contains     },\n\t{ \"data\",           KEYWORD_data         },\n\t{ \"deferred\",       KEYWORD_deferred     },\n\t{ \"dimension\",      KEYWORD_dimension    },\n\t{ \"dll_export\",     KEYWORD_dllexport    },\n\t{ \"dll_import\",     KEYWORD_dllimport    },\n\t{ \"do\",             KEYWORD_do           },\n\t{ \"double\",         KEYWORD_double       },\n\t{ \"elemental\",      KEYWORD_elemental    },\n\t{ \"end\",            KEYWORD_end          },\n\t{ \"entry\",          KEYWORD_entry        },\n\t{ \"enum\",           KEYWORD_enum         },\n\t{ \"enumerator\",     KEYWORD_enumerator   },\n\t{ \"equivalence\",    KEYWORD_equivalence  },\n\t{ \"extends\",        KEYWORD_extends      },\n\t{ \"external\",       KEYWORD_external     },\n\t{ \"final\",          KEYWORD_final        },\n\t{ \"forall\",         KEYWORD_forall       },\n\t{ \"format\",         KEYWORD_format       },\n\t{ \"function\",       KEYWORD_function     },\n\t{ \"generic\",        KEYWORD_generic      },\n\t{ \"if\",             KEYWORD_if           },\n\t{ \"implicit\",       KEYWORD_implicit     },\n\t{ \"import\",         KEYWORD_import       },\n\t{ \"include\",        KEYWORD_include      },\n\t{ \"inline\",         KEYWORD_inline       },\n\t{ \"integer\",        KEYWORD_integer      },\n\t{ \"intent\",         KEYWORD_intent       },\n\t{ \"interface\",      KEYWORD_interface    },\n\t{ \"intrinsic\",      KEYWORD_intrinsic    },\n\t{ \"kind\",           KEYWORD_kind         },\n\t{ \"len\",            KEYWORD_len          },\n\t{ \"logical\",        KEYWORD_logical      },\n\t{ \"map\",            KEYWORD_map          },\n\t{ \"module\",         KEYWORD_module       },\n\t{ \"namelist\",       KEYWORD_namelist     },\n\t{ \"non_overridable\", KEYWORD_non_overridable },\n\t{ \"nopass\",         KEYWORD_nopass       },\n\t{ \"operator\",       KEYWORD_operator     },\n\t{ \"optional\",       KEYWORD_optional     },\n\t{ \"parameter\",      KEYWORD_parameter    },\n\t{ \"pascal\",         KEYWORD_pascal       },\n\t{ \"pass\",           KEYWORD_pass         },\n\t{ \"pexternal\",      KEYWORD_pexternal    },\n\t{ \"pglobal\",        KEYWORD_pglobal      },\n\t{ \"pointer\",        KEYWORD_pointer      },\n\t{ \"precision\",      KEYWORD_precision    },\n\t{ \"private\",        KEYWORD_private      },\n\t{ \"procedure\",      KEYWORD_procedure    },\n\t{ \"program\",        KEYWORD_program      },\n\t{ \"protected\",      KEYWORD_protected    },\n\t{ \"public\",         KEYWORD_public       },\n\t{ \"pure\",           KEYWORD_pure         },\n\t{ \"real\",           KEYWORD_real         },\n\t{ \"record\",         KEYWORD_record       },\n\t{ \"recursive\",      KEYWORD_recursive    },\n\t{ \"save\",           KEYWORD_save         },\n\t{ \"select\",         KEYWORD_select       },\n\t{ \"sequence\",       KEYWORD_sequence     },\n\t{ \"static\",         KEYWORD_static       },\n\t{ \"stdcall\",        KEYWORD_stdcall      },\n\t{ \"structure\",      KEYWORD_structure    },\n\t{ \"submodule\",      KEYWORD_submodule   },\n\t{ \"subroutine\",     KEYWORD_subroutine   },\n\t{ \"target\",         KEYWORD_target       },\n\t{ \"then\",           KEYWORD_then         },\n\t{ \"type\",           KEYWORD_type         },\n\t{ \"union\",          KEYWORD_union        },\n\t{ \"use\",            KEYWORD_use          },\n\t{ \"value\",          KEYWORD_value        },\n\t{ \"virtual\",        KEYWORD_virtual      },\n\t{ \"volatile\",       KEYWORD_volatile     },\n\t{ \"where\",          KEYWORD_where        },\n\t{ \"while\",          KEYWORD_while        }\n};\n\ntypedef enum {\n\tX_LINK_NAME,\n} fortranXtag;\n\nstatic xtagDefinition FortranXtagTable [] = {\n\t{\n\t\t.enabled = false,\n\t\t.name    = \"linkName\",\n\t\t.description = \"Linking name used in foreign languages\",\n\t\t.version = 1\n\t},\n};\n\nstatic struct {\n\tunsigned int count;\n\tunsigned int max;\n\ttokenInfo* list;\n} Ancestors = { 0, 0, NULL };\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nstatic void parseStructureStmt (tokenInfo *const token);\nstatic void parseUnionStmt (tokenInfo *const token);\nstatic void parseDerivedTypeDef (tokenInfo *const token);\nstatic void parseSubprogram (tokenInfo *const token);\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void ancestorPush (tokenInfo *const token)\n{\n\tenum { incrementalIncrease = 10 };\n\tif (Ancestors.list == NULL)\n\t{\n\t\tAssert (Ancestors.max == 0);\n\t\tAncestors.count = 0;\n\t\tAncestors.max   = incrementalIncrease;\n\t\tAncestors.list  = xMalloc (Ancestors.max, tokenInfo);\n\t}\n\telse if (Ancestors.count == Ancestors.max)\n\t{\n\t\tAncestors.max += incrementalIncrease;\n\t\tAncestors.list = xRealloc (Ancestors.list, Ancestors.max, tokenInfo);\n\t}\n\tAncestors.list [Ancestors.count] = *token;\n\tAncestors.list [Ancestors.count].string = vStringNewCopy (token->string);\n\tAncestors.list [Ancestors.count].signature = token->signature? vStringNewCopy (token->signature): NULL;\n\tAncestors.count++;\n}\n\nstatic void ancestorPop (void)\n{\n\tAssert (Ancestors.count > 0);\n\t--Ancestors.count;\n\tvStringDelete (Ancestors.list [Ancestors.count].string);\n\tvStringDelete (Ancestors.list [Ancestors.count].signature);\n\n\tAncestors.list [Ancestors.count].type       = TOKEN_UNDEFINED;\n\tAncestors.list [Ancestors.count].keyword    = KEYWORD_NONE;\n\tAncestors.list [Ancestors.count].secondary  = NULL;\n\tAncestors.list [Ancestors.count].tag        = TAG_UNDEFINED;\n\tAncestors.list [Ancestors.count].string     = NULL;\n\tAncestors.list [Ancestors.count].lineNumber = 0L;\n\tAncestors.list [Ancestors.count].implementation = IMP_DEFAULT;\n\tAncestors.list [Ancestors.count].isMethod   = false;\n}\n\nstatic const tokenInfo* ancestorScope (void)\n{\n\ttokenInfo *result = NULL;\n\tunsigned int i;\n\tfor (i = Ancestors.count  ;  i > 0  &&  result == NULL ;  --i)\n\t{\n\t\ttokenInfo *const token = Ancestors.list + i - 1;\n\t\tif (token->type == TOKEN_IDENTIFIER &&\n\t\t\ttoken->tag != TAG_UNDEFINED)\n\t\t\tresult = token;\n\t}\n\treturn result;\n}\n\nstatic const tokenInfo* ancestorTop (void)\n{\n\tAssert (Ancestors.count > 0);\n\treturn &Ancestors.list [Ancestors.count - 1];\n}\n\n#define ancestorCount() (Ancestors.count)\n\nstatic void ancestorClear (void)\n{\n\twhile (Ancestors.count > 0)\n\t\tancestorPop ();\n\tif (Ancestors.list != NULL)\n\t\teFree (Ancestors.list);\n\tAncestors.list = NULL;\n\tAncestors.count = 0;\n\tAncestors.max = 0;\n}\n\nstatic bool insideInterface (void)\n{\n\tbool result = false;\n\tunsigned int i;\n\tfor (i = 0  ;  i < Ancestors.count && !result ;  ++i)\n\t{\n\t\tif (Ancestors.list [i].tag == TAG_INTERFACE)\n\t\t\tresult = true;\n\t}\n\treturn result;\n}\n\n/*\n*   Tag generation functions\n*/\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\n\ttoken->type         = TOKEN_UNDEFINED;\n\ttoken->keyword      = KEYWORD_NONE;\n\ttoken->tag          = TAG_UNDEFINED;\n\ttoken->string       = vStringNew ();\n\ttoken->secondary    = NULL;\n\ttoken->parentType   = NULL;\n\ttoken->signature    = NULL;\n\ttoken->implementation = IMP_DEFAULT;\n\ttoken->isMethod     = false;\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\ttoken->anonymous    = false;\n\n\treturn token;\n}\n\nstatic tokenInfo *newTokenFromFull (tokenInfo *const token, bool copyStr)\n{\n\ttokenInfo *result = xMalloc (1, tokenInfo);\n\t*result = *token;\n\tresult->string = copyStr? vStringNewCopy (token->string): vStringNew();\n\ttoken->secondary = NULL;\n\ttoken->parentType = NULL;\n\ttoken->signature = NULL;\n\treturn result;\n}\n\nstatic tokenInfo *newTokenFrom (tokenInfo *const token)\n{\n\treturn newTokenFromFull (token, true);\n}\n\nstatic tokenInfo *newAnonTokenFrom (tokenInfo *const token, unsigned int uTagKind)\n{\n\ttokenInfo *result = newTokenFromFull (token, false);\n\tresult->anonymous = true;\n\tanonGenerate (result->string, \"__anon\", uTagKind);\n\treturn result;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tif (token != NULL)\n\t{\n\t\tvStringDelete (token->string);\n\t\tvStringDelete (token->parentType);\n\t\tvStringDelete (token->signature);\n\t\tdeleteToken (token->secondary);\n\t\ttoken->secondary = NULL;\n\t\teFree (token);\n\t}\n}\n\nstatic bool isFileScope (const tagType type)\n{\n\treturn (bool) (type == TAG_LABEL || type == TAG_LOCAL);\n}\n\nstatic bool includeTag (const tagType type)\n{\n\tbool include;\n\tAssert (type != TAG_UNDEFINED);\n\tinclude = FortranKinds [(int) type].enabled;\n\tif (include && isFileScope (type))\n\t\tinclude = isXtagEnabled(XTAG_FILE_SCOPE);\n\treturn include;\n}\n\nstatic const char *implementationString (const impType imp)\n{\n\tstatic const char *const names [] ={\n\t\t\"?\", \"abstract\", \"deferred\", \"non_overridable\"\n\t};\n\tAssert (ARRAY_SIZE (names) == IMP_COUNT);\n\tAssert ((int) imp < IMP_COUNT);\n\treturn names [(int) imp];\n}\n\nstatic bool hasLinkName(tagEntryInfo *e)\n{\n\tswitch (e->kindIndex)\n\t{\n\tcase TAG_FUNCTION:\n\tcase TAG_SUBROUTINE:\n\tcase TAG_BLOCK_DATA:\n\tcase TAG_COMMON_BLOCK:\n\tcase TAG_ENTRY_POINT:\n\t\treturn true;\n\tdefault:\n\t\treturn false;\n\t}\n}\n\n/* ref.\n * * https://gcc.gnu.org/onlinedocs/gfortran/Code-Gen-Options.html\n *   - -fno-underscoring\n *   - -fsecond-underscore\n * * https://docs.oracle.com/cd/E19957-01/805-4940/z400091044a7/index.html\n */\nstatic void makeFortranLinkNameTag(tagEntryInfo *e)\n{\n\tvString *ln = vStringNewInit (e->name);\n\tvStringLower(ln);\n\n#if 0\n\tif (strchr(vStringValue (ln), '_'))\n\t\tvStringPut(ln, '_');\n#endif\n\n\tvStringPut(ln, '_');\n\n\ttagEntryInfo ln_e = *e;\n\tln_e.name = vStringValue (ln);\n\tmarkTagExtraBit (&ln_e, FortranXtagTable[X_LINK_NAME].xtype);\n\tmakeTagEntry (&ln_e);\n\tvStringDelete (ln);\n}\n\nstatic void makeFortranTag (tokenInfo *const token, tagType tag)\n{\n\ttoken->tag = tag;\n\tif (includeTag (token->tag))\n\t{\n\t\tconst char *const name = vStringValue (token->string);\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry (&e, name, token->tag);\n\n\t\tif (token->tag == TAG_COMMON_BLOCK)\n\t\t\te.lineNumberEntry = canUseLineNumberAsLocator();\n\n\t\tif (token->anonymous)\n\t\t\tmarkTagExtraBit (&e, XTAG_ANONYMOUS);\n\n\t\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\t\te.isFileScope\t= isFileScope (token->tag);\n\t\tif (e.isFileScope)\n\t\t\tmarkTagExtraBit (&e, XTAG_FILE_SCOPE);\n\t\te.truncateLineAfterTag = (bool) (token->tag != TAG_LABEL);\n\n\t\tif (ancestorCount () > 0)\n\t\t{\n\t\t\tconst tokenInfo* const scope = ancestorScope ();\n\t\t\tif (scope != NULL)\n\t\t\t{\n\t\t\t\te.extensionFields.scopeKindIndex = scope->tag;\n\t\t\t\te.extensionFields.scopeName = vStringValue (scope->string);\n\t\t\t}\n\t\t}\n\t\tif (token->parentType != NULL &&\n\t\t    vStringLength (token->parentType) > 0 &&\n\t\t    (token->tag == TAG_DERIVED_TYPE || (token->tag == TAG_SUBMODULE)))\n\t\t\te.extensionFields.inheritance = vStringValue (token->parentType);\n\t\tif (token->implementation != IMP_DEFAULT)\n\t\t\te.extensionFields.implementation =\n\t\t\t\timplementationString (token->implementation);\n\t\tif (token->signature &&\n\t\t\tvStringLength (token->signature) > 0 &&\n\t\t\t(token->tag == TAG_FUNCTION ||\n\t\t\t token->tag == TAG_SUBROUTINE ||\n\t\t\t token->tag == TAG_PROTOTYPE))\n\t\t\te.extensionFields.signature = vStringValue (token->signature);\n\t\tmakeTagEntry (&e);\n\t\tif (isXtagEnabled (FortranXtagTable[X_LINK_NAME].xtype)\n\t\t\t&& hasLinkName(&e))\n\t\t\tmakeFortranLinkNameTag(&e);\n\t}\n}\n\n/*\n*   Parsing functions\n*/\n\nstatic int skipLine (void)\n{\n\tint c;\n\n\tdo\n\t\tc = getcFromInputFile ();\n\twhile (c != EOF  &&  c != '\\n');\n\n\treturn c;\n}\n\nstatic void makeLabelTag (vString *const label)\n{\n\ttokenInfo *token = newToken ();\n\ttoken->type  = TOKEN_LABEL;\n\tvStringCopy (token->string, label);\n\tmakeFortranTag (token, TAG_LABEL);\n\tdeleteToken (token);\n}\n\nstatic lineType getLineType (void)\n{\n\tstatic vString *label = NULL;\n\tint column = 0;\n\tlineType type = LTYPE_UNDETERMINED;\n\n\tlabel = vStringNewOrClear (label);\n\tdo  /* read in first 6 \"margin\" characters */\n\t{\n\t\tint c = getcFromInputFile ();\n\n\t\t/* 3.2.1  Comment_Line.  A comment line is any line that contains\n\t\t * a C or an asterisk in column 1, or contains only blank characters\n\t\t * in  columns 1 through 72.  A comment line that contains a C or\n\t\t * an asterisk in column 1 may contain any character capable  of\n\t\t * representation in the processor in columns 2 through 72.\n\t\t */\n\t\t/*  EXCEPTION! Some compilers permit '!' as a comment character here.\n\t\t *\n\t\t *  Treat # and $ in column 1 as comment to permit preprocessor directives.\n\t\t *  Treat D and d in column 1 as comment for HP debug statements.\n\t\t */\n\t\tif (column == 0  &&  strchr (\"*Cc!#$Dd\", c) != NULL)\n\t\t\ttype = LTYPE_COMMENT;\n\t\telse if (c == '\\t')  /* EXCEPTION! Some compilers permit a tab here */\n\t\t{\n\t\t\tcolumn = 8;\n\t\t\ttype = LTYPE_INITIAL;\n\t\t}\n\t\telse if (column == 5)\n\t\t{\n\t\t\t/* 3.2.2  Initial_Line.  An initial line is any line that is not\n\t\t\t * a comment line and contains the character blank or the digit 0\n\t\t\t * in column 6.  Columns 1 through 5 may contain a statement label\n\t\t\t * (3.4), or each of the columns 1 through 5 must contain the\n\t\t\t * character blank.\n\t\t\t */\n\t\t\tif (c == ' '  ||  c == '0')\n\t\t\t\ttype = LTYPE_INITIAL;\n\n\t\t\t/* 3.2.3  Continuation_Line.  A continuation line is any line that\n\t\t\t * contains any character of the FORTRAN character set other than\n\t\t\t * the character blank or the digit 0 in column 6 and contains\n\t\t\t * only blank characters in columns 1 through 5.\n\t\t\t */\n\t\t\telse if (vStringLength (label) == 0)\n\t\t\t\ttype = LTYPE_CONTINUATION;\n\t\t\telse\n\t\t\t\ttype = LTYPE_INVALID;\n\t\t}\n\t\telse if (c == ' ')\n\t\t\t;\n\t\telse if (c == EOF)\n\t\t\ttype = LTYPE_EOF;\n\t\telse if (c == '\\n')\n\t\t\ttype = LTYPE_SHORT;\n\t\telse if (isdigit (c))\n\t\t\tvStringPut (label, c);\n\t\telse\n\t\t\ttype = LTYPE_INVALID;\n\n\t\t++column;\n\t} while (column < 6  &&  type == LTYPE_UNDETERMINED);\n\n\tAssert (type != LTYPE_UNDETERMINED);\n\n\tif (vStringLength (label) > 0)\n\t\tmakeLabelTag (label);\n\treturn type;\n}\n\nstatic int getFixedFormChar (bool parsingString, bool *freeSourceFormFound)\n{\n\tbool newline = false;\n\tlineType type;\n\tint c = '\\0';\n\n\tif (Fixed.column > 0)\n\t{\n#ifdef STRICT_FIXED_FORM\n\t\t/*  EXCEPTION! Some compilers permit more than 72 characters per line.\n\t\t */\n\t\tif (Fixed.column > 71)\n\t\t\tc = skipLine ();\n\t\telse\n#endif\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\t++Fixed.column;\n\t\t}\n\t\tif (c == '\\n')\n\t\t{\n\t\t\tnewline = true;  /* need to check for continuation line */\n\t\t\tFixed.column = 0;\n\t\t}\n\t\telse if (c == '!'  &&  ! parsingString)\n\t\t{\n\t\t\tc = skipLine ();\n\t\t\tnewline = true;  /* need to check for continuation line */\n\t\t\tFixed.column = 0;\n\t\t}\n\t\telse if (c == '&')  /* check for free source form */\n\t\t{\n\t\t\tconst int c2 = getcFromInputFile ();\n\t\t\tif (c2 == '\\n')\n\t\t\t\t*freeSourceFormFound = true;\n\t\t\telse\n\t\t\t\tungetcToInputFile (c2);\n\t\t}\n\t}\n\twhile (Fixed.column == 0)\n\t{\n\t\ttype = getLineType ();\n\t\tswitch (type)\n\t\t{\n\t\t\tcase LTYPE_UNDETERMINED:\n\t\t\tcase LTYPE_INVALID:\n\t\t\t\t*freeSourceFormFound = true;\n\t\t\t\tif (inFixedSourceForm)\n\t\t\t\t    return EOF;\n\n\t\t\tcase LTYPE_SHORT: break;\n\t\t\tcase LTYPE_COMMENT: skipLine (); break;\n\n\t\t\tcase LTYPE_EOF:\n\t\t\t\tFixed.column = 6;\n\t\t\t\tif (newline)\n\t\t\t\t\tc = '\\n';\n\t\t\t\telse\n\t\t\t\t\tc = EOF;\n\t\t\t\tbreak;\n\n\t\t\tcase LTYPE_INITIAL:\n\t\t\t\tif (newline)\n\t\t\t\t{\n\t\t\t\t\tc = '\\n';\n\t\t\t\t\tFixed.column = 6;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t/* fall through to next case */\n\t\t\tcase LTYPE_CONTINUATION:\n\t\t\t\tFixed.column = 5;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t\t++Fixed.column;\n\t\t\t\t} while (isBlank (c));\n\t\t\t\tif (c == '\\n')\n\t\t\t\t\tFixed.column = 0;\n\t\t\t\telse if (Fixed.column > 6)\n\t\t\t\t{\n\t\t\t\t\tungetcToInputFile (c);\n\t\t\t\t\tc = ' ';\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tAssert (\"Unexpected line type\" == NULL);\n\t\t}\n\t}\n\treturn c;\n}\n\nstatic int skipToNextLine (void)\n{\n\tint c = skipLine ();\n\tif (c != EOF)\n\t\tc = getcFromInputFile ();\n\treturn c;\n}\n\nstatic int getFreeFormChar (void)\n{\n\tbool advanceLine = false;\n\tint c = getcFromInputFile ();\n\n\t/* If the last nonblank, non-comment character of a FORTRAN 90\n\t * free-format text line is an ampersand then the next non-comment\n\t * line is a continuation line.\n\t */\n\tif (c == '&')\n\t{\n\t\tdo\n\t\t\tc = getcFromInputFile ();\n\t\twhile (isspace (c)  &&  c != '\\n');\n\t\tif (c == '\\n')\n\t\t{\n\t\t\tFree.newline = true;\n\t\t\tadvanceLine = true;\n\t\t}\n\t\telse if (c == '!')\n\t\t\tadvanceLine = true;\n\t\telse\n\t\t{\n\t\t\tungetcToInputFile (c);\n\t\t\tc = '&';\n\t\t}\n\t}\n\telse if (Free.newline && (c == '!' || c == '#'))\n\t\tadvanceLine = true;\n\twhile (advanceLine)\n\t{\n\t\twhile (isspace (c))\n\t\t\tc = getcFromInputFile ();\n\t\tif (c == '!' || (Free.newline && c == '#'))\n\t\t{\n\t\t\tc = skipToNextLine ();\n\t\t\tFree.newline = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (c == '&')\n\t\t\tc = getcFromInputFile ();\n\t\telse\n\t\t\tadvanceLine = false;\n\t}\n\tFree.newline = (bool) (c == '\\n');\n\treturn c;\n}\n\nstatic int getCharFull (bool parsingString, bool *freeSourceFormFound)\n{\n\tint c;\n\n\tif (Ungetc != '\\0')\n\t{\n\t\tc = Ungetc;\n\t\tUngetc = '\\0';\n\t}\n\telse if (inFreeSourceForm)\n\t\tc = getFreeFormChar ();\n\telse\n\t\tc = getFixedFormChar (parsingString,\n\t\t\t\t\t\t\t  freeSourceFormFound);\n\treturn c;\n}\n\nstatic int getChar (void)\n{\n\treturn getCharFull (false, &Fixed.freeSourceFormFound);\n}\n\nstatic void ungetChar (const int c)\n{\n\tUngetc = c;\n}\n\n/*  If a numeric is passed in 'c', this is used as the first digit of the\n *  numeric being parsed.\n */\nstatic vString *parseInteger (int c)\n{\n\tvString *string = vStringNew ();\n\n\tif (c == '-')\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getChar ();\n\t}\n\telse if (! isdigit (c))\n\t\tc = getChar ();\n\twhile (c != EOF  &&  isdigit (c))\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getChar ();\n\t}\n\n\tif (c == '_')\n\t{\n\t\tdo\n\t\t\tc = getChar ();\n\t\twhile (c != EOF  &&  isalpha (c));\n\t}\n\tungetChar (c);\n\n\treturn string;\n}\n\nstatic vString *parseNumeric (int c)\n{\n\tvString *string = parseInteger (c);\n\n\tc = getChar ();\n\tif (c == '.')\n\t{\n\t\tvString *integer = parseInteger ('\\0');\n\t\tvStringPut (string, c);\n\t\tvStringCat (string, integer);\n\t\tvStringDelete (integer);\n\t\tc = getChar ();\n\t}\n\tif (tolower (c) == 'e')\n\t{\n\t\tvString *integer = parseInteger ('\\0');\n\t\tvStringPut (string, c);\n\t\tvStringCat (string, integer);\n\t\tvStringDelete (integer);\n\t}\n\telse\n\t\tungetChar (c);\n\n\treturn string;\n}\n\nstatic void parseString (vString *const string, const int delimiter)\n{\n\tconst unsigned long inputLineNumber = getInputLineNumber ();\n\tint c = getCharFull (true, &Fixed.freeSourceFormFound);\n\n\twhile (c != delimiter  &&  c != '\\n'  &&  c != EOF)\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getCharFull (true, &Fixed.freeSourceFormFound);\n\t}\n\tif (c == '\\n'  ||  c == EOF)\n\t{\n\t\tverbose (\"%s: unterminated character string at line %lu\\n\",\n\t\t\t\tgetInputFileName (), inputLineNumber);\n\t\tif (c != EOF && inFixedSourceForm)\n\t\t\tFixed.freeSourceFormFound = true;\n\t}\n}\n\n/*  Read a C identifier beginning with \"firstChar\" and places it into \"name\".\n */\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getChar ();\n\t} while (isident (c));\n\n\tungetChar (c);  /* unget non-identifier character */\n}\n\nstatic void checkForLabel (void)\n{\n\ttokenInfo* token = NULL;\n\tint length;\n\tint c;\n\n\tdo\n\t\tc = getChar ();\n\twhile (isBlank (c));\n\n\tfor (length = 0  ;  isdigit (c)  &&  length < 5  ;  ++length)\n\t{\n\t\tif (token == NULL)\n\t\t{\n\t\t\ttoken = newToken ();\n\t\t\ttoken->type = TOKEN_LABEL;\n\t\t}\n\t\tvStringPut (token->string, c);\n\t\tc = getChar ();\n\t}\n\tif (length > 0  &&  token != NULL)\n\t{\n\t\tmakeFortranTag (token, TAG_LABEL);\n\t\tdeleteToken (token);\n\t}\n\tungetChar (c);\n}\n\nstatic void readIdentifier (tokenInfo *const token, const int c)\n{\n\tparseIdentifier (token->string, c);\n\ttoken->keyword = lookupCaseKeyword (vStringValue (token->string), Lang_fortran);\n\tif (! isKeyword (token, KEYWORD_NONE))\n\t\ttoken->type = TOKEN_KEYWORD;\n\telse\n\t{\n\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\tif (strncmp (vStringValue (token->string), \"end\", 3) == 0)\n\t\t{\n\t\t\tvString *const sub = vStringNewInit (vStringValue (token->string) + 3);\n\t\t\tconst keywordId kw = lookupCaseKeyword (vStringValue (sub), Lang_fortran);\n\t\t\tvStringDelete (sub);\n\t\t\tif (kw != KEYWORD_NONE)\n\t\t\t{\n\t\t\t\ttoken->secondary = newToken ();\n\t\t\t\ttoken->secondary->type = TOKEN_KEYWORD;\n\t\t\t\ttoken->secondary->keyword = kw;\n\t\t\t\ttoken->keyword = KEYWORD_end;\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\tint c;\n\n\tdeleteToken (token->secondary);\n\ttoken->type        = TOKEN_UNDEFINED;\n\ttoken->tag         = TAG_UNDEFINED;\n\ttoken->keyword     = KEYWORD_NONE;\n\ttoken->secondary   = NULL;\n\ttoken->implementation = IMP_DEFAULT;\n\tvStringClear (token->string);\n\tvStringDelete (token->parentType);\n\tvStringDelete (token->signature);\n\ttoken->parentType = NULL;\n\ttoken->isMethod = false;\n\ttoken->signature = NULL;\n\ngetNextChar:\n\tc = getChar ();\n\n\ttoken->lineNumber\t= getInputLineNumber ();\n\ttoken->filePosition\t= getInputFilePosition ();\n\n\tswitch (c)\n\t{\n\t\tcase EOF:  token->type = TOKEN_EOF;         break;\n\t\tcase ' ':  goto getNextChar;\n\t\tcase '\\t': goto getNextChar;\n\t\tcase ',':  token->type = TOKEN_COMMA;       break;\n\t\tcase '(':  token->type = TOKEN_PAREN_OPEN;  break;\n\t\tcase ')':  token->type = TOKEN_PAREN_CLOSE; break;\n\t\tcase '[':  token->type = TOKEN_SQUARE_OPEN; break;\n\t\tcase ']':  token->type = TOKEN_SQUARE_CLOSE; break;\n\t\tcase '%':  token->type = TOKEN_PERCENT;     break;\n\n\t\tcase '*':\n\t\tcase '/':\n\t\tcase '+':\n\t\tcase '-':\n\t\tcase '=':\n\t\tcase '<':\n\t\tcase '>':\n\t\t{\n\t\t\tconst char *const operatorChars = \"*/+=<>\";\n\t\t\tdo {\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\tc = getChar ();\n\t\t\t} while (strchr (operatorChars, c) != NULL);\n\t\t\tungetChar (c);\n\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '!':\n\t\t\tif (inFreeSourceForm)\n\t\t\t{\n\t\t\t\tdo\n\t\t\t\t   c = getChar ();\n\t\t\t\twhile (c != '\\n' && c != EOF);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tskipLine ();\n\t\t\t\tFixed.column = 0;\n\t\t\t}\n\t\t\t/* fall through to newline case */\n\t\tcase '\\n':\n\t\t\ttoken->type = TOKEN_STATEMENT_END;\n\t\t\tif (inFreeSourceForm)\n\t\t\t\tcheckForLabel ();\n\t\t\tbreak;\n\n\t\tcase '.':\n\t\t\tparseIdentifier (token->string, c);\n\t\t\tc = getChar ();\n\t\t\tif (c == '.')\n\t\t\t{\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetChar (c);\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase '\"':\n\t\tcase '\\'':\n\t\t\tparseString (token->string, c);\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tbreak;\n\n\t\tcase ';':\n\t\t\ttoken->type = TOKEN_STATEMENT_END;\n\t\t\tbreak;\n\n\t\tcase ':':\n\t\t\tc = getChar ();\n\t\t\tif (c == ':')\n\t\t\t\ttoken->type = TOKEN_DOUBLE_COLON;\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetChar (c);\n\t\t\t\ttoken->type = TOKEN_COLON;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tif (isalpha (c))\n\t\t\t\treadIdentifier (token, c);\n\t\t\telse if (isdigit (c))\n\t\t\t{\n\t\t\t\tvString *numeric = parseNumeric (c);\n\t\t\t\tvStringCat (token->string, numeric);\n\t\t\t\tvStringDelete (numeric);\n\t\t\t\ttoken->type = TOKEN_NUMERIC;\n\t\t\t}\n\t\t\telse\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\tbreak;\n\t}\n}\n\nstatic void readSubToken (tokenInfo *const token)\n{\n\tif (token->secondary == NULL)\n\t{\n\t\ttoken->secondary = newToken ();\n\t\treadToken (token->secondary);\n\t}\n}\n\n/*\n*   Scanning functions\n*/\n\nstatic void skipToToken (tokenInfo *const token, tokenType type)\n{\n\twhile (! isType (token, type) && ! isType (token, TOKEN_STATEMENT_END) &&\n\t\t\t!(token->secondary != NULL && isType (token->secondary, TOKEN_STATEMENT_END)) &&\n\t\t\t! isType (token, TOKEN_EOF))\n\t\treadToken (token);\n}\n\nstatic void skipPast (tokenInfo *const token, tokenType type)\n{\n\tskipToToken (token, type);\n\tif (! isType (token, TOKEN_STATEMENT_END))\n\t\treadToken (token);\n}\n\nstatic void skipToNextStatement (tokenInfo *const token)\n{\n\tdo\n\t{\n\t\tskipToToken (token, TOKEN_STATEMENT_END);\n\t\treadToken (token);\n\t} while (isType (token, TOKEN_STATEMENT_END));\n}\n\n/* skip over paired tokens, managing nested pairs and stopping at statement end\n * or right after closing token, whatever comes first.\n */\nstatic void skipOverPairsFull (tokenInfo *const token,\n\t\t\t\t\t\t\t   tokenType topen,\n\t\t\t\t\t\t\t   tokenType tclose,\n\t\t\t\t\t\t\t   void (* token_cb) (tokenInfo *const, void *),\n\t\t\t\t\t\t\t   void *user_data)\n{\n\tint level = 0;\n\tdo {\n\t\tif (isType (token, TOKEN_STATEMENT_END))\n\t\t\tbreak;\n\t\telse if (isType (token, topen))\n\t\t\t++level;\n\t\telse if (isType (token, tclose))\n\t\t\t--level;\n\t\telse if (token_cb)\n\t\t\ttoken_cb (token, user_data);\n\t\treadToken (token);\n\t} while (level > 0 && !isType (token, TOKEN_EOF));\n}\n\nstatic void skipOverParensFull (tokenInfo *const token,\n\t\t\t\t\t\t\t\tvoid (* token_cb) (tokenInfo *const, void *),\n\t\t\t\t\t\t\t\tvoid *user_data)\n{\n\tskipOverPairsFull (token, TOKEN_PAREN_OPEN,\n\t\t\t\t\t   TOKEN_PAREN_CLOSE,\n\t\t\t\t\t   token_cb, user_data);\n}\n\nstatic void skipOverSquaresFull (tokenInfo *const token,\n\t\t\t\t\t\t\t\t void (* token_cb) (tokenInfo *const, void *),\n\t\t\t\t\t\t\t\t void *user_data)\n{\n\tskipOverPairsFull (token, TOKEN_SQUARE_OPEN,\n\t\t\t\t\t   TOKEN_SQUARE_CLOSE,\n\t\t\t\t\t   token_cb, user_data);\n}\n\nstatic void skipOverParens (tokenInfo *const token)\n{\n\tskipOverParensFull (token, NULL, NULL);\n}\n\nstatic void skipOverSquares (tokenInfo *const token)\n{\n\tskipOverSquaresFull (token, NULL, NULL);\n}\n\nstatic bool isTypeSpec (tokenInfo *const token)\n{\n\tbool result;\n\tswitch (token->keyword)\n\t{\n\t\tcase KEYWORD_byte:\n\t\tcase KEYWORD_integer:\n\t\tcase KEYWORD_real:\n\t\tcase KEYWORD_double:\n\t\tcase KEYWORD_complex:\n\t\tcase KEYWORD_character:\n\t\tcase KEYWORD_logical:\n\t\tcase KEYWORD_record:\n\t\tcase KEYWORD_type:\n\t\tcase KEYWORD_procedure:\n\t\tcase KEYWORD_final:\n\t\tcase KEYWORD_generic:\n\t\tcase KEYWORD_class:\n\t\tcase KEYWORD_enumerator:\n\t\t\tresult = true;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tresult = false;\n\t\t\tbreak;\n\t}\n\treturn result;\n}\n\nstatic bool isSubprogramPrefix (tokenInfo *const token)\n{\n\tbool result;\n\tswitch (token->keyword)\n\t{\n\t\tcase KEYWORD_elemental:\n\t\tcase KEYWORD_pure:\n\t\tcase KEYWORD_recursive:\n\t\tcase KEYWORD_stdcall:\n\t\t\tresult = true;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tresult = false;\n\t\t\tbreak;\n\t}\n\treturn result;\n}\n\nstatic void parseKindSelector (tokenInfo *const token)\n{\n\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\tskipOverParens (token);  /* skip kind-selector */\n\tif (isType (token, TOKEN_OPERATOR) &&\n\t\tstrcmp (vStringValue (token->string), \"*\") == 0)\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\t\tskipOverParens (token);\n\t\telse\n\t\t\treadToken (token);\n\t}\n}\n\n/*  type-spec\n *      is INTEGER [kind-selector]\n *      or REAL [kind-selector] is ( etc. )\n *      or DOUBLE PRECISION\n *      or COMPLEX [kind-selector]\n *      or CHARACTER [kind-selector]\n *      or LOGICAL [kind-selector]\n *      or TYPE ( type-name )\n *\n *  Note that INTEGER and REAL may be followed by \"*N\" where \"N\" is an integer\n */\nstatic void parseTypeSpec (tokenInfo *const token)\n{\n\t/* parse type-spec, leaving `token' at first token following type-spec */\n\tAssert (isTypeSpec (token));\n\tswitch (token->keyword)\n\t{\n\t\tcase KEYWORD_character:\n\t\t\t/* skip char-selector */\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPERATOR) &&\n\t\t\t\t\t strcmp (vStringValue (token->string), \"*\") == 0)\n\t\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\t\t\tskipOverParens (token);\n\t\t\telse if (isType (token, TOKEN_NUMERIC))\n\t\t\t\treadToken (token);\n\t\t\tbreak;\n\n\n\t\tcase KEYWORD_byte:\n\t\tcase KEYWORD_complex:\n\t\tcase KEYWORD_integer:\n\t\tcase KEYWORD_logical:\n\t\tcase KEYWORD_real:\n\t\tcase KEYWORD_procedure:\n\t\tcase KEYWORD_class:\n\t\t\treadToken (token);\n\t\t\tparseKindSelector (token);\n\t\t\tbreak;\n\n\t\tcase KEYWORD_double:\n\t\t\treadToken (token);\n\t\t\tif (isKeyword (token, KEYWORD_complex) ||\n\t\t\t\tisKeyword (token, KEYWORD_precision))\n\t\t\t\t\treadToken (token);\n\t\t\telse\n\t\t\t\tskipToToken (token, TOKEN_STATEMENT_END);\n\t\t\tbreak;\n\n\t\tcase KEYWORD_record:\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPERATOR) &&\n\t\t\t\tstrcmp (vStringValue (token->string), \"/\") == 0)\n\t\t\t{\n\t\t\t\treadToken (token);  /* skip to structure name */\n\t\t\t\treadToken (token);  /* skip to '/' */\n\t\t\t\treadToken (token);  /* skip to variable name */\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase KEYWORD_type:\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\t\t\tskipOverParens (token);  /* skip type-name */\n\t\t\telse\n\t\t\t\tparseDerivedTypeDef (token);\n\t\t\tbreak;\n\n\t\tcase KEYWORD_final:\n\t\tcase KEYWORD_generic:\n\t\tcase KEYWORD_enumerator:\n\t\t\treadToken (token);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tskipToToken (token, TOKEN_STATEMENT_END);\n\t\t\tbreak;\n\t}\n}\n\nstatic bool skipStatementIfKeyword (tokenInfo *const token, keywordId keyword)\n{\n\tbool result = false;\n\tif (isKeyword (token, keyword))\n\t{\n\t\tresult = true;\n\t\tskipToNextStatement (token);\n\t}\n\treturn result;\n}\n\n/* parse extends qualifier, leaving token at first token following close\n * parenthesis.\n */\n\nstatic void attachParentType (tokenInfo *const token, vString* parentType)\n{\n\tif (token->parentType)\n\t\tvStringDelete (token->parentType);\n\ttoken->parentType = parentType;\n}\n\nstatic void makeParentType (tokenInfo *const token, void *userData)\n{\n\tattachParentType ((tokenInfo *const)userData,\n\t\t\t\t\t  vStringNewCopy (token->string));\n}\n\nstatic void parseExtendsQualifier (tokenInfo *const token,\n\t\t\t\t\t\t\t\t   tokenInfo *const qualifierToken)\n{\n\tskipOverParensFull (token, makeParentType, qualifierToken);\n}\n\nstatic void parseAbstractQualifier (tokenInfo *const token,\n\t\t\t\t\t\t\t\t\ttokenInfo *const qualifierToken)\n{\n\tAssert (isKeyword (token, KEYWORD_abstract));\n\tqualifierToken->implementation = IMP_ABSTRACT;\n\treadToken (token);\n}\n\nstatic void parseDeferredQualifier (tokenInfo *const token,\n\t\t\t\t\t\t\t\t\ttokenInfo *const qualifierToken)\n{\n\tAssert (isKeyword (token, KEYWORD_deferred));\n\tqualifierToken->implementation = IMP_DEFERRED;\n\treadToken (token);\n}\n\nstatic void parseNonOverridableQualifier (tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t\t  tokenInfo *const qualifierToken)\n{\n\tAssert (isKeyword (token, KEYWORD_non_overridable));\n\tqualifierToken->implementation = IMP_NON_OVERRIDABLE;\n\treadToken (token);\n}\n\n/* parse a list of qualifying specifiers, leaving `token' at first token\n * following list. Examples of such specifiers are:\n *      [[, attr-spec] ::]\n *      [[, component-attr-spec-list] ::]\n *\n *  attr-spec\n *      is PARAMETER\n *      or access-spec (is PUBLIC or PRIVATE)\n *      or ALLOCATABLE\n *      or DIMENSION ( array-spec )\n *      or EXTENDS ( extends-spec )\n *      or EXTERNAL\n *      or INTENT ( intent-spec )\n *      or INTRINSIC\n *      or OPTIONAL\n *      or POINTER\n *      or SAVE\n *      or TARGET\n *      or PASS\n *      or NOPASS\n *      or DEFERRED\n *      or NON_OVERRIDABLE\n *      or ABSTRACT\n *\n *  component-attr-spec\n *      is POINTER\n *      or DIMENSION ( component-array-spec )\n */\nstatic tokenInfo *parseQualifierSpecList (tokenInfo *const token)\n{\n\ttokenInfo *qualifierToken = newToken ();\n\n\tdo\n\t{\n\t\treadToken (token);  /* should be an attr-spec */\n\t\tswitch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_parameter:\n\t\t\tcase KEYWORD_allocatable:\n\t\t\tcase KEYWORD_external:\n\t\t\tcase KEYWORD_intrinsic:\n\t\t\tcase KEYWORD_kind:\n\t\t\tcase KEYWORD_len:\n\t\t\tcase KEYWORD_optional:\n\t\t\tcase KEYWORD_private:\n\t\t\tcase KEYWORD_pointer:\n\t\t\tcase KEYWORD_protected:\n\t\t\tcase KEYWORD_public:\n\t\t\tcase KEYWORD_save:\n\t\t\tcase KEYWORD_target:\n\t\t\tcase KEYWORD_nopass:\n\t\t\t\treadToken (token);\n\t\t\t\tbreak;\n\n\t\t\tcase KEYWORD_dimension:\n\t\t\tcase KEYWORD_intent:\n\t\t\tcase KEYWORD_bind:\n\t\t\t\treadToken (token);\n\t\t\t\tskipOverParens (token);\n\t\t\t\tbreak;\n\n\t\t\tcase KEYWORD_extends:\n\t\t\t\treadToken (token);\n\t\t\t\tparseExtendsQualifier (token, qualifierToken);\n\t\t\t\tbreak;\n\n\t\t\tcase KEYWORD_pass:\n\t\t\t\treadToken (token);\n\t\t\t\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\t\t\t\tskipOverParens (token);\n\t\t\t\tbreak;\n\n\t\t\tcase KEYWORD_abstract:\n\t\t\t\tparseAbstractQualifier (token, qualifierToken);\n\t\t\t\tbreak;\n\n\t\t\tcase KEYWORD_deferred:\n\t\t\t\tparseDeferredQualifier (token, qualifierToken);\n\t\t\t\tbreak;\n\n\t\t\tcase KEYWORD_non_overridable:\n\t\t\t\tparseNonOverridableQualifier (token, qualifierToken);\n\t\t\t\tbreak;\n\n\t\t\tcase KEYWORD_codimension:\n\t\t\t\treadToken (token);\n\t\t\t\tskipOverSquares (token);\n\t\t\t\tbreak;\n\n\t\t\tdefault: skipToToken (token, TOKEN_STATEMENT_END); break;\n\t\t}\n\t} while (isType (token, TOKEN_COMMA));\n\tif (! isType (token, TOKEN_DOUBLE_COLON))\n\t\tskipToToken (token, TOKEN_STATEMENT_END);\n\n\treturn qualifierToken;\n}\n\nstatic tagType variableTagType (tokenInfo *const st)\n{\n\ttagType result = TAG_VARIABLE;\n\tif (ancestorCount () > 0)\n\t{\n\t\tconst tokenInfo* const parent = ancestorTop ();\n\t\tswitch (parent->tag)\n\t\t{\n\t\t\tcase TAG_SUBMODULE:\t/* Fall through */\n\t\t\tcase TAG_MODULE:       result = TAG_VARIABLE;  break;\n\t\t\tcase TAG_DERIVED_TYPE:\n\t\t\t\tif (st && st->isMethod)\n\t\t\t\t\tresult = TAG_METHOD;\n\t\t\t\telse\n\t\t\t\t\tresult = TAG_COMPONENT;\n\t\t\t\tbreak;\n\t\t\tcase TAG_FUNCTION:     result = TAG_LOCAL;     break;\n\t\t\tcase TAG_SUBROUTINE:   result = TAG_LOCAL;     break;\n\t\t\tcase TAG_PROTOTYPE:    result = TAG_LOCAL;     break;\n\t\t\tcase TAG_ENUM:         result = TAG_ENUMERATOR; break;\n\t\t\tdefault:               result = TAG_VARIABLE;  break;\n\t\t}\n\t}\n\treturn result;\n}\n\nstatic void parseEntityDecl (tokenInfo *const token,\n\t\t\t\t\t\t\t tokenInfo *const st)\n{\n\tAssert (isType (token, TOKEN_IDENTIFIER));\n\tif (st && st->implementation != IMP_DEFAULT)\n\t\ttoken->implementation = st->implementation;\n\tmakeFortranTag (token, variableTagType (st));\n\treadToken (token);\n\t/* we check for both '()' and '[]'\n\t * coarray syntax permits variable(), variable[], or variable()[]\n\t */\n\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\tskipOverParens (token);\n\tif (isType (token, TOKEN_SQUARE_OPEN))\n\t\tskipOverSquares (token);\n\tif (isType (token, TOKEN_OPERATOR) &&\n\t\t\tstrcmp (vStringValue (token->string), \"*\") == 0)\n\t{\n\t\treadToken (token);  /* read char-length */\n\t\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\t\tskipOverParens (token);\n\t\telse\n\t\t\treadToken (token);\n\t}\n\tif (isType (token, TOKEN_OPERATOR))\n\t{\n\t\tif (strcmp (vStringValue (token->string), \"/\") == 0)\n\t\t{  /* skip over initializations of structure field */\n\t\t\treadToken (token);\n\t\t\tskipPast (token, TOKEN_OPERATOR);\n\t\t}\n\t\telse if (strcmp (vStringValue (token->string), \"=\") == 0 ||\n\t\t\t\t strcmp (vStringValue (token->string), \"=>\") == 0)\n\t\t{\n\t\t\twhile (! isType (token, TOKEN_COMMA) &&\n\t\t\t\t\t! isType (token, TOKEN_STATEMENT_END) &&\n\t\t\t\t\t! isType (token, TOKEN_EOF))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\t/* another coarray check, for () and [] */\n\t\t\t\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\t\t\t\tskipOverParens (token);\n\t\t\t\tif (isType (token, TOKEN_SQUARE_OPEN))\n\t\t\t\t\tskipOverSquares (token);\n\t\t\t}\n\t\t}\n\t}\n\t/* token left at either comma or statement end */\n}\n\nstatic void parseEntityDeclList (tokenInfo *const token,\n\t\t\t\t\t\t\t\t tokenInfo *const st)\n{\n\tif (isType (token, TOKEN_PERCENT))\n\t\tskipToNextStatement (token);\n\telse while (isType (token, TOKEN_IDENTIFIER) ||\n\t\t\t\t(isType (token, TOKEN_KEYWORD) &&\n\t\t\t\t !isKeyword (token, KEYWORD_function) &&\n\t\t\t\t !isKeyword (token, KEYWORD_subroutine)))\n\t{\n\t\t/* compilers accept keywords as identifiers */\n\t\tif (isType (token, TOKEN_KEYWORD))\n\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\tparseEntityDecl (token, st);\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t\treadToken (token);\n\t\telse if (isType (token, TOKEN_STATEMENT_END))\n\t\t{\n\t\t\tskipToNextStatement (token);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/*  type-declaration-stmt is\n *      type-spec [[, attr-spec] ... ::] entity-decl-list\n */\nstatic void parseTypeDeclarationStmt (tokenInfo *const token)\n{\n\tAssert (isTypeSpec (token));\n\tparseTypeSpec (token);\n\tif (!isType (token, TOKEN_STATEMENT_END))  /* if not end of derived type... */\n\t{\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t{\n\t\t\ttokenInfo* qualifierToken = parseQualifierSpecList (token);\n\t\t\tdeleteToken (qualifierToken);\n\t\t}\n\t\tif (isType (token, TOKEN_DOUBLE_COLON))\n\t\t\treadToken (token);\n\t\tparseEntityDeclList (token, NULL);\n\t}\n\tif (isType (token, TOKEN_STATEMENT_END))\n\t\tskipToNextStatement (token);\n}\n\n/*  namelist-stmt is\n *      NAMELIST /namelist-group-name/ namelist-group-object-list\n *\t\t\t[[,]/[namelist-group-name]/ namelist-block-object-list] ...\n *\n *  namelist-group-object is\n *      variable-name\n *\n *  common-stmt is\n *      COMMON [/[common-block-name]/] common-block-object-list\n *\t\t\t[[,]/[common-block-name]/ common-block-object-list] ...\n *\n *  common-block-object is\n *      variable-name [ ( explicit-shape-spec-list ) ]\n */\nstatic void parseCommonNamelistStmt (tokenInfo *const token, tagType type)\n{\n\tAssert (isKeyword (token, KEYWORD_common) ||\n\t\t\tisKeyword (token, KEYWORD_namelist));\n\treadToken (token);\n\tdo\n\t{\n\t\tif (isType (token, TOKEN_OPERATOR) &&\n\t\t\tstrcmp (vStringValue (token->string), \"/\") == 0)\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t{\n\t\t\t\tmakeFortranTag (token, type);\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\tskipPast (token, TOKEN_OPERATOR);\n\t\t}\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\tmakeFortranTag (token, TAG_LOCAL);\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\t\tskipOverParens (token);  /* skip explicit-shape-spec-list */\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t\treadToken (token);\n\t} while (! isType (token, TOKEN_STATEMENT_END) &&\n\t\t\t ! isType (token, TOKEN_EOF));\n\tskipToNextStatement (token);\n}\n\nstatic void parseFieldDefinition (tokenInfo *const token)\n{\n\tif (isTypeSpec (token))\n\t\tparseTypeDeclarationStmt (token);\n\telse if (isKeyword (token, KEYWORD_structure))\n\t\tparseStructureStmt (token);\n\telse if (isKeyword (token, KEYWORD_union))\n\t\tparseUnionStmt (token);\n\telse\n\t\tskipToNextStatement (token);\n}\n\nstatic void parseMap (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_map));\n\tskipToNextStatement (token);\n\twhile (! isKeyword (token, KEYWORD_end) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t\tparseFieldDefinition (token);\n\treadSubToken (token);\n\t/* should be at KEYWORD_map token */\n\tskipToNextStatement (token);\n}\n\n/* UNION\n *      MAP\n *          [field-definition] [field-definition] ...\n *      END MAP\n *      MAP\n *          [field-definition] [field-definition] ...\n *      END MAP\n *      [MAP\n *          [field-definition]\n *          [field-definition] ...\n *      END MAP] ...\n *  END UNION\n *      *\n *\n *  Typed data declarations (variables or arrays) in structure declarations\n *  have the form of normal Fortran typed data declarations. Data items with\n *  different types can be freely intermixed within a structure declaration.\n *\n *  Unnamed fields can be declared in a structure by specifying the pseudo\n *  name %FILL in place of an actual field name. You can use this mechanism to\n *  generate empty space in a record for purposes such as alignment.\n *\n *  All mapped field declarations that are made within a UNION declaration\n *  share a common location within the containing structure. When initializing\n *  the fields within a UNION, the final initialization value assigned\n *  overlays any value previously assigned to a field definition that shares\n *  that field.\n */\nstatic void parseUnionStmt (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_union));\n\tskipToNextStatement (token);\n\twhile (isKeyword (token, KEYWORD_map))\n\t\tparseMap (token);\n\t/* should be at KEYWORD_end token */\n\treadSubToken (token);\n\t/* secondary token should be KEYWORD_end token */\n\tskipToNextStatement (token);\n}\n\n/*  STRUCTURE [/structure-name/] [field-names]\n *      [field-definition]\n *      [field-definition] ...\n *  END STRUCTURE\n *\n *  structure-name\n *\t\tidentifies the structure in a subsequent RECORD statement.\n *\t\tSubstructures can be established within a structure by means of either\n *\t\ta nested STRUCTURE declaration or a RECORD statement.\n *\n *   field-names\n *\t\t(for substructure declarations only) one or more names having the\n *\t\tstructure of the substructure being defined.\n *\n *   field-definition\n *\t\tcan be one or more of the following:\n *\n *\t\t\tTyped data declarations, which can optionally include one or more\n *\t\t\tdata initialization values.\n *\n *\t\t\tSubstructure declarations (defined by either RECORD statements or\n *\t\t\tsubsequent STRUCTURE statements).\n *\n *\t\t\tUNION declarations, which are mapped fields defined by a block of\n *\t\t\tstatements. The syntax of a UNION declaration is described below.\n *\n *\t\t\tPARAMETER statements, which do not affect the form of the\n *\t\t\tstructure.\n */\nstatic void parseStructureStmt (tokenInfo *const token)\n{\n\ttokenInfo *name = NULL;\n\tAssert (isKeyword (token, KEYWORD_structure));\n\treadToken (token);\n\tif (isType (token, TOKEN_OPERATOR) &&\n\t\tstrcmp (vStringValue (token->string), \"/\") == 0)\n\t{  /* read structure name */\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))\n\t\t{\n\t\t\tname = newTokenFrom (token);\n\t\t\tname->type = TOKEN_IDENTIFIER;\n\t\t}\n\t\tskipPast (token, TOKEN_OPERATOR);\n\t}\n\tif (name == NULL)\n\t{  /* fake out anonymous structure */\n\t\tname = newAnonTokenFrom (token, TAG_COMPONENT);\n\t\tname->type = TOKEN_IDENTIFIER;\n\t\tname->tag = TAG_DERIVED_TYPE;\n\t}\n\tmakeFortranTag (name, TAG_DERIVED_TYPE);\n\twhile (isType (token, TOKEN_IDENTIFIER))\n\t{  /* read field names */\n\t\tmakeFortranTag (token, TAG_COMPONENT);\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t\treadToken (token);\n\t}\n\tskipToNextStatement (token);\n\tancestorPush (name);\n\twhile (! isKeyword (token, KEYWORD_end) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t\tparseFieldDefinition (token);\n\treadSubToken (token);\n\t/* secondary token should be KEYWORD_structure token */\n\tskipToNextStatement (token);\n\tancestorPop ();\n\tdeleteToken (name);\n}\n\n/*  specification-stmt\n *      is access-stmt      (is access-spec [[::] access-id-list)\n *      or allocatable-stmt (is ALLOCATABLE [::] array-name etc.)\n *      or common-stmt      (is COMMON [ / [common-block-name] /] etc.)\n *      or data-stmt        (is DATA data-stmt-list [[,] data-stmt-set] ...)\n *      or dimension-stmt   (is DIMENSION [::] array-name etc.)\n *      or equivalence-stmt (is EQUIVALENCE equivalence-set-list)\n *      or external-stmt    (is EXTERNAL etc.)\n *      or intent-stmt      (is INTENT ( intent-spec ) [::] etc.)\n *      or intrinsic-stmt   (is INTRINSIC etc.)\n *      or namelist-stmt    (is NAMELIST / namelist-group-name / etc.)\n *      or optional-stmt    (is OPTIONAL [::] etc.)\n *      or pointer-stmt     (is POINTER [::] object-name etc.)\n *      or save-stmt        (is SAVE etc.)\n *      or target-stmt      (is TARGET [::] object-name etc.)\n *\n *  access-spec is PUBLIC or PRIVATE\n */\nstatic bool parseSpecificationStmt (tokenInfo *const token)\n{\n\tbool result = true;\n\tswitch (token->keyword)\n\t{\n\t\tcase KEYWORD_common:\n\t\t\tparseCommonNamelistStmt (token, TAG_COMMON_BLOCK);\n\t\t\tbreak;\n\n\t\tcase KEYWORD_namelist:\n\t\t\tparseCommonNamelistStmt (token, TAG_NAMELIST);\n\t\t\tbreak;\n\n\t\tcase KEYWORD_structure:\n\t\t\tparseStructureStmt (token);\n\t\t\tbreak;\n\n\t\tcase KEYWORD_allocatable:\n\t\tcase KEYWORD_data:\n\t\tcase KEYWORD_dimension:\n\t\tcase KEYWORD_equivalence:\n\t\tcase KEYWORD_external:\n\t\tcase KEYWORD_intent:\n\t\tcase KEYWORD_intrinsic:\n\t\tcase KEYWORD_optional:\n\t\tcase KEYWORD_pointer:\n\t\tcase KEYWORD_private:\n\t\tcase KEYWORD_protected:\n\t\tcase KEYWORD_public:\n\t\tcase KEYWORD_save:\n\t\tcase KEYWORD_target:\n\t\t\tskipToNextStatement (token);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tresult = false;\n\t\t\tbreak;\n\t}\n\treturn result;\n}\n\n/* Type bound generic procedure is:\n *   GENERIC [, access-spec ] :: generic-spec => binding-name1 [, binding-name2]...\n *     access-spec: PUBLIC or PRIVATE\n *     generic-spec: 1. generic name; 2. OPERATOR(op); 3. ASSIGNMENT(=)\n *     binding-name: type bound procedure\n */\nstatic void parseGenericMethod (tokenInfo *const token)\n{\n\tif (isKeyword (token, KEYWORD_assignment) ||\n\t\tisKeyword (token, KEYWORD_operator))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\t\treadToken (token);\n\t\tif (isType (token, TOKEN_OPERATOR))\n\t\t\tmakeFortranTag (token, TAG_METHOD);\n\t}\n\telse\n\t{\n\t\tif (isType (token, TOKEN_KEYWORD))\n\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\tmakeFortranTag (token, TAG_METHOD);\n\t}\n\tskipToNextStatement (token);\n}\n\n/*  component-def-stmt is\n *      type-spec [[, component-attr-spec-list] ::] component-decl-list\n *\n *  component-decl is\n *      component-name [ ( component-array-spec ) ] [ * char-length ]\n */\nstatic void parseComponentDefStmt (tokenInfo *const token)\n{\n\ttokenInfo* st = newToken ();\n\ttokenInfo* qt = NULL;\n\tbool isGeneric = false;\n\n\tAssert (isTypeSpec (token));\n\tif (isKeyword (token, KEYWORD_procedure) ||\n\t\tisKeyword (token, KEYWORD_final) ||\n\t\tisKeyword (token, KEYWORD_generic))\n\t\tst->isMethod = true;\n\tif (isKeyword (token, KEYWORD_generic))\n\t\tisGeneric = true;\n\tparseTypeSpec (token);\n\tif (isType (token, TOKEN_COMMA))\n\t{\n\t\tqt = parseQualifierSpecList (token);\n\t\tif (qt->implementation != IMP_DEFAULT)\n\t\t\tst->implementation = qt->implementation;\n\t\tdeleteToken (qt);\n\t}\n\tif (isType (token, TOKEN_DOUBLE_COLON))\n\t\treadToken (token);\n\tif (isGeneric)\n\t\tparseGenericMethod (token);\n\telse\n\t\tparseEntityDeclList (token, st);\n\tdeleteToken (st);\n}\n\n/*  derived-type-def is\n *      derived-type-stmt is (TYPE [[, access-spec] ::] type-name\n *          [private-sequence-stmt] ... (is PRIVATE or SEQUENCE)\n *          component-def-stmt\n *          [component-def-stmt] ...\n *          end-type-stmt\n */\nstatic void parseDerivedTypeDef (tokenInfo *const token)\n{\n\ttokenInfo *qualifierToken = NULL;\n\n\tif (isType (token, TOKEN_COMMA))\n\t\tqualifierToken = parseQualifierSpecList (token);\n\tif (isType (token, TOKEN_DOUBLE_COLON))\n\t\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))\n\t{\n\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\tif (qualifierToken)\n\t\t{\n\t\t\tif (qualifierToken->parentType)\n\t\t\t\ttoken->parentType = vStringNewCopy (qualifierToken->parentType);\n\t\t\tif (qualifierToken->implementation != IMP_DEFAULT)\n\t\t\t\ttoken->implementation = qualifierToken->implementation;\n\t\t}\n\t\tmakeFortranTag (token, TAG_DERIVED_TYPE);\n\t}\n\tdeleteToken (qualifierToken);\n\tancestorPush (token);\n\tskipToNextStatement (token);\n\tif (isKeyword (token, KEYWORD_private) ||\n\t\tisKeyword (token, KEYWORD_sequence))\n\t{\n\t\tskipToNextStatement (token);\n\t}\n\twhile (! isKeyword (token, KEYWORD_end) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\tif (isTypeSpec (token))\n\t\t\tparseComponentDefStmt (token);\n\t\telse\n\t\t\tskipToNextStatement (token);\n\t}\n\treadSubToken (token);\n\t/* secondary token should be KEYWORD_type token */\n\tskipToToken (token, TOKEN_STATEMENT_END);\n\tancestorPop ();\n}\n\n/*  interface-block\n *      interface-stmt (is INTERFACE [generic-spec])\n *          [interface-body]\n *          [module-procedure-stmt] ...\n *          end-interface-stmt (is END INTERFACE)\n *\n *  generic-spec\n *      is generic-name\n *      or OPERATOR ( defined-operator )\n *      or ASSIGNMENT ( = )\n *\n *  interface-body\n *      is function-stmt\n *          [specification-part]\n *          end-function-stmt\n *      or subroutine-stmt\n *          [specification-part]\n *          end-subroutine-stmt\n *\n *  module-procedure-stmt is\n *      MODULE PROCEDURE procedure-name-list\n */\nstatic void parseInterfaceBlock (tokenInfo *const token)\n{\n\ttokenInfo *name = NULL;\n\tAssert (isKeyword (token, KEYWORD_interface));\n\treadToken (token);\n\tif (isKeyword (token, KEYWORD_assignment) ||\n\t\t\t isKeyword (token, KEYWORD_operator))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\t\treadToken (token);\n\t\tif (isType (token, TOKEN_OPERATOR))\n\t\t\tname = newTokenFrom (token);\n\t}\n\telse if (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))\n\t{\n\t\tname = newTokenFrom (token);\n\t\tname->type = TOKEN_IDENTIFIER;\n\t}\n\tif (name == NULL)\n\t{\n\t\tname = newAnonTokenFrom (token, TAG_INTERFACE);\n\t\tname->type = TOKEN_IDENTIFIER;\n\t\tname->tag = TAG_INTERFACE;\n\t}\n\tmakeFortranTag (name, TAG_INTERFACE);\n\tancestorPush (name);\n\twhile (! isKeyword (token, KEYWORD_end) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\tswitch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_function:\n\t\t\tcase KEYWORD_subroutine: parseSubprogram (token); break;\n\n\t\t\tdefault:\n\t\t\t\tif (isSubprogramPrefix (token))\n\t\t\t\t\treadToken (token);\n\t\t\t\telse if (isTypeSpec (token))\n\t\t\t\t\tparseTypeSpec (token);\n\t\t\t\telse\n\t\t\t\t\tskipToNextStatement (token);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treadSubToken (token);\n\t/* secondary token should be KEYWORD_interface token */\n\tskipToNextStatement (token);\n\tancestorPop ();\n\tdeleteToken (name);\n}\n\n/* enum-block\n *      enum-stmt (is ENUM, BIND(C) [ :: type-alias-name ]\n *                 or ENUM [ kind-selector ] [ :: ] [ type-alias-name ])\n *          [ enum-body (is ENUMERATOR [ :: ] enumerator-list) ]\n *      end-enum-stmt (is END ENUM)\n */\nstatic void parseEnumBlock (tokenInfo *const token)\n{\n\ttokenInfo *name = NULL;\n\tAssert (isKeyword (token, KEYWORD_enum));\n\treadToken (token);\n\tif (isType (token, TOKEN_COMMA))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_KEYWORD))\n\t\t\treadToken (token);\n\t\tif (isType (token, TOKEN_PAREN_OPEN))\n\t\t\tskipOverParens (token);\n\t}\n\tparseKindSelector (token);\n\tif (isType (token, TOKEN_DOUBLE_COLON))\n\t\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))\n\t{\n\t\tname = newTokenFrom (token);\n\t\tname->type = TOKEN_IDENTIFIER;\n\t}\n\tif (name == NULL)\n\t{\n\t\tname = newAnonTokenFrom (token, TAG_ENUM);\n\t\tname->type = TOKEN_IDENTIFIER;\n\t\tname->tag = TAG_ENUM;\n\t}\n\tmakeFortranTag (name, TAG_ENUM);\n\tskipToNextStatement (token);\n\tancestorPush (name);\n\twhile (! isKeyword (token, KEYWORD_end) &&\n\t\t   ! isType(token, TOKEN_EOF))\n\t{\n\t\tif (isTypeSpec (token))\n\t\t\tparseTypeDeclarationStmt (token);\n\t\telse\n\t\t\tskipToNextStatement (token);\n\t}\n\treadSubToken (token);\n\t/* secondary token should be KEYWORD_enum token */\n\tskipToNextStatement (token);\n\tancestorPop ();\n\tdeleteToken (name);\n}\n\n/*  entry-stmt is\n *      ENTRY entry-name [ ( dummy-arg-list ) ]\n */\nstatic void parseEntryStmt (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_entry));\n\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t\tmakeFortranTag (token, TAG_ENTRY_POINT);\n\tskipToNextStatement (token);\n}\n\n/*  stmt-function-stmt is\n *      function-name ([dummy-arg-name-list]) = scalar-expr\n */\nstatic bool parseStmtFunctionStmt (tokenInfo *const token)\n{\n\tbool result = false;\n\tAssert (isType (token, TOKEN_IDENTIFIER));\n#if 0  /* cannot reliably parse this yet */\n\tmakeFortranTag (token, TAG_FUNCTION);\n#endif\n\treadToken (token);\n\tif (isType (token, TOKEN_PAREN_OPEN))\n\t{\n\t\tskipOverParens (token);\n\t\tresult = (bool) (isType (token, TOKEN_OPERATOR) &&\n\t\t\tstrcmp (vStringValue (token->string), \"=\") == 0);\n\t}\n\tskipToNextStatement (token);\n\treturn result;\n}\n\nstatic bool isIgnoredDeclaration (tokenInfo *const token)\n{\n\tbool result;\n\tswitch (token->keyword)\n\t{\n\t\tcase KEYWORD_cexternal:\n\t\tcase KEYWORD_cglobal:\n\t\tcase KEYWORD_dllexport:\n\t\tcase KEYWORD_dllimport:\n\t\tcase KEYWORD_external:\n\t\tcase KEYWORD_format:\n\t\tcase KEYWORD_include:\n\t\tcase KEYWORD_inline:\n\t\tcase KEYWORD_parameter:\n\t\tcase KEYWORD_pascal:\n\t\tcase KEYWORD_pexternal:\n\t\tcase KEYWORD_pglobal:\n\t\tcase KEYWORD_static:\n\t\tcase KEYWORD_value:\n\t\tcase KEYWORD_virtual:\n\t\tcase KEYWORD_volatile:\n\t\t\tresult = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tresult = false;\n\t\t\tbreak;\n\t}\n\treturn result;\n}\n\n/*  declaration-construct\n *      [derived-type-def]\n *      [interface-block]\n *      [type-declaration-stmt]\n *      [specification-stmt]\n *      [parameter-stmt] (is PARAMETER ( named-constant-def-list )\n *      [format-stmt]    (is FORMAT format-specification)\n *      [entry-stmt]\n *      [stmt-function-stmt]\n */\nstatic bool parseDeclarationConstruct (tokenInfo *const token)\n{\n\tbool result = true;\n\tswitch (token->keyword)\n\t{\n\t\tcase KEYWORD_entry:\t\tparseEntryStmt (token);      break;\n\t\tcase KEYWORD_interface:\tparseInterfaceBlock (token); break;\n\t\tcase KEYWORD_enum:      parseEnumBlock (token);      break;\n\t\tcase KEYWORD_stdcall:   readToken (token);           break;\n\t\t/* derived type handled by parseTypeDeclarationStmt(); */\n\n\t\tcase KEYWORD_abstract:\n\t\t\treadToken (token);\n\t\t\tif (isKeyword (token, KEYWORD_interface))\n\t\t\t\tparseInterfaceBlock (token);\n\t\t\telse\n\t\t\t\tskipToNextStatement (token);\n\t\t\tresult = true;\n\t\t\tbreak;\n\n\t\tcase KEYWORD_automatic:\n\t\t\treadToken (token);\n\t\t\tif (isTypeSpec (token))\n\t\t\t\tparseTypeDeclarationStmt (token);\n\t\t\telse\n\t\t\t\tskipToNextStatement (token);\n\t\t\tresult = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tif (isIgnoredDeclaration (token))\n\t\t\t\tskipToNextStatement (token);\n\t\t\telse if (isTypeSpec (token))\n\t\t\t{\n\t\t\t\tparseTypeDeclarationStmt (token);\n\t\t\t\tresult = true;\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\tresult = parseStmtFunctionStmt (token);\n\t\t\telse\n\t\t\t\tresult = parseSpecificationStmt (token);\n\t\t\tbreak;\n\t}\n\treturn result;\n}\n\n/*  implicit-part-stmt\n *      is [implicit-stmt] (is IMPLICIT etc.)\n *      or [parameter-stmt] (is PARAMETER etc.)\n *      or [format-stmt] (is FORMAT etc.)\n *      or [entry-stmt] (is ENTRY entry-name etc.)\n */\nstatic bool parseImplicitPartStmt (tokenInfo *const token)\n{\n\tbool result = true;\n\tswitch (token->keyword)\n\t{\n\t\tcase KEYWORD_entry: parseEntryStmt (token); break;\n\n\t\tcase KEYWORD_implicit:\n\t\tcase KEYWORD_include:\n\t\tcase KEYWORD_parameter:\n\t\tcase KEYWORD_format:\n\t\t\tskipToNextStatement (token);\n\t\t\tbreak;\n\n\t\tdefault: result = false; break;\n\t}\n\treturn result;\n}\n\n/*  specification-part is\n *      [use-stmt] ... (is USE module-name etc.)\n *      [implicit-part] (is [implicit-part-stmt] ... [implicit-stmt])\n *      [declaration-construct] ...\n */\nstatic bool parseSpecificationPart (tokenInfo *const token)\n{\n\tbool result = false;\n\twhile (skipStatementIfKeyword (token, KEYWORD_use))\n\t\tresult = true;\n\twhile (skipStatementIfKeyword (token, KEYWORD_import))\n\t\tresult = true;\n\twhile (parseImplicitPartStmt (token))\n\t\tresult = true;\n\twhile (parseDeclarationConstruct (token))\n\t\tresult = true;\n\treturn result;\n}\n\n/*  block-data is\n *      block-data-stmt (is BLOCK DATA [block-data-name]\n *          [specification-part]\n *          end-block-data-stmt (is END [BLOCK DATA [block-data-name]])\n */\nstatic void parseBlockData (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_block));\n\treadToken (token);\n\tif (isKeyword (token, KEYWORD_data))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\tmakeFortranTag (token, TAG_BLOCK_DATA);\n\t}\n\tancestorPush (token);\n\tskipToNextStatement (token);\n\tparseSpecificationPart (token);\n\twhile (! isKeyword (token, KEYWORD_end) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t\tskipToNextStatement (token);\n\treadSubToken (token);\n\t/* secondary token should be KEYWORD_NONE or KEYWORD_block token */\n\tskipToNextStatement (token);\n\tancestorPop ();\n}\n\n/*  internal-subprogram-part is\n *      contains-stmt (is CONTAINS)\n *          internal-subprogram\n *          [internal-subprogram] ...\n *\n *  internal-subprogram\n *      is function-subprogram\n *      or subroutine-subprogram\n */\nstatic void parseInternalSubprogramPart (tokenInfo *const token)\n{\n\tbool done = false;\n\tif (isKeyword (token, KEYWORD_contains))\n\t\tskipToNextStatement (token);\n\tdo\n\t{\n\t\tswitch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_function:\n\t\t\tcase KEYWORD_subroutine: parseSubprogram (token); break;\n\t\t\tcase KEYWORD_end:        done = true;             break;\n\n\t\t\tdefault:\n\t\t\t\tif (isSubprogramPrefix (token))\n\t\t\t\t\treadToken (token);\n\t\t\t\telse if (isTypeSpec (token))\n\t\t\t\t\tparseTypeSpec (token);\n\t\t\t\telse\n\t\t\t\t\treadToken (token);\n\t\t\t\tbreak;\n\t\t}\n\t} while (! done && ! isType (token, TOKEN_EOF));\n}\n\n/* submodule is\n *     submodule-stmt (is SUBMODULE ( parent-identifier ) submodule-name)\n *          [specification-part]\n *          [module-subprogram-part]\n *          end-submodule-stmt (is END [SUBMODULE [submodule-name]])\n *\n * parent-identifier is\n *     ancestor_module_name [ : parent_submodule_name ]*\n *\n * ------------------------------------------------------------------\n * XL Fortran for AIX, V15.1.3\n * Language Reference\n * Program units and procedures\n *   https://www.ibm.com/support/knowledgecenter/en/SSGH4D_15.1.3/com.ibm.xlf1513.aix.doc/language_ref/submodules.html\n * -------------------------------------------------------------------\n */\nstatic vString *parserParentIdentifierOfSubmoduleStatement (tokenInfo *const token)\n{\n\tvString *parentId;\n\n\tif (!isType (token, TOKEN_PAREN_OPEN))\n\t\treturn NULL;\n\n\tparentId = vStringNew();\n\n\twhile (1)\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\tvStringCat (parentId, token->string);\n\t\telse if (isType (token, TOKEN_COLON))\n\t\t\tvStringPut (parentId, ':');\n\t\telse if (isType (token, TOKEN_PAREN_CLOSE))\n\t\t\tbreak;\n\t\telse\n\t\t{\n\t\t\t/* Unexpected token (including EOF) */\n\t\t\tvStringClear (parentId);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (vStringLength (parentId) == 0)\n\t{\n\t\tvStringDelete (parentId);\n\t\tparentId = NULL;\n\t}\n\treturn parentId;\n}\n\n/*  module is\n *      module-stmt (is MODULE module-name)\n *          [specification-part]\n *          [module-subprogram-part]\n *          end-module-stmt (is END [MODULE [module-name]])\n *\n *  module-subprogram-part\n *      contains-stmt (is CONTAINS)\n *          module-subprogram\n *          [module-subprogram] ...\n *\n *  module-subprogram\n *      is function-subprogram\n *      or subroutine-subprogram\n */\nstatic void parseModule (tokenInfo *const token, bool isSubmodule)\n{\n\tvString *parentIdentifier = NULL;\n\n\tAssert (((!isSubmodule) && isKeyword (token, KEYWORD_module))\n\t\t\t|| (isSubmodule && isKeyword (token, KEYWORD_submodule)));\n\n\n\tif (isSubmodule)\n\t{\n\t\treadToken (token);\n\t\tparentIdentifier = parserParentIdentifierOfSubmoduleStatement (token);\n\t\tif (parentIdentifier == NULL)\n\t\t{\n\t\t\t/* Unexpected syntax */\n\t\t\tskipToNextStatement (token);\n\t\t\treturn;\n\t\t}\n\t}\n\n\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))\n\t{\n\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\tif (isSubmodule)\n\t\t{\n\t\t\tattachParentType (token, parentIdentifier);\n\t\t\tparentIdentifier = NULL;\n\t\t}\n\t\tmakeFortranTag (token, isSubmodule? TAG_SUBMODULE: TAG_MODULE);\n\t}\n\tancestorPush (token);\n\tskipToNextStatement (token);\n\tparseSpecificationPart (token);\n\tif (isKeyword (token, KEYWORD_contains))\n\t\tparseInternalSubprogramPart (token);\n\twhile (! isKeyword (token, KEYWORD_end) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t\tskipToNextStatement (token);\n\treadSubToken (token);\n\t/* secondary token should be KEYWORD_NONE or KEYWORD_module token */\n\tskipToNextStatement (token);\n\tancestorPop ();\n\n\tif (parentIdentifier)\n\t\tvStringDelete (parentIdentifier);\n}\n\n/*  execution-part\n *      executable-construct\n *\n *  executable-construct is\n *      execution-part-construct [execution-part-construct]\n *\n *  execution-part-construct\n *      is executable-construct\n *      or format-stmt\n *      or data-stmt\n *      or entry-stmt\n */\nstatic bool parseExecutionPart (tokenInfo *const token)\n{\n\tbool result = false;\n\tbool done = false;\n\twhile (! done && ! isType (token, TOKEN_EOF))\n\t{\n\t\tswitch (token->keyword)\n\t\t{\n\t\t\tdefault:\n\t\t\t\tif (isSubprogramPrefix (token))\n\t\t\t\t\treadToken (token);\n\t\t\t\telse\n\t\t\t\t\tskipToNextStatement (token);\n\t\t\t\tresult = true;\n\t\t\t\tbreak;\n\n\t\t\tcase KEYWORD_entry:\n\t\t\t\tparseEntryStmt (token);\n\t\t\t\tresult = true;\n\t\t\t\tbreak;\n\n\t\t\tcase KEYWORD_contains:\n\t\t\tcase KEYWORD_function:\n\t\t\tcase KEYWORD_subroutine:\n\t\t\t\tdone = true;\n\t\t\t\tbreak;\n\n\t\t\tcase KEYWORD_end:\n\t\t\t\treadSubToken (token);\n\t\t\t\tif (isSecondaryKeyword (token, KEYWORD_do) ||\n\t\t\t\t\tisSecondaryKeyword (token, KEYWORD_enum) ||\n\t\t\t\t\tisSecondaryKeyword (token, KEYWORD_if) ||\n\t\t\t\t\tisSecondaryKeyword (token, KEYWORD_select) ||\n\t\t\t\t\tisSecondaryKeyword (token, KEYWORD_where) ||\n\t\t\t\t\tisSecondaryKeyword (token, KEYWORD_forall) ||\n\t\t\t\t\tisSecondaryKeyword (token, KEYWORD_associate) ||\n\t\t\t\t\tisSecondaryKeyword (token, KEYWORD_block))\n\t\t\t\t{\n\t\t\t\t\tskipToNextStatement (token);\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tdone = true;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treturn result;\n}\n\nstatic void makeSignature (tokenInfo *const token, void* signature)\n{\n\tif (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))\n\t\tvStringCat ((vString *)signature, token->string);\n\telse if (isType (token, TOKEN_COMMA))\n\t\tvStringCatS ((vString *)signature, \", \");\n}\n\nstatic vString* parseSignature (tokenInfo *const token)\n{\n\tvString* signature = vStringNew ();\n\n\treadToken (token);\n\tif (isType (token, TOKEN_PAREN_OPEN))\n\t{\n\t\tvStringPut (signature, '(');\n\t\tskipOverParensFull (token, makeSignature, signature);\n\t\tvStringPut (signature, ')');\n\t}\n\treturn signature;\n}\n\nstatic void parseSubprogramFull (tokenInfo *const token, const tagType tag)\n{\n\tAssert (isKeyword (token, KEYWORD_program) ||\n\t\t\tisKeyword (token, KEYWORD_function) ||\n\t\t\tisKeyword (token, KEYWORD_subroutine));\n\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))\n\t{\n\t\ttokenInfo* name = newTokenFrom (token);\n\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\tif (tag == TAG_SUBROUTINE ||\n\t\t\ttag == TAG_PROTOTYPE)\n\t\t\tname->signature = parseSignature (token);\n\t\tmakeFortranTag (name, tag);\n\t\tancestorPush (name);\n\t\tdeleteToken (name);\n\t}\n\telse\n\t\tancestorPush (token);\n\tskipToNextStatement (token);\n\tparseSpecificationPart (token);\n\tparseExecutionPart (token);\n\tif (isKeyword (token, KEYWORD_contains))\n\t\tparseInternalSubprogramPart (token);\n\t/* should be at KEYWORD_end token */\n\treadSubToken (token);\n\t/* secondary token should be one of KEYWORD_NONE, KEYWORD_program,\n\t * KEYWORD_function, KEYWORD_function\n\t */\n\tskipToNextStatement (token);\n\tancestorPop ();\n}\n\nstatic tagType subprogramTagType (tokenInfo *const token)\n{\n\ttagType result = TAG_UNDEFINED;\n\n\tif (insideInterface ())\n\t\tresult = TAG_PROTOTYPE;\n\telse if (isKeyword (token, KEYWORD_subroutine))\n\t\tresult = TAG_SUBROUTINE;\n\telse if (isKeyword (token, KEYWORD_function))\n\t\tresult = TAG_FUNCTION;\n\n\tAssert (result != TAG_UNDEFINED);\n\n\treturn result;\n}\n\n/*  function-subprogram is\n *      function-stmt (is [prefix] FUNCTION function-name etc.)\n *          [specification-part]\n *          [execution-part]\n *          [internal-subprogram-part]\n *          end-function-stmt (is END [FUNCTION [function-name]])\n *\n *  prefix\n *      is type-spec [RECURSIVE]\n *      or [RECURSIVE] type-spec\n */\n/*  subroutine-subprogram is\n *      subroutine-stmt (is [RECURSIVE] SUBROUTINE subroutine-name etc.)\n *          [specification-part]\n *          [execution-part]\n *          [internal-subprogram-part]\n *          end-subroutine-stmt (is END [SUBROUTINE [function-name]])\n */\nstatic void parseSubprogram (tokenInfo *const token)\n{\n\tparseSubprogramFull (token, subprogramTagType (token));\n}\n\n/*  main-program is\n *      [program-stmt] (is PROGRAM program-name)\n *          [specification-part]\n *          [execution-part]\n *          [internal-subprogram-part ]\n *          end-program-stmt\n */\nstatic void parseMainProgram (tokenInfo *const token)\n{\n\tparseSubprogramFull (token, TAG_PROGRAM);\n}\n\n/*  program-unit\n *      is main-program\n *      or external-subprogram (is function-subprogram or subroutine-subprogram)\n *      or module\n *      or block-data\n */\nstatic void parseProgramUnit (tokenInfo *const token)\n{\n\treadToken (token);\n\tdo\n\t{\n\t\tif (isType (token, TOKEN_STATEMENT_END))\n\t\t\treadToken (token);\n\t\telse switch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_block:      parseBlockData (token);            break;\n\t\t\tcase KEYWORD_end:        skipToNextStatement (token);       break;\n\t\t\tcase KEYWORD_function:\n\t\t\tcase KEYWORD_subroutine: parseSubprogram (token);           break;\n\t\t\tcase KEYWORD_submodule:  parseModule (token, true);         break;\n\t\t\tcase KEYWORD_module:     parseModule (token, false);        break;\n\t\t\tcase KEYWORD_program:    parseMainProgram (token);          break;\n\n\t\t\tdefault:\n\t\t\t\tif (isSubprogramPrefix (token))\n\t\t\t\t\treadToken (token);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbool one = parseSpecificationPart (token);\n\t\t\t\t\tbool two = parseExecutionPart (token);\n\t\t\t\t\tif (! (one || two))\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t} while (! isType (token, TOKEN_EOF));\n}\n\nstatic rescanReason findFortranTags (const unsigned int passCount)\n{\n\ttokenInfo *token;\n\trescanReason rescan;\n\n\tAssert (passCount <= MAX_PASS);\n\ttoken = newToken ();\n\n\tcurrentPass = (fortranPass)passCount;\n\tif (currentPass == INIT_PASS)\n\t\tUngetc = '\\0';\n\tif (inFreeSourceForm)\n\t\tFree.newline = true;\n\tif (inFixedSourceForm)\n\t{\n\t\tFixed.column = 0;\n\t\tFixed.freeSourceFormFound = false;\n\t}\n\n\tparseProgramUnit (token);\n\tif (inFixedSourceForm && Fixed.freeSourceFormFound)\n\t{\n\t\tverbose (\"%s: not fixed source form; retry as free source form\\n\",\n\t\t\t\tgetInputFileName ());\n\t\trescan = RESCAN_FAILED;\n\t}\n\telse\n\t{\n\t\trescan = RESCAN_NONE;\n\t}\n\tancestorClear ();\n\tdeleteToken (token);\n\n\treturn rescan;\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_fortran = language;\n}\n\nextern parserDefinition* FortranParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"f\", \"for\", \"ftn\", \"f77\", \"f90\", \"f95\", \"f03\", \"f08\", \"f15\",\n#ifndef CASE_INSENSITIVE_FILENAMES\n\t\t\"F\", \"FOR\", \"FTN\", \"F77\", \"F90\", \"F95\", \"F03\", \"F08\", \"F15\",\n#endif\n\t\tNULL\n\t};\n\tstatic selectLanguage selectors[] = { selectFortranOrForthByForthMarker,\n\t\t\t\t\t      NULL };\n\n\tparserDefinition* def = parserNew (\"Fortran\");\n\tdef->kindTable      = FortranKinds;\n\tdef->kindCount  = ARRAY_SIZE (FortranKinds);\n\tdef->extensions = extensions;\n\tdef->parser2    = findFortranTags;\n\tdef->initialize = initialize;\n\tdef->keywordTable = FortranKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (FortranKeywordTable);\n\tdef->xtagTable  = FortranXtagTable;\n\tdef->xtagCount  = ARRAY_SIZE(FortranXtagTable);\n\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\tdef->selectLanguage = selectors;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/frontmatter.c",
    "content": "/*\n*\n*   Copyright (c) 2022, Masatake YAMATO\n*   Copyright (c) 2022, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n* This module contains functions for extracting language objects in FrontMatter.\n*\n* https://gohugo.io/content-management/front-matter\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include \"x-frontmatter.h\"\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"promise.h\"\n#include \"read.h\"\n\n#include <string.h>\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic kindDefinition FrontMatterKinds [] = {\n\t{ true, 't', \"title\", \"titles\", },\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nstatic void findFrontMatterTags (void)\n{\n\tconst unsigned char *line = readLineFromInputFile ();\n\n\tif (line == NULL)\n\t\treturn;\n\n#ifdef HAVE_LIBYAML\n\tif (strcmp(\"---\", (const char *)line) == 0)\n\t{\n\t\tline = readLineFromInputFile ();\n\t\tif (line)\n\t\t{\n\t\t\tunsigned long endOffset = strlen((const char *)line);\n\t\t\tlong startLineNum = getInputLineNumber ();\n\t\t\twhile ((line = readLineFromInputFile()))\n\t\t\t\tendOffset = strlen((const char *)line);\n\n\t\t\tlong endLineNum = getInputLineNumber ();\n\n\t\t\tmakePromise (\"YamlFrontMatter\", startLineNum, 0,\n\t\t\t\t\t\t endLineNum, endOffset, startLineNum);\n\t\t}\n\t\treturn;\n\t}\n#endif\n}\n\nextern parserDefinition* FrontMatterParser (void)\n{\n\tparserDefinition* def = parserNew (\"FrontMatter\");\n\tdef->kindTable      = FrontMatterKinds;\n\tdef->kindCount  = ARRAY_SIZE (FrontMatterKinds);\n\n\tdef->parser     = findFrontMatterTags;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/fypp.c",
    "content": "/*\n *   Copyright (c) 2018 Masatake YAMATO\n *   Copyright (c) 2018 Red Hat, Inc.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions to generate tags for Fypp, a Python powered\n *   Fortran preprocessor.\n *   See: https://github.com/aradi/fypp\n */\n\n#include \"general.h\"  /* must always come first */\n\n#include \"ctags.h\"\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"numarray.h\"\n#include \"param.h\"\n#include \"parse.h\"\n#include \"promise.h\"\n#include \"read.h\"\n#include \"trace.h\"\n\n#include <string.h>\n\ntypedef enum {\n\tK_MACRO\n} fyppKind;\n\nstatic kindDefinition FyppKinds[] = {\n\t{ true, 'm', \"macro\", \"macros\" },\n};\n\n/* TODO\n   If \"guest\" extra is disabled, we can reduce the codes to be processed. */\n\nstruct fyppParseCtx {\n\tint macro_cork_index;\n\n\t/* Areas surrounded by Fypp directive should be masked with white\n\t   spaces when running a guest parser like Fortran parser.\n\n\t   in_fypp_area field counts the depth of areas. Zero means the\n\t   current line is not part of a Fypp area; the line should passed\n\t   as is to the guest parser. Otherwise it should not.\n\n\t   #:if/#:elif/#:else/#:endif areas are handled in a special way.\n\t   #:if areas are passed to the guest parser.\n\t   #:elif/#:else/#:endif areas are not.\n\t   This approach follows what CPreProcessor parser does.\n\t   Quoted from ctags.1 man page:\n\n\t   If a preprocessor conditional is encountered within a statement\n\t   which defines a tag, ctags follows only the first branch of\n\t   that conditional (except in the special case of \"#if 0\", in\n\t   which case it follows only the last branch).\n\n\t   About the behavior about \"#if 0\" is not applicable to Fypp parser.\n\t   if_tracker is for tracking \"the first branch of that conditional\".\n\t   A scalar value is not enough to track the branch because branches\n\t   can be nested:\n\n\t   #:if COND0\n\t   ***\n\t   #:if COND1\n\t   ***\n\t   #:else\n\t   ...\n\t   #:endif\n\t   ...\n\t   #:else\n\t   ...\n\t   #:endif\n\n\t   In the above example, Fypp parser passes only `***` lines to the\n\t   guest parser.\n\n\t   if_tracker field tracks the branches. When the parser enters #:if area,\n\t   it appends 1 to if_tracker. When it enters #:elif or #:else area,\n\t   it repalces 1 with 0. When it reaches at #:endif, remove the last\n\t   element from the field. The product of if_tracker should be either\n\t   0 or 1. In the case that the product is 1, we can say the current line\n\t   is in the first if block.\n\n\t   if_cont field is for tracking '&' at the end of #:if directive lines.\n\t   If it is true, the last line is ended with &. We can know the\n\t   current line is part of Fypp directive that should not be\n\t   passed to the guest parser.\n\n\t   other_cont field has the same purpose as if_cont but\n\t   other_cont is for the other directives than #:if.\n\t*/\n\tint in_fypp_area;\n\tintArray *if_tracker;\n\tbool if_cont;\n\tbool other_cont;\n\n\t/* fypp_lines field records the line numbers for masking. */\n\tulongArray *fypp_lines;\n};\n\nstatic vString *fyppGuestParser;\n\nstatic bool fypp_does_line_continue(const char *line,\n\t\t\t\t\t\t\t\t\tconst regexMatch *matches)\n{\n\tif (matches[0].length == 0)\n\t\treturn false;\n\treturn *(line + matches[0].start + matches[0].length - 1) == '&';\n}\n\nstatic bool fypp_start_cb(const char *line,\n\t\t\t\t\t\t  const regexMatch *matches,\n\t\t\t\t\t\t  unsigned int count,\n\t\t\t\t\t\t  void *userData)\n{\n\tstruct fyppParseCtx *ctx = userData;\n\n\tTRACE_PRINT_PREFIX();\n\tTRACE_PRINT_FMT(\"%04d - %s\", getInputLineNumber(), line);\n\n\tulongArrayAdd (ctx->fypp_lines,\n\t\t\t\t   getInputLineNumber());\n\tctx->in_fypp_area++;\n\tctx->if_cont = false;\n\tctx->other_cont = false;\n\n\treturn true;\n}\n\nstatic bool fypp_end_cb(const char *line,\n\t\t\t\t\t\tconst regexMatch *matches,\n\t\t\t\t\t\tunsigned int count,\n\t\t\t\t\t\tvoid *userData)\n{\n\tstruct fyppParseCtx *ctx = userData;\n\n\tTRACE_PRINT_PREFIX();\n\tTRACE_PRINT_FMT(\"%04d - %s\", getInputLineNumber(), line);\n\n\tulongArrayAdd (ctx->fypp_lines,\n\t\t\t\t   getInputLineNumber());\n\tctx->in_fypp_area--;\n\tctx->if_cont = false;\n\tctx->other_cont = false;\n\n\treturn true;\n}\n\nstatic bool fypp_line_cb (const char *line,\n\t\t\t\t\t\t  const regexMatch *matches,\n\t\t\t\t\t\t  unsigned int count,\n\t\t\t\t\t\t  void *userData)\n{\n\tstruct fyppParseCtx *ctx = userData;\n\n\tTRACE_PRINT_PREFIX();\n\tTRACE_PRINT_FMT(\"%04d - %s\", getInputLineNumber(), line);\n\n\tulongArrayAdd (ctx->fypp_lines,\n\t\t\t\t   getInputLineNumber());\n\tctx->if_cont = false;\n\tctx->other_cont = fypp_does_line_continue (line, matches);\n\n\treturn true;\n}\n\nstatic bool macro_start_cb (const char *line,\n\t\t\t\t\t\t\tconst regexMatch *matches,\n\t\t\t\t\t\t\tunsigned int count,\n\t\t\t\t\t\t\tvoid *userData)\n{\n\tstruct fyppParseCtx *ctx = userData;\n\tvString *macro = NULL;\n\tvString *signature = NULL;\n\n\tif (count > 0)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tmacro = vStringNew ();\n\t\tvStringNCopyS (macro,\n\t\t\t\t\t   line + matches[1].start,\n\t\t\t\t\t   matches[1].length);\n\n\t\tinitTagEntry (&e, vStringValue (macro), K_MACRO);\n\n\t\tif (count > 1)\n\t\t{\n\t\t\tsignature = vStringNew ();\n\t\t\tvStringNCopyS (signature,\n\t\t\t\t\t\t   line + matches[2].start,\n\t\t\t\t\t\t   matches[2].length);\n\t\t\te.extensionFields.signature = vStringValue (signature);\n\t\t}\n\n\t\tctx->macro_cork_index = makeTagEntry (&e);\n\t}\n\n\tif (macro)\n\t\tvStringDelete (macro);\n\tif (signature)\n\t\tvStringDelete (signature);\n\n\tfypp_start_cb (line, matches, count, userData);\n\treturn true;\n}\n\nstatic bool macro_end_cb (const char *line,\n\t\t\t\t\t\t  const regexMatch *matches,\n\t\t\t\t\t\t  unsigned int count,\n\t\t\t\t\t\t  void *userData)\n{\n\tstruct fyppParseCtx *ctx = userData;\n\n\tsetTagEndLineToCorkEntry (ctx->macro_cork_index, getInputLineNumber ());\n\tctx->macro_cork_index = CORK_NIL;\n\n\tfypp_end_cb (line, matches, count, userData);\n\treturn true;\n}\n\nstatic bool if_start_cb (const char *line,\n\t\t\t\t\t\t const regexMatch *matches,\n\t\t\t\t\t\t unsigned int count,\n\t\t\t\t\t\t void *userData)\n{\n\tstruct fyppParseCtx *ctx = userData;\n\n\tif (ctx->if_tracker == NULL)\n\t\tctx->if_tracker = intArrayNew ();\n\n\tintArrayAdd (ctx->if_tracker, 1);\n\n\tfypp_start_cb (line, matches, count, userData);\n\n\tctx->if_cont = fypp_does_line_continue (line, matches);\n\tTRACE_PRINT(\"(count: %d, len: %d, ifCont: %d)\",\n\t\t\t\tcount, matches[1].length, ctx->if_cont);\n\n\treturn true;\n}\n\nstatic bool if_else_cb (const char *line,\n\t\t\t\t\t\tconst regexMatch *matches,\n\t\t\t\t\t\tunsigned int count,\n\t\t\t\t\t\tvoid *userData)\n{\n\tstruct fyppParseCtx *ctx = userData;\n\n\tif (ctx->if_tracker)\n\t{\n\t\tintArrayRemoveLast (ctx->if_tracker);\n\t\tintArrayAdd (ctx->if_tracker, 0);\n\t}\n\n\tfypp_line_cb(line, matches, count, userData);\n\treturn true;\n}\n\nstatic bool if_end_cb (const char *line,\n\t\t\t\t\t   const regexMatch *matches,\n\t\t\t\t\t   unsigned int count,\n\t\t\t\t\t   void *userData)\n{\n\tstruct fyppParseCtx *ctx = userData;\n\n\tif (ctx->if_tracker)\n\t{\n\t\tintArrayRemoveLast (ctx->if_tracker);\n\n\t\tif (intArrayCount(ctx->if_tracker) == 0)\n\t\t{\n\t\t\tintArrayDelete (ctx->if_tracker);\n\t\t\tctx->if_tracker = NULL;\n\t\t}\n\t}\n\n\tfypp_end_cb (line, matches, count, userData);\n\treturn true;\n}\n\nstatic bool is_in_first_if_block (struct fyppParseCtx *ctx)\n{\n\tint r = 1;\n\n\tfor (unsigned int i = 0; i < intArrayCount (ctx->if_tracker); i++)\n\t\tr *= intArrayItem(ctx->if_tracker, i);\n\n\treturn r;\n}\n\nstatic bool non_fypp_line_cb (const char *line,\n\t\t\t\t\t\t\t  const regexMatch *matches,\n\t\t\t\t\t\t\t  unsigned int count,\n\t\t\t\t\t\t\t  void *userData)\n{\n\tstruct fyppParseCtx *ctx = userData;\n\n\tif ((ctx->in_fypp_area > 0 && ((!ctx->if_tracker)\n\t\t\t\t\t\t\t\t  || (! is_in_first_if_block (ctx))\n\t\t\t\t\t\t\t\t  || ctx->if_cont))\n\t\t|| ctx->other_cont )\n\t{\n\t\tulongArrayAdd (ctx->fypp_lines,\n\t\t\t\t\t   getInputLineNumber());\n\n\t\tTRACE_PRINT_PREFIX();\n\t\tTRACE_PRINT_FMT(\"%04d - %s\", getInputLineNumber(), line);\n\t\tTRACE_PRINT_PREFIX();\n\t\tTRACE_PRINT_FMT(\"(inFyppArea: %d, ifTracker: %p, inFirstIfBlock: %d, ifCont: %d otherCont: %d/ \",\n\t\t\t\t\t\tctx->in_fypp_area, ctx->if_tracker,\n\t\t\t\t\t\tctx->if_tracker? is_in_first_if_block (ctx): -1,\n\t\t\t\t\t\tctx->if_cont,\n\t\t\t\t\t\tctx->other_cont);\n#ifdef DO_TRACING\n\t\tif (ctx->if_tracker)\n\t\t{\n\t\t\tfor (int i = 0; i < intArrayCount (ctx->if_tracker); i++)\n\t\t\t\tTRACE_PRINT_FMT(\"%d \", intArrayItem(ctx->if_tracker, i));\n\t\t}\n#endif\t/* DO_TRACING */\n\t\tTRACE_PRINT_FMT(\")\");\n\t\tTRACE_PRINT_NEWLINE();\n\n\t\tbool continued = fypp_does_line_continue(line, matches);\n\t\tif (ctx->if_cont)\n\t\t{\n\t\t\tctx->if_cont = continued;\n\t\t\tTRACE_PRINT(\"(ifCont <= %d)\", ctx->if_cont);\n\t\t}\n\t\tif (ctx->other_cont)\n\t\t{\n\t\t\tctx->other_cont = continued;\n\t\t\tTRACE_PRINT(\"(otherCont <= %d)\", ctx->other_cont);\n\t\t}\n\t}\n\telse\n\t{\n\t\tTRACE_PRINT_PREFIX();\n\t\tTRACE_PRINT_FMT(\"%04d + %s\", getInputLineNumber(), line);\n\t\tTRACE_PRINT_PREFIX();\n\t\tTRACE_PRINT_FMT(\"(inFyppArea: %d, ifTracker: %p, ifCont: %d / \",\n\t\t\t\t\t\tctx->in_fypp_area, ctx->if_tracker,\n\t\t\t\t\t\tctx->if_cont);\n\t\tTRACE_PRINT_FMT(\")\");\n\t\tTRACE_PRINT_NEWLINE();\n\t}\n\n\treturn true;\n}\n\n\nstatic struct fyppParseCtx parseCtx;\n\nstatic void findFyppTags (void)\n{\n\tint promise;\n\n\tparseCtx.macro_cork_index = CORK_NIL;\n\tparseCtx.if_tracker = NULL;\n\n\tif (fyppGuestParser)\n\t\tparseCtx.fypp_lines = ulongArrayNew ();\n\n\tfindRegexTags ();\n\n\n\tif (fyppGuestParser)\n\t{\n\t\tpromise = makePromise (vStringValue(fyppGuestParser),\n\t\t\t\t\t\t\t   1, 0,\n\t\t\t\t\t\t\t   getInputLineNumber(), EOL_COLUMN,\n\t\t\t\t\t\t\t   0);\n\t\tif (promise >= 0)\n\t\t\tpromiseAttachLineFiller (promise, parseCtx.fypp_lines);\n\t\telse\n\t\t\tulongArrayDelete (parseCtx.fypp_lines);\n\t}\n\n\tif (parseCtx.if_tracker)\n\t{\n\t\tintArrayDelete (parseCtx.if_tracker);\n\t\tparseCtx.if_tracker = NULL;\n\t}\n}\n\nstatic void initializeFyppParser (langType language)\n{\n\taddLanguageCallbackRegex (language,  \"^[ \\t]*#:[ \\t]*def[ \\t]*([a-zA-Z][a-zA-Z0-9_]*)[ \\t]*(\\\\(.*\\\\))\",\n\t\t\t\t\t\t\t  \"{exclusive}\", macro_start_cb, NULL, &parseCtx);\n\taddLanguageCallbackRegex (language,  \"^[ \\t]*#:[ \\t]*enddef[ \\t]*([a-zA-Z][a-zA-Z0-9_]*)[ \\t]*$\",\n\t\t\t\t\t\t\t  \"{exclusive}\", macro_end_cb, NULL, &parseCtx);\n\taddLanguageCallbackRegex (language,  \"^[ \\t]*#:[ \\t]*for[ \\t].*$\",\n\t\t\t\t\t\t\t  \"{exclusive}\", fypp_start_cb, NULL, &parseCtx);\n\taddLanguageCallbackRegex (language,  \"^[ \\t]*#:[ \\t]*endfor.*$\",\n\t\t\t\t\t\t\t  \"{exclusive}\", fypp_end_cb, NULL, &parseCtx);\n\taddLanguageCallbackRegex (language,  \"^[ \\t]*#:[ \\t]*call[ \\t].*$\",\n\t\t\t\t\t\t\t  \"{exclusive}\", fypp_start_cb, NULL, &parseCtx);\n\taddLanguageCallbackRegex (language,  \"^[ \\t]*#:[ \\t]*endcall.*$\",\n\t\t\t\t\t\t\t  \"{exclusive}\", fypp_end_cb, NULL, &parseCtx);\n\n\taddLanguageCallbackRegex (language,  \"^[ \\t]*#:[ \\t]*if[ \\t].*$\",\n\t\t\t\t\t\t\t  \"{exclusive}\", if_start_cb, NULL, &parseCtx);\n\taddLanguageCallbackRegex (language,  \"^[ \\t]*#:[ \\t]*el(se|if)[ \\t].*$\",\n\t\t\t\t\t\t\t  \"{exclusive}\", if_else_cb, NULL, &parseCtx);\n\taddLanguageCallbackRegex (language,  \"^[ \\t]*#:[ \\t]*endif.*\",\n\t\t\t\t\t\t\t  \"{exclusive}\", if_end_cb, NULL, &parseCtx);\n\n\taddLanguageCallbackRegex (language,  \"^[ \\t]*(#!|[#@$]:).*$\",\n\t\t\t\t\t\t\t  \"{exclusive}\", fypp_line_cb, NULL, &parseCtx);\n\taddLanguageCallbackRegex (language,  \"^.*$\",\n\t\t\t\t\t\t\t  \"{exclusive}\", non_fypp_line_cb, NULL, &parseCtx);\n}\n\nstatic void finalizeFyppParser (langType language, bool initialized)\n{\n\tif (fyppGuestParser)\n\t{\n\t\tvStringDelete (fyppGuestParser);\n\t\tfyppGuestParser = NULL;\n\t}\n}\n\nstatic bool fyppSetGuestParser (const langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\tconst char *optname CTAGS_ATTR_UNUSED, const char *arg)\n{\n\tif (!strcmp (arg, RSV_NONE))\n\t{\n\t\tif (fyppGuestParser)\n\t\t{\n\t\t\tvStringDelete (fyppGuestParser);\n\t\t\tfyppGuestParser = NULL;\n\t\t}\n\t\treturn true;\n\t}\n\n\tlangType lang = getNamedLanguage (arg, strlen(arg));\n\tif (lang == LANG_IGNORE)\n\t\terror (FATAL, \"Unknown language: %s\", arg);\n\n\tif (fyppGuestParser)\n\t\tvStringClear(fyppGuestParser);\n\telse\n\t\tfyppGuestParser = vStringNew();\n\tvStringCatS (fyppGuestParser, arg);\n\n\treturn true;\n}\n\nstatic paramDefinition FyppParams [] = {\n\t{\n\t\t.name = \"guest\",\n\t\t.desc = \"parser run after Fypp parser parses the original input (\\\"NONE\\\" or a parser name [Fortran])\" ,\n\t\t.handleParam = fyppSetGuestParser,\n\t},\n};\n\nextern parserDefinition* FyppParser (void)\n{\n\tstatic const char *const extensions [] = { \"fy\", NULL };\n\tparserDefinition* const def = parserNew (\"Fypp\");\n\tdef->kindTable = FyppKinds;\n\tdef->kindCount = ARRAY_SIZE (FyppKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findFyppTags;\n\tdef->initialize = initializeFyppParser;\n\tdef->finalize   = finalizeFyppParser;\n\tdef->method     = METHOD_REGEX;\n\n\tdef->paramTable = FyppParams;\n\tdef->paramCount = ARRAY_SIZE(FyppParams);\n\n\tdef->useCork = CORK_QUEUE;\n\n\tfyppGuestParser = vStringNewInit (\"Fortran\");\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/gdscript.c",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*   Copyright (c) 2014-2016, Colomban Wendling <ban@herbesfolles.org>\n*\tCopyright (c) 2021, David Yang <davidyang6us@gmail.com>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for GDScript language\n*   files. This module is derived from the Python module.\n*\n*\tGDScript language reference:\n*\thttps://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/gdscript_basics.html\n*\thttps://docs.godotengine.org/en/stable/development/file_formats/gdscript_grammar.html#doc-gdscript-grammar\n*\thttps://godotengine.org/article/gdscript-progress-report-new-gdscript-now-merged\n*\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"nestlevel.h\"\n#include \"read.h\"\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"keyword.h\"\n#include \"routines.h\"\n#include \"debug.h\"\n#include \"xtag.h\"\n#include \"objpool.h\"\n#include \"strlist.h\"\n\n#define isIdentifierChar(c) \\\n\t(isalnum (c) || (c) == '_' || (c) >= 0x80)\n#define newToken() (objPoolGet (TokenPool))\n#define deleteToken(t) (objPoolPut (TokenPool, (t)))\n\nenum {\n\tKEYWORD_class,\n\tKEYWORD_func,\n\tKEYWORD_extends,\n\tKEYWORD_pass,\n\tKEYWORD_return,\n\tKEYWORD_lambda,\n\tKEYWORD_variable,\n\tKEYWORD_const,\n\tKEYWORD_enum,\n\tKEYWORD_class_name,\n\tKEYWORD_signal,\n\tKEYWORD_modifier,\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum {\n\tACCESS_PRIVATE,\n\tACCESS_PROTECTED,\n\tACCESS_PUBLIC,\n\tCOUNT_ACCESS\n} accessType;\n\nstatic const char *const GDScriptAccesses[COUNT_ACCESS] = {\n\t\"private\",\n\t\"protected\",\n\t\"public\"\n};\n\ntypedef enum {\n\tF_ANNOTATIONS,\n\tCOUNT_FIELD\n} gdscriptField;\n\nstatic fieldDefinition GDScriptFields[COUNT_FIELD] = {\n\t{ .name = \"annotations\",\n\t  .description = \"annotations on functions and variables\",\n\t  .enabled = true },\n};\n\ntypedef enum {\n\tK_CLASS,\n\tK_METHOD,\n\tK_VARIABLE,\n\tK_CONST,\n\tK_ENUM,\n\tK_ENUMERATOR,\n\tK_PARAMETER,\n\tK_LOCAL_VARIABLE,\n\tK_SIGNAL,\n\tCOUNT_KIND\n} gdscriptKind;\n\ntypedef enum {\n\tGDSCRIPT_CLASS_EXTENDED,\n} gdscriptClassRole;\n\nstatic roleDefinition GDScriptClassRoles [] = {\n\t{ true, \"extended\",   \"used as a base class for extending\" },\n};\n\nstatic kindDefinition GDScriptKinds[COUNT_KIND] = {\n\t{true, 'c', \"class\",\t\"classes\",\n\t .referenceOnly = false, ATTACH_ROLES(GDScriptClassRoles)},\n\t{true, 'm', \"method\",\t\"methods\"},\n\t{true, 'v', \"variable\",\t\"variables\"},\n\t{true, 'C', \"const\", \"constants\"},\n\t{true, 'g', \"enum\",\t\"enumeration names\"},\n\t{true, 'e', \"enumerator\",\t\"enumerated values\"},\n\t{false,'z', \"parameter\",\t\"function parameters\"},\n\t{false,'l', \"local\",\t\"local variables\"},\n\t{true, 's', \"signal\",   \"signals\"},\n};\n\ntypedef enum {\n\tX_IMPLICIT_CLASS,\n} gdscriptXtag;\n\nstatic xtagDefinition GDScriptXtagTable [] = {\n\t{\n\t\t.enabled     = false,\n\t\t.name        = \"implicitClass\",\n\t\t.description = \"Include tag for the implicitly defined unnamed class\",\n\t},\n};\n\nstatic const keywordTable GDScriptKeywordTable[] = {\n\t/* keyword\t\t\tkeyword ID */\n\t{ \"class\",\t\t\tKEYWORD_class\t\t\t},\n\t{ \"func\",\t\t\tKEYWORD_func\t\t\t},\n\t{ \"extends\",\t\tKEYWORD_extends\t\t\t},\n\t{ \"lambda\",\t\t\tKEYWORD_lambda\t\t\t}, // Future GDScript lambda currently uses func, may change\n\t{ \"pass\",\t\t\tKEYWORD_pass\t\t\t},\n\t{ \"return\",\t\t\tKEYWORD_return\t\t\t},\n\t{ \"var\",\t\t\tKEYWORD_variable\t\t},\n\t{ \"const\",\t\t\tKEYWORD_const\t\t\t},\n\t{ \"enum\",\t\t\tKEYWORD_enum\t\t\t},\n\t{ \"class_name\",\t\tKEYWORD_class_name\t\t},\n\t{ \"signal\",\t\t\tKEYWORD_signal\t\t\t},\n\n};\n\nstatic const struct keywordGroup modifierKeywords = {\n\t.value = KEYWORD_modifier,\n\t.addingUnlessExisting = false,\n\t.keywords = {\n\t\t\"static\",\n\t\t\"remote\", \"remotesync\",\n\t\t\"master\", \"mastersycn\",\n\t\t\"puppet\", \"puppetsync\",\n\t\tNULL,\n\t},\n};\n\ntypedef enum eTokenType {\n\t/* 0..255 are the byte's value */\n\tTOKEN_EOF = 256,\n\tTOKEN_UNDEFINED,\n\tTOKEN_INDENT,\n\tTOKEN_KEYWORD,\n\tTOKEN_OPERATOR,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n\tTOKEN_ARROW,\t\t\t\t/* -> */\n\tTOKEN_WHITESPACE,\n} tokenType;\n\ntypedef struct {\n\tint\t\t\t\ttype;\n\tkeywordId\t\tkeyword;\n\tvString *\t\tstring;\n\tint\t\t\t\tindent;\n\tunsigned long\tlineNumber;\n\tMIOPos\t\t\tfilePosition;\n} tokenInfo;\n\nstruct gdscriptNestingLevelUserData {\n\tint indentation;\n};\n#define GDS_NL(nl) ((struct gdscriptNestingLevelUserData *) nestingLevelGetUserData (nl))\n\nstatic langType Lang_gdscript;\nstatic unsigned int TokenContinuationDepth = 0;\nstatic tokenInfo *NextToken = NULL;\nstatic NestingLevels *GDScriptNestingLevels = NULL;\nstatic objPool *TokenPool = NULL;\n\n\n// Always reports single-underscores as protected\nstatic accessType accessFromIdentifier (const vString *const ident, int parentKind)\n{\n\tconst char *const p = vStringValue (ident);\n\tconst size_t len = vStringLength (ident);\n\n\t/* inside a function/method, private */\n\tif (parentKind != -1 && parentKind != K_CLASS)\n\t\treturn ACCESS_PRIVATE;\n\t/* not starting with \"_\", public */\n\telse if (len < 1 || p[0] != '_')\n\t\treturn ACCESS_PUBLIC;\n\t/* \"_...\": suggested as non-public, but easily accessible */\n\telse\n\t\treturn ACCESS_PROTECTED;\n}\n\nstatic void initGDScriptEntry (tagEntryInfo *const e, const tokenInfo *const token,\n\t\t\t\t\t\t\t const gdscriptKind kind)\n{\n\taccessType access;\n\tint parentKind = -1;\n\tNestingLevel *nl;\n\n\tinitTagEntry (e, vStringValue (token->string), kind);\n\tupdateTagLine (e, token->lineNumber, token->filePosition);\n\n\tnl = nestingLevelsGetCurrent (GDScriptNestingLevels);\n\tif (nl)\n\t{\n\t\ttagEntryInfo *nlEntry = getEntryOfNestingLevel (nl);\n\n\t\te->extensionFields.scopeIndex = nl->corkIndex;\n\n\t\t/* nlEntry can be NULL if a kind was disabled.  But what can we do\n\t\t * here?  Even disabled kinds should count for the hierarchy I\n\t\t * guess -- as it'd otherwise be wrong -- but with cork we're\n\t\t * fucked up as there's nothing to look up.  Damn. */\n\t\tif (nlEntry)\n\t\t\tparentKind = nlEntry->kindIndex;\n\t}\n\n\taccess = accessFromIdentifier (token->string, parentKind);\n\te->extensionFields.access = GDScriptAccesses[access];\n\t/* FIXME: should we really set isFileScope in addition to access? */\n\tif (access == ACCESS_PRIVATE)\n\t\te->isFileScope = true;\n}\n\nstatic int makeClassTag (const tokenInfo *const token,\n\t\t\t\t\t\t const vString *const inheritance)\n{\n\tif (GDScriptKinds[K_CLASS].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitGDScriptEntry (&e, token, K_CLASS);\n\n\t\te.extensionFields.inheritance = inheritance ? vStringValue (inheritance) : \"\";\n\n\t\treturn makeTagEntry (&e);\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic vString *makeDecoratorString (const stringList *const strlist)\n{\n\tvString *vstr = vStringNew ();\n\n\tfor (unsigned int i = 0; i < stringListCount (strlist); i++)\n\t{\n\t\tvString *elt = stringListItem (strlist, i);\n\t\tif (i != 0 && (vStringValue (elt) > 0\n\t\t\t\t\t   && vStringValue (elt)[0] != '('))\n\t\t\tvStringPut (vstr, ',');\n\t\tvStringCat (vstr, elt);\n\t}\n\treturn vstr;\n}\n\nstatic int makeFunctionTag (const tokenInfo *const token,\n\t\t\t\t\t\t\tint kind,\n\t\t\t\t\t\t\tconst vString *const arglist,\n\t\t\t\t\t\t\tconst stringList *const decorators)\n{\n\tif (GDScriptKinds[kind].enabled)\n\t{\n\t\ttagEntryInfo e;\n\t\tvString *vstr = NULL;\n\t\tint r;\n\n\t\tinitGDScriptEntry (&e, token, kind);\n\n\t\tif (arglist)\n\t\t\te.extensionFields.signature = vStringValue (arglist);\n\t\tif (decorators && stringListCount (decorators) > 0)\n\t\t{\n\t\t\tvstr = makeDecoratorString (decorators);\n\t\t\tattachParserField (&e, GDScriptFields[F_ANNOTATIONS].ftype,\n\t\t\t\t\t\t\t   vStringValue (vstr));\n\t\t}\n\n\t\tr = makeTagEntry (&e);\n\t\tvStringDelete (vstr);\t/* NULL is ignored. */\n\n\t\treturn r;\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic int makeSimpleGDScriptTag (const tokenInfo *const token, gdscriptKind const kind)\n{\n\tif (GDScriptKinds[kind].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitGDScriptEntry (&e, token, kind);\n\t\treturn makeTagEntry (&e);\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic int makeSimpleGDScriptRefTag (const tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t gdscriptKind const kind,\n\t\t\t\t\t\t\t\t\t int roleIndex, xtagType xtag)\n{\n\tif (isXtagEnabled (XTAG_REFERENCE_TAGS))\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitRefTagEntry (&e, vStringValue (token->string),\n\t\t\t\t\t\t kind, roleIndex);\n\t\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\n\t\tif (xtag != XTAG_UNKNOWN)\n\t\t\tmarkTagExtraBit (&e, xtag);\n\n\t\treturn makeTagEntry (&e);\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic void *newPoolToken (void *createArg CTAGS_ATTR_UNUSED)\n{\n\ttokenInfo *token = xMalloc (1, tokenInfo);\n\ttoken->string = vStringNew ();\n\treturn token;\n}\n\nstatic void deletePoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\tvStringDelete (token->string);\n\teFree (token);\n}\n\nstatic void clearPoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->indent\t\t= 0;\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\tvStringClear (token->string);\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const src)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tdest->keyword = src->keyword;\n\tdest->indent = src->indent;\n\tvStringCopy (dest->string, src->string);\n}\n\n/* Skip a single or double quoted string. */\nstatic void readString (vString *const string, const int delimiter)\n{\n\tint escaped = 0;\n\tint c;\n\n\twhile ((c = getcFromInputFile ()) != EOF)\n\t{\n\t\tif (escaped)\n\t\t{\n\t\t\tvStringPut (string, c);\n\t\t\tescaped--;\n\t\t}\n\t\telse if (c == '\\\\')\n\t\t\tescaped++;\n\t\telse if (c == delimiter || c == '\\n' || c == '\\r')\n\t\t{\n\t\t\tif (c != delimiter)\n\t\t\t\tungetcToInputFile (c);\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\n/* Skip a single or double triple quoted string. */\nstatic void readTripleString (vString *const string, const int delimiter)\n{\n\tint c;\n\tint escaped = 0;\n\tint n = 0;\n\twhile ((c = getcFromInputFile ()) != EOF)\n\t{\n\t\tif (c == delimiter && ! escaped)\n\t\t{\n\t\t\tif (++n >= 3)\n\t\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (; n > 0; n--)\n\t\t\t\tvStringPut (string, delimiter);\n\t\t\tif (c != '\\\\' || escaped)\n\t\t\t\tvStringPut (string, c);\n\t\t\tn = 0;\n\t\t}\n\n\t\tif (escaped)\n\t\t\tescaped--;\n\t\telse if (c == '\\\\')\n\t\t\tescaped++;\n\t}\n}\n\nstatic void readIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t}\n\twhile (isIdentifierChar (c));\n\tungetcToInputFile (c);\n}\n\nstatic void ungetToken (tokenInfo *const token)\n{\n\tAssert (NextToken == NULL);\n\tNextToken = newToken ();\n\tcopyToken (NextToken, token);\n}\n\nstatic void readTokenFull (tokenInfo *const token, bool inclWhitespaces)\n{\n\tint c;\n\tint n;\n\n\t/* if we've got a token held back, emit it */\n\tif (NextToken)\n\t{\n\t\tcopyToken (token, NextToken);\n\t\tdeleteToken (NextToken);\n\t\tNextToken = NULL;\n\t\treturn;\n\t}\n\n\ttoken->type\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tn = 0;\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\tn++;\n\t}\n\twhile (c == ' ' || c == '\\t' || c == '\\f');\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tif (inclWhitespaces && n > 1 && c != '\\r' && c != '\\n')\n\t{\n\t\tungetcToInputFile (c);\n\t\tvStringPut (token->string, ' ');\n\t\ttoken->type = TOKEN_WHITESPACE;\n\t\treturn;\n\t}\n\n\tswitch (c)\n\t{\n\t\tcase EOF:\n\t\t\ttoken->type = TOKEN_EOF;\n\t\t\tbreak;\n\n\t\tcase '\\'':\n\t\tcase '\"':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tvStringPut (token->string, c);\n\t\t\tif (d != c)\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\treadString (token->string, c);\n\t\t\t}\n\t\t\telse if ((d = getcFromInputFile ()) == c)\n\t\t\t\treadTripleString (token->string, c);\n\t\t\telse /* empty string */\n\t\t\t\tungetcToInputFile (d);\n\t\t\tvStringPut (token->string, c);\n\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '=':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tvStringPut (token->string, c);\n\t\t\tif (d == c)\n\t\t\t{\n\t\t\t\tvStringPut (token->string, d);\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = c;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '-':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '>')\n\t\t\t{\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\tvStringPut (token->string, d);\n\t\t\t\ttoken->type = TOKEN_ARROW;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tungetcToInputFile (d);\n\t\t\t/* fall through */\n\t\t}\n\t\tcase '+':\n\t\tcase '*':\n\t\tcase '%':\n\t\tcase '<':\n\t\tcase '>':\n\t\tcase '/':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tvStringPut (token->string, c);\n\t\t\tif (d != '=')\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = c;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvStringPut (token->string, d);\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t/* eats newline to implement line continuation  */\n\t\tcase '\\\\':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '\\r')\n\t\t\t\td = getcFromInputFile ();\n\t\t\tif (d != '\\n')\n\t\t\t\tungetcToInputFile (d);\n\t\t\tgoto getNextChar;\n\t\t}\n\n\t\tcase '#': /* comment */\n\t\tcase '\\r': /* newlines for indent */\n\t\tcase '\\n':\n\t\t{\n\t\t\tint indent = 0;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tif (c == '#')\n\t\t\t\t{\n\t\t\t\t\tdo\n\t\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t\twhile (c != EOF && c != '\\r' && c != '\\n');\n\t\t\t\t}\n\t\t\t\tif (c == '\\r')\n\t\t\t\t{\n\t\t\t\t\tint d = getcFromInputFile ();\n\t\t\t\t\tif (d != '\\n')\n\t\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\t}\n\t\t\t\tindent = 0;\n\t\t\t\twhile ((c = getcFromInputFile ()) == ' ' || c == '\\t' || c == '\\f')\n\t\t\t\t{\n\t\t\t\t\tif (c == '\\t')\n\t\t\t\t\t\tindent += 8 - (indent % 8);\n\t\t\t\t\telse if (c == '\\f') /* yeah, it's weird */\n\t\t\t\t\t\tindent = 0;\n\t\t\t\t\telse\n\t\t\t\t\t\tindent++;\n\t\t\t\t}\n\t\t\t} /* skip completely empty lines, so retry */\n\t\t\twhile (c == '\\r' || c == '\\n' || c == '#');\n\t\t\tungetcToInputFile (c);\n\t\t\tif (TokenContinuationDepth > 0)\n\t\t\t{\n\t\t\t\tif (inclWhitespaces)\n\t\t\t\t{\n\t\t\t\t\tvStringPut (token->string, ' ');\n\t\t\t\t\ttoken->type = TOKEN_WHITESPACE;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_INDENT;\n\t\t\t\ttoken->indent = indent;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tif (! isIdentifierChar (c))\n\t\t\t{\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\ttoken->type = c;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* FIXME: handle U, B, R and F string prefixes? */\n\t\t\t\treadIdentifier (token->string, c);\n\t\t\t\ttoken->keyword = lookupKeyword (vStringValue (token->string), Lang_gdscript);\n\t\t\t\tif (token->keyword == KEYWORD_NONE)\n\t\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\telse\n\t\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\t// handle implicit continuation lines not to emit INDENT inside brackets\n\tif (token->type == '(' ||\n\t\ttoken->type == '{' ||\n\t\ttoken->type == '[')\n\t{\n\t\tTokenContinuationDepth ++;\n\t}\n\telse if (TokenContinuationDepth > 0 &&\n\t\t\t (token->type == ')' ||\n\t\t\t  token->type == '}' ||\n\t\t\t  token->type == ']'))\n\t{\n\t\tTokenContinuationDepth --;\n\t}\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\treadTokenFull (token, false);\n}\n\n/*================================= parsing =================================*/\n\n\nstatic void reprCat (vString *const repr, const tokenInfo *const token)\n{\n\tif (token->type != TOKEN_INDENT &&\n\t\ttoken->type != TOKEN_WHITESPACE)\n\t{\n\t\tvStringCat (repr, token->string);\n\t}\n\telse if (vStringLength (repr) > 0 && vStringLast (repr) != ' ')\n\t{\n\t\tvStringPut (repr, ' ');\n\t}\n}\n\nstatic bool skipOverPair (tokenInfo *const token, int tOpen, int tClose,\n\t\t\t\t\t\t  vString *const repr, bool reprOuterPair)\n{\n\tif (token->type == tOpen)\n\t{\n\t\tint depth = 1;\n\n\t\tif (repr && reprOuterPair)\n\t\t\treprCat (repr, token);\n\t\tdo\n\t\t{\n\t\t\treadTokenFull (token, true);\n\t\t\tif (repr && (reprOuterPair || token->type != tClose || depth > 1))\n\t\t\t{\n\t\t\t\treprCat (repr, token);\n\t\t\t}\n\t\t\tif (token->type == tOpen)\n\t\t\t\tdepth ++;\n\t\t\telse if (token->type == tClose)\n\t\t\t\tdepth --;\n\t\t}\n\t\twhile (token->type != TOKEN_EOF && depth > 0);\n\t}\n\n\treturn token->type == tClose;\n}\n\nstatic void readQualifiedName (tokenInfo *const nameToken)\n{\n\treadToken (nameToken);\n\n\tif (nameToken->type == TOKEN_IDENTIFIER ||\n\t\tnameToken->type == '.')\n\t{\n\t\tvString *qualifiedName = vStringNew ();\n\t\ttokenInfo *token = newToken ();\n\n\t\twhile (nameToken->type == TOKEN_IDENTIFIER ||\n\t\t\t   nameToken->type == '.')\n\t\t{\n\t\t\tvStringCat (qualifiedName, nameToken->string);\n\t\t\tcopyToken (token, nameToken);\n\n\t\t\treadToken (nameToken);\n\t\t}\n\t\t/* put the last, non-matching, token back */\n\t\tungetToken (nameToken);\n\n\t\tcopyToken (nameToken, token);\n\t\tnameToken->type = TOKEN_IDENTIFIER;\n\t\tvStringCopy (nameToken->string, qualifiedName);\n\n\t\tdeleteToken (token);\n\t\tvStringDelete (qualifiedName);\n\t}\n}\n\nstatic vString *parseParamTypeAnnotation (tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t\t  vString *arglist)\n{\n\treadToken (token);\n\tif (token->type != ':')\n\t{\n\t\tungetToken (token);\n\t\treturn NULL;\n\t}\n\n\treprCat (arglist, token);\n\tint depth = 0;\n\tvString *t = vStringNew ();\n\twhile (true)\n\t{\n\t\treadTokenFull (token, true);\n\t\tif (token->type == TOKEN_WHITESPACE)\n\t\t{\n\t\t\treprCat (arglist, token);\n\t\t\tcontinue;\n\t\t}\n\t\telse if (token->type == TOKEN_EOF)\n\t\t\tbreak;\n\n\t\tif (token->type == '(' ||\n\t\t\ttoken->type == '[' ||\n\t\t\ttoken->type == '{')\n\t\t\tdepth ++;\n\t\telse if (token->type == ')' ||\n\t\t\t\t token->type == ']' ||\n\t\t\t\t token->type == '}')\n\t\t\tdepth --;\n\n\t\tif (depth < 0\n\t\t\t|| (depth == 0 && (token->type == '='\n\t\t\t\t\t\t\t   || token->type == ',')))\n\t\t{\n\t\t\tungetToken (token);\n\t\t\treturn t;\n\t\t}\n\t\treprCat (arglist, token);\n\t\treprCat (t, token);\n\t}\n\tvStringDelete (t);\n\treturn NULL;\n}\n\nstatic vString *parseReturnTypeAnnotation (tokenInfo *const token)\n{\n\treadToken (token);\n\tif (token->type != TOKEN_ARROW)\n\t{\n\t\treturn NULL;\n\t}\n\n\tint depth = 0;\n\tvString *t = vStringNew ();\n\twhile (true)\n\t{\n\t\treadToken (token);\n\t\tif (token->type == TOKEN_EOF)\n\t\t\tbreak;\n\n\t\tif (token->type == '(' ||\n\t\t\ttoken->type == '[' ||\n\t\t\ttoken->type == '{')\n\t\t\tdepth ++;\n\t\telse if (token->type == ')' ||\n\t\t\t\t token->type == ']' ||\n\t\t\t\t token->type == '}')\n\t\t\tdepth --;\n\t\tif (depth == 0 && token->type == ':')\n\t\t{\n\t\t\tungetToken (token);\n\t\t\treturn t;\n\t\t}\n\t\telse\n\t\t\treprCat (t, token);\n\t}\n\tvStringDelete (t);\n\treturn NULL;\n}\n\nstatic bool parseClassOrDef (tokenInfo *const token,\n\t\t\t\t\t\t\t const stringList *const decorators,\n\t\t\t\t\t\t\t gdscriptKind kind)\n{\n\tvString *arglist = NULL;\n\ttokenInfo *name = NULL;\n\ttokenInfo *parameterTokens[16] = { NULL };\n\tvString   *parameterTypes [ARRAY_SIZE (parameterTokens)] = { NULL };\n\tunsigned int parameterCount = 0;\n\tNestingLevel *lv;\n\tint corkIndex;\n\n\treadToken (token);\n\tif (token->type != TOKEN_IDENTIFIER)\n\t\treturn false;\n\n\tname = newToken ();\n\tcopyToken (name, token);\n\n\treadToken (token);\n\t/* collect parameters or inheritance */\n\tif (token->type == '(')\n\t{\n\t\tint prevTokenType = token->type;\n\t\tint depth = 1;\n\n\t\targlist = vStringNew ();\n\t\tif (kind != K_CLASS)\n\t\t\treprCat (arglist, token);\n\n\t\tdo\n\t\t{\n\t\t\tif (token->type != TOKEN_WHITESPACE &&\n\t\t\t\ttoken->type != '*')\n\t\t\t{\n\t\t\t\tprevTokenType = token->type;\n\t\t\t}\n\n\t\t\treadTokenFull (token, true);\n\t\t\tif (kind != K_CLASS || token->type != ')' || depth > 1)\n\t\t\t\treprCat (arglist, token);\n\n\t\t\tif (token->type == '(' ||\n\t\t\t\ttoken->type == '[' ||\n\t\t\t\ttoken->type == '{')\n\t\t\t\tdepth ++;\n\t\t\telse if (token->type == ')' ||\n\t\t\t\t\t token->type == ']' ||\n\t\t\t\t\t token->type == '}')\n\t\t\t\tdepth --;\n\t\t\telse if (kind != K_CLASS && depth == 1 &&\n\t\t\t\t\t token->type == TOKEN_IDENTIFIER &&\n\t\t\t\t\t (prevTokenType == '(' || prevTokenType == ',') &&\n\t\t\t\t\t parameterCount < ARRAY_SIZE (parameterTokens) &&\n\t\t\t\t\t GDScriptKinds[K_PARAMETER].enabled)\n\t\t\t{\n\t\t\t\ttokenInfo *parameterName = newToken ();\n\n\t\t\t\tcopyToken (parameterName, token);\n\t\t\t\tparameterTokens[parameterCount] = parameterName;\n\t\t\t\tparameterTypes [parameterCount++] = parseParamTypeAnnotation (token, arglist);\n\t\t\t}\n\t\t}\n\t\twhile (token->type != TOKEN_EOF && depth > 0);\n\t}\n\telse if (token->type == TOKEN_KEYWORD && token->keyword == KEYWORD_extends)\n\t{\n\t\treadToken (token);\n\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t{\n\t\t\tmakeSimpleGDScriptRefTag (token, K_CLASS, GDSCRIPT_CLASS_EXTENDED, XTAG_UNKNOWN);\n\t\t\targlist = vStringNewCopy (token->string);\n\t\t}\n\t}\n\telse if (kind == K_SIGNAL)\n\t{\n\t\t/* signal can be defined with no parameter list. */\n\t\tungetToken (token);\n\t}\n\n\tif (kind == K_CLASS)\n\t\tcorkIndex = makeClassTag (name, arglist);\n\telse\n\t\tcorkIndex = makeFunctionTag (name, kind, arglist, decorators);\n\n\tlv = nestingLevelsPush (GDScriptNestingLevels, corkIndex);\n\tGDS_NL (lv)->indentation = token->indent;\n\n\tdeleteToken (name);\n\tvStringDelete (arglist);\n\n\tif (parameterCount > 0)\n\t{\n\t\tunsigned int i;\n\n\t\tfor (i = 0; i < parameterCount; i++)\n\t\t{\n\t\t\tint paramCorkIndex = makeSimpleGDScriptTag (parameterTokens[i], K_PARAMETER);\n\t\t\tdeleteToken (parameterTokens[i]);\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (paramCorkIndex);\n\t\t\tif (e && parameterTypes[i])\n\t\t\t{\n\t\t\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\t\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (parameterTypes[i]);\n\t\t\t\tparameterTypes[i] = NULL;\n\t\t\t}\n\t\t\tvStringDelete (parameterTypes[i]); /* NULL is acceptable. */\n\t\t}\n\t}\n\n\ttagEntryInfo *e;\n\tvString *t;\n\tif (kind != K_CLASS\n\t\t&& (e = getEntryInCorkQueue (corkIndex))\n\t\t&& (t = parseReturnTypeAnnotation (token)))\n\t{\n\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (t);\n\t}\n\n\tif (kind == K_SIGNAL)\n\t\tnestingLevelsPop (GDScriptNestingLevels);\n\n\treturn true;\n}\n\nstatic bool parseEnum (tokenInfo *const token)\n{\n\tint corkIndex;\n\n\treadToken (token);\n\n\tif (token->type == '{')\n\t{\n\t\ttokenInfo *name = newToken ();\n\t\tcopyToken (name, token);\n\t\tvStringClear (name->string);\n\t\tanonGenerate (name->string, \"anon_enum_\", K_ENUM);\n\t\tname->type = TOKEN_IDENTIFIER;\n\t\tcorkIndex = makeSimpleGDScriptTag (name, K_ENUM);\n\t\tdeleteToken (name);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\t\tif (e)\n\t\t\tmarkTagExtraBit (e, XTAG_ANONYMOUS);\n\t}\n\telse if (token->type == TOKEN_IDENTIFIER)\n\t{\n\t\tcorkIndex = makeSimpleGDScriptTag (token, K_ENUM);\n\t\treadToken (token);\n\t}\n\telse\n\t\treturn false;\n\n\tif (token->type != '{')\n\t\treturn false;\n\n\treadToken (token);\n\tnestingLevelsPush (GDScriptNestingLevels, corkIndex);\n\n\twhile (token->type != '}' && token->type != TOKEN_EOF)\n\t{\n\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t\tmakeSimpleGDScriptTag (token, K_ENUMERATOR);\n\t\telse if (token->type == '=')\n\t\t{\n\t\t\t/* Skip the right value. */\n\t\t\tdo\n\t\t\t\treadToken (token);\n\t\t\twhile (token->type != ','\n\t\t\t\t   && token->type != '}'\n\t\t\t\t   && token->type != TOKEN_EOF);\n\t\t\tif (token->type != ',')\n\t\t\t\tcontinue;\n\t\t}\n\t\treadToken (token);\n\t}\n\n\ttagEntryInfo *e;\n\tvString *t;\n\tif ((e = getEntryInCorkQueue (corkIndex))\n\t\t&& (t = parseReturnTypeAnnotation (token)))\n\t{\n\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (t);\n\t}\n\n\tnestingLevelsPop (GDScriptNestingLevels);\n\treturn true;\n}\n\nstatic bool parseClassName (tokenInfo *const token)\n{\n\treadToken (token);\n\tif (token->type == TOKEN_IDENTIFIER)\n\t{\n\t\t/* A class name is explicitly given with \"class_name\" keyword.\n\t\t * Let's overwrite the anonymous tag for the class\n\t\t */\n\t\tNestingLevel *nl = nestingLevelsGetNthFromRoot (GDScriptNestingLevels, 0);\n\t\ttagEntryInfo *klass = nl? getEntryInCorkQueue (nl->corkIndex): NULL;\n\n\t\ttagEntryInfo e;\n\t\tchar *name = vStringStrdup (token->string);\n\t\tinitTagEntry (&e, klass? \"UNUSED\": name, K_CLASS);\n\n\t\tif (klass)\n\t\t{\n\t\t\teFree ((void *)klass->name);\n\t\t\tklass->name = name;\n\t\t\tname = NULL;\n\t\t\tunmarkTagExtraBit (klass, XTAG_ANONYMOUS);\n\t\t\tunmarkTagExtraBit (klass, GDScriptXtagTable[X_IMPLICIT_CLASS].xtype);\n\n\t\t\t/* Adjust the position. */\n\t\t\tsetTagPositionFromTag (klass, &e);\n\t\t}\n\n\t\t/* Extract B in class_name C extends B */\n\t\treadToken (token);\n\t\tif (token->type == TOKEN_KEYWORD\n\t\t\t&& token->keyword == KEYWORD_extends)\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t\t{\n\t\t\t\tmakeSimpleGDScriptRefTag (token, K_CLASS,\n\t\t\t\t\t\t\t\t\t\t  GDSCRIPT_CLASS_EXTENDED,\n\t\t\t\t\t\t\t\t\t\t  XTAG_UNKNOWN);\n\t\t\t\tif (klass)\n\t\t\t\t{\n\t\t\t\t\tif (klass->extensionFields.inheritance)\n\t\t\t\t\t\teFree ((void *)klass->extensionFields.inheritance);\n\t\t\t\t\tklass->extensionFields.inheritance = vStringStrdup (token->string);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\te.extensionFields.inheritance = vStringValue (token->string);\n\t\t\t}\n\t\t}\n\n\t\tif (!klass)\n\t\t\tmakeTagEntry (&e);\n\n\t\tif (name)\n\t\t\teFree (name);\n\t}\n\n\twhile (token->type != TOKEN_EOF &&\n\t\t   token->type != ';' &&\n\t\t   token->type != TOKEN_INDENT)\n\t\treadToken (token);\n\n\treturn false;\n}\n\nstatic bool parseExtends (tokenInfo *const token)\n{\n\tif (token->keyword == KEYWORD_extends)\n\t{\n\t\treadQualifiedName (token);\n\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t{\n\t\t\tmakeSimpleGDScriptRefTag (token, K_CLASS, GDSCRIPT_CLASS_EXTENDED, XTAG_UNKNOWN);\n\t\t\tNestingLevel *nl = nestingLevelsGetCurrent (GDScriptNestingLevels);\n\t\t\tif (nl)\n\t\t\t{\n\t\t\t\ttagEntryInfo *klass = getEntryInCorkQueue (nl->corkIndex);\n\t\t\t\tif (klass)\n\t\t\t\t{\n\t\t\t\t\tif (klass->extensionFields.inheritance)\n\t\t\t\t\t\teFree ((void *)klass->extensionFields.inheritance);\n\t\t\t\t\tklass->extensionFields.inheritance = vStringStrdup (token->string);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treadToken (token);\n\treturn false;\n}\n\n/* this only handles the most common cases, but an annotation can be any\n * expression in theory.\n * this function assumes there must be an annotation, and doesn't do any check\n * on the token on which it is called: the caller should do that part. */\nstatic bool skipVariableTypeAnnotation (tokenInfo *const token, vString *const repr)\n{\n\tbool readNext = true;\n\n\treadToken (token);\n\tswitch (token->type)\n\t{\n\t\tcase '[': readNext = skipOverPair (token, '[', ']', repr, true); break;\n\t\tcase '(': readNext = skipOverPair (token, '(', ')', repr, true); break;\n\t\tcase '{': readNext = skipOverPair (token, '{', '}', repr, true); break;\n\t\tdefault: reprCat (repr, token);\n\t}\n\tif (readNext)\n\t\treadToken (token);\n\t/* skip subscripts and calls */\n\twhile (token->type == '[' || token->type == '(' || token->type == '.' || token->type == '|')\n\t{\n\t\tswitch (token->type)\n\t\t{\n\t\t\tcase '[': readNext = skipOverPair (token, '[', ']', repr, true); break;\n\t\t\tcase '(': readNext = skipOverPair (token, '(', ')', repr, true); break;\n\t\t\tcase '|':\n\t\t\t\treprCat (repr, token);\n\t\t\t\tskipVariableTypeAnnotation (token, repr);\n\t\t\t\treadNext = false;\n\t\t\t\tbreak;\n\t\t\tcase '.':\n\t\t\t\treprCat (repr, token);\n\t\t\t\treadToken (token);\n\t\t\t\treadNext = token->type == TOKEN_IDENTIFIER;\n\t\t\t\tif (readNext)\n\t\t\t\t\treprCat (repr, token);\n\t\t\t\tbreak;\n\t\t\tdefault:  readNext = false; break;\n\t\t}\n\t\tif (readNext)\n\t\t\treadToken (token);\n\t}\n\n\treturn false;\n}\n\nstatic bool parseVariable (tokenInfo *const token, const gdscriptKind kind,\n\t\t\t\t\t\t\tconst stringList *const decorators,\n\t\t\t\t\t\t\tconst int keyword)\n{\n\treadToken (token);\n\tvString *type = vStringNew ();\n\ttokenInfo *name = newToken ();\n\tcopyToken (name, token);\n\tif (!name)\n\t\treturn false;\n\n\treadToken (token);\n\t// Variable declarations with dotted names are illegal\n\tif (token->type == '.')\n\t\treturn false;\n\n\t/* (parse and) skip annotations.  we need not to be too permissive because we\n\t * aren't yet sure we're actually parsing a variable. */\n\tif (token->type == ':' && skipVariableTypeAnnotation (token, type))\n\t\treadToken (token);\n\n\tint index = makeSimpleGDScriptTag (name, kind);\n\tdeleteToken (name);\n\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\n\tif (e && decorators && stringListCount (decorators) > 0)\n\t{\n\t\tvString *vstr = makeDecoratorString (decorators);\n\t\tattachParserField (e, GDScriptFields[F_ANNOTATIONS].ftype,\n\t\t\t\t\t\t   vStringValue (vstr));\n\t\tvStringDelete (vstr);\n\t}\n\n\tvString *vtype = vStringNew ();\n\tchar * stype = vStringValue (type);\n\tif (strcmp (stype, \"=\") && strcmp (stype, \"\"))\n\t{\n\t\t\tvStringCatS (vtype, stype);\n\t}\n\tvStringDelete (type);\n\n\tif (e && vStringLength (vtype) > 0) /// TODO: Fix types away\n\t{\n\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (vtype);\n\t}\n\telse\n\t{\n\t\tvStringDelete (vtype);\n\t}\n\n\n\twhile ((TokenContinuationDepth > 0 || token->type != ',') &&\n\t\t   token->type != TOKEN_EOF &&\n\t\t   token->type != ';' &&\n\t\t   token->type != TOKEN_INDENT)\n\t{\n\t\treadToken (token);\n\t}\n\n\n\treturn false;\n}\n\n/* pops any level >= to indent */\nstatic void setIndent (tokenInfo *const token)\n{\n\tNestingLevel *lv = nestingLevelsGetCurrent (GDScriptNestingLevels);\n\n\twhile (lv && GDS_NL (lv)->indentation >= token->indent)\n\t{\n\t\tsetTagEndLineToCorkEntry (lv->corkIndex, token->lineNumber);\n\n\t\tnestingLevelsPop (GDScriptNestingLevels);\n\t\tlv = nestingLevelsGetCurrent (GDScriptNestingLevels);\n\t}\n}\n\nstatic int prepareUnnamedClass (struct NestingLevels *nls)\n{\n\t{\n\t\t/* Ugly: we need a \"position\" on the input stream for making a tag.\n\t\t * At the begining of parsing, the position is undefined.\n\t\t * By reading a byte, the position is defined.\n\t\t */\n\t\tint c = getcFromInputFile ();\n\t\tif (c == EOF)\n\t\t\treturn CORK_NIL;\n\t\tungetcToInputFile (c);\n\t}\n\n\tvString * tmp_class = anonGenerateNew (\"anon_class_\", K_CLASS);\n\tint corkIndex = makeSimpleTag (tmp_class, K_CLASS);\n\tvStringDelete (tmp_class);\n\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\tif (e)\n\t\tmarkTagExtraBit (e, XTAG_ANONYMOUS);\n\n\t/* This virtual scope should not be poped. */\n\tNestingLevel *lv = nestingLevelsPush (nls, corkIndex);\n\tGDS_NL (lv)->indentation = -1;\n\n\treturn corkIndex;\n}\n\nstatic void findGDScriptTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\tstringList *decorators = stringListNew ();\n\tbool atStatementStart = true;\n\n\tTokenContinuationDepth = 0;\n\tNextToken = NULL;\n\tGDScriptNestingLevels = nestingLevelsNew (sizeof (struct gdscriptNestingLevelUserData));\n\n\tif (isXtagEnabled (GDScriptXtagTable[X_IMPLICIT_CLASS].xtype))\n\t{\n\t\tint index = prepareUnnamedClass (GDScriptNestingLevels);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\tif (e)\n\t\t\tmarkTagExtraBit (e, GDScriptXtagTable[X_IMPLICIT_CLASS].xtype);\n\t}\n\n\treadToken (token);\n\twhile (token->type != TOKEN_EOF)\n\t{\n\t\ttokenType iterationTokenType = token->type;\n\t\tint iterationTokenKeyword = token->keyword;\n\t\tbool readNext = true;\n\n\t\tif (token->type == TOKEN_INDENT)\n\t\t\tsetIndent (token);\n\t\telse if (token->keyword == KEYWORD_class ||\n\t\t\t\t token->keyword == KEYWORD_func  ||\n\t\t\t\t token->keyword == KEYWORD_signal)\n\t\t{\n\t\t\tgdscriptKind kind = K_METHOD;\n\t\t\tswitch (token->keyword)\n\t\t\t{\n\t\t\tcase KEYWORD_class:  kind = K_CLASS;  break;\n\t\t\tcase KEYWORD_func:   kind = K_METHOD; break;\n\t\t\tcase KEYWORD_signal: kind = K_SIGNAL; break;\n\t\t\tdefault:\n\t\t\t\tAssertNotReached ();\n\t\t\t}\n\t\t\treadNext = parseClassOrDef (token, decorators, kind);\n\t\t}\n\t\telse if (token->keyword == KEYWORD_extends)\n\t\t{\n\t\t\treadNext = parseExtends (token);\n\t\t}\n\t\telse if (token->type == '(')\n\t\t{ /* skip parentheses to avoid finding stuff inside them */\n\t\t\treadNext = skipOverPair (token, '(', ')', NULL, false);\n\t\t}\n\t\telse if (token->keyword == KEYWORD_variable || token->keyword == KEYWORD_const)\n\t\t{\n\t\t\tNestingLevel *lv = nestingLevelsGetCurrent (GDScriptNestingLevels);\n\t\t\ttagEntryInfo *lvEntry = NULL;\n\t\t\tgdscriptKind kind = K_VARIABLE;\n\n\t\t\tif (lv)\n\t\t\t\tlvEntry = getEntryOfNestingLevel (lv);\n\n\t\t\tif (lvEntry && lvEntry->kindIndex != K_CLASS)\n\t\t\t\tkind = K_LOCAL_VARIABLE;\n\n\t\t\tif (token->keyword == KEYWORD_const)\n\t\t\t\tkind = K_CONST;\n\n\t\t\treadNext = parseVariable (token, kind, decorators, token->keyword);\n\t\t}\n\t\telse if (token->keyword == KEYWORD_enum)\n\t\t{\n\t\t\treadNext = parseEnum (token);\n\t\t}\n\t\telse if (token->keyword == KEYWORD_class_name)\n\t\t{\n\t\t\treadNext = parseClassName (token);\n\t\t}\n\t\telse if (token->type == TOKEN_KEYWORD\n\t\t\t\t && token->keyword == KEYWORD_modifier)\n\t\t{\n\t\t\tstringListAdd (decorators, vStringNewCopy (token->string));\n\t\t}\n\t\telse if (token->type == '@' && atStatementStart &&\n\t\t\t\t GDScriptFields[F_ANNOTATIONS].enabled)\n\t\t{\n\t\t\t/* collect decorators */\n\t\t\treadQualifiedName (token);\n\t\t\tif (token->type != TOKEN_IDENTIFIER\n\t\t\t\t&& (token->keyword != KEYWORD_modifier))\n\t\t\t\treadNext = false;\n\t\t\telse\n\t\t\t{\n\t\t\t\tstringListAdd (decorators, vStringNewCopy (token->string));\n\t\t\t\treadToken (token);\n\n\t\t\t\tvString *d = vStringNew ();\n\t\t\t\treadNext = skipOverPair (token, '(', ')', d, true);\n\t\t\t\tif (vStringLength (d) > 0)\n\t\t\t\t\tstringListAdd (decorators, d);\n\t\t\t\telse\n\t\t\t\t\tvStringDelete (d);\n\t\t\t}\n\t\t}\n\n\t\t/* clear collected decorators for any non-decorator tokens non-indent\n\t\t * token.  decorator collection takes care of skipping the possible\n\t\t * argument list, so we should never hit here parsing a decorator */\n\t\tif (iterationTokenType != TOKEN_INDENT &&\n\t\t\titerationTokenType != '@' &&\n\t\t\titerationTokenKeyword != KEYWORD_modifier &&\n\t\t\tGDScriptFields[F_ANNOTATIONS].enabled)\n\t\t{\n\t\t\tstringListClear (decorators);\n\t\t}\n\n\t\tatStatementStart = (token->type == TOKEN_INDENT || token->type == ';');\n\n\t\tif (readNext)\n\t\t\treadToken (token);\n\t}\n\n\tnestingLevelsFree (GDScriptNestingLevels);\n\tstringListDelete (decorators);\n\tdeleteToken (token);\n\tAssert (NextToken == NULL);\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_gdscript = language;\n\n\tTokenPool = objPoolNew (16, newPoolToken, deletePoolToken, clearPoolToken, NULL);\n\taddKeywordGroup (&modifierKeywords, language);\n}\n\nstatic void finalize (langType language CTAGS_ATTR_UNUSED, bool initialized)\n{\n\tif (!initialized)\n\t\treturn;\n\n\tobjPoolDelete (TokenPool);\n}\n\nextern parserDefinition* GDScriptParser (void)\n{\n\tstatic const char *const extensions[] = { \"gd\", NULL };\n\tparserDefinition *def = parserNew (\"GDScript\");\n\tdef->kindTable = GDScriptKinds;\n\tdef->kindCount = ARRAY_SIZE (GDScriptKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findGDScriptTags;\n\tdef->initialize = initialize;\n\tdef->finalize = finalize;\n\tdef->keywordTable = GDScriptKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (GDScriptKeywordTable);\n\tdef->fieldTable = GDScriptFields;\n\tdef->fieldCount = ARRAY_SIZE (GDScriptFields);\n\tdef->xtagTable = GDScriptXtagTable;\n\tdef->xtagCount = ARRAY_SIZE (GDScriptXtagTable);\n\tdef->useCork = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/gemspec.c",
    "content": "/*\n* A parser for RUBYGEM's specification\n*\n* Copyright (c) 2021, Red Hat, Inc.\n* Copyright (c) 2021, Masatake YAMATO\n*\n* Author: Masatake YAMATO <yamato@redhat.com>\n*\n* This program is free software; you can redistribute it and/or\n* modify it under the terms of the GNU General Public License\n* as published by the Free Software Foundation; either version 2\n* of the License, or (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program; if not, write to the Free Software\n* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n* USA.\n*\n* Reference:\n* - https://guides.rubygems.org/specification-reference/\n*\n* See also:\n* - https://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"subparser.h\"\n\n#include \"x-ruby.h\"\n\n#include <string.h>\n\n/*\n* DATA STRUCTURES\n*/\nstruct sGemSpecSubparser {\n\trubySubparser ruby;\n\tvString *var_name;\n};\n\ntypedef enum {\n\tK_GEM,\n} gemspecKind;\n\ntypedef enum {\n\tR_GEM_RUNTIME_DEP,\n\tR_GEM_DEVEL_DEP,\n} gemspecGemRole;\n\nstatic roleDefinition GemSpecGemRoles [] = {\n\t{ true, \"runtimeDep\", \"specifying runtime dependency\" },\n\t{ true, \"develDep\",   \"specifying development dependency\" },\n};\n\nstatic kindDefinition GemSpecKinds [] = {\n\t{ true, 'g', \"gem\", \"gems\",\n\t  .referenceOnly = false, ATTACH_ROLES(GemSpecGemRoles)},\n};\n\n/*\n* FUNCTIONS\n*/\nstatic void findGemSpecTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nstatic int lineNotify (rubySubparser *s, const unsigned char **cp, int corkIndex CTAGS_ATTR_UNUSED)\n{\n\tstruct sGemSpecSubparser *gemspec = (struct sGemSpecSubparser *)s;\n\tconst unsigned char *p = *cp;\n\n\tif (vStringLength (gemspec->var_name) > 0\n\t\t&& (strncmp ((char *)p, vStringValue (gemspec->var_name),\n\t\t\t\t\t vStringLength (gemspec->var_name)) == 0))\n\t{\n\t\tint kind = K_GEM;\n\t\tint role = ROLE_DEFINITION_INDEX;\n\t\tbool is_attr = true;\n\n\t\tp += vStringLength (gemspec->var_name);\n\n\t\tif (strncmp ((const char *)p, \"name\", 4) == 0)\n\t\t\tp += 4;\n\t\telse if (strncmp ((const char *)p, \"add_dependency\", 14) == 0)\n\t\t{\n\t\t\tp += 14;\n\t\t\trole = R_GEM_RUNTIME_DEP;\n\t\t\tis_attr = false;\n\t\t}\n\t\telse if (strncmp ((const char *)p, \"add_runtime_dependency\", 22) == 0)\n\t\t{\n\t\t\tp += 22;\n\t\t\trole = R_GEM_RUNTIME_DEP;\n\t\t\tis_attr = false;\n\t\t}\n\t\telse if (strncmp ((const char *)p, \"add_development_dependency\", 26) == 0)\n\t\t{\n\t\t\tp += 26;\n\t\t\trole = R_GEM_DEVEL_DEP;\n\t\t\tis_attr = false;\n\t\t}\n\t\telse\n\t\t\tp = NULL;\n\n\t\tif (p)\n\t\t{\n\t\t\trubySkipWhitespace (&p);\n\t\t\tif (is_attr == false || *p == '=')\n\t\t\t{\n\t\t\t\tif (*p == '(' || *p == '=')\n\t\t\t\t{\n\t\t\t\t\tp++;\n\t\t\t\t\trubySkipWhitespace (&p);\n\t\t\t\t}\n\t\t\t\tif (*p == '\"' || *p == '\\'')\n\t\t\t\t{\n\t\t\t\t\tunsigned char b = *p;\n\t\t\t\t\tvString *gem = vStringNew ();\n\t\t\t\t\tp++;\n\t\t\t\t\tif (rubyParseString (&p, b, gem))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (role == ROLE_DEFINITION_INDEX)\n\t\t\t\t\t\t\tmakeSimpleTag (gem, kind);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tmakeSimpleRefTag (gem, kind, role);\n\t\t\t\t\t}\n\t\t\t\t\tvStringDelete (gem);\n\t\t\t\t}\n\t\t\t\telse if (p [0] == '%')\n\t\t\t\t{\n\t\t\t\t\tvString *gem = vStringNew ();\n\t\t\t\t\tp++;\n\t\t\t\t\tif (rubyParsePercentString(&p, gem))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (role == ROLE_DEFINITION_INDEX)\n\t\t\t\t\t\t\tmakeSimpleTag (gem, kind);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tmakeSimpleRefTag (gem, kind, role);\n\t\t\t\t\t}\n\t\t\t\t\tvStringDelete (gem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\telse if (rubyCanMatchKeywordWithAssign (&p, \"Gem::Specification.new\"))\n\t{\n\t\tvString *vstr = vStringNew ();\n\t\tbool curly_bracket = false;\n\n\t\trubySkipWhitespace (&p);\n\n\t\tcurly_bracket = (*p == '{');\n\t\tif (curly_bracket\n\t\t\t|| (rubyParseMethodName (&p, vstr)\n\t\t\t\t&& vStringLength (vstr) == 2\n\t\t\t\t&& strcmp (vStringValue(vstr), \"do\") == 0))\n\t\t{\n\t\t\tif (curly_bracket)\n\t\t\t\tp++;\n\n\t\t\trubySkipWhitespace (&p);\n\t\t\tif (*p == '|')\n\t\t\t{\n\t\t\t\tp++;\n\t\t\t\trubySkipWhitespace (&p);\n\t\t\t\tvStringClear (vstr);\n\t\t\t\tif (rubyParseMethodName (&p, vstr))\n\t\t\t\t{\n\t\t\t\t\tvStringPut (vstr, '.');\n\t\t\t\t\tvStringCopy(gemspec->var_name, vstr);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvStringDelete (vstr);\n\t}\n\treturn CORK_NIL;\n}\n\nstatic void inputStart (subparser *s)\n{\n\tstruct sGemSpecSubparser *gemspec = (struct sGemSpecSubparser *)s;\n\n\tgemspec->var_name = vStringNew ();\n}\n\nstatic void inputEnd (subparser *s)\n{\n\tstruct sGemSpecSubparser *gemspec = (struct sGemSpecSubparser *)s;\n\n\tvStringDelete (gemspec->var_name); /* NULL is acceptable. */\n\tgemspec->var_name = NULL;\n}\n\nextern parserDefinition* GemSpecParser (void)\n{\n\tstatic const char *const extensions [] = { \"gemspec\", NULL };\n\tstatic struct sGemSpecSubparser gemspecSubparser = {\n\t\t.ruby = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t\t\t.inputStart = inputStart,\n\t\t\t\t.inputEnd = inputEnd,\n\t\t\t},\n\t\t\t.lineNotify = lineNotify,\n\t\t},\n\t\t.var_name = NULL,\n\t};\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Ruby\", &gemspecSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"GemSpec\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE(dependencies);\n\tdef->kindTable  = GemSpecKinds;\n\tdef->kindCount  = ARRAY_SIZE (GemSpecKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findGemSpecTags;\n\tdef->useCork    = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/glade.c",
    "content": "/*\n*\n*   Copyright (c) 2015, Masatake YAMATO\n*   Copyright (c) 2015, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for diff files (based on Sh parser).\n*/\n\n#include \"general.h\"\t/* must always come first */\n#include \"entry.h\"\n#include \"debug.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"x-xml.h\"\n\n\ntypedef enum {\n\tR_CLASS_WIDGET,\n} gladeClassRole;\n\ntypedef enum {\n\tR_HANDLER_HANDLER,\n} gladeHandleRoler;\n\nstatic roleDefinition GladeClassRoles [] = {\n\t{ true, \"widget\", \"specified as a widget constructor\" },\n};\n\nstatic roleDefinition GladeHandlerRoles [] = {\n\t{ true, \"handler\", \"specified as a callback for signal emission\" },\n};\n\ntypedef enum {\n\tK_CLASS, K_HANDLER,\n} gladeKind;\n\nstatic kindDefinition GladeKinds [] = {\n\t/* These two are appeared on names in C source code. */\n\t{ true,  'c', \"class\",\t  \"classes\",\n\t  .referenceOnly = true, ATTACH_ROLES (GladeClassRoles) },\n\t{ true,  'h', \"handler\",  \"handlers\",\n\t  .referenceOnly = true, ATTACH_ROLES (GladeHandlerRoles) },\n};\n\nstatic tagXpathTable gladeXpathMainTable[] = {\n\t{ \"///glade-interface//widget//@class\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_CLASS, R_CLASS_WIDGET } }\n\t},\n\t{ \"///glade-interface//signal//@handler\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_HANDLER, R_HANDLER_HANDLER }}\n\t},\n};\n\nenum gladeXpathTable {\n\tTABLE_MAIN\n};\n\nstatic tagXpathTableTable gladeXpathTableTable[] = {\n\t[TABLE_MAIN] = { ARRAY_AND_SIZE(gladeXpathMainTable) },\n};\n\nstatic void\nfindGladeTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\n\nstatic void\nrunXPathEngine(xmlSubparser *s,\n\t\t\t   xmlXPathContext *ctx, xmlNode *root)\n{\n\tfindXMLTags (ctx, root, TABLE_MAIN, NULL);\n}\n\nstatic xmlSubparser gladeSubparser = {\n\t.subparser = {\n\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t},\n\t.runXPathEngine = runXPathEngine,\n};\n\nextern parserDefinition*\nGladeParser (void)\n{\n\tstatic const char *const extensions [] = { \"glade\", NULL };\n\tparserDefinition* const def = parserNew (\"Glade\");\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"XML\", &gladeSubparser },\n\t};\n\n\tdef->kindTable         = GladeKinds;\n\tdef->kindCount     = ARRAY_SIZE (GladeKinds);\n\tdef->extensions    = extensions;\n\tdef->parser        = findGladeTags;\n\tdef->tagXpathTableTable  = gladeXpathTableTable;\n\tdef->tagXpathTableCount  = ARRAY_SIZE (gladeXpathTableTable);\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/go.c",
    "content": "/*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Reference:\n*     https://go.dev/ref/spec\n*/\n\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"        /* must always come first */\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n#include \"numarray.h\"\n#include \"objpool.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n#include \"field.h\"\n#include \"htable.h\"\n\n#include <string.h>\n\n/*\n *\t MACROS\n */\n#define MAX_COLLECTOR_LENGTH 512\n#define isType(token,t) (bool) ((token)->type == (t))\n#define isKeyword(token,k) (bool) ((token)->keyword == (k))\n#define isStartIdentChar(c) (isalpha (c) ||  (c) == '_' || (c) > 128) /* XXX UTF-8 */\n#define isIdentChar(c) (isStartIdentChar (c) || isdigit (c))\n#define newToken() (objPoolGet (TokenPool))\n#define deleteToken(t) (objPoolPut (TokenPool, (t)))\n\n/*\n *\t DATA DECLARATIONS\n */\n\nenum eKeywordId {\n\tKEYWORD_package,\n\tKEYWORD_import,\n\tKEYWORD_const,\n\tKEYWORD_type,\n\tKEYWORD_var,\n\tKEYWORD_func,\n\tKEYWORD_struct,\n\tKEYWORD_interface,\n\tKEYWORD_map,\n\tKEYWORD_chan\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum eTokenType {\n\tTOKEN_NONE = -1,\n\t// Token not important for top-level Go parsing\n\tTOKEN_OTHER,\n\tTOKEN_KEYWORD,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_SEMICOLON,\n\tTOKEN_STAR,\n\tTOKEN_LEFT_ARROW,\n\tTOKEN_DOT,\n\tTOKEN_COMMA,\n\tTOKEN_EQUAL,\n\tTOKEN_3DOTS,\n\tTOKEN_EOF\n} tokenType;\n\ntypedef struct sTokenInfo {\n\ttokenType type;\n\tkeywordId keyword;\n\tvString *string;\t\t/* the name of the token */\n\tunsigned long lineNumber;\t/* line number of tag */\n\tMIOPos filePosition;\t\t/* file position of line containing name */\n\tint c;\t\t\t\t\t\t/* Used in AppendTokenToVString */\n} tokenInfo;\n\ntypedef struct sCollector {\n\tvString *str;\n\tsize_t last_len;\n} collector;\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic int Lang_go;\nstatic objPool *TokenPool = NULL;\n\ntypedef enum {\n\tGOTAG_UNDEFINED = -1,\n\tGOTAG_PACKAGE,\n\tGOTAG_FUNCTION,\n\tGOTAG_CONST,\n\tGOTAG_TYPE,\n\tGOTAG_VAR,\n\tGOTAG_STRUCT,\n\tGOTAG_INTERFACE,\n\tGOTAG_MEMBER,\n\tGOTAG_ANONMEMBER,\n\tGOTAG_METHODSPEC,\n\tGOTAG_UNKNOWN,\n\tGOTAG_PACKAGE_NAME,\n\tGOTAG_TALIAS,\n\tGOTAG_RECEIVER,\n} goKind;\n\ntypedef enum {\n\tR_GOTAG_PACKAGE_IMPORTED,\n} GoPackageRole;\n\nstatic roleDefinition GoPackageRoles [] = {\n\t{ true, \"imported\", \"imported package\" },\n};\n\ntypedef enum {\n\tR_GOTAG_UNKNOWN_RECEIVER,\n} GoUnknownRole;\n\nstatic roleDefinition GoUnknownRoles [] = {\n\t{ true, \"receiverType\", \"receiver type\" },\n};\n\nstatic kindDefinition GoKinds[] = {\n\t{true, 'p', \"package\", \"packages\",\n\t  .referenceOnly = false, ATTACH_ROLES (GoPackageRoles)},\n\t{true, 'f', \"func\", \"functions\"},\n\t{true, 'c', \"const\", \"constants\"},\n\t{true, 't', \"type\", \"types\"},\n\t{true, 'v', \"var\", \"variables\"},\n\t{true, 's', \"struct\", \"structs\"},\n\t{true, 'i', \"interface\", \"interfaces\"},\n\t{true, 'm', \"member\", \"struct members\"},\n\t{true, 'M', \"anonMember\", \"struct anonymous members\"},\n\t{true, 'n', \"methodSpec\", \"interface method specification\"},\n\t{true, 'Y', \"unknown\", \"unknown\",\n\t .referenceOnly = true, ATTACH_ROLES (GoUnknownRoles)},\n\t{true, 'P', \"packageName\", \"name for specifying imported package\"},\n\t{true, 'a', \"talias\", \"type aliases\"},\n\t{false,'R', \"receiver\", \"receivers\"},\n};\n\nstatic const keywordTable GoKeywordTable[] = {\n\t{\"package\", KEYWORD_package},\n\t{\"import\", KEYWORD_import},\n\t{\"const\", KEYWORD_const},\n\t{\"type\", KEYWORD_type},\n\t{\"var\", KEYWORD_var},\n\t{\"func\", KEYWORD_func},\n\t{\"struct\", KEYWORD_struct},\n\t{\"interface\", KEYWORD_interface},\n\t{\"map\", KEYWORD_map},\n\t{\"chan\", KEYWORD_chan}\n};\n\ntypedef enum {\n\tF_PACKAGE,\n\tF_PACKAGE_NAME,\n\tF_HOW_IMPORTED,\n\tF_RECEIVER,\n} goField;\n\nstatic fieldDefinition GoFields [] = {\n\t{\n\t\t.name = \"package\",\n\t\t.description = \"the real package specified by the package name\",\n\t\t.enabled = true,\n\t},\n\t{\n\t\t.name = \"packageName\",\n\t\t.description = \"the name for referring the package\",\n\t\t.enabled = true,\n\t},\n\t{\n\t\t.name = \"howImported\",\n\t\t.description = \"how the package is imported (\\\"inline\\\" for `.' or \\\"init\\\" for `_')\",\n\t\t.enabled = false,\n\t},\n\t{\n\t\t.name = \"receiver\",\n\t\t.description = \"the name of the receiver\",\n\t\t.enabled = false,\n\t\t.version = 1,\n\t}\n};\n\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void *newPoolToken (void *createArg CTAGS_ATTR_UNUSED)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\ttoken->string = vStringNew ();\n\treturn token;\n}\n\nstatic void clearPoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\n\ttoken->type = TOKEN_NONE;\n\ttoken->keyword = KEYWORD_NONE;\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\tvStringClear (token->string);\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const other)\n{\n\tdest->type = other->type;\n\tdest->keyword = other->keyword;\n\tvStringCopy(dest->string, other->string);\n\tdest->lineNumber = other->lineNumber;\n\tdest->filePosition = other->filePosition;\n}\n\nstatic void deletePoolToken (void* data)\n{\n\ttokenInfo * const token = data;\n\n\tvStringDelete (token->string);\n\teFree (token);\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_go = language;\n\tTokenPool = objPoolNew (16, newPoolToken, deletePoolToken, clearPoolToken, NULL);\n}\n\nstatic void finalize (const langType language, bool initialized)\n{\n\tif (!initialized)\n\t\treturn;\n\n\tobjPoolDelete (TokenPool);\n}\n\n/*\n *   Parsing functions\n */\n\nstatic void parseString (vString *const string, const int delimiter)\n{\n\tbool end = false;\n\twhile (!end)\n\t{\n\t\tint c = getcFromInputFile ();\n\t\tif (c == EOF)\n\t\t\tend = true;\n\t\telse if (c == '\\\\' && delimiter != '`')\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c != '\\'' && c != '\\\"')\n\t\t\t\tvStringPut (string, '\\\\');\n\t\t\tvStringPut (string, c);\n\t\t}\n\t\telse if (c == delimiter)\n\t\t\tend = true;\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isIdentChar (c));\n\tungetcToInputFile (c);\t\t/* always unget, LF might add a semicolon */\n}\n\nstatic bool collectorIsEmpty(const collector *collector)\n{\n\treturn !vStringLength(collector->str);\n}\n\nstatic bool collectorCanAppend (const collector *collector,\n\t\t\t\t\t\t\t\tsize_t n_to_append)\n{\n\tsize_t current_len = vStringLength (collector->str);\n\tif (current_len >= MAX_COLLECTOR_LENGTH)\n\t\treturn false;\n\tif (n_to_append == 0)\n\t\treturn true;\n\tif (n_to_append > MAX_COLLECTOR_LENGTH)\n\t\treturn false;\n\treturn n_to_append <= MAX_COLLECTOR_LENGTH - current_len;\n}\n\nstatic void collectorPut (collector *collector, char c)\n{\n\tif ((vStringLength(collector->str) > 2)\n\t\t&& strcmp (vStringValue (collector->str) + (vStringLength(collector->str) - 3),\n\t\t\t\t  \"...\") == 0\n\t\t&& c == ' ')\n\t\treturn;\n\n\tif (vStringLength(collector->str) > 0)\n\t{\n\t\tif (vStringLast(collector->str) == '(' && c == ' ')\n\t\t\treturn;\n\t\tif (vStringLast(collector->str) == ' ' && c == ')')\n\t\t\tvStringChop(collector->str);\n\t}\n\n\tif (!collectorCanAppend (collector, 1))\n\t\treturn;\n\n\tcollector->last_len = vStringLength (collector->str);\n\tvStringPut (collector->str, c);\n}\n\nstatic void collectorCatS (collector *collector, const char *cstr)\n{\n\tsize_t cstr_len = strlen (cstr);\n\tif (cstr_len == 0)\n\t\treturn;\n\n\tif (!collectorCanAppend (collector, cstr_len))\n\t\treturn;\n\n\tcollector->last_len = vStringLength (collector->str);\n\tvStringNCatSUnsafe (collector->str, cstr, cstr_len);\n}\n\nstatic void collectorCat (collector *collector, const vString *str)\n{\n\tif (!collectorCanAppend (collector, vStringLength (str)))\n\t\treturn;\n\n\tcollector->last_len = vStringLength (collector->str);\n\tvStringCat (collector->str, str);\n}\n\nstatic void collectorAppendToken (collector *collector, const tokenInfo *const token)\n{\n\tif (token->type == TOKEN_LEFT_ARROW)\n\t\tcollectorCatS (collector, \"<-\");\n\telse if (token->type == TOKEN_STRING)\n\t{\n\t\t// only struct member annotations can appear in function prototypes\n\t\t// so only `` type strings are possible\n\t\tif (!collectorCanAppend (collector,\n\t\t\t\t\t\t\t\t vStringLength (token->string) + 2))\n\t\t\treturn;\n\t\tcollector->last_len = vStringLength (collector->str);\n\t\tvStringPut(collector->str, '`');\n\t\tvStringCat(collector->str, token->string);\n\t\tvStringPut(collector->str, '`');\n\t}\n\telse if (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_KEYWORD)\n\t\tcollectorCat (collector, token->string);\n\telse if (token->type == TOKEN_3DOTS)\n\t{\n\t\tif ((vStringLength (collector->str) > 0)\n\t\t\t&& vStringLast(collector->str) != ' ')\n\t\t\tcollectorPut (collector, ' ');\n\t\tcollectorCatS (collector, \"...\");\n\t}\n\telse if (token->c != EOF)\n\t\tcollectorPut (collector, token->c);\n}\n\nstatic void collectorTruncate (collector *collector, bool dropLast)\n{\n\tif (dropLast)\n\t\tvStringTruncate (collector->str, collector->last_len);\n\n\tvStringStripLeading (collector->str);\n\tvStringStripTrailing (collector->str);\n}\n\nstatic void collectorReset (collector *collector)\n{\n\tif (collector->str)\n\t\tvStringClear (collector->str);\n\tcollector->last_len = 0;\n}\n\n#define COLLECTOR(VSTR) { .str = VSTR, .last_len = 0, }\n\nstatic void readTokenFull (tokenInfo *const token, collector *collector)\n{\n\tint c;\n\tstatic tokenType lastTokenType = TOKEN_NONE;\n\tbool firstWhitespace = true;\n\tbool whitespace;\n\n\ttoken->c = EOF;\n\ttoken->type = TOKEN_NONE;\n\ttoken->keyword = KEYWORD_NONE;\n\tvStringClear (token->string);\n\ngetNextChar:\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\ttoken->lineNumber = getInputLineNumber ();\n\t\ttoken->filePosition = getInputFilePosition ();\n\t\tif (c == '\\n' && (lastTokenType == TOKEN_IDENTIFIER ||\n\t\t\t\t\t\t  lastTokenType == TOKEN_STRING ||\n\t\t\t\t\t\t  lastTokenType == TOKEN_OTHER ||\n\t\t\t\t\t\t  lastTokenType == TOKEN_CLOSE_PAREN ||\n\t\t\t\t\t\t  lastTokenType == TOKEN_CLOSE_CURLY ||\n\t\t\t\t\t\t  lastTokenType == TOKEN_CLOSE_SQUARE))\n\t\t{\n\t\t\tc = ';';  // semicolon injection\n\t\t}\n\t\twhitespace = c == '\\t'  ||  c == ' ' ||  c == '\\r' || c == '\\n';\n\t\tif (collector && whitespace && firstWhitespace)\n\t\t{\n\t\t\tfirstWhitespace = false;\n\t\t\tcollectorPut (collector, ' ');\n\t\t}\n\t}\n\twhile (whitespace);\n\n\tswitch (c)\n\t{\n\t\tcase EOF:\n\t\t\ttoken->type = TOKEN_EOF;\n\t\t\tbreak;\n\n\t\tcase ';':\n\t\t\ttoken->type = TOKEN_SEMICOLON;\n\t\t\tbreak;\n\n\t\tcase '/':\n\t\t\t{\n\t\t\t\tbool hasNewline = false;\n\t\t\t\tint d = getcFromInputFile ();\n\t\t\t\tswitch (d)\n\t\t\t\t{\n\t\t\t\t\tcase '/':\n\t\t\t\t\t\tskipToCharacterInInputFile ('\\n');\n\t\t\t\t\t\t/* Line comments start with the\n\t\t\t\t\t\t * character sequence // and\n\t\t\t\t\t\t * continue through the next\n\t\t\t\t\t\t * newline. A line comment acts\n\t\t\t\t\t\t * like a newline.  */\n\t\t\t\t\t\tungetcToInputFile ('\\n');\n\t\t\t\t\t\tgoto getNextChar;\n\t\t\t\t\tcase '*':\n\t\t\t\t\t\tdo\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdo\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\td = getcFromInputFile ();\n\t\t\t\t\t\t\t\tif (d == '\\n')\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\thasNewline = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} while (d != EOF && d != '*');\n\n\t\t\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t\t\t\tif (c == '/')\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tungetcToInputFile (c);\n\t\t\t\t\t\t} while (c != EOF && c != '\\0');\n\n\t\t\t\t\t\tungetcToInputFile (hasNewline ? '\\n' : ' ');\n\t\t\t\t\t\tgoto getNextChar;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\ttoken->type = TOKEN_OTHER;\n\t\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase '\"':\n\t\tcase '\\'':\n\t\tcase '`':\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tparseString (token->string, c);\n\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\tbreak;\n\n\t\tcase '<':\n\t\t\t{\n\t\t\t\tint d = getcFromInputFile ();\n\t\t\t\tif (d == '-')\n\t\t\t\t\ttoken->type = TOKEN_LEFT_ARROW;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\t\ttoken->type = TOKEN_OTHER;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase '(':\n\t\t\ttoken->type = TOKEN_OPEN_PAREN;\n\t\t\tbreak;\n\n\t\tcase ')':\n\t\t\ttoken->type = TOKEN_CLOSE_PAREN;\n\t\t\tbreak;\n\n\t\tcase '{':\n\t\t\ttoken->type = TOKEN_OPEN_CURLY;\n\t\t\tbreak;\n\n\t\tcase '}':\n\t\t\ttoken->type = TOKEN_CLOSE_CURLY;\n\t\t\tbreak;\n\n\t\tcase '[':\n\t\t\ttoken->type = TOKEN_OPEN_SQUARE;\n\t\t\tbreak;\n\n\t\tcase ']':\n\t\t\ttoken->type = TOKEN_CLOSE_SQUARE;\n\t\t\tbreak;\n\n\t\tcase '*':\n\t\t\ttoken->type = TOKEN_STAR;\n\t\t\tbreak;\n\n\t\tcase '.':\n\t\t\t{\n\t\t\t\tint d, e;\n\t\t\t\td = getcFromInputFile ();\n\t\t\t\tif (d == '.')\n\t\t\t\t{\n\t\t\t\t\te = getcFromInputFile ();\n\t\t\t\t\tif (e == '.')\n\t\t\t\t\t{\n\t\t\t\t\t\ttoken->type = TOKEN_3DOTS;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tungetcToInputFile (e);\n\t\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tungetcToInputFile (d);\n\t\t\t}\n\t\t\ttoken->type = TOKEN_DOT;\n\t\t\tbreak;\n\n\t\tcase ',':\n\t\t\ttoken->type = TOKEN_COMMA;\n\t\t\tbreak;\n\n\t\tcase '=':\n\t\t\ttoken->type = TOKEN_EQUAL;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tif (isStartIdentChar (c))\n\t\t\t{\n\t\t\t\tparseIdentifier (token->string, c);\n\t\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\t\ttoken->keyword = lookupKeyword (vStringValue (token->string), Lang_go);\n\t\t\t\tif (isKeyword (token, KEYWORD_NONE))\n\t\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\telse\n\t\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t\t}\n\t\t\telse\n\t\t\t\ttoken->type = TOKEN_OTHER;\n\t\t\tbreak;\n\t}\n\n\ttoken->c = c;\n\n\tif (collector)\n\t\tcollectorAppendToken (collector, token);\n\n\tlastTokenType = token->type;\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\treadTokenFull (token, NULL);\n}\n\nstatic bool skipToMatchedNoRead (tokenInfo *const token, collector *collector)\n{\n\tint nest_level = 0;\n\ttokenType open_token = token->type;\n\ttokenType close_token;\n\n\tswitch (open_token)\n\t{\n\t\tcase TOKEN_OPEN_PAREN:\n\t\t\tclose_token = TOKEN_CLOSE_PAREN;\n\t\t\tbreak;\n\t\tcase TOKEN_OPEN_CURLY:\n\t\t\tclose_token = TOKEN_CLOSE_CURLY;\n\t\t\tbreak;\n\t\tcase TOKEN_OPEN_SQUARE:\n\t\t\tclose_token = TOKEN_CLOSE_SQUARE;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n\n\t/*\n\t * This routine will skip to a matching closing token.\n\t * It will also handle nested tokens.\n\t */\n\tnest_level++;\n\twhile (nest_level > 0 && !isType (token, TOKEN_EOF))\n\t{\n\t\treadTokenFull (token, collector);\n\t\tif (isType (token, open_token))\n\t\t\tnest_level++;\n\t\telse if (isType (token, close_token))\n\t\t\tnest_level--;\n\t}\n\n\treturn true;\n}\n\nstatic void skipToMatched (tokenInfo *const token, collector *collector)\n{\n\tif (skipToMatchedNoRead (token, collector))\n\t\treadTokenFull (token, collector);\n}\n\nstatic bool skipType (tokenInfo *const token, collector *collector)\n{\n\t// Type      = TypeName | TypeLit | \"(\" Type \")\" .\n\t// Skips also function multiple return values \"(\" Type {\",\" Type} \")\"\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tskipToMatched (token, collector);\n\t\treturn true;\n\t}\n\n\t// TypeName  = QualifiedIdent.\n\t// QualifiedIdent = [ PackageName \".\" ] identifier .\n\t// PackageName    = identifier .\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\treadTokenFull (token, collector);\n\t\tif (isType (token, TOKEN_DOT))\n\t\t{\n\t\t\treadTokenFull (token, collector);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\treadTokenFull (token, collector);\n\t\t}\n\t\treturn true;\n\t}\n\n\t// StructType     = \"struct\" \"{\" { FieldDecl \";\" } \"}\"\n\t// InterfaceType      = \"interface\" \"{\" { MethodSpec \";\" } \"}\" .\n\tif (isKeyword (token, KEYWORD_struct) || isKeyword (token, KEYWORD_interface))\n\t{\n\t\treadTokenFull (token, collector);\n\t\t// skip over \"{}\"\n\t\tskipToMatched (token, collector);\n\t\treturn true;\n\t}\n\n\t// ArrayType   = \"[\" ArrayLength \"]\" ElementType .\n\t// SliceType = \"[\" \"]\" ElementType .\n\t// ElementType = Type .\n\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t{\n\t\tskipToMatched (token, collector);\n\t\treturn skipType (token, collector);\n\t}\n\n\t// PointerType = \"*\" BaseType .\n\t// BaseType = Type .\n\t// ChannelType = ( \"chan\" [ \"<-\" ] | \"<-\" \"chan\" ) ElementType .\n\tif (isType (token, TOKEN_STAR) || isKeyword (token, KEYWORD_chan) || isType (token, TOKEN_LEFT_ARROW))\n\t{\n\t\treadTokenFull (token, collector);\n\t\treturn skipType (token, collector);\n\t}\n\n\t// MapType     = \"map\" \"[\" KeyType \"]\" ElementType .\n\t// KeyType     = Type .\n\tif (isKeyword (token, KEYWORD_map))\n\t{\n\t\treadTokenFull (token, collector);\n\t\t// skip over \"[]\"\n\t\tskipToMatched (token, collector);\n\t\treturn skipType (token, collector);\n\t}\n\n\t// FunctionType   = \"func\" Signature .\n\t// Signature      = Parameters [ Result ] .\n\t// Result         = Parameters | Type .\n\t// Parameters     = \"(\" [ ParameterList [ \",\" ] ] \")\" .\n\tif (isKeyword (token, KEYWORD_func))\n\t{\n\t\treadTokenFull (token, collector);\n\t\t// Parameters, skip over \"()\"\n\t\tskipToMatched (token, collector);\n\t\t// Result is parameters or type or nothing.  skipType treats anything\n\t\t// surrounded by parentheses as a type, and does nothing if what\n\t\t// follows is not a type.\n\t\treturn skipType (token, collector);\n\t}\n\n\treturn false;\n}\n\nstatic int makeTagFull (tokenInfo *const token, const goKind kind,\n\t\t\t\t\t\tconst int scope, const char *argList, const char *typeref,\n\t\t\t\t\t\tconst int role)\n{\n\tconst char *const name = vStringValue (token->string);\n\n\ttagEntryInfo e;\n\n\t/* Don't record `_' placeholder variable  */\n\tif (kind == GOTAG_VAR && name[0] == '_' && name[1] == '\\0')\n\t\treturn CORK_NIL;\n\n\tinitRefTagEntry (&e, name, kind, role);\n\n\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\tif (argList)\n\t\te.extensionFields.signature = argList;\n\tif (typeref)\n\t{\n\t\t/* Follows Cxx parser convention */\n\t\te.extensionFields.typeRef [0] = \"typename\";\n\t\te.extensionFields.typeRef [1] = typeref;\n\t}\n\n\te.extensionFields.scopeIndex = scope;\n\treturn makeTagEntry (&e);\n}\n\nstatic int makeTag (tokenInfo *const token, const goKind kind,\n\t\t\t\t\tconst int scope, const char *argList, const char *typeref)\n{\n\treturn makeTagFull (token, kind, scope, argList, typeref,\n\t\t\t\t\t\tROLE_DEFINITION_INDEX);\n}\n\nstatic int makeRefTag (tokenInfo *const token, const goKind kind,\n\t\t\t\t\t   const int role)\n{\n\treturn makeTagFull (token, kind, CORK_NIL, NULL, NULL, role);\n}\n\nstatic int parsePackage (tokenInfo *const token)\n{\n\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\treturn makeTag (token, GOTAG_PACKAGE, CORK_NIL, NULL, NULL);\n\t}\n\telse\n\t\treturn CORK_NIL;\n}\n\nstatic tokenInfo * parseReceiver (tokenInfo *const token, int *corkIndex)\n{\n\ttokenInfo *receiver_type_token = NULL;\n\tint nest_level = 1;\n\n\t*corkIndex = CORK_NIL;\n\n\t/* Looking for an identifier before ')'. */\n\twhile (nest_level > 0 && !isType (token, TOKEN_EOF))\n\t{\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tif (*corkIndex == CORK_NIL)\n\t\t\t\t*corkIndex = makeTag (token, GOTAG_RECEIVER, CORK_NIL, NULL, NULL);\n\t\t\tif (!receiver_type_token)\n\t\t\t\treceiver_type_token = newToken ();\n\t\t\tcopyToken (receiver_type_token, token);\n\t\t}\n\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\tnest_level++;\n\t\telse if (isType (token, TOKEN_CLOSE_PAREN))\n\t\t\tnest_level--;\n\t}\n\n\tif (nest_level > 0 && receiver_type_token)\n\t{\n\t\tdeleteToken (receiver_type_token);\n\t\treceiver_type_token = NULL;\n\t}\n\n\tif (receiver_type_token)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (*corkIndex);\n\t\tif (e)\n\t\t{\n\t\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\t\te->extensionFields.typeRef [1] = vStringStrdup (receiver_type_token->string);\n\t\t}\n\t}\n\treadToken (token);\n\treturn receiver_type_token;\n}\n\nstatic void parseFunctionOrMethod (tokenInfo *const token, const int scope)\n{\n\tint receiver_cork = CORK_NIL;\n\ttokenInfo *receiver_type_token = NULL;\n\n\t// FunctionDecl = \"func\" identifier Signature [ Body ] .\n\t// Body         = Block.\n\t//\n\t// MethodDecl   = \"func\" Receiver MethodName Signature [ Body ] .\n\t// Receiver     = \"(\" [ identifier ] [ \"*\" ] BaseTypeName \")\" .\n\t// BaseTypeName = identifier .\n\n\t// Pick up receiver type.\n\treadToken (token);\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\treceiver_type_token = parseReceiver (token, &receiver_cork);\n\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\tint cork;\n\t\ttagEntryInfo *e = NULL;\n\t\ttokenInfo *functionToken = newToken ();\n\t\tint func_scope;\n\n\t\tcopyToken (functionToken, token);\n\n\t\t// Start recording signature\n\t\tvString *buffer = vStringNew ();\n\t\tcollector collector = COLLECTOR (buffer);\n\n\t\t// Skip over parameters.\n\t\treadTokenFull (token, &collector);\n\t\tskipToMatchedNoRead (token, &collector);\n\n\t\tcollectorTruncate (&collector, false);\n\t\tif (receiver_type_token)\n\t\t{\n\t\t\tfunc_scope = anyEntryInScope (scope, vStringValue (receiver_type_token->string), false);\n\t\t\tif (func_scope == CORK_NIL)\n\t\t\t\tfunc_scope = makeTagFull(receiver_type_token, GOTAG_UNKNOWN,\n\t\t\t\t\t\t\t\t\t\t scope, NULL, NULL,\n\t\t\t\t\t\t\t\t\t\t R_GOTAG_UNKNOWN_RECEIVER);\n\t\t}\n\t\telse\n\t\t\tfunc_scope = scope;\n\n\t\tcork = makeTag (functionToken, GOTAG_FUNCTION,\n\t\t\t\t\t\tfunc_scope, vStringValue (buffer), NULL);\n\t\tif ((e = getEntryInCorkQueue (cork)))\n\t\t{\n\t\t\ttagEntryInfo *receiver = getEntryInCorkQueue (receiver_cork);\n\t\t\tif (receiver)\n\t\t\t{\n\t\t\t\treceiver->extensionFields.scopeIndex = cork;\n\t\t\t\tattachParserField (e, GoFields [F_RECEIVER].ftype, receiver->name);\n\t\t\t}\n\t\t}\n\n\t\tdeleteToken (functionToken);\n\n\t\tcollectorReset (&collector);\n\n\t\treadTokenFull (token, &collector);\n\n\t\t// Skip over result.\n\t\tskipType (token, &collector);\n\n\t\t// Neither \"{\" nor \" {\".\n\t\tif (!(isType (token, TOKEN_OPEN_CURLY) && collector.last_len < 2))\n\t\t{\n\t\t\tcollectorTruncate(&collector, isType (token, TOKEN_OPEN_CURLY));\n\t\t\tif (e)\n\t\t\t{\n\t\t\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\t\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (buffer);\n\t\t\t\tbuffer = NULL;\n\t\t\t}\n\t\t}\n\n\t\tif (buffer)\n\t\t\tvStringDelete (buffer);\n\n\t\t// Skip over function body.\n\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tskipToMatched (token, NULL);\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine (e, getInputLineNumber());\n\t\t}\n\t}\n\n\tif (receiver_type_token)\n\t\tdeleteToken(receiver_type_token);\n}\n\nstatic void attachTypeRefField (int scope, intArray *corks, const char *const type)\n{\n\tint type_cork = anyEntryInScope (scope, type, false);\n\ttagEntryInfo *type_e = getEntryInCorkQueue (type_cork);\n\n\tfor (unsigned int i = 0; i < intArrayCount (corks); i++)\n\t{\n\t\tint cork = intArrayItem (corks, i);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (cork);\n\t\tif (!e)\n\t\t\tcontinue;\n\t\te->extensionFields.typeRef [0] = eStrdup (type_e\n\t\t\t\t\t\t\t\t\t\t\t\t  ?GoKinds[type_e->kindIndex].name\n\t\t\t\t\t\t\t\t\t\t\t\t  :\"typename\");\n\t\te->extensionFields.typeRef [1] = eStrdup (type);\n\t}\n}\n\nstatic void parseInterfaceMethods (tokenInfo *const token, const int scope)\n{\n\t// InterfaceType      = \"interface\" \"{\" { MethodSpec \";\" } \"}\" .\n\t// MethodSpec         = MethodName Signature | InterfaceTypeName .\n\t// MethodName         = identifier .\n\t// InterfaceTypeName  = TypeName .\n\n\tvString *inheritsBuf = vStringNew ();\n\tcollector inherits = COLLECTOR (inheritsBuf);\n\n\treadToken (token);\n\tif (!isType (token, TOKEN_OPEN_CURLY))\n\t\treturn;\n\n\treadToken (token);\n\twhile (!isType (token, TOKEN_EOF) && !isType (token, TOKEN_CLOSE_CURLY))\n\t{\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\ttokenInfo * headToken = newToken();\n\t\t\tcopyToken (headToken, token);\n\n\t\t\treadToken (token);\n\t\t\tif(isType (token, TOKEN_DOT))\n\t\t\t{\n\t\t\t\tif (!collectorIsEmpty(&inherits))\n\t\t\t\t\tcollectorPut (&inherits, ',');\n\t\t\t\tcollectorAppendToken (&inherits, headToken);\n\t\t\t\treadTokenFull (token, NULL);\n\t\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\t{\n\t\t\t\t\tcollectorPut (&inherits, '.');\n\t\t\t\t\tcollectorAppendToken (&inherits, token);\n\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t\t/* If the token is not an identifier, the input\n\t\t\t\t   may be wrong. */\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_SEMICOLON))\n\t\t\t{\n\t\t\t\tif (!collectorIsEmpty(&inherits))\n\t\t\t\t\tcollectorPut (&inherits, ',');\n\t\t\t\tcollectorAppendToken (&inherits, headToken);\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t{\n\t\t\t\t// => Signature\n\t\t\t\t// Signature      = Parameters [ Result ] .\n\t\t\t\tvString *pbuf = vStringNew ();\n\t\t\t\tcollector pcol = COLLECTOR (pbuf);\n\t\t\t\tvString *rbuf = NULL;\n\t\t\t\tcollector rcol = COLLECTOR (NULL);\n\n\t\t\t\t// Parameters\n\t\t\t\tcollectorPut (&pcol, '(');\n\t\t\t\tskipToMatched (token, &pcol);\n\t\t\t\tcollectorTruncate(&pcol, true);\n\n\t\t\t\tif (!isType (token, TOKEN_SEMICOLON))\n\t\t\t\t{\n\t\t\t\t\trbuf = vStringNew ();\n\t\t\t\t\trcol.str = rbuf;\n\n\t\t\t\t\tcollectorAppendToken (&rcol, token);\n\t\t\t\t\tskipType (token, &rcol);\n\t\t\t\t\tcollectorTruncate(&rcol, true);\n\t\t\t\t}\n\n\t\t\t\tmakeTag (headToken, GOTAG_METHODSPEC, scope,\n\t\t\t\t\t\t vStringValue (pbuf),\n\t\t\t\t\t\t rbuf? vStringValue(rbuf): NULL);\n\n\t\t\t\tif (rbuf)\n\t\t\t\t\tvStringDelete (rbuf);\n\t\t\t\tvStringDelete (pbuf);\n\t\t\t}\n\t\t\tdeleteToken (headToken);\n\t\t}\n\t\telse\n\t\t\treadToken (token);\n\t}\n\n\tif (!collectorIsEmpty(&inherits))\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (scope);\n\t\tif (e)\n\t\t{\n\t\t\te->extensionFields.inheritance = vStringDeleteUnwrap (inheritsBuf);\n\t\t\tinheritsBuf = NULL;\n\t\t}\n\t}\n\tvStringDelete (inheritsBuf);\n}\n\nstatic void parseStructMembers (tokenInfo *const token, const int scope)\n{\n\t// StructType     = \"struct\" \"{\" { FieldDecl \";\" } \"}\" .\n\t// FieldDecl      = (IdentifierList Type | AnonymousField) [ Tag ] .\n\t// AnonymousField = [ \"*\" ] TypeName .\n\t// Tag            = string_lit .\n\n\treadToken (token);\n\tif (!isType (token, TOKEN_OPEN_CURLY))\n\t\treturn;\n\n\tvString *typeForAnonMember = vStringNew ();\n\tintArray *corkForFields = intArrayNew ();\n\n\treadToken (token);\n\twhile (!isType (token, TOKEN_EOF) && !isType (token, TOKEN_CLOSE_CURLY))\n\t{\n\t\ttokenInfo *memberCandidate = NULL;\n\t\tbool first = true;\n\n\t\twhile (!isType (token, TOKEN_EOF))\n\t\t{\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t{\n\t\t\t\tif (first)\n\t\t\t\t{\n\t\t\t\t\t// could be anonymous field like in 'struct {int}' - we don't know yet\n\t\t\t\t\tmemberCandidate = newToken ();\n\t\t\t\t\tcopyToken (memberCandidate, token);\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tint cork;\n\t\t\t\t\tif (memberCandidate)\n\t\t\t\t\t{\n\t\t\t\t\t\t// if we are here, there was a comma and memberCandidate isn't an anonymous field\n\t\t\t\t\t\tcork = makeTag (memberCandidate, GOTAG_MEMBER, scope, NULL, NULL);\n\t\t\t\t\t\tdeleteToken (memberCandidate);\n\t\t\t\t\t\tmemberCandidate = NULL;\n\t\t\t\t\t\tintArrayAdd (corkForFields, cork);\n\t\t\t\t\t}\n\t\t\t\t\tcork = makeTag (token, GOTAG_MEMBER, scope, NULL, NULL);\n\t\t\t\t\tintArrayAdd (corkForFields, cork);\n\t\t\t\t}\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\tif (!isType (token, TOKEN_COMMA))\n\t\t\t\tbreak;\n\t\t\treadToken (token);\n\t\t}\n\n\t\tif (first && isType (token, TOKEN_STAR))\n\t\t{\n\t\t\tvStringPut (typeForAnonMember, '*');\n\t\t\treadToken (token);\n\t\t}\n\t\telse if (memberCandidate &&\n\t\t\t\t (isType (token, TOKEN_DOT) ||\n\t\t\t\t  isType (token, TOKEN_STRING) ||\n\t\t\t\t  isType (token, TOKEN_SEMICOLON)))\n\t\t\t// memberCandidate is part of anonymous type\n\t\t\tvStringCat (typeForAnonMember, memberCandidate->string);\n\n\t\t// the above two cases that set typeForAnonMember guarantee\n\t\t// this is an anonymous member\n\t\tif (vStringLength (typeForAnonMember) > 0)\n\t\t{\n\t\t\ttokenInfo *anonMember = NULL;\n\n\t\t\tif (memberCandidate)\n\t\t\t{\n\t\t\t\tanonMember = newToken ();\n\t\t\t\tcopyToken (anonMember, memberCandidate);\n\t\t\t}\n\n\t\t\t// TypeName of AnonymousField has a dot like package\".\"type.\n\t\t\t// Pick up the last package component, and store it to\n\t\t\t// memberCandidate.\n\t\t\twhile (isType (token, TOKEN_IDENTIFIER) ||\n\t\t\t\t   isType (token, TOKEN_DOT))\n\t\t\t{\n\t\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\t{\n\t\t\t\t\tif (!anonMember)\n\t\t\t\t\t\tanonMember = newToken ();\n\t\t\t\t\tcopyToken (anonMember, token);\n\t\t\t\t\tvStringCat (typeForAnonMember, anonMember->string);\n\t\t\t\t}\n\t\t\t\telse if (isType (token, TOKEN_DOT))\n\t\t\t\t\tvStringPut (typeForAnonMember, '.');\n\t\t\t\treadToken (token);\n\t\t\t}\n\n\t\t\t// optional tag\n\t\t\tif (isType (token, TOKEN_STRING))\n\t\t\t\treadToken (token);\n\n\t\t\tif (anonMember)\n\t\t\t{\n\t\t\t\tmakeTag (anonMember, GOTAG_ANONMEMBER, scope, NULL,\n\t\t\t\t\t\t vStringValue (typeForAnonMember));\n\t\t\t\tdeleteToken (anonMember);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvString *typeForMember = vStringNew ();\n\t\t\tcollector collector = COLLECTOR (typeForMember);\n\n\t\t\tcollectorAppendToken (&collector, token);\n\t\t\tskipType (token, &collector);\n\t\t\tcollectorTruncate (&collector, true);\n\n\t\t\tif (memberCandidate)\n\t\t\t\tmakeTag (memberCandidate, GOTAG_MEMBER, scope, NULL,\n\t\t\t\t\t\t vStringValue (typeForMember));\n\n\t\t\tattachTypeRefField (scope, corkForFields, vStringValue (typeForMember));\n\t\t\tintArrayClear (corkForFields);\n\t\t\tvStringDelete (typeForMember);\n\t\t}\n\n\t\tif (memberCandidate)\n\t\t\tdeleteToken (memberCandidate);\n\n\t\tvStringClear (typeForAnonMember);\n\n\t\twhile (!isType (token, TOKEN_SEMICOLON) && !isType (token, TOKEN_CLOSE_CURLY)\n\t\t\t\t&& !isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tskipToMatched (token, NULL);\n\t\t}\n\n\t\tif (!isType (token, TOKEN_CLOSE_CURLY))\n\t\t{\n\t\t\t// we are at TOKEN_SEMICOLON\n\t\t\treadToken (token);\n\t\t}\n\t}\n\n\tintArrayDelete (corkForFields);\n\tvStringDelete (typeForAnonMember);\n}\n\nstatic void parseConstTypeVar (tokenInfo *const token, goKind kind, const int scope)\n{\n\t// ConstDecl      = \"const\" ( ConstSpec | \"(\" { ConstSpec \";\" } \")\" ) .\n\t// ConstSpec      = IdentifierList [ [ Type ] \"=\" ExpressionList ] .\n\t// IdentifierList = identifier { \",\" identifier } .\n\t// ExpressionList = Expression { \",\" Expression } .\n\t// TypeDecl     = \"type\" ( TypeSpec | \"(\" { TypeSpec \";\" } \")\" ) .\n\t// TypeSpec     = identifier [ \"=\" ] Type .\n\t// VarDecl     = \"var\" ( VarSpec | \"(\" { VarSpec \";\" } \")\" ) .\n\t// VarSpec     = IdentifierList ( Type [ \"=\" ExpressionList ] | \"=\" ExpressionList ) .\n\tbool usesParens = false;\n\tintArray *corks\n\t\t= (kind == GOTAG_VAR || kind == GOTAG_CONST)? intArrayNew (): NULL;\n\n\treadToken (token);\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tusesParens = true;\n\t\treadToken (token);\n\t}\n\n\tdo\n\t{\n\t\ttokenInfo *typeToken = NULL;\n\t\tint member_scope = scope;\n\n\t\twhile (!isType (token, TOKEN_EOF))\n\t\t{\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t{\n\t\t\t\tif (kind == GOTAG_TYPE)\n\t\t\t\t{\n\t\t\t\t\ttypeToken = newToken ();\n\t\t\t\t\tcopyToken (typeToken, token);\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isType (token, TOKEN_EQUAL))\n\t\t\t\t\t{\n\t\t\t\t\t\tkind = GOTAG_TALIAS;\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isKeyword (token, KEYWORD_struct))\n\t\t\t\t\t\tmember_scope = makeTag (typeToken, GOTAG_STRUCT,\n\t\t\t\t\t\t\t\t\t\t\t\tscope, NULL, NULL);\n\t\t\t\t\telse if (isKeyword (token, KEYWORD_interface))\n\t\t\t\t\t\tmember_scope = makeTag (typeToken, GOTAG_INTERFACE,\n\t\t\t\t\t\t\t\t\t\t\t\tscope, NULL, NULL);\n\t\t\t\t\telse\n\t\t\t\t\t\tmember_scope = makeTag (typeToken, kind,\n\t\t\t\t\t\t\t\t\t\t\t\tscope, NULL, NULL);\n\n\t\t\t\t\tif (member_scope != CORK_NIL)\n\t\t\t\t\t\tregisterEntry (member_scope);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tint c = makeTag (token, kind, scope, NULL, NULL);\n\t\t\t\t\tif (c != CORK_NIL && corks)\n\t\t\t\t\t\tintArrayAdd (corks, c);\n\t\t\t\t}\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\tif (!isType (token, TOKEN_COMMA))\n\t\t\t\tbreak;\n\t\t\treadToken (token);\n\t\t}\n\n\t\tif (typeToken)\n\t\t{\n\t\t\tif (isKeyword (token, KEYWORD_struct))\n\t\t\t\tparseStructMembers (token, member_scope);\n\t\t\telse if (isKeyword (token, KEYWORD_interface))\n\t\t\t\tparseInterfaceMethods (token, member_scope);\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* Filling \"typeref:\" field of typeToken. */\n\t\t\t\tvString *buffer = vStringNew ();\n\t\t\t\tcollector collector = COLLECTOR(buffer);\n\n\t\t\t\tcollectorAppendToken (&collector, token);\n\t\t\t\tskipType (token, &collector);\n\t\t\t\tcollectorTruncate (&collector, true);\n\n\t\t\t\tif ((member_scope != CORK_NIL) && !vStringIsEmpty (buffer))\n\t\t\t\t{\n\t\t\t\t\ttagEntryInfo *e = getEntryInCorkQueue (member_scope);\n\t\t\t\t\tif (e)\n\t\t\t\t\t{\n\t\t\t\t\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\t\t\t\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (buffer);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tvStringDelete (buffer);\n\t\t\t}\n\t\t\tdeleteToken (typeToken);\n\t\t}\n\t\telse if (corks)\n\t\t{\n\t\t\tvString *buffer = vStringNew ();\n\t\t\tcollector collector = COLLECTOR (buffer);\n\n\t\t\tcollectorAppendToken (&collector, token);\n\t\t\tskipType (token, &collector);\n\t\t\tcollectorTruncate (&collector, true);\n\n\t\t\tif (!vStringIsEmpty (buffer))\n\t\t\t\tattachTypeRefField (scope, corks, vStringValue (buffer));\n\t\t\tvStringDelete (buffer);\n\t\t\tintArrayClear (corks);\n\t\t}\n\t\telse\n\t\t\tskipType (token, NULL);\n\n\t\twhile (!isType (token, TOKEN_SEMICOLON) && !isType (token, TOKEN_CLOSE_PAREN)\n\t\t\t\t&& !isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tskipToMatched (token, NULL);\n\t\t}\n\n\t\tif (member_scope != scope && member_scope != CORK_NIL)\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (member_scope);\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine(e, getInputLineNumber ());\n\t\t}\n\n\t\tif (usesParens && !isType (token, TOKEN_CLOSE_PAREN))\n\t\t{\n\t\t\t// we are at TOKEN_SEMICOLON\n\t\t\treadToken (token);\n\t\t}\n\t}\n\twhile (!isType (token, TOKEN_EOF) &&\n\t\t\tusesParens && !isType (token, TOKEN_CLOSE_PAREN));\n\n\tintArrayDelete (corks);\n}\n\nstatic void parseImportSpec (tokenInfo *const token)\n{\n\t// ImportSpec       = [ \".\" | PackageName ] ImportPath .\n\t// ImportPath       = string_lit .\n\n\tint packageName_cork = CORK_NIL;\n\tchar *how_imported = NULL;\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\tif (strcmp(vStringValue (token->string), \"_\") == 0)\n\t\t\thow_imported = \"init\";\n\t\telse\n\t\t{\n\t\t\tpackageName_cork = makeTag (token, GOTAG_PACKAGE_NAME,\n\t\t\t\t\t\t\t\t\t\tCORK_NIL, NULL, NULL);\n\t\t}\n\t\treadToken (token);\n\t}\n\telse if (isType (token, TOKEN_DOT))\n\t{\n\t\thow_imported = \"inline\";\n\t\treadToken (token);\n\t}\n\n\tif (isType (token, TOKEN_STRING))\n\t{\n\t\tint package_cork =\n\t\t\tmakeRefTag (token, GOTAG_PACKAGE, R_GOTAG_PACKAGE_IMPORTED);\n\n\t\tif (package_cork != CORK_NIL && how_imported)\n\t\t\tattachParserFieldToCorkEntry (package_cork,\n\t\t\t\t\t\t\t\t\t\t  GoFields [F_HOW_IMPORTED].ftype,\n\t\t\t\t\t\t\t\t\t\t  how_imported);\n\n\t\tif (packageName_cork != CORK_NIL)\n\t\t{\n\t\t\tattachParserFieldToCorkEntry (packageName_cork,\n\t\t\t\t\t\t\t\t\t\t  GoFields [F_PACKAGE].ftype,\n\t\t\t\t\t\t\t\t\t\t  vStringValue (token->string));\n\t\t\tif (package_cork != CORK_NIL)\n\t\t\t{\n\t\t\t\ttagEntryInfo *e = getEntryInCorkQueue (packageName_cork);\n\t\t\t\tif (e)\n\t\t\t\t\tattachParserFieldToCorkEntry (package_cork,\n\t\t\t\t\t\t\t\t\t\t\t\t  GoFields [F_PACKAGE_NAME].ftype,\n\t\t\t\t\t\t\t\t\t\t\t\t  e->name);\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void parseImport (tokenInfo *const token)\n{\n\t// ImportDecl       = \"import\" ( ImportSpec | \"(\" { ImportSpec \";\" } \")\" ) .\n\n\treadToken (token);\n\tif (isType (token, TOKEN_EOF))\n\t\treturn;\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tdo\n\t\t{\n\t\t\tparseImportSpec (token);\n\t\t\treadToken (token);\n\t\t} while (!isType (token, TOKEN_EOF) &&\n\t\t\t\t !isType (token, TOKEN_CLOSE_PAREN));\n\t}\n\telse\n\t{\n\t\tparseImportSpec (token);\n\t\treturn;\n\t}\n}\n\nstatic void parseGoFile (tokenInfo *const token)\n{\n\tint scope = CORK_NIL;\n\tdo\n\t{\n\t\treadToken (token);\n\n\t\tif (isType (token, TOKEN_KEYWORD))\n\t\t{\n\t\t\tswitch (token->keyword)\n\t\t\t{\n\t\t\t\tcase KEYWORD_package:\n\t\t\t\t\tscope = parsePackage (token);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_func:\n\t\t\t\t\tparseFunctionOrMethod (token, scope);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_const:\n\t\t\t\t\tparseConstTypeVar (token, GOTAG_CONST, scope);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_type:\n\t\t\t\t\tparseConstTypeVar (token, GOTAG_TYPE, scope);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_var:\n\t\t\t\t\tparseConstTypeVar (token, GOTAG_VAR, scope);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_import:\n\t\t\t\t\tparseImport (token);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_PAREN) || isType (token, TOKEN_OPEN_CURLY) ||\n\t\t\tisType (token, TOKEN_OPEN_SQUARE))\n\t\t{\n\t\t\tskipToMatched (token, NULL);\n\t\t}\n\t} while (token->type != TOKEN_EOF);\n}\n\nstatic void findGoTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\tparseGoFile (token);\n\n\tdeleteToken (token);\n}\n\nextern parserDefinition *GoParser (void)\n{\n\tstatic const char *const extensions[] = { \"go\", NULL };\n\tparserDefinition *def = parserNew (\"Go\");\n\tdef->kindTable = GoKinds;\n\tdef->kindCount = ARRAY_SIZE (GoKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findGoTags;\n\tdef->initialize = initialize;\n\tdef->finalize = finalize;\n\tdef->keywordTable = GoKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (GoKeywordTable);\n\tdef->fieldTable = GoFields;\n\tdef->fieldCount = ARRAY_SIZE (GoFields);\n\tdef->useCork = CORK_QUEUE | CORK_SYMTAB;\n\tdef->requestAutomaticFQTag = true;\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/haskell.c",
    "content": "/*\n* Copyright (c) 2003, Peter Strand <peter@zarquon.se>\n*\n* This source code is released for free distribution under the terms of the\n* GNU General Public License version 2 or (at your opinion) any later version.\n*\n* This module contains functions for generating tags for Haskell language\n* files (https://en.wikipedia.org/wiki/Haskell_(programming_language)).\n*\n* Does not handle operators or infix definitions like:\n* a `f` b = ...\n*\n*/\n\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"    /* must always come first */\n\n#include <string.h>\n\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"routines.h\"\n\n\n#define HASKELL_STRMAXLEN 1000\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_TYPE, K_CONSTRUCTOR, K_FUNCTION, K_MODULE\n} haskellKind;\n\nstatic kindDefinition HaskellKinds [] = {\n\t{ true, 't', \"type\", \"types\" },\n\t{ true, 'c', \"constructor\", \"type constructors\" },\n\t{ true, 'f', \"function\", \"functions\" },\n\t{ true, 'm', \"module\", \"modules\"}\n};\n\n\ntypedef const unsigned char *custr;\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n\nstatic void skip_rest_of_line(void)\n{\n\tint c;\n\tdo {\n\t\tc = getcFromInputFile();\n\t} while (c != EOF && c != '\\n');\n}\n\nstatic int get_line(char *buf)\n{\n\tint i = 0;\n\tint c;\n\tdo {\n\t\tc = getcFromInputFile();\n\t\tbuf[i++] = c;\n\t} while (c != EOF && c != '\\n' && i < HASKELL_STRMAXLEN);\n\tbuf[i] = '\\0';\n\treturn i;\n}\n\nstatic int get_next_char(void)\n{\n\tint c, nxt;\n\tc = getcFromInputFile();\n\tif (c == EOF)\n\t\treturn c;\n\tnxt = getcFromInputFile();\n\tif (nxt == EOF)\n\t\treturn c;\n\tungetcToInputFile(nxt);\n\n\tif (c == '-' && nxt == '-') {\n\t\tskip_rest_of_line();\n\t\treturn get_next_char();\n\t}\n\tif (c == '{' && nxt == '-') {\n\t\tint last = '\\0';\n\t\tdo {\n\t\t\tlast = c;\n\t\t\tc = get_next_char();\n\t\t} while (! (c == EOF || (last == '-' && c == '}')));\n\t\treturn get_next_char();\n\t}\n\treturn c;\n}\n\nstatic void add_tag(const char *token, haskellKind kind, vString *name)\n{\n\tint i;\n\tfor (i = 0; token[i] != '\\0'; ++i)\n\t\tvStringPut(name, token[i]);\n\n\tmakeSimpleTag(name, kind);\n\tvStringClear(name);\n}\n\nstatic int isident(int c)\n{\n\treturn isalnum(c) || c == '_' || c == '\\'' || c == '$';\n}\n\nstatic int get_token(char *token, int n)\n{\n\tint c = getcFromInputFile();\n\tint i = n;\n\twhile (c != EOF && isident(c) && i < HASKELL_STRMAXLEN) {\n\t\ttoken[i] = c;\n\t\ti++;\n\t\tc = getcFromInputFile();\n\t}\n\ttoken[i] = '\\0';\n\tif (c == EOF)\n\t\treturn 0;\n\tif (i != n) {\n\t\tungetcToInputFile(c);\n\t\treturn 1;\n\t} else {\n\t\treturn 0;\n\t}\n}\n\nenum Find_State { Find_Eq, Find_Constr, Get_Extr, Find_Extr, Find_Bar };\n\nstatic int inside_datatype(vString *name)\n{\n\tenum Find_State st = Find_Eq;\n\tint c;\n\tchar token[HASKELL_STRMAXLEN + 1];\n\n\twhile (1) {\n\t\tif (st == Find_Eq)\n\t\t{\n\t\t\tdo {\n\t\t\t\tc = get_next_char();\n\t\t\t\tif (c == '\\n') {\n\t\t\t\t\tc = get_next_char();\n\t\t\t\t\tif (! (c == ' ' || c == '\\t')) {\n\t\t\t\t\t\treturn c;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} while (c != EOF && c != '=');\n\t\t\tst = Find_Constr;\n\t\t}\n\t\telse if (st == Find_Constr)\n\t\t{\n\t\t\tdo {\n\t\t\t\tc = get_next_char();\n\t\t\t} while (isspace(c));\n\t\t\tif (!isupper(c)) {\n\t\t\t\tskip_rest_of_line();\n\t\t\t\treturn '\\n';\n\t\t\t}\n\t\t\ttoken[0] = c;\n\t\t\tif (!get_token(token, 1))\n\t\t\t\treturn '\\n';\n\t\t\tadd_tag(token, K_CONSTRUCTOR, name);\n\t\t\tst = Find_Extr;\n\t\t}\n\t\telse if (st == Find_Extr)\n\t\t{\n\t\t\tc = get_next_char();\n\t\t\tif (c == '{')\n\t\t\t\tst = Get_Extr;\n\t\t\telse if (c == '|')\n\t\t\t\tst = Find_Constr;\n\t\t\telse if (c == '\\n') {\n\t\t\t\tc = get_next_char();\n\t\t\t\tif (! (c == ' ' || c == '\\t')) {\n\t\t\t\t\treturn c;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (!isspace(c))\n\t\t\t\tst = Find_Bar;\n\t\t}\n\t\telse if (st == Get_Extr)\n\t\t{\n\t\t\tdo {\n\t\t\t\tc = get_next_char();\n\t\t\t} while (isspace(c));\n\t\t\tif (c == EOF)\n\t\t\t\treturn c;\n\t\t\ttoken[0] = c;\n\t\t\tget_token(token, 1);\n\t\t\tadd_tag(token, K_FUNCTION, name);\n\t\t\tdo {\n\t\t\t\tc = get_next_char();\n\t\t\t\tif (c == '}') {\n\t\t\t\t\tst = Find_Bar;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} while (c != EOF && c != ',');\n\t\t}\n\t\telse if (st == Find_Bar)\n\t\t{\n\t\t\tdo {\n\t\t\t\tc = get_next_char();\n\t\t\t\tif (c == '\\n') {\n\t\t\t\t\tc = get_next_char();\n\t\t\t\t\tif (! (c == ' ' || c == '\\t')) {\n\t\t\t\t\t\treturn c;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} while (c != EOF && c != '|');\n\t\t\tst = Find_Constr;\n\t\t}\n\t}\n\treturn '\\n';\n}\n\nstatic void findHaskellTags (int is_literate)\n{\n\tvString *name = vStringNew ();\n\tchar token[HASKELL_STRMAXLEN + 1], arg[HASKELL_STRMAXLEN + 1];\n\tint c;\n\tint in_tex_lit_code = 0;\n\tc = get_next_char();\n\n\twhile (c != EOF)\n\t{\n\t\tif (c == '\\n') {\n\t\t\tc = get_next_char();\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isspace(c)) {\n\t\t\tskip_rest_of_line();\n\t\t\tc = get_next_char();\n\t\t\tcontinue;\n\t\t}\n\t\tif (is_literate && !in_tex_lit_code) {\n\t\t\tif (c == '>') {\n\t\t\t\tc = getcFromInputFile();\n\t\t\t\tif (c == ' ') {\n\t\t\t\t\tc = get_next_char();\n\t\t\t\t\tif (!isident(c)) {\n\t\t\t\t\t\tskip_rest_of_line();\n\t\t\t\t\t\tc = get_next_char();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tskip_rest_of_line();\n\t\t\t\t\tc = get_next_char();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} else if (c == '\\\\') {\n\t\t\t\tint n = get_line(token);\n\t\t\t\tif (strncmp(token, \"begin{code}\", 11) == 0) {\n\t\t\t\t\tin_tex_lit_code = 1;\n\t\t\t\t\tc = get_next_char();\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\tif (n > 0 && token[n-1] != '\\n')\n\t\t\t\t\t\tskip_rest_of_line();\n\t\t\t\t\telse\n\t\t\t\t\t\tc = get_next_char();\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tskip_rest_of_line();\n\t\t\t\tc = get_next_char();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (is_literate && in_tex_lit_code && c == '\\\\') {\n\t\t\tget_line(token);\n\t\t\tif (strncmp(token, \"end{code}\", 9) == 0) {\n\t\t\t\tin_tex_lit_code = 0;\n\t\t\t\tc = get_next_char();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\ttoken[0] = c;\n\t\tif (!isident(c)) {\n\t\t\tskip_rest_of_line();\n\t\t\tc = get_next_char();\n\t\t\tcontinue;\n\t\t}\n\t\tif (!get_token(token, 1)) {\n\t\t\tc = get_next_char();\n\t\t\tcontinue;\n\t\t}\n\t\tdo {\n\t\t\tif ((c = getcFromInputFile()) == EOF)\n\t\t\t\treturn;\n\t\t} while (c == ' ' || c == '\\t');\n\t\targ[0] = c;\n\t\tget_token(arg, 1);\n\t\tif (strcmp(token, \"data\") == 0 || strcmp(token, \"newtype\") == 0) {\n\t\t\tadd_tag(arg, K_TYPE, name);\n\t\t\tc = inside_datatype(name);\n\t\t\tcontinue;\n\t\t}\n\t\tif (strcmp(token, \"type\") == 0)\n\t\t\tadd_tag(arg, K_TYPE, name);\n\t\telse if (strcmp(token, \"module\") == 0)\n\t\t\tadd_tag(arg, K_MODULE, name);\n\t\telse if (strcmp(token, \"instance\") == 0 ||\n\t\t\t\t strcmp(token, \"foreign\") == 0 ||\n\t\t\t\t strcmp(token, \"import\") == 0)\n\t\t\t;\n\t\telse {\n\t\t\t/*\n\t\t\t * \"::\" can be after [\\n][ \\t]+\n\t\t\t * ------------------------------\n\t\t\t * thing\n\t\t\t *   :: App m\n\t\t\t *   => Int\n\t\t\t *   -> m Int\n\t\t\t * ------------------------------\n\t\t\t * Skip them to find ':'.\n\t\t\t */\n\t\t\tif (arg[0] == '\\n' && arg[1] == '\\0') {\n\t\t\t\tbool indented = false;\n\t\t\t\twhile (1)\n\t\t\t\t{\n\t\t\t\t\tif ((c = getcFromInputFile()) == EOF)\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (!isspace(c))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tindented = true;\n\t\t\t\t}\n\t\t\t\tif (indented)\n\t\t\t\t\targ[0] = c;\n\t\t\t\telse\n\t\t\t\t\tungetcToInputFile(c);\n\t\t\t}\n\n\t\t\tif (arg[0] != ':')\n\t\t\t\tadd_tag(token, K_FUNCTION, name);\n\t\t}\n\t\tskip_rest_of_line();\n\t\tc = get_next_char();\n\t}\n\tvStringDelete(name);\n}\n\nstatic void findNormalHaskellTags (void)\n{\n\tfindHaskellTags (0);\n}\n\nstatic void findLiterateHaskellTags (void)\n{\n\tfindHaskellTags (1);\n}\n\nextern parserDefinition* HaskellParser (void)\n{\n\tstatic const char *const extensions [] = { \"hs\", NULL };\n\tparserDefinition* def  = parserNew (\"Haskell\");\n\n\tdef->kindTable  = HaskellKinds;\n\tdef->kindCount  = ARRAY_SIZE(HaskellKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findNormalHaskellTags;\n\treturn def;\n}\n\nextern parserDefinition* LiterateHaskellParser (void)\n{\n\tstatic const char *const extensions [] = { \"lhs\", NULL };\n\tparserDefinition* def = parserNew (\"LiterateHaskell\");\n\tdef->kindTable  = HaskellKinds;\n\tdef->kindCount  = ARRAY_SIZE(HaskellKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findLiterateHaskellTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/haxe.c",
    "content": "/*\n *       Copyright (c) 2007, Ritchie Turner\n *\n *       This source code is released for free distribution under the terms of the\n *       GNU General Public License version 2 or (at your opinion) any later version.\n *\n *       This module contains functions for generating tags for Haxe files\n *       (https://en.wikipedia.org/wiki/Haxe).\n *\n *       Borrowed from PHP.\n */\n\n/*\n *       INCLUDE FILES\n */\n#include \"general.h\"    /* must always come first */\n#include <ctype.h>      /* to define isalpha () */\n#ifdef DEBUG\n#include <stdio.h>\n#endif\n#include <string.h>\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n\n/*\n *       MACROS\n */\n#define isType(token,t)         (bool) ((token)->type == (t))\n#define isKeyword(token,k)      (bool) ((token)->keyword == (k))\n\n/*\n *      DATA DEFINITIONS\n */\n\n/*static jmp_buf Exception;*/\n\ntypedef enum {\n\tHXTAG_METHODS,\n\tHXTAG_CLASS,\n\tHXTAG_ENUM,\n\tHXTAG_VARIABLE,\n\tHXTAG_INTERFACE,\n\tHXTAG_TYPEDEF,\n\tHXTAG_COUNT\n} hxKind;\n\nstatic kindDefinition HxKinds [] = {\n\t{ true,  'm', \"method\",         \"methods\" },\n\t{ true,  'c', \"class\",          \"classes\" },\n\t{ true,  'e', \"enum\",           \"enumerations\" },\n\t{ true,  'v', \"variable\",       \"variables\" },\n\t{ true,  'i', \"interface\",      \"interfaces\" },\n\t{ true,  't', \"typedef\",        \"typedefs\" },\n};\n\nstatic void findHxTags (void)\n{\n\tvString *name = vStringNew ();\n\tvString *clsName = vStringNew();\n\tvString *scope2 = vStringNew();\n\tvString *laccess = vStringNew();\n\tconst char *const priv = \"private\";\n\tconst char *const pub = \"public\";\n\n\tconst unsigned char *line;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char *cp = line;\nanother:\n\t\twhile (isspace (*cp))\n\t\t\tcp++;\n\n\t\tvStringCopyS(laccess,priv);\n\n\t\tif (strncmp ((const char*) cp, \"var\", (size_t) 3) == 0  &&\n\t\t\tisspace (cp [3]))\n\t\t{\n\t\t\tcp += 3;\n\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\n\t\t\tvStringClear (name);\n\t\t\twhile (isalnum (*cp)  ||  *cp == '_')\n\t\t\t{\n\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\tmakeSimpleTag (name, HXTAG_VARIABLE);\n\n\t\t\tvStringClear (name);\n\t\t}\n\t\telse if (strncmp ((const char*) cp, \"function\", (size_t) 8) == 0  &&\n\t\t\tisspace (cp [8]))\n\t\t{\n\t\t\tcp += 8;\n\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\n\t\t\tvStringClear (name);\n\t\t\twhile (isalnum (*cp)  ||  *cp == '_')\n\t\t\t{\n\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\tmakeSimpleTag (name, HXTAG_METHODS);\n\n\t\t\tvStringClear (name);\n\t\t}\n\t\telse if (strncmp ((const char*) cp, \"class\", (size_t) 5) == 0 &&\n\t\t\t\t isspace (cp [5]))\n\t\t{\n\t\t\tcp += 5;\n\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tvStringClear (name);\n\t\t\twhile (isalnum (*cp)  ||  *cp == '_')\n\t\t\t{\n\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\tmakeSimpleTag (name, HXTAG_CLASS);\n\t\t\tvStringCopy(clsName,name);\n\t\t\tvStringClear (name);\n\t\t}\n\t\telse if (strncmp ((const char*) cp, \"enum\", (size_t) 4) == 0 &&\n\t\t\t\t  isspace (cp [4]))\n\t\t{\n\t\t\tcp += 4;\n\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tvStringClear (name);\n\t\t\twhile (isalnum (*cp)  ||  *cp == '_')\n\t\t\t{\n\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\tmakeSimpleTag (name, HXTAG_ENUM);\n\t\t\tvStringClear (name);\n\t\t} else if (strncmp ((const char*) cp, \"public\", (size_t) 6) == 0 &&\n\t\t\t\t isspace(cp [6]))\n\t\t{\n\t\t\tcp += 6;\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tvStringCopyS(laccess,pub);\n\t\t\tgoto another;\n\t\t} else if (strncmp ((const char*) cp, \"static\", (size_t) 6) == 0 &&\n\t\t\t\t isspace(cp [6]))\n\t\t{\n\t\t\tcp += 6;\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tgoto another;\n\t\t} else if (strncmp ((const char*) cp, \"interface\", (size_t) 9) == 0 &&\n\t\t\tisspace(cp [9]))\n\t\t{\n\t\t\tcp += 9;\n\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tvStringClear (name);\n\t\t\twhile (isalnum (*cp)  ||  *cp == '_') {\n\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\tmakeSimpleTag (name, HXTAG_INTERFACE);\n\t\t\tvStringClear (name);\n\t\t} else if (strncmp ((const char *) cp,\"typedef\",(size_t) 7) == 0 && isspace((cp[7]))) {\n\t\t\tcp += 7;\n\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tvStringClear (name);\n\t\t\twhile (isalnum (*cp)  ||  *cp == '_') {\n\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\tmakeSimpleTag (name, HXTAG_TYPEDEF);\n\t\t\tvStringClear (name);\n\t\t}\n\n\n\t}\n\n\tvStringDelete(name);\n\tvStringDelete(clsName);\n\tvStringDelete(scope2);\n\tvStringDelete(laccess);\n}\n\n\n/* Create parser definition structure */\nextern parserDefinition* HaxeParser (void)\n{\n\tstatic const char *const extensions [] = { \"hx\", NULL };\n\n\tparserDefinition *const def = parserNew (\"Haxe\");\n\tdef->extensions = extensions;\n\n\tstatic selectLanguage selectors[] = { selectHaxeOrQemuHXByCommentMarker, NULL };\n\n\t/*\n\t * New definitions for parsing instead of regex\n\t */\n\tdef->kindTable          = HxKinds;\n\tdef->kindCount  = ARRAY_SIZE (HxKinds);\n\tdef->parser             = findHxTags;\n\tdef->selectLanguage = selectors;\n\t/*def->initialize = initialize;*/\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/html.c",
    "content": "/*\n*   Copyright (c) 2016, Jiri Techet\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for HTML language\n*   files.\n*/\n\n#include \"general.h\"\n\n#include <string.h>\n#include <ctype.h>\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"keyword.h\"\n#include \"promise.h\"\n#include \"trace.h\"\n\n#include \"x-jscript.h\"\n\n/* The max. number of nested elements - prevents further recursion if the limit\n * is exceeded and avoids stack overflow for invalid input containing too many\n * open tags */\n#define MAX_DEPTH 1000\n\n\ntypedef enum {\n\tK_ANCHOR,\n\tK_CLASS,\n\tK_TITLE,\n\tK_HEADING1,\n\tK_HEADING2,\n\tK_HEADING3,\n\tK_STYELSHEET,\n\tK_ID,\n\tK_SCRIPT,\n} htmlKind;\n\n\ntypedef enum {\n\tCLASS_KIND_ATTRIBUTE_ROLE,\n} ClassRole;\n\ntypedef enum {\n\tSCRIPT_KIND_EXTERNAL_FILE_ROLE,\n} ScriptRole;\n\ntypedef enum {\n\tSTYLESHEET_KIND_EXTERNAL_FILE_ROLE,\n} StylesheetRole;\n\nstatic roleDefinition ClassRoles [] = {\n\t{ true, \"attribute\", \"assigned as attributes\" },\n};\n\nstatic roleDefinition ScriptRoles [] = {\n\t{ true, \"extFile\", \"referenced as external files\" },\n};\n\nstatic roleDefinition StylesheetRoles [] = {\n\t{ true, \"extFile\", \"referenced as external files\" },\n};\n\nstatic kindDefinition HtmlKinds [] = {\n\t{ true, 'a', \"anchor\",\t\t\"named anchors\" },\n\t{ true, 'c', \"class\",\t\t\"classes\",\n\t  .referenceOnly = true, ATTACH_ROLES (ClassRoles)},\n\t{ true, 't', \"title\",\t\t\"titles\" },\n\t{ true, 'h', \"heading1\",\t\"H1 headings\" },\n\t{ true, 'i', \"heading2\",\t\"H2 headings\" },\n\t{ true, 'j', \"heading3\",\t\"H3 headings\" },\n\t{ true, 'C', \"stylesheet\",\t\"stylesheets\",\n\t  .referenceOnly = true, ATTACH_ROLES (StylesheetRoles)},\n\t{ true, 'I', \"id\",\t\t\t\"identifiers\" },\n\t{ true, 'J', \"script\",\t\t\"scripts\",\n\t  .referenceOnly = true, ATTACH_ROLES (ScriptRoles)},\n};\n\ntypedef enum {\n\t/* The order starting from \"title\" to \"h3\" should\n\t * not be changed.\n\t *\n\t */\n\tKEYWORD_heading_start,\n\tKEYWORD_title = KEYWORD_heading_start,\n\tKEYWORD_h1,\n\tKEYWORD_h2,\n\tKEYWORD_h3,\n\tKEYWORD_heading_end = KEYWORD_h3,\n\tKEYWORD_a,\n\tKEYWORD_script,\n\tKEYWORD_style,\n\tKEYWORD_name,\n\n\t/* void elements */\n\tKEYWORD_area,\n\tKEYWORD_base,\n\tKEYWORD_br,\n\tKEYWORD_class,\n\tKEYWORD_col,\n\tKEYWORD_command,\n\tKEYWORD_embed,\n\tKEYWORD_hr,\n\tKEYWORD_href,\n\tKEYWORD_id,\n\tKEYWORD_img,\n\tKEYWORD_input,\n\tKEYWORD_keygen,\n\tKEYWORD_link,\n\tKEYWORD_meta,\n\tKEYWORD_param,\n\tKEYWORD_rel,\n\tKEYWORD_source,\n\tKEYWORD_src,\n\tKEYWORD_track,\n\tKEYWORD_wbr\n} keywordId;\n\nstatic const keywordTable HtmlKeywordTable[] = {\n\t{\"title\", KEYWORD_title},\n\t{\"h1\", KEYWORD_h1},\n\t{\"h2\", KEYWORD_h2},\n\t{\"h3\", KEYWORD_h3},\n\t{\"a\", KEYWORD_a},\n\t{\"script\", KEYWORD_script},\n\t{\"style\", KEYWORD_style},\n\t{\"name\", KEYWORD_name},\n\n\t/* void elements */\n\t{\"area\", KEYWORD_area},\n\t{\"base\", KEYWORD_base},\n\t{\"br\", KEYWORD_br},\n\t{\"class\", KEYWORD_class},\n\t{\"col\", KEYWORD_col},\n\t{\"command\", KEYWORD_command},\n\t{\"embed\", KEYWORD_embed},\n\t{\"hr\", KEYWORD_hr},\n\t{\"href\", KEYWORD_href},\n\t{\"id\", KEYWORD_id},\n\t{\"img\", KEYWORD_img},\n\t{\"input\", KEYWORD_input},\n\t{\"keygen\", KEYWORD_keygen},\n\t{\"link\", KEYWORD_link},\n\t{\"meta\", KEYWORD_meta},\n\t{\"param\", KEYWORD_param},\n\t{\"rel\", KEYWORD_rel},\n\t{\"source\", KEYWORD_source},\n\t{\"src\", KEYWORD_src},\n\t{\"track\", KEYWORD_track},\n\t{\"wbr\", KEYWORD_wbr},\n};\n\ntypedef enum {\n\tTOKEN_EOF,\n\tTOKEN_NAME,\t\t\t/* tag and attribute names */\n\tTOKEN_STRING,\t\t/* single- or double-quoted attribute value */\n\tTOKEN_TEXT,\n\tTOKEN_OPEN_TAG_START,\t/* <  */\n\tTOKEN_CLOSE_TAG_START,\t/* </ */\n\tTOKEN_TAG_END,\t\t/* >  */\n\tTOKEN_TAG_END2,\t\t/* /> */\n\tTOKEN_EQUAL,\n\tTOKEN_COMMENT,\n\tTOKEN_OTHER\n} tokenType;\n\n#ifdef DEBUG\nstatic const char *tokenTypes[] = {\n#define E(X) [TOKEN_##X] = #X\n\tE(EOF),\n\tE(NAME),\n\tE(STRING),\n\tE(TEXT),\n\tE(OPEN_TAG_START),\n\tE(CLOSE_TAG_START),\n\tE(TAG_END),\n\tE(TAG_END2),\n\tE(EQUAL),\n\tE(COMMENT),\n\tE(OTHER),\n#undef E\n};\n#endif\n\ntypedef struct {\n\ttokenType type;\n\tvString *string;\n} tokenInfo;\n\n\nstatic int Lang_html;\n\n\nstatic void readTag (tokenInfo *token, vString *text, int depth, bool asJSX);\n\nstatic void skipOtherScriptContent (const int delimiter);\n\nstatic void skipJavaScriptObjectExpression (void)\n{\n\tungetcToInputFile ('{');\n\tjavaScriptSkipObjectExpression ();\n}\n\nstatic void readTokenText (tokenInfo *const token, bool collectText, bool asJSX)\n{\n\tint c;\n\tint lastC = 'X';  /* whatever non-space character */\n\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tc = getcFromInputFile ();\n\n\tswitch (c)\n\t{\n\t\tcase EOF:\n\t\t\ttoken->type = TOKEN_EOF;\n\t\t\tbreak;\n\n\t\tcase '<':\n\t\t\tungetcToInputFile (c);\n\t\t\ttoken->type = TOKEN_TEXT;\n\t\t\tbreak;\n\n\t\tcase '{':\n\t\t\tif (asJSX)\n\t\t\t{\n\t\t\t\t/* If we find {...} in HTML in JSXElement,\n\t\t\t\t * replace it with a whitespace ' '. */\n\t\t\t\tskipJavaScriptObjectExpression ();\n\t\t\t\tc = ' ';\n\t\t\t}\n\t\t\t/* FALLTHROUGH */\n\t\tdefault:\n\t\t\tif (collectText)\n\t\t\t{\n\t\t\t\tif (isspace (c))\n\t\t\t\t\tc = ' ';\n\t\t\t\tif (c != ' ' || lastC != ' ')\n\t\t\t\t{\n\t\t\t\t\tvStringPut (token->string, c);\n\t\t\t\t\tlastC = c;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tgoto getNextChar;\n\t}\n}\n\nstatic void readTokenInScript (tokenInfo *const token)\n{\n\tint c;\n\n\tvStringClear (token->string);\n\n\tc = getcFromInputFile ();\n\twhile (isspace (c))\n\t\tc = getcFromInputFile ();\n\n\tswitch (c)\n\t{\n\t\tcase EOF:\n\t\t\ttoken->type = TOKEN_EOF;\n\t\t\tbreak;\n\n\t\tcase '<':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '/')\n\t\t\t\ttoken->type = TOKEN_CLOSE_TAG_START;\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_OTHER;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t{\n\t\t\twhile (!isspace (c) && c != '<' && c != '>' && c != '/' &&\n\t\t\t\t   c != '=' && c != '\\'' && c != '\"' && c != EOF)\n\t\t\t{\n\t\t\t\tvStringPut (token->string, tolower (c));\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t}\n\n\t\t\tif (vStringLength (token->string) == 0)\n\t\t\t\ttoken->type = TOKEN_OTHER;\n\t\t\telse\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_NAME;\n\t\t\t\tif (c != EOF)\n\t\t\t\t\tungetcToInputFile (c);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tTRACE_PRINT(\"token (in script): %s (%s)\", tokenTypes[token->type], vStringValue (token->string));\n}\n\nstatic void readToken (tokenInfo *const token, bool skipComments, bool asJSX)\n{\n\tint c;\n\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tc = getcFromInputFile ();\n\twhile (isspace (c))\n\t\tc = getcFromInputFile ();\n\n\tswitch (c)\n\t{\n\t\tcase EOF:\n\t\t\ttoken->type = TOKEN_EOF;\n\t\t\tbreak;\n\n\t\tcase '<':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '!')\n\t\t\t{\n\t\t\t\td = getcFromInputFile ();\n\t\t\t\tif (d == '-')\n\t\t\t\t{\n\t\t\t\t\td = getcFromInputFile ();\n\t\t\t\t\tif (d == '-')\n\t\t\t\t\t{\n\t\t\t\t\t\tint e = ' ';\n\t\t\t\t\t\tint f = ' ';\n\t\t\t\t\t\tdo\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\td = e;\n\t\t\t\t\t\t\te = f;\n\t\t\t\t\t\t\tf = getcFromInputFile ();\n\t\t\t\t\t\t}\n\t\t\t\t\t\twhile (f != EOF && ! (d == '-' && e == '-' && f == '>'));\n\n\t\t\t\t\t\tif (skipComments)\n\t\t\t\t\t\t\tgoto getNextChar;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttoken->type = TOKEN_COMMENT;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_OTHER;\n\t\t\t}\n\t\t\telse if (d == '?')\n\t\t\t{\n\t\t\t\tskipOtherScriptContent(d);\n\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\telse if (d == '/')\n\t\t\t\ttoken->type = TOKEN_CLOSE_TAG_START;\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_OPEN_TAG_START;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase '/':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '>')\n\t\t\t\ttoken->type = TOKEN_TAG_END2;\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_OTHER;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase '>':\n\t\t\ttoken->type = TOKEN_TAG_END;\n\t\t\tbreak;\n\n\t\tcase '=':\n\t\t\ttoken->type = TOKEN_EQUAL;\n\t\t\tbreak;\n\n\t\tcase '\"':\n\t\tcase '\\'':\n\t\t{\n\t\t\tconst int delimiter = c;\n\t\t\tc = getcFromInputFile ();\n\t\t\twhile (c != EOF && c != delimiter)\n\t\t\t{\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t}\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '{':\n\t\t\tif (asJSX)\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_STRING;\n\t\t\t\tskipJavaScriptObjectExpression ();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t/* FALLTHROUGH */\n\n\t\tdefault:\n\t\t{\n\t\t\tdo\n\t\t\t{\n\t\t\t\tvStringPut (token->string, tolower (c));\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t}\n\t\t\twhile (!isspace (c) && c != '<' && c != '>' && c != '/' &&\n\t\t\t\t   c != '=' && c != '\\'' && c != '\"' && c != EOF);\n\t\t\tif (c != EOF)\n\t\t\t\tungetcToInputFile (c);\n\t\t\ttoken->type = TOKEN_NAME;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tTRACE_PRINT(\"token: %s (%s)\", tokenTypes[token->type], vStringValue (token->string));\n}\n\nstatic void appendText (vString *text, vString *appendedText)\n{\n\tif (text != NULL && vStringLength (appendedText) > 0)\n\t{\n\t\tif (vStringLength (text) > 0 && vStringLast (text) == ' ' &&\n\t\t\tvStringLength (appendedText) > 0 && vStringChar (appendedText, 0) == ' ')\n\t\t{\n\t\t\tvStringStripTrailing (text);\n\t\t}\n\t\tvStringCat (text, appendedText);\n\t}\n}\n\nstatic bool readTagContent (tokenInfo *token, vString *text, long *line, long *column, int depth, bool asJSX)\n{\n\tTRACE_ENTER();\n\n\ttokenType type;\n\n\treadTokenText (token, text != NULL, asJSX);\n\tappendText (text, token->string);\n\n\tdo\n\t{\n\t\t*line = getInputLineNumber ();\n\t\t*column = getInputColumnNumber ();\n\t\treadToken (token, false, asJSX);\n\t\ttype = token->type;\n\t\tif (type == TOKEN_OPEN_TAG_START)\n\t\t\treadTag (token, text, depth + 1, asJSX);\n\t\tif (type == TOKEN_COMMENT || type == TOKEN_OPEN_TAG_START)\n\t\t{\n\t\t\treadTokenText (token, text != NULL, asJSX);\n\t\t\tappendText (text, token->string);\n\t\t}\n\t}\n\twhile (type == TOKEN_COMMENT || type == TOKEN_OPEN_TAG_START);\n\n\tTRACE_LEAVE_TEXT(\"is_close_tag? %d\", type == TOKEN_CLOSE_TAG_START);\n\n\treturn type == TOKEN_CLOSE_TAG_START;\n}\n\nstatic bool skipScriptContent (tokenInfo *token, long *line, long *column)\n{\n\tTRACE_ENTER();\n\n\tbool found_start = false;\n\tbool found_script = false;\n\n\tlong line_tmp[2] = {0};\n\tlong column_tmp[2] = {0};\n\n\ttokenType type;\n\n\tdo\n\t{\n\t\tline_tmp[0] = getInputLineNumber ();\n\t\tcolumn_tmp[0] = getInputColumnNumber ();\n\n\t\treadTokenInScript (token);\n\t\ttype = token->type;\n\n\t\tif (type == TOKEN_CLOSE_TAG_START)\n\t\t{\n\t\t\tfound_start = true;\n\t\t\tline_tmp[1] = line_tmp[0];\n\t\t\tcolumn_tmp[1] = column_tmp[0];\n\t\t}\n\t\telse if (found_start\n\t\t\t\t && type == TOKEN_NAME\n\t\t\t\t && lookupKeyword (vStringValue (token->string), Lang_html) == KEYWORD_script)\n\t\t{\n\t\t\tfound_script = true;\n\t\t\t*line = line_tmp[1];\n\t\t\t*column = column_tmp[1];\n\t\t}\n\t\telse\n\t\t\tfound_start = false;\n\t}\n\twhile ((type != TOKEN_EOF) && (!found_script));\n\n\tTRACE_LEAVE_TEXT(\"found_script? %d\", found_script);\n\n\treturn found_script;\n}\n\nstatic void skipOtherScriptContent (const int delimiter)\n{\n\tTRACE_ENTER();\n\n\tconst long startSourceLineNumber = getSourceLineNumber ();\n\tconst long startLineNumber = getInputLineNumber ();\n\tconst long startColumn = getInputColumnNumber () - 2; /* strlen (\"<?\") */\n\n\tvString *script_name = vStringNew ();\n\tbool reading_script_name = true;\n\twhile (1)\n\t{\n\t\tint c = getcFromInputFile ();\n\t\tif (c == EOF)\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\telse if (reading_script_name && !isspace(c))\n\t\t{\n\t\t\tvStringPut (script_name, c);\n\t\t}\n\t\telse if (reading_script_name)\n\t\t{\n\t\t\treading_script_name = false;\n\t\t}\n\t\telse if (c == delimiter)\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == '>')\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tungetcToInputFile (c);\n\t\t}\n\t}\n\n\tif (strcasecmp (\"php\", vStringValue (script_name)) == 0\n\t\t|| strcmp (\"=\", vStringValue (script_name)) == 0)\n\t\tmakePromise (\"PHP\", startLineNumber, startColumn,\n\t\t\t\t\t getInputLineNumber (), getInputColumnNumber (),\n\t\t\t\t\t startSourceLineNumber);\n\n\tvStringDelete (script_name);\n\n\tTRACE_LEAVE();\n}\n\nstatic void makeClassRefTags (const char *classes)\n{\n\tvString *klass = vStringNew ();\n\n\tdo\n\t{\n\t\tif (*classes && !isspace ((unsigned char) *classes))\n\t\t\tvStringPut (klass, *classes);\n\t\telse if (!vStringIsEmpty (klass))\n\t\t{\n\t\t\tmakeSimpleRefTag (klass, K_CLASS,\n\t\t\t\t\t\t\t  CLASS_KIND_ATTRIBUTE_ROLE);\n\t\t\tvStringClear (klass);\n\t\t}\n\n\t\tif (!*classes)\n\t\t\tbreak;\n\n\t\tclasses++;\n\t} while (1);\n\n\tvStringDelete (klass);\n}\n\nstatic void readTag (tokenInfo *token, vString *text, int depth, bool asJSX)\n{\n\tTRACE_ENTER();\n\n\tbool textCreated = false;\n\n\treadToken (token, true, asJSX);\n\tif (asJSX && token->type == TOKEN_TAG_END)\n\t{\n\t\t/* Accept <> */\n\t\tungetcToInputFile ('>');\n\t\ttoken->type = TOKEN_NAME;\n\t\tvStringClear (token->string);\n\t}\n\n\tif (token->type == TOKEN_NAME)\n\t{\n\t\tkeywordId startTag;\n\t\tbool isHeading;\n\t\tbool isVoid;\n\t\tvString *stylesheet = NULL;\n\t\tbool stylesheet_expectation = false;\n\n\t\tstartTag = lookupKeyword (vStringValue (token->string), Lang_html);\n\t\tisHeading = (KEYWORD_heading_start <= startTag && startTag <= KEYWORD_heading_end);\n\t\tisVoid = (startTag >= KEYWORD_area && startTag <= KEYWORD_wbr);\n\t\tif (text == NULL && isHeading)\n\t\t{\n\t\t\ttext = vStringNew ();\n\t\t\ttextCreated = true;\n\t\t}\n\n\t\tdo\n\t\t{\n\t\t\tkeywordId attribute = KEYWORD_NONE;\n\n\t\t\treadToken (token, true, asJSX);\n\t\t\tif (token->type == TOKEN_NAME)\n\t\t\t\tattribute = lookupKeyword (vStringValue (token->string), Lang_html);\n\n\t\t\tif (attribute == KEYWORD_class)\n\t\t\t{\n\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\tif (token->type == TOKEN_EQUAL)\n\t\t\t\t{\n\t\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\t\tif (token->type == TOKEN_STRING\n\t\t\t\t\t\t&& !vStringIsEmpty (token->string))\n\t\t\t\t\t\tmakeClassRefTags (vStringValue (token->string));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (attribute == KEYWORD_id)\n\t\t\t{\n\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\tif (token->type == TOKEN_EQUAL)\n\t\t\t\t{\n\t\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\t\tif (token->type == TOKEN_STRING)\n\t\t\t\t\t\tmakeSimpleTag (token->string, K_ID);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (startTag == KEYWORD_a && attribute == KEYWORD_name)\n\t\t\t{\n\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\tif (token->type == TOKEN_EQUAL)\n\t\t\t\t{\n\t\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\t\tif (token->type == TOKEN_STRING || token->type == TOKEN_NAME)\n\t\t\t\t\t\tmakeSimpleTag (token->string, K_ANCHOR);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (startTag == KEYWORD_script && attribute == KEYWORD_src)\n\t\t\t{\n\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\tif (token->type == TOKEN_EQUAL)\n\t\t\t\t{\n\t\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\t\tif (token->type == TOKEN_STRING)\n\t\t\t\t\t\tmakeSimpleRefTag (token->string, K_SCRIPT,\n\t\t\t\t\t\t\t\t\t\t  SCRIPT_KIND_EXTERNAL_FILE_ROLE);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (startTag == KEYWORD_link)\n\t\t\t{\n\t\t\t\tif (attribute == KEYWORD_rel)\n\t\t\t\t{\n\t\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\t\tif (token->type == TOKEN_EQUAL)\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\t\t\tif (token->type == TOKEN_STRING &&\n\t\t\t\t\t\t\t/* strcmp is not enough:\n\t\t\t\t\t\t\t * e.g. <link href=\"fancy.css\"\n\t\t\t\t\t\t\t *            rel=\"alternate stylesheet\" title=\"Fancy\"> */\n\t\t\t\t\t\t\tvStringLength(token->string) >= 10 &&\n\t\t\t\t\t\t\tstrstr (vStringValue (token->string), \"stylesheet\"))\n\t\t\t\t\t\t\tstylesheet_expectation = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (attribute == KEYWORD_href)\n\t\t\t\t{\n\t\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\t\tif (token->type == TOKEN_EQUAL)\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\t\t\tif (token->type == TOKEN_STRING)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (stylesheet == NULL)\n\t\t\t\t\t\t\t\tstylesheet = vStringNewCopy (token->string);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tvStringCopy (stylesheet, token->string);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (stylesheet_expectation && stylesheet && !vStringIsEmpty (stylesheet))\n\t\t\t\t{\n\t\t\t\t\tmakeSimpleRefTag (stylesheet, K_STYELSHEET,\n\t\t\t\t\t\t\t\t\t  STYLESHEET_KIND_EXTERNAL_FILE_ROLE);\n\t\t\t\t\tstylesheet_expectation = false;\n\t\t\t\t\tif (stylesheet)\n\t\t\t\t\t\tvStringClear (stylesheet);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\twhile (token->type != TOKEN_TAG_END && token->type != TOKEN_TAG_END2 &&\n\t\t\t   token->type != TOKEN_EOF);\n\n\t\tvStringDelete (stylesheet);\n\t\tstylesheet = NULL;\n\n\t\tif (!isVoid && token->type == TOKEN_TAG_END && depth < MAX_DEPTH)\n\t\t{\n\t\t\tlong startSourceLineNumber = getSourceLineNumber ();\n\t\t\tlong startLineNumber = getInputLineNumber ();\n\t\t\tlong startColumn = getInputColumnNumber ();\n\t\t\tlong endLineNumber;\n\t\t\tlong endColumn;\n\t\t\tbool tag_start2;\n\n\t\t\tif (startTag == KEYWORD_script)\n\t\t\t{\n\t\t\t\tbool script = skipScriptContent (token, &endLineNumber, &endColumn);\n\t\t\t\tif (script)\n\t\t\t\t\tmakePromise (\"JavaScript\", startLineNumber, startColumn,\n\t\t\t\t\t\t\t\t endLineNumber, endColumn, startSourceLineNumber);\n\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\tgoto out;\n\t\t\t}\n\n\t\t\ttag_start2 = readTagContent (token, text, &endLineNumber, &endColumn, depth, asJSX);\n\t\t\tif (tag_start2)\n\t\t\t{\n\t\t\t\treadToken (token, true, asJSX);\n\t\t\t\tif (asJSX && token->type == TOKEN_TAG_END)\n\t\t\t\t{\n\t\t\t\t\t/* Accept </> */\n\t\t\t\t\tungetcToInputFile ('>');\n\t\t\t\t\ttoken->type = TOKEN_NAME;\n\t\t\t\t\tvStringClear (token->string);\n\t\t\t\t}\n\n\t\t\t\tif (isHeading && textCreated && vStringLength (text) > 0)\n\t\t\t\t{\n\t\t\t\t\tkeywordId endTag = lookupKeyword (vStringValue (token->string), Lang_html);\n\t\t\t\t\tif (startTag == endTag)\n\t\t\t\t\t{\n\t\t\t\t\t\thtmlKind headingKind;\n\n\t\t\t\t\t\tif (startTag == KEYWORD_title)\n\t\t\t\t\t\t\theadingKind = K_TITLE;\n\t\t\t\t\t\tif (startTag == KEYWORD_h1)\n\t\t\t\t\t\t\theadingKind = K_HEADING1;\n\t\t\t\t\t\telse if (startTag == KEYWORD_h2)\n\t\t\t\t\t\t\theadingKind = K_HEADING2;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\theadingKind = K_HEADING3;\n\n\t\t\t\t\t\tvStringStripLeading (text);\n\t\t\t\t\t\tvStringStripTrailing (text);\n\t\t\t\t\t\tmakeSimpleTag (text, headingKind);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (startTag == KEYWORD_style)\n\t\t\t\t{\n\t\t\t\t\tkeywordId endTag = lookupKeyword (vStringValue (token->string), Lang_html);\n\t\t\t\t\tif (startTag == endTag)\n\t\t\t\t\t\tmakePromise (\"CSS\", startLineNumber, startColumn,\n\t\t\t\t\t\t\t\t\t endLineNumber, endColumn, startSourceLineNumber);\n\t\t\t\t}\n\n\t\t\t\treadToken (token, true, asJSX);\n\t\t\t}\n\t\t}\n\t}\n\n out:\n\tif (textCreated)\n\t\tvStringDelete (text);\n\n\tTRACE_LEAVE();\n}\n\nstatic void findHtmlTags (void)\n{\n\tTRACE_ENTER();\n\n\ttokenInfo token;\n\n\ttoken.string = vStringNew ();\n\n\tdo\n\t{\n\t\treadToken (&token, true, false);\n\t\tif (token.type == TOKEN_OPEN_TAG_START)\n\t\t\treadTag (&token, NULL, 0, false);\n\t}\n\twhile (token.type != TOKEN_EOF);\n\n\tvStringDelete (token.string);\n\n\tTRACE_LEAVE();\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_html = language;\n}\n\n/* parser definition */\nextern parserDefinition* HtmlParser (void)\n{\n\tstatic const char *const extensions [] = { \"htm\", \"html\", NULL };\n\tparserDefinition* def = parserNew (\"HTML\");\n\tdef->kindTable        = HtmlKinds;\n\tdef->kindCount    = ARRAY_SIZE (HtmlKinds);\n\tdef->extensions   = extensions;\n\tdef->parser       = findHtmlTags;\n\tdef->initialize   = initialize;\n\tdef->keywordTable = HtmlKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (HtmlKeywordTable);\n\treturn def;\n}\n\n/* Just another entry point for handling JSX */\nextern void htmlParseJSXElement (void)\n{\n\tpushLanguage (Lang_html);\n\t{\n\t\tTRACE_ENTER();\n\n\t\ttokenInfo token;\n\t\ttoken.string = vStringNew ();\n\n\t\treadToken (&token, true, true);\n\t\tif (token.type == TOKEN_OPEN_TAG_START)\n\t\t\treadTag (&token, NULL, 0, true);\n\n\t\tvStringDelete (token.string);\n\n\t\tTRACE_LEAVE();\n\t}\n\tpopLanguage ();\n}\n"
  },
  {
    "path": "parsers/i18nrubygem.c",
    "content": "/*\n*\n*   Copyright (c) 2023, Masatake YAMATO\n*   Copyright (c) 2023, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for tagging input for I18n Ruby Gem.\n*\n*   References:\n*   - https://guides.rubyonrails.org/i18n.html#setup-the-rails-application-for-internationalization\n*   - https://github.com/ruby-i18n/i18n\n*/\n\n/*\n *\t INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n\n#include \"x-yaml.h\"\n\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"kind.h\"\n#include \"numarray.h\"\n#include \"read.h\"\n#include \"parse.h\"\n#include \"subparser.h\"\n\n/*\n *\t MACROS\n */\n\n/*\n *\t DATA DECLARATIONS\n */\n\ntypedef enum {\n\tKIND_KEY,\n\tKIND_KEY_IN_MIDDLE,\n\tKIND_LOCALE,\n} i18nRubyGemKind;\n\ntypedef enum {\n\tX_localeless,\n\tX_localeful,\n} i18nRubyGemXtag;\n\nstruct sI18nRubyGemSubparser {\n\tyamlSubparser yaml;\n\tint depth;\n\tenum { LOCALE_NOTYET = -1, LOCALE_NONE, LOCALE_FOUND } localeFound;\n\tint corkIndex;\n\tintArray *keys;\n};\n\nenum {\n\tKEYWORD_LOCALE,\n};\n\n/*\n *\t FUNCTION DECLARATIONS\n */\nstatic bool i18nRubyGemInitTagEntry(tagEntryInfo *e, yamlSubparser *yaml, char *key, void * data CTAGS_ATTR_UNUSED);\n\n/*\n *\tDATA DEFINITIONS\n */\n\nstatic kindDefinition I18nRubyGemKind [] = {\n\t{ true,  'k', \"key\",         \"translation keys at the leafs\" },\n\t{ false, 'm', \"keyInMiddle\", \"the middle component of keys\"  },\n\t{ false, 'l', \"locale\",      \"the root element representing a locale\"},\n};\n\nstatic xtagDefinition I18nRubyGemXtagTable [] = {\n\t{\n\t\t.enabled = true,\n\t\t.name = \"localeless\",\n\t\t.description = \"full qualifies translation key without locale component\",\n\t},\n\t{\n\t\t.enabled = true,\n\t\t.name = \"localeful\",\n\t\t.description = \"full qualifies translation key with locale component\",\n\t},\n};\n\nstatic tagYpathTable ypathTables [] = {\n#define E(PAT) { PAT, YPATH_DSTAT_LAST_KEY, KIND_GHOST_INDEX, \\\n\t\t.initTagEntry = i18nRubyGemInitTagEntry, }\n\n\t/* TODO: This should be written in E(\"**\"); */\n\tE(\"*\"),\n\tE(\"*/*\"),\n\tE(\"*/*/*\"),\n\tE(\"*/*/*/*\"),\n\tE(\"*/*/*/*/*\"),\n\tE(\"*/*/*/*/*/*\"),\n\tE(\"*/*/*/*/*/*/*\"),\n\tE(\"*/*/*/*/*/*/*/*\"),\n\tE(\"*/*/*/*/*/*/*/*/*\"),\n\tE(\"*/*/*/*/*/*/*/*/*/*\"),\n\tE(\"*/*/*/*/*/*/*/*/*/*/*\"),\n\tE(\"*/*/*/*/*/*/*/*/*/*/*/*\"),\n\tE(\"*/*/*/*/*/*/*/*/*/*/*/*/*\"),\n\tE(\"*/*/*/*/*/*/*/*/*/*/*/*/*/*\"),\n\tE(\"*/*/*/*/*/*/*/*/*/*/*/*/*/*/*\"),\n};\n\ntypedef int keywordId;\nstatic const struct keywordGroup i18nRubyGemLocales;\n\nstatic langType Lang_i18nrubygem;\n\n/*\n *\t FUNCTION DEFINITIONS\n */\nstatic bool isLocaleName (const char *key)\n{\n\treturn (lookupKeyword (key, Lang_i18nrubygem) == KEYWORD_LOCALE);\n}\n\nstatic bool i18nRubyGemInitTagEntry(tagEntryInfo *e, yamlSubparser *yaml, char *key, void * data CTAGS_ATTR_UNUSED)\n{\n\tstruct sI18nRubyGemSubparser *i18n = (struct sI18nRubyGemSubparser *)yaml;\n\ti18nRubyGemKind kindIndex = KIND_KEY;\n\n\tif (key[0] == ':')\n\t\tkey = key + 1;\n\n\tif (i18n->localeFound == LOCALE_NOTYET)\n\t{\n\t\tint depth = (int)ypathGetTypeStackDepth(yaml);\n\t\tif (depth == 1)\n\t\t{\n\t\t\tif (isLocaleName (key))\n\t\t\t{\n\t\t\t\tkindIndex = KIND_LOCALE;\n\t\t\t\ti18n->localeFound = LOCALE_FOUND;\n\t\t\t}\n\t\t\telse\n\t\t\t\ti18n->localeFound = LOCALE_NONE;\n\t\t}\n\t}\n\n\tif (i18n->localeFound != LOCALE_FOUND)\n\t\treturn false;\n\n\tinitTagEntry (e, key, kindIndex);\n\treturn true;\n}\n\nstatic void findI18nRubyGemTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nstatic void inputStart (subparser *s)\n{\n\tstruct sI18nRubyGemSubparser *i18n = (struct sI18nRubyGemSubparser *)s;\n\ti18n->depth = -1;\n\ti18n->corkIndex = CORK_NIL;\n\ti18n->keys = intArrayNew ();\n\ti18n->localeFound = LOCALE_NOTYET;\n}\n\nstatic int buildNameandReturnRoot (int corkIndex, vString *buf, int root)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\n\tif (e)\n\t{\n\t\tint parent = e->extensionFields.scopeIndex;\n\t\tif (parent == CORK_NIL)\n\t\t{\n\t\t\tif (root == 0)\n\t\t\t\tvStringCatS(buf, e->name);\n\t\t\treturn corkIndex;\n\t\t}\n\n\t\tint r = buildNameandReturnRoot (parent, buf, root);\n\t\tvStringJoinS (buf, '.', e->name);\n\t\treturn r;\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic void makeLocaleXTag (const tagEntryInfo *const e0, vString *buf, i18nRubyGemXtag xtag)\n{\n\ttagEntryInfo e  = *e0;\n\tresetTagCorkState (&e, RESET_TAG_MEMBER_CLEAR, RESET_TAG_MEMBER_CLEAR);\n\te.skipAutoFQEmission = 1;\n\n\tmarkTagExtraBit (&e, I18nRubyGemXtagTable[xtag].xtype);\n\tif (xtag == X_localeless)\n\t\te.extensionFields.scopeIndex\n\t\t\t= buildNameandReturnRoot (e.extensionFields.scopeIndex,\n\t\t\t\t\t\t\t\t\t  buf, 1);\n\telse\n\t\t(void)buildNameandReturnRoot (e.extensionFields.scopeIndex,\n\t\t\t\t\t\t\t\t\t  buf, 0);\n\n\tvStringJoinS (buf, '.', e.name);\n\te.name = vStringValue (buf);\n\tmakeTagEntry (&e);\n}\n\nstatic void makeLocalefulXTag (const tagEntryInfo *const e0, vString *buf)\n{\n\tmakeLocaleXTag (e0, buf, X_localeful);\n}\n\nstatic void makeLocalelessXTag (const tagEntryInfo *const e0, vString *buf)\n{\n\tmakeLocaleXTag (e0, buf, X_localeless);\n}\n\nstatic void inputEnd (subparser *s)\n{\n\tlangType i18nrubygem = getInputLanguage ();\n\tstruct sI18nRubyGemSubparser *i18n = (struct sI18nRubyGemSubparser *)s;\n\tsize_t count = intArrayCount(i18n->keys);\n\n\tvString *buf = vStringNew ();\n\tfor (unsigned int i = 0; i < count; i++)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue(intArrayItem(i18n->keys, i));\n\t\tif (e->langType != i18nrubygem)\n\t\t\tcontinue;\n\t\tif (e->kindIndex == KIND_KEY_IN_MIDDLE || e->kindIndex == KIND_LOCALE)\n\t\t\tcontinue;\n\n\t\tif (isXtagEnabled (I18nRubyGemXtagTable[X_localeless].xtype))\n\t\t{\n\t\t\tmakeLocalelessXTag (e, buf);\n\t\t\tvStringClear (buf);\n\t\t}\n\n\t\tif (isXtagEnabled (I18nRubyGemXtagTable[X_localeful].xtype))\n\t\t{\n\t\t\tmakeLocalefulXTag (e, buf);\n\t\t\tvStringClear (buf);\n\t\t}\n\t}\n\n\tvStringDelete (buf);\n\tintArrayDelete (i18n->keys);\n\ti18n->keys = NULL;\n}\n\nstatic int getAncestor(int corkIndex, int upwardSteps)\n{\n\tif (upwardSteps == 0)\n\t\treturn corkIndex;\n\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\tif (e == NULL)\n\t\treturn corkIndex;\n\n\treturn getAncestor (e->extensionFields.scopeIndex, upwardSteps - 1);\n}\n\nstatic void makeTagEntryNotifyViaYpath (yamlSubparser *s, int corkIndex)\n{\n\tint currentDepth = (int)ypathGetTypeStackDepth(s);\n\tstruct sI18nRubyGemSubparser *i18n = (struct sI18nRubyGemSubparser *)s;\n\n\tintArrayAdd (i18n->keys, corkIndex);\n\tif (i18n->depth < currentDepth)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue(corkIndex);\n\t\tif (e)\n\t\t\te->extensionFields.scopeIndex = i18n->corkIndex;\n\n\t\ttagEntryInfo *parent = getEntryInCorkQueue(i18n->corkIndex);\n\t\tif (parent && parent->kindIndex != KIND_LOCALE)\n\t\t\tparent->kindIndex = KIND_KEY_IN_MIDDLE;\n\n\t\ti18n->depth = currentDepth;\n\t\ti18n->corkIndex = corkIndex;\n\t}\n\telse if (i18n->depth == currentDepth)\n\t{\n\t\ttagEntryInfo *sibling = getEntryInCorkQueue(i18n->corkIndex);\n\t\tif (sibling)\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue(corkIndex);\n\t\t\tif (e)\n\t\t\t\te->extensionFields.scopeIndex = sibling->extensionFields.scopeIndex;\n\t\t\ti18n->corkIndex = corkIndex;\n\t\t}\n\t}\n\telse\n\t{\n\t\tint lastCorkIndex = i18n->corkIndex;\n\t\tint lastDepth = i18n->depth;\n\n\t\ti18n->depth = currentDepth;\n\t\ti18n->corkIndex = corkIndex;\n\n\t\ttagEntryInfo *e = getEntryInCorkQueue(corkIndex);\n\t\tif (e)\n\t\t{\n\t\t\tint upwardSteps = lastDepth - currentDepth + 1;\n\t\t\tAssert(upwardSteps >= 0);\n\t\t\te->extensionFields.scopeIndex = getAncestor (lastCorkIndex,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t upwardSteps);\n\t\t}\n\t}\n}\n\nstatic void initializeI18nRubyGemTags (const langType language)\n{\n\tLang_i18nrubygem = language;\n\taddKeywordGroup (&i18nRubyGemLocales, language);\n}\n\nextern parserDefinition* I18nRubyGemParser (void)\n{\n\tstatic struct sI18nRubyGemSubparser i18nRubyGemSubparser = {\n\t\t.yaml = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t\t\t.inputStart = inputStart,\n\t\t\t\t.inputEnd = inputEnd,\n\t\t\t},\n\t\t\t.ypathTables = ypathTables,\n\t\t\t.ypathTableCount = ARRAY_SIZE (ypathTables),\n\t\t\t.makeTagEntryNotifyViaYpath = makeTagEntryNotifyViaYpath,\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t{ DEPTYPE_SUBPARSER, \"Yaml\", &i18nRubyGemSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"I18nRubyGem\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable\t= I18nRubyGemKind;\n\tdef->kindCount = ARRAY_SIZE (I18nRubyGemKind);\n\tdef->xtagTable = I18nRubyGemXtagTable;\n\tdef->xtagCount = ARRAY_SIZE (I18nRubyGemXtagTable);\n\tdef->parser\t= findI18nRubyGemTags;\n\tdef->initialize = initializeI18nRubyGemTags;\n\n\tdef->requestAutomaticFQTag = true;\n\n\treturn def;\n}\n\n\f\n\nstatic const struct keywordGroup i18nRubyGemLocales = {\n\t.value = KEYWORD_LOCALE,\n\t.addingUnlessExisting = false,\n\t.keywords = {\n\t\t/* For generating this list, I did:\n\t\t *\n\t\t *\t{ ls /usr/share/locale/ | xargs -n 1 printf '\"%s\",\\n';\n\t\t *\t  ls /usr/share/locale/ | sed 's/_/-/g' | xargs -n 1 printf '\"%s\",\\n' } \\\n\t\t *\t  | sort | uniq; echo 'NULL'\n\t\t *\n\t\t *  on Fedora 39.\n\t\t *\n\t\t * rpm -qif /usr/share/locale\n\t\t * Name        : filesystem\n\t\t * Version     : 3.18\n\t\t * Release     : 6.fc39\n\t\t * Architecture: x86_64\n\t\t * Install Date: Tue 05 Dec 2023 11:56:59 PM JST\n\t\t * Group       : Unspecified\n\t\t * Size        : 106\n\t\t * License     : LicenseRef-Fedora-Public-Domain\n\t\t * Signature   : RSA/SHA256, Sat 22 Jul 2023 12:38:40 AM JST, Key ID 75cf5ac418b8e74c\n\t\t * Source RPM  : filesystem-3.18-6.fc39.src.rpm\n\t\t * ...\n\t\t * URL         : https://pagure.io/filesystem\n\t\t * Bug URL     : https://bugz.fedoraproject.org/filesystem\n\t\t * Summary     : The basic directory layout for a Linux system\n\t\t * Description :\n\t\t * The filesystem package is one of the basic packages that is installed\n\t\t * on a Linux system. Filesystem contains the basic directory layout\n\t\t * for a Linux operating system, including the correct permissions for\n\t\t * the directories.\n\t\t */\n\t\t\"aa\",\n\t\t\"ab\",\n\t\t\"ace\",\n\t\t\"ach\",\n\t\t\"ada\",\n\t\t\"ady\",\n\t\t\"ae\",\n\t\t\"af\",\n\t\t\"afa\",\n\t\t\"afh\",\n\t\t\"af-ZA\",\n\t\t\"af_ZA\",\n\t\t\"agr\",\n\t\t\"ain\",\n\t\t\"ak\",\n\t\t\"akk\",\n\t\t\"ale\",\n\t\t\"alg\",\n\t\t\"aln\",\n\t\t\"alt\",\n\t\t\"am\",\n\t\t\"an\",\n\t\t\"ang\",\n\t\t\"anp\",\n\t\t\"apa\",\n\t\t\"ar\",\n\t\t\"arc\",\n\t\t\"ar-DZ\",\n\t\t\"ar_DZ\",\n\t\t\"ar-MA\",\n\t\t\"ar_MA\",\n\t\t\"arn\",\n\t\t\"arp\",\n\t\t\"ar-SY\",\n\t\t\"ar_SY\",\n\t\t\"art\",\n\t\t\"arw\",\n\t\t\"as\",\n\t\t\"ast\",\n\t\t\"ath\",\n\t\t\"aus\",\n\t\t\"av\",\n\t\t\"awa\",\n\t\t\"ay\",\n\t\t\"ayc\",\n\t\t\"aym\",\n\t\t\"az\",\n\t\t\"az-AZ\",\n\t\t\"az_AZ\",\n\t\t\"az-IR\",\n\t\t\"az_IR\",\n\t\t\"ba\",\n\t\t\"bad\",\n\t\t\"bai\",\n\t\t\"bal\",\n\t\t\"ban\",\n\t\t\"bar\",\n\t\t\"bas\",\n\t\t\"bat\",\n\t\t\"be\",\n\t\t\"bej\",\n\t\t\"be@latin\",\n\t\t\"bem\",\n\t\t\"ber\",\n\t\t\"bg\",\n\t\t\"bg-BG\",\n\t\t\"bg_BG\",\n\t\t\"bh\",\n\t\t\"bho\",\n\t\t\"bi\",\n\t\t\"bik\",\n\t\t\"bin\",\n\t\t\"bla\",\n\t\t\"bm\",\n\t\t\"bn\",\n\t\t\"bn-BD\",\n\t\t\"bn_BD\",\n\t\t\"bn-IN\",\n\t\t\"bn_IN\",\n\t\t\"bnt\",\n\t\t\"bo\",\n\t\t\"br\",\n\t\t\"bra\",\n\t\t\"brx\",\n\t\t\"bs\",\n\t\t\"bs-BA\",\n\t\t\"bs_BA\",\n\t\t\"btk\",\n\t\t\"bua\",\n\t\t\"bug\",\n\t\t\"byn\",\n\t\t\"ca\",\n\t\t\"ca-AD\",\n\t\t\"ca_AD\",\n\t\t\"cad\",\n\t\t\"ca-ES\",\n\t\t\"ca_ES\",\n\t\t\"ca-FR\",\n\t\t\"ca_FR\",\n\t\t\"cai\",\n\t\t\"ca-IT\",\n\t\t\"ca_IT\",\n\t\t\"cak\",\n\t\t\"car\",\n\t\t\"cau\",\n\t\t\"ca.us-ascii\",\n\t\t\"ca@valencia\",\n\t\t\"ce\",\n\t\t\"ceb\",\n\t\t\"cel\",\n\t\t\"cgg\",\n\t\t\"ch\",\n\t\t\"chb\",\n\t\t\"chg\",\n\t\t\"chk\",\n\t\t\"chm\",\n\t\t\"chn\",\n\t\t\"cho\",\n\t\t\"chp\",\n\t\t\"chr\",\n\t\t\"chy\",\n\t\t\"ckb\",\n\t\t\"cmc\",\n\t\t\"cmn\",\n\t\t\"cn\",\n\t\t\"cnr\",\n\t\t\"co\",\n\t\t\"cop\",\n\t\t\"cpe\",\n\t\t\"cpf\",\n\t\t\"cpp\",\n\t\t\"cr\",\n\t\t\"crh\",\n\t\t\"crp\",\n\t\t\"cs\",\n\t\t\"csb\",\n\t\t\"cs.cp1250\",\n\t\t\"cs-CZ\",\n\t\t\"cs_CZ\",\n\t\t\"cu\",\n\t\t\"cus\",\n\t\t\"cv\",\n\t\t\"cy\",\n\t\t\"da\",\n\t\t\"da-DK\",\n\t\t\"da_DK\",\n\t\t\"dak\",\n\t\t\"dar\",\n\t\t\"day\",\n\t\t\"de\",\n\t\t\"de-AT\",\n\t\t\"de_AT\",\n\t\t\"de-CH\",\n\t\t\"de_CH\",\n\t\t\"de-DE\",\n\t\t\"de_DE\",\n\t\t\"de@hebrew\",\n\t\t\"del\",\n\t\t\"den\",\n\t\t\"de.us-ascii\",\n\t\t\"dgr\",\n\t\t\"din\",\n\t\t\"doi\",\n\t\t\"dra\",\n\t\t\"dsb\",\n\t\t\"dua\",\n\t\t\"dum\",\n\t\t\"dv\",\n\t\t\"dyu\",\n\t\t\"dz\",\n\t\t\"ee\",\n\t\t\"efi\",\n\t\t\"egy\",\n\t\t\"eka\",\n\t\t\"el\",\n\t\t\"el-GR\",\n\t\t\"el_GR\",\n\t\t\"elx\",\n\t\t\"en\",\n\t\t\"en@arabic\",\n\t\t\"en-AU\",\n\t\t\"en_AU\",\n\t\t\"en@boldquot\",\n\t\t\"en-CA\",\n\t\t\"en_CA\",\n\t\t\"en@cyrillic\",\n\t\t\"en-CZ\",\n\t\t\"en_CZ\",\n\t\t\"en-FR\",\n\t\t\"en_FR\",\n\t\t\"en-GB\",\n\t\t\"en_GB\",\n\t\t\"en@greek\",\n\t\t\"en@hebrew\",\n\t\t\"en-HK\",\n\t\t\"en_HK\",\n\t\t\"en-IE\",\n\t\t\"en_IE\",\n\t\t\"enm\",\n\t\t\"en-NZ\",\n\t\t\"en_NZ\",\n\t\t\"en@piglatin\",\n\t\t\"en@quot\",\n\t\t\"en@shaw\",\n\t\t\"en-US\",\n\t\t\"en_US\",\n\t\t\"en-US@piglatin\",\n\t\t\"en_US@piglatin\",\n\t\t\"en-ZA\",\n\t\t\"en_ZA\",\n\t\t\"eo\",\n\t\t\"es\",\n\t\t\"es-AR\",\n\t\t\"es_AR\",\n\t\t\"es-CL\",\n\t\t\"es_CL\",\n\t\t\"es-CO\",\n\t\t\"es_CO\",\n\t\t\"es-CR\",\n\t\t\"es_CR\",\n\t\t\"es-DO\",\n\t\t\"es_DO\",\n\t\t\"es-EC\",\n\t\t\"es_EC\",\n\t\t\"es-ES\",\n\t\t\"es_ES\",\n\t\t\"es-EU\",\n\t\t\"es_EU\",\n\t\t\"es-GT\",\n\t\t\"es_GT\",\n\t\t\"es-HN\",\n\t\t\"es_HN\",\n\t\t\"es-MX\",\n\t\t\"es_MX\",\n\t\t\"es-NI\",\n\t\t\"es_NI\",\n\t\t\"es-PA\",\n\t\t\"es_PA\",\n\t\t\"es-PE\",\n\t\t\"es_PE\",\n\t\t\"es-PR\",\n\t\t\"es_PR\",\n\t\t\"es-PY\",\n\t\t\"es_PY\",\n\t\t\"es-SV\",\n\t\t\"es_SV\",\n\t\t\"es-US\",\n\t\t\"es_US\",\n\t\t\"es.us-ascii\",\n\t\t\"es-UY\",\n\t\t\"es_UY\",\n\t\t\"es-VE\",\n\t\t\"es_VE\",\n\t\t\"et\",\n\t\t\"et-EE\",\n\t\t\"et_EE\",\n\t\t\"eu\",\n\t\t\"eu-ES\",\n\t\t\"eu_ES\",\n\t\t\"ewo\",\n\t\t\"fa\",\n\t\t\"fa-AF\",\n\t\t\"fa_AF\",\n\t\t\"fa-IR\",\n\t\t\"fa_IR\",\n\t\t\"fan\",\n\t\t\"fat\",\n\t\t\"ff\",\n\t\t\"fi\",\n\t\t\"fi-FI\",\n\t\t\"fi_FI\",\n\t\t\"fil\",\n\t\t\"fiu\",\n\t\t\"fj\",\n\t\t\"fo\",\n\t\t\"fon\",\n\t\t\"fr\",\n\t\t\"fr-CA\",\n\t\t\"fr_CA\",\n\t\t\"fr-CH\",\n\t\t\"fr_CH\",\n\t\t\"fr-FR\",\n\t\t\"fr_FR\",\n\t\t\"frm\",\n\t\t\"fro\",\n\t\t\"frp\",\n\t\t\"frr\",\n\t\t\"frs\",\n\t\t\"fr.us-ascii\",\n\t\t\"fur\",\n\t\t\"fy\",\n\t\t\"ga\",\n\t\t\"gaa\",\n\t\t\"gay\",\n\t\t\"gba\",\n\t\t\"gd\",\n\t\t\"gem\",\n\t\t\"gez\",\n\t\t\"gil\",\n\t\t\"gl\",\n\t\t\"gl-ES\",\n\t\t\"gl_ES\",\n\t\t\"gmh\",\n\t\t\"gn\",\n\t\t\"goh\",\n\t\t\"gom\",\n\t\t\"gon\",\n\t\t\"gor\",\n\t\t\"gos\",\n\t\t\"got\",\n\t\t\"grb\",\n\t\t\"grc\",\n\t\t\"gsw\",\n\t\t\"gu\",\n\t\t\"guc\",\n\t\t\"gv\",\n\t\t\"gwi\",\n\t\t\"ha\",\n\t\t\"hai\",\n\t\t\"haw\",\n\t\t\"he\",\n\t\t\"he-IL\",\n\t\t\"he_IL\",\n\t\t\"hi\",\n\t\t\"hi-IN\",\n\t\t\"hi_IN\",\n\t\t\"hil\",\n\t\t\"him\",\n\t\t\"hit\",\n\t\t\"hmn\",\n\t\t\"hne\",\n\t\t\"ho\",\n\t\t\"hr\",\n\t\t\"hr-HR\",\n\t\t\"hr_HR\",\n\t\t\"hsb\",\n\t\t\"ht\",\n\t\t\"hu\",\n\t\t\"hu-HU\",\n\t\t\"hu_HU\",\n\t\t\"hup\",\n\t\t\"hus\",\n\t\t\"hy\",\n\t\t\"hy-AM\",\n\t\t\"hy_AM\",\n\t\t\"hye\",\n\t\t\"hz\",\n\t\t\"ia\",\n\t\t\"iba\",\n\t\t\"ibo\",\n\t\t\"id\",\n\t\t\"id-ID\",\n\t\t\"id_ID\",\n\t\t\"ie\",\n\t\t\"ig\",\n\t\t\"ii\",\n\t\t\"ijo\",\n\t\t\"ik\",\n\t\t\"ilo\",\n\t\t\"inc\",\n\t\t\"ine\",\n\t\t\"inh\",\n\t\t\"io\",\n\t\t\"ira\",\n\t\t\"iro\",\n\t\t\"is\",\n\t\t\"it\",\n\t\t\"it-IT\",\n\t\t\"it_IT\",\n\t\t\"iu\",\n\t\t\"ja\",\n\t\t\"ja.euc-jp\",\n\t\t\"ja-JP\",\n\t\t\"ja_JP\",\n\t\t\"jam\",\n\t\t\"jbo\",\n\t\t\"jpr\",\n\t\t\"jrb\",\n\t\t\"jv\",\n\t\t\"ka\",\n\t\t\"kaa\",\n\t\t\"kab\",\n\t\t\"kac\",\n\t\t\"ka-GE\",\n\t\t\"ka_GE\",\n\t\t\"kam\",\n\t\t\"kar\",\n\t\t\"kaw\",\n\t\t\"kbd\",\n\t\t\"kg\",\n\t\t\"kha\",\n\t\t\"khi\",\n\t\t\"kho\",\n\t\t\"ki\",\n\t\t\"kj\",\n\t\t\"kk\",\n\t\t\"kl\",\n\t\t\"km\",\n\t\t\"kmb\",\n\t\t\"km-KH\",\n\t\t\"km_KH\",\n\t\t\"kmr\",\n\t\t\"kn\",\n\t\t\"ko\",\n\t\t\"kok\",\n\t\t\"kok@latin\",\n\t\t\"ko-KR\",\n\t\t\"ko_KR\",\n\t\t\"kos\",\n\t\t\"kpe\",\n\t\t\"kr\",\n\t\t\"krc\",\n\t\t\"krl\",\n\t\t\"kro\",\n\t\t\"kru\",\n\t\t\"ks\",\n\t\t\"ks@aran\",\n\t\t\"ks@deva\",\n\t\t\"ks@devanagari\",\n\t\t\"ksw\",\n\t\t\"ku\",\n\t\t\"ku-IQ\",\n\t\t\"ku_IQ\",\n\t\t\"kum\",\n\t\t\"kut\",\n\t\t\"kv\",\n\t\t\"kw\",\n\t\t\"kw-GB\",\n\t\t\"kw_GB\",\n\t\t\"kw@kkcor\",\n\t\t\"kw@uccor\",\n\t\t\"ky\",\n\t\t\"l10n\",\n\t\t\"la\",\n\t\t\"lad\",\n\t\t\"lah\",\n\t\t\"lam\",\n\t\t\"lb\",\n\t\t\"lez\",\n\t\t\"lg\",\n\t\t\"li\",\n\t\t\"ln\",\n\t\t\"lo\",\n\t\t\"locale.alias\",\n\t\t\"lol\",\n\t\t\"lo-LA\",\n\t\t\"lo_LA\",\n\t\t\"loz\",\n\t\t\"lt\",\n\t\t\"ltg\",\n\t\t\"lt-LT\",\n\t\t\"lt_LT\",\n\t\t\"lu\",\n\t\t\"lua\",\n\t\t\"lui\",\n\t\t\"lun\",\n\t\t\"luo\",\n\t\t\"lus\",\n\t\t\"lv\",\n\t\t\"lv-LV\",\n\t\t\"lv_LV\",\n\t\t\"mad\",\n\t\t\"mag\",\n\t\t\"mai\",\n\t\t\"mak\",\n\t\t\"man\",\n\t\t\"map\",\n\t\t\"mas\",\n\t\t\"mdf\",\n\t\t\"mdr\",\n\t\t\"men\",\n\t\t\"mg\",\n\t\t\"mga\",\n\t\t\"mh\",\n\t\t\"mhr\",\n\t\t\"mi\",\n\t\t\"mic\",\n\t\t\"min\",\n\t\t\"mis\",\n\t\t\"mjw\",\n\t\t\"mk\",\n\t\t\"mkh\",\n\t\t\"mk-MK\",\n\t\t\"mk_MK\",\n\t\t\"ml\",\n\t\t\"ml-IN\",\n\t\t\"ml_IN\",\n\t\t\"mn\",\n\t\t\"mnc\",\n\t\t\"mni\",\n\t\t\"mni@beng\",\n\t\t\"mni@bengali\",\n\t\t\"mni@meiteimayek\",\n\t\t\"mnk\",\n\t\t\"mno\",\n\t\t\"mo\",\n\t\t\"moh\",\n\t\t\"mos\",\n\t\t\"mr\",\n\t\t\"mr-IN\",\n\t\t\"mr_IN\",\n\t\t\"ms\",\n\t\t\"ms-MY\",\n\t\t\"ms_MY\",\n\t\t\"mt\",\n\t\t\"mul\",\n\t\t\"mun\",\n\t\t\"mus\",\n\t\t\"mvo\",\n\t\t\"mwl\",\n\t\t\"mwr\",\n\t\t\"my\",\n\t\t\"my-MM\",\n\t\t\"my_MM\",\n\t\t\"myn\",\n\t\t\"myv\",\n\t\t\"na\",\n\t\t\"nah\",\n\t\t\"nai\",\n\t\t\"nan\",\n\t\t\"nap\",\n\t\t\"nb\",\n\t\t\"nb-NO\",\n\t\t\"nb_NO\",\n\t\t\"nd\",\n\t\t\"nds\",\n\t\t\"ne\",\n\t\t\"new\",\n\t\t\"ng\",\n\t\t\"nia\",\n\t\t\"nic\",\n\t\t\"niu\",\n\t\t\"nl\",\n\t\t\"nl-BE\",\n\t\t\"nl_BE\",\n\t\t\"nl-NL\",\n\t\t\"nl_NL\",\n\t\t\"nl.us-ascii\",\n\t\t\"nn\",\n\t\t\"nn-NO\",\n\t\t\"nn_NO\",\n\t\t\"no\",\n\t\t\"nog\",\n\t\t\"non\",\n\t\t\"no-NO\",\n\t\t\"no_NO\",\n\t\t\"no.us-ascii\",\n\t\t\"nqo\",\n\t\t\"nr\",\n\t\t\"nso\",\n\t\t\"nub\",\n\t\t\"nv\",\n\t\t\"nwc\",\n\t\t\"ny\",\n\t\t\"nym\",\n\t\t\"nyn\",\n\t\t\"nyo\",\n\t\t\"nzi\",\n\t\t\"oc\",\n\t\t\"oj\",\n\t\t\"om\",\n\t\t\"or\",\n\t\t\"or-IN\",\n\t\t\"or_IN\",\n\t\t\"os\",\n\t\t\"osa\",\n\t\t\"ota\",\n\t\t\"oto\",\n\t\t\"pa\",\n\t\t\"paa\",\n\t\t\"pag\",\n\t\t\"pal\",\n\t\t\"pam\",\n\t\t\"pap\",\n\t\t\"pa-PK\",\n\t\t\"pa_PK\",\n\t\t\"pau\",\n\t\t\"pbs\",\n\t\t\"peo\",\n\t\t\"phi\",\n\t\t\"phn\",\n\t\t\"pi\",\n\t\t\"pis\",\n\t\t\"pl\",\n\t\t\"pl-PL\",\n\t\t\"pl_PL\",\n\t\t\"pms\",\n\t\t\"pon\",\n\t\t\"pra\",\n\t\t\"pro\",\n\t\t\"ps\",\n\t\t\"pt\",\n\t\t\"pt-BR\",\n\t\t\"pt_BR\",\n\t\t\"pt-BR.us-ascii\",\n\t\t\"pt_BR.us-ascii\",\n\t\t\"pt-PT\",\n\t\t\"pt_PT\",\n\t\t\"pt.us-ascii\",\n\t\t\"qaa-qtz\",\n\t\t\"qu\",\n\t\t\"quy\",\n\t\t\"quz\",\n\t\t\"raj\",\n\t\t\"rap\",\n\t\t\"rar\",\n\t\t\"rm\",\n\t\t\"rn\",\n\t\t\"ro\",\n\t\t\"roa\",\n\t\t\"rom\",\n\t\t\"ro-MD\",\n\t\t\"ro_MD\",\n\t\t\"ro-RO\",\n\t\t\"ro_RO\",\n\t\t\"ru\",\n\t\t\"rue\",\n\t\t\"rup\",\n\t\t\"ru-RU\",\n\t\t\"ru_RU\",\n\t\t\"ru-RU.KOI8-R\",\n\t\t\"ru_RU.KOI8-R\",\n\t\t\"rw\",\n\t\t\"sa\",\n\t\t\"sad\",\n\t\t\"sah\",\n\t\t\"sai\",\n\t\t\"sal\",\n\t\t\"sam\",\n\t\t\"sas\",\n\t\t\"sat\",\n\t\t\"sat@deva\",\n\t\t\"sat@olchiki\",\n\t\t\"sc\",\n\t\t\"scn\",\n\t\t\"sco\",\n\t\t\"sd\",\n\t\t\"sd@deva\",\n\t\t\"se\",\n\t\t\"sel\",\n\t\t\"sem\",\n\t\t\"sg\",\n\t\t\"sga\",\n\t\t\"sgn\",\n\t\t\"shn\",\n\t\t\"shs\",\n\t\t\"si\",\n\t\t\"sid\",\n\t\t\"si-LK\",\n\t\t\"si_LK\",\n\t\t\"sio\",\n\t\t\"sit\",\n\t\t\"sk\",\n\t\t\"sk.cp1250\",\n\t\t\"sk-SK\",\n\t\t\"sk_SK\",\n\t\t\"sl\",\n\t\t\"sla\",\n\t\t\"sl-SI\",\n\t\t\"sl_SI\",\n\t\t\"sm\",\n\t\t\"sma\",\n\t\t\"smi\",\n\t\t\"smj\",\n\t\t\"smn\",\n\t\t\"sms\",\n\t\t\"sn\",\n\t\t\"snk\",\n\t\t\"so\",\n\t\t\"sog\",\n\t\t\"son\",\n\t\t\"sp\",\n\t\t\"sq\",\n\t\t\"sq-AL\",\n\t\t\"sq_AL\",\n\t\t\"sr\",\n\t\t\"sr-Cyrl\",\n\t\t\"sr_Cyrl\",\n\t\t\"srd\",\n\t\t\"sr@ije\",\n\t\t\"sr@ijekavian\",\n\t\t\"sr@ijekavianlatin\",\n\t\t\"sr@latin\",\n\t\t\"sr-Latn\",\n\t\t\"sr@Latn\",\n\t\t\"sr_Latn\",\n\t\t\"sr-ME\",\n\t\t\"sr_ME\",\n\t\t\"srn\",\n\t\t\"srr\",\n\t\t\"sr-RS\",\n\t\t\"sr_RS\",\n\t\t\"sr-RS@latin\",\n\t\t\"sr_RS@latin\",\n\t\t\"ss\",\n\t\t\"ssa\",\n\t\t\"st\",\n\t\t\"su\",\n\t\t\"suk\",\n\t\t\"sus\",\n\t\t\"sux\",\n\t\t\"sv\",\n\t\t\"sv-SE\",\n\t\t\"sv_SE\",\n\t\t\"sw\",\n\t\t\"syc\",\n\t\t\"syr\",\n\t\t\"szl\",\n\t\t\"ta\",\n\t\t\"tai\",\n\t\t\"ta-IN\",\n\t\t\"ta_IN\",\n\t\t\"ta-LK\",\n\t\t\"ta_LK\",\n\t\t\"te\",\n\t\t\"tem\",\n\t\t\"ter\",\n\t\t\"tet\",\n\t\t\"tg\",\n\t\t\"th\",\n\t\t\"th-TH\",\n\t\t\"th_TH\",\n\t\t\"ti\",\n\t\t\"tig\",\n\t\t\"tiv\",\n\t\t\"tk\",\n\t\t\"tkl\",\n\t\t\"tl\",\n\t\t\"tlh\",\n\t\t\"tli\",\n\t\t\"tl-PH\",\n\t\t\"tl_PH\",\n\t\t\"tmh\",\n\t\t\"tn\",\n\t\t\"to\",\n\t\t\"tog\",\n\t\t\"tok\",\n\t\t\"ton\",\n\t\t\"tpi\",\n\t\t\"tr\",\n\t\t\"tr-TR\",\n\t\t\"tr_TR\",\n\t\t\"ts\",\n\t\t\"tsi\",\n\t\t\"tt\",\n\t\t\"tt@iqtelif\",\n\t\t\"tt-RU\",\n\t\t\"tt_RU\",\n\t\t\"tum\",\n\t\t\"tup\",\n\t\t\"tut\",\n\t\t\"tvl\",\n\t\t\"tw\",\n\t\t\"ty\",\n\t\t\"tyv\",\n\t\t\"tzm\",\n\t\t\"tzo\",\n\t\t\"ua\",\n\t\t\"udm\",\n\t\t\"ug\",\n\t\t\"uga\",\n\t\t\"uk\",\n\t\t\"uk-UA\",\n\t\t\"uk_UA\",\n\t\t\"umb\",\n\t\t\"und\",\n\t\t\"ur\",\n\t\t\"ur-PK\",\n\t\t\"ur_PK\",\n\t\t\"uz\",\n\t\t\"uz@cyrillic\",\n\t\t\"uz@Cyrl\",\n\t\t\"uz@Latn\",\n\t\t\"vai\",\n\t\t\"ve\",\n\t\t\"vec\",\n\t\t\"ven\",\n\t\t\"vi\",\n\t\t\"vi-VN\",\n\t\t\"vi_VN\",\n\t\t\"vo\",\n\t\t\"vot\",\n\t\t\"wa\",\n\t\t\"wae\",\n\t\t\"wak\",\n\t\t\"wal\",\n\t\t\"war\",\n\t\t\"was\",\n\t\t\"wba\",\n\t\t\"wen\",\n\t\t\"wo\",\n\t\t\"xal\",\n\t\t\"xh\",\n\t\t\"yao\",\n\t\t\"yap\",\n\t\t\"yi\",\n\t\t\"yo\",\n\t\t\"ypk\",\n\t\t\"yue\",\n\t\t\"za\",\n\t\t\"zam\",\n\t\t\"zap\",\n\t\t\"zbl\",\n\t\t\"zen\",\n\t\t\"zgh\",\n\t\t\"zh\",\n\t\t\"zh-CN\",\n\t\t\"zh_CN\",\n\t\t\"zh-CN.GB2312\",\n\t\t\"zh_CN.GB2312\",\n\t\t\"zh-Hans\",\n\t\t\"zh_Hans\",\n\t\t\"zh-Hans-CN\",\n\t\t\"zh_Hans_CN\",\n\t\t\"zh-Hant\",\n\t\t\"zh_Hant\",\n\t\t\"zh-Hant-TW\",\n\t\t\"zh_Hant_TW\",\n\t\t\"zh-HK\",\n\t\t\"zh_HK\",\n\t\t\"zh-TW\",\n\t\t\"zh_TW\",\n\t\t\"zh-TW.Big5\",\n\t\t\"zh_TW.Big5\",\n\t\t\"znd\",\n\t\t\"zu\",\n\t\t\"zun\",\n\t\t\"zxx\",\n\t\t\"zza\",\n\t\tNULL\n\t},\n};\n"
  },
  {
    "path": "parsers/iniconf.c",
    "content": "/*\n*\n*   Copyright (c) 2000-2001, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for ini/config files.\n*/\n\n/*\n *  This is based on geany's conf.c:\n * --------------------------------\n * commit 3af538fa65f8b17897259080db8144b1edc43470\n * Author: Enrico Tröger <enrico.troeger@uvena.de>\n * Date:   Sun Nov 27 20:39:57 2005 +0000\n *\n * added tag support for filetype Conf\n *\n *\n * git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@15 ea778897-0a13-0410-b9d1-a72fbfd435f5\n *\n */\n\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"htable.h\"\n#include \"x-iniconf.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"subparser.h\"\n#include \"vstring.h\"\n\n#define TOML_QUOTED_KEY_CHAR(c) ( (c) == '\"' || (c) == '\\'' )\n\nstatic bool isIdentifier (int c)\n{\n\t/* allow whitespace within keys and sections */\n\treturn (bool)(isalnum (c) || isspace (c) || c == '_' || c == '-' || c == '.'\n\t\t|| TOML_QUOTED_KEY_CHAR(c));\n}\n\nstatic bool isValue (int c)\n{\n\treturn (c != '\\0');\n}\n\nstatic iniconfSubparser *maySwitchLanguage (const char *section, const char *key, const char *value)\n{\n\tiniconfSubparser *iniconf_subparser = NULL;\n\tsubparser *sub;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\tiniconfSubparser *s = (iniconfSubparser *)sub;\n\t\tif ((sub->direction & SUBPARSER_BASE_RUNS_SUB)\n\t\t\t&& s->probeLanguage)\n\t\t{\n\t\t\tbool r;\n\n\t\t\tenterSubparser ((subparser *)s);\n\t\t\tr = s->probeLanguage(section, key, value);\n\t\t\tleaveSubparser ();\n\t\t\tif (r)\n\t\t\t{\n\t\t\t\tiniconf_subparser = s;\n\t\t\t\tchooseExclusiveSubparser (sub, NULL);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn iniconf_subparser;\n}\n\ntypedef enum {\n\tK_SECTION,\n\tK_KEY,\n} makeKind;\n\nstatic kindDefinition IniconfKinds [] = {\n\t{ true, 's', \"section\",  \"sections\"},\n\t{ true, 'k', \"key\",      \"keys\"},\n};\n\nstatic void updateEndLineMaybe (int index, bool atEOF)\n{\n\tif (index != CORK_NIL)\n\t{\n\t\tunsigned long el = getInputLineNumber ();\n\t\tif (atEOF)\n\t\t\tsetTagEndLineToCorkEntry (index, el);\n\t\telse\n\t\t\tsetTagEndLineToCorkEntry (index, el > 1? el - 1: 1);\n\t}\n}\n\nstatic void makeIniconfTagMaybe (const char *section, const char *key, const char *value CTAGS_ATTR_UNUSED, int *index)\n{\n\ttagEntryInfo e;\n\n\tif (!isLanguageEnabled (getInputLanguage ()))\n\t\treturn;\n\n\tif (key)\n\t{\n\t\tinitTagEntry (&e, key, K_KEY);\n\t\te.extensionFields.scopeIndex = *index;\n\t\tmakeTagEntry (&e);\n\t}\n\telse\n\t{\n\t\tupdateEndLineMaybe (*index, false);\n\n\t\tinitTagEntry (&e, section, K_SECTION);\n\t\t*index = makeTagEntry (&e);\n\t}\n}\n\nstatic void findIniconfTags (void)\n{\n\tconst unsigned char *line;\n\tvString *val   = vStringNew ();\n\tvString *name  = vStringNew ();\n\tvString *scope = vStringNew ();\n\tiniconfSubparser *sub;\n\tint sectionCorkIndex = CORK_NIL;\n\n\n\tsub = (iniconfSubparser *)getSubparserRunningBaseparser();\n\tif (sub)\n\t\tchooseExclusiveSubparser ((subparser *)sub, NULL);\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char* cp = line;\n\t\tbool possible = true;\n\n\t\tif (isspace (*cp) || *cp == '#' || *cp == ';' || *cp == '\\0'\n\t\t    || (*cp == '/' && *(cp+1) == '/'))\n\t\t\tcontinue;\n\n\t\t/* look for a section */\n\t\tif (*cp == '[')\n\t\t{\n\t\t\t++cp;\n\t\t\t/* look for the final ] to support TOML [[arrays.of.tables]] */\n\t\t\twhile (*cp != '\\0' && (*cp != ']' || *(cp+1) == ']'))\n\t\t\t{\n\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t++cp;\n\t\t\t}\n\n\t\t\tmakeIniconfTagMaybe (vStringValue (name), NULL, NULL,\n\t\t\t\t\t\t\t\t &sectionCorkIndex);\n\n\n\t\t\tif (!sub)\n\t\t\t\tsub = maySwitchLanguage (vStringValue (name), NULL, NULL);\n\n\t\t\tif (sub)\n\t\t\t{\n\t\t\t\tenterSubparser((subparser *)sub);\n\t\t\t\tsub->newDataNotify (sub, vStringValue (name), NULL, NULL);\n\t\t\t\tleaveSubparser ();\n\t\t\t}\n\n\t\t\tvStringCopy (scope, name);\n\t\t\tvStringClear (name);\n\t\t\tcontinue;\n\t\t}\n\n\t\twhile (*cp != '\\0')\n\t\t{\n\t\t\t/*  We look for any sequence of identifier characters following a white space */\n\t\t\tif (possible && isIdentifier (*cp))\n\t\t\t{\n\t\t\t\twhile (isIdentifier (*cp))\n\t\t\t\t{\n\t\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t\t++cp;\n\t\t\t\t}\n\t\t\t\tvStringStripTrailing (name);\n\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t++cp;\n\t\t\t\tif (*cp == '=' || *cp == ':')\n\t\t\t\t{\n\n\t\t\t\t\tcp++;\n\t\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t\t++cp;\n\t\t\t\t\twhile (isValue (*cp))\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (val, *cp);\n\t\t\t\t\t\t++cp;\n\t\t\t\t\t}\n\t\t\t\t\tvStringStripTrailing (val);\n\n\t\t\t\t\tmakeIniconfTagMaybe ((vStringLength (scope) > 0)\n\t\t\t\t\t\t\t\t\t\t ? vStringValue (scope)\n\t\t\t\t\t\t\t\t\t\t : NULL,\n\t\t\t\t\t\t\t\t\t\t vStringValue (name),\n\t\t\t\t\t\t\t\t\t\t vStringValue (val),\n\t\t\t\t\t\t\t\t\t\t &sectionCorkIndex);\n\t\t\t\t\tif (!sub)\n\t\t\t\t\t\tsub = maySwitchLanguage ((vStringLength (scope) > 0)\n\t\t\t\t\t\t\t\t\t\t\t\t ? vStringValue (scope)\n\t\t\t\t\t\t\t\t\t\t\t\t : NULL,\n\t\t\t\t\t\t\t\t\t\t\t\t vStringValue (name),\n\t\t\t\t\t\t\t\t\t\t\t\t vStringValue (val));\n\t\t\t\t\tif (sub)\n\t\t\t\t\t{\n\t\t\t\t\t\tenterSubparser ((subparser *)sub);\n\t\t\t\t\t\tsub->newDataNotify (sub,\n\t\t\t\t\t\t\t\t\t\t\t(vStringLength (scope) > 0)\n\t\t\t\t\t\t\t\t\t\t\t? vStringValue (scope)\n\t\t\t\t\t\t\t\t\t\t\t: NULL,\n\t\t\t\t\t\t\t\t\t\t\tvStringValue (name),\n\t\t\t\t\t\t\t\t\t\t\tvStringValue (val));\n\t\t\t\t\t\tleaveSubparser ();\n\t\t\t\t\t}\n\t\t\t\t\tvStringClear (val);\n\t\t\t\t}\n\t\t\t\tvStringClear (name);\n\t\t\t}\n\t\t\telse\n\t\t\t\tpossible = !!(isspace (*cp));\n\n\t\t\tif (*cp != '\\0')\n\t\t\t\t++cp;\n\t\t}\n\t}\n\n\tupdateEndLineMaybe(sectionCorkIndex, true);\n\tsectionCorkIndex = CORK_NIL;\n\n\tvStringDelete (name);\n\tvStringDelete (scope);\n\tvStringDelete (val);\n}\n\nextern parserDefinition* IniconfParser (void)\n{\n\tstatic const char *const extensions [] = { \"ini\", \"conf\", NULL };\n\tparserDefinition* const def = parserNew (\"Iniconf\");\n\n\tdef->kindTable      = IniconfKinds;\n\tdef->kindCount  = ARRAY_SIZE (IniconfKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findIniconfTags;\n\tdef->useCork   = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/itcl.c",
    "content": "/*\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n\n#include \"general.h\"  /* must always come first */\n#include \"x-tcl.h\"\n#include \"entry.h\"\n#include \"param.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"keyword.h\"\n\n#include <string.h>\n\n\nstruct itclSubparser {\n\ttclSubparser tcl;\n\tbool foundITclNamespaceImported;\n};\n\nstatic scopeSeparator ITclGenericSeparators [] = {\n\t{ KIND_WILDCARD_INDEX, \"::\" },\n};\n\nenum ITclKind {\n\tK_CLASS,\n\tK_METHOD,\n\tK_VARIABLE,\n\tK_COMMON,\n\tK_PROC,\n};\n\nstatic kindDefinition ITclKinds[] = {\n\t{ true, 'c', \"class\", \"classes\" },\n\t{ true, 'm', \"method\", \"methods\",\n\t  ATTACH_SEPARATORS(ITclGenericSeparators)},\n\t{ true, 'v', \"variable\", \"object-specific variables\",\n\t  ATTACH_SEPARATORS(ITclGenericSeparators)},\n\t{ true, 'C', \"common\", \"common variables\",\n\t  ATTACH_SEPARATORS(ITclGenericSeparators)},\n\t{ true, 'p', \"procedure\", \"procedures within the class namespace\",\n\t  ATTACH_SEPARATORS(ITclGenericSeparators)},\n};\n\nenum {\n\tKEYWORD_INHERIT,\n\tKEYWORD_METHOD,\n\tKEYWORD_PRIVATE,\n\tKEYWORD_PROTECTED,\n\tKEYWORD_PUBLIC,\n\tKEYWORD_VARIABLE,\n\tKEYWORD_COMMON,\n\tKEYWORD_PROC,\n};\n\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\nstatic const keywordTable ITclKeywordTable[] = {\n\t/* keyword\t\t\tkeyword ID */\n\t{ \"inherit\",\t\tKEYWORD_INHERIT\t\t},\n\t{ \"method\",\t\t\tKEYWORD_METHOD\t\t},\n\t{ \"private\",\t\tKEYWORD_PRIVATE\t\t},\n\t{ \"protected\",\t\tKEYWORD_PROTECTED\t},\n\t{ \"public\",\t\t\tKEYWORD_PUBLIC\t\t},\n\t{ \"variable\",\t\tKEYWORD_VARIABLE\t},\n\t{ \"common\",\t\t\tKEYWORD_COMMON\t\t},\n\t{ \"proc\",\t\t\tKEYWORD_PROC\t\t},\n};\n\nstatic bool itclForceUse;\n\nstatic keywordId resolveKeyword (vString *string)\n{\n\tchar *s = vStringValue (string);\n\tstatic langType lang = LANG_AUTO;\n\n\tif (lang == LANG_AUTO)\n\t\tlang = getInputLanguage ();\n\n\treturn lookupKeyword (s, lang);\n}\n\nstatic void parseInherit (tokenInfo *token, int r)\n{\n\tvString *inherits = vStringNew ();\n\n\tdo {\n\t\ttokenRead (token);\n\t\tif (tokenIsType (token, TCL_IDENTIFIER))\n\t\t\tvStringJoin(inherits, ',', token->string);\n\t\telse if (tokenIsType(token, TCL_EOL))\n\t\t\tbreak;\n\t\telse\n\t\t{\n\t\t\tskipToEndOfTclCmdline (token);\n\t\t\tbreak;\n\t\t}\n\t} while (1);\n\n\tif (vStringLength(inherits) > 0)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\t\tif (e)\n\t\t{\n\t\t\te->extensionFields.inheritance = vStringDeleteUnwrap (inherits);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tvStringDelete (inherits);\n}\n\nstatic void attachProtectionMaybe(tagEntryInfo *e, keywordId protection)\n{\n\t\tswitch (protection)\n\t\t{\n\t\tcase KEYWORD_PROTECTED:\n\t\t\te->extensionFields.access = \"protected\";\n\t\t\tbreak;\n\t\tcase KEYWORD_PRIVATE:\n\t\t\te->extensionFields.access = \"private\";\n\t\t\tbreak;\n\t\tcase KEYWORD_PUBLIC:\n\t\t\te->extensionFields.access = \"public\";\n\t\t\tbreak;\n\t\t}\n}\n\nstatic void parseSubobject (tokenInfo *token, int parent, enum ITclKind kind, keywordId protection)\n{\n\tint r = CORK_NIL;\n\n\ttokenRead (token);\n\tif (tokenIsType (token, TCL_IDENTIFIER))\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry(&e, vStringValue (token->string), kind);\n\t\te.extensionFields.scopeIndex = parent;\n\t\tattachProtectionMaybe (&e, protection);\n\t\tr = makeTagEntry (&e);\n\t}\n\n\tskipToEndOfTclCmdline (token);\n\tsetTagEndLineToCorkEntry (r, token->lineNumber);\n}\n\n\nstatic void parseVariable (tokenInfo *token, int r, keywordId protection)\n{\n\tparseSubobject(token, r, K_VARIABLE, protection);\n}\n\nstatic void parseMethod (tokenInfo *token, int r, keywordId protection)\n{\n\tparseSubobject(token, r, K_METHOD, protection);\n}\n\nstatic void parseProc (tokenInfo *token, int r, keywordId protection)\n{\n\tparseSubobject(token, r, K_PROC, protection);\n}\n\nstatic void parseCommon (tokenInfo *token, int r, keywordId protection)\n{\n\tparseSubobject(token, r, K_COMMON, protection);\n}\n\nstatic int parseClass (tclSubparser *s CTAGS_ATTR_UNUSED, int parentIndex,\n\t\t\t\t\t   void *pstate)\n{\n\ttokenInfo *token = newTclToken (pstate);\n\tint r = CORK_NIL;\n\n\ttokenRead (token);\n\tif (tokenIsType (token, TCL_IDENTIFIER))\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry(&e, vStringValue (token->string), K_CLASS);\n\t\te.extensionFields.scopeIndex = parentIndex;\n\t\tr = makeTagEntry (&e);\n\t}\n\n\tif (tokenSkipToType (token, '{'))\n\t{\n\t\tkeywordId protection = KEYWORD_NONE;\n\n\t\tdo {\n\t\t\ttokenRead (token);\n\t\t\tif (tokenIsType (token, TCL_IDENTIFIER)\n\t\t\t\t|| tokenIsType (token, TCL_KEYWORD))\n\t\t\t{\n\t\t\t\tkeywordId k = resolveKeyword (token->string);\n\t\t\t\tswitch (k)\n\t\t\t\t{\n\t\t\t\tcase KEYWORD_INHERIT:\n\t\t\t\t\tparseInherit(token, r);\n\t\t\t\t\tprotection = KEYWORD_NONE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_VARIABLE:\n\t\t\t\t\tparseVariable(token, r, protection);\n\t\t\t\t\tprotection = KEYWORD_NONE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_METHOD:\n\t\t\t\t\tparseMethod(token, r, protection);\n\t\t\t\t\tprotection = KEYWORD_NONE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_COMMON:\n\t\t\t\t\tparseCommon(token, r, protection);\n\t\t\t\t\tprotection = KEYWORD_NONE;\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_PUBLIC:\n\t\t\t\tcase KEYWORD_PROTECTED:\n\t\t\t\tcase KEYWORD_PRIVATE:\n\t\t\t\t\tprotection = k;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase KEYWORD_PROC:\n\t\t\t\t\tparseProc(token, r, protection);\n\t\t\t\t\tprotection = KEYWORD_NONE;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tprotection = KEYWORD_NONE;\n\t\t\t\t\tskipToEndOfTclCmdline (token);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (token->type == '}')\n\t\t\t{\n\t\t\t\tprotection = KEYWORD_NONE;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tprotection = KEYWORD_NONE;\n\t\t\t\tskipToEndOfTclCmdline (token);\n\t\t\t}\n\t\t} while (!tokenIsEOF(token));\n\t}\n\n\ttokenDelete(token);\n\treturn r;\n}\n\nstatic int commandNotify (tclSubparser *s, char *command,\n\t\t\t\t\t\t  int parentIndex, void *pstate)\n{\n\tstruct itclSubparser *itcl = (struct itclSubparser *)s;\n\tint r = CORK_NIL;\n\n\tif ((itcl->foundITclNamespaceImported\n\t\t && (strcmp (command, \"class\") == 0))\n\t\t|| (strcmp (command, \"itcl::class\") == 0))\n\t\tr = parseClass (s, parentIndex, pstate);\n\n\treturn r;\n}\n\nstatic void namespaceImportNotify (tclSubparser *s, char *namespace,\n\t\t\t\t\t\t\t\t   void *pstate CTAGS_ATTR_UNUSED)\n{\n\tstruct itclSubparser *itcl = (struct itclSubparser *)s;\n\n\tif (strcmp(namespace, \"itcl::*\") == 0\n\t\t|| strcmp(namespace, \"itcl::class\") == 0)\n\t\titcl->foundITclNamespaceImported = true;\n}\n\nstatic void inputStart (subparser *s)\n{\n\tstruct itclSubparser *itcl = (struct itclSubparser *)s;\n\n\titcl->foundITclNamespaceImported = itclForceUse;\n}\n\nstatic struct itclSubparser itclSubparser = {\n\t.tcl = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t\t.inputStart = inputStart,\n\t\t},\n\t\t.commandNotify = commandNotify,\n\t\t.namespaceImportNotify = namespaceImportNotify,\n\t},\n};\n\nstatic void findITclTags(void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic bool itclForceUseParamHandler (const langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t  const char *name, const char *arg)\n{\n\titclForceUse = paramParserBool (arg, itclForceUse, name, \"parameter\");\n\treturn true;\n}\n\nstatic paramDefinition ItclParams [] = {\n\t{ .name = \"forceUse\",\n\t  .desc = \"enable the parser even when `itcl' namespace is not specified in the input (true or [false])\" ,\n\t  .handleParam = itclForceUseParamHandler,\n\t},\n};\n\nextern parserDefinition* ITclParser (void)\n{\n\tstatic const char *const extensions [] = { \"itcl\", NULL };\n\tparserDefinition* const def = parserNew(\"ITcl\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Tcl\", &itclSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = ITclKinds;\n\tdef->kindCount = ARRAY_SIZE(ITclKinds);\n\n\tdef->extensions = extensions;\n\tdef->parser = findITclTags;\n\tdef->useCork = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\n\tdef->keywordTable = ITclKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (ITclKeywordTable);\n\n\tdef->paramTable = ItclParams;\n\tdef->paramCount = ARRAY_SIZE(ItclParams);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/jprop.c",
    "content": "/*\n*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for java properties\n*   https://docs.oracle.com/javase/7/docs/api/java/util/Properties.html\n*/\n\n#include \"general.h\"\t/* must always come first */\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n\ntypedef enum {\n\tK_KEY\n} javaPropertiesKind;\n\nstatic kindDefinition JavaPropertiesKinds [] = {\n\t{ true, 'k', \"key\", \"keys\" },\n};\n\nstatic const unsigned char *skipWhiteSpace (const unsigned char *line)\n{\n\twhile (*line == ' '\n\t       || *line == '\\t'\n\t       || *line == '\\f')\n\t\tline++;\n\treturn line;\n}\n\nstatic bool doesValueContinue (const unsigned char *line)\n{\n\tbool in_escaping = false;\n\twhile (*line != '\\0')\n\t{\n\t\tif (in_escaping)\n\t\t\tin_escaping = false;\n\t\telse if (*line == '\\\\')\n\t\t\tin_escaping = true;\n\t\tline++;\n\t}\n\treturn in_escaping;\n}\n\nstatic const unsigned char * extractKey (const unsigned char *line, vString *key)\n{\n\tbool in_escaping = false;\n\n\twhile (*line != '\\0')\n\t{\n\t\tif (in_escaping)\n\t\t{\n\t\t\tvStringPut (key, *line);\n\t\t\tin_escaping = false;\n\t\t}\n\t\telse if (*line == ':' || *line == '='\n\t\t\t || *line == ' ' || *line == '\\t' || *line == '\\f')\n\t\t{\n\t\t\tline++;\n\t\t\tbreak;\n\t\t}\n\t\telse if (*line == '\\\\')\n\t\t{\n\t\t\tvStringPut (key, *line);\n\t\t\tin_escaping = true;\n\t\t}\n\t\telse\n\t\t\tvStringPut (key, *line);\n\t\tline++;\n\t}\n\treturn line;\n}\n\nstatic void findJavaPropertiesTags (void)\n{\n\tconst unsigned char *line;\n\tbool in_value = false;\n\tbool value_continues;\n\tstatic vString *key;\n\n\tif (key == NULL)\n\t\tkey = vStringNew ();\n\telse\n\t\tvStringClear (key);\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tif (in_value)\n\t\t{\n\t\t\tvalue_continues = doesValueContinue (line);\n\t\t\tif (!value_continues)\n\t\t\t\tin_value = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tline = skipWhiteSpace (line);\n\t\tif (*line == '\\0'\n\t\t    || *line == '!' || *line == '#')\n\t\t\tcontinue;\n\n\t\tline = extractKey (line, key);\n\t\tmakeSimpleTag (key, K_KEY);\n\t\tvStringClear (key);\n\n\t\tvalue_continues = doesValueContinue (line);\n\t\tif (value_continues)\n\t\t\tin_value = true;\n\t}\n}\n\nextern parserDefinition*\nJavaPropertiesParser (void)\n{\n\tstatic const char *const extensions [] = { \"properties\", NULL };\n\tparserDefinition* const def = parserNew (\"JavaProperties\");\n\n\tdef->kindTable = JavaPropertiesKinds;\n\tdef->kindCount = ARRAY_SIZE (JavaPropertiesKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findJavaPropertiesTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/jscript.c",
    "content": "/*\n * Copyright (c) 2003, Darren Hiebert\n *\n * This source code is released for free distribution under the terms of the\n * GNU General Public License version 2 or (at your option) any later version.\n *\n * This module contains functions for generating tags for JavaScript language\n * files.\n *\n * Reference: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf\n *            https://tc39.es/ecma262/\n *\n * This is a good reference for different forms of the function statement:\n *     http://www.permadi.com/tutorial/jsFunc/\n * Another good reference:\n *     http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide\n * About JSX:\n *     https://facebook.github.io/jsx/\n *\n */\n\n/*\n * INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n#include <ctype.h>\t/* to define isalpha () */\n#ifdef DEBUG\n#include <stdio.h>\n#endif\n\n#ifdef HAVE_ICONV\n#include <iconv.h>\n#include <errno.h>\n#\tifdef WORDS_BIGENDIAN\n#\t\tdefine INTERNAL_ENCODING \"UTF-32BE\"\n#\telse\n#\t\tdefine INTERNAL_ENCODING \"UTF-32LE\"\n#\tendif /* WORDS_BIGENDIAN */\n#endif\n\n#include <string.h>\n#include \"debug.h\"\n#include \"dependency.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"numarray.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"objpool.h\"\n#include \"options.h\"\n#include \"mbcs.h\"\n#include \"trace.h\"\n\n#include \"x-html.h\"\n#include \"x-jscript.h\"\n\n/*\n * MACROS\n */\n#define isType(token,t)\t\t(bool) ((token)->type == (t))\n#define isKeyword(token,k)\t(bool) ((token)->keyword == (k))\n#define newToken() (objPoolGet (TokenPool))\n#define deleteToken(t) (objPoolPut (TokenPool, (t)))\n\n/*\n * DATA DECLARATIONS\n */\n\n/* Used to specify type of keyword.\n*/\nenum eKeywordId {\n\tKEYWORD_function,\n\tKEYWORD_capital_function,\n\tKEYWORD_capital_object,\n\tKEYWORD_prototype,\n\tKEYWORD_var,\n\tKEYWORD_let,\n\tKEYWORD_const,\n\tKEYWORD_new,\n\tKEYWORD_this,\n\tKEYWORD_for,\n\tKEYWORD_while,\n\tKEYWORD_do,\n\tKEYWORD_if,\n\tKEYWORD_else,\n\tKEYWORD_switch,\n\tKEYWORD_try,\n\tKEYWORD_catch,\n\tKEYWORD_finally,\n\tKEYWORD_sap,\n\tKEYWORD_return,\n\tKEYWORD_class,\n\tKEYWORD_extends,\n\tKEYWORD_static,\n\tKEYWORD_default,\n\tKEYWORD_export,\n\tKEYWORD_async,\n\tKEYWORD_get,\n\tKEYWORD_set,\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum eTokenType {\n\tTOKEN_UNDEFINED,\n\tTOKEN_EOF,\n\tTOKEN_CHARACTER,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_SEMICOLON,\n\tTOKEN_COLON,\n\tTOKEN_COMMA,\n\tTOKEN_KEYWORD,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n\tTOKEN_TEMPLATE_STRING,\n\tTOKEN_PERIOD,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_EQUAL_SIGN,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_REGEXP,\n\tTOKEN_POSTFIX_OPERATOR,\n\tTOKEN_STAR,\n\tTOKEN_HASH,\n\t/* To handle Babel's decorators.\n\t * Used only in readTokenFull or lower functions. */\n\tTOKEN_ATMARK,\n\tTOKEN_BINARY_OPERATOR,\n\tTOKEN_ARROW,\n\tTOKEN_JSX,\t\t\t\t\t/* <TAG> ... </TAG> or <TAG/> */\n\tTOKEN_DOTS,\t\t\t\t\t/* ... */\n} tokenType;\n\ntypedef struct sTokenInfo {\n\ttokenType\t\ttype;\n\tkeywordId\t\tkeyword;\n\tvString *\t\tstring;\n\tint\t\t\t\tscope;\n\tunsigned long\tlineNumber;\n\tMIOPos\t\t\tfilePosition;\n\tint\t\t\t\tnestLevel;\n\tbool\t\t\tdynamicProp;\n\tint\t\t\t\tc;\n} tokenInfo;\n\ntypedef enum {\n\tF_PROPERTIES,\n} jsField;\n\n/*\n * DATA DEFINITIONS\n */\n\nstatic tokenType LastTokenType;\nstatic tokenInfo *NextToken;\n\nstatic langType Lang_js;\n\nstatic objPool *TokenPool = NULL;\n\n#ifdef HAVE_ICONV\nstatic iconv_t JSUnicodeConverter = (iconv_t) -2;\n#endif\n\n/*\n * \"chain element\" role is introduced when adapting the JavaScript parser\n * to corkAPI.\n *\n * In the corkAPI, a cork index returned from makeTagEntry() can\n * represent a scope of another tag. Let's think about `input-0.js' that\n * the node command accepts as an input for ctags.\n *\n +---+ input-0.js ------------------------------------------------------\n | 1 | class A {\n | 2 |    f = function(x) {\n | 3 |       return x\n | 4 |    }\n | 5 | }\n +---+------------------------------------------------------------------\n *\n * The following pseudo C code illustrate the code for\n * tagging `A' and `f' in input-0.js:\n +---+------------------------------------------------------------------\n |   |...\n |   | tagEntryFor e_for_A, e_for_f;\n |   | ...\n |   | int index_for_A = makeTagEntry (&e_for_A);\n |   | ...\n |>>>| e_for_f.extensionFields.scopeIndex = index_for_A;\n |   | ...\n |   | makeTagEntry (&e_for_f);\n |   | ...\n +---+------------------------------------------------------------------\n *\n * `index_for_A' represents \"A\" in \"class A\".\n * `f' is defined in `A'. To fill the scope field of the tag for `f',\n * `scopeIndex' member of the tag is filled with `index_for_A' at line |>>>|.\n *\n * If `A' is defined in the input source file, this technique based on\n * the cork API works fine. However, if `A' is not defined in the input\n * source file, the technique doesn't work well.\n +---+ input-1.js -------------------------------------------------------\n | 1 | import {A} from 'input-0.js';\n | 2 | A.g = function(x) {\n | 3 |    return x\n | 4 | }\n +---+------------------------------------------------------------------\n *\n * In this case, `A' may be defined in input-0.js.\n * The current implementation of ctags processes file by file; it doesn't\n * use the knowledge in other input source files than current input source\n * file. ctags processing input-1.js doesn't know the cork index for `A'.\n *\n * When tagging `g' with \"function\" kind, how can we fill the scope field\n * of the tag for `g'?\n *\n * Here the \"chain element\" role comes.\n * This role is used for tagging `z' in \"x.y.z\" in the case when ctags\n * doesn't see the definitions for `x' and `y'.\n * The JavaScript parser makes reference tags for `x' and `'y' with\n * \"chain element\" role. makeTagEntry() returns a cork index regardless the\n * type of tags (definition or reference).\n * The index for the reference tag for `y' can be used to fill the scope\n * field of the tag for `z'. The index for `x' can be used to fill the\n * field for `y'.\n *\n * With these trick and technique, the scope field for `g' is filled:\n +---+ tags for input-1.js ---------------------------------------------\n | 1 | A  input-1.js  /^A.g = function(x) {$/;\"  f  roles:chainElt  extras:reference\n | 2 | g  input-1.js  /^A.g = function(x) {$/;\"  f  scope:function:A  signature:(x)  roles:def\n +---+------------------------------------------------------------------\n *\n * By default, reference tags are not emitted. So non-ctags-expert users may\n * not see the tag entry for `A'.\n *\n * makeJsRefTagsForNameChain() and makeJsTagCommon() implement the trick\n * and technique.\n *\n * Arguable points:\n *\n * Is \"chain element(chainElt)\" suitable name for people familier with JavaScript?\n *\n * Kinds assigned to the tag having chainElt role must revised. Eventually\n * we may need to introduce \"unknown\" kind like the Python parser. Assigning\n * \"function\" kind to `A' in input-1.js is obviously wrong.\n */\n\ntypedef enum {\n\tJS_VARIABLE_CHAINELT,\n} jsVariableRole;\n\ntypedef enum {\n\tJS_CLASS_CHAINELT,\n} jsClassRole;\n\nstatic roleDefinition JsFunctionRoles [] = {\n\t/* Currently V parser wants this items. */\n\t{ true, \"foreigndecl\", \"declared in foreign languages\",\n\t  .version = 1 },\n};\n\nstatic roleDefinition JsVariableRoles [] = {\n\t{ false, \"chainElt\", \"(EXPERIMENTAL)used as an element in a name chain like a.b.c\" },\n};\n\nstatic roleDefinition JsClassRoles [] = {\n\t{ false, \"chainElt\", \"(EXPERIMENTAL)used as an element in a name chain like a.b.c\" },\n};\n\nstatic kindDefinition JsKinds [] = {\n\t{ true,  'f', \"function\",\t  \"functions\",\n\t  .referenceOnly = false, ATTACH_ROLES(JsFunctionRoles) },\n\t{ true,  'c', \"class\",\t\t  \"classes\",\n\t  .referenceOnly = false, ATTACH_ROLES(JsClassRoles)    },\n\t{ true,  'm', \"method\",\t\t  \"methods\"          },\n\t{ true,  'p', \"property\",\t  \"properties\"       },\n\t{ true,  'C', \"constant\",\t  \"constants\"        },\n\t{ true,  'v', \"variable\",\t  \"global variables\",\n\t  .referenceOnly = false, ATTACH_ROLES(JsVariableRoles) },\n\t{ true,  'g', \"generator\",\t  \"generators\"       },\n\t{ true,  'G', \"getter\",\t\t  \"getters\"          },\n\t{ true,  'S', \"setter\",\t\t  \"setters\"          },\n\t{ true,  'M', \"field\",\t\t  \"fields\"           },\n};\n\nstatic fieldDefinition JsFields[] = {\n\t{\n\t\t.name = \"properties\",\n\t\t.description = \"properties (static)\",\n\t\t.enabled = false,\n\t\t.version = 2,\n\t},\n};\n\nstatic const keywordTable JsKeywordTable [] = {\n\t/* keyword\t\tkeyword ID */\n\t{ \"function\",\tKEYWORD_function\t\t\t},\n\t{ \"Function\",\tKEYWORD_capital_function\t},\n\t{ \"Object\",\t\tKEYWORD_capital_object\t\t},\n\t{ \"prototype\",\tKEYWORD_prototype\t\t\t},\n\t{ \"var\",\t\tKEYWORD_var\t\t\t\t\t},\n\t{ \"let\",\t\tKEYWORD_let\t\t\t\t\t},\n\t{ \"const\",\t\tKEYWORD_const\t\t\t\t},\n\t{ \"new\",\t\tKEYWORD_new\t\t\t\t\t},\n\t{ \"this\",\t\tKEYWORD_this\t\t\t\t},\n\t{ \"for\",\t\tKEYWORD_for\t\t\t\t\t},\n\t{ \"while\",\t\tKEYWORD_while\t\t\t\t},\n\t{ \"do\",\t\t\tKEYWORD_do\t\t\t\t\t},\n\t{ \"if\",\t\t\tKEYWORD_if\t\t\t\t\t},\n\t{ \"else\",\t\tKEYWORD_else\t\t\t\t},\n\t{ \"switch\",\t\tKEYWORD_switch\t\t\t\t},\n\t{ \"try\",\t\tKEYWORD_try\t\t\t\t\t},\n\t{ \"catch\",\t\tKEYWORD_catch\t\t\t\t},\n\t{ \"finally\",\tKEYWORD_finally\t\t\t\t},\n\t{ \"sap\",\t    KEYWORD_sap\t\t\t\t\t},\n\t{ \"return\",\t\tKEYWORD_return\t\t\t\t},\n\t{ \"class\",\t\tKEYWORD_class\t\t\t\t},\n\t{ \"extends\",\tKEYWORD_extends\t\t\t\t},\n\t{ \"static\",\t\tKEYWORD_static\t\t\t\t},\n\t{ \"default\",\tKEYWORD_default\t\t\t\t},\n\t{ \"export\",\t\tKEYWORD_export\t\t\t\t},\n\t{ \"async\",\t\tKEYWORD_async\t\t\t\t},\n\t{ \"get\",\t\tKEYWORD_get\t\t\t\t\t},\n\t{ \"set\",\t\tKEYWORD_set\t\t\t\t\t},\n};\n\n/*\n * FUNCTION DEFINITIONS\n */\n\n/* Recursive functions */\nstatic void readTokenFull (tokenInfo *const token, bool include_newlines, vString *const repr);\nstatic void skipArgumentList (tokenInfo *const token, bool include_newlines);\nstatic void skipParameterList (tokenInfo *const token, bool include_newlines, vString *const repr);\nstatic bool parseFunction (tokenInfo *const token, tokenInfo *const name, const bool is_inside_class);\nstatic bool parseBlock (tokenInfo *const token, int parent_scope);\nstatic bool parseMethods (tokenInfo *const token, int class_index, const bool is_es6_class);\nstatic bool parseLine (tokenInfo *const token, bool is_inside_class);\nstatic void parseUI5 (tokenInfo *const token);\n\n#ifdef DO_TRACING\nstatic const char *tokenTypeName(enum eTokenType e);\nstatic const char* getNameStringForCorkIndex(int index);\nstatic const char* getKindStringForCorkIndex(int index);\nstatic const char *kindName(jsKind kind);\n// #define DO_TRACING_USE_DUMP_TOKEN\n#ifdef DO_TRACING_USE_DUMP_TOKEN\nstatic void dumpToken (const tokenInfo *const token);\n#endif\n#endif\n\nstatic void *newPoolToken (void *createArg CTAGS_ATTR_UNUSED)\n{\n\ttokenInfo *token = xMalloc (1, tokenInfo);\n\n\ttoken->string = vStringNew ();\n\ttoken->scope = CORK_NIL;\n\n\treturn token;\n}\n\nstatic void clearPoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\n\ttoken->type = TOKEN_UNDEFINED;\n\ttoken->keyword = KEYWORD_NONE;\n\ttoken->nestLevel = 0;\n\ttoken->dynamicProp = false;\n\ttoken->lineNumber = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\tvStringClear (token->string);\n\ttoken->scope = CORK_NIL;\n}\n\nstatic void deletePoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\tvStringDelete (token->string);\n\teFree (token);\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const src,\n\t\t\t\t\t   bool const include_non_read_info)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tdest->keyword = src->keyword;\n\tdest->dynamicProp = src->dynamicProp;\n\tdest->c = src->c;\n\tvStringCopy(dest->string, src->string);\n\tif (include_non_read_info)\n\t{\n\t\tdest->nestLevel = src->nestLevel;\n\t\tdest->scope = src->scope;\n\t}\n}\n\nstatic void injectDynamicName (tokenInfo *const token, vString *newName)\n{\n\ttoken->dynamicProp = true;\n\tvStringDelete (token->string);\n\ttoken->string = newName;\n}\n\n/*\n * Tag generation functions\n */\n\nstruct bestJSEntryInScopeData {\n\tint index;\n};\n\nstatic bool findBestJSEntry (int corkIndex, tagEntryInfo *entry, void *cb_data)\n{\n\tstruct bestJSEntryInScopeData *data = cb_data;\n\n\tif (isRoleAssigned (entry, ROLE_DEFINITION_INDEX))\n\t{\n\t\tdata->index = corkIndex;\n\t\treturn false;\n\t}\n\n\tif (data->index == CORK_NIL || data->index > corkIndex)\n\t\tdata->index = corkIndex;\n\n\treturn true;\n}\n\nstatic int bestJSEntryInScope(int scope, const char *name)\n{\n\t/* If the SCOPE has a tag entry having NAME, the tag is the best\n\t * even if there are reference tag entries having NAME.\n\t * If the scope has only reference tag entries having NAME, the\n\t * tag having smallest cork index is the best.\n\t */\n\n\tstruct bestJSEntryInScopeData data = {\n\t\t.index = CORK_NIL,\n\t};\n\tforeachEntriesInScope (scope, name,  findBestJSEntry, &data);\n\treturn data.index;\n}\n\nstatic int makeJsRefTagsForNameChain (char *name_chain, const tokenInfo *token, int leaf_kind, int scope)\n{\n\t/* To fill the scope field of \"d\" of \"a.b.c.d\",\n\t * \"c\" must be tagged if the cork API is used.\n\t * ----------------------------------------------------------\n\t * How the fields for \"a\", \"b\", and \"c\" are filled.\n\t *   a  kind:class  scope:<given by SCOPE>  roles:chainElt\n\t *   b  kind:class  scope:class:a  roles:chainElt\n\t *\n\t *   The fields of c depends on LEAF_KIND that is passed to this functions.\n\t *\n\t *   if (LEAF_KIND == FUNCTION)\n\t *       c  kind:function  scope:class:b  roles:chainElt\n\t *   else\n\t *       c  kind:class  scope:class:b  roles:chainElt\n\t */\n\n\tconst char *name = name_chain;\n\tchar *next = strchr(name_chain, '.');\n\tif (next)\n\t\t*next = '\\0';\n\tint index = bestJSEntryInScope (scope, name);\n\n\tif (index == CORK_NIL)\n\t{\n\t\ttagEntryInfo e;\n\t\tint kind = JSTAG_CLASS;\n\t\tint role = JS_CLASS_CHAINELT;\n\t\tif (next == NULL && leaf_kind == JSTAG_FUNCTION)\n\t\t{\n\t\t\t/*\n\t\t\t * If we're creating a function (and not a method),\n\t\t\t * assume the parent is a plain variable.\n\t\t\t */\n\t\t\tkind = JSTAG_VARIABLE;\n\t\t\trole = JS_VARIABLE_CHAINELT;\n\t\t}\n\n\t\tinitRefTagEntry (&e, name, kind, role);\n\t\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\t\te.extensionFields.scopeIndex = scope;\n\n\t\tindex = makeTagEntry (&e);\n\t\t/* We should remove this condition. We should fix the callers passing\n\t\t * an empty name instead. makeTagEntry() returns CORK_NIL if the tag\n\t\t * name is empty. */\n\t\tif (index != CORK_NIL)\n\t\t\tregisterEntry (index);\n\t}\n\n\treturn next\n\t\t? makeJsRefTagsForNameChain (next + 1, token, leaf_kind, index)\n\t\t: index;\n}\n\nstatic int makeJsTagCommon (const tokenInfo *const token, const jsKind kind,\n\t\t\t\t\t\t\tvString *const signature, vString *const inheritance,\n\t\t\t\t\t\t\tbool anonymous, bool is_static, bool is_private, bool nulltag)\n{\n\tint index = CORK_NIL;\n\tconst char *name = vStringValue (token->string);\n\n\tconst char *p;\n\tchar *name_chain = NULL;\n\tif (!token->dynamicProp && kind != JSTAG_PROPERTY &&  (p = strrchr (name, '.')) != NULL )\n\t{\n\t\tif ((p - name) != 0)\n\t\t\tname_chain = eStrndup (name, (size_t) (p - name));\n\t\tname = p + 1;\n\t\tif (name[0] == '\\0')\n\t\t\treturn CORK_NIL;\n\t}\n\n\tint scope = token->scope;\n\tif (name_chain)\n\t{\n\t\tscope = makeJsRefTagsForNameChain (name_chain, token, kind, scope);\n\t\teFree (name_chain);\n\t}\n\n\t/*\n\t * Check whether NAME is already defined in SCOPE.\n\t * If the NAME is already defined, return the cork index for the NAME.\n\t */\n\tif (kind == JSTAG_FUNCTION || kind == JSTAG_CLASS)\n\t{\n\t\tindex = anyKindEntryInScope (scope, name, kind, true);\n\t\tif (index != CORK_NIL)\n\t\t\treturn index;\n\t}\n\n\ttagEntryInfo e;\n\tinitTagEntry (&e, name, kind);\n\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\te.extensionFields.scopeIndex = scope;\n\n\tif (is_private)\n\t\te.extensionFields.access = \"private\";\n\n\tif (is_static)\n\t\tattachParserField (&e, JsFields[F_PROPERTIES].ftype, \"static\");\n\n#ifdef DO_TRACING\n\t{\n\t\tconst char *scope_str = getNameStringForCorkIndex (scope);\n\t\tconst char *scope_kind_str = getKindStringForCorkIndex (scope);\n\t\tTRACE_PRINT(\"Emitting tag for symbol '%s' of kind '%s' with scope '%s:%s'\", name, kindName(kind), scope_kind_str, scope_str);\n\t}\n#endif\n\n\tif (signature && vStringLength(signature))\n\t{\n\t\tsize_t i;\n\t\t/* sanitize signature by replacing all control characters with a\n\t\t * space (because it's simple).\n\t\t * there should never be any junk in a valid signature, but who\n\t\t * knows what the user wrote and CTags doesn't cope well with weird\n\t\t * characters. */\n\t\tfor (i = 0; i < signature->length; i++)\n\t\t{\n\t\t\tunsigned char c = (unsigned char) vStringChar (signature, i);\n\t\t\tif (c < 0x20 /* below space */ || c == 0x7F /* DEL */)\n\t\t\t\tvStringChar (signature, i) = ' ';\n\t\t}\n\t\te.extensionFields.signature = vStringValue(signature);\n\t}\n\n\tif (inheritance)\n\t\te.extensionFields.inheritance = vStringValue(inheritance);\n\n\tif (anonymous)\n\t\tmarkTagExtraBit (&e, XTAG_ANONYMOUS);\n\n\tif (nulltag)\n\t\te.allowNullTag = 1;\n\n\tindex = makeTagEntry (&e);\n\t/* We shold remove This condition. We should fix the callers passing\n\t * an empty name instead. makeTagEntry() returns CORK_NIL if the tag\n\t * name is empty. */\n\tif (index != CORK_NIL)\n\t\tregisterEntry (index);\n\n\treturn index;\n}\n\nstatic int makeJsTag (const tokenInfo *const token, const jsKind kind,\n\t\t\t\t\t   vString *const signature, vString *const inheritance)\n{\n\treturn makeJsTagCommon (token, kind, signature, inheritance, false, false, false, false);\n}\n\nstatic int makeJsTagMaybePrivate (const tokenInfo *const token, const jsKind kind,\n\t\t\t\t\t\t\t\t  vString *const signature, vString *const inheritance,\n\t\t\t\t\t\t\t\t  const bool is_static, const bool is_private)\n{\n\tif (is_private) {\n\t\tvString * s = vStringNewInit (\"#\");\n\t\tvStringCat (s, token->string);\n\t\tvStringCopy (token->string, s);\n\t\tvStringDelete (s);\n\t}\n\n\treturn makeJsTagCommon (token, kind, signature, inheritance, false, is_static, is_private, false);\n}\n\nstatic int makeJsNullTag (const tokenInfo *const token, const jsKind kind,\n\t\t\t\t\t\t  vString *const signature, vString *const inheritance)\n{\n\treturn makeJsTagCommon (token, kind, signature, inheritance, false, false, false, true);\n}\n\nstatic int makeClassTagCommon (tokenInfo *const token, vString *const signature,\n\t\t\t\t\t\t  vString *const inheritance, bool anonymous)\n{\n\treturn makeJsTagCommon (token, JSTAG_CLASS, signature, inheritance, anonymous, false, false, false);\n}\n\nstatic int makeClassTag (tokenInfo *const token, vString *const signature,\n\t\t\t\t\t\t  vString *const inheritance)\n{\n\treturn makeClassTagCommon (token, signature, inheritance, false);\n}\n\nstatic int makeFunctionTagCommon (tokenInfo *const token, vString *const signature,\n\t\t\t\t\t\t\t\t  bool generator, bool anonymous)\n{\n\treturn makeJsTagCommon (token, generator ? JSTAG_GENERATOR : JSTAG_FUNCTION, signature, NULL,\n\t\t\t\t\t\t\tanonymous, false, false, false);\n}\n\nstatic int makeFunctionTag (tokenInfo *const token, vString *const signature, bool generator)\n{\n\treturn makeFunctionTagCommon (token, signature, generator, false);\n}\n\nstatic bool isClassName (tokenInfo *const name)\n{\n\tchar * p = strrchr(vStringValue (name->string), '.');\n\tif (p == NULL)\n\t\tp = vStringValue (name->string);\n\telse\n\t\tp++;\n\n\treturn isupper((unsigned char) *p);\n}\n\n/*\n * Parsing functions\n */\n\n/* given @p point, returns the first byte of the encoded output sequence, and\n * make sure the next ones will be returned by calls to getcFromInputFile()\n * as if the code point was simply written in the input file. */\nstatic int handleUnicodeCodePoint (uint32_t point)\n{\n\tint c = (int) point;\n\n\tAssert (point < 0x110000);\n\n#ifdef HAVE_ICONV\n\t/* if we do have iconv and the encodings are specified, use this */\n\tif (isConverting () && JSUnicodeConverter == (iconv_t) -2)\n\t{\n\t\t/* if we didn't try creating the converter yet, try and do so */\n\t\tJSUnicodeConverter = iconv_open (getLanguageEncoding (Lang_js), INTERNAL_ENCODING);\n\t}\n\tif (isConverting () && JSUnicodeConverter != (iconv_t) -1)\n\t{\n\t\tchar *input_ptr = (char *) &point;\n\t\tsize_t input_left = sizeof point;\n\t\t/* 4 bytes should be enough for any encoding (it's how much UTF-32\n\t\t * would need). */\n\t\t/* FIXME: actually iconv has a tendency to output a BOM for Unicode\n\t\t * encodings where it matters when the endianness is not specified in\n\t\t * the target encoding name.  E.g., if the target encoding is \"UTF-32\"\n\t\t * or \"UTF-16\" it will output 2 code points, the BOM (U+FEFF) and the\n\t\t * one we expect. This does not happen if the endianness is specified\n\t\t * explicitly, e.g. with \"UTF-32LE\", or \"UTF-16BE\".\n\t\t * However, it's not very relevant for the moment as nothing in CTags\n\t\t * cope well (if at all) with non-ASCII-compatible encodings like\n\t\t * UTF-32 or UTF-16 anyway. */\n\t\tchar output[4] = { 0 };\n\t\tchar *output_ptr = output;\n\t\tsize_t output_left = ARRAY_SIZE (output);\n\n\t\tif (iconv (JSUnicodeConverter, &input_ptr, &input_left, &output_ptr, &output_left) == (size_t) -1)\n\t\t{\n\t\t\t/* something went wrong, which probably means the output encoding\n\t\t\t * cannot represent the character.  Use a placeholder likely to be\n\t\t\t * supported instead, that's also valid in an identifier */\n\t\t\tverbose (\"JavaScript: Encoding: %s\\n\", strerror (errno));\n\t\t\tc = '_';\n\t\t}\n\t\telse\n\t\t{\n\t\t\tconst size_t output_len = ARRAY_SIZE (output) - output_left;\n\n\t\t\t/* put all but the first byte back so that getcFromInputFile() will\n\t\t\t * return them in the right order */\n\t\t\tfor (unsigned int i = 1; i < output_len; i++)\n\t\t\t\tungetcToInputFile ((unsigned char) output[output_len - i]);\n\t\t\tc = (unsigned char) output[0];\n\t\t}\n\n\t\ticonv (JSUnicodeConverter, NULL, NULL, NULL, NULL);\n\t}\n\telse\n#endif\n\t{\n\t\t/* when no encoding is specified (or no iconv), assume UTF-8 is good.\n\t\t * Why UTF-8?  Because it's an ASCII-compatible common Unicode encoding. */\n\t\tif (point < 0x80)\n\t\t\tc = (unsigned char) point;\n\t\telse if (point < 0x800)\n\t\t{\n\t\t\tc = (unsigned char) (0xc0 | ((point >> 6) & 0x1f));\n\t\t\tungetcToInputFile ((unsigned char) (0x80 | (point & 0x3f)));\n\t\t}\n\t\telse if (point < 0x10000)\n\t\t{\n\t\t\tc = (unsigned char) (0xe0 | ((point >> 12) & 0x0f));\n\t\t\tungetcToInputFile ((unsigned char) (0x80 | ((point >>  0) & 0x3f)));\n\t\t\tungetcToInputFile ((unsigned char) (0x80 | ((point >>  6) & 0x3f)));\n\t\t}\n\t\telse if (point < 0x110000)\n\t\t{\n\t\t\tc = (unsigned char) (0xf0 | ((point >> 18) & 0x07));\n\t\t\tungetcToInputFile ((unsigned char) (0x80 | ((point >>  0) & 0x3f)));\n\t\t\tungetcToInputFile ((unsigned char) (0x80 | ((point >>  6) & 0x3f)));\n\t\t\tungetcToInputFile ((unsigned char) (0x80 | ((point >> 12) & 0x3f)));\n\t\t}\n\t}\n\n\treturn c;\n}\n\n/* reads a Unicode escape sequence after the \"\\\" prefix.\n * @param value Location to store the escape sequence value.\n * @param isUTF16 Location to store whether @param value is an UTF-16 word.\n * @returns Whether a valid sequence was read. */\nstatic bool readUnicodeEscapeSequenceValue (uint32_t *const value,\n\t\t\t\t\t\t\t\t\t\t\tbool *const isUTF16)\n{\n\tbool valid = false;\n\tint d = getcFromInputFile ();\n\n\tif (d != 'u')\n\t\tungetcToInputFile (d);\n\telse\n\t{\n\t\tint e = getcFromInputFile ();\n\t\tchar cp[6 + 1]; /* up to 6 hex + possible closing '}' or invalid char */\n\t\tunsigned int cp_len = 0;\n\n\t\t*isUTF16 = (e != '{');\n\t\tif (e == '{')\n\t\t{\t/* Handles Unicode code point escapes: \\u{ HexDigits }\n\t\t\t * We skip the leading 0s because there can be any number of them\n\t\t\t * and they don't change any meaning. */\n\t\t\tbool has_leading_zero = false;\n\t\t\tint l;\n\n\t\t\twhile ((cp[cp_len] = (char) (l = getcFromInputFile ())) == '0')\n\t\t\t\thas_leading_zero = true;\n\n\t\t\twhile (isxdigit (l) && ++cp_len < ARRAY_SIZE (cp))\n\t\t\t\tcp[cp_len] = (char) (l = getcFromInputFile ());\n\t\t\tvalid = ((cp_len > 0 || has_leading_zero) &&\n\t\t\t\t\t cp_len < ARRAY_SIZE (cp) && cp[cp_len] == '}' &&\n\t\t\t\t\t /* also check if it's a valid Unicode code point */\n\t\t\t\t\t (cp_len < 6 ||\n\t\t\t\t\t  (cp_len == 6 && strncmp (cp, \"110000\", 6) < 0)));\n\t\t\tif (! valid) /* put back the last (likely invalid) character */\n\t\t\t\tungetcToInputFile (l);\n\t\t}\n\t\telse\n\t\t{\t/* Handles Unicode escape sequences: \\u Hex4Digits */\n\t\t\tint l;\n\t\t\tdo\n\t\t\t\tcp[cp_len] = (char) (l = ((cp_len == 0) ? e : getcFromInputFile ()));\n\t\t\twhile (isxdigit (l) && ++cp_len < 4);\n\t\t\tvalid = (cp_len == 4);\n\t\t}\n\n\t\tif (! valid)\n\t\t{\n\t\t\t/* we don't get every character back, but it would require to\n\t\t\t * be able to put up to 9 characters back (in the worst case\n\t\t\t * for handling invalid \\u{10FFFFx}), and here we're recovering\n\t\t\t * from invalid syntax anyway. */\n\t\t\tungetcToInputFile (e);\n\t\t\tungetcToInputFile (d);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t*value = 0;\n\t\t\tfor (unsigned int i = 0; i < cp_len; i++)\n\t\t\t{\n\t\t\t\t*value *= 16;\n\n\t\t\t\t/* we know it's a hex digit, no need to double check */\n\t\t\t\tif (cp[i] < 'A')\n\t\t\t\t\t*value += (unsigned int) cp[i] - '0';\n\t\t\t\telse if (cp[i] < 'a')\n\t\t\t\t\t*value += 10 + (unsigned int) cp[i] - 'A';\n\t\t\t\telse\n\t\t\t\t\t*value += 10 + (unsigned int) cp[i] - 'a';\n\t\t\t}\n\t\t}\n\t}\n\n\treturn valid;\n}\n\nstatic int valueToXDigit (unsigned char v)\n{\n\tAssert (v <= 0xF);\n\n\tif (v >= 0xA)\n\t\treturn 'A' + (v - 0xA);\n\telse\n\t\treturn '0' + v;\n}\n\n/* Reads and expands a Unicode escape sequence after the \"\\\" prefix.  If the\n * escape sequence is a UTF16 high surrogate, also try and read the low\n * surrogate to emit the proper code point.\n * @param fallback The character to return if the sequence is invalid. Usually\n *                 this would be the '\\' character starting the sequence.\n * @returns The first byte of the sequence, or @param fallback if the sequence\n *          is invalid. On success, next calls to getcFromInputFile() will\n *          return subsequent bytes (if any). */\nstatic int readUnicodeEscapeSequence (const int fallback)\n{\n\tint c;\n\tuint32_t value;\n\tbool isUTF16;\n\n\tif (! readUnicodeEscapeSequenceValue (&value, &isUTF16))\n\t\tc = fallback;\n\telse\n\t{\n\t\tif (isUTF16 && (value & 0xfc00) == 0xd800)\n\t\t{\t/* this is a high surrogate, try and read its low surrogate and\n\t\t\t * emit the resulting code point */\n\t\t\tuint32_t low;\n\t\t\tint d = getcFromInputFile ();\n\n\t\t\tif (d != '\\\\' || ! readUnicodeEscapeSequenceValue (&low, &isUTF16))\n\t\t\t\tungetcToInputFile (d);\n\t\t\telse if (! isUTF16)\n\t\t\t{\t/* not UTF-16 low surrogate but a plain code point */\n\t\t\t\td = handleUnicodeCodePoint (low);\n\t\t\t\tungetcToInputFile (d);\n\t\t\t}\n\t\t\telse if ((low & 0xfc00) != 0xdc00)\n\t\t\t{\t/* not a low surrogate, so put back the escaped representation\n\t\t\t\t * in case it was another high surrogate we should read as part\n\t\t\t\t * of another pair. */\n\t\t\t\tungetcToInputFile (valueToXDigit ((unsigned char) ((low & 0x000f) >>  0)));\n\t\t\t\tungetcToInputFile (valueToXDigit ((unsigned char) ((low & 0x00f0) >>  4)));\n\t\t\t\tungetcToInputFile (valueToXDigit ((unsigned char) ((low & 0x0f00) >>  8)));\n\t\t\t\tungetcToInputFile (valueToXDigit ((unsigned char) ((low & 0xf000) >> 12)));\n\t\t\t\tungetcToInputFile ('u');\n\t\t\t\tungetcToInputFile ('\\\\');\n\t\t\t}\n\t\t\telse\n\t\t\t\tvalue = 0x010000 + ((value & 0x03ff) << 10) + (low & 0x03ff);\n\t\t}\n\t\tc = handleUnicodeCodePoint (value);\n\t}\n\n\treturn c;\n}\n\nstatic void parseString (vString *const string, const int delimiter)\n{\n\tbool end = false;\n\twhile (! end)\n\t{\n\t\tint c = getcFromInputFile ();\n\t\tif (c == EOF)\n\t\t\tend = true;\n\t\telse if (c == '\\\\')\n\t\t{\n\t\t\t/* Eat the escape sequence (\\\", \\', etc).  We properly handle\n\t\t\t * <LineContinuation> by eating a whole \\<CR><LF> not to see <LF>\n\t\t\t * as an unescaped character, which is invalid and handled below.\n\t\t\t * Also, handle the fact that <LineContinuation> produces an empty\n\t\t\t * sequence.\n\t\t\t * See ECMA-262 7.8.4 */\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == 'u')\n\t\t\t{\n\t\t\t\tungetcToInputFile (c);\n\t\t\t\tc = readUnicodeEscapeSequence ('\\\\');\n\t\t\t\tvStringPut (string, c);\n\t\t\t}\n\t\t\telse if (c != '\\r' && c != '\\n')\n\t\t\t\tvStringPut(string, c);\n\t\t\telse if (c == '\\r')\n\t\t\t{\n\t\t\t\tc = getcFromInputFile();\n\t\t\t\tif (c != '\\n')\n\t\t\t\t\tungetcToInputFile (c);\n\t\t\t}\n\t\t}\n\t\telse if (c == delimiter)\n\t\t\tend = true;\n\t\telse if (c == '\\r' || c == '\\n')\n\t\t{\n\t\t\t/* those are invalid when not escaped */\n\t\t\tend = true;\n\t\t\t/* we don't want to eat the newline itself to let the automatic\n\t\t\t * semicolon insertion code kick in */\n\t\t\tungetcToInputFile (c);\n\t\t}\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\nstatic void parseRegExp (void)\n{\n\tint c;\n\tbool in_range = false;\n\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\tif (! in_range && c == '/')\n\t\t{\n\t\t\tdo /* skip flags */\n\t\t\t{\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t} while (isalpha (c));\n\t\t\tungetcToInputFile (c);\n\t\t\tbreak;\n\t\t}\n\t\telse if (c == '\\n' || c == '\\r')\n\t\t{\n\t\t\t/* invalid in a regex */\n\t\t\tungetcToInputFile (c);\n\t\t\tbreak;\n\t\t}\n\t\telse if (c == '\\\\')\n\t\t\tc = getcFromInputFile (); /* skip next character */\n\t\telse if (c == '[')\n\t\t\tin_range = true;\n\t\telse if (c == ']')\n\t\t\tin_range = false;\n\t} while (c != EOF);\n}\n\n/* Read a C identifier beginning with \"first_char\" and places it into\n * \"name\".\n */\n\nstatic int include_period_in_identifier = 0;\n\nstatic void accept_period_in_identifier(bool incl)\n{\n\tif (incl)\n\t{\n\t\tinclude_period_in_identifier++;\n\t}\n\telse if (!incl && include_period_in_identifier > 0)\n\t{\n\t\tinclude_period_in_identifier--;\n\t}\n}\n\nstatic bool isIdentChar(const int c)\n{\n\treturn (isalpha (c) || isdigit (c) || c == '$' || \\\n\t\t\tc == '@' || c == '_' || c == '#' || \\\n\t\t\tc >= 0x80 || (include_period_in_identifier > 0 && c == '.'));\n}\n\nstatic void parseIdentifier (vString *const string, const int first_char)\n{\n\tint c = first_char;\n\tAssert (isIdentChar (c));\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t\tif (c == '\\\\')\n\t\t\tc = readUnicodeEscapeSequence (c);\n\t} while (isIdentChar (c));\n\t/* if readUnicodeEscapeSequence() read an escape sequence this is incorrect,\n\t * as we should actually put back the whole escape sequence and not the\n\t * decoded character.  However, it's not really worth the hassle as it can\n\t * only happen if the input has an invalid escape sequence. */\n\tungetcToInputFile (c);\t\t/* unget non-identifier character */\n}\n\nstatic void parseTemplateString (vString *const string)\n{\n\tint c;\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\tif (c == '`' || c == EOF)\n\t\t\tbreak;\n\n\t\tvStringPut (string, c);\n\n\t\tif (c == '\\\\')\n\t\t{\n\t\t\tc = getcFromInputFile();\n\t\t\tif (c != EOF)\n\t\t\t\tvStringPut(string, c);\n\t\t}\n\t\telse if (c == '$')\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c != '{')\n\t\t\t\tungetcToInputFile (c);\n\t\t\telse\n\t\t\t{\n\t\t\t\tint depth = 1;\n\t\t\t\t/* we need to use the real token machinery to handle strings,\n\t\t\t\t * comments, regexes and whatnot */\n\t\t\t\ttokenInfo *token = newToken ();\n\t\t\t\tLastTokenType = TOKEN_UNDEFINED;\n\t\t\t\tvStringPut(string, c);\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\treadTokenFull (token, false, string);\n\t\t\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t\t\t\tdepth++;\n\t\t\t\t\telse if (isType (token, TOKEN_CLOSE_CURLY))\n\t\t\t\t\t\tdepth--;\n\t\t\t\t}\n\t\t\t\twhile (! isType (token, TOKEN_EOF) && depth > 0);\n\t\t\t\tdeleteToken (token);\n\t\t\t}\n\t\t}\n\t}\n\twhile (c != EOF);\n}\n\nstatic void reprToken (const tokenInfo *const token, vString *const repr)\n{\n\tswitch (token->type)\n\t{\n\t\tcase TOKEN_DOTS:\n\t\t\tvStringCatS (repr, \"...\");\n\t\t\tbreak;\n\n\t\tcase TOKEN_STRING:\n\t\tcase TOKEN_TEMPLATE_STRING:\n\t\t\tvStringPut (repr, token->c);\n\t\t\tvStringCat (repr, token->string);\n\t\t\tvStringPut (repr, token->c);\n\t\t\tbreak;\n\n\t\tcase TOKEN_IDENTIFIER:\n\t\tcase TOKEN_KEYWORD:\n\t\t\tvStringCat (repr, token->string);\n\t\t\tbreak;\n\n\t\tcase TOKEN_EOF:\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tvStringPut (repr, token->c);\n\t\t\tbreak;\n\t}\n}\n\nstatic bool doesExpectBinaryOperator (tokenType lastTokenType)\n{\n\tswitch (lastTokenType)\n\t{\n\t\tcase TOKEN_CHARACTER:\n\t\tcase TOKEN_IDENTIFIER:\n\t\tcase TOKEN_STRING:\n\t\tcase TOKEN_TEMPLATE_STRING:\n\t\tcase TOKEN_CLOSE_CURLY:\n\t\tcase TOKEN_CLOSE_PAREN:\n\t\tcase TOKEN_CLOSE_SQUARE:\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nstatic void parseHTML (bool skip)\n{\n\tint entries0 = countEntryInCorkQueue ();\n\n\tungetcToInputFile ('<');\n\thtmlParseJSXElement ();\n\n\tint entries1 = countEntryInCorkQueue ();\n\tif (entries1 > entries0)\n\t{\n\t\tfor (int i = (int)entries0; i < entries1; i++)\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (i);\n\t\t\tif (!e)\n\t\t\t\tcontinue;\n\n\t\t\tif (skip)\n\t\t\t\tmarkTagAsPlaceholder (e, true);\n\t\t\telse\n\t\t\t\tmarkTagExtraBit (e, XTAG_GUEST);\n\t\t}\n\t}\n}\n\nstatic void readTokenFullRaw (tokenInfo *const token, bool include_newlines, vString *const repr)\n{\n\tint c;\n\tint i;\n\tbool newline_encountered = false;\n\n\t/* if we've got a token held back, emit it */\n\tif (NextToken)\n\t{\n\t\tTRACE_PRINT(\"Emitting held token\");\n\t\tcopyToken (token, NextToken, false);\n\t\tdeleteToken (NextToken);\n\t\tNextToken = NULL;\n\t\tLastTokenType = token->type;\n\t\tif (repr)\n\t\t\treprToken (token, repr);\n\t\treturn;\n\t}\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\n#define SKIP_COMMENT_SINGLE_AND_RETRY()\t\t\t\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tskipToCharacterInInputFile ('\\n');\t\t\t\t\t\t\t\t\\\n\t\tnewline_encountered = true;\t\t\t\t\t\t\t\t\t\t\\\n\t\tgoto getNextChar;\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t} while (0)\n\ngetNextChar:\n\ti = 0;\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\tif (c == '\\r' || c == '\\n')\n\t\t\tnewline_encountered = true;\n\t\ti++;\n\t}\n\twhile (c == '\\t' || c == ' ' || c == '\\r' || c == '\\n');\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\t/* special case to insert a separator */\n\tif (repr && c != EOF && i > 1)\n\t\tvStringPut (repr, ' ');\n\n\ttoken->c = c;\n\n\tswitch (c)\n\t{\n\t\tcase EOF: token->type = TOKEN_EOF;\t\t\tbreak;\n\t\tcase '(': token->type = TOKEN_OPEN_PAREN;\tbreak;\n\t\tcase ')': token->type = TOKEN_CLOSE_PAREN;\tbreak;\n\t\tcase ';': token->type = TOKEN_SEMICOLON;\tbreak;\n\t\tcase ',': token->type = TOKEN_COMMA;\t\tbreak;\n\t\tcase '.':\n\t\t{\n\t\t\ttoken->type = TOKEN_PERIOD;\n\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d != '.')\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\td = getcFromInputFile ();\n\t\t\tif (d != '.')\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\tungetcToInputFile ('.');\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\ttoken->type = TOKEN_DOTS;\n\t\t\tbreak;\n\t\t}\n\t\tcase ':': token->type = TOKEN_COLON;\t\tbreak;\n\t\tcase '{': token->type = TOKEN_OPEN_CURLY;\tbreak;\n\t\tcase '}': token->type = TOKEN_CLOSE_CURLY;\tbreak;\n\t\tcase '[': token->type = TOKEN_OPEN_SQUARE;\tbreak;\n\t\tcase ']': token->type = TOKEN_CLOSE_SQUARE;\tbreak;\n\n\t\tcase '=':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '>')\n\t\t\t\ttoken->type = TOKEN_ARROW;\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_EQUAL_SIGN;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '+':\n\t\tcase '-':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == c) /* ++ or -- */\n\t\t\t{\n\t\t\t\t/* HTML comment close like \"-->\" behave as single-line comments \"//\", see\n\t\t\t\t * https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-html-like-comments */\n\t\t\t\tif (newline_encountered && c == '-')\n\t\t\t\t{\n\t\t\t\t\td = getcFromInputFile ();\n\t\t\t\t\tif (d != '>')\n\t\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\t\telse\n\t\t\t\t\t\tSKIP_COMMENT_SINGLE_AND_RETRY();\n\t\t\t\t}\n\t\t\t\ttoken->type = TOKEN_POSTFIX_OPERATOR;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_BINARY_OPERATOR;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '*':\n\t\t\ttoken->type = TOKEN_STAR;\n\t\t\tbreak;\n\t\tcase '%':\n\t\tcase '?':\n\t\tcase '>':\n\t\tcase '^':\n\t\tcase '|':\n\t\tcase '&':\n\t\t\ttoken->type = TOKEN_BINARY_OPERATOR;\n\t\t\tbreak;\n\n\t\tcase '<':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\t/* HTML comment like \"<!--\" behave as single-line comments \"//\", see\n\t\t\t * https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-html-like-comments\n\t\t\t * This is *not* JSX */\n\t\t\tif (d == '!')\n\t\t\t{\n\t\t\t\td = getcFromInputFile ();\n\t\t\t\tif (d != '-')\n\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\td = getcFromInputFile ();\n\t\t\t\t\tif (d != '-')\n\t\t\t\t\t{\n\t\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\t\t\t/* put back the previous '-' */\n\t\t\t\t\t\tungetcToInputFile ('-');\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tSKIP_COMMENT_SINGLE_AND_RETRY();\n\t\t\t\t}\n\t\t\t\t/* if we made it here, it's a binary '<' followed by '!' */\n\t\t\t\tungetcToInputFile ('!');\n\t\t\t\ttoken->type = TOKEN_BINARY_OPERATOR;\n\t\t\t}\n\t\t\telse if (doesExpectBinaryOperator (LastTokenType))\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_BINARY_OPERATOR;\n\t\t\t\t/*\n\t\t\t\t * Skip '<<', '<<=', and '<='.\n\t\t\t\t *\n\t\t\t\t * '<<' must be handled here.\n\t\t\t\t * If '<<' is read as two tokens, '<'\n\t\t\t\t * and '<', the parser treats the second one\n\t\t\t\t * as the start of JSX_TOKEN.\n\t\t\t\t *\n\t\t\t\t * Handling '<=' and '<<=' here is just for minor\n\t\t\t\t * optimization.\n\t\t\t\t */\n\t\t\t\tif (d == '<')\n\t\t\t\t\td = getcFromInputFile ();\n\t\t\t\tif (d != '=')\n\t\t\t\t\tungetcToInputFile (d);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\tbool skip = !isXtagEnabled (XTAG_GUEST);\n\t\t\t\ttoken->type = TOKEN_JSX;\n\t\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\t\tparseHTML (skip);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '\\'':\n\t\tcase '\"':\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tparseString (token->string, c);\n\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\tbreak;\n\n\t\tcase '`':\n\t\t\ttoken->type = TOKEN_TEMPLATE_STRING;\n\t\t\tparseTemplateString (token->string);\n\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\tbreak;\n\n\t\tcase '/':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif ( (d != '*') &&\t\t/* is this the start of a comment? */\n\t\t\t\t\t(d != '/') )\t\t/* is a one line comment? */\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\tswitch (LastTokenType)\n\t\t\t\t{\n\t\t\t\t\tcase TOKEN_CHARACTER:\n\t\t\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\t\tcase TOKEN_STRING:\n\t\t\t\t\tcase TOKEN_TEMPLATE_STRING:\n\t\t\t\t\tcase TOKEN_CLOSE_CURLY:\n\t\t\t\t\tcase TOKEN_CLOSE_PAREN:\n\t\t\t\t\tcase TOKEN_CLOSE_SQUARE:\n\t\t\t\t\t\ttoken->type = TOKEN_BINARY_OPERATOR;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\ttoken->type = TOKEN_REGEXP;\n\t\t\t\t\t\tparseRegExp ();\n\t\t\t\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (d == '*')\n\t\t\t\t{\n\t\t\t\t\tskipToCharacterInInputFile2('*', '/');\n\t\t\t\t\tgoto getNextChar;\n\t\t\t\t}\n\t\t\t\telse if (d == '/')\t/* is this the start of a comment?  */\n\t\t\t\t{\n\t\t\t\t\tSKIP_COMMENT_SINGLE_AND_RETRY();\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '#':\n\t\t\t/* skip shebang in case of e.g. Node.js scripts */\n\t\t\tif (token->lineNumber > 1)\n\t\t\t\ttoken->type = TOKEN_HASH;\n\t\t\telse if ((c = getcFromInputFile ()) != '!')\n\t\t\t{\n\t\t\t\tungetcToInputFile (c);\n\t\t\t\ttoken->type = TOKEN_HASH;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tskipToCharacterInInputFile ('\\n');\n\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase '@':\n\t\t\ttoken->type = TOKEN_ATMARK;\n\t\t\tbreak;\n\n\t\tcase '\\\\':\n\t\t\tc = readUnicodeEscapeSequence (c);\n\t\t\t/* fallthrough */\n\t\tdefault:\n\t\t\tif (! isIdentChar (c))\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\telse\n\t\t\t{\n\t\t\t\tparseIdentifier (token->string, c);\n\t\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\t\ttoken->keyword = lookupKeyword (vStringValue (token->string), Lang_js);\n\t\t\t\tif (isKeyword (token, KEYWORD_NONE))\n\t\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\telse\n\t\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\tif (include_newlines && newline_encountered)\n\t{\n\t\t/* This isn't strictly correct per the standard, but following the\n\t\t * real rules means understanding all statements, and that's not\n\t\t * what the parser currently does.  What we do here is a guess, by\n\t\t * avoiding inserting semicolons that would make the statement on\n\t\t * the left or right obviously invalid.  Hopefully this should not\n\t\t * have false negatives (e.g. should not miss insertion of a semicolon)\n\t\t * but might have false positives (e.g. it will wrongfully emit a\n\t\t * semicolon sometimes, i.e. for the newline in \"foo\\n(bar)\").\n\t\t * This should however be mostly harmless as we only deal with\n\t\t * newlines in specific situations where we know a false positive\n\t\t * wouldn't hurt too bad. */\n\n\t\t/* these already end a statement, so no need to duplicate it */\n\t\t#define IS_STMT_SEPARATOR(t) ((t) == TOKEN_SEMICOLON    || \\\n\t\t\t\t\t\t\t\t\t  (t) == TOKEN_EOF          || \\\n\t\t\t\t\t\t\t\t\t  (t) == TOKEN_COMMA        || \\\n\t\t\t\t\t\t\t\t\t  (t) == TOKEN_OPEN_CURLY)\n\t\t/* these cannot be the start or end of a statement */\n\t\t#define IS_BINARY_OPERATOR(t) ((t) == TOKEN_EQUAL_SIGN      || \\\n\t\t\t\t\t\t\t\t\t   (t) == TOKEN_ARROW           || \\\n\t\t\t\t\t\t\t\t\t   (t) == TOKEN_COLON           || \\\n\t\t\t\t\t\t\t\t\t   (t) == TOKEN_PERIOD          || \\\n\t\t\t\t\t\t\t\t\t   (t) == TOKEN_STAR            || \\\n\t\t\t\t\t\t\t\t\t   (t) == TOKEN_BINARY_OPERATOR)\n\n\t\tif (! IS_STMT_SEPARATOR(LastTokenType) &&\n\t\t\t! IS_STMT_SEPARATOR(token->type) &&\n\t\t\t! IS_BINARY_OPERATOR(LastTokenType) &&\n\t\t\t! IS_BINARY_OPERATOR(token->type) &&\n\t\t\t/* these cannot be followed by a semicolon */\n\t\t\t! (LastTokenType == TOKEN_OPEN_PAREN ||\n\t\t\t   LastTokenType == TOKEN_OPEN_SQUARE))\n\t\t{\n\t\t\t/* hold the token... */\n\t\t\tAssert (NextToken == NULL);\n\t\t\tNextToken = newToken ();\n\t\t\tcopyToken (NextToken, token, false);\n\n\t\t\t/* ...and emit a semicolon instead */\n\t\t\ttoken->type = TOKEN_SEMICOLON;\n\t\t\ttoken->keyword = KEYWORD_NONE;\n\t\t\tvStringClear (token->string);\n\t\t\ttoken->c = '\\n';\n\t\t}\n\n\t\t#undef IS_STMT_SEPARATOR\n\t\t#undef IS_BINARY_OPERATOR\n\t}\n\n\tLastTokenType = token->type;\n\n\tif (repr)\n\t\treprToken (token, repr);\n\n#undef SKIP_COMMENT_SINGLE_AND_RETRY\n}\n\n/* whether something we consider a keyword (either because it sometimes is or\n * because of the parser's perks) is actually valid as a function name\n * See https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#sec-keywords-and-reserved-words */\nstatic bool canBeFunctionName (const tokenInfo *const token, bool strict_mode)\n{\n\tswitch (token->keyword)\n\t{\n\t\t/* non-keywords specific to this parser */\n\t\tcase KEYWORD_capital_function:\n\t\tcase KEYWORD_capital_object:\n\t\tcase KEYWORD_prototype:\n\t\tcase KEYWORD_sap:\n\t\t/* syntactic, but not keyword:\n\t\t *     as async from get meta of set target\n\t\t * \"await\" is OK as well */\n\t\tcase KEYWORD_async:\n\t\tcase KEYWORD_get:\n\t\tcase KEYWORD_set:\n\t\t\treturn true;\n\n\t\t/* strict-mode keywords\n\t\t *     let static implements interface package private protected public\n\t\t * we need to also include those which are OK as function names\n\t\t *     yield\n\t\t */\n\t\tcase KEYWORD_let:\n\t\tcase KEYWORD_static:\n\t\t\treturn ! strict_mode;\n\n\t\tdefault:\n\t\t\treturn isType (token, TOKEN_IDENTIFIER);\n\t}\n}\n\nstatic bool canBePropertyName (const tokenInfo *const token)\n{\n\t/* property names are pretty relaxed, any non reserved word is OK, even\n\t * strict-mode ones in strict-mode */\n\treturn canBeFunctionName (token, false);\n}\n\n/* See https://babeljs.io/blog/2018/09/17/decorators */\nstatic void skipBabelDecorator (tokenInfo *token, bool include_newlines, vString *const repr)\n{\n\treadTokenFullRaw (token, include_newlines, repr);\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\t/*  @(complex ? dec1 : dec2) */\n\t\tif (repr)\n\t\t\tskipParameterList (token, include_newlines, repr);\n\t\telse\n\t\t\tskipArgumentList (token, include_newlines);\n\t\tTRACE_PRINT (\"found @(...) style decorator\");\n\t}\n\telse if (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\t/*  @namespace.foo (...) */\n\t\tbool found_period = false;\n\t\twhile (1)\n\t\t{\n\t\t\treadTokenFullRaw (token, include_newlines, repr);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t{\n\t\t\t\tif (!found_period)\n\t\t\t\t{\n\t\t\t\t\tTRACE_PRINT(\"found @namespace.bar style decorator\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tfound_period = false;\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_PERIOD))\n\t\t\t\tfound_period = true;\n\t\t\telse if (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t{\n\t\t\t\tif (repr)\n\t\t\t\t\tskipParameterList (token, include_newlines, repr);\n\t\t\t\telse\n\t\t\t\t\tskipArgumentList (token, include_newlines);\n\t\t\t\tTRACE_PRINT(\"found @foo(...) style decorator\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tTRACE_PRINT(\"found @foo style decorator\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t\t/* Unexpected token after @ */\n\t\tTRACE_PRINT(\"found unexpected token during skipping a decorator\");\n}\n\nstatic void readTokenFull (tokenInfo *const token, bool include_newlines, vString *const repr)\n{\n\treadTokenFullRaw (token, include_newlines, repr);\n\n\twhile (1)\n\t{\n\t\tif (!isType (token, TOKEN_ATMARK))\n\t\t\tbreak;\n\t\tskipBabelDecorator (token, include_newlines, repr);\n\t\t/* @decorator0 @decorator1 ... There can be more than one decorator. */\n\t}\n}\n\n#ifdef DO_TRACING_USE_DUMP_TOKEN\n/* trace readTokenFull() */\nstatic void readTokenFullDebug (tokenInfo *const token, bool include_newlines, vString *const repr)\n{\n\treadTokenFull (token, include_newlines, repr);\n\tdumpToken (token);\n}\n# define readTokenFull readTokenFullDebug\n#endif\n\nstatic void readToken (tokenInfo *const token)\n{\n\treadTokenFull (token, false, NULL);\n}\n\n/*\n * Token parsing functions\n */\n\nstatic int parseMethodsInAnonymousObject (tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tint index = CORK_NIL;\n\n\ttokenInfo *const anon_object = newToken ();\n\tcopyToken (anon_object, token, true);\n\tanonGenerate (anon_object->string, \"anonymousObject\", JSTAG_VARIABLE);\n\tanon_object->type = TOKEN_IDENTIFIER;\n\n\tindex = makeJsTagCommon (anon_object, JSTAG_VARIABLE, NULL, NULL, true, false, false, false);\n\tif (! parseMethods (token, index, false))\n\t{\n\t\t/* If no method is found, the anonymous object\n\t\t * should not be tagged.\n\t\t */\n\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\tif (e)\n\t\t\tmarkTagAsPlaceholder (e, true);\n\t\tindex = CORK_NIL;\n\t}\n\n\tdeleteToken (anon_object);\n\n\tTRACE_LEAVE();\n\treturn index;\n}\n\nstatic void skipArgumentList (tokenInfo *const token, bool include_newlines)\n{\n\tTRACE_ENTER();\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\t/* arguments? */\n\t{\n\t\tint nest_level = 1;\n\t\ttokenType prev_token_type = token->type;\n\t\twhile (nest_level > 0 && ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\tnest_level++;\n\t\t\telse if (isType (token, TOKEN_CLOSE_PAREN))\n\t\t\t\tnest_level--;\n\t\t\telse if (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\tif (prev_token_type == TOKEN_ARROW)\n\t\t\t\t\tparseBlock (token, CORK_NIL);\n\t\t\t\telse\n\t\t\t\t\tparseMethodsInAnonymousObject (token);\n\t\t\t}\n\t\t\telse if (isKeyword (token, KEYWORD_function))\n\t\t\t\tparseFunction (token, NULL, false);\n\n\t\t\tprev_token_type = token->type;\n\t\t}\n\t\treadTokenFull (token, include_newlines, NULL);\n\t}\n\tTRACE_LEAVE();\n}\n\nstatic void skipParameterList (tokenInfo *const token, bool include_newlines, vString *const repr)\n{\n\tTRACE_ENTER_TEXT(\"repr = %p\", repr);\n\n\tAssert (repr);\n\tif (isType (token, TOKEN_OPEN_PAREN))\t/* parameter? */\n\t{\n\t\tint nest_level = 1;\n\t\tif (repr)\n\t\t\tvStringPut (repr, '(');\n\n\t\twhile (nest_level > 0 && ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadTokenFull (token, false, repr);\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\tnest_level++;\n\t\t\telse if (isType (token, TOKEN_CLOSE_PAREN))\n\t\t\t\tnest_level--;\n\t\t}\n\t\treadTokenFull (token, include_newlines, NULL);\n\t}\n\tTRACE_LEAVE();\n}\n\nstatic void skipArrayList (tokenInfo *const token, bool include_newlines)\n{\n\t/*\n\t * Handle square brackets\n\t *   var name[1]\n\t * So we must check for nested open and closing square brackets\n\t */\n\n\tif (isType (token, TOKEN_OPEN_SQUARE))\t/* arguments? */\n\t{\n\t\tint nest_level = 1;\n\t\ttokenType prev_token_type = token->type;\n\t\twhile (nest_level > 0 && ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\tnest_level++;\n\t\t\telse if (isType (token, TOKEN_CLOSE_SQUARE))\n\t\t\t\tnest_level--;\n\t\t\telse if (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\tif (prev_token_type == TOKEN_ARROW)\n\t\t\t\t\tparseBlock (token, CORK_NIL);\n\t\t\t\telse\n\t\t\t\t\tparseMethodsInAnonymousObject (token);\n\t\t\t}\n\n\t\t\tprev_token_type = token->type;\n\t\t}\n\t\treadTokenFull (token, include_newlines, NULL);\n\t}\n}\n\nstatic void skipQualifiedIdentifier (tokenInfo *const token)\n{\n\t/* Skip foo.bar.baz */\n\twhile (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_PERIOD))\n\t\t\treadToken (token);\n\t\telse\n\t\t\tbreak;\n\t}\n}\n\nstatic void addContext (tokenInfo* const parent, const tokenInfo* const child)\n{\n\tvStringJoin (parent->string, '.', child->string);\n}\n\n/*\n * Scanning functions\n */\n\nstatic bool findCmdTerm (tokenInfo *const token, bool include_newlines, bool include_commas)\n{\n\t/*\n\t * Read until we find either a semicolon or closing brace.\n\t * Any nested braces will be handled within.\n\t */\n\twhile (! isType (token, TOKEN_SEMICOLON) &&\n\t\t   ! isType (token, TOKEN_CLOSE_CURLY) &&\n\t\t   ! (include_commas && isType (token, TOKEN_COMMA)) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\t/* Handle nested blocks */\n\t\tif ( isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tparseBlock (token, CORK_NIL);\n\t\t\treadTokenFull (token, include_newlines, NULL);\n\t\t}\n\t\telse if ( isType (token, TOKEN_OPEN_PAREN) )\n\t\t\tskipArgumentList(token, include_newlines);\n\t\telse if ( isType (token, TOKEN_OPEN_SQUARE) )\n\t\t\tskipArrayList(token, include_newlines);\n\t\telse\n\t\t\treadTokenFull (token, include_newlines, NULL);\n\t}\n\n\treturn isType (token, TOKEN_SEMICOLON);\n}\n\nstatic void parseSwitch (tokenInfo *const token)\n{\n\t/*\n\t * switch (expression) {\n\t * case value1:\n\t *     statement;\n\t *     break;\n\t * case value2:\n\t *     statement;\n\t *     break;\n\t * default : statement;\n\t * }\n\t */\n\n\treadToken (token);\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tskipArgumentList(token, false);\n\t}\n\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tparseBlock (token, CORK_NIL);\n\t}\n}\n\nstatic bool parseLoop (tokenInfo *const token)\n{\n\t/*\n\t * Handles these statements\n\t *     for (x=0; x<3; x++)\n\t *         document.write(\"This text is repeated three times<br>\");\n\t *\n\t *     for (x=0; x<3; x++)\n\t *     {\n\t *         document.write(\"This text is repeated three times<br>\");\n\t *     }\n\t *\n\t *     while (number<5){\n\t *         document.write(number+\"<br>\");\n\t *         number++;\n\t *     }\n\t *\n\t *     do{\n\t *         document.write(number+\"<br>\");\n\t *         number++;\n\t *     }\n\t *     while (number<5);\n\t */\n\tbool is_terminated = true;\n\n\tif (isKeyword (token, KEYWORD_for) || isKeyword (token, KEYWORD_while))\n\t{\n\t\treadToken(token);\n\n\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\tskipArgumentList(token, false);\n\n\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\tparseBlock (token, CORK_NIL);\n\t\telse\n\t\t\tis_terminated = parseLine(token, false);\n\t}\n\telse if (isKeyword (token, KEYWORD_do))\n\t{\n\t\treadToken(token);\n\n\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\tparseBlock (token, CORK_NIL);\n\t\telse\n\t\t\tis_terminated = parseLine(token, false);\n\n\t\tif (is_terminated)\n\t\t\treadToken(token);\n\n\t\tif (isKeyword (token, KEYWORD_while))\n\t\t{\n\t\t\treadToken(token);\n\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\tskipArgumentList(token, true);\n\n\t\t\tif (! isType (token, TOKEN_SEMICOLON))\n\t\t\t{\n\t\t\t\t/* oddly enough, `do {} while (0) var foo = 42` is perfectly\n\t\t\t\t * valid JS, so explicitly handle the remaining of the line\n\t\t\t\t * for the sake of the root scope handling (as parseJsFile()\n\t\t\t\t * always advances a token not to ever get stuck) */\n\t\t\t\tis_terminated = parseLine(token, false);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn is_terminated;\n}\n\nstatic bool parseIf (tokenInfo *const token)\n{\n\tbool read_next_token = true;\n\t/*\n\t * If statements have two forms\n\t *     if ( ... )\n\t *         one line;\n\t *\n\t *     if ( ... )\n\t *         statement;\n\t *     else\n\t *         statement\n\t *\n\t *     if ( ... ) {\n\t *         multiple;\n\t *         statements;\n\t *     }\n\t *\n\t *\n\t *     if ( ... ) {\n\t *         return elem\n\t *     }\n\t *\n\t *     This example if correctly written, but the\n\t *     else contains only 1 statement without a terminator\n\t *     since the function finishes with the closing brace.\n\t *\n\t *     function a(flag){\n\t *         if(flag)\n\t *             test(1);\n\t *         else\n\t *             test(2)\n\t *     }\n\t *\n\t * TODO:  Deal with statements that can optional end\n\t *        without a semi-colon.  Currently this messes up\n\t *        the parsing of blocks.\n\t *        Need to somehow detect this has happened, and either\n\t *        backup a token, or skip reading the next token if\n\t *        that is possible from all code locations.\n\t *\n\t */\n\n\treadToken (token);\n\n\tif (isKeyword (token, KEYWORD_if))\n\t{\n\t\t/*\n\t\t * Check for an \"else if\" and consume the \"if\"\n\t\t */\n\t\treadToken (token);\n\t}\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\tskipArgumentList(token, false);\n\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\tparseBlock (token, CORK_NIL);\n\telse\n\t{\n\t\t/* The next token should only be read if this statement had its own\n\t\t * terminator */\n\t\tread_next_token = findCmdTerm (token, true, false);\n\t}\n\treturn read_next_token;\n}\n\nstatic bool collectChildren (int corkIndex, tagEntryInfo *entry, void *data)\n{\n\tintArray *children = (intArray *)data;\n\n\tAssert (entry->extensionFields.scopeIndex != CORK_NIL);\n\tintArrayAdd (children, corkIndex);\n\n\treturn true;\n}\n\n/* During parsing, there is a case that a language object (parent)\n * should be tagged only when there are language objects (children)\n * are defined in the parent; if the parent has no child, the parser\n * should not make a tag for the parent.\n *\n * Handling the this case was not easy because the parser must fill\n * the scope field of children with the cork index of parent.\n * However, the parser can decide whether the parent should be tagged\n * or not after parsing inside the parent where the children are\n * defined.\n *\n * \"class\" is an example of the language object of the parent.\n * \"methods\" are examples of the language object of the children.\n * \"class\" is tagged as a class only when methods are found in it.\n *\n *\n * The parser handles this case with the following steps:\n *\n * 1.  make a dummy tag entry for the candidate of parent with\n *\n * >       int dummyIndex = makeSimplePlaceholder().\n *\n *     ctags doesn't emit this dummy tag entry.\n *\n * 2.  parse inside the candidate of parent and count children.\n *     If a child is found, make a tag for it with filling its\n *     scope field with the dummyIndex.\n *\n * 3. make a true tag entry for the parent if a child is found:\n *\n * >       int trueIdex = makeTagEntry (...);\n *\n * 4. update the scope fields of children with the trueIdex.\n *\n *         moveChildren (dummyIndex, trueIdex);\n *\n */\nstatic void moveChildren (int old_parent, int new_parent)\n{\n\tintArray *children = intArrayNew ();\n\tforeachEntriesInScope (old_parent, NULL, collectChildren, children);\n\tfor (unsigned int i = 0; i < intArrayCount (children); i++)\n\t{\n\t\tint c = intArrayItem (children, i);\n\n\t\tunregisterEntry (c);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (c);\n\t\tAssert (e);\n\t\te->extensionFields.scopeIndex = new_parent;\n\t\tregisterEntry (c);\n\t}\n\tintArrayDelete (children);\n}\n\nstatic bool parseFunction (tokenInfo *const token, tokenInfo *const lhs_name, const bool is_inside_class)\n{\n#ifdef DO_TRACING\n\t{\n\t\tconst char *scope_str = getNameStringForCorkIndex (token->scope);\n\t\tconst char *scope_kind_str = getKindStringForCorkIndex (token->scope);\n\t\tTRACE_ENTER_TEXT(\"token has scope '%s' of kind %s\", scope_str, scope_kind_str);\n\t}\n#endif\n\n\ttokenInfo *const name = newToken ();\n\tvString *const signature = vStringNew ();\n\tbool is_generator = false;\n\tbool is_anonymous = false;\n\tint index_for_name = CORK_NIL;\n\t/*\n\t * This deals with these formats\n\t *     function validFunctionTwo(a,b) {}\n\t *     function * generator(a,b) {}\n\t */\n\n\tcopyToken (name, token, true);\n\treadToken (name);\n\tif (isType (name, TOKEN_KEYWORD) &&\n\t\tcanBeFunctionName (name, false /* true if we're in strict mode */))\n\t{\n\t\t// treat as function name\n\t\tname->type = TOKEN_IDENTIFIER;\n\t\tname->keyword = KEYWORD_NONE;\n\t}\n\n\tif (isType (name, TOKEN_STAR))\n\t{\n\t\tis_generator = true;\n\t\treadToken (name);\n\t}\n\tif (isType (name, TOKEN_OPEN_PAREN))\n\t{\n\t\t/* anonymous function */\n\t\tcopyToken (token, name, false);\n\t\tanonGenerate (name->string, \"anonymousFunction\", JSTAG_FUNCTION);\n\t\tis_anonymous = true;\n\t}\n\telse if (!isType (name, TOKEN_IDENTIFIER))\n\t\tgoto cleanUp;\n\telse\n\t\treadToken (token);\n\n\tif ( isType (token, TOKEN_OPEN_PAREN) )\n\t\tskipParameterList(token, false, signature);\n\n\tif ( isType (token, TOKEN_OPEN_CURLY) )\n\t{\n\t\tif ( lhs_name != NULL && is_inside_class )\n\t\t{\n\t\t\tindex_for_name = makeJsTag (lhs_name, is_generator ? JSTAG_GENERATOR : JSTAG_METHOD, signature, NULL);\n\t\t}\n\t\telse if ( lhs_name != NULL )\n\t\t{\n\t\t\tindex_for_name = isClassName (lhs_name) ?\n\t\t\t\tmakeClassTag (lhs_name, signature, NULL):\n\t\t\t\tmakeFunctionTag (lhs_name, signature, is_generator);\n\t\t}\n\n\t\tint f = index_for_name,\n\t\t\tp = CORK_NIL;\n\t\tif ( f == CORK_NIL || !is_anonymous )\n\t\t\tp = isClassName (name) ?\n\t\t\t\tmakeClassTagCommon (name, signature, NULL, is_anonymous) :\n\t\t\t\tmakeFunctionTagCommon (name, signature, is_generator, is_anonymous);\n\n\t\tif (f == CORK_NIL)\n\t\t\tf = p;\n\n\t\tparseBlock (token, f);\n\t}\n\n\tif ( lhs_name == NULL )\n\t\tfindCmdTerm (token, false, false);\n\n cleanUp:\n\tvStringDelete (signature);\n\tdeleteToken (name);\n\n\tTRACE_LEAVE();\n\treturn index_for_name;\n}\n\n/* Parses a block surrounded by curly braces.\n * @p parent_scope is the scope name for this block, or NULL for unnamed scopes */\nstatic bool parseBlock (tokenInfo *const token, int parent_scope)\n{\n\tTRACE_ENTER();\n\n\tbool is_class = false;\n\tbool read_next_token = true;\n\tint save_scope = token->scope;\n\n\tif (parent_scope != CORK_NIL)\n\t{\n\t\ttoken->scope = parent_scope;\n\t\ttoken->nestLevel++;\n\t}\n\n\t/*\n\t * Make this routine a bit more forgiving.\n\t * If called on an open_curly advance it\n\t */\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\treadToken(token);\n\n\tif (! isType (token, TOKEN_CLOSE_CURLY))\n\t{\n\t\t/*\n\t\t * Read until we find the closing brace,\n\t\t * any nested braces will be handled within\n\t\t */\n\t\tdo\n\t\t{\n\t\t\tread_next_token = true;\n\t\t\tif (isKeyword (token, KEYWORD_this))\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * Means we are inside a class and have found\n\t\t\t\t * a class, not a function\n\t\t\t\t */\n\t\t\t\tis_class = true;\n\n\t\t\t\t/*\n\t\t\t\t * Ignore the remainder of the line\n\t\t\t\t * findCmdTerm(token);\n\t\t\t\t */\n\t\t\t\tread_next_token = parseLine (token, is_class);\n\t\t\t}\n\t\t\telse if (isKeyword (token, KEYWORD_var) ||\n\t\t\t\t\t isKeyword (token, KEYWORD_let) ||\n\t\t\t\t\t isKeyword (token, KEYWORD_const))\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * Potentially we have found an inner function.\n\t\t\t\t * Set something to indicate the scope\n\t\t\t\t */\n\t\t\t\tread_next_token = parseLine (token, is_class);\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\t/* Handle nested blocks */\n\t\t\t\tparseBlock (token, CORK_NIL);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * It is possible for a line to have no terminator\n\t\t\t\t * if the following line is a closing brace.\n\t\t\t\t * parseLine will detect this case and indicate\n\t\t\t\t * whether we should read an additional token.\n\t\t\t\t */\n\t\t\t\tread_next_token = parseLine (token, is_class);\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * Always read a new token unless we find a statement without\n\t\t\t * a ending terminator\n\t\t\t */\n\t\t\tif( read_next_token )\n\t\t\t\treadToken(token);\n\n\t\t\t/*\n\t\t\t * If we find a statement without a terminator consider the\n\t\t\t * block finished, otherwise the stack will be off by one.\n\t\t\t */\n\t\t} while (! isType (token, TOKEN_EOF) &&\n\t\t\t\t ! isType (token, TOKEN_CLOSE_CURLY) && read_next_token);\n\t}\n\n\ttoken->scope = save_scope;\n\tif (parent_scope != CORK_NIL)\n\t\ttoken->nestLevel--;\n\n\tTRACE_LEAVE();\n\treturn is_class;\n}\n\nstatic bool parseMethods (tokenInfo *const token, int class_index,\n\t\t\t\t\t\t  const bool is_es6_class)\n{\n\tTRACE_ENTER_TEXT(\"token is '%s' of type %s in parentToken '%s' of kind %s (es6: %s)\",\n\t\t\t\t\t vStringValue(token->string), tokenTypeName (token->type),\n\t\t\t\t\t class_index == CORK_NIL ? \"none\" : getNameStringForCorkIndex (class_index),\n\t\t\t\t\t class_index == CORK_NIL ? \"none\" : getKindStringForCorkIndex (class_index),\n\t\t\t\t\t is_es6_class? \"yes\": \"no\");\n\n\t/*\n\t * When making a tag for `name', its core index is stored to\n\t * `indexForName'. The value stored to `indexForName' is valid\n\t * till the value for `name' is updated. If the value for `name'\n\t * is changed, `indexForName' is reset to CORK_NIL.\n\t */\n\ttokenInfo *const name = newToken ();\n\tint index_for_name = CORK_NIL;\n\tbool has_methods = false;\n\tint save_scope = token->scope;\n\n\tif (class_index != CORK_NIL)\n\t\ttoken->scope = class_index;\n\n\t/*\n\t * This deals with these formats\n\t *     validProperty  : 2,\n\t *     validMethod    : function(a,b) {}\n\t *     'validMethod2' : function(a,b) {}\n\t *     container.dirtyTab = {'url': false, 'title':false, 'snapshot':false, '*': false}\n\t *     get prop() {}\n\t *     set prop(val) {}\n\t *     get(...) {}\n\t *     set(...) {}\n\t *\n\t * ES6 methods:\n\t *     property(...) {}\n\t *     *generator() {}\n\t *\n\t * ES6 computed name:\n\t *     [property]() {}\n\t *     get [property]() {}\n\t *     set [property]() {}\n\t *     *[generator]() {}\n\t *\n\t * tc39/proposal-class-fields\n\t *     field0 = function(a,b) {}\n\t *     field1 = 1\n\t * The parser extracts field0 as a method because the left value\n\t * is a function (kind propagation), and field1 as a field.\n\t *\n\t * static methods and static initialization blocks\n\t * - ref. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Static_initialization_blocks\n\t *\n\t *      static func() {}\n\t *      static {}\n\t *      static prop;\n\t *      static prop = val;\n\t */\n\n\tbool dont_read = false;\n\tdo\n\t{\n\t\tbool is_setter = false;\n\t\tbool is_getter = false;\n\t\tbool is_static = false;\n\n\t\tif (!dont_read)\n\t\t\treadToken (token);\n\t\tdont_read = false;\n\nstart:\n\t\tif (isType (token, TOKEN_CLOSE_CURLY))\n\t\t{\n\t\t\tgoto cleanUp;\n\t\t}\n\n\t\tif (isType (token, TOKEN_KEYWORD) && canBePropertyName (token))\n\t\t{\n\t\t\ttokenInfo *saved_token = newToken ();\n\t\t\tcopyToken (saved_token, token, true);\n\t\t\treadToken (token);\n\n\t\t\t/* it wasn't actually a keyword after all, make it an identifier */\n\t\t\tif (isType(token, TOKEN_OPEN_PAREN) || isType(token, TOKEN_COLON))\n\t\t\t{\n\t\t\t\tAssert (NextToken == NULL);\n\t\t\t\tNextToken = newToken ();\n\t\t\t\tcopyToken (NextToken, token, false);\t/* save token for next read */\n\t\t\t\tcopyToken (token, saved_token, true);\t/* restore token to process */\n\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\t\t\t/* process as identifier */\n\t\t\t\ttoken->keyword = KEYWORD_NONE;\n\t\t\t}\n\t\t\telse if (isKeyword (saved_token, KEYWORD_static) &&\n\t\t\t\t\t isType (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\t/* static initialization block */\n\t\t\t\tdeleteToken (saved_token);\n\t\t\t\tparseBlock (token, class_index);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (isKeyword (saved_token, KEYWORD_get))\n\t\t\t\tis_getter = true;\n\t\t\telse if (isKeyword (saved_token, KEYWORD_set))\n\t\t\t\tis_setter = true;\n\t\t\telse if (isKeyword (saved_token, KEYWORD_async) ||\n\t\t\t\t\t isKeyword (saved_token, KEYWORD_static))\n\t\t\t{\n\t\t\t\tif (isKeyword (saved_token, KEYWORD_static))\n\t\t\t\t\tis_static = true;\n\n\t\t\t\t/* can be a qualifier for another \"keyword\", so start over */\n\t\t\t\tdeleteToken (saved_token);\n\t\t\t\tgoto start;\n\t\t\t}\n\n\t\t\tdeleteToken (saved_token);\n\t\t}\n\t\telse if (isType (token, TOKEN_DOTS))\n\t\t{\n\t\t\t/* maybe spread operator. Just skip the next expression. */\n\t\t\tfindCmdTerm(token, true, true);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (! isType (token, TOKEN_KEYWORD) &&\n\t\t\t ! isType (token, TOKEN_SEMICOLON))\n\t\t{\n\t\t\tbool is_generator = false;\n\t\t\tbool is_private = false;\n\t\t\tbool is_shorthand = false; /* ES6 shorthand syntax */\n\t\t\tbool is_computed_name = false; /* ES6 computed property name */\n\t\t\tbool is_dynamic_prop = false;\n\t\t\tvString *dprop = NULL; /* is_computed_name is true but\n\t\t\t\t\t\t\t\t\t* the name is not represented in\n\t\t\t\t\t\t\t\t\t* a string literal. The expressions\n\t\t\t\t\t\t\t\t\t* go this string. */\n\n\t\t\tif (isType (token, TOKEN_STAR)) /* shorthand generator */\n\t\t\t{\n\t\t\t\tis_generator = true;\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_HASH))\n\t\t\t{\n\t\t\t\tis_private = true;\n\t\t\t\treadToken (token);\n\t\t\t}\n\n\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t{\n\t\t\t\tis_computed_name = true;\n\t\t\t\tdprop = vStringNewInit (\"[\");\n\t\t\t\treadTokenFull (token, false, dprop);\n\t\t\t}\n\n\t\t\tcopyToken(name, token, true);\n\t\t\tindex_for_name = CORK_NIL;\n\t\t\tif (is_computed_name && ! isType (token, TOKEN_STRING))\n\t\t\t\tis_dynamic_prop = true;\n\n\t\t\treadTokenFull (token, false, dprop);\n\n\t\t\tif (is_computed_name)\n\t\t\t{\n\t\t\t\tint depth = 1;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tif (isType (token, TOKEN_CLOSE_SQUARE))\n\t\t\t\t\t\tdepth--;\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tis_dynamic_prop = true;\n\t\t\t\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t\t\tdepth++;\n\t\t\t\t\t}\n\t\t\t\t\treadTokenFull (token, false, (is_dynamic_prop && depth != 0)? dprop: NULL);\n\t\t\t\t} while (! isType (token, TOKEN_EOF) && depth > 0);\n\t\t\t}\n\n\t\t\tif (is_dynamic_prop)\n\t\t\t{\n\t\t\t\tinjectDynamicName (name, dprop);\n\t\t\t\tindex_for_name = CORK_NIL;\n\t\t\t\tdprop = NULL;\n\t\t\t}\n\t\t\telse\n\t\t\t\tvStringDelete (dprop);\n\n\t\t\tis_shorthand = isType (token, TOKEN_OPEN_PAREN);\n\t\t\tbool can_be_field = isType (token, TOKEN_EQUAL_SIGN);\n\t\t\t/* is_comma is for handling\n\t\t\t *\n\t\t\t *     { ..., name, ... }\n\t\t\t *\n\t\t\t * . This is shorthand of\n\t\t\t *\n\t\t\t *     { ... ,name: name, ... }\n\t\t\t *\n\t\t\t * .\n\t\t\t * In this case, the token variables point to:\n\t\t\t *\n\t\t\t *     { ..., name, ... }\n\t\t\t * name-------^   ^\n\t\t\t * token----------+\n\t\t\t *\n\t\t\t */\n\t\t\tbool is_comma = ((!is_es6_class && isType (token, TOKEN_CLOSE_CURLY)) || isType (token, TOKEN_COMMA));\n\t\t\tif ( isType (token, TOKEN_COLON) || is_comma || can_be_field || is_shorthand )\n\t\t\t{\n\t\t\t\ttokenInfo * comma = NULL;\n\t\t\t\tif (! is_shorthand)\n\t\t\t\t{\n\t\t\t\t\tif (is_comma)\n\t\t\t\t\t{\n\t\t\t\t\t\tcomma = newToken ();\n\t\t\t\t\t\tcopyToken (comma, token, true);\n\t\t\t\t\t\tcopyToken (token, name, true);\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t *     { ..., name, ... }\n\t\t\t\t\t\t * token -----^   ^\n\t\t\t\t\t\t * comma ---------+\n\t\t\t\t\t\t */\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tif (isKeyword (token, KEYWORD_async))\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvString * signature = vStringNew ();\n\t\t\t\tif ( is_shorthand || isKeyword (token, KEYWORD_function) )\n\t\t\t\t{\n\t\t\t\t\tTRACE_PRINT(\"Seems to be a function or shorthand\");\n\n\t\t\t\t\tif (! is_shorthand)\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tif (isType (token, TOKEN_STAR))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* generator: 'function' '*' '(' ... ')' '{' ... '}' */\n\t\t\t\t\t\t\tis_generator = true;\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( isType (token, TOKEN_OPEN_PAREN) )\n\t\t\t\t\t{\n\t\t\t\t\t\tskipParameterList(token, false, signature);\n\t\t\t\t\t}\n\nfunction:\n\t\t\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t\t\t{\n\t\t\t\t\t\thas_methods = true;\n\n\t\t\t\t\t\tint kind = JSTAG_METHOD;\n\t\t\t\t\t\tif (is_generator)\n\t\t\t\t\t\t\tkind = JSTAG_GENERATOR;\n\t\t\t\t\t\telse if (is_getter)\n\t\t\t\t\t\t\tkind = JSTAG_GETTER;\n\t\t\t\t\t\telse if (is_setter)\n\t\t\t\t\t\t\tkind = JSTAG_SETTER;\n\n\t\t\t\t\t\tindex_for_name = makeJsTagMaybePrivate (name, kind, signature, NULL, is_static, is_private);\n\t\t\t\t\t\tparseBlock (token, index_for_name);\n\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * If we aren't parsing an ES6 class (for which there\n\t\t\t\t\t\t * is no mandatory separators), read to the closing\n\t\t\t\t\t\t * curly, check next token, if a comma, we must loop\n\t\t\t\t\t\t * again.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (! is_es6_class)\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (! is_es6_class)\n\t\t\t\t{\n\t\t\t\t\tint p = CORK_NIL;\n\t\t\t\t\ttokenInfo *saved_token = newToken ();\n\n\t\t\t\t\t/* skip whatever is the value */\n\t\t\t\t\twhile (! isType (token, TOKEN_COMMA) &&\n\t\t\t\t\t\t   ! isType (token, TOKEN_CLOSE_CURLY) &&\n\t\t\t\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* Recurse to find child properties/methods */\n\t\t\t\t\t\t\tp = makeSimplePlaceholder (name->string);\n\t\t\t\t\t\t\tparseMethods (token, p, false);\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvStringClear (signature);\n\t\t\t\t\t\t\tskipParameterList (token, false, signature);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tskipArrayList (token, false);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (isType (token, TOKEN_ARROW))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTRACE_PRINT(\"Seems to be an anonymous function\");\n\t\t\t\t\t\t\tif (vStringIsEmpty (signature) &&\n\t\t\t\t\t\t\t\tisType (saved_token, TOKEN_IDENTIFIER))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvStringPut (signature, '(');\n\t\t\t\t\t\t\t\tvStringCat (signature, saved_token->string);\n\t\t\t\t\t\t\t\tvStringPut (signature, ')');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t\tdeleteToken (saved_token);\n\t\t\t\t\t\t\tgoto function;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcopyToken (saved_token, token, true);\n\t\t\t\t\t\t\tif (comma)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcopyToken(token, comma, true);\n\t\t\t\t\t\t\t\tdeleteToken (comma);\n\t\t\t\t\t\t\t\tcomma = NULL;\n\t\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t\t *     { ..., name, ... }\n\t\t\t\t\t\t\t\t *                ^\n\t\t\t\t\t\t\t\t * token ---------+\n\t\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdeleteToken (saved_token);\n\n\t\t\t\t\thas_methods = true;\n\t\t\t\t\t/* property names can be empty strings such as { \"\": true },\n\t\t\t\t\t * use a special function for generating tags for those */\n\t\t\t\t\tif (name->string->length == 0)\n\t\t\t\t\t\tindex_for_name =  makeJsNullTag (name, JSTAG_PROPERTY, NULL, NULL);\n\t\t\t\t\telse\n\t\t\t\t\t\tindex_for_name = makeJsTag (name, JSTAG_PROPERTY, NULL, NULL);\n\t\t\t\t\tif (p != CORK_NIL)\n\t\t\t\t\t\tmoveChildren (p, index_for_name);\n\t\t\t\t}\n\t\t\t\telse if (can_be_field)\n\t\t\t\t{\n\t\t\t\t\tmakeJsTag (name, JSTAG_FIELD, NULL, NULL);\n\t\t\t\t\tparseLine (token, true);\n\t\t\t\t}\n\n\t\t\t\tvStringDelete (signature);\n\t\t\t\tif (comma)\n\t\t\t\t\tdeleteToken (comma);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbool is_property = isType (token, TOKEN_COMMA);\n\t\t\t\tmakeJsTagMaybePrivate (name, is_property ? JSTAG_PROPERTY : JSTAG_FIELD, NULL, NULL, is_static, is_private);\n\t\t\t\tif (!isType (token, TOKEN_SEMICOLON) && !is_property)\n\t\t\t\t\tdont_read = true;\n\t\t\t}\n\t\t}\n\t} while ( isType(token, TOKEN_COMMA) ||\n\t\t\t  ( is_es6_class && ! isType(token, TOKEN_EOF) ) );\n\n\tTRACE_PRINT(\"Finished parsing methods\");\n\n\tfindCmdTerm (token, false, false);\n\ncleanUp:\n\ttoken->scope = save_scope;\n\tdeleteToken (name);\n\n\tTRACE_LEAVE_TEXT(\"found method(s): %s\", has_methods? \"yes\": \"no\");\n\treturn has_methods;\n}\n\nstatic bool parseES6Class (tokenInfo *const token, const tokenInfo *target_name)\n{\n\tTRACE_ENTER();\n\n\ttokenInfo * class_name = newToken ();\n\tvString *inheritance = NULL;\n\tbool is_anonymous = true;\n\n\tcopyToken (class_name, token, true);\n\treadToken (class_name);\n\n\t/* optional name */\n\tif (isType (class_name, TOKEN_IDENTIFIER))\n\t{\n\t\treadToken (token);\n\t\tis_anonymous = false;\n\t}\n\telse\n\t{\n\t\tcopyToken (token, class_name, true);\n\t\t/* We create a fake name so we have a scope for the members */\n\t\tif (! target_name)\n\t\t\tanonGenerate (class_name->string, \"AnonymousClass\", JSTAG_CLASS);\n\t}\n\n\tif (! target_name)\n\t\ttarget_name = class_name;\n\n\tif (isKeyword (token, KEYWORD_extends))\n\t\tinheritance = vStringNew ();\n\n\t/* skip inheritance info */\n\twhile (! isType (token, TOKEN_OPEN_CURLY) &&\n\t\t   ! isType (token, TOKEN_EOF) &&\n\t\t   ! isType (token, TOKEN_SEMICOLON))\n\t\treadTokenFull (token, false, inheritance);\n\n\t/* remove the last added token (here we assume it's one char, \"{\" or \";\" */\n\tif (inheritance && vStringLength (inheritance) > 0 &&\n\t\t! isType (token, TOKEN_EOF))\n\t{\n\t\tvStringChop (inheritance);\n\t\tvStringStripTrailing (inheritance);\n\t\tvStringStripLeading (inheritance);\n\t}\n\n\tTRACE_PRINT(\"Emitting tag for class '%s'\", vStringValue(target_name->string));\n\n\tint r = makeJsTagCommon (target_name, JSTAG_CLASS, NULL, inheritance,\n\t\t\t\t\t\t\t (is_anonymous && (target_name == class_name)), false, false, false);\n\n\tif (! is_anonymous && target_name != class_name)\n\t{\n\t\t/* FIXME: what to do with the secondary name?  It's local to the\n\t\t *        class itself, so not very useful... let's hope people\n\t\t *        don't give it another name than the target in case of\n\t\t *          var MyClass = class MyClassSecondaryName { ... }\n\t\t *        I guess it could be an alias to MyClass, or duplicate it\n\t\t *        altogether, not sure. */\n\t\tmakeJsTag (class_name, JSTAG_CLASS, NULL, inheritance);\n\t}\n\n\tif (inheritance)\n\t\tvStringDelete (inheritance);\n\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\tparseMethods (token, r, true);\n\n\tdeleteToken (class_name);\n\n\tTRACE_LEAVE();\n\treturn true;\n}\n\nstatic void convertToFunction (int index, const char *signature)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue(index);\n\tif (e && e->kindIndex != JSTAG_FUNCTION\n\t\t&& ( signature == NULL || e->extensionFields.signature == NULL))\n\t{\n\t\te->kindIndex = JSTAG_FUNCTION;\n\t\tif (signature)\n\t\t\te->extensionFields.signature = eStrdup (signature);\n\t}\n}\n\nstatic vString *trimGarbageInSignature (vString *sig)\n{\n\t/* Drop \"=>\" at the end. */\n\tconst char *sigstr = vStringValue (sig);\n\tchar *last = strrchr (sigstr, ')');\n\tAssert (last);\n\tvStringTruncate (sig, last - sigstr + 1);\n\treturn sig;\n}\n\nstatic vString *makeVStringForSignature (tokenInfo *const token)\n{\n\tvString * sig = vStringNewInit (\"(\");\n\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t\tvStringCat (sig, token->string);\n\telse if (isType (token, TOKEN_CLOSE_PAREN))\n\t\tvStringPut (sig, ')');\n\telse if (isType (token, TOKEN_DOTS))\n\t\tvStringCatS (sig, \"...\");\n\n\treturn sig;\n}\n\ntypedef struct sStatementState {\n\tint  indexForName;\n\tbool isClass;\n\tbool isConst;\n\tbool isTerminated;\n\tbool isGlobal;\n\tbool foundThis;\n} statementState;\n\nstatic void deleteTokenFn(void *token) { deleteToken(token); }\n\nstatic bool parsePrototype (tokenInfo *const name, tokenInfo *const token, statementState *const state)\n{\n\tTRACE_ENTER();\n\n\t/*\n\t * When we reach the \"prototype\" tag, we infer:\n\t *     \"BindAgent\" is a class\n\t *     \"build\"     is a method\n\t *\n\t * function BindAgent( repeatableIdName, newParentIdName ) {\n\t * }\n\t *\n\t * CASE 1\n\t * Specified function name: \"build\"\n\t *     BindAgent.prototype.build =\n\t *     BondAgent.prototype.crush = function( mode ) {\n\t *         maybe parse nested functions\n\t *     }\n\t *\n\t * CASE 2\n\t * Prototype listing\n\t *     ValidClassOne.prototype = {\n\t *         'validMethodOne' : function(a,b) {},\n\t *         'validMethodTwo' : function(a,b) {}\n\t *     }\n\t *\n\t */\n\tif (! ( isType (name, TOKEN_IDENTIFIER)\n\t\t|| isType (name, TOKEN_STRING) ) )\n\t\t/*\n\t\t * Unexpected input. Try to reset the parsing.\n\t\t *\n\t\t * TOKEN_STRING is acceptable. e.g.:\n\t\t * -----------------------------------\n\t\t * \"a\".prototype = function( mode ) {}\n\t\t */\n\t{\n\t\tTRACE_LEAVE_TEXT(\"bad input\");\n\t\treturn false;\n\t}\n\n\tstate->indexForName = makeClassTag (name, NULL, NULL);\n\tstate->isClass = true;\n\n\t/*\n\t * There should a \".function_name\" next.\n\t */\n\treadToken (token);\n\tif (isType (token, TOKEN_PERIOD))\n\t{\n\t\t/*\n\t\t * Handle CASE 1\n\t\t */\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_KEYWORD) && canBePropertyName (token))\n\t\t{\n\t\t\t// treat as function name\n\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\ttoken->keyword = KEYWORD_NONE;\n\t\t}\n\n\t\tif (! isType(token, TOKEN_KEYWORD))\n\t\t{\n\t\t\tvString *const signature = vStringNew ();\n\n\t\t\ttoken->scope = state->indexForName;\n\n\t\t\ttokenInfo *identifier_token = newToken ();\n\t\t\tptrArray *prototype_tokens = NULL;\n\t\t\taccept_period_in_identifier(true);\n\n\t\t\ttokenInfo *const method_body_token = newToken ();\n\t\t\tcopyToken (method_body_token, token, true);\n\t\t\treadToken (method_body_token);\n\n\t\t\twhile (! isType (method_body_token, TOKEN_SEMICOLON) &&\n\t\t\t\t   ! isType (method_body_token, TOKEN_CLOSE_CURLY) &&\n\t\t\t\t   ! isType (method_body_token, TOKEN_OPEN_CURLY) &&\n\t\t\t\t   ! isType (method_body_token, TOKEN_EOF))\n\t\t\t{\n\t\t\t\tif ( isType (method_body_token, TOKEN_OPEN_PAREN) )\n\t\t\t\t{\n\t\t\t\t\tif (vStringIsEmpty (signature))\n\t\t\t\t\t\tskipParameterList(method_body_token, false, signature);\n\t\t\t\t\telse\n\t\t\t\t\t\tskipArgumentList(method_body_token, false);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tchar* s1 = vStringValue (identifier_token->string);\n\t\t\t\t\tchar* s2 = NULL;\n\t\t\t\t\tif ( isType (method_body_token, TOKEN_EQUAL_SIGN) &&\n\t\t\t\t\t\t! isType (identifier_token, TOKEN_UNDEFINED) &&\n\t\t\t\t\t\t(s2 = strstr (s1, \".prototype.\")))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (prototype_tokens == NULL)\n\t\t\t\t\t\t\tprototype_tokens = ptrArrayNew (deleteTokenFn);\n\n\t\t\t\t\t\tmemmove (s2, s2+10, strlen (s2+10) + 1);\n\t\t\t\t\t\tvStringSetLength (identifier_token->string);\n\n\t\t\t\t\t\ttokenInfo *const save_token = newToken ();\n\t\t\t\t\t\tcopyToken (save_token, identifier_token, true);\n\t\t\t\t\t\tptrArrayAdd (prototype_tokens, save_token);\n\t\t\t\t\t\tidentifier_token->type = TOKEN_UNDEFINED;\n\t\t\t\t\t}\n\t\t\t\t\telse if ( isType(method_body_token, TOKEN_IDENTIFIER))\n\t\t\t\t\t\tcopyToken (identifier_token, method_body_token, false);\n\n\t\t\t\t\treadToken (method_body_token);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeleteToken (identifier_token);\n\t\t\taccept_period_in_identifier(false);\n\n\t\t\tint index = makeJsTag (token, JSTAG_METHOD, signature, NULL);\n\n\t\t\tif (prototype_tokens != NULL)\n\t\t\t{\n\t\t\t\tfor (int i=0; i<ptrArrayCount (prototype_tokens); i++)\n\t\t\t\t{\n\t\t\t\t\tmakeJsTag (ptrArrayItem (prototype_tokens, i), JSTAG_METHOD, signature, NULL);\n\t\t\t\t}\n\t\t\t\tptrArrayUnref (prototype_tokens);\n\t\t\t}\n\n\t\t\tvStringDelete (signature);\n\n\t\t\tif ( isType (method_body_token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\tparseBlock (method_body_token, index);\n\t\t\t\tstate->isTerminated = true;\n\t\t\t}\n\t\t\telse\n\t\t\t\tstate->isTerminated = isType (method_body_token, TOKEN_SEMICOLON);\n\n\t\t\tdeleteToken (method_body_token);\n\t\t\tTRACE_LEAVE_TEXT(\"done: single\");\n\t\t\treturn false;\n\t\t}\n\t}\n\telse if (isType (token, TOKEN_EQUAL_SIGN))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\t/*\n\t\t\t * Handle CASE 2\n\t\t\t *\n\t\t\t * Creates tags for each of these class methods\n\t\t\t *     ValidClassOne.prototype = {\n\t\t\t *         'validMethodOne' : function(a,b) {},\n\t\t\t *         'validMethodTwo' : function(a,b) {}\n\t\t\t *     }\n\t\t\t */\n\t\t\tparseMethods(token, state->indexForName, false);\n\t\t\t/*\n\t\t\t * Find to the end of the statement\n\t\t\t */\n\t\t\tfindCmdTerm (token, false, false);\n\t\t\tstate->isTerminated = true;\n\t\t\tTRACE_LEAVE_TEXT(\"done: multiple\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tTRACE_LEAVE_TEXT(\"done: not found\");\n\treturn true;\n}\n\nstatic bool parseStatementLHS (tokenInfo *const name, tokenInfo *const token, statementState *const state)\n{\n\tTRACE_ENTER();\n\n\tdo\n\t{\n\t\treadToken (token);\n\t\tif (! isType(token, TOKEN_KEYWORD))\n\t\t{\n\t\t\tif ( state->isClass )\n\t\t\t\ttoken->scope = state->indexForName;\n\t\t\telse\n\t\t\t{\n\t\t\t\taddContext (name, token);\n\t\t\t\tstate->indexForName = CORK_NIL;\n\t\t\t}\n\n\t\t\treadToken (token);\n\t\t}\n\t\telse if ( isKeyword(token, KEYWORD_prototype) )\n\t\t{\n\t\t\tif (! parsePrototype (name, token, state) )\n\t\t\t{\n\t\t\t\tTRACE_LEAVE_TEXT(\"done: prototype\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\treadToken (token);\n\t} while (isType (token, TOKEN_PERIOD));\n\n\tTRACE_LEAVE();\n\treturn true;\n}\n\nstatic bool parseStatementRHS (tokenInfo *const name, tokenInfo *const token, statementState *const state, bool is_inside_class)\n{\n\tTRACE_ENTER();\n\n\tint paren_depth = 0;\n\tint arrowfun_paren_depth = 0;\n\tbool canbe_arrowfun = false;\n\n\treadToken (token);\n\n\t/* rvalue might be surrounded with parentheses */\n\twhile (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tparen_depth++;\n\t\tarrowfun_paren_depth++;\n\t\treadToken (token);\n\t}\n\n\tif (isKeyword (token, KEYWORD_async))\n\t{\n\t\tarrowfun_paren_depth = 0;\n\t\treadToken (token);\n\n\t\t/* check for function signature */\n\t\twhile (isType (token, TOKEN_OPEN_PAREN))\n\t\t{\n\t\t\tparen_depth++;\n\t\t\tarrowfun_paren_depth++;\n\t\t\treadToken (token);\n\t\t}\n\t}\n\n\tif ( isKeyword (token, KEYWORD_function) )\n\t{\n\t\tstate->indexForName = parseFunction (token, name, is_inside_class);\n\t}\n\telse if (isKeyword (token, KEYWORD_class))\n\t{\n\t\tstate->isTerminated = parseES6Class (token, name);\n\t}\n\telse if (isType (token, TOKEN_OPEN_CURLY))\n\t{\n\t\t/*\n\t\t * Creates tags for each of these class methods\n\t\t *     objectOne = {\n\t\t *         'validMethodOne' : function(a,b) {},\n\t\t *         'validMethodTwo' : function(a,b) {}\n\t\t *     }\n\t\t * Or checks if this is a hash variable.\n\t\t *     var z = {};\n\t\t */\n\t\tbool anon_object = vStringIsEmpty (name->string);\n\t\tif (anon_object)\n\t\t{\n\t\t\tanonGenerate (name->string, \"anonymousObject\", JSTAG_VARIABLE);\n\t\t\tstate->indexForName = CORK_NIL;\n\t\t}\n\t\tint p = makeSimplePlaceholder (name->string);\n\t\tif ( parseMethods(token, p, false) )\n\t\t{\n\t\t\tjsKind kind = state->foundThis || strchr (vStringValue(name->string), '.') != NULL ? JSTAG_PROPERTY : JSTAG_VARIABLE;\n\t\t\tstate->indexForName = makeJsTagCommon (name, kind, NULL, NULL, anon_object, false, false, false);\n\t\t\tmoveChildren (p, state->indexForName);\n\t\t}\n\t\telse if ( token->nestLevel == 0 && state->isGlobal )\n\t\t{\n\t\t\t/*\n\t\t\t * Only create variables for global scope\n\t\t\t *\n\t\t\t * A pointer can be created to the function.\n\t\t\t * If we recognize the function/class name ignore the variable.\n\t\t\t * This format looks identical to a variable definition.\n\t\t\t * A variable defined outside of a block is considered\n\t\t\t * a global variable:\n\t\t\t *     var g_var1 = 1;\n\t\t\t *     var g_var2;\n\t\t\t * This is not a global variable:\n\t\t\t *     var g_var = function;\n\t\t\t * This is a global variable:\n\t\t\t *     var g_var = different_var_name;\n\t\t\t */\n\t\t\tstate->indexForName = anyKindsEntryInScope (name->scope, vStringValue (name->string),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (int[]){JSTAG_VARIABLE, JSTAG_FUNCTION, JSTAG_CLASS}, 3, true);\n\n\t\t\tif (state->indexForName == CORK_NIL)\n\t\t\t\tstate->indexForName = makeJsTag (name, state->isConst ? JSTAG_CONSTANT : JSTAG_VARIABLE, NULL, NULL);\n\t\t}\n\t\t/* Here we should be at the end of the block, on the close curly.\n\t\t * If so, read the next token not to confuse that close curly with\n\t\t * the end of the current statement. */\n\t\tif (isType (token, TOKEN_CLOSE_CURLY))\n\t\t{\n\t\t\treadTokenFull(token, true, NULL);\n\t\t\tstate->isTerminated = isType (token, TOKEN_SEMICOLON);\n\t\t}\n\t}\n\telse if (isType (token, TOKEN_OPEN_SQUARE) && !vStringIsEmpty (name->string))\n\t{\n\t\t/*\n\t\t * Creates tag for an array\n\t\t */\n\t\tskipArrayList(token, true);\n\t\tjsKind kind = state->foundThis || strchr (vStringValue(name->string), '.') != NULL ? JSTAG_PROPERTY : JSTAG_VARIABLE;\n\t\t/*\n\t\t * Only create variables for global scope or class/object properties\n\t\t */\n\t\tif ( ( token->nestLevel == 0 && state->isGlobal ) || kind == JSTAG_PROPERTY )\n\t\t{\n\t\t\tstate->indexForName = makeJsTagCommon (name, kind, NULL, NULL, false, false, false, false);\n\t\t}\n\t}\n\telse if (isKeyword (token, KEYWORD_new))\n\t{\n\t\treadToken (token);\n\t\tbool is_var = isType (token, TOKEN_IDENTIFIER) || isKeyword (token, KEYWORD_capital_object);\n\t\tif ( isKeyword (token, KEYWORD_function) ||\n\t\t\t isKeyword (token, KEYWORD_capital_function) ||\n\t\t\t is_var )\n\t\t{\n\t\t\tif ( isKeyword (token, KEYWORD_capital_function) && isClassName (name) )\n\t\t\t\tstate->isClass = true;\n\n\t\t\tif ( isType (token, TOKEN_IDENTIFIER) )\n\t\t\t\tskipQualifiedIdentifier (token);\n\t\t\telse\n\t\t\t\treadToken (token);\n\n\t\t\tif ( isType (token, TOKEN_OPEN_PAREN) )\n\t\t\t\tskipArgumentList(token, true);\n\n\t\t\tif (isType (token, TOKEN_SEMICOLON) && token->nestLevel == 0)\n\t\t\t{\n\t\t\t\tif ( is_var )\n\t\t\t\t\tstate->indexForName = makeJsTag (name, state->isConst ? JSTAG_CONSTANT : state->foundThis ? JSTAG_PROPERTY : JSTAG_VARIABLE, NULL, NULL);\n\t\t\t\telse if ( state->isClass )\n\t\t\t\t\tstate->indexForName = makeClassTag (name, NULL, NULL);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* FIXME: we cannot really get a meaningful\n\t\t\t\t\t * signature from a `new Function()` call,\n\t\t\t\t\t * so for now just don't set any */\n\t\t\t\t\tstate->indexForName = makeFunctionTag (name, NULL, false);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_CLOSE_CURLY))\n\t\t\t\tstate->isTerminated = false;\n\t\t}\n\t}\n\telse if (! isType (token, TOKEN_KEYWORD) &&\n\t\t\t token->nestLevel == 0 && state->isGlobal )\n\t{\n\t\t/*\n\t\t * Only create variables for global scope\n\t\t *\n\t\t * A pointer can be created to the function.\n\t\t * If we recognize the function/class name ignore the variable.\n\t\t * This format looks identical to a variable definition.\n\t\t * A variable defined outside of a block is considered\n\t\t * a global variable:\n\t\t *     var g_var1 = 1;\n\t\t *     var g_var2;\n\t\t * This is not a global variable:\n\t\t *     var g_var = function;\n\t\t * This is a global variable:\n\t\t *     var g_var = different_var_name;\n\t\t */\n\t\tstate->indexForName = anyKindsEntryInScope (name->scope, vStringValue (name->string),\n\t\t\t\t\t\t\t\t\t\t\t\t\t (int[]){JSTAG_VARIABLE, JSTAG_FUNCTION, JSTAG_CLASS}, 3, true);\n\n\t\tif (state->indexForName == CORK_NIL)\n\t\t{\n\t\t\tif (!vStringIsEmpty (name->string))\n\t\t\t\tstate->indexForName = makeJsTag (name, state->isConst ? JSTAG_CONSTANT : JSTAG_VARIABLE, NULL, NULL);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\tcanbe_arrowfun = true;\n\t\t}\n\t}\n\telse if ( isType (token, TOKEN_IDENTIFIER) )\n\t{\n\t\tcanbe_arrowfun = true;\n\t}\n\n\tif (arrowfun_paren_depth == 0 && canbe_arrowfun)\n\t{\n\t\t/* var v = a => { ... } */\n\t\tvString *sig = vStringNewInit (\"(\");\n\t\tvStringCat (sig, token->string);\n\t\tvStringPut (sig, ')');\n\t\treadTokenFull (token, true, NULL);\n\t\tif (isType (token, TOKEN_ARROW))\n\t\t{\n\t\t\tif (state->indexForName == CORK_NIL)\t// was not a global variable\n\t\t\t\tstate->indexForName = makeFunctionTag (name, sig, false);\n\t\t\telse\n\t\t\t\tconvertToFunction (state->indexForName, vStringValue (sig));\n\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t\tparseBlock (token, state->indexForName);\n\t\t\telse if (! isType (token, TOKEN_SEMICOLON))\n\t\t\t\tstate->isTerminated = false;\n\t\t}\n\t\tvStringDelete (sig);\n\t}\n\n\tif (paren_depth > 0)\n\t{\n\t\t/* Collect parameters for arrow function. */\n\t\tvString *sig = (arrowfun_paren_depth == 1)? makeVStringForSignature (token): NULL;\n\n\t\twhile (paren_depth > 0 && ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t{\n\t\t\t\tparen_depth++;\n\t\t\t\tarrowfun_paren_depth++;\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_CLOSE_PAREN))\n\t\t\t{\n\t\t\t\tparen_depth--;\n\t\t\t\tarrowfun_paren_depth--;\n\t\t\t}\n\t\t\treadTokenFull (token, true, sig);\n\n\t\t\t/* var f = (a, b) => { ... } */\n\t\t\tif (arrowfun_paren_depth == 0 && isType (token, TOKEN_ARROW) && sig)\n\t\t\t{\n\t\t\t\tif (state->indexForName == CORK_NIL)\t// was not a global variable\n\t\t\t\t\tstate->indexForName = makeFunctionTag (name, trimGarbageInSignature (sig), false);\n\t\t\t\telse\n\t\t\t\t\tconvertToFunction (state->indexForName,\n\t\t\t\t\t\t\t\t\t   vStringValue (trimGarbageInSignature (sig)));\n\n\t\t\t\tvStringDelete (sig);\n\t\t\t\tsig = NULL;\n\t\t\t\treadToken (token);\n\t\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t\t{\n\t\t\t\t\tparseBlock (token, state->indexForName);\n\t\t\t\t\t/* here we're at the close curly but it's part of the arrow\n\t\t\t\t\t * function body, so skip over not to confuse further code */\n\t\t\t\t\treadTokenFull(token, true, NULL);\n\t\t\t\t\tstate->isTerminated = isType (token, TOKEN_SEMICOLON);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isType (token, TOKEN_CLOSE_CURLY))\n\t\t\tstate->isTerminated = false;\n\n\t\tvStringDelete (sig); /* NULL is acceptable. */\n\t}\n\n\tTRACE_LEAVE();\n\treturn true;\n}\n\nstatic bool parseObjectDestructuring (tokenInfo *const token, bool is_const);\nstatic bool parseArrayDestructuring (tokenInfo *const token, bool is_const)\n{\n\tint nest_level = 1;\n\tbool in_left_side = true;\n\tbool found = false;\n\n\twhile (nest_level > 0 && ! isType (token, TOKEN_EOF))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t{\n\t\t\tin_left_side = true;\n\t\t\tnest_level++;\n\t\t}\n\t\telse if (isType (token, TOKEN_CLOSE_SQUARE))\n\t\t{\n\t\t\tin_left_side = false;\n\t\t\tnest_level--;\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tin_left_side = false;\n\t\t\tif (parseObjectDestructuring (token, is_const))\n\t\t\t\tfound = true;\n\t\t}\n\t\telse if (isType (token, TOKEN_COMMA)\n\t\t\t || isType (token, TOKEN_DOTS))\n\t\t\tin_left_side = true;\n\t\telse if (in_left_side && isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tin_left_side = false;\n\t\t\tmakeJsTag (token,\n\t\t\t\t   is_const ? JSTAG_CONSTANT : JSTAG_VARIABLE,\n\t\t\t\t   NULL, NULL);\n\t\t\tfound = true;\n\t\t}\n\t\telse if (isType (token, TOKEN_EQUAL_SIGN))\n\t\t{\n\t\t\tin_left_side = false;\n\t\t\t/* TODO: SKIP */\n\t\t}\n\t\telse\n\t\t\tin_left_side = false;\n\t}\n\n\treturn found;\n}\n\nstatic bool parseObjectDestructuring (tokenInfo *const token, bool is_const)\n{\n\ttokenInfo *const name = newToken ();\n\tbool found = false;\n\n\t/*\n\t * let { k0: v0, k1: v1 = 0, v3 };\n\t *     |   |  ||   |  |    |    |\n\t *     ^...|..|^...|..|....^....|.: start\n\t *     ....^..|....^..|.........|.: colon\n\t *     .......^.......^.........|.: tagged (made a tag for an id after colon)\n\t *     .........................^.: BREAK\n\t */\n\tenum objDestructuringState {\n\t\tOBJ_DESTRUCTURING_START,\n\t\tOBJ_DESTRUCTURING_COLON,\n\t\tOBJ_DESTRUCTURING_TAGGED,\n\t} state = OBJ_DESTRUCTURING_START;\n\n\twhile (! isType (token, TOKEN_EOF))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tif (parseObjectDestructuring (token, is_const))\n\t\t\t\tfound = true;\n\t\t\tif (state == OBJ_DESTRUCTURING_COLON)\n\t\t\t\tstate = OBJ_DESTRUCTURING_TAGGED;\n\t\t}\n\t\telse if (isType (token, TOKEN_CLOSE_CURLY))\n\t\t{\n\t\t\tif (!vStringIsEmpty(name->string))\n\t\t\t{\n\t\t\t\tmakeJsTag (name,\n\t\t\t\t\t   is_const ? JSTAG_CONSTANT : JSTAG_VARIABLE,\n\t\t\t\t\t   NULL, NULL);\n\t\t\t\tfound = true;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_SQUARE))\n\t\t{\n\t\t\tif (state == OBJ_DESTRUCTURING_START)\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t *       @   >     @   >\n\t\t\t\t * let { [k0]: v0, [k1]: v1 = 0, v3 };\n\t\t\t\t *     ^.....|...^.....|.......^.....: start\n\t\t\t\t *           ^.........^.............: colon\n\t\t\t\t *\n\t\t\t\t * We are at '@' in this context.\n\t\t\t\t * Let's skip to '>'.\n\t\t\t\t */\n\t\t\t\tskipArrayList(token, true);\n\t\t\t\tif (isType (token, TOKEN_COLON))\n\t\t\t\t{\n\t\t\t\t\tvStringClear (name->string);\n\t\t\t\t\tstate = OBJ_DESTRUCTURING_COLON;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (parseArrayDestructuring (token, is_const))\n\t\t\t\t\tfound = true;\n\t\t\t\tif (state == OBJ_DESTRUCTURING_COLON)\n\t\t\t\t\tstate = OBJ_DESTRUCTURING_TAGGED;\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tif (state == OBJ_DESTRUCTURING_COLON)\n\t\t\t{\n\t\t\t\tmakeJsTag (token,\n\t\t\t\t\t   is_const ? JSTAG_CONSTANT : JSTAG_VARIABLE,\n\t\t\t\t\t   NULL, NULL);\n\t\t\t\tfound = true;\n\t\t\t\tstate = OBJ_DESTRUCTURING_TAGGED;\n\t\t\t}\n\t\t\telse if (state == OBJ_DESTRUCTURING_START\n\t\t\t\t && vStringIsEmpty(name->string))\n\t\t\t\tcopyToken(name, token, true);\n\t\t}\n\t\telse if (isType (token, TOKEN_COMMA))\n\t\t{\n\t\t\tif (!vStringIsEmpty(name->string))\n\t\t\t{\n\t\t\t\tmakeJsTag (name,\n\t\t\t\t\t   is_const ? JSTAG_CONSTANT : JSTAG_VARIABLE,\n\t\t\t\t\t   NULL, NULL);\n\t\t\t\tfound = true;\n\t\t\t\tvStringClear (name->string);\n\t\t\t}\n\t\t\tstate = OBJ_DESTRUCTURING_START;\n\t\t}\n\t\telse if (isType (token, TOKEN_COLON))\n\t\t{\n\t\t\tvStringClear (name->string);\n\t\t\tstate = OBJ_DESTRUCTURING_COLON;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (state == OBJ_DESTRUCTURING_COLON)\n\t\t\t\tstate = OBJ_DESTRUCTURING_TAGGED;\n\t\t}\n\t}\n\n\tdeleteToken (name);\n\treturn found;\n}\n\nstatic bool parseStatement (tokenInfo *const token, bool is_inside_class)\n{\n\tTRACE_ENTER_TEXT(\"is_inside_class: %s\", is_inside_class? \"yes\": \"no\");\n\n\t/*\n\t * When making a tag for `name', its core index is stored to\n\t * `indexForName'. The value stored to `indexForName' is valid\n\t * till the value for `name' is updated. If the value for `name'\n\t * is changed, `indexForName' is reset to CORK_NIL.\n\t */\n\ttokenInfo *const name = newToken ();\n\tint save_scope = token->scope;\n\tbool found_lhs = false;\n\tstatementState state = {\n\t\t.indexForName = CORK_NIL,\n\t\t.isClass = is_inside_class,\n\t\t.isConst = false,\n\t\t.isTerminated = true,\n\t\t.isGlobal = false,\n\t\t.foundThis = false\n\t};\n\n\t/*\n\t * Functions can be named or unnamed.\n\t * This deals with these formats:\n\t * Function\n\t *     validFunctionOne = function(a,b) {}\n\t *     testlib.validFunctionFive = function(a,b) {}\n\t *     var innerThree = function(a,b) {}\n\t *     var innerFour = (a,b) {}\n\t *     var D2 = secondary_fcn_name(a,b) {}\n\t *     var D3 = new Function(\"a\", \"b\", \"return a+b;\");\n\t * Class\n\t *     testlib.extras.ValidClassOne = function(a,b) {\n\t *         this.a = a;\n\t *     }\n\t * Class Methods\n\t *     testlib.extras.ValidClassOne.prototype = {\n\t *         'validMethodOne' : function(a,b) {},\n\t *         'validMethodTwo' : function(a,b) {}\n\t *     }\n\t *     ValidClassTwo = function ()\n\t *     {\n\t *         this.validMethodThree = function() {}\n\t *         // unnamed method\n\t *         this.validMethodFour = () {}\n\t *     }\n\t *     Database.prototype.validMethodThree = Database_getTodaysDate;\n\t */\n\n\t/*\n\t * var can precede an inner function\n\t */\n\tif ( isKeyword(token, KEYWORD_var) ||\n\t\t isKeyword(token, KEYWORD_let) ||\n\t\t isKeyword(token, KEYWORD_const) )\n\t{\n\t\tTRACE_PRINT(\"var/let/const case\");\n\t\tstate.isConst = isKeyword(token, KEYWORD_const);\n\t\t/*\n\t\t * Only create variables for global scope\n\t\t */\n\t\tif ( token->nestLevel == 0 )\n\t\t{\n\t\t\tstate.isGlobal = true;\n\t\t}\n\t\treadToken(token);\n\n\t\tif (state.isGlobal)\n\t\t{\n\t\t\tbool found = false;\n\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t\tfound = parseObjectDestructuring (token, state.isConst);\n\t\t\telse if (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\tfound = parseArrayDestructuring (token, state.isConst);\n\n\t\t\tif (found)\n\t\t\t{\n\t\t\t\t/* Adjust the context to the code for non-destructing. */\n\t\t\t\tfound_lhs = true;\n\t\t\t\treadToken(token);\n\t\t\t}\n\t\t}\n\t}\n\nnextVar:\n\tstate.indexForName = CORK_NIL;\n\tstate.foundThis = false;\n\tif ( isKeyword(token, KEYWORD_this) )\n\t{\n\t\tTRACE_PRINT(\"found 'this' keyword\");\n\t\tstate.foundThis = true;\n\n\t\treadToken(token);\n\t\tif (isType (token, TOKEN_PERIOD))\n\t\t{\n\t\t\treadToken(token);\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_SQUARE))\n\t\t{\n\t\t\tskipArrayList (token, false);\n\t\t}\n\t}\n\n\tcopyToken(name, token, true);\n\tTRACE_PRINT(\"name becomes '%s' of type %s\",\n\t\t\t\tvStringValue(token->string), tokenTypeName (token->type));\n\n\twhile (! isType (token, TOKEN_CLOSE_CURLY) &&\n\t\t   ! isType (token, TOKEN_SEMICOLON)   &&\n\t\t   ! isType (token, TOKEN_EQUAL_SIGN)  &&\n\t\t   ! isType (token, TOKEN_COMMA)       &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\tfound_lhs = true;\n\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tparseBlock (token, CORK_NIL);\n\t\t\treadTokenFull (token, true, NULL);\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_function))\n\t\t{\n\t\t\tparseFunction (token, NULL, false);\n\t\t\treadTokenFull (token, true, NULL);\n\t\t}\n\n\t\t/* Potentially the name of the function */\n\t\telse if (isType (token, TOKEN_PERIOD))\n\t\t{\n\t\t\t/*\n\t\t\t * Cannot be a global variable is it has dot references in the name\n\t\t\t */\n\t\t\tstate.isGlobal = false;\n\t\t\t/* Assume it's an assignment to a global name (e.g. a class) using\n\t\t\t * its fully qualified name, so strip the scope.\n\t\t\t * FIXME: resolve the scope so we can make more than an assumption. */\n\t\t\ttoken->scope = CORK_NIL;\n\t\t\tname->scope = CORK_NIL;\n\t\t\tif ( ! parseStatementLHS (name, token, &state) )\n\t\t\t\tgoto cleanUp;\n\t\t}\n\t\telse\n\t\t\treadTokenFull (token, true, NULL);\n\n\t\tif ( isType (token, TOKEN_OPEN_PAREN) )\n\t\t\tskipArgumentList(token, false);\n\n\t\tif ( isType (token, TOKEN_OPEN_SQUARE) )\n\t\t\tskipArrayList(token, false);\n\t}\n\n\tif ( isType (token, TOKEN_CLOSE_CURLY) )\n\t{\n\t\t/*\n\t\t * Reaching this section without having\n\t\t * processed an open curly brace indicates\n\t\t * the statement is most likely not terminated.\n\t\t */\n\t\tstate.isTerminated = false;\n\t}\n\telse if ( isType (token, TOKEN_SEMICOLON) ||\n\t\t\t  isType (token, TOKEN_EOF) ||\n\t\t\t  isType (token, TOKEN_COMMA) )\n\t{\n\t\t/*\n\t\t * Only create variables for global scope\n\t\t */\n\t\tif ( token->nestLevel == 0 && state.isGlobal )\n\t\t{\n\t\t\t/*\n\t\t\t * Handles this syntax:\n\t\t\t *     var g_var2;\n\t\t\t */\n\t\t\tif (!vStringIsEmpty (name->string))\n\t\t\t\tstate.indexForName = makeJsTag (name, state.isConst ? JSTAG_CONSTANT : JSTAG_VARIABLE, NULL, NULL);\n\t\t}\n\t\t/*\n\t\t * Statement has ended.\n\t\t * This deals with calls to functions, like:\n\t\t *     alert(..);\n\t\t */\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tstate.isClass = false;\n\t\t\tgoto nextVar;\n\t\t}\n\t}\n\telse\n\t{\n\t\tbool ok = found_lhs;\n\t\tif ( ok && isType (token, TOKEN_EQUAL_SIGN) )\n\t\t{\n\t\t\tok = parseStatementRHS (name, token, &state, is_inside_class);\n\t\t}\n\t\t/* if we aren't already at the cmd end, advance to it and check whether\n\t\t * the statement was terminated */\n\t\tif (ok &&\n\t\t\t! isType (token, TOKEN_CLOSE_CURLY) &&\n\t\t\t! isType (token, TOKEN_SEMICOLON))\n\t\t{\n\t\t\t/*\n\t\t\t * Statements can be optionally terminated in the case of\n\t\t\t * statement prior to a close curly brace as in the\n\t\t\t * document.write line below:\n\t\t\t *\n\t\t\t * function checkForUpdate() {\n\t\t\t *     if( 1==1 ) {\n\t\t\t *         document.write(\"hello from checkForUpdate<br>\")\n\t\t\t *     }\n\t\t\t *     return 1;\n\t\t\t * }\n\t\t\t */\n\t\t\tstate.isTerminated = findCmdTerm (token, true, true);\n\t\t\t/* if we're at a comma, try and read a second var */\n\t\t\tif (isType (token, TOKEN_COMMA))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tstate.isClass = false;\n\t\t\t\tgoto nextVar;\n\t\t\t}\n\t\t}\n\t\telse if (ok && isType (token, TOKEN_SEMICOLON))\n\t\t\tstate.isTerminated = true;\n\t}\n\ncleanUp:\n\ttoken->scope = save_scope;\n\tdeleteToken (name);\n\n\tTRACE_LEAVE_TEXT(\"is terminated: %d\", (int) state.isTerminated);\n\treturn state.isTerminated;\n}\n\nstatic void parseUI5 (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\t/*\n\t * SAPUI5 is built on top of jQuery.\n\t * It follows a standard format:\n\t *     sap.ui.controller(\"id.of.controller\", {\n\t *         method_name : function... {\n\t *         },\n\t *\n\t *         method_name : function ... {\n\t *         }\n\t *     }\n\t *\n\t * Handle the parsing of the initial controller (and the\n\t * same for \"view\") and then allow the methods to be\n\t * parsed as usual.\n\t */\n\n\treadToken (token);\n\n\tif (isType (token, TOKEN_PERIOD))\n\t{\n\t\tint r = CORK_NIL;\n\n\t\treadToken (token);\n\t\twhile (! isType (token, TOKEN_OPEN_PAREN) &&\n\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t}\n\t\treadToken (token);\n\n\t\tif (isType (token, TOKEN_STRING))\n\t\t{\n\t\t\tcopyToken(name, token, true);\n\t\t\treadToken (token);\n\t\t}\n\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t\treadToken (token);\n\n\t\tif (isType(name, TOKEN_STRING))\n\t\t{\n\t\t\t/*\n\t\t\t * `name' can include '.'.\n\t\t\t * Setting dynamicProp to true can prohibit\n\t\t\t * that makeClassTag ispects the inside\n\t\t\t * of `name'.\n\t\t\t */\n\t\t\tname->dynamicProp = true;\n\t\t\tr = makeClassTag (name, NULL, NULL);\n\t\t\t/*\n\t\t\t * TODO\n\t\t\t * `name' specifies a class of OpenUI5.\n\t\t\t * So tagging it as a language object of\n\t\t\t * JavaScript is incorrect. We have to introduce\n\t\t\t * OpenUI5 language as a subparser of JavaScript\n\t\t\t * to fix this situation.\n\t\t\t */\n\t\t}\n\n\t\tdo\n\t\t{\n\t\t\tparseMethods (token, r, false);\n\t\t} while (! isType (token, TOKEN_CLOSE_CURLY) &&\n\t\t\t\t ! isType (token, TOKEN_EOF));\n\t}\n\n\tdeleteToken (name);\n}\n\nstatic bool parseLine (tokenInfo *const token, bool is_inside_class)\n{\n\tTRACE_ENTER_TEXT(\"token is '%s' of type %s\",\n\t\t\t\t\t vStringValue(token->string), tokenTypeName (token->type));\n\n\tbool is_terminated = true;\n\t/*\n\t * Detect the common statements, if, while, for, do, ...\n\t * This is necessary since the last statement within a block \"{}\"\n\t * can be optionally terminated.\n\t *\n\t * If the statement is not terminated, we need to tell\n\t * the calling routine to prevent reading an additional token\n\t * looking for the end of the statement.\n\t */\n\n\tif (isType(token, TOKEN_KEYWORD))\n\t{\n\t\tswitch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_for:\n\t\t\tcase KEYWORD_while:\n\t\t\tcase KEYWORD_do:\n\t\t\t\tis_terminated = parseLoop (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_if:\n\t\t\tcase KEYWORD_else:\n\t\t\tcase KEYWORD_try:\n\t\t\tcase KEYWORD_catch:\n\t\t\tcase KEYWORD_finally:\n\t\t\t\t/* Common semantics */\n\t\t\t\tis_terminated = parseIf (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_switch:\n\t\t\t\tparseSwitch (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_return:\n\t\t\tcase KEYWORD_async:\n\t\t\t\treadToken (token);\n\t\t\t\tis_terminated = parseLine (token, is_inside_class);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_function:\n\t\t\t\tparseFunction (token, NULL, false);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_class:\n\t\t\t\tis_terminated = parseES6Class (token, NULL);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tis_terminated = parseStatement (token, is_inside_class);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\telse\n\t{\n\t\t/*\n\t\t * Special case where single line statements may not be\n\t\t * SEMICOLON terminated.  parseBlock needs to know this\n\t\t * so that it does not read the next token.\n\t\t */\n\t\tis_terminated = parseStatement (token, is_inside_class);\n\t}\n\n\tTRACE_LEAVE();\n\treturn is_terminated;\n}\n\nstatic void parseJsFile (tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tdo\n\t{\n\t\treadToken (token);\n\n\t\tif (isType (token, TOKEN_KEYWORD) && token->keyword == KEYWORD_sap)\n\t\t\tparseUI5 (token);\n\t\telse if (isType (token, TOKEN_KEYWORD) && (token->keyword == KEYWORD_export ||\n\t\t\t\t\t\t\t\t\t\t\t\t   token->keyword == KEYWORD_default))\n\t\t\t/* skip those at top-level */;\n\t\telse\n\t\t\tparseLine (token, false);\n\t} while (! isType (token, TOKEN_EOF));\n\n\tTRACE_LEAVE();\n}\n\n#ifdef DO_TRACING\n#ifdef DO_TRACING_USE_DUMP_TOKEN\nstatic void dumpToken (const tokenInfo *const token)\n{\n\tconst char *scope_str = getNameStringForCorkIndex (token->scope);\n\tconst char *scope_kind_str = getKindStringForCorkIndex (token->scope);\n\n\tif (strcmp(scope_str, \"placeholder\") == 0)\n\t{\n\t\tTRACE_PRINT(\"%s: '%s'\",\n\t\t\ttokenTypeName (token->type),\n\t\t\tvStringValue (token->string));\n\t}\n\telse\n\t{\n\t\tTRACE_PRINT(\"%s: '%s' (scope '%s' of kind '%s')\",\n\t\t\ttokenTypeName (token->type),\n\t\t\tvStringValue (token->string),\n\t\t\tscope_str, scope_kind_str);\n\t}\n}\n#endif\n\nstatic const char*\ngetNameStringForCorkIndex(int index)\n{\n\tif (index == CORK_NIL)\n\t\treturn \"none\";\n\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\tif (e == NULL)\n\t\treturn \"ghost\";\t\t\t/* Can this happen? */\n\n\tif (e->placeholder)\n\t\treturn \"placeholder\";\n\n\treturn e->name;\n}\n\nstatic const char*\ngetKindStringForCorkIndex(int index)\n{\n\tif (index == CORK_NIL)\n\t\treturn \"none\";\n\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\tif (e == NULL)\n\t\treturn \"ghost\";\t\t\t/* Can this happen? */\n\n\tif (e->placeholder)\n\t\treturn \"placeholder\";\n\n\tif (e->kindIndex == KIND_GHOST_INDEX)\n\t\treturn \"ghost\";\n\n\treturn JsKinds [e->kindIndex].name;\n}\n\nstatic const char *kindName(jsKind kind)\n{\n\treturn ((int)kind) >= 0 ? JsKinds[kind].name : \"none\";\n}\n\nstatic const char *tokenTypeName(enum eTokenType e)\n{ /* Generated by misc/enumstr.sh with cmdline:\n\t parsers/jscript.c eTokenType tokenTypeName */\n\tswitch (e)\n\t{\n\t\tcase      TOKEN_UNDEFINED: return \"TOKEN_UNDEFINED\";\n\t\tcase            TOKEN_EOF: return \"TOKEN_EOF\";\n\t\tcase      TOKEN_CHARACTER: return \"TOKEN_CHARACTER\";\n\t\tcase    TOKEN_CLOSE_PAREN: return \"TOKEN_CLOSE_PAREN\";\n\t\tcase      TOKEN_SEMICOLON: return \"TOKEN_SEMICOLON\";\n\t\tcase          TOKEN_COLON: return \"TOKEN_COLON\";\n\t\tcase          TOKEN_COMMA: return \"TOKEN_COMMA\";\n\t\tcase        TOKEN_KEYWORD: return \"TOKEN_KEYWORD\";\n\t\tcase     TOKEN_OPEN_PAREN: return \"TOKEN_OPEN_PAREN\";\n\t\tcase     TOKEN_IDENTIFIER: return \"TOKEN_IDENTIFIER\";\n\t\tcase         TOKEN_STRING: return \"TOKEN_STRING\";\n\t\tcase TOKEN_TEMPLATE_STRING: return \"TOKEN_TEMPLATE_STRING\";\n\t\tcase         TOKEN_PERIOD: return \"TOKEN_PERIOD\";\n\t\tcase     TOKEN_OPEN_CURLY: return \"TOKEN_OPEN_CURLY\";\n\t\tcase    TOKEN_CLOSE_CURLY: return \"TOKEN_CLOSE_CURLY\";\n\t\tcase     TOKEN_EQUAL_SIGN: return \"TOKEN_EQUAL_SIGN\";\n\t\tcase    TOKEN_OPEN_SQUARE: return \"TOKEN_OPEN_SQUARE\";\n\t\tcase   TOKEN_CLOSE_SQUARE: return \"TOKEN_CLOSE_SQUARE\";\n\t\tcase         TOKEN_REGEXP: return \"TOKEN_REGEXP\";\n\t\tcase TOKEN_POSTFIX_OPERATOR: return \"TOKEN_POSTFIX_OPERATOR\";\n\t\tcase           TOKEN_STAR: return \"TOKEN_STAR\";\n\t\tcase         TOKEN_ATMARK: return \"TOKEN_ATMARK\";\n\t\tcase TOKEN_BINARY_OPERATOR: return \"TOKEN_BINARY_OPERATOR\";\n\t\tcase          TOKEN_ARROW: return \"TOKEN_ARROW\";\n\t\tcase           TOKEN_DOTS: return \"TOKEN_DOTS\";\n\t\tdefault:                   return \"UNKNOWN\";\n\t}\n}\n#endif\n\nstatic void initialize (const langType language)\n{\n\tAssert (ARRAY_SIZE (JsKinds) == JSTAG_COUNT);\n\tLang_js = language;\n\n\tTokenPool = objPoolNew (16, newPoolToken, deletePoolToken, clearPoolToken, NULL);\n}\n\nstatic void finalize (langType language CTAGS_ATTR_UNUSED, bool initialized)\n{\n\tif (!initialized)\n\t\treturn;\n\n\tobjPoolDelete (TokenPool);\n}\n\nstatic void findJsTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\tNextToken = NULL;\n\tLastTokenType = TOKEN_UNDEFINED;\n\n\tparseJsFile (token);\n\n\tdeleteToken (token);\n\n#ifdef HAVE_ICONV\n\tif (JSUnicodeConverter != (iconv_t) -2 && /* not created */\n\t\tJSUnicodeConverter != (iconv_t) -1 /* creation failed */)\n\t{\n\t\ticonv_close (JSUnicodeConverter);\n\t\tJSUnicodeConverter = (iconv_t) -2;\n\t}\n#endif\n\n\tAssert (NextToken == NULL);\n}\n\n/* Create parser definition structure */\nextern parserDefinition* JavaScriptParser (void)\n{\n\t// .jsx files are JSX: https://facebook.github.io/jsx/\n\t// which have JS function definitions, so we just use the JS parser\n\tstatic const char *const extensions [] = { \"js\", \"jsx\", \"mjs\", NULL };\n\tstatic const char *const aliases [] = { \"js\", \"node\", \"nodejs\",\n\t\t\t\t\t\t\t\t\t\t\t\"seed\", \"gjs\",\n\t\t\t\t\t\t\t\t\t\t\t/* Used in PostgreSQL\n\t\t\t\t\t\t\t\t\t\t\t * https://github.com/plv8/plv8 */\n\t\t\t\t\t\t\t\t\t\t\t\"v8\",\n\t\t\t\t\t\t\t\t\t\t\tNULL };\n\n\t/* Fore initialize HTML parser to handle JSX elements. */\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_FOREIGNER, \"HTML\", NULL },\n\t};\n\n\tparserDefinition *const def = parserNew (\"JavaScript\");\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\t/*\n\t * New definitions for parsing instead of regex\n\t */\n\tdef->kindTable\t= JsKinds;\n\tdef->kindCount\t= ARRAY_SIZE (JsKinds);\n\tdef->fieldTable = JsFields;\n\tdef->fieldCount = ARRAY_SIZE (JsFields);\n\tdef->parser\t\t= findJsTags;\n\tdef->initialize = initialize;\n\tdef->finalize   = finalize;\n\tdef->keywordTable = JsKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (JsKeywordTable);\n\tdef->useCork\t= CORK_QUEUE|CORK_SYMTAB;\n\tdef->requestAutomaticFQTag = true;\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->versionCurrent = 2;\n\tdef->versionAge = 2;\n\n\treturn def;\n}\n\nextern void javaScriptSkipObjectExpression (void)\n{\n\tpushLanguage (Lang_js);\n\n\tint c = getcFromInputFile ();\n\tif (c == '{')\n\t{\n\t\ttokenInfo *originalNexToken = NextToken;\n\t\ttokenType originalLastTokenType = LastTokenType;\n#ifdef HAVE_ICONV\n\t\ticonv_t originalJSUnicodeConverter = JSUnicodeConverter;\n#endif\n\n\t\tint depth = 1;\n\t\ttokenInfo *const token = newToken ();\n\n\t\tNextToken = NULL;\n\t\tLastTokenType = TOKEN_UNDEFINED;\n\n\t\tdo\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t\tdepth++;\n\t\t\telse if (isType (token, TOKEN_CLOSE_CURLY))\n\t\t\t\tdepth--;\n\t\t}\n\t\twhile (! isType (token, TOKEN_EOF) && depth > 0);\n\n\t\tdeleteToken (token);\n\n#ifdef HAVE_ICONV\n\t\tif (\n\t\t\t/* not created */\n\t\t\tJSUnicodeConverter != (iconv_t) -2 &&\n\t\t\t/* creation failed */\n\t\t\tJSUnicodeConverter != (iconv_t) -1 &&\n\t\t\t/* The convert was created before entering this function\n\t\t\t * and no new converter is created in this function (and\n\t\t\t * functions called from this functions). */\n\t\t\tJSUnicodeConverter != originalJSUnicodeConverter\n\t\t\t)\n\t\t\ticonv_close (JSUnicodeConverter);\n\n\t\tJSUnicodeConverter = originalJSUnicodeConverter;\n#endif\n\n\t\tNextToken = originalNexToken;\n\t\tLastTokenType = originalLastTokenType;\n\t}\n\telse if (c != EOF)\n\t\tungetcToInputFile (c);\n\n\tpopLanguage ();\n}\n"
  },
  {
    "path": "parsers/json.c",
    "content": "/*\n * Copyright (c) 2014, Colomban Wendling <colomban@geany.org>\n *\n * This source code is released for free distribution under the terms of the\n * GNU General Public License version 2 or (at your option) any later version.\n */\n/*\n * This module contains functions for generating tags for JSON files.\n *\n * http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf\n *\n * This implementation is forgiving and allows many constructs that are not\n * actually valid but that don't conflict with the format.  This is intend to\n * better support partly broken or unfinished files.\n */\n\n#include \"general.h\"\n\n#include <string.h>\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n#define isIdentChar(c) \\\n\t(isalnum (c) || (c) == '+' || (c) == '-' || (c) == '.')\n\ntypedef enum {\n\tTOKEN_EOF,\n\tTOKEN_UNDEFINED,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_COLON,\n\tTOKEN_COMMA,\n\tTOKEN_TRUE,\n\tTOKEN_FALSE,\n\tTOKEN_NULL,\n\tTOKEN_NUMBER,\n\tTOKEN_STRING\n} tokenType;\n\ntypedef enum {\n\tTAG_NONE = -1,\n\tTAG_OBJECT,\n\tTAG_ARRAY,\n\tTAG_NUMBER,\n\tTAG_STRING,\n\tTAG_BOOLEAN,\n\tTAG_NULL,\n\tTAG_COUNT\n} jsonKind;\n\ntypedef struct {\n\ttokenType\t\ttype;\n\tjsonKind\t\tscopeKind;\n\tvString\t\t\t*string;\n\tvString\t\t\t*scope;\n\tunsigned long\tlineNumber;\n\tMIOPos\t\t\tfilePosition;\n} tokenInfo;\n\ntypedef enum {\n\tKEYWORD_true,\n\tKEYWORD_false,\n\tKEYWORD_null\n} keywordId;\n\nstatic langType Lang_json;\n\nstatic kindDefinition JsonKinds [] = {\n\t{ true,  'o', \"object\",\t\t\"objects\"\t},\n\t{ true,  'a', \"array\",\t\t\"arrays\"\t},\n\t{ true,  'n', \"number\",\t\t\"numbers\"\t},\n\t{ true,  's', \"string\",\t\t\"strings\"\t},\n\t{ true,  'b', \"boolean\",\t\"booleans\"\t},\n\t{ true,  'z', \"null\",\t\t\"nulls\"\t\t}\n};\n\nstatic const keywordTable JsonKeywordTable [] = {\n\t{\"true\",  KEYWORD_true },\n\t{\"false\", KEYWORD_false},\n\t{\"null\", KEYWORD_null },\n};\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->scopeKind\t= TAG_NONE;\n\ttoken->string\t\t= vStringNew ();\n\ttoken->scope\t\t= vStringNew ();\n\ttoken->lineNumber\t= getInputLineNumber ();\n\ttoken->filePosition\t= getInputFilePosition ();\n\n\treturn token;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tvStringDelete (token->string);\n\tvStringDelete (token->scope);\n\teFree (token);\n}\n\nstatic void copyToken (tokenInfo *const dest, tokenInfo *const src)\n{\n\tdest->type = src->type;\n\tdest->scopeKind = src->scopeKind;\n\tvStringCopy (dest->string, src->string);\n\tvStringCopy (dest->scope, src->scope);\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n}\n\nstatic void makeJsonTag (tokenInfo *const token, unsigned long endLine, const jsonKind kind, int nth)\n{\n\ttagEntryInfo e;\n\n\tif (! JsonKinds[kind].enabled)\n\t\treturn;\n\n\tinitTagEntry (&e, vStringValue (token->string), kind);\n\n\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\n\tif (!vStringIsEmpty (token->scope))\n\t{\n\t\tAssert (token->scopeKind > TAG_NONE && token->scopeKind < TAG_COUNT);\n\n\t\te.extensionFields.scopeKindIndex = token->scopeKind;\n\t\te.extensionFields.scopeName = vStringValue (token->scope);\n\n\t\tif (token->scopeKind == TAG_ARRAY)\n\t\t\te.extensionFields.nth = nth;\n\t}\n\n\tsetTagEndLine (&e, endLine);\n\tmakeTagEntry (&e);\n\n\tif (!vStringIsEmpty (token->scope) && isXtagEnabled (XTAG_QUALIFIED_TAGS))\n\t{\n\t\tvString *qname = vStringNewCopy(token->scope);\n\t\tvStringPut(qname, '.');\n\t\tvStringCat(qname, token->string);\n\t\te.name = vStringValue(qname);\n\t\tmarkTagExtraBit(&e, XTAG_QUALIFIED_TAGS);\n\t\tmakeTagEntry (&e);\n\t\tvStringDelete (qname);\n\t}\n}\n\n#define DEPTH_LIMIT 512\nstatic int depth_counter;\n\nstatic void readTokenFull (tokenInfo *const token,\n\t\t\t\t\t\t   bool includeStringRepr)\n{\n\tint c;\n\n\tif (depth_counter > DEPTH_LIMIT)\n\t{\n\t\ttoken->type = TOKEN_EOF;\n\n\t\t/* Not to repeat warnings. */\n\t\tif (depth_counter == (DEPTH_LIMIT + 1))\n\t\t{\n\t\t\tnotice (\"Terminate parsing: too deep brackets recursion in %s at %ld\",\n\t\t\t\t\tgetInputFileName(), getInputLineNumber());\n\t\t\tdepth_counter++;\n\t\t}\n\t\treturn;\n\t}\n\n\ttoken->type = TOKEN_UNDEFINED;\n\tvStringClear (token->string);\n\n\tdo\n\t\tc = getcFromInputFile ();\n\twhile (c == '\\t' || c == ' ' || c == '\\r' || c == '\\n');\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tswitch (c)\n\t{\n\t\tcase EOF: token->type = TOKEN_EOF;\t\t\tbreak;\n\t\tcase '[':\n\t\t\tdepth_counter++;\n\t\t\ttoken->type = TOKEN_OPEN_SQUARE;\t\tbreak;\n\t\tcase ']':\n\t\t\tdepth_counter--;\n\t\t\ttoken->type = TOKEN_CLOSE_SQUARE;\t\tbreak;\n\t\tcase '{':\n\t\t\tdepth_counter++;\n\t\t\ttoken->type = TOKEN_OPEN_CURLY;\t\t\tbreak;\n\t\tcase '}':\n\t\t\tdepth_counter--;\n\t\t\ttoken->type = TOKEN_CLOSE_CURLY;\t\tbreak;\n\t\tcase ':': token->type = TOKEN_COLON;\t\tbreak;\n\t\tcase ',': token->type = TOKEN_COMMA;\t\tbreak;\n\n\t\tcase '\"':\n\t\t{\n\t\t\tbool escaped = false;\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t/* we don't handle unicode escapes but they are safe */\n\t\t\t\tif (escaped)\n\t\t\t\t\tescaped = false;\n\t\t\t\telse if (c == '\\\\')\n\t\t\t\t\tescaped = true;\n\t\t\t\telse if (c >= 0x00 && c <= 0x1F)\n\t\t\t\t\tbreak; /* break on invalid, unescaped, control characters */\n\t\t\t\telse if (c == '\"' || c == EOF)\n\t\t\t\t\tbreak;\n\t\t\t\tif (includeStringRepr)\n\t\t\t\t\tvStringPut (token->string, c);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tif (! isIdentChar (c))\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\telse\n\t\t\t{\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tvStringPut (token->string, c);\n\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t}\n\t\t\t\twhile (c != EOF && isIdentChar (c));\n\t\t\t\tungetcToInputFile (c);\n\t\t\t\tswitch (lookupKeyword (vStringValue (token->string), Lang_json))\n\t\t\t\t{\n\t\t\t\t\tcase KEYWORD_true:\ttoken->type = TOKEN_TRUE;\tbreak;\n\t\t\t\t\tcase KEYWORD_false:\ttoken->type = TOKEN_FALSE;\tbreak;\n\t\t\t\t\tcase KEYWORD_null:\ttoken->type = TOKEN_NULL;\tbreak;\n\t\t\t\t\tdefault:\t\t\ttoken->type = TOKEN_NUMBER;\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n\n#define readToken(t) (readTokenFull ((t), false))\n\nstatic void pushScope (tokenInfo *const token,\n\t\t\t\t\t   const tokenInfo *const parent,\n\t\t\t\t\t   const jsonKind parentKind)\n{\n\tvStringJoin(token->scope, '.', parent->string);\n\ttoken->scopeKind = parentKind;\n}\n\nstatic void popScope (tokenInfo *const token,\n\t\t\t\t\t  const tokenInfo *const parent)\n{\n\tvStringTruncate (token->scope, vStringLength (parent->scope));\n\ttoken->scopeKind = parent->scopeKind;\n}\n\n#define skipToOneOf2(token, type1, type2) \\\n\t(skipToOneOf3 (token, type1, type2, TOKEN_EOF /* dummy */))\n\n#define skipTo(token, type) \\\n\t(skipToOneOf3 (token, type, /* dummies */ TOKEN_EOF, TOKEN_EOF))\n\nstatic void skipToOneOf3 (tokenInfo *const token,\n\t\t\t\t\t\t  const tokenType type1,\n\t\t\t\t\t\t  const tokenType type2,\n\t\t\t\t\t\t  const tokenType type3)\n{\n\twhile (token->type != TOKEN_EOF &&\n\t\t   token->type != type1 &&\n\t\t   token->type != type2 &&\n\t\t   token->type != type3)\n\t{\n\t\treadToken (token);\n\t\tif (token->type == TOKEN_OPEN_CURLY)\n\t\t{\n\t\t\tskipTo (token, TOKEN_CLOSE_CURLY);\n\t\t\treadToken (token);\n\t\t}\n\t\telse if (token->type == TOKEN_OPEN_SQUARE)\n\t\t{\n\t\t\tskipTo (token, TOKEN_CLOSE_SQUARE);\n\t\t\treadToken (token);\n\t\t}\n\t}\n}\n\nstatic jsonKind tokenToKind (const tokenType type)\n{\n\tswitch (type)\n\t{\n\t\tcase TOKEN_OPEN_CURLY:\treturn TAG_OBJECT;\n\t\tcase TOKEN_OPEN_SQUARE:\treturn TAG_ARRAY;\n\t\tcase TOKEN_STRING:\t\treturn TAG_STRING;\n\t\tcase TOKEN_TRUE:\n\t\tcase TOKEN_FALSE:\t\treturn TAG_BOOLEAN;\n\t\tcase TOKEN_NUMBER:\t\treturn TAG_NUMBER;\n\t\tdefault:\t\t\t\treturn TAG_NULL;\n\t}\n}\n\nstatic unsigned long parseValue (tokenInfo *const token)\n{\n\tunsigned long lastLine = token->lineNumber;\n\n\tif (token->type == TOKEN_OPEN_CURLY)\n\t{\n\t\ttokenInfo *name = newToken ();\n\n\t\tdo\n\t\t{\n\t\t\treadTokenFull (token, true);\n\t\t\tif (token->type == TOKEN_STRING)\n\t\t\t{\n\t\t\t\tjsonKind tagKind = TAG_NULL; /* default in case of invalid value */\n\t\t\t\tunsigned long lastLineOfChild;\n\n\t\t\t\tcopyToken (name, token);\n\n\t\t\t\t/* skip any possible garbage before the value */\n\t\t\t\tskipToOneOf3 (token, TOKEN_CLOSE_CURLY, TOKEN_COLON, TOKEN_COMMA);\n\n\t\t\t\tlastLineOfChild = token->lineNumber;\n\t\t\t\tif (token->type == TOKEN_COLON)\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\ttagKind = tokenToKind (token->type);\n\n\t\t\t\t\tpushScope (token, name, tagKind);\n\t\t\t\t\tlastLineOfChild = parseValue (token);\n\t\t\t\t\tpopScope (token, name);\n\t\t\t\t}\n\n\t\t\t\tmakeJsonTag (name, lastLineOfChild, tagKind, 0);\n\t\t\t}\n\t\t\t/* skip to the end of the construct */\n\t\t\tskipToOneOf2 (token, TOKEN_CLOSE_CURLY, TOKEN_COMMA);\n\t\t}\n\t\twhile (token->type != TOKEN_EOF &&\n\t\t\t   token->type != TOKEN_CLOSE_CURLY);\n\n\t\tlastLine = token->lineNumber;\n\t\tif (token->type == TOKEN_CLOSE_CURLY)\n\t\t\treadToken (token);\n\n\t\tdeleteToken (name);\n\t}\n\telse if (token->type == TOKEN_OPEN_SQUARE)\n\t{\n\t\ttokenInfo *name = newToken ();\n\t\tchar buf[32];\n\t\tunsigned int nth = 0;\n\n\t\treadToken (token);\n\t\twhile (token->type != TOKEN_EOF &&\n\t\t\t   token->type != TOKEN_CLOSE_SQUARE)\n\t\t{\n\t\t\tjsonKind tagKind;\n\t\t\tunsigned long lastLineOfChild;\n\n\t\t\ttagKind = tokenToKind (token->type);\n\n\t\t\tcopyToken (name, token);\n\t\t\tsnprintf (buf, sizeof buf, \"%u\", nth);\n\t\t\tvStringCopyS (name->string, buf);\n\n\t\t\tpushScope (token, name, tagKind);\n\t\t\tlastLineOfChild = parseValue (token);\n\t\t\tpopScope (token, name);\n\n\t\t\tmakeJsonTag (name, lastLineOfChild, tagKind, nth++);\n\n\t\t\t/* skip to the end of the construct */\n\t\t\tskipToOneOf2 (token, TOKEN_CLOSE_SQUARE, TOKEN_COMMA);\n\t\t\tif (token->type != TOKEN_CLOSE_SQUARE)\n\t\t\t\treadToken (token);\n\t\t}\n\n\t\tlastLine = token->lineNumber;\n\t\tif (token->type == TOKEN_CLOSE_SQUARE)\n\t\t\treadToken (token);\n\n\t\tdeleteToken (name);\n\t}\n\n\treturn lastLine;\n}\n\nstatic void findJsonTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\tdepth_counter = 0;\n\n\t/* We allow multiple top-level elements, although it's not actually valid\n\t * JSON.  An interesting side effect of this is that we allow a leading\n\t * Unicode BOM mark -- even though ok, many JSON parsers will choke on it */\n\tdo\n\t{\n\t\treadToken (token);\n\t\tparseValue (token);\n\t}\n\twhile (token->type != TOKEN_EOF);\n\n\tdeleteToken (token);\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_json = language;\n}\n\n/* Create parser definition structure */\nextern parserDefinition* JsonParser (void)\n{\n\tstatic const char *const extensions [] = { \"json\", NULL };\n\tparserDefinition *const def = parserNew (\"JSON\");\n\tdef->extensions = extensions;\n\tdef->kindTable\t= JsonKinds;\n\tdef->kindCount\t= ARRAY_SIZE (JsonKinds);\n\tdef->parser\t\t= findJsonTags;\n\tdef->initialize = initialize;\n\tdef->keywordTable = JsonKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (JsonKeywordTable);\n\tdef->allowNullTag = true;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/julia.c",
    "content": "/*\n*   Copyright (c) 2020-2021, getzze <getzze@gmail.com>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Julia files.\n*\n*   Documented 'kinds':\n*       https://docs.julialang.org/en/v1/manual/documentation/#Syntax-Guide\n*   Language parser in Scheme:\n*       https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"    /* must always come first */\n\n#include <string.h>\n\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"entry.h\"\n#include \"options.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n\n/*\n*   MACROS\n*/\n#define MAX_STRING_LENGTH 256\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n    K_CONSTANT,\n    K_FUNCTION,\n    K_FIELD,\n    K_MACRO,\n    K_MODULE,\n    K_STRUCT,\n    K_TYPE,\n    K_UNKNOWN,\n    K_NONE\n} JuliaKind;\n\ntypedef enum {\n    JULIA_MODULE_IMPORTED,\n    JULIA_MODULE_USED,\n    JULIA_MODULE_NAMESPACE,\n} juliaModuleRole;\n\ntypedef enum {\n    JULIA_UNKNOWN_IMPORTED,\n    JULIA_UNKNOWN_USED,\n} juliaUnknownRole;\n\n/*\n*  using X               X = (kind:module, role:used)\n*\n*  using X: a, b         X = (kind:module, role:namespace)\n*                     a, b = (kind:unknown, role:used, scope:module:X)\n*\n*  import X              X = (kind:module, role:imported)\n*\n*  import X.a, Y.b    X, Y = (kind:module, role:namespace)\n*                     a, b = (kind:unknown, role:imported, scope:module:X)\n*\n*  import X: a, b     Same as the above one\n*/\nstatic roleDefinition JuliaModuleRoles [] = {\n    { true, \"imported\", \"loaded by \\\"import\\\"\" },\n    { true, \"used\", \"loaded by \\\"using\\\"\" },\n    { true, \"namespace\", \"only some symbols in it are imported\" },\n};\n\nstatic roleDefinition JuliaUnknownRoles [] = {\n    { true, \"imported\", \"loaded by \\\"import\\\"\" },\n    { true, \"used\", \"loaded by \\\"using\\\"\"},\n};\n\nstatic kindDefinition JuliaKinds [] = {\n    { true, 'c', \"constant\", \"Constants\"    },\n    { true, 'f', \"function\", \"Functions\"    },\n    { true, 'g', \"field\",    \"Fields\"       },\n    { true, 'm', \"macro\",    \"Macros\"       },\n    { true, 'n', \"module\",   \"Modules\",\n      ATTACH_ROLES(JuliaModuleRoles) },\n    { true, 's', \"struct\",   \"Structures\"   },\n    { true, 't', \"type\",     \"Types\"        },\n    { true, 'Y', \"unknown\", \"name defined in other modules\",\n      .referenceOnly = true, ATTACH_ROLES(JuliaUnknownRoles) },\n};\n\ntypedef enum {\n    TOKEN_NONE=0,         /* none */\n    TOKEN_WHITESPACE,\n    TOKEN_PAREN_BLOCK,\n    TOKEN_BRACKET_BLOCK,\n    TOKEN_CURLY_BLOCK,\n    TOKEN_OPEN_BLOCK,\n    TOKEN_CLOSE_BLOCK,\n    TOKEN_TYPE_ANNOTATION,\n    TOKEN_TYPE_WHERE,\n    TOKEN_CONST,\n    TOKEN_STRING,         /*  = 10 */\n    TOKEN_COMMAND,\n    TOKEN_MACROCALL,\n    TOKEN_IDENTIFIER,\n    TOKEN_MODULE,\n    TOKEN_MACRO,\n    TOKEN_FUNCTION,\n    TOKEN_STRUCT,\n    TOKEN_ENUM,\n    TOKEN_TYPE,\n    TOKEN_IMPORT,         /*  = 20 */\n    TOKEN_USING,\n    TOKEN_EXPORT,\n    TOKEN_NEWLINE,\n    TOKEN_SEMICOLON,\n    TOKEN_COMPOSER_KWD,   /* KEYWORD only */\n    TOKEN_EOF,\n    TOKEN_COUNT\n} tokenType;\n\nstatic const keywordTable JuliaKeywordTable [] = {\n    /* TODO: Sort by keys. */\n    { \"mutable\",   TOKEN_COMPOSER_KWD },\n    { \"primitive\", TOKEN_COMPOSER_KWD },\n    { \"abstract\",  TOKEN_COMPOSER_KWD },\n\n    { \"if\",        TOKEN_OPEN_BLOCK   },\n    { \"for\",       TOKEN_OPEN_BLOCK   },\n    { \"while\",     TOKEN_OPEN_BLOCK   },\n    { \"try\",       TOKEN_OPEN_BLOCK   },\n    { \"do\",        TOKEN_OPEN_BLOCK   },\n    { \"begin\",     TOKEN_OPEN_BLOCK   },\n    { \"let\",       TOKEN_OPEN_BLOCK   },\n    { \"quote\",     TOKEN_OPEN_BLOCK   },\n\n    { \"module\",    TOKEN_MODULE       },\n    { \"baremodule\",TOKEN_MODULE       },\n\n    { \"using\",     TOKEN_USING        },\n    { \"import\",    TOKEN_IMPORT       },\n\n    { \"export\",    TOKEN_EXPORT       },\n    { \"const\",     TOKEN_CONST        },\n    { \"macro\",     TOKEN_MACRO        },\n    { \"function\",  TOKEN_FUNCTION     },\n    { \"struct\",    TOKEN_STRUCT       },\n    { \"type\",      TOKEN_TYPE         },\n    { \"where\",     TOKEN_TYPE_WHERE   },\n    { \"end\",       TOKEN_CLOSE_BLOCK  },\n};\n\ntypedef struct {\n    /* Characters */\n    int prev_c;\n    int cur_c;\n    int next_c;\n\n    /* Tokens */\n    bool first_token;\n    int cur_token;\n    vString* token_str;\n    unsigned long line;\n    MIOPos pos;\n} lexerState;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nstatic void parseExpr (lexerState *lexer, bool delim, int kind, vString *scope);\n\nstatic void scanParenBlock (lexerState *lexer);\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic int endswith(const char* what, const char* withwhat)\n{\n    int l1 = strlen(what);\n    int l2 = strlen(withwhat);\n    if (l2 > l1)\n    {\n        return 0;\n    }\n\n    return strcmp(withwhat, what + (l1 - l2)) == 0;\n}\n\n/* Resets the scope string to the old length */\nstatic void resetScope (vString *scope, size_t old_len)\n{\n    vStringTruncate (scope, old_len);\n}\n\n/* Adds a name to the end of the scope string */\nstatic void addToScope (vString *scope, vString *name)\n{\n\tvStringJoin(scope, '.', name);\n}\n\n/* Reads a character from the file */\nstatic void advanceChar (lexerState *lexer)\n{\n    lexer->prev_c = lexer->cur_c;\n    lexer->cur_c  = lexer->next_c;\n    lexer->next_c = getcFromInputFile();\n}\n\n/* Reads N characters from the file */\nstatic void advanceNChar (lexerState *lexer, int n)\n{\n    while (n--)\n    {\n        advanceChar(lexer);\n    }\n}\n\n/* Store the current character in lexerState::token_str if there is space\n * (set by MAX_STRING_LENGTH), and then read the next character from the file */\nstatic void advanceAndStoreChar (lexerState *lexer)\n{\n    if (vStringLength(lexer->token_str) < MAX_STRING_LENGTH)\n    {\n        vStringPut(lexer->token_str, lexer->cur_c);\n    }\n    advanceChar(lexer);\n}\n\nstatic bool isWhitespace (int c, bool newline)\n{\n    if (newline)\n    {\n        return c == ' ' || c == '\\t' || c == '\\r' || c == '\\n';\n    }\n    return c == ' ' || c == '\\t';\n}\n\nstatic bool isAscii (int c)\n{\n    return (c >= 0) && (c < 0x80);\n}\n\nstatic bool isOperator (int c)\n{\n    if (c == '%' || c == '^' || c == '&' || c == '|' ||\n        c == '*' || c == '-' || c == '+' || c == '~' ||\n        c == '<' || c == '>' || c == ',' || c == '/' ||\n        c == '?' || c == '=' || c == ':' )\n    {\n        return true;\n    }\n    return false;\n}\n\n/* This does not distinguish Unicode letters from operators... */\nstatic bool isIdentifierFirstCharacter (int c)\n{\n    return (bool) ((isAscii(c) && (isalpha (c) || c == '_')) || c >= 0xC0);\n}\n\n/* This does not distinguish Unicode letters from operators... */\nstatic bool isIdentifierCharacter (int c)\n{\n    return (bool) (isIdentifierFirstCharacter(c) || (isAscii(c) && (isdigit(c) || c == '!')) || c >= 0x80);\n}\n\nstatic void skipWhitespace (lexerState *lexer, bool newline)\n{\n    while (isWhitespace(lexer->cur_c, newline))\n    {\n        advanceChar(lexer);\n    }\n}\n\n/* The transpose operator is only allowed after an identifier, a number, an expression inside parenthesis or an index */\nstatic bool isTranspose (int c)\n{\n    return (isIdentifierCharacter(c) || c == ')' || c == ']');\n}\n\n\n/*\n *  Lexer functions\n * */\n\n/* Check that the current character sequence is a type declaration or inheritance */\nstatic bool isTypeDecl (lexerState *lexer)\n{\n    if ((lexer->prev_c != '.' && lexer->cur_c == '<' && lexer->next_c == ':') ||\n        (lexer->prev_c != '.' && lexer->cur_c == '>' && lexer->next_c == ':') ||\n        (lexer->cur_c == ':' && lexer->next_c == ':') )\n    {\n        return true;\n    }\n    return false;\n}\n\n/* Check if the current char is a new line */\nstatic bool isNewLine (lexerState *lexer)\n{\n    return (lexer->cur_c == '\\n')? true: false;\n}\n\n/* Check if the current char is a new line.\n * If it is, skip the newline and return true */\nstatic bool skipNewLine (lexerState *lexer)\n{\n    if (isNewLine(lexer))\n    {\n        advanceChar(lexer);\n        return true;\n    }\n    return false;\n}\n\n/* Skip a single comment or multiline comment\n * A single line comment starts with #\n * A multi-line comment is encapsulated in #=...=# and they are nesting\n * */\nstatic void skipComment (lexerState *lexer)\n{\n    /* # */\n    if (lexer->next_c != '=')\n    {\n        advanceNChar(lexer, 1);\n        while (lexer->cur_c != EOF && lexer->cur_c != '\\n')\n        {\n            advanceChar(lexer);\n        }\n    }\n    /* block comment */\n    else /* if (lexer->next_c == '=') */\n    {\n        int level = 1;\n        advanceNChar(lexer, 2);\n        while (lexer->cur_c != EOF && level > 0)\n        {\n            if (lexer->cur_c == '=' && lexer->next_c == '#')\n            {\n                level--;\n                advanceNChar(lexer, 2);\n            }\n            else if (lexer->cur_c == '#' && lexer->next_c == '=')\n            {\n                level++;\n                advanceNChar(lexer, 2);\n            }\n            else\n            {\n                advanceChar(lexer);\n            }\n        }\n    }\n}\n\nstatic void scanIdentifier (lexerState *lexer, bool clear)\n{\n    if (clear)\n    {\n        vStringClear(lexer->token_str);\n    }\n\n    do\n    {\n        advanceAndStoreChar(lexer);\n    } while(lexer->cur_c != EOF && isIdentifierCharacter(lexer->cur_c));\n}\n\n/* Scan a quote-like expression.\n * Allow for triple-character variand and interpolation with `$`.\n * These last past the end of the line, so be careful\n * not to store too much of them (see MAX_STRING_LENGTH). */\nstatic void scanStringOrCommand (lexerState *lexer, int c)\n{\n    bool istriple = false;\n\n    /* Pass the first \"quote\"-character */\n    advanceAndStoreChar(lexer);\n\n    /* Check for triple \"quote\"-character */\n    if (lexer->cur_c == c && lexer->next_c == c)\n    {\n        istriple = true;\n        advanceAndStoreChar(lexer);\n        advanceAndStoreChar(lexer);\n\n        /* Cancel up to 2 \"quote\"-characters after opening the triple */\n        if (lexer->cur_c == c)\n        {\n            advanceAndStoreChar(lexer);\n            if (lexer->cur_c == c)\n            {\n                advanceAndStoreChar(lexer);\n            }\n        }\n    }\n\n    while (lexer->cur_c != EOF && lexer->cur_c != c)\n    {\n        /* Check for interpolation before checking for end of \"quote\" */\n        if (lexer->cur_c == '$' && lexer->next_c == '(')\n        {\n            advanceAndStoreChar(lexer);\n            scanParenBlock(lexer);\n            /* continue to avoid advance character again. Correct bug\n             * with \"quote\"-character just after closing parenthesis */\n            continue;\n        }\n\n        if (lexer->cur_c == '\\\\' &&\n            (lexer->next_c == c || lexer->next_c == '\\\\'))\n        {\n            advanceAndStoreChar(lexer);\n        }\n        advanceAndStoreChar(lexer);\n\n        /* Cancel up to 2 \"quote\"-characters if triple string */\n        if (istriple && lexer->cur_c == c)\n        {\n            advanceAndStoreChar(lexer);\n            if (lexer->cur_c == c)\n            {\n                advanceAndStoreChar(lexer);\n            }\n        }\n    }\n    /* Pass the last \"quote\"-character */\n    advanceAndStoreChar(lexer);\n}\n\n\n/* Scan commands surrounded by backticks,\n * possibly triple backticks */\nstatic void scanCommand (lexerState *lexer)\n{\n    scanStringOrCommand(lexer, '`');\n}\n\n/* Double-quoted strings,\n * possibly triple doublequotes */\nstatic void scanString (lexerState *lexer)\n{\n    scanStringOrCommand(lexer, '\"');\n}\n\n\n/* This deals with character literals: 'n', '\\n', '\\uFFFF';\n * and matrix transpose: A'.\n * We'll use this approximate regexp for the literals:\n * \\' [^'] \\' or \\' \\\\ [^']+ \\' or \\' \\\\ \\' \\'\n * Either way, we'll treat this token as a string, so it gets preserved */\nstatic bool scanCharacterOrTranspose (lexerState *lexer)\n{\n    if (isTranspose(lexer->prev_c))\n    {\n        /* deal with untranspose/transpose sequence */\n        while (lexer->cur_c != EOF && lexer->cur_c == '\\'')\n        {\n            advanceAndStoreChar(lexer);\n        }\n        return false;\n    }\n\n    //vStringClear(lexer->token_str);\n    advanceAndStoreChar(lexer);\n\n    if (lexer->cur_c == '\\\\')\n    {\n        advanceAndStoreChar(lexer);\n        /* The \\' \\\\ \\' \\' (literally '\\'') case */\n        if (lexer->cur_c == '\\'' && lexer->next_c == '\\'')\n        {\n            advanceAndStoreChar(lexer);\n            advanceAndStoreChar(lexer);\n        }\n        /* The \\' \\\\ [^']+ \\' case */\n        else\n        {\n            while (lexer->cur_c != EOF && lexer->cur_c != '\\'')\n            {\n                advanceAndStoreChar(lexer);\n            }\n        }\n    }\n    /* The \\' [^'] \\' and  \\' \\' \\' cases */\n    else if (lexer->next_c == '\\'')\n    {\n        advanceAndStoreChar(lexer);\n        advanceAndStoreChar(lexer);\n    }\n    /* Otherwise it is malformed */\n    return true;\n}\n\n/* Parse a block with opening and closing character */\nstatic void scanBlock (lexerState *lexer, int open, int close, bool convert_newline)\n{\n    /* Assume the current char is `open` */\n    int level = 1;\n\n    /* Pass the first opening */\n    advanceAndStoreChar(lexer);\n\n    while (lexer->cur_c != EOF && level > 0)\n    {\n        /* Parse everything */\n        if (lexer->cur_c == ' ' || lexer->cur_c == '\\t')\n        {\n            skipWhitespace(lexer, false);\n            vStringPut(lexer->token_str, ' ');\n        }\n        if (lexer->cur_c == '#')\n        {\n            skipComment(lexer);\n        }\n        else if (lexer->cur_c == '\\\"')\n        {\n            scanString(lexer);\n        }\n        else if (lexer->cur_c == '\\'')\n        {\n            scanCharacterOrTranspose(lexer);\n        }\n\n        /* Parse opening/closing */\n        if (lexer->cur_c == open)\n        {\n            level++;\n        }\n        else if (lexer->cur_c == close)\n        {\n            level--;\n        }\n\n        if (convert_newline && skipNewLine(lexer))\n        {\n            vStringPut(lexer->token_str, ' ');\n        }\n        else\n        {\n            advanceAndStoreChar(lexer);\n        }\n\n    }\n    /* Lexer position is just after `close` */\n}\n\n\n/* Parse a block inside parenthesis, for example a function argument list */\nstatic void scanParenBlock (lexerState *lexer)\n{\n    scanBlock(lexer, '(', ')', true);\n}\n\n/* Indexing block with bracket.\n * Some keywords have a special meaning in this environment:\n * end, begin, for and if */\nstatic void scanIndexBlock (lexerState *lexer)\n{\n    scanBlock(lexer, '[', ']', false);\n\n}\n\n/* Parse a block inside curly brackets, for type parametrization */\nstatic void scanCurlyBlock (lexerState *lexer)\n{\n    scanBlock(lexer, '{', '}', true);\n}\n\n/* Scan type annotation like\n * `::Type`, `::Type{T}`\n */\nstatic void scanTypeAnnotation (lexerState *lexer)\n{\n    /* assume that current char is '<', '>' or ':', followed by ':' */\n    advanceAndStoreChar(lexer);\n    advanceAndStoreChar(lexer);\n\n    skipWhitespace(lexer, true);\n    scanIdentifier(lexer, false);\n    if (lexer->cur_c == '{')\n    {\n        scanCurlyBlock(lexer);\n    }\n}\n\n/* Scan type annotation like\n * `where Int<:T<:Real`, `where S<:Array{Real}` or `where {S, T}`\n */\nstatic void scanTypeWhere (lexerState *lexer)\n{\n    /* assume that current token is 'where'\n     * allow line continuation */\n    vStringPut(lexer->token_str, ' ');\n    skipWhitespace(lexer, true);\n\n    while (lexer->cur_c != EOF)\n    {\n\n        if (lexer->cur_c == '{')\n        {\n            scanCurlyBlock(lexer);\n        }\n        else if (isIdentifierFirstCharacter(lexer->cur_c))\n        {\n            scanIdentifier(lexer, false);\n            if (endswith(vStringValue(lexer->token_str), \"where\"))\n            {\n                /* allow line continuation */\n                vStringPut(lexer->token_str, ' ');\n                skipWhitespace(lexer, true);\n            }\n        }\n        else if (isTypeDecl(lexer))\n        {\n            scanTypeAnnotation(lexer);\n            //skipWhitespace(lexer, false);\n        }\n        else if (lexer->cur_c == '#')\n        {\n            skipComment(lexer);\n            /* allow line continuation */\n            if (endswith(vStringValue(lexer->token_str), \"where \"))\n            {\n                skipWhitespace(lexer, true);\n            }\n        }\n        else if (isWhitespace(lexer->cur_c, false))\n        {\n            while (isWhitespace(lexer->cur_c, false))\n            {\n                advanceChar(lexer);\n            }\n            /* Add a space, if it is not a trailing space */\n            if (!(isNewLine(lexer)))\n            {\n                vStringPut(lexer->token_str, ' ');\n            }\n        }\n        else\n        {\n            break;\n        }\n    }\n}\n\n\nstatic int parseIdentifier (lexerState *lexer)\n{\n    langType julia = getInputLanguage ();\n    scanIdentifier(lexer, true);\n\n    int k = lookupKeyword (vStringValue(lexer->token_str), julia);\n    /* First part of a composed identifier */\n    if (k == TOKEN_COMPOSER_KWD)\n    {\n        skipWhitespace(lexer, false);\n        scanIdentifier(lexer, true);\n        k = lookupKeyword (vStringValue(lexer->token_str), julia);\n    }\n\n    if ((k == TOKEN_OPEN_BLOCK)\n        || (k == TOKEN_MODULE)\n        || (k == TOKEN_IMPORT)\n        || (k == TOKEN_USING)\n        || (k == TOKEN_EXPORT)\n        || (k == TOKEN_CONST)\n        || (k == TOKEN_MACRO)\n        || (k == TOKEN_FUNCTION)\n        || (k == TOKEN_STRUCT)\n        || (k == TOKEN_TYPE)\n        || (k == TOKEN_TYPE_WHERE)\n        || (k == TOKEN_CLOSE_BLOCK))\n    {\n        if (k == TOKEN_TYPE_WHERE)\n        {\n            scanTypeWhere(lexer);\n        }\n        return lexer->cur_token = k;\n    }\n    return lexer->cur_token = TOKEN_IDENTIFIER;\n}\n\n\n/* Advances the parser one token, optionally skipping whitespace\n * (otherwise it is concatenated and returned as a single whitespace token).\n * Whitespace is needed to properly render function signatures. Unrecognized\n * token starts are stored literally, e.g. token may equal to a character '#'. */\nstatic int advanceToken (lexerState *lexer, bool skip_whitespace, bool propagate_first)\n{\n    bool have_whitespace = false;\n    bool newline = false;\n    lexer->line = getInputLineNumber();\n    lexer->pos = getInputFilePosition();\n\n    /* the next token is the first token of the line */\n    if (!propagate_first)\n    {\n        if (lexer->cur_token == TOKEN_NEWLINE ||\n            lexer->cur_token == TOKEN_SEMICOLON ||\n            lexer->cur_token == TOKEN_NONE ||\n            (lexer->first_token && lexer->cur_token == TOKEN_MACROCALL))\n        {\n            lexer->first_token = true;\n        }\n        else\n        {\n            lexer->first_token = false;\n        }\n    }\n\n    while (lexer->cur_c != EOF)\n    {\n        /* skip whitespaces but not newlines */\n        if (isWhitespace(lexer->cur_c, newline))\n        {\n            skipWhitespace(lexer, newline);\n            have_whitespace = true;\n        }\n        else if (lexer->cur_c == '#')\n        {\n            skipComment(lexer);\n            have_whitespace = true;\n        }\n        else\n        {\n            if (have_whitespace && !skip_whitespace)\n            {\n                return lexer->cur_token = TOKEN_WHITESPACE;\n            }\n            break;\n        }\n    }\n    lexer->line = getInputLineNumber();\n    lexer->pos = getInputFilePosition();\n    while (lexer->cur_c != EOF)\n    {\n        if (lexer->cur_c == '\"')\n        {\n            vStringClear(lexer->token_str);\n            scanString(lexer);\n            return lexer->cur_token = TOKEN_STRING;\n        }\n        else if (lexer->cur_c == '\\'')\n        {\n            vStringClear(lexer->token_str);\n            if (scanCharacterOrTranspose(lexer))\n            {\n                return lexer->cur_token = TOKEN_STRING;\n            }\n            else\n            {\n                return lexer->cur_token = '\\'';\n            }\n        }\n        else if (lexer->cur_c == '`')\n        {\n            vStringClear(lexer->token_str);\n            scanCommand(lexer);\n            return lexer->cur_token = TOKEN_COMMAND;\n        }\n        else if (isIdentifierFirstCharacter(lexer->cur_c))\n        {\n            return parseIdentifier(lexer);\n        }\n        else if (lexer->cur_c == '@')\n        {\n            vStringClear(lexer->token_str);\n            advanceAndStoreChar(lexer);\n            do\n            {\n                advanceAndStoreChar(lexer);\n            } while(lexer->cur_c != EOF && isIdentifierCharacter(lexer->cur_c));\n            return lexer->cur_token = TOKEN_MACROCALL;\n        }\n        else if (lexer->cur_c == '(')\n        {\n            vStringClear(lexer->token_str);\n            scanParenBlock(lexer);\n            return lexer->cur_token = TOKEN_PAREN_BLOCK;\n        }\n        else if (lexer->cur_c == '[')\n        {\n            vStringClear(lexer->token_str);\n            scanIndexBlock(lexer);\n            return lexer->cur_token = TOKEN_BRACKET_BLOCK;\n        }\n        else if (lexer->cur_c == '{')\n        {\n            vStringClear(lexer->token_str);\n            scanCurlyBlock(lexer);\n            return lexer->cur_token = TOKEN_CURLY_BLOCK;\n        }\n        else if (isTypeDecl(lexer))\n        {\n            vStringClear(lexer->token_str);\n            scanTypeAnnotation(lexer);\n            return lexer->cur_token = TOKEN_TYPE_ANNOTATION;\n        }\n        else if (skipNewLine(lexer))\n        {\n            /* allow line continuation */\n            if (isOperator(lexer->cur_token))\n            {\n                return lexer->cur_token;\n            }\n            return lexer->cur_token = TOKEN_NEWLINE;\n        }\n        else if (lexer->cur_c == ';')\n        {\n            advanceChar(lexer);\n            return lexer->cur_token = TOKEN_SEMICOLON;\n        }\n        else\n        {\n            int c = lexer->cur_c;\n            advanceChar(lexer);\n            return lexer->cur_token = c;\n        }\n    }\n    return lexer->cur_token = TOKEN_EOF;\n}\n\nstatic void initLexer (lexerState *lexer)\n{\n    advanceNChar(lexer, 2);\n    lexer->token_str = vStringNew();\n    lexer->first_token = true;\n    lexer->cur_token = TOKEN_NONE;\n    lexer->prev_c = '\\0';\n\n    if (lexer->cur_c == '#' && lexer->next_c == '!')\n    {\n        skipComment(lexer);\n    }\n    advanceToken(lexer, true, false);\n}\n\nstatic void deInitLexer (lexerState *lexer)\n{\n    vStringDelete(lexer->token_str);\n    lexer->token_str = NULL;\n}\n\n#if 0\nstatic void debugLexer (lexerState *lexer)\n{\n    printf(\"Current lexer state: line %d, token (%lu), cur char `%c`, token str:\\n\\t`\", lexer->line, lexer->cur_token, lexer->cur_c);\n    printf(vStringValue(lexer->token_str));\n    printf(\"`\\n\");\n}\n#endif\n\nstatic void addTag (vString* ident, const char* type, const char* arg_list, int kind, unsigned long line, MIOPos pos, vString *scope, int parent_kind)\n{\n    if (kind == K_NONE)\n    {\n        return;\n    }\n    tagEntryInfo tag;\n    initTagEntry(&tag, vStringValue(ident), kind);\n\n    updateTagLine(&tag, line, pos);\n    tag.sourceFileName = getInputFileName();\n\n    tag.extensionFields.signature = arg_list;\n    /* tag.extensionFields.varType = type; */  /* Needs a workaround */\n    if (parent_kind != K_NONE)\n    {\n        tag.extensionFields.scopeKindIndex = parent_kind;\n        tag.extensionFields.scopeName = vStringValue(scope);\n    }\n    makeTagEntry(&tag);\n}\n\nstatic void addReferenceTag (vString* ident, int kind, int role, unsigned long line, MIOPos pos, vString* scope, int parent_kind)\n{\n    if (kind == K_NONE)\n    {\n        return;\n    }\n    tagEntryInfo tag;\n    initRefTagEntry(&tag, vStringValue(ident), kind, role);\n    updateTagLine(&tag, line, pos);\n    if (parent_kind != K_NONE)\n    {\n        tag.extensionFields.scopeKindIndex = parent_kind;\n        tag.extensionFields.scopeName = vStringValue(scope);\n    }\n    makeTagEntry(&tag);\n}\n\n/* Skip tokens until one of the goal tokens is hit. Escapes when level = 0 if there are no goal tokens.\n * Keeps track of balanced ()'s, []'s, and {}'s and ignores the goal tokens within those pairings */\nstatic void skipUntil (lexerState *lexer, int goal_tokens[], int num_goal_tokens)\n{\n    int block_level = 0;\n\n    while (lexer->cur_token != TOKEN_EOF)\n    {\n        /* check if the keyword is reached, only if outside a block */\n        if (block_level == 0)\n        {\n            int ii = 0;\n            for(ii = 0; ii < num_goal_tokens; ii++)\n            {\n                if (lexer->cur_token == goal_tokens[ii])\n                {\n                    break;\n                }\n            }\n            if (ii < num_goal_tokens)\n            {\n                /* parse the next token */\n                advanceToken(lexer, true, false);\n                break;\n            }\n        }\n\n        /* take into account nested blocks */\n        switch (lexer->cur_token)\n        {\n            case TOKEN_OPEN_BLOCK:\n                block_level++;\n                break;\n            case TOKEN_CLOSE_BLOCK:\n                block_level--;\n                break;\n            default:\n                break;\n        }\n\n        /* Has to be after the token switch to catch the case when we start with the initial level token */\n        if (num_goal_tokens == 0 && block_level == 0)\n        {\n            break;\n        }\n\n        advanceToken(lexer, true, false);\n    }\n}\n\n/* Skip until the end of the block */\nstatic void skipUntilEnd (lexerState *lexer)\n{\n    int goal_tokens[] = { TOKEN_CLOSE_BLOCK };\n\n    skipUntil(lexer, goal_tokens, 1);\n}\n\n/* Skip a function body after assignment operator '='\n * Beware of continuation lines after operators\n *  */\nstatic void skipBody (lexerState *lexer)\n{\n    /* assume position just after '=' */\n    while (lexer->cur_token != TOKEN_EOF && lexer->cur_token != TOKEN_NEWLINE)\n    {\n        advanceToken(lexer, true, false);\n\n        if (lexer->cur_token == TOKEN_OPEN_BLOCK)\n        {\n            /* pass the keyword */\n            advanceToken(lexer, true, false);\n            skipUntilEnd(lexer);\n            /* the next token is already selected */\n        }\n    }\n}\n\n/* Short function format:\n * <ident> ( [<args>] ) [::<type>] [<where>] = [begin] <body> [end]\n * */\nstatic void parseShortFunction (lexerState *lexer, vString *scope, int parent_kind)\n{\n    /* assume the current char is just after identifier */\n    vString *name;\n    vString *arg_list;\n    unsigned long line;\n    MIOPos pos;\n\n    /* should be an open parenthesis after identifier\n     * with potentially parametric type */\n    skipWhitespace(lexer, false);\n    if (lexer->cur_c == '{')\n    {\n        scanCurlyBlock(lexer);\n        skipWhitespace(lexer, false);\n    }\n\n    if (lexer->cur_c != '(')\n    {\n        advanceToken(lexer, true, false);\n        return;\n    }\n\n    name = vStringNewCopy(lexer->token_str);\n    line = lexer->line;\n    pos = lexer->pos;\n\n    /* scan argument list */\n    advanceToken(lexer, true, false);\n    arg_list = vStringNewCopy(lexer->token_str);\n\n    /* scan potential type casting */\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token == TOKEN_TYPE_ANNOTATION)\n    {\n        vStringCat(arg_list, lexer->token_str);\n        advanceToken(lexer, true, false);\n    }\n    /* scan potential type union with 'where' */\n    if (lexer->cur_token == TOKEN_TYPE_WHERE)\n    {\n        vStringPut(arg_list, ' ');\n        vStringCat(arg_list, lexer->token_str);\n        advanceToken(lexer, true, false);\n    }\n\n    /* scan equal sign, ignore `==` and `=>` */\n    if (!(lexer->cur_token == '=' &&\n          lexer->cur_c != '=' &&\n          lexer->cur_c != '>'))\n    {\n        vStringDelete(name);\n        vStringDelete(arg_list);\n        return;\n    }\n\n    addTag(name, NULL, vStringValue(arg_list), K_FUNCTION, line, pos, scope, parent_kind);\n\n    /* scan until end of function definition */\n    skipBody(lexer);\n\n    /* Should end on a new line, parse next token */\n    advanceToken(lexer, true, false);\n    lexer->first_token = true;\n\n    vStringDelete(name);\n    vStringDelete(arg_list);\n}\n\n/* Function format:\n * function <ident> ( [<args>] ) [::<type>] [<where>] [<body>] end\n * */\nstatic void parseFunction (lexerState *lexer, vString *scope, int parent_kind)\n{\n    vString *name;\n    vString *arg_list;\n    vString *local_scope;\n    int local_parent_kind;\n    unsigned long line;\n    MIOPos pos;\n\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token != TOKEN_IDENTIFIER)\n    {\n        return;\n    }\n    else if (lexer->cur_c == '.')\n    {\n        local_scope = vStringNewCopy(lexer->token_str);\n        local_parent_kind = K_MODULE;\n        advanceChar(lexer);\n        advanceToken(lexer, true, false);\n    }\n    else\n    {\n        local_scope = vStringNewCopy(scope);\n        local_parent_kind = parent_kind;\n    }\n\n    /* Scan for parametric type constructor */\n    skipWhitespace(lexer, false);\n    if (lexer->cur_c == '{')\n    {\n        scanCurlyBlock(lexer);\n        skipWhitespace(lexer, false);\n    }\n\n    name = vStringNewCopy(lexer->token_str);\n    arg_list = vStringNew();\n    line = lexer->line;\n    pos = lexer->pos;\n\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token == TOKEN_PAREN_BLOCK)\n    {\n        vStringCopy(arg_list, lexer->token_str);\n\n        /* scan potential type casting */\n        advanceToken(lexer, true, false);\n        if (lexer->cur_token == TOKEN_TYPE_ANNOTATION)\n        {\n            vStringCat(arg_list, lexer->token_str);\n            advanceToken(lexer, true, false);\n        }\n        /* scan potential type union with 'where' */\n        if (lexer->cur_token == TOKEN_TYPE_WHERE)\n        {\n            vStringPut(arg_list, ' ');\n            vStringCat(arg_list, lexer->token_str);\n            advanceToken(lexer, true, false);\n        }\n\n        addTag(name, NULL, vStringValue(arg_list), K_FUNCTION, line, pos, local_scope, local_parent_kind);\n        addToScope(scope, name);\n        parseExpr(lexer, true, K_FUNCTION, scope);\n    }\n    else if (lexer->cur_token == TOKEN_CLOSE_BLOCK)\n    {\n        /* Function without method */\n        addTag(name, NULL, NULL, K_FUNCTION, line, pos, local_scope, local_parent_kind);\n        /* Go to the closing 'end' keyword */\n        skipUntilEnd(lexer);\n    }\n\n    vStringDelete(name);\n    vStringDelete(arg_list);\n    vStringDelete(local_scope);\n}\n\n/* Macro format:\n * \"macro\" <ident>()\n */\nstatic void parseMacro (lexerState *lexer, vString *scope, int parent_kind)\n{\n    vString *name;\n    unsigned long line;\n    MIOPos pos;\n\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token != TOKEN_IDENTIFIER)\n    {\n        return;\n    }\n\n    name = vStringNewCopy(lexer->token_str);\n    line = lexer->line;\n    pos = lexer->pos;\n\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token == TOKEN_PAREN_BLOCK)\n    {\n        addTag(name, NULL, vStringValue(lexer->token_str), K_MACRO, line, pos, scope, parent_kind);\n    }\n\n    skipUntilEnd(lexer);\n    vStringDelete(name);\n}\n\n/* Const format:\n * \"const\" <ident>\n */\nstatic void parseConst (lexerState *lexer, vString *scope, int parent_kind)\n{\n    vString *name;\n\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token != TOKEN_IDENTIFIER)\n    {\n        return;\n    }\n\n    name = vStringNewCopy(lexer->token_str);\n\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token == TOKEN_TYPE_ANNOTATION)\n    {\n        addTag(name, \"const\", vStringValue(lexer->token_str), K_CONSTANT, lexer->line, lexer->pos, scope, parent_kind);\n        advanceToken(lexer, true, false);\n    }\n    else\n    {\n        addTag(name, \"const\", NULL, K_CONSTANT, lexer->line, lexer->pos, scope, parent_kind);\n    }\n\n    vStringDelete(name);\n}\n\n/* Type format:\n * [ \"abstract\" | \"primitive\" ] \"type\" <ident>\n */\nstatic void parseType (lexerState *lexer, vString *scope, int parent_kind)\n{\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token != TOKEN_IDENTIFIER)\n    {\n        return;\n    }\n\n    addTag(lexer->token_str, NULL, NULL, K_TYPE, lexer->line, lexer->pos, scope, parent_kind);\n\n    skipUntilEnd(lexer);\n}\n\n/* Module format:\n * [ \"baremodule\" | \"module\" ] <ident>\n */\nstatic void parseModule (lexerState *lexer, vString *scope, int parent_kind)\n{\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token != TOKEN_IDENTIFIER)\n    {\n        return;\n    }\n\n    addTag(lexer->token_str, NULL, NULL, K_MODULE, lexer->line, lexer->pos, scope, parent_kind);\n    addToScope(scope, lexer->token_str);\n    advanceToken(lexer, true, false);\n    parseExpr(lexer, true, K_MODULE, scope);\n}\n\n/*\n * Parse comma separated entity in import/using expressions. An entity could be\n * in the form of \"Module\" or \"Module.symbol\". The lexer should be at the end\n * of \"Module\", and this function will take it to the end of the entity\n * (whitespaces also skipped).\n */\nstatic void parseImportEntity (lexerState *lexer, vString *scope, int token_type, int parent_kind)\n{\n    if (lexer->cur_c == '.')\n    {\n        if (token_type == TOKEN_IMPORT)\n        {\n            vString *module_name = vStringNewCopy(lexer->token_str);\n            addReferenceTag(module_name, K_MODULE, JULIA_MODULE_NAMESPACE, lexer->line, lexer->pos, scope, parent_kind);\n            advanceChar(lexer);\n            advanceToken(lexer, true, false);\n            addReferenceTag(lexer->token_str, K_UNKNOWN, JULIA_UNKNOWN_IMPORTED, lexer->line, lexer->pos, module_name, K_MODULE);\n            vStringDelete(module_name);\n        }\n        else /* if (token_type == TOKEN_USING) */\n        {\n            /* using Module.symbol is invalid, so we advance the lexer but don't tag it. */\n            advanceChar(lexer);\n            advanceToken(lexer, true, false);\n        }\n    }\n    else\n    {\n        if (token_type == TOKEN_IMPORT)\n        {\n            addReferenceTag(lexer->token_str, K_MODULE, JULIA_MODULE_IMPORTED, lexer->line, lexer->pos, scope, parent_kind);\n        }\n        else /* if (token_type == TOKEN_USING) */\n        {\n            addReferenceTag(lexer->token_str, K_MODULE, JULIA_MODULE_USED, lexer->line, lexer->pos, scope, parent_kind);\n        }\n    }\n}\n\n/* Parse import/using expressions with a colon, like: */\n/* import Module: symbol1, symbol2 */\n/* using Module: symbol1, symbol2 */\n/* The lexer should be at the end of \"Module\", and this function will take it\n * to the end of the token after this expression (whitespaces also skipped). */\nstatic void parseColonImportExpr (lexerState *lexer, vString *scope, int token_type, int parent_kind)\n{\n    int symbol_role;\n    if (token_type == TOKEN_IMPORT)\n    {\n        symbol_role = JULIA_UNKNOWN_IMPORTED;\n    }\n    else /* if (token_type == TOKEN_USING) */\n    {\n        symbol_role = JULIA_UNKNOWN_USED;\n    }\n    vString *name = vStringNewCopy(lexer->token_str);\n    addReferenceTag(name, K_MODULE, JULIA_MODULE_NAMESPACE, lexer->line, lexer->pos, scope, parent_kind);\n    advanceChar(lexer);\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token == TOKEN_NEWLINE)\n    {\n        advanceToken(lexer, true, false);\n    }\n    while (lexer->cur_token == TOKEN_IDENTIFIER || lexer->cur_token == TOKEN_MACROCALL)\n    {\n        addReferenceTag(lexer->token_str, K_UNKNOWN, symbol_role, lexer->line, lexer->pos, name, K_MODULE);\n        if (lexer->cur_c == ',')\n        {\n            advanceChar(lexer);\n            advanceToken(lexer, true, false);\n            if (lexer->cur_token == TOKEN_NEWLINE)\n            {\n                advanceToken(lexer, true, false);\n            }\n        }\n        else\n        {\n            advanceToken(lexer, true, false);\n        }\n    }\n    vStringDelete(name);\n}\n\n/* Import format:\n * [ \"import\" | \"using\" ] <ident> [: <name>]\n */\nstatic void parseImport (lexerState *lexer, vString *scope, int token_type, int parent_kind)\n{\n    /* capture the imported name */\n    advanceToken(lexer, true, false);\n    /* import Mod1: symbol1, symbol2 */\n    /* using Mod1: symbol1, symbol2 */\n    if (lexer->cur_c == ':')\n    {\n        parseColonImportExpr(lexer, scope, token_type, parent_kind);\n    }\n    /* All other situations, like import/using Mod1, Mod2.symbol1, Mod3... */\n    else\n    {\n        while (lexer->cur_token == TOKEN_IDENTIFIER || lexer->cur_token == TOKEN_MACROCALL)\n        {\n            parseImportEntity(lexer, scope, token_type, parent_kind);\n            if (lexer->cur_c == ',')\n            {\n                advanceChar(lexer);\n                advanceToken(lexer, true, false);\n                if (lexer->cur_token == TOKEN_NEWLINE)\n                {\n                    advanceToken(lexer, true, false);\n                }\n            }\n            else\n            {\n                advanceToken(lexer, true, false);\n            }\n        }\n    }\n}\n\n/* Structs format:\n * \"struct\" <ident>[{<param>}] [<:<type>]; <fields> <inner constructor> end\n * */\nstatic void parseStruct (lexerState *lexer, vString *scope, int parent_kind)\n{\n    vString *name;\n    vString *field;\n    size_t old_scope_len;\n    unsigned long line;\n    MIOPos pos;\n\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token != TOKEN_IDENTIFIER)\n    {\n        return;\n    }\n\n    name = vStringNewCopy(lexer->token_str);\n    field = vStringNew();\n    line = lexer->line;\n    pos = lexer->pos;\n\n    /* scan parametrization */\n    advanceToken(lexer, true, false);\n    if (lexer->cur_token == TOKEN_CURLY_BLOCK)\n    {\n        addTag(name, NULL, vStringValue(lexer->token_str), K_STRUCT, line, pos, scope, parent_kind);\n        advanceToken(lexer, true, false);\n    }\n    else\n    {\n        addTag(name, NULL, NULL, K_STRUCT, line, pos, scope, parent_kind);\n    }\n    addToScope(scope, name);\n\n    /* skip inheritance */\n    if (lexer->cur_token == TOKEN_TYPE_ANNOTATION)\n    {\n        advanceToken(lexer, true, false);\n    }\n\n    /* keep the struct scope in memory to reset it after parsing constructors */\n    old_scope_len = vStringLength(scope);\n    /* Parse fields and inner constructors */\n    while (lexer->cur_token != TOKEN_EOF && lexer->cur_token != TOKEN_CLOSE_BLOCK)\n    {\n        if (lexer->cur_token == TOKEN_IDENTIFIER && lexer->first_token)\n        {\n            if (strcmp(vStringValue(lexer->token_str), vStringValue(name)) == 0)\n            {\n                /* inner constructor */\n                parseShortFunction(lexer, scope, K_STRUCT);\n                continue;\n            }\n\n            vStringCopy(field, lexer->token_str);\n\n            /* parse type annotation */\n            advanceToken(lexer, true, false);\n            if (lexer->cur_token == TOKEN_TYPE_ANNOTATION)\n            {\n                addTag(field, NULL, vStringValue(lexer->token_str), K_FIELD, lexer->line, lexer->pos, scope, K_STRUCT);\n                advanceToken(lexer, true, false);\n            }\n            else\n            {\n                addTag(field, NULL, NULL, K_FIELD, lexer->line, lexer->pos, scope, K_STRUCT);\n            }\n        }\n        else if (lexer->cur_token == TOKEN_FUNCTION)\n        {\n            /* inner constructor */\n            parseFunction(lexer, scope, K_STRUCT);\n        }\n        else\n        {\n            /* Get next token */\n            advanceToken(lexer, true, false);\n        }\n        resetScope(scope, old_scope_len);\n    }\n\n    vStringDelete(name);\n    vStringDelete(field);\n}\n\n\nstatic void parseExpr (lexerState *lexer, bool delim, int kind, vString *scope)\n{\n    int level = 1;\n    size_t old_scope_len;\n    vString *local_scope = NULL;\n\n    while (lexer->cur_token != TOKEN_EOF)\n    {\n        old_scope_len = vStringLength(scope);\n        /* Advance token and update if this is a new line */\n        while (lexer->cur_token == TOKEN_NEWLINE ||\n               lexer->cur_token == TOKEN_SEMICOLON ||\n               lexer->cur_token == TOKEN_NONE )\n        {\n            advanceToken(lexer, true, false);\n        }\n\n        /* Make sure every case advances the token\n         * otherwise we can be stuck in infinite loop */\n        switch (lexer->cur_token)\n        {\n            case TOKEN_CONST:\n                parseConst(lexer, scope, kind);\n                break;\n            case TOKEN_FUNCTION:\n                parseFunction(lexer, scope, kind);\n                break;\n            case TOKEN_MACRO:\n                parseMacro(lexer, scope, kind);\n                break;\n            case TOKEN_MODULE:\n                parseModule(lexer, scope, kind);\n                break;\n            case TOKEN_STRUCT:\n                parseStruct(lexer, scope, kind);\n                break;\n            case TOKEN_TYPE:\n                parseType(lexer, scope, kind);\n                break;\n            case TOKEN_IMPORT:\n                parseImport(lexer, scope, TOKEN_IMPORT, kind);\n                break;\n            case TOKEN_USING:\n                parseImport(lexer, scope, TOKEN_USING, kind);\n            case TOKEN_IDENTIFIER:\n                if (lexer->first_token && lexer->cur_c == '.')\n                {\n                    if (local_scope == NULL)\n                    {\n                        local_scope = vStringNew();\n                    }\n                    vStringCopy(local_scope, lexer->token_str);\n                    advanceChar(lexer);\n                    // next token, but keep the first_token value\n                    advanceToken(lexer, true, true);\n                    skipWhitespace(lexer, false);\n                    if (lexer->cur_c == '(')\n                    {\n                        parseShortFunction(lexer, local_scope, K_MODULE);\n                    }\n                }\n                else\n                {\n                    skipWhitespace(lexer, false);\n                    if (lexer->first_token && (lexer->cur_c == '(' || lexer->cur_c == '{'))\n                    {\n                        parseShortFunction(lexer, scope, kind);\n                    }\n                    else\n                    {\n                        advanceToken(lexer, true, false);\n                    }\n                }\n                break;\n            case TOKEN_OPEN_BLOCK:\n                level++;\n                advanceToken(lexer, true, false);\n                break;\n            case TOKEN_CLOSE_BLOCK:\n                level--;\n                advanceToken(lexer, true, false);\n                break;\n            default:\n                advanceToken(lexer, true, false);\n                break;\n        }\n        resetScope(scope, old_scope_len);\n        if (delim && level <= 0)\n        {\n            break;\n        }\n    }\n    vStringDelete(local_scope);\n}\n\nstatic void findJuliaTags (void)\n{\n    lexerState lexer;\n    vString* scope = vStringNew();\n    initLexer(&lexer);\n\n    parseExpr(&lexer, false, K_NONE, scope);\n    vStringDelete(scope);\n\n    deInitLexer(&lexer);\n}\n\nextern parserDefinition* JuliaParser (void)\n{\n    static const char *const extensions [] = { \"jl\", NULL };\n    parserDefinition* def = parserNew (\"Julia\");\n    def->kindTable  = JuliaKinds;\n    def->kindCount  = ARRAY_SIZE (JuliaKinds);\n    def->extensions = extensions;\n    def->parser     = findJuliaTags;\n    def->keywordTable = JuliaKeywordTable;\n    def->keywordCount = ARRAY_SIZE (JuliaKeywordTable);\n    return def;\n}\n"
  },
  {
    "path": "parsers/ldscript.c",
    "content": "/*\n *   Copyright (c) 2016, Masatake YAMATO\n *   Copyright (c) 2016, Red Hat, Inc.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for GNU linker script\n *   files.\n */\n\n#include \"general.h\"\n#include \"tokeninfo.h\"\n\n#include \"entry.h\"\n#include \"x-cpreprocessor.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"ptrarray.h\"\n#include \"read.h\"\n#include \"trace.h\"\n#include \"xtag.h\"\n\n#include <string.h>\n\n/*\n *   DATA DEFINITIONS\n */\n\ntypedef enum {\n\tLD_SCRIPT_SYMBOL_ENTRYPOINT,\n\tLD_SCRIPT_SYMBOL_ALIASED,\n} ldScriptSymbolRole;\n\nstatic roleDefinition LdScriptSymbolRoles [] = {\n\t{ true, \"entrypoint\", \"entry points\" },\n\t{ true, \"aliased\", \"aliased with __attribute__((alias(...))) in C/C++ code\",\n\t  .version = 1 },\n};\n\ntypedef enum {\n\tLD_SCRIPT_INPUT_SECTION_MAPPED,\n\tLD_SCRIPT_INPUT_SECTION_DISCARDED,\n\tLD_SCRIPT_INPUT_SECTION_DESTINATION,\n} ldScriptInputSectionRole;\n\nstatic roleDefinition LdScriptInputSectionRoles [] = {\n\t{ true, \"mapped\",  \"mapped to output section\" },\n\t{ true, \"discarded\", \"discarded when linking\" },\n\t{ true, \"destination\", \"specified as the destination of code and data\",\n\t  .version = 1 },\n};\n\ntypedef enum {\n\tK_SECTION,\n\tK_SYMBOL,\n\tK_VERSION,\n\tK_INPUT_SECTION,\n} ldScriptKind;\n\nstatic kindDefinition LdScriptKinds [] = {\n\t{ true, 'S', \"section\", \"sections\" },\n\t{ true, 's', \"symbol\",  \"symbols\",\n\t  .referenceOnly = false, ATTACH_ROLES(LdScriptSymbolRoles)},\n\t{ true, 'v', \"version\", \"versions\" },\n\t{ true, 'i', \"inputSection\", \"input sections\",\n\t  .referenceOnly = false, ATTACH_ROLES(LdScriptInputSectionRoles)},\n};\n\nenum {\n\tKEYWORD_ENTRY,\n\tKEYWORD_SECTIONS,\n\tKEYWORD_LOC,\n\tKEYWORD_AT,\n\tKEYWORD_VERSION,\n\tKEYWORD_PROVIDE,\n\tKEYWORD_PROVIDE_HIDDEN,\n\tKEYWORD_HIDDEN,\n\tKEYWORD_EXCLUDE_FILE,\n\tKEYWORD_INPUT_SECTION_FLAGS,\n\tKEYWORD_COMMON,\n\tKEYWORD_KEEP,\n\tKEYWORD_DATA,\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\n\nstatic const keywordTable LdScriptKeywordTable[] = {\n\t/* keyword\t\t\tkeyword ID */\n\t{ \"ENTRY\",\t\t\tKEYWORD_ENTRY\t\t\t},\n\t{ \"SECTIONS\",\t\tKEYWORD_SECTIONS\t\t},\n\t{ \".\",\t\t\t\tKEYWORD_LOC\t\t\t\t},\n\t{ \"AT\",\t\t\t\tKEYWORD_AT\t\t\t\t},\n\t{ \"VERSION\",\t\tKEYWORD_VERSION\t\t\t},\n\t{ \"PROVIDE\",\t\tKEYWORD_PROVIDE\t\t\t},\n\t{ \"PROVIDE_HIDDEN\",\tKEYWORD_PROVIDE_HIDDEN\t},\n\t{ \"HIDDEN\",\t        KEYWORD_HIDDEN\t        },\n\t{ \"EXCLUDE_FILE\",   KEYWORD_EXCLUDE_FILE    },\n\t{ \"INPUT_SECTION_FLAGS\", KEYWORD_INPUT_SECTION_FLAGS },\n\t{ \"COMMON\",\t\t\tKEYWORD_COMMON },\n\t{ \"KEEP\",\t\t\tKEYWORD_KEEP },\n\t{ \"SORT\",\t\t\tKEYWORD_KEEP },\n\t{ \"BYTE\",\t\t\tKEYWORD_DATA },\n\t{ \"SHORT\",\t\t\tKEYWORD_DATA },\n\t{ \"LONG\",\t\t\tKEYWORD_DATA },\n\t{ \"QUAD\",\t\t\tKEYWORD_DATA },\n\t{ \"SQUAD\",\t\t\tKEYWORD_DATA },\n\t{ \"FILL\",\t\t\tKEYWORD_DATA },\n};\n\nenum eTokenType {\n\t/* 0..255 are the byte's value */\n\tTOKEN_EOF = 256,\n\tTOKEN_UNDEFINED,\n\tTOKEN_KEYWORD,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_NUMBER,\n\tTOKEN_ASSIGNMENT_OP,\n\tTOKEN_OP,\n\tTOKEN_PHDIR,\n\tTOKEN_REGION,\n\tTOKEN_FILLEXP,\n\tTOKEN_DISCARD,\n};\n\nstatic void readToken (tokenInfo *const token, void *data CTAGS_ATTR_UNUSED);\nstatic void clearToken (tokenInfo *token);\nstatic void copyToken (tokenInfo *dest, tokenInfo *src, void *data CTAGS_ATTR_UNUSED);\n\ntypedef struct sLdScriptToken {\n\ttokenInfo base;\n\tint scopeIndex;\n\ttokenKeyword assignment;\n\tbool whitespacePrefixed;\n} ldScriptToken;\n\n#define LDSCRIPT(TOKEN) ((ldScriptToken *)TOKEN)\n\nstatic struct tokenTypePair ldScriptTypePairs [] = {\n\t{ '{', '}' },\n};\n\nstatic struct tokenInfoClass ldScriptTokenInfoClass = {\n\t.nPreAlloc = 4,\n\t.typeForUndefined = TOKEN_UNDEFINED,\n\t.keywordNone      = KEYWORD_NONE,\n\t.typeForKeyword   = TOKEN_KEYWORD,\n\t.typeForEOF       = TOKEN_EOF,\n\t.extraSpace       = sizeof (ldScriptToken) - sizeof (tokenInfo),\n\t.pairs            = ldScriptTypePairs,\n\t.pairCount        = ARRAY_SIZE (ldScriptTypePairs),\n\t.read             = readToken,\n\t.clear            = clearToken,\n\t.copy             = copyToken,\n};\n\ntypedef enum {\n\tF_ASSIGNMENT,\n\tCOUNT_FIELD\n} ldScriptField;\n\nstatic fieldDefinition LdScriptFields[COUNT_FIELD] = {\n\t{ .name = \"assignment\",\n\t  .description = \"how a value is assigned to the symbol\",\n\t  .enabled = true },\n};\n\nstatic langType Lang_ldscript;\n\n/*\n *   FUNCTION DEFINITIONS\n */\n\nstatic tokenInfo *newLdScriptToken (void)\n{\n\treturn newToken (&ldScriptTokenInfoClass);\n}\n\nstatic void clearToken (tokenInfo *token)\n{\n\tLDSCRIPT(token)->scopeIndex = CORK_NIL;\n\tLDSCRIPT(token)->assignment = KEYWORD_NONE;\n}\n\nstatic void copyToken (tokenInfo *dest, tokenInfo *src, void *data CTAGS_ATTR_UNUSED)\n{\n\tLDSCRIPT (dest)->scopeIndex =\n\t\tLDSCRIPT (src)->scopeIndex;\n\tLDSCRIPT (dest)->assignment =\n\t\tLDSCRIPT (src)->assignment;\n\tLDSCRIPT (dest)->whitespacePrefixed =\n\t\tLDSCRIPT (src)->whitespacePrefixed;\n}\n\nstatic int makeLdScriptTagMaybe (tagEntryInfo *const e, tokenInfo *const token,\n\t\t\t\t\t\t\t\t int kind, int role)\n{\n\tif (role == ROLE_DEFINITION_INDEX)\n\t{\n\t\tif (! LdScriptKinds[kind].enabled)\n\t\t\treturn CORK_NIL;\n\t}\n\telse if (! (isXtagEnabled (XTAG_REFERENCE_TAGS)\n\t\t\t\t&& LdScriptKinds[kind].roles[role].enabled))\n\t\treturn CORK_NIL;\n\n\tinitRefTagEntry (e, tokenString (token),\n\t\t\t\t\t kind,\n\t\t\t\t\t role);\n\tupdateTagLine (e, token->lineNumber, token->filePosition);\n\te->extensionFields.scopeIndex = LDSCRIPT (token)->scopeIndex;\n\n\t/* TODO: implement file: field. */\n\tif ((kind == K_SYMBOL)\n\t\t&& LdScriptFields[F_ASSIGNMENT].enabled)\n\t{\n\t\tconst char *assignment = NULL;\n\n\t\tswitch (LDSCRIPT (token)->assignment)\n\t\t{\n\t\tcase KEYWORD_PROVIDE:\n\t\t\tassignment = \"provide\";\n\t\t\tbreak;\n\t\tcase KEYWORD_PROVIDE_HIDDEN:\n\t\t\tassignment = \"provide_hidden\";\n\t\t\tbreak;\n\t\tcase KEYWORD_HIDDEN:\n\t\t\tassignment = \"hidden\";\n\t\t\tbreak;\n\t\t}\n\n\t\tif (assignment)\n\t\t\tattachParserField (e, LdScriptFields[F_ASSIGNMENT].ftype,\n\t\t\t\t\t\t\t   assignment);\n\t}\n\n\treturn makeTagEntry (e);\n}\n\n#define isIdentifierChar(c)\t\t\t\t\t\t\t\t\t\t\\\n\t(cppIsalnum (c) || (c) == '_' || (c) == '.' || (c) == '-' \\\n\t || (((c) >= 0x80) && ((c) <= 0xff)))\n\nstatic int readPrefixedToken (tokenInfo *const token, int type)\n{\n\tint n = 0;\n\tint c;\n\n\twhile ((c = cppGetc()) != EOF)\n\t{\n\t\tif (isIdentifierChar (c))\n\t\t{\n\t\t\tn++;\n\t\t\ttokenPutc (token, c);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcppUngetc (c);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (n)\n\t\ttoken->type = type;\n\treturn n;\n}\n\nstatic bool collectMacroArguments (ptrArray *args)\n{\n\tvString *s = vStringNew ();\n\ttokenInfo *const t = newLdScriptToken ();\n\tint depth = 1;\n\n\tunsigned long ln = cppGetInputLineNumber ();\n\tMIOPos pos = cppGetInputFilePosition ();\n\t/* Above initial values for ln and pos are not used: just\n\t   for suppressing compiler warnings. */\n\n\tdo\n\t{\n\t\ttokenRead (t);\n\t\tif (s && vStringLength (s) == 0)\n\t\t{\n\t\t\tln = t->lineNumber;\n\t\t\tpos = t->filePosition;\n\t\t}\n\n\t\tif (tokenIsType (t, EOF))\n\t\t\tbreak;\n\t\telse if (tokenIsTypeVal (t, ')'))\n\t\t{\n\t\t\tdepth--;\n\t\t\tif (depth == 0)\n\t\t\t{\n\t\t\t\tcppMacroArg *a = cppMacroArgNew (vStringDeleteUnwrap (s), true,\n\t\t\t\t\t\t\t\t\t\t\t\t ln, pos);\n\t\t\t\tptrArrayAdd (args, a);\n\t\t\t\ts = NULL;\n\t\t\t}\n\t\t\telse\n\t\t\t\tvStringCat (s, t->string);\n\t\t}\n\t\telse if (tokenIsTypeVal (t, '('))\n\t\t{\n\t\t\tdepth++;\n\t\t\tvStringCat (s, t->string);\n\t\t}\n\t\telse if (tokenIsTypeVal (t, ','))\n\t\t{\n\t\t\tcppMacroArg *a = cppMacroArgNew (vStringDeleteUnwrap (s), true,\n\t\t\t\t\t\t\t\t\t\t\t ln, pos);\n\t\t\tptrArrayAdd (args, a);\n\t\t\ts = vStringNew ();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (LDSCRIPT(t)->whitespacePrefixed)\n\t\t\t\tvStringPut(s, ' ');\n\t\t\tvStringCat (s, t->string);\n\t\t}\n\t}\n\twhile (depth > 0);\n\n\tvStringDelete (s);\t\t\t/* NULL is acceptable. */\n\n\ttokenDelete (t);\n\n\tif (depth > 0)\n\t\tTRACE_PRINT(\"unbalanced argument list\");\n\n\treturn (depth > 0)? false: true;\n}\n\nstatic bool expandCppMacro (cppMacroInfo *macroInfo,\n\t\t\t\t\t\t\tunsigned long lineNumber, MIOPos filePosition)\n{\n\tptrArray *args = NULL;\n\n\tif (macroInfo->hasParameterList)\n\t{\n\t\ttokenInfo *const t = newLdScriptToken ();\n\n\t\t/* Though macro arguments are expected, they are not found. */\n\t\ttokenRead (t);\n\t\tif (!tokenIsTypeVal (t, '('))\n\t\t{\n\t\t\ttokenUnread (t);\n\t\t\ttokenDelete (t);\n\t\t\tTRACE_PRINT(\"no argument for the %s<%p>\", macroInfo->name, macroInfo);\n\t\t\treturn false;\n\t\t}\n\n\t\targs = ptrArrayNew (cppMacroArgDelete);\n\t\tif (!collectMacroArguments (args))\n\t\t{\n\t\t\tptrArrayDelete (args);\n\t\t\ttokenUnread (t);\n\t\t\ttokenDelete (t);\n\t\t\treturn false;\n\t\t}\n\t\ttokenDelete (t);\n\t}\n\n#ifdef DO_TRACING\n\tif (args)\n\t{\n\t\tfor (int i = 0; i < ptrArrayCount(args); i++)\n\t\t\tTRACE_PRINT(\"[%d] %s\", i, (const char *)ptrArrayItem (args, i));\n\t}\n#endif\n\n\t{\n\t\tcppMacroTokens *tokens = cppExpandMacro (macroInfo, args,\n\t\t\t\t\t\t\t\t\t\t\t\t lineNumber, filePosition);\n\t\tcppUngetMacroTokens (tokens);\n\t}\n\n\tptrArrayDelete (args);\t\t/* NULL is acceptable. */\n\treturn true;\n}\n\nstatic void processCppMacroX (tokenInfo *const token)\n{\n\tif (cppUngetBufferSize() >= CPP_MAXIMUM_UNGET_BUFFER_SIZE_FOR_MACRO_REPLACEMENTS)\n\t{\n\t\tTRACE_PRINT (\"Ungetbuffer overflow when processing \\\"%s\\\": %d\",\n\t\t\t\t\t vStringValue (token->string), cppUngetBufferSize());\n\t\treturn;\n\t}\n\n\tcppMacroInfo *macroInfo = cppFindMacro (vStringValue (token->string));\n\tif (macroInfo)\n\t{\n\t\tTRACE_PRINT(\"Macro expansion: %s<%p>%s\", vStringValue (token->string),\n\t\t\t\t\tmacroInfo, macroInfo->hasParameterList? \"(...)\": \"\");\n\n\t\tif (macroInfo->useCount >= CPP_MAXIMUM_MACRO_USE_COUNT)\n\t\t{\n\t\t\tTRACE_PRINT (\"Overly uesd macro %s<%p> useCount: %d (> %d)\",\n\t\t\t\t\t\t vStringValue (token->string), macroInfo, macroInfo->useCount,\n\t\t\t\t\t\t CPP_MAXIMUM_MACRO_USE_COUNT);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!macroInfo->replacements)\n\t\t\treturn;\n\n\t\tif (expandCppMacro (macroInfo, token->lineNumber, token->filePosition))\n\t\t\treadToken (token, NULL);\n\t}\n}\n\nstatic void readToken (tokenInfo *const token, void *data CTAGS_ATTR_UNUSED)\n{\n\tint c, c0, c1;\n\n\ttoken->type\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\n\tint prefix_count = -1;\n\tLDSCRIPT (token)->whitespacePrefixed = false;\n\tdo {\n\t\tc = cppGetc();\n\t\tprefix_count++;\n\t\tif (prefix_count > 0)\n\t\t\tLDSCRIPT (token)->whitespacePrefixed = true;\n\t} while (c == ' ' || c== '\\t' || c == '\\f' || c == '\\r' || c == '\\n'\n\t\t\t || c == CPP_STRING_SYMBOL || c == CPP_CHAR_SYMBOL);\n\n\ttoken->lineNumber   = cppGetInputLineNumber ();\n\ttoken->filePosition = cppGetInputFilePosition ();\n\n\tswitch (c)\n\t{\n\tcase EOF:\n\t\ttoken->type = TOKEN_EOF;\n\t\tbreak;\n\tcase ';':\n\tcase '(':\n\tcase ')':\n\tcase '{':\n\tcase '}':\n\tcase '[':\n\tcase ']':\n\t\ttokenPutc(token, c);\n\t\ttoken->type = c;\n\t\tbreak;\n\tcase '~':\n\tcase '%':\n\tcase '?':\n\t\ttokenPutc(token, c);\n\t\ttoken->type = TOKEN_OP;\n\t\tbreak;\n\tcase '-':\n\tcase '+':\n\tcase '*':\n\tcase '/':\t\t\t\t\t/* -,+,*,/,-=,+=,*=,/= */\n\t\ttokenPutc(token, c);\n\t\tc0 = cppGetc ();\n\t\ttoken->type = TOKEN_OP;\n\t\tif (c0 == '=')\n\t\t{\n\t\t\ttokenPutc(token, c0);\n\t\t\ttoken->type = TOKEN_ASSIGNMENT_OP;\n\t\t}\n\t\telse if (c == '/' && c0 == 'D')\n\t\t{\n\t\t\ttokenInfo *const discard = newLdScriptToken ();\n\n\t\t\tcppUngetc (c0);\n\t\t\ttokenRead (discard);\n\t\t\tif (tokenIsType(discard, IDENTIFIER) &&\n\t\t\t\t(strcmp(tokenString(discard), \"DISCARD\")) == 0)\n\t\t\t{\n\t\t\t\tc1 = cppGetc ();\n\t\t\t\tif (c1 == '/')\n\t\t\t\t\ttoken->type = TOKEN_DISCARD;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcppUngetc (c1);\n\t\t\t\t\ttokenUnread (discard);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\ttokenUnread (discard);\n\t\t\ttokenDelete (discard);\n\t\t}\n\t\telse\n\t\t\tcppUngetc (c0);\n\t\tbreak;\n\tcase '!':\t\t\t\t\t/* !, != */\n\t\ttokenPutc(token, c);\n\t\ttoken->type = TOKEN_OP;\n\t\tc0 = cppGetc ();\n\t\tif (c0 == '=')\n\t\t\ttokenPutc(token, c0);\n\t\telse\n\t\t\tcppUngetc (c0);\n\tcase '<':\t\t\t\t\t/* <,<=,<<,<<= */\n\t\ttokenPutc(token, c);\n\t\ttoken->type = TOKEN_OP;\n\t\tc0 = cppGetc ();\n\t\tif (c0 == c  || c0 == '=')\n\t\t{\n\t\t\ttokenPutc(token, c0);\n\t\t\tif (c0 == c)\n\t\t\t{\n\t\t\t\tc1 = cppGetc ();\n\t\t\t\tif (c1 == '=')\n\t\t\t\t{\n\t\t\t\t\ttokenPutc(token, c1);\n\t\t\t\t\ttoken->type = TOKEN_ASSIGNMENT_OP;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tcppUngetc (c1);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tcppUngetc (c0);\n\tcase '|':\t\t\t\t\t/* |,||,|= */\n\tcase '&':\t\t\t\t\t/* &,&&,&= */\n\t\ttokenPutc(token, c);\n\t\ttoken->type = TOKEN_OP;\n\t\tc0 = cppGetc ();\n\t\tif (c0 == c)\n\t\t\ttokenPutc(token, c0);\n\t\telse if (c0 == '=')\n\t\t{\n\t\t\ttokenPutc(token, c0);\n\t\t\ttoken->type = TOKEN_ASSIGNMENT_OP;\n\t\t}\n\t\telse\n\t\t\tcppUngetc (c0);\n\t\tbreak;\n\tcase '=':\t\t\t\t\t/* =,== */\n\t\ttokenPutc(token, c);\n\t\tif (!readPrefixedToken (token, TOKEN_FILLEXP))\n\t\t{\n\t\t\tc0 = cppGetc ();\n\t\t\tif (c0 == '=')\n\t\t\t{\n\t\t\t\ttokenPutc(token, c0);\n\t\t\t\ttoken->type = TOKEN_OP;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcppUngetc (c0);\n\t\t\t\ttoken->type = TOKEN_ASSIGNMENT_OP;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase '>':\t\t\t\t\t/* >,>>,>>= */\n\t\ttokenPutc(token, c);\n\t\tif (!readPrefixedToken (token, TOKEN_REGION))\n\t\t{\n\t\t\ttoken->type = TOKEN_OP;\n\t\t\tc0 = cppGetc ();\n\t\t\tif (c0 == c  || c0 == '=')\n\t\t\t{\n\t\t\t\ttokenPutc(token, c0);\n\t\t\t\tc1 = cppGetc();\n\t\t\t\tif (c1 == '=')\n\t\t\t\t{\n\t\t\t\t\ttokenPutc(token, c1);\n\t\t\t\t\ttoken->type = TOKEN_ASSIGNMENT_OP;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tcppUngetc (c1);\n\t\t\t}\n\t\t\telse\n\t\t\t\tcppUngetc (c0);\n\t\t}\n\t\tbreak;\n\tcase ':':\n\t\ttokenPutc(token, c);\n\t\tif (!readPrefixedToken (token, TOKEN_PHDIR))\n\t\t\ttoken->type = c;\n\t\tbreak;\n\tdefault:\n\t\tif (cppIsdigit (c))\n\t\t{\n\t\t\t/* Using cppIsdigit here is redundant.\n\t\t\t *\n\t\t\t * `c' never takes STRING_SYMBOL or CHAR_SYMBOL as\n\t\t\t * its value here.\n\t\t\t * However, the practice using cppIs... macros for the value\n\t\t\t * returned from cppGetc() may avoid unexpected programming\n\t\t\t * mistakes I took repeatedly.\n\t\t\t */\n\t\t\ttoken->type = TOKEN_NUMBER;\n\t\t\ttokenPutc(token, c);\n\t\t\twhile ((c = cppGetc()))\n\t\t\t{\n\t\t\t\tif (isIdentifierChar (c))\n\t\t\t\t\ttokenPutc(token, c);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcppUngetc (c);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (isIdentifierChar(c))\n\t\t{\n\t\t\ttokenPutc(token, c);\n\t\t\twhile ((c = cppGetc()))\n\t\t\t{\n\t\t\t\tif (isIdentifierChar(c))\n\t\t\t\t\ttokenPutc(token, c);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcppUngetc (c);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttoken->keyword = lookupKeyword (vStringValue (token->string), Lang_ldscript);\n\t\t\tif (token->keyword == KEYWORD_NONE)\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\tprocessCppMacroX (token);\n\t\t\t}\n\t\t\telse\n\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttokenPutc(token, c);\n\t\t\ttoken->type = c;\n\t\t}\n\t\tbreak;\n\t}\n}\n\nstatic void parseEntry (tokenInfo *const token)\n{\n\ttokenRead (token);\n\tif (token->type == '(')\n\t{\n\t\ttokenInfo *const name = newLdScriptToken ();\n\n\t\ttokenRead (name);\n\t\tif (tokenIsType(name, IDENTIFIER))\n\t\t{\n\t\t\ttagEntryInfo e;\n\n\t\t\tmakeLdScriptTagMaybe (&e, name, K_SYMBOL, LD_SCRIPT_SYMBOL_ENTRYPOINT);\n\t\t\ttokenRead (token);\n\t\t\ttokenSkipToType (token, ')');\n\t\t}\n\t\ttokenDelete (name);\n\t}\n}\n\nstatic void parseProvide (tokenInfo * token)\n{\n\ttokenKeyword p = token->keyword;\n\n\tif (tokenSkipToType (token, '('))\n\t{\n\t\ttagEntryInfo e;\n\t\ttokenRead (token);\n\t\tif (tokenIsType(token, IDENTIFIER))\n\t\t{\n\t\t\tLDSCRIPT (token)->assignment = p;\n\n\t\t\tmakeLdScriptTagMaybe (&e, token,\n\t\t\t\t\t\t\t\t  K_SYMBOL, ROLE_DEFINITION_INDEX);\n\t\t\tLDSCRIPT (token)->assignment = KEYWORD_NONE;\n\t\t}\n\t\ttokenSkipToType (token, ')');\n\t}\n}\n\n/* An example of input sections:\n\n\t(.text .rdata)\n\n  .text and .rtada are input sections. */\nstatic void parseInputSections (tokenInfo *const token)\n{\n\ttagEntryInfo e;\n\tdo {\n\t\ttokenRead (token);\n\t\tif (token->type == ')')\n\t\t\tbreak;\n\t\telse if (tokenIsType (token, IDENTIFIER))\n\t\t\tmakeLdScriptTagMaybe (&e, token,\n\t\t\t\t\t\t\t\t  K_INPUT_SECTION,\n\t\t\t\t\t\t\t\t  LDSCRIPT(token)->scopeIndex == CORK_NIL\n\t\t\t\t\t\t\t\t  ? LD_SCRIPT_INPUT_SECTION_DISCARDED\n\t\t\t\t\t\t\t\t  : LD_SCRIPT_INPUT_SECTION_MAPPED);\n\t\telse if (tokenIsKeyword (token, EXCLUDE_FILE))\n\t\t\ttokenSkipToType (token, ')');\n\t} while (!tokenIsEOF (token));\n}\n\n/* Symbols and input sections are captured here.\n   An example of output sections:\n\n\t\t__brk_base = .;\n\t\t. += 64 * 1024;\n\t\t*(.brk_reservation)\n\t\t__brk_limit = .;\n\n  __brk_base and __brk_limit should be recorded as a symbol.\n  .brk_reservationshould be recorded as an input section. */\n\nstatic void parseOutputSectionCommands (tokenInfo *const token, int terminator)\n{\n\ttokenInfo *const tmp = newLdScriptToken ();\n\tint scope_index = LDSCRIPT (token)->scopeIndex;\n\n\tdo {\n\t\ttokenRead (token);\n\t\tLDSCRIPT (token)->scopeIndex = scope_index;\n\n\t\tif (tokenIsKeyword (token, INPUT_SECTION_FLAGS))\n\t\t{\n\t\t\ttokenSkipToType (token, '(');\n\t\t\ttokenSkipToType (token, ')');\n\t\t}\n\t\telse if (tokenIsKeyword (token, KEEP))\n\t\t{\n\t\t\ttokenSkipToType (token, '(');\n\t\t\tparseOutputSectionCommands (token, ')');\n\t\t}\n\t\telse if (tokenIsType (token,IDENTIFIER)\n\t\t\t\t || tokenIsKeyword (token, LOC))\n\t\t{\n\t\t\ttagEntryInfo e;\n\n\t\t\ttokenRead (tmp);\n\t\t\tif (tokenIsType (tmp, ASSIGNMENT_OP))\n\t\t\t{\n\t\t\t\tif (! tokenIsKeyword (token, LOC))\n\t\t\t\t\tmakeLdScriptTagMaybe (&e, token,\n\t\t\t\t\t\t\t\t\t\t  K_SYMBOL, ROLE_DEFINITION_INDEX);\n\t\t\t\ttokenSkipToType (token, ';');\n\t\t\t}\n\t\t\telse if (tmp->type == '(')\n\t\t\t\tparseInputSections (token);\n\t\t\telse\n\t\t\t\ttokenUnread (tmp);\n\t\t}\n\t\t/* `*',`?', `[', `]' can be part of a pattern of input object file names\n\t\t   as a meta character.\n\t\t   `[' can enumerated here because it cannot be at the end of pattern. */\n\t\telse if ((token->type == TOKEN_OP\n\t\t\t\t  && ((tokenString(token)[0] == '*')\n\t\t\t\t\t  || (tokenString(token)[0] == '?'))\n\t\t\t\t  && (tokenString(token)[1] == '\\0'))\n\t\t\t\t || token->type == ']')\n\t\t{\n\t\t\ttokenRead (tmp);\n\t\t\tif (tmp->type == '(')\n\t\t\t\tparseInputSections (token);\n\t\t\telse\n\t\t\t\ttokenUnread (tmp);\n\t\t}\n\t\telse if (tokenIsKeyword (token, PROVIDE)\n\t\t\t\t || tokenIsKeyword (token, PROVIDE_HIDDEN)\n\t\t\t\t || tokenIsKeyword (token, HIDDEN))\n\t\t\tparseProvide (token);\n\t} while (! (tokenIsEOF (token) || token->type == terminator));\n\n\ttokenDelete (tmp);\n}\n\nstatic void parseSection (tokenInfo * name)\n{\n\ttokenInfo *const token = newLdScriptToken ();\n\ttagEntryInfo e;\n\n\ttokenRead (token);\n\n\tif (tokenIsType (token, ASSIGNMENT_OP))\n\t{\n\t\tif (!tokenIsKeyword (name, LOC))\n\t\t\tmakeLdScriptTagMaybe (&e, name,\n\t\t\t\t\t\t\t\t  K_SYMBOL, ROLE_DEFINITION_INDEX);\n\t\ttokenSkipToType (token, ';');\n\t}\n\telse\n\t{\n\tretry:\n\t\tif (tokenIsType (token, NUMBER))\n\t\t\ttokenSkipToType (token, ':');\n\t\telse if (tokenIsType (token, IDENTIFIER))\n\t\t{\n\t\t\ttokenCopy (name, token);\n\t\t\ttokenRead (token);\n\t\t\tgoto retry;\n\t\t}\n\t\telse if (token->type == '(')\n\t\t\ttokenSkipToType (token, ')');\n\n\t\tif (token->type == ':')\n\t\t{\n\t\t\tint scope_index;\n\n\t\t\tif (tokenIsType (name, DISCARD))\n\t\t\t\tscope_index = CORK_NIL;\n\t\t\telse\n\t\t\t\tscope_index = makeLdScriptTagMaybe (&e, name,\n\t\t\t\t\t\t\t\t\t\t\t\t\tK_SECTION, ROLE_DEFINITION_INDEX);\n\n\t\t\tif (tokenSkipToType (token, '{'))\n\t\t\t{\n\t\t\t\tLDSCRIPT (token)->scopeIndex = scope_index;\n\t\t\t\tparseOutputSectionCommands (token, '}');\n\t\t\t}\n\t\t}\n\t}\n\ttokenDelete (token);\n}\n\nstatic void parseSections (tokenInfo *const token)\n{\n\ttokenRead (token);\n\tif (token->type == '{')\n\t{\n\t\tdo {\n\t\t\ttokenRead (token);\n\t\t\tif (tokenIsKeyword (token, ENTRY))\n\t\t\t\tparseEntry (token);\n\t\t\telse if (tokenIsType(token, IDENTIFIER)\n\t\t\t\t\t || tokenIsKeyword (token, LOC)\n\t\t\t\t\t || tokenIsType (token, DISCARD))\n\t\t\t\tparseSection (token);\n\t\t\telse if (tokenIsKeyword (token, PROVIDE)\n\t\t\t\t\t || tokenIsKeyword (token, PROVIDE_HIDDEN)\n\t\t\t\t\t || tokenIsKeyword (token, HIDDEN))\n\t\t\t\tparseProvide (token);\n\t\t} while (! (tokenIsEOF (token) || token->type == '}'));\n\t}\n}\n\nstatic void parseVersion (tokenInfo *const token)\n{\n\ttagEntryInfo e;\n\tmakeLdScriptTagMaybe (&e, token,\n\t\t\t\t\t\t  K_VERSION, ROLE_DEFINITION_INDEX);\n\n\tif (tokenSkipToType (token, '{'))\n\t\ttokenSkipOverPair (token);\n}\n\nstatic void parseVersions (tokenInfo *const token)\n{\n\ttokenRead (token);\n\tif (token->type == '{')\n\t{\n\t\ttokenInfo *curly = newTokenByCopying(token);\n\t\ttokenRead (token);\n\t\tif (token->type == '{')\n\t\t{\n\t\t\tvString *anonver = anonGenerateNew (\"ver\", K_VERSION);\n\t\t\t{\n\t\t\t\ttagEntryInfo e;\n\t\t\t\tinitTagEntry (&e, vStringValue (anonver), K_VERSION);\n\t\t\t\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\t\t\t\tmakeTagEntry (&e);\n\t\t\t}\n\t\t\tvStringDelete(anonver);\n\t\t\ttokenUnread (token);\n\t\t\ttokenSkipOverPair (curly);\n\t\t\ttokenCopy (token, curly);\n\t\t\ttokenDelete (curly);\n\t\t\treturn;\n\t\t}\n\t\ttokenDelete (curly);\n\t\ttokenUnread (token);\n\n\t\tdo {\n\t\t\ttokenRead (token);\n\t\t\tif (tokenIsType(token, IDENTIFIER))\n\t\t\t{\n\t\t\t\tparseVersion (token);\n\t\t\t\ttokenSkipToType (token, ';');\n\t\t\t}\n\t\t} while (! (tokenIsEOF (token) || token->type == '}'));\n\t}\n}\n\nstatic void findLdScriptTags (void)\n{\n\ttokenInfo *const token = newLdScriptToken ();\n\ttokenInfo *const tmp = newLdScriptToken ();\n\n\tcppInit (false, false, false, false,\n\t\t\t KIND_GHOST_INDEX, 0, 0,\n\t\t\t KIND_GHOST_INDEX,\n\t\t\t KIND_GHOST_INDEX, 0, 0,\n\t\t\t FIELD_UNKNOWN);\n\n\tdo {\n\t\ttokenRead (token);\n\t\tif (tokenIsKeyword (token, ENTRY))\n\t\t\tparseEntry (token);\n\t\telse if (tokenIsKeyword (token, SECTIONS))\n\t\t\tparseSections (token);\n\t\telse if (tokenIsType(token, IDENTIFIER))\n\t\t{\n\t\t\ttagEntryInfo e;\n\t\t\ttokenRead (tmp);\n\t\t\tif (tokenIsType(tmp, ASSIGNMENT_OP))\n\t\t\t{\n\t\t\t\tmakeLdScriptTagMaybe (&e, token,\n\t\t\t\t\t\t\t\t\t  K_SYMBOL, ROLE_DEFINITION_INDEX);\n\t\t\t\ttokenSkipToType (tmp, ';');\n\t\t\t}\n\t\t}\n\t\telse if (tokenIsKeyword (token, VERSION))\n\t\t\tparseVersions(token);\n\t} while (!tokenIsEOF (token));\n\n\tcppTerminate ();\n\n\ttokenDelete (tmp);\n\ttokenDelete (token);\n\n\tflashTokenBacklog (&ldScriptTokenInfoClass);\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_ldscript = language;\n}\n\nextern parserDefinition* LdScriptParser (void)\n{\n\tparserDefinition* def = parserNew (\"LdScript\");\n\n\t/* File name patters are picked from Linux kernel and ecos. */\n\tstatic const char *const extensions [] = { \"lds\", \"scr\", \"ld\", \"ldi\", NULL };\n\n\t/* lds.S must be here because Asm parser registers .S as an extension.\n\t * ld.script is used in linux/arch/mips/boot/compressed/ld.script. */\n\tstatic const char *const patterns [] = { \"*.lds.S\", \"*.ld.S\", \"ld.script\", NULL };\n\n\t/* Emacs's mode */\n\tstatic const char *const aliases [] = { \"ld-script\", NULL };\n\n\tdef->initialize = initialize;\n\tdef->parser     = findLdScriptTags;\n\n\tdef->kindTable      = LdScriptKinds;\n\tdef->kindCount  = ARRAY_SIZE (LdScriptKinds);\n\tdef->extensions = extensions;\n\tdef->patterns   = patterns;\n\tdef->aliases    = aliases;\n\tdef->keywordTable = LdScriptKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (LdScriptKeywordTable);\n\tdef->fieldTable = LdScriptFields;\n\tdef->fieldCount = ARRAY_SIZE (LdScriptFields);\n\n\tdef->useCork    = CORK_QUEUE|CORK_SYMTAB;\n\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/lisp.c",
    "content": "/*\n*   Copyright (c) 2000-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for LISP files.\n*\n*   References:\n*\n*   - [Lisp] https://www.lispworks.com/documentation/HyperSpec/Front/index.htm\n*   - [EmacsLisp] https://www.gnu.org/software/emacs/manual/html_node/elisp/index.html\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"vstring.h\"\n\n#include \"x-lisp.h\"\n\n#include <string.h>\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_UNKNOWN,\n\tK_FUNCTION,\n\tK_VARIABLE,\n\tK_MACRO,\n\tK_CONST,\n\tK_TYPE,\n\tK_CLASS,\n\tK_STRUCT,\n\tK_METHOD,\n\tK_GENERIC,\n\tK_PARAMETER,\n} lispKind;\n\nstatic kindDefinition LispKinds [] = {\n\t{ true, 'Y', \"unknown\", \"unknown type of definitions\" },\n\t{ true, 'f', \"function\", \"functions\" },\n\t{ true, 'v', \"variable\", \"variables\" },\n\t{ true, 'm', \"macro\", \"macros\" },\n\t{ true, 'c', \"const\", \"constants\" },\n\t{ true, 't', \"type\", \"types\",\n\t  .version = 1 },\n\t{ true, 'C', \"class\", \"classes\",\n\t  .version = 1 },\n\t{ true, 's', \"struct\", \"structs\",\n\t  .version = 1 },\n\t{ true, 'M', \"method\", \"methods\" },\n\t{ true, 'G', \"generic\", \"generics\",\n\t  .version = 1 },\n\t{ true, 'p', \"parameter\", \"parameters\",\n\t  .version = 1 },\n};\n\ntypedef enum {\n\tF_DEFINER,\n} lispField;\n\nstatic fieldDefinition LispFields[] = {\n\t{ .name = \"definer\",\n\t  .description = \"the name of the function or macro that defines the unknown/Y-kind object\",\n\t  .enabled = true,\n\t  .version = 1 },\n};\n\ntypedef enum {\n\teK_UNKNOWN,\n\teK_FUNCTION,\n\teK_VARIABLE,\n\teK_CONST,\n\teK_MACRO,\n\teK_ALIAS,\n\teK_VARALIAS,\n\teK_SUBST,\n\teK_INLINE,\n\teK_ERROR,\n\teK_MINOR_MODE,\n\teK_DERIVED_MODE,\n\t/* custom.el */\n\teK_CUSTOM,\n\teK_GROUP,\n\teK_FACE,\n\teK_THEME,\n} emacsLispKind;\n\ntypedef enum {\n\teF_DEFINER,\n} emacsLispField;\n\nstatic fieldDefinition EmacsLispFields[] = {\n\t{ .name = \"definer\",\n\t  .description = \"the name of the function or macro that defines the unknown/Y-kind object\",\n\t  .enabled = true,\n\t  .version = 1 },\n};\n\n/* Following macro/builtin doesn't define a name appeared\n * at car. So this parser doesn't handle it well.\n * -----------------------------------------------------\n * defadvice           (=> cadadr)\n * defconst-mode-local (=> cadr)\n * defvar-mode-local   (=> cadr)\n */\nstatic kindDefinition EmacsLispKinds [] = {\n\t{ true, 'Y', \"unknown\", \"unknown type of definitions\" },\n\t{ true, 'f', \"function\", \"functions\" },\n\t{ true, 'v', \"variable\", \"variables\" },\n\t{ true, 'c', \"const\", \"constants\" },\n\t{ true, 'm', \"macro\", \"macros\" },\n\t{ true, 'a', \"alias\", \"aliases for functions\" },\n\t{ true, 'V', \"varalias\", \"aliases for variables\" },\n\t{ true, 's', \"subst\", \"inline function\" },\n\t{ true, 'i', \"inline\", \"inline function\" },\n\t{ true, 'e', \"error\", \"errors\" },\n\t{ true, 'M', \"minorMode\", \"minor modes\" },\n\t{ true, 'D', \"derivedMode\", \"derived major mode\" },\n\t/* custom.el */\n\t{ true, 'C', \"custom\", \"customizable variables\" },\n\t{ true, 'G', \"group\", \"customization groups\" },\n\t{ true, 'H', \"face\", \"customizable faces\" }, /* 'F' is reserved by ctags */\n\t{ true, 'T', \"theme\", \"custom themes\" },\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n/*\n * lisp tag functions\n *  look for (def or (DEF, quote or QUOTE\n */\nextern struct lispIsDefResult lispIsDef (struct lispDialect *dialect,\n\t\t\t\t\t\t\t\t\t\t const unsigned char *strp)\n{\n\tbool cis = dialect->case_insensitive; /* Renaming for making code short */\n\tbool is_def = ( (strp [1] == 'd' || (cis && strp [1] == 'D'))\n\t\t\t\t\t&& (strp [2] == 'e' || (cis && strp [2] == 'E'))\n\t\t\t\t\t&& (strp [3] == 'f' || (cis && strp [3] == 'F')));\n\n\t/* Ignore def\"ault\" */\n\tif (is_def\n\t\t&& (strp [4] == 'a' || (cis && strp [4] == 'A'))\n\t\t&& (strp [5] == 'u' || (cis && strp [5] == 'U'))\n\t\t&& (strp [6] == 'l' || (cis && strp [6] == 'L'))\n\t\t&& (strp [7] == 't' || (cis && strp [7] == 'T')))\n\t\tis_def = false;\n\n\t/* Ignore def\"inition\" */\n\tif (is_def\n\t\t&& (strp  [4] == 'i' || (cis && strp  [4] == 'I'))\n\t\t&& (strp  [5] == 'n' || (cis && strp  [5] == 'N'))\n\t\t&& (strp  [6] == 'i' || (cis && strp  [6] == 'I'))\n\t\t&& (strp  [7] == 't' || (cis && strp  [7] == 'T'))\n\t\t&& (strp  [8] == 'i' || (cis && strp  [8] == 'I'))\n\t\t&& (strp  [9] == 'o' || (cis && strp  [9] == 'O'))\n\t\t&& (strp [10] == 'n' || (cis && strp [10] == 'N')))\n\t\tis_def = false;\n\n\n\treturn (struct lispIsDefResult) { .is_def = is_def, .kind = KIND_GHOST_INDEX };\n}\n\nstatic int L_isquote (const unsigned char *strp, bool case_insensitive)\n{\n\tbool cis = case_insensitive; /* Renaming for making code short */\n\n\treturn ( (*(++strp) == 'q' || (cis && *strp == 'Q'))\n\t\t  && (*(++strp) == 'u' || (cis && *strp == 'U'))\n\t\t  && (*(++strp) == 'o' || (cis && *strp == 'O'))\n\t\t  && (*(++strp) == 't' || (cis && *strp == 'T'))\n\t\t  && (*(++strp) == 'e' || (cis && *strp == 'E'))\n\t\t  && isspace (*(++strp)));\n}\n\nstatic int L_issetf (const unsigned char *strp, bool case_insensitive)\n{\n\tbool cis = case_insensitive; /* Renaming for making code short */\n\n\treturn ( (*(++strp) == 's' || (cis && *strp == 'S'))\n\t\t  && (*(++strp) == 'e' || (cis && *strp == 'E'))\n\t\t  && (*(++strp) == 't' || (cis && *strp == 'T'))\n\t\t  && (*(++strp) == 'f' || (cis && *strp == 'F'))\n\t\t  && isspace (*(++strp)));\n}\n\nstatic int lisp_hint2kind (struct lispKindHint *hint, const char *namespace CTAGS_ATTR_UNUSED)\n{\n\tint k = K_UNKNOWN;\n\tint n = vStringLength (hint->str) - 4;\n\n\t/* 4 means strlen(\"(def\"). */\n#define EQN(X) strncmp(vStringValue (hint->str) + 4, &X[3], n) == 0\n\tswitch (n)\n\t{\n\tcase 2:\n\t\tif (EQN(\"DEFUN\"))\n\t\t\tk = K_FUNCTION;\n\t\tbreak;\n\tcase 3:\n\t\tif (EQN(\"DEFVAR\"))\n\t\t\tk = K_VARIABLE;\n\t\tbreak;\n\tcase 4:\n\t\tif (EQN(\"DEFTYPE\"))\n\t\t\tk = K_TYPE;\n\t\tbreak;\n\tcase 5:\n\t\tif (EQN(\"DEFMACRO\"))\n\t\t\tk = K_MACRO;\n\t\telse if (EQN(\"DEFCLASS\"))\n\t\t\tk = K_CLASS;\n\t\tbreak;\n\tcase 6:\n\t\tif (EQN(\"DEFSTRUCT\"))\n\t\t\tk = K_STRUCT;\n\t\telse if (EQN(\"DEFMETHOD\"))\n\t\t\tk = K_METHOD;\n\t\tbreak;\n\tcase 7:\n\t\tif (EQN(\"DEFGENERIC\"))\n\t\t\tk = K_GENERIC;\n\t\tbreak;\n\tcase 8:\n\t\tif (EQN(\"DEFCONSTANT\"))\n\t\t\tk = K_CONST;\n\t\tbreak;\n\tcase 9:\n\t\tif (EQN(\"DEFPARAMETER\"))\n\t\t\tk = K_PARAMETER;\n\t\tbreak;\n\t}\n#undef EQN\n\treturn k;\n}\n\n/* TODO: implement this in hashtable. */\nstatic int elisp_hint2kind (struct lispKindHint *hint, const char *namespace CTAGS_ATTR_UNUSED)\n{\n\tint k = eK_UNKNOWN;\n\tint n = vStringLength (hint->str) - 4;\n\n\t/* 4 means strlen(\"(def\"). */\n#define EQN(X) strncmp(vStringValue (hint->str) + 4, &X[3], n) == 0\n\tswitch (n)\n\t{\n\tcase 2:\n\t\tif (EQN(\"defun\"))\n\t\t\tk = eK_FUNCTION;\n\t\tbreak;\n\tcase 3:\n\t\tif (EQN(\"defvar\"))\n\t\t\tk = eK_VARIABLE;\n\t\telse if (EQN(\"defun*\"))\n\t\t\tk = eK_FUNCTION;\n\t\tbreak;\n\tcase 4:\n\t\tif (EQN(\"defface\"))\n\t\t\tk = eK_FACE;\n\tcase 5:\n\t\tif (EQN(\"defconst\"))\n\t\t\tk = eK_CONST;\n\t\telse if (EQN(\"defmacro\"))\n\t\t\tk = eK_MACRO;\n\t\telse if (EQN(\"defalias\"))\n\t\t\tk = eK_ALIAS;\n\t\telse if (EQN(\"defsubst\"))\n\t\t\tk = eK_SUBST;\n\t\telse if (EQN(\"defgroup\"))\n\t\t\tk = eK_GROUP;\n\t\telse if (EQN(\"deftheme\"))\n\t\t\tk = eK_THEME;\n\t\tbreak;\n\tcase 6:\n\t\tif (EQN(\"defcustom\"))\n\t\t\tk = eK_CUSTOM;\n\t\telse if (EQN(\"defsubst*\"))\n\t\t\tk = eK_SUBST;\n\t\telse if (EQN(\"defmacro*\"))\n\t\t\tk = eK_MACRO;\n\t\tbreak;\n\tcase 7:\n\t\tif (EQN(\"define-key\"))\n\t\t\tk = KIND_GHOST_INDEX;\n\t\tbreak;\n\tcase 9:\n\t\tif (EQN(\"defvar-local\"))\n\t\t\tk = eK_VARIABLE;\n\t\telse if (EQN(\"define-error\"))\n\t\t\tk = eK_ERROR;\n\t\tbreak;\n\tcase 8:\n\t\tif (EQN(\"defvaralias\"))\n\t\t\tk = eK_VARALIAS;\n\t\tbreak;\n\tcase 10:\n\t\tif (EQN(\"define-inline\"))\n\t\t\tk = eK_INLINE;\n\t\tbreak;\n\tcase 14:\n\t\tif (EQN(\"define-minor-mode\"))\n\t\t\tk = eK_MINOR_MODE;\n\t\tbreak;\n\tcase 16:\n\t\tif (EQN(\"define-derived-mode\"))\n\t\t\tk = eK_DERIVED_MODE;\n\t\tbreak;\n\tcase 21:\n\t\tif (EQN(\"define-global-minor-mode\"))\n\t\t\tk = eK_MINOR_MODE;\n\t\tbreak;\n\tcase 25:\n\t\tif (EQN(\"define-globalized-minor-mode\"))\n\t\t\tk = eK_MINOR_MODE;\n\t\tbreak;\n\tcase 27:\n\t\tif (EQN(\"define-obsolete-function-alias\"))\n\t\t\tk = eK_ALIAS;\n\t\tbreak;\n\t}\n#undef EQN\n\treturn k;\n}\n\nextern int lispGetIt (struct lispDialect *dialect,\n\t\t\t\t\t  vString *const name, const unsigned char *dbp, struct lispKindHint *kind_hint,\n\t\t\t\t\t  const char *namespace)\n{\n\tint index = CORK_NIL;\n\n\tif (*dbp == '\\'')  /* Skip prefix quote */\n\t\tdbp++;\n\telse if (*dbp == '(' && L_isquote (dbp, dialect->case_insensitive))  /* Skip \"(quote \" */\n\t{\n\t\tdbp += 7;\n\t\twhile (isspace (*dbp))\n\t\t\tdbp++;\n\t}\n\telse if (*dbp == '(' && L_issetf (dbp, dialect->case_insensitive)) /* Skip \"(setf \" */\n\t{\n\t\tdbp += 6;\n\t\twhile (isspace (*dbp))\n\t\t\tdbp++;\n\t}\n\tfor (const unsigned char *p = dbp;\n\t\t *p != '\\0' && *p != '(' && !isspace (*p) && *p != ')';\n\t\t p++)\n\t\tvStringPut (name, *p);\n\n\tif (vStringLength (name) > 0)\n\t{\n\t\tint kind = dialect->definer2kind(kind_hint, namespace);\n\t\tconst char *definer = NULL;\n\n\t\tif (kind == dialect->unknown_kind)\n\t\t{\n\t\t\tdefiner = vStringValue(kind_hint->str);\n\t\t\tif (definer[0] == '(')\n\t\t\t\tdefiner++;\n\t\t}\n\n\t\tif (kind != KIND_GHOST_INDEX)\n\t\t{\n\t\t\tindex = makeSimpleTag (name, kind);\n\t\t\tif (dialect->definer_field && dialect->definer_field->enabled\n\t\t\t\t&& definer && index != CORK_NIL)\n\t\t\t\tattachParserFieldToCorkEntry (index, dialect->definer_field->ftype, definer);\n\t\t}\n\t}\n\tvStringClear (name);\n\n\treturn index;\n}\n\n/* Algorithm adapted from from GNU etags.\n */\nextern void findLispTagsCommon (struct lispDialect *dialect)\n{\n\tvString *name = vStringNew ();\n\tstruct lispKindHint kind_hint = {0};\n\tconst unsigned char* line;\n\n\tkind_hint.str = vStringNew ();\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char *p = line;\n\n\t\tif (dialect->skip_initial_spaces)\n\t\t{\n\t\t\twhile (isspace ((unsigned char) *p))\n\t\t\t\tp++;\n\t\t}\n\n\t\tif (*p == '(')\n\t\t{\n\t\t\tkind_hint.isDefResult = dialect->is_def (dialect, p);\n\t\t\tif (kind_hint.isDefResult.is_def)\n\t\t\t{\n\t\t\t\tvStringClear (kind_hint.str);\n\t\t\t\twhile (*p != '\\0' && !isspace (*p))\n\t\t\t\t{\n\t\t\t\t\tvStringPut (kind_hint.str,\n\t\t\t\t\t\t\t\tdialect->case_insensitive? toupper(*p): *p);\n\t\t\t\t\tp++;\n\t\t\t\t}\n\n\n\t\t\t\tif (dialect->lambda_syntax_sugar)\n\t\t\t\t{\n\t\t\t\t\t/* Skip over open parens and white space:\n\t\t\t\t\t   (def ((foo\n\t\t\t\t\t   -----^^\n\t\t\t\t\t */\n\t\t\t\t\tdo {\n\t\t\t\t\t\twhile (*p != '\\0' && (isspace (*p) || *p == '('))\n\t\t\t\t\t\t\tp++;\n\t\t\t\t\t\tif (*p == '\\0')\n\t\t\t\t\t\t\tp = line = readLineFromInputFile ();\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t} while (line);\n\t\t\t\t\tif (line == NULL)\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\twhile (isspace (*p))\n\t\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t\tdialect->get_it(dialect, name, p, &kind_hint, \"\");\n\t\t\t}\n\t\t\telse if (dialect->namespace_sep != 0)\n\t\t\t{\n\t\t\t\tvString *namespace = vStringNew();\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tif (*p != '(')\n\t\t\t\t\t\tvStringPut (namespace, *p);\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t\twhile (*p != '\\0' && !isspace (*p)\n\t\t\t\t\t\t&& *p != dialect->namespace_sep && *p != '(' && *p != ')');\n\t\t\t\tif (*p == dialect->namespace_sep)\n\t\t\t\t{\n\t\t\t\t\tdo\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (namespace, *p);\n\t\t\t\t\t\tp++;\n\t\t\t\t\t}\n\t\t\t\t\twhile (*p == dialect->namespace_sep);\n\n\t\t\t\t\tkind_hint.isDefResult = dialect->is_def (dialect, p - 1);\n\t\t\t\t\tif (kind_hint.isDefResult.is_def)\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringClear (kind_hint.str);\n\t\t\t\t\t\twhile (*p != '\\0' && !isspace (*p))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvStringPut (kind_hint.str,\n\t\t\t\t\t\t\t\t\t\tdialect->case_insensitive? toupper(*p): *p);\n\t\t\t\t\t\t\tp++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\twhile (isspace (*p))\n\t\t\t\t\t\t\tp++;\n\t\t\t\t\t\tdialect->get_it(dialect, name, p, &kind_hint, vStringValue (namespace));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvStringDelete (namespace);\n\t\t\t}\n\t\t}\n\t}\n\tvStringDelete (name);\n\tvStringDelete (kind_hint.str);\n}\n\nstatic void findLispTags (void)\n{\n\tstruct lispDialect lisp_dialect = {\n\t\t.definer2kind = lisp_hint2kind,\n\t\t.case_insensitive = true,\n\t\t.namespace_sep = ':',\n\t\t.unknown_kind = K_UNKNOWN,\n\t\t.definer_field = LispFields + F_DEFINER,\n\t\t.skip_initial_spaces = false,\n\t\t.lambda_syntax_sugar = false,\n\t\t.is_def = lispIsDef,\n\t\t.get_it = lispGetIt,\n\t\t.scope = CORK_NIL,\n\t};\n\n\tfindLispTagsCommon (&lisp_dialect);\n}\n\nstatic void findEmacsLispTags (void)\n{\n\tstruct lispDialect elisp_dialect = {\n\t\t.definer2kind = elisp_hint2kind,\n\t\t.case_insensitive = false,\n\t\t.namespace_sep = 0,\n\t\t.unknown_kind = eK_UNKNOWN,\n\t\t.definer_field = EmacsLispFields + eF_DEFINER,\n\t\t.skip_initial_spaces = false,\n\t\t.lambda_syntax_sugar = false,\n\t\t.is_def = lispIsDef,\n\t\t.get_it = lispGetIt,\n\t\t.scope = CORK_NIL,\n\t};\n\n\tfindLispTagsCommon (&elisp_dialect);\n}\n\n\nextern parserDefinition* LispParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"cl\", \"clisp\", \"l\", \"lisp\", \"lsp\", NULL\n\t};\n\tstatic const char *const aliases [] = {\n\t\t\"clisp\", NULL\n\t};\n\n\tstatic selectLanguage selectors[] = { selectLispOrLEXByLEXMarker, NULL };\n\n\tparserDefinition* def = parserNew (\"Lisp\");\n\tdef->kindTable      = LispKinds;\n\tdef->kindCount  = ARRAY_SIZE (LispKinds);\n\tdef->fieldTable = LispFields;\n\tdef->fieldCount = ARRAY_SIZE (LispFields);\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->parser     = findLispTags;\n\tdef->selectLanguage = selectors;\n\tdef->useCork = CORK_QUEUE;\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\treturn def;\n}\n\nextern parserDefinition* EmacsLispParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"el\", NULL\n\t};\n\tstatic const char *const aliases [] = {\n\t\t\"emacs-lisp\", NULL\n\t};\n\n\tparserDefinition* def = parserNew (\"EmacsLisp\");\n\tdef->kindTable      = EmacsLispKinds;\n\tdef->kindCount  = ARRAY_SIZE (EmacsLispKinds);\n\tdef->fieldTable = EmacsLispFields;\n\tdef->fieldCount = ARRAY_SIZE (EmacsLispFields);\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->parser     = findEmacsLispTags;\n\tdef->useCork = CORK_QUEUE;\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/lua.c",
    "content": "/*\n*   Copyright (c) 2000-2001, Max Ischenko <mfi@ukr.net>.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Lua language.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_FUNCTION,\n\tK_UNKNOWN,\n} luaKind;\n\ntypedef enum {\n\tLUA_UNKNOWN_REFERENCED,\n} luaUnknownRole;\n\nstatic roleDefinition LuaUnknownRoles [] = {\n\t{ false, \"referenced\", \"referenced somehow\" },\n};\n\nstatic kindDefinition LuaKinds [] = {\n\t{ true, 'f', \"function\", \"functions\" },\n\n\t/* `unknown' is a kind just for making FQ tag for functions. */\n\t{ false, 'Y', \"unknown\",  \"unknown language object\",\n\t  .referenceOnly = true, ATTACH_ROLES(LuaUnknownRoles) },\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n/*\n * Helper function.\n * Returns 1 if line looks like a line of Lua code.\n *\n * TODO: Recognize UNIX bang notation.\n * (Lua treat first line as a comment if it starts with #!)\n *\n */\nstatic bool is_a_code_line (const unsigned char *line)\n{\n\tbool result;\n\tconst unsigned char *p = line;\n\twhile (isspace (*p))\n\t\tp++;\n\tif (p [0] == '\\0')\n\t\tresult = false;\n\telse if (p [0] == '-' && p [1] == '-')\n\t\tresult = false;\n\telse\n\t\tresult = true;\n\treturn result;\n}\n\nstatic bool isLuaIdentifier (char c)\n{\n\treturn (bool) !(isspace((unsigned char) c)  || c == '(' || c == ')'\n\t\t\t\t\t|| c == '=' || c == '.' || c == ':' || c == '{'\n\t\t\t\t\t|| c == '}');\n}\n\nstatic void set_scope (int child, int parent)\n{\n\tif (parent == CORK_NIL || child == CORK_NIL)\n\t\treturn;\n\n\ttagEntryInfo *e = getEntryInCorkQueue (child);\n\tif (!e)\n\t\treturn;\n\n\te->extensionFields.scopeIndex = parent;\n}\n\nstatic void extract_next_token (const char *begin, const char *end_sentinel, vString *name)\n{\n\tif (begin == NULL || end_sentinel == NULL)\n\t\treturn;\n\n\tAssert (begin <= end_sentinel);\n\n\t/* Both on '(' */\n\tif (begin == end_sentinel)\n\t\treturn;\n\n\t/* Trim prefixed white spaces  */\n\twhile (isspace ((unsigned char) *begin))\n\t\tbegin++;\n\n\t/* Both on '(' */\n\tif (begin == end_sentinel)\n\t\treturn;\n\n\tconst char *end = end_sentinel - 1;\n\n\t/* Trim suffixed white spaces  */\n\twhile (isspace ((unsigned char) *end))\n\t\tend--;\n\n\tAssert (begin <= end);\n\n\tint lastCorkIndx = CORK_NIL;\n\tfor (const char *c = begin; c <= end; ++c)\n\t{\n\t\tif (*c == '.' || *c == ':')\n\t\t{\n\t\t\tint r = makeSimpleRefTag(name,\n\t\t\t\t\t\t\t\t\t K_UNKNOWN, LUA_UNKNOWN_REFERENCED);\n\t\t\tset_scope(r, lastCorkIndx);\n\t\t\tlastCorkIndx = r;\n\n\t\t\t/* Do not include module names in function name */\n\t\t\tvStringClear (name);\n\t\t}\n\t\telse if (isLuaIdentifier (*c))\n\t\t\tvStringPut (name, *c);\n\t\telse\n\t\t{\n\t\t\t/* An unexpected character is found\n\t\t\t * between \"function\" and \"(\" */\n\t\t\tvStringClear (name);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tint d = makeSimpleTag (name, K_FUNCTION);\n\tset_scope(d, lastCorkIndx);\n\tvStringClear (name);\n}\n\nstatic void extract_prev_token (const char *end, const char *begin_sentinel, vString *name)\n{\n\tconst char *begin;\n\n\tif (end == NULL || begin_sentinel == NULL)\n\t\treturn;\n\n\tif (! (begin_sentinel <= end))\n\t\treturn;\n\n\twhile (isspace ((unsigned char) *end))\n\t{\n\t\tend--;\n\t\tif (! (begin_sentinel <= end))\n\t\t\treturn;\n\t}\n\n\tbegin = end;\n\twhile (begin_sentinel <= begin && isLuaIdentifier (*begin))\n\t\tbegin--;\n\n\tint targetCorkIndex = CORK_NIL;\n\tif (end - begin)\n\t{\n\t\tvStringNCatS (name, begin + 1, end - begin);\n\t\ttargetCorkIndex = makeSimpleTag (name, K_FUNCTION);\n\t\tvStringClear (name);\n\t}\n\n\tif (targetCorkIndex == CORK_NIL || begin_sentinel == begin)\n\t\treturn;\n\n\t/* Fill the scope field of the function. */\n\tend = begin;\n\twhile (begin_sentinel <= (begin + 1))\n\t{\n\t\tbool on_boundary = false;\n\t\tif (begin < begin_sentinel || !isLuaIdentifier (*begin))\n\t\t{\n\t\t\tif (end - begin)\n\t\t\t{\n\t\t\t\tvStringNCatS (name, begin + 1, end - begin);\n\t\t\t\tint r = makeSimpleRefTag (name,\n\t\t\t\t\t\t\t\t\t\t  K_UNKNOWN, LUA_UNKNOWN_REFERENCED);\n\t\t\t\tset_scope (targetCorkIndex, r);\n\t\t\t\ttargetCorkIndex = r;\n\t\t\t\tvStringClear (name);\n\t\t\t}\n\t\t\tif (begin_sentinel <= begin && ! (*begin == ':' || *begin == '.'))\n\t\t\t\tbreak;\n\t\t\ton_boundary = true;\n\t\t}\n\t\tbegin--;\n\n\t\tif(on_boundary)\n\t\t\tend = begin;\n\t}\n}\n\nstatic void findLuaTags (void)\n{\n\tvString *name = vStringNew ();\n\tconst unsigned char *line;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst char *p, *q;\n\n\t\tif (! is_a_code_line (line))\n\t\t\tcontinue;\n\n\t\tp = (const char*) strstr ((const char*) line, \"function\");\n\t\tif (p == NULL)\n\t\t\tcontinue;\n\n\t\tq = strchr ((const char*) line, '=');\n\n\t\tif (q == NULL) {\n\t\t\tp = p + 8;  /* skip the `function' word */\n\n\t\t\t/* We expect [ \\t(] */\n\t\t\tif (! (*p == '(' || isspace ((unsigned char) *p)))\n\t\t\t\tcontinue;\n\t\t\tq = strchr ((const char*) p, '(');\n\t\t\tif (q)\n\t\t\t\textract_next_token (p, q, name);\n\t\t} else if (\n\t\t\t   (*(q+1) != '=') /* ignore `if type(v) == \"function\" then ...' */\n\t\t\t   && (q < p)\t   /* ignore \"function\" ~=  */\n\t\t\t   ) {\n\t\t\tp = (const char*) &line[0];\n\t\t\tif (p < q)\n\t\t\t\textract_prev_token (q - 1, p, name);\n\t\t}\n\t}\n\tvStringDelete (name);\n}\n\nextern parserDefinition* LuaParser (void)\n{\n\tstatic const char* const extensions [] = { \"lua\", NULL };\n\tparserDefinition* def = parserNew (\"Lua\");\n\tdef->kindTable      = LuaKinds;\n\tdef->kindCount  = ARRAY_SIZE (LuaKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findLuaTags;\n\tdef->useCork    = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/m4.c",
    "content": "/*\n *   Copyright (c) 2011, Colomban Wendling <colomban@geany.org>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for M4.\n */\n\n#include \"general.h\"\t/* must always come first */\n\n#include <ctype.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"entry.h\"\n#include \"htable.h\"\n#include \"keyword.h\"\n#include \"x-m4.h\"\n#include \"numarray.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n\n\nenum M4Kind {\n\tM4_MACRO_KIND,\n\tM4_MACROFILE_KIND,\n};\n\nenum M4MacroRole {\n\tM4_MACRO_ROLE_UNDEF,\n};\n\nenum M4MacrofileRole {\n\tM4_MACROFILE_ROLE_INCLUDED,\n\tM4_MACROFILE_ROLE_SILENTLY_INCLUDED,\n};\n\n\nstatic roleDefinition M4MacroRoles [] = {\n\t{ true, \"undef\", \"undefined\" },\n};\n\nstatic roleDefinition M4MacrofileRoles [] = {\n\t{ true, \"included\", \"included macro\" },\n\t{ true, \"sincluded\", \"silently included macro\" },\n};\n\nstatic kindDefinition M4Kinds[] = {\n\t{ true, 'd', \"macro\", \"macros\",\n\t  .referenceOnly = false, ATTACH_ROLES(M4MacroRoles) },\n\t{ true, 'I', \"macrofile\", \"macro files\",\n\t  .referenceOnly = true, ATTACH_ROLES(M4MacrofileRoles) },\n};\n\ntypedef enum {\n\tKEYWORD_define,\n\tKEYWORD_undefine,\n\tKEYWORD_include,\n\tKEYWORD_sinclude,\n\tKEYWORD_changequote,\n} m4KeywordId;\n\n/* TODO: ideally \"m4_\" prefix keywords should be\n   installed and handled in Autoconf parser. */\nstatic const keywordTable m4KeywordTable[] = {\n#define ENTRY(K) \\\n\t{ #K, KEYWORD_##K }, \\\n\t{ \"m4_\" #K, KEYWORD_##K }\n\tENTRY(define),\n\tENTRY(undefine),\n\tENTRY(include),\n\tENTRY(sinclude),\n\tENTRY(changequote),\n};\n\n\nstruct m4Ctx {\n\tm4Subparser *sub;\n\tintArray *indexStack;\n};\n\nstatic void parseM4Char(struct m4Ctx *ctx, vString *const token, int c);\n\n/* Quote handling */\n\n/* TODO: Characters are assumed for quoting.\n   However, m4 allows strings. */\nstatic char m4QuoteOpen = 0;\nstatic char m4QuoteClose = 0;\n\nextern void setM4Quotes(char openQuote, char closeQuote)\n{\n\tm4QuoteOpen = openQuote;\n\tm4QuoteClose = closeQuote;\n}\n\n/* gets the close quote corresponding to openQuote.\n * return 0 if openQuote is not a valid open quote */\nstatic int getCloseQuote(int openQuote)\n{\n\tif (openQuote == m4QuoteOpen)\n\t{\n\t\treturn m4QuoteClose;\n\t}\n\treturn 0;\n}\n\nstatic void parseQuotes(struct m4Ctx *ctx, vString *const token, int c)\n{\n\tunsigned int depth = 0;\n\tint openQuote = 0, closeQuote = 0;\n\n\tcloseQuote = getCloseQuote(c);\n\tif (! closeQuote)\n\t\treturn;\n\telse\n\t\topenQuote = c;\n\n\tbool reenter = false;\n\tif (ctx->sub && ctx->sub->doesWantToParseInsideQuotes)\n\t{\n\t\tenterSubparser ((subparser *)ctx->sub);\n\t\treenter = ctx->sub->doesWantToParseInsideQuotes (ctx->sub, ctx->indexStack);\n\t\tleaveSubparser ();\n\t}\n\n\tfor (; c != EOF; c = getcFromInputFile())\n\t{\n\t\tif (c == closeQuote)\n\t\t\tdepth --;\n\t\telse if (c == openQuote)\n\t\t\tdepth ++;\n\t\telse if (reenter)\n\t\t\tparseM4Char (ctx, token, c);\n\n\t\tif (depth == 0)\n\t\t\tbreak;\n\t}\n}\n\nstatic void pushIndex (struct m4Ctx *ctx, int index)\n{\n\tintArrayAdd (ctx->indexStack, index);\n}\n\nstatic int popIndexSafe (struct m4Ctx *ctx)\n{\n\treturn intArrayIsEmpty (ctx->indexStack)? CORK_NIL: intArrayRemoveLast (ctx->indexStack);\n}\n\nstatic int topIndex (struct m4Ctx *ctx)\n{\n\treturn intArrayIsEmpty (ctx->indexStack)? CORK_NIL: intArrayLast (ctx->indexStack);\n}\n\n/* parser */\n\n#define IS_WORD(c) (isalnum(c) || (c) == '_')\n\n/* reads a possibly quoted word.  word characters are those passing IS_WORD() */\nstatic void readQuotedWord(vString *const name)\n{\n\tunsigned int depth = 0;\n\tint openQuote = 0, closeQuote = 0;\n\tint c = getcFromInputFile();\n\n\tcloseQuote = getCloseQuote(c);\n\tif (closeQuote != 0)\n\t{\n\t\topenQuote = c;\n\t\tdepth ++;\n\t\tc = getcFromInputFile();\n\t}\n\n\tfor (; c != EOF; c = getcFromInputFile())\n\t{\n\t\t/* don't allow embedded NULs, and prevents to match when quote == 0 (aka none) */\n\t\tif (c == 0)\n\t\t\tbreak;\n\t\t/* close before open to support open and close characters to be the same */\n\t\telse if (c == closeQuote)\n\t\t\tdepth --;\n\t\telse if (c == openQuote)\n\t\t\tdepth ++;\n\t\telse if (IS_WORD(c) || depth > 0)\n\t\t\tvStringPut(name, c);\n\t\telse\n\t\t{\n\t\t\tungetcToInputFile(c);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic bool skipLineEnding(int c)\n{\n\tif (c == '\\n')\n\t\treturn true;\n\telse if (c == '\\r')\n\t{\n\t\t/* try to eat the `\\n' of a `\\r\\n' sequence */\n\t\tc = getcFromInputFile();\n\t\tif (c != '\\n')\n\t\t\tungetcToInputFile(c);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic void skipToCharacter(int ch, bool oneLine)\n{\n\tint c;\n\n\twhile ((c = getcFromInputFile()) != EOF)\n\t{\n\t\tif (c == ch)\n\t\t\tbreak;\n\t\telse if (oneLine && skipLineEnding(c))\n\t\t\tbreak;\n\t}\n}\n\nstatic void skipLine(int c)\n{\n\tfor (; c != EOF; c = getcFromInputFile())\n\t{\n\t\tif (skipLineEnding(c))\n\t\t\tbreak;\n\t}\n}\n\nstatic m4Subparser * maySwitchLanguage (const char* token)\n{\n\tsubparser *tmp;\n\tm4Subparser *m4found = NULL;\n\n\tforeachSubparser (tmp, false)\n\t{\n\t\tm4Subparser *m4tmp = (m4Subparser *)tmp;\n\n\t\tenterSubparser(tmp);\n\t\tif (m4tmp->probeLanguage\n\t\t\t&& m4tmp->probeLanguage (m4tmp, token))\n\t\t{\n\t\t\tchooseExclusiveSubparser (tmp, NULL);\n\t\t\tm4found = m4tmp;\n\t\t}\n\t\tleaveSubparser();\n\n\t\tif (m4found)\n\t\t\tbreak;\n\t}\n\n\treturn m4found;\n}\n\n/* reads everything in a macro argument\n * return true if there are more args, false otherwise */\nextern bool readM4MacroArgument(vString *const arg)\n{\n\tint c;\n\n\t/* discard leading blanks */\n\twhile ((c = getcFromInputFile()) != EOF && isspace(c))\n\t\t;\n\n\tfor (; c != EOF; c = getcFromInputFile())\n\t{\n\t\tif (c == ',' || c == ')')\n\t\t{\n\t\t\tungetcToInputFile(c);\n\t\t\treturn c == ',';\n\t\t}\n\t\telse if (getCloseQuote(c) != 0)\n\t\t{\n\t\t\tungetcToInputFile(c);\n\t\t\treadQuotedWord(arg);\n\t\t}\n\t\telse\n\t\t\tvStringPut(arg, c);\n\t}\n\n\treturn false;\n}\n\nstatic void handleM4Changequote(void)\n{\n\tvString *const arg = vStringNew();\n\tchar args[2] = {0,0};\n\tint i, n = (sizeof(args) / sizeof(args[0]));\n\tbool more = true;\n\n\tfor (i = 0; more && i < n; i++)\n\t{\n\t\tconst char *v;\n\n\t\tvStringClear(arg);\n\t\tmore = readM4MacroArgument(arg);\n\t\tif (more)\n\t\t\tgetcFromInputFile();\n\t\tv = vStringValue(arg);\n\t\tif (! v[0] || v[1])\n\t\t\tbreak;\n\t\telse\n\t\t\targs[i] = *v;\n\t}\n\n\tif (! more)\n\t{\n\t\tif (args[0] && args[1])\n\t\t\tsetM4Quotes (args[0], args[1]);\n\t\telse if (args[1])\n\t\t\tsetM4Quotes (args[0], '\\'');\n\t\telse if (args[0])\n\t\t\tsetM4Quotes ('\\0', '\\0');\n\t\telse\n\t\t\tsetM4Quotes ('`', '\\'');\n\t}\n\n\tvStringDelete(arg);\n}\n\nstatic bool doesQuoteStart (int c)\n{\n\treturn (c == m4QuoteOpen);\n}\n\nstatic bool doesLineCommentStart (m4Subparser *m4, int c, char *token)\n{\n\tif (m4 && m4->doesLineCommentStart)\n\t{\n\t\tbool r;\n\t\tenterSubparser ((subparser *)m4);\n\t\tr = m4->doesLineCommentStart (m4, c, token);\n\t\tleaveSubparser ();\n\t\tif (r)\n\t\t\treturn true;\n\t}\n\n\treturn (strcmp(token, \"dnl\") == 0);\n}\n\nstatic bool doesStringLiteralStart (m4Subparser *m4, int c)\n{\n\tif (m4 && m4->doesStringLiteralStart)\n\t{\n\t\tbool r;\n\t\tenterSubparser ((subparser *)m4);\n\t\tr = m4->doesStringLiteralStart (m4, c);\n\t\tleaveSubparser ();\n\t\treturn r;\n\t}\n\treturn false;\n}\n\nstatic int notifyNewMacro (m4Subparser *m4, const char *token)\n{\n\tint index;\n\n\tenterSubparser ((subparser *)m4);\n\tindex = m4->newMacroNotify (m4, token);\n\tleaveSubparser ();\n\n\treturn index;\n}\n\n/* tag creation */\n\nstatic int makeM4RefTag(int kind, const vString *const name, int role)\n{\n\ttagEntryInfo e;\n\n\tif (vStringLength(name) <= 0)\n\t\treturn CORK_NIL;\n\n\tinitRefTagEntry (&e, vStringValue(name), kind, role);\n\n\treturn makeTagEntry(&e);\n}\n\nstatic int makeM4Tag (int kind, int role)\n{\n\tint index = CORK_NIL;\n\tvString *name = NULL;\n\n\tif (kind == M4_MACRO_KIND)\n\t{\n\t\tif (role == ROLE_DEFINITION_INDEX)\n\t\t{\n\t\t\tname = vStringNew();\n\t\t\treadM4MacroArgument(name);\n\t\t\tindex = makeM4RefTag (kind, name, role);\n\t\t}\n\t\telse if (role == M4_MACRO_ROLE_UNDEF)\n\t\t{\n\t\t\tname = vStringNew();\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tbool more = readM4MacroArgument(name);\n\t\t\t\t/* TODO: The cork indexes are thrown away here.\n\t\t\t\t   `end' field cannot be attached to multiple\n\t\t\t\t   indexes. */\n\t\t\t\tmakeM4RefTag (kind, name, role);\n\t\t\t\tvStringClear (name);\n\t\t\t\tif (more)\n\t\t\t\t\tgetcFromInputFile ();\n\t\t\t\telse\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t}\n\t}\n\telse if (kind == M4_MACROFILE_KIND)\n\t{\n\t\tname = vStringNew();\n\t\treadM4MacroArgument(name);\n\t\tindex = makeM4RefTag (kind, name, role);\n\t}\n\n\tif (name)\n\t\tvStringDelete (name);\n\n\treturn index;\n}\n\nstruct newMacroResult\n{\n\tint index;\n\tbool consumed;\n};\n\nstatic struct newMacroResult newMacroM4 (const char* token)\n{\n\tstatic langType lang = LANG_IGNORE;\n\tstruct newMacroResult result = {\n\t\t.index = CORK_NIL,\n\t\t.consumed = false,\n\t};\n\n\tint keyword;\n\tint role = ROLE_DEFINITION_INDEX;\n\tint kind = -1;\n\n\tif (lang == LANG_IGNORE)\n\t\tlang = getNamedLanguage (\"M4\", 0);\n\tkeyword = lookupKeyword (token, lang);\n\n\tswitch (keyword)\n\t{\n\tcase KEYWORD_NONE:\n\t\tbreak;\n\tcase KEYWORD_define:\n\t\tkind = M4_MACRO_KIND;\n\t\trole = ROLE_DEFINITION_INDEX;\n\t\tresult.consumed = true;\n\t\tbreak;\n\tcase KEYWORD_undefine:\n\t\tkind = M4_MACRO_KIND;\n\t\trole = M4_MACRO_ROLE_UNDEF;\n\t\tresult.consumed = true;\n\t\tbreak;\n\tcase KEYWORD_include:\n\t\tkind = M4_MACROFILE_KIND;\n\t\trole = M4_MACROFILE_ROLE_INCLUDED;\n\t\tresult.consumed = true;\n\t\tbreak;\n\tcase KEYWORD_sinclude:\n\t\tkind = M4_MACROFILE_KIND;\n\t\trole = M4_MACROFILE_ROLE_SILENTLY_INCLUDED;\n\t\tresult.consumed = true;\n\t\tbreak;\n\tcase KEYWORD_changequote:\n\t\thandleM4Changequote ();\n\t\tresult.consumed = true;\n\t\tbreak;\n\t}\n\n\tif (kind == -1)\n\t\treturn result;\n\n\tif ((! isXtagEnabled (XTAG_REFERENCE_TAGS))\n\t    && (role != ROLE_DEFINITION_INDEX))\n\t\treturn result;\n\n\tresult.index = makeM4Tag (kind, role);\n\treturn result;\n}\n\n\n/* parser instance  */\nstatic void parseM4Char (struct m4Ctx *ctx, vString *const token, int c)\n{\n\tif (doesLineCommentStart (ctx->sub, c, vStringValue (token)))\n\t\tskipLine(c);\n\telse if (doesQuoteStart (c))\n\t\tparseQuotes(ctx, token, c);\n\telse if (doesStringLiteralStart (ctx->sub, c))\n\t\tskipToCharacter(c, false);\n\telse if (c == '(' && vStringLength(token) > 0) /* catch a few macro calls */\n\t{\n\t\tstruct newMacroResult r;\n\n\t\tif (!ctx->sub)\n\t\t\tctx->sub = maySwitchLanguage (vStringValue (token));\n\n\t\tr = newMacroM4 (vStringValue (token));\n\t\tif (r.consumed)\n\t\t\tpushIndex (ctx, r.index);\n\t\telse if (ctx->sub)\n\t\t{\n\t\t\tint index = notifyNewMacro (ctx->sub, vStringValue (token));\n\t\t\tpushIndex (ctx, index);\n\t\t}\n\t}\n\n\tvStringClear(token);\n\tif (IS_WORD(c))\n\t{\n\t\tungetcToInputFile(c);\n\t\treadQuotedWord(token);\n\t}\n\telse if (c == ')')\n\t{\n\t\tsetTagEndLineToCorkEntry (topIndex (ctx),getInputLineNumber ());\n\t\tpopIndexSafe (ctx);\n\t}\n}\n\nstatic void findM4Tags(void)\n{\n\tstruct m4Ctx ctx;\n\tvString *const token = vStringNew();\n\n\tsetM4Quotes ('`', '\\'');\n\n\tctx.sub = (m4Subparser *)getSubparserRunningBaseparser();\n\tif (ctx.sub)\n\t\tchooseExclusiveSubparser ((subparser *)ctx.sub, NULL);\n\n\tctx.indexStack = intArrayNew ();\n\n\tint c;\n\twhile ((c = getcFromInputFile()) != EOF)\n\t\tparseM4Char (&ctx, token, c);\n\n\tintArrayDelete (ctx.indexStack);\n\n\tvStringDelete(token);\n}\n\nextern parserDefinition* M4Parser (void)\n{\n\tstatic const char *const extensions [] = { \"m4\",\n\t\t\t\t\t\t   \"spt\", /* used in `selinux-policy' */\n\t\t\t\t\t\t   NULL };\n\tparserDefinition* const def = parserNew(\"M4\");\n\n\tdef->kindTable = M4Kinds;\n\tdef->kindCount = ARRAY_SIZE(M4Kinds);\n\tdef->extensions = extensions;\n\tdef->parser = findM4Tags;\n\tdef->useCork = CORK_QUEUE;\n\tdef->keywordTable = m4KeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (m4KeywordTable);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/make.c",
    "content": "/*\n*   Copyright (c) 2000-2005, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for makefiles.\n*\n*   References:\n*   - https://www.gnu.org/software/make/manual/html_node/index.html\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <ctype.h>\n\n#include \"x-make.h\"\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"numarray.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"strlist.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n\n#include \"x-cpreprocessor.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_MACRO, K_TARGET, K_INCLUDE,\n} makeKind;\n\ntypedef enum {\n\tR_INCLUDE_GENERIC,\n\tR_INCLUDE_OPTIONAL,\n} makeMakefileRole;\n\nstatic roleDefinition MakeMakefileRoles [] = {\n\t{ true, \"included\", \"included\" },\n\t{ true, \"optional\", \"optionally included\"},\n};\n\nstatic kindDefinition MakeKinds [] = {\n\t{ true, 'm', \"macro\",  \"macros\"},\n\t{ true, 't', \"target\", \"targets\"},\n\t{ true, 'I', \"makefile\", \"makefiles\",\n\t  .referenceOnly = true, ATTACH_ROLES(MakeMakefileRoles)},\n};\n\ntypedef enum {\n\tX_CPP_DEF,\n} makeXtag;\n\nstatic xtagDefinition MakeXtagTable [] = {\n\t{\n\t\t.enabled = false,\n\t\t.name = \"CppDef\",\n\t\t.description = \"Include FOO in -DFOO as as a name of CPreProcessor macro\",\n\t\t.version = 1,\n\t}\n};\n\nstatic langType Lang_cpreprocessor;\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic int nextCharFull (void (* cb) (int, void *), void *cb_data)\n{\n\tint c = getcFromInputFile ();\n\tif (c != EOF && cb)\n\t\tcb (c, cb_data);\n\tif (c == '\\\\')\n\t{\n\t\tc = getcFromInputFile ();\n\t\tif (c != EOF && cb)\n\t\t\tcb (c, cb_data);\n\t\tif (c == '\\n')\n\t\t\tc = nextCharFull (cb, cb_data);\n\t}\n\treturn c;\n}\n\nstatic int nextChar (void)\n{\n\treturn nextCharFull (NULL, NULL);\n}\n\nstatic void skipLineFull (void (* cb) (int, void *), void *cb_data)\n{\n\tint c;\n\tdo\n\t{\n\t\tc = nextChar ();\n\t\tif (c == EOF)\n\t\t\tbreak;\n\t\tif (cb)\n\t\t\tcb (c, cb_data);\n\t}\n\twhile (c != '\\n');\n\tif (c == '\\n')\n\t\tungetcToInputFile (c);\n}\n\nstatic void skipLine (void)\n{\n\tskipLineFull (NULL, NULL);\n}\n\nstatic int skipToNonWhite (int c)\n{\n\twhile (c != '\\n' && isspace (c))\n\t\tc = nextChar ();\n\treturn c;\n}\n\nstatic bool isIdentifier (int c)\n{\n\treturn (bool)(c != '\\0' && (isalnum (c)  ||  strchr (\".-_/$(){}%\", c) != NULL));\n}\n\nstatic bool isSpecialTarget (vString *const name)\n{\n\tsize_t i = 0;\n\t/* All special targets begin with '.'. */\n\tif (vStringLength (name) < 1 || vStringChar (name, i++) != '.') {\n\t\treturn false;\n\t}\n\twhile (i < vStringLength (name)) {\n\t\tchar ch = vStringChar (name, i++);\n\t\tif (ch != '_' && !isupper ((unsigned char) ch))\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nstatic int makeSimpleMakeTag (vString *const name, makeKind kind, int scopeIndex)\n{\n\tif (!isLanguageEnabled (getInputLanguage ()))\n\t\treturn CORK_NIL;\n\n\ttagEntryInfo e;\n\tinitTagEntry (&e, vStringValue (name), kind);\n\te.extensionFields.scopeIndex = scopeIndex;\n\treturn makeTagEntry (&e);\n}\n\nstatic void makeSimpleMakeRefTag (const vString* const name, const int kind,\n\t\t\t\t  int roleIndex, int scopeIndex)\n{\n\tif (!isLanguageEnabled (getInputLanguage ()))\n\t\treturn;\n\n\ttagEntryInfo e;\n\tinitRefTagEntry (&e, vStringValue (name), kind, roleIndex);\n\te.extensionFields.scopeIndex = scopeIndex;\n\tmakeTagEntry (&e);\n}\n\nstatic int newTarget (vString *const name, int scopeIndex)\n{\n\t/* Ignore GNU Make's \"special targets\". */\n\tif  (isSpecialTarget (name))\n\t{\n\t\treturn CORK_NIL;\n\t}\n\treturn makeSimpleMakeTag (name, K_TARGET, scopeIndex);\n}\n\nstatic int newMacro (vString *const name, bool with_define_directive, bool appending, int scopeIndex)\n{\n\tint r = CORK_NIL;\n\tsubparser *s;\n\n\tif (!appending)\n\t\tr = makeSimpleMakeTag (name, K_MACRO, scopeIndex);\n\n\tforeachSubparser(s, false)\n\t{\n\t\tmakeSubparser *m = (makeSubparser *)s;\n\t\tenterSubparser(s);\n\t\tif (m->newMacroNotify)\n\t\t\tm->newMacroNotify (m, vStringValue(name), with_define_directive, appending, scopeIndex);\n\t\tleaveSubparser();\n\t}\n\n\treturn r;\n}\n\nstatic void valueFound (vString *const name)\n{\n\tsubparser *s;\n\tforeachSubparser(s, false)\n\t{\n\t\tmakeSubparser *m = (makeSubparser *)s;\n\t\tenterSubparser(s);\n\t\tif (m->valueNotify)\n\t\t\tm->valueNotify (m, vStringValue (name));\n\t\tleaveSubparser();\n\t}\n}\n\nstatic void directiveFound (vString *const name)\n{\n\tsubparser *s;\n\tforeachSubparser (s, false)\n\t{\n\t\tmakeSubparser *m = (makeSubparser *)s;\n\t\tenterSubparser(s);\n\t\tif (m->directiveNotify)\n\t\t\tm->directiveNotify (m, vStringValue (name));\n\t\tleaveSubparser();\n\t}\n}\n\nstatic void newInclude (vString *const name, bool optional, int scopeIndex)\n{\n\tmakeSimpleMakeRefTag (name, K_INCLUDE,\n\t\t\t      optional? R_INCLUDE_OPTIONAL: R_INCLUDE_GENERIC, scopeIndex);\n}\n\nstatic bool isAcceptableAsInclude (vString *const name)\n{\n\tif (strcmp (vStringValue (name), \"$\") == 0)\n\t\treturn false;\n\treturn true;\n}\n\n/* Return true if a newline is seen. */\nstatic void readIdentifierFull (const int first, vString *const id,\n\t\t\t\t\t\t\t\tvoid (* cb) (int, void *), void *cb_data)\n{\n\tint depth = 0;\n\tint c = first;\n\n\tif (cb)\n\t\tcb (c, cb_data);\n\n\tvStringClear (id);\n\twhile (isIdentifier (c) || (depth > 0 && c != EOF && c != '\\n'))\n\t{\n\t\tif (c == '(' || c == '{')\n\t\t\tdepth++;\n\t\telse if (depth > 0 && (c == ')' || c == '}'))\n\t\t\tdepth--;\n\t\tvStringPut (id, c);\n\t\tc = nextCharFull (cb, cb_data);\n\t}\n\tungetcToInputFile (c);\n}\n\nstatic void readIdentifier (const int first, vString *const id)\n{\n\treadIdentifierFull (first, id, NULL, NULL);\n}\n\nstatic void endTargets (intArray *targets, unsigned long lnum)\n{\n\tfor (unsigned int i = 0; i < intArrayCount (targets); i++)\n\t{\n\t\tint cork_index = intArrayItem (targets, i);\n\t\tsetTagEndLineToCorkEntry (cork_index, lnum);\n\t}\n\tintArrayClear (targets);\n}\n\nstatic bool isTheLastTargetOnTheSameLine (intArray *current_targets,\n\t\t\t\t\t\t\t\t\t\t  unsigned long line)\n{\n\tif (!intArrayIsEmpty (current_targets))\n\t{\n\t\tint r = intArrayLast (current_targets);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\t\tif (e && e->lineNumber == line)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/* valueTracker is for extracting FOO in -DFOO. */\nstruct valueTracker\n{\n\tenum {VT_LOOKING_FOR_D, VT_AFTER_D} state;\n\tvString *value;\t\t\t\t/* NULL: valueTracker is disabled. */\n\tint leftSideIndex;\n\tlangType cpp;\n};\n\nstatic vString *extractSignature (const char *input, size_t end)\n{\n\tvString *sig = vStringNewInit (\"(\");\n\tchar c = 0;\n\n\tfor (size_t j = 0; j < end; j++)\n\t{\n\t\tc = input[j];\n\t\tvStringPut (sig, c);\n\t\tif (c == ')')\n\t\t\tbreak;\n\t}\n\n\tif (c != ')')\n\t{\n\t\t/* Incomplete. */\n\t\tvStringDelete (sig);\n\t\tsig = NULL;\n\t}\n\n\treturn sig;\n}\n\nstatic void valueTrackerEval (struct valueTracker *vt)\n{\n\tif (!vt->value)\n\t\treturn;\n\n\tsize_t len = vStringLength (vt->value);\n\n\tif ((vt->state == VT_AFTER_D && len > 0) ||\n\t\t((vt->state == VT_LOOKING_FOR_D &&\n\t\t  len > 2 && strncmp(\"-D\", vStringValue (vt->value), 2) == 0)))\n\t{\n\t\tvString *d = vStringNew ();\n\t\tvString *sig = NULL;\n\t\tsize_t i0 = (vt->state == VT_AFTER_D? 0: 2);\n\t\tfor (size_t i = i0; i < len; i++)\n\t\t{\n\t\t\tint c = vStringChar (vt->value, i);\n\n\t\t\tif (c == '\\'' || c == '\"')\n\t\t\t\tcontinue;\n\t\t\tif (isspace(c) || c == '=')\n\t\t\t\tbreak;\n\n\t\t\t/* \",\" can be a separator.\n\t\t\t * -------------------------------------------------\n\t\t\t * $(filter -D__LINUX_ARM_ARCH__%, $(KBUILD_CFLAGS)) */\n\t\t\tif (c == ',')\n\t\t\t\tbreak;\n\n\t\t\tif (c == '('\n\t\t\t\t/* FOO_$(...) isn't a signature. */\n\t\t\t\t&& (i - i0 > 1) && (vStringChar (vt->value, i -1) != '$'))\n\t\t\t{\n\t\t\t\tAssert(sig == NULL);\n\t\t\t\tsig = extractSignature (vStringValue (vt->value) + i + 1, len - i + 1);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tvStringPut (d, c);\n\t\t}\n\t\tif (!vStringIsEmpty (d)\n\t\t\t&& vStringValue(d)[0] != '$' && vStringValue(d)[0] != '-')\n\t\t{\n\t\t\ttagEntryInfo e;\n\t\t\tinitForeignTagEntry (&e, vStringValue (d), vt->cpp, CPREPRO_MACRO);\n\t\t\tmarkTagExtraBit (&e, MakeXtagTable[X_CPP_DEF].xtype);\n\t\t\tif (sig)\n\t\t\t\te.extensionFields.signature = vStringValue(sig);\n\t\t\tmakeTagEntry (&e);\n\t\t}\n\t\tvStringDelete (sig);\t/* NULL is acceptable. */\n\t\tvStringDelete (d);\n\n\t\tvt->state = VT_LOOKING_FOR_D;\n\t}\n\telse if (len == 2 && strcmp(\"-D\", vStringValue (vt->value)) == 0)\n\t\tvt->state = VT_AFTER_D;\n}\n\nstatic void valueTrackerFlush (struct valueTracker *vt)\n{\n\tif (!vt->value)\n\t\treturn;\n\n\tif (vStringIsEmpty (vt->value))\n\t\treturn;\n\n\tvalueTrackerEval (vt);\n\tvStringClear (vt->value);\n\tvt->state = VT_LOOKING_FOR_D;\n}\n\nstatic void valueTrackerUpdateLeftSideIndex (struct valueTracker *vt, int corkIndex)\n{\n\tif (!vt->value)\n\t\treturn;\n\n\tif (vt->leftSideIndex != corkIndex)\n\t{\n\t\tvalueTrackerFlush (vt);\n\t\tvt->leftSideIndex = corkIndex;\n\t}\n}\n\nstatic void valueTrackerPut (struct valueTracker *vt, int c)\n{\n\tif (!vt->value)\n\t\treturn;\n\n\tif (isspace(c) || c == '\\\\'  || c == EOF)\n\t{\n\t\tif (!vStringIsEmpty (vt->value))\n\t\t{\n\t\t\tvalueTrackerEval (vt);\n\t\t\tvStringClear (vt->value);\n\t\t}\n\t\treturn;\n\t}\n\tvStringPut (vt->value, c);\n}\n\nstatic void valueTrackerPutAsCallback (int c, void *vt)\n{\n\tvalueTrackerPut ((struct valueTracker *)vt, c);\n}\n\nstatic void valueTrackerInit (struct valueTracker *vt)\n{\n\tbool enabled = isXtagEnabled (MakeXtagTable[X_CPP_DEF].xtype);\n\tvt->state = VT_LOOKING_FOR_D;\n\tvt->leftSideIndex = CORK_NIL;\n\tvt->value = enabled? vStringNew(): NULL;\n\tvt->cpp = enabled? Lang_cpreprocessor: LANG_IGNORE;\n}\n\nstatic void valueTrackerFini (struct valueTracker *vt)\n{\n\tif (!vt->value)\n\t\treturn;\n\n\tvalueTrackerFlush (vt);\n\tvStringDelete (vt->value);\n}\n\n/*\n * Naming\n *\n *   X = ...\n *\n * We refer to X as a macro or a variable macro (varmac) here.\n *\n *   define M\n *    ...\n *   endef\n *\n * We refer to M as a macro or a macro definition (macdef) here.\n */\nstatic void findMakeTags0 (void)\n{\n\t/* MAINLY for tracking the candidates of MULTIPLE targets like:\n\t *\n\t * clean distclean install:\n\t *     ...\n\t */\n\tstringList *identifiers = stringListNew ();\n\n\t/* parsing the right side of =, :=, +=, ?=, !=\n\t *\n\t * Nothing to do with targets or macdefs.\n\t */\n\tbool in_varmac_value  = false;\n\n\t/* For tracking a tag for a macdef. */\n\tint  current_macdef = CORK_NIL;\n\n\t/* For tracking tags for (multiple) targets.\n\t */\n\tintArray *current_targets = intArrayNew ();\n\n\t/* Reading char can be a part of macro name.\n\t * In the other words, we are \"not in a recipe\". */\n\tbool macro_possible = true;\n\n\t/* A char just read*/\n\tint c;\n\n\t/* '\\n' seen. */\n\tbool newline = true;\n\n\t/* += seen. */\n\tbool appending = false;\n\n\t/* Gathering uninteresting parts of input to extract -DCPP_MACRO. */\n\tstruct valueTracker value_tracker;\n\tvalueTrackerInit (&value_tracker);\n\n\twhile ((c = nextChar ()) != EOF)\n\t{\n\t\tif (newline)\n\t\t{\n\t\t\tif (!intArrayIsEmpty (current_targets))\n\t\t\t{\n\t\t\t\tif (c == '\\t' || (c = skipToNonWhite (c)) == '#')\n\t\t\t\t{\n\t\t\t\t\tvalueTrackerPut(&value_tracker, c == '\\t'? '\\t': ' ');\n\t\t\t\t\t/* skip rule or comment */\n\t\t\t\t\tif (c == '#')\n\t\t\t\t\t\tskipLine ();\n\t\t\t\t\telse\n\t\t\t\t\t\tskipLineFull (valueTrackerPutAsCallback, &value_tracker);\n\t\t\t\t\tc = nextChar ();\n\t\t\t\t}\n\t\t\t\telse if (c != '\\n')\n\t\t\t\t\tendTargets (current_targets, getInputLineNumber () - 1);\n\t\t\t}\n\t\t\telse if (in_varmac_value)\n\t\t\t\tin_varmac_value = false;\n\n\t\t\tstringListClear (identifiers);\n\t\t\tmacro_possible = intArrayIsEmpty (current_targets);\n\t\t\tnewline = false;\n\t\t}\n\t\tif (c == '\\n')\n\t\t{\n\t\t\tvalueTrackerPut (&value_tracker, '\\n');\n\t\t\tnewline = true;\n\t\t}\n\t\telse if (isspace (c))\n\t\t{\n\t\t\tvalueTrackerPut (&value_tracker, ' ');\n\t\t\tcontinue;\n\t\t}\n\t\telse if (c == '#')\n\t\t\tskipLine ();\n\t\telse if (macro_possible && (c == '?' || c == '!'))\n\t\t{\n\t\t\tc = nextChar ();\n\t\t\tungetcToInputFile (c);\n\t\t\tmacro_possible = (c == '=');\n\t\t}\n\t\telse if (macro_possible && c == '+')\n\t\t{\n\t\t\tc = nextChar ();\n\t\t\tungetcToInputFile (c);\n\t\t\tmacro_possible = (c == '=');\n\t\t\tappending = true;\n\t\t}\n\t\telse if ((! in_varmac_value) && macro_possible && c == ':' &&\n\t\t\t\t stringListCount (identifiers) > 0)\n\t\t{\n\t\t\tc = nextChar ();\n\t\t\tungetcToInputFile (c);\n\t\t\tif (c != '=')\n\t\t\t{\n\t\t\t\tunsigned int i;\n\t\t\t\tfor (i = 0; i < stringListCount (identifiers); i++)\n\t\t\t\t{\n\t\t\t\t\tint r = newTarget (stringListItem (identifiers, i), current_macdef);\n\t\t\t\t\tif (r != CORK_NIL)\n\t\t\t\t\t{\n\t\t\t\t\t\tintArrayAdd (current_targets, r);\n\t\t\t\t\t\tvalueTrackerUpdateLeftSideIndex (&value_tracker, r);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstringListClear (identifiers);\n\t\t\t}\n\t\t}\n\t\telse if (macro_possible && c == '=' &&\n\t\t\t\t stringListCount (identifiers) > 0\n\t\t\t\t && !in_varmac_value)\n\t\t{\n\t\t\tint r = newMacro (stringListItem (identifiers, 0), false, appending, current_macdef);\n\t\t\tvalueTrackerUpdateLeftSideIndex (&value_tracker, r);\n\t\t\tstringListClear (identifiers);\n\n\t\t\tin_varmac_value = true;\n\t\t\tunsigned long curline = getInputLineNumber ();\n\t\t\tunsigned long adj = isTheLastTargetOnTheSameLine (current_targets,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  curline)? 0: 1;\n\t\t\tendTargets (current_targets, curline - adj);\n\t\t\tappending = false;\n\t\t}\n\t\telse if (macro_possible && isIdentifier (c))\n\t\t{\n\t\t\tvString *name = vStringNew ();\n\t\t\treadIdentifierFull (c, name,\n\t\t\t\t\t\t\t\tvalueTrackerPutAsCallback, &value_tracker);\n\t\t\tstringListAdd (identifiers, name);\n\n\t\t\tif (in_varmac_value)\n\t\t\t\tvalueFound(name);\n\n\t\t\tif (stringListCount (identifiers) == 1)\n\t\t\t{\n\t\t\t\tif ((current_macdef != CORK_NIL) && ! strcmp (vStringValue (name), \"endef\"))\n\t\t\t\t{\n\t\t\t\t\tsetTagEndLineToCorkEntry (current_macdef, getInputLineNumber ());\n\t\t\t\t\tcurrent_macdef = CORK_NIL;\n\t\t\t\t\tstringListClear (identifiers);\n\t\t\t\t}\n\t\t\t\telse if (in_varmac_value && current_macdef != CORK_NIL)\n\t\t\t\t\tskipLineFull (valueTrackerPutAsCallback, &value_tracker);\n\t\t\t\telse if (! strcmp (vStringValue (name), \"define\"))\n\t\t\t\t{\n\t\t\t\t\tc = skipToNonWhite (nextChar ());\n\t\t\t\t\tvStringClear (name);\n\t\t\t\t\t/* all remaining characters on the line are the name -- even spaces */\n\t\t\t\t\twhile (c != EOF && c != '\\n')\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringPut (name, c);\n\t\t\t\t\t\tc = nextChar ();\n\t\t\t\t\t}\n\t\t\t\t\tif (c == '\\n')\n\t\t\t\t\t\tungetcToInputFile (c);\n\t\t\t\t\tvStringStripTrailing (name);\n\n\t\t\t\t\tcurrent_macdef = newMacro (name, true, false, CORK_NIL);\n\t\t\t\t\tstringListClear (identifiers);\n\t\t\t\t\tvalueTrackerUpdateLeftSideIndex (&value_tracker, current_macdef);\n\t\t\t\t}\n\t\t\t\telse if (! strcmp (vStringValue (name), \"export\")\n\t\t\t\t\t\t || ! strcmp (vStringValue (name), \"override\"))\n\t\t\t\t\tstringListClear (identifiers);\n\t\t\t\telse if (! strcmp (vStringValue (name), \"include\")\n\t\t\t\t\t || ! strcmp (vStringValue (name), \"sinclude\")\n\t\t\t\t\t || ! strcmp (vStringValue (name), \"-include\"))\n\t\t\t\t{\n\t\t\t\t\tbool optional = (vStringValue (name)[0] == 'i')? false: true;\n\t\t\t\t\twhile (1)\n\t\t\t\t\t{\n\t\t\t\t\t\tc = skipToNonWhite (nextChar ());\n\t\t\t\t\t\treadIdentifier (c, name);\n\t\t\t\t\t\tvStringStripTrailing (name);\n\t\t\t\t\t\tif (!vStringIsEmpty (name) && isAcceptableAsInclude(name))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnewInclude (name, optional, current_macdef);\n\t\t\t\t\t\t\tvalueTrackerUpdateLeftSideIndex (&value_tracker, CORK_NIL);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t/* non-space characters after readIdentifier() may\n\t\t\t\t\t\t * be rejected by the function:\n\t\t\t\t\t\t * e.g.\n\t\t\t\t\t\t * include $*\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * Here, remove such characters from input stream.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tdo\n\t\t\t\t\t\t\tc = nextChar ();\n\t\t\t\t\t\twhile (c != EOF && c != '\\n' && (!isspace (c)));\n\t\t\t\t\t\tif (c == '\\n')\n\t\t\t\t\t\t\tungetcToInputFile (c);\n\n\t\t\t\t\t\tif (c == EOF || c == '\\n')\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tstringListClear (identifiers);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tdirectiveFound (name);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvalueTrackerPut (&value_tracker, c);\n\t\t\tmacro_possible = false;\n\t\t}\n\t}\n\n\tendTargets (current_targets, getInputLineNumber ());\n\n\tvalueTrackerFini (&value_tracker);\n\n\tintArrayDelete (current_targets);\n\tstringListDelete (identifiers);\n}\n\nstatic void findMakeTags (void)\n{\n\n\tsubparser *sub = getSubparserRunningBaseparser();\n\tif (sub)\n\t\tchooseExclusiveSubparser (sub, NULL);\n\n\tfindMakeTags0 ();\n}\n\nextern parserDefinition* MakefileParser (void)\n{\n\tstatic const char *const patterns [] = { \"[Mm]akefile\", \"GNUmakefile\", NULL };\n\tstatic const char *const extensions [] = { \"mak\", \"mk\", NULL };\n\tstatic const char *const aliases [] = {\n\t\t/* the mode names defined in make-mode.el in GNU Emacs */\n\t\t\"makefile\",\n\t\t\"makefile-gmake\",\n\t\tNULL };\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_FOREIGNER, \"CPreProcessor\", &Lang_cpreprocessor },\n\t};\n\n\tparserDefinition* const def = parserNew (\"Make\");\n\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\n\tdef->kindTable      = MakeKinds;\n\tdef->kindCount  = ARRAY_SIZE (MakeKinds);\n\tdef->patterns   = patterns;\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\tdef->xtagTable = MakeXtagTable;\n\tdef->xtagCount = ARRAY_SIZE (MakeXtagTable);\n\tdef->parser     = findMakeTags;\n\tdef->useCork = CORK_QUEUE;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/markdown.c",
    "content": "/*\n *\n *  Copyright (c) 2007-2011, Nick Treleaven\n *  Copyright (c) 2012, Lex Trotman\n *  Copyright (c) 2021, Jiri Techet\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n * This module contains functions for generating tags for markdown files.\n *\n * This parser was based on the asciidoc parser.\n *\n * Extended syntax like footnotes is described in\n * https://www.markdownguide.org/extended-syntax/\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n\n#include <ctype.h>\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"utf8_str.h\"\n#include \"nestlevel.h\"\n#include \"routines.h\"\n#include \"promise.h\"\n#include \"htable.h\"\n\n#include \"x-markdown.h\"\n\n/*\n *   DATA DEFINITIONS\n */\ntypedef enum {\n\tK_CHAPTER = 0,\n\tK_SECTION,\n\tK_SUBSECTION,\n\tK_SUBSUBSECTION,\n\tK_LEVEL4SECTION,\n\tK_LEVEL5SECTION,\n\tK_SECTION_COUNT,\n\tK_FOOTNOTE = K_SECTION_COUNT,\n\tK_HASHTAG,\n} markdownKind;\n\nstatic kindDefinition MarkdownKinds[] = {\n\t{ true, 'c', \"chapter\",       \"chapters\"},\n\t{ true, 's', \"section\",       \"sections\" },\n\t{ true, 'S', \"subsection\",    \"level 2 sections\" },\n\t{ true, 't', \"subsubsection\", \"level 3 sections\" },\n\t{ true, 'T', \"l4subsection\",  \"level 4 sections\" },\n\t{ true, 'u', \"l5subsection\",  \"level 5 sections\" },\n\t{ true, 'n', \"footnote\",      \"footnotes\" },\n\t{ true, 'h', \"hashtag\",       \"hashtags\",\n\t  .version = 1 },\n};\n\nstatic fieldDefinition MarkdownFields [] = {\n\t{\n\t  .enabled     = false,\n\t  .name        = \"sectionMarker\",\n\t  .description = \"character used for declaring section(#, ##, =, or -)\",\n\t},\n};\n\ntypedef enum {\n\tF_MARKER,\n} markdownField;\n\nstatic NestingLevels *nestingLevels = NULL;\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic NestingLevel *getNestingLevel (const int kind, unsigned long adjustmentWhenPop)\n{\n\tNestingLevel *nl;\n\ttagEntryInfo *e;\n\tunsigned long line = getInputLineNumber ();\n\n\tline = (line > adjustmentWhenPop)? (line - adjustmentWhenPop): 0;\n\n\twhile (1)\n\t{\n\t\tnl = nestingLevelsGetCurrent (nestingLevels);\n\t\te = getEntryOfNestingLevel (nl);\n\t\tif ((nl && (e == NULL)) || (e && (e->kindIndex >= kind)))\n\t\t\tnestingLevelsPopFull (nestingLevels, HT_UINT_TO_PTR ((unsigned int)line));\n\t\telse\n\t\t\tbreak;\n\t}\n\treturn nl;\n}\n\n\nstatic int makeMarkdownTag (const vString* const name, const int kind, const bool twoLine)\n{\n\tint r = CORK_NIL;\n\n\tif (vStringLength (name) > 0)\n\t{\n\t\tconst NestingLevel *const nl = getNestingLevel (kind, twoLine? 2: 1);\n\t\ttagEntryInfo *parent = getEntryOfNestingLevel (nl);\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry (&e, vStringValue (name), kind);\n\n\t\tif (twoLine)\n\t\t{\n\t\t\t/* we want the line before the '---' underline chars */\n\t\t\tAssert (e.lineNumber > 1);\n\t\t\tif (e.lineNumber > 1)\n\t\t\t{\n\t\t\t\tunsigned long lineNumber = e.lineNumber - 1;\n\t\t\t\tupdateTagLine (&e, lineNumber, getInputFilePositionForLine (lineNumber));\n\t\t\t}\n\t\t}\n\n\t\tif (parent && (parent->kindIndex < kind))\n\t\t\te.extensionFields.scopeIndex = nl->corkIndex;\n\n\t\tr = makeTagEntry (&e);\n\t}\n\treturn r;\n}\n\n\nstatic int makeSectionMarkdownTag (const vString* const name, const int kind, const char *marker)\n{\n\tint r = makeMarkdownTag (name, kind, marker[0] != '#');\n\tattachParserFieldToCorkEntry (r, MarkdownFields [F_MARKER].ftype, marker);\n\n\tnestingLevelsPush (nestingLevels, r);\n\treturn r;\n}\n\n\nstatic vString *getHeading (const int kind, const unsigned char *line,\n\tconst int lineLen, bool *delimited)\n{\n\tint pos = 0;\n\tint start = kind + 1;\n\tint end = lineLen - 1;\n\tvString *name = vStringNew ();\n\n\tAssert (kind >= 0 && kind < K_SECTION_COUNT);\n\tAssert (lineLen > start);\n\n\t*delimited = false;\n\twhile (isspace (line[pos])) ++pos;\n\twhile (line[end] == line[pos] && end - 1 >= 0 && line[end - 1] != '\\\\')\n\t{\n\t\t--end;\n\t\t*delimited = true;\n\t}\n\twhile (isspace (line[start])) ++start;\n\twhile (isspace (line[end])) --end;\n\n\tif (start <= end)\n\t\tvStringNCatS (name, (const char*)(&(line[start])), end - start + 1);\n\n\treturn name;\n}\n\n\nstatic int getFirstCharPos (const unsigned char *line, int lineLen, bool *indented)\n{\n\tint indent = 0;\n\tint i;\n\tfor (i = 0; i < lineLen && isspace (line[i]); i++)\n\t\tindent += line[i] == '\\t' ? 4 : 1;\n\t*indented = indent >= 4;\n\treturn i;\n}\n\n\nstatic void fillEndField (NestingLevel *nl, void *ctxData)\n{\n\ttagEntryInfo *e = getEntryOfNestingLevel (nl);\n\tif (e)\n\t{\n\t\tunsigned long line = (unsigned long)(HT_PTR_TO_UINT (ctxData));\n\t\tsetTagEndLine (e, line);\n\t}\n}\n\nstatic void getFootnoteMaybe (const char *line)\n{\n\tconst char *start = strstr (line, \"[^\");\n\tconst char *end = start? strstr(start + 2, \"]:\"): NULL;\n\n\tif (! (start && end))\n\t\treturn;\n\tif (! (end > (start + 2)))\n\t\treturn;\n\n\tvString * footnote = vStringNewNInit (start + 2, end - (start + 2));\n\tconst NestingLevel *const nl = nestingLevelsGetCurrent (nestingLevels);\n\ttagEntryInfo e;\n\n\tinitTagEntry (&e, vStringValue (footnote), K_FOOTNOTE);\n\tif (nl)\n\t\te.extensionFields.scopeIndex = nl->corkIndex;\n\tmakeTagEntry (&e);\n\n\tvStringDelete (footnote);\n}\n\nstatic markdownSubparser * extractLanguageForCodeBlock (const char *langMarker,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvString *codeLang)\n{\n\tsubparser *s = NULL;\n\tbool b = false;\n\tmarkdownSubparser *r = NULL;\n\n\tforeachSubparser (s, false)\n\t{\n\t\tmarkdownSubparser *m = (markdownSubparser *)s;\n\t\tenterSubparser(s);\n\t\tif (m->extractLanguageForCodeBlock)\n\t\t\tb = m->extractLanguageForCodeBlock (m, langMarker, codeLang);\n\t\tleaveSubparser();\n\t\tif (b)\n\t\t{\n\t\t\tr = m;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn r;\n}\n\nstatic void notifyCodeBlockLine (markdownSubparser *m, const unsigned char *line)\n{\n\tsubparser *s = (subparser *)m;\n\tif (m->notifyCodeBlockLine)\n\t{\n\t\tenterSubparser(s);\n\t\tm->notifyCodeBlockLine (m, line);\n\t\tleaveSubparser();\n\t}\n}\n\nstatic void notifyEndOfCodeBlock (markdownSubparser *m)\n{\n\tsubparser *s = (subparser *)m;\n\n\tif (m->notifyEndOfCodeBlock)\n\t{\n\t\tenterSubparser(s);\n\t\tm->notifyEndOfCodeBlock (m);\n\t\tleaveSubparser();\n\t}\n}\n\ntypedef enum {\n\tHTAG_SPACE_FOUND,\n\tHTAG_HASHTAG_FOUND,\n\tHTAG_TEXT,\n} hashtagState;\n\n/*\n   State machine to find all hashtags in a line.\n */\nstatic void getAllHashTagsInLineMaybe (const unsigned char *line, int pos,\n\tint lineLen, hashtagState state)\n{\n\twhile (pos < lineLen)\n\t{\n\t\tswitch (state)\n\t\t{\n\t\tcase HTAG_SPACE_FOUND:\n\t\t\tif (line[pos] == '#')\n\t\t\t{\n\t\t\t\tstate = HTAG_HASHTAG_FOUND;\n\t\t\t}\n\t\t\telse if (!isspace (line[pos]))\n\t\t\t\tstate = HTAG_TEXT;\n\t\t\tpos++;\n\t\t\tbreak;\n\t\tcase HTAG_HASHTAG_FOUND:\n\t\t{\n\t\t\t/* `#123` is invalid */\n\t\t\tbool hasNonNumericalChar = false;\n\n\t\t\tconst int hashtag_start = pos;\n\t\t\twhile (pos < lineLen)\n\t\t\t{\n\t\t\t\tint utf8_len;\n\t\t\t\tif (isalpha (line[pos])\n\t\t\t\t\t|| line[pos] == '_' || line[pos] == '-' || line[pos] == '/')\n\t\t\t\t{\n\t\t\t\t\thasNonNumericalChar = true;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\telse if (isdigit (line[pos]))\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\telse if ((utf8_len =\n\t\t\t\t\t\tutf8_raw_strlen ((const char *) &line[pos],\n\t\t\t\t\t\t\tlineLen - pos)) > 0)\n\t\t\t\t{\n\t\t\t\t\thasNonNumericalChar = true;\n\t\t\t\t\tpos += utf8_len;\n\t\t\t\t\tAssert (pos <= lineLen);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tint hashtag_length = pos - hashtag_start;\n\t\t\tif (hasNonNumericalChar && hashtag_length > 0)\n\t\t\t{\n\t\t\t\tvString *tag =\n\t\t\t\t\tvStringNewNInit ((const char *) (&(line[hashtag_start])), hashtag_length);\n\t\t\t\tmakeMarkdownTag (tag, K_HASHTAG, false);\n\t\t\t\tvStringDelete (tag);\n\t\t\t}\n\n\t\t\tif (pos < lineLen)\n\t\t\t{\n\t\t\t\tif (isspace (line[pos]))\n\t\t\t\t\tstate = HTAG_SPACE_FOUND;\n\t\t\t\telse\n\t\t\t\t\tstate = HTAG_TEXT;\n\t\t\t}\n\t\t}\n\t\t\tbreak;\n\t\tcase HTAG_TEXT:\n\t\t\twhile (pos < lineLen && !isspace (line[pos]))\n\t\t\t\tpos++;\n\t\t\tstate = HTAG_SPACE_FOUND;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic void findMarkdownTags (void)\n{\n\tvString *prevLine = vStringNew ();\n\tvString *codeLang = vStringNew ();\n\tconst unsigned char *line;\n\tchar inCodeChar = 0;\n\tlong startSourceLineNumber = 0;\n\tlong startLineNumber = 0;\n\tbool inPreambule = false;\n\tbool inComment = false;\n\n\tsubparser *sub = getSubparserRunningBaseparser();\n\tif (sub)\n\t\tchooseExclusiveSubparser (sub, NULL);\n\n\tnestingLevels = nestingLevelsNewFull (0, fillEndField);\n\n\tmarkdownSubparser *marksub = NULL;\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tint lineLen = strlen ((const char*) line);\n\t\tbool lineProcessed = false;\n\t\tbool indented;\n\t\tint pos = getFirstCharPos (line, lineLen, &indented);\n\t\tconst int lineNum = getInputLineNumber ();\n\n\t\tif (lineNum == 1 || inPreambule)\n\t\t{\n\t\t\tif ((line[pos] == '-' && line[pos + 1] == '-' && line[pos + 2] == '-')\n\t\t\t\t|| ( /* Yaml uses \"...\" as the end of a document.\n\t\t\t\t\t  * See https://yaml.org/spec/1.2.2/#22-structures */\n\t\t\t\t\tinPreambule &&\n\t\t\t\t\t(line[pos] == '.' && line[pos + 1] == '.' && line[pos + 2] == '.')))\n\t\t\t{\n\t\t\t\tif (inPreambule)\n\t\t\t\t{\n\t\t\t\t\tlong endLineNumber = lineNum;\n\t\t\t\t\tif (startLineNumber < endLineNumber)\n\t\t\t\t\t\tmakePromise (\"FrontMatter\", startLineNumber, 0,\n\t\t\t\t\t\t\t\t\t endLineNumber, 0, startSourceLineNumber);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tstartSourceLineNumber = startLineNumber = lineNum;\n\t\t\t\tinPreambule = !inPreambule;\n\t\t\t}\n\t\t}\n\n\t\tif (inPreambule)\n\t\t\tcontinue;\n\n\t\t/* fenced code block */\n\t\tif (line[pos] == '`' || line[pos] == '~')\n\t\t{\n\t\t\tchar c = line[pos];\n\t\t\tchar otherC = c == '`' ? '~' : '`';\n\t\t\tint nSame;\n\t\t\tfor (nSame = 1; line[nSame + pos] == line[pos]; ++nSame);\n\n\t\t\tif (inCodeChar != otherC && nSame >= 3)\n\t\t\t{\n\t\t\t\tinCodeChar = inCodeChar ? 0 : c;\n\t\t\t\tif (inCodeChar == c && strstr ((const char *)(line + pos + nSame), \"```\") != NULL)\n\t\t\t\t\tinCodeChar = 0;\n\t\t\t\telse if (inCodeChar)\n\t\t\t\t{\n\t\t\t\t\tconst char *langMarker = (const char *)(line + pos + nSame);\n\t\t\t\t\tstartLineNumber = startSourceLineNumber = lineNum + 1;\n\n\t\t\t\t\tvStringClear (codeLang);\n\t\t\t\t\tmarksub = extractLanguageForCodeBlock (langMarker, codeLang);\n\t\t\t\t\tif (! marksub)\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringCopyS (codeLang, langMarker);\n\t\t\t\t\t\tvStringStripLeading (codeLang);\n\t\t\t\t\t\tvStringStripTrailing (codeLang);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlong endLineNumber = lineNum;\n\t\t\t\t\tif (vStringLength (codeLang) > 0\n\t\t\t\t\t\t&& startLineNumber < endLineNumber)\n\t\t\t\t\t\tmakePromise (vStringValue (codeLang), startLineNumber, 0,\n\t\t\t\t\t\t\t\t\t endLineNumber, 0, startSourceLineNumber);\n\t\t\t\t\tif (marksub)\n\t\t\t\t\t{\n\t\t\t\t\t\tnotifyEndOfCodeBlock(marksub);\n\t\t\t\t\t\tmarksub = NULL;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlineProcessed = true;\n\t\t\t}\n\t\t}\n\t\t/* XML comment start */\n\t\telse if (lineLen >= pos + 4 && line[pos] == '<' && line[pos + 1] == '!' &&\n\t\t\tline[pos + 2] == '-' && line[pos + 3] == '-')\n\t\t{\n\t\t\tif (strstr ((const char *)(line + pos + 4), \"-->\") == NULL)\n\t\t\t\tinComment = true;\n\t\t\tlineProcessed = true;\n\t\t}\n\t\t/* XML comment end */\n\t\telse if (inComment && strstr ((const char *)(line + pos), \"-->\"))\n\t\t{\n\t\t\tinComment = false;\n\t\t\tlineProcessed = true;\n\t\t}\n\n\t\tif (marksub)\n\t\t\tnotifyCodeBlockLine (marksub, line);\n\n\t\t/* code block or comment */\n\t\tif (inCodeChar || inComment)\n\t\t\tlineProcessed = true;\n\n\t\t/* code block using indent */\n\t\telse if (indented)\n\t\t\tlineProcessed = true;\n\n\t\t/* if it's a title underline, or a delimited block marking character */\n\t\telse if (line[pos] == '=' || line[pos] == '-' || line[pos] == '#' || line[pos] == '>')\n\t\t{\n\t\t\t/* hashtags may follow the title or quote */\n\t\t\tgetAllHashTagsInLineMaybe(line, pos, lineLen, line[pos] == '#' ? HTAG_SPACE_FOUND :HTAG_TEXT);\n\t\t\tint nSame;\n\t\t\tfor (nSame = 1; line[pos + nSame] == line[pos]; ++nSame);\n\n\t\t\t/* quote */\n\t\t\tif (line[pos] == '>')\n\t\t\t\t;  /* just to make sure lineProcessed = true so it won't be in a heading */\n\t\t\t/* is it a two line title */\n\t\t\telse if (line[pos] == '=' || line[pos] == '-')\n\t\t\t{\n\t\t\t\tchar marker[2] = { line[pos], '\\0' };\n\t\t\t\tint kind = line[pos] == '=' ? K_CHAPTER : K_SECTION;\n\t\t\t\tbool whitespaceTerminated = true;\n\n\t\t\t\tfor (int i = pos + nSame; i < lineLen; i++)\n\t\t\t\t{\n\t\t\t\t\tif (!isspace (line[i]))\n\t\t\t\t\t{\n\t\t\t\t\t\twhitespaceTerminated = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvStringStripLeading (prevLine);\n\t\t\t\tvStringStripTrailing (prevLine);\n\t\t\t\tif (whitespaceTerminated && vStringLength (prevLine) > 0)\n\t\t\t\t\tmakeSectionMarkdownTag (prevLine, kind, marker);\n\t\t\t}\n\t\t\t/* otherwise is it a one line title */\n\t\t\telse if (line[pos] == '#' && nSame <= K_SECTION_COUNT && isspace (line[pos + nSame]))\n\t\t\t{\n\t\t\t\tint kind = nSame - 1;\n\t\t\t\tbool delimited = false;\n\t\t\t\tvString *name = getHeading (kind, line + pos, lineLen - pos, &delimited);\n\t\t\t\tif (vStringLength (name) > 0)\n\t\t\t\t\tmakeSectionMarkdownTag (name, kind, delimited ? \"##\" : \"#\");\n\t\t\t\tvStringDelete (name);\n\t\t\t}\n\n\t\t\tlineProcessed = true;\n\t\t}\n\n\t\tvStringClear (prevLine);\n\t\tif (!lineProcessed)\n\t\t{\n\t\t\tgetAllHashTagsInLineMaybe(line, pos, lineLen, HTAG_SPACE_FOUND);\n\t\t\tgetFootnoteMaybe ((const char *)line);\n\t\t\tvStringCatS (prevLine, (const char*) line);\n\t\t}\n\t}\n\tvStringDelete (prevLine);\n\tvStringDelete (codeLang);\n\t{\n\t\tunsigned int line = (unsigned int)getInputLineNumber ();\n\t\tnestingLevelsFreeFull (nestingLevels, HT_UINT_TO_PTR (line));\n\t}\n}\n\nextern parserDefinition* MarkdownParser (void)\n{\n\tparserDefinition* const def = parserNew (\"Markdown\");\n\tstatic const char *const extensions [] = { \"md\", \"markdown\", NULL };\n\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\n\tdef->enabled  = true;\n\tdef->extensions = extensions;\n\tdef->useCork = CORK_QUEUE;\n\tdef->kindTable = MarkdownKinds;\n\tdef->kindCount = ARRAY_SIZE (MarkdownKinds);\n\tdef->fieldTable = MarkdownFields;\n\tdef->fieldCount = ARRAY_SIZE (MarkdownFields);\n\tdef->defaultScopeSeparator = \"\\\"\\\"\";\n\tdef->parser = findMarkdownTags;\n\n\t/*\n\t * This setting (useMemoryStreamInput) is for running\n\t * Yaml parser from YamlFrontMatter as subparser.\n\t * YamlFrontMatter is run from FrontMatter as a geust parser.\n\t * FrontMatter is run from Markdown as a guest parser.\n\t * This stacked structure hits the limitation of the main\n\t * part: subparser's requirement for memory based input stream\n\t * is not propagated to the main part.\n\t *\n\t * TODO: instead of setting useMemoryStreamInput here, we\n\t * should remove the limitation.\n\t */\n\tdef->useMemoryStreamInput = true;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/matlab.c",
    "content": "/*\r\n*   Copyright (c) 2008, David Fishburn\r\n*\r\n*   This source code is released for free distribution under the terms of the\r\n*   GNU General Public License version 2 or (at your option) any later version.\r\n*\r\n*   This module contains functions for generating tags for MATLAB language files.\r\n*/\r\n\r\n/*\r\n*   INCLUDE FILES\r\n*/\r\n#include \"general.h\"  /* must always come first */\r\n\r\n#include <string.h>\r\n#include \"parse.h\"\r\n#include \"routines.h\"\r\n#include \"selectors.h\"\r\n\r\nstatic tagRegexTable matlabTagRegexTable [] = {\r\n\t/* function [x,y,z] = asdf */\r\n\t{ \"^[ \\t]*function[ \\t]+\\\\[.*\\\\][ \\t]*=[ \\t]*([.a-zA-Z0-9_]+)\",\r\n\t  \"\\\\1\", \"f,function\", NULL},\r\n\t/* function x = asdf */\r\n\t{\"^[ \\t]*function[ \\t]+[a-zA-Z0-9_]+[ \\t]*=[ \\t]*([.a-zA-Z0-9_]+)\",\r\n\t \"\\\\1\", \"f,function\", NULL},\r\n\t/* function asdf\r\n\t * function asdf % some comment */\r\n\t{\"^[ \\t]*function[ \\t]+([.a-zA-Z0-9_]+)[^=%]*($|%)\", \"\\\\1\",\r\n\t \"f,function\", NULL},\r\n\t/* variables */\r\n\t{\"^[ \\t]*([a-zA-Z0-9_]+)[ \\t]*=[ \\t]\", \"\\\\1\",\r\n\t \"v,variable\", NULL},\r\n\t/* class definitions */\r\n\t{\"^[ \\t]*classdef[ \\t]+([a-zA-Z0-9_]+)\", \"\\\\1\",\r\n\t \"c,class\", NULL},\r\n};\r\n\r\n/*\r\n*   FUNCTION DEFINITIONS\r\n*/\r\nextern parserDefinition* MatLabParser (void)\r\n{\r\n\tstatic const char *const extensions [] = { \"m\", NULL };\r\n\tstatic selectLanguage selectors [] = { selectByObjectiveCAndMatLabKeywords,\r\n\t\t\t\t\t       NULL };\r\n\tparserDefinition* const def = parserNew (\"MatLab\");\r\n\tdef->extensions = extensions;\r\n\tdef->tagRegexTable = matlabTagRegexTable;\r\n\tdef->tagRegexCount = ARRAY_SIZE (matlabTagRegexTable);\r\n\tdef->method     = METHOD_NOT_CRAFTED|METHOD_REGEX;\r\n\tdef->selectLanguage = selectors;\r\n\treturn def;\r\n}\r\n"
  },
  {
    "path": "parsers/maven2.c",
    "content": "/*\n *\n *   Copyright (c) 2016, Masatake YAMATO\n *   Copyright (c) 2016, Red Hat, K.K.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for maven2 project model\n *   defined in http://maven.apache.org/POM/4.0.0,\n *              http://maven.apache.org/maven-v4_0_0.xsd.\n */\n\n#include \"general.h\"\t/* must always come first */\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"x-xml.h\"\n\n#include <string.h>\n\ntypedef enum {\n\tK_GROUP_ID, K_ARTIFACT_ID, K_PROPERTY, K_REPOSITORY_ID\n} maven2Kind;\n\ntypedef enum {\n\tR_GROUP_ID_PARENT,\n\tR_GROUP_ID_DEPENDENCY,\n} maven2GroupIdRole;\n\ntypedef enum {\n\tR_ARTIFACT_ID_PARENT,\n\tR_ARTIFACT_ID_DEPENDENCY,\n} maven2ArtifactIdRole;\n\nstatic roleDefinition Maven2GroupIdRoles [] = {\n\t{ true, \"parent\", \"parent\" },\n\t{ true, \"dependency\", \"dependency\" },\n};\n\nstatic roleDefinition Maven2ArtifactIdRoles [] = {\n\t{ true, \"parent\", \"parent\" },\n\t{ true, \"dependency\", \"dependency\" },\n};\n\nstatic kindDefinition Maven2Kinds [] = {\n\t{ true,  'g', \"groupId\",    \"group identifiers\",\n\t  .referenceOnly = false, ATTACH_ROLES (Maven2GroupIdRoles) },\n\t{ true,  'a', \"artifactId\", \"artifact identifiers\",\n\t  .referenceOnly = false, ATTACH_ROLES (Maven2ArtifactIdRoles) },\n\t{ true,  'p', \"property\",   \"properties\" },\n\t{ true,  'r', \"repositoryId\", \"repository identifiers\" },\n};\n\nstatic void makeTagWithScope (xmlNode *node,\n\t\t\t      const char *xpath,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec,\n\t\t\t      struct sTagEntryInfo *tag,\n\t\t\t      void *userData);\n\nstatic void makeTagRecursively (xmlNode *node,\n\t\t\t    const char *xpath,\n\t\t\t\tconst struct sTagXpathRecurSpec *spec,\n\t\t\t\txmlXPathContext *ctx,\n\t\t\t\tvoid *userData);\n\nstatic void makeTagForProperties (xmlNode *node,\n\t\t\t      const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\t  const struct sTagXpathRecurSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t\t  xmlXPathContext *ctx CTAGS_ATTR_UNUSED,\n\t\t\t\t  void *userData CTAGS_ATTR_UNUSED)\n{\n\tconst xmlChar* str;\n\ttagEntryInfo tag;\n\n\tstr = node->name;\n\tinitTagEntry (&tag, (char *)str, K_PROPERTY);\n\n\tunsigned long lineNumber = xmlGetLineNo (node);\n\tupdateTagLine (&tag, lineNumber, getInputFilePositionForLine (lineNumber));\n\n\tmakeTagEntry (&tag);\n}\n\n\nenum maven2XpathTable {\n\tTABLE_MAIN,\n\tTABLE_PARENT,\n\tTABLE_DEPEDENCY,\n};\n\nstatic tagXpathTable maven2XpathMainTable[] = {\n\t{ \"/*[local-name()='project']/*[local-name()='groupId']\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_GROUP_ID, ROLE_DEFINITION_INDEX,\n\t\t\t     makeTagWithScope } }\n\t},\n\t{ \"/*[local-name()='project']/*[local-name()='parent']\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { makeTagRecursively, TABLE_PARENT } }\n\t},\n\t{ \"/*[local-name()='project']/*[local-name()='dependencies']/*[local-name()='dependency']\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { makeTagRecursively, TABLE_DEPEDENCY } }\n\t},\n\t{ \"/*[local-name()='project']/*[local-name()='artifactId']\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_ARTIFACT_ID, ROLE_DEFINITION_INDEX,\n\t\t\t     makeTagWithScope } }\n\t},\n\t{ \"/*[local-name()='project']/*[local-name()='properties']/*\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { makeTagForProperties } }\n\t},\n\t{ \"/*[local-name()='project']/*[local-name()='repositories']/*[local-name()='repository']/*[local-name()='id']\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_REPOSITORY_ID, ROLE_DEFINITION_INDEX, } }\n\t},\n};\n\nstatic tagXpathTable maven2XpathParentTable[] = {\n\t{ \"./*[local-name()='groupId']\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_GROUP_ID, R_GROUP_ID_PARENT,\n\t\t\t     makeTagWithScope } }\n\t},\n\t{ \"./*[local-name()='artifactId']\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_ARTIFACT_ID, R_ARTIFACT_ID_PARENT,\n\t\t\t     makeTagWithScope } }\n\t},\n};\n\nstatic tagXpathTable maven2XpathDependencyTable[] = {\n\t{ \"./*[local-name()='groupId']\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_GROUP_ID, R_GROUP_ID_DEPENDENCY,\n\t\t\t     makeTagWithScope } }\n\t},\n\t{ \"./*[local-name()='artifactId']\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_ARTIFACT_ID, R_ARTIFACT_ID_DEPENDENCY,\n\t\t\t     makeTagWithScope } }\n\t},\n};\n\nstatic tagXpathTableTable maven2XpathTableTable[] = {\n\t[TABLE_MAIN] = { ARRAY_AND_SIZE(maven2XpathMainTable) },\n\t[TABLE_PARENT] = { ARRAY_AND_SIZE(maven2XpathParentTable) },\n\t[TABLE_DEPEDENCY] = { ARRAY_AND_SIZE(maven2XpathDependencyTable) },\n};\n\ntypedef enum {\n\tF_VERSION,\n} maven2Field;\n\nstatic fieldDefinition Maven2Fields [] = {\n\t{\n\t\t.name = \"version\",\n\t\t.description = \"version of artifact\",\n\t\t.enabled = false,\n\t}\n};\n\nstatic char* attachVersionIfExisting (struct sTagEntryInfo *tag, xmlNode *node)\n{\n\tchar *version = NULL;\n\n\tfor (node = node->next; node != NULL; node = node->next)\n\t{\n\t\tif (strcmp ((char *)node->name, \"version\") == 0)\n\t\t{\n\t\t\tversion = (char *)xmlNodeGetContent (node);\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (version)\n\t\tattachParserField (tag, Maven2Fields [F_VERSION].ftype, version);\n\treturn version;\n}\n\nstatic void makeTagWithScope (xmlNode *node,\n\t\t\t      const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec,\n\t\t\t      struct sTagEntryInfo *tag,\n\t\t\t      void *userData)\n{\n\tint *corkIndexes = userData;\n\tint i;\n\tchar* version = NULL;\n\n\tif (tag->kindIndex == K_ARTIFACT_ID)\n\t\tversion = attachVersionIfExisting (tag, node);\n\n\ti = makeTagEntry (tag);\n\n\tif (version)\n\t\txmlFree (version);\n\n\tif ((tag->kindIndex == K_GROUP_ID)\n\t    || (tag->kindIndex == K_ARTIFACT_ID))\n\t\tcorkIndexes [spec->kind] = i;\n}\n\nstatic void\nfindMaven2TagsForTable (enum maven2XpathTable tindex,\n\t\t\txmlNode *node,\n\t\t\txmlXPathContext *ctx)\n{\n\tint corkIndexes [] = {\n\t\t[K_GROUP_ID]    = CORK_NIL,\n\t\t[K_ARTIFACT_ID] = CORK_NIL,\n\t};\n\n\tfindXMLTags (ctx, node, tindex, &corkIndexes);\n\n\ttagEntryInfo *tag = getEntryInCorkQueue (corkIndexes [K_ARTIFACT_ID]);\n\tif (tag && corkIndexes [K_GROUP_ID] != CORK_NIL)\n\t\ttag->extensionFields.scopeIndex = corkIndexes [K_GROUP_ID];\n}\n\nstatic void makeTagRecursively (xmlNode *node,\n\t\t\t      const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\t  const struct sTagXpathRecurSpec *spec,\n\t\t\t\t  xmlXPathContext *ctx,\n\t\t\t\t  void *userData CTAGS_ATTR_UNUSED)\n{\n\tfindMaven2TagsForTable (spec->nextTable, node, ctx);\n}\n\nstatic void\nfindMaven2Tags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic void\nrunXPathEngine(xmlSubparser *s,\n\t\t\t   xmlXPathContext *ctx, xmlNode *root)\n{\n\tfindMaven2TagsForTable (TABLE_MAIN, root, ctx);\n}\n\nstatic xmlSubparser maven2Subparser = {\n\t.subparser = {\n\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t},\n\t.runXPathEngine = runXPathEngine,\n};\n\nextern parserDefinition*\nMaven2Parser (void)\n{\n\tstatic const char *const extensions [] = { \"pom\", \"xml\", NULL };\n\tstatic const char *const patterns [] =   { \"pom.xml\", NULL };\n\tparserDefinition* const def = parserNew (\"Maven2\");\n\tstatic selectLanguage selectors[] = { selectByXpathFileSpec, NULL };\n\n\tstatic xpathFileSpec xpathFileSpecs[] = {\n\t\t{\n\t\t\t.rootElementName = \"project\",\n\t\t\t.rootNSHref      = \"http://maven.apache.org/POM/4.0.0\",\n\t\t},\n\t};\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"XML\", &maven2Subparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable         = Maven2Kinds;\n\tdef->kindCount     = ARRAY_SIZE (Maven2Kinds);\n\tdef->extensions    = extensions;\n\tdef->patterns      = patterns;\n\tdef->parser        = findMaven2Tags;\n\tdef->tagXpathTableTable  = maven2XpathTableTable;\n\tdef->tagXpathTableCount  = ARRAY_SIZE (maven2XpathTableTable);\n\tdef->useCork = CORK_QUEUE;\n\tdef->selectLanguage = selectors;\n\tdef->fieldTable = Maven2Fields;\n\tdef->fieldCount = ARRAY_SIZE (Maven2Fields);\n\tdef->xpathFileSpecs = xpathFileSpecs;\n\tdef->xpathFileSpecCount = ARRAY_SIZE (xpathFileSpecs);\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/myrddin.c",
    "content": "/*\n *   Copyright (c) 2016, Ori Bernstein\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for Myrddin language\n *   files. (https://myrlang.org)\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"  /* must always come first */\n#include \"parse.h\"\n\nstatic tagRegexTable myrddinTagRegexTable [] = {\n\t/* const foo = {; function literal } */\n\t{\"^([ \\t]*extern)?[ \\t]*const[ \\t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \\t]*=[ \\t]\\\\{\",\n\t\t\"\\\\2\", \"f,function,functions\", NULL},\n\t/* const foo = initializer */\n\t{\"^([ \\t]*extern)?[ \\t]*const[ \\t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \\t]*(=[ \\t][^{].*)?$\",\n\t\t\"\\\\2\", \"c,constant,constants\", NULL},\n\t/* var foo = initializer */\n\t{\"^([ \\t]*extern)?[ \\t]*var[ \\t]+([a-zA-Z_][a-zA-Z0-9_]*)\",\n\t\t\"\\\\2\", \"v,var,variables\", NULL},\n\t/* type foo = name */\n\t{\"^[ \\t]*type[ \\t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \\t]*=\",\n\t\t\"\\\\1\", \"t,type,types\", NULL},\n\t/* trait foo = trait-defn ;; */\n\t{\"^[ \\t]*trait[ \\t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \\t]*=\",\n\t\t\"\\\\1\", \"r,trait,traits\", NULL},\n\t/* pkg foo = declarations ;; */\n\t{\"^[ \\t]*pkg[ \\t]+([a-zA-Z_][a-zA-Z0-9_]*)\",\n\t\t\"\\\\1\", \"p,pkg,packages\", NULL},\n};\n\n/*\n *   FUNCTION DEFINITIONS\n */\n\nextern parserDefinition *MyrddinParser (void)\n{\n\tstatic const char *const extensions [] = { \"myr\", NULL };\n\tparserDefinition* const def = parserNew (\"Myrddin\");\n\tdef->extensions = extensions;\n\tdef->tagRegexTable = myrddinTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE (myrddinTagRegexTable);\n\tdef->method     = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/nsis.c",
    "content": "/*\n*   Copyright (c) 2000-2002, Darren Hiebert\n*   Copyright (c) 2009-2011, Enrico Tröger\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for NSIS scripts\n*   (https://en.wikipedia.org/wiki/Nullsoft_Scriptable_Install_System).\n*\n*   Based on sh.c.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"routines.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_SECTION,\n\tK_FUNCTION,\n\tK_VARIABLE,\n\tK_DEFINITION,\n\tK_MACRO,\n\tK_SECTION_GROUP,\n\tK_MACRO_PARAM,\n\tK_LANGSTR,\n\tK_SCRIPT,\n} NsisKind;\n\ntypedef enum {\n\tNSIS_SCRIPT_INCLUDED,\n} nsisScriptRole;\n\nstatic roleDefinition NsisScriptRoles [] = {\n\t{ true, \"included\",  \"included with !include\" },\n};\n\nstatic kindDefinition NsisKinds [] = {\n\t{ true, 's', \"section\", \"sections\"},\n\t{ true, 'f', \"function\", \"functions\"},\n\t{ true, 'v', \"variable\", \"variables\"},\n\t{ true, 'd', \"definition\", \"definitions\"},\n\t{ true, 'm', \"macro\", \"macros\"},\n\t{ true, 'S', \"sectionGroup\", \"section groups\"},\n\t{ false, 'p', \"macroparam\", \"macro parameters\"},\n\t{ true, 'l', \"langstr\", \"language strings\"},\n\t{ true, 'i', \"script\", \"NSIS scripts\",\n\t  .referenceOnly = true, ATTACH_ROLES(NsisScriptRoles)},\n};\n\ntypedef enum {\n\tF_LANGID,\n} nsisField;\n\nstatic fieldDefinition NsisFields[] = {\n\t{ .name = \"langid\",\n\t  .description = \"language identifier specified in (License)LangString commands\",\n\t  .enabled = true },\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic const unsigned char* skipWhitespace (const unsigned char* cp)\n{\n\twhile (isspace (*cp))\n\t\t++cp;\n\treturn cp;\n}\n\nstatic const unsigned char* skipFlags (const unsigned char* cp)\n{\n\twhile (*cp == '/')\n\t{\n\t\t++cp;\n\t\twhile (! isspace (*cp))\n\t\t\t++cp;\n\t\twhile (isspace (*cp))\n\t\t\t++cp;\n\t}\n\treturn cp;\n}\n\nstatic int makeSimpleTagWithScope(vString *name, int kindIndex, int parentCorkIndex)\n{\n\ttagEntryInfo e;\n\tinitTagEntry (&e, vStringValue (name), kindIndex);\n\te.extensionFields.scopeIndex = parentCorkIndex;\n\treturn makeTagEntry (&e);\n}\n\n#define lineStartingWith(CP,EXPECTED,EOL)\t\t\t\t\t\t\t\t\\\n\t(strncasecmp ((const char*) CP, EXPECTED, strlen(EXPECTED)) == 0\t\\\n\t\t&& (EOL ? (isspace ((unsigned char) CP [strlen(EXPECTED)]) || CP [strlen(EXPECTED)] == '\\0') \\\n\t\t\t: isspace ((unsigned char) CP [strlen(EXPECTED)])))\n\n#define fillName(NAME,CP,CONDITION)\t\t\t\t\\\n\twhile (CONDITION)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tvStringPut ((NAME), *(CP));\t\t\t\t\\\n\t\t++(CP);\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\\\n\tdo {} while (0)\n\nstatic const unsigned char* parseSection (const unsigned char* cp, vString *name,\n\t\t\t\t\t\t\t\t\t\t  int kindIndex, int scopeIndex, int *corkIndex)\n{\n\tcp = skipWhitespace (cp);\n\tcp = skipFlags (cp);\n\tcp = skipWhitespace (cp);\n\n\tif (corkIndex)\n\t\t*corkIndex = CORK_NIL;\n\n\tif (strpbrk((const char *)cp, \"'`\\\"\"))\n\t{\n\t\tconst unsigned char terminator = *cp;\n\n\t\tcp++;\n\t\tif (*cp == terminator)\n\t\t{\n\t\t\t/* An empty section.\n\t\t\t * See https://nsis.sourceforge.io/Docs/Chapter4.html#sectionsettext\n\t\t\t */\n\t\t\tanonGenerate (name,\n\t\t\t\t\t\t  (kindIndex == K_SECTION\n\t\t\t\t\t\t   ? \"AnonymousSection\"\n\t\t\t\t\t\t   : \"AnonymousSectionGroup\"),\n\t\t\t\t\t\t  kindIndex);\n\t\t\tcp++;\n\t\t}\n\t\telse if (*cp == '\\0')\n\t\t\treturn cp;\n\t\telse\n\t\t{\n\t\t\tint in_escape = 0;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t++cp;\n\n\t\t\t\tif (*cp == '\\0')\n\t\t\t\t\tbreak;\n\n\t\t\t\t/*\n\t\t\t\t * Ignore `\"' in `$\\\"' as the terminator of quotation.\n\t\t\t\t */\n\t\t\t\tif (*cp == '$' && in_escape == 0)\n\t\t\t\t\tin_escape++;\n\t\t\t\telse if (*cp == '\\\\' && in_escape == 1)\n\t\t\t\t\tin_escape++;\n\t\t\t\telse if (*cp == terminator && in_escape == 2)\n\t\t\t\t\t/*\n\t\t\t\t\t * This `\"' is not a terminator of quotation;\n\t\t\t\t\t * set in_escape to 3.\n\t\t\t\t\t */\n\t\t\t\t\tin_escape++;\n\t\t\t\telse\n\t\t\t\t\tin_escape = 0;\n\n\t\t\t\tif ((in_escape != 3) && *cp == terminator)\n\t\t\t\t{\n\t\t\t\t\t++cp;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile (1);\n\t\t}\n\t}\n\telse\n\t{\n\t\twhile (isalnum (*cp)\n\t\t\t   || *cp == '_' || *cp == '-' || *cp == '.' || *cp == '!'\n\t\t\t   || *cp == '$' || *cp == '{' || *cp == '}' || *cp == '(' || *cp == ')')\n\t\t{\n\t\t\tvStringPut (name, *cp);\n\t\t\t++cp;\n\t\t}\n\t}\n\tint r = makeSimpleTagWithScope (name, kindIndex, scopeIndex);\n\tif (corkIndex)\n\t\t*corkIndex = r;\n\tif (vStringLength (name) > 0)\n\t{\n\t\t/*\n\t\t * Try to capture section_index_output.\n\t\t */\n\t\tvStringClear (name);\n\t\tcp = skipWhitespace (cp);\n\n\t\tfillName (name, cp, (isalnum (*cp) || *cp == '_'));\n\n\t\tif (vStringLength (name) > 0)\n\t\t{\n\t\t\tmakeSimpleTag (name, K_DEFINITION);\n\t\t\tvStringClear (name);\n\t\t}\n\t}\n\treturn cp;\n}\n\nstatic const unsigned char* parseLangString (const unsigned char* cp, vString *name)\n{\n\tcp = skipWhitespace (cp);\n\n\t/* `^' is not explained in the nsis reference manual. However, it is used\n\t * in gvim.\n\t * e.g.\n\t * https://github.com/vim/vim/blob/3dabd718f4b2d8e09de9e2ec73832620b91c2f79/nsis/lang/english.nsi\n\t */\n\tfillName (name, cp, (isalnum (*cp) || *cp == '_' || *cp == '^'));\n\n\tif (vStringLength (name) > 0)\n\t{\n\t\tint r = makeSimpleTag (name, K_LANGSTR);\n\t\tif (r == CORK_NIL)\n\t\t\tgoto out;\n\t\tvStringClear (name);\n\n\t\tcp = skipWhitespace (cp);\n\t\tfillName (name, cp, ((*cp != '\\0') && (!isspace (*cp))));\n\t\tif (vStringLength (name) > 0)\n\t\t{\n\t\t\tattachParserFieldToCorkEntry (r, NsisFields[F_LANGID].ftype,\n\t\t\t\t\t\t\t\t\t\t  vStringValue (name));\n\t\t\tvStringClear (name);\n\t\t}\n\t}\n out:\n\treturn cp;\n}\n\nstatic void findNsisTags (void)\n{\n\tint sectionGroupIndex = CORK_NIL;\n\tvString *name = vStringNew ();\n\tconst unsigned char *line;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char* cp = line;\n\n\t\twhile (isspace (*cp))\n\t\t\tcp++;\n\n\t\tif (*cp == '#' || *cp == ';')\n\t\t\tcontinue;\n\n\t\t/* functions */\n\t\tif (lineStartingWith (cp, \"function\", false))\n\t\t{\n\t\t\tcp += 8;\n\t\t\tcp = skipWhitespace (cp);\n\n\t\t\tfillName (name, cp,\n\t\t\t\t\t  (isalnum (*cp) || *cp == '_' || *cp == '-' || *cp == '.' || *cp == '!'));\n\n\t\t\tmakeSimpleTag (name, K_FUNCTION);\n\t\t\tvStringClear (name);\n\t\t}\n\t\t/* variables */\n\t\telse if (lineStartingWith (cp, \"var\", false))\n\t\t{\n\t\t\tcp += 3;\n\t\t\tcp = skipWhitespace (cp);\n\t\t\tcp = skipFlags (cp);\n\n\t\t\tfillName (name, cp, (isalnum (*cp) || *cp == '_'));\n\n\t\t\tmakeSimpleTag (name, K_VARIABLE);\n\t\t\tvStringClear (name);\n\t\t}\n\t\t/* section groups */\n\t\telse if (lineStartingWith (cp, \"sectiongroup\", false))\n\t\t{\n\t\t\tcp += 12;\n\t\t\tcp = parseSection (cp, name, K_SECTION_GROUP, CORK_NIL, &sectionGroupIndex);\n\t\t}\n\t\telse if (lineStartingWith (cp, \"sectiongroupend\", true))\n\t\t{\n\t\t\tcp += 15;\n\t\t\tsectionGroupIndex = CORK_NIL;\n\t\t}\n\t\t/* sections */\n\t\telse if (lineStartingWith (cp, \"section\", false))\n\t\t{\n\t\t\tcp += 7;\n\t\t\tcp = parseSection (cp, name, K_SECTION, sectionGroupIndex, NULL);\n\t\t}\n\t\t/* LangString */\n\t\telse if (lineStartingWith (cp, \"langstring\", false))\n\t\t{\n\t\t\tcp += 10;\n\t\t\tcp = parseLangString (cp, name);\n\t\t}\n\t\t/* LicenseLangString */\n\t\telse if (lineStartingWith (cp, \"licenselangstring\", false))\n\t\t{\n\t\t\tcp += 17;\n\t\t\tcp = parseLangString (cp, name);\n\t\t}\n\t\t/* definitions */\n\t\telse if (lineStartingWith (cp, \"!define\", false))\n\t\t{\n\t\t\tcp += 7;\n\t\t\tcp = skipWhitespace (cp);\n\t\t\tcp = skipFlags (cp);\n\n\t\t\tfillName (name, cp, (isalnum (*cp) || *cp == '_'));\n\n\t\t\tmakeSimpleTag (name, K_DEFINITION);\n\t\t\tvStringClear (name);\n\t\t}\n\t\t/* macro */\n\t\telse if (lineStartingWith (cp, \"!macro\", false))\n\t\t{\n\t\t\tcp += 6;\n\t\t\tcp = skipWhitespace (cp);\n\t\t\tcp = skipFlags (cp);\n\n\t\t\tfillName (name, cp, (isalnum (*cp) || *cp == '_'));\n\n\t\t\tint index = makeSimpleTag (name, K_MACRO);\n\t\t\tif (vStringLength (name) > 0)\n\t\t\t{\n\t\t\t\twhile (1)\n\t\t\t\t{\n\t\t\t\t\tvStringClear (name);\n\t\t\t\t\tcp = skipWhitespace (cp);\n\t\t\t\t\tfillName (name, cp, (isalnum (*cp) || *cp == '_'));\n\t\t\t\t\tif (vStringLength (name) == 0)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tmakeSimpleTagWithScope (name, K_MACRO_PARAM, index);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t/* include */\n\t\telse if (lineStartingWith (cp, \"!include\", false))\n\t\t{\n\t\t\tcp += 8;\n\n\t\t\t/* !include [/NONFATAL] [/CHARSET=ACP|OEM|CP#|UTF8|UTF16LE|UTF16BE] file */\n\t\t\tcp = skipWhitespace (cp);\n\n\t\t\t/* /NONFATAL */\n\t\t\tcp = skipFlags (cp);\n\t\t\tcp = skipWhitespace (cp);\n\n\t\t\t/* /CHARSET */\n\t\t\tcp = skipFlags (cp);\n\t\t\tcp = skipWhitespace (cp);\n\n\t\t\tfillName (name, cp, (*cp != '\\0' && *cp != ';' && *cp != '#'));\n\t\t\tvStringStripTrailing (name);\n\n\t\t\tif (vStringLength (name) > 0)\n\t\t\t{\n\t\t\t\tmakeSimpleRefTag (name, K_SCRIPT, NSIS_SCRIPT_INCLUDED);\n\t\t\t\tvStringClear (name);\n\t\t\t}\n\t\t\t/* TODO: capture !addincludedir */\n\t\t}\n\t}\n\tvStringDelete (name);\n}\n\nextern parserDefinition* NsisParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"nsi\", \"nsh\", NULL\n\t};\n\tparserDefinition* def = parserNew (\"NSIS\");\n\tdef->kindTable  = NsisKinds;\n\tdef->kindCount  = ARRAY_SIZE (NsisKinds);\n\tdef->extensions = extensions;\n\tdef->fieldTable = NsisFields;\n\tdef->fieldCount = ARRAY_SIZE (NsisFields);\n\tdef->parser     = findNsisTags;\n\tdef->useCork    = CORK_QUEUE;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/objc.c",
    "content": "/*\n*   Copyright (c) 2010, Vincent Berthoux\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Objective C\n*   language files.\n*/\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include <string.h>\n\n#include \"keyword.h\"\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"trashbox.h\"\n#include \"vstring.h\"\n\ntypedef enum {\n\tK_INTERFACE,\n\tK_IMPLEMENTATION,\n\tK_PROTOCOL,\n\tK_METHOD,\n\tK_CLASSMETHOD,\n\tK_VAR,\n\tK_FIELD,\n\tK_FUNCTION,\n\tK_PROPERTY,\n\tK_TYPEDEF,\n\tK_STRUCT,\n\tK_ENUM,\n\tK_MACRO,\n\tK_CATEGORY,\n} objcKind;\n\nstatic kindDefinition ObjcKinds[] = {\n\t{true, 'i', \"interface\", \"class interface\"},\n\t{true, 'I', \"implementation\", \"class implementation\"},\n\t{true, 'P', \"protocol\", \"Protocol\"},\n\t{true, 'm', \"method\", \"Object's method\"},\n\t{true, 'c', \"class\", \"Class' method\"},\n\t{true, 'v', \"var\", \"Global variable\"},\n\t{true, 'E', \"field\", \"Object field\"},\n\t{true, 'f', \"function\", \"A function\"},\n\t{true, 'p', \"property\", \"A property\"},\n\t{true, 't', \"typedef\", \"A type alias\"},\n\t{true, 's', \"struct\", \"A type structure\"},\n\t{true, 'e', \"enum\", \"An enumeration\"},\n\t{true, 'M', \"macro\", \"A preprocessor macro\"},\n\t{true, 'C', \"category\", \"categories\"},\n};\n\ntypedef enum {\n\tObjcTYPEDEF,\n\tObjcSTRUCT,\n\tObjcENUM,\n\tObjcIMPLEMENTATION,\n\tObjcINTERFACE,\n\tObjcPROTOCOL,\n\tObjcENCODE,\n\tObjcEXTERN,\n\tObjcSYNCHRONIZED,\n\tObjcSELECTOR,\n\tObjcPROPERTY,\n\tObjcEND,\n\tObjcDEFS,\n\tObjcCLASS,\n\tObjcPRIVATE,\n\tObjcPACKAGE,\n\tObjcPUBLIC,\n\tObjcPROTECTED,\n\tObjcSYNTHESIZE,\n\tObjcDYNAMIC,\n\tObjcOPTIONAL,\n\tObjcREQUIRED,\n\tObjcSTRING,\n\tObjcIDENTIFIER,\n\n\tTok_COMA,\t/* ',' */\n\tTok_PLUS,\t/* '+' */\n\tTok_MINUS,\t/* '-' */\n\tTok_PARL,\t/* '(' */\n\tTok_PARR,\t/* ')' */\n\tTok_CurlL,\t/* '{' */\n\tTok_CurlR,\t/* '}' */\n\tTok_SQUAREL,\t/* '[' */\n\tTok_SQUARER,\t/* ']' */\n\tTok_semi,\t/* ';' */\n\tTok_dpoint,\t/* ':' */\n\tTok_Sharp,\t/* '#' */\n\tTok_Backslash,\t/* '\\\\' */\n\tTok_Asterisk,\t/* '*' */\n\tTok_ANGLEL,\t\t/* '<' */\n\tTok_ANGLER,\t\t/* '>' */\n\tTok_EOL,\t/* '\\r''\\n' */\n\tTok_CSTRING,\t/* \"...\" */\n\tTok_any,\n\n\tTok_EOF\t/* END of file */\n} objcKeyword;\n\ntypedef objcKeyword objcToken;\n\nstatic const keywordTable objcKeywordTable[] = {\n\t{\"typedef\", ObjcTYPEDEF},\n\t{\"struct\", ObjcSTRUCT},\n\t{\"enum\", ObjcENUM},\n\t{\"extern\", ObjcEXTERN},\n\t{\"@implementation\", ObjcIMPLEMENTATION},\n\t{\"@interface\", ObjcINTERFACE},\n\t{\"@protocol\", ObjcPROTOCOL},\n\t{\"@encode\", ObjcENCODE},\n\t{\"@property\", ObjcPROPERTY},\n\t{\"@synchronized\", ObjcSYNCHRONIZED},\n\t{\"@selector\", ObjcSELECTOR},\n\t{\"@end\", ObjcEND},\n\t{\"@defs\", ObjcDEFS},\n\t{\"@class\", ObjcCLASS},\n\t{\"@private\", ObjcPRIVATE},\n\t{\"@package\", ObjcPACKAGE},\n\t{\"@public\", ObjcPUBLIC},\n\t{\"@protected\", ObjcPROTECTED},\n\t{\"@synthesize\", ObjcSYNTHESIZE},\n\t{\"@dynamic\", ObjcDYNAMIC},\n\t{\"@optional\", ObjcOPTIONAL},\n\t{\"@required\", ObjcREQUIRED},\n};\n\ntypedef enum {\n\tF_CATEGORY,\n\tF_PROTOCOLS,\n} objcField;\n\nstatic fieldDefinition ObjcFields [] = {\n\t{\n\t\t.name = \"category\",\n\t\t.description = \"category attached to the class\",\n\t\t.enabled = true,\n\t},\n\t{\n\t\t.name = \"protocols\",\n\t\t.description = \"protocols that the class (or category) confirms to\",\n\t\t.enabled = true,\n\t},\n};\n\nstatic langType Lang_ObjectiveC;\n\n/*//////////////////////////////////////////////////////////////////\n//// lexingInit             */\ntypedef struct _lexingState {\n\tvString *name;\t/* current parsed identifier/operator */\n\tconst unsigned char *cp;\t/* position in stream */\n\tunsigned long ln;\t\t\t/* line number, just for making tags, not used in parsing */\n\tMIOPos pos;\t\t\t\t/* file pos, just for making tags, not used in parsing1 */\n} lexingState;\n\ntypedef struct _objcString {\n\tvString *name;\n\tunsigned long ln;\n\tMIOPos pos;\n} objcString;\n\n/*//////////////////////////////////////////////////////////////////////\n//// Lexing                                     */\nstatic bool isNum (char c)\n{\n\treturn c >= '0' && c <= '9';\n}\n\nstatic bool isLowerAlpha (char c)\n{\n\treturn c >= 'a' && c <= 'z';\n}\n\nstatic bool isUpperAlpha (char c)\n{\n\treturn c >= 'A' && c <= 'Z';\n}\n\nstatic bool isAlpha (char c)\n{\n\treturn isLowerAlpha (c) || isUpperAlpha (c);\n}\n\nstatic bool isIdent (char c)\n{\n\treturn isNum (c) || isAlpha (c) || c == '_';\n}\n\nstatic bool isSpace (char c)\n{\n\treturn c == ' ' || c == '\\t';\n}\n\n/* return true if it end with an end of line */\nstatic void eatWhiteSpace (lexingState * st)\n{\n\tconst unsigned char *cp = st->cp;\n\twhile (isSpace (*cp))\n\t\tcp++;\n\n\tst->cp = cp;\n}\n\nstatic void readCString (lexingState * st)\n{\n\tbool lastIsBackSlash = false;\n\tbool unfinished = true;\n\tconst unsigned char *c = st->cp + 1;\n\n\tvStringClear (st->name);\n\n\twhile (unfinished)\n\t{\n\t\t/* end of line should never happen.\n\t\t * we tolerate it */\n\t\tif (c == NULL || c[0] == '\\0')\n\t\t\tbreak;\n\t\telse if (*c == '\"' && !lastIsBackSlash)\n\t\t\tunfinished = false;\n\t\telse\n\t\t{\n\t\t\tlastIsBackSlash = *c == '\\\\';\n\t\t\tvStringPut (st->name, *c);\n\t\t}\n\n\t\tc++;\n\t}\n\n\tst->cp = c;\n}\n\nstatic void updateLine (lexingState * st)\n{\n\tst->cp = readLineFromInputFile ();\n\tst->ln = getInputLineNumber ();\n\tst->pos = getInputFilePosition ();\n}\n\nstatic void eatComment (lexingState * st)\n{\n\tbool unfinished = true;\n\tbool lastIsStar = false;\n\tconst unsigned char *c = st->cp + 2;\n\n\twhile (unfinished)\n\t{\n\t\t/* we've reached the end of the line..\n\t\t * so we have to reload a line... */\n\t\tif (c == NULL || *c == '\\0')\n\t\t{\n\t\t\tupdateLine (st);\n\t\t\t/* WOOPS... no more input...\n\t\t\t * we return, next lexing read\n\t\t\t * will be null and ok */\n\t\t\tif (st->cp == NULL)\n\t\t\t\treturn;\n\t\t\tc = st->cp;\n\t\t}\n\t\t/* we've reached the end of the comment */\n\t\telse if (*c == '/' && lastIsStar)\n\t\t\tunfinished = false;\n\t\telse\n\t\t{\n\t\t\tlastIsStar = '*' == *c;\n\t\t\tc++;\n\t\t}\n\t}\n\n\tst->cp = c;\n}\n\nstatic void readIdentifier (lexingState * st)\n{\n\tconst unsigned char *p;\n\tvStringClear (st->name);\n\n\t/* first char is a simple letter */\n\tif (isAlpha (*st->cp) || *st->cp == '_')\n\t\tvStringPut (st->name, *st->cp);\n\n\t/* Go till you get identifier chars */\n\tfor (p = st->cp + 1; isIdent (*p); p++)\n\t\tvStringPut (st->name, *p);\n\n\tst->cp = p;\n}\n\n/* read the @something directives */\nstatic void readIdentifierObjcDirective (lexingState * st)\n{\n\tconst unsigned char *p;\n\tvStringClear (st->name);\n\n\t/* first char is a simple letter */\n\tif (*st->cp == '@')\n\t\tvStringPut (st->name, *st->cp);\n\n\t/* Go till you get identifier chars */\n\tfor (p = st->cp + 1; isIdent (*p); p++)\n\t\tvStringPut (st->name, *p);\n\n\tst->cp = p;\n}\n\n/* The lexer is in charge of reading the file.\n * Some of sub-lexer (like eatComment) also read file.\n * lexing is finished when the lexer return Tok_EOF */\nstatic objcKeyword lex (lexingState * st)\n{\n\tint retType;\n\n\t/* handling data input here */\n\twhile (st->cp == NULL || st->cp[0] == '\\0')\n\t{\n\t\tupdateLine (st);\n\t\tif (st->cp == NULL)\n\t\t\treturn Tok_EOF;\n\n\t\treturn Tok_EOL;\n\t}\n\n\tif (isAlpha (*st->cp) || (*st->cp == '_'))\n\t{\n\t\treadIdentifier (st);\n\t\tretType = lookupKeyword (vStringValue (st->name), Lang_ObjectiveC);\n\n\t\tif (retType == -1)\t/* If it's not a keyword */\n\t\t{\n\t\t\treturn ObjcIDENTIFIER;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn retType;\n\t\t}\n\t}\n\telse if (*st->cp == '@')\n\t{\n\t\treadIdentifierObjcDirective (st);\n\t\tretType = lookupKeyword (vStringValue (st->name), Lang_ObjectiveC);\n\n\t\tif (retType == -1)\t/* If it's not a keyword */\n\t\t{\n\t\t\treturn Tok_any;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn retType;\n\t\t}\n\t}\n\telse if (isSpace (*st->cp))\n\t{\n\t\teatWhiteSpace (st);\n\t\treturn lex (st);\n\t}\n\telse\n\t\tswitch (*st->cp)\n\t\t{\n\t\tcase '(':\n\t\t\tst->cp++;\n\t\t\treturn Tok_PARL;\n\n\t\tcase '\\\\':\n\t\t\tst->cp++;\n\t\t\treturn Tok_Backslash;\n\n\t\tcase '#':\n\t\t\tst->cp++;\n\t\t\treturn Tok_Sharp;\n\n\t\tcase '/':\n\t\t\tif (st->cp[1] == '*')\t/* ergl, a comment */\n\t\t\t{\n\t\t\t\teatComment (st);\n\t\t\t\treturn lex (st);\n\t\t\t}\n\t\t\telse if (st->cp[1] == '/')\n\t\t\t{\n\t\t\t\tst->cp = NULL;\n\t\t\t\treturn lex (st);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tst->cp++;\n\t\t\t\treturn Tok_any;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase ')':\n\t\t\tst->cp++;\n\t\t\treturn Tok_PARR;\n\t\tcase '{':\n\t\t\tst->cp++;\n\t\t\treturn Tok_CurlL;\n\t\tcase '}':\n\t\t\tst->cp++;\n\t\t\treturn Tok_CurlR;\n\t\tcase '[':\n\t\t\tst->cp++;\n\t\t\treturn Tok_SQUAREL;\n\t\tcase ']':\n\t\t\tst->cp++;\n\t\t\treturn Tok_SQUARER;\n\t\tcase ',':\n\t\t\tst->cp++;\n\t\t\treturn Tok_COMA;\n\t\tcase ';':\n\t\t\tst->cp++;\n\t\t\treturn Tok_semi;\n\t\tcase ':':\n\t\t\tst->cp++;\n\t\t\treturn Tok_dpoint;\n\t\tcase '\"':\n\t\t\treadCString (st);\n\t\t\treturn Tok_CSTRING;\n\t\tcase '+':\n\t\t\tst->cp++;\n\t\t\treturn Tok_PLUS;\n\t\tcase '-':\n\t\t\tst->cp++;\n\t\t\treturn Tok_MINUS;\n\t\tcase '*':\n\t\t\tst->cp++;\n\t\t\treturn Tok_Asterisk;\n\t\tcase '<':\n\t\t\tst->cp++;\n\t\t\treturn Tok_ANGLEL;\n\t\tcase '>':\n\t\t\tst->cp++;\n\t\t\treturn Tok_ANGLER;\n\n\t\tdefault:\n\t\t\tst->cp++;\n\t\t\tbreak;\n\t\t}\n\n\t/* default return if nothing is recognized,\n\t * shouldn't happen, but at least, it will\n\t * be handled without destroying the parsing. */\n\treturn Tok_any;\n}\n\n/*//////////////////////////////////////////////////////////////////////\n//// Parsing                                    */\ntypedef void (*parseNext) (vString * const ident, objcToken what,\n\t\t\t\t\t\t   unsigned long ln, MIOPos pos);\n\n/********** Helpers */\n/* This variable hold the 'parser' which is going to\n * handle the next token */\nstatic parseNext toDoNext;\n\n/* Special variable used by parser eater to\n * determine which action to put after their\n * job is finished. */\nstatic parseNext comeAfter;\n\n/* Used by some parsers detecting certain token\n * to revert to previous parser. */\nstatic parseNext fallback;\n\n\n/********** Grammar */\nstatic void globalScope (vString * const ident, objcToken what, unsigned long ln, MIOPos pos);\nstatic void parseMethods (vString * const ident, objcToken what, unsigned long ln, MIOPos pos);\nstatic void parseImplemMethods (vString * const ident, objcToken what, unsigned long ln, MIOPos pos);\nstatic vString *tempName = NULL;\nstatic vString *parentName = NULL;\nstatic objcKind parentType = K_INTERFACE;\nstatic int parentCorkIndex = CORK_NIL;\nstatic int categoryCorkIndex = CORK_NIL;\n\n/* used to prepare tag for OCaml, just in case their is a need to\n * add additional information to the tag. */\nstatic void prepareTag (tagEntryInfo * tag, vString const *name, objcKind kind)\n{\n\tinitTagEntry (tag, vStringValue (name), kind);\n\n\tif (!vStringIsEmpty (parentName))\n\t{\n\t\ttag->extensionFields.scopeKindIndex = parentType;\n\t\ttag->extensionFields.scopeName = vStringValue (parentName);\n\t}\n}\n\nstatic void pushEnclosingContext (const vString * parent, objcKind type)\n{\n\tvStringCopy (parentName, parent);\n\tparentType = type;\n}\n\nstatic void pushEnclosingContextFull (const vString * parent, objcKind type, int corkIndex)\n{\n\tpushEnclosingContext (parent, type);\n\tparentCorkIndex = corkIndex;\n}\n\nstatic void popEnclosingContext (void)\n{\n\tvStringClear (parentName);\n\tparentCorkIndex = CORK_NIL;\n}\n\nstatic void pushCategoryContext (int category_index)\n{\n\tcategoryCorkIndex = category_index;\n}\n\nstatic void popCategoryContext (void)\n{\n\tcategoryCorkIndex = CORK_NIL;\n}\n\n/* Used to centralise tag creation, and be able to add\n * more information to it in the future */\nstatic int addTag (vString * const ident, int kind)\n{\n\ttagEntryInfo toCreate;\n\n\tif (! ObjcKinds[kind].enabled)\n\t\treturn CORK_NIL;\n\n\tif (vStringIsEmpty (ident))\n\t\treturn CORK_NIL;\n\n\tprepareTag (&toCreate, ident, kind);\n\treturn makeTagEntry (&toCreate);\n}\n\nstatic int objcAddTag (objcString * const ident, int kind)\n{\n\tint q = addTag (ident->name, kind);\n\ttagEntryInfo *e = getEntryInCorkQueue (q);\n\tif (e)\n\t\tupdateTagLine (e, ident->ln, ident->pos);\n\n\treturn q;\n}\n\nstatic objcToken waitedToken, fallBackToken;\n\n/* Ignore everything till waitedToken and jump to comeAfter.\n * If the \"end\" keyword is encountered break, doesn't remember\n * why though. */\nstatic void tillToken (vString * const ident CTAGS_ATTR_UNUSED, objcToken what,\n\t\t\t\t\t   unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tif (what == waitedToken)\n\t\ttoDoNext = comeAfter;\n}\n\nstatic void tillTokenOrFallBack (vString * const ident CTAGS_ATTR_UNUSED, objcToken what,\n\t\t\t\t\t\t\t\t unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tif (what == waitedToken)\n\t\ttoDoNext = comeAfter;\n\telse if (what == fallBackToken)\n\t{\n\t\ttoDoNext = fallback;\n\t}\n}\n\nstatic int ignoreBalanced_count = 0;\nstatic void ignoreBalanced (vString * const ident CTAGS_ATTR_UNUSED, objcToken what,\n\t\t\t\t\t\t\tunsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\n\tswitch (what)\n\t{\n\tcase Tok_PARL:\n\tcase Tok_CurlL:\n\tcase Tok_SQUAREL:\n\t\tignoreBalanced_count++;\n\t\tbreak;\n\n\tcase Tok_PARR:\n\tcase Tok_CurlR:\n\tcase Tok_SQUARER:\n\t\tignoreBalanced_count--;\n\t\tbreak;\n\n\tdefault:\n\t\t/* don't care */\n\t\tbreak;\n\t}\n\n\tif (ignoreBalanced_count == 0)\n\t\ttoDoNext = comeAfter;\n}\n\nstatic void parseFields (vString * const ident, objcToken what,\n\t\t\t\t\t\t unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase Tok_CurlR:\n\t\ttoDoNext = &parseMethods;\n\t\tbreak;\n\n\tcase Tok_SQUAREL:\n\tcase Tok_PARL:\n\t\ttoDoNext = &ignoreBalanced;\n\t\tcomeAfter = &parseFields;\n\t\tbreak;\n\n\t\t/* we got an identifier, keep track of it */\n\tcase ObjcIDENTIFIER:\n\t\tvStringCopy (tempName, ident);\n\t\tbreak;\n\n\t\t/* our last kept identifier must be our variable name =) */\n\tcase Tok_semi:\n\t\taddTag (tempName, K_FIELD);\n\t\tvStringClear (tempName);\n\t\tbreak;\n\n\tdefault:\n\t\t/* NOTHING */\n\t\tbreak;\n\t}\n}\n\nstatic objcKind methodKind;\n\n\nstatic objcString *fullMethodName;\nstatic objcString *prevIdent;\nstatic vString *signature;\n\nstatic void tillTokenWithCapturingSignature (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t\t\t\t\t unsigned long ln, MIOPos pos)\n{\n\ttillToken (ident, what, ln, pos);\n\n\tif (what != waitedToken)\n\t{\n\t\tif (what == Tok_Asterisk)\n\t\t\tvStringPut (signature, '*');\n\t\telse if (!vStringIsEmpty (ident))\n\t\t{\n\t\t\tif (! (vStringLast (signature) == ','\n\t\t\t\t   || vStringLast (signature) == '('\n\t\t\t\t   || vStringLast (signature) == ' '))\n\t\t\t\tvStringPut (signature, ' ');\n\n\t\t\tvStringCat (signature, ident);\n\t\t}\n\t}\n}\n\nstatic objcString *objcStringNew (void)\n{\n\tobjcString *o = xCalloc(1, objcString);\n\to->name = vStringNew ();\n\treturn o;\n}\n\nstatic void objcStringDelete (objcString *o)\n{\n\tvStringDelete (o->name);\n\teFree (o);\n}\n\nstatic bool objcStringIsEmpty (const objcString *o)\n{\n\treturn vStringIsEmpty (o->name);\n}\n\nstatic void objcStringClear (objcString *o)\n{\n\tvStringClear (o->name);\n}\n\nstatic void objcStringCat (objcString *string, const objcString *s)\n{\n\tbool was_empty = objcStringIsEmpty (string);\n\n\tvStringCat (string->name, s->name);\n\tif (was_empty)\n\t{\n\t\tstring->ln = s->ln;\n\t\tstring->pos = s->pos;\n\t}\n}\n\n#define objcStringPut(S, C, LN, POS) do\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tvStringPut(S->name, C);\t\t\t\t\t\\\n\t\tif (vStringLength(S->name) == 1)\t\t\\\n\t\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tS->ln = LN;\t\t\t\t\t\t\t\\\n\t\t\tS->pos = POS;\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\\\n\twhile (0)\n\nstatic void objcStringCopy (objcString *string, vString *s,\n\t\t\t\t\t\t\tunsigned long ln, MIOPos pos)\n{\n\tvStringCopy (string->name, s);\n\tstring->ln = ln;\n\tstring->pos = pos;\n}\n\nstatic void parseMethodsNameCommon (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t\t\tparseNext reEnter,\n\t\t\t\t\t\t\t\t\tparseNext nextAction,\n\t\t\t\t\t\t\t\t\tunsigned long ln, MIOPos pos)\n{\n\tint index;\n\n\tswitch (what)\n\t{\n\tcase Tok_PARL:\n\t\ttoDoNext = &tillToken;\n\t\tcomeAfter = reEnter;\n\t\twaitedToken = Tok_PARR;\n\n\t\tif (! (objcStringIsEmpty(prevIdent)\n\t\t\t   && objcStringIsEmpty(fullMethodName)))\n\t\t\ttoDoNext = &tillTokenWithCapturingSignature;\n\t\tbreak;\n\n\tcase Tok_dpoint:\n\t\tobjcStringCat (fullMethodName, prevIdent);\n\t\tobjcStringPut (fullMethodName, ':', ln, pos);\n\t\tobjcStringClear (prevIdent);\n\n\t\tif (vStringLength (signature) > 1)\n\t\t\tvStringPut (signature, ',');\n\t\tbreak;\n\n\tcase ObjcIDENTIFIER:\n\t\tif (((!objcStringIsEmpty (prevIdent))\n\t\t\t /* \"- initWithObject: o0 withAnotherObject: o1;\"\n\t\t\t\tOverwriting the last value of prevIdent (\"o0\");\n\t\t\t\ta parameter name (\"o0\") was stored to prevIdent,\n\t\t\t\tand a part of selector(\"withAnotherObject\")\n\t\t\t\toverwrites it.\n\t\t\t\tIf type for the parameter specified explicitly,\n\t\t\t\tthe last char of signature should not be ',' nor\n\t\t\t\t'('. In this case, \"id\" must be put as the type for\n\t\t\t\tthe parameter. */\n\t\t\t && (vStringLast (signature) == ','\n\t\t\t\t || vStringLast (signature) == '('))\n\t\t\t|| (/* \"- initWithObject: object;\"\n\t\t\t\t   In this case no overwriting happens.\n\t\t\t\t   However, \"id\" for \"object\" is part\n\t\t\t\t   of signature. */\n\t\t\t\tobjcStringIsEmpty (prevIdent)\n\t\t\t\t&& (!objcStringIsEmpty (fullMethodName))\n\t\t\t\t&& vStringLast (signature) == '('))\n\t\t\tvStringCatS (signature, \"id\");\n\n\t\tobjcStringCopy (prevIdent, ident, ln, pos);\n\t\tbreak;\n\n\tcase Tok_CurlL:\n\tcase Tok_semi:\n\t\t/* method name is not simple */\n\t\tif (!objcStringIsEmpty (fullMethodName))\n\t\t{\n\t\t\tindex = objcAddTag (fullMethodName, methodKind);\n\t\t\tobjcStringClear (fullMethodName);\n\t\t}\n\t\telse\n\t\t\tindex = objcAddTag (prevIdent, methodKind);\n\n\t\ttoDoNext = nextAction;\n\t\tparseImplemMethods (ident, what, ln, pos);\n\t\tobjcStringClear (prevIdent);\n\n\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\tif (e)\n\t\t{\n\t\t\tif (vStringLast (signature) == ',')\n\t\t\t\tvStringCatS (signature, \"id\");\n\t\t\tvStringPut (signature, ')');\n\n\t\t\te->extensionFields.signature = vStringStrdup (signature);\n\n\t\t\tvStringClear (signature);\n\t\t\tvStringPut (signature, '(');\n\n\t\t\ttagEntryInfo *e_cat = getEntryInCorkQueue (categoryCorkIndex);\n\t\t\tif (e_cat)\n\t\t\t\tattachParserFieldToCorkEntry (index,\n\t\t\t\t\t\t\t\t\t\t\t  ObjcFields [F_CATEGORY].ftype,\n\t\t\t\t\t\t\t\t\t\t\t  e_cat->name);\n\t\t}\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nstatic void parseMethodsName (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t  unsigned long ln, MIOPos pos)\n{\n\tparseMethodsNameCommon (ident, what, parseMethodsName, parseMethods, ln ,pos);\n}\n\nstatic void parseMethodsImplemName (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t\t\tunsigned long ln, MIOPos pos)\n{\n\tparseMethodsNameCommon (ident, what, parseMethodsImplemName, parseImplemMethods, ln, pos);\n}\n\nstatic void parseCategory (vString * const ident, objcToken what,\n\t\t\t\t\t\t   unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tif (what == ObjcIDENTIFIER)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (parentCorkIndex);\n\t\tif (e)\n\t\t{\n\t\t\tattachParserFieldToCorkEntry (parentCorkIndex,\n\t\t\t\t\t\t\t\t\t\t  ObjcFields [F_CATEGORY].ftype,\n\t\t\t\t\t\t\t\t\t\t  vStringValue (ident));\n\t\t\tif (e->kindIndex == K_INTERFACE)\n\t\t\t\ttoDoNext = &parseMethods;\n\t\t\telse\n\t\t\t\ttoDoNext = &parseImplemMethods;\n\t\t}\n\n\t\tint index = addTag (ident, K_CATEGORY);\n\t\tpushCategoryContext (index);\n\t}\n}\n\nstatic void parseImplemMethods (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t\tunsigned long ln, MIOPos pos)\n{\n\tswitch (what)\n\t{\n\tcase Tok_PLUS:\t/* + */\n\t\ttoDoNext = &parseMethodsImplemName;\n\t\tmethodKind = K_CLASSMETHOD;\n\t\tbreak;\n\n\tcase Tok_MINUS:\t/* - */\n\t\ttoDoNext = &parseMethodsImplemName;\n\t\tmethodKind = K_METHOD;\n\t\tbreak;\n\n\tcase ObjcEND:\t/* @end */\n\t\tpopEnclosingContext ();\n\t\tpopCategoryContext ();\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\n\tcase Tok_CurlL:\t/* { */\n\t\ttoDoNext = &ignoreBalanced;\n\t\tignoreBalanced (ident, what, ln, pos);\n\t\tcomeAfter = &parseImplemMethods;\n\t\tbreak;\n\n\tcase Tok_PARL: /* ( */\n\t\ttoDoNext = &parseCategory;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nstatic void parseProperty (vString * const ident, objcToken what,\n\t\t\t\t\t\t   unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase Tok_PARL:\n\t\ttoDoNext = &tillToken;\n\t\tcomeAfter = &parseProperty;\n\t\twaitedToken = Tok_PARR;\n\t\tbreak;\n\n\t\t/* we got an identifier, keep track of it */\n\tcase ObjcIDENTIFIER:\n\t\tvStringCopy (tempName, ident);\n\t\tbreak;\n\n\t\t/* our last kept identifier must be our variable name =) */\n\tcase Tok_semi:\n\t\taddTag (tempName, K_PROPERTY);\n\t\tvStringClear (tempName);\n\t\ttoDoNext = &parseMethods;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nstatic void parseInterfaceSuperclass (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t\t\t  unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (parentCorkIndex);\n\tif (what == ObjcIDENTIFIER && e)\n\t\te->extensionFields.inheritance = vStringStrdup (ident);\n\n\ttoDoNext = &parseMethods;\n}\n\nstatic void parseInterfaceProtocolList (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t\t\t\tunsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tstatic vString *protocol_list;\n\n\tif (parentCorkIndex == CORK_NIL)\n\t{\n\t\ttoDoNext = &parseMethods;\n\t\treturn;\n\t}\n\n\tif (protocol_list == NULL)\n\t{\n\t\tprotocol_list = vStringNew ();\n\t\tDEFAULT_TRASH_BOX(protocol_list, vStringDelete);\n\t}\n\n\tif (what == ObjcIDENTIFIER)\n\t\tvStringCat(protocol_list, ident);\n\telse if (what == Tok_COMA)\n\t\tvStringPut (protocol_list, ',');\n\telse if (what == Tok_ANGLER)\n\t{\n\t\tattachParserFieldToCorkEntry (parentCorkIndex,\n\t\t\t\t\t\t\t\t\t  ObjcFields [F_PROTOCOLS].ftype,\n\t\t\t\t\t\t\t\t\t  vStringValue (protocol_list));\n\t\tif (categoryCorkIndex != CORK_NIL)\n\t\t\tattachParserFieldToCorkEntry (categoryCorkIndex,\n\t\t\t\t\t\t\t\t\t\t  ObjcFields [F_PROTOCOLS].ftype,\n\t\t\t\t\t\t\t\t\t\t  vStringValue (protocol_list));\n\t\tvStringClear (protocol_list);\n\t\ttoDoNext = &parseMethods;\n\t}\n}\n\nstatic void parseMethods (vString * const ident CTAGS_ATTR_UNUSED, objcToken what,\n\t\t\t\t\t\t  unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase Tok_PLUS:\t/* + */\n\t\ttoDoNext = &parseMethodsName;\n\t\tmethodKind = K_CLASSMETHOD;\n\t\tbreak;\n\n\tcase Tok_MINUS:\t/* - */\n\t\ttoDoNext = &parseMethodsName;\n\t\tmethodKind = K_METHOD;\n\t\tbreak;\n\n\tcase ObjcPROPERTY:\n\t\ttoDoNext = &parseProperty;\n\t\tbreak;\n\n\tcase ObjcEND:\t/* @end */\n\t\tpopEnclosingContext ();\n\t\tpopCategoryContext ();\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\n\tcase Tok_CurlL:\t/* { */\n\t\ttoDoNext = &parseFields;\n\t\tbreak;\n\n\tcase Tok_dpoint: /* : */\n\t\ttoDoNext = &parseInterfaceSuperclass;\n\t\tbreak;\n\n\tcase Tok_PARL: /* ( */\n\t\ttoDoNext = &parseCategory;\n\t\tbreak;\n\n\tcase Tok_ANGLEL: /* < */\n\t\ttoDoNext = &parseInterfaceProtocolList;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\n\nstatic void parseProtocol (vString * const ident, objcToken what,\n\t\t\t\t\t\t   unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tif (what == ObjcIDENTIFIER)\n\t{\n\t\tint index = addTag (ident, K_PROTOCOL);\n\t\tpushEnclosingContextFull (ident, K_PROTOCOL, index);\n\t}\n\ttoDoNext = &parseMethods;\n}\n\nstatic void parseImplementation (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t\t unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tif (what == ObjcIDENTIFIER)\n\t{\n\t\tint index = addTag (ident, K_IMPLEMENTATION);\n\t\tpushEnclosingContextFull (ident, K_IMPLEMENTATION, index);\n\t}\n\ttoDoNext = &parseImplemMethods;\n}\n\nstatic void parseInterface (vString * const ident, objcToken what,\n\t\t\t\t\t\t\tunsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tif (what == ObjcIDENTIFIER)\n\t{\n\t\tint index = addTag (ident, K_INTERFACE);\n\t\tpushEnclosingContextFull (ident, K_INTERFACE, index);\n\t}\n\n\ttoDoNext = &parseMethods;\n}\n\nstatic void parseStructMembers (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t\tunsigned long ln, MIOPos pos)\n{\n\tstatic parseNext prev = NULL;\n\n\tif (prev != NULL)\n\t{\n\t\tcomeAfter = prev;\n\t\tprev = NULL;\n\t}\n\n\tswitch (what)\n\t{\n\tcase ObjcIDENTIFIER:\n\t\tvStringCopy (tempName, ident);\n\t\tbreak;\n\n\tcase Tok_semi:\t/* ';' */\n\t\taddTag (tempName, K_FIELD);\n\t\tvStringClear (tempName);\n\t\tbreak;\n\n\t\t/* some types are complex, the only one\n\t\t * we will loose is the function type.\n\t\t */\n\tcase Tok_CurlL:\t/* '{' */\n\tcase Tok_PARL:\t/* '(' */\n\tcase Tok_SQUAREL:\t/* '[' */\n\t\ttoDoNext = &ignoreBalanced;\n\t\tprev = comeAfter;\n\t\tcomeAfter = &parseStructMembers;\n\t\tignoreBalanced (ident, what, ln, pos);\n\t\tbreak;\n\n\tcase Tok_CurlR:\n\t\ttoDoNext = comeAfter;\n\t\tbreak;\n\n\tdefault:\n\t\t/* don't care */\n\t\tbreak;\n\t}\n}\n\n/* Called just after the struct keyword */\nstatic bool parseStruct_gotName = false;\nstatic void parseStruct (vString * const ident, objcToken what,\n\t\t\t\t\t\t unsigned long ln, MIOPos pos)\n{\n\tswitch (what)\n\t{\n\tcase ObjcIDENTIFIER:\n\t\tif (!parseStruct_gotName)\n\t\t{\n\t\t\taddTag (ident, K_STRUCT);\n\t\t\tpushEnclosingContext (ident, K_STRUCT);\n\t\t\tparseStruct_gotName = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tparseStruct_gotName = false;\n\t\t\tpopEnclosingContext ();\n\t\t\ttoDoNext = comeAfter;\n\t\t\tcomeAfter (ident, what, ln, pos);\n\t\t}\n\t\tbreak;\n\n\tcase Tok_CurlL:\n\t\ttoDoNext = &parseStructMembers;\n\t\tbreak;\n\n\t\t/* maybe it was just a forward declaration\n\t\t * in which case, we pop the context */\n\tcase Tok_semi:\n\t\tif (parseStruct_gotName)\n\t\t\tpopEnclosingContext ();\n\n\t\ttoDoNext = comeAfter;\n\t\tcomeAfter (ident, what, ln, pos);\n\t\tbreak;\n\n\tdefault:\n\t\t/* we don't care */\n\t\tbreak;\n\t}\n}\n\n/* Parse enumeration members, ignoring potential initialization */\nstatic parseNext parseEnumFields_prev = NULL;\nstatic void parseEnumFields (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tif (parseEnumFields_prev != NULL)\n\t{\n\t\tcomeAfter = parseEnumFields_prev;\n\t\tparseEnumFields_prev = NULL;\n\t}\n\n\tswitch (what)\n\t{\n\tcase ObjcIDENTIFIER:\n\t\taddTag (ident, K_ENUM);\n\t\tparseEnumFields_prev = comeAfter;\n\t\twaitedToken = Tok_COMA;\n\t\t/* last item might not have a coma */\n\t\tfallBackToken = Tok_CurlR;\n\t\tfallback = comeAfter;\n\t\tcomeAfter = parseEnumFields;\n\t\ttoDoNext = &tillTokenOrFallBack;\n\t\tbreak;\n\n\tcase Tok_CurlR:\n\t\ttoDoNext = comeAfter;\n\t\tpopEnclosingContext ();\n\t\tbreak;\n\n\tdefault:\n\t\t/* don't care */\n\t\tbreak;\n\t}\n}\n\n/* parse enum ... { ... */\nstatic bool parseEnum_named = false;\nstatic void parseEnum (vString * const ident, objcToken what,\n\t\t\t\t\t   unsigned long ln, MIOPos pos)\n{\n\tswitch (what)\n\t{\n\tcase ObjcIDENTIFIER:\n\t\tif (!parseEnum_named)\n\t\t{\n\t\t\taddTag (ident, K_ENUM);\n\t\t\tpushEnclosingContext (ident, K_ENUM);\n\t\t\tparseEnum_named = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tparseEnum_named = false;\n\t\t\tpopEnclosingContext ();\n\t\t\ttoDoNext = comeAfter;\n\t\t\tcomeAfter (ident, what, ln, pos);\n\t\t}\n\t\tbreak;\n\n\tcase Tok_CurlL:\t/* '{' */\n\t\ttoDoNext = &parseEnumFields;\n\t\tparseEnum_named = false;\n\t\tbreak;\n\n\tcase Tok_semi:\t/* ';' */\n\t\tif (parseEnum_named)\n\t\t\tpopEnclosingContext ();\n\t\ttoDoNext = comeAfter;\n\t\tcomeAfter (ident, what, ln, pos);\n\t\tbreak;\n\n\tdefault:\n\t\t/* don't care */\n\t\tbreak;\n\t}\n}\n\n/* Parse something like\n * typedef .... ident ;\n * ignoring the defined type but in the case of struct,\n * in which case struct are parsed.\n */\nstatic void parseTypedef (vString * const ident, objcToken what,\n\t\t\t\t\t\t  unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase ObjcSTRUCT:\n\t\ttoDoNext = &parseStruct;\n\t\tcomeAfter = &parseTypedef;\n\t\tbreak;\n\n\tcase ObjcENUM:\n\t\ttoDoNext = &parseEnum;\n\t\tcomeAfter = &parseTypedef;\n\t\tbreak;\n\n\tcase ObjcIDENTIFIER:\n\t\tvStringCopy (tempName, ident);\n\t\tbreak;\n\n\tcase Tok_semi:\t/* ';' */\n\t\taddTag (tempName, K_TYPEDEF);\n\t\tvStringClear (tempName);\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\n\tdefault:\n\t\t/* we don't care */\n\t\tbreak;\n\t}\n}\n\nstatic bool ignorePreprocStuff_escaped = false;\nstatic void ignorePreprocStuff (vString * const ident CTAGS_ATTR_UNUSED, objcToken what,\n\t\t\t\t\t\t\t\tunsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase Tok_Backslash:\n\t\tignorePreprocStuff_escaped = true;\n\t\tbreak;\n\n\tcase Tok_EOL:\n\t\tif (ignorePreprocStuff_escaped)\n\t\t{\n\t\t\tignorePreprocStuff_escaped = false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttoDoNext = &globalScope;\n\t\t}\n\t\tbreak;\n\n\tdefault:\n\t\tignorePreprocStuff_escaped = false;\n\t\tbreak;\n\t}\n}\n\nstatic void parseMacroName (vString * const ident, objcToken what,\n\t\t\t\t\t\t\tunsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tif (what == ObjcIDENTIFIER)\n\t\taddTag (ident, K_MACRO);\n\n\ttoDoNext = &ignorePreprocStuff;\n}\n\nstatic void parsePreproc (vString * const ident, objcToken what,\n\t\t\t\t\t\t  unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase ObjcIDENTIFIER:\n\t\tif (strcmp (vStringValue (ident), \"define\") == 0)\n\t\t\ttoDoNext = &parseMacroName;\n\t\telse\n\t\t\ttoDoNext = &ignorePreprocStuff;\n\t\tbreak;\n\n\tdefault:\n\t\ttoDoNext = &ignorePreprocStuff;\n\t\tbreak;\n\t}\n}\n\nstatic void skipCurlL (vString * const ident, objcToken what,\n\t\t\t\t\t   unsigned long ln CTAGS_ATTR_UNUSED, MIOPos pos CTAGS_ATTR_UNUSED)\n{\n\tif (what == Tok_CurlL)\n\t\ttoDoNext = comeAfter;\n}\n\nstatic void parseCPlusPlusCLinkage (vString * const ident, objcToken what,\n\t\t\t\t\t\t\t\t\tunsigned long ln, MIOPos pos)\n{\n\ttoDoNext = comeAfter;\n\n\t/* Linkage specification like \"C\" */\n\tif (what == Tok_CSTRING)\n\t\ttoDoNext = skipCurlL;\n\telse\n\t\t/* Force handle this ident in globalScope */\n\t\tglobalScope (ident, what, ln, pos);\n}\n\n/* Handle the \"strong\" top levels, all 'big' declarations\n * happen here */\nstatic void globalScope (vString * const ident, objcToken what,\n\t\t\t\t\t\t unsigned long ln, MIOPos pos)\n{\n\tswitch (what)\n\t{\n\tcase Tok_Sharp:\n\t\ttoDoNext = &parsePreproc;\n\t\tbreak;\n\n\tcase ObjcSTRUCT:\n\t\ttoDoNext = &parseStruct;\n\t\tcomeAfter = &globalScope;\n\t\tbreak;\n\n\tcase ObjcIDENTIFIER:\n\t\t/* we keep track of the identifier if we\n\t\t * come across a function. */\n\t\tvStringCopy (tempName, ident);\n\t\tbreak;\n\n\tcase Tok_PARL:\n\t\t/* if we find an opening parenthesis it means we\n\t\t * found a function (or a macro...) */\n\t\taddTag (tempName, K_FUNCTION);\n\t\tvStringClear (tempName);\n\t\tcomeAfter = &globalScope;\n\t\ttoDoNext = &ignoreBalanced;\n\t\tignoreBalanced (ident, what, ln, pos);\n\t\tbreak;\n\n\tcase ObjcINTERFACE:\n\t\ttoDoNext = &parseInterface;\n\t\tbreak;\n\n\tcase ObjcIMPLEMENTATION:\n\t\ttoDoNext = &parseImplementation;\n\t\tbreak;\n\n\tcase ObjcPROTOCOL:\n\t\ttoDoNext = &parseProtocol;\n\t\tbreak;\n\n\tcase ObjcTYPEDEF:\n\t\ttoDoNext = parseTypedef;\n\t\tcomeAfter = &globalScope;\n\t\tbreak;\n\n\tcase Tok_CurlL:\n\t\tcomeAfter = &globalScope;\n\t\ttoDoNext = &ignoreBalanced;\n\t\tignoreBalanced (ident, what, ln, pos);\n\t\tbreak;\n\n\tcase ObjcEXTERN:\n\t\tcomeAfter = &globalScope;\n\t\ttoDoNext = &parseCPlusPlusCLinkage;\n\t\tbreak;\n\n\tcase ObjcEND:\n\tcase ObjcPUBLIC:\n\tcase ObjcPROTECTED:\n\tcase ObjcPRIVATE:\n\n\tdefault:\n\t\t/* we don't care */\n\t\tbreak;\n\t}\n}\n\n/*////////////////////////////////////////////////////////////////\n//// Deal with the system                                       */\n\nstatic void findObjcTags (void)\n{\n\tvString *name = vStringNew ();\n\tlexingState st;\n\tobjcToken tok;\n\n\tparentName = vStringNew ();\n\ttempName = vStringNew ();\n\tfullMethodName = objcStringNew ();\n\tprevIdent = objcStringNew ();\n\tsignature = vStringNewInit (\"(\");\n\n\t/* (Re-)initialize state variables, this might be a second file */\n\tcomeAfter = NULL;\n\tfallback = NULL;\n\tparentType = K_INTERFACE;\n\tignoreBalanced_count = 0;\n\tmethodKind = 0;\n\tparseStruct_gotName = false;\n\tparseEnumFields_prev = NULL;\n\tparseEnum_named = false;\n\tignorePreprocStuff_escaped = false;\n\n\tst.name = vStringNew ();\n\tupdateLine(&st);\n\ttoDoNext = &globalScope;\n\ttok = lex (&st);\n\twhile (tok != Tok_EOF)\n\t{\n\t\t(*toDoNext) (st.name, tok, st.ln, st.pos);\n\t\ttok = lex (&st);\n\t}\n\tvStringDelete(st.name);\n\n\tvStringDelete (name);\n\tvStringDelete (parentName);\n\tvStringDelete (tempName);\n\tobjcStringDelete (fullMethodName);\n\tobjcStringDelete (prevIdent);\n\tvStringDelete (signature);\n\tsignature = NULL;\n\tparentName = NULL;\n\ttempName = NULL;\n\tprevIdent = NULL;\n\tfullMethodName = NULL;\n\tcategoryCorkIndex = CORK_NIL;\n\tparentCorkIndex = CORK_NIL;\n}\n\nstatic void objcInitialize (const langType language)\n{\n\tLang_ObjectiveC = language;\n}\n\nextern parserDefinition *ObjcParser (void)\n{\n\tstatic const char *const extensions[] = { \"mm\", \"m\", \"h\",\n\t\t\t\t\t\t  NULL };\n\tstatic const char *const aliases[] = { \"objc\", \"objective-c\",\n\t\t\t\t\t       NULL };\n\tstatic selectLanguage selectors[] = { selectByObjectiveCAndMatLabKeywords,\n\t\t\t\t\t      selectByObjectiveCKeywords,\n\t\t\t\t\t      NULL };\n\tparserDefinition *def = parserNew (\"ObjectiveC\");\n\tdef->kindTable = ObjcKinds;\n\tdef->kindCount = ARRAY_SIZE (ObjcKinds);\n\tdef->extensions = extensions;\n\tdef->fieldTable = ObjcFields;\n\tdef->fieldCount = ARRAY_SIZE (ObjcFields);\n\tdef->aliases = aliases;\n\tdef->parser = findObjcTags;\n\tdef->initialize = objcInitialize;\n\tdef->selectLanguage = selectors;\n\tdef->keywordTable = objcKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (objcKeywordTable);\n\tdef->useCork = CORK_QUEUE;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/ocaml.c",
    "content": "/*\n*   Copyright (c) 2009, Vincent Berthoux\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Objective Caml\n*   language files.\n*/\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n#define OCAML_MAX_STACK_SIZE 256\n\ntypedef enum {\n\tK_CLASS,        /* OCaml class, relatively rare */\n\tK_METHOD,       /* class method */\n\tK_MODULE,       /* OCaml module OR functor */\n\tK_VARIABLE,\n\tK_VAL,\n\tK_TYPE,         /* name of an OCaml type */\n\tK_FUNCTION,\n\tK_CONSTRUCTOR,  /* Constructor of a sum type */\n\tK_RECORDFIELD,\n\tK_EXCEPTION,\n} ocamlKind;\n\nstatic kindDefinition OcamlKinds[] = {\n\t{true, 'c', \"class\", \"classes\"},\n\t{true, 'm', \"method\", \"Object's method\"},\n\t{true, 'M', \"module\", \"Module or functor\"},\n\t{true, 'v', \"var\", \"Global variable\"},\n\t{true, 'p', \"val\", \"Signature item\"},\n\t{true, 't', \"type\", \"Type name\"},\n\t{true, 'f', \"function\", \"A function\"},\n\t{true, 'C', \"Constructor\", \"A constructor\"},\n\t{true, 'r', \"RecordField\", \"A 'structure' field\"},\n\t{true, 'e', \"Exception\", \"An exception\"},\n};\n\ntypedef enum {\n\tOcaKEYWORD_and,\n\tOcaKEYWORD_begin,\n\tOcaKEYWORD_class,\n\tOcaKEYWORD_do,\n\tOcaKEYWORD_done,\n\tOcaKEYWORD_else,\n\tOcaKEYWORD_end,\n\tOcaKEYWORD_exception,\n\tOcaKEYWORD_for,\n\tOcaKEYWORD_functor,\n\tOcaKEYWORD_fun,\n\tOcaKEYWORD_function,\n\tOcaKEYWORD_if,\n\tOcaKEYWORD_in,\n\tOcaKEYWORD_let,\n\tOcaKEYWORD_value,\n\tOcaKEYWORD_match,\n\tOcaKEYWORD_method,\n\tOcaKEYWORD_module,\n\tOcaKEYWORD_mutable,\n\tOcaKEYWORD_object,\n\tOcaKEYWORD_of,\n\tOcaKEYWORD_rec,\n\tOcaKEYWORD_sig,\n\tOcaKEYWORD_struct,\n\tOcaKEYWORD_then,\n\tOcaKEYWORD_try,\n\tOcaKEYWORD_type,\n\tOcaKEYWORD_val,\n\tOcaKEYWORD_virtual,\n\tOcaKEYWORD_while,\n\tOcaKEYWORD_with,\n\n\tOcaIDENTIFIER,\n\tTok_PARL,       /* '(' */\n\tTok_PARR,       /* ')' */\n\tTok_BRL,        /* '[' */\n\tTok_BRR,        /* ']' */\n\tTok_CurlL,      /* '{' */\n\tTok_CurlR,      /* '}' */\n\tTok_Prime,      /* '\\'' */\n\tTok_Pipe,       /* '|' */\n\tTok_EQ,         /* '=' */\n\tTok_Val,        /* string/number/poo */\n\tTok_Op,         /* any operator recognized by the language */\n\tTok_semi,       /* ';' */\n\tTok_comma,      /* ',' */\n\tTok_To,         /* '->' */\n\tTok_Of,         /* ':' */\n\tTok_Sharp,      /* '#' */\n\tTok_Backslash,  /* '\\\\' */\n\n\tTok_EOF         /* END of file */\n} ocamlKeyword;\n\ntypedef struct sOcaKeywordDesc {\n\tconst char *name;\n\tocamlKeyword id;\n} ocaKeywordDesc;\n\ntypedef ocamlKeyword ocaToken;\n\nstatic const keywordTable OcamlKeywordTable[] = {\n\t{ \"and\"       , OcaKEYWORD_and       },\n\t{ \"begin\"     , OcaKEYWORD_begin     },\n\t{ \"class\"     , OcaKEYWORD_class     },\n\t{ \"do\"        , OcaKEYWORD_do        },\n\t{ \"done\"      , OcaKEYWORD_done      },\n\t{ \"else\"      , OcaKEYWORD_else      },\n\t{ \"end\"       , OcaKEYWORD_end       },\n\t{ \"exception\" , OcaKEYWORD_exception },\n\t{ \"for\"       , OcaKEYWORD_for       },\n\t{ \"fun\"       , OcaKEYWORD_fun       },\n\t{ \"function\"  , OcaKEYWORD_fun       },\n\t{ \"functor\"   , OcaKEYWORD_functor   },\n\t{ \"if\"        , OcaKEYWORD_if        },\n\t{ \"in\"        , OcaKEYWORD_in        },\n\t{ \"let\"       , OcaKEYWORD_let       },\n\t{ \"match\"     , OcaKEYWORD_match     },\n\t{ \"method\"    , OcaKEYWORD_method    },\n\t{ \"module\"    , OcaKEYWORD_module    },\n\t{ \"mutable\"   , OcaKEYWORD_mutable   },\n\t{ \"object\"    , OcaKEYWORD_object    },\n\t{ \"of\"        , OcaKEYWORD_of        },\n\t{ \"rec\"       , OcaKEYWORD_rec       },\n\t{ \"sig\"       , OcaKEYWORD_sig       },\n\t{ \"struct\"    , OcaKEYWORD_struct    },\n\t{ \"then\"      , OcaKEYWORD_then      },\n\t{ \"try\"       , OcaKEYWORD_try       },\n\t{ \"type\"      , OcaKEYWORD_type      },\n\t{ \"val\"       , OcaKEYWORD_val       },\n\t{ \"value\"     , OcaKEYWORD_value     }, /* just to handle revised syntax */\n\t{ \"virtual\"   , OcaKEYWORD_virtual   },\n\t{ \"while\"     , OcaKEYWORD_while     },\n\t{ \"with\"      , OcaKEYWORD_with      },\n\n\t{ \"or\"        , Tok_Op               },\n\t{ \"mod \"      , Tok_Op               },\n\t{ \"land \"     , Tok_Op               },\n\t{ \"lor \"      , Tok_Op               },\n\t{ \"lxor \"     , Tok_Op               },\n\t{ \"lsl \"      , Tok_Op               },\n\t{ \"lsr \"      , Tok_Op               },\n\t{ \"asr\"       , Tok_Op               },\n\t{ \"->\"        , Tok_To               },\n\t{ \":\"         , Tok_Of               },\n\t{ \"true\"      , Tok_Val              },\n\t{ \"false\"     , Tok_Val              }\n};\n\nstatic langType Lang_Ocaml;\n\nstatic bool exportLocalInfo = false;\n\n/*//////////////////////////////////////////////////////////////////\n//// lexingInit             */\ntypedef struct _lexingState {\n\tvString *name;\t/* current parsed identifier/operator */\n\tconst unsigned char *cp;\t/* position in stream */\n} lexingState;\n\n/* array of the size of all possible value for a char */\nstatic bool isOperator[1 << (8 * sizeof (char))] = { false };\n\n/* definition of all the operator in OCaml,\n * /!\\ certain operator get special treatment\n * in regards of their role in OCaml grammar :\n * '|' ':' '=' '~' and '?' */\nstatic void initOperatorTable ( void )\n{\n\tisOperator['!'] = true;\n\tisOperator['$'] = true;\n\tisOperator['%'] = true;\n\tisOperator['&'] = true;\n\tisOperator['*'] = true;\n\tisOperator['+'] = true;\n\tisOperator['-'] = true;\n\tisOperator['.'] = true;\n\tisOperator['/'] = true;\n\tisOperator[':'] = true;\n\tisOperator['<'] = true;\n\tisOperator['='] = true;\n\tisOperator['>'] = true;\n\tisOperator['?'] = true;\n\tisOperator['@'] = true;\n\tisOperator['^'] = true;\n\tisOperator['~'] = true;\n\tisOperator['|'] = true;\n}\n\n/*//////////////////////////////////////////////////////////////////////\n//// Lexing                                     */\nstatic bool isNum (char c)\n{\n\treturn c >= '0' && c <= '9';\n}\n\nstatic bool isLowerAlpha (char c)\n{\n\treturn c >= 'a' && c <= 'z';\n}\n\nstatic bool isUpperAlpha (char c)\n{\n\treturn c >= 'A' && c <= 'Z';\n}\n\nstatic bool isAlpha (char c)\n{\n\treturn isLowerAlpha (c) || isUpperAlpha (c);\n}\n\nstatic bool isIdent (char c)\n{\n\treturn isNum (c) || isAlpha (c) || c == '_' || c == '\\'';\n}\n\nstatic bool isSpace (char c)\n{\n\treturn c == ' ' || c == '\\t' || c == '\\r' || c == '\\n';\n}\n\nstatic void eatWhiteSpace (lexingState * st)\n{\n\tconst unsigned char *cp = st->cp;\n\twhile (isSpace (*cp))\n\t\tcp++;\n\n\tst->cp = cp;\n}\n\nstatic void eatString (lexingState * st)\n{\n\tbool lastIsBackSlash = false;\n\tbool unfinished = true;\n\tconst unsigned char *c = st->cp + 1;\n\n\twhile (unfinished)\n\t{\n\t\t/* end of line should never happen.\n\t\t * we tolerate it */\n\t\tif (c == NULL || c[0] == '\\0')\n\t\t\tbreak;\n\t\telse if (*c == '\"' && !lastIsBackSlash)\n\t\t\tunfinished = false;\n\t\telse\n\t\t\tlastIsBackSlash = *c == '\\\\';\n\n\t\tc++;\n\t}\n\n\tst->cp = c;\n}\n\nstatic void eatComment (lexingState * st)\n{\n\tbool unfinished = true;\n\tbool lastIsStar = false;\n\tconst unsigned char *c = st->cp + 2;\n\n\twhile (unfinished)\n\t{\n\t\t/* we've reached the end of the line..\n\t\t * so we have to reload a line... */\n\t\tif (c == NULL || *c == '\\0')\n\t\t{\n\t\t\tst->cp = readLineFromInputFile ();\n\t\t\t/* WOOPS... no more input...\n\t\t\t * we return, next lexing read\n\t\t\t * will be null and ok */\n\t\t\tif (st->cp == NULL)\n\t\t\t\treturn;\n\t\t\tc = st->cp;\n\t\t}\n\t\t/* we've reached the end of the comment */\n\t\telse if (*c == ')' && lastIsStar)\n\t\t{\n\t\t\tunfinished = false;\n\t\t\tc++;\n\t\t}\n\t\t/* here we deal with imbricated comment, which\n\t\t * are allowed in OCaml */\n\t\telse if (c[0] == '(' && c[1] == '*')\n\t\t{\n\t\t\tst->cp = c;\n\t\t\teatComment (st);\n\n\t\t\tc = st->cp;\n\t\t\tif (c == NULL)\n\t\t\t\treturn;\n\n\t\t\tlastIsStar = false;\n\t\t\tc++;\n\t\t}\n\t\t/* OCaml has a rule which says :\n\t\t *\n\t\t *   \"Comments do not occur inside string or character literals.\n\t\t *    Nested comments are handled correctly.\"\n\t\t *\n\t\t * So if we encounter a string beginning, we must parse it to\n\t\t * get a good comment nesting (bug ID: 3117537)\n\t\t */\n\t\telse if (*c == '\"')\n\t\t{\n\t\t\tst->cp = c;\n\t\t\teatString (st);\n\t\t\tc = st->cp;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlastIsStar = '*' == *c;\n\t\t\tc++;\n\t\t}\n\t}\n\n\tst->cp = c;\n}\n\nstatic void readIdentifier (lexingState * st)\n{\n\tconst unsigned char *p;\n\tvStringClear (st->name);\n\n\t/* first char is a simple letter */\n\tif (isAlpha (*st->cp) || *st->cp == '_')\n\t\tvStringPut (st->name, *st->cp);\n\n\t/* Go till you get identifier chars */\n\tfor (p = st->cp + 1; isIdent (*p); p++)\n\t\tvStringPut (st->name, *p);\n\n\tst->cp = p;\n}\n\nstatic ocamlKeyword eatNumber (lexingState * st)\n{\n\twhile (isNum (*st->cp))\n\t\tst->cp++;\n\treturn Tok_Val;\n}\n\n/* Operator can be defined in OCaml as a function\n * so we must be ample enough to parse them normally */\nstatic ocamlKeyword eatOperator (lexingState * st)\n{\n\tint count = 0;\n\tconst unsigned char *root = st->cp;\n\n\tvStringClear (st->name);\n\n\twhile (isOperator[st->cp[count]])\n\t{\n\t\tvStringPut (st->name, st->cp[count]);\n\t\tcount++;\n\t}\n\n\tst->cp += count;\n\tif (count <= 1)\n\t{\n\t\tswitch (root[0])\n\t\t{\n\t\tcase '|':\n\t\t\treturn Tok_Pipe;\n\t\tcase '=':\n\t\t\treturn Tok_EQ;\n\t\tcase ':':\n\t\t\treturn Tok_Of;\n\t\tdefault:\n\t\t\treturn Tok_Op;\n\t\t}\n\t}\n\telse if (count == 2 && root[0] == '-' && root[1] == '>')\n\t\treturn Tok_To;\n\telse if (count == 2 && root[0] == '|' && root[1] == '>')\n\t\treturn Tok_Op;\n\telse\n\t\treturn Tok_Op;\n}\n\n/* The lexer is in charge of reading the file.\n * Some of sub-lexer (like eatComment) also read file.\n * lexing is finished when the lexer return Tok_EOF */\nstatic ocamlKeyword lex (lexingState * st)\n{\n\tint retType;\n\t/* handling data input here */\n\twhile (st->cp == NULL || st->cp[0] == '\\0')\n\t{\n\t\tst->cp = readLineFromInputFile ();\n\t\tif (st->cp == NULL)\n\t\t\treturn Tok_EOF;\n\t}\n\n\tif (isAlpha (*st->cp))\n\t{\n\t\treadIdentifier (st);\n\t\tretType = lookupKeyword (vStringValue (st->name), Lang_Ocaml);\n\n\t\tif (retType == -1)\t/* If it's not a keyword */\n\t\t{\n\t\t\treturn OcaIDENTIFIER;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn retType;\n\t\t}\n\t}\n\telse if (isNum (*st->cp))\n\t\treturn eatNumber (st);\n\telse if (isSpace (*st->cp))\n\t{\n\t\teatWhiteSpace (st);\n\t\treturn lex (st);\n\t}\n\telse if (*st->cp == '_')\n\t{\t// special\n\t\treadIdentifier (st);\n\t\treturn Tok_Val;\n\t}\n\n\t/* OCaml permit the definition of our own operators\n\t * so here we check all the consecutive chars which\n\t * are operators to discard them. */\n\telse if (isOperator[*st->cp])\n\t\treturn eatOperator (st);\n\telse\n\t{\n\t\tswitch (*st->cp)\n\t\t{\n\t\tcase '(':\n\t\t\tif (st->cp[1] == '*')\t/* ergl, a comment */\n\t\t\t{\n\t\t\t\teatComment (st);\n\t\t\t\treturn lex (st);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tst->cp++;\n\t\t\t\treturn Tok_PARL;\n\t\t\t}\n\n\t\tcase ')':\n\t\t\tst->cp++;\n\t\t\treturn Tok_PARR;\n\t\tcase '[':\n\t\t\tst->cp++;\n\t\t\treturn Tok_BRL;\n\t\tcase ']':\n\t\t\tst->cp++;\n\t\t\treturn Tok_BRR;\n\t\tcase '{':\n\t\t\tst->cp++;\n\t\t\treturn Tok_CurlL;\n\t\tcase '}':\n\t\t\tst->cp++;\n\t\t\treturn Tok_CurlR;\n\t\tcase '\\'':\n\t\t\tst->cp++;\n\t\t\treturn Tok_Prime;\n\t\tcase ',':\n\t\t\tst->cp++;\n\t\t\treturn Tok_comma;\n\t\tcase '=':\n\t\t\tst->cp++;\n\t\t\treturn Tok_EQ;\n\t\tcase ';':\n\t\t\tst->cp++;\n\t\t\treturn Tok_semi;\n\t\tcase '\"':\n\t\t\teatString (st);\n\t\t\treturn Tok_Val;\n\t\tcase '#':\n\t\t\tst->cp++;\n\t\t\treturn Tok_Sharp;\n\t\tcase '\\\\':\n\t\t\tst->cp++;\n\t\t\treturn Tok_Backslash;\n\t\tdefault:\n\t\t\tst->cp++;\n\t\t\tbreak;\n\t\t}\n\t}\n\t/* default return if nothing is recognized,\n\t * shouldn't happen, but at least, it will\n\t * be handled without destroying the parsing. */\n\treturn Tok_Val;\n}\n\n/*//////////////////////////////////////////////////////////////////////\n//// Parsing                                    */\ntypedef void (*parseNext) (vString * const ident, ocaToken what, ocaToken whatNext);\n\n/********** Helpers */\n/* This variable hold the 'parser' which is going to\n * handle the next token */\nstatic parseNext toDoNext;\n\n/* Special variable used by parser eater to\n * determine which action to put after their\n * job is finished. */\nstatic parseNext comeAfter;\n\n/* If a token put an end to current declaration/\n * statement */\nstatic ocaToken terminatingToken;\n\n/* Token to be searched by the different\n * parser eater. */\nstatic ocaToken waitedToken;\n\n/* name of the last class, used for\n * context stacking. */\nstatic vString *lastClass;\n\ntypedef enum _sContextKind {\n\tContextStrong,\n\tContextSoft\n} contextKind;\n\ntypedef enum _sContextType {\n\tContextType,\n\tContextModule,\n\tContextClass,\n\tContextValue,\n\tContextFunction,\n\tContextMethod,\n\tContextBlock,\n\tContextMatch\n} contextType;\n\ntypedef struct _sOcamlContext {\n\tcontextKind kind;\t/* well if the context is strong or not */\n\tcontextType type;\n\tparseNext callback;\t/* what to do when a context is pop'd */\n\tvString *contextName;\t/* name, if any, of the surrounding context */\n} ocamlContext;\n\n/* context stack, can be used to output scope information\n * into the tag file. */\nstatic ocamlContext stack[OCAML_MAX_STACK_SIZE];\n/* current position in the tag */\nstatic int stackIndex;\n\n/* special function, often recalled, so putting it here */\nstatic void globalScope (vString * const ident, ocaToken what, ocaToken whatNext);\n\n/* Return : index of the last named context if one\n *          is found, -1 otherwise */\nstatic int getLastNamedIndex ( void )\n{\n\tint i;\n\n\tfor (i = stackIndex - 1; i >= 0; --i)\n\t{\n\t\tif (vStringLength (stack[i].contextName) > 0)\n\t\t{\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n}\n\nstatic int contextDescription (contextType t)\n{\n\tswitch (t)\n\t{\n\tcase ContextFunction:\n\t\treturn K_FUNCTION;\n\tcase ContextMethod:\n\t\treturn K_METHOD;\n\tcase ContextValue:\n\t\treturn K_VAL;\n\tcase ContextModule:\n\t\treturn K_MODULE;\n\tcase ContextType:\n\t\treturn K_TYPE;\n\tcase ContextClass:\n\t\treturn K_CLASS;\n\tdefault:\n\t\tAssertNotReached();\n\t\treturn KIND_GHOST_INDEX;\n\t}\n}\n\nstatic char contextTypeSuffix (contextType t)\n{\n\tswitch (t)\n\t{\n\tcase ContextFunction:\n\tcase ContextMethod:\n\tcase ContextValue:\n\tcase ContextModule:\n\t\treturn '/';\n\tcase ContextType:\n\t\treturn '.';\n\tcase ContextClass:\n\t\treturn '#';\n\tcase ContextBlock:\n\t\treturn ' ';\n\tcase ContextMatch:\n\t\treturn '|';\n\tdefault:\n\t\treturn '$';\n\t}\n}\n\n/* Push a new context, handle null string */\nstatic void pushContext (contextKind kind, contextType type, parseNext after,\n\tvString const *contextName)\n{\n\tint parentIndex;\n\n\tif (stackIndex >= OCAML_MAX_STACK_SIZE)\n\t{\n\t\tverbose (\"OCaml Maximum depth reached\");\n\t\treturn;\n\t}\n\n\tstack[stackIndex].kind = kind;\n\tstack[stackIndex].type = type;\n\tstack[stackIndex].callback = after;\n\n\tparentIndex = getLastNamedIndex ();\n\tif (contextName == NULL)\n\t{\n\t\tvStringClear (stack[stackIndex++].contextName);\n\t\treturn;\n\t}\n\n\tif (parentIndex >= 0)\n\t{\n\t\tvStringCopy (stack[stackIndex].contextName,\n\t\t\tstack[parentIndex].contextName);\n\t\tvStringPut (stack[stackIndex].contextName,\n\t\t\tcontextTypeSuffix (stack[parentIndex].type));\n\n\t\tvStringCat (stack[stackIndex].contextName, contextName);\n\t}\n\telse\n\t\tvStringCopy (stack[stackIndex].contextName, contextName);\n\n\tstackIndex++;\n}\n\nstatic void pushStrongContext (vString * name, contextType type)\n{\n\tpushContext (ContextStrong, type, &globalScope, name);\n}\n\nstatic void pushSoftContext (parseNext continuation,\n\tvString * name, contextType type)\n{\n\tpushContext (ContextSoft, type, continuation, name);\n}\n\nstatic void pushEmptyContext (parseNext continuation)\n{\n\tpushContext (ContextSoft, ContextValue, continuation, NULL);\n}\n\n/* unroll the stack until the last named context.\n * then discard it. Used to handle the :\n * let f x y = ...\n * in ...\n * where the context is reseted after the in. Context may have\n * been really nested before that. */\nstatic void popLastNamed ( void )\n{\n\tint i = getLastNamedIndex ();\n\n\tif (i >= 0)\n\t{\n\t\tstackIndex = i;\n\t\ttoDoNext = stack[i].callback;\n\t\tvStringClear (stack[i].contextName);\n\t}\n\telse\n\t{\n\t\t/* ok, no named context found...\n\t\t * (should not happen). */\n\t\tstackIndex = 0;\n\t\ttoDoNext = &globalScope;\n\t}\n}\n\n/* pop a context without regarding it's content\n * (beside handling empty stack case) */\nstatic void popSoftContext ( void )\n{\n\tif (stackIndex <= 0)\n\t{\n\t\ttoDoNext = &globalScope;\n\t}\n\telse\n\t{\n\t\tstackIndex--;\n\t\ttoDoNext = stack[stackIndex].callback;\n\t\tvStringClear (stack[stackIndex].contextName);\n\t}\n}\n\n/* Reset everything until the last global space.\n * a strong context can be :\n * - module\n * - class definition\n * - the initial global space\n * - a _global_ declaration (let at global scope or in a module).\n * Created to exit quickly deeply nested context */\nstatic contextType popStrongContext ( void )\n{\n\tint i;\n\n\tfor (i = stackIndex - 1; i >= 0; --i)\n\t{\n\t\tif (stack[i].kind == ContextStrong)\n\t\t{\n\t\t\tstackIndex = i;\n\t\t\ttoDoNext = stack[i].callback;\n\t\t\tvStringClear (stack[i].contextName);\n\t\t\treturn stack[i].type;\n\t\t}\n\t}\n\t/* ok, no strong context found... */\n\tstackIndex = 0;\n\ttoDoNext = &globalScope;\n\treturn -1;\n}\n\n/* Reset everything before the last match. */\nstatic void jumpToMatchContext ( void )\n{\n\tint i;\n\tfor (i = stackIndex - 1; i >= 0; --i)\n\t{\n\t\tif (stack[i].type == ContextMatch)\n\t\t{\n\t\t\tstackIndex = i + 1;\n\t\t\ttoDoNext = stack[i].callback;\t// this should always be\n\t\t\t\t\t\t\t// matchPattern\n\t\t\tstack[i + 1].callback = NULL;\n\t\t\tvStringClear (stack[i + 1].contextName);\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/* Ignore everything till waitedToken and jump to comeAfter.\n * If the \"end\" keyword is encountered break, doesn't remember\n * why though. */\nstatic void tillToken (vString * const ident CTAGS_ATTR_UNUSED, ocaToken what, ocaToken whatNext CTAGS_ATTR_UNUSED)\n{\n\tif (what == waitedToken)\n\t\ttoDoNext = comeAfter;\n\telse if (what == OcaKEYWORD_end)\n\t{\n\t\tpopStrongContext ();\n\t\ttoDoNext = &globalScope;\n\t}\n}\n\n/* Ignore everything till a waitedToken is seen, but\n * take care of balanced parentheses/bracket use */\nstatic void contextualTillToken (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tstatic int parentheses = 0;\n\tstatic int bracket = 0;\n\tstatic int curly = 0;\n\n\tswitch (what)\n\t{\n\tcase Tok_PARL:\n\t\tparentheses--;\n\t\tbreak;\n\tcase Tok_PARR:\n\t\tparentheses++;\n\t\tbreak;\n\tcase Tok_CurlL:\n\t\tcurly--;\n\t\tbreak;\n\tcase Tok_CurlR:\n\t\tcurly++;\n\t\tbreak;\n\tcase Tok_BRL:\n\t\tbracket--;\n\t\tbreak;\n\tcase Tok_BRR:\n\t\tbracket++;\n\t\tbreak;\n\n\tdefault:\t/* other token are ignored */\n\t\tbreak;\n\t}\n\n\tif (what == waitedToken && parentheses == 0 && bracket == 0 && curly == 0)\n\t\ttoDoNext = comeAfter;\n\telse if (what == OcaKEYWORD_end)\n\t\tglobalScope (ident, what, whatNext);\n}\n\n/* Wait for waitedToken and jump to comeAfter or let\n * the globalScope handle declarations */\nstatic void tillTokenOrFallback (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tif (what == waitedToken)\n\t\ttoDoNext = comeAfter;\n\telse\n\t\tglobalScope (ident, what, whatNext);\n}\n\n/* ignore token till waitedToken, or give up if find\n * terminatingToken. Use globalScope to handle new\n * declarations. */\nstatic void tillTokenOrTerminatingOrFallback (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tif (what == waitedToken)\n\t\ttoDoNext = comeAfter;\n\telse if (what == terminatingToken)\n\t\ttoDoNext = globalScope;\n\telse\n\t\tglobalScope (ident, what, whatNext);\n}\n\n/* ignore the next token in the stream and jump to the\n * given comeAfter state */\nstatic void ignoreToken (vString * const ident CTAGS_ATTR_UNUSED, ocaToken what CTAGS_ATTR_UNUSED, ocaToken whatNext CTAGS_ATTR_UNUSED)\n{\n\ttoDoNext = comeAfter;\n}\n\n/********** Grammar */\n/* the purpose of each function is detailed near their\n * implementation */\n\nstatic contextType killCurrentState ( void )\n{\n\tcontextType popped = popStrongContext ();\n\n\t/* Tracking the kind of previous strong\n\t * context, if it doesn't match with a\n\t * really strong entity, repop */\n\tswitch (popped)\n\t{\n\tcase ContextValue:\n\t\tpopped = popStrongContext ();\n\t\tbreak;\n\tcase ContextFunction:\n\t\tpopped = popStrongContext ();\n\t\tbreak;\n\tcase ContextMethod:\n\t\tpopped = popStrongContext ();\n\t\tbreak;\n\tcase ContextType:\n\t\tpopped = popStrongContext ();\n\t\tbreak;\n\tcase ContextMatch:\n\t\tpopped = popStrongContext ();\n\t\tbreak;\n\tcase ContextBlock:\n\t\tbreak;\n\tcase ContextModule:\n\t\tbreak;\n\tcase ContextClass:\n\t\tbreak;\n\tdefault:\n\t\t/* nothing more */\n\t\tbreak;\n\t}\n\treturn popped;\n}\n\n/* Keep track of our _true_ line number and file pos,\n * as the lookahead token gives us false values. */\nstatic unsigned long ocaLineNumber;\nstatic MIOPos ocaFilePosition;\n\n/* Used to prepare an OCaml tag, just in case there is a need to\n * add additional information to the tag. */\nstatic void prepareTag (tagEntryInfo * tag, vString const *name, int kind)\n{\n\tint parentIndex;\n\n\tinitTagEntry (tag, vStringValue (name), kind);\n\t/* Ripped out of read.h initTagEntry, because of line number\n\t * shenanigans.\n\t * Ugh. Lookahead is harder than I expected. */\n\tupdateTagLine(tag, ocaLineNumber, ocaFilePosition);\n\n\tparentIndex = getLastNamedIndex ();\n\tif (parentIndex >= 0)\n\t{\n\t\ttag->extensionFields.scopeKindIndex =\n\t\t\tcontextDescription (stack[parentIndex].type);\n\t\ttag->extensionFields.scopeName =\n\t\t\tvStringValue (stack[parentIndex].contextName);\n\t}\n}\n\n/* Used to centralise tag creation, and be able to add\n * more information to it in the future */\nstatic void addTag (vString * const ident, int kind)\n{\n\tif (OcamlKinds [kind].enabled  &&  ident != NULL  &&  vStringLength (ident) > 0)\n\t{\n\t\ttagEntryInfo toCreate;\n\t\tprepareTag (&toCreate, ident, kind);\n\t\tmakeTagEntry (&toCreate);\n\t}\n}\n\nstatic bool needStrongPoping = false;\nstatic void requestStrongPoping ( void )\n{\n\tneedStrongPoping = true;\n}\n\nstatic void cleanupPreviousParser ( void )\n{\n\tif (needStrongPoping)\n\t{\n\t\tneedStrongPoping = false;\n\t\tpopStrongContext ();\n\t}\n}\n\n/* Due to some circular dependencies, the following functions\n * must be forward-declared. */\nstatic void letParam (vString * const ident, ocaToken what, ocaToken whatNext);\nstatic void localScope (vString * const ident, ocaToken what, ocaToken whatNext);\nstatic void mayRedeclare (vString * const ident, ocaToken what, ocaToken whatNext);\nstatic void typeSpecification (vString * const ident, ocaToken what, ocaToken whatNext);\n\n/*\n * Parse a record type\n * type ident = // parsed previously\n *  {\n *      ident1: type1;\n *      ident2: type2;\n *  }\n */\nstatic void typeRecord (vString * const ident, ocaToken what, ocaToken whatNext CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase OcaIDENTIFIER:\n\t\taddTag (ident, K_RECORDFIELD);\n\t\tterminatingToken = Tok_CurlR;\n\t\twaitedToken = Tok_semi;\n\t\tcomeAfter = &typeRecord;\n\t\ttoDoNext = &tillTokenOrTerminatingOrFallback;\n\t\tbreak;\n\n\tcase OcaKEYWORD_mutable:\n\t\t/* ignore it */\n\t\tbreak;\n\n\tcase Tok_CurlR:\n\t\tpopStrongContext ();\n\t\t// don't pop the module context when going to another expression\n\t\tneedStrongPoping = false;\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\n\tdefault:\t/* don't care */\n\t\tbreak;\n\t}\n}\n\n/* handle :\n * exception ExceptionName of ... */\nstatic void exceptionDecl (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tif (what == OcaIDENTIFIER)\n\t{\n\t\taddTag (ident, K_EXCEPTION);\n\t}\n\telse /* probably ill-formed, give back to global scope */\n\t{\n\t\tglobalScope (ident, what, whatNext);\n\t}\n\ttoDoNext = &globalScope;\n}\n\nstatic tagEntryInfo tempTag;\nstatic vString *tempIdent;\n\n/* Ensure a constructor is not a type path beginning\n * with a module */\nstatic void constructorValidation (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tswitch (what)\n\t{\n\tcase Tok_Op:\t/* if we got a '.' which is an operator */\n\t\ttoDoNext = &globalScope;\n\t\tpopStrongContext ();\n\t\tneedStrongPoping = false;\n\t\tbreak;\n\n\tcase OcaKEYWORD_of:\t/* OK, it must be a constructor :) */\n\t\tif (vStringLength (tempIdent) > 0)\n\t\t{\n\t\t\tmakeTagEntry (&tempTag);\n\t\t\tvStringClear (tempIdent);\n\t\t}\n\t\ttoDoNext = &tillTokenOrFallback;\n\t\tcomeAfter = &typeSpecification;\n\t\twaitedToken = Tok_Pipe;\n\t\tbreak;\n\n\tcase Tok_Pipe:\t/* OK, it was a constructor :)  */\n\t\tif (vStringLength (tempIdent) > 0)\n\t\t{\n\t\t\tmakeTagEntry (&tempTag);\n\t\t\tvStringClear (tempIdent);\n\t\t}\n\t\ttoDoNext = &typeSpecification;\n\t\tbreak;\n\n\tdefault:\t/* and mean that we're not facing a module name */\n\t\tif (vStringLength (tempIdent) > 0)\n\t\t{\n\t\t\tmakeTagEntry (&tempTag);\n\t\t\tvStringClear (tempIdent);\n\t\t}\n\t\ttoDoNext = &tillTokenOrFallback;\n\t\tcomeAfter = &typeSpecification;\n\t\twaitedToken = Tok_Pipe;\n\n\t\tpopStrongContext ();\n\n\t\t// don't pop the module context when going to another expression\n\t\tneedStrongPoping = false;\n\n\t\t/* to be sure we use this token */\n\t\tglobalScope (ident, what, whatNext);\n\t}\n}\n\n/* Parse beginning of type definition\n * type 'avar ident =\n * or\n * type ('var1, 'var2) ident =\n */\nstatic void typeDecl (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tswitch (what)\n\t{\n\t\t/* parameterized */\n\tcase Tok_Prime:\n\t\tcomeAfter = &typeDecl;\n\t\ttoDoNext = &ignoreToken;\n\t\tbreak;\n\t\t/* LOTS of parameters */\n\tcase Tok_PARL:\n\t\tcomeAfter = &typeDecl;\n\t\twaitedToken = Tok_PARR;\n\t\ttoDoNext = &tillToken;\n\t\tbreak;\n\n\tcase OcaIDENTIFIER:\n\t\taddTag (ident, K_TYPE);\n\t\t// true type declaration\n\t\tif (whatNext == Tok_EQ)\n\t\t{\n\t\t\tpushStrongContext (ident, ContextType);\n\t\t\trequestStrongPoping ();\n\t\t\ttoDoNext = &typeSpecification;\n\t\t}\n\t\telse // we're in a sig\n\t\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\n\tdefault:\n\t\tglobalScope (ident, what, whatNext);\n\t}\n}\n\n/** handle 'val' signatures in sigs and .mli files\n  * val ident : String.t -> Val.t\n  * Eventually, this will do cool things to annotate\n  * functions with their actual signatures. But for now,\n  * it's basically globalLet */\nstatic void val (vString * const ident, ocaToken what, ocaToken whatNext CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase Tok_PARL:\n\tcase OcaKEYWORD_rec:\n\t\tbreak;\n\n\tcase Tok_Op:\n\t\t/* we are defining a new operator, it's a\n\t\t * function definition */\n\t\taddTag (ident, K_VAL);\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\n\tcase Tok_Val:\t/* Can be a weiiird binding, or an '_' */\n\tcase OcaIDENTIFIER:\n\t\taddTag (ident, K_VAL);\n\t\ttoDoNext = &globalScope;\t// sig parser ?\n\t\tbreak;\n\n\tdefault:\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\t}\n}\n\n/* Parse type of kind\n * type bidule = Ctor1 of ...\n *             | Ctor2\n *             | Ctor3 of ...\n * or\n * type bidule = | Ctor1 of ... | Ctor2\n *\n * when type bidule = { ... } is detected,\n * let typeRecord handle it. */\nstatic void typeSpecification (vString * const ident, ocaToken what, ocaToken whatNext CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase OcaIDENTIFIER:\n\t\tif (isUpperAlpha (vStringChar (ident, 0)))\n\t\t{\n\t\t\t/* here we handle type aliases of type\n\t\t\t * type foo = AnotherModule.bar\n\t\t\t * AnotherModule can mistakenly be took\n\t\t\t * for a constructor. */\n\t\t\tif (! OcamlKinds[K_CONSTRUCTOR].enabled)\n\t\t\t\tvStringClear (tempIdent);\n\t\t\telse\n\t\t\t{\n\t\t\t\tvStringCopy (tempIdent, ident);\n\t\t\t\tprepareTag (&tempTag, tempIdent, K_CONSTRUCTOR);\n\t\t\t}\n\t\t\ttoDoNext = &constructorValidation;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttoDoNext = &tillTokenOrFallback;\n\t\t\tcomeAfter = &typeSpecification;\n\t\t\twaitedToken = Tok_Pipe;\n\t\t}\n\t\tbreak;\n\n\tcase OcaKEYWORD_and:\n\t\ttoDoNext = &typeDecl;\n\t\tbreak;\n\n\tcase OcaKEYWORD_val:\n\t\ttoDoNext = &val;\n\t\tbreak;\n\n\tcase Tok_BRL:\t/* the '[' & ']' are ignored to accommodate */\n\tcase Tok_BRR:\t/* with the revised syntax */\n\tcase Tok_Pipe:\n\t\t/* just ignore it */\n\t\tbreak;\n\n\tcase Tok_CurlL:\n\t\ttoDoNext = &typeRecord;\n\t\tbreak;\n\n\tdefault:\t/* don't care */\n\t\tbreak;\n\t}\n}\n\n\nstatic bool dirtySpecialParam = false;\n\n/* parse the ~label and ~label:type parameter */\nstatic void parseLabel (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tstatic int parCount = 0;\n\n\tswitch (what)\n\t{\n\tcase OcaIDENTIFIER:\n\t\tif (!dirtySpecialParam)\n\t\t{\n\t\t\tif (exportLocalInfo)\n\t\t\t\taddTag (ident, K_VARIABLE);\n\n\t\t\tdirtySpecialParam = true;\n\t\t}\n\t\tbreak;\n\n\tcase Tok_PARL:\n\t\tparCount++;\n\t\tbreak;\n\n\tcase Tok_PARR:\n\t\tparCount--;\n\t\tif (parCount == 0)\n\t\t\ttoDoNext = &letParam;\n\t\tbreak;\n\n\tcase Tok_Op:\n\t\tif (vStringChar(ident, 0) == ':')\n\t\t{\n\t\t\ttoDoNext = &ignoreToken;\n\t\t\tcomeAfter = &letParam;\n\t\t}\n\t\telse if (parCount == 0 && dirtySpecialParam)\n\t\t{\n\t\t\ttoDoNext = &letParam;\n\t\t\tletParam (ident, what, whatNext);\n\t\t}\n\t\tbreak;\n\n\tdefault:\n\t\tif (parCount == 0 && dirtySpecialParam)\n\t\t{\n\t\t\ttoDoNext = &letParam;\n\t\t\tletParam (ident, what, whatNext);\n\t\t}\n\t\tbreak;\n\t}\n}\n\n/* Optional argument with syntax like this :\n * ?(foo = value) */\nstatic void parseOptionnal (vString * const ident, ocaToken what, ocaToken whatNext CTAGS_ATTR_UNUSED)\n{\n\tstatic int parCount = 0;\n\n\tswitch (what)\n\t{\n\tcase OcaIDENTIFIER:\n\t\tif (!dirtySpecialParam)\n\t\t{\n\t\t\tif (exportLocalInfo)\n\t\t\t\taddTag (ident, K_VARIABLE);\n\n\t\t\tdirtySpecialParam = true;\n\n\t\t\tif (parCount == 0)\n\t\t\t\ttoDoNext = &letParam;\n\t\t}\n\t\tbreak;\n\n\tcase Tok_PARL:\n\t\tparCount++;\n\t\tbreak;\n\n\tcase Tok_PARR:\n\t\tparCount--;\n\t\tif (parCount == 0)\n\t\t\ttoDoNext = &letParam;\n\t\tbreak;\n\n\tdefault:\t/* don't care */\n\t\tbreak;\n\t}\n}\n\n/** handle let inside functions (so like it's name\n * say : local let */\nstatic void localLet (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tswitch (what)\n\t{\n\tcase Tok_PARL:\n\t\t/* We ignore this token to be able to parse such\n\t\t * declarations :\n\t\t * let (ident : type) = ...\n\t\t */\n\t\tbreak;\n\n\tcase OcaKEYWORD_rec:\n\t\t/* just ignore to be able to parse such declarations:\n\t\t * let rec ident = ... */\n\t\tbreak;\n\n\tcase Tok_Op:\n\t\t/* we are defining a new operator, it's a\n\t\t * function definition */\n\t\tif (exportLocalInfo)\n\t\t\taddTag (ident, K_FUNCTION);\n\t\tpushSoftContext (mayRedeclare, ident, ContextFunction);\n\t\ttoDoNext = &letParam;\n\t\tbreak;\n\n\tcase Tok_Val:\t/* Can be a weiiird binding, or an '_' */\n\tcase OcaIDENTIFIER:\n\t\t// if we're an identifier, and the next token is too, then\n\t\t// we're definitely a function.\n\t\tif (whatNext == OcaIDENTIFIER || whatNext == Tok_PARL)\n\t\t{\n\t\t\tif (exportLocalInfo)\n\t\t\t\taddTag (ident, K_FUNCTION);\n\t\t\tpushSoftContext (mayRedeclare, ident, ContextFunction);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (exportLocalInfo)\n\t\t\t\taddTag (ident, K_VARIABLE);\n\t\t\tpushSoftContext (mayRedeclare, ident, ContextValue);\n\t\t}\n\t\ttoDoNext = &letParam;\n\t\tbreak;\n\n\tcase OcaKEYWORD_end:\n\t\tlocalScope (ident, what, whatNext);\n\t\tbreak;\n\n\tdefault:\n\t\ttoDoNext = &localScope;\n\t\tbreak;\n\t}\n}\n\n/* parse :\n * | pattern pattern -> ...\n * or\n * pattern apttern apttern -> ...\n * we ignore all identifiers declared in the pattern,\n * because their scope is likely to be even more limited\n * than the let definitions.\n * Used after a match ... with, or a function ...\n * because their syntax is similar.  */\nstatic void matchPattern (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tswitch (what)\n\t{\n\tcase Tok_To:\n\t\tpushEmptyContext (&matchPattern);\n\t\ttoDoNext = &mayRedeclare;\n\t\tbreak;\n\n\tcase OcaKEYWORD_value:\n\t\tpopLastNamed ();\n\t\t// fall through\n\tcase OcaKEYWORD_and:\n\tcase OcaKEYWORD_end:\n\t\t// why was this global? matches only make sense in local scope\n\t\tlocalScope (ident, what, whatNext);\n\t\tbreak;\n\n\tcase OcaKEYWORD_in:\n\t\tpopLastNamed ();\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\n/* Used at the beginning of a new scope (begin of a\n * definition, parenthesis...) to catch inner let\n * definition that may be in. */\nstatic void mayRedeclare (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tswitch (what)\n\t{\n\tcase OcaKEYWORD_value:\n\t/* let globalScope handle it */\n\tglobalScope (ident, what, whatNext);\n\n\tcase OcaKEYWORD_let:\n\t\ttoDoNext = &localLet;\n\t\tbreak;\n\n\tcase OcaKEYWORD_val:\n\t\ttoDoNext = &val;\n\t\tbreak;\n\n\tcase OcaKEYWORD_object:\n\t\tvStringClear (lastClass);\n\t\tpushContext (ContextStrong, ContextClass,\n\t\t\t&localScope, NULL);\n\t\tneedStrongPoping = false;\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\n\tcase OcaKEYWORD_for:\n\tcase OcaKEYWORD_while:\n\t\ttoDoNext = &tillToken;\n\t\twaitedToken = OcaKEYWORD_do;\n\t\tcomeAfter = &mayRedeclare;\n\t\tbreak;\n\n\tcase OcaKEYWORD_try:\n\t\ttoDoNext = &mayRedeclare;\n\t\tpushSoftContext (&matchPattern, ident, ContextFunction);\n\t\tbreak;\n\n\tcase OcaKEYWORD_function:\n\t\ttoDoNext = &matchPattern;\n\t\tpushSoftContext (&matchPattern, NULL, ContextMatch);\n\t\tbreak;\n\n\tcase OcaKEYWORD_fun:\n\t\ttoDoNext = &letParam;\n\t\tbreak;\n\n\t\t/* Handle the special ;; from the OCaml\n\t\t * Top level */\n\tcase Tok_semi:\n\tdefault:\n\t\ttoDoNext = &localScope;\n\t\tlocalScope (ident, what, whatNext);\n\t}\n}\n\n/* parse :\n * p1 p2 ... pn = ...\n * or\n * ?(p1=v) p2 ~p3 ~pn:ja ... = ... */\nstatic void letParam (vString * const ident, ocaToken what, ocaToken whatNext CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase Tok_To:\n\tcase Tok_EQ:\n\t\ttoDoNext = &mayRedeclare;\n\t\tbreak;\n\n\tcase OcaIDENTIFIER:\n\t\tif (exportLocalInfo)\n\t\t\taddTag (ident, K_VARIABLE);\n\t\tbreak;\n\n\tcase Tok_Op:\n\t\tswitch (vStringChar (ident, 0))\n\t\t{\n\t\tcase ':':\n\t\t\t/*popSoftContext(); */\n\t\t\t/* we got a type signature */\n\t\t\tcomeAfter = &mayRedeclare;\n\t\t\ttoDoNext = &tillTokenOrFallback;\n\t\t\twaitedToken = Tok_EQ;\n\t\t\tbreak;\n\n\t\t\t/* parse something like\n\t\t\t * ~varname:type\n\t\t\t * or\n\t\t\t * ~varname\n\t\t\t * or\n\t\t\t * ~(varname: long type) */\n\t\tcase '~':\n\t\t\ttoDoNext = &parseLabel;\n\t\t\tdirtySpecialParam = false;\n\t\t\tbreak;\n\n\t\t\t/* Optional argument with syntax like this :\n\t\t\t * ?(bla = value)\n\t\t\t * or\n\t\t\t * ?bla */\n\t\tcase '?':\n\t\t\ttoDoNext = &parseOptionnal;\n\t\t\tdirtySpecialParam = false;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tdefault:\t/* don't care */\n\t\tbreak;\n\t}\n}\n\n/* parse object ...\n * used to be sure the class definition is not a type\n * alias */\nstatic void classSpecif (vString * const ident CTAGS_ATTR_UNUSED, ocaToken what, ocaToken whatNext CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase OcaKEYWORD_object:\n\t\tpushStrongContext (lastClass, ContextClass);\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\n\tdefault:\n\t\tvStringClear (lastClass);\n\t\ttoDoNext = &globalScope;\n\t}\n}\n\n/* Handle a method ... class declaration.\n * nearly a copy/paste of globalLet. */\nstatic void methodDecl (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tswitch (what)\n\t{\n\tcase Tok_PARL:\n\t\t/* We ignore this token to be able to parse such\n\t\t * declarations :\n\t\t * let (ident : type) = ...  */\n\t\tbreak;\n\n\tcase OcaKEYWORD_mutable:\n\tcase OcaKEYWORD_virtual:\n\tcase OcaKEYWORD_rec:\n\t\t/* just ignore to be able to parse such declarations:\n\t\t * let rec ident = ... */\n\t\tbreak;\n\n\tcase OcaIDENTIFIER:\n\t\taddTag (ident, K_METHOD);\n\t\t/* Normal pushing to get good subs */\n\t\tpushStrongContext (ident, ContextMethod);\n\t\t/*pushSoftContext( globalScope, ident, ContextMethod ); */\n\t\ttoDoNext = &letParam;\n\t\tbreak;\n\n\tcase OcaKEYWORD_end:\n\t\tlocalScope (ident, what, whatNext);\n\t\tbreak;\n\n\tdefault:\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\t}\n}\n\n/* name of the last module, used for\n * context stacking. */\nstatic vString *lastModule;\n\n/* parse\n * ... struct (* new global scope *) end\n * or\n * ... sig (* new global scope *) end\n * or\n * functor ... -> moduleSpecif\n */\nstatic void moduleSpecif (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tswitch (what)\n\t{\n\tcase OcaKEYWORD_functor:\n\t\ttoDoNext = &contextualTillToken;\n\t\twaitedToken = Tok_To;\n\t\tcomeAfter = &moduleSpecif;\n\t\tbreak;\n\n\tcase OcaKEYWORD_struct:\n\tcase OcaKEYWORD_sig:\n\t\tpushStrongContext (lastModule, ContextModule);\n\t\ttoDoNext = &globalScope;\n\t\tneedStrongPoping = false;\n\t\tbreak;\n\n\tcase Tok_PARL:\t/* ( */\n\t\ttoDoNext = &contextualTillToken;\n\t\tcomeAfter = &globalScope;\n\t\twaitedToken = Tok_PARR;\n\t\tcontextualTillToken (ident, what, whatNext);\n\t\tbreak;\n\n\tcase Tok_Of:\n\tcase Tok_EQ:\n\t\tbreak;\n\n\tdefault:\n\t\tvStringClear (lastModule);\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\t}\n}\n\n/* parse :\n * module name = ...\n * then pass the token stream to moduleSpecif */\nstatic void moduleDecl (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tswitch (what)\n\t{\n\tcase OcaKEYWORD_rec:\n\t\t/* recursive modules are _weird_, but they happen */\n\tcase OcaKEYWORD_type:\n\t\t/* this is technically a special type, but whatever */\n\t\tbreak;\n\n\tcase OcaIDENTIFIER:\n\t\taddTag (ident, K_MODULE);\n\t\tvStringCopy (lastModule, ident);\n\t\tif (whatNext == Tok_Of || whatNext == Tok_EQ)\n\t\t\ttoDoNext = &moduleSpecif;\n\t\telse\n\t\t{\n\t\t\t// default to waiting on a '=' since\n\t\t\t// module M : sig ... end = struct ... end\n\t\t\t// is rarer\n\t\t\twaitedToken = Tok_EQ;\n\t\t\tcomeAfter = &moduleSpecif;\n\t\t\ttoDoNext = &contextualTillToken;\n\t\t}\n\t\tbreak;\n\n\tdefault:\t/* don't care */\n\t\tbreak;\n\t}\n}\n\n/* parse :\n * class name = ...\n * or\n * class virtual ['a,'b] classname = ... */\nstatic void classDecl (vString * const ident, ocaToken what, ocaToken whatNext CTAGS_ATTR_UNUSED)\n{\n\tswitch (what)\n\t{\n\tcase OcaIDENTIFIER:\n\t\taddTag (ident, K_CLASS);\n\t\tvStringCopy (lastClass, ident);\n\t\ttoDoNext = &contextualTillToken;\n\t\twaitedToken = Tok_EQ;\n\t\tcomeAfter = &classSpecif;\n\t\tbreak;\n\n\tcase Tok_BRL:\n\t\ttoDoNext = &tillToken;\n\t\twaitedToken = Tok_BRR;\n\t\tcomeAfter = &classDecl;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\n/* Handle a global\n * let ident ...\n * or\n * let rec ident ... */\nstatic void globalLet (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tswitch (what)\n\t{\n\tcase Tok_PARL:\n\t\t/* We ignore this token to be able to parse such\n\t\t * declarations :\n\t\t * let (ident : type) = ...\n\t\t * but () is the toplevel function name, so fake ourselves\n\t\t * as an ident and make a new function */\n\t\tif (whatNext == Tok_PARR)\n\t\t{\n\t\t\tvString *fakeIdent = vStringNewInit (\"()\");\n\t\t\taddTag (fakeIdent, K_FUNCTION);\n\t\t\tpushStrongContext (fakeIdent, ContextFunction);\n\t\t\tvStringDelete (fakeIdent);\n\t\t\trequestStrongPoping ();\n\t\t\ttoDoNext = &letParam;\n\t\t}\n\t\tbreak;\n\n\tcase OcaKEYWORD_mutable:\n\tcase OcaKEYWORD_virtual:\n\tcase OcaKEYWORD_rec:\n\t\t/* just ignore to be able to parse such declarations:\n\t\t * let rec ident = ... */\n\t\tbreak;\n\n\tcase Tok_Op:\n\t\t/* we are defining a new operator, it's a\n\t\t * function definition */\n\t\taddTag (ident, K_FUNCTION);\n\t\tpushStrongContext (ident, ContextFunction);\n\t\ttoDoNext = &letParam;\n\t\tbreak;\n\n\tcase Tok_Val:\n\t\tif (vStringValue (ident)[0] == '_')\n\t\t\taddTag (ident, K_FUNCTION);\n\t\tpushStrongContext (ident, ContextFunction);\n\t\trequestStrongPoping ();\n\t\ttoDoNext = &letParam;\n\t\tbreak;\n\n\tcase OcaIDENTIFIER:\n\t\t// if we're an identifier, and the next token is too, then\n\t\t// we're definitely a function.\n\t\tif (whatNext == OcaIDENTIFIER || whatNext == Tok_PARL)\n\t\t{\n\t\t\taddTag (ident, K_FUNCTION);\n\t\t\tpushStrongContext (ident, ContextFunction);\n\t\t}\n\t\telse\n\t\t{\n\t\t\taddTag (ident, K_VARIABLE);\n\t\t\tpushStrongContext (ident, ContextValue);\n\t\t}\n\t\trequestStrongPoping ();\n\t\ttoDoNext = &letParam;\n\t\tbreak;\n\n\tcase OcaKEYWORD_end:\n\t\tglobalScope (ident, what, whatNext);\n\t\tbreak;\n\n\tdefault:\n\t\ttoDoNext = &globalScope;\n\t\tbreak;\n\t}\n}\n\n/* Handle the \"strong\" top levels, all 'big' declarations\n * happen here */\nstatic void globalScope (vString * const ident CTAGS_ATTR_UNUSED, ocaToken what, ocaToken whatNext)\n{\n\t/* Do not touch, this is used only by the global scope\n\t * to handle an 'and' */\n\tstatic parseNext previousParser = &globalScope;\n\n\tswitch (what)\n\t{\n\tcase OcaKEYWORD_and:\n\t\tcleanupPreviousParser ();\n\t\t// deal with module M = struct ... end _and_ N = struct ... end\n\t\ttoDoNext = previousParser;\n\t\tbreak;\n\n\tcase OcaKEYWORD_type:\n\t\tcleanupPreviousParser ();\n\t\ttoDoNext = &typeDecl;\n\t\tpreviousParser = &typeDecl;\n\t\tbreak;\n\n\tcase OcaKEYWORD_class:\n\t\tcleanupPreviousParser ();\n\t\ttoDoNext = &classDecl;\n\t\tpreviousParser = &classDecl;\n\t\tbreak;\n\n\tcase OcaKEYWORD_module:\n\t\tcleanupPreviousParser ();\n\t\ttoDoNext = &moduleDecl;\n\t\tpreviousParser = &moduleDecl;\n\t\tbreak;\n\n\tcase OcaKEYWORD_end:;\n\t\tcontextType popped = killCurrentState ();\n\n\t\t/** so here, end can legally be followed by = or and in the\n\t\t * situation of\n\t\t * module M : sig ... end = struct ... end  and\n\t\t * module M struct ... end and N = struct ... end\n\t\t * and we need to make sure we know we're still inside of a\n\t\t * struct */\n\t\tif (whatNext == Tok_EQ && popped == ContextModule)\n\t\t{\n\t\t\tpreviousParser = &moduleDecl;\n\t\t\ttoDoNext = &moduleSpecif;\n\t\t}\n\t\telse if (whatNext == OcaKEYWORD_and && popped == ContextModule)\n\t\t\ttoDoNext = &moduleDecl;\n\t\tneedStrongPoping = false;\n\t\tbreak;\n\n\tcase OcaKEYWORD_method:\n\t\tcleanupPreviousParser ();\n\t\ttoDoNext = &methodDecl;\n\t\t/* and is not allowed in methods */\n\t\tbreak;\n\n\tcase OcaKEYWORD_val:\n\t\ttoDoNext = &val;\n\t\t/* and is not allowed in sigs */\n\t\tbreak;\n\n\tcase OcaKEYWORD_let:\n\t\tcleanupPreviousParser ();\n\t\ttoDoNext = &globalLet;\n\t\tpreviousParser = &globalLet;\n\t\tbreak;\n\n\tcase OcaKEYWORD_exception:\n\t\tcleanupPreviousParser ();\n\t\ttoDoNext = &exceptionDecl;\n\t\tpreviousParser = &globalScope;\n\t\tbreak;\n\n\t\t/* must be a #line directive, discard the\n\t\t * whole line. */\n\tcase Tok_Sharp:\n\t\t/* ignore */\n\t\tbreak;\n\n\tdefault:\n\t\t/* we don't care */\n\t\tbreak;\n\t}\n}\n\n/* Parse expression. Well ignore it is more the case,\n * ignore all tokens except \"shocking\" keywords */\nstatic void localScope (vString * const ident, ocaToken what, ocaToken whatNext)\n{\n\tswitch (what)\n\t{\n\n\t\t// we're probably in a match, so let's go to the last one\n\tcase Tok_Pipe:\n\t\tjumpToMatchContext ();\n\t\tbreak;\n\n\tcase Tok_PARR:\n\tcase Tok_BRR:\n\tcase Tok_CurlR:\n\t\tpopSoftContext ();\n\t\tbreak;\n\n\t\t/* Everything that `begin` has an `end`\n\t\t * as end is overloaded and signal many end\n\t\t * of things, we add an empty strong context to\n\t\t * avoid problem with the end.\n\t\t */\n\tcase OcaKEYWORD_begin:\n\t\tpushContext (ContextStrong, ContextBlock, &mayRedeclare, NULL);\n\t\ttoDoNext = &mayRedeclare;\n\t\tbreak;\n\n\t\t/* An in keyword signals the end of the previous context and the\n\t\t * start of a new one. */\n\tcase OcaKEYWORD_in:\n\t\tpopLastNamed ();\n\t\tpushEmptyContext (&localScope);\n\t\ttoDoNext = &mayRedeclare;\n\t\tbreak;\n\n\t\t/* Ok, we got a '{', which is much likely to create\n\t\t * a record. We cannot treat it like other [ && (,\n\t\t * because it may contain the 'with' keyword and screw\n\t\t * everything else. */\n\tcase Tok_CurlL:\n\t\ttoDoNext = &contextualTillToken;\n\t\twaitedToken = Tok_CurlR;\n\t\tcomeAfter = &localScope;\n\t\tcontextualTillToken (ident, what, whatNext);\n\t\tbreak;\n\n\t\t/* Yeah imperative feature of OCaml,\n\t\t * a ';' like in C */\n\tcase Tok_semi:\n\t\t/* ';;' case should end all scopes */\n\t\tif (whatNext == Tok_semi)\n\t\t{\n\t\t\tpopStrongContext ();\n\t\t\ttoDoNext = &globalScope;\n\t\t\tbreak;\n\t\t}\t/* else fallthrough */\n\n\t\t/* Every standard operator has very high precedence\n\t\t * e.g. expr * expr needs no parentheses */\n\tcase Tok_Op:\n\t\ttoDoNext = &mayRedeclare;\n\t\tbreak;\n\n\tcase Tok_PARL:\n\tcase Tok_BRL:\n\t\tpushEmptyContext (&localScope);\n\t\ttoDoNext = &mayRedeclare;\n\t\tbreak;\n\n\tcase OcaKEYWORD_and:\n\t\tif (toDoNext == &mayRedeclare)\n\t\t{\n\t\t\tpopSoftContext ();\n\t\t\tpushEmptyContext (localScope);\n\t\t\ttoDoNext = &localLet;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* a local 'and' keyword jumps up a context to the last\n\t\t\t * named. For ex\n\t\t\t * in `with let IDENT ... and IDENT2 ...` ident and\n\t\t\t * ident2 are on\n\t\t\t * same level, the same as `let IDENT ... in let IDENT2\n\t\t\t * ...`\n\t\t\t * a 'let' is the only 'and'-chainable construct allowed\n\t\t\t * locally\n\t\t\t * (thus we had to be one to get here), so we either go\n\t\t\t * to\n\t\t\t * globalLet or localLet depending on our scope. */\n\t\t\tpopLastNamed ();\n\t\t\ttoDoNext = stackIndex == 0 ? &globalLet : &localLet;\n\t\t}\n\t\tbreak;\n\n\tcase OcaKEYWORD_else:\n\tcase OcaKEYWORD_then:\n\t\tpopSoftContext ();\n\t\tpushEmptyContext (&localScope);\n\t\ttoDoNext = &mayRedeclare;\n\t\tbreak;\n\n\tcase OcaKEYWORD_if:\n\t\tpushEmptyContext (&localScope);\n\t\ttoDoNext = &mayRedeclare;\n\t\tbreak;\n\n\tcase OcaKEYWORD_match:\n\t\tpushEmptyContext (&localScope);\n\t\ttoDoNext = &mayRedeclare;\n\t\tbreak;\n\n\tcase OcaKEYWORD_with:\n\t\tpopSoftContext ();\n\t\ttoDoNext = &matchPattern;\n\t\tpushSoftContext (&matchPattern, NULL, ContextMatch);\n\t\tbreak;\n\n\tcase OcaKEYWORD_fun:\n\t\ttoDoNext = &letParam;\n\t\tbreak;\n\n\tcase OcaKEYWORD_done:\n\t\t/* doesn't care */\n\t\tbreak;\n\n\tdefault:\n\t\trequestStrongPoping ();\n\t\tglobalScope (ident, what, whatNext);\n\t\tbreak;\n\t}\n}\n\n/*////////////////////////////////////////////////////////////////\n//// Deal with the system                                       */\n/* in OCaml the file name is the module name used in the language\n * with it first letter put in upper case */\nstatic void computeModuleName ( void )\n{\n\t/* in OCaml the file name define a module.\n\t * so we define a module if the file has\n\t * things in it. =)\n\t */\n\tconst char *filename = getInputFileName ();\n\n\tint beginIndex = 0;\n\tint endIndex = strlen (filename) - 1;\n\tvString *moduleName = vStringNew ();\n\n\twhile (filename[endIndex] != '.' && endIndex > 0)\n\t\tendIndex--;\n\n\t/* avoid problem with path in front of filename */\n\tbeginIndex = endIndex;\n\twhile (beginIndex > 0)\n\t{\n\t\tif (filename[beginIndex] == '\\\\' || filename[beginIndex] == '/')\n\t\t{\n\t\t\tbeginIndex++;\n\t\t\tbreak;\n\t\t}\n\n\t\tbeginIndex--;\n\t}\n\n\tvStringNCopyS (moduleName, &filename[beginIndex], endIndex - beginIndex);\n\n\tif (isLowerAlpha (vStringChar (moduleName, 0)))\n\t\tvStringChar (moduleName, 0) += ('A' - 'a');\n\n\taddTag (moduleName, K_MODULE);\n\tvStringDelete (moduleName);\n}\n\n/* Allocate all string of the context stack */\nstatic void initStack ( void )\n{\n\tint i;\n\tfor (i = 0; i < OCAML_MAX_STACK_SIZE; ++i)\n\t\tstack[i].contextName = vStringNew ();\n\tstackIndex = 0;\n}\n\nstatic void clearStack ( void )\n{\n\tint i;\n\tfor (i = 0; i < OCAML_MAX_STACK_SIZE; ++i)\n\t\tvStringDelete (stack[i].contextName);\n}\n\nstatic void findOcamlTags (void)\n{\n\tlexingState st;\n\tocaToken tok;\n\n\t/* One-token lookahead gives us the ability to\n\t * do much more accurate analysis */\n\tlexingState nextSt;\n\tocaToken nextTok;\n\n\tinitStack ();\n\n\ttempIdent = vStringNew ();\n\tlastModule = vStringNew ();\n\tlastClass = vStringNew ();\n\tvString *temp_cp = vStringNew ();\n\n\tnextSt.name = vStringNew ();\n\tnextSt.cp = readLineFromInputFile ();\n\tocaLineNumber = getInputLineNumber();\n\tocaFilePosition = getInputFilePosition();\n\ttoDoNext = &globalScope;\n\tnextTok = lex (&nextSt);\n\n\tif (nextTok != Tok_EOF)\n\t\tcomputeModuleName ();\n\n\t/* prime the lookahead token */\n\tst = nextSt;\t// preserve the old state for our first token\n\tst.name = vStringNewCopy (st.name);\n\tst.cp = (const unsigned char *) vStringValue (temp_cp);\n\ttok = nextTok;\n\tocaLineNumber = getInputLineNumber(); /* ??? getSourceLineNumber() */\n\tocaFilePosition = getInputFilePosition();\n\tnextTok = lex (&nextSt);\n\n\t/* main loop */\n\twhile (tok != Tok_EOF)\n\t{\n\t\t(*toDoNext) (st.name, tok, nextTok);\n\n\t\ttok = nextTok;\n\t\tocaLineNumber = getInputLineNumber(); /* ??? */\n\t\tocaFilePosition = getInputFilePosition();\n\n\t\tif (nextTok != Tok_EOF)\n\t\t{\n\t\t\tvStringCopyS (temp_cp, (const char *) nextSt.cp);\n\t\t\tst.cp = (const unsigned char *) vStringValue (temp_cp);\n\t\t\tvStringCopy (st.name, nextSt.name);\n\t\t\tnextTok = lex (&nextSt);\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\n\tvStringDelete (st.name);\n\tvStringDelete (nextSt.name);\n\tvStringDelete (temp_cp);\n\tvStringDelete (tempIdent);\n\tvStringDelete (lastModule);\n\tvStringDelete (lastClass);\n\tclearStack ();\n}\n\nstatic void ocamlInitialize (const langType language)\n{\n\tLang_Ocaml = language;\n\n\tinitOperatorTable ();\n}\n\nextern parserDefinition *OcamlParser (void)\n{\n\tstatic const char *const extensions[] = { \"ml\", \"mli\", \"aug\", NULL };\n\tstatic const char *const aliases[] = { \"tuareg\", /* mode name of emacs */\n\t\t\t\t\t\t\t\t\t\t   \"caml\",\t /* mode name of emacs */\n\t\t\t\t\t\t\t\t\t\t   NULL };\n\tparserDefinition *def = parserNew (\"OCaml\");\n\tdef->kindTable = OcamlKinds;\n\tdef->kindCount = ARRAY_SIZE (OcamlKinds);\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->parser = findOcamlTags;\n\tdef->initialize = ocamlInitialize;\n\tdef->keywordTable = OcamlKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (OcamlKeywordTable);\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/odin.c",
    "content": "/*\n*   Copyright (c) 2026, Ryan Funduk\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Reference:\n*     https://odin-lang.org/docs/overview/\n*/\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"        /* must always come first */\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n#include \"objpool.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n\n#include <string.h>\n\n/*\n *\t MACROS\n */\n#define MAX_COLLECTOR_LENGTH 512\n#define isType(token,t) (bool) ((token)->type == (t))\n#define isKeyword(token,k) (bool) ((token)->keyword == (k))\n#define isStartIdentChar(c) (isalpha (c) ||  (c) == '_' || (c) > 128) /* XXX UTF-8 */\n#define isIdentChar(c) (isStartIdentChar (c) || isdigit (c))\n#define newToken() (objPoolGet (TokenPool))\n#define deleteToken(t) (objPoolPut (TokenPool, (t)))\n\n/*\n *\t DATA DECLARATIONS\n */\nenum eKeywordId {\n\tKEYWORD_package,\n\tKEYWORD_import,\n\tKEYWORD_foreign,\n\tKEYWORD_proc,\n\tKEYWORD_struct,\n\tKEYWORD_enum,\n\tKEYWORD_union,\n\tKEYWORD_bit_set,\n\tKEYWORD_bit_field,\n\tKEYWORD_map,\n\tKEYWORD_distinct,\n\tKEYWORD_when,\n\tKEYWORD_if,\n\tKEYWORD_else,\n\tKEYWORD_for,\n\tKEYWORD_switch,\n\tKEYWORD_return,\n\tKEYWORD_defer,\n\tKEYWORD_using,\n\tKEYWORD_where,\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum eTokenType {\n\tTOKEN_NONE = -1,\n\tTOKEN_OTHER,\n\tTOKEN_KEYWORD,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_SEMICOLON,\n\tTOKEN_DOT,\n\tTOKEN_COMMA,\n\tTOKEN_COLON,\n\tTOKEN_DOUBLE_COLON,\n\tTOKEN_COLON_EQUAL,\n\tTOKEN_EQUAL,\n\tTOKEN_ARROW,\n\tTOKEN_HASH,\n\tTOKEN_AT,\n\tTOKEN_CARET,\n\tTOKEN_EOF,\n} tokenType;\n\ntypedef struct sTokenInfo {\n\ttokenType type;\n\tkeywordId keyword;\n\tvString *string;\t\t/* the name of the token */\n\tunsigned long lineNumber;\t/* line number of tag */\n\tMIOPos filePosition;\t\t/* file position of line containing name */\n\tint c;\t\t\t\t\t\t/* Used in AppendTokenToVString */\n} tokenInfo;\n\ntypedef struct sCollector {\n\tvString *str;\n\tsize_t last_len;\n} collector;\n\n/*\n *   DATA DEFINITIONS\n */\nstatic int Lang_odin;\nstatic objPool *TokenPool = NULL;\n\ntypedef enum {\n\tODINTAG_UNDEFINED = -1,\n\tODINTAG_PACKAGE,\n\tODINTAG_PROC,\n\tODINTAG_CONST,\n\tODINTAG_VAR,\n\tODINTAG_STRUCT,\n\tODINTAG_ENUM,\n\tODINTAG_UNION,\n\tODINTAG_MEMBER,\n\tODINTAG_ENUMERATOR,\n\tODINTAG_TYPE,\n\tODINTAG_FOREIGN,\n\tODINTAG_IMPORT_NAME,\n\tODINTAG_CCODE,\n\tODINTAG_ASMFILE,\n\tODINTAG_COLLECTION,\n} odinKind;\n\ntypedef enum {\n\tR_ODINTAG_PACKAGE_IMPORTED,\n} OdinPackageRole;\n\ntypedef enum {\n\tR_ODINTAG_CCODE_IMPORTED,\n} OdinCcodeRole;\n\ntypedef enum {\n\tR_ODINTAG_ASMFILE_IMPORTED,\n} OdinAsmfileRole;\n\ntypedef enum {\n\tR_ODINTAG_COLLECTION_REFERENCED,\n} OdinCollectionRole;\n\ntypedef enum {\n\tF_IMPORT_NAME,\n} OdinForeignField;\n\ntypedef enum {\n\tX_IMPLICIT_IMPORT_NAME,\n} OdinXtag;\n\nstatic roleDefinition OdinPackageRoles [] = {\n\t{ true, \"imported\", \"imported package\" },\n};\n\nstatic roleDefinition OdinCcodeRoles [] = {\n\t{ true, \"imported\", \"imported ccode via foreign\" },\n};\n\nstatic roleDefinition OdinAsmfileRoles [] = {\n\t{ true, \"imported\", \"imported assembly file via foreign\" },\n};\n\nstatic roleDefinition OdinCollectionRoles [] = {\n\t{ true, \"referenced\", \"referenced in import statement\" },\n};\n\nstatic kindDefinition OdinKinds[] = {\n\t{ true, 'p', \"package\", \"packages\",\n\t  .referenceOnly = false, ATTACH_ROLES (OdinPackageRoles) },\n\t{ true, 'f', \"proc\", \"procedures\" },\n\t{ true, 'c', \"const\", \"constants\" },\n\t{ true, 'v', \"var\", \"variables\" },\n\t{ true, 's', \"struct\", \"structs\" },\n\t{ true, 'e', \"enum\", \"enums\" },\n\t{ true, 'u', \"union\", \"unions\" },\n\t{ true, 'm', \"member\", \"struct members\" },\n\t{ true, 'n', \"enumerator\", \"enum values\" },\n\t{ true, 't', \"type\", \"type aliases\" },\n\t{ true, 'g', \"foreign\", \"foreign imports\" },\n\t{ true, 'i', \"importName\", \"import names\" },\n\t{ true, 'L', \"ccode\", \"C code\",\n\t  .referenceOnly = true, ATTACH_ROLES (OdinCcodeRoles) },\n\t{ true, 'A', \"asmfile\", \"assembly files\",\n\t  .referenceOnly = true, ATTACH_ROLES (OdinAsmfileRoles) },\n\t{ true, 'C', \"collection\", \"collection\",\n\t  .referenceOnly = true, ATTACH_ROLES (OdinCollectionRoles) },\n};\n\nstatic fieldDefinition OdinFields[] = {\n\t{\n\t\t.name = \"importName\",\n\t\t.description = \"import name for the imported entity\",\n\t\t.enabled = true,\n\t},\n};\n\nstatic xtagDefinition OdinXtags [] = {\n\t{\n\t\t.enabled = true,\n\t\t.name = \"implicitImportName\",\n\t\t.description = \"implicitly defined import name like \\\"filepath\\\" in \\\"core:path/filepath\\\"\",\n\t},\n};\n\nstatic const keywordTable OdinKeywordTable[] = {\n\t{\"package\", KEYWORD_package},\n\t{\"import\", KEYWORD_import},\n\t{\"foreign\", KEYWORD_foreign},\n\t{\"proc\", KEYWORD_proc},\n\t{\"struct\", KEYWORD_struct},\n\t{\"enum\", KEYWORD_enum},\n\t{\"union\", KEYWORD_union},\n\t{\"bit_set\", KEYWORD_bit_set},\n\t{\"bit_field\", KEYWORD_bit_field},\n\t{\"map\", KEYWORD_map},\n\t{\"distinct\", KEYWORD_distinct},\n\t{\"when\", KEYWORD_when},\n\t{\"if\", KEYWORD_if},\n\t{\"else\", KEYWORD_else},\n\t{\"for\", KEYWORD_for},\n\t{\"switch\", KEYWORD_switch},\n\t{\"return\", KEYWORD_return},\n\t{\"defer\", KEYWORD_defer},\n\t{\"using\", KEYWORD_using},\n\t{\"where\", KEYWORD_where},\n};\n\n/*\n *   FUNCTION DEFINITIONS\n */\nstatic void *newPoolToken (void *createArg CTAGS_ATTR_UNUSED)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\ttoken->string = vStringNew ();\n\treturn token;\n}\n\nstatic void clearPoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\n\ttoken->type = TOKEN_NONE;\n\ttoken->keyword = KEYWORD_NONE;\n\ttoken->c = EOF;\n\tvStringClear (token->string);\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const other)\n{\n\tdest->type = other->type;\n\tdest->keyword = other->keyword;\n\tdest->c = other->c;\n\tvStringCopy (dest->string, other->string);\n\tdest->lineNumber = other->lineNumber;\n\tdest->filePosition = other->filePosition;\n}\n\nstatic void deletePoolToken (void* data)\n{\n\ttokenInfo * const token = data;\n\n\tvStringDelete (token->string);\n\teFree (token);\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_odin = language;\n\tTokenPool = objPoolNew (16, newPoolToken, deletePoolToken, clearPoolToken, NULL);\n}\n\nstatic void finalize (const langType language, bool initialized)\n{\n\tif (!initialized)\n\t\treturn;\n\n\tobjPoolDelete (TokenPool);\n}\n\nstatic void parseString (vString *const string, const int delimiter)\n{\n\tbool end = false;\n\twhile (!end)\n\t{\n\t\tint c = getcFromInputFile ();\n\t\tif (c == EOF)\n\t\t\tend = true;\n\t\telse if (c == '\\\\' && delimiter != '`')\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c != delimiter)\n\t\t\t\tvStringPut (string, '\\\\');\n\t\t\tvStringPut (string, c);\n\t\t}\n\t\telse if (c == delimiter)\n\t\t\tend = true;\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isIdentChar (c));\n\tungetcToInputFile (c);\n}\n\nstatic void collectorPut (collector *collector, char c)\n{\n\tif (vStringLength (collector->str) > 0)\n\t{\n\t\tif (vStringLast (collector->str) == '(' && c == ' ')\n\t\t\treturn;\n\t\telse if (vStringLast (collector->str) == ' ' && c == ')')\n\t\t\tvStringChop (collector->str);\n\t}\n\n\tcollector->last_len = vStringLength (collector->str);\n\tvStringPut (collector->str, c);\n}\n\nstatic void collectorCatS (collector *collector, const char *cstr)\n{\n\tcollector->last_len = vStringLength (collector->str);\n\tvStringCatS (collector->str, cstr);\n}\n\nstatic void collectorCat (collector *collector, vString *str)\n{\n\tcollector->last_len = vStringLength (collector->str);\n\tvStringCat (collector->str, str);\n}\n\nstatic void collectorAppendToken (collector *collector, const tokenInfo *const token)\n{\n\tif (token->type == TOKEN_ARROW)\n\t\tcollectorCatS (collector, \"->\");\n\telse if (token->type == TOKEN_COLON_EQUAL)\n\t\tcollectorCatS (collector, \":=\");\n\telse if (token->type == TOKEN_STRING)\n\t{\n\t\tcollector->last_len = vStringLength (collector->str);\n\t\tvStringPut (collector->str, '\"');\n\t\tvStringCat (collector->str, token->string);\n\t\tvStringPut (collector->str, '\"');\n\t}\n\telse if (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_KEYWORD)\n\t\tcollectorCat (collector, token->string);\n\telse if (token->c != EOF)\n\t\tcollectorPut (collector, token->c);\n}\n\nstatic void collectorTruncate (collector *collector)\n{\n\tvStringStripLeading (collector->str);\n\tvStringStripTrailing (collector->str);\n}\n\nstatic bool skipComment (int c, bool hasNewline)\n{\n\tint d;\n\n\tdo\n\t{\n\t\tdo\n\t\t{\n\t\t\td = getcFromInputFile ();\n\t\t\tif (d == '\\n')\n\t\t\t{\n\t\t\t\thasNewline = true;\n\t\t\t}\n\t\t\telse if (d == '/')\n\t\t\t{\n\t\t\t\t/* Check for nested comment */\n\t\t\t\tint e = getcFromInputFile ();\n\t\t\t\tif (e == '*')\n\t\t\t\t{\n\t\t\t\t\t/* Nested comment - recurse */\n\t\t\t\t\tint nest = 1;\n\t\t\t\t\twhile (nest > 0 && d != EOF)\n\t\t\t\t\t{\n\t\t\t\t\t\td = getcFromInputFile ();\n\t\t\t\t\t\tif (d == '*')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint f = getcFromInputFile ();\n\t\t\t\t\t\t\tif (f == '/')\n\t\t\t\t\t\t\t\tnest--;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tungetcToInputFile (f);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (d == '/')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint f = getcFromInputFile ();\n\t\t\t\t\t\t\tif (f == '*')\n\t\t\t\t\t\t\t\tnest++;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tungetcToInputFile (f);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (d == '\\n')\n\t\t\t\t\t\t\thasNewline = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tungetcToInputFile (e);\n\t\t\t}\n\t\t} while (d != EOF && d != '*');\n\n\t\tc = getcFromInputFile ();\n\t\tif (c == '/')\n\t\t\tbreak;\n\t\telse\n\t\t\tungetcToInputFile (c);\n\t} while (c != EOF);\n\n\treturn hasNewline;\n}\n\nstatic void readTokenFull (tokenInfo *const token, collector *collector)\n{\n\tint c;\n\tbool firstWhitespace = true;\n\tbool whitespace;\n\n\ttoken->c = EOF;\n\ttoken->type = TOKEN_NONE;\n\ttoken->keyword = KEYWORD_NONE;\n\tvStringClear (token->string);\n\n getNextChar:\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\ttoken->lineNumber = getInputLineNumber ();\n\t\ttoken->filePosition = getInputFilePosition ();\n\t\twhitespace = c == '\\t'  ||  c == ' ' ||  c == '\\r' || c == '\\n';\n\t\tif (collector && whitespace && firstWhitespace && vStringLength (collector->str) < MAX_COLLECTOR_LENGTH)\n\t\t{\n\t\t\tfirstWhitespace = false;\n\t\t\tcollectorPut (collector, ' ');\n\t\t}\n\t}\n\twhile (whitespace);\n\n\tswitch (c)\n\t{\n\tcase EOF:\n\t\ttoken->type = TOKEN_EOF;\n\t\tbreak;\n\n\tcase ';':\n\t\ttoken->type = TOKEN_SEMICOLON;\n\t\tbreak;\n\n\tcase '/':\n\t{\n\t\tbool hasNewline = false;\n\t\tint d = getcFromInputFile ();\n\t\tswitch (d)\n\t\t{\n\t\tcase '/':\n\t\t\tskipToCharacterInInputFile ('\\n');\n\t\t\tgoto getNextChar;\n\t\tcase '*':\n\t\t\thasNewline = skipComment(c, hasNewline);\n\t\t\tungetcToInputFile (hasNewline ? '\\n' : ' ');\n\t\t\tgoto getNextChar;\n\t\tdefault:\n\t\t\ttoken->type = TOKEN_OTHER;\n\t\t\tungetcToInputFile (d);\n\t\t\tbreak;\n\t\t}\n\t}\n\tbreak;\n\n\tcase '\"':\n\tcase '\\'':\n\tcase '`':\n\t\ttoken->type = TOKEN_STRING;\n\t\tparseString (token->string, c);\n\t\ttoken->lineNumber = getInputLineNumber ();\n\t\ttoken->filePosition = getInputFilePosition ();\n\t\tbreak;\n\n\tcase '-':\n\t{\n\t\tint d = getcFromInputFile ();\n\t\tif (d == '>')\n\t\t\ttoken->type = TOKEN_ARROW;\n\t\telse\n\t\t{\n\t\t\tungetcToInputFile (d);\n\t\t\ttoken->type = TOKEN_OTHER;\n\t\t}\n\t}\n\tbreak;\n\n\tcase ':':\n\t{\n\t\tint d = getcFromInputFile ();\n\t\tif (d == ':')\n\t\t\ttoken->type = TOKEN_DOUBLE_COLON;\n\t\telse if (d == '=')\n\t\t\ttoken->type = TOKEN_COLON_EQUAL;\n\t\telse\n\t\t{\n\t\t\tungetcToInputFile (d);\n\t\t\ttoken->type = TOKEN_COLON;\n\t\t}\n\t}\n\tbreak;\n\n\tcase '(':\n\t\ttoken->type = TOKEN_OPEN_PAREN;\n\t\tbreak;\n\n\tcase ')':\n\t\ttoken->type = TOKEN_CLOSE_PAREN;\n\t\tbreak;\n\n\tcase '{':\n\t\ttoken->type = TOKEN_OPEN_CURLY;\n\t\tbreak;\n\n\tcase '}':\n\t\ttoken->type = TOKEN_CLOSE_CURLY;\n\t\tbreak;\n\n\tcase '[':\n\t\ttoken->type = TOKEN_OPEN_SQUARE;\n\t\tbreak;\n\n\tcase ']':\n\t\ttoken->type = TOKEN_CLOSE_SQUARE;\n\t\tbreak;\n\n\tcase '.':\n\t\ttoken->type = TOKEN_DOT;\n\t\tbreak;\n\n\tcase ',':\n\t\ttoken->type = TOKEN_COMMA;\n\t\tbreak;\n\n\tcase '=':\n\t\ttoken->type = TOKEN_EQUAL;\n\t\tbreak;\n\n\tcase '#':\n\t\ttoken->type = TOKEN_HASH;\n\t\tbreak;\n\n\tcase '@':\n\t\ttoken->type = TOKEN_AT;\n\t\tbreak;\n\n\tcase '^':\n\t\ttoken->type = TOKEN_CARET;\n\t\tbreak;\n\n\tdefault:\n\t\tif (isStartIdentChar (c))\n\t\t{\n\t\t\tparseIdentifier (token->string, c);\n\t\t\ttoken->keyword = lookupKeyword (vStringValue (token->string), Lang_odin);\n\t\t\tif (isKeyword (token, KEYWORD_NONE))\n\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\telse\n\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t}\n\t\telse\n\t\t\ttoken->type = TOKEN_OTHER;\n\t\tbreak;\n\t}\n\n\ttoken->c = c;\n\n\tif (collector && vStringLength (collector->str) < MAX_COLLECTOR_LENGTH)\n\t\tcollectorAppendToken (collector, token);\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\treadTokenFull (token, NULL);\n}\n\nstatic bool skipToMatchedNoRead (tokenInfo *const token, collector *collector)\n{\n\tint nest_level = 0;\n\ttokenType open_token = token->type;\n\ttokenType close_token;\n\n\tswitch (open_token)\n\t{\n\tcase TOKEN_OPEN_PAREN:\n\t\tclose_token = TOKEN_CLOSE_PAREN;\n\t\tbreak;\n\tcase TOKEN_OPEN_CURLY:\n\t\tclose_token = TOKEN_CLOSE_CURLY;\n\t\tbreak;\n\tcase TOKEN_OPEN_SQUARE:\n\t\tclose_token = TOKEN_CLOSE_SQUARE;\n\t\tbreak;\n\tdefault:\n\t\treturn false;\n\t}\n\n\tnest_level++;\n\twhile (nest_level > 0 && !isType (token, TOKEN_EOF))\n\t{\n\t\treadTokenFull (token, collector);\n\t\tif (isType (token, open_token))\n\t\t\tnest_level++;\n\t\telse if (isType (token, close_token))\n\t\t\tnest_level--;\n\t}\n\n\treturn true;\n}\n\nstatic void skipToMatched (tokenInfo *const token, collector *collector)\n{\n\tif (skipToMatchedNoRead (token, collector))\n\t\treadTokenFull (token, collector);\n}\n\nstatic int makeTagFull (tokenInfo *const token, const odinKind kind,\n\t\t\t\t\t\tconst int scope, const char *argList,\n\t\t\t\t\t\tconst int role)\n{\n\tconst char *const name = vStringValue (token->string);\n\n\ttagEntryInfo e;\n\n\t/* Don't record `_' placeholder variable  */\n\tif (kind == ODINTAG_VAR && name[0] == '_' && name[1] == '\\0')\n\t\treturn CORK_NIL;\n\n\tinitRefTagEntry (&e, name, kind, role);\n\n\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\te.extensionFields.signature = argList;\n\n\te.extensionFields.scopeIndex = scope;\n\treturn makeTagEntry (&e);\n}\n\nstatic int makeTag (tokenInfo *const token, const odinKind kind,\n\t\t\t\t\tconst int scope, const char *argList)\n{\n\treturn makeTagFull (token, kind, scope, argList,\n\t\t\t\t\t\tROLE_DEFINITION_INDEX);\n}\n\nstatic int makeRefTag (tokenInfo *const token, const odinKind kind,\n\t\t\t\t\t   const int role, const int scope)\n{\n\treturn makeTagFull (token, kind, scope, NULL, role);\n}\n\nstatic int parsePackage (tokenInfo *const token)\n{\n\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\treturn makeTag (token, ODINTAG_PACKAGE, CORK_NIL, NULL);\n\t}\n\treturn CORK_NIL;\n}\n\nstatic bool nameHasLower (const vString *name)\n{\n\tfor (const char *p = vStringValue (name); *p; p++)\n\t\tif (islower ((unsigned char) *p))\n\t\t\treturn true;\n\treturn false;\n}\n\nstatic int parseCollection (tokenInfo *const token)\n{\n\tif (vStringLength (token->string) == 0)\n\t\treturn CORK_NIL;\n\n\tint col_index = CORK_NIL;\n\tconst char *col_sep = strchr (vStringValue (token->string), ':');\n\n\tif (col_sep)\n\t{\n\t\t/* Extract \"collection\" in \"collection:lib\" */\n\t\tsize_t seppos = col_sep - vStringValue (token->string);\n\n\t\ttokenInfo *col_token = newToken ();\n\t\tcopyToken (col_token, token);\n\t\tvStringTruncateTrailing (col_token->string, seppos);\n\n\t\t/* Update the token pointing to \"lib\" in \"collection:lib\". */\n\t\tvStringTruncateLeading (token->string, seppos + 1);\n\n\t\tif (!vStringIsEmpty (col_token->string))\n\t\t\tcol_index = makeRefTag (col_token, ODINTAG_COLLECTION,\n\t\t\t\t\t\t\t\t\tR_ODINTAG_COLLECTION_REFERENCED,\n\t\t\t\t\t\t\t\t\tCORK_NIL);\n\t\tdeleteToken (col_token);\n\t}\n\n\treturn col_index;\n}\n\nstatic int tryMakeImplicitImportNameXtag (tokenInfo *const token)\n{\n\tint index = CORK_NIL;\n\n\t/* Looking for \"f\" in \"collection:lib/f\" */\n\tconst char *implicit_name = strrchr (vStringValue (token->string), '/');\n\n\tif (/* Reject \"colle\" in \"colle/ction:lib\" */\n\t\timplicit_name && !strchr (implicit_name, ':')\n\t\t/* Reject an empty name */\n\t\t&& implicit_name[1] != '\\0')\n\t{\n\t\timplicit_name++;\n\n\t\ttokenInfo *implicitNameToken = newToken ();\n\t\tcopyToken (implicitNameToken, token);\n\n\t\tvStringCopyS (implicitNameToken->string, implicit_name);\n\t\tindex = makeTag (implicitNameToken,\n\t\t\t\t\t\t ODINTAG_IMPORT_NAME, CORK_NIL, NULL);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\tif (e)\n\t\t\tmarkTagExtraBit (e, OdinXtags[X_IMPLICIT_IMPORT_NAME].xtype);\n\n\t\tdeleteToken (implicitNameToken);\n\t}\n\n\treturn index;\n}\n\nstatic int makeImportedPackageRefTag (tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t  const char *import_name)\n{\n\tint index = CORK_NIL;\n\tint col_index = parseCollection(token);\n\n\tif (!vStringIsEmpty (token->string))\n\t{\n\t\tindex = makeRefTag (token, ODINTAG_PACKAGE, R_ODINTAG_PACKAGE_IMPORTED,\n\t\t\t\t\t\t\tcol_index);\n\n\t\tif (import_name)\n\t\t\tattachParserFieldToCorkEntry (index,\n\t\t\t\t\t\t\t\t\t\t  OdinFields[F_IMPORT_NAME].ftype,\n\t\t\t\t\t\t\t\t\t\t  import_name);\n\t\telse if (isXtagEnabled (OdinXtags[X_IMPLICIT_IMPORT_NAME].xtype))\n\t\t{\n\t\t\tint import_name_index = tryMakeImplicitImportNameXtag (token);\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (import_name_index);\n\t\t\tif (e)\n\t\t\t\tattachParserFieldToCorkEntry (index,\n\t\t\t\t\t\t\t\t\t\t\t  OdinFields[F_IMPORT_NAME].ftype,\n\t\t\t\t\t\t\t\t\t\t\t  e->name);\n\t\t}\n\t}\n\n\treturn index;\n}\n\nstatic void parseImport (tokenInfo *const token)\n{\n\t/* import \"path\"\n\t * import name \"path\"\n\t */\n\treadToken (token);\n\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\ttokenInfo *nameToken = newToken ();\n\t\tcopyToken (nameToken, token);\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_STRING))\n\t\t{\n\t\t\tmakeTag (nameToken, ODINTAG_IMPORT_NAME, CORK_NIL, NULL);\n\t\t\tmakeImportedPackageRefTag (token,\n\t\t\t\t\t\t\t\t\t   vStringValue (nameToken->string));\n\t\t}\n\t\tdeleteToken (nameToken);\n\t}\n\telse if (isType (token, TOKEN_STRING))\n\t{\n\t\tmakeImportedPackageRefTag (token, NULL);\n\t}\n}\n\nstatic void parseForeignBlockProcs (tokenInfo *const token, const int scope)\n{\n\t/* foreign name {\n\t *     ProcName :: proc \"c\" (...) -> RetType ---\n\t *     varName: Type\n\t * }\n\t */\n\treadToken (token);\n\twhile (!isType (token, TOKEN_EOF) && !isType (token, TOKEN_CLOSE_CURLY))\n\t{\n\t\twhile (isType (token, TOKEN_AT))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\tskipToMatched (token, NULL);\n\t\t\telse if (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\treadToken (token);\n\t\t}\n\n\t\tif (isType (token, TOKEN_CLOSE_CURLY) || isType (token, TOKEN_EOF))\n\t\t\tbreak;\n\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\ttokenInfo *nameToken = newToken ();\n\t\t\tcopyToken (nameToken, token);\n\t\t\treadToken (token);\n\n\t\t\tif (isType (token, TOKEN_DOUBLE_COLON))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (isKeyword (token, KEYWORD_proc))\n\t\t\t\t{\n\t\t\t\t\tvString *signature = vStringNew ();\n\t\t\t\t\tcollector sig_collector = { .str = signature, .last_len = 0, };\n\n\t\t\t\t\treadTokenFull (token, &sig_collector);\n\n\t\t\t\t\tif (isType (token, TOKEN_STRING))\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringClear (signature);\n\t\t\t\t\t\treadTokenFull (token, &sig_collector);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipToMatchedNoRead (token, &sig_collector);\n\t\t\t\t\t\tcollectorTruncate (&sig_collector);\n\t\t\t\t\t}\n\n\t\t\t\t\tmakeTag (nameToken, ODINTAG_PROC, scope,\n\t\t\t\t\t\t\t vStringValue (signature));\n\t\t\t\t\tvStringDelete (signature);\n\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isType (token, TOKEN_ARROW))\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\t\t\t\tskipToMatched (token, NULL);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twhile (!isType (token, TOKEN_EOF) &&\n\t\t\t\t\t\t\t\t   !isType (token, TOKEN_CLOSE_CURLY) &&\n\t\t\t\t\t\t\t\t   !isType (token, TOKEN_OTHER))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (isType (token, TOKEN_OPEN_PAREN) ||\n\t\t\t\t\t\t\t\t\tisType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tskipToMatched (token, NULL);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t/* --- */\n\t\t\t\t\twhile (isType (token, TOKEN_OTHER))\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_COLON))\n\t\t\t{\n\t\t\t\tmakeTag (nameToken, ODINTAG_VAR, scope, NULL);\n\t\t\t\treadToken (token);\n\t\t\t\twhile (!isType (token, TOKEN_EOF) &&\n\t\t\t\t\t   !isType (token, TOKEN_CLOSE_CURLY) &&\n\t\t\t\t\t   !isType (token, TOKEN_AT) &&\n\t\t\t\t\t   !isType (token, TOKEN_IDENTIFIER))\n\t\t\t\t{\n\t\t\t\t\tif (isType (token, TOKEN_OPEN_PAREN) ||\n\t\t\t\t\t\tisType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipToMatched (token, NULL);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeleteToken (nameToken);\n\t\t}\n\t\telse\n\t\t{\n\t\t\treadToken (token);\n\t\t}\n\t}\n}\n\nstatic bool isAsmfile (const char *fname)\n{\n\tconst char *ext = fileExtension (fname);\n\treturn (strcmp (ext, \"asm\") == 0\n\t\t\t|| strcmp (ext, \"s\") == 0\n\t\t\t|| strcmp (ext, \"S\") == 0);\n}\n\nstatic int makeForeignImportRefTag (tokenInfo *const token,\n\t\t\t\t\t\t\t\t\tconst char *foreign_name)\n{\n\tint index = CORK_NIL;\n\tint col_index = parseCollection(token);\n\n\tif (!vStringIsEmpty (token->string))\n\t{\n\t\tbool asmfile = isAsmfile (vStringValue (token->string));\n\t\tindex = makeRefTag (token,\n\t\t\t\t\t\t\tasmfile ? ODINTAG_ASMFILE : ODINTAG_CCODE,\n\t\t\t\t\t\t\tasmfile ? R_ODINTAG_ASMFILE_IMPORTED : R_ODINTAG_CCODE_IMPORTED,\n\t\t\t\t\t\t\tcol_index);\n\t\tif (foreign_name)\n\t\t\tattachParserFieldToCorkEntry (index,\n\t\t\t\t\t\t\t\t\t\t  OdinFields[F_IMPORT_NAME].ftype,\n\t\t\t\t\t\t\t\t\t\t  foreign_name);\n\t}\n\n\treturn index;\n}\n\nstatic void parseForeign (tokenInfo *const token, const int scope)\n{\n\t/* foreign import name \"path\"\n\t * foreign import name { \"path1\", \"path2\" }\n\t * foreign import name { EXPR when COND else \"fallback\", ... }\n\t * foreign name { ... }  (proc block)\n\t */\n\treadToken (token);\n\n\tif (isKeyword (token, KEYWORD_import))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tint foreign = makeTag (token, ODINTAG_FOREIGN, scope, NULL);\n\t\t\ttagEntryInfo *foreign_e = getEntryInCorkQueue (foreign);\n\t\t\tconst char *foreign_name = foreign_e ? foreign_e->name : NULL;\n\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isType (token, TOKEN_STRING))\n\t\t\t\t\t\tmakeForeignImportRefTag (token, foreign_name);\n\t\t\t\t} while (!isType (token, TOKEN_CLOSE_CURLY)\n\t\t\t\t\t\t && !isType (token, TOKEN_EOF));\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_STRING))\n\t\t\t\tmakeForeignImportRefTag (token, foreign_name);\n\t\t}\n\t}\n\telse if (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tparseForeignBlockProcs (token, scope);\n\t\t}\n\t}\n}\n\nstatic void parseStructMembers (tokenInfo *const token, const int scope)\n{\n\treadToken (token);\n\twhile (!isType (token, TOKEN_EOF) && !isType (token, TOKEN_CLOSE_CURLY))\n\t{\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\ttokenInfo *memberToken = newToken ();\n\t\t\tcopyToken (memberToken, token);\n\t\t\tbool multiField = false;\n\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_COMMA))\n\t\t\t{\n\t\t\t\tmultiField = true;\n\t\t\t\tmakeTag (memberToken, ODINTAG_MEMBER, scope, NULL);\n\t\t\t\twhile (isType (token, TOKEN_COMMA))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\t\t{\n\t\t\t\t\t\tmakeTag (token, ODINTAG_MEMBER, scope, NULL);\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isType (token, TOKEN_COLON))\n\t\t\t{\n\t\t\t\tif (!multiField)\n\t\t\t\t\tmakeTag (memberToken, ODINTAG_MEMBER, scope, NULL);\n\t\t\t\treadToken (token);\n\t\t\t\twhile (!isType (token, TOKEN_EOF) &&\n\t\t\t\t\t   !isType (token, TOKEN_COMMA) &&\n\t\t\t\t\t   !isType (token, TOKEN_CLOSE_CURLY))\n\t\t\t\t{\n\t\t\t\t\tif (isType (token, TOKEN_OPEN_PAREN) ||\n\t\t\t\t\t\tisType (token, TOKEN_OPEN_CURLY) ||\n\t\t\t\t\t\tisType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipToMatched (token, NULL);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdeleteToken (memberToken);\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_using))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t{\n\t\t\t\tmakeTag (token, ODINTAG_MEMBER, scope, NULL);\n\t\t\t\treadToken (token);\n\t\t\t\tif (isType (token, TOKEN_COLON))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\twhile (!isType (token, TOKEN_EOF) &&\n\t\t\t\t\t\t   !isType (token, TOKEN_COMMA) &&\n\t\t\t\t\t\t   !isType (token, TOKEN_CLOSE_CURLY))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (isType (token, TOKEN_OPEN_PAREN) ||\n\t\t\t\t\t\t\tisType (token, TOKEN_OPEN_CURLY) ||\n\t\t\t\t\t\t\tisType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tskipToMatched (token, NULL);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\treadToken (token);\n\t\t}\n\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t\treadToken (token);\n\t}\n}\n\nstatic void parseEnumMembers (tokenInfo *const token, const int scope)\n{\n\treadToken (token);\n\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (scope);\n\t\tif (e)\n\t\t{\n\t\t\te->extensionFields.typeRef[0] = eStrdup (\"typename\");\n\t\t\te->extensionFields.typeRef[1] = vStringStrdup (token->string);\n\t\t}\n\t\treadToken (token);\n\t}\n\n\tif (!isType (token, TOKEN_OPEN_CURLY))\n\t\treturn;\n\n\treadToken (token);\n\twhile (!isType (token, TOKEN_EOF) && !isType (token, TOKEN_CLOSE_CURLY))\n\t{\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tmakeTag (token, ODINTAG_ENUMERATOR, scope, NULL);\n\t\t\treadToken (token);\n\n\t\t\tif (isType (token, TOKEN_EQUAL))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\twhile (!isType (token, TOKEN_EOF) &&\n\t\t\t\t\t   !isType (token, TOKEN_COMMA) &&\n\t\t\t\t\t   !isType (token, TOKEN_CLOSE_CURLY))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t\treadToken (token);\n\t}\n}\n\nstatic void parseUnionMembers (tokenInfo *const token, const int scope)\n{\n\treadToken (token);\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\tskipToMatched (token, NULL);\n\n\twhile (isType (token, TOKEN_HASH))\n\t{\n\t\treadToken (token);\n\t\treadToken (token);\n\t}\n\n\tif (!isType (token, TOKEN_OPEN_CURLY))\n\t\treturn;\n\n\t/* union members are types, not named */\n\tskipToMatchedNoRead (token, NULL);\n}\n\n/* ^T, [N]T, map[K]V, proc(...)->T, etc. */\nstatic void skipTypeExpression (tokenInfo *const token)\n{\n\twhile (isType (token, TOKEN_CARET))\n\t\treadToken (token);\n\n\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\tskipToMatched (token, NULL);\n\n\tif (isType (token, TOKEN_HASH))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\treadToken (token);\n\t\tskipTypeExpression (token);\n\t\treturn;\n\t}\n\n\tif (isKeyword (token, KEYWORD_map))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\tskipToMatched (token, NULL);\n\t}\n\n\tif (isKeyword (token, KEYWORD_proc))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_STRING))\n\t\t\treadToken (token);\n\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\tskipToMatched (token, NULL);\n\t\tif (isType (token, TOKEN_ARROW))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\tskipToMatched (token, NULL);\n\t\t\telse\n\t\t\t\tskipTypeExpression (token);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_DOT))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\treadToken (token);\n\t\t}\n\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\tskipToMatched (token, NULL);\n\t}\n}\n\nstatic void parseProcedure (tokenInfo *const token, tokenInfo *const nameToken, const int scope)\n{\n\t/* proc \"conv\" (args) -> ret { body } */\n\tvString *signature = vStringNew ();\n\tcollector sig_collector = { .str = signature, .last_len = 0, };\n\n\treadTokenFull (token, &sig_collector);\n\n\tif (isType (token, TOKEN_STRING))\n\t{\n\t\tvStringClear (signature);\n\t\treadTokenFull (token, &sig_collector);\n\t}\n\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t{\n\t\t/* proc group: proc{a, b} */\n\t\tmakeTag (nameToken, ODINTAG_PROC, scope, NULL);\n\t\tskipToMatchedNoRead (token, NULL);\n\t\tvStringDelete (signature);\n\t\treturn;\n\t}\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tskipToMatchedNoRead (token, &sig_collector);\n\t\tcollectorTruncate (&sig_collector);\n\t}\n\n\tint cork = makeTag (nameToken, ODINTAG_PROC, scope, vStringValue (signature));\n\n\treadToken (token);\n\n\tif (isType (token, TOKEN_ARROW))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\tskipToMatched (token, NULL);\n\t\telse\n\t\t\tskipTypeExpression (token);\n\t}\n\n\twhile (isType (token, TOKEN_HASH))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\treadToken (token);\n\t}\n\n\tif (isKeyword (token, KEYWORD_where))\n\t{\n\t\twhile (!isType (token, TOKEN_EOF) &&\n\t\t\t   !isType (token, TOKEN_OPEN_CURLY) &&\n\t\t\t   !isType (token, TOKEN_SEMICOLON))\n\t\t{\n\t\t\treadToken (token);\n\t\t}\n\t}\n\n\tif (isType (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tskipToMatchedNoRead (token, NULL);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (cork);\n\t\tif (e)\n\t\t\tsetTagEndLine (e, getInputLineNumber());\n\t}\n\telse\n\t{\n\t\t/* bodyless: reclassify as type alias */\n\t\ttagEntryInfo *e = getEntryInCorkQueue (cork);\n\t\tif (e)\n\t\t\te->kindIndex = ODINTAG_TYPE;\n\t}\n\n\tvStringDelete (signature);\n}\n\nstatic void parseDeclaration (tokenInfo *const token, const int scope)\n{\n\t/* name :: proc(...)\n\t * name :: struct/enum/union { ... }\n\t * name :: distinct Type\n\t * name :: value  (constant)\n\t * name : type = value  (variable)\n\t * name : type : value  (typed constant)\n\t * name := value  (variable)\n\t */\n\ttokenInfo *nameToken = newToken ();\n\tcopyToken (nameToken, token);\n\n\treadToken (token);\n\n\tif (isType (token, TOKEN_DOUBLE_COLON))\n\t{\n\t\treadToken (token);\n\n\t\tif (isKeyword (token, KEYWORD_proc))\n\t\t{\n\t\t\tparseProcedure (token, nameToken, scope);\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_struct))\n\t\t{\n\t\t\tint member_scope = makeTag (nameToken, ODINTAG_STRUCT, scope, NULL);\n\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\tskipToMatched (token, NULL);\n\n\t\t\twhile (isType (token, TOKEN_HASH))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\treadToken (token);\n\t\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\t\tskipToMatched (token, NULL);\n\t\t\t}\n\n\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\tparseStructMembers (token, member_scope);\n\t\t\t}\n\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (member_scope);\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine (e, getInputLineNumber());\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_enum))\n\t\t{\n\t\t\tint member_scope = makeTag (nameToken, ODINTAG_ENUM, scope, NULL);\n\t\t\tparseEnumMembers (token, member_scope);\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (member_scope);\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine (e, getInputLineNumber());\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_union))\n\t\t{\n\t\t\tint member_scope = makeTag (nameToken, ODINTAG_UNION, scope, NULL);\n\t\t\tparseUnionMembers (token, member_scope);\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (member_scope);\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine (e, getInputLineNumber());\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_bit_set))\n\t\t{\n\t\t\tmakeTag (nameToken, ODINTAG_TYPE, scope, NULL);\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\tskipToMatchedNoRead (token, NULL);\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_bit_field))\n\t\t{\n\t\t\tint member_scope = makeTag (nameToken, ODINTAG_TYPE, scope, NULL);\n\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\treadToken (token);\n\n\t\t\tif (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\t/* bit_field | widths are TOKEN_OTHER, so struct parsing works */\n\t\t\t\tparseStructMembers (token, member_scope);\n\t\t\t}\n\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (member_scope);\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine (e, getInputLineNumber());\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_distinct))\n\t\t{\n\t\t\tmakeTag (nameToken, ODINTAG_TYPE, scope, NULL);\n\t\t\treadToken (token);\n\t\t\twhile (isType (token, TOKEN_CARET))\n\t\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\tskipToMatchedNoRead (token, NULL);\n\t\t\telse if (isKeyword (token, KEYWORD_map))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\tskipToMatched (token, NULL);\n\t\t\t}\n\t\t\t/* parseBlock's readToken advances past this */\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_map))\n\t\t{\n\t\t\tmakeTag (nameToken, ODINTAG_TYPE, scope, NULL);\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\tskipToMatched (token, NULL);\n\t\t}\n\t\telse if (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\t/* Lowercase in name => type alias, else constant */\n\t\t\tif (nameHasLower (nameToken->string))\n\t\t\t\tmakeTag (nameToken, ODINTAG_TYPE, scope, NULL);\n\t\t\telse\n\t\t\t\tmakeTag (nameToken, ODINTAG_CONST, scope, NULL);\n\t\t}\n\t\telse if (isType (token, TOKEN_STRING) ||\n\t\t\t\t isType (token, TOKEN_OTHER))\n\t\t{\n\t\t\tmakeTag (nameToken, ODINTAG_CONST, scope, NULL);\n\t\t}\n\t\telse if (isType (token, TOKEN_CARET) ||\n\t\t\t\t isType (token, TOKEN_HASH) ||\n\t\t\t\t isType (token, TOKEN_OPEN_SQUARE))\n\t\t{\n\t\t\tif (isType (token, TOKEN_HASH))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\t\treadToken (token);\n\t\t\t\tif (isKeyword (token, KEYWORD_proc))\n\t\t\t\t{\n\t\t\t\t\tparseProcedure (token, nameToken, scope);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (nameHasLower (nameToken->string))\n\t\t\t\t\t\tmakeTag (nameToken, ODINTAG_TYPE, scope, NULL);\n\t\t\t\t\telse\n\t\t\t\t\t\tmakeTag (nameToken, ODINTAG_CONST, scope, NULL);\n\t\t\t\t\tif (isType (token, TOKEN_OPEN_PAREN) ||\n\t\t\t\t\t\tisType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipToMatchedNoRead (token, NULL);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmakeTag (nameToken, ODINTAG_TYPE, scope, NULL);\n\t\t\t\tif (isType (token, TOKEN_CARET))\n\t\t\t\t{\n\t\t\t\t\twhile (isType (token, TOKEN_CARET))\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t\telse if (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t{\n\t\t\t\t\tskipToMatched (token, NULL);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_PAREN) ||\n\t\t\t\t isType (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tmakeTag (nameToken, ODINTAG_CONST, scope, NULL);\n\t\t}\n\t}\n\telse if (isType (token, TOKEN_COLON))\n\t{\n\t\treadToken (token);\n\n\t\twhile (!isType (token, TOKEN_EOF) &&\n\t\t\t   !isType (token, TOKEN_EQUAL) &&\n\t\t\t   !isType (token, TOKEN_COLON) &&\n\t\t\t   !isType (token, TOKEN_SEMICOLON) &&\n\t\t\t   !isType (token, TOKEN_CLOSE_CURLY) &&\n\t\t\t   !isType (token, TOKEN_COMMA) &&\n\t\t\t   !isType (token, TOKEN_AT) &&\n\t\t\t   !isType (token, TOKEN_HASH))\n\t\t{\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN) ||\n\t\t\t\tisType (token, TOKEN_OPEN_CURLY) ||\n\t\t\t\tisType (token, TOKEN_OPEN_SQUARE))\n\t\t\t{\n\t\t\t\tskipToMatched (token, NULL);\n\t\t\t}\n\t\t\telse\n\t\t\t\treadToken (token);\n\t\t}\n\n\t\tif (isType (token, TOKEN_COLON))\n\t\t\tmakeTag (nameToken, ODINTAG_CONST, scope, NULL);\n\t\telse\n\t\t\tmakeTag (nameToken, ODINTAG_VAR, scope, NULL);\n\t}\n\telse if (isType (token, TOKEN_COLON_EQUAL))\n\t{\n\t\tmakeTag (nameToken, ODINTAG_VAR, scope, NULL);\n\t}\n\telse if (isType (token, TOKEN_COMMA))\n\t{\n\t\tmakeTag (nameToken, ODINTAG_VAR, scope, NULL);\n\n\t\twhile (isType (token, TOKEN_COMMA))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t{\n\t\t\t\tmakeTag (token, ODINTAG_VAR, scope, NULL);\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t}\n\t}\n\n\tdeleteToken (nameToken);\n}\n\nstatic void parseBlock (tokenInfo *const token, int scope, bool isTopLevel);\n\nstatic void parseWhenBlock (tokenInfo *const token, const int scope)\n{\n\t/* when cond { ... } else when cond { ... } else { ... } */\n\treadToken (token);\n\n\tfor (;;)\n\t{\n\t\t/* Bail on declaration operators — expression-level when */\n\t\twhile (!isType (token, TOKEN_EOF) &&\n\t\t\t   !isType (token, TOKEN_OPEN_CURLY) &&\n\t\t\t   !isType (token, TOKEN_DOUBLE_COLON) &&\n\t\t\t   !isType (token, TOKEN_COLON) &&\n\t\t\t   !isType (token, TOKEN_COLON_EQUAL))\n\t\t{\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN) ||\n\t\t\t\tisType (token, TOKEN_OPEN_SQUARE))\n\t\t\t{\n\t\t\t\tskipToMatched (token, NULL);\n\t\t\t}\n\t\t\telse\n\t\t\t\treadToken (token);\n\t\t}\n\n\t\tif (!isType (token, TOKEN_OPEN_CURLY))\n\t\t\tbreak;\n\n\t\treadToken (token);\n\t\tparseBlock (token, scope, false);\n\n\t\treadToken (token);\n\t\tif (isKeyword (token, KEYWORD_else))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isKeyword (token, KEYWORD_when))\n\t\t\t\treadToken (token);\n\t\t\tcontinue;\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n}\n\nstatic void parseBlock (tokenInfo *const token, int scope, bool isTopLevel)\n{\n\ttokenType stopToken = isTopLevel ? TOKEN_EOF : TOKEN_CLOSE_CURLY;\n\n\tif (isTopLevel)\n\t\treadToken (token);\n\n\twhile (!isType (token, TOKEN_EOF) && !isType (token, stopToken))\n\t{\n\t\twhile (isType (token, TOKEN_AT))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\tskipToMatched (token, NULL);\n\t\t\telse if (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\treadToken (token);\n\t\t}\n\n\t\tif (isType (token, stopToken) || isType (token, TOKEN_EOF))\n\t\t\tbreak;\n\n\t\tif (isType (token, TOKEN_KEYWORD))\n\t\t{\n\t\t\tswitch (token->keyword)\n\t\t\t{\n\t\t\tcase KEYWORD_package:\n\t\t\t\tif (isTopLevel)\n\t\t\t\t\tscope = parsePackage (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_import:\n\t\t\t\tparseImport (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_foreign:\n\t\t\t\tparseForeign (token, scope);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_when:\n\t\t\t\tparseWhenBlock (token, scope);\n\t\t\t\tcontinue;\n\t\t\tcase KEYWORD_if:\n\t\t\tcase KEYWORD_for:\n\t\t\tcase KEYWORD_switch:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_HASH))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OTHER))\n\t\t\t{\n\t\t\t\t/* #+build — skip line to avoid misparsing */\n\t\t\t\tskipToCharacterInInputFile ('\\n');\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\telse if (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tparseDeclaration (token, scope);\n\t\t\t/* parseDeclaration may leave token at next statement */\n\t\t\tif (isType (token, TOKEN_AT) || isType (token, TOKEN_HASH) ||\n\t\t\t\tisType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))\n\t\t\t\tcontinue;\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_PAREN) ||\n\t\t\t\t isType (token, TOKEN_OPEN_CURLY) ||\n\t\t\t\t isType (token, TOKEN_OPEN_SQUARE))\n\t\t{\n\t\t\tskipToMatched (token, NULL);\n\t\t\tcontinue;\n\t\t}\n\n\t\treadToken (token);\n\t}\n}\n\nstatic void parseOdinFile (tokenInfo *const token)\n{\n\tparseBlock (token, CORK_NIL, true);\n}\n\nstatic void findOdinTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\tparseOdinFile (token);\n\n\tdeleteToken (token);\n}\n\nextern parserDefinition *OdinParser (void)\n{\n\tstatic const char *const extensions[] = { \"odin\", NULL };\n\tparserDefinition *def = parserNew (\"Odin\");\n\tdef->kindTable = OdinKinds;\n\tdef->kindCount = ARRAY_SIZE (OdinKinds);\n\tdef->fieldTable = OdinFields;\n\tdef->fieldCount = ARRAY_SIZE (OdinFields);\n\tdef->xtagTable = OdinXtags;\n\tdef->xtagCount = ARRAY_SIZE (OdinXtags);\n\tdef->extensions = extensions;\n\tdef->parser = findOdinTags;\n\tdef->initialize = initialize;\n\tdef->finalize = finalize;\n\tdef->keywordTable = OdinKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (OdinKeywordTable);\n\tdef->useCork = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/openapi.c",
    "content": "/*\n*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, K.K.\n*   Copyright (c) 2022, Vasily Kulikov\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Documentation on the schemas:\n*   https://github.com/OAI/OpenAPI-Specification/tree/main/versions\n*/\n\n#include \"general.h\"\t/* must always come first */\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"x-yaml.h\"\n#include \"parse.h\"\n#include \"subparser.h\"\n#include \"read.h\"\n\n\ntypedef enum {\n\tKIND_SCHEMA,\n\tKIND_PATH,\n\tKIND_RESPONSE,\n\tKIND_PARAMETER,\n\tKIND_TITLE,\n\tKIND_SERVER,\n\tKIND_TAG,\n} openapiKind;\n\nstatic kindDefinition OpenAPIKinds [] = {\n\t{ true, 'd', \"schema\", \"schemas\" },\n\t{ true, 'p', \"path\", \"paths\" },\n\t{ true, 'R', \"response\", \"responses\" },\n\t{ true, 'P', \"parameter\", \"parameters\" },\n\t{ true, 't', \"title\", \"titles\" },\n\t{ true, 's', \"server\", \"servers (or hosts in swagger)\" },\n\t{ true, 'T', \"tag\", \"tags\"},\n};\n\nstruct sOpenAPISubparser {\n\tyamlSubparser yaml;\n};\n\nstatic tagYpathTable ypathTables [] = {\n\t{ \"paths/*\",\n\t  YPATH_DSTAT_LAST_KEY,   KIND_PATH,      },\n\t{ \"components/responses/*\",\n\t  YPATH_DSTAT_LAST_KEY,   KIND_RESPONSE,  },\n\t{ \"responses/*\",\n\t  YPATH_DSTAT_LAST_KEY,   KIND_RESPONSE,  },\n\t{ \"components/parameters/*\",\n\t  YPATH_DSTAT_LAST_KEY,   KIND_PARAMETER, },\n\t{ \"parameters/*\",\n\t  YPATH_DSTAT_LAST_KEY,   KIND_PARAMETER, },\n\t{ \"components/schemas/*\",\n\t  YPATH_DSTAT_LAST_KEY,   KIND_SCHEMA,    },\n\t{ \"definitions/*\",\n\t  YPATH_DSTAT_LAST_KEY,   KIND_SCHEMA,    },\n\t{ \"info/title\",\n\t  YPATH_DSTAT_LAST_VALUE, KIND_TITLE,     },\n\t{ \"servers/*/url\",\n\t  YPATH_DSTAT_LAST_VALUE, KIND_SERVER,    },\n\t{ \"host\",\n\t  YPATH_DSTAT_LAST_VALUE, KIND_SERVER,    },\n\t{ \"tags/*/name\",\n\t  YPATH_DSTAT_LAST_VALUE, KIND_TAG,       },\n};\n\nstatic void findOpenAPITags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* OpenAPIParser (void)\n{\n\tstatic const char *const patterns [] = { \"openapi.yaml\", NULL };\n\tstatic struct sOpenAPISubparser openapiSubparser = {\n\t\t.yaml = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t\t},\n\t\t\t.ypathTables = ypathTables,\n\t\t\t.ypathTableCount = ARRAY_SIZE (ypathTables),\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t{ DEPTYPE_SUBPARSER, \"Yaml\", &openapiSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"OpenAPI\");\n\n\tdef->patterns   = patterns;\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable\t= OpenAPIKinds;\n\tdef->kindCount = ARRAY_SIZE (OpenAPIKinds);\n\tdef->parser\t= findOpenAPITags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/pascal.c",
    "content": "/*\n*   Copyright (c) 2001-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for the Pascal language,\n*   including some extensions for Object Pascal.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_FUNCTION, K_PROCEDURE\n} pascalKind;\n\nstatic kindDefinition PascalKinds [] = {\n\t{ true, 'f', \"function\",  \"functions\"},\n\t{ true, 'p', \"procedure\", \"procedures\"}\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void createPascalTag (\n\t\ttagEntryInfo* const tag, const vString* const name, const int kind,\n\t\tconst vString *arglist, const vString *vartype)\n{\n\tif (PascalKinds [kind].enabled  &&  name != NULL  &&  vStringLength (name) > 0)\n\t{\n\t\tinitTagEntry (tag, vStringValue (name), kind);\n\t\tif (arglist && !vStringIsEmpty (arglist))\n\t\t{\n\t\t\ttag->extensionFields.signature = vStringValue (arglist);\n\t\t}\n\t\tif (vartype && !vStringIsEmpty (vartype))\n\t\t{\n\t\t\ttag->extensionFields.typeRef[0] = \"typename\";\n\t\t\ttag->extensionFields.typeRef[1] = vStringValue (vartype);\n\t\t}\n\t}\n\telse\n\t\t/* TODO: Passing NULL as name makes an assertion behind initTagEntry failure */\n\t\tinitTagEntry (tag, NULL, KIND_GHOST_INDEX);\n}\n\nstatic void makePascalTag (tagEntryInfo* const tag)\n{\n\tif (tag->name != NULL)\n\t\tmakeTagEntry (tag);\n}\n\nstatic const unsigned char* dbp;\n\n#define starttoken(c) (isalpha ((unsigned char) c) || (int) c == '_')\n#define intoken(c)    (isalnum ((unsigned char) c) || (int) c == '_' || (int) c == '.')\n#define endtoken(c)   (! intoken (c)  &&  ! isdigit ((unsigned char) c))\n\nstatic bool tail (const char *cp)\n{\n\tbool result = false;\n\tregister int len = 0;\n\n\twhile (*cp != '\\0' && tolower ((unsigned char) *cp) == tolower (dbp [len]))\n\t\tcp++, len++;\n\tif (*cp == '\\0' && !intoken (dbp [len]))\n\t{\n\t\tdbp += len;\n\t\tresult = true;\n\t}\n\treturn result;\n}\n\nstatic void parseArglist (const char *buf, vString *arglist, vString *vartype)\n{\n\tconst char *start, *end;\n\tint level;\n\n\tif (NULL == buf || arglist == NULL)\n\t\treturn;\n\n\t/* parse argument list which can be missing like in \"function ginit:integer;\" */\n\tif (NULL != (start = strchr (buf, '(')))\n\t{\n\t\tfor (level = 1, end = start + 1; level > 0; ++end)\n\t\t{\n\t\t\tif ('\\0' == *end)\n\t\t\t\tbreak;\n\t\t\telse if ('(' == *end)\n\t\t\t\t++ level;\n\t\t\telse if (')' == *end)\n\t\t\t\t-- level;\n\t\t}\n\t}\n\telse /* if no argument list was found, continue looking for a return value */\n\t{\n\t\tstart = NULL;\n\t\tend = buf;\n\t}\n\n\t/* parse return type if requested by passing a non-NULL vartype argument */\n\tif (NULL != vartype)\n\t{\n\t\tchar *var, *var_start;\n\n\t\tif (NULL != (var = strchr (end, ':')))\n\t\t{\n\t\t\tvar++; /* skip ':' */\n\t\t\twhile (isspace ((unsigned char) *var))\n\t\t\t\t++var;\n\n\t\t\tif (starttoken (*var))\n\t\t\t{\n\t\t\t\tvar_start = var;\n\t\t\t\tvar++;\n\t\t\t\twhile (intoken (*var))\n\t\t\t\t\tvar++;\n\t\t\t\tif (endtoken (*var))\n\t\t\t\t{\n\t\t\t\t\tvStringNCatS (vartype, var_start, var - var_start);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (NULL == start) /* no argument list */\n\t\tvStringCatS (arglist, \"()\");\n\telse\n\t\tvStringNCatS (arglist, start, end - start);\n}\n\n/* Algorithm adapted from from GNU etags.\n * Locates tags for procedures & functions.  Doesn't do any type- or\n * var-definitions.  It does look for the keyword \"extern\" or \"forward\"\n * immediately following the procedure statement; if found, the tag is\n * skipped.\n */\nstatic void findPascalTags (void)\n{\n\tvString *name = vStringNew ();\n\tvString *arglist = vStringNew ();\n\tvString *vartype = vStringNew ();\n\ttagEntryInfo tag;\n\tpascalKind kind = K_FUNCTION;\n\t\t/* each of these flags is true iff: */\n\tbool incomment = false;  /* point is inside a comment */\n\tint comment_char = '\\0';    /* type of current comment */\n\tbool inquote = false;    /* point is inside '..' string */\n\tbool get_tagname = false;/* point is after PROCEDURE/FUNCTION\n\t\tkeyword, so next item = potential tag */\n\tbool found_tag = false;  /* point is after a potential tag */\n\tbool inparms = false;    /* point is within parameter-list */\n\tbool verify_tag = false;\n\t\t/* point has passed the parm-list, so the next token will determine\n\t\t * whether this is a FORWARD/EXTERN to be ignored, or whether it is a\n\t\t * real tag\n\t\t */\n\n\tdbp = readLineFromInputFile ();\n\twhile (dbp != NULL)\n\t{\n\t\tint c = *dbp++;\n\n\t\tif (c == '\\0')  /* if end of line */\n\t\t{\n\t\t\tif (incomment && comment_char == '/')\n\t\t\t\tincomment = false;\n\n\t\t\tdbp = readLineFromInputFile ();\n\t\t\tif (dbp == NULL  ||  *dbp == '\\0')\n\t\t\t\tcontinue;\n\t\t\tif (!((found_tag && verify_tag) || get_tagname))\n\t\t\t\tc = *dbp++;\n\t\t\t\t\t/* only if don't need *dbp pointing to the beginning of\n\t\t\t\t\t * the name of the procedure or function\n\t\t\t\t\t */\n\t\t}\n\t\tif (incomment)\n\t\t{\n\t\t\tif (comment_char == '{' && c == '}')\n\t\t\t\tincomment = false;\n\t\t\telse if (comment_char == '(' && c == '*' && *dbp == ')')\n\t\t\t{\n\t\t\t\tdbp++;\n\t\t\t\tincomment = false;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\telse if (inquote)\n\t\t{\n\t\t\tif (c == '\\'')\n\t\t\t\tinquote = false;\n\t\t\tcontinue;\n\t\t}\n\t\telse switch (c)\n\t\t{\n\t\t\tcase '\\'':\n\t\t\t\tinquote = true;  /* found first quote */\n\t\t\t\tcontinue;\n\t\t\tcase '{':  /* found open { comment */\n\t\t\t\tincomment = true;\n\t\t\t\tcomment_char = c;\n\t\t\t\tcontinue;\n\t\t\tcase '/':\n\t\t\t\tif (*dbp == '/')  /* found one line // comment */\n\t\t\t\t{\n\t\t\t\t\tincomment = true;\n\t\t\t\t\tcomment_char = c;\n\t\t\t\t\tdbp++;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\tcase '(':\n\t\t\t\tif (*dbp == '*')  /* found open (* comment */\n\t\t\t\t{\n\t\t\t\t\tincomment = true;\n\t\t\t\t\tcomment_char = c;\n\t\t\t\t\tdbp++;\n\t\t\t\t}\n\t\t\t\telse if (found_tag)  /* found '(' after tag, i.e., parm-list */\n\t\t\t\t\tinparms = true;\n\t\t\t\tcontinue;\n\t\t\tcase ')':  /* end of parms list */\n\t\t\t\tif (inparms)\n\t\t\t\t\tinparms = false;\n\t\t\t\tcontinue;\n\t\t\tcase ';':\n\t\t\t\tif (found_tag && !inparms)  /* end of proc or fn stmt */\n\t\t\t\t{\n\t\t\t\t\tverify_tag = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t}\n\t\tif (found_tag && verify_tag && *dbp != ' ')\n\t\t{\n\t\t\t/* check if this is an \"extern\" declaration */\n\t\t\tif (*dbp == '\\0')\n\t\t\t\tcontinue;\n\t\t\tif (tolower (*dbp == 'e'))\n\t\t\t{\n\t\t\t\tif (tail (\"extern\"))  /* superfluous, really! */\n\t\t\t\t{\n\t\t\t\t\tfound_tag = false;\n\t\t\t\t\tverify_tag = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (tolower (*dbp) == 'f')\n\t\t\t{\n\t\t\t\tif (tail (\"forward\"))  /*  check for forward reference */\n\t\t\t\t{\n\t\t\t\t\tfound_tag = false;\n\t\t\t\t\tverify_tag = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found_tag && verify_tag)  /* not external proc, so make tag */\n\t\t\t{\n\t\t\t\tfound_tag = false;\n\t\t\t\tverify_tag = false;\n\t\t\t\tmakePascalTag (&tag);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (get_tagname)  /* grab name of proc or fn */\n\t\t{\n\t\t\tconst unsigned char *cp;\n\n\t\t\tif (*dbp == '\\0')\n\t\t\t\tcontinue;\n\n\t\t\t/* grab block name */\n\t\t\twhile (isspace (*dbp))\n\t\t\t\t++dbp;\n\t\t\tif (!starttoken(*dbp))\n\t\t\t\tcontinue;\n\t\t\tfor (cp = dbp  ;  *cp != '\\0' && !endtoken (*cp)  ;  cp++)\n\t\t\t\tcontinue;\n\t\t\tvStringNCopyS (name, (const char*) dbp,  cp - dbp);\n\n\t\t\tvStringClear (arglist);\n\t\t\tvStringClear (vartype);\n\t\t\tparseArglist ((const char*) cp, arglist, (kind == K_FUNCTION) ? vartype : NULL);\n\n\t\t\tcreatePascalTag (&tag, name, kind, arglist, (kind == K_FUNCTION) ? vartype : NULL);\n\t\t\tdbp = cp;  /* set dbp to e-o-token */\n\t\t\tget_tagname = false;\n\t\t\tfound_tag = true;\n\t\t\t/* and proceed to check for \"extern\" */\n\t\t}\n\t\telse if (!incomment && !inquote && !found_tag)\n\t\t{\n\t\t\tswitch (tolower (c))\n\t\t\t{\n\t\t\t\tcase 'c':\n\t\t\t\t\tif (tail (\"onstructor\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tget_tagname = true;\n\t\t\t\t\t\tkind = K_PROCEDURE;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'd':\n\t\t\t\t\tif (tail (\"estructor\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tget_tagname = true;\n\t\t\t\t\t\tkind = K_PROCEDURE;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'p':\n\t\t\t\t\tif (tail (\"rocedure\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tget_tagname = true;\n\t\t\t\t\t\tkind = K_PROCEDURE;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'f':\n\t\t\t\t\tif (tail (\"unction\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tget_tagname = true;\n\t\t\t\t\t\tkind = K_FUNCTION;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}  /* while not eof */\n\t}\n\tvStringDelete (arglist);\n\tvStringDelete (vartype);\n\tvStringDelete (name);\n}\n\nextern parserDefinition* PascalParser (void)\n{\n\tstatic const char *const extensions [] = { \"p\", \"pas\", NULL };\n\tparserDefinition* def = parserNew (\"Pascal\");\n\tdef->extensions = extensions;\n\tdef->kindTable      = PascalKinds;\n\tdef->kindCount  = ARRAY_SIZE (PascalKinds);\n\tdef->parser     = findPascalTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/perl-function-parameters.c",
    "content": "/*\n *   Copyright (c) 2021, Masatake YAMATO\n *   Copyright (c) 2021, Red Hat, Inc.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for Function::Parameters perl extension.\n *   https://metacpan.org/pod/Function::Parameters\n *\n *   This parser is inspired by the pull request submitted by Jim Butler (@jimmygoogle).\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"x-perl.h\"\n\n#include <string.h>\n\n/*\n *   DATA DECLARATIONS\n */\n\nenum FParamsKind {\n\tK_METHOD,\n\tK_FUN,\n};\n\nstatic kindDefinition FParamsKinds[] = {\n\t{ true, 'm', \"method\", \"methods\" },\n\t{ true, 'f', \"fun\",    \"functions\" },\n};\n\nstruct FParamsSubparser {\n\tperlSubparser perl;\n\tbool notInFParams;\n\tbool inPod;\n};\n\n/*\n *   FUNCTION PROTOTYPES\n */\n\nstatic void inputStart (subparser *s);\nstatic void makeTagEntryNotify (subparser *s, const tagEntryInfo *tag, int corkIndex);\nstatic void enterFParams (struct FParamsSubparser *fparms);\nstatic void leaveFParams (struct FParamsSubparser *fparams);\nstatic void enteringPodNotify (perlSubparser *perl);\nstatic void leavingPodNotify  (perlSubparser *perl);\n\n/*\n *   DATA DEFINITIONS\n */\n\nstatic struct FParamsSubparser fparamsSubparser = {\n\t.perl = {\n\t\t.subparser = {\n\t\t\t.direction  = SUBPARSER_BI_DIRECTION,\n\t\t\t.inputStart = inputStart,\n\t\t\t.makeTagEntryNotify = makeTagEntryNotify,\n\t\t},\n\t\t.enteringPodNotify = enteringPodNotify,\n\t\t.leavingPodNotify  = leavingPodNotify,\n\t}\n};\n\n/*\n *   FUNCTION DEFINITIONS\n */\n\nstatic void inputStart (subparser *s)\n{\n\tstruct FParamsSubparser *fparams = (struct FParamsSubparser *)s;\n\n\tfparams->notInFParams = true;\n\tfparams->inPod = false;\n}\n\nstatic void makeTagEntryNotify (subparser *s, const tagEntryInfo *tag, int corkIndex)\n{\n\tperlSubparser *perl = (perlSubparser *)s;\n\tstruct FParamsSubparser *fparams = (struct FParamsSubparser *)perl;\n\n\tif (isTagExtraBitMarked(tag, XTAG_QUALIFIED_TAGS))\n\t\treturn;\n\n\tif (tag->kindIndex == KIND_PERL_MODULE)\n\t{\n\t\tif (isRoleAssigned(tag, ROLE_PERL_MODULE_USED)\n\t\t\t&& strcmp (tag->name, \"Function::Parameters\") == 0)\n\t\t\tenterFParams (fparams);\n\t\telse if (isRoleAssigned(tag, ROLE_PERL_MODULE_UNUSED)\n\t\t\t\t && strcmp (tag->name, \"Function::Parameters\") == 0)\n\t\t\tleaveFParams (fparams);\n\t}\n}\n\nstatic void enterFParams (struct FParamsSubparser *fparams)\n{\n\tfparams->notInFParams = false;\n}\n\nstatic void leaveFParams (struct FParamsSubparser *fparams)\n{\n\tfparams->notInFParams = true;\n}\n\nstatic void enteringPodNotify (perlSubparser *perl)\n{\n\tstruct FParamsSubparser *fparams = (struct FParamsSubparser *)perl;\n\tfparams->inPod = true;\n}\n\nstatic void leavingPodNotify  (perlSubparser *perl)\n{\n\tstruct FParamsSubparser *fparams = (struct FParamsSubparser *)perl;\n\tfparams->inPod = false;\n}\n\nstatic bool findFParamsObject (const char * line, const regexMatch *matches, unsigned int count,\n\t\t\t\t\t\t\t   void *userData)\n{\n\tstruct FParamsSubparser *fparams = (struct FParamsSubparser *)userData;\n\n\tif (fparams->inPod)\n\t\treturn false;\n\n\n\tconst char *kindHint = line + matches[1].start;\n\tint kind = kindHint [0] == 'm'? K_METHOD: K_FUN;\n\n\tchar *name = eStrndup (line + matches[2].start, matches[2].length);\n\ttagEntryInfo e;\n\tinitTagEntry (&e, name, kind);\n\n\tmakeTagEntry (&e);\n\teFree (name);\n\treturn true;\n}\n\nstatic void findFParamsTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic void initializeFParamsParser (langType language)\n{\n\taddLanguageCallbackRegex (language, \"^[ \\t]*(method|fun)[ \\t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \\t]*\\\\(\",\n\t\t\t\t\t\t\t  NULL,\n\t\t\t\t\t\t\t  findFParamsObject, &fparamsSubparser.notInFParams,\n\t\t\t\t\t\t\t  &fparamsSubparser);\n}\n\nextern parserDefinition* FunctionParametersParser (void)\n{\n\tparserDefinition* const def = parserNew(\"FunctionParameters\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Perl\", &fparamsSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = FParamsKinds;\n\tdef->kindCount = ARRAY_SIZE(FParamsKinds);\n\n\tdef->initialize = initializeFParamsParser;\n\tdef->parser = findFParamsTags;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/perl-moose.c",
    "content": "/*\n *   Copyright (c) 2019, Masatake YAMATO\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for Moose perl extension.\n *   https://metacpan.org/pod/Moose\n *\n *   This module can gather tags for Moo perl extension, too.\n *   https://metacpan.org/pod/Moo\n *\n */\n\n/* NOTE about kind/role design:\n *\n * sub foo { ... }\n * after 'foo' => sub { ...}\n *\n * There were two ideas to capture 'foo':\n *\n * A: capturing 'foo' as a reference tag with 'method' kind and 'wrapped' role, and\n * B: capturing 'foo' as a definition tag with 'wrapper' kind.\n *\n * This implementation takes the idea B. */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"  /* must always come first */\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"x-perl.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"trace.h\"\n\n#include <string.h>\n\n/*\n *   DATA DECLARATIONS\n */\n\nenum MooseKind {\n\tK_CLASS,\n\tK_METHOD,\n\tK_ATTR,\n\tK_WRAPPER,\n\tK_ROLE,\n};\n\nstatic kindDefinition MooseKinds[] = {\n\t{ true, 'c', \"class\", \"classes\"  },\n\t{ true, 'm', \"method\", \"methods\" },\n\t{ true, 'a', \"attribute\", \"attributes\" },\n\t{ true, 'w', \"wrapper\", \"wrappers\" },\n\t{ true, 'r', \"role\", \"roles\" },\n};\n\ntypedef enum {\n\tF_WRAPPING,\n} MooseField;\n\nstatic fieldDefinition MooseFields [] = {\n\t{\n\t\t.name = \"wrapping\",\n\t\t.description = \"how a wrapper wrapping the method (around, after, or before)\",\n\t\t.enabled = true,\n\t},\n};\n\nenum Wrapping {\n\tW_UNKNOWN,\n\tW_AROUND,\n\tW_BEFORE,\n\tW_AFTER,\n};\n\nstatic char * WrappingStrings[] = {\n\t\"unknown\",\n\t\"around\",\n\t\"before\",\n\t\"after\",\n};\n\nstruct mooseSubparser {\n\tperlSubparser perl;\n\tbool notInMoose;\n\tbool inPod;\n\tint packageCork;\n\tint classCork;\n\tbool notContinuousExtendsLines;\n\n\tint indexForFunctionParameters;\n\n\t/* functionParametersModifiersStateCounter is for tracking the conditions\n\t * that both \"use Moose;\" and \"use Functions::Parameters qw/:modifiers/\"\n\t * are specified.\n\t * functionParametersModifiersStateCounter is initialized to 2.\n\t * Decrement functionParametersModifiersStateCounter when finding one of two.\n\t * When functionParametersModifiersStateCounter is 0, the state is\n\t * propagated to notInFunctionParametersModifiers. */\n\tbool notInFunctionParametersModifiers;\n\tint  functionParametersModifiersStateCounter;\n#define RESET_FunctionParameters_STATE(MOOSE)\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tMOOSE->notInFunctionParametersModifiers = true;\t\t\\\n\t\tMOOSE->functionParametersModifiersStateCounter = 2;\t\\\n\t} while (0)\n#define DEC_FunctionParameters_STATE(MOOSE)\t\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tMOOSE->functionParametersModifiersStateCounter--;\t\t\t\\\n\t\tif (MOOSE->functionParametersModifiersStateCounter == 0)\t\\\n\t\t\tMOOSE->notInFunctionParametersModifiers = false;\t\t\\\n\t\tif (MOOSE->functionParametersModifiersStateCounter < 0)\t\t\\\n\t\t\tMOOSE->functionParametersModifiersStateCounter = 0; \t\\\n\t} while (0)\n#define INC_FunctionParameters_STATE(MOOSE)\t\t\t\t\t\t\\\n\tdo {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tMOOSE->functionParametersModifiersStateCounter++;\t\t\\\n\t\tif (MOOSE->functionParametersModifiersStateCounter > 0)\t\\\n\t\t\tMOOSE->notInFunctionParametersModifiers = true;\t\t\\\n\t\tif (MOOSE->functionParametersModifiersStateCounter > 2)\t\\\n\t\t\tMOOSE->functionParametersModifiersStateCounter = 2;\t\\\n\t} while (0)\n\n\tvString *supersOrRoles;\n};\n\n/*\n *   FUNCTION PROTOTYPES\n */\nstatic void inputStart (subparser *s);\nstatic void inputEnd (subparser *s);\nstatic void makeTagEntryNotify (subparser *s, const tagEntryInfo *tag, int corkIndex);\nstatic void enterMoose (struct mooseSubparser *moose, bool role);\nstatic void leaveMoose (struct mooseSubparser *moose);\nstatic void enteringPodNotify (perlSubparser *perl);\nstatic void leavingPodNotify  (perlSubparser *perl);\nstatic void findingQuotedWordNotify (perlSubparser *perl, int moduleIndex, const char *qwd);\n\n/*\n *   DATA DEFINITIONS\n */\n\nstatic struct mooseSubparser mooseSubparser = {\n\t.perl = {\n\t\t.subparser = {\n\t\t\t.direction  = SUBPARSER_BI_DIRECTION,\n\t\t\t.inputStart = inputStart,\n\t\t\t.inputEnd   = inputEnd,\n\t\t\t.makeTagEntryNotify = makeTagEntryNotify,\n\t\t},\n\t\t.enteringPodNotify = enteringPodNotify,\n\t\t.leavingPodNotify  = leavingPodNotify,\n\t\t.findingQuotedWordNotify = findingQuotedWordNotify,\n\t},\n};\n\n\n/*\n *   FUNCTION DEFINITIONS\n */\n\nstatic void inputStart (subparser *s)\n{\n\tstruct mooseSubparser *moose = (struct mooseSubparser *)s;\n\n\tmoose->notInMoose = true;\n\tmoose->packageCork = CORK_NIL;\n\tmoose->classCork = CORK_NIL;\n\tmoose->inPod = false;\n\tmoose->supersOrRoles = vStringNew ();\n\tmoose->notContinuousExtendsLines = true;\n\tmoose->indexForFunctionParameters = CORK_NIL;\n\tRESET_FunctionParameters_STATE (moose);\n}\n\nstatic void inputEnd (subparser *s)\n{\n\tstruct mooseSubparser *moose = (struct mooseSubparser *)s;\n\tsetTagEndLineToCorkEntry (moose->classCork, getInputLineNumber ());\n\n\tvStringDelete (moose->supersOrRoles);\n\tmoose->supersOrRoles = NULL;\n\tmoose->notInMoose = true;\n}\n\nstatic void makeTagEntryNotify (subparser *s, const tagEntryInfo *tag, int corkIndex)\n{\n\tperlSubparser *perl = (perlSubparser *)s;\n\tstruct mooseSubparser *moose = (struct mooseSubparser *)perl;\n\n\tif (isTagExtraBitMarked(tag, XTAG_QUALIFIED_TAGS))\n\t\treturn;\n\n\tif (tag->kindIndex == KIND_PERL_PACKAGE)\n\t\tmoose->packageCork = corkIndex;\n\telse if ((!moose->notInMoose) && tag->kindIndex == KIND_PERL_SUBROUTINE)\n\t{\n\t\ttagEntryInfo moose_e;\n\t\tinitTagEntry (&moose_e, tag->name, K_METHOD);\n\t\tsetTagPositionFromTag (&moose_e, tag);\n\t\tmoose_e.extensionFields.scopeIndex = moose->classCork;\n\t\tmakeTagEntry (&moose_e);\n\t}\n\telse if (tag->kindIndex == KIND_PERL_MODULE)\n\t{\n\t\tif (isRoleAssigned(tag, ROLE_PERL_MODULE_USED))\n\t\t{\n\t\t\tif (strcmp (tag->name, \"Moose\") == 0\n\t\t\t\t|| strcmp (tag->name, \"Moo\") == 0)\n\t\t\t\tenterMoose (moose, false);\n\t\t\telse if (strcmp (tag->name, \"Moose::Role\") == 0)\n\t\t\t\tenterMoose (moose, true);\n\t\t\telse if (strcmp (tag->name, \"Function::Parameters\") == 0)\n\t\t\t\tmoose->indexForFunctionParameters = corkIndex;\n\t\t}\n\t\telse if (isRoleAssigned(tag, ROLE_PERL_MODULE_UNUSED))\n\t\t{\n\t\t\tif (strcmp (tag->name, \"Moose\") == 0\n\t\t\t\t|| strcmp (tag->name, \"Moo\") == 0)\n\t\t\t\tleaveMoose (moose);\n\t\t\telse if (strcmp (tag->name, \"Function::Parameters\") == 0)\n\t\t\t{\n\t\t\t\tmoose->indexForFunctionParameters = CORK_NIL;\n\t\t\t\tINC_FunctionParameters_STATE(moose);\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void enteringPodNotify (perlSubparser *perl)\n{\n\tstruct mooseSubparser *moose = (struct mooseSubparser *)perl;\n\tmoose->inPod = true;\n}\n\nstatic void leavingPodNotify  (perlSubparser *perl)\n{\n\tstruct mooseSubparser *moose = (struct mooseSubparser *)perl;\n\tmoose->inPod = false;\n}\n\nstatic void findingQuotedWordNotify (perlSubparser *perl,\n\t\t\t\t\t\t\t\t\t int moduleIndex, const char *qwd)\n{\n\tstruct mooseSubparser *moose = (struct mooseSubparser *)perl;\n\tif (moose->indexForFunctionParameters != moduleIndex)\n\t\treturn;\n\n\tif (strcmp (qwd, \":modifiers\") == 0)\n\t\tDEC_FunctionParameters_STATE(moose);\n}\n\nstatic void leaveMoose (struct mooseSubparser *moose)\n{\n\tmoose->notContinuousExtendsLines = true;\n\n\tsetTagEndLineToCorkEntry (moose->classCork, getInputLineNumber ());\n\n\tmoose->classCork = CORK_NIL;\n\tmoose->notInMoose = true;\n\tmoose->packageCork = CORK_NIL;\n\tINC_FunctionParameters_STATE(moose);\n}\n\nstatic void enterMoose (struct mooseSubparser *moose, bool role)\n{\n\tmoose->notContinuousExtendsLines = true;\n\n\ttagEntryInfo *perl_e = getEntryInCorkQueue (moose->packageCork);\n\tif (!perl_e)\n\t\treturn;\n\n\tmoose->notInMoose = false;\n\n\ttagEntryInfo moose_e;\n\tinitTagEntry (&moose_e, perl_e->name, role? K_ROLE: K_CLASS);\n\tupdateTagLine(&moose_e, perl_e->lineNumber, perl_e->filePosition);\n\tmoose->classCork = makeTagEntry (&moose_e);\n\tvStringClear (moose->supersOrRoles);\n\n\tDEC_FunctionParameters_STATE(moose);\n\n\treturn;\n}\n\nstatic void parseExtendsClass (const char *input,\n\t\t\t\t\t\t\t   size_t input_len,\n\t\t\t\t\t\t\t   vString *inherits,\n\t\t\t\t\t\t\t   bool *notContinuousLine)\n{\n\tsize_t i = 0;\n\tdo\n\t{\n\t\tif (input [i] == ',')\n\t\t\ti++;\n\n\t\tfor (; (i < input_len) && input[i] != '\\n' && input[i] != '\\0'; i++)\n\t\t{\n\t\t\tif (input[i] == '\\'' || input[i] == ' '  || input[i] == '\\t')\n\t\t\t\tcontinue;\n\t\t\telse if (input[i] == ',')\n\t\t\t{\n\t\t\t\tvStringPut (inherits, ',');\n\t\t\t\t*notContinuousLine = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (input[i] == ';')\n\t\t\t{\n\t\t\t\t*notContinuousLine = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t\tvStringPut (inherits, input[i]);\n\t\t}\n\t}\n\twhile (input[i] == ',');\n}\n\nstatic bool findExtendsClass (const char *line,\n\t\t\t\t\t\t\t  const regexMatch *matches,\n\t\t\t\t\t\t\t  unsigned int count,\n\t\t\t\t\t\t\t  void *data)\n{\n\tstruct mooseSubparser *moose = data;\n\tmoose->notContinuousExtendsLines = true;\n\n\tif (moose->inPod)\n\t\treturn true;\n\n\ttagEntryInfo *e = getEntryInCorkQueue (moose->classCork);\n\tif (!e)\n\t\treturn true;\n\n\tconst char *input = line + matches[2].start;\n\tvString *str = moose->supersOrRoles;\n\n\tvStringPutUnlessEmpty (str, ',');\n\tparseExtendsClass (input, matches[2].length, str,\n\t\t\t\t\t   &moose->notContinuousExtendsLines);\n\n\tif (moose->notContinuousExtendsLines == true\n\t\t&& vStringLength (str) > 0)\n\t{\n\t\tif (e->extensionFields.inheritance)\n\t\t\teFree ((void *)e->extensionFields.inheritance);\n\t\te->extensionFields.inheritance = vStringStrdup (str);\n\t}\n\n\treturn true;\n}\n\nstatic bool findExtendsClassContinuation (const char *line,\n\t\t\t\t\t\t\t\t\t\t  const regexMatch *matches,\n\t\t\t\t\t\t\t\t\t\t  unsigned int count,\n\t\t\t\t\t\t\t\t\t\t  void *data)\n{\n\tstruct mooseSubparser *moose = data;\n\tmoose->notContinuousExtendsLines = true;\n\n\ttagEntryInfo *e = getEntryInCorkQueue (moose->classCork);\n\tif (!e)\n\t\treturn true;\n\n\tconst char *input = line + matches[1].start;\n\tvString *str = moose->supersOrRoles;\n\n\tparseExtendsClass (input, matches[1].length, str,\n\t\t\t\t\t   &moose->notContinuousExtendsLines);\n\n\tif (moose->notContinuousExtendsLines == true\n\t\t&& vStringLength (str) > 0)\n\t{\n\t\tif (e->extensionFields.inheritance)\n\t\t\teFree ((void *)e->extensionFields.inheritance);\n\t\te->extensionFields.inheritance = vStringStrdup (str);\n\t}\n\n\treturn true;\n}\n\nstatic const char *parseAttributeOrWrapper (const char *str, int parentCorkIndex, int extraTerminator,\n\t\t\t\t\t\t\t\t\t\t\tint kind, enum Wrapping wrapping)\n{\n\tint i;\n\n\tfor (i = 0;\n\t\t str[i]\n\t\t\t && str[i] != extraTerminator\n\t\t\t && (isalnum ((unsigned char)str[i]) || str[i] == '_');\n\t\t i++)\n\t\t;\t\t\t\t\t\t/* Just advancing `i' */\n\n\tif (i == 0)\n\t\treturn NULL;\n\n\ttagEntryInfo e;\n\tchar *buf = eStrndup (str, i);\n\n\tinitTagEntry (&e, buf, kind);\n\tif (parentCorkIndex != CORK_NIL)\n\t\te.extensionFields.scopeIndex = parentCorkIndex;\n\n\tint corkIndex = makeTagEntry (&e);\n\tif (kind == K_WRAPPER)\n\t\tattachParserFieldToCorkEntry (corkIndex, MooseFields[F_WRAPPING].ftype,\n\t\t\t\t\t\t\t\t\t  WrappingStrings [wrapping]);\n\teFree (buf);\n\n\treturn str[i] == '\\0'? NULL: str + i;\n}\n\nstatic void solveKindAndWrapping (const char *str, int *kind, enum Wrapping *wrapping)\n{\n\t*kind = K_WRAPPER;\n\t*wrapping = W_UNKNOWN;\n\tswitch (str[0])\n\t{\n\tcase 'h':\t\t\t\t\t/* has */\n\t\t*kind = K_ATTR;\n\t\tbreak;\n\tcase 'a':\t\t\t\t\t/* around or after */\n\t\tif (str[1] == 'r')\n\t\t\t*wrapping = W_AROUND;\n\t\telse if (str[1] == 'f')\n\t\t\t*wrapping = W_AFTER;\n\t\tbreak;\n\tcase 'b':\t\t\t\t\t/* before */\n\t\t*wrapping = W_BEFORE;\n\t\tbreak;\n\tcase 'o':\t\t\t\t\t/* override */\n\t\t*kind = K_METHOD;\n\t}\n}\n\nstatic bool findAttributeOrWrapperOne (const char *line,\n\t\t\t\t\t\t\t\t\t   const regexMatch *matches,\n\t\t\t\t\t\t\t\t\t   unsigned int count,\n\t\t\t\t\t\t\t\t\t   void *data)\n{\n\tstruct mooseSubparser *moose = data;\n\tint kind;\n\tenum Wrapping wrapping;\n\n\tif (moose->inPod)\n\t\treturn true;\n\n\tmoose->notContinuousExtendsLines = true;\n\n\tif (count < 3)\n\t\treturn true;\n\n\tsolveKindAndWrapping (line + matches[1].start, &kind, &wrapping);\n\tparseAttributeOrWrapper (line + matches[2].start, moose->classCork, -1,\n\t\t\t\t\t\t\t kind, wrapping);\n\treturn true;\n}\n\nstatic bool findAttributeOrWrapperMulti (const char *line,\n\t\t\t\t\t\t\t\t\t\t const regexMatch *matches,\n\t\t\t\t\t\t\t\t\t\t unsigned int count,\n\t\t\t\t\t\t\t\t\t\t void *data)\n{\n\n\tstruct mooseSubparser *moose = data;\n\tint kind;\n\tenum Wrapping wrapping;\n\tint terminator;\n\n\tif (moose->inPod)\n\t\treturn true;\n\n\tmoose->notContinuousExtendsLines = true;\n\n\tif (count < 4)\n\t\treturn true;\n\n\tsolveKindAndWrapping (line + matches[1].start, &kind, &wrapping);\n\tterminator = line[matches[2].start];\n\n\n\tconst char *str = line + matches[3].start;\n\twhile ((str = parseAttributeOrWrapper (str, moose->classCork, terminator,\n\t\t\t\t\t\t\t\t\t\t   kind, wrapping)))\n\t{\n\t\tint i;\n\t\tfor (i = 0; (str[i] == ' ') || (str[i] == '\\t'); i++)\n\t\t\t;\n\t\tif (str[i] == '\\0' || str[i] == terminator)\n\t\t\tbreak;\n\t\tstr = str + i;\n\t}\n\n\treturn true;\n}\n\nstatic void findMooseTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic void initializeMooseParser (langType language)\n{\n\taddLanguageCallbackRegex (language, \"^[ \\t]*(extends|with) *(.+)\",\n\t\t\t\t\t\t\t  \"{exclusive}\",\n\t\t\t\t\t\t\t  findExtendsClass, &mooseSubparser.notInMoose,\n\t\t\t\t\t\t\t  &mooseSubparser);\n\taddLanguageCallbackRegex (language, \"^[ \\t]*(has|after|before|around|override) +\"\n\t\t\t\t\t\t\t  /* foo => ()\n\t\t\t\t\t\t\t   * 'foo' => ()\n\t\t\t\t\t\t\t   * \"foo\" => ()\n\t\t\t\t\t\t\t   * ( foo => ())\n\t\t\t\t\t\t\t   * ( \"foo\" => ())\n\t\t\t\t\t\t\t   * ( 'foo' => ()) */\n\t\t\t\t\t\t\t  \"\\\\(?[ \\t]*[\\\"']?\"\n\t\t\t\t\t\t\t  \"\"\n\t\t\t\t\t\t\t  \"([a-zA-Z_][a-zA-Z0-9_]*([ \\t][a-zA-Z_][a-zA-Z0-9_]*)*).*=>\",\n\t\t\t\t\t\t\t  \"{exclusive}\",\n\t\t\t\t\t\t\t  findAttributeOrWrapperOne, &mooseSubparser.notInMoose,\n\t\t\t\t\t\t\t  &mooseSubparser);\n\taddLanguageCallbackRegex (language, \"^[ \\t]*(has|after|before|around) +\\\\(?\\\\[qw([^ \\t])[ \\t]*\"\n\t\t\t\t\t\t\t  /* [qw/foo bar/] => ()\n\t\t\t\t\t\t\t   * ([qw/foo bar/] => ()) */\n\t\t\t\t\t\t\t  \"([a-zA-Z_][a-zA-Z0-9_]*([ \\t][a-zA-Z_][a-zA-Z0-9_]*)*).*=>\",\n\t\t\t\t\t\t\t  \"{exclusive}\",\n\t\t\t\t\t\t\t  findAttributeOrWrapperMulti, &mooseSubparser.notInMoose,\n\t\t\t\t\t\t\t  &mooseSubparser);\n\taddLanguageCallbackRegex (language, \"^[ \\t]*(has|after|before|around|override) +\"\n\t\t\t\t\t\t\t  \"([a-zA-Z_][a-zA-Z0-9_]*)[ \\t]*\\\\(\",\n\t\t\t\t\t\t\t  \"{exclusive}\",\n\t\t\t\t\t\t\t  findAttributeOrWrapperOne, &mooseSubparser.notInFunctionParametersModifiers,\n\t\t\t\t\t\t\t  &mooseSubparser);\n\taddLanguageCallbackRegex (language, \"^[ \\t]*(.+)\",\n\t\t\t\t\t\t\t  \"{exclusive}\",\n\t\t\t\t\t\t\t  findExtendsClassContinuation, &mooseSubparser.notContinuousExtendsLines,\n\t\t\t\t\t\t\t  &mooseSubparser);\n}\n\nextern parserDefinition* MooseParser (void)\n{\n\tparserDefinition* const def = parserNew(\"Moose\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Perl\", &mooseSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = MooseKinds;\n\tdef->kindCount = ARRAY_SIZE(MooseKinds);\n\n\tdef->fieldTable = MooseFields;\n\tdef->fieldCount = ARRAY_SIZE (MooseFields);\n\n\tdef->initialize = initializeMooseParser;\n\tdef->parser = findMooseTags;\n\tdef->useCork = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/perl.c",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for PERL language\n*   files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"x-perl.h\"\n#include \"promise.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"subparser.h\"\n#include \"trace.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum PerlKindType perlKind;\ntypedef enum PerlModuleRoleType perlModuleRole;\n\nstatic roleDefinition PerlModuleRoles [] = {\n\t{ true, \"used\",   \"specified in `use' built-in function\" },\n\t{ true, \"unused\", \"specified in `no' built-in function\" },\n};\n\ntypedef enum {\n\tR_HEREDOC_ENDLABEL,\n} perlHeredocRole;\n\nstatic roleDefinition PerlHeredocRoles [] = {\n\t{ true, \"endmarker\", \"end marker\" },\n};\n\nstatic kindDefinition PerlKinds [] = {\n\t{ true,  'c', \"constant\",               \"constants\" },\n\t{ true,  'f', \"format\",                 \"formats\" },\n\t{ true,  'l', \"label\",                  \"labels\" },\n\t{ true,  'p', \"package\",                \"packages\" },\n\t{ true,  's', \"subroutine\",             \"subroutines\" },\n\t{ false, 'd', \"subroutineDeclaration\",  \"subroutine declarations\" },\n\t{ false, 'M', \"module\",                 \"modules\",\n\t  .referenceOnly = true,  ATTACH_ROLES(PerlModuleRoles)},\n\t{ false, 'h', \"heredoc\", \"marker for here document\",\n\t  .referenceOnly = false, ATTACH_ROLES (PerlHeredocRoles) },\n};\n\nstruct hereDocMarker {\n\tvString *marker;\n\tbool indented;\n\tint corkIndex;\n};\n\nstruct hereDocMarkerManager {\n\tptrArray *markers;\n\tsize_t current;\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void notifyEnteringPod (void)\n{\n\tsubparser *sub;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\tperlSubparser *perlsub = (perlSubparser *)sub;\n\t\tif (perlsub->enteringPodNotify)\n\t\t{\n\t\t\tenterSubparser (sub);\n\t\t\tperlsub->enteringPodNotify (perlsub);\n\t\t\tleaveSubparser ();\n\t\t}\n\t}\n}\n\nstatic void notifyLeavingPod (void)\n{\n\tsubparser *sub;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\tperlSubparser *perlsub = (perlSubparser *)sub;\n\t\tif (perlsub->leavingPodNotify)\n\t\t{\n\t\t\tenterSubparser (sub);\n\t\t\tperlsub->leavingPodNotify (perlsub);\n\t\t\tleaveSubparser ();\n\t\t}\n\t}\n}\n\nstatic void notifyFindingQuotedWord (int moduleIndex,\n\t\t\t\t\t\t\t\t\t const char *qwd)\n{\n\tsubparser *sub;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\tperlSubparser *perlsub = (perlSubparser *)sub;\n\t\tif (perlsub->findingQuotedWordNotify)\n\t\t{\n\t\t\tenterSubparser (sub);\n\t\t\tperlsub->findingQuotedWordNotify (perlsub,\n\t\t\t\t\t\t\t\t\t\t\t  moduleIndex,\n\t\t\t\t\t\t\t\t\t\t\t  qwd);\n\t\t\tleaveSubparser ();\n\t\t}\n\t}\n}\n\nstatic bool isIdentifier1 (int c)\n{\n\treturn (bool) (isalpha (c) || c == '_');\n}\n\nstatic bool isIdentifier (int c)\n{\n\treturn (bool) (isalnum (c) || c == '_');\n}\n\nstatic bool isPodWord (const char *word)\n{\n\t/* Perl POD words are three to eight characters in size.  We use this\n\t * fact to find (or not find) the right side of the word and then\n\t * perform comparisons, if necessary, of POD words of that size.\n\t */\n\tsize_t len;\n\tfor (len = 0; len < 9; ++len)\n\t\tif ('\\0' == word[len] || ' ' == word[len] || '\\t' == word[len])\n\t\t\tbreak;\n\tswitch (len) {\n\t\tcase 3:\n\t\t\treturn 0 == strncmp(word, \"end\", 3)\n\t\t\t\t|| 0 == strncmp(word, \"for\", 3)\n\t\t\t\t|| 0 == strncmp(word, \"pod\", 3);\n\t\tcase 4:\n\t\t\treturn 0 == strncmp(word, \"back\", 4)\n\t\t\t\t|| 0 == strncmp(word, \"item\", 4)\n\t\t\t\t|| 0 == strncmp(word, \"over\", 4);\n\t\tcase 5:\n\t\t\treturn 0 == strncmp(word, \"begin\", 5)\n\t\t\t\t|| 0 == strncmp(word, \"head1\", 5)\n\t\t\t\t|| 0 == strncmp(word, \"head2\", 5)\n\t\t\t\t|| 0 == strncmp(word, \"head3\", 5)\n\t\t\t\t|| 0 == strncmp(word, \"head4\", 5);\n\t\tcase 8:\n\t\t\treturn 0 == strncmp(word, \"encoding\", 8);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\n/*\n * Perl subroutine declaration may look like one of the following:\n *\n *  sub abc;\n *  sub abc :attr;\n *  sub abc (proto);\n *  sub abc (proto) :attr;\n *\n * Note that there may be more than one attribute.  Attributes may\n * have things in parentheses (they look like arguments).  Anything\n * inside of those parentheses goes.  Prototypes may contain semi-colons.\n * The matching end when we encounter (outside of any parentheses) either\n * a semi-colon (that'd be a declaration) or an left curly brace\n * (definition).\n *\n * This is pretty complicated parsing (plus we all know that only perl can\n * parse Perl), so we are only promising best effort here.\n *\n * If we can't determine what this is (due to a file ending, for example),\n * we will return false.\n */\nstatic bool isSubroutineDeclaration (const unsigned char *cp)\n{\n\tbool attr = false;\n\tint nparens = 0;\n\n\tdo {\n\t\tfor ( ; *cp; ++cp) {\nSUB_DECL_SWITCH:\n\t\t\tswitch (*cp) {\n\t\t\t\tcase ':':\n\t\t\t\t\tif (nparens)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\telse if (true == attr)\n\t\t\t\t\t\treturn false;    /* Invalid attribute name */\n\t\t\t\t\telse\n\t\t\t\t\t\tattr = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '(':\n\t\t\t\t\t++nparens;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ')':\n\t\t\t\t\t--nparens;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ' ':\n\t\t\t\tcase '\\t':\n\t\t\t\t\tbreak;\n\t\t\t\tcase ';':\n\t\t\t\t\tif (!nparens)\n\t\t\t\t\t\treturn true;\n\t\t\t\tcase '{':\n\t\t\t\t\tif (!nparens)\n\t\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\tif (attr) {\n\t\t\t\t\t\tif (isIdentifier1(*cp)) {\n\t\t\t\t\t\t\tcp++;\n\t\t\t\t\t\t\twhile (isIdentifier (*cp))\n\t\t\t\t\t\t\t\tcp++;\n\t\t\t\t\t\t\tattr = false;\n\t\t\t\t\t\t\tgoto SUB_DECL_SWITCH; /* Instead of --cp; */\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (nparens) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} while (NULL != (cp = readLineFromInputFile ()));\n\n\treturn false;\n}\n\n/* `end' points to the equal sign.  Parse from right to left to get the\n * identifier.  Assume we're dealing with something of form \\s*\\w+\\s*=>\n */\nstatic void makeTagFromLeftSide (const char *begin, const char *end,\n\tvString *name, vString *package)\n{\n\ttagEntryInfo entry;\n\tconst char *b, *e;\n\tif (! PerlKinds[KIND_PERL_CONSTANT].enabled)\n\t\treturn;\n\tfor (e = end - 1; e > begin && isspace((unsigned char) *e); --e)\n\t\t;\n\tif (e < begin)\n\t\treturn;\n\tfor (b = e; b >= begin && isIdentifier((unsigned char) *b); --b)\n\t\t;\n\t/* Identifier must be either beginning of line of have some whitespace\n\t * on its left:\n\t */\n\tif (b < begin || isspace((unsigned char) *b) || ',' == *b)\n\t\t++b;\n\telse if (b != begin)\n\t\treturn;\n\tif (e - b + 1 <= 0)\n\t\treturn;\t\t\t/* Left side of => has an invalid identifier. */\n\tvStringClear(name);\n\tvStringNCatS(name, b, e - b + 1);\n\tinitTagEntry(&entry, vStringValue(name), KIND_PERL_CONSTANT);\n\tmakeTagEntry(&entry);\n\tif (isXtagEnabled (XTAG_QUALIFIED_TAGS) && package && vStringLength(package)) {\n\t\tvStringClear(name);\n\t\tvStringCopy(name, package);\n\t\tvStringNCatS(name, b, e - b + 1);\n\t\tinitTagEntry(&entry, vStringValue(name), KIND_PERL_CONSTANT);\n\t\tmarkTagExtraBit (&entry, XTAG_QUALIFIED_TAGS);\n\t\tmakeTagEntry(&entry);\n\t}\n}\n\nstatic int makeTagForModule (const char *name, int role)\n{\n\ttagEntryInfo entry;\n\tinitRefTagEntry(&entry, name, KIND_PERL_MODULE, role);\n\treturn makeTagEntry(&entry);\n}\n\nenum const_state { CONST_STATE_NEXT_LINE, CONST_STATE_HIT_END };\n\n/* Parse a single line, find as many NAME => VALUE pairs as we can and try\n * to detect the end of the hashref.\n */\nstatic enum const_state parseConstantsFromLine (const char *cp,\n\tvString *name, vString *package)\n{\n\twhile (1) {\n\t\tconst size_t sz = strcspn(cp, \"#}=\");\n\t\tswitch (cp[sz]) {\n\t\t\tcase '=':\n\t\t\t\tif ('>' == cp[sz + 1])\n\t\t\t\t\tmakeTagFromLeftSide(cp, cp + sz, name, package);\n\t\t\t\tbreak;\n\t\t\tcase '}':\t/* Assume this is the end of the hashref. */\n\t\t\t\treturn CONST_STATE_HIT_END;\n\t\t\tcase '\\0':\t/* End of the line. */\n\t\t\tcase '#':\t/* Assume this is a comment and thus end of the line. */\n\t\t\t\treturn CONST_STATE_NEXT_LINE;\n\t\t}\n\t\tcp += sz + 1;\n\t}\n}\n\n/* Parse constants declared via hash reference, like this:\n * use constant {\n *   A => 1,\n *   B => 2,\n * };\n * The approach we take is simplistic, but it covers the vast majority of\n * cases well.  There can be some false positives.\n * Returns 0 if found the end of the hashref, -1 if we hit EOF\n */\nstatic int parseConstantsFromHashRef (const unsigned char *cp,\n\tvString *name, vString *package)\n{\n\twhile (1) {\n\t\tenum const_state state =\n\t\t\tparseConstantsFromLine((const char *) cp, name, package);\n\t\tswitch (state) {\n\t\t\tcase CONST_STATE_NEXT_LINE:\n\t\t\t\tcp = readLineFromInputFile();\n\t\t\t\tif (cp)\n\t\t\t\t\tbreak;\n\t\t\t\telse\n\t\t\t\t\treturn -1;\n\t\t\tcase CONST_STATE_HIT_END:\n\t\t\t\treturn 0;\n\t\t}\n\t}\n}\n\nstatic void parseQuotedWords(const unsigned char *cp,\n\t\t\t\t\t\t\t vString *name, int moduleIndex)\n{\n\tunsigned char end = *cp++;\n\tswitch (end)\n\t{\n\tcase '[': end = ']'; break;\n\tcase '(': end = ')'; break;\n\tcase '{': end = '}'; break;\n\tcase '<': end = '>'; break;\n\t}\n\n\tdo {\n\t\twhile (*cp && *cp != end)\n\t\t{\n\t\t\tif (isspace(*cp))\n\t\t\t{\n\t\t\t\tnotifyFindingQuotedWord (moduleIndex, vStringValue(name));\n\t\t\t\tvStringClear(name);\n\t\t\t\tcp++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (*cp == '\\\\')\n\t\t\t{\n\t\t\t\tcp++;\n\t\t\t\tif (*cp == '\\0')\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tvStringPut(name, *cp);\n\t\t\tcp++;\n\t\t}\n\t\tif (!vStringIsEmpty(name))\n\t\t\tnotifyFindingQuotedWord (moduleIndex, vStringValue(name));\n\n\t\tif (*cp == end)\n\t\t\tbreak;\n\t} while ((cp = readLineFromInputFile()) != NULL);\n}\n\n/*\n * Extract heredoc markers and skip the heredoc areas.\n *\n * - https://perldoc.perl.org/perlop#%3C%3CEOF\n */\nstatic struct hereDocMarker *hereDocMarkerNew (bool indented)\n{\n\tstruct hereDocMarker *marker = xMalloc(1, struct hereDocMarker);\n\n\tmarker->indented = indented;\n\tmarker->marker = vStringNew();\n\tmarker->corkIndex = CORK_NIL;\n\n\treturn marker;\n}\n\nstatic void hereDocMarkerDelete (struct hereDocMarker *marker)\n{\n\tvStringDelete (marker->marker);\n\teFree (marker);\n}\n\nstatic unsigned char *readHereDocMarker (unsigned char *line,\n\t\t\t\t\t\t\t\t\t\t vString *marker,\n\t\t\t\t\t\t\t\t\t\t unsigned char quote_char)\n{\n\tunsigned char *cp = line;\n\tbool backslash = false;\n\n\tfor (cp = line; *cp != '\\0'; cp++)\n\t{\n\t\tif (backslash)\n\t\t{\n\t\t\tvStringPut (marker, *cp);\n\t\t\tbackslash = false;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote_char == '\"' && (*cp == '\\\\'))\n\t\t{\n\t\t\tbackslash = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote_char && *cp == quote_char)\n\t\t{\n\t\t\tcp++;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!quote_char && !isIdentifier(*cp))\n\t\t\tbreak;\n\n\t\tvStringPut (marker, *cp);\n\t}\n\n\treturn cp;\n}\n\nenum stringType {\n\tSTRING_TYPE_NONE = '\\0',\n\tSTRING_TYPE_SINGLEQ = '\\'',\n\tSTRING_TYPE_DOUBLEQ = '\"',\n\tSTRING_TYPE_BACKQ = '`',\n};\n\n\nstatic const unsigned char *escapeFromString (const unsigned char *line,\n\t\t\t\t\t\t\t\t\t\t\t  const unsigned char *end,\n\t\t\t\t\t\t\t\t\t\t\t  enum stringType stype)\n{\n\tbool in_escape = false;\n\tconst unsigned char *cp = line;\n\n\tswitch (stype)\n\t{\n\tcase STRING_TYPE_NONE:\n\t\treturn line;\n\tcase STRING_TYPE_SINGLEQ:\n\tcase STRING_TYPE_DOUBLEQ:\n\tcase STRING_TYPE_BACKQ:\n\t\twhile ((end && cp < end) || (end == NULL && *cp != '\\0'))\n\t\t{\n\t\t\tif (in_escape)\n\t\t\t{\n\t\t\t\tcp++;\n\t\t\t\tin_escape = false;\n\t\t\t}\n\t\t\telse if (*cp == '\\\\')\n\t\t\t{\n\t\t\t\tcp++;\n\t\t\t\tin_escape = true;\n\t\t\t}\n\t\t\telse if (*cp == (unsigned char)stype)\n\t\t\t{\n\t\t\t\tcp++;\n\t\t\t\treturn cp;\n\t\t\t}\n\t\t\telse\n\t\t\t\tcp++;\n\t\t}\n\t\treturn NULL;\n\tdefault:\n\t\tAssertNotReached ();\n\t\treturn NULL;\n\t}\n}\n\nstatic enum stringType isInString (const unsigned char *line,\n\t\t\t\t\t\t\t\t   const unsigned char *end)\n{\n\tconst unsigned char *cp = line;\n\tenum stringType t = STRING_TYPE_NONE;\n\n\twhile (cp && cp < end)\n\t{\n\t\tswitch (*cp)\n\t\t{\n\t\tcase '\\'':\n\t\tcase '\\\"':\n\t\tcase '`':\n\t\t\tt = *cp;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tt = STRING_TYPE_NONE;\n\t\t\tbreak;\n\t\t}\n\n\t\tcp++;\n\t\tif (t != STRING_TYPE_NONE)\n\t\t\tcp = escapeFromString (cp, end, t);\n\t}\n\n\treturn (cp == NULL)? t: STRING_TYPE_NONE;\n}\n\n\nstatic const unsigned char *collectHereDocMarker (struct hereDocMarkerManager *mgr,\n\t\t\t\t\t\t\t\t\t\t\t\t  const unsigned char *line)\n{\n\tunsigned char *starter = (unsigned char*)strstr((char *)line, \"<<\");\n\tunsigned char *cp = NULL;\n\tbool indented = false;\n\tunsigned char quote_char = 0;\n\tbool space_seen = false;\n\n\tif (starter == NULL)\n\t\treturn NULL;\n\n\tenum stringType stype;\n\tif ((stype = isInString(line, starter)) != STRING_TYPE_NONE)\n\t\treturn escapeFromString (starter + 2, NULL, stype);\n\n\tcp = starter + 2;\n\twhile (isspace (*cp))\n\t{\n\t\t/* To avoid confusing with a shift operator, we track\n\t\t * spaces after the starter (<<). */\n\t\tspace_seen = true;\n\t\tcp++;\n\t}\n\n\tif (*cp == '\\0')\n\t\treturn NULL;\n\n\tif (*cp == '~') {\n\t\tif (space_seen)\n\t\t\treturn cp + 1;\n\t\tindented = true;\n\t\tcp++;\n\t\tif (*cp == '\\0')\n\t\t\treturn NULL;\n\t\twhile (isspace (*cp))\n\t\t\tcp++;\n\t\tif (*cp == '\\0')\n\t\t\treturn NULL;\n\t}\n\n\tswitch (*cp)\n\t{\n\tcase '\\'':\n\tcase '\"':\n\tcase '`':\n\t\tquote_char = *cp;\n\t\t/* Fall through */\n\tcase '\\\\':\n\t\tcp++;\n\t\tif (*cp == '\\0')\n\t\t\treturn NULL;\n\t\tbreak;\n\tdefault:\n\t\tif (!isIdentifier1(*cp))\n\t\t\treturn cp;\n\t\tif (space_seen)\n\t\t\treturn cp;\n\t\tbreak;\n\t}\n\n\tstruct hereDocMarker *marker = hereDocMarkerNew (indented);\n\tconst unsigned char *last_cp = cp;\n\tcp = readHereDocMarker(cp, marker->marker, quote_char);\n\tif (vStringLength (marker->marker) > 0)\n\t{\n\t\tmarker->corkIndex = makeSimpleTag (marker->marker,\n\t\t\t\t\t\t\t\t\t\t   KIND_PERL_HEREDOCMARKER);\n\t\tptrArrayAdd (mgr->markers, marker);\n\t}\n\telse\n\t\thereDocMarkerDelete (marker);\n\n\tif (*cp != '\\0' && cp != last_cp)\n\t\treturn cp;\n\treturn NULL;\n}\n\nstatic void collectHereDocMarkers (struct hereDocMarkerManager *mgr,\n\t\t\t\t\t\t\t\t   const unsigned char *line)\n{\n\tconst unsigned char *cp = line;\n#ifdef DEBUG\n\tconst unsigned char *last = cp;\n#endif\n\twhile ((cp = collectHereDocMarker(mgr, cp)) != NULL)\n\t\tAssert(last < cp);\n}\n\nstatic bool isInHereDoc (struct hereDocMarkerManager *mgr,\n\t\t\t\t\t\t const unsigned char *line)\n{\n\tif (ptrArrayCount (mgr->markers) == 0)\n\t\treturn false;\n\n\tconst unsigned char *cp = line;\n\tstruct hereDocMarker *current = ptrArrayItem (mgr->markers, mgr->current);\n\tif (current->indented)\n\t{\n\t\twhile (isspace(*cp))\n\t\t\tcp++;\n\t}\n\tif (strncmp((const char *)cp, vStringValue (current->marker), vStringLength (current->marker)) == 0\n\t\t&& (cp [vStringLength (current->marker)] == '\\0'\n\t\t\t|| (!isIdentifier (cp [vStringLength (current->marker)]))))\n\t{\n\t\tsetTagEndLineToCorkEntry (current->corkIndex, getInputLineNumber());\n\n\t\tmakeSimpleRefTag (current->marker, KIND_PERL_HEREDOCMARKER, R_HEREDOC_ENDLABEL);\n\n\t\tmgr->current++;\n\t\tif (mgr->current == ptrArrayCount (mgr->markers))\n\t\t{\n\t\t\tptrArrayClear (mgr->markers);\n\t\t\tmgr->current = 0;\n\t\t}\n\t}\n\treturn true;\n}\n\nstatic void initHereDocMarkerManager(struct hereDocMarkerManager *mgr)\n{\n\tmgr->markers = ptrArrayNew((ptrArrayDeleteFunc)hereDocMarkerDelete);\n\tmgr->current = 0;\n}\n\nstatic void finiHereDocMarkerManager(struct hereDocMarkerManager *mgr)\n{\n\tptrArrayDelete (mgr->markers);\n\tmgr->markers = NULL;\n\tmgr->current = 0;\n}\n\n/* Algorithm adapted from from GNU etags.\n * Perl support by Bart Robinson <lomew@cs.utah.edu>\n * Perl sub names: look for /^ [ \\t\\n]sub [ \\t\\n]+ [^ \\t\\n{ (]+/\n */\nstatic void findPerlTags (void)\n{\n\tvString *name = vStringNew ();\n\tvString *package = NULL;\n\tbool skipPodDoc = false;\n\tconst unsigned char *line;\n\tunsigned long podStart = 0UL;\n\n\t/* A pod area can be after __END__ marker.\n\t * Perl parser itself doesn't need to parse the area\n\t * after the marker. Parsing the area is needed only\n\t * if Perl parser runs Pod parser as a guest.\n\t * This variable is set true when it is needed.\n\t */\n\tbool parse_only_pod_area = false;\n\n\t/* Core modules AutoLoader and SelfLoader support delayed compilation\n\t * by allowing Perl code that follows __END__ and __DATA__ tokens,\n\t * respectively.  When we detect that one of these modules is used\n\t * in the file, we continue processing even after we see the\n\t * corresponding token that would usually terminate parsing of the\n\t * file.\n\t */\n\tenum {\n\t\tRESPECT_END\t\t= (1 << 0),\n\t\tRESPECT_DATA\t= (1 << 1),\n\t} respect_token = RESPECT_END | RESPECT_DATA;\n\n\tstruct hereDocMarkerManager hdoc_mgr;\n\tinitHereDocMarkerManager (&hdoc_mgr);\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tbool spaceRequired = false;\n\t\tbool qualified = false;\n\t\tconst unsigned char *cp = line;\n\t\tperlKind kind = KIND_PERL_NONE;\n\t\ttagEntryInfo e;\n\n\t\tif (isInHereDoc (&hdoc_mgr, line))\n\t\t\tcontinue;\n\n\t\tif (skipPodDoc)\n\t\t{\n\t\t\tif (strncmp ((const char*) line, \"=cut\", (size_t) 4) == 0)\n\t\t\t{\n\t\t\t\tskipPodDoc = false;\n\t\t\t\tif (podStart != 0UL)\n\t\t\t\t{\n\t\t\t\t\tnotifyLeavingPod ();\n\t\t\t\t\tmakePromise (\"Pod\",\n\t\t\t\t\t\t     podStart, 0,\n\t\t\t\t\t\t     getInputLineNumber(), 0,\n\t\t\t\t\t\t     getSourceLineNumber());\n\t\t\t\t\tpodStart = 0UL;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\telse if (line [0] == '=')\n\t\t{\n\t\t\tskipPodDoc = isPodWord ((const char*)line + 1);\n\t\t\tif (skipPodDoc)\n\t\t\t{\n\t\t\t\tpodStart = getSourceLineNumber ();\n\t\t\t\tnotifyEnteringPod ();\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\telse if (strcmp ((const char*) line, \"__DATA__\") == 0)\n\t\t{\n\t\t\tif (respect_token & RESPECT_DATA)\n\t\t\t{\n\t\t\t\tif (isXtagEnabled (XTAG_GUEST))\n\t\t\t\t\tparse_only_pod_area = true;\n\t\t\t\telse\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t\tcontinue;\n\t\t}\n\t\telse if (strcmp ((const char*) line, \"__END__\") == 0)\n\t\t{\n\t\t\tif (respect_token & RESPECT_END)\n\t\t\t{\n\t\t\t\tif (isXtagEnabled (XTAG_GUEST))\n\t\t\t\t\tparse_only_pod_area = true;\n\t\t\t\telse\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t\tcontinue;\n\t\t}\n\t\telse if (line [0] == '#')\n\t\t\tcontinue;\n\n\t\tif (parse_only_pod_area)\n\t\t\tcontinue;\n\n\t\twhile (isspace (*cp) || *cp == '{' || *cp == '}')\n\t\t\tcp++;\n\n\t\tif (strncmp((const char*) cp, \"sub\", (size_t) 3) == 0)\n\t\t{\n\t\t\tTRACE_PRINT(\"this looks like a sub\");\n\t\t\tcp += 3;\n\t\t\tkind = KIND_PERL_SUBROUTINE;\n\t\t\tspaceRequired = true;\n\t\t\tqualified = true;\n\t\t}\n\t\telse if (strncmp((const char*) cp, \"use\", (size_t) 3) == 0)\n\t\t{\n\t\t\tcp += 3;\n\t\t\tif (!isspace(*cp))\n\t\t\t\tcontinue;\n\t\t\twhile (*cp && isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tif (strncmp((const char*) cp, \"AutoLoader\", (size_t) 10) == 0) {\n\t\t\t\trespect_token &= ~RESPECT_END;\n\t\t\t\tmakeTagForModule(\"AutoLoader\", ROLE_PERL_MODULE_USED);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (strncmp((const char*) cp, \"SelfLoader\", (size_t) 10) == 0) {\n\t\t\t\trespect_token &= ~RESPECT_DATA;\n\t\t\t\tmakeTagForModule(\"SelfLoader\", ROLE_PERL_MODULE_USED);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tvString *module = NULL;\n\t\t\twhile (isalnum(*cp) || *cp == ':' || *cp == '.' || *cp == '_') {\n\t\t\t\tif (!module)\n\t\t\t\t\tmodule = vStringNew();\n\t\t\t\tvStringPut(module, *cp);\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\tif (!module)\n\t\t\t\tcontinue;\n\n\t\t\tint q = makeTagForModule(vStringValue(module), ROLE_PERL_MODULE_USED);\n\t\t\tbool isConstant = (strcmp(vStringValue(module), \"constant\") == 0);\n\t\t\tvStringDelete(module);\n\t\t\tif (!isConstant)\n\t\t\t{\n\t\t\t\twhile (isspace(*cp))\n\t\t\t\t\tcp++;\n\t\t\t\tif (strncmp(\"qw\", (const char *)cp, 2) != 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tcp += 2;\n\t\t\t\twhile (isspace(*cp))\n\t\t\t\t\tcp++;\n\t\t\t\tif (*cp == '\\0')\n\t\t\t\t\tcontinue;\n\t\t\t\tvStringClear (name);\n\n\t\t\t\tparseQuotedWords(cp, name, q);\n\t\t\t\tvStringClear (name);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* Skip up to the first non-space character, skipping empty\n\t\t\t * and comment lines.\n\t\t\t */\n\t\t\twhile (isspace(*cp))\n\t\t\t\tcp++;\n\t\t\twhile (!*cp || '#' == *cp) {\n\t\t\t\tcp = readLineFromInputFile ();\n\t\t\t\tif (!cp)\n\t\t\t\t\tgoto END_MAIN_WHILE;\n\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\tcp++;\n\t\t\t}\n\t\t\tif ('{' == *cp) {\n\t\t\t\t++cp;\n\t\t\t\tif (0 == parseConstantsFromHashRef(cp, name, package)) {\n\t\t\t\t\tvStringClear(name);\n\t\t\t\t\tcontinue;\n\t\t\t\t} else\n\t\t\t\t\tgoto END_MAIN_WHILE;\n\t\t\t}\n\t\t\tkind = KIND_PERL_CONSTANT;\n\t\t\tspaceRequired = false;\n\t\t\tqualified = true;\n\t\t}\n\t\telse if (strncmp((const char*) cp, \"no\", (size_t) 2) == 0 && isspace(cp[2]))\n\t\t{\n\t\t\tcp += 3;\n\t\t\twhile (isspace (*cp))\n\t\t\t\tcp++;\n\t\t\tvString *module = NULL;\n\t\t\twhile (isalnum(*cp) || *cp == ':' || *cp == '.' || *cp == '_') {\n\t\t\t\tif (!module)\n\t\t\t\t\tmodule = vStringNew();\n\t\t\t\tvStringPut(module, *cp);\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\tif (module) {\n\t\t\t\tmakeTagForModule(vStringValue(module), ROLE_PERL_MODULE_UNUSED);\n\t\t\t\tvStringDelete(module);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\telse if (strncmp((const char*) cp, \"package\", (size_t) 7) == 0 &&\n\t\t\t\t ('\\0' == cp[7] || isspace(cp[7])))\n\t\t{\n\t\t\tcp += 7;\n\t\t\twhile (isspace (*cp))\n\t\t\t\tcp++;\n\t\t\twhile (!*cp || '#' == *cp) {\n\t\t\t\tcp = readLineFromInputFile ();\n\t\t\t\tif (!cp)\n\t\t\t\t\tgoto END_MAIN_WHILE;\n\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\tcp++;\n\t\t\t}\n\t\t\tif (package == NULL)\n\t\t\t\tpackage = vStringNew ();\n\t\t\telse\n\t\t\t\tvStringClear (package);\n\t\t\tconst unsigned char *const first = cp;\n\t\t\twhile (*cp && (int) *cp != ';'  &&  !isspace (*cp))\n\t\t\t{\n\t\t\t\tvStringPut (package, *cp);\n\t\t\t\tcp++;\n\t\t\t}\n\t\t\tvStringCatS (package, \"::\");\n\n\t\t\tcp = first;\t /* Rewind */\n\t\t\tkind = KIND_PERL_PACKAGE;\n\t\t\tspaceRequired = false;\n\t\t\tqualified = true;\n\t\t}\n\t\telse if (strncmp((const char*) cp, \"format\", (size_t) 6) == 0)\n\t\t{\n\t\t\tcp += 6;\n\t\t\tkind = KIND_PERL_FORMAT;\n\t\t\tspaceRequired = true;\n\t\t\tqualified = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (isIdentifier1 (*cp))\n\t\t\t{\n\t\t\t\tconst unsigned char *p = cp;\n\t\t\t\twhile (isIdentifier (*p))\n\t\t\t\t\t++p;\n\t\t\t\twhile (isspace (*p))\n\t\t\t\t\t++p;\n\t\t\t\tif ((int) *p == ':' && (int) *(p + 1) != ':')\n\t\t\t\t\tkind = KIND_PERL_LABEL;\n\t\t\t}\n\t\t\tif (kind != KIND_PERL_LABEL)\n\t\t\t\tcollectHereDocMarkers (&hdoc_mgr, cp);\n\t\t}\n\t\tif (kind != KIND_PERL_NONE)\n\t\t{\n\t\t\tTRACE_PRINT(\"cp0: %s\", (const char *) cp);\n\t\t\tif (spaceRequired && *cp && !isspace (*cp))\n\t\t\t\tcontinue;\n\n\t\t\tTRACE_PRINT(\"cp1: %s\", (const char *) cp);\n\t\t\twhile (isspace (*cp))\n\t\t\t\tcp++;\n\n\t\t\twhile (!*cp || '#' == *cp) { /* Gobble up empty lines\n\t\t\t\t                            and comments */\n\t\t\t\tcp = readLineFromInputFile ();\n\t\t\t\tif (!cp)\n\t\t\t\t\tgoto END_MAIN_WHILE;\n\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\tcp++;\n\t\t\t}\n\n\t\t\twhile (isIdentifier (*cp) || (KIND_PERL_PACKAGE == kind && ':' == *cp))\n\t\t\t{\n\t\t\t\tvStringPut (name, *cp);\n\t\t\t\tcp++;\n\t\t\t}\n\n\t\t\tif (KIND_PERL_FORMAT == kind &&\n\t\t\t\tvStringLength (name) == 0 && /* cp did not advance */\n\t\t\t\t'=' == *cp)\n\t\t\t{\n\t\t\t\t/* format's name is optional.  If it's omitted, 'STDOUT'\n\t\t\t\t   is assumed. */\n\t\t\t\tvStringCatS (name, \"STDOUT\");\n\t\t\t}\n\n\t\t\tTRACE_PRINT(\"name: %s\", vStringValue (name));\n\n\t\t\tif (0 == vStringLength(name)) {\n\t\t\t\tvStringClear(name);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (KIND_PERL_SUBROUTINE == kind)\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * isSubroutineDeclaration() may consume several lines.  So\n\t\t\t\t * we record line positions.\n\t\t\t\t */\n\t\t\t\tinitTagEntry(&e, vStringValue(name), KIND_GHOST_INDEX);\n\n\t\t\t\tif (true == isSubroutineDeclaration(cp)) {\n\t\t\t\t\tif (true == PerlKinds[KIND_PERL_SUBROUTINE_DECLARATION].enabled) {\n\t\t\t\t\t\tkind = KIND_PERL_SUBROUTINE_DECLARATION;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvStringClear (name);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t} else if (! PerlKinds[kind].enabled) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\te.kindIndex = kind;\n\n\t\t\t\tmakeTagEntry(&e);\n\n\t\t\t\tif (isXtagEnabled (XTAG_QUALIFIED_TAGS) && qualified &&\n\t\t\t\t\tpackage != NULL  && vStringLength (package) > 0)\n\t\t\t\t{\n\t\t\t\t\tvString *const qualifiedName = vStringNew ();\n\t\t\t\t\tvStringCopy (qualifiedName, package);\n\t\t\t\t\tvStringCat (qualifiedName, name);\n\t\t\t\t\te.name = vStringValue(qualifiedName);\n\t\t\t\t\tmarkTagExtraBit (&e, XTAG_QUALIFIED_TAGS);\n\t\t\t\t\tmakeTagEntry(&e);\n\t\t\t\t\tvStringDelete (qualifiedName);\n\t\t\t\t}\n\t\t\t} else if (vStringLength (name) > 0)\n\t\t\t{\n\t\t\t\tmakeSimpleTag (name, kind);\n\t\t\t\tif (isXtagEnabled(XTAG_QUALIFIED_TAGS) && qualified &&\n\t\t\t\t\tKIND_PERL_PACKAGE != kind &&\n\t\t\t\t\tpackage != NULL  && vStringLength (package) > 0)\n\t\t\t\t{\n\t\t\t\t\ttagEntryInfo fqe;\n\t\t\t\t\tvString *const qualifiedName = vStringNew ();\n\t\t\t\t\tvStringCopy (qualifiedName, package);\n\t\t\t\t\tvStringCat (qualifiedName, name);\n\t\t\t\t\tinitTagEntry (&fqe, vStringValue (qualifiedName), kind);\n\t\t\t\t\tmarkTagExtraBit (&fqe, XTAG_QUALIFIED_TAGS);\n\t\t\t\t\tmakeTagEntry (&fqe);\n\t\t\t\t\tvStringDelete (qualifiedName);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvStringClear (name);\n\t\t}\n\t}\n\nEND_MAIN_WHILE:\n\tvStringDelete (name);\n\tfiniHereDocMarkerManager (&hdoc_mgr);\n\tif (package != NULL)\n\t\tvStringDelete (package);\n}\n\nextern parserDefinition* PerlParser (void)\n{\n\tstatic const char *const extensions [] = { \"pl\", \"pm\", \"ph\", \"plx\", \"perl\", NULL };\n\tstatic const char *const aliases [] = {\n\t\t/* cperl is an Emacs' editing mode for Perl source code  */\n\t\t\"cperl\",\n\t\tNULL };\n\tstatic selectLanguage selectors [] = {\n\t\tselectPerlOrPrologByDistinctiveToken,\n\t\tselectByPickingPerlVersion,\n\t\tNULL };\n\tparserDefinition* def = parserNew (\"Perl\");\n\tdef->kindTable      = PerlKinds;\n\tdef->kindCount  = ARRAY_SIZE (PerlKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findPerlTags;\n\tdef->selectLanguage = selectors;\n\tdef->aliases    = aliases;\n\n\t/* Subparsers need this */\n\tdef->useCork = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/php.c",
    "content": "/*\n*   Copyright (c) 2013, Colomban Wendling <ban@herbesfolles.org>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains code for generating tags for the PHP scripting\n*   language.\n*\n*   The language reference: http://php.net/manual/en/langref.php\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"keyword.h\"\n#include \"entry.h\"\n#include \"routines.h\"\n#include \"debug.h\"\n#include \"objpool.h\"\n#include \"promise.h\"\n#include \"trace.h\"\n\n#define isIdentChar(c) (isalnum (c) || (c) == '_' || (c) >= 0x80)\n#define newToken() (objPoolGet (TokenPool))\n#define deleteToken(t) (objPoolPut (TokenPool, (t)))\n\nenum {\n\tKEYWORD_abstract,\n\tKEYWORD_and,\n\tKEYWORD_as,\n\tKEYWORD_break,\n\tKEYWORD_callable,\n\tKEYWORD_case,\n\tKEYWORD_catch,\n\tKEYWORD_class,\n\tKEYWORD_clone,\n\tKEYWORD_const,\n\tKEYWORD_continue,\n\tKEYWORD_declare,\n\tKEYWORD_define,\n\tKEYWORD_default,\n\tKEYWORD_do,\n\tKEYWORD_echo,\n\tKEYWORD_else,\n\tKEYWORD_elif,\n\tKEYWORD_enddeclare,\n\tKEYWORD_endfor,\n\tKEYWORD_endforeach,\n\tKEYWORD_endif,\n\tKEYWORD_endswitch,\n\tKEYWORD_endwhile,\n\tKEYWORD_extends,\n\tKEYWORD_final,\n\tKEYWORD_finally,\n\tKEYWORD_for,\n\tKEYWORD_foreach,\n\tKEYWORD_function,\n\tKEYWORD_global,\n\tKEYWORD_goto,\n\tKEYWORD_if,\n\tKEYWORD_implements,\n\tKEYWORD_include,\n\tKEYWORD_include_once,\n\tKEYWORD_instanceof,\n\tKEYWORD_insteadof,\n\tKEYWORD_interface,\n\tKEYWORD_namespace,\n\tKEYWORD_new,\n\tKEYWORD_or,\n\tKEYWORD_print,\n\tKEYWORD_private,\n\tKEYWORD_protected,\n\tKEYWORD_public,\n\tKEYWORD_require,\n\tKEYWORD_require_once,\n\tKEYWORD_return,\n\tKEYWORD_static,\n\tKEYWORD_switch,\n\tKEYWORD_throw,\n\tKEYWORD_trait,\n\tKEYWORD_try,\n\tKEYWORD_use,\n\tKEYWORD_var,\n\tKEYWORD_while,\n\tKEYWORD_xor,\n\tKEYWORD_yield\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum {\n\tACCESS_UNDEFINED,\n\tACCESS_PRIVATE,\n\tACCESS_PROTECTED,\n\tACCESS_PUBLIC,\n\tCOUNT_ACCESS\n} accessType;\n\ntypedef enum {\n\tIMPL_UNDEFINED,\n\tIMPL_ABSTRACT,\n\tCOUNT_IMPL\n} implType;\n\ntypedef enum {\n\tK_CLASS,\n\tK_DEFINE,\n\tK_FUNCTION,\n\tK_INTERFACE,\n\tK_LOCAL_VARIABLE,\n\tK_NAMESPACE,\n\tK_TRAIT,\n\tK_VARIABLE,\n\tK_ALIAS,\n\tCOUNT_KIND\n} phpKind;\n\n#define NAMESPACE_SEPARATOR \"\\\\\"\nstatic scopeSeparator PhpGenericSeparators [] = {\n\t{ K_NAMESPACE        , NAMESPACE_SEPARATOR },\n\t{ KIND_WILDCARD_INDEX, \"::\" },\n};\n\nstatic kindDefinition PhpKinds[COUNT_KIND] = {\n\t{ true, 'c', \"class\",\t\t\"classes\",\n\t  ATTACH_SEPARATORS(PhpGenericSeparators) },\n\t{ true, 'd', \"define\",\t\t\"constant definitions\",\n\t  ATTACH_SEPARATORS(PhpGenericSeparators)},\n\t{ true, 'f', \"function\",\t\"functions\",\n\t  ATTACH_SEPARATORS(PhpGenericSeparators)},\n\t{ true, 'i', \"interface\",\t\"interfaces\",\n\t  ATTACH_SEPARATORS(PhpGenericSeparators)},\n\t{ false, 'l', \"local\",\t\t\"local variables\",\n\t  ATTACH_SEPARATORS(PhpGenericSeparators)},\n\t{ true, 'n', \"namespace\",\t\"namespaces\",\n\t  ATTACH_SEPARATORS(PhpGenericSeparators)},\n\t{ true, 't', \"trait\",\t\t\"traits\",\n\t  ATTACH_SEPARATORS(PhpGenericSeparators)},\n\t{ true, 'v', \"variable\",\t\"variables\",\n\t  ATTACH_SEPARATORS(PhpGenericSeparators)},\n\t{ true, 'a', \"alias\",\t\t\"aliases\",\n\t  ATTACH_SEPARATORS(PhpGenericSeparators)},\n};\n\nstatic const keywordTable PhpKeywordTable[] = {\n\t/* keyword\t\t\tkeyword ID */\n\t{ \"abstract\",\t\tKEYWORD_abstract\t\t},\n\t{ \"and\",\t\t\tKEYWORD_and\t\t\t\t},\n\t{ \"as\",\t\t\t\tKEYWORD_as\t\t\t\t},\n\t{ \"break\",\t\t\tKEYWORD_break\t\t\t},\n\t{ \"callable\",\t\tKEYWORD_callable\t\t},\n\t{ \"case\",\t\t\tKEYWORD_case\t\t\t},\n\t{ \"catch\",\t\t\tKEYWORD_catch\t\t\t},\n\t{ \"cfunction\",\t\tKEYWORD_function\t\t}, /* nobody knows what the hell this is, but it seems to behave much like \"function\" so bind it to it */\n\t{ \"class\",\t\t\tKEYWORD_class\t\t\t},\n\t{ \"clone\",\t\t\tKEYWORD_clone\t\t\t},\n\t{ \"const\",\t\t\tKEYWORD_const\t\t\t},\n\t{ \"continue\",\t\tKEYWORD_continue\t\t},\n\t{ \"declare\",\t\tKEYWORD_declare\t\t\t},\n\t{ \"define\",\t\t\tKEYWORD_define\t\t\t}, /* this isn't really a keyword but we handle it so it's easier this way */\n\t{ \"default\",\t\tKEYWORD_default\t\t\t},\n\t{ \"do\",\t\t\t\tKEYWORD_do\t\t\t\t},\n\t{ \"echo\",\t\t\tKEYWORD_echo\t\t\t},\n\t{ \"else\",\t\t\tKEYWORD_else\t\t\t},\n\t{ \"elseif\",\t\t\tKEYWORD_elif\t\t\t},\n\t{ \"enddeclare\",\t\tKEYWORD_enddeclare\t\t},\n\t{ \"endfor\",\t\t\tKEYWORD_endfor\t\t\t},\n\t{ \"endforeach\",\t\tKEYWORD_endforeach\t\t},\n\t{ \"endif\",\t\t\tKEYWORD_endif\t\t\t},\n\t{ \"endswitch\",\t\tKEYWORD_endswitch\t\t},\n\t{ \"endwhile\",\t\tKEYWORD_endwhile\t\t},\n\t{ \"extends\",\t\tKEYWORD_extends\t\t\t},\n\t{ \"final\",\t\t\tKEYWORD_final\t\t\t},\n\t{ \"finally\",\t\tKEYWORD_finally\t\t\t},\n\t{ \"for\",\t\t\tKEYWORD_for\t\t\t\t},\n\t{ \"foreach\",\t\tKEYWORD_foreach\t\t\t},\n\t{ \"function\",\t\tKEYWORD_function\t\t},\n\t{ \"global\",\t\t\tKEYWORD_global\t\t\t},\n\t{ \"goto\",\t\t\tKEYWORD_goto\t\t\t},\n\t{ \"if\",\t\t\t\tKEYWORD_if\t\t\t\t},\n\t{ \"implements\",\t\tKEYWORD_implements\t\t},\n\t{ \"include\",\t\tKEYWORD_include\t\t\t},\n\t{ \"include_once\",\tKEYWORD_include_once\t},\n\t{ \"instanceof\",\t\tKEYWORD_instanceof\t\t},\n\t{ \"insteadof\",\t\tKEYWORD_insteadof\t\t},\n\t{ \"interface\",\t\tKEYWORD_interface\t\t},\n\t{ \"namespace\",\t\tKEYWORD_namespace\t\t},\n\t{ \"new\",\t\t\tKEYWORD_new\t\t\t\t},\n\t{ \"or\",\t\t\t\tKEYWORD_or\t\t\t\t},\n\t{ \"print\",\t\t\tKEYWORD_print\t\t\t},\n\t{ \"private\",\t\tKEYWORD_private\t\t\t},\n\t{ \"protected\",\t\tKEYWORD_protected\t\t},\n\t{ \"public\",\t\t\tKEYWORD_public\t\t\t},\n\t{ \"require\",\t\tKEYWORD_require\t\t\t},\n\t{ \"require_once\",\tKEYWORD_require_once\t},\n\t{ \"return\",\t\t\tKEYWORD_return\t\t\t},\n\t{ \"static\",\t\t\tKEYWORD_static\t\t\t},\n\t{ \"switch\",\t\t\tKEYWORD_switch\t\t\t},\n\t{ \"throw\",\t\t\tKEYWORD_throw\t\t\t},\n\t{ \"trait\",\t\t\tKEYWORD_trait\t\t\t},\n\t{ \"try\",\t\t\tKEYWORD_try\t\t\t\t},\n\t{ \"use\",\t\t\tKEYWORD_use\t\t\t\t},\n\t{ \"var\",\t\t\tKEYWORD_var\t\t\t\t},\n\t{ \"while\",\t\t\tKEYWORD_while\t\t\t},\n\t{ \"xor\",\t\t\tKEYWORD_xor\t\t\t\t},\n\t{ \"yield\",\t\t\tKEYWORD_yield\t\t\t}\n};\n\n\ntypedef enum eTokenType {\n\tTOKEN_UNDEFINED,\n\tTOKEN_EOF,\n\tTOKEN_CHARACTER,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_SEMICOLON,\n\tTOKEN_COLON,\n\tTOKEN_COMMA,\n\tTOKEN_KEYWORD,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_OPERATOR,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n\tTOKEN_PERIOD,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_EQUAL_SIGN,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_VARIABLE,\n\tTOKEN_AMPERSAND,\n\tTOKEN_BACKSLASH,\n\tTOKEN_QMARK,\n} tokenType;\n\n#ifdef DEBUG\nstatic const char *tokenTypes[] = {\n#define E(X) [TOKEN_##X] = #X\n\tE(UNDEFINED),\n\tE(EOF),\n\tE(CHARACTER),\n\tE(CLOSE_PAREN),\n\tE(SEMICOLON),\n\tE(COLON),\n\tE(COMMA),\n\tE(KEYWORD),\n\tE(OPEN_PAREN),\n\tE(OPERATOR),\n\tE(IDENTIFIER),\n\tE(STRING),\n\tE(PERIOD),\n\tE(OPEN_CURLY),\n\tE(CLOSE_CURLY),\n\tE(EQUAL_SIGN),\n\tE(OPEN_SQUARE),\n\tE(CLOSE_SQUARE),\n\tE(VARIABLE),\n\tE(AMPERSAND),\n\tE(BACKSLASH),\n\tE(QMARK),\n#undef E\n};\n#endif\n\ntypedef struct {\n\ttokenType\t\ttype;\n\tkeywordId\t\tkeyword;\n\tvString *\t\tstring;\n\tvString *\t\tscope;\n\tunsigned long \tlineNumber;\n\tMIOPos\t\t\tfilePosition;\n\tint \t\t\tparentKind; /* -1 if none */\n\tbool\t\t\tanonymous;\t/* true if token specifies\n\t\t\t\t\t\t\t\t * an anonymous class */\n} tokenInfo;\n\nstatic langType Lang_php;\nstatic langType Lang_zephir;\n\nstatic bool InPhp = false; /* whether we are between <? ?> */\n/* whether the next token may be a keyword, e.g. not after \"::\" or \"->\" */\nstatic bool MayBeKeyword = true;\n\n/* current statement details */\nstatic struct {\n\taccessType access;\n\timplType impl;\n} CurrentStatement;\n\n/* Current namespace */\nstatic vString *CurrentNamesapce;\n/* Cache variable to build the tag's scope.  It has no real meaning outside\n * of initPhpEntry()'s scope. */\nstatic vString *FullScope;\n/* The class name specified at \"extends\" keyword in the current class\n * definition. Used to resolve \"parent\" in return type. */\nstatic vString *ParentClass;\n\nstatic objPool *TokenPool = NULL;\n\nstatic const char *phpScopeSeparatorFor (int kind, int upperScopeKind)\n{\n\treturn scopeSeparatorFor (getInputLanguage(), kind, upperScopeKind);\n}\n\nstatic const char *accessToString (const accessType access)\n{\n\tstatic const char *const names[COUNT_ACCESS] = {\n\t\t\"undefined\",\n\t\t\"private\",\n\t\t\"protected\",\n\t\t\"public\"\n\t};\n\n\tAssert (access < COUNT_ACCESS);\n\n\treturn names[access];\n}\n\nstatic const char *implToString (const implType impl)\n{\n\tstatic const char *const names[COUNT_IMPL] = {\n\t\t\"undefined\",\n\t\t\"abstract\"\n\t};\n\n\tAssert (impl < COUNT_IMPL);\n\n\treturn names[impl];\n}\n\nstatic void initPhpEntry (tagEntryInfo *const e, const tokenInfo *const token,\n\t\t\t\t\t\t  const phpKind kind, const accessType access)\n{\n\tint parentKind = -1;\n\n\tvStringClear (FullScope);\n\n\tif (vStringLength (CurrentNamesapce) > 0)\n\t{\n\t\tparentKind = K_NAMESPACE;\n\t\tvStringCat (FullScope, CurrentNamesapce);\n\n\t}\n\n\tinitTagEntry (e, vStringValue (token->string), kind);\n\n\tupdateTagLine (e, token->lineNumber, token->filePosition);\n\n\tif (access != ACCESS_UNDEFINED)\n\t\te->extensionFields.access = accessToString (access);\n\tif (vStringLength (token->scope) > 0)\n\t{\n\t\tparentKind = token->parentKind;\n\n\t\tif (vStringLength (FullScope) > 0)\n\t\t{\n\t\t\tconst char* sep;\n\n\t\t\tsep = phpScopeSeparatorFor (parentKind,\n\t\t\t\t\t\t    K_NAMESPACE);\n\t\t\tvStringCatS (FullScope, sep);\n\t\t}\n\t\t\tvStringCat (FullScope, token->scope);\n\t}\n\tif (vStringLength (FullScope) > 0)\n\t{\n\t\tAssert (parentKind >= 0);\n\n\t\te->extensionFields.scopeKindIndex = parentKind;\n\t\te->extensionFields.scopeName = vStringValue (FullScope);\n\t}\n\n\tif (token->anonymous)\n\t\tmarkTagExtraBit (e, XTAG_ANONYMOUS);\n}\n\nstatic void makePhpTagEntry (tagEntryInfo *const e)\n{\n\tmakeTagEntry (e);\n\tmakeQualifiedTagEntry (e);\n}\n\nstatic void fillTypeRefField (tagEntryInfo *const e,\n\t\t\t\t\t\t\t  const vString *const rtype, const tokenInfo *const token)\n{\n\tif ((vStringLength (rtype) == 4)\n\t\t&& (strcmp (vStringValue (rtype), \"self\") == 0)\n\t\t&& vStringLength (token->scope) > 0)\n\t{\n\t\tif (token->parentKind == -1)\n\t\t\te->extensionFields.typeRef [0] = \"unknown\";\n\t\telse\n\t\t\te->extensionFields.typeRef [0] = PhpKinds [token->parentKind].name;\n\t\te->extensionFields.typeRef [1] = vStringValue (token->scope);\n\t}\n\telse if ((vStringLength (rtype) == 6)\n\t\t\t && (strcmp (vStringValue (rtype), \"parent\") == 0)\n\t\t\t && (ParentClass && vStringLength (ParentClass) > 0))\n\t{\n\t\te->extensionFields.typeRef [0] = \"class\";\n\t\te->extensionFields.typeRef [1] = vStringValue (ParentClass);\n\t}\n\telse\n\t{\n\t\te->extensionFields.typeRef [0] = \"unknown\";\n\t\te->extensionFields.typeRef [1] = vStringValue (rtype);\n\t}\n}\n\nstatic void makeTypedPhpTag (const tokenInfo *const token, const phpKind kind,\n\t\t\t\t\t\t\t const accessType access, vString* typeName)\n{\n\tif (PhpKinds[kind].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitPhpEntry (&e, token, kind, access);\n\t\tif (typeName)\n\t\t\tfillTypeRefField (&e, typeName, token);\n\t\tmakePhpTagEntry (&e);\n\t}\n}\n\nstatic void makeSimplePhpTag (const tokenInfo *const token, const phpKind kind,\n\t\t\t\t\t\t\t  const accessType access)\n{\n\tmakeTypedPhpTag (token, kind, access, NULL);\n}\n\nstatic void makeNamespacePhpTag (const tokenInfo *const token, const vString *const name)\n{\n\tif (PhpKinds[K_NAMESPACE].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry (&e, vStringValue (name), K_NAMESPACE);\n\n\t\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\n\t\tmakePhpTagEntry (&e);\n\t}\n}\n\nstatic void makeClassOrIfaceTag (const phpKind kind, const tokenInfo *const token,\n\t\t\t\t\t\t\t\t vString *const inheritance, const implType impl)\n{\n\tif (PhpKinds[kind].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitPhpEntry (&e, token, kind, ACCESS_UNDEFINED);\n\n\t\tif (impl != IMPL_UNDEFINED)\n\t\t\te.extensionFields.implementation = implToString (impl);\n\t\tif (vStringLength (inheritance) > 0)\n\t\t\te.extensionFields.inheritance = vStringValue (inheritance);\n\n\t\tmakePhpTagEntry (&e);\n\t}\n}\n\nstatic void makeFunctionTag (const tokenInfo *const token,\n\t\t\t\t\t\t\t const vString *const arglist,\n\t\t\t\t\t\t\t const vString *const rtype,\n\t\t\t\t\t\t\t const accessType access, const implType impl)\n{\n\tif (PhpKinds[K_FUNCTION].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitPhpEntry (&e, token, K_FUNCTION, access);\n\n\t\tif (impl != IMPL_UNDEFINED)\n\t\t\te.extensionFields.implementation = implToString (impl);\n\t\tif (arglist)\n\t\t\te.extensionFields.signature = vStringValue (arglist);\n\t\tif (rtype)\n\t\t\tfillTypeRefField (&e, rtype, token);\n\n\t\tmakePhpTagEntry (&e);\n\t}\n}\n\nstatic void *newPoolToken (void *createArg CTAGS_ATTR_UNUSED)\n{\n\ttokenInfo *token = xMalloc (1, tokenInfo);\n\n\ttoken->string = vStringNew ();\n\ttoken->scope  = vStringNew ();\n\treturn token;\n}\n\nstatic void clearPoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\ttoken->parentKind\t= -1;\n\ttoken->anonymous\t= false;\n\tvStringClear (token->string);\n\tvStringClear (token->scope);\n}\n\nstatic void deletePoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\tvStringDelete (token->string);\n\tvStringDelete (token->scope);\n\teFree (token);\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const src,\n\t\t\t\t\t   bool scope)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tdest->keyword = src->keyword;\n\tvStringCopy(dest->string, src->string);\n\tdest->parentKind = src->parentKind;\n\tif (scope)\n\t\tvStringCopy(dest->scope, src->scope);\n\tdest->anonymous = src->anonymous;\n}\n\n#if 0\n#include <stdio.h>\n\nstatic const char *tokenTypeName (const tokenType type)\n{\n\tswitch (type)\n\t{\n\t\tcase TOKEN_UNDEFINED:\t\treturn \"undefined\";\n\t\tcase TOKEN_EOF:\t\t\t\treturn \"EOF\";\n\t\tcase TOKEN_CHARACTER:\t\treturn \"character\";\n\t\tcase TOKEN_CLOSE_PAREN:\t\treturn \"')'\";\n\t\tcase TOKEN_SEMICOLON:\t\treturn \"';'\";\n\t\tcase TOKEN_COLON:\t\t\treturn \"':'\";\n\t\tcase TOKEN_COMMA:\t\t\treturn \"','\";\n\t\tcase TOKEN_OPEN_PAREN:\t\treturn \"'('\";\n\t\tcase TOKEN_OPERATOR:\t\treturn \"operator\";\n\t\tcase TOKEN_IDENTIFIER:\t\treturn \"identifier\";\n\t\tcase TOKEN_KEYWORD:\t\t\treturn \"keyword\";\n\t\tcase TOKEN_STRING:\t\t\treturn \"string\";\n\t\tcase TOKEN_PERIOD:\t\t\treturn \"'.'\";\n\t\tcase TOKEN_OPEN_CURLY:\t\treturn \"'{'\";\n\t\tcase TOKEN_CLOSE_CURLY:\t\treturn \"'}'\";\n\t\tcase TOKEN_EQUAL_SIGN:\t\treturn \"'='\";\n\t\tcase TOKEN_OPEN_SQUARE:\t\treturn \"'['\";\n\t\tcase TOKEN_CLOSE_SQUARE:\treturn \"']'\";\n\t\tcase TOKEN_VARIABLE:\t\treturn \"variable\";\n\t}\n\treturn NULL;\n}\n\nstatic void printToken (const tokenInfo *const token)\n{\n\tfprintf (stderr, \"%p:\\n\\ttype:\\t%s\\n\\tline:\\t%lu\\n\\tscope:\\t%s\\n\", (void *) token,\n\t\t\t tokenTypeName (token->type),\n\t\t\t token->lineNumber,\n\t\t\t vStringValue (token->scope));\n\tswitch (token->type)\n\t{\n\t\tcase TOKEN_IDENTIFIER:\n\t\tcase TOKEN_STRING:\n\t\tcase TOKEN_VARIABLE:\n\t\t\tfprintf (stderr, \"\\tcontent:\\t%s\\n\", vStringValue (token->string));\n\t\t\tbreak;\n\n\t\tcase TOKEN_KEYWORD:\n\t\t{\n\t\t\tsize_t n = ARRAY_SIZE (PhpKeywordTable);\n\t\t\tsize_t i;\n\n\t\t\tfprintf (stderr, \"\\tkeyword:\\t\");\n\t\t\tfor (i = 0; i < n; i++)\n\t\t\t{\n\t\t\t\tif (PhpKeywordTable[i].id == token->keyword)\n\t\t\t\t{\n\t\t\t\t\tfprintf (stderr, \"%s\\n\", PhpKeywordTable[i].name);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (i >= n)\n\t\t\t\tfprintf (stderr, \"(unknown)\\n\");\n\t\t}\n\n\t\tdefault: break;\n\t}\n}\n#endif\n\nstatic void addToScope (tokenInfo *const token, const vString *const extra,\n\t\t\tint kindOfUpperScope)\n{\n\tif (vStringLength (token->scope) > 0)\n\t{\n\t\tconst char* sep;\n\n\t\tsep = phpScopeSeparatorFor(token->parentKind,\n\t\t\t\t\t   kindOfUpperScope);\n\t\tvStringCatS (token->scope, sep);\n\t}\n\tvStringCat (token->scope, extra);\n}\n\nstatic int skipToCharacter (const int c)\n{\n\tint d;\n\tdo\n\t{\n\t\td = getcFromInputFile ();\n\t} while (d != EOF  &&  d != c);\n\treturn d;\n}\n\nstatic void parseString (vString *const string, const int delimiter)\n{\n\twhile (true)\n\t{\n\t\tint c = getcFromInputFile ();\n\n\t\tif (c == '\\\\' && (c = getcFromInputFile ()) != EOF)\n\t\t\tvStringPut (string, c);\n\t\telse if (c == EOF || c == delimiter)\n\t\t\tbreak;\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\n/* Strips @indent_len characters from lines in @string to get the correct\n * string value for an indented heredoc (PHP 7.3+).\n * This doesn't handle invalid values specially and might yield surprising\n * results with them, but it doesn't really matter as it's invalid anyway. */\nstatic void stripHeredocIndent (vString *const string, size_t indent_len)\n{\n\tchar *str = vStringValue (string);\n\tsize_t str_len = vStringLength (string);\n\tchar *p = str;\n\tsize_t new_len = str_len;\n\tbool at_line_start = true;\n\n\twhile (*p)\n\t{\n\t\tif (at_line_start)\n\t\t{\n\t\t\tsize_t p_len;\n\t\t\tsize_t strip_len;\n\n\t\t\tp_len = str_len - (p - str);\n\t\t\tstrip_len = p_len < indent_len ? p_len : indent_len;\n\t\t\tmemmove (p, p + strip_len, p_len - strip_len);\n\t\t\tp += strip_len;\n\t\t\tnew_len -= strip_len;\n\t\t}\n\t\t/* CRLF is already normalized as LF */\n\t\tat_line_start = (*p == '\\r' || *p == '\\n');\n\t\tp++;\n\t}\n\tvStringTruncate (string, new_len);\n}\n\n/* reads a PHP >= 7.3 HereDoc or a NowDoc (the part after the <<<).\n * \t<<<[ \\t]*(ID|'ID'|\"ID\")\n * \t...\n * \t[ \\t]*ID[^:indent-char:];?\n *\n * note that:\n *  1) starting ID must be immediately followed by a newline;\n *  2) closing ID is the same as opening one;\n *  3) closing ID must not be immediately followed by an identifier character;\n *  4) optional indentation of the closing ID is stripped from body lines,\n *     which lines must have the exact same prefix indentation.\n *\n * This is slightly relaxed from PHP < 7.3, where the closing ID had to be the\n * only thing on its line, with the only exception of a semicolon right after\n * the ID.\n *\n * Example of a single valid heredoc:\n * \t<<< FOO\n * \tsomething\n * \tsomething else\n * \tFOO_this is not an end\n * \tFOO;\n * \t# previous line was the end, but the semicolon wasn't required\n *\n * Another example using indentation and more code after the heredoc:\n * \t<<<FOO\n * \t\tsomething\n * \t\tsomething else\n * \t\tFOO . 'hello';\n * \t# the heredoc ends at FOO, and leading tabs are stripped from the body.\n * \t# \". 'hello'\" is a normal concatenation operator and the string \"hello\".\n */\nstatic void parseHeredoc (vString *const string)\n{\n\tint c;\n\tunsigned int len;\n\tchar delimiter[64]; /* arbitrary limit, but more is crazy anyway */\n\tint quote = 0;\n\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t}\n\twhile (c == ' ' || c == '\\t');\n\n\tif (c == '\\'' || c == '\"')\n\t{\n\t\tquote = c;\n\t\tc = getcFromInputFile ();\n\t}\n\tfor (len = 0; len < ARRAY_SIZE (delimiter) - 1; len++)\n\t{\n\t\tif (! isIdentChar (c))\n\t\t\tbreak;\n\t\tdelimiter[len] = (char) c;\n\t\tc = getcFromInputFile ();\n\t}\n\tdelimiter[len] = 0;\n\n\tif (len == 0) /* no delimiter, give up */\n\t\tgoto error;\n\tif (quote)\n\t{\n\t\tif (c != quote) /* no closing quote for quoted identifier, give up */\n\t\t\tgoto error;\n\t\tc = getcFromInputFile ();\n\t}\n\tif (c != '\\r' && c != '\\n') /* missing newline, give up */\n\t\tgoto error;\n\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\n\t\tvStringPut (string, c);\n\t\tif (c == '\\r' || c == '\\n')\n\t\t{\n\t\t\t/* new line, check for a delimiter right after.  No need to handle\n\t\t\t * CRLF, getcFromInputFile() normalizes it to LF already. */\n\t\t\tconst size_t prev_string_len = vStringLength (string) - 1;\n\t\t\tsize_t indent_len = 0;\n\n\t\t\tc = getcFromInputFile ();\n\t\t\twhile (c == ' ' || c == '\\t')\n\t\t\t{\n\t\t\t\tvStringPut (string, c);\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t\tindent_len++;\n\t\t\t}\n\n\t\t\tfor (len = 0; c != 0 && (c - delimiter[len]) == 0; len++)\n\t\t\t\tc = getcFromInputFile ();\n\n\t\t\tif (delimiter[len] != 0)\n\t\t\t\tungetcToInputFile (c);\n\t\t\telse if (! isIdentChar (c))\n\t\t\t{\n\t\t\t\t/* line start matched the delimiter and has a separator, we're done */\n\t\t\t\tungetcToInputFile (c);\n\n\t\t\t\t/* strip trailing newline and indent of the end delimiter */\n\t\t\t\tvStringTruncate (string, prev_string_len);\n\n\t\t\t\t/* strip indent from the value if needed */\n\t\t\t\tif (indent_len > 0)\n\t\t\t\t\tstripHeredocIndent (string, indent_len);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* if we are here it wasn't a delimiter, so put everything in the\n\t\t\t * string */\n\t\t\tvStringNCatS (string, delimiter, len);\n\t\t}\n\t}\n\twhile (c != EOF);\n\n\treturn;\n\nerror:\n\tungetcToInputFile (c);\n}\n\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isIdentChar (c));\n\tungetcToInputFile (c);\n}\n\nstatic bool isSpace (int c)\n{\n\treturn (c == '\\t' || c == ' ' || c == '\\v' ||\n\t\t\tc == '\\n' || c == '\\r' || c == '\\f');\n}\n\nstatic int skipWhitespaces (int c)\n{\n\twhile (isSpace (c))\n\t\tc = getcFromInputFile ();\n\treturn c;\n}\n\n/* <script[:white:]+language[:white:]*=[:white:]*(php|'php'|\"php\")[:white:]*>\n *\n * This is ugly, but the whole \"<script language=php>\" tag is and we can't\n * really do better without adding a lot of code only for this */\nstatic bool isOpenScriptLanguagePhp (int c)\n{\n\tint quote = 0;\n\n\t/* <script[:white:]+language[:white:]*= */\n\tif (c                                   != '<' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 's' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'c' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'r' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'i' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'p' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 't' ||\n\t\t! isSpace ((c = getcFromInputFile ()))              ||\n\t\ttolower ((c = skipWhitespaces (c))) != 'l' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'a' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'n' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'g' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'u' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'a' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'g' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'e' ||\n\t\t(c = skipWhitespaces (getcFromInputFile ())) != '=')\n\t\treturn false;\n\n\t/* (php|'php'|\"php\")> */\n\tc = skipWhitespaces (getcFromInputFile ());\n\tif (c == '\"' || c == '\\'')\n\t{\n\t\tquote = c;\n\t\tc = getcFromInputFile ();\n\t}\n\tif (tolower (c)                         != 'p' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'h' ||\n\t\ttolower ((c = getcFromInputFile ()))         != 'p' ||\n\t\t(quote != 0 && (c = getcFromInputFile ()) != quote) ||\n\t\t(c = skipWhitespaces (getcFromInputFile ())) != '>')\n\t\treturn false;\n\n\treturn true;\n}\n\nstatic int findPhpStart (int *tagStartColumn)\n{\n\tint c;\n\tdo\n\t{\n\t\tif ((c = getcFromInputFile ()) == '<')\n\t\t{\n\t\t\t*tagStartColumn = getInputColumnNumber () - 1;\n\t\t\tc = getcFromInputFile ();\n\t\t\t/* <?, <?= and <?php, but not <?xml */\n\t\t\tif (c == '?')\n\t\t\t{\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t/* echo tag */\n\t\t\t\tif (c == '=')\n\t\t\t\t{\n\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t/* don't enter PHP mode on \"<?xml\", yet still support short open tags (<?) */\n\t\t\t\telse if (tolower (c)                          != 'x' ||\n\t\t\t\t         tolower ((c = getcFromInputFile ())) != 'm' ||\n\t\t\t\t         tolower ((c = getcFromInputFile ())) != 'l')\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* <script language=\"php\"> */\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (c);\n\t\t\t\tif (isOpenScriptLanguagePhp ('<'))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\twhile (c != EOF);\n\n\treturn c;\n}\n\nstatic int skipSingleComment (void)\n{\n\tint c;\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\t/* ?> in single-line comments leaves PHP mode */\n\t\tif (c == '?')\n\t\t{\n\t\t\tint next = getcFromInputFile ();\n\t\t\tif (next == '>')\n\t\t\t\tInPhp = false;\n\t\t\telse\n\t\t\t\tungetcToInputFile (next);\n\t\t}\n\t} while (InPhp && c != EOF && c != '\\n' && c != '\\r');\n\treturn c;\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\tint c;\n\tbool nextMayBeKeyword = true;\n\n\ttoken->type\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tif (! InPhp)\n\t{\n\t\tunsigned long startSourceLineNumber = getSourceLineNumber ();\n\t\tunsigned long startLineNumber = getInputLineNumber ();\n\n\t\tint startColumnNumber = getInputColumnNumber ();\n\t\tint endColumnNumber;\n\n\t\tc = findPhpStart (&endColumnNumber);\n\t\tif (c != EOF)\n\t\t\tInPhp = true;\n\t\telse\n\t\t\tendColumnNumber = getInputColumnNumber ();\n\n\t\tunsigned long endLineNumber = getInputLineNumber ();\n\n\t\tmakePromise (\"HTML\", startLineNumber, startColumnNumber,\n\t\t\t\t\t endLineNumber, endColumnNumber, startSourceLineNumber);\n\t}\n\telse\n\t\tc = getcFromInputFile ();\n\n\tc = skipWhitespaces (c);\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tswitch (c)\n\t{\n\t\tcase EOF: token->type = TOKEN_EOF;\t\t\t\t\tbreak;\n\t\tcase '(': token->type = TOKEN_OPEN_PAREN;\t\t\tbreak;\n\t\tcase ')': token->type = TOKEN_CLOSE_PAREN;\t\t\tbreak;\n\t\tcase ';': token->type = TOKEN_SEMICOLON;\t\t\tbreak;\n\t\tcase ',': token->type = TOKEN_COMMA;\t\t\t\tbreak;\n\t\tcase '.': token->type = TOKEN_PERIOD;\t\t\t\tbreak;\n\t\tcase '{': token->type = TOKEN_OPEN_CURLY;\t\t\tbreak;\n\t\tcase '}': token->type = TOKEN_CLOSE_CURLY;\t\t\tbreak;\n\t\tcase '[': token->type = TOKEN_OPEN_SQUARE;\t\t\tbreak;\n\t\tcase ']': token->type = TOKEN_CLOSE_SQUARE;\t\t\tbreak;\n\t\tcase '&': token->type = TOKEN_AMPERSAND;\t\t\tbreak;\n\t\tcase '\\\\': token->type = TOKEN_BACKSLASH;\t\t\tbreak;\n\n\t\tcase ':':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == c) /* :: */\n\t\t\t{\n\t\t\t\tnextMayBeKeyword = false;\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_COLON;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '=':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '=' || d == '>')\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_EQUAL_SIGN;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '\\'':\n\t\tcase '\"':\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tparseString (token->string, c);\n\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\tbreak;\n\n\t\tcase '<':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '/')\n\t\t\t{\n\t\t\t\t/* </script[:white:]*> */\n\t\t\t\tif (tolower ((d = getcFromInputFile ())) == 's' &&\n\t\t\t\t\ttolower ((d = getcFromInputFile ())) == 'c' &&\n\t\t\t\t\ttolower ((d = getcFromInputFile ())) == 'r' &&\n\t\t\t\t\ttolower ((d = getcFromInputFile ())) == 'i' &&\n\t\t\t\t\ttolower ((d = getcFromInputFile ())) == 'p' &&\n\t\t\t\t\ttolower ((d = getcFromInputFile ())) == 't' &&\n\t\t\t\t\t(d = skipWhitespaces (getcFromInputFile ())) == '>')\n\t\t\t\t{\n\t\t\t\t\tInPhp = false;\n\t\t\t\t\tgoto getNextChar;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (d == '<' && (d = getcFromInputFile ()) == '<')\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_STRING;\n\t\t\t\tparseHeredoc (token->string);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '#': /* comment */\n\t\t\tskipSingleComment ();\n\t\t\tgoto getNextChar;\n\t\t\tbreak;\n\n\t\tcase '+':\n\t\tcase '-':\n\t\tcase '*':\n\t\tcase '%':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (c == '-' && d == '>')\n\t\t\t\tnextMayBeKeyword = false;\n\t\t\telse if (d != '=')\n\t\t\t\tungetcToInputFile (d);\n\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '/': /* division or comment start */\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '/') /* single-line comment */\n\t\t\t{\n\t\t\t\tskipSingleComment ();\n\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\telse if (d == '*')\n\t\t\t{\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tc = skipToCharacter ('*');\n\t\t\t\t\tif (c != EOF)\n\t\t\t\t\t{\n\t\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t\t\tif (c == '/')\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tungetcToInputFile (c);\n\t\t\t\t\t}\n\t\t\t\t} while (c != EOF && c != '\\0');\n\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (d != '=')\n\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '$': /* variable start */\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (! isIdentChar (d))\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tparseIdentifier (token->string, d);\n\t\t\t\ttoken->type = TOKEN_VARIABLE;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '?': /* maybe the end of the PHP chunk */\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '>')\n\t\t\t{\n\t\t\t\tInPhp = false;\n\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_QMARK;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tif (! isIdentChar (c))\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\telse\n\t\t\t{\n\t\t\t\tparseIdentifier (token->string, c);\n\t\t\t\tif (MayBeKeyword)\n\t\t\t\t\ttoken->keyword = lookupCaseKeyword (vStringValue (token->string), getInputLanguage ());\n\t\t\t\telse\n\t\t\t\t\ttoken->keyword = KEYWORD_NONE;\n\n\t\t\t\tif (token->keyword == KEYWORD_NONE)\n\t\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\telse\n\t\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\tif (token->type == TOKEN_SEMICOLON ||\n\t\ttoken->type == TOKEN_OPEN_CURLY ||\n\t\ttoken->type == TOKEN_CLOSE_CURLY)\n\t{\n\t\t/* reset current statement details on statement end, and when entering\n\t\t * a deeper scope.\n\t\t * it is a bit ugly to do this in readToken(), but it makes everything\n\t\t * a lot simpler. */\n\t\tCurrentStatement.access = ACCESS_UNDEFINED;\n\t\tCurrentStatement.impl = IMPL_UNDEFINED;\n\t}\n\n\tMayBeKeyword = nextMayBeKeyword;\n\n\tTRACE_PRINT(\"token: %s (%s)\", tokenTypes[token->type], vStringValue (token->string));\n}\n\nstatic void readQualifiedName (tokenInfo *const token, vString *name,\n                               tokenInfo *const lastToken)\n{\n\twhile (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_BACKSLASH)\n\t{\n\t\tif (name)\n\t\t{\n\t\t\tif (token->type == TOKEN_BACKSLASH)\n\t\t\t\tvStringPut (name, '\\\\');\n\t\t\telse\n\t\t\t\tvStringCat (name, token->string);\n\t\t}\n\t\tif (lastToken)\n\t\t\tcopyToken (lastToken, token, true);\n\t\treadToken (token);\n\t}\n}\n\nstatic void enterScope (tokenInfo *const parentToken,\n\t\t\t\t\t\tconst vString *const extraScope,\n\t\t\t\t\t\tconst int parentKind);\n\nstatic void skipOverParens (tokenInfo *token)\n{\n\tif (token->type == TOKEN_OPEN_PAREN)\n\t{\n\t\tint depth = 1;\n\n\t\tdo\n\t\t{\n\t\t\treadToken (token);\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_OPEN_PAREN:  depth++; break;\n\t\t\t\tcase TOKEN_CLOSE_PAREN: depth--; break;\n\t\t\t\tdefault: break;\n\t\t\t}\n\t\t}\n\t\twhile (token->type != TOKEN_EOF && depth > 0);\n\n\t\treadToken (token);\n\t}\n}\n\n/* parses a class or an interface:\n * \tclass Foo {}\n * \tclass Foo extends Bar {}\n * \tclass Foo extends Bar implements iFoo, iBar {}\n * \tinterface iFoo {}\n * \tinterface iBar extends iFoo {}\n *\n * if @name is not NULL, parses an anonymous class with name @name\n * \tnew class {}\n * \tnew class(1, 2) {}\n * \tnew class(1, 2) extends Foo implements iFoo, iBar {} */\nstatic bool parseClassOrIface (tokenInfo *const token, const phpKind kind,\n                                  const tokenInfo *name)\n{\n\tbool readNext = true;\n\timplType impl = CurrentStatement.impl;\n\ttokenInfo *nameFree = NULL;\n\tvString *inheritance = NULL;\n\tvString *parent = NULL;\n\n\treadToken (token);\n\tif (name) /* anonymous class */\n\t{\n\t\t/* skip possible construction arguments */\n\t\tskipOverParens (token);\n\t}\n\telse /* normal, named class */\n\t{\n\t\tif (token->type != TOKEN_IDENTIFIER)\n\t\t\treturn false;\n\n\t\tname = nameFree = newToken ();\n\t\tcopyToken (nameFree, token, true);\n\n\t\treadToken (token);\n\t}\n\n\tinheritance = vStringNew ();\n\t/* read every identifiers, keywords and commas, and assume each\n\t *  identifier (not keyword) is an inheritance\n\t * (like in \"class Foo extends Bar implements iA, iB\") */\n\tenum { inheritance_initial,\n\t\t   inheritance_extends,\n\t\t   inheritance_implements\n\t} istat = inheritance_initial;\n\twhile (token->type == TOKEN_IDENTIFIER ||\n\t       token->type == TOKEN_BACKSLASH ||\n\t       token->type == TOKEN_KEYWORD ||\n\t       token->type == TOKEN_COMMA)\n\t{\n\t\tif (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_BACKSLASH)\n\t\t{\n\t\t\tvString *qualifiedName = vStringNew ();\n\n\t\t\treadQualifiedName (token, qualifiedName, NULL);\n\t\t\tvStringJoin(inheritance, ',', qualifiedName);\n\t\t\tif (istat == inheritance_extends && !parent)\n\t\t\t\tparent = qualifiedName;\n\t\t\telse\n\t\t\t\tvStringDelete (qualifiedName);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (token->type == TOKEN_KEYWORD)\n\t\t\t{\n\t\t\t\tif (token->keyword == KEYWORD_extends)\n\t\t\t\t\tistat = inheritance_extends;\n\t\t\t\telse if (token->keyword == KEYWORD_implements)\n\t\t\t\t\tistat = inheritance_implements;\n\t\t\t}\n\t\t\treadToken (token);\n\t\t}\n\t}\n\n\tmakeClassOrIfaceTag (kind, name, inheritance, impl);\n\n\tif (token->type == TOKEN_OPEN_CURLY)\n\t{\n\t\tvString *backup = ParentClass;\n\t\tParentClass = parent;\n\t\tenterScope (token, name->string, kind);\n\t\tParentClass = backup;\n\t}\n\telse\n\t\treadNext = false;\n\n\tif (nameFree)\n\t\tdeleteToken (nameFree);\n\tvStringDelete (parent);\n\tvStringDelete (inheritance);\n\n\treturn readNext;\n}\n\n/* parses a trait:\n * \ttrait Foo {} */\nstatic bool parseTrait (tokenInfo *const token)\n{\n\tbool readNext = true;\n\ttokenInfo *name;\n\n\treadToken (token);\n\tif (token->type != TOKEN_IDENTIFIER)\n\t\treturn false;\n\n\tname = newToken ();\n\tcopyToken (name, token, true);\n\n\tmakeSimplePhpTag (name, K_TRAIT, ACCESS_UNDEFINED);\n\n\treadToken (token);\n\tif (token->type == TOKEN_OPEN_CURLY)\n\t\tenterScope (token, name->string, K_TRAIT);\n\telse\n\t\treadNext = false;\n\n\tdeleteToken (name);\n\n\treturn readNext;\n}\n\n/* parse a function\n *\n * if @name is NULL, parses a normal function\n * \tfunction myfunc($foo, $bar) {}\n * \tfunction &myfunc($foo, $bar) {}\n * \tfunction myfunc($foo, $bar) : type {}\n * \tfunction myfunc($foo, $bar) : ?type {}\n *\n * if @name is not NULL, parses an anonymous function with name @name\n * \t$foo = function($foo, $bar) {}\n * \t$foo = function&($foo, $bar) {}\n * \t$foo = function($foo, $bar) use ($x, &$y) {}\n * \t$foo = function($foo, $bar) use ($x, &$y) : type {}\n * \t$foo = function($foo, $bar) use ($x, &$y) : ?type {} */\nstatic bool parseFunction (tokenInfo *const token, const tokenInfo *name)\n{\n\tbool readNext = true;\n\taccessType access = CurrentStatement.access;\n\timplType impl = CurrentStatement.impl;\n\ttokenInfo *nameFree = NULL;\n\tvString *rtype = NULL;\n\tvString *arglist = NULL;\n\n\treadToken (token);\n\t/* skip a possible leading ampersand (return by reference) */\n\tif (token->type == TOKEN_AMPERSAND)\n\t\treadToken (token);\n\n\tif (! name)\n\t{\n\t\tif (token->type != TOKEN_IDENTIFIER && token->type != TOKEN_KEYWORD)\n\t\t\treturn false;\n\n\t\tname = nameFree = newToken ();\n\t\tcopyToken (nameFree, token, true);\n\t\treadToken (token);\n\t}\n\n\tif (token->type == TOKEN_OPEN_PAREN)\n\t{\n\t\tint depth = 1;\n\n\t\targlist = vStringNew ();\n\t\tvStringPut (arglist, '(');\n\t\tdo\n\t\t{\n\t\t\treadToken (token);\n\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_OPEN_PAREN:  depth++; break;\n\t\t\t\tcase TOKEN_CLOSE_PAREN: depth--; break;\n\t\t\t\tdefault: break;\n\t\t\t}\n\t\t\t/* display part */\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_AMPERSAND:\t\tvStringPut (arglist, '&');\t\tbreak;\n\t\t\t\tcase TOKEN_CLOSE_CURLY:\t\tvStringPut (arglist, '}');\t\tbreak;\n\t\t\t\tcase TOKEN_CLOSE_PAREN:\t\tvStringPut (arglist, ')');\t\tbreak;\n\t\t\t\tcase TOKEN_CLOSE_SQUARE:\tvStringPut (arglist, ']');\t\tbreak;\n\t\t\t\tcase TOKEN_COLON:\t\t\tvStringPut (arglist, ':');\t\tbreak;\n\t\t\t\tcase TOKEN_COMMA:\t\t\tvStringCatS (arglist, \", \");\tbreak;\n\t\t\t\tcase TOKEN_EQUAL_SIGN:\t\tvStringCatS (arglist, \" = \");\tbreak;\n\t\t\t\tcase TOKEN_OPEN_CURLY:\t\tvStringPut (arglist, '{');\t\tbreak;\n\t\t\t\tcase TOKEN_OPEN_PAREN:\t\tvStringPut (arglist, '(');\t\tbreak;\n\t\t\t\tcase TOKEN_OPEN_SQUARE:\t\tvStringPut (arglist, '[');\t\tbreak;\n\t\t\t\tcase TOKEN_PERIOD:\t\t\tvStringPut (arglist, '.');\t\tbreak;\n\t\t\t\tcase TOKEN_SEMICOLON:\t\tvStringPut (arglist, ';');\t\tbreak;\n\t\t\t\tcase TOKEN_BACKSLASH:\t\tvStringPut (arglist, '\\\\');\t\tbreak;\n\t\t\t\tcase TOKEN_STRING:\n\t\t\t\t{\n\t\t\t\t\tvStringPut (arglist, '\\'');\n\t\t\t\t\tvStringCat  (arglist, token->string);\n\t\t\t\t\tvStringPut (arglist, '\\'');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\tcase TOKEN_VARIABLE:\n\t\t\t\t{\n\t\t\t\t\tswitch (vStringLast (arglist))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 0:\n\t\t\t\t\t\tcase ' ':\n\t\t\t\t\t\tcase '{':\n\t\t\t\t\t\tcase '(':\n\t\t\t\t\t\tcase '[':\n\t\t\t\t\t\tcase '.':\n\t\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\t\t/* no need for a space between those and the identifier */\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tvStringPut (arglist, ' ');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (token->type == TOKEN_VARIABLE)\n\t\t\t\t\t\tvStringPut (arglist, '$');\n\t\t\t\t\tvStringCat (arglist, token->string);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault: break;\n\t\t\t}\n\t\t}\n\t\twhile (token->type != TOKEN_EOF && depth > 0);\n\n\t\treadToken (token); /* normally it's an open brace or \"use\" keyword */\n\t}\n\n\t/* skip use(...) */\n\tif (token->type == TOKEN_KEYWORD && token->keyword == KEYWORD_use)\n\t{\n\t\treadToken (token);\n\t\tskipOverParens (token);\n\t}\n\n\t/* PHP7 return type declaration or if parsing Zephir, gather function return\n\t * type hint to fill typeRef. */\n\tif ((getInputLanguage () == Lang_php && token->type == TOKEN_COLON) ||\n\t    (getInputLanguage () == Lang_zephir && token->type == TOKEN_OPERATOR))\n\t{\n\t\tif (arglist)\n\t\t\trtype = vStringNew ();\n\n\t\treadToken (token);\n\t\tif (token->type == TOKEN_QMARK)\n\t\t{\n\t\t\tif (rtype)\n\t\t\t\tvStringPut (rtype, '?');\n\t\t\treadToken (token);\n\t\t}\n\t\treadQualifiedName (token, rtype, NULL);\n\n\t\tif (rtype && vStringIsEmpty (rtype))\n\t\t{\n\t\t\tvStringDelete (rtype);\n\t\t\trtype = NULL;\n\t\t}\n\t}\n\n\tif (arglist)\n\t\tmakeFunctionTag (name, arglist, rtype, access, impl);\n\n\tif (token->type == TOKEN_OPEN_CURLY)\n\t\tenterScope (token, name->string, K_FUNCTION);\n\telse\n\t\treadNext = false;\n\n\tvStringDelete (rtype);\n\tvStringDelete (arglist);\n\tif (nameFree)\n\t\tdeleteToken (nameFree);\n\n\treturn readNext;\n}\n\n/* parses declarations of the form\n * \tconst NAME = VALUE */\nstatic bool parseConstant (tokenInfo *const token)\n{\n\ttokenInfo *name;\n\n\treadToken (token); /* skip const keyword */\n\tif (token->type != TOKEN_IDENTIFIER && token->type != TOKEN_KEYWORD)\n\t\treturn false;\n\n\tname = newToken ();\n\tcopyToken (name, token, true);\n\n\treadToken (token);\n\tif (token->type == TOKEN_EQUAL_SIGN)\n\t\tmakeSimplePhpTag (name, K_DEFINE, ACCESS_UNDEFINED);\n\n\tdeleteToken (name);\n\n\treturn token->type == TOKEN_EQUAL_SIGN;\n}\n\n/* parses declarations of the form\n * \tdefine('NAME', 'VALUE')\n * \tdefine(NAME, 'VALUE) */\nstatic bool parseDefine (tokenInfo *const token)\n{\n\tint depth = 1;\n\n\treadToken (token); /* skip \"define\" identifier */\n\tif (token->type != TOKEN_OPEN_PAREN)\n\t\treturn false;\n\n\treadToken (token);\n\tif (token->type == TOKEN_STRING ||\n\t\ttoken->type == TOKEN_IDENTIFIER)\n\t{\n\t\tmakeSimplePhpTag (token, K_DEFINE, ACCESS_UNDEFINED);\n\t\treadToken (token);\n\t}\n\n\t/* skip until the close parenthesis.\n\t * no need to handle nested blocks since they would be invalid\n\t * in this context anyway (the VALUE may only be a scalar, like\n\t * \t42\n\t * \t(42)\n\t * and alike) */\n\twhile (token->type != TOKEN_EOF && depth > 0)\n\t{\n\t\tswitch (token->type)\n\t\t{\n\t\t\tcase TOKEN_OPEN_PAREN:\tdepth++; break;\n\t\t\tcase TOKEN_CLOSE_PAREN:\tdepth--; break;\n\t\t\tdefault: break;\n\t\t}\n\t\treadToken (token);\n\t}\n\n\treturn false;\n}\n\n/* parses declarations of the form\n * \tuse Foo\n * \tuse Foo\\Bar\\Class\n * \tuse Foo\\Bar\\Class as FooBarClass\n * \tuse function Foo\\Bar\\func\n * \tuse function Foo\\Bar\\func as foobarfunc\n * \tuse const Foo\\Bar\\CONST\n * \tuse const Foo\\Bar\\CONST as FOOBARCONST\n * \tuse Foo, Bar\n * \tuse Foo, Bar as Baz\n * \tuse Foo as Test, Bar as Baz\n * \tuse Foo\\{Bar, Baz as Child, Nested\\Other, Even\\More as Something} */\nstatic bool parseUse (tokenInfo *const token)\n{\n\tbool readNext = false;\n\t/* we can't know the use type, because class, interface and namespaces\n\t * aliases are the same, and the only difference is the referenced name's\n\t * type */\n\tconst char *refType = \"unknown\";\n\tvString *refName = vStringNew ();\n\ttokenInfo *nameToken = newToken ();\n\tbool grouped = false;\n\n\treadToken (token); /* skip use keyword itself */\n\tif (token->type == TOKEN_KEYWORD && (token->keyword == KEYWORD_function ||\n\t                                     token->keyword == KEYWORD_const))\n\t{\n\t\tswitch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_function:\trefType = PhpKinds[K_FUNCTION].name;\tbreak;\n\t\t\tcase KEYWORD_const:\t\trefType = PhpKinds[K_DEFINE].name;\t\tbreak;\n\t\t\tdefault: break; /* silence compilers */\n\t\t}\n\t\treadNext = true;\n\t}\n\n\tif (readNext)\n\t\treadToken (token);\n\n\treadQualifiedName (token, refName, nameToken);\n\tgrouped = readNext = (token->type == TOKEN_OPEN_CURLY);\n\n\tdo\n\t{\n\t\tsize_t refNamePrefixLength = grouped ? vStringLength (refName) : 0;\n\n\t\t/* if it's either not the first name in a comma-separated list, or we\n\t\t * are in a grouped alias and need to read the leaf name */\n\t\tif (readNext)\n\t\t{\n\t\t\treadToken (token);\n\t\t\t/* in case of a trailing comma (or an empty group) */\n\t\t\tif (token->type == TOKEN_CLOSE_CURLY)\n\t\t\t\tbreak;\n\t\t\treadQualifiedName (token, refName, nameToken);\n\t\t}\n\n\t\tif (token->type == TOKEN_KEYWORD && token->keyword == KEYWORD_as)\n\t\t{\n\t\t\treadToken (token);\n\t\t\tcopyToken (nameToken, token, true);\n\t\t\treadToken (token);\n\t\t}\n\n\t\tif (nameToken->type == TOKEN_IDENTIFIER && PhpKinds[K_ALIAS].enabled)\n\t\t{\n\t\t\ttagEntryInfo entry;\n\n\t\t\tinitPhpEntry (&entry, nameToken, K_ALIAS, ACCESS_UNDEFINED);\n\n\t\t\tentry.extensionFields.typeRef[0] = refType;\n\t\t\tentry.extensionFields.typeRef[1] = vStringValue (refName);\n\n\t\t\tmakePhpTagEntry (&entry);\n\t\t}\n\n\t\tvStringTruncate (refName, refNamePrefixLength);\n\n\t\treadNext = true;\n\t}\n\twhile (token->type == TOKEN_COMMA);\n\n\tif (grouped && token->type == TOKEN_CLOSE_CURLY)\n\t\treadToken (token);\n\n\tvStringDelete (refName);\n\tdeleteToken (nameToken);\n\n\treturn (token->type == TOKEN_SEMICOLON);\n}\n\n/* parses declarations of the form\n * \t$var = VALUE\n * \t$var; */\nstatic bool parseVariable (tokenInfo *const token, vString * typeName)\n{\n\ttokenInfo *name;\n\tbool readNext = true;\n\taccessType access = CurrentStatement.access;\n\n\tname = newToken ();\n\tcopyToken (name, token, true);\n\n\treadToken (token);\n\tif (token->type == TOKEN_EQUAL_SIGN)\n\t{\n\t\tphpKind kind = K_VARIABLE;\n\n\t\tif (token->parentKind == K_FUNCTION)\n\t\t\tkind = K_LOCAL_VARIABLE;\n\n\t\treadToken (token);\n\t\tif (token->type == TOKEN_KEYWORD &&\n\t\t\ttoken->keyword == KEYWORD_function &&\n\t\t\tPhpKinds[kind].enabled)\n\t\t{\n\t\t\tif (parseFunction (token, name))\n\t\t\t\treadToken (token);\n\t\t\treadNext = (bool) (token->type == TOKEN_SEMICOLON);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmakeSimplePhpTag (name, kind, access);\n\t\t\treadNext = false;\n\t\t}\n\t}\n\telse if (token->type == TOKEN_SEMICOLON)\n\t{\n\t\t/* generate tags for variable declarations in classes\n\t\t * \tclass Foo {\n\t\t * \t\tprotected $foo;\n\t\t * \t}\n\t\t * but don't get fooled by stuff like $foo = $bar; */\n\t\tif (token->parentKind == K_CLASS ||\n\t\t    token->parentKind == K_INTERFACE ||\n\t\t    token->parentKind == K_TRAIT)\n\t\t\tmakeTypedPhpTag (name, K_VARIABLE, access, typeName);\n\t}\n\telse\n\t\treadNext = false;\n\n\tdeleteToken (name);\n\n\treturn readNext;\n}\n\n/* parses namespace declarations\n * \tnamespace Foo {}\n * \tnamespace Foo\\Bar {}\n * \tnamespace Foo;\n * \tnamespace Foo\\Bar;\n * \tnamespace;\n * \tnamespace {} */\nstatic bool parseNamespace (tokenInfo *const token)\n{\n\ttokenInfo *nsToken = newToken ();\n\n\tvStringClear (CurrentNamesapce);\n\tcopyToken (nsToken, token, false);\n\n\tdo\n\t{\n\t\treadToken (token);\n\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t{\n\t\t\tif (vStringLength (CurrentNamesapce) > 0)\n\t\t\t{\n\t\t\t\tconst char *sep;\n\n\t\t\t\tsep = phpScopeSeparatorFor(K_NAMESPACE,\n\t\t\t\t\t\t\t   K_NAMESPACE);\n\t\t\t\tvStringCatS (CurrentNamesapce, sep);\n\t\t\t}\n\t\t\tvStringCat (CurrentNamesapce, token->string);\n\t\t}\n\t}\n\twhile (token->type != TOKEN_EOF &&\n\t\t   token->type != TOKEN_SEMICOLON &&\n\t\t   token->type != TOKEN_OPEN_CURLY);\n\n\tif (vStringLength (CurrentNamesapce) > 0)\n\t\tmakeNamespacePhpTag (nsToken, CurrentNamesapce);\n\n\tif (token->type == TOKEN_OPEN_CURLY)\n\t\tenterScope (token, NULL, -1);\n\n\tdeleteToken (nsToken);\n\n\treturn true;\n}\n\n/* skip trait uses not to confuse typerefs\n * \tuse Name;\n * \tuse \\\\Some\\\\Name;\n * \tuse Name, Other;\n * \tuse Name { method as private; }\n * \tuse Name, Other { otherMethod as public otherName; }\n *\n * Note that curly braces are only allowed on the last `use`, this is a syntax\n * error:\n * \tuse Name { method as private; }, Other;\n * This has to be split in two `use`es or reordered.\n */\nstatic bool parseClassUse (tokenInfo *const token)\n{\n\tdo\n\t{\n\t\treadToken (token);\n\t\tif (token->type == TOKEN_OPEN_CURLY)\n\t\t{\n\t\t\tenterScope (token, NULL, -1);\n\t\t\treturn true;\n\t\t}\n\t}\n\twhile (token->type == TOKEN_IDENTIFIER ||\n\t\t   token->type == TOKEN_BACKSLASH ||\n\t\t   token->type == TOKEN_COMMA);\n\n\treturn (token->type == TOKEN_SEMICOLON);\n}\n\nstatic void enterScope (tokenInfo *const parentToken,\n\t\t\t\t\t\tconst vString *const extraScope,\n\t\t\t\t\t\tconst int parentKind)\n{\n\tTRACE_ENTER();\n\n\ttokenInfo *token = newToken ();\n\tvString *typeName = vStringNew ();\n\tint origParentKind = parentToken->parentKind;\n\n\tcopyToken (token, parentToken, true);\n\n\tif (extraScope)\n\t{\n\t\ttoken->parentKind = parentKind;\n\t\taddToScope (token, extraScope, origParentKind);\n\t}\n\n\treadToken (token);\n\twhile (token->type != TOKEN_EOF &&\n\t\t   token->type != TOKEN_CLOSE_CURLY)\n\t{\n\t\tbool readNext = true;\n\n\t\tswitch (token->type)\n\t\t{\n\t\t\tcase TOKEN_OPEN_CURLY:\n\t\t\t\tenterScope (token, NULL, -1);\n\t\t\t\tbreak;\n\n\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\tswitch (token->keyword)\n\t\t\t\t{\n\t\t\t\t\t/* handle anonymous classes */\n\t\t\t\t\tcase KEYWORD_new:\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tif (token->keyword != KEYWORD_class)\n\t\t\t\t\t\t\treadNext = false;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttokenInfo *name = newToken ();\n\n\t\t\t\t\t\t\tcopyToken (name, token, true);\n\t\t\t\t\t\t\tanonGenerate (name->string, \"AnonymousClass\", K_CLASS);\n\t\t\t\t\t\t\tname->anonymous = true;\n\t\t\t\t\t\t\treadNext = parseClassOrIface (token, K_CLASS, name);\n\t\t\t\t\t\t\tdeleteToken (name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_class:\t\treadNext = parseClassOrIface (token, K_CLASS, NULL);\t\tbreak;\n\t\t\t\t\tcase KEYWORD_interface:\treadNext = parseClassOrIface (token, K_INTERFACE, NULL);\tbreak;\n\t\t\t\t\tcase KEYWORD_trait:\t\treadNext = parseTrait (token);\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_function:\treadNext = parseFunction (token, NULL);\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_const:\t\treadNext = parseConstant (token);\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_define:\treadNext = parseDefine (token);\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_use:\n\t\t\t\t\t\t/* aliases are only allowed at root scope, but the keyword\n\t\t\t\t\t\t * is also used to i.e. \"import\" traits into a class */\n\t\t\t\t\t\tif (vStringLength (token->scope) == 0)\n\t\t\t\t\t\t\treadNext = parseUse (token);\n\t\t\t\t\t\telse if (parentKind == K_CLASS || parentKind == K_TRAIT)\n\t\t\t\t\t\t\treadNext = parseClassUse (token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_namespace:\treadNext = parseNamespace (token);\tbreak;\n\n\t\t\t\t\tcase KEYWORD_private:\tCurrentStatement.access = ACCESS_PRIVATE;\tbreak;\n\t\t\t\t\tcase KEYWORD_protected:\tCurrentStatement.access = ACCESS_PROTECTED;\tbreak;\n\t\t\t\t\tcase KEYWORD_public:\tCurrentStatement.access = ACCESS_PUBLIC;\tbreak;\n\t\t\t\t\tcase KEYWORD_var:\t\tCurrentStatement.access = ACCESS_PUBLIC;\tbreak;\n\n\t\t\t\t\tcase KEYWORD_abstract:\tCurrentStatement.impl = IMPL_ABSTRACT;\t\tbreak;\n\n\t\t\t\t\tdefault: break;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase TOKEN_QMARK:\n\t\t\t\tvStringClear (typeName);\n\t\t\t\tvStringPut (typeName, '?');\n\t\t\t\treadNext = true;\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\tvStringCat (typeName, token->string);\n\t\t\t\treadNext = true;\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_VARIABLE:\n\t\t\t\treadNext = parseVariable (token,\n\t\t\t\t\t\t\t\t\t\t  vStringIsEmpty(typeName)\n\t\t\t\t\t\t\t\t\t\t  ? NULL\n\t\t\t\t\t\t\t\t\t\t  : typeName);\n\t\t\t\tvStringClear (typeName);\n\t\t\t\tbreak;\n\n\t\t\tdefault: break;\n\t\t}\n\n\t\tif (readNext)\n\t\t\treadToken (token);\n\t}\n\n\tcopyToken (parentToken, token, false);\n\tparentToken->parentKind = origParentKind;\n\tvStringDelete (typeName);\n\tdeleteToken (token);\n\n\tTRACE_LEAVE();\n}\n\nstatic void findTags (bool startsInPhpMode)\n{\n\tTRACE_ENTER();\n\n\ttokenInfo *const token = newToken ();\n\n\tInPhp = startsInPhpMode;\n\tMayBeKeyword = true;\n\tCurrentStatement.access = ACCESS_UNDEFINED;\n\tCurrentStatement.impl = IMPL_UNDEFINED;\n\tCurrentNamesapce = vStringNew ();\n\tFullScope = vStringNew ();\n\tAssert (ParentClass == NULL);\n\n\tdo\n\t{\n\t\tenterScope (token, NULL, -1);\n\t}\n\twhile (token->type != TOKEN_EOF); /* keep going even with unmatched braces */\n\n\tvStringDelete (FullScope);\n\tvStringDelete (CurrentNamesapce);\n\tdeleteToken (token);\n\n\tTRACE_LEAVE();\n}\n\nstatic void findPhpTags (void)\n{\n\tTRACE_ENTER();\n\tfindTags (false);\n\tTRACE_LEAVE();\n}\n\nstatic void findZephirTags (void)\n{\n\tTRACE_ENTER();\n\tfindTags (true);\n\tTRACE_LEAVE();\n}\n\nstatic void initializePool (void)\n{\n\tif (TokenPool == NULL)\n\t\tTokenPool = objPoolNew (16, newPoolToken, deletePoolToken, clearPoolToken, NULL);\n}\n\nstatic void initializePhpParser (const langType language)\n{\n\tLang_php = language;\n\tinitializePool ();\n}\n\nstatic void initializeZephirParser (const langType language)\n{\n\tLang_zephir = language;\n\tinitializePool ();\n}\n\nstatic void finalize (langType language CTAGS_ATTR_UNUSED, bool initialized)\n{\n\tif (!initialized)\n\t\treturn;\n\n\tif (TokenPool != NULL)\n\t{\n\t\tobjPoolDelete (TokenPool);\n\t\tTokenPool = NULL;\n\t}\n}\n\nextern parserDefinition* PhpParser (void)\n{\n\tstatic const char *const extensions [] = { \"php\", \"php3\", \"php4\", \"php5\", \"php7\", \"phtml\", NULL };\n\tparserDefinition* def = parserNew (\"PHP\");\n\tdef->kindTable      = PhpKinds;\n\tdef->kindCount  = ARRAY_SIZE (PhpKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findPhpTags;\n\tdef->initialize = initializePhpParser;\n\tdef->finalize   = finalize;\n\tdef->keywordTable = PhpKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (PhpKeywordTable);\n\treturn def;\n}\n\nextern parserDefinition* ZephirParser (void)\n{\n\tstatic const char *const extensions [] = { \"zep\", NULL };\n\tparserDefinition* def = parserNew (\"Zephir\");\n\tdef->kindTable      = PhpKinds;\n\tdef->kindCount  = ARRAY_SIZE (PhpKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findZephirTags;\n\tdef->initialize = initializeZephirParser;\n\tdef->finalize   = finalize;\n\tdef->keywordTable = PhpKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (PhpKeywordTable);\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/plist.c",
    "content": "/*\n*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for property list defined\n*   in http://www.apple.com/DTDs/PropertyList-1.0.dtd.\n*/\n\n#include \"general.h\"\t/* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"strlist.h\"\n#include \"x-xml.h\"\n\n\ntypedef enum {\n\tK_KEY,\n} plistKind;\n\nstatic kindDefinition PlistKinds [] = {\n\t{ true,  'k', \"key\",\t  \"keys\" },\n};\n\nstatic void plistFindTagsUnderKey (xmlNode *node,\n\t\t\t\t   const char *xpath,\n\t\t\t\t   const struct sTagXpathRecurSpec *spec,\n\t\t\t\t   xmlXPathContext *ctx,\n\t\t\t\t   void *userData);\n\nstatic void makeTagWithScope (xmlNode *node,\n\t\t\t      const char *xpath,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec,\n\t\t\t      struct sTagEntryInfo *tag,\n\t\t\t      void *userData);\n\nstatic tagXpathTable plistXpathMainTable[] = {\n\t{ \"///plist//dict/key\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  .spec.recurSpec = {\n\t\t\tplistFindTagsUnderKey\n\t\t}\n\t},\n};\n\nstatic tagXpathTable plistXpathTextTable[] = {\n\t{ \"text()\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  .spec.makeTagSpec = {\n\t\t\tK_KEY,  ROLE_DEFINITION_INDEX,\n\t\t\tmakeTagWithScope\n\t\t}\n\t},\n};\n\nenum plistXpathTable {\n\tTABLE_MAIN,\n\tTABLE_TEXT,\n};\n\nstatic tagXpathTableTable plistXpathTableTable[] = {\n\t[TABLE_MAIN] = { ARRAY_AND_SIZE(plistXpathMainTable) },\n\t[TABLE_TEXT] = { ARRAY_AND_SIZE(plistXpathTextTable) },\n};\n\nstatic bool isCompoundElement (xmlNode *node)\n{\n\treturn !! (node->name\n\t\t   && ((strcmp ((char *)(node->name), \"dict\") == 0)\n\t\t       || (strcmp ((char *)(node->name), \"array\") == 0)));\n}\n\nstatic xmlNode *getPrevKeyElement (xmlNode *node)\n{\n\txmlNode *prev;\n\n\tprev = xmlPreviousElementSibling (node);\n\tif (prev)\n\t{\n\t\tif (strcmp ((char *)prev->name, \"key\") == 0)\n\t\t\treturn prev;\n\t\telse\n\t\t\tprev = NULL;\n\t}\n\treturn prev;\n}\n\nstatic void plistFindTagsUnderKey (xmlNode *node,\n\t\t\t\t   const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\t   const struct sTagXpathRecurSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t\t   xmlXPathContext *ctx,\n\t\t\t\t   void *userData CTAGS_ATTR_UNUSED)\n{\n\txmlNode *current;\n\txmlNode *prev;\n\tstringList *queue;\n\tvString* path;\n\tvString* v;\n\tint c;\n\n\tqueue = stringListNew ();\n\tcurrent = node;\n\tfor (current = node; current; current = current->parent)\n\t{\n\t\tif (isCompoundElement (current)\n\t\t    && (prev = getPrevKeyElement (current)))\n\t\t{\n\t\t\tchar* parent = (char *)xmlNodeGetContent (prev);\n\t\t\tif (parent)\n\t\t\t{\n\t\t\t\tv = vStringNewInit (parent);\n\t\t\t\tstringListAdd (queue, v);\n\t\t\t\txmlFree (parent);\n\t\t\t}\n\t\t}\n\t}\n\n\tpath = vStringNew ();\n\twhile ((c = stringListCount (queue)) > 0)\n\t{\n\t\tv = stringListLast (queue);\n\t\tvStringCat (path, v);\n\t\tvStringDelete (v);\n\t\tstringListRemoveLast (queue);\n\t\tif (c != 1)\n\t\t\tvStringPut (path, '.');\n\t}\n\tstringListDelete (queue);\n\n\tfindXMLTags (ctx, node,\n\t\t\t\t TABLE_TEXT, (vStringLength (path) > 0)? vStringValue (path): NULL);\n\n\tvStringDelete (path);\n}\n\nstatic void makeTagWithScope (xmlNode *node CTAGS_ATTR_UNUSED,\n\t\t\t      const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t      struct sTagEntryInfo *tag,\n\t\t\t      void *userData)\n{\n\ttag->extensionFields.scopeKindIndex = userData? K_KEY: KIND_GHOST_INDEX;\n\ttag->extensionFields.scopeName  = userData;\n\tmakeTagEntry (tag);\n}\n\nstatic void\nfindPlistTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic void\nrunXPathEngine(xmlSubparser *s,\n\t\t\t   xmlXPathContext *ctx, xmlNode *root)\n{\n\tfindXMLTags (ctx, root, TABLE_MAIN, NULL);\n}\n\nstatic xmlSubparser plistSubparser = {\n\t.subparser = {\n\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t},\n\t.runXPathEngine = runXPathEngine,\n};\n\nextern parserDefinition*\nPlistXMLParser (void)\n{\n\tstatic const char *const extensions [] = { \"plist\", NULL };\n\tparserDefinition* const def = parserNew (\"PlistXML\");\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"XML\", &plistSubparser },\n\t};\n\n\tdef->kindTable         = PlistKinds;\n\tdef->kindCount     = ARRAY_SIZE (PlistKinds);\n\tdef->extensions    = extensions;\n\tdef->parser        = findPlistTags;\n\tdef->tagXpathTableTable  = plistXpathTableTable;\n\tdef->tagXpathTableCount  = ARRAY_SIZE (plistXpathTableTable);\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/powershell.c",
    "content": "/*\n*   Copyright (c) 2015, Enrico Tröger <enrico.troeger@uvena.de>\n*\n*   Loosely based on the PHP tags parser since the syntax is somewhat similar\n*   regarding variable and function definitions.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains code for generating tags for Windows PowerShell scripts\n*   (https://en.wikipedia.org/wiki/PowerShell).\n*\n*   References:\n*   - https://learn.microsoft.com/en-us/powershell/scripting/developer/windows-powershell-reference\n*   - https://learn.microsoft.com/en-us/powershell/scripting/lang-spec/chapter-01\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"debug.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"keyword.h\"\n#include \"entry.h\"\n#include \"routines.h\"\n#include <string.h>\n\n#define SCOPE_SEPARATOR \"::\"\n\n\n#define ACCESS_UNDEFINED NULL\nstatic const char *const accessTypes[] = {\n\tACCESS_UNDEFINED,\n\t\"global\",\n\t\"local\",\n\t\"script\",\n\t\"private\"\n};\n\ntypedef enum {\n\tK_FUNCTION,\n\tK_VARIABLE,\n\tK_CLASS,\n\tK_FILTER,\n\tK_ENUM,\n\tK_ENUMLABEL,\n\tCOUNT_KIND\n} powerShellKind;\n\nstatic kindDefinition PowerShellKinds[COUNT_KIND] = {\n\t{ true, 'f', \"function\",\t\"functions\" },\n\t{ true, 'v', \"variable\",\t\"variables\" },\n\t{ true, 'c', \"class\",\t\t\"classes\" },\n\t{ true, 'i', \"filter\",\t\t\"filter\" },\n\t{ true, 'g', \"enum\",\t\t\"enum names\" },\n\t{ true, 'e', \"enumlabel\",\t\"enum labels\",\n\t  .version = 1 },\n};\n\n\ntypedef enum eTokenType {\n\tTOKEN_UNDEFINED,\n\tTOKEN_EOF,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_SEMICOLON,\n\tTOKEN_COLON,\n\tTOKEN_COMMA,\n\tTOKEN_KEYWORD,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_OPERATOR,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n\tTOKEN_PERIOD,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_EQUAL_SIGN,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_VARIABLE\n} tokenType;\n\nenum {\n\tKEYWORD_function,\n\tKEYWORD_filter,\n\tKEYWORD_class,\n\tKEYWORD_enum,\n};\n\n/* We need an integer that is not an unsigned to allow KEYWORD_NONE. */\ntypedef int keywordId;\n\nstatic const keywordTable PowerShellKeywordTable[] = {\n\t{ \"function\",\tKEYWORD_function },\n\t{ \"filter\",\t\tKEYWORD_filter },\n\t{ \"class\",\t\tKEYWORD_class },\n\t{ \"enum\",\t\tKEYWORD_enum },\n};\n\ntypedef struct {\n\ttokenType\t\ttype;\n\tkeywordId\t\tkeyword;\n\tvString *\t\tstring;\n\tvString *\t\tscope;\n\tunsigned long\tlineNumber;\n\tMIOPos\t\t\tfilePosition;\n\tint\t\t\t\tparentKind; /* KIND_GHOST_INDEX if none */\n\tbool            herestring;\t/* Meaningful only when type is TOKEN_STRING. */\n} tokenInfo;\n\n\nstatic const char *findValidAccessType (const char *const access)\n{\n\tunsigned int i;\n\tif (access == ACCESS_UNDEFINED)\n\t\treturn ACCESS_UNDEFINED; /* early out to save the for-loop if possible */\n\tfor (i = 0; i < ARRAY_SIZE(accessTypes); i++)\n\t{\n\t\tif (accessTypes[i] == ACCESS_UNDEFINED)\n\t\t\tcontinue;\n\t\tif (strcasecmp (access, accessTypes[i]) == 0)\n\t\t\treturn accessTypes[i];\n\t\ti++;\n\t}\n\treturn ACCESS_UNDEFINED;\n}\n\nstatic void initPowerShellEntry (tagEntryInfo *const e, const tokenInfo *const token,\n\t\t\t\t\t\t\t\t const powerShellKind kind, const char *const access)\n{\n\tinitTagEntry (e, vStringValue (token->string), kind);\n\n\tupdateTagLine (e, token->lineNumber, token->filePosition);\n\n\tif (access != NULL)\n\t\te->extensionFields.access = access;\n\tif (vStringLength (token->scope) > 0)\n\t{\n\t\tint parentKind = token->parentKind;\n\t\tAssert (parentKind >= 0);\n\n\t\te->extensionFields.scopeKindIndex = parentKind;\n\t\te->extensionFields.scopeName = vStringValue (token->scope);\n\t}\n}\n\nstatic void makeSimplePowerShellTag (const tokenInfo *const token, const powerShellKind kind,\n\t\t\t\t\t\t\t\t\t const char *const access)\n{\n\tif (PowerShellKinds[kind].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitPowerShellEntry (&e, token, kind, access);\n\t\tmakeTagEntry (&e);\n\t}\n}\n\nstatic void makeFunctionTag (const tokenInfo *const token, const vString *const arglist,\n\t\t\t\t\t\t\t const char *const access, int kind)\n{\n\tif (PowerShellKinds[kind].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitPowerShellEntry (&e, token, kind, access);\n\n\t\tif (arglist)\n\t\t\te.extensionFields.signature = vStringValue (arglist);\n\n\t\tmakeTagEntry (&e);\n\t}\n}\n\nstatic void makeClassTag (const tokenInfo *const token)\n{\n\tif (PowerShellKinds[K_CLASS].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitPowerShellEntry (&e, token, K_CLASS, NULL);\n\n\t\tmakeTagEntry (&e);\n\t}\n}\n\nstatic void makeEnumTag (const tokenInfo *const token)\n{\n\tif (PowerShellKinds[K_ENUM].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitPowerShellEntry (&e, token, K_ENUM, NULL);\n\n\t\tmakeTagEntry (&e);\n\t}\n}\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->string\t\t= vStringNew ();\n\ttoken->scope\t\t= vStringNew ();\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\ttoken->parentKind\t= KIND_GHOST_INDEX;\n\n\treturn token;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tvStringDelete (token->string);\n\tvStringDelete (token->scope);\n\teFree (token);\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const src,\n\t\t\t\t\t   bool scope)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tvStringCopy (dest->string, src->string);\n\tdest->parentKind = src->parentKind;\n\tif (scope)\n\t\tvStringCopy (dest->scope, src->scope);\n}\n\nstatic void addToScope (tokenInfo *const token, const vString *const extra)\n{\n\tif (vStringLength (token->scope) > 0)\n\t\tvStringCatS (token->scope, SCOPE_SEPARATOR);\n\tvStringCatS (token->scope, vStringValue (extra));\n}\n\nstatic bool isIdentChar (const int c)\n{\n\treturn (isalnum (c) || c == '_' || c == '-' || c >= 0x80);\n}\n\nstatic bool isScopeIdentifierChar (const int c)\n{\n\treturn (isIdentChar (c) || c == ':');\n}\n\nstatic void parseString (vString *const string, const int delimiter)\n{\n\twhile (true)\n\t{\n\t\tint c = getcFromInputFile ();\n\n\t\tif (delimiter == '\"' && c == '`' && (c = getcFromInputFile ()) != EOF)\n\t\t\tvStringPut (string, c);\n\t\telse if (c == EOF || c == delimiter)\n\t\t\tbreak;\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\nstatic bool parseHereString (vString *const string, const int delimiter)\n{\n\tenum phs_state {\n\t\tPHS_INIT,\n\t\tPHS_NEWLINE0,\n\t\tPHS_QUOTE,\n\t\tPHS_AT,\n\t\tPHS_NEWLINE1,\n\t\tPHS_END = PHS_NEWLINE1\n\t} s = PHS_INIT;\n\n\twhile (s != PHS_END)\n\t{\n\t\tint c = getcFromInputFile ();\n\n\t\tif (c == EOF)\n\t\t\treturn false;\n\n\t\tvStringPut (string, c);\n\n\t\tif (s == PHS_INIT && c == '\\n')\n\t\t\ts = PHS_NEWLINE0;\n\t\telse if (s == PHS_NEWLINE0 && c == delimiter)\n\t\t\ts = PHS_QUOTE;\n\t\telse if (s == PHS_QUOTE && c == '@')\n\t\t\ts = PHS_AT;\n\t\telse if (s == PHS_AT && c == '\\n')\n\t\t\ts = PHS_NEWLINE1;\n\t\telse\n\t\t\ts = PHS_INIT;\n\t}\n\n\tAssert (vStringLength (string) >= 4);\n\tvStringTruncate (string, vStringLength (string) - 4);\n\treturn true;\n}\n\n/* parse a identifier that may contain scopes, such as function names and\n * variable names.\n *\n * \tVariableName\n * \tFunctionName\n * \tlocal:VariableName\n * \tprivate:FunctionName\n */\nstatic void parseScopeIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isScopeIdentifierChar (c));\n\tungetcToInputFile (c);\n}\n\n/* parse a identifier that do not contain scope, such as class names. */\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isIdentChar (c));\n\tungetcToInputFile (c);\n}\n\nstatic bool isSpace (int c)\n{\n\treturn (c == '\\t' || c == ' ' || c == '\\v' ||\n\t\t\tc == '\\n' || c == '\\r' || c == '\\f');\n}\n\nstatic int skipWhitespaces (int c)\n{\n\twhile (isSpace (c))\n\t\tc = getcFromInputFile ();\n\treturn c;\n}\n\nstatic int skipSingleComment (void)\n{\n\tint c;\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\tif (c == '\\r')\n\t\t{\n\t\t\tint next = getcFromInputFile ();\n\t\t\tif (next != '\\n')\n\t\t\t\tungetcToInputFile (next);\n\t\t\telse\n\t\t\t\tc = next;\n\t\t}\n\t} while (c != EOF && c != '\\n' && c != '\\r');\n\treturn c;\n}\n\nstatic void readTokenFull (tokenInfo *const token, bool includingScope)\n{\n\tint c;\n\n\ttoken->type\t\t= TOKEN_UNDEFINED;\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tc = getcFromInputFile ();\n\tc = skipWhitespaces (c);\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tswitch (c)\n\t{\n\t\tcase EOF: token->type = TOKEN_EOF;\t\t\t\t\tbreak;\n\t\tcase '(': token->type = TOKEN_OPEN_PAREN;\t\t\tbreak;\n\t\tcase ')': token->type = TOKEN_CLOSE_PAREN;\t\t\tbreak;\n\t\tcase ';': token->type = TOKEN_SEMICOLON;\t\t\tbreak;\n\t\tcase ',': token->type = TOKEN_COMMA;\t\t\t\tbreak;\n\t\tcase '.': token->type = TOKEN_PERIOD;\t\t\t\tbreak;\n\t\tcase ':': token->type = TOKEN_COLON;\t\t\t\tbreak;\n\t\tcase '{': token->type = TOKEN_OPEN_CURLY;\t\t\tbreak;\n\t\tcase '}': token->type = TOKEN_CLOSE_CURLY;\t\t\tbreak;\n\t\tcase '[': token->type = TOKEN_OPEN_SQUARE;\t\t\tbreak;\n\t\tcase ']': token->type = TOKEN_CLOSE_SQUARE;\t\t\tbreak;\n\t\tcase '=': token->type = TOKEN_EQUAL_SIGN;\t\t\tbreak;\n\n\t\tcase '\\'':\n\t\tcase '\"':\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tparseString (token->string, c);\n\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\ttoken->herestring = false;\n\t\t\tbreak;\n\n\t\tcase '@':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '\\'' || d == '\"')\n\t\t\t{\n\t\t\t\tbool is_herestr;\n\t\t\t\ttoken->type = TOKEN_STRING;\n\t\t\t\tis_herestr = parseHereString (token->string, d);\n\t\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\t\tif (is_herestr)\n\t\t\t\t\ttoken->herestring = true;\n\t\t\t\telse\n\t\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\t}\n\t\t\telse if (d == EOF)\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase '<':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '#')\n\t\t\t{\n\t\t\t\t/* <# ... #> multiline comment */\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tc = skipToCharacterInInputFile ('#');\n\t\t\t\t\tif (c != EOF)\n\t\t\t\t\t{\n\t\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t\t\tif (c == '>')\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tungetcToInputFile (c);\n\t\t\t\t\t}\n\t\t\t\t} while (c != EOF);\n\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '#': /* comment */\n\t\t\tskipSingleComment ();\n\t\t\tgoto getNextChar;\n\t\t\tbreak;\n\n\t\tcase '+':\n\t\tcase '-':\n\t\tcase '*':\n\t\tcase '/':\n\t\tcase '%':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d != '=')\n\t\t\t\tungetcToInputFile (d);\n\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '$': /* variable start */\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (! isScopeIdentifierChar (d))\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tparseScopeIdentifier (token->string, d);\n\t\t\t\ttoken->type = TOKEN_VARIABLE;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tif (! isIdentChar (c))\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (includingScope)\n\t\t\t\t\tparseScopeIdentifier (token->string, c);\n\t\t\t\telse\n\t\t\t\t\tparseIdentifier (token->string, c);\n\t\t\t\ttoken->keyword = lookupCaseKeyword (\n\t\t\t\t\t\tvStringValue (token->string), getInputLanguage ());\n\t\t\t\tif (token->keyword == KEYWORD_NONE)\n\t\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\telse\n\t\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\treadTokenFull (token, false);\n}\n\nstatic void enterScope (tokenInfo *const parentToken,\n\t\t\t\t\t\tconst vString *const extraScope,\n\t\t\t\t\t\tconst int parentKind);\n\n/* strip a possible PowerShell scope specification and convert it to accessType */\nstatic const char *parsePowerShellScope (tokenInfo *const token)\n{\n\tconst char *access = ACCESS_UNDEFINED;\n\tconst char *const tokenName = vStringValue (token->string);\n\tconst char *powershellScopeEnd;\n\n\tpowershellScopeEnd = strchr (tokenName, ':');\n\tif (powershellScopeEnd)\n\t{\n\t\tsize_t powershellScopeLen;\n\t\tvString * powershellScope = vStringNew ();\n\n\t\tpowershellScopeLen = (size_t)(powershellScopeEnd - tokenName);\n\t\t/* extract the scope */\n\t\tvStringNCopyS (powershellScope, tokenName, powershellScopeLen);\n\t\t/* cut the resulting scope string from the identifier */\n\t\tmemmove (vStringValue (token->string),\n\t\t\t\t /* +1 to skip the leading colon */\n\t\t\t\t vStringValue (token->string) + powershellScopeLen + 1,\n\t\t\t\t /* +1 for the skipped leading colon and - 1 to include the trailing \\0 byte */\n\t\t\t\t token->string->length + 1 - powershellScopeLen - 1);\n\t\ttoken->string->length -= powershellScopeLen + 1;\n\n\t\taccess = findValidAccessType (vStringValue (powershellScope));\n\n\t\tvStringDelete (powershellScope);\n\t}\n\treturn access;\n}\n\n\n/* parse a function\n *\n * \tfunction myfunc($foo, $bar) {}\n */\nstatic bool parseFunction (tokenInfo *const token, int kind)\n{\n\tbool readNext = true;\n\ttokenInfo *nameFree = NULL;\n\tconst char *access;\n\n\treadTokenFull (token, true);\n\n\tif (token->type != TOKEN_IDENTIFIER)\n\t\treturn false;\n\n\taccess = parsePowerShellScope (token);\n\n\tnameFree = newToken ();\n\tcopyToken (nameFree, token, true);\n\treadToken (token);\n\n\tif (token->type == TOKEN_OPEN_PAREN)\n\t{\n\t\tvString *arglist = vStringNew ();\n\t\tint depth = 1;\n\n\t\tvStringPut (arglist, '(');\n\t\tdo\n\t\t{\n\t\t\treadToken (token);\n\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_OPEN_PAREN:  depth++; break;\n\t\t\t\tcase TOKEN_CLOSE_PAREN: depth--; break;\n\t\t\t\tdefault: break;\n\t\t\t}\n\t\t\t/* display part */\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_CLOSE_CURLY:\t\tvStringPut (arglist, '}');\t\tbreak;\n\t\t\t\tcase TOKEN_CLOSE_PAREN:\t\tvStringPut (arglist, ')');\t\tbreak;\n\t\t\t\tcase TOKEN_CLOSE_SQUARE:\tvStringPut (arglist, ']');\t\tbreak;\n\t\t\t\tcase TOKEN_COLON:\t\t\tvStringPut (arglist, ':');\t\tbreak;\n\t\t\t\tcase TOKEN_COMMA:\t\t\tvStringCatS (arglist, \", \");\tbreak;\n\t\t\t\tcase TOKEN_EQUAL_SIGN:\t\tvStringCatS (arglist, \" = \");\tbreak;\n\t\t\t\tcase TOKEN_OPEN_CURLY:\t\tvStringPut (arglist, '{');\t\tbreak;\n\t\t\t\tcase TOKEN_OPEN_PAREN:\t\tvStringPut (arglist, '(');\t\tbreak;\n\t\t\t\tcase TOKEN_OPEN_SQUARE:\t\tvStringPut (arglist, '[');\t\tbreak;\n\t\t\t\tcase TOKEN_PERIOD:\t\t\tvStringPut (arglist, '.');\t\tbreak;\n\t\t\t\tcase TOKEN_SEMICOLON:\t\tvStringPut (arglist, ';');\t\tbreak;\n\t\t\t\tcase TOKEN_STRING:\t\t\tvStringCatS (arglist, \"'...'\");\tbreak;\n\n\t\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\tcase TOKEN_VARIABLE:\n\t\t\t\t{\n\t\t\t\t\tswitch (vStringLast (arglist))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 0:\n\t\t\t\t\t\tcase ' ':\n\t\t\t\t\t\tcase '{':\n\t\t\t\t\t\tcase '(':\n\t\t\t\t\t\tcase '[':\n\t\t\t\t\t\tcase '.':\n\t\t\t\t\t\t\t/* no need for a space between those and the identifier */\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tvStringPut (arglist, ' ');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (token->type == TOKEN_VARIABLE)\n\t\t\t\t\t\tvStringPut (arglist, '$');\n\t\t\t\t\tvStringCat (arglist, token->string);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault: break;\n\t\t\t}\n\t\t}\n\t\twhile (token->type != TOKEN_EOF && depth > 0);\n\n\t\tmakeFunctionTag (nameFree, arglist, access, kind);\n\t\tvStringDelete (arglist);\n\n\t\treadToken (token);\n\t}\n\telse if (token->type == TOKEN_OPEN_CURLY)\n\t{\t/* filters doesn't need to have an arglist */\n\t\tmakeFunctionTag (nameFree, NULL, access, kind);\n\t}\n\n\tif (token->type == TOKEN_OPEN_CURLY)\n\t\tenterScope (token, nameFree->string, kind);\n\telse\n\t\treadNext = false;\n\n\tdeleteToken (nameFree);\n\n\treturn readNext;\n}\n\n/* parse a class\n *\n * \tclass MyClass {}\n * \tclass Derived : Base {}\n */\nstatic bool parseClass (tokenInfo *const token)\n{\n\tbool readNext = true;\n\tvString *nameFree = NULL;\n\n\treadToken (token);\n\n\tif (token->type != TOKEN_IDENTIFIER)\n\t\treturn false;\n\n\tmakeClassTag (token);\n\tnameFree = vStringNewCopy (token->string);\n\treadToken (token);\n\n\twhile (token->type != TOKEN_OPEN_CURLY && token->type != TOKEN_EOF)\n\t{\n\t\treadToken (token);\n\t}\n\n\tif (token->type == TOKEN_OPEN_CURLY)\n\t\tenterScope (token, nameFree, K_CLASS);\n\telse\n\t\treadNext = false;\n\n\tvStringDelete (nameFree);\n\n\treturn readNext;\n}\n\n/* parse a enum\n *\n * \tenum EnumName {}\n */\nstatic bool parseEnum (tokenInfo *const token)\n{\n\tbool readNext = true;\n\tvString *nameFree = NULL;\n\n\treadToken (token);\n\n\tif (token->type != TOKEN_IDENTIFIER)\n\t\treturn false;\n\n\tmakeEnumTag (token);\n\tnameFree = vStringNewCopy (token->string);\n\treadToken (token);\n\n\twhile (token->type != TOKEN_OPEN_CURLY && token->type != TOKEN_EOF)\n\t{\n\t\treadToken (token);\n\t}\n\n\tif (token->type == TOKEN_OPEN_CURLY)\n\t\tenterScope (token, nameFree, K_ENUM);\n\telse\n\t\treadNext = false;\n\n\tvStringDelete (nameFree);\n\n\treturn readNext;\n}\n\n/* parses declarations of the form\n * \t<label> [= <int-value>]\n * that is, contents of an enum\n */\nstatic bool parseEnumLabel (tokenInfo *const token)\n{\n\tbool readNext = true;\n\n\tif (token->parentKind != K_ENUM)\n\t\treturn false;\n\n\tif (token->type != TOKEN_IDENTIFIER)\n\t\treturn false;\n\n\tmakeSimplePowerShellTag (token, K_ENUMLABEL, ACCESS_UNDEFINED);\n\treadToken (token);\n\tif (token->type != TOKEN_EQUAL_SIGN)\n\t\treadNext = false;\n\telse /* skip int-value */\n\t\treadToken (token);\n\n\treturn readNext;\n}\n\n/* parses declarations of the form\n * \t$var = VALUE\n */\nstatic bool parseVariable (tokenInfo *const token)\n{\n\ttokenInfo *name;\n\tbool readNext = true;\n\tconst char *access;\n\n\tname = newToken ();\n\tcopyToken (name, token, true);\n\n\treadToken (token);\n\tif (token->type == TOKEN_EQUAL_SIGN)\n\t{\n\t\tif (token->parentKind != K_FUNCTION &&\n\t\t\t\ttoken->parentKind != K_FILTER &&\n\t\t\t\ttoken->parentKind != K_CLASS)\n\t\t{   /* ignore local variables (i.e. within a function)\n\t\t\t * TODO: Parses class properties to make tags. */\n\t\t\taccess = parsePowerShellScope (name);\n\t\t\tmakeSimplePowerShellTag (name, K_VARIABLE, access);\n\t\t\treadNext = true;\n\t\t}\n\t}\n\telse\n\t\treadNext = false;\n\n\tdeleteToken (name);\n\n\treturn readNext;\n}\n\nstatic void enterScope (tokenInfo *const parentToken,\n\t\t\t\t\t\tconst vString *const extraScope,\n\t\t\t\t\t\tconst int parentKind)\n{\n\ttokenInfo *token = newToken ();\n\tint origParentKind = parentToken->parentKind;\n\n\tcopyToken (token, parentToken, true);\n\n\tif (extraScope)\n\t{\n\t\taddToScope (token, extraScope);\n\t\ttoken->parentKind = parentKind;\n\t}\n\n\treadToken (token);\n\twhile (token->type != TOKEN_EOF &&\n\t\t   token->type != TOKEN_CLOSE_CURLY)\n\t{\n\t\tbool readNext = true;\n\n\t\tswitch (token->type)\n\t\t{\n\t\t\tcase TOKEN_OPEN_CURLY:\n\t\t\t\tenterScope (token, NULL, KIND_GHOST_INDEX);\n\t\t\t\tbreak;\n\n\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\tswitch (token->keyword)\n\t\t\t\t{\n\t\t\t\t\tcase KEYWORD_function:\n\t\t\t\t\t\treadNext = parseFunction (token, K_FUNCTION);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_filter:\n\t\t\t\t\t\treadNext = parseFunction (token, K_FILTER);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_class:\n\t\t\t\t\t\treadNext = parseClass (token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_enum:\n\t\t\t\t\t\treadNext = parseEnum (token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: break;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase TOKEN_VARIABLE:\n\t\t\t\treadNext = parseVariable (token);\n\t\t\t\tbreak;\n\n\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\tif (parentKind == K_ENUM)\n\t\t\t\t\treadNext = parseEnumLabel (token);\n\t\t\t\tbreak;\n\n\t\t\tdefault: break;\n\t\t}\n\n\t\tif (readNext)\n\t\t\treadToken (token);\n\t}\n\n\tcopyToken (parentToken, token, false);\n\tparentToken->parentKind = origParentKind;\n\tdeleteToken (token);\n}\n\nstatic void findPowerShellTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\tdo\n\t{\n\t\tenterScope (token, NULL, KIND_GHOST_INDEX);\n\t}\n\twhile (token->type != TOKEN_EOF); /* keep going even with unmatched braces */\n\n\tdeleteToken (token);\n}\n\nextern parserDefinition* PowerShellParser (void)\n{\n\tstatic const char *const extensions [] = { \"ps1\", \"psm1\", NULL };\n\tparserDefinition* def = parserNew (\"PowerShell\");\n\tdef->kindTable  = PowerShellKinds;\n\tdef->kindCount  = ARRAY_SIZE (PowerShellKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findPowerShellTags;\n\tdef->keywordTable = PowerShellKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (PowerShellKeywordTable);\n\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/prolog.c",
    "content": "/*\n*   Copyright (c) 2025, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for prolog source file.\n*\n*   References:\n*   - https://www.swi-prolog.org/pldoc/man?section=syntax\n*   - https://sicstus.sics.se/sicstus/docs/3.7.1/html/sicstus_45.html\n*   - https://www.az-prolog.com/manual/manuals/manual_program.html (in Japanese)\n*\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"        /* must always come first */\n\n#include \"entry.h\"\n#include \"field.h\"\n#include \"keyword.h\"\n#include \"param.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"tokeninfo.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n\n#include <string.h>\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef enum {\n\tK_PREDICATE,\n\tK_GRAMMAR,\n\tK_MODULE,\n} prologKind;\n\ntypedef enum {\n\tF_ARITY,\n} prologField;\n\ntypedef enum {\n\tX_ARITY,\n} prologXtag;\n\ntypedef enum {\n\tR_MODULE_CHAINELT,\n} prologModuleRole;\n\n\ntypedef enum {\n\t/* 0..255 are the byte's value */\n\tTOKEN_EOF = 256,\n\tTOKEN_UNDEFINED,\n\tTOKEN_KEYWORD,\n\n\tTOKEN_STRATOM,\n\tTOKEN_STRING,\n\tTOKEN_APPLY,\n\tTOKEN_RULEOP,\n\tTOKEN_DCGOP,\n\n\tTOKEN_CODE,\n\tTOKEN_ATOM,\n\tTOKEN_VAR,\n\tTOKEN_NUM,\n\n} prologTokenType;\n\ntypedef enum {\n\tKEYWORD_MODULE,\n#if 0\n\tKEYWORD_USE_MODULE,\n\tKEYWORD_AUTOLOAD,\n\tKEYWORD_LIBRARY,\n#endif\n} prologKeyword;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nstatic void readToken (tokenInfo *const token, void *data CTAGS_ATTR_UNUSED);\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic roleDefinition PrologModuleRoles [] = {\n\t/* Currently V parser wants this items. */\n\t{ false, \"chainElt\", \"(EXPERIMENTAL)used as an element in a module-qualified atom like module:predicate\" },\n};\n\nstatic kindDefinition PrologKinds []  = {\n\t{true,  'p', \"predicate\", \"predicates\", },\n\t{true,  'g', \"grammar\",   \"grammars\",   },\n\t{true,  'm', \"module\",    \"modules\",\n\t .referenceOnly = false, ATTACH_ROLES(PrologModuleRoles),\n\t},\n};\n\nstatic fieldDefinition PrologFields[] = {\n\t{ .name = \"arity\",\n\t  .description = \"the number of parameters\",\n\t  .enabled = true,\n\t  .dataType = FIELDTYPE_INTEGER,\n\t},\n};\n\nstatic xtagDefinition PrologXtags [] = {\n\t{ .enabled     = true,\n\t  .name        = \"arityAppended\",\n\t  .description = \"Include predicates with their arities\",\n\t},\n};\n\nstatic bool prologAllowNestedComments = true;\nstatic bool prologAllowNestedCommentsHandler (const langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\t\t  const char *name, const char *arg)\n{\n\tprologAllowNestedComments = paramParserBool (arg, prologAllowNestedComments, name, \"parameter\");\n\treturn true;\n}\n\nstatic paramDefinition PrologParams [] = {\n\t{ .name = \"allowNestedComments\",\n\t  .desc = \"allow nested comments like \\\"/* /* */ */\\\" ([true] or false)\",\n\t  .handleParam = prologAllowNestedCommentsHandler,\n\t  /* https://www.swi-prolog.org/pldoc/man?section=nestedcomments */\n\t},\n};\n\nstatic struct tokenTypePair prologTypePairs [] = {\n\t{ '(', ')' },\n\t{ '[', ']' },\n\t{ '{', '}' },\n};\n\nstatic const keywordTable PrologKeywords[] = {\n\t{ \"module\", KEYWORD_MODULE },\n};\n\nstatic struct tokenInfoClass prologTokenInfoClass = {\n\t.nPreAlloc = 4,\n\t.typeForUndefined = TOKEN_UNDEFINED,\n\t.keywordNone      = KEYWORD_NONE,\n\t.typeForKeyword   = TOKEN_KEYWORD,\n\t.typeForEOF       = TOKEN_EOF,\n\t.extraSpace       = 0,\n\t.pairs            = prologTypePairs,\n\t.pairCount        = ARRAY_SIZE (prologTypePairs),\n\t.read             = readToken,\n};\n\nstatic langType Lang_prolog;\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic tokenInfo *newPrologToken (void)\n{\n\treturn newToken (&prologTokenInfoClass);\n}\n\nstatic void skipNestedBlockComment (int c)\n{\n\tint depth = 1;\n\n\twhile (c != EOF)\n\t{\n\t\tif (c == '/')\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == '*')\n\t\t\t{\n\t\t\t\t++depth;\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t}\n\t\t}\n\t\telse if (c == '*')\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == '/')\n\t\t\t{\n\t\t\t\tif (--depth == 0)\n\t\t\t\t\treturn;\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tc = getcFromInputFile ();\n\t}\n}\n\nstatic void skipBlockComment (int c)\n{\n\twhile (c != EOF)\n\t{\n\t\tif (c == '*')\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == '/')\n\t\t\t\treturn;\n\t\t}\n\t\telse\n\t\t\tc = getcFromInputFile ();\n\t}\n}\n\nstatic void readString (tokenInfo *const token, int c)\n{\n\tint terminator = c;\n\n\ttokenPutc (token, c);\n\tc = getcFromInputFile ();\n\n\twhile (c != EOF)\n\t{\n\t\ttokenPutc (token, c);\n\n\t\tif (c == '\\\\')\n\t\t{\n\t\t\t/* consume the next char */\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c != EOF)\n\t\t\t{\n\t\t\t\ttokenPutc (token, c);\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (c == terminator)\n\t\t\treturn;\n\n\t\tc = getcFromInputFile ();\n\t}\n}\n\nstatic void readNumber (tokenInfo *const token, int c)\n{\n\tbool dpoint_seen = false;\n\n\ttokenPutc (token, c);\n\tc = getcFromInputFile ();\n\n\twhile (c != EOF)\n\t{\n\t\t// SWI prolog accepts:\n\t\t//\n\t\t//   1_000_000\n\t\t//   1 000 000\n\t\t//   1_000_/*more*/000\n\t\t//\n\t\t// We handle _ here.\n\t\t//\n\t\tif (isdigit (c) || c == '_')\n\t\t{\n\t\t\ttokenPutc (token, c);\n\t\t\tc = getcFromInputFile ();\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (c == '.')\n\t\t{\n\t\t\tif (dpoint_seen)\n\t\t\t{\n\t\t\t\tungetcToInputFile ('.');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdpoint_seen = true;\n\t\t\tint c0 = getcFromInputFile ();\n\t\t\tif (isdigit (c0))\n\t\t\t{\n\t\t\t\ttokenPutc (token, '.');\n\t\t\t\ttokenPutc (token, c0);\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tungetcToInputFile (c0);\n\t\t\tungetcToInputFile ('.');\n\t\t\treturn;\n\t\t}\n\n\t\tungetcToInputFile (c);\n\t\treturn;\n\t}\n}\n\nstatic void readAtom (tokenInfo *const token, int c)\n{\n\ttokenPutc (token, c);\n\tc = getcFromInputFile ();\n\n\twhile (c != EOF)\n\t{\n\t\tif (isalnum (c) || c == '_')\n\t\t{\n\t\t\ttokenPutc (token, c);\n\t\t\tc = getcFromInputFile ();\n\t\t\tcontinue;\n\t\t}\n\n\t\tungetcToInputFile (c);\n\t\treturn;\n\t}\n}\n\nstatic void readToken (tokenInfo *const token, void *data CTAGS_ATTR_UNUSED)\n{\n\tint c;\n\n\ttoken->type = TOKEN_UNDEFINED;\n\ttoken->keyword = KEYWORD_NONE;\n\tvStringClear (token->string);\n\n getNextChar:\n\tdo\n\t\tc = getcFromInputFile ();\n\twhile (c == ' ' || c == '\\t' || c == '\\f' || c == '\\r' || c == '\\n');\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tswitch (c)\n\t{\n\tcase EOF:\n\t\ttoken->type = TOKEN_EOF;\n\t\tbreak;\n\tcase '%':\n\t\tdo\n\t\t\tc = getcFromInputFile ();\n\t\twhile (c != EOF && c != '\\n');\n\t\tgoto getNextChar;\n\tcase '/':\n\t{\n\t\tint c0 = getcFromInputFile ();\n\t\tif (c0 == '*')\n\t\t{\n\t\t\tc0 = getcFromInputFile ();\n\t\t\tif (prologAllowNestedComments)\n\t\t\t\tskipNestedBlockComment (c0);\n\t\t\telse\n\t\t\t\tskipBlockComment (c0);\n\t\t\tgoto getNextChar;\n\t\t}\n\t\tungetcToInputFile (c0);\n\t\ttokenPutc (token, c);\n\t\ttoken->type = c;\n\t\tbreak;\n\t}\n\tcase '\\'':\n\t{\n\t\treadString (token, c);\n\t\ttoken->type = TOKEN_STRATOM;\n\t\tbreak;\n\t}\n\tcase '\"':\n\t{\n\t\treadString (token, c);\n\t\ttoken->type = TOKEN_STRING;\n\t\tbreak;\n\t}\n\n\tcase '(':\n\tcase ')':\n\tcase '{':\n\tcase '}':\n\tcase '[':\n\tcase ']':\n\tcase ',':\n\tcase '.':\n\t\ttokenPutc(token, c);\n\t\ttoken->type = c;\n\t\tbreak;\n\tcase '=':\n\t{\n\t\ttokenPutc(token, c);\n\t\tint c0 = getcFromInputFile ();\n\t\tif (c0 == '.')\n\t\t{\n\t\t\tint c1 = getcFromInputFile ();\n\t\t\tif (c1 == '.')\n\t\t\t{\n\t\t\t\ttokenCatS (token, \"..\");\n\t\t\t\ttoken->type = TOKEN_APPLY;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tungetcToInputFile (c1);\n\t\t}\n\t\tungetcToInputFile (c0);\n\t\ttoken->type = c;\n\t\tbreak;\n\t}\n\tcase ':':\n\t{\n\t\ttokenPutc(token, c);\n\t\tint c0 = getcFromInputFile ();\n\t\tif (c0 == '-')\n\t\t{\n\t\t\ttokenPutc(token, c0);\n\t\t\ttoken->type = TOKEN_RULEOP;\n\t\t\tbreak;\n\t\t}\n\t\tungetcToInputFile (c0);\n\t\ttoken->type = c;\n\t\tbreak;\n\t}\n\tcase '-':\n\t{\n\t\ttokenPutc(token, c);\n\n\t\tint c0 = getcFromInputFile ();\n\t\tif (c0 == '-')\n\t\t{\n\t\t\tint c1 = getcFromInputFile ();\n\t\t\tif (c1 == '>')\n\t\t\t{\n\t\t\t\ttokenCatS (token, \"->\");\n\t\t\t\ttoken->type = TOKEN_DCGOP;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tungetcToInputFile (c1);\n\t\t}\n\t\tungetcToInputFile (c0);\n\t\ttoken->type = c;\n\t\tbreak;\n\t}\n\tdefault:\n\t\tif (c == '0')\n\t\t{\n\t\t\tint c0 = getcFromInputFile ();\n\t\t\tif (c0 == '\\'')\n\t\t\t{\n\t\t\t\ttokenPutc(token, c);\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t\tif (c != EOF)\n\t\t\t\t\ttokenPutc(token, c);\n\n\t\t\t\ttoken->type = TOKEN_CODE;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tungetcToInputFile (c0);\n\t\t\treadNumber (token, c);\n\t\t\ttoken->type = TOKEN_NUM;\n\t\t\treturn;\n\t\t}\n\t\tif (isdigit(c))\n\t\t{\n\t\t\treadNumber (token, c);\n\t\t\ttoken->type = TOKEN_NUM;\n\t\t}\n\t\telse if (c == '_' || ('A' <= c && c <= 'Z'))\n\t\t{\n\t\t\treadAtom (token, c);\n\t\t\ttoken->type = TOKEN_VAR;\n\t\t}\n\t\telse if ('a' <= c && c <= 'z')\n\t\t{\n\t\t\treadAtom (token, c);\n\t\t\ttoken->keyword = lookupKeyword (tokenString (token), Lang_prolog);\n\t\t\ttoken->type = (token->keyword == KEYWORD_NONE)\n\t\t\t\t? TOKEN_ATOM\n\t\t\t\t: TOKEN_KEYWORD;\n\t\t}\n\t\telse if (c == '-')\n\t\t{\n\t\t\ttokenPutc (token, c);\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (isdigit (c))\n\t\t\t{\n\t\t\t\treadNumber (token, c);\n\t\t\t\ttoken->type = TOKEN_NUM;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* I wonder what I should do here? */\n\t\t\t\tungetcToInputFile (c);\n\t\t\t\ttoken->type = TOKEN_ATOM;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttokenPutc (token, c);\n\t\t\tif (c == '\\\\')\n\t\t\t{\n\t\t\t\tint c0 = getcFromInputFile ();\n\t\t\t\tif (c0 != EOF)\n\t\t\t\t\ttokenPutc (token, c0);\n\t\t\t}\n\t\t\ttoken->type = c;\n#if 0\n\t\t\ttokenCatS (token, \" REST :: \");\n\t\t\ttokenCatS (token, getInputFileName ());\n#endif\n\t\t}\n\t\tbreak;\n\t}\n}\n\nstatic void makePrologTagEntry (tokenInfo *const atom, prologKind kindex, int arity,\n\t\t\t\t\t\t\t\tunsigned long endLine, int module)\n{\n\ttagEntryInfo e, ex;\n\tchar arity_str[16];\n\n\ttokenInitTagEntry (atom, &e, kindex);\n\tsetTagEndLine (&e, endLine);\n\te.extensionFields.scopeIndex = module;\n\tsnprintf (arity_str, sizeof (arity_str), \"%d\", arity);\n\tattachParserField (&e, PrologFields[F_ARITY].ftype, arity_str);\n\tmakeTagEntry (&e);\n\n\ttokenPutc (atom, '/');\n\ttokenCatS (atom, arity_str);\n\ttokenInitTagEntry (atom, &ex, kindex);\n\tsetTagEndLine (&ex, endLine);\n\tex.extensionFields.scopeIndex = module;\n\tattachParserField (&ex, PrologFields[F_ARITY].ftype, arity_str);\n\tmarkTagExtraBit (&ex, PrologXtags[X_ARITY].xtype);\n\tmakeTagEntry (&ex);\n}\n\nstatic int parseArguments (tokenInfo *const t)\n{\n\ttokenRead (t);\n\n\tint arity = 0;\n\twhile (!tokenIsEOF (t) && tokenSkipToOneOfTypes (t, true, ',', '(', ')'))\n\t{\n\t\tif (t->type == '(')\n\t\t\ttokenSkipOverPair (t);\n\t\telse\n\t\t{\n\t\t\tarity++;\n\t\t\tif (t->type == ')')\n\t\t\t\tbreak;\n\t\t}\n\t\ttokenRead (t);\n\t}\n\treturn arity;\n}\n\nstatic void deleteBackToken (tokenInfo *t)\n{\n\tif (!tokenIsEOF (t))\n\t\ttokenUnread (t);\n\ttokenDelete (t);\n}\n\nstatic int lookModuleAhead (void)\n{\n\tint r = CORK_NIL;\n\ttokenInfo *openparen = newPrologToken ();\n\n\ttokenRead (openparen);\n\tif (openparen->type == '(')\n\t{\n\t\ttokenInfo *mod = newPrologToken ();\n\t\ttokenRead (mod);\n\t\tif (tokenIsType (mod, ATOM))\n\t\t\tr = tokenMakeSimpleTag (mod, K_MODULE);\n\t\tdeleteBackToken (mod);\n\t}\n\tdeleteBackToken (openparen);\n\n\treturn r;\n}\n\nstatic int lookBodyAhead (void)\n{\n\tint r = CORK_NIL;\n\n\ttokenInfo *modpred = newPrologToken ();\n\n\ttokenRead (modpred);\n\tif (tokenIsKeyword (modpred, MODULE))\n\t\tr = lookModuleAhead ();\n\tdeleteBackToken (modpred);\n\n\treturn r;\n}\n\nstatic int parseClause (tokenInfo *const t, int module)\n{\n\ttokenInfo *atom = NULL;\n\tint arity = 0;\n\n\tif (tokenIsType (t, ATOM)\n\t\t|| tokenIsType (t, STRATOM)\n\t\t|| tokenIsType (t, KEYWORD))\n\t{\n\t\tatom = newPrologToken ();\n\t\ttokenCopy (atom, t);\n\n\t\ttokenRead (t);\n\t\tif (tokenIsEOF (t))\n\t\t{\n\t\t\ttokenDelete (atom);\n\t\t\treturn module;\n\t\t}\n\t\tif (t->type == ':')\n\t\t{\n\t\t\tint chainelt = makeSimpleRefTag (atom->string, K_MODULE, R_MODULE_CHAINELT);\n\t\t\ttokenDelete (atom);\n\t\t\ttokenRead (t);\n\t\t\tparseClause (t, chainelt);\n\t\t\treturn module;\n\t\t}\n\t\telse\n\t\t\ttokenUnread (t);\n\t}\n\telse if (tokenIsType (t, RULEOP))\n\t{\n\t\tint newmod = lookBodyAhead ();\n\t\ttokenSkipToOneOfTypes (t, true, '.');\n\t\tif (newmod != CORK_NIL)\n\t\t\tmodule = newmod;\n\t\treturn module;\n\t}\n\telse\n\t{\n\t\ttokenSkipToOneOfTypes (t, true, '.');\n\t\treturn module;\n\t}\n\n\ttokenRead (t);\n\tif (atom)\n\t{\n\t\tint kindex = K_PREDICATE;\n\n\t\tif (t->type == '(')\n\t\t{\n\t\t\tarity = parseArguments (t);\n\t\t\ttokenRead (t);\n\t\t}\n\n\t\tif (tokenIsType (t, RULEOP)\n\t\t\t|| tokenIsType (t, DCGOP))\n\t\t{\n\t\t\tif (tokenIsType (t, DCGOP))\n\t\t\t\tkindex = K_GRAMMAR;\n\t\t\ttokenSkipToOneOfTypes (t, true, '.');\n\t\t}\n\n\t\tif (t->type == '.')\n\t\t\tmakePrologTagEntry (atom, kindex, arity, t->lineNumber,\n\t\t\t\t\t\t\t\tmodule);\n\n\t\ttokenDelete (atom);\n\t}\n\n\treturn module;\n}\n\nstatic void findPrologTags (void)\n{\n\tint module = CORK_NIL;\n\ttokenInfo *t = newPrologToken ();\n\n\twhile (1)\n\t{\n\t\ttokenRead (t);\n\t\tif (tokenIsEOF (t))\n\t\t\tbreak;\n\t\tmodule = parseClause (t, module);\n\t}\n\n\ttokenDelete (t);\n}\n\nextern void initialize (const langType language)\n{\n\tLang_prolog = language;\n}\n\nextern parserDefinition* PrologParser (void)\n{\n\tstatic const char *const extensions [] = {\"pl\", NULL};\n\n\t/* Interpreters supporting shebang:\n\t *\n\t * + swipl\n\t *   https://www.swi-prolog.org/pldoc/man?section=plscript\n\t * + gprolog\n\t *   http://www.gprolog.org/manual/html_node/gprolog007.html\n\t * + yap\n\t *   https://github.com/search?q=repo%3Avscosta%2Fyap%20%20%22%23!%22&type=code\n\t */\n\tstatic const char *const aliases [] = {\n\t\t\"swipl\",\n\t\t\"gprolog\",\n\t\t\"yap\",\n\t\tNULL\n\t};\n\n\tstatic selectLanguage selectors[] = { selectPerlOrPrologByDistinctiveToken, NULL };\n\n\tparserDefinition* const def = parserNew (\"Prolog\");\n\tdef->initialize     = initialize;\n\tdef->parser         = findPrologTags;\n\tdef->extensions     = extensions;\n\tdef->aliases        = aliases;\n\tdef->selectLanguage = selectors;\n\tdef->keywordTable   = PrologKeywords;\n\tdef->keywordCount   = ARRAY_SIZE(PrologKeywords);\n\tdef->useCork        = CORK_QUEUE;\n\tdef->kindTable      = PrologKinds;\n\tdef->kindCount      = ARRAY_SIZE(PrologKinds);\n\tdef->fieldTable     = PrologFields;\n\tdef->fieldCount     = ARRAY_SIZE(PrologFields);\n\tdef->xtagTable      = PrologXtags;\n\tdef->xtagCount      = ARRAY_SIZE(PrologXtags);\n\tdef->paramTable     = PrologParams;\n\tdef->paramCount     = ARRAY_SIZE(PrologParams);\n\tdef->requestAutomaticFQTag = true;\n\tdef->defaultScopeSeparator = \":\";\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/protobuf.c",
    "content": "/*\n *\n *   Copyright (c) 2011, Ivan Krasilnikov\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module implements parsing of protocol buffers definition files\n *   (http://code.google.com/apis/protocolbuffers/docs/proto.html)\n */\n\n/*\n  Masatake YAMATO takes this from https://sourceforge.net/p/ctags/patches/74/\n  after getting following approval:\n  ===============================================================================\n  Message-ID: <CALPttHe+hSa_kjwx6GoWS6CsDf_OG0bcmhmPahb4shnKb8tkWg@mail.gmail.com>\n  Subject: Re: your protobuf.patch\n  From: Ivan Krasilnikov <infnty@gmail.com>\n  To: m_yamato@users.sf.net\n  Date: Fri, 8 Jul 2016 15:37:07 +0200\n\n  Hi, yes, it's fine, no problem.\n\n  --\n  Ivan\n\n  On 8 July 2016 at 06:31, <m_yamato@users.sf.net> wrote:\n\n  > Hi,\n  >\n  > I am a developer of universal ctags(http://ctags.io).\n  >\n  > I would like to merge your patch for protobuf in *GPL v2 or later*.\n  >\n  > Is it o.k.?\n  > ------------------------------\n  >\n  > This message was sent to you via the SourceForge web mail form.\n  > You may reply to this message directly, or at\n  > https://sourceforge.net/u/userid-2121776/profile/send_message\n  >\n  ===============================================================================\n*/\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#include <ctype.h>\n\n#include \"x-cpreprocessor.h\"\n\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n\n/*\n *   DATA DEFINITIONS\n */\nstatic langType Lang_protobuf;\n\ntypedef enum {\n\tSYNTAX_UNKNOWN,\n\tSYNTAX_PROTO2,\n\tSYNTAX_PROTO3,\n} protobufSyntax;\nstatic protobufSyntax syntax = SYNTAX_UNKNOWN;\n\ntypedef enum {\n\tPK_PACKAGE,\n\tPK_MESSAGE,\n\tPK_FIELD,\n\tPK_ENUMERATOR,\n\tPK_ENUM,\n\tPK_SERVICE,\n\tPK_RPC,\n\tPK_ONEOF,\n\tPK_GROUP,\n\tPK_PROTODEF,\n} protobufKind;\n\ntypedef enum {\n\tR_MESSAGE_EXTENSION,\n} protobufMessageRole;\n\ntypedef enum {\n\tR_PROTODEF_IMPORTED,\n} protobufProtodefRole;\n\nstatic roleDefinition ProtobufMessageRoles [] = {\n\t{ true, \"extension\", \"extending the message\" },\n};\n\nstatic roleDefinition ProtobufProtodefRoles [] = {\n\t{ true, \"imported\", \"imported\" },\n};\n\nstatic kindDefinition ProtobufKinds [] = {\n\t{ true,  'p', \"package\",    \"packages\" },\n\t{ true,  'm', \"message\",    \"messages\",\n\t  .referenceOnly = false, ATTACH_ROLES (ProtobufMessageRoles)},\n\t{ true,  'f', \"field\",      \"fields\" },\n\t{ true,  'e', \"enumerator\", \"enum constants\" },\n\t{ true,  'g', \"enum\",       \"enum types\" },\n\t{ true,  's', \"service\",    \"services\" },\n\t{ true,  'r', \"rpc\",        \"RPC methods\" },\n\t{ true,  'o', \"oneof\",      \"oneof names\" },\n\t{ true,  'G', \"group\",      \"groups\" },\n\t{ true,  'D', \"protodef\",   \".proto definition\",\n\t  .referenceOnly = true, ATTACH_ROLES (ProtobufProtodefRoles)},\n};\n\ntypedef enum eKeywordId {\n\tKEYWORD_OPTION,\n\tKEYWORD_PACKAGE,\n\tKEYWORD_MESSAGE,\n\tKEYWORD_ENUM,\n\tKEYWORD_REPEATED,\n\tKEYWORD_OPTIONAL,\n\tKEYWORD_REQUIRED,\n\tKEYWORD_SERVICE,\n\tKEYWORD_RPC,\n\tKEYWORD_STREAM,\n\tKEYWORD_RETURNS,\n\tKEYWORD_EXTEND,\n\tKEYWORD_ONEOF,\n\tKEYWORD_MAP,\n\tKEYWORD_GROUP,\n\tKEYWORD_IMPORT,\n\tKEYWORD_PUBLIC,\n\tKEYWORD_WEAK,\n\tKEYWORD_SYNTAX,\n} keywordId;\n\nstatic const keywordTable ProtobufKeywordTable [] = {\n\t{ \"option\",   KEYWORD_OPTION   },\n\t{ \"package\",  KEYWORD_PACKAGE  },\n\t{ \"message\",  KEYWORD_MESSAGE  },\n\t{ \"enum\",     KEYWORD_ENUM     },\n\t{ \"repeated\", KEYWORD_REPEATED },\n\t{ \"optional\", KEYWORD_OPTIONAL },\n\t{ \"required\", KEYWORD_REQUIRED },\n\t{ \"service\",  KEYWORD_SERVICE  },\n\t{ \"rpc\",      KEYWORD_RPC      },\n\t{ \"stream\",   KEYWORD_STREAM   },\n\t{ \"returns\",  KEYWORD_RETURNS  },\n\t{ \"extend\",   KEYWORD_EXTEND   },\n\t{ \"oneof\",    KEYWORD_ONEOF    },\n\t{ \"map\",      KEYWORD_MAP      },\n\t{ \"group\",    KEYWORD_GROUP    },\n\t{ \"import\",   KEYWORD_IMPORT   },\n\t{ \"public\",   KEYWORD_PUBLIC   },\n\t{ \"weak\",     KEYWORD_WEAK     },\n\t{ \"syntax\",   KEYWORD_SYNTAX   },\n};\n\n#define TOKEN_EOF   0\n#define TOKEN_ID    'i'\n#define TOKEN_STR   's'\n\nstatic struct sTokenInfo {\n\tint type;         /* one of TOKEN_* constants or punctuation characters */\n\tkeywordId keyword;\n\tvString *value;\n} token;\n\n\n/*\n *   FUNCTION DECLARATIONS\n */\nstatic void findProtobufTags0 (bool oneshot, int originalScopeCorkIndex);\n\n\n/*\n *   FUNCTION DEFINITIONS\n */\n\nstatic void nextTokenFull (bool expectingStringLiteral)\n{\n\tint c;\n\nrepeat:\n\t/*\n\t * .proto files may contain C and C++ style comments and\n\t * quoted strings. cppGetc() takes care of them.\n\t */\n\tc = cppGetc ();\n\n\ttoken.keyword = KEYWORD_NONE;\n\tif (c <= 0)\n\t\ttoken.type = TOKEN_EOF;\n\telse if (c == '{' || c == '}' || c == ';' || c == '.' || c == '=' || c == ',' || c == '<' || c == '>')\n\t\ttoken.type = c;\n\telse if (cppIsalnum (c) || c == '_')\n\t{\n\t\ttoken.type = TOKEN_ID;\n\t\tvStringClear (token.value);\n\t\twhile (c > 0 && (cppIsalnum (c) || c == '_')) {\n\t\t\tvStringPut (token.value, c);\n\t\t\tc = cppGetc ();\n\t\t}\n\t\ttoken.keyword = lookupCaseKeyword (vStringValue (token.value), Lang_protobuf);\n\t\tcppUngetc (c);\n\t}\n\telse if (expectingStringLiteral && c == CPP_STRING_SYMBOL)\n\t{\n\t\ttoken.type = TOKEN_STR;\n\t\tvStringCopy (token.value,\n\t\t\t\t\t cppGetLastCharOrStringContents ());\n\t}\n\telse\n\t\tgoto repeat;  /* anything else is not important for this parser */\n}\n\nstatic void nextToken (void)\n{\n\tnextTokenFull (false);\n}\n\nstatic void skipUntil (const char *punctuation)\n{\n\twhile (token.type != TOKEN_EOF && strchr (punctuation, token.type) == NULL)\n\t\tnextToken ();\n}\n\nstatic void parseFullQualifiedId (vString *buf)\n{\n\twhile (true)\n\t{\n\t\tnextToken ();\n\n\t\tif (token.type == TOKEN_ID)\n\t\t{\n\t\t\tif (vStringIsEmpty (buf) || vStringLast (buf) == '.')\n\t\t\t\tvStringCat (buf, token.value);\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t\telse if (token.type == '.')\n\t\t{\n\t\t\tif (vStringIsEmpty (buf) || vStringLast (buf) != '.')\n\t\t\t\tvStringPut (buf, '.');\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n}\n\nstatic int tokenIsKeyword(keywordId keyword)\n{\n\treturn token.type == TOKEN_ID && token.keyword == keyword;\n}\n\nstatic int createProtobufTagFull (const vString *name, int kind, int role, int scopeCorkIndex)\n{\n\tstatic tagEntryInfo tag;\n\tint corkIndex = CORK_NIL;\n\n\tif (ProtobufKinds [kind].enabled)\n\t{\n\t\tinitRefTagEntry (&tag, vStringValue (name), kind, role);\n\t\ttag.extensionFields.scopeIndex = scopeCorkIndex;\n\t\tcorkIndex = makeTagEntry (&tag);\n\t}\n\n\treturn corkIndex;\n}\n\nstatic int createProtobufTag (const vString *name, int kind, int scopeCorkIndex)\n{\n\treturn createProtobufTagFull (name, kind, ROLE_DEFINITION_INDEX, scopeCorkIndex);\n}\n\nstatic void parseEnumConstants (int scopeCorkIndex)\n{\n\tif (token.type != '{')\n\t\treturn;\n\tnextToken ();\n\n\twhile (token.type != TOKEN_EOF && token.type != '}')\n\t{\n\t\tif (token.type == TOKEN_ID && !tokenIsKeyword (KEYWORD_OPTION))\n\t\t{\n\t\t\tnextToken ();  /* doesn't clear token.value if it's punctuation */\n\t\t\tif (token.type == '=')\n\t\t\t\tcreateProtobufTag (token.value, PK_ENUMERATOR, scopeCorkIndex);\n\t\t}\n\n\t\tskipUntil (\";}\");\n\n\t\tif (token.type == ';')\n\t\t\tnextToken ();\n\t}\n\tsetTagEndLineToCorkEntry (scopeCorkIndex, getInputLineNumber ());\n}\n\nstatic void parseOneofField (int scopeCorkIndex)\n{\n\tif (tokenIsKeyword (KEYWORD_GROUP))\n\t{\n\t\tfindProtobufTags0 (true, scopeCorkIndex);\n\t\treturn;\n\t}\n\n\tvString *type = vStringNewCopy (token.value);\n\tparseFullQualifiedId (type);\n\n\tif (token.type == TOKEN_ID)\n\t{\n\t\tint corkIndex = createProtobufTag (token.value, PK_FIELD, scopeCorkIndex);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\t\tif (e)\n\t\t{\n\t\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\"); /* As C++ parser does */\n\t\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (type);\n\t\t\ttype = NULL;\n\t\t}\n\t}\n\n\tskipUntil (\";}\");\n\tvStringDelete (type);\t\t/* NULL is acceptable */\n}\n\nstatic void parseOneofFields (int scopeCorkIndex)\n{\n\tif (token.type != '{')\n\t\treturn;\n\tnextToken ();\n\n\twhile (token.type != TOKEN_EOF && token.type != '}')\n\t{\n\t\tif (token.type == TOKEN_ID || token.type == '.')\n\t\t{\n\t\t\tparseOneofField (scopeCorkIndex);\n\t\t\tif (token.type == ';')\n\t\t\t\tnextToken ();\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\n\tsetTagEndLineToCorkEntry (scopeCorkIndex, getInputLineNumber ());\n}\n\n#define gatherTypeinfo(VSTRING,CONDITION)\t\t\t\\\n\twhile (CONDITION)\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (token.type == TOKEN_ID)\t\t\t\t\t\\\n\t\t\tvStringCat (VSTRING, token.value);\t\t\\\n\t\telse if (tokenIsKeyword (KEYWORD_STREAM))\t\\\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tvStringCat (VSTRING, token.value);\t\t\\\n\t\t\tvStringPut (VSTRING, ' ');\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\\\n\t\telse\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tvStringPut (VSTRING, token.type);\t\t\\\n\t\tnextToken ();\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void parseRPCTypeinfos (int corkIndex)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\tif (!e)\n\t\treturn;\n\n\tvString *signature = vStringNew ();\n\tgatherTypeinfo(signature,\n\t\t\t\t   (token.type != TOKEN_EOF\n\t\t\t\t\t&& token.type != '{' && token.type != ';'\n\t\t\t\t\t&& !tokenIsKeyword (KEYWORD_RETURNS)));\n\tif (!vStringIsEmpty(signature))\n\t\te->extensionFields.signature = vStringDeleteUnwrap (signature);\n\telse\n\t\tvStringDelete (signature);\n\n\tif (!tokenIsKeyword (KEYWORD_RETURNS))\n\t\treturn;\n\tnextToken ();\n\n\tvString *typeref = vStringNew ();\n\tgatherTypeinfo(typeref, (token.type != EOF\n\t\t\t\t\t\t\t && token.type != '{' && token.type != ';'));\n\tif (!vStringIsEmpty(typeref))\n\t{\n\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\"); /* As C++ parser does */\n\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (typeref);\n\t}\n\telse\n\t\tvStringDelete (typeref);\n}\n\nstatic int parseStatementFull (int kind, int role, int scopeCorkIndex)\n{\n\tint corkIndex = CORK_NIL;\n\tvString *fullName = NULL;\n\tvString *fieldType = NULL;\n\n\tif (kind == PK_FIELD)\n\t{\n\t\tfieldType = vStringNew ();\n\n\t\tif (syntax == SYNTAX_PROTO3\n\t\t\t&& !tokenIsKeyword (KEYWORD_REPEATED))\n\t\t{\n\t\t\tif (token.type == TOKEN_ID)\n\t\t\t\tvStringCat (fieldType, token.value);\n\t\t\telse if (token.type == '.')\n\t\t\t\tvStringPut (fieldType, '.');\n\t\t}\n\n\t\tparseFullQualifiedId (fieldType);\n\t\tif (vStringIsEmpty (fieldType) || vStringLast (fieldType) == '.')\n\t\t\tgoto out;\n\t}\n\telse\n\t\tnextToken ();\n\n\t/* When extending message defined in the external package, the name\n\t * becomes longer. */\n\tif (kind == PK_MESSAGE && role == R_MESSAGE_EXTENSION)\n\t{\n\t\tif (token.type != TOKEN_ID)\n\t\t\tgoto out;\n\n\t\tfullName = vStringNewCopy (token.value);\n\t\tparseFullQualifiedId (fullName);\n\t}\n\telse if (token.type != TOKEN_ID)\n\t\tgoto out;\n\n\tcorkIndex = createProtobufTagFull (fullName? fullName: token.value,\n\t\t\t\t\t\t\t\t\t   kind, role, scopeCorkIndex);\n\n\tif (!fullName)\n\t\tnextToken ();\n\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\tif (fieldType && e)\n\t{\n\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\"); /* As C++ parser does */\n\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (fieldType);\n\t\tfieldType = NULL;\n\t}\n\n\tif (kind == PK_RPC && corkIndex != CORK_NIL)\n\t\tparseRPCTypeinfos (corkIndex);\n\n\tif (kind == PK_ENUM)\n\t\tparseEnumConstants (corkIndex);\n\telse if (kind == PK_ONEOF)\n\t\tparseOneofFields (corkIndex);\n\n out:\n\tvStringDelete (fieldType);\t/* NULL is acceptable. */\n\tvStringDelete (fullName);\t/* NULL is acceptable. */\n\treturn corkIndex;\n}\n\nstatic int parseStatement (int kind, int scopeCorkIndex)\n{\n\treturn parseStatementFull (kind, ROLE_DEFINITION_INDEX, scopeCorkIndex);\n}\n\nstatic int parsePackage (void)\n{\n\tint corkIndex = CORK_NIL;\n\n\tvString *pkg = vStringNew ();\n\tparseFullQualifiedId (pkg);\n\tif (vStringLength (pkg) > 0)\n\t\tcorkIndex = createProtobufTag (pkg, PK_PACKAGE, CORK_NIL);\n\tvStringDelete (pkg);\n\n\treturn corkIndex;\n}\n\nstatic void parseMap (int scopeCorkIndex)\n{\n\tnextToken ();\n\tif (token.type != '<')\n\t\treturn;\n\n\tvString *typeref = vStringNewInit (\"map<\");\n\n\tnextToken ();\n\tif (token.type != TOKEN_ID)\n\t\tgoto out;\n\n\tvStringCat (typeref, token.value);\n\n\tnextToken ();\n\tif (token.type != ',')\n\t\tgoto out;\n\tvStringPut (typeref, ',');\n\n\tvString *vtyperef = vStringNew ();\n\tparseFullQualifiedId (vtyperef);\n\tvStringCat (typeref, vtyperef);\n\tvStringDelete (vtyperef);\n\tif (vStringLast (typeref) == ',')\n\t\tgoto out;\n\n\tif (token.type != '>')\n\t\tgoto out;\n\tvStringPut (typeref, '>');\n\n\tnextToken ();\n\tif (token.type != TOKEN_ID)\n\t\tgoto out;\n\n\tint corkIndex = createProtobufTag (token.value, PK_FIELD, scopeCorkIndex);\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\tif (e)\n\t{\n\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\"); /* As C++ parser does */\n\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (typeref);\n\t\ttyperef = NULL;\n\t}\n\n out:\n\tvStringDelete (typeref);\n}\n\nstatic int parseImport (int scopeCorkIndex)\n{\n\tnextTokenFull (true);\n\tif (token.type == TOKEN_ID)\n\t{\n\t\tif (tokenIsKeyword (KEYWORD_PUBLIC)\n\t\t\t|| tokenIsKeyword (KEYWORD_WEAK))\n\t\t\tnextTokenFull (true);\n\t\telse\n\t\t\treturn CORK_NIL;\t/* Unexpected */\n\t}\n\n\tif (token.type == TOKEN_STR)\n\t\treturn createProtobufTagFull (token.value,\n\t\t\t\t\t\t\t\t\t  PK_PROTODEF, R_PROTODEF_IMPORTED,\n\t\t\t\t\t\t\t\t\t  /* TODO: whether the package scope should be specified or not. */\n\t\t\t\t\t\t\t\t\t  scopeCorkIndex\n\t\t\t);\n\n\treturn CORK_NIL;\n}\n\nstatic void parseSyntax (void)\n{\n\tnextToken ();\n\tif (token.type != '=')\n\t\treturn;\n\n\tnextTokenFull (true);\n\tif (token.type == TOKEN_STR)\n\t{\n\t\tconst vString *proto = token.value;\n\t\tif (strcmp (vStringValue (proto), \"proto2\") == 0)\n\t\t\tsyntax = SYNTAX_PROTO2;\n\t\telse if (strcmp (vStringValue (proto), \"proto3\") == 0)\n\t\t\tsyntax = SYNTAX_PROTO3;\n\t\telse\n\t\t\tsyntax = SYNTAX_UNKNOWN;\n\t}\n}\n\nstatic void findProtobufTags0 (bool oneshot, int originalScopeCorkIndex)\n{\n\tint scopeCorkIndex = originalScopeCorkIndex;\n\twhile (token.type != TOKEN_EOF)\n\t{\n\t\tint corkIndex = CORK_NIL;\n\t\tbool dontChangeScope = false;\n\n\t\tif (tokenIsKeyword (KEYWORD_SYNTAX) && originalScopeCorkIndex == CORK_NIL)\n\t\t{\n\t\t\tparseSyntax ();\n\t\t\tdontChangeScope = true;\n\t\t}\n\t\telse if (tokenIsKeyword (KEYWORD_PACKAGE))\n\t\t{\n\t\t\tcorkIndex = parsePackage ();\n\t\t\tscopeCorkIndex = corkIndex;\n\t\t}\n\t\telse if (tokenIsKeyword (KEYWORD_MESSAGE))\n\t\t\tcorkIndex = parseStatement (PK_MESSAGE, scopeCorkIndex);\n\t\telse if (tokenIsKeyword (KEYWORD_ENUM))\n\t\t{\n\t\t\tcorkIndex = parseStatement (PK_ENUM, scopeCorkIndex);\n\t\t\tdontChangeScope = true;\n\t\t}\n\t\telse if (tokenIsKeyword (KEYWORD_REPEATED) || tokenIsKeyword (KEYWORD_OPTIONAL) || tokenIsKeyword (KEYWORD_REQUIRED))\n\t\t\tcorkIndex = parseStatement (PK_FIELD, scopeCorkIndex);\n\t\telse if (tokenIsKeyword (KEYWORD_SERVICE))\n\t\t\tcorkIndex = parseStatement (PK_SERVICE, scopeCorkIndex);\n\t\telse if (tokenIsKeyword (KEYWORD_RPC))\n\t\t\tcorkIndex = parseStatement (PK_RPC, scopeCorkIndex);\n\t\telse if (tokenIsKeyword (KEYWORD_EXTEND))\n\t\t\tcorkIndex = parseStatementFull (PK_MESSAGE, R_MESSAGE_EXTENSION, scopeCorkIndex);\n\t\telse if (tokenIsKeyword (KEYWORD_ONEOF))\n\t\t{\n\t\t\tcorkIndex = parseStatement (PK_ONEOF, scopeCorkIndex);\n\t\t\tdontChangeScope = true;\n\t\t}\n\t\telse if (tokenIsKeyword (KEYWORD_MAP))\n\t\t\tparseMap (scopeCorkIndex);\n\t\telse if (tokenIsKeyword (KEYWORD_GROUP))\n\t\t\tcorkIndex = parseStatement (PK_GROUP, scopeCorkIndex);\n\t\telse if (tokenIsKeyword (KEYWORD_IMPORT))\n\t\t{\n\t\t\tcorkIndex = parseImport (scopeCorkIndex);\n\t\t\tdontChangeScope = true;\n\t\t}\n\t\telse if (tokenIsKeyword (KEYWORD_OPTION))\n\t\t\tdontChangeScope = true;\n\t\telse if (syntax == SYNTAX_PROTO3\n\t\t\t\t && (token.type == '.' || token.type == TOKEN_ID))\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (scopeCorkIndex);\n\t\t\tif (e && e->kindIndex == PK_MESSAGE)\n\t\t\t\tcorkIndex = parseStatement (PK_FIELD, scopeCorkIndex);\n\t\t}\n\n\t\tskipUntil (\";{}\");\n\t\tif (!dontChangeScope && token.type == '{' && corkIndex != CORK_NIL)\n\t\t{\n\t\t\t/* Enter the new scope. */\n\t\t\tscopeCorkIndex = corkIndex;\n\t\t}\n\t\telse if (!dontChangeScope && token.type == '}')\n\t\t{\n\t\t\t/* Return to the parent scope. */\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (scopeCorkIndex);\n\t\t\tif (e)\n\t\t\t{\n\t\t\t\tscopeCorkIndex = e->extensionFields.scopeIndex;\n\t\t\t\tsetTagEndLine (e, getInputLineNumber ());\n\t\t\t}\n\t\t}\n\t\tnextToken ();\n\n\t\tif (oneshot && scopeCorkIndex == originalScopeCorkIndex)\n\t\t\tbreak;\n\t}\n}\n\nstatic void findProtobufTags (void)\n{\n\tcppInit (false, false, false, false,\n\t\t\t KIND_GHOST_INDEX, 0, 0,\n\t\t\t KIND_GHOST_INDEX,\n\t\t\t KIND_GHOST_INDEX, 0, 0,\n\t\t\t FIELD_UNKNOWN);\n\ttoken.value = vStringNew ();\n\n\tsyntax = SYNTAX_UNKNOWN;\n\n\tnextToken ();\n\tfindProtobufTags0 (false, CORK_NIL);\n\n\tvStringDelete (token.value);\n\tcppTerminate ();\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_protobuf = language;\n}\n\nextern parserDefinition* ProtobufParser (void)\n{\n\tstatic const char *const extensions [] = { \"proto\", NULL };\n\tparserDefinition* def = parserNew (\"Protobuf\");\n\n\tdef->extensions = extensions;\n\tdef->kindTable      = ProtobufKinds;\n\tdef->initialize = initialize;\n\tdef->kindCount  = ARRAY_SIZE (ProtobufKinds);\n\tdef->parser     = findProtobufTags;\n\tdef->keywordTable = ProtobufKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (ProtobufKeywordTable);\n\n\t/* cpreprocessor wants corkQueue. */\n\tdef->useCork    = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/python-entry-points.c",
    "content": "/*\n *   python-entry-points.c\n *\n *   Copyright (c) 2025, Masatake YAMATO\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for config files of\n *   Python's entry_points.txt file.\n *\n *   https://packaging.python.org/en/latest/specifications/entry-points/\n *\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"x-iniconf.h\"\n#include \"x-python.h\"\n\n#include <string.h>\n\n/*\n*   DATA DECLARATIONS\n*/\nstruct sPythonEntryPointsSubparser {\n\tiniconfSubparser iniconf;\n};\n\ntypedef enum {\n\tK_CONSOLE,\n\tK_GUI,\n\tCOUNT_KINDS\t\t\t\t\t/* must be last */\n} pythonEntryPointsKind;\n\ntypedef enum {\n\tKEY_UNDEFINED = -1,\n\tKEY_CONSOLE_SCRIPTS,\n\tKEY_GUI_SCRIPTS,\n} pythonEntryPointsKeyword;\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic kindDefinition PythonEntryPointsKinds [COUNT_KINDS] = {\n\t{ true, 'c', \"console\", \"entry points of console_scripts\" },\n\t{ true, 'g', \"gui\", \"entry points of gui_scripts\" },\n};\n\nstatic const keywordTable PythonEntryPointsKeywords [] = {\n\t{ \"console_scripts\", KEY_CONSOLE_SCRIPTS },\n\t{ \"gui_scripts\", KEY_GUI_SCRIPTS },\n};\n\nstatic langType Lang_python;\t/* For making foreign tags */\n\n/*\n* FUNCTION DEFINITIONS\n*/\nstatic void newDataCallback (iniconfSubparser *iniconf,\n\t\t\t\t\t\t\t const char *section, const char *key, const char *value)\n{\n\tif (!section)\n\t\treturn;\n\tif (!key)\n\t\treturn;\n\n\tint kind;\n\tlangType lang = getSubparserLanguage (&iniconf->subparser);\n\tswitch (lookupKeyword (section, lang))\n\t{\n\tcase KEY_CONSOLE_SCRIPTS:\n\t\tkind = K_CONSOLE;\n\t\tbreak;\n\tcase KEY_GUI_SCRIPTS:\n\t\tkind = K_GUI;\n\t\tbreak;\n\tdefault:\n\t\treturn;\n\t}\n\n\ttagEntryInfo e;\n\tinitTagEntry (&e, key, kind);\n\tmakeTagEntry (&e);\n\n\tif (!value)\n\t\treturn;\n\n\tchar *sep = strrchr (value, ':');\n\tif (sep)\n\t\t*sep = '\\0';\n\n\tinitForeignRefTagEntry (&e, value, Lang_python,\n\t\t\t\t\t\t\tPYTHON_MODULE_KIND, PYTHON_MODULE_ENTRY_POINT);\n\tint mod = makeTagEntry (&e);\n\n\tif (sep && sep[1])\n\t{\n\t\tinitForeignRefTagEntry (&e, sep + 1, Lang_python,\n\t\t\t\t\t\t\t\tPYTHON_FUNCTION_KIND, PYTHON_FUNCTION_ENTRY_POINT);\n\t\te.extensionFields.scopeIndex = mod;\n\t\tmakeTagEntry (&e);\n\t}\n\n\tif (sep)\n\t\t*sep = ':';\n}\n\nstatic void findPythonEntryPointsTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* PythonEntryPointsParser (void)\n{\n\tstatic const char *const patterns [] = { \"entry_points.txt\", NULL };\n\tstatic struct sPythonEntryPointsSubparser pythonEntryPointsSubparser = {\n\t\t.iniconf = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t\t},\n\t\t\t.newDataNotify = newDataCallback,\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Iniconf\", &pythonEntryPointsSubparser },\n\t\t[1] = { DEPTYPE_FOREIGNER, \"Python\",  &Lang_python },\n\t};\n\n\tparserDefinition* const def = parserNew (\"PythonEntryPoints\");\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->patterns   = patterns;\n\n\tdef->kindTable = PythonEntryPointsKinds;\n\tdef->kindCount  = ARRAY_SIZE (PythonEntryPointsKinds);\n\n\tdef->keywordTable = PythonEntryPointsKeywords;\n\tdef->keywordCount = ARRAY_SIZE (PythonEntryPointsKeywords);\n\n\tdef->parser = findPythonEntryPointsTags;\n\tdef->useCork    = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/python-logging-config.c",
    "content": "/*\n *   python-logging-config.c\n *\n *   Copyright (c) 2016, Masatake YAMATO <yamato@redhat.com>\n *   Copyright (c) 2016, Red Hat, K.K.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for config files of\n *   python's logging.config module.\n *\n *   https://docs.python.org/2/library/logging.config.html\n *\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"x-iniconf.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include <string.h>\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_LOGGER_SECTION,\n\tK_LOGGER_QUALNAME,\n} pythonLoggingConfigKind;\n\nstatic kindDefinition PythonLoggingConfigKinds [] = {\n\t{ true, 'L', \"loggerSection\", \"logger sections\" },\n\t{ true, 'q', \"qualname\",      \"logger qualnames\" },\n};\n\n#define LOGGER_PREFIX \"logger_\"\n#define LOGGER_LEN (sizeof(\"logger_\") - 1)\n\nstruct sPythonLoggingConfigSubparser {\n\tiniconfSubparser iniconf;\n\tint index;\n};\n\nstatic void newDataCallback (iniconfSubparser *iniconf,\n\t\t\t\t\t\t\t const char *section, const char *key, const char *value)\n{\n\ttagEntryInfo e;\n\n\tif (section && (strncmp (LOGGER_PREFIX, section, LOGGER_LEN) == 0))\n\t{\n\t\tif (key == NULL && value == NULL)\n\t\t{\n\t\t\tconst char *logger = section + LOGGER_LEN;\n\t\t\tif (logger [0] == '\\0')\n\t\t\t\tgoto out;\n\n\t\t\tinitTagEntry (&e, logger, K_LOGGER_SECTION);\n\t\t\t((struct sPythonLoggingConfigSubparser *)iniconf)->index = makeTagEntry (&e);\n\t\t}\n\t\telse if (key && (strcmp (key, \"qualname\") == 0)\n\t\t\t && value && value[0] != '\\0')\n\t\t{\n\t\t\tinitTagEntry (&e, value, K_LOGGER_QUALNAME);\n\t\t\te.extensionFields.scopeIndex = ((struct sPythonLoggingConfigSubparser*)iniconf)->index;\n\t\t\tmakeTagEntry (&e);\n\t\t}\n\t}\n\nout:\n\treturn;\n}\n\nstatic bool probeLanguage (const char *section, const char *key CTAGS_ATTR_UNUSED, const char *value CTAGS_ATTR_UNUSED)\n{\n\tif (section && (strncmp (LOGGER_PREFIX, section, LOGGER_LEN) == 0))\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\n\nstatic void exclusiveSubparserChosenCallback (subparser *s, void *data CTAGS_ATTR_UNUSED)\n{\n\t((struct sPythonLoggingConfigSubparser *)s)->index = CORK_NIL;\n}\n\nstatic void findPythonLoggingConfigTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* PythonLoggingConfigParser (void)\n{\n\tstatic struct sPythonLoggingConfigSubparser pythonLoggingConfigSubparser = {\n\t\t.iniconf = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t\t\t.exclusiveSubparserChosenNotify = exclusiveSubparserChosenCallback,\n\t\t\t},\n\t\t\t.probeLanguage = probeLanguage,\n\t\t\t.newDataNotify = newDataCallback,\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Iniconf\", &pythonLoggingConfigSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"PythonLoggingConfig\");\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable      = PythonLoggingConfigKinds;\n\tdef->kindCount  = ARRAY_SIZE (PythonLoggingConfigKinds);\n\tdef->parser     = findPythonLoggingConfigTags;\n\tdef->useCork    = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/python.c",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*   Copyright (c) 2014-2016, Colomban Wendling <ban@herbesfolles.org>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Python language\n*   files.\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"nestlevel.h\"\n#include \"read.h\"\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"keyword.h\"\n#include \"routines.h\"\n#include \"debug.h\"\n#include \"xtag.h\"\n#include \"objpool.h\"\n#include \"ptrarray.h\"\n#include \"trace.h\"\n\n#include \"x-python.h\"\n\n#define isIdentifierChar(c) \\\n\t(isalnum (c) || (c) == '_' || (c) >= 0x80)\n#define newToken() (objPoolGet (TokenPool))\n#define deleteToken(t) (objPoolPut (TokenPool, (t)))\n\n/* A token holding a soft keyword\n * has TOKEN_IDENTIFIER as its type member and\n * SOFT_KEYWORD_* as its keyword member.\n */\n#define isSoftKeyword(K) (K < 0 && K != KEYWORD_NONE)\nenum {\n\tSOFT_KEYWORD_type = -2,\n\t/* KEYWORD_NONE occupies -1. */\n\tKEYWORD_as = 0,\n\tKEYWORD_async,\n\tKEYWORD_cdef,\n\tKEYWORD_class,\n\tKEYWORD_cpdef,\n\tKEYWORD_def,\n\tKEYWORD_extern,\n\tKEYWORD_from,\n\tKEYWORD_import,\n\tKEYWORD_inline,\n\tKEYWORD_lambda,\n\tKEYWORD_pass,\n\tKEYWORD_return,\n\tKEYWORD_REST\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum {\n\tACCESS_PRIVATE,\n\tACCESS_PROTECTED,\n\tACCESS_PUBLIC,\n\tCOUNT_ACCESS\n} accessType;\n\nstatic const char *const PythonAccesses[COUNT_ACCESS] = {\n\t\"private\",\n\t\"protected\",\n\t\"public\"\n};\n\ntypedef enum {\n\tF_DECORATORS,\n\tF_NAMEREF,\n\tCOUNT_FIELD\n} pythonField;\n\nstatic fieldDefinition PythonFields[COUNT_FIELD] = {\n\t{ .name = \"decorators\",\n\t  .description = \"decorators on functions and classes\",\n\t  .enabled = false },\n\t{ .name = \"nameref\",\n\t  .description = \"the original name for the tag\",\n\t  .enabled = true },\n};\n\ntypedef enum {\n\tPYTHON_UNKNOWN_IMPORTED,\n\tPYTHON_UNKNOWN_INDIRECTLY_IMPORTED,\n} pythonUnknownRole;\n\n/* Roles related to `import'\n * ==========================\n * import X              X = (kind:module, role:imported)\n *\n * import X as Y         X = (kind:module, role:indirectlyImported),\n *                       Y = (kind:namespace, nameref:module:X)\n *                       ------------------------------------------------\n *                       Don't confuse the kind of Y with namespace role of module kind.\n *\n * from X import *       X = (kind:module,  role:namespace)\n *\n * from X import Y       X = (kind:module,  role:namespace),\n *                       Y = (kind:unknown, role:imported, scope:module:X)\n *\n * from X import Y as Z  X = (kind:module,  role:namespace),\n *                       Y = (kind:unknown, role:indirectlyImported, scope:module:X)\n *                       Z = (kind:unknown, nameref:unknown:Y) */\n\nstatic roleDefinition PythonModuleRoles [] = {\n\t{ true, \"imported\",\n\t  \"imported modules\" },\n\t{ true, \"namespace\",\n\t  \"namespace from where classes/variables/functions are imported\" },\n\t{ true, \"indirectlyImported\",\n\t  \"module imported in alternative name\" },\n\t{ true, \"entryPoint\",\n\t  \"specified as a module of an entry point\",\n\t  .version = 1 },\n};\n\nstatic roleDefinition PythonUnknownRoles [] = {\n\t{ true, \"imported\",   \"imported from the other module\" },\n\t{ true, \"indirectlyImported\",\n\t  \"classes/variables/functions/modules imported in alternative name\" },\n};\n\nstatic roleDefinition PythonFunctionRoles [] = {\n\t{ true, \"entryPoint\",\n\t  \"specified as an entry point\",\n\t  .version = 1 },\n};\n\nstatic kindDefinition PythonKinds[PYTHON_COUNT_KIND] = {\n\t{true, 'c', \"class\",    \"classes\"},\n\t{true, 'f', \"function\", \"functions\",\n\t .referenceOnly = false, ATTACH_ROLES(PythonFunctionRoles) },\n\t{true, 'm', \"member\",   \"class members\"},\n\t{true, 'v', \"variable\", \"variables\"},\n\t{true, 'I', \"namespace\", \"name referring a module defined in other file\"},\n\t{true, 'i', \"module\",    \"modules\",\n\t .referenceOnly = true,  ATTACH_ROLES(PythonModuleRoles)},\n\t{true, 'Y', \"unknown\",   \"name referring a class/variable/function/module defined in other module\",\n\t .referenceOnly = false, ATTACH_ROLES(PythonUnknownRoles)},\n\t{false, 'z', \"parameter\", \"function parameters\" },\n\t{false, 'l', \"local\",    \"local variables\" },\n};\n\nstatic const keywordTable PythonKeywordTable[] = {\n\t/* keyword\t\t\tkeyword ID */\n\t{ \"as\",\t\t\t\tKEYWORD_as\t\t\t\t},\n\t{ \"async\",\t\t\tKEYWORD_async\t\t\t},\n\t{ \"cdef\",\t\t\tKEYWORD_cdef\t\t\t},\n\t{ \"cimport\",\t\tKEYWORD_import\t\t\t},\n\t{ \"class\",\t\t\tKEYWORD_class\t\t\t},\n\t{ \"cpdef\",\t\t\tKEYWORD_cpdef\t\t\t},\n\t{ \"def\",\t\t\tKEYWORD_def\t\t\t\t},\n\t{ \"extern\",\t\t\tKEYWORD_extern\t\t\t},\n\t{ \"from\",\t\t\tKEYWORD_from\t\t\t},\n\t{ \"import\",\t\t\tKEYWORD_import\t\t\t},\n\t{ \"inline\",\t\t\tKEYWORD_inline\t\t\t},\n\t{ \"lambda\",\t\t\tKEYWORD_lambda\t\t\t},\n\t{ \"pass\",\t\t\tKEYWORD_pass\t\t\t},\n\t{ \"return\",\t\t\tKEYWORD_return\t\t\t},\n\t{ \"type\",\t\t\tSOFT_KEYWORD_type\t\t},\n};\n\n/* Taken from https://docs.python.org/3/reference/lexical_analysis.html#keywords */\nstatic const struct keywordGroup PythonRestKeywords = {\n\t.value = KEYWORD_REST,\n\t.addingUnlessExisting = true,\n\t.keywords = {\n\t\t\"False\",      \"await\",      \"else\",       \"import\",     \"pass\",\n\t\t\"None\",       \"break\",      \"except\",     \"in\",         \"raise\",\n\t\t\"True\",       \"class\",      \"finally\",    \"is\",         \"return\",\n\t\t\"and\",        \"continue\",   \"for\",        \"lambda\",     \"try\",\n\t\t\"as\",         \"def\",        \"from\",       \"nonlocal\",   \"while\",\n\t\t\"assert\",     \"del\",        \"global\",     \"not\",        \"with\",\n\t\t\"async\",      \"elif\",       \"if\",         \"or\",         \"yield\",\n\t\tNULL\n\t},\n};\n\ntypedef enum eTokenType {\n\t/* 0..255 are the byte's value */\n\tTOKEN_EOF = 256,\n\tTOKEN_UNDEFINED,\n\tTOKEN_INDENT,\n\tTOKEN_KEYWORD,\n\tTOKEN_OPERATOR,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n\tTOKEN_ARROW,\t\t\t\t/* -> */\n\tTOKEN_WHITESPACE,\n} tokenType;\n\ntypedef struct {\n\tint\t\t\t\ttype;\n\tkeywordId\t\tkeyword;\n\tvString *\t\tstring;\n\tint\t\t\t\tindent;\n\tunsigned long \tlineNumber;\n\tMIOPos\t\t\tfilePosition;\n} tokenInfo;\n\nstruct pythonNestingLevelUserData {\n\tint indentation;\n};\n#define PY_NL(nl) ((struct pythonNestingLevelUserData *) nestingLevelGetUserData (nl))\n\nstatic langType Lang_python;\nstatic unsigned int TokenContinuationDepth = 0;\nstatic tokenInfo *NextToken = NULL;\nstatic NestingLevels *PythonNestingLevels = NULL;\nstatic objPool *TokenPool = NULL;\n\n\n/* follows PEP-8, and always reports single-underscores as protected\n * See:\n * - http://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables\n * - http://www.python.org/dev/peps/pep-0008/#designing-for-inheritance\n */\nstatic accessType accessFromIdentifier (const vString *const ident,\n                                        pythonKind kind, int parentKind)\n{\n\tconst char *const p = vStringValue (ident);\n\tconst size_t len = vStringLength (ident);\n\n\t/* inside a function/method, private */\n\tif (parentKind != -1 && parentKind != PYTHON_CLASS_KIND)\n\t\treturn ACCESS_PRIVATE;\n\t/* not starting with \"_\", public */\n\telse if (len < 1 || p[0] != '_')\n\t\treturn ACCESS_PUBLIC;\n\t/* \"__...__\": magic methods */\n\telse if (kind == PYTHON_FUNCTION_KIND && parentKind == PYTHON_CLASS_KIND &&\n\t         len > 3 && p[1] == '_' && p[len - 2] == '_' && p[len - 1] == '_')\n\t\treturn ACCESS_PUBLIC;\n\t/* \"__...\": name mangling */\n\telse if (parentKind == PYTHON_CLASS_KIND && len > 1 && p[1] == '_')\n\t\treturn ACCESS_PRIVATE;\n\t/* \"_...\": suggested as non-public, but easily accessible */\n\telse\n\t\treturn ACCESS_PROTECTED;\n}\n\nstatic void initPythonEntry (tagEntryInfo *const e, const tokenInfo *const token,\n                             const pythonKind kind)\n{\n\taccessType access;\n\tint parentKind = -1;\n\tNestingLevel *nl;\n\n\tinitTagEntry (e, vStringValue (token->string), kind);\n\n\tupdateTagLine (e, token->lineNumber, token->filePosition);\n\n\tnl = nestingLevelsGetCurrent (PythonNestingLevels);\n\tif (nl)\n\t{\n\t\ttagEntryInfo *nlEntry = getEntryOfNestingLevel (nl);\n\n\t\te->extensionFields.scopeIndex = nl->corkIndex;\n\n\t\t/* nlEntry can be NULL if a kind was disabled.  But what can we do\n\t\t * here?  Even disabled kinds should count for the hierarchy I\n\t\t * guess -- as it'd otherwise be wrong -- but with cork we're\n\t\t * fucked up as there's nothing to look up.  Damn. */\n\t\tif (nlEntry)\n\t\t{\n\t\t\tparentKind = nlEntry->kindIndex;\n\n\t\t\t/* functions directly inside classes are methods, fix it up */\n\t\t\tif (kind == PYTHON_FUNCTION_KIND && parentKind == PYTHON_CLASS_KIND)\n\t\t\t\te->kindIndex = PYTHON_METHOD_KIND;\n\t\t}\n\t}\n\n\taccess = accessFromIdentifier (token->string, kind, parentKind);\n\te->extensionFields.access = PythonAccesses[access];\n\t/* FIXME: should we really set isFileScope in addition to access? */\n\tif (access == ACCESS_PRIVATE)\n\t\te->isFileScope = true;\n}\n\nstatic int makeClassTag (const tokenInfo *const token,\n                         const vString *const inheritance,\n                         const vString *const decorators)\n{\n\tif (PythonKinds[PYTHON_CLASS_KIND].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitPythonEntry (&e, token, PYTHON_CLASS_KIND);\n\n\t\te.extensionFields.inheritance = inheritance ? vStringValue (inheritance) : \"\";\n\t\tif (decorators && vStringLength (decorators) > 0)\n\t\t{\n\t\t\tattachParserField (&e, PythonFields[F_DECORATORS].ftype,\n\t\t\t                   vStringValue (decorators));\n\t\t}\n\n\t\treturn makeTagEntry (&e);\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic int makeFunctionTag (const tokenInfo *const token,\n                            const vString *const arglist,\n                            const vString *const decorators)\n{\n\tif (PythonKinds[PYTHON_FUNCTION_KIND].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitPythonEntry (&e, token, PYTHON_FUNCTION_KIND);\n\n\t\tif (arglist)\n\t\t\te.extensionFields.signature = vStringValue (arglist);\n\t\tif (decorators && vStringLength (decorators) > 0)\n\t\t{\n\t\t\tattachParserField (&e, PythonFields[F_DECORATORS].ftype,\n\t\t\t                   vStringValue (decorators));\n\t\t}\n\n\t\treturn makeTagEntry (&e);\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic int makeSimplePythonTag (const tokenInfo *const token, pythonKind const kind)\n{\n\tif (PythonKinds[kind].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitPythonEntry (&e, token, kind);\n\t\treturn makeTagEntry (&e);\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic int makeSimplePythonRefTag (const tokenInfo *const token,\n                                   const vString *const altName,\n                                   pythonKind const kind,\n                                   int roleIndex, xtagType xtag)\n{\n\tif (isXtagEnabled (XTAG_REFERENCE_TAGS) &&\n\t    PythonKinds[kind].roles[roleIndex].enabled)\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitRefTagEntry (&e, vStringValue (altName ? altName : token->string),\n\t\t                 kind, roleIndex);\n\n\t\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\n\t\tif (xtag != XTAG_UNKNOWN)\n\t\t\tmarkTagExtraBit (&e, xtag);\n\n\t\treturn makeTagEntry (&e);\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic void *newPoolToken (void *createArg CTAGS_ATTR_UNUSED)\n{\n\ttokenInfo *token = xMalloc (1, tokenInfo);\n\ttoken->string = vStringNew ();\n\treturn token;\n}\n\nstatic void deletePoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\tvStringDelete (token->string);\n\teFree (token);\n}\n\nstatic void clearPoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->indent\t\t= 0;\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\tvStringClear (token->string);\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const src)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tdest->keyword = src->keyword;\n\tdest->indent = src->indent;\n\tvStringCopy(dest->string, src->string);\n}\n\n/* Skip a single or double quoted string. */\nstatic void readString (vString *const string, const int delimiter)\n{\n\tint escaped = 0;\n\tint c;\n\n\twhile ((c = getcFromInputFile ()) != EOF)\n\t{\n\t\tif (escaped)\n\t\t{\n\t\t\tvStringPut (string, c);\n\t\t\tescaped--;\n\t\t}\n\t\telse if (c == '\\\\')\n\t\t\tescaped++;\n\t\telse if (c == delimiter || c == '\\n' || c == '\\r')\n\t\t{\n\t\t\tif (c != delimiter)\n\t\t\t\tungetcToInputFile (c);\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\n/* Skip a single or double triple quoted string. */\nstatic void readTripleString (vString *const string, const int delimiter)\n{\n\tint c;\n\tint escaped = 0;\n\tint n = 0;\n\twhile ((c = getcFromInputFile ()) != EOF)\n\t{\n\t\tif (c == delimiter && ! escaped)\n\t\t{\n\t\t\tif (++n >= 3)\n\t\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (; n > 0; n--)\n\t\t\t\tvStringPut (string, delimiter);\n\t\t\tif (c != '\\\\' || escaped)\n\t\t\t\tvStringPut (string, c);\n\t\t\tn = 0;\n\t\t}\n\n\t\tif (escaped)\n\t\t\tescaped--;\n\t\telse if (c == '\\\\')\n\t\t\tescaped++;\n\t}\n}\n\nstatic void readIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t}\n\twhile (isIdentifierChar (c));\n\tungetcToInputFile (c);\n}\n\nstatic void ungetToken (tokenInfo *const token)\n{\n\tAssert (NextToken == NULL);\n\tNextToken = newToken ();\n\tcopyToken (NextToken, token);\n}\n\nstatic void readTokenFull (tokenInfo *const token, bool inclWhitespaces)\n{\n\tint c;\n\tint n;\n\n\t/* if we've got a token held back, emit it */\n\tif (NextToken)\n\t{\n\t\tcopyToken (token, NextToken);\n\t\tdeleteToken (NextToken);\n\t\tNextToken = NULL;\n\t\treturn;\n\t}\n\n\ttoken->type\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tn = 0;\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\tn++;\n\t}\n\twhile (c == ' ' || c == '\\t' || c == '\\f');\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tif (inclWhitespaces && n > 1 && c != '\\r' && c != '\\n')\n\t{\n\t\tungetcToInputFile (c);\n\t\tvStringPut (token->string, ' ');\n\t\ttoken->type = TOKEN_WHITESPACE;\n\t\treturn;\n\t}\n\n\tswitch (c)\n\t{\n\t\tcase EOF:\n\t\t\ttoken->type = TOKEN_EOF;\n\t\t\tbreak;\n\n\t\tcase '\\'':\n\t\tcase '\"':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tvStringPut (token->string, c);\n\t\t\tif (d != c)\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\treadString (token->string, c);\n\t\t\t}\n\t\t\telse if ((d = getcFromInputFile ()) == c)\n\t\t\t\treadTripleString (token->string, c);\n\t\t\telse /* empty string */\n\t\t\t\tungetcToInputFile (d);\n\t\t\tvStringPut (token->string, c);\n\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '=':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tvStringPut (token->string, c);\n\t\t\tif (d == c)\n\t\t\t{\n\t\t\t\tvStringPut (token->string, d);\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = c;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '-':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '>')\n\t\t\t{\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\tvStringPut (token->string, d);\n\t\t\t\ttoken->type = TOKEN_ARROW;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tungetcToInputFile (d);\n\t\t\t/* fall through */\n\t\t}\n\t\tcase '+':\n\t\tcase '*':\n\t\tcase '%':\n\t\tcase '<':\n\t\tcase '>':\n\t\tcase '/':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tvStringPut (token->string, c);\n\t\t\tif (d != '=')\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = c;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvStringPut (token->string, d);\n\t\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t/* eats newline to implement line continuation  */\n\t\tcase '\\\\':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '\\r')\n\t\t\t\td = getcFromInputFile ();\n\t\t\tif (d != '\\n')\n\t\t\t\tungetcToInputFile (d);\n\t\t\tgoto getNextChar;\n\t\t}\n\n\t\tcase '#': /* comment */\n\t\tcase '\\r': /* newlines for indent */\n\t\tcase '\\n':\n\t\t{\n\t\t\tint indent = 0;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tif (c == '#')\n\t\t\t\t{\n\t\t\t\t\tdo\n\t\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t\twhile (c != EOF && c != '\\r' && c != '\\n');\n\t\t\t\t}\n\t\t\t\tif (c == '\\r')\n\t\t\t\t{\n\t\t\t\t\tint d = getcFromInputFile ();\n\t\t\t\t\tif (d != '\\n')\n\t\t\t\t\t\tungetcToInputFile (d);\n\t\t\t\t}\n\t\t\t\tindent = 0;\n\t\t\t\twhile ((c = getcFromInputFile ()) == ' ' || c == '\\t' || c == '\\f')\n\t\t\t\t{\n\t\t\t\t\tif (c == '\\t')\n\t\t\t\t\t\tindent += 8 - (indent % 8);\n\t\t\t\t\telse if (c == '\\f') /* yeah, it's weird */\n\t\t\t\t\t\tindent = 0;\n\t\t\t\t\telse\n\t\t\t\t\t\tindent++;\n\t\t\t\t}\n\t\t\t} /* skip completely empty lines, so retry */\n\t\t\twhile (c == '\\r' || c == '\\n' || c == '#');\n\t\t\tungetcToInputFile (c);\n\t\t\tif (TokenContinuationDepth > 0)\n\t\t\t{\n\t\t\t\tif (inclWhitespaces)\n\t\t\t\t{\n\t\t\t\t\tvStringPut (token->string, ' ');\n\t\t\t\t\ttoken->type = TOKEN_WHITESPACE;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_INDENT;\n\t\t\t\ttoken->indent = indent;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\tif (! isIdentifierChar (c))\n\t\t\t{\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\ttoken->type = c;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* FIXME: handle U, B, R and F string prefixes? */\n\t\t\t\treadIdentifier (token->string, c);\n\t\t\t\ttoken->keyword = lookupKeyword (vStringValue (token->string), Lang_python);\n\t\t\t\tif (token->keyword == KEYWORD_NONE\n\t\t\t\t\t|| isSoftKeyword(token->keyword))\n\t\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\telse\n\t\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\t/* handle implicit continuation lines not to emit INDENT inside brackets\n\t * https://docs.python.org/3.6/reference/lexical_analysis.html#implicit-line-joining */\n\tif (token->type == '(' ||\n\t    token->type == '{' ||\n\t    token->type == '[')\n\t{\n\t\tTokenContinuationDepth ++;\n\t}\n\telse if (TokenContinuationDepth > 0 &&\n\t         (token->type == ')' ||\n\t          token->type == '}' ||\n\t          token->type == ']'))\n\t{\n\t\tTokenContinuationDepth --;\n\t}\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\treadTokenFull (token, false);\n}\n\n/*================================= parsing =================================*/\n\n\nstatic void reprCat (vString *const repr, const tokenInfo *const token)\n{\n\tif (token->type != TOKEN_INDENT &&\n\t    token->type != TOKEN_WHITESPACE)\n\t{\n\t\tvStringCat (repr, token->string);\n\t}\n\telse if (vStringLength (repr) > 0 && vStringLast (repr) != ' ')\n\t{\n\t\tvStringPut (repr, ' ');\n\t}\n}\n\nstatic bool skipOverPair (tokenInfo *const token, int tOpen, int tClose,\n                             vString *const repr, bool reprOuterPair)\n{\n\tif (token->type == tOpen)\n\t{\n\t\tint depth = 1;\n\n\t\tif (repr && reprOuterPair)\n\t\t\treprCat (repr, token);\n\t\tdo\n\t\t{\n\t\t\treadTokenFull (token, true);\n\t\t\tif (repr && (reprOuterPair || token->type != tClose || depth > 1))\n\t\t\t{\n\t\t\t\treprCat (repr, token);\n\t\t\t}\n\t\t\tif (token->type == tOpen)\n\t\t\t\tdepth ++;\n\t\t\telse if (token->type == tClose)\n\t\t\t\tdepth --;\n\t\t}\n\t\twhile (token->type != TOKEN_EOF && depth > 0);\n\t}\n\n\treturn token->type == tClose;\n}\n\nstatic bool skipLambdaArglist (tokenInfo *const token, vString *const repr)\n{\n\twhile (token->type != TOKEN_EOF && token->type != ':' &&\n\t       /* avoid reading too much, just in case */\n\t       token->type != TOKEN_INDENT)\n\t{\n\t\tbool readNext = true;\n\n\t\tif (token->type == '(')\n\t\t\treadNext = skipOverPair (token, '(', ')', repr, true);\n\t\telse if (token->type == '[')\n\t\t\treadNext = skipOverPair (token, '[', ']', repr, true);\n\t\telse if (token->type == '{')\n\t\t\treadNext = skipOverPair (token, '{', '}', repr, true);\n\t\telse if (token->keyword == KEYWORD_lambda)\n\t\t{ /* handle lambdas in a default value */\n\t\t\tif (repr)\n\t\t\t\treprCat (repr, token);\n\t\t\treadTokenFull (token, true);\n\t\t\treadNext = skipLambdaArglist (token, repr);\n\t\t\tif (token->type == ':')\n\t\t\t\treadNext = true;\n\t\t\tif (readNext && repr)\n\t\t\t\treprCat (repr, token);\n\t\t}\n\t\telse if (repr)\n\t\t{\n\t\t\treprCat (repr, token);\n\t\t}\n\n\t\tif (readNext)\n\t\t\treadTokenFull (token, true);\n\t}\n\treturn false;\n}\n\nstatic void readQualifiedName (tokenInfo *const nameToken)\n{\n\treadToken (nameToken);\n\n\tif (nameToken->type == TOKEN_IDENTIFIER ||\n\t    nameToken->type == '.')\n\t{\n\t\tvString *qualifiedName = vStringNew ();\n\t\ttokenInfo *token = newToken ();\n\n\t\twhile (nameToken->type == TOKEN_IDENTIFIER ||\n\t\t       nameToken->type == '.')\n\t\t{\n\t\t\tvStringCat (qualifiedName, nameToken->string);\n\t\t\tcopyToken (token, nameToken);\n\n\t\t\treadToken (nameToken);\n\t\t}\n\t\t/* put the last, non-matching, token back */\n\t\tungetToken (nameToken);\n\n\t\tcopyToken (nameToken, token);\n\t\tnameToken->type = TOKEN_IDENTIFIER;\n\t\tvStringCopy (nameToken->string, qualifiedName);\n\n\t\tdeleteToken (token);\n\t\tvStringDelete (qualifiedName);\n\t}\n}\n\nstatic bool readCDefName (tokenInfo *const token, pythonKind *kind)\n{\n\treadToken (token);\n\n\tif (token->keyword == KEYWORD_extern ||\n\t    token->keyword == KEYWORD_import)\n\t{\n\t\treadToken (token);\n\t\tif (token->keyword == KEYWORD_from)\n\t\t\treturn false;\n\t}\n\n\tif (token->keyword == KEYWORD_class)\n\t{\n\t\t*kind = PYTHON_CLASS_KIND;\n\t\treadToken (token);\n\t}\n\telse\n\t{\n\t\t/* skip the optional type declaration -- everything on the same line\n\t\t * until an identifier followed by \"(\". */\n\t\ttokenInfo *candidate = newToken ();\n\n\t\twhile (token->type != TOKEN_EOF &&\n\t\t       token->type != TOKEN_INDENT &&\n\t\t       token->type != '=' &&\n\t\t       token->type != ',' &&\n\t\t       token->type != ':')\n\t\t{\n\t\t\tif (token->type == '[')\n\t\t\t{\n\t\t\t\tif (skipOverPair (token, '[', ']', NULL, false))\n\t\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\telse if (token->type == '(')\n\t\t\t{\n\t\t\t\tif (skipOverPair (token, '(', ')', NULL, false))\n\t\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\telse if (token->type == TOKEN_IDENTIFIER)\n\t\t\t{\n\t\t\t\tcopyToken (candidate, token);\n\t\t\t\treadToken (token);\n\t\t\t\tif (token->type == '(')\n\t\t\t\t{ /* okay, we really found a function, use this */\n\t\t\t\t\t*kind = PYTHON_FUNCTION_KIND;\n\t\t\t\t\tungetToken (token);\n\t\t\t\t\tcopyToken (token, candidate);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\treadToken (token);\n\t\t}\n\n\t\tdeleteToken (candidate);\n\t}\n\n\treturn token->type == TOKEN_IDENTIFIER;\n}\n\nstatic vString *parseParamTypeAnnotation (tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t\t  vString *arglist)\n{\n\tTRACE_ENTER();\n\treadToken (token);\n\tif (token->type != ':')\n\t{\n\t\tungetToken (token);\n\t\tTRACE_LEAVE_TEXT(\"type != :\");\n\t\treturn NULL;\n\t}\n\n\treprCat (arglist, token);\n\tint depth = 0;\n\tvString *t = vStringNew ();\n\twhile (true)\n\t{\n\t\treadTokenFull (token, true);\n\t\tif (token->type == TOKEN_WHITESPACE)\n\t\t{\n\t\t\treprCat (arglist, token);\n\t\t\tcontinue;\n\t\t}\n\t\telse if (token->type == TOKEN_EOF)\n\t\t\tbreak;\n\n\t\tif (token->type == '(' ||\n\t\t\ttoken->type == '[' ||\n\t\t\ttoken->type == '{')\n\t\t\tdepth ++;\n\t\telse if (token->type == ')' ||\n\t\t\t\t token->type == ']' ||\n\t\t\t\t token->type == '}')\n\t\t\tdepth --;\n\n\t\tif (depth < 0\n\t\t\t|| (depth == 0 && (token->type == '='\n\t\t\t\t\t\t\t   || token->type == ',')))\n\t\t{\n\t\t\tungetToken (token);\n\t\t\tTRACE_LEAVE_TEXT(\"= or ,\");\n\t\t\treturn t;\n\t\t}\n\t\treprCat (arglist, token);\n\t\treprCat (t, token);\n\t}\n\tvStringDelete (t);\n\tTRACE_LEAVE_TEXT(\"return NULL\");\n\treturn NULL;\n}\n\nstatic vString *parseReturnTypeAnnotation (tokenInfo *const token)\n{\n\treadToken (token);\n\tif (token->type != TOKEN_ARROW)\n\t{\n\t\tungetToken (token);\n\t\treturn NULL;\n\t}\n\n\tint depth = 0;\n\tvString *t = vStringNew ();\n\twhile (true)\n\t{\n\t\treadToken (token);\n\t\tif (token->type == TOKEN_EOF)\n\t\t\tbreak;\n\n\t\tif (token->type == '(' ||\n\t\t\ttoken->type == '[' ||\n\t\t\ttoken->type == '{')\n\t\t\tdepth ++;\n\t\telse if (token->type == ')' ||\n\t\t\t\t token->type == ']' ||\n\t\t\t\t token->type == '}')\n\t\t\tdepth --;\n\t\tif (depth == 0 && token->type == ':')\n\t\t{\n\t\t\tungetToken (token);\n\t\t\treturn t;\n\t\t}\n\t\telse\n\t\t\treprCat (t, token);\n\t}\n\tvStringDelete (t);\n\treturn NULL;\n}\n\nstruct typedParam {\n\ttokenInfo *token;\n\tvString *type;\n};\n\nstatic struct typedParam *makeTypedParam (tokenInfo *token, vString *type)\n{\n\tstruct typedParam *p = xMalloc (1, struct typedParam);\n\tp->token = token;\n\tp->type = type;\n\treturn p;\n}\n\nstatic struct typedParam *makeTypedParamWithCopy (const tokenInfo *token, const vString *type)\n{\n\ttokenInfo *token_copied = newToken ();\n\tcopyToken (token_copied, token);\n\n\n\tvString *type_copied = type? vStringNewCopy (type): NULL;\n\treturn makeTypedParam (token_copied, type_copied);\n}\n\nstatic void deleteTypedParam (struct typedParam *p)\n{\n\tdeleteToken (p->token);\n\tvStringDelete (p->type);\t/* NULL is acceptable. */\n\teFree (p);\n}\n\nstatic void parseArglist (tokenInfo *const token, const int kind,\n\t\t\t\t\t\t  vString *const arglist, ptrArray *const parameters)\n{\n\tTRACE_ENTER();\n\tint prevTokenType = token->type;\n\tint depth = 1;\n\n\tif (kind != PYTHON_CLASS_KIND)\n\t\treprCat (arglist, token);\n\n\tdo\n\t{\n\t\tif (token->type != TOKEN_WHITESPACE &&\n\t\t\t/* for easy `*args` and `**kwargs` support, we also ignore\n\t\t\t * `*`, which anyway can't otherwise screw us up */\n\t\t\ttoken->type != '*')\n\t\t{\n\t\t\tprevTokenType = token->type;\n\t\t}\n\n\t\treadTokenFull (token, true);\n\t\tif (kind != PYTHON_CLASS_KIND || token->type != ')' || depth > 1)\n\t\t\treprCat (arglist, token);\n\n\t\tif (token->type == '(' ||\n\t\t\ttoken->type == '[' ||\n\t\t\ttoken->type == '{')\n\t\t\tdepth ++;\n\t\telse if (token->type == ')' ||\n\t\t\t\t token->type == ']' ||\n\t\t\t\t token->type == '}')\n\t\t\tdepth --;\n\t\telse if (kind != PYTHON_CLASS_KIND && depth == 1 &&\n\t\t\t\t token->type == TOKEN_IDENTIFIER &&\n\t\t\t\t (prevTokenType == '(' || prevTokenType == ',') &&\n\t\t\t\t PythonKinds[PYTHON_PARAMETER_KIND].enabled)\n\t\t{\n\t\t\ttokenInfo *parameterName;\n\t\t\tvString *parameterType;\n\t\t\tstruct typedParam *parameter;\n\n\t\t\tparameterName = newToken ();\n\t\t\tcopyToken (parameterName, token);\n\t\t\tparameterType = parseParamTypeAnnotation (token, arglist);\n\n\t\t\tparameter = makeTypedParam (parameterName, parameterType);\n\t\t\tptrArrayAdd (parameters, parameter);\n\t\t}\n\t}\n\twhile (token->type != TOKEN_EOF && depth > 0);\n\tTRACE_LEAVE();\n}\n\nstatic void parseCArglist (tokenInfo *const token, const int kind,\n\t\t\t\t\t\t  vString *const arglist, ptrArray *const parameters)\n{\n\tTRACE_ENTER();\n\tint depth = 1;\n\ttokenInfo *pname = newToken ();\n\tvString *ptype = vStringNew ();\n\tvStringCat (arglist, token->string);\t/* '(' */\n\n\twhile (true)\n\t{\n\t\treadToken (token);\n\t\tif (token->type == TOKEN_EOF)\n\t\t{\n\t\t\t/* Unexpected input. */\n\t\t\tvStringClear (arglist);\n\t\t\tptrArrayClear (parameters);\n\t\t\tbreak;\n\t\t}\n\n\t\tif (depth == 1 && (token->type == ',' || token->type == ')'))\n\t\t{\n\t\t\tif (pname->type == TOKEN_IDENTIFIER)\n\t\t\t{\n\t\t\t\tstruct typedParam *p;\n\n\t\t\t\t/*\n\t\t\t\t * Clean up the type string.\n\t\t\t\t * The type string includes the parameter name at the end.\n\t\t\t\t * 1. Trim the parameter name at the end.\n\t\t\t\t * 2. Then, trim the white space at the end of the type string.\n\t\t\t\t * 3. If the type string is not empty,\n\t\t\t\t *    3.a append (the type stirng + ' ' + the parameter name) to arglist.\n\t\t\t\t *    3.b else just append the parameter name to arglist.\n\t\t\t\t *\n\t\t\t\t * FIXME:\n\t\t\t\t * This doesn't work well with an array and a function pointer.\n\t\t\t\t *\n\t\t\t\t *   f(..., int seq [dim], ...)\n\t\t\t\t *      in this case, dim is extacted as a parameter.\n\t\t\t\t *\n\t\t\t\t *   f(..., int (*fn)(int), ...)\n\t\t\t\t *      in this case , int is extacted as a parameter.\n\t\t\t\t */\n\t\t\t\tAssert (vStringLength (ptype) >= vStringLength (pname->string));\n\t\t\t\tsize_t ptype_len = vStringLength (ptype) - vStringLength (pname->string);\n\t\t\t\tvStringTruncate (ptype, ptype_len);\n\n\t\t\t\tif (vStringLength (ptype) > 0)\n\t\t\t\t{\n\t\t\t\t\tvStringStripTrailing (ptype);\n\t\t\t\t\tif (vStringLength (ptype) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringCat (arglist, ptype);\n\t\t\t\t\t\tvStringPut (arglist, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvStringCat (arglist, pname->string);\n\n\t\t\t\tp = makeTypedParamWithCopy (pname, vStringIsEmpty(ptype)? NULL: ptype);\n\t\t\t\tptrArrayAdd (parameters, p);\n\t\t\t}\n\t\t\tif (token->type == ')')\n\t\t\t{\n\t\t\t\tvStringPut (arglist, ')');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tvStringCatS (arglist, \", \");\n\t\t\tvStringClear (ptype);\n\t\t\tpname->type = TOKEN_UNDEFINED;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (token->type == '(' ||\n\t\t\ttoken->type == '[' ||\n\t\t\ttoken->type == '{')\n\t\t{\n\t\t\tvStringPut (ptype, token->type);\n\t\t\tdepth ++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (token->type == ')' ||\n\t\t\ttoken->type == ']' ||\n\t\t\ttoken->type == '}')\n\t\t{\n\t\t\tvStringPut (ptype, token->type);\n\t\t\tdepth --;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_KEYWORD)\n\t\t{\n\t\t\tif (vStringLength (ptype) > 0\n\t\t\t\t&& (isalnum ((unsigned char)vStringLast (ptype))\n\t\t\t\t\t|| vStringLast (ptype) == ','))\n\t\t\t\tvStringPut (ptype, ' ');\n\t\t\tvStringCat (ptype, token->string);\n\n\t\t\tif (!isdigit ((unsigned char)vStringLast (token->string)))\n\t\t\t\tcopyToken (pname, token);\n\t\t\tcontinue;\n\t\t}\n\n\t\tvStringCat (ptype, token->string);\n\t}\n\n\tvStringDelete (ptype);\n\tdeleteToken (pname);\n\tTRACE_LEAVE();\n}\n\nstatic bool parseClassOrDef (tokenInfo *const token,\n                                const vString *const decorators,\n                                pythonKind kind, bool isCDef)\n{\n\tTRACE_ENTER();\n\tvString *arglist = NULL;\n\ttokenInfo *name = NULL;\n\tptrArray *parameters = NULL;\n\tNestingLevel *lv;\n\tint corkIndex;\n\n\tif (isCDef)\n\t{\n\t\tif (! readCDefName (token, &kind))\n\t\t{\n\t\t\tTRACE_LEAVE_TEXT(\"!readCDefName\");\n\t\t\treturn false;\n\t\t}\n\t}\n\telse\n\t{\n\t\treadToken (token);\n\t\tif (token->type != TOKEN_IDENTIFIER)\n\t\t{\n\t\t\tTRACE_LEAVE_TEXT(\"token->type != TOKEN_IDENTIFIER\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tname = newToken ();\n\tcopyToken (name, token);\n\n\treadToken (token);\n\t/* collect parameters or inheritance */\n\tif (token->type == '(')\n\t{\n\t\targlist = vStringNew ();\n\t\tparameters = ptrArrayNew ((ptrArrayDeleteFunc)deleteTypedParam);\n\n\t\tif (isCDef && kind != PYTHON_CLASS_KIND)\n\t\t\tparseCArglist (token, kind, arglist, parameters);\n\t\telse\n\t\t\tparseArglist (token, kind, arglist, parameters);\n\t}\n\n\tif (kind == PYTHON_CLASS_KIND)\n\t\tcorkIndex = makeClassTag (name, arglist, decorators);\n\telse\n\t\tcorkIndex = makeFunctionTag (name, arglist, decorators);\n\n\tlv = nestingLevelsPush (PythonNestingLevels, corkIndex);\n\tPY_NL (lv)->indentation = token->indent;\n\n\tdeleteToken (name);\n\tvStringDelete (arglist);\n\n\tif (parameters && !ptrArrayIsEmpty (parameters))\n\t{\n\t\tunsigned int i;\n\n\t\tfor (i = 0; i < ptrArrayCount (parameters); i++)\n\t\t{\n\t\t\tstruct typedParam *parameter = ptrArrayItem (parameters, i);\n\t\t\tint paramCorkIndex = makeSimplePythonTag (parameter->token, PYTHON_PARAMETER_KIND);\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (paramCorkIndex);\n\t\t\tif (e && parameter->type)\n\t\t\t{\n\t\t\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\t\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (parameter->type);\n\t\t\t\tparameter->type = NULL;\n\t\t\t}\n\t\t}\n\t}\n\tptrArrayDelete (parameters); /* NULL is acceptable. */\n\n\ttagEntryInfo *e;\n\tvString *t;\n\tif (kind != PYTHON_CLASS_KIND\n\t\t&& (e = getEntryInCorkQueue (corkIndex))\n\t\t&& (t = parseReturnTypeAnnotation (token)))\n\t{\n\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (t);\n\t}\n\n\tTRACE_LEAVE_TEXT(\"return true\");\n\treturn true;\n}\n\nstatic bool parseImport (tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\ttokenInfo *fromModule = NULL;\n\n\tif (token->keyword == KEYWORD_from)\n\t{\n\t\treadQualifiedName (token);\n\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t{\n\t\t\tfromModule = newToken ();\n\t\t\tcopyToken (fromModule, token);\n\t\t\treadToken (token);\n\t\t}\n\t}\n\n\tif (token->keyword == KEYWORD_import)\n\t{\n\t\tbool parenthesized = false;\n\t\tint moduleIndex;\n\n\t\tif (fromModule)\n\t\t{\n\t\t\t/* from X import ...\n\t\t\t * --------------------\n\t\t\t * X = (kind:module, role:namespace) */\n\t\t\tmoduleIndex = makeSimplePythonRefTag (fromModule, NULL, PYTHON_MODULE_KIND,\n\t\t\t\t\t\t\t\t\t\t\t\t  PYTHON_MODULE_NAMESPACE,\n\t\t\t\t\t\t\t\t\t\t\t\t  XTAG_UNKNOWN);\n\t\t}\n\n\t\tdo\n\t\t{\n\t\t\treadQualifiedName (token);\n\n\t\t\t/* support for `from x import (...)` */\n\t\t\tif (fromModule && ! parenthesized && token->type == '(')\n\t\t\t{\n\t\t\t\tparenthesized = true;\n\t\t\t\treadQualifiedName (token);\n\t\t\t}\n\n\t\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t\t{\n\t\t\t\ttokenInfo *name = newToken ();\n\n\t\t\t\tcopyToken (name, token);\n\t\t\t\treadToken (token);\n\t\t\t\t/* if there is an \"as\", use it as the name */\n\t\t\t\tif (token->keyword == KEYWORD_as)\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (fromModule)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* from x import Y as Z\n\t\t\t\t\t\t\t * ----------------------------\n\t\t\t\t\t\t\t * x = (kind:module,  role:namespace),\n\t\t\t\t\t\t\t * Y = (kind:unknown, role:indirectlyImported, scope:module:X),\n\t\t\t\t\t\t\t * Z = (kind:unknown, nameref:unknown:Y) */\n\t\t\t\t\t\t\tint index;\n\n\t\t\t\t\t\t\t/* Y */\n\t\t\t\t\t\t\tindex = makeSimplePythonRefTag (name, NULL, PYTHON_UNKNOWN_KIND,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPYTHON_UNKNOWN_INDIRECTLY_IMPORTED,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tXTAG_UNKNOWN);\n\t\t\t\t\t\t\t/* fill the scope field for Y */\n\t\t\t\t\t\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\t\t\t\t\t\tif (e)\n\t\t\t\t\t\t\t\te->extensionFields.scopeIndex = moduleIndex;\n\n\t\t\t\t\t\t\t/* Z */\n\t\t\t\t\t\t\tindex = makeSimplePythonTag (token, PYTHON_UNKNOWN_KIND);\n\t\t\t\t\t\t\t/* fill the nameref filed for Y */\n\t\t\t\t\t\t\tif (PythonFields[F_NAMEREF].enabled)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvString *nameref = vStringNewInit (PythonKinds [PYTHON_UNKNOWN_KIND].name);\n\t\t\t\t\t\t\t\tvStringPut (nameref, ':');\n\t\t\t\t\t\t\t\tvStringCat (nameref, name->string);\n\t\t\t\t\t\t\t\tattachParserFieldToCorkEntry (index, PythonFields[F_NAMEREF].ftype,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  vStringValue (nameref));\n\t\t\t\t\t\t\t\tvStringDelete (nameref);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* import x as Y\n\t\t\t\t\t\t\t * ----------------------------\n\t\t\t\t\t\t\t * x = (kind:module, role:indirectlyImported)\n\t\t\t\t\t\t\t * Y = (kind:namespace, nameref:module:x)*/\n\t\t\t\t\t\t\t/* x */\n\t\t\t\t\t\t\tmakeSimplePythonRefTag (name, NULL, PYTHON_MODULE_KIND,\n\t\t\t\t\t\t\t                        PYTHON_MODULE_INDIRECTLY_IMPORTED,\n\t\t\t\t\t\t\t                        XTAG_UNKNOWN);\n\t\t\t\t\t\t\t/* Y */\n\t\t\t\t\t\t\tint index = makeSimplePythonTag (token, PYTHON_NAMESPACE_KIND);\n\t\t\t\t\t\t\t/* fill the nameref filed for Y */\n\t\t\t\t\t\t\tif (PythonFields[F_NAMEREF].enabled)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvString *nameref = vStringNewInit (PythonKinds [PYTHON_MODULE_KIND].name);\n\t\t\t\t\t\t\t\tvStringPut (nameref, ':');\n\t\t\t\t\t\t\t\tvStringCat (nameref, name->string);\n\t\t\t\t\t\t\t\tattachParserFieldToCorkEntry (index, PythonFields[F_NAMEREF].ftype,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  vStringValue (nameref));\n\t\t\t\t\t\t\t\tvStringDelete (nameref);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcopyToken (name, token);\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (fromModule)\n\t\t\t\t\t{\n\t\t\t\t\t\t/* from x import Y\n\t\t\t\t\t\t   --------------\n\t\t\t\t\t\t   x = (kind:module,  role:namespace),\n\t\t\t\t\t\t   Y = (kind:unknown, role:imported, scope:module:x) */\n\t\t\t\t\t\t/* Y */\n\t\t\t\t\t\tint index = makeSimplePythonRefTag (name, NULL, PYTHON_UNKNOWN_KIND,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPYTHON_UNKNOWN_IMPORTED,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tXTAG_UNKNOWN);\n\t\t\t\t\t\t/* fill the scope field for Y */\n\t\t\t\t\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\t\t\t\t\tif (e)\n\t\t\t\t\t\t\te->extensionFields.scopeIndex = moduleIndex;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t/* import X\n\t\t\t\t\t\t   --------------\n\t\t\t\t\t\t   X = (kind:module, role:imported) */\n\t\t\t\t\t\tmakeSimplePythonRefTag (name, NULL, PYTHON_MODULE_KIND,\n\t\t\t\t\t\t                        PYTHON_MODULE_IMPORTED,\n\t\t\t\t\t\t                        XTAG_UNKNOWN);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdeleteToken (name);\n\t\t\t}\n\t\t}\n\t\twhile (token->type == ',');\n\n\t\tif (parenthesized && token->type == ')')\n\t\t\treadToken (token);\n\t}\n\n\tif (fromModule)\n\t\tdeleteToken (fromModule);\n\n\tTRACE_LEAVE();\n\treturn false;\n}\n\n/* this only handles the most common cases, but an annotation can be any\n * expression in theory.\n * this function assumes there must be an annotation, and doesn't do any check\n * on the token on which it is called: the caller should do that part. */\nstatic bool skipVariableTypeAnnotation (tokenInfo *const token, vString *const repr)\n{\n\tbool readNext = true;\n\n\treadToken (token);\n\tswitch (token->type)\n\t{\n\t\tcase '[': readNext = skipOverPair (token, '[', ']', repr, true); break;\n\t\tcase '(': readNext = skipOverPair (token, '(', ')', repr, true); break;\n\t\tcase '{': readNext = skipOverPair (token, '{', '}', repr, true); break;\n\t\tdefault: reprCat (repr, token);\n\t}\n\tif (readNext)\n\t\treadToken (token);\n\t/* skip subscripts and calls */\n\twhile (token->type == '[' || token->type == '(' || token->type == '.' || token->type == '|')\n\t{\n\t\tswitch (token->type)\n\t\t{\n\t\t\tcase '[': readNext = skipOverPair (token, '[', ']', repr, true); break;\n\t\t\tcase '(': readNext = skipOverPair (token, '(', ')', repr, true); break;\n\t\t\tcase '|':\n\t\t\t\treprCat (repr, token);\n\t\t\t\tskipVariableTypeAnnotation (token, repr);\n\t\t\t\treadNext = false;\n\t\t\t\tbreak;\n\t\t\tcase '.':\n\t\t\t\treprCat (repr, token);\n\t\t\t\treadToken (token);\n\t\t\t\treadNext = token->type == TOKEN_IDENTIFIER;\n\t\t\t\tif (readNext)\n\t\t\t\t\treprCat (repr, token);\n\t\t\t\tbreak;\n\t\t\tdefault:  readNext = false; break;\n\t\t}\n\t\tif (readNext)\n\t\t\treadToken (token);\n\t}\n\n\treturn false;\n}\n\nstatic bool isAtSimpleNamespace (tokenInfo *const token)\n{\n\tif (token->type == TOKEN_IDENTIFIER\n\t\t&& vStringEqC (token->string, \"SimpleNamespace\"))\n\t{\n\t\ttokenInfo *backup = newToken();\n\n\t\tcopyToken (backup, token);\n\t\treadToken (token);\n\t\tif (token->type != '(')\n\t\t{\n\t\t\tungetToken (token);\n\t\t\tcopyToken (token, backup);\n\t\t\tdeleteToken (backup);\n\t\t\treturn false;\n\t\t}\n\t\tdeleteToken (backup);\n\t\treturn true;\n\t}\n\n\tif (token->type == TOKEN_IDENTIFIER\n\t\t&& vStringEqC (token->string, \"types\"))\n\t{\n\t\treadQualifiedName(token);\n\t\tif (token->type == TOKEN_IDENTIFIER\n\t\t\t&& vStringEqC (token->string, \".SimpleNamespace\"))\n\t\t{\n\t\t\ttokenInfo *backup = newToken();\n\n\t\t\tcopyToken (backup, token);\n\t\t\treadToken (token);\n\n\t\t\tif (token->type != '(')\n\t\t\t{\n\t\t\t\tungetToken (token);\n\t\t\t\tcopyToken (token, backup);\n\t\t\t\tdeleteToken (backup);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdeleteToken (backup);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nstatic void parseSimpleNamespace (tokenInfo *const token, int namespaceIndex)\n{\n\tTRACE_ENTER();\n\n\tnestingLevelsPush (PythonNestingLevels, namespaceIndex);\n\tint prevTokenType = token->type;\n\tint depth = 1;\n\tint lastIndex = CORK_NIL;\n\n\tdo\n\t{\n\t\tif (token->type != TOKEN_WHITESPACE)\n\t\t\tprevTokenType = token->type;\n\n\t\treadTokenFull (token, true);\n\n\t\tif (token->type == '(' ||\n\t\t\ttoken->type == '[' ||\n\t\t\ttoken->type == '{')\n\t\t\tdepth ++;\n\t\telse if (token->type == ')' ||\n\t\t\t\t token->type == ']' ||\n\t\t\t\t token->type == '}')\n\t\t\tdepth --;\n\t\telse if (depth == 1 &&\n\t\t\t\t token->type == TOKEN_IDENTIFIER &&\n\t\t\t\t (prevTokenType == '(' || prevTokenType == ','))\n\t\t\tlastIndex = makeSimplePythonTag (token, PYTHON_UNKNOWN_KIND);\n\t\telse if (depth == 1 &&\n\t\t\t\t token->keyword == KEYWORD_lambda &&\n\t\t\t\t prevTokenType == '=' &&\n\t\t\t\t lastIndex != CORK_NIL)\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (lastIndex);\n\t\t\tif (e)\n\t\t\t\te->kindIndex = PYTHON_FUNCTION_KIND; /* PYTHON_METHOD_KIND? */\n\t\t\tlastIndex = CORK_NIL;\n\t\t}\n\t}\n\twhile (token->type != TOKEN_EOF && depth > 0);\n\tnestingLevelsPop (PythonNestingLevels);\n\n\tTRACE_LEAVE();\n}\n\nstatic bool parseVariable (tokenInfo *const token, const pythonKind kind)\n{\n\tTRACE_ENTER();\n\t/* In order to support proper tag type for lambdas in multiple\n\t * assignations, we first collect all the names, and then try and map\n\t * an assignation to it */\n\ttokenInfo *nameTokens[8] = { NULL };\n\tvString   *nameTypes [ARRAY_SIZE (nameTokens)] = { NULL };\n\tunsigned int nameCount = 0;\n\tvString *type = vStringNew();\n\n\t/* first, collect variable name tokens */\n\twhile (token->type == TOKEN_IDENTIFIER &&\n\t       nameCount < ARRAY_SIZE (nameTokens))\n\t{\n\t\tunsigned int i;\n\t\ttokenInfo *name = newToken ();\n\t\tcopyToken (name, token);\n\n\t\treadToken (token);\n\t\tif (token->type == '.')\n\t\t{\n\t\t\t/* FIXME: what to do with dotted names?  We currently ignore them\n\t\t\t *        as we need to do something not to break the whole\n\t\t\t *        declaration, but the expected behavior is questionable */\n\t\t\tdeleteToken (name);\n\t\t\tname = NULL;\n\n\t\t\tdo\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\twhile (token->type == TOKEN_IDENTIFIER ||\n\t\t\t       token->type == '.');\n\t\t}\n\n\t\ti = nameCount++;\n\t\tnameTokens[i] = name;\n\n\t\t/* (parse and) skip annotations.  we need not to be too permissive because we\n\t\t * aren't yet sure we're actually parsing a variable. */\n\t\tif (token->type == ':' && skipVariableTypeAnnotation (token, type))\n\t\t\treadToken (token);\n\n\t\tif (vStringLength (type) > 0)\n\t\t{\n\t\t\tnameTypes[i] = type;\n\t\t\ttype = vStringNew ();\n\t\t}\n\n\t\tif (token->type == ',')\n\t\t\treadToken (token);\n\t\telse\n\t\t\tbreak;\n\t}\n\tvStringDelete (type);\n\n\t/* then, if it's a proper assignation, try and map assignations so that\n\t * we catch lambdas and alike */\n\tif (token->type == '=')\n\t{\n\t\tTRACE_PRINT(\"operator: =\");\n\t\tunsigned int i = 0;\n\n\t\tdo\n\t\t{\n\t\t\tconst tokenInfo *const nameToken = nameTokens[i];\n\t\t\tvString **type = &(nameTypes[i++]);\n\n\t\t\treadToken (token);\n\n\t\t\tif (! nameToken)\n\t\t\t\t/* nothing */;\n\t\t\telse if (token->keyword == KEYWORD_lambda)\n\t\t\t{\n\t\t\t\tTRACE_PRINT(\"keyword: lambda\");\n\t\t\t\ttokenInfo *anon  = NULL;\n\t\t\t\tvString *arglist = vStringNew ();\n\t\t\t\tif (*type)\n\t\t\t\t{\n\t\t\t\t\tanon = newToken ();\n\t\t\t\t\tcopyToken (anon, token);\n\t\t\t\t}\n\t\t\t\treadToken (token);\n\t\t\t\tvStringPut (arglist, '(');\n\t\t\t\tskipLambdaArglist (token, arglist);\n\t\t\t\tvStringPut (arglist, ')');\n\t\t\t\tif (*type)\n\t\t\t\t{\n\t\t\t\t\t/* How to handle lambda assigned to a variable\n\t\t\t\t\t * --------------------------------------------\n\t\t\t\t\t *\n\t\t\t\t\t * input.py:\n\t\t\t\t\t *\n\t\t\t\t\t * \t  id = lambda var: var\n\t\t\t\t\t * \t  id_t: Callable[[int], int] = lambda var: var\n\t\t\t\t\t *\n\t\t\t\t\t * `id' is tagged as a function kind object like:\n\t\t\t\t\t *\n\t\t\t\t\t *    id\tinput.py\t/^id = lambda var: var$/;\"\tfunction\n\t\t\t\t\t *\n\t\t\t\t\t * For `id_t' we cannot do the same as `id'.\n\t\t\t\t\t *\n\t\t\t\t\t * We should not store `Callable[[int], int]' to typeref\n\t\t\t\t\t * field of the tag of `id_t' if the tag has \"function\" as\n\t\t\t\t\t * its kind because users expect the typeref field of a\n\t\t\t\t\t * function kind represents a type for the value returned\n\t\t\t\t\t * from the function (return type).\n\t\t\t\t\t *\n\t\t\t\t\t * the unexpected tag:\n\t\t\t\t\t *\n\t\t\t\t\t *    id_t\tinput.py\t/^id_t: Callable[[int], int] = lambda var: var$/;\"\tfunction \\\n\t\t\t\t\t *                          typeref:typename:Callable[[int], int]\n\t\t\t\t\t *\n\t\t\t\t\t * If we make a tag for `id_t' as a function, we should\n\t\t\t\t\t * attach `typeref:typename:int' and `signature:(int)'. To\n\t\t\t\t\t * achieve this, we have to make ctags analyze\n\t\t\t\t\t * `Callable[[int], int]'.  However, we want to avoid the\n\t\t\t\t\t * level of analyzing.\n\t\t\t\t\t *\n\t\t\t\t\t * For recording `Callable[[int], int]', a valuable\n\t\t\t\t\t * information in the input, we use indirection.\n\t\t\t\t\t *\n\t\t\t\t\t *    id_t\tinput.py\t/^id_t: Callable[[int], int] = lambda var: var$/;\"\tvariable \\\n\t\t\t\t\t *                          typeref:typename:Callable[[int], int]\tnameref:function:anonFuncNNN\n\t\t\t\t\t *    anonFuncNNN\tinput.py\t/^id_t: Callable[[int], int] = lambda var: var$/;\"\tfunction \\\n\t\t\t\t\t *                          extras:anonymous\n\t\t\t\t\t */\n\t\t\t\t\tint vindex = makeSimplePythonTag (nameToken, kind);\n\t\t\t\t\tvStringClear (anon->string);\n\t\t\t\t\tanonGenerate (anon->string, \"anonFunc\", PYTHON_FUNCTION_KIND);\n\t\t\t\t\tint findex = makeFunctionTag (anon, arglist, NULL);\n\t\t\t\t\ttagEntryInfo *fe = getEntryInCorkQueue (findex);\n\t\t\t\t\tif (fe)\n\t\t\t\t\t\tmarkTagExtraBit (fe, XTAG_ANONYMOUS);\n\n\t\t\t\t\ttagEntryInfo *ve = getEntryInCorkQueue (vindex);\n\t\t\t\t\tif (ve)\n\t\t\t\t\t{\n\t\t\t\t\t\tve->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\t\t\t\t\tve->extensionFields.typeRef [1] = vStringDeleteUnwrap (*type);\n\t\t\t\t\t\t*type = NULL;\n\t\t\t\t\t\tvString *nameref = vStringNewInit (PythonKinds [PYTHON_FUNCTION_KIND].name);\n\t\t\t\t\t\tvStringPut (nameref, ':');\n\t\t\t\t\t\tvStringCat (nameref, anon->string);\n\t\t\t\t\t\tattachParserField (ve, PythonFields[F_NAMEREF].ftype,\n\t\t\t\t\t\t\t\t\t\t   vStringValue (nameref));\n\t\t\t\t\t\tvStringDelete (nameref);\n\t\t\t\t\t}\n\t\t\t\t\tif (anon)\n\t\t\t\t\t\tdeleteToken (anon);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tmakeFunctionTag (nameToken, arglist, NULL);\n\t\t\t\tvStringDelete (arglist);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tTRACE_PRINT(\"name: %s\", vStringValue(nameToken->string));\n\t\t\t\tbool isAtSN = isAtSimpleNamespace(token);\n\t\t\t\tint index = makeSimplePythonTag (nameToken,\n\t\t\t\t\t\t\t\t\t\t\t\t ((kind != PYTHON_LOCAL_VARIABLE_KIND) && isAtSN)\n\t\t\t\t\t\t\t\t\t\t\t\t ? PYTHON_NAMESPACE_KIND\n\t\t\t\t\t\t\t\t\t\t\t\t : kind);\n\t\t\t\tif (isAtSN)\n\t\t\t\t\tparseSimpleNamespace(token, index);\n\t\t\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\t\t\tif (e && *type)\n\t\t\t\t{\n\t\t\t\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\t\t\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (*type);\n\t\t\t\t\t*type = NULL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* skip until next initializer */\n\t\t\twhile ((TokenContinuationDepth > 0 || token->type != ',') &&\n\t\t\t       token->type != TOKEN_EOF &&\n\t\t\t       token->type != ';' &&\n\t\t\t       token->type != TOKEN_INDENT)\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t}\n\t\twhile (token->type == ',' && i < nameCount);\n\n\t\t/* if we got leftover to initialize, just make variables out of them.\n\t\t * This handles cases like `a, b, c = (c, d, e)` -- or worse */\n\t\tfor (; i < nameCount; i++)\n\t\t{\n\t\t\tif (nameTokens[i])\n\t\t\t\tmakeSimplePythonTag (nameTokens[i], kind);\n\t\t}\n\t}\n\n\twhile (nameCount > 0)\n\t{\n\t\tif (nameTokens[--nameCount])\n\t\t\tdeleteToken (nameTokens[nameCount]);\n\t\tvStringDelete (nameTypes[nameCount]); /* NULL is acceptable. */\n\t}\n\n\tTRACE_LEAVE_TEXT(\"return false\");\n\treturn false;\n}\n\n/* pops any level >= to indent */\nstatic void setIndent (tokenInfo *const token)\n{\n\tNestingLevel *lv = nestingLevelsGetCurrent (PythonNestingLevels);\n\n\twhile (lv && PY_NL (lv)->indentation >= token->indent)\n\t{\n\t\tsetTagEndLineToCorkEntry (lv->corkIndex, token->lineNumber);\n\n\t\tnestingLevelsPop (PythonNestingLevels);\n\t\tlv = nestingLevelsGetCurrent (PythonNestingLevels);\n\t}\n}\n\nstatic bool parseType (tokenInfo *const token, pythonKind kind)\n{\n\tTRACE_ENTER();\n\t/* https://docs.python.org/3.14/reference/simple_stmts.html#type */\n\tint index = makeSimplePythonTag (token, kind);\n\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\tif (e)\n\t{\n\t\t/* Technically the type statement creates variables of type typing.TypeAliasType,\n\t\t * which is a different thing from typing.TypeAlias (which is deprecated).\n\t\t * Thus it would be misleading to claim they're of type TypeAlias. */\n\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\te->extensionFields.typeRef [1] = eStrdup (\"TypeAliasType\");\n\t}\n\n\treadToken (token);\n\n\tif (token->type == '[')\n\t{\n\t\tif (skipOverPair (token, '[', ']', NULL, false))\n\t\t\treadToken (token);\n\t}\n\tif (token->type == TOKEN_EOF)\n\t{\n\t\tTRACE_LEAVE_TEXT(\"Unexpected EOF\");\n\t\treturn false;\n\t}\n\n\tvString *tspec = vStringNew ();\n\tbool r = skipVariableTypeAnnotation (token, tspec);\n\tvStringDelete (tspec);\n\tTRACE_LEAVE();\n\treturn r;\n}\n\nstatic void findPythonTags (void)\n{\n\tTRACE_ENTER();\n\n\ttokenInfo *const token = newToken ();\n\tvString *decorators = vStringNew ();\n\tbool atStatementStart = true;\n\n\tTokenContinuationDepth = 0;\n\tNextToken = NULL;\n\tPythonNestingLevels = nestingLevelsNew (sizeof (struct pythonNestingLevelUserData));\n\n\treadToken (token);\n\twhile (token->type != TOKEN_EOF)\n\t{\n\t\ttokenType iterationTokenType = token->type;\n\t\tbool readNext = true;\n\n\t\t/* skip async keyword that confuses decorator parsing before a def */\n\t\tif (token->keyword == KEYWORD_async)\n\t\t\treadToken (token);\n\n\t\tif (token->type == TOKEN_INDENT)\n\t\t\tsetIndent (token);\n\t\telse if (token->keyword == KEYWORD_class ||\n\t\t         token->keyword == KEYWORD_def)\n\t\t{\n\t\t\tpythonKind kind = token->keyword == KEYWORD_class ? PYTHON_CLASS_KIND : PYTHON_FUNCTION_KIND;\n\n\t\t\treadNext = parseClassOrDef (token, decorators, kind, false);\n\t\t}\n\t\telse if (token->keyword == KEYWORD_cdef ||\n\t\t         token->keyword == KEYWORD_cpdef)\n\t\t{\n\t\t\treadNext = parseClassOrDef (token, decorators, PYTHON_FUNCTION_KIND, true);\n\t\t}\n\t\telse if (token->keyword == KEYWORD_from ||\n\t\t         token->keyword == KEYWORD_import)\n\t\t{\n\t\t\treadNext = parseImport (token);\n\t\t}\n\t\telse if (token->type == '(')\n\t\t{ /* skip parentheses to avoid finding stuff inside them */\n\t\t\treadNext = skipOverPair (token, '(', ')', NULL, false);\n\t\t}\n\t\telse if (token->type == TOKEN_IDENTIFIER && atStatementStart)\n\t\t{\n\t\t\tNestingLevel *lv = nestingLevelsGetCurrent (PythonNestingLevels);\n\t\t\ttagEntryInfo *lvEntry = getEntryOfNestingLevel (lv);\n\t\t\tpythonKind kind = PYTHON_VARIABLE_KIND;\n\t\t\tbool isTypeStatement = false;\n\n\t\t\tif (lvEntry && lvEntry->kindIndex != PYTHON_CLASS_KIND)\n\t\t\t\tkind = PYTHON_LOCAL_VARIABLE_KIND;\n\n\t\t\tif (token->keyword == SOFT_KEYWORD_type)\n\t\t\t{\n\t\t\t\t/* Is a type statement? */\n\t\t\t\ttokenInfo *const type = newToken ();\n\n\t\t\t\tcopyToken (type, token);\n\t\t\t\treadToken (token);\n\t\t\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t\t\t{\n\t\t\t\t\t/* Yes. this is a type statement. */\n\t\t\t\t\tisTypeStatement = true;\n\t\t\t\t\treadNext = parseType (token, kind);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* No. */\n\t\t\t\t\tungetToken (token);\n\t\t\t\t\tcopyToken (token, type);\n\t\t\t\t}\n\t\t\t\tdeleteToken (type);\n\t\t\t}\n\n\t\t\tif (!isTypeStatement)\n\t\t\t\treadNext = parseVariable (token, kind);\n\t\t}\n\t\telse if (token->type == '@' && atStatementStart &&\n\t\t         PythonFields[F_DECORATORS].enabled)\n\t\t{\n\t\t\t/* collect decorators */\n\t\t\treadQualifiedName (token);\n\t\t\tif (token->type != TOKEN_IDENTIFIER)\n\t\t\t\treadNext = false;\n\t\t\telse\n\t\t\t{\n\t\t\t\tvStringJoin(decorators, ',', token->string);\n\t\t\t\treadToken (token);\n\t\t\t\treadNext = skipOverPair (token, '(', ')', decorators, true);\n\t\t\t}\n\t\t}\n\n\t\t/* clear collected decorators for any non-decorator tokens non-indent\n\t\t * token.  decorator collection takes care of skipping the possible\n\t\t * argument list, so we should never hit here parsing a decorator */\n\t\tif (iterationTokenType != TOKEN_INDENT &&\n\t\t    iterationTokenType != '@' &&\n\t\t    PythonFields[F_DECORATORS].enabled)\n\t\t{\n\t\t\tvStringClear (decorators);\n\t\t}\n\n\t\tatStatementStart = (token->type == TOKEN_INDENT || token->type == ';');\n\n\t\tif (readNext)\n\t\t\treadToken (token);\n\t}\n\n\tnestingLevelsFree (PythonNestingLevels);\n\tvStringDelete (decorators);\n\tdeleteToken (token);\n\tAssert (NextToken == NULL);\n\tTRACE_LEAVE();\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_python = language;\n\n\tTokenPool = objPoolNew (16, newPoolToken, deletePoolToken, clearPoolToken, NULL);\n\taddKeywordGroup (&PythonRestKeywords, Lang_python);\n}\n\nstatic void finalize (langType language CTAGS_ATTR_UNUSED, bool initialized)\n{\n\tif (!initialized)\n\t\treturn;\n\n\tobjPoolDelete (TokenPool);\n}\n\nextern parserDefinition* PythonParser (void)\n{\n\tstatic const char *const extensions[] = { \"py\", \"pyx\", \"pxd\", \"pxi\", \"scons\",\n\t\t\t\t\t\t\t\t\t\t\t  \"wsgi\", NULL };\n\tstatic const char *const aliases[] = { \"python[23]*\", \"scons\", NULL };\n\tparserDefinition *def = parserNew (\"Python\");\n\tdef->kindTable = PythonKinds;\n\tdef->kindCount = ARRAY_SIZE (PythonKinds);\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->parser = findPythonTags;\n\tdef->initialize = initialize;\n\tdef->finalize = finalize;\n\tdef->keywordTable = PythonKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (PythonKeywordTable);\n\tdef->fieldTable = PythonFields;\n\tdef->fieldCount = ARRAY_SIZE (PythonFields);\n\tdef->useCork = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/quarto.c",
    "content": "/*\n *\n *  Copyright (c) 2023, Masatake YAMATO\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n * This module contains functions for generating tags for Quarto files.\n * https://quarto.org/docs/guide/\n * https://quarto.org/docs/reference/\n * https://www.jaysong.net/RBook/quarto.html#sec-quarto-howtouse <Japanese>\n *\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n#include \"x-markdown.h\"\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n\n#include <ctype.h>\n#include <string.h>\n\n/*\n *   DATA DEFINITIONS\n */\ntypedef enum {\n\tK_CHUNK_LABEL = 0,\n} quartoKind;\n\nstatic kindDefinition QuartoKinds[] = {\n\t{ true, 'l', \"chunklabel\",       \"chunk labels\"},\n};\n\nstruct sQuartoSubparser {\n\tmarkdownSubparser markdown;\n\tint lastChunkLabel;\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void findQuartoTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\n#define skip_space(CP) \twhile (*CP == ' ' || *CP == '\\t') CP++;\n\nstatic int makeQuartoTag (vString *name, int kindIndex, bool anonymous)\n{\n\ttagEntryInfo e;\n\tinitTagEntry (&e, vStringValue (name), kindIndex);\n\tif (anonymous)\n\t\tmarkTagExtraBit (&e, XTAG_ANONYMOUS);\n\treturn makeTagEntry (&e);\n}\n\nstatic bool extractLanguageForCodeBlock (markdownSubparser *s,\n\t\t\t\t\t\t\t\t\t\t const char *langMarker,\n\t\t\t\t\t\t\t\t\t\t vString *langName)\n{\n\tstruct sQuartoSubparser *quarto = (struct sQuartoSubparser *)s;\n\tconst char *cp = langMarker;\n\tbool unexecutedBlock = false;\n\n\tif (*cp != '{')\n\t\treturn false;\n\tcp++;\n\n\t/* Handle unexecuted blocks like ```{{python}} */\n\tif (*cp == '{') {\n\t\tunexecutedBlock = true;\n\t\tcp++;\n\t}\n\n\tconst char *end = strpbrk(cp, \" \\t,}\");\n\tif (!end)\n\t\treturn false;\n\n\tif (end - cp == 0)\n\t\treturn false;\n\n\tvStringNCatS (langName, cp, end - cp);\n\n\tif (unexecutedBlock) {\n\t\tend = strpbrk(cp, \" \\t,}\");\n\t\tif (!end)\n\t\t{\n\t\t\tvStringClear (langName);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tcp = end;\n\tif (*cp == ',' || *cp == '}')\n\t{\n\t\tvString *name = anonGenerateNew(\"__anon\", K_CHUNK_LABEL);\n\t\tquarto->lastChunkLabel = makeQuartoTag (name,\n\t\t\t\t\t\t\t\t\t\t\t\tK_CHUNK_LABEL,\n\t\t\t\t\t\t\t\t\t\t\t\ttrue);\n\t\tvStringDelete (name);\n\t\treturn true;\n\t}\n\n\tskip_space(cp);\n\n\tvString *chunk_label  = vStringNew ();\n\tbool anonymous = false;\n\twhile (isalnum((unsigned char)*cp) || *cp == '-')\n\t\tvStringPut (chunk_label, *cp++);\n\n\tif (vStringLength (chunk_label) == 0)\n\t{\n\t\tanonGenerate (chunk_label, \"__anon\", K_CHUNK_LABEL);\n\t\tanonymous = true;\n\t}\n\n\tskip_space(cp);\n\tif (*cp == ',' || *cp == '}')\n\t\tquarto->lastChunkLabel = makeQuartoTag (chunk_label,\n\t\t\t\t\t\t\t\t\t\t\t\tK_CHUNK_LABEL,\n\t\t\t\t\t\t\t\t\t\t\t\tanonymous);\n\n\tvStringDelete (chunk_label);\n\treturn true;\n}\n\nstatic void notifyCodeBlockLine (markdownSubparser *s,\n\t\t\t\t\t\t\t\t const unsigned char *line)\n{\n\tstruct sQuartoSubparser *quarto = (struct sQuartoSubparser *)s;\n\n\tif (strncmp ((const char *)line, \"#| \", 3))\n\t\treturn;\n\n\tline += 3;\n\tskip_space (line);\n\n\tif (strncmp ((const char *)line, \"label:\", 6))\n\t\treturn;\n\n\tline += 6;\n\tskip_space (line);\n\n\tif (!*line)\n\t\treturn;\n\n\tvString *label = vStringNewInit ((const char *)line);\n\tvStringStripTrailing (label);\n\tif (!vStringIsEmpty (label))\n\t{\n\t\t/* If an anonymous tag is made for the label of this code chunk,\n\t\t * it becomes unnecessary; the real one can be made from\n\t\t * \"#! label: ...\" */\n\t\tif (quarto->lastChunkLabel != CORK_NIL)\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (quarto->lastChunkLabel);\n\t\t\tif (e && isTagExtraBitMarked (e, XTAG_ANONYMOUS))\n\t\t\t\tmarkTagAsPlaceholder (e, true);\n\t\t}\n\n\t\tquarto->lastChunkLabel = makeQuartoTag (label,\n\t\t\t\t\t\t\t\t\t\t\t\tK_CHUNK_LABEL,\n\t\t\t\t\t\t\t\t\t\t\t\tfalse);\n\t}\n\tvStringDelete (label);\n}\n\nstatic void notifyEndOfCodeBlock (markdownSubparser *s)\n{\n\tstruct sQuartoSubparser *quarto = (struct sQuartoSubparser *)s;\n\n\tif (quarto->lastChunkLabel == CORK_NIL)\n\t\treturn;\n\n\tsetTagEndLineToCorkEntry (quarto->lastChunkLabel, getInputLineNumber ());\n\n\tquarto->lastChunkLabel = CORK_NIL;\n}\n\nstatic void inputStart (subparser *s)\n{\n\tstruct sQuartoSubparser *quatro = (struct sQuartoSubparser*)s;\n\n\tquatro->lastChunkLabel = CORK_NIL;\n}\n\nextern parserDefinition* QuartoParser (void)\n{\n\tstatic const char *const extensions [] = { \"qmd\", NULL };\n\tstatic struct sQuartoSubparser quartoSubparser = {\n\t\t.markdown = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t\t\t.inputStart = inputStart,\n\t\t\t},\n\t\t\t.extractLanguageForCodeBlock = extractLanguageForCodeBlock,\n\t\t\t.notifyCodeBlockLine = notifyCodeBlockLine,\n\t\t\t.notifyEndOfCodeBlock = notifyEndOfCodeBlock,\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Markdown\", &quartoSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"Quarto\");\n\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE(dependencies);\n\tdef->kindTable      = QuartoKinds;\n\tdef->kindCount  = ARRAY_SIZE (QuartoKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findQuartoTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/r-r6class.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for R6Class.\n*   https://www.rdocumentation.org/packages/R6/versions/2.4.1/topics/R6Class\n*/\n\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include \"x-r.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"entry.h\"\n#include \"tokeninfo.h\"\n#include \"read.h\"\n\n#include <string.h>\n\n\n/*\n*   DATA DECLARATIONS\n*/\n\nstruct r6Subparser {\n\trSubparser r;\n\tconst char * access;\n\tbool activeBinding;\n};\n\n/*\n* FUNCTION PROTOTYPES\n*/\n\nstatic int r6ReadRightSideSymbol (rSubparser *s,\n\t\t\t\t\t\t\t\t  tokenInfo *const symbol,\n\t\t\t\t\t\t\t\t  const char *const assignmentOperator,\n\t\t\t\t\t\t\t\t  int parent,\n\t\t\t\t\t\t\t\t  tokenInfo *const token);\nstatic int r6MakeTagWithTranslation (rSubparser *s,\n\t\t\t\t\t\t\t\t\t tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t int parent,\n\t\t\t\t\t\t\t\t\t bool in_func,\n\t\t\t\t\t\t\t\t\t int kindInR,\n\t\t\t\t\t\t\t\t\t const char *const assignmentOperator);\nstatic bool r6AskTagAcceptancy (rSubparser *s, tagEntryInfo *pe);\nstatic bool r6HasFunctionAlikeKind (rSubparser *s, tagEntryInfo *e);\n\nstatic void parseClass (rSubparser *s, tokenInfo *const token, int classIndex);\n\n\n/*\n*   DATA DEFINITIONS\n*/\n\ntypedef enum {\n\tR6_K_CLASS,\n\tR6_K_METHOD,\n\tR6_K_FIELD,\n\tR6_K_ACTIVE_BINDING_FUNCTION,\n} r6Kind;\n\nstatic kindDefinition R6Kinds[] = {\n\t{ true, 'c', \"class\",  \"classes\" },\n\t{ true, 'm', \"method\", \"methods\" },\n\t{ true, 'f', \"field\",  \"fields\" },\n\t{ true, 'a', \"activeBindingFunc\", \"active binding functions\" },\n};\n\nstatic struct r6Subparser r6Subparser = {\n\t.r = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t},\n\t\t.readRightSideSymbol = r6ReadRightSideSymbol,\n\t\t.makeTagWithTranslation = r6MakeTagWithTranslation,\n\t\t.askTagAcceptancy = r6AskTagAcceptancy,\n\t\t.hasFunctionAlikeKind = r6HasFunctionAlikeKind,\n\t},\n\t.access = NULL,\n\t.activeBinding = false,\n};\n\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n/*\n *       parse this area:              V======V\n * klass = R6Class(\"klass\", ..., inherit=parent)\n */\nstatic void parseInherit (rSubparser *s,\n\t\t\t\t\t\t\ttokenInfo *const token, int classIndex)\n{\n\trTokenReadNoNewline (token);\n\tif (tokenIsTypeVal (token, '='))\n\t{\n\t\trTokenReadNoNewline (token);\n\t\tif (tokenIsType (token, R_SYMBOL))\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (classIndex);\n\t\t\te->extensionFields.inheritance = vStringStrdup (token->string);\n\t\t}\n\t\telse\n\t\t\ttokenUnread (token);\n\t}\n\telse\n\t\ttokenUnread (token);\n}\n\n/*\n *       parse this area:              V===V              V===V             V===V\n * klass = R6Class(\"klass\", public=list(...), private=list(...), active=list(...), ...)\n */\nstatic void parseListMain (rSubparser *s,\n\t\t\t\t\t\t\t tokenInfo *const token, int classIndex, const char *access,\n\t\t\t\t\t\t\t bool activeBinding)\n{\n\tconst char *last_access = ((struct r6Subparser *)s)->access;\n\t((struct r6Subparser *)s)->access = access;\n\n\tbool last_active_binding = ((struct r6Subparser *)s)->activeBinding;\n\t((struct r6Subparser *)s)->activeBinding = activeBinding;\n\n\trTokenReadNoNewline (token);\n\n\twhile (! tokenIsTypeVal (token, ')'))\n\t{\n\t\tif (!rParseStatement (token, classIndex, false))\n\t\t\tbreak;\n\t\telse if (tokenIsTypeVal (token, '\\n'))\n\t\t\trTokenReadNoNewline (token);\n\t}\n\t((struct r6Subparser *)s)->access = last_access;\n\t((struct r6Subparser *)s)->activeBinding = last_active_binding;\n}\n\n/*\n *       parse this area:        V=====|---V        V=====|---V       V=====|---V\n * klass = R6Class(\"klass\", public=list(...), private=list(...), active=list(...), ...)\n */\nstatic void parseList (rSubparser *s,\n\t\t\t\t\t   tokenInfo *const token, int classIndex, const char *access,\n\t\t\t\t\t   bool activeBinding)\n{\n\trTokenReadNoNewline (token);\n\tif (tokenIsTypeVal (token, '='))\n\t{\n\t\trTokenReadNoNewline (token);\n\t\tif (tokenIsKeyword (token, R_LIST))\n\t\t{\n\t\t\trTokenReadNoNewline (token);\n\t\t\tif (tokenIsTypeVal (token, '('))\n\t\t\t\tparseListMain (s, token, classIndex, access, activeBinding);\n\t\t\telse\n\t\t\t\ttokenUnread (token);\n\t\t}\n\t\telse\n\t\t\ttokenUnread (token);\n\t}\n\telse\n\t\ttokenUnread (token);\n}\n\n/*\n *      parse this area: V=======|----V=======|----V======|----V=======|----V\n * klass = R6Class(\"klass\", public=..., private=..., active=..., inherit=...)\n */\nstatic void parseClass (rSubparser *s,\n\t\t\t\t\t\t  tokenInfo *const token, int classIndex)\n{\n\tdo\n\t{\n\t\trTokenReadNoNewline (token);\n\n\t\tif (tokenIsTypeVal (token, ')'))\n\t\t\tbreak;\n\t\telse if (tokenIsTypeVal (token, '('))\n\t\t\ttokenSkipOverPair (token);\n\t\telse if (tokenIsTypeVal (token, '{'))\n\t\t\ttokenSkipOverPair (token);\n\t\telse if (tokenIsTypeVal (token, '['))\n\t\t\ttokenSkipOverPair (token);\n\t\telse if (tokenIsType (token, R_SYMBOL))\n\t\t{\n\t\t\tconst char *str = tokenString (token);\n\t\t\tif (strcmp (str, \"inherit\") == 0)\n\t\t\t\tparseInherit (s, token, classIndex);\n\t\t\telse if (strcmp (str, \"public\") == 0)\n\t\t\t\tparseList (s, token, classIndex, \"public\", false);\n\t\t\telse if (strcmp (str, \"private\") == 0)\n\t\t\t\tparseList (s, token, classIndex, \"private\", false);\n\t\t\telse if (strcmp (str, \"active\") == 0)\n\t\t\t\tparseList (s, token, classIndex, \"public\", true);\n\t\t}\n\t}\n\twhile (!tokenIsEOF (token));\n}\n\n/*\n *         V=============|-----V: parse this area\n * klass = R6Class(\"klass\", ...)\n */\nstatic int r6ReadRightSideSymbol (rSubparser *s,\n\t\t\t\t\t\t\t\t  tokenInfo *const symbol,\n\t\t\t\t\t\t\t\t  const char *const assignmentOperator,\n\t\t\t\t\t\t\t\t  int parent,\n\t\t\t\t\t\t\t\t  tokenInfo *const token)\n{\n\ttokenInfo * token0 = NULL;\n\ttokenInfo * token1 = NULL;\n\tif (strcmp (tokenString (token), \"R6\") == 0)\n\t{\n\t\ttoken0 = rNewToken ();\n\t\ttokenRead (token0);\n\t\tif (!tokenIsType (token0, R_SCOPE))\n\t\t\tgoto reject;\n\t\tif (strcmp (tokenString (token0), \"::\"))\n\t\t\tgoto reject;\n\n\t\ttoken1 = rNewToken ();\n\t\ttokenRead (token1);\n\t\tif (!tokenIsType (token1, R_SYMBOL))\n\t\t\tgoto reject;\n\t\tif (strcmp (tokenString (token1), \"R6Class\"))\n\t\t\tgoto reject;\n\t\ttokenCopy (token, token1);\n\t\ttokenDelete (token1);\n\t\ttokenDelete (token0);\n\t\ttoken0 = token1 = NULL;\n\t}\n\telse if (strcmp (tokenString (token), \"R6Class\") != 0)\n\t\treturn CORK_NIL;\n\n\trTokenReadNoNewline (token);\n\tif (tokenIsTypeVal (token, '('))\n\t{\n\t\tint corkIndex = makeSimpleTag (symbol->string, R6_K_CLASS);\n\t\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\t\tif (e)\n\t\t\te->extensionFields.scopeIndex = parent;\n\t\tparseClass (s, token, corkIndex);\n\t\treturn corkIndex;\n\t}\n\treturn CORK_NIL;\n reject:\n\t/* For incomplete \"R6::\" cases, we don't want to unread the \"::\" token\n\t   as the main R parser may not handle it well. */\n\tif (token1 && tokenIsType(token1, R_SYMBOL)) {\n\t\ttokenUnread (token1);\n\t}\n\t/* Don't unread token0 (::) to prevent main parser confusion */\n\ttokenDelete (token1);\n\ttokenDelete (token0);\n\n\treturn CORK_NIL;\n}\n\nstatic int r6MakeTagWithTranslation (rSubparser *s,\n\t\t\t\t\t\t\t\t\t tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t int parent,\n\t\t\t\t\t\t\t\t\t bool in_func,\n\t\t\t\t\t\t\t\t\t int kindInR,\n\t\t\t\t\t\t\t\t\t const char *const assignmentOperator)\n{\n\ttagEntryInfo e;\n\n\tinitTagEntry (&e, tokenString (token),\n\t\t\t\t  in_func\n\t\t\t\t  ? (((struct r6Subparser*)s)->activeBinding\n\t\t\t\t\t ? R6_K_ACTIVE_BINDING_FUNCTION\n\t\t\t\t\t : R6_K_METHOD)\n\t\t\t\t  : R6_K_FIELD);\n\te.extensionFields.scopeIndex = parent;\n\te.extensionFields.access = ((struct r6Subparser*)s)->access;\n\n\treturn makeTagEntry (&e);\n}\n\nstatic bool r6AskTagAcceptancy (rSubparser *s, tagEntryInfo *pe)\n{\n\treturn (pe->kindIndex == R6_K_CLASS);\n}\n\nstatic bool r6HasFunctionAlikeKind (rSubparser *s,\n\t\t\t\t\t\t\t\t\ttagEntryInfo *e)\n{\n\treturn e->kindIndex == R6_K_METHOD ||\n\t\te->kindIndex == R6_K_ACTIVE_BINDING_FUNCTION;\n}\n\nstatic void findR6Tags(void)\n{\n\tr6Subparser.access = NULL;\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nextern parserDefinition* R6ClassParser (void)\n{\n\tparserDefinition* const def = parserNew(\"R6Class\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"R\", &r6Subparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = R6Kinds;\n\tdef->kindCount = ARRAY_SIZE(R6Kinds);\n\n\tdef->parser =  findR6Tags;\n\tdef->useCork = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/r-s4class.c",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for S4 Classes and Methods.\n*   https://www.r-project.org/conferences/useR-2004/Keynotes/Leisch.pdf\n*/\n\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include \"x-r.h\"\n#include \"kind.h\"\n#include \"tokeninfo.h\"\n#include \"parse.h\"\n#include \"subparser.h\"\n\n#include <string.h>\n\n\n/*\n*   DATA DECLARATIONS\n*/\n\nstruct s4Subparser {\n\trSubparser r;\n};\n\n\n/*\n* FUNCTION PROTOTYPES\n*/\n\nstatic int s4ReadFuncall (rSubparser *s,\n\t\t\t\t\t\t  tokenInfo *const func, tokenInfo *const token,\n\t\t\t\t\t\t  int parent);\nstatic int s4ReadRightSideSymbol (rSubparser *s,\n\t\t\t\t\t\t\t\t  tokenInfo *const symbol,\n\t\t\t\t\t\t\t\t  const char *const assignmentOperator,\n\t\t\t\t\t\t\t\t  int parent,\n\t\t\t\t\t\t\t\t  tokenInfo *const token);\nstatic bool s4AskTagAcceptancy (rSubparser *s, tagEntryInfo *pe);\nstatic bool s4HasFunctionAlikeKind (rSubparser *s, tagEntryInfo *e);\n\n\n/*\n*   DATA DEFINITIONS\n*/\n\ntypedef enum {\n\tS4_K_CLASS,\n\tS4_K_REPRESENTATION,\n\tS4_K_GENERIC,\n\tS4_K_METHOD,\n} s4Kind;\n\nstatic kindDefinition S4Kinds[] = {\n\t{ true, 'c', \"class\",   \"classes\" },\n\t{ true, 'r', \"repr\",    \"representations\" },\n\t{ true, 'g', \"generic\", \"generics\" },\n\t{ true, 'm', \"method\",  \"methods\" },\n};\n\nstatic struct s4Subparser s4Subparser = {\n\t.r = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t},\n\t\t.readFuncall = s4ReadFuncall,\n\t\t.readRightSideSymbol = s4ReadRightSideSymbol,\n\t\t.askTagAcceptancy = s4AskTagAcceptancy,\n\t\t.hasFunctionAlikeKind = s4HasFunctionAlikeKind,\n\t},\n};\n\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n/*\n * V=================V: parse this area\n * representation(...)) ...\n * representation(...), ...\n */\nstatic void parseRepresentation (rSubparser *s, tokenInfo *const token, int parent)\n{\n\trTokenReadNoNewline (token);\n\tif (tokenIsTypeVal (token, '('))\n\t{\n\t\trTokenReadNoNewline (token);\n\t\twhile (!(tokenIsTypeVal (token, ')') || tokenIsTypeVal (token, ',')))\n\t\t{\n\t\t\tif (!rParseStatement (token, parent, false))\n\t\t\t\tbreak;\n\t\t\telse if (tokenIsTypeVal (token, '\\n'))\n\t\t\t\trTokenReadNoNewline (token);\n\t\t}\n\t}\n\telse\n\t\ttokenUnread (token);\n}\n\n/*\n * V==============V: parse this area\n * contains = \"...\"\n */\nstatic void parseContains (rSubparser *s, tokenInfo *const token, int parent)\n{\n\trTokenReadNoNewline (token);\n\tif (tokenIsTypeVal (token, '='))\n\t{\n\t\trTokenReadNoNewline (token);\n\t\tif (tokenIsType (token, R_STRING))\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (parent);\n\t\t\tif (e)\n\t\t\t{\n\t\t\t\tvString *n = rExtractNameFromString (token->string);\n\t\t\t\te->extensionFields.inheritance = vStringDeleteUnwrap (n);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\ttokenUnread (token);\n\t}\n\telse\n\t\ttokenUnread (token);\n}\n\n/*\n *                  V====V: parse this area\n * setClass (\"class\", ...)\n */\nstatic bool parseClassArgs (rSubparser *s, tokenInfo *const token, int parent,\n\t\t\t\t\t\t\ttokenInfo *const open_paren CTAGS_ATTR_UNUSED)\n{\n\tdo\n\t{\n\t\trTokenReadNoNewline (token);\n\n\t\tif (tokenIsTypeVal (token, ')'))\n\t\t\tbreak;\n\t\telse if (tokenIsTypeVal (token, '('))\n\t\t\ttokenSkipOverPair (token);\n\t\telse if (tokenIsTypeVal (token, '{'))\n\t\t\ttokenSkipOverPair (token);\n\t\telse if (tokenIsTypeVal (token, '['))\n\t\t\ttokenSkipOverPair (token);\n\t\telse if (tokenIsType (token, R_SYMBOL))\n\t\t{\n\t\t\tconst char *str = tokenString (token);\n\t\t\tif (strcmp (str, \"representation\") == 0)\n\t\t\t\tparseRepresentation (s, token, parent);\n\t\t\telse if (strcmp (str, \"contains\") == 0)\n\t\t\t\tparseContains (s, token, parent);\n\t\t}\n\t}\n\twhile (!tokenIsEOF (token));\n\n\treturn false;\n}\n\n/*\n *                    V============V: parse this area\n * setMethod (\"method\", c(...), ...)\n *                    V====================V: parse this area\n * setMethod (\"method\", signature(...), ...)\n *\n * Attaching c(...) or signature(...) to \"signature:\" field of\n * the tag for \"method\" specified by parent.\n */\nstatic bool parseMethodArgs (rSubparser *s, tokenInfo *const token, int parent,\n\t\t\t\t\t\t\t tokenInfo *const open_paren)\n{\n\trTokenReadNoNewline (token);\n\tif (tokenIsTypeVal (token, ','))\n\t{\n\t\trTokenReadNoNewline (token);\n\t\tif (tokenIsKeyword (token, R_C)\n\t\t\t|| (tokenIsType (token, R_SYMBOL)\n\t\t\t\t&& (strcmp (tokenString (token), \"signature\") == 0)))\n\t\t{\n\t\t\trTokenReadNoNewline (token);\n\t\t\tif (tokenIsTypeVal (token, '('))\n\t\t\t{\n\t\t\t\tvString *signature = vStringNewInit(\"(\");\n\t\t\t\trSetupCollectingSignature (token, signature);\n\t\t\t\ttokenSkipOverPair (token);\n\t\t\t\trTeardownCollectingSignature (token);\n\t\t\t\ttagEntryInfo *e = getEntryInCorkQueue (parent);\n\t\t\t\tif (e)\n\t\t\t\t{\n\t\t\t\t\te->extensionFields.signature = vStringDeleteUnwrap (signature);\n\t\t\t\t\tsignature = NULL;\n\t\t\t\t}\n\t\t\t\tvStringDelete (signature); /* NULL is acceptable */\n\t\t\t}\n\t\t\trTokenReadNoNewline (token);\n\t\t\tif (tokenIsTypeVal (token, ','))\n\t\t\t{\n\t\t\t\trTokenReadNoNewline (token);\n\t\t\t\t/* anonymous function for implementing this method may be here.*/\n\t\t\t\twhile (!tokenIsTypeVal (token, ')'))\n\t\t\t\t{\n\t\t\t\t\tif (!rParseStatement (token, parent, true))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\telse if (tokenIsTypeVal (token, '\\n'))\n\t\t\t\t\t\trTokenReadNoNewline (token);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t\ttokenUnread (token);\n\t}\n\telse\n\t\ttokenUnread (token);\n\treturn true;\n}\n\n/*\n *                      V====V: parse this area\n * setGeneric (\"generic\", ...)\n */\nstatic bool parseGenericArgs (rSubparser *s, tokenInfo *const token, int parent,\n\t\t\t\t\t\t\t  tokenInfo *const open_paren)\n{\n\twhile (!tokenIsTypeVal (token, ')'))\n\t{\n\t\tif (!rParseStatement (token, parent, true))\n\t\t\tbreak;\n\t\telse if (tokenIsTypeVal (token, '\\n'))\n\t\t\trTokenReadNoNewline (token);\n\t}\n\treturn false;\n}\n\n/* parse\n * this\n * area ---\\          /--- parseArgs parses this area.\n *         V====VV----V\n *   setXXX(\"...\", ...)\n */\nstatic int parseSetCommon (rSubparser *s, tokenInfo *const token, int parent,\n\t\t\t\t\t\t   int kind,\n\t\t\t\t\t\t   bool (* parseArgs) (rSubparser *, tokenInfo *const, int, tokenInfo *const))\n{\n\tint q = CORK_NIL;\n\ttokenInfo *const open_paren = newTokenByCopying (token);\n\n\trTokenReadNoNewline (token);\n\tif (tokenIsType (token, R_STRING))\n\t{\n\t\tvString *n = rExtractNameFromString (token->string);\n\t\tif (n)\n\t\t{\n\t\t\tq = makeSimpleTag (n, kind);\n\t\t\tvStringDelete (n);\n\t\t}\n\t}\n\n\tbool skip = true;\n\tif (q != CORK_NIL && parseArgs)\n\t\tskip = (* parseArgs) (s, token, q, open_paren);\n\n\tif (skip)\n\t{\n\t\ttokenCopy (token, open_paren);\n\t\ttokenSkipOverPair (token);\n\t}\n\n\ttokenDelete (open_paren);\n\treturn q;\n}\n\nstatic int parseSetClass (rSubparser *s, tokenInfo *const token, int parent)\n{\n\treturn parseSetCommon (s, token, parent, S4_K_CLASS, parseClassArgs);\n}\n\nstatic int parseSetGeneric (rSubparser *s, tokenInfo *const token, int parent)\n{\n\treturn parseSetCommon (s, token, parent, S4_K_GENERIC, parseGenericArgs);\n}\n\nstatic int parseSetMethod (rSubparser *s, tokenInfo *const token, int parent)\n{\n\treturn parseSetCommon (s, token, parent, S4_K_METHOD, parseMethodArgs);\n}\n\nstatic int s4ReadFuncall (rSubparser *s,\n\t\t\t\t\t\t  tokenInfo *const func, tokenInfo *const token,\n\t\t\t\t\t\t  int parent)\n{\n\tif (strcmp (tokenString (func), \"setClass\") == 0)\n\t\treturn parseSetClass (s, token, parent);\n\telse if (strcmp (tokenString (func), \"setGeneric\") == 0)\n\t\treturn parseSetGeneric (s, token, parent);\n\telse if (strcmp (tokenString (func), \"setMethod\") == 0)\n\t\treturn parseSetMethod (s, token, parent);\n\telse\n\t\treturn CORK_NIL;\n}\n\nstatic bool s4AskTagAcceptancy (rSubparser *s, tagEntryInfo *pe)\n{\n\treturn (pe->kindIndex == S4_K_CLASS);\n}\n\nstatic bool s4HasFunctionAlikeKind (rSubparser *s, tagEntryInfo *e)\n{\n\treturn e->kindIndex == S4_K_METHOD ||\n\t\te->kindIndex == S4_K_GENERIC;\n}\n\n/*\n * setClass(\"class\", representation(r0 = \"t0\", r1 = \"t1\", ...\n *\n * Attaching t as \"typeref:typename:\" field of r.\n *\n * the tag for \"class\" -> parent.\n * r0, r1, ... -> symbol\n */\nstatic int s4ReadRightSideSymbol (rSubparser *s,\n\t\t\t\t\t\t\t\t  tokenInfo *const symbol,\n\t\t\t\t\t\t\t\t  const char *const assignmentOperator,\n\t\t\t\t\t\t\t\t  int parent,\n\t\t\t\t\t\t\t\t  tokenInfo *const token)\n{\n\ttagEntryInfo *pe = getEntryInCorkQueue (parent);\n\tif (! (pe\n\t\t   && pe->langType == s->subparser.slaveParser->id\n\t\t   && pe->kindIndex == S4_K_CLASS))\n\t\treturn CORK_NIL;\n\n\ttagEntryInfo e;\n\tint q;\n\tvString *t = NULL;\n\n\tif (tokenIsType (token, R_STRING))\n\t\tt = rExtractNameFromString (token->string);\n\n\tinitTagEntry (&e, tokenString (symbol), S4_K_REPRESENTATION);\n\te.extensionFields.scopeIndex = parent;\n\tif (t)\n\t{\n\t\te.extensionFields.typeRef[0] = \"typename\";\n\t\te.extensionFields.typeRef[1] = vStringValue (t);\n\t}\n\tq = makeTagEntry (&e);\n\tvStringDelete (t);\t\t\t/* NULL is acceptable. */\n\n\treturn q;\n}\n\nstatic void findS4Tags(void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nextern parserDefinition* S4ClassParser (void)\n{\n\tparserDefinition* const def = parserNew(\"S4Class\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"R\", &s4Subparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = S4Kinds;\n\tdef->kindCount = ARRAY_SIZE(S4Kinds);\n\n\tdef->parser =  findS4Tags;\n\tdef->useCork = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/r.c",
    "content": "/*\n*   Copyright (c) 2003-2004, Ascher Stefan <stievie@utanet.at>\n*   Copyright (c) 2020, Masatake YAMATO <yamato@redhat.com>\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for R language files.\n*   R is a programming language for statistical computing.\n*   R is GPL Software, get it from http://www.r-project.org/\n*\n*   The language references are available at\n*   https://cran.r-project.org/manuals.html, and\n*   https://cran.r-project.org/doc/manuals/r-release/R-lang.html\n*\n*   The base library (including library and source functions) release is at\n*   https://stat.ethz.ch/R-manual/R-devel/library/base/html/00Index.html\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"selectors.h\"\n#include \"tokeninfo.h\"\n#include \"trace.h\"\n#include \"vstring.h\"\n#include \"subparser.h\"\n#include \"x-r.h\"\n\n#include <string.h>\n#include <ctype.h>\t/* to define isalpha(), isalnum(), isspace() */\n\n\n/*\n*   MACROS\n*/\n#ifdef DEBUG\n#define R_TRACE_TOKEN_TEXT(TXT,T,Q) TRACE_PRINT(\"<%s> token: %s (%s), parent: %s\", \\\n\t\t\t\t\t\t\t\t\t\t\t\t(TXT),\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\ttokenIsTypeVal(T, '\\n')? \"\\\\n\": tokenString(T), \\\n\t\t\t\t\t\t\t\t\t\t\t\ttokenTypeStr(T->type),\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t(Q) == CORK_NIL? \"\": getEntryInCorkQueue(Q)->name)\n#define R_TRACE_TOKEN(T,Q) TRACE_PRINT(\"token: %s (%s), parent: %s\", \\\n\t\t\t\t\t\t\t\t\t   tokenIsTypeVal((T), '\\n')? \"\\\\n\": tokenString(T), \\\n\t\t\t\t\t\t\t\t\t   tokenTypeStr((T)->type),\t\t\t\\\n\t\t\t\t\t\t\t\t\t   (Q) == CORK_NIL? \"\": getEntryInCorkQueue(Q)->name)\n\n#define R_TRACE_ENTER() TRACE_ENTER_TEXT(\"token: %s (%s), parent: %s\", \\\n\t\t\t\t\t\t\t\t\t\t tokenIsTypeVal(token, '\\n')? \"\\\\n\": tokenString(token), \\\n\t\t\t\t\t\t\t\t\t\t tokenTypeStr(token->type), \\\n\t\t\t\t\t\t\t\t\t\t parent == CORK_NIL? \"\": getEntryInCorkQueue(parent)->name)\n#define R_TRACE_LEAVE() TRACE_LEAVE()\n#else\n#define R_TRACE_TOKEN_TEXT(TXT,T,Q) do {} while (0);\n#define R_TRACE_TOKEN(T,Q) do {} while (0);\n#define R_TRACE_ENTER() do {} while (0);\n#define R_TRACE_LEAVE() do {} while (0);\n#endif\n\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_UNDEFINED = -1,\n\tK_FUNCTION,\n\tK_LIBRARY,\n\tK_SOURCE,\n\tK_GLOBALVAR,\n\tK_FUNCVAR,\n\tK_PARAM,\n\tK_VECTOR,\n\tK_LIST,\n\tK_DATAFRAME,\n\tK_NAMEATTR,\n\tKIND_COUNT\n} rKind;\n\ntypedef enum {\n\tR_LIBRARY_ATTACHED_BY_LIBRARY,\n\tR_LIBRARY_ATTACHED_BY_REQUIRE,\n} rLibraryRole;\n\ntypedef enum {\n\tR_SOURCE_LOADED_BY_SOURCE,\n} rSourceRole;\n\nstatic roleDefinition RLibraryRoles [] = {\n\t{ true, \"library\", \"library attached by library function\" },\n\t{ true, \"require\", \"library attached by require function\" },\n};\n\nstatic roleDefinition RSourceRoles [] = {\n\t{ true, \"source\", \"source loaded by source fucntion\" },\n};\n\nstatic kindDefinition RKinds[KIND_COUNT] = {\n\t{true, 'f', \"function\", \"functions\"},\n\t{true, 'l', \"library\", \"libraries\",\n\t .referenceOnly = true, ATTACH_ROLES (RLibraryRoles) },\n\t{true, 's', \"source\", \"sources\",\n\t .referenceOnly = true, ATTACH_ROLES (RSourceRoles) },\n\t{true, 'g', \"globalVar\", \"global variables having values other than function()\"},\n\t{true, 'v', \"functionVar\", \"function variables having values other than function()\"},\n\t{false,'z', \"parameter\",  \"function parameters inside function definitions\" },\n\t{true, 'c', \"vector\", \"vectors explicitly created with `c()'\" },\n\t{true, 'L', \"list\", \"lists explicitly created with `list()'\" },\n\t{true, 'd', \"dataframe\", \"data frame explicitly created with `data.frame()'\" },\n\t{true, 'n', \"nameattr\", \"names attribtes in vectors, lists, or dataframes\" },\n};\n\nstruct sKindExtraInfo {\n\tconst char *anon_prefix;\n\tconst char *ctor;\n};\n\nstatic struct sKindExtraInfo kindExtraInfo[KIND_COUNT] = {\n\t[K_FUNCTION] = {\n\t\t\"anonFunc\",\n\t\t\"function\",\n\t},\n\t[K_VECTOR] = {\n\t\t\"anonVec\",\n\t\t\"c\",\n\t},\n\t[K_LIST] = {\n\t\t\"anonList\",\n\t\t\"list\",\n\t},\n\t[K_DATAFRAME] = {\n\t\t\"anonDataFrame\",\n\t\t\"data.frame\",\n\t},\n};\n\ntypedef enum {\n\tF_ASSIGNMENT_OPERATOR,\n\tF_CONSTRUCTOR,\n} rField;\n\nstatic fieldDefinition RFields [] = {\n\t{\n\t\t.name = \"assignmentop\",\n\t\t.description = \"operator for assignment\",\n\t\t.enabled = false,\n\t},\n\t{\n\t\t.name = \"constructor\",\n\t\t.description = \"function used for making value assigned to the nameattr tag\",\n\t\t.enabled = true,\n\t}\n};\n\ntypedef int keywordId;\t\t\t/* to allow KEYWORD_NONE */\n\nstatic const keywordTable RKeywordTable [] = {\n\t{ \"c\",        KEYWORD_R_C        },\n\t{ \"list\",     KEYWORD_R_LIST     },\n\t{ \"data.frame\",KEYWORD_R_DATAFRAME },\n\t{ \"function\", KEYWORD_R_FUNCTION },\n\t{ \"if\",       KEYWORD_R_IF       },\n\t{ \"else\",     KEYWORD_R_ELSE     },\n\t{ \"for\",      KEYWORD_R_FOR      },\n\t{ \"while\",    KEYWORD_R_WHILE    },\n\t{ \"repeat\",   KEYWORD_R_REPEAT   },\n\t{ \"in\",       KEYWORD_R_IN       },\n\t{ \"next\",     KEYWORD_R_NEXT     },\n\t{ \"break\",    KEYWORD_R_BREAK    },\n\t{ \"TRUE\",     KEYWORD_R_TRUE,    },\n\t{ \"FALSE\",    KEYWORD_R_FALSE,   },\n\t{ \"NULL\",     KEYWORD_R_NULL,    },\n\t{ \"Inf\",      KEYWORD_R_INF,     },\n\t{ \"NaN\",      KEYWORD_R_NAN,     },\n\t{ \"NA\",       KEYWORD_R_NA,      },\n\t{ \"NA_integer_\",   KEYWORD_R_NA, },\n\t{ \"NA_real_\",      KEYWORD_R_NA, },\n\t{ \"NA_complex_\",   KEYWORD_R_NA, },\n\t{ \"NA_character_\", KEYWORD_R_NA, },\n\t{ \"source\",   KEYWORD_R_SOURCE   },\n\t{ \"library\",  KEYWORD_R_LIBRARY  },\n\t{ \"require\",  KEYWORD_R_LIBRARY  },\n};\n\n#ifdef DEBUG\nstatic const char *tokenTypeStr(enum RTokenType e);\n#endif\n\nstatic struct tokenTypePair typePairs [] = {\n\t{ '{', '}' },\n\t{ '[', ']' },\n\t{ '(', ')' },\n};\n\ntypedef struct sRToken {\n\ttokenInfo base;\n\tint scopeIndex;\n\tint parenDepth;\n\tvString *signature;\n\tint kindIndexForParams;\t\t/* Used only when gathering parameters */\n} rToken;\n\n#define R(TOKEN) ((rToken *)TOKEN)\n\nstatic int blackHoleIndex;\n\nstatic langType Lang_R;\n\nstatic void readToken (tokenInfo *const token, void *data);\nstatic void clearToken (tokenInfo *token);\nstatic struct tokenInfoClass rTokenInfoClass = {\n\t.nPreAlloc        = 4,\n\t.typeForUndefined = TOKEN_R_UNDEFINED,\n\t.keywordNone      = KEYWORD_NONE,\n\t.typeForKeyword   = TOKEN_R_KEYWORD,\n\t.typeForEOF       = TOKEN_R_EOF,\n\t.extraSpace       = sizeof (rToken) - sizeof (tokenInfo),\n\t.pairs            = typePairs,\n\t.pairCount        = ARRAY_SIZE (typePairs),\n\t.init             = NULL,\n\t.read             = readToken,\n\t.clear            = clearToken,\n\t.copy             = NULL,\n};\n\n\n/*\n * FUNCTION PROTOTYPES\n */\nstatic bool parseStatement (tokenInfo *const token, int parent, bool in_arglist, bool in_continuous_pair);\nstatic void parsePair (tokenInfo *const token, int parent, tokenInfo *const funcall);\n\nstatic int notifyReadRightSideSymbol (tokenInfo *const symbol,\n\t\t\t\t\t\t\t\t\t  const char *const assignmentOperator,\n\t\t\t\t\t\t\t\t\t  int parent,\n\t\t\t\t\t\t\t\t\t  tokenInfo *const token);\nstatic int makeSimpleSubparserTag (int langType, tokenInfo *const token, int parent,\n\t\t\t\t\t\t\t\t   bool in_func, int kindInR, const char *assignmentOperator);\nstatic bool askSubparserTagAcceptancy (tagEntryInfo *pe);\nstatic bool askSubparserTagHasFunctionAlikeKind (tagEntryInfo *e);\nstatic int notifyReadFuncall (tokenInfo *const func, tokenInfo *const token, int parent);\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nstatic bool hasKindsOrCtors (tagEntryInfo * e, int kinds[], size_t count)\n{\n       if (e->langType == Lang_R)\n\t   {\n\t\t   for (size_t i = 0; i < count; i++)\n\t\t   {\n\t\t\t   if (e->kindIndex == kinds[i])\n\t\t\t\t   return true;\n\t\t   }\n\t   }\n\t   else\n\t   {\n\t\t   bool function = false;\n\t\t   for (size_t i = 0; i < count; i++)\n\t\t   {\n\t\t\t   if (K_FUNCTION == kinds[i])\n\t\t\t   {\n\t\t\t\t   function = true;\n\t\t\t\t   break;\n\t\t\t   }\n\t\t   }\n\t\t   if (function && askSubparserTagHasFunctionAlikeKind (e))\n\t\t\t   return true;\n\t   }\n\n\t   const char *tmp = getParserFieldValueForType (e,\n\t\t\t\t\t\t\t\t\t\t\t\t\t RFields [F_CONSTRUCTOR].ftype);\n\t   if (tmp == NULL)\n\t\t   return false;\n\n\t   for (size_t i = 0; i < count; i++)\n\t   {\n\t\t   const char * ctor = kindExtraInfo [kinds[i]].ctor;\n\t\t   if (ctor && strcmp (tmp, ctor) == 0)\n               return true;\n\t   }\n\n       return false;\n}\n\nstatic int searchScopeOtherThan (int scope, int kinds[], size_t count)\n{\n\tdo\n\t{\n\t\ttagEntryInfo * e = getEntryInCorkQueue (scope);\n\t\tif (!e)\n\t\t\treturn CORK_NIL;\n\n\t\tif (!hasKindsOrCtors (e, kinds, count))\n\t\t\treturn scope;\n\n\t\tscope = e->extensionFields.scopeIndex;\n\t}\n\twhile (1);\n}\n\nstatic int makeSimpleRTagR (tokenInfo *const token, int parent, int kind,\n\t\t\t\t\t\t\tconst char * assignmentOp)\n{\n\tif (assignmentOp && (strlen (assignmentOp) == 3))\n\t{\n\t\t/* <<- or ->> is used here. */\n\t\tif (anyKindsEntryInScopeRecursive (parent, tokenString (token),\n\t\t\t\t\t\t\t\t\t\t   (int[]){K_FUNCTION,\n\t\t\t\t\t\t\t\t\t\t\t\t   K_GLOBALVAR,\n\t\t\t\t\t\t\t\t\t\t\t\t   K_FUNCVAR,\n\t\t\t\t\t\t\t\t\t\t\t\t   K_PARAM}, 4,\n\t\t\t\t\t\t\t\t\t\t   false) != CORK_NIL)\n\t\t\treturn CORK_NIL;\n\n\t\tparent = CORK_NIL;\n\t}\n\n\t/* If the tag (T) to be created is defined in a scope and\n\t   the scope already has another tag having the same name\n\t   as T, T should not be created. */\n\ttagEntryInfo *pe = getEntryInCorkQueue (parent);\n\tint cousin = CORK_NIL;\n\tif (pe && ((pe->langType == Lang_R && pe->kindIndex == K_FUNCTION)\n\t\t\t   || (pe->langType != Lang_R && askSubparserTagHasFunctionAlikeKind (pe))))\n\t{\n\t\tcousin = anyEntryInScope (parent, tokenString (token), false);\n\t\tif (kind == K_GLOBALVAR)\n\t\t\tkind = K_FUNCVAR;\n\t}\n\telse if (pe && (kind == K_GLOBALVAR)\n\t\t\t && hasKindsOrCtors (pe, (int[]){K_VECTOR, K_LIST, K_DATAFRAME}, 3))\n\t{\n\t\tparent = searchScopeOtherThan (pe->extensionFields.scopeIndex,\n\t\t\t\t\t\t\t\t\t   (int[]){K_VECTOR, K_LIST, K_DATAFRAME}, 3);\n\t\tif (parent == CORK_NIL)\n\t\t\tcousin = anyKindEntryInScope (parent, tokenString (token), K_GLOBALVAR, false);\n\t\telse\n\t\t{\n\t\t\tcousin = anyKindEntryInScope (parent, tokenString (token), K_FUNCVAR, false);\n\t\t\tkind = K_FUNCVAR;\n\t\t}\n\t}\n\telse if (pe)\n\t{\n\t\t/* The condition for tagging is a bit relaxed here.\n\t\t   Even if the same name tag is created in the scope, a name\n\t\t   is tagged if kinds are different. */\n\t\tcousin = anyKindEntryInScope (parent, tokenString (token), kind, false);\n\t}\n\tif (cousin != CORK_NIL)\n\t\treturn CORK_NIL;\n\n\tint corkIndex = makeSimpleTag (token->string, kind);\n\ttagEntryInfo *tag = getEntryInCorkQueue (corkIndex);\n\tif (tag)\n\t{\n\t\ttag->extensionFields.scopeIndex = parent;\n\t\tif (assignmentOp)\n\t\t{\n\t\t\tif (strlen (assignmentOp) > 0)\n\t\t\t\tattachParserField (tag,\n\t\t\t\t\t\t\t\t   RFields [F_ASSIGNMENT_OPERATOR].ftype,\n\t\t\t\t\t\t\t\t   assignmentOp);\n\t\t\telse\n\t\t\t\tmarkTagExtraBit (tag, XTAG_ANONYMOUS);\n\t\t}\n\t\tregisterEntry (corkIndex);\n\t}\n\treturn corkIndex;\n}\n\nstatic int makeSimpleRTag (tokenInfo *const token, int parent, bool in_func, int kind,\n\t\t\t\t\t\t   const char * assignmentOp)\n{\n\tint r;\n\tconst char *ctor = kindExtraInfo [kind].ctor;\n\ttagEntryInfo *pe = (parent == CORK_NIL)? NULL: getEntryInCorkQueue (parent);\n\n\t/* makeTagWithTranslation method for subparsers\n\t   called from makeSimpleSubparserTag expects\n\t   kind should be resolved. */\n\tif (pe && hasKindsOrCtors (pe, (int[]){K_VECTOR, K_LIST, K_DATAFRAME}, 3))\n\t{\n\t\tif (assignmentOp\n\t\t\t&& strcmp (assignmentOp, \"=\") == 0)\n\t\t\tkind = K_NAMEATTR;\n\t}\n\n\tbool foreign_tag = false;\n\tif (pe == NULL || pe->langType == Lang_R ||\n\t\t!askSubparserTagAcceptancy (pe))\n\t\tr = makeSimpleRTagR (token, parent, kind, assignmentOp);\n\telse\n\t{\n\t\tforeign_tag = true;\n\t\tr = makeSimpleSubparserTag (pe->langType, token, parent, in_func,\n\t\t\t\t\t\t\t\t\tkind, assignmentOp);\n\t}\n\n\tif ((kind == K_NAMEATTR || foreign_tag) && ctor)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\t\tif (e)\n\t\t\tattachParserField (e,\n\t\t\t\t\t\t\t   RFields [F_CONSTRUCTOR].ftype,\n\t\t\t\t\t\t\t   ctor);\n\t}\n\n\treturn r;\n}\n\nstatic void clearToken (tokenInfo *token)\n{\n\tR (token)->parenDepth = 0;\n\tR (token)->scopeIndex = CORK_NIL;\n\tR (token)->kindIndexForParams = KIND_GHOST_INDEX;\n\tif (R (token)->signature)\n\t{\n\t\tvStringDelete (R (token)->signature);\n\t\tR (token)->signature = NULL;\n\t}\n}\n\nstatic void readString (tokenInfo *const token, void *data)\n{\n\tint c;\n\tbool escaped = false;\n\n\tint c0 = tokenString(token)[0];\n\n\twhile (1)\n\t{\n\t\tc = getcFromInputFile ();\n\t\tswitch (c)\n\t\t{\n\t\tcase EOF:\n\t\t\treturn;\n\t\tcase '\\'':\n\t\tcase '\"':\n\t\tcase '`':\n\t\t\ttokenPutc (token, c);\n\t\t\tif (!escaped && c == c0)\n\t\t\t\treturn;\n\t\t\tescaped = false;\n\t\t\tbreak;\n\t\tcase '\\\\':\n\t\t\ttokenPutc (token, c);\n\t\t\tescaped = !escaped;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ttokenPutc (token, c);\n\t\t\tescaped = false;\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic void readNumber (tokenInfo *const token, void *data)\n{\n\tint c;\n\n\t/* 10.3.1 Constants\n\t *\n\t * Valid numeric constants: 1 10 0.1 .2 1e-7 1.2e+7\n\t * Valid integer constants:  1L, 0x10L, 1000000L, 1e6L\n\t * Valid numeric constants:  1.1L, 1e-3L, 0x1.1p-2\n\t * Valid complex constants: 2i 4.1i 1e-2i\n\t */\n\twhile ((c = getcFromInputFile ()))\n\t{\n\t\tif (isxdigit (c) || c == '.' || c == 'E'\n\t\t\t|| c == '+' || c == '-'\n\t\t\t|| c == 'L' || c == 'x' || c == 'p'\n\t\t\t|| c == 'i')\n\t\t\ttokenPutc (token, c);\n\t\telse\n\t\t{\n\t\t\tungetcToInputFile (c);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic void readSymbol (tokenInfo *const token, void *data)\n{\n\tint c;\n\twhile ((c = getcFromInputFile ()))\n\t{\n\t\tif (isalnum (c) || c == '.' || c == '_')\n\t\t\ttokenPutc (token, c);\n\t\telse\n\t\t{\n\t\t\tungetcToInputFile (c);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic keywordId resolveKeyword (vString *string)\n{\n\tchar *s = vStringValue (string);\n\tstatic langType lang = LANG_AUTO;\n\n\tif (lang == LANG_AUTO)\n\t\tlang = getInputLanguage ();\n\n\treturn lookupCaseKeyword (s, lang);\n}\n\nstatic bool signatureExpectingParameter (vString *signature)\n{\n\tif (vStringLast (signature) == '(')\n\t\treturn true;\n\n\tfor (size_t i = vStringLength (signature); i > 0; i--)\n\t{\n\t\tchar c = vStringChar (signature, i - 1);\n\t\tif (c == ' ')\n\t\t\tcontinue;\n\t\telse if (c == ',')\n\t\t\treturn true;\n\t\tbreak;\n\t}\n\treturn false;\n}\n\nstatic void readToken (tokenInfo *const token, void *data)\n{\n\tint c, c0;\n\n\ttoken->type = TOKEN_R_UNDEFINED;\n\ttoken->keyword = KEYWORD_NONE;\n\tvStringClear (token->string);\n\n\tdo\n\t\tc = getcFromInputFile ();\n\twhile (c == ' ' || c== '\\t' || c == '\\f');\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tswitch (c)\n\t{\n\tcase EOF:\n\t\ttoken->type = TOKEN_R_EOF;\n\t\tbreak;\n\tcase '#':\n\t\twhile (1)\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == EOF)\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_R_EOF;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (c == '\\n')\n\t\t\t{\n\t\t\t\ttoken->type = c;\n\t\t\t\ttokenPutc (token, c);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase '\\n':\n\tcase ';':\n\t\ttoken->type = c;\n\t\ttokenPutc (token, c);\n\t\tbreak;\n\tcase '\\'':\n\tcase '\"':\n\tcase '`':\n\t\ttoken->type = TOKEN_R_STRING;\n\t\ttokenPutc (token, c);\n\t\treadString (token, data);\n\t\tbreak;\n\tcase '+':\n\tcase '/':\n\tcase '^':\n\tcase '~':\n\t\ttoken->type = TOKEN_R_OPERATOR;\n\t\ttokenPutc (token, c);\n\t\tbreak;\n\tcase ':':\n\t\ttoken->type = TOKEN_R_OPERATOR;\n\t\ttokenPutc (token, c);\n\t\tc = getcFromInputFile ();\n\t\tif (c == ':')\n\t\t{\n\t\t\ttokenPutc (token, c);\n\t\t\ttoken->type = TOKEN_R_SCOPE;\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == ':')\n\t\t\t\ttokenPutc (token, c);\n\t\t\telse\n\t\t\t\tungetcToInputFile (c);\n\t\t}\n\t\telse\n\t\t\tungetcToInputFile (c);\n\t\tbreak;\n\tcase '&':\n\tcase '|':\n\tcase '*':\n\t\ttoken->type = TOKEN_R_OPERATOR;\n\t\ttokenPutc (token, c);\n\t\tc0 = getcFromInputFile ();\n\t\tif (c == c0)\n\t\t\ttokenPutc (token, c0);\n\t\telse\n\t\t\tungetcToInputFile (c0);\n\t\tbreak;\n\tcase '=':\n\t\ttoken->type = TOKEN_R_OPERATOR;\n\t\ttokenPutc (token, c);\n\t\tc = getcFromInputFile ();\n\t\tif (c == '=')\n\t\t\ttokenPutc (token, c);\n\t\telse\n\t\t{\n\t\t\ttoken->type = '=';\n\t\t\tungetcToInputFile (c);\n\t\t}\n\t\tbreak;\n\tcase '-':\n\t\ttoken->type = TOKEN_R_OPERATOR;\n\t\ttokenPutc (token, c);\n\t\tc = getcFromInputFile ();\n\t\tif (c == '>')\n\t\t{\n\t\t\ttoken->type = TOKEN_R_RASSIGN;\n\t\t\ttokenPutc (token, c);\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == '>')\n\t\t\t\ttokenPutc (token, c);\n\t\t\telse\n\t\t\t\tungetcToInputFile (c);\n\t\t}\n\t\telse\n\t\t\tungetcToInputFile (c);\n\t\tbreak;\n\tcase '>':\n\t\ttoken->type = TOKEN_R_OPERATOR;\n\t\ttokenPutc (token, c);\n\t\tc = getcFromInputFile ();\n\t\tif (c == '=')\n\t\t\ttokenPutc (token, c);\n\t\telse\n\t\t\tungetcToInputFile (c);\n\t\tbreak;\n\tcase '<':\n\t\ttoken->type = TOKEN_R_OPERATOR;\n\t\ttokenPutc (token, c);\n\t\tc = getcFromInputFile ();\n\n\t\t/* <<- */\n\t\tif (c == '<')\n\t\t{\n\t\t\ttokenPutc (token, c);\n\t\t\tc = getcFromInputFile ();\n\t\t}\n\n\t\tif (c == '-')\n\t\t{\n\t\t\ttoken->type = TOKEN_R_LASSIGN;\n\t\t\ttokenPutc (token, c);\n\t\t}\n\t\telse if (c == '=')\n\t\t\ttokenPutc (token, c);\n\t\telse\n\t\t\tungetcToInputFile (c);\n\t\tbreak;\n\tcase '%':\n\t\ttoken->type = TOKEN_R_OPERATOR;\n\t\ttokenPutc (token, c);\n\t\tdo\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == EOF)\n\t\t\t\tbreak;\n\n\t\t\ttokenPutc (token, c);\n\t\t\tif (c == '%')\n\t\t\t\tbreak;\n\t\t}\n\t\twhile (1);\n\t\tbreak;\n\tcase '!':\n\t\ttoken->type = TOKEN_R_OPERATOR;\n\t\ttokenPutc (token, c);\n\t\tc = getcFromInputFile ();\n\t\tif (c == '=')\n\t\t\ttokenPutc (token, c);\n\t\telse\n\t\t\tungetcToInputFile (c);\n\t\tbreak;\n\tcase '{':\n\tcase '}':\n\tcase '(':\n\tcase ')':\n\tcase '[':\n\tcase ']':\n\tcase ',':\n\tcase '$':\n\tcase '@':\n\t\ttoken->type = c;\n\t\ttokenPutc (token, c);\n\t\tbreak;\n\tcase '.':\n\t\ttokenPutc (token, c);\n\t\tc = getcFromInputFile ();\n\t\tif (isdigit(c))\n\t\t{\n\t\t\ttoken->type = TOKEN_R_NUMBER;\n\t\t\ttokenPutc (token, c);\n\t\t\treadNumber(token, data);\n\t\t}\n\t\telse if (isalpha (c) || c == '_')\n\t\t{\n\t\t\ttoken->type = TOKEN_R_SYMBOL;\n\t\t\ttokenPutc (token, c);\n\t\t\treadSymbol (token, data);\n\n\t\t\ttoken->keyword = resolveKeyword (token->string);\n\t\t\tif (token->keyword != KEYWORD_NONE)\n\t\t\t\ttoken->type = TOKEN_R_KEYWORD;\n\t\t}\n\t\telse if (c == '.')\n\t\t{\n\t\t\ttoken->type = TOKEN_R_DOTS;\n\t\t\ttokenPutc (token, c);\n\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (c == '.')\n\t\t\t\ttokenPutc (token, c);\n\t\t\telse if (isdigit(c))\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_R_DOTS_N;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\ttokenPutc (token, c);\n\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t}\n\t\t\t\twhile (isdigit(c));\n\t\t\t\tungetcToInputFile (c);\n\t\t\t}\n\t\t\telse if (isalpha (c) || c == '_')\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_R_SYMBOL;\n\t\t\t\ttokenPutc (token, c);\n\t\t\t\treadSymbol (token, data);\n\n\t\t\t\ttoken->keyword = resolveKeyword (token->string);\n\t\t\t\tif (token->keyword != KEYWORD_NONE)\n\t\t\t\t\ttoken->type = TOKEN_R_KEYWORD;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_R_UNDEFINED;\n\t\t\t\tungetcToInputFile (c);\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\ttokenPutc (token, c);\n\t\tif (isdigit (c))\n\t\t{\n\t\t\ttoken->type = TOKEN_R_NUMBER;\n\t\t\treadNumber(token, data);\n\t\t}\n\t\telse if (isalpha (c))\n\t\t{\n\t\t\ttoken->type = TOKEN_R_SYMBOL;\n\t\t\treadSymbol (token, data);\n\n\t\t\ttoken->keyword = resolveKeyword (token->string);\n\t\t\tif (token->keyword != KEYWORD_NONE)\n\t\t\t\ttoken->type = TOKEN_R_KEYWORD;\n\t\t}\n\t\telse\n\t\t\ttoken->type = TOKEN_R_UNDEFINED;\n\t\tbreak;\n\t}\n\n\t/* Handle parameters in a signature */\n\tif (R(token)->signature && !tokenIsType(token, R_EOF) && !tokenIsTypeVal(token, '\\n'))\n\t{\n\t\tvString *signature = R (token)->signature;\n\n\t\tif (tokenIsTypeVal (token, '('))\n\t\t\tR (token)->parenDepth++;\n\t\telse if (tokenIsTypeVal (token, ')'))\n\t\t\tR (token)->parenDepth--;\n\n\t\tif (R (token)->kindIndexForParams != KIND_GHOST_INDEX\n\t\t\t&& R (token)->parenDepth == 1 && tokenIsType (token, R_SYMBOL)\n\t\t\t&& signatureExpectingParameter (signature))\n\t\t\tmakeSimpleRTag (token, R (token)->scopeIndex, false,\n\t\t\t\t\t\t\tR (token)->kindIndexForParams, NULL);\n\n\t\tif (vStringLast (signature) != '(' &&\n\t\t\t!tokenIsTypeVal (token, ',') &&\n\t\t\t!tokenIsTypeVal (token, ')'))\n\t\t\tvStringPut (signature, ' ');\n\t\tvStringCat (signature, token->string);\n\t}\n}\n\n#define newRToken rNewToken\nextern tokenInfo *rNewToken (void)\n{\n\treturn newToken (&rTokenInfoClass);\n}\n\n#define tokenReadNoNewline rTokenReadNoNewline\nextern void rTokenReadNoNewline (tokenInfo *const token)\n{\n\twhile (1)\n\t{\n\t\ttokenRead(token);\n\t\tif (!tokenIsTypeVal (token, '\\n'))\n\t\t\tbreak;\n\t}\n}\n\nstatic void setupCollectingSignature (tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t  vString   *signature,\n\t\t\t\t\t\t\t\t\t  int kindIndexForParams,\n\t\t\t\t\t\t\t\t\t  int corkIndex)\n{\n\tR (token)->signature = signature;\n\tR (token)->kindIndexForParams = kindIndexForParams;\n\tR (token)->scopeIndex = corkIndex;\n\tR (token)->parenDepth = 1;\n}\n\nextern void rSetupCollectingSignature (tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t   vString   *signature)\n{\n\tsetupCollectingSignature (token, signature,\n\t\t\t\t\t\t\t  KIND_GHOST_INDEX, CORK_NIL);\n}\n\nstatic void teardownCollectingSignature (tokenInfo *const token)\n{\n\tR (token)->parenDepth = 0;\n\tR (token)->scopeIndex = CORK_NIL;\n\tR (token)->kindIndexForParams = KIND_GHOST_INDEX;\n\tR (token)->signature = NULL;\n}\n\nextern void rTeardownCollectingSignature (tokenInfo *const token)\n{\n\tteardownCollectingSignature (token);\n}\n\nstatic int getKindForToken (tokenInfo *const token)\n{\n\tif (tokenIsKeyword (token, R_FUNCTION))\n\t\treturn K_FUNCTION;\n\telse if (tokenIsKeyword (token, R_C))\n\t\treturn K_VECTOR;\n\telse if (tokenIsKeyword (token, R_LIST))\n\t\treturn K_LIST;\n\telse if (tokenIsKeyword (token, R_DATAFRAME))\n\t\treturn K_DATAFRAME;\n\treturn K_GLOBALVAR;\n}\n\nstatic bool findNonPlaceholder (int corkIndex, tagEntryInfo *entry, void *data)\n{\n\tbool *any_non_placehoders = data;\n\tif (!entry->placeholder)\n\t{\n\t\t*any_non_placehoders = true;\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nstatic void parseRightSide (tokenInfo *const token, tokenInfo *const symbol, int parent)\n{\n\tR_TRACE_ENTER();\n\n\tchar *const assignment_operator = eStrdup (tokenString (token));\n\tvString *signature = NULL;\n\n\ttokenReadNoNewline (token);\n\n\tint kind = getKindForToken (token);\n\n\t/* Call sub parsers */\n\tint corkIndex = notifyReadRightSideSymbol (symbol,\n\t\t\t\t\t\t\t\t\t\t\t   assignment_operator,\n\t\t\t\t\t\t\t\t\t\t\t   parent,\n\t\t\t\t\t\t\t\t\t\t\t   token);\n\tif (corkIndex == CORK_NIL)\n\t{\n\t\t/* No subparser handle the symbol */\n\t\tcorkIndex = makeSimpleRTag (symbol, parent, kind == K_FUNCTION,\n\t\t\t\t\t\t\t\t\tkind,\n\t\t\t\t\t\t\t\t\tassignment_operator);\n\t}\n\n\tif (kind == K_FUNCTION)\n\t{\n\t\t/* parse signature */\n\t\ttokenReadNoNewline (token);\n\t\tif (tokenIsTypeVal (token, '('))\n\t\t{\n\t\t\tif (corkIndex == CORK_NIL)\n\t\t\t\ttokenSkipOverPair (token);\n\t\t\telse\n\t\t\t{\n\t\t\t\tsignature = vStringNewInit(\"(\");\n\t\t\t\tsetupCollectingSignature (token, signature, K_PARAM, corkIndex);\n\t\t\t\ttokenSkipOverPair (token);\n\t\t\t\tteardownCollectingSignature (token);\n\t\t\t}\n\t\t\ttokenReadNoNewline (token);\n\t\t}\n\t\tparent = (corkIndex == CORK_NIL\n\t\t\t\t  ? blackHoleIndex\n\t\t\t\t  : corkIndex);\n\t}\n\telse if (kind == K_VECTOR || kind == K_LIST || kind == K_DATAFRAME)\n\t{\n\t\ttokenRead (token);\n\t\tparsePair (token, corkIndex, NULL);\n\t\ttokenRead (token);\n\t\tparent = corkIndex;\n\t}\n\n\tR_TRACE_TOKEN_TEXT(\"body\", token, parent);\n\n\tparseStatement (token, parent, false, false);\n\n\ttagEntryInfo *tag = getEntryInCorkQueue (corkIndex);\n\tif (tag)\n\t{\n\t\tsetTagEndLine (tag, token->lineNumber);\n\t\tif (signature)\n\t\t{\n\t\t\ttag->extensionFields.signature = vStringDeleteUnwrap(signature);\n\t\t\tsignature = NULL;\n\t\t}\n\t\t/* If a vector has no named attribte and it has no lval,\n\t\t * we don't make a tag for the vector. */\n\t\tif ((kind == K_VECTOR || kind == K_LIST || kind == K_DATAFRAME)\n\t\t\t&& *assignment_operator == '\\0')\n\t\t{\n\t\t\tbool any_non_placehoders = false;\n\t\t\tforeachEntriesInScope (corkIndex, NULL,\n\t\t\t\t\t\t\t\t   findNonPlaceholder, &any_non_placehoders);\n\t\t\tif (!any_non_placehoders)\n\t\t\t\tmarkTagAsPlaceholder (tag, true); /* TODO: remove from intervaltab */\n\t\t}\n\t}\n\n\tvStringDelete (signature);\t/* NULL is acceptable. */\n\teFree (assignment_operator);\n\tR_TRACE_LEAVE();\n}\n\n/* Parse arguments for library and source. */\nstatic bool preParseExternalEntitiy (tokenInfo *const token, tokenInfo *const funcall)\n{\n\tTRACE_ENTER();\n\n\tbool r = true;\n\ttokenInfo *prefetch_token = newRToken ();\n\n\ttokenReadNoNewline (prefetch_token);\n\tif (tokenIsType (prefetch_token, R_SYMBOL)\n\t\t|| tokenIsType (prefetch_token, R_STRING))\n\t{\n\t\ttokenInfo *const loaded_obj_token = newTokenByCopying (prefetch_token);\n\t\ttokenReadNoNewline (prefetch_token);\n\t\tif (tokenIsTypeVal (prefetch_token, ')')\n\t\t\t|| tokenIsTypeVal (prefetch_token, ','))\n\t\t{\n\t\t\tif (tokenIsTypeVal (prefetch_token, ')'))\n\t\t\t\tr = false;\n\n\t\t\tmakeSimpleRefTag (loaded_obj_token->string,\n\t\t\t\t\t\t\t  (tokenIsKeyword (funcall, R_LIBRARY)\n\t\t\t\t\t\t\t   ? K_LIBRARY\n\t\t\t\t\t\t\t   : K_SOURCE),\n\t\t\t\t\t\t\t  (tokenIsKeyword (funcall, R_LIBRARY)\n\t\t\t\t\t\t\t   ? (strcmp (tokenString(funcall), \"library\") == 0\n\t\t\t\t\t\t\t\t  ? R_LIBRARY_ATTACHED_BY_LIBRARY\n\t\t\t\t\t\t\t\t  : R_LIBRARY_ATTACHED_BY_REQUIRE)\n\t\t\t\t\t\t\t   : R_SOURCE_LOADED_BY_SOURCE));\n\t\t\ttokenDelete (loaded_obj_token);\n\t\t}\n\t\telse if (tokenIsEOF (prefetch_token))\n\t\t{\n\t\t\ttokenCopy (token, prefetch_token);\n\t\t\ttokenDelete (loaded_obj_token);\n\t\t\tr = false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttokenUnread (prefetch_token);\n\t\t\ttokenUnread (loaded_obj_token);\n\t\t\ttokenDelete (loaded_obj_token);\n\t\t}\n\t}\n\telse if (tokenIsEOF (prefetch_token))\n\t{\n\t\ttokenCopy (token, prefetch_token);\n\t\tr = false;\n\t}\n\telse\n\t\ttokenUnread (prefetch_token);\n\n\ttokenDelete (prefetch_token);\n\n\tTRACE_LEAVE_TEXT(r\n\t\t\t\t\t ? \"unread tokens and request parsing again to the upper context\"\n\t\t\t\t\t : \"parse all arguments\");\n\treturn r;\n}\n\nstatic bool preParseLoopCounter(tokenInfo *const token, int parent)\n{\n\tbool r = true;\n\tTRACE_ENTER();\n\n\ttokenReadNoNewline (token);\n\tif (tokenIsType (token, R_SYMBOL))\n\t\tmakeSimpleRTag (token, parent, false, K_GLOBALVAR, NULL);\n\n\tif (tokenIsEOF (token)\n\t\t|| tokenIsTypeVal (token, ')'))\n\t\tr = false;\n\n\tTRACE_LEAVE_TEXT(r\n\t\t\t\t\t ? \"unread tokens and request parsing again to the upper context\"\n\t\t\t\t\t : \"parse all arguments\");\n\treturn r;\n}\n\n\n/* If funcall is non-NULL, this pair represents the argument list for the function\n * call for FUNCALL. */\nstatic void parsePair (tokenInfo *const token, int parent, tokenInfo *const funcall)\n{\n\tR_TRACE_ENTER();\n\n\tbool in_continuous_pair = tokenIsTypeVal (token, '(')\n\t\t|| tokenIsTypeVal (token, '[');\n\tbool is_funcall = funcall && tokenIsTypeVal (token, '(');\n\tbool done = false;\n\n\tif (is_funcall)\n\t{\n\t\tif \t(tokenIsKeyword (funcall, R_LIBRARY) ||\n\t\t\t tokenIsKeyword (funcall, R_SOURCE))\n\t\t\tdone = !preParseExternalEntitiy (token, funcall);\n\t\telse if (tokenIsKeyword (funcall, R_FOR))\n\t\t\tdone = !preParseLoopCounter (token, parent);\n\t\telse if (notifyReadFuncall (funcall, token, parent) != CORK_NIL)\n\t\t\tdone = true;\n\t}\n\n\tif (done)\n\t{\n\t\tR_TRACE_LEAVE();\n\t\treturn;\n\t}\n\n\tdo\n\t{\n\t\ttokenRead (token);\n\t\tR_TRACE_TOKEN_TEXT(\"inside pair\", token, parent);\n\t\tparseStatement (token, parent, (funcall != NULL), in_continuous_pair);\n\t}\n\twhile (! (tokenIsEOF (token)\n\t\t\t  || tokenIsTypeVal (token, ')')\n\t\t\t  || tokenIsTypeVal (token, '}')\n\t\t\t  || tokenIsTypeVal (token, ']')));\n\tR_TRACE_LEAVE();\n}\n\nstatic bool isAtConstructorInvocation (void)\n{\n\tbool r = false;\n\n\ttokenInfo *const token = newRToken ();\n\ttokenRead (token);\n\tif (tokenIsTypeVal (token, '('))\n\t\tr = true;\n\ttokenUnread (token);\n\ttokenDelete (token);\n\treturn r;\n}\n\nstatic bool parseStatement (tokenInfo *const token, int parent,\n\t\t\t\t\t\t\tbool in_arglist, bool in_continuous_pair)\n{\n\tR_TRACE_ENTER();\n\tint last_count = rTokenInfoClass.read_counter;\n\n\tdo\n\t{\n\t\tif (tokenIsEOF (token))\n\t\t\tbreak;\n\t\telse if (tokenIsTypeVal (token, ';'))\n\t\t{\n\t\t\tR_TRACE_TOKEN_TEXT (\"break with ;\", token, parent);\n\t\t\tbreak;\n\t\t}\n\t\telse if (tokenIsTypeVal (token, '\\n'))\n\t\t{\n\t\t\tR_TRACE_TOKEN_TEXT (\"break with \\\\n\", token, parent);\n\t\t\tbreak;\n\t\t}\n\t\telse if ((tokenIsKeyword (token, R_FUNCTION)\n\t\t\t\t  || ((tokenIsKeyword (token, R_C)\n\t\t\t\t\t   || tokenIsKeyword (token, R_LIST)\n\t\t\t\t\t   || tokenIsKeyword (token, R_DATAFRAME))\n\t\t\t\t\t  && isAtConstructorInvocation ())))\n\t\t{\n\t\t\t/* This statement doesn't start with a symbol.\n\t\t\t * This function is not assigned to any symbol. */\n\t\t\ttokenInfo *const anonfunc = newTokenByCopying (token);\n\t\t\tint kind = getKindForToken (token);\n\t\t\tanonGenerate (anonfunc->string,\n\t\t\t\t\t\t  kindExtraInfo [kind].anon_prefix, kind);\n\t\t\ttokenUnread (token);\n\t\t\tvStringClear (token->string);\n\t\t\tparseRightSide (token, anonfunc, parent);\n\t\t\ttokenDelete (anonfunc);\n\t\t}\n\t\telse if (tokenIsType (token, R_SYMBOL)\n\t\t\t\t || tokenIsType (token, R_STRING)\n\t\t\t\t || tokenIsType (token, R_KEYWORD))\n\t\t{\n\t\t\ttokenInfo *const symbol = newTokenByCopying (token);\n\n\t\t\tif (in_continuous_pair)\n\t\t\t\ttokenReadNoNewline (token);\n\t\t\telse\n\t\t\t\ttokenRead (token);\n\n\t\t\tif (tokenIsType (token, R_LASSIGN))\n\t\t\t{\n\t\t\t\t/* Assignment */\n\t\t\t\tparseRightSide (token, symbol, parent);\n\t\t\t\tR_TRACE_TOKEN_TEXT (\"break with right side\", token, parent);\n\t\t\t\ttokenDelete(symbol);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (tokenIsTypeVal (token, '='))\n\t\t\t{\n\t\t\t\t/* Assignment */\n\t\t\t\tif (in_arglist)\n\t\t\t\t{\n\t\t\t\t\t/* Ignore the left side symbol. */\n\t\t\t\t\ttokenRead (token);\n\t\t\t\t\tR_TRACE_TOKEN_TEXT(\"(in arg list) after = body\", token, parent);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tparseRightSide (token, symbol, parent);\n\t\t\t\t\tR_TRACE_TOKEN_TEXT (\"break with right side\", token, parent);\n\t\t\t\t\ttokenDelete(symbol);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (tokenIsTypeVal (token, '('))\n\t\t\t{\n\t\t\t\t/* function call */\n\t\t\t\tparsePair (token, parent, symbol);\n\t\t\t\ttokenRead (token);\n\t\t\t\tR_TRACE_TOKEN_TEXT(\"after arglist\", token, parent);\n\t\t\t}\n\t\t\telse if (tokenIsTypeVal (token, '$')\n\t\t\t\t\t || tokenIsTypeVal (token, '@')\n\t\t\t\t\t || tokenIsType (token, R_SCOPE))\n\t\t\t{\n\t\t\t\ttokenReadNoNewline (token); /* Skip the next identifier */\n\t\t\t\ttokenRead (token);\n\t\t\t\tR_TRACE_TOKEN_TEXT(\"after $\", token, parent);\n\t\t\t}\n\t\t\telse\n\t\t\t\tR_TRACE_TOKEN_TEXT(\"else after symbol\", token, parent);\n\t\t\ttokenDelete(symbol);\n\t\t}\n\t\telse if (tokenIsType (token, R_RASSIGN))\n\t\t{\n\t\t\tchar *const assignment_operator = eStrdup (tokenString (token));\n\t\t\ttokenReadNoNewline (token);\n\t\t\tif (tokenIsType (token, R_SYMBOL)\n\t\t\t\t|| tokenIsType (token, R_STRING))\n\t\t\t{\n\t\t\t\tmakeSimpleRTag (token, parent, false,\n\t\t\t\t\t\t\t\tK_GLOBALVAR, assignment_operator);\n\t\t\t\ttokenRead (token);\n\t\t\t}\n\t\t\teFree (assignment_operator);\n\t\t\tR_TRACE_TOKEN_TEXT(\"after ->\", token, parent);\n\t\t}\n\t\telse if (tokenIsType (token, R_OPERATOR))\n\t\t{\n\t\t\ttokenReadNoNewline (token);\n\t\t\tR_TRACE_TOKEN_TEXT(\"after operator\", token, parent);\n\t\t}\n\t\telse if (tokenIsTypeVal (token, '(')\n\t\t\t\t || tokenIsTypeVal (token, '{')\n\t\t\t\t || tokenIsTypeVal (token, '['))\n\t\t{\n\t\t\tparsePair (token, parent, NULL);\n\t\t\ttokenRead (token);\n\t\t\tR_TRACE_TOKEN_TEXT(\"after pair\", token, parent);\n\t\t}\n\t\telse if (tokenIsTypeVal (token, ')')\n\t\t\t\t || tokenIsTypeVal (token, '}')\n\t\t\t\t || tokenIsTypeVal (token, ']'))\n\t\t{\n\t\t\tR_TRACE_TOKEN_TEXT (\"break with close\", token, parent);\n\t\t\tbreak;\n\t\t}\n\t\telse if (tokenIsTypeVal (token, '$')\n\t\t\t\t || tokenIsTypeVal (token, '@')\n\t\t\t\t || tokenIsType (token, R_SCOPE))\n\t\t{\n\t\t\ttokenReadNoNewline (token); /* Skip the next identifier */\n\t\t\ttokenRead (token);\n\t\t\tR_TRACE_TOKEN_TEXT(\"after $\", token, parent);\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttokenRead (token);\n\t\t\tR_TRACE_TOKEN_TEXT(\"else\", token, parent);\n\t\t}\n\t}\n\twhile (!tokenIsEOF (token));\n\n\tR_TRACE_LEAVE();\n\n\treturn (last_count != rTokenInfoClass.read_counter);\n}\n\nextern bool rParseStatement (tokenInfo *const token, int parentIndex, bool in_arglist)\n{\n\tpushLanguage (Lang_R);\n\tbool r = parseStatement (token, parentIndex, in_arglist, true);\n\tpopLanguage ();\n\treturn r;\n}\n\nstatic int notifyReadRightSideSymbol (tokenInfo *const symbol,\n\t\t\t\t\t\t\t\t\t  const char *const assignmentOperator,\n\t\t\t\t\t\t\t\t\t  int parent,\n\t\t\t\t\t\t\t\t\t  tokenInfo *const token)\n{\n\tsubparser *sub;\n\tint q = CORK_NIL;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\trSubparser *rsub = (rSubparser *)sub;\n\t\tif (rsub->readRightSideSymbol)\n\t\t{\n\t\t\tenterSubparser (sub);\n\t\t\tq = rsub->readRightSideSymbol (rsub, symbol, assignmentOperator, parent, token);\n\t\t\tleaveSubparser ();\n\t\t\tif (q != CORK_NIL)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn q;\n}\n\nstatic int makeSimpleSubparserTag (int langType,\n\t\t\t\t\t\t\t\t   tokenInfo *const token, int parent,\n\t\t\t\t\t\t\t\t   bool in_func, int kindInR,\n\t\t\t\t\t\t\t\t   const char *assignmentOperator)\n{\n\tint q = CORK_NIL;\n\tsubparser *sub = getLanguageSubparser (langType, false);\n\tif (sub)\n\t{\n\t\trSubparser *rsub = (rSubparser *)sub;\n\t\tif (rsub->makeTagWithTranslation)\n\t\t{\n\t\t\tenterSubparser (sub);\n\t\t\tq = rsub->makeTagWithTranslation (rsub,\n\t\t\t\t\t\t\t\t\t\t\t  token, parent,\n\t\t\t\t\t\t\t\t\t\t\t  in_func, kindInR,\n\t\t\t\t\t\t\t\t\t\t\t  assignmentOperator);\n\t\t\tleaveSubparser ();\n\t\t}\n\t}\n\treturn q;\n}\n\nstatic bool askSubparserTagAcceptancy (tagEntryInfo *pe)\n{\n\tbool q = false;\n\tsubparser *sub = getLanguageSubparser (pe->langType, false);\n\t{\n\t\trSubparser *rsub = (rSubparser *)sub;\n\t\tif (rsub->askTagAcceptancy)\n\t\t{\n\t\t\tenterSubparser (sub);\n\t\t\tq = rsub->askTagAcceptancy (rsub, pe);\n\t\t\tleaveSubparser ();\n\t\t}\n\t}\n\treturn q;\n}\n\nstatic bool askSubparserTagHasFunctionAlikeKind (tagEntryInfo *e)\n{\n\tbool q = false;\n\tpushLanguage (Lang_R);\n\tsubparser *sub = getLanguageSubparser (e->langType, false);\n\tAssert (sub);\n\tpopLanguage ();\n\trSubparser *rsub = (rSubparser *)sub;\n\tif (rsub->hasFunctionAlikeKind)\n\t{\n\t\tenterSubparser (sub);\n\t\tq = rsub->hasFunctionAlikeKind (rsub, e);\n\t\tleaveSubparser ();\n\t}\n\treturn q;\n}\n\nstatic int notifyReadFuncall (tokenInfo *const func,\n\t\t\t\t\t\t\t  tokenInfo *const token,\n\t\t\t\t\t\t\t  int parent)\n{\n\tint q = CORK_NIL;\n\tsubparser *sub;\n\tforeachSubparser (sub, false)\n\t{\n\t\trSubparser *rsub = (rSubparser *)sub;\n\t\tif (rsub->readFuncall)\n\t\t{\n\t\t\tenterSubparser (sub);\n\t\t\tq = rsub->readFuncall (rsub, func, token, parent);\n\t\t\tleaveSubparser ();\n\t\t\tif (q != CORK_NIL)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treturn q;\n}\n\nstatic void findRTags (void)\n{\n\ttokenInfo *const token = newRToken ();\n\n\tblackHoleIndex = makePlaceholder (\"**BLACK-HOLE/DON'T TAG ME**\");\n\tregisterEntry (blackHoleIndex);\n\n\tTRACE_PRINT (\"install blackhole: %d\", blackHoleIndex);\n\n\tdo\n\t{\n\t\ttokenRead(token);\n\t\tR_TRACE_TOKEN(token, CORK_NIL);\n\t\tparseStatement (token, CORK_NIL, false, false);\n\t}\n\twhile (!tokenIsEOF (token));\n\n\tTRACE_PRINT (\"run blackhole\", blackHoleIndex);\n\tmarkAllEntriesInScopeAsPlaceholder (blackHoleIndex);\n\n\ttokenDelete (token);\n}\n\nstatic void initializeRParser (const langType language)\n{\n\tLang_R = language;\n}\n\nextern parserDefinition *RParser (void)\n{\n\tstatic const char *const extensions[] = { \"r\", \"R\", \"s\", \"q\", NULL };\n\tparserDefinition *const def = parserNew (\"R\");\n\tstatic selectLanguage selectors[] = { selectByArrowOfR,\n\t\t\t\t\t\t\t\t\t\t  NULL };\n\n\tdef->extensions = extensions;\n\tdef->kindTable = RKinds;\n\tdef->kindCount = ARRAY_SIZE(RKinds);\n\tdef->fieldTable = RFields;\n\tdef->fieldCount = ARRAY_SIZE (RFields);\n\tdef->keywordTable = RKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE(RKeywordTable);\n\tdef->useCork = CORK_QUEUE | CORK_SYMTAB;\n\tdef->parser = findRTags;\n\tdef->selectLanguage = selectors;\n\tdef->initialize = initializeRParser;\n\n\treturn def;\n}\n\nextern vString *rExtractNameFromString (vString* str)\n{\n\tint offset = 0;\n\n\tif (vStringLength (str) == 0)\n\t\treturn NULL;\n\n\tchar b = vStringChar (str, 0);\n\tif (b == '\\'' || b == '\"' || b == '`')\n\t\toffset = 1;\n\n\tif (offset && vStringLength (str) < 3)\n\t\treturn NULL;\n\n\tvString *n = vStringNewInit (vStringValue (str) + offset);\n\tif (vStringChar (n, vStringLength (n) - 1) == b)\n\t\tvStringChop (n);\n\n\treturn n;\n}\n\n#ifdef DEBUG\nstatic const char *tokenTypeStr(enum RTokenType e)\n{ /* Generated by misc/enumstr.sh with cmdline:\n     parsers/r.c RTokenType tokenTypeStr TOKEN_R_ --use-lower-bits-as-is */\n\tswitch (e)\n\t{\n\t\tcase            TOKEN_R_EOF: return \"EOF\";\n\t\tcase      TOKEN_R_UNDEFINED: return \"UNDEFINED\";\n\t\tcase        TOKEN_R_KEYWORD: return \"KEYWORD\";\n\t\tcase        TOKEN_R_NEWLINE: return \"NEWLINE\";\n\t\tcase         TOKEN_R_NUMBER: return \"NUMBER\";\n\t\tcase         TOKEN_R_SYMBOL: return \"SYMBOL\";\n\t\tcase         TOKEN_R_STRING: return \"STRING\";\n\t\tcase       TOKEN_R_OPERATOR: return \"OPERATOR\";\n\t\tcase           TOKEN_R_DOTS: return \"DOTS\";\n\t\tcase         TOKEN_R_DOTS_N: return \"DOTS_N\";\n\t\tcase        TOKEN_R_LASSIGN: return \"LASSIGN\";\n\t\tcase        TOKEN_R_RASSIGN: return \"RASSIGN\";\n\t\tcase          TOKEN_R_SCOPE: return \"SCOPE\";\n\t\tdefault:                   break;\n\t}\n\tstatic char buf[3];\n\tif (isprint (e))\n\t{\n\t\tbuf[0] = e;\n\t\tbuf[1] = '\\0';\n\t}\n\telse if (e == '\\n')\n\t{\n\t\tbuf[0] = '\\\\';\n\t\tbuf[1] = 'n';\n\t\tbuf[2] = '\\0';\n\t}\n\telse\n\t{\n\t\tbuf[0] = '\\0';\n\t}\n\treturn buf;\n}\n#endif\n"
  },
  {
    "path": "parsers/rake.c",
    "content": "/*\n*   Copyright (c) 2022 Masatake YAMATO <yamato@redhat.com>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Rakefile.\n*\n*   Reference:\n*   - https://ruby.github.io/rake/doc/rakefile_rdoc.html\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"numarray.h\"\n#include \"parse.h\"\n#include \"subparser.h\"\n\n#include \"x-ruby.h\"\n\n#include <string.h>\n\n/*\n* DATA STRUCTURES\n*/\nstruct sRakeSubparser {\n\trubySubparser ruby;\n\tintArray *namespaces;\n};\n\ntypedef enum {\n\tK_TASK,\n\tK_NAMESPACE,\n\tK_FILE,\n\tK_DIRECTORY,\n\tK_MULTITASK,\n\tK_XTASK,\n} rakeKind;\n\n/*\n* DATA DEFINITIONS\n*/\nstatic scopeSeparator RakeGenericSeparators [] = {\n\t{ KIND_WILDCARD_INDEX, \":\" },\n};\n\nstatic kindDefinition RakeKinds [] = {\n\t{ true, 't', \"task\", \"tasks\",\n\t  ATTACH_SEPARATORS(RakeGenericSeparators)},\n\t{ true, 'n', \"namespace\", \"namespaces\",\n\t  ATTACH_SEPARATORS(RakeGenericSeparators)},\n\t/* F/file is reserved in the main part. */\n\t{ true, 'f', \"File\", \"file tasks\",\n\t  ATTACH_SEPARATORS(RakeGenericSeparators)},\n\t{ true, 'd', \"directory\", \"directory tasks\",\n\t  ATTACH_SEPARATORS(RakeGenericSeparators)},\n\t{ true, 'm', \"multitask\", \"multi tasks\",\n\t  ATTACH_SEPARATORS(RakeGenericSeparators)},\n\t{ true, 'x', \"xtask\", \"tasks defined with special constructor\",\n\t  ATTACH_SEPARATORS(RakeGenericSeparators)},\n};\n\n/*\n* FUNCTIONS\n*/\nstatic void findRakeTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nstatic vString *readTask (const unsigned char **cp, bool *variable)\n{\n\tvString *vstr = NULL;\n\tunsigned char b;\n\tconst unsigned char *start;\n\n\tif (**cp == '(')\n\t{\n\t\t++*cp;\n\t\trubySkipWhitespace (cp);\n\t}\n\n\tswitch (**cp)\n\t{\n\tcase '\\'':\n\tcase '\"':\n\t\tb = **cp;\n\t\t++*cp;\n\t\tvstr = vStringNew ();\n\t\tif (!rubyParseString (cp, b, vstr))\n\t\t{\n\t\t\tvStringDelete (vstr);\n\t\t\tvstr = NULL;\n\t\t}\n\t\tbreak;\n\tcase ':':\n\t\tvstr = vStringNew ();\n\t\tif (!rubyParseMethodName (cp, vstr))\n\t\t{\n\t\t\tvStringDelete (vstr);\n\t\t\tvstr = NULL;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tvstr = vStringNew ();\n\t\tstart = *cp;\n\t\tif (!rubyParseMethodName (cp, vstr))\n\t\t{\n\t\t\tvStringDelete (vstr);\n\t\t\tvstr = NULL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tconst char *end = strstr((const char *)start, vStringValue (vstr));\n\t\t\tif (end)\n\t\t\t{\n\t\t\t\tend += vStringLength (vstr);\n\t\t\t\tif (*end != ':')\n\t\t\t\t\t*variable = true;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\treturn vstr;\n}\n\nstatic int makeSimpleRakeTag (vString *vstr, int kindIndex, rubySubparser *subparser,\n\t\t\t\t\t\t\t  bool anonymous)\n{\n\tif (anonymous)\n\t{\n\t\tvStringPut (vstr, '_');\n\t\tanonConcat (vstr, kindIndex);\n\t}\n\n\tint r = makeSimpleTag (vstr, kindIndex);\n\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\tif (e)\n\t{\n\t\tstruct sRakeSubparser *rake = (struct sRakeSubparser *)subparser;\n\t\tif (!intArrayIsEmpty (rake->namespaces))\n\t\t\te->extensionFields.scopeIndex = intArrayLast(rake->namespaces);\n\t\tif (anonymous)\n\t\t\tmarkTagExtraBit (e, XTAG_ANONYMOUS);\n\t}\n\treturn r;\n}\n\nstruct taskType {\n\tconst char *keyword;\n\trakeKind    kind;\n};\n\nstatic int parseTask (rubySubparser *s, int kind, const unsigned char **cp)\n{\n\tvString *vstr = NULL;\n\tbool variable = false;\n\trubySkipWhitespace (cp);\n\tvstr = readTask (cp, &variable);\n\tif (vstr)\n\t{\n\t\tint r = makeSimpleRakeTag (vstr, kind, s, variable);\n\t\tvStringDelete (vstr);\n\t\treturn r;\n\t}\n\treturn CORK_NIL;\n}\n\nstatic int parseXTask (rubySubparser *s, struct taskType *xtask, const unsigned char **cp)\n{\n\trubySkipWhitespace (cp);\n\tif (**cp == '(' || **cp == '\"' || **cp == '\\'')\n\t{\n\t\tvString *vstr = NULL;\n\t\tbool variable = false;\n\t\tvstr = readTask (cp, &variable);\n\t\tif (vstr)\n\t\t{\n\t\t\tint r = makeSimpleRakeTag (vstr, xtask->kind, s, variable);\n\t\t\tvStringDelete (vstr);\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\t\t\tif (e)\n\t\t\t{\n\t\t\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\t\t\te->extensionFields.typeRef [1] = eStrdup (xtask->keyword);\n\t\t\t}\n\t\t\treturn r;\n\t\t}\n\t}\n\treturn CORK_NIL;\n}\n\nstatic int lineNotify (rubySubparser *s, const unsigned char **cp, int corkIndex CTAGS_ATTR_UNUSED)\n{\n\tstruct taskType taskTypes [] = {\n\t\t{ \"task\",       K_TASK      },\n\t\t{ \"namespace\",  K_NAMESPACE },\n\t\t{ \"file\",       K_FILE      },\n\t\t{ \"directory\",  K_DIRECTORY },\n\t\t{ \"multitask\",  K_MULTITASK },\n\t};\n\n\tfor (int i = 0; i < ARRAY_SIZE(taskTypes); i++)\n\t{\n\t\tif (rubyCanMatchKeywordWithAssign (cp, taskTypes[i].keyword))\n\t\t\treturn parseTask (s, taskTypes[i].kind, cp);\n\t}\n\n\tstruct taskType xtaskTypes [] = {\n\t\t{ \"RSpec::Core::RakeTask.new\", K_XTASK },\n\t\t{ \"Cucumber::Rake::Task.new\",  K_XTASK },\n\t\t{ \"Rake::TestTask.new\",        K_XTASK },\n\t\t{ \"Rake::PackageTask.new\",     K_XTASK },\n\t\t/* ... */\n\t};\n\n\tfor (int i = 0; i < ARRAY_SIZE(xtaskTypes); i++)\n\t{\n\t\tif (rubyCanMatchKeywordWithAssign (cp, xtaskTypes[i].keyword))\n\t\t\treturn parseXTask (s, xtaskTypes + i, cp);\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic void inputStart (subparser *s)\n{\n\tstruct sRakeSubparser *rake = (struct sRakeSubparser *)s;\n\n\tintArrayClear (rake->namespaces);\n}\n\nstatic void enterBlockNotify (rubySubparser *s, int corkIndex)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\n\tif (e && e->kindIndex == K_NAMESPACE)\n\t{\n\t\tstruct sRakeSubparser *rake = (struct sRakeSubparser *)s;\n\t\tintArrayAdd (rake->namespaces, corkIndex);\n\t}\n}\n\nstatic void leaveBlockNotify (rubySubparser *s, int corkIndex)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\n\tif (e && e->kindIndex == K_NAMESPACE)\n\t{\n\t\tstruct sRakeSubparser *rake = (struct sRakeSubparser *)s;\n\t\tintArrayRemoveLast (rake->namespaces);\n\t}\n}\n\nstatic struct sRakeSubparser rakeSubparser = {\n\t.ruby = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t\t.inputStart = inputStart,\n\t\t},\n\t\t.lineNotify = lineNotify,\n\t\t.enterBlockNotify = enterBlockNotify,\n\t\t.leaveBlockNotify = leaveBlockNotify,\n\t},\n\t.namespaces = NULL,\n};\n\nstatic void initialize (const langType language CTAGS_ATTR_UNUSED)\n{\n\trakeSubparser.namespaces = intArrayNew ();\n}\n\nstatic void finalize (langType language CTAGS_ATTR_UNUSED, bool initialized)\n{\n\tif (rakeSubparser.namespaces)\n\t\tintArrayDelete (rakeSubparser.namespaces);\n}\n\nextern parserDefinition* RakeParser (void)\n{\n\tstatic const char *const extensions [] = { \"rake\", NULL };\n\tstatic const char *const patterns [] = { \"Rakefile\", NULL };\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Ruby\", &rakeSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"Rake\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE(dependencies);\n\tdef->kindTable  = RakeKinds;\n\tdef->kindCount  = ARRAY_SIZE (RakeKinds);\n\tdef->extensions = extensions;\n\tdef->patterns   = patterns;\n\tdef->parser     = findRakeTags;\n\tdef->initialize = initialize;\n\tdef->finalize   = finalize;\n\tdef->useCork    = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/raku.c",
    "content": "/*\n * raku.c -- Raku parser.\n * Author: Dmitri Tikhonov <dmitri@cpan.org>\n * Author: Will Coleda <will@coleda.com>\n *\n * This is a very basic Perl 6 parser.  It does not know how to:\n *   - skip POD;\n *   - skip multiline comments;\n *   - skip quoted strings;\n *   - generate fully-qualified tags.\n *\n * This source code is released for free distribution under the terms of\n * the GNU General Public License version 2 or (at your option) any later version.\n */\n\n#include \"general.h\"    /* must always come first */\n\n#include <stdio.h>\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\nenum rakuKind {\n    K_NONE = -1,\n    K_CLASS,\n    K_GRAMMAR,\n    K_METHOD,\n    K_MODULE,\n    K_PACKAGE,\n    K_ROLE,\n    K_RULE,\n    K_SUBMETHOD,\n    K_SUBROUTINE,\n    K_TOKEN,\n};\n\nstatic kindDefinition rakuKinds[] = {\n    [K_CLASS]       = { true,  'c', \"class\",      \"classes\" },\n    [K_GRAMMAR]     = { true,  'g', \"grammar\",    \"grammars\" },\n    [K_METHOD]      = { true,  'm', \"method\",     \"methods\" },\n    [K_MODULE]      = { true,  'o', \"module\",     \"modules\" },\n    [K_PACKAGE]     = { true,  'p', \"package\",    \"packages\" },\n    [K_ROLE]        = { true,  'r', \"role\",       \"roles\" },\n    [K_RULE]        = { true,  'u', \"rule\",       \"rules\" },\n    [K_SUBMETHOD]   = { true,  'b', \"submethod\",  \"submethods\" },\n    [K_SUBROUTINE]  = { true,  's', \"subroutine\", \"subroutines\" },\n    [K_TOKEN]       = { true,  't', \"token\",      \"tokens\" },\n};\n\nenum token {\n    T_CLASS,\n    T_GRAMMAR,\n    T_METHOD,\n    T_MODULE,\n    T_MULTI,\n    T_MY,\n    T_OUR,\n    T_PACKAGE,\n    T_PROTO,\n    T_ROLE,\n    T_RULE,\n    T_SUB,\n    T_SUBMETHOD,\n    T_UNIT,\n    T_TOKEN,\n};\n\nstatic const enum rakuKind token2kind[] = {\n    [T_CLASS]       = K_CLASS,\n    [T_GRAMMAR]     = K_GRAMMAR,\n    [T_METHOD]      = K_METHOD,\n    [T_MODULE]      = K_MODULE,\n    [T_MULTI]       = K_SUBROUTINE,\n    [T_MY]          = K_NONE,\n    [T_OUR]         = K_NONE,\n    [T_PACKAGE]     = K_PACKAGE,\n    [T_PROTO]       = K_NONE,\n    [T_ROLE]        = K_ROLE,\n    [T_RULE]        = K_RULE,\n    [T_SUB]         = K_SUBROUTINE,\n    [T_SUBMETHOD]   = K_SUBMETHOD,\n    [T_UNIT]        = K_NONE,\n    [T_TOKEN]       = K_TOKEN,\n};\n\n#define STRLEN(s) (sizeof(s) - 1)\n#define STREQN(s, token) (0 == strncmp(s, token, STRLEN(token)))\n\nstatic enum token\nmatchToken (const char *s, int len)\n{\n    switch (len) {\n        case 2:\n            if (STREQN(s, \"my\"))                return T_MY;\n            break;\n        case 3:\n            switch (s[0]) {\n                case 'o':\n                    if (STREQN(s, \"our\"))       return T_OUR;\n                    break;\n                case 's':\n                    if (STREQN(s, \"sub\"))       return T_SUB;\n                    break;\n            }\n            break;\n        case 4:\n            switch (s[1]) {\n                case 'o':\n                    if (STREQN(s, \"role\"))      return T_ROLE;\n                    break;\n                case 'u':\n                    if (STREQN(s, \"rule\"))      return T_RULE;\n                    break;\n                case 'n':\n                    if (STREQN(s, \"unit\"))      return T_UNIT;\n                    break;\n            }\n            break;\n        case 5:\n            switch (s[0]) {\n                case 'c':\n                    if (STREQN(s, \"class\"))     return T_CLASS;\n                    break;\n                case 'm':\n                    if (STREQN(s, \"multi\"))     return T_MULTI;\n                    break;\n                case 'p':\n                    if (STREQN(s, \"proto\"))     return T_PROTO;\n                    break;\n                case 't':\n                    if (STREQN(s, \"token\"))     return T_TOKEN;\n                    break;\n            }\n            break;\n        case 6:\n            switch (s[1]) {\n                case 'e':\n                    if (STREQN(s, \"method\"))    return T_METHOD;\n                    break;\n                case 'o':\n                    if (STREQN(s, \"module\"))    return T_MODULE;\n                    break;\n            }\n            break;\n        case 7:\n            switch (s[0]) {\n                case 'g':\n                    if (STREQN(s, \"grammar\"))   return T_GRAMMAR;\n                    break;\n                case 'p':\n                    if (STREQN(s, \"package\"))   return T_PACKAGE;\n                    break;\n            }\n            break;\n        case 9:\n            if (STREQN(s, \"submethod\"))         return T_SUBMETHOD;\n            break;\n    }\n    return -1;\n}\n\nstatic const int validRakuIdentifier[0x100] = {\n/* r!perl -e \"print qq([(int)'\\$_'] = 1,\\n)for a..z,A..Z,0..9,':','-','_'\"|fmt\n */\n    [(int)'a'] = 1, [(int)'b'] = 1, [(int)'c'] = 1, [(int)'d'] = 1,\n    [(int)'e'] = 1, [(int)'f'] = 1, [(int)'g'] = 1, [(int)'h'] = 1,\n    [(int)'i'] = 1, [(int)'j'] = 1, [(int)'k'] = 1, [(int)'l'] = 1,\n    [(int)'m'] = 1, [(int)'n'] = 1, [(int)'o'] = 1, [(int)'p'] = 1,\n    [(int)'q'] = 1, [(int)'r'] = 1, [(int)'s'] = 1, [(int)'t'] = 1,\n    [(int)'u'] = 1, [(int)'v'] = 1, [(int)'w'] = 1, [(int)'x'] = 1,\n    [(int)'y'] = 1, [(int)'z'] = 1, [(int)'A'] = 1, [(int)'B'] = 1,\n    [(int)'C'] = 1, [(int)'D'] = 1, [(int)'E'] = 1, [(int)'F'] = 1,\n    [(int)'G'] = 1, [(int)'H'] = 1, [(int)'I'] = 1, [(int)'J'] = 1,\n    [(int)'K'] = 1, [(int)'L'] = 1, [(int)'M'] = 1, [(int)'N'] = 1,\n    [(int)'O'] = 1, [(int)'P'] = 1, [(int)'Q'] = 1, [(int)'R'] = 1,\n    [(int)'S'] = 1, [(int)'T'] = 1, [(int)'U'] = 1, [(int)'V'] = 1,\n    [(int)'W'] = 1, [(int)'X'] = 1, [(int)'Y'] = 1, [(int)'Z'] = 1,\n    [(int)'0'] = 1, [(int)'1'] = 1, [(int)'2'] = 1, [(int)'3'] = 1,\n    [(int)'4'] = 1, [(int)'5'] = 1, [(int)'6'] = 1, [(int)'7'] = 1,\n    [(int)'8'] = 1, [(int)'9'] = 1, [(int)':'] = 1, [(int)'-'] = 1,\n    [(int)'_'] = 1,\n};\n\nstatic const int validMethodPrefix[0x100] = {\n    [(int)'!'] = 1, [(int)'^'] = 1,\n};\n\nstatic const int kindMayHaveMethodPrefix = (1 << K_SUBMETHOD) |\n                                           (1 << K_METHOD)    ;\n\n/* Trim identifier pointed to by ps, possibly advancing it, and return\n * the length of the valid portion.  If the returned value is zero, the\n * identifier is invalid.\n */\nstatic int\ntrimIdentifier (enum rakuKind kind, const char **ps, int len)\n{\n    Assert(len > 0);\n    const char *const end = *ps + len;\n    const char *s = *ps;\n    /* Trim the front if possible: */\n    s += (kindMayHaveMethodPrefix & (1 << kind)) &&\n         validMethodPrefix[(int)*s];\n    /* Record the start of identifier: */\n    *ps = s;\n    /* Continuous string of valid characters: */\n    while (s < end && validRakuIdentifier[(int)*s])\n        ++s;\n    /* sub multi infix:<...>        -- we want the \"infix\" only */\n    while (s - *ps > 0 && ':' == s[-1])\n        --s;\n    /* It's ok if this is zero: */\n    return s - *ps;\n}\n\nstruct rakuCtx {\n    enum token  tokens[128 /* unlikely to need more than this */];\n    unsigned int n_tokens;\n    vString    *name;\n    const char *line;      /* Saved from readLineFromInputFile() */\n};\n\nstatic void\nmakeTag (struct rakuCtx *ctx, int kind, const char *name, int len)\n{\n    tagEntryInfo entry;\n    vStringNCopyS(ctx->name, name, len);\n    initTagEntry(&entry, vStringValue(ctx->name), kind);\n    makeTagEntry(&entry);\n}\n\nstatic void\npossiblyMakeTag (struct rakuCtx *ctx, const char *s, int len)\n{\n    Assert(ctx->n_tokens > 0);\n    enum rakuKind kind = token2kind[ ctx->tokens[ctx->n_tokens - 1] ];\n    if (K_NONE != kind && rakuKinds[kind].enabled\n                       && (len = trimIdentifier(kind, &s, len)) > 0)\n        makeTag(ctx, kind, s, len);\n}\n\nstatic void\ninitRakuCtx (struct rakuCtx *ctx)\n{\n    ctx->n_tokens = 0;\n    ctx->name = vStringNew();\n    ctx->line = NULL;\n}\n\nstatic void\ndeinitRakuCtx (struct rakuCtx *ctx)\n{\n    vStringDelete(ctx->name);\n}\n\n/* Read next contiguous sequence of non-whitespace characters, store\n * the address in `ptok', and return its length.  Return value of zero\n * means EOF.\n *\n * TODO: Currently, POD and multi-line comments are not handled.\n */\nstatic int\ngetNonSpaceStr (struct rakuCtx *ctx, const char **ptok)\n{\n    size_t non_white_len;\n    const char *s;\n\n    while (ctx->line)\n    {\n        s = ctx->line;\n        while (*s && isspace((unsigned char) *s))   /* Skip whitespace */\n            ++s;\n        if ('#' != *s                               /* Skip comments */\n                && (non_white_len = strcspn(s, \",; \\t\"), non_white_len > 0))\n        {\n            ctx->line = s + non_white_len;          /* Save state */\n            *ptok = s;\n            return non_white_len;\n        }\n        ctx->line = (const char *) readLineFromInputFile();\n    }\n\n    return 0;\n}\n\nstatic void\nfindRakuTags (void)\n{\n    struct rakuCtx ctx;\n\n#define RESET_TOKENS() do { ctx.n_tokens = 0; } while (0)\n\n#define PUSH_TOKEN(_t_) do {                                            \\\n    if (ctx.n_tokens < ARRAY_SIZE(ctx.tokens)) {\t\t\t\\\n        ctx.tokens[ ctx.n_tokens ] = _t_;                               \\\n        ++ctx.n_tokens;                                                 \\\n    } else {                                                            \\\n        Assert(!\"Token stack overflown: this is quite odd\");            \\\n        RESET_TOKENS();                                                 \\\n    }                                                                   \\\n} while (0)\n\n    initRakuCtx(&ctx);\n\n    const char *s;\n    int len;\n\n    ctx.line = (const char *) readLineFromInputFile();\n    while ((len = getNonSpaceStr(&ctx, &s)) > 0) {\n        enum token token = matchToken(s, len);\n        if ((int) token >= 0) {\n            PUSH_TOKEN(token);\n        } else if (ctx.n_tokens > 0) {\n            possiblyMakeTag(&ctx, s, len);\n            RESET_TOKENS();\n        }\n    }\n\n    deinitRakuCtx(&ctx);\n}\n\nparserDefinition *\nRakuParser (void)\n{\n    static const char *const extensions[] = { \"raku\", \"rakumod\", \"rakutest\", \"rakudoc\", NULL };\n    parserDefinition* def = parserNew(\"Raku\");\n    def->kindTable      = rakuKinds;\n    def->kindCount  = ARRAY_SIZE(rakuKinds);\n    def->extensions = extensions;\n    def->parser     = findRakuTags;\n    return def;\n}\n\n\n/*\n * Perl6 for keeping backward compatibility of the CLI.\n */\n#include \"selectors.h\"\n/* TODO: sharing a kind array within two parsers are bad idea.\n * e.g. The combination of --kinds-Perl6=+c and --kinds-Raku=-c\n * doesn't work.\n */\n#define perl6Kinds rakuKinds\n/* NOTE: We assume the grammer of Raku is upper compatible with\n * Perl6. When this assumption is no longer true, we may have to\n * copy the function, or this file. Don't waste your time to\n * make one function support two languages; Copying may be enough. */\n#define findPerl6Tags findRakuTags\nparserDefinition *\nPerl6Parser (void)\n{\n\tstatic const char *const extensions[] = { \"p6\", \"pm6\", \"pm\", \"pl6\", \"t6\", NULL };\n    static selectLanguage selectors [] = { selectByPickingPerlVersion,\n\t\t\t\t\t   NULL };\n    parserDefinition* def = parserNew(\"Perl6\");\n    def->kindTable      = perl6Kinds;\n    def->kindCount  = ARRAY_SIZE(perl6Kinds);\n    def->extensions = extensions;\n    def->parser     = findPerl6Tags;\n    def->selectLanguage = selectors;\n    return def;\n}\n"
  },
  {
    "path": "parsers/relaxng.c",
    "content": "/*\n*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for RelaxNG.\n*\n*   https://www.oasis-open.org/committees/relax-ng/spec-20010811.html\n*\n*/\n\n#include \"general.h\"\t/* must always come first */\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"x-xml.h\"\n\ntypedef enum {\n\tK_ELEMENT,\n\tK_ATTRIBUTE,\n\tK_NAMED_PATTERN,\n} relaxngKind;\n\nstatic kindDefinition RelaxNGKinds [] = {\n\t{ true,  'e', \"element\",     \"elements\"       },\n\t{ true,  'a', \"attribute\",   \"attributes\"     },\n\t{ true,  'n', \"namedPattern\", \"named patterns\" },\n};\n\nenum relaxngXpathTable {\n\tTABLE_MAIN, TABLE_ELEMENT_NAME, TABLE_PATTERN, TABLE_GRAMMAR, TABLE_DEFINE_NAME,\n};\n\nstatic void relaxngMakeAndFindTagsUnderElement (xmlNode *node,\n\t\t\t\t\t\tconst char *xpath,\n\t\t\t\t\t\tconst struct sTagXpathRecurSpec *spec,\n\t\t\t\t\t\txmlXPathContext *ctx,\n\t\t\t\t\t\tvoid *userData);\nstatic void relaxngMakeAndFindTagsUnderDefine (xmlNode *node,\n\t\t\t\t\t       const char *xpath,\n\t\t\t\t\t       const struct sTagXpathRecurSpec *spec,\n\t\t\t\t\t       xmlXPathContext *ctx,\n\t\t\t\t\t       void *userData);\n\nstatic void relaxngFindTags (xmlNode *node,\n\t\t\t     const char *xpath,\n\t\t\t     const struct sTagXpathRecurSpec *spec,\n\t\t\t     xmlXPathContext *ctx,\n\t\t\t     void *userData);\n\n\nstatic tagXpathTable relaxngXpathMainTable [] = {\n\t{ \"/*[local-name()='element']\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { relaxngMakeAndFindTagsUnderElement, TABLE_PATTERN } }\n\t},\n\t{ \"/*[local-name()='grammar']\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { relaxngFindTags, TABLE_GRAMMAR } }\n\t},\n};\n\nstatic void makeTagWithScope (xmlNode *node,\n\t\t\t      const char *xpath,\n\t\t\t      const struct sTagXpathMakeTagSpec *spec,\n\t\t\t      struct sTagEntryInfo *tag,\n\t\t\t      void *userData);\n\nstatic tagXpathTable relaxngXpathPatternTable [] = {\n\t{ \"./*[local-name()='element']\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { relaxngMakeAndFindTagsUnderElement, TABLE_PATTERN } }\n\t},\n\t{ \"./*[local-name()='attribute']/@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_ATTRIBUTE, ROLE_DEFINITION_INDEX,\n\t\t\t     makeTagWithScope } }\n\t},\n\t{ \"./*[not(local-name()='element')][not(local-name()='attribute')]\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { relaxngFindTags, TABLE_PATTERN } }\n\t},\n};\n\n\nstatic void makeTagWithUpdatingScope (xmlNode *node,\n\t\t\t\t      const char *xpath,\n\t\t\t\t      const struct sTagXpathMakeTagSpec *spec,\n\t\t\t\t      struct sTagEntryInfo *tag,\n\t\t\t\t      void *userData);\n\nstatic tagXpathTable relaxngXpathElementNameTable [] = {\n\t{ \"@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_ELEMENT, ROLE_DEFINITION_INDEX,\n\t\t\t     makeTagWithUpdatingScope } }\n\t},\n};\n\nstatic tagXpathTable relaxngXpathGrammerTable [] = {\n\t{ \"./*[local-name()='start']\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { relaxngFindTags, TABLE_PATTERN } }\n\t},\n\t{ \"./*[local-name()='define']\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { relaxngMakeAndFindTagsUnderDefine, TABLE_PATTERN } }\n\t}\n};\n\nstatic tagXpathTable relaxngXpathDefineNameTable [] = {\n\t{ \"@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_NAMED_PATTERN, ROLE_DEFINITION_INDEX,\n\t\t\t     makeTagWithUpdatingScope } }\n\t},\n};\n\nstatic tagXpathTableTable relaxngXpathTableTable[] = {\n\t[TABLE_MAIN]         = { ARRAY_AND_SIZE (relaxngXpathMainTable)        },\n\t[TABLE_ELEMENT_NAME] = { ARRAY_AND_SIZE (relaxngXpathElementNameTable) },\n\t[TABLE_PATTERN]      = { ARRAY_AND_SIZE (relaxngXpathPatternTable)     },\n\t[TABLE_GRAMMAR]      = { ARRAY_AND_SIZE (relaxngXpathGrammerTable)     },\n\t[TABLE_DEFINE_NAME]  = { ARRAY_AND_SIZE (relaxngXpathDefineNameTable)  },\n};\n\n\nstatic void\nrelaxngMakeAndFindTags(xmlNode *node,\n\t\t       const char *xpath,\n\t\t       const struct sTagXpathRecurSpec *spec,\n\t\t       xmlXPathContext *ctx,\n\t\t       int nextTable,\n\t\t       void *userData)\n{\n\tint corkIndex = *(int *)userData;\n\n\tfindXMLTags (ctx, node, nextTable, &corkIndex);\n\n\trelaxngFindTags (node, xpath, spec, ctx, &corkIndex);\n}\n\nstatic void\nrelaxngMakeAndFindTagsUnderElement (xmlNode *node,\n\t\t\t\t    const char *xpath,\n\t\t\t\t    const struct sTagXpathRecurSpec *spec,\n\t\t\t\t    xmlXPathContext *ctx,\n\t\t\t\t    void *userData)\n{\n\trelaxngMakeAndFindTags (node, xpath, spec, ctx, TABLE_ELEMENT_NAME, userData);\n}\n\nstatic void\nrelaxngMakeAndFindTagsUnderDefine (xmlNode *node,\n\t\t\t\t   const char *xpath,\n\t\t\t\t   const struct sTagXpathRecurSpec *spec,\n\t\t\t\t   xmlXPathContext *ctx,\n\t\t\t\t   void *userData)\n{\n\trelaxngMakeAndFindTags (node, xpath, spec, ctx, TABLE_DEFINE_NAME, userData);\n}\n\nstatic void\nrelaxngFindTags (xmlNode *node,\n\t\t const char *xpath CTAGS_ATTR_UNUSED,\n\t\t const struct sTagXpathRecurSpec *spec,\n\t\t xmlXPathContext *ctx,\n\t\t void *userData)\n{\n\tint corkIndex = *(int *)userData;\n\n\tfindXMLTags (ctx, node, spec->nextTable, &corkIndex);\n}\n\nstatic void\nsetScope (struct sTagEntryInfo *tag, int index)\n{\n\ttag->extensionFields.scopeKindIndex = KIND_GHOST_INDEX;\n\ttag->extensionFields.scopeName  = NULL;\n\ttag->extensionFields.scopeIndex = index;\n\n}\n\nstatic void\nmakeTagWithUpdatingScope (xmlNode *node CTAGS_ATTR_UNUSED,\n\t\t\t  const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t  const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t  struct sTagEntryInfo *tag,\n\t\t\t  void *userData)\n{\n\tint *corkIndex = userData;\n\n\n#if 0\n\tif (*corkIndex == CORK_NIL)\n\t\t/* TODO: mark tag as an entry point */\n\t\t;\n#endif\n\n\tsetScope (tag, *corkIndex);\n\n\t*corkIndex = makeTagEntry (tag);\n}\n\n\nstatic void\nfindRelaxNGTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic void\nmakeTagWithScope (xmlNode *node CTAGS_ATTR_UNUSED,\n\t\t  const char *xpath CTAGS_ATTR_UNUSED,\n\t\t  const struct sTagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t  struct sTagEntryInfo *tag,\n\t\t  void *userData)\n{\n\tsetScope (tag, *(int *)userData);\n\n\tmakeTagEntry (tag);\n}\n\nstatic void\nrunXPathEngine(xmlSubparser *s,\n\t\t\t   xmlXPathContext *ctx, xmlNode *root)\n{\n\tint corkIndex = CORK_NIL;\n\n\tfindXMLTags (ctx, root, TABLE_MAIN, &corkIndex);\n}\n\nstatic xmlSubparser relaxngSubparser = {\n\t.subparser = {\n\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t},\n\t.runXPathEngine = runXPathEngine,\n};\n\nextern parserDefinition*\nRelaxNGParser (void)\n{\n\tstatic const char *const extensions [] = { \"rng\", NULL };\n\tparserDefinition* const def = parserNew (\"RelaxNG\");\n\t/* static selectLanguage selectors[] = { selectByDTD, NULL }; */\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"XML\", &relaxngSubparser },\n\t};\n\n\tdef->kindTable         = RelaxNGKinds;\n\tdef->kindCount     = ARRAY_SIZE (RelaxNGKinds);\n\tdef->extensions    = extensions;\n\tdef->parser        = findRelaxNGTags;\n\tdef->tagXpathTableTable = relaxngXpathTableTable;\n\tdef->tagXpathTableCount = ARRAY_SIZE (relaxngXpathTableTable);\n\tdef->useCork = CORK_QUEUE;\n\t/* def->selectLanguage = selectors; */\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/rexx.c",
    "content": "/*\n*   Copyright (c) 2001-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for the REXX language\n*   (http://www.rexxla.org, http://www2.hursley.ibm.com/rexx).\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* always include first */\n#include \"parse.h\"    /* always include */\n#include \"routines.h\"\n#include \"selectors.h\"\n\nstatic tagRegexTable rexxTagRegexTable [] = {\n\t{\"^([A-Za-z0-9@#$\\\\.!?_]+)[ \\t]*:\", \"\\\\1\",\n\t \"s,subroutine,subroutines\", NULL},\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nextern parserDefinition* RexxParser (void)\n{\n\tstatic const char *const extensions [] = { \"cmd\", \"rexx\", \"rx\", NULL };\n\tparserDefinition* const def = parserNew (\"REXX\");\n\tstatic selectLanguage selectors[] = { selectByRexxCommentAndDosbatchLabelPrefix,\n\t\t\t\t\t      NULL };\n\tdef->extensions = extensions;\n\tdef->tagRegexTable = rexxTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE (rexxTagRegexTable);\n\tdef->method     = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\tdef->selectLanguage = selectors;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/rmarkdown.c",
    "content": "/*\n *\n *  Copyright (c) 2022, Masatake YAMATO\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n * This module contains functions for generating tags for R Markdown files.\n * https://bookdown.org/yihui/rmarkdown/\n *\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n#include \"x-markdown.h\"\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n\n#include <ctype.h>\n#include <string.h>\n\n/*\n *   DATA DEFINITIONS\n */\ntypedef enum {\n\tK_CHUNK_LABEL = 0,\n} rmarkdownKind;\n\nstatic kindDefinition RMarkdownKinds[] = {\n\t{ true, 'l', \"chunklabel\",       \"chunk labels\"},\n};\n\nstruct sRMarkdownSubparser {\n\tmarkdownSubparser markdown;\n\tint lastChunkLabel;\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void findRMarkdownTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\n#define skip_space(CP) \twhile (*CP == ' ' || *CP == '\\t') CP++;\n\nstatic int makeRMarkdownTag (vString *name, int kindIndex, bool anonymous)\n{\n\ttagEntryInfo e;\n\tinitTagEntry (&e, vStringValue (name), kindIndex);\n\tif (anonymous)\n\t\tmarkTagExtraBit (&e, XTAG_ANONYMOUS);\n\treturn makeTagEntry (&e);\n}\n\nstatic bool extractLanguageForCodeBlock (markdownSubparser *s,\n\t\t\t\t\t\t\t\t\t\t const char *langMarker,\n\t\t\t\t\t\t\t\t\t\t vString *langName)\n{\n\tstruct sRMarkdownSubparser *rmarkdown = (struct sRMarkdownSubparser *)s;\n\tconst char *cp = langMarker;\n\n\tif (*cp != '{')\n\t\treturn false;\n\tcp++;\n\n\tconst char *end = strpbrk(cp, \" \\t,}\");\n\tif (!end)\n\t\treturn false;\n\n\tif (end - cp == 0)\n\t\treturn false;\n\n\tvStringNCatS (langName, cp, end - cp);\n\n\tcp = end;\n\tif (*cp == ',' || *cp == '}')\n\t{\n\t\tvString *name = anonGenerateNew(\"__anon\", K_CHUNK_LABEL);\n\t\trmarkdown->lastChunkLabel = makeRMarkdownTag (name, K_CHUNK_LABEL, true);\n\t\tvStringDelete (name);\n\t\treturn true;\n\t}\n\n\tskip_space(cp);\n\n\tvString *chunk_label  = vStringNew ();\n\tbool anonymous = false;\n\twhile (isalnum((unsigned char)*cp) || *cp == '-')\n\t\tvStringPut (chunk_label, *cp++);\n\n\tif (vStringLength (chunk_label) == 0)\n\t{\n\t\tanonGenerate (chunk_label, \"__anon\", K_CHUNK_LABEL);\n\t\tanonymous = true;\n\t}\n\n\tskip_space(cp);\n\tif (*cp == ',' || *cp == '}')\n\t\trmarkdown->lastChunkLabel = makeRMarkdownTag (chunk_label, K_CHUNK_LABEL, anonymous);\n\n\tvStringDelete (chunk_label);\n\treturn true;\n}\n\nstatic void notifyEndOfCodeBlock (markdownSubparser *s)\n{\n\tstruct sRMarkdownSubparser *rmarkdown = (struct sRMarkdownSubparser *)s;\n\n\tif (rmarkdown->lastChunkLabel == CORK_NIL)\n\t\treturn;\n\n\tsetTagEndLineToCorkEntry (rmarkdown->lastChunkLabel, getInputLineNumber ());\n\n\trmarkdown->lastChunkLabel = CORK_NIL;\n}\n\nstatic void inputStart (subparser *s)\n{\n\tstruct sRMarkdownSubparser *rmarkdown = (struct sRMarkdownSubparser*)s;\n\n\trmarkdown->lastChunkLabel = CORK_NIL;\n}\n\nextern parserDefinition* RMarkdownParser (void)\n{\n\tstatic const char *const extensions [] = { \"rmd\", NULL };\n\tstatic struct sRMarkdownSubparser rmarkdownSubparser = {\n\t\t.markdown = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t\t\t.inputStart = inputStart,\n\t\t\t},\n\t\t\t.extractLanguageForCodeBlock = extractLanguageForCodeBlock,\n\t\t\t.notifyEndOfCodeBlock = notifyEndOfCodeBlock,\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Markdown\", &rmarkdownSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"RMarkdown\");\n\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE(dependencies);\n\tdef->kindTable      = RMarkdownKinds;\n\tdef->kindCount  = ARRAY_SIZE (RMarkdownKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findRMarkdownTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/robot.c",
    "content": "/*\n *   Copyright (c) 2017, Daniel Riechers\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   Parser from Robot Framework http://robotframework.org\n */\n\n#include \"general.h\"\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"vstring.h\"\n#include \"routines.h\"\n\ntypedef enum {\n        K_TESTCASE,\n        K_KEYWORD,\n        K_VARIABLE,\n        COUNT_KIND\n} RobotKind;\n\nstatic RobotKind section = -1;\n\nstatic kindDefinition RobotKinds[COUNT_KIND] = {\n\t{true, 't', \"testcase\",   \"testcases\"},\n\t{true, 'k', \"keyword\",    \"keywords\"},\n\t{true, 'v', \"variable\",   \"variables\"},\n};\n\ntypedef enum {\n\tX_WHITESPACE_SWAPPED,\n} robotXtag;\n\nstatic xtagDefinition RobotXtags [] = {\n\t{\n\t\t.enabled = true,\n\t\t.name = \"whitespaceSwapped\",\n\t\t.description = \"Include tags swapping whitespace and underscore chars\",\n\t},\n};\n\n\nstatic void findRobotTags (void)\n{\n\tfindRegexTags ();\n}\n\nstatic bool whitespaceSwap (vString *const s)\n{\n        char replaceWith = '_';\n        char toReplace = ' ';\n\t\tchar changed = false;\n\n        if(strchr(vStringValue (s), '_'))\n        {\n            replaceWith = ' ';\n            toReplace = '_';\n        }\n\n        for(unsigned int i=0; i < vStringLength(s); i++)\n            if(vStringChar(s, i) == toReplace)\n\t\t\t{\n                vStringChar (s, i) = replaceWith;\n\t\t\t\tchanged = true;\n\t\t\t}\n\n\t\treturn changed;\n}\n\nstatic bool changeSection (const char *const line, const regexMatch *const matches,\n                               const unsigned int count CTAGS_ATTR_UNUSED, void *data CTAGS_ATTR_UNUSED)\n{\n    const char * const matchedSection = line + matches[1].start;\n\n    if(strncasecmp(matchedSection, \"test cases\", matches[1].length) == 0)\n    {\n        section = K_TESTCASE;\n    }\n    else if(strncasecmp(matchedSection, \"keywords\", matches[1].length) == 0)\n    {\n        section = K_KEYWORD;\n    }\n    else if(strncasecmp(matchedSection, \"variables\", matches[1].length) == 0)\n    {\n        section = K_VARIABLE;\n    }\n\treturn true;\n}\n\nstatic void makeSimpleXTag (const vString* const name, const int kind,\n\t\t\t\t\t\t\tunsigned int xtagType)\n{\n\ttagEntryInfo e;\n\n\tinitTagEntry (&e, vStringValue(name), kind);\n\tmarkTagExtraBit (&e, xtagType);\n\tmakeTagEntry (&e);\n}\n\nstatic bool tagKeywordsAndTestCases (const char *const line, const regexMatch *const matches,\n                               const unsigned int count, void *data CTAGS_ATTR_UNUSED)\n{\n    if (count > 1 && ( section == K_KEYWORD || section == K_TESTCASE) )\n    {\n        vString *const name = vStringNew ();\n        vStringNCopyS (name, line + matches [1].start, matches [1].length);\n        makeSimpleTag (name, section);\n        if (isXtagEnabled (RobotXtags[X_WHITESPACE_SWAPPED].xtype)\n\t\t\t&& whitespaceSwap(name))\n\t\t\tmakeSimpleXTag (name, section,\n\t\t\t\t\t\t\tRobotXtags[X_WHITESPACE_SWAPPED].xtype);\n        vStringDelete (name);\n\t\treturn true;\n    }\n\treturn false;\n}\n\nstatic bool tagVariables (const char *const line, const regexMatch *const matches,\n                               const unsigned int count, void *data CTAGS_ATTR_UNUSED)\n{\n    if (count > 1 && section == K_VARIABLE)\n    {\n        vString *const name = vStringNew ();\n        vStringNCopyS (name, line + matches [1].start, matches [1].length);\n        makeSimpleTag (name, K_VARIABLE);\n        if (isXtagEnabled (RobotXtags[X_WHITESPACE_SWAPPED].xtype)\n\t\t\t&& whitespaceSwap(name))\n\t\t\tmakeSimpleXTag (name, K_VARIABLE,\n\t\t\t\t\t\t\tRobotXtags[X_WHITESPACE_SWAPPED].xtype);\n        vStringDelete (name);\n\t\treturn true;\n    }\n\treturn false;\n}\n\nstatic void initialize (const langType language)\n{\n    addLanguageCallbackRegex (language, \"^\\\\*+ *([^* ].+[^* ]) *\\\\*+$\",\n            \"{exclusive}\", changeSection, NULL, NULL);\n\n    addLanguageCallbackRegex (\n\t\tlanguage,\n\t\t\"(^([A-Za-z0-9]+|\\\\$\\\\{[_A-Za-z0-9][' _A-Za-z0-9]*(:([^}]|\\\\\\\\)+)*\\\\})([${}' _]([-_$A-Za-z0-9]+|\\\\{[_A-Za-z0-9][' _A-Za-z0-9]*(:([^}]|\\\\\\\\)+)*\\\\})+)*)\",\n\t\t\"{exclusive}\", tagKeywordsAndTestCases, NULL, NULL);\n\n    addLanguageCallbackRegex (language, \"^[$@]\\\\{([_A-Za-z0-9][' _A-Za-z0-9]+)\\\\}  [ ]*.+\",\n            \"{exclusive}\", tagVariables, NULL, NULL);\n}\n\nextern parserDefinition* RobotParser (void)\n{\n\tstatic const char *const extensions[] = { \"robot\", NULL };\n\tparserDefinition *def = parserNew (\"Robot\");\n    def->kindTable      = RobotKinds;\n    def->kindCount  = COUNT_KIND;\n\tdef->extensions = extensions;\n\tdef->initialize = initialize;\n    def->parser     = findRobotTags;\n\tdef->xtagTable = RobotXtags;\n\tdef->xtagCount = ARRAY_SIZE (RobotXtags);\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/rpmspec.c",
    "content": "/*\n*   Copyright (c) 2016 Masatake YAMATO\n*   Copyright (c) 2016 Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for rpm spec files.\n*\n*   References:\n*   \t- https://rpm-software-management.github.io/rpm/manual/macros.html\n*   \t- https://rpm-software-management.github.io/rpm/manual/spec.html\n*   \t- http://ftp.rpm.org/api/4.4.2.2/dependencies.html\n*/\n\n/*\n * TODO\n *\n * 1. Capturing required and provide packages as reference tags\n * 2. Capturing bz numbers and package versions in %changelog section\n */\n#include \"general.h\"  /* must always come first */\n\n#include <ctype.h>\n#include <stddef.h>\n#ifdef HAVE_SYS_TYPES_H\n# include <sys/types.h>  /* declare off_t (not known to regex.h on FreeBSD) */\n#endif\n#include <regex.h>\n\n#include <string.h>\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"trace.h\"\n\n#include \"dependency.h\"\n#include \"x-autoconf.h\"\n\ntypedef enum {\n\tK_TAG,\n\tK_MACOR,\n\tK_PACKAGE,\n\tK_GLOBAL,\n\tK_PATCH,\n\tK_BCOND,\n} rpmSpecKind;\n\nenum rpmSpecMacroRole {\n\tR_MACRO_UNDEF,\n};\ntypedef int rpmSpecMacroRole; /* to allow ROLE_INDEX_* */\n\nstatic roleDefinition RpmSpecMacroRoles [] = {\n\t{ true, \"undef\", \"undefined\" },\n};\n\nenum rpmSpecPatchRole {\n\tR_PATCH_DECL,\n};\n\nstatic roleDefinition RpmSpecPatchRoles [] = {\n\t{ true, \"decl\", \"declared for applying later\" },\n};\n\nstatic scopeSeparator RpmSpecPackageSeparators [] = {\n\t{ K_PACKAGE , \"-\" },\n};\n\nstatic kindDefinition RpmSpecKinds[] = {\n\t{ true, 't', \"tag\", \"tags\" },\n\t{ true, 'm', \"macro\", \"macros\",\n\t  .referenceOnly = false, ATTACH_ROLES(RpmSpecMacroRoles) },\n\t{ true, 'p', \"package\", \"packages\",\n\t  ATTACH_SEPARATORS(RpmSpecPackageSeparators) },\n\t{ true, 'g', \"global\", \"global macros\" },\n\t{ true, 'p', \"patch\", \"patch files\",\n\t  .referenceOnly = true, ATTACH_ROLES(RpmSpecPatchRoles) },\n\t{ true, 'b', \"bcond\", \"build condition\",\n\t  .version = 1 },\n\n};\n\nstruct macro_cb_data {\n\trpmSpecKind kindex;\n\trpmSpecMacroRole rindex;\n};\n\nstruct rpmSpecCtx {\n\tbool rejecting;\n\tstruct macro_cb_data macro;\n\tstruct macro_cb_data global;\n\tstruct macro_cb_data undef;\n\tint package_index;\n\tint macro_index;\n\tbool in_configure;\n} rpmSpecCtx;\n\nstatic langType Lang_autoconf;\n\nstatic bool is_line_continued(const char *line)\n{\n\tsize_t len = strlen (line);\n\n\tif (len == 0)\n\t\treturn false;\n\n\treturn ((line[len - 1] == '\\\\')\n\t\t|| ((len >= 2) && (line[len - 1] == '\\n') && (line[len - 2] == '\\\\')))? true: false;\n}\n\nstatic void scan_configure_options (const char *line)\n{\n\tstruct configure_opt_prefix {\n\t\tconst char *prefix;\n\t\tint kindIndex, roleIndex;\n\t} prefixes[] = {\n\t\t{.prefix = \"--with-\",\n\t\t .kindIndex = AUTOCONF_OPTWITH_KIND,\n\t\t .roleIndex = AUTOCONF_OPTWITH_CMDLINE_ROLE},\n\t\t{.prefix = \"--without-\",\n\t\t .kindIndex = AUTOCONF_OPTWITH_KIND,\n\t\t .roleIndex = AUTOCONF_OPTWITH_CMDLINE_ROLE},\n\t\t{.prefix = \"--enable-\",\n\t\t .kindIndex = AUTOCONF_OPTENABLE_KIND,\n\t\t .roleIndex = AUTOCONF_OPTENABLE_CMDLINE_ROLE},\n\t\t{.prefix = \"--disable-\",\n\t\t .kindIndex = AUTOCONF_OPTENABLE_KIND,\n\t\t .roleIndex = AUTOCONF_OPTENABLE_CMDLINE_ROLE},\n\t\t{.prefix = NULL,},\n\t};\n\tvString *name = vStringNew ();\n\n\tfor (struct configure_opt_prefix *prefix = &(prefixes [0]);\n\t\t prefix->prefix;\n\t\t prefix++)\n\t{\n\t\tconst char *tmp = line;\n\n\t\twhile ((tmp = strstr (tmp, prefix->prefix)))\n\t\t{\n\t\t\ttmp += strlen(prefix->prefix);\n\t\t\twhile (*tmp)\n\t\t\t{\n\t\t\t\tif (isspace ((unsigned char) *tmp) || iscntrl ((unsigned char) *tmp)\n\t\t\t\t\t|| *tmp == '=' || *tmp == '\\\\')\n\t\t\t\t\tbreak;\n\t\t\t\tvStringPut(name, *tmp);\n\t\t\t\ttmp++;\n\t\t\t}\n\t\t\tif (vStringLength (name) > 0)\n\t\t\t{\n\t\t\t\ttagEntryInfo e;\n\n\t\t\t\tinitForeignRefTagEntry (&e,\n\t\t\t\t\t\t\t\t\t\tvStringValue (name),\n\t\t\t\t\t\t\t\t\t\tLang_autoconf,\n\t\t\t\t\t\t\t\t\t\tprefix->kindIndex,\n\t\t\t\t\t\t\t\t\t\tprefix->roleIndex);\n\t\t\t\tmakeTagEntry (&e);\n\t\t\t\tvStringClear (name);\n\t\t\t}\n\t\t\ttmp++;\n\t\t}\n\t}\n\tvStringDelete (name);\n}\n\nstatic bool found_configure_cb (const char *line,\n\t\t\t\t\t\t\tconst regexMatch *matches,\n\t\t\t\t\t\t\tunsigned int count,\n\t\t\t\t\t\t\tvoid *userData)\n{\n\tstruct rpmSpecCtx *ctx = (struct rpmSpecCtx *)userData;\n\tctx->rejecting = (line && is_line_continued (line));\n\tctx->in_configure = true;\n\tscan_configure_options (line);\n\treturn true;\n}\n\nstatic bool found_macro_cb_full (const char *line,\n\t\t\t\t\t\t\t\t const regexMatch *matches,\n\t\t\t\t\t\t\t\t unsigned int count,\n\t\t\t\t\t\t\t\t bool global,\n\t\t\t\t\t\t\t\t bool undef,\n\t\t\t\t\t\t\t\t void *userData)\n{\n\tstruct rpmSpecCtx *ctx = (struct rpmSpecCtx *)userData;\n\tstruct macro_cb_data *data;\n\n\tctx->rejecting = (line && is_line_continued (line));\n\n\tTRACE_PRINT(\"Line %04d continuation: %d\",\n\t\t\t\tgetInputLineNumber(), ctx->rejecting);\n\n\tif (undef)\n\t\tdata = &ctx->undef;\n\telse if (global)\n\t\tdata = &ctx->global;\n\telse\n\t\tdata = &ctx->macro;\n\n\tif (count > 0)\n\t{\n\t\tvString *signature = ((count > 1) && (matches[2].length > 0))? vStringNew(): NULL;\n\t\tvString *name = vStringNew ();\n\t\ttagEntryInfo tag;\n\n\t\tif (signature)\n\t\t\tvStringNCopyS (signature, line + matches[2].start, matches[2].length);\n\t\tvStringNCopyS (name, line + matches[1].start, matches[1].length);\n\n\t\tif (data->rindex == ROLE_DEFINITION_INDEX)\n\t\t\tinitTagEntry (&tag, vStringValue (name), data->kindex);\n\t\telse\n\t\t\tinitRefTagEntry (&tag, vStringValue (name), data->kindex, data->rindex);\n\n\t\tif (signature)\n\t\t\ttag.extensionFields.signature = vStringValue (signature);\n\n\t\tif (!ctx->rejecting)\n\t\t{\n\t\t\t/* The line is not continued. Let's record the endLine now. */\n\t\t\tsetTagEndLine (&tag, getInputLineNumber());\n\t\t}\n\n\t\tint cork_index = makeTagEntry (&tag);\n\t\tif (data->rindex == ROLE_DEFINITION_INDEX && ctx->rejecting)\n\t\t{\n\t\t\t/* The line is continued. Let's record the cork index\n\t\t\t   for attaching endLine field later. */\n\t\t\tctx->macro_index = cork_index;\n\t\t}\n\n\t\tvStringDelete (name);\n\t\tif (signature)\n\t\t\tvStringDelete (signature);\n\t}\n\treturn true;\n}\n\nstatic bool found_macro_cb (const char *line,\n\t\t\t\t\t\t\tconst regexMatch *matches,\n\t\t\t\t\t\t\tunsigned int count,\n\t\t\t\t\t\t\tvoid *userData)\n{\n\treturn found_macro_cb_full(line, matches, count, false, false, userData);\n}\n\nstatic bool found_global_cb (const char *line,\n\t\t\t    const regexMatch *matches,\n\t\t\t    unsigned int count,\n\t\t\t    void *userData)\n{\n\treturn found_macro_cb_full(line, matches, count, true, false, userData);\n}\n\nstatic bool found_undef_cb (const char *line,\n\t\t\t    const regexMatch *matches,\n\t\t\t    unsigned int count,\n\t\t\t    void *userData)\n{\n\treturn found_macro_cb_full(line, matches, count, false, true, userData);\n}\n\n\nstatic bool alldigits (const char * str)\n{\n\twhile (isdigit ((unsigned char) *str))\n\t\tstr++;\n\n\tif (*str == '\\0')\n\t\treturn true;\n\treturn false;\n}\n\nstatic bool found_tag_cb (const char *line,\n\t\t\t  const regexMatch *matches,\n\t\t\t  unsigned int count,\n\t\t\t  void *userData)\n{\n\tif (count > 0)\n\t{\n\t\tvString *name = vStringNew ();\n\t\tvStringNCopyS (name, line + matches[1].start, matches[1].length);\n\t\tmakeSimpleTag (name, K_TAG);\n\n\t\tif (count > 1)\n\t\t{\n\t\t\tif (strcasecmp (vStringValue (name), \"name\") == 0)\n\t\t\t{\n\t\t\t\tvString *package = vStringNew ();\n\t\t\t\tvStringNCopyS (package, line + matches[2].start, matches[2].length);\n\t\t\t\t((struct rpmSpecCtx *)userData)->package_index\n\t\t\t\t\t= makeSimpleTag (package, K_PACKAGE);\n\t\t\t\tvStringDelete (package);\n\t\t\t}\n\t\t\telse if (strncasecmp (vStringValue (name), \"patch\", 5) == 0\n\t\t\t\t\t && alldigits (vStringValue (name) + 5))\n\t\t\t{\n\t\t\t\tvString *patch = vStringNew ();\n\t\t\t\tvStringNCopyS (patch, line + matches[2].start, matches[2].length);\n\t\t\t\tmakeSimpleRefTag (patch, K_PATCH, R_PATCH_DECL);\n\t\t\t\tvStringDelete (patch);\n\t\t\t}\n\t\t}\n\t\tvStringDelete (name);\n\t}\n\treturn true;\n}\n\nstatic bool found_package_cb (const char *line,\n\t\t\t      const regexMatch *matches,\n\t\t\t      unsigned int count,\n\t\t\t      void *userData)\n{\n\tif (count == 0)\n\t\treturn true;\n\n\t/* ---\n\t * NAME: foo\n\t * %package bar\n\t * ---\n\t * In this case, emit foo-bar as a FQ tag.\n\t *\n\t * ---\n\t * NAME: foo\n\t * %package -n baz\n\t * ---\n\t * In this case, don't emit FQ tag.\n\t */\n\tbool fq = true;\n\n\t/* strlen(\"-n\") => 2 */\n\tif (matches[1].length > 2)\n\t\tfq = false;\n\n\tvString *name = vStringNew ();\n\ttagEntryInfo tag;\n\n\tvStringNCopyS (name, line + matches[2].start, matches[2].length);\n\tinitTagEntry (&tag, vStringValue (name), K_PACKAGE);\n\ttag.extensionFields.scopeIndex = ((struct rpmSpecCtx *)userData)->package_index;\n\n\tif (!fq)\n\t\ttag.skipAutoFQEmission = 1;\n\n\tmakeTagEntry (&tag);\n\tvStringDelete (name);\n\n\treturn true;\n}\n\nstatic bool found_bcond_cb (const char *line,\n\t\t\t      const regexMatch *matches,\n\t\t\t      unsigned int count,\n\t\t\t      void *userData)\n{\n\tchar *name = eStrndup(line + matches[2].start, matches[2].length);\n\ttagEntryInfo tag;\n\n\tinitTagEntry (&tag, name, K_BCOND);\n\n\tmakeTagEntry (&tag);\n\teFree (name);\n\treturn true;\n}\n\nstatic bool check_line_continuation (const char *line,\n\t\t\t      const regexMatch *matches,\n\t\t\t      unsigned int count,\n\t\t\t      void *userData)\n{\n\tstruct rpmSpecCtx *ctx = (struct rpmSpecCtx *)userData;\n\tbool rejecting = ctx->rejecting;\n\tctx->rejecting = (line && is_line_continued (line));\n\n\tTRACE_PRINT(\"Line %04d continuation: %d -> %d\",\n\t\t\t\tgetInputLineNumber(), rejecting, ctx->rejecting);\n\n\ttagEntryInfo *e = getEntryInCorkQueue (ctx->macro_index);\n\tif (rejecting && (!ctx->rejecting) && e)\n\t{\n\t\tsetTagEndLine (e, getInputLineNumber());\n\t\tctx->macro_index = CORK_NIL;\n\t}\n\telse if (rejecting && ctx->in_configure)\n\t{\n\t\tscan_configure_options (line);\n\t\tif (!ctx->rejecting)\n\t\t\tctx->in_configure = false;\n\t}\n\n\treturn true;\n}\n\nstatic void findRpmSpecTags (void)\n{\n\trpmSpecCtx.rejecting = false;\n\trpmSpecCtx.macro = (struct macro_cb_data){.kindex = K_MACOR, .rindex = ROLE_DEFINITION_INDEX};\n\trpmSpecCtx.global = (struct macro_cb_data){K_GLOBAL, ROLE_DEFINITION_INDEX};\n\trpmSpecCtx.undef = (struct macro_cb_data){K_MACOR,  R_MACRO_UNDEF};\n\trpmSpecCtx.package_index = CORK_NIL;\n\trpmSpecCtx.macro_index = CORK_NIL;\n\trpmSpecCtx.in_configure = false;\n\n\tfindRegexTags ();\n}\n\nstatic void initializeRpmSpecParser (langType language)\n{\n\taddLanguageCallbackRegex (language,  \"^([A-Za-z_][A-Za-z_0-9()]+)[ \\t]*:[ \\t]*([^ \\t]*)\",\n\t\t\t  \"{exclusive}\", found_tag_cb, &rpmSpecCtx.rejecting, &rpmSpecCtx);\n\taddLanguageCallbackRegex (language, \"^%configure\",\n\t\t\t  \"{exclusive}\", found_configure_cb, &rpmSpecCtx.rejecting, &rpmSpecCtx);\n\taddLanguageCallbackRegex (language, \"^%define[ \\t]+([A-Za-z_][A-Za-z_0-9]+)(\\\\([^)]+\\\\))?\",\n\t\t\t  \"{exclusive}\", found_macro_cb, &rpmSpecCtx.rejecting, &rpmSpecCtx);\n\taddLanguageCallbackRegex (language, \"^%undef[ \\t]+([A-Za-z_][A-Za-z_0-9]+)\",\n\t\t\t  \"{exclusive}\", found_undef_cb, &rpmSpecCtx.rejecting, &rpmSpecCtx);\n\taddLanguageCallbackRegex (language, \"^%global[ \\t]+([A-Za-z_][A-Za-z_0-9]+)(\\\\([^)]+\\\\))?\",\n\t\t\t  \"{exclusive}\", found_global_cb, &rpmSpecCtx.rejecting, &rpmSpecCtx);\n\taddLanguageCallbackRegex (language, \"^%package[ \\t]+(-n[ \\t]+)?([A-Za-z_][A-Za-z_0-9-]+)\",\n\t\t\t  \"{exclusive}\", found_package_cb, &rpmSpecCtx.rejecting, &rpmSpecCtx);\n\taddLanguageCallbackRegex (language, \"^%bcond(|_without|_with)[ \\t]+([A-Za-z_]+)\",\n\t\t\t  \"{exclusive}\", found_bcond_cb, &rpmSpecCtx.rejecting, &rpmSpecCtx);\n\taddLanguageCallbackRegex (language, \"^.*$\",\n\t\t\t  \"{exclusive}\", check_line_continuation, NULL, &rpmSpecCtx);\n}\n\nextern parserDefinition* RpmSpecParser (void)\n{\n\tstatic const char *const extensions [] = { \"spec\", NULL };\n\tstatic const char *const aliases [] = {\n\t\t\"rpm-spec\",\t\t\t\t/* the mode name in Emacs */\n\t\tNULL };\n\tparserDefinition* const def = parserNew (\"RpmSpec\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_FOREIGNER, \"Autoconf\", &Lang_autoconf },\n\t};\n\n\tdef->kindTable = RpmSpecKinds;\n\tdef->kindCount = ARRAY_SIZE (RpmSpecKinds);\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\tdef->initialize = initializeRpmSpecParser;\n\tdef->parser = findRpmSpecTags;\n\tdef->method     = METHOD_REGEX;\n\tdef->useCork = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/rspec.c",
    "content": "/*\n*\n* Copyright (c) 2017, Red Hat, Inc.\n* Copyright (c) 2017, Masatake YAMATO\n*\n* Author: Masatake YAMATO <yamato@redhat.com>\n*\n* This program is free software; you can redistribute it and/or\n* modify it under the terms of the GNU General Public License\n* as published by the Free Software Foundation; either version 2\n* of the License, or (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program; if not, write to the Free Software\n* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n* USA.\n*\n* Inspired by the following commit but written from scratch:\n* ==========================================================\n*\n* commit 76dbed4de88875d8c8409dfd65da4f94f901c94a\n* Author: Ram Singla <ram.singla@gmail.com>\n* Date:   Tue Jan 18 13:24:46 2011 +0800\n*\n*    RSpec Code added. Courtesy: mortice\n*\n* ==========================================================\n*\n* Reference:\n* - https://rubydoc.info/gems/rspec-core/frames\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"numarray.h\"\n#include \"parse.h\"\n#include \"subparser.h\"\n\n#include \"x-ruby.h\"\n\n#include <string.h>\n\n/*\n* DATA STRUCTURES\n*/\nstruct sRSpecSubparser {\n\trubySubparser ruby;\n\tint scope;\n};\n\ntypedef enum {\n\tK_DESCRIBE,\n\tK_CONTEXT,\n\tK_IT,\n} rspecKind;\n\nstatic kindDefinition RSpecKinds [] = {\n\t{ true, 'd', \"describe\", \"describes\" },\n\t{ true, 'c', \"context\", \"contexts\" },\n\t{ true, 'i', \"it\", \"things described with \\\"it\\\"\" },\n};\n\n/*\n* FUNCTIONS\n*/\nstatic int makeSimpleRSpecTag (vString *vstr, int kindIndex, rubySubparser *subparser)\n{\n\tint r = makeSimpleTag (vstr, kindIndex);\n\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\tif (e)\n\t{\n\t\tstruct sRSpecSubparser *rspec = (struct sRSpecSubparser *)subparser;\n\t\te->extensionFields.scopeIndex = rspec->scope;\n\t}\n\treturn r;\n}\n\nstatic vString *readRest (const unsigned char **cp)\n{\n\tvString *vstr = NULL;\n\tunsigned char b;\n\n\tswitch (**cp)\n\t{\n\tcase '\\'':\n\tcase '\"':\n\t\tb = **cp;\n\t\t++*cp;\n\t\tvstr = vStringNew ();\n\t\tif (!rubyParseString (cp, b, vstr))\n\t\t{\n\t\t\tvStringDelete (vstr);\n\t\t\tvstr = NULL;\n\t\t}\n\t\tbreak;\n\tcase ':':\n\t\t/* symbol, Should this be part of the Ruby parser side? */\n\t\tbreak;\n\tdefault:\n\t\tvstr = vStringNew ();\n\t\tif (!rubyParseModuleName (cp, vstr))\n\t\t{\n\t\t\tvStringDelete (vstr);\n\t\t\tvstr = NULL;\n\t\t}\n\t\telse if (strcmp (vStringValue (vstr), \"do\") == 0)\n\t\t{\n\t\t\tvStringDelete (vstr);\n\t\t\tvstr = NULL;\n\t\t\t*cp += -2;\t\t\t/* push back \"do\" */\n\t\t}\n\n\t\tbreak;\n\t}\n\n\tif (vstr)\n\t{\n\t\trubySkipWhitespace (cp);\n\t\tif (**cp == ',')\n\t\t{\n\t\t\t++*cp;\n\t\t\trubySkipWhitespace (cp);\n\t\t\tvString *vstr_rest = readRest (cp);\n\t\t\tif (vstr_rest)\n\t\t\t{\n\t\t\t\tvStringPut (vstr, ' ');\n\t\t\t\tvStringCat (vstr, vstr_rest);\n\t\t\t\tvStringDelete (vstr_rest);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn vstr;\n}\n\nstruct caseType {\n\tconst char *keyword;\n\trspecKind    kind;\n};\n\nstatic int lineNotify (rubySubparser *s, const unsigned char **cp, int corkIndex CTAGS_ATTR_UNUSED)\n{\n\tstruct caseType caseTypes [] = {\n\t\t{ \"describe\", K_DESCRIBE },\n\t\t{ \"RSpec.describe\", K_DESCRIBE },\n\t\t{ \"context\", K_CONTEXT },\n\t\t{ \"it\", K_IT },\n\t};\n\n\tfor (int i = 0; i < ARRAY_SIZE(caseTypes); i++)\n\t{\n\t\tif (rubyCanMatchKeywordWithAssign(cp, caseTypes[i].keyword))\n\t\t{\n\t\t\tvString *vstr = NULL;\n\t\t\trubySkipWhitespace (cp);\n\t\t\tvstr = readRest (cp);\n\t\t\tif (vstr)\n\t\t\t{\n\t\t\t\tint r = makeSimpleRSpecTag (vstr, caseTypes[i].kind, s);\n\t\t\t\tvStringDelete (vstr);\n\t\t\t\treturn r;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn CORK_NIL;\n}\n\nstatic void enterBlockNotify (rubySubparser *s, int corkIndex)\n{\n\tstruct sRSpecSubparser *rspec = (struct sRSpecSubparser *)s;\n\trspec->scope = corkIndex;\n}\n\nstatic void leaveBlockNotify (rubySubparser *s, int corkIndex)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\tif (e)\n\t{\n\t\tstruct sRSpecSubparser *rspec = (struct sRSpecSubparser *)s;\n\t\trspec->scope = e->extensionFields.scopeIndex;\n\t}\n}\n\nstatic void findRSpecTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic void inputStart (subparser *s)\n{\n\tstruct sRSpecSubparser *rspec = (struct sRSpecSubparser *)s;\n\trspec->scope = CORK_NIL;\n}\n\nextern parserDefinition* RSpecParser (void)\n{\n\tstatic struct sRSpecSubparser rspecSubparser = {\n\t\t.ruby = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_BASE_RUNS_SUB,\n\t\t\t\t.inputStart = inputStart,\n\t\t\t},\n\t\t\t.lineNotify = lineNotify,\n\t\t\t.enterBlockNotify = enterBlockNotify,\n\t\t\t.leaveBlockNotify = leaveBlockNotify,\n\t\t},\n\t\t.scope = CORK_NIL,\n\t};\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Ruby\", &rspecSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"RSpec\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE(dependencies);\n\tdef->kindTable  = RSpecKinds;\n\tdef->kindCount  = ARRAY_SIZE (RSpecKinds);\n\tdef->parser     = findRSpecTags;\n\tdef->useCork    = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/rst.c",
    "content": "/*\n*\n*   Copyright (c) 2007-2011, Nick Treleaven\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for reStructuredText (reST) files.\n*\n*   This module was ported from geany.\n*\n*   References:\n*      https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include <ctype.h>\n#include <string.h>\n\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"utf8_str.h\"\n#include \"nestlevel.h\"\n#include \"entry.h\"\n#include \"routines.h\"\n#include \"field.h\"\n#include \"htable.h\"\n#include \"debug.h\"\n#include \"promise.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_EOF = -1,\n\tK_TITLE = 0,\n\tK_SUBTITLE,\n\tK_CHAPTER,\n\tK_SECTION,\n\tK_SUBSECTION,\n\tK_SUBSUBSECTION,\n\tSECTION_COUNT,\n\tK_CITATION = SECTION_COUNT,\n\tK_TARGET,\n\tK_SUBSTDEF,\n} rstKind;\n\nstatic kindDefinition RstKinds[] = {\n\t{ true, 'H', \"title\",         \"titles\"},\n\t{ true, 'h', \"subtitle\",      \"sub titles\" },\n\t{ true, 'c', \"chapter\",       \"chapters\"},\n\t{ true, 's', \"section\",       \"sections\" },\n\t{ true, 'S', \"subsection\",    \"subsections\" },\n\t{ true, 't', \"subsubsection\", \"subsubsections\" },\n\t{ true, 'C', \"citation\",      \"citations\"},\n\t{ true, 'T', \"target\",        \"targets\" },\n\t{ true, 'd', \"substdef\",      \"substitute definitions\" },\n};\n\ntypedef enum {\n\tF_SECTION_MARKER,\n\tF_SECTION_OVERLINE,\n} rstField;\n\nstatic fieldDefinition RstFields [] = {\n\t{\n\t\t.name = \"sectionMarker\",\n\t\t.description = \"character used for declaring section\",\n\t\t.enabled = false,\n\t},\n\t{\n\t\t.name = \"overline\",\n\t\t.description = \"whether using overline & underline for declaring section\",\n\t\t.enabled = false,\n\t\t.dataType = FIELDTYPE_BOOL\n\t},\n};\n\nstatic NestingLevels *nestingLevels = NULL;\n\nstruct sectionTracker {\n\tchar kindchar;\n\tbool overline;\n\tint count;\n};\n\nstruct olineTracker\n{\n\tchar c;\n\tsize_t len;\n};\n\nstruct codeblockTracker {\n\tsize_t blockIndent;\n\tchar *language;\n\tunsigned long startLine;\n\tunsigned long endLine;\n\tunsigned long endLineLength;\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic NestingLevel *getNestingLevel(const int kind)\n{\n\tNestingLevel *nl;\n\ttagEntryInfo *e;\n\n\tint d = 0;\n\n\tif (kind > K_EOF)\n\t{\n\t\td++;\n\t\t/* 1. we want the line before the '---' underline chars */\n\t\td++;\n\t\t/* 2. we want the line before the next section/chapter title. */\n\t}\n\n\twhile (1)\n\t{\n\t\tnl = nestingLevelsGetCurrent(nestingLevels);\n\t\te = getEntryOfNestingLevel (nl);\n\t\tif ((nl && (e == NULL)) || (e && e->kindIndex >= kind))\n\t\t{\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine (e, (getInputLineNumber() - d));\n\t\t\tnestingLevelsPop(nestingLevels);\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t}\n\treturn nl;\n}\n\nstatic int makeTargetRstTag(const vString* const name, rstKind kindex)\n{\n\ttagEntryInfo e;\n\n\tinitTagEntry (&e, vStringValue (name), kindex);\n\n\tconst NestingLevel *nl = nestingLevelsGetCurrent(nestingLevels);\n\tif (nl)\n\t\te.extensionFields.scopeIndex = nl->corkIndex;\n\n\treturn makeTagEntry (&e);\n}\n\nstatic void makeSectionRstTag(const vString* const name, const int kind, const MIOPos filepos,\n\t\t       char marker, bool overline)\n{\n\tconst NestingLevel *const nl = getNestingLevel(kind);\n\ttagEntryInfo *parent;\n\n\tint r = CORK_NIL;\n\n\tif (vStringLength (name) > 0)\n\t{\n\t\ttagEntryInfo e;\n\t\tchar m [2] = { [1] = '\\0' };\n\n\t\tinitTagEntry (&e, vStringValue (name), kind);\n\t\tAssert (e.lineNumber > 1);\n\t\t/* we want the line before the '---' underline chars */\n\t\tif (e.lineNumber > 1)\n\t\t\tupdateTagLine (&e, e.lineNumber - 1, filepos);\n\n\t\tparent = getEntryOfNestingLevel (nl);\n\t\tif (parent && (parent->kindIndex < kind))\n\t\t\te.extensionFields.scopeIndex = nl->corkIndex;\n\n\t\tm[0] = marker;\n\t\tattachParserField (&e, RstFields [F_SECTION_MARKER].ftype, m);\n\n\t\tif (overline)\n\t\t\tattachParserField (&e, RstFields [F_SECTION_OVERLINE].ftype, \"\");\n\n\t\tr = makeTagEntry (&e);\n\t}\n\tnestingLevelsPush(nestingLevels, r);\n}\n\n\n/* checks if str is all the same character */\nstatic bool issame(const char *str)\n{\n\tchar first = *str;\n\n\twhile (*str)\n\t{\n\t\tchar c;\n\n\t\tstr++;\n\t\tc = *str;\n\t\tif (c && c != first)\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\n\nstatic int get_kind(char c, bool overline, struct sectionTracker tracker[])\n{\n\tint i;\n\n\tfor (i = 0; i < SECTION_COUNT; i++)\n\t{\n\t\tif (tracker[i].kindchar == c && tracker[i].overline == overline)\n\t\t{\n\t\t\ttracker[i].count++;\n\t\t\treturn i;\n\t\t}\n\n\t\tif (tracker[i].count == 0)\n\t\t{\n\t\t\ttracker[i].count = 1;\n\t\t\ttracker[i].kindchar = c;\n\t\t\ttracker[i].overline = overline;\n\t\t\treturn i;\n\t\t}\n\t}\n\treturn -1;\n}\n\nstatic const unsigned char *is_markup_line_with_char (const unsigned char *line, char reftype)\n{\n\tif ((line [0] == '.') && (line [1] == '.') && (line [2] == ' ')\n\t\t&& (line [3] == reftype))\n\t\treturn line + 4;\n\treturn NULL;\n}\n\nstatic const unsigned char *is_markup_line_with_cstr (const unsigned char *line, char *str, size_t len)\n{\n\tif ((line [0] == '.') && (line [1] == '.') && (line [2] == ' ')\n\t\t&& (strncmp ((char *)line + 3, str, len) == 0))\n\t\treturn line + 3 + len;\n\treturn NULL;\n}\n\nstatic int capture_markup (const unsigned char *target_line, char defaultTerminator, rstKind kindex)\n{\n\tvString *name = vStringNew ();\n\tunsigned char terminator;\n\tint r = CORK_NIL;\n\n\tif (*target_line == '`')\n\t\tterminator = '`';\n\telse if (!isspace (*target_line) && *target_line != '\\0')\n\t{\n\t\t/* \"Simple reference names are single words consisting of\n\t\t * alphanumerics plus isolated (no two adjacent) internal\n\t\t * hyphens, underscores, periods, colons and plus signs; no\n\t\t * whitespace or other characters are allowed.\"\n\t\t * -- http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#reference-names\n\t\t */\n\t\tvStringPut (name, *target_line);\n\t\tterminator = defaultTerminator;\n\t}\n\telse\n\t\tgoto out;\n\n\ttarget_line++;\n\n\n\tbool escaped = false;\n\twhile (*target_line != '\\0')\n\t{\n\t\tif (escaped)\n\t\t{\n\t\t\tvStringPut (name, *target_line);\n\t\t\tescaped = false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (*target_line == '\\\\')\n\t\t\t{\n\t\t\t\tvStringPut (name, *target_line);\n\t\t\t\tescaped = true;\n\t\t\t}\n\t\t\telse if (*target_line == terminator)\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t\tvStringPut (name, *target_line);\n\t\t}\n\t\ttarget_line++;\n\t}\n\n\tif (vStringLength (name) == 0)\n\t\tgoto out;\n\n\tr = makeTargetRstTag (name, kindex);\n\n out:\n\tvStringDelete (name);\n\treturn r;\n}\n\nstatic void overline_clear(struct olineTracker *ol)\n{\n\tol->c = 0;\n\tol->len = 0;\n}\n\nstatic void overline_set(struct olineTracker *ol, char c, size_t len)\n{\n\tol->c = c;\n\tol->len = len;\n}\n\nstatic bool has_overline(struct olineTracker *ol)\n{\n\treturn (ol->c != 0);\n}\n\nstatic void init_codeblock (struct codeblockTracker *codeblock, const char *language,\n\t\t\t\t\t\t\tsize_t blockIndent, unsigned long startLine)\n{\n\tcodeblock->language = eStrdup (language);\n\tcodeblock->blockIndent = blockIndent;\n\tcodeblock->startLine = startLine;\n\tcodeblock->endLine = 0;\n\tcodeblock->endLineLength = 0;\n}\n\nstatic bool is_in_codeblock (struct codeblockTracker *codeblock)\n{\n\treturn (codeblock->language != NULL);\n}\n\nstatic void reset_codeblock (struct codeblockTracker *codeblock)\n{\n\teFree (codeblock->language);\n\tcodeblock->language = NULL;\n}\n\nstatic bool does_codeblock_continue (struct codeblockTracker *codeblock, size_t blockOffset,\n\t\t\t\t\t\t\t\t   unsigned char initChar)\n{\n\tif (blockOffset > codeblock->blockIndent)\n\t\treturn true;\n\n\tif (blockOffset <= codeblock->blockIndent && initChar == '\\0')\n\t\treturn true;\n\n\treturn false;\n}\n\nstatic void update_codeblock (struct codeblockTracker *codeblock, unsigned int endLine, unsigned long endLineLength)\n{\n\tcodeblock->endLine = endLine;\n\tcodeblock->endLineLength = endLineLength;\n}\n\nstatic void submit_codeblock (struct codeblockTracker *codeblock)\n{\n\tif (codeblock->endLine)\n\t\tmakePromise (codeblock->language,\n\t\t\t\t\t codeblock->startLine, 0,\n\t\t\t\t\t codeblock->endLine, codeblock->endLineLength, codeblock->startLine);\n\treset_codeblock (codeblock);\n}\n\nstatic int getFosterEntry(tagEntryInfo *e, int shift)\n{\n\tint r = CORK_NIL;\n\n\twhile (shift-- > 0)\n\t{\n\t\tr = e->extensionFields.scopeIndex;\n\t\tAssert(r != CORK_NIL);\n\t\te = getEntryInCorkQueue(r);\n\t\tAssert(e);\n\t}\n\treturn r;\n}\n\nstatic void shiftKinds(int shift, rstKind baseKind)\n{\n\tsize_t count = countEntryInCorkQueue();\n\thashTable *remapping_table = hashTableNew (count,\n\t\t\t\t\t\t\t\t\t\t\t   hashPtrhash,\n\t\t\t\t\t\t\t\t\t\t\t   hashPtreq, NULL, NULL);\n\thashTableSetValueForUnknownKey(remapping_table, HT_INT_TO_PTR(CORK_NIL), NULL);\n\n\tfor (size_t index = 0; index < count; index++)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue((int)index);\n\t\tif (e && (baseKind <= e->kindIndex && e->kindIndex < SECTION_COUNT))\n\t\t{\n\t\t\te->kindIndex += shift;\n\t\t\tif (e->kindIndex >= SECTION_COUNT)\n\t\t\t{\n\t\t\t\tmarkTagAsPlaceholder(e, true);\n\n\t\t\t\tint foster_parent = getFosterEntry(e, shift);\n\t\t\t\tAssert (foster_parent != CORK_NIL);\n\t\t\t\thashTablePutItem(remapping_table, HT_INT_TO_PTR(index),\n\t\t\t\t\t\t\t\t HT_INT_TO_PTR(foster_parent));\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (size_t index = 0; index < count; index++)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue((int)index);\n\t\tif (e && e->extensionFields.scopeIndex != CORK_NIL)\n\t\t{\n\t\t\tvoid *remapping_to = hashTableGetItem (remapping_table,\n\t\t\t\t\t\t\t\t\t\t\t\t   HT_INT_TO_PTR(e->extensionFields.scopeIndex));\n\t\t\tif (HT_PTR_TO_INT(remapping_to) != CORK_NIL)\n\t\t\t\te->extensionFields.scopeIndex = HT_PTR_TO_INT(remapping_to);\n\t\t}\n\t}\n\thashTableDelete(remapping_table);\n}\n\nstatic void adjustSectionKinds(struct sectionTracker section_tracker[])\n{\n\tif (section_tracker[K_TITLE].count > 1)\n\t{\n\t\tshiftKinds(2, K_TITLE);\n\t\treturn;\n\t}\n\n\tif (section_tracker[K_TITLE].count == 1\n\t\t&& section_tracker[K_SUBTITLE].count > 1)\n\t{\n\t\tshiftKinds(1, K_SUBTITLE);\n\t\treturn;\n\t}\n}\n\nstatic void inlineTagScope(tagEntryInfo *e, int parent_index)\n{\n\ttagEntryInfo *parent = getEntryInCorkQueue (parent_index);\n\tif (parent)\n\t{\n\t\te->extensionFields.scopeKindIndex = parent->kindIndex;\n\t\te->extensionFields.scopeName = eStrdup(parent->name);\n\t\te->extensionFields.scopeIndex = CORK_NIL;\n\t}\n}\n\nstatic void inlineScopes (void)\n{\n\t/* TODO\n\t   Following code makes the scope information full qualified form.\n\t   Do users want the full qualified form?\n\t   --- ./Units/rst.simple.d/expected.tags\t2015-12-18 01:32:35.574255617 +0900\n\t   +++ /home/yamato/var/ctags-github/Units/rst.simple.d/FILTERED.tmp\t2016-05-05 03:05:38.165604756 +0900\n\t   @@ -5,2 +5,2 @@\n\t   -Subsection 1.1.1\tinput.rst\t/^Subsection 1.1.1$/;\"\tS\tsection:Section 1.1\n\t   -Subsubsection 1.1.1.1\tinput.rst\t/^Subsubsection 1.1.1.1$/;\"\tt\tsubsection:Subsection 1.1.1\n\t   +Subsection 1.1.1\tinput.rst\t/^Subsection 1.1.1$/;\"\tS\tsection:Chapter 1.Section 1.1\n\t   +Subsubsection 1.1.1.1\tinput.rst\t/^Subsubsection 1.1.1.1$/;\"\tt\tsubsection:Chapter 1.Section 1.1.Subsection 1.1.1\n\t*/\n\tsize_t count = countEntryInCorkQueue();\n\tfor (size_t index = 0; index < count; index++)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue((int)index);\n\n\t\tif (e && e->extensionFields.scopeIndex != CORK_NIL)\n\t\t\tinlineTagScope(e, e->extensionFields.scopeIndex);\n\t}\n}\n\nstatic void findRstTags (void)\n{\n\tvString *name = vStringNew ();\n\tMIOPos filepos;\n\tconst unsigned char *line;\n\tconst unsigned char *markup_line;\n\tstruct sectionTracker section_tracker[SECTION_COUNT];\n\tstruct olineTracker overline;\n\tstruct codeblockTracker codeblock = { .language = NULL };\n\tconst bool run_guest = isXtagEnabled (XTAG_GUEST);\n\n\tmemset(&filepos, 0, sizeof(filepos));\n\tmemset(section_tracker, 0, sizeof section_tracker);\n\toverline_clear(&overline);\n\tnestingLevels = nestingLevelsNew(0);\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char *line_trimmed = line;\n\t\twhile (isspace(*line_trimmed))\n\t\t\t   line_trimmed++;\n\n\t\tif (run_guest && is_in_codeblock (&codeblock))\n\t\t{\n\t\t\tif (does_codeblock_continue (&codeblock, (line_trimmed - line), *line_trimmed))\n\t\t\t{\n\t\t\t\tupdate_codeblock(&codeblock, getInputLineNumber(), strlen((const char *)line));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse\n\t\t\t\tsubmit_codeblock(&codeblock);\n\t\t}\n\n\t\tif ((markup_line = is_markup_line_with_char (line_trimmed, '_')) != NULL)\n\t\t{\n\t\t\toverline_clear(&overline);\n\t\t\t/* Handle .. _target:\n\t\t\t * http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#hyperlink-targets\n\t\t\t */\n\t\t\tif (capture_markup (markup_line, ':', K_TARGET) != CORK_NIL)\n\t\t\t{\n\t\t\t\tvStringClear (name);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\telse if ((markup_line = is_markup_line_with_char (line_trimmed, '[')) != NULL)\n\t\t{\n\t\t\toverline_clear(&overline);\n\t\t\t/* Handle .. [citation]\n\t\t\t * https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#citations\n\t\t\t */\n\t\t\tif (capture_markup (markup_line, ']', K_CITATION) != CORK_NIL)\n\t\t\t{\n\t\t\t\tvStringClear (name);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\telse if ((markup_line = is_markup_line_with_char (line_trimmed, '|')) != NULL)\n\t\t{\n\t\t\toverline_clear(&overline);\n\t\t\t/* Hanle .. |substitute definition|\n\t\t\t * https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#substitution-definitions\n\t\t\t */\n\t\t\tif (capture_markup (markup_line, '|', K_SUBSTDEF) != CORK_NIL)\n\t\t\t{\n\t\t\t\tvStringClear (name);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\telse if (run_guest\n\t\t\t\t && (markup_line = is_markup_line_with_cstr (line_trimmed, \"code-block::\", 12)) != NULL)\n\t\t{\n\t\t\tif (is_in_codeblock (&codeblock))\n\t\t\t\treset_codeblock (&codeblock);\n\n\t\t\twhile (isspace(*markup_line))\n\t\t\t\tmarkup_line++;\n\n\t\t\tif (*markup_line)\n\t\t\t{\n\t\t\t\tinit_codeblock (&codeblock, (const char *)markup_line, line_trimmed - line,\n\t\t\t\t\t\t\t\tgetInputLineNumber() + 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tint line_len = strlen((const char*) line);\n\t\tint name_len_bytes = vStringLength(name);\n\t\t/* FIXME: this isn't right, actually we need the real display width,\n\t\t * taking into account double-width characters and stuff like that.\n\t\t * But duh. */\n\t\tint name_len = utf8_strlen(vStringValue(name), name_len_bytes);\n\n\t\t/* if the name doesn't look like UTF-8, assume one-byte charset */\n\t\tif (name_len < 0)\n\t\t\tname_len = name_len_bytes;\n\n\t\t/* overline may come after an empty line (or begging of file). */\n\t\tif (name_len_bytes == 0 && line_len > 0 &&\n\t\t\tispunct(line[0]) && issame((const char*) line))\n\t\t{\n\t\t\toverline_set(&overline, *line, line_len);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* underlines must be the same length or more */\n\t\tif (line_len >= name_len && name_len > 0 &&\n\t\t\tispunct(line[0]) && issame((const char*) line))\n\t\t{\n\t\t\tchar c = line[0];\n\t\t\tbool o = (overline.c == c && overline.len == line_len);\n\t\t\tint kind = get_kind(c, o, section_tracker);\n\n\t\t\toverline_clear(&overline);\n\n\t\t\tif (kind >= 0)\n\t\t\t{\n\t\t\t\tmakeSectionRstTag(name, kind, filepos, c, o);\n\t\t\t\tvStringClear(name);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (has_overline(&overline))\n\t\t{\n\t\t\tif (name_len > 0)\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * Though we saw an overline and a section title text,\n\t\t\t\t * we cannot find the associated underline.\n\t\t\t\t * In that case, we must reset the state of tracking\n\t\t\t\t * overline.\n\t\t\t\t */\n\t\t\t\toverline_clear(&overline);\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * We san an overline. The line is the candidate\n\t\t\t * of a section title text. Skip the prefixed whitespaces.\n\t\t\t */\n\t\t\twhile (isspace(*line))\n\t\t\t\tline++;\n\t\t}\n\n\t\tvStringClear (name);\n\t\tif (!isspace(*line))\n\t\t{\n\t\t\tvStringCatS(name, (const char*)line);\n\t\t\tvStringStripTrailing (name);\n\t\t\tfilepos = getInputFilePosition();\n\t\t}\n\t}\n\n\tif (run_guest && is_in_codeblock (&codeblock))\n\t\tsubmit_codeblock(&codeblock);\n\n\t/* Force popping all nesting levels */\n\tgetNestingLevel (K_EOF);\n\tvStringDelete (name);\n\tnestingLevelsFree(nestingLevels);\n\n\tadjustSectionKinds(section_tracker);\n\tinlineScopes();\n\n\tif (run_guest && codeblock.language)\n\t\teFree (codeblock.language);\n}\n\nextern parserDefinition* RstParser (void)\n{\n\tstatic const char *const extensions [] = { \"rest\", \"reST\", \"rst\", NULL };\n\tparserDefinition* const def = parserNew (\"ReStructuredText\");\n\tstatic const char *const aliases[] = {\n\t\t\"rst\",\t\t\t\t\t/* The name of emacs's mode */\n\t\tNULL\n\t};\n\n\tdef->kindTable = RstKinds;\n\tdef->kindCount = ARRAY_SIZE (RstKinds);\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->parser = findRstTags;\n\n\tdef->fieldTable = RstFields;\n\tdef->fieldCount = ARRAY_SIZE (RstFields);\n\n\tdef->useCork = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/ruby.c",
    "content": "/*\n*   Copyright (c) 2000-2001, Thaddeus Covert <sahuagin@mediaone.net>\n*   Copyright (c) 2002 Matthias Veit <matthias_veit@yahoo.de>\n*   Copyright (c) 2004 Elliott Hughes <enh@acm.org>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Ruby language\n*   files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <ctype.h>\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"promise.h\"\n#include \"nestlevel.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"strlist.h\"\n#include \"subparser.h\"\n#include \"vstring.h\"\n\n#include \"x-ruby.h\"\n\n/*\n*   DATA DECLARATIONS\n*/\n#define K_UNDEFINED -1\n#define K_CLASS     RUBY_CLASS_KIND\n#define K_METHOD    RUBY_METHOD_KIND\n#define K_MODULE    RUBY_MODULE_KIND\n#define K_SINGLETON RUBY_SINGLETON_KIND\n#define K_CONST     RUBY_CONST_KIND\n#define K_ACCESSOR  RUBY_ACCESSOR_KIND\n#define K_ALIAS     RUBY_ALIAS_KIND\n#define K_LIBRARY   RUBY_LIBRARY_KIND\n\ntypedef enum {\n\tRUBY_LIBRARY_REQUIRED,\n\tRUBY_LIBRARY_REQUIRED_REL,\n\tRUBY_LIBRARY_LOADED,\n} rubyLibraryRole;\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic roleDefinition RubyLibraryRoles [] = {\n\t{ true, \"required\",  \"loaded by \\\"require\\\" method\" },\n\t{ true, \"requiredRel\", \"loaded by \\\"require_relative\\\" method\" },\n\t{ true, \"loaded\", \"loaded by \\\"load\\\" method\" },\n};\n\nstatic kindDefinition RubyKinds [] = {\n\t{ true, 'c', \"class\",  \"classes\" },\n\t{ true, 'f', \"method\", \"methods\" },\n\t{ true, 'm', \"module\", \"modules\" },\n\t{ true, 'S', \"singletonMethod\", \"singleton methods\" },\n\t{ true, 'C', \"constant\", \"constants\" },\n\t{ true, 'A', \"accessor\", \"accessors\" },\n\t{ true, 'a', \"alias\",    \"aliases\" },\n\t{ true, 'L', \"library\",  \"libraries\",\n\t  .referenceOnly = true, ATTACH_ROLES(RubyLibraryRoles) },\n};\n\ntypedef enum {\n\tF_MIXIN,\n} rubyField;\n\nstatic fieldDefinition RubyFields[] = {\n\t{ .name = \"mixin\",\n\t  .description = \"how the class or module is mixed in (mixin:HOW:MODULE)\",\n\t  .enabled = true },\n};\n\nstruct blockData {\n\tstringList *mixin;\n\trubySubparser *subparser;\n\tint subparserCorkIndex;\n};\n\nstatic NestingLevels* nesting = NULL;\n\n#define SCOPE_SEPARATOR '.'\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic void enterUnnamedScope (void);\n\n/*\n* Attempts to advance 's' past 'literal'.\n* Returns true if it did, false (and leaves 's' where\n* it was) otherwise.\n*/\nstatic bool canMatchWithEnd (const unsigned char** s, const unsigned char *end,\n\t\t\t\t\t\t\t const char* literal, bool (*end_check) (int))\n{\n\tconst int literal_length = strlen (literal);\n\tconst int s_length = end - *s;\n\n\tif (s_length < literal_length)\n\t\treturn false;\n\n\tconst unsigned char next_char = *(*s + literal_length);\n\tif (strncmp ((const char*) *s, literal, literal_length) != 0)\n\t{\n\t\treturn false;\n\t}\n\t/* Additionally check that we're at the end of a token. */\n\tif (! end_check (next_char))\n\t{\n\t\treturn false;\n\t}\n\t*s += literal_length;\n\treturn true;\n}\n\nstatic bool isIdentChar (int c)\n{\n\treturn (isalnum (c) || c == '_');\n}\n\nstatic bool notIdentCharButColon (int c)\n{\n\treturn ! (isIdentChar (c) || c == ':');\n}\n\nstatic bool isOperatorChar (int c)\n{\n\treturn (c == '[' || c == ']' ||\n\t\t\tc == '=' || c == '!' || c == '~' ||\n\t\t\tc == '+' || c == '-' ||\n\t\t\tc == '@' || c == '*' || c == '/' || c == '%' ||\n\t\t\tc == '<' || c == '>' ||\n\t\t\tc == '&' || c == '^' || c == '|');\n}\n\nstatic bool notOperatorChar (int c)\n{\n\treturn ! isOperatorChar (c);\n}\n\nstatic bool isSigilChar (int c)\n{\n\treturn (c == '@' || c == '$');\n}\n\nstatic bool isWhitespace (int c)\n{\n\treturn c == 0 || isspace (c);\n}\n\n/*\n * Advance 's' while the passed predicate is true. Returns true if\n * advanced by at least one position.\n */\nstatic bool advanceWhileFull (const unsigned char** s, bool (*predicate) (int), vString *repr)\n{\n\tconst unsigned char* original_pos = *s;\n\n\twhile (**s != '\\0')\n\t{\n\t\tif (! predicate (**s))\n\t\t{\n\t\t\treturn *s != original_pos;\n\t\t}\n\n\t\tif (repr)\n\t\t\tvStringPut (repr, **s);\n\t\t(*s)++;\n\t}\n\n\treturn *s != original_pos;\n}\n\nstatic bool advanceWhile (const unsigned char** s, bool (*predicate) (int))\n{\n\treturn advanceWhileFull (s, predicate, NULL);\n}\n\nextern bool rubyCanMatchKeyword (const unsigned char** s, const char* literal)\n{\n\t/* Using notIdentCharButColon() here.\n\t *\n\t * A hash can be defined like {for: nil, foo: 0}.\n\t *\"for\" in the above example is not a keyword.\n\t */\n\tsize_t s_length = strlen ((const char *)*s);\n\treturn canMatchWithEnd (s, *s + s_length, literal, notIdentCharButColon);\n}\n\nextern bool canMatchKeyword (const unsigned char** s, const unsigned char *end, const char* literal)\n{\n\t/* Using notIdentCharButColon() here.\n\t *\n\t * A hash can be defined like {for: nil, foo: 0}.\n\t *\"for\" in the above example is not a keyword.\n\t */\n\treturn canMatchWithEnd (s, end, literal, notIdentCharButColon);\n}\n\n/*\n * Extends canMatch. Works similarly, but allows assignment to precede\n * the keyword, as block assignment is a common Ruby idiom.\n */\n#define vStringTruncateMaybe(VS,LEN) if (VS) vStringTruncate ((VS), (LEN))\n\nstatic bool canMatchKeywordWithAssignFull (const unsigned char** s, const unsigned char *end,\n\t\t\t\t\t\t\t\t\t\t   const char* literal, vString *assignee)\n{\n\tconst unsigned char* original_pos = *s;\n\tsize_t original_len;\n\tif (assignee)\n\t\toriginal_len = vStringLength  (assignee);\n\n\tif (canMatchKeyword (s, end, literal))\n\t{\n\t\treturn true;\n\t}\n\n\tadvanceWhile (s, isSigilChar);\n\n\tif (! advanceWhileFull (s, isIdentChar, assignee))\n\t{\n\t\t*s = original_pos;\n\t\tvStringTruncateMaybe (assignee, original_len);\n\t\treturn false;\n\t}\n\n\tadvanceWhile (s, isWhitespace);\n\n\tif (! (advanceWhile (s, isOperatorChar) && *(*s - 1) == '='))\n\t{\n\t\t*s = original_pos;\n\t\tvStringTruncateMaybe (assignee, original_len);\n\t\treturn false;\n\t}\n\n\tadvanceWhile (s, isWhitespace);\n\n\tif (canMatchKeyword (s, end, literal))\n\t{\n\t\treturn true;\n\t}\n\n\t*s = original_pos;\n\tvStringTruncateMaybe (assignee, original_len);\n\treturn false;\n}\n\nstatic bool canMatchKeywordWithAssign (const unsigned char** s, const unsigned char *end,\n\t\t\t\t\t\t\t\t\t   const char* literal)\n{\n\treturn canMatchKeywordWithAssignFull (s, end, literal, NULL);\n}\n\nextern bool rubyCanMatchKeywordWithAssign (const unsigned char** s, const char* literal)\n{\n\tsize_t s_length = strlen ((const char *)*s);\n\treturn canMatchKeywordWithAssign (s, *s + s_length, literal);\n}\n\n/*\n* Attempts to advance 'cp' past a Ruby operator method name. Returns\n* true if successful (and copies the name into 'name'), false otherwise.\n*/\nstatic bool parseRubyOperator (vString* name, const unsigned char** cp,\n\t\t\t\t\t\t\t   const unsigned char *end)\n{\n\tstatic const char* RUBY_OPERATORS[] = {\n\t\t\"[]\", \"[]=\",\n\t\t\t\"**\",\n\t\t\t\"!\", \"~\", \"+@\", \"-@\",\n\t\t\t\"*\", \"/\", \"%\",\n\t\t\t\"+\", \"-\",\n\t\t\t\">>\", \"<<\",\n\t\t\t\"&\",\n\t\t\t\"^\", \"|\",\n\t\t\t\"<=\", \"<\", \">\", \">=\",\n\t\t\t\"<=>\", \"==\", \"===\", \"!=\", \"=~\", \"!~\",\n\t\t\t\"`\",\n\t\t\tNULL\n\t};\n\tint i;\n\tfor (i = 0; RUBY_OPERATORS[i] != NULL; ++i)\n\t{\n\t\tif (canMatchWithEnd (cp, end, RUBY_OPERATORS[i], notOperatorChar))\n\t\t{\n\t\t\tvStringCatS (name, RUBY_OPERATORS[i]);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/*\n* Emits a tag for the given 'name' of kind 'kind' at the current nesting.\n*/\nstatic int emitRubyTagFull (vString* name, rubyKind kind, bool pushLevel, bool clearName)\n{\n\ttagEntryInfo tag;\n\tvString* scope;\n\ttagEntryInfo *parent;\n\trubyKind parent_kind = K_UNDEFINED;\n\tNestingLevel *lvl;\n\tconst char *unqualified_name;\n\tconst char *qualified_name;\n\tint r;\n\tbool anonymous = false;\n\n\tif (!name)\n\t{\n\t\tname = anonGenerateNew (\"__anon\", kind == K_UNDEFINED? K_CLASS: kind);\n\t\tanonymous = true;\n\t}\n\n\tif (!RubyKinds[kind].enabled) {\n\t\treturn CORK_NIL;\n\t}\n\n\tscope = nestingLevelsToScopeNew (nesting, SCOPE_SEPARATOR);\n\tlvl = nestingLevelsGetCurrent (nesting);\n\tparent = getEntryOfNestingLevel (lvl);\n\tif (parent)\n\t\tparent_kind =  parent->kindIndex;\n\n\tqualified_name = vStringValue (name);\n\tunqualified_name = strrchr (qualified_name, SCOPE_SEPARATOR);\n\tif (unqualified_name && unqualified_name[1])\n\t{\n\t\tif (unqualified_name > qualified_name)\n\t\t{\n\t\t\tvStringPutUnlessEmpty (scope, SCOPE_SEPARATOR);\n\t\t\tvStringNCatS (scope, qualified_name,\n\t\t\t\t\t\t  unqualified_name - qualified_name);\n\t\t\t/* assume module parent type for a lack of a better option */\n\t\t\tparent_kind = K_MODULE;\n\t\t}\n\t\tunqualified_name++;\n\t}\n\telse\n\t\tunqualified_name = qualified_name;\n\n\tinitTagEntry (&tag, unqualified_name, kind);\n\n\t/* Don't fill the scope field for a tag entry representing\n\t * a global variable. */\n\tif (unqualified_name[0] != '$'\n\t\t&& vStringLength (scope) > 0) {\n\t\tAssert (0 <= parent_kind &&\n\t\t\t\t(size_t) parent_kind < (ARRAY_SIZE (RubyKinds)));\n\n\t\ttag.extensionFields.scopeKindIndex = parent_kind;\n\t\ttag.extensionFields.scopeName = vStringValue (scope);\n\t}\n\n\tif (anonymous)\n\t\tmarkTagExtraBit (&tag, XTAG_ANONYMOUS);\n\n\tr = makeTagEntry (&tag);\n\n\tif (pushLevel)\n\t\tnestingLevelsPush (nesting, r);\n\n\tif (clearName)\n\t\tvStringClear (name);\n\n\tif (anonymous)\n\t\tvStringDelete (name);\n\n\tvStringDelete (scope);\n\n\treturn r;\n}\n\nstatic int emitRubyTag (vString* name, rubyKind kind)\n{\n\treturn emitRubyTagFull (name, kind, kind != K_CONST, true);\n}\n\n/* Tests whether 'ch' is a character in 'list'. */\nstatic bool charIsIn (char ch, const char* list)\n{\n\treturn (strchr (list, ch) != NULL);\n}\n\n/* Advances 'cp' over leading whitespace. */\n#define skipWhitespace rubySkipWhitespace\nextern bool rubySkipWhitespace (const unsigned char** cp)\n{\n\tbool r = false;\n\twhile (isspace (**cp))\n\t{\n\t\t++*cp;\n\t\tr = true;\n\t}\n\treturn r;\n}\n\n/* TODO: handle double quote if boundary == '\"' */\nstatic void parseString (const unsigned char** cp, unsigned char boundary, vString* vstr)\n{\n\twhile (**cp != 0 && **cp != boundary)\n\t{\n\t\tif (vstr)\n\t\t\tvStringPut (vstr, **cp);\n\t\t++*cp;\n\t}\n\n\t/* skip the last found '\"' */\n\tif (**cp == boundary)\n\t\t++*cp;\n}\n\nextern bool rubyParseString (const unsigned char** cp, unsigned char boundary, vString* vstr)\n{\n\tconst unsigned char *p = *cp;\n\tparseString (cp, boundary, vstr);\n\treturn (p != *cp);\n}\n\nstatic bool rubyParsePercent_q (const unsigned char** cp, vString* vstr)\n{\n\tconst unsigned char *p = *cp;\n\tbool recursive;\n\tunsigned char boundary[2];\n\n\tif (*p == '\\0' || isalnum (*p))\n\t\treturn false;\n\n\tboundary[0] = *p;\n\tboundary[1] = *p;\n\trecursive = false;\n\tswitch (*p)\n\t{\n\tcase '{':\n\t\tboundary[1] = '}';\n\t\trecursive = true;\n\t\tbreak;\n\tcase '[':\n\t\tboundary[1] = ']';\n\t\trecursive = true;\n\t\tbreak;\n\tcase '(':\n\t\tboundary[1] = ')';\n\t\trecursive = true;\n\t\tbreak;\n\tcase '<':\n\t\tboundary[1] = '>';\n\t\trecursive = true;\n\t\tbreak;\n\t}\n\tp++;\n\n\tunsigned int depth = 1;\n\twhile (*p != '\\0')\n\t{\n\t\tif (*p == boundary[1])\n\t\t{\n\t\t\tdepth--;\n\t\t\tif (depth == 0)\n\t\t\t{\n\t\t\t\t*cp = p;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\telse if (recursive && boundary[0] == *p)\n\t\t\tdepth++;\n\t\tvStringPut (vstr, *p);\n\t\tp++;\n\t}\n\treturn false;\n}\n\nextern bool rubyParsePercentString (const unsigned char** cp, vString* vstr)\n{\n\tconst unsigned char *p = *cp;\n\n\tswitch (*p)\n\t{\n\tcase 'q':\n\t\t++p;\n\t\tif (rubyParsePercent_q(&p, vstr))\n\t\t{\n\t\t\t*cp = p;\n\t\t\treturn true;\n\t\t}\n\t\tbreak;\n\t}\n\treturn false;\n}\n\n/* If the current scope is A.B, and the name is B.C, B is overlapped.\n * In that case, the function returns true. Else false.\n */\nstatic bool doesNameOverlapCurrentScope (vString *name)\n{\n\tbool r = false;\n\tvString *scope = nestingLevelsToScopeNew (nesting, SCOPE_SEPARATOR);\n\n\tconst char *scope_cstr = vStringValue(scope);\n\tconst char *scope_last = strrchr (scope_cstr, SCOPE_SEPARATOR);\n\tsize_t scope_last_slen;\n\n\tif (scope_last)\n\t{\n\t\tscope_last++;\n\t\tscope_last_slen = strlen (scope_last);\n\t}\n\telse\n\t{\n\t\tscope_last = scope_cstr;\n\t\tscope_last_slen = vStringLength (scope);\n\t}\n\n\tif (strncmp (vStringValue (name), scope_last, scope_last_slen) == 0\n\t\t&& *(vStringValue (name) + scope_last_slen) == '.')\n\t\tr = true;\n\n\tvStringDelete (scope);\n\n\treturn r;\n}\n\n/*\n* Copies the characters forming an identifier from *cp into\n* name, leaving *cp pointing to the character after the identifier.\n*/\nstatic rubyKind parseIdentifier (\n\tconst unsigned char** cp, const unsigned char *end,\n\tvString* name, rubyKind kind)\n{\n\t/* Method names are slightly different to class and variable names.\n\t * A method name may optionally end with a question mark, exclamation\n\t * point or equals sign. These are all part of the name.\n\t * A method name may also contain a period if it's a singleton method.\n\t */\n\tbool had_sep = false;\n\tconst char* also_ok;\n\tif (kind == K_METHOD)\n\t{\n\t\talso_ok = \".?!=\";\n\t}\n\telse if (kind == K_SINGLETON)\n\t{\n\t\talso_ok = \"?!=\";\n\t}\n\telse\n\t{\n\t\talso_ok = \"\";\n\t}\n\n\tskipWhitespace (cp);\n\n\t/* Check for an anonymous (singleton) class such as \"class << HTTP\". */\n\tif (kind == K_CLASS && **cp == '<' && *(*cp + 1) == '<')\n\t{\n\t\treturn K_UNDEFINED;\n\t}\n\n\t/* Check for operators such as \"def []=(key, val)\". */\n\tif (kind == K_METHOD || kind == K_SINGLETON)\n\t{\n\t\tif (parseRubyOperator (name, cp, end))\n\t\t{\n\t\t\treturn kind;\n\t\t}\n\t}\n\n\t/* Copy the identifier into 'name'. */\n\tif (**cp == ':')\n\t{\n\t\tif (*((*cp) + 1) == '\"' || *((*cp) + 1) == '\\'')\n\t\t{\n\t\t\t/* The symbol is defined with string literal like:\n\t\t\t   ----\n\t\t\t   :\"[]\"\n\t\t\t   :\"[]=\"\n\t\t\t   ----\n\t\t\t*/\n\t\t\tunsigned char b = *(++*cp);\n\t\t\t++*cp;\n\t\t\tparseString (cp, b, name);\n\t\t\treturn kind;\n\t\t}\n\t\t/* May be symbol like :name. Skip the first character. */\n\t\t++*cp;\n\t}\n\n\twhile (**cp != 0 && (**cp == ':' || isIdentChar (**cp) || charIsIn (**cp, also_ok)))\n\t{\n\t\tchar last_char = **cp;\n\n\t\tif (last_char == ':')\n\t\t\thad_sep = true;\n\t\telse\n\t\t{\n\t\t\tif (had_sep)\n\t\t\t{\n\t\t\t\tvStringPut (name, SCOPE_SEPARATOR);\n\t\t\t\thad_sep = false;\n\t\t\t}\n\t\t\tvStringPut (name, last_char);\n\t\t}\n\t\t++*cp;\n\n\t\tif (kind == K_METHOD)\n\t\t{\n\t\t\t/* Recognize singleton methods. */\n\t\t\tif (last_char == '.')\n\t\t\t{\n\t\t\t\tif (strcmp (vStringValue (name), \"self.\") == 0\n\t\t\t\t\t|| doesNameOverlapCurrentScope (name))\n\t\t\t\t\tvStringClear (name);\n\t\t\t\treturn parseIdentifier (cp, end, name, K_SINGLETON);\n\t\t\t}\n\t\t}\n\n\t\tif (kind == K_METHOD || kind == K_SINGLETON)\n\t\t{\n\t\t\t/* Recognize characters which mark the end of a method name. */\n\t\t\tif (charIsIn (last_char, \"?!=\"))\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn kind;\n}\n\nextern bool rubyParseMethodName (const unsigned char **cp, vString* vstr)\n{\n\tsize_t cp_length = strlen ((const char *)*cp);\n\treturn (parseIdentifier (cp, *cp + cp_length, vstr, K_METHOD) == K_METHOD);\n}\n\nextern bool rubyParseModuleName (const unsigned char **cp, vString* vstr)\n{\n\tsize_t cp_length = strlen ((const char *)*cp);\n\treturn (parseIdentifier (cp, *cp + cp_length, vstr, K_MODULE) == K_MODULE);\n}\n\nstatic void parseSignature (const unsigned char** cp, vString* vstr)\n{\n\tint depth = 1;\n\n\twhile (1)\n\t{\n\t\t/* FIXME:\n\t\t * - handle string literals including ( or ), and\n\t\t * - skip comments.\n\t\t */\n\t\twhile (! (depth == 0 || **cp == '\\0'))\n\t\t{\n\t\t\tif (**cp == '(' || **cp == ')')\n\t\t\t{\n\t\t\t\tdepth += (**cp == '(')? 1: -1;\n\t\t\t\tvStringPut (vstr, **cp);\n\t\t\t}\n\t\t\telse if (**cp == '#')\n\t\t\t{\n\t\t\t\t++*cp;\n\t\t\t\twhile (**cp != '\\0')\n\t\t\t\t\t++*cp;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (**cp == '\\'' || **cp == '\"')\n\t\t\t{\n\t\t\t\tunsigned char b = **cp;\n\t\t\t\tvStringPut (vstr, b);\n\t\t\t\t++*cp;\n\t\t\t\tparseString (cp, b, vstr);\n\t\t\t\tvStringPut (vstr, b);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (isspace ((unsigned char) vStringLast (vstr)))\n\t\t\t{\n\t\t\t\tif (! (isspace (**cp)))\n\t\t\t\t{\n\t\t\t\t\tif (**cp == ',')\n\t\t\t\t\t\tvStringChop (vstr);\n\t\t\t\t\tvStringPut (vstr, **cp);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tvStringPut (vstr, **cp);\n\t\t\t++*cp;\n\t\t}\n\t\tif (depth == 0)\n\t\t\treturn;\n\n\t\tconst unsigned char *line = readLineFromInputFile ();\n\t\tif (line == NULL)\n\t\t\treturn;\n\t\telse\n\t\t\t*cp = line;\n\t}\n}\n\nstatic int readAndEmitTagFull (const unsigned char** cp, const unsigned char *end,\n\t\t\t\t\t\t\t   rubyKind expected_kind,\n\t\t\t\t\t\t\t   bool pushLevel, bool clearName)\n{\n\tint r = CORK_NIL;\n\tif (isspace (**cp))\n\t{\n\t\tvString *name = vStringNew ();\n\t\trubyKind actual_kind = parseIdentifier (cp, end, name, expected_kind);\n\n\t\tif (actual_kind == K_UNDEFINED || vStringLength (name) == 0)\n\t\t{\n\t\t\t/*\n\t\t\t* What kind of tags should we create for code like this?\n\t\t\t*\n\t\t\t*    %w(self.clfloor clfloor).each do |name|\n\t\t\t*        module_eval <<-\"end;\"\n\t\t\t*            def #{name}(x, y=1)\n\t\t\t*                q, r = x.divmod(y)\n\t\t\t*                q = q.to_i\n\t\t\t*                return q, r\n\t\t\t*            end\n\t\t\t*        end;\n\t\t\t*    end\n\t\t\t*\n\t\t\t* Or this?\n\t\t\t*\n\t\t\t*    class << HTTP\n\t\t\t*\n\t\t\t* For now, we don't create any.\n\t\t\t*/\n\t\t\tenterUnnamedScope ();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tr = emitRubyTagFull (name, actual_kind, pushLevel, clearName);\n\t\t}\n\t\tvStringDelete (name);\n\t}\n\treturn r;\n}\n\nstatic int readAndEmitTag (const unsigned char** cp, const unsigned char *end, rubyKind expected_kind)\n{\n\treturn readAndEmitTagFull (cp, end, expected_kind, expected_kind != K_CONST, true);\n}\n\nstatic void readAndStoreMixinSpec (const unsigned char** cp, const unsigned char *end, const char *how_mixin)\n{\n\n\tNestingLevel *nl = NULL;\n\ttagEntryInfo *e = NULL;\n\tint ownerLevel = 0;\n\n\tfor (ownerLevel = 0; ownerLevel < nesting->n; ownerLevel++)\n\t{\n\t\tnl = nestingLevelsGetNthParent (nesting, ownerLevel);\n\t\te = nl? getEntryOfNestingLevel (nl): NULL;\n\n\t\t/* Ignore \"if\", \"unless\", \"while\" ... */\n\t\tif ((nl && (nl->corkIndex == CORK_NIL)) || (e && e->placeholder))\n\t\t\tcontinue;\n\t\tbreak;\n\t}\n\n\tif (!e)\n\t\treturn;\n\n\tif (e->kindIndex == K_SINGLETON)\n\t{\n\t\tnl = nestingLevelsGetNthParent (nesting,\n\t\t\t\t\t\t\t\t\t\townerLevel + 1);\n\t\tif (nl == NULL)\n\t\t\treturn;\n\t\te = getEntryOfNestingLevel (nl);\n\t}\n\n\tif (!e)\n\t\treturn;\n\n\tif (! (e->kindIndex == K_CLASS || e->kindIndex == K_MODULE))\n\t\treturn;\n\n\tif (isspace (**cp) || (**cp == '('))\n\t{\n\t\tif (isspace (**cp))\n\t\t\tskipWhitespace (cp);\n\t\tif (**cp == '(')\n\t\t\t++*cp;\n\n\t\tvString *spec = vStringNewInit (how_mixin);\n\t\tvStringPut(spec, ':');\n\n\t\tsize_t len = vStringLength (spec);\n\t\tparseIdentifier (cp, end, spec, K_MODULE);\n\t\tif (len == vStringLength (spec))\n\t\t{\n\t\t\tvStringDelete (spec);\n\t\t\treturn;\n\t\t}\n\n\t\tstruct blockData *bdata =  nestingLevelGetUserData (nl);\n\t\tif (bdata->mixin == NULL)\n\t\t\tbdata->mixin = stringListNew ();\n\t\tstringListAdd (bdata->mixin, spec);\n\t}\n}\n\nstatic void enterUnnamedScope (void)\n{\n\tint r = CORK_NIL;\n\tNestingLevel *parent = nestingLevelsGetCurrent (nesting);\n\ttagEntryInfo *e_parent = getEntryOfNestingLevel (parent);\n\n\tif (e_parent)\n\t{\n\t\ttagEntryInfo e;\n\t\tinitTagEntry (&e, \"\", e_parent->kindIndex);\n\t\tmarkTagAsPlaceholder(&e, true);\n\t\tr = makeTagEntry (&e);\n\t}\n\tnestingLevelsPush (nesting, r);\n}\n\nstatic void parasiteToScope (rubySubparser *subparser, int subparserCorkIndex)\n{\n\tNestingLevel *nl = nestingLevelsGetCurrent (nesting);\n\tstruct blockData *bdata =  nestingLevelGetUserData (nl);\n\tbdata->subparser = subparser;\n\tbdata->subparserCorkIndex = subparserCorkIndex;\n\n\tif (subparser->enterBlockNotify)\n\t\tsubparser->enterBlockNotify (subparser, subparserCorkIndex);\n}\n\nstatic void attachMixinField (int corkIndex, stringList *mixinSpec)\n{\n\tvString *mixinField = stringListItem (mixinSpec, 0);\n\tfor (unsigned int i = 1; i < stringListCount (mixinSpec); i++)\n\t{\n\t\tvStringPut (mixinField, ',');\n\t\tvStringCat (mixinField, stringListItem (mixinSpec, i));\n\t}\n\n\tattachParserFieldToCorkEntry (corkIndex, RubyFields [F_MIXIN].ftype,\n\t\t\t\t\t\t\t\t  vStringValue (mixinField));\n}\n\nstatic void deleteBlockData (NestingLevel *nl, void *data CTAGS_ATTR_UNUSED)\n{\n\tstruct blockData *bdata = nestingLevelGetUserData (nl);\n\n\tif (nl->corkIndex != CORK_NIL\n\t\t&& bdata->mixin != NULL\n\t\t&& stringListCount (bdata->mixin) > 0)\n\t\tattachMixinField (nl->corkIndex, bdata->mixin);\n\n\ttagEntryInfo *e = getEntryInCorkQueue (nl->corkIndex);\n\tif (e && !e->placeholder)\n\t\tsetTagEndLine (e, getInputLineNumber ());\n\n\ttagEntryInfo *sub_e;\n\tif (bdata->subparserCorkIndex != CORK_NIL\n\t\t&& (sub_e = getEntryInCorkQueue (bdata->subparserCorkIndex)))\n\t{\n\t\tsetTagEndLine (sub_e, getInputLineNumber ());\n\t\tif (bdata->subparser && bdata->subparser->leaveBlockNotify)\n\t\t\tbdata->subparser->leaveBlockNotify (bdata->subparser,\n\t\t\t\t\t\t\t\t\t\t\t\tbdata->subparserCorkIndex);\n\t}\n\n\tif (bdata->mixin)\n\t\tstringListDelete (bdata->mixin);\n}\n\nstatic bool doesLineIncludeConstant (const unsigned char **cp, vString *constant)\n{\n\tconst unsigned char *p = *cp;\n\n\tif (isspace (*p))\n\t\tskipWhitespace (&p);\n\n\tif (isupper (*p))\n\t{\n\t\twhile (*p != 0 && isIdentChar (*p))\n\t\t{\n\t\t\tvStringPut (constant, *p);\n\t\t\t++p;\n\t\t}\n\t\tif (isspace (*p))\n\t\t\tskipWhitespace (&p);\n\t\tif (*p == '=')\n\t\t{\n\t\t\t*cp = p;\n\t\t\treturn true;\n\t\t}\n\t\tvStringClear (constant);\n\t}\n\n\treturn false;\n}\n\nstatic void emitRubyAccessorTags (vString *a, bool reader, bool writer)\n{\n\tif (vStringLength (a) == 0)\n\t\treturn;\n\n\tif (reader)\n\t\temitRubyTagFull (a, K_ACCESSOR, false, !writer);\n\tif (writer)\n\t{\n\t\tvStringPut (a, '=');\n\t\temitRubyTagFull (a, K_ACCESSOR, false, true);\n\t}\n}\n\nstatic void readAttrsAndEmitTags (const unsigned char **cp, const unsigned char *end,\n\t\t\t\t\t\t\t\t  bool reader, bool writer)\n{\n\tvString *a = vStringNew ();\n\n\tskipWhitespace (cp);\n\tif (**cp == '(')\n\t\t++*cp;\n\n\tdo {\n\t\tskipWhitespace (cp);\n\t\tif (**cp == ':')\n\t\t{\n\t\t\tif (K_METHOD == parseIdentifier (cp, end, a, K_METHOD))\n\t\t\t{\n\t\t\t\temitRubyAccessorTags (a, reader, writer);\n\t\t\t\tskipWhitespace (cp);\n\t\t\t\tif (**cp == ',')\n\t\t\t\t{\n\t\t\t\t\t++*cp;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (**cp == '\"' || **cp == '\\'')\n\t\t{\n\t\t\tunsigned char b = **cp;\n\t\t\t++*cp;\n\t\t\tparseString (cp, b, a);\n\n\t\t\temitRubyAccessorTags (a, reader, writer);\n\t\t\tskipWhitespace (cp);\n\t\t\tif (**cp == ',')\n\t\t\t{\n\t\t\t\t++*cp;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t} while (1);\n\n\tvStringDelete (a);\n}\n\n/*\n * The following patterns doen't make a scope:\n * define_method (:name,...\n * define_method (\"name\",...\n * define_method ('name',...\n * define_method :name, ...\n * define_method \"name\", ...\n * define_method 'name', ...\n *\n * The following patterns make a scope:\n * define_method (:name) do ...\n * define_method (\"name\") do ...\n * define_method ('name') do ...\n * define_method :name  do ...\n * define_method \"name\" do ...\n * define_method 'name' do ...\n *\n * The following patterns may make a scope:\n * define_method (:name) ...\n * define_method (\"name\") ...\n * define_method ('name') ...\n * define_method :name ...\n * define_method \"name\" ...\n * define_method 'name' ...\n */\nstatic int readMethodAndEmitTags (const unsigned char **cp, const unsigned char *end, rubyKind kind)\n{\n\tint r = CORK_NIL;\n\tvString *a = vStringNew ();\n\n\tskipWhitespace (cp);\n\tif (**cp == '(')\n\t\t++*cp;\n\n\tskipWhitespace (cp);\n\tif (**cp == ':')\n\t{\n\t\tif (K_METHOD != parseIdentifier (cp, end, a, K_METHOD))\n\t\t\tvStringClear (a);\n\t}\n\telse if (**cp == '\"' || **cp == '\\'')\n\t{\n\t\tunsigned char b = **cp;\n\t\t++*cp;\n\t\tparseString (cp, b, a);\n\t}\n\n\tif (vStringLength (a) > 0)\n\t{\n\t\tbool pushLevel = false;\n\t\tskipWhitespace (cp);\n\t\tif (kind == K_METHOD\n\t\t\t&& (**cp == ')'\n\t\t\t\t || strncmp((const char *)*cp, \"do\", 2) == 0)) {\n\t\t\tif (**cp == ')')\n\t\t\t\t++*cp;\n\t\t\tpushLevel = true;\n\t\t}\n\n\t\tr = emitRubyTagFull (a, kind, pushLevel, false);\n\n\t\t/* If the name doesn't make a scope, fill the end: field of the tag. */\n\t\tif (kind == K_METHOD && !pushLevel)\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine (e, e->lineNumber);\n\t\t}\n\t}\n\n\tvStringDelete (a);\n\treturn r;\n}\n\nstatic int readStringAndEmitTag (const unsigned char **cp, rubyKind kind, int role)\n{\n\tint r = CORK_NIL;\n\tvString *s = NULL;\n\n\tskipWhitespace (cp);\n\tif (**cp == '(')\n\t\t++*cp;\n\n\tskipWhitespace (cp);\n\tif (**cp == '\"' || **cp == '\\'')\n\t{\n\t\tunsigned char b = **cp;\n\t\t++*cp;\n\t\ts = vStringNew ();\n\t\tparseString (cp, b, s);\n\t}\n\n\tif (s && vStringLength (s) > 0)\n\t\tr = makeSimpleRefTag (s, kind, role);\n\n\tvStringDelete (s);\n\treturn r;\n}\n\nstatic int readAndEmitDef (const unsigned char **cp, const unsigned char *end)\n{\n\trubyKind kind = K_METHOD;\n\tNestingLevel *nl = nestingLevelsGetCurrent (nesting);\n\ttagEntryInfo *e_scope  = getEntryOfNestingLevel (nl);\n\n\t/* if the def is inside an unnamed scope at the class level, assume\n\t * it's from a singleton from a construct like this:\n\t *\n\t * class C\n\t *   class << self\n\t *     def singleton\n\t *       ...\n\t *     end\n\t *   end\n\t * end\n\t */\n\tif (e_scope && (e_scope->kindIndex == K_CLASS || e_scope->kindIndex == K_MODULE)\n\t\t&& (\n\t\t\t/* Class.new do\n\t\t\t   ... in this case, an anonymous class is created and\n\t\t\t   ... pushed. */\n\t\t\tisTagExtraBitMarked (e_scope, XTAG_ANONYMOUS)\n\t\t\t||\n\t\t\t/* class <<\n\t\t\t   ... in this case, a placeholder tag having an empty\n\t\t\t   ... name is created and pushed. */\n\t\t\t*(e_scope->name) == '\\0'\n\t\t\t))\n\t\tkind = K_SINGLETON;\n\tint corkIndex = readAndEmitTag (cp, end, kind);\n\ttagEntryInfo *e = getEntryInCorkQueue (corkIndex);\n\n\t/* Fill signature: field. */\n\tif (e)\n\t{\n\t\tvString *signature = vStringNewInit (\"(\");\n\t\tskipWhitespace (cp);\n\t\tif (**cp == '(')\n\t\t{\n\t\t\t++(*cp);\n\t\t\tparseSignature (cp, signature);\n\t\t\tif (vStringLast(signature) != ')')\n\t\t\t{\n\t\t\t\tvStringDelete (signature);\n\t\t\t\tsignature = NULL;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tvStringPut (signature, ')');\n\t\te->extensionFields.signature = vStringDeleteUnwrap (signature);\n\t\tsignature = NULL;\n\t\tvStringDelete (signature);\n\t}\n\treturn corkIndex;\n}\n\nstatic rubySubparser *notifyLine (const unsigned char **cp)\n{\n\tsubparser *sub;\n\trubySubparser *rubysub = NULL;\n\tNestingLevel *nl = nestingLevelsGetCurrent (nesting);\n\n\tforeachSubparser (sub, false)\n\t{\n\t\trubysub = (rubySubparser *)sub;\n\t\trubysub->corkIndex = CORK_NIL;\n\n\t\tif (rubysub->lineNotify)\n\t\t{\n\t\t\tenterSubparser(sub);\n\t\t\tconst unsigned char *base = *cp;\n\t\t\trubysub->corkIndex = rubysub->lineNotify(rubysub, cp, nl? nl->corkIndex: CORK_NIL);\n\t\t\tleaveSubparser();\n\t\t\tif (rubysub->corkIndex != CORK_NIL)\n\t\t\t\tbreak;\n\t\t\t*cp = base;\n\t\t}\n\t}\n\n\tif (rubysub && rubysub->corkIndex != CORK_NIL)\n\t\treturn rubysub;\n\treturn NULL;\n}\n\nstatic void findRubyTags (void)\n{\n\tconst unsigned char *line;\n\tbool inMultiLineComment = false;\n\tvString *constant = vStringNew ();\n\tvString *leftSide = vStringNew ();\n\tbool found_rdoc = false;\n\n\tnesting = nestingLevelsNewFull (sizeof (struct blockData), deleteBlockData);\n\n\t/* FIXME: this whole scheme is wrong, because Ruby isn't line-based.\n\t* You could perfectly well write:\n\t*\n\t*  def\n\t*  method\n\t*   puts(\"hello\")\n\t*  end\n\t*\n\t* if you wished, and this function would fail to recognize anything.\n\t*/\n\tsize_t llen;\n\twhile ((line = readLineFromInputFileWithLength (&llen)) != NULL)\n\t{\n\t\trubySubparser *subparser = CORK_NIL;\n\t\tconst unsigned char *cp = line;\n\t\tconst unsigned char *lend = line + llen;\n\t\t/* if we expect a separator after a while, for, or until statement\n\t\t * separators are \"do\", \";\" or newline */\n\t\tbool expect_separator = false;\n\n\t\tif (found_rdoc == false)\n\t\t{\n\t\t\tif (strncmp ((const char*)cp, \"__END__\", 7) == 0)\n\t\t\t\tbreak;\n\n\t\t\tif (strncmp ((const char*)cp, \"# =\", 3) == 0)\n\t\t\t{\n\t\t\t\tfound_rdoc = true;\n\t\t\t\tmakePromise (\"RDoc\", 0, 0, 0, 0, 0);\n\t\t\t}\n\t\t}\n\n\t\tif (canMatchWithEnd (&cp, lend, \"=begin\", isWhitespace))\n\t\t{\n\t\t\tinMultiLineComment = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (canMatchWithEnd (&cp, lend, \"=end\", isWhitespace))\n\t\t{\n\t\t\tinMultiLineComment = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (inMultiLineComment)\n\t\t\tcontinue;\n\n\t\tskipWhitespace (&cp);\n\n\t\t/* Avoid mistakenly starting a scope for modifiers such as\n\t\t*\n\t\t*   return if <exp>\n\t\t*\n\t\t* FIXME: we're fooled if someone does something heinous such as\n\t\t*\n\t\t*   puts(\"hello\") \\\n\t\t*       unless <exp>\n\t\t*/\n\n\t\tif (canMatchKeywordWithAssign (&cp, lend, \"for\") ||\n\t\t\tcanMatchKeywordWithAssign (&cp, lend, \"until\") ||\n\t\t\tcanMatchKeywordWithAssign (&cp, lend, \"while\"))\n\t\t{\n\t\t\texpect_separator = true;\n\t\t\tenterUnnamedScope ();\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"case\") ||\n\t\t\t\t canMatchKeywordWithAssign (&cp, lend, \"if\") ||\n\t\t\t\t canMatchKeywordWithAssign (&cp, lend, \"unless\"))\n\t\t{\n\t\t\tenterUnnamedScope ();\n\t\t}\n\n\t\t/*\n\t\t* \"module M\", \"class C\" and \"def m\" should only be at the beginning\n\t\t* of a line.\n\t\t*/\n\t\tif (canMatchKeywordWithAssign (&cp, lend, \"class\")\n\t\t\t|| canMatchKeywordWithAssign (&cp, lend, \"module\")\n\t\t\t|| (canMatchKeywordWithAssignFull (&cp, lend, \"Class.new\", leftSide))\n\t\t\t|| (canMatchKeywordWithAssignFull (&cp, lend, \"Module.new\", leftSide)))\n\t\t{\n\t\t\tint r;\n\n\t\t\tint kind = K_UNDEFINED;\n\t\t\tif (*(cp - 1) == 's')\n\t\t\t\t/* clas*s* */\n\t\t\t\tkind = K_CLASS;\n\t\t\telse if (*(cp - 1) == 'e')\n\t\t\t\t/* *modul*e* */\n\t\t\t\tkind = K_MODULE;\n\t\t\telse if (*(cp - 5) == 's')\n\t\t\t{\n\t\t\t\t/* Clas*s*.new */\n\t\t\t\tkind = K_CLASS;\n\t\t\t\texpect_separator = true;\n\t\t\t}\n\t\t\telse if (*(cp - 5) == 'e')\n\t\t\t{\n\t\t\t\t/* Modul*e*.new */\n\t\t\t\tkind = K_MODULE;\n\t\t\t\texpect_separator = true;\n\t\t\t}\n\t\t\telse\n\t\t\t\tAssertNotReached();\n\n\t\t\tif (expect_separator)\n\t\t\t{\n\t\t\t\tr = emitRubyTagFull(vStringLength (leftSide) > 0? leftSide: NULL, kind, true, false);\n\t\t\t\tvStringClear (leftSide);\n\t\t\t}\n\t\t\telse\n\t\t\t\tr = readAndEmitTag (&cp, lend, kind);\n\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\n\t\t\tif (e)\n\t\t\t{\n\t\t\t\tskipWhitespace (&cp);\n\t\t\t\tif ((*cp == '<' && *(cp + 1) != '<')\n\t\t\t\t\t|| (expect_separator && (*cp == '(')))\n\t\t\t\t{\n\t\t\t\t\tcp++;\n\t\t\t\t\tvString *parent = vStringNew ();\n\t\t\t\t\tparseIdentifier (&cp, lend, parent, K_CLASS);\n\t\t\t\t\tif (vStringLength (parent) > 0)\n\t\t\t\t\t\te->extensionFields.inheritance = vStringDeleteUnwrap (parent);\n\t\t\t\t\telse\n\t\t\t\t\t\tvStringDelete (parent);\n\t\t\t\t\tif (expect_separator)\n\t\t\t\t\t{\n\t\t\t\t\t\tskipWhitespace (&cp);\n\t\t\t\t\t\tif (*cp == ')')\n\t\t\t\t\t\t\tcp++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"include\"))\n\t\t{\n\t\t\treadAndStoreMixinSpec (&cp, lend, \"include\");\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"prepend\"))\n\t\t{\n\t\t\treadAndStoreMixinSpec (&cp, lend, \"prepend\");\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"extend\"))\n\t\t{\n\t\t\treadAndStoreMixinSpec (&cp, lend, \"extend\");\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"def\"))\n\t\t{\n\t\t\treadAndEmitDef (&cp, lend);\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"attr_reader\"))\n\t\t{\n\t\t\treadAttrsAndEmitTags (&cp, lend, true, false);\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"attr_writer\"))\n\t\t{\n\t\t\treadAttrsAndEmitTags (&cp, lend, false, true);\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"attr_accessor\"))\n\t\t{\n\t\t\treadAttrsAndEmitTags (&cp, lend, true, true);\n\t\t}\n\t\telse if (doesLineIncludeConstant (&cp, constant))\n\t\t{\n\t\t\temitRubyTag (constant, K_CONST);\n\t\t\tvStringClear (constant);\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"require\"))\n\t\t{\n\t\t\treadStringAndEmitTag (&cp, K_LIBRARY, RUBY_LIBRARY_REQUIRED);\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"require_relative\"))\n\t\t{\n\t\t\treadStringAndEmitTag (&cp, K_LIBRARY, RUBY_LIBRARY_REQUIRED_REL);\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"load\"))\n\t\t{\n\t\t\treadStringAndEmitTag (&cp, K_LIBRARY, RUBY_LIBRARY_LOADED);\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"alias\"))\n\t\t{\n\t\t\tif (!readAndEmitTagFull (&cp, lend, K_ALIAS, false, true)\n\t\t\t\t&& (*cp == '$'))\n\t\t\t{\n\t\t\t\t/* Alias for a global variable. */\n\t\t\t\t++cp;\n\t\t\t\tvString *alias = vStringNew ();\n\t\t\t\tvStringPut (alias, '$');\n\t\t\t\tif (K_METHOD == parseIdentifier (&cp, lend, alias, K_METHOD)\n\t\t\t\t\t&& vStringLength (alias) > 0)\n\t\t\t\t\temitRubyTagFull (alias, K_ALIAS, false, false);\n\t\t\t\tvStringDelete (alias);\n\t\t\t}\n\t\t}\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"alias_method\"))\n\t\t\treadMethodAndEmitTags (&cp, lend, K_ALIAS);\n\t\telse if (canMatchKeywordWithAssign (&cp, lend, \"define_method\"))\n\t\t{\n\t\t\tint r = readMethodAndEmitTags (&cp, lend, K_METHOD);\n\t\t\t/* \"define_method(m)\" makes a scope.\n\t\t\t * In that case, we know we will see '{' or 'do' soon.\n\t\t\t */\n\t\t\tNestingLevel *nl = nestingLevelsGetCurrent (nesting);\n\t\t\tif (nl && r == nl->corkIndex)\n\t\t\t\texpect_separator = true;\n\t\t}\n\t\telse if ((canMatchKeywordWithAssign (&cp, lend, \"private\")\n\t\t\t\t  || canMatchKeywordWithAssign (&cp, lend, \"protected\")\n\t\t\t\t  || canMatchKeywordWithAssign (&cp, lend, \"public\")\n\t\t\t\t  || canMatchKeywordWithAssign (&cp, lend, \"private_class_method\")\n\t\t\t\t  || canMatchKeywordWithAssign (&cp, lend, \"public_class_method\")))\n\t\t{\n\t\t\tskipWhitespace (&cp);\n\t\t\tif (canMatchKeywordWithAssign (&cp, lend, \"def\"))\n\t\t\t\treadAndEmitDef (&cp, lend);\n\t\t\t/* TODO: store the method for controlling visibility\n\t\t\t * to the \"access:\" field of the tag.*/\n\t\t}\n\t\telse\n\t\t\tsubparser = notifyLine(&cp);\n\n\n\t\twhile (*cp != '\\0')\n\t\t{\n\t\t\t/* FIXME: we don't cope with here documents,\n\t\t\t* or regular expression literals, or ... you get the idea.\n\t\t\t* Hopefully, the restriction above that insists on seeing\n\t\t\t* definitions at the starts of lines should keep us out of\n\t\t\t* mischief.\n\t\t\t*/\n\t\t\tif (inMultiLineComment || isspace (*cp))\n\t\t\t{\n\t\t\t\t++cp;\n\t\t\t}\n\t\t\telse if (*cp == '#')\n\t\t\t{\n\t\t\t\t/* FIXME: this is wrong, but there *probably* won't be a\n\t\t\t\t* definition after an interpolated string (where # doesn't\n\t\t\t\t* mean 'comment').\n\t\t\t\t*/\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (canMatchKeyword (&cp, lend, \"begin\"))\n\t\t\t{\n\t\t\t\tenterUnnamedScope ();\n\t\t\t}\n\t\t\telse if (canMatchKeyword (&cp, lend, \"do\") || (*cp == '{'))\n\t\t\t{\n\t\t\t\tif (*cp == '{')\n\t\t\t\t\t++cp;\n\n\t\t\t\tif (! expect_separator)\n\t\t\t\t{\n\t\t\t\t\t/* We saw '{' or 'do' unexpectedly.\n\t\t\t\t\t * Let's make an placeholder scope for it.\n\t\t\t\t\t *\n\t\t\t\t\t * If '{' or 'do' is expected, a scope will be pushed already.\n\t\t\t\t\t * If they are not expected, a scope is pushed here.\n\t\t\t\t\t * Either case a scope is pushed. See the code handling \"end\".\n\t\t\t\t\t */\n\t\t\t\t\tenterUnnamedScope ();\n\t\t\t\t\tif (subparser && subparser->corkIndex)\n\t\t\t\t\t\tparasiteToScope (subparser, subparser->corkIndex);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\texpect_separator = false;\n\t\t\t}\n\t\t\telse if ((canMatchKeyword (&cp, lend, \"end\") || (*cp == '}')) && nesting->n > 0)\n\t\t\t{\n\t\t\t\tif (*cp == '}')\n\t\t\t\t\t++cp;\n\n\t\t\t\t/* Leave the most recent scope. */\n\t\t\t\tnestingLevelsPop (nesting);\n\t\t\t}\n\t\t\telse if (*cp == '\"' || *cp == '\\'')\n\t\t\t{\n\t\t\t\tunsigned char b = *cp;\n\t\t\t\t/* Skip string literals.\n\t\t\t\t * FIXME: should cope with escapes and interpolation.\n\t\t\t\t */\n\t\t\t\t++cp;\n\t\t\t\tparseString (&cp, b, NULL);\n\t\t\t}\n\t\t\telse if (*cp == ';')\n\t\t\t{\n\t\t\t\t++cp;\n\t\t\t\texpect_separator = false;\n\t\t\t}\n\t\t\telse if (*cp != '\\0')\n\t\t\t{\n\t\t\t\tdo\n\t\t\t\t\t++cp;\n\t\t\t\twhile (isIdentChar (*cp));\n\t\t\t}\n\t\t}\n\n\t\tif (expect_separator)\n\t\t{\n\t\t\tNestingLevel *nl = nestingLevelsGetCurrent (nesting);\n\t\t\ttagEntryInfo *e_scope  = getEntryOfNestingLevel (nl);\n\n\t\t\tif (e_scope && (e_scope->kindIndex == K_CLASS\n\t\t\t\t\t\t\t|| e_scope->kindIndex == K_MODULE\n\t\t\t\t\t\t\t/* Though \"define_method(m)\" is seen, no\n\t\t\t\t\t\t\t * \"do\" or \"{\" is found.\n\t\t\t\t\t\t\t *\n\t\t\t\t\t\t\t * If \"define_method(m, x)\" is seen, neither\n\t\t\t\t\t\t\t * \"do\" nor \"{\" is expected; a scope was not\n\t\t\t\t\t\t\t * pushed.\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\t|| ((e_scope->kindIndex == K_METHOD) &&\n\t\t\t\t\t\t\t\t!e_scope->placeholder)))\n\t\t\t\t/* Class.new() ... was found but \"do\" or `{' is not\n\t\t\t\t * found at the end; no block is made. Let's\n\t\t\t\t * pop the nesting level push when Class.new()\n\t\t\t\t * was found. This is applicable to Module.new. */\n\t\t\t\tnestingLevelsPop (nesting);\n\t\t}\n\t}\n\tnestingLevelsFree (nesting);\n\tvStringDelete (leftSide);\n\tvStringDelete (constant);\n}\n\nextern parserDefinition* RubyParser (void)\n{\n\tstatic const char *const extensions [] = { \"rb\", \"ruby\", NULL };\n\tparserDefinition* def = parserNew (\"Ruby\");\n\tdef->kindTable      = RubyKinds;\n\tdef->kindCount  = ARRAY_SIZE (RubyKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findRubyTags;\n\tdef->fieldTable = RubyFields;\n\tdef->fieldCount = ARRAY_SIZE (RubyFields);\n\tdef->useCork    = CORK_QUEUE;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/rust.c",
    "content": "/*\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Rust files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include <string.h>\n\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"entry.h\"\n#include \"options.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n#include \"trace.h\"\n\n/*\n*   MACROS\n*/\n#define MAX_STRING_LENGTH 256\n\n#define tokenLitEq(LEXER,CSTRLIT) (vStringEqC((LEXER)->token_str,CSTRLIT))\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef enum {\n\tK_MOD,\n\tK_STRUCT,\n\tK_TRAIT,\n\tK_IMPL,\n\tK_FN,\n\tK_ENUM,\n\tK_TYPE,\n\tK_STATIC,\n\tK_MACRO,\n\tK_FIELD,\n\tK_VARIANT,\n\tK_METHOD,\n\tK_CONST,\n\tK_NONE\n} RustKind;\n\ntypedef enum {\n\tF_MACRO,\n} RustField;\n\nstatic kindDefinition rustKinds[] = {\n\t{true, 'n', \"module\", \"module\"},\n\t{true, 's', \"struct\", \"structural type\"},\n\t{true, 'i', \"interface\", \"trait interface\"},\n\t{true, 'c', \"implementation\", \"implementation\"},\n\t{true, 'f', \"function\", \"Function\"},\n\t{true, 'g', \"enum\", \"Enum\"},\n\t{true, 't', \"typedef\", \"Type Alias\"},\n\t{true, 'v', \"variable\", \"Global variable\"},\n\t{true, 'M', \"macro\", \"Macro Definition\"},\n\t{true, 'm', \"field\", \"A struct field\"},\n\t{true, 'e', \"enumerator\", \"An enum variant\"},\n\t{true, 'P', \"method\", \"A method\"},\n\t{true, 'C', \"constant\", \"A constant\"},\n};\n\nstatic fieldDefinition rustFields[] = {\n\t{\n\t\t.name = \"macro\",\n\t\t.description = \"macro invocation containing the definition\",\n\t\t.enabled = true,\n\t\t.version = 1,\n\t},\n};\n\ntypedef enum eTokenType {\n\tTOKEN_WHITESPACE,\n\tTOKEN_STRING,\n\tTOKEN_IDENT,\n\tTOKEN_LSHIFT,\n\tTOKEN_RSHIFT,\n\tTOKEN_RARROW,\n\tTOKEN_EOF\n} tokenType;\n\ntypedef struct {\n\t/* Characters */\n\tint cur_c;\n\tint next_c;\n\n\t/* Tokens */\n\tint cur_token;\n\tvString* token_str;\n\tunsigned long line;\n\tMIOPos pos;\n\n\tconst char *macro;\n} lexerState;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n\nstatic void parseBlock (lexerState *lexer, bool delim, int kind, vString *scope,\n\t\t\t\t\t\tbool as_token_tree);\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n#include \"d-rust.h\"\n\n/* Resets the scope string to the old length */\nstatic void resetScope (vString *scope, size_t old_len)\n{\n\tvStringTruncate (scope, old_len);\n}\n\n/* Adds a name to the end of the scope string */\nstatic void addToScope (vString *scope, vString *name)\n{\n\tif (vStringLength(scope) > 0)\n\t\tvStringCatS(scope, \"::\");\n\tvStringCat(scope, name);\n}\n\nstatic const char* swapMacroInvocation (lexerState *lexer, const char *macro)\n{\n\tconst char *tmp = lexer->macro;\n\tlexer->macro = macro;\n\treturn tmp;\n}\n\n/* Write the lexer's current token to string, taking care of special tokens */\nstatic void writeCurTokenToStr (lexerState *lexer, vString *out_str)\n{\n\tswitch (lexer->cur_token)\n\t{\n\t\tcase TOKEN_IDENT:\n\t\t\tvStringCat(out_str, lexer->token_str);\n\t\t\tbreak;\n\t\tcase TOKEN_STRING:\n\t\t\tvStringCat(out_str, lexer->token_str);\n\t\t\tbreak;\n\t\tcase TOKEN_WHITESPACE:\n\t\t\tvStringPut(out_str, ' ');\n\t\t\tbreak;\n\t\tcase TOKEN_LSHIFT:\n\t\t\tvStringCatS(out_str, \"<<\");\n\t\t\tbreak;\n\t\tcase TOKEN_RSHIFT:\n\t\t\tvStringCatS(out_str, \">>\");\n\t\t\tbreak;\n\t\tcase TOKEN_RARROW:\n\t\t\tvStringCatS(out_str, \"->\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tvStringPut(out_str, lexer->cur_token);\n\t}\n}\n\n/* Reads a character from the file */\nstatic void advanceChar (lexerState *lexer)\n{\n\tlexer->cur_c = lexer->next_c;\n\tlexer->next_c = getcFromInputFile();\n}\n\n/* Reads N characters from the file */\nstatic void advanceNChar (lexerState *lexer, int n)\n{\n\twhile (n--)\n\t\tadvanceChar(lexer);\n}\n\n/* Store the current character in lexerState::token_str if there is space\n * (set by MAX_STRING_LENGTH), and then read the next character from the file */\nstatic void advanceAndStoreChar (lexerState *lexer)\n{\n\tif (vStringLength(lexer->token_str) < MAX_STRING_LENGTH)\n\t\tvStringPut(lexer->token_str, lexer->cur_c);\n\tadvanceChar(lexer);\n}\n\nstatic bool isWhitespace (int c)\n{\n\treturn c == ' ' || c == '\\t' || c == '\\r' || c == '\\n';\n}\n\nstatic bool isAscii (int c)\n{\n\treturn (c >= 0) && (c < 0x80);\n}\n\n/* This isn't quite right for Unicode identifiers */\nstatic bool isIdentifierStart (int c)\n{\n\treturn (isAscii(c) && (isalpha(c) || c == '_')) || !isAscii(c);\n}\n\n/* This isn't quite right for Unicode identifiers */\nstatic bool isIdentifierContinue (int c)\n{\n\treturn (isAscii(c) && (isalnum(c) || c == '_')) || !isAscii(c);\n}\n\nstatic void scanWhitespace (lexerState *lexer)\n{\n\twhile (isWhitespace(lexer->cur_c))\n\t\tadvanceChar(lexer);\n}\n\n/* Normal line comments start with two /'s and continue until the next \\n\n * (potentially after a \\r). Additionally, a shebang in the beginning of the\n * file also counts as a line comment as long as it is not this sequence: #![ .\n * Block comments start with / followed by a * and end with a * followed by a /.\n * Unlike in C/C++ they nest. */\nstatic void scanComments (lexerState *lexer)\n{\n\t/* // */\n\tif (lexer->next_c == '/')\n\t{\n\t\tadvanceNChar(lexer, 2);\n\t\twhile (lexer->cur_c != EOF && lexer->cur_c != '\\n')\n\t\t\tadvanceChar(lexer);\n\t}\n\t/* #! */\n\telse if (lexer->next_c == '!')\n\t{\n\t\tadvanceNChar(lexer, 2);\n\t\t/* If it is exactly #![ then it is not a comment, but an attribute */\n\t\tif (lexer->cur_c == '[')\n\t\t\treturn;\n\t\twhile (lexer->cur_c != EOF && lexer->cur_c != '\\n')\n\t\t\tadvanceChar(lexer);\n\t}\n\t/* block comment */\n\telse if (lexer->next_c == '*')\n\t{\n\t\tint level = 1;\n\t\tadvanceNChar(lexer, 2);\n\t\twhile (lexer->cur_c != EOF && level > 0)\n\t\t{\n\t\t\tif (lexer->cur_c == '*' && lexer->next_c == '/')\n\t\t\t{\n\t\t\t\tlevel--;\n\t\t\t\tadvanceNChar(lexer, 2);\n\t\t\t}\n\t\t\telse if (lexer->cur_c == '/' && lexer->next_c == '*')\n\t\t\t{\n\t\t\t\tlevel++;\n\t\t\t\tadvanceNChar(lexer, 2);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tadvanceChar(lexer);\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void scanIdentifier (lexerState *lexer)\n{\n\tvStringClear(lexer->token_str);\n\tdo\n\t{\n\t\tadvanceAndStoreChar(lexer);\n\t} while(lexer->cur_c != EOF && isIdentifierContinue(lexer->cur_c));\n}\n\n/* Double-quoted strings, we only care about the \\\" escape. These\n * last past the end of the line, so be careful not too store too much\n * of them (see MAX_STRING_LENGTH). The only place we look at their\n * contents is in the function definitions, and there the valid strings are\n * things like \"C\" and \"Rust\" */\nstatic void scanString (lexerState *lexer)\n{\n\tvStringClear(lexer->token_str);\n\tadvanceAndStoreChar(lexer);\n\twhile (lexer->cur_c != EOF && lexer->cur_c != '\"')\n\t{\n\t\tif (lexer->cur_c == '\\\\' && lexer->next_c == '\"')\n\t\t\tadvanceAndStoreChar(lexer);\n\t\tadvanceAndStoreChar(lexer);\n\t}\n\tif (lexer->cur_c != EOF)\n\t\tadvanceAndStoreChar(lexer);\n}\n\n/* Raw strings look like this: r\"\" or r##\"\"## where the number of\n * hashes must match */\nstatic void scanRawString (lexerState *lexer)\n{\n\tsize_t num_initial_hashes = 0;\n\tvStringClear(lexer->token_str);\n\tadvanceAndStoreChar(lexer);\n\t/* Count how many leading hashes there are */\n\twhile (lexer->cur_c == '#')\n\t{\n\t\tnum_initial_hashes++;\n\t\tadvanceAndStoreChar(lexer);\n\t}\n\tif (lexer->cur_c != '\"')\n\t\treturn;\n\tadvanceAndStoreChar(lexer);\n\twhile (lexer->cur_c != EOF)\n\t{\n\t\t/* Count how many trailing hashes there are. If the number is equal or more\n\t\t * than the number of leading hashes, break. */\n\t\tif (lexer->cur_c == '\"')\n\t\t{\n\t\t\tsize_t num_trailing_hashes = 0;\n\t\t\tadvanceAndStoreChar(lexer);\n\t\t\twhile (lexer->cur_c == '#' && num_trailing_hashes < num_initial_hashes)\n\t\t\t{\n\t\t\t\tnum_trailing_hashes++;\n\n\t\t\t\tadvanceAndStoreChar(lexer);\n\t\t\t}\n\t\t\tif (num_trailing_hashes == num_initial_hashes)\n\t\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tadvanceAndStoreChar(lexer);\n\t\t}\n\t}\n}\n\n/* This deals with character literals: 'n', '\\n', '\\uFFFF'; and lifetimes:\n * 'lifetime. We'll use this approximate regexp for the literals:\n * \\' \\\\ [^']+ \\' or \\' [^'] \\' or \\' \\\\ \\' \\'. Either way, we'll treat this\n * token as a string, so it gets preserved as is for function signatures with\n * lifetimes. */\nstatic void scanCharacterOrLifetime (lexerState *lexer)\n{\n\tvStringClear(lexer->token_str);\n\tadvanceAndStoreChar(lexer);\n\n\tif (lexer->cur_c == '\\\\')\n\t{\n\t\tadvanceAndStoreChar(lexer);\n\t\t/* The \\' \\\\ \\' \\' (literally '\\'') case */\n\t\tif (lexer->cur_c == '\\'' && lexer->next_c == '\\'')\n\t\t{\n\t\t\tadvanceAndStoreChar(lexer);\n\t\t\tadvanceAndStoreChar(lexer);\n\t\t}\n\t\t/* The \\' \\\\ [^']+ \\' case */\n\t\telse\n\t\t{\n\t\t\twhile (lexer->cur_c != EOF && lexer->cur_c != '\\'')\n\t\t\t\tadvanceAndStoreChar(lexer);\n\t\t}\n\t}\n\t/* The \\' [^'] \\' case */\n\telse if (lexer->cur_c != '\\'' && lexer->next_c == '\\'')\n\t{\n\t\tadvanceAndStoreChar(lexer);\n\t\tadvanceAndStoreChar(lexer);\n\t}\n\t/* Otherwise it is malformed, or a lifetime */\n}\n\n/* Advances the parser one token, optionally skipping whitespace\n * (otherwise it is concatenated and returned as a single whitespace token).\n * Whitespace is needed to properly render function signatures. Unrecognized\n * token starts are stored literally, e.g. token may equal to a character '#'. */\nstatic int advanceToken0 (lexerState *lexer, bool skip_whitspace)\n{\n\tbool have_whitespace = false;\n\tlexer->line = getInputLineNumber();\n\tlexer->pos = getInputFilePosition();\n\twhile (lexer->cur_c != EOF)\n\t{\n\t\tif (isWhitespace(lexer->cur_c))\n\t\t{\n\t\t\tscanWhitespace(lexer);\n\t\t\thave_whitespace = true;\n\t\t}\n\t\telse if (lexer->cur_c == '/' && (lexer->next_c == '/' || lexer->next_c == '*'))\n\t\t{\n\t\t\tscanComments(lexer);\n\t\t\thave_whitespace = true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (have_whitespace && !skip_whitspace)\n\t\t\t\treturn lexer->cur_token = TOKEN_WHITESPACE;\n\t\t\tbreak;\n\t\t}\n\t}\n\tlexer->line = getInputLineNumber();\n\tlexer->pos = getInputFilePosition();\n\twhile (lexer->cur_c != EOF)\n\t{\n\t\tif (lexer->cur_c == '\"')\n\t\t{\n\t\t\tscanString(lexer);\n\t\t\treturn lexer->cur_token = TOKEN_STRING;\n\t\t}\n\t\telse if (lexer->cur_c == 'r' && (lexer->next_c == '#' || lexer->next_c == '\"'))\n\t\t{\n\t\t\tscanRawString(lexer);\n\t\t\treturn lexer->cur_token = TOKEN_STRING;\n\t\t}\n\t\telse if (lexer->cur_c == '\\'')\n\t\t{\n\t\t\tscanCharacterOrLifetime(lexer);\n\t\t\treturn lexer->cur_token = TOKEN_STRING;\n\t\t}\n\t\telse if (isIdentifierStart(lexer->cur_c))\n\t\t{\n\t\t\tscanIdentifier(lexer);\n\t\t\treturn lexer->cur_token = TOKEN_IDENT;\n\t\t}\n\t\t/* These shift tokens aren't too important for tag-generation per se,\n\t\t * but they confuse the skipUntil code which tracks the <> pairs. */\n\t\telse if (lexer->cur_c == '>' && lexer->next_c == '>')\n\t\t{\n\t\t\tadvanceNChar(lexer, 2);\n\t\t\treturn lexer->cur_token = TOKEN_RSHIFT;\n\t\t}\n\t\telse if (lexer->cur_c == '<' && lexer->next_c == '<')\n\t\t{\n\t\t\tadvanceNChar(lexer, 2);\n\t\t\treturn lexer->cur_token = TOKEN_LSHIFT;\n\t\t}\n\t\telse if (lexer->cur_c == '-' && lexer->next_c == '>')\n\t\t{\n\t\t\tadvanceNChar(lexer, 2);\n\t\t\treturn lexer->cur_token = TOKEN_RARROW;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tint c = lexer->cur_c;\n\t\t\tadvanceChar(lexer);\n\t\t\treturn lexer->cur_token = c;\n\t\t}\n\t}\n\treturn lexer->cur_token = TOKEN_EOF;\n}\n\nstatic int advanceToken (lexerState *lexer, bool skip_whitspace)\n{\n\tint r = advanceToken0(lexer, skip_whitspace);\n\tTRACE_PRINT(\"token: %s\", decodeTokenType(r));\n\treturn r;\n}\n\nstatic void initLexer (lexerState *lexer)\n{\n\tlexer->macro = NULL;\n\tadvanceNChar(lexer, 2);\n\tlexer->token_str = vStringNew();\n\n\tif (lexer->cur_c == '#' && lexer->next_c == '!')\n\t\tscanComments(lexer);\n\tadvanceToken(lexer, true);\n}\n\nstatic void deInitLexer (lexerState *lexer)\n{\n\tvStringDelete(lexer->token_str);\n\tlexer->token_str = NULL;\n}\n\nstatic void addTag (vString* ident, const char* arg_list, int kind, unsigned long line, MIOPos pos, vString *scope, int parent_kind,\n\t\t\t\t\tconst char* macro)\n{\n\tTRACE_PRINT(\"tag: %s\", vStringValue (ident));\n\n\tif (kind == K_NONE || ! rustKinds[kind].enabled)\n\t\treturn;\n\ttagEntryInfo tag;\n\tinitTagEntry(&tag, vStringValue(ident), kind);\n\n\tupdateTagLine (&tag, line, pos);\n\n\ttag.extensionFields.signature = arg_list;\n\t/*tag.extensionFields.varType = type;*/ /* FIXME: map to typeRef[1]? */\n\tif (parent_kind != K_NONE)\n\t{\n\t\ttag.extensionFields.scopeKindIndex = parent_kind;\n\t\ttag.extensionFields.scopeName = vStringValue(scope);\n\t}\n\n\tif (macro)\n\t\tattachParserField (&tag, rustFields[F_MACRO].ftype, macro);\n\n\tmakeTagEntry(&tag);\n}\n\n/* Skip tokens until one of the goal tokens is hit. Escapes when level = 0 if there are no goal tokens.\n * Keeps track of balanced <>'s, ()'s, []'s, and {}'s and ignores the goal tokens within those pairings */\nstatic void skipUntil (lexerState *lexer, int goal_tokens[], int num_goal_tokens)\n{\n\tint angle_level = 0;\n\tint paren_level = 0;\n\tint brace_level = 0;\n\tint bracket_level = 0;\n\twhile (lexer->cur_token != TOKEN_EOF)\n\t{\n\t\tif (angle_level == 0 && paren_level == 0 && brace_level == 0\n\t\t    && bracket_level == 0)\n\t\t{\n\t\t\tint ii = 0;\n\t\t\tfor(ii = 0; ii < num_goal_tokens; ii++)\n\t\t\t{\n\t\t\t\tif (lexer->cur_token == goal_tokens[ii])\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (ii < num_goal_tokens)\n\t\t\t\tbreak;\n\t\t}\n\t\tswitch (lexer->cur_token)\n\t\t{\n\t\t\tcase '<':\n\t\t\t\tangle_level++;\n\t\t\t\tbreak;\n\t\t\tcase '(':\n\t\t\t\tparen_level++;\n\t\t\t\tbreak;\n\t\t\tcase '{':\n\t\t\t\tbrace_level++;\n\t\t\t\tbreak;\n\t\t\tcase '[':\n\t\t\t\tbracket_level++;\n\t\t\t\tbreak;\n\t\t\tcase '>':\n\t\t\t\tangle_level--;\n\t\t\t\tbreak;\n\t\t\tcase ')':\n\t\t\t\tparen_level--;\n\t\t\t\tbreak;\n\t\t\tcase '}':\n\t\t\t\tbrace_level--;\n\t\t\t\tbreak;\n\t\t\tcase ']':\n\t\t\t\tbracket_level--;\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_RSHIFT:\n\t\t\t\tif (angle_level >= 2)\n\t\t\t\t\tangle_level -= 2;\n\t\t\t\tbreak;\n\t\t\t/* TOKEN_LSHIFT is never interpreted as two <'s in valid Rust code */\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t\t/* Has to be after the token switch to catch the case when we start with the initial level token */\n\t\tif (num_goal_tokens == 0 && angle_level == 0 && paren_level == 0 && brace_level == 0\n\t\t    && bracket_level == 0)\n\t\t\tbreak;\n\t\tadvanceToken(lexer, true);\n\t}\n}\n\n/* Function format:\n * \"fn\" <ident>[<type_bounds>] \"(\" [<args>] \")\" [\"->\" <ret_type>] \"{\" [<body>] \"}\"*/\nstatic void parseFn (lexerState *lexer, vString *scope, int parent_kind)\n{\n\tTRACE_ENTER();\n\n\tint kind = (parent_kind == K_TRAIT || parent_kind == K_IMPL) ? K_METHOD : K_FN;\n\tvString *name;\n\tvString *arg_list;\n\tunsigned long line;\n\tMIOPos pos;\n\tint paren_level = 0;\n\tint bracket_level = 0;\n\tbool found_paren = false;\n\tbool valid_signature = true;\n\n\tadvanceToken(lexer, true);\n\tif (lexer->cur_token != TOKEN_IDENT)\n\t{\n\t\tTRACE_LEAVE_TEXT(\"no identifier\");\n\t\treturn;\n\t}\n\n\tname = vStringNewCopy(lexer->token_str);\n\targ_list = vStringNew();\n\n\tline = lexer->line;\n\tpos = lexer->pos;\n\n\tadvanceToken(lexer, true);\n\n\t/* HACK: This is a bit coarse as far as what tag entry means by\n\t * 'arglist'... */\n\twhile (lexer->cur_token != '{')\n\t{\n\t\tif (lexer->cur_token == ';' && bracket_level == 0)\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\telse if (lexer->cur_token == '}')\n\t\t{\n\t\t\tvalid_signature = false;\n\t\t\tbreak;\n\t\t}\n\t\telse if (lexer->cur_token == '(')\n\t\t{\n\t\t\tfound_paren = true;\n\t\t\tparen_level++;\n\t\t}\n\t\telse if (lexer->cur_token == ')')\n\t\t{\n\t\t\tparen_level--;\n\t\t\tif (paren_level < 0)\n\t\t\t{\n\t\t\t\tvalid_signature = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if (lexer->cur_token == '[')\n\t\t{\n\t\t\tbracket_level++;\n\t\t}\n\t\telse if (lexer->cur_token == ']')\n\t\t{\n\t\t\tbracket_level--;\n\t\t}\n\t\telse if (lexer->cur_token == TOKEN_EOF)\n\t\t{\n\t\t\tvalid_signature = false;\n\t\t\tbreak;\n\t\t}\n\t\twriteCurTokenToStr(lexer, arg_list);\n\t\tadvanceToken(lexer, false);\n\t}\n\tif (!found_paren || paren_level != 0 || bracket_level != 0)\n\t\tvalid_signature = false;\n\n\tif (valid_signature)\n\t{\n\t\tvStringStripTrailing(arg_list);\n\t\taddTag(name, vStringValue(arg_list), kind, line, pos, scope, parent_kind,\n\t\t\t   lexer->macro);\n\t\taddToScope(scope, name);\n\t\tparseBlock(lexer, true, kind, scope, false);\n\t}\n\n\tvStringDelete(name);\n\tvStringDelete(arg_list);\n\n\tTRACE_LEAVE();\n}\n\n/* Mod format:\n * \"mod\" <ident> \"{\" [<body>] \"}\"\n * \"mod\" <ident> \";\"*/\nstatic void parseMod (lexerState *lexer, vString *scope, int parent_kind)\n{\n\tTRACE_ENTER();\n\n\tadvanceToken(lexer, true);\n\tif (lexer->cur_token != TOKEN_IDENT)\n\t{\n\t\tTRACE_LEAVE_TEXT(\"no identifier\");\n\t\treturn;\n\t}\n\n\taddTag(lexer->token_str, NULL, K_MOD, lexer->line, lexer->pos, scope, parent_kind,\n\t\t   lexer->macro);\n\taddToScope(scope, lexer->token_str);\n\n\tadvanceToken(lexer, true);\n\n\tparseBlock(lexer, true, K_MOD, scope, false);\n\n\tTRACE_LEAVE();\n}\n\n/* Trait format:\n * \"trait\" <ident> [<type_bounds>] \"{\" [<body>] \"}\"\n */\nstatic void parseTrait (lexerState *lexer, vString *scope, int parent_kind)\n{\n\tint goal_tokens[] = {'{'};\n\n\tadvanceToken(lexer, true);\n\tif (lexer->cur_token != TOKEN_IDENT)\n\t\treturn;\n\n\taddTag(lexer->token_str, NULL, K_TRAIT, lexer->line, lexer->pos, scope, parent_kind,\n\t\t   lexer->macro);\n\taddToScope(scope, lexer->token_str);\n\n\tadvanceToken(lexer, true);\n\n\tskipUntil(lexer, goal_tokens, 1);\n\n\tparseBlock(lexer, true, K_TRAIT, scope, false);\n}\n\n/* Skips type blocks of the form <T:T<T>, ...> */\nstatic void skipTypeBlock (lexerState *lexer)\n{\n\tif (lexer->cur_token == '<')\n\t{\n\t\tskipUntil(lexer, NULL, 0);\n\t\tadvanceToken(lexer, true);\n\t}\n}\n\n/* Essentially grabs the last ident before 'for', '<' and '{', which\n * tends to correspond to what we want as the impl tag entry name */\nstatic void parseQualifiedType (lexerState *lexer, vString* name)\n{\n\twhile (lexer->cur_token != TOKEN_EOF)\n\t{\n\t\tif (lexer->cur_token == TOKEN_IDENT)\n\t\t{\n\t\t\tif (tokenLitEq (lexer, \"for\")\n\t\t\t\t|| tokenLitEq (lexer, \"where\"))\n\t\t\t\tbreak;\n\t\t\tvStringClear(name);\n\t\t\tvStringCat(name, lexer->token_str);\n\t\t}\n\t\telse if (lexer->cur_token == '<' || lexer->cur_token == '{')\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\tadvanceToken(lexer, true);\n\t}\n\tskipTypeBlock(lexer);\n}\n\n/* Impl format:\n * \"impl\" [<type_bounds>] <qualified_ident>[<type_bounds>] [\"for\" <qualified_ident>[<type_bounds>]] \"{\" [<body>] \"}\"\n */\nstatic void parseImpl (lexerState *lexer, vString *scope, int parent_kind)\n{\n\tunsigned long line;\n\tMIOPos pos;\n\tvString *name;\n\n\tadvanceToken(lexer, true);\n\n\tline = lexer->line;\n\tpos = lexer->pos;\n\n\tskipTypeBlock(lexer);\n\n\tname = vStringNew();\n\n\tparseQualifiedType(lexer, name);\n\n\tif (lexer->cur_token == TOKEN_IDENT && tokenLitEq (lexer, \"for\"))\n\t{\n\t\tadvanceToken(lexer, true);\n\t\tparseQualifiedType(lexer, name);\n\t}\n\n\taddTag(name, NULL, K_IMPL, line, pos, scope, parent_kind,\n\t\t   lexer->macro);\n\taddToScope(scope, name);\n\n\tparseBlock(lexer, true, K_IMPL, scope, false);\n\n\tvStringDelete(name);\n}\n\n/* Static format:\n * \"static\" [\"mut\"] <ident>\n */\nstatic void parseStatic (lexerState *lexer, vString *scope, int parent_kind)\n{\n\tTRACE_ENTER();\n\n\tadvanceToken(lexer, true);\n\tif (lexer->cur_token != TOKEN_IDENT)\n\t{\n\t\tTRACE_LEAVE_TEXT(\"no identifier (0)\");\n\t\treturn;\n\t}\n\tif (tokenLitEq (lexer, \"mut\"))\n\t{\n\t\tadvanceToken(lexer, true);\n\t}\n\tif (lexer->cur_token != TOKEN_IDENT)\n\t{\n\t\tTRACE_LEAVE_TEXT(\"no identifier (1)\");\n\t\treturn;\n\t}\n\n\taddTag(lexer->token_str, NULL, K_STATIC, lexer->line, lexer->pos, scope, parent_kind,\n\t\t   lexer->macro);\n\n\tTRACE_LEAVE();\n}\n\n/* Const format:\n * \"const\" <ident>\n */\nstatic void parseConst (lexerState *lexer, vString *scope, int parent_kind)\n{\n\tTRACE_ENTER();\n\n\tadvanceToken(lexer, true);\n\tif (lexer->cur_token != TOKEN_IDENT)\n\t{\n\t\tTRACE_LEAVE_TEXT(\"no identifier\");\n\t\treturn;\n\t}\n\tif (tokenLitEq (lexer, \"fn\"))\n\t{\n\t\tTRACE_LEAVE_TEXT(\"fn follows\");\n\t\treturn;\n\t}\n\n\taddTag(lexer->token_str, NULL, K_CONST, lexer->line, lexer->pos, scope, parent_kind,\n\t\t   lexer->macro);\n\n\tTRACE_LEAVE();\n}\n\n/* Type format:\n * \"type\" <ident>\n */\nstatic void parseType (lexerState *lexer, vString *scope, int parent_kind)\n{\n\tTRACE_ENTER();\n\n\tadvanceToken(lexer, true);\n\tif (lexer->cur_token != TOKEN_IDENT)\n\t{\n\t\tTRACE_LEAVE_TEXT(\"no identifier\");\n\t\treturn;\n\t}\n\n\taddTag(lexer->token_str, NULL, K_TYPE, lexer->line, lexer->pos, scope, parent_kind,\n\t\t   lexer->macro);\n\n\tTRACE_LEAVE();\n}\n\n/* Structs and enums are very similar syntax-wise.\n * It is possible to parse variants a bit more cleverly (e.g. make tuple variants functions and\n * struct variants structs) but it'd be too clever and the signature wouldn't make too much sense without\n * the enum's definition (e.g. for the type bounds)\n *\n * Struct/Enum format:\n * \"struct/enum\" <ident>[<type_bounds>] \"{\" [<ident>,]+ \"}\"\n * \"struct/enum\" <ident>[<type_bounds>] \";\"\n * */\nstatic void parseStructOrEnum (lexerState *lexer, vString *scope, int parent_kind, bool is_struct)\n{\n\tTRACE_ENTER();\n\n\tint kind = is_struct ? K_STRUCT : K_ENUM;\n\tint field_kind = is_struct ? K_FIELD : K_VARIANT;\n\tint goal_tokens1[] = {';', '{'};\n\n\tadvanceToken(lexer, true);\n\tif (lexer->cur_token != TOKEN_IDENT)\n\t{\n\t\tTRACE_LEAVE_TEXT(\"no identifier\");\n\t\treturn;\n\t}\n\n\taddTag(lexer->token_str, NULL, kind, lexer->line, lexer->pos, scope, parent_kind,\n\t\t   lexer->macro);\n\taddToScope(scope, lexer->token_str);\n\n\tskipUntil(lexer, goal_tokens1, 2);\n\n\tif (lexer->cur_token == '{')\n\t{\n\t\tvString *field_name = vStringNew();\n\t\twhile (lexer->cur_token != TOKEN_EOF)\n\t\t{\n\t\t\tint goal_tokens2[] = {'}', ','};\n\t\t\t/* Skip attributes. Format:\n\t\t\t * #[..] or #![..]\n\t\t\t * */\n\t\t\tif (lexer->cur_token == '#')\n\t\t\t{\n\t\t\t\tadvanceToken(lexer, true);\n\t\t\t\tif (lexer->cur_token == '!')\n\t\t\t\t\tadvanceToken(lexer, true);\n\t\t\t\tif (lexer->cur_token == '[')\n\t\t\t\t{\n\t\t\t\t\t/* It's an attribute, skip it. */\n\t\t\t\t\tskipUntil(lexer, NULL, 0);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* Something's up with this field, skip to the next one */\n\t\t\t\t\tskipUntil(lexer, goal_tokens2, 2);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (lexer->cur_token == TOKEN_IDENT)\n\t\t\t{\n\t\t\t\tif (tokenLitEq (lexer, \"priv\")\n\t\t\t\t    || tokenLitEq (lexer, \"pub\"))\n\t\t\t\t{\n\t\t\t\t\tadvanceToken(lexer, true);\n\n\t\t\t\t\t/* Skip thevisibility specificaions.\n\t\t\t\t\t * https://doc.rust-lang.org/reference/visibility-and-privacy.html */\n\t\t\t\t\tif (lexer->cur_token == '(')\n\t\t\t\t\t{\n\t\t\t\t\t\tadvanceToken(lexer, true);\n\t\t\t\t\t\tskipUntil (lexer, (int []){')'}, 1);\n\t\t\t\t\t\tadvanceToken(lexer, true);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (lexer->cur_token != TOKEN_IDENT)\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Something's up with this field, skip to the next one */\n\t\t\t\t\t\tskipUntil(lexer, goal_tokens2, 2);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvStringClear(field_name);\n\t\t\t\tvStringCat(field_name, lexer->token_str);\n\t\t\t\taddTag(field_name, NULL, field_kind, lexer->line, lexer->pos, scope, kind,\n\t\t\t\t\t   lexer->macro);\n\t\t\t\tskipUntil(lexer, goal_tokens2, 2);\n\t\t\t}\n\t\t\tif (lexer->cur_token == '}')\n\t\t\t{\n\t\t\t\tadvanceToken(lexer, true);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tadvanceToken(lexer, true);\n\t\t}\n\t\tvStringDelete(field_name);\n\t}\n\n\tTRACE_LEAVE();\n}\n\n/* Skip the body of the macro. Can't use skipUntil here as\n * the body of the macro may have arbitrary code which confuses it (e.g.\n * bitshift operators/function return arrows) */\nstatic void skipMacro (lexerState *lexer)\n{\n\tTRACE_ENTER();\n\n\tint level = 0;\n\tint plus_token = 0;\n\tint minus_token = 0;\n\n\tadvanceToken(lexer, true);\n\tswitch (lexer->cur_token)\n\t{\n\t\tcase '(':\n\t\t\tplus_token = '(';\n\t\t\tminus_token = ')';\n\t\t\tbreak;\n\t\tcase '{':\n\t\t\tplus_token = '{';\n\t\t\tminus_token = '}';\n\t\t\tbreak;\n\t\tcase '[':\n\t\t\tplus_token = '[';\n\t\t\tminus_token = ']';\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tTRACE_LEAVE_TEXT(\"unexpected cur_token: %d\", lexer->cur_token);\n\t\t\treturn;\n\t}\n\n\twhile (lexer->cur_token != TOKEN_EOF)\n\t{\n\t\tif (lexer->cur_token == plus_token)\n\t\t\tlevel++;\n\t\telse if (lexer->cur_token == minus_token)\n\t\t\tlevel--;\n\t\tif (level == 0)\n\t\t\tbreak;\n\t\tadvanceToken(lexer, true);\n\t}\n\tadvanceToken(lexer, true);\n\n\tTRACE_LEAVE();\n}\n\n/*\n * Macro rules format:\n * \"macro_rules\" \"!\" <ident> <macro_body>\n */\nstatic void parseMacroRules (lexerState *lexer, vString *scope, int parent_kind)\n{\n\tTRACE_ENTER();\n\n\tadvanceToken(lexer, true);\n\n\tif (lexer->cur_token != '!')\n\t{\n\t\tTRACE_LEAVE_TEXT(\"no bang '!'\");\n\t\treturn;\n\t}\n\n\tadvanceToken(lexer, true);\n\n\tif (lexer->cur_token != TOKEN_IDENT)\n\t{\n\t\tTRACE_LEAVE_TEXT(\"no identifier\");\n\t\treturn;\n\t}\n\n\taddTag(lexer->token_str, NULL, K_MACRO, lexer->line, lexer->pos, scope, parent_kind,\n\t\t   lexer->macro);\n\n\tskipMacro(lexer);\n\n\tTRACE_LEAVE();\n}\n\n/*\n * Rust is very liberal with nesting, so this function is used pretty much for any block\n */\nstatic void parseBlock (lexerState *lexer, bool delim, int kind, vString *scope,\n\t\t\t\t\t\tbool as_token_tree)\n{\n\tTRACE_ENTER();\n\n\tint level = 1;\n\tif (delim)\n\t{\n\t\tif (as_token_tree)\n\t\t{\n\t\t\tif (lexer->cur_token != '{'\n\t\t\t\t&& lexer->cur_token != '('\n\t\t\t\t&& lexer->cur_token != '[')\n\t\t\t{\n\t\t\t\tTRACE_LEAVE_TEXT(\"no opening characters '{[('\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\telse if (lexer->cur_token != '{')\n\t\t{\n\t\t\tTRACE_LEAVE_TEXT(\"no opening curly bracket '{'\");\n\t\t\treturn;\n\t\t}\n\t\tadvanceToken(lexer, true);\n\t}\n\twhile (lexer->cur_token != TOKEN_EOF)\n\t{\n\t\tif (lexer->cur_token == TOKEN_IDENT)\n\t\t{\n\t\t\tsize_t old_scope_len = vStringLength(scope);\n\t\t\tif (tokenLitEq (lexer, \"fn\"))\n\t\t\t{\n\t\t\t\tparseFn(lexer, scope, kind);\n\t\t\t}\n\t\t\telse if (tokenLitEq (lexer, \"mod\"))\n\t\t\t{\n\t\t\t\tparseMod(lexer, scope, kind);\n\t\t\t}\n\t\t\telse if (tokenLitEq (lexer, \"static\"))\n\t\t\t{\n\t\t\t\tparseStatic(lexer, scope, kind);\n\t\t\t}\n\t\t\telse if (tokenLitEq (lexer, \"const\"))\n\t\t\t{\n\t\t\t\tparseConst(lexer, scope, kind);\n\t\t\t}\n\t\t\telse if (tokenLitEq (lexer, \"trait\"))\n\t\t\t{\n\t\t\t\tparseTrait(lexer, scope, kind);\n\t\t\t}\n\t\t\telse if (tokenLitEq (lexer, \"type\"))\n\t\t\t{\n\t\t\t\tparseType(lexer, scope, kind);\n\t\t\t}\n\t\t\telse if (tokenLitEq (lexer, \"impl\"))\n\t\t\t{\n\t\t\t\tparseImpl(lexer, scope, kind);\n\t\t\t}\n\t\t\telse if (tokenLitEq (lexer, \"struct\"))\n\t\t\t{\n\t\t\t\tparseStructOrEnum(lexer, scope, kind, true);\n\t\t\t}\n\t\t\telse if (tokenLitEq (lexer, \"enum\"))\n\t\t\t{\n\t\t\t\tparseStructOrEnum(lexer, scope, kind, false);\n\t\t\t}\n\t\t\telse if (tokenLitEq (lexer, \"macro_rules\"))\n\t\t\t{\n\t\t\t\tparseMacroRules(lexer, scope, kind);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvString* macro = vStringNewCopy (lexer->token_str);\n\n\t\t\t\tadvanceToken(lexer, true);\n\t\t\t\tif (lexer->cur_token == '!')\n\t\t\t\t{\n\t\t\t\t\tconst char *last_macro = swapMacroInvocation (lexer,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  vStringValue (macro));\n\t\t\t\t\tadvanceToken(lexer, true);\n\t\t\t\t\tparseBlock(lexer, true, kind, scope, true);\n\t\t\t\t\tswapMacroInvocation (lexer, last_macro);\n\t\t\t\t}\n\t\t\t\tvStringDelete (macro);\n\t\t\t}\n\t\t\tresetScope(scope, old_scope_len);\n\t\t}\n\t\telse if (lexer->cur_token == '{'\n\t\t\t\t || (as_token_tree\n\t\t\t\t\t && (lexer->cur_token == '('\n\t\t\t\t\t\t || lexer->cur_token == '[')))\n\t\t{\n\t\t\tlevel++;\n\t\t\tadvanceToken(lexer, true);\n\t\t}\n\t\telse if (lexer->cur_token == '}'\n\t\t\t\t || (as_token_tree\n\t\t\t\t\t && (lexer->cur_token == ')'\n\t\t\t\t\t\t || lexer->cur_token == ']')))\n\t\t{\n\t\t\tlevel--;\n\t\t\tadvanceToken(lexer, true);\n\t\t}\n\t\telse if (lexer->cur_token == '\\'')\n\t\t{\n\t\t\t/* Skip over the 'static lifetime, as it confuses the static parser above */\n\t\t\tadvanceToken(lexer, true);\n\t\t\tif (lexer->cur_token == TOKEN_IDENT && tokenLitEq (lexer, \"static\"))\n\t\t\t\tadvanceToken(lexer, true);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tadvanceToken(lexer, true);\n\t\t}\n\t\tif (delim && level <= 0)\n\t\t\tbreak;\n\t}\n\n\tTRACE_LEAVE();\n}\n\nstatic void findRustTags (void)\n{\n\tTRACE_ENTER();\n\n\tlexerState lexer = {0};\n\tvString* scope = vStringNew();\n\tinitLexer(&lexer);\n\n\tparseBlock(&lexer, false, K_NONE, scope, false);\n\tvStringDelete(scope);\n\n\tdeInitLexer(&lexer);\n\n\tTRACE_LEAVE();\n}\n\nextern parserDefinition *RustParser (void)\n{\n\tstatic const char *const extensions[] = { \"rs\", NULL };\n\tparserDefinition *def = parserNew (\"Rust\");\n\tdef->kindTable = rustKinds;\n\tdef->kindCount = ARRAY_SIZE (rustKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findRustTags;\n\tdef->fieldTable = rustFields;\n\tdef->fieldCount = ARRAY_SIZE (rustFields);\n\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/scheme.c",
    "content": "/*\n*   Copyright (c) 2000-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Scheme language\n*   files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"parse.h\"\n\n#include \"x-lisp.h\"\n\n#include <ctype.h>\n#include <string.h>\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_UNKNOWN,\n\tK_FUNCTION, K_SET\n} schemeKind;\n\ntypedef enum {\n\tF_DEFINER,\n} schemeField;\n\nstatic fieldDefinition SchemeFields[] = {\n\t{ .name = \"definer\",\n\t  .description = \"the name of the function or macro that defines the unknown/Y-kind object\",\n\t  .enabled = true,\n\t  .version = 1 },\n};\n\nstatic kindDefinition SchemeKinds [] = {\n\t{ true, 'Y', \"unknown\", \"unknown type of definitions\",\n\t  .version = 1 },\n\t{ true, 'f', \"function\", \"functions\" },\n\t{ true, 's', \"set\",      \"sets\" }\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n/*\n*   FUNCTION DEFINITIONS\n*/\nstatic struct lispIsDefResult scheme_is_def (struct lispDialect *dialect,\n\t\t\t\t\t\t\t\t\t\t\t const unsigned char *strp)\n{\n\tbool cis = dialect->case_insensitive; /* Renaming for making code short */\n\n\tbool is_set = ( (strp [1] == 's' || (cis && strp [1] == 'S'))\n\t\t\t\t\t&& (strp [2] == 'e' || (cis && strp [2] == 'E'))\n\t\t\t\t\t&& (strp [3] == 't' || (cis && strp [3] == 'T'))\n\t\t\t\t\t&& (strp [4] == '!'));\n\tif (is_set)\n\t\treturn (struct lispIsDefResult){ .is_def = true, .kind = K_SET, };\n\n\treturn lispIsDef (dialect, strp);\n}\n\nstatic int scheme_hint2kind (struct lispKindHint *hint, const char *namespace CTAGS_ATTR_UNUSED)\n{\n\tint k = K_UNKNOWN;\n\tint n = vStringLength (hint->str) - 4;\n\n\tif (strncmp (vStringValue (hint->str) + 1, \"SET!\", 4) == 0)\n\t\treturn K_SET;\n\n\t/* 4 means strlen(\"(def\"). */\n#define EQN(X) strncmp(vStringValue (hint->str) + 4, &X[3], n) == 0\n\tswitch (n)\n\t{\n\tcase 3:\n\t\tif (EQN(\"DEFINE\"))\n\t\t\tk = K_FUNCTION;\n\t\tbreak;\n\n\t}\n\treturn k;\n}\n\nstatic void findSchemeTags (void)\n{\n\tstruct lispDialect scheme_dialect = {\n\t\t.definer2kind = scheme_hint2kind,\n\t\t.case_insensitive = true,\n\t\t.namespace_sep = 0,\n\t\t.unknown_kind = K_UNKNOWN,\n\t\t.definer_field = SchemeFields + F_DEFINER,\n\t\t.skip_initial_spaces = false,\n\t\t.lambda_syntax_sugar = true,\n\t\t.is_def = scheme_is_def,\n\t\t.get_it = lispGetIt,\n\t\t.scope = CORK_NIL,\n\t};\n\n\tfindLispTagsCommon (&scheme_dialect);\n}\n\nextern parserDefinition* SchemeParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"SCM\", \"SM\", \"sch\", \"scheme\", \"scm\", \"sm\", \"rkt\", NULL\n\t};\n\tstatic const char *const aliases [] = {\n\t\t\"gosh\", \"guile\", \"racket\", NULL\n\t};\n\tparserDefinition* def = parserNew (\"Scheme\");\n\tdef->kindTable      = SchemeKinds;\n\tdef->kindCount  = ARRAY_SIZE (SchemeKinds);\n\tdef->fieldTable = SchemeFields;\n\tdef->fieldCount = ARRAY_SIZE (SchemeFields);\n\tdef->extensions = extensions;\n\tdef->aliases    = aliases;\n\tdef->parser     = findSchemeTags;\n\tdef->useCork = CORK_QUEUE;\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/selinux-interface.c",
    "content": "/*\n*   Copyright (c) 2025 Masatake YAMATO\n*   Copyright (c) 2025 Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for *if files in SELinux policy definitions:\n*\n*   https://github.com/SELinuxProject/refpolicy/blob/main/policy/support/loadable_module.spt\n*\n*/\n\n#include \"general.h\"\t/* must always come first */\n\n#include <string.h>\n\n#include \"x-m4.h\"\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"read.h\"\n#include \"keyword.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n\ntypedef enum {\n\tINTERFACE_KIND,\n\tTEMPLATE_KIND,\n} autoconfKind;\n\nstatic kindDefinition SELinuxInterfaceKinds[] = {\n\t{ true, 'i', \"interface\", \"interfaces\" },\n\t{ true, 't', \"template\", \"templates\" },\n};\n\ntypedef enum {\n\tKEYWORD_interface,\n\tKEYWORD_template,\n} selinuxInterfaceKeywordId;\n\nstatic const keywordTable selinuxInterfaceKeywordTable[] = {\n\t{ \"interface\", KEYWORD_interface, },\n\t{ \"template\",  KEYWORD_template, },\n};\n\nstatic bool doesLineCommentStart (m4Subparser *m4 CTAGS_ATTR_UNUSED, int c, const char* token CTAGS_ATTR_UNUSED)\n{\n\treturn (c == '#');\n}\n\nstatic bool doesStringLiteralStart (m4Subparser *m4 CTAGS_ATTR_UNUSED, int c CTAGS_ATTR_UNUSED)\n{\n\t// return (c == '\"') || (c == '\\'') || (c == '`');\n\treturn false;\n}\n\nstatic bool doesWantToParseInsideQuotes (m4Subparser *m4 CTAGS_ATTR_UNUSED, intArray *indexStack CTAGS_ATTR_UNUSED)\n{\n\treturn false;\n}\n\nstatic int makeSELinuxInterfaceTag (int kind)\n{\n\tint index = CORK_NIL;\n\tvString * name;\n\n\tname = vStringNew();\n\treadM4MacroArgument(name);\n\tif (vStringLength (name) > 0)\n\t\tindex = makeSimpleTag(name, kind);\n\tvStringDelete (name);\n\n\treturn index;\n}\n\nstatic int newMacroCallback (m4Subparser *m4 CTAGS_ATTR_UNUSED, const char* token)\n{\n\tint keyword;\n\tint index = CORK_NIL;\n\n\tkeyword = lookupKeyword (token, getInputLanguage ());\n\n\tswitch (keyword)\n\t{\n\tcase KEYWORD_NONE:\n\t\tbreak;\n\tcase KEYWORD_interface:\n\t\tindex = makeSELinuxInterfaceTag (INTERFACE_KIND);\n\t\tbreak;\n\tcase KEYWORD_template:\n\t\tindex = makeSELinuxInterfaceTag (TEMPLATE_KIND);\n\t\tbreak;\n\tdefault:\n\t\tAssertNotReached ();\n\t}\n\treturn index;\n}\n\nstatic void findSELinuxInterfaceTags(void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* SELinuxInterfaceParser (void)\n{\n\tstatic const char *const extensions [] = { \"if\", NULL };\n\tparserDefinition* const def = parserNew(\"SELinuxInterface\");\n\n\tstatic m4Subparser selinuxInterfaceSubparser = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t},\n\t\t.probeLanguage  = NULL,\n\t\t.newMacroNotify = newMacroCallback,\n\t\t.doesLineCommentStart = doesLineCommentStart,\n\t\t.doesStringLiteralStart = doesStringLiteralStart,\n\t\t.doesWantToParseInsideQuotes = doesWantToParseInsideQuotes,\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"M4\", &selinuxInterfaceSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = SELinuxInterfaceKinds;\n\tdef->kindCount = ARRAY_SIZE(SELinuxInterfaceKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findSELinuxInterfaceTags;\n\tdef->useCork = CORK_QUEUE;\n\n\tdef->keywordTable = selinuxInterfaceKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (selinuxInterfaceKeywordTable);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/sh.c",
    "content": "/*\n*   Copyright (c) 2000-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for scripts for the\n*   Bourne shell (and its derivatives, the Korn and Z shells).\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"promise.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n\n#include \"x-sh.h\"\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_SUBPARSER = -2,\n\tK_NOTHING = -1,\t\t/* place holder. Never appears on tags file. */\n\tK_ALIAS,\n\tK_FUNCTION,\n\tK_SCRIPT,\n\tK_HEREDOCLABEL,\n} shKind;\n\ntypedef enum {\n\tR_SCRIPT_LOADED,\n\tLAST_R_SCRIPT,\n} shScriptRole;\n\ntypedef enum {\n\tR_ZSH_SCRIPT_AUTOLOADED = LAST_R_SCRIPT,\n} zshScriptRole;\n\n#define SH_SCRIPT_ROLES_COMMON \t{ true, \"loaded\", \"loaded\" }\nstatic roleDefinition ShScriptRoles [] = {\n\tSH_SCRIPT_ROLES_COMMON,\n};\n\nstatic roleDefinition ZshScriptRoles [] = {\n\tSH_SCRIPT_ROLES_COMMON,\n\t{ true, \"autoloaded\", \"autoloaded\" },\n};\n\ntypedef enum {\n\tR_HEREDOC_ENDMARKER,\n} shHeredocRole;\n\n#define SH_HEREDOC_ROLES_COMMON { true, \"endmarker\", \"end marker\" }\nstatic roleDefinition ShHeredocRoles [] = {\n\tSH_HEREDOC_ROLES_COMMON,\n};\n\nstatic roleDefinition ZshHeredocRoles [] = {\n\tSH_HEREDOC_ROLES_COMMON,\n};\n\ntypedef enum {\n\tR_ZSH_FUNCTION_AUTOLOADED,\n} zshFunctionRole;\n\nstatic roleDefinition ZshFunctionRoles [] = {\n\t{ true, \"autoloaded\", \"function name passed to autoload built-in command\" },\n};\n\n#define SH_KINDS_COMMON(SCRIPT_ROLES,HEREDOC_ROLES, FUNCTION_ROLES_SPEC) \\\n\t{ true, 'a', \"alias\", \"aliases\"},\t\t\t\t\t\t\t\\\n\t{ true, 'f', \"function\", \"functions\",\t\t\t\t\t\t\\\n\t  .referenceOnly = false, FUNCTION_ROLES_SPEC },\t\t\t\\\n\t{ true, 's', \"script\", \"script files\",\t\t\t\t\t\t\\\n\t  .referenceOnly = true, ATTACH_ROLES (SCRIPT_ROLES) },\t\t\\\n\t{ true, 'h', \"heredoc\", \"label for here document\",\t\t\t\\\n\t  .referenceOnly = false, ATTACH_ROLES (HEREDOC_ROLES) }\n\nstatic kindDefinition ShKinds [] = {\n\tSH_KINDS_COMMON(ShScriptRoles, ShHeredocRoles,),\n};\n\nstatic kindDefinition ZshKinds [] = {\n\tSH_KINDS_COMMON(ZshScriptRoles, ZshHeredocRoles,\n\t\t\t\t\tATTACH_ROLES(ZshFunctionRoles)),\n};\n\nenum eShKeywordId {\n\tKEYWORD_function,\n\tKEYWORD_alias,\n\tKEYWORD_source,\n\tKEYWORD_autoload,\n};\n\nconst char *dialectMap [] = {\n\t\"Sh\", \"Zsh\",\n};\n\nstatic const struct dialectalKeyword KeywordTable [] = {\n\t{ \"function\",  KEYWORD_function, { 1, 1 } },\n\t{ \"alias\",     KEYWORD_alias,    { 1, 1 } },\n\t{ \"source\",    KEYWORD_source,   { 1, 1 } },\n\t{ \"autoload\",  KEYWORD_autoload, { 0, 1 } },\n};\n\n/*\n* FUNCTION DECLARATIONS\n*/\nstatic subparser *notifyLineToSubparsers (const unsigned char *cp,\n\t\t\t\t\t\t\t\t\t\t  int *n);\nstatic int extractNameToSubparser (subparser *sub, const unsigned char *cp,\n\t\t\t\t\t\t\t\t   vString *name);\nstatic int makeTagInSubparser (subparser *sub, vString *name);\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic bool isFileChar  (int c)\n{\n\treturn (isalnum (c)\n\t\t|| c == '_' || c == '-'\n\t\t|| c == '/' || c == '.'\n\t\t|| c == '+' || c == '^'\n\t\t|| c == '%' || c == '@'\n\t\t|| c == '~');\n}\n\nstatic bool isIdentChar0 (int c)\n{\n\treturn (isalpha (c) || c == '_' || c == '-');\n}\n\nstatic bool isIdentChar (int c)\n{\n\treturn (isalnum (c) || c == '_' || c == '-');\n}\n\n/* bash allows all kinds of crazy stuff as the identifier after 'function' */\nstatic bool isBashFunctionChar (int c)\n{\n\treturn (c > 1 /* NUL and SOH are disallowed */ && c != 0x7f &&\n\t        /* blanks are disallowed, but VT and FF (and CR to some extent, but\n\t         * let's not fall into the pit of craziness) */\n\t        c != ' ' && c != '\\t' && c != '\\n' && c != '\\r' &&\n\t        c != '\"' && c != '\\'' && c != '$' && c != '`' && c != '\\\\' &&\n\t        c != '&' && c != ';' &&\n\t        c != '(' && c != ')' &&\n\t        c != '<' && c != '>');\n}\n\nstatic const unsigned char *skipDoubleString (const unsigned char *cp)\n{\n\tconst unsigned char* prev = cp;\n\tcp++;\n\twhile ((*cp != '\"' || *prev == '\\\\') && *cp != '\\0')\n\t{\n\t\tprev = cp;\n\t\tcp++;\n\t}\n\treturn cp;\n}\n\nstatic const unsigned char *skipSingleString (const unsigned char *cp)\n{\n\tcp++;\n\twhile (*cp != '\\'' && *cp != '\\0')\n\t\tcp++;\n\treturn cp;\n}\n\nstatic bool isEnvCommand (const vString *cmd)\n{\n\tconst char *lc = vStringValue(cmd);\n\tconst char * tmp = baseFilename (lc);\n\n\treturn (strcmp(tmp, \"env\") == 0);\n}\n\nstatic int readDestfileName (const unsigned char *cp, vString *destfile)\n{\n\tconst unsigned char *origin = cp;\n\n\twhile (isspace (*cp))\n\t\t++cp;\n\n\t/* >... */\n\tif (*cp != '>')\n\t\treturn 0;\n\n\t/* >>... */\n\tif (*cp == '>')\n\t\t++cp;\n\n\twhile (isspace (*cp))\n\t\t++cp;\n\n\tif (!isFileChar (*cp))\n\t\treturn 0;\n\n\tvStringClear(destfile);\n\tdo {\n\t\tvStringPut (destfile, *cp);\n\t\t++cp;\n\t} while (isFileChar (*cp));\n\n\tif (vStringLength(destfile) > 0)\n\t\treturn cp - origin;\n\n\treturn 0;\n}\n\nstruct hereDocParsingState {\n\tvString *args[2];\n\tvString *destfile;\n\tlangType sublang;\n\tunsigned long startLine;\n\n\tint corkIndex;\n};\n\nstatic void hdocStateInit (struct hereDocParsingState *hstate)\n{\n\thstate->args[0] = vStringNew ();\n\thstate->args[1] = vStringNew ();\n\thstate->destfile = vStringNew ();\n\n\thstate->corkIndex = CORK_NIL;\n\thstate->sublang = LANG_IGNORE;\n}\n\nstatic void hdocStateClear (struct hereDocParsingState *hstate)\n{\n\tvStringClear (hstate->args[0]);\n\tvStringClear (hstate->args[1]);\n\tvStringClear (hstate->destfile);\n}\n\nstatic void hdocStateFini (struct hereDocParsingState *hstate)\n{\n\tvStringDelete (hstate->args[0]);\n\tvStringDelete (hstate->args[1]);\n\tvStringDelete (hstate->destfile);\n}\n\nstatic void hdocStateUpdateArgs (struct hereDocParsingState *hstate,\n\t\t\t\t\t\t\t\t\t\t   vString *name)\n{\n\tif (vStringIsEmpty(hstate->args[0]))\n\t\tvStringCopy(hstate->args[0], name);\n\telse if (vStringIsEmpty(hstate->args[1]))\n\t\tvStringCopy(hstate->args[1], name);\n}\n\nstatic void hdocStateMakePromiseMaybe (struct hereDocParsingState *hstate)\n{\n\tif (hstate->sublang != LANG_IGNORE)\n\t\tmakePromise (getLanguageName(hstate->sublang),\n\t\t\t\t\t hstate->startLine, 0,\n\t\t\t\t\t getInputLineNumber(), 0,\n\t\t\t\t\t 0);\n\thstate->sublang = LANG_IGNORE;\n}\n\nstatic void hdocStateRecordStartlineFromDestfileMaybe (struct hereDocParsingState *hstate)\n{\n\tconst char *f = vStringValue(hstate->destfile);\n\n\tif (hstate->sublang != LANG_IGNORE)\n\t\treturn;\n\n\thstate->sublang = getLanguageForFilename (f, 0);\n\tif (hstate->sublang != LANG_IGNORE)\n\t\thstate->startLine = getInputLineNumber () + 1;\n\tvStringClear (hstate->destfile);\n}\n\nstatic void hdocStateRecordStatelineMaybe (struct hereDocParsingState *hstate)\n{\n\tif (!vStringIsEmpty(hstate->args[0]))\n\t{\n\t\tconst char *cmd;\n\n\t\tcmd = vStringValue(hstate->args[0]);\n\t\tif (isEnvCommand (hstate->args[0]))\n\t\t{\n\t\t\tcmd = NULL;\n\t\t\tif (!vStringIsEmpty(hstate->args[1]))\n\t\t\t\tcmd = vStringValue(hstate->args[1]);\n\t\t}\n\n\t\tif (cmd)\n\t\t{\n\t\t\thstate->sublang = getLanguageForCommand (cmd, 0);\n\t\t\tif (hstate->sublang != LANG_IGNORE)\n\t\t\t\thstate->startLine = getInputLineNumber () + 1;\n\t\t}\n\t}\n\n\tif (vStringLength(hstate->destfile) > 0)\n\t\thdocStateRecordStartlineFromDestfileMaybe (hstate);\n}\n\nstatic int hdocStateReadDestfileName (struct hereDocParsingState *hstate,\n\t\t\t\t\t\t\t\t\t  const unsigned char* cp,\n\t\t\t\t\t\t\t\t\t  const vString *const hereDocDelimiter)\n{\n\tint d = readDestfileName (cp, hstate->destfile);\n\n\tif (d > 0 && hereDocDelimiter)\n\t\thdocStateRecordStartlineFromDestfileMaybe (hstate);\n\n\treturn d;\n}\n\nstatic void hdocStateUpdateTag (struct hereDocParsingState *hstate, unsigned long endLine)\n{\n\tif (hstate->corkIndex == CORK_NIL)\n\t\treturn;\n\n\tsetTagEndLineToCorkEntry (hstate->corkIndex, endLine);\n\tregisterEntry (hstate->corkIndex);\n\thstate->corkIndex = CORK_NIL;\n}\n\nstatic size_t handleShKeyword (int keyword,\n\t\t\t\t\t\t\t   vString *token,\n\t\t\t\t\t\t\t   int *kind,\n\t\t\t\t\t\t\t   int *role,\n\t\t\t\t\t\t\t   bool (** check_char)(int))\n{\n\tswitch (keyword)\n\t{\n\tcase KEYWORD_function:\n\t\t*kind = K_FUNCTION;\n\t\tbreak;\n\tcase KEYWORD_alias:\n\t\t*kind = K_ALIAS;\n\t\t*check_char = isIdentChar;\n\t\tbreak;\n\tcase KEYWORD_source:\n\t\t*kind = K_SCRIPT;\n\t\t*role = R_SCRIPT_LOADED;\n\t\t*check_char = isFileChar;\n\t\tbreak;\n\tdefault:\n\t\tAssertNotReached();\n\t\tbreak;\n\t}\n\n\treturn vStringLength(token);\n}\n\nstatic int makeShAliasTag(vString *name, const unsigned char ** cp, const char *options)\n{\n\tconst unsigned char *p = *cp;\n\tint r = CORK_NIL;\n\n\tconst char *opt = vStringValue (name);\n\tif (opt[0] == '-')\n\t{\n\t\tif  (strpbrk(opt, options))\n\t\t\treturn CORK_NIL;\n\n\t\tvStringClear(name);\n\n\t\twhile (isspace (*p))\n\t\t\tp++;\n\n\t\twhile (*p && isIdentChar (*p))\n\t\t\tvStringPut (name, *p++);\n\t}\n\n\tif (!vStringIsEmpty(name) && *p == '=')\n\t\tr = makeSimpleTag (name, K_ALIAS);\n\t*cp = p;\n\treturn r;\n}\n\nstatic int makeShTag (vString *name, const unsigned char ** cp,\n\t\t\t\t\t  int found_kind, int found_role)\n{\n\tif (found_kind == K_ALIAS && found_role == ROLE_DEFINITION_INDEX)\n\t\t/* -p is for printing defined aliases in bash. */\n\t\treturn makeShAliasTag (name, cp, \"p\");\n\n\treturn makeSimpleRefTag (name, found_kind, found_role);\n}\n\nstatic int makeZshAutoloadTag(vString *name, const unsigned char ** cp)\n{\n\tconst unsigned char *p = *cp;\n\n\tint r = CORK_NIL;\n\tdo\n\t{\n\t\tif (vStringChar(name, 0) != '-' && vStringChar(name, 0) != '+')\n\t\t{\n\t\t\tdo\n\t\t\t{\n\t\t\t\tr = makeSimpleRefTag (name, K_SCRIPT, R_ZSH_SCRIPT_AUTOLOADED);\n\n\t\t\t\ttagEntryInfo e;\n\t\t\t\tconst char *func = strrchr(vStringValue (name), '/');\n\t\t\t\tfunc = func? func + 1: vStringValue (name);\n\t\t\t\tif (*func != '\\0')\n\t\t\t\t{\n\t\t\t\t\tinitRefTagEntry (&e, func, K_FUNCTION, R_ZSH_FUNCTION_AUTOLOADED);\n\t\t\t\t\tr = makeTagEntry(&e);\n\t\t\t\t}\n\n\t\t\t\twhile (isspace (*p))\n\t\t\t\t\tp++;\n\n\t\t\t\tif (*p == '\\0')\n\t\t\t\t\tbreak;\n\n\t\t\t\tvStringClear (name);\n\t\t\t\twhile (*p != '\\0' && !isspace (*p))\n\t\t\t\t\tvStringPut (name, *p++);\n\t\t\t}\n\t\t\twhile (1);\n\t\t\tbreak;\n\t\t}\n\n\t\tif (*p == '\\0')\n\t\t\tbreak;\n\n\t\tvStringClear(name);\n\t\twhile (*p != '\\0' && !isspace(*p))\n\t\t\tvStringPut (name, *p++);\n\n\t\twhile (isspace (*p))\n\t\t\t++p;\n\t}\n\twhile (1);\n\n\t*cp = p;\n\treturn r;\n}\n\nstatic int makeZshFunctionTag(vString *name, const unsigned char ** cp)\n{\n\tconst unsigned char *p = *cp;\n\n\tint r = CORK_NIL;\n\n\tif (strcmp(vStringValue(name), \"-T\") == 0)\n\t{\n\t\tvStringClear(name);\n\n\t\twhile (isspace (*p))\n\t\t\tp++;\n\n\t\twhile (isBashFunctionChar (*p))\n\t\t{\n\t\t\tvStringPut (name, *p);\n\t\t\t++p;\n\t\t}\n\t}\n\n\tif (!vStringIsEmpty(name))\n\t\tr = makeSimpleTag (name, K_FUNCTION);\n\t*cp = p;\n\treturn r;\n}\n\nstatic int makeZshTag (vString *name, const unsigned char ** cp,\n\t\t\t\t\t  int found_kind, int found_role)\n{\n\tif (found_kind == K_SCRIPT && found_role == R_ZSH_SCRIPT_AUTOLOADED)\n\t\treturn makeZshAutoloadTag(name, cp);\n\n\tif (found_kind == K_FUNCTION && found_role == ROLE_DEFINITION_INDEX)\n\t\treturn makeZshFunctionTag(name, cp);\n\n\tif (found_kind == K_ALIAS && found_role == ROLE_DEFINITION_INDEX)\n\t\t/* -m, -r, and -L are for printing defined aliases. */\n\t\treturn makeShAliasTag (name, cp, \"mrL\");\n\n\treturn makeShTag (name, cp, found_kind, found_role);\n}\n\nstatic size_t handleZshKeyword (int keyword,\n\t\t\t\t\t\t\t\tvString *token,\n\t\t\t\t\t\t\t\tint *kind,\n\t\t\t\t\t\t\t\tint *role,\n\t\t\t\t\t\t\t\tbool (** check_char)(int))\n{\n\tswitch (keyword)\n\t{\n\tcase KEYWORD_autoload:\n\t\t*kind = K_SCRIPT;\n\t\t*role = R_ZSH_SCRIPT_AUTOLOADED;\n\t\tbreak;\n\tdefault:\n\t\treturn handleShKeyword (keyword, token, kind, role, check_char);\n\t}\n\n\treturn vStringLength(token);\n}\n\ntypedef bool (* checkCharFunc) (int);\nstatic void findShTagsCommon (size_t (* keyword_handler) (int,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  vString *,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  int *,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  int *,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  checkCharFunc *check_char),\n\t\t\t\t\t\t\t  int (* make_tag_handler) (vString *, const unsigned char **, int, int))\n\n{\n\tvString *name = vStringNew ();\n\tconst unsigned char *line;\n\tvString *hereDocDelimiter = NULL;\n\tbool hereDocIndented = false;\n\tcheckCharFunc check_char;\n\n\tstruct hereDocParsingState hstate;\n\thdocStateInit (&hstate);\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char* cp = line;\n\t\tint found_kind = K_NOTHING;\n\t\tint found_role = ROLE_DEFINITION_INDEX;\n\n\t\tif (hereDocDelimiter)\n\t\t{\n\t\t\tif (hereDocIndented)\n\t\t\t{\n\t\t\t\twhile (*cp == '\\t')\n\t\t\t\t\tcp++;\n\t\t\t}\n\t\t\tif ((strncmp ((const char *) cp, vStringValue (hereDocDelimiter), vStringLength (hereDocDelimiter)) == 0)\n\t\t\t\t&& ((*(cp + vStringLength (hereDocDelimiter)) == '\\0')\n\t\t\t\t\t|| isspace (*(cp + vStringLength (hereDocDelimiter)) )))\n\t\t\t{\n\t\t\t\thdocStateUpdateTag (&hstate, getInputLineNumber ());\n\t\t\t\thdocStateMakePromiseMaybe (&hstate);\n\n\t\t\t\tif (!vStringIsEmpty(hereDocDelimiter))\n\t\t\t\t\tmakeSimpleRefTag(hereDocDelimiter, K_HEREDOCLABEL, R_HEREDOC_ENDMARKER);\n\t\t\t\tvStringDelete (hereDocDelimiter);\n\t\t\t\thereDocDelimiter = NULL;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\thdocStateClear (&hstate);\n\t\twhile (*cp != '\\0')\n\t\t{\n\t\t\tsubparser *sub = NULL;\n\t\t\tint sub_n = 0;\n\n\t\t\t/* jump over whitespace */\n\t\t\twhile (isspace (*cp))\n\t\t\t\tcp++;\n\n\t\t\t/* jump over strings */\n\t\t\tif (*cp == '\"')\n\t\t\t\tcp = skipDoubleString (cp);\n\t\t\telse if (*cp == '\\'')\n\t\t\t\tcp = skipSingleString (cp);\n\t\t\t/* jump over comments */\n\t\t\telse if (*cp == '#')\n\t\t\t\tbreak;\n\t\t\t/* jump over here-documents */\n\t\t\telse if (cp[0] == '<' && cp[1] == '<')\n\t\t\t{\n\t\t\t\tconst unsigned char *start, *end;\n\t\t\t\tbool trimEscapeSequences = false;\n\t\t\t\tbool quoted = false;\n\t\t\t\tcp += 2;\n\t\t\t\t/* an optional \"-\" strips leading tabulations from the heredoc lines */\n\t\t\t\tif (*cp != '-')\n\t\t\t\t\thereDocIndented = false;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\thereDocIndented = true;\n\t\t\t\t\tcp++;\n\t\t\t\t}\n\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\tcp++;\n\t\t\t\tstart = end = cp;\n\t\t\t\t/* the delimiter can be surrounded by quotes */\n\t\t\t\tif (*cp == '\"')\n\t\t\t\t{\n\t\t\t\t\tstart++;\n\t\t\t\t\tend = cp = skipDoubleString (cp);\n\t\t\t\t\t/* we need not to worry about variable substitution, they\n\t\t\t\t\t * don't happen in heredoc delimiter definition */\n\t\t\t\t\ttrimEscapeSequences = true;\n\t\t\t\t\tquoted = true;\n\t\t\t\t}\n\t\t\t\telse if (*cp == '\\'')\n\t\t\t\t{\n\t\t\t\t\tstart++;\n\t\t\t\t\tend = cp = skipSingleString (cp);\n\t\t\t\t\tquoted = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\twhile (isIdentChar (*cp))\n\t\t\t\t\t\tcp++;\n\t\t\t\t\tend = cp;\n\t\t\t\t}\n\t\t\t\tif (end > start || quoted)\n\t\t\t\t{\n\t\t\t\t\t/* The input may be broken as a shell script but we need to avoid\n\t\t\t\t\t   memory leaking. */\n\t\t\t\t\tif (hereDocDelimiter)\n\t\t\t\t\t\tvStringClear(hereDocDelimiter);\n\t\t\t\t\telse\n\t\t\t\t\t\thereDocDelimiter = vStringNew ();\n\t\t\t\t\tfor (; end > start; start++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (trimEscapeSequences && *start == '\\\\')\n\t\t\t\t\t\t\tstart++;\n\t\t\t\t\t\tvStringPut (hereDocDelimiter, *start);\n\t\t\t\t\t}\n\t\t\t\t\tif (vStringLength(hereDocDelimiter) > 0)\n\t\t\t\t\t\thstate.corkIndex = makeSimpleTag(hereDocDelimiter, K_HEREDOCLABEL);\n\n\t\t\t\t\thdocStateRecordStatelineMaybe(&hstate);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcheck_char = isBashFunctionChar;\n\n\t\t\tif (cp [0] == '.'\n\t\t\t\t    && isspace(cp [1]))\n\t\t\t{\n\t\t\t\tfound_kind = K_SCRIPT;\n\t\t\t\tfound_role = R_SCRIPT_LOADED;\n\t\t\t\t++cp;\n\t\t\t\tcheck_char = isFileChar;\n\t\t\t}\n\t\t\telse if ((sub = notifyLineToSubparsers (cp, &sub_n)))\n\t\t\t{\n\t\t\t\tfound_kind = K_SUBPARSER;\n\t\t\t\tcp += sub_n;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvString *token = vStringNew ();\n\t\t\t\tconst unsigned char *tmp = cp;\n\t\t\t\twhile (*tmp && (tmp == cp\n\t\t\t\t\t\t\t\t? (isIdentChar0 (*tmp))\n\t\t\t\t\t\t\t\t: (isIdentChar (*tmp))))\n\t\t\t\t{\n\t\t\t\t\tvStringPut (token, *tmp);\n\t\t\t\t\ttmp++;\n\t\t\t\t}\n\n\t\t\t\tint keyword = lookupKeyword (vStringValue (token),\n\t\t\t\t\t\t\t\t\t\t\t getInputLanguage ());\n\t\t\t\tif (keyword != KEYWORD_NONE)\n\t\t\t\t\tcp += (* keyword_handler) (keyword, token,\n\t\t\t\t\t\t\t\t\t\t\t   &found_kind, &found_role, &check_char);\n\t\t\t\tvStringDelete (token);\n\t\t\t}\n\n\t\t\tif (found_kind != K_NOTHING)\n\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t++cp;\n\n\t\t\tif (found_kind == K_SUBPARSER)\n\t\t\t{\n\t\t\t\tsub_n = extractNameToSubparser (sub, cp, name);\n\t\t\t\tif (!vStringIsEmpty (name))\n\t\t\t\t\tcp += sub_n;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Get the name of the function, alias or file to be read by source\n\t\t\t\tif (! check_char (*cp))\n\t\t\t\t{\n\t\t\t\t\tfound_kind = K_NOTHING;\n\t\t\t\t\tfound_role = ROLE_DEFINITION_INDEX;\n\n\t\t\t\t\tint d = hdocStateReadDestfileName (&hstate, cp,\n\t\t\t\t\t\t\t\t\t\t\t\t\t   hereDocDelimiter);\n\t\t\t\t\tif (d > 0)\n\t\t\t\t\t\tcp += d;\n\t\t\t\t\telse if (*cp != '\\0')\n\t\t\t\t\t\t++cp;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\twhile (check_char (*cp))\n\t\t\t\t{\n\t\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t\t++cp;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twhile (isspace (*cp))\n\t\t\t\t++cp;\n\n\t\t\tif ((found_kind != K_SCRIPT)\n\t\t\t    && *cp == '(')\n\t\t\t{\n\t\t\t\t++cp;\n\t\t\t\twhile (isspace (*cp))\n\t\t\t\t\t++cp;\n\t\t\t\tif (*cp == ')')\n\t\t\t\t{\n\t\t\t\t\t/* A function definiton can look like an array initialization:\n\t\t\t\t\t *\n\t\t\t\t\t *   ... f=()\n\t\t\t\t\t *\n\t\t\t\t\t * We use followng heuristics to distinguish a function definition\n\t\t\t\t\t * from an array initialization:\n\t\t\t\t\t *\n\t\t\t\t\t *   preceding \"function\" keyword: function f=()\n\t\t\t\t\t *   followed by '{': f=() {\n\t\t\t\t\t *\n\t\t\t\t\t */\n\t\t\t\t\tif (! ((vStringLast(name) == '=')\n\t\t\t\t\t\t   /* Have we found \"function\" yet? */\n\t\t\t\t\t\t   && (found_kind != K_FUNCTION)\n\t\t\t\t\t\t   && (strchr ((char *)(cp + 1), '{') == NULL)))\n\t\t\t\t\t\tfound_kind = K_FUNCTION;\n\t\t\t\t\t++cp;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (found_kind != K_NOTHING)\n\t\t\t{\n\t\t\t\tif (found_kind == K_SUBPARSER)\n\t\t\t\t{\n\t\t\t\t\tif (!vStringIsEmpty (name))\n\t\t\t\t\t\tmakeTagInSubparser (sub, name);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tmake_tag_handler (name, &cp, found_kind, found_role);\n\t\t\t\tfound_kind = K_NOTHING;\n\t\t\t\tfound_role = ROLE_DEFINITION_INDEX;\n\t\t\t}\n\t\t\telse if (!hereDocDelimiter)\n\t\t\t\thdocStateUpdateArgs (&hstate, name);\n\t\t\tvStringClear (name);\n\t\t}\n\t}\n\thdocStateFini (&hstate);\n\tvStringDelete (name);\n\tif (hereDocDelimiter)\n\t\tvStringDelete (hereDocDelimiter);\n}\n\nstatic void findShTags (void)\n{\n\tfindShTagsCommon (handleShKeyword, makeShTag);\n}\n\nstatic void findZshTags (void)\n{\n\tfindShTagsCommon (handleZshKeyword, makeZshTag);\n}\n\nstatic subparser *notifyLineToSubparsers (const unsigned char *cp,\n\t\t\t\t\t\t\t\t\t\t  int *n)\n{\n\tint r = 0;\n\tsubparser *sub;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\tshSubparser *shsub = (shSubparser *)sub;\n\n\t\tif(shsub->lineNotify)\n\t\t{\n\t\t\tenterSubparser(sub);\n\t\t\tr = shsub->lineNotify (shsub, cp);\n\t\t\tleaveSubparser();\n\t\t\tif (r > 0)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (r > 0)\n\t{\n\t\t*n = r;\n\t\treturn sub;\n\t}\n\treturn NULL;\n}\n\nstatic int extractNameToSubparser(subparser *sub, const unsigned char *cp,\n\t\t\t\t\t\t\t\t  vString *name)\n{\n\tint n;\n\tshSubparser *shsub = (shSubparser *)sub;\n\n\tenterSubparser(sub);\n\tn = shsub->extractName(shsub, cp, name);\n\tleaveSubparser();\n\n\treturn n;\n}\n\nstatic int makeTagInSubparser (subparser *sub, vString *name)\n{\n\tint r;\n\tshSubparser *shsub = (shSubparser *)sub;\n\n\tenterSubparser(sub);\n\tr = shsub->makeTag(shsub, name);\n\tleaveSubparser();\n\n\treturn r;\n}\n\nstatic void initializeSh (const langType language)\n{\n\taddDialectalKeywords (KeywordTable, ARRAY_SIZE (KeywordTable),\n\t\t\t\t\t\t  language,\n\t\t\t\t\t\t  dialectMap, ARRAY_SIZE (dialectMap));\n}\n\nextern parserDefinition* ShParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"sh\", \"SH\", \"bsh\", \"bash\", \"ksh\", \"ash\", NULL\n\t};\n\tstatic const char *const aliases [] = {\n\t\t\"sh\", \"bash\", \"ksh\", \"ash\", \"dash\",\n\t\t/* major mode name in emacs */\n\t\t\"shell-script\",\n\t\tNULL\n\t};\n\tparserDefinition* def = parserNew (\"Sh\");\n\tdef->kindTable      = ShKinds;\n\tdef->kindCount  = ARRAY_SIZE (ShKinds);\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->parser     = findShTags;\n\tdef->initialize = initializeSh;\n\tdef->useCork    = CORK_QUEUE|CORK_SYMTAB;\n\treturn def;\n}\n\nextern parserDefinition* ZshParser (void)\n{\n\tstatic const char *const extensions [] = {\n\t\t\"zsh\", NULL\n\t};\n\tstatic const char *const aliases [] = {\n\t\t\"zsh\", NULL,\n\t};\n\tparserDefinition* def = parserNew (\"Zsh\");\n\tdef->kindTable      = ZshKinds;\n\tdef->kindCount  = ARRAY_SIZE (ZshKinds);\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->parser     = findZshTags;\n\tdef->initialize = initializeSh;\n\tdef->useCork    = CORK_QUEUE|CORK_SYMTAB;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/sinex.c",
    "content": "/*\n*   Copyright (c) 2025, Franck Reinquin <freinquin@free.fr>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Define tags by looking for block names in a SINEX file\n* \n*   The format is fairly simple :\n*   %=SNX <version and other details>\n*   +BLOCK_NAME\n*     content line 1\n*     content line 2\n*     ...\n*   -BLOCK_NAME\n*   \n*   SINEX blocks are stored one after another and are not nested. Comment\n*   lines start with '*' and can be present inside or outside blocks.\n*   \n*   The parser does not check the block names, its only goal is to register\n*   all blocks to help navigate in a text editor (e.g geany).\n* \n*   References :\n*   https://www.iers.org/SharedDocs/Publikationen/EN/IERS/Documents/ac/sinex/sinex_v202_pdf.pdf\n*/\n#include \"general.h\"\n\n#include <string.h>\n#include <ctype.h>\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n\n/* the SINEX standard sets a maximum line length of 80 chars ; a block name has\n * a '+'/'-' prefix so can be up to 79 characters long */\n#define MAX_BLOCK_NAME_LEN   79\n\ntypedef enum eSinexKinds {\n\tK_BLOCK\n} sinexKind;\n\nstatic kindDefinition SinexKinds [] = {\n\t{ true, 'b', \"block\",\t\t\"blocks\" }\n};\n\n\nstatic void blockNameCopy (char blockName[MAX_BLOCK_NAME_LEN+1], const char *line)\n{\n\tstrncpy (blockName, (const char *)&line[1], MAX_BLOCK_NAME_LEN);\n\tblockName[MAX_BLOCK_NAME_LEN] = '\\0'; /* THIS IS O.K. */\n\n\t// remove possible trailing spaces\n\tfor (char * ptr = blockName+strlen(blockName)-1 ; (ptr>=blockName) && isspace(*ptr) ; ptr--)\n\t\t*ptr = '\\0' ;\n}\n\n\nstatic void findSinexTags (void)\n{\n\tconst unsigned char *line;\n\ttagEntryInfo e;\n\tchar blockNameStart[MAX_BLOCK_NAME_LEN+1];\n\tchar blockNameEnd[MAX_BLOCK_NAME_LEN+1];\n\tbool inBlock = false ;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tif (line[0] == '+')\n\t\t{\n\t\t\tblockNameCopy(blockNameStart, (const char *)line);\n\t\t\tinitTagEntry (&e, (const char * const)blockNameStart, K_BLOCK);\n\t\t\tinBlock = true ;\n\t\t} \n\t\telse if (inBlock && (line[0] == '-'))\n\t\t{\n\t\t\tunsigned long lineNumber = getInputLineNumber ();\n\t\t\tblockNameCopy(blockNameEnd, (const char *)line);\n\t\t\tif (strcmp (blockNameStart, blockNameEnd) == 0)\n\t\t\t{\n\t\t\t\tsetTagEndLine(&e, lineNumber);\n\t\t\t\tmakeTagEntry (&e);\n\t\t\t\tinBlock = false ;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/* parser definition */\nextern parserDefinition* SinexParser (void)\n{\n\tstatic const char *const extensions [] = { \"snx\", \"sinex\", NULL };\n\tparserDefinition* def = parserNew (\"SINEX\");\n\tdef->kindTable  = SinexKinds;\n\tdef->kindCount  = ARRAY_SIZE (SinexKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findSinexTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/slang.c",
    "content": "/*\n *   Copyright (c) 2000-2001, Francesc Rocher\n *\n *   Author: Francesc Rocher <f.rocher@computer.org>.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for S-Lang files.\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"  /* must always come first */\n#include \"parse.h\"\n#include \"routines.h\"\n\nstatic tagRegexTable slangTagRegexTable [] = {\n\t{\"^.*define[ \\t]+([A-Z_][A-Z0-9_]*)[^;]*$\", \"\\\\1\",\n\t \"f,function,functions\", \"i\"},\n\t{\"^[ \\t]*implements[ \\t]+\\\\([ \\t]*\\\"([^\\\"]*)\\\"[ \\t]*\\\\)[ \\t]*;\", \"\\\\1\",\n\t \"n,namespace,namespaces\", NULL},\n};\n\n/*\n *   FUNCTION DEFINITIONS\n */\n\nextern parserDefinition* SlangParser (void)\n{\n\tstatic const char *const extensions [] = { \"sl\", NULL };\n\tparserDefinition* const def = parserNew (\"SLang\");\n\tdef->extensions = extensions;\n\tdef->tagRegexTable = slangTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE (slangTagRegexTable);\n\tdef->method     = METHOD_NOT_CRAFTED|METHOD_REGEX;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/sml.c",
    "content": "/*\n*   Copyright (c) 2002, Venkatesh Prasad Ranganath and Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for SML language files.\n*/\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n/*\n *   DATA DECLARATIONS\n */\ntypedef enum {\n\tK_AND = -2,\n\tK_NONE = -1,\n\tK_EXCEPTION,\n\tK_FUNCTION,\n\tK_FUNCTOR,\n\tK_SIGNATURE,\n\tK_STRUCTURE,\n\tK_TYPE,\n\tK_VAL,\n\tK_COUNT\t\t\t/* must be last */\n} smlKind;\n\n/*\n *   DATA DEFINITIONS\n */\nstatic kindDefinition SmlKinds[] = {\n\t{ true, 'e', \"exception\", \"exception declarations\" },\n\t{ true, 'f', \"function\",  \"function definitions\" },\n\t{ true, 'c', \"functor\",   \"functor definitions\" },\n\t{ true, 's', \"signature\", \"signature declarations\" },\n\t{ true, 'r', \"structure\", \"structure declarations\" },\n\t{ true, 't', \"type\",      \"type definitions\" },\n\t{ true, 'v', \"value\",     \"value bindings\" }\n};\n\nstatic struct {\n\tconst char *keyword;\n\tsmlKind kind;\n} SmlKeywordTypes [] = {\n\t{ \"abstype\",   K_TYPE      },\n\t{ \"and\",       K_AND       },\n\t{ \"datatype\",  K_TYPE      },\n\t{ \"exception\", K_EXCEPTION },\n\t{ \"functor\",   K_FUNCTOR   },\n\t{ \"fun\",       K_FUNCTION  },\n\t{ \"signature\", K_SIGNATURE },\n\t{ \"structure\", K_STRUCTURE },\n\t{ \"type\",      K_TYPE      },\n\t{ \"val\",       K_VAL       }\n};\n\nstatic unsigned int CommentLevel = 0;\n\n/*\n * FUNCTION DEFINITIONS\n */\n\nstatic void makeSmlTag (smlKind type, vString *name)\n{\n\ttagEntryInfo tag;\n\n\tAssert (0 <= type && type < K_COUNT);\n\tif (! SmlKinds [type].enabled)\n\t\treturn;\n\n\tinitTagEntry (&tag, vStringValue (name), type);\n\tmakeTagEntry (&tag);\n}\n\nstatic const unsigned char *skipSpace (const unsigned char *cp)\n{\n\twhile (isspace (*cp))\n\t\t++cp;\n\treturn cp;\n}\n\nstatic bool isIdentifier (int c)\n{\n\tbool result = false;\n\t/* Consider '_' as an delimiter to aid user in tracking it's usage. */\n\tconst char *const alternateIdentifiers = \"!%&$#+-<>=/?@\\\\~'^|*_\";\n\tif (isalnum (c))\n\t\tresult = true;\n\telse if (c != '\\0'  &&  strchr (alternateIdentifiers, c) != NULL)\n\t\tresult = true;\n\treturn result;\n}\n\nstatic const unsigned char *parseIdentifier (\n\t\tconst unsigned char *cp, vString *const identifier)\n{\n\tbool stringLit = false;\n\tvStringClear (identifier);\n\twhile (*cp != '\\0'  &&  (!isIdentifier (*cp) || stringLit))\n\t{\n\t\tint oneback = *cp;\n\t\tcp++;\n\t\tif (oneback == '('  &&  *cp == '*'  &&  stringLit == false)\n\t\t{\n\t\t\tCommentLevel++;\n\t\t\treturn ++cp;\n\t\t}\n\t\tif (*cp == '\"' && oneback != '\\\\')\n\t\t{\n\t\t\tstringLit = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (stringLit && *cp == '\"' && oneback != '\\\\')\n\t\t\tstringLit = false;\n\t}\n\tif (strcmp ((const char *) cp, \"\") == 0 || cp == NULL)\n\t\treturn cp;\n\n\twhile (isIdentifier (*cp))\n\t{\n\t\tvStringPut (identifier, *cp);\n\t\tcp++;\n\t}\n\treturn cp;\n}\n\nstatic smlKind findNextIdentifier (const unsigned char **cp)\n{\n\tsmlKind result = K_NONE;\n\tvString *const identifier = vStringNew ();\n\tunsigned int count = ARRAY_SIZE (SmlKeywordTypes);\n\tunsigned int i;\n\t*cp = parseIdentifier (*cp, identifier);\n\tfor (i = 0  ;  i < count  &&  result == K_NONE ;  ++i)\n\t{\n\t\tconst char *id = vStringValue (identifier);\n\t\tif (strcmp (id, SmlKeywordTypes [i].keyword) == 0)\n\t\t\tresult = SmlKeywordTypes [i].kind;\n\t}\n\tvStringDelete (identifier);\n\treturn result;\n}\n\nstatic void findSmlTags (void)\n{\n\tvString *const identifier = vStringNew ();\n\tconst unsigned char *line;\n\tsmlKind lastTag = K_NONE;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tconst unsigned char *cp = skipSpace (line);\n\t\tdo\n\t\t{\n\t\t\tsmlKind foundTag;\n\t\t\tif (CommentLevel != 0)\n\t\t\t{\n\t\t\t\tcp = (const unsigned char *) strstr ((const char *) cp, \"*)\");\n\t\t\t\tif (cp == NULL)\n\t\t\t\t\tcontinue;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t--CommentLevel;\n\t\t\t\t\tcp += 2;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfoundTag = findNextIdentifier (&cp);\n\t\t\tif (foundTag != K_NONE)\n\t\t\t{\n\t\t\t\tcp = skipSpace (cp);\n\t\t\t\tcp = parseIdentifier (cp, identifier);\n\t\t\t\tif (foundTag == K_AND)\n\t\t\t\t{\n\t\t\t\t\tif (lastTag != K_NONE)\n\t\t\t\t\t\tmakeSmlTag (lastTag, identifier);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmakeSmlTag (foundTag, identifier);\n\t\t\t\t\tlastTag = foundTag;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (strstr ((const char *) cp, \"(*\") != NULL)\n\t\t\t{\n\t\t\t\tcp += 2;\n\t\t\t\tcp = (const unsigned char *) strstr ((const char *) cp, \"*)\");\n\t\t\t\tif (cp == NULL)\n\t\t\t\t\t++CommentLevel;\n\t\t\t}\n\t\t} while (cp != NULL  &&  strcmp ((const char *) cp, \"\") != 0);\n\t}\n\tvStringDelete (identifier);\n}\n\nextern parserDefinition *SmlParser (void)\n{\n\tstatic const char *const extensions[] = { \"sml\", \"sig\", NULL };\n\tparserDefinition *def = parserNew (\"SML\");\n\tdef->kindTable = SmlKinds;\n\tdef->kindCount = ARRAY_SIZE (SmlKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findSmlTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/sql.c",
    "content": "/*\n *\tCopyright (c) 2002-2003, Darren Hiebert\n *\n *\tThis source code is released for free distribution under the terms of the\n *\tGNU General Public License version 2 or (at your option) any later version.\n *\n *\tThis module contains functions for generating tags for PL/SQL language\n *\tfiles.\n */\n\n/*\n *\t INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n\n#include <ctype.h>\t/* to define isalpha () */\n#ifdef DEBUG\n#include <stdio.h>\n#endif\n#include <string.h>\n\n#include \"collector.h\"\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n#include \"promise.h\"\n\n#include \"dependency.h\"\n#include \"cxx/cxx_tag.h\"\n\n/*\n *\tOn-line \"Oracle Database PL/SQL Language Reference\":\n *\thttp://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/toc.htm\n *\n *\tSample PL/SQL code is available from:\n *\thttp://www.orafaq.com/faqscrpt.htm#GENPLSQL\n *\n *\tOn-line SQL Anywhere Documentation\n *\thttp://www.ianywhere.com/developer/product_manuals/sqlanywhere/index.html\n */\n\n/*\n *\t MACROS\n */\n#define isType(token,t)\t\t(bool) ((token)->type == (t))\n#define isKeyword(token,k)\t(bool) ((token)->keyword == (k))\n#define isReservedWord(token) (SqlReservedWord[(token)->keyword].fn \\\n\t\t\t\t\t\t\t   ?(bool)SqlReservedWord[(token)->keyword].fn(token) \\\n\t\t\t\t\t\t\t   :SqlReservedWord[(token)->keyword].bit)\n#define isIdentChar1(c) \\\n\t/*\n\t * Other databases are less restrictive on the first character of\n\t * an identifier.\n\t * isIdentChar1 is used to identify the first character of an\n\t * identifier, so we are removing some restrictions.\n\t */ \\\n\t(isalpha (c) || (c) == '@' || (c) == '_' )\n#define isIdentChar(c) \\\n\t(isalpha (c) || isdigit (c) || (c) == '$' || \\\n\t\t(c) == '@' || (c) == '_' || (c) == '#')\n\n/*\n *\t DATA DECLARATIONS\n */\n\n/*\n * Used to specify type of keyword.\n */\nenum eKeywordId {\n\tKEYWORD_at,\n\tKEYWORD_begin,\n\tKEYWORD_body,\n\tKEYWORD_call,\n\tKEYWORD_case,\n\tKEYWORD_check,\n\tKEYWORD_commit,\n\tKEYWORD_comment,\n\tKEYWORD_constraint,\n\tKEYWORD_create,\n\tKEYWORD_cursor,\n\tKEYWORD_database,\n\tKEYWORD_datatype,\n\tKEYWORD_declare,\n\tKEYWORD_do,\n\tKEYWORD_domain,\n\tKEYWORD_drop,\n\tKEYWORD_else,\n\tKEYWORD_elseif,\n\tKEYWORD_elsif,\n\tKEYWORD_end,\n\tKEYWORD_endif,\n\tKEYWORD_event,\n\tKEYWORD_exception,\n\tKEYWORD_extension,\n\tKEYWORD_external,\n\tKEYWORD_for,\n\tKEYWORD_foreign,\n\tKEYWORD_from,\n\tKEYWORD_function,\n\tKEYWORD_go,\n\tKEYWORD_handler,\n\tKEYWORD_if,\n\tKEYWORD_index,\n\tKEYWORD_internal,\n\tKEYWORD_is,\n\tKEYWORD_language,\n\tKEYWORD_local,\n\tKEYWORD_loop,\n\tKEYWORD_ml_conn,\n\tKEYWORD_ml_conn_chk,\n\tKEYWORD_ml_conn_dnet,\n\tKEYWORD_ml_conn_java,\n\tKEYWORD_ml_conn_lang,\n\tKEYWORD_ml_prop,\n\tKEYWORD_ml_table,\n\tKEYWORD_ml_table_chk,\n\tKEYWORD_ml_table_dnet,\n\tKEYWORD_ml_table_java,\n\tKEYWORD_ml_table_lang,\n\tKEYWORD_object,\n\tKEYWORD_on,\n\tKEYWORD_package,\n\tKEYWORD_pragma,\n\tKEYWORD_inquiry_directive,\n\tKEYWORD_primary,\n\tKEYWORD_procedure,\n\tKEYWORD_publication,\n\tKEYWORD_record,\n\tKEYWORD_ref,\n\tKEYWORD_references,\n\tKEYWORD_rem,\n\tKEYWORD_result,\n\tKEYWORD_return,\n\tKEYWORD_returns,\n\tKEYWORD_schema,\n\tKEYWORD_select,\n\tKEYWORD_service,\n\tKEYWORD_subtype,\n\tKEYWORD_synonym,\n\tKEYWORD_table,\n\tKEYWORD_temporary,\n\tKEYWORD_then,\n\tKEYWORD_trigger,\n\tKEYWORD_type,\n\tKEYWORD_unique,\n\tKEYWORD_url,\n\tKEYWORD_variable,\n\tKEYWORD_view,\n\tKEYWORD_when,\n\tKEYWORD_while,\n\tKEYWORD_with,\n\tKEYWORD_without,\n\tSQLKEYWORD_COUNT,\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum eTokenType {\n\tTOKEN_UNDEFINED,\n\tTOKEN_EOF,\n\tTOKEN_BLOCK_LABEL_BEGIN,\n\tTOKEN_BLOCK_LABEL_END,\n\tTOKEN_CHARACTER,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_COLON,\n\tTOKEN_SEMICOLON,\n\tTOKEN_COMMA,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_KEYWORD,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_OPERATOR,\n\tTOKEN_OTHER,\n\tTOKEN_STRING,\n\tTOKEN_PERIOD,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_TILDE,\n\tTOKEN_FORWARD_SLASH,\n\tTOKEN_EQUAL,\n\tTOKEN_PREPROC_IF,\n\tTOKEN_PREPROC_ELSIF,\n\tTOKEN_PREPROC_ELSE,\n\tTOKEN_PREPROC_THEN,\n\tTOKEN_PREPROC_END,\n} tokenType;\n\ntypedef struct sTokenInfoSQL {\n\ttokenType\ttype;\n\tkeywordId\tkeyword;\n\tvString *\tstring;\n\tvString *\tscope;\n\tint         scopeKind;\n\tint         begin_end_nest_lvl;\n\tunsigned long lineNumber;\n\tMIOPos filePosition;\n\n\t/* When the \"guest\" extra is enabled, a promise is\n\t * made always when reading a string (literal or dollar quote).\n\t * The lexer stores the id of promise to this member.\n\t * When making the promise, the language of guest parser\n\t * may not be determined yet.\n\t *\n\t *   CREATE FUNCTION ... AS ' sub code_written_in_perl {... ' LANGUAGE plperl;\n\t *\n\t * After reading a string, the parser may find LANGUAGE keyword. In the case,\n\t * the parser updates the language of the promies.\n\t *\n\t * This field is filled only when `guest` extra is enabled.\n\t *\n\t */\n\tint promise;\n} tokenInfo;\n\n/*\n *\tDATA DEFINITIONS\n */\n\nstatic langType Lang_sql;\n\ntypedef enum {\n\tSQLTAG_PLSQL_CCFLAGS,\n\tSQLTAG_DOMAIN,\n\tSQLTAG_FIELD,\n\tSQLTAG_BLOCK_LABEL,\n\tSQLTAG_PACKAGE,\n\tSQLTAG_SERVICE,\n\tSQLTAG_SCHEMA,\n\tSQLTAG_TRIGGER,\n\tSQLTAG_PUBLICATION,\n\tSQLTAG_VIEW,\n\tSQLTAG_DATABASE,\n\tSQLTAG_CURSOR,\n\tSQLTAG_PROTOTYPE,\n\tSQLTAG_EVENT,\n\tSQLTAG_FUNCTION,\n\tSQLTAG_INDEX,\n\tSQLTAG_TYPE,\n\tSQLTAG_LOCAL_VARIABLE,\n\tSQLTAG_SYNONYM,\n\tSQLTAG_PROCEDURE,\n\tSQLTAG_RECORD,\n\tSQLTAG_SUBTYPE,\n\tSQLTAG_TABLE,\n\tSQLTAG_VARIABLE,\n\tSQLTAG_MLTABLE,\n\tSQLTAG_MLCONN,\n\tSQLTAG_MLPROP,\n\tSQLTAG_COUNT\n} sqlKind;\n\ntypedef enum {\n\tR_SQLTAG_TYPE_DECL,\n} sqlTypeRole;\n\nstatic roleDefinition SqlTypeRoles [] = {\n\t{ false, \"decl\", \"declaration (shell in PostgreSQL)\",\n\t  .version = 1 },\n};\n\nstatic kindDefinition SqlKinds [] = {\n\t{ true,  'C', \"ccflag\",\t\t  \"PLSQL_CCFLAGS\"          },\n\t{ true,  'D', \"domain\",\t\t  \"domains\"\t\t\t\t   },\n\t{ true,  'E', \"field\",\t\t  \"record fields\"\t\t   },\n\t{ true,  'L', \"label\",\t\t  \"block label\"\t\t\t   },\n\t{ true,  'P', \"package\",\t  \"packages\"\t\t\t   },\n\t{ true,  'R', \"service\",\t  \"services\"\t\t\t   },\n\t{ true,  'S', \"schema\",\t\t  \"schemas\"\t\t\t  \t   },\n\t{ true,  'T', \"trigger\",\t  \"triggers\"\t\t\t   },\n\t{ true,  'U', \"publication\",  \"publications\"\t\t   },\n\t{ true,  'V', \"view\",\t\t  \"views\"\t\t\t\t   },\n\t{ true,  'b', \"database\",\t  \"database\"\t\t\t   },\n\t{ true,  'c', \"cursor\",\t\t  \"cursors\"\t\t\t\t   },\n\t{ false, 'd', \"prototype\",\t  \"prototypes\"\t\t\t   },\n\t{ true,  'e', \"event\",\t\t  \"events\"\t\t\t\t   },\n\t{ true,  'f', \"function\",\t  \"functions\"\t\t\t   },\n\t{ true,  'i', \"index\",\t\t  \"indexes\"\t\t\t\t   },\n\t{ true,  'k', \"type\",\t\t  \"types\",\n\t  .referenceOnly = false, ATTACH_ROLES (SqlTypeRoles),\n\t  .version = 1 },\n\t{ false, 'l', \"local\",\t\t  \"local variables\"\t\t   },\n\t{ true,  'n', \"synonym\",\t  \"synonyms\"\t\t\t   },\n\t{ true,  'p', \"procedure\",\t  \"procedures\"\t\t\t   },\n\t{ false, 'r', \"record\",\t\t  \"records\"\t\t\t\t   },\n\t{ true,  's', \"subtype\",\t  \"subtypes\"\t\t\t   },\n\t{ true,  't', \"table\",\t\t  \"tables\"\t\t\t\t   },\n\t{ true,  'v', \"variable\",\t  \"variables\"\t\t\t   },\n\t{ true,  'x', \"mltable\",\t  \"MobiLink Table Scripts\" },\n\t{ true,  'y', \"mlconn\",\t\t  \"MobiLink Conn Scripts\"  },\n\t{ true,  'z', \"mlprop\",\t\t  \"MobiLink Properties\"    },\n};\n\nstatic const keywordTable SqlKeywordTable [] = {\n\t/* keyword\t\tkeyword ID */\n\t{ \"as\",\t\t\t\t\t\t\t\tKEYWORD_is\t\t\t\t      },\n\t{ \"at\",\t\t\t\t\t\t\t\tKEYWORD_at\t\t\t\t      },\n\t{ \"begin\",\t\t\t\t\t\t\tKEYWORD_begin\t\t\t      },\n\t{ \"body\",\t\t\t\t\t\t\tKEYWORD_body\t\t\t      },\n\t{ \"call\",\t\t\t\t\t\t\tKEYWORD_call\t\t\t      },\n\t{ \"case\",\t\t\t\t\t\t\tKEYWORD_case\t\t\t      },\n\t{ \"check\",\t\t\t\t\t\t\tKEYWORD_check\t\t\t      },\n\t{ \"commit\",\t\t\t\t\t\t\tKEYWORD_commit\t\t\t\t  },\n\t{ \"comment\",\t\t\t\t\t\tKEYWORD_comment\t\t\t      },\n\t{ \"constraint\",\t\t\t\t\t\tKEYWORD_constraint\t\t      },\n\t{ \"create\",\t\t\t\t\t\t\tKEYWORD_create\t\t\t\t  },\n\t{ \"cursor\",\t\t\t\t\t\t\tKEYWORD_cursor\t\t\t      },\n\t{ \"database\",\t\t\t\t\t\tKEYWORD_database\t\t      },\n\t{ \"datatype\",\t\t\t\t\t\tKEYWORD_datatype\t\t      },\n\t{ \"declare\",\t\t\t\t\t\tKEYWORD_declare\t\t\t      },\n\t{ \"do\",\t\t\t\t\t\t\t\tKEYWORD_do\t\t\t\t      },\n\t{ \"domain\",\t\t\t\t\t\t\tKEYWORD_domain\t\t\t\t  },\n\t{ \"drop\",\t\t\t\t\t\t\tKEYWORD_drop\t\t\t      },\n\t{ \"else\",\t\t\t\t\t\t\tKEYWORD_else\t\t\t      },\n\t{ \"elseif\",\t\t\t\t\t\t\tKEYWORD_elseif\t\t\t      },\n\t{ \"elsif\",\t\t\t\t\t\t\tKEYWORD_elsif\t\t\t      },\n\t{ \"end\",\t\t\t\t\t\t\tKEYWORD_end\t\t\t\t      },\n\t{ \"endif\",\t\t\t\t\t\t\tKEYWORD_endif\t\t\t      },\n\t{ \"event\",\t\t\t\t\t\t\tKEYWORD_event\t\t\t      },\n\t{ \"exception\",\t\t\t\t\t\tKEYWORD_exception\t\t      },\n\t{ \"extension\",\t\t\t\t\t\tKEYWORD_extension\t\t      },\n\t{ \"external\",\t\t\t\t\t\tKEYWORD_external\t\t      },\n\t{ \"for\",\t\t\t\t\t\t\tKEYWORD_for\t\t\t\t      },\n\t{ \"foreign\",\t\t\t\t\t\tKEYWORD_foreign\t\t\t      },\n\t{ \"from\",\t\t\t\t\t\t\tKEYWORD_from\t\t\t      },\n\t{ \"function\",\t\t\t\t\t\tKEYWORD_function\t\t      },\n\t{ \"go\",\t\t\t\t\t\t\t\tKEYWORD_go\t\t\t\t      },\n\t{ \"handler\",\t\t\t\t\t\tKEYWORD_handler\t\t\t      },\n\t{ \"if\",\t\t\t\t\t\t\t\tKEYWORD_if\t\t\t\t      },\n\t{ \"index\",\t\t\t\t\t\t\tKEYWORD_index\t\t\t      },\n\t{ \"internal\",\t\t\t\t\t\tKEYWORD_internal\t\t      },\n\t{ \"is\",\t\t\t\t\t\t\t\tKEYWORD_is\t\t\t\t      },\n\t{ \"language\",\t\t\t\t\t\tKEYWORD_language              },\n\t{ \"local\",\t\t\t\t\t\t\tKEYWORD_local\t\t\t      },\n\t{ \"loop\",\t\t\t\t\t\t\tKEYWORD_loop\t\t\t      },\n\t{ \"ml_add_connection_script\",\t\tKEYWORD_ml_conn\t\t\t      },\n\t{ \"ml_add_dnet_connection_script\",\tKEYWORD_ml_conn_dnet\t      },\n\t{ \"ml_add_dnet_table_script\",\t\tKEYWORD_ml_table_dnet\t      },\n\t{ \"ml_add_java_connection_script\",\tKEYWORD_ml_conn_java\t      },\n\t{ \"ml_add_java_table_script\",\t\tKEYWORD_ml_table_java\t      },\n\t{ \"ml_add_lang_conn_script_chk\",\tKEYWORD_ml_conn_chk \t      },\n\t{ \"ml_add_lang_connection_script\",\tKEYWORD_ml_conn_lang\t      },\n\t{ \"ml_add_lang_table_script\",\t\tKEYWORD_ml_table_lang\t      },\n\t{ \"ml_add_lang_table_script_chk\",\tKEYWORD_ml_table_chk\t      },\n\t{ \"ml_add_property\",\t\t\t\tKEYWORD_ml_prop\t\t \t      },\n\t{ \"ml_add_table_script\",\t\t\tKEYWORD_ml_table\t\t      },\n\t{ \"object\",\t\t\t\t\t\t\tKEYWORD_object\t\t\t      },\n\t{ \"on\",\t\t\t\t\t\t\t\tKEYWORD_on\t\t\t\t      },\n\t{ \"package\",\t\t\t\t\t\tKEYWORD_package\t\t\t      },\n\t{ \"pragma\",\t\t\t\t\t\t\tKEYWORD_pragma\t\t\t      },\n\t{ \"primary\",\t\t\t\t\t\tKEYWORD_primary\t\t\t      },\n\t{ \"procedure\",\t\t\t\t\t\tKEYWORD_procedure\t\t      },\n\t{ \"publication\",\t\t\t\t\tKEYWORD_publication\t\t      },\n\t{ \"record\",\t\t\t\t\t\t\tKEYWORD_record\t\t\t      },\n\t{ \"ref\",\t\t\t\t\t\t\tKEYWORD_ref\t\t\t\t      },\n\t{ \"references\",\t\t\t\t\t\tKEYWORD_references\t\t      },\n\t{ \"rem\",\t\t\t\t\t\t\tKEYWORD_rem\t\t\t\t      },\n\t{ \"result\",\t\t\t\t\t\t\tKEYWORD_result\t\t\t      },\n\t{ \"return\",\t\t\t\t\t\t\tKEYWORD_return\t\t\t      },\n\t{ \"returns\",\t\t\t\t\t\tKEYWORD_returns\t\t\t      },\n\t{ \"schema\",\t\t\t\t\t\t\tKEYWORD_schema\t\t\t      },\n\t{ \"select\",\t\t\t\t\t\t\tKEYWORD_select\t\t\t      },\n\t{ \"service\",\t\t\t\t\t\tKEYWORD_service\t\t\t      },\n\t{ \"subtype\",\t\t\t\t\t\tKEYWORD_subtype\t\t\t      },\n\t{ \"synonym\",\t\t\t\t\t\tKEYWORD_synonym\t\t\t      },\n\t{ \"table\",\t\t\t\t\t\t\tKEYWORD_table\t\t\t      },\n\t{ \"temporary\",\t\t\t\t\t\tKEYWORD_temporary\t\t      },\n\t{ \"then\",\t\t\t\t\t\t\tKEYWORD_then\t\t\t      },\n\t{ \"trigger\",\t\t\t\t\t\tKEYWORD_trigger\t\t\t      },\n\t{ \"type\",\t\t\t\t\t\t\tKEYWORD_type\t\t\t      },\n\t{ \"unique\",\t\t\t\t\t\t\tKEYWORD_unique\t\t\t      },\n\t{ \"url\",\t\t\t\t\t\t\tKEYWORD_url\t\t\t\t      },\n\t{ \"variable\",\t\t\t\t\t\tKEYWORD_variable\t\t      },\n\t{ \"view\",\t\t\t\t\t\t\tKEYWORD_view\t\t\t      },\n\t{ \"when\",\t\t\t\t\t\t\tKEYWORD_when\t\t\t      },\n\t{ \"while\",\t\t\t\t\t\t\tKEYWORD_while\t\t\t      },\n\t{ \"with\",\t\t\t\t\t\t\tKEYWORD_with\t\t\t      },\n\t{ \"without\",\t\t\t\t\t\tKEYWORD_without\t\t\t      },\n};\n\nstatic const struct keywordGroup predefinedInquiryDirective = {\n\t.value = KEYWORD_inquiry_directive,\n\t.addingUnlessExisting = false,\n\t.keywords = {\n\t\t/* https://docs.oracle.com/en/database/oracle/oracle-database/18/lnpls/plsql-language-fundamentals.html#GUID-3DABF5E1-AC84-448B-810F-31196991EA10 */\n\t\t\"PLSQL_LINE\",\n\t\t\"PLSQL_UNIT\",\n\t\t\"PLSQL_UNIT_OWNER\",\n\t\t\"PLSQL_UNIT_TYPE\",\n\t\t/* https://docs.oracle.com/en/database/oracle/oracle-database/18/lnpls/overview.html#GUID-DF63BC59-22C2-4BA8-9240-F74D505D5102 */\n\t\t\"PLSCOPE_SETTINGS\",\n\t\t\"PLSQL_CCFLAGS\",\n\t\t\"PLSQL_CODE_TYPE\",\n\t\t\"PLSQL_OPTIMIZE_LEVEL\",\n\t\t\"PLSQL_WARNINGS\",\n\t\t\"NLS_LENGTH_SEMANTICS\",\n\t\t\"PERMIT_92_WRAP_FORMAT\",\n\t\tNULL\n\t},\n};\n\n/* A table representing whether a keyword is \"reserved word\" or not.\n * \"reserved word\" cannot be used as an name.\n * See https://dev.mysql.com/doc/refman/8.0/en/keywords.html about the\n * difference between keywords and the reserved words.\n *\n * We will mark a keyword as a reserved word only if all the SQL dialects\n * specify it as a reserved word.\n */\nstruct SqlReservedWord {\n\t/* If fn is non-NULL, value returned from fn(token) is used\n\t * to repreesnt whether a keyword is reserved (true) or not.\n\t * If fn is NULL, bit is used. */\n\tunsigned int bit;\n\tbool (* fn) (tokenInfo *const token);\n};\n\n/*\n * MYSQL\n * => https://dev.mysql.com/doc/refman/8.0/en/keywords.html\n * POSTGRESQL,SQL2016,SQL2011,SQL92\n * => https://www.postgresql.org/docs/12/sql-keywords-appendix.html\n * ORACLE11g, PLSQL\n * => https://docs.oracle.com/cd/B28359_01/appdev.111/b31231/appb.htm#CJHIIICD\n * SQLANYWERE\n * => http://dcx.sap.com/1200/en/dbreference/alhakeywords.html <the page is gone>\n */\nstatic bool SqlReservedWordPredicatorForIsOrAs (tokenInfo *const token);\nstatic struct SqlReservedWord SqlReservedWord [SQLKEYWORD_COUNT] = {\n\t/*\n\t * RESERVED_BIT: MYSQL & POSTGRESQL&SQL2016&SQL2011&SQL92 & ORACLE11g&PLSQL & SQLANYWERE\n\t *\n\t * {  0  } means we have not inspect whether the keyword is reserved or not.\n\t */\n\t[KEYWORD_at]            = {0 & 0&1&1&1 & 0&1 & 0},\n\t[KEYWORD_begin]         = {0 & 0&1&1&1 & 0&1 & 1},\n\t[KEYWORD_body]          = {0 & 0&0&0&0 & 0&1 & 0},\n\t[KEYWORD_call]          = {1 & 0&1&1&0 & 0&0 & 1},\n\t[KEYWORD_case]          = {1 & 1&1&1&1 & 0&1 & 1},\n\t[KEYWORD_check]         = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_commit]        = {0 & 0&1&1&1 & 0&0 & 0}, /* SQLANYWERE:??? */\n\t[KEYWORD_comment]       = {0 & 0&0&0&0 & 1&1 & 1},\n\t[KEYWORD_constraint]    = {1 & 1&1&1&1 & 0&1 & 1},\n\t[KEYWORD_create]        = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_cursor]        = {1 & 0&1&1&1 & 0&1 & 1},\n\t[KEYWORD_database]      = {         0           },\n\t[KEYWORD_datatype]      = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_declare]       = {1 & 0&1&1&1 & 0&1 & 1},\n\t[KEYWORD_do]            = {0 & 1&0&0&0 & 0&1 & 1},\n\t[KEYWORD_domain]        = {0 & 0&0&0&1 & 0&0 & 0},\n\t[KEYWORD_drop]          = {1 & 0&1&1&1 & 1&1 & 1},\n\t[KEYWORD_else]          = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_elseif]        = {1 & 0&0&0&0 & 0&0 & 1},\n\t[KEYWORD_elsif]         = {0 & 0&0&0&0 & 0&1 & 0},\n\t[KEYWORD_end]           = {0 & 1&1&1&1 & 0&1 & 1},\n\t[KEYWORD_endif]         = {0 & 0&0&0&0 & 0&0 & 1},\n\t[KEYWORD_event]         = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_exception]     = {0 & 0&0&0&1 & 0&1 & 1},\n\t[KEYWORD_extension]     = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_external]      = {0 & 0&1&1&1 & 0&0 & 0},\n\t[KEYWORD_for]           = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_foreign]       = {1 & 1&1&1&1 & 0&0 & 1},\n\t[KEYWORD_from]          = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_function]      = {1 & 0&1&1&0 & 0&1 & 0},\n\t[KEYWORD_go]            = {0 & 0&0&0&1 & 0&0 & 0},\n\t[KEYWORD_handler]       = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_if]            = {1 & 0&0&0&0 & 0&1 & 1},\n\t[KEYWORD_index]         = {1 & 0&0&0&0 & 1&1 & 1},\n\t[KEYWORD_inquiry_directive] = {        0        },\n\t[KEYWORD_internal]      = {1 & 0&1&1&0 & 0&0 & 0},\n\t[KEYWORD_is]            = {0, SqlReservedWordPredicatorForIsOrAs},\n\t[KEYWORD_language]      = {            0        },\n\t[KEYWORD_local]         = {0 & 0&1&1&1 & 0&0 & 0},\n\t[KEYWORD_loop]          = {1 & 1&1&1&1 & 0&1 & 0},\n\t[KEYWORD_ml_conn]       = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_ml_conn_dnet]  = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_ml_table_dnet] = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_ml_conn_java]  = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_ml_table_java] = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_ml_conn_chk]   = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_ml_conn_lang]  = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_ml_table_lang] = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_ml_table_chk]  = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_ml_prop]       = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_ml_table]      = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_object]        = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_on]            = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_package]       = {0 & 0&0&0&0 & 0&1 & 0},\n\t[KEYWORD_pragma]        = {0 & 0&0&0&0 & 0&1 & 0},\n\t[KEYWORD_primary]       = {1 & 1&1&1&1 & 0&0 & 1},\n\t[KEYWORD_procedure]     = {1 & 0&0&0&0 & 0&1 & 1},\n\t[KEYWORD_publication]   = {0 & 0&0&0&0 & 0&0 & 1},\n\t[KEYWORD_record]        = {0 & 0&0&0&0 & 0&1 & 0},\n\t[KEYWORD_ref]           = {0 & 0&1&1&0 & 0&0 & 0},\n\t[KEYWORD_references]    = {1 & 1&1&1&1 & 0&0 & 1},\n\t[KEYWORD_rem]           = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_result]        = {0 & 0&1&1&0 & 0&0 & 0},\n\t[KEYWORD_return]        = {1 & 0&1&1&0 & 0&1 & 1},\n\t[KEYWORD_returns]       = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_schema]        = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_select]        = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_service]       = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_subtype]       = {0 & 0&0&0&0 & 0&1 & 0},\n\t[KEYWORD_synonym]       = {0 & 0&0&0&0 & 1&0 & 0},\n\t[KEYWORD_table]         = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_temporary]     = {0 & 0&0&0&1 & 0&0 & 1},\n\t[KEYWORD_then]          = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_trigger]       = {1 & 0&1&1&0 & 1&0 & 1},\n\t[KEYWORD_type]          = {0 & 0&0&0&0 & 0&1 & 0},\n\t[KEYWORD_unique]        = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_url]           = {0 & 0&0&0&0 & 0&0 & 0},\n\t[KEYWORD_variable]      = {0 & 0&0&0&0 & 0&0 & 1},\n\t[KEYWORD_view]          = {0 & 0&0&0&1 & 1&1 & 1},\n\t[KEYWORD_when]          = {1 & 1&1&1&1 & 0&1 & 1},\n\t[KEYWORD_while]         = {1 & 0&0&0&0 & 0&1 & 1},\n\t[KEYWORD_with]          = {1 & 1&1&1&1 & 1&1 & 1},\n\t[KEYWORD_without]       = {0 & 0&1&1&0 & 0&0 & 0},\n};\n\nstatic langType Lang_c;\n\n/*\n *\t FUNCTION DECLARATIONS\n */\n\n/* Recursive calls */\nstatic void parseBlock (tokenInfo *const token, const bool local);\nstatic void parseBlockFull (tokenInfo *const token, const bool local, langType lang);\nstatic void parseDeclare (tokenInfo *const token, const bool local);\nstatic void parseKeywords (tokenInfo *const token, enum eKeywordId precedingKeyword);\nstatic tokenType parseSqlFile (tokenInfo *const token);\n\n/*\n *\t FUNCTION DEFINITIONS\n */\n\nstatic bool SqlReservedWordPredicatorForIsOrAs (tokenInfo *const token)\n{\n\tif (strcasecmp (\"as\", vStringValue (token->string)) == 0)\n\t\treturn (bool) (1 & 1&1&1&1 & 1&1 & 1);\n\telse\t\t\t\t\t\t/* for \"is\" */\n\t\treturn (bool) (1 & 0&1&1&1 & 1&1 & 1);\n\t/* PostgresSQL can use \"is\" as a name of function. */\n}\n\nstatic bool isCmdTerm (tokenInfo *const token)\n{\n\tDebugStatement (\n\t\t\tdebugPrintf (DEBUG_PARSE\n\t\t\t\t, \"\\n isCmdTerm: token same  tt:%d  tk:%d\\n\"\n\t\t\t\t, token->type\n\t\t\t\t, token->keyword\n\t\t\t\t);\n\t\t\t);\n\n\t/*\n\t * Based on the various customer sites I have been at\n\t * the most common command delimiters are\n\t *\t   ;\n\t *\t   ~\n\t *\t   /\n\t *\t   go\n\t * This routine will check for any of these, more\n\t * can easily be added by modifying readToken and\n\t * either adding the character to:\n\t *\t   enum eTokenType\n\t *\t   enum eTokenType\n\t */\n\treturn (isType (token, TOKEN_SEMICOLON) ||\n\t\t\tisType (token, TOKEN_TILDE) ||\n\t\t\tisType (token, TOKEN_FORWARD_SLASH) ||\n\t\t\tisKeyword (token, KEYWORD_go));\n}\n\nstatic bool isMatchedEnd (tokenInfo *const token, int nest_lvl)\n{\n\tbool terminated = false;\n\t/*\n\t * Since different forms of SQL allow the use of\n\t * BEGIN\n\t * ...\n\t * END\n\t * blocks, some statements may not be terminated using\n\t * the standard delimiters:\n\t *\t   ;\n\t *\t   ~\n\t *\t   /\n\t *\t   go\n\t * This routine will check to see if we encounter and END\n\t * for the matching nest level of BEGIN ... END statements.\n\t * If we find one, then we can assume, the statement was terminated\n\t * since we have fallen through to the END statement of the BEGIN\n\t * block.\n\t */\n\tif ( nest_lvl > 0 && isKeyword (token, KEYWORD_end) )\n\t{\n\t\tif ( token->begin_end_nest_lvl == nest_lvl )\n\t\t\tterminated = true;\n\t}\n\n\treturn terminated;\n}\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\n\ttoken->type               = TOKEN_UNDEFINED;\n\ttoken->keyword            = KEYWORD_NONE;\n\ttoken->string             = vStringNew ();\n\ttoken->scope              = vStringNew ();\n\ttoken->scopeKind          = SQLTAG_COUNT;\n\ttoken->begin_end_nest_lvl = 0;\n\ttoken->lineNumber         = getInputLineNumber ();\n\ttoken->filePosition       = getInputFilePosition ();\n\ttoken->promise            = -1;\n\n\treturn token;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tvStringDelete (token->string);\n\tvStringDelete (token->scope);\n\teFree (token);\n}\n\n/*\n *\t Tag generation functions\n */\n\nstatic int makeSqlTagFull (tokenInfo *const token, const sqlKind kind, int *fqIndex)\n{\n\tint r = CORK_NIL;\n\tif (fqIndex)\n\t\t*fqIndex = CORK_NIL;\n\n\tif (SqlKinds [kind].enabled)\n\t{\n\t\tconst char *const name = vStringValue (token->string);\n\t\ttagEntryInfo e;\n\t\tinitTagEntry (&e, name, kind);\n\n\t\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\n\t\tif (vStringLength (token->scope) > 0)\n\t\t{\n\t\t\tAssert (token->scopeKind < SQLTAG_COUNT);\n\t\t\te.extensionFields.scopeKindIndex = token->scopeKind;\n\t\t\te.extensionFields.scopeName = vStringValue (token->scope);\n\n\t\t\tif (isXtagEnabled (XTAG_QUALIFIED_TAGS))\n\t\t\t{\n\t\t\t\tint r_fq;\n\t\t\t\tvString *fulltag;\n\t\t\t\ttagEntryInfo xe = e;\n\n\t\t\t\tfulltag =  vStringNewCopy (token->scope);\n\t\t\t\tvStringPut (fulltag, '.');\n\t\t\t\tvStringCat (fulltag, token->string);\n\t\t\t\txe.name = vStringValue (fulltag);\n\t\t\t\tmarkTagExtraBit (&xe, XTAG_QUALIFIED_TAGS);\n\t\t\t\tr_fq = makeTagEntry (&xe);\n\t\t\t\tif (fqIndex)\n\t\t\t\t\t*fqIndex = r_fq;\n\t\t\t\tvStringDelete (fulltag);\n\t\t\t}\n\t\t}\n\n\t\tr = makeTagEntry (&e);\n\t}\n\n\treturn r;\n}\n\nstatic int makeSqlTag (tokenInfo *const token, const sqlKind kind)\n{\n\treturn makeSqlTagFull (token, kind, NULL);\n}\n\n/* Make the tag that OLDTAGINDEX specifies a placeholder, then make a new\n * tag for TOKEN with KIND kind. */\nstatic int makeSqlTagInstead (tokenInfo *const token, const sqlKind kind, int oldTagIndex)\n{\n\tmarkCorkEntryAsPlaceholder(oldTagIndex, true);\n\treturn makeSqlTag (token, kind);\n}\n\n/*\n *\t Parsing functions\n */\n\nstatic void parseString (vString *const string, const int delimiter, int *promise)\n{\n\tint column[2];\n\tunsigned long linenum[3];\n\tenum { START, END, SOURCE };\n\n\tint c0;\n\n\tif (promise && !isXtagEnabled(XTAG_GUEST))\n\t\tpromise = NULL;\n\n\tif (promise)\n\t{\n\t\tc0 = getcFromInputFile ();\n\t\tlinenum[START] = getInputLineNumber ();\n\t\tcolumn[START]  = getInputColumnNumber ();\n\t\tlinenum[SOURCE] = getSourceLineNumber ();\n\t\tungetcToInputFile(c0);\n\t}\n\n\tbool end = false;\n\twhile (! end)\n\t{\n\t\tint c = getcFromInputFile ();\n\t\tif (c == EOF)\n\t\t\tend = true;\n\t\t/*\n\t\telse if (c == '\\\\')\n\t\t{\n\t\t\tc = getcFromInputFile(); // This maybe a ' or \". //\n\t\t\tvStringPut(string, c);\n\t\t}\n\t\t*/\n\t\telse if (c == delimiter)\n\t\t{\n\t\t\tif (c == '\\'')\n\t\t\t{\n\t\t\t\tint d = getcFromInputFile ();\n\t\t\t\tif (d == '\\'')\n\t\t\t\t{\n\t\t\t\t\tvStringPut (string, c);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tungetcToInputFile(d);\n\t\t\t}\n\n\t\t\tif (promise)\n\t\t\t{\n\t\t\t\tungetcToInputFile(c);\n\t\t\t\tlinenum[END] = getInputLineNumber ();\n\t\t\t\tcolumn[END]  = getInputColumnNumber ();\n\t\t\t\t(void)getcFromInputFile ();\n\t\t\t\t*promise = makePromise (NULL,\n\t\t\t\t\t\t\t\t\t\tlinenum [START], column [START],\n\t\t\t\t\t\t\t\t\t\tlinenum [END], column [END],\n\t\t\t\t\t\t\t\t\t\tlinenum [SOURCE]);\n\t\t\t}\n\t\t\tend = true;\n\t\t}\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\n/*\tRead a C identifier beginning with \"firstChar\" and places it into \"name\".\n*/\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tAssert (isIdentChar1 (c));\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isIdentChar (c));\n\tif (!isspace (c))\n\t\tungetcToInputFile (c);\t\t/* unget non-identifier character */\n}\n\nstatic bool isCCFlag (const char *str)\n{\n\treturn (anyKindEntryInScope(CORK_NIL, str, SQLTAG_PLSQL_CCFLAGS, false) != 0);\n}\n\n/* Parse a PostgreSQL: dollar-quoted string\n * https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING\n *\n * The syntax for dollar-quoted string ca collide with PL/SQL inquiry directive ($$name).\n * https://docs.oracle.com/en/database/oracle/oracle-database/18/lnpls/plsql-language-fundamentals.html#GUID-E918087C-D5A8-4CEE-841B-5333DE6D4C15\n * https://github.com/universal-ctags/ctags/issues/3006\n\n * In addition, it can also collide with variable checks in PL/SQL selection directives such as:\n * $IF $$my_var > 1 $THEN ... $END\n * https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/plsql-language-fundamentals.html#GUID-78F2074C-C799-4CF9-9290-EB8473D0C8FB\n */\nstatic tokenType parseDollarQuote (vString *const string, const int delimiter, int *promise)\n{\n\tint column[2];\n\tunsigned long linenum[3];\n\tenum { START, END, SOURCE };\n\n\tunsigned int len = 0;\n\tchar tag[32 /* arbitrary limit */] = {0};\n\tint c = 0;\n\n\t/* read the tag */\n\ttag[len++] = (char) delimiter;\n\twhile ((len + 1) < sizeof tag && c != delimiter)\n\t{\n\t\tc = getcFromInputFile ();\n\t\tif (isIdentChar(c))\n\t\t\ttag[len++] = (char) c;\n\t\telse\n\t\t\tbreak;\n\t}\n\ttag[len] = 0;\n\n\tbool empty_tag = (len == 2);\n\n\tif (c != delimiter)\n\t{\n\t\t/* not a dollar quote */\n\t\tkeywordId kw = lookupCaseKeyword (tag+1, Lang_sql);\n\t\tungetcToInputFile (c);\n\n\t\tif (kw == KEYWORD_if)\n\t\t\treturn TOKEN_PREPROC_IF;\n\t\telse if (kw == KEYWORD_elsif)\n\t\t\treturn TOKEN_PREPROC_ELSIF;\n\t\telse if (kw == KEYWORD_else)\n\t\t\treturn TOKEN_PREPROC_ELSE;\n\t\telse if (kw == KEYWORD_then)\n\t\t\treturn TOKEN_PREPROC_THEN;\n\t\telse if (kw == KEYWORD_end)\n\t\t\treturn TOKEN_PREPROC_END;\n\t\treturn TOKEN_UNDEFINED;\n\t}\n\n\tif (promise && !isXtagEnabled(XTAG_GUEST))\n\t\tpromise = NULL;\n\n\tif (promise)\n\t{\n\t\tlinenum[START] = getInputLineNumber ();\n\t\tcolumn[START]  = getInputColumnNumber ();\n\t\tlinenum[SOURCE] = getSourceLineNumber ();\n\t}\n\n\t/* and read the content (until a matching end tag) */\n\twhile ((c = getcFromInputFile ()) != EOF)\n\t{\n\t\tif (c != delimiter)\n\t\t{\n\t\t\tvStringPut (string, c);\n\t\t\tif (empty_tag\n\t\t\t\t&& (KEYWORD_inquiry_directive == lookupCaseKeyword (vStringValue (string),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tLang_sql)\n\t\t\t\t\t|| isCCFlag(vStringValue (string))))\n\t\t\t{\n\t\t\t\t/* PL/SQL inquiry directives */\n\t\t\t\tint c0 = getcFromInputFile ();\n\n\t\t\t\tif (c0 != delimiter && (isalnum(c0) || c0 == '_'))\n\t\t\t\t{\n\t\t\t\t\tvStringPut (string, c0);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tungetcToInputFile (c0);\n\t\t\t\t/* Oracle PL/SQL's inquiry directive ($$name) */\n\t\t\t\treturn TOKEN_UNDEFINED;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tchar *end_p = tag;\n\n\t\t\twhile (c != EOF && *end_p && ((int) c) == *end_p)\n\t\t\t{\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t\tend_p++;\n\t\t\t}\n\n\t\t\tif (c != EOF)\n\t\t\t\tungetcToInputFile (c);\n\n\t\t\tif (! *end_p) /* full tag match */\n\t\t\t{\n\t\t\t\tif (promise)\n\t\t\t\t{\n\t\t\t\t\tlinenum[END] = getInputLineNumber ();\n\t\t\t\t\tcolumn[END]  = getInputColumnNumber ();\n\t\t\t\t\tif (column[END] > len)\n\t\t\t\t\t\tcolumn[END] -= len;\n\t\t\t\t\t*promise = makePromise (NULL,\n\t\t\t\t\t\t\t\t\t\t\tlinenum [START], column [START],\n\t\t\t\t\t\t\t\t\t\t\tlinenum [END], column [END],\n\t\t\t\t\t\t\t\t\t\t\tlinenum [SOURCE]);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t\tvStringNCatS (string, tag, (size_t) (end_p - tag));\n\t\t}\n\t}\n\n\treturn TOKEN_STRING;\n}\n\nstatic void readTokenFull (tokenInfo *const token, bool skippingPreproc)\n{\n\tint c;\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\ttoken->promise      = -1;\n\ngetNextChar:\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\ttoken->lineNumber   = getInputLineNumber ();\n\t\ttoken->filePosition = getInputFilePosition ();\n\t\t/*\n\t\t * Added \" to the list of ignores, not sure what this\n\t\t * might break but it gets by this issue:\n\t\t *\t  create table \"t1\" (...)\n\t\t *\n\t\t * Darren, the code passes all my tests for both\n\t\t * Oracle and SQL Anywhere, but maybe you can tell me\n\t\t * what this may effect.\n\t\t */\n\t}\n\twhile (c == '\\t'  ||  c == ' ' ||  c == '\\n');\n\n\tswitch (c)\n\t{\n\t\tcase EOF: token->type = TOKEN_EOF;\t\t\t\tbreak;\n\t\tcase '(':\n\t\t\t\t  token->type = TOKEN_OPEN_PAREN;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase ')':\n\t\t\t\t  token->type = TOKEN_CLOSE_PAREN;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase ':':\n\t\t\t\t  token->type = TOKEN_COLON;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase ';':\n\t\t\t\t  token->type = TOKEN_SEMICOLON;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase '.':\n\t\t\t\t  token->type = TOKEN_PERIOD;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase ',':\n\t\t\t\t  token->type = TOKEN_COMMA;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase '{':\n\t\t\t\t  token->type = TOKEN_OPEN_CURLY;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase '}':\n\t\t\t\t  token->type = TOKEN_CLOSE_CURLY;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase '~':\n\t\t\t\t  token->type = TOKEN_TILDE;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase '[':\n\t\t\t\t  token->type = TOKEN_OPEN_SQUARE;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase ']':\n\t\t\t\t  token->type = TOKEN_CLOSE_SQUARE;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\t\tcase '=':\n\t\t\t\t  token->type = TOKEN_EQUAL;\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  break;\n\n\t\tcase '\\'':\n\t\tcase '\"':\n\t\t\t\t  token->type = TOKEN_STRING;\n\t\t\t\t  parseString (token->string, c, &token->promise);\n\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t  break;\n\n\t\tcase '#':\n\t\t\t\tskipToCharacterInInputFile ('\\n');\n\t\t\t\tgoto getNextChar;\n\t\tcase '-':\n\t\t\t\t  c = getcFromInputFile ();\n\t\t\t\t  if (c == '-')\t\t/* -- is this the start of a comment? */\n\t\t\t\t  {\n\t\t\t\t\t  skipToCharacterInInputFile ('\\n');\n\t\t\t\t\t  goto getNextChar;\n\t\t\t\t  }\n\t\t\t\t  else\n\t\t\t\t  {\n\t\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t\t  if (!isspace (c))\n\t\t\t\t\t\t  ungetcToInputFile (c);\n\t\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t\t  token->type = TOKEN_OPERATOR;\n\t\t\t\t  }\n\t\t\t\t  break;\n\n\t\tcase '<':\n\t\tcase '>':\n\t\t\t\t  {\n\t\t\t\t\t  const int initial = c;\n\t\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t\t  int d = getcFromInputFile ();\n\t\t\t\t\t  if (d == initial)\n\t\t\t\t\t  {\n\t\t\t\t\t\t  vStringPut (token->string, d);\n\t\t\t\t\t\t  if (initial == '<')\n\t\t\t\t\t\t\t  token->type = TOKEN_BLOCK_LABEL_BEGIN;\n\t\t\t\t\t\t  else\n\t\t\t\t\t\t\t  token->type = TOKEN_BLOCK_LABEL_END;\n\t\t\t\t\t  }\n\t\t\t\t\t  else\n\t\t\t\t\t  {\n\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t\t  token->type = TOKEN_UNDEFINED;\n\t\t\t\t\t  }\n\t\t\t\t\t  break;\n\t\t\t\t  }\n\n\t\tcase '\\\\':\n\t\t\t\t  c = getcFromInputFile ();\n\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  if (c != '\\\\'  && c != '\"'  && c != '\\''  &&  !isspace (c))\n\t\t\t\t\t  ungetcToInputFile (c);\n\t\t\t\t  else\n\t\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t  token->type = TOKEN_CHARACTER;\n\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t  break;\n\n\t\tcase '/':\n\t\t\t\t  {\n\t\t\t\t\t  int d = getcFromInputFile ();\n\t\t\t\t\t  if ((d != '*') &&\t\t/* is this the start of a comment? */\n\t\t\t\t\t\t  (d != '/'))\t\t/* is a one line comment? */\n\t\t\t\t\t  {\n\t\t\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t\t\t  token->type = TOKEN_FORWARD_SLASH;\n\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t  }\n\t\t\t\t\t  else\n\t\t\t\t\t  {\n\t\t\t\t\t\t  if (d == '*')\n\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t  skipToCharacterInInputFile2('*', '/');\n\t\t\t\t\t\t\t  goto getNextChar;\n\t\t\t\t\t\t  }\n\t\t\t\t\t\t  else if (d == '/')\t/* is this the start of a comment?  */\n\t\t\t\t\t\t  {\n\t\t\t\t\t\t\t  skipToCharacterInInputFile ('\\n');\n\t\t\t\t\t\t\t  goto getNextChar;\n\t\t\t\t\t\t  }\n\t\t\t\t\t  }\n\t\t\t\t\t  break;\n\t\t\t\t  }\n\n\t\tcase '$':\n\t\t\t\t  {\n\t\t\t\t\t  /* Too complicated: we will not puts $ to token->string. */\n\t\t\t\t\t  tokenType t;\n\t\t\t\t\t  if (skippingPreproc)\n\t\t\t\t\t  {\n\t\t\t\t\t\t  int d = getcFromInputFile ();\n\t\t\t\t\t\t  if (d != '$')\n\t\t\t\t\t\t\t  ungetcToInputFile (d);\n\t\t\t\t\t  }\n\t\t\t\t\t  t = parseDollarQuote (token->string, c, &token->promise);\n\t\t\t\t\t  if (t == TOKEN_PREPROC_IF)\n\t\t\t\t\t  {\n\t\t\t\t\t\t  /* skip until $THEN and keep the content of this branch */\n\t\t\t\t\t\t  readTokenFull (token, true);\n\t\t\t\t\t\t  while (!isType (token, TOKEN_PREPROC_THEN) && !isType (token, TOKEN_EOF))\n\t\t\t\t\t\t\t  readTokenFull (token, true);\n\t\t\t\t\t\t  readTokenFull (token, false);\n\t\t\t\t\t  }\n\t\t\t\t\t  else if (!skippingPreproc && (t == TOKEN_PREPROC_ELSIF || t == TOKEN_PREPROC_ELSE))\n\t\t\t\t\t  {\n\t\t\t\t\t\t  /* skip until $END and drop $ELSIF and $ELSE branches */\n\t\t\t\t\t\t  readTokenFull (token, true);\n\t\t\t\t\t\t  while (!isType (token, TOKEN_PREPROC_END) && !isType (token, TOKEN_EOF))\n\t\t\t\t\t\t\t  readTokenFull (token, true);\n\t\t\t\t\t\t  readTokenFull (token, false);\n\t\t\t\t\t  }\n\t\t\t\t\t  else\n\t\t\t\t\t  {\n\t\t\t\t\t\t  token->type = t;\n\t\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t  }\n\t\t\t\t\t  break;\n\t\t\t\t  }\n\n\t\tdefault:\n\t\t\t\t  if (! isIdentChar1 (c))\n\t\t\t\t  {\n\t\t\t\t\t  vStringPut (token->string, c);\n\t\t\t\t\t  token->type = TOKEN_UNDEFINED;\n\t\t\t\t  }\n\t\t\t\t  else\n\t\t\t\t  {\n\t\t\t\t\t  parseIdentifier (token->string, c);\n\t\t\t\t\t  token->lineNumber = getInputLineNumber ();\n\t\t\t\t\t  token->filePosition = getInputFilePosition ();\n\t\t\t\t\t  token->keyword = lookupCaseKeyword (vStringValue (token->string), Lang_sql);\n\t\t\t\t\t  if (isKeyword (token, KEYWORD_rem))\n\t\t\t\t\t  {\n\t\t\t\t\t\t  vStringClear (token->string);\n\t\t\t\t\t\t  skipToCharacterInInputFile ('\\n');\n\t\t\t\t\t\t  goto getNextChar;\n\t\t\t\t\t  }\n\t\t\t\t\t  else if (isKeyword (token, KEYWORD_NONE))\n\t\t\t\t\t\t  token->type = TOKEN_IDENTIFIER;\n\t\t\t\t\t  else\n\t\t\t\t\t\t  token->type = TOKEN_KEYWORD;\n\t\t\t\t  }\n\t\t\t\t  break;\n\t}\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\treadTokenFull (token, false);\n}\n\n/*\n * reads an identifier, possibly quoted:\n * \t\tidentifier\n * \t\t\"identifier\"\n * \t\t[identifier]\n */\nstatic void readIdentifier (tokenInfo *const token)\n{\n\treadToken (token);\n\tif (isType (token, TOKEN_OPEN_SQUARE))\n\t{\n\t\ttokenInfo *const close_square = newToken ();\n\n\t\treadToken (token);\n\t\t/* eat close square */\n\t\treadToken (close_square);\n\t\tdeleteToken (close_square);\n\t}\n}\n\n/*\n *\t Token parsing functions\n */\n\n/*\n * static void addContext (tokenInfo* const parent, const tokenInfo* const child)\n * {\n *\t   if (vStringLength (parent->string) > 0)\n *\t   {\n *\t\t   vStringPut (parent->string, '.');\n *\t   }\n *\t   vStringCat (parent->string, child->string);\n * }\n */\n\nstatic void addToScope (tokenInfo* const token, vString* const extra, sqlKind kind)\n{\n\tvStringJoin (token->scope, '.', extra);\n\ttoken->scopeKind = kind;\n}\n\n/*\n *\t Scanning functions\n */\n\nstatic bool isOneOfKeyword (tokenInfo *const token, const keywordId *const keywords, unsigned int count)\n{\n\tunsigned int i;\n\tfor (i = 0; i < count; i++)\n\t{\n\t\tif (isKeyword (token, keywords[i]))\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic void findTokenOrKeywords (tokenInfo *const token, const tokenType type,\n\t\t\t\t const keywordId *const keywords,\n\t\t\t\t unsigned int kcount)\n{\n\twhile (! isType (token, type) &&\n\t       ! (isType (token, TOKEN_KEYWORD) && isOneOfKeyword (token, keywords, kcount)) &&\n\t       ! isType (token, TOKEN_EOF))\n\t{\n\t\treadToken (token);\n\t}\n}\n\nstatic void findToken (tokenInfo *const token, const tokenType type)\n{\n\twhile (! isType (token, type) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\treadToken (token);\n\t}\n}\n\nstatic void findCmdTerm (tokenInfo *const token, const bool check_first)\n{\n\tint begin_end_nest_lvl = token->begin_end_nest_lvl;\n\n\tif (check_first)\n\t{\n\t\tif (isCmdTerm(token))\n\t\t\treturn;\n\t}\n\tdo\n\t{\n\t\treadToken (token);\n\t} while (! isCmdTerm(token) &&\n\t\t\t ! isMatchedEnd(token, begin_end_nest_lvl) &&\n\t\t\t ! isType (token, TOKEN_EOF));\n}\n\nstatic void collectorAppend (collector *collector, tokenInfo *const token)\n{\n\tif (vStringIsEmpty (token->string))\n\t\treturn;\n\n\n\tint lastType = collector->xdata;\n\tcollectorStamp (collector, token->type);\n\n\tvString *str;\n\tvString *strrepr = NULL;\n\tif (isType (token, TOKEN_STRING))\n\t{\n\t\t/* Rebuild the original text on the source input. */\n\t\tstrrepr = vStringNew ();\n\n\t\tvStringPut (strrepr, '\\'');\n\t\tfor (size_t i = 0; i < vStringLength (token->string); i++)\n\t\t{\n\t\t\tchar c = vStringChar (token->string, i);\n\t\t\tif (c == '\\'')\n\t\t\t\tvStringCatS (strrepr, \"''\");\n\t\t\telse\n\t\t\t\tvStringPut (strrepr, c);\n\t\t}\n\t\tvStringPut (strrepr, '\\'');\n\n\t\tstr = strrepr;\n\t}\n\telse\n\t\tstr = token->string;\n\n\tif (isType (token, TOKEN_COMMA)\n\t\t|| isType (token, TOKEN_OPEN_PAREN)\n\t\t|| isType (token, TOKEN_OPEN_SQUARE) || isType (token, TOKEN_OPEN_CURLY)\n\t\t|| isType (token, TOKEN_CLOSE_PAREN)\n\t\t|| isType (token, TOKEN_CLOSE_SQUARE) || isType (token, TOKEN_CLOSE_CURLY)\n\t\t|| isType (token, TOKEN_PERIOD) || isType (token, TOKEN_COLON)\n\t\t|| lastType == TOKEN_OPEN_PAREN\n\t\t|| lastType == TOKEN_OPEN_SQUARE || lastType == TOKEN_OPEN_CURLY\n\t\t|| lastType == TOKEN_PERIOD || lastType == TOKEN_COLON\n\t\t|| (lastType == TOKEN_UNDEFINED && isType (token, TOKEN_UNDEFINED)))\n\t\tcollectorCat (collector, str);\n\telse\n\t\tcollectorJoin (collector, ' ', str);\n\n\tvStringDelete (strrepr);\t\t/* NULL is acceptable. */\n}\n\nstatic void skipToMatchedFull (tokenInfo *const token, collector *collector)\n{\n\tint nest_level = 0;\n\ttokenType open_token;\n\ttokenType close_token;\n\n\tswitch (token->type)\n\t{\n\t\tcase TOKEN_OPEN_PAREN:\n\t\t\topen_token  = TOKEN_OPEN_PAREN;\n\t\t\tclose_token = TOKEN_CLOSE_PAREN;\n\t\t\tbreak;\n\t\tcase TOKEN_OPEN_CURLY:\n\t\t\topen_token  = TOKEN_OPEN_CURLY;\n\t\t\tclose_token = TOKEN_CLOSE_CURLY;\n\t\t\tbreak;\n\t\tcase TOKEN_OPEN_SQUARE:\n\t\t\topen_token  = TOKEN_OPEN_SQUARE;\n\t\t\tclose_token = TOKEN_CLOSE_SQUARE;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn;\n\t}\n\n\t/*\n\t * This routine will skip to a matching closing token.\n\t * It will also handle nested tokens like the (, ) below.\n\t *\t (\tname varchar(30), text binary(10)  )\n\t */\n\n\tif (isType (token, open_token))\n\t{\n\t\tnest_level++;\n\t\twhile (nest_level > 0 && !isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (collector)\n\t\t\t\tcollectorAppend (collector, token);\n\t\t\tif (isType (token, open_token))\n\t\t\t{\n\t\t\t\tnest_level++;\n\t\t\t}\n\t\t\tif (isType (token, close_token))\n\t\t\t{\n\t\t\t\tif (nest_level > 0)\n\t\t\t\t{\n\t\t\t\t\tnest_level--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treadToken (token);\n\t}\n}\n\nstatic void skipToMatched (tokenInfo *const token)\n{\n\tskipToMatchedFull (token, NULL);\n}\n\nstatic void copyToken (tokenInfo *const dest, tokenInfo *const src)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tdest->keyword = src->keyword;\n\tvStringCopy(dest->string, src->string);\n\tvStringCopy(dest->scope, src->scope);\n\tdest->scopeKind = src->scopeKind;\n}\n\nstatic void skipArgumentListFull (tokenInfo *const token, collector *collector)\n{\n\t/*\n\t * Other databases can have arguments with fully declared\n\t * datatypes:\n\t *\t (\tname varchar(30), text binary(10)  )\n\t * So we must check for nested open and closing parentheses\n\t */\n\n\tif (isType (token, TOKEN_OPEN_PAREN))\t/* arguments? */\n\t{\n\t\tif (collector)\n\t\t\tcollectorAppend (collector, token);\n\t\tskipToMatchedFull (token, collector);\n\t}\n}\n\nstatic void collectParameterList (tokenInfo *const token, collector *collector)\n{\n\tskipArgumentListFull (token, collector);\n}\n\nstatic void skipArgumentList (tokenInfo *const token)\n{\n\tskipArgumentListFull (token, NULL);\n}\n\nstatic langType getNamedLanguageFromToken (tokenInfo *const token)\n{\n\tlangType lang = LANG_IGNORE;\n\n\tif (isType (token, TOKEN_IDENTIFIER)\n\t\t/* https://www.postgresql.org/docs/current/sql-createprocedure.html\n\t\t   ... Enclosing the name in single quotes is deprecated and requires matching\n\t\t   case. ...*/\n\t\t|| isType (token, TOKEN_STRING))\n\t{\n\t\tif (vStringLength (token->string) > 2\n\t\t\t&& vStringValue (token->string) [0] == 'p'\n\t\t\t&& vStringValue (token->string) [1] == 'l')\n\t\t{\n\t\t\t/* Remove first 'pl' and last 'u' for extracting the\n\t\t\t * name of the language. */\n\t\t\tbool unsafe = (vStringLast(token->string) == 'u');\n\t\t\tlang = getNamedLanguageOrAlias (vStringValue (token->string) + 2,\n\t\t\t\t\t\t\t\t\t\t\tvStringLength (token->string)\n\t\t\t\t\t\t\t\t\t\t\t- 2\n\t\t\t\t\t\t\t\t\t\t\t- (unsafe? 1: 0));\n\t\t}\n\t}\n\treturn lang;\n}\n\nstatic void fillExtensionFields (tagEntryInfo *e, collector *signature, collector *typeref)\n{\n\tif (signature->repr)\n\t\te->extensionFields.signature =  collectorStrdup (signature);\n\tif (typeref->repr)\n\t{\n\t\te->extensionFields.typeRef[0] = eStrdup (\"typename\");\n\t\te->extensionFields.typeRef[1] = collectorStrdup (typeref);\n\t}\n}\n\nstatic void parseSubProgram (tokenInfo *const token)\n{\n\ttokenInfo *const name  = newToken ();\n\tvString * saveScope = vStringNew ();\n\tsqlKind saveScopeKind;\n\n\tcollector signature = { .repr = 0 };\n\tcollector typeref = { .repr = 0 };\n\n\t/*\n\t * This must handle both prototypes and the body of\n\t * the procedures.\n\t *\n\t * Prototype:\n\t *\t   FUNCTION func_name RETURN integer;\n\t *\t   PROCEDURE proc_name( parameters );\n\t * Procedure\n\t *\t   FUNCTION GET_ML_USERNAME RETURN VARCHAR2\n\t *\t   IS\n\t *\t   BEGIN\n\t *\t\t   RETURN v_sync_user_id;\n\t *\t   END GET_ML_USERNAME;\n\t *\n\t *\t   PROCEDURE proc_name( parameters )\n\t *\t\t   IS\n\t *\t\t   BEGIN\n\t *\t\t   END;\n\t *\t   CREATE PROCEDURE proc_name( parameters )\n\t *\t\t   EXTERNAL NAME ... ;\n\t *\t   CREATE PROCEDURE proc_name( parameters )\n\t *\t\t   BEGIN\n\t *\t\t   END;\n\t *\n\t *\t   CREATE FUNCTION f_GetClassName(\n\t *\t\t   IN @object VARCHAR(128)\n\t *\t\t  ,IN @code   VARCHAR(128)\n\t *\t   )\n\t *\t   RETURNS VARCHAR(200)\n\t *\t   DETERMINISTIC\n\t *\t   BEGIN\n\t *\n\t *\t\t   IF( @object = 'user_state' ) THEN\n\t *\t\t\t   SET something = something;\n\t *\t\t   END IF;\n\t *\n\t *\t\t   RETURN @name;\n\t *\t   END;\n\t *\n\t * Note, a Package adds scope to the items within.\n\t *     create or replace package demo_pkg is\n\t *         test_var number;\n\t *         function test_func return varchar2;\n\t *         function more.test_func2 return varchar2;\n\t *     end demo_pkg;\n\t * So the tags generated here, contain the package name:\n\t *         demo_pkg.test_var\n\t *         demo_pkg.test_func\n\t *         demo_pkg.more.test_func2\n\t *\n\t *  ---\n\t *  PostgreSQL 18devel Documentation/36.5. Query Language (SQL) Functions\n\t *         https://www.postgresql.org/docs/devel/xfunc-sql.html\n\t */\n\tconst sqlKind kind = isKeyword (token, KEYWORD_function) ?\n\t\tSQLTAG_FUNCTION : SQLTAG_PROCEDURE;\n\tAssert (isKeyword (token, KEYWORD_function) ||\n\t\t\tisKeyword (token, KEYWORD_procedure));\n\n\tvStringCopy(saveScope, token->scope);\n\tsaveScopeKind = token->scopeKind;\n\treadToken (token);\n\tcopyToken (name, token);\n\treadToken (token);\n\n\tif (isType (token, TOKEN_PERIOD))\n\t{\n\t\t/*\n\t\t * If this is an Oracle package, then the token->scope should\n\t\t * already be set.  If this is the case, also add this value to the\n\t\t * scope.\n\t\t * If this is not an Oracle package, chances are the scope should be\n\t\t * blank and the value just read is the OWNER or CREATOR of the\n\t\t * function and should not be considered part of the scope.\n\t\t */\n\t\tif (vStringLength(saveScope) > 0)\n\t\t{\n\t\t\taddToScope(token, name->string, kind);\n\t\t}\n\t\treadToken (token);\n\t\tcopyToken (name, token);\n\t\treadToken (token);\n\t}\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\t/* Reads to the next token after the TOKEN_CLOSE_PAREN */\n\t\tcollectorInit (&signature, TOKEN_EOF);\n\t\tcollectParameterList (token, &signature);\n\t}\n\n\tif (kind == SQLTAG_FUNCTION)\n\t{\n\t\tif (isKeyword (token, KEYWORD_return) ||\n\t\t\tisKeyword (token, KEYWORD_returns))\n\t\t{\n\t\t\t/* Read datatype */\n\t\t\treadToken (token);\n\t\t\tcollectorInit (&typeref, TOKEN_EOF);\n\t\t\tcollectorCat (&typeref, token->string);\n\n\t\t\t/*\n\t\t\t * Read token after which could be the\n\t\t\t * command terminator if a prototype\n\t\t\t * or an open parenthesis\n\t\t\t */\n\t\t\treadToken (token);\n\t\t\twhile (isType (token, TOKEN_IDENTIFIER)\n\t\t\t\t   || isType (token, TOKEN_PERIOD))\n\t\t\t{\n\t\t\t\tcollectorAppend (&typeref, token);\n\t\t\t\treadToken (token);\n\t\t\t}\n\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t{\n\t\t\t\t/* Reads to the next token after the TOKEN_CLOSE_PAREN. */\n\t\t\t\tcollectParameterList (token, &typeref);\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t{\n\t\t\t\tcollectorAppend (&typeref, token);\n\t\t\t\tskipToMatchedFull (token, &typeref);\n\t\t\t}\n\t\t}\n\t}\n\tif (isCmdTerm (token))\n\t{\n\t\tmakeSqlTag (name, SQLTAG_PROTOTYPE);\n\t}\n\telse\n\t{\n\t\tlangType lang = LANG_IGNORE;\n\n\t\twhile (! isKeyword (token, KEYWORD_is) &&\n\t\t\t   ! isKeyword (token, KEYWORD_begin) &&\n\t\t\t   ! isKeyword (token, KEYWORD_at) &&\n\t\t\t   ! isKeyword (token, KEYWORD_internal) &&\n\t\t\t   ! isKeyword (token, KEYWORD_external) &&\n\t\t\t   ! isKeyword (token, KEYWORD_url) &&\n\t\t\t   ! isType (token, TOKEN_EQUAL) &&\n\t\t\t   ! isType (token, TOKEN_EOF) &&\n\t\t\t   ! isCmdTerm (token))\n\t\t{\n\t\t\tif (isKeyword (token, KEYWORD_result))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t\t{\n\t\t\t\t\t/* Reads to the next token after the TOKEN_CLOSE_PAREN */\n\t\t\t\t\tskipArgumentList(token);\n\t\t\t\t}\n\t\t\t} else if (lang == LANG_IGNORE\n\t\t\t\t\t   && isKeyword (token, KEYWORD_language)) {\n\t\t\t\treadToken (token);\n\t\t\t\tlang = getNamedLanguageFromToken (token);\n\t\t\t\tif (lang != LANG_IGNORE)\n\t\t\t\t\treadToken (token);\n\t\t\t} else {\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t}\n\t\tif (isKeyword (token, KEYWORD_at) ||\n\t\t\tisKeyword (token, KEYWORD_url) ||\n\t\t\tisKeyword (token, KEYWORD_internal) ||\n\t\t\tisKeyword (token, KEYWORD_external))\n\t\t{\n\t\t\taddToScope(token, name->string, kind);\n\t\t\tif (isType (name, TOKEN_IDENTIFIER) ||\n\t\t\t\tisType (name, TOKEN_STRING) ||\n\t\t\t\tisType (name, TOKEN_KEYWORD))\n\t\t\t{\n\t\t\t\tmakeSqlTag (name, kind);\n\t\t\t}\n\n\t\t\tvStringClear (token->scope);\n\t\t\ttoken->scopeKind = SQLTAG_COUNT;\n\t\t}\n\t\tif (isType (token, TOKEN_EQUAL))\n\t\t\treadToken (token);\n\n\t\tif (isKeyword (token, KEYWORD_declare))\n\t\t\tparseDeclare (token, false);\n\n\t\tif (isKeyword (token, KEYWORD_is) ||\n\t\t\tisKeyword (token, KEYWORD_begin))\n\t\t{\n\t\t\taddToScope(token, name->string, kind);\n\t\t\tif (isType (name, TOKEN_IDENTIFIER) ||\n\t\t\t\tisType (name, TOKEN_STRING) ||\n\t\t\t\tisType (name, TOKEN_KEYWORD))\n\t\t\t{\n\t\t\t\tint fq = CORK_NIL;\n\t\t\t\tint r = makeSqlTagFull (name, kind, &fq);\n\n\t\t\t\ttagEntryInfo *e;\n\t\t\t\te = getEntryInCorkQueue (r);\n\t\t\t\tif (e)\n\t\t\t\t\tfillExtensionFields (e, &signature, &typeref);\n\t\t\t\te = getEntryInCorkQueue (fq);\n\t\t\t\tif (e)\n\t\t\t\t\tfillExtensionFields (e, &signature, &typeref);\n\t\t\t}\n\n\t\t\tparseBlockFull (token, true, lang);\n\t\t\tvStringClear (token->scope);\n\t\t\ttoken->scopeKind = SQLTAG_COUNT;\n\t\t}\n\t}\n\tvStringCopy(token->scope, saveScope);\n\ttoken->scopeKind = saveScopeKind;\n\tif (typeref.repr)\n\t\tcollectorFini (&typeref);\t/* NULL is acceptable. */\n\tif (signature.repr)\n\t\tcollectorFini (&signature);\t/* NULL is acceptable. */\n\tdeleteToken (name);\n\tvStringDelete(saveScope);\n}\n\nstatic void parseRecord (tokenInfo *const token)\n{\n\t/*\n\t * Make it a bit forgiving, this is called from\n\t * multiple functions, parseTable, parseType\n\t */\n\tif (!isType (token, TOKEN_OPEN_PAREN))\n\t\treadToken (token);\n\tif (!isType (token, TOKEN_OPEN_PAREN))\n\t\treturn;\n\n\tdo\n\t{\n\t\tif (isType (token, TOKEN_COMMA) ||\n\t\t\tisType (token, TOKEN_OPEN_PAREN))\n\t\t{\n\t\t\treadToken (token);\n\t\t}\n\n\t\t/*\n\t\t * Create table statements can end with various constraints\n\t\t * which must be excluded from the SQLTAG_FIELD.\n\t\t *\t  create table t1 (\n\t\t *\t\t  c1 integer,\n\t\t *\t\t  c2 char(30),\n\t\t *\t\t  c3 numeric(10,5),\n\t\t *\t\t  c4 integer,\n\t\t *\t\t  constraint whatever,\n\t\t *\t\t  primary key(c1),\n\t\t *\t\t  foreign key (),\n\t\t *\t\t  check ()\n\t\t *\t  )\n\t\t */\n\t\tif (! isKeyword(token, KEYWORD_primary) &&\n\t\t\t! isKeyword(token, KEYWORD_references) &&\n\t\t\t! isKeyword(token, KEYWORD_unique) &&\n\t\t\t! isKeyword(token, KEYWORD_check) &&\n\t\t\t! isKeyword(token, KEYWORD_constraint) &&\n\t\t\t! isKeyword(token, KEYWORD_foreign))\n\t\t{\n\t\t\t/* keyword test above is redundant as only a TOKEN_KEYWORD could\n\t\t\t * match any isKeyword() anyway */\n\t\t\tif (isType (token, TOKEN_IDENTIFIER) ||\n\t\t\t\tisType (token, TOKEN_STRING)     ||\n\t\t\t\t(isType (token, TOKEN_KEYWORD)\n\t\t\t\t && (!isReservedWord (token))))\n\t\t\t{\n\t\t\t\tmakeSqlTag (token, SQLTAG_FIELD);\n\t\t\t}\n\t\t}\n\n\t\twhile (! isType (token, TOKEN_COMMA) &&\n\t\t\t   ! isType (token, TOKEN_CLOSE_PAREN) &&\n\t\t\t   ! isType (token, TOKEN_OPEN_PAREN) &&\n\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t\t/*\n\t\t\t * A table structure can look like this:\n\t\t\t *\t  create table t1 (\n\t\t\t *\t\t  c1 integer,\n\t\t\t *\t\t  c2 char(30),\n\t\t\t *\t\t  c3 numeric(10,5),\n\t\t\t *\t\t  c4 integer\n\t\t\t *\t  )\n\t\t\t * We can't just look for a COMMA or CLOSE_PAREN\n\t\t\t * since that will not deal with the numeric(10,5)\n\t\t\t * case.  So we need to skip the argument list\n\t\t\t * when we find an open paren.\n\t\t\t */\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t{\n\t\t\t\t/* Reads to the next token after the TOKEN_CLOSE_PAREN */\n\t\t\t\tskipArgumentList(token);\n\t\t\t}\n\t\t}\n\t} while (! isType (token, TOKEN_CLOSE_PAREN) &&\n\t\t\t ! isType (token, TOKEN_EOF));\n}\n\nstatic void parseType (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\tvString * saveScope = vStringNew ();\n\tsqlKind saveScopeKind;\n\n\tvStringCopy(saveScope, token->scope);\n\t/* If a scope has been set, add it to the name */\n\taddToScope (name, token->scope, token->scopeKind);\n\tsaveScopeKind = token->scopeKind;\n\treadIdentifier (name);\n\n\t/* Consider \"CREATE TYPE BODY t\" in oracle. */\n\tif (isType (name, TOKEN_KEYWORD)\n\t\t&& isKeyword (name, KEYWORD_body))\n\t\treadIdentifier (name);\n\n\twhile (isType (name, TOKEN_IDENTIFIER) ||\n\t\t   isType (name, TOKEN_STRING) ||\n\t\t   (isType (name, TOKEN_KEYWORD)\n\t\t\t&& (!isReservedWord (name))))\n\t{\n\t\treadToken (token);\n\t\tif (!isType (token, TOKEN_PERIOD))\n\t\t\tbreak;\n\t\t/* FIXME: Throw away valuable scope information. */\n\t\treadIdentifier (name);\n\t}\n\n\tif (isType (name, TOKEN_IDENTIFIER) ||\n\t\tisType (name, TOKEN_STRING) ||\n\t\t\t(isType (name, TOKEN_KEYWORD)\n\t\t\t && (!isReservedWord (name))))\n\t{\n\t\tint r = makeSqlTag (name, SQLTAG_TYPE);\n\t\tsqlKind scopeKind = SQLTAG_TYPE;\n\n\t\tif (isKeyword (token, KEYWORD_is))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_KEYWORD))\n\t\t\t{\n\t\t\t\tswitch (token->keyword)\n\t\t\t\t{\n\t\t\t\tcase KEYWORD_record:\n\t\t\t\tcase KEYWORD_object:\n\t\t\t\t\tif (isLanguageKindEnabled (Lang_sql, SQLTAG_RECORD))\n\t\t\t\t\t{\n\t\t\t\t\t\tmakeSqlTagInstead (name, SQLTAG_RECORD, r);\n\t\t\t\t\t\tscopeKind = SQLTAG_RECORD;\n\t\t\t\t\t}\n\t\t\t\t\taddToScope (token, name->string, scopeKind);\n\t\t\t\t\tparseRecord (token);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase KEYWORD_table:\n\t\t\t\t\tif (isLanguageKindEnabled (Lang_sql, SQLTAG_TABLE))\n\t\t\t\t\t\tmakeSqlTagInstead (name, SQLTAG_TABLE, r);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase KEYWORD_ref:\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isKeyword (token, KEYWORD_cursor)\n\t\t\t\t\t\t&& isLanguageKindEnabled (Lang_sql, SQLTAG_CURSOR))\n\t\t\t\t\t\t\tmakeSqlTagInstead (name, SQLTAG_CURSOR, r);\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\t/* TODO: PostgreSQL can take 'enum (' and 'range (' here.\n\t\t\t\t\t * Add them as keywords first when implementing this branch. */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t{\n\t\t\t\tif (isLanguageKindEnabled (Lang_sql, SQLTAG_RECORD))\n\t\t\t\t{\n\t\t\t\t\t/* When the record kind is enabled, emit a\n\t\t\t\t\t * record tag and suppress the type tag. */\n\t\t\t\t\tmakeSqlTagInstead (name, SQLTAG_RECORD, r);\n\t\t\t\t\tscopeKind = SQLTAG_RECORD;\n\t\t\t\t}\n\t\t\t\taddToScope (token, name->string, scopeKind);\n\t\t\t\tparseRecord (token);\n\t\t\t}\n\t\t\tvStringClear (token->scope);\n\t\t\ttoken->scopeKind = SQLTAG_COUNT;\n\t\t}\n\t\telse if (isType (token, TOKEN_SEMICOLON))\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\t\t\tif (e)\n\t\t\t\tassignRole (e, R_SQLTAG_TYPE_DECL);\n\t\t}\n\t}\n\tvStringCopy(token->scope, saveScope);\n\ttoken->scopeKind = saveScopeKind;\n\tdeleteToken (name);\n\tvStringDelete(saveScope);\n}\n\nstatic void parseSimple (tokenInfo *const token, const sqlKind kind)\n{\n\t/* This will simply make the tagname from the first word found */\n\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER) ||\n\t\tisType (token, TOKEN_STRING))\n\t{\n\t\tmakeSqlTag (token, kind);\n\t}\n}\n\nstatic void parseDeclare (tokenInfo *const token, const bool local)\n{\n\t/*\n\t * PL/SQL declares are of this format:\n\t *\t  IS|AS\n\t *\t  [declare]\n\t *\t\t CURSOR curname ...\n\t *\t\t varname1 datatype;\n\t *\t\t varname2 datatype;\n\t *\t\t varname3 datatype;\n\t *\t  begin\n\t */\n\n\tif (isKeyword (token, KEYWORD_declare))\n\t\treadToken (token);\n\twhile (! isKeyword (token, KEYWORD_begin) &&\n\t\t   ! isKeyword (token, KEYWORD_end) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\tkeywordId stoppers [] = {\n\t\t\tKEYWORD_begin,\n\t\t\tKEYWORD_end,\n\t\t};\n\n\t\tswitch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_cursor:\tparseSimple (token, SQLTAG_CURSOR); break;\n\t\t\tcase KEYWORD_function:\tparseSubProgram (token); break;\n\t\t\tcase KEYWORD_procedure: parseSubProgram (token); break;\n\t\t\tcase KEYWORD_subtype:\tparseSimple (token, SQLTAG_SUBTYPE); break;\n\t\t\tcase KEYWORD_trigger:\tparseSimple (token, SQLTAG_TRIGGER); break;\n\t\t\tcase KEYWORD_type:\t\tparseType (token); break;\n\n\t\t\tdefault:\n\t\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\t{\n\t\t\t\t\tmakeSqlTag (token, local? SQLTAG_LOCAL_VARIABLE: SQLTAG_VARIABLE);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\tfindTokenOrKeywords (token, TOKEN_SEMICOLON, stoppers, ARRAY_SIZE (stoppers));\n\t\tif (isType (token, TOKEN_SEMICOLON))\n\t\t\treadToken (token);\n\t}\n}\n\nstatic void parseDeclareANSI (tokenInfo *const token, const bool local)\n{\n\ttokenInfo *const type = newToken ();\n\t/*\n\t * ANSI declares are of this format:\n\t *\t BEGIN\n\t *\t\t DECLARE varname1 datatype;\n\t *\t\t DECLARE varname2 datatype;\n\t *\t\t ...\n\t *\n\t * This differ from PL/SQL where DECLARE precedes the BEGIN block\n\t * and the DECLARE keyword is not repeated.\n\t */\n\twhile (isKeyword (token, KEYWORD_declare))\n\t{\n\t\treadToken (token);\n\t\treadToken (type);\n\n\t\tif (isKeyword (type, KEYWORD_cursor))\n\t\t\tmakeSqlTag (token, SQLTAG_CURSOR);\n\t\telse if (isKeyword (token, KEYWORD_local) &&\n\t\t\t\t isKeyword (type, KEYWORD_temporary))\n\t\t{\n\t\t\t/*\n\t\t\t * DECLARE LOCAL TEMPORARY TABLE table_name (\n\t\t\t *\t  c1 int,\n\t\t\t *\t  c2 int\n\t\t\t * );\n\t\t\t */\n\t\t\treadToken (token);\n\t\t\tif (isKeyword (token, KEYWORD_table))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (isType(token, TOKEN_IDENTIFIER) ||\n\t\t\t\t\tisType(token, TOKEN_STRING))\n\t\t\t\t{\n\t\t\t\t\tmakeSqlTag (token, SQLTAG_TABLE);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_IDENTIFIER) ||\n\t\t\t\t isType (token, TOKEN_STRING))\n\t\t{\n\t\t\tmakeSqlTag (token, local? SQLTAG_LOCAL_VARIABLE: SQLTAG_VARIABLE);\n\t\t}\n\t\tfindToken (token, TOKEN_SEMICOLON);\n\t\treadToken (token);\n\t}\n\tdeleteToken (type);\n}\n\nstatic void parseLabel (tokenInfo *const token)\n{\n\t/*\n\t * A label has this format:\n\t *\t   <<tobacco_dependency>>\n\t *\t   DECLARE\n\t *\t\t  v_senator VARCHAR2(100) := 'THURMOND, JESSE';\n\t *\t   BEGIN\n\t *\t\t  IF total_contributions (v_senator, 'TOBACCO') > 25000\n\t *\t\t  THEN\n\t *\t\t\t <<alochol_dependency>>\n\t *\t\t\t DECLARE\n\t *\t\t\t\tv_senator VARCHAR2(100) := 'WHATEVERIT, TAKES';\n\t *\t\t\t BEGIN\n\t *\t\t\t\t...\n\t */\n\n\tAssert (isType (token, TOKEN_BLOCK_LABEL_BEGIN));\n\treadToken (token);\n\tif (isType (token, TOKEN_IDENTIFIER))\n\t{\n\t\tmakeSqlTag (token, SQLTAG_BLOCK_LABEL);\n\t\treadToken (token);\t\t  /* read end of label */\n\t}\n}\n\nstatic void parseStatements (tokenInfo *const token, const bool exit_on_endif )\n{\n\t/* bool isAnsi   = true; */\n\tbool stmtTerm = false;\n\tdo\n\t{\n\n\t\tif (isType (token, TOKEN_BLOCK_LABEL_BEGIN))\n\t\t\tparseLabel (token);\n\t\telse\n\t\t{\n\t\t\tswitch (token->keyword)\n\t\t\t{\n\t\t\t\tcase KEYWORD_exception:\n\t\t\t\t\t/*\n\t\t\t\t\t * EXCEPTION\n\t\t\t\t\t *\t <exception handler>;\n\t\t\t\t\t *\n\t\t\t\t\t * Where an exception handler could be:\n\t\t\t\t\t *\t BEGIN\n\t\t\t\t\t *\t\tWHEN OTHERS THEN\n\t\t\t\t\t *\t\t\tx := x + 3;\n\t\t\t\t\t *\t END;\n\t\t\t\t\t * In this case we need to skip this keyword and\n\t\t\t\t\t * move on to the next token without reading until\n\t\t\t\t\t * TOKEN_SEMICOLON;\n\t\t\t\t\t */\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tcontinue;\n\n\t\t\t\tcase KEYWORD_when:\n\t\t\t\t\t/*\n\t\t\t\t\t * WHEN statements can be used in exception clauses\n\t\t\t\t\t * and CASE statements.  The CASE statement should skip\n\t\t\t\t\t * these given below we skip over to an END statement.\n\t\t\t\t\t * But for an exception clause, we can have:\n\t\t\t\t\t *\t   EXCEPTION\n\t\t\t\t\t *\t\t   WHEN OTHERS THEN\n\t\t\t\t\t *\t\t   BEGIN\n\t\t\t\t\t *\t\t\t\t  x := x + 3;\n\t\t\t\t\t *\t\t   END;\n\t\t\t\t\t * If we skip to the TOKEN_SEMICOLON, we miss the begin\n\t\t\t\t\t * of a nested BEGIN END block.  So read the next token\n\t\t\t\t\t * after the THEN and restart the LOOP.\n\t\t\t\t\t */\n\t\t\t\t\twhile (! isKeyword (token, KEYWORD_then) &&\n\t\t\t\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t\t\t\t\treadToken (token);\n\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tcontinue;\n\n\t\t\t\tcase KEYWORD_if:\n\t\t\t\t\t/*\n\t\t\t\t\t * We do not want to look for a ; since for an empty\n\t\t\t\t\t * IF block, it would skip over the END.\n\t\t\t\t\t *\tIF...THEN\n\t\t\t\t\t *\tEND IF;\n\t\t\t\t\t *\n\t\t\t\t\t *\tIF...THEN\n\t\t\t\t\t *\tELSE\n\t\t\t\t\t *\tEND IF;\n\t\t\t\t\t *\n\t\t\t\t\t *\tIF...THEN\n\t\t\t\t\t *\tELSEIF...THEN\n\t\t\t\t\t *\tELSE\n\t\t\t\t\t *\tEND IF;\n\t\t\t\t\t *\n\t\t\t\t\t *\tor non-ANSI\n\t\t\t\t\t *\tIF ...\n\t\t\t\t\t *\tBEGIN\n\t\t\t\t\t *\tEND\n\t\t\t\t\t */\n\t\t\t\t\twhile (! isKeyword (token, KEYWORD_then)  &&\n\t\t\t\t\t\t   ! isKeyword (token, KEYWORD_begin) &&\n\t\t\t\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isKeyword (token, KEYWORD_begin))\n\t\t\t\t\t{\n\t\t\t\t\t\t/* isAnsi = false; */\n\t\t\t\t\t\tparseBlock(token, false);\n\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * Handle the non-Ansi IF blocks.\n\t\t\t\t\t\t * parseBlock consumes the END, so if the next\n\t\t\t\t\t\t * token in a command terminator (like GO)\n\t\t\t\t\t\t * we know we are done with this statement.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (isCmdTerm (token))\n\t\t\t\t\t\t\tstmtTerm = true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\n\t\t\t\t\t\twhile (! isKeyword (token, KEYWORD_end) &&\n\t\t\t\t\t\t\t   ! isKeyword (token, KEYWORD_endif) &&\n\t\t\t\t\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (isKeyword (token, KEYWORD_else) ||\n\t\t\t\t\t\t\t\tisKeyword (token, KEYWORD_elseif))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tparseStatements (token, true);\n\n\t\t\t\t\t\t\tif (isCmdTerm(token))\n\t\t\t\t\t\t\t\treadToken (token);\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * parseStatements returns when it finds an END, an IF\n\t\t\t\t\t\t * should follow the END for ANSI anyway.\n\t\t\t\t\t\t *\tIF...THEN\n\t\t\t\t\t\t *\tEND IF;\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (isKeyword (token, KEYWORD_end))\n\t\t\t\t\t\t\treadToken (token);\n\n\t\t\t\t\t\tif (isKeyword (token, KEYWORD_if) ||\n\t\t\t\t\t\t\tisKeyword (token, KEYWORD_endif))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t\tif (isCmdTerm(token))\n\t\t\t\t\t\t\t\tstmtTerm = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t * Well we need to do something here.\n\t\t\t\t\t\t\t * There are lots of different END statements\n\t\t\t\t\t\t\t * END;\n\t\t\t\t\t\t\t * END CASE;\n\t\t\t\t\t\t\t * ENDIF;\n\t\t\t\t\t\t\t * ENDCASE;\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase KEYWORD_loop:\n\t\t\t\tcase KEYWORD_case:\n\t\t\t\tcase KEYWORD_for:\n\t\t\t\t\t/*\n\t\t\t\t\t *\tLOOP...\n\t\t\t\t\t *\tEND LOOP;\n\t\t\t\t\t *\n\t\t\t\t\t *\tCASE\n\t\t\t\t\t *\tWHEN '1' THEN\n\t\t\t\t\t *\tEND CASE;\n\t\t\t\t\t *\n\t\t\t\t\t *\tFOR loop_name AS cursor_name CURSOR FOR ...\n\t\t\t\t\t *\tDO\n\t\t\t\t\t *\tEND FOR;\n\t\t\t\t\t */\n\t\t\t\t\tif (isKeyword (token, KEYWORD_for))\n\t\t\t\t\t{\n\t\t\t\t\t\t/* loop name */\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t/* AS */\n\t\t\t\t\t\treadToken (token);\n\n\t\t\t\t\t\twhile (! isKeyword (token, KEYWORD_is) &&\n\t\t\t\t\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t * If this is not an AS keyword this is\n\t\t\t\t\t\t\t * not a proper FOR statement and should\n\t\t\t\t\t\t\t * simply be ignored\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\twhile (! isKeyword (token, KEYWORD_do) &&\n\t\t\t\t\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\n\n\t\t\t\t\treadToken (token);\n\t\t\t\t\twhile (! isKeyword (token, KEYWORD_end) &&\n\t\t\t\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t\t\t\t{\n\t\t\t\t\t\t/*\n\t\t\t\t\t\tif ( isKeyword (token, KEYWORD_else) ||\n\t\t\t\t\t\t\t\tisKeyword (token, KEYWORD_elseif)    )\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t\t*/\n\n\t\t\t\t\t\tparseStatements (token, false);\n\n\t\t\t\t\t\tif (isCmdTerm(token))\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\n\n\t\t\t\t\tif (isKeyword (token, KEYWORD_end ))\n\t\t\t\t\t\treadToken (token);\n\n\t\t\t\t\t/*\n\t\t\t\t\t * Typically ended with\n\t\t\t\t\t *    END LOOP [loop name];\n\t\t\t\t\t *    END CASE\n\t\t\t\t\t *    END FOR [loop name];\n\t\t\t\t\t */\n\t\t\t\t\tif (isKeyword (token, KEYWORD_loop) ||\n\t\t\t\t\t\tisKeyword (token, KEYWORD_case) ||\n\t\t\t\t\t\tisKeyword (token, KEYWORD_for))\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isCmdTerm(token))\n\t\t\t\t\t\tstmtTerm = true;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase KEYWORD_create:\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tparseKeywords(token, KEYWORD_create);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase KEYWORD_declare:\n\t\t\t\tcase KEYWORD_begin:\n\t\t\t\t\tparseBlock (token, true);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase KEYWORD_end:\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/*\n\t\t\t * Not all statements must end in a semi-colon\n\t\t\t *\t   begin\n\t\t\t *\t\t   if current publisher <> 'publish' then\n\t\t\t *\t\t\t signal UE_FailStatement\n\t\t\t *\t\t   end if\n\t\t\t *\t   end;\n\t\t\t * The last statement prior to an end (\"signal\" above) does\n\t\t\t * not need a semi-colon, nor does the end if, since it is\n\t\t\t * also the last statement prior to the end of the block.\n\t\t\t *\n\t\t\t * So we must read to the first semi-colon or an END block\n\t\t\t */\n\t\t\twhile (! stmtTerm &&\n\t\t\t\t   ! isKeyword (token, KEYWORD_end) &&\n\t\t\t\t   ! isCmdTerm(token) &&\n\t\t\t\t   ! isType(token, TOKEN_EOF))\n\t\t\t{\n\t\t\t\tif (exit_on_endif && isKeyword (token, KEYWORD_endif))\n\t\t\t\t\treturn;\n\n\t\t\t\tif (isType (token, TOKEN_COLON) )\n\t\t\t\t{\n\t\t\t\t\t/*\n\t\t\t\t\t * A : can signal a loop name\n\t\t\t\t\t *    myloop:\n\t\t\t\t\t *    LOOP\n\t\t\t\t\t *        LEAVE myloop;\n\t\t\t\t\t *    END LOOP;\n\t\t\t\t\t * Unfortunately, labels do not have a\n\t\t\t\t\t * cmd terminator, therefore we have to check\n\t\t\t\t\t * if the next token is a keyword and process\n\t\t\t\t\t * it accordingly.\n\t\t\t\t\t */\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isKeyword (token, KEYWORD_loop) ||\n\t\t\t\t\t\tisKeyword (token, KEYWORD_while) ||\n\t\t\t\t\t\tisKeyword (token, KEYWORD_for))\n\t\t\t\t\t{\n\t\t\t\t\t\t/* parseStatements (token); */\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treadToken (token);\n\n\t\t\t\tif (isType (token, TOKEN_OPEN_PAREN) ||\n\t\t\t\t    isType (token, TOKEN_OPEN_CURLY) ||\n\t\t\t\t    isType (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t{\n\t\t\t\t\tskipToMatched (token);\n\t\t\t\t}\n\n\t\t\t\t/*\n\t\t\t\t * Since we know how to parse various statements\n\t\t\t\t * if we detect them, parse them to completion\n\t\t\t\t */\n\t\t\t\tif (isType (token, TOKEN_BLOCK_LABEL_BEGIN) ||\n\t\t\t\t\tisKeyword (token, KEYWORD_exception) ||\n\t\t\t\t\tisKeyword (token, KEYWORD_loop) ||\n\t\t\t\t\tisKeyword (token, KEYWORD_case) ||\n\t\t\t\t\tisKeyword (token, KEYWORD_for) ||\n\t\t\t\t\tisKeyword (token, KEYWORD_begin))\n\t\t\t\t{\n\t\t\t\t\tparseStatements (token, false);\n\t\t\t\t}\n\t\t\t\telse if (isKeyword (token, KEYWORD_if))\n\t\t\t\t\tparseStatements (token, true);\n\n\t\t\t}\n\t\t}\n\t\t/*\n\t\t * We assumed earlier all statements ended with a command terminator.\n\t\t * See comment above, now, only read if the current token\n\t\t * is not a command terminator.\n\t\t */\n\t\tif (isCmdTerm(token) && ! stmtTerm)\n\t\t\tstmtTerm = true;\n\n\t} while (! isKeyword (token, KEYWORD_end) &&\n\t\t\t ! (exit_on_endif && isKeyword (token, KEYWORD_endif) ) &&\n\t\t\t ! isType (token, TOKEN_EOF) &&\n\t\t\t ! stmtTerm );\n}\n\nstatic void parseBlock (tokenInfo *const token, const bool local)\n{\n\tparseBlockFull (token, local, LANG_IGNORE);\n}\n\nstatic void makeSqlTagForInternalFunction (tokenInfo *const token)\n{\n\ttagEntryInfo foreignEntry;\n\tinitForeignRefTagEntry (\n\t\t&foreignEntry, vStringValue (token->string), Lang_c,\n\t\tCXXTagKindFUNCTION, CXXTagFUNCTIONRoleFOREIGNCALL);\n\tupdateTagLine (&foreignEntry, token->lineNumber, token->filePosition);\n\tmakeTagEntry (&foreignEntry);\n}\n\nstatic void parseBlockFull (tokenInfo *const token, const bool local, langType lang)\n{\n\tint promise = -1;\n\n\tif (isType (token, TOKEN_BLOCK_LABEL_BEGIN))\n\t{\n\t\tparseLabel (token);\n\t\treadToken (token);\n\t}\n\tif (! isKeyword (token, KEYWORD_begin))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_STRING))\n\t\t{\n\t\t\t/* Likely a PostgreSQL FUNCTION name AS '...'\n\t\t\t * https://www.postgresql.org/docs/current/static/sql-createfunction.html */\n\t\t\tpromise = token->promise;\n\t\t\ttoken->promise = -1;\n\n\t\t\ttokenInfo *const body = newToken ();\n\t\t\tcopyToken (body, token);\n\n\t\t\treadToken (token);\n\t\t\twhile (! isCmdTerm (token)\n\t\t\t\t   && !isType (token, TOKEN_EOF))\n\t\t\t{\n\t\t\t\tif (lang == LANG_IGNORE &&\n\t\t\t\t\tisKeyword (token, KEYWORD_language))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tlang = getNamedLanguageFromToken (token);\n\t\t\t\t\tif (lang != LANG_IGNORE)\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\telse if (vStringEqC (token->string, \"internal\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tmakeSqlTagForInternalFunction (body);\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\tdeleteToken (body);\n\n\t\t\tif (promise != -1 && lang != LANG_IGNORE)\n\t\t\t\tpromiseUpdateLanguage(promise, lang);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/*\n\t\t\t * These are Oracle style declares which generally come\n\t\t\t * between an IS/AS and BEGIN block.\n\t\t\t */\n\t\t\tparseDeclare (token, local);\n\t\t}\n\t}\n\tif (isKeyword (token, KEYWORD_begin))\n\t{\n\t\tbool is_transaction = false;\n\n\t\treadToken (token);\n\n\t\t/* BEGIN of Postgresql initiates a transaction.\n\t\t *\n\t\t *   BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ]\n\t\t *\n\t\t * BEGIN of MySQL does the same.\n\t\t *\n\t\t *   BEGIN [WORK]\n\t\t *\n\t\t * BEGIN of SQLite does the same.\n\t\t *\n\t\t *   BEGIN [[DEFERRED | IMMEDIATE | EXCLUSIVE] TRANSACTION]\n\t\t *\n\t\t */\n\t\tif (isCmdTerm(token))\n\t\t{\n\t\t\tis_transaction = true;\n\t\t\treadToken (token);\n\t\t}\n\t\telse if (isType (token, TOKEN_IDENTIFIER)\n\t\t\t\t && (strcasecmp (vStringValue(token->string), \"work\") == 0\n\t\t\t\t\t || strcasecmp (vStringValue(token->string), \"transaction\") == 0\n\t\t\t\t\t || (\n\t\t\t\t\t\t strcasecmp (vStringValue(token->string), \"deferred\") == 0\n\t\t\t\t\t\t || strcasecmp (vStringValue(token->string), \"immediate\") == 0\n\t\t\t\t\t\t || strcasecmp (vStringValue(token->string), \"exclusive\") == 0\n\t\t\t\t\t\t )\n\t\t\t\t\t ))\n\t\t\tis_transaction = true;\n\t\telse\n\t\t{\n\t\t\t/*\n\t\t\t * Check for ANSI declarations which always follow\n\t\t\t * a BEGIN statement.  This routine will not advance\n\t\t\t * the token if none are found.\n\t\t\t */\n\t\t\tparseDeclareANSI (token, local);\n\t\t}\n\n\t\ttoken->begin_end_nest_lvl++;\n\t\twhile (! isKeyword (token, KEYWORD_end) &&\n\t\t\t   ! (is_transaction && isKeyword(token, KEYWORD_commit)) &&\n\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\tparseStatements (token, false);\n\n\t\t\tif (isCmdTerm(token))\n\t\t\t\treadToken (token);\n\t\t}\n\t\ttoken->begin_end_nest_lvl--;\n\n\t\t/*\n\t\t * Read the next token (we will assume\n\t\t * it is the command delimiter)\n\t\t */\n\t\treadToken (token);\n\n\t\t/*\n\t\t * Check if the END block is terminated\n\t\t */\n\t\tif (! isCmdTerm (token))\n\t\t{\n\t\t\t/*\n\t\t\t * Not sure what to do here at the moment.\n\t\t\t * I think the routine that calls parseBlock\n\t\t\t * must expect the next token has already\n\t\t\t * been read since it is possible this\n\t\t\t * token is not a command delimiter.\n\t\t\t */\n\t\t\t/* findCmdTerm (token, false); */\n\t\t}\n\t}\n}\n\nstatic void parsePackage (tokenInfo *const token)\n{\n\t/*\n\t * Packages can be specified in a number of ways:\n\t *\t\tCREATE OR REPLACE PACKAGE pkg_name AS\n\t * or\n\t *\t\tCREATE OR REPLACE PACKAGE owner.pkg_name AS\n\t * or by specifying a package body\n\t *\t   CREATE OR REPLACE PACKAGE BODY pkg_name AS\n\t *\t   CREATE OR REPLACE PACKAGE BODY owner.pkg_name AS\n\t */\n\ttokenInfo *const name = newToken ();\n\treadIdentifier (name);\n\tif (isKeyword (name, KEYWORD_body))\n\t{\n\t\t/*\n\t\t * Ignore the BODY tag since we will process\n\t\t * the body or prototypes in the same manner\n\t\t */\n\t\treadIdentifier (name);\n\t}\n\t/* Check for owner.pkg_name */\n\twhile (! isKeyword (token, KEYWORD_is) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\treadToken (token);\n\t\tif ( isType(token, TOKEN_PERIOD) )\n\t\t{\n\t\t\treadIdentifier (name);\n\t\t}\n\t}\n\tif (isKeyword (token, KEYWORD_is))\n\t{\n\t\tif (isType (name, TOKEN_IDENTIFIER) ||\n\t\t\tisType (name, TOKEN_STRING))\n\t\t{\n\t\t\tmakeSqlTag (name, SQLTAG_PACKAGE);\n\t\t}\n\t\taddToScope (token, name->string, SQLTAG_PACKAGE);\n\t\tparseBlock (token, false);\n\t\tvStringClear (token->scope);\n\t\ttoken->scopeKind = SQLTAG_COUNT;\n\t}\n\tfindCmdTerm (token, false);\n\tdeleteToken (name);\n}\n\nstatic void parseColumnsAndAliases (tokenInfo *const token)\n{\n\tbool columnAcceptable = true;\n\ttokenInfo *const lastId = newToken ();\n\n\t/*\n\t * -- A\n\t * create table foo as select A;\n\t *\n\t * -- B\n\t * create table foo as select B from ...;\n\t *\n\t * -- D\n\t * create table foo as select C as D from ...;\n\t *\n\t * -- E, F\n\t * create table foo as select E, a.F;\n\t *\n\t * -- G, H\n\t * create table foo as select G, a.H from ...;\n\t *\n\t * -- J, K\n\t * create table foo as select I as J, a.K from ...;\n\t *\n\t * lastID is used for capturing A, B, E, F, G, H, and K.\n\t */\n\treadToken (token);\n\tdo\n\t{\n\t\tif (isType (token, TOKEN_KEYWORD)\n\t\t\t&& isKeyword (token, KEYWORD_is))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t{\n\t\t\t\t/* Emit the alias */\n\t\t\t\tmakeSqlTag (token, SQLTAG_FIELD);\n\t\t\t\tcolumnAcceptable = true;\n\t\t\t}\n\t\t\tlastId->type = TOKEN_UNDEFINED;\n\t\t}\n\t\telse if ((isType (token, TOKEN_KEYWORD)\n\t\t\t\t  && isKeyword (token, KEYWORD_from))\n\t\t\t\t || isType (token, TOKEN_SEMICOLON)\n\t\t\t\t || isType(token, TOKEN_COMMA))\n\t\t{\n\t\t\tif (lastId->type == TOKEN_IDENTIFIER)\n\t\t\t{\n\t\t\t\t/* Emit the column */\n\t\t\t\tmakeSqlTag(lastId, SQLTAG_FIELD);\n\t\t\t\tcolumnAcceptable = true;\n\t\t\t}\n\n\t\t\tif (isType(token, TOKEN_COMMA))\n\t\t\t\tlastId->type = TOKEN_UNDEFINED;\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t\telse if (isType (token, TOKEN_OPEN_PAREN))\n\t\t{\n\t\t\tcolumnAcceptable = false;\n\t\t\tskipToMatched (token);\n\t\t\tlastId->type = TOKEN_UNDEFINED;\n\t\t\tcontinue;\n\t\t}\n\t\telse if (isType (token, TOKEN_PERIOD))\n\t\t{\n\t\t\tlastId->type = TOKEN_UNDEFINED;\n\t\t}\n\t\telse if (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tif (columnAcceptable)\n\t\t\t\tcopyToken (lastId, token);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcolumnAcceptable = false;\n\t\t\tlastId->type = TOKEN_UNDEFINED;\n\t\t}\n\n\t\treadToken (token);\n\t} while (! isType (token, TOKEN_EOF));\n\n\tdeleteToken (lastId);\n}\n\n/* Skip \"IF NOT EXISTS\"\n * https://dev.mysql.com/doc/refman/8.0/en/create-table.html\n * https://www.postgresql.org/docs/current/sql-createtable.html\n * https://sqlite.org/lang_createtable.html\n */\nstatic bool parseIdAfterIfNotExists (tokenInfo *const name,\n\t\t\t\t\t\t\t\t\t tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t bool authorization_following)\n{\n\tif (isKeyword (name, KEYWORD_if)\n\t\t&& (isType (token, TOKEN_IDENTIFIER)\n\t\t\t&& vStringLength (token->string) == 3\n\t\t\t&& strcasecmp (\"not\", vStringValue (token->string)) == 0))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER)\n\t\t\t&& vStringLength (token->string) == 6\n\t\t\t&& strcasecmp (\"exists\", vStringValue (token->string)) == 0)\n\t\t{\n\t\t\treadIdentifier (name);\n\t\t\tif (authorization_following\n\t\t\t\t&& isType (name, TOKEN_IDENTIFIER)\n\t\t\t\t&& vStringLength (name->string) == 13\n\t\t\t\t&& strcasecmp(\"authorization\", vStringValue(name->string)) == 0)\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * PostgreSQL:\n\t\t\t\t * - CREATE SCHEMA IF NOT EXISTS AUTHORIZATION role_specification\n\t\t\t\t */\n\t\t\t\treadIdentifier (name);\n\t\t\t}\n\t\t\treadToken (token);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nstatic void parseTable (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\tbool emitted = false;\n\n\t/*\n\t * This deals with these formats:\n\t *\t   create table t1 (c1 int);\n\t *\t   create global temporary table t2 (c1 int);\n\t *\t   create table \"t3\" (c1 int);\n\t *\t   create table bob.t4 (c1 int);\n\t *\t   create table bob.\"t5\" (c1 int);\n\t *\t   create table \"bob\".\"t6\" (c1 int);\n\t *\t   create table bob.\"t7\" (c1 int);\n\t * Proxy tables use this format:\n\t *\t   create existing table bob.\"t7\" AT '...';\n\t * SQL Server and Sybase formats\n     *     create table OnlyTable (\n     *     create table dbo.HasOwner (\n     *     create table [dbo].[HasOwnerSquare] (\n     *     create table master.dbo.HasDb (\n     *     create table master..HasDbNoOwner (\n     *     create table [master].dbo.[HasDbAndOwnerSquare] (\n     *     create table [master]..[HasDbNoOwnerSquare] (\n\t * Oracle and PostgreSQL use this format:\n\t *     create table FOO as select...\n\t * MySQL allows omitting \"as\" like:\n\t *     create table FOO select...\n\t *     create table FOO (...) select...\n\t * (At least) MYSQL, PostgreSQL, and SQLite takes \"IF NOT EXISTS\"\n\t * between \"table\" and a table name:\n\t *     create table if not exists foo ...\n\t */\n\n\t/* This could be a database, owner or table name */\n\treadIdentifier (name);\n\treadToken (token);\n\n\tparseIdAfterIfNotExists(name, token, false);\n\n\tif (isType (token, TOKEN_PERIOD))\n\t{\n\t\t/*\n\t\t * This could be a owner or table name.\n\t\t * But this is also a special case since the table can be\n\t\t * referenced with a blank owner:\n\t\t *     dbname..tablename\n\t\t */\n\t\treadIdentifier (name);\n\t\t/* Check if a blank name was provided */\n\t\tif (isType (name, TOKEN_PERIOD))\n\t\t{\n\t\t\treadIdentifier (name);\n\t\t}\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_PERIOD))\n\t\t{\n\t\t\t/* This can only be the table name */\n\t\t\treadIdentifier (name);\n\t\t\treadToken (token);\n\t\t}\n\t}\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tif (isType (name, TOKEN_IDENTIFIER) ||\n\t\t\tisType (name, TOKEN_STRING) ||\n\t\t\t(isType (name, TOKEN_KEYWORD)\n\t\t\t && (!isReservedWord (name))))\n\t\t{\n\t\t\tmakeSqlTag (name, SQLTAG_TABLE);\n\t\t\temitted = true;\n\n\t\t\tvStringCopy(token->scope, name->string);\n\t\t\ttoken->scopeKind = SQLTAG_TABLE;\n\t\t\tparseRecord (token);\n\t\t\tvStringClear (token->scope);\n\t\t\ttoken->scopeKind = SQLTAG_COUNT;\n\t\t\treadToken (token);\n\t\t}\n\t\telse\n\t\t\tskipToMatched(token);\n\t}\n\telse if (isKeyword (token, KEYWORD_at))\n\t{\n\t\tif (isType (name, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tmakeSqlTag (name, SQLTAG_TABLE);\n\t\t}\n\t}\n\n\tif (isKeyword (token, KEYWORD_select)\n\t\t\t /* KEYWORD_is is for recognizing \"as\" */\n\t\t\t || isKeyword (token, KEYWORD_is))\n\t{\n\t\tif (isType (name, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tif (!emitted)\n\t\t\t\tmakeSqlTag (name, SQLTAG_TABLE);\n\n\t\t\tif (isKeyword (token, KEYWORD_is))\n\t\t\t\treadToken (token);\n\n\t\t\tif (isKeyword (token, KEYWORD_select))\n\t\t\t{\n\t\t\t\taddToScope (token, name->string, SQLTAG_TABLE);\n\t\t\t\tparseColumnsAndAliases (token);\n\t\t\t\tvStringClear (token->scope);\n\t\t\t}\n\t\t}\n\t}\n\tfindCmdTerm (token, true);\n\tdeleteToken (name);\n}\n\nstatic void parseIndex (tokenInfo *const token)\n{\n\ttokenInfo *const name  = newToken ();\n\ttokenInfo *const owner = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *\t   create index i1 on t1(c1) create index \"i2\" on t1(c1)\n\t *\t   create virtual unique clustered index \"i3\" on t1(c1)\n\t *\t   create unique clustered index \"i4\" on t1(c1)\n\t *\t   create clustered index \"i5\" on t1(c1)\n\t *\t   create bitmap index \"i6\" on t1(c1)\n\t */\n\n\treadIdentifier (name);\n\treadToken (token);\n\tif (isType (token, TOKEN_PERIOD))\n\t{\n\t\treadIdentifier (name);\n\t\treadToken (token);\n\t}\n\tif (isKeyword (token, KEYWORD_on) &&\n\t\t(isType (name, TOKEN_IDENTIFIER) ||\n\t\t isType (name, TOKEN_STRING)))\n\t{\n\t\treadIdentifier (owner);\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_PERIOD))\n\t\t{\n\t\t\treadIdentifier (owner);\n\t\t\treadToken (token);\n\t\t}\n\t\taddToScope(name, owner->string, SQLTAG_TABLE /* FIXME? */);\n\t\tmakeSqlTag (name, SQLTAG_INDEX);\n\t}\n\tfindCmdTerm (token, false);\n\tdeleteToken (name);\n\tdeleteToken (owner);\n}\n\nstatic void parseEvent (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *\t   create event e1 handler begin end;\n\t *\t   create event \"e2\" handler begin end;\n\t *\t   create event dba.\"e3\" handler begin end;\n\t *\t   create event \"dba\".\"e4\" handler begin end;\n\t */\n\n\treadIdentifier (name);\n\treadToken (token);\n\tif (isType (token, TOKEN_PERIOD))\n\t{\n\t\treadIdentifier (name);\n\t}\n\twhile (! isKeyword (token, KEYWORD_handler) &&\n\t\t   ! isType (token, TOKEN_SEMICOLON) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\treadToken (token);\n\t}\n\n\tif ((isKeyword (token, KEYWORD_handler) ||\n\t\t isType (token, TOKEN_SEMICOLON))\n\t\t&& (isType (name, TOKEN_IDENTIFIER) ||\n\t\t\tisType (name, TOKEN_STRING)     ||\n\t\t\t(isType (name, TOKEN_KEYWORD)\n\t\t\t && (!isReservedWord (name)))))\n\t{\n\t\tmakeSqlTag (name, SQLTAG_EVENT);\n\t}\n\n\tif (isKeyword (token, KEYWORD_handler))\n\t{\n\t\treadToken (token);\n\t\tif (isKeyword (token, KEYWORD_begin))\n\t\t{\n\t\t\tparseBlock (token, true);\n\t\t}\n\t\tfindCmdTerm (token, true);\n\t}\n\tdeleteToken (name);\n}\n\nstatic void parseTrigger (tokenInfo *const token)\n{\n\ttokenInfo *const name  = newToken ();\n\ttokenInfo *const table = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *\t   create or replace trigger tr1 begin end;\n\t *\t   create trigger \"tr2\" begin end;\n\t *\t   drop trigger \"droptr1\";\n\t *\t   create trigger \"tr3\" CALL sp_something();\n\t *\t   create trigger \"owner\".\"tr4\" begin end;\n\t *\t   create trigger \"tr5\" not valid;\n\t *\t   create trigger \"tr6\" begin end;\n\t *\n\t * (PostgreSQL)\n\t *\t   create trigger trigger ... on table ... execute procedure fn();\n\t *\n\t */\n\n\treadIdentifier (name);\n\treadToken (token);\n\tif (isType (token, TOKEN_PERIOD))\n\t{\n\t\treadIdentifier (name);\n\t\treadToken (token);\n\t}\n\n\twhile (! isKeyword (token, KEYWORD_on) &&\n\t\t   ! isType (token, TOKEN_EOF) &&\n\t\t   ! isCmdTerm (token))\n\t{\n\t\treadToken (token);\n\t}\n\n\t/*if (! isType (token, TOKEN_SEMICOLON) ) */\n\tif (! isCmdTerm (token))\n\t{\n\t\treadToken (table);\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_PERIOD))\n\t\t{\n\t\t\treadToken (table);\n\t\t\treadToken (token);\n\t\t}\n\n\t\twhile (! isKeyword (token, KEYWORD_begin) &&\n\t\t\t   ! isKeyword (token, KEYWORD_call) &&\n\t\t\t   ! isKeyword (token, KEYWORD_procedure) &&\n\t\t\t   ! isCmdTerm (token) &&\n\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\tif (isKeyword (token, KEYWORD_declare))\n\t\t\t{\n\t\t\t\taddToScope(token, name->string, SQLTAG_TRIGGER);\n\t\t\t\tparseDeclare(token, true);\n\t\t\t\tvStringClear(token->scope);\n\t\t\t\ttoken->scopeKind = SQLTAG_COUNT;\n\t\t\t}\n\t\t\telse\n\t\t\t\treadToken (token);\n\t\t}\n\n\t\tif (isKeyword (token, KEYWORD_begin) ||\n\t\t\tisKeyword (token, KEYWORD_call)  ||\n\t\t\tisKeyword (token, KEYWORD_procedure))\n\t\t{\n\t\t\taddToScope(name, table->string, SQLTAG_TABLE);\n\t\t\tmakeSqlTag (name, SQLTAG_TRIGGER);\n\t\t\taddToScope(token, table->string, SQLTAG_TABLE);\n\t\t\tif (isKeyword (token, KEYWORD_begin))\n\t\t\t{\n\t\t\t\tparseBlock (token, true);\n\t\t\t}\n\t\t\tvStringClear(token->scope);\n\t\t\ttoken->scopeKind = SQLTAG_COUNT;\n\t\t}\n\t}\n\n\tfindCmdTerm (token, true);\n\tdeleteToken (name);\n\tdeleteToken (table);\n}\n\nstatic void parsePublication (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *\t   create or replace publication pu1 ()\n\t *\t   create publication \"pu2\" ()\n\t *\t   create publication dba.\"pu3\" ()\n\t *\t   create publication \"dba\".\"pu4\" ()\n\t */\n\n\treadIdentifier (name);\n\treadToken (token);\n\tif (isType (token, TOKEN_PERIOD))\n\t{\n\t\treadIdentifier (name);\n\t\treadToken (token);\n\t}\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tif (isType (name, TOKEN_IDENTIFIER) ||\n\t\t\tisType (name, TOKEN_STRING))\n\t\t{\n\t\t\tmakeSqlTag (name, SQLTAG_PUBLICATION);\n\t\t}\n\t}\n\tfindCmdTerm (token, false);\n\tdeleteToken (name);\n}\nstatic void parseService (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *\t   CREATE SERVICE s1 TYPE 'HTML'\n\t *\t\t   AUTHORIZATION OFF USER DBA AS\n\t *\t\t   SELECT *\n\t *\t\t\t FROM SYS.SYSTABLE;\n\t *\t   CREATE SERVICE \"s2\" TYPE 'HTML'\n\t *\t\t   AUTHORIZATION OFF USER DBA AS\n\t *\t\t   CALL sp_Something();\n\t */\n\n\treadIdentifier (name);\n\treadToken (token);\n\tif (isKeyword (token, KEYWORD_type))\n\t{\n\t\tif (isType (name, TOKEN_IDENTIFIER) ||\n\t\t\tisType (name, TOKEN_STRING))\n\t\t{\n\t\t\tmakeSqlTag (name, SQLTAG_SERVICE);\n\t\t}\n\t}\n\tfindCmdTerm (token, false);\n\tdeleteToken (name);\n}\n\nstatic void parseDomain (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *\t   CREATE DOMAIN|DATATYPE [AS] your_name ...;\n\t */\n\n\treadIdentifier (name);\n\tif (isKeyword (name, KEYWORD_is))\n\t{\n\t\treadIdentifier (name);\n\t}\n\treadToken (token);\n\tif (isType (name, TOKEN_IDENTIFIER) ||\n\t\tisType (name, TOKEN_STRING))\n\t{\n\t\tmakeSqlTag (name, SQLTAG_DOMAIN);\n\t}\n\tfindCmdTerm (token, false);\n\tdeleteToken (name);\n}\n\nstatic void parseDrop (tokenInfo *const token)\n{\n\t/*\n\t * This deals with these formats\n\t *\t   DROP TABLE|PROCEDURE|DOMAIN|DATATYPE name;\n\t *\n\t * Just simply skip over these statements.\n\t * They are often confused with PROCEDURE prototypes\n\t * since the syntax is similar, this effectively deals with\n\t * the issue for all types.\n\t */\n\n\tfindCmdTerm (token, false);\n}\n\nstatic void parseVariable (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *\t   create variable varname1 integer;\n\t *\t   create variable @varname2 integer;\n\t *\t   create variable \"varname3\" integer;\n\t *\t   drop   variable @varname3;\n\t */\n\n\treadIdentifier (name);\n\treadToken (token);\n\tif (! isType (token, TOKEN_SEMICOLON) &&\n\t\t(isType (name, TOKEN_IDENTIFIER) ||\n\t\t isType (name, TOKEN_STRING)))\n\t{\n\t\tmakeSqlTag (name, SQLTAG_VARIABLE);\n\t}\n\tfindCmdTerm (token, true);\n\n\tdeleteToken (name);\n}\n\nstatic void parseSynonym (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *\t   create variable varname1 integer;\n\t *\t   create variable @varname2 integer;\n\t *\t   create variable \"varname3\" integer;\n\t *\t   drop   variable @varname3;\n\t */\n\n\treadIdentifier (name);\n\treadToken (token);\n\tif (isKeyword (token, KEYWORD_for) &&\n\t\t(isType (name, TOKEN_IDENTIFIER) ||\n\t\t isType (name, TOKEN_STRING)))\n\t{\n\t\tmakeSqlTag (name, SQLTAG_SYNONYM);\n\t}\n\tfindCmdTerm (token, true);\n\n\tdeleteToken (name);\n}\n\nstatic void parseView (tokenInfo *const token)\n{\n\ttokenInfo *const name = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *     create view VIEW;\n\t *     create view VIEW as ...;\n\t *     create view VIEW (...) as ...;\n\t *     create view if not exists VIEW as ...;\n\t *       -- [SQLITE] https://www.sqlite.org/lang_createview.html\n\t */\n\n\treadIdentifier (name);\n\treadToken (token);\n\n\tparseIdAfterIfNotExists(name, token, false);\n\n\tif (isType (token, TOKEN_PERIOD))\n\t{\n\t\treadIdentifier (name);\n\t\treadToken (token);\n\t}\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tskipArgumentList(token);\n\t}\n\n\twhile (! isKeyword (token, KEYWORD_is) &&\n\t\t   ! isType (token, TOKEN_SEMICOLON) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\treadToken (token);\n\t}\n\n\tif (isKeyword (token, KEYWORD_is) &&\n\t\t(isType (name, TOKEN_IDENTIFIER) ||\n\t\t isType (name, TOKEN_STRING)))\n\t{\n\t\tmakeSqlTag (name, SQLTAG_VIEW);\n\t}\n\n\tfindCmdTerm (token, true);\n\n\tdeleteToken (name);\n}\n\nstatic void parseMLTable (tokenInfo *const token)\n{\n\ttokenInfo *const version = newToken ();\n\ttokenInfo *const table\t = newToken ();\n\ttokenInfo *const event\t = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *\t  call dbo.ml_add_table_script( 'version', 'table_name', 'event',\n\t *\t\t   'some SQL statement'\n\t *\t\t   );\n\t */\n\n\treadToken (token);\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\treadToken (version);\n\t\treadToken (token);\n\t\twhile (! isType (token, TOKEN_COMMA) &&\n\t\t\t   ! isType (token, TOKEN_CLOSE_PAREN) &&\n\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t}\n\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t{\n\t\t\treadToken (table);\n\t\t\treadToken (token);\n\t\t\twhile (! isType (token, TOKEN_COMMA) &&\n\t\t\t\t   ! isType (token, TOKEN_CLOSE_PAREN) &&\n\t\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t}\n\n\t\t\tif (isType (token, TOKEN_COMMA))\n\t\t\t{\n\t\t\t\treadToken (event);\n\n\t\t\t\tif (isType (version, TOKEN_STRING) &&\n\t\t\t\t\tisType (table, TOKEN_STRING) &&\n\t\t\t\t\tisType (event, TOKEN_STRING))\n\t\t\t\t{\n\t\t\t\t\taddToScope(version, table->string, SQLTAG_TABLE);\n\t\t\t\t\taddToScope(version, event->string, SQLTAG_EVENT);\n\t\t\t\t\tmakeSqlTag (version, SQLTAG_MLTABLE);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (! isType (token, TOKEN_CLOSE_PAREN))\n\t\t\t\tfindToken (token, TOKEN_CLOSE_PAREN);\n\t\t}\n\t}\n\n\tfindCmdTerm (token, true);\n\n\tdeleteToken (version);\n\tdeleteToken (table);\n\tdeleteToken (event);\n}\n\nstatic void parseMLConn (tokenInfo *const token)\n{\n\ttokenInfo *const version = newToken ();\n\ttokenInfo *const event\t = newToken ();\n\n\t/*\n\t * This deals with these formats\n\t *\t  call ml_add_connection_script( 'version', 'event',\n\t *\t\t   'some SQL statement'\n\t *\t\t   );\n\t */\n\n\treadToken (token);\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\treadToken (version);\n\t\treadToken (token);\n\t\twhile (! isType (token, TOKEN_COMMA) &&\n\t\t\t   ! isType (token, TOKEN_CLOSE_PAREN) &&\n\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t}\n\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t{\n\t\t\treadToken (event);\n\n\t\t\tif (isType (version, TOKEN_STRING) &&\n\t\t\t\tisType (event, TOKEN_STRING))\n\t\t\t{\n\t\t\t\taddToScope(version, event->string, SQLTAG_EVENT);\n\t\t\t\tmakeSqlTag (version, SQLTAG_MLCONN);\n\t\t\t}\n\t\t}\n\t\tif (! isType (token, TOKEN_CLOSE_PAREN))\n\t\t\tfindToken (token, TOKEN_CLOSE_PAREN);\n\n\t}\n\n\tfindCmdTerm (token, true);\n\n\tdeleteToken (version);\n\tdeleteToken (event);\n}\n\nstatic void parseMLProp (tokenInfo *const token)\n{\n\ttokenInfo *const component     = newToken ();\n\ttokenInfo *const prop_set_name = newToken ();\n\ttokenInfo *const prop_name     = newToken ();\n\n\t/*\n\t * This deals with these formats\n     *   ml_add_property (\n     *       'comp_name',\n     *       'prop_set_name',\n     *       'prop_name',\n     *       'prop_value'\n     *   )\n\t */\n\n\treadToken (token);\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\treadToken (component);\n\t\treadToken (token);\n\t\twhile (! isType (token, TOKEN_COMMA) &&\n\t\t\t   ! isType (token, TOKEN_CLOSE_PAREN) &&\n\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t}\n\n\t\tif (isType (token, TOKEN_COMMA))\n\t\t{\n\t\t\treadToken (prop_set_name);\n\t\t\treadToken (token);\n\t\t\twhile (! isType (token, TOKEN_COMMA) &&\n\t\t\t\t   ! isType (token, TOKEN_CLOSE_PAREN) &&\n\t\t\t\t   ! isType (token, TOKEN_EOF))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t}\n\n\t\t\tif (isType (token, TOKEN_COMMA))\n\t\t\t{\n\t\t\t\treadToken (prop_name);\n\n\t\t\t\tif (isType (component, TOKEN_STRING) &&\n\t\t\t\t\tisType (prop_set_name, TOKEN_STRING) &&\n\t\t\t\t\tisType (prop_name, TOKEN_STRING))\n\t\t\t\t{\n\t\t\t\t\taddToScope(component, prop_set_name->string, SQLTAG_MLPROP /* FIXME */);\n\t\t\t\t\taddToScope(component, prop_name->string, SQLTAG_MLPROP /* FIXME */);\n\t\t\t\t\tmakeSqlTag (component, SQLTAG_MLPROP);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (! isType (token, TOKEN_CLOSE_PAREN))\n\t\t\t\tfindToken (token, TOKEN_CLOSE_PAREN);\n\t\t}\n\t}\n\n\tfindCmdTerm (token, true);\n\n\tdeleteToken (component);\n\tdeleteToken (prop_set_name);\n\tdeleteToken (prop_name);\n}\n\nstatic void parseComment (tokenInfo *const token)\n{\n\t/*\n\t * This deals with this statement:\n\t *\t   COMMENT TO PRESERVE FORMAT ON PROCEDURE \"DBA\".\"test\" IS\n\t *\t   {create PROCEDURE DBA.\"test\"()\n\t *\t   BEGIN\n\t *\t\tsignal dave;\n\t *\t   END\n\t *\t   }\n\t *\t   ;\n\t * The comment can contain anything between the CURLY\n\t * braces\n\t *\t   COMMENT ON USER \"admin\" IS\n\t *\t\t\t'Administration Group'\n\t *\t\t\t;\n\t * Or it could be a simple string with no curly braces\n\t */\n\twhile (! isKeyword (token, KEYWORD_is) &&\n\t\t   ! isType (token, TOKEN_EOF))\n\t{\n\t\treadToken (token);\n\t}\n\treadToken (token);\n\tif (isType(token, TOKEN_OPEN_CURLY))\n\t{\n\t\tfindToken (token, TOKEN_CLOSE_CURLY);\n\t}\n\n\tfindCmdTerm (token, true);\n}\n\nstatic void parseCCFLAGS (tokenInfo *const token)\n{\n\treadToken(token);\n\tif (!isType (token, TOKEN_EQUAL))\n\t{\n\t\tfindCmdTerm (token, true);\n\t\treturn;\n\t}\n\n\treadToken(token);\n\tif (!isType (token, TOKEN_STRING))\n\t{\n\t\tfindCmdTerm (token, true);\n\t\treturn;\n\t}\n\n\tbool in_var = true;\n\tconst char *s = vStringValue(token->string);\n\tvString *ccflag = vStringNew();\n\t/* http://web.deu.edu.tr/doc/oracle/B19306_01/server.102/b14237/initparams158.htm#REFRN10261 */\n\twhile (*s)\n\t{\n\t\tif (in_var && isIdentChar1((unsigned char) *s))\n\t\t\tvStringPut(ccflag, *s);\n\t\telse if (*s == ':' && !vStringIsEmpty(ccflag))\n\t\t{\n\t\t\tif (lookupCaseKeyword(vStringValue(ccflag), Lang_sql)\n\t\t\t\t!= KEYWORD_inquiry_directive)\n\t\t\t{\n\t\t\t\tint index = makeSimpleTag(ccflag, SQLTAG_PLSQL_CCFLAGS);\n\t\t\t\tregisterEntry(index);\n\t\t\t\tvStringClear(ccflag);\n\t\t\t\tin_var = false;\n\t\t\t}\n\t\t}\n\t\telse if (*s == ',')\n\t\t\tin_var = true;\n\t\ts++;\n\t}\n\tvStringDelete(ccflag);\n\n}\n\nstatic void parseDatabase (tokenInfo *const token, enum eKeywordId keyword)\n{\n\ttokenInfo * name;\n\n\t/*\n\t * In MySQL and HPL/SQL, \"CREATE DATABASE\" and \"CREATE SCHEMA\"\n\t * are the same. However, In PostgreSQL, they are different.\n\t * Too support PostgreSQL, we prepare different kinds for them.\n\t *\n\t * MySQL\n\t * A. CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name ...;\n\t *\n\t * PostgreSQL\n\t *\n\t * B. CREATE DATABASE name ...;\n\t *\n\t * C. CREATE SCHEMA schema_name [ AUTHORIZATION role_specification ] [ schema_element [ ... ] ]\n\t * D. CREATE SCHEMA AUTHORIZATION role_specification [ schema_element [ ... ] ]\n\t * E. CREATE SCHEMA IF NOT EXISTS schema_name [ AUTHORIZATION role_specification ]\n\t * F. CREATE SCHEMA IF NOT EXISTS AUTHORIZATION role_specification\n\t *\n\t * HPL/SQL\n\t * G. CREATE DATABASE | SCHEMA [IF NOT EXISTS] dbname_expr...;\n\t */\n\treadIdentifier (token);\n\tif (keyword == KEYWORD_schema\n\t\t&& isType (token, TOKEN_IDENTIFIER)\n\t\t&& vStringLength (token->string) == 13\n\t\t&& strcasecmp(\"authorization\", vStringValue(token->string)) == 0)\n\t{\n\t\t/* D. */\n\t\treadIdentifier (token);\n\t\tmakeSqlTag (token, SQLTAG_SCHEMA);\n\t\tfindCmdTerm (token, false);\n\t\treturn;\n\t}\n\n\tname = newToken ();\n\tcopyToken (name, token);\n\treadIdentifier (token);\n\tparseIdAfterIfNotExists (name, token, true);\n\n\tmakeSqlTag (name,\n\t\t\t\tkeyword == KEYWORD_database\n\t\t\t\t? SQLTAG_DATABASE: SQLTAG_SCHEMA);\n\tdeleteToken (name);\n\n\t/* TODO:\n\t *\n\t * In PostgreSQL, CREATE FOO can follow to CREATE SCHEMA like:\n\t *\n\t * -- https://www.postgresql.org/docs/current/sql-createschema.html\n\t *\n\t *     CREATE SCHEMA hollywood\n\t *         CREATE TABLE films (title text, release date, awards text[])\n\t *         CREATE VIEW winners AS\n\t *             SELECT title, release FROM films WHERE awards IS NOT NULL;\n\t *\n\t * In above example, \"hollywood.films\" and \"hollywood.winners\" should be\n\t * tagged.\n\t */\n\tfindCmdTerm (token, true);\n}\n\nstatic void parseKeywords (tokenInfo *const token, enum eKeywordId precedingKeyword)\n{\n\t\tswitch (token->keyword)\n\t\t{\n\t\t\tcase KEYWORD_begin:\t\t\tparseBlock (token, false); break;\n\t\t\tcase KEYWORD_inquiry_directive:\n\t\t\t\tif (strcasecmp(vStringValue(token->string), \"PLSQL_CCFLAGS\") == 0)\n\t\t\t\t\tparseCCFLAGS (token);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_comment:\t\tparseComment (token); break;\n\t\t\tcase KEYWORD_cursor:\t\tparseSimple (token, SQLTAG_CURSOR); break;\n\t\t\tcase KEYWORD_database:\n\t\t\t\tif (precedingKeyword == KEYWORD_create)\n\t\t\t\t\tparseDatabase (token, KEYWORD_database);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_datatype:\t\tparseDomain (token); break;\n\t\t\tcase KEYWORD_declare:\t\tparseBlock (token, false); break;\n\t\t\tcase KEYWORD_domain:\t\tparseDomain (token); break;\n\t\t\tcase KEYWORD_drop:\t\t\tparseDrop (token); break;\n\t\t\tcase KEYWORD_event:\t\t\tparseEvent (token); break;\n\t\t\tcase KEYWORD_extension:\t\tfindCmdTerm (token, false); break;\n\t\t\tcase KEYWORD_function:\t\tparseSubProgram (token); break;\n\t\t\tcase KEYWORD_if:\t\t\tparseStatements (token, false); break;\n\t\t\tcase KEYWORD_index:\t\t\tparseIndex (token); break;\n\t\t\tcase KEYWORD_ml_table:\t\tparseMLTable (token); break;\n\t\t\tcase KEYWORD_ml_table_lang: parseMLTable (token); break;\n\t\t\tcase KEYWORD_ml_table_dnet: parseMLTable (token); break;\n\t\t\tcase KEYWORD_ml_table_java: parseMLTable (token); break;\n\t\t\tcase KEYWORD_ml_table_chk:  parseMLTable (token); break;\n\t\t\tcase KEYWORD_ml_conn:\t\tparseMLConn (token); break;\n\t\t\tcase KEYWORD_ml_conn_lang:\tparseMLConn (token); break;\n\t\t\tcase KEYWORD_ml_conn_dnet:\tparseMLConn (token); break;\n\t\t\tcase KEYWORD_ml_conn_java:\tparseMLConn (token); break;\n\t\t\tcase KEYWORD_ml_conn_chk:\tparseMLConn (token); break;\n\t\t\tcase KEYWORD_ml_prop:\t\tparseMLProp (token); break;\n\t\t\tcase KEYWORD_package:\t\tparsePackage (token); break;\n\t\t\tcase KEYWORD_procedure:\t\tparseSubProgram (token); break;\n\t\t\tcase KEYWORD_publication:\tparsePublication (token); break;\n\t\t\tcase KEYWORD_schema:\n\t\t\t\tif (precedingKeyword == KEYWORD_create)\n\t\t\t\t\tparseDatabase (token, KEYWORD_schema);\n\t\t\t\tbreak;\n\t\t\tcase KEYWORD_service:\t\tparseService (token); break;\n\t\t\tcase KEYWORD_subtype:\t\tparseSimple (token, SQLTAG_SUBTYPE); break;\n\t\t\tcase KEYWORD_synonym:\t\tparseSynonym (token); break;\n\t\t\tcase KEYWORD_table:\t\t\tparseTable (token); break;\n\t\t\tcase KEYWORD_trigger:\t\tparseTrigger (token); break;\n\t\t\tcase KEYWORD_type:\t\t\tparseType (token); break;\n\t\t\tcase KEYWORD_variable:\t\tparseVariable (token); break;\n\t\t\tcase KEYWORD_view:\t\t\tparseView (token); break;\n\t\t\tcase KEYWORD_with:\t\t\treadToken (token); break; /* skip next token */\n\t\t\tcase KEYWORD_without:\t\treadToken (token); break; /* skip next token */\n\t\t\tdefault:\t\t\t\t    break;\n\t\t}\n}\n\nstatic tokenType parseSqlFile (tokenInfo *const token)\n{\n\tdo\n\t{\n\t\tenum eKeywordId k = token->keyword;\n\t\treadToken (token);\n\n\t\tif (isType (token, TOKEN_BLOCK_LABEL_BEGIN))\n\t\t\tparseLabel (token);\n\t\telse\n\t\t\tparseKeywords (token, k);\n\t} while (! isKeyword (token, KEYWORD_end) &&\n\t\t\t ! isType (token, TOKEN_EOF));\n\n\treturn token->type;\n}\n\nstatic void initialize (const langType language)\n{\n\tAssert (ARRAY_SIZE (SqlKinds) == SQLTAG_COUNT);\n\tLang_sql = language;\n\taddKeywordGroup (&predefinedInquiryDirective, language);\n}\n\nstatic void findSqlTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\twhile (parseSqlFile (token) != TOKEN_EOF);\n\n\tdeleteToken (token);\n}\n\nextern parserDefinition* SqlParser (void)\n{\n\tstatic const char *const extensions [] = { \"sql\", NULL };\n\tstatic const char *const aliases [] = {\"pgsql\", NULL };\n\tparserDefinition* def = parserNew (\"SQL\");\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_FOREIGNER, \"C\",  &Lang_c },\n\t};\n\n\tdef->kindTable\t= SqlKinds;\n\tdef->kindCount\t= ARRAY_SIZE (SqlKinds);\n\tdef->extensions = extensions;\n\tdef->aliases    = aliases;\n\tdef->parser\t\t= findSqlTags;\n\tdef->initialize = initialize;\n\tdef->keywordTable = SqlKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (SqlKeywordTable);\n\tdef->useCork = CORK_QUEUE | CORK_SYMTAB;\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/svg.c",
    "content": "/*\n*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for svg.\n*\n*/\n\n#include \"general.h\"\t/* must always come first */\n#include \"entry.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"x-xml.h\"\n\n#include <string.h>\n\ntypedef enum {\n\tK_DEF,\n} svgKind;\n\nstatic kindDefinition SvgKinds [] = {\n\t{ true,  'd', \"def\", \"ids in defs tags\" },\n};\n\nstatic void\nfindSvgTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic void\nmakeTagEntryWithNodeNotify (xmlSubparser *s,\n\t\t\t\t\t\t\txmlNode *node,\n\t\t\t\t\t\t\ttagEntryInfo *xmlTag)\n{\n\tif (node->type == XML_ATTRIBUTE_NODE\n\t\t&& (strcmp ((char *)node->name, \"id\") == 0)\n\t\t&& node->parent && node->parent->parent\n\t\t&& node->parent->parent->type == XML_ELEMENT_NODE\n\t\t&& (strcmp ((char *)node->parent->parent->name, \"defs\") == 0))\n\t{\n\t\ttagEntryInfo tag;\n\t\tinitTagEntry (&tag, xmlTag->name, K_DEF);\n\t\tupdateTagLine (&tag, xmlTag->lineNumber, xmlTag->filePosition);\n\t\tmakeTagEntry (&tag);\n\t}\n}\n\nstatic xmlSubparser svgSubparser = {\n\t.subparser = {\n\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t},\n\t.makeTagEntryWithNodeNotify = makeTagEntryWithNodeNotify,\n};\n\nextern parserDefinition*\nSvgParser (void)\n{\n\tstatic const char *const extensions [] = { \"svg\", NULL };\n\tparserDefinition* const def = parserNew (\"SVG\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"XML\", &svgSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable         = SvgKinds;\n\tdef->kindCount     = ARRAY_SIZE (SvgKinds);\n\tdef->extensions    = extensions;\n\tdef->parser        = findSvgTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/systemdunit.c",
    "content": "/*\n*\n*   Copyright (c) 2015, Red Hat, Inc.\n*   Copyright (c) 2015, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include <ctype.h>\n#include <string.h>\n\n#include \"x-systemdunit.h\"\n#include \"entry.h\"\n#include \"x-iniconf.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n\n\n\n/*\n*   DATA DEFINITIONS\n*/\nstatic roleDefinition SystemdUnitUnitRoles [] = {\n\t{ true, \"Requires\", \"referred in Requires key\" },\n\t{ true, \"Wants\", \"referred in Wants key\" },\n\t{ true, \"After\", \"referred in After key\" },\n\t{ true, \"Before\", \"referred in Before key\" },\n\t{ true, \"RequiredBy\", \"referred in RequiredBy key\" },\n\t{ true, \"WantedBy\", \"referred in WantedBy key\" },\n\t{ true, \"foreignlang\", \"referenced in foreign languages\", .version = 1 },\n\t/* ... */\n};\n\nstatic kindDefinition SystemdUnitKinds [] = {\n\t{ true, 'u', \"unit\", \"units\",\n\t  .referenceOnly = true, ATTACH_ROLES(SystemdUnitUnitRoles)},\n};\n\nstatic int roleOf (const char* key, int kind)\n{\n\tint i;\n\n\tfor (i = 0; i < SystemdUnitKinds [kind].nRoles; i++)\n\t{\n\t\tif (strcmp (SystemdUnitKinds [kind].roles[i].name, key) == 0)\n\t\t\treturn i;\n\t}\n\n\treturn -1;\n}\n\nstatic void makeSystemdReferencedUnit (const char *value, int kind, int role)\n{\n\tvString *unit = vStringNew ();\n\n\twhile (*value != '\\0')\n\t{\n\t\tif (*value == ',')\n\t\t{\n\t\t\tmakeSimpleRefTag (unit, kind, role);\n\t\t\tvStringClear (unit);\n\t\t}\n\t\telse if (! isspace ((unsigned char) *value))\n\t\t\tvStringPut (unit, *value);\n\n\t\tvalue++;\n\t}\n\n\tif (vStringLength (unit) > 0)\n\t\tmakeSimpleRefTag (unit, kind, role);\n\tvStringDelete (unit);\n}\n\nstatic void newDataCallback (iniconfSubparser *s CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t const char *section CTAGS_ATTR_UNUSED, const char *key, const char *value)\n{\n\tint r;\n\n\tif (isXtagEnabled (XTAG_REFERENCE_TAGS) && value)\n\t{\n\t\tr = roleOf (key, SYSTEMD_UNIT_KIND);\n\t\tif (r >= 0)\n\t\t\tmakeSystemdReferencedUnit (value, SYSTEMD_UNIT_KIND, r);\n\t}\n}\n\nstatic void findSystemdUnitTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* SystemdUnitParser (void)\n{\n\tstatic const char *const extensions [] = { \"service\", \"socket\", \"device\",\n\t\t\t\t\t\t\t\t\t\t\t   \"mount\", \"automount\", \"swap\", \"target\",\n\t\t\t\t\t\t\t\t\t\t\t   \"path\", \"timer\", \"snapshot\",\n\t\t\t\t\t\t\t\t\t\t\t   \"slice\", NULL };\n\tstatic iniconfSubparser systemdUnitSubparser = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t},\n\t\t.newDataNotify = newDataCallback,\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Iniconf\", &systemdUnitSubparser },\n\t};\n\n\tstatic selectLanguage selectors[] = {\n\t\tselectByDBusServiceAndSystemdUnitSectionNames,\n\t\tNULL\n\t};\n\n\tparserDefinition* const def = parserNew (\"SystemdUnit\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE(dependencies);\n\tdef->kindTable      = SystemdUnitKinds;\n\tdef->kindCount  = ARRAY_SIZE (SystemdUnitKinds);\n\tdef->extensions = extensions;\n\tdef->selectLanguage = selectors;\n\tdef->parser     = findSystemdUnitTags;\n\tdef->useCork    = CORK_QUEUE;\n\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/tcl.c",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*   Copyright (c) 2017, Masatake YAMATO\n*   Copyright (c) 2017, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for TCL scripts.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"tokeninfo.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"keyword.h\"\n#include \"entry.h\"\n#include \"routines.h\"\n#include \"ptrarray.h\"\n#include \"x-tcl.h\"\n\n#include <string.h>\n\n\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_PROCEDURE, K_NAMESPACE, K_PARAMETER,\n} tclKind;\n\nstatic scopeSeparator TclParameterSeparators [] = {\n\t{ K_PROCEDURE        , \"{\" },\n};\n\nstatic kindDefinition TclKinds [] = {\n\t{ true, 'p', \"procedure\", \"procedures\", },\n\t{ true, 'n', \"namespace\", \"namespaces\", },\n\t{ false, 'z', \"parameter\", \"procedure parameters\",\n\t  ATTACH_SEPARATORS(TclParameterSeparators)},\n};\n\nenum {\n\tKEYWORD_PROC,\n\tKEYWORD_NAMESPACE,\n\tKEYWORD_EVAL,\n\tKEYWORD_PACKAGE,\n};\n\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\n\nstatic const keywordTable TclKeywordTable[] = {\n\t/* keyword\t\t\tkeyword ID */\n\t{ \"proc\",\t\t\tKEYWORD_PROC\t\t},\n\t{ \"namespace\",\t\tKEYWORD_NAMESPACE\t},\n\t{ \"eval\",\t\t\tKEYWORD_EVAL\t\t},\n\t{ \"package\",        KEYWORD_PACKAGE     },\n};\n\ntypedef struct sCollector collector;\nstruct sCollector {\n\tvoid (* proc) (const tokenInfo *const, collector *);\n\tvString *str;\n\tint depth;\n\tint scopeIndex;\n\tint nth;\n};\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic bool tokenIsEOL (const tokenInfo *const token);\n\nstatic void initToken (tokenInfo *token, void *data);\nstatic void readToken (tokenInfo *const token, void *data);\nstatic void clearToken (tokenInfo *token);\nstatic void copyToken (tokenInfo *dest, tokenInfo *src, void *data CTAGS_ATTR_UNUSED);\n\nstruct sTclParserState {\n\tenum TclTokenType lastTokenType;\n};\n\ntypedef struct sTclToken {\n\ttokenInfo base;\n\tint scopeIndex;\n\tstruct sTclParserState *pstate;\n} tclToken;\n\n#define TCL(TOKEN) ((tclToken *)TOKEN)\n#define TCL_PSTATE(TOKEN) (TCL(TOKEN)->pstate)\n\nstatic struct tokenTypePair typePairs [] = {\n\t{ '{', '}' },\n\t{ '[', ']' },\n};\n\n\nstatic struct tokenInfoClass tclTokenInfoClass = {\n\t.nPreAlloc = 4,\n\t.typeForUndefined = TOKEN_TCL_UNDEFINED,\n\t.keywordNone      = KEYWORD_NONE,\n\t.typeForKeyword   = TOKEN_TCL_KEYWORD,\n\t.typeForEOF       = TOKEN_TCL_EOF,\n\t.extraSpace       = sizeof (tclToken) - sizeof (tokenInfo),\n\t.pairs            = typePairs,\n\t.pairCount        = ARRAY_SIZE (typePairs),\n\t.init             = initToken,\n\t.read             = readToken,\n\t.clear            = clearToken,\n\t.copy             = copyToken,\n};\n\nextern tokenInfo *newTclToken (void *pstate)\n{\n\treturn newTokenFull (&tclTokenInfoClass, pstate);\n}\n\nstatic void clearToken (tokenInfo *token)\n{\n\tTCL (token)->scopeIndex = CORK_NIL;\n\tTCL (token)->pstate = NULL;\n}\n\nstatic void copyToken (tokenInfo *dest, tokenInfo *src, void *data CTAGS_ATTR_UNUSED)\n{\n\tTCL (dest)->scopeIndex =\n\t\tTCL (src)->scopeIndex;\n\tTCL (dest)->pstate =\n\t\tTCL (src)->pstate;\n}\n\nstatic void readString (vString *string)\n{\n\tint c;\n\tbool escaped = false;\n\n\twhile (1)\n\t{\n\t\tc = getcFromInputFile ();\n\t\tswitch (c)\n\t\t{\n\t\tcase EOF:\n\t\t\treturn;\n\t\tcase '\\\\':\n\t\t\tif (escaped)\n\t\t\t{\n\t\t\t\tvStringPut (string, c);\n\t\t\t\tescaped = false;\n\t\t\t}\n\t\t\telse\n\t\t\t\tescaped = true;\n\t\t\tbreak;\n\t\tcase '\"':\n\t\t\tvStringPut (string, c);\n\t\t\tif (escaped)\n\t\t\t\tescaped = false;\n\t\t\telse\n\t\t\t\treturn;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tescaped = false;\n\t\t\tvStringPut (string, c);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic void readIdentifier (vString *string)\n{\n\tbool seen_backslash = false;\n\n\twhile (1)\n\t{\n\t\tint c = getcFromInputFile ();\n\t\tif (c == EOF)\n\t\t\tbreak;\n\n\t\tif (c == '\\\\')\n\t\t{\n\t\t\tvStringPut (string, c);\n\t\t\tseen_backslash = true;\n\t\t}\n\t\telse if (isgraph (c) &&\n\t\t\t\t (seen_backslash ||  (!strchr (\"{}[]\\\"\", c))))\n\t\t{\n\t\t\tvStringPut (string, c);\n\t\t\tseen_backslash = false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tungetcToInputFile (c);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic keywordId resolveKeyword (vString *string)\n{\n\tchar *s = vStringValue (string);\n\tstatic langType lang = LANG_AUTO;\n\n\tif (lang == LANG_AUTO)\n\t\tlang = getInputLanguage ();\n\n\treturn lookupKeyword (s, lang);\n}\n\nstatic void initToken (tokenInfo *token, void *data)\n{\n\tTCL (token)->pstate = data;\n}\n\nstatic void readToken0 (tokenInfo *const token, struct sTclParserState *pstate)\n{\n\tint c = EOF;\n\tbool escaped;\n\tbool bol = (pstate->lastTokenType == TOKEN_TCL_EOL\n\t\t\t\t|| pstate->lastTokenType == ';'\n\t\t\t\t|| pstate->lastTokenType == TOKEN_TCL_UNDEFINED);\n\ttoken->type\t\t= TOKEN_TCL_UNDEFINED;\n\ttoken->keyword\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\n getNextChar:\n\tescaped = false;\n\n\tdo {\n\t\tc = getcFromInputFile ();\n\t} while (c == ' ' || c== '\\t' || c == '\\f');\n\n\tif (c == '\\\\')\n\t{\n\t\tbol = false;\n\t\tint c0 = getcFromInputFile ();\n\t\tswitch (c0)\n\t\t{\n\t\tcase '\\n':\n\t\tcase '\\r':\n\t\t\tgoto getNextChar;\n\t\tdefault:\n\t\t\tescaped = true;\n\t\t\tc = c0;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tswitch (c)\n\t{\n\tcase EOF:\n\t\ttoken->type = TOKEN_TCL_EOF;\n\t\tbreak;\n\tcase '\\n':\n\tcase '\\r':\n\t\ttoken->type = TOKEN_TCL_EOL;\n\t\tbreak;\n\tcase '#':\n\t\tif (!escaped)\n\t\t{\n\t\t\tif (bol)\n\t\t\t{\n\t\t\t\tdo\n\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\twhile (c != EOF && c != '\\r' && c != '\\n');\n\t\t\t}\n\t\t\tgoto getNextChar;\n\t\t}\n\tcase '\"':\n\t\tif (!escaped)\n\t\t{\n\t\t\ttoken->type = TOKEN_TCL_STRING;\n\t\t\ttokenPutc (token, c);\n\t\t\treadString (token->string);\n\t\t\tbreak;\n\t\t}\n\tcase ';':\n\tcase '{':\n\tcase '}':\n\tcase '[':\n\tcase ']':\n\t\tif (!escaped)\n\t\t{\n\t\t\ttokenPutc (token, c);\n\t\t\ttoken->type = c;\n\t\t\tbreak;\n\t\t}\n\tcase '$':\n\t\tif (!escaped)\n\t\t{\n\t\t\ttokenPutc (token, c);\n\t\t\ttoken->type = TOKEN_TCL_VARIABLE;\n\n\t\t\tint c0 = getcFromInputFile ();\n\t\t\tif (c0 == EOF)\n\t\t\t\tbreak;\n\n\t\t\tif (c0 == '{')\n\t\t\t{\n\t\t\t\ttokenPutc (token, c0);\n\t\t\t\twhile ((c0 = getcFromInputFile ()) != EOF)\n\t\t\t\t{\n\t\t\t\t\ttokenPutc (token, c0);\n\t\t\t\t\tif (c0 == '}')\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (isalnum (c0))\n\t\t\t{\n\t\t\t\ttokenPutc (token, c0);\n\t\t\t\treadIdentifier (token->string);\n\t\t\t}\n\t\t\telse\n\t\t\t\tungetcToInputFile (c0);\n\t\t\tbreak;\n\t\t}\n\tdefault:\n\t\t\ttokenPutc (token, c);\n\t\t\treadIdentifier (token->string);\n\n\t\t\ttoken->keyword = resolveKeyword (token->string);\n\t\t\tif (token->keyword == KEYWORD_NONE)\n\t\t\t\ttoken->type = TOKEN_TCL_IDENTIFIER;\n\t\t\telse\n\t\t\t\ttoken->type = TOKEN_TCL_KEYWORD;\n\t\t\tbreak;\n\t}\n}\n\nstatic void readToken (tokenInfo *const token, void *data)\n{\n\tstruct sTclParserState *pstate = TCL_PSTATE(token);\n\n\treadToken0 (token, pstate);\n\n\tpstate->lastTokenType = token->type;\n\n\tif (data)\n\t{\n\t\tcollector *col = data;\n\t\tcol->proc (token, col);\n\t}\n}\n\nstatic bool tokenIsEOL (const tokenInfo *const token)\n{\n\tif (token->type == ';'\n\t\t|| tokenIsType (token, TCL_EOL)\n\t\t|| tokenIsEOF (token))\n\t\treturn true;\n\treturn false;\n}\n\nstatic void skipToEndOfCmdline (tokenInfo *const token)\n{\n\twhile (!tokenIsEOL (token))\n\t{\n\t\tif ((token->type == '{')\n\t\t\t|| (token->type == '['))\n\t\t\ttokenSkipOverPair(token);\n\t\ttokenRead (token);\n\t}\n}\n\nextern void skipToEndOfTclCmdline (tokenInfo *const token)\n{\n\tskipToEndOfCmdline (token);\n}\n\nstatic bool isAbsoluteIdentifier(tokenInfo *const token)\n{\n\treturn !strncmp (tokenString (token), \"::\", 2);\n}\n\nstatic const char* getLastComponentInIdentifier(tokenInfo *const token)\n{\n\tconst char* s = tokenString (token);\n\tchar *last = strrstr(s, \"::\");\n\n\tif (last)\n\t\treturn last + 2;\n\telse\n\t\treturn NULL;\n}\n\n\nstatic void notifyNamespaceImport (tokenInfo *const token)\n{\n\tsubparser *sub;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\ttclSubparser *tclsub = (tclSubparser *)sub;\n\n\t\tif (tclsub->namespaceImportNotify)\n\t\t{\n\t\t\tenterSubparser(sub);\n\t\t\ttclsub->namespaceImportNotify (tclsub, tokenString (token),\n\t\t\t\t\t\t\t\t\t\t   TCL_PSTATE(token));\n\t\t\tleaveSubparser();\n\t\t}\n\t}\n}\n\nstatic int notifyCommand (tokenInfo *const token, int parent)\n{\n\tsubparser *sub;\n\tint r = CORK_NIL;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\ttclSubparser *tclsub = (tclSubparser *)sub;\n\n\t\tif (tclsub->commandNotify)\n\t\t{\n\t\t\tenterSubparser(sub);\n\t\t\tr = tclsub->commandNotify (tclsub, tokenString (token), parent,\n\t\t\t\t\t\t\t\t\t   TCL_PSTATE(token));\n\t\t\tleaveSubparser();\n\t\t\tif (r != CORK_NIL)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treturn r;\n}\n\nstatic void collectSignature (const tokenInfo *const token, collector * col)\n{\n\tif (tokenIsEOL (token))\n\t\treturn;\n\n\tif (tokenIsType (token, TCL_IDENTIFIER) &&\n\t\t(col->depth == 1\n\t\t || (col->depth == 2 && tokenIsType (token, TCL_IDENTIFIER)\n\t\t\t && vStringLast (col->str) == '{')))\n\t{\n\t\ttagEntryInfo e;\n\t\tinitTagEntry (&e, tokenString (token), K_PARAMETER);\n\t\te.extensionFields.scopeIndex = col->scopeIndex;\n\t\te.extensionFields.nth = col->nth++;\n\t\tmakeTagEntry (&e);\n\t}\n\telse if (tokenIsTypeVal (token, '{'))\n\t\tcol->depth++;\n\telse if (tokenIsTypeVal (token, '}'))\n\t\tcol->depth--;\n\n\tif ((vStringLength (col->str) > 0\n\t\t && vStringLast (col->str) != '{'\n\t\t && vStringLast (col->str) != '['\n\t\t && vStringLast (col->str) != '(')\n\t\t&& (!tokenIsTypeVal (token, '}'))\n\t\t&& (!tokenIsTypeVal (token, ']'))\n\t\t&& (!tokenIsTypeVal (token, ')')))\n\t\tvStringPut (col->str, ' ');\n\tvStringCat (col->str, token->string);\n}\n\nstatic void tokenReadQuotedIdentifier (tokenInfo *const token)\n{\n\ttoken->type  = TOKEN_TCL_IDENTIFIER;\n\tvStringClear (token->string);\n\tunsigned int depth = 1;\n\twhile (depth > 0)\n\t{\n\t\tint c = getcFromInputFile ();\n\t\tswitch (c)\n\t\t{\n\t\tcase EOF:\n\t\t\treturn;\n\t\tcase '{':\n\t\t\tdepth++;\n\t\t\ttokenPutc (token, c);\n\t\t\tbreak;\n\t\tcase '}':\n\t\t\tif (depth != 1)\n\t\t\t\ttokenPutc (token, c);\n\t\t\tdepth--;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tvStringPut (token->string, c);\n\t\t}\n\t}\n}\n\nstatic void parseProc (tokenInfo *const token,\n\t\t\t\t\t   int parent, bool quoted)\n{\n\tint index = CORK_NIL;\n\tint index_fq = CORK_NIL;\n\tif (quoted)\n\t\ttokenReadQuotedIdentifier (token);\n\telse\n\t\ttokenRead (token);\n\n\tif (tokenIsType(token, TCL_IDENTIFIER))\n\t{\n\t\tconst char *last = getLastComponentInIdentifier (token);\n\t\tif (last)\n\t\t{\n\t\t\ttagEntryInfo e;\n\n\t\t\tinitTagEntry (&e, last, K_PROCEDURE);\n\t\t\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\n\t\t\tint len  = (last - tokenString (token));\n\t\t\tvString *ns = vStringNew();\n\t\t\ttagEntryInfo *e_parent = getEntryInCorkQueue (parent);\n\t\t\tif (isAbsoluteIdentifier (token))\n\t\t\t{\n\t\t\t\tif (len > 2)\n\t\t\t\t\tvStringNCopy (ns, token->string, len - 2);\n\t\t\t}\n\t\t\telse if (e_parent)\n\t\t\t{\n\t\t\t\tconst char * sep = scopeSeparatorFor (getInputLanguage(),\n\t\t\t\t\t\t\t\t\t\t\t\t\t  K_PROCEDURE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  e_parent->kindIndex);\n\t\t\t\tvStringCatS(ns, e_parent->name);\n\t\t\t\tvStringCatS(ns, sep);\n\t\t\t\tvStringNCopy(ns, token->string, len - 2);\n\t\t\t}\n\t\t\telse\n\t\t\t\tvStringNCopy (ns, token->string, len - 2);\n\n\t\t\tif (vStringLength(ns) > 0)\n\t\t\t{\n\t\t\t\te.extensionFields.scopeKindIndex = K_NAMESPACE;\n\t\t\t\te.extensionFields.scopeName = vStringValue (ns);\n\t\t\t}\n\n\t\t\tif (*e.name == '\\0')\n\t\t\t\te.allowNullTag = 1;\n\t\t\te.skipAutoFQEmission = 1;\n\t\t\tindex = makeTagEntry (&e);\n\n\t\t\tif (isXtagEnabled(XTAG_QUALIFIED_TAGS))\n\t\t\t{\n\t\t\t\tconst char * sep = scopeSeparatorFor (getInputLanguage(),\n\t\t\t\t\t\t\t\t\t\t\t\t\t  K_PROCEDURE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  vStringIsEmpty (ns)\n\t\t\t\t\t\t\t\t\t\t\t\t\t  ? KIND_GHOST_INDEX\n\t\t\t\t\t\t\t\t\t\t\t\t\t  : K_NAMESPACE);\n\n\t\t\t\tvStringCatS (ns, sep);\n\t\t\t\tvStringCatS (ns, last);\n\n\t\t\t\tindex_fq = makeSimpleTag (ns, K_PROCEDURE);\n\t\t\t\ttagEntryInfo *e_fq = getEntryInCorkQueue (index_fq);\n\t\t\t\tif (e_fq)\n\t\t\t\t\tmarkTagExtraBit (e_fq, XTAG_QUALIFIED_TAGS);\n\t\t\t}\n\t\t\tvStringDelete (ns);\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttagEntryInfo e;\n\t\t\tinitTagEntry (&e, tokenString (token), K_PROCEDURE);\n\t\t\tif (quoted)\n\t\t\t{\n\t\t\t\tupdateTagLine(&e, token->lineNumber, token->filePosition);\n\t\t\t\tif (vStringIsEmpty (token->string))\n\t\t\t\t\te.allowNullTag = 1;\n\t\t\t}\n\t\t\te.extensionFields.scopeIndex = parent;\n\t\t\tindex = makeTagEntry (&e);\n\t\t}\n\t}\n\telse if (!quoted && token->type == '{')\n\t{\n\t\tparseProc(token, parent, true);\n\t\treturn;\n\t}\n\n\tvString *signature = NULL;\n\tif (!tokenIsEOL (token))\n\t{\n\t\ttokenRead (token);\n\t\tif (tokenIsType (token, TCL_IDENTIFIER))\n\t\t{\n\t\t\ttagEntryInfo e;\n\t\t\tinitTagEntry (&e, tokenString (token), K_PARAMETER);\n\t\t\te.extensionFields.scopeIndex = index;\n\t\t\tmakeTagEntry (&e);\n\t\t\tsignature = vStringNewCopy (token->string);\n\t\t}\n\t\telse if (token->type == '{')\n\t\t{\n\t\t\tsignature = vStringNewInit (\"{\");\n\t\t\tcollector col = {\n\t\t\t\t.proc = collectSignature,\n\t\t\t\t.str = signature,\n\t\t\t\t.depth = 1,\n\t\t\t\t.scopeIndex = index,\n\t\t\t\t.nth = 0,\n\t\t\t};\n\t\t\ttokenSkipOverPairFull (token, &col);\n\t\t}\n\n\t\tskipToEndOfCmdline(token);\n\t}\n\n\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\tif (e)\n\t{\n\t\tsetTagEndLine (e, token->lineNumber);\n\n\t\tif (signature)\n\t\t{\n\t\t\te->extensionFields.signature = vStringDeleteUnwrap (signature);\n\t\t\tsignature = NULL;\n\t\t}\n\n\t\ttagEntryInfo *e_fq = getEntryInCorkQueue (index_fq);\n\t\tif (e_fq)\n\t\t{\n\t\t\tconst char *sig = e->extensionFields.signature;\n\t\t\tsetTagEndLine (e_fq, token->lineNumber);\n\t\t\tif (sig)\n\t\t\t\te_fq->extensionFields.signature = eStrdup (sig);\n\t\t}\n\t}\n\tvStringDelete (signature);\t/* NULL is acceptable */\n}\n\nstatic void parseNamespace (tokenInfo *const token,\n\t\t\t\t\t\t\tint parent)\n{\n\ttokenRead (token);\n\tif (tokenIsEOF(token))\n\t\treturn;\n\n\tif (tokenIsType (token, TCL_IDENTIFIER) &&\n\t\t(strcmp(tokenString(token), \"import\") == 0))\n\t{\n\t\twhile (1)\n\t\t{\n\t\t\ttokenRead (token);\n\n\t\t\tif (!tokenIsType (token, TCL_IDENTIFIER))\n\t\t\t\tbreak;\n\n\t\t\tif (tokenString(token)[0] == '-')\n\t\t\t\tcontinue;\n\n\t\t\tnotifyNamespaceImport (token);\n\t\t}\n\t\tskipToEndOfCmdline(token);\n\t\treturn;\n\t}\n\telse if (!tokenIsKeyword (token, EVAL))\n\t\treturn;\n\n\ttokenRead (token);\n\tif (!tokenIsType (token, TCL_IDENTIFIER))\n\t{\n\t\tskipToEndOfCmdline(token);\n\t\treturn;\n\t}\n\n\tint index = makeSimpleTag (token->string, K_NAMESPACE);\n\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\tif (e && parent != CORK_NIL && !isAbsoluteIdentifier(token))\n\t\te->extensionFields.scopeIndex = parent;\n\n\ttokenRead (token);\n\tif (token->type != '{')\n\t{\n\t\tskipToEndOfCmdline(token);\n\t\treturn;\n\t}\n\n\tdo {\n\t\ttokenRead (token);\n\t\tif (tokenIsKeyword (token, NAMESPACE))\n\t\t\tparseNamespace (token, index);\n\t\telse if (tokenIsKeyword (token, PROC))\n\t\t\tparseProc (token, index, false);\n\t\telse if (tokenIsType (token, TCL_IDENTIFIER))\n\t\t{\n\t\t\tint r = notifyCommand (token, index);\n\t\t\tif (r == CORK_NIL)\n\t\t\t\tskipToEndOfCmdline(token);\n\t\t}\n\t\telse if (token->type == '}')\n\t\t{\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine (e, token->lineNumber);\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tskipToEndOfCmdline(token);\n\t} while (!tokenIsEOF(token));\n}\n\nstatic void parsePackage (tokenInfo *const token)\n{\n\ttokenRead (token);\n\tif (tokenIsType (token, TCL_IDENTIFIER)\n\t\t&& (strcmp (tokenString (token), \"require\") == 0))\n\t{\n\tnext:\n\t\ttokenRead (token);\n\t\tif (tokenIsType (token, TCL_IDENTIFIER)\n\t\t\t&& (vStringLength (token->string) > 0))\n\t\t{\n\t\t\tif (tokenString(token)[0] == '-')\n\t\t\t\tgoto next;\n\t\t}\n\t}\n\tskipToEndOfCmdline(token);\n}\n\n\nstatic void findTclTags (void)\n{\n\tstruct sTclParserState pstate = {\n\t\t.lastTokenType = TOKEN_TCL_UNDEFINED,\n\t};\n\ttokenInfo *const token = newTclToken (&pstate);\n\n\tdo {\n\t\ttokenRead (token);\n\t\tif (tokenIsKeyword (token, NAMESPACE))\n\t\t\tparseNamespace (token, CORK_NIL);\n\t\telse if (tokenIsKeyword (token, PROC))\n\t\t\tparseProc (token, CORK_NIL, false);\n\t\telse if (tokenIsKeyword (token, PACKAGE))\n\t\t\tparsePackage (token);\n\t\telse if (tokenIsType (token, TCL_IDENTIFIER))\n\t\t{\n\t\t\tint r = notifyCommand (token, CORK_NIL);\n\t\t\tif (r == CORK_NIL)\n\t\t\t\tskipToEndOfCmdline(token);\n\t\t}\n\t\telse\n\t\t\tskipToEndOfCmdline(token);\n\t} while (!tokenIsEOF(token));\n\n\ttokenDelete (token);\n\tflashTokenBacklog (&tclTokenInfoClass);\n}\n\nextern parserDefinition* TclParser (void)\n{\n\tstatic const char *const extensions [] = { \"tcl\", \"tk\", \"wish\", \"exp\", NULL };\n\tstatic const char *const aliases [] = {\"expect\", \"tclsh\", NULL };\n\n\tparserDefinition* def = parserNew (\"Tcl\");\n\tdef->kindTable      = TclKinds;\n\tdef->kindCount  = ARRAY_SIZE (TclKinds);\n\tdef->extensions = extensions;\n\tdef->aliases = aliases;\n\tdef->keywordTable = TclKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (TclKeywordTable);\n\n\tdef->parser     = findTclTags;\n\tdef->useCork    = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\tdef->defaultScopeSeparator = \"::\";\n\tdef->defaultRootScopeSeparator = \"::\";\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/tcloo.c",
    "content": "/*\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n\n#include \"general.h\"  /* must always come first */\n#include \"x-tcl.h\"\n#include \"param.h\"\n#include \"parse.h\"\n#include \"entry.h\"\n#include \"tokeninfo.h\"\n\n#include <string.h>\n\n\nstruct tclooSubparser {\n\ttclSubparser tcl;\n\tbool foundTclOONamespaceImported;\n};\n\nstatic scopeSeparator TclOOGenericSeparators [] = {\n\t{ KIND_WILDCARD_INDEX, \"::\" },\n};\n\nenum TclOOKind {\n\tK_CLASS,\n\tK_METHOD,\n};\n\nstatic kindDefinition TclOOKinds[] = {\n\t{ true, 'c', \"class\", \"classes\" },\n\t{ true, 'm', \"method\", \"methods\",\n\t  ATTACH_SEPARATORS(TclOOGenericSeparators) },\n};\n\nstatic bool tclooForceUse;\n\nstatic void parseMethod (tokenInfo *token, int owner)\n{\n\ttokenRead (token);\n\tif (tokenIsType (token, TCL_IDENTIFIER))\n\t{\n\t\ttagEntryInfo e;\n\n\t\tinitTagEntry(&e, tokenString (token), K_METHOD);\n\t\te.extensionFields.scopeIndex = owner;\n\t\tmakeTagEntry (&e);\n\t}\n\tskipToEndOfTclCmdline (token);\n}\n\nstatic void parseSuperclass (tokenInfo *token, int this_class)\n{\n\ttokenRead (token);\n\tif (tokenIsType (token, TCL_IDENTIFIER))\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue(this_class);\n\n\t\tif (e)\n\t\t{\n\t\t\tif (e->extensionFields.inheritance)\n\t\t\t{   /* superclass is used twice in a class. */\n\t\t\t\teFree ((void *)e->extensionFields.inheritance);\n\t\t\t}\n\t\t\te->extensionFields.inheritance = eStrdup(tokenString(token));\n\t\t}\n\t}\n\tskipToEndOfTclCmdline (token);\n}\n\nstatic int parseClass (tclSubparser *s CTAGS_ATTR_UNUSED, int parentIndex,\n\t\t\t\t\t   void *pstate)\n{\n\ttokenInfo *token = newTclToken (pstate);\n\tint r = CORK_NIL;\n\n\ttokenRead (token);\n\tif (tokenIsType (token, TCL_IDENTIFIER)\n\t\t&& (strcmp(tokenString(token), \"create\") == 0))\n\t{\n\t\ttokenRead (token);\n\t\tif (tokenIsType (token, TCL_IDENTIFIER))\n\t\t{\n\t\t\ttagEntryInfo e;\n\n\t\t\tinitTagEntry(&e, tokenString (token), K_CLASS);\n\t\t\te.extensionFields.scopeIndex = parentIndex;\n\t\t\tr = makeTagEntry (&e);\n\t\t}\n\n\t\tif (tokenSkipToType (token, '{'))\n\t\t{\n\t\t\tdo {\n\t\t\t\ttokenRead (token);\n\t\t\t\tif (tokenIsType (token, TCL_IDENTIFIER)\n\t\t\t\t\t|| tokenIsType (token, TCL_KEYWORD))\n\t\t\t\t{\n\t\t\t\t\tif (strcmp(tokenString(token), \"method\") == 0)\n\t\t\t\t\t\tparseMethod(token, r);\n\t\t\t\t\telse if (strcmp(tokenString(token), \"superclass\") == 0)\n\t\t\t\t\t\tparseSuperclass(token, r);\n\t\t\t\t\telse\n\t\t\t\t\t\tskipToEndOfTclCmdline (token);\n\t\t\t\t}\n\t\t\t\telse if (token->type == '}')\n\t\t\t\t\tbreak;\n\t\t\t} while (!tokenIsEOF(token));\n\t\t}\n\t}\n\n\tskipToEndOfTclCmdline (token);\n\ttokenDelete(token);\n\treturn r;\n}\n\nstatic int commandNotify (tclSubparser *s, char *command,\n\t\t\t\t\t\t  int parentIndex, void *pstate)\n{\n\tstruct tclooSubparser *tcloo = (struct tclooSubparser *)s;\n\tint r = CORK_NIL;\n\n\tif ((tcloo->foundTclOONamespaceImported\n\t\t && (strcmp (command, \"class\") == 0))\n\t\t|| (strcmp (command, \"oo::class\") == 0))\n\t\tr = parseClass (s, parentIndex, pstate);\n\n\treturn r;\n}\n\nstatic void namespaceImportNotify (tclSubparser *s, char *namespace,\n\t\t\t\t\t\t\t\t   void *pstate CTAGS_ATTR_UNUSED)\n{\n\tstruct tclooSubparser *tcloo = (struct tclooSubparser *)s;\n\n\tif (strcmp(namespace, \"oo::*\") == 0\n\t\t|| strcmp(namespace, \"oo::class\") == 0)\n\t\ttcloo->foundTclOONamespaceImported = true;\n}\n\nstatic void inputStart (subparser *s)\n{\n\tstruct tclooSubparser *tcloo = (struct tclooSubparser *)s;\n\n\ttcloo->foundTclOONamespaceImported = tclooForceUse;\n}\n\nstatic struct tclooSubparser tclooSubparser = {\n\t.tcl = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t\t.inputStart = inputStart,\n\t\t},\n\t\t.commandNotify = commandNotify,\n\t\t.namespaceImportNotify = namespaceImportNotify,\n\t},\n};\n\nstatic void findTclOOTags(void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic bool tclooForceUseParamHandler (const langType language CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t  const char *name, const char *arg)\n{\n\ttclooForceUse = paramParserBool (arg, tclooForceUse, name, \"parameter\");\n\treturn true;\n}\n\nstatic paramDefinition TclOOParams [] = {\n\t{ .name = \"forceUse\",\n\t  .desc = \"enable the parser even when `oo' namespace is not specified in the input (true or [false])\" ,\n\t  .handleParam = tclooForceUseParamHandler,\n\t},\n};\n\nextern parserDefinition* TclOOParser (void)\n{\n\tparserDefinition* const def = parserNew(\"TclOO\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Tcl\", &tclooSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = TclOOKinds;\n\tdef->kindCount = ARRAY_SIZE(TclOOKinds);\n\n\tdef->parser = findTclOOTags;\n\tdef->useCork = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\n\tdef->paramTable = TclOOParams;\n\tdef->paramCount = ARRAY_SIZE(TclOOParams);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/tex-beamer.c",
    "content": "/*\n *\t Copyright (c) 2020, Masatake YAMATO\n *\n *\t This source code is released for free distribution under the terms of the\n *\t GNU General Public License version 2 or (at your option) any later version.\n *\n *\t This module contains functions for generating tags for Beamer class of TeX.\n *   - https://github.com/josephwright/beamer\n *   - http://mirrors.ibiblio.org/CTAN/macros/latex/contrib/beamer/doc/beameruserguide.pdf\n *\n */\n\n/*\n *\t INCLUDE FILES\n */\n\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"x-tex.h\"\n\n#include <string.h>\n\n\n/*\n *\t DATA DECLARATIONS\n */\n\nstruct beamerSubparser {\n\ttexSubparser tex;\n\tint lastTitleCorkIndex;\n};\n\nenum BamerKind {\n\tK_FRAMETITLE,\n\tK_FRAMESUBTITLE,\n};\n\n\n/*\n *\t DATA DEFINITIONS\n */\n\nstatic kindDefinition beamerKinds[] = {\n\t{ true, 'f', \"frametitle\", \"frametitles\" },\n\t{ true, 'g', \"framesubtitle\", \"framesubtitles\"},\n};\n\n/* \\frametitle<overlay specification>[short frame title]{frame title text} */\nstatic struct TexParseStrategy frametitle_strategy[] = {\n\t{\n\t\t.type = '<',\n\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t.name = NULL,\n\t},\n\t{\n\t\t.type = '[',\n\t\t.flags = TEX_NAME_FLAG_OPTIONAL|TEX_NAME_FLAG_EXCLUSIVE,\n\t\t.kindIndex = K_FRAMETITLE,\n\t\t.roleIndex = ROLE_DEFINITION_INDEX,\n\t\t.name = NULL,\n\t\t.unique = false,\n\t},\n\t{\n\t\t.type = '{',\n\t\t.flags = TEX_NAME_FLAG_INCLUDING_WHITESPACE,\n\t\t.kindIndex = K_FRAMETITLE,\n\t\t.roleIndex = ROLE_DEFINITION_INDEX,\n\t\t.name = NULL,\n\t\t.unique = true,\n\t\t.scopeIndex = CORK_NIL,\t/* root scope */\n\t},\n\t{\n\t\t.type = 0\n\t}\n};\n\n/* \\framesubtitle<overlay specification>{frame subtitle text} */\nstatic struct TexParseStrategy framesubtitle_strategy[] = {\n\t{\n\t\t.type = '<',\n\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t.name = NULL,\n\t},\n\t{\n\t\t.type = '{',\n\t\t.flags = TEX_NAME_FLAG_INCLUDING_WHITESPACE,\n\t\t.kindIndex = K_FRAMESUBTITLE,\n\t\t.roleIndex = ROLE_DEFINITION_INDEX,\n\t\t.name = NULL,\n\t\t.unique = false,\n\t},\n\t{\n\t\t.type = 0\n\t}\n};\n\n/*  \\begin{frame}<overlay specification>[<default overlay specification>][options]{title}{subtitle}*/\nstatic struct TexParseStrategy frame_env_strategy [] = {\n\t{\n\t\t.type = '<',\n\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t.name = NULL,\n\t},\n\t{\n\t\t.type = '[',\n\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t.name = NULL,\n\t},\n\t{\n\t\t.type = '[',\n\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t.name = NULL,\n\t},\n\t{\n\t\t.type = '{',\n\t\t.flags = TEX_NAME_FLAG_INCLUDING_WHITESPACE,\n\t\t.kindIndex = K_FRAMETITLE,\n\t\t.roleIndex = ROLE_DEFINITION_INDEX,\n\t\t.unique = true,\n\t\t.scopeIndex = CORK_NIL,\t/* root scope */\n\t},\n\t{\n\t\t/* This should not be optoinal. */\n\t\t.type = '{',\n\t\t.flags = TEX_NAME_FLAG_INCLUDING_WHITESPACE,\n\t\t.kindIndex = K_FRAMESUBTITLE,\n\t\t.roleIndex = ROLE_DEFINITION_INDEX,\n\t\t.name = NULL,\n\t\t.unique = false,\n\t},\n\t{\n\t\t.type = 0\n\t}\n};\n\n\n/*\n *\t FUNCTION DEFINITIONS\n */\n\nstatic struct TexParseStrategy *readIdentifierNotify (texSubparser *s,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  vString *identifier)\n{\n\t/* Reject uninteresting identifiers early. */\n\tif (! (vStringLength (identifier) > 10\n\t\t   && strncmp (vStringValue(identifier), \"\\\\frame\", 6) == 0))\n\t\treturn NULL;\n\telse if (vStringLength (identifier) == 11\n\t\t&& strcmp (vStringValue(identifier), \"\\\\frametitle\") == 0)\n\t\treturn frametitle_strategy;\n\t/* strlen(\"\\\\framesubtitle\") = 14 */\n\telse if (vStringLength (identifier) == 14\n\t\t&& strcmp (vStringValue(identifier), \"\\\\framesubtitle\") == 0)\n\t\treturn framesubtitle_strategy;\n\telse\n\t\treturn NULL;\n}\n\nstatic void inputStart (subparser *s)\n{\n\tstruct beamerSubparser *b = (struct beamerSubparser *)s;\n\tb->lastTitleCorkIndex = CORK_NIL;\n}\n\nstatic void reportStrategicParsing (texSubparser *s,\n\t\t\t\t\t\t\t\t\tconst struct TexParseStrategy *strategy)\n{\n\tstruct beamerSubparser *b = (struct beamerSubparser *)s;\n\n\tif (strategy == frametitle_strategy)\n\t{\n\t\tif (strategy [1].corkIndex != CORK_NIL)\n\t\t\tb->lastTitleCorkIndex = strategy [1].corkIndex;\n\t\telse if (strategy [2].corkIndex != CORK_NIL)\n\t\t\tb->lastTitleCorkIndex = strategy [2].corkIndex;\n\t}\n\telse if (strategy == framesubtitle_strategy)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (strategy [1].corkIndex);\n\t\tif (e)\n\t\t\te->extensionFields.scopeIndex = b->lastTitleCorkIndex;\n\t}\n\telse if (strategy == frame_env_strategy)\n\t{\n\t\tb->lastTitleCorkIndex = CORK_NIL;\n\n\t\tif (strategy [3].corkIndex != CORK_NIL)\n\t\t\tb->lastTitleCorkIndex = strategy [3].corkIndex;\n\n\t\ttagEntryInfo *e = getEntryInCorkQueue (strategy [4].corkIndex);\n\t\tif (e && b->lastTitleCorkIndex != CORK_NIL)\n\t\t\te->extensionFields.scopeIndex = b->lastTitleCorkIndex;\n\t}\n}\n\nstatic struct TexParseStrategy *readEnviromentBeginNotify (texSubparser *s,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   vString *env)\n{\n\tif (strcmp (vStringValue (env), \"frame\") == 0)\n       return frame_env_strategy;\n\treturn NULL;\n}\n\nstatic bool readEnviromentEndNotify (texSubparser *s,\n\t\t\t\t\t\t\t\t\t vString *env)\n{\n\tif (strcmp (vStringValue (env), \"frame\") == 0)\n\t{\n\t\tstruct beamerSubparser *b = (struct beamerSubparser *)s;\n\t\tsetTagEndLineToCorkEntry (b->lastTitleCorkIndex, getInputLineNumber ());\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic struct beamerSubparser beamerSubparser = {\n\t.tex = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t\t\t.inputStart = inputStart,\n\t\t},\n\t\t.readIdentifierNotify = readIdentifierNotify,\n\t\t.readEnviromentBeginNotify = readEnviromentBeginNotify,\n\t\t.readEnviromentEndNotify = readEnviromentEndNotify,\n\t\t.reportStrategicParsing = reportStrategicParsing,\n\t},\n};\n\nstatic void findBeamerTags(void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nextern parserDefinition* TexBeamerParser (void)\n{\n\tparserDefinition* const def = parserNew(\"TeXBeamer\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Tex\", &beamerSubparser },\n\t};\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable = beamerKinds;\n\tdef->kindCount = ARRAY_SIZE(beamerKinds);\n\n\tdef->parser = findBeamerTags;\n\tdef->useCork = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/tex.c",
    "content": "/*\n *\t Copyright (c) 2008, David Fishburn\n *\t Copyright (c) 2012, Jan Larres\n *\n *\t This source code is released for free distribution under the terms of the\n *\t GNU General Public License version 2 or (at your option) any later version.\n *\n *\t This module contains functions for generating tags for TeX language files.\n *\n *\t Tex language reference:\n *\t\t http://en.wikibooks.org/wiki/TeX#The_Structure_of_TeX\n */\n\n/*\n *\t INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n#include <ctype.h>\t/* to define isalpha () */\n#ifdef DEBUG\n#include <stdio.h>\n#endif\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n#include \"x-tex.h\"\n\n/*\n *\t MACROS\n */\n#define isType(token,t)\t\t(bool) ((token)->type == (t))\n#define isKeyword(token,k)\t(bool) ((token)->keyword == (k))\n#define isIdentChar(c) \\\n\t(isalpha (c) || isdigit (c) || (c) >= 0x80 || (c) == '$' || \\\n\t\t(c) == '_' || (c) == '#' || (c) == '-' || (c) == '.' || (c) == ':')\n\n/*\n *\t DATA DECLARATIONS\n */\n\n/*\n * Used to specify type of keyword.\n */\nenum eKeywordId {\n\tKEYWORD_part,\n\tKEYWORD_chapter,\n\tKEYWORD_section,\n\tKEYWORD_subsection,\n\tKEYWORD_subsubsection,\n\tKEYWORD_paragraph,\n\tKEYWORD_subparagraph,\n\tKEYWORD_label,\n\tKEYWORD_include,\n\tKEYWORD_input,\n\tKEYWORD_begin,\n\tKEYWORD_end,\n\tKEYWORD_bibitem,\n\tKEYWORD_bibliography,\n\tKEYWORD_newcommand,\n\tKEYWORD_renewcommand,\n\tKEYWORD_providecommand,\n\tKEYWORD_def,\n\tKEYWORD_declaremathoperator,\n\tKEYWORD_newenvironment,\n\tKEYWORD_renewenvironment,\n\tKEYWORD_newtheorem,\n\tKEYWORD_newcounter,\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\nenum eTokenType {\n\t/* 0..255 are the byte's value.  Some are named for convenience */\n\tTOKEN_OPEN_PAREN = '(',\n\tTOKEN_CLOSE_PAREN = ')',\n\tTOKEN_OPEN_CURLY = '{',\n\tTOKEN_CLOSE_CURLY = '}',\n\tTOKEN_OPEN_SQUARE = '[',\n\tTOKEN_CLOSE_SQUARE = ']',\n\tTOKEN_STAR = '*',\n\t/* above is special types */\n\tTOKEN_UNDEFINED = 256,\n\tTOKEN_KEYWORD,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n};\ntypedef int tokenType;\n\ntypedef struct sTokenInfo {\n\ttokenType\t\ttype;\n\tkeywordId\t\tkeyword;\n\tvString *\t\tstring;\n\tvString *\t\tscope;\n\tunsigned long \tlineNumber;\n\tMIOPos \t\t\tfilePosition;\n} tokenInfo;\n\n/*\n *\tDATA DEFINITIONS\n */\n\nstatic langType Lang_tex;\n\nstatic vString *lastPart;\nstatic vString *lastChapter;\nstatic vString *lastSection;\nstatic vString *lastSubS;\nstatic vString *lastSubSubS;\n\ntypedef enum {\n\tTEXTAG_PART,\n\tTEXTAG_CHAPTER,\n\tTEXTAG_SECTION,\n\tTEXTAG_SUBSECTION,\n\tTEXTAG_SUBSUBSECTION,\n\tTEXTAG_PARAGRAPH,\n\tTEXTAG_SUBPARAGRAPH,\n\tTEXTAG_LABEL,\n\tTEXTAG_XINPUT,\n\tTEXTAG_BIBITEM,\n\tTEXTAG_COMMAND,\n\tTEXTAG_OPERATOR,\n\tTEXTAG_ENVIRONMENT,\n\tTEXTAG_THEOREM,\n\tTEXTAG_COUNTER,\n\tTEXTAG_COUNT\n} texKind;\n\ntypedef enum {\n\tTEX_XINPUT_INCLUDED,\n\tTEX_XINPUT_INPUT,\n\tTEX_XINPUT_BIBLIOGRAPHY,\n} texInputRole;\n\ntypedef enum {\n\tTEX_ENVIRONMENT_USED,\n} texEnvironmentRole;\n\nstatic roleDefinition TexInputRoles [] = {\n\t{ true, \"included\",\n\t  \"external input file specified with \\\\include\" },\n\t{ true, \"input\",\n\t  \"external input file specified with \\\\input\" },\n\t{ true, \"bibliography\",\n\t  \"bibliography (.bib) file\" },\n};\n\nstatic roleDefinition TexEnvironmentRoles [] = {\n\t{ false, \"used\", \"environment usage introduced by \\\\begin{MyEnv}\" },\n};\n\nstatic kindDefinition TexKinds [] = {\n\t{ true,  'p', \"part\",\t\t\t  \"parts\"\t\t\t   },\n\t{ true,  'c', \"chapter\",\t\t  \"chapters\"\t\t   },\n\t{ true,  's', \"section\",\t\t  \"sections\"\t\t   },\n\t{ true,  'u', \"subsection\",\t\t  \"subsections\"\t\t   },\n\t{ true,  'b', \"subsubsection\",\t  \"subsubsections\"\t   },\n\t{ true,  'P', \"paragraph\",\t\t  \"paragraphs\"\t\t   },\n\t{ true,  'G', \"subparagraph\",\t  \"subparagraphs\"\t   },\n\t{ true,  'l', \"label\",\t\t\t  \"labels\"\t\t\t   },\n\t{ true,  'i', \"xinput\",\t\t\t  \"external input files\",\n\t  .referenceOnly = true, ATTACH_ROLES(TexInputRoles)   },\n\t{ true,  'B', \"bibitem\",\t\t  \"bibliography items\" },\n\t{ true,  'C', \"command\",\t\t  \"command created with \\\\newcommand\" },\n\t{ true,  'o', \"operator\",\t\t  \"math operator created with \\\\DeclareMathOperator\" },\n\t{ true,  'e', \"environment\",\t  \"environment created with \\\\newenvironment\",\n\t  .referenceOnly = false, ATTACH_ROLES(TexEnvironmentRoles) },\n\t{ true,  't', \"theorem\",\t\t  \"theorem created with \\\\newtheorem\" },\n\t{ true,  'N', \"counter\",\t\t  \"counter created with \\\\newcounter\" },\n};\n\nstatic const keywordTable TexKeywordTable [] = {\n\t/* keyword\t\t\tkeyword ID */\n\t{ \"part\",\t\t\tKEYWORD_part\t\t\t\t},\n\t{ \"chapter\",\t\tKEYWORD_chapter\t\t\t\t},\n\t{ \"section\",\t\tKEYWORD_section\t\t\t\t},\n\t{ \"subsection\",\t\tKEYWORD_subsection\t\t\t},\n\t{ \"subsubsection\",\tKEYWORD_subsubsection\t\t},\n\t{ \"paragraph\",\t\tKEYWORD_paragraph\t\t\t},\n\t{ \"subparagraph\",\tKEYWORD_subparagraph\t\t},\n\t{ \"label\",\t\t\tKEYWORD_label\t\t\t\t},\n\t{ \"include\",\t\tKEYWORD_include\t\t\t\t},\n\t{ \"input\",\t\t\tKEYWORD_input\t\t\t\t},\n\t{ \"begin\",\t\t\tKEYWORD_begin\t\t\t\t},\n\t{ \"end\",\t\t\tKEYWORD_end\t\t\t\t\t},\n\t{ \"bibitem\",\t\tKEYWORD_bibitem\t\t\t\t},\n\t{ \"bibliography\",\tKEYWORD_bibliography\t\t},\n\t{ \"newcommand\",\t\tKEYWORD_newcommand\t\t\t},\n\t{ \"renewcommand\",\tKEYWORD_renewcommand\t\t},\n\t{ \"providecommand\",\tKEYWORD_providecommand\t\t},\n\t{ \"def\",\t\t\tKEYWORD_def\t\t\t\t\t},\n\t{ \"DeclareMathOperator\",\tKEYWORD_declaremathoperator\t},\n\t{ \"newenvironment\",\tKEYWORD_newenvironment\t\t},\n\t{ \"renewenvironment\",\tKEYWORD_renewenvironment},\n\t{ \"newtheorem\",\t\tKEYWORD_newtheorem\t\t\t},\n\t{ \"newcounter\",\t\tKEYWORD_newcounter\t\t\t},\n};\n\n/*\n * FUNCTION DECLARATIONS\n */\n\nstatic bool notifyReadingIdentifier  (tokenInfo *id_token, bool *tokenUnprocessed);\nstatic bool notifyReadingBeginEnvironment (tokenInfo *token, vString *envName, bool *tokenUnprocessed);\nstatic bool notifyReadingEndEnvironment (vString *envName);\n\n\n/*\n *\t FUNCTION DEFINITIONS\n */\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->string\t\t= vStringNew ();\n\ttoken->scope\t\t= vStringNew ();\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\treturn token;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tvStringDelete (token->string);\n\tvStringDelete (token->scope);\n\teFree (token);\n}\n\nstatic int getScopeInfo(texKind kind, vString *const parentName)\n{\n\tint parentKind = KIND_GHOST_INDEX;\n\tint i;\n\n\t/*\n\t * Put labels separately instead of under their scope.\n\t * Is this The Right Thing To Do?\n\t */\n\tif (kind >= TEXTAG_LABEL) {\n\t\tgoto out;\n\t}\n\n\t/*\n\t * This abuses the enum internals somewhat, but it should be ok in this\n\t * case.\n\t */\n\t/* TODO: This loop and conditions can be squashed. */\n\tfor (i = kind - 1; i >= TEXTAG_PART; --i) {\n\t\tif (i == TEXTAG_SUBSECTION && vStringLength(lastSubS) > 0) {\n\t\t\tparentKind = i;\n\t\t\tbreak;\n\t\t} else if (i == TEXTAG_SECTION && vStringLength(lastSection) > 0) {\n\t\t\tparentKind = i;\n\t\t\tbreak;\n\t\t} else if (i == TEXTAG_CHAPTER && vStringLength(lastChapter) > 0) {\n\t\t\tparentKind = i;\n\t\t\tbreak;\n\t\t} else if (i == TEXTAG_PART && vStringLength(lastPart) > 0) {\n\t\t\tparentKind = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/*\n\t * Is '\"\"' the best way to separate scopes? It has to be something that\n\t * should ideally never occur in normal LaTeX text.\n\t */\n\tfor (i = TEXTAG_PART; i < (int)kind; ++i) {\n\t\tif (i == TEXTAG_PART && vStringLength(lastPart) > 0) {\n\t\t\tvStringCat(parentName, lastPart);\n\t\t} else if (i == TEXTAG_CHAPTER && vStringLength(lastChapter) > 0) {\n\t\t\tif (vStringLength(parentName) > 0) {\n\t\t\t\tvStringCatS(parentName, \"\\\"\\\"\");\n\t\t\t}\n\t\t\tvStringCat(parentName, lastChapter);\n\t\t} else if (i == TEXTAG_SECTION && vStringLength(lastSection) > 0) {\n\t\t\tif (vStringLength(parentName) > 0) {\n\t\t\t\tvStringCatS(parentName, \"\\\"\\\"\");\n\t\t\t}\n\t\t\tvStringCat(parentName, lastSection);\n\t\t} else if (i == TEXTAG_SUBSECTION && vStringLength(lastSubS) > 0) {\n\t\t\tif (vStringLength(parentName) > 0) {\n\t\t\t\tvStringCatS(parentName, \"\\\"\\\"\");\n\t\t\t}\n\t\t\tvStringCat(parentName, lastSubS);\n\t\t}\n\t}\n out:\n\treturn parentKind;\n}\n\n/*\n *\t Tag generation functions\n */\n\nstruct symbolData {\n\tlangType lang;\n\tint kind;\n\tint *corkQueue;\n};\n\nstatic bool findTheName (int corkIndex, tagEntryInfo *entry, void *data)\n{\n\tstruct symbolData *symbolData = data;\n\n\tif (entry->langType == symbolData->lang && entry->kindIndex == symbolData->kind)\n\t{\n\t\t/* TODO: The case operation should be removed */\n\t\t*symbolData->corkQueue = corkIndex;\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nstatic int makeTexTag (tokenInfo *const token, int kind,\n\t\t\t\t\t   int roleIndex, bool unique, int scopeIndex)\n{\n\tint corkQueue = CORK_NIL;\n\tconst char *const name = vStringValue (token->string);\n\n\tif (unique)\n\t{\n\t\tstruct symbolData data = {\n\t\t\t.lang = getInputLanguage(),\n\t\t\t.kind = kind,\n\t\t\t.corkQueue = &corkQueue,\n\t\t};\n\t\t/* TODO: The case operation should be removed */\n\t\tif (foreachEntriesInScope (scopeIndex, name, findTheName, (void *)&data) == false)\n\t\t\treturn *data.corkQueue;\n\t}\n\n\ttagEntryInfo e;\n\tinitTagEntry (&e, name, kind);\n\n\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\n\tvString *parentName = NULL;\n\n\n\tif (unique)\n\t\te.extensionFields.scopeIndex = scopeIndex;\n\n\t/* Filling e.extensionFields.scopeKindIndex and\n\t * e.extensionFields.scopeName can be filled from \"kind\" parameter\n\t * of this function only when Tex parser calls this function. The\n\t * fields cannot be filled with a kind defined in a subparser.\n\t * Subparsers may fill the scope after running strategy. So in the\n\t * context of a subparser, filling the scope fields here is not\n\t * needed.\n\t */\n\tif (Lang_tex == getInputLanguage ())\n\t{\n\t\tint parentKind = KIND_GHOST_INDEX;\n\t\tparentName = vStringNew();\n\t\tparentKind = getScopeInfo(kind, parentName);\n\t\tif (parentKind != KIND_GHOST_INDEX) {\n\t\t\te.extensionFields.scopeKindIndex = parentKind;\n\t\t\te.extensionFields.scopeName = vStringValue(parentName);\n\t\t}\n\t}\n\n\tassignRole (&e, roleIndex);\n\n\tcorkQueue = makeTagEntry (&e);\n\tvStringDelete (parentName);\t/* NULL is o.k. */\n\n\tif (unique && corkQueue != CORK_NIL)\n\t\tregisterEntry (corkQueue);\n\n\treturn corkQueue;\n}\n\n/*\n *\t Parsing functions\n */\n\n/*\n *\tRead a C identifier beginning with \"firstChar\" and places it into\n *\t\"name\".\n */\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tAssert (isIdentChar (c));\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (c != EOF && isIdentChar (c));\n\n\tif (c != EOF)\n\t\tungetcToInputFile (c);\t\t/* unget non-identifier character */\n}\n\nstatic bool readTokenFull (tokenInfo *const token, const bool includeWhitespaces)\n{\n\tint c;\n\tint whitespaces = -1;\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\twhitespaces++;\n\t}\n\twhile (c == '\\t'  ||  c == ' ' ||  c == '\\n');\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tif (includeWhitespaces && whitespaces > 0 && c != '%' && c != EOF)\n\t{\n\t\tungetcToInputFile (c);\n\t\tc = ' ';\n\t}\n\n\ttoken->type = (unsigned char) c;\n\tswitch (c)\n\t{\n\t\tcase EOF: return false;\n\n\t\tcase '\\\\':\n\t\t\t\t  /*\n\t\t\t\t   * All Tex tags start with a backslash.\n\t\t\t\t   * Check if the next character is an alpha character\n\t\t\t\t   * else it is not a potential tex tag.\n\t\t\t\t   */\n\t\t\t\t  c = getcFromInputFile ();\n\t\t\t\t  if (! isalpha (c))\n\t\t\t\t\t  ungetcToInputFile (c);\n\t\t\t\t  else\n\t\t\t\t  {\n\t\t\t\t\t  vStringPut (token->string, '\\\\');\n\t\t\t\t\t  parseIdentifier (token->string, c);\n\t\t\t\t\t  token->keyword = lookupKeyword (vStringValue (token->string) + 1, Lang_tex);\n\t\t\t\t\t  if (isKeyword (token, KEYWORD_NONE))\n\t\t\t\t\t\t  token->type = TOKEN_IDENTIFIER;\n\t\t\t\t\t  else\n\t\t\t\t\t\t  token->type = TOKEN_KEYWORD;\n\t\t\t\t  }\n\t\t\t\t  break;\n\n\t\tcase '%':\n\t\t\t\t  skipToCharacterInInputFile ('\\n'); /* % are single line comments */\n\t\t\t\t  goto getNextChar;\n\t\t\t\t  break;\n\n\t\tdefault:\n\t\t\t\t  if (isIdentChar (c))\n\t\t\t\t  {\n\t\t\t\t\t  parseIdentifier (token->string, c);\n\t\t\t\t\t  token->type = TOKEN_IDENTIFIER;\n\t\t\t\t  }\n\t\t\t\t  break;\n\t}\n\treturn true;\n}\n\nstatic bool readToken (tokenInfo *const token)\n{\n\treturn readTokenFull (token, false);\n}\n\nstatic void copyToken (tokenInfo *const dest, tokenInfo *const src)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tdest->keyword = src->keyword;\n\tvStringCopy (dest->string, src->string);\n\tvStringCopy (dest->scope, src->scope);\n}\n\nstatic void updateScopeInfo (texKind kind, vString *fullname)\n{\n\tswitch (kind)\n\t{\n\t\tcase TEXTAG_PART:\n\t\t\tvStringCopy(lastPart, fullname);\n\t\t\tvStringClear(lastChapter);\n\t\t\tvStringClear(lastSection);\n\t\t\tvStringClear(lastSubS);\n\t\t\tvStringClear(lastSubSubS);\n\t\t\tbreak;\n\t\tcase TEXTAG_CHAPTER:\n\t\t\tvStringCopy(lastChapter, fullname);\n\t\t\tvStringClear(lastSection);\n\t\t\tvStringClear(lastSubS);\n\t\t\tvStringClear(lastSubSubS);\n\t\t\tbreak;\n\t\tcase TEXTAG_SECTION:\n\t\t\tvStringCopy(lastSection, fullname);\n\t\t\tvStringClear(lastSubS);\n\t\t\tvStringClear(lastSubSubS);\n\t\t\tbreak;\n\t\tcase TEXTAG_SUBSECTION:\n\t\t\tvStringCopy(lastSubS, fullname);\n\t\t\tvStringClear(lastSubSubS);\n\t\t\tbreak;\n\t\tcase TEXTAG_SUBSUBSECTION:\n\t\t\tvStringCopy(lastSubSubS, fullname);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\n/*\n *\t Scanning functions\n */\n\n/* STRATEGY array represents the sequence of * expected tokens. If an\n * input token matches the current * expectation (the current strategy),\n * parseWithStrategy() runs * the actions attached to the strategy.\n *\n * The actions are making a tag with the kind specified with kindIndex\n * field of the current strategy and/or storing a name to NAME field\n * of the current strategy.\n *\n * If the input token doesn't much the current strategy, above actions\n * are not run. If TEX_NAME_FLAG_OPTIONAL is specified in FLAGS field\n * of the current specified, parseWithStrategy() tries the next\n * strategy of STRATEGY array without reading a new token.  If\n * TEX_NAME_FLAG_OPTIONAL is not in FLAGS field, parseWithStrategy()\n * returns the control to its caller immediately.\n *\n * TOKENUNPROCESSED is used for both input and output.  As input,\n * TOKENUNPROCESSED tells whether parseWithStrategy() should read a\n * new token before matching the STRATEGY array or not.  If\n * TOKENUNPROCESSED is true, parseWithStrategy function reads a new\n * token before matching.  As output, TOKENUNPROCESSED tells the\n * caller of parseWithStrategy() that a new token is already stored to\n * TOKEN but parseWithStrategy() has not processed yet.\n */\nstatic bool parseWithStrategy (tokenInfo *token,\n\t\t\t\t\t\t\t   struct TexParseStrategy *strategy,\n\t\t\t\t\t\t\t   bool *tokenUnprocessed)\n{\n\tbool next_token = !*tokenUnprocessed;\n\ttokenInfo * name = NULL;\n\tbool eof = false;\n\tbool exclusive = false;\n\n\tfor (struct TexParseStrategy *s = strategy; s->type != 0; ++s)\n\t\ts->corkIndex = CORK_NIL;\n\n\tfor (struct TexParseStrategy *s = strategy; !eof && s->type != 0; ++s)\n\t{\n\t\tif (s->kindIndex != KIND_GHOST_INDEX || s->name)\n\t\t{\n\t\t\tname = newToken ();\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tfor (struct TexParseStrategy *s = strategy; !eof && s->type != 0; ++s)\n\t{\n\t\tbool capture_name = s->kindIndex != KIND_GHOST_INDEX || s->name;\n\n\t\tif (next_token)\n\t\t{\n\t\t\tif (!readToken (token))\n\t\t\t{\n\t\t\t\teof = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif ((s->type == '<' && isType (token, '<'))\n\t\t\t|| (s->type == '[' && isType (token, '[')))\n\t\t{\n\t\t\ttokenType terminator = (s->type == '<') ? '>' : ']';\n\n\t\t\tnext_token = true;\n\n\n\t\t\tif (!readToken (token))\n\t\t\t{\n\t\t\t\teof = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (capture_name)\n\t\t\t{\n\t\t\t\tcopyToken (name, token);\n\t\t\t\tvStringClear (name->string);\n\t\t\t}\n\n\t\t\twhile (! isType (token, terminator))\n\t\t\t{\n\t\t\t\tif (capture_name && isType (token, TOKEN_IDENTIFIER))\n\t\t\t\t\tvStringJoin (name->string, ' ', token->string);\n\n\t\t\t\tif (!readTokenFull (token,\n\t\t\t\t\t\t\t\t\ts->flags & TEX_NAME_FLAG_INCLUDING_WHITESPACE))\n\t\t\t\t{\n\t\t\t\t\teof = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!exclusive && capture_name && vStringLength (name->string) > 0)\n\t\t\t{\n\t\t\t\tif (s->kindIndex != KIND_GHOST_INDEX)\n\t\t\t\t\ts->corkIndex = makeTexTag (name, s->kindIndex, s->roleIndex,\n\t\t\t\t\t\t\t\t\t\t\t   s->unique, s->scopeIndex);\n\n\t\t\t\tif (s->name)\n\t\t\t\t\tvStringCopy(s->name, name->string);\n\n\t\t\t\tif (s->flags & TEX_NAME_FLAG_EXCLUSIVE)\n\t\t\t\t\texclusive = true;\n\t\t\t}\n\t\t}\n\t\telse if (s->type == '*' && isType (token, '*'))\n\t\t\tnext_token = true;\n\t\telse if (((s->type == '{' || s->type == '\\\\') && isType (token, '{')) ||\n\t\t\t(s->type == '\\\\' && isType (token, TOKEN_IDENTIFIER)))\n\t\t{\n\t\t\tint depth = 1;\n\t\t\tbool missing_parens = isType (token, TOKEN_IDENTIFIER);\n\n\t\t\tnext_token = true;\n\n\t\t\tif (!missing_parens && !readToken (token))\n\t\t\t{\n\t\t\t\teof = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (capture_name)\n\t\t\t{\n\t\t\t\tcopyToken (name, token);\n\t\t\t\tvStringClear (name->string);\n\t\t\t}\n\t\t\tif (missing_parens)\n\t\t\t{\n\t\t\t\tvStringCat (name->string, token->string);\n\t\t\t\tdepth = 0;\n\t\t\t}\n\n\t\t\t/* Handle the case the code like \\section{} */\n\t\t\tif (isType (token, '}'))\n\t\t\t\tbreak;\n\t\t\twhile (depth > 0)\n\t\t\t{\n\t\t\t\tif (capture_name)\n\t\t\t\t{\n\t\t\t\t\tif (isType (token, TOKEN_IDENTIFIER) || isType (token, TOKEN_KEYWORD))\n\t\t\t\t\t\tvStringCat (name->string, token->string);\n\t\t\t\t\telse\n\t\t\t\t\t\tvStringPut (name->string, token->type);\n\t\t\t\t}\n\t\t\t\tif (!readTokenFull (token,\n\t\t\t\t\t\t\t\t\ts->flags & TEX_NAME_FLAG_INCLUDING_WHITESPACE))\n\t\t\t\t{\n\t\t\t\t\teof = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if (isType (token, TOKEN_OPEN_CURLY))\n\t\t\t\t\tdepth++;\n\t\t\t\telse if (isType (token, TOKEN_CLOSE_CURLY))\n\t\t\t\t\tdepth--;\n\t\t\t}\n\t\t\tif (!exclusive && depth == 0 && capture_name && vStringLength (name->string) > 0)\n\t\t\t{\n\t\t\t\tvStringStripTrailing (name->string);\n\n\t\t\t\tif (s->kindIndex != KIND_GHOST_INDEX)\n\t\t\t\t\ts->corkIndex = makeTexTag (name, s->kindIndex, s->roleIndex,\n\t\t\t\t\t\t\t\t\t\t\t   s->unique, s->scopeIndex);\n\n\t\t\t\tif (s->name)\n\t\t\t\t\tvStringCopy(s->name, name->string);\n\n\t\t\t\tif (s->flags & TEX_NAME_FLAG_EXCLUSIVE)\n\t\t\t\t\texclusive = true;\n\n\t\t\t}\n\t\t}\n\t\telse if (s->flags & TEX_NAME_FLAG_OPTIONAL)\n\t\t\t/* Apply next strategy to the same token */\n\t\t\tnext_token = false;\n\t\telse\n\t\t{\n\t\t\t*tokenUnprocessed = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* The last token is optional and not present - let the caller know */\n\tif (!next_token)\n\t\t*tokenUnprocessed = true;\n\n\tif (name)\n\t\tdeleteToken (name);\n\n\treturn eof;\n}\n\nstatic bool parseTagFull (tokenInfo *const token, texKind kind, int roleIndex, bool enterSquare, bool *tokenUnprocessed)\n{\n\tbool eof = false;\n\tvString *taggedName = vStringNew();\n\n\t/*\n\t * Tex tags are of these formats:\n\t *   \\keyword{any number of words}\n\t *   \\keyword[short desc]{any number of words}\n\t *   \\keyword*[short desc]{any number of words}\n\t *\n\t * When a keyword is found, loop through all words within\n\t * the curly braces for the tag name.\n\t *\n\t * If the keyword is label like \\label, words in the square\n\t * brackets should be skipped. This can be controlled\n\t * with `enterSquare' parameter; true is for tagging, and\n\t * false is for skipping.\n\t */\n\n\tstruct TexParseStrategy strategy [] = {\n\t\t{\n\t\t\t.type = '[',\n\t\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t\t/* .kindIndex is initialized dynamically. */\n\t\t},\n\t\t{\n\t\t\t.type = '*',\n\t\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = '{',\n\t\t\t.flags = TEX_NAME_FLAG_INCLUDING_WHITESPACE,\n\t\t\t.kindIndex = kind,\n\t\t\t.roleIndex = roleIndex,\n\t\t\t.name = taggedName,\n\t\t\t.unique = false,\n\t\t},\n\t\t{\n\t\t\t.type = 0\n\t\t}\n\t};\n\n\n\tif (enterSquare)\n\t{\n\t\tstrategy [0].kindIndex = kind;\n\t\tstrategy [0].roleIndex = roleIndex;\n\t\tstrategy [0].flags |= TEX_NAME_FLAG_EXCLUSIVE;\n\t\tstrategy [0].name = taggedName;\n\t\tstrategy [0].unique = false;\n\t}\n\telse\n\t{\n\t\tstrategy [0].kindIndex = KIND_GHOST_INDEX;\n\t\tstrategy [0].name = NULL;\n\t}\n\n\tif (parseWithStrategy (token, strategy, tokenUnprocessed))\n\t{\n\t\teof = true;\n\t\tgoto out;\n\t}\n\n\t/*\n\t * save the name of the last section definitions for scope-resolution\n\t * later\n\t */\n\tif (vStringLength (taggedName) > 0)\n\t\tupdateScopeInfo (kind, taggedName);\n\n out:\n\tvStringDelete (taggedName);\n\n\treturn eof;\n}\n\nstatic bool parseTag (tokenInfo *const token, texKind kind,\n\t\t\t\t\t  bool enterSquare, bool *tokenUnprocessed)\n{\n\treturn parseTagFull (token, kind, ROLE_DEFINITION_INDEX,\n\t\t\t\t\t\t enterSquare, tokenUnprocessed);\n}\n\nstatic bool parseEnv (tokenInfo *const token, bool begin, bool *tokenUnprocessed)\n{\n\tbool eof = false;\n\tvString *envName = vStringNew ();\n\tstruct TexParseStrategy strategy [] = {\n\t\t{\n\t\t\t.type = '{',\n\t\t\t.flags = TEX_NAME_FLAG_INCLUDING_WHITESPACE,\n\t\t\t.kindIndex = begin ? TEXTAG_ENVIRONMENT : KIND_GHOST_INDEX,\n\t\t\t.roleIndex = TEX_ENVIRONMENT_USED,\n\t\t\t.name = envName,\n\t\t},\n\t\t{\n\t\t\t.type = 0\n\t\t}\n\t};\n\n\tif (parseWithStrategy (token, strategy, tokenUnprocessed))\n\t{\n\t\teof = true;\n\t\tgoto out;\n\t}\n\n\n\tif (vStringLength (envName) > 0)\n\t{\n\t\tif (begin)\n\t\t\teof = notifyReadingBeginEnvironment (token, envName, tokenUnprocessed);\n\t\telse\n\t\t\teof = notifyReadingEndEnvironment (envName);\n\t}\n\n out:\n\tvStringDelete (envName);\n\n\treturn eof;\n\n}\n\nstatic bool parseNewcommandFull (tokenInfo *const token, bool *tokenUnprocessed, texKind kind)\n{\n\tbool eof = false;\n\n\t/* \\newcommand{cmd}[args][opt]{def} */\n\t/* \\newcommand\\cmd[args][opt]{def} */\n\t/* \\def\\cmd{replacement} */\n\tstruct TexParseStrategy strategy [] = {\n\t\t{\n\t\t\t.type = '\\\\',\n\t\t\t.flags = 0,\n\t\t\t.kindIndex = kind,\n\t\t\t.roleIndex = ROLE_DEFINITION_INDEX,\n\t\t\t.name = NULL,\n\t\t\t.unique = false,\n\t\t},\n\t\t{\n\t\t\t.type = '[',\n\t\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = '[',\n\t\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = '{',\n\t\t\t.flags = 0,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = 0\n\t\t}\n\t};\n\n\tif (parseWithStrategy (token, strategy, tokenUnprocessed))\n\t\teof = true;\n\n\treturn eof;\n}\n\nstatic bool parseNewcommand (tokenInfo *const token, bool *tokenUnprocessed)\n{\n\treturn parseNewcommandFull (token, tokenUnprocessed, TEXTAG_COMMAND);\n}\n\nstatic bool parseNewEnvironment (tokenInfo *const token, bool *tokenUnprocessed)\n{\n\tbool eof = false;\n\t/* \\newenvironment{nam}[args]{begdef}{enddef} */\n\tstruct TexParseStrategy strategy [] = {\n\t\t{\n\t\t\t.type = '{',\n\t\t\t.flags = 0,\n\t\t\t.kindIndex = TEXTAG_ENVIRONMENT,\n\t\t\t.roleIndex = ROLE_DEFINITION_INDEX,\n\t\t\t.name = NULL,\n\t\t\t.unique = false,\n\t\t},\n\t\t{\n\t\t\t.type = '[',\n\t\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = '{',\n\t\t\t.flags = 0,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = '{',\n\t\t\t.flags = 0,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = 0\n\t\t}\n\t};\n\n\tif (parseWithStrategy (token, strategy, tokenUnprocessed))\n\t\teof = true;\n\n\treturn eof;\n}\n\nstatic bool parseNewTheorem (tokenInfo *const token, bool *tokenUnprocessed)\n{\n\tbool eof = false;\n\t/*\t\\newtheorem{name}{title}\n\t\t\\newtheorem{name}{title}[numbered_within]\n\t\t\\newtheorem{name}[numbered_like]{title} */\n\tstruct TexParseStrategy strategy [] = {\n\t\t{\n\t\t\t.type = '{',\n\t\t\t.flags = 0,\n\t\t\t.kindIndex = TEXTAG_THEOREM,\n\t\t\t.roleIndex = ROLE_DEFINITION_INDEX,\n\t\t\t.name = NULL,\n\t\t\t.unique = false,\n\t\t},\n\t\t{\n\t\t\t.type = '[',\n\t\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = '{',\n\t\t\t.flags = 0,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = '[',\n\t\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = 0\n\t\t}\n\t};\n\n\tif (parseWithStrategy (token, strategy, tokenUnprocessed))\n\t\teof = true;\n\n\treturn eof;\n}\n\nstatic bool parseNewcounter (tokenInfo *const token, bool *tokenUnprocessed)\n{\n\tbool eof = false;\n\t/* \\newcounter {counter}[parentCounter] */\n\tstruct TexParseStrategy strategy [] = {\n\t\t{\n\t\t\t.type = '{',\n\t\t\t.flags = 0,\n\t\t\t.kindIndex = TEXTAG_COUNTER,\n\t\t\t.roleIndex = ROLE_DEFINITION_INDEX,\n\t\t\t.name = NULL,\n\t\t\t.unique = false,\n\t\t},\n\t\t{\n\t\t\t.type = '[',\n\t\t\t.flags = TEX_NAME_FLAG_OPTIONAL,\n\t\t\t.kindIndex = KIND_GHOST_INDEX,\n\t\t\t.name = NULL,\n\t\t},\n\t\t{\n\t\t\t.type = 0\n\t\t}\n\t};\n\n\tif (parseWithStrategy (token, strategy, tokenUnprocessed))\n\t\teof = true;\n\n\treturn eof;\n}\n\nstatic void parseTexFile (tokenInfo *const token)\n{\n\tbool eof = false;\n\tbool tokenUnprocessed = false;\n\n\tdo\n\t{\n\t\tif (!tokenUnprocessed)\n\t\t{\n\t\t\tif (!readToken (token))\n\t\t\t\tbreak;\n\t\t}\n\t\ttokenUnprocessed = false;\n\n\t\tif (isType (token, TOKEN_KEYWORD))\n\t\t{\n\t\t\tswitch (token->keyword)\n\t\t\t{\n\t\t\t\tcase KEYWORD_part:\n\t\t\t\t\teof = parseTag (token, TEXTAG_PART, true, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_chapter:\n\t\t\t\t\teof = parseTag (token, TEXTAG_CHAPTER, true, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_section:\n\t\t\t\t\teof = parseTag (token, TEXTAG_SECTION, true, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_subsection:\n\t\t\t\t\teof = parseTag (token, TEXTAG_SUBSECTION, true, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_subsubsection:\n\t\t\t\t\teof = parseTag (token, TEXTAG_SUBSUBSECTION, true, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_paragraph:\n\t\t\t\t\teof = parseTag (token, TEXTAG_PARAGRAPH, true, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_subparagraph:\n\t\t\t\t\teof = parseTag (token, TEXTAG_SUBPARAGRAPH, true, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_label:\n\t\t\t\t\teof = parseTag (token, TEXTAG_LABEL, false, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_include:\n\t\t\t\t\teof = parseTagFull (token, TEXTAG_XINPUT, TEX_XINPUT_INCLUDED,\n\t\t\t\t\t\t\t\t\t\tfalse, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_input:\n\t\t\t\t\teof = parseTagFull (token, TEXTAG_XINPUT, TEX_XINPUT_INPUT,\n\t\t\t\t\t\t\t\t\t\tfalse, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_begin:\n\t\t\t\t\teof = parseEnv (token, true, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_end:\n\t\t\t\t\teof = parseEnv (token, false, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_bibitem:\n\t\t\t\t\teof = parseTag (token, TEXTAG_BIBITEM, false, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_bibliography:\n\t\t\t\t\teof = parseTagFull (token, TEXTAG_XINPUT, TEX_XINPUT_BIBLIOGRAPHY,\n\t\t\t\t\t\t\t\t\t\tfalse, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_newcommand:\n\t\t\t\tcase KEYWORD_renewcommand:\n\t\t\t\tcase KEYWORD_providecommand:\n\t\t\t\tcase KEYWORD_def:\n\t\t\t\t\teof = parseNewcommand (token, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_declaremathoperator:\n\t\t\t\t\teof = parseNewcommandFull (token, &tokenUnprocessed, TEXTAG_OPERATOR);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_newenvironment:\n\t\t\t\tcase KEYWORD_renewenvironment:\n\t\t\t\t\teof = parseNewEnvironment (token, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_newtheorem:\n\t\t\t\t\teof = parseNewTheorem (token, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KEYWORD_newcounter:\n\t\t\t\t\teof = parseNewcounter (token, &tokenUnprocessed);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_IDENTIFIER))\n\t\t\teof = notifyReadingIdentifier (token, &tokenUnprocessed);\n\t\tif (eof)\n\t\t\tbreak;\n\t} while (true);\n}\n\nstatic void initialize (const langType language)\n{\n\tAssert (ARRAY_SIZE (TexKinds) == TEXTAG_COUNT);\n\tLang_tex = language;\n\n\tlastPart    = vStringNew();\n\tlastChapter = vStringNew();\n\tlastSection = vStringNew();\n\tlastSubS    = vStringNew();\n\tlastSubSubS = vStringNew();\n}\n\nstatic void finalize (const langType language CTAGS_ATTR_UNUSED,\n\t\t      bool initialized)\n{\n\tif (initialized)\n\t{\n\t\tvStringDelete(lastPart);\n\t\tlastPart = NULL;\n\t\tvStringDelete(lastChapter);\n\t\tlastChapter = NULL;\n\t\tvStringDelete(lastSection);\n\t\tlastSection = NULL;\n\t\tvStringDelete(lastSubS);\n\t\tlastSubS = NULL;\n\t\tvStringDelete(lastSubSubS);\n\t\tlastSubSubS = NULL;\n\t}\n}\n\nstatic void findTexTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\tvStringClear(lastPart);\n\tvStringClear(lastChapter);\n\tvStringClear(lastSection);\n\tvStringClear(lastSubS);\n\tvStringClear(lastSubSubS);\n\n\tparseTexFile (token);\n\n\tdeleteToken (token);\n}\n\nstatic bool notifyReadingIdentifier (tokenInfo *id_token, bool *tokenUnprocessed)\n{\n\tsubparser *sub;\n\tbool eof = false;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\ttexSubparser *texsub = (texSubparser *)sub;\n\n\t\tif (texsub->readIdentifierNotify)\n\t\t{\n\t\t\tstruct TexParseStrategy *strategy;\n\n\t\t\tenterSubparser(sub);\n\n\t\t\tstrategy = texsub->readIdentifierNotify (texsub, id_token->string);\n\n\t\t\tif (strategy)\n\t\t\t{\n\t\t\t\teof = parseWithStrategy (id_token, strategy, tokenUnprocessed);\n\t\t\t\tif (texsub->reportStrategicParsing)\n\t\t\t\t\ttexsub->reportStrategicParsing (texsub, strategy);\n\t\t\t}\n\n\t\t\tleaveSubparser();\n\n\t\t\tif (strategy)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn eof;\n}\n\nstatic bool notifyReadingBeginEnvironment (tokenInfo *token,\n\t\t\t\t\t\t\t\t\t\t   vString *envName,\n\t\t\t\t\t\t\t\t\t\t   bool *tokenUnprocessed)\n{\n\tsubparser *sub;\n\tbool eof = false;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\ttexSubparser *texsub = (texSubparser *)sub;\n\n\t\tif (texsub->readEnviromentBeginNotify)\n\t\t{\n\t\t\tstruct TexParseStrategy *strategy;\n\n\t\t\tenterSubparser (sub);\n\t\t\tstrategy = texsub->readEnviromentBeginNotify (texsub, envName);\n\t\t\tif (strategy)\n\t\t\t{\n\t\t\t\teof = parseWithStrategy (token, strategy, tokenUnprocessed);\n\t\t\t\tif (texsub->reportStrategicParsing)\n\t\t\t\t\ttexsub->reportStrategicParsing (texsub, strategy);\n\t\t\t}\n\t\t\tleaveSubparser ();\n\t\t\tif (strategy)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn eof;\n}\n\nstatic bool notifyReadingEndEnvironment (vString  *envName)\n{\n\tsubparser *sub;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\ttexSubparser *texsub = (texSubparser *)sub;\n\n\t\tif (texsub->readEnviromentEndNotify)\n\t\t{\n\t\t\tbool consuming;\n\n\t\t\tenterSubparser (sub);\n\t\t\tconsuming = texsub->readEnviromentEndNotify (texsub, envName);\n\t\t\tleaveSubparser ();\n\t\t\tif (consuming)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/* Create parser definition structure */\nextern parserDefinition* TexParser (void)\n{\n\tstatic const char *const extensions [] = { \"tex\", NULL };\n\tparserDefinition *const def = parserNew (\"Tex\");\n\tdef->extensions = extensions;\n\t/*\n\t * New definitions for parsing instead of regex\n\t */\n\tdef->kindTable\t= TexKinds;\n\tdef->kindCount\t= ARRAY_SIZE (TexKinds);\n\tdef->parser\t\t= findTexTags;\n\tdef->initialize = initialize;\n\tdef->finalize   = finalize;\n\tdef->keywordTable =  TexKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (TexKeywordTable);\n\tdef->useCork = CORK_QUEUE  | CORK_SYMTAB;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/ttcn.c",
    "content": "/*\n*   Copyright (c) 2009, Dmitry Peskov (dmitrypeskov@users.sourceforge.net)\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   File: ttcn.c\n*   Description: Adds TTCN-3 support to Exuberant ctags\n*   Version: 0.4\n*   Author: Dmitry Peskov (dmitrypeskov@users.sourceforge.net)\n*   Based on ETSI ES 201 873-1 V3.4.1 appendix A\n*   Version history:\n*   0.1     Initial version\n*   0.2     Enhancement: faster binary search in keyword list\n*           Fix: skip tag generation from import definitions (import/except lists)\n*   0.3     Fix: expression parser no longer relies on optional semicolon\n*           after a const/var/timer/modulepar definition to find where the initializer\n*           actually ends\n*           Fix: handle multiple module parameters not separated by semicolons\n*   0.31    Fix: lexer bug, missing character after a charstring close-quote\n*   0.4     Enhancement: tags for record/set/union members, enum values, port instances\n*           within components\n*/\n\n/* INCLUDE FILES */\n\n#include \"general.h\"    /* always include first */\n#include <stdlib.h>\n#include <string.h>     /* to declare strxxx() functions */\n#include <ctype.h>      /* to define isxxx() macros */\n#include \"parse.h\"      /* always include */\n#include \"read.h\"       /* to define file fileReadLine() */\n#include \"routines.h\"\n#include \"debug.h\"\n\n/*    DATA    */\n\n/* Tag kinds generated by parser */\ntypedef enum {\n\tK_MODULE,\n\tK_TYPE,\n\tK_CONST,\n\tK_TEMPLATE,\n\tK_FUNCTION,\n\tK_SIGNATURE,\n\tK_TESTCASE,\n\tK_ALTSTEP,\n\tK_GROUP,\n\tK_MODULEPAR,\n\tK_VAR,\n\tK_TIMER,\n\tK_PORT,\n\tK_MEMBER,\n\tK_ENUM,\n\tK_NONE  /* No tag */\n} ttcnKind_t;\n\nstatic kindDefinition ttcnKinds [] = {\n\t{ true, 'M', \"module\",    \"module definition\" },\n\t{ true, 't', \"type\",      \"type definition\" },\n\t{ true, 'c', \"const\",     \"constant definition\" },\n\t{ true, 'd', \"template\",  \"template definition\" },\n\t{ true, 'f', \"function\",  \"function definition\" },\n\t{ true, 's', \"signature\", \"signature definition\" },\n\t{ true, 'C', \"testcase\",  \"testcase definition\" },\n\t{ true, 'a', \"altstep\",   \"altstep definition\" },\n\t{ true, 'G', \"group\",     \"group definition\" },\n\t{ true, 'P', \"modulepar\", \"module parameter definition\" },\n\t{ true, 'v', \"var\",       \"variable instance\" },\n\t{ true, 'T', \"timer\",     \"timer instance\" },\n\t{ true, 'p', \"port\",      \"port instance\" },\n\t{ true, 'm', \"member\",    \"record/set/union member\" },\n\t{ true, 'e', \"enum\",      \"enumeration value\" }\n};\n\n/* TTCN token types */\ntypedef enum {\n\t/* Values up to 255 are reserved for single-char tokens: '+', '-', etc. */\n\tT_ID = 256,   /* Identifier */\n\tT_LITERAL,    /* Literal: integer, real, (char|hex|octet|bit)string */\n\t/* Keywords */\n\tT_ACTION, T_ACTIVATE, T_ADDRESS, T_ALIVE, T_ALL, T_ALT, T_ALTSTEP, T_AND,\n\tT_AND4B, T_ANY, T_ANYTYPE, T_BITSTRING, T_BOOLEAN, T_CASE, T_CALL, T_CATCH,\n\tT_CHAR, T_CHARSTRING, T_CHECK, T_CLEAR, T_COMPLEMENT, T_COMPONENT,\n\tT_CONNECT, T_CONST, T_CONTROL, T_CREATE, T_DEACTIVATE, T_DEFAULT,\n\tT_DISCONNECT, T_DISPLAY, T_DO, T_DONE, T_ELSE, T_ENCODE, T_ENUMERATED,\n\tT_ERROR, T_EXCEPT, T_EXCEPTION, T_EXECUTE, T_EXTENDS, T_EXTENSION,\n\tT_EXTERNAL, T_FAIL, T_FALSE, T_FLOAT, T_FOR, T_FROM, T_FUNCTION,\n\tT_GETVERDICT, T_GETCALL, T_GETREPLY, T_GOTO, T_GROUP, T_HEXSTRING, T_IF,\n\tT_IFPRESENT, T_IMPORT, T_IN, T_INCONC, T_INFINITY, T_INOUT, T_INTEGER,\n\tT_INTERLEAVE, T_KILL, T_KILLED,    T_LABEL, T_LANGUAGE, T_LENGTH, T_LOG, T_MAP,\n\tT_MATCH, T_MESSAGE, T_MIXED, T_MOD, T_MODIFIES, T_MODULE, T_MODULEPAR,\n\tT_MTC, T_NOBLOCK, T_NONE, T_NOT, T_NOT4B, T_NOWAIT, T_NULL, T_OCTETSTRING,\n\tT_OF, T_OMIT, T_ON, T_OPTIONAL, T_OR, T_OR4B, T_OUT, T_OVERRIDE, T_PARAM,\n\tT_PASS, T_PATTERN, T_PORT, T_PROCEDURE, T_RAISE, T_READ, T_RECEIVE,\n\tT_RECORD, T_RECURSIVE, T_REM, T_REPEAT, T_REPLY, T_RETURN, T_RUNNING,\n\tT_RUNS,    T_SELECT, T_SELF, T_SEND, T_SENDER, T_SET, T_SETVERDICT,\n\tT_SIGNATURE, T_START, T_STOP, T_SUBSET, T_SUPERSET, T_SYSTEM, T_TEMPLATE,\n\tT_TESTCASE, T_TIMEOUT, T_TIMER, T_TO, T_TRIGGER, T_TRUE, T_TYPE, T_UNION,\n\tT_UNIVERSAL, T_UNMAP, T_VALUE, T_VALUEOF, T_VAR, T_VARIANT, T_VERDICTTYPE,\n\tT_WHILE, T_WITH, T_XOR, T_XOR4B,\n\t/* Double-char operators (single-char operators are returned \"as is\") */\n\tT_OP_TO /* .. */, T_OP_EQ /* == */, T_OP_NE /* != */,\n\tT_OP_LE /* <= */, T_OP_GE /* >= */,    T_OP_ASS /* := */, T_OP_ARROW /* -> */,\n\tT_OP_SHL /* << */, T_OP_SHR /* >> */, T_OP_ROTL /* <@ */, T_OP_ROTR /* @> */\n} ttcnTokenType_t;\n\n/* TTCN keywords. List MUST be sorted in alphabetic order!!! */\nstatic struct s_ttcnKeyword {\n\tconst ttcnTokenType_t id;\n\tconst char * name;\n\tconst ttcnKind_t kind;  /* Corresponding tag kind, K_NONE if none */\n} ttcnKeywords [] = {\n\t{T_ACTION,      \"action\",       K_NONE},\n\t{T_ACTIVATE,    \"activate\",     K_NONE},\n\t{T_ADDRESS,     \"address\",      K_NONE},\n\t{T_ALIVE,       \"alive\",        K_NONE},\n\t{T_ALL,         \"all\",          K_NONE},\n\t{T_ALT,         \"alt\",          K_NONE},\n\t{T_ALTSTEP,     \"altstep\",      K_ALTSTEP},\n\t{T_AND,         \"and\",          K_NONE},\n\t{T_AND4B,       \"and4b\",        K_NONE},\n\t{T_ANY,         \"any\",          K_NONE},\n\t{T_ANYTYPE,     \"anytype\",      K_NONE},\n\t{T_BITSTRING,   \"bitstring\",    K_NONE},\n\t{T_BOOLEAN,     \"boolean\",      K_NONE},\n\t{T_CASE,        \"case\",         K_NONE},\n\t{T_CALL,        \"call\",         K_NONE},\n\t{T_CATCH,       \"catch\",        K_NONE},\n\t{T_CHAR,        \"char\",         K_NONE},\n\t{T_CHARSTRING,  \"charstring\",   K_NONE},\n\t{T_CHECK,       \"check\",        K_NONE},\n\t{T_CLEAR,       \"clear\",        K_NONE},\n\t{T_COMPLEMENT,  \"complement\",   K_NONE},\n\t{T_COMPONENT,   \"component\",    K_NONE},\n\t{T_CONNECT,     \"connect\",      K_NONE},\n\t{T_CONST,       \"const\",        K_CONST},\n\t{T_CONTROL,     \"control\",      K_NONE},\n\t{T_CREATE,      \"create\",       K_NONE},\n\t{T_DEACTIVATE,  \"deactivate\",   K_NONE},\n\t{T_DEFAULT,     \"default\",      K_NONE},\n\t{T_DISCONNECT,  \"disconnect\",   K_NONE},\n\t{T_DISPLAY,     \"display\",      K_NONE},\n\t{T_DO,          \"do\",           K_NONE},\n\t{T_DONE,        \"done\",         K_NONE},\n\t{T_ELSE,        \"else\",         K_NONE},\n\t{T_ENCODE,      \"encode\",       K_NONE},\n\t{T_ENUMERATED,  \"enumerated\",   K_NONE},\n\t{T_ERROR,       \"error\",        K_NONE},\n\t{T_EXCEPT,      \"except\",       K_NONE},\n\t{T_EXCEPTION,   \"exception\",    K_NONE},\n\t{T_EXECUTE,     \"execute\",      K_NONE},\n\t{T_EXTENDS,     \"extends\",      K_NONE},\n\t{T_EXTENSION,   \"extension\",    K_NONE},\n\t{T_EXTERNAL,    \"external\",     K_NONE},\n\t{T_FAIL,        \"fail\",         K_NONE},\n\t{T_FALSE,       \"false\",        K_NONE},\n\t{T_FLOAT,       \"float\",        K_NONE},\n\t{T_FOR,         \"for\",          K_NONE},\n\t{T_FROM,        \"from\",         K_NONE},\n\t{T_FUNCTION,    \"function\",     K_FUNCTION},\n\t{T_GETVERDICT,  \"getverdict\",   K_NONE},\n\t{T_GETCALL,     \"getcall\",      K_NONE},\n\t{T_GETREPLY,    \"getreply\",     K_NONE},\n\t{T_GOTO,        \"goto\",         K_NONE},\n\t{T_GROUP,       \"group\",        K_GROUP},\n\t{T_HEXSTRING,   \"hexstring\",    K_NONE},\n\t{T_IF,          \"if\",           K_NONE},\n\t{T_IFPRESENT,   \"ifpresent\",    K_NONE},\n\t{T_IMPORT,      \"import\",       K_NONE},\n\t{T_IN,          \"in\",           K_NONE},\n\t{T_INCONC,      \"inconc\",       K_NONE},\n\t{T_INFINITY,    \"infinity\",     K_NONE},\n\t{T_INOUT,       \"inout\",        K_NONE},\n\t{T_INTEGER,     \"integer\",      K_NONE},\n\t{T_INTERLEAVE,  \"interleave\",   K_NONE},\n\t{T_KILL,        \"kill\",         K_NONE},\n\t{T_KILLED,      \"killed\",       K_NONE},\n\t{T_LABEL,       \"label\",        K_NONE},\n\t{T_LANGUAGE,    \"language\",     K_NONE},\n\t{T_LENGTH,      \"length\",       K_NONE},\n\t{T_LOG,         \"log\",          K_NONE},\n\t{T_MAP,         \"map\",          K_NONE},\n\t{T_MATCH,       \"match\",        K_NONE},\n\t{T_MESSAGE,     \"message\",      K_NONE},\n\t{T_MIXED,       \"mixed\",        K_NONE},\n\t{T_MOD,         \"mod\",          K_NONE},\n\t{T_MODIFIES,    \"modifies\",     K_NONE},\n\t{T_MODULE,      \"module\",       K_MODULE},\n\t{T_MODULEPAR,   \"modulepar\",    K_MODULEPAR},\n\t{T_MTC,         \"mtc\",          K_NONE},\n\t{T_NOBLOCK,     \"noblock\",      K_NONE},\n\t{T_NONE,        \"none\",         K_NONE},\n\t{T_NOT,         \"not\",          K_NONE},\n\t{T_NOT4B,       \"not4b\",        K_NONE},\n\t{T_NOWAIT,      \"nowait\",       K_NONE},\n\t{T_NULL,        \"null\",         K_NONE},\n\t{T_OCTETSTRING, \"octetstring\",  K_NONE},\n\t{T_OF,          \"of\",           K_NONE},\n\t{T_OMIT,        \"omit\",         K_NONE},\n\t{T_ON,          \"on\",           K_NONE},\n\t{T_OPTIONAL,    \"optional\",     K_NONE},\n\t{T_OR,          \"or\",           K_NONE},\n\t{T_OR4B,        \"or4b\",         K_NONE},\n\t{T_OUT,         \"out\",          K_NONE},\n\t{T_OVERRIDE,    \"override\",     K_NONE},\n\t{T_PARAM,       \"param\",        K_NONE},\n\t{T_PASS,        \"pass\",         K_NONE},\n\t{T_PATTERN,     \"pattern\",      K_NONE},\n\t{T_PORT,        \"port\",         K_PORT},\n\t{T_PROCEDURE,   \"procedure\",    K_NONE},\n\t{T_RAISE,       \"raise\",        K_NONE},\n\t{T_READ,        \"read\",         K_NONE},\n\t{T_RECEIVE,     \"receive\",      K_NONE},\n\t{T_RECORD,      \"record\",       K_NONE},\n\t{T_RECURSIVE,   \"recursive\",    K_NONE},\n\t{T_REM,         \"rem\",          K_NONE},\n\t{T_REPEAT,      \"repeat\",       K_NONE},\n\t{T_REPLY,       \"reply\",        K_NONE},\n\t{T_RETURN,      \"return\",       K_NONE},\n\t{T_RUNNING,     \"running\",      K_NONE},\n\t{T_RUNS,        \"runs\",         K_NONE},\n\t{T_SELECT,      \"select\",       K_NONE},\n\t{T_SELF,        \"self\",         K_NONE},\n\t{T_SEND,        \"send\",         K_NONE},\n\t{T_SENDER,      \"sender\",       K_NONE},\n\t{T_SET,         \"set\",          K_NONE},\n\t{T_SETVERDICT,  \"setverdict\",   K_NONE},\n\t{T_SIGNATURE,   \"signature\",    K_SIGNATURE},\n\t{T_START,       \"start\",        K_NONE},\n\t{T_STOP,        \"stop\",         K_NONE},\n\t{T_SUBSET,      \"subset\",       K_NONE},\n\t{T_SUPERSET,    \"superset\",     K_NONE},\n\t{T_SYSTEM,      \"system\",       K_NONE},\n\t{T_TEMPLATE,    \"template\",     K_TEMPLATE},\n\t{T_TESTCASE,    \"testcase\",     K_TESTCASE},\n\t{T_TIMEOUT,     \"timeout\",      K_NONE},\n\t{T_TIMER,       \"timer\",        K_TIMER},\n\t{T_TO,          \"to\",           K_NONE},\n\t{T_TRIGGER,     \"trigger\",      K_NONE},\n\t{T_TRUE,        \"true\",         K_NONE},\n\t{T_TYPE,        \"type\",         K_TYPE},\n\t{T_UNION,       \"union\",        K_NONE},\n\t{T_UNIVERSAL,   \"universal\",    K_NONE},\n\t{T_UNMAP,       \"unmap\",        K_NONE},\n\t{T_VALUE,       \"value\",        K_NONE},\n\t{T_VALUEOF,     \"valueof\",      K_NONE},\n\t{T_VAR,         \"var\",          K_VAR},\n\t{T_VARIANT,     \"variant\",      K_NONE},\n\t{T_VERDICTTYPE, \"verdicttype\",  K_NONE},\n\t{T_WHILE,       \"while\",        K_NONE},\n\t{T_WITH,        \"with\",         K_NONE},\n\t{T_XOR,         \"xor\",          K_NONE},\n\t{T_XOR4B,       \"xor4b\",        K_NONE}\n};\nstatic const int ttcnKeywordCount = ARRAY_SIZE(ttcnKeywords);\n\n/* TTCN double-char operators */\nstatic struct s_ttcnOp {\n\tconst ttcnTokenType_t id;\n\tconst char name[3];\n} ttcnOps [] = {\n\t{T_OP_TO,       \"..\"},\n\t{T_OP_EQ,       \"==\"},\n\t{T_OP_NE,       \"!=\"},\n\t{T_OP_LE,       \"<=\"},\n\t{T_OP_GE,       \">=\"},\n\t{T_OP_ASS,      \":=\"},\n\t{T_OP_ARROW,    \"->\"},\n\t{T_OP_SHL,      \"<<\"},\n\t{T_OP_SHR,      \">>\"},\n\t{T_OP_ROTL,     \"<@\"},\n\t{T_OP_ROTR,     \"@>\"}\n};\nstatic const int ttcnOpCount = ARRAY_SIZE(ttcnOps);\n\n/* Token */\ntypedef struct s_ttcnToken {\n\tttcnTokenType_t type;\n\tvString * value;    /* Semantic value (T_ID and T_LITERAL only) */\n\tttcnKind_t kind;    /* Corresponding tag kind (keywords only) */\n} ttcnToken_t;\n\n/*    LEXER    */\n\n/* Functions forward declarations */\nstatic void findTTCNKeyword(ttcnToken_t * pTok);\nstatic void freeToken(ttcnToken_t * pTok);\nstatic int getNonWhiteSpaceChar (void);\nstatic ttcnToken_t * getToken (void);\nstatic void ungetToken (void);\n\nstatic int ttcnKeywordsCompare (const void * key, const void * member)\n{\n\treturn strcmp(key, ((struct s_ttcnKeyword *)member)->name);\n}\n\n/* Check if token is a TTCN-3 keyword or not */\nstatic void findTTCNKeyword(ttcnToken_t * pTok)\n{\n\tstruct s_ttcnKeyword * k;\n\tif (!pTok || !(pTok->value) || !(vStringValue(pTok->value)))\n\t\treturn;\n\t/* Binary search */\n\tk = bsearch (vStringValue (pTok->value), ttcnKeywords,\n\t\t ttcnKeywordCount, sizeof (*ttcnKeywords),\n\t\t ttcnKeywordsCompare);\n\tif (k)\n\t{\n\t\tpTok->type = k->id;\n\t\tpTok->kind = k->kind;\n\t}\n\telse\n\t{\n\t\tpTok->type = T_ID;\n\t}\n}\n\nstatic ttcnToken_t * pTtcnToken = NULL;\nstatic int repeatLastToken = false;\n\nstatic void freeToken(ttcnToken_t * pTok)\n{\n\tif (pTok)\n\t{\n\t\tif (pTok->value)\n\t\t\tvStringDelete(pTok->value);\n\t\teFree (pTok);\n\t}\n}\n\n/* This function skips all whitespace and comments */\nstatic int getNonWhiteSpaceChar (void)\n{\n\tint c, c2;\n\twhile (1)\n\t{\n\t\t/* Skip whitespace */\n\t\twhile (isspace(c = getcFromInputFile()) && (c != EOF));\n\t\t/* Skip C/C++-style comment */\n\t\tif (c=='/')\n\t\t{\n\t\t\tc2 = getcFromInputFile();\n\t\t\tif (c2=='/')\n\t\t\t{\n\t\t\t\t/* Line comment */\n\t\t\t\twhile (((c = getcFromInputFile()) != EOF) && (c != '\\n'));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse if (c2=='*')\n\t\t\t{\n\t\t\t\t/* Block comment */\n\t\t\t\twhile ((c = getcFromInputFile()) != EOF)\n\t\t\t\t{\n\t\t\t\t\tif (c=='*')\n\t\t\t\t\t{\n\t\t\t\t\t\tc2 = getcFromInputFile();\n\t\t\t\t\t\tif (c2 == '/')\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tungetcToInputFile(c2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t/* Not a comment */\n\t\t\t\tungetcToInputFile(c2);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\tAssert (c == EOF || !isspace(c));\n\treturn c;\n}\n\nstatic ttcnToken_t * getToken (void)\n{\n\tint c, c2;\n\tint i;\n\tif (repeatLastToken)\n\t{\n\t\t/* If ungetToken() has been called before, return last token again */\n\t\trepeatLastToken = false;\n\t\treturn pTtcnToken;\n\t}\n\telse\n\t{\n\t\t/* Clean up last token */\n\t\tfreeToken(pTtcnToken);\n\t\tpTtcnToken = NULL;\n\t}\n\t/* Handle EOF and malloc errors */\n\tif ((c = getNonWhiteSpaceChar()) == EOF)\n\t\treturn NULL;\n\n\tpTtcnToken = xMalloc (1, ttcnToken_t);\n\tpTtcnToken->type = 0;\n\tpTtcnToken->value = NULL;\n\tpTtcnToken->kind = K_NONE;\n\n\t/* Parse tokens */\n\tif (isalpha(c))\n\t{\n\t\t/* Identifier or keyword */\n\t\tpTtcnToken->value = vStringNew();\n\t\tdo\n\t\t{\n\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t\tc = getcFromInputFile();\n\t\t} while (isalnum(c) || c == '_');\n\t\t/* Push back last char */\n\t\tungetcToInputFile(c);\n\t\t/* Is it a keyword or an identifier? */\n\t\tfindTTCNKeyword(pTtcnToken);\n\t}\n\telse if (c == '\\'')\n\t{\n\t\t/* Octetstring, bitstring, hexstring */\n\t\tpTtcnToken->type = T_LITERAL;\n\t\tpTtcnToken->value = vStringNew();\n\t\tvStringPut(pTtcnToken->value, c);\n\t\t/* Hex digits only (NB: 0/1 only in case of bitstring) */\n\t\twhile (isxdigit(c = getcFromInputFile()))\n\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t/* Must be terminated with \"'O\", \"'B\" or \"'H\" */\n\t\tif (c != '\\'')\n\t\t\tpTtcnToken->type = 0;\n\t\telse\n\t\t{\n\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t\tc = getcFromInputFile();\n\t\t\tif ((c != 'O') && (c != 'H') && (c != 'B'))\n\t\t\t\tpTtcnToken->type = 0;\n\t\t\telse\n\t\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t}\n\t}\n\telse if (c == '\"')\n\t{\n\t\t/* Charstring */\n\t\tpTtcnToken->type = T_LITERAL;\n\t\tpTtcnToken->value = vStringNew();\n        vStringPut(pTtcnToken->value, c);\n\t\twhile((c = getcFromInputFile()) != EOF)\n\t\t{\n\t\t\tvStringPut(pTtcnToken->value, c);\n            /* consume escaped characters */\n            if(c == '\\\\' && ((c2 = getcFromInputFile()) != EOF))\n            {\n                vStringPut(pTtcnToken->value, c2);\n                continue;\n            }\n            /* Double '\"' represents '\"' within a Charstring literal */\n\t\t\tif (c == '\"')\n\t\t\t{\n\t\t\t\tc2 = getcFromInputFile();\n                /* consume \"\" */\n\t\t\t\tif (c2 == '\"')\n                {\n                    vStringPut(pTtcnToken->value, c2);\n                    continue;\n                }\n                /* c is \" that close string, c2 is out of string */\n                if(c2 != EOF)\n                    ungetcToInputFile(c2);\n                break;\n\t\t\t}\n\t\t}\n\t\tif (c != '\"')\n\t\t\tpTtcnToken->type = 0;\n\t}\n\telse if (isdigit(c))\n\t{\n\t\t/* Number */\n\t\tpTtcnToken->type = T_LITERAL;\n\t\tpTtcnToken->value = vStringNew();\n\t\t/* Integer part */\n\t\tdo\n\t\t\tvStringPut(pTtcnToken->value, c);\n\t\twhile (isdigit(c = getcFromInputFile()));\n\t\t/* Decimal dot */\n\t\tif (c == '.')\n\t\t{\n\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t\t/* Fractional part */\n\t\t\twhile (isdigit(c = getcFromInputFile()))\n\t\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t}\n\t\t/* Exponent */\n\t\tif ((c == 'E') || (c == 'e'))\n\t\t{\n\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t\t/* Exponent sign */\n\t\t\tif ((c = getcFromInputFile()) == '-')\n\t\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t\telse\n\t\t\t\tungetcToInputFile(c);\n\t\t\t/* Exponent integer part */\n\t\t\twhile (isdigit(c = getcFromInputFile()))\n\t\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t\t/* Exponent decimal dot */\n\t\t\tif (c == '.')\n\t\t\t{\n\t\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t\t\t/* Exponent fractional part */\n\t\t\t\twhile (isdigit(c = getcFromInputFile()))\n\t\t\t\t\tvStringPut(pTtcnToken->value, c);\n\t\t\t}\n\t\t}\n\t\t/* Push back last char */\n\t\tungetcToInputFile(c);\n\t}\n\telse\n\t{\n\t\t/* Operator, 1 or 2 chars, need to look 1 char ahead */\n\t\tc2 = getcFromInputFile();\n\t\tfor (i = 0; i<ttcnOpCount; i++)\n\t\t{\n\t\t\tif ((c == ttcnOps[i].name[0]) && (c2 == ttcnOps[i].name[1]))\n\t\t\t{\n\t\t\t\tpTtcnToken->type = ttcnOps[i].id;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (i == ttcnOpCount)\n\t\t{\n\t\t\t/* No double-char operator found => single-char operator */\n\t\t\tpTtcnToken->type = c;\n\t\t\t/* Push back the second char */\n\t\t\tungetcToInputFile(c2);\n\t\t}\n\t}\n\t/* Only identifier and literal tokens have a value */\n\tif ((pTtcnToken->type != T_ID) && (pTtcnToken->type != T_LITERAL))\n\t{\n\t\tvStringDelete(pTtcnToken->value);\n\t\tpTtcnToken->value = NULL;\n\t}\n\treturn pTtcnToken;\n}\n\nstatic void ungetToken (void) { repeatLastToken = true; }\n\n/*    PARSER    */\n\n/* Functions forward declarations */\nstatic ttcnToken_t * matchToken (ttcnTokenType_t toktype);\nstatic int matchBrackets (const char * br);\nstatic int matchExprOperator (void);\nstatic int parseExprOperand (void);\nstatic int parseSimpleExpression(void);\nstatic int parseID (ttcnKind_t kind);\nstatic int parseStringLength (void);\nstatic int parseExtendedFieldReference (void);\nstatic int parseArrayDef (void);\nstatic int parseInitializer (void);\nstatic int parseNameInitList (ttcnKind_t kind);\nstatic int parseType (void);\nstatic int parseSignature (void);\nstatic int parseStructure (void);\nstatic int parseEnumeration(void);\nstatic int parseNestedTypeDef (void);\nstatic int parseTypeDefBody (void);\nstatic void parseTTCN (void);\n\n/* Check if next token is of a specified type */\nstatic ttcnToken_t * matchToken (ttcnTokenType_t toktype)\n{\n\tttcnToken_t * pTok = getToken();\n\tif (pTok && (pTok->type == toktype))\n\t\treturn pTok;\n\tungetToken();\n\treturn NULL;\n}\n\n/* Count nested brackets, return when brackets are balanced */\nstatic int matchBrackets (const char * br)\n{\n\tif (matchToken(br[0]))\n\t{\n\t\tint brcount = 1;\n\t\twhile (brcount > 0)\n\t\t{\n\t\t\tif (matchToken(br[0]))       /* Open */\n\t\t\t\tbrcount++;\n\t\t\telse if (matchToken(br[1]))  /* Close */\n\t\t\t\tbrcount--;\n\t\t\telse if (!getToken())        /* EOF */\n\t\t\t\treturn 0;\n\t\t}\n\t\treturn 1;\n\t}\n\treturn 0;\n}\nstatic const char BR_CUR[] = \"{}\";\nstatic const char BR_PAR[] = \"()\";\nstatic const char BR_SQ[] = \"[]\";\nstatic const char BR_ANG[] = \"<>\";\n\n/* List of TTCN operators.\n   A dot (.) is not a TTCN operator but it is included to simplify\n   the expression parser. Instead of treating X.Y.Z as a single primary\n   the parser treats it as an expression with 3 primaries and two dots. */\nstatic const ttcnTokenType_t ttcnExprOps[] = {\n\tT_OR, T_XOR, T_AND, T_NOT, T_OP_EQ, T_OP_NE, '>', '<', T_OP_GE, T_OP_LE,\n\tT_OP_SHL, T_OP_SHR, T_OP_ROTL, T_OP_ROTR, T_OR4B, T_XOR4B, T_AND4B, T_NOT4B,\n\t'+', '-', '&', '*', '/', T_MOD, T_REM, '.'\n};\nstatic const int ttcnExprOpCount = ARRAY_SIZE(ttcnExprOps);\n\n/* Check if next token is an expression operator */\nstatic int matchExprOperator (void)\n{\n\tttcnToken_t * pTok = getToken();\n\tint i;\n\tif (!pTok)\n\t\treturn 0;\n\tfor (i = 0; i < ttcnExprOpCount; i++)\n\t\tif (pTok->type == ttcnExprOps[i])\n\t\t\treturn 1;\n\t/* Not found */\n\tungetToken();\n\treturn 0;\n}\n\n/* Check if next token is one of \"(omit)\", \"(value)\", \"(present)\".\n * ETSI ES 201 873-1 V4.14.1\n * A.1.6.7 471. TemplateRestriction ::= \"(\" (OmitKeyword | ValueKeyword | PresentKeyword) \")\"\n * A.1.6.6 461. OmitKeyword ::= \"omit\"\n * A.1.6.4.2 346. ValueKeyword ::= \"value\"\n * A.1.6.1.3 145.PresentKeyword ::= \"present\"\n */\nstatic int matchTemplateRestriction (void)\n{\n\t/* Simplistic: do not verify the actual \"omit\"/\"value\"/\"present\" keyword, just skip the entire brackets when\n\t * present. This also is tolerant to typos in the keyword. Drawback: would also accept any amount of unrelated\n\t * tokens and punctuation in the braces. */\n\treturn matchBrackets(BR_PAR);\n}\n\nstatic int parseExprOperand (void)\n{\n\tttcnToken_t * pTok;\n\tif (matchBrackets(BR_PAR)) /* Nested expression in brackets */\n\t\treturn 1;\n\tif (!(pTok = getToken()))\n\t\treturn 0;\n\tswitch (pTok->type)\n\t{\n\t\tcase T_CREATE:\n\t\t\t/* Create statement */\n\t\t\tmatchBrackets(BR_PAR);\n\t\t\tmatchToken(T_ALIVE);\n\t\t\treturn 1;\n\t\tcase T_EXECUTE:\n\t\tcase T_MATCH:\n\t\tcase T_VALUEOF:\n\t\tcase T_ACTIVATE:\n\t\tcase T_CHAR:\n\t\t\t/* These tokens must be followed by something in parentheses */\n\t\t\treturn matchBrackets(BR_PAR);\n\t\tcase T_SELF:\n\t\tcase T_SYSTEM:\n\t\tcase T_MTC:\n\t\tcase T_RUNNING:\n\t\tcase T_ALIVE:\n\t\tcase T_GETVERDICT:\n\t\tcase T_READ:\n\t\tcase T_ANY:\n\t\tcase T_LITERAL:\n\t\tcase T_TRUE:\n\t\tcase T_FALSE:\n\t\tcase T_PASS:\n\t\tcase T_FAIL:\n\t\tcase T_INCONC:\n\t\tcase T_NONE:\n\t\tcase T_ERROR:\n\t\tcase T_NULL:\n\t\tcase T_OMIT:\n\t\t\treturn 1;\n\t\tcase T_ID:\n\t\t\tif (!matchBrackets(BR_PAR))          /* Function call OR ... */\n\t\t\t\twhile (matchBrackets(BR_SQ));    /* ... array indexing */\n\t\t\treturn 1;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\tungetToken();\n\treturn 0;\n}\n\n/* Too lazy to really parse expressions so the parser is rather simplistic:\n   an expression is a series of operands separated by 1 or more operators. */\nstatic int parseSimpleExpression(void)\n{\n\twhile (matchExprOperator());    /* Skip leading unary ops */\n\twhile (parseExprOperand() && matchExprOperator())\n\t\twhile (matchExprOperator());\n\treturn 1;\n}\n\n/* Check if next token is an identifier, make a tag of a specified kind */\nstatic int parseID (ttcnKind_t kind)\n{\n\tttcnToken_t * pTok = matchToken(T_ID);\n\tif (pTok)\n\t{\n\t\tif (kind < K_NONE)\n\t\t\tmakeSimpleTag(pTok->value, kind);\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\n/* StringLength ::= \"length\" '(' ... ')' */\nstatic int parseStringLength (void)\n{\n\treturn (matchToken(T_LENGTH) && matchBrackets(BR_PAR));\n}\n\n/* ExtendedFieldReference ::= { '.' ID | '[' ... ']' }+ */\nstatic int parseExtendedFieldReference (void)\n{\n\tint res = 0;\n\twhile ((matchToken('.') && matchToken(T_ID)) || matchBrackets(BR_SQ))\n\t\tres = 1;\n\treturn res;\n}\n\n/* ArrayDef ::= { '[' ... ']' }+ */\nstatic int parseArrayDef (void)\n{\n\tint res = 0;\n\twhile (matchBrackets(BR_SQ))\n\t\tres = 1;\n\treturn res;\n}\n\n/* Initializer ::= \":=\" Expression */\nstatic int parseInitializer (void)\n{\n\tif (matchToken(T_OP_ASS))\n\t{\n\t\t/* Compound expression */\n\t\tif (matchBrackets(BR_CUR))\n\t\t\treturn 1;\n\t\t/* Simple expression */\n\t\treturn parseSimpleExpression();\n\t}\n\treturn 0;\n}\n\n/* NameInitList ::= ID [ArrayDef] [Initializer]\n   { ',' ID [ArrayDef] [Initializer] }\n   Used for parsing const/modulepar/var/timer/port definitions. */\nstatic int parseNameInitList (ttcnKind_t kind)\n{\n\tdo\n\t{\n\t\tif (!parseID(kind))\n\t\t\treturn 0;\n\t\t/* NB: ArrayDef is not allowed for modulepar */\n\t\tparseArrayDef();\n\t\t/* NB: Initializer is mandatory for constants, not allowed for ports */\n\t\tparseInitializer();\n\t} while (matchToken(','));\n\treturn 1;\n}\n\n/* A.1.6.3 Type ::= PredefinedType | ReferencedType */\nstatic int parseType (void)\n{\n\tttcnToken_t * pTok = getToken();\n\tif (!pTok)\n\t\treturn 0;\n\tswitch (pTok->type)\n\t{\n\t\t/* PredefinedType */\n\t\tcase T_BITSTRING:\n\t\tcase T_BOOLEAN:\n\t\tcase T_CHARSTRING:\n\t\tcase T_INTEGER:\n\t\tcase T_OCTETSTRING:\n\t\tcase T_HEXSTRING:\n\t\tcase T_VERDICTTYPE:\n\t\tcase T_FLOAT:\n\t\tcase T_ADDRESS:\n\t\tcase T_DEFAULT:\n\t\tcase T_ANYTYPE:\n\t\t\treturn 1;\n\t\tcase T_UNIVERSAL:\n\t\t\tif (!matchToken(T_CHARSTRING))\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t\treturn 1;\n\t\t/* ReferencedType ::= [ModuleID '.'] TypeID\n\t\t   [TypeActualParList] [ExtendedFieldReference] */\n\t\tcase T_ID:\n\t\t\t/* ModuleID.TypeID */\n\t\t\tif (matchToken('.') && !(matchToken(T_ID)))\n\t\t\t\tbreak;\n            /* FormalTypeParList */\n            matchBrackets(BR_ANG);\n\t\t\t/* TypeActualParList */\n\t\t\tmatchBrackets(BR_PAR);\n\t\t\t/* ExtendedFieldReference */\n\t\t\tparseExtendedFieldReference();\n\t\t\treturn 1;\n\t\tdefault :\n\t\t\tbreak;\n\t}\n\tungetToken();\n\treturn 0;\n}\n\n/* A.1.6.1.5 Signature ::= \"signature\" [ModuleID '.'] ID */\nstatic int parseSignature (void)\n{\n\treturn (matchToken(T_SIGNATURE) && matchToken(T_ID) && (!matchToken('.') || matchToken(T_ID)));\n}\n\n/* A.1.6.1.1 Structure ::= \"{\" [FieldDef {\",\" FieldDef}] \"}\"    */\nstatic int parseStructure (void)\n{\n\tif (!matchToken('{'))\n\t\treturn 0;\n\t/* Comma-separated list of fields */\n\tdo\n\t{\n\t\t/* StructFieldDef ::= (Type | NestedTypeDef) ID\n\t\t[ArrayDef] [SubTypeSpec] [\"optional\"] */\n\t\tif (!((parseType() || parseNestedTypeDef()) && parseID(K_MEMBER)))\n\t\t\treturn 0;\n\t\tparseArrayDef();\n\t\t/* SubTypeSpec */\n\t\tmatchBrackets(BR_PAR);  /* AllowedValues */\n\t\tparseStringLength();    /* StringLength */\n\t\tmatchToken(T_OPTIONAL); /* \"optional\" keyword */\n\t} while (matchToken(','));\n\tif (!matchToken('}'))\n\t\treturn 0;\n\treturn 1;\n}\n\n/* A.1.6.1.1 Enumeration ::= \"{\" [EnumDef {\",\" EnumDef}] \"}\" */\nstatic int parseEnumeration(void)\n{\n\tif (!matchToken('{'))\n\t\treturn 0;\n\t/* Comma-separated list of names and values */\n\tdo\n\t{\n\t\t/* EnumDef ::= ID ['(' ['-'] Value ')'] */\n\t\tif (!parseID(K_ENUM))\n\t\t\treturn 0;\n\t\tmatchBrackets(BR_PAR);    /* Value */\n\t} while (matchToken(','));\n\tif (!matchToken('}'))\n\t\treturn 0;\n\treturn 1;\n}\n\n/* NestedTypeDef ::= NestedRecordDef | NestedUnionDef | NestedSetDef |\n   NestedRecordOfDef | NestedSetOfDef | NestedEnumDef */\nstatic int parseNestedTypeDef (void)\n{\n\tttcnToken_t * pTok = getToken();\n\tif (!pTok)\n\t\treturn 0;\n\tswitch (pTok->type)\n\t{\n\t\tcase T_RECORD:\n\t\tcase T_SET:\n\t\t\t/* StringLength (optional), applies to RecordOf and SetOf */\n\t\t\tparseStringLength();\n\t\t\t/* RecordOf/SetOf */\n\t\t\tif (matchToken(T_OF))\n\t\t\t\treturn (parseType() || parseNestedTypeDef());\n\t\t\t/* This is correct, no break here! */\n\t\tcase T_UNION:\n\t\t\t/* Parse Record/Set/Union structure */\n\t\t\treturn parseStructure();\n\t\tcase T_ENUMERATED:\n\t\t\t/* Parse Enumeration values */\n\t\t\treturn parseEnumeration();\n\t\tdefault :\n\t\t\tbreak;\n\t}\n\t/* No match */\n\tungetToken();\n\treturn 0;\n}\n\n/* A.1.6.1.1 TypeDefBody ::= StructuredTypeDef | SubTypeDef */\nstatic int parseTypeDefBody (void)\n{\n\tttcnToken_t * pTok = getToken();\n\tif (!pTok)\n\t\treturn 0;\n\tswitch (pTok->type)\n\t{\n\t\t/* StructuredTypeDef ::= RecordDef | UnionDef | SetDef |\n\t\t   RecordOfDef | SetOfDef | EnumDef | PortDef | ComponentDef */\n\t\tcase T_RECORD:\n\t\tcase T_SET:\n\t\t\t/* StringLength (optional), applies to RecordOf and SetOf */\n\t\t\tparseStringLength();\n\t\t\tif (matchToken(T_OF))    /* RecordOf/SetOf */\n\t\t\t\treturn ((parseType() || parseNestedTypeDef()) && parseID(K_TYPE));\n\t\t\t/* This is correct, no break here! */\n\t\tcase T_UNION:\n\t\t\t/* Parse Record/Set/Union structure */\n\t\t\tif (!(parseID(K_TYPE) || matchToken(T_ADDRESS)))\n\t\t\t\treturn 0;\n\t\t\tmatchBrackets(BR_PAR);    /* StructDefFormalParList */\n\t\t\treturn parseStructure();\n\t\tcase T_ENUMERATED:\n\t\t\tif (!(parseID(K_TYPE) || matchToken(T_ADDRESS)))\n\t\t\t\treturn 0;\n\t\t\treturn parseEnumeration();\n\t\tcase T_PORT:\n\t\tcase T_COMPONENT:\n\t\t\t/* Record/Set/Union/Enum/Port/Component */\n\t\t\treturn parseID(K_TYPE);\n\t\tdefault:\n\t\t\t/* SubTypeDef */\n\t\t\tungetToken();\n\t\t\t/* Stop after type name, no need to parse ArrayDef, StringLength, etc */\n\t\t\treturn (parseType() && parseID(K_TYPE));\n\t}\n}\n\nstatic void parseTTCN (void)\n{\n\tttcnToken_t * pTok;\n\tttcnKind_t kind;\n\twhile ((pTok = getToken()))\n\t{\n\t\tkind = pTok->kind;\n\t\tswitch (pTok->type)\n\t\t{\n\t\t\tcase T_MODULE:      /* A.1.6.0 */\n\t\t\tcase T_FUNCTION:    /* A.1.6.1.4 */\n\t\t\tcase T_SIGNATURE:   /* A.1.6.1.5 */\n\t\t\tcase T_TESTCASE:    /* A.1.6.1.6 */\n\t\t\tcase T_ALTSTEP:     /* A.1.6.1.7 */\n\t\t\tcase T_GROUP:       /* A.1.6.1.9 */\n\t\t\t\t/* Def ::= Keyword ID ... */\n\t\t\t\tparseID(kind);\n\t\t\t\tbreak;\n\n\t\t\tcase T_VAR:\n\t\t\t\t/* A.1.6.2.1 VarInstance ::= \"var\" [\"template\"] Type List */\n\t\t\t\tmatchToken(T_TEMPLATE);\n\t\t\tcase T_CONST:   /* A.1.6.1.2 ConstDef ::= \"const\" Type List */\n\t\t\tcase T_PORT:    /* A.1.6.1.1 PortInstance ::= \"port\" Type List */\n\t\t\t\tif (!parseType())\n\t\t\t\t\tbreak;\n\t\t\tcase T_TIMER:   /* A.1.6.2.2 TimerInstance ::= \"timer\" List */\n\t\t\t\tparseNameInitList(kind);\n\t\t\t\tbreak;\n\t\t\tcase T_TYPE:    /* A.1.6.1.1 */\n\t\t\t\tparseTypeDefBody();\n\t\t\t\tbreak;\n\t\t\tcase T_TEMPLATE:\n\t\t\t\t/* A.1.6.1.3 TemplateDef ::= \"template\" [TemplateRestriction] (Type | Signature) ID ... */\n\t\t\t\tmatchTemplateRestriction();\n\t\t\t\tif (parseType() || parseSignature())\n\t\t\t\t\tparseID(K_TEMPLATE);\n\t\t\t\tbreak;\n\t\t\tcase T_MODULEPAR:\n\t\t\t\t/* A.1.6.1.12 ModuleParDef ::= \"modulepar\"\n\t\t\t\t   (Type ModuleParList | '{' MultitypedModuleParList '}') */\n\t\t\t\tif (matchToken('{'))\n\t\t\t\t{\n\t\t\t\t\t/* MultitypedModuleParList ::= (Type ModuleParList [;])* */\n\t\t\t\t\twhile (parseType() && parseNameInitList(K_MODULEPAR))\n\t\t\t\t\t\t/* Separating semicolons are optional */\n\t\t\t\t\t\twhile (matchToken(';'));\n\t\t\t\t}\n\t\t\t\telse if (parseType())\n\t\t\t\t{\n\t\t\t\t\t/* Type ModuleParList */\n\t\t\t\t\tparseNameInitList(K_MODULEPAR);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase T_IMPORT:\n\t\t\t\t/* A.1.6.1.8 ImportDef = \"import\" \"from\" ModuleId [\"recursive\"]\n\t\t\t\t('{' ImportList '}') | (\"all\" [\"except\"] '{' ExceptList '}')\n\t\t\t\tParse import definition not to generate tags but to avoid\n\t\t\t\tgenerating misleading tags from import/except lists */\n\t\t\t\tif (!matchToken(T_FROM) || ! matchToken(T_ID))\n\t\t\t\t\tbreak;\n\t\t\t\tmatchToken(T_RECURSIVE);\n\t\t\t\tif (matchToken(T_ALL) && !matchToken(T_EXCEPT))\n\t\t\t\t\tbreak;\n\t\t\t\t/* Skip import/except list */\n\t\t\t\tmatchBrackets(BR_CUR);\n\t\t\t\tbreak;\n\t\t\tdefault :\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/* Parser definition */\nextern parserDefinition * TTCNParser (void)\n{\n\tstatic const char * const extensions [] = { \"ttcn\", \"ttcn3\", NULL };\n\tparserDefinition * def = parserNew (\"TTCN\");\n\tdef->kindTable      = ttcnKinds;\n\tdef->kindCount  = ARRAY_SIZE(ttcnKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = parseTTCN;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/txt2tags.c",
    "content": "/*\n*   Copyright (c) 2009, Eric Forgeot\n*   Copyright (c) 2014, Colomban Wendling <colomban@geany.org>\n*\n*   Based on work by Jon Strait\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your opinion) any later version.\n*\n*   This module contains functions for generating tags for Txt2tags files\n*   (https://en.wikipedia.org/wiki/Txt2tags).\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include <ctype.h>\n#include <string.h>\n\n#include \"parse.h\"\n#include \"read.h\"\n#include \"nestlevel.h\"\n#include \"vstring.h\"\n#include \"routines.h\"\n#include \"entry.h\"\n\n\n#define SCOPE_SEPARATOR \"\\\"\\\"\"\n\n/*\n*   DATA DEFINITIONS\n*/\n\ntypedef enum {\n\tK_SECTION = 0\n} Txt2tagsKind;\n\nstatic scopeSeparator Txt2TagsSeparators [] = {\n\t{ KIND_WILDCARD_INDEX, SCOPE_SEPARATOR }\n};\n\nstatic kindDefinition Txt2tagsKinds[] = {\n\t{ true, 's', \"section\", \"sections\",\n\t  ATTACH_SEPARATORS(Txt2TagsSeparators) },\n};\n\nstruct nestingLevelUserData {\n\tint indentation;\n};\n#define NL_INDENTATION(nl) ((struct nestingLevelUserData *)nestingLevelGetUserData(nl))->indentation\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic int makeTxt2tagsTag (const vString* const name,\n                            const NestingLevels *const nls,\n                            Txt2tagsKind type)\n{\n\ttagEntryInfo e;\n\tNestingLevel *nl;\n\tinitTagEntry (&e, vStringValue(name), type);\n\n\tnl = nestingLevelsGetCurrent (nls);\n\tif (nl)\n\t\te.extensionFields.scopeIndex = nl->corkIndex;\n\n\treturn makeTagEntry(&e);\n}\n\n/* matches: ^ *[=_-]{20,} *$ */\nstatic bool isTxt2tagsLine (const unsigned char *line)\n{\n\tunsigned int len;\n\n\twhile (isspace(*line)) line++;\n\tfor (len = 0; *line == '=' || *line == '-' || *line == '_'; len++)\n\t\tline++;\n\twhile (isspace(*line)) line++;\n\n\treturn len >= 20 && *line == 0;\n}\n\nstatic bool parseTxt2tagsTitle (const unsigned char *line,\n                                vString *const title,\n                                int *const depth_)\n{\n\tconst int MAX_TITLE_DEPTH = 5; /* maximum length of a title delimiter */\n\tunsigned char delim;\n\tint delim_delta = 0;\n\tconst unsigned char *end;\n\n\t/* skip leading spaces, but no tabs (probably because they create quotes) */\n\twhile (*line == ' ') line++;\n\n\t/* normal/numbered titles */\n\tif (*line != '=' && *line != '+')\n\t\treturn false;\n\n\tdelim = *line;\n\n\t/* find the start delimiter length */\n\twhile (*line == delim && delim_delta < MAX_TITLE_DEPTH+1)\n\t{\n\t\tline++;\n\t\tdelim_delta++;\n\t}\n\twhile (isspace(*line))\n\t\tline++;\n\n\tif (delim_delta > MAX_TITLE_DEPTH) /* invalid */\n\t\treturn false;\n\n\t*depth_ = delim_delta;\n\n\t/* find the end delimiter */\n\tend = line + strlen((const char *) line) - 1;\n\twhile (end > line && isspace(*end)) end--;\n\t/* skip a possible label: \\[[A-Za-z0-9_-]+\\] */\n\tif (*end == ']')\n\t{\n\t\tend--;\n\t\twhile (end > line && (isalnum(*end) || *end == '_' || *end == '-'))\n\t\t\tend--;\n\t\tif (*end != '[') /* invalid */\n\t\t\treturn false;\n\t\tend--;\n\t}\n\twhile (end > line && *end == delim && delim_delta >= 0)\n\t{\n\t\tdelim_delta--;\n\t\tend--;\n\t}\n\twhile (end > line && isspace(*end)) end--;\n\tend++;\n\n\t/* if start and end delimiters are not identical, or the the name is empty */\n\tif (delim_delta != 0 || (end - line) <= 0)\n\t\treturn false;\n\n\tvStringNCopyS(title, (const char *) line, end - line);\n\treturn true;\n}\n\nstatic void findTxt2tagsTags (void)\n{\n\tNestingLevels *nls = nestingLevelsNew(sizeof(struct nestingLevelUserData));\n\tvString *name = vStringNew();\n\tconst unsigned char *line;\n\n\twhile ((line = readLineFromInputFile()) != NULL)\n\t{\n\t\tint depth;\n\n\t\tif (isTxt2tagsLine(line))\n\t\t\t; /* skip not to improperly match titles */\n\t\telse if (parseTxt2tagsTitle(line, name, &depth))\n\t\t{\n\t\t\tNestingLevel *nl = nestingLevelsGetCurrent(nls);\n\t\t\tint r;\n\n\t\t\twhile (nl && NL_INDENTATION(nl) >= depth)\n\t\t\t{\n\t\t\t\tnestingLevelsPop(nls);\n\t\t\t\tnl = nestingLevelsGetCurrent(nls);\n\t\t\t}\n\n\t\t\tr = makeTxt2tagsTag(name, nls, K_SECTION);\n\t\t\tnestingLevelsPush(nls, r);\n\t\t\tnl = nestingLevelsGetCurrent(nls);\n\t\t\tNL_INDENTATION(nl) = depth;\n\t\t}\n\t}\n\tvStringDelete (name);\n\tnestingLevelsFree(nls);\n}\n\nextern parserDefinition* Txt2tagsParser (void)\n{\n\tstatic const char *const patterns [] = { \"*.t2t\", NULL };\n\tstatic const char *const extensions [] = { \"t2t\", NULL };\n\tparserDefinition* const def = parserNew (\"Txt2tags\");\n\n\tdef->kindTable = Txt2tagsKinds;\n\tdef->kindCount = ARRAY_SIZE (Txt2tagsKinds);\n\tdef->patterns = patterns;\n\tdef->extensions = extensions;\n\tdef->parser = findTxt2tagsTags;\n\tdef->useCork = CORK_QUEUE;\n\treturn def;\n}\n\n"
  },
  {
    "path": "parsers/typescript.c",
    "content": "/*\n *\t Copyright (c) 2019, Karol Samborski\n *\n *\t This source code is released for free distribution under the terms of the\n *\t GNU General Public License version 2 or (at your option) any later version.\n *\n *\t This module contains functions for generating tags for TypeScript language\n *\t files.\n *\n *\t Reference: https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.pdf\n *\n */\n\n/*\n *\t INCLUDE FILES\n */\n#include \"general.h\"    /* must always come first */\n\n#include <stdio.h>\n#include <stdarg.h>\n#include <string.h>\n\n#include \"parse.h\"\n#include \"objpool.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n#include \"numarray.h\"\n#include \"routines.h\"\n#include \"entry.h\"\n#include \"inline.h\"\n#include \"unwindi.h\"\n#include \"trace.h\"\n\n#define STATUS2STRING(status)\t\t\t\t\t\t\t\t\t\\\n\t((status) == PARSER_FINISHED ? \"FINISHED\" :\t\t\t\t\t\\\n\t (status) == PARSER_NEEDS_MORE_INPUT ? \"needs_more_input\" :\t\\\n\t (status) == PARSER_FAILED ? \"failed\" : \"unknown\")\n#define TRACE_LEAVE_WITH_RESULT(RESULT)\t\t\t\t\t\\\n\tTRACE_LEAVE_TEXT(\"status: %s, unusedChars: %u\",\t\t\\\n\t\t\t\t\t STATUS2STRING((RESULT)->status),\t\\\n\t\t\t\t\t (RESULT)->unusedChars)\n#define TRACE_LEAVE_WITH_RESULT_AND_TOKEN(RESULT,TOKEN)\t\t\t\t\t\\\n\tTRACE_LEAVE_TEXT(\"status: %s, unusedChars: %u%s%s%s%s\",\t\t\t\t\\\n\t\t\t\t\t STATUS2STRING((RESULT)->status),\t\t\t\t\t\\\n\t\t\t\t\t (RESULT)->unusedChars,\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t ((RESULT)->status == PARSER_FAILED)?\"\":\", \",\t\t\\\n\t\t\t\t\t ((RESULT)->status == PARSER_FAILED)?\"\":decodeToken(TOKEN), \\\n\t\t\t\t\t ((RESULT)->status == PARSER_FAILED)?\"\":\", str: \",\t\\\n\t\t\t\t\t ((RESULT)->status == PARSER_FAILED)?\"\":vStringValue((TOKEN)->string))\n#define TRACE_LEAVE_IN_THE_MIDDLE()\t\t\t\t\\\n\tTRACE_LEAVE_TEXT(\"(in the middle)\")\n#define TRACE_LEAVE_IN_THE_STAGE(STAGE)\t\t\t\t\\\n\tTRACE_LEAVE_TEXT(\"(at the stage %d)\", STAGE)\n#ifdef DO_TRACING\nstatic const char *encodeString (const char *str)\n{\n\tstatic vString *buf;\n\tbuf = vStringNewOrClearWithAutoRelease (buf);\n\n\twhile (*str)\n\t{\n\t\tif (*str == '\\n')\n\t\t{\n\t\t\tvStringPut (buf, '\\\\');\n\t\t\tvStringPut (buf, 'n');\n\t\t}\n\t\telse if (*str == '\\t')\n\t\t{\n\t\t\tvStringPut (buf, '\\\\');\n\t\t\tvStringPut (buf, 't');\n\t\t}\n\t\telse if (*str == '\\r')\n\t\t{\n\t\t\tvStringPut (buf, '\\\\');\n\t\t\tvStringPut (buf, 'r');\n\t\t}\n\t\telse if (*str == '\\f')\n\t\t{\n\t\t\tvStringPut (buf, '\\\\');\n\t\t\tvStringPut (buf, 'f');\n\t\t}\n\t\telse\n\t\t\tvStringPut (buf, *str);\n\t\tstr++;\n\t}\n\n\treturn vStringValue (buf);\n}\n\nstatic const char *encodeChar (const char c)\n{\n\tconst char str[] = {c, '\\0'};\n\treturn encodeString(str);\n}\n#endif\n\n#define isType(token,t)     (bool) ((token)->type == (t))\n#define isKeyword(token,k)  (bool) ((token)->keyword == (k))\n#define newToken() (objPoolGet (TokenPool))\n#define deleteToken(t) (objPoolPut (TokenPool, (t)))\n#define isIdentChar(c) \\\n\t(isalpha (c) || isdigit (c) || (c) == '$' || \\\n\t (c) == '@' || (c) == '_' || (c) == '#' || \\\n\t (c) >= 0x80)\n\n#define PARSER_DEF(fname, pfun, word, stateField) \\\n\tCTAGS_INLINE void parse ## fname (const int c, tokenInfo * const token, \\\n\t\t\t\t\t\t\t\t\t  parserState *state, \\\n\t\t\t\t\t\t\t\t\t  parserResult * const result)\t\\\n\t{ \\\n\t\tTRACE_ENTER();\t\t\t\t\t\t\t\t\t   \\\n\t\tpfun (c, token, word, &state->stateField, result); \\\n\t\tTRACE_LEAVE_WITH_RESULT_AND_TOKEN(result, token);\t\\\n\t}\n\n#define SINGLE_CHAR_PARSER_DEF(fname, ch, ttype) \\\n\tCTAGS_INLINE void parse ## fname (const int c, tokenInfo * const token, \\\n\t\t\t\t\t\t\t\t\t  parserState *state, \\\n\t\t\t\t\t\t\t\t\t  parserResult * const result)\t\\\n\t{ \\\n\t\tTRACE_ENTER();\t\t\t\t\t\t\t\t\\\n\t\tparseOneChar (c, token, ch, ttype, result); \\\n\t\tTRACE_LEAVE_WITH_RESULT_AND_TOKEN(result, token);\t\\\n\t}\n\n#define MULTI_CHAR_PARSER_DEF(fname, chs, ...) \\\n\tCTAGS_INLINE void parse ## fname (const int c, tokenInfo * const token, \\\n\t\t\t\t\t\t\t\t\t  parserState *state, \\\n\t\t\t\t\t\t\t\t\t  parserResult * const result)\t\\\n\t{ \\\n\t\tTRACE_ENTER();\t\t\t\t\t\t\t\t\\\n\t\ttokenType types[] = { __VA_ARGS__ }; \\\n\t\tparseChar (c, token, state, result, chs, types); \\\n\t\tTRACE_LEAVE_WITH_RESULT_AND_TOKEN(result, token);\t\\\n\t}\n\n#define WORD_TOKEN_PARSER_DEF(fname, w, ttype) \\\n\tCTAGS_INLINE void parse ## fname (const int c, tokenInfo * const token, \\\n\t\t\t\t\t\t\t\t\t  parserState *state, \\\n\t\t\t\t\t\t\t\t\t  parserResult * const result)\t\\\n\t{ \\\n\t\tTRACE_ENTER();\t\t\t\t\t\t\t\t\\\n\t\tparseWordToken (c, token, w, ttype, &state->num, result); \\\n\t\tTRACE_LEAVE_WITH_RESULT_AND_TOKEN(result, token);\t\\\n\t}\n\n#define BLOCK_PARSER_DEF(fname, start, end, ttype) \\\n\tCTAGS_INLINE void parse ## fname (const int c, tokenInfo * const token, \\\n\t\t\t\t\t\t\t\t\t  parserState *state, \\\n\t\t\t\t\t\t\t\t\t  parserResult * const result)\t\\\n\t{ \\\n\t\tTRACE_ENTER();\t\t\t\t\t\t\t\t\\\n\t\tparseBlock (c, token, ttype, start, end, &state->block, result); \\\n\t\tTRACE_LEAVE_WITH_RESULT_AND_TOKEN(result, token);\t\\\n\t}\n\n/*\n *\tDATA DEFINITIONS\n */\nstatic langType Lang_ts;\nstatic objPool *TokenPool = NULL;\n\n/*\tUsed to specify type of keyword.\n */\nenum eKeywordId {\n\tKEYWORD_as,\n\tKEYWORD_async,\n\tKEYWORD_await,\n\tKEYWORD_class,\n\tKEYWORD_constructor,\n\tKEYWORD_const,\n\tKEYWORD_enum,\n\tKEYWORD_extends,\n\tKEYWORD_for,\n\tKEYWORD_function,\n\tKEYWORD_instanceof,\n\tKEYWORD_in,\n\tKEYWORD_interface,\n\tKEYWORD_implements,\n\tKEYWORD_let,\n\tKEYWORD_namespace,\n\tKEYWORD_new,\n\tKEYWORD_of,\n\tKEYWORD_private,\n\tKEYWORD_protected,\n\tKEYWORD_public,\n\tKEYWORD_return,\n\tKEYWORD_readonly,\n\tKEYWORD_static,\n\tKEYWORD_this,\n\tKEYWORD_type,\n\tKEYWORD_typeof,\n\tKEYWORD_var,\n\tKEYWORD_while\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum eTokenType {\n\tTOKEN_UNDEFINED,\n\tTOKEN_EOF,\n\tTOKEN_CHARACTER,\n\tTOKEN_SEMICOLON,\n\tTOKEN_COLON,\n\tTOKEN_QUESTION_MARK,\n\tTOKEN_COMMA,\n\tTOKEN_KEYWORD,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n\tTOKEN_GENERIC,\n\tTOKEN_PERIOD,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_EQUAL_SIGN,\n\tTOKEN_STAR,\n\tTOKEN_NL,\n\tTOKEN_COMMENT_BLOCK,\n\tTOKEN_PARENS,\n\tTOKEN_SQUARES,\n\tTOKEN_CURLIES,\n\tTOKEN_PIPE,\n\tTOKEN_AMPERSAND,\n\tTOKEN_ARROW,\n\tTOKEN_NUMBER,\n\tTOKEN_AT,\n\tTOKEN_MINUS,\n\tTOKEN_PLUS,\n\tTOKEN_BANG,\n\tTOKEN_DIV,\n\tTOKEN_POWER,\n\tTOKEN_GREATER,\n\tTOKEN_LOWER\n} tokenType;\n\ntypedef enum {\n\tTSTAG_FUNCTION,\n\tTSTAG_CLASS,\n\tTSTAG_INTERFACE,\n\tTSTAG_ENUM,\n\tTSTAG_ENUMERATOR,\n\tTSTAG_METHOD,\n\tTSTAG_NAMESPACE,\n\tTSTAG_PARAMETER,\n\tTSTAG_PROPERTY,\n\tTSTAG_VARIABLE,\n\tTSTAG_LOCAL,\n\tTSTAG_CONSTANT,\n\tTSTAG_GENERATOR,\n\tTSTAG_ALIAS\n} tsKind;\n\ntypedef enum {\n\tF_PROPERTIES,\n} tsField;\n\ntypedef struct sTokenInfo {\n\ttokenType type;\n\tkeywordId keyword;\n\tvString *string;\n\tint scope;\n\tunsigned long lineNumber;\n\tMIOPos filePosition;\n\tkeywordId accessKeyword;\n\tbool isStatic;\n} tokenInfo;\n#include \"d-typescript.h\"\n\ntypedef struct sCommentState {\n\tint parsed;\n\tint blockParsed;\n\tbool isBlock;\n} commentState;\n\ntypedef struct sBlockState {\n\tint parsed;\n\tint nestLevel;\n\tint curlyLevel;\n} blockState;\n\nstatic fieldDefinition TsFields[] = {\n\t{\n\t\t.name = \"properties\",\n\t\t.description = \"properties (static)\",\n\t\t.enabled = false,\n\t\t.version = 1,\n\t},\n};\n\nstatic const keywordTable TsKeywordTable [] = {\n\t/* keyword\t\t  keyword ID */\n\t{ \"as\"\t        , KEYWORD_as          },\n\t{ \"async\"       , KEYWORD_async       },\n\t{ \"await\"       , KEYWORD_await       },\n\t{ \"class\"       , KEYWORD_class       },\n\t{ \"const\"       , KEYWORD_const       },\n\t{ \"constructor\" , KEYWORD_constructor },\n\t{ \"enum\"        , KEYWORD_enum        },\n\t{ \"extends\"     , KEYWORD_extends     },\n\t{ \"for\"         , KEYWORD_for         },\n\t{ \"function\"    , KEYWORD_function    },\n\t{ \"in\"          , KEYWORD_in          },\n\t{ \"interface\"   , KEYWORD_interface   },\n\t{ \"implements\"  , KEYWORD_implements  },\n\t{ \"let\"         , KEYWORD_let         },\n\t{ \"namespace\"   , KEYWORD_namespace   },\n\t{ \"new\"\t\t\t, KEYWORD_new\t\t  },\n\t{ \"of\"          , KEYWORD_of          },\n\t{ \"private\"     , KEYWORD_private     },\n\t{ \"protected\"   , KEYWORD_protected   },\n\t{ \"public\"      , KEYWORD_public      },\n\t{ \"static\"      , KEYWORD_static      },\n\t{ \"this\"        , KEYWORD_this        },\n\t{ \"type\"        , KEYWORD_type        },\n\t{ \"typeof\"      , KEYWORD_typeof      },\n\t{ \"var\"         , KEYWORD_var         },\n\t{ \"while\"       , KEYWORD_while       }\n};\n\nstatic kindDefinition TsKinds [] = {\n\t{ true,  'f', \"function\",     \"functions\"                                       },\n\t{ true,  'c', \"class\",        \"classes\"                                         },\n\t{ true,  'i', \"interface\",    \"interfaces\"                                      },\n\t{ true,  'g', \"enum\",         \"enums\"                                           },\n\t{ true,  'e', \"enumerator\",   \"enumerators (values inside an enumeration)\"      },\n\t{ true,  'm', \"method\",       \"methods\"                                         },\n\t{ true,  'n', \"namespace\",    \"namespaces\"                                      },\n\t{ false, 'z', \"parameter\",    \"function parameters inside function definitions\" },\n\t{ true,  'p', \"property\",     \"properties\"                                      },\n\t{ true,  'v', \"variable\",     \"variables\"                                       },\n\t{ false, 'l', \"local\",        \"local variables\"                                 },\n\t{ true,  'C', \"constant\",     \"constants\"                                       },\n\t{ true,  'G', \"generator\",    \"generators\"                                      },\n\t{ true,  'a', \"alias\",        \"aliases\",                                        }\n};\n\ntypedef enum eParserResult {\n\tPARSER_FINISHED,\n\tPARSER_NEEDS_MORE_INPUT,\n\tPARSER_FAILED\n} parserResultStatus;\n\ntypedef struct sParserResult {\n\tparserResultStatus status;\n\tunsigned int unusedChars;\n} parserResult;\n\ntypedef union uParserState {\n\tint num;\n\tblockState block;\n\tcommentState comment;\n\tchar ch;\n} parserState;\n\nstatic struct sUwiStats tsUwiStats;\n\ntypedef void (*Parser)(const int c, tokenInfo *const,\n\t\t\t\t\t   parserState *state, parserResult *const);\n\nstatic bool tryParser(Parser parser, tokenInfo *const token, bool skipWhite);\nCTAGS_INLINE void parseStringRegex(const int c, tokenInfo * const token,\n\t\t\t\t\t\t\t\t   parserState *state, parserResult * const result);\nCTAGS_INLINE void parseStringSQuote(const int c, tokenInfo * const token,\n\t\t\t\t\t\t\t\t\tparserState *state, parserResult * const result);\nCTAGS_INLINE void parseStringDQuote(const int c, tokenInfo * const token,\n\t\t\t\t\t\t\t\t\tparserState *state, parserResult * const result);\nCTAGS_INLINE void parseStringTemplate(const int c, tokenInfo * const token,\n\t\t\t\t\t\t\t\t\t  parserState *state, parserResult * const result);\n\nstatic int emitTag(const tokenInfo *const token, const tsKind kind)\n{\n\tTRACE_PRINT(\"tag: %s\", vStringValue (token->string));\n\n\tif (! TsKinds [kind].enabled)\n\t\treturn CORK_NIL;\n\n\tstatic const char *const access [3] = {\n\t\t\"private\",\n\t\t\"protected\",\n\t\t\"public\"\n\t};\n\n\tconst char *name = vStringValue (token->string);\n\ttagEntryInfo e;\n\n\tinitTagEntry (&e, name, kind);\n\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\te.extensionFields.scopeIndex = token->scope;\n\n\tswitch (token->accessKeyword)\n\t{\n\t\tcase KEYWORD_public:\n\t\t\te.extensionFields.access = access [2];\n\t\t\tbreak;\n\t\tcase KEYWORD_protected:\n\t\t\te.extensionFields.access = access [1];\n\t\t\tbreak;\n\t\tcase KEYWORD_private:\n\t\t\te.extensionFields.access = access [0];\n\t\t\tbreak;\n\t}\n\n\tif (token->isStatic)\n\t\tattachParserField (&e, TsFields[F_PROPERTIES].ftype, \"static\");\n\n\treturn makeTagEntry (&e);\n}\n\nstatic void *newPoolToken (void *createArg CTAGS_ATTR_UNUSED)\n{\n\ttokenInfo *token = xMalloc (1, tokenInfo);\n\ttoken->scope = CORK_NIL;\n\ttoken->string = NULL;\n\n\treturn token;\n}\n\nstatic void clearPoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\n\ttoken->type            = TOKEN_UNDEFINED;\n\ttoken->keyword         = KEYWORD_NONE;\n\ttoken->lineNumber      = uwiGetLineNumber ();\n\ttoken->filePosition    = uwiGetFilePosition ();\n\n\ttoken->scope = CORK_NIL;\n\n\ttoken->accessKeyword = KEYWORD_NONE;\n\ttoken->isStatic      = false;\n\n\ttoken->string = vStringNewOrClear (token->string);\n}\n\nstatic void deletePoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\tvStringDelete (token->string); /* NULL is acceptable */\n\teFree (token);\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const src,\n\t\t\t\t\t   bool scope)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tdest->keyword = src->keyword;\n\tvStringCopy (dest->string, src->string);\n\tif (scope)\n\t\tdest->scope = src->scope;\n}\n\nstatic void initToken (tokenInfo *const token, tokenType type)\n{\n\ttoken->type = type;\n\ttoken->keyword = KEYWORD_NONE;\n\ttoken->lineNumber   = uwiGetLineNumber ();\n\ttoken->filePosition = uwiGetFilePosition ();\n}\n\nCTAGS_INLINE bool whiteChar(const int c)\n{\n\treturn c == ' ' || c == '\\r' || c == '\\t';\n}\n\nCTAGS_INLINE void parseWhiteChars(const int c, tokenInfo *const token,\n\t\t\t\t\t\t\t\t  parserState *state,\n\t\t\t\t\t\t\t\t  parserResult * const result)\n{\n\tTRACE_ENTER();\n\n\tif (whiteChar (c))\n\t{\n\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\t\tstate->num += 1;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tif (state->num == 0)\n\t{\n\t\tresult->status = PARSER_FAILED;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tresult->status = PARSER_FINISHED;\n\tresult->unusedChars = 1;\n\n\tTRACE_LEAVE_WITH_RESULT(result);\n}\n\nCTAGS_INLINE void parseOneChar(const int c, tokenInfo *const token, const char expected,\n\t\t\t\t\t\t\t   const tokenType type, parserResult *const result)\n{\n\tTRACE_ENTER_TEXT(\"char: %c\", expected);\n\n\tif (c != expected)\n\t{\n\t\tresult->status = PARSER_FAILED;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tinitToken (token, type);\n\tresult->status = PARSER_FINISHED;\n\n\tTRACE_LEAVE_WITH_RESULT(result);\n}\n\nCTAGS_INLINE void parseChar(const int c, tokenInfo *const token, void *state,\n\t\t\t\t\t\t\tparserResult *const result,\n\t\t\t\t\t\t\tconst char *chars, const tokenType *types)\n{\n\tTRACE_ENTER_TEXT(\"chars: %s\", encodeString (chars));\n\n\tconst char *pos = strchr (chars, c);\n\n\tif (pos)\n\t{\n\t\tTRACE_PRINT(\"found: %s\", encodeChar(*pos));\n\n\t\tresult->status = PARSER_FINISHED;\n\t\tinitToken (token, types[pos - chars]);\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tresult->status = PARSER_FAILED;\n\n\tTRACE_LEAVE_WITH_RESULT(result);\n}\n\nCTAGS_INLINE void parseWord(const int c, tokenInfo *const token, const char *word, int *parsed,\n\t\t\t\t\t\t\tparserResult *const result)\n{\n\tTRACE_ENTER();\n\n\tif (word [*parsed] == '\\0')\n\t{\n\t\tif (isIdentChar (c))\n\t\t{\n\t\t\tresult->status = PARSER_FAILED;\n\n\t\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\t\treturn;\n\t\t}\n\n\t\tvStringCatS (token->string, word);\n\t\tinitToken (token, TOKEN_KEYWORD);\n\t\ttoken->keyword = lookupKeyword (vStringValue (token->string), Lang_ts);\n\n\t\tresult->unusedChars = 1;\n\t\tresult->status = PARSER_FINISHED;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tif (c == word [*parsed])\n\t{\n\t\t*parsed += 1;\n\n\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tresult->status = PARSER_FAILED;\n\n\tTRACE_LEAVE_WITH_RESULT(result);\n}\n\nCTAGS_INLINE void parseNumber(const int c, tokenInfo *const token, int *parsed,\n\t\t\t\t\t\t\t  parserResult *const result)\n{\n\tTRACE_ENTER();\n\n\tif (*parsed == 0)\n\t{\n\t\tif (c == '-')\n\t\t{\n\t\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\t\t\t*parsed += 1;\n\n\t\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (isdigit (c))\n\t{\n\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\t\t*parsed += 1;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\telse if (*parsed == 0)\n\t{\n\t\tresult->status = PARSER_FAILED;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tinitToken (token, TOKEN_NUMBER);\n\n\tresult->unusedChars = 1;\n\tresult->status = PARSER_FINISHED;\n\n\tTRACE_LEAVE_WITH_RESULT(result);\n}\n\nCTAGS_INLINE void parseWordToken(const int c, tokenInfo *const token, const char *word,\n\t\t\t\t\t\t\t\t const tokenType type, int *parsed,\n\t\t\t\t\t\t\t\t parserResult *const result)\n{\n\tTRACE_ENTER();\n\n\tif (c == word [*parsed])\n\t{\n\t\t*parsed += 1;\n\n\t\tif (word [*parsed] == '\\0')\n\t\t{\n\t\t\tinitToken (token, type);\n\t\t\tresult->status = PARSER_FINISHED;\n\n\t\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\t\treturn;\n\t\t}\n\n\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tresult->status = PARSER_FAILED;\n\n\tTRACE_LEAVE_WITH_RESULT(result);\n}\n\nCTAGS_INLINE void parseComment(const int c, tokenInfo *const token, parserState *state,\n\t\t\t\t\t\t\t   parserResult *const result)\n{\n\tTRACE_ENTER();\n\n\tif (state->comment.parsed < 2)\n\t{\n\t\tparseWordToken (c, token, \"//\", TOKEN_COMMENT_BLOCK, &state->comment.parsed,\n\t\t\t\t\t\tresult);\n\n\t\tif (result->status == PARSER_FAILED)\n\t\t{\n\t\t\tparseWordToken (c, token, \"/*\", TOKEN_COMMENT_BLOCK, &state->comment.parsed,\n\t\t\t\t\t\t\tresult);\n\t\t\tif (result->status == PARSER_FINISHED)\n\t\t\t{\n\t\t\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\t\t\t\tstate->comment.isBlock = true;\n\t\t\t}\n\t\t}\n\t\telse if (result->status == PARSER_FINISHED)\n\t\t{\n\t\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\t\t\tstate->comment.isBlock = false;\n\t\t}\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tstate->comment.parsed += 1;\n\n\tif (c == EOF)\n\t\tresult->status = PARSER_FINISHED;\n\telse if (state->comment.isBlock)\n\t{\n\t\tparseWordToken (c, token, \"*/\", TOKEN_COMMENT_BLOCK, &state->comment.blockParsed,\n\t\t\t\t\t\tresult);\n\n\t\tif (result->status == PARSER_FAILED)\n\t\t{\n\t\t\tstate->comment.blockParsed = c == '*' ? 1 : 0;\n\t\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\t\t}\n\t}\n\telse if (c == '\\n')\n\t{\n\t\tresult->status = PARSER_FINISHED;\n\t\tresult->unusedChars = 1;\n\t}\n\n\tif (result->status == PARSER_FINISHED)\n\t{\n\t\tinitToken (token, TOKEN_COMMENT_BLOCK);\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\n\tTRACE_LEAVE_WITH_RESULT(result);\n}\n\nCTAGS_INLINE void parseString(const int c, tokenInfo *const token, const char quote, char *prev,\n\t\t\t\t\t\t\t  parserResult *const result)\n{\n\tTRACE_ENTER();\n\n\tif (*prev == '\\0')\n\t{\n\t\tif (c == quote)\n\t\t{\n\t\t\t*prev = c;\n\t\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\t\t}\n\t\telse\n\t\t\tresult->status = PARSER_FAILED;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\telse if (c == EOF)\n\t{\n\t\tresult->status = PARSER_FAILED;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\tif (c == '\\\\' && *prev == '\\\\')\n\t{\n\t\t*prev = '\\1';\n\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\telse if (c == quote && *prev != '\\\\')\n\t{\n\t\tresult->status = PARSER_FINISHED;\n\t\tinitToken (token, TOKEN_STRING);\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\telse if (quote == '/' && c == '\\n') // regex cannot contain new lines\n\t{\n\t\tresult->status = PARSER_FAILED;\n\n\t\tTRACE_LEAVE_WITH_RESULT(result);\n\t\treturn;\n\t}\n\n\t*prev = c;\n\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\n\tTRACE_LEAVE_WITH_RESULT(result);\n}\n\n\nCTAGS_INLINE void parseBlock(const int c, tokenInfo *const token, tokenType const ttype,\n\t\t\t\t\t\t\t const char start, const char end, blockState *state,\n\t\t\t\t\t\t\t parserResult *const result)\n{\n\tif (state->parsed == 0)\n\t{\n\t\tif (c != start)\n\t\t{\n\t\t\tresult->status = PARSER_FAILED;\n\t\t\treturn;\n\t\t}\n\n\t\tstate->parsed = 1;\n\t}\n\n\tif (c == '{')\n\t\tstate->curlyLevel += 1;\n\telse if (c == '}')\n\t\tstate->curlyLevel -= 1;\n\n\tif (c == start)\n\t\tstate->nestLevel += 1;\n\telse if (c == end)\n\t\tstate->nestLevel -= 1;\n\telse if ((state->curlyLevel < 1 && c == ';') || c == EOF)\n\t{\n\t\tresult->status = PARSER_FAILED;\n\t\treturn;\n\t}\n\n\tif (state->nestLevel <= 0)\n\t{\n\t\tinitToken (token, ttype);\n\t\tresult->status = PARSER_FINISHED;\n\n\t\treturn;\n\t}\n\n\t//skip comments:\n\ttryParser ((Parser) parseComment, token, false);\n\t//skip strings:\n\ttryParser ((Parser) parseStringRegex, token, false);\n\ttryParser ((Parser) parseStringSQuote, token, false);\n\ttryParser ((Parser) parseStringDQuote, token, false);\n\ttryParser ((Parser) parseStringTemplate, token, false);\n\n\tresult->status = PARSER_NEEDS_MORE_INPUT;\n}\n\n\nCTAGS_INLINE void parseIdentifierCommon(const int c, tokenInfo *const token, int *parsed,\n\t\t\t\t\t\t\t\t\t\tparserResult *const result, bool acceptFqName)\n{\n\tif (isIdentChar (c) || (acceptFqName && c == '.'))\n\t{\n\t\tvStringPut (token->string, c);\n\t\t*parsed = *parsed + 1;\n\t\tresult->status = PARSER_NEEDS_MORE_INPUT;\n\n\t\treturn;\n\t}\n\n\tif (*parsed > 0)\n\t{\n\t\tinitToken (token, TOKEN_IDENTIFIER);\n\t\tresult->status = PARSER_FINISHED;\n\t\tresult->unusedChars = 1;\n\t\treturn;\n\t}\n\n\tresult->status = PARSER_FAILED;\n}\n\nCTAGS_INLINE void parseIdentifier(const int c, tokenInfo *const token, int *parsed,\n\t\t\t\t\t\t\t\t  parserResult *const result)\n{\n\tTRACE_ENTER();\n\tparseIdentifierCommon (c, token, parsed, result, false);\n\tTRACE_LEAVE_WITH_RESULT_AND_TOKEN(result, token);\n}\n\nCTAGS_INLINE void parseFQIdentifier(const int c, tokenInfo *const token, int *parsed,\n\t\t\t\t\t\t\t\t\tparserResult *const result)\n{\n\tTRACE_ENTER();\n\tparseIdentifierCommon (c, token, parsed, result, true);\n\tTRACE_LEAVE_WITH_RESULT_AND_TOKEN(result, token);\n}\n\nPARSER_DEF (AsKeyword, parseWord, \"as\", num)\nPARSER_DEF (AsyncKeyword, parseWord, \"async\", num)\nPARSER_DEF (AwaitKeyword, parseWord, \"await\", num)\nPARSER_DEF (ClassKeyword, parseWord, \"class\", num)\nPARSER_DEF (ConstKeyword, parseWord, \"const\", num)\nPARSER_DEF (ConstructorKeyword, parseWord, \"constructor\", num)\nPARSER_DEF (EnumKeyword, parseWord, \"enum\", num)\nPARSER_DEF (ExtendsKeyword, parseWord, \"extends\", num)\nPARSER_DEF (ForKeyword, parseWord, \"for\", num)\nPARSER_DEF (FunctionKeyword, parseWord, \"function\", num)\nPARSER_DEF (InKeyword, parseWord, \"in\", num)\nPARSER_DEF (InterfaceKeyword, parseWord, \"interface\", num)\nPARSER_DEF (ImplementsKeyword, parseWord, \"implements\", num)\nPARSER_DEF (LetKeyword, parseWord, \"let\", num)\nPARSER_DEF (NamespaceKeyword, parseWord, \"namespace\", num)\nPARSER_DEF (NewKeyword, parseWord, \"new\", num)\nPARSER_DEF (OfKeyword, parseWord, \"of\", num)\nPARSER_DEF (PrivateKeyword, parseWord, \"private\", num)\nPARSER_DEF (ProtectedKeyword, parseWord, \"protected\", num)\nPARSER_DEF (PublicKeyword, parseWord, \"public\", num)\nPARSER_DEF (ReadonlyKeyword, parseWord, \"readonly\", num)\nPARSER_DEF (StaticKeyword, parseWord, \"static\", num)\nPARSER_DEF (ThisKeyword, parseWord, \"this\", num)\nPARSER_DEF (TypeKeyword, parseWord, \"type\", num)\nPARSER_DEF (TypeofKeyword, parseWord, \"typeof\", num)\nPARSER_DEF (VarKeyword, parseWord, \"var\", num)\nPARSER_DEF (WhileKeyword, parseWord, \"while\", num)\n\nSINGLE_CHAR_PARSER_DEF (Colon, ':', TOKEN_COLON)\nSINGLE_CHAR_PARSER_DEF (Period, '.', TOKEN_PERIOD)\nSINGLE_CHAR_PARSER_DEF (OpenCurly, '{', TOKEN_OPEN_CURLY)\nSINGLE_CHAR_PARSER_DEF (Star, '*', TOKEN_STAR)\nSINGLE_CHAR_PARSER_DEF (At, '@', TOKEN_AT)\nSINGLE_CHAR_PARSER_DEF (NewLine, '\\n', TOKEN_NL)\n\nWORD_TOKEN_PARSER_DEF (Arrow, \"=>\", TOKEN_ARROW)\n\nPARSER_DEF (StringSQuote, parseString, '\\'', ch)\nPARSER_DEF (StringDQuote, parseString, '\"', ch)\nPARSER_DEF (StringTemplate, parseString, '`', ch)\nPARSER_DEF (StringRegex, parseString, '/', ch)\n\nBLOCK_PARSER_DEF (Parens, '(', ')', TOKEN_PARENS)\nBLOCK_PARSER_DEF (Squares, '[', ']', TOKEN_SQUARES)\nBLOCK_PARSER_DEF (Generic, '<', '>', TOKEN_GENERIC)\nBLOCK_PARSER_DEF (Curlies, '{', '}', TOKEN_CURLIES)\n\nCTAGS_INLINE bool tryParser(Parser parser, tokenInfo *const token, bool skipWhite)\n{\n\tTRACE_ENTER();\n\n\tparserState currentState;\n\tparserResult result;\n\tint c;\n\n\tresult.status = PARSER_NEEDS_MORE_INPUT;\n\tresult.unusedChars = 0;\n\tmemset(&currentState, 0, sizeof (currentState));\n\n\tuwiPushMarker();\n\n\tc = uwiGetC ();\n\tif (skipWhite && whiteChar (c))\n\t{\n\t\tdo\n\t\t\tc = uwiGetC ();\n\t\twhile (whiteChar (c));\n\t}\n\tparser (c, token, &currentState, &result);\n\n\twhile (result.status == PARSER_NEEDS_MORE_INPUT)\n\t{\n\t\tc = uwiGetC ();\n\t\tparser (c, token, &currentState, &result);\n\t}\n\n\tif (result.status == PARSER_FAILED)\n\t\tuwiPopMarker (-1, true);\n\telse if (result.unusedChars > 0)\n\t\tuwiPopMarker (result.unusedChars, true);\n\telse\n\t\tuwiDropMaker ();\n\n\tTRACE_LEAVE_TEXT(\"result: %d\", result.status == PARSER_FINISHED);\n\treturn result.status == PARSER_FINISHED;\n}\n\nstatic bool tryInSequence(tokenInfo *const token, bool skipUnparsed, Parser parser, ...)\n{\n\tTRACE_ENTER();\n\n\tParser currentParser = NULL;\n\tbool result = false;\n\n\ttryParser (parseWhiteChars, token, false);\n\n\tva_list args;\n\tva_start (args, parser);\n\n\tcurrentParser = parser;\n\twhile (! result && currentParser)\n\t{\n\t\tresult = tryParser (currentParser, token, false);\n\t\tcurrentParser = va_arg (args, Parser);\n\t}\n\n\tva_end (args);\n\n\tif (skipUnparsed && ! result)\n\t{\n\t\tbool skippedNextWord = false;\n\t\tint c = uwiGetC ();\n\n\t\twhile (c != EOF && isIdentChar(c))\n\t\t{\n\t\t\tc = uwiGetC ();\n\t\t\tskippedNextWord = true;\n\t\t}\n\n\t\tif (c != EOF && skippedNextWord)\n\t\t\tuwiUngetC (c);\n\n\t\tTRACE_LEAVE_TEXT(\"(skipUnparsed) result: %d\", c != EOF);\n\t\treturn c != EOF;\n\t}\n\n\tTRACE_LEAVE_TEXT(\"result: %d\", result);\n\treturn result;\n}\n\nMULTI_CHAR_PARSER_DEF (DecoratorChars, \"@\\n\", TOKEN_AT, TOKEN_NL)\nstatic void parseDecorator (tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed = false;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\t\tparsed = tryInSequence (token, false, parseDecoratorChars, parseComment,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && token->type != TOKEN_PARENS);\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, false, parseNewLine, parseComment, parseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && (token->type != TOKEN_IDENTIFIER\n\t\t\t\t\t\t|| tryParser ((Parser) parsePeriod, token, true)));\n\n\t//parse optional parens block\n\ttryParser ((Parser) parseParens, token, true);\n\n\tTRACE_LEAVE();\n}\n\nMULTI_CHAR_PARSER_DEF (InterfaceBodyChars, \"}:;.,|&\",\n\t\tTOKEN_CLOSE_CURLY, TOKEN_COLON,\n\t\tTOKEN_SEMICOLON, TOKEN_PERIOD, TOKEN_COMMA,\n\t\tTOKEN_PIPE, TOKEN_AMPERSAND)\nstatic void parseInterfaceBody (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed;\n\n\tdo\n\t{\n\t\tparsed = tryInSequence (token, true,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseParens,\n\t\t\t\t\t\t\t\tparseSquares,\n\t\t\t\t\t\t\t\tparseOpenCurly,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && ! isType (token, TOKEN_OPEN_CURLY));\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\ttokenInfo *member = NULL;\n\tbool parsingType = false;\n\tint visibility = 0;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, true,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseParens,\n\t\t\t\t\t\t\t\tparseSquares,\n\t\t\t\t\t\t\t\tparseCurlies,\n\t\t\t\t\t\t\t\tparseNumber,\n\t\t\t\t\t\t\t\tparsePrivateKeyword,\n\t\t\t\t\t\t\t\tparseProtectedKeyword,\n\t\t\t\t\t\t\t\tparsePublicKeyword,\n\t\t\t\t\t\t\t\tparseReadonlyKeyword,\n\t\t\t\t\t\t\t\tparseStaticKeyword,\n\t\t\t\t\t\t\t\tparseArrow,\n\t\t\t\t\t\t\t\tparseTypeofKeyword,\n\t\t\t\t\t\t\t\tparseInterfaceBodyChars,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tif (parsed)\n\t\t{\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\t\tswitch (token->keyword)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase KEYWORD_private:\n\t\t\t\t\t\tcase KEYWORD_public:\n\t\t\t\t\t\tcase KEYWORD_protected:\n\t\t\t\t\t\t\tif (member)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\temitTag (member, TSTAG_PROPERTY);\n\t\t\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\t\t\tmember = NULL;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvisibility = token->keyword;\n\t\t\t\t\t\t\tparsingType = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase KEYWORD_typeof:\n\t\t\t\t\t\t\tparsingType = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_COLON:\n\t\t\t\tcase TOKEN_PERIOD:\n\t\t\t\tcase TOKEN_PIPE:\n\t\t\t\tcase TOKEN_AMPERSAND:\n\t\t\t\tcase TOKEN_ARROW:\n\t\t\t\t\tparsingType = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\t\tif (member)\n\t\t\t\t\t{\n\t\t\t\t\t\temitTag (member, TSTAG_PROPERTY);\n\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\tmember = NULL;\n\t\t\t\t\t\tvisibility = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!parsingType)\n\t\t\t\t\t{\n\t\t\t\t\t\tmember = newToken ();\n\t\t\t\t\t\tcopyToken (member, token, false);\n\t\t\t\t\t\tmember->scope = scope;\n\t\t\t\t\t\tif (visibility)\n\t\t\t\t\t\t\tmember->accessKeyword = visibility;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tmember->accessKeyword = KEYWORD_public;\n\t\t\t\t\t}\n\t\t\t\t\tparsingType = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_PARENS:\n\t\t\t\t\tif (!parsingType && member)\n\t\t\t\t\t{\n\t\t\t\t\t\temitTag (member, TSTAG_METHOD);\n\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\tmember = NULL;\n\t\t\t\t\t\tvisibility = 0;\n\t\t\t\t\t}\n\t\t\t\tcase TOKEN_SQUARES:\n\t\t\t\tcase TOKEN_CURLIES:\n\t\t\t\tcase TOKEN_GENERIC:\n\t\t\t\tcase TOKEN_SEMICOLON:\n\t\t\t\tcase TOKEN_COMMA:\n\t\t\t\tcase TOKEN_STRING:\n\t\t\t\tcase TOKEN_NUMBER:\n\t\t\t\t\tparsingType = false;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while (parsed && ! isType (token, TOKEN_CLOSE_CURLY));\n\n\tif (member)\n\t{\n\t\temitTag (member, TSTAG_PROPERTY);\n\t\tdeleteToken (member);\n\t}\n\n\tTRACE_LEAVE();\n}\n\nstatic void parseInterface (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseNewLine,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && token->type != TOKEN_IDENTIFIER);\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\ttoken->scope = scope;\n\n\tconst int nscope = emitTag (token, TSTAG_INTERFACE);\n\n\tparseInterfaceBody (nscope, token);\n\n\tTRACE_LEAVE();\n}\n\nMULTI_CHAR_PARSER_DEF (TypeChars, \":;,=|&\",\n\t\tTOKEN_COLON, TOKEN_SEMICOLON, TOKEN_COMMA,\n\t\tTOKEN_EQUAL_SIGN, TOKEN_PIPE, TOKEN_AMPERSAND)\nstatic void parseType (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed;\n\tbool parsingType = false;\n\tbool shouldEnd = false;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseParens,\n\t\t\t\t\t\t\t\tparseSquares,\n\t\t\t\t\t\t\t\tparseCurlies,\n\t\t\t\t\t\t\t\tparseArrow,\n\t\t\t\t\t\t\t\tparseNumber,\n\t\t\t\t\t\t\t\tparseTypeofKeyword,\n\t\t\t\t\t\t\t\tparseTypeChars,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\t\tif (parsed)\n\t\t{\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\t\tswitch (token->keyword)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase KEYWORD_typeof:\n\t\t\t\t\t\t\tshouldEnd = true;\n\t\t\t\t\t\t\tparsingType = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_COLON:\n\t\t\t\tcase TOKEN_GENERIC:\n\t\t\t\tcase TOKEN_STRING:\n\t\t\t\tcase TOKEN_PARENS:\n\t\t\t\tcase TOKEN_SQUARES:\n\t\t\t\tcase TOKEN_CURLIES:\n\t\t\t\tcase TOKEN_NUMBER:\n\t\t\t\t\tshouldEnd = true;\n\t\t\t\t\tparsingType = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_EQUAL_SIGN:\n\t\t\t\tcase TOKEN_PIPE:\n\t\t\t\tcase TOKEN_AMPERSAND:\n\t\t\t\tcase TOKEN_ARROW:\n\t\t\t\t\tparsingType = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\t\tif (! parsingType && ! shouldEnd)\n\t\t\t\t\t{\n\t\t\t\t\t\ttoken->scope = scope;\n\t\t\t\t\t\temitTag (token, TSTAG_ALIAS);\n\t\t\t\t\t}\n\t\t\t\t\telse if (! parsingType && shouldEnd)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int i = vStringLength(token->string); i >= 0; i--)\n\t\t\t\t\t\t\tuwiUngetC (vStringChar(token->string, i));\n\n\t\t\t\t\t\tparsed = false;\n\t\t\t\t\t}\n\t\t\t\t\tparsingType = false;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while (parsed && ! isType (token, TOKEN_COMMA)\n\t\t\t && ! isType (token, TOKEN_SEMICOLON));\n\n\tclearPoolToken(token);\n\n\tTRACE_LEAVE();\n}\n\nMULTI_CHAR_PARSER_DEF (EnumBodyChars, \"},=|&.\",\n\t\tTOKEN_CLOSE_CURLY, TOKEN_COMMA, TOKEN_EQUAL_SIGN,\n\t\tTOKEN_PIPE, TOKEN_AMPERSAND, TOKEN_PERIOD)\nstatic void parseEnumBody (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed;\n\n\tdo\n\t{\n\t\tparsed = tryInSequence (token, true,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseParens,\n\t\t\t\t\t\t\t\tparseSquares,\n\t\t\t\t\t\t\t\tparseOpenCurly,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && token->type != TOKEN_OPEN_CURLY);\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\ttokenInfo *member = NULL;\n\tbool parsingValue = false;\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\t\tparsed = tryInSequence (token, true,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseParens,\n\t\t\t\t\t\t\t\tparseSquares,\n\t\t\t\t\t\t\t\tparseCurlies,\n\t\t\t\t\t\t\t\tparseNumber,\n\t\t\t\t\t\t\t\tparseEnumBodyChars,\n\t\t\t\t\t\t\t\tparseNewKeyword,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tif (parsed)\n\t\t{\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\t\tswitch (token->keyword)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase KEYWORD_new:\n\t\t\t\t\t\t\tparsingValue = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_EQUAL_SIGN:\n\t\t\t\tcase TOKEN_PIPE:\n\t\t\t\tcase TOKEN_AMPERSAND:\n\t\t\t\tcase TOKEN_PERIOD:\n\t\t\t\t\tparsingValue = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_COMMA:\n\t\t\t\tcase TOKEN_SEMICOLON:\n\t\t\t\tcase TOKEN_STRING:\n\t\t\t\tcase TOKEN_PARENS:\n\t\t\t\tcase TOKEN_SQUARES:\n\t\t\t\tcase TOKEN_CURLIES:\n\t\t\t\tcase TOKEN_NUMBER:\n\t\t\t\t\tparsingValue = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\t\tif (!parsingValue)\n\t\t\t\t\t{\n\t\t\t\t\t\tmember = newToken ();\n\t\t\t\t\t\tcopyToken (member, token, false);\n\t\t\t\t\t\tmember->scope = scope;\n\t\t\t\t\t\temitTag (member, TSTAG_ENUMERATOR);\n\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\tmember = NULL;\n\t\t\t\t\t}\n\t\t\t\t\tparsingValue = false;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while (parsed && ! isType (token, TOKEN_CLOSE_CURLY));\n\n\tif (member)\n\t\tdeleteToken (member);\n\n\tTRACE_LEAVE();\n}\n\nstatic void parseEnum (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && token->type != TOKEN_IDENTIFIER);\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\ttoken->scope = scope;\n\tconst int nscope = emitTag (token, TSTAG_ENUM);\n\n\tparseEnumBody (nscope, token);\n\n\tTRACE_LEAVE();\n}\n\nMULTI_CHAR_PARSER_DEF (VariableChars, \"|&=?[]{}()\\n:;,.-+/^<>*!\",\n\t\tTOKEN_PIPE, TOKEN_AMPERSAND, TOKEN_EQUAL_SIGN, TOKEN_QUESTION_MARK,\n\t\tTOKEN_OPEN_SQUARE, TOKEN_CLOSE_SQUARE, TOKEN_OPEN_CURLY, TOKEN_CLOSE_CURLY,\n\t\tTOKEN_OPEN_PAREN, TOKEN_CLOSE_PAREN, TOKEN_NL, TOKEN_COLON, TOKEN_SEMICOLON,\n\t\tTOKEN_COMMA, TOKEN_PERIOD, TOKEN_MINUS, TOKEN_PLUS,\n\t\tTOKEN_DIV, TOKEN_POWER, TOKEN_LOWER, TOKEN_GREATER, TOKEN_STAR, TOKEN_BANG)\nstatic void parseVariable (bool constVar, bool localVar, const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\ttokenInfo *member = NULL;\n\tbool parsed = false;\n\tbool parsingType = false;\n\tbool expectingVariable = false;\n\tbool mayBeFun = false;\n\tbool isFunction = false;\n\tint nestLevel = 0, parenLevel = 0;\n\ttsKind varKind = constVar ? TSTAG_CONSTANT : (localVar\n\t\t\t\t\t\t\t\t\t\t\t\t  ? TSTAG_LOCAL\n\t\t\t\t\t\t\t\t\t\t\t\t  : TSTAG_VARIABLE);\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseNumber,\n\t\t\t\t\t\t\t\tparseArrow,\n\t\t\t\t\t\t\t\tparseAsKeyword,\n\t\t\t\t\t\t\t\tparseAwaitKeyword,\n\t\t\t\t\t\t\t\tparseForKeyword,\n\t\t\t\t\t\t\t\tparseFunctionKeyword,\n\t\t\t\t\t\t\t\tparseWhileKeyword,\n\t\t\t\t\t\t\t\tparseThisKeyword,\n\t\t\t\t\t\t\t\tparseEnumKeyword,\n\t\t\t\t\t\t\t\tparseOfKeyword,\n\t\t\t\t\t\t\t\tparseInKeyword,\n\t\t\t\t\t\t\t\tparseNewKeyword,\n\t\t\t\t\t\t\t\tparseTypeofKeyword,\n\t\t\t\t\t\t\t\tparseVariableChars,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tif (parsed)\n\t\t{\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_OPEN_SQUARE:\n\t\t\t\tcase TOKEN_OPEN_CURLY:\n\t\t\t\t\tnestLevel += 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_OPEN_PAREN:\n\t\t\t\t\tparenLevel += 1;\n\t\t\t\t\tnestLevel += 1;\n\t\t\t\t\tif (mayBeFun)\n\t\t\t\t\t\tisFunction = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_CLOSE_SQUARE:\n\t\t\t\t\tnestLevel -= 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_CLOSE_PAREN:\n\t\t\t\t\tparenLevel -= 1;\n\t\t\t\t\tnestLevel -= 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_CLOSE_CURLY:\n\t\t\t\t\tnestLevel -= 1;\n\t\t\t\t\tif (nestLevel <= 0)\n\t\t\t\t\t\tisFunction = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_COMMA:\n\t\t\t\t\texpectingVariable = true;\n\t\t\t\tcase TOKEN_SEMICOLON:\n\t\t\t\tcase TOKEN_NUMBER:\n\t\t\t\tcase TOKEN_STRING:\n\t\t\t\t\tif (nestLevel <= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tparsingType = false;\n\t\t\t\t\t\tnestLevel = 0;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_BANG:\n\t\t\t\tcase TOKEN_STAR:\n\t\t\t\tcase TOKEN_MINUS:\n\t\t\t\tcase TOKEN_PLUS:\n\t\t\t\tcase TOKEN_DIV:\n\t\t\t\tcase TOKEN_POWER:\n\t\t\t\tcase TOKEN_GREATER:\n\t\t\t\tcase TOKEN_LOWER:\n\t\t\t\tcase TOKEN_PERIOD:\n\t\t\t\tcase TOKEN_PIPE:\n\t\t\t\tcase TOKEN_AMPERSAND:\n\t\t\t\tcase TOKEN_COLON:\n\t\t\t\tcase TOKEN_EQUAL_SIGN:\n\t\t\t\t\tparsingType = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_ARROW:\n\t\t\t\t\tisFunction = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\t\tif (parenLevel <= 0 && ! isFunction && ! parsingType)\n\t\t\t\t\t{\n\t\t\t\t\t\tmember = newToken ();\n\t\t\t\t\t\tcopyToken (member, token, false);\n\t\t\t\t\t\tmember->scope = scope;\n\t\t\t\t\t\temitTag (member, varKind);\n\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t}\n\t\t\t\t\texpectingVariable = false;\n\t\t\t\t\tparsingType = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\t\tswitch (token->keyword)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase KEYWORD_enum:\n\t\t\t\t\t\t\tparseEnum (scope, token);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase KEYWORD_as:\n\t\t\t\t\t\tcase KEYWORD_of:\n\t\t\t\t\t\tcase KEYWORD_in:\n\t\t\t\t\t\tcase KEYWORD_await:\n\t\t\t\t\t\tcase KEYWORD_new:\n\t\t\t\t\t\tcase KEYWORD_typeof:\n\t\t\t\t\t\t\tparsingType = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif (nestLevel <= 0)\n\t\t\t\t\t\tparsingType = false;\n\t\t\t\t\tif (token->type != TOKEN_NL)\n\t\t\t\t\t\texpectingVariable = false;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (isType (token, TOKEN_EQUAL_SIGN)\n\t\t\t\t|| isKeyword (token, KEYWORD_function))\n\t\t\t\tmayBeFun = true;\n\t\t\telse if (! isType(token, TOKEN_COMMENT_BLOCK) && nestLevel <= 0)\n\t\t\t\tmayBeFun = false;\n\t\t}\n\t} while (parsed &&\n\t\t\t! ((token->type == TOKEN_SEMICOLON\n\t\t\t\t\t|| (token->type == TOKEN_CLOSE_PAREN && ! isFunction)\n\t\t\t\t\t|| (token->type == TOKEN_NL && ! expectingVariable))\n\t\t\t\t&& ! parsingType && nestLevel <= 0));\n\n\tclearPoolToken (token);\n\n\tTRACE_LEAVE();\n}\n\nMULTI_CHAR_PARSER_DEF (FunctionArgsChars, \"\\n(\", TOKEN_NL, TOKEN_OPEN_PAREN)\nMULTI_CHAR_PARSER_DEF (FunctionArgsAfterParenChars, \"|&=?[]{})\\n:,.@\",\n\t\tTOKEN_PIPE, TOKEN_AMPERSAND, TOKEN_EQUAL_SIGN, TOKEN_QUESTION_MARK,\n\t\tTOKEN_OPEN_SQUARE, TOKEN_CLOSE_SQUARE, TOKEN_OPEN_CURLY, TOKEN_CLOSE_CURLY,\n\t\tTOKEN_CLOSE_PAREN, TOKEN_NL, TOKEN_COLON, TOKEN_COMMA, TOKEN_PERIOD, TOKEN_AT)\nstatic void parseFunctionArgs (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed = false;\n\tbool parsingType = false;\n\tint nestLevel = 0;\n\ttokenInfo *member = NULL;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseFunctionArgsChars,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && token->type != TOKEN_OPEN_PAREN);\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseParens,\n\t\t\t\t\t\t\t\tparseNumber,\n\t\t\t\t\t\t\t\tparseFunctionArgsAfterParenChars,\n\t\t\t\t\t\t\t\tparseArrow,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tif (parsed)\n\t\t{\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_AT:\n\t\t\t\t\tuwiUngetC ('@');\n\t\t\t\t\tparseDecorator (token);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_OPEN_SQUARE:\n\t\t\t\tcase TOKEN_OPEN_CURLY:\n\t\t\t\t\tif (parsingType)\n\t\t\t\t\t\tnestLevel += 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_CLOSE_SQUARE:\n\t\t\t\tcase TOKEN_CLOSE_CURLY:\n\t\t\t\t\tif (parsingType)\n\t\t\t\t\t\tnestLevel -= 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_COMMA:\n\t\t\t\t\tif (nestLevel <= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tparsingType = false;\n\t\t\t\t\t\tnestLevel = 0;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_COLON:\n\t\t\t\tcase TOKEN_EQUAL_SIGN:\n\t\t\t\t\tparsingType = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\t\tif (! parsingType)\n\t\t\t\t\t{\n\t\t\t\t\t\tmember = newToken ();\n\t\t\t\t\t\tcopyToken (member, token, false);\n\t\t\t\t\t\tmember->scope = scope;\n\t\t\t\t\t\temitTag (member, TSTAG_PARAMETER);\n\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while (parsed && token->type != TOKEN_CLOSE_PAREN);\n\n\tTRACE_LEAVE();\n}\n\nMULTI_CHAR_PARSER_DEF (FunctionBodyChars, \"{}\", TOKEN_OPEN_CURLY, TOKEN_CLOSE_CURLY)\nstatic void parseFunctionBody (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed = false;\n\tint nestLevel = 1;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, true,\n\t\t\t\t\t\t\t\tparseOpenCurly,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tNULL);\n\n\t} while (parsed && ! isType (token, TOKEN_OPEN_CURLY));\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, true,\n\t\t\t\t\t\t\t\tparseFunctionBodyChars,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseVarKeyword,\n\t\t\t\t\t\t\t\tparseLetKeyword,\n\t\t\t\t\t\t\t\tparseConstKeyword,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tif (parsed)\n\t\t{\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_OPEN_CURLY:\n\t\t\t\t\tnestLevel += 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_CLOSE_CURLY:\n\t\t\t\t\tnestLevel -= 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\t\tswitch (token->keyword)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase KEYWORD_var:\n\t\t\t\t\t\tcase KEYWORD_let:\n\t\t\t\t\t\t\tparseVariable (false, true, scope, token);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase KEYWORD_const:\n\t\t\t\t\t\t\tparseVariable (true, true, scope, token);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while (parsed && ! (isType (token, TOKEN_CLOSE_CURLY)\n\t\t\t\t\t\t  && nestLevel <= 0));\n\n\tclearPoolToken (token);\n\n\tTRACE_LEAVE();\n}\n\nstatic void parseFunction (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool isGenerator = false;\n\tbool parsed;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseStar,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tif (parsed && isType (token, TOKEN_STAR))\n\t\t\tisGenerator = true;\n\t} while (parsed && token->type != TOKEN_IDENTIFIER);\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\ttoken->scope = scope;\n\n\tconst int nscope = emitTag (token,\n\t\t\t\t\t\t\t\tisGenerator ? TSTAG_GENERATOR : TSTAG_FUNCTION);\n\n\tparseFunctionArgs (nscope, token);\n\tparseFunctionBody (nscope, token);\n\n\tTRACE_LEAVE();\n}\n\nMULTI_CHAR_PARSER_DEF (PropertyTypeChars, \"\\n;|&,)\",\n\t\tTOKEN_NL, TOKEN_SEMICOLON, TOKEN_PIPE, TOKEN_AMPERSAND,\n\t\tTOKEN_COMMA, TOKEN_CLOSE_PAREN)\nstatic void parsePropertyType (tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed = tryParser ((Parser) parseColon, token, true);\n\tbool parsedIdentifier = false;\n\tbool parseReturnValue = false;\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_STAGE(0);\n\t\treturn;\n\t}\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tif (parsedIdentifier)\n\t\t{\n\t\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\t\tparsePropertyTypeChars,\n\t\t\t\t\t\t\t\t\tparseArrow,\n\t\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\t\tparseParens,\n\t\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\t\tparseSquares,\n\t\t\t\t\t\t\t\t\tparseCurlies,\n\t\t\t\t\t\t\t\t\tNULL);\n\n\t\t\tif (isType (token, TOKEN_PIPE) || isType (token, TOKEN_AMPERSAND))\n\t\t\t\tparsedIdentifier = false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\t\tparsePropertyTypeChars,\n\t\t\t\t\t\t\t\t\tparseArrow,\n\t\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\t\tparseParens,\n\t\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\t\tparseSquares,\n\t\t\t\t\t\t\t\t\tparseCurlies,\n\t\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\t\tNULL);\n\n\t\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\t\tparsedIdentifier = true;\n\t\t}\n\n\n\t\tif (isType (token, TOKEN_ARROW))\n\t\t\tparseReturnValue = true;\n\t} while (parsed\n\t\t\t&& ! isType (token, TOKEN_CLOSE_PAREN)\n\t\t\t&& ! isType (token, TOKEN_SEMICOLON)\n\t\t\t&& ! isType (token, TOKEN_COMMA)\n\t\t\t&& ! (parseReturnValue && (\n\t\t\t\t\tisType (token, TOKEN_PARENS)\n\t\t\t\t\t|| isType (token, TOKEN_CURLIES)\n\t\t\t\t\t|| isType (token, TOKEN_SQUARES))));\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_STAGE(1);\n\t\treturn;\n\t}\n\n\tif (isType (token, TOKEN_CLOSE_PAREN))\n\t\tuwiUngetC (')');\n\n\tclearPoolToken (token);\n\n\tTRACE_LEAVE();\n}\n\nMULTI_CHAR_PARSER_DEF (ConstructorParamsChars, \"\\n(\", TOKEN_NL, TOKEN_OPEN_PAREN)\nMULTI_CHAR_PARSER_DEF (ConstructorParamsAfterParenChars, \"\\n:,)@\",\n\t\tTOKEN_NL, TOKEN_COLON, TOKEN_COMMA, TOKEN_CLOSE_PAREN, TOKEN_AT)\nstatic void parseConstructorParams (const int classScope, const int constrScope,\n\t\t\t\t\t\t\t\t\ttokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed = false;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseConstructorParamsChars,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && ! isType (token, TOKEN_OPEN_PAREN));\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE();\n\t\treturn;\n\t}\n\n\ttokenInfo *member = NULL;\n\tint visibility = 0;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseConstructorParamsAfterParenChars,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparsePrivateKeyword,\n\t\t\t\t\t\t\t\tparseProtectedKeyword,\n\t\t\t\t\t\t\t\tparsePublicKeyword,\n\t\t\t\t\t\t\t\tparseReadonlyKeyword,\n\t\t\t\t\t\t\t\tparseStaticKeyword,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tif (parsed)\n\t\t{\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_AT:\n\t\t\t\t\tuwiUngetC ('@');\n\t\t\t\t\tparseDecorator (token);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\t\tswitch (token->keyword)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase KEYWORD_private:\n\t\t\t\t\t\tcase KEYWORD_public:\n\t\t\t\t\t\tcase KEYWORD_protected:\n\t\t\t\t\t\t\tvisibility = token->keyword;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_COLON:\n\t\t\t\t\tuwiUngetC (':');\n\t\t\t\t\tparsePropertyType (token);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\t\tmember = newToken ();\n\t\t\t\t\tcopyToken (member, token, false);\n\t\t\t\t\tif (visibility)\n\t\t\t\t\t{\n\t\t\t\t\t\tmember->accessKeyword = visibility;\n\t\t\t\t\t\tmember->scope = classScope;\n\t\t\t\t\t\temitTag (member, TSTAG_PROPERTY);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tmember->scope = constrScope;\n\t\t\t\t\t\temitTag (member, TSTAG_PARAMETER);\n\t\t\t\t\t}\n\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\tmember = NULL;\n\t\t\t\t\tvisibility = 0;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while (parsed && ! isType (token, TOKEN_CLOSE_PAREN));\n\n\tTRACE_LEAVE();\n}\n\nMULTI_CHAR_PARSER_DEF (ClassBodyChars, \"\\n,{\", TOKEN_NL, TOKEN_COMMA, TOKEN_OPEN_CURLY)\nMULTI_CHAR_PARSER_DEF (ClassBodyAfterCurlyChars, \"\\n}*@(?!:;=-+/^<>.,|&\",\n\t\tTOKEN_NL, TOKEN_CLOSE_CURLY, TOKEN_STAR, TOKEN_AT, TOKEN_OPEN_PAREN,\n\t\tTOKEN_QUESTION_MARK, TOKEN_BANG, TOKEN_COLON, TOKEN_SEMICOLON, TOKEN_EQUAL_SIGN,\n\t\tTOKEN_MINUS, TOKEN_PLUS, TOKEN_DIV, TOKEN_POWER,\n\t\tTOKEN_LOWER, TOKEN_GREATER, TOKEN_PERIOD, TOKEN_COMMA,\n\t\tTOKEN_PIPE, TOKEN_AMPERSAND)\nstatic void parseClassBody (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed = false;\n\tvString *inheritance = NULL;\n\n\t//parse until {\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseClassBodyChars,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseExtendsKeyword,\n\t\t\t\t\t\t\t\tparseImplementsKeyword,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tif (token->type == TOKEN_KEYWORD\n\t\t\t&& (token->keyword == KEYWORD_extends\n\t\t\t\t|| token->keyword == KEYWORD_implements)\n\t\t\t&& inheritance == NULL)\n\t\t\tinheritance = vStringNew ();\n\t\telse if (inheritance && token->type == TOKEN_IDENTIFIER)\n\t\t\tvStringJoin (inheritance, ',', token->string);\n\t} while (parsed && token->type != TOKEN_OPEN_CURLY);\n\n\tif (! parsed)\n\t{\n\t\tvStringDelete (inheritance); /* NULL is acceptable. */\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\tif (inheritance)\n\t{\n\t\ttagEntryInfo *klass = getEntryInCorkQueue (scope);\n\t\tif (klass)\n\t\t{\n\t\t\tklass->extensionFields.inheritance = vStringDeleteUnwrap (inheritance);\n\t\t\tinheritance = NULL;\n\t\t}\n\t\tvStringDelete (inheritance);\n\t}\n\n\ttokenInfo *member = NULL;\n\tbool isGenerator = false;\n\tbool parsingValue = false;\n\tint visibility = 0;\n\tbool isStatic = false;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseAsyncKeyword,\n\t\t\t\t\t\t\t\tparseConstructorKeyword,\n\t\t\t\t\t\t\t\tparseNewKeyword,\n\t\t\t\t\t\t\t\tparsePrivateKeyword,\n\t\t\t\t\t\t\t\tparseProtectedKeyword,\n\t\t\t\t\t\t\t\tparsePublicKeyword,\n\t\t\t\t\t\t\t\tparseReadonlyKeyword,\n\t\t\t\t\t\t\t\tparseStaticKeyword,\n\t\t\t\t\t\t\t\tparseNumber,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseTypeofKeyword,\n\t\t\t\t\t\t\t\tparseClassBodyAfterCurlyChars,\n\t\t\t\t\t\t\t\tparseSquares,\n\t\t\t\t\t\t\t\tparseCurlies,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tif (parsed)\n\t\t{\n\t\t\tswitch (token->type)\n\t\t\t{\n\t\t\t\tcase TOKEN_AT:\n\t\t\t\t\tuwiUngetC ('@');\n\t\t\t\t\tparseDecorator (token);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\t\tswitch (token->keyword)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase KEYWORD_constructor:\n\t\t\t\t\t\t\tif (member)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\temitTag (member, TSTAG_PROPERTY);\n\t\t\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\t\t\tmember = NULL;\n\t\t\t\t\t\t\t\tisGenerator = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tmember = newToken ();\n\t\t\t\t\t\t\tcopyToken (member, token, false);\n\t\t\t\t\t\t\tmember->scope = scope;\n\n\t\t\t\t\t\t\tif (visibility)\n\t\t\t\t\t\t\t\tmember->accessKeyword = visibility;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tmember->accessKeyword = KEYWORD_public;\n\n\t\t\t\t\t\t\tconst int nscope = emitTag (member, TSTAG_METHOD);\n\t\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\t\tmember = NULL;\n\t\t\t\t\t\t\tvisibility = 0;\n\n\t\t\t\t\t\t\tparseConstructorParams (scope, nscope, token);\n\n\t\t\t\t\t\t\tparseFunctionBody (nscope, token);\n\t\t\t\t\t\t\tparsingValue = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase KEYWORD_private:\n\t\t\t\t\t\tcase KEYWORD_public:\n\t\t\t\t\t\tcase KEYWORD_protected:\n\t\t\t\t\t\t\tif (member)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\temitTag (member, TSTAG_PROPERTY);\n\t\t\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\t\t\tmember = NULL;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvisibility = token->keyword;\n\t\t\t\t\t\t\tparsingValue = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase KEYWORD_static:\n\t\t\t\t\t\t\tif (member)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\temitTag (member, TSTAG_PROPERTY);\n\t\t\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\t\t\tmember = NULL;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tisStatic = true;\n\t\t\t\t\t\t\tparsingValue = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase KEYWORD_new:\n\t\t\t\t\t\tcase KEYWORD_typeof:\n\t\t\t\t\t\t\tparsingValue = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tisGenerator = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_EQUAL_SIGN:\n\t\t\t\t\tif (member)\n\t\t\t\t\t{\n\t\t\t\t\t\temitTag (member, TSTAG_PROPERTY);\n\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\tmember = NULL;\n\t\t\t\t\t\tisGenerator = false;\n\t\t\t\t\t}\n\t\t\t\t\tparsingValue = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_BANG:\n\t\t\t\tcase TOKEN_QUESTION_MARK:\n\t\t\t\t\tbreak;\t\t/* Just consuming the token */\n\t\t\t\tcase TOKEN_COLON:\n\t\t\t\t\tuwiUngetC (':');\n\t\t\t\t\tparsePropertyType (token);\n\t\t\t\tcase TOKEN_SEMICOLON:\n\t\t\t\t\tif (member)\n\t\t\t\t\t{\n\t\t\t\t\t\temitTag (member, TSTAG_PROPERTY);\n\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\tmember = NULL;\n\t\t\t\t\t\tisGenerator = false;\n\t\t\t\t\t\tvisibility = 0;\n\t\t\t\t\t\tisStatic = false;\n\t\t\t\t\t}\n\t\t\t\t\tparsingValue = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_STAR:\n\t\t\t\t\tif (!parsingValue)\n\t\t\t\t\t{\n\t\t\t\t\t\tisGenerator = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t/* FALLTHROUGH */\n\t\t\t\tcase TOKEN_MINUS:\n\t\t\t\tcase TOKEN_PLUS:\n\t\t\t\tcase TOKEN_DIV:\n\t\t\t\tcase TOKEN_POWER:\n\t\t\t\tcase TOKEN_GREATER:\n\t\t\t\tcase TOKEN_LOWER:\n\t\t\t\tcase TOKEN_PERIOD:\n\t\t\t\tcase TOKEN_PIPE:\n\t\t\t\tcase TOKEN_AMPERSAND:\n\t\t\t\t\tparsingValue = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_STRING:\n\t\t\t\tcase TOKEN_COMMA:\n\t\t\t\tcase TOKEN_NUMBER:\n\t\t\t\tcase TOKEN_SQUARES:\n\t\t\t\tcase TOKEN_CURLIES:\n\t\t\t\t\tparsingValue = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_OPEN_PAREN:\n\t\t\t\t\tuwiUngetC ('(');\n\t\t\t\t\tif (! member) {\n\t\t\t\t\t\tparsed = tryParser (parseParens, token, false);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst int nscope = emitTag (member,\n\t\t\t\t\t\t\t\t\t\t\t\tisGenerator\n\t\t\t\t\t\t\t\t\t\t\t\t? TSTAG_GENERATOR\n\t\t\t\t\t\t\t\t\t\t\t\t: TSTAG_METHOD);\n\n\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\tmember = NULL;\n\n\t\t\t\t\tparseFunctionArgs (nscope, token);\n\t\t\t\t\tparseFunctionBody (nscope, token);\n\n\t\t\t\t\tisGenerator = false;\n\t\t\t\t\tvisibility = 0;\n\t\t\t\t\tisStatic = false;\n\t\t\t\t\tparsingValue = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\t\t\tif (parsingValue)\n\t\t\t\t\t\tisGenerator = false;\n\t\t\t\t\telse {\n\t\t\t\t\t\tif (member)\n\t\t\t\t\t\t\tdeleteToken (member);\n\t\t\t\t\t\tmember = newToken ();\n\t\t\t\t\t\tcopyToken (member, token, false);\n\t\t\t\t\t\tmember->scope = scope;\n\t\t\t\t\t\tmember->isStatic = isStatic;\n\t\t\t\t\t\tif (visibility)\n\t\t\t\t\t\t\tmember->accessKeyword = visibility;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tmember->accessKeyword = KEYWORD_public;\n\t\t\t\t\t}\n\n\t\t\t\t\tparsingValue = false;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tisGenerator = false;\n\t\t\t\t\tvisibility = 0;\n\t\t\t\t\tisStatic = false;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while (parsed && token->type != TOKEN_CLOSE_CURLY);\n\n\tif (parsed && member)\n\t{\n\t\temitTag (member, TSTAG_PROPERTY);\n\t\tdeleteToken (member);\n\t}\n\telse if (member)\n\t\tdeleteToken (member);\n\n\tTRACE_LEAVE();\n}\n\nstatic void parseClass (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed = false;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseNewLine,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && token->type != TOKEN_IDENTIFIER);\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\ttoken->scope = scope;\n\tconst int nscope = emitTag (token, TSTAG_CLASS);\n\n\tparseClassBody (nscope, token);\n\n\tTRACE_LEAVE();\n}\n\nMULTI_CHAR_PARSER_DEF (NamespaceBodyChars, \"\\n{\", TOKEN_NL, TOKEN_OPEN_CURLY)\nMULTI_CHAR_PARSER_DEF (NamespaceBodyAfterCurlyChars, \"@{}()[]\",\n\t\tTOKEN_AT, TOKEN_OPEN_CURLY, TOKEN_CLOSE_CURLY, TOKEN_OPEN_PAREN,\n\t\tTOKEN_CLOSE_PAREN, TOKEN_OPEN_SQUARE, TOKEN_CLOSE_SQUARE)\nstatic void parseNamespaceBody (const int scope, tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed = false;\n\n\t//parse until {\n\tdo\n\t{\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseNamespaceBodyChars,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && token->type != TOKEN_OPEN_CURLY);\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\tint parenLvl = 0;\n\tint squareLvl = 0;\n\tint curlyLvl = 1;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, true,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseInterfaceKeyword,\n\t\t\t\t\t\t\t\tparseTypeKeyword,\n\t\t\t\t\t\t\t\tparseEnumKeyword,\n\t\t\t\t\t\t\t\tparseFunctionKeyword,\n\t\t\t\t\t\t\t\tparseClassKeyword,\n\t\t\t\t\t\t\t\tparseVarKeyword,\n\t\t\t\t\t\t\t\tparseLetKeyword,\n\t\t\t\t\t\t\t\tparseConstKeyword,\n\t\t\t\t\t\t\t\tparseNamespaceBodyAfterCurlyChars,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tswitch (token->type)\n\t\t{\n\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\tswitch (token->keyword)\n\t\t\t\t{\n\t\t\t\t\tcase KEYWORD_interface:\n\t\t\t\t\t\tparseInterface (scope, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_type:\n\t\t\t\t\t\tparseType (scope, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_enum:\n\t\t\t\t\t\tparseEnum (scope, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_function:\n\t\t\t\t\t\tparseFunction (scope, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_class:\n\t\t\t\t\t\tparseClass (scope, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_var:\n\t\t\t\t\tcase KEYWORD_let:\n\t\t\t\t\t\tparseVariable (false, false, scope, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_const:\n\t\t\t\t\t\tparseVariable (true, false, scope, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_AT:\n\t\t\t\tuwiUngetC ('@');\n\t\t\t\tparseDecorator (token);\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_OPEN_CURLY:\n\t\t\t\tcurlyLvl += 1;\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_OPEN_SQUARE:\n\t\t\t\tsquareLvl += 1;\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_OPEN_PAREN:\n\t\t\t\tparenLvl += 1;\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_CLOSE_CURLY:\n\t\t\t\tcurlyLvl -= 1;\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_CLOSE_SQUARE:\n\t\t\t\tsquareLvl -= 1;\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_CLOSE_PAREN:\n\t\t\t\tparenLvl -= 1;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t} while (parsed\n\t\t\t && ! (isType (token, TOKEN_CLOSE_CURLY)\n\t\t\t\t   && parenLvl <= 0 && squareLvl <= 0 && curlyLvl <= 0));\n\n\tTRACE_LEAVE();\n}\n\nstatic void parseNamespace (tokenInfo *const token)\n{\n\tTRACE_ENTER();\n\n\tbool parsed = false;\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, false,\n\t\t\t\t\t\t\t\tparseNewLine,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseFQIdentifier,\n\t\t\t\t\t\t\t\tNULL);\n\t} while (parsed && token->type != TOKEN_IDENTIFIER);\n\n\tif (! parsed)\n\t{\n\t\tTRACE_LEAVE_IN_THE_MIDDLE();\n\t\treturn;\n\t}\n\n\tconst int scope = emitTag (token, TSTAG_NAMESPACE);\n\n\tparseNamespaceBody (scope, token);\n\n\tTRACE_LEAVE();\n}\n\nstatic void parseTsFile (tokenInfo *const token)\n{\n\tbool parsed;\n\n\tTRACE_ENTER();\n\n\tdo\n\t{\n\t\tclearPoolToken (token);\n\n\t\tparsed = tryInSequence (token, true,\n\t\t\t\t\t\t\t\tparseComment,\n\t\t\t\t\t\t\t\tparseGeneric,\n\t\t\t\t\t\t\t\tparseStringSQuote,\n\t\t\t\t\t\t\t\tparseStringDQuote,\n\t\t\t\t\t\t\t\tparseStringTemplate,\n\t\t\t\t\t\t\t\tparseStringRegex,\n\t\t\t\t\t\t\t\tparseInterfaceKeyword,\n\t\t\t\t\t\t\t\tparseTypeKeyword,\n\t\t\t\t\t\t\t\tparseEnumKeyword,\n\t\t\t\t\t\t\t\tparseFunctionKeyword,\n\t\t\t\t\t\t\t\tparseClassKeyword,\n\t\t\t\t\t\t\t\tparseNamespaceKeyword,\n\t\t\t\t\t\t\t\tparseVarKeyword,\n\t\t\t\t\t\t\t\tparseLetKeyword,\n\t\t\t\t\t\t\t\tparseConstKeyword,\n\t\t\t\t\t\t\t\tparseAt,\n\t\t\t\t\t\t\t\tNULL);\n\n\t\tswitch (token->type)\n\t\t{\n\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\tswitch (token->keyword)\n\t\t\t\t{\n\t\t\t\t\tcase KEYWORD_interface:\n\t\t\t\t\t\tparseInterface (CORK_NIL, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_type:\n\t\t\t\t\t\tparseType (CORK_NIL, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_enum:\n\t\t\t\t\t\tparseEnum (CORK_NIL, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_function:\n\t\t\t\t\t\tparseFunction (CORK_NIL, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_class:\n\t\t\t\t\t\tparseClass (CORK_NIL, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_namespace:\n\t\t\t\t\t\tparseNamespace (token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_var:\n\t\t\t\t\tcase KEYWORD_let:\n\t\t\t\t\t\tparseVariable (false, false, CORK_NIL, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KEYWORD_const:\n\t\t\t\t\t\tparseVariable (true, false, CORK_NIL, token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase TOKEN_AT:\n\t\t\t\tuwiUngetC ('@');\n\t\t\t\tparseDecorator (token);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t} while (parsed);\n\n\tTRACE_LEAVE();\n}\n\nstatic void findTsTags (void)\n{\n\tTRACE_ENTER();\n\n\tuwiActivate (256);\n\n\ttokenInfo *const token = newToken ();\n\n\tparseTsFile (token);\n\n\tdeleteToken (token);\n\n\tuwiDeactivate (&tsUwiStats);\n\n\tTRACE_LEAVE();\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_ts = language;\n\n\tTokenPool = objPoolNew (16, newPoolToken, deletePoolToken, clearPoolToken,\n\t\t\t\t\t\t\tNULL);\n}\n\nstatic void finalize (langType language CTAGS_ATTR_UNUSED, bool initialized)\n{\n\tif (! initialized)\n\t\treturn;\n\n\tobjPoolDelete (TokenPool);\n}\n\nstatic void initStats (langType language CTAGS_ATTR_UNUSED)\n{\n\tuwiStatsInit (&tsUwiStats);\n}\nstatic void printStats (langType language CTAGS_ATTR_UNUSED)\n{\n\tuwiStatsPrint (&tsUwiStats);\n}\n\n/* Create parser definition structure */\nextern parserDefinition *TypeScriptParser (void)\n{\n\tstatic const char *const extensions [] = { \"ts\", NULL };\n\tparserDefinition *const def = parserNew (\"TypeScript\");\n\tdef->extensions = extensions;\n\tdef->kindTable  = TsKinds;\n\tdef->kindCount  = ARRAY_SIZE (TsKinds);\n\tdef->fieldTable = TsFields;\n\tdef->fieldCount = ARRAY_SIZE (TsFields);\n\tdef->parser     = findTsTags;\n\tdef->initialize = initialize;\n\tdef->finalize   = finalize;\n\tdef->keywordTable = TsKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (TsKeywordTable);\n\tdef->useCork = CORK_QUEUE;\n\tdef->requestAutomaticFQTag = true;\n\n\tdef->initStats = initStats;\n\tdef->printStats = printStats;\n\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/typespec.c",
    "content": "/*\n*   Copyright (c) 2025, Kaisheng Xu\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains code for generating tags for TypeSpec language files\n*   (https://microsoft.github.io/typespec/)\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"debug.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"vstring.h\"\n#include \"keyword.h\"\n#include \"entry.h\"\n#include \"routines.h\"\n#include <string.h>\n\n#define SCOPE_SEPARATOR \".\"\n\ntypedef enum {\n\tK_NAMESPACE,\n\tK_ENUM,\n\tK_OPERATION,\n\tK_INTERFACE,\n\tK_MODEL,\n\tK_UNION,\n\tK_ALIAS,\n\tK_PROPERTY,\n\tK_ENUMERATOR,\n\tCOUNT_KIND\n} typeSpecKind;\n\nstatic kindDefinition TypeSpecKinds[COUNT_KIND] = {\n\t{ true, 'n', \"namespace\",\t\"namespaces\" },\n\t{ true, 'g', \"enum\",\t\t\"enumeration names\" },\n\t{ true, 'o', \"operation\",\t\"operations\" },\n\t{ true, 'i', \"interface\",\t\"interfaces\" },\n\t{ true, 'm', \"model\",\t\t\"models\" },\n\t{ true, 'u', \"union\",\t\t\"unions\" },\n\t{ true, 'a', \"alias\",\t\t\"aliases\" },\n\t{ true, 'p', \"property\",\t\"properties\" },\n\t{ true, 'e', \"enumerator\",\t\"enumerators (values inside an enumeration)\", .version = 1 },\n};\n\ntypedef enum eTokenType {\n\tTOKEN_UNDEFINED,\n\tTOKEN_EOF,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_SEMICOLON,\n\tTOKEN_COLON,\n\tTOKEN_COMMA,\n\tTOKEN_KEYWORD,\n\tTOKEN_IDENTIFIER,\n\tTOKEN_STRING,\n\tTOKEN_PERIOD,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_OPEN_ANGLE,\n\tTOKEN_CLOSE_ANGLE,\n\tTOKEN_EQUAL_SIGN,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_DECORATOR,\n\tTOKEN_SPREAD\n} tokenType;\n\nenum {\n\tKEYWORD_namespace,\n\tKEYWORD_enum,\n\tKEYWORD_op,\n\tKEYWORD_interface,\n\tKEYWORD_model,\n\tKEYWORD_union,\n\tKEYWORD_alias,\n\tKEYWORD_using,\n\tKEYWORD_import,\n\tKEYWORD_is,\n\tKEYWORD_extends\n};\n\n/* We need an integer that is not an unsigned to allow KEYWORD_NONE. */\ntypedef int keywordId;\n\nstatic const keywordTable TypeSpecKeywordTable[] = {\n\t{ \"namespace\",\tKEYWORD_namespace },\n\t{ \"enum\",\t\tKEYWORD_enum },\n\t{ \"op\",\t\t\tKEYWORD_op },\n\t{ \"interface\",\tKEYWORD_interface },\n\t{ \"model\",\t\tKEYWORD_model },\n\t{ \"union\",\t\tKEYWORD_union },\n\t{ \"alias\",\t\tKEYWORD_alias },\n\t{ \"using\",\t\tKEYWORD_using },\n\t{ \"import\",\t\tKEYWORD_import },\n\t{ \"is\",\t\t KEYWORD_is },\n\t{ \"extends\",\tKEYWORD_extends }\n};\n\ntypedef struct {\n\ttokenType\t\ttype;\n\tkeywordId\t\tkeyword;\n\tvString *\t\tstring;\n\tint\t\t\t\tscope;\n\tunsigned long\tlineNumber;\n\tMIOPos\t\t\tfilePosition;\n} tokenInfo;\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\n\ttoken->type\t\t\t= TOKEN_UNDEFINED;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->string\t\t= vStringNew ();\n\ttoken->scope\t\t= CORK_NIL;\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\treturn token;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tvStringDelete (token->string);\n\teFree (token);\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const src)\n{\n\tdest->lineNumber = src->lineNumber;\n\tdest->filePosition = src->filePosition;\n\tdest->type = src->type;\n\tvStringCopy (dest->string, src->string);\n}\n\nstatic void setScope (tokenInfo *const token, int scope)\n{\n\ttoken->scope = scope;\n}\n\nstatic bool isIdentChar (const int c)\n{\n\treturn (isalnum (c) || c == '_' || c == '$' || c >= 0x80);\n}\n\nstatic bool isSpace (int c)\n{\n\treturn (c == '\\t' || c == ' ' || c == '\\v' ||\n\t\t\tc == '\\n' || c == '\\r' || c == '\\f');\n}\n\nstatic int skipWhitespace (int c)\n{\n\twhile (isSpace (c))\n\t\tc = getcFromInputFile ();\n\treturn c;\n}\n\nstatic int skipSingleComment (void)\n{\n\tint c;\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t} while (c != EOF && c != '\\n');\n\treturn c;\n}\n\nstatic int skipMultiComment (void)\n{\n\tint c = getcFromInputFile ();\n\tint next = getcFromInputFile ();\n\n\twhile (c != EOF && !(c == '*' && next == '/'))\n\t{\n\t\tc = next;\n\t\tnext = getcFromInputFile ();\n\t}\n\n\treturn getcFromInputFile ();\n}\n\nstatic void parseString (vString *const string, const int delimiter)\n{\n\twhile (true)\n\t{\n\t\tint c = getcFromInputFile ();\n\n\t\tif (c == '\\\\' && (c = getcFromInputFile ()) != EOF)\n\t\t\tvStringPut (string, c);\n\t\telse if (c == EOF || c == delimiter)\n\t\t\tbreak;\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\nstatic void parseIdentifier (vString *const string, const int firstChar)\n{\n\tint c = firstChar;\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isIdentChar (c));\n\tungetcToInputFile (c);\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\tint c;\n\n\ttoken->type\t\t= TOKEN_UNDEFINED;\n\tvStringClear (token->string);\n\ngetNextChar:\n\n\tc = getcFromInputFile ();\n\tc = skipWhitespace (c);\n\n\ttoken->lineNumber   = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\n\tswitch (c)\n\t{\n\t\tcase EOF: token->type = TOKEN_EOF;\t\t\t\t\tbreak;\n\t\tcase '(': token->type = TOKEN_OPEN_PAREN;\t\t\tbreak;\n\t\tcase ')': token->type = TOKEN_CLOSE_PAREN;\t\t\tbreak;\n\t\tcase ';': token->type = TOKEN_SEMICOLON;\t\t\tbreak;\n\t\tcase ',': token->type = TOKEN_COMMA;\t\t\t\tbreak;\n\t\tcase '.':\n\t\t{\n\t\t\t/* Handle ... (spread) operator */\n\t\t\tint c1 = getcFromInputFile ();\n\t\t\tint c2 = getcFromInputFile ();\n\t\t\tif (c1 == '.' && c2 == '.')\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_SPREAD;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (c2);\n\t\t\t\tungetcToInputFile (c1);\n\t\t\t\ttoken->type = TOKEN_PERIOD;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase ':': token->type = TOKEN_COLON;\t\t\t\tbreak;\n\t\tcase '{': token->type = TOKEN_OPEN_CURLY;\t\t\tbreak;\n\t\tcase '}': token->type = TOKEN_CLOSE_CURLY;\t\t\tbreak;\n\t\tcase '<': token->type = TOKEN_OPEN_ANGLE;\t\t\tbreak;\n\t\tcase '>': token->type = TOKEN_CLOSE_ANGLE;\t\t\tbreak;\n\t\tcase '=': token->type = TOKEN_EQUAL_SIGN;\t\t\tbreak;\n\t\tcase '[': token->type = TOKEN_OPEN_SQUARE;\t\t\tbreak;\n\t\tcase ']': token->type = TOKEN_CLOSE_SQUARE;\t\t\tbreak;\n\n\t\tcase '\\'':\n\t\tcase '\"':\n\t\t\ttoken->type = TOKEN_STRING;\n\t\t\tparseString (token->string, c);\n\t\t\tbreak;\n\n\t\tcase '/':\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (d == '/')  /* single-line comment */\n\t\t\t{\n\t\t\t\tskipSingleComment ();\n\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\telse if (d == '*')  /* multi-line comment */\n\t\t\t{\n\t\t\t\tskipMultiComment ();\n\t\t\t\tgoto getNextChar;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase '@':  /* decorator */\n\t\t\ttoken->type = TOKEN_DECORATOR;\n\t\t\tc = getcFromInputFile ();\n\t\t\tparseIdentifier (token->string, c);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tif (! isIdentChar (c))\n\t\t\t\ttoken->type = TOKEN_UNDEFINED;\n\t\t\telse\n\t\t\t{\n\t\t\t\tparseIdentifier (token->string, c);\n\t\t\t\ttoken->keyword = lookupCaseKeyword (\n\t\t\t\t\tvStringValue (token->string), getInputLanguage ());\n\t\t\t\tif (token->keyword == KEYWORD_NONE)\n\t\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\t\telse\n\t\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t\t}\n\t\t\tbreak;\n\t}\n}\n\nstatic void initTypeSpecEntry (tagEntryInfo *const e, const tokenInfo *const token,\n\t\t\t\t\t\t\t  const typeSpecKind kind)\n{\n\tinitTagEntry (e, vStringValue (token->string), kind);\n\n\te->lineNumber\t= token->lineNumber;\n\te->filePosition\t= token->filePosition;\n\n\te->extensionFields.scopeIndex = token->scope;\n}\n\nstatic int makeTypeSpecTag (const tokenInfo *const token, const typeSpecKind kind)\n{\n\ttagEntryInfo e;\n\tinitTypeSpecEntry (&e, token, kind);\n\treturn makeTagEntry (&e);\n}\n\nstatic void enterScope (tokenInfo *const parentToken, int scope);\n\nstatic void skipTypeParameters(tokenInfo *const token)\n{\n\tint depth = 1;\n\n\twhile (depth > 0 && token->type != TOKEN_EOF)\n\t{\n\t\treadToken(token);\n\n\t\tif (token->type == TOKEN_OPEN_ANGLE)\n\t\t\tdepth++;\n\t\telse if (token->type == TOKEN_CLOSE_ANGLE)\n\t\t\tdepth--;\n\t}\n\treadToken(token);\n}\n\nstatic void skipToSemicolon(tokenInfo *const token)\n{\n\twhile (token->type != TOKEN_SEMICOLON && token->type != TOKEN_EOF)\n\t{\n\t\treadToken(token);\n\t}\n}\n\nstatic void parseNamespace(tokenInfo *const token)\n{\n\tvString *name = vStringNew();\n\n\t/* Read namespace components */\n\tdo\n\t{\n\t\treadToken(token);\n\n\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t{\n\t\t\tif (!vStringIsEmpty(name))\n\t\t\t\tvStringCatS(name, SCOPE_SEPARATOR);\n\t\t\tvStringCat(name, token->string);\n\n\t\t\treadToken(token);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t} while (token->type == TOKEN_PERIOD);\n\n\t/* Create namespace tag */\n\tvStringCopy(token->string, name);\n\tint namespaceIndex = makeTypeSpecTag(token, K_NAMESPACE);\n\n\t/* Parse namespace body */\n\tif (token->type == TOKEN_SEMICOLON || token->type == TOKEN_OPEN_CURLY)\n\t{\n\t\tenterScope(token, namespaceIndex);\n\t}\n\n\tvStringDelete(name);\n}\n\nstatic void parseEnum(tokenInfo *const parentToken)\n{\n\ttokenInfo *token = newToken();\n\tcopyToken (token, parentToken);\n\tsetScope(token, parentToken->scope);\n\n\treadToken(token);\n\n\tif (token->type == TOKEN_IDENTIFIER)\n\t{\n\t\tint enumIndex = makeTypeSpecTag(token, K_ENUM);\n\t\treadToken(token);\n\n\t\tif (token->type == TOKEN_OPEN_CURLY)\n\t\t{\n\t\t\t/* Parse enum body */\n\t\t\twhile (token->type != TOKEN_CLOSE_CURLY && token->type != TOKEN_EOF)\n\t\t\t{\n\t\t\t\tif (token->type == TOKEN_IDENTIFIER)\n\t\t\t\t{\n\t\t\t\t\t/* Create tag for enumerator */\n\t\t\t\t\tsetScope (token, enumIndex);\n\t\t\t\t\tmakeTypeSpecTag(token, K_ENUMERATOR);\n\t\t\t\t\treadToken(token);\n\n\t\t\t\t\t/* Skip value assignment if any */\n\t\t\t\t\tif (token->type == TOKEN_COLON)\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken(token);\n\t\t\t\t\t\t/* Skip the value */\n\t\t\t\t\t\twhile (token->type != TOKEN_COMMA &&\n\t\t\t\t\t\t\t   token->type != TOKEN_CLOSE_CURLY &&\n\t\t\t\t\t\t\t   token->type != TOKEN_EOF)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treadToken(token);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t/* Skip comma if present */\n\t\t\t\t\tif (token->type == TOKEN_COMMA)\n\t\t\t\t\t\treadToken(token);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\treadToken(token);\n\t\t\t}\n\t\t}\n\t}\n\n\tdeleteToken (token);\n}\n\nstatic void parseProperty(tokenInfo *const token)\n{\n\tif (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_STRING)\n\t{\n\t\t/* This is a property */\n\t\tmakeTypeSpecTag(token, K_PROPERTY);\n\n\t\t/* Skip type declaration, modifiers, etc. until ; or , */\n\t\twhile (token->type != TOKEN_SEMICOLON &&\n\t\t\t   token->type != TOKEN_COMMA &&\n\t\t\t   token->type != TOKEN_CLOSE_CURLY &&\n\t\t\t   token->type != TOKEN_EOF)\n\t\t{\n\t\t/* Skip generic parameters if any */\n\t\t\treadToken(token);\n\t\t\tif (token->type == TOKEN_OPEN_ANGLE)\n\t\t\t{\n\t\t\t\tskipTypeParameters(token);\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void parseOperation(tokenInfo *const token)\n{\n\treadToken(token);\n\n\tif (token->type == TOKEN_IDENTIFIER)\n\t{\n\t\tmakeTypeSpecTag(token, K_OPERATION);\n\t\treadToken(token);\n\n\t\t/* Skip generic parameters if any */\n\t\tif (token->type == TOKEN_OPEN_ANGLE)\n\t\t{\n\t\t\tskipTypeParameters(token);\n\t\t}\n\n\t\t/* Handle \"is\" relationship */\n\t\tif (token->type == TOKEN_KEYWORD && token->keyword == KEYWORD_is)\n\t\t{\n\t\t\t/* Skip expression after \"is\" */\n\t\t\tdo {\n\t\t\t\treadToken(token);\n\n\t\t\t\tif (token->type == TOKEN_OPEN_ANGLE)\n\t\t\t\t{\n\t\t\t\t\tskipTypeParameters(token);\n\t\t\t\t}\n\n\t\t\t\tif (token->type == TOKEN_SEMICOLON)\n\t\t\t\t\tbreak;\n\n\t\t\t} while (token->type != TOKEN_SEMICOLON && token->type != TOKEN_EOF);\n\t\t}\n\t}\n}\n\nstatic void parseInterface(tokenInfo *const token)\n{\n\treadToken(token);\n\n\tif (token->type == TOKEN_IDENTIFIER)\n\t{\n\t\tint ifaceIndex = makeTypeSpecTag(token, K_INTERFACE);\n\t\treadToken(token);\n\n\t\t/* Skip extends clause */\n\t\tif (token->type == TOKEN_KEYWORD && token->keyword == KEYWORD_extends)\n\t\t{\n\t\t\twhile (token->type != TOKEN_OPEN_CURLY && token->type != TOKEN_EOF)\n\t\t\t{\n\t\t\t\treadToken(token);\n\t\t\t}\n\t\t}\n\n\t\tif (token->type == TOKEN_OPEN_CURLY)\n\t\t{\n\t\t\tenterScope(token, ifaceIndex);\n\t\t}\n\t}\n}\n\nstatic void parseModel(tokenInfo *const token)\n{\n\treadToken(token);\n\n\tif (token->type == TOKEN_IDENTIFIER)\n\t{\n\t\tint modelIndex = makeTypeSpecTag(token, K_MODEL);\n\t\treadToken(token);\n\n\t\t/* Skip extends clause if any */\n\t\tif (token->type == TOKEN_KEYWORD && token->keyword == KEYWORD_extends)\n\t\t{\n\t\t\twhile (token->type != TOKEN_OPEN_CURLY && token->type != TOKEN_EOF)\n\t\t\t{\n\t\t\t\treadToken(token);\n\t\t\t}\n\t\t}\n\n\t\tif (token->type == TOKEN_OPEN_CURLY)\n\t\t{\n\t\t\tenterScope(token, modelIndex);\n\t\t}\n\t}\n}\n\nstatic void parseUnion(tokenInfo *const token)\n{\n\treadToken(token);\n\n\tif (token->type == TOKEN_IDENTIFIER)\n\t{\n\t\tint unionIndex = makeTypeSpecTag(token, K_UNION);\n\t\treadToken(token);\n\n\t\tif (token->type == TOKEN_OPEN_CURLY)\n\t\t{\n\t\t\tenterScope(token, unionIndex);\n\t\t}\n\t}\n}\n\nstatic void parseAlias(tokenInfo *const token)\n{\n\treadToken(token);\n\n\tif (token->type == TOKEN_IDENTIFIER)\n\t{\n\t\tmakeTypeSpecTag(token, K_ALIAS);\n\t\treadToken(token);\n\n\t\t/* Skip generic parameters if any */\n\t\tif (token->type == TOKEN_OPEN_ANGLE)\n\t\t{\n\t\t\tskipTypeParameters(token);\n\t\t}\n\n\t\t/* Skip the rest until semicolon */\n\t\tskipToSemicolon(token);\n\t}\n}\n\nstatic void enterScope (tokenInfo *const parentToken, int scope)\n{\n\ttokenInfo *token = newToken ();\n\ttagEntryInfo *e_parent;\n\n\tcopyToken (token, parentToken);\n\tsetScope (token, scope);\n\n\treadToken (token);\n\twhile (token->type != TOKEN_EOF && token->type != TOKEN_CLOSE_CURLY)\n\t{\n\t\t/* Skip decorators */\n\t\twhile (token->type == TOKEN_DECORATOR)\n\t\t{\n\t\t\t/* Skip the decorator body if it has parameters */\n\t\t\treadToken(token);\n\t\t\tif (token->type == TOKEN_OPEN_PAREN)\n\t\t\t{\n\t\t\t\tint depth = 1;\n\t\t\t\twhile (depth > 0 && token->type != TOKEN_EOF)\n\t\t\t\t{\n\t\t\t\t\treadToken(token);\n\t\t\t\t\tif (token->type == TOKEN_OPEN_PAREN)\n\t\t\t\t\t\tdepth++;\n\t\t\t\t\telse if (token->type == TOKEN_CLOSE_PAREN)\n\t\t\t\t\t\tdepth--;\n\t\t\t\t}\n\t\t\t\treadToken(token);\n\t\t\t}\n\t\t}\n\n\t\tswitch (token->type)\n\t\t{\n\t\t\tcase TOKEN_KEYWORD:\n\t\t\t\tswitch (token->keyword)\n\t\t\t\t{\n\t\t\t\t\tcase KEYWORD_namespace:\n\t\t\t\t\t\tparseNamespace(token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_enum:\n\t\t\t\t\t\tparseEnum(token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_op:\n\t\t\t\t\t\tparseOperation(token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_interface:\n\t\t\t\t\t\tparseInterface(token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_model:\n\t\t\t\t\t\tparseModel(token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_union:\n\t\t\t\t\t\tparseUnion(token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_alias:\n\t\t\t\t\t\tparseAlias(token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase KEYWORD_using:\n\t\t\t\t\tcase KEYWORD_import:\n\t\t\t\t\tcase KEYWORD_is:\n\t\t\t\t\tcase KEYWORD_extends:\n\t\t\t\t\t\tskipToSemicolon(token);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treadToken(token);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase TOKEN_SPREAD:\n\t\t\t\t/* Skip spread expressions (e.g. ...LivenessSessionData) */\n\t\t\t\treadToken(token);\n\t\t\t\tbreak;\n\n\t\t\tcase TOKEN_IDENTIFIER:\n\t\t\tcase TOKEN_STRING:\n\t\t\t\te_parent = getEntryInCorkQueue (scope);\n\t\t\t\tif (e_parent\n\t\t\t\t\t&& (e_parent->kindIndex == K_MODEL\n\t\t\t\t\t\t|| e_parent->kindIndex == K_INTERFACE))\n\t\t\t\t{\n\t\t\t\t\tparseProperty(token);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\treadToken(token);\n\t}\n\n\tcopyToken (parentToken, token);\n\t/* the scope of parentToken is not changed in this function.  */\n\tdeleteToken (token);\n}\n\nstatic void findTypeSpecTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\tdo\n\t{\n\t\tenterScope (token, CORK_NIL);\n\t}\n\twhile (token->type != TOKEN_EOF);\n\n\tdeleteToken (token);\n}\n\nextern parserDefinition* TypeSpecParser (void)\n{\n\tstatic const char *const extensions [] = { \"tsp\", NULL };\n\tparserDefinition* def = parserNew (\"TypeSpec\");\n\tdef->kindTable  = TypeSpecKinds;\n\tdef->kindCount  = ARRAY_SIZE (TypeSpecKinds);\n\tdef->extensions = extensions;\n\tdef->parser\t = findTypeSpecTags;\n\tdef->keywordTable = TypeSpecKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (TypeSpecKeywordTable);\n\tdef->defaultScopeSeparator = SCOPE_SEPARATOR;\n\tdef->useCork = CORK_QUEUE;\n\tdef->versionCurrent = 1;\n \tdef->versionAge = 1;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/v.c",
    "content": "/*\n*   Copyright (c) 2023, Tim Marston\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   References for developers:\n*     https://vlang.io/\n*     https://github.com/vlang/vls/blob/master/tree_sitter_v/grammar.js\n*/\n\n\n#include \"general.h\"        /* must always come first */\n\n#include <string.h>\n#include <stdarg.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"read.h\"\n#include \"numarray.h\"\n#include \"objpool.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"xtag.h\"\n#include \"field.h\"\n#include \"htable.h\"\n#include \"param.h\"\n#include \"selectors.h\"\n\n#include \"dependency.h\"\n#include \"cxx/cxx_tag.h\"\n#include \"x-jscript.h\"\n\n#define MAX_REPLAYS 3\n#define _NARGS(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N\n#define nArgs(...) _NARGS (__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)\n#define newToken() (objPoolGet (TokenPool))\n#define deleteToken(t) (objPoolPut (TokenPool, (t)))\n#define vStringAccumulateMaybe(a, s) \\\n\tdo{ if (a && s) vStringAccumulate(a, s); }while(0)\n#define isToken(token, ...) \\\n\t_isToken (token,  false, false, __LINE__, nArgs (__VA_ARGS__), __VA_ARGS__)\n#define expectToken(token, ...) \\\n\t_isToken (token,  true, false, __LINE__, nArgs (__VA_ARGS__), __VA_ARGS__)\n#define isKeyword(token, ...) \\\n\t_isToken (token, false, true, __LINE__, nArgs (__VA_ARGS__), __VA_ARGS__)\n#define expectKeyword(token, ...) \\\n\t_isToken (token, true, true, __LINE__, nArgs (__VA_ARGS__), __VA_ARGS__)\n#define isOneOf(c, s) (strchr (s, c) != NULL)\n#define isDigit(c) (c >= '0' && c <= '9')\n#define isHexDigit(c) (isDigit (c) || \\\n\t\t\t\t\t   (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))\n#define isInitialIdent(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || \\\n\t\t\t\t\t\t   c == '_' || c == '$')\n#define isSubsequentIdent(c) (isInitialIdent (c) || isDigit (c))\n#define isOperator(t) ( \\\n\t\tisToken (t, TOKEN_OPERATOR, TOKEN_PLUSMINUS, TOKEN_ANDAND, \\\n\t\t\t\t TOKEN_ASTERISK, TOKEN_AMPERSAND, TOKEN_CHPOP, TOKEN_PIPE) || \\\n\t\tisKeyword (token, KEYWORD_in))\n#define isInitialType(t) ( \\\n\t\tisToken (t, TOKEN_TYPE, TOKEN_EXTERN, TOKEN_OPEN_SQUARE, \\\n\t\t\t\t TOKEN_QUESTION, TOKEN_EXCLAMATION, TOKEN_ASTERISK, \\\n\t\t\t\t TOKEN_AMPERSAND, TOKEN_ANDAND) || \\\n\t\tisKeyword (t, KEYWORD_TYPE, KEYWORD_map, KEYWORD_chan, KEYWORD_Smap, \\\n\t\t\t\t   KEYWORD_shared, KEYWORD_fn, KEYWORD_none))\n#define isClose(t) ( \\\n\t\tisToken (t, TOKEN_CLOSE_PAREN, TOKEN_CLOSE_SQUARE, TOKEN_CLOSE_CURLY))\n#define unreadToken(t) (unreadTokenFull (t, NULL))\n#define RED \"\\033[91m\\033[1m\"\n#define NORM \"\\033[0m\\n\"\n\n#ifdef DEBUG\n#define vDebugPrintf(...) \\\n\tdo { if (debug (DEBUG_CPP)) fprintf (stderr, __VA_ARGS__); }while(0)\n#define vDebugParserPrintf(...) \\\n\tdo { if (debug (DEBUG_OPTION)) fprintf(stderr, __VA_ARGS__); }while(0)\n#define vDebugUnexpected(t, e, l) vDebugPrintf ( \\\n\tRED \"\\nUNEXPECTED %s%s%s%s in {%s} at %s:%lu (v.c:%i)\" NORM, \\\n\tt->keyword != KEYWORD_NONE? \"KEYWORD\" : tokenNames[t->type], \\\n\t(e)? \" (expected \" : \"\", e? e : \"\", (e)? \")\" : \"\", \\\n\tPS->currentParser, getInputFileName (), t->lineNumber, l? l : __LINE__)\n#define PARSER_PROLOGUE(c) \\\n\tconst char *const _prevParser = PS->currentParser; \\\n\tPS->currentParser = (c); \\\n\tvDebugParserPrintf (\"{%s: \", PS->currentParser)\n#define PARSER_EPILOGUE() \\\n\tvDebugParserPrintf (\":%s} \", PS->currentParser); \\\n\tPS->currentParser = _prevParser\n#else\n#define vDebugPrintf(...)\n#define vDebugParserPrintf(...)\n#define vDebugUnexpected(t, e, l)\n#define PARSER_PROLOGUE(c)\n#define PARSER_EPILOGUE()\n#endif\n\nenum {\n\tKEYWORD_fn,\n\tKEYWORD_map,\n\tKEYWORD_or,\n\tKEYWORD_module,\n\tKEYWORD_as,\n\tKEYWORD_import,\n\tKEYWORD_if,\n\tKEYWORD_Sif,\n\tKEYWORD_else,\n\tKEYWORD_Selse,\n\tKEYWORD_const,\n\tKEYWORD_return,\n\tKEYWORD_mut,\n\tKEYWORD_pub,\n\tKEYWORD_static,\n\tKEYWORD___global,\n\tKEYWORD_defer,\n\tKEYWORD_unsafe,\n\tKEYWORD_go,\n\tKEYWORD_spawn,\n\tKEYWORD_for,\n\tKEYWORD_Sfor,\n\tKEYWORD_in,\n\tKEYWORD_continue,\n\tKEYWORD_break,\n\tKEYWORD_assert,\n\tKEYWORD_struct,\n\tKEYWORD_interface,\n\tKEYWORD_union,\n\tKEYWORD_is,\n\tKEYWORD_none,\n\tKEYWORD_enum,\n\tKEYWORD_type,\n\tKEYWORD_asm,\n\tKEYWORD_chan,\n\tKEYWORD_match,\n\tKEYWORD_select,\n\tKEYWORD_lock,\n\tKEYWORD_rlock,\n\tKEYWORD_shared,\n\tKEYWORD_sql,\n\tKEYWORD_Smap,\n\tKEYWORD_Sarray,\n\tKEYWORD_Ssumtype,\n\tKEYWORD_Salias,\n\tKEYWORD_Sstruct,\n\tKEYWORD_Senum,\n\tKEYWORD_Sfloat,\n\tCOUNT_KEYWORD,\n\tKEYWORD_TYPE,\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\nconst static struct keywordGroup VTypeKeywords = {\n\t.value = KEYWORD_TYPE,\n\t.addingUnlessExisting = true,\n\t.keywords = {\n\t\t\"voidptr\", \"byteptr\", \"charptr\", \"i8\", \"i16\", \"i32\", \"int\", \"i64\",\n\t\t\"byte\", \"u8\", \"u16\", \"u32\", \"u64\", \"f32\", \"f64\", \"char\", \"bool\",\n\t\t\"string\", \"array\", \"rune\", \"mapnode\", \"size_t\", \"usize\", \"isize\",\n\t\t\"$int\", \"float_literal\", \"int_literal\", \"thread\", \"any\", \"IError\",\n\t\t\"_option\", \"_result\", NULL\n\t},\n};\n\nstatic const keywordTable VKeywordTable[COUNT_KEYWORD] = {\n\t{\"fn\", KEYWORD_fn},\n\t{\"map\", KEYWORD_map},\n\t{\"or\", KEYWORD_or},\n\t{\"module\", KEYWORD_module},\n\t{\"as\", KEYWORD_as},\n\t{\"import\", KEYWORD_import},\n\t{\"if\", KEYWORD_if},\n\t{\"$if\", KEYWORD_Sif},\n\t{\"else\", KEYWORD_else},\n\t{\"$else\", KEYWORD_Selse},\n\t{\"const\", KEYWORD_const},\n\t{\"return\", KEYWORD_return},\n\t{\"mut\", KEYWORD_mut},\n\t{\"pub\", KEYWORD_pub},\n\t{\"static\", KEYWORD_static},\n\t{\"__global\", KEYWORD___global},\n\t{\"defer\", KEYWORD_defer},\n\t{\"unsafe\", KEYWORD_unsafe},\n\t{\"go\", KEYWORD_go},\n\t{\"spawn\", KEYWORD_spawn},\n\t{\"for\", KEYWORD_for},\n\t{\"$for\", KEYWORD_Sfor},\n\t{\"in\", KEYWORD_in},\n\t{\"continue\", KEYWORD_continue},\n\t{\"break\", KEYWORD_break},\n\t{\"assert\", KEYWORD_assert},\n\t{\"struct\", KEYWORD_struct},\n\t{\"interface\", KEYWORD_interface},\n\t{\"union\", KEYWORD_union},\n\t{\"is\", KEYWORD_is},\n\t{\"none\", KEYWORD_none},\n\t{\"enum\", KEYWORD_enum},\n\t{\"type\", KEYWORD_type},\n\t{\"asm\", KEYWORD_asm},\n\t{\"chan\", KEYWORD_chan},\n\t{\"match\", KEYWORD_match},\n\t{\"select\", KEYWORD_select},\n\t{\"lock\", KEYWORD_lock},\n\t{\"rlock\", KEYWORD_rlock},\n\t{\"shared\", KEYWORD_shared},\n\t{\"sql\", KEYWORD_sql},\n\t{\"$map\", KEYWORD_Smap},\n\t{\"$array\", KEYWORD_Sarray},\n\t{\"$sumtype\", KEYWORD_Ssumtype},\n\t{\"$alias\", KEYWORD_Salias},\n\t{\"$struct\", KEYWORD_Sstruct},\n\t{\"$enum\", KEYWORD_Senum},\n\t{\"$float\", KEYWORD_Sfloat,}\n};\n\ntypedef enum eTokenType {\n\tTOKEN_NONE,\n\tTOKEN_KEYWORD,\n\tTOKEN_IDENT,\n\tTOKEN_TYPE, // V type ident (e.g., \"Foo\"), not KEYWORD_TYPE (e.g. \"int\")\n\tTOKEN_IMMEDIATE,\n\tTOKEN_OPEN_PAREN,\n\tTOKEN_CLOSE_PAREN,\n\tTOKEN_OPEN_CURLY,\n\tTOKEN_CLOSE_CURLY,\n\tTOKEN_OPEN_SQUARE,\n\tTOKEN_CLOSE_SQUARE,\n\tTOKEN_DECLARE, // :=\n\tTOKEN_OPERATOR,\n\tTOKEN_PLUSMINUS, // + -\n\tTOKEN_ANDAND, // &&\n\tTOKEN_EXCLAMATION,\n\tTOKEN_QUESTION,\n\tTOKEN_DOT, // .\n\tTOKEN_COMMA,\n\tTOKEN_SLICE,\n\tTOKEN_ASSIGN, // =\n\tTOKEN_ASTERISK,\n\tTOKEN_AMPERSAND,\n\tTOKEN_TILDE,\n\tTOKEN_COLON,\n\tTOKEN_SEMICOLON,\n\tTOKEN_INCDECOP, // ++ --\n\tTOKEN_PIPE,\n\tTOKEN_CHPOP, // <-\n\tTOKEN_AT,\n\tTOKEN_LABEL, // ident-then-colon (e.g., \"foo:\")\n\tTOKEN_EXTERN, // symbol in exteral namespace (e.g., \"C.foo\" or \"JS.Object\")\n\tTOKEN_EOF,\n\tCOUNT_TOKEN\n} tokenType;\n\n#ifdef DEBUG\nstatic char *const tokenNames[COUNT_TOKEN] = {\n\t\"NONE\",\n\t\"KEYWORD\",\n\t\"IDENT\",\n\t\"TYPE\",\n\t\"IMMEDIATE\",\n\t\"OPEN_PAREN\",\n\t\"CLOSE_PAREN\",\n\t\"OPEN_CURLY\",\n\t\"CLOSE_CURLY\",\n\t\"OPEN_SQUARE\",\n\t\"CLOSE_SQUARE\",\n\t\"DECLARE\",\n\t\"OPERATOR\",\n\t\"PLUSMINUS\",\n\t\"ANDAND\",\n\t\"EXCLAMATION\",\n\t\"QUESTION\",\n\t\"DOT\",\n\t\"COMMA\",\n\t\"SLICE\",\n\t\"ASSIGN\",\n\t\"ASTERISK\",\n\t\"AMPERSAND\",\n\t\"TILDE\",\n\t\"COLON\",\n\t\"SEMICOLON\",\n\t\"INCDECOP\",\n\t\"PIPE\",\n\t\"CHPOP\",\n\t\"AT\",\n\t\"LABEL\",\n\t\"EXTERN\",\n\t\"EOF\"\n};\n#endif\n\ntypedef enum {\n\tROLE_IMPORTED_MODULE,\n\tROLE_FOREIGNLANG_MODULE,\n\tCOUNT_MODULE_ROLE\n} VModuleRole;\n\nstatic roleDefinition VModuleRoles [COUNT_MODULE_ROLE] = {\n\t{ true, \"imported\", \"imported module\" },\n\t{ true, \"foreignlang\", \"representing a foreign language (i.e., C, JS...)\" },\n};\n\ntypedef enum {\n\tROLE_IMPORTED_SYMBOL,\n\tCOUNT_UNKNOWN_ROLE\n} VUnknownRole;\n\nstatic roleDefinition VUnknownRoles [COUNT_UNKNOWN_ROLE] = {\n\t{ true, \"imported\", \"imported symbol\" },\n};\n\ntypedef enum {\n\tKIND_FUNCTION,\n\tKIND_MODULE,\n\tKIND_VARIABLE,\n\tKIND_CONST,\n\t//KIND_FNARG,\n\tKIND_RECEIVER,\n\t//KIND_CLSARG,\n\tKIND_LABEL,\n\tKIND_STRUCT,\n\tKIND_FIELD,\n\tKIND_METHOD,\n\tKIND_ENUMERATOR,\n\tKIND_ENUMERATION,\n\tKIND_ALIAS,\n\tKIND_INTERFACE,\n\tKIND_UNION,\n\tKIND_UNKNOWN,\n\tCOUNT_KIND\n} kindType;\n\nstatic kindDefinition VKinds[COUNT_KIND] = {\n\t{true, 'f', \"fn\", \"functions\"},\n\t{true, 'p', \"module\", \"modules\",\n\t .referenceOnly = false, ATTACH_ROLES (VModuleRoles)},\n\t{true, 'v', \"variable\", \"variables\"},\n\t{true, 'c', \"const\", \"constants\"},\n\t//{false, 'z', \"param\", \"function parameters in functions\"},\n\t{true, 'R', \"receiver\", \"receivers in functions\"},\n\t//{false, 'c', \"closure\", \"closure parameters in functions\"},\n\t{true, 'l', \"label\", \"labels\"},\n\t{true, 's', \"struct\", \"structs\"},\n\t{true, 'm', \"field\", \"struct/interface members\"},\n\t{true, 'n', \"method\", \"interface methods\"},\n\t{true, 'e', \"enumerator\", \"enumerators (values inside an enumeration)\"},\n\t{true, 'g', \"enum\", \"enumeration names\"},\n\t{true, 'a', \"alias\", \"type aliases\"},\n\t{true, 'i', \"interface\", \"interfaces\"},\n\t{true, 'u', \"union\", \"union names\"},\n\t{true, 'Y', \"unknown\", \"unknown (imported) variables, types and functions\",\n\t .referenceOnly = false, ATTACH_ROLES (VUnknownRoles)},\n};\n\nstatic int vLookupKinds[] = { // int, compatible with anyKindsEntryInScope()\n\tKIND_STRUCT,\n\tKIND_ENUMERATION,\n\tKIND_INTERFACE,\n\tKIND_UNION,\n\tKIND_MODULE,\n};\nconst static int vLookupNumKinds = sizeof (vLookupKinds) / sizeof (int);\n\ntypedef struct {\n\tkindType kind;\n\tint role;\n} refSpec;\n\ntypedef struct {\n\tint type;\n\tkeywordId keyword;          /* when type is KEYWORD */\n\tvString *string;            /* when type is KEYWORD, IDENT or TYPE */\n\tbool fullyQualified;        /* when type is IDENT or TYPE */\n\tunsigned long lineNumber;\t/* line number of tagName */\n\tMIOPos filePosition;\t\t/* file position of line containing name */\n\tint captureLen;             /* num chars captured by token */\n\tbool onNewline;             /* token follows a \\n (V is not ws agnostic!) */\n#ifdef DEBUG\n\tint id;\n#endif\n} tokenInfo;\n\ntypedef struct {\n\ttokenType lastTokenType;\n\tint numReplays;\n\tstruct {\n\t\ttokenInfo *token;\n\t\tvString *capture;\n\t\ttokenType lastTokenType;\n\t} replays[MAX_REPLAYS];\n\tbool isBuiltin;\n#ifdef DEBUG\n\tconst char *currentParser;\n\tint nextTokenId;\n#endif\n} parserState;\n\nstatic langType LangV;\nstatic langType Lang_c;\nstatic langType Lang_javascript;\n\nstatic objPool *TokenPool = NULL;\nstatic parserState *PS = NULL; // global parser state\n\nstatic int lookupQualifiedName (tokenInfo *const, vString *, int,\n\t\t\t\t\t\t\t\tconst refSpec *);\nstatic void parseStatement (tokenInfo *const, int);\nstatic bool parseExpression (tokenInfo *const, int, vString *const);\nstatic void parseExprList (tokenInfo *const, int, vString *const, bool);\nstatic bool parseExprCont (tokenInfo *const, int, bool);\nstatic bool parseVType (tokenInfo *const, vString *const, int, bool, bool);\n\nstatic void *newPoolToken (void *createArg CTAGS_ATTR_UNUSED)\n{\n\ttokenInfo *token = xMalloc (1, tokenInfo);\n\ttoken->string = vStringNew();\n#ifdef DEBUG\n\ttoken->id = PS->nextTokenId++;\n#endif\n\treturn token;\n}\n\nstatic void deletePoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\tvStringDelete (token->string);\n\teFree (token);\n}\n\nstatic void clearPoolToken (void *data)\n{\n\ttokenInfo *token = data;\n\n\ttoken->type = TOKEN_NONE;\n\ttoken->keyword = KEYWORD_NONE;\n\tvStringClear (token->string);\n\ttoken->fullyQualified = false;\n\ttoken->captureLen = -1;\n\ttoken->onNewline = false;\n}\n\nstatic void copyToken (tokenInfo *const dst, tokenInfo *const src)\n{\n\tdst->type = src->type;\n\tdst->keyword = src->keyword;\n\tvStringCopy (dst->string, src->string);\n\tdst->fullyQualified = src->fullyQualified;\n\tdst->lineNumber = src->lineNumber;\n\tdst->filePosition = src->filePosition;\n\tdst->captureLen = src->captureLen;\n\tdst->onNewline = src->onNewline;\n}\n\nstatic tokenInfo *dupToken (tokenInfo *const token)\n{\n\ttokenInfo *newToken = newToken ();\n\tcopyToken (newToken, token);\n\treturn newToken;\n}\n\nstatic parserState *newParserState ()\n{\n\tparserState *st = xMalloc (1, parserState);\n\tst->numReplays = 0;\n\tst->isBuiltin = false;\n\tst->lastTokenType = TOKEN_IMMEDIATE;\n#ifdef DEBUG\n\tst->nextTokenId = 1;\n#endif\n\treturn st;\n}\n\nstatic void deleteParserState (parserState *st)\n{\n\tfor (int i = 0; i < st->numReplays; i++)\n\t{\n\t\tdeleteToken (st->replays[i].token);\n\t\tvStringDelete (st->replays[i].capture);\n\t}\n\teFree (st);\n}\n\n// _____________________________________________________________________________\n//                                                                     TOKENISER\n\nstatic void captureChar (vString *capture, tokenInfo *token, char c)\n{\n\tif (capture)\n\t\tvStringPut (capture, c);\n\ttoken->captureLen++;\n}\n\nstatic bool getcAndCaptureIfEq (int expect,\n\t\t\t\t\t\t\t\tvString *const capture, tokenInfo *token)\n{\n\tint c = getcFromInputFile ();\n\tif (c != expect)\n\t\tungetcToInputFile (c);\n\telse\n\t\tcaptureChar (capture, token, c);\n\treturn c == expect;\n}\n\nstatic int peekcFromInputFile ()\n{\n\tint c = getcFromInputFile ();\n\tungetcToInputFile (c);\n\treturn c;\n}\n\nstatic void skipInputFileTillEOL ()\n{\n\tint c;\n\tdo\n\t\tc = getcFromInputFile ();\n\twhile (c != EOF && !isOneOf (c, \"\\r\\n\"));\n}\n\nstatic void skipInputFileTillCommentEnd ()\n{\n\tint c = 0, last;\n\tdo\n\t{\n\t\tlast = c;\n\t\tc = getcFromInputFile ();\n\t\tif (last == '/' && c == '*')\n\t\t\tskipInputFileTillCommentEnd ();\n\t\telse if (last == '*' && c == '/')\n\t\t\tbreak;\n\t} while (c != EOF);\n}\n\nstatic void checkLabel (tokenInfo *const token, vString *capture)\n{\n\tint c = getcFromInputFile ();\n\tif (c == ':')\n\t{\n\t\tint d = getcFromInputFile ();\n\t\tungetcToInputFile (d);\n\t\tif (d != '=')\n\t\t{\n\t\t\ttoken->type = TOKEN_LABEL;\n\t\t\tif (capture)\n\t\t\t\tvStringPut (capture, ':');\n\t\t}\n\t\telse\n\t\t\tungetcToInputFile (c);\n\t}\n\telse\n\t\tungetcToInputFile (c);\n}\n\nstatic void readTokenFull (tokenInfo *const token, vString *capture)\n{\n\tint c;\n\n\t// replay?\n\tif (PS->numReplays > 0)\n\t{\n\t\tPS->numReplays--;\n\t\tcopyToken (token, PS->replays[PS->numReplays].token);\n\t\tdeleteToken (PS->replays[PS->numReplays].token);\n\t\tvDebugParserPrintf (\n\t\t\t\"v%s%s%s%s%s \", token->id > 1? \"[\" : \"\", tokenNames[token->type],\n\t\t\t!vStringIsEmpty (token->string)? \":\" : \"\",\n\t\t\tvStringValue (token->string), token->id > 1? \"]\" : \"\");\n\t\tif (capture)\n\t\t{\n\t\t\tAssert (PS->replays[PS->numReplays].capture);\n\t\t\tvStringCat (capture, PS->replays[PS->numReplays].capture);\n\t\t}\n\t\tvStringDelete (PS->replays[PS->numReplays].capture);\n\t\tPS->lastTokenType = PS->replays[PS->numReplays].lastTokenType;\n\t\treturn;\n\t}\n\n\t// skip whitespace and comments\n\tbool skippedNewline = false;\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\tif (isOneOf (c, \"\\r\\n\"))\n\t\t\tskippedNewline = true;\n\t\telse if (isOneOf (c, \" \\t\"))\n\t\t\t;\n\t\telse if (isOneOf (c, \"/#\"))\n\t\t{\n\t\t\tint d = getcFromInputFile ();\n\t\t\tif (c == '/' && d == '*')\n\t\t\t\tskipInputFileTillCommentEnd (); // /*\n\t\t\telse if ((c == '/' && d == '/') || (c == '#' && d != '['))\n\t\t\t{\n\t\t\t\tskipInputFileTillEOL (); // // #flag #include\n\t\t\t\tskippedNewline = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (d);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tbreak;\n\t} while (true);\n\n\t// init token\n\ttoken->lineNumber = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\tvStringClear (token->string);\n\ttoken->captureLen = 0;\n\ttoken->onNewline = skippedNewline;\n\ttoken->keyword = KEYWORD_NONE;\n\n\t// start capture\n\tif (c != EOF &&\n\t\t(isDigit (c) || isInitialIdent (c) || isOneOf (c, \"-+'\\\\*\\\"`\")) &&\n\t\t(PS->lastTokenType == TOKEN_IDENT ||\n\t\t PS->lastTokenType == TOKEN_KEYWORD ||\n\t\t PS->lastTokenType == TOKEN_TYPE ||\n\t\t PS->lastTokenType == TOKEN_COMMA))\n\t\tcaptureChar (capture, token, ' ');\n\tif (c != EOF)\n\t\tcaptureChar (capture, token, c);\n\n\t// match token...\n\tif (c == EOF)\n\t\ttoken->type = TOKEN_EOF;\n\telse if (c == '(')\n\t\ttoken->type = TOKEN_OPEN_PAREN;\n\telse if (c == ')')\n\t\ttoken->type = TOKEN_CLOSE_PAREN;\n\telse if (c == '{')\n\t\ttoken->type = TOKEN_OPEN_CURLY;\n\telse if (c == '}')\n\t\ttoken->type = TOKEN_CLOSE_CURLY;\n\telse if (c == '[')\n\t\ttoken->type = TOKEN_OPEN_SQUARE;\n\telse if (c == ']')\n\t\ttoken->type = TOKEN_CLOSE_SQUARE;\n\telse if (c == '?')\n\t\ttoken->type = TOKEN_QUESTION;\n\telse if (c == ',')\n\t\ttoken->type = TOKEN_COMMA;\n\telse if (c == '~')\n\t\ttoken->type = TOKEN_TILDE;\n\telse if (c == ';')\n\t\ttoken->type = TOKEN_SEMICOLON;\n\telse if (c == '#' && getcAndCaptureIfEq ('[', capture, token))\n\t\ttoken->type = TOKEN_OPEN_SQUARE; // #[\n\telse if (isDigit (c) ||\n\t\t\t (isOneOf (c, \"-+.\") && isDigit (peekcFromInputFile ())))\n\t{\n\t\tbool more;\n\t\ttoken->type = TOKEN_IMMEDIATE;\n\t\tdo\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tmore = isHexDigit (c) ||\n\t\t\t\t(isOneOf (c, \".-+xo_\") && isHexDigit (peekcFromInputFile ())) ||\n\t\t\t\t(isOneOf (c, \"eE\") && (isDigit (peekcFromInputFile ()) ||\n\t\t\t\t\t\t\t\t\t   isOneOf (peekcFromInputFile (), \"-+\")));\n\t\t\tif (more)\n\t\t\t\tcaptureChar (capture, token, c);\n\t\t} while (more);\n\t\tungetcToInputFile (c);\n\t\tcheckLabel (token, capture);\n\t}\n\telse if (isOneOf (c, \"+-*/%&|^\"))\n\t{\n\t\tif (getcAndCaptureIfEq ('=', capture, token))\n\t\t\ttoken->type = TOKEN_ASSIGN; // += -= *= /= %= &= |= ^=\n\t\telse if (c == '*')\n\t\t\ttoken->type = TOKEN_ASTERISK; // *\n\t\telse if (c == '|' && getcAndCaptureIfEq (c, capture, token))\n\t\t\ttoken->type = TOKEN_OPERATOR; // ||\n\t\telse if (c == '&' && getcAndCaptureIfEq (c, capture, token))\n\t\t\ttoken->type = TOKEN_ANDAND; // &&\n\t\telse if (isOneOf (c, \"+-\") && getcAndCaptureIfEq (c, capture, token))\n\t\t\ttoken->type = TOKEN_INCDECOP; // ++ --\n\t\telse if (isOneOf (c, \"+-\"))\n\t\t\ttoken->type = TOKEN_PLUSMINUS; // + -\n\t\telse if (c == '&')\n\t\t\ttoken->type = TOKEN_AMPERSAND; // &\n\t\telse if (c == '|')\n\t\t\ttoken->type = TOKEN_PIPE; // |\n\t\telse\n\t\t\ttoken->type = TOKEN_OPERATOR; // / % ^\n\t}\n\telse if (isOneOf (c, \"=!\"))\n\t{\n\t\tif (getcAndCaptureIfEq ('=', capture, token))\n\t\t\ttoken->type = TOKEN_OPERATOR; // == !=\n\t\telse if (c == '=')\n\t\t\ttoken->type = TOKEN_ASSIGN; // =\n\t\telse if (getcAndCaptureIfEq ('i', capture, token))\n\t\t{\n\t\t\tc = getcFromInputFile ();\n\t\t\tif (isOneOf (c, \"ns\") && !isSubsequentIdent (peekcFromInputFile ()))\n\t\t\t{\n\t\t\t\ttoken->type = TOKEN_KEYWORD; // !in !is\n\t\t\t\ttoken->keyword = c == 'n'? KEYWORD_in : KEYWORD_is;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tungetcToInputFile (c);\n\t\t\t\tungetcToInputFile ('i');\n\t\t\t\ttoken->type = TOKEN_EXCLAMATION; // !\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\ttoken->type = TOKEN_EXCLAMATION; // !\n\t}\n\telse if (isOneOf (c, \"<>\"))\n\t{\n\t\tif (getcAndCaptureIfEq (c, capture, token))\n\t\t{\n\t\t\tif (c == '>')\n\t\t\t\tgetcAndCaptureIfEq ('>', capture, token);\n\t\t\tif (getcAndCaptureIfEq ('=', capture, token))\n\t\t\t\ttoken->type = TOKEN_ASSIGN; // <<= >>= >>>=\n\t\t\telse\n\t\t\t\ttoken->type = TOKEN_OPERATOR; // << >> >>>\n\t\t}\n\t\telse if (c == '<' && getcAndCaptureIfEq ('-', capture, token))\n\t\t\ttoken->type = TOKEN_CHPOP; // <-\n\t\telse\n\t\t{\n\t\t\tgetcAndCaptureIfEq ('=', capture, token);\n\t\t\ttoken->type = TOKEN_OPERATOR; // < > <= >=\n\t\t}\n\t}\n\telse if (c == '.')\n\t{\n\t\tif (getcAndCaptureIfEq ('.', capture, token))\n\t\t{\n\t\t\tgetcAndCaptureIfEq ('.', capture, token);\n\t\t\ttoken->type = TOKEN_SLICE; // .. ...\n\t\t}\n\t\telse\n\t\t\ttoken->type = TOKEN_DOT; // .\n\t}\n\telse if (c == ':')\n\t{\n\t\tif (getcAndCaptureIfEq ('=', capture, token))\n\t\t\ttoken->type = TOKEN_DECLARE; // :=\n\t\telse\n\t\t\ttoken->type = TOKEN_COLON; // :\n\t}\n\telse if (isOneOf (c, \"\\\"'`\"))\n\t{\n\t\tint terminator = c;\n\t\tbool inEscape = false;\n\t\tbool inEval = false;\n\t\tint evalLevel = 0;\n\t\ttoken->type = TOKEN_IMMEDIATE;\n\t\tdo\n\t\t{\n\t\t\tif (inEscape)\n\t\t\t{\n\t\t\t\tcaptureChar (capture, token, c);\n\t\t\t\tinEscape = false;\n\t\t\t}\n\t\t\telse if (inEval) // TODO: this doesn't handle nested strings/evals\n\t\t\t{\n\t\t\t\tif (c == '{')\n\t\t\t\t\tevalLevel++;\n\t\t\t\telse if (c == '}')\n\t\t\t\t\tevalLevel--;\n\t\t\t\tif (evalLevel == 0)\n\t\t\t\t\tinEval = false;\n\t\t\t}\n\t\t\telse if (c == '\\\\')\n\t\t\t\tinEscape = true;\n\t\t\telse if (c == '$')\n\t\t\t\tinEval = true;\n\t\t\tc = getcFromInputFile ();\n\t\t\tcaptureChar (capture, token, c);\n\t\t} while (c != EOF &&\n\t\t\t\t (c != terminator || inEscape || (inEval && evalLevel > 0)));\n\t\tcheckLabel (token, capture);\n\t}\n\telse if (c == '@')\n\t{\n\t\tif (isSubsequentIdent (peekcFromInputFile ()))\n\t\t{\n\t\t\ttoken->type = TOKEN_IDENT;\n\t\t\tbool more;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tvStringPut (token->string, c);\n\t\t\t\tc = getcFromInputFile ();\n\t\t\t\tmore = isSubsequentIdent (c);\n\t\t\t\tif (more)\n\t\t\t\t\tcaptureChar (capture, token, c);\n\t\t\t} while (more);\n\t\t\tungetcToInputFile (c);\n\t\t\tcheckLabel (token, capture);\n\t\t}\n\t\telse\n\t\t\ttoken->type = TOKEN_AT;\n\t}\n\telse if (isInitialIdent (c))\n\t{\n\t\tbool more;\n\t\tdo\n\t\t{\n\t\t\tvStringPut (token->string, c);\n\t\t\tc = getcFromInputFile ();\n\t\t\tmore = isSubsequentIdent (c);\n\t\t\tif (more)\n\t\t\t\tcaptureChar (capture, token, c);\n\t\t} while (more);\n\t\tungetcToInputFile (c);\n\n\t\ttoken->keyword = lookupKeyword (vStringValue (token->string), LangV);\n\t\tif (token->keyword != KEYWORD_NONE)\n\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\telse\n\t\t{\n\t\t\tchar initChar = vStringChar (token->string, 0);\n\t\t\tif (initChar >= 'A' && initChar <= 'Z')\n\t\t\t\ttoken->type = TOKEN_TYPE;\n\t\t\telse if (isOneOf (initChar, \"rc\") &&\n\t\t\t\t\t vStringLength (token->string) == 1 &&\n\t\t\t\t\t isOneOf (peekcFromInputFile (), \"'\\\"`\"))\n\t\t\t{\n\t\t\t\tint end = getcFromInputFile ();\n\t\t\t\tcaptureChar (capture, token, end);\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tc = getcFromInputFile ();\n\t\t\t\t\tcaptureChar (capture, token, c);\n\t\t\t\t}\n\t\t\t\twhile (c != end && c != EOF);\n\t\t\t\tvStringClear (token->string);\n\t\t\t\ttoken->type = TOKEN_IMMEDIATE; // raw string\n\t\t\t}\n\t\t\telse\n\t\t\t\ttoken->type = TOKEN_IDENT;\n\t\t}\n\n\t\tif (token->type != TOKEN_KEYWORD)\n\t\t\tcheckLabel (token, capture);\n\t}\n\telse\n\t{\n\t\tvDebugPrintf (RED \"\\nUNRECOGNISED CHAR at %s:%lu: %c (%u)\" NORM,\n\t\t\t\t\t  getInputFileName (), token->lineNumber, c, c);\n\t}\n\n\tvDebugParserPrintf (\n\t\t\"%s%s%s%s%s \", token->id > 1? \"[\" : \"\", tokenNames[token->type],\n\t\t!vStringIsEmpty (token->string)? \":\" : \"\",\n\t\tvStringValue (token->string), token->id > 1? \"]\" : \"\");\n\n\tPS->lastTokenType = token->type;\n}\n\nstatic void unreadTokenFull (tokenInfo *const token, vString *const acc)\n{\n\tif (token->type == TOKEN_EOF) {\n\t\treturn;\n\t}\n\tAssert (PS->numReplays < MAX_REPLAYS);\n\tDebugStatement (\n\t\t// multiple-replay in only possible where additional tokenInfos are\n\t\t// loaded with tokens so different tokens can be unread.\n\t\tfor (int i = 0; i < PS->numReplays; i++)\n\t\t\tAssert (token->id != PS->replays[i].token->id);\n\t);\n\tvDebugParserPrintf (\"^ \");\n\n\tPS->replays[PS->numReplays].token = dupToken (token);\n\tif (acc)\n\t{\n\t\tAssert (token->captureLen > -1);\n\t\tAssert (token->captureLen <= vStringLength (acc));\n\t\tint off = vStringLength (acc) - token->captureLen;\n\t\tPS->replays[PS->numReplays].capture =\n\t\t\tvStringNewInit (vStringValue (acc) + off);\n\t\tvStringTruncate (acc, off);\n\t}\n\telse\n\t\tPS->replays[PS->numReplays].capture = NULL;\n\tPS->replays[PS->numReplays].lastTokenType = PS->lastTokenType;\n\tPS->numReplays++;\n}\n\nstatic void readToken (tokenInfo *const token)\n{\n\treadTokenFull (token, NULL);\n}\n\n// _____________________________________________________________________________\n//                                                                    HELPER FNS\n\nstatic bool _isToken (tokenInfo *const token, bool expect, bool keyword,\n\t\t\t\t\t  int lineNum, int nTypes, ...)\n{\n\tva_list argp;\n\tva_start (argp, nTypes);\n\tbool found = false;\n\tif (!keyword)\n\t\tfor (int i = 0; i < nTypes; i++)\n\t\t\tfound = found || (token->type == va_arg (argp, tokenType));\n\telse if (token->type == TOKEN_KEYWORD)\n\t\tfor (int i = 0; i < nTypes; i++)\n\t\t\tfound = found || (token->keyword == va_arg (argp, keywordId));\n\tva_end (argp);\n\tDebugStatement (\n\t\tif (expect && !found)\n\t\t{\n\t\t\tif (!keyword)\n\t\t\t{\n\t\t\t\tvString *exp = NULL;\n\t\t\t\tva_start (argp, nTypes);\n\t\t\t\tfor (int i = 0; i < nTypes; i++)\t\t\t\t{\n\t\t\t\t\ttokenType type = va_arg (argp, tokenType);\n\t\t\t\t\tif (type == TOKEN_NONE)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\telse if (exp)\n\t\t\t\t\t\tvStringCatS (exp, \", \");\n\t\t\t\t\telse\n\t\t\t\t\t\texp = vStringNew ();\n\t\t\t\t\tvStringCatS (exp, tokenNames[type]);\n\t\t\t\t}\n\t\t\t\tva_end (argp);\n\t\t\t\tvDebugUnexpected (token, exp? vStringValue (exp) : NULL, lineNum);\n\t\t\t\tvStringDelete (exp);\n\t\t\t}\n\t\t\telse if (token->type == TOKEN_KEYWORD)\n\t\t\t\tvDebugUnexpected (token, \"other KEYWORD\", lineNum);\n\t\t\telse\n\t\t\t\tvDebugUnexpected (token, \"KEYWORD\", lineNum);\n\t\t}\n\t);\n\t// Although we don't show a debug parser error, we always return failure for\n\t// expectToken() on a keyword token, so that the call can be chained to an\n\t// expectKeyword() call to check which keyword it is. E.g.:\n\t//     expectToken (token, ..., TOKEN_KEYWORD) || expectKeyword (token, ...)\n\t// Note that isToken() is not affected by this special case.\n\treturn (expect && !keyword && token->type == TOKEN_KEYWORD)? false : found;\n}\n\nstatic int makeTagFull (tokenInfo *const token, const char *name,\n\t\t\t\t\t\tconst kindType kind, const int scope, int role,\n\t\t\t\t\t\tvString *const argList, vString *retType,\n\t\t\t\t\t\tconst char *access)\n{\n\tAssert (token);\n\tAssert (name == NULL || name[0] != '\\0');\n\tAssert (name != NULL || !vStringIsEmpty(token->string));\n\tvDebugParserPrintf (\"#%c \", VKinds[kind].letter);\n\n\ttagEntryInfo e;\n\n\tconst char *const tagName = name? name : vStringValue (token->string);\n\tif (!strcmp (tagName, \"_\"))\n\t\treturn CORK_NIL; // ignore _\n\tinitRefTagEntry (&e, tagName, kind, role);\n\n\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\tif (argList && !vStringIsEmpty (argList))\n\t\te.extensionFields.signature = vStringValue (argList);\n\tif (access && *access != '\\0')\n\t\te.extensionFields.access = access;\n\tif (retType)\n\t{\n\t\te.extensionFields.typeRef [0] = \"typename\";\n\t\te.extensionFields.typeRef [1] = vStringValue( retType );\n\t}\n\te.extensionFields.scopeIndex = scope;\n\n\treturn makeTagEntry (&e);\n}\n\nstatic int makeFnTag (tokenInfo *const token, vString *const name,\n\t\t\t\t\t  kindType kind, int scope, vString *const argList,\n\t\t\t\t\t  vString *const retType, vString *const access)\n{\n\treturn makeTagFull (token, name? vStringValue (name) : NULL, kind,\n\t\t\t\t\t\tscope, ROLE_DEFINITION_INDEX, argList, retType,\n\t\t\t\t\t\taccess? vStringValue (access) : NULL);\n}\n\nstatic int makeTag (tokenInfo *const token, vString *const name, kindType kind,\n\t\t\t\t\tint scope)\n{\n\treturn makeTagFull (token, name? vStringValue (name) : NULL, kind, scope,\n\t\t\t\t\t\tROLE_DEFINITION_INDEX, NULL, NULL, NULL);\n}\n\nstatic int makeTagEx (tokenInfo *const token, vString *const name, kindType kind,\n\t\t\t\t\t  int scope, vString *const access)\n{\n\treturn makeTagFull (token, name? vStringValue (name) : NULL, kind, scope,\n\t\t\t\t\t\tROLE_DEFINITION_INDEX, NULL, NULL,\n\t\t\t\t\t\taccess? vStringValue (access) : NULL);\n}\n\nstatic int makeRefTag (tokenInfo *const token, vString *const name,\n\t\t\t\t\t   kindType kind, int scope, int role)\n{\n\treturn makeTagFull (token, name? vStringValue (name) : NULL, kind, scope,\n\t\t\t\t\t\trole, NULL, NULL, NULL);\n}\n\nstatic void makeForeignDeclTagMaybe (tokenInfo *const token, vString *const name,\n\t\t\t\t\t\t\t\t\t kindType kind, int scope)\n{\n\ttagEntryInfo *scopeEntry = getEntryInCorkQueue (scope);\n\tif (!scopeEntry)\n\t\treturn;\n\tif (! (scopeEntry->langType == LangV &&\n\t\t   scopeEntry->kindIndex == KIND_MODULE &&\n\t\t   isRoleAssigned (scopeEntry, ROLE_FOREIGNLANG_MODULE)))\n\t\treturn;\n\n\tint foreignKind, foreignRole;\n\tlangType lang;\n\n\tif (strcmp (scopeEntry->name, \"C\") == 0)\n\t{\n\t\tlang = Lang_c;\n\t\tif (kind == KIND_STRUCT)\n\t\t{\n\t\t\tforeignKind = CXXTagKindSTRUCT;\n\t\t\tforeignRole = CXXTagSTRUCTRoleFOREIGNDECL;\n\t\t}\n\t\telse if (kind == KIND_FUNCTION)\n\t\t{\n\t\t\tforeignKind = CXXTagKindFUNCTION;\n\t\t\tforeignRole = CXXTagFUNCTIONRoleFOREIGNDECL;\n\t\t}\n\t\telse\n\t\t\treturn;\n\t}\n\telse if (strcmp (scopeEntry->name, \"JS\") == 0)\n\t{\n\t\tlang = Lang_javascript;\n\t\tif (kind == KIND_FUNCTION)\n\t\t{\n\t\t\tforeignKind = JSTAG_FUNCTION;\n\t\t\tforeignRole = JSTAG_FUNCTIONRoleFOREIGNDECL;\n\t\t}\n\t\telse\n\t\t\treturn;\n\t}\n\telse\n\t\treturn;\n\n\tif (lang == LANG_IGNORE)\n\t\treturn;\n\n\tvDebugParserPrintf (\"#~ \");\n\ttagEntryInfo foreignEntry;\n\tconst char *const tagName =\n\t\tname? vStringValue (name) : vStringValue (token->string);\n\tinitForeignRefTagEntry (\n\t\t&foreignEntry, tagName, lang, foreignKind, foreignRole);\n\tupdateTagLine(&foreignEntry, token->lineNumber, token->filePosition);\n\tmakeTagEntry (&foreignEntry);\n}\n\nstatic tokenType getOpen (tokenType close)\n{\n\tswitch (close)\n\t{\n\tcase TOKEN_CLOSE_PAREN: return TOKEN_OPEN_PAREN;\n\tcase TOKEN_CLOSE_SQUARE: return TOKEN_OPEN_SQUARE;\n\tcase TOKEN_CLOSE_CURLY: return TOKEN_OPEN_CURLY;\n\tdefault: return TOKEN_NONE;\n\t}\n}\n\nstatic tokenType getClose (tokenType open)\n{\n\tswitch (open)\n\t{\n\tcase TOKEN_OPEN_PAREN: return TOKEN_CLOSE_PAREN;\n\tcase TOKEN_OPEN_SQUARE: return TOKEN_CLOSE_SQUARE;\n\tcase TOKEN_OPEN_CURLY: return TOKEN_CLOSE_CURLY;\n\tdefault: return TOKEN_NONE;\n\t}\n}\n\nstatic void skipToTokenFull (tokenType type, vString *const capture,\n\t\t\t\t\t\t\t tokenInfo *token)\n{\n\tif (type != TOKEN_NONE)\n\t{\n\t\ttokenType open =\n\t\t\t(type == TOKEN_CLOSE_PAREN || type == TOKEN_CLOSE_SQUARE ||\n\t\t\t type == TOKEN_CLOSE_CURLY)? getOpen (type) : TOKEN_NONE;\n\t\tint nest = 1;\n\t\tdo\n\t\t{\n\t\t\treadTokenFull (token, capture);\n\t\t\tif (open != TOKEN_NONE && isToken (token, open))\n\t\t\t\tnest++;\n\t\t\telse if (isToken (token, type))\n\t\t\t\tnest--;\n\t\t\telse if (isToken (token, TOKEN_EOF))\n\t\t\t\tbreak;\n\t\t} while (nest > 0);\n\t}\n}\n\nstatic void skipToToken (tokenType type, vString *const capture)\n{\n\ttokenInfo *token = newToken ();\n\tskipToTokenFull (type, capture, token);\n\tdeleteToken (token);\n}\n\n// NOTE: over-reads!\nstatic void skipAccessAndReadToken (tokenInfo *const token, vString **capture)\n{\n\twhile (true)\n\t{\n\t\tconst char *add = NULL;\n\t\tif (isKeyword (token, KEYWORD_mut))\n\t\t\tadd = \"mut\";\n\t\telse if (isKeyword (token, KEYWORD_pub))\n\t\t\tadd = \"pub\";\n\t\telse if (isKeyword (token, KEYWORD_static))\n\t\t\tadd = \"static\";\n\t\telse if (isKeyword (token, KEYWORD___global))\n\t\t\tadd = \"__global\";\n\t\telse if (isKeyword (token, KEYWORD_shared))\n\t\t\tadd = \"shared\";\n\t\tif (!add)\n\t\t\tbreak;\n\t\tif (capture)\n\t\t{\n\t\t\tif (*capture == NULL)\n\t\t\t\t*capture = vStringNew ();\n\t\t\telse\n\t\t\t\tvStringPutUnlessEmpty(*capture, ' ');\n\t\t\tvStringCatS (*capture, add);\n\t\t}\n\t\treadToken (token);\n\t}\n}\n\nstatic char *nextCharIdent (char *s, char sep)\n{\n\tif (s)\n\t{\n\t\twhile (*s != sep && *s != '\\0')\n\t\t\ts++;\n\t\tif (*s == sep)\n\t\t\t*(s++) = '\\0';\n\t\twhile (*s == ' ')\n\t\t\ts++;\n\t\tif (*s == '\\0')\n\t\t\ts = NULL;\n\t}\n\treturn s;\n}\n\n// lookup qualified name, updating it (name or token->string) to last part and\n// returning the last part's scope, and making references of intermediate parts\n// which can not be looked-up, if requested\nstatic int lookupQualifiedName (tokenInfo *const token, vString *name,\n\t\t\t\t\t\t\t\tint scope, const refSpec *makeRefs)\n{\n\tAssert (token);\n\tAssert (!name || vStringLength (name) > 0);\n\tAssert (name || !vStringIsEmpty (token->string));\n\n\tchar *tmp = eStrdup (vStringValue (name? name : token->string));\n\tchar *part = NULL, *next = tmp;\n\tbool once = true, ongoing = true, external = false;\n\twhile (next)\n\t{\n\t\tpart = next;\n\t\tnext = nextCharIdent (next, '.');\n\t\tif (*part != '\\0' && next) // has another next (don't lookup last next)\n\t\t{\n\t\t\tif (once)\n\t\t\t{\n\t\t\t\tonce = false;\n\t\t\t\tif (!strcmp (part, \"C\") || !strcmp (part, \"JS\"))\n\t\t\t\t{\n\t\t\t\t\texternal = true;\n\t\t\t\t\tscope = makeTagFull (token, part, KIND_MODULE, CORK_NIL,\n\t\t\t\t\t\t\t\t\t\t ROLE_FOREIGNLANG_MODULE, NULL, NULL, NULL);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!external && ongoing)\n\t\t\t{\n\t\t\t\tint newScope = CORK_NIL;\n\t\t\t\tif (makeRefs)\n\t\t\t\t\tnewScope = makeTagFull (token, part, makeRefs->kind, scope,\n\t\t\t\t\t\t\t\t\t\t\tmakeRefs->role, NULL, NULL, NULL);\n\t\t\t\tif (newScope == CORK_NIL)\n\t\t\t\t\tnewScope = anyKindsEntryInScope (\n\t\t\t\t\t\t\tscope, part, vLookupKinds, vLookupNumKinds, true);\n\t\t\t\tscope = newScope;\n\t\t\t\tongoing = scope != CORK_NIL;\n\t\t\t}\n\t\t}\n\t}\n\tif (part)\n\t\tvStringCopyS (name? name : token->string, part);\n\teFree (tmp);\n\treturn scope;\n}\n\n// _____________________________________________________________________________\n//                                                                       PARSERS\n\n// Note: all parsers expect the caller to have already read the initial token\n// prior to calling, but will not themselves over-read on exit. Parsers will\n// unread the last token, if is not within their purview.\n\n// fq: [ident | type] ['.' [ident | type | kwtype | 'assert']]*\n// on return, token->type is IDENT/TYPE/EXTERN, token->string is fully-qualified\nstatic void parseFullyQualified (tokenInfo *const token, bool captureInToken)\n{\n\tAssert (isToken (token, TOKEN_IDENT, TOKEN_TYPE, TOKEN_EXTERN));\n\tif (token->fullyQualified)\n\t\treturn;\n\tPARSER_PROLOGUE (\"fq\");\n\n\tconst char *s = vStringValue (token->string);\n\tbool isExtern =\n\t\t(s[0] == 'C' && (s[1] == '\\0' || s[1] == '.')) ||\n\t\t(s[0] == 'J' && s[1] == 'S' && (s[2] == '\\0' || s[2] == '.'));\n\tvString *acc = captureInToken? token->string : NULL;\n\ttokenType prev = TOKEN_NONE, prevprev = TOKEN_NONE;\n\ttokenInfo *tokens[2] = { NULL, NULL };\n\tint count = 0, idx = 1;\n\twhile (prev == TOKEN_NONE ||\n\t\t   (prev == TOKEN_DOT &&\n\t\t\t(isToken (tokens[idx], TOKEN_IDENT, TOKEN_TYPE) ||\n\t\t\t isKeyword (tokens[idx], KEYWORD_TYPE,\n\t\t\t\t\t\tKEYWORD_map, KEYWORD_chan, KEYWORD_sql) ||\n\t\t\t (isExtern && isKeyword (tokens[idx], KEYWORD_assert)))) ||\n\t\t   (prev != TOKEN_DOT && isToken (tokens[idx], TOKEN_DOT)))\n\t{\n\t\tprevprev = prev;\n\t\tprev = prev == TOKEN_NONE? token->type : tokens[idx]->type;\n\t\tidx = 1 - idx;\n\t\tif (tokens[idx] == NULL)\n\t\t\ttokens[idx] = newToken ();\n\t\treadTokenFull (tokens[idx], acc);\n\t\tcount++;\n\t}\n\tunreadTokenFull (tokens[idx], acc);\n\tif (prev == TOKEN_DOT && count >= 2)\n\t{\n\t\tunreadTokenFull (tokens[1 - idx], acc);\n\t\tprev = prevprev;\n\t}\n\tif (prev == TOKEN_KEYWORD)\n\t\tprev = TOKEN_IDENT;\n\tdeleteToken (tokens[0]);\n\tdeleteToken (tokens[1]);\n\n\t// load token with type (and fq name)\n\ttoken->type = isExtern? TOKEN_EXTERN : prev;\n\ttoken->fullyQualified = true;\n\n\t// should end on one of these\n\tif (!expectToken (token,\n\t                  TOKEN_TYPE, TOKEN_IDENT, TOKEN_EXTERN, TOKEN_KEYWORD))\n\t\texpectKeyword (token,\n\t\t               KEYWORD_TYPE, KEYWORD_map, KEYWORD_chan, KEYWORD_sql);\n\n\tPARSER_EPILOGUE ();\n}\n\n// fqident: [ident | type] fq\nstatic void parseFQIdent (tokenInfo *const token, vString *const capture)\n{\n\tAssert (isToken (token, TOKEN_IDENT, TOKEN_TYPE, TOKEN_EXTERN));\n\tparseFullyQualified (token, !!capture);\n\texpectToken (token, TOKEN_IDENT, TOKEN_EXTERN);\n\tif (capture)\n\t\tvStringCat (capture, token->string);\n}\n\n// init: [\n//     ['{' ['...' fqident]? [',' | [ [label | expr ':']? expr ]]* '}'] |\n//     ['(' [',' | [[label | expr ':']? expr | '...' expr ]]* ')']\n// ]\nstatic void parseInit (tokenInfo *const token, int scope)\n{\n\tAssert (isToken (token, TOKEN_OPEN_CURLY, TOKEN_OPEN_PAREN));\n\tPARSER_PROLOGUE (\"init\");\n\n\tbool hasDestructure = isToken (token, TOKEN_OPEN_CURLY);\n\tbool hasVarArgs = isToken (token, TOKEN_OPEN_PAREN);\n\ttokenType close = getClose (token->type);\n\treadToken (token);\n\tif (hasDestructure && isToken (token, TOKEN_SLICE))\n\t{\n\t\treadToken (token);\n\t\tif (!isToken (token, close))\n\t\t{\n\t\t\tif (parseExpression (token, scope, NULL))\n\t\t\t\treadToken (token);\n\t\t}\n\t\telse\n\t\t\tunreadToken (token);\n\t}\n\twhile (!isToken (token, TOKEN_EOF, close))\n\t{\n\t\tif (isToken (token, TOKEN_COMMA))\n\t\t\treadToken (token);\n\t\telse\n\t\t{\n\t\t\tif (isToken (token, TOKEN_LABEL))\n\t\t\t\treadToken (token);\n\t\t\telse if (isToken (token, TOKEN_DOT))\n\t\t\t{\n\t\t\t\t// enumerator labels\n\t\t\t\treadToken (token);\n\t\t\t\tif (isToken (token, TOKEN_LABEL))\n\t\t\t\t\treadToken (token);\n\t\t\t\telse\n\t\t\t\t\tunreadToken (token);\n\t\t\t}\n\t\t\telse if (hasVarArgs && isToken (token, TOKEN_SLICE))\n\t\t\t\treadToken (token);\n\t\t\tif (!isToken (token, close))\n\t\t\t{\n\t\t\t\tif (parseExpression (token, scope, NULL))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isToken (token, TOKEN_COLON)) // expr labels\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tif (!isToken (token, close))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparseExpression (token, scope, NULL);\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\treadToken(token);\n\t\t\t}\n\t\t}\n\t}\n\n\tPARSER_EPILOGUE ();\n}\n\n// fncall: '(' init err-cont\nstatic void parseFnCall (tokenInfo *const token, int scope)\n{\n\tAssert (isToken (token, TOKEN_OPEN_PAREN));\n\tPARSER_PROLOGUE (\"fncall\");\n\n\tparseInit (token, scope);\n\treadToken (token);\n\tif (!parseExprCont (token, scope, true))\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// chain: '.' [ident | type | kwtype | 'map'] err-cont?\nstatic void parseChain (tokenInfo *const token, int scope)\n{\n\tAssert (isToken (token, TOKEN_DOT));\n\tPARSER_PROLOGUE (\"chain\");\n\n\treadToken (token);\n\tif (expectToken (token, TOKEN_IDENT, TOKEN_TYPE, TOKEN_KEYWORD) ||\n\t\texpectKeyword (token, KEYWORD_TYPE, KEYWORD_map))\n\t{\n\t\treadToken (token);\n\t\tif (!parseExprCont (token, scope, true))\n\t\t\tunreadToken (token);\n\t}\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// block: '{' statement* '}' chain?\n// returns line number of CLOSE_CURLY\nstatic int parseBlock (tokenInfo *const token, int scope, bool hasChain)\n{\n\tAssert (isToken (token, TOKEN_OPEN_CURLY));\n\tPARSER_PROLOGUE (\"block\");\n\n\ttokenType close = getClose (token->type);\n\tdo\n\t{\n\t\treadToken (token);\n\t\tif (isToken (token, close))\n\t\t\tbreak;\n\t\telse\n\t\t\tparseStatement (token, scope);\n\t}\n\twhile (!isToken (token, TOKEN_EOF));\n\tint ret = token->lineNumber;\n\tif (hasChain)\n\t{\n\t\treadToken (token);\n\t\tif (isToken (token, TOKEN_DOT))\n\t\t\tparseChain (token, scope);\n\t\telse\n\t\t\tunreadToken (token);\n\t}\n\n\tPARSER_EPILOGUE ();\n\treturn ret;\n}\n\n// decl: [':=' | 'in'] list\nstatic void parseDeclare (tokenInfo *const token, vString *const names,\n\t\t\t\t\t\t  int scope, vString *const accesses)\n{\n\tAssert (isToken (token, TOKEN_DECLARE) || isKeyword (token, KEYWORD_in));\n\tPARSER_PROLOGUE (\"decl\");\n\n\tif (isToken (token, TOKEN_DECLARE) || isKeyword (token, KEYWORD_in))\n\t{\n\t\tchar *name = names? vStringValue (names) : NULL;\n\t\tchar *access = accesses? vStringValue (accesses) : NULL;\n\t\twhile (name)\n\t\t{\n\t\t\tchar *n = name, *a = access;\n\t\t\tname = nextCharIdent (name, ',');\n\t\t\taccess = nextCharIdent (access, ',');\n\t\t\tmakeTagFull (token, n, KIND_VARIABLE, scope,\n\t\t\t\t\t\t ROLE_DEFINITION_INDEX, NULL, NULL, a);\n\t\t}\n\t}\n\treadToken (token);\n\tparseExprList (token, scope, NULL, false);\n\n\tPARSER_EPILOGUE ();\n}\n\n// if: 'if' list '?'? block ['else' [block | if]]?\nstatic void parseIf (tokenInfo *const token, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_if, KEYWORD_Sif));\n\tPARSER_PROLOGUE (\"if\");\n\n\tvString *access = NULL;\n\treadToken (token);\n\tskipAccessAndReadToken (token, &access);\n\tparseExprList (token, scope, access, false);\n\tvStringDelete (access);\n\treadToken (token);\n\tif (isToken (token, TOKEN_QUESTION))\n\t\treadToken (token);\n\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tparseBlock (token, scope, false);\n\t\treadToken (token);\n\t\tif (isKeyword (token, KEYWORD_else, KEYWORD_Selse))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isToken (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\tparseBlock (token, scope, false);\n\t\t\t\treadToken (token);\n\t\t\t\tif (!parseExprCont (token, scope, false))\n\t\t\t\t\tunreadToken (token);\n\t\t\t}\n\t\t\telse if (isKeyword (token, KEYWORD_if, KEYWORD_Sif))\n\t\t\t\tparseIf (token, scope);\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!expectToken (token, TOKEN_OPEN_CURLY, TOKEN_KEYWORD))\n\t\t\t\t\texpectKeyword (token, KEYWORD_if, KEYWORD_Sif);\n\t\t\t\tunreadToken (token);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tunreadToken (token);\n\t}\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// ret-vtype: [ '?' ret-vtype-rest | '!' ret-vtype-rest? ]?\n// ret-vtype-rest: ['(' any ')' | vtype ]\n// returns false if token is not matched\nstatic void parseRetVType (tokenInfo *const token, vString *const capture,\n\t\t\t\t\t\t   int scope) {\n\tPARSER_PROLOGUE (\"ret-vtype\");\n\n\tbool vtypeRequired = false;\n\n\tif (isToken (token, TOKEN_EXCLAMATION))\n\t\treadTokenFull (token, capture);\n\telse if (isToken (token, TOKEN_QUESTION))\n\t{\n\t\tvtypeRequired = true;\n\t\treadTokenFull (token, capture);\n\t}\n\n\tif (isToken (token, TOKEN_TYPE, TOKEN_IDENT))\n\t{\n\t\tsize_t len = capture? vStringLength (token->string) : 0;\n\t\tparseFullyQualified (token, !!capture);\n\t\tif (capture)\n\t\t\tvStringCatS (capture, vStringValue (token->string) + len);\n\t}\n\n\tif (!token->onNewline && isToken (token, TOKEN_OPEN_PAREN))\n\t\tskipToTokenFull (TOKEN_CLOSE_PAREN, capture, token);\n\telse if (token->onNewline || !isInitialType (token) ||\n\t\t\t !parseVType (token, capture, scope, false, false))\n\t{\n\t\tunreadTokenFull (token, capture);\n\t\tif (vtypeRequired)\n\t\t\tvDebugUnexpected (token, \"vtype\", 0);\n\t}\n\n\tPARSER_EPILOGUE ();\n}\n\n// fndef: 'fn' receiver? [fqident | kwtype] tmpl-args? args ret-vtype? block?\n// method: [fqident | kwtype] args vtype?\n// lambda: 'fn' [id | clsr-args]? tmpl-args? args vtype? block fncall?\n// fntype: 'fn' tmpl-args args vtype?\n//\n// receiver: '(' 'mut'? '*'? ident vtype ')'\n// tmpl-args: '[' any ']'\n// clsr-args: '[' any ']'\n// args: '(' any ')'\nstatic void parseFunction (tokenInfo *const token, int scope,\n\t\t\t\t\t\tvString *const access, kindType kind)\n{\n\tAssert (kind == KIND_FUNCTION || kind == KIND_METHOD ||\n\t\t\tkind == KIND_ALIAS || kind == KIND_GHOST_INDEX);\n\tAssert (kind == KIND_METHOD || isKeyword (token, KEYWORD_fn));\n\tPARSER_PROLOGUE (kind == KIND_FUNCTION? \"fndef\" :\n\t\t\t\t\t (kind == KIND_METHOD? \"method\" :\n\t\t\t\t\t  (kind == KIND_ALIAS? \"fntype\" : \"lambda\")));\n\n\t// TODO: make return false if calling function should not further read token\n\t// due to failure of this function to process token (like parseExpression)\n\n\tvString *receiver = NULL;\n\tvString *name = NULL;\n\tvString *acc = vStringNew ();\n\tvString *argList = vStringNew ();\n\tvString *retType = vStringNew ();\n\ttokenInfo *fnToken = dupToken (token);\n\ttokenInfo *rxToken = NULL;\n\treadToken (token);\n\n\t// receiver\n\tif (kind == KIND_FUNCTION && isToken (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tvStringPut (acc, '(');\n\t\treadTokenFull (token, acc);\n\t\tif (expectToken (token, TOKEN_IDENT, TOKEN_KEYWORD) ||\n\t\t\texpectKeyword (token, KEYWORD_mut))\n\t\t{\n\t\t\tif (isKeyword (token, KEYWORD_mut))\n\t\t\t\treadTokenFull (token, acc);\n\t\t\tif (expectToken (token, TOKEN_IDENT))\n\t\t\t{\n\t\t\t\trxToken = dupToken (token);\n\t\t\t\treceiver = vStringNewCopy (token->string);\n\n\t\t\t\treadTokenFull (token, acc);\n\t\t\t\tif (isToken (token, TOKEN_ASTERISK))\n\t\t\t\t\treadTokenFull (token, acc);\n\t\t\t\tif (!isToken (token, TOKEN_CLOSE_PAREN))\n\t\t\t\t{\n\t\t\t\t\tif (parseVType (token, acc, CORK_NIL, false, false))\n\t\t\t\t\t\treadTokenFull (token, acc);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (expectToken (token, TOKEN_CLOSE_PAREN))\n\t\t{\n\t\t\tvStringAccumulateMaybe (argList, acc);\n\t\t\treadToken (token);\n\t\t}\n\t\telse\n\t\t\tskipToToken (TOKEN_CLOSE_PAREN, NULL);\n\t}\n\t// name\n\tif ((kind == KIND_GHOST_INDEX && (\n\t\t\t isToken (token, TOKEN_IDENT, TOKEN_TYPE) ||\n\t\t\t isKeyword (token, KEYWORD_TYPE))) ||\n\t\t(kind == KIND_FUNCTION && (\n\t\t\texpectToken (token, TOKEN_IDENT, TOKEN_TYPE, TOKEN_KEYWORD,\n\t\t\t\t\t\t TOKEN_OPERATOR, TOKEN_PLUSMINUS, TOKEN_ANDAND,\n\t\t\t\t\t\t TOKEN_ASTERISK) ||\n\t\t\texpectKeyword (token, KEYWORD_TYPE, KEYWORD_map))))\n\t{\n\t\tif (isToken (token, TOKEN_KEYWORD))\n\t\t\tname = vStringNewCopy (token->string);\n\t\telse if (isToken (token, TOKEN_TYPE, TOKEN_IDENT))\n\t\t{\n\t\t\tname = vStringNew ();\n\t\t\tparseFQIdent (token, name);\n\t\t}\n\t\tdeleteToken (fnToken);\n\t\tfnToken = dupToken (token);\n\t\treadToken (token);\n\t}\n\t// closure args\n\tif (kind == KIND_GHOST_INDEX && name == NULL &&\n\t\tisToken (token, TOKEN_OPEN_SQUARE))\n\t{\n\t\tvStringPut (argList, '[');\n\t\tskipToToken (TOKEN_CLOSE_SQUARE, acc);\n\t\tvStringAccumulateMaybe (argList, acc);\n\t\treadToken (token);\n\t}\n\t// template args\n\tif ((kind == KIND_FUNCTION ||\n\t\t (kind == KIND_GHOST_INDEX && name == NULL)) &&\n\t\tisToken (token, TOKEN_OPEN_SQUARE))\n\t{\n\t\tvStringPut (argList, '[');\n\t\tskipToToken (TOKEN_CLOSE_SQUARE, acc);\n\t\tvStringAccumulateMaybe (argList, acc);\n\t\treadToken (token);\n\t}\n\t// args\n\tif (expectToken (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tvStringPut (argList, '(');\n\t\tskipToToken (TOKEN_CLOSE_PAREN, acc);\n\t\tvStringAccumulateMaybe (argList, acc);\n\t\t// next token could be ident of next interface method or struct field\n\t\treadTokenFull (token, acc);\n\t\tif (isToken (token, TOKEN_TYPE, TOKEN_IDENT))\n\t\t{\n\t\t\tsize_t len = vStringLength (token->string);\n\t\t\tparseFullyQualified (token, true);\n\t\t\tvStringCatS (acc, vStringValue (token->string) + len);\n\t\t}\n\t\t// return type (unless on next line)\n\t\tif (isInitialType (token) && !token->onNewline)\n\t\t{\n\t\t\tparseRetVType (token, acc, scope);\n\t\t\tvStringAccumulateMaybe (retType, acc);\n\t\t\treadToken (token);\n\t\t}\n\t\telse if (isToken (token, TOKEN_OPEN_PAREN))\n\t\t{\n\t\t\tskipToToken (TOKEN_CLOSE_PAREN, acc);\n\t\t\tvStringAccumulateMaybe (retType, acc);\n\t\t\treadToken (token);\n\t\t}\n\t\telse if ((kind == KIND_METHOD || kind == KIND_ALIAS) &&\n\t\t\t\t isToken (token, TOKEN_IDENT))\n\t\t{\n\t\t\tvStringCopy (token->string, acc);\n\t\t\tvStringDelete (acc);\n\t\t\tacc = NULL;\n\t\t}\n\t\tint newScope = CORK_NIL;\n\t\tif (name || kind == KIND_METHOD)\n\t\t{\n\t\t\tkindType realKind = kind == KIND_GHOST_INDEX? KIND_FUNCTION : kind;\n\t\t\tint realScope = name?\n\t\t\t\tlookupQualifiedName (fnToken, name, scope, NULL) : scope;\n\t\t\tnewScope = makeFnTag (fnToken, name, realKind, realScope,\n\t\t\t\t\t\t\t\t  argList, retType, access);\n\t\t\tmakeForeignDeclTagMaybe (fnToken, name, realKind, realScope);\n\n\t\t\tif (receiver)\n\t\t\t\tmakeTag (rxToken, NULL, KIND_RECEIVER, newScope);\n\t\t}\n\t\t// block\n\t\tif ((kind == KIND_GHOST_INDEX && expectToken (token, TOKEN_OPEN_CURLY)) ||\n\t\t\t(kind == KIND_FUNCTION && isToken (token, TOKEN_OPEN_CURLY)))\n\t\t{\n\t\t\tint lineNumber = parseBlock (token, newScope, false);\n\t\t\ttagEntryInfo *entry = getEntryInCorkQueue (newScope);\n\t\t\tif (entry)\n\t\t\t\tsetTagEndLine (entry, lineNumber);\n\t\t\t// fncall\n\t\t\tif (kind == KIND_GHOST_INDEX)\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (isToken (token, TOKEN_OPEN_PAREN))\n\t\t\t\t\tparseFnCall (token, newScope);\n\t\t\t\telse\n\t\t\t\t\tunreadToken (token);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tunreadToken (token);\n\t}\n\telse\n\t\tunreadToken (token);\n\tdeleteToken (fnToken);\n\tdeleteToken (rxToken);\n\tvStringDelete (receiver);\n\tvStringDelete (name);\n\tvStringDelete (acc);\n\tvStringDelete (argList);\n\tvStringDelete (retType);\n\n\tPARSER_EPILOGUE ();\n}\n\n// chpop: '<-' ident ['or' block]?\nstatic void parseChanPop (tokenInfo *const token, int scope)\n{\n\tAssert (isToken (token, TOKEN_CHPOP));\n\tPARSER_PROLOGUE (\"chpop\");\n\n\treadToken (token);\n\tif (expectToken (token, TOKEN_IDENT, TOKEN_TYPE))\n\t{\n\t\tparseFQIdent (token, NULL);\n\t\treadToken (token);\n\t\tif (isKeyword (token, KEYWORD_or))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t\t\t\tparseBlock (token, scope, true);\n\t\t\telse\n\t\t\t\tunreadToken (token);\n\t\t}\n\t\telse\n\t\t\tunreadToken (token);\n\t}\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// match: 'match' access* fqident cont '{' [\n//     [[vtype fncall? | expr] [',' [vtype | expr]]* | 'else'] block\n// ]* '}'\nstatic void parseMatch (tokenInfo *const token, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_match));\n\tPARSER_PROLOGUE (\"match\");\n\n\treadToken (token);\n\tskipAccessAndReadToken (token, NULL);\n\tif (!isClose (token))\n\t{\n\t\tparseExprList (token, scope, NULL, false);\n\t\treadToken (token);\n\t}\n\tif (!expectToken (token, TOKEN_OPEN_CURLY))\n\t\tskipToTokenFull (TOKEN_OPEN_CURLY, NULL, token);\n\tif (isToken (token, TOKEN_OPEN_CURLY))\n\t{\n\t\treadToken (token);\n\t\tdo // match clauses\n\t\t{\n\t\t\twhile (true) // match clause comma-list\n\t\t\t{\n\t\t\t\tif (isToken (token, TOKEN_TYPE, TOKEN_IDENT))\n\t\t\t\t\tparseFullyQualified (token, true);\n\n\t\t\t\tif (isToken (token, TOKEN_OPEN_CURLY, TOKEN_CLOSE_CURLY))\n\t\t\t\t\tbreak;\n\t\t\t\telse if (isInitialType (token))\n\t\t\t\t{\n\t\t\t\t\tif (parseVType (token, NULL, scope, false, false))\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tif (isToken (token, TOKEN_OPEN_PAREN)) // cast\n\t\t\t\t\t\t\tparseFnCall (token, scope);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tunreadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (isKeyword (token, KEYWORD_else))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tparseExpression (token, scope, NULL);\n\t\t\t\treadToken (token);\n\t\t\t\tif (!isToken (token, TOKEN_COMMA))\n\t\t\t\t\tbreak;\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\tparseBlock (token, scope, false);\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t\twhile (!isToken (token, TOKEN_EOF, TOKEN_CLOSE_CURLY));\n\t\tif (!expectToken (token, TOKEN_CLOSE_CURLY))\n\t\t\tskipToToken (TOKEN_CLOSE_CURLY, NULL);\n\t}\n\n\tPARSER_EPILOGUE ();\n}\n\n// select: 'select' '{' [list block]* '}'\nstatic void parseSelect (tokenInfo *const token, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_select));\n\tPARSER_PROLOGUE (\"select\");\n\n\treadToken (token);\n\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t{\n\t\treadToken (token);\n\t\tdo // select clauses\n\t\t{\n\t\t\tif (!isToken (token, TOKEN_CLOSE_CURLY))\n\t\t\t\tparseExprList (token, scope, NULL, false);\n\t\t\treadToken (token);\n\t\t\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\tparseBlock (token, scope, false);\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t}\n\t\twhile (!isToken (token, TOKEN_EOF, TOKEN_CLOSE_CURLY));\n\t\texpectToken (token, TOKEN_CLOSE_CURLY);\n\t}\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// for: list? [';' expr]* block\nstatic void parseFor (tokenInfo *const token, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_for, KEYWORD_Sfor));\n\tPARSER_PROLOGUE (\"for\");\n\n\tvString *access = NULL;\n\treadToken (token);\n\tskipAccessAndReadToken (token, &access);\n\tif (!isToken (token, TOKEN_OPEN_CURLY, TOKEN_SEMICOLON, TOKEN_EOF))\n\t{\n\t\tparseExprList (token, CORK_NIL, access, true);\n\t\treadToken (token);\n\t}\n\tvStringDelete (access);\n\twhile (isToken (token, TOKEN_SEMICOLON))\n\t{\n\t\treadToken (token);\n\t\tif (isToken (token, TOKEN_OPEN_CURLY, TOKEN_EOF))\n\t\t\tbreak;\n\t\telse if (!isToken (token, TOKEN_SEMICOLON))\n\t\t{\n\t\t\tparseExpression (token, scope, NULL);\n\t\t\treadToken (token);\n\t\t}\n\t}\n\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t\tparseBlock (token, scope, false);\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// import: 'import' fqident ['as' ident]? ['{' ident [',' ident]* '}']?\nstatic void parseImport (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_import));\n\tPARSER_PROLOGUE (\"import\");\n\n\tstatic const refSpec makeModules = {\n\t\t.kind = KIND_MODULE,\n\t\t.role = ROLE_IMPORTED_MODULE\n\t};\n\n\treadToken (token);\n\tif (expectToken (token, TOKEN_IDENT))\n\t{\n\t\ttokenInfo *moduleToken = dupToken (token);\n\t\tvString *moduleName = vStringNew ();\n\t\tint scope = CORK_NIL;\n\t\tparseFQIdent (token, moduleName);\n\t\treadToken (token);\n\t\tif (isKeyword (token, KEYWORD_as))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (expectToken (token, TOKEN_IDENT))\n\t\t\t\tvStringCopy (moduleName, token->string);\n\t\t\treadToken (token);\n\t\t}\n\t\telse\n\t\t\tscope = lookupQualifiedName (\n\t\t\t\tmoduleToken, moduleName, scope, &makeModules);\n\t\tint moduleScope = makeRefTag (moduleToken, moduleName, KIND_MODULE,\n\t\t\t\t\t\t\t\t\t  scope, ROLE_IMPORTED_MODULE);\n\t\tvStringDelete (moduleName);\n\t\tdeleteToken (moduleToken);\n\t\tif (isToken (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\tdo\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (expectToken (token, TOKEN_IDENT, TOKEN_TYPE))\n\t\t\t\t{\n\t\t\t\t\tmakeRefTag (token, NULL, KIND_UNKNOWN, moduleScope,\n\t\t\t\t\t\t\t\tROLE_IMPORTED_SYMBOL);\n\t\t\t\t\treadToken (token);\n\t\t\t\t\texpectToken (token, TOKEN_COMMA, TOKEN_CLOSE_CURLY);\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile (!isToken (token, TOKEN_EOF, TOKEN_CLOSE_CURLY));\n\t\t}\n\t\telse\n\t\t\tunreadToken (token);\n\t}\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// struct: 'struct' [fqtype | extern] ['[' any ']']? struct-rest\n// iface: 'interface' [fqtype | extern] ['[' any ']']? struct-rest\n// union: 'union' [fqtype | extern] ['[' any ']']? struct-rest\n// anon: ['struct' | 'union'] [[fqtype | extern] ['[' any ']']?]? struct-rest\n// struct-rest: '{' [\n//     [access* ':'] | [\n//         fqtype | extern | [ident | kwtype | 'map'] method |\n//         [ident | extern] vtype ['@'? '[' any ']']? ['=' expr]?\n//     ]*\n// ]* '}'\nstatic void parseStruct (tokenInfo *const token, vString *const access,\n\t\t\t\t\t\t int scope, kindType kind)\n{\n\tAssert (\n\t\t(kind == KIND_STRUCT && isKeyword (token, KEYWORD_struct)) ||\n\t\t(kind == KIND_INTERFACE && isKeyword (token, KEYWORD_interface)) ||\n\t\t(kind == KIND_UNION && isKeyword (token, KEYWORD_union)) ||\n\t\t(kind == KIND_GHOST_INDEX && isKeyword (token, KEYWORD_struct, KEYWORD_union)));\n\tPARSER_PROLOGUE (kind == KIND_INTERFACE? \"iface\" :\n\t\t\t\t\t (kind == KIND_UNION? \"union\" :\n\t\t\t\t\t  (kind == KIND_STRUCT? \"struct\" : \"anon\")));\n\n\tint newScope = scope;\n\treadToken (token);\n\n\t// name\n\tif ((kind == KIND_STRUCT || kind == KIND_INTERFACE) && PS->isBuiltin &&\n\t\tscope == CORK_NIL && isKeyword (token, KEYWORD_TYPE, KEYWORD_map))\n\t\treadToken (token);\n\telse if ((kind != KIND_GHOST_INDEX && expectToken (token, TOKEN_TYPE)) ||\n\t\t\t (kind == KIND_GHOST_INDEX && isToken (token, TOKEN_TYPE)))\n\t{\n\t\tparseFullyQualified (token, true);\n\t\tif (expectToken (token, TOKEN_TYPE, TOKEN_EXTERN))\n\t\t{\n\t\t\tscope = lookupQualifiedName (token, NULL, scope, false);\n\t\t\tkindType realKind = kind == KIND_GHOST_INDEX? KIND_STRUCT : kind;\n\t\t\tnewScope = makeTagEx (token, NULL, realKind, scope, access);\n\t\t\tmakeForeignDeclTagMaybe (token, NULL, realKind, scope);\n\t\t\tregisterEntry (newScope);\n\t\t\treadToken (token);\n\t\t}\n\t\tif (isToken (token, TOKEN_OPEN_SQUARE)) // template args\n\t\t{\n\t\t\tskipToToken (TOKEN_CLOSE_SQUARE, NULL);\n\t\t\treadToken (token);\n\t\t}\n\t}\n\n\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tvString *fieldAccess = NULL;\n\t\treadToken (token);\n\t\twhile (!isToken (token, TOKEN_CLOSE_CURLY, TOKEN_EOF))\n\t\t{\n\t\t\tvString *tmp = NULL;\n\t\t\tskipAccessAndReadToken (token, &tmp);\n\t\t\tif (tmp)\n\t\t\t{\n\t\t\t\tvStringDelete (fieldAccess);\n\t\t\t\tfieldAccess = tmp;\n\t\t\t\tif(expectToken (token, TOKEN_COLON))\n\t\t\t\t\treadToken (token);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (isToken (token, TOKEN_TYPE, TOKEN_IDENT))\n\t\t\t\tparseFullyQualified (token, true);\n\n\t\t\t// if set, parse field below (with next token already read)\n\t\t\ttokenInfo *fieldToken = NULL;\n\n\t\t\tif (isToken (token, TOKEN_IDENT))\n\t\t\t{\n\t\t\t\tfieldToken = dupToken (token);\n\t\t\t\treadToken (token);\n\t\t\t\tif (kind == KIND_INTERFACE && isToken (token, TOKEN_OPEN_PAREN))\n\t\t\t\t{\n\t\t\t\t\tunreadToken (token);\n\t\t\t\t\tcopyToken (token, fieldToken);\n\t\t\t\t\tdeleteToken (fieldToken);\n\t\t\t\t\tparseFunction (token, newScope, fieldAccess, KIND_METHOD);\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tcontinue; // method\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (kind == KIND_INTERFACE &&\n\t\t\t\t\t isKeyword (token, KEYWORD_TYPE, KEYWORD_map))\n\t\t\t{\n\t\t\t\tparseFunction (token, newScope, fieldAccess, KIND_METHOD);\n\t\t\t\treadToken (token);\n\t\t\t\tcontinue; // method\n\t\t\t}\n\t\t\telse if (isToken (token, TOKEN_TYPE))\n\t\t\t{\n\t\t\t\tif (PS->isBuiltin)\n\t\t\t\t{\n\t\t\t\t\tfieldToken = dupToken (token);\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (token->onNewline)\n\t\t\t\t\t{\n\t\t\t\t\t\tdeleteToken (fieldToken);\n\t\t\t\t\t\tcontinue; // embed type (after all)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tcontinue; // embedded type\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (isToken (token, TOKEN_EXTERN))\n\t\t\t{\n\t\t\t\tfieldToken = dupToken (token);\n\t\t\t\treadToken (token);\n\t\t\t\tif (token->onNewline)\n\t\t\t\t{\n\t\t\t\t\tdeleteToken (fieldToken);\n\t\t\t\t\tcontinue; // embedded extern\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\texpectToken (token, TOKEN_TYPE, TOKEN_IDENT, TOKEN_EXTERN,\n\t\t\t\t\t\t\t TOKEN_KEYWORD);\n\t\t\t\tskipToToken (TOKEN_CLOSE_CURLY, false);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (fieldToken) // parse field\n\t\t\t{\n\t\t\t\tif (parseVType (token, NULL, newScope, false, false))\n\t\t\t\t{\n\t\t\t\t\tmakeTagEx (fieldToken, NULL, KIND_FIELD, newScope,\n\t\t\t\t\t\t\t   fieldAccess);\n\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isToken (token, TOKEN_ASSIGN))\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tif (parseExpression (token, newScope, NULL))\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t\tif (isToken (token, TOKEN_AT))\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tif (expectToken (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tskipToToken (TOKEN_CLOSE_SQUARE, NULL);\n\t\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (isToken (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipToToken (TOKEN_CLOSE_SQUARE, NULL);\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tvDebugUnexpected (token, \"vtype\", 0);\n\t\t\t\tdeleteToken (fieldToken);\n\t\t\t}\n\t\t}\n\t\tvStringDelete (fieldAccess);\n\t}\n\n\tif (kind != KIND_GHOST_INDEX)\n\t{\n\t\ttagEntryInfo *entry = getEntryInCorkQueue (newScope);\n\t\tif (entry)\n\t\t\tsetTagEndLine (entry, token->lineNumber);\n\t}\n\n\tPARSER_EPILOGUE ();\n}\n\n// enum: 'enum' type ['as' type]? '{' [\n//     [ident | kwtype] ['=' [immediate | extern]]? ['@'? '[' any ']']?\n// ]* '}'\nstatic void parseEnum (tokenInfo *const token, vString *const access, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_enum));\n\tPARSER_PROLOGUE (\"enum\");\n\n\treadToken (token);\n\tif (expectToken (token, TOKEN_TYPE)) {\n\t\tint newScope = makeTagEx (token, NULL, KIND_ENUMERATION, scope, access);\n\t\tregisterEntry (newScope);\n\t\treadToken (token);\n\t\tif (isKeyword (token, KEYWORD_as))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (expectToken (token, TOKEN_TYPE, TOKEN_KEYWORD) ||\n\t\t\t\texpectKeyword (token, KEYWORD_TYPE))\n\t\t\t\treadToken (token);\n\t\t}\n\t\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\treadToken (token);\n\t\t\twhile (expectToken (token, TOKEN_CLOSE_CURLY, TOKEN_IDENT,\n\t\t\t\t\t\t\t\tTOKEN_KEYWORD) ||\n\t\t\t\t   expectKeyword (token, KEYWORD_TYPE, KEYWORD_map,\n\t\t\t\t\t\t\t\t  KEYWORD_chan))\n\t\t\t{\n\t\t\t\tif (isToken (token, TOKEN_CLOSE_CURLY))\n\t\t\t\t\tbreak;\n\n\t\t\t\tmakeTag (token, NULL, KIND_ENUMERATOR, newScope);\n\n\t\t\t\treadToken (token);\n\t\t\t\tif (isToken (token, TOKEN_ASSIGN))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (isToken (token, TOKEN_IDENT, TOKEN_TYPE))\n\t\t\t\t\t\tparseFullyQualified (token, true);\n\t\t\t\t\tif (expectToken (token, TOKEN_IMMEDIATE, TOKEN_EXTERN))\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\n\t\t\t\tif (isToken (token, TOKEN_AT))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (expectToken (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t\t{\n\t\t\t\t\t\tskipToToken (TOKEN_CLOSE_SQUARE, NULL);\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (isToken (token, TOKEN_OPEN_SQUARE))\n\t\t\t\t{\n\t\t\t\t\tskipToToken (TOKEN_CLOSE_SQUARE, NULL);\n\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttagEntryInfo *entry = getEntryInCorkQueue (newScope);\n\t\t\tif (entry)\n\t\t\t\tsetTagEndLine (entry, token->lineNumber);\n\t\t}\n\t}\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// vtype: [\n//    '[' any ']' [vtype init?]? | '?' vtype | ['&' | '&&'] vtype init? |\n//    [fqtype | extern] ['[' any ']']? init? | 'fn' fntype |\n//    ['chan' | 'shared'] vtype init? | 'map' '[' any ']' vtype init? |\n//    kwtype | '$map' | '$struct' | '$enum' | '$array' | '$sumtype' | '$alias' |\n//    'struct' struct init? | 'union' union init?\n// ]\n// returns false if token is not matched\n// set letInit false to parse *only* V type (with no {...} initialisation after)\n// set canInit false unless tokens already read which would permit it (e.g., [])\nstatic bool parseVType (tokenInfo *const token, vString *const capture,\n\t\t\t\t\t\tint scope, bool canInit, bool letInit)\n{\n\tPARSER_PROLOGUE (\"vtype\");\n\n\tbool ok = true;\n\n\tif (isToken (token, TOKEN_OPEN_SQUARE))\n\t{\n\t\tskipToToken (TOKEN_CLOSE_SQUARE, capture);\n\t\treadTokenFull (token, capture);\n\t\tif (parseVType (token, capture, scope, false, false))\n\t\t\tcanInit = true;\n\t\telse\n\t\t\tunreadTokenFull (token, capture);\n\t}\n\telse if (isToken (token, TOKEN_QUESTION))\n\t{\n\t\treadTokenFull (token, capture);\n\t\tif (!parseVType (token, capture, scope, false, false))\n\t\t{\n\t\t\tvDebugUnexpected (token, \"vtype\", 0);\n\t\t\tunreadTokenFull (token, capture);\n\t\t}\n\t}\n\telse if (isToken (token, TOKEN_AMPERSAND, TOKEN_ANDAND))\n\t{\n\t\treadTokenFull (token, capture);\n\t\tif (parseVType (token, capture, scope, false, false))\n\t\t\tcanInit = true;\n\t\telse\n\t\t{\n\t\t\tvDebugUnexpected (token, \"vtype\", 0);\n\t\t\tunreadTokenFull (token, capture);\n\t\t}\n\t}\n\telse if (isToken (token, TOKEN_TYPE, TOKEN_IDENT, TOKEN_EXTERN))\n\t{\n\t\tsize_t len = capture? vStringLength (token->string) : 0;\n\t\tparseFullyQualified (token, !!capture);\n\t\tif (capture)\n\t\t\tvStringCatS (capture, vStringValue (token->string) + len);\n\t\tif (expectToken (token, TOKEN_TYPE, TOKEN_EXTERN, TOKEN_KEYWORD) ||\n\t\t\texpectKeyword (token, KEYWORD_none))\n\t\t{\n\t\t\tcanInit = true;\n\t\t\treadTokenFull (token, capture);\n\t\t\tif (isToken (token, TOKEN_OPEN_SQUARE))\n\t\t\t\tskipToToken (TOKEN_CLOSE_SQUARE, capture);\n\t\t\telse\n\t\t\t\tunreadTokenFull (token, capture);\n\t\t}\n\t}\n\telse if (isKeyword (token, KEYWORD_TYPE, KEYWORD_none))\n\t\t;\n\telse if (isKeyword (token, KEYWORD_chan, KEYWORD_shared))\n\t{\n\t\treadTokenFull (token, capture);\n\t\tif (parseVType (token, capture, scope, false, false))\n\t\t\tcanInit = true;\n\t\telse\n\t\t\tunreadTokenFull (token, capture);\n\t}\n\telse if (isKeyword (token, KEYWORD_map))\n\t{\n\t\treadTokenFull (token, capture);\n\t\tif ((!PS->isBuiltin && expectToken (token, TOKEN_OPEN_SQUARE)) ||\n\t\t\t(PS->isBuiltin && isToken (token, TOKEN_OPEN_SQUARE)))\n\t\t{\n\t\t\tskipToToken (TOKEN_CLOSE_SQUARE, capture);\n\t\t\treadTokenFull (token, capture);\n\t\t\tif (parseVType (token, capture, scope, false, false))\n\t\t\t\tcanInit = true;\n\t\t\telse\n\t\t\t\tunreadTokenFull (token, capture);\n\t\t}\n\t\telse\n\t\t\tunreadTokenFull (token, capture);\n\t}\n\telse if (isKeyword (token, KEYWORD_struct, KEYWORD_union))\n\t{\n\t\tparseStruct (token, NULL, scope, KIND_GHOST_INDEX);\n\t\tcanInit = true;\n\t}\n\telse if (isKeyword (token, KEYWORD_fn) && !token->onNewline)\n\t\tparseFunction (token, scope, NULL, KIND_ALIAS);\n\telse\n\t\tok = false;\n\n\tif (letInit && canInit)\n\t{\n\t\treadTokenFull (token, capture);\n\t\tif (isToken (token, TOKEN_OPEN_CURLY))\n\t\t\tparseInit (token, scope);\n\t\telse\n\t\t\tunreadTokenFull (token, capture);\n\t}\n\n\tPARSER_EPILOGUE ();\n\treturn ok;\n}\n\n// alias: 'type' type ['[' type ']']? '=' vtype ['|' vtype]*\nstatic void parseAlias (tokenInfo *const token, vString *const access, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_type));\n\tPARSER_PROLOGUE (\"alias\");\n\n\treadToken (token);\n\tif (isToken (token, TOKEN_TYPE, TOKEN_IDENT))\n\t\tparseFullyQualified (token, false);\n\tif ((!PS->isBuiltin && expectToken (token, TOKEN_TYPE, TOKEN_EXTERN)) ||\n\t\t(PS->isBuiltin && (\n\t\t\texpectToken (token, TOKEN_TYPE, TOKEN_EXTERN, TOKEN_KEYWORD) ||\n\t\t\texpectKeyword (token, KEYWORD_TYPE))))\n\t{\n\t\tint newScope = makeTagEx (token, NULL, KIND_ALIAS, scope, access);\n\t\tregisterEntry (newScope);\n\t\treadToken (token);\n\t\tif (isToken (token, TOKEN_OPEN_SQUARE)) // template args\n\t\t{\n\t\t\tskipToToken (TOKEN_CLOSE_SQUARE, NULL);\n\t\t\treadToken (token);\n\t\t}\n\t\tif (expectToken (token, TOKEN_ASSIGN))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif(parseVType (token, NULL, scope, false, false))\n\t\t\t\treadToken (token);\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tif (isToken (token, TOKEN_PIPE))\n\t\t\t\t{\n\t\t\t\t\treadToken (token);\n\t\t\t\t\tif (parseVType (token, NULL, scope, false, false))\n\t\t\t\t\t{\n\t\t\t\t\t\treadToken (token);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tunreadToken (token);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tunreadToken (token);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tPARSER_EPILOGUE ();\n}\n\n// list: [\n//     [access* ident [',' access* ident]* [':=' | 'in'] list] |\n//     [expr? [',' expr]*]\n// ]\nstatic void parseExprList (tokenInfo *const token, int scope,\n\t\t\t\t\t\t   vString *const access, bool hasInDecl)\n{\n\tPARSER_PROLOGUE (\"list\");\n\n\t// attempt to consume multi-var declaration (special case of list)\n\tbool consumedIdent = true;\n\tif (isToken (token, TOKEN_IDENT))\n\t{\n\t\ttokenInfo *identToken = dupToken (token);\n\t\tvString *accesses = accesses = access? access : vStringNew ();\n\t\tvString *idents = vStringNewCopy (token->string);\n\t\treadToken (token);\n\t\tif (isToken (token, TOKEN_COMMA))\n\t\t{\n\t\t\tdo\n\t\t\t{\n\t\t\t\tvStringPut (accesses, ',');\n\t\t\t\tvStringPut (idents, ',');\n\t\t\t\treadToken (token);\n\t\t\t\tskipAccessAndReadToken (token, &accesses);\n\t\t\t\tif (!isToken (token, TOKEN_IDENT))\n\t\t\t\t\tconsumedIdent = false;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tdeleteToken (identToken);\n\t\t\t\t\tidentToken = dupToken (token);\n\t\t\t\t\tvStringCat (idents, token->string);\n\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile (consumedIdent && isToken (token, TOKEN_COMMA));\n\t\t}\n\t\tif (consumedIdent)\n\t\t{\n\t\t\tif (isToken (token, TOKEN_DECLARE) ||\n\t\t\t\t(hasInDecl && isKeyword (token, KEYWORD_in)))\n\t\t\t\tparseDeclare (token, idents, scope, accesses);\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (isToken (token, TOKEN_DOT))\n\t\t\t\t{\n\t\t\t\t\tunreadToken (token);\n\t\t\t\t\tparseFullyQualified (identToken, false);\n\t\t\t\t\tif (isToken (identToken, TOKEN_TYPE))\n\t\t\t\t\t\tparseVType (identToken, NULL, scope, false, true);\n\t\t\t\t\treadToken (token);\n\t\t\t\t}\n\t\t\t\tif (!parseExprCont (token, scope, true))\n\t\t\t\t\tunreadToken (token);\n\t\t\t}\n\t\t}\n\t\tdeleteToken (identToken);\n\t\tvStringDelete (idents);\n\t\tif (!access)\n\t\t\tvStringDelete (accesses);\n\t}\n\telse\n\t\tparseExpression (token, scope, NULL);\n\n\twhile (true)\n\t{\n\t\tif (!consumedIdent)\n\t\t\tconsumedIdent = true;\n\t\telse\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (!isToken (token, TOKEN_COMMA))\n\t\t\t\tbreak;\n\t\t\treadToken (token);\n\t\t\tskipAccessAndReadToken (token, NULL);\n\t\t}\n\t\tif (isToken (token, TOKEN_EOF, TOKEN_CLOSE_PAREN, TOKEN_CLOSE_SQUARE,\n\t\t\t\t\t TOKEN_CLOSE_CURLY))\n\t\t\tbreak;\n\t\tparseExpression (token, scope, NULL);\n\t}\n\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// err: ['!' | '?' | 'or' block]?\n// cont: ['--' | '++']? [\n//     chain | op expr | '...' expr? | ['is' | 'as'] vtype cont |\n//     '[' '...'? list ']' err-cont | ['=' ':='] expr | fncall\n// ]?\n// return false if token is rejected\nstatic bool parseExprCont (tokenInfo *const token, int scope, bool hasErr)\n{\n\tbool ok = true;\n\n\tif (isClose (token))\n\t\tok = false;\n\n\tif (ok && hasErr)\n\t{\n\t\tPARSER_PROLOGUE (\"err\");\n\n\t\tif (isToken (token, TOKEN_EXCLAMATION, TOKEN_QUESTION))\n\t\t\treadToken (token);\n\t\telse if (isKeyword (token, KEYWORD_or))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t\t\t{\n\t\t\t\tparseBlock (token, scope, true);\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t}\n\n\t\tPARSER_EPILOGUE ();\n\t}\n\n\tif (ok)\n\t{\n\t\tPARSER_PROLOGUE (\"cont\");\n\n\t\tif (isToken (token, TOKEN_INCDECOP))\n\t\t\treadToken (token);\n\t\tif (isToken (token, TOKEN_DOT))\n\t\t{\n\t\t\t// could be enumerator label\n\t\t\ttokenInfo *tmpToken = newToken ();\n\t\t\tbool isLabel;\n\t\t\treadToken (tmpToken);\n\t\t\tisLabel = isToken (tmpToken, TOKEN_LABEL);\n\t\t\tunreadToken (tmpToken);\n\t\t\tif (isLabel)\n\t\t\t\tunreadToken (token);\n\t\t\telse\n\t\t\t\tparseChain (token, scope);\n\t\t\tdeleteToken (tmpToken);\n\t\t}\n\t\telse if (isOperator (token))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tparseExpression (token, scope, NULL);\n\t\t}\n\t\telse if (isToken (token, TOKEN_SLICE))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (!isClose (token))\n\t\t\t\tparseExpression (token, scope, NULL);\n\t\t\telse\n\t\t\t\tunreadToken (token);\n\t\t}\n\t\telse if (isKeyword (token, KEYWORD_is, KEYWORD_as))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isKeyword (token, KEYWORD_Sfloat, KEYWORD_Sarray, KEYWORD_Senum,\n\t\t\t               KEYWORD_Sstruct, KEYWORD_Smap, KEYWORD_Salias) ||\n\t\t\t\tparseVType (token, NULL, scope, false, false))\n\t\t\t\treadToken (token);\n\t\t\tif (!parseExprCont (token, scope, false))\n\t\t\t\tunreadToken (token);\n\t\t}\n\t\telse if (isToken (token, TOKEN_OPEN_SQUARE) && !token->onNewline)\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isToken (token, TOKEN_SLICE))\n\t\t\t\treadToken (token);\n\t\t\tif (!isClose (token))\n\t\t\t{\n\t\t\t\tparseExprList (token, scope, NULL, false);\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\tif (expectToken (token, TOKEN_CLOSE_SQUARE))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (!parseExprCont (token, scope, true))\n\t\t\t\t\tunreadToken (token);\n\t\t\t}\n\t\t\telse\n\t\t\t\tunreadToken (token);\n\t\t}\n\t\telse if (isToken (token, TOKEN_DECLARE, TOKEN_ASSIGN))\n\t\t{\n\t\t\texpectToken (token, TOKEN_ASSIGN);\n\t\t\treadToken (token);\n\t\t\tparseExprList (token, scope, NULL, false);\n\t\t}\n\t\telse if (isToken (token, TOKEN_OPEN_PAREN))\n\t\t\tparseFnCall (token, scope);\n\t\telse\n\t\t\tok = false;\n\n\t\tPARSER_EPILOGUE ();\n\t}\n\n\treturn ok;\n}\n\n// unsafe: 'unsafe' block cont?\nstatic void parseUnsafe (tokenInfo *const token, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_unsafe));\n\tPARSER_PROLOGUE (\"unsafe\");\n\n\treadToken (token);\n\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tparseBlock (token, scope, false);\n\t\treadToken (token);\n\t\tif (!parseExprCont (token, scope, false))\n\t\t\tunreadToken (token);\n\t}\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// lock: ['lock' | 'rlock'] fqident? block\nstatic void parseLock (tokenInfo *const token, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_lock, KEYWORD_rlock));\n\tPARSER_PROLOGUE (\"lock\");\n\n\treadToken (token);\n\tif (isToken (token, TOKEN_IDENT, TOKEN_TYPE))\n\t{\n\t\tparseFQIdent (token, NULL);\n\t\treadToken (token);\n\t}\n\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t\tparseBlock (token, scope, false);\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// sql: 'sql' fqident '{' any '}' err cont\nstatic void parseSql (tokenInfo *const token, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_sql));\n\tPARSER_PROLOGUE (\"sql\");\n\n\treadToken (token);\n\tif (expectToken (token, TOKEN_IDENT, TOKEN_TYPE))\n\t\tparseFullyQualified (token, false);\n\treadToken (token);\n\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t{\n\t\tskipToToken (TOKEN_CLOSE_CURLY, NULL);\n\t\treadToken (token);\n\t\tif (!parseExprCont (token, scope, true))\n\t\t\tunreadToken (token);\n\t}\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// expr: access* label? [\n//     [fqident | 'none' | kwtype] err-cont | extern ['{' '}' | err-cont ] |\n//     '.' [ident | kwtype | 'map' | 'chan'] cont | '(' expr ')' |\n//     vtype cont? | kwtype fncall? | immediate cont | 'struct'? init |\n//     lock | sql | lambda | if | match | select | chpop | unsafe |\n//     ['~' | '!' | '?' | '*' | '&' | '+' | '-' | 'spawn' | 'go'] expr |\n//     '[' list ']' '!'? [cont | vtype]? | '[' ']' [vtype fncall?]?\n// ]\nstatic bool parseExpression (tokenInfo *const token, int scope,\n\t\t\t\t\t\t\t vString *const access)\n{\n\tPARSER_PROLOGUE (\"expr\");\n\n\tbool ok = true;\n\tbool cont = false, contErr = false, contRead = false;\n\n\tskipAccessAndReadToken (token, NULL);\n\n\tif (isToken (token, TOKEN_LABEL))\n\t\treadToken (token);\n\n\tif (isToken (token, TOKEN_IDENT, TOKEN_TYPE))\n\t\tparseFullyQualified (token, false);\n\tif (isToken (token, TOKEN_IDENT) ||\n\t\tisKeyword (token, KEYWORD_none, KEYWORD_TYPE))\n\t\tcont = contRead = contErr = true;\n\telse if (isToken (token, TOKEN_EXTERN))\n\t{\n\t\treadToken (token);\n\t\tif (isToken (token, TOKEN_OPEN_CURLY))\n\t\t{\n\t\t\ttokenInfo *tmpToken = newToken ();\n\t\t\treadToken (tmpToken);\n\t\t\tif (!isToken (tmpToken, TOKEN_CLOSE_CURLY))\n\t\t\t{\n\t\t\t\tunreadToken (tmpToken);\n\t\t\t\tcont = contErr = true;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tcont = contErr = true;\n\t}\n\telse if (isToken (token, TOKEN_DOT)) // enumerators\n\t{\n\t\treadToken (token);\n\t\tif (expectToken (token, TOKEN_IDENT, TOKEN_KEYWORD) ||\n\t\t\texpectKeyword (token, KEYWORD_TYPE, KEYWORD_map, KEYWORD_chan))\n\t\t\tcont = contRead = true;\n\t\telse // if (isClose (token))\n\t\t\tunreadToken (token);\n\t}\n\telse if (isToken (token, TOKEN_IMMEDIATE))\n\t\tcont = contRead = true;\n\telse if (isToken (token, TOKEN_TYPE))\n\t{\n\t\tparseVType (token, NULL, scope, false, true);\n\t\treadToken (token);\n\t\tif (isToken (token, TOKEN_OPEN_PAREN, TOKEN_OPERATOR) ||\n\t\t\tisKeyword (token, KEYWORD_is, KEYWORD_in))\n\t\t\tcont = true;\n\t\telse\n\t\t\tunreadToken (token);\n\t}\n\telse if (isKeyword (token, KEYWORD_lock, KEYWORD_rlock))\n\t\tparseLock (token, scope);\n\telse if (isKeyword (token, KEYWORD_sql))\n\t\tparseSql (token, scope);\n\telse if (isKeyword (token, KEYWORD_fn))\n\t\tparseFunction (token, scope, NULL, KIND_GHOST_INDEX);\n\telse if (isKeyword (token, KEYWORD_if, KEYWORD_Sif))\n\t\tparseIf (token, scope);\n\telse if (isKeyword (token, KEYWORD_match))\n\t\tparseMatch (token, scope);\n\telse if (isKeyword (token, KEYWORD_select))\n\t\tparseSelect (token, scope);\n\telse if (isToken (token, TOKEN_OPEN_CURLY))\n\t\tparseInit (token, scope);\n\telse if (isKeyword (token, KEYWORD_chan, KEYWORD_map))\n\t\tparseVType (token, NULL, scope, false, true);\n\telse if (isToken (token, TOKEN_CHPOP))\n\t\tparseChanPop (token, scope);\n\telse if (isKeyword (token, KEYWORD_unsafe))\n\t\tparseUnsafe (token, scope);\n\telse if (isToken (token, TOKEN_TILDE, TOKEN_EXCLAMATION, TOKEN_QUESTION,\n\t\t\t\t\t  TOKEN_ASTERISK, TOKEN_AMPERSAND, TOKEN_PLUSMINUS,\n\t\t\t\t\t  TOKEN_ANDAND) ||\n\t\t\t isKeyword (token, KEYWORD_spawn, KEYWORD_go))\n\t{\n\t\treadToken (token);\n\t\tparseExpression (token, scope, NULL);\n\t}\n\telse if (isKeyword (token, KEYWORD_TYPE))\n\t{\n\t\treadToken (token);\n\t\tif (isToken (token, TOKEN_OPEN_PAREN))\n\t\t\tparseFnCall (token, scope);\n\t\telse\n\t\t\tunreadToken (token);\n\t}\n\telse if (isKeyword (token, KEYWORD_struct))\n\t{\n\t\treadToken (token);\n\t\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t\t\tparseInit (token, scope);\n\t\telse\n\t\t\tunreadToken (token);\n\t}\n\telse if (isToken (token, TOKEN_OPEN_PAREN))\n\t{\n\t\treadToken (token);\n\t\tif (isToken (token, TOKEN_CLOSE_PAREN))\n\t\t\tvDebugUnexpected (token, \"CLOSE_PAREN\", 0);\n\t\telse\n\t\t{\n\t\t\tparseExpression (token, scope, NULL);\n\t\t\treadToken (token);\n\t\t}\n\t\tif (expectToken (token, TOKEN_CLOSE_PAREN))\n\t\t\tcont = contRead = true;\n\t\telse\n\t\t\tskipToToken (TOKEN_CLOSE_PAREN, NULL);\n\t}\n\telse if (isToken (token, TOKEN_OPEN_SQUARE))\n\t{\n\t\treadToken (token);\n\t\tif (isToken (token, TOKEN_CLOSE_SQUARE)) // []type or []?\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isToken (token, TOKEN_TYPE, TOKEN_IDENT))\n\t\t\t\tparseFullyQualified (token, true);\n\t\t\tif (isToken (token, TOKEN_TYPE, TOKEN_OPEN_SQUARE) ||\n\t\t\t\tisKeyword (token, KEYWORD_TYPE, KEYWORD_map, KEYWORD_chan))\n\t\t\t{\n\t\t\t\tparseVType (token, NULL, scope, true, true);\n\t\t\t\treadToken (token);\n\t\t\t\tif (isToken (token, TOKEN_OPEN_PAREN)) // cast\n\t\t\t\t\tparseFnCall (token, scope);\n\t\t\t\telse\n\t\t\t\t\tunreadToken (token);\n\t\t\t}\n\t\t\telse\n\t\t\t\tunreadToken (token);\n\t\t}\n\t\telse\n\t\t{\n\t\t\twhile (!isToken (token, TOKEN_EOF, TOKEN_CLOSE_SQUARE))\n\t\t\t{\n\t\t\t\tparseExprList (token, scope, NULL, false);\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t\tif (expectToken (token, TOKEN_CLOSE_SQUARE))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tif (isToken (token, TOKEN_EXCLAMATION))\n\t\t\t\t\treadToken (token);\n\t\t\t\tif (parseExprCont (token, scope, false))\n\t\t\t\t\t;\n\t\t\t\telse if (!token->onNewline && isInitialType (token) &&\n\t\t\t\t\t\t parseVType (token, NULL, scope, true, true))\n\t\t\t\t\t;\n\t\t\t\telse\n\t\t\t\t\tunreadToken (token);\n\t\t\t}\n\t\t\telse\n\t\t\t\tunreadToken (token);\n\t\t}\n\t}\n\telse\n\t{\n\t\tvDebugUnexpected (token, \"expression\", 0);\n\t\tok = false;\n\t}\n\n\tif (cont)\n\t{\n\t\tif (contRead)\n\t\t\treadToken (token);\n\t\tif (!parseExprCont (token, scope, contErr))\n\t\t\tunreadToken (token);\n\t}\n\n\tPARSER_EPILOGUE ();\n\treturn ok;\n}\n\n// return: 'return' list?\nstatic void parseReturn (tokenInfo *const token, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_return));\n\tPARSER_PROLOGUE (\"return\");\n\n\treadToken (token);\n\tif (!isClose (token))\n\t\tparseExprList (token, scope, NULL, false);\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// defer: 'defer' block\nstatic void parseDefer (tokenInfo *const token, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_defer));\n\tPARSER_PROLOGUE (\"defer\");\n\n\treadToken (token);\n\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t\tparseBlock (token, scope, false);\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// asm: 'asm' ident? '{' any '}'\nstatic void parseAsm (tokenInfo *const token, int scope)\n{\n\tAssert (isKeyword (token, KEYWORD_asm));\n\tPARSER_PROLOGUE (\"asm\");\n\n\treadToken (token);\n\tif (isToken (token, TOKEN_IDENT))\n\t\treadToken (token);\n\tif (expectToken (token, TOKEN_OPEN_CURLY))\n\t\tskipToToken (TOKEN_CLOSE_CURLY, NULL);\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// stmt: [\n//     'for' for | 'return' list? | 'defer' block | 'assert' expr |\n//     'break' ident? | 'asm' '{' any '}' | 'lock' fqident block | expr\n// ]\nstatic void parseStatement (tokenInfo *const token, int scope)\n{\n\tPARSER_PROLOGUE (\"stmt\");\n\n\tif (isToken (token, TOKEN_LABEL))\n\t{\n\t\tmakeTag (token, NULL, KIND_LABEL, scope);\n\t\treadToken (token);\n\t}\n\n\tif (isToken (token, TOKEN_CLOSE_CURLY))\n\t\t;\n\telse if (isToken (token, TOKEN_IDENT))\n\t\tparseExprList (token, scope, NULL, false);\n\telse if (isKeyword (token, KEYWORD_for, KEYWORD_Sfor))\n\t\tparseFor (token, scope);\n\telse if (isKeyword (token, KEYWORD_return))\n\t\tparseReturn (token, scope);\n\telse if (isKeyword (token, KEYWORD_defer))\n\t\tparseDefer (token, scope);\n\telse if (isKeyword (token, KEYWORD_asm))\n\t\tparseAsm (token, scope);\n\telse if (isToken (token, TOKEN_OPEN_CURLY))\n\t\tparseBlock (token, scope, false);\n\telse if (isKeyword (token, KEYWORD_assert))\n\t{\n\t\treadToken (token);\n\t\tparseExprList (token, scope, NULL, false);\n\t}\n\telse if (isKeyword (token, KEYWORD_continue, KEYWORD_break))\n\t{\n\t\treadToken (token);\n\t\tif (!isToken (token, TOKEN_IDENT))\n\t\t\tunreadToken (token);\n\t}\n\telse\n\t{\n\t\tvString *access = NULL;\n\t\tskipAccessAndReadToken (token, &access);\n\t\tparseExprList (token, scope, access, false);\n\t\tvStringDelete (access);\n\t}\n\n\tPARSER_EPILOGUE ();\n}\n\n// constexpr: ident '=' expr\nstatic void parseConstExpr (tokenInfo *const token, vString *const access)\n{\n\tPARSER_PROLOGUE (\"constexpr\");\n\n\tmakeTagEx (token, NULL, KIND_CONST, CORK_NIL, access);\n\treadToken (token);\n\tif (expectToken (token, TOKEN_ASSIGN))\n\t{\n\t\treadToken (token);\n\t\tparseExpression (token, CORK_NIL, NULL);\n\t}\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n}\n\n// cont: 'const' [constexpr | '(' constexpr* ')' ]\nstatic void parseConst (tokenInfo *const token, vString *const access)\n{\n\tAssert (isKeyword (token, KEYWORD_const));\n\tPARSER_PROLOGUE (\"const\");\n\n\treadToken (token);\n\tif (isToken (token, TOKEN_OPEN_PAREN))\n\t{\n\t\treadToken (token);\n\t\tdo\n\t\t{\n\t\t\tif (isToken (token, TOKEN_IDENT))\n\t\t\t\tparseConstExpr (token, access);\n\t\t\treadToken (token);\n\t\t} while (!isToken (token, TOKEN_EOF, TOKEN_CLOSE_PAREN));\n\t}\n\telse if (isToken (token, TOKEN_IDENT))\n\t\tparseConstExpr (token, access);\n\telse\n\t{\n\t\texpectToken (token, NULL);\n\t\tunreadToken (token);\n\t}\n\n\tPARSER_EPILOGUE ();\n}\n\n// module: 'module' ident\nstatic int parseModule (tokenInfo *const token)\n{\n\tAssert (isKeyword (token, KEYWORD_module));\n\tPARSER_PROLOGUE (\"module\");\n\n\tint scope = CORK_NIL;\n\treadToken (token);\n\tif (expectToken (token, TOKEN_IDENT))\n\t{\n\t\tif (!strcmp (vStringValue (token->string), \"builtin\"))\n\t\t\tPS->isBuiltin = true;\n\t\telse\n\t\t\tscope = makeTag (token, NULL, KIND_MODULE, CORK_NIL);\n\t}\n\telse\n\t\tunreadToken (token);\n\n\tPARSER_EPILOGUE ();\n\treturn scope;\n}\n\n// global: '__global' ident '=' expr\nstatic void parseGlobal (tokenInfo *token, vString *access, int scope)\n{\n\tAssert (isToken (token, TOKEN_IDENT));\n\tAssert (!strcmp (vStringValue (access), \"__global\"));\n\tPARSER_PROLOGUE (\"global\");\n\n\ttokenInfo *identToken = dupToken (token);\n\treadToken (token);\n\tmakeTag (identToken, NULL, KIND_VARIABLE, CORK_NIL);\n\tif (isToken (token, TOKEN_ASSIGN))\n\t\treadToken (token);\n\tif (!isClose (token))\n\t\tparseExpression (token, scope, access);\n\telse\n\t\tunreadToken (token);\n\tdeleteToken (identToken);\n\n\tPARSER_EPILOGUE ();\n}\n\n// file: [access* [\n//     ['(' any ')'] | ['{' any '}'] | 'module' module | 'fn' fn | 'enum' enum |\n//     'import' import | 'const' const | 'struct' struct | 'interface' iface |\n//     'union' union | 'type' alias | '$if' if | 'asm' asm\n// ]]*\nstatic void parseFile (tokenInfo *const token)\n{\n\tPARSER_PROLOGUE (\"file\");\n\n\tint scope = CORK_NIL;\n\tvString *access = NULL;\n\tdo\n\t{\n\t\treadToken (token);\n\t\tskipAccessAndReadToken (token, &access);\n\n\t\tif (isToken (token, TOKEN_AT)) { // attributes\n\t\t\treadToken (token);\n\t\t\tif (expectToken (token, TOKEN_OPEN_SQUARE))\n\t\t\t\tskipToToken (getClose (token->type), NULL);\n\t\t\telse\n\t\t\t\tunreadToken (token);\n\t\t}\n\t\telse if (isToken (token, TOKEN_OPEN_SQUARE)) // old-style attributes\n\t\t\tskipToToken (TOKEN_CLOSE_SQUARE, NULL);\n\t\telse if (isKeyword (token, KEYWORD_module))\n\t\t\tscope = parseModule (token);\n\t\telse if (isKeyword (token, KEYWORD_fn))\n\t\t\tparseFunction (token, scope, access, KIND_FUNCTION);\n\t\telse if (isKeyword (token, KEYWORD_import))\n\t\t\tparseImport (token);\n\t\telse if (isKeyword (token, KEYWORD_const))\n\t\t\tparseConst (token, access);\n\t\telse if (isKeyword (token, KEYWORD_struct))\n\t\t\tparseStruct (token, access, scope, KIND_STRUCT);\n\t\telse if (isKeyword (token, KEYWORD_interface))\n\t\t\tparseStruct (token, access, scope, KIND_INTERFACE);\n\t\telse if (isKeyword (token, KEYWORD_union))\n\t\t\tparseStruct (token, access, scope, KIND_UNION);\n\t\telse if (isKeyword (token, KEYWORD_enum))\n\t\t\tparseEnum (token, access, scope);\n\t\telse if (isKeyword (token, KEYWORD_type))\n\t\t\tparseAlias (token, access, scope);\n\t\telse if (isToken (token, TOKEN_IDENT, TOKEN_TYPE) &&\n\t\t\t\t access && !strcmp (vStringValue (access), \"__global\"))\n\t\t\tparseGlobal (token, access, scope);\n\t\telse if (isKeyword (token, KEYWORD_Sif))\n\t\t\tparseIf (token, scope);\n\t\telse if (isKeyword (token, KEYWORD_asm))\n\t\t\tparseAsm (token, scope);\n\t\telse if (!isToken (token, TOKEN_EOF))\n\t\t{\n\t\t\tvDebugUnexpected (token, NULL, 0);\n\t\t\tif (isToken (token, TOKEN_OPEN_PAREN, TOKEN_OPEN_CURLY))\n\t\t\t\tskipToToken (getClose (token->type), NULL);\n\t\t}\n\n\t\tif (access)\n\t\t\tvStringClear (access);\n\t}\n\twhile (!isToken (token, TOKEN_EOF));\n\tvStringDelete (access);\n\n\tPARSER_EPILOGUE ();\n}\n\n// _____________________________________________________________________________\n//\n\nstatic void findVTags (void)\n{\n\tPS = newParserState ();\n\ttokenInfo *const token = newToken ();\n\n\tparseFile (token);\n\n\tdeleteToken (token);\n\tdeleteParserState (PS);\n\n\tvDebugParserPrintf (\"\\n\");\n}\n\nstatic void initialize (const langType language)\n{\n\tLangV = language;\n\n#ifdef DEBUG\n#define\tPOOL_N 1\n#else\n#define POOL_N 16\n#endif\n\tTokenPool = objPoolNew (\n\t\tPOOL_N, newPoolToken, deletePoolToken, clearPoolToken, NULL);\n\taddKeywordGroup (&VTypeKeywords, LangV);\n}\n\nstatic void finalize (langType language CTAGS_ATTR_UNUSED, bool initialized)\n{\n\tif (!initialized)\n\t\treturn;\n\n\tobjPoolDelete (TokenPool);\n}\n\nextern parserDefinition *VParser (void)\n{\n\tstatic const char *const extensions[] = { \"v\", NULL };\n\tparserDefinition *def = parserNew (\"V\");\n\tstatic selectLanguage selectors[] = { selectVOrVerilogByKeywords, NULL };\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_FOREIGNER, \"C\", &Lang_c },\n\t\t[1] = { DEPTYPE_FOREIGNER, \"JavaScript\", &Lang_javascript },\n\t};\n\tdef->kindTable = VKinds;\n\tdef->kindCount = ARRAY_SIZE (VKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findVTags;\n\tdef->initialize = initialize;\n\tdef->finalize = finalize;\n\tdef->selectLanguage  = selectors;\n\tdef->keywordTable = VKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (VKeywordTable);\n\tdef->useCork = CORK_QUEUE | CORK_SYMTAB;\n\tdef->requestAutomaticFQTag = true;\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/vera.c",
    "content": "/*\n*   Copyright (c) 1996-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for parsing and scanning Vera\n*   source files.\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"        /* must always come first */\n\n#include <string.h>\n#include <setjmp.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"x-cpreprocessor.h\"\n#include \"keyword.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"xtag.h\"\n\n/*\n*   MACROS\n*/\n\n#define activeToken(st)     ((st)->token [(int) (st)->tokenIndex])\n#define parentDecl(st)      ((st)->parent == NULL ? \\\n                            DECL_NONE : (st)->parent->declaration)\n#define isType(token,t)     (bool) ((token)->type == (t))\n#define insideEnumBody(st)  ((st)->parent == NULL ? false : \\\n                            (bool) ((st)->parent->declaration == DECL_ENUM))\n#define insideInterfaceBody(st) ((st)->parent == NULL ? false : \\\n                            (bool) ((st)->parent->declaration == DECL_INTERFACE))\n#define isSignalDirection(token) (bool)(( (token)->keyword == KEYWORD_INPUT  ) ||\\\n\t\t\t\t\t   ( (token)->keyword == KEYWORD_OUTPUT ) ||\\\n\t\t\t\t\t   ( (token)->keyword == KEYWORD_INOUT  )  )\n\n#define isOneOf(c,s)        (bool) (strchr ((s), (c)) != NULL)\n\n\n/*\n*   DATA DECLARATIONS\n*/\n\nenum { NumTokens = 3 };\n\ntypedef enum eException {\n\tExceptionNone, ExceptionEOF, ExceptionFormattingError,\n\tExceptionBraceFormattingError\n} exception_t;\n\n/*  Used to specify type of keyword.\n */\nenum eKeywordId {\n\tKEYWORD_BAD_STATE, KEYWORD_BAD_TRANS,\n\tKEYWORD_BIND, KEYWORD_BIND_VAR, KEYWORD_BIT,\n\tKEYWORD_CLASS, KEYWORD_CLOCK,\n\tKEYWORD_CONSTRAINT, KEYWORD_COVERAGE_BLOCK, KEYWORD_COVERAGE_DEF,\n\tKEYWORD_ENUM, KEYWORD_EXTERN,\n\tKEYWORD_EXTENDS, KEYWORD_EVENT,\n\tKEYWORD_FUNCTION,\n\tKEYWORD_HDL_NODE,\n\tKEYWORD_INOUT, KEYWORD_INPUT, KEYWORD_INTEGER, KEYWORD_INTERFACE,\n\tKEYWORD_LOCAL,\n\tKEYWORD_M_BAD_STATE, KEYWORD_M_BAD_TRANS, KEYWORD_M_STATE, KEYWORD_M_TRANS,\n\tKEYWORD_NEWCOV,\n\tKEYWORD_NHOLD, KEYWORD_NSAMPLE,\n\tKEYWORD_OUTPUT,\n\tKEYWORD_PACKED, KEYWORD_PORT, KEYWORD_PHOLD,\n\tKEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PSAMPLE, KEYWORD_PUBLIC,\n\tKEYWORD_SHADOW, KEYWORD_STATE,\n\tKEYWORD_STATIC, KEYWORD_STRING,\n\tKEYWORD_TASK,\n\tKEYWORD_TRANS, KEYWORD_TRANSITION,\n\tKEYWORD_TYPEDEF,\n\tKEYWORD_VIRTUAL, KEYWORD_VOID\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\n/*  Used to determine whether keyword is valid for the current language and\n *  what its ID is.\n */\ntypedef struct sKeywordDesc {\n\tconst char *name;\n\tkeywordId id;\n} keywordDesc;\n\n/*  Used for reporting the type of object parsed by nextToken ().\n */\ntypedef enum eTokenType {\n\tTOKEN_NONE,          /* none */\n\tTOKEN_ARGS,          /* a parenthetical pair and its contents */\n\tTOKEN_BRACE_CLOSE,\n\tTOKEN_BRACE_OPEN,\n\tTOKEN_COLON,         /* the colon character */\n\tTOKEN_COMMA,         /* the comma character */\n\tTOKEN_DOUBLE_COLON,  /* double colon indicates nested-name-specifier */\n\tTOKEN_KEYWORD,\n\tTOKEN_NAME,          /* an unknown name */\n\tTOKEN_PAREN_NAME,    /* a single name in parentheses */\n\tTOKEN_SEMICOLON,     /* the semicolon character */\n\tTOKEN_COUNT\n} tokenType;\n\n/*  This describes the scoping of the current statement.\n */\ntypedef enum eTagScope {\n\tSCOPE_GLOBAL,        /* no storage class specified */\n\tSCOPE_STATIC,        /* static storage class */\n\tSCOPE_EXTERN,        /* external storage class */\n\tSCOPE_TYPEDEF,       /* scoping depends upon context */\n\tSCOPE_COUNT\n} tagScope;\n\ntypedef enum eDeclaration {\n\tDECL_NONE,\n\tDECL_BASE,           /* base type (default) */\n\tDECL_CLASS,\n\tDECL_ENUM,\n\tDECL_EVENT,\n\tDECL_FUNCTION,\n\tDECL_INTERFACE,\n\tDECL_PROGRAM,\n\tDECL_TASK,\n\tDECL_COUNT\n} declType;\n\ntypedef enum eVisibilityType {\n\tACCESS_UNDEFINED,\n\tACCESS_LOCAL,\n\tACCESS_PRIVATE,\n\tACCESS_PROTECTED,\n\tACCESS_PUBLIC,\n\tACCESS_COUNT\n} accessType;\n\n/*  Information about the parent class of a member (if any).\n */\ntypedef struct sMemberInfo {\n\taccessType access;           /* access of current statement */\n\taccessType accessDefault;    /* access default for current statement */\n} memberInfo;\n\ntypedef struct sTokenInfo {\n\ttokenType     type;\n\tkeywordId     keyword;\n\tvString*      name;          /* the name of the token */\n\tunsigned long lineNumber;    /* line number of tag */\n\tMIOPos        filePosition;  /* file position of line containing name */\n} tokenInfo;\n\ntypedef enum eImplementation {\n\tIMP_DEFAULT,\n\tIMP_VIRTUAL,\n\tIMP_PURE_VIRTUAL,\n\tIMP_COUNT\n} impType;\n\n/*  Describes the statement currently undergoing analysis.\n */\ntypedef struct sStatementInfo {\n\ttagScope\tscope;\n\tdeclType\tdeclaration;    /* specifier associated with TOKEN_SPEC */\n\tbool\t\tgotName;        /* was a name parsed yet? */\n\tbool\t\thaveQualifyingName;  /* do we have a name we are considering? */\n\tbool\t\tgotParenName;   /* was a name inside parentheses parsed yet? */\n\tbool\t\tgotArgs;        /* was a list of parameters parsed yet? */\n\tbool\t\tisPointer;      /* is 'name' a pointer? */\n\tbool     inFunction;     /* are we inside of a function? */\n\tbool\t\tassignment;     /* have we handled an '='? */\n\tbool\t\tnotVariable;    /* has a variable declaration been disqualified ? */\n\timpType\t\timplementation; /* abstract or concrete implementation? */\n\tunsigned int tokenIndex;    /* currently active token */\n\ttokenInfo*\ttoken [(int) NumTokens];\n\ttokenInfo*\tcontext;        /* accumulated scope of current statement */\n\ttokenInfo*\tblockName;      /* name of current block */\n\tmemberInfo\tmember;         /* information regarding parent class/struct */\n\tvString*\tparentClasses;  /* parent classes */\n\tstruct sStatementInfo *parent;  /* statement we are nested within */\n} statementInfo;\n\n/*  Describes the type of tag being generated.\n */\ntypedef enum eTagType {\n\tTAG_UNDEFINED,\n\tTAG_CLASS,       /* class name */\n\tTAG_ENUM,        /* enumeration name */\n\tTAG_ENUMERATOR,  /* enumerator (enumeration value) */\n\tTAG_EVENT,       /* event */\n\tTAG_FUNCTION,    /* function definition */\n\tTAG_INTERFACE,   /* interface declaration */\n\tTAG_LOCAL,       /* local variable definition */\n\tTAG_MEMBER,      /* structure, class or interface member */\n\tTAG_PROGRAM,     /* program name */\n\tTAG_PROTOTYPE,   /* function prototype or declaration */\n\tTAG_SIGNAL,      /* signal name */\n\tTAG_TASK,        /* task name */\n\tTAG_TYPEDEF,     /* typedef name / D alias name */\n\tTAG_VARIABLE,    /* variable definition */\n\tTAG_EXTERN_VAR,  /* external variable declaration */\n\tTAG_LABEL,       /* goto label */\n\tTAG_COUNT        /* must be last */\n} tagType;\n\ntypedef struct sParenInfo {\n\tbool isPointer;\n\tbool isParamList;\n\tbool isNameCandidate;\n\tbool invalidContents;\n\tbool nestedArgs;\n\tunsigned int parameterCount;\n} parenInfo;\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic jmp_buf Exception;\n\nstatic langType Lang_vera;\nstatic vString *Signature;\nstatic bool CollectingSignature;\n\n/* Number used to uniquely identify anonymous structs and unions. */\nstatic int AnonymousID = 0;\n\n#define COMMONK_UNDEFINED -1\n\n\n/* Used to index into the VeraKinds table. */\ntypedef enum {\n\tVR_MACRO_UNDEF,\n\tVR_MACRO_CONDITION,\n} veraMacroRole;\n\nstatic roleDefinition VeraMacroRoles [] = {\n\tRoleTemplateUndef,\n\tRoleTemplateCondition,\n};\n\n\ntypedef enum {\n\tVR_HEADER_SYSTEM,\n\tVR_HEADER_LOCAL,\n} veraHeaderRole;\n\nstatic roleDefinition VeraHeaderRoles [] = {\n\tRoleTemplateSystem,\n\tRoleTemplateLocal,\n};\n\ntypedef enum {\n\tVK_UNDEFINED = COMMONK_UNDEFINED,\n\tVK_CLASS, VK_DEFINE, VK_ENUMERATOR, VK_FUNCTION,\n\tVK_ENUMERATION, VK_INTERFACE, VK_LOCAL, VK_MEMBER, VK_PROGRAM, VK_PROTOTYPE,\n\tVK_SIGNAL, VK_TASK, VK_TYPEDEF, VK_VARIABLE,\n\tVK_EXTERN_VARIABLE, VK_HEADER, VK_MACRO_PARAM,\n} veraKind;\n\nstatic kindDefinition VeraKinds [] = {\n\t{ true,  'c', \"class\",      \"classes\"},\n\t{ true,  'd', \"macro\",      \"macro definitions\",\n\t  .referenceOnly = false, ATTACH_ROLES(VeraMacroRoles)},\n\t{ true,  'e', \"enumerator\", \"enumerators (values inside an enumeration)\"},\n\t{ true,  'f', \"function\",   \"function definitions\"},\n\t{ true,  'g', \"enum\",       \"enumeration names\"},\n\t{ true,  'i', \"interface\",  \"interfaces\"},\n\t{ false, 'l', \"local\",      \"local variables\"},\n\t{ true,  'm', \"member\",     \"class, struct, and union members\"},\n\t{ true,  'p', \"program\",    \"programs\"},\n\t{ false, 'P', \"prototype\",  \"function prototypes\"},\n\t{ true,  's', \"signal\",     \"signals\"},\n\t{ true,  't', \"task\",       \"tasks\"},\n\t{ true,  'T', \"typedef\",    \"typedefs\"},\n\t{ true,  'v', \"variable\",   \"variable definitions\"},\n\t{ false, 'x', \"externvar\",  \"external variable declarations\"},\n\t{ true,  'h', \"header\",     \"included header files\",\n\t  .referenceOnly = true, ATTACH_ROLES(VeraHeaderRoles)},\n\t{ false, 'D', \"macroParameter\", \"cpp macro parameters\"},\n};\n\nstatic const keywordDesc KeywordTable [] = {\n     { \"bad_state\",       KEYWORD_BAD_STATE,      },\n     { \"bad_trans\",       KEYWORD_BAD_TRANS,      },\n     { \"bind\",            KEYWORD_BIND,           },\n     { \"bind_var\",        KEYWORD_BIND_VAR,       },\n     { \"bit\",             KEYWORD_BIT,            },\n     { \"class\",           KEYWORD_CLASS,          },\n     { \"CLOCK\",           KEYWORD_CLOCK,          },\n     { \"constraint\",      KEYWORD_CONSTRAINT,     },\n     { \"coverage_block\",  KEYWORD_COVERAGE_BLOCK, },\n     { \"coverage_def\",    KEYWORD_COVERAGE_DEF,   },\n     { \"enum\",            KEYWORD_ENUM,           },\n     { \"event\",           KEYWORD_EVENT,          },\n     { \"extends\",         KEYWORD_EXTENDS,        },\n     { \"extern\",          KEYWORD_EXTERN,         },\n     { \"function\",        KEYWORD_FUNCTION,       },\n     { \"hdl_node\",        KEYWORD_HDL_NODE,       },\n     { \"inout\",           KEYWORD_INOUT,          },\n     { \"input\",           KEYWORD_INPUT,          },\n     { \"integer\",         KEYWORD_INTEGER,        },\n     { \"interface\",       KEYWORD_INTERFACE,      },\n     { \"local\",           KEYWORD_LOCAL,          },\n     { \"m_bad_state\",     KEYWORD_M_BAD_STATE,    },\n     { \"m_bad_trans\",     KEYWORD_M_BAD_TRANS,    },\n     { \"m_state\",         KEYWORD_M_STATE,        },\n     { \"m_trans\",         KEYWORD_M_TRANS,        },\n     { \"newcov\",          KEYWORD_NEWCOV,         },\n     { \"NHOLD\",           KEYWORD_NHOLD,          },\n     { \"NSAMPLE\",         KEYWORD_NSAMPLE,        },\n     { \"output\",          KEYWORD_OUTPUT,         },\n     { \"packed\",          KEYWORD_PACKED,         },\n     { \"PHOLD\",           KEYWORD_PHOLD,          },\n     { \"port\",            KEYWORD_PORT,           },\n     { \"program\",         KEYWORD_PROGRAM,        },\n     { \"protected\",       KEYWORD_PROTECTED,      },\n     { \"PSAMPLE\",         KEYWORD_PSAMPLE,        },\n     { \"public\",          KEYWORD_PUBLIC,         },\n     { \"shadow\",          KEYWORD_SHADOW,         },\n     { \"state\",           KEYWORD_STATE,          },\n     { \"static\",          KEYWORD_STATIC,         },\n     { \"string\",          KEYWORD_STRING,         },\n     { \"task\",            KEYWORD_TASK,           },\n     { \"trans\",           KEYWORD_TRANS,          },\n     { \"transition\",      KEYWORD_TRANSITION,     },\n     { \"typedef\",         KEYWORD_TYPEDEF,        },\n     { \"virtual\",         KEYWORD_VIRTUAL,        },\n     { \"void\",            KEYWORD_VOID,           },\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nstatic void createTags (const unsigned int nestLevel, statementInfo *const parent);\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\n/*\n*   Token management\n*/\n\nstatic void initToken (tokenInfo* const token)\n{\n\ttoken->type\t\t\t= TOKEN_NONE;\n\ttoken->keyword\t\t= KEYWORD_NONE;\n\ttoken->lineNumber\t= getInputLineNumber ();\n\ttoken->filePosition\t= getInputFilePosition ();\n\tvStringClear (token->name);\n}\n\nstatic void advanceToken (statementInfo* const st)\n{\n\tif (st->tokenIndex >= (unsigned int) NumTokens - 1)\n\t\tst->tokenIndex = 0;\n\telse\n\t\t++st->tokenIndex;\n\tinitToken (st->token [st->tokenIndex]);\n}\n\nstatic tokenInfo *prevToken (const statementInfo *const st, unsigned int n)\n{\n\tunsigned int tokenIndex;\n\tunsigned int num = (unsigned int) NumTokens;\n\tAssert (n < num);\n\ttokenIndex = (st->tokenIndex + num - n) % num;\n\treturn st->token [tokenIndex];\n}\n\nstatic void setToken (statementInfo *const st, const tokenType type)\n{\n\ttokenInfo *token;\n\ttoken = activeToken (st);\n\tinitToken (token);\n\ttoken->type = type;\n}\n\nstatic void retardToken (statementInfo *const st)\n{\n\tif (st->tokenIndex == 0)\n\t\tst->tokenIndex = (unsigned int) NumTokens - 1;\n\telse\n\t\t--st->tokenIndex;\n\tsetToken (st, TOKEN_NONE);\n}\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\ttoken->name = vStringNew ();\n\tinitToken (token);\n\treturn token;\n}\n\nstatic void deleteToken (tokenInfo *const token)\n{\n\tif (token != NULL)\n\t{\n\t\tvStringDelete (token->name);\n\t\teFree (token);\n\t}\n}\n\nstatic const char *accessString (const accessType access)\n{\n\tstatic const char *const names [] = {\n\t\t\"?\", \"local\", \"private\", \"protected\", \"public\"\n\t};\n\tAssert (ARRAY_SIZE (names) == ACCESS_COUNT);\n\tAssert ((int) access < ACCESS_COUNT);\n\treturn names [(int) access];\n}\n\n/*\n*   Debugging functions\n*/\n\n#ifdef DEBUG\n\n#define boolString(c)   ((c) ? \"true\" : \"false\")\n\nstatic const char *tokenString (const tokenType type)\n{\n\tstatic const char *const names [] = {\n\t\t\"none\", \"args\", \"}\", \"{\", \"colon\", \"comma\", \"double colon\", \"keyword\",\n\t\t\"name\", \"paren-name\", \"semicolon\"\n\t};\n\tAssert (ARRAY_SIZE (names) == TOKEN_COUNT);\n\tAssert ((int) type < TOKEN_COUNT);\n\treturn names [(int) type];\n}\n\nstatic const char *scopeString (const tagScope scope)\n{\n\tstatic const char *const names [] = {\n\t\t\"global\", \"static\", \"extern\", \"typedef\"\n\t};\n\tAssert (ARRAY_SIZE (names) == SCOPE_COUNT);\n\tAssert ((int) scope < SCOPE_COUNT);\n\treturn names [(int) scope];\n}\n\nstatic const char *declString (const declType declaration)\n{\n\tstatic const char *const names [] = {\n\t\t\"?\", \"base\", \"class\", \"enum\", \"event\", \"function\",\n\t\t\"interface\",\n\t\t\"program\", \"task\"\n\t};\n\tAssert (ARRAY_SIZE (names) == DECL_COUNT);\n\tAssert ((int) declaration < DECL_COUNT);\n\treturn names [(int) declaration];\n}\n\nstatic const char *keywordString (const keywordId keyword)\n{\n\tconst size_t count = ARRAY_SIZE (KeywordTable);\n\tconst char *name = \"none\";\n\tsize_t i;\n\tfor (i = 0  ;  i < count  ;  ++i)\n\t{\n\t\tconst keywordDesc *p = &KeywordTable [i];\n\t\tif (p->id == keyword)\n\t\t{\n\t\t\tname = p->name;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn name;\n}\n\nstatic void CTAGS_ATTR_UNUSED pt (tokenInfo *const token)\n{\n\tif (isType (token, TOKEN_NAME))\n\t\tprintf (\"type: %-12s: %-13s   line: %lu\\n\",\n\t\t\ttokenString (token->type), vStringValue (token->name),\n\t\t\ttoken->lineNumber);\n\telse if (isType (token, TOKEN_KEYWORD))\n\t\tprintf (\"type: %-12s: %-13s   line: %lu\\n\",\n\t\t\ttokenString (token->type), keywordString (token->keyword),\n\t\t\ttoken->lineNumber);\n\telse\n\t\tprintf (\"type: %-12s                  line: %lu\\n\",\n\t\t\ttokenString (token->type), token->lineNumber);\n}\n\nstatic void CTAGS_ATTR_UNUSED ps (statementInfo *const st)\n{\n#define P\t\"[%-7u]\"\n\tstatic unsigned int id = 0;\n\tunsigned int i;\n\tprintf (P\"scope: %s   decl: %s   gotName: %s   gotParenName: %s\\n\", id,\n\t\tscopeString (st->scope), declString (st->declaration),\n\t\tboolString (st->gotName), boolString (st->gotParenName));\n\tprintf (P\"haveQualifyingName: %s\\n\", id, boolString (st->haveQualifyingName));\n\tprintf (P\"access: %s   default: %s\\n\", id, accessString (st->member.access),\n\t\taccessString (st->member.accessDefault));\n\tprintf (P\"token  : \", id);\n\tpt (activeToken (st));\n\tfor (i = 1  ;  i < (unsigned int) NumTokens  ;  ++i)\n\t{\n\t\tprintf (P\"prev %u : \", id, i);\n\t\tpt (prevToken (st, i));\n\t}\n\tprintf (P\"context: \", id);\n\tpt (st->context);\n\tid++;\n#undef P\n}\n\n#endif\n\n/*\n*   Statement management\n*/\n\nstatic bool isContextualKeyword (const tokenInfo *const token)\n{\n\tbool result;\n\tswitch (token->keyword)\n\t{\n\t\tcase KEYWORD_CLASS:\n\t\tcase KEYWORD_ENUM:\n\t\tcase KEYWORD_INTERFACE:\n\t\t\tresult = true;\n\t\t\tbreak;\n\n\t\tdefault: result = false; break;\n\t}\n\treturn result;\n}\n\nstatic bool isContextualStatement (const statementInfo *const st)\n{\n\tbool result = false;\n\tif (st != NULL) switch (st->declaration)\n\t{\n\t\tcase DECL_CLASS:\n\t\tcase DECL_ENUM:\n\t\tcase DECL_INTERFACE:\n\t\t\tresult = true;\n\t\t\tbreak;\n\n\t\tdefault: result = false; break;\n\t}\n\treturn result;\n}\n\nstatic bool isMember (const statementInfo *const st)\n{\n\tbool result;\n\tif (isType (st->context, TOKEN_NAME))\n\t\tresult = true;\n\telse\n\t\tresult = (bool)\n\t\t\t(st->parent != NULL && isContextualStatement (st->parent));\n\treturn result;\n}\n\nstatic void initMemberInfo (statementInfo *const st)\n{\n\taccessType accessDefault = ACCESS_UNDEFINED;\n\tif (st->parent != NULL) switch (st->parent->declaration)\n\t{\n\t\tcase DECL_ENUM:\n\t\t\taccessDefault = ACCESS_UNDEFINED;\n\t\t\tbreak;\n\n\t\tcase DECL_CLASS:\n\t\t\taccessDefault = ACCESS_PRIVATE;\n\t\t\tbreak;\n\n\t\tcase DECL_INTERFACE:\n\t\t\taccessDefault = ACCESS_PUBLIC;\n\t\t\tbreak;\n\n\t\tdefault: break;\n\t}\n\tst->member.accessDefault = accessDefault;\n\tst->member.access\t\t = accessDefault;\n}\n\nstatic void reinitStatement (statementInfo *const st, const bool partial)\n{\n\tunsigned int i;\n\n\tif (! partial)\n\t{\n\t\tst->scope = SCOPE_GLOBAL;\n\t\tif (isContextualStatement (st->parent))\n\t\t\tst->declaration = DECL_BASE;\n\t\telse\n\t\t\tst->declaration = DECL_NONE;\n\t}\n\tst->gotParenName\t= false;\n\tst->isPointer\t\t= false;\n\tst->inFunction\t\t= false;\n\tst->assignment\t\t= false;\n\tst->notVariable\t\t= false;\n\tst->implementation\t= IMP_DEFAULT;\n\tst->gotArgs\t\t\t= false;\n\tst->gotName\t\t\t= false;\n\tst->haveQualifyingName = false;\n\tst->tokenIndex\t\t= 0;\n\n\tif (st->parent != NULL)\n\t\tst->inFunction = st->parent->inFunction;\n\n\tfor (i = 0  ;  i < (unsigned int) NumTokens  ;  ++i)\n\t\tinitToken (st->token [i]);\n\n\tinitToken (st->context);\n\n\t/*\tKeep the block name, so that a variable following after a comma will\n\t *\tstill have the structure name.\n\t */\n\tif (! partial)\n\t\tinitToken (st->blockName);\n\n\tvStringClear (st->parentClasses);\n\n\t/*  Init member info.\n\t */\n\tif (! partial)\n\t\tst->member.access = st->member.accessDefault;\n}\n\nstatic void initStatement (statementInfo *const st, statementInfo *const parent)\n{\n\tst->parent = parent;\n\tinitMemberInfo (st);\n\treinitStatement (st, false);\n}\n\n/*\n*   Tag generation functions\n*/\n#define veraTagKind(type) veraTagKindFull(type, true)\n#define veraTagKindNoAssert(type) veraTagKindFull(type, false)\nstatic veraKind veraTagKindFull (const tagType type, bool with_assert) {\n\tveraKind result = VK_UNDEFINED;\n\tswitch (type)\n\t{\n\t\tcase TAG_CLASS:      result = VK_CLASS;           break;\n\t\tcase TAG_ENUM:       result = VK_ENUMERATION;     break;\n\t\tcase TAG_ENUMERATOR: result = VK_ENUMERATOR;      break;\n\t\tcase TAG_FUNCTION:   result = VK_FUNCTION;        break;\n\t\tcase TAG_INTERFACE:  result = VK_INTERFACE;       break;\n\t\tcase TAG_LOCAL:      result = VK_LOCAL;           break;\n\t\tcase TAG_MEMBER:     result = VK_MEMBER;          break;\n\t\tcase TAG_PROGRAM:    result = VK_PROGRAM;         break;\n\t\tcase TAG_PROTOTYPE:  result = VK_PROTOTYPE;       break;\n\t\tcase TAG_SIGNAL:     result = VK_SIGNAL;          break;\n\t\tcase TAG_TASK:       result = VK_TASK;            break;\n\t\tcase TAG_TYPEDEF:    result = VK_TYPEDEF;         break;\n\t\tcase TAG_VARIABLE:   result = VK_VARIABLE;        break;\n\t\tcase TAG_EXTERN_VAR: result = VK_EXTERN_VARIABLE; break;\n\n\t\tdefault: if (with_assert) Assert (\"Bad Vera tag type\" == NULL); break;\n\t}\n\treturn result;\n}\n\nstatic int kindIndexForType (const tagType type)\n{\n\treturn veraTagKind (type);\n}\n\nstatic const char *tagName (const tagType type)\n{\n\treturn VeraKinds [veraTagKind (type)].name;\n}\n\nstatic bool includeTag (const tagType type, const bool isFileScope)\n{\n\tbool result;\n\tint k = COMMONK_UNDEFINED;\n\n\tif (isFileScope && !isXtagEnabled(XTAG_FILE_SCOPE))\n\t\treturn false;\n\n\tk = veraTagKindNoAssert (type);\n\tif (k == COMMONK_UNDEFINED)\n\t\tresult = false;\n\telse\n\t\tresult = isInputLanguageKindEnabled (k);\n\n\treturn result;\n}\n\nstatic tagType declToTagType (const declType declaration)\n{\n\ttagType type = TAG_UNDEFINED;\n\n\tswitch (declaration)\n\t{\n\t\tcase DECL_CLASS:        type = TAG_CLASS;       break;\n\t\tcase DECL_ENUM:         type = TAG_ENUM;        break;\n\t\tcase DECL_EVENT:        type = TAG_EVENT;       break;\n\t\tcase DECL_FUNCTION:     type = TAG_FUNCTION;    break;\n\t\tcase DECL_INTERFACE:    type = TAG_INTERFACE;   break;\n\t\tcase DECL_PROGRAM:      type = TAG_PROGRAM;     break;\n\t\tcase DECL_TASK:         type = TAG_TASK;        break;\n\n\t\tdefault: Assert (\"Unexpected declaration\" == NULL); break;\n\t}\n\treturn type;\n}\n\nstatic const char* accessField (const statementInfo *const st)\n{\n\tconst char* result = NULL;\n\tif (st->member.access != ACCESS_UNDEFINED)\n\t\tresult = accessString (st->member.access);\n\treturn result;\n}\n\nstatic void addOtherFields (tagEntryInfo* const tag, const tagType type,\n\t\t\t\t\t\t\tconst statementInfo *const st,\n\t\t\t\t\t\t\tvString *const scope, vString *const typeRef)\n{\n\t/*  For selected tag types, append an extension flag designating the\n\t *  parent object in which the tag is defined.\n\t */\n\tswitch (type)\n\t{\n\t\tdefault: break;\n\n\t\tcase TAG_FUNCTION:\n\t\tcase TAG_PROTOTYPE:\n\t\t\tif (vStringLength (Signature) > 0)\n\t\t\t\ttag->extensionFields.signature = vStringValue (Signature);\n\t\t\t/* Fallthrough */\n\t\tcase TAG_CLASS:\n\t\tcase TAG_ENUM:\n\t\tcase TAG_ENUMERATOR:\n\t\tcase TAG_EVENT:\n\t\tcase TAG_INTERFACE:\n\t\tcase TAG_MEMBER:\n\t\tcase TAG_SIGNAL:\n\t\tcase TAG_TASK:\n\t\tcase TAG_TYPEDEF:\n\t\t\tif (vStringLength (scope) > 0  &&  isMember (st))\n\t\t\t{\n\t\t\t\ttagType ptype;\n\n\t\t\t\tif (isType (st->context, TOKEN_NAME))\n\t\t\t\t{\n\t\t\t\t\ttag->extensionFields.scopeKindIndex = kindIndexForType (TAG_CLASS);\n\t\t\t\t\ttag->extensionFields.scopeName = vStringValue (scope);\n\t\t\t\t}\n\t\t\t\telse if ((ptype = declToTagType (parentDecl (st))) &&\n\t\t\t\t\t includeTag (ptype, isXtagEnabled(XTAG_FILE_SCOPE)))\n\t\t\t\t{\n\t\t\t\t\ttag->extensionFields.scopeKindIndex = kindIndexForType (ptype);\n\t\t\t\t\ttag->extensionFields.scopeName = vStringValue (scope);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ((type == TAG_CLASS  ||  type == TAG_INTERFACE) &&\n\t\t\t\t vStringLength (st->parentClasses) > 0)\n\t\t\t{\n\n\t\t\t\ttag->extensionFields.inheritance =\n\t\t\t\t\t\tvStringValue (st->parentClasses);\n\t\t\t}\n\t\t\tif (isMember (st))\n\t\t\t{\n\t\t\t\ttag->extensionFields.access = accessField (st);\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\t/* Add typename info, type of the tag and name of struct/union/etc. */\n\tif ((type == TAG_TYPEDEF || type == TAG_VARIABLE || type == TAG_MEMBER)\n\t\t\t&& isContextualStatement(st))\n\t{\n\t\tchar *p;\n\n\t\ttag->extensionFields.typeRef [0] =\n\t\t\t\t\t\ttagName (declToTagType (st->declaration));\n\t\tp = vStringValue (st->blockName->name);\n\n\t\t/*  If there was no {} block get the name from the token before the\n\t\t *  name (current token is ';' or ',', previous token is the name).\n\t\t */\n\t\tif (p == NULL || *p == '\\0')\n\t\t{\n\t\t\ttokenInfo *const prev2 = prevToken (st, 2);\n\t\t\tif (isType (prev2, TOKEN_NAME))\n\t\t\t\tp = vStringValue (prev2->name);\n\t\t}\n\n\t\t/* Prepend the scope name if there is one. */\n\t\tif (vStringLength (scope) > 0)\n\t\t{\n\t\t\tvStringCopy(typeRef, scope);\n\t\t\tvStringCatS(typeRef, p);\n\t\t\tp = vStringValue (typeRef);\n\t\t}\n\t\ttag->extensionFields.typeRef [1] = p;\n\t}\n}\n\nstatic bool findScopeHierarchy (vString *const string, const statementInfo *const st)\n{\n\tbool found = false;\n\n\tvStringClear (string);\n\n\tif (isType (st->context, TOKEN_NAME))\n\t{\n\t\tvStringCopy (string, st->context->name);\n\t\tfound = true;\n\t}\n\n\tif (st->parent != NULL)\n\t{\n\t\tvString *temp = vStringNew ();\n\t\tconst statementInfo *s;\n\t\tfor (s = st->parent  ;  s != NULL  ;  s = s->parent)\n\t\t{\n\t\t\tif (isContextualStatement (s) ||\n\t\t\t\ts->declaration == DECL_PROGRAM)\n\t\t\t{\n\t\t\t\tfound = true;\n\t\t\t\tvStringCopy (temp, string);\n\t\t\t\tvStringClear (string);\n\t\t\t\tif (isType (s->blockName, TOKEN_NAME))\n\t\t\t\t{\n\t\t\t\t\tif (isType (s->context, TOKEN_NAME) &&\n\t\t\t\t\t    vStringLength (s->context->name) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tvStringCat (string, s->context->name);\n\t\t\t\t\t}\n\t\t\t\t\tvStringCat (string, s->blockName->name);\n\t\t\t\t\tvStringCat (string, temp);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/* Information for building scope string\n\t\t\t\t\t   is lacking. Maybe input is broken. */\n\t\t\t\t\tfound = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvStringDelete (temp);\n\t}\n\treturn found;\n}\n\nstatic void makeExtraTagEntry (const tagType type, tagEntryInfo *const e,\n\t\t\t\t\t\t\t   vString *const scope)\n{\n\tif (isXtagEnabled(XTAG_QUALIFIED_TAGS)  &&\n\t\tscope != NULL  &&  vStringLength (scope) > 0)\n\t{\n\t\tvString *const scopedName = vStringNew ();\n\n\t\tif (type != TAG_ENUMERATOR)\n\t\t\tvStringCopy (scopedName, scope);\n\t\telse\n\t\t{\n\t\t\t/* remove last component (i.e. enumeration name) from scope */\n\t\t\tconst char* const sc = vStringValue (scope);\n\t\t\tconst char* colon = strrchr (sc, ':');\n\t\t\tif (colon != NULL)\n\t\t\t{\n\t\t\t\twhile (*colon == ':'  &&  colon > sc)\n\t\t\t\t\t--colon;\n\t\t\t\tvStringNCopy (scopedName, scope, colon + 1 - sc);\n\t\t\t}\n\t\t}\n\t\tif (vStringLength (scopedName) > 0)\n\t\t{\n\t\t\tvStringCatS (scopedName, e->name);\n\t\t\te->name = vStringValue (scopedName);\n\t\t\tmarkTagExtraBit (e, XTAG_QUALIFIED_TAGS);\n\t\t\tmakeTagEntry (e);\n\t\t}\n\t\tvStringDelete (scopedName);\n\t}\n}\n\nstatic int makeTag (const tokenInfo *const token,\n\t\t\t\t\t const statementInfo *const st,\n\t\t\t\t\t bool isFileScope, const tagType type)\n{\n\tint corkIndex = CORK_NIL;\n\t/*  Nothing is really of file scope when it appears in a header file.\n\t */\n\tisFileScope = (bool) (isFileScope && ! isInputHeaderFile ());\n\n\tif (isType (token, TOKEN_NAME)  &&  vStringLength (token->name) > 0  &&\n\t\tincludeTag (type, isFileScope))\n\t{\n\t\tvString *scope;\n\t\tvString *typeRef;\n\t\tbool isScopeBuilt;\n\t\t/* Use \"typeRef\" to store the typename from addOtherFields() until\n\t\t * it's used in makeTagEntry().\n\t\t */\n\t\ttagEntryInfo e;\n\t\tint kind;\n\n\t\tscope  = vStringNew ();\n\t\ttypeRef = vStringNew ();\n\n\t\tkind  = kindIndexForType(type);\n\t\tinitTagEntry (&e, vStringValue (token->name), kind);\n\n\t\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\t\te.isFileScope\t= isFileScope;\n\t\tif (e.isFileScope)\n\t\t\tmarkTagExtraBit (&e, XTAG_FILE_SCOPE);\n\n\t\tisScopeBuilt = findScopeHierarchy (scope, st);\n\t\taddOtherFields (&e, type, st, scope, typeRef);\n\n\t\tcorkIndex = makeTagEntry (&e);\n\t\tif (isScopeBuilt)\n\t\t\tmakeExtraTagEntry (type, &e, scope);\n\t\tvStringDelete (scope);\n\t\tvStringDelete (typeRef);\n\t}\n\treturn corkIndex;\n}\n\nstatic bool isValidTypeSpecifier (const declType declaration)\n{\n\tbool result;\n\tswitch (declaration)\n\t{\n\t\tcase DECL_BASE:\n\t\tcase DECL_CLASS:\n\t\tcase DECL_ENUM:\n\t\tcase DECL_EVENT:\n\t\t\tresult = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tresult = false;\n\t\t\tbreak;\n\t}\n\treturn result;\n}\n\nstatic int qualifyEnumeratorTag (const statementInfo *const st,\n\t\t\t\t\t\t\t\t const tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\tif (isType (nameToken, TOKEN_NAME))\n\t\tcorkIndex = makeTag (nameToken, st, true, TAG_ENUMERATOR);\n\treturn corkIndex;\n}\n\nstatic int qualifyFunctionTag (const statementInfo *const st,\n\t\t\t\t\t\t\t\tconst tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\tif (isType (nameToken, TOKEN_NAME))\n\t{\n\t\ttagType type;\n\t\tconst bool isFileScope =\n\t\t\t\t\t\t(bool) (st->member.access == ACCESS_PRIVATE ||\n\t\t\t\t\t\t(!isMember (st)  &&  st->scope == SCOPE_STATIC));\n\t\tif (st->declaration == DECL_TASK)\n\t\t\ttype = TAG_TASK;\n\t\telse\n\t\t\ttype = TAG_FUNCTION;\n\t\tcorkIndex = makeTag (nameToken, st, isFileScope, type);\n\t}\n\treturn corkIndex;\n}\n\nstatic int qualifyFunctionDeclTag (const statementInfo *const st,\n\t\t\t\t\t\t\t\t\tconst tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\tif (! isType (nameToken, TOKEN_NAME))\n\t\t;\n\telse if (st->scope == SCOPE_TYPEDEF)\n\t\tcorkIndex = makeTag (nameToken, st, true, TAG_TYPEDEF);\n\telse if (isValidTypeSpecifier (st->declaration))\n\t\tcorkIndex = makeTag (nameToken, st, true, TAG_PROTOTYPE);\n\treturn corkIndex;\n}\n\nstatic int qualifyCompoundTag (const statementInfo *const st,\n\t\t\t\t\t\t\t\tconst tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\tif (isType (nameToken, TOKEN_NAME))\n\t{\n\t\tconst tagType type = declToTagType (st->declaration);\n\n\t\tif (type != TAG_UNDEFINED)\n\t\t\tcorkIndex = makeTag (nameToken, st, false, type);\n\t}\n\treturn corkIndex;\n}\n\nstatic int qualifyBlockTag (statementInfo *const st,\n\t\t\t\t\t\t\t const tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\tswitch (st->declaration)\n\t{\n\n\t\tcase DECL_CLASS:\n\t\tcase DECL_ENUM:\n\t\tcase DECL_INTERFACE:\n\t\tcase DECL_PROGRAM:\n\t\t\tcorkIndex = qualifyCompoundTag (st, nameToken);\n\t\t\tbreak;\n\t\tdefault: break;\n\t}\n\treturn corkIndex;\n}\n\nstatic int qualifyVariableTag (const statementInfo *const st,\n\t\t\t\t\t\t\t\tconst tokenInfo *const nameToken)\n{\n\tint corkIndex = CORK_NIL;\n\t/*\tWe have to watch that we do not interpret a declaration of the\n\t *\tform \"struct tag;\" as a variable definition. In such a case, the\n\t *\ttoken preceding the name will be a keyword.\n\t */\n\tif (! isType (nameToken, TOKEN_NAME))\n\t\t;\n\telse if (st->scope == SCOPE_TYPEDEF)\n\t\tcorkIndex = makeTag (nameToken, st, true, TAG_TYPEDEF);\n\telse if (st->declaration == DECL_EVENT)\n\t\tcorkIndex = makeTag (nameToken, st, (bool) (st->member.access == ACCESS_PRIVATE),\n\t\t\t\t\t\t\t TAG_EVENT);\n\telse if (isValidTypeSpecifier (st->declaration))\n\t{\n\t\tif (st->notVariable)\n\t\t\t;\n\t\telse if (isMember (st))\n\t\t{\n\t\t\tif (st->scope == SCOPE_GLOBAL  ||  st->scope == SCOPE_STATIC)\n\t\t\t\tcorkIndex = makeTag (nameToken, st, true, TAG_MEMBER);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (st->scope == SCOPE_EXTERN  ||  ! st->haveQualifyingName)\n\t\t\t\tcorkIndex = makeTag (nameToken, st, false, TAG_EXTERN_VAR);\n\t\t\telse if (st->inFunction)\n\t\t\t\tcorkIndex = makeTag (nameToken, st, (bool) (st->scope == SCOPE_STATIC),\n\t\t\t\t\t\t\t\t\t TAG_LOCAL);\n\t\t\telse\n\t\t\t\tcorkIndex = makeTag (nameToken, st, (bool) (st->scope == SCOPE_STATIC),\n\t\t\t\t\t\t\t\t\t TAG_VARIABLE);\n\t\t}\n\t}\n\treturn corkIndex;\n}\n\n/*\n*   Parsing functions\n*/\n\n\n/*  Skip to the next non-white character.\n */\nstatic int skipToNonWhite (void)\n{\n\tbool found = false;\n\tint c;\n\n#if 0\n\tdo\n\t\tc = cppGetc ();\n\twhile (cppIsspace (c));\n#else\n\twhile (1)\n\t{\n\t\tc = cppGetc ();\n\t\tif (cppIsspace (c))\n\t\t\tfound = true;\n\t\telse\n\t\t\tbreak;\n\t}\n\tif (CollectingSignature && found)\n\t\tvStringPut (Signature, ' ');\n#endif\n\n\treturn c;\n}\n\n/*  Skips to the next brace in column 1. This is intended for cases where\n *  preprocessor constructs result in unbalanced braces.\n */\nstatic void skipToFormattedBraceMatch (void)\n{\n\tint c, next;\n\n\tc = cppGetc ();\n\tnext = cppGetc ();\n\twhile (c != EOF  &&  (c != '\\n'  ||  next != '}'))\n\t{\n\t\tc = next;\n\t\tnext = cppGetc ();\n\t}\n}\n\n/*  Skip to the matching character indicated by the pair string. If skipping\n *  to a matching brace and any brace is found within a different level of a\n *  #if conditional statement while brace formatting is in effect, we skip to\n *  the brace matched by its formatting. It is assumed that we have already\n *  read the character which starts the group (i.e. the first character of\n *  \"pair\").\n */\nstatic void skipToMatch (const char *const pair)\n{\n\tconst bool braceMatching = (bool) (strcmp (\"{}\", pair) == 0);\n\tconst bool braceFormatting = (bool) (cppIsBraceFormat () && braceMatching);\n\tconst unsigned int initialLevel = cppGetDirectiveNestLevel ();\n\tconst int begin = pair [0], end = pair [1];\n\tconst unsigned long inputLineNumber = getInputLineNumber ();\n\tint matchLevel = 1;\n\tint c = '\\0';\n\n\twhile (matchLevel > 0  &&  (c = skipToNonWhite ()) != EOF)\n\t{\n\t\tif (CollectingSignature)\n\t\t\tcppVStringPut (Signature, c);\n\t\tif (c == begin)\n\t\t{\n\t\t\t++matchLevel;\n\t\t\tif (braceFormatting  &&  cppGetDirectiveNestLevel () != initialLevel)\n\t\t\t{\n\t\t\t\tskipToFormattedBraceMatch ();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse if (c == end)\n\t\t{\n\t\t\t--matchLevel;\n\t\t\tif (braceFormatting  &&  cppGetDirectiveNestLevel () != initialLevel)\n\t\t\t{\n\t\t\t\tskipToFormattedBraceMatch ();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif (c == EOF)\n\t{\n\t\tverbose (\"%s: failed to find match for '%c' at line %lu\\n\",\n\t\t\t\tgetInputFileName (), begin, inputLineNumber);\n\t\tif (braceMatching)\n\t\t\tlongjmp (Exception, (int) ExceptionBraceFormattingError);\n\t\telse\n\t\t\tlongjmp (Exception, (int) ExceptionFormattingError);\n\t}\n}\n\nstatic keywordId analyzeKeyword (const char *const name)\n{\n\tconst keywordId id = (keywordId) lookupKeyword (name, getInputLanguage ());\n\treturn id;\n}\n\nstatic void analyzeIdentifier (tokenInfo *const token)\n{\n\tconst char * name = vStringValue (token->name);\n\n\tvString * replacement = NULL;\n\n\t// C: check for ignored token\n\t// (FIXME: java doesn't support -I... but maybe it should?)\n\tcppMacroInfo * macro = cppFindMacro(name);\n\n\tif(macro)\n\t{\n\t\tif(macro->hasParameterList)\n\t\t{\n\t\t\t// This old parser does not support macro parameters: we simply assume them to be empty\n\t\t\tint c = skipToNonWhite ();\n\n\t\t\tif (c == '(')\n\t\t\t\tskipToMatch (\"()\");\n\t\t}\n\n\t\tif(macro->replacements)\n\t\t{\n\t\t\t// There is a replacement: analyze it\n\t\t\treplacement = cppExpandMacroAsNewString(macro,NULL);\n\t\t\tname = replacement ? vStringValue(replacement) : NULL;\n\t\t} else {\n\t\t\t// There is no replacement: just ignore\n\t\t\tname = NULL;\n\t\t}\n\t}\n\n\tif(!name)\n\t{\n\t\tinitToken(token);\n\t\tif(replacement)\n\t\t\tvStringDelete(replacement);\n\t\treturn;\n\t}\n\n\ttoken->keyword = analyzeKeyword (name);\n\n\tif (token->keyword == KEYWORD_NONE)\n\t\ttoken->type = TOKEN_NAME;\n\telse\n\t\ttoken->type = TOKEN_KEYWORD;\n\n\tif(replacement)\n\t\tvStringDelete(replacement);\n}\n\nstatic void readIdentifier (tokenInfo *const token, const int firstChar)\n{\n\tvString *const name = token->name;\n\tint c = firstChar;\n\tbool first = true;\n\n\tinitToken (token);\n\n\tdo\n\t{\n\t\tcppVStringPut (name, c);\n\t\tif (CollectingSignature)\n\t\t{\n\t\t\tif (!first)\n\t\t\t\tcppVStringPut (Signature, c);\n\t\t\tfirst = false;\n\t\t}\n\t\tc = cppGetc ();\n\t} while (cppIsident (c));\n\tcppUngetc (c);        /* unget non-identifier character */\n\n\tanalyzeIdentifier (token);\n}\n\nstatic void processName (statementInfo *const st)\n{\n\tAssert (isType (activeToken (st), TOKEN_NAME));\n\tif (st->gotName  &&  st->declaration == DECL_NONE)\n\t\tst->declaration = DECL_BASE;\n\tst->gotName = true;\n\tst->haveQualifyingName = true;\n}\n\nstatic void copyToken (tokenInfo *const dest, const tokenInfo *const src)\n{\n\tdest->type         = src->type;\n\tdest->keyword      = src->keyword;\n\tdest->filePosition = src->filePosition;\n\tdest->lineNumber   = src->lineNumber;\n\tvStringCopy (dest->name, src->name);\n}\n\nstatic void setAccess (statementInfo *const st, const accessType access)\n{\n\tif (isMember (st))\n\t{\n\t\tst->member.access = access;\n\t}\n}\n\nstatic void addParentClass (statementInfo *const st, tokenInfo *const token)\n{\n\tif (vStringLength (token->name) > 0)\n\t\tvStringJoin (st->parentClasses, ',', token->name);\n}\n\nstatic void readParents (statementInfo *const st, const int qualifier)\n{\n\ttokenInfo *const token = newToken ();\n\ttokenInfo *const parent = newToken ();\n\tint c;\n\n\tdo\n\t{\n\t\tc = skipToNonWhite ();\n\t\tif (cppIsident1 (c))\n\t\t{\n\t\t\treadIdentifier (token, c);\n\t\t\tif (isType (token, TOKEN_NAME))\n\t\t\t\tvStringCat (parent->name, token->name);\n\t\t\telse\n\t\t\t{\n\t\t\t\taddParentClass (st, parent);\n\t\t\t\tinitToken (parent);\n\t\t\t}\n\t\t}\n\t\telse if (c == qualifier)\n\t\t\tvStringPut (parent->name, c);\n\t\telse if (c == '<')\n\t\t\tskipToMatch (\"<>\");\n\t\telse if (isType (token, TOKEN_NAME))\n\t\t{\n\t\t\taddParentClass (st, parent);\n\t\t\tinitToken (parent);\n\t\t}\n\t} while (c != '{'  &&  c != EOF);\n\tcppUngetc (c);\n\tdeleteToken (parent);\n\tdeleteToken (token);\n}\n\nstatic void processInterface (statementInfo *const st)\n{\n\tst->declaration = DECL_INTERFACE;\n}\n\nstatic void checkIsClassEnum (statementInfo *const st, const declType decl)\n{\n\tst->declaration = decl;\n}\n\nstatic void processToken (tokenInfo *const token, statementInfo *const st)\n{\n\tswitch ((int)token->keyword)        /* is it a reserved word? */\n\t{\n\t\tdefault: break;\n\n\t\tcase KEYWORD_NONE:      processName (st);                       break;\n\t\tcase KEYWORD_BIND:      st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_BIT:       st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_CLASS:     checkIsClassEnum (st, DECL_CLASS);      break;\n\t\tcase KEYWORD_ENUM:      st->declaration = DECL_ENUM;            break;\n\t\tcase KEYWORD_EXTENDS:   readParents (st, '.');\n\t\t                        setToken (st, TOKEN_NONE);              break;\n\t\tcase KEYWORD_FUNCTION:  st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_INTEGER:   st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_INTERFACE: processInterface (st);                  break;\n\t\tcase KEYWORD_LOCAL:     setAccess (st, ACCESS_LOCAL);           break;\n\t\tcase KEYWORD_PROGRAM:   st->declaration = DECL_PROGRAM;         break;\n\t\tcase KEYWORD_PROTECTED: setAccess (st, ACCESS_PROTECTED);       break;\n\t\tcase KEYWORD_PUBLIC:    setAccess (st, ACCESS_PUBLIC);          break;\n\t\tcase KEYWORD_STRING:    st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_TASK:      st->declaration = DECL_TASK;            break;\n\t\tcase KEYWORD_VOID:      st->declaration = DECL_BASE;            break;\n\t\tcase KEYWORD_VIRTUAL:   st->implementation = IMP_VIRTUAL;       break;\n\n\t\tcase KEYWORD_EVENT:\n\t\t\tbreak;\n\n\t\tcase KEYWORD_TYPEDEF:\n\t\t\treinitStatement (st, false);\n\t\t\tst->scope = SCOPE_TYPEDEF;\n\t\t\tbreak;\n\n\t\tcase KEYWORD_EXTERN:\n\t\t\treinitStatement (st, false);\n\t\t\tst->scope = SCOPE_EXTERN;\n\t\t\tst->declaration = DECL_BASE;\n\t\t\tbreak;\n\n\t\tcase KEYWORD_STATIC:\n\t\t\treinitStatement (st, false);\n\t\t\tst->scope = SCOPE_STATIC;\n\t\t\tst->declaration = DECL_BASE;\n\t\t\tbreak;\n\t}\n}\n\n/*\n*   Parenthesis handling functions\n*/\n\nstatic void restartStatement (statementInfo *const st)\n{\n\ttokenInfo *const save = newToken ();\n\ttokenInfo *token = activeToken (st);\n\n\tcopyToken (save, token);\n\tDebugStatement ( if (debug (DEBUG_PARSE)) printf (\"<ES>\");)\n\treinitStatement (st, false);\n\ttoken = activeToken (st);\n\tcopyToken (token, save);\n\tdeleteToken (save);\n\tprocessToken (token, st);\n}\n\n/*  Skips over a mem-initializer-list of a ctor-initializer, defined as:\n *\n *  mem-initializer-list:\n *    mem-initializer, mem-initializer-list\n *\n *  mem-initializer:\n *    [::] [nested-name-spec] class-name (...)\n *    identifier\n */\nstatic void skipMemIntializerList (tokenInfo *const token)\n{\n\tint c;\n\n\tdo\n\t{\n\t\tc = skipToNonWhite ();\n\t\twhile (cppIsident1 (c)  ||  c == ':')\n\t\t{\n\t\t\tif (c != ':')\n\t\t\t\treadIdentifier (token, c);\n\t\t\tc = skipToNonWhite ();\n\t\t}\n\t\tif (c == '<')\n\t\t{\n\t\t\tskipToMatch (\"<>\");\n\t\t\tc = skipToNonWhite ();\n\t\t}\n\t\tif (c == '(')\n\t\t{\n\t\t\tskipToMatch (\"()\");\n\t\t\tc = skipToNonWhite ();\n\t\t}\n\t} while (c == ',');\n\tcppUngetc (c);\n}\n\nstatic void skipMacro (statementInfo *const st)\n{\n\ttokenInfo *const prev2 = prevToken (st, 2);\n\n\tif (isType (prev2, TOKEN_NAME))\n\t\tretardToken (st);\n\tskipToMatch (\"()\");\n}\n\n/*  Skips over characters following the parameter list.\n *  Originally written for C++, may contain unnecessary stuff.\n *\n *  C#:\n *    public C(double x) : base(x) {}\n */\nstatic bool skipPostArgumentStuff (\n\t\tstatementInfo *const st, parenInfo *const info)\n{\n\ttokenInfo *const token = activeToken (st);\n\tunsigned int parameters = info->parameterCount;\n\tunsigned int elementCount = 0;\n\tbool restart = false;\n\tbool end = false;\n\tint c = skipToNonWhite ();\n\n\tdo\n\t{\n\t\tswitch (c)\n\t\t{\n\t\tcase ')':                               break;\n\t\tcase ':': skipMemIntializerList (token);break;  /* ctor-initializer */\n\t\tcase '[': skipToMatch (\"[]\");           break;\n\t\tcase '=': cppUngetc (c); end = true;    break;\n\t\tcase '{': cppUngetc (c); end = true;    break;\n\t\tcase '}': cppUngetc (c); end = true;    break;\n\n\t\tcase '(':\n\t\t\tif (elementCount > 0)\n\t\t\t\t++elementCount;\n\t\t\tskipToMatch (\"()\");\n\t\t\tbreak;\n\n\t\tcase ';':\n\t\t\tif (parameters == 0  ||  elementCount < 2)\n\t\t\t{\n\t\t\t\tcppUngetc (c);\n\t\t\t\tend = true;\n\t\t\t}\n\t\t\telse if (--parameters == 0)\n\t\t\t\tend = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tif (cppIsident1 (c))\n\t\t\t{\n\t\t\t\treadIdentifier (token, c);\n\t\t\t\tswitch (token->keyword)\n\t\t\t\t{\n\t\t\t\tcase KEYWORD_CLASS:\n\t\t\t\tcase KEYWORD_EXTERN:\n\t\t\t\tcase KEYWORD_NEWCOV:\n\t\t\t\tcase KEYWORD_PROTECTED:\n\t\t\t\tcase KEYWORD_PUBLIC:\n\t\t\t\tcase KEYWORD_STATIC:\n\t\t\t\tcase KEYWORD_TYPEDEF:\n\t\t\t\tcase KEYWORD_VIRTUAL:\n\t\t\t\t\t/* Never allowed within parameter declarations. */\n\t\t\t\t\trestart = true;\n\t\t\t\t\tend = true;\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tif (isType (token, TOKEN_NONE))\n\t\t\t\t\t\t;\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t/*  If we encounter any other identifier immediately\n\t\t\t\t\t\t *  following an empty parameter list, this is almost\n\t\t\t\t\t\t *  certainly one of those Microsoft macro \"thingies\"\n\t\t\t\t\t\t *  that the automatic source code generation sticks\n\t\t\t\t\t\t *  in. Terminate the current statement.\n\t\t\t\t\t\t */\n\t\t\t\t\t\trestart = true;\n\t\t\t\t\t\tend = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (! end)\n\t\t{\n\t\t\tc = skipToNonWhite ();\n\t\t\tif (c == EOF)\n\t\t\t\tend = true;\n\t\t}\n\t} while (! end);\n\n\tif (restart)\n\t\trestartStatement (st);\n\telse\n\t\tsetToken (st, TOKEN_NONE);\n\n\treturn (bool) (c != EOF);\n}\n\nstatic void analyzePostParens (statementInfo *const st, parenInfo *const info)\n{\n\tconst unsigned long inputLineNumber = getInputLineNumber ();\n\tint c = skipToNonWhite ();\n\n\tcppUngetc (c);\n\tif (isOneOf (c, \"{;,=\"))\n\t\t;\n\telse {\n\t\tif (! skipPostArgumentStuff (st, info))\n\t\t{\n\t\t\tverbose (\n\t\t\t\t\"%s: confusing argument declarations beginning at line %lu\\n\",\n\t\t\t\tgetInputFileName (), inputLineNumber);\n\t\t\tlongjmp (Exception, (int) ExceptionFormattingError);\n\t\t}\n\t}\n}\n\nstatic void processAngleBracket (void)\n{\n\tint c = cppGetc ();\n\tif (c == '>') {\n\t\t/* already found match for template */\n\t} else if (c == '<') {\n\t\t/* skip \"<<\" or \"<<=\". */\n\t\tc = cppGetc ();\n\t\tif (c != '=') {\n\t\t\tcppUngetc (c);\n\t\t}\n\t} else {\n\t\tcppUngetc (c);\n\t}\n}\n\nstatic int parseParens (statementInfo *const st, parenInfo *const info)\n{\n\ttokenInfo *const token = activeToken (st);\n\tunsigned int identifierCount = 0;\n\tunsigned int depth = 1;\n\tbool firstChar = true;\n\tint nextChar = '\\0';\n\n\tCollectingSignature = true;\n\tvStringClear (Signature);\n\tvStringPut (Signature, '(');\n\tinfo->parameterCount = 1;\n\tdo\n\t{\n\t\tint c = skipToNonWhite ();\n\t\tcppVStringPut (Signature, c);\n\n\t\tswitch (c)\n\t\t{\n\t\t\tcase '^':\n\t\t\t\tbreak;\n\n\t\t\tcase '&':\n\t\t\tcase '*':\n\t\t\t\tinfo->isPointer = true;\n\t\t\t\tif (identifierCount == 0)\n\t\t\t\t\tinfo->isParamList = false;\n\t\t\t\tinitToken (token);\n\t\t\t\tbreak;\n\n\t\t\tcase ':':\n\t\t\t\tbreak;\n\n\t\t\tcase '.':\n\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\tc = cppGetc ();\n\t\t\t\tif (c != '.')\n\t\t\t\t\tcppUngetc (c);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tc = cppGetc ();\n\t\t\t\t\tif (c != '.')\n\t\t\t\t\t\tcppUngetc (c);\n\t\t\t\t\telse\n\t\t\t\t\t\tvStringCatS (Signature, \"...\"); /* variable arg list */\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase ',':\n\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\tbreak;\n\n\t\t\tcase '=':\n\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\tif (firstChar)\n\t\t\t\t{\n\t\t\t\t\tinfo->isParamList = false;\n\t\t\t\t\tskipMacro (st);\n\t\t\t\t\tdepth = 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase '[':\n\t\t\t\tskipToMatch (\"[]\");\n\t\t\t\tbreak;\n\n\t\t\tcase '<':\n\t\t\t\tprocessAngleBracket ();\n\t\t\t\tbreak;\n\n\t\t\tcase ')':\n\t\t\t\tif (firstChar)\n\t\t\t\t\tinfo->parameterCount = 0;\n\t\t\t\t--depth;\n\t\t\t\tbreak;\n\n\t\t\tcase '(':\n\t\t\t\tif (firstChar)\n\t\t\t\t{\n\t\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\t\tcppUngetc (c);\n\t\t\t\t\tvStringClear (Signature);\n\t\t\t\t\tskipMacro (st);\n\t\t\t\t\tdepth = 0;\n\t\t\t\t\tvStringChop (Signature);\n\t\t\t\t}\n\t\t\t\telse if (isType (token, TOKEN_PAREN_NAME))\n\t\t\t\t{\n\t\t\t\t\tc = skipToNonWhite ();\n\t\t\t\t\tif (c == '*')        /* check for function pointer */\n\t\t\t\t\t{\n\t\t\t\t\t\tskipToMatch (\"()\");\n\t\t\t\t\t\tc = skipToNonWhite ();\n\t\t\t\t\t\tif (c == '(')\n\t\t\t\t\t\t\tskipToMatch (\"()\");\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tcppUngetc (c);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcppUngetc (c);\n\t\t\t\t\t\tcppUngetc ('(');\n\t\t\t\t\t\tinfo->nestedArgs = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\t++depth;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tif (cppIsident1 (c))\n\t\t\t\t{\n\t\t\t\t\treadIdentifier (token, c);\n\t\t\t\t\tif (isType (token, TOKEN_NAME)  &&  info->isNameCandidate)\n\t\t\t\t\t\ttoken->type = TOKEN_PAREN_NAME;\n\t\t\t\t\telse if (isType (token, TOKEN_KEYWORD))\n\t\t\t\t\t{\n\t\t\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tinfo->isParamList     = false;\n\t\t\t\t\tinfo->isNameCandidate = false;\n\t\t\t\t\tinfo->invalidContents = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\tfirstChar = false;\n\t} while (! info->nestedArgs  &&  depth > 0  &&  info->isNameCandidate);\n\n\tif (! info->nestedArgs) while (depth > 0)\n\t{\n\t\tskipToMatch (\"()\");\n\t\t--depth;\n\t}\n\n\tif (! info->isNameCandidate)\n\t\tinitToken (token);\n\n\tCollectingSignature = false;\n\treturn nextChar;\n}\n\nstatic void initParenInfo (parenInfo *const info)\n{\n\tinfo->isPointer\t\t\t\t= false;\n\tinfo->isParamList\t\t\t= true;\n\tinfo->isNameCandidate\t\t= true;\n\tinfo->invalidContents\t\t= false;\n\tinfo->nestedArgs\t\t\t= false;\n\tinfo->parameterCount\t\t= 0;\n}\n\nstatic void analyzeParens (statementInfo *const st)\n{\n\ttokenInfo *const prev = prevToken (st, 1);\n\n\tif (st->inFunction && !st->assignment)\n\t\tst->notVariable = true;\n\n\tif (! isType (prev, TOKEN_NONE))  /* in case of ignored enclosing macros */\n\t{\n\t\ttokenInfo *const token = activeToken (st);\n\t\tparenInfo info;\n\t\tint c;\n\n\t\tinitParenInfo (&info);\n\t\tparseParens (st, &info);\n\t\tc = skipToNonWhite ();\n\t\tcppUngetc (c);\n\t\tif (info.invalidContents)\n\t\t{\n\t\t\t/* FIXME: This breaks parsing of variable instantiations that have\n\t\t\t   constants as parameters: Type var(0) or Type var(\"...\"). */\n\t\t\treinitStatement (st, false);\n\t\t}\n\t\telse if (info.isNameCandidate  &&  isType (token, TOKEN_PAREN_NAME)  &&\n\t\t\t\t ! st->gotParenName  &&\n\t\t\t\t (! info.isParamList || ! st->haveQualifyingName  ||\n\t\t\t\t  c == '('  ||\n\t\t\t\t  (c == '='  &&  st->implementation != IMP_VIRTUAL) ||\n\t\t\t\t  (st->declaration == DECL_NONE  &&  isOneOf (c, \",;\"))))\n\t\t{\n\t\t\ttoken->type = TOKEN_NAME;\n\t\t\tprocessName (st);\n\t\t\tst->gotParenName = true;\n\t\t\tif (! (c == '('  &&  info.nestedArgs))\n\t\t\t\tst->isPointer = info.isPointer;\n\t\t}\n\t\telse if (! st->gotArgs  &&  info.isParamList)\n\t\t{\n\t\t\tst->gotArgs = true;\n\t\t\tsetToken (st, TOKEN_ARGS);\n\t\t\tadvanceToken (st);\n\t\t\tif (st->scope != SCOPE_TYPEDEF)\n\t\t\t\tanalyzePostParens (st, &info);\n\t\t}\n\t\telse\n\t\t\tsetToken (st, TOKEN_NONE);\n\t}\n}\n\n/*\n*   Token parsing functions\n*/\n\nstatic void addContext (statementInfo *const st, const tokenInfo* const token)\n{\n\tif (isType (token, TOKEN_NAME))\n\t{\n\t\tvStringCat (st->context->name, token->name);\n\t\tst->context->type = TOKEN_NAME;\n\t}\n}\n\nstatic void processColon (statementInfo *const st)\n{\n\tint c = skipToNonWhite ();\n\tconst bool doubleColon = (bool) (c == ':');\n\n\tif (doubleColon)\n\t{\n\t\tsetToken (st, TOKEN_DOUBLE_COLON);\n\t\tst->haveQualifyingName = false;\n\t}\n\telse\n\t{\n\t\tconst tokenInfo *const prev  = prevToken (st, 1);\n\t\tcppUngetc (c);\n\t\tif (st->parent != NULL)\n\t\t{\n\t\t\tmakeTag (prev, st, false, TAG_LABEL);\n\t\t\treinitStatement (st, false);\n\t\t}\n\t}\n}\n\n/*  Skips over any initializing value which may follow an '=' character in a\n *  variable definition.\n */\nstatic int skipInitializer (statementInfo *const st)\n{\n\tbool done = false;\n\tint c;\n\n\twhile (! done)\n\t{\n\t\tc = skipToNonWhite ();\n\n\t\tif (c == EOF)\n\t\t\tlongjmp (Exception, (int) ExceptionFormattingError);\n\t\telse switch (c)\n\t\t{\n\t\t\tcase ',':\n\t\t\tcase ';': done = true; break;\n\n\t\t\tcase '0':\n\t\t\t\tif (st->implementation == IMP_VIRTUAL)\n\t\t\t\t\tst->implementation = IMP_PURE_VIRTUAL;\n\t\t\t\tbreak;\n\n\t\t\tcase '[': skipToMatch (\"[]\"); break;\n\t\t\tcase '(': skipToMatch (\"()\"); break;\n\t\t\tcase '{': skipToMatch (\"{}\"); break;\n\t\t\tcase '<': processAngleBracket(); break;\n\n\t\t\tcase '}':\n\t\t\t\tif (insideEnumBody (st))\n\t\t\t\t\tdone = true;\n\t\t\t\telse if (! cppIsBraceFormat ())\n\t\t\t\t{\n\t\t\t\t\tverbose (\"%s: unexpected closing brace at line %lu\\n\",\n\t\t\t\t\t\t\tgetInputFileName (), getInputLineNumber ());\n\t\t\t\t\tlongjmp (Exception, (int) ExceptionBraceFormattingError);\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault: break;\n\t\t}\n\t}\n\treturn c;\n}\n\nstatic void processInitializer (statementInfo *const st)\n{\n\tconst bool inEnumBody = insideEnumBody (st);\n\tint c = cppGetc ();\n\n\tif (c != '=')\n\t{\n\t\tcppUngetc (c);\n\t\tc = skipInitializer (st);\n\t\tst->assignment = true;\n\t\tif (c == ';')\n\t\t\tsetToken (st, TOKEN_SEMICOLON);\n\t\telse if (c == ',')\n\t\t\tsetToken (st, TOKEN_COMMA);\n\t\telse if (c == '}'  &&  inEnumBody)\n\t\t{\n\t\t\tcppUngetc (c);\n\t\t\tsetToken (st, TOKEN_COMMA);\n\t\t}\n\t\tif (st->scope == SCOPE_EXTERN)\n\t\t\tst->scope = SCOPE_GLOBAL;\n\t}\n}\n\nstatic void parseIdentifier (statementInfo *const st, const int c)\n{\n\ttokenInfo *const token = activeToken (st);\n\n\treadIdentifier (token, c);\n\tif (! isType (token, TOKEN_NONE))\n\t\tprocessToken (token, st);\n}\n\nstatic void parseGeneralToken (statementInfo *const st, const int c)\n{\n\tconst tokenInfo *const prev = prevToken (st, 1);\n\n\tif (cppIsident1 (c))\n\t{\n\n\t\tparseIdentifier (st, c);\n\t\tif (isType (st->context, TOKEN_NAME) &&\n\t\t\tisType (activeToken (st), TOKEN_NAME) && isType (prev, TOKEN_NAME))\n\t\t{\n\t\t\tinitToken (st->context);\n\t\t}\n\t}\n\telse if (c == '.' || c == '-')\n\t{\n\t\tif (! st->assignment)\n\t\t\tst->notVariable = true;\n\t\tif (c == '-')\n\t\t{\n\t\t\tint c2 = cppGetc ();\n\t\t\tif (c2 != '>')\n\t\t\t\tcppUngetc (c2);\n\t\t}\n\t}\n\telse if (c == '!' || c == '>')\n\t{\n\t\tint c2 = cppGetc ();\n\t\tif (c2 != '=')\n\t\t\tcppUngetc (c2);\n\t}\n\telse if (c == CPP_STRING_SYMBOL) {\n\t\tsetToken(st, TOKEN_NONE);\n\t}\n}\n\n/*  Reads characters from the pre-processor and assembles tokens, setting\n *  the current statement state.\n */\nstatic void nextToken (statementInfo *const st)\n{\n\ttokenInfo *token;\n\tdo\n\t{\n\t\tint c = skipToNonWhite ();\n\t\tswitch (c)\n\t\t{\n\t\t\tcase EOF: longjmp (Exception, (int) ExceptionEOF);  break;\n\t\t\tcase '(': analyzeParens (st);                       break;\n\t\t\tcase '<': processAngleBracket ();                   break;\n\t\t\tcase '*': st->haveQualifyingName = false;           break;\n\t\t\tcase ',': setToken (st, TOKEN_COMMA);               break;\n\t\t\tcase ':': processColon (st);                        break;\n\t\t\tcase ';': setToken (st, TOKEN_SEMICOLON);           break;\n\t\t\tcase '=': processInitializer (st);                  break;\n\t\t\tcase '[': skipToMatch (\"[]\");                       break;\n\t\t\tcase '{': setToken (st, TOKEN_BRACE_OPEN);          break;\n\t\t\tcase '}': setToken (st, TOKEN_BRACE_CLOSE);         break;\n\t\t\tdefault:  parseGeneralToken (st, c);                break;\n\t\t}\n\t\ttoken = activeToken (st);\n\t} while (isType (token, TOKEN_NONE));\n}\n\n/*\n*   Scanning support functions\n*/\n\nstatic statementInfo *CurrentStatement = NULL;\n\nstatic statementInfo *newStatement (statementInfo *const parent)\n{\n\tstatementInfo *const st = xMalloc (1, statementInfo);\n\tunsigned int i;\n\n\tfor (i = 0  ;  i < (unsigned int) NumTokens  ;  ++i)\n\t\tst->token [i] = newToken ();\n\n\tst->context = newToken ();\n\tst->blockName = newToken ();\n\tst->parentClasses = vStringNew ();\n\n\tinitStatement (st, parent);\n\tCurrentStatement = st;\n\n\treturn st;\n}\n\nstatic void deleteStatement (void)\n{\n\tstatementInfo *const st = CurrentStatement;\n\tstatementInfo *const parent = st->parent;\n\tunsigned int i;\n\n\tfor (i = 0  ;  i < (unsigned int) NumTokens  ;  ++i)\n\t{\n\t\tdeleteToken (st->token [i]);       st->token [i] = NULL;\n\t}\n\tdeleteToken (st->blockName);           st->blockName = NULL;\n\tdeleteToken (st->context);             st->context = NULL;\n\tvStringDelete (st->parentClasses);     st->parentClasses = NULL;\n\teFree (st);\n\tCurrentStatement = parent;\n}\n\nstatic void deleteAllStatements (void)\n{\n\twhile (CurrentStatement != NULL)\n\t\tdeleteStatement ();\n}\n\nstatic bool isStatementEnd (const statementInfo *const st)\n{\n\tconst tokenInfo *const token = activeToken (st);\n\tbool isEnd;\n\n\tif (isType (token, TOKEN_SEMICOLON))\n\t\tisEnd = true;\n\telse if (isType (token, TOKEN_BRACE_CLOSE))\n\t\tisEnd = ! isContextualStatement (st);\n\telse\n\t\tisEnd = false;\n\n\treturn isEnd;\n}\n\nstatic void checkStatementEnd (statementInfo *const st, int corkIndex)\n{\n\tconst tokenInfo *const token = activeToken (st);\n\n\tsetTagEndLineToCorkEntry (corkIndex, token->lineNumber);\n\n\tif (isType (token, TOKEN_COMMA))\n\t\treinitStatement (st, true);\n\telse if (isStatementEnd (st))\n\t{\n\t\tDebugStatement ( if (debug (DEBUG_PARSE)) printf (\"<ES>\"); )\n\t\treinitStatement (st, false);\n\t\tcppEndStatement ();\n\t}\n\telse\n\t{\n\t\tcppBeginStatement ();\n\t\tadvanceToken (st);\n\t}\n}\n\nstatic void nest (statementInfo *const st, const unsigned int nestLevel)\n{\n\tswitch (st->declaration)\n\t{\n\t\tcase DECL_CLASS:\n\t\tcase DECL_ENUM:\n\t\tcase DECL_INTERFACE:\n\t\t\tcreateTags (nestLevel, st);\n\t\t\tbreak;\n\n\t\tcase DECL_FUNCTION:\n\t\tcase DECL_TASK:\n\t\t\tst->inFunction = true;\n\t\t\t/* fall through */\n\t\tdefault:\n\t\t\tif (includeTag (TAG_LOCAL, false) || includeTag (TAG_LABEL, false))\n\t\t\t\tcreateTags (nestLevel, st);\n\t\t\telse\n\t\t\t\tskipToMatch (\"{}\");\n\t\t\tbreak;\n\t}\n\tadvanceToken (st);\n\tsetToken (st, TOKEN_BRACE_CLOSE);\n}\n\nstatic int tagCheck (statementInfo *const st)\n{\n\tconst tokenInfo *const token = activeToken (st);\n\tconst tokenInfo *const prev  = prevToken (st, 1);\n\tconst tokenInfo *const prev2 = prevToken (st, 2);\n\tint corkIndex = CORK_NIL;\n\n\tswitch (token->type)\n\t{\n\t\tcase TOKEN_NAME:\n\t\t\tif (insideEnumBody (st))\n\t\t\t\tcorkIndex = qualifyEnumeratorTag (st, token);\n\t\t\tif (insideInterfaceBody (st))\n\t\t\t{\n\t\t\t\t/* Quoted from\n\t\t\t\t   http://www.asic-world.com/vera/hdl1.html#Interface_Declaration\n\t\t\t\t   ------------------------------------------------\n\t\t\t\t   interface interface_name\n\t\t\t\t   {\n\t\t\t\t   signal_direction [signal_width] signal_name signal_type\n\t\t\t\t   [skew] [depth value][vca q_value][force][hdl_node \"hdl_path\"];\n\t\t\t\t   }\n\t\t\t\t   Where\n\t\t\t\t   signal_direction : This can be one of the following\n\t\t\t\t        input : ...\n\t\t\t\t        output : ...\n\t\t\t\t        inout : ...\n\t\t\t\t   signal_width : The signal_width is a range specifying the width of\n\t\t\t\t                  a vector signal. It must be in the form [msb:lsb].\n\t\t\t\t\t\t  Interface signals can have any integer lsb value,\n\t\t\t\t\t\t  even a negative value. The default width is 1.\n\t\t\t\t   signal_name : The signal_name identifies the signal being defined.\n\t\t\t\t                 It is the Vera name for the HDL signal being connected.\n\t\t\t\t   signal_type : There are many signals types, most commonly used one are\n\t\t\t\t\tNHOLD : ...\n\t\t\t\t\tPHOLD : ...\n\t\t\t\t\tPHOLD NHOLD : ...\n\t\t\t\t\tNSAMPLE : ...\n\t\t\t\t\tPSAMPLE : ...\n\t\t\t\t\tPSAMPLE NSAMPLE : ...\n\t\t\t\t\tCLOCK : ...\n\t\t\t\t\tPSAMPLE PHOLD : ...\n\t\t\t\t\tNSAMPLE NHOLD : ...\n\t\t\t\t\tPSAMPLE PHOLD NSAMPLE NHOLD : ...\n\t\t\t\t   ------------------------------------------------\n\t\t\t\t   We want to capture \"signal_name\" here.\n\t\t\t\t*/\n\t\t\t\tif (( isType (prev, TOKEN_KEYWORD)\n\t\t\t\t      && isSignalDirection(prev) ) ||\n\t\t\t\t    ( isType (prev2, TOKEN_KEYWORD)\n\t\t\t\t      && isSignalDirection(prev) ))\n\t\t\t\t\tcorkIndex = makeTag (token, st, false, TAG_SIGNAL);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase TOKEN_BRACE_OPEN:\n\t\t\tif (isType (prev, TOKEN_ARGS))\n\t\t\t{\n\t\t\t\tif (st->haveQualifyingName)\n\t\t\t\t{\n\t\t\t\t\tif (isType (prev2, TOKEN_NAME))\n\t\t\t\t\t\tcopyToken (st->blockName, prev2);\n\n\t\t\t\t\tcorkIndex = qualifyFunctionTag (st, prev2);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (isContextualStatement (st) ||\n\t\t\t\t\tst->declaration == DECL_PROGRAM)\n\t\t\t{\n\t\t\t\tconst tokenInfo *name_token = prev;\n\n\t\t\t\tif (isType (name_token, TOKEN_NAME))\n\t\t\t\t\tcopyToken (st->blockName, name_token);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t/*  For an anonymous struct or union we use a unique ID\n\t\t\t\t\t *  a number, so that the members can be found.\n\t\t\t\t\t */\n\t\t\t\t\tchar buf [20];  /* length of \"_anon\" + digits  + null */\n\t\t\t\t\tsprintf (buf, \"__anon%d\", ++AnonymousID);\n\t\t\t\t\tvStringCopyS (st->blockName->name, buf);\n\t\t\t\t\tst->blockName->type = TOKEN_NAME;\n\t\t\t\t\tst->blockName->keyword = KEYWORD_NONE;\n\t\t\t\t}\n\t\t\t\tcorkIndex = qualifyBlockTag (st, name_token);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase TOKEN_KEYWORD:\n\t\t\tbreak;\n\n\t\tcase TOKEN_SEMICOLON:\n\t\tcase TOKEN_COMMA:\n\t\t\tif (insideEnumBody (st))\n\t\t\t\t;\n\t\t\telse if (isType (prev, TOKEN_NAME))\n\t\t\t{\n\t\t\t\tif (isContextualKeyword (prev2))\n\t\t\t\t\tcorkIndex = makeTag (prev, st, true, TAG_EXTERN_VAR);\n\t\t\t\telse\n\t\t\t\t\tcorkIndex = qualifyVariableTag (st, prev);\n\t\t\t}\n\t\t\telse if (isType (prev, TOKEN_ARGS)  &&  isType (prev2, TOKEN_NAME))\n\t\t\t{\n\t\t\t\tif (st->isPointer || st->inFunction)\n\t\t\t\t{\n\t\t\t\t\t/* If it looks like a pointer or we are in a function body then\n\t\t\t\t\t   it's far more likely to be a variable. */\n\t\t\t\t\tcorkIndex = qualifyVariableTag (st, prev2);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tcorkIndex = qualifyFunctionDeclTag (st, prev2);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault: break;\n\t}\n\n\treturn corkIndex;\n}\n\n/*  Parses the current file and decides whether to write out and tags that\n *  are discovered.\n */\nstatic void createTags (const unsigned int nestLevel,\n\t\t\t\t\t\tstatementInfo *const parent)\n{\n\tstatementInfo *const st = newStatement (parent);\n\n\tDebugStatement ( if (nestLevel > 0) debugParseNest (true, nestLevel); )\n\twhile (true)\n\t{\n\t\ttokenInfo *token;\n\n\t\tnextToken (st);\n\t\ttoken = activeToken (st);\n\t\tif (isType (token, TOKEN_BRACE_CLOSE))\n\t\t{\n\t\t\tif (nestLevel > 0)\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t{\n\t\t\t\tverbose (\"%s: unexpected closing brace at line %lu\\n\",\n\t\t\t\t\t\tgetInputFileName (), getInputLineNumber ());\n\t\t\t\tlongjmp (Exception, (int) ExceptionBraceFormattingError);\n\t\t\t}\n\t\t}\n\t\telse if (isType (token, TOKEN_DOUBLE_COLON))\n\t\t{\n\t\t\taddContext (st, prevToken (st, 1));\n\t\t\tadvanceToken (st);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tint corkIndex = tagCheck (st);\n\t\t\tif (isType (token, TOKEN_BRACE_OPEN))\n\t\t\t\tnest (st, nestLevel + 1);\n\t\t\tcheckStatementEnd (st, corkIndex);\n\t\t}\n\t}\n\tdeleteStatement ();\n\tDebugStatement ( if (nestLevel > 0) debugParseNest (false, nestLevel - 1); )\n}\n\nstatic rescanReason findCTags (const unsigned int passCount)\n{\n\texception_t exception;\n\trescanReason rescan;\n\tint kind_for_define = VK_DEFINE;\n\tint kind_for_header = VK_HEADER;\n\tint kind_for_param  = VK_MACRO_PARAM;\n\tint role_for_macro_undef = VR_MACRO_UNDEF;\n\tint role_for_macro_condition = VR_MACRO_CONDITION;\n\tint role_for_header_system   = VR_HEADER_SYSTEM;\n\tint role_for_header_local   = VR_HEADER_LOCAL;\n\n\tAssert (passCount < 3);\n\n\tAnonymousID = 0;\n\n\tcppInit ((bool) (passCount > 1), false, false,\n\t\t true,\n\t\t kind_for_define, role_for_macro_undef, role_for_macro_condition, kind_for_param,\n\t\t kind_for_header, role_for_header_system, role_for_header_local,\n\t\t FIELD_UNKNOWN);\n\n\tSignature = vStringNew ();\n\n\texception = (exception_t) setjmp (Exception);\n\trescan = RESCAN_NONE;\n\tif (exception == ExceptionNone)\n\t\tcreateTags (0, NULL);\n\telse\n\t{\n\t\tdeleteAllStatements ();\n\t\tif (exception == ExceptionBraceFormattingError  &&  passCount == 1)\n\t\t{\n\t\t\trescan = RESCAN_FAILED;\n\t\t\tverbose (\"%s: retrying file with fallback brace matching algorithm\\n\",\n\t\t\t\t\tgetInputFileName ());\n\t\t}\n\t}\n\tvStringDelete (Signature);\n\tcppTerminate ();\n\treturn rescan;\n}\n\nstatic void buildKeywordHash (const langType language, unsigned int idx)\n{\n\tconst size_t count = ARRAY_SIZE (KeywordTable);\n\tsize_t i;\n\tfor (i = 0  ;  i < count  ;  ++i)\n\t{\n\t\tconst keywordDesc* const p = &KeywordTable [i];\n\t\taddKeyword (p->name, language, (int) p->id);\n\t}\n}\n\nstatic void initializeVeraParser (const langType language)\n{\n\tLang_vera = language;\n\tbuildKeywordHash (language, 0);\n}\n\nextern parserDefinition* VeraParser (void)\n{\n\tstatic const char *const extensions [] = { \"vr\", \"vri\", \"vrh\", NULL };\n\tparserDefinition* def = parserNew (\"Vera\");\n\tdef->kindTable      = VeraKinds;\n\tdef->kindCount  = ARRAY_SIZE (VeraKinds);\n\tdef->extensions = extensions;\n\tdef->parser2    = findCTags;\n\tdef->initialize = initializeVeraParser;\n\t// end: field is not tested.\n\n\t/* cpreprocessor wants corkQueue. */\n\tdef->useCork    = CORK_QUEUE;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/verilog.c",
    "content": "/*\n *\t Copyright (c) 2003, Darren Hiebert\n *\t Copyright (c) 2017, Vitor Antunes\n *\t Copyright (c) 2020, Hiroo Hayashi\n *\n *\t This source code is released for free distribution under the terms of the\n *\t GNU General Public License version 2 or (at your option) any later version.\n *\n *\t This module contains functions for generating tags for the Verilog or\n *\t SystemVerilog HDL (Hardware Description Language).\n *\n *\t References:\n *\t\tIEEE Std 1800-2017, SystemVerilog Language Reference Manual\n *\t\t\thttps://ieeexplore.ieee.org/document/8299595\n *\t\tSystemVerilog IEEE Std 1800-2012 Grammer\n *\t\t\thttps://insights.sigasi.com/tech/systemverilog.ebnf/\n *\t\tVerilog Formal Syntax Specification\n *\t\t\thttp://www.verilog.com/VerilogBNF.html\n */\n\n/*\n *\t INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"xtag.h\"\n#include \"ptrarray.h\"\n#include \"numarray.h\"\n\n/*\n *\t MACROS\n */\n#define NUMBER_LANGUAGES\t2\t/* Indicates number of defined indexes */\n#define IDX_SYSTEMVERILOG\t0\n#define IDX_VERILOG\t\t\t1\n\n#ifndef DEBUG\n#define VERBOSE(...) do { \\\n\t\tverbose(\"%s:%ld:%s:%d:Internal Error:\", getInputFileName(), getInputLineNumber(), __FILE__, __LINE__); \\\n\t\tverbose(__VA_ARGS__); \\\n\t} while (0)\n#else\n#define VERBOSE(...) do { \\\n\t\tfprintf(stderr, \"%s:%ld:%s:%d:Internal Error:\", getInputFileName(), getInputLineNumber(), __FILE__, __LINE__); \\\n\t\tfprintf(stderr, __VA_ARGS__); \\\n\t} while (0)\n#endif\n\n/*\n *\t DATA DECLARATIONS\n */\n\n/* A callback function searching a symbol from the cork symbol table assumes\n * this kind definitions are shared in Verilog and SystemVerilog parsers.\n * If you will separate the definitions for the parsers, you must revise the\n * code related to the symbol table. */\ntypedef enum {\n\t/* parser private items */\n\tK_IGNORE = -16,\t/* Verilog/SystemVerilog keywords to be ignored */\n\tK_DIRECTIVE,\n\tK_END,\n\tK_END_DE,\t/* End of Design Elements */\n\tK_IDENTIFIER,\n\tK_LOCALPARAM,\n\tK_PARAMETER,\n\tK_IMPORT,\n\tK_WITH,\n\n\tK_UNDEFINED = KEYWORD_NONE,\n\t/* the followings items are also used as indices for VerilogKinds[] and SystemVerilogKinds[] */\n\tK_CONSTANT= 0,\n\tK_DEFINE,\n\tK_EVENT,\n\tK_FUNCTION,\n\tK_MODULE,\n\tK_NET,\n\tK_PORT,\n\tK_REGISTER,\n\tK_TASK,\n\tK_BLOCK,\n\tK_INSTANCE,\n\tK_ASSERTION,\n\tK_CLASS,\n\tK_COVERGROUP,\n\tK_ENUM,\n\tK_INTERFACE,\n\tK_MODPORT,\n\tK_PACKAGE,\n\tK_PROGRAM,\n\tK_PROTOTYPE,\n\tK_PROPERTY,\n\tK_STRUCT,\n\tK_TYPEDEF,\n\tK_CHECKER,\n\tK_CLOCKING,\n\tK_SEQUENCE,\n\tK_MEMBER,\n\tK_IFCLASS,\t/* interface class */\n\tK_CONSTRAINT,\n\tK_NETTYPE,\n\tK_VIRTUAL,\n} verilogKind;\n\ntypedef enum {\n\tR_MODULE_DECL,\n} verilogModuleRole;\n\ntypedef struct {\n\tconst char *keyword;\n\tverilogKind kind;\n\tshort isValid [NUMBER_LANGUAGES];\n} keywordAssoc;\n\ntypedef struct sTokenInfo {\n\tverilogKind\t\t\tkind;\n\tvString*\t\t\tname;\t\t\t/* the name of the token */\n\tunsigned long\t\tlineNumber;\t\t/* line number where token was found */\n\tMIOPos\t\t\t\tfilePosition;\t/* file position where token was found */\n\tstruct sTokenInfo*\tscope;\t\t\t/* context of keyword */\n\tint\t\t\t\t\tnestLevel;\t\t/* Current nest level */\n\tverilogKind\t\t\tlastKind;\t\t/* Kind of last found tag */\n\tvString*\t\t\tblockName;\t\t/* Current block name */\n\tvString*\t\t\tinheritance;\t/* Class inheritance */\n\tbool\t\t\t\tprototype;\t\t/* Is only a prototype */\n\tbool\t\t\t\tclassScope;\t\t/* Context is local to the current sub-context */\n\tbool\t\t\t\tparameter;\t\t/* parameter which can be overridden */\n\tbool\t\t\t\thasParamList;\t/* module definition has a parameter port list */\n\tbool\t\t\t\tvirtual;\t\t/* has virtual */\n} tokenInfo;\n\ntypedef enum {\n\tF_PARAMETER,\n} verilogField;\n\n/*\n *\t DATA DEFINITIONS\n */\nstatic int Ungetc;\nstatic int Lang_verilog;\nstatic int Lang_systemverilog;\n\nstatic roleDefinition VerilogModuleRoles [] = {\n { true, \"decl\", \"declaring instances\" },\n};\n\nstatic roleDefinition SystemVerilogModuleRoles [] = {\n { true, \"decl\", \"declaring instances\" },\n};\n\nstatic kindDefinition VerilogKinds [] = {\n { true, 'c', \"constant\",\t\"constants (parameter, specparam)\" },\n { true, 'd', \"define\",\t\t\"text macros\",\n   .version = 1 },\n { true, 'e', \"event\",\t\t\"events\" },\n { true, 'f', \"function\",\t\"functions\" },\n { true, 'm', \"module\",\t\t\"modules\",\n   .referenceOnly = false, ATTACH_ROLES(VerilogModuleRoles) },\n { true, 'n', \"net\",\t\t\"net data types\" },\n { true, 'p', \"port\",\t\t\"ports\" },\n { true, 'r', \"register\",\t\"variable data types\" },\n { true, 't', \"task\",\t\t\"tasks\" },\n { true, 'b', \"block\",\t\t\"blocks (begin, fork)\" },\n { true, 'i', \"instance\",\t\"instances of module\" },\n};\n\nstatic kindDefinition SystemVerilogKinds [] = {\n { true, 'c', \"constant\",\t\"constants (parameter, specparam, enum values)\" },\n { true, 'd', \"define\",\t\t\"text macros\",\n   .version = 1 },\n { true, 'e', \"event\",\t\t\"events\" },\n { true, 'f', \"function\",\t\"functions\" },\n { true, 'm', \"module\",\t\t\"modules\",\n   .referenceOnly = false, ATTACH_ROLES(SystemVerilogModuleRoles) },\n { true, 'n', \"net\",\t\t\"net data types\" },\n { true, 'p', \"port\",\t\t\"ports\" },\n { true, 'r', \"register\",\t\"variable data types\" },\n { true, 't', \"task\",\t\t\"tasks\" },\n { true, 'b', \"block\",\t\t\"blocks (begin, fork)\" },\n { true, 'i', \"instance\",\t\"instances of module or interface\" },\n { true, 'A', \"assert\",\t\t\"assertions (assert, assume, cover, restrict)\" },\n { true, 'C', \"class\",\t\t\"classes\" },\n { true, 'V', \"covergroup\",\t\"covergroups\" },\n { true, 'E', \"enum\",\t\t\"enumerators\" },\n { true, 'I', \"interface\", \t\"interfaces\" },\n { true, 'M', \"modport\",\t\"modports\" },\n { true, 'K', \"package\",\t\"packages\" },\n { true, 'P', \"program\",\t\"programs\" },\n { false,'Q', \"prototype\",\t\"prototypes (extern, pure)\" },\n { true, 'R', \"property\",\t\"properties\" },\n { true, 'S', \"struct\",\t\t\"structs and unions\" },\n { true, 'T', \"typedef\",\t\"type declarations\" },\n { true, 'H', \"checker\",\t\"checkers\" },\n { true, 'L', \"clocking\",\t\"clocking\" },\n { true, 'q', \"sequence\",\t\"sequences\" },\n { true, 'w', \"member\",\t\t\"struct and union members\" },\n { true, 'l', \"ifclass\",\t\"interface class\" },\n { true, 'O', \"constraint\",\t\"constraints\" },\n { true, 'N', \"nettype\",\t\"nettype declarations\" },\n};\n\nstatic const keywordAssoc KeywordTable [] = {\n\t/*\t\t\t\t\t\t\t\t \t  SystemVerilog\t*/\n\t/*\t\t\t\t\t\t\t\t \t  |  Verilog\t*/\n\t/* keyword\t\t \tkeyword ID\t \t  |  |\t\t\t*/\n\t{ \"`define\",\t\tK_DEFINE,\t\t{ 1, 1 } },\n\t{ \"begin\",\t\t\tK_BLOCK,\t\t{ 1, 1 } },\n\t{ \"end\",\t\t\tK_END,\t\t\t{ 1, 1 } },\n\t{ \"endfunction\",\tK_END_DE,\t\t{ 1, 1 } },\n\t{ \"endmodule\",\t\tK_END_DE,\t\t{ 1, 1 } },\n\t{ \"endtask\",\t\tK_END_DE,\t\t{ 1, 1 } },\n\t{ \"event\",\t\t\tK_EVENT,\t\t{ 1, 1 } },\n\t{ \"fork\",\t\t\tK_BLOCK,\t\t{ 1, 1 } },\n\t{ \"function\",\t\tK_FUNCTION,\t\t{ 1, 1 } },\n\t{ \"genvar\",\t\t\tK_REGISTER,\t\t{ 1, 1 } },\n\t{ \"inout\",\t\t\tK_PORT,\t\t\t{ 1, 1 } },\n\t{ \"input\",\t\t\tK_PORT,\t\t\t{ 1, 1 } },\n\t{ \"integer\",\t\tK_REGISTER,\t\t{ 1, 1 } },\n\t{ \"join\",\t\t\tK_END,\t\t\t{ 1, 1 } },\n\t{ \"localparam\",\t\tK_LOCALPARAM,\t{ 1, 1 } },\n\t{ \"module\",\t\t\tK_MODULE,\t\t{ 1, 1 } },\n\t{ \"output\",\t\t\tK_PORT,\t\t\t{ 1, 1 } },\n\t{ \"parameter\",\t\tK_PARAMETER,\t{ 1, 1 } },\n\t{ \"real\",\t\t\tK_REGISTER,\t\t{ 1, 1 } },\n\t{ \"realtime\",\t\tK_REGISTER,\t\t{ 1, 1 } },\n\t{ \"reg\",\t\t\tK_REGISTER,\t\t{ 1, 1 } },\n\t{ \"signed\",\t\t\tK_IGNORE,\t\t{ 1, 1 } },\n\t{ \"specparam\",\t\tK_CONSTANT,\t\t{ 1, 1 } },\n\t{ \"supply0\",\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"supply1\",\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"task\",\t\t\tK_TASK,\t\t\t{ 1, 1 } },\n\t{ \"time\",\t\t\tK_REGISTER,\t\t{ 1, 1 } },\n\t{ \"tri\",\t\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"triand\",\t\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"trior\",\t\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"trireg\",\t\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"tri0\",\t\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"tri1\",\t\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"uwire\",\t\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"wand\",\t\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"wire\",\t\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"wor\",\t\t\tK_NET,\t\t\t{ 1, 1 } },\n\t{ \"assert\",\t\t\tK_ASSERTION,\t{ 1, 0 } },\n\t{ \"assume\",\t\t\tK_ASSERTION,\t{ 1, 0 } },\n\t{ \"bit\",\t\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"byte\",\t\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"chandle\",\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"checker\",\t\tK_CHECKER,\t\t{ 1, 0 } },\n\t{ \"class\",\t\t\tK_CLASS,\t\t{ 1, 0 } },\n\t{ \"constraint\",\t\tK_CONSTRAINT,\t{ 1, 0 } },\n\t{ \"cover\",\t\t\tK_ASSERTION,\t{ 1, 0 } },\n\t{ \"clocking\",\t\tK_CLOCKING,\t\t{ 1, 0 } },\n\t{ \"covergroup\",\t\tK_COVERGROUP,\t{ 1, 0 } },\n\t{ \"endchecker\",\t\tK_END_DE,\t\t{ 1, 0 } },\n\t{ \"endclass\",\t\tK_END_DE,\t\t{ 1, 0 } },\n\t{ \"endclocking\",\tK_END_DE,\t\t{ 1, 0 } },\n\t{ \"endgroup\",\t\tK_END_DE,\t\t{ 1, 0 } },\n\t{ \"endinterface\",\tK_END_DE,\t\t{ 1, 0 } },\n\t{ \"endpackage\",\t\tK_END_DE,\t\t{ 1, 0 } },\n\t{ \"endprogram\",\t\tK_END_DE,\t\t{ 1, 0 } },\n\t{ \"endproperty\",\tK_END_DE,\t\t{ 1, 0 } },\n\t{ \"endsequence\",\tK_END_DE,\t\t{ 1, 0 } },\n\t{ \"enum\",\t\t\tK_ENUM,\t\t\t{ 1, 0 } },\n\t{ \"extern\",\t\t\tK_PROTOTYPE,\t{ 1, 0 } },\n\t{ \"import\",\t\t\tK_IMPORT,\t\t{ 1, 0 } },\n\t{ \"int\",\t\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"interconnect\",\tK_NET,\t\t\t{ 1, 0 } },\n\t{ \"interface\",\t\tK_INTERFACE,\t{ 1, 0 } },\n\t{ \"join_any\",\t\tK_END,\t\t\t{ 1, 0 } },\n\t{ \"join_none\",\t\tK_END,\t\t\t{ 1, 0 } },\n\t{ \"logic\",\t\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"longint\",\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"modport\",\t\tK_MODPORT,\t\t{ 1, 0 } },\n\t{ \"package\",\t\tK_PACKAGE,\t\t{ 1, 0 } },\n\t{ \"program\",\t\tK_PROGRAM,\t\t{ 1, 0 } },\n\t{ \"property\",\t\tK_PROPERTY,\t\t{ 1, 0 } },\n\t{ \"pure\",\t\t\tK_PROTOTYPE,\t{ 1, 0 } },\n\t{ \"ref\",\t\t\tK_PORT,\t\t\t{ 1, 0 } },\n\t{ \"restrict\",\t\tK_ASSERTION,\t{ 1, 0 } },\n\t{ \"sequence\",\t\tK_SEQUENCE,\t\t{ 1, 0 } },\n\t{ \"shortint\",\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"shortreal\",\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"string\",\t\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"struct\",\t\t\tK_STRUCT,\t\t{ 1, 0 } },\n\t{ \"type\",\t\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"typedef\",\t\tK_TYPEDEF,\t\t{ 1, 0 } },\n\t{ \"union\",\t\t\tK_STRUCT,\t\t{ 1, 0 } },\n\t{ \"var\",\t\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"void\",\t\t\tK_REGISTER,\t\t{ 1, 0 } },\n\t{ \"with\",\t\t\tK_WITH,\t\t\t{ 1, 0 } },\n\t{ \"nettype\",\t\tK_NETTYPE,\t\t{ 1, 0 } },\n\t{ \"virtual\",\t\tK_VIRTUAL,\t\t{ 1, 0 } },\n};\n\nstatic tokenInfo *currentContext = NULL;\nstatic ptrArray *tagContents;\nstatic fieldDefinition *fieldTable = NULL;\n\n// IEEE Std 1364-2005 LRM, Appendix B \"List of Keywords\"\nstatic const struct keywordGroup verilogKeywords = {\n\t.value = K_IGNORE,\n\t.addingUnlessExisting = true,\n\t.keywords = {\n\t\t\"always\", \"and\", \"assign\", \"automatic\", \"begin\", \"buf\", \"bufif0\",\n\t\t\"bufif1\", \"case\", \"casex\", \"casez\", \"cell\", \"cmos\", \"config\",\n\t\t\"deassign\", \"default\", \"defparam\", \"design\", \"disable\", \"edge\",\n\t\t\"else\", \"end\", \"endcase\", \"endconfig\", \"endfunction\", \"endgenerate\",\n\t\t\"endmodule\", \"endprimitive\", \"endspecify\", \"endtable\", \"endtask\",\n\t\t\"event\", \"for\", \"force\", \"forever\", \"fork\", \"function\", \"generate\",\n\t\t\"genvar\", \"highz0\", \"highz1\", \"if\", \"ifnone\", \"incdir\", \"include\",\n\t\t\"initial\", \"inout\", \"input\", \"instance\", \"integer\", \"join\", \"large\",\n\t\t\"liblist\", \"library\", \"localparam\", \"macromodule\", \"medium\", \"module\",\n\t\t\"nand\", \"negedge\", \"nmos\", \"nor\", \"noshowcancelled\", \"not\", \"notif0\",\n\t\t\"notif1\", \"or\", \"output\", \"parameter\", \"pmos\", \"posedge\", \"primitive\",\n\t\t\"pull0\", \"pull1\", \"pulldown\", \"pullup\", \"pulsestyle_onevent\",\n\t\t\"pulsestyle_ondetect\", \"rcmos\", \"real\", \"realtime\", \"reg\", \"release\",\n\t\t\"repeat\", \"rnmos\", \"rpmos\", \"rtran\", \"rtranif0\", \"rtranif1\",\n\t\t\"scalared\", \"showcancelled\", \"signed\", \"small\", \"specify\",\n\t\t\"specparam\", \"strong0\", \"strong1\", \"supply0\", \"supply1\", \"table\",\n\t\t\"task\", \"time\", \"tran\", \"tranif0\", \"tranif1\", \"tri\", \"tri0\", \"tri1\",\n\t\t\"triand\", \"trior\", \"trireg\", \"unsigned\", \"use\", \"uwire\", \"vectored\",\n\t\t\"wait\", \"wand\", \"weak0\", \"weak1\", \"while\", \"wire\", \"wor\", \"xnor\", \"xor\",\n\t\tNULL\n\t},\n};\n// IEEE Std 1800-2017 LRM, Annex B \"Keywords\"\nstatic const struct keywordGroup systemVerilogKeywords = {\n\t.value = K_IGNORE,\n\t.addingUnlessExisting = true,\n\t.keywords = {\n\t\t\"accept_on\", \"alias\", \"always\", \"always_comb\", \"always_ff\",\n\t\t\"always_latch\", \"and\", \"assert\", \"assign\", \"assume\", \"automatic\",\n\t\t\"before\", \"begin\", \"bind\", \"bins\", \"binsof\", \"bit\", \"break\", \"buf\",\n\t\t\"bufif0\", \"bufif1\", \"byte\", \"case\", \"casex\", \"casez\", \"cell\",\n\t\t\"chandle\", \"checker\", \"class\", \"clocking\", \"cmos\", \"config\", \"const\",\n\t\t\"constraint\", \"context\", \"continue\", \"cover\", \"covergroup\",\n\t\t\"coverpoint\", \"cross\", \"deassign\", \"default\", \"defparam\", \"design\",\n\t\t\"disable\", \"dist\", \"do\", \"edge\", \"else\", \"end\", \"endcase\",\n\t\t\"endchecker\", \"endclass\", \"endclocking\", \"endconfig\", \"endfunction\",\n\t\t\"endgenerate\", \"endgroup\", \"endinterface\", \"endmodule\", \"endpackage\",\n\t\t\"endprimitive\", \"endprogram\", \"endproperty\", \"endspecify\",\n\t\t\"endsequence\", \"endtable\", \"endtask\", \"enum\", \"event\", \"eventually\",\n\t\t\"expect\", \"export\", \"extends\", \"extern\", \"final\", \"first_match\",\n\t\t\"for\", \"force\", \"foreach\", \"forever\", \"fork\", \"forkjoin\", \"function\",\n\t\t\"generate\", \"genvar\", \"global\", \"highz0\", \"highz1\", \"if\", \"iff\",\n\t\t\"ifnone\", \"ignore_bins\", \"illegal_bins\", \"implements\", \"implies\",\n\t\t\"import\", \"incdir\", \"include\", \"initial\", \"inout\", \"input\", \"inside\",\n\t\t\"instance\", \"int\", \"integer\", \"interconnect\", \"interface\",\n\t\t\"intersect\", \"join\", \"join_any\", \"join_none\", \"large\", \"let\",\n\t\t\"liblist\", \"library\", \"local\", \"localparam\", \"logic\", \"longint\",\n\t\t\"macromodule\", \"matches\", \"medium\", \"modport\", \"module\", \"nand\",\n\t\t\"negedge\", \"nettype\", \"new\", \"nexttime\", \"nmos\", \"nor\",\n\t\t\"noshowcancelled\", \"not\", \"notif0\", \"notif1\", \"null\", \"or\", \"output\",\n\t\t\"package\", \"packed\", \"parameter\", \"pmos\", \"posedge\", \"primitive\",\n\t\t\"priority\", \"program\", \"property\", \"protected\", \"pull0\", \"pull1\",\n\t\t\"pulldown\", \"pullup\", \"pulsestyle_ondetect\", \"pulsestyle_onevent\",\n\t\t\"pure\", \"rand\", \"randc\", \"randcase\", \"randsequence\", \"rcmos\", \"real\",\n\t\t\"realtime\", \"ref\", \"reg\", \"reject_on\", \"release\", \"repeat\",\n\t\t\"restrict\", \"return\", \"rnmos\", \"rpmos\", \"rtran\", \"rtranif0\",\n\t\t\"rtranif1\", \"s_always\", \"s_eventually\", \"s_nexttime\", \"s_until\",\n\t\t\"s_until_with\", \"scalared\", \"sequence\", \"shortint\", \"shortreal\",\n\t\t\"showcancelled\", \"signed\", \"small\", \"soft\", \"solve\", \"specify\",\n\t\t\"specparam\", \"static\", \"string\", \"strong\", \"strong0\", \"strong1\",\n\t\t\"struct\", \"super\", \"supply0\", \"supply1\", \"sync_accept_on\",\n\t\t\"sync_reject_on\", \"table\", \"tagged\", \"task\", \"this\", \"throughout\",\n\t\t\"time\", \"timeprecision\", \"timeunit\", \"tran\", \"tranif0\", \"tranif1\",\n\t\t\"tri\", \"tri0\", \"tri1\", \"triand\", \"trior\", \"trireg\", \"type\", \"typedef\",\n\t\t\"union\", \"unique\", \"unique0\", \"unsigned\", \"until\", \"until_with\",\n\t\t\"untyped\", \"use\", \"uwire\", \"var\", \"vectored\", \"virtual\", \"void\",\n\t\t\"wait\", \"wait_order\", \"wand\", \"weak\", \"weak0\", \"weak1\", \"while\",\n\t\t\"wildcard\", \"wire\", \"with\", \"within\", \"wor\", \"xnor\", \"xor\",\n\t\tNULL\n\t},\n};\n\n// IEEE Std 1364-2005 LRM, \"19. Compiler directives\"\nstatic const struct keywordGroup verilogDirectives = {\n\t.value = K_DIRECTIVE,\n\t.addingUnlessExisting = true,\n\t.keywords = {\n\t\t\"`begin_keywords\", \"`celldefine\", \"`default_nettype\", \"`define\",\n\t\t\"`else\", \"`elsif\", \"`end_keywords\", \"`endcelldefine\", \"`endif\",\n\t\t\"`ifdef\", \"`ifndef\", \"`include\", \"`line\", \"`nounconnected_drive\",\n\t\t\"`pragma\", \"`resetall\", \"`timescale\", \"`unconnected_drive\", \"`undef\",\n\t\tNULL\n\t},\n};\n\n// IEEE Std 1800-2017 LRM, \"22. Compiler directives\"\nstatic const struct keywordGroup systemVerilogDirectives = {\n\t.value = K_DIRECTIVE,\n\t.addingUnlessExisting = true,\n\t.keywords = {\n\t\t\"`__LINE__\", \"`begin_keywords\", \"`celldefine\", \"`default_nettype\",\n\t\t\"`define\", \"`else\", \"`elsif\", \"`end_keywords\", \"`endcelldefine\",\n\t\t\"`endif\", \"`ifdef\", \"`ifndef\", \"`include\", \"`line\",\n\t\t\"`nounconnected_drive\", \"`pragma\", \"`resetall\", \"`timescale\",\n\t\t\"`unconnected_drive\", \"`undef\", \"`undefineall\",\n\t\tNULL\n\t},\n};\n\n// .enabled field cannot be shared by two languages\nstatic fieldDefinition VerilogFields[] = {\n\t{\n\t\t.name = \"parameter\",\n\t\t.description = \"parameter whose value can be overridden.\",\n\t\t.enabled = false,\n\t\t.dataType = FIELDTYPE_BOOL,\n\t},\n};\n\nstatic fieldDefinition SystemVerilogFields[] = {\n\t{\n\t\t.name = \"parameter\",\n\t\t.description = \"parameter whose value can be overridden.\",\n\t\t.enabled = false,\n\t\t.dataType = FIELDTYPE_BOOL,\n\t},\n};\n\n/*\n *\t PROTOTYPE DEFINITIONS\n */\n\nstatic bool isIdentifier (tokenInfo* token);\nstatic int processDefine (tokenInfo *const token, int c);\nstatic int processType (tokenInfo* token, int c, verilogKind* kind, bool* with);\nstatic int pushEnumNames (tokenInfo* token, int c);\nstatic int pushMembers (tokenInfo* token, int c);\nstatic int readWordToken (tokenInfo *const token, int c);\nstatic int readWordTokenNoSkip (tokenInfo *const token, int c);\nstatic int skipBlockName (tokenInfo *const token, int c);\nstatic int skipClockEvent (tokenInfo* token, int c);\nstatic int skipDelay (tokenInfo* token, int c);\nstatic int tagIdsInPort (tokenInfo *const token, int c, verilogKind kind, bool mayPortDecl);\nstatic int tagIdsInDataDecl (tokenInfo* token, int c, verilogKind kind);\n\n/*\n *\t FUNCTION DEFINITIONS\n */\n\nstatic short isContainer (verilogKind kind)\n{\n\tswitch (kind)\n\t{\n\t\tcase K_MODULE:\n\t\tcase K_TASK:\n\t\tcase K_FUNCTION:\n\t\tcase K_BLOCK:\n\t\tcase K_CHECKER:\n\t\tcase K_CLASS:\n\t\tcase K_CLOCKING:\n\t\tcase K_COVERGROUP:\n\t\tcase K_IFCLASS:\n\t\tcase K_INTERFACE:\n\t\tcase K_PACKAGE:\n\t\tcase K_PROGRAM:\n\t\tcase K_PROPERTY:\n\t\tcase K_SEQUENCE:\n\t\tcase K_TYPEDEF:\n\t\tcase K_NETTYPE:\n\t\tcase K_ENUM:\n\t\tcase K_STRUCT:\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nstatic short isTempContext (tokenInfo const* token)\n{\n\tswitch (token->kind)\n\t{\n\t\tcase K_TYPEDEF:\n\t\tcase K_NETTYPE:\n\t\tcase K_ENUM:\n\t\tcase K_STRUCT:\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nstatic void clearToken (tokenInfo *token)\n{\n\ttoken->kind = K_UNDEFINED;\t// to be set by updateKind()\n\tvStringClear (token->name);\n\ttoken->lineNumber = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\ttoken->scope = NULL;\n\ttoken->nestLevel = 0;\n\ttoken->lastKind = K_UNDEFINED;\n\tvStringClear (token->blockName);\n\tvStringClear (token->inheritance);\n\ttoken->prototype = false;\n\ttoken->classScope = false;\n\ttoken->parameter = false;\n\ttoken->hasParamList = false;\n\ttoken->virtual = false;\n}\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\ttoken->name = vStringNew ();\n\ttoken->blockName = vStringNew ();\n\ttoken->inheritance = vStringNew ();\n\tclearToken (token);\n\treturn token;\n}\n\nstatic tokenInfo *dupToken (tokenInfo *token)\n{\n\ttokenInfo *dup = newToken ();\n\ttokenInfo tmp = *dup;\t// save vStrings, name, blockName, and inheritance\n\t*dup = *token;\n\t// revert vStrings allocated for dup\n\tdup->name = tmp.name;\n\tdup->blockName = tmp.blockName;\n\tdup->inheritance = tmp.inheritance;\n\t// copy contents of vStrings\n\tvStringCopy (dup->name, token->name);\n\tvStringCopy (dup->blockName, token->blockName);\n\tvStringCopy (dup->inheritance, token->inheritance);\n\treturn dup;\n}\n\nstatic void deleteToken (tokenInfo * const token)\n{\n\tif (token != NULL)\n\t{\n\t\tvStringDelete (token->name);\n\t\tvStringDelete (token->blockName);\n\t\tvStringDelete (token->inheritance);\n\t\teFree (token);\n\t}\n}\n\nstatic tokenInfo *pushToken (tokenInfo * const token, tokenInfo * const tokenPush)\n{\n\ttokenPush->scope = token;\n\treturn tokenPush;\n}\n\nstatic tokenInfo *popToken (tokenInfo * const token)\n{\n\ttokenInfo *localToken;\n\tif (token != NULL)\n\t{\n\t\tlocalToken = token->scope;\n\t\tdeleteToken (token);\n\t\treturn localToken;\n\t}\n\treturn NULL;\n}\n\nstatic void pruneTokens (tokenInfo * token)\n{\n\twhile ((token = popToken (token)))\n\t\t;\n}\n\nstatic void swapToken (tokenInfo *t0, tokenInfo *t1)\n{\n\ttokenInfo tmp = *t0;\n\t*t0 = *t1;\n\t*t1 = tmp;\n}\n\nstatic const char *getNameForKind (const verilogKind kind)\n{\n\tif (isInputLanguage (Lang_systemverilog))\n\t\treturn (SystemVerilogKinds[kind]).name;\n\telse /* isInputLanguage (Lang_verilog) */\n\t\treturn (VerilogKinds[kind]).name;\n}\n\nstatic char kindEnabled (const verilogKind kind)\n{\n\tif (isInputLanguage (Lang_systemverilog))\n\t\treturn SystemVerilogKinds[kind].enabled;\n\telse /* isInputLanguage (Lang_verilog) */\n\t\treturn VerilogKinds[kind].enabled;\n}\n\nstatic void buildKeywordHash (const langType language, unsigned int idx)\n{\n\tsize_t i;\n\tconst size_t count = ARRAY_SIZE (KeywordTable);\n\tfor (i = 0; i < count; ++i)\n\t{\n\t\tconst keywordAssoc *p = &KeywordTable [i];\n\t\tif (p->isValid [idx])\n\t\t\taddKeyword (p->keyword, language, (int) p->kind);\n\t}\n}\n\nstatic void initializeVerilog (const langType language)\n{\n\tLang_verilog = language;\n\tbuildKeywordHash (language, IDX_VERILOG);\n\taddKeywordGroup (&verilogKeywords, language);\n\taddKeywordGroup (&verilogDirectives, language);\n\tif (tagContents == NULL)\n\t\ttagContents = ptrArrayNew ((ptrArrayDeleteFunc)deleteToken);\n\n}\n\nstatic void initializeSystemVerilog (const langType language)\n{\n\tLang_systemverilog = language;\n\tbuildKeywordHash (language, IDX_SYSTEMVERILOG);\n\taddKeywordGroup (&systemVerilogKeywords, language);\n\taddKeywordGroup (&systemVerilogDirectives, language);\n\tif (tagContents == NULL)\n\t\ttagContents = ptrArrayNew ((ptrArrayDeleteFunc)deleteToken);\n}\n\nstatic void vUngetc (int c)\n{\n\tAssert (Ungetc == '\\0');\n\tUngetc = c;\n}\n\n/* Mostly copied from cppSkipOverCComment() in cpreprocessor.c.\n *\n * cppSkipOverCComment() uses the internal ungetc buffer of\n * CPreProcessor. On the other hand, the Verilog parser uses\n * getcFromInputFile() directly. getcFromInputFile() uses just\n * another internal ungetc buffer. Using them mixed way will\n * cause a trouble. */\nstatic int verilogSkipOverCComment (void)\n{\n\tint c = getcFromInputFile ();\n\n\twhile (c != EOF)\n\t{\n\t\tif (c != '*')\n\t\t\tc = getcFromInputFile ();\n\t\telse\n\t\t{\n\t\t\tconst int next = getcFromInputFile ();\n\n\t\t\tif (next != '/')\n\t\t\t\tc = next;\n\t\t\telse\n\t\t\t{\n\t\t\t\tc = ' ';\t/* replace comment with space */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn c;\n}\n\nstatic int _vGetc (bool inSkipPastMatch)\n{\n\tint c;\n\tif (Ungetc == '\\0')\n\t\tc = getcFromInputFile ();\n\telse\n\t{\n\t\tc = Ungetc;\n\t\tUngetc = '\\0';\n\t}\n\tif (c == '/')\n\t{\n\t\tint c2 = getcFromInputFile ();\n\t\tif (c2 == EOF)\n\t\t\treturn EOF;\n\t\telse if (c2 == '/')\t/* strip comment until end-of-line */\n\t\t{\n\t\t\tdo\n\t\t\t\tc = getcFromInputFile ();\n\t\t\twhile (c != '\\n' && c != EOF);\n\t\t}\n\t\telse if (c2 == '*')\t/* strip block comment */\n\t\t\tc = verilogSkipOverCComment ();\n\t\telse\n\t\t\tungetcToInputFile (c2);\n\t}\n\t// replace a string with \"@\" only in skipPastMatch()\n\t// because the string may contain parens, etc.\n\telse if (inSkipPastMatch && c == '\"')\n\t{\n\t\tint c2;\n\t\tdo\n\t\t\tc2 = getcFromInputFile ();\n\t\twhile (c2 != '\"' && c2 != EOF);\n\t\tc = '@';\n\t}\n\treturn c;\n}\n\nstatic int vGetc (void)\n{\n\treturn _vGetc (false);\n}\n\n// Is the first character in an identifier? [a-zA-Z_`\\\\]\nstatic bool isWordToken (const int c)\n{\n\treturn (isalpha (c) || c == '_' || c == '`' || c == '\\\\');\n}\n\n// Is a charactor in an identifier? [a-zA-Z0-9_`$]\nstatic bool isIdentifierCharacter (const int c)\n{\n\treturn (isalnum (c) || c == '_' || c == '`' || c == '$');\n}\n\n// check if double colon.\nstatic bool isDoubleColon (int c)\n{\n\tif (c != ':')\n\t\treturn false;\n\tc = vGetc ();\n\tif (c == ':') {\n\t\treturn true;\n\t} else {\n\t\tvUngetc (c);\n\t\treturn false;\n\t}\n}\n\nstatic int skipWhite (int c)\n{\n\twhile (isspace (c))\n\t\tc = vGetc ();\n\treturn c;\n}\n\nstatic int skipPastMatch (const char *const pair)\n{\n\tconst int begin = pair [0], end = pair [1];\n\tint matchLevel = 1;\n\tint c;\n\tdo\n\t{\n\t\tc = _vGetc (true);\n\t\tif (c == begin)\n\t\t\t++matchLevel;\n\t\telse if (c == end)\n\t\t\t--matchLevel;\n\t}\n\twhile (matchLevel > 0 && c != EOF);\n\treturn skipWhite (vGetc ());\n}\n\nstatic int skipDimension (int c)\n{\n\twhile (c == '[' && c != EOF)\n\t\tc = skipPastMatch (\"[]\");\n\treturn c;\n}\n\nstatic int skipToSemiColon (int c)\n{\n\twhile (c != ';' && c != EOF)\n\t\tc = vGetc ();\n\treturn c;\t// ';' or EOF\n}\n\nstatic bool isEscapedCharacter (int c)\n{\n\tif (c != '\\\\')\n\t\treturn false;\n\tc = vGetc ();\n\tif (c == '\"')\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nstatic int skipString (int c)\n{\n\tif (c == '\"')\n\t{\n\t\tdo\n\t\t\tc = vGetc ();\n\t\twhile (isEscapedCharacter(c) || (c != '\"' && c != EOF));\n\t}\n\tc = skipWhite (vGetc ());\n\treturn c;\n}\n\nstatic int skipExpression (int c)\n{\n\twhile (c != ',' && c != ';' && c != ')' && c != '}' && c != ']' && c != EOF)\n\t{\n\t\tif (c == '(')\n\t\t\tc = skipPastMatch (\"()\");\n\t\telse if (c == '{')\n\t\t\tc = skipPastMatch (\"{}\");\n\t\telse if (c == '[')\n\t\t\tc = skipPastMatch (\"[]\");\n\t\telse if (c == '\"')\n\t\t\tc = skipString (c);\n\t\telse\n\t\t\tc = skipWhite (vGetc ());\n\t}\n\treturn c;\n}\n\n// Skip to newline. The newline preceded by a backslash ( \\ ) is ignored.\n// Should be used after readWordTokenNoSkip() for compiler directives\nstatic int skipToNewLine (int c)\n{\n\tint prev = EOF; // The previous char of 'c' never be a EOF.\n\twhile (!((prev != '\\\\') && (c == '\\n')) && (c != EOF)) {\n\t\tprev = c;\n\t\t// Getc() does not work for a comment in multi-line macro\n\t\tc = getcFromInputFile ();\n\t}\n\tAssert(c == '\\n' || c == EOF);\n\treturn c;\n}\n\nstatic int skipMacro (int c, tokenInfo *token)\n{\n\ttokenInfo *localToken = newToken ();\t// don't update token outside\n\twhile (c == '`')\t// to support back-to-back compiler directives\n\t{\n\t\tc = readWordTokenNoSkip (localToken, c);\n\t\t/* Skip compiler directive other than `define */\n\t\tif (localToken->kind == K_DIRECTIVE)\n\t\t{\n\t\t\tc = skipToNewLine (c);\n\t\t\tc = skipWhite (c);\n\t\t}\n\t\t/* Skip `define */\n\t\telse if (localToken->kind == K_DEFINE)\n\t\t{\n\t\t\tc = skipWhite (c);\n\t\t\tc = processDefine (localToken, c);\n\t\t}\n\t\t/* return macro expansion */\n\t\telse if (localToken->kind == K_IDENTIFIER)\n\t\t{\n\t\t\tswapToken (token, localToken);\n\t\t\tc = skipWhite (c);\n\t\t\tif (c == '(')\n\t\t\t\tc = skipPastMatch (\"()\");\n\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tVERBOSE (\"Unexpected input: localToken->kind %d\\n\", localToken->kind);\n\t\t\tbreak;\n\t\t}\n\t}\n\tdeleteToken (localToken);\n\treturn c;\n}\n\nstatic void _updateKind (tokenInfo *const token)\n{\n\tverilogKind kind = (verilogKind) lookupKeyword (vStringValue (token->name), getInputLanguage () );\n\ttoken->kind = ((kind == K_UNDEFINED) && isIdentifier (token)) ? K_IDENTIFIER : kind;\n}\n\n/* read an identifier, keyword, number, compiler directive, or macro identifier */\nstatic int _readWordToken (tokenInfo *const token, int c, bool skip)\n{\n\tAssert (isWordToken (c));\n\n\tclearToken (token);\n\tif (c == '\\\\')\n\t{\n\t\t// Escaped identifier (may be empty)\n\t\tc = vGetc (); // skip leading '\\'\n\t\twhile (isgraph (c))\n\t\t{\n\t\t\tvStringPut (token->name, c);\n\t\t\tc = vGetc ();\n\t\t}\n\t\ttoken->kind = K_IDENTIFIER;\n\t}\n\telse\n\t{\n\t\tdo\n\t\t{\n\t\t\tvStringPut (token->name, c);\n\t\t\tc = vGetc ();\n\t\t} while (isIdentifierCharacter (c));\n\t\t_updateKind (token);\n\t}\n\n\tif (skip)\n\t\treturn skipWhite (c);\n\telse\n\t\treturn c;\n}\n\n// read a word token starting with \"c\".\n// returns the first charactor of the next token.\nstatic int readWordToken (tokenInfo *const token, int c)\n{\n\treturn _readWordToken (token, c, true);\n}\n\n// read a word token starting with \"c\".\n// returns the next charactor of the token read.\n// For compiler directives which are line-based, skipWhite() cannot be used.\nstatic int readWordTokenNoSkip (tokenInfo *const token, int c)\n{\n\treturn _readWordToken (token, c, false);\n}\n\n/* check if an identifier:\n *\t simple_identifier ::= [ a-zA-Z_ ] { [ a-zA-Z0-9_$ ] } */\nstatic bool isIdentifier (tokenInfo* token)\n{\n\tif (token->kind == K_UNDEFINED)\n\t{\n\t\tfor (int i = 0; i < vStringLength (token->name); i++)\n\t\t{\n\t\t\tint c = (unsigned char) vStringChar (token->name, i);\n\t\t\tif (i == 0)\n\t\t\t{\n\t\t\t\t// treat a text-macro as an identifier (#3712)\n\t\t\t\tif (!isWordToken (c))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!isIdentifierCharacter (c))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\telse\n\t\treturn false;\n}\n\nstatic void createContext (verilogKind kind, vString* const name)\n{\n\ttokenInfo *const scope = newToken ();\n\tvStringCopy (scope->name, name);\n\tscope->kind = kind;\n\n\tif (scope)\n\t{\n\t\tvString *contextName = vStringNew ();\n\n\t\t/* Determine full context name */\n\t\tif (currentContext->kind != K_UNDEFINED)\n\t\t{\n\t\t\tvStringCopy (contextName, currentContext->name);\n\t\t\tvStringPut (contextName, '.');\n\t\t}\n\t\tvStringCat (contextName, scope->name);\n\t\t/* Create context */\n\t\tcurrentContext = pushToken (currentContext, scope);\n\t\tvStringCopy (currentContext->name, contextName);\n\t\tvStringDelete (contextName);\n\t\tverbose (\"Created new context %s (kind %d)\\n\", vStringValue (currentContext->name), currentContext->kind);\n\t}\n}\n\nstatic void dropContext (void)\n{\n\tverbose (\"Dropping context %s\\n\", vStringValue (currentContext->name));\n\tcurrentContext = popToken (currentContext);\n}\n\n/* Drop context, but only if an end token is found */\nstatic int dropEndContext (tokenInfo *const token, int c)\n{\n\tverbose (\"current context %s; context kind %0d; nest level %0d\\n\", vStringValue (currentContext->name), currentContext->kind, currentContext->nestLevel);\n\tif ((currentContext->kind == K_COVERGROUP && strcmp (vStringValue (token->name), \"endgroup\") == 0)\n\t\t|| (currentContext->kind == K_IFCLASS && strcmp (vStringValue (token->name), \"endclass\") == 0))\n\t{\n\t\tdropContext ();\n\t\tc = skipBlockName (token ,c);\n\t}\n\telse if (currentContext->kind != K_UNDEFINED)\n\t{\n\t\tvString *endTokenName = vStringNewInit (\"end\");\n\t\tvStringCatS (endTokenName, getNameForKind (currentContext->kind));\n\t\tif (strcmp (vStringValue (token->name), vStringValue (endTokenName)) == 0)\n\t\t{\n\t\t\tdropContext ();\n\t\t\tc = skipBlockName (token ,c);\n\t\t\twhile (currentContext->classScope)\n\t\t\t{\n\t\t\t\tverbose (\"Dropping local context %s\\n\", vStringValue (currentContext->name));\n\t\t\t\tcurrentContext = popToken (currentContext);\n\t\t\t}\n\t\t\tcurrentContext->virtual = false;\n\t\t}\n\t\tvStringDelete (endTokenName);\n\t}\n\telse\n\t\tVERBOSE (\"Unexpected current context %s\\n\", vStringValue (currentContext->name));\n\treturn c;\n}\n\n\nstatic void createTagFull (tokenInfo *const token, verilogKind kind, int role, tokenInfo *const typeref)\n{\n\ttagEntryInfo tag;\n\n\tif (kind == K_LOCALPARAM)\n\t\tkind = K_CONSTANT;\n\telse if (kind == K_PARAMETER)\n\t{\n\t\tkind = K_CONSTANT;\n\t\t// See LRM 2017 6.20.1 Parameter declaration syntax\n\t\tif (currentContext->kind != K_CLASS && currentContext->kind != K_PACKAGE && !currentContext->hasParamList)\n\t\t\ttoken->parameter = true;\n\t}\n\tAssert (kind >= 0 && kind != K_UNDEFINED && kind != K_IDENTIFIER);\n\n\t/* check if a container before kind is modified by prototype */\n\t/* BTW should we create a context for a prototype? */\n\tbool container = isContainer (kind);\n\n\t/* Determine if kind is prototype */\n\tif (currentContext->prototype)\n\t\tkind = K_PROTOTYPE;\n\n\t/* Do nothing if tag kind is disabled */\n\tif (! kindEnabled (kind))\n\t{\n\t\tverbose (\"kind disabled\\n\");\n\t\treturn;\n\t}\n\n\t/* Create tag */\n\tif (role == ROLE_DEFINITION_INDEX)\n\t\tinitTagEntry (&tag, vStringValue (token->name), kind);\n\telse\n\t\tinitRefTagEntry (&tag, vStringValue (token->name), kind, role);\n\tupdateTagLine (&tag, token->lineNumber, token->filePosition);\n\n\tverbose (\"Adding tag %s (kind %d)\", vStringValue (token->name), kind);\n\tif (currentContext->kind != K_UNDEFINED\n\t\t&& kind != K_DEFINE)\t// a define macro should not be scoped. #4127\n\t{\n\t\tverbose (\" to context %s\\n\", vStringValue (currentContext->name));\n\t\tcurrentContext->lastKind = kind;\n\t\ttag.extensionFields.scopeKindIndex = currentContext->kind;\n\t\ttag.extensionFields.scopeName = vStringValue (currentContext->name);\n\t}\n\tverbose (\"\\n\");\n\tif (vStringLength (token->inheritance) > 0)\n\t{\n\t\ttag.extensionFields.inheritance = vStringValue (token->inheritance);\n\t\tverbose (\"Class %s extends %s\\n\", vStringValue (token->name), tag.extensionFields.inheritance);\n\t}\n\n\tif (typeref)\n\t{\n\t\ttag.extensionFields.typeRef [0] = getNameForKind (typeref->kind);\n\t\ttag.extensionFields.typeRef [1] = vStringValue (typeref->name);\n\t}\n\n\tif (token->parameter)\n\t\tattachParserField (&tag, fieldTable [F_PARAMETER].ftype, \"\");\n\n\tmakeTagEntry (&tag);\n\n\tif (isXtagEnabled (XTAG_QUALIFIED_TAGS) && currentContext->kind != K_UNDEFINED\n\t\t&& role == ROLE_DEFINITION_INDEX)\n\t{\n\t\tvString *const scopedName = vStringNew ();\n\n\t\tvStringCopy (scopedName, currentContext->name);\n\t\tvStringPut (scopedName, '.');\n\t\tvStringCat (scopedName, token->name);\n\t\ttag.name = vStringValue (scopedName);\n\n\t\tmarkTagExtraBit (&tag, XTAG_QUALIFIED_TAGS);\n\t\tmakeTagEntry (&tag);\n\n\t\tvStringDelete (scopedName);\n\t}\n\n\t/* Push token as context if it is a container */\n\tif (container && role == ROLE_DEFINITION_INDEX)\n\t{\n\t\tcreateContext (kind, token->name);\n\n\t\t/* Put found contents in context */\n\t\tverbose (\"Putting tagContents: %d element(s)\\n\",\n\t\t\t\t ptrArrayCount (tagContents));\n\t\tfor (unsigned int i = 0; i < ptrArrayCount (tagContents); i++)\n\t\t{\n\t\t\ttokenInfo *content = ptrArrayItem (tagContents, i);\n\t\t\tcreateTagFull (content, content->kind, ROLE_DEFINITION_INDEX, NULL);\n\t\t}\n\n\t\t/* Drop temporary contexts */\n\t\tif (isTempContext (currentContext))\n\t\t\tdropContext ();\n\t}\n\n\t/* Clear no longer required inheritance information */\n\tvStringClear (token->inheritance);\n}\n\nstatic void createTagWithTypeRef (tokenInfo *const token, verilogKind kind, tokenInfo *const typeref)\n{\n\tcreateTagFull (token, kind, ROLE_DEFINITION_INDEX, typeref);\n}\n\nstatic void createTag (tokenInfo *const token, verilogKind kind)\n{\n\tcreateTagWithTypeRef (token, kind, NULL);\n}\n\nstatic void createRefTag (tokenInfo *const token, verilogKind kind, int role)\n{\n\tcreateTagFull (token, kind, role, NULL);\n}\n\nstatic int skipBlockName (tokenInfo *const token, int c)\n{\n\tif (c == ':')\n\t{\n\t\tc = skipWhite (vGetc ());\n\t\tif (isWordToken (c))\n\t\t\tc = readWordToken (token, c);\n\t}\n\treturn c;\n}\n\n// begin, fork\nstatic int processBlock (tokenInfo *const token, int c)\n{\n\tif (c == ':')\t// tag an optional block identifier\n\t{\n\t\tc = skipWhite (vGetc ());\n\t\tif (isWordToken (c))\n\t\t{\n\t\t\tc = readWordToken (token, c);\n\t\t\tverbose (\"Found block: %s\\n\", vStringValue (token->name));\n\t\t\tcreateTag (token, K_BLOCK);\n\t\t\tverbose (\"Current context %s\\n\", vStringValue (currentContext->name));\n\t\t}\n\t}\n\tcurrentContext->nestLevel++;\t// increment after creating a context\n\treturn c;\n}\n\n// end, join, join_any, join_none\nstatic int processEnd (tokenInfo *const token, int c)\n{\n\tif (currentContext->nestLevel > 0)\t// for sanity check\n\t\tcurrentContext->nestLevel--;\n\tif (currentContext->kind == K_BLOCK && currentContext->nestLevel == 0)\n\t\tdropContext ();\n\n\tc = skipBlockName (token, c);\n\treturn c;\n}\n\nstatic int processPortList (tokenInfo *token, int c, bool mayPortDecl)\n{\n\tif (c == '(')\n\t{\n\t\tc = skipWhite (vGetc ());\t// skip '('\n\t\tc = tagIdsInPort (token, c, K_PORT, mayPortDecl);\n\t\tif (c == ')')\t// sanity check\n\t\t\tc = skipWhite (vGetc ());\n\t\telse\n\t\t\tVERBOSE (\"Unexpected input: %c\\n\", c);\n\t}\n\treturn c;\n}\n\nstatic int skipParameterAssignment (int c)\n{\n\tif (c == '#')\n\t{\n\t\tc = skipWhite (vGetc ());\n\t\tif (c == '(')\n\t\t\tc = skipPastMatch (\"()\");\n\t}\n\treturn c;\n}\n\n// Using LRM Annex A Formal syntax, The declaration of function and task can be combined\n// to describe as follows (always ignore parameter_value_assignment in the class_scope):\n// --------------------------------------------------------------------------------------------------\n//                                    |  class_scope  |               |  class_scope  |\n// [ function | task ] [ lifetime ] [ { class_name :: } return_type ] { class_name :: } function_name\n//                                  |       return_type field       | |     function_name field     |\n// --------------------------------------------------------------------------------------------------\n// tokenNameSaved : Store All word tokens after the [ function | task ] keyword except those in `#()`\n//                  If there is [ dynamic_override_specifiers ] before [ lifetime ], will also be stored\n//                      dynamic_override_specifiers ::= [ : initial | : extends ] [ : final ]\n// doubleColonPos : Record the position of `::` inserted into tokenNameSaved Array\n// return the index of first class_name in tokenNameSaved Array (return -1 if not exist)\n// NOTE: return_type field is ignored, only the class_scope of function_name field is concerned\nstatic int getFirstClassNameIndex (const ptrArray *const tokenNameSaved, const intArray *const doubleColonPos)\n{\n\tconst int colonsCount = intArrayCount (doubleColonPos);\n\tif (colonsCount == 0 || intArrayLast (doubleColonPos) != (ptrArrayCount (tokenNameSaved) - 1))\n\t\treturn -1;\n\tint curColon = colonsCount - 1;\n\twhile (curColon > 0 && intArrayItem (doubleColonPos, curColon) - intArrayItem (doubleColonPos, curColon - 1) == 1)\n\t\tcurColon--;\n\treturn intArrayItem (doubleColonPos, curColon) - 1;\n}\n\n// Functions are treated differently because they may also include the type of the return value.\n// Tasks are treated in the same way, although not having a return value.\n//\n// function [ lifetime ] function_data_type_or_implicit [ interface_identifier . | class_scope ] function_identifier [ ( [ tf_port_list ] ) ] ;\n// task     [ lifetime ] task_body_declaration          [ interface_identifier . | class_scope ] task_identifier     [ ( [ tf_port_list ] ) ] ;\nstatic int processFunction (tokenInfo *const token, int c)\n{\n\tverilogKind kind = token->kind;\t// K_FUNCTION or K_TASK\n\tptrArray *tokenNameSaved = ptrArrayNew ((ptrArrayDeleteFunc)vStringDelete);\n\tintArray *doubleColonPos = intArrayNew ();\n\tint firstClassNameIndex;\t// class_scope of function name\n\n\t/* Search for function name\n\t * Last identifier found before a '(' or a ';' is the function name */\n\twhile (c != '(' && c != ';' && c != EOF)\n\t{\n\t\tif (isWordToken (c))\n\t\t{\n\t\t\tc = readWordToken (token, c);\n\t\t\tptrArrayAdd (tokenNameSaved, vStringNewCopy (token->name));\n\t\t}\n\t\telse\n\t\t\tc = skipWhite (vGetc ());\n\t\t/* skip parameter assignment of a class type\n\t\t *\tex. function uvm_port_base #(IF) get_if(int index=0); */\n\t\tc = skipParameterAssignment (c);\n\n\t\t/* Record the position where the class resolution `::` appears */\n\t\tif (isInputLanguage (Lang_systemverilog) && isDoubleColon (c))\n\t\t\tintArrayAdd (doubleColonPos, ptrArrayCount (tokenNameSaved));\n\t}\n\n\t/* If the function's class_scope is found, then create respective context */\n\tfirstClassNameIndex = getFirstClassNameIndex (tokenNameSaved, doubleColonPos);\n\tif (firstClassNameIndex >= 0)\n\t\tfor (int i = firstClassNameIndex; i < ptrArrayCount (tokenNameSaved) - 1; i++)\n\t\t{\n\t\t\tvString *className = ptrArrayItem (tokenNameSaved, i);\n\t\t\tverbose (\"Found function declaration with class type %s\\n\", vStringValue (className));\n\t\t\tcreateContext (K_CLASS, className);\n\t\t\tcurrentContext->classScope = true;\n\t\t}\n\n\tptrArrayDelete (tokenNameSaved);\n\tintArrayDelete (doubleColonPos);\n\n\tverbose (\"Found function: %s\\n\", vStringValue (token->name));\n\tcreateTag (token, kind);\n\n\t/* Get port list from function */\n\tc = skipWhite (c);\n\tc = processPortList (token, c, false);\n\treturn c;\n}\n\n// ( enum | union ) [ enum_base_type ] { < enum_name_declaration > }  { [ ... ] }\nstatic int processEnum (tokenInfo *const token, int c)\n{\n\ttokenInfo* enumToken = dupToken (token);\t// save enum token\n\n\t/* skip enum_base_type */\n\twhile (isWordToken (c))\n\t\tc = readWordToken (token, c);\n\tc = skipDimension (c);\n\n\t/* Search enum elements */\n\tc = pushEnumNames (token, c);\n\n\t/* Skip bus width definition */\n\tc = skipDimension (c);\n\n\t/* Following identifiers are tag names */\n\tverbose (\"Find enum tags. Token %s kind %d\\n\", vStringValue (enumToken->name), enumToken->kind);\n\tc = tagIdsInDataDecl (enumToken, c, enumToken->kind);\n\tdeleteToken (enumToken);\n\n\t// Clean up the tag content list at the end of the declaration to support multiple variables\n\t//\t enum { ... } foo, bar;\n\tptrArrayClear (tagContents);\n\treturn c;\n}\n\n// [ struct | union [ tagged ] ] [ packed [ signed | unsigned ] ] { struct_union_member { struct_union_member } } { [ ... ] }\nstatic int processStruct (tokenInfo *const token, int c)\n{\n\tverilogKind kind = token->kind;\t// K_STRUCT, K_TYPEDEF, or K_NETTYPE\n\n\t/* Skip packed, signed, and unsigned */\n\twhile (isWordToken (c))\n\t\tc = readWordToken (token, c);\n\n\t/* create a list of members */\n\tc = pushMembers (token, c);\n\n\t/* Skip packed_dimension */\n\tc = skipDimension (c);\n\n\t/* Following identifiers are tag names */\n\tverbose (\"Find struct|union tags. Token %s kind %d\\n\", vStringValue (token->name), token->kind);\n\tc = tagIdsInDataDecl (token, c, kind);\n\tptrArrayClear (tagContents);\n\treturn c;\n}\n\n// data_declaration ::=\n//\t     [ const ] [ var ] [ static | automatic ] data_type_or_implicit list_of_variable_decl_assignments ;\n//\t   | typedef data_type type_identifier { [ ... ] } ;\n//\t   | typedef interface_instance_identifier [ ... ] . type_identifier type_identifier ; // interface based typedef\n//\t   | typedef [ enum | struct | union | class | interface class ] type_identifier ;\n//\t   | import < package_import_item > ;\n//\t   | nettype data_type net_type_identifier [ with [ class_type :: | package_identifier :: | $unit :: ] tf_identifier ] ;\n//\t   | nettype [ class_type :: | package_identifier :: | $unit :: ] net_type_identifier net_type_identifier ;\nstatic int processTypedef (tokenInfo *const token, int c)\n{\n\tverilogKind kindSave = token->kind;\t// K_TYPEDEF or K_NETTYPE\n\tverilogKind kind = K_UNDEFINED;\n\tbool not_used;\n\tif (isWordToken (c))\n\t{\n\t\tc = readWordToken (token, c);\n\t\tkind = token->kind;\n\t}\n\t// forward typedef (LRM 6.18) is tagged as prototype\n\t//\t (I don't know why...)\n\tswitch (kind)\n\t{\n\t\tcase K_CLASS:\n\t\tcase K_INTERFACE:\n\t\t\tcurrentContext->prototype = true;\n\t\t\tbreak;\n\t\tcase K_ENUM:\n\t\tcase K_STRUCT:\n\t\t\tif (isWordToken (c))\n\t\t\t{\n\t\t\t\tc = readWordToken (token, c);\n\t\t\t\tif (token->kind == K_IDENTIFIER && c == ';')\n\t\t\t\t\tcurrentContext->prototype = true;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase K_IDENTIFIER:\n\t\t\t// interface based typedef\n\t\t\tc = skipDimension (c);\n\t\t\tif (c == '.')\n\t\t\t{\n\t\t\t\tc = skipWhite (vGetc ());\n\t\t\t\tif (isWordToken (c))\n\t\t\t\t\tc = readWordToken (token, c);\n\t\t\t}\n\t\t\tif (c == ';')\n\t\t\t\tcurrentContext->prototype = true;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t; // do nothing\n\t}\n\tc = processType (token, c, &kind, &not_used);\n\n\tcreateTag (token, kindSave);\n\n\tptrArrayClear (tagContents);\n\treturn c;\n}\n\nstatic int processParameterList (tokenInfo *token, int c)\n{\n\tbool parameter = true;\t// default \"parameter\"\n\n\tif (c != '#')\n\t\treturn c;\n\tc = skipWhite (vGetc ());\n\n\tif (c != '(')\n\t\treturn c;\n\tc = skipWhite (vGetc ());\n\n\twhile (c != ')' && c != EOF)\n\t{\n\t\tif (isWordToken (c))\n\t\t{\n\t\t\tc = readWordToken (token, c);\n\t\t\tverbose (\"Found parameter %s\\n\", vStringValue (token->name));\n\t\t\tif (token->kind == K_IDENTIFIER)\n\t\t\t{\n\t\t\t\tif (c == ',' || c == ')' || c == '=')\t// ignore user defined type\n\t\t\t\t{\n\t\t\t\t\ttokenInfo *param = dupToken (token);\n\t\t\t\t\tparam->kind = K_CONSTANT;\n\t\t\t\t\tparam->parameter = parameter;\n\t\t\t\t\tptrArrayAdd (tagContents, param);\n\t\t\t\t\tif (c == '=')\n\t\t\t\t\t\tc = skipExpression (vGetc ());\n\t\t\t\t\telse if (c == ',')\n\t\t\t\t\t\tc = skipWhite (vGetc ());\n\t\t\t\t\telse\t// ')'\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (token->kind == K_PARAMETER)\n\t\t\t\tparameter = true;\n\t\t\telse if (token->kind == K_LOCALPARAM)\n\t\t\t\tparameter = false;\n\t\t}\n\t\telse\n\t\t\tc = skipWhite (vGetc ());\n\t\t// unpacked array is not allowed for a parameter\n\t}\n\tc = skipWhite (vGetc ());\t// skip ')'\n\treturn c;\n}\n\n// LRM IEEE Std 1800-2017 and previous versions\n//  [ virtual ] class [ static | automatic ] class_identifier [ parameter_port_list ]\n// LRM IEEE Std 1800-2023 ( Fixed )\n//  [ virtual ] class [ : final ] class_identifier [ parameter_port_list ]\n//\t   [ extends class_type [ ( list_of_arguments ) ] ] [ implements < interface_class_type > ] ;\n// interface class class_identifier [ parameter_port_list ] [ extends < interface_class_type > ] ;\nstatic int processClass (tokenInfo *const token, int c, verilogKind kind)\n{\n\ttokenInfo *classToken;\n\n\tif (kind == K_CLASS && c == ':')\n\t\tc = skipWhite (vGetc ());\n\n\t/* Get identifiers */\n\twhile (isWordToken (c))\n\t{\n\t\tc = readWordToken (token, c);\n\t\t// skip static or automatic or final\n\t\tif (token->kind != K_IGNORE)\n\t\t\tbreak;\n\t}\n\n\tif (token->kind != K_IDENTIFIER)\n\t{\n\t\tVERBOSE (\"Unexpected input: class name is expected.\\n\");\n\t\treturn c;\n\t}\n\n\t/* save token */\n\tclassToken = dupToken (token);\n\n\t/* Find class parameters list */\n\tc = processParameterList (token, c);\n\n\t/* Search for inheritance information */\n\tif (isWordToken (c))\n\t{\n\t\tc = readWordToken (token, c);\n\t\tif (strcmp (vStringValue (token->name), \"extends\") == 0)\n\t\t{\n\t\t\tif (isWordToken (c))\n\t\t\t\tc = readWordToken (token, c);\n\t\t\tvStringCopy (classToken->inheritance, token->name);\n\t\t\tverbose (\"Inheritance %s\\n\", vStringValue (classToken->inheritance));\n\t\t}\n\t}\n\t// process implements: FIXME\n\n\tcreateTag (classToken, kind);\n\tdeleteToken (classToken);\n\tptrArrayClear (tagContents);\n\treturn c;\n}\n\n// constraint_declaration ::= [ static ] constraint constraint_identifier '{' { constraint_block_item } '}'\n// constraint_prototype ::= [ extern | pure ] [ static ] constraint constraint_identifier ;\nstatic int processConstraint (tokenInfo *const token, int c)\n{\n\tverilogKind kind;\n\tif (isWordToken (c))\n\t\tc = readWordToken (token, c);\n\tif (c == '{')\n\t{\n\t\tc = skipPastMatch (\"{}\");\n\t\tkind = K_CONSTRAINT;\n\t}\n\telse\n\t\tkind = K_PROTOTYPE;\n\tcreateTag (token, kind);\n\treturn c;\n}\n\nstatic int processDefine (tokenInfo *const token, int c)\n{\n\t/* Bug #961001: Verilog compiler directives are line-based. */\n\tif (isWordToken (c))\n\t{\n\t\tc = readWordTokenNoSkip (token, c);\n\t\tcreateTag (token, K_DEFINE);\n\t}\n\tc = skipToNewLine (c);\n\tc = skipWhite (c);\n\treturn c;\n}\n\n// immediate_assertion_statement ::=\n//\t   ( assert | asume | cover ) [ #0 | final ] '(' expression ')' block\n// concurrent_assertion_statement ::=\n//\t   ( assert | assume ) property ( property_spec ) action_block\n//\t | expect ( property_spec ) action_block  # ignore : processed as same as \"if\"\n//\t | cover property ( property_spec ) statement_or_null\n//\t | cover sequence ( [clocking_event ] [ disable iff ( expression_or_dist ) ] sequence_expr ) statement_or_null\n//\t | restrict property ( property_spec ) ;\nstatic int processAssertion (tokenInfo *const token, int c)\n{\n\tif (vStringLength (currentContext->blockName) > 0)\n\t{\n\t\tvStringCopy (token->name, currentContext->blockName);\n\t\tvStringClear (currentContext->blockName);\t// clear block name not to be reused\n\t\tcreateTag (token, K_ASSERTION);\n\t}\n\t// skip final | property | sequence\n\tif (isWordToken (c))\n\t\tc = readWordToken (token, c);\n\t// skip #0\n\tc = skipDelay (token, c);\n\t// skip ( ... )\n\tif (c == '(')\n\t\tc = skipPastMatch (\"()\");\n\treturn c;\n}\n\n// data_declaration ::=\n//\t ...\n//\t import < package_identifier :: identifier | package_identifier :: * > ;\n// dpi_import_export ::=\n//\t import ( \"DPI-C\" | \"DPI\" ) [ context | pure ] [ c_identifier = ] function data_type_or_void function_identifier [ ( [ tf_port_list ] ) ] ;\n// | import ( \"DPI-C\" | \"DPI\" ) [ context ]        [ c_identifier = ] task task_identifier [ ( [ tf_port_list ] ) ] ;\n// | export ( \"DPI-C\" | \"DPI\" ) [ c_identifier = ] function function_identifier ;\n// | export ( \"DPI-C\" | \"DPI\" ) [ c_identifier = ] task     task_identifier ;\nstatic int processImport (tokenInfo *const token, int c)\n{\n\tif (c == '\"') {\t// dpi_import: we don't care about export.\n\t\tcurrentContext->prototype = true;\n\t} else {\n\t\tc = skipToSemiColon (c);\n\t\tc = skipWhite (vGetc ());\t// skip semicolon\n\t}\n\treturn c;\n}\n\n// non-ANSI type\n// ( module | interface | program ) [ static | automatic ] identifier { package_import_declaration } [ parameter_port_list ] ( port { , port } ) ;\n// ANSI type\n// ( module | interface | program ) [ static | automatic ] identifier { package_import_declaration } [ parameter_port_list ] [ ( [ < { (* ... *) } ansi_port_declaration > ] ) ] ;\n//\n// interface class class_identifier [ parameter_port_list ] [ extends < interface_class_type > ] ;\nstatic int processDesignElementL (tokenInfo *const token, int c)\n{\n\tverilogKind kind = token->kind;\n\n\twhile (isWordToken (c))\n\t{\n\t\tc = readWordToken (token, c);\n\t\t// interface class\n\t\tif (token->kind == K_CLASS)\n\t\t\treturn processClass (token, c, K_IFCLASS);\n\t\t// skip static or automatic\n\t\telse if (token->kind != K_IGNORE)\n\t\t\tbreak;\n\t}\n\tif (token->kind == K_IDENTIFIER)\n\t\tcreateTag (token, kind);\t// identifier\n\n\t// skip package_import_declaration\n\twhile (isWordToken (c))\n\t{\n\t\tc = readWordToken (token, c);\n\t\tif (token->kind == K_IMPORT)\n\t\t{\n\t\t\tc = skipToSemiColon (c);\n\t\t\tc = skipWhite (vGetc ());\t// skip semicolon\n\t\t}\n\t\telse\n\t\t{\n\t\t\tVERBOSE (\"Unexpected input\\n\");\n\t\t\treturn c;\n\t\t}\n\t}\n\tif (c == '#')\t// parameter_port_list\n\t{\n\t\tc = processParameterList (token, c);\n\n\t\t/* Put found parameters in context */\n\t\tverbose (\"Putting parameters: %d element(s)\\n\",\n\t\t\t\tptrArrayCount (tagContents));\n\t\tfor (unsigned int i = 0; i < ptrArrayCount (tagContents); i++)\n\t\t{\n\t\t\ttokenInfo *content = ptrArrayItem (tagContents, i);\n\t\t\tcreateTag (content, K_CONSTANT);\n\t\t}\n\t\tptrArrayClear (tagContents);\n\t\t// disable parameter property on parameter declaration statement\n\t\tcurrentContext->hasParamList = true;\n\t}\n\t// Process ANSI/non-ANSI port list in main loop\n\tc = processPortList (token, c, true);\n\treturn c;\n}\n\n// ( checker | property | sequence ) identifier [ ( [ port_list ] ) ] ;\n// covergroup identifier [ ( [ port_list ] ) ] [ coverage_event ] ;\n//\t coverage_event ::= clocking_event | with function sample ( ... ) | @@( ... )\n// package identifier ;\n// modport < identifier ( < ports_declaration > ) > ;\n// [ default | global ] clocking [ identifier ] ( @ identifier | @ ( event_expression ) )\nstatic int processDesignElementS (tokenInfo *const token, int c)\n{\n\tverilogKind kind = token->kind;\n\n\tif (isWordToken (c))\n\t\tc = readWordToken (token, c);\n\telse\n\t\treturn c;\n\n\tcreateTag (token, kind);\t// identifier\n\n\t/* Get port list if required */\n\tif (c == '(')\t// port_list\n\t{\n\t\tif (kind == K_MODPORT)\n\t\t\tc = skipPastMatch (\"()\");\t// ignore port list\n\t\telse\n\t\t\tc = processPortList (token, c, false);\n\t}\n\t// skip clocking_event for clocking block or coverage_event for covergroup\n\t// \"with function sample ()\" is processed in the main loop\n\tif (c == '@')\n\t\tc = skipClockEvent (token, c);\n\treturn c;\n}\n\nstatic int skipDelay (tokenInfo* token, int c)\n{\n\tif (c == '#')\n\t{\n\t\tc = skipWhite (vGetc ());\n\t\tif (c == '(')\n\t\t\tc = skipPastMatch (\"()\");\n\t\telse if (c == '#')\n\t\t\t// a dirty hack for \"x ##delay1 y[*min:max];\"\n\t\t\tc = skipToSemiColon (vGetc ());\n\t\telse\t// time literals\n\t\t{\n\t\t\twhile (isIdentifierCharacter (c) || c == '.')\n\t\t\t\tc = vGetc ();\n\t\t\tc = skipWhite (c);\n\t\t}\n\t}\n\treturn c;\n}\n\nstatic int skipClockEvent (tokenInfo* token, int c)\n{\n\tif (c == '@')\n\t{\n\t\tc = skipWhite (vGetc ());\n\t\t// for @@ ( ... ) : coverage_event\n\t\tif (c == '@')\n\t\t\tc = skipWhite (vGetc ());\n\t\tif (c == '(')\n\t\t\tc = skipPastMatch (\"()\");\n\t\telse if (isWordToken (c))\n\t\t\tc = readWordToken (token, c);\n\t}\n\treturn c;\n}\n\nstatic int pushEnumNames (tokenInfo* token, int c)\n{\n\tif (c == '{')\n\t{\n\t\tc = skipWhite (vGetc ());\n\t\twhile (c != '}' && c != EOF)\n\t\t{\n\t\t\tc = skipMacro (c, token);\n\t\t\tif (!isWordToken (c))\n\t\t\t{\n\t\t\t\tVERBOSE (\"Unexpected input: %c\\n\", c);\n\t\t\t\treturn c;\n\t\t\t}\n\t\t\tc = readWordToken (token, c);\n\n\t\t\ttoken->kind = K_CONSTANT;\n\t\t\tptrArrayAdd (tagContents, dupToken (token));\n\t\t\tverbose (\"Pushed enum element \\\"%s\\\"\\n\", vStringValue (token->name));\n\n\t\t\t/* Skip element ranges */\n\t\t\t/* TODO Implement element ranges */\n\t\t\tc = skipDimension (c);\n\n\t\t\t/* Skip value assignments */\n\t\t\tif (c == '=')\n\t\t\t\tc = skipExpression (vGetc ());\n\n\t\t\tc = skipMacro (c, token);\n\t\t\t/* Skip comma */\n\t\t\tif (c == ',')\n\t\t\t\tc = skipWhite (vGetc ());\n\t\t}\n\t\tc = skipWhite (vGetc ());\t// skip '}'\n\t}\n\treturn c;\n}\n\n// create a list of struct/union members\nstatic int pushMembers (tokenInfo* token, int c)\n{\n\tif (c == '{')\n\t{\n\t\tc = skipWhite (vGetc ());\n\t\twhile (c != '}' && c != EOF)\n\t\t{\n\t\t\tverilogKind kind = K_UNDEFINED;\t// set kind of context for processType()\n\t\t\tbool not_used;\n\t\t\tc = skipMacro (c, token);\n\t\t\tif (c == '}')\n\t\t\t\tbreak;\t// end of struct/union\n\t\t\tif (!isWordToken (c))\n\t\t\t{\n\t\t\t\tVERBOSE (\"Unexpected input: %c\\n\", c);\n\t\t\t\treturn c;\n\t\t\t}\n\t\t\tc = readWordToken (token, c);\n\n\t\t\tc = processType (token, c, &kind, &not_used);\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\ttoken->kind = K_MEMBER;\n\t\t\t\tptrArrayAdd (tagContents, dupToken (token));\n\t\t\t\tverbose (\"Pushed struct/union member \\\"%s\\\"\\n\", vStringValue (token->name));\n\n\t\t\t\t/* Skip unpacked dimensions */\n\t\t\t\tc = skipDimension (c);\n\n\t\t\t\t/* Skip value assignments */\n\t\t\t\tif (c == '=')\n\t\t\t\t\tc = skipExpression (vGetc ());\n\n\t\t\t\tif (c != ',' || c == EOF)\n\t\t\t\t\tbreak;\t\t// should be ';'\n\n\t\t\t\tc = skipWhite (vGetc ());\t// skip ','\n\t\t\t\tif (isWordToken (c))\n\t\t\t\t\tc = readWordToken (token, c);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tVERBOSE (\"Unexpected input.\\n\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* Skip semicolon */\n\t\t\tif (c == ';')\n\t\t\t\tc = skipWhite (vGetc ());\n\t\t\t/* End of enum elements list */\n\t\t}\n\t\tc = skipWhite (vGetc ());\t// skip '}'\n\t}\n\treturn c;\n}\n\n// input\n//\t kind: kind of context\n// output\n//\t kind: kind of type\n//\t token: identifier token (unless K_IDENTIFIER nor K_UNDEFINED)\nstatic int processType (tokenInfo* token, int c, verilogKind* kind, bool* with)\n{\n\tverilogKind actualKind = K_UNDEFINED;\n\ttokenInfo *tokenSaved;\n\t*with = false;\n\tdo\n\t{\n\t\tc = skipDimension (c);\n\t\tc = skipDelay (token, c);\t// class parameter #(...)\n\t\tif (c == '{')\t// skip enum, struct, or union member\n\t\t{\n\t\t\tif (*kind == K_ENUM)\n\t\t\t\tc = pushEnumNames (token, c);\n\t\t\telse if (*kind == K_STRUCT)\n\t\t\t\tc = pushMembers (token, c);\n\t\t\telse\t// for a nested structure\n\t\t\t\tc = skipPastMatch (\"{}\");\n\t\t}\n\t\tc = skipDimension (c);\n\t\tc = skipMacro (c, token);\n\n\t\t// break on ',', ';', ')', '}', or other unexpected charactors\n\t\tif (!isWordToken (c))\n\t\t\tbreak;\n\n\t\ttokenSaved = dupToken (token);\n\t\tc = readWordToken (token, c);\n\t\t// break on \"with\"\n\t\tif (token->kind == K_WITH)\n\t\t{\n \t\t\tswapToken (token, tokenSaved);\n\t\t\tdeleteToken (tokenSaved);\n\t\t\t*with = true;\t// inform to caller\n\t\t\tbreak;\n\t\t}\n\t\tdeleteToken (tokenSaved);\n\n\t\t// fix kind of user defined type\n\t\tif (*kind == K_IDENTIFIER)\n\t\t{\n\t\t\tif (token->kind == K_NET)\n\t\t\t\tactualKind = K_NET;\n\t\t\telse if (token->kind == K_REGISTER)\n\t\t\t\tactualKind = K_REGISTER;\n\t\t\telse if (token->kind == K_PORT)\n\t\t\t\tactualKind = K_PORT;\n\t\t\telse if (token->kind == K_IDENTIFIER)\n\t\t\t{\t// identifier of a user defined type\n\t\t\t\t*kind = K_REGISTER;\t// FIXME: consider kind of the user defined type\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tVERBOSE (\"Unexpected input\\n\");\t// FIXME: x dist {}, with\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while (c != '`' && c != EOF);\t// break on compiler directive\n\n\t// skip unpacked dimension (or packed dimension after type-words)\n\tc = skipDimension (skipWhite (c));\n\n\tif (*kind == K_UNDEFINED && *kind != K_PORT)\n\t\t*kind = actualKind;\n\treturn c;\n}\n\n// class_type ::=\n//\t\t ps_class_identifier [ # ( ... ) ] { :: class_identifier [ # ( ... ) ] }\n// \"interface_identifier .\" is also handled\nstatic int skipClassType (tokenInfo* token, int c)\n{\n\twhile (c == '#' || c == ':' || c == '.')\n\t{\n\t\tif (c == '#')\n\t\t{\n\t\t\tc = skipWhite (vGetc ());\n\t\t\t// a dirty hack for \"x ##delay1 y[*min:max];\"\n\t\t\tif (c == '#')\n\t\t\t\treturn skipToSemiColon (vGetc ());\n\t\t\tc = skipPastMatch (\"()\");\n\t\t}\n\t\telse if (c == ':')\n\t\t{\n\t\t\tif (!isDoubleColon(c))\n\t\t\t{\n\t\t\t\tVERBOSE (\"Unexpected input.\\n\");\n\t\t\t\treturn c;\n\t\t\t}\n\t\t\tc = skipWhite (vGetc ());\n\t\t\tif (isWordToken (c))\n\t\t\t\tc = readWordToken (token, c);\n\t\t}\n\t\telse\t// c == '.' : interface_identifier .\n\t\t{\n\t\t\tc = skipWhite (vGetc ());\n\t\t\tif (isWordToken (c))\n\t\t\t\tc = readWordToken (token, c);\n\t\t}\n\t}\n\treturn c;\n}\n\n// Tag a list of identifiers in a port list\n// data_type :: =\n//\t ...\n//\t | virtual [ interface ] identifier [ # ( [ ... ] ) ]  [ . identifier ]\n//\t | [ class_type :: | identifier :: | $unit :: ] identifier { [ ... ] }\n//\t | [ identifier :: | $unit :: ] identifier [ # ( ... ) ] { :: identifier [ # ( ... ) ] }\n//\t | ...\n//\n//\t mayPortDecl: may be a ANSI port declaration.  true for module, interface, or program.\nstatic int tagIdsInPort (tokenInfo *const token, int c, verilogKind kind, bool mayPortDecl)\n{\n\tbool first_port = true;\n\tbool enableTag = true;\n\tverilogKind localKind;\n\tbool not_used;\n\n\twhile (c != ')' && c != EOF)\t// skip empty port, \"()\"\n\t{\n\t\t// skip attribute_instance: (* ... *)\n\t\tif (c == '(')\n\t\t\tc = skipPastMatch (\"()\");\n\n\t\t// skip port direction, \"virtual\", or \"interface\"\n\t\twhile (isWordToken (c))\n\t\t{\n\t\t\tc = readWordToken (token, c);\n\t\t\tif (token->kind == K_PORT || token->kind == K_IGNORE || token->kind == K_INTERFACE)\n\t\t\t\tmayPortDecl = false;\t// now never be a non-ANSI port\n\t\t\telse\n\t\t\t\tbreak;\n\t\t}\n\t\tif (token->kind == K_IDENTIFIER)\n\t\t\tc = skipClassType (token, c);\n\t\tc = skipMacro (c, token);\t// `ifdef, `else, `endif, etc. (between identifiers)\n\n\t\tif (isWordToken (c))\n\t\t{\n\t\t\tc = readWordToken (token, c);\n\t\t\tif (token->kind == K_IDENTIFIER)\n\t\t\t{\n\t\t\t\tmayPortDecl = false;\n\t\t\t\tc = skipClassType (token, c);\n\t\t\t}\n\t\t}\n\t\t// aoid tagging enum and struct items\n\t\tlocalKind = token->kind == K_ENUM || token->kind == K_STRUCT ? K_PORT : token->kind;\n\t\tc = processType (token, c, &localKind, &not_used);\n\n\t\t// LRM 23.2.2.3 Rules for determining port kind, data type, and direction\n\t\t// If the direction, port kind, and data type are all omitted for\n\t\t// the first port in the port list, ... non-ANSI style, ...\n\t\tif (mayPortDecl && first_port)\n\t\t{\n\t\t\tfirst_port = false;\n\t\t\tif (localKind == K_IDENTIFIER)\n\t\t\t\tenableTag = false;\t// don't tag for non-ANSI port\n\t\t}\n\t\tif (enableTag && token->kind == K_IDENTIFIER)\n\t\t\tcreateTag (token, kind);\n\n\t\tif (c == '=')\n\t\t\tc = skipExpression (vGetc ());\n\n\t\tc = skipMacro (c, token);\t// `ifdef, `else, `endif, etc. (before comma)\n\t\tif (c != ',' || c == EOF)\n\t\t\tbreak;\n\t\tc = skipWhite (vGetc ());\t// skip ','\n\t\tc = skipMacro (c, token);\t// `ifdef, `else, `endif, etc. (after comma)\n\t}\n\treturn c;\n}\n\n// Tag a list of identifiers in a data declaration\nstatic int tagIdsInDataDecl (tokenInfo* token, int c, verilogKind kind)\n{\n\tif (token->kind != K_NET)\n\t\tc = skipClassType (token, c);\n\tif (c == ';')\n\t\treturn c;\n\n\t// skip drive|charge strength or type_reference, dimensions, and delay for net\n\tif (c == '(')\n\t\tc = skipPastMatch (\"()\");\n\tc = skipDimension (c);\n\tif (c == '.')\n\t\treturn c;\t// foo[...].bar = ..;\n\tc = skipDelay (token, c);\t// ## (cycle delay)\n\n\ttokenInfo *tokenSaved = dupToken(token); // maybe a module_identifier\n\twhile (c != EOF)\n\t{\n\t\tbool with = false;\n\t\tc = processType (token, c, &kind, &with);\t// update token and kind\n\n\t\tif (c == '=' || c == ',' || c == ';' || c == ')' || c == '`' || with)\n\t\t{\n\t\t\t// ignore an empty token or procedual assignment: foo = bar;\n\t\t\tif (kind != K_UNDEFINED && kind != K_IDENTIFIER && token->kind != K_UNDEFINED)\n\t\t\t\tcreateTag (token, kind);\n\t\t\tif (c == '=')\n\t\t\t\tc = skipExpression (c);\n\t\t}\n\t\telse if (c == '(' || c == '[')\t// should be an instance\n\t\t{\n\t\t\tc = skipDimension (c); // name_of_instance {unpacked_dimension}\n\t\t\tc = skipPastMatch (\"()\"); // list_of_port_connections\n\n\t\t\t// if without the next \"if\" clause, get a instance named: `add_t from the following example\n\t\t\t// var `add_t(foo) = '0;\n\t\t\tif (c == ';' || c == ',')\n\t\t\t{\n\t\t\t\ttokenSaved->kind = K_MODULE;\t// for typeRef field\n\t\t\t\tverbose (\"find instance: %s with kind %s\\n\", vStringValue (token->name), getNameForKind (K_INSTANCE));\n\t\t\t\tcreateTagWithTypeRef (token, K_INSTANCE, tokenSaved);\n\t\t\t\tcreateRefTag (tokenSaved, K_MODULE, R_MODULE_DECL);\n\t\t\t}\n\t\t}\n\t\tc = skipMacro (c, token);\t// `ifdef, `else, `endif, etc. (before comma)\n\t\tif (c != ',' || c == EOF)\n\t\t\tbreak;\n\t\tc = skipWhite (vGetc ());\t// skip ','\n\t\tc = skipMacro (c, token);\t// `ifdef, `else, `endif, etc. (after comma)\n\t}\n\tdeleteToken (tokenSaved);\n\treturn c;\n}\n\nstatic int findTag (tokenInfo *const token, int c)\n{\n\tverbose (\"Checking token %s of kind %d\\n\", vStringValue (token->name), token->kind);\n\n\tswitch (token->kind)\n\t{\n\t\tcase K_CONSTANT:\n\t\tcase K_EVENT:\n\t\tcase K_LOCALPARAM:\n\t\tcase K_NET:\n\t\tcase K_PARAMETER:\n\t\tcase K_PORT:\n\t\tcase K_REGISTER:\n\t\t\tif (token->kind == K_PORT && currentContext->kind == K_CLOCKING)\n\t\t\t\tc = skipToSemiColon (c); // clocking items are not port definitions\n\t\t\telse\n\t\t\t\tc = tagIdsInDataDecl (token, c, token->kind);\n\t\t\tbreak;\n\t\tcase K_IDENTIFIER:\n\t\t\t{\n\t\t\t\tif (c == '[')\t// for a case label foo[x]:\n\t\t\t\t\tc = skipPastMatch (\"[]\");\n\n\t\t\t\tif (c == ':')\n\t\t\t\t\t; /* label */\n\t\t\t\telse if (c == ',' || c == '.' || c == '{')\t// \"foo, ...\", \"foo.bar,...\", or \"coverpoint foo { ... }\"\n\t\t\t\t\tc = skipWhite (vGetc ());\n\t\t\t\telse if (c == '(')\t// task, function, or method call\n\t\t\t\t\tc = skipPastMatch (\"()\");\n\t\t\t\telse if (c == '=')\t// assignment\n\t\t\t\t\tc = skipExpression (skipWhite (vGetc ()));\n\t\t\t\telse\n\t\t\t\t\tc = tagIdsInDataDecl (token, c, token->kind); /* user defined type */\n\t\t\t}\n\t\t\tbreak;\n\t\tcase K_CLASS:\n\t\t\tc = processClass (token, c, K_CLASS);\n\t\t\tbreak;\n\t\tcase K_TYPEDEF:\n\t\tcase K_NETTYPE:\n\t\t\tc = processTypedef (token, c);\n\t\t\tbreak;\n\t\tcase K_ENUM:\n\t\t\tc = processEnum (token, c);\n\t\t\tbreak;\n\t\tcase K_STRUCT:\n\t\t\tc = processStruct (token, c);\n\t\t\tbreak;\n\t\tcase K_IMPORT:\n\t\t\tc = processImport (token, c);\n\t\t\tbreak;\n\t\tcase K_PROTOTYPE:\n\t\tcase K_WITH:\n\t\t\tcurrentContext->prototype = true;\n\t\t\tbreak;\n\n\t\tcase K_INTERFACE:\n\t\t\t// a virtual interface variable\n\t\t\tif (currentContext->virtual)\n\t\t\t\tbreak;\n\t\t\t// fallthrough\n\t\tcase K_MODULE:\n\t\tcase K_PROGRAM:\n\t\t\tc = processDesignElementL (token, c);\n\t\t\tbreak;\n\t\tcase K_CHECKER:\n\t\tcase K_CLOCKING:\n\t\tcase K_COVERGROUP:\n\t\tcase K_MODPORT:\n\t\tcase K_PACKAGE:\n\t\tcase K_PROPERTY:\n\t\tcase K_SEQUENCE:\n\t\t\tc = processDesignElementS (token, c);\n\t\t\tbreak;\n\t\tcase K_END_DE:\n\t\t\tc = dropEndContext (token, c);\n\t\t\tbreak;\n\t\tcase K_BLOCK:\n\t\t\tc = processBlock (token, c);\n\t\t\tbreak;\n\t\tcase K_END:\n\t\t\tc = processEnd (token, c);\n\t\t\tbreak;\n\t\tcase K_FUNCTION:\n\t\tcase K_TASK:\n\t\t\tc = processFunction (token, c);\n\t\t\tbreak;\n\t\tcase K_ASSERTION:\n\t\t\tc = processAssertion (token, c);\n\t\t\tbreak;\n\t\tcase K_CONSTRAINT:\n\t\t\tc = processConstraint (token, c);\n\t\t\tbreak;\n\n\t\tcase K_DEFINE:\n\t\t\tc = processDefine (token, c);\n\t\t\tbreak;\n\n\t\tcase K_VIRTUAL:\n\t\t\tcurrentContext->virtual = true;\n\t\t\tbreak;\n\n\t\tcase K_IGNORE:\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tVERBOSE (\"Unexpected kind->token %d\\n\", token->kind);\n\t}\n\treturn c;\n}\n\nstatic void findVerilogTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\tint c = skipWhite (vGetc ());\n\tcurrentContext = newToken ();\n\tfieldTable = isInputLanguage (Lang_verilog) ? VerilogFields : SystemVerilogFields;\n\tptrArrayClear (tagContents);\n\n\twhile (c != EOF)\n\t{\n\t\tswitch (c)\n\t\t{\n\t\t\tcase ':':\n\t\t\t\t/* Store current block name whenever a : is found\n\t\t\t\t * This is used later by any tag type that requires this information */\n\t\t\t\tif (!isDoubleColon(c))\n\t\t\t\t\tvStringCopy (currentContext->blockName, token->name);\n\t\t\t\tc = skipWhite (vGetc ());\n\t\t\t\tbreak;\n\t\t\tcase ';':\n\t\t\t\t/* Drop context on prototypes because they don't have an\n\t\t\t\t * end statement */\n\t\t\t\tif (currentContext->scope && currentContext->scope->prototype)\n\t\t\t\t\tdropContext ();\n\n\t\t\t\t/* Prototypes end at the end of statement */\n\t\t\t\tcurrentContext->prototype = false;\n\t\t\t\tc = skipWhite (vGetc ());\n\t\t\t\tbreak;\n\t\t\tcase '(':\t// ignore locally declared variables in a for-loop (LRM 12.7.1)\n\t\t\t\tc = skipPastMatch (\"()\");\n\t\t\t\tbreak;\n\t\t\tcase '{':\n\t\t\t\tc = skipPastMatch (\"{}\");\n\t\t\t\tbreak;\n\t\t\tcase '#':\n\t\t\t\tc = skipDelay (token, c);\n\t\t\t\tbreak;\n\t\t\tcase '@':\n\t\t\t\tc = skipClockEvent (token, c);\n\t\t\t\tbreak;\n\t\t\tcase '\"':\n\t\t\t\tc = skipString (c);\n\t\t\t\tbreak;\n\t\t\tdefault :\n\t\t\t\tif (isWordToken (c))\n\t\t\t\t{\n\t\t\t\t\t// NoSkip for compiler directives\n\t\t\t\t\tc = readWordTokenNoSkip (token, c);\n\t\t\t\t\tif (token->kind == K_DIRECTIVE)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Skip compiler directives which are line-based.\n\t\t\t\t\t\tc = skipToNewLine (c);\n\t\t\t\t\t\tc = skipWhite (c);\n\t\t\t\t\t}\n\t\t\t\t\telse if ((token->kind == K_UNDEFINED)\n\t\t\t\t\t\t\t || (token->kind == K_IDENTIFIER && vStringChar(token->name, 0) == '`'))\n\t\t\t\t\t\t// ignore an undefined token and text-macro identifier, i.e.`foo(bar) (#3712)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\telse\n\t\t\t\t\t\t// call findTag() after skipping whitespaces\n\t\t\t\t\t\tc = findTag (token, skipWhite (c));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tc = skipWhite (vGetc ());\n\t\t}\n\t}\n\tdeleteToken (token);\n\tpruneTokens (currentContext);\n\tcurrentContext = NULL;\n}\n\nextern parserDefinition* VerilogParser (void)\n{\n\tstatic const char *const extensions [] = { \"v\", \"vh\", NULL };\n\tparserDefinition* def = parserNew (\"Verilog\");\n\tstatic selectLanguage selectors[] = { selectVOrVerilogByKeywords, NULL };\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\tdef->kindTable  = VerilogKinds;\n\tdef->kindCount  = ARRAY_SIZE (VerilogKinds);\n\tdef->fieldTable = VerilogFields;\n\tdef->fieldCount = ARRAY_SIZE (VerilogFields);\n\tdef->extensions = extensions;\n\tdef->parser     = findVerilogTags;\n\tdef->initialize = initializeVerilog;\n\tdef->selectLanguage  = selectors;\n\n\t/* See the comment in SystemVerilogParser. */\n\tdef->allowNullTag = true;\n\treturn def;\n}\n\nextern parserDefinition* SystemVerilogParser (void)\n{\n\tstatic const char *const extensions [] = { \"sv\", \"svh\", \"svi\", NULL };\n\tparserDefinition* def = parserNew (\"SystemVerilog\");\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\tdef->kindTable  = SystemVerilogKinds;\n\tdef->kindCount  = ARRAY_SIZE (SystemVerilogKinds);\n\tdef->fieldTable = SystemVerilogFields;\n\tdef->fieldCount = ARRAY_SIZE (SystemVerilogFields);\n\tdef->extensions = extensions;\n\tdef->parser     = findVerilogTags;\n\tdef->initialize = initializeSystemVerilog;\n\n\t/*\n\t * A.9.3 Identifiers in LRM\n\t * ------------------------\n\t * escaped_identifier ::= \\ {any_printable_ASCII_character_except_white_space} white_space\n\t * ...\n\t * identifier ::=\n\t * simple_identifier\n\t * | escaped_identifier\n\t * ...\n\t * simple_identifier ::= [ a-zA-Z_ ] { [ a-zA-Z0-9_$ ] }\n\t * ------------------------\n\t * All kinds are classified as identifiers, including text macros.\n\t * Let the parser allow to emit null tags for any kind of language\n\t * objects the parser extracts. See als #4257.\n\t */\n\tdef->allowNullTag = true;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/vhdl.c",
    "content": "/*\n*   Copyright (c) 2008, Nicolas Vincent\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for VHDL files.\n*\n*   References:\n*     https://rti.etf.bg.ac.rs/rti/ri5rvl/tutorial/TUTORIAL/IEEE/HTML/1076_TOC.HTM\n*     https://tams.informatik.uni-hamburg.de/vhdl/tools/grammar/vhdl93-bnf.html\n*     http://www.vhdl.renerta.com/mobile/index.html\n*     https://www.hdlworks.com/hdl_corner/vhdl_ref/\n*     https://www.ics.uci.edu/~jmoorkan/vhdlref/Synario%20VHDL%20Manual.pdf\n*     http://atlas.physics.arizona.edu/~kjohns/downloads/vhdl/VHDL-xilinx-help.pdf\n*     http://www.csit-sun.pub.ro/resources/xilinx/synvhdl.pdf\n*     https://edg.uchicago.edu/~tang/VHDLref.pdf\n*/\n\n/*\n *   INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n\n#include <ctype.h>\t/* to define isalpha () */\n#include <string.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"keyword.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n#include \"trace.h\"\n\n/*\n *   MACROS\n */\n#define isType(token,t)     (bool) ((token)->type == (t))\n#define isKeyword(token,k)  (bool) ((token)->keyword == (k))\n#define isIdentChar1(c) (isalpha (c) || (c) == '_')\n#define isIdentChar(c) (isalpha (c) || isdigit (c) || (c) == '_')\n\n/*\n *   DATA DECLARATIONS\n */\n\n/*\n * Used to specify type of keyword.\n */\nenum eKeywordId {\n\tKEYWORD_ABS,\n\tKEYWORD_ACCESS,\n\tKEYWORD_AFTER,\n\tKEYWORD_ALIAS,\n\tKEYWORD_ALL,\n\tKEYWORD_AND,\n\tKEYWORD_ARCHITECTURE,\n\tKEYWORD_ARRAY,\n\tKEYWORD_ASSERT,\n\tKEYWORD_ATTRIBUTE,\n\tKEYWORD_BEGIN,\n\tKEYWORD_BLOCK,\n\tKEYWORD_BODY,\n\tKEYWORD_BUFFER,\n\tKEYWORD_BUS,\n\tKEYWORD_CASE,\n\tKEYWORD_COMPONENT,\n\tKEYWORD_CONFIGURATION,\n\tKEYWORD_CONSTANT,\n\tKEYWORD_DISCONNECT,\n\tKEYWORD_DOWNTO,\n\tKEYWORD_ELSE,\n\tKEYWORD_ELSIF,\n\tKEYWORD_END,\n\tKEYWORD_ENTITY,\n\tKEYWORD_EXIT,\n\tKEYWORD_FILE,\n\tKEYWORD_FOR,\n\tKEYWORD_FUNCTION,\n\tKEYWORD_GENERATE,\n\tKEYWORD_GENERIC,\n\tKEYWORD_GROUP,\n\tKEYWORD_GUARDED,\n\tKEYWORD_IF,\n\tKEYWORD_IMPURE,\n\tKEYWORD_IN,\n\tKEYWORD_INERTIAL,\n\tKEYWORD_INOUT,\n\tKEYWORD_IS,\n\tKEYWORD_LABEL,\n\tKEYWORD_LIBRARY,\n\tKEYWORD_LINKAGE,\n\tKEYWORD_LITERAL,\n\tKEYWORD_LOOP,\n\tKEYWORD_MAP,\n\tKEYWORD_MOD,\n\tKEYWORD_NAND,\n\tKEYWORD_NEW,\n\tKEYWORD_NEXT,\n\tKEYWORD_NOR,\n\tKEYWORD_NOT,\n\tKEYWORD_NULL,\n\tKEYWORD_OF,\n\tKEYWORD_ON,\n\tKEYWORD_OPEN,\n\tKEYWORD_OR,\n\tKEYWORD_OTHERS,\n\tKEYWORD_OUT,\n\tKEYWORD_PACKAGE,\n\tKEYWORD_PORT,\n\tKEYWORD_POSTPONED,\n\tKEYWORD_PROCEDURE,\n\tKEYWORD_PROCESS,\n\tKEYWORD_PURE,\n\tKEYWORD_RANGE,\n\tKEYWORD_RECORD,\n\tKEYWORD_REGISTER,\n\tKEYWORD_REJECT,\n\tKEYWORD_RETURN,\n\tKEYWORD_ROL,\n\tKEYWORD_ROR,\n\tKEYWORD_SELECT,\n\tKEYWORD_SEVERITY,\n\tKEYWORD_SIGNAL,\n\tKEYWORD_SHARED,\n\tKEYWORD_SLA,\n\tKEYWORD_SLI,\n\tKEYWORD_SRA,\n\tKEYWORD_SRL,\n\tKEYWORD_SUBTYPE,\n\tKEYWORD_THEN,\n\tKEYWORD_TO,\n\tKEYWORD_TRANSPORT,\n\tKEYWORD_TYPE,\n\tKEYWORD_UNAFFECTED,\n\tKEYWORD_UNITS,\n\tKEYWORD_UNTIL,\n\tKEYWORD_USE,\n\tKEYWORD_VARIABLE,\n\tKEYWORD_WAIT,\n\tKEYWORD_WHEN,\n\tKEYWORD_WHILE,\n\tKEYWORD_WITH,\n\tKEYWORD_XNOR,\n\tKEYWORD_XOR\n};\ntypedef int keywordId; /* to allow KEYWORD_NONE */\n\ntypedef enum eTokenType {\n\tTOKEN_NONE,\t\t/* none */\n\tTOKEN_EOF,\t\t/* end-of-file */\n\tTOKEN_OPEN_PAREN,\t/* ( */\n\tTOKEN_CLOSE_PAREN,\t/* ) */\n\tTOKEN_COMMA,\t\t/* the comma character */\n\tTOKEN_IDENTIFIER,\n\tTOKEN_KEYWORD,\n\tTOKEN_PERIOD,\t\t/* . */\n\tTOKEN_OPERATOR,\n\tTOKEN_SEMICOLON,\t/* the semicolon character */\n\tTOKEN_COLON,\t\t/* : */\n\tTOKEN_STRING\n} tokenType;\n\ntypedef struct sTokenInfo {\n\ttokenType type;\n\tkeywordId keyword;\n\tvString *string;\t\t/* the name of the token */\n\tunsigned long lineNumber;\t/* line number of tag */\n\tMIOPos filePosition;\t\t/* file position of line containing name */\n} tokenInfo;\n\n/*\n *   DATA DEFINITIONS\n */\nstatic int Lang_vhdl;\n\ntypedef enum {\n\tVHDL_ENTITY_DESIGNED,\n} vhdlEntityRole;\n\nstatic roleDefinition VhdlEntityRoles [] = {\n\t{ true, \"desigend\",\n\t  \"designed by an architecture\" },\n};\n\n/* Used to index into the VhdlKinds table. */\ntypedef enum {\n\tVHDLTAG_UNDEFINED = -1,\n\tVHDLTAG_CONSTANT,\n\tVHDLTAG_TYPE,\n\tVHDLTAG_SUBTYPE,\n\tVHDLTAG_RECORD,\n\tVHDLTAG_ENTITY,\n\tVHDLTAG_COMPONENT,\n\tVHDLTAG_PROTOTYPE,\n\tVHDLTAG_FUNCTION,\n\tVHDLTAG_PROCEDURE,\n\tVHDLTAG_PACKAGE,\n\tVHDLTAG_LOCAL,\n\tVHDLTAG_ARCHITECTURE,\n\tVHDLTAG_PORT,\n\tVHDLTAG_GENERIC,\n\tVHDLTAG_SIGNAL,\n\tVHDLTAG_PROCESS,\n\tVHDLTAG_VARIABLE,\n\tVHDLTAG_ALIAS,\n} vhdlKind;\n\nstatic kindDefinition VhdlKinds[] = {\n\t{true, 'c', \"constant\", \"constant declarations\"},\n\t{true, 't', \"type\", \"type definitions\"},\n\t{true, 'T', \"subtype\", \"subtype definitions\"},\n\t{true, 'r', \"record\", \"record names\"},\n\t{true, 'e', \"entity\", \"entity declarations\",\n\t .referenceOnly = false, ATTACH_ROLES(VhdlEntityRoles)},\n\t{false, 'C', \"component\", \"component declarations\"},\n\t{false, 'd', \"prototype\", \"prototypes\"},\n\t{true, 'f', \"function\", \"function prototypes and declarations\"},\n\t{true, 'p', \"procedure\", \"procedure prototypes and declarations\"},\n\t{true, 'P', \"package\", \"package definitions\"},\n\t{false, 'l', \"local\", \"local definitions\"},\n\t{true, 'a', \"architecture\", \"architectures\"},\n\t{true, 'q', \"port\", \"port declarations\"},\n\t{true, 'g', \"generic\", \"generic declarations\"},\n\t{true , 's', \"signal\", \"signal declarations\"},\n\t{true, 'Q',  \"process\", \"processes\"},\n\t{true, 'v',  \"variable\", \"variables\"},\n\t{true, 'A',  \"alias\", \"aliases\"},\n};\n\nstatic const keywordTable VhdlKeywordTable[] = {\n\t{\"abs\", KEYWORD_ABS},\n\t{\"access\", KEYWORD_ACCESS},\n\t{\"after\", KEYWORD_AFTER},\n\t{\"alias\", KEYWORD_ALIAS},\n\t{\"all\", KEYWORD_ALL},\n\t{\"and\", KEYWORD_AND},\n\t{\"architecture\", KEYWORD_ARCHITECTURE},\n\t{\"array\", KEYWORD_ARRAY},\n\t{\"assert\", KEYWORD_ASSERT},\n\t{\"attribute\", KEYWORD_ATTRIBUTE},\n\t{\"begin\", KEYWORD_BEGIN},\n\t{\"block\", KEYWORD_BLOCK},\n\t{\"body\", KEYWORD_BODY},\n\t{\"buffer\", KEYWORD_BUFFER},\n\t{\"bus\", KEYWORD_BUS},\n\t{\"case\", KEYWORD_CASE},\n\t{\"component\", KEYWORD_COMPONENT},\n\t{\"configuration\", KEYWORD_CONFIGURATION},\n\t{\"constant\", KEYWORD_CONSTANT},\n\t{\"disconnect\", KEYWORD_DISCONNECT},\n\t{\"downto\", KEYWORD_DOWNTO},\n\t{\"else\", KEYWORD_ELSE},\n\t{\"elsif\", KEYWORD_ELSIF},\n\t{\"end\", KEYWORD_END},\n\t{\"entity\", KEYWORD_ENTITY},\n\t{\"exit\", KEYWORD_EXIT},\n\t{\"file\", KEYWORD_FILE},\n\t{\"for\", KEYWORD_FOR},\n\t{\"function\", KEYWORD_FUNCTION},\n\t{\"generate\", KEYWORD_GENERATE},\n\t{\"generic\", KEYWORD_GENERIC},\n\t{\"group\", KEYWORD_GROUP},\n\t{\"guarded\", KEYWORD_GUARDED},\n\t{\"if\", KEYWORD_IF},\n\t{\"impure\", KEYWORD_IMPURE},\n\t{\"in\", KEYWORD_IN},\n\t{\"inertial\", KEYWORD_INERTIAL},\n\t{\"inout\", KEYWORD_INOUT},\n\t{\"is\", KEYWORD_IS},\n\t{\"label\", KEYWORD_LABEL},\n\t{\"library\", KEYWORD_LIBRARY},\n\t{\"linkage\", KEYWORD_LINKAGE},\n\t{\"literal\", KEYWORD_LITERAL},\n\t{\"loop\", KEYWORD_LOOP},\n\t{\"map\", KEYWORD_MAP},\n\t{\"mod\", KEYWORD_MOD},\n\t{\"nand\", KEYWORD_NAND},\n\t{\"new\", KEYWORD_NEW},\n\t{\"next\", KEYWORD_NEXT},\n\t{\"nor\", KEYWORD_NOR},\n\t{\"not\", KEYWORD_NOT},\n\t{\"null\", KEYWORD_NULL},\n\t{\"of\", KEYWORD_OF},\n\t{\"on\", KEYWORD_ON},\n\t{\"open\", KEYWORD_OPEN},\n\t{\"or\", KEYWORD_OR},\n\t{\"others\", KEYWORD_OTHERS},\n\t{\"out\", KEYWORD_OUT},\n\t{\"package\", KEYWORD_PACKAGE},\n\t{\"port\", KEYWORD_PORT},\n\t{\"postponed\", KEYWORD_POSTPONED},\n\t{\"procedure\", KEYWORD_PROCEDURE},\n\t{\"process\", KEYWORD_PROCESS},\n\t{\"pure\", KEYWORD_PURE},\n\t{\"range\", KEYWORD_RANGE},\n\t{\"record\", KEYWORD_RECORD},\n\t{\"register\", KEYWORD_REGISTER},\n\t{\"reject\", KEYWORD_REJECT},\n\t{\"return\", KEYWORD_RETURN},\n\t{\"rol\", KEYWORD_ROL},\n\t{\"ror\", KEYWORD_ROR},\n\t{\"select\", KEYWORD_SELECT},\n\t{\"severity\", KEYWORD_SEVERITY},\n\t{\"signal\", KEYWORD_SIGNAL},\n\t{\"shared\", KEYWORD_SHARED},\n\t{\"sla\", KEYWORD_SLA},\n\t{\"sli\", KEYWORD_SLI},\n\t{\"sra\", KEYWORD_SRA},\n\t{\"srl\", KEYWORD_SRL},\n\t{\"subtype\", KEYWORD_SUBTYPE},\n\t{\"then\", KEYWORD_THEN},\n\t{\"to\", KEYWORD_TO},\n\t{\"transport\", KEYWORD_TRANSPORT},\n\t{\"type\", KEYWORD_TYPE},\n\t{\"unaffected\", KEYWORD_UNAFFECTED},\n\t{\"units\", KEYWORD_UNITS},\n\t{\"until\", KEYWORD_UNTIL},\n\t{\"use\", KEYWORD_USE},\n\t{\"variable\", KEYWORD_VARIABLE},\n\t{\"wait\", KEYWORD_WAIT},\n\t{\"when\", KEYWORD_WHEN},\n\t{\"while\", KEYWORD_WHILE},\n\t{\"with\", KEYWORD_WITH},\n\t{\"xnor\", KEYWORD_XNOR},\n\t{\"xor\", KEYWORD_XOR}\n};\n\ntypedef enum {\n\tF_ARCHITECTURE,\n} vhdlField;\n\nstatic fieldDefinition VhdlFields [] = {\n\t{ .name = \"architecture\",\n\t  .description = \"architecture designing the entity\",\n\t  .enabled = true },\n};\n\n/*\n *   FUNCTION DECLARATIONS\n */\nstatic void parseKeywords (tokenInfo * const token, tokenInfo * const label, int parent);\n\n/*\n *   FUNCTION DEFINITIONS\n */\nstatic bool isIdentifierMatch (const tokenInfo * const token,\n\tconst char *name)\n{\n\treturn (bool) (isType (token, TOKEN_IDENTIFIER) &&\n\t\tstrncasecmp (vStringValue (token->string), name,\n\t\t\t\t\t vStringLength (token->string)) == 0);\n}\n\nstatic bool isSemicolonOrKeywordOrIdent (const tokenInfo * const token,\n\tconst keywordId keyword, const char *name)\n{\n\treturn (bool) (isType (token, TOKEN_SEMICOLON)\n\t\t\t\t   || isKeyword (token, keyword)\n\t\t\t\t   || isIdentifierMatch (token, name));\n}\n\nstatic tokenInfo *newToken (void)\n{\n\ttokenInfo *const token = xMalloc (1, tokenInfo);\n\ttoken->type = TOKEN_NONE;\n\ttoken->keyword = KEYWORD_NONE;\n\ttoken->string = vStringNew ();\n\ttoken->lineNumber = getInputLineNumber ();\n\ttoken->filePosition = getInputFilePosition ();\n\treturn token;\n}\n\nstatic tokenInfo *copyToken (tokenInfo * const src)\n{\n\ttokenInfo *dst = newToken ();\n\tvStringCopy (dst->string, src->string);\n\treturn dst;\n}\n\nstatic void deleteToken (tokenInfo * const token)\n{\n\tif (token != NULL)\n\t{\n\t\tvStringDelete (token->string);\n\t\teFree (token);\n\t}\n}\n\n/*\n *   Parsing functions\n */\n\nstatic void parseString (vString * const string, const int delimiter)\n{\n\tbool end = false;\n\twhile (!end)\n\t{\n\t\tint c = getcFromInputFile ();\n\t\tif (c == EOF)\n\t\t\tend = true;\n\t\telse if (c == '\\\\')\n\t\t{\n\t\t\tc = getcFromInputFile ();\t/* This maybe a ' or \". */\n\t\t\tvStringPut (string, c);\n\t\t}\n\t\telse if (c == delimiter)\n\t\t\tend = true;\n\t\telse\n\t\t\tvStringPut (string, c);\n\t}\n}\n\n/*  Read a VHDL identifier beginning with \"firstChar\" and place it into \"name\".\n*/\nstatic void parseIdentifier (vString * const string, const int firstChar)\n{\n\tint c = firstChar;\n\tAssert (isIdentChar1 (c));\n\tdo\n\t{\n\t\tvStringPut (string, c);\n\t\tc = getcFromInputFile ();\n\t} while (isIdentChar (c));\n\tif (!isspace (c))\n\t\tungetcToInputFile (c);\t/* unget non-identifier character */\n}\n\nstatic void readToken (tokenInfo * const token)\n{\n\tint c;\n\n\ttoken->type = TOKEN_NONE;\n\ttoken->keyword = KEYWORD_NONE;\n\tvStringClear (token->string);\n\n  getNextChar:\n\tdo\n\t{\n\t\tc = getcFromInputFile ();\n\t\ttoken->lineNumber = getInputLineNumber ();\n\t\ttoken->filePosition = getInputFilePosition ();\n\t}\n\twhile (c == '\\t' || c == ' ' || c == '\\n');\n\n\tswitch (c)\n\t{\n\tcase EOF:\n\t\ttoken->type = TOKEN_EOF;\n\t\tbreak;\n\tcase '(':\n\t\ttoken->type = TOKEN_OPEN_PAREN;\n\t\tbreak;\n\tcase ')':\n\t\ttoken->type = TOKEN_CLOSE_PAREN;\n\t\tbreak;\n\tcase ';':\n\t\ttoken->type = TOKEN_SEMICOLON;\n\t\tbreak;\n\tcase ':':\n\t\ttoken->type = TOKEN_COLON;\n\t\tbreak;\n\tcase '.':\n\t\ttoken->type = TOKEN_PERIOD;\n\t\tbreak;\n\tcase ',':\n\t\ttoken->type = TOKEN_COMMA;\n\t\tbreak;\n\tcase '\\'':\t/* only single char are inside simple quotes */\n\t\tbreak;\t/* or it is for attributes so we don't care */\n\tcase '\"':\n\t\ttoken->type = TOKEN_STRING;\n\t\tparseString (token->string, c);\n\t\ttoken->lineNumber = getInputLineNumber ();\n\t\ttoken->filePosition = getInputFilePosition ();\n\t\tbreak;\n\tcase '-':\n\t\tc = getcFromInputFile ();\n\t\tif (c == '-')\t/* start of a comment */\n\t\t{\n\t\t\tskipToCharacterInInputFile ('\\n');\n\t\t\tgoto getNextChar;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (!isspace (c))\n\t\t\t\tungetcToInputFile (c);\n\t\t\ttoken->type = TOKEN_OPERATOR;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tif (!isIdentChar1 (c))\n\t\t\ttoken->type = TOKEN_NONE;\n\t\telse\n\t\t{\n\t\t\tparseIdentifier (token->string, c);\n\t\t\ttoken->lineNumber = getInputLineNumber ();\n\t\t\ttoken->filePosition = getInputFilePosition ();\n\t\t\ttoken->keyword = lookupCaseKeyword (vStringValue (token->string), Lang_vhdl);\n\t\t\tif (isKeyword (token, KEYWORD_NONE))\n\t\t\t\ttoken->type = TOKEN_IDENTIFIER;\n\t\t\telse\n\t\t\t\ttoken->type = TOKEN_KEYWORD;\n\t\t}\n\t\tbreak;\n\t}\n}\n\nstatic bool skipToKeyword (const keywordId keyword)\n{\n\ttokenInfo *const token = newToken ();\n\tdo\n\t{\n\t\treadToken (token);\n\t}\n\twhile (!isType (token, TOKEN_EOF) && !isKeyword (token, keyword));\n\n\tbool r = isKeyword (token, keyword);\n\tdeleteToken (token);\n\treturn r;\n}\n\nstatic void skipToMatched (tokenInfo * const token)\n{\n\tint nest_level = 0;\n\ttokenType open_token;\n\ttokenType close_token;\n\n\tswitch (token->type)\n\t{\n\tcase TOKEN_OPEN_PAREN:\n\t\topen_token = TOKEN_OPEN_PAREN;\n\t\tclose_token = TOKEN_CLOSE_PAREN;\n\t\tbreak;\n\tdefault:\n\t\treturn;\n\t}\n\n\t/*\n\t * This routine will skip to a matching closing token.\n\t * It will also handle nested tokens like the (, ) below.\n\t *   (  name varchar(30), text binary(10)  )\n\t */\n\tif (isType (token, open_token))\n\t{\n\t\tnest_level++;\n\t\twhile (!(isType (token, close_token) && (nest_level == 0)) && !isType (token, TOKEN_EOF))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, open_token))\n\t\t\t{\n\t\t\t\tnest_level++;\n\t\t\t}\n\t\t\tif (isType (token, close_token))\n\t\t\t{\n\t\t\t\tif (nest_level > 0)\n\t\t\t\t{\n\t\t\t\t\tnest_level--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treadToken (token);\n\t}\n}\n\nstatic int makeVhdlTagWithScope (tokenInfo * const token, const vhdlKind kind, int parent)\n{\n\tconst char *const name = vStringValue (token->string);\n\ttagEntryInfo e;\n\tinitTagEntry (&e, name, kind);\n\tupdateTagLine (&e, token->lineNumber, token->filePosition);\n\te.extensionFields.scopeIndex = parent;\n\treturn makeTagEntry (&e);\n}\n\nstatic int makeVhdlTag (tokenInfo * const token, const vhdlKind kind)\n{\n\treturn makeVhdlTagWithScope (token, kind, CORK_NIL);\n}\n\nstatic void initialize (const langType language)\n{\n\tLang_vhdl = language;\n}\n\nstatic void parseTillEnd (tokenInfo * const token, int parent, const int end_keyword)\n{\n\tbool ended = false;\n\ttagEntryInfo *e = getEntryInCorkQueue (parent);\n\t/* If e is NULL, the input may be broken as VHDL code\n\t * or unsupported syntax in this parser. */\n\n\tdo\n\t{\n\t\treadToken (token);\n\t\tif (isKeyword (token, KEYWORD_END))\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (e)\n\t\t\t\tended = isSemicolonOrKeywordOrIdent (token,\n\t\t\t\t\t\t\t\t\t\t\t\t\t end_keyword, e->name);\n\t\t\tif (!isType (token, TOKEN_SEMICOLON))\n\t\t\t\tskipToCharacterInInputFile (';');\n\t\t\tif (ended)\n\t\t\t\tsetTagEndLine (e, getInputLineNumber ());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (isType (token, TOKEN_EOF))\n\t\t\t{\n\t\t\t\tended = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tparseKeywords (token, NULL, parent);\n\t\t\t}\n\t\t}\n\t} while (!ended);\n}\n\nstatic void parseTillBegin (tokenInfo * const token, int parent)\n{\n\tbool begun = false;\n\tdo\n\t{\n\t\treadToken (token);\n\t\tif (isKeyword (token, KEYWORD_BEGIN)\n\t\t\t|| isType (token, TOKEN_EOF))\n\t\t\tbegun = true;\n\t\telse\n\t\t\tparseKeywords (token, NULL, parent);\n\t} while (!begun);\n}\n\nstatic void parsePackage (tokenInfo * const token)\n{\n\ttokenInfo *const name = newToken ();\n\ttokenInfo *token_for_tagging = NULL;\n\tAssert (isKeyword (token, KEYWORD_PACKAGE));\n\treadToken (token);\n\tif (isKeyword (token, KEYWORD_BODY))\n\t{\n\t\treadToken (name);\n\t\ttoken_for_tagging = name;\n\t}\n\telse if (isType (token, TOKEN_IDENTIFIER))\n\t\ttoken_for_tagging = token;\n\n\tif (token_for_tagging)\n\t{\n\t\tint index = makeVhdlTag (token_for_tagging, VHDLTAG_PACKAGE);\n\t\tparseTillEnd (token, index, KEYWORD_PACKAGE);\n\t}\n\n\tdeleteToken (name);\n}\n\n\nstatic void parseDeclElement (tokenInfo * const token,\n\t\t\t\t\t\t\t  vhdlKind kind, int parent,\n\t\t\t\t\t\t\t  bool ended_with_semicolon)\n{\n\tTRACE_ENTER ();\n\twhile (! (isType (token, TOKEN_EOF)\n\t\t\t  || isType (token, TOKEN_CLOSE_PAREN)\n\t\t\t  || (ended_with_semicolon && isType (token, TOKEN_SEMICOLON))))\n\t{\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\tmakeVhdlTagWithScope (token, kind, parent);\n\t\t\treadToken (token);\n\t\t}\n\t\telse if (isType (token, TOKEN_COMMA))\n\t\t\treadToken (token);\n\t\telse if (isType (token, TOKEN_COLON))\n\t\t{\n\t\t\tdo\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tskipToMatched (token);\n\t\t\t\tif (isType (token, TOKEN_CLOSE_PAREN)\n\t\t\t\t\t|| isType (token, TOKEN_SEMICOLON))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\twhile (!isType (token, TOKEN_EOF));\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Unexpected */\n\t\t\treadToken (token);\n\t\t}\n\t}\n\tTRACE_LEAVE ();\n}\n\nstatic void parseModuleDecl (tokenInfo * const token, int parent)\n{\n\tTRACE_ENTER ();\n\twhile (! (isKeyword (token, KEYWORD_END)\n\t\t\t  || isType (token, TOKEN_EOF)))\n\t{\n\t\tvhdlKind kind = VHDLTAG_UNDEFINED;\n\t\tif (isKeyword (token, KEYWORD_PORT))\n\t\t\tkind = VHDLTAG_PORT;\n\t\telse if (isKeyword (token, KEYWORD_GENERIC))\n\t\t\tkind = VHDLTAG_GENERIC;\n\n\t\tif (kind != VHDLTAG_UNDEFINED)\n\t\t{\n\t\t\treadToken (token);\n\t\t\tif (isType (token, TOKEN_OPEN_PAREN))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t\tparseDeclElement (token, kind, parent, false);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\treadToken (token);\n\t}\n\tTRACE_LEAVE ();\n}\n\nstatic void parseModule (tokenInfo * const token, int parent)\n{\n\ttokenInfo *const name = newToken ();\n\tconst vhdlKind kind = isKeyword (token, KEYWORD_ENTITY) ?\n\t\tVHDLTAG_ENTITY : VHDLTAG_COMPONENT;\n\tAssert (isKeyword (token, KEYWORD_ENTITY) ||\n\t\tisKeyword (token, KEYWORD_COMPONENT));\n\treadToken (name);\n\treadToken (token);\n\tif (kind == VHDLTAG_COMPONENT || isKeyword (token, KEYWORD_IS))\n\t{\n\t\tint index = makeVhdlTagWithScope (name, kind, parent);\n\t\tif (isKeyword (token, KEYWORD_IS))\n\t\t\treadToken (token);\n\t\tparseModuleDecl (token, index);\n\n\t\tbool ended = isKeyword (token, KEYWORD_END);\n\t\tif (!ended)\n\t\t\tended = skipToKeyword (KEYWORD_END);\n\t\tskipToCharacterInInputFile (';');\n\n\t\tif (ended)\n\t\t{\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine (e, getInputLineNumber ());\n\t\t}\n\n\t\tif (kind == VHDLTAG_ENTITY)\n\t\t\tregisterEntry (index);\n\t}\n\tdeleteToken (name);\n}\n\nstatic void parseRecord (tokenInfo * const token, int parent)\n{\n\ttokenInfo *const name = newToken ();\n\tAssert (isKeyword (token, KEYWORD_RECORD));\n\treadToken (name);\n\tdo\n\t{\n\t\treadToken (token);\t/* should be a colon */\n\t\tskipToCharacterInInputFile (';');\n\t\tmakeVhdlTagWithScope (name, VHDLTAG_RECORD, parent);\n\t\treadToken (name);\n\t}\n\twhile (!isKeyword (name, KEYWORD_END) && !isType (name, TOKEN_EOF));\n\tskipToCharacterInInputFile (';');\n\n\tif (isKeyword (name, KEYWORD_END))\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (parent);\n\t\tif (e)\n\t\t\tsetTagEndLine (e, getInputLineNumber ());\n\t}\n\n\tdeleteToken (name);\n}\n\nstatic void parseTypes (tokenInfo * const token, int parent)\n{\n\ttokenInfo *const name = newToken ();\n\tconst vhdlKind kind = isKeyword (token, KEYWORD_TYPE) ?\n\t\tVHDLTAG_TYPE : VHDLTAG_SUBTYPE;\n\tAssert (isKeyword (token, KEYWORD_TYPE) ||\n\t\tisKeyword (token, KEYWORD_SUBTYPE));\n\treadToken (name);\n\treadToken (token);\n\tif (isKeyword (token, KEYWORD_IS))\n\t{\n\t\treadToken (token);\t/* type */\n\t\tif (isKeyword (token, KEYWORD_RECORD))\n\t\t{\n\t\t\tint index = makeVhdlTagWithScope (name, kind, parent);\n\t\t\t/*TODO: make tags of the record's names */\n\t\t\tparseRecord (token, index);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmakeVhdlTagWithScope (name, kind, parent);\n\t\t}\n\t}\n\tdeleteToken (name);\n}\n\nstatic void parseConstant (int parent)\n{\n\tvhdlKind parent_kind = VHDLTAG_UNDEFINED;\n\ttagEntryInfo *e = getEntryInCorkQueue (parent);\n\tif (e)\n\t\tparent_kind = e->kindIndex;\n\n\tvhdlKind kind;\n\tswitch (parent_kind)\n\t{\n\tcase VHDLTAG_FUNCTION:\n\tcase VHDLTAG_PROCEDURE:\n\t\tkind = VHDLTAG_LOCAL;\n\t\tbreak;\n\tdefault:\n\t\tkind = VHDLTAG_CONSTANT;\n\t\tbreak;\n\t}\n\n\ttokenInfo *const name = newToken ();\n\treadToken (name);\n\tmakeVhdlTagWithScope (name, kind, parent);\n\tskipToCharacterInInputFile (';');\n\tdeleteToken (name);\n}\n\nstatic void parseSubProgram (tokenInfo * const token, int parent)\n{\n\ttokenInfo *const name = newToken ();\n\tconst vhdlKind kind = isKeyword (token, KEYWORD_FUNCTION) ?\n\t\tVHDLTAG_FUNCTION : VHDLTAG_PROCEDURE;\n\tconst int end_keyword = token->keyword;\n\tAssert (isKeyword (token, KEYWORD_FUNCTION) ||\n\t\tisKeyword (token, KEYWORD_PROCEDURE));\n\treadToken (name);\t/* the name of the function or procedure */\n\treadToken (token);\n\tif (isType (token, TOKEN_OPEN_PAREN))\n\t{\n\t\tskipToMatched (token);\n\t}\n\n\tif (kind == VHDLTAG_FUNCTION)\n\t{\n\t\tif (isKeyword (token, KEYWORD_RETURN))\n\t\t{\n\t\t\t/* Read datatype */\n\t\t\treadToken (token);\n\t\t\twhile (! isKeyword (token, KEYWORD_IS) &&\n\t\t\t\t\t! isType (token, TOKEN_SEMICOLON) &&\n\t\t\t\t\t! isType (token, TOKEN_EOF))\n\t\t\t{\n\t\t\t\treadToken (token);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (isType (token, TOKEN_SEMICOLON))\n\t{\n\t\tmakeVhdlTagWithScope (name, VHDLTAG_PROTOTYPE, parent);\n\t}\n\telse if (isKeyword (token, KEYWORD_IS))\n\t{\n\t\tint index = makeVhdlTagWithScope (name, kind, parent);\n\t\tparseTillEnd (token, index, end_keyword);\n\t}\n\tdeleteToken (name);\n}\n\n/*  architecture behavioral of ent is*/\nstatic void parseArchitecture (tokenInfo * const token)\n{\n\ttokenInfo *const name = newToken ();\n\n\treadToken (name);\n\tif (!isType (name, TOKEN_IDENTIFIER))\n\t{\n\t\tskipToKeyword (KEYWORD_END);\n\t\tskipToCharacterInInputFile (';');\n\t\tdeleteToken (name);\n\t\treturn;\n\t}\n\n\tint index = makeVhdlTag (name, VHDLTAG_ARCHITECTURE);\n\treadToken (token);\n\tif (isKeyword (token, KEYWORD_OF))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t{\n\t\t\t/* Filling scope field of this architecture.\n\t\t\t   If the definition for the entity can be found in the symbol table,\n\t\t\t   use its cork as the scope. If not, use the reference tag for the\n\t\t\t   entity as fallback. */\n\t\t\tint role_index = makeSimpleRefTag (token->string,\n\t\t\t\t\t\t\t\t\t\t\t   VHDLTAG_ENTITY, VHDL_ENTITY_DESIGNED);\n\t\t\tint entity_index = anyKindEntryInScope (CORK_NIL,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvStringValue (token->string),\n\t\t\t\t\t\t\t\t\t\t\t\t\tVHDLTAG_ENTITY,\n\t\t\t\t\t\t\t\t\t\t\t\t\tfalse);\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\t\tif (e)\n\t\t\t{\n\t\t\t\te->extensionFields.scopeIndex = (\n\t\t\t\t\tentity_index == CORK_NIL\n\t\t\t\t\t? role_index\n\t\t\t\t\t: entity_index);\n\n\t\t\t\t/* TODO: append thes architecture name to\n\t\t\t\t * architecture: field of *e*. */\n\t\t\t}\n\n\t\t\tattachParserFieldToCorkEntry (role_index,\n\t\t\t\t\t\t\t\t\t\t  VhdlFields[F_ARCHITECTURE].ftype,\n\t\t\t\t\t\t\t\t\t\t  vStringValue (name->string));\n\n\t\t\treadToken (token);\n\t\t\tif (isKeyword (token, KEYWORD_IS))\n\t\t\t{\n\t\t\t\tparseTillBegin (token, index);\n\t\t\t\tparseTillEnd (token, index, KEYWORD_ARCHITECTURE);\n\t\t\t}\n\t\t}\n\t}\n\tdeleteToken (name);\n}\n\nstatic void parseSignal (tokenInfo * const token, int parent)\n{\n\treadToken (token);\n\tparseDeclElement (token, VHDLTAG_SIGNAL, parent, true);\n}\n\nstatic void parseLabel (tokenInfo * const name, int parent)\n{\n\ttokenInfo *const token = newToken ();\n\n\treadToken (token);\n\tif (isType (token, TOKEN_COLON))\n\t{\n\t\treadToken (token);\n\t\tif (isType (token, TOKEN_KEYWORD))\n\t\t\tparseKeywords (token, name, parent);\n\t}\n\tdeleteToken (token);\n}\n\nstatic void parseProcess (tokenInfo * const token, tokenInfo * const label, int parent)\n{\n\ttokenInfo *process = label? label: copyToken (token);\n\n\tif (label == NULL)\n\t{\n\t\tprocess->type = TOKEN_IDENTIFIER;\n\t\tvStringClear (process->string);\n\t\tanonGenerate (process->string, \"anonProcess\", VHDLTAG_PROCESS);\n\t}\n\n\tint index = makeVhdlTagWithScope (process, VHDLTAG_PROCESS, parent);\n\n\tif (label == NULL)\n\t{\n\t\ttagEntryInfo *e = getEntryInCorkQueue (index);\n\t\tif (e)\n\t\t\tmarkTagExtraBit (e, XTAG_ANONYMOUS);\n\t\tdeleteToken (process);\n\t}\n\n\tskipToMatched (token);\n\tparseTillBegin (token, index);\n\tparseTillEnd (token, index, KEYWORD_PROCESS);\n}\n\nstatic void parseVariable (tokenInfo * const token, int parent)\n{\n\treadToken (token);\n\tparseDeclElement (token, VHDLTAG_VARIABLE, parent, true);\n}\n\nstatic void parseAlias (tokenInfo * const token, int parent)\n{\n\treadToken (token);\n\tparseDeclElement (token, VHDLTAG_ALIAS, parent, true);\n}\n\n/* TODO */\n/* records */\nstatic void parseKeywords (tokenInfo * const token, tokenInfo * const label, int index)\n{\n\tswitch (token->keyword)\n\t{\n\tcase KEYWORD_END:\n\t\tskipToCharacterInInputFile (';');\n\t\tbreak;\n\tcase KEYWORD_CONSTANT:\n\t\tparseConstant (index);\n\t\tbreak;\n\tcase KEYWORD_TYPE:\n\t\tparseTypes (token, index);\n\t\tbreak;\n\tcase KEYWORD_SUBTYPE:\n\t\tparseTypes (token, index);\n\t\tbreak;\n\tcase KEYWORD_ENTITY:\n\t\tparseModule (token, index);\n\t\tbreak;\n\tcase KEYWORD_COMPONENT:\n\t\tparseModule (token, index);\n\t\tbreak;\n\tcase KEYWORD_FUNCTION:\n\t\tparseSubProgram (token, index);\n\t\tbreak;\n\tcase KEYWORD_PROCEDURE:\n\t\tparseSubProgram (token, index);\n\t\tbreak;\n\tcase KEYWORD_PACKAGE:\n\t\tparsePackage (token);\n\t\tbreak;\n\tcase KEYWORD_ARCHITECTURE:\n\t\tparseArchitecture (token);\n\t\tbreak;\n\tcase KEYWORD_SIGNAL:\n\t\tparseSignal (token, index);\n\t\tbreak;\n\tcase KEYWORD_PROCESS:\n\t\tparseProcess (token, label, index);\n\t\tbreak;\n\tcase KEYWORD_VARIABLE:\n\t\tparseVariable (token, index);\n\t\tbreak;\n\tcase KEYWORD_ALIAS:\n\t\tparseAlias (token, index);\n\t\tbreak;\n\tdefault:\n\t\tif (isType (token, TOKEN_IDENTIFIER))\n\t\t\tparseLabel (token, index);\n\t\tbreak;\n\t}\n}\n\nstatic tokenType parseVhdlFile (tokenInfo * const token)\n{\n\tdo\n\t{\n\t\treadToken (token);\n\t\tparseKeywords (token, NULL, CORK_NIL);\n\t} while (!isKeyword (token, KEYWORD_END) && !isType (token, TOKEN_EOF));\n\treturn token->type;\n}\n\nstatic void findVhdlTags (void)\n{\n\ttokenInfo *const token = newToken ();\n\n\twhile (parseVhdlFile (token) != TOKEN_EOF);\n\n\tdeleteToken (token);\n}\n\nextern parserDefinition *VhdlParser (void)\n{\n\tstatic const char *const extensions[] = { \"vhdl\", \"vhd\", NULL };\n\tparserDefinition *def = parserNew (\"VHDL\");\n\tdef->kindTable = VhdlKinds;\n\tdef->kindCount = ARRAY_SIZE (VhdlKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findVhdlTags;\n\tdef->initialize = initialize;\n\tdef->keywordTable = VhdlKeywordTable;\n\tdef->keywordCount = ARRAY_SIZE (VhdlKeywordTable);\n\tdef->fieldTable = VhdlFields;\n\tdef->fieldCount = ARRAY_SIZE (VhdlFields);\n\tdef->useCork = CORK_QUEUE|CORK_SYMTAB;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/vim.c",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Thanks are due to Jay Glanville for significant improvements.\n*\n*   This module contains functions for generating tags for user-defined\n*   functions for the Vim editor.\n*\n*   references:\n*   - https://vim-jp.org/vimdoc-en/\n*   - https://vim-jp.org/vimdoc-ja/\n*\n*/\n\n/*\n *  INCLUDE FILES\n */\n#include \"general.h\"  /* must always come first */\n\n#include <string.h>\n#ifdef DEBUG\n#include <stdio.h>\n#endif\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"vstring.h\"\n\n#if 0\ntypedef struct sLineInfo {\n\ttokenType type;\n\tkeywordId keyword;\n\tvString *string;\n\tvString *scope;\n\tunsigned long lineNumber;\n\tMIOPos filePosition;\n} lineInfo;\n#endif\n\n/*\n * DATA DEFINITIONS\n */\ntypedef enum {\n\tK_AUGROUP,\n\tK_COMMAND,\n\tK_FUNCTION,\n\tK_MAP,\n\tK_VARIABLE,\n\tK_FILENAME,\n\tK_CONST,\n\tK_HEREDOC,\n\tK_CLASS,\n} vimKind;\n\ntypedef enum {\n\tR_HEREDOC_ENDLABEL,\n} vimHeredocRole;\n\nstatic roleDefinition VimHeredocRoles [] = {\n\t{ true, \"endmarker\", \"end marker\" },\n};\n\nstatic kindDefinition VimKinds [] = {\n\t{ true,  'a', \"augroup\",  \"autocommand groups\" },\n\t{ true,  'c', \"command\",  \"user-defined commands\" },\n\t{ true,  'f', \"function\", \"function definitions\" },\n\t{ true,  'm', \"map\",      \"maps\" },\n\t{ true,  'v', \"variable\", \"variable definitions\" },\n\t{ true,  'n', \"filename\", \"vimball filename\" },\n\t{ true,  'C', \"constant\", \"constant definitions\" },\n\t{ false, 'h', \"heredoc\",  \"marker for here document\",\n\t  .referenceOnly = false, ATTACH_ROLES (VimHeredocRoles),\n\t  .version = 1 },\n\t{ true,  'k', \"class\", \"vim9script classes\",\n\t  .version = 1 },\n};\n\n/*\n *  DATA DECLARATIONS\n */\n\n/*\n *  DATA DEFINITIONS\n */\nstatic bool vim9script;\n\n/*\n *  FUNCTION DEFINITIONS\n */\n\nstatic bool parseVimLine (const unsigned char *line, int parent);\n\n/* This function takes a char pointer, tries to find a scope separator in the\n * string, and if it does, returns a pointer to the character after the colon,\n * and the character defining the scope.\n * If a colon is not found, it returns the original pointer.\n */\nstatic const unsigned char *skipPrefix (const unsigned char *name, int *scope)\n{\n\tconst unsigned char *result = name;\n\tint counter;\n\tsize_t length;\n\tlength = strlen ((const char *) name);\n\tif (scope != NULL)\n\t\t*scope = '\\0';\n\tif (length > 3 && name[1] == ':')\n\t{\n\t\tif (scope != NULL)\n\t\t\t*scope = *name;\n\t\tresult = name + 2;\n\t}\n\telse if (length > 5 && strncasecmp ((const char *) name, \"<SID>\", (size_t) 5) == 0)\n\t{\n\t\tif (scope != NULL)\n\t\t\t*scope = *name;\n\t\tresult = name + 5;\n\t}\n\telse\n\t{\n\t\t/*\n\t\t * Vim7 check for dictionaries or autoload function names\n\t\t */\n\t\tcounter = 0;\n\t\tdo\n\t\t{\n\t\t\tswitch (name[counter])\n\t\t\t{\n\t\t\t\tcase '.':\n\t\t\t\t\t/* Set the scope to d - Dictionary */\n\t\t\t\t\t*scope = 'd';\n\t\t\t\t\tbreak;\n\t\t\t\tcase '#':\n\t\t\t\t\t/* Set the scope to a - autoload */\n\t\t\t\t\t*scope = 'a';\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t++counter;\n\t\t} while (isalnum (name[counter]) ||\n\t\t\t\tname[counter] == '_'           ||\n\t\t\t\tname[counter] == '.'           ||\n\t\t\t\tname[counter] == '#'\n\t\t\t\t);\n\t}\n\treturn result;\n}\n\nstatic bool isWordChar (const unsigned char c)\n{\n\treturn (isalnum (c) || c == '_');\n}\n\n/* checks if a word at the start of `p` matches at least `min_len` first\n * characters from `word` */\nstatic bool wordMatchLen (const unsigned char *p, const char *const word, size_t min_len)\n{\n\tconst unsigned char *w = (const unsigned char *) word;\n\tsize_t n = 0;\n\n\twhile (*p && *p == *w)\n\t{\n\t\tp++;\n\t\tw++;\n\t\tn++;\n\t}\n\n\tif (isWordChar (*p))\n\t\treturn false;\n\n\treturn n >= min_len;\n}\n\nstatic const unsigned char *skipWord (const unsigned char *p)\n{\n\twhile (*p && isWordChar (*p))\n\t\tp++;\n\treturn p;\n}\n\nstatic bool isMap (const unsigned char *line)\n{\n\t/*\n\t * There are many different short cuts for specifying a map.\n\t * This routine should capture all the permutations.\n\t */\n\treturn (wordMatchLen (line, \"map\", 3) ||\n\t\t\twordMatchLen (line, \"nmap\", 2) ||\n\t\t\twordMatchLen (line, \"vmap\", 2) ||\n\t\t\twordMatchLen (line, \"xmap\", 2) ||\n\t\t\twordMatchLen (line, \"smap\", 4) ||\n\t\t\twordMatchLen (line, \"omap\", 2) ||\n\t\t\twordMatchLen (line, \"imap\", 2) ||\n\t\t\twordMatchLen (line, \"lmap\", 2) ||\n\t\t\twordMatchLen (line, \"cmap\", 2) ||\n\t\t\twordMatchLen (line, \"noremap\", 2) ||\n\t\t\twordMatchLen (line, \"nnoremap\", 2) ||\n\t\t\twordMatchLen (line, \"vnoremap\", 2) ||\n\t\t\twordMatchLen (line, \"xnoremap\", 2) ||\n\t\t\twordMatchLen (line, \"snoremap\", 4) ||\n\t\t\twordMatchLen (line, \"onoremap\", 3) ||\n\t\t\twordMatchLen (line, \"inoremap\", 3) ||\n\t\t\twordMatchLen (line, \"lnoremap\", 2) ||\n\t\t\twordMatchLen (line, \"cnoremap\", 3));\n}\n\nstatic const unsigned char *readVimLineRaw (void)\n{\n\treturn readLineFromInputFile ();\n}\n\nstatic const unsigned char *readVimLine (void)\n{\n\tconst unsigned char *line;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\twhile (isspace (*line))\n\t\t\t++line;\n\n\t\tif ((int) *line == (vim9script? '#': '\"'))\n\t\t\tcontinue;  /* skip comment */\n\n\t\tbreak;\n\t}\n\n\treturn line;\n}\n\nstatic const unsigned char *readVimballLine (void)\n{\n\tconst unsigned char *line;\n\n\twhile ((line = readLineFromInputFile ()) != NULL)\n\t{\n\t\tbreak;\n\t}\n\n\treturn line;\n}\n\nstatic const unsigned char *parseRettype (const unsigned char *cp, tagEntryInfo *e)\n{\n\twhile (*cp && isspace (*cp))\n\t\t++cp;\n\n\tif (!*cp)\n\t\treturn cp;\n\n\tvString *buf = vStringNew ();\n\twhile (*cp && *cp != '#' && *cp != '=')\n\t{\n\t\tif (isspace (*cp)\n\t\t\t&& !vStringIsEmpty(buf)\n\t\t\t&& isspace (vStringLast(buf)))\n\t\t{\n\t\t\t++cp;\n\t\t\tcontinue;\n\t\t}\n\t\tvStringPut (buf, *cp);\n\t\t++cp;\n\t}\n\n\tif (vStringIsEmpty(buf))\n\t\treturn cp;\n\n\tvStringStripTrailing (buf);\n\te->extensionFields.typeRef[0] = eStrdup (\"typename\");\n\te->extensionFields.typeRef[1] = vStringDeleteUnwrap (buf);\n\n\treturn cp;\n}\n\nstatic vString *parseSignatureAndRettype (const unsigned char *cp,\n\t\t\t\t\t\t\t\t\t\t  tagEntryInfo *e,\n\t\t\t\t\t\t\t\t\t\t  vString *buf,\n\t\t\t\t\t\t\t\t\t\t  bool extractRettype)\n{\n\t/* TODO capture parameters */\n\n\tAssert (e);\n\tAssert (cp);\n\n\tif (!buf)\n\t{\n\t\tbuf = vStringNew ();\n\t\tvStringPut (buf, *cp);\n\t\t++cp;\n\t}\n\n\twhile (*cp != '\\0')\n\t{\n\t\tif (isspace (*cp)\n\t\t\t&& vStringLast (buf) == ',')\n\t\t{\n\t\t\t++cp;\n\t\t\tcontinue;\n\t\t}\n\t\tvStringPut (buf, *cp);\n\t\tif (*cp == ')')\n\t\t\tbreak;\n\t\t++cp;\n\t}\n\n\tif (*cp == ')')\n\t{\n\t\te->extensionFields.signature = vStringDeleteUnwrap (buf);\n\t\tbuf = NULL;\n\n\t\tif (extractRettype)\n\t\t{\n\t\t\t++cp;\n\t\t\twhile (*cp && isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tif (*cp == ':')\n\t\t\t\tparseRettype (++cp, e);\n\t\t}\n\t}\n\n\treturn buf;\n}\n\nstatic void parseFunction (const unsigned char *line, int parent, bool definedWithDEF,\n\t\t\t\t\t\t   bool isPublic)\n{\n\tvString *name = vStringNew ();\n\tvString *signature = NULL;\n\t/* bool inFunction = false; */\n\tint scope;\n\tconst unsigned char *cp = line;\n\tint index = CORK_NIL;\n\ttagEntryInfo *e = NULL;\n\n\tif (*cp == '!')\n\t\t++cp;\n\tif (isspace (*cp))\n\t{\n\t\twhile (*cp && isspace (*cp))\n\t\t\t++cp;\n\n\t\tif (*cp)\n\t\t{\n\t\t\tcp = skipPrefix (cp, &scope);\n\t\t\tif ((definedWithDEF && (*cp == '_' || isalpha (*cp))) ||\n\t\t\t\tisupper (*cp)  ||\n\t\t\t\t\tscope == 's'  ||  /* script scope */\n\t\t\t\t\tscope == '<'  ||  /* script scope */\n\t\t\t\t\tscope == 'g'  ||  /* global scope */\n\t\t\t\t\tscope == 'd'  ||  /* dictionary */\n\t\t\t\t\tscope == 'a')     /* autoload */\n\t\t\t{\n\t\t\t\tchar prefix[3] = { [0] = (char)scope, [1] = ':', [2] = '\\0' };\n\t\t\t\tif (scope == 's')\n\t\t\t\t\tvStringCatS (name, prefix);\n\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tvStringPut (name, *cp);\n\t\t\t\t\t++cp;\n\t\t\t\t} while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '#');\n\t\t\t\tindex = makeSimpleTag (name, K_FUNCTION);\n\t\t\t\tvStringClear (name);\n\n\t\t\t\te = getEntryInCorkQueue (index);\n\t\t\t\tif (e)\n\t\t\t\t{\n\t\t\t\t\te->extensionFields.scopeIndex = parent;\n\t\t\t\t\tif (isFieldEnabled (FIELD_SIGNATURE))\n\t\t\t\t\t{\n\t\t\t\t\t\twhile (*cp && isspace (*cp))\n\t\t\t\t\t\t\t++cp;\n\t\t\t\t\t\tif (*cp == '(')\n\t\t\t\t\t\t\tsignature = parseSignatureAndRettype (cp, e, NULL,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  definedWithDEF);\n\t\t\t\t\t}\n\t\t\t\t\tif (isPublic)\n\t\t\t\t\t\te->extensionFields.access = eStrdup(\"public\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* TODO - update struct to indicate inside function */\n\twhile ((line = readVimLine ()) != NULL)\n\t{\n\t\tif (signature)\n\t\t{\n\t\t\tcp = line;\n\t\t\twhile (*cp && isspace (*cp))\n\t\t\t\t++cp;\n\t\t\t/* A backslash at the start of a line stands for a line continuation.\n\t\t\t * https://vimhelp.org/repeat.txt.html#line-continuation */\n\t\t\tif (*cp == '\\\\')\n\t\t\t\tsignature = parseSignatureAndRettype (++cp, e, signature,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  definedWithDEF);\n\t\t}\n\n\t\tif (wordMatchLen (line, \"endfunction\", 4) || wordMatchLen (line, \"enddef\", 6))\n\t\t{\n\t\t\tif (e)\n\t\t\t\tsetTagEndLine (e, getInputLineNumber ());\n\t\t\tbreak;\n\t\t}\n\n\t\tparseVimLine (line, index);\n\t}\n\tif (signature)\n\t\tvStringDelete (signature);\n\tvStringDelete (name);\n}\n\nstatic void parseClass (const unsigned char *line, int parent,\n\t\t\t\t\t\tbool isPublic, bool isAbstract)\n{\n\tvString *name = vStringNew ();\n\tvString *super = NULL;\n\tconst unsigned char *cp = line;\n\tint index = CORK_NIL;\n\n\tif (isspace (*cp))\n\t{\n\t\twhile (*cp && isspace (*cp))\n\t\t\t++cp;\n\n\t\twhile (isalnum (*cp) || *cp == '_')\n\t\t{\n\t\t\tvStringPut (name, *cp);\n\t\t\t++cp;\n\t\t}\n\n\t\twhile (*cp && isspace (*cp))\n\t\t\t++cp;\n\n\t\tif (wordMatchLen (cp, \"extends\", 7))\n\t\t{\n\t\t\tcp += 7;\n\t\t\twhile (*cp && isspace (*cp))\n\t\t\t\t++cp;\n\t\t\tsuper = vStringNew ();\n\t\t\twhile (*cp && (isalnum (*cp) || *cp == '_'\n\t\t\t\t\t\t   /* ??? */\n\t\t\t\t\t\t   || *cp == '.'))\n\t\t\t{\n\t\t\t\tvStringPut (super, *cp);\n\t\t\t\tcp++;\n\t\t\t}\n\t\t}\n\n\t\tif (!vStringIsEmpty (name))\n\t\t{\n\t\t\ttagEntryInfo *e;\n\n\t\t\tindex = makeSimpleTag (name, K_CLASS);\n\t\t\te = getEntryInCorkQueue (index);\n\t\t\tif (e)\n\t\t\t{\n\t\t\t\te->extensionFields.scopeIndex = parent;\n\t\t\t\tif (isPublic)\n\t\t\t\t\te->extensionFields.access = eStrdup (\"public\");\n\t\t\t\tif (isAbstract)\n\t\t\t\t\te->extensionFields.implementation = eStrdup (\"abstract\");\n\t\t\t\tif (super && !vStringIsEmpty (super))\n\t\t\t\t{\n\t\t\t\t\te->extensionFields.inheritance = vStringDeleteUnwrap(super);\n\t\t\t\t\tsuper = NULL;\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile ((line = readVimLine ()) != NULL)\n\t\t\t{\n\t\t\t\tif (wordMatchLen (line, \"endclass\", 8))\n\t\t\t\t{\n\t\t\t\t\tif (e)\n\t\t\t\t\t\tsetTagEndLine (e, getInputLineNumber ());\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tparseVimLine (line, index);\n\t\t\t}\n\t\t}\n\t}\n\n\tvStringDelete (super);\t\t/* NULL ia acceptable. */\n\tvStringDelete (name);\n}\n\nstatic void parseAutogroup (const unsigned char *line)\n{\n\tvString *name = vStringNew ();\n\n\t/* Found Autocommand Group (augroup) */\n\tconst unsigned char *cp = line;\n\tif (isspace (*cp))\n\t{\n\t\twhile (*cp && isspace (*cp))\n\t\t\t++cp;\n\n\t\tif (*cp)\n\t\t{\n\t\t\tconst unsigned char *end = skipWord (cp);\n\n\t\t\t/* \"end\" (caseless) has a special meaning and should not generate a tag */\n\t\t\tif (end > cp && strncasecmp ((const char *) cp, \"end\", end - cp) != 0)\n\t\t\t{\n\t\t\t\tvStringNCatS (name, (const char *) cp, end - cp);\n\t\t\t\tmakeSimpleTag (name, K_AUGROUP);\n\t\t\t\tvStringClear (name);\n\t\t\t}\n\t\t}\n\t}\n\tvStringDelete (name);\n}\n\nstatic bool parseCommand (const unsigned char *line)\n{\n\tvString *name = vStringNew ();\n\tbool cmdProcessed = true;\n\n\t/*\n\t * Found a user-defined command\n\t *\n\t * They can have many options preceded by a dash\n\t * command! -nargs=+ -complete Select  :call s:DB_execSql(\"select \" . <q-args>)\n\t * The name of the command should be the first word not preceded by a dash\n\t *\n\t */\n\tconst unsigned char *cp = line;\n\n\tif (cp && (*cp == '\\\\'))\n\t{\n\t\t/*\n\t\t * We are recursively calling this function is the command\n\t\t * has been continued on to the next line\n\t\t *\n\t\t * Vim statements can be continued onto a newline using a \\\n\t\t * to indicate the previous line is continuing.\n\t\t *\n\t\t * com -nargs=1 -bang -complete=customlist,EditFileComplete\n\t\t *          \\ EditFile edit<bang> <args>\n\t\t *\n\t\t * If the following lines do not have a line continuation\n\t\t * the command must not be spanning multiple lines and should\n\t\t * be syntactically incorrect.\n\t\t */\n\t\tif (*cp == '\\\\')\n\t\t\t++cp;\n\n\t\twhile (*cp && isspace (*cp))\n\t\t\t++cp;\n\t}\n\telse if (line && wordMatchLen (cp, \"command\", 3))\n\t{\n\t\tcp = skipWord (cp);\n\n\t\tif (*cp == '!')\n\t\t\t++cp;\n\n\t\tif (*cp != ' ')\n\t\t{\n\t\t\t/*\n\t\t\t * :command must be followed by a space.  If it is not, it is\n\t\t\t * not a valid command.\n\t\t\t * Treat the line as processed and continue.\n\t\t\t */\n\t\t\tcmdProcessed = true;\n\t\t\tgoto cleanUp;\n\t\t}\n\n\t\twhile (*cp && isspace (*cp))\n\t\t\t++cp;\n\t}\n\telse\n\t{\n\t\t/*\n\t\t * We are recursively calling this function.  If it does not start\n\t\t * with \"com\" or a line continuation character, we have moved off\n\t\t * the command line and should let the other routines parse this file.\n\t\t */\n\t\tcmdProcessed = false;\n\t\tgoto cleanUp;\n\t}\n\n\t/*\n\t * Strip off any spaces and options which are part of the command.\n\t * These should precede the command name.\n\t */\n\tdo\n\t{\n\t\tif (isspace (*cp))\n\t\t{\n\t\t\t++cp;\n\t\t}\n\t\telse if (*cp == '-')\n\t\t{\n\t\t\t/*\n\t\t\t * Read until the next space which separates options or the name\n\t\t\t */\n\t\t\twhile (*cp && !isspace (*cp))\n\t\t\t\t++cp;\n\t\t}\n\t\telse if (!isalnum (*cp))\n\t\t{\n\t\t\t/*\n\t\t\t * Broken syntax: throw away this line\n\t\t\t */\n\t\t\tcmdProcessed = true;\n\t\t\tgoto cleanUp;\n\t\t}\n\t} while (*cp &&  !isalnum (*cp));\n\n\tif (!*cp)\n\t{\n\t\t/*\n\t\t * We have reached the end of the line without finding the command name.\n\t\t * Read the next line and continue processing it as a command.\n\t\t */\n\t\tif ((line = readVimLine ()) != NULL)\n\t\t\tcmdProcessed = parseCommand (line);\n\t\telse\n\t\t\tcmdProcessed = false;\n\t\tgoto cleanUp;\n\t}\n\n\tdo\n\t{\n\t\tvStringPut (name, *cp);\n\t\t++cp;\n\t} while (isalnum (*cp) || *cp == '_');\n\n\tmakeSimpleTag (name, K_COMMAND);\n\tvStringClear (name);\n\ncleanUp:\n\tvStringDelete (name);\n\n\treturn cmdProcessed;\n}\n\n/* =<< trim {endmarker} */\nstatic int parseHeredocMarker(const unsigned char *cp)\n{\n\twhile (*cp && isspace (*cp))\n\t\t++cp;\n\n\tif (! (cp[0] == '=' && cp[1] == '<' && cp[2] == '<'))\n\t\treturn CORK_NIL;\n\n\tcp += 3;\n\n\twhile (*cp && isspace (*cp))\n\t\t++cp;\n\n\tif (wordMatchLen (cp, \"trim\", 4))\n\t{\n\t\t\tcp += 4;\n\t\t\twhile (*cp && isspace (*cp))\n\t\t\t\t++cp;\n\t}\n\n\tif (!('A' <= *cp && *cp <= 'Z'))\n\t\treturn CORK_NIL;\n\n\tvString *heredoc = vStringNew ();\n\tdo\n\t\tvStringPut (heredoc, *cp++);\n\twhile (*cp != '\\0' && !isspace (*cp));\n\n\tif (vStringIsEmpty (heredoc))\n\t{\n\t\tvStringDelete (heredoc);\n\t\treturn CORK_NIL;\n\t}\n\n\tint r = makeSimpleTag (heredoc, K_HEREDOC);\n\tvStringDelete (heredoc);\n\treturn r;\n}\n\nstatic bool isFunction(int index)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue(index);\n\tif (!e)\n\t\treturn false;\n\treturn (e->kindIndex == K_FUNCTION);\n}\n\n/*\n * If we have a heredoc end marker at the end of LINE,\n * parseVariableOrConstant returns the tag cork index for the marker.\n */\nstatic int parseVariableOrConstant (const unsigned char *line, int parent, int kindIndex,\n\t\t\t\t\t\t\t\t\tbool isPublic)\n{\n\tvString *name = vStringNew ();\n\tint heredoc = CORK_NIL;\n\n\tconst unsigned char *cp = line;\n\tconst unsigned char *np = line;\n\t/* get the name */\n\tif (isspace (*cp))\n\t{\n\t\twhile (*cp && isspace (*cp))\n\t\t\t++cp;\n\n\t\t/*\n\t\t * Ignore lets which set:\n\t\t *    &  - local buffer vim settings\n\t\t *    @  - registers\n\t\t *    [  - Lists or Dictionaries\n\t\t */\n\t\tif (!*cp || *cp == '&' || *cp == '@' || *cp == '[')\n\t\t\tgoto cleanUp;\n\n\t\t/*\n\t\t * Ignore vim variables which are read only\n\t\t *    v: - Vim variables.\n\t\t */\n\t\tnp = cp;\n\t\t++np;\n\t\tif (*cp == 'v' && *np == ':')\n\t\t\tgoto cleanUp;\n\n\t\t/* Skip non-global vars in functions */\n\t\tbool inFunction = isFunction(parent);\n\t\tif (parent != CORK_NIL && inFunction && (*np != ':' || *cp != 'g'))\n\t\t\tgoto cleanUp;\n\n\t\t/* deal with spaces, $, @ and & */\n\t\twhile (*cp && *cp != '$' && !isalnum (*cp)\n\t\t\t   && !(vim9script && *cp == '_'))\n\t\t\t++cp;\n\n\t\tif (!*cp)\n\t\t\tgoto cleanUp;\n\n\t\t/* cp = skipPrefix (cp, &scope); */\n\t\tdo\n\t\t{\n\t\t\tif (!*cp)\n\t\t\t\tbreak;\n\n\t\t\tvStringPut (name, *cp);\n\t\t\t++cp;\n\t\t} while (isalnum (*cp) || *cp == '_' || *cp == '#' || *cp == ':' || *cp == '$');\n\n\t\tbool hasType = false;\n\t\tif (*cp && vim9script && !vStringIsEmpty (name) && (vStringLast (name) == ':'))\n\t\t{\n\t\t\tAssert(line != cp);\n\t\t\tAssert(*(cp - 1) == ':');\n\t\t\tvStringChop (name);\n\t\t\thasType = true;\n\t\t}\n\n\t\tif (!vStringIsEmpty (name))\n\t\t{\n\t\t\tint r = makeSimpleTag (name, kindIndex);\n\t\t\tvStringClear (name);\n\n\t\t\ttagEntryInfo *e = getEntryInCorkQueue (r);\n\t\t\tif (e)\n\t\t\t{\n\t\t\t\tif (hasType)\n\t\t\t\t\tcp = parseRettype (cp, e);\n\t\t\t\tif (!inFunction)\n\t\t\t\t\te->extensionFields.scopeIndex = parent;\n\t\t\t\tif (isPublic)\n\t\t\t\t\te->extensionFields.access = eStrdup(\"public\");\n\t\t\t}\n\n\t\t\theredoc = parseHeredocMarker(cp);\n\t\t}\n\t}\n\ncleanUp:\n\tvStringDelete (name);\n\n\treturn heredoc;\n}\n\nstatic bool parseMap (const unsigned char *line)\n{\n\tvString *name = vStringNew ();\n\tconst unsigned char *cp = line;\n\n\tif (*cp == '!')\n\t\t++cp;\n\n\t/*\n\t * Maps follow this basic format\n\t *    map\n\t *    nnoremap <silent> <F8> :Tlist<CR>\n\t *    map <unique> <Leader>scdt <Plug>GetColumnDataType\n\t *    inoremap ,,, <esc>diwi<<esc>pa><cr></<esc>pa><esc>kA\n\t *    inoremap <buffer> ( <C-R>=PreviewFunctionSignature()<LF>\n\t *\n\t * The Vim help shows the various special arguments available to a map:\n\t * 1.2 SPECIAL ARGUMENTS                    *:map-arguments*\n\t *    <buffer>\n\t *    <nowait>\n\t *    <silent>\n\t *    <script>\n\t *    <unique>\n\t *    <special>\n\t *    <expr>\n\t *\n\t * Strip the special arguments from the map command, this should leave\n\t * the map name which we will use as the \"name\".\n\t */\n\n\tdo\n\t{\n\t\twhile (*cp && isspace (*cp))\n\t\t\t++cp;\n\n\t\tif (strncmp ((const char *) cp, \"<Leader>\", (size_t) 8) == 0)\n\t\t\tbreak;\n\n\t\tif (\n\t\t\t\tstrncmp ((const char *) cp, \"<buffer>\", (size_t) 8) == 0 ||\n\t\t\t\tstrncmp ((const char *) cp, \"<nowait>\", (size_t) 8) == 0 ||\n\t\t\t\tstrncmp ((const char *) cp, \"<silent>\", (size_t) 8) == 0 ||\n\t\t\t\tstrncmp ((const char *) cp, \"<script>\", (size_t) 8) == 0 ||\n\t\t\t\tstrncmp ((const char *) cp, \"<unique>\", (size_t) 8) == 0\n\t\t   )\n\t\t{\n\t\t\tcp += 8;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (strncmp ((const char *) cp, \"<expr>\", (size_t) 6) == 0)\n\t\t{\n\t\t\tcp += 6;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (strncmp ((const char *) cp, \"<special>\", (size_t) 9) == 0)\n\t\t{\n\t\t\tcp += 9;\n\t\t\tcontinue;\n\t\t}\n\n\t\tbreak;\n\t} while (*cp);\n\n\tdo\n\t{\n\t\tvStringPut (name, *cp);\n\t\t++cp;\n\t} while (*cp && *cp != ' ');\n\n\tmakeSimpleTag (name, K_MAP);\n\tvStringClear (name);\n\n\tvStringDelete (name);\n\n\treturn true;\n}\n\nstatic bool parseVimLine (const unsigned char *line, int parent)\n{\n\tbool readNextLine = true;\n\tint heredoc = CORK_NIL;\n\tbool isPublic = false;\n\tbool isAbstract = false;\n\n\twhile (true)\n\t{\n\t\tif (vim9script && wordMatchLen (line, \"export\", 6))\n\t\t{\n\t\t\tline += 6;\n\t\t\twhile (*line && isspace (*line))\n\t\t\t\t++line;\n\t\t\t/* TODO: export should be stored to a field. */\n\t\t\tcontinue;\n\t\t}\n\t\telse if (vim9script && wordMatchLen (line, \"abstract\", 8))\n\t\t{\n\t\t\tline += 8;\n\t\t\twhile (*line && isspace (*line))\n\t\t\t\t++line;\n\t\t\tisAbstract = true;\n\t\t\tcontinue;\n\t\t}\n\t\telse if (vim9script && wordMatchLen (line, \"static\", 6))\n\t\t{\n\t\t\tline += 6;\n\t\t\twhile (*line && isspace (*line))\n\t\t\t\t++line;\n\t\t\t/* TODO: static should be stored to a field. */\n\t\t\tcontinue;\n\t\t}\n\t\telse if (vim9script && wordMatchLen (line, \"public\", 6))\n\t\t{\n\t\t\tline += 6;\n\t\t\twhile (*line && isspace (*line))\n\t\t\t\t++line;\n\t\t\tisPublic = true;\n\t\t\tcontinue;\n\t\t}\n\t\tbreak;\n\t}\n\n\tif (wordMatchLen (line, \"vim9script\", 10))\n\t{\n\t\tvim9script = true;\n\t}\n\n\telse if (wordMatchLen (line, \"command\", 3))\n\t{\n\t\treadNextLine = parseCommand (line);\n\t\t/* TODO - Handle parseCommand returning false */\n\t}\n\n\telse if (isMap (line))\n\t{\n\t\tparseMap (skipWord (line));\n\t}\n\n\telse if (wordMatchLen (line, \"function\", 2) || wordMatchLen (line, \"def\", 3))\n\t{\n\t\tparseFunction (skipWord (line), parent, vim9script && line[0] == 'd', isPublic);\n\t}\n\n\telse if (wordMatchLen (line, \"augroup\", 3))\n\t{\n\t\tparseAutogroup (skipWord (line));\n\t}\n\n\telse if (wordMatchLen (line, \"let\", 3) || (vim9script && wordMatchLen (line, \"var\", 3)))\n\t{\n\t\theredoc = parseVariableOrConstant (skipWord (line), parent, K_VARIABLE, isPublic);\n\t}\n\telse if (wordMatchLen (line, \"const\", 4) || wordMatchLen (line, \"final\", 5))\n\t{\n\t\theredoc = parseVariableOrConstant (skipWord (line), parent, K_CONST, isPublic);\n\t}\n\telse if (vim9script && wordMatchLen (line, \"class\", 5))\n\t{\n\t\tparseClass (skipWord (line), parent, isPublic, isAbstract);\n\t}\n\n\ttagEntryInfo *e;\n\tif (heredoc != CORK_NIL && (e = getEntryInCorkQueue (heredoc)))\n\t{\n\t\tconst unsigned char *line;\n\n\t\twhile ((line = readVimLineRaw()) != NULL)\n\t\t\tif (strcmp (e->name, (const char *)line) == 0)\n\t\t\t{\n\t\t\t\tsetTagEndLine (e, getInputLineNumber());\n\n\t\t\t\ttagEntryInfo h;\n\t\t\t\tinitRefTagEntry (&h, e->name, K_HEREDOC, R_HEREDOC_ENDLABEL);\n\t\t\t\tmakeTagEntry(&h);\n\n\t\t\t\tbreak;\n\t\t\t}\n\t}\n\n\treturn readNextLine;\n}\n\nstatic void parseVimFile (const unsigned char *line, int parent)\n{\n\tbool readNextLine = true;\n\n\twhile (line != NULL)\n\t{\n\t\treadNextLine = parseVimLine (line, parent);\n\n\t\tif (readNextLine)\n\t\t\tline = readVimLine ();\n\n\t}\n}\n\nstatic void parseVimBallFile (const unsigned char *line)\n{\n\tvString *fname = vStringNew ();\n\tconst unsigned char *cp;\n\tint file_line_count;\n\tint i;\n\n\t/*\n\t * Vimball Archives follow this format\n\t *    \" Vimball Archiver comment\n\t *    UseVimball\n\t *    finish\n\t *    filename\n\t *    line count (n) for filename\n\t *    (n) lines\n\t *    filename\n\t *    line count (n) for filename\n\t *    (n) lines\n\t *    ...\n\t */\n\n\t/* Next line should be \"finish\" */\n\tline = readVimLine ();\n\n\twhile (line != NULL)\n\t{\n\t\t/* Next line should be a filename */\n\t\tline = readVimLine ();\n\t\tif (line == NULL)\n\t\t{\n\t\t\tgoto cleanUp;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcp = line;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tvStringPut (fname, *cp);\n\t\t\t\t++cp;\n\t\t\t} while (isalnum (*cp) || *cp == '.' || *cp == '/' || *cp == '\\\\');\n\t\t\tmakeSimpleTag (fname, K_FILENAME);\n\t\t\tvStringClear (fname);\n\t\t}\n\n\t\tfile_line_count = 0;\n\t\t/* Next line should be the line count of the file */\n\t\tline = readVimLine ();\n\t\tif (line == NULL)\n\t\t{\n\t\t\tgoto cleanUp;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfile_line_count = atoi ((const char *) line);\n\t\t}\n\n\t\t/* Read all lines of the file */\n\t\tfor (i = 0; i < file_line_count; i++)\n\t\t{\n\t\t\tline = readVimballLine ();\n\t\t\tif (line == NULL)\n\t\t\t{\n\t\t\t\tgoto cleanUp;\n\t\t\t}\n\t\t}\n\t}\n\ncleanUp:\n\tvStringDelete (fname);\n}\n\nstatic void findVimTags (void)\n{\n\tconst unsigned char *line;\n\t/* TODO - change this into a structure */\n\n\tvim9script = false;\n\n\tline = readVimLine ();\n\n\tif (line == NULL)\n\t{\n\t\t\treturn;\n\t}\n\n\tif (strncmp ((const char *) line, \"UseVimball\", (size_t) 10) == 0)\n\t{\n\t\tparseVimBallFile (line);\n\t}\n\telse\n\t{\n\t\tparseVimFile (line, CORK_NIL);\n\t}\n}\n\nextern parserDefinition *VimParser (void)\n{\n\tstatic const char *const extensions [] = { \"vim\", \"vba\", NULL };\n\tstatic const char *const patterns [] = { \"vimrc\", \"[._]vimrc\", \"gvimrc\",\n\t\t\"[._]gvimrc\", NULL };\n\tparserDefinition *def = parserNew (\"Vim\");\n\tdef->kindTable      = VimKinds;\n\tdef->kindCount  = ARRAY_SIZE (VimKinds);\n\tdef->extensions = extensions;\n\tdef->patterns   = patterns;\n\tdef->parser     = findVimTags;\n\tdef->useCork    = CORK_QUEUE;\n\n\tdef->versionCurrent = 1;\n\tdef->versionAge = 1;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/windres.c",
    "content": "/*\n *\twindres.c\n *\n *\tCopyright (c) 2013, Frank Fesevur <ffes(at)users.sourceforge.net>\n *\n *\tThis source code is released for free distribution under the terms of the\n *\tGNU General Public License version 2 or (at your option) any later version.\n *\n *\tThis module contains functions for generating tags for Windows Resource files.\n */\n\n#include \"general.h\"\n\n#include <string.h>\n#include <ctype.h>\n\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n\nstatic int _blockDepth = 0;\n\ntypedef enum _WindResKinds\n{\n\tK_NONE = -1,\n\tK_DIALOG,\n\tK_MENU,\n\tK_ICON,\n\tK_BITMAP,\n\tK_CURSOR,\n\tK_FONT,\n\tK_VERSION,\n\tK_ACCELERATORS\n} ResKind;\n\nstatic kindDefinition ResKinds [] = {\n\t{ true, 'd', \"dialog\",\t\t\t\"dialogs\"\t\t},\n\t{ true, 'm', \"menu\",\t\t\t\"menus\"\t\t\t},\n\t{ true, 'i', \"icon\",\t\t\t\"icons\"\t\t\t},\n\t{ true, 'b', \"bitmap\",\t\t\t\"bitmaps\"\t\t},\n\t{ true, 'c', \"cursor\",\t\t\t\"cursors\"\t\t},\n\t{ true, 'f', \"font\",\t\t\t\"fonts\"\t\t\t},\n\t{ true, 'v', \"version\",\t\t\t\"versions\"\t\t},\n\t{ true, 'a', \"accelerators\",\t\"accelerators\"\t}\n};\n\ntypedef enum _WindResParserState\n{\n\tP_STATE_NONE,\n\tP_STATE_IN_COMMENT,\n\tP_STATE_IN_STATEMENTS,\t\t/* Between first line of item and BEGIN/{ */\n\tP_STATE_IN_BLOCK,\t\t\t/* In a BEGIN/END or {/} block */\n\tP_STATE_AT_END\n} ResParserState;\n\nstatic void makeResTag(vString *name, ResKind kind)\n{\n\tvStringStripTrailing(name);\n\tmakeSimpleTag(name, kind);\n\tvStringClear(name);\n}\n\nstatic ResParserState parseResDefinition(const unsigned char *line)\n{\n\tResParserState state = P_STATE_NONE;\n\tvString *name, *type;\n\n\tname = vStringNew();\n\twhile (*line && !isspace(*line))\n\t{\n\t\tvStringPut(name, *line);\n\t\tline++;\n\t}\n\n\twhile (*line && isspace(*line))\n\t\tline++;\n\n\ttype = vStringNew();\n\twhile (*line && !isspace(*line))\n\t{\n\t\tvStringPut(type, *line);\n\t\tline++;\n\t}\n\n\tif (strcmp(vStringValue(type), \"DIALOG\") == 0 || strcmp(vStringValue(type), \"DIALOGEX\") == 0)\n\t{\n\t\tmakeResTag(name, K_DIALOG);\n\t\tstate = P_STATE_IN_STATEMENTS;\n\t}\n\telse if (strcmp(vStringValue(type), \"MENU\") == 0 || strcmp(vStringValue(type), \"MENUEX\") == 0)\n\t{\n\t\tmakeResTag(name, K_MENU);\n\t\tstate = P_STATE_IN_STATEMENTS;\n\t}\n\telse if (strcmp(vStringValue(type), \"VERSIONINFO\") == 0)\n\t{\n\t\tmakeResTag(name, K_VERSION);\n\t\tstate = P_STATE_IN_STATEMENTS;\n\t}\n\telse if (strcmp(vStringValue(type), \"ACCELERATORS\") == 0)\n\t{\n\t\tmakeResTag(name, K_ACCELERATORS);\n\t\tstate = P_STATE_IN_STATEMENTS;\n\t}\n\telse if (strcmp(vStringValue(type), \"ICON\") == 0)\n\t{\n\t\tmakeResTag(name, K_ICON);\n\t\tstate = P_STATE_NONE;\n\t}\n\telse if (strcmp(vStringValue(type), \"CURSOR\") == 0)\n\t{\n\t\tmakeResTag(name, K_CURSOR);\n\t\tstate = P_STATE_NONE;\n\t}\n\telse if (strcmp(vStringValue(type), \"BITMAP\") == 0)\n\t{\n\t\tmakeResTag(name, K_BITMAP);\n\t\tstate = P_STATE_NONE;\n\t}\n\telse if (strcmp(vStringValue(type), \"FONT\") == 0)\n\t{\n\t\tmakeResTag(name, K_FONT);\n\t\tstate = P_STATE_NONE;\n\t}\n\n\tvStringDelete(name);\n\tvStringDelete(type);\n\n\treturn state;\n}\n\nstatic ResParserState parseResLine(const unsigned char *line, ResParserState state)\n{\n\twhile (*line != '\\0')\t/* readLineFromInputFile returns NULL terminated strings */\n\t{\n\t\twhile (isspace(*line))\n\t\t\tline++;\n\n\t\tswitch (state)\n\t\t{\n\t\t\tcase P_STATE_NONE:\n\t\t\t{\n\t\t\t\t/* C-styled # line (#include, #define, etc), ignore rest of line */\n\t\t\t\tif (*line == '#')\n\t\t\t\t{\n\t\t\t\t\treturn P_STATE_NONE;\n\t\t\t\t}\n\t\t\t\t/* single line comment, ignore rest of line */\n\t\t\t\telse if (*line == '/' && line[1] == '/')\n\t\t\t\t{\n\t\t\t\t\treturn P_STATE_NONE;\n\t\t\t\t}\n\t\t\t\t/* multi-line comment */\n\t\t\t\telse if( *line == '/' && line[1] == '*' )\n\t\t\t\t{\n\t\t\t\t\tstate = P_STATE_IN_COMMENT;\n\t\t\t\t}\n\t\t\t\telse if (isalnum(*line))\n\t\t\t\t{\n\t\t\t\t\treturn parseResDefinition(line);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase P_STATE_IN_COMMENT:\n\t\t\t{\n\t\t\t\tif (*line == '*' && line[1] == '/')\n\t\t\t\t\tstate = P_STATE_NONE;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase P_STATE_IN_STATEMENTS:\n\t\t\t{\n\t\t\t\t/* First BEGIN block */\n\t\t\t\tif (*line == '{' || strcmp((const char *) line, \"BEGIN\") == 0)\n\t\t\t\t{\n\t\t\t\t\t_blockDepth = 1;\n\t\t\t\t\treturn P_STATE_IN_BLOCK;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase P_STATE_IN_BLOCK:\n\t\t\t{\n\t\t\t\t/* Nested BEGIN blocks? */\n\t\t\t\tif (*line == '{' || strcmp((const char *) line, \"BEGIN\") == 0)\n\t\t\t\t{\n\t\t\t\t\t_blockDepth++;\n\t\t\t\t}\n\t\t\t\telse if (*line == '}' || strcmp((const char *) line, \"END\") == 0)\n\t\t\t\t{\n\t\t\t\t\tif (_blockDepth == 1)\n\t\t\t\t\t\treturn P_STATE_NONE;\n\t\t\t\t\telse\n\t\t\t\t\t\t_blockDepth--;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase P_STATE_AT_END:\n\t\t\t{\n\t\t\t\treturn state;\n\t\t\t}\n\t\t}\n\t\tif (line == NULL)\n\t\t\treturn P_STATE_AT_END;\n\t\tline++;\n\t}\n\n\treturn state;\n}\n\nstatic void findResTags(void)\n{\n\tconst unsigned char *line;\n\tResParserState state = P_STATE_NONE;\n\t_blockDepth = 0;\n\n\twhile ((line = readLineFromInputFile()) != NULL)\n\t{\n\t\tstate = parseResLine(line, state);\n\t\tif (state == P_STATE_AT_END)\n\t\t\treturn;\n\t}\n}\n\n/* parser definition */\nextern parserDefinition* WindResParser(void)\n{\n\tstatic const char *const extensions [] = { \"rc\", NULL };\n\tparserDefinition* def = parserNew(\"WindRes\");\n\tdef->kindTable\t= ResKinds;\n\tdef->kindCount\t= ARRAY_SIZE(ResKinds);\n\tdef->extensions\t= extensions;\n\tdef->parser\t\t= findResTags;\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/x-autoconf.h",
    "content": "/*\n *   Copyright (c) 2011, Colomban Wendling <colomban@geany.org>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   Autoconf parser interface exported to the other parsers\n */\n\n#ifndef CTAGS_AUTOCONF_H\n#define CTAGS_AUTOCONF_H\n\n#include \"general.h\"\n\ntypedef enum {\n\tAUTOCONF_PACKAGE_KIND,\n\tAUTOCONF_TEMPLATE_KIND,\n\tAUTOCONF_MACRO_KIND,\n\tAUTOCONF_OPTWITH_KIND,\n\tAUTOCONF_OPTENABLE_KIND,\n\tAUTOCONF_SUBST_KIND,\n\tAUTOCONF_CONDITION_KIND,\n\tAUTOCONF_DEFINITION_KIND,\n} autoconfKind;\n\ntypedef enum {\n\tAUTOCONF_OPTWITH_CMDLINE_ROLE,\n} autoconfOptwithRole;\n\ntypedef enum {\n\tAUTOCONF_OPTENABLE_CMDLINE_ROLE,\n} autoconfOptenableRole;\n\n#endif\t/* CTAGS_AUTOCONF_H */\n"
  },
  {
    "path": "parsers/x-bibtex.h",
    "content": "/*\n*   Copyright (c) 2023, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n#ifndef CTAGS_PARSER_BIBTEX_H\n#define CTAGS_PARSER_BIBTEX_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n\ntypedef struct sBibTexSubparser bibTexSubparser;\n\nstruct sBibTexSubparser {\n\tsubparser subparser;\n\tint (* isKeywordForTagging) (bibTexSubparser *,\n\t\t\t\t\t\t\t\t const char *string);\n};\n\n#endif\t/* CTAGS_PARSER_BIBTEX_H */\n"
  },
  {
    "path": "parsers/x-cpreprocessor.h",
    "content": "/*\n*   Copyright (c) 1998-2002, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   External interface to get.c\n*/\n#ifndef CTAGS_MAIN_GET_H\n#define CTAGS_MAIN_GET_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"debug.h\"\n#include \"mio.h\"\n#include \"ptrarray.h\"\n#include \"types.h\"\n#include \"vstring.h\"\n\n/*\n*   MACROS\n*/\n/* symbolic representations, above 0xFF not to conflict with any byte */\n#define CPP_STRING_SYMBOL ('S' + 0xff)\n#define CPP_CHAR_SYMBOL ('C' + 0xff)\n\n/*\n * cppIs... macros are for the value returned from cppGetc().  Don't\n * use \"char\" value. Don't pass a value stored to C-string\n * (char*... or char[]) or vString.\n *\n * cppGetc() can return the value out of range of unsigned char.\n * cppGetc calls skipToEndOfString() and skipToEndOfString() internally.\n * They return STRING_SYMBOL (== 338) and CHAR_SYMBOL (== 322) in a\n * case. (cppGetc() can return EOF (== -1). However, it is not an issue\n * here.)\n *\n * is...() macros/functions defined in ctype.h can handle the value of\n * an unsigned char or EOF; we cannot pass STRING_SYMBOL or CHAR_SYMBOL\n * returned from cppGetc().\n *\n * Depending on the platform, isalpha(338) returns different value.\n * As far as Fedora22, it returns 0. On Windows 2010, it returns 1.\n *\n * So, we need cppIs... macros.\n * cppIs... macros considers STRING_SYMBOL and CHAR_SYMBOL */\n\n#define cppIsascii(c) ((c >= 0) && (c < 0x80))\n/* isascii is not portable enough. */\n\n/*  Is the character valid as a character of a C identifier?\n *  VMS allows '$' in identifiers.\n */\n#define cppIsalnum(c)  (cppIsascii(c) && isalnum(c))\n#define cppIsident(c)  (cppIsalnum(c)\t\t\t\t\t\\\n\t\t\t\t\t\t|| (c) == '_' || (c) == '$')\n\n/*  Is the character valid as the first character of a C identifier?\n *  C++ allows '~' in destructors.\n *  VMS allows '$' in identifiers.\n */\n#define cppIsalpha(c)   (cppIsascii(c) && isalpha(c))\n#define cppIsident1(c)  (cppIsalpha(c)\t\t\t\t\t\\\n\t\t\t\t\t\t  || (c) == '_' || (c) == '~' || (c) == '$')\n\n#define cppIsspace(c)   (cppIsascii(c) && isspace(c))\n#define cppIsdigit(c)   (cppIsascii(c) && isdigit(c))\n\n\n#define RoleTemplateUndef { true, \"undef\", \"undefined\" }\n#define RoleTemplateCondition { false, \"condition\", \"used in part of #if/#ifdef/#elif conditions\" }\n\n#define RoleTemplateSystem { true, \"system\", \"system header\" }\n#define RoleTemplateLocal  { true, \"local\", \"local header\" }\n\ntypedef enum {\n\tCPREPRO_MACRO, CPREPRO_HEADER, CPREPRO_PARAM,\n} cPreProKind;\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nextern bool cppIsBraceFormat (void);\nextern unsigned int cppGetDirectiveNestLevel (void);\n\n/* Don't forget to set useCort true in your parser.\n * The corkQueue is needed to capture macro parameters.\n */\nextern void cppInit (const bool state,\n\t\t     const bool hasAtLiteralStrings,\n\t\t     const bool hasCxxRawLiteralStrings,\n\t\t     const bool hasSingleQuoteLiteralNumbers,\n\t\t     int defineMacroKindIndex,\n\t\t     int macroUndefRoleIndex,\n\t\t     int macroConditionRoleIndex,\n\t\t     int headerKindIndex,\n\t\t     int headerSystemRoleIndex, int headerLocalRoleIndex,\n\t\t     int macroParamKindIndex,\n\t\t     int macrodefFieldIndex);\n\nextern void cppTerminate (void);\nextern void cppBeginStatement (void);\nextern void cppEndStatement (void);\nextern void cppUngetc (const int c);\nextern int cppUngetBufferSize(void);\nextern void cppUngetString(const char * string,int len);\nextern int cppGetc (void);\nextern const vString * cppGetLastCharOrStringContents (void);\n\n/*\n * Replacement for vStringPut that can handle c > 0xff\n */\nextern void cppVStringPut (vString * string, const int c);\n\n/* Notify the external parser state for the purpose of conditional\n * branch choice. The CXX parser stores the block level here. */\nextern void cppPushExternalParserBlock(void);\nextern void cppPopExternalParserBlock(void);\n\n/*\n * Macro expander related declarations\n */\n\n/* We stop applying macro replacements if the unget buffer gets too big\n   as it is a sign of recursive macro expansion */\n#define CPP_MAXIMUM_UNGET_BUFFER_SIZE_FOR_MACRO_REPLACEMENTS 65536\n\n/* We stop applying macro replacements if a macro is used so many\n   times in a recursive macro expansion. */\n#define CPP_MAXIMUM_MACRO_USE_COUNT 8\n\ntypedef struct sCppMacroReplacementPartInfo cppMacroReplacementPartInfo;\n\ntypedef struct sCppMacroInfo {\n\tchar *name;\t\t\t/* the name of macro. Useful for debugging. */\n\tbool hasParameterList; /* true if the macro has a trailing () */\n\tcppMacroReplacementPartInfo * replacements;\n\tint useCount;\n\tstruct sCppMacroInfo * next;\n} cppMacroInfo;\n\nstruct sCppMacroTokens;\ntypedef struct sCppMacroTokens cppMacroTokens;\n\nstruct sCppMacroArg;\ntypedef struct sCppMacroArg cppMacroArg;\n\n/* Expanding macros\n * ================\n *\n * Build a replacement tokens for the specified macro.\n * If the macro has parameters, they will be used.\n * Parameters not found in the list will be assumed to be empty.\n * May return NULL or equivalently an empty replacement tokens.\n *\n * Data types\n * ----------\n * + cppFindMacro:\n *   Macro definition.\n * + cppMacroArg:\n *   Argument passed to a macro.\n * + cppMacroTokens:\n *   The result of macro expansion. You can push back this object\n *   to the input stream.\n *\n * Functions\n * ---------\n * + cppFindMacro()\n * Find a macro definition for a given macro.\n * Macros defined with -D option are stored to a database behind this function.\n *\n * + cppMacroArgNew()\n * Make an object representing a macro argument.\n * STR passed to cppMacroArgNew is freed when deleting it with\n * cppMacroArgDelete() if FREE_STR_WHEN_DELETING is true.\n *\n * + cppExpandMacro()\n * Expand the macro with arguments.\n * MACRO is a cppMacroInfo object returned from cppFindMacro.\n * ARGS is a ptrArray containing cppMacroArg objects.\n * LINENUMBER and FILEPOSITION are the place where the macro is expanded.\n * Pass the returned value to cppUngetMacroTokens.\n * cppExpandMacro allocates the cppMacroTokens. It is deleted in\n * cppUngetMacroTokens().\n * Use this function only if MACRO->replacements is not-NULL.\n *\n * + cppExpandMacroAsNewString()\n * A wrapper of cppExpandMacro. This function returns\n * a vString instead of returning a cppMacroTokens object.\n * Use this function only if MACRO->replacements is not-NULL.\n *\n */\nextern cppMacroInfo * cppFindMacro (const char *const name);\nextern void cppUngetMacroTokens (cppMacroTokens *tokens);\n\nextern cppMacroArg *cppMacroArgNew (const char *str, bool free_str_when_deleting,\n\t\t\t\t\t\t\t\t\tunsigned long lineNumber, MIOPos filePosition);\nextern void cppMacroArgDelete (void *macroArg);\nextern cppMacroTokens *cppExpandMacro (cppMacroInfo * macro, const ptrArray *args,\n\t\t\t\t\t\t\t\t\t   unsigned long lineNumber, MIOPos filePosition);\nextern vString *cppExpandMacroAsNewString (cppMacroInfo * macro, const ptrArray *args);\n\nextern unsigned long cppGetInputLineNumber (void);\nextern MIOPos cppGetInputFilePosition (void);\n\n#ifdef DEBUG\nextern vString *cppFlattenMacroTokensToNewString (cppMacroTokens *tokens);\nextern void cppDebugPutc (const int level, const int c);\n#endif\n\n#endif  /* CTAGS_MAIN_GET_H */\n"
  },
  {
    "path": "parsers/x-frontmatter.h",
    "content": "/*\n *   Copyright (c) 2022, Masatake YAMATO <yamato@redhat.com>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   Frontmatter parser interface exported to the other parsers\n */\n\n#ifndef CTAGS_FRONTMATTER_H\n#define CTAGS_FRONTMATTER_H\n\n#include \"general.h\"\n\ntypedef enum {\n\tFRONTMATTER_TITLE_KIND,\n} frontmatterKind;\n\n#endif\n"
  },
  {
    "path": "parsers/x-html.h",
    "content": "/*\n*\n* Copyright (c) 2025, Red Hat, Inc.\n* Copyright (c) 2025, Masatake YAMATO\n*\n* Author: Masatake YAMATO <yamato@redhat.com>\n*\n* This program is free software; you can redistribute it and/or\n* modify it under the terms of the GNU General Public License\n* as published by the Free Software Foundation; either version 2\n* of the License, or (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program; if not, write to the Free Software\n* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n* USA.\n*/\n#ifndef CTAGS_HTML_H\n#define CTAGS_HTML_H\n\nextern void htmlParseJSXElement (void);\n\n#endif\n"
  },
  {
    "path": "parsers/x-iniconf.h",
    "content": "/*\n*\n*   Copyright (c) 2000-2001, Darren Hiebert\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for ini/config files.\n*/\n\n/*\n *  This is based on geany's conf.c:\n * --------------------------------\n * commit 3af538fa65f8b17897259080db8144b1edc43470\n * Author: Enrico Tröger <enrico.troeger@uvena.de>\n * Date:   Sun Nov 27 20:39:57 2005 +0000\n *\n * added tag support for filetype Conf\nlang *\n *\n * git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@15 ea778897-0a13-0410-b9d1-a72fbfd435f5\n *\n */\n\n#ifndef CTAGS_INITCONF_H\n#define CTAGS_INITCONF_H\n\n#include \"general.h\"\n\n#include \"subparser.h\"\n\ntypedef struct sIniconfSubparser iniconfSubparser;\nstruct sIniconfSubparser {\n\tsubparser subparser;\n\n\tbool  (* probeLanguage)  (const char *section, const char *key, const char *value);\n\tvoid  (* newDataNotify)  (iniconfSubparser *s,\n\t\t\t\t\t\t\t  const char *section, const char *key, const char *value);\n};\n\n#endif\n"
  },
  {
    "path": "parsers/x-jscript.h",
    "content": "/*\n * Copyright (c) 2003, Darren Hiebert\n *\n * This source code is released for free distribution under the terms of the\n * GNU General Public License version 2 or (at your option) any later version.\n *\n * This module contains functions for generating tags for JavaScript language\n * files.\n */\n\n#ifndef CTAGS_JSCRIPT_H\n#define CTAGS_JSCRIPT_H\n\ntypedef enum {\n\tJSTAG_FUNCTION,\n\tJSTAG_CLASS,\n\tJSTAG_METHOD,\n\tJSTAG_PROPERTY,\n\tJSTAG_CONSTANT,\n\tJSTAG_VARIABLE,\n\tJSTAG_GENERATOR,\n\tJSTAG_GETTER,\n\tJSTAG_SETTER,\n\tJSTAG_FIELD,\n\tJSTAG_COUNT\n} jsKind;\n\ntypedef enum {\n\tJSTAG_FUNCTIONRoleFOREIGNDECL\n} JSTAGFunctionRole;\n\n/* Skip over { ... } */\nvoid javaScriptSkipObjectExpression (void);\n\n#endif\n"
  },
  {
    "path": "parsers/x-lisp.h",
    "content": "/*\n *   Copyright (c) 2011, Colomban Wendling <colomban@geany.org>\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   List meata parser interface exported to the other lisp families\n */\n\n#ifndef CTAGS_LISP_H\n#define CTAGS_LISP_H\n\n#include \"general.h\"\n\n#include \"field.h\"\n\nstruct lispIsDefResult {\n\tbool is_def;\n\tint kind;\n};\n\nstruct lispKindHint {\n\tvString * str;\n\tstruct lispIsDefResult isDefResult;\n};\n\nstruct lispDialect {\n\tint (* definer2kind) (struct lispKindHint *hint, const char *namespace);\n\tbool case_insensitive;\n\tunsigned char namespace_sep;\n\tint unknown_kind;\n\tfieldDefinition *definer_field;\n\tbool skip_initial_spaces;\n\tbool lambda_syntax_sugar;\n\tstruct lispIsDefResult (* is_def) (struct lispDialect *, const unsigned char *);\n\tint (* get_it) (struct lispDialect *,\n\t\t\t\t\tvString *const, const unsigned char *, struct lispKindHint *,\n\t\t\t\t\tconst char *);\n\tint scope;\n};\n\nvoid findLispTagsCommon (struct lispDialect *dialect);\n\nint lispGetIt (struct lispDialect *dialect,\n\t\t\t   vString *const name, const unsigned char *dbp, struct lispKindHint *kind_hint,\n\t\t\t   const char *namespace);\nstruct lispIsDefResult lispIsDef (struct lispDialect *dialect, const unsigned char *strp);\n\n#endif\t/* CTAGS_LISP_H */\n"
  },
  {
    "path": "parsers/x-m4.h",
    "content": "/*\n*   Copyright (c) 2016, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for makefiles.\n*/\n\n#ifndef CTAGS_PARSER_M4_H\n#define CTAGS_PARSER_M4_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n#include \"types.h\"\n#include \"subparser.h\"\n#include \"vstring.h\"\n#include \"numarray.h\"\n\ntypedef struct sM4Subparser m4Subparser;\nstruct sM4Subparser {\n\tsubparser subparser;\n\n\tbool (* probeLanguage) (m4Subparser *m4, const char* token);\n\n\t/* return value: Cork index */\n\tint  (* newMacroNotify) (m4Subparser *m4, const char* token);\n\n\tbool (* doesLineCommentStart)   (m4Subparser *m4, int c, const char *token);\n\tbool (* doesStringLiteralStart) (m4Subparser *m4, int c);\n\n\tbool (* doesWantToParseInsideQuotes) (m4Subparser *m4, intArray *indexStack);\n};\n\n/* Helpers functions */\nextern bool readM4MacroArgument(vString *const arg);\nextern void setM4Quotes(char openQuote, char closeQuote);\n\n#endif\n"
  },
  {
    "path": "parsers/x-make.h",
    "content": "/*\n*   Copyright (c) 2016, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for makefiles.\n*/\n\n#ifndef CTAGS_PARSER_MAKE_H\n#define CTAGS_PARSER_MAKE_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n#include \"vstring.h\"\n\ntypedef struct sMakeSubparser makeSubparser;\n\nstruct sMakeSubparser {\n\tsubparser subparser;\n\n\tvoid (* valueNotify) (makeSubparser *s, char* name);\n\tvoid (* directiveNotify) (makeSubparser *s, char* name);\n\tvoid (* newMacroNotify) (makeSubparser *s,\n\t\t\t\t\t\t\t char* name,\n\t\t\t\t\t\t\t bool withDefineDirective,\n\t\t\t\t\t\t\t bool appending,\n\t\t\t\t\t\t\t /* If the macro is found in a define/endef area. */\n\t\t\t\t\t\t\t int scopeIndex);\n};\n\n#endif\n"
  },
  {
    "path": "parsers/x-markdown.h",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   The interface for subparsers of Markdown\n*/\n#ifndef CTAGS_PARSER_MARKDOWN_H\n#define CTAGS_PARSER_MARKDOWN_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n#include \"vstring.h\"\n\ntypedef struct sMarkdownSubparser markdownSubparser;\n\nstruct sMarkdownSubparser {\n\tsubparser subparser;\n\t/* ```something\n\t   ---^ The rest of string is passed as LANGMARKER.\n\n\t   A sub parser analyses LANGMARKER.\n\t   If the sub parser can extract a name of language from LANGMARKER,\n\t   the parser puts the name to LANGNAME, and returns true.\n\t   If not, return false.\n\n\t   e.g.\n\n\t   ```{python}\n\n\t   Fot this input, ctags pases \"{python}\" as LANGMARKER. */\n\tbool (* extractLanguageForCodeBlock) (markdownSubparser *s,\n\t\t\t\t\t\t\t\t\t\t  const char *langMarker,\n\t\t\t\t\t\t\t\t\t\t  vString *langName);\n\n\t/* ```something\n\t   ...\n\t   <code block>\n\t   ...\n\t   ```\n\n\t   ctags passes each LINE in the code block to the sub parser\n\t   that returns true when ctags calls extractLanguageForCodeBlock()\n\t   with the sub parser. */\n\tvoid (* notifyCodeBlockLine) (markdownSubparser *s,\n\t\t\t\t\t\t\t\t  const unsigned char *line);\n\n\t/* ```something\n\t   ...\n\t   codeblock\n\t   ...\n\t   ```\n\t   ^ The end of code block.\n\n\t   ctags notifies the sub parser that the end of code block\n\t   is found.\n\t*/\n\tvoid (* notifyEndOfCodeBlock) (markdownSubparser *s);\n};\n\n#endif\n"
  },
  {
    "path": "parsers/x-perl.h",
    "content": "/*\n*   Copyright (c) 2019, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n#ifndef CTAGS_PARSER_PERL_H\n#define CTAGS_PARSER_PERL_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n\ntypedef struct sPerlSubparser perlSubparser;\n\nenum PerlModuleRoleType {\n\tROLE_PERL_MODULE_USED,\n\tROLE_PERL_MODULE_UNUSED,\n};\n\nenum PerlKindType {\n\tKIND_PERL_NONE = -1,\n\tKIND_PERL_CONSTANT,\n\tKIND_PERL_FORMAT,\n\tKIND_PERL_LABEL,\n\tKIND_PERL_PACKAGE,\n\tKIND_PERL_SUBROUTINE,\n\tKIND_PERL_SUBROUTINE_DECLARATION,\n\tKIND_PERL_MODULE,\n\tKIND_PERL_HEREDOCMARKER,\n};\n\nstruct sPerlSubparser {\n\tsubparser subparser;\n\tvoid (* findingQuotedWordNotify) (perlSubparser *,\n\t\t\t\t\t\t\t\t\t  int moduleIndex,\n\t\t\t\t\t\t\t\t\t  const char *qwd);\n\tvoid (* enteringPodNotify) (perlSubparser *);\n\tvoid (* leavingPodNotify)    (perlSubparser *);\n};\n\n#endif\t/* CTAGS_PARSER_PERL_H */\n"
  },
  {
    "path": "parsers/x-python.h",
    "content": "/*\n*   Copyright (c) 2000-2003, Darren Hiebert\n*   Copyright (c) 2014-2016, Colomban Wendling <ban@herbesfolles.org>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef CTAGS_PARSER_PYTHON_H\n#define CTAGS_PARSER_PYTHON_H\n\ntypedef enum {\n\tPYTHON_CLASS_KIND,\n\tPYTHON_FUNCTION_KIND,\n\tPYTHON_METHOD_KIND,\n\tPYTHON_VARIABLE_KIND,\n\tPYTHON_NAMESPACE_KIND,\n\tPYTHON_MODULE_KIND,\n\tPYTHON_UNKNOWN_KIND,\n\tPYTHON_PARAMETER_KIND,\n\tPYTHON_LOCAL_VARIABLE_KIND,\n\tPYTHON_COUNT_KIND\n} pythonKind;\n\ntypedef enum {\n\tPYTHON_MODULE_IMPORTED,\n\tPYTHON_MODULE_NAMESPACE,\n\tPYTHON_MODULE_INDIRECTLY_IMPORTED,\n\tPYTHON_MODULE_ENTRY_POINT,\n} pythonModuleRole;\n\ntypedef enum {\n\tPYTHON_FUNCTION_ENTRY_POINT,\n} pythonFunctionRole;\n\n#endif\t/* CTAGS_PARSER_PYTHON_H */\n"
  },
  {
    "path": "parsers/x-r.h",
    "content": "/*\n*   Copyright (c) 2003-2004, Ascher Stefan <stievie@utanet.at>\n*   Copyright (c) 2020, Masatake YAMATO\n*   Copyright (c) 2020, Red Hat, Inc.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef CTAGS_PARSER_R_H\n#define CTAGS_PARSER_R_H\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n#include \"tokeninfo.h\"\n#include \"entry.h\"\n\n\n/*\n*   DATA DECLARATIONS\n*/\n\ntypedef struct sRSubparser rSubparser;\n\nenum RTokenType {\n\t/* 0..255 are the byte's values */\n\tTOKEN_R_EOF = 256,\n\tTOKEN_R_UNDEFINED,\n\tTOKEN_R_KEYWORD,\n\tTOKEN_R_NEWLINE,\n\tTOKEN_R_NUMBER,\t\t\t\t/* 1, 1L */\n\tTOKEN_R_SYMBOL,\t\t\t\t/* [0-9a-zA-Z._] */\n\tTOKEN_R_STRING,\n\tTOKEN_R_OPERATOR,\t\t\t\t/* - + ! ~ ? : * / ^ %...%, <, > ==\n\t\t\t\t\t\t\t\t * >=, <=, &, &&, |, || */\n\tTOKEN_R_DOTS,\t\t\t\t\t/* ... */\n\tTOKEN_R_DOTS_N,\t\t\t\t/* ..1, ..2, etc */\n\tTOKEN_R_LASSIGN,\t\t\t\t/* <-, <<- */\n\tTOKEN_R_RASSIGN,\t\t\t\t/* ->, ->> */\n\tTOKEN_R_SCOPE,\t\t\t\t/* ::, ::: */\n};\n\nenum eRKeywordId\n{\n\tKEYWORD_R_C,\n\tKEYWORD_R_DATAFRAME,\n\tKEYWORD_R_FUNCTION,\n\tKEYWORD_R_IF,\n\tKEYWORD_R_ELSE,\n\tKEYWORD_R_FOR,\n\tKEYWORD_R_WHILE,\n\tKEYWORD_R_REPEAT,\n\tKEYWORD_R_IN,\n\tKEYWORD_R_NEXT,\n\tKEYWORD_R_BREAK,\n\tKEYWORD_R_TRUE,\n\tKEYWORD_R_FALSE,\n\tKEYWORD_R_NULL,\n\tKEYWORD_R_INF,\n\tKEYWORD_R_LIST,\n\tKEYWORD_R_NAN,\n\tKEYWORD_R_NA,\n\tKEYWORD_R_SOURCE,\n\tKEYWORD_R_LIBRARY,\n};\n\nstruct sRSubparser {\n\tsubparser subparser;\n\tint (* readRightSideSymbol) (rSubparser *s,\n\t\t\t\t\t\t\t\t tokenInfo *const symbol,\n\t\t\t\t\t\t\t\t const char *const assignmentOperator,\n\t\t\t\t\t\t\t\t int parent,\n\t\t\t\t\t\t\t\t tokenInfo *const token);\n\tint (* makeTagWithTranslation) (rSubparser *s,\n\t\t\t\t\t\t\t\t\ttokenInfo *const token,\n\t\t\t\t\t\t\t\t\tint parent,\n\t\t\t\t\t\t\t\t\tbool in_func,\n\t\t\t\t\t\t\t\t\tint kindInR,\n\t\t\t\t\t\t\t\t\tconst char *const assignmentOperator);\n\tbool (* askTagAcceptancy) (rSubparser *s, tagEntryInfo *pe);\n\tbool (* hasFunctionAlikeKind) (rSubparser *s, tagEntryInfo *pe);\n\tint (* readFuncall) (rSubparser *s,\n\t\t\t\t\t\t tokenInfo *const func,\n\t\t\t\t\t\t tokenInfo *const token,\n\t\t\t\t\t\t int parent);\n};\n\nextern void rSetupCollectingSignature (tokenInfo *const token,\n\t\t\t\t\t\t\t\t\t   vString   *signature);\nextern void rTeardownCollectingSignature (tokenInfo *const token);\n\n/*\n * FUNCTION PROTOTYPES\n */\n\nextern tokenInfo *rNewToken (void);\n\nextern void rTokenReadNoNewline (tokenInfo *const token);\n\n/* This function returns true if a new token is read.\n * EOF is exception. If EOF is read, this function returns FALSE. */\nextern bool rParseStatement (tokenInfo *const token, int parentIndex, bool inArgList);\n\nextern vString *rExtractNameFromString (vString* str);\n\n#endif\t/* CTAGS_PARSER_TEX_H */\n"
  },
  {
    "path": "parsers/x-ruby.h",
    "content": "/*\n*   Copyright (c) 2000-2001, Thaddeus Covert <sahuagin@mediaone.net>\n*   Copyright (c) 2002 Matthias Veit <matthias_veit@yahoo.de>\n*   Copyright (c) 2004 Elliott Hughes <enh@acm.org>\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for Ruby language\n*   files.\n*/\n\n#ifndef CTAGS_PARSER_RUBY_H\n#define CTAGS_PARSER_RUBY_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n\ntypedef struct sRubySubparser rubySubparser;\n\ntypedef enum {\n\tRUBY_CLASS_KIND,\n\tRUBY_METHOD_KIND,\n\tRUBY_MODULE_KIND,\n\tRUBY_SINGLETON_KIND,\n\tRUBY_CONST_KIND,\n\tRUBY_ACCESSOR_KIND,\n\tRUBY_ALIAS_KIND,\n\tRUBY_LIBRARY_KIND,\n} rubyKind;\n\nstruct sRubySubparser {\n\tsubparser subparser;\n\t/* Returning other than CORK_NIL means the string is consumed. */\n\tint (* lineNotify) (rubySubparser *s, const unsigned char **cp, int corkIndex);\n\tvoid (* enterBlockNotify) (rubySubparser *s, int corkIndex);\n\tvoid (* leaveBlockNotify) (rubySubparser *s, int corkIndex);\n\t/* Privately used in Ruby parser side. */\n\tint corkIndex;\n};\n\n/* Return true if it skips something. */\nextern bool rubySkipWhitespace (const unsigned char **cp);\n\nextern bool rubyCanMatchKeyword (const unsigned char** s, const char* literal);\nextern bool rubyCanMatchKeywordWithAssign (const unsigned char** s, const char* literal);\n\n/* rubyParseString() moves the *CP to the char just after the string literal started from\n * BOUNDARY (' or \"). The string with no BOUNDARY is stored to VSTR.\n * You can use rubyParseString() just for skipping if you specify NULL as VSTR.\n\n * rubyParseString() returns false if **s is '\\0' else true.\n * NOTE: even if the string is not terminated with BOUNDARY, the function moves *cp\n * and returns true. */\nextern bool rubyParseString (const unsigned char** cp, unsigned char boundary, vString* vstr);\nextern bool rubyParsePercentString (const unsigned char** cp, vString* vstr);\n\nextern bool rubyParseMethodName (const unsigned char **cp, vString* vstr);\nextern bool rubyParseModuleName (const unsigned char **cp, vString* vstr);\n\n#endif\n"
  },
  {
    "path": "parsers/x-sh.h",
    "content": "/*\n*   Copyright (c) 2022, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef CTAGS_PARSER_SH_H\n#define CTAGS_PARSER_SH_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n#include \"vstring.h\"\n\ntypedef struct sShSubparser shSubparser;\n\nstruct sShSubparser {\n\tsubparser subparser;\n\n\t/* Scan the line pointed by CP and return the number of\n\t * consumed bytes if something interesting is found.\n\t * Return 0 if no interest.\n\t */\n\tint (* lineNotify) (shSubparser *s, const unsigned char *cp);\n\n\t/* Extract the interesting item from CP and store it to NAME.\n\t * Return the number of consumed bytes during extracting.\n\t */\n\tint (* extractName) (shSubparser *s, const unsigned char *cp,\n\t\t\t\t\t\t vString *name);\n\n\t/* Make a tag for NAME.\n\t * Return the cork index for the tag.\n\t */\n\tint (* makeTag) (shSubparser *s, vString *name);\n};\n\n#endif\t/* CTAGS_PARSER_SH_H */\n"
  },
  {
    "path": "parsers/x-systemdunit.h",
    "content": "/*\n*\n*   Copyright (c) 2015, Red Hat, Inc.\n*   Copyright (c) 2015, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*/\n\n#ifndef CTAGS_SYSTEMDUNIT_H\n#define CTAGS_SYSTEMDUNIT_H\n\n#include \"general.h\"\n\ntypedef enum {\n\tSYSTEMD_UNIT_KIND,\n} systemdUnitKind;\n\ntypedef enum {\n\tSYSTEMD_UNIT_Requires_ROLE,\n\tSYSTEMD_UNIT_Wants_ROLE,\n\tSYSTEMD_UNIT_After_ROLE,\n\tSYSTEMD_UNIT_Before_ROLE,\n\tSYSTEMD_UNIT_RequiredBy_ROLE,\n\tSYSTEMD_UNIT_WantedBy_ROLE,\n\tSYSTEMD_UNIT_FOREIGNLANG_ROLE,\n} systemdUnitRole;\n\n#endif\t/* CTAGS_SYSTEMDUNIT_H */\n"
  },
  {
    "path": "parsers/x-tcl.h",
    "content": "/*\n*   Copyright (c) 2017, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef CTAGS_PARSER_TCL_H\n#define CTAGS_PARSER_TCL_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n#include \"tokeninfo.h\"\n\ntypedef struct sTclSubparser tclSubparser;\n\nenum TclTokenType {\n\t/* 0..255 are the byte's value */\n\tTOKEN_TCL_EOF = 256,\n\tTOKEN_TCL_UNDEFINED,\n\tTOKEN_TCL_KEYWORD,\n\tTOKEN_TCL_IDENTIFIER,\n\tTOKEN_TCL_VARIABLE,\n\tTOKEN_TCL_EOL,\n\tTOKEN_TCL_STRING,\n};\n\nstruct sTclSubparser {\n\tsubparser subparser;\n\n\t/* `pstate' is needed to call newTclToken(). */\n\tvoid (* namespaceImportNotify) (tclSubparser *s, char *namespace,\n\t\t\t\t\t\t\t\t\tvoid *pstate);\n\t/* Return CORK_NIL if the command line is NOT consumed.\n\t   If a positive integer is returned, end: field may\n\t   be attached by tcl base parser.\n\t   Return CORK_NIL - 1 if the command line is consumed\n\t   but not tag is made. */\n\tint (* commandNotify) (tclSubparser *s, char *command,\n\t\t\t\t\t\t   int parentIndex,\n\t\t\t\t\t\t   void *pstate);\n};\n\nextern tokenInfo *newTclToken (void *pstate);\nextern void skipToEndOfTclCmdline (tokenInfo *const token);\n\n#endif\t/* CTAGS_PARSER_TCL_H */\n"
  },
  {
    "path": "parsers/x-tex.h",
    "content": "/*\n*   Copyright (c) 2020, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   Tex base parser interface exported to subparsers\n*/\n\n#ifndef CTAGS_PARSER_TEX_H\n#define CTAGS_PARSER_TEX_H\n\n/*\n*\t INCLUDE FILES\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n#include \"vstring.h\"\n\n\n/*\n*\t DATA DEFINITIONS\n*/\n\n/* Parsing strategy */\n\nenum TexNameFlag {\n\t/* Allow that the type of input token doesn't match\n\t * the type of strategy. In stread of aborting,\n\t * apply the next strategy to the same token. */\n\tTEX_NAME_FLAG_OPTIONAL             = (1 << 0),\n\n\t/* When reading tokens inside pair,\n\t * whitespaces are considered as parts of a token or not. */\n\tTEX_NAME_FLAG_INCLUDING_WHITESPACE = (1 << 1),\n\n\t/* If a tag is created with this strategy, don't\n\t * create a tag in its successor strategies. */\n\tTEX_NAME_FLAG_EXCLUSIVE            = (1 << 2),\n};\n\nstruct TexParseStrategy {\n\t/* Expected token type '<', '[', '*', '{', and '\\\\' are supported.\n\t * 0 means the end of strategies. '\\\\' means {} pair may be omitted.\n\t *\n\t * A string between <>, [], or {} (pairs) can be tagged or store to\n\t * a vString. See kindIndex and name field of this structure.\n\t */\n\tint type;\n\n\t/* Bits combination of enum TexNameFlag */\n\tunsigned int flags;\n\n\t/* Kind and role for making a tag for the string surrounded by one of pairs.\n\t * If you don't need to make a tag for the string,\n\t * specify KIND_GHOST_INDEX. */\n\tint kindIndex;\n\tint roleIndex;\n\n\t/* If a tag is made, Tex parser stores its cork index here. */\n\tint corkIndex;\n\n\t/* Store the string surrounded by one of paris.\n\t * If you don't need to store the string, set NULL here. */\n\tvString *name;\n\n\t/* If true, make at most one tag for the name in the scope specified\n\t * with scopeIndex. When making a tag, scopeIndex is set to\n\t * extensionFields.scopeIndex only if unique is true.\n\t * scopeIndex is never referred if unique if false. */\n\tbool unique;\n\tint scopeIndex;\n};\n\ntypedef struct sTexSubparser texSubparser;\nstruct sTexSubparser {\n\tsubparser subparser;\n\n\t/* When Tex parser reads an \\begin{foo}, it calls\n\t * this method.\n\t *\n\t * A subparser having interests in successor tokens may return strategies.\n\t * If it doesn't, just return NULL; Tex base parser may call the next subparser.\n\t */\n\tstruct TexParseStrategy * (* readEnviromentBeginNotify) (texSubparser *s,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t vString *env);\n\t/* When Tex parser reads an \\end{foo}, it calls\n\t * this method.\n\t *\n\t * If this method returns true, Tex base parser may call the next subparser.\n\t * If it returns false, Tex base parser stops calling the rest of subparsers.\n\t */\n\tbool (* readEnviromentEndNotify) (texSubparser *s, vString *env);\n\n\t/* When Tex parser reads an \\identifier, it calls\n\t * this method.\n\t *\n\t * A subparser having interests in successor tokens may return strategies.\n\t * If it has no interest, just return NULL; Tex base parser may call next subparser.\n\t */\n\tstruct TexParseStrategy *(* readIdentifierNotify) (texSubparser *s,\n\t\t\t\t\t\t\t\t\t\t\t\t\t   vString *identifier);\n\n\t/* After Tex parser runs the strategies returned from readIdentifierNotify\n\t * method, Tex parser calls this method to notify the subparser the result\n\t * of running the strategies; corkIndex and/or name fields of strategies\n\t * may be filled. */\n\tvoid (* reportStrategicParsing) (texSubparser *s,\n\t\t\t\t\t\t\t\t\t const struct TexParseStrategy *strategy);\n};\n\n#endif\t/* CTAGS_PARSER_TEX_H */\n"
  },
  {
    "path": "parsers/x-toml.h",
    "content": "/*\n*   Copyright (c) 2024, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for TOML files.\n*/\n#ifndef CTAGS_PARSER_TOML_H\n#define CTAGS_PARSER_TOML_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n#include \"numarray.h\"\n\ntypedef enum {\n\tTOML_K_KEY,\n\tTOML_K_TABLE,\n\tTOML_K_ARRAYTABLE,\n\tTOML_K_QKEY,\n} tomlKind;\n\ntypedef enum {\n\tTOML_R_KEY_CHAINELT,\n} tomlKeyRole;\n\ntypedef struct sTomlSubparser tomlSubparser;\n\nstruct sTomlSubparser {\n\tsubparser subparser;\n\n\tvoid (* valueNotify) (tomlSubparser *sub, const char *value, long offset, int corkIndex);\n};\n\n#endif\t/* CTAGS_PARSER_TOML_H */\n"
  },
  {
    "path": "parsers/x-xml.h",
    "content": "/*\n*   Copyright (c) 2019, Red Hat, Inc.\n*   Copyright (c) 2019, Masatake YAMATO\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*/\n\n#ifndef CTAGS_PARSER_XML_H\n#define CTAGS_PARSER_XML_H\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"subparser.h\"\n#include \"lxpath.h\"\n\n/*\n*\t DATA DECLARATIONS\n*/\n\ntypedef struct sXmlSubparser xmlSubparser;\nstruct sXmlSubparser {\n\tsubparser subparser;\n\n\t/* Similar to makeTagEntryNotify method of subparser.\n\t * However, makeTagEntryWithNodeNotify passes the xml node\n\t * just found to subparsers.\n\t */\n\tvoid (* makeTagEntryWithNodeNotify) (xmlSubparser *s,\n\t\t\t\t\t\t\t\t\t\t xmlNode *node, tagEntryInfo *xmlTag);\n\n\t/* A subparser should call findXMLTags() in the callback function\n\t * assigned to this field. The XML base parser prepares CTX and ROOT.\n\t * A subparser may pass the CTX and ROOT to findXMLTags().\n\t * The XML base parser tags id= and namespace related attributes before\n\t * calling this hook. CTX and ROOT are already used once by\n\t * the XML base parser for tagging id= and namespace related attributes.\n\t * The resource life cycle of CTX and ROOT is managed by the base parser.\n\t */\n\tvoid (* runXPathEngine) (xmlSubparser *s,\n\t\t\t\t\t\t\t xmlXPathContext *ctx, xmlNode *root);\n};\n\n#endif /* CTAGS_PARSER_XML_H */\n"
  },
  {
    "path": "parsers/x-yaml.h",
    "content": "/*\n *\n *   Copyright (c) 2016, Masatake YAMATO\n *   Copyright (c) 2016, Red Hat, K.K.\n *   Copyright (c) 2022, Vasily Kulikov\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n */\n\n#ifndef CTAGS_YAML__H\n#define CTAGS_YAML__H\n\n#include \"general.h\"\n#include \"subparser.h\"\n#include \"types.h\"\n\n#ifdef HAVE_LIBYAML\n#include <yaml.h>\n#else\n#define yaml_token_t void\n#endif\n\nstruct ypathTypeStack;\n\ntypedef struct sYamlSubparser yamlSubparser;\nstruct sYamlSubparser {\n\tsubparser subparser;\n\tvoid (* newTokenNotfify) (yamlSubparser *s, yaml_token_t *token);\n\n\tvoid (* enterBlockNotify) (yamlSubparser *s, yaml_token_t *token);\n\tvoid (* leaveBlockNotify) (yamlSubparser *s, yaml_token_t *token);\n\tvoid (* makeTagEntryNotifyViaYpath) (yamlSubparser *s, int corkIndex);\n\n\tstruct sTagYpathTable *ypathTables;\n\tsize_t ypathTableCount;\n\n\tbool compiled;\n\tstruct ypathTypeStack *ypathTypeStack;\n\tenum ypathDetectingState {\n\t\tYPATH_DSTAT_LAST_KEY,\n\t\tYPATH_DSTAT_LAST_VALUE,\n\t\tYPATH_DSTAT_INITIAL,\n\t} detectionState;\n};\n\n#define YAML(S) ((yamlSubparser *)S)\n\nextern void attachYamlPosition (tagEntryInfo *tag, yaml_token_t *token, bool asEndPosition);\nextern size_t ypathGetTypeStackDepth (yamlSubparser *yaml);\n\n/*\n * Experimental Ypath code\n */\ntypedef struct sTagYpathTable {\n\tconst char * ypath;\n\tint expected_state;\n\t/* If INITTAGENTRY filed is non-NULL, call it for initializing\n\t * a tagEntry. If it is NULL, initializing the tagEntry in usual way:\n\t * call initTagEntry() defined in the main part with KIND. */\n\tint kind;\n\tbool (* initTagEntry) (tagEntryInfo *, yamlSubparser *, char *, void *);\n\tvoid *data;\n\tvoid *code;\t\t\t\t\t/* YAML base parser private */\n} tagYpathTable;\n\nextern void ypathPrintTypeStack(yamlSubparser *yaml);\n#endif\n"
  },
  {
    "path": "parsers/xml.c",
    "content": "/*\n*\n*   Copyright (c) 2019, Masatake YAMATO\n*   Copyright (c) 2019, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for id=\"...\" in a XML file\n*/\n\n#include \"general.h\"\t/* must always come first */\n#include \"entry.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"subparser.h\"\n#include \"x-xml.h\"\n\nstatic void makeTagWithNotification (xmlNode *node,\n\t\t\t\t\t\t\t\t\t const char *xpath,\n\t\t\t\t\t\t\t\t\t const tagXpathMakeTagSpec *spec,\n\t\t\t\t\t\t\t\t\t tagEntryInfo *tag,\n\t\t\t\t\t\t\t\t\t void *userData);\n\ntypedef enum {\n\tK_ID,\n\tK_NSPREFIX,\n\tK_ROOT,\n} xmlKind;\n\n#define ROOT_ELT_LETTER 'r'\nstatic const char ROOT_ELT_LETTER_STR[2] = {ROOT_ELT_LETTER, '\\0'};\nstatic kindDefinition XmlKinds [] = {\n\t{ true, 'i', \"id\", \"id attributes\" },\n\t{ true, 'n', \"nsprefix\", \"namespace prefixes\" },\n\t{ true, ROOT_ELT_LETTER, \"root\", \"root elements\" },\n};\n\nenum xmlXpathTables {\n\tTABLE_MAIN,\n\tTABLE_ID,\n};\n\ntypedef enum {\n\tF_NS_URI,\n} xmlField;\n\nstatic fieldDefinition XmlFields [] = {\n\t{\n\t\t.name = \"uri\",\n\t\t.description = \"uri associated with name prefix\",\n\t\t.enabled = true,\n\t}\n};\n\nstatic void findNsPrefix (xmlNode *node,\n\t\t\t\t\t   const char *xpath,\n\t\t\t\t\t   const struct sTagXpathRecurSpec *spec,\n\t\t\t\t\t   xmlXPathContext *ctx,\n\t\t\t\t\t   void *userData);\n\nstatic tagXpathTable XmlXpathMainTable [] = {\n\t{ \"//*\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { .enter = findNsPrefix, .nextTable = TABLE_ID } }\n\t},\n};\n\nstatic tagXpathTable XmlXpathIdTable [] = {\n\t{ \"./@id\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = { K_ID, ROLE_DEFINITION_INDEX,\n\t\t\t\t\t\t .make = makeTagWithNotification,} }\n\t},\n};\n\nstatic tagXpathTableTable xmlXpathTableTable[] = {\n\t[TABLE_MAIN] = { ARRAY_AND_SIZE (XmlXpathMainTable) },\n\t[TABLE_ID]   = { ARRAY_AND_SIZE (XmlXpathIdTable) },\n};\n\n/* Pick up the root element specifier from \"<!DOCTYPE...\", and\n * run DTD parser for the \"[\" ... \"]>\" area.\n *\n * optlib2c translates the following .ctags elements:\n * ==========================================================\n * --langdef=Xml\n * --kinddef-Xml=r,root,root elements\n * --mline-regex-Xml=/<!DOCTYPE[[:space:]]+([a-zA-Z0-9]+)[[:space:]]+[^[]+\\[((.|[\\n])+)\\]>/\\1/r/{mgroup=1}{_guest=DTD,2start,2end}\n * ==========================================================\n */\nstatic tagRegexTable XmlTagRegexTable [] = {\n\t{\"<!DOCTYPE[[:space:]]+([a-zA-Z0-9]+)[[:space:]]+[^[]*\\\\[((.|[\\n])+)\\\\]>\", \"\\\\1\",\n\t ROOT_ELT_LETTER_STR, \"{mgroup=1}{_guest=DTD,2start,2end}\", NULL, true},\n};\n\nstatic int makeTagWithNotificationCommon (tagEntryInfo *tag,\n\t\t\t\t\t\t\t\t\t\t   xmlNode *node)\n{\n\tint n = makeTagEntry (tag);\n\n\tsubparser *sub;\n\tforeachSubparser (sub, false)\n\t{\n\t\txmlSubparser *xmlsub = (xmlSubparser *)sub;\n\n\t\tif (xmlsub->makeTagEntryWithNodeNotify)\n\t\t{\n\t\t\tenterSubparser(sub);\n\t\t\txmlsub->makeTagEntryWithNodeNotify (xmlsub, node, tag);\n\t\t\tleaveSubparser();\n\t\t}\n\t}\n\treturn n;\n}\n\nstatic void makeTagWithNotification (xmlNode *node,\n\t\t\t\t\t\t\t\t\t const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t const tagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t tagEntryInfo *tag,\n\t\t\t\t\t\t\t\t\t void *userData CTAGS_ATTR_UNUSED)\n{\n\tmakeTagWithNotificationCommon (tag, node);\n}\n\nstatic int makeNsPrefixTag (const char *name, xmlNode *node, xmlNsPtr ns)\n{\n\tint n = CORK_NIL;\n\ttagEntryInfo tag;\n\tvString *anon = NULL;\n\n\tif (name)\n\t\tinitTagEntry (&tag, name, K_NSPREFIX);\n\telse\n\t{\n\t\tanon = anonGenerateNew (\"ns\", K_NSPREFIX);\n\t\tinitTagEntry (&tag, vStringValue (anon), K_NSPREFIX);\n\t\tmarkTagExtraBit (&tag, XTAG_ANONYMOUS);\n\t}\n\n\t/* TODO\n\t * - adjust the line number for nsprefixes forward. */\n\tupdateXMLTagLine (&tag, node);\n\tchar *p = (char *)xmlGetNodePath (node);\n\tif (ns->href && *ns->href)\n\t\tattachParserField (&tag, XmlFields [F_NS_URI].ftype, (char *)ns->href);\n\n\tn = makeTagWithNotificationCommon (&tag, node);\n\tif (p)\n\t\txmlFree (p);\n\tif (anon)\n\t\tvStringDelete (anon);\n\n\treturn n;\n}\n\nstatic void findNsPrefix (xmlNode *node,\n\t\t\t\t\t   const char *xpath,\n\t\t\t\t\t   const struct sTagXpathRecurSpec *spec,\n\t\t\t\t\t   xmlXPathContext *ctx,\n\t\t\t\t\t   void *userData)\n{\n\tfor (xmlNsPtr ns = node->nsDef; ns; ns = ns->next)\n\t\tmakeNsPrefixTag ((char *)ns->prefix, node, ns);\n\n\tfindXMLTags (ctx, node, spec->nextTable, userData);\n}\n\nstatic void runAfter (xmlXPathContext *ctx, xmlNode *root, void *user_data)\n{\n\tsubparser *sub;\n\tforeachSubparser (sub, false)\n\t{\n\t\txmlSubparser *xmlsub = (xmlSubparser *)sub;\n\t\tif (xmlsub->runXPathEngine)\n\t\t{\n\t\t\tenterSubparser(sub);\n\t\t\txmlsub->runXPathEngine (xmlsub, ctx, root);\n\t\t\tleaveSubparser();\n\t\t}\n\t}\n}\n\nstatic void\nfindXmlTags (void)\n{\n\tfindXMLTagsFull (NULL, NULL, TABLE_MAIN, runAfter, NULL);\n}\n\nextern parserDefinition*\nXmlParser (void)\n{\n\tstatic const char *const extensions [] = { \"xml\", NULL };\n\tparserDefinition* const def = parserNew (\"XML\");\n\tstatic selectLanguage selectors[] = { selectByXpathFileSpec, NULL };\n\n\tdef->kindTable     = XmlKinds;\n\tdef->kindCount     = ARRAY_SIZE (XmlKinds);\n\tdef->extensions    = extensions;\n\tdef->parser        = findXmlTags;\n\tdef->tagXpathTableTable = xmlXpathTableTable;\n\tdef->tagXpathTableCount = ARRAY_SIZE (xmlXpathTableTable);\n\tdef->selectLanguage = selectors;\n\tdef->fieldTable = XmlFields;\n\tdef->fieldCount = ARRAY_SIZE (XmlFields);\n\tdef->tagRegexTable = XmlTagRegexTable;\n\tdef->tagRegexCount = ARRAY_SIZE(XmlTagRegexTable);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/xrc.c",
    "content": "/*\n*\n*   Copyright (c) 2023, Masatake YAMATO\n*   Copyright (c) 2023, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for XML Based Resource System (XRC) files\n*\n*   Reference:\n*   - https://docs.wxwidgets.org/3.0/overview_xrc.html\n*/\n\n/*\n *\t INCLUDE FILES\n */\n#include \"general.h\"\t/* must always come first */\n\n#include \"x-xml.h\"\n\n#include \"entry.h\"\n#include \"parse.h\"\n\n/*\n *\t DATA DECLARATIONS\n */\n\ntypedef enum {\n\tK_OBJECT,\n} xrcKind;\n\n/*\n *\t FUNCTION DECLARATIONS\n */\n\nstatic void makeXRCTag (xmlNode *node,\n\t\t\t\t\t\tconst char *xpath,\n\t\t\t\t\t\tconst struct sTagXpathMakeTagSpec *spec,\n\t\t\t\t\t\tstruct sTagEntryInfo *tag,\n\t\t\t\t\t\tvoid *userData);\n\n/*\n *\tDATA DEFINITIONS\n */\n\nstatic kindDefinition XrcKinds [] = {\n\t{ true,  'o', \"object\",\t  \"objects\", }\n};\n\nstatic tagXpathTable xrcXpathMainTable[] = {\n\t{ /* \"//object/@name\", */\n\t\t\"/resource//object/@name\",\n\t\tLXPATH_TABLE_DO_MAKE,\n\t\t{ .makeTagSpec = { K_OBJECT, ROLE_DEFINITION_INDEX, makeXRCTag, } }\n\t},\n};\n\nenum xrcXpathTable {\n\tTABLE_MAIN\n};\n\nstatic tagXpathTableTable xrcXpathTableTable[] = {\n\t[TABLE_MAIN] = { ARRAY_AND_SIZE(xrcXpathMainTable) },\n};\n\n/*\n *\t FUNCTION DEFINITIONS\n */\n\nstatic void makeXRCTag (xmlNode *node,\n\t\t\t\t\t\tconst char *xpath,\n\t\t\t\t\t\tconst struct sTagXpathMakeTagSpec *spec,\n\t\t\t\t\t\tstruct sTagEntryInfo *tag,\n\t\t\t\t\t\tvoid *userData)\n{\n\tif (*tag->name == '\\0')\n\t\treturn;\n\n\tmakeTagEntry (tag);\n}\n\nstatic void\nfindXrcTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nstatic void\nrunXPathEngine(xmlSubparser *s,\n\t\t\t   xmlXPathContext *ctx, xmlNode *root)\n{\n\tfindXMLTags (ctx, root, TABLE_MAIN, NULL);\n}\n\nstatic xmlSubparser xrcSubparser = {\n\t.subparser = {\n\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t},\n\t.runXPathEngine = runXPathEngine,\n};\n\nextern parserDefinition*\nXrcParser (void)\n{\n\tstatic const char *const extensions [] = { \"xrc\", NULL };\n\tparserDefinition* const def = parserNew (\"XRC\");\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"XML\", &xrcSubparser },\n\t};\n\n\tdef->kindTable         = XrcKinds;\n\tdef->kindCount     = ARRAY_SIZE (XrcKinds);\n\tdef->extensions    = extensions;\n\tdef->parser        = findXrcTags;\n\tdef->tagXpathTableTable  = xrcXpathTableTable;\n\tdef->tagXpathTableCount  = ARRAY_SIZE (xrcXpathTableTable);\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/xslt.c",
    "content": "/*\n*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for generating tags for xslt 1.0.\n*   Reference: https://www.w3.org/1999/11/xslt10.dtd\n*\n*/\n\n#include \"general.h\"\t/* must always come first */\n\n#include <string.h>\n\n#include \"entry.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include \"selectors.h\"\n#include \"x-xml.h\"\n\ntypedef enum {\n\tK_STYLESHEET,\n\tK_PARAMETER,\n\tK_MATCHED_TEMPLATE,\n\tK_NAMED_TEMPLATE,\n\tK_VARIABLE,\n\t/* TODO: KEY, DECIMAL-FORMAT, ATTRIBUTE, ATTRIBUTE-SET, ... */\n} xsltKind;\n\ntypedef enum {\n\tR_STYLESHEET_IMPORTED,\n\tR_STYLESHEET_INCLUDED,\n} xsltStylesheetRole;\nstatic roleDefinition XsltStylesheetRoles [] = {\n\t{ true, \"imported\", \"imported\" },\n\t{ true, \"included\", \"included\" },\n};\n\ntypedef enum {\n\tR_PARAMETER_BOUND,\n} xsltParameterRole;\nstatic roleDefinition XsltParameterRoles [] = {\n\t{ true, \"bound\", \"bound to value\" },\n};\n\ntypedef enum {\n\tR_MATCHED_TEMPLATE_APPLIED,\n} xsltMatchedTemplateRole;\nstatic roleDefinition XsltMatchedTemplateRoles [] = {\n\t{ true, \"applied\", \"applied\" },\n};\n\ntypedef enum {\n\tR_NAMED_TEMPLATE_CALLED,\n} xsltNamedTemplateRole;\nstatic roleDefinition XsltNamedTemplateRoles [] = {\n\t{ true, \"called\", \"called\" },\n};\n\n\nstatic kindDefinition XsltKinds [] = {\n\t{ true,  's', \"stylesheet\", \"stylesheets\",\n\t  .referenceOnly = true, ATTACH_ROLES (XsltStylesheetRoles) },\n\t{ true,  'p', \"parameter\", \"parameters\",\n\t  .referenceOnly = false, ATTACH_ROLES (XsltParameterRoles) },\n\t{ true,  'm', \"matchedTemplate\", \"matched template\",\n\t  .referenceOnly = false, ATTACH_ROLES (XsltMatchedTemplateRoles) },\n\t{ true,  'n', \"namedTemplate\",   \"named template\",\n\t  .referenceOnly = false, ATTACH_ROLES (XsltNamedTemplateRoles) },\n\t{ true,  'v', \"variable\", \"variables\" },\n};\n\nstatic void makeTagRecursivelyWithVersionVerification (xmlNode *node,\n\t\t\t\t\t\t       const char *xpath,\n\t\t\t\t\t\t       const tagXpathRecurSpec *spec,\n\t\t\t\t\t\t       xmlXPathContext *ctx,\n\t\t\t\t\t\t       void *userData);\nstatic void makeTagRecursively (xmlNode *node,\n\t\t\t\tconst char *xpath,\n\t\t\t\tconst tagXpathRecurSpec *spec,\n\t\t\t\txmlXPathContext *ctx,\n\t\t\t\tvoid *userData);\n\nstatic void makeTagWithProvidingScope (xmlNode *node,\n\t\t\t\t       const char *xpath,\n\t\t\t\t       const tagXpathMakeTagSpec *spec,\n\t\t\t\t       struct sTagEntryInfo *tag,\n\t\t\t\t       void *userData);\n\nenum xsltXpathTable {\n\tTABLE_MAIN,\n\tTABLE_STYLESHEET,\n\tTABLE_VERSION_VERIFY,\n\tTABLE_TEMPLATE,\n\tTABLE_APPLIED_TEMPLATES,\n\tTABLE_CALL_TEMPLATE,\n\tTABLE_PARAM,\n\tTABLE_VARIABLE,\n\tTABLE_WITH_PARAM,\n\tTABLE_CALL_TEMPLATE_INTERNAL,\n};\n\n#define xsltXpathTemplateTableEntry(PREFIX)\t\t\t\t\\\n\t{ PREFIX \"/*[local-name()='template']\",\t\t\t\t\\\n\t  LXPATH_TABLE_DO_RECUR,\t\t\t\t\t\\\n\t  { .recurSpec = { makeTagRecursively, TABLE_TEMPLATE} }}\n\n#define xsltXpathVariableTableEntry(PREFIX)\t\t\t\t\\\n\t{ PREFIX \"/*[local-name()='variable']\",\t\t\t\t\\\n\t  LXPATH_TABLE_DO_RECUR,\t\t\t\t\t\\\n\t  { .recurSpec = { makeTagRecursively, TABLE_VARIABLE} }}\n\n#define xsltXpathParamTableEntry(PREFIX)\t\t\t\\\n\t{ PREFIX \"/*[local-name()='param']\",\t\t\t\\\n\t  LXPATH_TABLE_DO_RECUR,\t\t\t\t\\\n\t  { .recurSpec = { makeTagRecursively, TABLE_PARAM} }}\n\n#define xsltXpathWithParamTableEntry(PREFIX)\t\t\t\t\\\n\t{ PREFIX \"/*[local-name()='with-param']\",\t\t\t\\\n\t  LXPATH_TABLE_DO_RECUR,\t\t\t\t\t\\\n\t  { .recurSpec = { makeTagRecursively, TABLE_WITH_PARAM} }}\t\\\n\nstatic tagXpathTable xsltXpathMainTable[] = {\n\t{ \"(/*[local-name()='stylesheet']|/*[local-name()='transform'])\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { makeTagRecursivelyWithVersionVerification } }},\n};\n\nstatic tagXpathTable xsltXpathStylesheetTable[] = {\n\t{ \"./*[local-name()='import']/@href\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = {K_STYLESHEET, R_STYLESHEET_IMPORTED} }},\n\t{ \"./*[local-name()='include']/@href\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = {K_STYLESHEET, R_STYLESHEET_INCLUDED} }},\n\n\txsltXpathTemplateTableEntry (\".\"),\n\txsltXpathVariableTableEntry (\".\"),\n\txsltXpathParamTableEntry    (\".\"),\n};\n\nstatic tagXpathTable xsltXpathTemplateTable[] = {\n\t{ \"./@match\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = {K_MATCHED_TEMPLATE, ROLE_DEFINITION_INDEX,\n\t\t\t    makeTagWithProvidingScope } }},\n\t{ \"./@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = {K_NAMED_TEMPLATE, ROLE_DEFINITION_INDEX,\n\t\t\t    makeTagWithProvidingScope } }},\n\t{ \".\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { makeTagRecursively, TABLE_CALL_TEMPLATE_INTERNAL } }},\n};\n\nstatic tagXpathTable xsltXpathAppliedTemplatesTable [] = {\n\t{ \"./@select\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = {K_MATCHED_TEMPLATE, R_MATCHED_TEMPLATE_APPLIED,\n\t\t\t    makeTagWithProvidingScope } }},\n\txsltXpathWithParamTableEntry(\".\"),\n};\n\nstatic tagXpathTable xsltXpathCallTemplateTable [] = {\n\t{ \"./@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = {K_NAMED_TEMPLATE, R_NAMED_TEMPLATE_CALLED,\n\t\t\t    makeTagWithProvidingScope } }},\n\txsltXpathWithParamTableEntry(\".\"),\n};\n\nstatic tagXpathTable xsltXpathParamTable [] = {\n\t{ \"./@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = {K_PARAMETER, ROLE_DEFINITION_INDEX,\n\t\t\t    makeTagWithProvidingScope} }},\n\txsltXpathTemplateTableEntry (\".\"),\n};\n\nstatic tagXpathTable xsltXpathVariableTable [] = {\n\t{ \"./@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = {K_VARIABLE, ROLE_DEFINITION_INDEX,\n\t\t\t    makeTagWithProvidingScope} }},\n\txsltXpathTemplateTableEntry (\".\"),\n};\n\nstatic tagXpathTable xsltXpathWithParamTable [] = {\n\t{ \"./@name\",\n\t  LXPATH_TABLE_DO_MAKE,\n\t  { .makeTagSpec = {K_PARAMETER, R_PARAMETER_BOUND,\n\t\t\t    makeTagWithProvidingScope} }},\n\txsltXpathTemplateTableEntry (\".\"),\n};\n\nstatic tagXpathTable xsltXpathTemplateInternalTable [] = {\n\t{ \"./*[local-name()='apply-templates']\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { makeTagRecursively, TABLE_APPLIED_TEMPLATES } }},\n\t{ \"./*[local-name()='call-template']\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { makeTagRecursively, TABLE_CALL_TEMPLATE } }},\n\txsltXpathVariableTableEntry (\".\"),\n\txsltXpathParamTableEntry (\".\"),\n\t{ \"./node()[not (\"\n\t  \"local-name()='apply-templates'\"\n\t  \" or \"\n\t  \"local-name()='call-template'\"\n\t  \" or \"\n\t  \"local-name()='variable'\"\n\t  \" or \"\n\t  \"local-name()='param'\"\n\t  \")]\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { makeTagRecursively, TABLE_CALL_TEMPLATE_INTERNAL } }},\n};\n\nstatic void verifyVersion (xmlNode *node,\n\t\t\t   const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t   const tagXpathRecurSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t   xmlXPathContext *ctx CTAGS_ATTR_UNUSED,\n\t\t\t   void *userData)\n{\n\tbool *acceptable = userData;\n\tchar *version = (char *)xmlNodeGetContent (node);\n\n\tif (version)\n\t{\n\t\tif (strcmp (version, \"1.0\") == 0)\n\t\t{\n\t\t\tverbose (\"xslt: accept version: %s\\n\", version);\n\t\t\t*acceptable = true;\n\t\t}\n\t\telse\n\t\t\tverbose (\"xslt: unsupported version: %s\\n\", version);\n\n\t\teFree (version);\n\t}\n\telse\n\t\tverbose (\"xslt: version unknown\\n\");\n}\n\nstatic tagXpathTable xsltXpathVersionVerifyTable [] = {\n\t{ \"./@version\",\n\t  LXPATH_TABLE_DO_RECUR,\n\t  { .recurSpec = { verifyVersion } }},\n};\n\n\nstatic tagXpathTableTable xsltXpathTableTable[] = {\n\t[TABLE_MAIN]              = { ARRAY_AND_SIZE (xsltXpathMainTable) },\n\t[TABLE_STYLESHEET]        = { ARRAY_AND_SIZE (xsltXpathStylesheetTable) },\n\t[TABLE_VERSION_VERIFY]    = { ARRAY_AND_SIZE (xsltXpathVersionVerifyTable) },\n\t[TABLE_TEMPLATE]          = { ARRAY_AND_SIZE (xsltXpathTemplateTable) },\n\t[TABLE_APPLIED_TEMPLATES] = { ARRAY_AND_SIZE (xsltXpathAppliedTemplatesTable) },\n\t[TABLE_CALL_TEMPLATE]     = { ARRAY_AND_SIZE (xsltXpathCallTemplateTable) },\n\t[TABLE_PARAM]             = { ARRAY_AND_SIZE (xsltXpathParamTable) },\n\t[TABLE_VARIABLE]          = { ARRAY_AND_SIZE (xsltXpathVariableTable) },\n\t[TABLE_WITH_PARAM]        = { ARRAY_AND_SIZE (xsltXpathWithParamTable) },\n\t[TABLE_CALL_TEMPLATE_INTERNAL] = { ARRAY_AND_SIZE (xsltXpathTemplateInternalTable) },\n};\n\n\nstatic void makeTagRecursivelyWithVersionVerification (xmlNode *node,\n\t\t\t\t\t\t       const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t       const tagXpathRecurSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t       xmlXPathContext *ctx,\n\t\t\t\t\t\t       void *userData)\n{\n\tbool acceptable = false;\n\tint backup;\n\n\tfindXMLTags (ctx, node, TABLE_VERSION_VERIFY, &acceptable);\n\tif (!acceptable)\n\t\treturn;\n\n\tbackup = *(int *)userData;\n\tfindXMLTags (ctx, node, TABLE_STYLESHEET, userData);\n\n\t*(int *)userData = backup;\n}\n\nstatic void makeTagRecursively (xmlNode *node,\n\t\t\t\tconst char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\tconst tagXpathRecurSpec *spec,\n\t\t\t\txmlXPathContext *ctx,\n\t\t\t\tvoid *userData)\n{\n\tint backup = *(int *)userData;\n\n\tfindXMLTags (ctx, node, spec->nextTable, userData);\n\n\t*(int *)userData = backup;\n}\n\nstatic void makeTagWithProvidingScope (xmlNode *node CTAGS_ATTR_UNUSED,\n\t\t\t\t       const char *xpath CTAGS_ATTR_UNUSED,\n\t\t\t\t       const tagXpathMakeTagSpec *spec CTAGS_ATTR_UNUSED,\n\t\t\t\t       struct sTagEntryInfo *tag,\n\t\t\t\t       void *userData)\n{\n\tint *index = (int *)userData;\n\n\ttag->extensionFields.scopeIndex = *index;\n\t*index = makeTagEntry (tag);\n}\n\nstatic void\nfindXsltTags (void)\n{\n\tscheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);\n}\n\nstatic void\nrunXPathEngine(xmlSubparser *s,\n\t\t\t   xmlXPathContext *ctx, xmlNode *root)\n{\n\tint corkIndex = CORK_NIL;\n\n\tfindXMLTags (ctx, root, TABLE_MAIN, &corkIndex);\n}\n\nstatic xmlSubparser xsltSubparser = {\n\t.subparser = {\n\t\t.direction = SUBPARSER_BI_DIRECTION,\n\t},\n\t.runXPathEngine = runXPathEngine,\n};\n\nextern parserDefinition*\nXsltParser (void)\n{\n\tstatic const char *const extensions [] = { \"xsl\", \"xslt\", NULL };\n\tparserDefinition* const def = parserNew (\"XSLT\");\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"XML\", &xsltSubparser },\n\t};\n\n\tdef->kindTable         = XsltKinds;\n\tdef->kindCount     = ARRAY_SIZE (XsltKinds);\n\tdef->extensions    = extensions;\n\tdef->parser        = findXsltTags;\n\tdef->tagXpathTableTable = xsltXpathTableTable;\n\tdef->tagXpathTableCount = ARRAY_SIZE (xsltXpathTableTable);\n\tdef->useCork = CORK_QUEUE;\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/yaml.c",
    "content": "/*\n*   Copyright (c) 2016, Masatake YAMATO\n*   Copyright (c) 2016, Red Hat, Inc.\n*   Copyright (c) 2022, Vasily Kulikov\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n*   This module contains functions for applying yaml traversing.\n*/\n\n#include \"general.h\"  /* must always come first */\n\n#include <inttypes.h>\n\n#include \"debug.h\"\n#include \"entry.h\"\n#include \"htable.h\"\n#include \"options.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"subparser.h\"\n#include \"trace.h\"\n#include \"types.h\"\n#include \"x-yaml.h\"\n\n#include \"numarray.h\"\n#include \"keyword.h\"\n#include \"trashbox.h\"\n\n\n#ifdef DEBUG\n#define entry(X) [X] = #X\nstatic const char *tokenTypeName [] = {\n    entry (YAML_NO_TOKEN),\n    entry (YAML_STREAM_START_TOKEN),\n    entry (YAML_STREAM_END_TOKEN),\n    entry (YAML_VERSION_DIRECTIVE_TOKEN),\n    entry (YAML_TAG_DIRECTIVE_TOKEN),\n    entry (YAML_DOCUMENT_START_TOKEN),\n    entry (YAML_DOCUMENT_END_TOKEN),\n    entry (YAML_BLOCK_SEQUENCE_START_TOKEN),\n    entry (YAML_BLOCK_MAPPING_START_TOKEN),\n    entry (YAML_BLOCK_END_TOKEN),\n    entry (YAML_FLOW_SEQUENCE_START_TOKEN),\n    entry (YAML_FLOW_SEQUENCE_END_TOKEN),\n    entry (YAML_FLOW_MAPPING_START_TOKEN),\n    entry (YAML_FLOW_MAPPING_END_TOKEN),\n    entry (YAML_BLOCK_ENTRY_TOKEN),\n    entry (YAML_FLOW_ENTRY_TOKEN),\n    entry (YAML_KEY_TOKEN),\n    entry (YAML_VALUE_TOKEN),\n    entry (YAML_ALIAS_TOKEN),\n    entry (YAML_ANCHOR_TOKEN),\n    entry (YAML_TAG_TOKEN),\n    entry (YAML_SCALAR_TOKEN),\n};\n#undef entry\n#endif\n\nstatic void yamlInit (yaml_parser_t *yaml)\n{\n\tconst unsigned char* data;\n\tsize_t size;\n\n\tyaml_parser_initialize (yaml);\n\n\tdata = getInputFileData (&size);\n\tAssert (data);\n\n\tyaml_parser_set_input_string (yaml, data, size);\n}\n\nstatic void yamlFini (yaml_parser_t *yaml)\n{\n\tyaml_parser_delete (yaml);\n}\n\nextern void attachYamlPosition (tagEntryInfo *tag, yaml_token_t *token, bool asEndPosition)\n{\n\t/* start_mark.line is 0-based. translateLineNumber expects 1-based line number. */\n\tunsigned long abs_line = translateLineNumber (token->start_mark.line + 1);\n\n\tif (asEndPosition)\n\t\tsetTagEndLine (tag, abs_line);\n\telse\n\t{\n\t\tMIOPos rela_pos = getInputFilePositionForLine (abs_line);\n\t\tupdateTagLine (tag, abs_line, rela_pos);\n\t}\n}\n\nenum YamlKind {\n\tK_ANCHOR,\n};\n\nenum YamlAnchorRole {\n\tR_ANCHOR_ALIAS,\n};\n\nstatic roleDefinition YamlAnchorRoles [] = {\n\t{ true, \"alias\", \"alias\" },\n};\n\nstatic kindDefinition YamlKinds [] = {\n\t{ true,  'a', \"anchor\", \"anchors\",\n\t  .referenceOnly = false, ATTACH_ROLES(YamlAnchorRoles) },\n};\n\nstatic void handlYamlToken (yaml_token_t *token)\n{\n\ttagEntryInfo tag;\n\n\tif (token->type == YAML_ANCHOR_TOKEN)\n\t{\n\t\tinitTagEntry (&tag, (char *)token->data.anchor.value,\n\t\t\t\t\t  K_ANCHOR);\n\t\tattachYamlPosition (&tag, token, false);\n\t\tmakeTagEntry (&tag);\n\t}\n\telse if (token->type == YAML_ALIAS_TOKEN)\n\t{\n\t\tinitRefTagEntry (&tag, (char *)token->data.alias.value,\n\t\t\t\t\t\t K_ANCHOR, R_ANCHOR_ALIAS);\n\t\tattachYamlPosition (&tag, token, false);\n\t\tmakeTagEntry (&tag);\n\t}\n}\n\nstatic int ypathCompileTable (langType language, tagYpathTable *table, int keywordId);\nstatic void ypathCompileTables (langType language, tagYpathTable tables[], size_t count, int keywordId);\nstatic void ypathCompiledCodeDelete (tagYpathTable tables[], size_t count);\n\nstatic void ypathHandleToken (yamlSubparser *yaml, yaml_token_t *token, int state, tagYpathTable tables[], size_t count);\n\nstatic void ypathPushType (yamlSubparser *yaml, yaml_token_t *token);\nstatic void ypathPopType (yamlSubparser *yaml, yaml_token_t *token);\nstatic void ypathPopAllTypes (yamlSubparser *yaml, yaml_token_t *token);\nstatic void ypathFillKeywordOfTokenMaybe (yamlSubparser *yaml, yaml_token_t *token, langType lang);\n\nstatic void ypathDefaultStateMachine (yamlSubparser *s, yaml_token_t *token)\n{\n#ifdef DO_TRACING\n\typathPrintTypeStack (s);\n#endif\n\n\tswitch (token->type)\n\t{\n\tcase YAML_KEY_TOKEN:\n\t\ts->detectionState = YPATH_DSTAT_LAST_KEY;\n\t\tbreak;\n\tcase YAML_SCALAR_TOKEN:\n\t\tswitch (s->detectionState)\n\t\t{\n\t\tcase YPATH_DSTAT_LAST_KEY:\n\t\t\typathFillKeywordOfTokenMaybe (s, token, getInputLanguage ());\n\t\t\t/* FALL THROUGH */\n\t\tcase YPATH_DSTAT_LAST_VALUE:\n\t\t\tTRACE_PRINT(\"token-callback: %s: %s\",\n\t\t\t\t\t\t(s->detectionState == YPATH_DSTAT_LAST_KEY)? \"key\": \"value\",\n\t\t\t\t\t\t(char*)token->data.scalar.value);\n\t\t\typathHandleToken (s, token, s->detectionState,\n\t\t\t\t\t\t\t  s->ypathTables, s->ypathTableCount);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\ts->detectionState = YPATH_DSTAT_INITIAL;\n\n\t\tbreak;\n\tcase YAML_VALUE_TOKEN:\n\t\ts->detectionState = YPATH_DSTAT_LAST_VALUE;\n\t\tbreak;\n\n\tdefault:\n\t\ts->detectionState = YPATH_DSTAT_INITIAL;\n\t\tbreak;\n\t}\n}\n\nstatic void ypathDefaultNewTokenCallback (yamlSubparser *s, yaml_token_t *token)\n{\n\tif (token->type == YAML_BLOCK_SEQUENCE_START_TOKEN\n\t\t|| token->type == YAML_BLOCK_MAPPING_START_TOKEN)\n\t\typathPushType (s, token);\n\n\typathDefaultStateMachine (s, token);\n\n\tif (token->type == YAML_BLOCK_END_TOKEN)\n\t\typathPopType (s, token);\n\telse if (token->type == YAML_STREAM_END_TOKEN)\n\t\typathPopAllTypes (s, token);\n}\n\nstatic void finiSubparserState (yamlSubparser *yaml)\n{\n\typathCompiledCodeDelete (yaml->ypathTables,\n\t\t\t\t\t\t\t yaml->ypathTableCount);\n\tyaml->compiled = false;\n}\n\nstatic void initSubparserState (yamlSubparser *yaml, langType sublang)\n{\n\tyaml->ypathTypeStack = NULL;\n\tyaml->detectionState = YPATH_DSTAT_INITIAL;\n\tif (yaml->ypathTables && !yaml->compiled)\n\t{\n\t\typathCompileTables (sublang, yaml->ypathTables,\n\t\t\t\t\t\t\tyaml->ypathTableCount, 0);\n\t\tyaml->compiled = true;\n\n\t\t/* We cannot use the finalize method of the YAML parser for releasing\n\t\t * the compiled code because foreachSubparser doesn't work in the\n\t\t * method. In the context. We use the global trash instead. */\n\t\tDEFAULT_TRASH_BOX(yaml, finiSubparserState);\n\t}\n}\n\nstatic void findYamlTags (void)\n{\n\tsubparser *sub;\n\tyaml_parser_t yaml;\n\tyaml_token_t token;\n\tbool done;\n\n\tyamlInit (&yaml);\n\n\tforeachSubparser(sub, false)\n\t{\n\t\tlangType sublang = getSubparserLanguage(sub);\n\t\tinitSubparserState ((yamlSubparser*)sub, sublang);\n\t}\n\n\tfindRegexTags ();\n\n\tsub = getSubparserRunningBaseparser();\n\tif (sub)\n\t\tchooseExclusiveSubparser (sub, NULL);\n\n\tdone = false;\n\twhile (!done)\n\t{\n\t\tif (!yaml_parser_scan (&yaml, &token))\n\t\t\tbreak;\n\n\t\thandlYamlToken (&token);\n\t\tforeachSubparser(sub, false)\n\t\t{\n\t\t\tenterSubparser (sub);\n\t\t\tif (((yamlSubparser *)sub)->newTokenNotfify)\n\t\t\t\t((yamlSubparser *)sub)->newTokenNotfify ((yamlSubparser *)sub, &token);\n\t\t\telse\n\t\t\t\typathDefaultNewTokenCallback ((yamlSubparser *)sub, &token);\n\t\t\tleaveSubparser ();\n\t\t}\n\n\t\tTRACE_PRINT(\"yaml token:%s<%d>@Line:%\"PRIuPTR\"\", tokenTypeName[token.type], token.type,\n\t\t\t\ttoken.start_mark.line + 1);\n\t\tif (isTraced() && token.type == YAML_SCALAR_TOKEN)\n\t\t{\n\t\t\tTRACE_PRINT_FMT(\"\t\");\n\t\t\tfor (size_t i = 0; i < token.data.scalar.length; i++)\n\t\t\t\tTRACE_PRINT_FMT(\"%c\", token.data.scalar.value[i]);\n\t\t\tTRACE_PRINT_NEWLINE();\n\t\t}\n\n\t\tif (token.type == YAML_STREAM_END_TOKEN)\n\t\t\tdone = true;\n\n\t\tyaml_token_delete (&token);\n\t}\n\n\tforeachSubparser(sub, false)\n\t{\n\t\tenterSubparser (sub);\n\t\typathPopAllTypes ((yamlSubparser*)sub, NULL);\n\t\tleaveSubparser ();\n\t}\n\n\tyamlFini (&yaml);\n}\n\nextern parserDefinition* YamlParser (void)\n{\n\tstatic const char *const extensions [] = { \"yml\", \"yaml\", NULL };\n\tparserDefinition* const def = parserNew (\"Yaml\");\n\n\tdef->kindTable = YamlKinds;\n\tdef->extensions = extensions;\n\tdef->parser = findYamlTags;\n\tdef->useCork = CORK_QUEUE;\n\tdef->kindTable = YamlKinds;\n\tdef->kindCount = ARRAY_SIZE (YamlKinds);\n\tdef->useMemoryStreamInput = true;\n\n\treturn def;\n}\n\n/*\n * Experimental Ypath code\n */\nstruct ypathTypeStack {\n\tyaml_token_type_t type;\n\tint key;\n\tstruct ypathTypeStack *next;\n};\n\nstatic int ypathCompileTable (langType language, tagYpathTable *table, int keywordId)\n{\n\tvString *tmpkey = vStringNew();\n\tintArray *code = intArrayNew ();\n\n\tfor (const char *ypath = table->ypath; true; ypath++)\n\t{\n\t\tif (*ypath == '/' || *ypath == '\\0')\n\t\t{\n\t\t\tif (!vStringIsEmpty (tmpkey))\n\t\t\t{\n\t\t\t\tint k;\n\t\t\t\tif (vStringLength (tmpkey) == 1 && (vStringValue (tmpkey)[0] == '*'))\n\t\t\t\t\tk = KEYWORD_NONE;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tk = lookupKeyword (vStringValue (tmpkey), language);\n\t\t\t\t\tif (k == KEYWORD_NONE)\n\t\t\t\t\t{\n\t\t\t\t\t\tchar *keyword = DEFAULT_TRASH_BOX(vStringStrdup (tmpkey), eFree);\n\t\t\t\t\t\tk = keywordId++;\n\t\t\t\t\t\taddKeyword (keyword, language, k);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tintArrayAdd (code, k);\n\t\t\t\tvStringClear (tmpkey);\n\t\t\t}\n\t\t\tif (*ypath == '\\0')\n\t\t\t\tbreak;\n\t\t}\n\t\telse\n\t\t\tvStringPut (tmpkey, *ypath);\n\t}\n\n\tintArrayReverse (code);\n\ttable->code = code;\n\n\tvStringDelete (tmpkey);\n\treturn keywordId;\n}\n\nstatic void ypathCompileTables (langType language, tagYpathTable tables[], size_t count, int keywordId)\n{\n\tfor (size_t i = 0; i < count; i++)\n\t\tkeywordId = ypathCompileTable (language, tables + i, keywordId);\n}\n\nstatic void ypathCompiledCodeDelete (tagYpathTable tables[], size_t count)\n{\n\tfor (size_t i = 0; i < count; i++)\n\t{\n\t\tintArrayDelete (tables[i].code);\n\t\ttables[i].code = NULL;\n\t}\n}\n\nstatic void ypathPushType (yamlSubparser *yaml, yaml_token_t *token)\n{\n\tstruct ypathTypeStack *s;\n\n\ts = xMalloc (1, struct ypathTypeStack);\n\n\ts->next = yaml->ypathTypeStack;\n\tyaml->ypathTypeStack = s;\n\n\ts->type = token->type;\n\ts->key = KEYWORD_NONE;\n\n\tif (yaml->enterBlockNotify)\n\t\tyaml->enterBlockNotify (yaml, token);\n}\n\nstatic void ypathPopType (yamlSubparser *yaml, yaml_token_t *token)\n{\n\tstruct ypathTypeStack *s;\n\n\tif (yaml->leaveBlockNotify)\n\t\tyaml->leaveBlockNotify (yaml, token);\n\n\ts = yaml->ypathTypeStack;\n\tyaml->ypathTypeStack = s->next;\n\n\ts->next = NULL;\n\n\teFree (s);\n}\n\nstatic void ypathPopAllTypes (yamlSubparser *yaml, yaml_token_t *token)\n{\n\twhile (yaml->ypathTypeStack)\n\t\typathPopType (yaml, token);\n}\n\nextern size_t ypathGetTypeStackDepth (yamlSubparser *yaml)\n{\n\tsize_t depth = 0;\n\tstruct ypathTypeStack *s = yaml->ypathTypeStack;\n\n\twhile (s) {\n\t\tdepth++;\n\t\ts = s->next;\n\t}\n\n\treturn depth;\n}\n\nstatic void ypathFillKeywordOfTokenMaybe (yamlSubparser *yaml, yaml_token_t *token, langType lang)\n{\n\tif (!yaml->ypathTypeStack)\n\t\treturn;\n\n\tint k = lookupKeyword ((char *)token->data.scalar.value, lang);\n\tyaml->ypathTypeStack->key = k;\n}\n\nstatic bool ypathStateStackMatch (struct ypathTypeStack *stack,\n\t\t\t\t\t\t\t\t  intArray *code, size_t offset)\n{\n\tif (intArrayCount (code) - offset == 0)\n\t{\n\t\tif (stack == NULL)\n\t\t\treturn true;\n\t\telse\n\t\t\treturn false;\n\t}\n\n\tif (stack == NULL)\n\t\treturn false;\n\n\tint expected_key = intArrayItem (code, offset);\n\n\t/* KEYWORD_NONE represents '*'. */\n\tif (expected_key == KEYWORD_NONE || stack->key == expected_key)\n\t\treturn ypathStateStackMatch (stack->next, code, offset + 1);\n\telse\n\t\treturn false;\n}\n\nstatic void ypathHandleToken (yamlSubparser *yaml, yaml_token_t *token, int state,\n\t\t\t\t\t\t\t  tagYpathTable tables[], size_t count)\n{\n\tif (!yaml->ypathTypeStack)\n\t\treturn;\n\n\tfor (size_t i = 0; i < count; i++)\n\t{\n\t\tif (tables[i].expected_state != state)\n\t\t\tcontinue;\n\n\t\tif (ypathStateStackMatch(yaml->ypathTypeStack, tables[i].code, 0))\n\t\t{\n\t\t\ttagEntryInfo tag;\n\t\t\tbool r = true;\n\t\t\tif (tables[i].initTagEntry)\n\t\t\t\tr = (* tables[i].initTagEntry) (&tag, yaml, (char *)token->data.scalar.value,\n\t\t\t\t\t\t\t\t\t\t\t\ttables[i].data);\n\t\t\telse\n\t\t\t\tinitTagEntry (&tag, (char *)token->data.scalar.value, tables[i].kind);\n\n\t\t\tif (r)\n\t\t\t{\n\t\t\t\tattachYamlPosition (&tag, token, false);\n\t\t\t\tint index = makeTagEntry (&tag);\n\t\t\t\tif (index != CORK_NIL && yaml->makeTagEntryNotifyViaYpath)\n\t\t\t\t\tyaml->makeTagEntryNotifyViaYpath (yaml, index);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n#ifdef DO_TRACING\nstatic void ypathPrintTypeStack0(struct ypathTypeStack *stack)\n{\n\tif (!stack)\n\t{\n\t\tTRACE_PRINT_NEWLINE();\n\t\treturn;\n\t}\n\n\ttracePrintFmt(\"[%d] - \", stack->key);\n\typathPrintTypeStack0 (stack->next);\n}\n\nextern void ypathPrintTypeStack(yamlSubparser *yaml)\n{\n\typathPrintTypeStack0 (yaml->ypathTypeStack);\n}\n#else\nextern void ypathPrintTypeStack(yamlSubparser *yaml) {}\n#endif\n"
  },
  {
    "path": "parsers/yamlfrontmatter.c",
    "content": "/*\n*\n*   Copyright (c) 2022, Masatake YAMATO\n*   Copyright (c) 2022, Red Hat, K.K.\n*\n*   This source code is released for free distribution under the terms of the\n*   GNU General Public License version 2 or (at your option) any later version.\n*\n* This module contains functions for extracting language objects in FrontMatter\n* using Yaml.\n*\n* https://gohugo.io/content-management/front-matter\n*/\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"\t/* must always come first */\n\n#include \"x-frontmatter.h\"\n#include \"x-yaml.h\"\n\n#include \"entry.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"subparser.h\"\n\n\n/*\n*   DATA DECLARATIONS\n*/\nstruct sYamlFrontMatterSubparser {\n\tyamlSubparser yaml;\n};\n\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nstatic bool yamlFrontmattterInitTagEntry (tagEntryInfo *e, yamlSubparser *yaml, char *name, void *data);\n\n\n/*\n*   DATA DEFINITIONS\n*/\n\nstatic langType Lang_frontmatter;\n\nstatic tagYpathTable ypathTables [] = {\n\t{\n\t\t\"title\",\n\t\tYPATH_DSTAT_LAST_VALUE,\n\t\t.initTagEntry = yamlFrontmattterInitTagEntry,\n\t},\n};\n\n\n/*\n*   FUNCTION DEFINITIONS\n*/\n\nstatic bool yamlFrontmattterInitTagEntry (tagEntryInfo *e, yamlSubparser *s CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t\t\t\t  char *name, void * data CTAGS_ATTR_UNUSED)\n{\n\tinitForeignTagEntry (e, name, Lang_frontmatter, FRONTMATTER_TITLE_KIND);\n\treturn true;\n}\n\nstatic void findYamlFrontMatterTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* YamlFrontMatter (void)\n{\n\tstatic struct sYamlFrontMatterSubparser yamlfrontmatterSubparser = {\n\t\t.yaml = {\n\t\t\t.subparser = {\n\t\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t\t},\n\t\t\t.ypathTables = ypathTables,\n\t\t\t.ypathTableCount = ARRAY_SIZE (ypathTables),\n\t\t},\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t{ DEPTYPE_SUBPARSER, \"Yaml\", &yamlfrontmatterSubparser },\n\t\t{ DEPTYPE_FOREIGNER, \"FrontMatter\", &Lang_frontmatter },\n\t};\n\n\tparserDefinition* const def = parserNew (\"YamlFrontMatter\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\n\tdef->kindTable\t= NULL;\n\tdef->kindCount = 0;\n\tdef->parser\t= findYamlFrontMatterTags;\n\n\t/* This parser runs ONLY as a part of FrontMatter parser.\n\t * User may not want to enable/disable this parser directly. */\n\tdef->invisible = true;\n\n\treturn def;\n}\n"
  },
  {
    "path": "parsers/yumrepo.c",
    "content": "/*\n *   yumrepo.c\n *\n *   Copyright (c) 2016, Masatake YAMATO <yamato@redhat.com>\n *   Copyright (c) 2016, Red Hat, K.K.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions for generating tags for yum repo file\n *\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"general.h\"  /* must always come first */\n\n#include \"entry.h\"\n#include \"x-iniconf.h\"\n#include \"kind.h\"\n#include \"parse.h\"\n#include \"read.h\"\n#include \"routines.h\"\n#include <string.h>\n\n/*\n*   DATA DEFINITIONS\n*/\ntypedef enum {\n\tK_REPO_ID,\n} yumRepoKind;\n\nstatic kindDefinition YumRepoKinds [] = {\n\t{ true, 'r', \"repoid\", \"repository id\" },\n};\n\n\nstatic void newDataCallback (iniconfSubparser *s CTAGS_ATTR_UNUSED,\n\t\t\t\t\t\t\t const char *section, const char *key, const char *value)\n{\n\ttagEntryInfo e;\n\n\tif (section && key == NULL && value == NULL)\n\t{\n\t\tinitTagEntry (&e, section, K_REPO_ID);\n\t\tmakeTagEntry (&e);\n\t}\n}\n\nstatic void findYumRepoTags (void)\n{\n\tscheduleRunningBaseparser (0);\n}\n\nextern parserDefinition* YumRepoParser (void)\n{\n\tstatic const char *const extensions [] = { \"repo\", NULL };\n\tstatic iniconfSubparser yumRepoSubparser = {\n\t\t.subparser = {\n\t\t\t.direction = SUBPARSER_SUB_RUNS_BASE,\n\t\t},\n\t\t.newDataNotify = newDataCallback,\n\t};\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_SUBPARSER, \"Iniconf\", &yumRepoSubparser },\n\t};\n\n\tparserDefinition* const def = parserNew (\"YumRepo\");\n\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE(dependencies);\n\tdef->kindTable      = YumRepoKinds;\n\tdef->kindCount  = ARRAY_SIZE (YumRepoKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findYumRepoTags;\n\n\treturn def;\n}\n"
  },
  {
    "path": "peg/.gitignore",
    "content": "varlink.[ch]\nkotlin.[ch]\nthrift.[ch]\nelm.[ch]\ntoml.[ch]\n\n*.pego\n"
  },
  {
    "path": "peg/elm.peg",
    "content": "# Copyright (c) 2022 Nik Silver\n#\n# This source code is released for free distribution under the terms of the\n# GNU General Public License version 2 or later.\n#\n# Thanks to:\n# - Mark Skipper, for the original Elm optlib parser, which inspired this;\n# - Samuel Stauffer, for the Thrift PEG parser, which showed me how to\n#   write a PEG parser;\n# - Jan Dolinár, for the Kotlin PEG parser, which also provided insight;\n# - Masatake YAMATO, for patience and guidance in code reviews.\n#\n# This parser generates tags for Elm. See https://elm-lang.org/docs/syntax\n# for language reference.\n#\n# The parser will tag items reliably at the top level. Functions\n# defined in let/in blocks are also tagged, but with limitations. See below.\n#\n# Kinds\n# - m module\n# - n namespace (ie a module that's renamed)\n# - t type\n# - c constructor (within a type)\n# - a alias\n# - p port\n# - f function\n#\n# Key/value pairs\n# - roles:def       This is defined here.\n# - roles:imported  This is imported here.\n# - type:<t>        This constructor is in the scope of type <t>, which\n#                   may be dotted. Eg Main.myType.\n# - function:<f>    This function is in the scope of function <f>, which\n#                   may be dotted. Eg Main.myFunc.\n# - module:<m>      This is in the scope of module <m>.\n# - typeref:description:<t>   This function, constructor or port\n#                   has type <t>.\n# - moduleName:<m>  This namespace has original module name <m>.\n#\n# Functions defined in let/in blocks may be tagged, with these limitations:\n# - the LHS (up to and including the '=') need to be on a single line;\n# - the LHS can only have simple parameters;\n# - their scope is only marked as being in the top-most function;\n# - any type annotation is ignored.\n# This should be good for 90% of inner functions. To make it totally robust\n# is much more complicated due to (a) Elm's clever indentation-sensitivity\n# and (b) limitations of the PEG parser used here.\n#\n# To do:\n# Maybe do:\n# - let/in blocks\n#   - Allow tuples on the LHS. Eg '(val1, val2) = valFunc'.\n#   - Inner functions' type annotations are used in the function's\n#     type description.\n#   - Inner functions can have more complex parameters.\n# - Functions\n#   - Allow non-Latin upper and lower case. Use\n#     https://util.unicode.org/UnicodeJsps/properties.html\n#     combined with \\p{Lu}, \\p{Ll} and \\p{L}.\n#\n# Won't do:\n# - Handle Elm's indentation properly.\n\n\n%prefix \"pelm\"\n\n%auxil\t\"struct parserCtx *\"\n\n%earlysource {\n    #include \"general.h\"\n}\n\n%header {\n\tstruct parserCtx;\n}\n\n%source {\n#include \"elm_pre.h\"\n#include \"routines.h\"\n\n/*\n * Include these lines to debug the parsing.\n * From https://github.com/arithy/packcc#macros\n * This will output parsing info to STDERR.tmp in the vent of a failed test.\n */\n\n/*\nstatic const char *dbg_str[] = { \"Evaluating rule\", \"Matched rule\", \"Abandoning rule\" };\n\n#define PCC_DEBUG(auxil, event, rule, level, pos, buffer, length) \\\n    fprintf(stderr, \"%*s%s %s @%zu [%.*s]\\n\", \\\n        (int)((level) * 2), \"\", dbg_str[event], rule, pos, (int)(length), buffer)\n */\n}\n\n# Top level elements -----------------------------------------------------\n\n# We separate the file into the module section and the main section\n# so that we only consider and tag one module declaration\n\nfile <-\n    {\n        ELM_INIT_MODULE_SCOPE;\n    }\n    TLSS?\n    moduleDeclaration?\n    TLSS?\n    mainTopLevelStatements?\n    TLSS?\n    EOF\n\nmainTopLevelStatements <-\n    topLevelStatement (TLSS topLevelStatement)*\n\ntopLevelStatement <-\n    importStatement\n    / typeAlias\n    / customType\n    / portDeclaration\n    / functionWithTypeAnnotation\n    / functionDefinition\n    / ignoreRestOfStatement\n\n# Main Elm grammar -------------------------------------------------------\n\n# Module declaration\n#\n# We can be a bit relaxed about distinguishing functions, types and\n# constructors listed in a module declaration, because we're not going\n# to tag them.\n\nmoduleDeclaration <-\n    ('port' _1_)? 'module' _1_ <dottedIdentifier> _1_ 'exposing' _0_ '(' exposedList ')' EOS {\n        elm_module_scope_index = makeElmTagSettingScope(auxil, $1, $1s, K_MODULE, ROLE_DEFINITION_INDEX);\n    }\n\nexposedList <- _0_ exposedItem _0_ (',' _0_ exposedList )*\n\nexposedItem <-\n    exposedFieldOrType\n    / exposedFunction\n    / exposedItemIgnored\n\nexposedFieldOrType <-\n    <upperStartIdentifier> (_0_ '(' _0_ exposedTypeConstructorList _0_ ')')?\n\nexposedFunction <-\n    lowerStartIdentifier\n\nexposedItemIgnored <- '.'+\n\nexposedTypeConstructorList <-\n    (upperStartIdentifier / exposedItemIgnored) _0_ (',' _0_ exposedTypeConstructorList)*\n\n# Type alias\n#\n# We don't care what the actual alias is\n\ntypeAlias <-\n    'type' _1_ 'alias' _1_ <upperStartIdentifier> _0_ '=' _0_ ignoreRestOfStatement {\n        makeElmTag(auxil, $1, $1s, K_ALIAS, ROLE_DEFINITION_INDEX);\n    }\n\n# Custom type\n#\n# Includes type parameters, such as 'x' in 'type MyType x = Wrap x'.\n#\n# In a definition such as 'type MyType = Cons1 String Int' we\n# capture 'MyType', and then for each type in each constructor\n# subtype (here, 'String' and 'Int') we append a '->' and finally\n# concatentate them all to get the constructor's type description,\n# such as 'String -> Int -> MyType'\n\ncustomType <-\n    'type' _1_ <upperStartIdentifier> (_0_ typeParameterList)? _0_ '=' _0_ {\n        initElmConstructorFields(auxil, $1);\n        makeElmTagSettingScope(auxil, $1, $1s, K_TYPE, ROLE_DEFINITION_INDEX);\n    } constructorList EOS {\n        POP_SCOPE(auxil);\n        tidyElmConstructorFields(auxil);\n    }\n\ntypeParameterList <- lowerStartIdentifier (_1_ lowerStartIdentifier)*\n\n# A type could be defined as a constructor list:\n#     type A = Cons1 String | Cons2 Float Float | ...\n# The 'String' and the 'Float Float' etc are the constructor subtypes.\n# Each 'String', 'Float', etc is a single type spec.\n# But a single type spec could also be a record, a tuple or a function spec.\n#\n# Subtypes in constructors need to be parsed differently from types in\n# type annotations and record fields. Consider these:\n#     type A1Type a b = A1Cons a b              -- Line 1\n#     type A2Type a b = A2Cons String a b       -- Line 2\n#     type BType a b = BCons { x : A2Type a b}  -- Line 3\n#     cFunc : A1Type String Int -> String       -- Line 4\n# In line 1, 'a b' must be parsed as two individual types (parameterised).\n# In line 2, 'String a b' must be parsed as three individual types.\n# In line 3, 'A2Type a b' must be parsed as one type, even though it's\n# lexically equivalent to 'String a b' on line 2.\n# In line 4, 'A1Type String Int' must also be parsed one type.\n# This means we have to have slightly different rules for parsing a\n# constructor's subtypes as from other cases. The first case is handled\n# by constructorSubtypeList and singleConstructorSubtypeSpec. The second\n# case is handled by singleTypeSpec.\n\nconstructorList <- <upperStartIdentifier> {\n        initElmConstructorSubtypeFields(auxil);\n    } _0_ <constructorSubtypeList>? {\n        int r = makeElmTag(auxil, $1, $1s, K_CONSTRUCTOR, ROLE_DEFINITION_INDEX);\n        addElmConstructorTypeRef(auxil, r);\n    } _0_ ('|' _0_ constructorList)?\n\nconstructorSubtypeList <- singleConstructorSubtypeSpec (_0_ singleConstructorSubtypeSpec)*\n\nsingleConstructorSubtypeSpec <-\n    < recordTypeSpec\n      / tupleTypeSpec\n      / functionTypeSpec\n      / dottedIdentifier\n    >\n    {\n        addElmConstructorSubtype(auxil, $1);\n    }\n\nsingleTypeSpec <-\n    recordTypeSpec\n    / tupleTypeSpec\n    / functionTypeSpec\n    / parameterisedTypeSpec\n\nrecordTypeSpec <-\n    '{' (_0_ recordRestrictionPrefix)? _0_ fieldSpec (_0_ ',' _0_ fieldSpec)* _0_ '}'\n    / '{' (_0_ recordRestrictionPrefix)? _0_ '}'\n\nrecordRestrictionPrefix <-\n    lowerStartIdentifier _0_ '|'\n\nfieldSpec <-\n    lowerStartIdentifier _0_ ':' _0_ singleTypeSpec\n\ntupleTypeSpec <-\n    '(' _0_ singleTypeSpec (_0_ ',' _0_ singleTypeSpec)* _0_ ')'\n    / '(' _0_ ')'\n\nparameterisedTypeSpec <-\n    dottedIdentifier (_1_ (singleTypeSpec / lowerStartIdentifier))*\n\nfunctionTypeSpec <-\n    singleTypeSpec (_0_ '->' _0_ singleTypeSpec)+\n\n# Port declaration\n\nportDeclaration <-\n    'port' _1_ <lowerStartIdentifier> _0_ ':' _0_ <typeAnnotation> EOS {\n        int r = makeElmTag(auxil, $1, $1s, K_PORT, ROLE_DEFINITION_INDEX);\n        addElmTypeRef(r, $2);\n    }\n\n# Import statement\n#\n# For the import statement we don't want the imported items to appear in the\n# scope of the current module (ie this file), otherwise they'll be named\n# wrongly. So we # want to save the module scope, make the imported tags,\n# then restore the module scope. We do this in two separate C code blocks,\n# because the module scope needs to be saved before any of the imported tags\n# are made.\n#\n# Also, if we create a namespace then that *does* live in the scope of the\n# current module, so we'll make that tag (if needed) before saving the\n# module scope.\n\nimportStatement <-\n    'import' _1_ <dottedIdentifier> (_1_ 'as' _1_ <upperStartIdentifier>)? {\n        // Make the namespace tag first, as it's in the file module's scope\n        if ($2s > 0) {\n            int r = makeElmTag(auxil, $2, $2s, K_NAMESPACE, ROLE_DEFINITION_INDEX);\n            attachParserFieldToCorkEntry (r, ElmFields[F_MODULENAME].ftype, $1);\n        }\n\n        // Now make the tag for the imported module, as it lives outside\n        // the scope of the file module\n        ELM_SAVE_MODULE_SCOPE;\n        makeElmTagSettingScope(auxil, $1, $1s, K_MODULE, ELM_MODULE_IMPORTED);\n    } (_1_ 'exposing' _0_ '(' _0_ importedList _0_ ')')? EOS {\n        ELM_RESTORE_MODULE_SCOPE;\n    }\n\nimportedList <- importedItem _0_ (',' _0_ importedList)*\n\nimportedItem <-\n    importedFunction\n    / importedType\n    / importedItemIgnored\n\nimportedFunction <- <lowerStartIdentifier> {\n        makeElmTag(auxil, $1, $1s, K_FUNCTION, ELM_FUNCTION_EXPOSED);\n    }\n\n# When importing a type and constructors we want the constructors\n# to be in the scope of the type. So we have to set the scope as the\n# type first, before parsing (and making the tags for) the constructors.\n# That's why the code here uses two separate C code blocks.\n\nimportedType <-\n    <upperStartIdentifier> {\n        makeElmTagSettingScope(auxil, $1, $1s, K_TYPE, ELM_TYPE_EXPOSED);\n    } (_0_ '(' _0_ importedTypeConstructorList _0_ ')')? {\n        // We're done with the type and its constructors, so we can pop it\n        POP_SCOPE(auxil);\n    }\n\nimportedItemIgnored <- '.'+\n\nimportedTypeConstructorList <-\n    (importedTypeConstructor / importedItemIgnored) _0_ (',' _0_ importedTypeConstructorList)*\n\nimportedTypeConstructor <-\n    <upperStartIdentifier> {\n        makeElmTag(auxil, $1, $1s, K_CONSTRUCTOR, ELM_CONSTRUCTOR_EXPOSED);\n    }\n\n# Function with a type annotation.\n#\n# The type is on one line, and the function must follow immediately as\n# the next top level statement\n\nfunctionWithTypeAnnotation <-\n    <lowerStartIdentifier> _0_ ':' _0_ <typeAnnotation> TLSS\n    <$1> _1_ <functionParameterList>? {\n        int r = makeElmTagSettingScope(auxil, $3, $3s, K_FUNCTION, ROLE_DEFINITION_INDEX);\n        addElmTypeRef(r, $2);\n        addElmSignature(r, $4);\n    } _0_ '=' _0_ expression EOS {\n        POP_SCOPE(auxil);\n    }\n\ntypeAnnotation <-\n    singleTypeSpec (_0_ '->' _0_ singleTypeSpec)*\n\n# Function without a type annotation\n\nfunctionDefinition <-\n    <nonKeywordIdentifier> _0_ <functionParameterList>? {\n        int r = makeElmTagSettingScope(auxil, $1, $1s, K_FUNCTION, ROLE_DEFINITION_INDEX);\n        addElmSignature(r, $2);\n    } _0_ '=' _0_ expression EOS {\n        POP_SCOPE(auxil);\n    }\n\n# A function parameter list is what we define a function with. It's the\n# x y z in 'fn x y z'. But of course they can be more complex, such as\n# 'fn (Cons a b) ({ thing } as otherThing))' etc.\n\nfunctionParameterList <- functionParameter (_0_ functionParameter)*\n\nfunctionParameter <-\n    plainFunctionParameter\n    / tupleFunctionParameter\n    / recordFunctionParameter\n    / constructorFunctionParameter\n\nplainFunctionParameter <-\n    lowerStartIdentifier (_0_ asClause)?\n\ntupleFunctionParameter <-\n    '(' _0_ functionParameter (_0_ ',' _0_ functionParameter)* _0_ ')' (_0_ asClause)?\n\nrecordFunctionParameter <-\n    '{' _0_ lowerStartIdentifier (_0_ ',' _0_ lowerStartIdentifier)* _0_ '}' (_0_ asClause)?\n\nconstructorFunctionParameter <-\n    upperStartIdentifier (_0_ functionParameter)* (_0_ asClause)?\n\nasClause <-\n    'as' _1_ lowerStartIdentifier\n\n# Expressions\n\nexpression <-\n    (letInBlock _NL_IND_)? simpleExpression (_0_ binaryOperator _0_ expression)*\n\nsimpleExpression <-\n    hexNumber\n    / decimal\n    / multilineString\n    / characterLiteral\n    / oneLineString\n    / tupleExpression\n    / listExpression\n    / recordExpression\n    / caseStatement\n    / ifThenElseStatement\n    / anonymousFunction\n    / functionCall\n\ntupleExpression <-\n    '(' _0_ expression (_0_ ',' _0_ expression)* _0_ ')'\n    / '(' _0_ ')'\n\nlistExpression <-\n    '[' _0_ expression (_0_ ',' _0_ expression)* _0_ ']'\n    / '[' _0_ ']'\n\nrecordExpression <-\n    '{' _0_\n    (lowerStartIdentifier _0_ '|' _0_)?\n    recordExpressionAssignment (_0_ ',' _0_ recordExpressionAssignment)* _0_\n    '}'\n    / '{' _0_ '}'\n\nrecordExpressionAssignment <-\n    lowerStartIdentifier _0_ '=' _0_ expression\n\nanonymousFunction <-\n    '\\\\' _0_ functionParameterList _0_ '->' _0_ expression\n\nfunctionCall <-\n    ( dottedIdentifier\n      / '.' lowerStartIdentifier\n      / '(' binaryOperator ')'\n    ) (_1_ expression)*\n\n# Let/in block\n#\n# We'll treat let/in blocks very simply - we'll consider each line\n# and expect the whole line either to be the start of a function\n# definition (perhaps with some of its body) or its body. So something\n# like 'f x y =' will have to be on one line.\n\nletInBlock <-\n    'let' _NL_IND_\n    letInLine (_NL_IND_ letInLine)* _NL_IND_\n    'in'\n\nletInLine <-\n    letInFunctionDefinition\n    / letInBlock\n    / letInFunctionBody\n\nletInFunctionDefinition <-\n    <nonKeywordIdentifier> WS* <letInFunctionParameters>? WS* '=' Non_NL* {\n        int r = makeElmTag(auxil, $1, $1s, K_FUNCTION, ROLE_DEFINITION_INDEX);\n        addElmSignature(r, $2);\n    }\n\nletInFunctionParameters <-\n    nonKeywordIdentifier (WS+ nonKeywordIdentifier)*\n\nletInFunctionBody <-\n    !('let' / 'in') Non_NL+\n\n# Case statements\n#\n# We're going to be pretty loose with case statements, otherwise we'd\n# have to follow Elm's indentation rules. So we'll just say\n# the body of a case statement is a series of patterns like this:\n# <something> -> <expression>. The <expression> might well swallow\n# up a bit of the next case pattern (because to do otherwise requires\n# following Elm's indentation rules), so that's why we just specify\n# <something>.\n\ncaseStatement <-\n    'case' _1_ expression _0_ 'of' _1_\n    caseClauseList\n\ncaseClauseList <-\n    caseClause (_1_ caseClause)*\n\ncaseClause <-\n    roughCasePatternChar* '->' _0_ expression\n\nroughCasePatternChar <-\n    !('->' / TLSS / lineComment / delimitedComment / NL) .\n\n# If/then/else statements\n\nifThenElseStatement <-\n    'if' _1_ expression _1_\n    'then' _1_ expression _1_\n    'else' _1_ expression\n\n# Binary operators\n\nbinaryOperator <-\n    '>>' / '<<' / '|>' / '<|'\n    / '//' / '++' / '::'\n    / '==' / '/='\n    / '&&' / '||'\n    / '<=' / '>='\n    / '<' / '>'\n    / '+' / '-' / '*' / '/' / '^'\n\n# Sometimes we just need to ignore the rest of the (top level) statement\n\nignoreRestOfStatement <-\n    (multilineString / Non_WS_or_NL+) (_1_ ignoreRestOfStatement)*\n\nmultilineString <-\n    '\"\"\"' (!'\"\"\"' .)* '\"\"\"'\n\n# Low level tokens -------------------------------------------------------\n\n# Identifiers\n\nnaiveIdentifier <- [A-Za-z_] alphanumeric*\n\nupperStartIdentifier <- [A-Z] alphanumeric*\n\nlowerStartIdentifier <- !keyword [a-z_] alphanumeric*\n\nalphanumeric <- [A-Za-z0-9_]\n\nnonKeywordIdentifier <-\n    !keyword naiveIdentifier\n\nkeyword <-\n    'type' !alphanumeric\n    / 'module' !alphanumeric\n    / 'port' !alphanumeric\n    / 'alias' !alphanumeric\n    / 'as' !alphanumeric\n    / 'exposing' !alphanumeric\n    / 'import' !alphanumeric\n    / 'let' !alphanumeric\n    / 'in' !alphanumeric\n    / 'case' !alphanumeric\n    / 'of' !alphanumeric\n    / 'if' !alphanumeric\n    / 'then' !alphanumeric\n    / 'else' !alphanumeric\n\ndottedIdentifier <- nonKeywordIdentifier ('.' nonKeywordIdentifier)*\n\n# Numbers\n\ndecimal <-\n    exponentialDecimal\n    / simpleDecimal\n\nexponentialDecimal <-\n    simpleDecimal 'e' simpleInteger\n\nsimpleDecimal <-\n    simpleInteger ('.' digits)?\n    / '.' digits+\n\nsimpleInteger <- [-+]? digits\n\ndigits <- [0-9]+\n\nhexNumber <- '0x' [0-9A-Fa-f]+\n\n# One line strings and characters\n\noneLineString <- '\"' inStringChar* '\"'\n\ncharacterLiteral <- \"'\" inStringChar \"'\"\n\ninStringChar <-\n    !('\"' / NL)\n    ( inStringUnicodeChar / inStringEscapedChar / inStringPlainChar )\n\ninStringPlainChar <-\n    !('\"' / '\\\\' / NL) .\n\ninStringEscapedChar <-\n    '\\\\' !('u' / NL) .\n\ninStringUnicodeChar <-\n    '\\\\u{' [0-9A-Fa-f]+ '}'\n\n# Ignorable things -------------------------------------------------------\n\n# Simple things...\n\nWS <- [ \\t]+\nNL <- '\\n' / '\\f' / '\\r' '\\n'?\nNon_NL <- [^\\n\\r\\f]\nNon_WS_or_NL <- [^ \\t\\n\\r\\f]\nEOF <- !.\n\n# A delimited comment is effectively \"nothing\", even if it spans several\n# lines. But it does separate two tokens.\n#\n# A line comment can only come at the end of a line. Notice here it doesn't\n# include the actual newline.\n\ndelimitedComment <- '{-' (delimitedComment / !'-}' .)* '-}'\n\nlineComment <- '--' Non_NL*\n\n# Elm whitespacing is a bit special...\n# - Two statements are at the same level (eg at the top level, or statements\n#   in the same let...in block) only if they begin with the same indentation.\n# - One line has more indentation than the previous line then it is a\n#   continuation of that previous line.\n# - But sometimes several statements can appear on the same line if tokens\n#   make it obvious. Eg this is okay:\n#   Eg: 'myFunc = let f x y = x + y in f 3 4'\n#\n# We'll only worry about top level statements for this part. But we still\n# need to know\n# - when a top level statement begins; and\n# - when two sequential tokens are part of the same top level statement.\n#   They may be separated by a combination of whitespace, comments, and\n#   newlines, but if there is a newline then that will always be followed\n#   by an indent.\n#\n# When considering how one token relates to the next in top level statements\n# we should only need three kinds of \"join\"s:\n# - Where we need whitespace, such as 'import MyModule', but that space\n#   may occur over multiple lines. If it's over multiple lines, the\n#   second token needs to be somewhat in from the first column of text.\n#   We'll call this _1_ - ie at least one space.\n# - Where we don't need whitespace, such as 'f = 3', but that space\n#   may occur over multiple lines. If it's over multiple lines then again\n#   the second token needs to be somewhat in from the first column of text.\n#   We'll call this _0_ - ie possibly zero space.\n# - When we've got an end of statement, and the next token is some\n#   meaningful code (not a comment) and starts in the first column of text.\n#   Then that next token is the start of the next top level statement.\n#   We'll call this TLSS, for top level statement separator.\n#\n# We can define _1_ as\n# - The longest possible sequence of whitespace, delimited comments,\n#   newlines, and line comments, as long as it ends with a whitespace\n#   or a delimited comment, because then it won't be in the first column.\n#\n# We can define _0_ as\n# - _1_ or the empty string.\n#\n# We can define TLSS as\n# - The longest possible sequence of whitespace, delimited comments,\n#   newlines, and line comments, as long as it ends with a newline or EOF\n#   (and there's no more ignorable characters after that).\n#\n# PEG parsing tip: If we want to define a sequence like 'the longest\n# sequence of As, Bs and Cs, as long as it ends with C' we define a short\n# sequence like 'the longest sequence of As and Bs, then a C' and then\n# define 'the longest sequence of those'.\n\n_1_short <-\n    (lineComment / NL)* (WS / delimitedComment)\n\n_1_ <- _1_short+\n\n\n_0_ <- _1_ / ''\n\nTLSS_short <-\n    (WS / lineComment / delimitedComment)* (NL / EOF)\n\nTLSS <-\n    TLSS_short+\n    !(WS / lineComment / delimitedComment)\n\n# An end of statement marks the end of a top level statement, but\n# doesn't consume anything\n\nEOS <- &( TLSS / EOF )\n\n# When considering lines in a let/in block we'll want to look for\n# a newline and an indent. There may be some delimited comments etc\n# in between.\n\n_NL_IND_ <-\n    TLSS_short+ WS+\n\n%%\n#include \"elm_post.h\"\n"
  },
  {
    "path": "peg/elm_post.h",
    "content": "/*\n *   Copyright (c) 2022 Nik Silver\n *   based on the Kotlin code by Jan Dolinár\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions to generate tags for Elm.\n *   See https://elm-lang.org/docs/syntax for language reference.\n */\n\n/*\n *   INCLUDE FILES\n */\n#include \"parse.h\"\n#include \"trace.h\"\n\n/*\n * FUNCTION DEFINITIONS\n */\n\n/* kind - The kind of this tag.\n * role - The role this tag plays. But def(ined) is expressed by setting\n *     this to ROLE_DEFINITION_INDEX.\n * pushScope - If true, also update the scope to be this tag.\n */\nstatic int makeElmTag (struct parserCtx *auxil, const char *name, long offset, int kind, int role)\n{\n\ttagEntryInfo e;\n\n\tif (role == ROLE_DEFINITION_INDEX)\n\t{\n\t\tinitTagEntry (&e, name, kind);\n\t}\n\telse\n\t{\n\t\tinitRefTagEntry (&e, name, kind, role);\n\t}\n\n\tlong abs_offset = translateFileOffset (offset);\n\tunsigned long lineNumber = getInputLineNumberForFileOffset (abs_offset);\n\tupdateTagLine (&e, lineNumber, getInputFilePositionForLine (lineNumber));\n\te.extensionFields.scopeIndex = BASE_SCOPE (auxil);\n\tint scope_index = makeTagEntry (&e);\n\treturn scope_index;\n}\n\n/* Like makeElmTag, but have this tag be the latest scope.\n */\nstatic int makeElmTagSettingScope (struct parserCtx *auxil, const char *name, long offset, int kind, int role)\n{\n\t// Here is a useless line just to use a function and so\n\t// get rid of a compiler warning.\n\tif (1 < 0)\n\t{\n\t\tPEEK_KIND (auxil);\n\t}\n\t// The real function starts here...\n\n\tint scope_index = makeElmTag (auxil, name, offset, kind, role);\n\tSET_SCOPE (auxil, scope_index);\n\treturn scope_index;\n}\n\nstatic void addElmSignature(int scope_index, const char *sig)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (scope_index);\n\n\tif (e)\n\t{\n\t\tvString *vsig = collapseWhitespace (sig);\n\n\t\te->extensionFields.signature = vStringDeleteUnwrap (vsig);\n\t}\n}\n\nstatic void addElmTypeRef(int scope_index, const char *sig)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (scope_index);\n\n\tif (e)\n\t{\n\t\tvString *vsig = collapseWhitespace (sig);\n\n\t\te->extensionFields.typeRef [0] = eStrdup (\"typename\");\n\t\te->extensionFields.typeRef [1] = vStringDeleteUnwrap (vsig);\n\t}\n}\n\n/* There are several steps to making the type of constructors within\n * a custom type:\n *   1. Initialise the fields when we encounter the custom type declaration.\n *   2. Initialise the subtype field (do this for each new constructor).\n *   3. Add each subtype as we find it.\n *   4. Make the typeref field.\n *   5. Tidy up\n */\nstatic void initElmConstructorFields (struct parserCtx *auxil, const char *name)\n{\n\tauxil->customType = vStringNewInit (name);\n\tauxil->consSubtype = vStringNew ();\n}\n\nstatic void initElmConstructorSubtypeFields (struct parserCtx *auxil)\n{\n\tvStringClear (auxil->consSubtype);\n}\n\nstatic void addElmConstructorSubtype (struct parserCtx *auxil, const char *name)\n{\n\tvStringCatS (auxil->consSubtype, name);\n\tvStringCatS (auxil->consSubtype, \" -> \");\n}\n\nstatic void addElmConstructorTypeRef (struct parserCtx *auxil, int tag_index)\n{\n\tvStringCat (auxil->consSubtype, auxil->customType);\n\taddElmTypeRef (tag_index, vStringValue (auxil->consSubtype));\n}\n\nstatic void tidyElmConstructorFields (struct parserCtx *auxil)\n{\n\tvStringDelete (auxil->consSubtype);\n\tvStringDelete (auxil->customType);\n}\n\n/* For a signature such as \"a1   b2  c3\" we want to transform it\n * to \"a1 b2 c3\" for the signature field.\n */\nstatic vString *collapseWhitespace (const char *sig)\n{\n\tvString *vstr = vStringNew ();\n\n\tconst char *c = sig;\n\tchar c2;\n\tint found_ws = 0;\n\n\tfor ( ; *c != '\\0'; c++)\n\t{\n\t\t// The character, in case we need to change it\n\t\tc2 = *c;\n\n\t\tif (isspace ((unsigned char) c2))\n\t\t{\n\t\t\t// It's whitespace. Make it plain space\n\t\t\tc2 = ' ';\n\t\t\tif (found_ws)\n\t\t\t{\n\t\t\t\t// We found whitespace just before, so ignore this\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfound_ws = 1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfound_ws = 0;\n\t\t}\n\t\tvStringPut (vstr, c2);\n\t}\n\n\treturn vstr;\n}\n\nstatic void ctxInit (struct parserCtx *auxil)\n{\n\tBASE_INIT (auxil, K_MODULE);\n}\n\nstatic void ctxFini (struct parserCtx *auxil)\n{\n\tBASE_FINI (auxil);\n}\n\nstatic void findElmTags (void)\n{\n\tstruct parserCtx auxil;\n\n\tctxInit (&auxil);\n\tpelm_context_t *pctx = pelm_create (&auxil);\n\n\twhile (pelm_parse (pctx, NULL) && (! BASE_ERROR (&auxil)))\n\t\t;\n\n\tpelm_destroy (pctx);\n\tctxFini (&auxil);\n}\n\nextern parserDefinition *ElmParser (void)\n{\n\tstatic const char *const extensions [] = { \"elm\", NULL };\n\tparserDefinition *def = parserNew (\"Elm\");\n\tdef->kindTable = ElmKinds;\n\tdef->kindCount = ARRAY_SIZE (ElmKinds);\n\tdef->extensions = extensions;\n\tdef->parser = findElmTags;\n\tdef->fieldTable = ElmFields;\n\tdef->fieldCount = ARRAY_SIZE (ElmFields);\n\tdef->useCork = true;\n\tdef->enabled    = true;\n\t//def->requestAutomaticFQTag = true;\n\tdef->defaultScopeSeparator = \".\";\n\treturn def;\n}\n"
  },
  {
    "path": "peg/elm_pre.h",
    "content": "/*\n *   Copyright (c) 2022 Nik Silver\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains macros, data decls and prototypes to generate tags for Elm.\n */\n\n/*\n *   INCLUDE FILES\n */\n\n#include \"kind.h\"\n#include \"peg_common.h\"\n\n/*\n * This allows us to save and restore the module scope.\n * We want to do this because it's unhelpful to say that an imported item\n * is the scope of the importing module.\n */\n\n// Remember the scope of the module tag. But at first there is none (CORK_NIL).\nstatic int elm_module_scope_index;\n\n#define ELM_INIT_MODULE_SCOPE \\\n\telm_module_scope_index = CORK_NIL\n#define ELM_SAVE_MODULE_SCOPE \\\n\tif (elm_module_scope_index != CORK_NIL) { \\\n\t\tPOP_SCOPE (auxil); \\\n\t}\n#define ELM_RESTORE_MODULE_SCOPE \\\n\tif (elm_module_scope_index != CORK_NIL) { \\\n\t\tSET_SCOPE (auxil, elm_module_scope_index); \\\n\t} else { \\\n\t\tPOP_SCOPE (auxil); \\\n\t}\n\n/*\n *   DATA DECLARATIONS\n */\ntypedef enum {\n\tK_MODULE,\n\tK_NAMESPACE,\n\tK_TYPE,\n\tK_CONSTRUCTOR,\n\tK_ALIAS,\n\tK_PORT,\n\tK_FUNCTION,\n\tCOUNT_KINDS,\n} ElmKind;\n\n/* We only define roles which aren't def(ined)\n */\ntypedef enum {\n\tELM_MODULE_IMPORTED,\n} elmModuleRoles;\n\nstatic roleDefinition ElmModuleRoles [] = {\n\t{ true, \"imported\", \"module imported\" },\n};\n\n#define define_elm_role(NAME,Name)\t\t\t\t\t\t\t\\\n\ttypedef enum {\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tELM_##NAME##_EXPOSED,\t\t\t\t\t\t\t\t\\\n\t} elm##Name##Roleds;\t\t\t\t\t\t\t\t\t\\\n\tstatic roleDefinition Elm##Name##Roles [] = {\t\t\t\\\n\t\t{ true, \"exposed\", \"item exposed from a module\" },\t\\\n\t}\ndefine_elm_role(TYPE,Type);\ndefine_elm_role(CONSTRUCTOR,Constructor);\ndefine_elm_role(FUNCTION,Function);\n\ntypedef enum {\n\tF_MODULENAME,\n\tCOUNT_FIELDS,\n} ElmField;\n\nstatic fieldDefinition ElmFields [COUNT_FIELDS] = {\n\t{ .name        = \"moduleName\",\n\t  .description = \"actual name of renamed module\",\n\t  .enabled     = true },\n};\n\n/* Use referenceOnly = true when a tag must always appear\n * as role that's not def(ined).\n */\nstatic kindDefinition ElmKinds [COUNT_KINDS] = {\n\t{ true, 'm', \"module\", \"modules\",\n\t  .referenceOnly = false, ATTACH_ROLES (ElmModuleRoles) },\n\t{ true, 'n', \"namespace\", \"modules renamed\", },\n\t{ true, 't', \"type\", \"types\",\n\t  .referenceOnly = false, ATTACH_ROLES (ElmTypeRoles) },\n\t{ true, 'c', \"constructor\", \"constructors\",\n\t  .referenceOnly = false, ATTACH_ROLES (ElmConstructorRoles) },\n\t{ true, 'a', \"alias\", \"aliases\", },\n\t{ true, 'p', \"port\", \"ports\", },\n\t{ true, 'f', \"function\", \"functions\",\n\t  .referenceOnly = false, ATTACH_ROLES (ElmFunctionRoles) },\n};\n\nstruct parserCtx {\n\tstruct parserBaseCtx base;\n\tvString *customType;\n\tvString *consSubtype;\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n#define USE_KIND_STACK KIND_GHOST_INDEX\nstatic int makeElmTag (struct parserCtx *auxil, const char *name, long offset, int kind, int role);\nstatic int makeElmTagSettingScope (struct parserCtx *auxil, const char *name, long offset, int kind, int role);\nstatic void addElmSignature(int scope_index, const char *sig);\nstatic void addElmTypeRef(int scope_index, const char *str);\nstatic void initElmConstructorFields (struct parserCtx *auxil, const char *name);\nstatic void initElmConstructorSubtypeFields (struct parserCtx *auxil);\nstatic void addElmConstructorSubtype (struct parserCtx *auxil, const char *name);\nstatic void addElmConstructorTypeRef (struct parserCtx *auxil, int tag_index);\nstatic void tidyElmConstructorFields (struct parserCtx *auxil);\nstatic vString *collapseWhitespace (const char *sig);\n"
  },
  {
    "path": "peg/kotlin.peg",
    "content": "# Copyright (c) 2021 Jan Dolinár\n#\n# This source code is released for free distribution under the terms of the\n# GNU General Public License version 2.\n#\n# This file contains description of Kotlin grammar based on the ANTLR grammar\n# from https://github.com/Kotlin/kotlin-grammar-gpl2.\n#\n# Notes:\n#   1. This file was originally derived from files (reference grammar files) in https://github.com/Kotlin/kotlin-spec\n#   2. Kotlin/kotlin-spec is distributed under Apache2 license\n#   3. I have requested the original developers to \"re-license or dual-license\" (see https://github.com/Kotlin/kotlin-spec/issues/70)\n#   4. The request was accepted and the original developer made a new repository https://github.com/Kotlin/kotlin-grammar-gpl2\n#      for redistributing the reference grammar files under GPLv2 license.\n#   5. This file is now derived from Kotlin/kotlin-grammar-gpl2 repository.\n#   6. Unlike many other files in Universal Ctags, this source code is released strictly under GPLv2\n#      and should not be relicensed to later versions of GPL.\n\n\n\n%prefix \"pkotlin\"\n\n%auxil\t\"struct parserCtx *\"\n\n%earlysource {\n    #include \"general.h\"\n}\n\n%header {\n\tstruct parserCtx;\n}\n\n%source {\n#include \"kotlin_pre.h\"\n}\n\nfile <- shebangLine? NL* fileAnnotation* _* packageHeader* _* importList* _* (filePart / _ / unparsable)* EOF\nfilePart <- (topLevelObject / (statement _* semi)) {resetFailure(auxil, $0s);}\nunparsable <- [^\\n]+ NL* {reportFailure(auxil, $0s);}\n\n### Converted from peg/kotlin/KotlinParser.g4\n\n# options\n# // SECTION: general\n#kotlinFile <- shebangLine? NL* fileAnnotation* _* packageHeader _* importList _* topLevelObject* EOF\n#script <- shebangLine? NL* fileAnnotation* _* packageHeader _* importList _* (statement _* semi)* EOF\nshebangLine <- ShebangLine _* NL+\nfileAnnotation <- (AT_NO_WS / AT_PRE_WS) FILE NL* COLON _* NL* (LSQUARE _* unescapedAnnotation+ _* RSQUARE / unescapedAnnotation) _* NL*\npackageHeader <- PACKAGE {PUSH_KIND(auxil, K_PACKAGE);} _ <identifier> {makeKotlinTag(auxil, $1, $1s, true);} _* semi?\nimportList <- importHeader+\nimportHeader <- IMPORT _ identifier (DOT MULT / importAlias)? _* semi? _*\nimportAlias <- _ AS _ simpleIdentifier\ntopLevelObject <- declaration _* semis?\ntypeAlias <- modifiers? _* TYPE_ALIAS {PUSH_KIND(auxil, K_TYPEALIAS);} (_ / NL)* <simpleIdentifier> {makeKotlinTag(auxil, $1, $1s, false);} _* (__* typeParameters)? __* ASSIGNMENT __* type\ndeclaration <- classDeclaration / objectDeclaration / functionDeclaration / propertyDeclaration / typeAlias\n\n# // SECTION: classes\nclassDeclaration <- modifiers? (CLASS {PUSH_KIND(auxil, K_CLASS);} / (FUN __*)? INTERFACE {PUSH_KIND(auxil, K_INTERFACE);}) _ NL* <simpleIdentifier> {makeKotlinTag(auxil, $1, $1s, true);} (__* typeParameters)? (__* primaryConstructor)? (__* COLON __* delegationSpecifiers)? (__* typeConstraints)? (__* classBody / __* enumClassBody)? {POP_SCOPE(auxil);}\nprimaryConstructor <- (modifiers? CONSTRUCTOR __*)? classParameters\nclassBody <- LCURL __* classMemberDeclarations __* RCURL\nclassParameters <- LPAREN __* (classParameter (__* COMMA __* classParameter)* (__* COMMA)?)? __* RPAREN\nclassParameter <- (modifiers? _* VAL {PUSH_KIND(auxil, K_CONSTANT);} / modifiers? _* VAR {PUSH_KIND(auxil, K_VARIABLE);} / modifiers? {PUSH_KIND(auxil, K_IGNORE);} _*)? __* <simpleIdentifier> {makeKotlinTag(auxil, $1, $1s, true);} _* COLON __* type (__* ASSIGNMENT __* expression)? {POP_SCOPE(auxil);}\ndelegationSpecifiers <- annotatedDelegationSpecifier (__* COMMA __* annotatedDelegationSpecifier)*\ndelegationSpecifier <- constructorInvocation / explicitDelegation / userType / functionType\nconstructorInvocation <- userType __* valueArguments\nannotatedDelegationSpecifier <- annotation* __* delegationSpecifier\nexplicitDelegation <- (userType / functionType) __* BY __* expression\ntypeParameters <- LANGLE __* typeParameter (__* COMMA __* typeParameter)* (__* COMMA)? __* RANGLE\ntypeParameter <- typeParameterModifiers? __* simpleIdentifier (__* COLON __* type)?\ntypeConstraints <- WHERE __* typeConstraint (__* COMMA __* typeConstraint)*\ntypeConstraint <- annotation* simpleIdentifier __* COLON __* type\n\n# // SECTION: classMembers\nclassMemberDeclarations <- (classMemberDeclaration semis?)*\nclassMemberDeclaration <- secondaryConstructor / anonymousInitializer / companionObject / declaration\nanonymousInitializer <- INIT __* block\ncompanionObject <- modifiers? COMPANION __* (DATA __*)? OBJECT {PUSH_KIND(auxil, K_OBJECT);} <(__* simpleIdentifier)?> {makeKotlinTag(auxil, $1e-$1s != 0 ? $1 : \"Companion\", $1s, true);} (__* COLON __* delegationSpecifiers)? (__* classBody)? {POP_SCOPE(auxil);}\nfunctionValueParameters <- LPAREN __* (functionValueParameter (__* COMMA __* functionValueParameter)* (__* COMMA)?)? __* RPAREN\nfunctionValueParameter <- parameterModifiers? _* parameter (__* ASSIGNMENT __* expression)?\nfunctionDeclaration <- modifiers? _* FUN {PUSH_KIND(auxil, K_METHOD);} _* (__* typeParameters)? _* (__* receiverTypeAndDot)? __* <simpleIdentifier> {makeKotlinTag(auxil, $1, $1s, true);} __* functionValueParameters _* (__* COLON __* type)? _* (__* typeConstraints)? _* (__* functionBody)? {POP_SCOPE(auxil);}\nfunctionBody <- block / ASSIGNMENT __* expression\nvariableDeclaration <- annotation* __* <simpleIdentifier> {makeKotlinTag(auxil, $1, $1s, false);} (__* COLON __* type)?\nmultiVariableDeclaration <- LPAREN __* variableDeclaration _* (__* COMMA __* variableDeclaration)* _* (__* COMMA)? __* RPAREN\npropertyDeclaration <- modifiers? _* (VAL {PUSH_KIND(auxil, K_CONSTANT);} / VAR {PUSH_KIND(auxil, K_VARIABLE);}) _ (__* typeParameters)? (__* receiverTypeAndDot)? (__* (multiVariableDeclaration / variableDeclaration)) (__* typeConstraints)? (__* (ASSIGNMENT __* expression / propertyDelegate))? (semi? _* setter (NL* semi? _* getter)? / semi? _* getter (NL* semi? _* setter)?)?\npropertyDelegate <- BY __* expression\n# TODO: better handling of empty getters and setters?\ngetter <- (modifiers _*)? GET __* LPAREN __* RPAREN (__* COLON __* type)? __* functionBody / (modifiers _*)? GET !(_* [^;\\r\\n])\nsetter <- (modifiers _*)? SET __* LPAREN __* parameterWithOptionalType (__* COMMA)? __* RPAREN (__* COLON __* type)? __* functionBody / (modifiers _*)? SET !(_* [^;\\r\\n])\nparametersWithOptionalType <- LPAREN __* (parameterWithOptionalType (__* COMMA __* parameterWithOptionalType)* (__* COMMA)?)? __* RPAREN\nparameterWithOptionalType <- parameterModifiers? simpleIdentifier __* (COLON __* type)?\nparameter <- simpleIdentifier __* COLON __* type\nobjectDeclaration <- modifiers? _* OBJECT {PUSH_KIND(auxil, K_OBJECT);} __* <simpleIdentifier> {makeKotlinTag(auxil, $1, $1s, true);} (__* COLON __* delegationSpecifiers)? (__* classBody)? {POP_SCOPE(auxil);}\nsecondaryConstructor <- modifiers? CONSTRUCTOR __* functionValueParameters (__* COLON __* constructorDelegationCall)? __* block?\nconstructorDelegationCall <- THIS __* valueArguments / SUPER __* valueArguments\n\n# // SECTION: enumClasses\nenumClassBody <- LCURL __* enumEntries? (__* SEMICOLON __* classMemberDeclarations)? __* RCURL\nenumEntries <- enumEntry (__* COMMA __* enumEntry)* __* COMMA?\nenumEntry <- (modifiers __*)? simpleIdentifier (__* valueArguments)? (__* classBody)?\n\n# // SECTION: types\ntype <- typeModifiers? ( functionType / nullableType / parenthesizedType / typeReference)\ntypeReference <- userType / DYNAMIC\nnullableType <- (typeReference / parenthesizedType) __* quest+\nquest <- !elvis (QUEST_WS / QUEST_NO_WS)\nuserType <- simpleUserType (__* DOT __* simpleUserType)*\nsimpleUserType <- simpleIdentifier (__* typeArguments)?\ntypeProjection <- typeProjectionModifiers? type / MULT\ntypeProjectionModifiers <- typeProjectionModifier+\ntypeProjectionModifier <- varianceModifier __* / annotation\nfunctionType <- (receiverType __* DOT __*)? functionTypeParameters __* ARROW __* type\nfunctionTypeParameters <- LPAREN __* (parameter / type)? _* (__* COMMA __* (parameter / type))* _* (__* COMMA)? __* RPAREN\nparenthesizedType <- LPAREN __* type __* RPAREN\nreceiverType <- (typeModifiers _*)? (nullableType / parenthesizedType / typeReference)\n# parenthesizedUserType <- LPAREN __* userType __* RPAREN / LPAREN __* parenthesizedUserType __* RPAREN\nreceiverTypeAndDot <- (typeModifiers _*)? (nullableType __* DOT __* / parenthesizedType __* DOT __* / (simpleUserType __* DOT __*)+)\n\n# // SECTION: statements\n#statements <- (statement (semis statement)*)? semis?\nstatements <- (statement _* (semis _* statement _*)*)? _* semis?\nstatement <- (label / annotation)* ( declaration / assignment / loopStatement / expression)\nlabel <- simpleIdentifier (AT_POST_WS / AT_NO_WS) __*\ncontrolStructureBody <- block / statement\nblock <- LCURL __* statements __* RCURL\nloopStatement <- forStatement / whileStatement / doWhileStatement\nforStatement <- FOR __* LPAREN _* annotation* _* (variableDeclaration / multiVariableDeclaration) _ IN _ inside_expression _* RPAREN __* (controlStructureBody)?\nwhileStatement <- WHILE __* LPAREN _* inside_expression _* RPAREN __* controlStructureBody / WHILE __* LPAREN _* expression _* RPAREN __* SEMICOLON\ndoWhileStatement <- DO __* controlStructureBody? __* WHILE __* LPAREN _* expression _* RPAREN\nassignment <- directlyAssignableExpression _* ASSIGNMENT __* expression / assignableExpression _* assignmentAndOperator __* expression\nsemi <- (_* (SEMICOLON / NL) _*) NL*\nsemis <- (_* (SEMICOLON / NL) _*)+\n\n# // SECTION: expressions\nexpression <- disjunction\ndisjunction <- conjunction (__* DISJ __* conjunction)*\nconjunction <- equality (__* CONJ __* equality)*\nequality <- comparison (_* equalityOperator __* comparison _*)*\ncomparison <- genericCallLikeComparison (_* comparisonOperator __* genericCallLikeComparison _*)*\ngenericCallLikeComparison <- infixOperation (_* callSuffix)*\ninfixOperation <- elvisExpression (_* inOperator __* elvisExpression / _* isOperator __* type)*\nelvisExpression <- infixFunctionCall (__* elvis __* infixFunctionCall)*\nelvis <- QUEST_NO_WS COLON\ninfixFunctionCall <- rangeExpression (_* simpleIdentifier __* rangeExpression)*\nrangeExpression <- additiveExpression (_* (RANGE_UNTIL / RANGE) __* additiveExpression)*\nadditiveExpression <- multiplicativeExpression (_* additiveOperator __* multiplicativeExpression)*\nmultiplicativeExpression <- asExpression (_* multiplicativeOperator __* asExpression)*\nasExpression <- prefixUnaryExpression (__* asOperator __* type)*\nprefixUnaryExpression <- (unaryPrefix _*)* postfixUnaryExpression\nunaryPrefix <- annotation / label / prefixUnaryOperator __*\npostfixUnaryExpression <- primaryExpression (_* postfixUnarySuffix)+ / primaryExpression\npostfixUnarySuffix <- postfixUnaryOperator / typeArguments / callSuffix / indexingSuffix / navigationSuffix\ndirectlyAssignableExpression <- postfixUnaryExpression _* assignableSuffix / postfixUnaryExpression / simpleIdentifier / parenthesizedDirectlyAssignableExpression\nparenthesizedDirectlyAssignableExpression <- LPAREN __* inside_directlyAssignableExpression __* RPAREN\nassignableExpression <- prefixUnaryExpression / parenthesizedAssignableExpression\nparenthesizedAssignableExpression <- LPAREN __* inside_assignableExpression __* RPAREN\nassignableSuffix <- navigationSuffix / typeArguments / indexingSuffix\nindexingSuffix <- LSQUARE __* inside_expression (__* COMMA __* inside_expression)* (__* COMMA)? __* RSQUARE\nnavigationSuffix <- __* memberAccessOperator __* (simpleIdentifier / parenthesizedExpression / CLASS)\ncallSuffix <- typeArguments? _* valueArguments? _* annotatedLambda / typeArguments? _* valueArguments\nannotatedLambda <- annotation* _* label? __* lambdaLiteral\ntypeArguments <- LANGLE __* typeProjection (__* COMMA __* typeProjection)* (__* COMMA)? __* RANGLE\nvalueArguments <- LPAREN __* RPAREN / LPAREN __* inside_valueArgument (__* COMMA __* inside_valueArgument)* (__* COMMA)? __* RPAREN\n#valueArgument <- annotation? __* (simpleIdentifier __* ASSIGNMENT __*)? MULT? __* expression\nprimaryExpression <- thisExpression / superExpression / ifExpression / whenExpression / tryExpression / jumpExpression / parenthesizedExpression/ callableReference / stringLiteral / functionLiteral / objectLiteral / collectionLiteral  / simpleIdentifier / literalConstant\nparenthesizedExpression <- LPAREN __* inside_expression __* RPAREN\ncollectionLiteral <- LSQUARE __* inside_expression (__* COMMA __* inside_expression)* (__* COMMA)? __* RSQUARE / LSQUARE __* RSQUARE\nliteralConstant <- BooleanLiteral / CharacterLiteral / NullLiteral / RealLiteral / UnsignedLiteral / LongLiteral / HexLiteral / BinLiteral / IntegerLiteral\nstringLiteral <- multiLineStringLiteral / lineStringLiteral\nlineStringLiteral <- QUOTE_OPEN (lineStringExpression / lineStringContent)* QUOTE_CLOSE\n#lineStringLiteral <- QUOTE_OPEN (lineStringExpression / EscapedIdentifier / UniCharacterLiteral / stringChar)* QUOTE_CLOSE\nmultiLineStringLiteral <- TRIPLE_QUOTE_OPEN (multiLineStringExpression / multiLineStringContent / MultiLineStringQuote)* TRIPLE_QUOTE_CLOSE\n#multiLineStringLiteral <- TRIPLE_QUOTE_OPEN (multiLineStringExpression / MultiLineStringQuote / EscapedIdentifier / UniChracterLiteral / stringChar)* TRIPLE_QUOTE_CLOSE\nlineStringContent <- LineStrText / LineStrEscapedChar / LineStrRef\nlineStringExpression <- LineStrExprStart __* expression __* RCURL\nmultiLineStringContent <- MultiLineStrRef / MultiLineStrText / MultiLineStringQuote\nmultiLineStringExpression <- MultiLineStrExprStart __* expression __* RCURL\n\ninside_expression <- inside_disjunction\ninside_disjunction <- inside_conjunction (__* DISJ __* inside_conjunction)*\ninside_conjunction <- inside_equality (__* CONJ __* inside_equality)*\ninside_equality <- inside_comparison ((_ / NL)* equalityOperator __* inside_comparison (_ / NL)*)*\ninside_comparison <- inside_genericCallLikeComparison ((_ / NL)* comparisonOperator __* inside_genericCallLikeComparison (_ / NL)*)*\ninside_genericCallLikeComparison <- inside_infixOperation ((_ / NL)* callSuffix)*\ninside_infixOperation <- inside_elvisExpression ((_ / NL)* inOperator __* inside_elvisExpression / (_ / NL)* isOperator __* type)*\ninside_elvisExpression <- inside_infixFunctionCall (__* elvis __* inside_infixFunctionCall)*\ninside_infixFunctionCall <- inside_rangeExpression ((_ / NL)* simpleIdentifier __* inside_rangeExpression)*\ninside_rangeExpression <- inside_additiveExpression ((_ / NL)* RANGE __* inside_additiveExpression)*\ninside_additiveExpression <- inside_multiplicativeExpression ((_ / NL)* additiveOperator __* inside_multiplicativeExpression)*\ninside_multiplicativeExpression <- inside_asExpression ((_ / NL)* multiplicativeOperator __* inside_asExpression)*\ninside_asExpression <- inside_prefixUnaryExpression (__* asOperator __* type)*\ninside_prefixUnaryExpression <- (inside_unaryPrefix (_ / NL)*)* inside_postfixUnaryExpression\ninside_unaryPrefix <- annotation / label / prefixUnaryOperator __*\ninside_postfixUnaryExpression <- primaryExpression ((_ / NL)* inside_postfixUnarySuffix)+ / primaryExpression\ninside_postfixUnarySuffix <- postfixUnaryOperator / typeArguments / callSuffix / indexingSuffix / navigationSuffix\ninside_directlyAssignableExpression <- inside_postfixUnaryExpression (_ / NL)* assignableSuffix / inside_postfixUnaryExpression / simpleIdentifier / parenthesizedDirectlyAssignableExpression\ninside_assignableExpression <- inside_prefixUnaryExpression / parenthesizedAssignableExpression\ninside_valueArgument <- annotation? __* (simpleIdentifier __* ASSIGNMENT __*)? MULT? __* inside_expression\n\n\n#characterLiteral <- \"'\" (UniCharacterLiteral / EscapedIdentifier / [^\\n\\r'\\\\]) \"'\"\n#stringChar <- [^\"]\n\nlambdaLiteral <- LCURL {PUSH_KIND(auxil, K_METHOD); makeKotlinTag(auxil, \"<lambda>\", $0s, true);} __* statements __* RCURL {POP_SCOPE(auxil);} / LCURL {PUSH_KIND(auxil, K_METHOD); makeKotlinTag(auxil, \"<lambda>\", 8, true);} __* lambdaParameters? __* ARROW __* statements __* RCURL {POP_SCOPE(auxil);}\nlambdaParameters <- lambdaParameter (__* COMMA __* lambdaParameter)* (__* COMMA)?\nlambdaParameter <- variableDeclaration / multiVariableDeclaration (__* COLON __* type)?\nanonymousFunction <- (SUSPEND __*)? FUN {PUSH_KIND(auxil, K_METHOD); makeKotlinTag(auxil, \"<anonymous>\", $0s, true);} (__* type __* DOT)? __* parametersWithOptionalType (__* COLON __* type)? (__* typeConstraints)? (__* functionBody)? {POP_SCOPE(auxil);}\nfunctionLiteral <- lambdaLiteral / anonymousFunction\nobjectLiteral <- (DATA __*)? OBJECT __* COLON __* delegationSpecifiers __* classBody / OBJECT __* classBody\nthisExpression <- THIS_AT / THIS !(Letter / UnicodeDigit)\nsuperExpression <- SUPER_AT / SUPER (LANGLE __* type __* RANGLE)? (AT_NO_WS simpleIdentifier)?\nifExpression <- IF __* LPAREN __* expression __* RPAREN __* controlStructureBody? __* SEMICOLON? __* ELSE __* (controlStructureBody / SEMICOLON) / IF __* LPAREN __* expression __* RPAREN __* (controlStructureBody / SEMICOLON)\nwhenSubject <- LPAREN (annotation* __* VAL __* variableDeclaration __* ASSIGNMENT __*)? expression RPAREN\nwhenExpression <- WHEN __* whenSubject? __* LCURL __* (whenEntry __*)* __* RCURL\nwhenEntry <- whenCondition (__* COMMA __* whenCondition)* (__* COMMA)? __* ARROW __* controlStructureBody semi? / ELSE __* ARROW __* controlStructureBody semi?\nwhenCondition <- expression / rangeTest / typeTest\nrangeTest <- inOperator __* expression\ntypeTest <- isOperator __* type\ntryExpression <- TRY __* block ((__* catchBlock)+ (__* finallyBlock)? / __* finallyBlock)\ncatchBlock <- CATCH __* LPAREN _* (annotation _*)* simpleIdentifier _* COLON _* type (__* COMMA)? _* RPAREN __* block\nfinallyBlock <- FINALLY __* block\njumpExpression <- THROW __* expression / (RETURN_AT / RETURN) _* expression? / CONTINUE_AT / CONTINUE / BREAK_AT / BREAK\ncallableReference <- (receiverType? __* COLONCOLON __* (simpleIdentifier / CLASS))\nassignmentAndOperator <- ADD_ASSIGNMENT / SUB_ASSIGNMENT / MULT_ASSIGNMENT / DIV_ASSIGNMENT / MOD_ASSIGNMENT\nequalityOperator <- EQEQEQ / EQEQ / EXCL_EQEQ / EXCL_EQ\ncomparisonOperator <- LE / GE / LANGLE / RANGLE\ninOperator <- IN / NOT_IN\nisOperator <- IS / NOT_IS\nadditiveOperator <- ADD / SUB\nmultiplicativeOperator <- MULT / DIV / MOD\nasOperator <- AS_SAFE / AS\nprefixUnaryOperator <- INCR / DECR / SUB / ADD / excl\npostfixUnaryOperator <- INCR / DECR / EXCL_NO_WS excl\nexcl <- EXCL_WS / EXCL_NO_WS\nmemberAccessOperator <- DOT / safeNav / COLONCOLON\nsafeNav <- QUEST_NO_WS DOT\n\n# // SECTION: modifiers\nmodifiers <- (annotation / modifier)+\nparameterModifiers <- (annotation / parameterModifier)+\nmodifier <- (classModifier / memberModifier / visibilityModifier / functionModifier / propertyModifier / inheritanceModifier / parameterModifier / platformModifier) __*\ntypeModifiers <- typeModifier+\ntypeModifier <- annotation / SUSPEND __*\nclassModifier <- ENUM / SEALED / ANNOTATION / DATA / INNER\nmemberModifier <- OVERRIDE / LATEINIT\nvisibilityModifier <- PUBLIC / PRIVATE / INTERNAL / PROTECTED\nvarianceModifier <- IN / OUT\ntypeParameterModifiers <- typeParameterModifier+\ntypeParameterModifier <- reificationModifier __* / varianceModifier __* / annotation\nfunctionModifier <- TAILREC / OPERATOR / INFIX / INLINE / EXTERNAL / SUSPEND\npropertyModifier <- CONST\ninheritanceModifier <- ABSTRACT / FINAL / OPEN\nparameterModifier <- VARARG / NOINLINE / CROSSINLINE\nreificationModifier <- REIFIED\nplatformModifier <- EXPECT / ACTUAL\n\n# // SECTION: annotations\nannotation <- (singleAnnotation / multiAnnotation) __*\nsingleAnnotation <- annotationUseSiteTarget __* unescapedAnnotation / (AT_NO_WS / AT_PRE_WS) unescapedAnnotation\nmultiAnnotation <- annotationUseSiteTarget __* LSQUARE unescapedAnnotation+ RSQUARE / (AT_NO_WS / AT_PRE_WS) LSQUARE unescapedAnnotation+ RSQUARE\nannotationUseSiteTarget <- (AT_NO_WS / AT_PRE_WS) (FIELD / PROPERTY / GET / SET / RECEIVER / PARAM / SETPARAM / DELEGATE) __* COLON\nunescapedAnnotation <- userType valueArguments?\n\n# // SECTION: identifiers\nsimpleIdentifier <- !(hardKeyword !(Letter / '_' / UnicodeDigit)) Identifier / ABSTRACT / ANNOTATION / BY / CATCH / COMPANION / CONSTRUCTOR / CROSSINLINE / DATA / DYNAMIC / ENUM / EXTERNAL / FINAL / FINALLY / GET / IMPORT / INFIX / INIT / INLINE / INNER / INTERNAL / LATEINIT / NOINLINE / OPEN / OPERATOR / OUT / OVERRIDE / PRIVATE / PROTECTED / PUBLIC / REIFIED / SEALED / TAILREC / SET / VARARG / WHERE / FIELD / PROPERTY / RECEIVER / PARAM / SETPARAM / DELEGATE / FILE / EXPECT / ACTUAL / CONST / SUSPEND\nidentifier <- simpleIdentifier (__* DOT simpleIdentifier)*\n\nhardKeyword <- AS / BREAK / CLASS / CONTINUE / DO / ELSE / FOR / FUN / IF / IN / INTERFACE / IS / NullLiteral / OBJECT / PACKAGE / RETURN / SUPER / THIS / THROW / TRY / TYPE_ALIAS / TYPEOF / VAL / VAR / WHEN / WHILE / BooleanLiteral\n\n\n### Converted from peg/kotlin/KotlinLexer.g4\n\n\n# // SECTION: lexicalGeneral\nShebangLine <- '#!' [^\\r\\n]*\nDelimitedComment <- '/*' (DelimitedComment / !'*/' .)* '*/'\nLineComment <- '//' [^\\r\\n]*\n#WS <- [\\u0020\\u0009\\u000C]\n#NL <- '\\n' / '\\r' '\\n'?\nHidden <- DelimitedComment / LineComment / WS\n\n# // SECTION: separatorsAndOperations\n#RESERVED <- '...'\nDOT <- '.'\nCOMMA <- ','\nLPAREN <- '('\nRPAREN <- ')'\nLSQUARE <- '['\nRSQUARE <- ']'\nLCURL <- '{'\n# /*\n# * When using another programming language (not Java) to generate a parser,\n# * please replace this code with the corresponding code of a programming language you are using.\n# */\nRCURL <- '}'\nMULT <- '*'\nMOD <- '%'\nDIV <- '/'\nADD <- '+'\nSUB <- '-'\nINCR <- '++'\nDECR <- '--'\nCONJ <- '&&'\nDISJ <- '||'\nEXCL_WS <- '!' Hidden\nEXCL_NO_WS <- '!'\nCOLON <- ':'\nSEMICOLON <- ';'\nASSIGNMENT <- '=' !'='\nADD_ASSIGNMENT <- '+='\nSUB_ASSIGNMENT <- '-='\nMULT_ASSIGNMENT <- '*='\nDIV_ASSIGNMENT <- '/='\nMOD_ASSIGNMENT <- '%='\nARROW <- '->'\n#DOUBLE_ARROW <- '=>'\nRANGE <- '..'\nRANGE_UNTIL <- '..<'\nCOLONCOLON <- '::'\n#DOUBLE_SEMICOLON <- ';;'\n#HASH <- '#'\nAT_NO_WS <- '@'\nAT_POST_WS <- '@' (Hidden / NL)\nAT_PRE_WS <- (Hidden / NL) '@'\n#AT_BOTH_WS <- (Hidden / NL) '@' (Hidden / NL)\nQUEST_WS <- '?' Hidden\nQUEST_NO_WS <- '?'\nLANGLE <- '<'\nRANGLE <- '>'\nLE <- '<='\nGE <- '>='\nEXCL_EQ <- '!='\nEXCL_EQEQ <- '!=='\nAS_SAFE <- 'as?'\nEQEQ <- '=='\nEQEQEQ <- '==='\n#SINGLE_QUOTE <- '\\''\n\n# // SECTION: keywords\nRETURN_AT <- 'return@' Identifier\nCONTINUE_AT <- 'continue@' Identifier\nBREAK_AT <- 'break@' Identifier\nTHIS_AT <- 'this@' Identifier\nSUPER_AT <- 'super@' Identifier\nFILE <- 'file' !(Letter / UnicodeDigit)\nFIELD <- 'field' !(Letter / UnicodeDigit)\nPROPERTY <- 'property' !(Letter / UnicodeDigit)\nGET <- 'get' !(Letter / UnicodeDigit)\nSET <- 'set' !(Letter / UnicodeDigit)\nRECEIVER <- 'receiver' !(Letter / UnicodeDigit)\nPARAM <- 'param' !(Letter / UnicodeDigit)\nSETPARAM <- 'setparam' !(Letter / UnicodeDigit)\nDELEGATE <- 'delegate' !(Letter / UnicodeDigit)\nPACKAGE <- 'package' !(Letter / UnicodeDigit)\nIMPORT <- 'import' !(Letter / UnicodeDigit)\nCLASS <- 'class' !(Letter / UnicodeDigit)\nINTERFACE <- 'interface' !(Letter / UnicodeDigit)\nFUN <- 'fun' !(Letter / UnicodeDigit)\nOBJECT <- 'object' !(Letter / UnicodeDigit)\nVAL <- 'val' !(Letter / UnicodeDigit)\nVAR <- 'var' !(Letter / UnicodeDigit)\nTYPE_ALIAS <- 'typealias' !(Letter / UnicodeDigit)\nCONSTRUCTOR <- 'constructor' !(Letter / UnicodeDigit)\nBY <- 'by' !(Letter / UnicodeDigit)\nCOMPANION <- 'companion' !(Letter / UnicodeDigit)\nINIT <- 'init' !(Letter / UnicodeDigit)\nTHIS <- 'this' !(Letter / UnicodeDigit)\nSUPER <- 'super' !(Letter / UnicodeDigit)\nTYPEOF <- 'typeof' !(Letter / UnicodeDigit)\nWHERE <- 'where' !(Letter / UnicodeDigit)\nIF <- 'if' !(Letter / UnicodeDigit)\nELSE <- 'else' !(Letter / UnicodeDigit)\nWHEN <- 'when' !(Letter / UnicodeDigit)\nTRY <- 'try' !(Letter / UnicodeDigit)\nCATCH <- 'catch' !(Letter / UnicodeDigit)\nFINALLY <- 'finally' !(Letter / UnicodeDigit)\nFOR <- 'for' !(Letter / UnicodeDigit)\nDO <- 'do' !(Letter / UnicodeDigit)\nWHILE <- 'while' !(Letter / UnicodeDigit)\nTHROW <- 'throw' !(Letter / UnicodeDigit)\nRETURN <- 'return' !(Letter / UnicodeDigit)\nCONTINUE <- 'continue' !(Letter / UnicodeDigit)\nBREAK <- 'break' !(Letter / UnicodeDigit)\nAS <- 'as' !(Letter / UnicodeDigit)\nIS <- 'is' !(Letter / UnicodeDigit)\nIN <- 'in' !(Letter / UnicodeDigit)\nNOT_IS <- '!is' !(Letter / UnicodeDigit)\nNOT_IN <- '!in' !(Letter / UnicodeDigit)\nOUT <- 'out' !(Letter / UnicodeDigit)\nDYNAMIC <- 'dynamic' !(Letter / UnicodeDigit)\n\n# // SECTION: lexicalModifiers\nPUBLIC <- 'public' !(Letter / UnicodeDigit)\nPRIVATE <- 'private' !(Letter / UnicodeDigit)\nPROTECTED <- 'protected' !(Letter / UnicodeDigit)\nINTERNAL <- 'internal' !(Letter / UnicodeDigit)\nENUM <- 'enum' !(Letter / UnicodeDigit)\nSEALED <- 'sealed' !(Letter / UnicodeDigit)\nANNOTATION <- 'annotation' !(Letter / UnicodeDigit)\nDATA <- 'data' !(Letter / UnicodeDigit)\nINNER <- 'inner' !(Letter / UnicodeDigit)\nTAILREC <- 'tailrec' !(Letter / UnicodeDigit)\nOPERATOR <- 'operator' !(Letter / UnicodeDigit)\nINLINE <- 'inline' !(Letter / UnicodeDigit)\nINFIX <- 'infix' !(Letter / UnicodeDigit)\nEXTERNAL <- 'external' !(Letter / UnicodeDigit)\nSUSPEND <- 'suspend' !(Letter / UnicodeDigit)\nOVERRIDE <- 'override' !(Letter / UnicodeDigit)\nABSTRACT <- 'abstract' !(Letter / UnicodeDigit)\nFINAL <- 'final' !(Letter / UnicodeDigit)\nOPEN <- 'open' !(Letter / UnicodeDigit)\nCONST <- 'const' !(Letter / UnicodeDigit)\nLATEINIT <- 'lateinit' !(Letter / UnicodeDigit)\nVARARG <- 'vararg' !(Letter / UnicodeDigit)\nNOINLINE <- 'noinline' !(Letter / UnicodeDigit)\nCROSSINLINE <- 'crossinline' !(Letter / UnicodeDigit)\nREIFIED <- 'reified' !(Letter / UnicodeDigit)\nEXPECT <- 'expect' !(Letter / UnicodeDigit)\nACTUAL <- 'actual' !(Letter / UnicodeDigit)\n\n# // SECTION: literals\nDecDigit <- [0-9]\nDecDigitNoZero <- [1-9]\nDecDigitOrSeparator <- DecDigit / '_'\nDecDigits <- DecDigit DecDigitOrSeparator* / DecDigit\nDoubleExponent <- [eE] [-+]? DecDigits\nRealLiteral <- FloatLiteral / DoubleLiteral\nFloatLiteral <- DoubleLiteral [fF] / DecDigits [fF]\nDoubleLiteral <- DecDigits? '.' DecDigits DoubleExponent? / DecDigits DoubleExponent\nIntegerLiteral <- DecDigitNoZero DecDigitOrSeparator* / DecDigit\n#IntegerLiteral <- DecDigitNoZero DecDigitOrSeparator* DecDigit / DecDigit\nHexDigit <- [0-9a-fA-F]\nHexDigitOrSeparator <- HexDigit / '_'\nHexLiteral <- '0' [xX] HexDigit HexDigitOrSeparator* / '0' [xX] HexDigit\nBinDigit <- [01]\nBinDigitOrSeparator <- BinDigit / '_'\nBinLiteral <- '0' [bB] BinDigit BinDigitOrSeparator* / '0' [bB] BinDigit\nUnsignedLiteral <- (HexLiteral / BinLiteral / IntegerLiteral) [uU] [lL]?\nLongLiteral <- (HexLiteral / BinLiteral / IntegerLiteral) [lL]\nBooleanLiteral <- 'true'/ 'false'\nNullLiteral <- 'null'\nCharacterLiteral <- '\\'' (EscapeSeq / [^\\n\\r'\\\\]) '\\''\n\n# // SECTION: lexicalIdentifiers\n#UnicodeDigit <- UNICODE_CLASS_ND\nIdentifier <- '`' [^`\\r\\n]+ '`' / (Letter / '_') (Letter / '_' / UnicodeDigit)*\nIdentifierOrSoftKey <- Identifier / ABSTRACT / ANNOTATION / BY / CATCH / COMPANION / CONSTRUCTOR / CROSSINLINE / DATA / DYNAMIC / ENUM / EXTERNAL / FINAL / FINALLY / IMPORT / INFIX / INIT / INLINE / INNER / INTERNAL / LATEINIT / NOINLINE / OPEN / OPERATOR / OUT / OVERRIDE / PRIVATE / PROTECTED / PUBLIC / REIFIED / SEALED / TAILREC / VARARG / WHERE / GET / SET / FIELD / PROPERTY / RECEIVER / PARAM / SETPARAM / DELEGATE / FILE / EXPECT / ACTUAL / CONST / SUSPEND\nFieldIdentifier <- '$' IdentifierOrSoftKey\nUniCharacterLiteral <- '\\\\' 'u' HexDigit HexDigit HexDigit HexDigit\nEscapedIdentifier <- '\\\\' ('t' / 'b' / 'r' / 'n' / '\\'' / '\"' / '\\\\' / '$')\nEscapeSeq <- UniCharacterLiteral / EscapedIdentifier\n\n# // SECTION: characters\nLetter <- [\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376-\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E-\\u066F\\u0671-\\u06D3\\u06D5\\u06E5-\\u06E6\\u06EE-\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4-\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0\\u08A2-\\u08AC\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097F\\u0985-\\u098C\\u098F-\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC-\\u09DD\\u09DF-\\u09E1\\u09F0-\\u09F1\\u0A05-\\u0A0A\\u0A0F-\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32-\\u0A33\\u0A35-\\u0A36\\u0A38-\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2-\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0-\\u0AE1\\u0B05-\\u0B0C\\u0B0F-\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32-\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C-\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99-\\u0B9A\\u0B9C\\u0B9E-\\u0B9F\\u0BA3-\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58-\\u0C59\\u0C60-\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0-\\u0CE1\\u0CF1-\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32-\\u0E33\\u0E40-\\u0E46\\u0E81-\\u0E82\\u0E84\\u0E87-\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA-\\u0EAB\\u0EAD-\\u0EB0\\u0EB2-\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065-\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F0\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE-\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5-\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A-\\uA62B\\uA640-\\uA66E\\uA67F-\\uA697\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA793\\uA7A0-\\uA7AA\\uA7F8-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA80-\\uAAAF\\uAAB1\\uAAB5-\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uABC0-\\uABE2\\uAC00\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40-\\uFB41\\uFB43-\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]\nUnicodeDigit <- [\\u0030-\\u0039\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE6-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29\\u1040-\\u1049\\u1090-\\u1099\\u17E0-\\u17E9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19D9\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\uA620-\\uA629\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19]\n\n# // SECTION: strings\nQUOTE_OPEN <- '\"' !'\"\"'\nTRIPLE_QUOTE_OPEN <- '\"\"\"'\nQUOTE_CLOSE <- '\"'\nLineStrRef <- FieldIdentifier\n#LineStrText <- [^\\\\\"$]+ / '$'\nLineStrText <- [^\\\\\"$]+ / '$'\nLineStrEscapedChar <- EscapedIdentifier / UniCharacterLiteral\nLineStrExprStart <- '${'\nTRIPLE_QUOTE_CLOSE <- '\"\"\"\"\"'/ '\"\"\"\"' / '\"\"\"'\nMultiLineStringQuote <- '\"\"' !'\"' / '\"' !'\"\"'\nMultiLineStrRef <- FieldIdentifier\n#MultiLineStrText <- !('\"' / '$')+ / '$'\nMultiLineStrText <- [^\"$]+ / '$'\nMultiLineStrExprStart <- '${'\n\n_ <- (WS / DelimitedComment / LineComment)+\n__ <- ([ \\t\\f\\r\\n] / DelimitedComment / LineComment)+\nWS <- [ \\t\\f]\nNL <- _* ('\\n' / '\\r' '\\n'?) _*\nEOF <- !.\n\n%%\n#include \"kotlin_post.h\"\n"
  },
  {
    "path": "peg/kotlin_post.h",
    "content": "/*\n *   Copyright (c) 2021 Jan Dolinár\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions to generate tags for Kotlin.\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"parse.h\"\n#include \"trace.h\"\n\n/*\n* FUNCTION DEFINITIONS\n*/\nstatic int getcFromKotlinFile(struct parserCtx *auxil)\n{\n    int c = getcFromInputFile();\n    if (auxil->parenthesis_level > 0 && (c == '\\r' || c == '\\n'))\n    {\n        return ' ';\n    }\n    return c;\n}\n\nstatic void makeKotlinTag (struct parserCtx *auxil, const char *name, long offset, bool pushScope)\n{\n    int k = PEEK_KIND(auxil);\n    if (k == K_IGNORE) return;\n    tagEntryInfo e;\n    char *stripped = NULL;\n    if (*name != '`')\n    {\n        initTagEntry(&e, name, k);\n    } else\n    {\n        size_t len = strlen(name);\n        Assert(len >= 2);\n        len -= 2;\n        stripped = eStrndup (name + 1, len);\n        initTagEntry(&e, stripped, k);\n    }\n    long abs_offset = translateFileOffset (offset);\n    unsigned long lineNumber = getInputLineNumberForFileOffset (abs_offset);\n    updateTagLine (&e, lineNumber, getInputFilePositionForLine (lineNumber));\n    e.extensionFields.scopeIndex = BASE_SCOPE(auxil);\n    int scope_index = makeTagEntry (&e);\n    if (pushScope)\n    {\n        SET_SCOPE(auxil, scope_index);\n    }\n    if (stripped)\n        eFree (stripped);\n}\n\n#ifdef DEBUG\nstatic void reportFailure(struct parserCtx *auxil, long offset)\n{\n    if(auxil->fail_offset < 0)\n    {\n        auxil->fail_offset = translateFileOffset (offset);\n    }\n}\n\nstatic void resetFailure(struct parserCtx *auxil, long offset)\n{\n    if(auxil->fail_offset >= 0)\n    {\n        long abs_offset = translateFileOffset (offset);\n        unsigned long startLine = getInputLineNumberForFileOffset(auxil->fail_offset);\n        unsigned long endLine = getInputLineNumberForFileOffset(abs_offset-1);\n        if (startLine == endLine)\n        {\n            TRACE_PRINT(\"Failed to parse '%s' at line %lu!\\n\", getInputFileName(), startLine);\n        } else\n        {\n            TRACE_PRINT(\"Failed to parse '%s' from line %lu to line %lu!\\n\", getInputFileName(), startLine, endLine);\n        }\n    }\n    auxil->fail_offset = -1;\n}\n#endif\n\nstatic void ctxInit (struct parserCtx *auxil)\n{\n    BASE_INIT(auxil, K_INTERFACE);\n    auxil->parenthesis_level = 0;\n    #ifdef DEBUG\n    auxil->fail_offset = -1;\n    #endif\n}\n\nstatic void ctxFini (struct parserCtx *auxil)\n{\n    BASE_FINI(auxil);\n}\n\nstatic void findKotlinTags (void)\n{\n    struct parserCtx auxil;\n\n    ctxInit (&auxil);\n    pkotlin_context_t *pctx = pkotlin_create(&auxil);\n\n    while (pkotlin_parse(pctx, NULL) && (!BASE_ERROR(&auxil)) );\n\n    pkotlin_destroy(pctx);\n    ctxFini (&auxil);\n}\n\nextern parserDefinition* KotlinParser (void)\n{\n    static const char *const extensions [] = { \"kt\", \"kts\", NULL };\n    parserDefinition* def = parserNew (\"Kotlin\");\n    def->kindTable = KotlinKinds;\n    def->kindCount = ARRAY_SIZE (KotlinKinds);\n    def->extensions = extensions;\n    def->parser = findKotlinTags;\n    def->useCork = true;\n    def->requestAutomaticFQTag = true;\n    def->defaultScopeSeparator = \".\";\n    def->enabled = true;\n    return def;\n}\n"
  },
  {
    "path": "peg/kotlin_pre.h",
    "content": "/*\n *   Copyright (c) 2021 Jan Dolinár\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains macros, data decls and prototypes to generate tags for Kotlin.\n */\n\n/*\n*   INCLUDE FILES\n*/\n\n#include \"kind.h\"\n#include \"peg_common.h\"\n\n\n/*\n*   MACROS\n*/\n#undef PCC_GETCHAR\n#define PCC_GETCHAR(auxil) getcFromKotlinFile(auxil)\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef enum {\n    K_PACKAGE,\n    K_INTERFACE,\n    K_CLASS,\n    K_OBJECT,\n    K_METHOD,\n    K_TYPEALIAS,\n    K_CONSTANT,\n    K_VARIABLE,\n    K_IGNORE\n} KotlinKind;\n\nstatic kindDefinition KotlinKinds [] = {\n    { true, 'p', \"package\", \"packages\", },\n    { true, 'i', \"interface\", \"interfaces\", },\n    { true, 'c', \"class\", \"classes\", },\n    { true, 'o', \"object\", \"objects\", },\n    { true, 'm', \"method\", \"methods\", },\n    { true, 'T', \"typealias\", \"typealiases\", },\n    { true, 'C', \"constant\", \"constants\", },\n    { true, 'v', \"variable\", \"variables\", },\n};\n\nstruct parserCtx {\n    struct parserBaseCtx base;\n    int parenthesis_level;\n    #ifdef DEBUG\n    long fail_offset;\n    #endif\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nstatic int getcFromKotlinFile(struct parserCtx *auxil);\nstatic void makeKotlinTag (struct parserCtx *auxil, const char *name, long offset, bool pushScope);\n#ifdef DEBUG\nstatic void reportFailure(struct parserCtx *auxil, long offset);\nstatic void resetFailure(struct parserCtx *auxil, long offset);\n#else\n    #define reportFailure(AUXIL, OFFSET)\n    #define resetFailure(AUXIL, OFFSET)\n#endif\n"
  },
  {
    "path": "peg/peg_common.h",
    "content": "/*\n *   Copyright (c) 2021 Masatake YAMATO\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains macros, data decls and prototypes to generate tags for Kotlin.\n */\n\n#ifndef CTAGS_PEG_COMMON\n#define CTAGS_PEG_COMMON\n\n#include \"debug.h\"\n\n#define PCC_GETCHAR(auxil) getcFromInputFile()\n#define PCC_MALLCO(auxil,size) eMalloc(size)\n#define PCC_REALLOC(auxil,ptr,size) eRealloc(ptr,size)\n#define PCC_FREE(auxil,ptr) eFreeNoNullCheck((void *)ptr)\n#define PCC_ERROR(auxil) baseReportError(BASE(auxil))\n#ifdef DEBUG\n#define PCC_DEBUG(auxil, event, rule, level, pos, buffer, length) baseDebug(BASE(auxil), event, rule, level, pos, buffer, length)\n#endif\n\n#include \"numarray.h\"\n#include \"parse.h\"\n#include \"entry.h\"\n#include \"read.h\"\n#ifdef DEBUG\n#include \"htable.h\"\n#endif\n\nstruct parserBaseCtx {\n\tintArray *kind_stack;\n\tint scope_cork_index;\n\tbool found_syntax_error;\n#ifdef DEBUG\n\thashTable *debug_rules;\n#endif\n};\n\n#define BASE_STRUCT parserBaseCtx\n#define BASE(P) ((struct BASE_STRUCT*)(P))\n#define BASE_ERROR(P) ((BASE(P))->found_syntax_error)\n#define BASE_SCOPE(P) ((BASE(P))->scope_cork_index)\n\n#define SET_SCOPE(P,S) (BASE_SCOPE(P) = (S))\n#define POP_SCOPE(P) (basePopScope(BASE(P)))\n#define PUSH_KIND(P,K) (basePushKind(BASE(P),(K)))\n#define POP_KIND(P,POP_SCOPE_TOO) (basePopKind(BASE(P),(POP_SCOPE_TOO)))\n#define PEEK_KIND(P) (basePeekKind(BASE(P)))\n\n#define BASE_INIT(P,KIND) (baseInit((BASE(P)),KIND))\n#define BASE_FINI(P) (baseFini(BASE(P)))\n\n#ifdef DEBUG\n#define BASE_DEBUG_RULE(P, R) baseAddDebugRule(BASE(P), R)\n#else\n#define BASE_DEBUG_RULE(P, R)\n#endif\n\nstatic void basePopScope(struct parserBaseCtx *auxil)\n{\n    tagEntryInfo *e = getEntryInCorkQueue (auxil->scope_cork_index);\n    if (e)\n        auxil->scope_cork_index = e->extensionFields.scopeIndex;\n}\n\nstatic void basePushKind (struct parserBaseCtx *auxil, int kind)\n{\n\tintArrayAdd (auxil->kind_stack, kind);\n}\n\nstatic void basePopKind (struct parserBaseCtx *auxil, bool popScopeToo)\n{\n    intArrayRemoveLast (auxil->kind_stack);\n\n    if (popScopeToo)\n    {\n        basePopScope(auxil);\n    }\n}\n\nCTAGS_ATTR_UNUSED\nstatic int basePeekKind (struct parserBaseCtx *auxil)\n{\n    return intArrayLast (auxil->kind_stack);\n}\n\nstatic void baseReportError (struct parserBaseCtx *auxil)\n{\n    auxil->found_syntax_error = true;\n    fprintf(stderr, \"%s: syntax error in \\\"%s\\\"\\n\",\n\t\t\tgetLanguageName (getInputLanguage ()), getInputFileName());\n}\n\nstatic void baseInit(struct parserBaseCtx *auxil, int initial_kind)\n{\n\tauxil->kind_stack = intArrayNew ();\n\tbasePushKind (auxil, initial_kind);\n\tauxil->scope_cork_index = CORK_NIL;\n\tauxil->found_syntax_error = false;\n#ifdef DEBUG\n\tauxil->debug_rules = hashTableNew (11,\n\t\t\t\t\t\t\t\t\t   hashCstrhash, hashCstreq,\n\t\t\t\t\t\t\t\t\t   NULL, NULL);\n#endif\n}\n\nstatic void baseFini(struct parserBaseCtx *auxil)\n{\n\tbasePopKind (auxil, false);\n\tintArrayDelete (auxil->kind_stack);\n#ifdef DEBUG\n\thashTableDelete (auxil->debug_rules);\n#endif\n}\n\n#ifdef DEBUG\nCTAGS_ATTR_UNUSED static void baseAddDebugRule (struct parserBaseCtx *auxil, char *rule)\n{\n\thashTablePutItem (auxil->debug_rules, rule, HT_INT_TO_PTR(1));\n}\n\nstatic bool baseIsDebugRule (struct parserBaseCtx *auxil, const char *rule)\n{\n\treturn hashTableHasItem (auxil->debug_rules, rule);\n}\n\nstatic void baseDebug(struct parserBaseCtx *auxil, int event, const char *rule, size_t level, size_t pos, const char *buffer, size_t len)\n{\n\tif (!baseIsDebugRule(auxil, rule))\n\t\treturn;\n\n\tfprintf(stderr, \"<level:%2zu, len:%4zu>[%7s] %10s: \",\n\t\t\tlevel, len,\n\t\t\tevent == 0 /*PCC_DBG_EVALUATE*/ ? \"eval\" :\n\t\t\tevent == 1 /*PCC_DBG_MATCH*/    ? \"match\":\n\t\t\tevent == 2 /*PCC_DBG_NOMATCH*/  ? \"nomatch\": \"unknown\",\n\t\t\trule);\n\tfor (size_t i = 0; i < len; i++)\n\t{\n\t\tif (buffer[i] == '\\n')\n\t\t\tbreak;\n\t\tfputc(buffer[i], stderr);\n\t}\n\tfputc('\\n', stderr);\n}\n#endif\n\n#endif\t/* !CTAGS_PEG_COMMON */\n"
  },
  {
    "path": "peg/thrift.peg",
    "content": "#\n# This file is derived from\n# https://raw.githubusercontent.com/samuel/go-thrift/master/parser/grammar.peg\n# (commit id: 586f6174a55deba8cbe982f15ecc28a901e44f4a)\n#\n# Reference:\n#     - https://thrift.apache.org/docs/idl\n#     - https://diwakergupta.github.io/thrift-missing-guide/\n#\n#\n# Copyright (c) 2012, Samuel Stauffer <samuel@descolada.com>\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are met:\n#\n# * Redistributions of source code must retain the above copyright\n#   notice, this list of conditions and the following disclaimer.\n# * Redistributions in binary form must reproduce the above copyright\n#   notice, this list of conditions and the following disclaimer in the\n#   documentation and/or other materials provided with the distribution.\n# * Neither the name of the author nor the\n#   names of its contributors may be used to endorse or promote products\n#   derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#\n%prefix \"pthrift\"\n\n%auxil \"struct parserCtx *\"\n\n%earlysource {\n    #include \"general.h\"\n}\n\n%header {\n    struct parserCtx;\n}\n\n%source {\n#include \"thrift_pre.h\"\n#include \"routines.h\"\n}\n\nGrammar <- __ ( Statement __ )* (EOF / SyntaxError)\nSyntaxError <- .\n\n# MODIFIED\nInclude <- <( \"include\" / \"cpp_include\" )> _ <Literal> EOS {\n    vString *f = unliteral ($2);\n    if (vStringLength(f) > 0)\n    {\n        if ($1[0] == 'i')\n            makeThriftTagFull (auxil, vStringValue (f), $2s, K_THRIFTFILE, THRIFT_THRIFT_FILE_INCLUDED, false);\n        else\n        {\n            tagEntryInfo e;\n            initForeignRefTagEntry (&e, vStringValue(f), getNamedLanguage (\"C++\", 0), CXXTagKindINCLUDE, CR_HEADER_LOCAL);\n            long abs_offset = translateFileOffset ($2s);\n            e.lineNumber = getInputLineNumberForFileOffset (abs_offset);\n            e.filePosition = getInputFilePositionForLine (e.lineNumber);\n            makeTagEntry (&e);\n        }\n    }\n    vStringDelete (f);\n}\n\nStatement <- Include / Namespace / Const / Enum / TypeDef / Struct / Exception / Union / Service\n\nNamespace <- \"namespace\" _ <[-*a-z.]+> _ <Identifier> {\n    int r = makeThriftTag (auxil, $2, $2s, K_NAMESPACE, false);\n    attachParserFieldToCorkEntry (r, ThriftFields[F_TARGET].ftype, $1);\n} EOS\n\nConst <- \"const\" _ <FieldType> _ <Identifier> {\n    int r = makeThriftTag (auxil, $2, $2s, K_CONST, false);\n    tagEntryInfo *e = getEntryInCorkQueue (r);\n    if (e)\n    {\n        e->extensionFields.typeRef[0] = eStrdup (\"typename\");\n        e->extensionFields.typeRef[1] = eStrdup ($1);\n    }\n} __ \"=\" __ ConstValue _ ListSeparator? EOS\n# MODIFIED\n\nEnum <- \"enum\" { PUSH_KIND (auxil, K_ENUM); } _ <Identifier> {\n    makeThriftTag (auxil, $1, $1s, USE_KIND_STACK, true);\n} __ '{' __ (EnumValue __)* '}' _ TypeAnnotations? EOS { POP_KIND (auxil, true); }\n\nEnumValue <- <Identifier> {\n    makeThriftTag (auxil, $1, $1s, K_ENUMERATOR, false);\n} _ ('=' _ IntConstant)? _ TypeAnnotations? ListSeparator?\n\n\nTypeDef <- \"typedef\" _ <FieldType> _ <Identifier> {\n    int r = makeThriftTag (auxil, $2, $2s, K_TYPEDEF, false);\n    tagEntryInfo *e = getEntryInCorkQueue (r);\n    if (e)\n    {\n        e->extensionFields.typeRef[0] = eStrdup (\"typename\");\n        e->extensionFields.typeRef[1] = eStrdup ($1);\n    }\n} _ TypeAnnotations? EOS\n\nStruct <- \"struct\" { PUSH_KIND (auxil, K_STRUCT); }_ StructLike { POP_KIND (auxil, true); }\nException <- \"exception\" { PUSH_KIND (auxil, K_EXCEPTION); } _ StructLike { POP_KIND (auxil, true); }\nUnion <- \"union\" { PUSH_KIND (auxil, K_UNION); }  _ StructLike { POP_KIND (auxil, true); }\nStructLike <- <Identifier> {\n    makeThriftTag (auxil, $1, $1s, USE_KIND_STACK, true);\n    PUSH_KIND (auxil, K_MEMBER);\n} __ '{' __ FieldList '}' _ TypeAnnotations? EOS { POP_KIND (auxil, false); }\n\nFieldList <- (Field __)*\n\nField <- IntConstant _ ':' _ FieldReq? _ <FieldType> _ <Identifier> {\n    int r = makeThriftTag (auxil, $2, $2s, USE_KIND_STACK, false);\n    tagEntryInfo *e = getEntryInCorkQueue (r);\n    if (e)\n    {\n        e->extensionFields.typeRef[0] = eStrdup (\"typename\");\n        e->extensionFields.typeRef[1] = eStrdup ($1);\n    }\n} __ ('=' _ ConstValue)? _ TypeAnnotations? ListSeparator?\n\nFieldReq <- (\"required\" / \"optional\")\n\nService <- \"service\" _ <Identifier> {\n    makeThriftTag (auxil, $1, $1s, K_SERVICE, true);\n} _ (\"extends\" __ <Identifier> {\n        int r = BASE_SCOPE (auxil);\n        tagEntryInfo *e = getEntryInCorkQueue (r);\n        if (e)\n            e->extensionFields.inheritance = eStrdup ($2);\n} __)? __ '{' __ (Function __)* ('}' / EndOfServiceError) _ TypeAnnotations?  EOS {\n    POP_SCOPE (auxil);\n}\nEndOfServiceError <- .\n\nFunction <- (\"oneway\" __)? <FunctionType> __ <Identifier> {\n    int r = makeThriftTag (auxil, $2, $2s, K_FUNCTION, true);\n    tagEntryInfo *e = getEntryInCorkQueue (r);\n    if (e)\n    {\n        e->extensionFields.typeRef[0] = eStrdup (\"typename\");\n        e->extensionFields.typeRef[1] = eStrdup ($1);\n    }\n    PUSH_KIND (auxil, K_PARAMETER);\n} _ <'(' __ FieldList ')'> {\n    int r = BASE_SCOPE (auxil);\n    tagEntryInfo *e = getEntryInCorkQueue (r);\n    if (e)\n         e->extensionFields.signature = eStrdup ($3);\n} __ Throws? _ TypeAnnotations? ListSeparator? { POP_KIND (auxil, true); }\n\nFunctionType <- (\"void\" / FieldType)\n\nThrows <- \"throws\" { PUSH_KIND (auxil, K_THROWSPARAM); } __ < '(' __ FieldList ')' > {\n    int r = BASE_SCOPE (auxil);\n    attachParserFieldToCorkEntry (r, ThriftFields[F_THROWS].ftype, $1);\n    POP_KIND (auxil, false);\n}\n\nFieldType <- (BaseType / ContainerType / Identifier)\n\n# DefinitionType <- (BaseType / ContainerType)\n\nBaseType <- BaseTypeName _ TypeAnnotations?\n\nBaseTypeName <- (\"bool\" / \"byte\" / \"i16\" / \"i32\" / \"i64\" / \"double\" / \"string\" / \"binary\" )\n\nContainerType <- (MapType / SetType / ListType)\n\nMapType <- CppType? \"map\" WS \"<\" WS FieldType WS \",\" WS FieldType WS \">\" _ TypeAnnotations?\n\nSetType <- CppType? \"set\" WS \"<\" WS FieldType WS \">\" _ TypeAnnotations?\n\nListType <- \"list\" WS \"<\" WS FieldType WS \">\" _ TypeAnnotations?\n\nCppType <- \"cpp_type\" Literal\n\nConstValue <- Literal / DoubleConstant / IntConstant / ConstMap / ConstList / Identifier\n\nTypeAnnotations <- '(' __ TypeAnnotation* ')'\n\nTypeAnnotation <- Identifier _ ('=' __ Literal)? ListSeparator? __\n\nIntConstant <- [-+]? Digit+\n\nDoubleConstant <- [-+]? Digit* '.' Digit* ( ['Ee'] IntConstant )?\n\nConstList <- '[' __ (ConstValue __ ListSeparator? __)* __ ']'\n\n# MODIFIED\nConstMap <- '{' __ (ConstValue __ ':' __ ConstValue __ (ListSeparator? / &'}') __)* '}'\n\n# ...\nLiteral <- (('\"' (\"\\\\\\\"\" / [^\"])* '\"') / (\"'\" (\"\\\\'\" / [^'])* \"'\"))\n# '\"\n\nIdentifier <- (Letter / '_')+ (Letter / Digit / [._])*\n\nListSeparator <- [,;]\nLetter <- [A-Za-z]\nDigit <- [0-9]\n\n# //\n\nSourceChar <- .\nComment <- MultiLineComment / SingleLineComment\nMultiLineComment <- \"/*\" ( !\"*/\" SourceChar )* \"*/\"\nMultiLineCommentNoLineTerminator <- \"/*\" ( !( \"*/\" / EOL ) SourceChar )* \"*/\"\nSingleLineComment <- (\"//\" ( !EOL SourceChar )*) / (\"#\" ( !EOL SourceChar )*)\n\n__ <- ( Whitespace / EOL / Comment )*\n_ <- ( Whitespace / MultiLineCommentNoLineTerminator )*\nWS <- Whitespace*\n\nWhitespace <- [ \\t\\r]\nEOL <- '\\n'\nEOS <- __ ';' / _ SingleLineComment? EOL / __ EOF\n\nEOF <- !.\n\n%%\n#include \"thrift_post.h\"\n"
  },
  {
    "path": "peg/thrift_post.h",
    "content": "/*\n *   Copyright (c) 2021 Masatake YAMATO\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains macros, data decls and prototypes to generate tags for Thrift IDL.\n *   Reference: https://thrift.apache.org/docs/idl\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"options.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n#include \"dependency.h\"\n\nstatic int makeThriftTagFull (struct parserCtx *auxil, const char *name, long offset, int kind, int role,\n\t\t\t\t\t\t\t  bool pushScope)\n{\n\ttagEntryInfo e;\n\tint k = (kind == USE_KIND_STACK? PEEK_KIND (auxil): kind);\n\tif (role == ROLE_DEFINITION_INDEX)\n\t\tinitTagEntry(&e, name, k);\n\telse\n\t\tinitRefTagEntry(&e, name, k, role);\n\tlong abs_offset = translateFileOffset (offset);\n\tunsigned long lineNumber = getInputLineNumberForFileOffset (abs_offset);\n\tupdateTagLine (&e, lineNumber, getInputFilePositionForLine (lineNumber));\n\te.extensionFields.scopeIndex = BASE_SCOPE (auxil);\n\tint scope_index = makeTagEntry (&e);\n\tif (pushScope)\n\t\tSET_SCOPE(auxil, scope_index);\n\treturn scope_index;\n}\n\nstatic int makeThriftTag (struct parserCtx *auxil, const char *name, long offset, int kind, bool pushScope)\n{\n\treturn makeThriftTagFull (auxil, name, offset, kind, ROLE_DEFINITION_INDEX, pushScope);\n}\n\nstatic vString* unliteral(const char *literal)\n{\n\tvString *vstr = vStringNew ();\n\n\tconst char *c = literal;\n\tif (*c == '\"' || *c == '\\'')\n\t\tc++;\n\n\tfor (; *c != '\\0'; c++)\n\t{\n\t\tif (*c == '\\\\')\n\t\t{\n\t\t\tc++;\n\t\t\tif (*c == '\\0')\n\t\t\t\tbreak;\n\n\t\t\t/* ???\n\t\t\t * How the backslash is handled is not wel explained in the document. */\n\t\t\tif (! (*c == '\"' || *c == '\\'' || *c == '\\\\'))\n\t\t\t\tvStringPut (vstr, '\\\\');\n\t\t}\n\t\tvStringPut (vstr, *c);\n\t}\n\n\tif (vStringLength (vstr) > 0 &&\n\t\t(vStringLast (vstr) == '\"' ||\n\t\t vStringLast (vstr) == '\\''))\n\t\tvStringTruncate(vstr, vStringLength(vstr) - 1);\n\n\treturn vstr;\n}\n\nstatic void ctxInit (struct parserCtx *auxil)\n{\n \tBASE_INIT(auxil, K_STRUCT);\n}\n\nstatic void ctxFini (struct parserCtx *auxil)\n{\n\tBASE_FINI(auxil);\n}\n\nstatic void findThriftTags (void)\n{\n\tstruct parserCtx auxil;\n\n\tctxInit (&auxil);\n\t// \tBASE_DEBUG_RULE(&auxil, \"Const\");\n\n\tpthrift_context_t *pctx = pthrift_create(&auxil);\n\n\twhile ( pthrift_parse(pctx, NULL) && (!BASE_ERROR(&auxil)) );\n\n\tpthrift_destroy(pctx);\n\tctxFini (&auxil);\n}\n\nextern parserDefinition* ThriftParser (void)\n{\n\tstatic const char *const extensions [] = { \"thrift\", NULL };\n\tparserDefinition* def = parserNew (\"Thrift\");\n\n\tstatic parserDependency dependencies [] = {\n\t\t[0] = { DEPTYPE_FOREIGNER, \"C++\", NULL },\n\t};\n\n\tdef->kindTable  = ThriftKinds;\n\tdef->kindCount  = ARRAY_SIZE (ThriftKinds);\n\tdef->fieldTable = ThriftFields;\n\tdef->fieldCount = ARRAY_SIZE (ThriftFields);\n\tdef->extensions = extensions;\n\tdef->dependencies = dependencies;\n\tdef->dependencyCount = ARRAY_SIZE (dependencies);\n\tdef->parser     = findThriftTags;\n\tdef->useCork    = true;\n\tdef->enabled    = true;\n\tdef->defaultScopeSeparator = \".\";\n\treturn def;\n}\n"
  },
  {
    "path": "peg/thrift_pre.h",
    "content": "/*\n *   Copyright (c) 2021 Masatake YAMATO\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains macros, data decls and prototypes to generate tags for Thrift IDL.\n *   Reference: https://thrift.apache.org/docs/idl\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"kind.h\"\n#include \"field.h\"\n#include \"peg_common.h\"\n\n#include \"parsers/cxx/cxx_tag.h\"\n\n/*\n*   MACROS\n*/\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef enum {\n\tK_STRUCT,\n\tK_EXCEPTION,\n\tK_UNION,\n\tK_NAMESPACE,\n\tK_ENUMERATOR,\n\tK_ENUM,\n\tK_MEMBER,\n\tK_CONST,\n\tK_TYPEDEF,\n\tK_SERVICE,\n\tK_FUNCTION,\n\tK_PARAMETER,\n\tK_THROWSPARAM,\n\tK_THRIFTFILE,\n\tCOUNT_KINDS\n} thriftKind;\n\ntypedef enum {\n\tTHRIFT_THRIFT_FILE_INCLUDED,\n} thriftThriftFileRole;\n\nstatic roleDefinition ThriftThriftFileRoles [] = {\n\t{ true, \"included\", \"included file\" },\n};\n\nstatic kindDefinition ThriftKinds [COUNT_KINDS] = {\n\t{ true,  's', \"struct\",       \"structs\"    },\n\t{ true,  'x', \"exception\",    \"exceptions\" },\n\t{ true,  'u', \"union\",        \"unions\"     },\n\t{ true,  'n', \"namespace\",    \"namespaces\" },\n\t{ true,  'e', \"enumerator\",   \"enumerators (values inside an enumeration)\" },\n\t{ true,  'g', \"enum\",         \"enumeration names\" },\n\t{ true,  'm', \"member\",       \"members\"    },\n\t{ true,  'C', \"const\",        \"constants\"  },\n\t{ true,  't', \"typedef\",      \"typedefs\"   },\n\t{ true,  'v', \"service\",      \"services\"   },\n\t{ true,  'f', \"function\",     \"functions\"  },\n\t{ false, 'z', \"parameter\",    \"parameters\" },\n\t{ false, 'Z', \"throwsparam\",  \"parameters in throws list\" },\n\t{ true,  'T', \"thriftFile\",   \"thrift files\",\n\t  .referenceOnly = true, ATTACH_ROLES(ThriftThriftFileRoles) },\n};\n\ntypedef enum {\n\tF_THROWS,\n\tF_TARGET,\n\tCOUNT_FIELDS\n} thriftField;\n\nstatic fieldDefinition ThriftFields[COUNT_FIELDS] = {\n\t{ .name        = \"throws\",\n\t  .description = \"throws list of function\",\n\t  .enabled     = true },\n\t{ .name        = \"target\",\n\t  .description = \"the target language specified at \\\"namespace\\\"\",\n\t  .enabled     = true },\n};\n\nstruct parserCtx {\n\tstruct parserBaseCtx base;\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\n#define USE_KIND_STACK KIND_GHOST_INDEX\nstatic int makeThriftTagFull (struct parserCtx *auxil, const char *name, long offset, int kind, int role, bool pushScope);\nstatic int makeThriftTag (struct parserCtx *auxil, const char *name, long offset, int kind, bool pushScope);\nstatic vString* unliteral(const char *literal);\n"
  },
  {
    "path": "peg/toml.peg",
    "content": "#\n# This file is derived from\n#\n# https://github.com/toml-lang/toml/blob/main/toml.abnf\n#\n########################################################################\n#\n# The MIT License\n#\n# Copyright (c) Tom Preston-Werner\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n# THE SOFTWARE.\n#\n# (https://github.com/toml-lang/toml/blob/main/LICENSE)\n#\n##########################################################################\n#\n# Masatake YAMATO converted the abnf to peg for ctags.\n#\n##########################################################################\n%prefix \"ptoml\"\n\n%auxil\t\"struct parserCtx *\"\n\n%earlysource {\n    #include \"general.h\"\n}\n\n%header {\n\tstruct parserCtx;\n}\n\n%source {\n#include \"toml_pre.h\"\n}\n\n## Overall Structure\ntoml <- expression ( newline expression )* newline* (!. / .)\n\n# the order of elements is arranged for peg'ify.\nexpression <-\n   ws keyval ws comment?\n   / ws table ws comment?\n   / ws comment?\n\n## Whitespace\nws <- wschar*\nwschar <- ' ' / '\\t'\n\n## Newline\nnewline <- '\\r\\n' / '\\n'\n\n## Comment\ncommentStartSymbol <- '#'\nnonAscii <- [\\u0080-\\uD7FF] / [\\uE000-\\u110FFFF]\nnonEol <- '\\t' / [\\u0020-\\u007F] / nonAscii\n\ncomment <- commentStartSymbol nonEol*\n\n## Key-Value pairs\n\nkeyval <- {keyvalStart(auxil, $0s);} key {keyvalKeyEnd(auxil);} keyvalSep val {keyvalValEnd(auxil);}\n\n# the order of elements is arranged for peg'ify.\nkey <- dottedKey / simpleKey\nsimpleKey <- <quotedKey / unquotedKey> {queueKey (auxil, $0);}\n\nunquotedKey <- ( ALPHA / DIGIT / '-' / '_' )+\nquotedKey <- basicString / literalString\ndottedKey <- simpleKey ( dotSep simpleKey )+\n\ndotSep <- ws '.' ws\nkeyvalSep <- ws '=' ws\n\nval <- <string / boolean / array / inlineTable / dateTime / float / integer> {notifyValue(auxil, $0, $0s);}\n\n## String\n\nstring <- mlBasicString / basicString / mlLiteralString / literalString\n\n## Basic String\n\nbasicString <- quotationMark basicChar* quotationMark\n\nquotationMark <- '\"'\n\nbasicChar <- basicUnescaped / escaped\nbasicUnescaped <- wschar / '\\u0021' / [\\u0023-\\u005B] / [\\u005D-\\u007E] / nonAscii\nescaped <- escape escapeSeqChar\n\nescape <- '\\u005C'\nescapeSeqChar <- [\\u0022\\u005C\\u0062\\u0066\\u006E\\u0072\\u0074]\n\t      / '\\u0075' HEXDIG HEXDIG HEXDIG HEXDIG\n\t      / '\\u0055' HEXDIG HEXDIG HEXDIG HEXDIG HEXDIG HEXDIG HEXDIG HEXDIG\n\n## Multiline Basic String\n\nmlBasicString <- mlBasicStringDelim newline? mlBasicBody mlBasicStringDelim\nmlBasicStringDelim <- quotationMark quotationMark quotationMark\nmlBasicBody <- mlbContent* ( mlbQuotes mlbContent+ )* mlbQuotes?\n\nmlbContent <- mlbChar / newline / mlbEscapedNl\nmlbChar <- mlbUnescaped / escaped\nmlbQuotes <- quotationMark quotationMark / quotationMark\nmlbUnescaped <- wschar / '\\u0021' / [\\u0023-\\u005B] / [\\u005D-\\u007E] / nonAscii\nmlbEscapedNl <- escape ws newline ( wschar / newline )*\n\n## Literal String\n\nliteralString <- apostrophe literalChar* apostrophe\n\napostrophe <- '\\u0027'\n\nliteralChar <- '\\u0009' / [\\u0020-\\u0026] / [\\u0028-\\u007E] / nonAscii\n\n## Multiline Literal String\n\nmlLiteralString <- mlLiteralStringDelim newline? mlLiteralBody\n                  mlLiteralStringDelim\nmlLiteralStringDelim <- apostrophe apostrophe apostrophe\nmlLiteralBody <- mllContent* ( mllQuotes mllContent+ )* mllQuotes?\n\nmllContent <- mllChar / newline\nmllChar <- '\\u0009' / [\\u0020-\\u0026] / [\\u0028-\\u007E] / nonAscii\nmllQuotes <- apostrophe apostrophe / apostrophe\n\n## Integer\n\ninteger <- decInt / hexInt / octInt / binInt\n\nminus <- '\\u002D'\nplus <- '\\u002B'\nunderscore <- '\\u005F'\ndigit1_9 <- [\\u0031-\\u0039]\ndigit0_7 <- [\\u0030-\\u0037]\ndigit0_1 <- [\\u0030-\\u0031]\n\nhexPrefix <- '\\u0030' '\\u0078'\noctPrefix <- '\\u0030' '\\u006F'\nbinPrefix <- '\\u0030' '\\u0062'\n\ndecInt <- ( minus / plus )? unsignedDecInt\n# the order of elements is arranged for peg'ify.\nunsignedDecInt <- digit1_9 ( DIGIT / underscore DIGIT )+ / DIGIT\n\nhexInt <- hexPrefix HEXDIG ( HEXDIG / underscore HEXDIG )*\noctInt <- octPrefix digit0_7 ( digit0_7 / underscore digit0_7 )*\nbinInt <- binPrefix digit0_1 ( digit0_1 / underscore digit0_1 )*\n\n## Float\n\nfloat <- floatIntPart ( exp / frac exp? ) / specialFloat\n\nfloatIntPart <- decInt\nfrac <- decimalPoint zeroPrefixableInt\ndecimalPoint <- '\\u002E'\nzeroPrefixableInt <- DIGIT ( DIGIT / underscore DIGIT )*\n\nexp <- [eE] floatExpPart\nfloatExpPart <- ( minus / plus )? zeroPrefixableInt\n\nspecialFloat <- ( minus / plus )? ( inf / nan )\ninf <- '\\u0069' '\\u006e' '\\u0066'\nnan <- '\\u006e' '\\u0061' '\\u006e'\n\n## Boolean\n\nboolean <- true / false\n\ntrue    <- '\\u0074' '\\u0072' '\\u0075' '\\u0065'\nfalse   <- '\\u0066' '\\u0061' '\\u006C' '\\u0073' '\\u0065'\n\n## Date and Time (as defined in RFC 3339)\n\ndateTime      <- offsetDateTime / localDateTime / localDate / localTime\n\ndateFullyear  <- DIGIT DIGIT DIGIT DIGIT\ndateMonth     <- DIGIT DIGIT\ndateMday      <- DIGIT DIGIT\ntimeDelim     <- [tT] / '\\u0020'\ntimeHour      <- DIGIT DIGIT\ntimeMinute    <- DIGIT DIGIT\ntimeSecond    <- DIGIT DIGIT\ntimeSecfrac   <- \".\" DIGIT+\ntimeNumoffset <- ( \"+\" / \"-\" ) timeHour \":\" timeMinute\ntimeOffset    <- [zZ] / timeNumoffset\n\npartialTime   <- timeHour \":\" timeMinute \":\" timeSecond timeSecfrac?\nfullDate      <- dateFullyear \"-\" dateMonth \"-\" dateMday\nfullTime      <- partialTime timeOffset\n\n## Offset Date-Time\n\noffsetDateTime <- fullDate timeDelim fullTime\n\n## Local Date-Time\n\nlocalDateTime <- fullDate timeDelim partialTime\n\n## Local Date\n\nlocalDate <- fullDate\n\n## Local Time\n\nlocalTime <- partialTime\n\n## Array\n\narray <- arrayOpen arrayValues? wsCommentNewline arrayClose\n\narrayOpen <-  '\\u005B'\narrayClose <- '\\u005D'\n\narrayValues <-  wsCommentNewline val wsCommentNewline arraySep arrayValues\n               / wsCommentNewline val wsCommentNewline arraySep*\n\narraySep <- '\\u002C'\n\nwsCommentNewline <- ( wschar / comment? newline )*\n\n## Table\n\ntable <- stdTable / arrayTable\n\n## Standard Table\n\nstdTable <- stdTableOpen {tableKeyStart(auxil, false, $0s);} key {tableKeyEnd(auxil);} stdTableClose\n\nstdTableOpen  <- '\\u005B' ws\nstdTableClose <- ws '\\u005D'\n\n## Inline Table\n\ninlineTable <- inlineTableOpen inlineTableKeyvals? inlineTableClose\n\ninlineTableOpen  <- '\\u007B' ws\ninlineTableClose <- ws '\\u007D'\ninlineTableSep   <- ws '\\u002C' ws\n\ninlineTableKeyvals <- keyval ( inlineTableSep inlineTableKeyvals )?\n\n## Array Table\n\narrayTable <- arrayTableOpen {tableKeyStart(auxil, true, $0s);} key {tableKeyEnd(auxil);} arrayTableClose\n\narrayTableOpen  <- '\\u005B' '\\u005B' ws\narrayTableClose <- ws '\\u005D' '\\u005D'\n\n## Built-in ABNF terms, reproduced here for clarity\n\nALPHA <- [\\u0041-\\u005A] / [\\u0061-\\u007A]\nDIGIT <- [\\u0030-\\u0039]\nHEXDIG <- DIGIT / [aA] / [bB] / [cC] / [dD] / [eE] / [fF]\n\n%%\n#include \"toml_post.h\"\n"
  },
  {
    "path": "peg/toml_post.h",
    "content": "/*\n *   Copyright (c) 2024 Masatake YAMATO\n *   Copyright (c) 2024 Red Hat, Inc.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions to generate tags for TOML.\n */\n\n\n/*\n*   INCLUDE FILES\n*/\n#include \"options.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n\n/*\n* FUNCTION DEFINITIONS\n*/\nstatic void markTableEnd (struct parserCtx *auxil, long offset)\n{\n\ttagEntryInfo *e = getEntryInCorkQueue (auxil->lastTableIndex);\n\tif (!e)\n\t\treturn;\n\n\tunsigned long lineNumber = (offset == -1)\n\t\t? getInputLineNumber()\n\t\t: getInputLineNumberForFileOffset (translateFileOffset (offset));\n\n\tsetTagEndLine(e, ((offset != -1 && lineNumber > 1)\n\t\t\t\t\t  ? lineNumber - 1\n\t\t\t\t\t  : lineNumber));\n\n\tauxil->lastTableIndex = CORK_NIL;\n\tfor (unsigned int i = uintArrayLast (auxil->unwind_depths); i > 0; i--)\n\t\tPOP_SCOPE (auxil);\n\tuintArrayRemoveLast (auxil->unwind_depths);\n}\n\nstatic vString *makeVStringFromKeyQueue (ptrArray *keyQueue)\n{\n\tvString *vname = vStringNew ();\n\n\tfor (size_t i = 0; i < ptrArrayCount (keyQueue); i++)\n\t{\n\t\tconst char *key = ptrArrayItem (keyQueue, i);\n\t\tvStringCatS (vname, key);\n\t\tif (i != ptrArrayCount (keyQueue) - 1)\n\t\t\tvStringPut (vname, '.');\n\t}\n\n\treturn vname;\n}\n\nstatic void makeTagsForKeys (struct parserCtx *auxil, unsigned long lineNumber, MIOPos filePosition,\n\t\t\t\t\t\t\t int last_key_index0)\n{\n\tint last_key_index = last_key_index0;\n\tfor (size_t i = 0; i < ptrArrayCount (auxil->keyQueue); i++)\n\t{\n\t\ttagEntryInfo e;\n\t\tconst char *key = ptrArrayItem (auxil->keyQueue, i);\n\t\tif (i == ptrArrayCount (auxil->keyQueue) - 1)\n\t\t\tinitTagEntry (&e, key, TOML_K_KEY);\n\t\telse\n\t\t\tinitRefTagEntry (&e, key, TOML_K_KEY, TOML_R_KEY_CHAINELT);\n\t\te.lineNumber = lineNumber;\n\t\te.filePosition = filePosition;\n\t\te.extensionFields.scopeIndex = last_key_index;\n\t\tif (i == ptrArrayCount (auxil->keyQueue) - 1)\n\t\t\t;/* TODO: Attach partOf:vStringValue(vname) */\n\t\tlast_key_index= makeTagEntry (&e);\n\t\tif (i == ptrArrayCount (auxil->keyQueue) - 1)\n\t\t{\n\t\t\tSET_SCOPE(auxil, last_key_index);\n\t\t\tuintArrayAdd (auxil->unwind_depths, ptrArrayCount (auxil->keyQueue));\n\t\t}\n\t}\n}\n\nstatic void tableKeyStart (struct parserCtx *auxil, bool isArrayTable, long offset)\n{\n\tif (auxil->keyQueue == NULL)\n\t\tauxil->keyQueue = ptrArrayNew (eFree);\n\tauxil->isArrayTable = isArrayTable;\n\tauxil->keyOffset = offset;\n\n\tif (auxil->lastTableIndex != CORK_NIL)\n\t\tmarkTableEnd (auxil, offset);\n}\n\nstatic void tableKeyEnd (struct parserCtx *auxil)\n{\n\ttagEntryInfo e;\n\tlong abs_offset = translateFileOffset (auxil->keyOffset);\n\tunsigned long lineNumber = getInputLineNumberForFileOffset (abs_offset);\n\tMIOPos filePosition = getInputFilePositionForLine (lineNumber);\n\n\tvString *vname = makeVStringFromKeyQueue (auxil->keyQueue);\n\tconst char *name = vStringValue (vname);\n\n\tinitTagEntry (&e, name, auxil->isArrayTable? TOML_K_ARRAYTABLE: TOML_K_TABLE);\n\te.lineNumber = lineNumber;\n\te.filePosition = filePosition;\n\n\tif (auxil->isArrayTable)\n\t{\n\t\tif (hashTableHasItem (auxil->arrayTableCounters, name))\n\t\t{\n\t\t\tvoid *tmp = hashTableGetItem (auxil->arrayTableCounters, name);\n\t\t\tint num = HT_PTR_TO_INT(tmp);\n\t\t\te.extensionFields.nth = num;\n\t\t\tnum++;\n\t\t\thashTableUpdateItem (auxil->arrayTableCounters, name, HT_INT_TO_PTR(num));\n\t\t}\n\t\telse\n\t\t{\n\t\t\te.extensionFields.nth = 0;\n\t\t\tchar *key = eStrdup (name);\n\t\t\thashTablePutItem (auxil->arrayTableCounters, key, HT_INT_TO_PTR(1));\n\t\t}\n\t}\n\n\tint table_index = makeTagEntry (&e);\n\tauxil->lastTableIndex = table_index;\n\n\tmakeTagsForKeys (auxil, lineNumber, filePosition, CORK_NIL);\n\tptrArrayClear (auxil->keyQueue);\n\n\tvStringDelete (vname);\t\t/* NULL is acceptable. */\n}\n\nstatic void keyvalStart (struct parserCtx *auxil, long offset)\n{\n\tif (auxil->keyQueue == NULL)\n\t\tauxil->keyQueue = ptrArrayNew (eFree);\n\tauxil->isArrayTable = false;\n\tauxil->keyOffset = offset;\n}\n\nstatic void keyvalKeyEnd (struct parserCtx *auxil)\n{\n\ttagEntryInfo e;\n\tlong abs_offset = translateFileOffset (auxil->keyOffset);\n\tunsigned long lineNumber = getInputLineNumberForFileOffset (abs_offset);\n\tMIOPos filePosition = getInputFilePositionForLine (lineNumber);\n\n\tvString *vname = makeVStringFromKeyQueue (auxil->keyQueue);\n\tconst char *name = vStringValue (vname);\n\n\tinitTagEntry (&e, name, TOML_K_QKEY);\n\te.lineNumber = lineNumber;\n\te.filePosition = filePosition;\n\te.extensionFields.scopeIndex = auxil->lastTableIndex;\n\tmakeTagEntry (&e);\n\n\tmakeTagsForKeys (auxil, lineNumber, filePosition, BASE_SCOPE(auxil));\n\tptrArrayClear (auxil->keyQueue);\n\n\tvStringDelete (vname);\t\t/* NULL is acceptable. */\n}\n\nstatic void keyvalValEnd (struct parserCtx *auxil)\n{\n\tfor (unsigned int i = uintArrayLast (auxil->unwind_depths); i > 0; i--)\n\t\tPOP_SCOPE (auxil);\n\tuintArrayRemoveLast (auxil->unwind_depths);\n}\n\nstatic void queueKey (struct parserCtx *auxil, const char *name)\n{\n\tif (auxil->keyQueue)\n\t{\n\t\tchar *key = eStrdup (name);\n\t\tptrArrayAdd (auxil->keyQueue, key);\n\t}\n}\n\nstatic void notifyValue (struct parserCtx *auxil, const char *value, long offset)\n{\n\tsubparser *sub;\n\ttomlSubparser *tomlsub = NULL;\n\n\tforeachSubparser (sub, false)\n\t{\n\t\ttomlsub = (tomlSubparser *)sub;\n\t\tif (tomlsub->valueNotify)\n\t\t{\n\t\t\tenterSubparser(sub);\n\t\t\ttomlsub->valueNotify(tomlsub, value, offset, BASE_SCOPE(auxil));\n\t\t\tleaveSubparser();\n\t\t}\n\t}\n}\n\nstatic void ctxInit (struct parserCtx *auxil)\n{\n\tBASE_INIT(auxil, KIND_GHOST_INDEX);\n\tauxil->keyQueue = NULL;\n\tauxil->lastTableIndex = CORK_NIL;\n\tauxil->arrayTableCounters = hashTableNew (7,\n\t\t\t\t\t\t\t\t\t\t\t  hashCstrhash,\n\t\t\t\t\t\t\t\t\t\t\t  hashCstreq,\n\t\t\t\t\t\t\t\t\t\t\t  eFree,\n\t\t\t\t\t\t\t\t\t\t\t  NULL);\n\tauxil->unwind_depths = uintArrayNew ();\n}\n\nstatic void ctxFini (struct parserCtx *auxil)\n{\n\tif (auxil->lastTableIndex != CORK_NIL)\n\t\tmarkTableEnd (auxil, -1);\n\n\tBASE_FINI(auxil);\n\tif (auxil->keyQueue)\n\t\tptrArrayDelete (auxil->keyQueue);\n\thashTableDelete (auxil->arrayTableCounters);\n\tuintArrayDelete (auxil->unwind_depths);\n}\n\nstatic void findTomlTags (void)\n{\n\tstruct parserCtx auxil;\n\n\tctxInit (&auxil);\n\tptoml_context_t *pctx = ptoml_create(&auxil);\n\n\twhile (ptoml_parse(pctx, NULL) && (!BASE_ERROR(&auxil)) );\n\n\tptoml_destroy(pctx);\n\twhile (getcFromInputFile() != EOF);\n\tctxFini (&auxil);\n}\n\nextern parserDefinition* TomlParser (void)\n{\n\tstatic const char *const extensions [] = { \"toml\", NULL };\n\tparserDefinition* def = parserNew (\"TOML\");\n\tdef->kindTable  = TomlKinds;\n\tdef->kindCount  = ARRAY_SIZE (TomlKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findTomlTags;\n\tdef->useCork    = true;\n\tdef->requestAutomaticFQTag = false;\n\n\tdef->enabled    = false;\t/* This parser is broken. */\n\n\treturn def;\n}\n"
  },
  {
    "path": "peg/toml_pre.h",
    "content": "/*\n *   Copyright (c) 2024 Masatake YAMATO\n *   Copyright (c) 2024 Red Hat, Inc.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains macros, data decls and prototypes to generate tags for TOML.\n *\n *   references:\n *   - https://toml.io/en/v1.0.0\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"kind.h\"\n#include \"peg_common.h\"\n#include \"../parsers/x-toml.h\"\n\n#include \"htable.h\"\n#include \"ptrarray.h\"\n\n/*\n*   MACROS\n*/\n\n/*\n*   DATA DECLARATIONS\n*/\nstatic roleDefinition TomlKeyRoles [] = {\n\t{ false, \"chainElt\", \"(EXPERIMENTAL)used as an element in a key name chain like a.b.c\" },\n};\n\nstatic kindDefinition TomlKinds [] = {\n\t{ false, 'k', \"key\",        \"keys\",\n\t  .referenceOnly = false, ATTACH_ROLES(TomlKeyRoles) },\n\t{ true,  't', \"table\",      \"tables\"                 },\n\t{ true,  'a', \"arraytable\", \"array tables\"           },\n\t{ true,  'K', \"qkey\",       \"qualified keys\"         },\n};\n\nstruct parserCtx {\n\tstruct parserBaseCtx base;\n\tptrArray *keyQueue;\n\tbool isArrayTable;\n\tlong keyOffset;\n\tint lastTableIndex;\n\thashTable *arrayTableCounters;\n\tuintArray *unwind_depths;\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nstatic void tableKeyStart (struct parserCtx *auxil, bool isArrayTable, long offset);\nstatic void tableKeyEnd (struct parserCtx *auxil);\nstatic void keyvalStart (struct parserCtx *auxil, long offset);\nstatic void keyvalKeyEnd (struct parserCtx *auxil);\nstatic void keyvalValEnd (struct parserCtx *auxil);\nstatic void queueKey (struct parserCtx *auxil, const char *name);\nstatic void notifyValue (struct parserCtx *auxil, const char *value, long offset);\n"
  },
  {
    "path": "peg/varlink.peg",
    "content": "#\n# This file is derived from\n#\n# https://github.com/varlink/rust/blob/master/varlink_parser/src/varlink_grammar.rustpeg\n#\n# Using the file in MIT License is allowed in https://github.com/varlink/rust/issues/20.\n#\n########################################################################\n#\n# MIT License\n#\n# Copyright (c) 2016 - 2018 Red Hat, Inc.\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n#\n########################################################################\n#\n# This module contains PEG grammer and functions for generating tags\n# for varlink IDL:\n#\n# * https://github.com/varlink\n# * https://varlink.org/Interface-Definition\n#\n# varlink_grammar.rustpeg uses ** and ++ extended operators.\n# peg processor written in Rust can understand the operators.\n# However, packcc doesn't do. So ** and ++ are replaced with\n# rules without ** and ++ operators.\n#\n# This parser is the test-bed for using packcc in ctags.\n#\n# TODO\n#\n# * revise scope field for field value\n# * implement typeref and signature fields\n#\n\n#\n# To avoid conflicting names in code generated by packcc and code written manually,\n# add \"p\" as prefix to names in generated code.\n#\n%prefix \"pvarlink\"\n\n%auxil\t\"struct parserCtx *\"\n\n%earlysource {\n    #include \"general.h\"\n}\n\n%header {\n\tstruct parserCtx;\n}\n\n%source {\n#include \"varlink_pre.h\"\n}\n\n#\n# Packcc tries to apply the first grammar rule in the input.\n#\ninterface\n    <- _* \"interface\" _+ interface_name eol ( member_list ) _*\n\n# Modeled after ECMA-262, 5th ed., 7.2. \\v\\f removed\nwhitespace\n    <- [ \\t\\u00A0\\uFEFF\\u1680\\u180E\\u2000-\\u200A\\u202F\\u205F\\u3000]\n\n# Modeled after ECMA-262, 5th ed., 7.3.\neol_r\n  <- \"\\n\"\n  / \"\\r\\n\"\n  / \"\\r\"\n  / \"\\u2028\"\n  / \"\\u2029\"\n\ncomment\n    <- \"#\" [^\\n\\r\\u2028\\u2029]* eol_r\n\neol\n    <- whitespace* eol_r\n    / comment\n\n_\n    <- whitespace / comment / eol_r\n\nfield_name\n    <- < [A-Za-z]('_'?[A-Za-z0-9])* > {\n    makeVarlinkTag(auxil, $1, $1s);\n}\n\nfield_name_list\n    <- field_name (_* ',' _* field_name)*\n\nname\n    <- < [A-Z][A-Za-z0-9]* > {\n    if (PEEK_KIND (auxil) != KIND_GHOST_INDEX)\n       SET_SCOPE(auxil, makeVarlinkTag(auxil, $1, $1s));\n}\n\ninterface_name\n    <- < [a-z]([-]* [a-z0-9])* ( '.' [a-z0-9]([-]*[a-z0-9])* )+ > {\n    SET_SCOPE(auxil, makeVarlinkTag(auxil, $1, $1s));\n}\n\ndict\n    <- \"[string]\"\n\narray\n    <- \"[]\"\n\nmaybe\n    <- \"?\"\n\nelement_type\n    <- \"bool\"\n    / \"int\"\n    / \"float\"\n    / \"string\"\n    / \"object\"\n    / { PUSH_KIND (auxil, KIND_GHOST_INDEX); } name { POP_KIND (auxil, false); }\n    / venum\n    / vstruct\n\ntype\n    <- element_type\n    / maybe element_type\n    / array type\n    / dict type\n    / maybe array type\n    / maybe dict type\n\nvenum\n    <- { PUSH_KIND (auxil, K_ENUMERATION); } '(' _* field_name_list? _* ')' { POP_KIND (auxil, false); }\n\nargument\n    <- _* field_name _* ':' _* type\n\nargument_list\n    <- argument (_* ',' _* argument)*\n\nvstruct\n    <- { pushKindContextual (auxil); } '(' _* argument_list? _* ')' { POP_KIND (auxil, false); }\n\nvtypedef\n    <- \"type\" { PUSH_KIND (auxil, K_STRUCT); } _+ name _* vstruct { POP_KIND (auxil, true); }\n    / \"type\" { PUSH_KIND (auxil, K_ENUM); } _+ name _* venum { POP_KIND (auxil, true); }\n\nerror\n    <- \"error\" { PUSH_KIND (auxil, K_ERROR); } _+ name _* vstruct { POP_KIND (auxil, true); }\n\nmethod\n    <- \"method\" {\n       PUSH_KIND (auxil, K_METHOD); setMethodParamState (auxil, METHOD_PARAM_INPUT);\n    } _+ name _* vstruct _* {\n       setMethodParamState (auxil, METHOD_PARAM_OUTPUT);\n    } \"->\" _* vstruct { POP_KIND (auxil, true); }\n\nmember\n    <- _* m:method\n    / _* t:vtypedef\n    / _* e:error\n\nmember_list\n   <- member (eol member)*\n\n%%\n#include \"varlink_post.h\"\n"
  },
  {
    "path": "peg/varlink_post.h",
    "content": "/*\n *   Copyright (c) 2019 Masatake YAMATO\n *   Copyright (c) 2019 Red Hat, Inc.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains functions to generate tags for Varlink.\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"options.h\"\n#include \"parse.h\"\n#include \"routines.h\"\n\n/*\n* FUNCTION DEFINITIONS\n*/\nstatic void pushKindContextual (struct parserCtx *auxil)\n{\n\tint k0 = basePeekKind(BASE(auxil));\n\tint k = KIND_GHOST_INDEX;\n\n\tswitch (k0)\n\t{\n\tcase K_METHOD:\n\t\tif (auxil->mparam_state == METHOD_PARAM_INPUT)\n\t\t\tk = K_IPARAM;\n\t\telse\n\t\t\tk = K_OPARAM;\n\t\tbreak;\n\tcase K_STRUCT:\n\t\tk = K_FIELD;\n\t\tbreak;\n\tcase K_ENUM:\n\t\tk = K_ENUMERATION;\n\t\tbreak;\n\tcase K_ERROR:\n\t\tk = K_EDESC;\n\t\tbreak;\n\tdefault:\n\t\tk = k0;\n\t\tbreak;\n\t}\n\n\tbasePushKind (BASE(auxil), k);\n}\n\nstatic void setMethodParamState (struct parserCtx *auxil, methodParamState s)\n{\n\tauxil->mparam_state = s;\n}\n\nstatic int makeVarlinkTag (struct parserCtx *auxil, const char *name, long offset)\n{\n\ttagEntryInfo e;\n\tint k = PEEK_KIND (auxil);\n\tinitTagEntry(&e, name, k);\n\tlong abs_offset = translateFileOffset (offset);\n\tunsigned long lineNumber = getInputLineNumberForFileOffset (abs_offset);\n\tupdateTagLine (&e, lineNumber, getInputFilePositionForLine (lineNumber));\n\te.extensionFields.scopeIndex = BASE_SCOPE (auxil);\n\treturn makeTagEntry (&e);\n}\n\nstatic void ctxInit (struct parserCtx *auxil)\n{\n\tBASE_INIT(auxil, K_INTERFACE);\n}\n\nstatic void ctxFini (struct parserCtx *auxil)\n{\n\tBASE_FINI(auxil);\n}\n\nstatic void findVarlinkTags (void)\n{\n\tstruct parserCtx auxil;\n\n\tctxInit (&auxil);\n\tpvarlink_context_t *pctx = pvarlink_create(&auxil);\n\n\twhile (pvarlink_parse(pctx, NULL) && (!BASE_ERROR(&auxil)) );\n\n\tpvarlink_destroy(pctx);\n\tctxFini (&auxil);\n}\n\nextern parserDefinition* VarlinkParser (void)\n{\n\tstatic const char *const extensions [] = { \"varlink\", NULL };\n\tparserDefinition* def = parserNew (\"Varlink\");\n\tdef->kindTable  = VarlinkKinds;\n\tdef->kindCount  = ARRAY_SIZE (VarlinkKinds);\n\tdef->extensions = extensions;\n\tdef->parser     = findVarlinkTags;\n\tdef->useCork    = true;\n\tdef->enabled    = true;\n\tdef->defaultScopeSeparator = \".\";\n\treturn def;\n}\n"
  },
  {
    "path": "peg/varlink_pre.h",
    "content": "/*\n *   Copyright (c) 2019 Masatake YAMATO\n *   Copyright (c) 2019 Red Hat, Inc.\n *\n *   This source code is released for free distribution under the terms of the\n *   GNU General Public License version 2 or (at your option) any later version.\n *\n *   This module contains macros, data decls and prototypes to generate tags for Varlink.\n */\n\n/*\n*   INCLUDE FILES\n*/\n#include \"kind.h\"\n#include \"peg_common.h\"\n\n\n/*\n*   MACROS\n*/\n\n/*\n*   DATA DECLARATIONS\n*/\ntypedef enum {\n\tK_INTERFACE,\n\tK_METHOD,\n\tK_IPARAM,\n\tK_OPARAM,\n\tK_STRUCT,\n\tK_FIELD,\n\tK_ENUM,\n\tK_ENUMERATION,\n\tK_ERROR,\n\tK_EDESC,\n} varlinkKind;\n\nstatic kindDefinition VarlinkKinds [] = {\n\t{ true,  'i', \"interface\",   \"interfaces\" },\n\t{ true,  'm', \"method\",      \"methods\" },\n\t{ true,  'I', \"iparam\",      \"input parameters\" },\n\t{ true,  'O', \"oparam\",      \"output parameters\" },\n\t{ true,  's', \"struct\",      \"structs\" },\n\t{ true,  'f', \"field\",       \"fields\" },\n\t{ true,  'g', \"enum\",        \"enumeration names\" },\n\t{ true,  'e', \"enumerator\",  \"enumerators (values inside an enumeration)\" },\n\t{ true,  'E', \"error\",       \"errors\" },\n\t{ true,  'd', \"edesc\",       \"error descriptors\" },\n};\n\ntypedef enum  {\n\tMETHOD_PARAM_INPUT,\n\tMETHOD_PARAM_OUTPUT,\n} methodParamState;\n\nstruct parserCtx {\n\tstruct parserBaseCtx base;\n\tmethodParamState mparam_state;\n};\n\n/*\n*   FUNCTION PROTOTYPES\n*/\nstatic void pushKindContextual (struct parserCtx *auxil);\nstatic void setMethodParamState (struct parserCtx *auxil, methodParamState s);\nstatic int makeVarlinkTag (struct parserCtx *auxil, const char *name, long offset);\n"
  },
  {
    "path": "source.mak",
    "content": "#\n# Shared macros\n#\n#   $(NULL) at the end of a list makes diff readable\n\n# REPOINFO_HEADS is included from REPOINFO_SRCS\n# only when the building environment has ability\n# to generate the header file.\n# REPOINFO_OBJS is always linked to ctags executable.\nREPOINFO_HEADS = main/repoinfo.h\nREPOINFO_SRCS  = main/repoinfo.c\nREPOINFO_OBJS  = $(REPOINFO_SRCS:.c=.$(OBJEXT))\n\nUTIL_PUBLIC_HEADS = \\\n\tmain/general.h\t\t\\\n\t\\\n\tmain/collector.h\t\\\n\tmain/fname.h\t\t\\\n\tmain/gcc-attr.h\t\t\\\n\tmain/htable.h\t\t\\\n\tmain/inline.h\t\t\\\n\tmain/intern.h\t\t\\\n\tmain/mio.h\t\t\\\n\tmain/numarray.h\t\t\\\n\tmain/ptrarray.h\t\t\\\n\tmain/routines.h\t\t\\\n\tmain/sort_r.h\t\t\\\n\tmain/trashbox.h \t\\\n\tmain/vstring.h\t\t\\\n\t\\\n\t$(NULL)\n\nUTIL_PRIVATE_HEADS = \\\n\tmain/routines_p.h\t\\\n\t\\\n\t$(NULL)\n\nUTIL_HEADS = \\\n\t$(UTIL_PUBLIC_HEADS)\t\\\n\t$(UTIL_PRIVATE_HEADS)\t\\\n\t\\\n\t$(NULL)\n\nUTIL_SRCS = \\\n\tmain/collector.c\t\\\n\tmain/fname.c\t\t\\\n\tmain/htable.c\t\t\\\n\tmain/intern.c\t\t\\\n\tmain/numarray.c\t\t\\\n\tmain/mio.c\t\t\\\n\tmain/ptrarray.c\t\t\\\n\tmain/routines.c\t\t\\\n\tmain/trashbox.c\t\t\\\n\tmain/vstring.c\t\t\\\n\t\\\n\t$(NULL)\nUTIL_OBJS = $(UTIL_SRCS:.c=.$(OBJEXT))\n\nUTILTEST_HEADS = \\\n\textra-cmds/acutest.h \\\n\t\\\n\t$(NULL)\nUTILTEST_SRCS  = \\\n\textra-cmds/utiltest.c \\\n\textra-cmds/readtags-stub.c \\\n\t\\\n\t$(NULL)\nUTILTEST_OBJS = $(UTILTEST_SRCS:.c=.$(OBJEXT))\n\nMAIN_PUBLIC_HEADS =\t\t\\\n\t$(UTIL_PUBLIC_HEADS)\t\\\n\t\\\n\tmain/dependency.h\t\\\n\tmain/entry.h\t\t\\\n\tmain/field.h\t\t\\\n\tmain/gvars.h\t\t\\\n\tmain/interval_tree_generic.h \\\n\tmain/keyword.h\t\t\\\n\tmain/kind.h\t\t\\\n\tmain/lregex.h\t\t\\\n\tmain/lxpath.h\t\t\\\n\tmain/mbcs.h\t\t\\\n\tmain/nestlevel.h\t\\\n\tmain/objpool.h\t\t\\\n\tmain/options.h\t\t\\\n\tmain/param.h\t\t\\\n\tmain/parse.h\t\t\\\n\tmain/promise.h\t\t\\\n\tmain/rbtree.h\t\t\\\n\tmain/rbtree_augmented.h\t\\\n\tmain/read.h\t\t\\\n\tmain/selectors.h\t\\\n\tmain/strlist.h\t\t\\\n\tmain/subparser.h\t\\\n\tmain/tokeninfo.h\t\\\n\tmain/trace.h\t\t\\\n\tmain/types.h\t\t\\\n\tmain/unwindi.h  \t\\\n\tmain/xtag.h\t\t\\\n\t\\\n\t$(NULL)\n\nLIB_PRIVATE_HEADS =\t\t\\\n\t$(UTIL_PRIVATE_HEADS)\t\\\n\t\\\n\tmain/args_p.h\t\t\\\n\tmain/colprint_p.h\t\\\n\tmain/dependency_p.h\t\\\n\tmain/entry_p.h\t\t\\\n\tmain/error_p.h\t\t\\\n\tmain/field_p.h\t\t\\\n\tmain/flags_p.h\t\t\\\n\tmain/fmt_p.h\t\t\\\n\tmain/interactive_p.h\t\\\n\tmain/keyword_p.h\t\\\n\tmain/kind_p.h\t\t\\\n\tmain/lregex_p.h\t\t\\\n\tmain/lxpath_p.h\t\t\\\n\tmain/main_p.h\t\t\\\n\tmain/mbcs_p.h\t\t\\\n\tmain/options_p.h\t\\\n\tmain/param_p.h\t\t\\\n\tmain/parse_p.h\t\t\\\n\tmain/parsers_p.h\t\\\n\tmain/portable-dirent_p.h\\\n\tmain/promise_p.h\t\\\n\tmain/ptag_p.h\t\t\\\n\tmain/read_p.h\t\t\\\n\tmain/rexprcode_p.h\t\\\n\tmain/script_p.h\t\t\\\n\tmain/sort_p.h\t\t\\\n\tmain/stats_p.h\t\t\\\n\tmain/subparser_p.h\t\\\n\tmain/trashbox_p.h\t\\\n\tmain/utf8_str.h\t\t\\\n\tmain/writer_p.h\t\t\\\n\tmain/xtag_p.h\t\t\\\n\t\\\n\t$(NULL)\n\nLIB_HEADS =\t\t\t\\\n\tmain/ctags.h\t\t\\\n\t\\\n\t$(MAIN_PUBLIC_HEADS)\t\\\n\t$(LIB_PRIVATE_HEADS)\t\\\n\t\\\n\t$(NULL)\n\nLIB_SRCS =\t\t\t\\\n\t$(UTIL_SRCS)\t\t\t\\\n\t\\\n\tmain/args.c\t\t\t\\\n\tmain/colprint.c\t\t\t\\\n\tmain/dependency.c\t\t\\\n\tmain/entry.c\t\t\t\\\n\tmain/entry_private.c\t\t\\\n\tmain/error.c\t\t\t\\\n\tmain/field.c\t\t\t\\\n\tmain/flags.c\t\t\t\\\n\tmain/fmt.c\t\t\t\\\n\tmain/keyword.c\t\t\t\\\n\tmain/kind.c\t\t\t\\\n\tmain/lregex.c\t\t\t\\\n\tmain/lregex-default.c\t\t\\\n\tmain/lxpath.c\t\t\t\\\n\tmain/main.c\t\t\t\\\n\tmain/mbcs.c\t\t\t\\\n\tmain/nestlevel.c\t\t\\\n\tmain/objpool.c\t\t\t\\\n\tmain/options.c\t\t\t\\\n\tmain/param.c\t\t\t\\\n\tmain/parse.c\t\t\t\\\n\tmain/portable-scandir.c\t\t\\\n\tmain/promise.c\t\t\t\\\n\tmain/ptag.c\t\t\t\\\n\tmain/rbtree.c\t\t\t\\\n\tmain/read.c\t\t\t\\\n\tmain/rexprcode.c\t\t\\\n\tmain/script.c\t\t\t\\\n\tmain/seccomp.c\t\t\t\\\n\tmain/selectors.c\t\t\\\n\tmain/sort.c\t\t\t\\\n\tmain/stats.c\t\t\t\\\n\tmain/strlist.c\t\t\t\\\n\tmain/trace.c\t\t\t\\\n\tmain/tokeninfo.c\t\t\\\n\tmain/unwindi.c\t\t\t\\\n\tmain/utf8_str.c\t\t\t\\\n\tmain/writer.c\t\t\t\\\n\tmain/writer-etags.c\t\t\\\n\tmain/writer-ctags.c\t\t\\\n\tmain/writer-json.c\t\t\\\n\tmain/writer-xref.c\t\t\\\n\tmain/xtag.c\t\t\t\\\n\t\\\n\t$(TXT2CSTR_SRCS) \\\n\t\\\n\t$(REPOINFO_SRCS) \\\n\t\\\n\t$(NULL)\n\nCMDLINE_HEADS =\nCMDLINE_SRCS = \\\n\tmain/cmd.c \\\n\t\\\n\t$(NULL)\n\nDEBUG_HEADS = main/debug.h\nDEBUG_SRCS = main/debug.c\n\nMINI_GEANY_HEADS =\nMINI_GEANY_SRCS = \\\n\tmain/mini-geany.c \\\n\t\\\n\t$(NULL)\n\nOPTSCRIPT_SRCS = \\\n\textra-cmds/optscript-repl.c \\\n\t\\\n\t$(NULL)\nOPTSCRIPT_OBJS = $(OPTSCRIPT_SRCS:.c=.$(OBJEXT))\n\nOPTLIB2C_PCRE2_INPUT =       \\\n   optlib/rdoc.ctags         \\\n   \\\n   $(NULL)\nOPTLIB2C_PCRE2_SRCS = $(OPTLIB2C_PCRE2_INPUT:.ctags=.c)\n\nOPTLIB2C_INPUT = \\\n\toptlib/cmake.ctags\t\t\t\\\n\toptlib/ctags-optlib.ctags\t\t\\\n\toptlib/elixir.ctags\t\t\t\\\n\toptlib/forth.ctags\t\t\t\\\n\toptlib/gdbinit.ctags\t\t\t\\\n\toptlib/gomod.ctags\t\t\t\\\n\toptlib/gperf.ctags\t\t\t\\\n\toptlib/inko.ctags\t\t\t\\\n\toptlib/iPythonCell.ctags\t\t\\\n\toptlib/kconfig.ctags\t\t\t\\\n\toptlib/lex.ctags\t\t\t\\\n\toptlib/man.ctags\t\t\t\\\n\toptlib/meson.ctags\t\t\t\\\n\toptlib/mesonOptions.ctags\t\t\\\n\toptlib/nftables.ctags\t\t\t\\\n\toptlib/org.ctags\t\t\t\\\n\toptlib/passwd.ctags\t\t\t\\\n\toptlib/pkgConfig.ctags\t\t\t\\\n\toptlib/pod.ctags\t\t\t\\\n\toptlib/puppetManifest.ctags\t\t\\\n\toptlib/qemuhx.ctags\t\t\t\\\n\toptlib/rpmMacros.ctags\t\t\t\\\n\toptlib/selinux-type-enforcement.ctags\t\\\n\toptlib/scdoc.ctags\t\t\t\\\n\toptlib/scss.ctags\t\t\t\\\n\toptlib/systemtap.ctags\t\t\t\\\n\toptlib/terraform.ctags\t\t\t\\\n\toptlib/terraformvariables.ctags\t\t\\\n\toptlib/yacc.ctags\t\t\t\\\n\t\\\n\t$(NULL)\nOPTLIB2C_SRCS = $(OPTLIB2C_INPUT:.ctags=.c)\n\nTXT2CSTR_INPUT = \\\n\tmain/CommonPrelude.ps\t\t\t\\\n\t\\\n\t$(NULL)\nTXT2CSTR_SRCS = $(TXT2CSTR_INPUT:.ps=.c)\n\nPEG_INPUT = \\\n       peg/varlink.peg\t\t\t\t\\\n       peg/kotlin.peg\t\t\t\t\\\n       peg/thrift.peg\t\t\t\t\\\n       peg/elm.peg\t\t\t\t\t\\\n       peg/toml.peg\t\t\t\t\\\n       \\\n       $(NULL)\nPEG_SRCS = $(PEG_INPUT:.peg=.c)\nPEG_HEADS = $(PEG_INPUT:.peg=.h)\nPEG_EXTRA_HEADS = peg/peg_common.h $(PEG_INPUT:.peg=_pre.h) $(PEG_INPUT:.peg=_post.h)\nPEG_OBJS = $(PEG_SRCS:.c=.$(OBJEXT))\n\nPEGO_INTERMEDIATE = $(PEG_INPUT:.peg=.pego)\n\nPARSER_X_HEADS = \\\n\tparsers/x-autoconf.h \\\n\tparsers/x-bibtex.h \\\n\tparsers/x-cpreprocessor.h \\\n\tparsers/x-frontmatter.h \\\n\tparsers/x-html.h \\\n\tparsers/x-iniconf.h \\\n\tparsers/x-jscript.h \\\n\tparsers/x-lisp.h \\\n\tparsers/x-m4.h \\\n\tparsers/x-make.h \\\n\tparsers/x-markdown.h \\\n\tparsers/x-perl.h \\\n\tparsers/x-python.h \\\n\tparsers/x-r.h \\\n\tparsers/x-ruby.h \\\n\tparsers/x-sh.h \\\n\tparsers/x-systemdunit.h \\\n\tparsers/x-tcl.h \\\n\tparsers/x-tex.h \\\n\tparsers/x-toml.h \\\n\t\\\n\t$(NULL)\n\nPARSER_D_HEADS = \\\n\tparsers/d-typescript.h \\\n\tparsers/d-rust.h \\\n\t\\\n\t$(NULL)\n\nPARSER_HEADS = \\\n\tparsers/cxx/cxx_debug.h \\\n\tparsers/cxx/cxx_keyword.h \\\n\tparsers/cxx/cxx_parser_internal.h \\\n\tparsers/cxx/cxx_parser.h \\\n\tparsers/cxx/cxx_scope.h \\\n\tparsers/cxx/cxx_side_chain.h \\\n\tparsers/cxx/cxx_subparser.h \\\n\tparsers/cxx/cxx_subparser_internal.h \\\n\tparsers/cxx/cxx_tag.h \\\n\tparsers/cxx/cxx_token.h \\\n\tparsers/cxx/cxx_token_chain.h \\\n\t\\\n\t$(PARSER_X_HEADS) \\\n\t$(PARSER_D_HEADS) \\\n\t\\\n\t$(NULL)\n\nPARSER_SRCS =\t\t\t\t\\\n\tparsers/abaqus.c\t\t\\\n\tparsers/abc.c\t\t\t\\\n\tparsers/ada.c\t\t\t\\\n\tparsers/ant.c\t\t\t\\\n\tparsers/asciidoc.c\t\t\\\n\tparsers/asm.c\t\t\t\\\n\tparsers/asp.c\t\t\t\\\n\tparsers/autoconf.c\t\t\\\n\tparsers/autoit.c\t\t\\\n\tparsers/automake.c\t\t\\\n\tparsers/awk.c\t\t\t\\\n\tparsers/basic.c\t\t\t\\\n\tparsers/bats.c\t\t\t\\\n\tparsers/beta.c\t\t\t\\\n\tparsers/biblatex.c\t\t\\\n\tparsers/bibtex.c\t\t\\\n\tparsers/c-based.c\t\t\\\n\tparsers/clojure.c\t\t\\\n\tparsers/css.c\t\t\t\\\n\tparsers/cobol.c\t\t\t\\\n\tparsers/cpreprocessor.c\t\t\\\n\tparsers/cxx/cxx.c\t\t\\\n\tparsers/cxx/cxx_debug.c\t\t\\\n\tparsers/cxx/cxx_debug_type.c\t\\\n\tparsers/cxx/cxx_jni.c\t\t\\\n\tparsers/cxx/cxx_keyword.c\t\t\\\n\tparsers/cxx/cxx_parser.c\t\t\\\n\tparsers/cxx/cxx_parser_block.c\t\t\\\n\tparsers/cxx/cxx_parser_function.c\t\\\n\tparsers/cxx/cxx_parser_lambda.c\t\t\\\n\tparsers/cxx/cxx_parser_module.c\t\t\\\n\tparsers/cxx/cxx_parser_namespace.c\t\\\n\tparsers/cxx/cxx_parser_template.c\t\\\n\tparsers/cxx/cxx_parser_tokenizer.c\t\\\n\tparsers/cxx/cxx_parser_typedef.c\t\\\n\tparsers/cxx/cxx_parser_using.c\t\t\\\n\tparsers/cxx/cxx_parser_variable.c\t\\\n\tparsers/cxx/cxx_qtmoc.c\t\t\\\n\tparsers/cxx/cxx_scope.c\t\t\\\n\tparsers/cxx/cxx_side_chain.c\t\\\n\tparsers/cxx/cxx_subparser.c\t\\\n\tparsers/cxx/cxx_tag.c\t\t\\\n\tparsers/cxx/cxx_token.c\t\t\\\n\tparsers/cxx/cxx_token_chain.c\t\\\n\tparsers/dbus-service.c\t\t\\\n\tparsers/diff.c\t\t\t\\\n\tparsers/dosbatch.c\t\t\\\n\tparsers/dtd.c\t\t\t\\\n\tparsers/dts.c\t\t\t\\\n\tparsers/eiffel.c\t\t\\\n\tparsers/erlang.c\t\t\\\n\tparsers/falcon.c\t\t\\\n\tparsers/flex.c\t\t\t\\\n\tparsers/fortran.c\t\t\\\n\tparsers/frontmatter.c\t\t\\\n\tparsers/fypp.c\t\t\t\\\n\tparsers/gdscript.c\t\t\\\n\tparsers/gemspec.c\t\t\\\n\tparsers/go.c\t\t\t\\\n\tparsers/haskell.c\t\t\\\n\tparsers/haxe.c\t\t\t\\\n\tparsers/html.c\t\t\t\\\n\tparsers/iniconf.c\t\t\\\n\tparsers/itcl.c\t\t\t\\\n\tparsers/jprop.c\t\t\t\\\n\tparsers/jscript.c\t\t\\\n\tparsers/json.c\t\t\t\\\n\tparsers/julia.c\t\t\t\\\n\tparsers/ldscript.c\t\t\\\n\tparsers/lisp.c\t\t\t\\\n\tparsers/lua.c\t\t\t\\\n\tparsers/m4.c\t\t\t\\\n\tparsers/make.c\t\t\t\\\n\tparsers/markdown.c\t\t\t\\\n\tparsers/matlab.c\t\t\\\n\tparsers/myrddin.c\t\t\\\n\tparsers/nsis.c\t\t\t\\\n\tparsers/objc.c\t\t\t\\\n\tparsers/ocaml.c\t\t\t\\\n\tparsers/odin.c\t\t\t\\\n\tparsers/pascal.c\t\t\\\n\tparsers/perl.c\t\t\t\\\n\tparsers/perl-function-parameters.c \\\n\tparsers/perl-moose.c\t\t\\\n\tparsers/php.c\t\t\t\\\n\tparsers/powershell.c\t\t\\\n\tparsers/prolog.c\t\t\\\n\tparsers/protobuf.c\t\t\\\n\tparsers/python.c\t\t\\\n\tparsers/python-entry-points.c\t\\\n\tparsers/python-logging-config.c\t\\\n\tparsers/quarto.c\t\t\\\n\tparsers/r-r6class.c\t\t\\\n\tparsers/r-s4class.c\t\t\\\n\tparsers/r.c\t\t\t\\\n\tparsers/rake.c\t\t\t\\\n\tparsers/raku.c\t\t\t\\\n\tparsers/rexx.c\t\t\t\\\n\tparsers/rmarkdown.c\t\t\\\n\tparsers/robot.c\t\t\t\\\n\tparsers/rpmspec.c\t\t\\\n\tparsers/rspec.c\t\t\t\\\n\tparsers/rst.c\t\t\t\\\n\tparsers/ruby.c\t\t\t\\\n\tparsers/rust.c\t\t\t\\\n\tparsers/scheme.c\t\t\\\n\tparsers/selinux-interface.c\t\\\n\tparsers/sh.c\t\t\t\\\n\tparsers/sinex.c\t\t\t\\\n\tparsers/slang.c\t\t\t\\\n\tparsers/sml.c\t\t\t\\\n\tparsers/sql.c\t\t\t\\\n\tparsers/systemdunit.c\t\t\\\n\tparsers/tcl.c\t\t\t\\\n\tparsers/tcloo.c\t\t\t\\\n\tparsers/tex.c\t\t\t\\\n\tparsers/tex-beamer.c\t\t\\\n\tparsers/cargo.c\t\t\t\\\n\tparsers/ttcn.c\t\t\t\\\n\tparsers/txt2tags.c\t\t\\\n\tparsers/typescript.c\t\t\\\n\tparsers/v.c\t\t\t\\\n\tparsers/typespec.c\t\t\\\n\tparsers/vera.c\t\t\t\\\n\tparsers/verilog.c\t\t\\\n\tparsers/vhdl.c\t\t\t\\\n\tparsers/vim.c\t\t\t\\\n\tparsers/windres.c\t\t\\\n\tparsers/yumrepo.c\t\t\\\n\t\\\n\t$(OPTLIB2C_SRCS)\t\t\\\n\t\\\n\t$(NULL)\n\nXML_HEADS = parsers/x-xml.h\nXML_SRCS = \\\n\tparsers/maven2.c\t\t\\\n\tparsers/dbus-introspect.c\t\\\n\tparsers/glade.c\t\t\t\\\n\tparsers/svg.c\t\t\t\\\n\tparsers/plist.c\t\t\t\\\n\tparsers/relaxng.c\t\t\\\n\tparsers/xml.c\t\t\t\\\n\tparsers/xrc.c\t\t\t\\\n\tparsers/xslt.c\t\t\t\\\n\t\\\n\t$(NULL)\n\nYAML_HEADS = parsers/x-yaml.h\nYAML_SRCS = \\\n\tparsers/yaml.c\t\t\\\n\t\\\n\tparsers/openapi.c\t\\\n\t\\\n\tparsers/ansibleplaybook.c\t\\\n\t\\\n\tparsers/yamlfrontmatter.c\t\\\n\t\\\n\tparsers/i18nrubygem.c\t\\\n\t\\\n\t$(NULL)\n\nPCRE2_HEADS =\nPCRE2_SRCS = \\\n\t    main/lregex-pcre2.c \\\n\t    \\\n\t    $(NULL)\n\nOPTSCRIPT_DSL_HEADS = \\\n\tdsl/es.h \\\n\tdsl/optscript.h \\\n\t\\\n\t$(NULL)\n\nOPTSCRIPT_DSL_SRCS = \\\n\tdsl/es.c \\\n\tdsl/optscript.c \\\n\t\\\n\t$(NULL)\nOPTSCRIPT_DSL_OBJS = $(OPTSCRIPT_DSL_SRCS:.c=.$(OBJEXT))\n\nREADTAGS_DSL_HEADS = \\\n\tdsl/es.h \\\n\tdsl/dsl.h \\\n\tdsl/formatter.h \\\n\tdsl/qualifier.h \\\n\tdsl/sorter.h \\\n\t\\\n\t$(NULL)\n\nREADTAGS_DSL_SRCS = \\\n\tdsl/es.c \\\n\tdsl/dsl.c \\\n\tdsl/formatter.c \\\n\tdsl/qualifier.c \\\n\tdsl/sorter.c \\\n\t\\\n\t$(NULL)\nREADTAGS_DSL_OBJS = $(READTAGS_DSL_SRCS:.c=.$(OBJEXT))\n\nREADTAGS_SRCS  = \\\n\tlibreadtags/readtags.c      \\\n\textra-cmds/printtags.c  \\\n\textra-cmds/readtags-cmd.c  \\\n\textra-cmds/readtags-stub.c \\\n\t\\\n\t$(NULL)\nREADTAGS_HEADS = \\\n\tlibreadtags/readtags.h \\\n\textra-cmds/printtags.h  \\\n\textra-cmds/readtags-stub.h \\\n\t\\\n\t$(NULL)\nREADTAGS_OBJS  = $(READTAGS_SRCS:.c=.$(OBJEXT))\n\nPACKCC_SRC = misc/packcc/src/packcc.c\nPACKCC_OBJ = $(PACKCC_SRC:.c=.$(OBJEXT))\n\nWIN32_HEADS = main/e_msoft.h\nWIN32_SRCS = win32/mkstemp/mkstemp.c\nWIN32_OBJS = $(WIN32_SRCS:.c=.$(OBJEXT))\n\n# common to MVC and MINGW\nCOMMON_GNULIB_HEADS = \\\n\tgnulib/regex.h\t\t\t\\\n\tgnulib/fnmatch.h\t\t\\\n\t\\\n\t$(NULL)\nCOMMON_GNULIB_SRCS = \\\n\tgnulib/regex.c\t\t\t\\\n\tgnulib/nl_langinfo.c\t\t\\\n\tgnulib/setlocale_null.c\t\t\\\n\tgnulib/malloc/dynarray_resize.c\t\\\n\tgnulib/fnmatch.c\t\t\\\n\tgnulib/mempcpy.c\t\t\\\n\tgnulib/wmempcpy.c\t\t\\\n\t\\\n\t$(NULL)\n\nMVC_GNULIB_HEADS = \\\n\t$(COMMON_GNULIB_HEADS)\t\t\\\n\t\\\n\t$(NULL)\nMVC_GNULIB_SRCS = \\\n\t$(COMMON_GNULIB_SRCS)\t\t\\\n\t\\\n\t$(NULL)\n\nMINGW_GNULIB_HEADS = \\\n\t$(COMMON_GNULIB_HEADS)\t\t\\\n\t\\\n\t$(NULL)\nMINGW_GNULIB_SRCS = \\\n\t$(COMMON_GNULIB_SRCS)\t\t\\\n\tgnulib/localeconv.c\t\t\\\n\t\\\n\t$(NULL)\n\nENVIRONMENT_HEADS =\nENVIRONMENT_SRCS =\n\nALL_LIB_HEADS = $(LIB_HEADS) $(PARSER_HEADS) $(DEBUG_HEADS) $(DSL_HEADS) $(OPTSCRIPT_DSL_HEADS)\nALL_LIB_SRCS  = $(LIB_SRCS) $(PARSER_SRCS) $(DEBUG_SRCS) $(DSL_SRCS) $(OPTSCRIPT_DSL_SRCS)\nALL_LIB_OBJS = \\\n\t$(ALL_LIB_SRCS:.c=.$(OBJEXT)) \\\n\t$(LIBOBJS)\n\nALL_HEADS = $(ALL_LIB_HEADS) $(CMDLINE_HEADS)\nALL_SRCS = $(ALL_LIB_SRCS) $(CMDLINE_SRCS)\nALL_OBJS = \\\n\t$(ALL_SRCS:.c=.$(OBJEXT)) \\\n\t$(LIBOBJS)\n\n# vim: ts=8\n"
  },
  {
    "path": "win32/GNUmakefile",
    "content": "#\n# Copyright (c) 2021, Hiroo Hayashi\n#\n# This source code is released for free distribution under the terms of the\n# GNU General Public License version 2 or (at your option) any later version.\n#\n# Makefile to generate ctags_vs2013.vcxproj, ctags_vs2013.vcxproj.filters, and peg_rule.mak\n#\n#   usage: make [-B]\n#\n# Restrictions:\n#   - Input Files: ctags_vs2013.vcxproj.in and ctags_vs2013.vcxproj.filters.in\n#     - The last charactor of the files must be '>'.\n#       cf. check_eof_chars_in_vcxproj() in misc/src-check.\n#     - Other lines must be end with LF.\n#   - GNU make is required.\n\nVCXPROJ = ctags_vs2013.vcxproj\nVCXPROJ_FILTERS = ctags_vs2013.vcxproj.filters\nSOURCE_MAK = ../source.mak\nPEG_RULE_MAK = peg_rule.mak\n\nall: $(VCXPROJ) $(VCXPROJ_FILTERS) $(PEG_RULE_MAK)\n\ninclude $(SOURCE_MAK)\n\n# exclude some files for Win32 and replace a slash (/) to a backslash (\\)\nMVC_SRCS = $(MVC_GNULIB_SRCS) $(CMDLINE_SRCS) $(LIB_SRCS) $(OPTLIB2C_SRCS) $(PARSER_SRCS) $(OPTSCRIPT_DSL_SRCS) $(DEBUG_SRCS) $(WIN32_SRCS)\nMVC_SRCS_EXCLUDE = main/mbcs.c main/seccomp.c main/trace.c\nMVC_SRCS_CONV = $(sort $(subst /,\\\\,$(filter-out $(MVC_SRCS_EXCLUDE),$(MVC_SRCS))))\n\nMVC_HEADS = $(MVC_GNULIB_HEADS) $(CMDLINE_HEADS) $(LIB_HEADS) $(OPTLIB2C_HEADS) $(PARSER_HEADS) $(OPTSCRIPT_DSL_HEADS) $(DEBUG_HEADS)  $(WIN32_HEADS)\nMVC_HEADS_EXCLUDE = main/interactive_p.h main/mbcs.h main/mbcs_p.h main/trace.h\nMVC_HEADS_CONV = $(sort $(subst /,\\\\,$(filter-out $(MVC_HEADS_EXCLUDE),$(MVC_HEADS))))\n\nMVC_INC_DIRS = ..;../main;../gnulib;../parsers;../parsers/cxx;../dsl;\n\n# a portable 'echo' which disables the interpretation of escape characters like 'echo -E' on bash\n# see https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.70/autoconf.html#Limitations-of-Builtins\nECHO = printf '%s\\n'\n# escape backslashes and newlines in the replacement pattern for sed\nESCAPE_BACKSLASH = sed -e 's|\\\\|\\\\\\\\|g' -e 's/$$/\\\\/' | sed -e '$$s/\\\\$$//'\n# insert CR before LF except for the last line\nLF2CRLF = sed -e '$$!s/$$/\\r/'\n\n$(VCXPROJ): $(VCXPROJ).in $(SOURCE_MAK)\n\t@echo generating $@ ...\n\t@# C source files \\\n\tSRCS=$$(for i in $(MVC_SRCS_CONV); do \\\n\t\t$(ECHO) \"    <ClCompile Include=\\\"..\\\\$$i\\\" />\"; \\\n\tdone); \\\n\tSRCS=$$($(ECHO) \"$$SRCS\" | $(ESCAPE_BACKSLASH)); \\\n\t# header files \\\n\tHEADS=$$(for i in $(MVC_HEADS_CONV); do \\\n\t\t$(ECHO) \"    <ClInclude Include=\\\"..\\\\$$i\\\" />\"; \\\n\tdone; \\\n\t$(ECHO) \"    <ClInclude Include=\\\"resource.h\\\" />\"); \\\n\tHEADS=$$($(ECHO) \"$$HEADS\" | $(ESCAPE_BACKSLASH)); \\\n\t# replace @foo@ in $(VCXPROJ).in \\\n\tsed -e \"s![@]SRCS[@]!$$SRCS!\" \\\n\t    -e \"s![@]HEADS[@]!$$HEADS!\" \\\n\t    -e \"s|[@]INC_DIRS[@]|${MVC_INC_DIRS}|\" $< | $(LF2CRLF) > $@\n\n$(VCXPROJ_FILTERS): $(VCXPROJ_FILTERS).in $(SOURCE_MAK)\n\t@echo generating $@ ...\n\t@# C source files \\\n\tSRCS=$$(for i in $(MVC_SRCS_CONV); do \\\n\t\tdirname=$$($(ECHO) $$i | sed -e 's/\\\\[a-zA-Z_0-9.-]*$$//'); \\\n\t\t$(ECHO) \"    <ClCompile Include=\\\"..\\\\$$i\\\">\"; \\\n\t\t$(ECHO) \"      <Filter>Source Files\\\\$$dirname</Filter>\"; \\\n\t\t$(ECHO) \"    </ClCompile>\"; \\\n\tdone); \\\n\tSRCS=$$($(ECHO) \"$$SRCS\" | $(ESCAPE_BACKSLASH)); \\\n\t# header files \\\n\tHEADS=$$(for i in $(MVC_HEADS_CONV); do \\\n\t\t$(ECHO) \"    <ClInclude Include=\\\"..\\\\$$i\\\">\"; \\\n\t\t$(ECHO) \"      <Filter>Header Files</Filter>\"; \\\n\t\t$(ECHO) \"    </ClInclude>\"; \\\n\tdone; \\\n\t$(ECHO) \"    <ClInclude Include=\\\"resource.h\\\">\"; \\\n\t$(ECHO) \"      <Filter>Header Files</Filter>\"; \\\n\t$(ECHO) \"    </ClInclude>\"); \\\n\tHEADS=$$($(ECHO) \"$$HEADS\" | $(ESCAPE_BACKSLASH)); \\\n\t# replace @foo@ in $(VCXPROJ_FILTERS).in \\\n\tsed -e \"s![@]SRCS[@]!$$SRCS!\" \\\n\t    -e \"s![@]HEADS[@]!$$HEADS!\" $< | $(LF2CRLF) > $@\n\n$(PEG_RULE_MAK): $(SOURCE_MAK)\n\t@echo generating $@ ...\n\t@# PEG source files \\\n\t$(ECHO) '# Generated by win32/GNUmakefile' > $@; \\\n\tfor i in $(PEG_INPUT); do \\\n\t\t$(ECHO) \"peg/$$(basename $$i .peg).c peg/$$(basename $$i .peg).h: $$i \\$$(PACKCC)\"; \\\n\tdone >> $@\n"
  },
  {
    "path": "win32/Makefile",
    "content": "# Based on https://github.com/universal-ctags/ctags/pull/3353#issuecomment-1103403502\n# posted by @eli-schwartz.\nall:\n\t@if type gmake > /dev/null 2>&1; then\t\t\t\t\t\t\t\\\n\t\tgmake $@;\t\t\t\t\t\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t@echo \"WARNING: GNU make is needed for updating win32 related build-script.\";\t\\\n\t\t@echo \"WARNING: skip the operations in this directory: gmake $@\";\t\t\\\n\tfi\n\n.DEFAULT:\n\t@if type gmake > /dev/null 2>&1; then\t\t\t\t\t\t\t\\\n\t\tgmake $@;\t\t\t\t\t\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\t\t\t\\\n\t\techo \"WARNING: GNU make is needed for updating win32 related build-script.\";\t\\\n\t\techo \"WARNING: skip the operations in this directory: gmake $@\";\t\t\\\n\tfi\n\n.PHONY: all\n"
  },
  {
    "path": "win32/appveyor.bat",
    "content": "@echo off\r\n:: Batch file for building/testing ctags on AppVeyor\r\n::\r\n:: Copyright (C) 2015 Ken Takata\r\n:: License: GPL-2 or later\r\n\r\n\r\ncd %APPVEYOR_BUILD_FOLDER%\r\nif \"%1\"==\"\" (\r\n  set target=build\r\n) else (\r\n  set target=%1\r\n)\r\n\r\n:: Daily builds or tag builds should be only built by msys2\r\nset normalbuild=yes\r\nif \"%APPVEYOR_SCHEDULED_BUILD%\"==\"True\" (\r\n  set normalbuild=no\r\n)\r\nif not \"%APPVEYOR_REPO_TAG_NAME%\"==\"\" (\r\n  set normalbuild=no\r\n)\r\nif \"%normalbuild%\"==\"no\" (\r\n  if not \"%compiler%\"==\"msys2\" (\r\n    exit 0\r\n  )\r\n)\r\n\r\nfor %%i in (msbuild msvc msys2 mingw cygwin) do if \"%compiler%\"==\"%%i\" goto %compiler%_%target%\r\n\r\necho Unknown build target.\r\nexit 1\r\n\r\n:msbuild_build\r\n:: ----------------------------------------------------------------------\r\n:: Using VC12 (VC2013) with msbuild, iconv disabled\r\n@echo on\r\ncopy win32\\config_mvc.h config.h\r\ncopy win32\\gnulib_h\\langinfo.h gnulib\r\ncopy win32\\gnulib_h\\fnmatch.h gnulib\r\ncd win32\r\nmsbuild ctags_vs2013.sln /logger:\"C:\\Program Files\\AppVeyor\\BuildAgent\\Appveyor.MSBuildLogger.dll\" /p:Configuration=%CONFIGURATION%\r\n\r\n@echo off\r\ngoto :eof\r\n\r\n:msbuild_test\r\ncd win32\r\n@echo on\r\n:: Check filetype\r\nc:\\cygwin64\\bin\\file %CONFIGURATION%\\ctags.exe\r\n:: Check if it works\r\n%CONFIGURATION%\\ctags --version || exit 1\r\n\r\n@echo off\r\ngoto :eof\r\n\r\n:msbuild_package\r\n:: Do nothing.\r\ngoto :eof\r\n\r\n\r\n:msvc_build\r\n:: ----------------------------------------------------------------------\r\n:: Using VC12 (VC2013) with nmake, iconv enabled\r\n:: Also create Makefile with msys2 and test the VC binary on msys2.\r\nset MSYS2_ARCH=x86_64\r\nset MSYS2_DIR=msys64\r\nset MSYSTEM=MINGW64\r\ncall \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat\" %ARCH%\r\n\r\n:: Build libiconv (MSVC port)\r\nset ICONV_BUILD_DIR=C:\\projects\\libiconv\r\ngit clone -q --branch=master --depth=1 https://github.com/koron/libiconv.git %ICONV_BUILD_DIR%\r\ncd %ICONV_BUILD_DIR%\\msvc10\r\nnmake NODEBUG=1 NOMSVCRT=1\r\n\r\n:: Install libiconv to %ICONV_DIR%\r\nset ICONV_DIR=C:\\projects\\iconv\r\nmkdir %ICONV_DIR%\\include\r\nmkdir %ICONV_DIR%\\lib\r\ncopy %ICONV_BUILD_DIR%\\msvc10\\iconv.h   %ICONV_DIR%\\include     > nul\r\ncopy %ICONV_BUILD_DIR%\\msvc10\\iconv.lib %ICONV_DIR%\\lib         > nul\r\ncopy %ICONV_BUILD_DIR%\\msvc10\\iconv.dll %APPVEYOR_BUILD_FOLDER% > nul\r\n\r\n:: Build ctags with nmake\r\n@echo on\r\ncd %APPVEYOR_BUILD_FOLDER%\r\nnmake -f mk_mvc.mak WITH_ICONV=yes ICONV_DIR=%ICONV_DIR% PDB=yes DEBUG=1 || exit 1\r\n\r\n@echo off\r\ngoto :eof\r\n\r\n:msvc_test\r\n@echo on\r\n:: Prepare for msys2\r\npath C:\\%MSYS2_DIR%\\usr\\bin;%PATH%\r\nset CHERE_INVOKING=yes\r\n\r\n:: Check filetype (VC binaries)\r\nc:\\cygwin64\\bin\\file ctags.exe\r\nc:\\cygwin64\\bin\\file readtags.exe\r\n:: Check if it works\r\n.\\ctags --version || exit 1\r\n\r\n:: Run tests using misc/units.py on msys2\r\nbash -lc \"py misc/units.py tmain ./Tmain --ctags=./ctags.exe --readtags=./readtags.exe --show-diff-output --shell=c:/msys64/usr/bin/sh\" || exit 1\r\nbash -lc \"py misc/units.py run ./Units --ctags=./ctags.exe --show-diff-output --with-timeout=10 --shell=c:/msys64/usr/bin/sh\" || exit 1\r\n\r\n@echo off\r\ngoto :eof\r\n\r\n:msvc_package\r\n:: Do nothing.\r\ngoto :eof\r\n\r\n\r\n:msys2_build\r\n:: ----------------------------------------------------------------------\r\n:: Using msys2\r\n@echo on\r\nPATH C:\\%MSYS2_DIR%\\%MSYSTEM%\\bin;C:\\%MSYS2_DIR%\\usr\\bin;%PATH%\r\nset CHERE_INVOKING=yes\r\n@rem Reduce time required to install packages by disabling pacman's disk space checking.\r\nbash -lc \"sed -i 's/^CheckSpace/#CheckSpace/g' /etc/pacman.conf\"\r\nif \"%normalbuild%\"==\"no\" (\r\n  @rem Change build message: \"Daily build: YYYY-MM-DD\"\r\n  for /f \"tokens=2-4 delims=/ \" %%i in ('date /t') do appveyor UpdateBuild -Message \"Daily build: %%k-%%i-%%j\"\r\n\r\n  @rem Remove unused toolchain to reduce the time for updating\r\n  if \"%MSYSTEM%\"==\"MINGW64\" (\r\n    bash -lc \"pacman --noconfirm -Rs mingw-w64-i686-toolchain\"\r\n  ) else if \"%MSYSTEM%\"==\"MINGW32\" (\r\n    bash -lc \"pacman --noconfirm -Rs mingw-w64-x86_64-toolchain\"\r\n  )\r\n  @rem Synchronize package databases and upgrade the core system\r\n  C:\\%MSYS2_DIR%\\usr\\bin\\pacman --noconfirm --noprogressbar -Syu\r\n  @rem Run again to update the rest of packages\r\n  C:\\%MSYS2_DIR%\\usr\\bin\\pacman --noconfirm --noprogressbar -Su\r\n  @rem Also install packages needed for creating zip package\r\n  bash -lc \"for i in {1..3}; do pacman --noconfirm --noprogressbar -S --needed mingw-w64-%MSYS2_ARCH%-python3-sphinx && break || sleep 15; done\"\r\n)\r\n:: Install necessary packages\r\nbash -lc \"for i in {1..3}; do pacman --noconfirm --noprogressbar -S --needed mingw-w64-%MSYS2_ARCH%-{jansson,libxml2,libyaml,pcre2} autoconf automake && break || sleep 15; done\"\r\n\r\nbash -lc \"./autogen.sh\" || exit 1\r\n:: Use static link.\r\nbash -lc \"./configure --disable-external-sort --enable-static && make -j2\"\r\n\r\n@echo off\r\ngoto :eof\r\n\r\n:msys2_test\r\n@echo on\r\n:: Check filetype (msys2 binaries)\r\nc:\\cygwin64\\bin\\file ctags.exe\r\nc:\\cygwin64\\bin\\file readtags.exe\r\n:: Check if it works\r\n.\\ctags --version || exit 1\r\n\r\n:: Run tests\r\nif \"%normalbuild%-%ARCH%\"==\"yes-x64\" (\r\n  @echo Tests for msys2 x64 are skipped.\r\n  exit 0\r\n)\r\nbash -lc \"make check PYTHON=py\"\r\n\r\n@echo off\r\ngoto :eof\r\n\r\n:msys2_package\r\n:: Only daily builds or tag builds need to create zip packages\r\nif \"%normalbuild%\"==\"yes\" (\r\n  exit 0\r\n)\r\nmd package\r\n:: Build html docs and man pages\r\nbash -lc \"make -C docs html && make -C man html\" || exit 1\r\nmove docs\\_build\\html package\\docs > nul\r\nrd /s/q package\\docs\\_sources\r\n\r\n:: Get version\r\nif \"%APPVEYOR_REPO_TAG_NAME%\"==\"\" (\r\n  for /f %%i in ('git describe --tags --always') do set ver=%%i\r\n) else (\r\n  set ver=%APPVEYOR_REPO_TAG_NAME%\r\n)\r\nset ver=%ver:/=_%\r\n\r\n:: Create zip package\r\nset filelist=ctags.exe readtags.exe README.md\r\nset dirlist=docs license man\r\nrobocopy . package %filelist% > nul\r\nrobocopy win32\\license package\\license > nul\r\ncopy COPYING package\\license > nul\r\ncopy win32\\mkstemp\\COPYING.MinGW-w64-runtime.txt package\\license > nul\r\nrobocopy man package\\man *.html > nul\r\ncd package\r\nfor %%i in (*.exe) do call :strip %%i\r\n7z a ..\\ctags-%ver%-%ARCH%.zip %filelist% %dirlist%\r\n7z a ..\\ctags-%ver%-%ARCH%.debuginfo.zip *.exe.debug\r\ncd ..\r\ngoto :eof\r\n\r\n:strip\r\nobjcopy --only-keep-debug %1 %1.debug\r\nstrip %1\r\nobjcopy --add-gnu-debuglink=%1.debug %1\r\ngoto :eof\r\n\r\n\r\n:mingw_build\r\n:: ----------------------------------------------------------------------\r\n:: Using MinGW-w64 without autotools, iconv disabled\r\n@echo on\r\nset MSYS2_ARCH=x86_64\r\nset MSYS2_DIR=msys64\r\nset MSYSTEM=MINGW64\r\nPATH C:\\%MSYS2_DIR%\\%MSYSTEM%\\bin;C:\\%MSYS2_DIR%\\usr\\bin;%PATH%\r\nmake -f mk_mingw.mak -j2\r\n\r\n@echo off\r\ngoto :eof\r\n\r\n:mingw_test\r\n@echo on\r\n:: Check filetype\r\nc:\\cygwin64\\bin\\file ctags.exe\r\nc:\\cygwin64\\bin\\file readtags.exe\r\n:: Check if it works\r\n.\\ctags --version || exit 1\r\n\r\n@echo off\r\ngoto :eof\r\n\r\n:mingw_package\r\n:: Do nothing.\r\ngoto :eof\r\n\r\n\r\n:cygwin_build\r\n:: ----------------------------------------------------------------------\r\n:: Using Cygwin, iconv enabled\r\n@echo on\r\nc:\\cygwin64\\setup-x86_64.exe -qnNdO -P dos2unix,libiconv-devel,libjansson-devel,libxml2-devel,libyaml-devel,pcre2,perl\r\nPATH c:\\cygwin64\\bin;%PATH%\r\nset CHERE_INVOKING=yes\r\nbash -lc \"./autogen.sh\"\r\nbash -lc \"./configure && make -j2\"\r\n\r\n@echo off\r\ngoto :eof\r\n\r\n:cygwin_test\r\n@echo on\r\n:: Check filetype\r\nc:\\cygwin64\\bin\\file ctags.exe\r\nc:\\cygwin64\\bin\\file readtags.exe\r\n:: Check if it works\r\n.\\ctags --version || exit 1\r\n:: Run tests\r\nbash -lc \"make check PYTHON=py\"\r\n\r\n@echo off\r\ngoto :eof\r\n\r\n:cygwin_package\r\n:: Do nothing.\r\ngoto :eof\r\n"
  },
  {
    "path": "win32/config_mingw.h",
    "content": "/* config.h.  Generated from config.h.in by configure.  */\n/* config.h.in.  Generated from configure.ac by autoheader.  */\n\n/* Define if building universal (internal helper macro) */\n/* #undef AC_APPLE_UNIVERSAL_BUILD */\n\n/* Define to the number of bits in type 'ptrdiff_t'. */\n/* #undef BITSIZEOF_PTRDIFF_T */\n\n/* Define to the number of bits in type 'sig_atomic_t'. */\n/* #undef BITSIZEOF_SIG_ATOMIC_T */\n\n/* Define to the number of bits in type 'size_t'. */\n/* #undef BITSIZEOF_SIZE_T */\n\n/* Define to the number of bits in type 'wchar_t'. */\n/* #undef BITSIZEOF_WCHAR_T */\n\n/* Define to the number of bits in type 'wint_t'. */\n/* #undef BITSIZEOF_WINT_T */\n\n/* Define this label if your system uses case-insensitive file names */\n#define CASE_INSENSITIVE_FILENAMES 1\n\n/* You can define this label to be a string containing the name of a\n   site-specific configuration file containing site-wide default options. The\n   files /etc/ctags.conf and /usr/local/etc/ctags.conf are already checked, so\n   only define one here if you need a file somewhere else. */\n/* #undef CUSTOM_CONFIGURATION_FILE */\n\n\n/* Define this as desired.\n * 1:  Original ctags format\n * 2:  Extended ctags format with extension flags in EX-style comment.\n */\n#define DEFAULT_FILE_FORMAT 2\n\n\n/* Define to 1 if gcov is instrumented. */\n/* #undef ENABLE_GCOV */\n\n/* Define the string to check (in executable name) for etags mode */\n#define ETAGS \"etags\"\n\n\n/* Define this label to use the system sort utility (which is probably more\n*  efficient) over the internal sorting algorithm.\n*/\n#ifndef INTERNAL_SORT\n/* # undef EXTERNAL_SORT */\n#endif\n\n\n/* Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string. */\n/* #undef FUNC_NL_LANGINFO_YESEXPR_WORKS */\n\n/* Define to a C preprocessor expression that evaluates to 1 or 0, depending\n   whether the gnulib module lock shall be considered present. */\n/* !!!#define GNULIB_LOCK 1 */\n\n/* Define to 1 when the gnulib module btowc should be tested. */\n#define GNULIB_TEST_BTOWC 1\n\n/* Define to 1 when the gnulib module localeconv should be tested. */\n#define GNULIB_TEST_LOCALECONV 1\n\n/* Define to 1 when the gnulib module mbrtowc should be tested. */\n#define GNULIB_TEST_MBRTOWC 1\n\n/* Define to 1 when the gnulib module mbsinit should be tested. */\n#define GNULIB_TEST_MBSINIT 1\n\n/* Define to 1 when the gnulib module mbtowc should be tested. */\n#define GNULIB_TEST_MBTOWC 1\n\n/* Define to 1 when the gnulib module nl_langinfo should be tested. */\n#define GNULIB_TEST_NL_LANGINFO 1\n\n/* Define to 1 when the gnulib module setlocale_null should be tested. */\n#define GNULIB_TEST_SETLOCALE_NULL 1\n\n/* Define to 1 when the gnulib module wcrtomb should be tested. */\n#define GNULIB_TEST_WCRTOMB 1\n\n/* Define to 1 if you have the `asprintf' function. */\n#define HAVE_ASPRINTF 1\n\n/* Define to 1 if you have the `btowc' function. */\n#define HAVE_BTOWC 1\n\n/* Define to 1 if you have the `chmod' function. */\n/* #undef HAVE_CHMOD */\n\n/* Define to 1 if you have the `chsize' function. */\n/* #undef HAVE_CHSIZE */\n\n/* Define to 1 if you have the <crtdefs.h> header file. */\n/* !!!#define HAVE_CRTDEFS_H 1 */\n\n/* Define to 1 if you have the declaration of `alarm', and to 0 if you don't.\n   */\n#define HAVE_DECL_ALARM 0\n\n/* Define to 1 if you have the declaration of `ecvt', and to 0 if you don't.\n   */\n#define HAVE_DECL_ECVT 1\n\n/* Define to 1 if you have the declaration of `execvpe', and to 0 if you\n   don't. */\n#define HAVE_DECL_EXECVPE 1\n\n/* Define to 1 if you have the declaration of `fcvt', and to 0 if you don't.\n   */\n#define HAVE_DECL_FCVT 1\n\n/* Define to 1 if you have the declaration of `gcvt', and to 0 if you don't.\n   */\n#define HAVE_DECL_GCVT 1\n\n/* Define to 1 if you have the declaration of `isblank', and to 0 if you\n   don't. */\n#define HAVE_DECL_ISBLANK 1\n\n/* Define to 1 if you have the declaration of `mbrtowc', and to 0 if you\n   don't. */\n/* #undef HAVE_DECL_MBRTOWC */\n\n/* Define to 1 if you have the declaration of `mbsinit', and to 0 if you\n   don't. */\n/* #undef HAVE_DECL_MBSINIT */\n\n/* Define to 1 if you have the declaration of `strnlen', and to 0 if you\n   don't. */\n#define HAVE_DECL_STRNLEN 1\n\n/* Define to 1 if you have the declaration of `towlower', and to 0 if you\n   don't. */\n/* #undef HAVE_DECL_TOWLOWER */\n\n/* Define to 1 if you have the declaration of `wcrtomb', and to 0 if you\n   don't. */\n/* #undef HAVE_DECL_WCRTOMB */\n\n/* Define to 1 if you have the declaration of `wcsdup', and to 0 if you don't.\n   */\n#define HAVE_DECL_WCSDUP 1\n\n/* Define to 1 if you have the declaration of `_NSGetEnviron', and to 0 if you\n   don't. */\n#define HAVE_DECL__NSGETENVIRON 0\n\n/* Define to 1 if you have the declaration of `__environ', and to 0 if you\n   don't. */\n#define HAVE_DECL___ENVIRON 0\n\n/* Define to 1 if you have the <direct.h> header file. */\n#define HAVE_DIRECT_H 1\n\n/* Define to 1 if you have the <dirent.h> header file. */\n#define HAVE_DIRENT_H 1\n\n/* Define to 1 if you have the <fcntl.h> header file. */\n#define HAVE_FCNTL_H 1\n\n/* Define to 1 if you have the <features.h> header file. */\n/* #undef HAVE_FEATURES_H */\n\n/* Define to 1 if you have the `findfirst' function. */\n/* #undef HAVE_FINDFIRST */\n\n/* Define to 1 if you have the `fnmatch' function. */\n#define HAVE_FNMATCH 1\n\n/* Define to 1 if you have the <fnmatch.h> header file. */\n/* #undef HAVE_FNMATCH_H */\n\n/* Define to 1 if you have the `ftruncate' function. */\n/* #undef HAVE_FTRUNCATE */\n\n/* Define this value if support multibyte character encoding. */\n/* !!!#define HAVE_ICONV 1 */\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n#define HAVE_INTTYPES_H 1\n\n/* Define to 1 if you have the <io.h> header file. */\n#define HAVE_IO_H 1\n\n/* Define to 1 if you have the `isblank' function. */\n#define HAVE_ISBLANK 1\n\n/* Define to 1 if you have the `iswcntrl' function. */\n#define HAVE_ISWCNTRL 1\n\n/* Define to 1 if you have the `iswctype' function. */\n#define HAVE_ISWCTYPE 1\n\n/* Define this value if jansson is available. */\n/* !!!#define HAVE_JANSSON 1 */\n\n/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */\n/* #undef HAVE_LANGINFO_CODESET */\n\n/* Define to 1 if you have the <langinfo.h> header file. */\n/* #undef HAVE_LANGINFO_H */\n\n/* Define to 1 if you have the <libintl.h> header file. */\n#define HAVE_LIBINTL_H 1\n\n/* Define this value if libxml is available. */\n/* !!!#define HAVE_LIBXML 1 */\n\n/* Define this value if libyaml is available. */\n/* !!!#define HAVE_LIBYAML 1 */\n\n/* Define to 1 if you have the <limits.h> header file. */\n#define HAVE_LIMITS_H 1\n\n/* Define to 1 if the system has the type 'long long int'. */\n#define HAVE_LONG_LONG_INT 1\n\n/* Define to 1 if you have the <malloc.h> header file. */\n#define HAVE_MALLOC_H 1\n\n/* Define to 1 if you have the `mblen' function. */\n#define HAVE_MBLEN 1\n\n/* Define to 1 if you have the `mbrtowc' function. */\n#define HAVE_MBRTOWC 1\n\n/* Define to 1 if you have the `mbsinit' function. */\n#define HAVE_MBSINIT 1\n\n/* Define to 1 if <wchar.h> declares mbstate_t. */\n#define HAVE_MBSTATE_T 1\n\n/* Define to 1 if you have the `mbtowc' function. */\n#define HAVE_MBTOWC 1\n\n/* Define to 1 if you have the <memory.h> header file. */\n#define HAVE_MEMORY_H 1\n\n/* Define to 1 if you have the <minix/config.h> header file. */\n/* #undef HAVE_MINIX_CONFIG_H */\n\n/* Define to 1 if you have the `mkstemp' function. */\n#define HAVE_MKSTEMP 1\n\n/* Define to 1 if you have the `nl_langinfo' function. */\n/* #undef HAVE_NL_LANGINFO */\n\n/* Define to 1 if you have the `opendir' function. */\n#define HAVE_OPENDIR 1\n\n/* Define if you have the <pthread.h> header and the POSIX threads API. */\n#define HAVE_PTHREAD_API 1\n\n/* Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE. */\n#define HAVE_PTHREAD_MUTEX_RECURSIVE 1\n\n/* Define if the POSIX multithreading library has read/write locks. */\n#define HAVE_PTHREAD_RWLOCK 1\n\n/* Define if the 'pthread_rwlock_rdlock' function prefers a writer to a\n   reader. */\n#define HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER 1\n\n/* Define to 1 if you have the `putenv' function. */\n#define HAVE_PUTENV 1\n\n/* Define to 1 if you have the `scandir' function. */\n/* #undef HAVE_SCANDIR */\n\n/* Define this value if libseccomp is available. */\n/* #undef HAVE_SECCOMP */\n\n/* Define to 1 if you have the `setenv' function. */\n/* #undef HAVE_SETENV */\n\n/* Define to 1 if 'sig_atomic_t' is a signed integer type. */\n/* #undef HAVE_SIGNED_SIG_ATOMIC_T */\n\n/* Define to 1 if 'wchar_t' is a signed integer type. */\n/* #undef HAVE_SIGNED_WCHAR_T */\n\n/* Define to 1 if 'wint_t' is a signed integer type. */\n/* #undef HAVE_SIGNED_WINT_T */\n\n/* Define this macro if compiler supports statement expression non-standard C\n   feature. */\n#define HAVE_STATEMENT_EXPRESSION_EXT 1\n\n/* Define to 1 if you have the <stat.h> header file. */\n/* #undef HAVE_STAT_H */\n\n/* Define this macro if the field \"st_ino\" exists in struct stat in\n   <sys/stat.h>. */\n/* #undef HAVE_STAT_ST_INO */\n\n/* Define to 1 if you have the <stdbool.h> header file. */\n#define HAVE_STDBOOL_H 1\n\n/* Define to 1 if you have the <stdint.h> header file. */\n#define HAVE_STDINT_H 1\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#define HAVE_STDLIB_H 1\n\n/* Define to 1 if you have the `strcasecmp' function. */\n#define HAVE_STRCASECMP 1\n\n/* Define to 1 if you have the `strerror' function. */\n#define HAVE_STRERROR 1\n\n/* Define to 1 if you have the `stricmp' function. */\n/* #undef HAVE_STRICMP */\n\n/* Define to 1 if you have the <strings.h> header file. */\n#define HAVE_STRINGS_H 1\n\n/* Define to 1 if you have the <string.h> header file. */\n#define HAVE_STRING_H 1\n\n/* Define to 1 if you have the `strncasecmp' function. */\n#define HAVE_STRNCASECMP 1\n\n/* Define to 1 if you have the `strnicmp' function. */\n/* #undef HAVE_STRNICMP */\n\n/* Define to 1 if you have the `strstr' function. */\n#define HAVE_STRSTR 1\n\n/* Define to 1 if `decimal_point' is a member of `struct lconv'. */\n#define HAVE_STRUCT_LCONV_DECIMAL_POINT 1\n\n/* Define to 1 if you have the <sys/bitypes.h> header file. */\n/* #undef HAVE_SYS_BITYPES_H */\n\n/* Define to 1 if you have the <sys/dir.h> header file. */\n/* #undef HAVE_SYS_DIR_H */\n\n/* Define to 1 if you have the <sys/inttypes.h> header file. */\n/* #undef HAVE_SYS_INTTYPES_H */\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n#define HAVE_SYS_STAT_H 1\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#define HAVE_SYS_TYPES_H 1\n\n/* Define to 1 if you have the <sys/wait.h> header file. */\n/* #undef HAVE_SYS_WAIT_H */\n\n/* Define to 1 if you have the `tempnam' function. */\n/* #undef HAVE_TEMPNAM */\n\n/* Define to 1 if you have the `thrd_create' function. */\n/* #undef HAVE_THRD_CREATE */\n\n/* Define to 1 if you have the <threads.h> header file. */\n/* #undef HAVE_THREADS_H */\n\n/* Define to 1 if you have the `towlower' function. */\n/* #undef HAVE_TOWLOWER */\n\n/* Define to 1 if you have the `truncate' function. */\n/* !!!#define HAVE_TRUNCATE 1 */\n\n/* Define to 1 if typeof works with your compiler. */\n#define HAVE_TYPEOF 1\n\n/* Define to 1 if you have the <types.h> header file. */\n/* #undef HAVE_TYPES_H */\n\n/* Define to 1 if you have the <unistd.h> header file. */\n#define HAVE_UNISTD_H 1\n\n/* Define to 1 if the system has the type 'unsigned long long int'. */\n#define HAVE_UNSIGNED_LONG_LONG_INT 1\n\n/* Define to 1 or 0, depending whether the compiler supports simple visibility\n   declarations. */\n/* #undef HAVE_VISIBILITY */\n\n/* Define to 1 if you have the <wchar.h> header file. */\n#define HAVE_WCHAR_H 1\n\n/* Define if you have the 'wchar_t' type. */\n#define HAVE_WCHAR_T 1\n\n/* Define to 1 if you have the `wcrtomb' function. */\n#define HAVE_WCRTOMB 1\n\n/* Define to 1 if you have the <wctype.h> header file. */\n#define HAVE_WCTYPE_H 1\n\n/* Define to 1 if the compiler and linker support weak declarations of\n   symbols. */\n/* #undef HAVE_WEAK_SYMBOLS */\n\n/* Define if you have the 'wint_t' type. */\n#define HAVE_WINT_T 1\n\n/* Define to 1 if you have the <xlocale.h> header file. */\n/* #undef HAVE_XLOCALE_H */\n\n/* Define to 1 if the system has the type `_Bool'. */\n#define HAVE__BOOL 1\n\n/* Define to 1 if you have the `_findfirst' function. */\n/* #undef HAVE__FINDFIRST */\n\n/* Define to 1 if the compiler supports __builtin_expect,\n   and to 2 if <builtins.h> does.  */\n#define HAVE___BUILTIN_EXPECT 1\n#ifndef HAVE___BUILTIN_EXPECT\n# define __builtin_expect(e, c) (e)\n#elif HAVE___BUILTIN_EXPECT == 2\n# include <builtins.h>\n#endif\n\n\n/* Define to 1 if the compiler supports the keyword '__inline'. */\n#define HAVE___INLINE 1\n\n/* Define this value if the platform uses \"lib\" as prefix for iconv functions.\n   */\n/* #undef ICONV_USE_LIB_PREFIX */\n\n/* Define as the maximum integer on your system if not defined <limits.h>. */\n/* #undef INT_MAX */\n\n/* Define to the appropriate size for tmpnam() if <stdio.h> does not define\n   this. */\n/* #undef L_tmpnam */\n\n/* Define this label if you want macro tags (defined lables) to use patterns\n   in the EX command by default (original ctags behavior is to use line\n   numbers). */\n/* #undef MACROS_USE_PATTERNS */\n\n/* If malloc(0) is != NULL, define this to 1. Otherwise define this to 0. */\n#define MALLOC_0_IS_NONNULL 1\n\n/* Define if the mbrtowc function does not return (size_t) -2 for empty input.\n   */\n/* #undef MBRTOWC_EMPTY_INPUT_BUG */\n\n/* Define if the mbrtowc function may signal encoding errors in the C locale.\n   */\n/* #undef MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ */\n\n/* Define if the mbrtowc function has the NULL pwc argument bug. */\n/* #undef MBRTOWC_NULL_ARG1_BUG */\n\n/* Define if the mbrtowc function has the NULL string argument bug. */\n/* #undef MBRTOWC_NULL_ARG2_BUG */\n\n/* Define if the mbrtowc function does not return 0 for a NUL character. */\n/* #undef MBRTOWC_NUL_RETVAL_BUG */\n\n/* Define if the mbrtowc function returns a wrong return value. */\n#define MBRTOWC_RETVAL_BUG 1\n\n/* Define if the mbrtowc function stores a wide character when reporting\n   incomplete input. */\n/* #undef MBRTOWC_STORES_INCOMPLETE_BUG */\n\n/* Define to 1 if your system uses MS-DOS style path. */\n#define MSDOS_STYLE_PATH 1\n\n/* If you receive error or warning messages indicating that you are missing a\n   prototype for, or a type mismatch using, the following function, define\n   this label and remake. */\n/* #undef NEED_PROTO_FTRUNCATE */\n\n/* If you receive error or warning messages indicating that you are missing a\n   prototype for, or a type mismatch using, the following function, define\n   this label and remake. */\n#define NEED_PROTO_LSTAT 1\n\n/* If you receive error or warning messages indicating that you are missing a\n   prototype for, or a type mismatch using, the following function, define\n   this label and remake. */\n/* #undef NEED_PROTO_STAT */\n\n/* If you receive error or warning messages indicating that you are missing a\n   prototype for, or a type mismatch using, the following function, define\n   this label and remake. */\n/* #undef NEED_PROTO_TRUNCATE */\n\n/* Define to 1 if nl_langinfo is multithread-safe. */\n/* #undef NL_LANGINFO_MTSAFE */\n\n/* Define this is you have a prototype for putenv() in <stdlib.h>, but doesn't\n   declare its argument as \"const char *\". */\n#define NON_CONST_PUTENV_PROTOTYPE 1\n\n/* Package name. */\n#define PACKAGE \"universal-ctags\"\n\n/* Define to the address where bug reports for this package should be sent. */\n#define PACKAGE_BUGREPORT \"\"\n\n/* Define to the full name of this package. */\n#define PACKAGE_NAME \"universal-ctags\"\n\n/* Define to the full name and version of this package. */\n#define PACKAGE_STRING \"universal-ctags 6.2.0\"\n\n/* Define to the one symbol short name of this package. */\n#define PACKAGE_TARNAME \"universal-ctags\"\n\n/* Define to the home page for this package. */\n#define PACKAGE_URL \"\"\n\n/* Define to the version of this package. */\n#define PACKAGE_VERSION \"6.2.0\"\n\n/* Define if the pthread_in_use() detection is hard. */\n/* #undef PTHREAD_IN_USE_DETECTION_HARD */\n\n/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type\n   'ptrdiff_t'. */\n/* #undef PTRDIFF_T_SUFFIX */\n\n/* Define if nl_langinfo exists but is overridden by gnulib. */\n/* #undef REPLACE_NL_LANGINFO */\n\n/* Define to 1 if setlocale (LC_ALL, NULL) is multithread-safe. */\n#define SETLOCALE_NULL_ALL_MTSAFE 1\n\n/* Define to 1 if setlocale (category, NULL) is multithread-safe. */\n#define SETLOCALE_NULL_ONE_MTSAFE 1\n\n/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type\n   'sig_atomic_t'. */\n/* #undef SIG_ATOMIC_T_SUFFIX */\n\n/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type\n   'size_t'. */\n/* #undef SIZE_T_SUFFIX */\n\n/* Define to 1 if you have the ANSI C header files. */\n#define STDC_HEADERS 1\n\n/* If you wish to change the directory in which temporary files are stored,\n   define this label to the directory desired. */\n#define TMPDIR \"/tmp\"\n\n/* Define to 1 when using fnmatch implementation in bundled gnulib. */\n#define USE_GNULIB_FNMATCH\n\n/* Define if the combination of the ISO C and POSIX multithreading APIs can be\n   used. */\n/* #undef USE_ISOC_AND_POSIX_THREADS */\n\n/* Define if the ISO C multithreading library can be used. */\n/* #undef USE_ISOC_THREADS */\n\n/* Define if the POSIX multithreading library can be used. */\n#define USE_POSIX_THREADS 1\n\n/* Define if references to the POSIX multithreading library should be made\n   weak. */\n/* #undef USE_POSIX_THREADS_WEAK */\n\n/* Enable extensions on AIX 3, Interix.  */\n#ifndef _ALL_SOURCE\n# define _ALL_SOURCE 1\n#endif\n/* Enable general extensions on macOS.  */\n#ifndef _DARWIN_C_SOURCE\n# define _DARWIN_C_SOURCE 1\n#endif\n/* Enable general extensions on Solaris.  */\n#ifndef __EXTENSIONS__\n# define __EXTENSIONS__ 1\n#endif\n/* Enable GNU extensions on systems that have them.  */\n#ifndef _GNU_SOURCE\n# define _GNU_SOURCE 1\n#endif\n/* Enable X/Open compliant socket functions that do not require linking\n   with -lxnet on HP-UX 11.11.  */\n#ifndef _HPUX_ALT_XOPEN_SOCKET_API\n# define _HPUX_ALT_XOPEN_SOCKET_API 1\n#endif\n/* Identify the host operating system as Minix.\n   This macro does not affect the system headers' behavior.\n   A future release of Autoconf may stop defining this macro.  */\n#ifndef _MINIX\n/* # undef _MINIX */\n#endif\n/* Enable general extensions on NetBSD.\n   Enable NetBSD compatibility extensions on Minix.  */\n#ifndef _NETBSD_SOURCE\n# define _NETBSD_SOURCE 1\n#endif\n/* Enable OpenBSD compatibility extensions on NetBSD.\n   Oddly enough, this does nothing on OpenBSD.  */\n#ifndef _OPENBSD_SOURCE\n# define _OPENBSD_SOURCE 1\n#endif\n/* Define to 1 if needed for POSIX-compatible behavior.  */\n#ifndef _POSIX_SOURCE\n/* # undef _POSIX_SOURCE */\n#endif\n/* Define to 2 if needed for POSIX-compatible behavior.  */\n#ifndef _POSIX_1_SOURCE\n/* # undef _POSIX_1_SOURCE */\n#endif\n/* Enable POSIX-compatible threading on Solaris.  */\n#ifndef _POSIX_PTHREAD_SEMANTICS\n# define _POSIX_PTHREAD_SEMANTICS 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-5:2014.  */\n#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__\n# define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-1:2014.  */\n#ifndef __STDC_WANT_IEC_60559_BFP_EXT__\n# define __STDC_WANT_IEC_60559_BFP_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-2:2015.  */\n#ifndef __STDC_WANT_IEC_60559_DFP_EXT__\n# define __STDC_WANT_IEC_60559_DFP_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-4:2015.  */\n#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__\n# define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-3:2015.  */\n#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__\n# define __STDC_WANT_IEC_60559_TYPES_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TR 24731-2:2010.  */\n#ifndef __STDC_WANT_LIB_EXT2__\n# define __STDC_WANT_LIB_EXT2__ 1\n#endif\n/* Enable extensions specified by ISO/IEC 24747:2009.  */\n#ifndef __STDC_WANT_MATH_SPEC_FUNCS__\n# define __STDC_WANT_MATH_SPEC_FUNCS__ 1\n#endif\n/* Enable extensions on HP NonStop.  */\n#ifndef _TANDEM_SOURCE\n# define _TANDEM_SOURCE 1\n#endif\n/* Enable X/Open extensions.  Define to 500 only if necessary\n   to make mbstate_t available.  */\n#ifndef _XOPEN_SOURCE\n/* # undef _XOPEN_SOURCE */\n#endif\n\n\n/* Define if the native Windows multithreading API can be used. */\n/* #undef USE_WINDOWS_THREADS */\n\n/* Package version. */\n#define VERSION \"6.2.0\"\n\n/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type\n   'wchar_t'. */\n/* #undef WCHAR_T_SUFFIX */\n\n/* Define if the wcrtomb function does not work in the C locale. */\n/* #undef WCRTOMB_C_LOCALE_BUG */\n\n/* Define if the wcrtomb function has an incorrect return value. */\n/* #undef WCRTOMB_RETVAL_BUG */\n\n/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type\n   'wint_t'. */\n/* #undef WINT_T_SUFFIX */\n\n/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most\n   significant byte first (like Motorola and SPARC, unlike Intel). */\n#if defined AC_APPLE_UNIVERSAL_BUILD\n# if defined __BIG_ENDIAN__\n#  define WORDS_BIGENDIAN 1\n# endif\n#else\n# ifndef WORDS_BIGENDIAN\n/* #  undef WORDS_BIGENDIAN */\n# endif\n#endif\n\n/* Enable large inode numbers on Mac OS X 10.5.  */\n#ifndef _DARWIN_USE_64_BIT_INODE\n# define _DARWIN_USE_64_BIT_INODE 1\n#endif\n\n/* Number of bits in a file offset, on hosts where this is settable. */\n#define _FILE_OFFSET_BITS 64\n\n/* True if the compiler says it groks GNU C version MAJOR.MINOR.  */\n#if defined __GNUC__ && defined __GNUC_MINOR__\n# define _GL_GNUC_PREREQ(major, minor) \\\n    ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__))\n#else\n# define _GL_GNUC_PREREQ(major, minor) 0\n#endif\n\n\n/* Define to enable the declarations of ISO C 11 types and functions. */\n/* #undef _ISOC11_SOURCE */\n\n/* Define for large files, on AIX-style hosts. */\n/* #undef _LARGE_FILES */\n\n/* Define to 1 on Solaris. */\n/* #undef _LCONV_C99 */\n\n/* The _Noreturn keyword of C11.  */\n#ifndef _Noreturn\n# if (defined __cplusplus \\\n      && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \\\n          || (defined _MSC_VER && 1900 <= _MSC_VER)) \\\n      && 0)\n    /* [[noreturn]] is not practically usable, because with it the syntax\n         extern _Noreturn void func (...);\n       would not be valid; such a declaration would only be valid with 'extern'\n       and '_Noreturn' swapped, or without the 'extern' keyword.  However, some\n       AIX system header files and several gnulib header files use precisely\n       this syntax with 'extern'.  */\n#  define _Noreturn [[noreturn]]\n# elif ((!defined __cplusplus || defined __clang__) \\\n        && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \\\n            || (!defined __STRICT_ANSI__ \\\n                && (_GL_GNUC_PREREQ (4, 7) \\\n                    || (defined __apple_build_version__ \\\n                        ? 6000000 <= __apple_build_version__ \\\n                        : 3 < __clang_major__ + (5 <= __clang_minor__))))))\n   /* _Noreturn works as-is.  */\n# elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C\n#  define _Noreturn __attribute__ ((__noreturn__))\n# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)\n#  define _Noreturn __declspec (noreturn)\n# else\n#  define _Noreturn\n# endif\n#endif\n\n\n/* Define if you want <regex.h> to include <limits.h>, so that it consistently\n   overrides <limits.h>'s RE_DUP_MAX. */\n#define _REGEX_INCLUDE_LIMITS_H 1\n\n/* Define if you want regoff_t to be at least as wide POSIX requires. */\n#define _REGEX_LARGE_OFFSETS 1\n\n/* For standard stat data types on VMS. */\n#define _USE_STD_STAT 1\n\n/* Define to 1 if the system <stdint.h> predates C++11. */\n/* #undef __STDC_CONSTANT_MACROS */\n\n/* Define to 1 if the system <stdint.h> predates C++11. */\n/* #undef __STDC_LIMIT_MACROS */\n\n/* The _GL_ASYNC_SAFE marker should be attached to functions that are\n   signal handlers (for signals other than SIGABRT, SIGPIPE) or can be\n   invoked from such signal handlers.  Such functions have some restrictions:\n     * All functions that it calls should be marked _GL_ASYNC_SAFE as well,\n       or should be listed as async-signal-safe in POSIX\n       <https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04>\n       section 2.4.3.  Note that malloc(), sprintf(), and fwrite(), in\n       particular, are NOT async-signal-safe.\n     * All memory locations (variables and struct fields) that these functions\n       access must be marked 'volatile'.  This holds for both read and write\n       accesses.  Otherwise the compiler might optimize away stores to and\n       reads from such locations that occur in the program, depending on its\n       data flow analysis.  For example, when the program contains a loop\n       that is intended to inspect a variable set from within a signal handler\n           while (!signal_occurred)\n             ;\n       the compiler is allowed to transform this into an endless loop if the\n       variable 'signal_occurred' is not declared 'volatile'.\n   Additionally, recall that:\n     * A signal handler should not modify errno (except if it is a handler\n       for a fatal signal and ends by raising the same signal again, thus\n       provoking the termination of the process).  If it invokes a function\n       that may clobber errno, it needs to save and restore the value of\n       errno.  */\n#define _GL_ASYNC_SAFE\n\n\n/* Attributes.  */\n#if (defined __has_attribute \\\n     && (!defined __clang_minor__ \\\n         || 3 < __clang_major__ + (5 <= __clang_minor__)))\n# define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__)\n#else\n# define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr\n# define _GL_ATTR_alloc_size _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_always_inline _GL_GNUC_PREREQ (3, 2)\n# define _GL_ATTR_artificial _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_cold _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_const _GL_GNUC_PREREQ (2, 95)\n# define _GL_ATTR_deprecated _GL_GNUC_PREREQ (3, 1)\n# define _GL_ATTR_diagnose_if 0\n# define _GL_ATTR_error _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_externally_visible _GL_GNUC_PREREQ (4, 1)\n# define _GL_ATTR_fallthrough _GL_GNUC_PREREQ (7, 0)\n# define _GL_ATTR_format _GL_GNUC_PREREQ (2, 7)\n# define _GL_ATTR_leaf _GL_GNUC_PREREQ (4, 6)\n# ifdef _ICC\n#  define _GL_ATTR_may_alias 0\n# else\n#  define _GL_ATTR_may_alias _GL_GNUC_PREREQ (3, 3)\n# endif\n# define _GL_ATTR_malloc _GL_GNUC_PREREQ (3, 0)\n# define _GL_ATTR_noinline _GL_GNUC_PREREQ (3, 1)\n# define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3)\n# define _GL_ATTR_nonstring _GL_GNUC_PREREQ (8, 0)\n# define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3)\n# define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7)\n# define _GL_ATTR_pure _GL_GNUC_PREREQ (2, 96)\n# define _GL_ATTR_returns_nonnull _GL_GNUC_PREREQ (4, 9)\n# define _GL_ATTR_sentinel _GL_GNUC_PREREQ (4, 0)\n# define _GL_ATTR_unused _GL_GNUC_PREREQ (2, 7)\n# define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4)\n#endif\n\n\n#if _GL_HAS_ATTRIBUTE (alloc_size)\n# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))\n#else\n# define _GL_ATTRIBUTE_ALLOC_SIZE(args)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (always_inline)\n# define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))\n#else\n# define _GL_ATTRIBUTE_ALWAYS_INLINE\n#endif\n\n#if _GL_HAS_ATTRIBUTE (artificial)\n# define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__))\n#else\n# define _GL_ATTRIBUTE_ARTIFICIAL\n#endif\n\n/* Avoid __attribute__ ((cold)) on MinGW; see thread starting at\n   <https://lists.gnu.org/r/emacs-devel/2019-04/msg01152.html>.\n   Also, Oracle Studio 12.6 requires 'cold' not '__cold__'.  */\n#if _GL_HAS_ATTRIBUTE (cold) && !defined __MINGW32__\n# ifndef __SUNPRO_C\n#  define _GL_ATTRIBUTE_COLD __attribute__ ((__cold__))\n# else\n#  define _GL_ATTRIBUTE_COLD __attribute__ ((cold))\n# endif\n#else\n# define _GL_ATTRIBUTE_COLD\n#endif\n\n#if _GL_HAS_ATTRIBUTE (const)\n# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__))\n#else\n# define _GL_ATTRIBUTE_CONST\n#endif\n\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_DEPRECATED [[__deprecated__]]\n#elif _GL_HAS_ATTRIBUTE (deprecated)\n# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__))\n#else\n# define _GL_ATTRIBUTE_DEPRECATED\n#endif\n\n#if _GL_HAS_ATTRIBUTE (error)\n# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg)))\n# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg)))\n#elif _GL_HAS_ATTRIBUTE (diagnose_if)\n# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__diagnose_if__ (1, msg, \"error\")))\n# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__diagnose_if__ (1, msg, \"warning\")))\n#else\n# define _GL_ATTRIBUTE_ERROR(msg)\n# define _GL_ATTRIBUTE_WARNING(msg)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (externally_visible)\n# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE __attribute__ ((externally_visible))\n#else\n# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE\n#endif\n\n/* FALLTHROUGH is special, because it always expands to something.  */\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_FALLTHROUGH [[__fallthrough__]]\n#elif _GL_HAS_ATTRIBUTE (fallthrough)\n# define _GL_ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))\n#else\n# define _GL_ATTRIBUTE_FALLTHROUGH ((void) 0)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (format)\n# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))\n#else\n# define _GL_ATTRIBUTE_FORMAT(spec)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (leaf)\n# define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__))\n#else\n# define _GL_ATTRIBUTE_LEAF\n#endif\n\n/* Oracle Studio 12.6 mishandles may_alias despite __has_attribute OK.  */\n#if _GL_HAS_ATTRIBUTE (may_alias) && !defined __SUNPRO_C\n# define _GL_ATTRIBUTE_MAY_ALIAS __attribute__ ((__may_alias__))\n#else\n# define _GL_ATTRIBUTE_MAY_ALIAS\n#endif\n\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_MAYBE_UNUSED [[__maybe_unused__]]\n#elif _GL_HAS_ATTRIBUTE (unused)\n# define _GL_ATTRIBUTE_MAYBE_UNUSED __attribute__ ((__unused__))\n#else\n# define _GL_ATTRIBUTE_MAYBE_UNUSED\n#endif\n/* Earlier spellings of this macro.  */\n#define _GL_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED\n#define _UNUSED_PARAMETER_ _GL_ATTRIBUTE_MAYBE_UNUSED\n\n#if _GL_HAS_ATTRIBUTE (malloc)\n# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))\n#else\n# define _GL_ATTRIBUTE_MALLOC\n#endif\n\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_NODISCARD [[__nodiscard__]]\n#elif _GL_HAS_ATTRIBUTE (warn_unused_result)\n# define _GL_ATTRIBUTE_NODISCARD __attribute__ ((__warn_unused_result__))\n#else\n# define _GL_ATTRIBUTE_NODISCARD\n#endif\n\n#if _GL_HAS_ATTRIBUTE (noinline)\n# define _GL_ATTRIBUTE_NOINLINE __attribute__ ((__noinline__))\n#else\n# define _GL_ATTRIBUTE_NOINLINE\n#endif\n\n#if _GL_HAS_ATTRIBUTE (nonnull)\n# define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args))\n#else\n# define _GL_ATTRIBUTE_NONNULL(args)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (nonstring)\n# define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__))\n#else\n# define _GL_ATTRIBUTE_NONSTRING\n#endif\n\n/* There is no _GL_ATTRIBUTE_NORETURN; use _Noreturn instead.  */\n\n#if _GL_HAS_ATTRIBUTE (nothrow) && !defined __cplusplus\n# define _GL_ATTRIBUTE_NOTHROW __attribute__ ((__nothrow__))\n#else\n# define _GL_ATTRIBUTE_NOTHROW\n#endif\n\n#if _GL_HAS_ATTRIBUTE (packed)\n# define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__))\n#else\n# define _GL_ATTRIBUTE_PACKED\n#endif\n\n#if _GL_HAS_ATTRIBUTE (pure)\n# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))\n#else\n# define _GL_ATTRIBUTE_PURE\n#endif\n\n#if _GL_HAS_ATTRIBUTE (returns_nonnull)\n# define _GL_ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__))\n#else\n# define _GL_ATTRIBUTE_RETURNS_NONNULL\n#endif\n\n#if _GL_HAS_ATTRIBUTE (sentinel)\n# define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos))\n#else\n# define _GL_ATTRIBUTE_SENTINEL(pos)\n#endif\n\n\n/* To support C++ as well as C, use _GL_UNUSED_LABEL with trailing ';'.  */\n#if !defined __cplusplus || _GL_GNUC_PREREQ (4, 5)\n# define _GL_UNUSED_LABEL _GL_ATTRIBUTE_MAYBE_UNUSED\n#else\n# define _GL_UNUSED_LABEL\n#endif\n\n\n/* Define to the appropriate type if <time.h> does not define this. */\n/* #undef clock_t */\n\n/* Define to empty if `const' does not conform to ANSI C. */\n/* #undef const */\n\n/* Please see the Gnulib manual for how to use these macros.\n\n   Suppress extern inline with HP-UX cc, as it appears to be broken; see\n   <https://lists.gnu.org/r/bug-texinfo/2013-02/msg00030.html>.\n\n   Suppress extern inline with Sun C in standards-conformance mode, as it\n   mishandles inline functions that call each other.  E.g., for 'inline void f\n   (void) { } inline void g (void) { f (); }', c99 incorrectly complains\n   'reference to static identifier \"f\" in extern inline function'.\n   This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.\n\n   Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))\n   on configurations that mistakenly use 'static inline' to implement\n   functions or macros in standard C headers like <ctype.h>.  For example,\n   if isdigit is mistakenly implemented via a static inline function,\n   a program containing an extern inline function that calls isdigit\n   may not work since the C standard prohibits extern inline functions\n   from calling static functions (ISO C 99 section 6.7.4.(3).\n   This bug is known to occur on:\n\n     OS X 10.8 and earlier; see:\n     https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html\n\n     DragonFly; see\n     http://muscles.dragonflybsd.org/bulk/clang-master-potential/20141111_102002/logs/ah-tty-0.3.12.log\n\n     FreeBSD; see:\n     https://lists.gnu.org/r/bug-gnulib/2014-07/msg00104.html\n\n   OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and\n   for clang but remains for g++; see <https://trac.macports.org/ticket/41033>.\n   Assume DragonFly and FreeBSD will be similar.\n\n   GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99\n   inline semantics, unless -fgnu89-inline is used.  It defines a macro\n   __GNUC_STDC_INLINE__ to indicate this situation or a macro\n   __GNUC_GNU_INLINE__ to indicate the opposite situation.\n   GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline\n   semantics but warns, unless -fgnu89-inline is used:\n     warning: C99 inline functions are not supported; using GNU89\n     warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute\n   It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.\n */\n#if (((defined __APPLE__ && defined __MACH__) \\\n      || defined __DragonFly__ || defined __FreeBSD__) \\\n     && (defined __header_inline \\\n         ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \\\n            && ! defined __clang__) \\\n         : ((! defined _DONT_USE_CTYPE_INLINE_ \\\n             && (defined __GNUC__ || defined __cplusplus)) \\\n            || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \\\n                && defined __GNUC__ && ! defined __cplusplus))))\n# define _GL_EXTERN_INLINE_STDHEADER_BUG\n#endif\n#if ((__GNUC__ \\\n      ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \\\n      : (199901L <= __STDC_VERSION__ \\\n         && !defined __HP_cc \\\n         && !defined __PGI \\\n         && !(defined __SUNPRO_C && __STDC__))) \\\n     && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)\n# define _GL_INLINE inline\n# define _GL_EXTERN_INLINE extern inline\n# define _GL_EXTERN_INLINE_IN_USE\n#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \\\n       && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)\n# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__\n   /* __gnu_inline__ suppresses a GCC 4.2 diagnostic.  */\n#  define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))\n# else\n#  define _GL_INLINE extern inline\n# endif\n# define _GL_EXTERN_INLINE extern\n# define _GL_EXTERN_INLINE_IN_USE\n#else\n# define _GL_INLINE static _GL_UNUSED\n# define _GL_EXTERN_INLINE static _GL_UNUSED\n#endif\n\n/* In GCC 4.6 (inclusive) to 5.1 (exclusive),\n   suppress bogus \"no previous prototype for 'FOO'\"\n   and \"no previous declaration for 'FOO'\" diagnostics,\n   when FOO is an inline function in the header; see\n   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and\n   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>.  */\n#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__\n# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__\n#  define _GL_INLINE_HEADER_CONST_PRAGMA\n# else\n#  define _GL_INLINE_HEADER_CONST_PRAGMA \\\n     _Pragma (\"GCC diagnostic ignored \\\"-Wsuggest-attribute=const\\\"\")\n# endif\n# define _GL_INLINE_HEADER_BEGIN \\\n    _Pragma (\"GCC diagnostic push\") \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wmissing-prototypes\\\"\") \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wmissing-declarations\\\"\") \\\n    _GL_INLINE_HEADER_CONST_PRAGMA\n# define _GL_INLINE_HEADER_END \\\n    _Pragma (\"GCC diagnostic pop\")\n#else\n# define _GL_INLINE_HEADER_BEGIN\n# define _GL_INLINE_HEADER_END\n#endif\n\n/* Define to long if <stdio.h> does not define this. */\n/* #undef fpos_t */\n\n/* Define to `__inline__' or `__inline' if that's what the C compiler\n   calls it, or to nothing if 'inline' is not supported under any name.  */\n#ifndef __cplusplus\n/* #undef inline */\n#endif\n\n/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports\n   the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of\n   earlier versions), but does not display it by setting __GNUC_STDC_INLINE__.\n   __APPLE__ && __MACH__ test for Mac OS X.\n   __APPLE_CC__ tests for the Apple compiler and its version.\n   __STDC_VERSION__ tests for the C99 mode.  */\n#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__\n# define __GNUC_STDC_INLINE__ 1\n#endif\n\n/* Define to a type if <wchar.h> does not define. */\n/* #undef mbstate_t */\n\n/* _GL_CMP (n1, n2) performs a three-valued comparison on n1 vs. n2, where\n   n1 and n2 are expressions without side effects, that evaluate to real\n   numbers (excluding NaN).\n   It returns\n     1  if n1 > n2\n     0  if n1 == n2\n     -1 if n1 < n2\n   The naïve code   (n1 > n2 ? 1 : n1 < n2 ? -1 : 0)  produces a conditional\n   jump with nearly all GCC versions up to GCC 10.\n   This variant     (n1 < n2 ? -1 : n1 > n2)  produces a conditional with many\n   GCC versions up to GCC 9.\n   The better code  (n1 > n2) - (n1 < n2)  from Hacker's Delight § 2-9\n   avoids conditional jumps in all GCC versions >= 3.4.  */\n#define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2)))\n\n\n/* Define to `int' if <sys/types.h> does not define. */\n/* #undef mode_t */\n\n/* Define to `long int' if <sys/types.h> does not define. */\n/* #undef off_t */\n\n/* Define as a signed integer type capable of holding a process identifier. */\n/* #undef pid_t */\n\n/* Define to rpl_re_comp if the replacement should be used. */\n#define re_comp rpl_re_comp\n\n/* Define to rpl_re_compile_fastmap if the replacement should be used. */\n#define re_compile_fastmap rpl_re_compile_fastmap\n\n/* Define to rpl_re_compile_pattern if the replacement should be used. */\n#define re_compile_pattern rpl_re_compile_pattern\n\n/* Define to rpl_re_exec if the replacement should be used. */\n#define re_exec rpl_re_exec\n\n/* Define to rpl_re_match if the replacement should be used. */\n#define re_match rpl_re_match\n\n/* Define to rpl_re_match_2 if the replacement should be used. */\n#define re_match_2 rpl_re_match_2\n\n/* Define to rpl_re_search if the replacement should be used. */\n#define re_search rpl_re_search\n\n/* Define to rpl_re_search_2 if the replacement should be used. */\n#define re_search_2 rpl_re_search_2\n\n/* Define to rpl_re_set_registers if the replacement should be used. */\n#define re_set_registers rpl_re_set_registers\n\n/* Define to rpl_re_set_syntax if the replacement should be used. */\n#define re_set_syntax rpl_re_set_syntax\n\n/* Define to rpl_re_syntax_options if the replacement should be used. */\n#define re_syntax_options rpl_re_syntax_options\n\n/* Define to rpl_regcomp if the replacement should be used. */\n#define regcomp rpl_regcomp\n\n/* Define to rpl_regerror if the replacement should be used. */\n#define regerror rpl_regerror\n\n/* Define to rpl_regexec if the replacement should be used. */\n#define regexec rpl_regexec\n\n/* Define to rpl_regfree if the replacement should be used. */\n#define regfree rpl_regfree\n\n/* Define remove to unlink if you have unlink(), but not remove(). */\n/* #undef remove */\n\n/* Define to the equivalent of the C99 'restrict' keyword, or to\n   nothing if this is not supported.  Do not define if restrict is\n   supported only directly.  */\n#define restrict __restrict__\n/* Work around a bug in older versions of Sun C++, which did not\n   #define __restrict__ or support _Restrict or __restrict__\n   even though the corresponding Sun C compiler ended up with\n   \"#define restrict _Restrict\" or \"#define restrict __restrict__\"\n   in the previous line.  This workaround can be removed once\n   we assume Oracle Developer Studio 12.5 (2016) or later.  */\n#if defined __SUNPRO_CC && !defined __RESTRICT && !defined __restrict__\n# define _Restrict\n# define __restrict__\n#endif\n\n/* Define as a signed type of the same size as size_t. */\n/* #undef ssize_t */\n\n/* Define to __typeof__ if your compiler spells it that way. */\n/* #undef typeof */\n"
  },
  {
    "path": "win32/config_mvc.h",
    "content": "/* config.h.  Generated from config.h.in by configure.  */\n/* config.h.in.  Generated from configure.ac by autoheader.  */\n\n/* Define if building universal (internal helper macro) */\n/* #undef AC_APPLE_UNIVERSAL_BUILD */\n\n/* Define to the number of bits in type 'ptrdiff_t'. */\n/* #undef BITSIZEOF_PTRDIFF_T */\n\n/* Define to the number of bits in type 'sig_atomic_t'. */\n/* #undef BITSIZEOF_SIG_ATOMIC_T */\n\n/* Define to the number of bits in type 'size_t'. */\n/* #undef BITSIZEOF_SIZE_T */\n\n/* Define to the number of bits in type 'wchar_t'. */\n/* #undef BITSIZEOF_WCHAR_T */\n\n/* Define to the number of bits in type 'wint_t'. */\n/* #undef BITSIZEOF_WINT_T */\n\n/* Define this label if your system uses case-insensitive file names */\n#define CASE_INSENSITIVE_FILENAMES 1\n\n/* You can define this label to be a string containing the name of a\n   site-specific configuration file containing site-wide default options. The\n   files /etc/ctags.conf and /usr/local/etc/ctags.conf are already checked, so\n   only define one here if you need a file somewhere else. */\n/* #undef CUSTOM_CONFIGURATION_FILE */\n\n\n/* Define this as desired.\n * 1:  Original ctags format\n * 2:  Extended ctags format with extension flags in EX-style comment.\n */\n#define DEFAULT_FILE_FORMAT 2\n\n\n/* Define to 1 if gcov is instrumented. */\n/* #undef ENABLE_GCOV */\n\n/* Define the string to check (in executable name) for etags mode */\n#define ETAGS \"etags\"\n\n\n/* Define this label to use the system sort utility (which is probably more\n*  efficient) over the internal sorting algorithm.\n*/\n#ifndef INTERNAL_SORT\n/* # undef EXTERNAL_SORT */\n#endif\n\n\n/* Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string. */\n/* #undef FUNC_NL_LANGINFO_YESEXPR_WORKS */\n\n/* Define to a C preprocessor expression that evaluates to 1 or 0, depending\n   whether the gnulib module lock shall be considered present. */\n#define GNULIB_LOCK 1\n\n/* Define to 1 when the gnulib module btowc should be tested. */\n#define GNULIB_TEST_BTOWC 1\n\n/* Define to 1 when the gnulib module localeconv should be tested. */\n#define GNULIB_TEST_LOCALECONV 1\n\n/* Define to 1 when the gnulib module mbrtowc should be tested. */\n#define GNULIB_TEST_MBRTOWC 1\n\n/* Define to 1 when the gnulib module mbsinit should be tested. */\n#define GNULIB_TEST_MBSINIT 1\n\n/* Define to 1 when the gnulib module mbtowc should be tested. */\n#define GNULIB_TEST_MBTOWC 1\n\n/* Define to 1 when the gnulib module nl_langinfo should be tested. */\n#define GNULIB_TEST_NL_LANGINFO 1\n\n/* Define to 1 when the gnulib module setlocale_null should be tested. */\n#define GNULIB_TEST_SETLOCALE_NULL 1\n\n/* Define to 1 when the gnulib module wcrtomb should be tested. */\n#define GNULIB_TEST_WCRTOMB 1\n\n/* Define to 1 if you have the `asprintf' function. */\n#define HAVE_ASPRINTF 1\n\n/* Define to 1 if you have the `btowc' function. */\n#define HAVE_BTOWC 1\n\n/* Define to 1 if you have the `chmod' function. */\n/* #undef HAVE_CHMOD */\n\n/* Define to 1 if you have the `chsize' function. */\n/* #undef HAVE_CHSIZE */\n\n/* Define to 1 if you have the <crtdefs.h> header file. */\n#define HAVE_CRTDEFS_H 1\n\n/* Define to 1 if you have the declaration of `alarm', and to 0 if you don't.\n   */\n#define HAVE_DECL_ALARM 0\n\n/* Define to 1 if you have the declaration of `ecvt', and to 0 if you don't.\n   */\n#define HAVE_DECL_ECVT 1\n\n/* Define to 1 if you have the declaration of `execvpe', and to 0 if you\n   don't. */\n#define HAVE_DECL_EXECVPE 1\n\n/* Define to 1 if you have the declaration of `fcvt', and to 0 if you don't.\n   */\n#define HAVE_DECL_FCVT 1\n\n/* Define to 1 if you have the declaration of `gcvt', and to 0 if you don't.\n   */\n#define HAVE_DECL_GCVT 1\n\n/* Define to 1 if you have the declaration of `isblank', and to 0 if you\n   don't. */\n#define HAVE_DECL_ISBLANK 1\n\n/* Define to 1 if you have the declaration of `mbrtowc', and to 0 if you\n   don't. */\n/* #undef HAVE_DECL_MBRTOWC */\n\n/* Define to 1 if you have the declaration of `mbsinit', and to 0 if you\n   don't. */\n/* #undef HAVE_DECL_MBSINIT */\n\n/* Define to 1 if you have the declaration of `strnlen', and to 0 if you\n   don't. */\n#define HAVE_DECL_STRNLEN 1\n\n/* Define to 1 if you have the declaration of `towlower', and to 0 if you\n   don't. */\n/* #undef HAVE_DECL_TOWLOWER */\n\n/* Define to 1 if you have the declaration of `wcrtomb', and to 0 if you\n   don't. */\n/* #undef HAVE_DECL_WCRTOMB */\n\n/* Define to 1 if you have the declaration of `wcsdup', and to 0 if you don't.\n   */\n#define HAVE_DECL_WCSDUP 1\n\n/* Define to 1 if you have the declaration of `_NSGetEnviron', and to 0 if you\n   don't. */\n#define HAVE_DECL__NSGETENVIRON 0\n\n/* Define to 1 if you have the declaration of `__environ', and to 0 if you\n   don't. */\n#define HAVE_DECL___ENVIRON 0\n\n/* Define to 1 if you have the <direct.h> header file. */\n#define HAVE_DIRECT_H 1\n\n/* Define to 1 if you have the <dirent.h> header file. */\n#define HAVE_DIRENT_H 1\n\n/* Define to 1 if you have the <fcntl.h> header file. */\n#define HAVE_FCNTL_H 1\n\n/* Define to 1 if you have the <features.h> header file. */\n/* #undef HAVE_FEATURES_H */\n\n/* Define to 1 if you have the `findfirst' function. */\n/* #undef HAVE_FINDFIRST */\n\n/* Define to 1 if you have the `fnmatch' function. */\n#define HAVE_FNMATCH 1\n\n/* Define to 1 if you have the <fnmatch.h> header file. */\n/* #undef HAVE_FNMATCH_H */\n\n/* Define to 1 if you have the `ftruncate' function. */\n/* #undef HAVE_FTRUNCATE */\n\n/* Define this value if support multibyte character encoding. */\n/* !!!#define HAVE_ICONV 1 */\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n#define HAVE_INTTYPES_H 1\n\n/* Define to 1 if you have the <io.h> header file. */\n#define HAVE_IO_H 1\n\n/* Define to 1 if you have the `isblank' function. */\n#define HAVE_ISBLANK 1\n\n/* Define to 1 if you have the `iswcntrl' function. */\n#define HAVE_ISWCNTRL 1\n\n/* Define to 1 if you have the `iswctype' function. */\n#define HAVE_ISWCTYPE 1\n\n/* Define this value if jansson is available. */\n/* !!!#define HAVE_JANSSON 1 */\n\n/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */\n/* #undef HAVE_LANGINFO_CODESET */\n\n/* Define to 1 if you have the <langinfo.h> header file. */\n/* #undef HAVE_LANGINFO_H */\n\n/* Define to 1 if you have the <libintl.h> header file. */\n#define HAVE_LIBINTL_H 1\n\n/* Define this value if libxml is available. */\n/* !!!#define HAVE_LIBXML 1 */\n\n/* Define this value if libyaml is available. */\n/* !!!#define HAVE_LIBYAML 1 */\n\n/* Define to 1 if you have the <limits.h> header file. */\n#define HAVE_LIMITS_H 1\n\n/* Define to 1 if the system has the type 'long long int'. */\n#define HAVE_LONG_LONG_INT 1\n\n/* Define to 1 if you have the <malloc.h> header file. */\n#define HAVE_MALLOC_H 1\n\n/* Define to 1 if you have the `mblen' function. */\n#define HAVE_MBLEN 1\n\n/* Define to 1 if you have the `mbrtowc' function. */\n#define HAVE_MBRTOWC 1\n\n/* Define to 1 if you have the `mbsinit' function. */\n#define HAVE_MBSINIT 1\n\n/* Define to 1 if <wchar.h> declares mbstate_t. */\n#define HAVE_MBSTATE_T 1\n\n/* Define to 1 if you have the `mbtowc' function. */\n#define HAVE_MBTOWC 1\n\n/* Define to 1 if you have the <memory.h> header file. */\n#define HAVE_MEMORY_H 1\n\n/* Define to 1 if you have the <minix/config.h> header file. */\n/* #undef HAVE_MINIX_CONFIG_H */\n\n/* Define to 1 if you have the `mkstemp' function. */\n#define HAVE_MKSTEMP 1\n\n/* Define to 1 if you have the `nl_langinfo' function. */\n/* #undef HAVE_NL_LANGINFO */\n\n/* Define to 1 if you have the `opendir' function. */\n#define HAVE_OPENDIR 1\n\n/* Define if you have the <pthread.h> header and the POSIX threads API. */\n/* !!!#define HAVE_PTHREAD_API 1 */\n\n/* Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE. */\n/* !!!#define HAVE_PTHREAD_MUTEX_RECURSIVE 1 */\n\n/* Define if the POSIX multithreading library has read/write locks. */\n/* !!!#define HAVE_PTHREAD_RWLOCK 1 */\n\n/* Define if the 'pthread_rwlock_rdlock' function prefers a writer to a\n   reader. */\n/* !!!#define HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER 1 */\n\n/* Define to 1 if you have the `putenv' function. */\n#define HAVE_PUTENV 1\n\n/* Define to 1 if you have the `scandir' function. */\n/* #undef HAVE_SCANDIR */\n\n/* Define this value if libseccomp is available. */\n/* #undef HAVE_SECCOMP */\n\n/* Define to 1 if you have the `setenv' function. */\n/* #undef HAVE_SETENV */\n\n/* Define to 1 if 'sig_atomic_t' is a signed integer type. */\n/* #undef HAVE_SIGNED_SIG_ATOMIC_T */\n\n/* Define to 1 if 'wchar_t' is a signed integer type. */\n/* #undef HAVE_SIGNED_WCHAR_T */\n\n/* Define to 1 if 'wint_t' is a signed integer type. */\n/* #undef HAVE_SIGNED_WINT_T */\n\n/* Define this macro if compiler supports statement expression non-standard C\n   feature. */\n#define HAVE_STATEMENT_EXPRESSION_EXT 1\n\n/* Define to 1 if you have the <stat.h> header file. */\n/* #undef HAVE_STAT_H */\n\n/* Define this macro if the field \"st_ino\" exists in struct stat in\n   <sys/stat.h>. */\n/* #undef HAVE_STAT_ST_INO */\n\n/* Define to 1 if you have the <stdbool.h> header file. */\n#define HAVE_STDBOOL_H 1\n\n/* Define to 1 if you have the <stdint.h> header file. */\n#define HAVE_STDINT_H 1\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#define HAVE_STDLIB_H 1\n\n/* Define to 1 if you have the `strcasecmp' function. */\n#define HAVE_STRCASECMP 1\n\n/* Define to 1 if you have the `strerror' function. */\n#define HAVE_STRERROR 1\n\n/* Define to 1 if you have the `stricmp' function. */\n/* #undef HAVE_STRICMP */\n\n/* Define to 1 if you have the <strings.h> header file. */\n#define HAVE_STRINGS_H 1\n\n/* Define to 1 if you have the <string.h> header file. */\n#define HAVE_STRING_H 1\n\n/* Define to 1 if you have the `strncasecmp' function. */\n#define HAVE_STRNCASECMP 1\n\n/* Define to 1 if you have the `strnicmp' function. */\n/* #undef HAVE_STRNICMP */\n\n/* Define to 1 if you have the `strstr' function. */\n#define HAVE_STRSTR 1\n\n/* Define to 1 if `decimal_point' is a member of `struct lconv'. */\n#define HAVE_STRUCT_LCONV_DECIMAL_POINT 1\n\n/* Define to 1 if you have the <sys/bitypes.h> header file. */\n/* #undef HAVE_SYS_BITYPES_H */\n\n/* Define to 1 if you have the <sys/dir.h> header file. */\n/* #undef HAVE_SYS_DIR_H */\n\n/* Define to 1 if you have the <sys/inttypes.h> header file. */\n/* #undef HAVE_SYS_INTTYPES_H */\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n#define HAVE_SYS_STAT_H 1\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#define HAVE_SYS_TYPES_H 1\n\n/* Define to 1 if you have the <sys/wait.h> header file. */\n/* #undef HAVE_SYS_WAIT_H */\n\n/* Define to 1 if you have the `tempnam' function. */\n/* #undef HAVE_TEMPNAM */\n\n/* Define to 1 if you have the `thrd_create' function. */\n/* #undef HAVE_THRD_CREATE */\n\n/* Define to 1 if you have the <threads.h> header file. */\n/* #undef HAVE_THREADS_H */\n\n/* Define to 1 if you have the `towlower' function. */\n/* #undef HAVE_TOWLOWER */\n\n/* Define to 1 if you have the `truncate' function. */\n/* !!!#define HAVE_TRUNCATE 1 */\n\n/* Define to 1 if typeof works with your compiler. */\n#define HAVE_TYPEOF 1\n\n/* Define to 1 if you have the <types.h> header file. */\n/* #undef HAVE_TYPES_H */\n\n/* Define to 1 if you have the <unistd.h> header file. */\n#define HAVE_UNISTD_H 1\n\n/* Define to 1 if the system has the type 'unsigned long long int'. */\n#define HAVE_UNSIGNED_LONG_LONG_INT 1\n\n/* Define to 1 or 0, depending whether the compiler supports simple visibility\n   declarations. */\n/* #undef HAVE_VISIBILITY */\n\n/* Define to 1 if you have the <wchar.h> header file. */\n#define HAVE_WCHAR_H 1\n\n/* Define if you have the 'wchar_t' type. */\n#define HAVE_WCHAR_T 1\n\n/* Define to 1 if you have the `wcrtomb' function. */\n#define HAVE_WCRTOMB 1\n\n/* Define to 1 if you have the <wctype.h> header file. */\n#define HAVE_WCTYPE_H 1\n\n/* Define to 1 if the compiler and linker support weak declarations of\n   symbols. */\n/* #undef HAVE_WEAK_SYMBOLS */\n\n/* Define if you have the 'wint_t' type. */\n#define HAVE_WINT_T 1\n\n/* Define to 1 if you have the <xlocale.h> header file. */\n/* #undef HAVE_XLOCALE_H */\n\n/* Define to 1 if the system has the type `_Bool'. */\n#define HAVE__BOOL 1\n\n/* Define to 1 if you have the `_findfirst' function. */\n/* #undef HAVE__FINDFIRST */\n\n/* Define to 1 if the compiler supports __builtin_expect,\n   and to 2 if <builtins.h> does.  */\n#define HAVE___BUILTIN_EXPECT 1\n#ifndef HAVE___BUILTIN_EXPECT\n# define __builtin_expect(e, c) (e)\n#elif HAVE___BUILTIN_EXPECT == 2\n# include <builtins.h>\n#endif\n\n\n/* Define to 1 if the compiler supports the keyword '__inline'. */\n#define HAVE___INLINE 1\n\n/* Define this value if the platform uses \"lib\" as prefix for iconv functions.\n   */\n/* #undef ICONV_USE_LIB_PREFIX */\n\n/* Define as the maximum integer on your system if not defined <limits.h>. */\n/* #undef INT_MAX */\n\n/* Define to the appropriate size for tmpnam() if <stdio.h> does not define\n   this. */\n/* #undef L_tmpnam */\n\n/* Define this label if you want macro tags (defined lables) to use patterns\n   in the EX command by default (original ctags behavior is to use line\n   numbers). */\n/* #undef MACROS_USE_PATTERNS */\n\n/* If malloc(0) is != NULL, define this to 1. Otherwise define this to 0. */\n#define MALLOC_0_IS_NONNULL 1\n\n/* Define if the mbrtowc function does not return (size_t) -2 for empty input.\n   */\n/* #undef MBRTOWC_EMPTY_INPUT_BUG */\n\n/* Define if the mbrtowc function may signal encoding errors in the C locale.\n   */\n/* #undef MBRTOWC_IN_C_LOCALE_MAYBE_EILSEQ */\n\n/* Define if the mbrtowc function has the NULL pwc argument bug. */\n/* #undef MBRTOWC_NULL_ARG1_BUG */\n\n/* Define if the mbrtowc function has the NULL string argument bug. */\n/* #undef MBRTOWC_NULL_ARG2_BUG */\n\n/* Define if the mbrtowc function does not return 0 for a NUL character. */\n/* #undef MBRTOWC_NUL_RETVAL_BUG */\n\n/* Define if the mbrtowc function returns a wrong return value. */\n#define MBRTOWC_RETVAL_BUG 1\n\n/* Define if the mbrtowc function stores a wide character when reporting\n   incomplete input. */\n/* #undef MBRTOWC_STORES_INCOMPLETE_BUG */\n\n/* Define to 1 if your system uses MS-DOS style path. */\n#define MSDOS_STYLE_PATH 1\n\n/* If you receive error or warning messages indicating that you are missing a\n   prototype for, or a type mismatch using, the following function, define\n   this label and remake. */\n/* #undef NEED_PROTO_FTRUNCATE */\n\n/* If you receive error or warning messages indicating that you are missing a\n   prototype for, or a type mismatch using, the following function, define\n   this label and remake. */\n#define NEED_PROTO_LSTAT 1\n\n/* If you receive error or warning messages indicating that you are missing a\n   prototype for, or a type mismatch using, the following function, define\n   this label and remake. */\n/* #undef NEED_PROTO_STAT */\n\n/* If you receive error or warning messages indicating that you are missing a\n   prototype for, or a type mismatch using, the following function, define\n   this label and remake. */\n/* #undef NEED_PROTO_TRUNCATE */\n\n/* Define to 1 if nl_langinfo is multithread-safe. */\n/* #undef NL_LANGINFO_MTSAFE */\n\n/* Define this is you have a prototype for putenv() in <stdlib.h>, but doesn't\n   declare its argument as \"const char *\". */\n#define NON_CONST_PUTENV_PROTOTYPE 1\n\n/* Package name. */\n#define PACKAGE \"universal-ctags\"\n\n/* Define to the address where bug reports for this package should be sent. */\n#define PACKAGE_BUGREPORT \"\"\n\n/* Define to the full name of this package. */\n#define PACKAGE_NAME \"universal-ctags\"\n\n/* Define to the full name and version of this package. */\n#define PACKAGE_STRING \"universal-ctags 6.2.0\"\n\n/* Define to the one symbol short name of this package. */\n#define PACKAGE_TARNAME \"universal-ctags\"\n\n/* Define to the home page for this package. */\n#define PACKAGE_URL \"\"\n\n/* Define to the version of this package. */\n#define PACKAGE_VERSION \"6.2.0\"\n\n/* Define if the pthread_in_use() detection is hard. */\n/* #undef PTHREAD_IN_USE_DETECTION_HARD */\n\n/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type\n   'ptrdiff_t'. */\n/* #undef PTRDIFF_T_SUFFIX */\n\n/* Define if nl_langinfo exists but is overridden by gnulib. */\n/* #undef REPLACE_NL_LANGINFO */\n\n/* Define to 1 if setlocale (LC_ALL, NULL) is multithread-safe. */\n#define SETLOCALE_NULL_ALL_MTSAFE 1\n\n/* Define to 1 if setlocale (category, NULL) is multithread-safe. */\n#define SETLOCALE_NULL_ONE_MTSAFE 1\n\n/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type\n   'sig_atomic_t'. */\n/* #undef SIG_ATOMIC_T_SUFFIX */\n\n/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type\n   'size_t'. */\n/* #undef SIZE_T_SUFFIX */\n\n/* Define to 1 if you have the ANSI C header files. */\n#define STDC_HEADERS 1\n\n/* If you wish to change the directory in which temporary files are stored,\n   define this label to the directory desired. */\n#define TMPDIR \"/tmp\"\n\n/* Define to 1 when using fnmatch implementation in bundled gnulib. */\n#define USE_GNULIB_FNMATCH\n\n/* Define if the combination of the ISO C and POSIX multithreading APIs can be\n   used. */\n/* #undef USE_ISOC_AND_POSIX_THREADS */\n\n/* Define if the ISO C multithreading library can be used. */\n/* #undef USE_ISOC_THREADS */\n\n/* Define if the POSIX multithreading library can be used. */\n/* !!!#define USE_POSIX_THREADS 1 */\n\n/* Define if references to the POSIX multithreading library should be made\n   weak. */\n/* #undef USE_POSIX_THREADS_WEAK */\n\n/* Enable extensions on AIX 3, Interix.  */\n#ifndef _ALL_SOURCE\n# define _ALL_SOURCE 1\n#endif\n/* Enable general extensions on macOS.  */\n#ifndef _DARWIN_C_SOURCE\n# define _DARWIN_C_SOURCE 1\n#endif\n/* Enable general extensions on Solaris.  */\n#ifndef __EXTENSIONS__\n# define __EXTENSIONS__ 1\n#endif\n/* Enable GNU extensions on systems that have them.  */\n#ifndef _GNU_SOURCE\n# define _GNU_SOURCE 1\n#endif\n/* Enable X/Open compliant socket functions that do not require linking\n   with -lxnet on HP-UX 11.11.  */\n#ifndef _HPUX_ALT_XOPEN_SOCKET_API\n# define _HPUX_ALT_XOPEN_SOCKET_API 1\n#endif\n/* Identify the host operating system as Minix.\n   This macro does not affect the system headers' behavior.\n   A future release of Autoconf may stop defining this macro.  */\n#ifndef _MINIX\n/* # undef _MINIX */\n#endif\n/* Enable general extensions on NetBSD.\n   Enable NetBSD compatibility extensions on Minix.  */\n#ifndef _NETBSD_SOURCE\n# define _NETBSD_SOURCE 1\n#endif\n/* Enable OpenBSD compatibility extensions on NetBSD.\n   Oddly enough, this does nothing on OpenBSD.  */\n#ifndef _OPENBSD_SOURCE\n# define _OPENBSD_SOURCE 1\n#endif\n/* Define to 1 if needed for POSIX-compatible behavior.  */\n#ifndef _POSIX_SOURCE\n/* # undef _POSIX_SOURCE */\n#endif\n/* Define to 2 if needed for POSIX-compatible behavior.  */\n#ifndef _POSIX_1_SOURCE\n/* # undef _POSIX_1_SOURCE */\n#endif\n/* Enable POSIX-compatible threading on Solaris.  */\n#ifndef _POSIX_PTHREAD_SEMANTICS\n# define _POSIX_PTHREAD_SEMANTICS 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-5:2014.  */\n#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__\n# define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-1:2014.  */\n#ifndef __STDC_WANT_IEC_60559_BFP_EXT__\n# define __STDC_WANT_IEC_60559_BFP_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-2:2015.  */\n#ifndef __STDC_WANT_IEC_60559_DFP_EXT__\n# define __STDC_WANT_IEC_60559_DFP_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-4:2015.  */\n#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__\n# define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TS 18661-3:2015.  */\n#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__\n# define __STDC_WANT_IEC_60559_TYPES_EXT__ 1\n#endif\n/* Enable extensions specified by ISO/IEC TR 24731-2:2010.  */\n#ifndef __STDC_WANT_LIB_EXT2__\n# define __STDC_WANT_LIB_EXT2__ 1\n#endif\n/* Enable extensions specified by ISO/IEC 24747:2009.  */\n#ifndef __STDC_WANT_MATH_SPEC_FUNCS__\n# define __STDC_WANT_MATH_SPEC_FUNCS__ 1\n#endif\n/* Enable extensions on HP NonStop.  */\n#ifndef _TANDEM_SOURCE\n# define _TANDEM_SOURCE 1\n#endif\n/* Enable X/Open extensions.  Define to 500 only if necessary\n   to make mbstate_t available.  */\n#ifndef _XOPEN_SOURCE\n/* # undef _XOPEN_SOURCE */\n#endif\n\n\n/* Define if the native Windows multithreading API can be used. */\n/* #undef USE_WINDOWS_THREADS */\n\n/* Package version. */\n#define VERSION \"6.2.0\"\n\n/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type\n   'wchar_t'. */\n/* #undef WCHAR_T_SUFFIX */\n\n/* Define if the wcrtomb function does not work in the C locale. */\n/* #undef WCRTOMB_C_LOCALE_BUG */\n\n/* Define if the wcrtomb function has an incorrect return value. */\n/* #undef WCRTOMB_RETVAL_BUG */\n\n/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type\n   'wint_t'. */\n/* #undef WINT_T_SUFFIX */\n\n/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most\n   significant byte first (like Motorola and SPARC, unlike Intel). */\n#if defined AC_APPLE_UNIVERSAL_BUILD\n# if defined __BIG_ENDIAN__\n#  define WORDS_BIGENDIAN 1\n# endif\n#else\n# ifndef WORDS_BIGENDIAN\n/* #  undef WORDS_BIGENDIAN */\n# endif\n#endif\n\n/* Enable large inode numbers on Mac OS X 10.5.  */\n#ifndef _DARWIN_USE_64_BIT_INODE\n# define _DARWIN_USE_64_BIT_INODE 1\n#endif\n\n/* Number of bits in a file offset, on hosts where this is settable. */\n#define _FILE_OFFSET_BITS 64\n\n/* True if the compiler says it groks GNU C version MAJOR.MINOR.  */\n#if defined __GNUC__ && defined __GNUC_MINOR__\n# define _GL_GNUC_PREREQ(major, minor) \\\n    ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__))\n#else\n# define _GL_GNUC_PREREQ(major, minor) 0\n#endif\n\n\n/* Define to enable the declarations of ISO C 11 types and functions. */\n/* #undef _ISOC11_SOURCE */\n\n/* Define for large files, on AIX-style hosts. */\n/* #undef _LARGE_FILES */\n\n/* Define to 1 on Solaris. */\n/* #undef _LCONV_C99 */\n\n/* The _Noreturn keyword of C11.  */\n#ifndef _Noreturn\n# if (defined __cplusplus \\\n      && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \\\n          || (defined _MSC_VER && 1900 <= _MSC_VER)) \\\n      && 0)\n    /* [[noreturn]] is not practically usable, because with it the syntax\n         extern _Noreturn void func (...);\n       would not be valid; such a declaration would only be valid with 'extern'\n       and '_Noreturn' swapped, or without the 'extern' keyword.  However, some\n       AIX system header files and several gnulib header files use precisely\n       this syntax with 'extern'.  */\n#  define _Noreturn [[noreturn]]\n# elif ((!defined __cplusplus || defined __clang__) \\\n        && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \\\n            || (!defined __STRICT_ANSI__ \\\n                && (_GL_GNUC_PREREQ (4, 7) \\\n                    || (defined __apple_build_version__ \\\n                        ? 6000000 <= __apple_build_version__ \\\n                        : 3 < __clang_major__ + (5 <= __clang_minor__))))))\n   /* _Noreturn works as-is.  */\n# elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C\n#  define _Noreturn __attribute__ ((__noreturn__))\n# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)\n#  define _Noreturn __declspec (noreturn)\n# else\n#  define _Noreturn\n# endif\n#endif\n\n\n/* Define if you want <regex.h> to include <limits.h>, so that it consistently\n   overrides <limits.h>'s RE_DUP_MAX. */\n#define _REGEX_INCLUDE_LIMITS_H 1\n\n/* Define if you want regoff_t to be at least as wide POSIX requires. */\n/* !!!#define _REGEX_LARGE_OFFSETS 1*/\n\n/* For standard stat data types on VMS. */\n#define _USE_STD_STAT 1\n\n/* Define to 1 if the system <stdint.h> predates C++11. */\n/* #undef __STDC_CONSTANT_MACROS */\n\n/* Define to 1 if the system <stdint.h> predates C++11. */\n/* #undef __STDC_LIMIT_MACROS */\n\n/* The _GL_ASYNC_SAFE marker should be attached to functions that are\n   signal handlers (for signals other than SIGABRT, SIGPIPE) or can be\n   invoked from such signal handlers.  Such functions have some restrictions:\n     * All functions that it calls should be marked _GL_ASYNC_SAFE as well,\n       or should be listed as async-signal-safe in POSIX\n       <https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04>\n       section 2.4.3.  Note that malloc(), sprintf(), and fwrite(), in\n       particular, are NOT async-signal-safe.\n     * All memory locations (variables and struct fields) that these functions\n       access must be marked 'volatile'.  This holds for both read and write\n       accesses.  Otherwise the compiler might optimize away stores to and\n       reads from such locations that occur in the program, depending on its\n       data flow analysis.  For example, when the program contains a loop\n       that is intended to inspect a variable set from within a signal handler\n           while (!signal_occurred)\n             ;\n       the compiler is allowed to transform this into an endless loop if the\n       variable 'signal_occurred' is not declared 'volatile'.\n   Additionally, recall that:\n     * A signal handler should not modify errno (except if it is a handler\n       for a fatal signal and ends by raising the same signal again, thus\n       provoking the termination of the process).  If it invokes a function\n       that may clobber errno, it needs to save and restore the value of\n       errno.  */\n#define _GL_ASYNC_SAFE\n\n\n/* Attributes.  */\n#if (defined __has_attribute \\\n     && (!defined __clang_minor__ \\\n         || 3 < __clang_major__ + (5 <= __clang_minor__)))\n# define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__)\n#else\n# define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr\n# define _GL_ATTR_alloc_size _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_always_inline _GL_GNUC_PREREQ (3, 2)\n# define _GL_ATTR_artificial _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_cold _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_const _GL_GNUC_PREREQ (2, 95)\n# define _GL_ATTR_deprecated _GL_GNUC_PREREQ (3, 1)\n# define _GL_ATTR_diagnose_if 0\n# define _GL_ATTR_error _GL_GNUC_PREREQ (4, 3)\n# define _GL_ATTR_externally_visible _GL_GNUC_PREREQ (4, 1)\n# define _GL_ATTR_fallthrough _GL_GNUC_PREREQ (7, 0)\n# define _GL_ATTR_format _GL_GNUC_PREREQ (2, 7)\n# define _GL_ATTR_leaf _GL_GNUC_PREREQ (4, 6)\n# ifdef _ICC\n#  define _GL_ATTR_may_alias 0\n# else\n#  define _GL_ATTR_may_alias _GL_GNUC_PREREQ (3, 3)\n# endif\n# define _GL_ATTR_malloc _GL_GNUC_PREREQ (3, 0)\n# define _GL_ATTR_noinline _GL_GNUC_PREREQ (3, 1)\n# define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3)\n# define _GL_ATTR_nonstring _GL_GNUC_PREREQ (8, 0)\n# define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3)\n# define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7)\n# define _GL_ATTR_pure _GL_GNUC_PREREQ (2, 96)\n# define _GL_ATTR_returns_nonnull _GL_GNUC_PREREQ (4, 9)\n# define _GL_ATTR_sentinel _GL_GNUC_PREREQ (4, 0)\n# define _GL_ATTR_unused _GL_GNUC_PREREQ (2, 7)\n# define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4)\n#endif\n\n\n#if _GL_HAS_ATTRIBUTE (alloc_size)\n# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))\n#else\n# define _GL_ATTRIBUTE_ALLOC_SIZE(args)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (always_inline)\n# define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))\n#else\n# define _GL_ATTRIBUTE_ALWAYS_INLINE\n#endif\n\n#if _GL_HAS_ATTRIBUTE (artificial)\n# define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__))\n#else\n# define _GL_ATTRIBUTE_ARTIFICIAL\n#endif\n\n/* Avoid __attribute__ ((cold)) on MinGW; see thread starting at\n   <https://lists.gnu.org/r/emacs-devel/2019-04/msg01152.html>.\n   Also, Oracle Studio 12.6 requires 'cold' not '__cold__'.  */\n#if _GL_HAS_ATTRIBUTE (cold) && !defined __MINGW32__\n# ifndef __SUNPRO_C\n#  define _GL_ATTRIBUTE_COLD __attribute__ ((__cold__))\n# else\n#  define _GL_ATTRIBUTE_COLD __attribute__ ((cold))\n# endif\n#else\n# define _GL_ATTRIBUTE_COLD\n#endif\n\n#if _GL_HAS_ATTRIBUTE (const)\n# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__))\n#else\n# define _GL_ATTRIBUTE_CONST\n#endif\n\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_DEPRECATED [[__deprecated__]]\n#elif _GL_HAS_ATTRIBUTE (deprecated)\n# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__))\n#else\n# define _GL_ATTRIBUTE_DEPRECATED\n#endif\n\n#if _GL_HAS_ATTRIBUTE (error)\n# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg)))\n# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg)))\n#elif _GL_HAS_ATTRIBUTE (diagnose_if)\n# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__diagnose_if__ (1, msg, \"error\")))\n# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__diagnose_if__ (1, msg, \"warning\")))\n#else\n# define _GL_ATTRIBUTE_ERROR(msg)\n# define _GL_ATTRIBUTE_WARNING(msg)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (externally_visible)\n# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE __attribute__ ((externally_visible))\n#else\n# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE\n#endif\n\n/* FALLTHROUGH is special, because it always expands to something.  */\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_FALLTHROUGH [[__fallthrough__]]\n#elif _GL_HAS_ATTRIBUTE (fallthrough)\n# define _GL_ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))\n#else\n# define _GL_ATTRIBUTE_FALLTHROUGH ((void) 0)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (format)\n# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))\n#else\n# define _GL_ATTRIBUTE_FORMAT(spec)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (leaf)\n# define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__))\n#else\n# define _GL_ATTRIBUTE_LEAF\n#endif\n\n/* Oracle Studio 12.6 mishandles may_alias despite __has_attribute OK.  */\n#if _GL_HAS_ATTRIBUTE (may_alias) && !defined __SUNPRO_C\n# define _GL_ATTRIBUTE_MAY_ALIAS __attribute__ ((__may_alias__))\n#else\n# define _GL_ATTRIBUTE_MAY_ALIAS\n#endif\n\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_MAYBE_UNUSED [[__maybe_unused__]]\n#elif _GL_HAS_ATTRIBUTE (unused)\n# define _GL_ATTRIBUTE_MAYBE_UNUSED __attribute__ ((__unused__))\n#else\n# define _GL_ATTRIBUTE_MAYBE_UNUSED\n#endif\n/* Earlier spellings of this macro.  */\n#define _GL_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED\n#define _UNUSED_PARAMETER_ _GL_ATTRIBUTE_MAYBE_UNUSED\n\n#if 0 /* !!!_GL_HAS_ATTRIBUTE (malloc) */\n# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))\n#else\n# define _GL_ATTRIBUTE_MALLOC\n#endif\n\n#if 201710L < __STDC_VERSION__\n# define _GL_ATTRIBUTE_NODISCARD [[__nodiscard__]]\n#elif _GL_HAS_ATTRIBUTE (warn_unused_result)\n# define _GL_ATTRIBUTE_NODISCARD __attribute__ ((__warn_unused_result__))\n#else\n# define _GL_ATTRIBUTE_NODISCARD\n#endif\n\n#if _GL_HAS_ATTRIBUTE (noinline)\n# define _GL_ATTRIBUTE_NOINLINE __attribute__ ((__noinline__))\n#else\n# define _GL_ATTRIBUTE_NOINLINE\n#endif\n\n#if _GL_HAS_ATTRIBUTE (nonnull)\n# define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args))\n#else\n# define _GL_ATTRIBUTE_NONNULL(args)\n#endif\n\n#if _GL_HAS_ATTRIBUTE (nonstring)\n# define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__))\n#else\n# define _GL_ATTRIBUTE_NONSTRING\n#endif\n\n/* There is no _GL_ATTRIBUTE_NORETURN; use _Noreturn instead.  */\n\n#if _GL_HAS_ATTRIBUTE (nothrow) && !defined __cplusplus\n# define _GL_ATTRIBUTE_NOTHROW __attribute__ ((__nothrow__))\n#else\n# define _GL_ATTRIBUTE_NOTHROW\n#endif\n\n#if _GL_HAS_ATTRIBUTE (packed)\n# define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__))\n#else\n# define _GL_ATTRIBUTE_PACKED\n#endif\n\n#if _GL_HAS_ATTRIBUTE (pure)\n# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))\n#else\n# define _GL_ATTRIBUTE_PURE\n#endif\n\n#if _GL_HAS_ATTRIBUTE (returns_nonnull)\n# define _GL_ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__))\n#else\n# define _GL_ATTRIBUTE_RETURNS_NONNULL\n#endif\n\n#if _GL_HAS_ATTRIBUTE (sentinel)\n# define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos))\n#else\n# define _GL_ATTRIBUTE_SENTINEL(pos)\n#endif\n\n\n/* To support C++ as well as C, use _GL_UNUSED_LABEL with trailing ';'.  */\n#if !defined __cplusplus || _GL_GNUC_PREREQ (4, 5)\n# define _GL_UNUSED_LABEL _GL_ATTRIBUTE_MAYBE_UNUSED\n#else\n# define _GL_UNUSED_LABEL\n#endif\n\n\n/* Define to the appropriate type if <time.h> does not define this. */\n/* #undef clock_t */\n\n/* Define to empty if `const' does not conform to ANSI C. */\n/* #undef const */\n\n/* Please see the Gnulib manual for how to use these macros.\n\n   Suppress extern inline with HP-UX cc, as it appears to be broken; see\n   <https://lists.gnu.org/r/bug-texinfo/2013-02/msg00030.html>.\n\n   Suppress extern inline with Sun C in standards-conformance mode, as it\n   mishandles inline functions that call each other.  E.g., for 'inline void f\n   (void) { } inline void g (void) { f (); }', c99 incorrectly complains\n   'reference to static identifier \"f\" in extern inline function'.\n   This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.\n\n   Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))\n   on configurations that mistakenly use 'static inline' to implement\n   functions or macros in standard C headers like <ctype.h>.  For example,\n   if isdigit is mistakenly implemented via a static inline function,\n   a program containing an extern inline function that calls isdigit\n   may not work since the C standard prohibits extern inline functions\n   from calling static functions (ISO C 99 section 6.7.4.(3).\n   This bug is known to occur on:\n\n     OS X 10.8 and earlier; see:\n     https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html\n\n     DragonFly; see\n     http://muscles.dragonflybsd.org/bulk/clang-master-potential/20141111_102002/logs/ah-tty-0.3.12.log\n\n     FreeBSD; see:\n     https://lists.gnu.org/r/bug-gnulib/2014-07/msg00104.html\n\n   OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and\n   for clang but remains for g++; see <https://trac.macports.org/ticket/41033>.\n   Assume DragonFly and FreeBSD will be similar.\n\n   GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99\n   inline semantics, unless -fgnu89-inline is used.  It defines a macro\n   __GNUC_STDC_INLINE__ to indicate this situation or a macro\n   __GNUC_GNU_INLINE__ to indicate the opposite situation.\n   GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline\n   semantics but warns, unless -fgnu89-inline is used:\n     warning: C99 inline functions are not supported; using GNU89\n     warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute\n   It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.\n */\n#if 0 /* !!!disable inline processing */\n#if (((defined __APPLE__ && defined __MACH__) \\\n      || defined __DragonFly__ || defined __FreeBSD__) \\\n     && (defined __header_inline \\\n         ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \\\n            && ! defined __clang__) \\\n         : ((! defined _DONT_USE_CTYPE_INLINE_ \\\n             && (defined __GNUC__ || defined __cplusplus)) \\\n            || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \\\n                && defined __GNUC__ && ! defined __cplusplus))))\n# define _GL_EXTERN_INLINE_STDHEADER_BUG\n#endif\n#if ((__GNUC__ \\\n      ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \\\n      : (199901L <= __STDC_VERSION__ \\\n         && !defined __HP_cc \\\n         && !defined __PGI \\\n         && !(defined __SUNPRO_C && __STDC__))) \\\n     && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)\n# define _GL_INLINE inline\n# define _GL_EXTERN_INLINE extern inline\n# define _GL_EXTERN_INLINE_IN_USE\n#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \\\n       && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)\n# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__\n   /* __gnu_inline__ suppresses a GCC 4.2 diagnostic.  */\n#  define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))\n# else\n#  define _GL_INLINE extern inline\n# endif\n# define _GL_EXTERN_INLINE extern\n# define _GL_EXTERN_INLINE_IN_USE\n#else\n# define _GL_INLINE static _GL_UNUSED\n# define _GL_EXTERN_INLINE static _GL_UNUSED\n#endif\n\n/* In GCC 4.6 (inclusive) to 5.1 (exclusive),\n   suppress bogus \"no previous prototype for 'FOO'\"\n   and \"no previous declaration for 'FOO'\" diagnostics,\n   when FOO is an inline function in the header; see\n   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and\n   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>.  */\n#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__\n# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__\n#  define _GL_INLINE_HEADER_CONST_PRAGMA\n# else\n#  define _GL_INLINE_HEADER_CONST_PRAGMA \\\n     _Pragma (\"GCC diagnostic ignored \\\"-Wsuggest-attribute=const\\\"\")\n# endif\n# define _GL_INLINE_HEADER_BEGIN \\\n    _Pragma (\"GCC diagnostic push\") \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wmissing-prototypes\\\"\") \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wmissing-declarations\\\"\") \\\n    _GL_INLINE_HEADER_CONST_PRAGMA\n# define _GL_INLINE_HEADER_END \\\n    _Pragma (\"GCC diagnostic pop\")\n#else\n# define _GL_INLINE_HEADER_BEGIN\n# define _GL_INLINE_HEADER_END\n#endif\n\n/* Define to long if <stdio.h> does not define this. */\n/* #undef fpos_t */\n\n/* Define to `__inline__' or `__inline' if that's what the C compiler\n   calls it, or to nothing if 'inline' is not supported under any name.  */\n#ifndef __cplusplus\n/* #undef inline */\n#endif\n#endif /* !!!disable inline processing */\n\n/* #define inline __inline */\n#define inline\n\n/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports\n   the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of\n   earlier versions), but does not display it by setting __GNUC_STDC_INLINE__.\n   __APPLE__ && __MACH__ test for Mac OS X.\n   __APPLE_CC__ tests for the Apple compiler and its version.\n   __STDC_VERSION__ tests for the C99 mode.  */\n#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__\n# define __GNUC_STDC_INLINE__ 1\n#endif\n\n/* Define to a type if <wchar.h> does not define. */\n/* #undef mbstate_t */\n\n/* _GL_CMP (n1, n2) performs a three-valued comparison on n1 vs. n2, where\n   n1 and n2 are expressions without side effects, that evaluate to real\n   numbers (excluding NaN).\n   It returns\n     1  if n1 > n2\n     0  if n1 == n2\n     -1 if n1 < n2\n   The naïve code   (n1 > n2 ? 1 : n1 < n2 ? -1 : 0)  produces a conditional\n   jump with nearly all GCC versions up to GCC 10.\n   This variant     (n1 < n2 ? -1 : n1 > n2)  produces a conditional with many\n   GCC versions up to GCC 9.\n   The better code  (n1 > n2) - (n1 < n2)  from Hacker's Delight § 2-9\n   avoids conditional jumps in all GCC versions >= 3.4.  */\n#define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2)))\n\n\n/* Define to `int' if <sys/types.h> does not define. */\n/* #undef mode_t */\n\n/* Define to `long int' if <sys/types.h> does not define. */\n/* #undef off_t */\n\n/* Define as a signed integer type capable of holding a process identifier. */\n/* #undef pid_t */\n\n/* Define to rpl_re_comp if the replacement should be used. */\n#define re_comp rpl_re_comp\n\n/* Define to rpl_re_compile_fastmap if the replacement should be used. */\n#define re_compile_fastmap rpl_re_compile_fastmap\n\n/* Define to rpl_re_compile_pattern if the replacement should be used. */\n#define re_compile_pattern rpl_re_compile_pattern\n\n/* Define to rpl_re_exec if the replacement should be used. */\n#define re_exec rpl_re_exec\n\n/* Define to rpl_re_match if the replacement should be used. */\n#define re_match rpl_re_match\n\n/* Define to rpl_re_match_2 if the replacement should be used. */\n#define re_match_2 rpl_re_match_2\n\n/* Define to rpl_re_search if the replacement should be used. */\n#define re_search rpl_re_search\n\n/* Define to rpl_re_search_2 if the replacement should be used. */\n#define re_search_2 rpl_re_search_2\n\n/* Define to rpl_re_set_registers if the replacement should be used. */\n#define re_set_registers rpl_re_set_registers\n\n/* Define to rpl_re_set_syntax if the replacement should be used. */\n#define re_set_syntax rpl_re_set_syntax\n\n/* Define to rpl_re_syntax_options if the replacement should be used. */\n#define re_syntax_options rpl_re_syntax_options\n\n/* Define to rpl_regcomp if the replacement should be used. */\n/* !!!#define regcomp rpl_regcomp */\n\n/* Define to rpl_regerror if the replacement should be used. */\n/* !!!#define regerror rpl_regerror */\n\n/* Define to rpl_regexec if the replacement should be used. */\n/* !!!#define regexec rpl_regexec */\n\n/* Define to rpl_regfree if the replacement should be used. */\n/* !!!#define regfree rpl_regfree */\n\n/* Define remove to unlink if you have unlink(), but not remove(). */\n/* #undef remove */\n\n/* Define to the equivalent of the C99 'restrict' keyword, or to\n   nothing if this is not supported.  Do not define if restrict is\n   supported only directly.  */\n/* !!!#define restrict __restrict__*/\n/* Work around a bug in older versions of Sun C++, which did not\n   #define __restrict__ or support _Restrict or __restrict__\n   even though the corresponding Sun C compiler ended up with\n   \"#define restrict _Restrict\" or \"#define restrict __restrict__\"\n   in the previous line.  This workaround can be removed once\n   we assume Oracle Developer Studio 12.5 (2016) or later.  */\n#if defined __SUNPRO_CC && !defined __RESTRICT && !defined __restrict__\n# define _Restrict\n# define __restrict__\n#endif\n\n/* Define as a signed type of the same size as size_t. */\n/* #undef ssize_t */\n\n/* Define to __typeof__ if your compiler spells it that way. */\n/* #undef typeof */\n\n/* _WIN32 is defined implicitly */\n# include \"setlocale_null.h\"\n\n/* for fnmatch() */\n#include <sys/types.h>\n#include <wchar.h>\nvoid *mempcpy (void *dest, const void *src, size_t n);\nwchar_t *wmempcpy (wchar_t *dest, const wchar_t *src, size_t n);\n"
  },
  {
    "path": "win32/ctags.exe.manifest",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n  <assemblyIdentity type=\"win32\" name=\"Universal Ctags\" version=\"6.2.0.0\" />\n  <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n    <security>\n      <requestedPrivileges>\n        <requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\" />\n      </requestedPrivileges>\n    </security>\n  </trustInfo>\n  <application>\n    <windowsSettings>\n      <activeCodePage xmlns=\"http://schemas.microsoft.com/SMI/2019/WindowsSettings\">UTF-8</activeCodePage>\n    </windowsSettings>\n  </application>\n  <compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">\n    <application>\n      <!--The ID below indicates application support for Windows Vista -->\n      <supportedOS Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\"/>\n      <!--The ID below indicates application support for Windows 7 -->\n      <supportedOS Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\"/>\n      <!--The ID below indicates application support for Windows 8 -->\n      <supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\"/>\n      <!--The ID below indicates application support for Windows 8.1 -->\n      <supportedOS Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\"/>\n      <!--The ID below indicates application support for Windows 10 -->\n      <supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\"/>\n    </application>\n  </compatibility>\n</assembly>\n"
  },
  {
    "path": "win32/ctags.rc",
    "content": "// Microsoft Visual C++ generated resource script.\n//\n#include \"resource.h\"\n\n#define APSTUDIO_READONLY_SYMBOLS\n/////////////////////////////////////////////////////////////////////////////\n//\n// Generated from the TEXTINCLUDE 2 resource.\n//\n#include \"winresrc.h\"\n\n/////////////////////////////////////////////////////////////////////////////\n#undef APSTUDIO_READONLY_SYMBOLS\n\n/////////////////////////////////////////////////////////////////////////////\n// English (United States) resources\n\n#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\nLANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\n#pragma code_page(1252)\n\n#ifdef APSTUDIO_INVOKED\n/////////////////////////////////////////////////////////////////////////////\n//\n// TEXTINCLUDE\n//\n\n1 TEXTINCLUDE \nBEGIN\n    \"resource.h\\0\"\nEND\n\n2 TEXTINCLUDE \nBEGIN\n    \"#include \"\"winres.h\"\"\\r\\n\"\n    \"\\0\"\nEND\n\n3 TEXTINCLUDE \nBEGIN\n    \"\\r\\n\"\n    \"\\0\"\nEND\n\n#endif    // APSTUDIO_INVOKED\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// RT_MANIFEST\n//\n\n1                       RT_MANIFEST             \"ctags.exe.manifest\"\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Version\n//\n\nVS_VERSION_INFO VERSIONINFO\n FILEVERSION 6,2,0,0\n PRODUCTVERSION 6,2,0,0\n FILEFLAGSMASK 0x3fL\n#ifdef _DEBUG\n FILEFLAGS 0x1L\n#else\n FILEFLAGS 0x0L\n#endif\n FILEOS 0x40004L\n FILETYPE 0x1L\n FILESUBTYPE 0x0L\nBEGIN\n    BLOCK \"StringFileInfo\"\n    BEGIN\n        BLOCK \"040904b0\"\n        BEGIN\n            VALUE \"CompanyName\", \"Universal Ctags Team\"\n            VALUE \"FileDescription\", \"Universal Ctags\"\n            VALUE \"FileVersion\", \"6.2.0.0\"\n            VALUE \"InternalName\", \"ctags.exe\"\n            VALUE \"LegalCopyright\", \"Copyright \\251 2015-2023 Universal Ctags Team\"\n            VALUE \"OriginalFilename\", \"ctags.exe\"\n            VALUE \"ProductName\", \"Universal Ctags\"\n            VALUE \"ProductVersion\", \"6.2.0.0\"\n        END\n    END\n    BLOCK \"VarFileInfo\"\n    BEGIN\n        VALUE \"Translation\", 0x409, 1200\n    END\nEND\n\n#endif    // English (United States) resources\n/////////////////////////////////////////////////////////////////////////////\n\n\n\n#ifndef APSTUDIO_INVOKED\n/////////////////////////////////////////////////////////////////////////////\n//\n// Generated from the TEXTINCLUDE 3 resource.\n//\n\n\n/////////////////////////////////////////////////////////////////////////////\n#endif    // not APSTUDIO_INVOKED\n\n"
  },
  {
    "path": "win32/ctags_vs2013.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 2013\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"ctags\", \"ctags_vs2013.vcxproj\", \"{CE5CDD7C-2102-4753-8AAB-7915802BF658}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Win32 = Debug|Win32\r\n\t\tDebug|x64 = Debug|x64\r\n\t\tRelease|Win32 = Release|Win32\r\n\t\tRelease|x64 = Release|x64\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{CE5CDD7C-2102-4753-8AAB-7915802BF658}.Debug|Win32.ActiveCfg = Debug|Win32\r\n\t\t{CE5CDD7C-2102-4753-8AAB-7915802BF658}.Debug|Win32.Build.0 = Debug|Win32\r\n\t\t{CE5CDD7C-2102-4753-8AAB-7915802BF658}.Debug|x64.ActiveCfg = Debug|x64\r\n\t\t{CE5CDD7C-2102-4753-8AAB-7915802BF658}.Debug|x64.Build.0 = Debug|x64\r\n\t\t{CE5CDD7C-2102-4753-8AAB-7915802BF658}.Release|Win32.ActiveCfg = Release|Win32\r\n\t\t{CE5CDD7C-2102-4753-8AAB-7915802BF658}.Release|Win32.Build.0 = Release|Win32\r\n\t\t{CE5CDD7C-2102-4753-8AAB-7915802BF658}.Release|x64.ActiveCfg = Release|x64\r\n\t\t{CE5CDD7C-2102-4753-8AAB-7915802BF658}.Release|x64.Build.0 = Release|x64\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "win32/ctags_vs2013.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup Label=\"ProjectConfigurations\">\r\n    <ProjectConfiguration Include=\"Debug|Win32\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Debug|x64\">\r\n      <Configuration>Debug</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|Win32\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>Win32</Platform>\r\n    </ProjectConfiguration>\r\n    <ProjectConfiguration Include=\"Release|x64\">\r\n      <Configuration>Release</Configuration>\r\n      <Platform>x64</Platform>\r\n    </ProjectConfiguration>\r\n  </ItemGroup>\r\n  <PropertyGroup Label=\"Globals\">\r\n    <ProjectName>ctags</ProjectName>\r\n    <ProjectGuid>{CE5CDD7C-2102-4753-8AAB-7915802BF658}</ProjectGuid>\r\n    <RootNamespace>ctags</RootNamespace>\r\n    <Keyword>Win32Proj</Keyword>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <PlatformToolset>v120</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <WholeProgramOptimization>true</WholeProgramOptimization>\r\n    <PlatformToolset>v120</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v120</PlatformToolset>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\r\n    <ConfigurationType>Application</ConfigurationType>\r\n    <CharacterSet>Unicode</CharacterSet>\r\n    <PlatformToolset>v120</PlatformToolset>\r\n  </PropertyGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\r\n  <ImportGroup Label=\"ExtensionSettings\">\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\r\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\r\n  </ImportGroup>\r\n  <PropertyGroup Label=\"UserMacros\" />\r\n  <PropertyGroup>\r\n    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\r\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(SolutionDir)$(Configuration)\\</OutDir>\r\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(Configuration)\\</IntDir>\r\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\r\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\r\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(SolutionDir)$(Configuration)\\</OutDir>\r\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(Configuration)\\</IntDir>\r\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\r\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\r\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\r\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\r\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\r\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\r\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\r\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\r\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\r\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\r\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\r\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\r\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\r\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <EmbedManifest>false</EmbedManifest>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <EmbedManifest>false</EmbedManifest>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <EmbedManifest>false</EmbedManifest>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <EmbedManifest>false</EmbedManifest>\r\n  </PropertyGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <AdditionalIncludeDirectories>..;../main;../gnulib;../parsers;../parsers/cxx;../dsl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <MinimalRebuild>true</MinimalRebuild>\r\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <SubSystem>Console</SubSystem>\r\n      <TargetMachine>MachineX86</TargetMachine>\r\n      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\r\n    <ClCompile>\r\n      <Optimization>Disabled</Optimization>\r\n      <AdditionalIncludeDirectories>..;../main;../gnulib;../parsers;../parsers/cxx;../dsl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <SubSystem>Console</SubSystem>\r\n      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>..;../main;../gnulib;../parsers;../parsers/cxx;../dsl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <SubSystem>Console</SubSystem>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n      <TargetMachine>MachineX86</TargetMachine>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\r\n    <ClCompile>\r\n      <AdditionalIncludeDirectories>..;../main;../gnulib;../parsers;../parsers/cxx;../dsl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r\n      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r\n      <PrecompiledHeader>\r\n      </PrecompiledHeader>\r\n      <WarningLevel>Level3</WarningLevel>\r\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r\n    </ClCompile>\r\n    <Link>\r\n      <GenerateDebugInformation>true</GenerateDebugInformation>\r\n      <SubSystem>Console</SubSystem>\r\n      <OptimizeReferences>true</OptimizeReferences>\r\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r\n    </Link>\r\n  </ItemDefinitionGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"..\\dsl\\es.c\" />\r\n    <ClCompile Include=\"..\\dsl\\optscript.c\" />\r\n    <ClCompile Include=\"..\\gnulib\\fnmatch.c\" />\r\n    <ClCompile Include=\"..\\gnulib\\malloc\\dynarray_resize.c\" />\r\n    <ClCompile Include=\"..\\gnulib\\mempcpy.c\" />\r\n    <ClCompile Include=\"..\\gnulib\\nl_langinfo.c\" />\r\n    <ClCompile Include=\"..\\gnulib\\regex.c\" />\r\n    <ClCompile Include=\"..\\gnulib\\setlocale_null.c\" />\r\n    <ClCompile Include=\"..\\gnulib\\wmempcpy.c\" />\r\n    <ClCompile Include=\"..\\main\\CommonPrelude.c\" />\r\n    <ClCompile Include=\"..\\main\\args.c\" />\r\n    <ClCompile Include=\"..\\main\\cmd.c\" />\r\n    <ClCompile Include=\"..\\main\\collector.c\" />\r\n    <ClCompile Include=\"..\\main\\colprint.c\" />\r\n    <ClCompile Include=\"..\\main\\debug.c\" />\r\n    <ClCompile Include=\"..\\main\\dependency.c\" />\r\n    <ClCompile Include=\"..\\main\\entry.c\" />\r\n    <ClCompile Include=\"..\\main\\entry_private.c\" />\r\n    <ClCompile Include=\"..\\main\\error.c\" />\r\n    <ClCompile Include=\"..\\main\\field.c\" />\r\n    <ClCompile Include=\"..\\main\\flags.c\" />\r\n    <ClCompile Include=\"..\\main\\fmt.c\" />\r\n    <ClCompile Include=\"..\\main\\fname.c\" />\r\n    <ClCompile Include=\"..\\main\\htable.c\" />\r\n    <ClCompile Include=\"..\\main\\intern.c\" />\r\n    <ClCompile Include=\"..\\main\\keyword.c\" />\r\n    <ClCompile Include=\"..\\main\\kind.c\" />\r\n    <ClCompile Include=\"..\\main\\lregex-default.c\" />\r\n    <ClCompile Include=\"..\\main\\lregex.c\" />\r\n    <ClCompile Include=\"..\\main\\lxpath.c\" />\r\n    <ClCompile Include=\"..\\main\\main.c\" />\r\n    <ClCompile Include=\"..\\main\\mio.c\" />\r\n    <ClCompile Include=\"..\\main\\nestlevel.c\" />\r\n    <ClCompile Include=\"..\\main\\numarray.c\" />\r\n    <ClCompile Include=\"..\\main\\objpool.c\" />\r\n    <ClCompile Include=\"..\\main\\options.c\" />\r\n    <ClCompile Include=\"..\\main\\param.c\" />\r\n    <ClCompile Include=\"..\\main\\parse.c\" />\r\n    <ClCompile Include=\"..\\main\\portable-scandir.c\" />\r\n    <ClCompile Include=\"..\\main\\promise.c\" />\r\n    <ClCompile Include=\"..\\main\\ptag.c\" />\r\n    <ClCompile Include=\"..\\main\\ptrarray.c\" />\r\n    <ClCompile Include=\"..\\main\\rbtree.c\" />\r\n    <ClCompile Include=\"..\\main\\read.c\" />\r\n    <ClCompile Include=\"..\\main\\repoinfo.c\" />\r\n    <ClCompile Include=\"..\\main\\rexprcode.c\" />\r\n    <ClCompile Include=\"..\\main\\routines.c\" />\r\n    <ClCompile Include=\"..\\main\\script.c\" />\r\n    <ClCompile Include=\"..\\main\\selectors.c\" />\r\n    <ClCompile Include=\"..\\main\\sort.c\" />\r\n    <ClCompile Include=\"..\\main\\stats.c\" />\r\n    <ClCompile Include=\"..\\main\\strlist.c\" />\r\n    <ClCompile Include=\"..\\main\\tokeninfo.c\" />\r\n    <ClCompile Include=\"..\\main\\trashbox.c\" />\r\n    <ClCompile Include=\"..\\main\\unwindi.c\" />\r\n    <ClCompile Include=\"..\\main\\utf8_str.c\" />\r\n    <ClCompile Include=\"..\\main\\vstring.c\" />\r\n    <ClCompile Include=\"..\\main\\writer-ctags.c\" />\r\n    <ClCompile Include=\"..\\main\\writer-etags.c\" />\r\n    <ClCompile Include=\"..\\main\\writer-json.c\" />\r\n    <ClCompile Include=\"..\\main\\writer-xref.c\" />\r\n    <ClCompile Include=\"..\\main\\writer.c\" />\r\n    <ClCompile Include=\"..\\main\\xtag.c\" />\r\n    <ClCompile Include=\"..\\optlib\\cmake.c\" />\r\n    <ClCompile Include=\"..\\optlib\\ctags-optlib.c\" />\r\n    <ClCompile Include=\"..\\optlib\\elixir.c\" />\r\n    <ClCompile Include=\"..\\optlib\\forth.c\" />\r\n    <ClCompile Include=\"..\\optlib\\gdbinit.c\" />\r\n    <ClCompile Include=\"..\\optlib\\gomod.c\" />\r\n    <ClCompile Include=\"..\\optlib\\gperf.c\" />\r\n    <ClCompile Include=\"..\\optlib\\iPythonCell.c\" />\r\n    <ClCompile Include=\"..\\optlib\\inko.c\" />\r\n    <ClCompile Include=\"..\\optlib\\kconfig.c\" />\r\n    <ClCompile Include=\"..\\optlib\\lex.c\" />\r\n    <ClCompile Include=\"..\\optlib\\man.c\" />\r\n    <ClCompile Include=\"..\\optlib\\meson.c\" />\r\n    <ClCompile Include=\"..\\optlib\\mesonOptions.c\" />\r\n    <ClCompile Include=\"..\\optlib\\nftables.c\" />\r\n    <ClCompile Include=\"..\\optlib\\org.c\" />\r\n    <ClCompile Include=\"..\\optlib\\passwd.c\" />\r\n    <ClCompile Include=\"..\\optlib\\pkgConfig.c\" />\r\n    <ClCompile Include=\"..\\optlib\\pod.c\" />\r\n    <ClCompile Include=\"..\\optlib\\puppetManifest.c\" />\r\n    <ClCompile Include=\"..\\optlib\\qemuhx.c\" />\r\n    <ClCompile Include=\"..\\optlib\\rpmMacros.c\" />\r\n    <ClCompile Include=\"..\\optlib\\scdoc.c\" />\r\n    <ClCompile Include=\"..\\optlib\\scss.c\" />\r\n    <ClCompile Include=\"..\\optlib\\selinux-type-enforcement.c\" />\r\n    <ClCompile Include=\"..\\optlib\\systemtap.c\" />\r\n    <ClCompile Include=\"..\\optlib\\terraform.c\" />\r\n    <ClCompile Include=\"..\\optlib\\terraformvariables.c\" />\r\n    <ClCompile Include=\"..\\optlib\\yacc.c\" />\r\n    <ClCompile Include=\"..\\parsers\\abaqus.c\" />\r\n    <ClCompile Include=\"..\\parsers\\abc.c\" />\r\n    <ClCompile Include=\"..\\parsers\\ada.c\" />\r\n    <ClCompile Include=\"..\\parsers\\ant.c\" />\r\n    <ClCompile Include=\"..\\parsers\\asciidoc.c\" />\r\n    <ClCompile Include=\"..\\parsers\\asm.c\" />\r\n    <ClCompile Include=\"..\\parsers\\asp.c\" />\r\n    <ClCompile Include=\"..\\parsers\\autoconf.c\" />\r\n    <ClCompile Include=\"..\\parsers\\autoit.c\" />\r\n    <ClCompile Include=\"..\\parsers\\automake.c\" />\r\n    <ClCompile Include=\"..\\parsers\\awk.c\" />\r\n    <ClCompile Include=\"..\\parsers\\basic.c\" />\r\n    <ClCompile Include=\"..\\parsers\\bats.c\" />\r\n    <ClCompile Include=\"..\\parsers\\beta.c\" />\r\n    <ClCompile Include=\"..\\parsers\\biblatex.c\" />\r\n    <ClCompile Include=\"..\\parsers\\bibtex.c\" />\r\n    <ClCompile Include=\"..\\parsers\\c-based.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cargo.c\" />\r\n    <ClCompile Include=\"..\\parsers\\clojure.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cobol.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cpreprocessor.c\" />\r\n    <ClCompile Include=\"..\\parsers\\css.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_debug.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_debug_type.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_jni.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_keyword.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_block.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_function.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_lambda.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_module.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_namespace.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_template.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_tokenizer.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_typedef.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_using.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_variable.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_qtmoc.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_scope.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_side_chain.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_subparser.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_tag.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_token.c\" />\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_token_chain.c\" />\r\n    <ClCompile Include=\"..\\parsers\\dbus-service.c\" />\r\n    <ClCompile Include=\"..\\parsers\\diff.c\" />\r\n    <ClCompile Include=\"..\\parsers\\dosbatch.c\" />\r\n    <ClCompile Include=\"..\\parsers\\dtd.c\" />\r\n    <ClCompile Include=\"..\\parsers\\dts.c\" />\r\n    <ClCompile Include=\"..\\parsers\\eiffel.c\" />\r\n    <ClCompile Include=\"..\\parsers\\erlang.c\" />\r\n    <ClCompile Include=\"..\\parsers\\falcon.c\" />\r\n    <ClCompile Include=\"..\\parsers\\flex.c\" />\r\n    <ClCompile Include=\"..\\parsers\\fortran.c\" />\r\n    <ClCompile Include=\"..\\parsers\\frontmatter.c\" />\r\n    <ClCompile Include=\"..\\parsers\\fypp.c\" />\r\n    <ClCompile Include=\"..\\parsers\\gdscript.c\" />\r\n    <ClCompile Include=\"..\\parsers\\gemspec.c\" />\r\n    <ClCompile Include=\"..\\parsers\\go.c\" />\r\n    <ClCompile Include=\"..\\parsers\\haskell.c\" />\r\n    <ClCompile Include=\"..\\parsers\\haxe.c\" />\r\n    <ClCompile Include=\"..\\parsers\\html.c\" />\r\n    <ClCompile Include=\"..\\parsers\\iniconf.c\" />\r\n    <ClCompile Include=\"..\\parsers\\itcl.c\" />\r\n    <ClCompile Include=\"..\\parsers\\jprop.c\" />\r\n    <ClCompile Include=\"..\\parsers\\jscript.c\" />\r\n    <ClCompile Include=\"..\\parsers\\json.c\" />\r\n    <ClCompile Include=\"..\\parsers\\julia.c\" />\r\n    <ClCompile Include=\"..\\parsers\\ldscript.c\" />\r\n    <ClCompile Include=\"..\\parsers\\lisp.c\" />\r\n    <ClCompile Include=\"..\\parsers\\lua.c\" />\r\n    <ClCompile Include=\"..\\parsers\\m4.c\" />\r\n    <ClCompile Include=\"..\\parsers\\make.c\" />\r\n    <ClCompile Include=\"..\\parsers\\markdown.c\" />\r\n    <ClCompile Include=\"..\\parsers\\matlab.c\" />\r\n    <ClCompile Include=\"..\\parsers\\myrddin.c\" />\r\n    <ClCompile Include=\"..\\parsers\\nsis.c\" />\r\n    <ClCompile Include=\"..\\parsers\\objc.c\" />\r\n    <ClCompile Include=\"..\\parsers\\ocaml.c\" />\r\n    <ClCompile Include=\"..\\parsers\\odin.c\" />\r\n    <ClCompile Include=\"..\\parsers\\pascal.c\" />\r\n    <ClCompile Include=\"..\\parsers\\perl-function-parameters.c\" />\r\n    <ClCompile Include=\"..\\parsers\\perl-moose.c\" />\r\n    <ClCompile Include=\"..\\parsers\\perl.c\" />\r\n    <ClCompile Include=\"..\\parsers\\php.c\" />\r\n    <ClCompile Include=\"..\\parsers\\powershell.c\" />\r\n    <ClCompile Include=\"..\\parsers\\prolog.c\" />\r\n    <ClCompile Include=\"..\\parsers\\protobuf.c\" />\r\n    <ClCompile Include=\"..\\parsers\\python-entry-points.c\" />\r\n    <ClCompile Include=\"..\\parsers\\python-logging-config.c\" />\r\n    <ClCompile Include=\"..\\parsers\\python.c\" />\r\n    <ClCompile Include=\"..\\parsers\\quarto.c\" />\r\n    <ClCompile Include=\"..\\parsers\\r-r6class.c\" />\r\n    <ClCompile Include=\"..\\parsers\\r-s4class.c\" />\r\n    <ClCompile Include=\"..\\parsers\\r.c\" />\r\n    <ClCompile Include=\"..\\parsers\\rake.c\" />\r\n    <ClCompile Include=\"..\\parsers\\raku.c\" />\r\n    <ClCompile Include=\"..\\parsers\\rexx.c\" />\r\n    <ClCompile Include=\"..\\parsers\\rmarkdown.c\" />\r\n    <ClCompile Include=\"..\\parsers\\robot.c\" />\r\n    <ClCompile Include=\"..\\parsers\\rpmspec.c\" />\r\n    <ClCompile Include=\"..\\parsers\\rspec.c\" />\r\n    <ClCompile Include=\"..\\parsers\\rst.c\" />\r\n    <ClCompile Include=\"..\\parsers\\ruby.c\" />\r\n    <ClCompile Include=\"..\\parsers\\rust.c\" />\r\n    <ClCompile Include=\"..\\parsers\\scheme.c\" />\r\n    <ClCompile Include=\"..\\parsers\\selinux-interface.c\" />\r\n    <ClCompile Include=\"..\\parsers\\sh.c\" />\r\n    <ClCompile Include=\"..\\parsers\\sinex.c\" />\r\n    <ClCompile Include=\"..\\parsers\\slang.c\" />\r\n    <ClCompile Include=\"..\\parsers\\sml.c\" />\r\n    <ClCompile Include=\"..\\parsers\\sql.c\" />\r\n    <ClCompile Include=\"..\\parsers\\systemdunit.c\" />\r\n    <ClCompile Include=\"..\\parsers\\tcl.c\" />\r\n    <ClCompile Include=\"..\\parsers\\tcloo.c\" />\r\n    <ClCompile Include=\"..\\parsers\\tex-beamer.c\" />\r\n    <ClCompile Include=\"..\\parsers\\tex.c\" />\r\n    <ClCompile Include=\"..\\parsers\\ttcn.c\" />\r\n    <ClCompile Include=\"..\\parsers\\txt2tags.c\" />\r\n    <ClCompile Include=\"..\\parsers\\typescript.c\" />\r\n    <ClCompile Include=\"..\\parsers\\typespec.c\" />\r\n    <ClCompile Include=\"..\\parsers\\v.c\" />\r\n    <ClCompile Include=\"..\\parsers\\vera.c\" />\r\n    <ClCompile Include=\"..\\parsers\\verilog.c\" />\r\n    <ClCompile Include=\"..\\parsers\\vhdl.c\" />\r\n    <ClCompile Include=\"..\\parsers\\vim.c\" />\r\n    <ClCompile Include=\"..\\parsers\\windres.c\" />\r\n    <ClCompile Include=\"..\\parsers\\yumrepo.c\" />\r\n    <ClCompile Include=\"..\\win32\\mkstemp\\mkstemp.c\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"..\\dsl\\es.h\" />\r\n    <ClInclude Include=\"..\\dsl\\optscript.h\" />\r\n    <ClInclude Include=\"..\\gnulib\\fnmatch.h\" />\r\n    <ClInclude Include=\"..\\gnulib\\regex.h\" />\r\n    <ClInclude Include=\"..\\main\\args_p.h\" />\r\n    <ClInclude Include=\"..\\main\\collector.h\" />\r\n    <ClInclude Include=\"..\\main\\colprint_p.h\" />\r\n    <ClInclude Include=\"..\\main\\ctags.h\" />\r\n    <ClInclude Include=\"..\\main\\debug.h\" />\r\n    <ClInclude Include=\"..\\main\\dependency.h\" />\r\n    <ClInclude Include=\"..\\main\\dependency_p.h\" />\r\n    <ClInclude Include=\"..\\main\\e_msoft.h\" />\r\n    <ClInclude Include=\"..\\main\\entry.h\" />\r\n    <ClInclude Include=\"..\\main\\entry_p.h\" />\r\n    <ClInclude Include=\"..\\main\\error_p.h\" />\r\n    <ClInclude Include=\"..\\main\\field.h\" />\r\n    <ClInclude Include=\"..\\main\\field_p.h\" />\r\n    <ClInclude Include=\"..\\main\\flags_p.h\" />\r\n    <ClInclude Include=\"..\\main\\fmt_p.h\" />\r\n    <ClInclude Include=\"..\\main\\fname.h\" />\r\n    <ClInclude Include=\"..\\main\\gcc-attr.h\" />\r\n    <ClInclude Include=\"..\\main\\general.h\" />\r\n    <ClInclude Include=\"..\\main\\gvars.h\" />\r\n    <ClInclude Include=\"..\\main\\htable.h\" />\r\n    <ClInclude Include=\"..\\main\\inline.h\" />\r\n    <ClInclude Include=\"..\\main\\intern.h\" />\r\n    <ClInclude Include=\"..\\main\\interval_tree_generic.h\" />\r\n    <ClInclude Include=\"..\\main\\keyword.h\" />\r\n    <ClInclude Include=\"..\\main\\keyword_p.h\" />\r\n    <ClInclude Include=\"..\\main\\kind.h\" />\r\n    <ClInclude Include=\"..\\main\\kind_p.h\" />\r\n    <ClInclude Include=\"..\\main\\lregex.h\" />\r\n    <ClInclude Include=\"..\\main\\lregex_p.h\" />\r\n    <ClInclude Include=\"..\\main\\lxpath.h\" />\r\n    <ClInclude Include=\"..\\main\\lxpath_p.h\" />\r\n    <ClInclude Include=\"..\\main\\main_p.h\" />\r\n    <ClInclude Include=\"..\\main\\mio.h\" />\r\n    <ClInclude Include=\"..\\main\\nestlevel.h\" />\r\n    <ClInclude Include=\"..\\main\\numarray.h\" />\r\n    <ClInclude Include=\"..\\main\\objpool.h\" />\r\n    <ClInclude Include=\"..\\main\\options.h\" />\r\n    <ClInclude Include=\"..\\main\\options_p.h\" />\r\n    <ClInclude Include=\"..\\main\\param.h\" />\r\n    <ClInclude Include=\"..\\main\\param_p.h\" />\r\n    <ClInclude Include=\"..\\main\\parse.h\" />\r\n    <ClInclude Include=\"..\\main\\parse_p.h\" />\r\n    <ClInclude Include=\"..\\main\\parsers_p.h\" />\r\n    <ClInclude Include=\"..\\main\\portable-dirent_p.h\" />\r\n    <ClInclude Include=\"..\\main\\promise.h\" />\r\n    <ClInclude Include=\"..\\main\\promise_p.h\" />\r\n    <ClInclude Include=\"..\\main\\ptag_p.h\" />\r\n    <ClInclude Include=\"..\\main\\ptrarray.h\" />\r\n    <ClInclude Include=\"..\\main\\rbtree.h\" />\r\n    <ClInclude Include=\"..\\main\\rbtree_augmented.h\" />\r\n    <ClInclude Include=\"..\\main\\read.h\" />\r\n    <ClInclude Include=\"..\\main\\read_p.h\" />\r\n    <ClInclude Include=\"..\\main\\rexprcode_p.h\" />\r\n    <ClInclude Include=\"..\\main\\routines.h\" />\r\n    <ClInclude Include=\"..\\main\\routines_p.h\" />\r\n    <ClInclude Include=\"..\\main\\script_p.h\" />\r\n    <ClInclude Include=\"..\\main\\selectors.h\" />\r\n    <ClInclude Include=\"..\\main\\sort_p.h\" />\r\n    <ClInclude Include=\"..\\main\\sort_r.h\" />\r\n    <ClInclude Include=\"..\\main\\stats_p.h\" />\r\n    <ClInclude Include=\"..\\main\\strlist.h\" />\r\n    <ClInclude Include=\"..\\main\\subparser.h\" />\r\n    <ClInclude Include=\"..\\main\\subparser_p.h\" />\r\n    <ClInclude Include=\"..\\main\\tokeninfo.h\" />\r\n    <ClInclude Include=\"..\\main\\trashbox.h\" />\r\n    <ClInclude Include=\"..\\main\\trashbox_p.h\" />\r\n    <ClInclude Include=\"..\\main\\types.h\" />\r\n    <ClInclude Include=\"..\\main\\unwindi.h\" />\r\n    <ClInclude Include=\"..\\main\\utf8_str.h\" />\r\n    <ClInclude Include=\"..\\main\\vstring.h\" />\r\n    <ClInclude Include=\"..\\main\\writer_p.h\" />\r\n    <ClInclude Include=\"..\\main\\xtag.h\" />\r\n    <ClInclude Include=\"..\\main\\xtag_p.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_debug.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_keyword.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_parser.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_parser_internal.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_scope.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_side_chain.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_subparser.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_subparser_internal.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_tag.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_token.h\" />\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_token_chain.h\" />\r\n    <ClInclude Include=\"..\\parsers\\d-rust.h\" />\r\n    <ClInclude Include=\"..\\parsers\\d-typescript.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-autoconf.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-bibtex.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-cpreprocessor.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-frontmatter.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-html.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-iniconf.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-jscript.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-lisp.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-m4.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-make.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-markdown.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-perl.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-python.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-r.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-ruby.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-sh.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-systemdunit.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-tcl.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-tex.h\" />\r\n    <ClInclude Include=\"..\\parsers\\x-toml.h\" />\r\n    <ClInclude Include=\"resource.h\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ResourceCompile Include=\"ctags.rc\" />\r\n  </ItemGroup>\r\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\r\n  <ImportGroup Label=\"ExtensionTargets\">\r\n  </ImportGroup>\r\n</Project>"
  },
  {
    "path": "win32/ctags_vs2013.vcxproj.filters",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <ItemGroup>\r\n    <Filter Include=\"Source Files\">\r\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Header Files\">\r\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Resource Files\">\r\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\Parsers\">\r\n      <UniqueIdentifier>{f77929ed-5bdf-496f-9ea6-c3c6180e6ca5}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\optlib\">\r\n      <UniqueIdentifier>{3f3f2216-39c2-44f3-8bea-13db663a5c09}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\Parsers\\cxx\">\r\n      <UniqueIdentifier>{f9b4c892-3488-4eac-9ab2-b69086a06c43}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\win32\">\r\n      <UniqueIdentifier>{492b86f3-82b5-455e-89cb-b4213f937614}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\win32\\mkstemp\">\r\n      <UniqueIdentifier>{71dfb57e-e1b2-4795-96d8-05a2d16af795}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\gnulib\">\r\n      <UniqueIdentifier>{a49cb3ac-6c1b-4b33-9bb7-af130fadeee1}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\dsl\">\r\n      <UniqueIdentifier>{d6480ae4-8f0c-11eb-8e04-8c1645efab21}</UniqueIdentifier>\r\n    </Filter>\r\n    <Filter Include=\"Source Files\\Main\">\r\n      <UniqueIdentifier>{45974afc-d1c3-4696-a74a-60eeaa6e1441}</UniqueIdentifier>\r\n    </Filter>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClCompile Include=\"..\\dsl\\es.c\">\r\n      <Filter>Source Files\\dsl</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\dsl\\optscript.c\">\r\n      <Filter>Source Files\\dsl</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\gnulib\\fnmatch.c\">\r\n      <Filter>Source Files\\gnulib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\gnulib\\malloc\\dynarray_resize.c\">\r\n      <Filter>Source Files\\gnulib\\malloc</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\gnulib\\mempcpy.c\">\r\n      <Filter>Source Files\\gnulib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\gnulib\\nl_langinfo.c\">\r\n      <Filter>Source Files\\gnulib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\gnulib\\regex.c\">\r\n      <Filter>Source Files\\gnulib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\gnulib\\setlocale_null.c\">\r\n      <Filter>Source Files\\gnulib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\gnulib\\wmempcpy.c\">\r\n      <Filter>Source Files\\gnulib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\CommonPrelude.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\args.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\cmd.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\collector.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\colprint.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\debug.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\dependency.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\entry.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\entry_private.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\error.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\field.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\flags.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\fmt.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\fname.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\htable.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\intern.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\keyword.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\kind.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\lregex-default.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\lregex.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\lxpath.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\main.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\mio.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\nestlevel.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\numarray.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\objpool.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\options.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\param.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\parse.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\portable-scandir.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\promise.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\ptag.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\ptrarray.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\rbtree.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\read.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\repoinfo.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\rexprcode.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\routines.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\script.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\selectors.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\sort.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\stats.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\strlist.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\tokeninfo.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\trashbox.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\unwindi.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\utf8_str.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\vstring.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\writer-ctags.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\writer-etags.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\writer-json.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\writer-xref.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\writer.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\main\\xtag.c\">\r\n      <Filter>Source Files\\main</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\cmake.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\ctags-optlib.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\elixir.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\forth.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\gdbinit.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\gomod.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\gperf.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\iPythonCell.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\inko.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\kconfig.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\lex.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\man.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\meson.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\mesonOptions.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\nftables.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\org.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\passwd.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\pkgConfig.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\pod.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\puppetManifest.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\qemuhx.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\rpmMacros.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\scdoc.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\scss.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\selinux-type-enforcement.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\systemtap.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\terraform.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\terraformvariables.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\optlib\\yacc.c\">\r\n      <Filter>Source Files\\optlib</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\abaqus.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\abc.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\ada.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\ant.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\asciidoc.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\asm.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\asp.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\autoconf.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\autoit.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\automake.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\awk.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\basic.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\bats.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\beta.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\biblatex.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\bibtex.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\c-based.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cargo.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\clojure.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cobol.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cpreprocessor.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\css.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_debug.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_debug_type.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_jni.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_keyword.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_block.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_function.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_lambda.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_module.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_namespace.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_template.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_tokenizer.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_typedef.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_using.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_parser_variable.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_qtmoc.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_scope.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_side_chain.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_subparser.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_tag.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_token.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\cxx\\cxx_token_chain.c\">\r\n      <Filter>Source Files\\parsers\\cxx</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\dbus-service.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\diff.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\dosbatch.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\dtd.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\dts.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\eiffel.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\erlang.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\falcon.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\flex.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\fortran.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\frontmatter.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\fypp.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\gdscript.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\gemspec.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\go.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\haskell.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\haxe.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\html.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\iniconf.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\itcl.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\jprop.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\jscript.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\json.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\julia.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\ldscript.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\lisp.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\lua.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\m4.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\make.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\markdown.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\matlab.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\myrddin.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\nsis.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\objc.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\ocaml.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\odin.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\pascal.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\perl-function-parameters.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\perl-moose.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\perl.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\php.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\powershell.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\prolog.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\protobuf.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\python-entry-points.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\python-logging-config.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\python.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\quarto.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\r-r6class.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\r-s4class.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\r.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\rake.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\raku.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\rexx.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\rmarkdown.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\robot.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\rpmspec.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\rspec.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\rst.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\ruby.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\rust.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\scheme.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\selinux-interface.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\sh.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\sinex.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\slang.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\sml.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\sql.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\systemdunit.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\tcl.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\tcloo.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\tex-beamer.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\tex.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\ttcn.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\txt2tags.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\typescript.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\typespec.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\v.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\vera.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\verilog.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\vhdl.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\vim.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\windres.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\parsers\\yumrepo.c\">\r\n      <Filter>Source Files\\parsers</Filter>\r\n    </ClCompile>\r\n    <ClCompile Include=\"..\\win32\\mkstemp\\mkstemp.c\">\r\n      <Filter>Source Files\\win32\\mkstemp</Filter>\r\n    </ClCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ClInclude Include=\"..\\dsl\\es.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\dsl\\optscript.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\gnulib\\fnmatch.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\gnulib\\regex.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\args_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\collector.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\colprint_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\ctags.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\debug.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\dependency.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\dependency_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\e_msoft.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\entry.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\entry_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\error_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\field.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\field_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\flags_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\fmt_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\fname.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\gcc-attr.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\general.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\gvars.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\htable.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\inline.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\intern.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\interval_tree_generic.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\keyword.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\keyword_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\kind.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\kind_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\lregex.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\lregex_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\lxpath.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\lxpath_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\main_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\mio.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\nestlevel.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\numarray.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\objpool.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\options.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\options_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\param.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\param_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\parse.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\parse_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\parsers_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\portable-dirent_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\promise.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\promise_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\ptag_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\ptrarray.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\rbtree.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\rbtree_augmented.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\read.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\read_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\rexprcode_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\routines.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\routines_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\script_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\selectors.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\sort_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\sort_r.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\stats_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\strlist.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\subparser.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\subparser_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\tokeninfo.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\trashbox.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\trashbox_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\types.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\unwindi.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\utf8_str.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\vstring.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\writer_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\xtag.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\main\\xtag_p.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_debug.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_keyword.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_parser.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_parser_internal.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_scope.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_side_chain.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_subparser.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_subparser_internal.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_tag.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_token.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\cxx\\cxx_token_chain.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\d-rust.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\d-typescript.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-autoconf.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-bibtex.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-cpreprocessor.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-frontmatter.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-html.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-iniconf.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-jscript.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-lisp.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-m4.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-make.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-markdown.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-perl.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-python.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-r.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-ruby.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-sh.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-systemdunit.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-tcl.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-tex.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"..\\parsers\\x-toml.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n    <ClInclude Include=\"resource.h\">\r\n      <Filter>Header Files</Filter>\r\n    </ClInclude>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <ResourceCompile Include=\"ctags.rc\">\r\n      <Filter>Resource Files</Filter>\r\n    </ResourceCompile>\r\n  </ItemGroup>\r\n</Project>"
  },
  {
    "path": "win32/ctags_vs2013.vcxproj.filters.in",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>\n    </Filter>\n    <Filter Include=\"Source Files\\Parsers\">\n      <UniqueIdentifier>{f77929ed-5bdf-496f-9ea6-c3c6180e6ca5}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Source Files\\optlib\">\n      <UniqueIdentifier>{3f3f2216-39c2-44f3-8bea-13db663a5c09}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Source Files\\Parsers\\cxx\">\n      <UniqueIdentifier>{f9b4c892-3488-4eac-9ab2-b69086a06c43}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Source Files\\win32\">\n      <UniqueIdentifier>{492b86f3-82b5-455e-89cb-b4213f937614}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Source Files\\win32\\mkstemp\">\n      <UniqueIdentifier>{71dfb57e-e1b2-4795-96d8-05a2d16af795}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Source Files\\gnulib\">\n      <UniqueIdentifier>{a49cb3ac-6c1b-4b33-9bb7-af130fadeee1}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Source Files\\dsl\">\n      <UniqueIdentifier>{d6480ae4-8f0c-11eb-8e04-8c1645efab21}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Source Files\\Main\">\n      <UniqueIdentifier>{45974afc-d1c3-4696-a74a-60eeaa6e1441}</UniqueIdentifier>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n@SRCS@\n  </ItemGroup>\n  <ItemGroup>\n@HEADS@\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"ctags.rc\">\n      <Filter>Resource Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "win32/ctags_vs2013.vcxproj.in",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectName>ctags</ProjectName>\n    <ProjectGuid>{CE5CDD7C-2102-4753-8AAB-7915802BF658}</ProjectGuid>\n    <RootNamespace>ctags</RootNamespace>\n    <Keyword>Win32Proj</Keyword>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <PlatformToolset>v120</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <PlatformToolset>v120</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v120</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v120</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(SolutionDir)$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">$(Configuration)\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">true</LinkIncremental>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">true</LinkIncremental>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(SolutionDir)$(Configuration)\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">$(Configuration)\\</IntDir>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</LinkIncremental>\n    <LinkIncremental Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</LinkIncremental>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" />\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRuleSet Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">AllRules.ruleset</CodeAnalysisRuleSet>\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRules Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" />\n    <CodeAnalysisRuleAssemblies Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <EmbedManifest>false</EmbedManifest>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <EmbedManifest>false</EmbedManifest>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <EmbedManifest>false</EmbedManifest>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <EmbedManifest>false</EmbedManifest>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>@INC_DIRS@%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MinimalRebuild>true</MinimalRebuild>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <TargetMachine>MachineX86</TargetMachine>\n      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>@INC_DIRS@%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalIncludeDirectories>@INC_DIRS@%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <TargetMachine>MachineX86</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalIncludeDirectories>@INC_DIRS@%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n@SRCS@\n  </ItemGroup>\n  <ItemGroup>\n@HEADS@\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"ctags.rc\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "win32/gen-repoinfo.bat",
    "content": "@echo off\r\n:: Copyright (C) 2017 Ken Takata\r\n:: License: GPL-2 or later\r\n\r\nsetlocal\r\n\r\nif \"%1\"==\"\" (\r\n  echo Usage: gen-repoinfo ^<headerfile^>\r\n  goto :eof\r\n)\r\nset repoinfo_header=%1\r\n\r\nset oldinfo=\r\nif exist %repoinfo_header% (\r\n  for /f \"delims=\" %%i in (%1) do set oldinfo=%%i\r\n) else (\r\n  type nul > %repoinfo_header%\r\n)\r\n\r\nset newinfo=%oldinfo%\r\nif exist .git (\r\n  for /f %%i in ('cmd /c \"git describe --tag --exact-match HEAD 2> nul || git rev-parse --short HEAD\"') do set newinfo=#define CTAGS_REPOINFO \"%%i\"\r\n)\r\n\r\nif not \"%newinfo%\"==\"%oldinfo%\" echo %newinfo%> %repoinfo_header%\r\n"
  },
  {
    "path": "win32/gnulib_h/fnmatch.h",
    "content": "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\n/* Substitute for and wrapper around <fnmatch.h>.\n   Copyright (C) 1991-1993, 1996-1999, 2001-2003, 2005, 2007, 2009-2021 Free\n   Software Foundation, Inc.\n\n   This file is part of the GNU C Library.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _GL_FNMATCH_H\n\n#if __GNUC__ >= 3\n#pragma GCC system_header\n#endif\n\n\n/* The include_next requires a split double-inclusion guard.  */\n#if 0 && !1\n# include_next <fnmatch.h>\n#endif\n\n#ifndef _GL_FNMATCH_H\n#define _GL_FNMATCH_H\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n/* C++ compatible function declaration macros.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _GL_CXXDEFS_H\n#define _GL_CXXDEFS_H\n\n/* Begin/end the GNULIB_NAMESPACE namespace.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {\n# define _GL_END_NAMESPACE }\n#else\n# define _GL_BEGIN_NAMESPACE\n# define _GL_END_NAMESPACE\n#endif\n\n/* The three most frequent use cases of these macros are:\n\n   * For providing a substitute for a function that is missing on some\n     platforms, but is declared and works fine on the platforms on which\n     it exists:\n\n       #if @GNULIB_FOO@\n       # if !@HAVE_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       # endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on all platforms,\n     but is broken/insufficient and needs to be replaced on some platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on some platforms\n     but is broken/insufficient and needs to be replaced on some of them and\n     is additionally either missing or undeclared on some other platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       #  endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n*/\n\n/* _GL_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#if defined __cplusplus\n# define _GL_EXTERN_C extern \"C\"\n#else\n# define _GL_EXTERN_C extern\n#endif\n\n/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);\n   declares a replacement function, named rpl_func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \\\n  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)\n#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype rpl_func parameters_and_attributes\n\n/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);\n   declares the system function, named func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype func parameters_and_attributes\n\n/* _GL_CXXALIAS_RPL (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));\n\n   Wrapping rpl_func in an object with an inline conversion operator\n   avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#define _GL_CXXALIAS_RPL(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::rpl_func;                                  \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA (func, rettype, parameters);\n   is to be used when func is a Microsoft deprecated alias, on native Windows.\n   It declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to _func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));\n */\n#define _GL_CXXALIAS_MDA(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);\n   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);\n   except that the C function rpl_func may have a slightly different\n   declaration.  A cast is used to silence the \"invalid conversion\" error\n   that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                     \\\n    {                                                              \\\n      static const struct _gl_ ## func ## _wrapper                 \\\n      {                                                            \\\n        typedef rettype (*type) parameters;                        \\\n                                                                   \\\n        inline operator type () const                              \\\n        {                                                          \\\n          return reinterpret_cast<type>(::rpl_func);               \\\n        }                                                          \\\n      } func = {};                                                 \\\n    }                                                              \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_MDA (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_SYS (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to the system provided function func, if GNULIB_NAMESPACE\n   is defined.\n   Example:\n     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));\n\n   Wrapping func in an object with an inline conversion operator\n   avoids a reference to func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS(func,rettype,parameters)            \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::func;                                      \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                          \\\n    {                                                   \\\n      static const struct _gl_ ## func ## _wrapper      \\\n      {                                                 \\\n        typedef rettype (*type) parameters;             \\\n                                                        \\\n        inline operator type () const                   \\\n        {                                               \\\n          return reinterpret_cast<type>(::func);        \\\n        }                                               \\\n      } func = {};                                      \\\n    }                                                   \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function is picked among a set of overloaded functions,\n   namely the one with rettype2 and parameters2.  Two consecutive casts\n   are used to silence the \"cannot find a match\" and \"invalid conversion\"\n   errors that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n  /* The outer cast must be a reinterpret_cast.\n     The inner cast: When the function is defined as a set of overloaded\n     functions, it works as a static_cast<>, choosing the designated variant.\n     When the function is defined as a single variant, it works as a\n     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    namespace GNULIB_NAMESPACE                                                \\\n    {                                                                         \\\n      static const struct _gl_ ## func ## _wrapper                            \\\n      {                                                                       \\\n        typedef rettype (*type) parameters;                                   \\\n                                                                              \\\n        inline operator type () const                                         \\\n        {                                                                     \\\n          return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \\\n        }                                                                     \\\n      } func = {};                                                            \\\n    }                                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN (func);\n   causes a warning to be emitted when ::func is used but not when\n   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded\n   variants.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN(func) \\\n   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN_1(func,namespace) \\\n   _GL_CXXALIASWARN_2 (func, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n    _GL_WARN_ON_USE (func, \\\n                     \"The symbol ::\" #func \" refers to the system function. \" \\\n                     \"Use \" #namespace \"::\" #func \" instead.\")\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     extern __typeof__ (func) func\n# else\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN(func) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);\n   causes a warning to be emitted when the given overloaded variant of ::func\n   is used but not when GNULIB_NAMESPACE::func is used.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \\\n                        GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \\\n   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n    _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \\\n                         \"The symbol ::\" #func \" refers to the system function. \" \\\n                         \"Use \" #namespace \"::\" #func \" instead.\")\n# else\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n#endif /* _GL_CXXDEFS_H */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n/* A C macro for declaring that specific arguments must not be NULL.\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools\n   that the values passed as arguments n, ..., m must be non-NULL pointers.\n   n = 1 stands for the first argument, n = 2 for the second argument etc.  */\n#ifndef _GL_ARG_NONNULL\n# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__\n#  define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))\n# else\n#  define _GL_ARG_NONNULL(params)\n# endif\n#endif\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n/* A C macro for emitting warnings if a function is used.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_WARN_ON_USE (function, \"literal string\") issues a declaration\n   for FUNCTION which will then trigger a compiler warning containing\n   the text of \"literal string\" anywhere that function is called, if\n   supported by the compiler.  If the compiler does not support this\n   feature, the macro expands to an unused extern declaration.\n\n   _GL_WARN_ON_USE_ATTRIBUTE (\"literal string\") expands to the\n   attribute used in _GL_WARN_ON_USE.  If the compiler does not support\n   this feature, it expands to empty.\n\n   These macros are useful for marking a function as a potential\n   portability trap, with the intent that \"literal string\" include\n   instructions on the replacement function that should be used\n   instead.\n   _GL_WARN_ON_USE is for functions with 'extern' linkage.\n   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'\n   linkage.\n\n   However, one of the reasons that a function is a portability trap is\n   if it has the wrong signature.  Declaring FUNCTION with a different\n   signature in C is a compilation error, so this macro must use the\n   same type as any existing declaration so that programs that avoid\n   the problematic FUNCTION do not fail to compile merely because they\n   included a header that poisoned the function.  But this implies that\n   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already\n   have a declaration.  Use of this macro implies that there must not\n   be any other macro hiding the declaration of FUNCTION; but\n   undefining FUNCTION first is part of the poisoning process anyway\n   (although for symbols that are provided only via a macro, the result\n   is a compilation error rather than a warning containing\n   \"literal string\").  Also note that in C++, it is only safe to use if\n   FUNCTION has no overloads.\n\n   For an example, it is possible to poison 'getline' by:\n   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],\n     [getline]) in configure.ac, which potentially defines\n     HAVE_RAW_DECL_GETLINE\n   - adding this code to a header that wraps the system <stdio.h>:\n     #undef getline\n     #if HAVE_RAW_DECL_GETLINE\n     _GL_WARN_ON_USE (getline, \"getline is required by POSIX 2008, but\"\n       \"not universally present; use the gnulib module getline\");\n     #endif\n\n   It is not possible to directly poison global variables.  But it is\n   possible to write a wrapper accessor function, and poison that\n   (less common usage, like &environ, will cause a compilation error\n   rather than issue the nice warning, but the end result of informing\n   the developer about their portability problem is still achieved):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     rpl_environ (void) { return &environ; }\n     _GL_WARN_ON_USE (rpl_environ, \"environ is not always properly declared\");\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   or better (avoiding contradictory use of 'static' and 'extern'):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     _GL_WARN_ON_USE_ATTRIBUTE (\"environ is not always properly declared\")\n     rpl_environ (void) { return &environ; }\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   */\n#ifndef _GL_WARN_ON_USE\n\n# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function __attribute__ ((__warning__ (message)))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__warning__ (message)))\n# elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# else /* Unsupported.  */\n#  define _GL_WARN_ON_USE(function, message) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# endif\n#endif\n\n/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, \"message\")\n   is like _GL_WARN_ON_USE (function, \"message\"), except that in C++ mode the\n   function is declared with the given prototype, consisting of return type,\n   parameters, and attributes.\n   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does\n   not work in this case.  */\n#ifndef _GL_WARN_ON_USE_CXX\n# if !defined __cplusplus\n#  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n     _GL_WARN_ON_USE (function, msg)\n# else\n#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes \\\n  __attribute__ ((__warning__ (msg)))\n#  elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_clang function parameters_and_attributes \\\n  __attribute__ ((__diagnose_if__ (1, msg, \"warning\")))\n#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes\n#  else /* Unsupported.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  endif\n# endif\n#endif\n\n/* _GL_WARN_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#ifndef _GL_WARN_EXTERN_C\n# if defined __cplusplus\n#  define _GL_WARN_EXTERN_C extern \"C\"\n# else\n#  define _GL_WARN_EXTERN_C extern\n# endif\n#endif\n\n#if !0 || 1\n\n/* We #undef these before defining them because some losing systems\n   (HP-UX A.08.07 for example) define these in <unistd.h>.  */\n#undef  FNM_PATHNAME\n#undef  FNM_NOESCAPE\n#undef  FNM_PERIOD\n\n/* Bits set in the FLAGS argument to 'fnmatch'.  */\n#define FNM_PATHNAME    (1 << 0) /* No wildcard can ever match '/'.  */\n#define FNM_NOESCAPE    (1 << 1) /* Backslashes don't quote special chars.  */\n#define FNM_PERIOD      (1 << 2) /* Leading '.' is matched only explicitly.  */\n\n#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE\n# define FNM_FILE_NAME   FNM_PATHNAME   /* Preferred GNU name.  */\n# define FNM_LEADING_DIR (1 << 3)       /* Ignore '/...' after a match.  */\n# define FNM_CASEFOLD    (1 << 4)       /* Compare without regard to case.  */\n# define FNM_EXTMATCH    (1 << 5)       /* Use ksh-like extended matching. */\n#endif\n\n/* Value returned by 'fnmatch' if STRING does not match PATTERN.  */\n#define FNM_NOMATCH     1\n\n/* This value is returned if the implementation does not support\n   'fnmatch'.  Since this is not the case here it will never be\n   returned but the conformance test suites still require the symbol\n   to be defined.  */\n#ifdef _XOPEN_SOURCE\n# define FNM_NOSYS      (-1)\n#endif\n\n#endif\n\n\n#if 1\n/* Match NAME against the file name pattern PATTERN,\n   returning zero if it matches, FNM_NOMATCH if not.  */\n# if 1\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define fnmatch rpl_fnmatch\n#  endif\n_GL_FUNCDECL_RPL (fnmatch, int,\n                  (const char *pattern, const char *name, int flags)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (fnmatch, int,\n                  (const char *pattern, const char *name, int flags));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (fnmatch, int,\n                  (const char *pattern, const char *name, int flags)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (fnmatch, int,\n                  (const char *pattern, const char *name, int flags));\n# endif\n# if !GNULIB_FNMATCH_GNU && __GLIBC__ >= 2\n_GL_CXXALIASWARN (fnmatch);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef fnmatch\n# if HAVE_RAW_DECL_FNMATCH\n_GL_WARN_ON_USE (fnmatch,\n                 \"fnmatch does not portably work - \"\n                 \"use gnulib module fnmatch for portability or gnulib module fnmatch-gnu for a glibc compatible implementation\");\n# endif\n#endif\n\n\n#endif /* _GL_FNMATCH_H */\n#endif /* _GL_FNMATCH_H */\n"
  },
  {
    "path": "win32/gnulib_h/langinfo.h",
    "content": "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\n/* Substitute for and wrapper around <langinfo.h>.\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/*\n * POSIX <langinfo.h> for platforms that lack it or have an incomplete one.\n * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/langinfo.h.html>\n */\n\n#ifndef _GL_LANGINFO_H\n\n#if __GNUC__ >= 3\n#pragma GCC system_header\n#endif\n\n\n/* The include_next requires a split double-inclusion guard.  */\n#if 0\n# include_next <langinfo.h>\n#endif\n\n#ifndef _GL_LANGINFO_H\n#define _GL_LANGINFO_H\n\n\n#if !0\n\n/* A platform that lacks <langinfo.h>.  */\n\n/* Assume that it also lacks <nl_types.h> and the nl_item type.  */\n# if !GNULIB_defined_nl_item\ntypedef int nl_item;\n#  define GNULIB_defined_nl_item 1\n# endif\n\n/* nl_langinfo items of the LC_CTYPE category */\n# define CODESET     10000\n/* nl_langinfo items of the LC_NUMERIC category */\n# define RADIXCHAR   10001\n# define DECIMAL_POINT RADIXCHAR\n# define THOUSEP     10002\n# define THOUSANDS_SEP THOUSEP\n# define GROUPING    10114\n/* nl_langinfo items of the LC_TIME category */\n# define D_T_FMT     10003\n# define D_FMT       10004\n# define T_FMT       10005\n# define T_FMT_AMPM  10006\n# define AM_STR      10007\n# define PM_STR      10008\n# define DAY_1       10009\n# define DAY_2       (DAY_1 + 1)\n# define DAY_3       (DAY_1 + 2)\n# define DAY_4       (DAY_1 + 3)\n# define DAY_5       (DAY_1 + 4)\n# define DAY_6       (DAY_1 + 5)\n# define DAY_7       (DAY_1 + 6)\n# define ABDAY_1     10016\n# define ABDAY_2     (ABDAY_1 + 1)\n# define ABDAY_3     (ABDAY_1 + 2)\n# define ABDAY_4     (ABDAY_1 + 3)\n# define ABDAY_5     (ABDAY_1 + 4)\n# define ABDAY_6     (ABDAY_1 + 5)\n# define ABDAY_7     (ABDAY_1 + 6)\n# define MON_1       10023\n# define MON_2       (MON_1 + 1)\n# define MON_3       (MON_1 + 2)\n# define MON_4       (MON_1 + 3)\n# define MON_5       (MON_1 + 4)\n# define MON_6       (MON_1 + 5)\n# define MON_7       (MON_1 + 6)\n# define MON_8       (MON_1 + 7)\n# define MON_9       (MON_1 + 8)\n# define MON_10      (MON_1 + 9)\n# define MON_11      (MON_1 + 10)\n# define MON_12      (MON_1 + 11)\n# define ALTMON_1    10200\n# define ALTMON_2    (ALTMON_1 + 1)\n# define ALTMON_3    (ALTMON_1 + 2)\n# define ALTMON_4    (ALTMON_1 + 3)\n# define ALTMON_5    (ALTMON_1 + 4)\n# define ALTMON_6    (ALTMON_1 + 5)\n# define ALTMON_7    (ALTMON_1 + 6)\n# define ALTMON_8    (ALTMON_1 + 7)\n# define ALTMON_9    (ALTMON_1 + 8)\n# define ALTMON_10   (ALTMON_1 + 9)\n# define ALTMON_11   (ALTMON_1 + 10)\n# define ALTMON_12   (ALTMON_1 + 11)\n# define ABMON_1     10035\n# define ABMON_2     (ABMON_1 + 1)\n# define ABMON_3     (ABMON_1 + 2)\n# define ABMON_4     (ABMON_1 + 3)\n# define ABMON_5     (ABMON_1 + 4)\n# define ABMON_6     (ABMON_1 + 5)\n# define ABMON_7     (ABMON_1 + 6)\n# define ABMON_8     (ABMON_1 + 7)\n# define ABMON_9     (ABMON_1 + 8)\n# define ABMON_10    (ABMON_1 + 9)\n# define ABMON_11    (ABMON_1 + 10)\n# define ABMON_12    (ABMON_1 + 11)\n# define ERA         10047\n# define ERA_D_FMT   10048\n# define ERA_D_T_FMT 10049\n# define ERA_T_FMT   10050\n# define ALT_DIGITS  10051\n/* nl_langinfo items of the LC_MONETARY category */\n# define CRNCYSTR    10052\n# define CURRENCY_SYMBOL   CRNCYSTR\n# define INT_CURR_SYMBOL   10100\n# define MON_DECIMAL_POINT 10101\n# define MON_THOUSANDS_SEP 10102\n# define MON_GROUPING      10103\n# define POSITIVE_SIGN     10104\n# define NEGATIVE_SIGN     10105\n# define FRAC_DIGITS       10106\n# define INT_FRAC_DIGITS   10107\n# define P_CS_PRECEDES     10108\n# define N_CS_PRECEDES     10109\n# define P_SEP_BY_SPACE    10110\n# define N_SEP_BY_SPACE    10111\n# define P_SIGN_POSN       10112\n# define N_SIGN_POSN       10113\n/* nl_langinfo items of the LC_MESSAGES category */\n# define YESEXPR     10053\n# define NOEXPR      10054\n\n#else\n\n/* A platform that has <langinfo.h>.  */\n\n# if !0\n#  define CODESET     10000\n#  define GNULIB_defined_CODESET 1\n# endif\n\n# if !0\n#  define T_FMT_AMPM  10006\n#  define GNULIB_defined_T_FMT_AMPM 1\n# endif\n\n# if !0\n#  define ALTMON_1    10200\n#  define ALTMON_2    (ALTMON_1 + 1)\n#  define ALTMON_3    (ALTMON_1 + 2)\n#  define ALTMON_4    (ALTMON_1 + 3)\n#  define ALTMON_5    (ALTMON_1 + 4)\n#  define ALTMON_6    (ALTMON_1 + 5)\n#  define ALTMON_7    (ALTMON_1 + 6)\n#  define ALTMON_8    (ALTMON_1 + 7)\n#  define ALTMON_9    (ALTMON_1 + 8)\n#  define ALTMON_10   (ALTMON_1 + 9)\n#  define ALTMON_11   (ALTMON_1 + 10)\n#  define ALTMON_12   (ALTMON_1 + 11)\n#  define GNULIB_defined_ALTMON 1\n# endif\n\n# if !0\n#  define ERA         10047\n#  define ERA_D_FMT   10048\n#  define ERA_D_T_FMT 10049\n#  define ERA_T_FMT   10050\n#  define ALT_DIGITS  10051\n#  define GNULIB_defined_ERA 1\n# endif\n\n# if !0\n#  define YESEXPR     10053\n#  define NOEXPR      10054\n#  define GNULIB_defined_YESEXPR 1\n# endif\n\n#endif\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n/* C++ compatible function declaration macros.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _GL_CXXDEFS_H\n#define _GL_CXXDEFS_H\n\n/* Begin/end the GNULIB_NAMESPACE namespace.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {\n# define _GL_END_NAMESPACE }\n#else\n# define _GL_BEGIN_NAMESPACE\n# define _GL_END_NAMESPACE\n#endif\n\n/* The three most frequent use cases of these macros are:\n\n   * For providing a substitute for a function that is missing on some\n     platforms, but is declared and works fine on the platforms on which\n     it exists:\n\n       #if @GNULIB_FOO@\n       # if !@HAVE_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       # endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on all platforms,\n     but is broken/insufficient and needs to be replaced on some platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on some platforms\n     but is broken/insufficient and needs to be replaced on some of them and\n     is additionally either missing or undeclared on some other platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       #  endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n*/\n\n/* _GL_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#if defined __cplusplus\n# define _GL_EXTERN_C extern \"C\"\n#else\n# define _GL_EXTERN_C extern\n#endif\n\n/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);\n   declares a replacement function, named rpl_func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \\\n  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)\n#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype rpl_func parameters_and_attributes\n\n/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);\n   declares the system function, named func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype func parameters_and_attributes\n\n/* _GL_CXXALIAS_RPL (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));\n\n   Wrapping rpl_func in an object with an inline conversion operator\n   avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#define _GL_CXXALIAS_RPL(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::rpl_func;                                  \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA (func, rettype, parameters);\n   is to be used when func is a Microsoft deprecated alias, on native Windows.\n   It declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to _func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));\n */\n#define _GL_CXXALIAS_MDA(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);\n   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);\n   except that the C function rpl_func may have a slightly different\n   declaration.  A cast is used to silence the \"invalid conversion\" error\n   that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                     \\\n    {                                                              \\\n      static const struct _gl_ ## func ## _wrapper                 \\\n      {                                                            \\\n        typedef rettype (*type) parameters;                        \\\n                                                                   \\\n        inline operator type () const                              \\\n        {                                                          \\\n          return reinterpret_cast<type>(::rpl_func);               \\\n        }                                                          \\\n      } func = {};                                                 \\\n    }                                                              \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_MDA (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_SYS (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to the system provided function func, if GNULIB_NAMESPACE\n   is defined.\n   Example:\n     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));\n\n   Wrapping func in an object with an inline conversion operator\n   avoids a reference to func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS(func,rettype,parameters)            \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::func;                                      \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                          \\\n    {                                                   \\\n      static const struct _gl_ ## func ## _wrapper      \\\n      {                                                 \\\n        typedef rettype (*type) parameters;             \\\n                                                        \\\n        inline operator type () const                   \\\n        {                                               \\\n          return reinterpret_cast<type>(::func);        \\\n        }                                               \\\n      } func = {};                                      \\\n    }                                                   \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function is picked among a set of overloaded functions,\n   namely the one with rettype2 and parameters2.  Two consecutive casts\n   are used to silence the \"cannot find a match\" and \"invalid conversion\"\n   errors that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n  /* The outer cast must be a reinterpret_cast.\n     The inner cast: When the function is defined as a set of overloaded\n     functions, it works as a static_cast<>, choosing the designated variant.\n     When the function is defined as a single variant, it works as a\n     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    namespace GNULIB_NAMESPACE                                                \\\n    {                                                                         \\\n      static const struct _gl_ ## func ## _wrapper                            \\\n      {                                                                       \\\n        typedef rettype (*type) parameters;                                   \\\n                                                                              \\\n        inline operator type () const                                         \\\n        {                                                                     \\\n          return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \\\n        }                                                                     \\\n      } func = {};                                                            \\\n    }                                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN (func);\n   causes a warning to be emitted when ::func is used but not when\n   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded\n   variants.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN(func) \\\n   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN_1(func,namespace) \\\n   _GL_CXXALIASWARN_2 (func, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n    _GL_WARN_ON_USE (func, \\\n                     \"The symbol ::\" #func \" refers to the system function. \" \\\n                     \"Use \" #namespace \"::\" #func \" instead.\")\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     extern __typeof__ (func) func\n# else\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN(func) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);\n   causes a warning to be emitted when the given overloaded variant of ::func\n   is used but not when GNULIB_NAMESPACE::func is used.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \\\n                        GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \\\n   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n    _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \\\n                         \"The symbol ::\" #func \" refers to the system function. \" \\\n                         \"Use \" #namespace \"::\" #func \" instead.\")\n# else\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n#endif /* _GL_CXXDEFS_H */\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n/* A C macro for emitting warnings if a function is used.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_WARN_ON_USE (function, \"literal string\") issues a declaration\n   for FUNCTION which will then trigger a compiler warning containing\n   the text of \"literal string\" anywhere that function is called, if\n   supported by the compiler.  If the compiler does not support this\n   feature, the macro expands to an unused extern declaration.\n\n   _GL_WARN_ON_USE_ATTRIBUTE (\"literal string\") expands to the\n   attribute used in _GL_WARN_ON_USE.  If the compiler does not support\n   this feature, it expands to empty.\n\n   These macros are useful for marking a function as a potential\n   portability trap, with the intent that \"literal string\" include\n   instructions on the replacement function that should be used\n   instead.\n   _GL_WARN_ON_USE is for functions with 'extern' linkage.\n   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'\n   linkage.\n\n   However, one of the reasons that a function is a portability trap is\n   if it has the wrong signature.  Declaring FUNCTION with a different\n   signature in C is a compilation error, so this macro must use the\n   same type as any existing declaration so that programs that avoid\n   the problematic FUNCTION do not fail to compile merely because they\n   included a header that poisoned the function.  But this implies that\n   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already\n   have a declaration.  Use of this macro implies that there must not\n   be any other macro hiding the declaration of FUNCTION; but\n   undefining FUNCTION first is part of the poisoning process anyway\n   (although for symbols that are provided only via a macro, the result\n   is a compilation error rather than a warning containing\n   \"literal string\").  Also note that in C++, it is only safe to use if\n   FUNCTION has no overloads.\n\n   For an example, it is possible to poison 'getline' by:\n   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],\n     [getline]) in configure.ac, which potentially defines\n     HAVE_RAW_DECL_GETLINE\n   - adding this code to a header that wraps the system <stdio.h>:\n     #undef getline\n     #if HAVE_RAW_DECL_GETLINE\n     _GL_WARN_ON_USE (getline, \"getline is required by POSIX 2008, but\"\n       \"not universally present; use the gnulib module getline\");\n     #endif\n\n   It is not possible to directly poison global variables.  But it is\n   possible to write a wrapper accessor function, and poison that\n   (less common usage, like &environ, will cause a compilation error\n   rather than issue the nice warning, but the end result of informing\n   the developer about their portability problem is still achieved):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     rpl_environ (void) { return &environ; }\n     _GL_WARN_ON_USE (rpl_environ, \"environ is not always properly declared\");\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   or better (avoiding contradictory use of 'static' and 'extern'):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     _GL_WARN_ON_USE_ATTRIBUTE (\"environ is not always properly declared\")\n     rpl_environ (void) { return &environ; }\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   */\n#ifndef _GL_WARN_ON_USE\n\n# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function __attribute__ ((__warning__ (message)))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__warning__ (message)))\n# elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# else /* Unsupported.  */\n#  define _GL_WARN_ON_USE(function, message) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# endif\n#endif\n\n/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, \"message\")\n   is like _GL_WARN_ON_USE (function, \"message\"), except that in C++ mode the\n   function is declared with the given prototype, consisting of return type,\n   parameters, and attributes.\n   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does\n   not work in this case.  */\n#ifndef _GL_WARN_ON_USE_CXX\n# if !defined __cplusplus\n#  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n     _GL_WARN_ON_USE (function, msg)\n# else\n#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes \\\n  __attribute__ ((__warning__ (msg)))\n#  elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_clang function parameters_and_attributes \\\n  __attribute__ ((__diagnose_if__ (1, msg, \"warning\")))\n#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes\n#  else /* Unsupported.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  endif\n# endif\n#endif\n\n/* _GL_WARN_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#ifndef _GL_WARN_EXTERN_C\n# if defined __cplusplus\n#  define _GL_WARN_EXTERN_C extern \"C\"\n# else\n#  define _GL_WARN_EXTERN_C extern\n# endif\n#endif\n\n/* Declare overridden functions.  */\n\n\n/* Return a piece of locale dependent information.\n   Note: The difference between nl_langinfo (CODESET) and locale_charset ()\n   is that the latter normalizes the encoding names to GNU conventions.  */\n\n#if 1\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef nl_langinfo\n#   define nl_langinfo rpl_nl_langinfo\n#  endif\n_GL_FUNCDECL_RPL (nl_langinfo, char *, (nl_item item));\n_GL_CXXALIAS_RPL (nl_langinfo, char *, (nl_item item));\n# else\n#  if !0\n_GL_FUNCDECL_SYS (nl_langinfo, char *, (nl_item item));\n#  endif\n_GL_CXXALIAS_SYS (nl_langinfo, char *, (nl_item item));\n# endif\n_GL_CXXALIASWARN (nl_langinfo);\n#elif defined GNULIB_POSIXCHECK\n# undef nl_langinfo\n# if HAVE_RAW_DECL_NL_LANGINFO\n_GL_WARN_ON_USE (nl_langinfo, \"nl_langinfo is not portable - \"\n                 \"use gnulib module nl_langinfo for portability\");\n# endif\n#endif\n\n\n#endif /* _GL_LANGINFO_H */\n#endif /* _GL_LANGINFO_H */\n"
  },
  {
    "path": "win32/gnulib_h/locale.h",
    "content": "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\n/* A POSIX <locale.h>.\n   Copyright (C) 2007-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#if __GNUC__ >= 3\n#pragma GCC system_header\n#endif\n\n\n#if (defined _WIN32 && !defined __CYGWIN__ && defined __need_locale_t) \\\n    || defined _GL_ALREADY_INCLUDING_LOCALE_H\n\n/* Special invocation convention:\n   - Inside mingw header files,\n   - To handle Solaris header files (through Solaris 10) when combined\n     with gettext's libintl.h.  */\n\n#include_next <locale.h>\n\n#else\n/* Normal invocation convention.  */\n\n#ifndef _GL_LOCALE_H\n\n#define _GL_ALREADY_INCLUDING_LOCALE_H\n\n/* The include_next requires a split double-inclusion guard.  */\n#include_next <locale.h>\n\n#undef _GL_ALREADY_INCLUDING_LOCALE_H\n\n#ifndef _GL_LOCALE_H\n#define _GL_LOCALE_H\n\n/* NetBSD 5.0 mis-defines NULL.  */\n#include <stddef.h>\n\n/* Mac OS X 10.5 defines the locale_t type in <xlocale.h>.  */\n#if 0\n# include <xlocale.h>\n#endif\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n/* C++ compatible function declaration macros.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _GL_CXXDEFS_H\n#define _GL_CXXDEFS_H\n\n/* Begin/end the GNULIB_NAMESPACE namespace.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {\n# define _GL_END_NAMESPACE }\n#else\n# define _GL_BEGIN_NAMESPACE\n# define _GL_END_NAMESPACE\n#endif\n\n/* The three most frequent use cases of these macros are:\n\n   * For providing a substitute for a function that is missing on some\n     platforms, but is declared and works fine on the platforms on which\n     it exists:\n\n       #if @GNULIB_FOO@\n       # if !@HAVE_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       # endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on all platforms,\n     but is broken/insufficient and needs to be replaced on some platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on some platforms\n     but is broken/insufficient and needs to be replaced on some of them and\n     is additionally either missing or undeclared on some other platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       #  endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n*/\n\n/* _GL_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#if defined __cplusplus\n# define _GL_EXTERN_C extern \"C\"\n#else\n# define _GL_EXTERN_C extern\n#endif\n\n/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);\n   declares a replacement function, named rpl_func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \\\n  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)\n#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype rpl_func parameters_and_attributes\n\n/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);\n   declares the system function, named func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype func parameters_and_attributes\n\n/* _GL_CXXALIAS_RPL (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));\n\n   Wrapping rpl_func in an object with an inline conversion operator\n   avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#define _GL_CXXALIAS_RPL(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::rpl_func;                                  \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA (func, rettype, parameters);\n   is to be used when func is a Microsoft deprecated alias, on native Windows.\n   It declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to _func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));\n */\n#define _GL_CXXALIAS_MDA(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);\n   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);\n   except that the C function rpl_func may have a slightly different\n   declaration.  A cast is used to silence the \"invalid conversion\" error\n   that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                     \\\n    {                                                              \\\n      static const struct _gl_ ## func ## _wrapper                 \\\n      {                                                            \\\n        typedef rettype (*type) parameters;                        \\\n                                                                   \\\n        inline operator type () const                              \\\n        {                                                          \\\n          return reinterpret_cast<type>(::rpl_func);               \\\n        }                                                          \\\n      } func = {};                                                 \\\n    }                                                              \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_MDA (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_SYS (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to the system provided function func, if GNULIB_NAMESPACE\n   is defined.\n   Example:\n     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));\n\n   Wrapping func in an object with an inline conversion operator\n   avoids a reference to func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS(func,rettype,parameters)            \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::func;                                      \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                          \\\n    {                                                   \\\n      static const struct _gl_ ## func ## _wrapper      \\\n      {                                                 \\\n        typedef rettype (*type) parameters;             \\\n                                                        \\\n        inline operator type () const                   \\\n        {                                               \\\n          return reinterpret_cast<type>(::func);        \\\n        }                                               \\\n      } func = {};                                      \\\n    }                                                   \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function is picked among a set of overloaded functions,\n   namely the one with rettype2 and parameters2.  Two consecutive casts\n   are used to silence the \"cannot find a match\" and \"invalid conversion\"\n   errors that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n  /* The outer cast must be a reinterpret_cast.\n     The inner cast: When the function is defined as a set of overloaded\n     functions, it works as a static_cast<>, choosing the designated variant.\n     When the function is defined as a single variant, it works as a\n     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    namespace GNULIB_NAMESPACE                                                \\\n    {                                                                         \\\n      static const struct _gl_ ## func ## _wrapper                            \\\n      {                                                                       \\\n        typedef rettype (*type) parameters;                                   \\\n                                                                              \\\n        inline operator type () const                                         \\\n        {                                                                     \\\n          return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \\\n        }                                                                     \\\n      } func = {};                                                            \\\n    }                                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN (func);\n   causes a warning to be emitted when ::func is used but not when\n   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded\n   variants.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN(func) \\\n   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN_1(func,namespace) \\\n   _GL_CXXALIASWARN_2 (func, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n    _GL_WARN_ON_USE (func, \\\n                     \"The symbol ::\" #func \" refers to the system function. \" \\\n                     \"Use \" #namespace \"::\" #func \" instead.\")\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     extern __typeof__ (func) func\n# else\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN(func) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);\n   causes a warning to be emitted when the given overloaded variant of ::func\n   is used but not when GNULIB_NAMESPACE::func is used.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \\\n                        GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \\\n   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n    _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \\\n                         \"The symbol ::\" #func \" refers to the system function. \" \\\n                         \"Use \" #namespace \"::\" #func \" instead.\")\n# else\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n#endif /* _GL_CXXDEFS_H */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n/* A C macro for declaring that specific arguments must not be NULL.\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools\n   that the values passed as arguments n, ..., m must be non-NULL pointers.\n   n = 1 stands for the first argument, n = 2 for the second argument etc.  */\n#ifndef _GL_ARG_NONNULL\n# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__\n#  define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))\n# else\n#  define _GL_ARG_NONNULL(params)\n# endif\n#endif\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n/* A C macro for emitting warnings if a function is used.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_WARN_ON_USE (function, \"literal string\") issues a declaration\n   for FUNCTION which will then trigger a compiler warning containing\n   the text of \"literal string\" anywhere that function is called, if\n   supported by the compiler.  If the compiler does not support this\n   feature, the macro expands to an unused extern declaration.\n\n   _GL_WARN_ON_USE_ATTRIBUTE (\"literal string\") expands to the\n   attribute used in _GL_WARN_ON_USE.  If the compiler does not support\n   this feature, it expands to empty.\n\n   These macros are useful for marking a function as a potential\n   portability trap, with the intent that \"literal string\" include\n   instructions on the replacement function that should be used\n   instead.\n   _GL_WARN_ON_USE is for functions with 'extern' linkage.\n   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'\n   linkage.\n\n   However, one of the reasons that a function is a portability trap is\n   if it has the wrong signature.  Declaring FUNCTION with a different\n   signature in C is a compilation error, so this macro must use the\n   same type as any existing declaration so that programs that avoid\n   the problematic FUNCTION do not fail to compile merely because they\n   included a header that poisoned the function.  But this implies that\n   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already\n   have a declaration.  Use of this macro implies that there must not\n   be any other macro hiding the declaration of FUNCTION; but\n   undefining FUNCTION first is part of the poisoning process anyway\n   (although for symbols that are provided only via a macro, the result\n   is a compilation error rather than a warning containing\n   \"literal string\").  Also note that in C++, it is only safe to use if\n   FUNCTION has no overloads.\n\n   For an example, it is possible to poison 'getline' by:\n   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],\n     [getline]) in configure.ac, which potentially defines\n     HAVE_RAW_DECL_GETLINE\n   - adding this code to a header that wraps the system <stdio.h>:\n     #undef getline\n     #if HAVE_RAW_DECL_GETLINE\n     _GL_WARN_ON_USE (getline, \"getline is required by POSIX 2008, but\"\n       \"not universally present; use the gnulib module getline\");\n     #endif\n\n   It is not possible to directly poison global variables.  But it is\n   possible to write a wrapper accessor function, and poison that\n   (less common usage, like &environ, will cause a compilation error\n   rather than issue the nice warning, but the end result of informing\n   the developer about their portability problem is still achieved):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     rpl_environ (void) { return &environ; }\n     _GL_WARN_ON_USE (rpl_environ, \"environ is not always properly declared\");\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   or better (avoiding contradictory use of 'static' and 'extern'):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     _GL_WARN_ON_USE_ATTRIBUTE (\"environ is not always properly declared\")\n     rpl_environ (void) { return &environ; }\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   */\n#ifndef _GL_WARN_ON_USE\n\n# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function __attribute__ ((__warning__ (message)))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__warning__ (message)))\n# elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# else /* Unsupported.  */\n#  define _GL_WARN_ON_USE(function, message) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# endif\n#endif\n\n/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, \"message\")\n   is like _GL_WARN_ON_USE (function, \"message\"), except that in C++ mode the\n   function is declared with the given prototype, consisting of return type,\n   parameters, and attributes.\n   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does\n   not work in this case.  */\n#ifndef _GL_WARN_ON_USE_CXX\n# if !defined __cplusplus\n#  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n     _GL_WARN_ON_USE (function, msg)\n# else\n#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes \\\n  __attribute__ ((__warning__ (msg)))\n#  elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_clang function parameters_and_attributes \\\n  __attribute__ ((__diagnose_if__ (1, msg, \"warning\")))\n#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes\n#  else /* Unsupported.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  endif\n# endif\n#endif\n\n/* _GL_WARN_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#ifndef _GL_WARN_EXTERN_C\n# if defined __cplusplus\n#  define _GL_WARN_EXTERN_C extern \"C\"\n# else\n#  define _GL_WARN_EXTERN_C extern\n# endif\n#endif\n\n/* The LC_MESSAGES locale category is specified in POSIX, but not in ISO C.\n   On systems that don't define it, use the same value as GNU libintl.  */\n#if !defined LC_MESSAGES\n# define LC_MESSAGES 1729\n#endif\n\n/* On native Windows with MSVC, 'struct lconv' lacks the members int_p_* and\n   int_n_*.  Instead of overriding 'struct lconv', merely define these member\n   names as macros.  This avoids trouble in C++ mode.  */\n#if defined _MSC_VER\n# define int_p_cs_precedes   p_cs_precedes\n# define int_p_sign_posn     p_sign_posn\n# define int_p_sep_by_space  p_sep_by_space\n# define int_n_cs_precedes   n_cs_precedes\n# define int_n_sign_posn     n_sign_posn\n# define int_n_sep_by_space  n_sep_by_space\n#endif\n\n/* Bionic libc's 'struct lconv' is just a dummy.  */\n#if 1\n# define lconv rpl_lconv\nstruct lconv\n{\n  /* All 'char *' are actually 'const char *'.  */\n\n  /* Members that depend on the LC_NUMERIC category of the locale.  See\n     <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_04> */\n\n  /* Symbol used as decimal point.  */\n  char *decimal_point;\n  /* Symbol used to separate groups of digits to the left of the decimal\n     point.  */\n  char *thousands_sep;\n  /* Definition of the size of groups of digits to the left of the decimal\n     point.  */\n  char *grouping;\n\n  /* Members that depend on the LC_MONETARY category of the locale.  See\n     <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_03> */\n\n  /* Symbol used as decimal point.  */\n  char *mon_decimal_point;\n  /* Symbol used to separate groups of digits to the left of the decimal\n     point.  */\n  char *mon_thousands_sep;\n  /* Definition of the size of groups of digits to the left of the decimal\n     point.  */\n  char *mon_grouping;\n  /* Sign used to indicate a value >= 0.  */\n  char *positive_sign;\n  /* Sign used to indicate a value < 0.  */\n  char *negative_sign;\n\n  /* For formatting local currency.  */\n  /* Currency symbol (3 characters) followed by separator (1 character).  */\n  char *currency_symbol;\n  /* Number of digits after the decimal point.  */\n  char frac_digits;\n  /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it\n     comes after the number.  */\n  char p_cs_precedes;\n  /* For values >= 0: Position of the sign.  */\n  char p_sign_posn;\n  /* For values >= 0: Placement of spaces between currency symbol, sign, and\n     number.  */\n  char p_sep_by_space;\n  /* For values < 0: 1 if the currency symbol precedes the number, 0 if it\n     comes after the number.  */\n  char n_cs_precedes;\n  /* For values < 0: Position of the sign.  */\n  char n_sign_posn;\n  /* For values < 0: Placement of spaces between currency symbol, sign, and\n     number.  */\n  char n_sep_by_space;\n\n  /* For formatting international currency.  */\n  /* Currency symbol (3 characters) followed by separator (1 character).  */\n  char *int_curr_symbol;\n  /* Number of digits after the decimal point.  */\n  char int_frac_digits;\n  /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it\n     comes after the number.  */\n  char int_p_cs_precedes;\n  /* For values >= 0: Position of the sign.  */\n  char int_p_sign_posn;\n  /* For values >= 0: Placement of spaces between currency symbol, sign, and\n     number.  */\n  char int_p_sep_by_space;\n  /* For values < 0: 1 if the currency symbol precedes the number, 0 if it\n     comes after the number.  */\n  char int_n_cs_precedes;\n  /* For values < 0: Position of the sign.  */\n  char int_n_sign_posn;\n  /* For values < 0: Placement of spaces between currency symbol, sign, and\n     number.  */\n  char int_n_sep_by_space;\n};\n#endif\n\n#if 1\n# if 1\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef localeconv\n#   define localeconv rpl_localeconv\n#  endif\n_GL_FUNCDECL_RPL (localeconv, struct lconv *, (void));\n_GL_CXXALIAS_RPL (localeconv, struct lconv *, (void));\n# else\n_GL_CXXALIAS_SYS (localeconv, struct lconv *, (void));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (localeconv);\n# endif\n#elif 1\n# undef localeconv\n# define localeconv localeconv_used_without_requesting_gnulib_module_localeconv\n#elif defined GNULIB_POSIXCHECK\n# undef localeconv\n# if HAVE_RAW_DECL_LOCALECONV\n_GL_WARN_ON_USE (localeconv,\n                 \"localeconv returns too few information on some platforms - \"\n                 \"use gnulib module localeconv for portability\");\n# endif\n#endif\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef setlocale\n#   define setlocale rpl_setlocale\n#   define GNULIB_defined_setlocale 1\n#  endif\n_GL_FUNCDECL_RPL (setlocale, char *, (int category, const char *locale));\n_GL_CXXALIAS_RPL (setlocale, char *, (int category, const char *locale));\n# else\n_GL_CXXALIAS_SYS (setlocale, char *, (int category, const char *locale));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (setlocale);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef setlocale\n# if HAVE_RAW_DECL_SETLOCALE\n_GL_WARN_ON_USE (setlocale, \"setlocale works differently on native Windows - \"\n                 \"use gnulib module setlocale for portability\");\n# endif\n#endif\n\n#if 1\n/* Included here for convenience.  */\n# include \"setlocale_null.h\"\n#endif\n\n#if /*@GNULIB_NEWLOCALE@ ||*/ (0 && 0 && 1)\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef newlocale\n#   define newlocale rpl_newlocale\n#   define GNULIB_defined_newlocale 1\n#  endif\n_GL_FUNCDECL_RPL (newlocale, locale_t,\n                  (int category_mask, const char *name, locale_t base)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (newlocale, locale_t,\n                  (int category_mask, const char *name, locale_t base));\n# else\n#  if 1\n_GL_CXXALIAS_SYS (newlocale, locale_t,\n                  (int category_mask, const char *name, locale_t base));\n#  endif\n# endif\n# if 1\n_GL_CXXALIASWARN (newlocale);\n# endif\n# if 1 || 0\n#  ifndef HAVE_WORKING_NEWLOCALE\n#   define HAVE_WORKING_NEWLOCALE 1\n#  endif\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef newlocale\n# if HAVE_RAW_DECL_NEWLOCALE\n_GL_WARN_ON_USE (newlocale, \"newlocale is not portable\");\n# endif\n#endif\n\n#if 0 || (0 && 0 && 1)\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef duplocale\n#   define duplocale rpl_duplocale\n#   define GNULIB_defined_duplocale 1\n#  endif\n_GL_FUNCDECL_RPL (duplocale, locale_t, (locale_t locale) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (duplocale, locale_t, (locale_t locale));\n# else\n#  if 1\n_GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale));\n#  endif\n# endif\n# if 1\n_GL_CXXALIASWARN (duplocale);\n# endif\n# if 1 || 0\n#  ifndef HAVE_WORKING_DUPLOCALE\n#   define HAVE_WORKING_DUPLOCALE 1\n#  endif\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef duplocale\n# if HAVE_RAW_DECL_DUPLOCALE\n_GL_WARN_ON_USE (duplocale, \"duplocale is buggy on some glibc systems - \"\n                 \"use gnulib module duplocale for portability\");\n# endif\n#endif\n\n#if /*@GNULIB_FREELOCALE@ ||*/ (0 && 0 && 1)\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef freelocale\n#   define freelocale rpl_freelocale\n#   define GNULIB_defined_freelocale 1\n#  endif\n_GL_FUNCDECL_RPL (freelocale, void, (locale_t locale) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (freelocale, void, (locale_t locale));\n# else\n#  if 1\n/* Need to cast, because on FreeBSD and Mac OS X 10.13, the return type is\n                                   int.  */\n_GL_CXXALIAS_SYS_CAST (freelocale, void, (locale_t locale));\n#  endif\n# endif\n# if 1\n_GL_CXXALIASWARN (freelocale);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef freelocale\n# if HAVE_RAW_DECL_FREELOCALE\n_GL_WARN_ON_USE (freelocale, \"freelocale is not portable\");\n# endif\n#endif\n\n#endif /* _GL_LOCALE_H */\n#endif /* _GL_LOCALE_H */\n#endif /* !(__need_locale_t || _GL_ALREADY_INCLUDING_LOCALE_H) */\n"
  },
  {
    "path": "win32/gnulib_h/string.h",
    "content": "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\n/* A GNU-like <string.h>.\n\n   Copyright (C) 1995-1996, 2001-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#if __GNUC__ >= 3\n#pragma GCC system_header\n#endif\n\n\n#if defined _GL_ALREADY_INCLUDING_STRING_H\n/* Special invocation convention:\n   - On OS X/NetBSD we have a sequence of nested includes\n       <string.h> -> <strings.h> -> \"string.h\"\n     In this situation system _chk variants due to -D_FORTIFY_SOURCE\n     might be used after any replacements defined here.  */\n\n#include_next <string.h>\n\n#else\n/* Normal invocation convention.  */\n\n#ifndef _GL_STRING_H\n\n#define _GL_ALREADY_INCLUDING_STRING_H\n\n/* The include_next requires a split double-inclusion guard.  */\n#include_next <string.h>\n\n#undef _GL_ALREADY_INCLUDING_STRING_H\n\n#ifndef _GL_STRING_H\n#define _GL_STRING_H\n\n/* NetBSD 5.0 mis-defines NULL.  */\n#include <stddef.h>\n\n/* MirBSD defines mbslen as a macro.  */\n#if 0 && defined __MirBSD__\n# include <wchar.h>\n#endif\n\n/* The __attribute__ feature is available in gcc versions 2.5 and later.\n   The attribute __pure__ was added in gcc 2.96.  */\n#ifndef _GL_ATTRIBUTE_PURE\n# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__\n#  define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))\n# else\n#  define _GL_ATTRIBUTE_PURE /* empty */\n# endif\n#endif\n\n/* NetBSD 5.0 declares strsignal in <unistd.h>, not in <string.h>.  */\n/* But in any case avoid namespace pollution on glibc systems.  */\n#if (0 || defined GNULIB_POSIXCHECK) && defined __NetBSD__ \\\n    && ! defined __GLIBC__\n# include <unistd.h>\n#endif\n\n/* AIX 7.2 declares ffsl and ffsll in <strings.h>, not in <string.h>.  */\n/* But in any case avoid namespace pollution on glibc systems.  */\n#if ((0 || 0 || defined GNULIB_POSIXCHECK) \\\n     && defined _AIX) \\\n    && ! defined __GLIBC__\n# include <strings.h>\n#endif\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n/* C++ compatible function declaration macros.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _GL_CXXDEFS_H\n#define _GL_CXXDEFS_H\n\n/* Begin/end the GNULIB_NAMESPACE namespace.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {\n# define _GL_END_NAMESPACE }\n#else\n# define _GL_BEGIN_NAMESPACE\n# define _GL_END_NAMESPACE\n#endif\n\n/* The three most frequent use cases of these macros are:\n\n   * For providing a substitute for a function that is missing on some\n     platforms, but is declared and works fine on the platforms on which\n     it exists:\n\n       #if @GNULIB_FOO@\n       # if !@HAVE_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       # endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on all platforms,\n     but is broken/insufficient and needs to be replaced on some platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on some platforms\n     but is broken/insufficient and needs to be replaced on some of them and\n     is additionally either missing or undeclared on some other platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       #  endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n*/\n\n/* _GL_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#if defined __cplusplus\n# define _GL_EXTERN_C extern \"C\"\n#else\n# define _GL_EXTERN_C extern\n#endif\n\n/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);\n   declares a replacement function, named rpl_func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \\\n  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)\n#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype rpl_func parameters_and_attributes\n\n/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);\n   declares the system function, named func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype func parameters_and_attributes\n\n/* _GL_CXXALIAS_RPL (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));\n\n   Wrapping rpl_func in an object with an inline conversion operator\n   avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#define _GL_CXXALIAS_RPL(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::rpl_func;                                  \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA (func, rettype, parameters);\n   is to be used when func is a Microsoft deprecated alias, on native Windows.\n   It declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to _func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));\n */\n#define _GL_CXXALIAS_MDA(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);\n   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);\n   except that the C function rpl_func may have a slightly different\n   declaration.  A cast is used to silence the \"invalid conversion\" error\n   that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                     \\\n    {                                                              \\\n      static const struct _gl_ ## func ## _wrapper                 \\\n      {                                                            \\\n        typedef rettype (*type) parameters;                        \\\n                                                                   \\\n        inline operator type () const                              \\\n        {                                                          \\\n          return reinterpret_cast<type>(::rpl_func);               \\\n        }                                                          \\\n      } func = {};                                                 \\\n    }                                                              \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_MDA (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_SYS (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to the system provided function func, if GNULIB_NAMESPACE\n   is defined.\n   Example:\n     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));\n\n   Wrapping func in an object with an inline conversion operator\n   avoids a reference to func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS(func,rettype,parameters)            \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::func;                                      \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                          \\\n    {                                                   \\\n      static const struct _gl_ ## func ## _wrapper      \\\n      {                                                 \\\n        typedef rettype (*type) parameters;             \\\n                                                        \\\n        inline operator type () const                   \\\n        {                                               \\\n          return reinterpret_cast<type>(::func);        \\\n        }                                               \\\n      } func = {};                                      \\\n    }                                                   \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function is picked among a set of overloaded functions,\n   namely the one with rettype2 and parameters2.  Two consecutive casts\n   are used to silence the \"cannot find a match\" and \"invalid conversion\"\n   errors that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n  /* The outer cast must be a reinterpret_cast.\n     The inner cast: When the function is defined as a set of overloaded\n     functions, it works as a static_cast<>, choosing the designated variant.\n     When the function is defined as a single variant, it works as a\n     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    namespace GNULIB_NAMESPACE                                                \\\n    {                                                                         \\\n      static const struct _gl_ ## func ## _wrapper                            \\\n      {                                                                       \\\n        typedef rettype (*type) parameters;                                   \\\n                                                                              \\\n        inline operator type () const                                         \\\n        {                                                                     \\\n          return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \\\n        }                                                                     \\\n      } func = {};                                                            \\\n    }                                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN (func);\n   causes a warning to be emitted when ::func is used but not when\n   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded\n   variants.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN(func) \\\n   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN_1(func,namespace) \\\n   _GL_CXXALIASWARN_2 (func, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n    _GL_WARN_ON_USE (func, \\\n                     \"The symbol ::\" #func \" refers to the system function. \" \\\n                     \"Use \" #namespace \"::\" #func \" instead.\")\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     extern __typeof__ (func) func\n# else\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN(func) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);\n   causes a warning to be emitted when the given overloaded variant of ::func\n   is used but not when GNULIB_NAMESPACE::func is used.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \\\n                        GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \\\n   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n    _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \\\n                         \"The symbol ::\" #func \" refers to the system function. \" \\\n                         \"Use \" #namespace \"::\" #func \" instead.\")\n# else\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n#endif /* _GL_CXXDEFS_H */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n/* A C macro for declaring that specific arguments must not be NULL.\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools\n   that the values passed as arguments n, ..., m must be non-NULL pointers.\n   n = 1 stands for the first argument, n = 2 for the second argument etc.  */\n#ifndef _GL_ARG_NONNULL\n# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__\n#  define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))\n# else\n#  define _GL_ARG_NONNULL(params)\n# endif\n#endif\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n/* A C macro for emitting warnings if a function is used.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_WARN_ON_USE (function, \"literal string\") issues a declaration\n   for FUNCTION which will then trigger a compiler warning containing\n   the text of \"literal string\" anywhere that function is called, if\n   supported by the compiler.  If the compiler does not support this\n   feature, the macro expands to an unused extern declaration.\n\n   _GL_WARN_ON_USE_ATTRIBUTE (\"literal string\") expands to the\n   attribute used in _GL_WARN_ON_USE.  If the compiler does not support\n   this feature, it expands to empty.\n\n   These macros are useful for marking a function as a potential\n   portability trap, with the intent that \"literal string\" include\n   instructions on the replacement function that should be used\n   instead.\n   _GL_WARN_ON_USE is for functions with 'extern' linkage.\n   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'\n   linkage.\n\n   However, one of the reasons that a function is a portability trap is\n   if it has the wrong signature.  Declaring FUNCTION with a different\n   signature in C is a compilation error, so this macro must use the\n   same type as any existing declaration so that programs that avoid\n   the problematic FUNCTION do not fail to compile merely because they\n   included a header that poisoned the function.  But this implies that\n   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already\n   have a declaration.  Use of this macro implies that there must not\n   be any other macro hiding the declaration of FUNCTION; but\n   undefining FUNCTION first is part of the poisoning process anyway\n   (although for symbols that are provided only via a macro, the result\n   is a compilation error rather than a warning containing\n   \"literal string\").  Also note that in C++, it is only safe to use if\n   FUNCTION has no overloads.\n\n   For an example, it is possible to poison 'getline' by:\n   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],\n     [getline]) in configure.ac, which potentially defines\n     HAVE_RAW_DECL_GETLINE\n   - adding this code to a header that wraps the system <stdio.h>:\n     #undef getline\n     #if HAVE_RAW_DECL_GETLINE\n     _GL_WARN_ON_USE (getline, \"getline is required by POSIX 2008, but\"\n       \"not universally present; use the gnulib module getline\");\n     #endif\n\n   It is not possible to directly poison global variables.  But it is\n   possible to write a wrapper accessor function, and poison that\n   (less common usage, like &environ, will cause a compilation error\n   rather than issue the nice warning, but the end result of informing\n   the developer about their portability problem is still achieved):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     rpl_environ (void) { return &environ; }\n     _GL_WARN_ON_USE (rpl_environ, \"environ is not always properly declared\");\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   or better (avoiding contradictory use of 'static' and 'extern'):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     _GL_WARN_ON_USE_ATTRIBUTE (\"environ is not always properly declared\")\n     rpl_environ (void) { return &environ; }\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   */\n#ifndef _GL_WARN_ON_USE\n\n# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function __attribute__ ((__warning__ (message)))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__warning__ (message)))\n# elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# else /* Unsupported.  */\n#  define _GL_WARN_ON_USE(function, message) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# endif\n#endif\n\n/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, \"message\")\n   is like _GL_WARN_ON_USE (function, \"message\"), except that in C++ mode the\n   function is declared with the given prototype, consisting of return type,\n   parameters, and attributes.\n   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does\n   not work in this case.  */\n#ifndef _GL_WARN_ON_USE_CXX\n# if !defined __cplusplus\n#  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n     _GL_WARN_ON_USE (function, msg)\n# else\n#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes \\\n  __attribute__ ((__warning__ (msg)))\n#  elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_clang function parameters_and_attributes \\\n  __attribute__ ((__diagnose_if__ (1, msg, \"warning\")))\n#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes\n#  else /* Unsupported.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  endif\n# endif\n#endif\n\n/* _GL_WARN_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#ifndef _GL_WARN_EXTERN_C\n# if defined __cplusplus\n#  define _GL_WARN_EXTERN_C extern \"C\"\n# else\n#  define _GL_WARN_EXTERN_C extern\n# endif\n#endif\n\n\n/* Clear a block of memory.  The compiler will not delete a call to\n   this function, even if the block is dead after the call.  */\n#if 0\n# if ! 1\n_GL_FUNCDECL_SYS (explicit_bzero, void,\n                  (void *__dest, size_t __n) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (explicit_bzero, void, (void *__dest, size_t __n));\n_GL_CXXALIASWARN (explicit_bzero);\n#elif defined GNULIB_POSIXCHECK\n# undef explicit_bzero\n# if HAVE_RAW_DECL_EXPLICIT_BZERO\n_GL_WARN_ON_USE (explicit_bzero, \"explicit_bzero is unportable - \"\n                 \"use gnulib module explicit_bzero for portability\");\n# endif\n#endif\n\n/* Find the index of the least-significant set bit.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (ffsl, int, (long int i));\n# endif\n_GL_CXXALIAS_SYS (ffsl, int, (long int i));\n_GL_CXXALIASWARN (ffsl);\n#elif defined GNULIB_POSIXCHECK\n# undef ffsl\n# if HAVE_RAW_DECL_FFSL\n_GL_WARN_ON_USE (ffsl, \"ffsl is not portable - use the ffsl module\");\n# endif\n#endif\n\n\n/* Find the index of the least-significant set bit.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define ffsll rpl_ffsll\n#  endif\n_GL_FUNCDECL_RPL (ffsll, int, (long long int i));\n_GL_CXXALIAS_RPL (ffsll, int, (long long int i));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (ffsll, int, (long long int i));\n#  endif\n_GL_CXXALIAS_SYS (ffsll, int, (long long int i));\n# endif\n_GL_CXXALIASWARN (ffsll);\n#elif defined GNULIB_POSIXCHECK\n# undef ffsll\n# if HAVE_RAW_DECL_FFSLL\n_GL_WARN_ON_USE (ffsll, \"ffsll is not portable - use the ffsll module\");\n# endif\n#endif\n\n\n#if 1\n/* On native Windows, map 'memccpy' to '_memccpy', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::memccpy always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef memccpy\n#   define memccpy _memccpy\n#  endif\n_GL_CXXALIAS_MDA (memccpy, void *,\n                  (void *dest, const void *src, int c, size_t n));\n# else\n_GL_CXXALIAS_SYS (memccpy, void *,\n                  (void *dest, const void *src, int c, size_t n));\n# endif\n_GL_CXXALIASWARN (memccpy);\n#endif\n\n\n/* Return the first instance of C within N bytes of S, or NULL.  */\n#if 1\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef memchr\n#   define memchr rpl_memchr\n#  endif\n_GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n));\n# else\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C\" { const void * std::memchr (const void *, int, size_t); }\n       extern \"C++\" { void * std::memchr (void *, int, size_t); }  */\n_GL_CXXALIAS_SYS_CAST2 (memchr,\n                        void *, (void const *__s, int __c, size_t __n),\n                        void const *, (void const *__s, int __c, size_t __n));\n# endif\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n));\n_GL_CXXALIASWARN1 (memchr, void const *,\n                   (void const *__s, int __c, size_t __n));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (memchr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef memchr\n/* Assume memchr is always declared.  */\n_GL_WARN_ON_USE (memchr, \"memchr has platform-specific bugs - \"\n                 \"use gnulib module memchr for portability\" );\n#endif\n\n/* Return the first occurrence of NEEDLE in HAYSTACK.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define memmem rpl_memmem\n#  endif\n_GL_FUNCDECL_RPL (memmem, void *,\n                  (void const *__haystack, size_t __haystack_len,\n                   void const *__needle, size_t __needle_len)\n                  _GL_ATTRIBUTE_PURE\n                  _GL_ARG_NONNULL ((1, 3)));\n_GL_CXXALIAS_RPL (memmem, void *,\n                  (void const *__haystack, size_t __haystack_len,\n                   void const *__needle, size_t __needle_len));\n# else\n#  if ! 1\n_GL_FUNCDECL_SYS (memmem, void *,\n                  (void const *__haystack, size_t __haystack_len,\n                   void const *__needle, size_t __needle_len)\n                  _GL_ATTRIBUTE_PURE\n                  _GL_ARG_NONNULL ((1, 3)));\n#  endif\n_GL_CXXALIAS_SYS (memmem, void *,\n                  (void const *__haystack, size_t __haystack_len,\n                   void const *__needle, size_t __needle_len));\n# endif\n_GL_CXXALIASWARN (memmem);\n#elif defined GNULIB_POSIXCHECK\n# undef memmem\n# if HAVE_RAW_DECL_MEMMEM\n_GL_WARN_ON_USE (memmem, \"memmem is unportable and often quadratic - \"\n                 \"use gnulib module memmem-simple for portability, \"\n                 \"and module memmem for speed\" );\n# endif\n#endif\n\n/* Copy N bytes of SRC to DEST, return pointer to bytes after the\n   last written byte.  */\n#if 1\n# if ! 0\n_GL_FUNCDECL_SYS (mempcpy, void *,\n                  (void *restrict __dest, void const *restrict __src,\n                   size_t __n)\n                  _GL_ARG_NONNULL ((1, 2)));\n# endif\n_GL_CXXALIAS_SYS (mempcpy, void *,\n                  (void *restrict __dest, void const *restrict __src,\n                   size_t __n));\n_GL_CXXALIASWARN (mempcpy);\n#elif defined GNULIB_POSIXCHECK\n# undef mempcpy\n# if HAVE_RAW_DECL_MEMPCPY\n_GL_WARN_ON_USE (mempcpy, \"mempcpy is unportable - \"\n                 \"use gnulib module mempcpy for portability\");\n# endif\n#endif\n\n/* Search backwards through a block for a byte (specified as an int).  */\n#if 0\n# if ! 1\n_GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1)));\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" { const void * std::memrchr (const void *, int, size_t); }\n       extern \"C++\" { void * std::memrchr (void *, int, size_t); }  */\n_GL_CXXALIAS_SYS_CAST2 (memrchr,\n                        void *, (void const *, int, size_t),\n                        void const *, (void const *, int, size_t));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (memrchr, void *, (void *, int, size_t));\n_GL_CXXALIASWARN1 (memrchr, void const *, (void const *, int, size_t));\n# else\n_GL_CXXALIASWARN (memrchr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef memrchr\n# if HAVE_RAW_DECL_MEMRCHR\n_GL_WARN_ON_USE (memrchr, \"memrchr is unportable - \"\n                 \"use gnulib module memrchr for portability\");\n# endif\n#endif\n\n/* Find the first occurrence of C in S.  More efficient than\n   memchr(S,C,N), at the expense of undefined behavior if C does not\n   occur within N bytes.  */\n#if 0\n# if ! 1\n_GL_FUNCDECL_SYS (rawmemchr, void *, (void const *__s, int __c_in)\n                                     _GL_ATTRIBUTE_PURE\n                                     _GL_ARG_NONNULL ((1)));\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" { const void * std::rawmemchr (const void *, int); }\n       extern \"C++\" { void * std::rawmemchr (void *, int); }  */\n_GL_CXXALIAS_SYS_CAST2 (rawmemchr,\n                        void *, (void const *__s, int __c_in),\n                        void const *, (void const *__s, int __c_in));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (rawmemchr, void *, (void *__s, int __c_in));\n_GL_CXXALIASWARN1 (rawmemchr, void const *, (void const *__s, int __c_in));\n# else\n_GL_CXXALIASWARN (rawmemchr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef rawmemchr\n# if HAVE_RAW_DECL_RAWMEMCHR\n_GL_WARN_ON_USE (rawmemchr, \"rawmemchr is unportable - \"\n                 \"use gnulib module rawmemchr for portability\");\n# endif\n#endif\n\n/* Copy SRC to DST, returning the address of the terminating '\\0' in DST.  */\n#if 0\n# if ! 1\n_GL_FUNCDECL_SYS (stpcpy, char *,\n                  (char *restrict __dst, char const *restrict __src)\n                  _GL_ARG_NONNULL ((1, 2)));\n# endif\n_GL_CXXALIAS_SYS (stpcpy, char *,\n                  (char *restrict __dst, char const *restrict __src));\n_GL_CXXALIASWARN (stpcpy);\n#elif defined GNULIB_POSIXCHECK\n# undef stpcpy\n# if HAVE_RAW_DECL_STPCPY\n_GL_WARN_ON_USE (stpcpy, \"stpcpy is unportable - \"\n                 \"use gnulib module stpcpy for portability\");\n# endif\n#endif\n\n/* Copy no more than N bytes of SRC to DST, returning a pointer past the\n   last non-NUL byte written into DST.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef stpncpy\n#   define stpncpy rpl_stpncpy\n#  endif\n_GL_FUNCDECL_RPL (stpncpy, char *,\n                  (char *restrict __dst, char const *restrict __src,\n                   size_t __n)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (stpncpy, char *,\n                  (char *restrict __dst, char const *restrict __src,\n                   size_t __n));\n# else\n#  if ! 1\n_GL_FUNCDECL_SYS (stpncpy, char *,\n                  (char *restrict __dst, char const *restrict __src,\n                   size_t __n)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (stpncpy, char *,\n                  (char *restrict __dst, char const *restrict __src,\n                   size_t __n));\n# endif\n_GL_CXXALIASWARN (stpncpy);\n#elif defined GNULIB_POSIXCHECK\n# undef stpncpy\n# if HAVE_RAW_DECL_STPNCPY\n_GL_WARN_ON_USE (stpncpy, \"stpncpy is unportable - \"\n                 \"use gnulib module stpncpy for portability\");\n# endif\n#endif\n\n#if defined GNULIB_POSIXCHECK\n/* strchr() does not work with multibyte strings if the locale encoding is\n   GB18030 and the character to be searched is a digit.  */\n# undef strchr\n/* Assume strchr is always declared.  */\n_GL_WARN_ON_USE_CXX (strchr,\n                     const char *, char *, (const char *, int),\n                     \"strchr cannot work correctly on character strings \"\n                     \"in some multibyte locales - \"\n                     \"use mbschr if you care about internationalization\");\n#endif\n\n/* Find the first occurrence of C in S or the final NUL byte.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strchrnul rpl_strchrnul\n#  endif\n_GL_FUNCDECL_RPL (strchrnul, char *, (const char *__s, int __c_in)\n                                     _GL_ATTRIBUTE_PURE\n                                     _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strchrnul, char *,\n                  (const char *str, int ch));\n# else\n#  if ! 1\n_GL_FUNCDECL_SYS (strchrnul, char *, (char const *__s, int __c_in)\n                                     _GL_ATTRIBUTE_PURE\n                                     _GL_ARG_NONNULL ((1)));\n#  endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" { const char * std::strchrnul (const char *, int); }\n       extern \"C++\" { char * std::strchrnul (char *, int); }  */\n_GL_CXXALIAS_SYS_CAST2 (strchrnul,\n                        char *, (char const *__s, int __c_in),\n                        char const *, (char const *__s, int __c_in));\n# endif\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in));\n_GL_CXXALIASWARN1 (strchrnul, char const *, (char const *__s, int __c_in));\n# else\n_GL_CXXALIASWARN (strchrnul);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strchrnul\n# if HAVE_RAW_DECL_STRCHRNUL\n_GL_WARN_ON_USE (strchrnul, \"strchrnul is unportable - \"\n                 \"use gnulib module strchrnul for portability\");\n# endif\n#endif\n\n/* Duplicate S, returning an identical malloc'd string.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strdup\n#   define strdup rpl_strdup\n#  endif\n_GL_FUNCDECL_RPL (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strdup, char *, (char const *__s));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strdup\n#   define strdup _strdup\n#  endif\n_GL_CXXALIAS_MDA (strdup, char *, (char const *__s));\n# else\n#  if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup\n    /* strdup exists as a function and as a macro.  Get rid of the macro.  */\n#   undef strdup\n#  endif\n#  if !(1 || defined strdup)\n_GL_FUNCDECL_SYS (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strdup, char *, (char const *__s));\n# endif\n_GL_CXXALIASWARN (strdup);\n#elif defined GNULIB_POSIXCHECK\n# undef strdup\n# if HAVE_RAW_DECL_STRDUP\n_GL_WARN_ON_USE (strdup, \"strdup is unportable - \"\n                 \"use gnulib module strdup for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'creat' to '_creat', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::strdup always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strdup\n#   define strdup _strdup\n#  endif\n_GL_CXXALIAS_MDA (strdup, char *, (char const *__s));\n# else\n#  if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup\n#   undef strdup\n#  endif\n_GL_CXXALIAS_SYS (strdup, char *, (char const *__s));\n# endif\n_GL_CXXALIASWARN (strdup);\n#endif\n\n/* Append no more than N characters from SRC onto DEST.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strncat\n#   define strncat rpl_strncat\n#  endif\n_GL_FUNCDECL_RPL (strncat, char *,\n                  (char *restrict dest, const char *restrict src, size_t n)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (strncat, char *,\n                  (char *restrict dest, const char *restrict src, size_t n));\n# else\n_GL_CXXALIAS_SYS (strncat, char *,\n                  (char *restrict dest, const char *restrict src, size_t n));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (strncat);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strncat\n# if HAVE_RAW_DECL_STRNCAT\n_GL_WARN_ON_USE (strncat, \"strncat is unportable - \"\n                 \"use gnulib module strncat for portability\");\n# endif\n#endif\n\n/* Return a newly allocated copy of at most N bytes of STRING.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strndup\n#   define strndup rpl_strndup\n#  endif\n_GL_FUNCDECL_RPL (strndup, char *, (char const *__s, size_t __n)\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n));\n# else\n#  if ! 1\n_GL_FUNCDECL_SYS (strndup, char *, (char const *__s, size_t __n)\n                                   _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strndup, char *, (char const *__s, size_t __n));\n# endif\n_GL_CXXALIASWARN (strndup);\n#elif defined GNULIB_POSIXCHECK\n# undef strndup\n# if HAVE_RAW_DECL_STRNDUP\n_GL_WARN_ON_USE (strndup, \"strndup is unportable - \"\n                 \"use gnulib module strndup for portability\");\n# endif\n#endif\n\n/* Find the length (number of bytes) of STRING, but scan at most\n   MAXLEN bytes.  If no '\\0' terminator is found in that many bytes,\n   return MAXLEN.  */\n#if 1\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strnlen\n#   define strnlen rpl_strnlen\n#  endif\n_GL_FUNCDECL_RPL (strnlen, size_t, (char const *__s, size_t __maxlen)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (strnlen, size_t, (char const *__s, size_t __maxlen));\n# else\n#  if ! 0\n_GL_FUNCDECL_SYS (strnlen, size_t, (char const *__s, size_t __maxlen)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (strnlen, size_t, (char const *__s, size_t __maxlen));\n# endif\n_GL_CXXALIASWARN (strnlen);\n#elif defined GNULIB_POSIXCHECK\n# undef strnlen\n# if HAVE_RAW_DECL_STRNLEN\n_GL_WARN_ON_USE (strnlen, \"strnlen is unportable - \"\n                 \"use gnulib module strnlen for portability\");\n# endif\n#endif\n\n#if defined GNULIB_POSIXCHECK\n/* strcspn() assumes the second argument is a list of single-byte characters.\n   Even in this simple case, it does not work with multibyte strings if the\n   locale encoding is GB18030 and one of the characters to be searched is a\n   digit.  */\n# undef strcspn\n/* Assume strcspn is always declared.  */\n_GL_WARN_ON_USE (strcspn, \"strcspn cannot work correctly on character strings \"\n                 \"in multibyte locales - \"\n                 \"use mbscspn if you care about internationalization\");\n#endif\n\n/* Find the first occurrence in S of any character in ACCEPT.  */\n#if 0\n# if ! 1\n_GL_FUNCDECL_SYS (strpbrk, char *, (char const *__s, char const *__accept)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1, 2)));\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C\" { const char * strpbrk (const char *, const char *); }\n       extern \"C++\" { char * strpbrk (char *, const char *); }  */\n_GL_CXXALIAS_SYS_CAST2 (strpbrk,\n                        char *, (char const *__s, char const *__accept),\n                        const char *, (char const *__s, char const *__accept));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (strpbrk, char *, (char *__s, char const *__accept));\n_GL_CXXALIASWARN1 (strpbrk, char const *,\n                   (char const *__s, char const *__accept));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (strpbrk);\n# endif\n# if defined GNULIB_POSIXCHECK\n/* strpbrk() assumes the second argument is a list of single-byte characters.\n   Even in this simple case, it does not work with multibyte strings if the\n   locale encoding is GB18030 and one of the characters to be searched is a\n   digit.  */\n#  undef strpbrk\n_GL_WARN_ON_USE_CXX (strpbrk,\n                     const char *, char *, (const char *, const char *),\n                     \"strpbrk cannot work correctly on character strings \"\n                     \"in multibyte locales - \"\n                     \"use mbspbrk if you care about internationalization\");\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strpbrk\n# if HAVE_RAW_DECL_STRPBRK\n_GL_WARN_ON_USE_CXX (strpbrk,\n                     const char *, char *, (const char *, const char *),\n                     \"strpbrk is unportable - \"\n                     \"use gnulib module strpbrk for portability\");\n# endif\n#endif\n\n#if defined GNULIB_POSIXCHECK\n/* strspn() assumes the second argument is a list of single-byte characters.\n   Even in this simple case, it cannot work with multibyte strings.  */\n# undef strspn\n/* Assume strspn is always declared.  */\n_GL_WARN_ON_USE (strspn, \"strspn cannot work correctly on character strings \"\n                 \"in multibyte locales - \"\n                 \"use mbsspn if you care about internationalization\");\n#endif\n\n#if defined GNULIB_POSIXCHECK\n/* strrchr() does not work with multibyte strings if the locale encoding is\n   GB18030 and the character to be searched is a digit.  */\n# undef strrchr\n/* Assume strrchr is always declared.  */\n_GL_WARN_ON_USE_CXX (strrchr,\n                     const char *, char *, (const char *, int),\n                     \"strrchr cannot work correctly on character strings \"\n                     \"in some multibyte locales - \"\n                     \"use mbsrchr if you care about internationalization\");\n#endif\n\n/* Search the next delimiter (char listed in DELIM) starting at *STRINGP.\n   If one is found, overwrite it with a NUL, and advance *STRINGP\n   to point to the next char after it.  Otherwise, set *STRINGP to NULL.\n   If *STRINGP was already NULL, nothing happens.\n   Return the old value of *STRINGP.\n\n   This is a variant of strtok() that is multithread-safe and supports\n   empty fields.\n\n   Caveat: It modifies the original string.\n   Caveat: These functions cannot be used on constant strings.\n   Caveat: The identity of the delimiting character is lost.\n   Caveat: It doesn't work with multibyte strings unless all of the delimiter\n           characters are ASCII characters < 0x30.\n\n   See also strtok_r().  */\n#if 0\n# if ! 1\n_GL_FUNCDECL_SYS (strsep, char *,\n                  (char **restrict __stringp, char const *restrict __delim)\n                  _GL_ARG_NONNULL ((1, 2)));\n# endif\n_GL_CXXALIAS_SYS (strsep, char *,\n                  (char **restrict __stringp, char const *restrict __delim));\n_GL_CXXALIASWARN (strsep);\n# if defined GNULIB_POSIXCHECK\n#  undef strsep\n_GL_WARN_ON_USE (strsep, \"strsep cannot work correctly on character strings \"\n                 \"in multibyte locales - \"\n                 \"use mbssep if you care about internationalization\");\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strsep\n# if HAVE_RAW_DECL_STRSEP\n_GL_WARN_ON_USE (strsep, \"strsep is unportable - \"\n                 \"use gnulib module strsep for portability\");\n# endif\n#endif\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strstr rpl_strstr\n#  endif\n_GL_FUNCDECL_RPL (strstr, char *, (const char *haystack, const char *needle)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (strstr, char *, (const char *haystack, const char *needle));\n# else\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" { const char * strstr (const char *, const char *); }\n       extern \"C++\" { char * strstr (char *, const char *); }  */\n_GL_CXXALIAS_SYS_CAST2 (strstr,\n                        char *, (const char *haystack, const char *needle),\n                        const char *, (const char *haystack, const char *needle));\n# endif\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (strstr, char *, (char *haystack, const char *needle));\n_GL_CXXALIASWARN1 (strstr, const char *,\n                   (const char *haystack, const char *needle));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (strstr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n/* strstr() does not work with multibyte strings if the locale encoding is\n   different from UTF-8:\n   POSIX says that it operates on \"strings\", and \"string\" in POSIX is defined\n   as a sequence of bytes, not of characters.  */\n# undef strstr\n/* Assume strstr is always declared.  */\n_GL_WARN_ON_USE (strstr, \"strstr is quadratic on many systems, and cannot \"\n                 \"work correctly on character strings in most \"\n                 \"multibyte locales - \"\n                 \"use mbsstr if you care about internationalization, \"\n                 \"or use strstr if you care about speed\");\n#endif\n\n/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive\n   comparison.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strcasestr rpl_strcasestr\n#  endif\n_GL_FUNCDECL_RPL (strcasestr, char *,\n                  (const char *haystack, const char *needle)\n                  _GL_ATTRIBUTE_PURE\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (strcasestr, char *,\n                  (const char *haystack, const char *needle));\n# else\n#  if ! 1\n_GL_FUNCDECL_SYS (strcasestr, char *,\n                  (const char *haystack, const char *needle)\n                  _GL_ATTRIBUTE_PURE\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" { const char * strcasestr (const char *, const char *); }\n       extern \"C++\" { char * strcasestr (char *, const char *); }  */\n_GL_CXXALIAS_SYS_CAST2 (strcasestr,\n                        char *, (const char *haystack, const char *needle),\n                        const char *, (const char *haystack, const char *needle));\n# endif\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (strcasestr, char *, (char *haystack, const char *needle));\n_GL_CXXALIASWARN1 (strcasestr, const char *,\n                   (const char *haystack, const char *needle));\n# else\n_GL_CXXALIASWARN (strcasestr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n/* strcasestr() does not work with multibyte strings:\n   It is a glibc extension, and glibc implements it only for unibyte\n   locales.  */\n# undef strcasestr\n# if HAVE_RAW_DECL_STRCASESTR\n_GL_WARN_ON_USE (strcasestr, \"strcasestr does work correctly on character \"\n                 \"strings in multibyte locales - \"\n                 \"use mbscasestr if you care about \"\n                 \"internationalization, or use c-strcasestr if you want \"\n                 \"a locale independent function\");\n# endif\n#endif\n\n/* Parse S into tokens separated by characters in DELIM.\n   If S is NULL, the saved pointer in SAVE_PTR is used as\n   the next starting point.  For example:\n        char s[] = \"-abc-=-def\";\n        char *sp;\n        x = strtok_r(s, \"-\", &sp);      // x = \"abc\", sp = \"=-def\"\n        x = strtok_r(NULL, \"-=\", &sp);  // x = \"def\", sp = NULL\n        x = strtok_r(NULL, \"=\", &sp);   // x = NULL\n                // s = \"abc\\0-def\\0\"\n\n   This is a variant of strtok() that is multithread-safe.\n\n   For the POSIX documentation for this function, see:\n   https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtok.html\n\n   Caveat: It modifies the original string.\n   Caveat: These functions cannot be used on constant strings.\n   Caveat: The identity of the delimiting character is lost.\n   Caveat: It doesn't work with multibyte strings unless all of the delimiter\n           characters are ASCII characters < 0x30.\n\n   See also strsep().  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strtok_r\n#   define strtok_r rpl_strtok_r\n#  endif\n_GL_FUNCDECL_RPL (strtok_r, char *,\n                  (char *restrict s, char const *restrict delim,\n                   char **restrict save_ptr)\n                  _GL_ARG_NONNULL ((2, 3)));\n_GL_CXXALIAS_RPL (strtok_r, char *,\n                  (char *restrict s, char const *restrict delim,\n                   char **restrict save_ptr));\n# else\n#  if 0 || defined GNULIB_POSIXCHECK\n#   undef strtok_r\n#  endif\n#  if ! 1\n_GL_FUNCDECL_SYS (strtok_r, char *,\n                  (char *restrict s, char const *restrict delim,\n                   char **restrict save_ptr)\n                  _GL_ARG_NONNULL ((2, 3)));\n#  endif\n_GL_CXXALIAS_SYS (strtok_r, char *,\n                  (char *restrict s, char const *restrict delim,\n                   char **restrict save_ptr));\n# endif\n_GL_CXXALIASWARN (strtok_r);\n# if defined GNULIB_POSIXCHECK\n_GL_WARN_ON_USE (strtok_r, \"strtok_r cannot work correctly on character \"\n                 \"strings in multibyte locales - \"\n                 \"use mbstok_r if you care about internationalization\");\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strtok_r\n# if HAVE_RAW_DECL_STRTOK_R\n_GL_WARN_ON_USE (strtok_r, \"strtok_r is unportable - \"\n                 \"use gnulib module strtok_r for portability\");\n# endif\n#endif\n\n\n/* The following functions are not specified by POSIX.  They are gnulib\n   extensions.  */\n\n#if 0\n/* Return the number of multibyte characters in the character string STRING.\n   This considers multibyte characters, unlike strlen, which counts bytes.  */\n# ifdef __MirBSD__  /* MirBSD defines mbslen as a macro.  Override it.  */\n#  undef mbslen\n# endif\n# if 0  /* AIX, OSF/1, MirBSD define mbslen already in libc.  */\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define mbslen rpl_mbslen\n#  endif\n_GL_FUNCDECL_RPL (mbslen, size_t, (const char *string)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (mbslen, size_t, (const char *string));\n# else\n_GL_FUNCDECL_SYS (mbslen, size_t, (const char *string)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_SYS (mbslen, size_t, (const char *string));\n# endif\n_GL_CXXALIASWARN (mbslen);\n#endif\n\n#if 0\n/* Return the number of multibyte characters in the character string starting\n   at STRING and ending at STRING + LEN.  */\n_GL_EXTERN_C size_t mbsnlen (const char *string, size_t len)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1));\n#endif\n\n#if 0\n/* Locate the first single-byte character C in the character string STRING,\n   and return a pointer to it.  Return NULL if C is not found in STRING.\n   Unlike strchr(), this function works correctly in multibyte locales with\n   encodings such as GB18030.  */\n# if defined __hpux\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define mbschr rpl_mbschr /* avoid collision with HP-UX function */\n#  endif\n_GL_FUNCDECL_RPL (mbschr, char *, (const char *string, int c)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (mbschr, char *, (const char *string, int c));\n# else\n_GL_FUNCDECL_SYS (mbschr, char *, (const char *string, int c)\n                                  _GL_ATTRIBUTE_PURE\n                                  _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_SYS (mbschr, char *, (const char *string, int c));\n# endif\n_GL_CXXALIASWARN (mbschr);\n#endif\n\n#if 0\n/* Locate the last single-byte character C in the character string STRING,\n   and return a pointer to it.  Return NULL if C is not found in STRING.\n   Unlike strrchr(), this function works correctly in multibyte locales with\n   encodings such as GB18030.  */\n# if defined __hpux || defined __INTERIX\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define mbsrchr rpl_mbsrchr /* avoid collision with system function */\n#  endif\n_GL_FUNCDECL_RPL (mbsrchr, char *, (const char *string, int c)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (mbsrchr, char *, (const char *string, int c));\n# else\n_GL_FUNCDECL_SYS (mbsrchr, char *, (const char *string, int c)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_SYS (mbsrchr, char *, (const char *string, int c));\n# endif\n_GL_CXXALIASWARN (mbsrchr);\n#endif\n\n#if 0\n/* Find the first occurrence of the character string NEEDLE in the character\n   string HAYSTACK.  Return NULL if NEEDLE is not found in HAYSTACK.\n   Unlike strstr(), this function works correctly in multibyte locales with\n   encodings different from UTF-8.  */\n_GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if 0\n/* Compare the character strings S1 and S2, ignoring case, returning less than,\n   equal to or greater than zero if S1 is lexicographically less than, equal to\n   or greater than S2.\n   Note: This function may, in multibyte locales, return 0 for strings of\n   different lengths!\n   Unlike strcasecmp(), this function works correctly in multibyte locales.  */\n_GL_EXTERN_C int mbscasecmp (const char *s1, const char *s2)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if 0\n/* Compare the initial segment of the character string S1 consisting of at most\n   N characters with the initial segment of the character string S2 consisting\n   of at most N characters, ignoring case, returning less than, equal to or\n   greater than zero if the initial segment of S1 is lexicographically less\n   than, equal to or greater than the initial segment of S2.\n   Note: This function may, in multibyte locales, return 0 for initial segments\n   of different lengths!\n   Unlike strncasecmp(), this function works correctly in multibyte locales.\n   But beware that N is not a byte count but a character count!  */\n_GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if 0\n/* Compare the initial segment of the character string STRING consisting of\n   at most mbslen (PREFIX) characters with the character string PREFIX,\n   ignoring case.  If the two match, return a pointer to the first byte\n   after this prefix in STRING.  Otherwise, return NULL.\n   Note: This function may, in multibyte locales, return non-NULL if STRING\n   is of smaller length than PREFIX!\n   Unlike strncasecmp(), this function works correctly in multibyte\n   locales.  */\n_GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if 0\n/* Find the first occurrence of the character string NEEDLE in the character\n   string HAYSTACK, using case-insensitive comparison.\n   Note: This function may, in multibyte locales, return success even if\n   strlen (haystack) < strlen (needle) !\n   Unlike strcasestr(), this function works correctly in multibyte locales.  */\n_GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if 0\n/* Find the first occurrence in the character string STRING of any character\n   in the character string ACCEPT.  Return the number of bytes from the\n   beginning of the string to this occurrence, or to the end of the string\n   if none exists.\n   Unlike strcspn(), this function works correctly in multibyte locales.  */\n_GL_EXTERN_C size_t mbscspn (const char *string, const char *accept)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if 0\n/* Find the first occurrence in the character string STRING of any character\n   in the character string ACCEPT.  Return the pointer to it, or NULL if none\n   exists.\n   Unlike strpbrk(), this function works correctly in multibyte locales.  */\n# if defined __hpux\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */\n#  endif\n_GL_FUNCDECL_RPL (mbspbrk, char *, (const char *string, const char *accept)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (mbspbrk, char *, (const char *string, const char *accept));\n# else\n_GL_FUNCDECL_SYS (mbspbrk, char *, (const char *string, const char *accept)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_SYS (mbspbrk, char *, (const char *string, const char *accept));\n# endif\n_GL_CXXALIASWARN (mbspbrk);\n#endif\n\n#if 0\n/* Find the first occurrence in the character string STRING of any character\n   not in the character string REJECT.  Return the number of bytes from the\n   beginning of the string to this occurrence, or to the end of the string\n   if none exists.\n   Unlike strspn(), this function works correctly in multibyte locales.  */\n_GL_EXTERN_C size_t mbsspn (const char *string, const char *reject)\n     _GL_ATTRIBUTE_PURE\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if 0\n/* Search the next delimiter (multibyte character listed in the character\n   string DELIM) starting at the character string *STRINGP.\n   If one is found, overwrite it with a NUL, and advance *STRINGP to point\n   to the next multibyte character after it.  Otherwise, set *STRINGP to NULL.\n   If *STRINGP was already NULL, nothing happens.\n   Return the old value of *STRINGP.\n\n   This is a variant of mbstok_r() that supports empty fields.\n\n   Caveat: It modifies the original string.\n   Caveat: These functions cannot be used on constant strings.\n   Caveat: The identity of the delimiting character is lost.\n\n   See also mbstok_r().  */\n_GL_EXTERN_C char * mbssep (char **stringp, const char *delim)\n     _GL_ARG_NONNULL ((1, 2));\n#endif\n\n#if 0\n/* Parse the character string STRING into tokens separated by characters in\n   the character string DELIM.\n   If STRING is NULL, the saved pointer in SAVE_PTR is used as\n   the next starting point.  For example:\n        char s[] = \"-abc-=-def\";\n        char *sp;\n        x = mbstok_r(s, \"-\", &sp);      // x = \"abc\", sp = \"=-def\"\n        x = mbstok_r(NULL, \"-=\", &sp);  // x = \"def\", sp = NULL\n        x = mbstok_r(NULL, \"=\", &sp);   // x = NULL\n                // s = \"abc\\0-def\\0\"\n\n   Caveat: It modifies the original string.\n   Caveat: These functions cannot be used on constant strings.\n   Caveat: The identity of the delimiting character is lost.\n\n   See also mbssep().  */\n_GL_EXTERN_C char * mbstok_r (char *restrict string, const char *delim,\n                              char **save_ptr)\n     _GL_ARG_NONNULL ((2, 3));\n#endif\n\n/* Map any int, typically from errno, into an error message.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strerror\n#   define strerror rpl_strerror\n#  endif\n_GL_FUNCDECL_RPL (strerror, char *, (int));\n_GL_CXXALIAS_RPL (strerror, char *, (int));\n# else\n_GL_CXXALIAS_SYS (strerror, char *, (int));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (strerror);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strerror\n/* Assume strerror is always declared.  */\n_GL_WARN_ON_USE (strerror, \"strerror is unportable - \"\n                 \"use gnulib module strerror to guarantee non-NULL result\");\n#endif\n\n/* Map any int, typically from errno, into an error message.  Multithread-safe.\n   Uses the POSIX declaration, not the glibc declaration.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strerror_r\n#   define strerror_r rpl_strerror_r\n#  endif\n_GL_FUNCDECL_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen)\n                                   _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen)\n                                   _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen));\n# endif\n# if 1\n_GL_CXXALIASWARN (strerror_r);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef strerror_r\n# if HAVE_RAW_DECL_STRERROR_R\n_GL_WARN_ON_USE (strerror_r, \"strerror_r is unportable - \"\n                 \"use gnulib module strerror_r-posix for portability\");\n# endif\n#endif\n\n/* Return the name of the system error code ERRNUM.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef strerrorname_np\n#   define strerrorname_np rpl_strerrorname_np\n#  endif\n_GL_FUNCDECL_RPL (strerrorname_np, const char *, (int errnum));\n_GL_CXXALIAS_RPL (strerrorname_np, const char *, (int errnum));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (strerrorname_np, const char *, (int errnum));\n#  endif\n_GL_CXXALIAS_SYS (strerrorname_np, const char *, (int errnum));\n# endif\n_GL_CXXALIASWARN (strerrorname_np);\n#elif defined GNULIB_POSIXCHECK\n# undef strerrorname_np\n# if HAVE_RAW_DECL_STRERRORNAME_NP\n_GL_WARN_ON_USE (strerrorname_np, \"strerrorname_np is unportable - \"\n                 \"use gnulib module strerrorname_np for portability\");\n# endif\n#endif\n\n/* Return an abbreviation string for the signal number SIG.  */\n#if 0\n# if ! 1\n_GL_FUNCDECL_SYS (sigabbrev_np, const char *, (int sig));\n# endif\n_GL_CXXALIAS_SYS (sigabbrev_np, const char *, (int sig));\n_GL_CXXALIASWARN (sigabbrev_np);\n#elif defined GNULIB_POSIXCHECK\n# undef sigabbrev_np\n# if HAVE_RAW_DECL_SIGABBREV_NP\n_GL_WARN_ON_USE (sigabbrev_np, \"sigabbrev_np is unportable - \"\n                 \"use gnulib module sigabbrev_np for portability\");\n# endif\n#endif\n\n/* Return an English description string for the signal number SIG.  */\n#if 0\n# if ! 1\n_GL_FUNCDECL_SYS (sigdescr_np, const char *, (int sig));\n# endif\n_GL_CXXALIAS_SYS (sigdescr_np, const char *, (int sig));\n_GL_CXXALIASWARN (sigdescr_np);\n#elif defined GNULIB_POSIXCHECK\n# undef sigdescr_np\n# if HAVE_RAW_DECL_SIGDESCR_NP\n_GL_WARN_ON_USE (sigdescr_np, \"sigdescr_np is unportable - \"\n                 \"use gnulib module sigdescr_np for portability\");\n# endif\n#endif\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define strsignal rpl_strsignal\n#  endif\n_GL_FUNCDECL_RPL (strsignal, char *, (int __sig));\n_GL_CXXALIAS_RPL (strsignal, char *, (int __sig));\n# else\n#  if ! 1\n_GL_FUNCDECL_SYS (strsignal, char *, (int __sig));\n#  endif\n/* Need to cast, because on Cygwin 1.5.x systems, the return type is\n   'const char *'.  */\n_GL_CXXALIAS_SYS_CAST (strsignal, char *, (int __sig));\n# endif\n_GL_CXXALIASWARN (strsignal);\n#elif defined GNULIB_POSIXCHECK\n# undef strsignal\n# if HAVE_RAW_DECL_STRSIGNAL\n_GL_WARN_ON_USE (strsignal, \"strsignal is unportable - \"\n                 \"use gnulib module strsignal for portability\");\n# endif\n#endif\n\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *)\n                                   _GL_ATTRIBUTE_PURE\n                                   _GL_ARG_NONNULL ((1, 2)));\n# endif\n_GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *));\n_GL_CXXALIASWARN (strverscmp);\n#elif defined GNULIB_POSIXCHECK\n# undef strverscmp\n# if HAVE_RAW_DECL_STRVERSCMP\n_GL_WARN_ON_USE (strverscmp, \"strverscmp is unportable - \"\n                 \"use gnulib module strverscmp for portability\");\n# endif\n#endif\n\n\n#endif /* _GL_STRING_H */\n#endif /* _GL_STRING_H */\n#endif\n"
  },
  {
    "path": "win32/gnulib_h/unistd.h",
    "content": "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\n/* Substitute for and wrapper around <unistd.h>.\n   Copyright (C) 2003-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _GL_UNISTD_H\n\n#if __GNUC__ >= 3\n#pragma GCC system_header\n#endif\n\n\n#if 1 && defined _GL_INCLUDING_UNISTD_H\n/* Special invocation convention:\n   - On Mac OS X 10.3.9 we have a sequence of nested includes\n     <unistd.h> -> <signal.h> -> <pthread.h> -> <unistd.h>\n     In this situation, the functions are not yet declared, therefore we cannot\n     provide the C++ aliases.  */\n\n#include_next <unistd.h>\n\n#else\n/* Normal invocation convention.  */\n\n/* The include_next requires a split double-inclusion guard.  */\n#if 1\n# define _GL_INCLUDING_UNISTD_H\n# include_next <unistd.h>\n# undef _GL_INCLUDING_UNISTD_H\n#endif\n\n/* Get all possible declarations of gethostname().  */\n#if 0 && 0 \\\n  && !defined _GL_INCLUDING_WINSOCK2_H\n# define _GL_INCLUDING_WINSOCK2_H\n# include <winsock2.h>\n# undef _GL_INCLUDING_WINSOCK2_H\n#endif\n\n#if !defined _GL_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H\n#define _GL_UNISTD_H\n\n/* NetBSD 5.0 mis-defines NULL.  Also get size_t.  */\n/* But avoid namespace pollution on glibc systems.  */\n#ifndef __GLIBC__\n# include <stddef.h>\n#endif\n\n/* mingw doesn't define the SEEK_* or *_FILENO macros in <unistd.h>.  */\n/* MSVC declares 'unlink' in <stdio.h>, not in <unistd.h>.  We must include\n   it before we  #define unlink rpl_unlink.  */\n/* Cygwin 1.7.1 declares symlinkat in <stdio.h>, not in <unistd.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if (!(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) \\\n     || ((0 || defined GNULIB_POSIXCHECK) \\\n         && (defined _WIN32 && ! defined __CYGWIN__)) \\\n     || ((0 || defined GNULIB_POSIXCHECK) \\\n         && defined __CYGWIN__)) \\\n    && ! defined __GLIBC__\n# include <stdio.h>\n#endif\n\n/* Cygwin 1.7.1 and Android 4.3 declare unlinkat in <fcntl.h>, not in\n   <unistd.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if (0 || defined GNULIB_POSIXCHECK) \\\n    && (defined __CYGWIN__ || defined __ANDROID__) \\\n    && ! defined __GLIBC__\n# include <fcntl.h>\n#endif\n\n/* mingw fails to declare _exit in <unistd.h>.  */\n/* mingw, MSVC, BeOS, Haiku declare environ in <stdlib.h>, not in\n   <unistd.h>.  */\n/* Solaris declares getcwd not only in <unistd.h> but also in <stdlib.h>.  */\n/* OSF Tru64 Unix cannot see gnulib rpl_strtod when system <stdlib.h> is\n   included here.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if !defined __GLIBC__ && !defined __osf__\n# define __need_system_stdlib_h\n# include <stdlib.h>\n# undef __need_system_stdlib_h\n#endif\n\n/* Native Windows platforms declare _chdir, _getcwd, _rmdir in\n   <io.h> and/or <direct.h>, not in <unistd.h>.\n   They also declare _access(), _chmod(), _close(), _dup(), _dup2(), _isatty(),\n   _lseek(), _read(), _unlink(), _write() in <io.h>.  */\n#if defined _WIN32 && !defined __CYGWIN__\n# include <io.h>\n# include <direct.h>\n#endif\n\n/* Native Windows platforms declare _execl*, _execv* in <process.h>.  */\n#if defined _WIN32 && !defined __CYGWIN__\n# include <process.h>\n#endif\n\n/* AIX and OSF/1 5.1 declare getdomainname in <netdb.h>, not in <unistd.h>.\n   NonStop Kernel declares gethostname in <netdb.h>, not in <unistd.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if ((0 && (defined _AIX || defined __osf__)) \\\n     || (0 && defined __TANDEM)) \\\n    && !defined __GLIBC__\n# include <netdb.h>\n#endif\n\n/* Mac OS X 10.13, Solaris 11.4, and Android 9.0 declare getentropy in\n   <sys/random.h>, not in <unistd.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if (0 || defined GNULIB_POSIXCHECK) \\\n    && ((defined __APPLE__ && defined __MACH__) || defined __sun \\\n        || defined __ANDROID__) \\\n    && 0 \\\n    && !defined __GLIBC__\n# include <sys/random.h>\n#endif\n\n/* Android 4.3 declares fchownat in <sys/stat.h>, not in <unistd.h>.  */\n/* But avoid namespace pollution on glibc systems.  */\n#if (0 || defined GNULIB_POSIXCHECK) && defined __ANDROID__ \\\n    && !defined __GLIBC__\n# include <sys/stat.h>\n#endif\n\n/* MSVC defines off_t in <sys/types.h>.\n   May also define off_t to a 64-bit type on native Windows.  */\n/* Get off_t, ssize_t, mode_t.  */\n#include <sys/types.h>\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n/* C++ compatible function declaration macros.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _GL_CXXDEFS_H\n#define _GL_CXXDEFS_H\n\n/* Begin/end the GNULIB_NAMESPACE namespace.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {\n# define _GL_END_NAMESPACE }\n#else\n# define _GL_BEGIN_NAMESPACE\n# define _GL_END_NAMESPACE\n#endif\n\n/* The three most frequent use cases of these macros are:\n\n   * For providing a substitute for a function that is missing on some\n     platforms, but is declared and works fine on the platforms on which\n     it exists:\n\n       #if @GNULIB_FOO@\n       # if !@HAVE_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       # endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on all platforms,\n     but is broken/insufficient and needs to be replaced on some platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on some platforms\n     but is broken/insufficient and needs to be replaced on some of them and\n     is additionally either missing or undeclared on some other platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       #  endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n*/\n\n/* _GL_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#if defined __cplusplus\n# define _GL_EXTERN_C extern \"C\"\n#else\n# define _GL_EXTERN_C extern\n#endif\n\n/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);\n   declares a replacement function, named rpl_func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \\\n  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)\n#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype rpl_func parameters_and_attributes\n\n/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);\n   declares the system function, named func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype func parameters_and_attributes\n\n/* _GL_CXXALIAS_RPL (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));\n\n   Wrapping rpl_func in an object with an inline conversion operator\n   avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#define _GL_CXXALIAS_RPL(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::rpl_func;                                  \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA (func, rettype, parameters);\n   is to be used when func is a Microsoft deprecated alias, on native Windows.\n   It declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to _func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));\n */\n#define _GL_CXXALIAS_MDA(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);\n   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);\n   except that the C function rpl_func may have a slightly different\n   declaration.  A cast is used to silence the \"invalid conversion\" error\n   that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                     \\\n    {                                                              \\\n      static const struct _gl_ ## func ## _wrapper                 \\\n      {                                                            \\\n        typedef rettype (*type) parameters;                        \\\n                                                                   \\\n        inline operator type () const                              \\\n        {                                                          \\\n          return reinterpret_cast<type>(::rpl_func);               \\\n        }                                                          \\\n      } func = {};                                                 \\\n    }                                                              \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_MDA (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_SYS (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to the system provided function func, if GNULIB_NAMESPACE\n   is defined.\n   Example:\n     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));\n\n   Wrapping func in an object with an inline conversion operator\n   avoids a reference to func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS(func,rettype,parameters)            \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::func;                                      \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                          \\\n    {                                                   \\\n      static const struct _gl_ ## func ## _wrapper      \\\n      {                                                 \\\n        typedef rettype (*type) parameters;             \\\n                                                        \\\n        inline operator type () const                   \\\n        {                                               \\\n          return reinterpret_cast<type>(::func);        \\\n        }                                               \\\n      } func = {};                                      \\\n    }                                                   \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function is picked among a set of overloaded functions,\n   namely the one with rettype2 and parameters2.  Two consecutive casts\n   are used to silence the \"cannot find a match\" and \"invalid conversion\"\n   errors that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n  /* The outer cast must be a reinterpret_cast.\n     The inner cast: When the function is defined as a set of overloaded\n     functions, it works as a static_cast<>, choosing the designated variant.\n     When the function is defined as a single variant, it works as a\n     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    namespace GNULIB_NAMESPACE                                                \\\n    {                                                                         \\\n      static const struct _gl_ ## func ## _wrapper                            \\\n      {                                                                       \\\n        typedef rettype (*type) parameters;                                   \\\n                                                                              \\\n        inline operator type () const                                         \\\n        {                                                                     \\\n          return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \\\n        }                                                                     \\\n      } func = {};                                                            \\\n    }                                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN (func);\n   causes a warning to be emitted when ::func is used but not when\n   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded\n   variants.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN(func) \\\n   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN_1(func,namespace) \\\n   _GL_CXXALIASWARN_2 (func, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n    _GL_WARN_ON_USE (func, \\\n                     \"The symbol ::\" #func \" refers to the system function. \" \\\n                     \"Use \" #namespace \"::\" #func \" instead.\")\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     extern __typeof__ (func) func\n# else\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN(func) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);\n   causes a warning to be emitted when the given overloaded variant of ::func\n   is used but not when GNULIB_NAMESPACE::func is used.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \\\n                        GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \\\n   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n    _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \\\n                         \"The symbol ::\" #func \" refers to the system function. \" \\\n                         \"Use \" #namespace \"::\" #func \" instead.\")\n# else\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n#endif /* _GL_CXXDEFS_H */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n/* A C macro for declaring that specific arguments must not be NULL.\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools\n   that the values passed as arguments n, ..., m must be non-NULL pointers.\n   n = 1 stands for the first argument, n = 2 for the second argument etc.  */\n#ifndef _GL_ARG_NONNULL\n# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__\n#  define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))\n# else\n#  define _GL_ARG_NONNULL(params)\n# endif\n#endif\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n/* A C macro for emitting warnings if a function is used.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_WARN_ON_USE (function, \"literal string\") issues a declaration\n   for FUNCTION which will then trigger a compiler warning containing\n   the text of \"literal string\" anywhere that function is called, if\n   supported by the compiler.  If the compiler does not support this\n   feature, the macro expands to an unused extern declaration.\n\n   _GL_WARN_ON_USE_ATTRIBUTE (\"literal string\") expands to the\n   attribute used in _GL_WARN_ON_USE.  If the compiler does not support\n   this feature, it expands to empty.\n\n   These macros are useful for marking a function as a potential\n   portability trap, with the intent that \"literal string\" include\n   instructions on the replacement function that should be used\n   instead.\n   _GL_WARN_ON_USE is for functions with 'extern' linkage.\n   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'\n   linkage.\n\n   However, one of the reasons that a function is a portability trap is\n   if it has the wrong signature.  Declaring FUNCTION with a different\n   signature in C is a compilation error, so this macro must use the\n   same type as any existing declaration so that programs that avoid\n   the problematic FUNCTION do not fail to compile merely because they\n   included a header that poisoned the function.  But this implies that\n   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already\n   have a declaration.  Use of this macro implies that there must not\n   be any other macro hiding the declaration of FUNCTION; but\n   undefining FUNCTION first is part of the poisoning process anyway\n   (although for symbols that are provided only via a macro, the result\n   is a compilation error rather than a warning containing\n   \"literal string\").  Also note that in C++, it is only safe to use if\n   FUNCTION has no overloads.\n\n   For an example, it is possible to poison 'getline' by:\n   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],\n     [getline]) in configure.ac, which potentially defines\n     HAVE_RAW_DECL_GETLINE\n   - adding this code to a header that wraps the system <stdio.h>:\n     #undef getline\n     #if HAVE_RAW_DECL_GETLINE\n     _GL_WARN_ON_USE (getline, \"getline is required by POSIX 2008, but\"\n       \"not universally present; use the gnulib module getline\");\n     #endif\n\n   It is not possible to directly poison global variables.  But it is\n   possible to write a wrapper accessor function, and poison that\n   (less common usage, like &environ, will cause a compilation error\n   rather than issue the nice warning, but the end result of informing\n   the developer about their portability problem is still achieved):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     rpl_environ (void) { return &environ; }\n     _GL_WARN_ON_USE (rpl_environ, \"environ is not always properly declared\");\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   or better (avoiding contradictory use of 'static' and 'extern'):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     _GL_WARN_ON_USE_ATTRIBUTE (\"environ is not always properly declared\")\n     rpl_environ (void) { return &environ; }\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   */\n#ifndef _GL_WARN_ON_USE\n\n# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function __attribute__ ((__warning__ (message)))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__warning__ (message)))\n# elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# else /* Unsupported.  */\n#  define _GL_WARN_ON_USE(function, message) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# endif\n#endif\n\n/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, \"message\")\n   is like _GL_WARN_ON_USE (function, \"message\"), except that in C++ mode the\n   function is declared with the given prototype, consisting of return type,\n   parameters, and attributes.\n   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does\n   not work in this case.  */\n#ifndef _GL_WARN_ON_USE_CXX\n# if !defined __cplusplus\n#  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n     _GL_WARN_ON_USE (function, msg)\n# else\n#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes \\\n  __attribute__ ((__warning__ (msg)))\n#  elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_clang function parameters_and_attributes \\\n  __attribute__ ((__diagnose_if__ (1, msg, \"warning\")))\n#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes\n#  else /* Unsupported.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  endif\n# endif\n#endif\n\n/* _GL_WARN_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#ifndef _GL_WARN_EXTERN_C\n# if defined __cplusplus\n#  define _GL_WARN_EXTERN_C extern \"C\"\n# else\n#  define _GL_WARN_EXTERN_C extern\n# endif\n#endif\n\n\n/* Get getopt(), optarg, optind, opterr, optopt.  */\n#if 0 && 0 && !defined _GL_SYSTEM_GETOPT\n# include <getopt-cdefs.h>\n# include <getopt-pfx-core.h>\n#endif\n\n#ifndef _GL_INLINE_HEADER_BEGIN\n #error \"Please include config.h first.\"\n#endif\n_GL_INLINE_HEADER_BEGIN\n#ifndef _GL_UNISTD_INLINE\n# define _GL_UNISTD_INLINE _GL_INLINE\n#endif\n\n/* Hide some function declarations from <winsock2.h>.  */\n\n#if 0 && 0\n# if !defined _GL_SYS_SOCKET_H\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef socket\n#   define socket              socket_used_without_including_sys_socket_h\n#   undef connect\n#   define connect             connect_used_without_including_sys_socket_h\n#   undef accept\n#   define accept              accept_used_without_including_sys_socket_h\n#   undef bind\n#   define bind                bind_used_without_including_sys_socket_h\n#   undef getpeername\n#   define getpeername         getpeername_used_without_including_sys_socket_h\n#   undef getsockname\n#   define getsockname         getsockname_used_without_including_sys_socket_h\n#   undef getsockopt\n#   define getsockopt          getsockopt_used_without_including_sys_socket_h\n#   undef listen\n#   define listen              listen_used_without_including_sys_socket_h\n#   undef recv\n#   define recv                recv_used_without_including_sys_socket_h\n#   undef send\n#   define send                send_used_without_including_sys_socket_h\n#   undef recvfrom\n#   define recvfrom            recvfrom_used_without_including_sys_socket_h\n#   undef sendto\n#   define sendto              sendto_used_without_including_sys_socket_h\n#   undef setsockopt\n#   define setsockopt          setsockopt_used_without_including_sys_socket_h\n#   undef shutdown\n#   define shutdown            shutdown_used_without_including_sys_socket_h\n#  else\n    _GL_WARN_ON_USE (socket,\n                     \"socket() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (connect,\n                     \"connect() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (accept,\n                     \"accept() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (bind,\n                     \"bind() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (getpeername,\n                     \"getpeername() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (getsockname,\n                     \"getsockname() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (getsockopt,\n                     \"getsockopt() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (listen,\n                     \"listen() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (recv,\n                     \"recv() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (send,\n                     \"send() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (recvfrom,\n                     \"recvfrom() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (sendto,\n                     \"sendto() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (setsockopt,\n                     \"setsockopt() used without including <sys/socket.h>\");\n    _GL_WARN_ON_USE (shutdown,\n                     \"shutdown() used without including <sys/socket.h>\");\n#  endif\n# endif\n# if !defined _GL_SYS_SELECT_H\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef select\n#   define select              select_used_without_including_sys_select_h\n#  else\n    _GL_WARN_ON_USE (select,\n                     \"select() used without including <sys/select.h>\");\n#  endif\n# endif\n#endif\n\n\n/* OS/2 EMX lacks these macros.  */\n#ifndef STDIN_FILENO\n# define STDIN_FILENO 0\n#endif\n#ifndef STDOUT_FILENO\n# define STDOUT_FILENO 1\n#endif\n#ifndef STDERR_FILENO\n# define STDERR_FILENO 2\n#endif\n\n/* Ensure *_OK macros exist.  */\n#ifndef F_OK\n# define F_OK 0\n# define X_OK 1\n# define W_OK 2\n# define R_OK 4\n#endif\n\n\n/* Declare overridden functions.  */\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef access\n#   define access rpl_access\n#  endif\n_GL_FUNCDECL_RPL (access, int, (const char *file, int mode)\n                               _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (access, int, (const char *file, int mode));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef access\n#   define access _access\n#  endif\n_GL_CXXALIAS_MDA (access, int, (const char *file, int mode));\n# else\n_GL_CXXALIAS_SYS (access, int, (const char *file, int mode));\n# endif\n_GL_CXXALIASWARN (access);\n#elif defined GNULIB_POSIXCHECK\n# undef access\n# if HAVE_RAW_DECL_ACCESS\n/* The access() function is a security risk.  */\n_GL_WARN_ON_USE (access, \"access does not always support X_OK - \"\n                 \"use gnulib module access for portability; \"\n                 \"also, this function is a security risk - \"\n                 \"use the gnulib module faccessat instead\");\n# endif\n#elif 1\n/* On native Windows, map 'access' to '_access', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::access always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef access\n#   define access _access\n#  endif\n_GL_CXXALIAS_MDA (access, int, (const char *file, int mode));\n# else\n_GL_CXXALIAS_SYS (access, int, (const char *file, int mode));\n# endif\n_GL_CXXALIASWARN (access);\n#endif\n\n\n#if 0\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef chdir\n#   define chdir _chdir\n#  endif\n_GL_CXXALIAS_MDA (chdir, int, (const char *file));\n# else\n_GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIASWARN (chdir);\n#elif defined GNULIB_POSIXCHECK\n# undef chdir\n# if HAVE_RAW_DECL_CHDIR\n_GL_WARN_ON_USE (chown, \"chdir is not always in <unistd.h> - \"\n                 \"use gnulib module chdir for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'chdir' to '_chdir', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::chdir always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef chdir\n#   define chdir _chdir\n#  endif\n_GL_CXXALIAS_MDA (chdir, int, (const char *file));\n# else\n_GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIASWARN (chdir);\n#endif\n\n\n#if 0\n/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE\n   to GID (if GID is not -1).  Follow symbolic links.\n   Return 0 if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef chown\n#   define chown rpl_chown\n#  endif\n_GL_FUNCDECL_RPL (chown, int, (const char *file, uid_t uid, gid_t gid)\n                              _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (chown, int, (const char *file, uid_t uid, gid_t gid));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (chown, int, (const char *file, uid_t uid, gid_t gid)\n                              _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (chown, int, (const char *file, uid_t uid, gid_t gid));\n# endif\n_GL_CXXALIASWARN (chown);\n#elif defined GNULIB_POSIXCHECK\n# undef chown\n# if HAVE_RAW_DECL_CHOWN\n_GL_WARN_ON_USE (chown, \"chown fails to follow symlinks on some systems and \"\n                 \"doesn't treat a uid or gid of -1 on some systems - \"\n                 \"use gnulib module chown for portability\");\n# endif\n#endif\n\n\n#if 0\n# if 0\n/* Automatically included by modules that need a replacement for close.  */\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef close\n#   define close rpl_close\n#  endif\n_GL_FUNCDECL_RPL (close, int, (int fd));\n_GL_CXXALIAS_RPL (close, int, (int fd));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef close\n#   define close _close\n#  endif\n_GL_CXXALIAS_MDA (close, int, (int fd));\n# else\n_GL_CXXALIAS_SYS (close, int, (int fd));\n# endif\n_GL_CXXALIASWARN (close);\n#elif 0\n# undef close\n# define close close_used_without_requesting_gnulib_module_close\n#elif defined GNULIB_POSIXCHECK\n# undef close\n/* Assume close is always declared.  */\n_GL_WARN_ON_USE (close, \"close does not portably work on sockets - \"\n                 \"use gnulib module close for portability\");\n#elif 1\n/* On native Windows, map 'close' to '_close', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::close always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef close\n#   define close _close\n#  endif\n_GL_CXXALIAS_MDA (close, int, (int fd));\n# else\n_GL_CXXALIAS_SYS (close, int, (int fd));\n# endif\n_GL_CXXALIASWARN (close);\n#endif\n\n\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos,\n                                             int ofd, off_t *opos,\n                                             size_t len, unsigned flags));\n_GL_CXXALIAS_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos,\n                                             int ofd, off_t *opos,\n                                             size_t len, unsigned flags));\n# endif\n_GL_CXXALIASWARN (copy_file_range);\n#elif defined GNULIB_POSIXCHECK\n# if HAVE_RAW_DECL_COPY_FILE_RANGE\n_GL_WARN_ON_USE (copy_file_range,\n                 \"copy_file_range is unportable - \"\n                 \"use gnulib module copy_file_range for portability\");\n# endif\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define dup rpl_dup\n#  endif\n_GL_FUNCDECL_RPL (dup, int, (int oldfd));\n_GL_CXXALIAS_RPL (dup, int, (int oldfd));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef dup\n#   define dup _dup\n#  endif\n_GL_CXXALIAS_MDA (dup, int, (int oldfd));\n# else\n_GL_CXXALIAS_SYS (dup, int, (int oldfd));\n# endif\n_GL_CXXALIASWARN (dup);\n#elif defined GNULIB_POSIXCHECK\n# undef dup\n# if HAVE_RAW_DECL_DUP\n_GL_WARN_ON_USE (dup, \"dup is unportable - \"\n                 \"use gnulib module dup for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'dup' to '_dup', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::dup always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef dup\n#   define dup _dup\n#  endif\n_GL_CXXALIAS_MDA (dup, int, (int oldfd));\n# else\n_GL_CXXALIAS_SYS (dup, int, (int oldfd));\n# endif\n_GL_CXXALIASWARN (dup);\n#endif\n\n\n#if 0\n/* Copy the file descriptor OLDFD into file descriptor NEWFD.  Do nothing if\n   NEWFD = OLDFD, otherwise close NEWFD first if it is open.\n   Return newfd if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup2.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define dup2 rpl_dup2\n#  endif\n_GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd));\n_GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef dup2\n#   define dup2 _dup2\n#  endif\n_GL_CXXALIAS_MDA (dup2, int, (int oldfd, int newfd));\n# else\n_GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd));\n# endif\n_GL_CXXALIASWARN (dup2);\n#elif defined GNULIB_POSIXCHECK\n# undef dup2\n# if HAVE_RAW_DECL_DUP2\n_GL_WARN_ON_USE (dup2, \"dup2 is unportable - \"\n                 \"use gnulib module dup2 for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'dup2' to '_dup2', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::dup2 always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef dup2\n#   define dup2 _dup2\n#  endif\n_GL_CXXALIAS_MDA (dup2, int, (int oldfd, int newfd));\n# else\n_GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd));\n# endif\n_GL_CXXALIASWARN (dup2);\n#endif\n\n\n#if 0\n/* Copy the file descriptor OLDFD into file descriptor NEWFD, with the\n   specified flags.\n   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)\n   and O_TEXT, O_BINARY (defined in \"binary-io.h\").\n   Close NEWFD first if it is open.\n   Return newfd if successful, otherwise -1 and errno set.\n   See the Linux man page at\n   <https://www.kernel.org/doc/man-pages/online/pages/man2/dup3.2.html>.  */\n# if 1\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define dup3 rpl_dup3\n#  endif\n_GL_FUNCDECL_RPL (dup3, int, (int oldfd, int newfd, int flags));\n_GL_CXXALIAS_RPL (dup3, int, (int oldfd, int newfd, int flags));\n# else\n_GL_FUNCDECL_SYS (dup3, int, (int oldfd, int newfd, int flags));\n_GL_CXXALIAS_SYS (dup3, int, (int oldfd, int newfd, int flags));\n# endif\n_GL_CXXALIASWARN (dup3);\n#elif defined GNULIB_POSIXCHECK\n# undef dup3\n# if HAVE_RAW_DECL_DUP3\n_GL_WARN_ON_USE (dup3, \"dup3 is unportable - \"\n                 \"use gnulib module dup3 for portability\");\n# endif\n#endif\n\n\n#if 0\n# if defined __CYGWIN__ && !defined __i386__\n/* The 'environ' variable is defined in a DLL. Therefore its declaration needs\n   the '__declspec(dllimport)' attribute, but the system's <unistd.h> lacks it.\n   This leads to a link error on 64-bit Cygwin when the option\n   -Wl,--disable-auto-import is in use.  */\n_GL_EXTERN_C __declspec(dllimport) char **environ;\n# endif\n# if !1\n/* Set of environment variables and values.  An array of strings of the form\n   \"VARIABLE=VALUE\", terminated with a NULL.  */\n#  if defined __APPLE__ && defined __MACH__\n#   include <TargetConditionals.h>\n#   if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR\n#    define _GL_USE_CRT_EXTERNS\n#   endif\n#  endif\n#  ifdef _GL_USE_CRT_EXTERNS\n#   include <crt_externs.h>\n#   define environ (*_NSGetEnviron ())\n#  else\n#   ifdef __cplusplus\nextern \"C\" {\n#   endif\nextern char **environ;\n#   ifdef __cplusplus\n}\n#   endif\n#  endif\n# endif\n#elif defined GNULIB_POSIXCHECK\n# if HAVE_RAW_DECL_ENVIRON\n_GL_UNISTD_INLINE char ***\n_GL_WARN_ON_USE_ATTRIBUTE (\"environ is unportable - \"\n                           \"use gnulib module environ for portability\")\nrpl_environ (void)\n{\n  return &environ;\n}\n#  undef environ\n#  define environ (*rpl_environ ())\n# endif\n#endif\n\n\n#if 0\n/* Like access(), except that it uses the effective user id and group id of\n   the current process.  */\n# if !1\n_GL_FUNCDECL_SYS (euidaccess, int, (const char *filename, int mode)\n                                   _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (euidaccess, int, (const char *filename, int mode));\n_GL_CXXALIASWARN (euidaccess);\n# if defined GNULIB_POSIXCHECK\n/* Like access(), this function is a security risk.  */\n_GL_WARN_ON_USE (euidaccess, \"the euidaccess function is a security risk - \"\n                 \"use the gnulib module faccessat instead\");\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef euidaccess\n# if HAVE_RAW_DECL_EUIDACCESS\n_GL_WARN_ON_USE (euidaccess, \"euidaccess is unportable - \"\n                 \"use gnulib module euidaccess for portability\");\n# endif\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execl\n#   define execl rpl_execl\n#  endif\n_GL_FUNCDECL_RPL (execl, int, (const char *program, const char *arg, ...)\n                              _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (execl, int, (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execl, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execl);\n#elif defined GNULIB_POSIXCHECK\n# undef execl\n# if HAVE_RAW_DECL_EXECL\n_GL_WARN_ON_USE (execl, \"execl behaves very differently on mingw - \"\n                 \"use gnulib module execl for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'execl' to '_execl', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execl always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execl\n#   define execl _execl\n#  endif\n_GL_CXXALIAS_MDA (execl, intptr_t, (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execl, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execl);\n#endif\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execle\n#   define execle rpl_execle\n#  endif\n_GL_FUNCDECL_RPL (execle, int, (const char *program, const char *arg, ...)\n                               _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (execle, int, (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execle, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execle);\n#elif defined GNULIB_POSIXCHECK\n# undef execle\n# if HAVE_RAW_DECL_EXECLE\n_GL_WARN_ON_USE (execle, \"execle behaves very differently on mingw - \"\n                 \"use gnulib module execle for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'execle' to '_execle', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execle always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execle\n#   define execle _execle\n#  endif\n_GL_CXXALIAS_MDA (execle, intptr_t,\n                  (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execle, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execle);\n#endif\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execlp\n#   define execlp rpl_execlp\n#  endif\n_GL_FUNCDECL_RPL (execlp, int, (const char *program, const char *arg, ...)\n                               _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (execlp, int, (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execlp, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execlp);\n#elif defined GNULIB_POSIXCHECK\n# undef execlp\n# if HAVE_RAW_DECL_EXECLP\n_GL_WARN_ON_USE (execlp, \"execlp behaves very differently on mingw - \"\n                 \"use gnulib module execlp for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'execlp' to '_execlp', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execlp always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execlp\n#   define execlp _execlp\n#  endif\n_GL_CXXALIAS_MDA (execlp, intptr_t,\n                  (const char *program, const char *arg, ...));\n# else\n_GL_CXXALIAS_SYS (execlp, int, (const char *program, const char *arg, ...));\n# endif\n_GL_CXXALIASWARN (execlp);\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execv\n#   define execv rpl_execv\n#  endif\n_GL_FUNCDECL_RPL (execv, int, (const char *program, char * const *argv)\n                              _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (execv, int, (const char *program, char * const *argv));\n# else\n_GL_CXXALIAS_SYS (execv, int, (const char *program, char * const *argv));\n# endif\n_GL_CXXALIASWARN (execv);\n#elif defined GNULIB_POSIXCHECK\n# undef execv\n# if HAVE_RAW_DECL_EXECV\n_GL_WARN_ON_USE (execv, \"execv behaves very differently on mingw - \"\n                 \"use gnulib module execv for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'execv' to '_execv', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execv always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execv\n#   define execv _execv\n#  endif\n_GL_CXXALIAS_MDA_CAST (execv, intptr_t,\n                       (const char *program, char * const *argv));\n# else\n_GL_CXXALIAS_SYS (execv, int, (const char *program, char * const *argv));\n# endif\n_GL_CXXALIASWARN (execv);\n#endif\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execve\n#   define execve rpl_execve\n#  endif\n_GL_FUNCDECL_RPL (execve, int,\n                  (const char *program, char * const *argv, char * const *env)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (execve, int,\n                  (const char *program, char * const *argv, char * const *env));\n# else\n_GL_CXXALIAS_SYS (execve, int,\n                  (const char *program, char * const *argv, char * const *env));\n# endif\n_GL_CXXALIASWARN (execve);\n#elif defined GNULIB_POSIXCHECK\n# undef execve\n# if HAVE_RAW_DECL_EXECVE\n_GL_WARN_ON_USE (execve, \"execve behaves very differently on mingw - \"\n                 \"use gnulib module execve for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'execve' to '_execve', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execve always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execve\n#   define execve _execve\n#  endif\n_GL_CXXALIAS_MDA_CAST (execve, intptr_t,\n                       (const char *program, char * const *argv,\n                        char * const *env));\n# else\n_GL_CXXALIAS_SYS (execve, int,\n                  (const char *program, char * const *argv, char * const *env));\n# endif\n_GL_CXXALIASWARN (execve);\n#endif\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execvp\n#   define execvp rpl_execvp\n#  endif\n_GL_FUNCDECL_RPL (execvp, int, (const char *program, char * const *argv)\n                               _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (execvp, int, (const char *program, char * const *argv));\n# else\n_GL_CXXALIAS_SYS (execvp, int, (const char *program, char * const *argv));\n# endif\n_GL_CXXALIASWARN (execvp);\n#elif defined GNULIB_POSIXCHECK\n# undef execvp\n# if HAVE_RAW_DECL_EXECVP\n_GL_WARN_ON_USE (execvp, \"execvp behaves very differently on mingw - \"\n                 \"use gnulib module execvp for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'execvp' to '_execvp', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execvp always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execvp\n#   define execvp _execvp\n#  endif\n_GL_CXXALIAS_MDA_CAST (execvp, intptr_t,\n                       (const char *program, char * const *argv));\n# else\n_GL_CXXALIAS_SYS (execvp, int, (const char *program, char * const *argv));\n# endif\n_GL_CXXALIASWARN (execvp);\n#endif\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execvpe\n#   define execvpe rpl_execvpe\n#  endif\n_GL_FUNCDECL_RPL (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env));\n# endif\n_GL_CXXALIASWARN (execvpe);\n#elif defined GNULIB_POSIXCHECK\n# undef execvpe\n# if HAVE_RAW_DECL_EXECVPE\n_GL_WARN_ON_USE (execvpe, \"execvpe behaves very differently on mingw - \"\n                 \"use gnulib module execvpe for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'execvpe' to '_execvpe', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::execvpe on all platforms that have\n   it.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef execvpe\n#   define execvpe _execvpe\n#  endif\n_GL_CXXALIAS_MDA_CAST (execvpe, intptr_t,\n                       (const char *program, char * const *argv,\n                        char * const *env));\n# elif 1\n#  if !1\n_GL_FUNCDECL_SYS (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (execvpe, int,\n                  (const char *program, char * const *argv, char * const *env));\n# endif\n# if (defined _WIN32 && !defined __CYGWIN__) || 1\n_GL_CXXALIASWARN (execvpe);\n# endif\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef faccessat\n#   define faccessat rpl_faccessat\n#  endif\n_GL_FUNCDECL_RPL (faccessat, int,\n                  (int fd, char const *name, int mode, int flag)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (faccessat, int,\n                  (int fd, char const *name, int mode, int flag));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (faccessat, int,\n                  (int fd, char const *file, int mode, int flag)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (faccessat, int,\n                  (int fd, char const *file, int mode, int flag));\n# endif\n_GL_CXXALIASWARN (faccessat);\n#elif defined GNULIB_POSIXCHECK\n# undef faccessat\n# if HAVE_RAW_DECL_FACCESSAT\n_GL_WARN_ON_USE (faccessat, \"faccessat is not portable - \"\n                 \"use gnulib module faccessat for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Change the process' current working directory to the directory on which\n   the given file descriptor is open.\n   Return 0 if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html>.  */\n# if ! 1\n_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/));\n\n/* Gnulib internal hooks needed to maintain the fchdir metadata.  */\n_GL_EXTERN_C int _gl_register_fd (int fd, const char *filename)\n     _GL_ARG_NONNULL ((2));\n_GL_EXTERN_C void _gl_unregister_fd (int fd);\n_GL_EXTERN_C int _gl_register_dup (int oldfd, int newfd);\n_GL_EXTERN_C const char *_gl_directory_name (int fd);\n\n# else\n#  if !1\n_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/));\n#  endif\n# endif\n_GL_CXXALIAS_SYS (fchdir, int, (int /*fd*/));\n_GL_CXXALIASWARN (fchdir);\n#elif defined GNULIB_POSIXCHECK\n# undef fchdir\n# if HAVE_RAW_DECL_FCHDIR\n_GL_WARN_ON_USE (fchdir, \"fchdir is unportable - \"\n                 \"use gnulib module fchdir for portability\");\n# endif\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef fchownat\n#   define fchownat rpl_fchownat\n#  endif\n_GL_FUNCDECL_RPL (fchownat, int, (int fd, char const *file,\n                                  uid_t owner, gid_t group, int flag)\n                                 _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (fchownat, int, (int fd, char const *file,\n                                  uid_t owner, gid_t group, int flag));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (fchownat, int, (int fd, char const *file,\n                                  uid_t owner, gid_t group, int flag)\n                                 _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (fchownat, int, (int fd, char const *file,\n                                  uid_t owner, gid_t group, int flag));\n# endif\n_GL_CXXALIASWARN (fchownat);\n#elif defined GNULIB_POSIXCHECK\n# undef fchownat\n# if HAVE_RAW_DECL_FCHOWNAT\n_GL_WARN_ON_USE (fchownat, \"fchownat is not portable - \"\n                 \"use gnulib module fchownat for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Synchronize changes to a file.\n   Return 0 if successful, otherwise -1 and errno set.\n   See POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html>.  */\n# if !1 || !1\n_GL_FUNCDECL_SYS (fdatasync, int, (int fd));\n# endif\n_GL_CXXALIAS_SYS (fdatasync, int, (int fd));\n_GL_CXXALIASWARN (fdatasync);\n#elif defined GNULIB_POSIXCHECK\n# undef fdatasync\n# if HAVE_RAW_DECL_FDATASYNC\n_GL_WARN_ON_USE (fdatasync, \"fdatasync is unportable - \"\n                 \"use gnulib module fdatasync for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Synchronize changes, including metadata, to a file.\n   Return 0 if successful, otherwise -1 and errno set.\n   See POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html>.  */\n# if !1\n_GL_FUNCDECL_SYS (fsync, int, (int fd));\n# endif\n_GL_CXXALIAS_SYS (fsync, int, (int fd));\n_GL_CXXALIASWARN (fsync);\n#elif defined GNULIB_POSIXCHECK\n# undef fsync\n# if HAVE_RAW_DECL_FSYNC\n_GL_WARN_ON_USE (fsync, \"fsync is unportable - \"\n                 \"use gnulib module fsync for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Change the size of the file to which FD is opened to become equal to LENGTH.\n   Return 0 if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef ftruncate\n#   define ftruncate rpl_ftruncate\n#  endif\n_GL_FUNCDECL_RPL (ftruncate, int, (int fd, off_t length));\n_GL_CXXALIAS_RPL (ftruncate, int, (int fd, off_t length));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length));\n#  endif\n_GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length));\n# endif\n_GL_CXXALIASWARN (ftruncate);\n#elif defined GNULIB_POSIXCHECK\n# undef ftruncate\n# if HAVE_RAW_DECL_FTRUNCATE\n_GL_WARN_ON_USE (ftruncate, \"ftruncate is unportable - \"\n                 \"use gnulib module ftruncate for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Get the name of the current working directory, and put it in SIZE bytes\n   of BUF.\n   Return BUF if successful, or NULL if the directory couldn't be determined\n   or SIZE was too small.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html>.\n   Additionally, the gnulib module 'getcwd' guarantees the following GNU\n   extension: If BUF is NULL, an array is allocated with 'malloc'; the array\n   is SIZE bytes long, unless SIZE == 0, in which case it is as big as\n   necessary.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define getcwd rpl_getcwd\n#  endif\n_GL_FUNCDECL_RPL (getcwd, char *, (char *buf, size_t size));\n_GL_CXXALIAS_RPL (getcwd, char *, (char *buf, size_t size));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getcwd\n#   define getcwd _getcwd\n#  endif\n_GL_CXXALIAS_MDA (getcwd, char *, (char *buf, size_t size));\n# else\n/* Need to cast, because on mingw, the second parameter is\n                                                   int size.  */\n_GL_CXXALIAS_SYS_CAST (getcwd, char *, (char *buf, size_t size));\n# endif\n_GL_CXXALIASWARN (getcwd);\n#elif defined GNULIB_POSIXCHECK\n# undef getcwd\n# if HAVE_RAW_DECL_GETCWD\n_GL_WARN_ON_USE (getcwd, \"getcwd is unportable - \"\n                 \"use gnulib module getcwd for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'getcwd' to '_getcwd', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::getcwd always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getcwd\n#   define getcwd _getcwd\n#  endif\n/* Need to cast, because on mingw, the second parameter is either\n   'int size' or 'size_t size'.  */\n_GL_CXXALIAS_MDA_CAST (getcwd, char *, (char *buf, size_t size));\n# else\n_GL_CXXALIAS_SYS_CAST (getcwd, char *, (char *buf, size_t size));\n# endif\n_GL_CXXALIASWARN (getcwd);\n#endif\n\n\n#if 0\n/* Return the NIS domain name of the machine.\n   WARNING! The NIS domain name is unrelated to the fully qualified host name\n            of the machine.  It is also unrelated to email addresses.\n   WARNING! The NIS domain name is usually the empty string or \"(none)\" when\n            not using NIS.\n\n   Put up to LEN bytes of the NIS domain name into NAME.\n   Null terminate it if the name is shorter than LEN.\n   If the NIS domain name is longer than LEN, set errno = EINVAL and return -1.\n   Return 0 if successful, otherwise set errno and return -1.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getdomainname\n#   define getdomainname rpl_getdomainname\n#  endif\n_GL_FUNCDECL_RPL (getdomainname, int, (char *name, size_t len)\n                                      _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (getdomainname, int, (char *name, size_t len));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len)\n                                      _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (getdomainname, int, (char *name, size_t len));\n# endif\n_GL_CXXALIASWARN (getdomainname);\n#elif defined GNULIB_POSIXCHECK\n# undef getdomainname\n# if HAVE_RAW_DECL_GETDOMAINNAME\n_GL_WARN_ON_USE (getdomainname, \"getdomainname is unportable - \"\n                 \"use gnulib module getdomainname for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Return the maximum number of file descriptors in the current process.\n   In POSIX, this is same as sysconf (_SC_OPEN_MAX).  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getdtablesize\n#   define getdtablesize rpl_getdtablesize\n#  endif\n_GL_FUNCDECL_RPL (getdtablesize, int, (void));\n_GL_CXXALIAS_RPL (getdtablesize, int, (void));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (getdtablesize, int, (void));\n#  endif\n/* Need to cast, because on AIX, the parameter list is\n                                           (...).  */\n_GL_CXXALIAS_SYS_CAST (getdtablesize, int, (void));\n# endif\n_GL_CXXALIASWARN (getdtablesize);\n#elif defined GNULIB_POSIXCHECK\n# undef getdtablesize\n# if HAVE_RAW_DECL_GETDTABLESIZE\n_GL_WARN_ON_USE (getdtablesize, \"getdtablesize is unportable - \"\n                 \"use gnulib module getdtablesize for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Fill a buffer with random bytes.  */\n# if !1\n_GL_FUNCDECL_SYS (getentropy, int, (void *buffer, size_t length));\n# endif\n_GL_CXXALIAS_SYS (getentropy, int, (void *buffer, size_t length));\n_GL_CXXALIASWARN (getentropy);\n#elif defined GNULIB_POSIXCHECK\n# undef getentropy\n# if HAVE_RAW_DECL_GETENTROPY\n_GL_WARN_ON_USE (getentropy, \"getentropy is unportable - \"\n                 \"use gnulib module getentropy for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Return the supplemental groups that the current process belongs to.\n   It is unspecified whether the effective group id is in the list.\n   If N is 0, return the group count; otherwise, N describes how many\n   entries are available in GROUPS.  Return -1 and set errno if N is\n   not 0 and not large enough.  Fails with ENOSYS on some systems.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getgroups\n#   define getgroups rpl_getgroups\n#  endif\n_GL_FUNCDECL_RPL (getgroups, int, (int n, gid_t *groups));\n_GL_CXXALIAS_RPL (getgroups, int, (int n, gid_t *groups));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (getgroups, int, (int n, gid_t *groups));\n#  endif\n_GL_CXXALIAS_SYS (getgroups, int, (int n, gid_t *groups));\n# endif\n_GL_CXXALIASWARN (getgroups);\n#elif defined GNULIB_POSIXCHECK\n# undef getgroups\n# if HAVE_RAW_DECL_GETGROUPS\n_GL_WARN_ON_USE (getgroups, \"getgroups is unportable - \"\n                 \"use gnulib module getgroups for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Return the standard host name of the machine.\n   WARNING! The host name may or may not be fully qualified.\n\n   Put up to LEN bytes of the host name into NAME.\n   Null terminate it if the name is shorter than LEN.\n   If the host name is longer than LEN, set errno = EINVAL and return -1.\n   Return 0 if successful, otherwise set errno and return -1.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef gethostname\n#   define gethostname rpl_gethostname\n#  endif\n_GL_FUNCDECL_RPL (gethostname, int, (char *name, size_t len)\n                                    _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len)\n                                    _GL_ARG_NONNULL ((1)));\n#  endif\n/* Need to cast, because on Solaris 10 and OSF/1 5.1 systems, the second\n   parameter is\n                                                      int len.  */\n_GL_CXXALIAS_SYS_CAST (gethostname, int, (char *name, size_t len));\n# endif\n_GL_CXXALIASWARN (gethostname);\n#elif 0\n# undef gethostname\n# define gethostname gethostname_used_without_requesting_gnulib_module_gethostname\n#elif defined GNULIB_POSIXCHECK\n# undef gethostname\n# if HAVE_RAW_DECL_GETHOSTNAME\n_GL_WARN_ON_USE (gethostname, \"gethostname is unportable - \"\n                 \"use gnulib module gethostname for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Returns the user's login name, or NULL if it cannot be found.  Upon error,\n   returns NULL with errno set.\n\n   See <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getlogin.html>.\n\n   Most programs don't need to use this function, because the information is\n   available through environment variables:\n     ${LOGNAME-$USER}        on Unix platforms,\n     $USERNAME               on native Windows platforms.\n */\n# if !1\n_GL_FUNCDECL_SYS (getlogin, char *, (void));\n# endif\n_GL_CXXALIAS_SYS (getlogin, char *, (void));\n_GL_CXXALIASWARN (getlogin);\n#elif defined GNULIB_POSIXCHECK\n# undef getlogin\n# if HAVE_RAW_DECL_GETLOGIN\n_GL_WARN_ON_USE (getlogin, \"getlogin is unportable - \"\n                 \"use gnulib module getlogin for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Copies the user's login name to NAME.\n   The array pointed to by NAME has room for SIZE bytes.\n\n   Returns 0 if successful.  Upon error, an error number is returned, or -1 in\n   the case that the login name cannot be found but no specific error is\n   provided (this case is hopefully rare but is left open by the POSIX spec).\n\n   See <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getlogin.html>.\n\n   Most programs don't need to use this function, because the information is\n   available through environment variables:\n     ${LOGNAME-$USER}        on Unix platforms,\n     $USERNAME               on native Windows platforms.\n */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define getlogin_r rpl_getlogin_r\n#  endif\n_GL_FUNCDECL_RPL (getlogin_r, int, (char *name, size_t size)\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (getlogin_r, int, (char *name, size_t size));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size)\n                                   _GL_ARG_NONNULL ((1)));\n#  endif\n/* Need to cast, because on Solaris 10 systems, the second argument is\n                                                     int size.  */\n_GL_CXXALIAS_SYS_CAST (getlogin_r, int, (char *name, size_t size));\n# endif\n_GL_CXXALIASWARN (getlogin_r);\n#elif defined GNULIB_POSIXCHECK\n# undef getlogin_r\n# if HAVE_RAW_DECL_GETLOGIN_R\n_GL_WARN_ON_USE (getlogin_r, \"getlogin_r is unportable - \"\n                 \"use gnulib module getlogin_r for portability\");\n# endif\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define getpagesize rpl_getpagesize\n#  endif\n_GL_FUNCDECL_RPL (getpagesize, int, (void));\n_GL_CXXALIAS_RPL (getpagesize, int, (void));\n# else\n/* On HP-UX, getpagesize exists, but it is not declared in <unistd.h> even if\n   the compiler options -D_HPUX_SOURCE -D_XOPEN_SOURCE=600 are used.  */\n#  if defined __hpux\n_GL_FUNCDECL_SYS (getpagesize, int, (void));\n#  endif\n#  if !1\n#   if !defined getpagesize\n/* This is for POSIX systems.  */\n#    if !defined _gl_getpagesize && defined _SC_PAGESIZE\n#     if ! (defined __VMS && __VMS_VER < 70000000)\n#      define _gl_getpagesize() sysconf (_SC_PAGESIZE)\n#     endif\n#    endif\n/* This is for older VMS.  */\n#    if !defined _gl_getpagesize && defined __VMS\n#     ifdef __ALPHA\n#      define _gl_getpagesize() 8192\n#     else\n#      define _gl_getpagesize() 512\n#     endif\n#    endif\n/* This is for BeOS.  */\n#    if !defined _gl_getpagesize && 0\n#     include <OS.h>\n#     if defined B_PAGE_SIZE\n#      define _gl_getpagesize() B_PAGE_SIZE\n#     endif\n#    endif\n/* This is for AmigaOS4.0.  */\n#    if !defined _gl_getpagesize && defined __amigaos4__\n#     define _gl_getpagesize() 2048\n#    endif\n/* This is for older Unix systems.  */\n#    if !defined _gl_getpagesize && 0\n#     include <sys/param.h>\n#     ifdef EXEC_PAGESIZE\n#      define _gl_getpagesize() EXEC_PAGESIZE\n#     else\n#      ifdef NBPG\n#       ifndef CLSIZE\n#        define CLSIZE 1\n#       endif\n#       define _gl_getpagesize() (NBPG * CLSIZE)\n#      else\n#       ifdef NBPC\n#        define _gl_getpagesize() NBPC\n#       endif\n#      endif\n#     endif\n#    endif\n#    if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#     define getpagesize() _gl_getpagesize ()\n#    else\n#     if !GNULIB_defined_getpagesize_function\n_GL_UNISTD_INLINE int\ngetpagesize ()\n{\n  return _gl_getpagesize ();\n}\n#      define GNULIB_defined_getpagesize_function 1\n#     endif\n#    endif\n#   endif\n#  endif\n/* Need to cast, because on Cygwin 1.5.x systems, the return type is size_t.  */\n_GL_CXXALIAS_SYS_CAST (getpagesize, int, (void));\n# endif\n# if 1\n_GL_CXXALIASWARN (getpagesize);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef getpagesize\n# if HAVE_RAW_DECL_GETPAGESIZE\n_GL_WARN_ON_USE (getpagesize, \"getpagesize is unportable - \"\n                 \"use gnulib module getpagesize for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Function getpass() from module 'getpass':\n     Read a password from /dev/tty or stdin.\n   Function getpass() from module 'getpass-gnu':\n     Read a password of arbitrary length from /dev/tty or stdin.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getpass\n#   define getpass rpl_getpass\n#  endif\n_GL_FUNCDECL_RPL (getpass, char *, (const char *prompt)\n                                   _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (getpass, char *, (const char *prompt));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (getpass, char *, (const char *prompt)\n                                   _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (getpass, char *, (const char *prompt));\n# endif\n_GL_CXXALIASWARN (getpass);\n#elif defined GNULIB_POSIXCHECK\n# undef getpass\n# if HAVE_RAW_DECL_GETPASS\n_GL_WARN_ON_USE (getpass, \"getpass is unportable - \"\n                 \"use gnulib module getpass or getpass-gnu for portability\");\n# endif\n#endif\n\n\n#if 1\n/* On native Windows, map 'getpid' to '_getpid', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::getpid always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef getpid\n#   define getpid _getpid\n#  endif\n_GL_CXXALIAS_MDA (getpid, int, (void));\n# else\n_GL_CXXALIAS_SYS (getpid, pid_t, (void));\n# endif\n_GL_CXXALIASWARN (getpid);\n#endif\n\n\n#if 0\n/* Return the next valid login shell on the system, or NULL when the end of\n   the list has been reached.  */\n# if !1\n_GL_FUNCDECL_SYS (getusershell, char *, (void));\n# endif\n_GL_CXXALIAS_SYS (getusershell, char *, (void));\n_GL_CXXALIASWARN (getusershell);\n#elif defined GNULIB_POSIXCHECK\n# undef getusershell\n# if HAVE_RAW_DECL_GETUSERSHELL\n_GL_WARN_ON_USE (getusershell, \"getusershell is unportable - \"\n                 \"use gnulib module getusershell for portability\");\n# endif\n#endif\n\n#if 0\n/* Rewind to pointer that is advanced at each getusershell() call.  */\n# if !1\n_GL_FUNCDECL_SYS (setusershell, void, (void));\n# endif\n_GL_CXXALIAS_SYS (setusershell, void, (void));\n_GL_CXXALIASWARN (setusershell);\n#elif defined GNULIB_POSIXCHECK\n# undef setusershell\n# if HAVE_RAW_DECL_SETUSERSHELL\n_GL_WARN_ON_USE (setusershell, \"setusershell is unportable - \"\n                 \"use gnulib module getusershell for portability\");\n# endif\n#endif\n\n#if 0\n/* Free the pointer that is advanced at each getusershell() call and\n   associated resources.  */\n# if !1\n_GL_FUNCDECL_SYS (endusershell, void, (void));\n# endif\n_GL_CXXALIAS_SYS (endusershell, void, (void));\n_GL_CXXALIASWARN (endusershell);\n#elif defined GNULIB_POSIXCHECK\n# undef endusershell\n# if HAVE_RAW_DECL_ENDUSERSHELL\n_GL_WARN_ON_USE (endusershell, \"endusershell is unportable - \"\n                 \"use gnulib module getusershell for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Determine whether group id is in calling user's group list.  */\n# if !1\n_GL_FUNCDECL_SYS (group_member, int, (gid_t gid));\n# endif\n_GL_CXXALIAS_SYS (group_member, int, (gid_t gid));\n_GL_CXXALIASWARN (group_member);\n#elif defined GNULIB_POSIXCHECK\n# undef group_member\n# if HAVE_RAW_DECL_GROUP_MEMBER\n_GL_WARN_ON_USE (group_member, \"group_member is unportable - \"\n                 \"use gnulib module group-member for portability\");\n# endif\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef isatty\n#   define isatty rpl_isatty\n#  endif\n_GL_FUNCDECL_RPL (isatty, int, (int fd));\n_GL_CXXALIAS_RPL (isatty, int, (int fd));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef isatty\n#   define isatty _isatty\n#  endif\n_GL_CXXALIAS_MDA (isatty, int, (int fd));\n# else\n_GL_CXXALIAS_SYS (isatty, int, (int fd));\n# endif\n_GL_CXXALIASWARN (isatty);\n#elif defined GNULIB_POSIXCHECK\n# undef isatty\n# if HAVE_RAW_DECL_ISATTY\n_GL_WARN_ON_USE (isatty, \"isatty has portability problems on native Windows - \"\n                 \"use gnulib module isatty for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'isatty' to '_isatty', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::isatty always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef isatty\n#   define isatty _isatty\n#  endif\n_GL_CXXALIAS_MDA (isatty, int, (int fd));\n# else\n_GL_CXXALIAS_SYS (isatty, int, (int fd));\n# endif\n_GL_CXXALIASWARN (isatty);\n#endif\n\n\n#if 0\n/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE\n   to GID (if GID is not -1).  Do not follow symbolic links.\n   Return 0 if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/lchown.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef lchown\n#   define lchown rpl_lchown\n#  endif\n_GL_FUNCDECL_RPL (lchown, int, (char const *file, uid_t owner, gid_t group)\n                               _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (lchown, int, (char const *file, uid_t owner, gid_t group));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (lchown, int, (char const *file, uid_t owner, gid_t group)\n                               _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (lchown, int, (char const *file, uid_t owner, gid_t group));\n# endif\n_GL_CXXALIASWARN (lchown);\n#elif defined GNULIB_POSIXCHECK\n# undef lchown\n# if HAVE_RAW_DECL_LCHOWN\n_GL_WARN_ON_USE (lchown, \"lchown is unportable to pre-POSIX.1-2001 systems - \"\n                 \"use gnulib module lchown for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Create a new hard link for an existing file.\n   Return 0 if successful, otherwise -1 and errno set.\n   See POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define link rpl_link\n#  endif\n_GL_FUNCDECL_RPL (link, int, (const char *path1, const char *path2)\n                             _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (link, int, (const char *path1, const char *path2));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (link, int, (const char *path1, const char *path2)\n                             _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (link, int, (const char *path1, const char *path2));\n# endif\n_GL_CXXALIASWARN (link);\n#elif defined GNULIB_POSIXCHECK\n# undef link\n# if HAVE_RAW_DECL_LINK\n_GL_WARN_ON_USE (link, \"link is unportable - \"\n                 \"use gnulib module link for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Create a new hard link for an existing file, relative to two\n   directories.  FLAG controls whether symlinks are followed.\n   Return 0 if successful, otherwise -1 and errno set.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef linkat\n#   define linkat rpl_linkat\n#  endif\n_GL_FUNCDECL_RPL (linkat, int,\n                  (int fd1, const char *path1, int fd2, const char *path2,\n                   int flag)\n                  _GL_ARG_NONNULL ((2, 4)));\n_GL_CXXALIAS_RPL (linkat, int,\n                  (int fd1, const char *path1, int fd2, const char *path2,\n                   int flag));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (linkat, int,\n                  (int fd1, const char *path1, int fd2, const char *path2,\n                   int flag)\n                  _GL_ARG_NONNULL ((2, 4)));\n#  endif\n_GL_CXXALIAS_SYS (linkat, int,\n                  (int fd1, const char *path1, int fd2, const char *path2,\n                   int flag));\n# endif\n_GL_CXXALIASWARN (linkat);\n#elif defined GNULIB_POSIXCHECK\n# undef linkat\n# if HAVE_RAW_DECL_LINKAT\n_GL_WARN_ON_USE (linkat, \"linkat is unportable - \"\n                 \"use gnulib module linkat for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END.\n   Return the new offset if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define lseek rpl_lseek\n#  endif\n_GL_FUNCDECL_RPL (lseek, off_t, (int fd, off_t offset, int whence));\n_GL_CXXALIAS_RPL (lseek, off_t, (int fd, off_t offset, int whence));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef lseek\n#   define lseek _lseek\n#  endif\n_GL_CXXALIAS_MDA (lseek, off_t, (int fd, off_t offset, int whence));\n# else\n_GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence));\n# endif\n_GL_CXXALIASWARN (lseek);\n#elif defined GNULIB_POSIXCHECK\n# undef lseek\n# if HAVE_RAW_DECL_LSEEK\n_GL_WARN_ON_USE (lseek, \"lseek does not fail with ESPIPE on pipes on some \"\n                 \"systems - use gnulib module lseek for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'lseek' to '_lseek', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::lseek always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef lseek\n#   define lseek _lseek\n#  endif\n_GL_CXXALIAS_MDA (lseek, long, (int fd, long offset, int whence));\n# else\n_GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence));\n# endif\n_GL_CXXALIASWARN (lseek);\n#endif\n\n\n#if 0\n/* Create a pipe, defaulting to O_BINARY mode.\n   Store the read-end as fd[0] and the write-end as fd[1].\n   Return 0 upon success, or -1 with errno set upon failure.  */\n# if !1\n_GL_FUNCDECL_SYS (pipe, int, (int fd[2]) _GL_ARG_NONNULL ((1)));\n# endif\n_GL_CXXALIAS_SYS (pipe, int, (int fd[2]));\n_GL_CXXALIASWARN (pipe);\n#elif defined GNULIB_POSIXCHECK\n# undef pipe\n# if HAVE_RAW_DECL_PIPE\n_GL_WARN_ON_USE (pipe, \"pipe is unportable - \"\n                 \"use gnulib module pipe-posix for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Create a pipe, applying the given flags when opening the read-end of the\n   pipe and the write-end of the pipe.\n   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)\n   and O_TEXT, O_BINARY (defined in \"binary-io.h\").\n   Store the read-end as fd[0] and the write-end as fd[1].\n   Return 0 upon success, or -1 with errno set upon failure.\n   See also the Linux man page at\n   <https://www.kernel.org/doc/man-pages/online/pages/man2/pipe2.2.html>.  */\n# if 1\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define pipe2 rpl_pipe2\n#  endif\n_GL_FUNCDECL_RPL (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (pipe2, int, (int fd[2], int flags));\n# else\n_GL_FUNCDECL_SYS (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_SYS (pipe2, int, (int fd[2], int flags));\n# endif\n_GL_CXXALIASWARN (pipe2);\n#elif defined GNULIB_POSIXCHECK\n# undef pipe2\n# if HAVE_RAW_DECL_PIPE2\n_GL_WARN_ON_USE (pipe2, \"pipe2 is unportable - \"\n                 \"use gnulib module pipe2 for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Read at most BUFSIZE bytes from FD into BUF, starting at OFFSET.\n   Return the number of bytes placed into BUF if successful, otherwise\n   set errno and return -1.  0 indicates EOF.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef pread\n#   define pread rpl_pread\n#  endif\n_GL_FUNCDECL_RPL (pread, ssize_t,\n                  (int fd, void *buf, size_t bufsize, off_t offset)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (pread, ssize_t,\n                  (int fd, void *buf, size_t bufsize, off_t offset));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (pread, ssize_t,\n                  (int fd, void *buf, size_t bufsize, off_t offset)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (pread, ssize_t,\n                  (int fd, void *buf, size_t bufsize, off_t offset));\n# endif\n_GL_CXXALIASWARN (pread);\n#elif defined GNULIB_POSIXCHECK\n# undef pread\n# if HAVE_RAW_DECL_PREAD\n_GL_WARN_ON_USE (pread, \"pread is unportable - \"\n                 \"use gnulib module pread for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Write at most BUFSIZE bytes from BUF into FD, starting at OFFSET.\n   Return the number of bytes written if successful, otherwise\n   set errno and return -1.  0 indicates nothing written.  See the\n   POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef pwrite\n#   define pwrite rpl_pwrite\n#  endif\n_GL_FUNCDECL_RPL (pwrite, ssize_t,\n                  (int fd, const void *buf, size_t bufsize, off_t offset)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (pwrite, ssize_t,\n                  (int fd, const void *buf, size_t bufsize, off_t offset));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (pwrite, ssize_t,\n                  (int fd, const void *buf, size_t bufsize, off_t offset)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (pwrite, ssize_t,\n                  (int fd, const void *buf, size_t bufsize, off_t offset));\n# endif\n_GL_CXXALIASWARN (pwrite);\n#elif defined GNULIB_POSIXCHECK\n# undef pwrite\n# if HAVE_RAW_DECL_PWRITE\n_GL_WARN_ON_USE (pwrite, \"pwrite is unportable - \"\n                 \"use gnulib module pwrite for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Read up to COUNT bytes from file descriptor FD into the buffer starting\n   at BUF.  See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef read\n#   define read rpl_read\n#  endif\n_GL_FUNCDECL_RPL (read, ssize_t, (int fd, void *buf, size_t count)\n                                 _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (read, ssize_t, (int fd, void *buf, size_t count));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef read\n#   define read _read\n#  endif\n_GL_CXXALIAS_MDA (read, ssize_t, (int fd, void *buf, size_t count));\n# else\n_GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count));\n# endif\n_GL_CXXALIASWARN (read);\n#elif 1\n/* On native Windows, map 'read' to '_read', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::read always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef read\n#   define read _read\n#  endif\n#  ifdef __MINGW32__\n_GL_CXXALIAS_MDA (read, int, (int fd, void *buf, unsigned int count));\n#  else\n_GL_CXXALIAS_MDA (read, ssize_t, (int fd, void *buf, unsigned int count));\n#  endif\n# else\n_GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count));\n# endif\n_GL_CXXALIASWARN (read);\n#endif\n\n\n#if 0\n/* Read the contents of the symbolic link FILE and place the first BUFSIZE\n   bytes of it into BUF.  Return the number of bytes placed into BUF if\n   successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define readlink rpl_readlink\n#  endif\n_GL_FUNCDECL_RPL (readlink, ssize_t,\n                  (const char *restrict file,\n                   char *restrict buf, size_t bufsize)\n                  _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (readlink, ssize_t,\n                  (const char *restrict file,\n                   char *restrict buf, size_t bufsize));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (readlink, ssize_t,\n                  (const char *restrict file,\n                   char *restrict buf, size_t bufsize)\n                  _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (readlink, ssize_t,\n                  (const char *restrict file,\n                   char *restrict buf, size_t bufsize));\n# endif\n_GL_CXXALIASWARN (readlink);\n#elif defined GNULIB_POSIXCHECK\n# undef readlink\n# if HAVE_RAW_DECL_READLINK\n_GL_WARN_ON_USE (readlink, \"readlink is unportable - \"\n                 \"use gnulib module readlink for portability\");\n# endif\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define readlinkat rpl_readlinkat\n#  endif\n_GL_FUNCDECL_RPL (readlinkat, ssize_t,\n                  (int fd, char const *restrict file,\n                   char *restrict buf, size_t len)\n                  _GL_ARG_NONNULL ((2, 3)));\n_GL_CXXALIAS_RPL (readlinkat, ssize_t,\n                  (int fd, char const *restrict file,\n                   char *restrict buf, size_t len));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (readlinkat, ssize_t,\n                  (int fd, char const *restrict file,\n                   char *restrict buf, size_t len)\n                  _GL_ARG_NONNULL ((2, 3)));\n#  endif\n_GL_CXXALIAS_SYS (readlinkat, ssize_t,\n                  (int fd, char const *restrict file,\n                   char *restrict buf, size_t len));\n# endif\n_GL_CXXALIASWARN (readlinkat);\n#elif defined GNULIB_POSIXCHECK\n# undef readlinkat\n# if HAVE_RAW_DECL_READLINKAT\n_GL_WARN_ON_USE (readlinkat, \"readlinkat is not portable - \"\n                 \"use gnulib module readlinkat for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Remove the directory DIR.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   define rmdir rpl_rmdir\n#  endif\n_GL_FUNCDECL_RPL (rmdir, int, (char const *name) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (rmdir, int, (char const *name));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef rmdir\n#   define rmdir _rmdir\n#  endif\n_GL_CXXALIAS_MDA (rmdir, int, (char const *name));\n# else\n_GL_CXXALIAS_SYS (rmdir, int, (char const *name));\n# endif\n_GL_CXXALIASWARN (rmdir);\n#elif defined GNULIB_POSIXCHECK\n# undef rmdir\n# if HAVE_RAW_DECL_RMDIR\n_GL_WARN_ON_USE (rmdir, \"rmdir is unportable - \"\n                 \"use gnulib module rmdir for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'rmdir' to '_rmdir', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::rmdir always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef rmdir\n#   define rmdir _rmdir\n#  endif\n_GL_CXXALIAS_MDA (rmdir, int, (char const *name));\n# else\n_GL_CXXALIAS_SYS (rmdir, int, (char const *name));\n# endif\n_GL_CXXALIASWARN (rmdir);\n#endif\n\n\n#if 0\n/* Set the host name of the machine.\n   The host name may or may not be fully qualified.\n\n   Put LEN bytes of NAME into the host name.\n   Return 0 if successful, otherwise, set errno and return -1.\n\n   Platforms with no ability to set the hostname return -1 and set\n   errno = ENOSYS.  */\n# if !1 || !1\n_GL_FUNCDECL_SYS (sethostname, int, (const char *name, size_t len)\n                                    _GL_ARG_NONNULL ((1)));\n# endif\n/* Need to cast, because on Solaris 11 2011-10, Mac OS X 10.5, IRIX 6.5\n   and FreeBSD 6.4 the second parameter is int.  On Solaris 11\n   2011-10, the first parameter is not const.  */\n_GL_CXXALIAS_SYS_CAST (sethostname, int, (const char *name, size_t len));\n_GL_CXXALIASWARN (sethostname);\n#elif defined GNULIB_POSIXCHECK\n# undef sethostname\n# if HAVE_RAW_DECL_SETHOSTNAME\n_GL_WARN_ON_USE (sethostname, \"sethostname is unportable - \"\n                 \"use gnulib module sethostname for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Pause the execution of the current thread for N seconds.\n   Returns the number of seconds left to sleep.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/sleep.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef sleep\n#   define sleep rpl_sleep\n#  endif\n_GL_FUNCDECL_RPL (sleep, unsigned int, (unsigned int n));\n_GL_CXXALIAS_RPL (sleep, unsigned int, (unsigned int n));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (sleep, unsigned int, (unsigned int n));\n#  endif\n_GL_CXXALIAS_SYS (sleep, unsigned int, (unsigned int n));\n# endif\n_GL_CXXALIASWARN (sleep);\n#elif defined GNULIB_POSIXCHECK\n# undef sleep\n# if HAVE_RAW_DECL_SLEEP\n_GL_WARN_ON_USE (sleep, \"sleep is unportable - \"\n                 \"use gnulib module sleep for portability\");\n# endif\n#endif\n\n\n#if 1\n/* On native Windows, map 'swab' to '_swab', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::creat always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef swab\n#   define swab _swab\n#  endif\n_GL_CXXALIAS_MDA (swab, void, (char *from, char *to, int n));\n# else\n_GL_CXXALIAS_SYS (swab, void, (const void *from, void *to, ssize_t n));\n# endif\n_GL_CXXALIASWARN (swab);\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef symlink\n#   define symlink rpl_symlink\n#  endif\n_GL_FUNCDECL_RPL (symlink, int, (char const *contents, char const *file)\n                                _GL_ARG_NONNULL ((1, 2)));\n_GL_CXXALIAS_RPL (symlink, int, (char const *contents, char const *file));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (symlink, int, (char const *contents, char const *file)\n                                _GL_ARG_NONNULL ((1, 2)));\n#  endif\n_GL_CXXALIAS_SYS (symlink, int, (char const *contents, char const *file));\n# endif\n_GL_CXXALIASWARN (symlink);\n#elif defined GNULIB_POSIXCHECK\n# undef symlink\n# if HAVE_RAW_DECL_SYMLINK\n_GL_WARN_ON_USE (symlink, \"symlink is not portable - \"\n                 \"use gnulib module symlink for portability\");\n# endif\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef symlinkat\n#   define symlinkat rpl_symlinkat\n#  endif\n_GL_FUNCDECL_RPL (symlinkat, int,\n                  (char const *contents, int fd, char const *file)\n                  _GL_ARG_NONNULL ((1, 3)));\n_GL_CXXALIAS_RPL (symlinkat, int,\n                  (char const *contents, int fd, char const *file));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (symlinkat, int,\n                  (char const *contents, int fd, char const *file)\n                  _GL_ARG_NONNULL ((1, 3)));\n#  endif\n_GL_CXXALIAS_SYS (symlinkat, int,\n                  (char const *contents, int fd, char const *file));\n# endif\n_GL_CXXALIASWARN (symlinkat);\n#elif defined GNULIB_POSIXCHECK\n# undef symlinkat\n# if HAVE_RAW_DECL_SYMLINKAT\n_GL_WARN_ON_USE (symlinkat, \"symlinkat is not portable - \"\n                 \"use gnulib module symlinkat for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Change the size of the file designated by FILENAME to become equal to LENGTH.\n   Return 0 if successful, otherwise -1 and errno set.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef truncate\n#   define truncate rpl_truncate\n#  endif\n_GL_FUNCDECL_RPL (truncate, int, (const char *filename, off_t length)\n                                 _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (truncate, int, (const char *filename, off_t length));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (truncate, int, (const char *filename, off_t length)\n                                 _GL_ARG_NONNULL ((1)));\n#  endif\n_GL_CXXALIAS_SYS (truncate, int, (const char *filename, off_t length));\n# endif\n_GL_CXXALIASWARN (truncate);\n#elif defined GNULIB_POSIXCHECK\n# undef truncate\n# if HAVE_RAW_DECL_TRUNCATE\n_GL_WARN_ON_USE (truncate, \"truncate is unportable - \"\n                 \"use gnulib module truncate for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Store at most BUFLEN characters of the pathname of the terminal FD is\n   open on in BUF.  Return 0 on success, otherwise an error number.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef ttyname_r\n#   define ttyname_r rpl_ttyname_r\n#  endif\n_GL_FUNCDECL_RPL (ttyname_r, int,\n                  (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (ttyname_r, int,\n                  (int fd, char *buf, size_t buflen));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (ttyname_r, int,\n                  (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (ttyname_r, int,\n                  (int fd, char *buf, size_t buflen));\n# endif\n_GL_CXXALIASWARN (ttyname_r);\n#elif defined GNULIB_POSIXCHECK\n# undef ttyname_r\n# if HAVE_RAW_DECL_TTYNAME_R\n_GL_WARN_ON_USE (ttyname_r, \"ttyname_r is not portable - \"\n                 \"use gnulib module ttyname_r for portability\");\n# endif\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef unlink\n#   define unlink rpl_unlink\n#  endif\n_GL_FUNCDECL_RPL (unlink, int, (char const *file) _GL_ARG_NONNULL ((1)));\n_GL_CXXALIAS_RPL (unlink, int, (char const *file));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef unlink\n#   define unlink _unlink\n#  endif\n_GL_CXXALIAS_MDA (unlink, int, (char const *file));\n# else\n_GL_CXXALIAS_SYS (unlink, int, (char const *file));\n# endif\n_GL_CXXALIASWARN (unlink);\n#elif defined GNULIB_POSIXCHECK\n# undef unlink\n# if HAVE_RAW_DECL_UNLINK\n_GL_WARN_ON_USE (unlink, \"unlink is not portable - \"\n                 \"use gnulib module unlink for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'unlink' to '_unlink', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::unlink always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef unlink\n#   define unlink _unlink\n#  endif\n_GL_CXXALIAS_MDA (unlink, int, (char const *file));\n# else\n_GL_CXXALIAS_SYS (unlink, int, (char const *file));\n# endif\n_GL_CXXALIASWARN (unlink);\n#endif\n\n\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef unlinkat\n#   define unlinkat rpl_unlinkat\n#  endif\n_GL_FUNCDECL_RPL (unlinkat, int, (int fd, char const *file, int flag)\n                                 _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (unlinkat, int, (int fd, char const *file, int flag));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (unlinkat, int, (int fd, char const *file, int flag)\n                                 _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (unlinkat, int, (int fd, char const *file, int flag));\n# endif\n_GL_CXXALIASWARN (unlinkat);\n#elif defined GNULIB_POSIXCHECK\n# undef unlinkat\n# if HAVE_RAW_DECL_UNLINKAT\n_GL_WARN_ON_USE (unlinkat, \"unlinkat is not portable - \"\n                 \"use gnulib module unlinkat for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Pause the execution of the current thread for N microseconds.\n   Returns 0 on completion, or -1 on range error.\n   See the POSIX:2001 specification\n   <https://pubs.opengroup.org/onlinepubs/009695399/functions/usleep.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef usleep\n#   define usleep rpl_usleep\n#  endif\n_GL_FUNCDECL_RPL (usleep, int, (useconds_t n));\n_GL_CXXALIAS_RPL (usleep, int, (useconds_t n));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (usleep, int, (useconds_t n));\n#  endif\n/* Need to cast, because on Haiku, the first parameter is\n                                     unsigned int n.  */\n_GL_CXXALIAS_SYS_CAST (usleep, int, (useconds_t n));\n# endif\n_GL_CXXALIASWARN (usleep);\n#elif defined GNULIB_POSIXCHECK\n# undef usleep\n# if HAVE_RAW_DECL_USLEEP\n_GL_WARN_ON_USE (usleep, \"usleep is unportable - \"\n                 \"use gnulib module usleep for portability\");\n# endif\n#endif\n\n\n#if 0\n/* Write up to COUNT bytes starting at BUF to file descriptor FD.\n   See the POSIX:2008 specification\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html>.  */\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef write\n#   define write rpl_write\n#  endif\n_GL_FUNCDECL_RPL (write, ssize_t, (int fd, const void *buf, size_t count)\n                                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void *buf, size_t count));\n# elif defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef write\n#   define write _write\n#  endif\n_GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, size_t count));\n# else\n_GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count));\n# endif\n_GL_CXXALIASWARN (write);\n#elif 1\n/* On native Windows, map 'write' to '_write', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::write always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef write\n#   define write _write\n#  endif\n#  ifdef __MINGW32__\n_GL_CXXALIAS_MDA (write, int, (int fd, const void *buf, unsigned int count));\n#  else\n_GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, unsigned int count));\n#  endif\n# else\n_GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count));\n# endif\n_GL_CXXALIASWARN (write);\n#endif\n\n_GL_INLINE_HEADER_END\n\n#endif /* _GL_UNISTD_H */\n#endif /* _GL_INCLUDING_UNISTD_H */\n#endif /* _GL_UNISTD_H */\n"
  },
  {
    "path": "win32/gnulib_h/wchar.h",
    "content": "/* DO NOT EDIT! GENERATED AUTOMATICALLY! */\n/* A substitute for ISO C99 <wchar.h>, for platforms that have issues.\n\n   Copyright (C) 2007-2021 Free Software Foundation, Inc.\n\n   This file is free software: you can redistribute it and/or modify\n   it under the terms of the GNU Lesser General Public License as\n   published by the Free Software Foundation; either version 2.1 of the\n   License, or (at your option) any later version.\n\n   This file is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* Written by Eric Blake.  */\n\n/*\n * ISO C 99 <wchar.h> for platforms that have issues.\n * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/wchar.h.html>\n *\n * For now, this just ensures proper prerequisite inclusion order and\n * the declaration of wcwidth().\n */\n\n#if __GNUC__ >= 3\n#pragma GCC system_header\n#endif\n\n\n#if (((defined __need_mbstate_t || defined __need_wint_t)               \\\n      && !defined __MINGW32__)                                          \\\n     || (defined __hpux                                                 \\\n         && ((defined _INTTYPES_INCLUDED                                \\\n              && !defined _GL_FINISHED_INCLUDING_SYSTEM_INTTYPES_H)     \\\n             || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H))               \\\n     || (defined __MINGW32__ && defined __STRING_H_SOURCED__)           \\\n     || defined _GL_ALREADY_INCLUDING_WCHAR_H)\n/* Special invocation convention:\n   - Inside glibc and uClibc header files, but not MinGW.\n   - On HP-UX 11.00 we have a sequence of nested includes\n     <wchar.h> -> <stdlib.h> -> <stdint.h>, and the latter includes <wchar.h>,\n     once indirectly <stdint.h> -> <sys/types.h> -> <inttypes.h> -> <wchar.h>\n     and once directly.  In both situations 'wint_t' is not yet defined,\n     therefore we cannot provide the function overrides; instead include only\n     the system's <wchar.h>.\n   - With MinGW 3.22, when <string.h> includes <wchar.h>, only some part of\n     <wchar.h> is actually processed, and that doesn't include 'mbstate_t'.\n   - On IRIX 6.5, similarly, we have an include <wchar.h> -> <wctype.h>, and\n     the latter includes <wchar.h>.  But here, we have no way to detect whether\n     <wctype.h> is completely included or is still being included.  */\n\n#include_next <wchar.h>\n\n#else\n/* Normal invocation convention.  */\n\n#ifndef _GL_WCHAR_H\n\n#define _GL_ALREADY_INCLUDING_WCHAR_H\n\n#if 0\n# include <features.h> /* for __GLIBC__ */\n#endif\n\n/* In some builds of uClibc, <wchar.h> is nonexistent and wchar_t is defined\n   by <stddef.h>.\n   But avoid namespace pollution on glibc systems.  */\n#if !(defined __GLIBC__ && !defined __UCLIBC__)\n# include <stddef.h>\n#endif\n\n/* Include the original <wchar.h> if it exists.\n   Some builds of uClibc lack it.  */\n/* The include_next requires a split double-inclusion guard.  */\n#if 1\n# include_next <wchar.h>\n#endif\n\n#undef _GL_ALREADY_INCLUDING_WCHAR_H\n\n#ifndef _GL_WCHAR_H\n#define _GL_WCHAR_H\n\n/* The __attribute__ feature is available in gcc versions 2.5 and later.\n   The attribute __pure__ was added in gcc 2.96.  */\n#ifndef _GL_ATTRIBUTE_PURE\n# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__\n#  define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))\n# else\n#  define _GL_ATTRIBUTE_PURE /* empty */\n# endif\n#endif\n\n/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */\n/* C++ compatible function declaration macros.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n#ifndef _GL_CXXDEFS_H\n#define _GL_CXXDEFS_H\n\n/* Begin/end the GNULIB_NAMESPACE namespace.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {\n# define _GL_END_NAMESPACE }\n#else\n# define _GL_BEGIN_NAMESPACE\n# define _GL_END_NAMESPACE\n#endif\n\n/* The three most frequent use cases of these macros are:\n\n   * For providing a substitute for a function that is missing on some\n     platforms, but is declared and works fine on the platforms on which\n     it exists:\n\n       #if @GNULIB_FOO@\n       # if !@HAVE_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       # endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on all platforms,\n     but is broken/insufficient and needs to be replaced on some platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n\n   * For providing a replacement for a function that exists on some platforms\n     but is broken/insufficient and needs to be replaced on some of them and\n     is additionally either missing or undeclared on some other platforms:\n\n       #if @GNULIB_FOO@\n       # if @REPLACE_FOO@\n       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n       #   undef foo\n       #   define foo rpl_foo\n       #  endif\n       _GL_FUNCDECL_RPL (foo, ...);\n       _GL_CXXALIAS_RPL (foo, ...);\n       # else\n       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@\n       _GL_FUNCDECL_SYS (foo, ...);\n       #  endif\n       _GL_CXXALIAS_SYS (foo, ...);\n       # endif\n       _GL_CXXALIASWARN (foo);\n       #elif defined GNULIB_POSIXCHECK\n       ...\n       #endif\n*/\n\n/* _GL_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#if defined __cplusplus\n# define _GL_EXTERN_C extern \"C\"\n#else\n# define _GL_EXTERN_C extern\n#endif\n\n/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);\n   declares a replacement function, named rpl_func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \\\n  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)\n#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype rpl_func parameters_and_attributes\n\n/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);\n   declares the system function, named func, with the given prototype,\n   consisting of return type, parameters, and attributes.\n   Example:\n     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)\n                                  _GL_ARG_NONNULL ((1)));\n */\n#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \\\n  _GL_EXTERN_C rettype func parameters_and_attributes\n\n/* _GL_CXXALIAS_RPL (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));\n\n   Wrapping rpl_func in an object with an inline conversion operator\n   avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#define _GL_CXXALIAS_RPL(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::rpl_func;                                  \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA (func, rettype, parameters);\n   is to be used when func is a Microsoft deprecated alias, on native Windows.\n   It declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to _func, if GNULIB_NAMESPACE is defined.\n   Example:\n     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));\n */\n#define _GL_CXXALIAS_MDA(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);\n   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);\n   except that the C function rpl_func may have a slightly different\n   declaration.  A cast is used to silence the \"invalid conversion\" error\n   that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                                     \\\n    {                                                              \\\n      static const struct _gl_ ## func ## _wrapper                 \\\n      {                                                            \\\n        typedef rettype (*type) parameters;                        \\\n                                                                   \\\n        inline operator type () const                              \\\n        {                                                          \\\n          return reinterpret_cast<type>(::rpl_func);               \\\n        }                                                          \\\n      } func = {};                                                 \\\n    }                                                              \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_MDA (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \\\n  _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)\n\n/* _GL_CXXALIAS_SYS (func, rettype, parameters);\n   declares a C++ alias called GNULIB_NAMESPACE::func\n   that redirects to the system provided function func, if GNULIB_NAMESPACE\n   is defined.\n   Example:\n     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));\n\n   Wrapping func in an object with an inline conversion operator\n   avoids a reference to func unless GNULIB_NAMESPACE::func is\n   actually used in the program.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS(func,rettype,parameters)            \\\n    namespace GNULIB_NAMESPACE                                \\\n    {                                                         \\\n      static const struct _gl_ ## func ## _wrapper            \\\n      {                                                       \\\n        typedef rettype (*type) parameters;                   \\\n                                                              \\\n        inline operator type () const                         \\\n        {                                                     \\\n          return ::func;                                      \\\n        }                                                     \\\n      } func = {};                                            \\\n    }                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function func may have a slightly different declaration.\n   A cast is used to silence the \"invalid conversion\" error that would\n   otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    namespace GNULIB_NAMESPACE                          \\\n    {                                                   \\\n      static const struct _gl_ ## func ## _wrapper      \\\n      {                                                 \\\n        typedef rettype (*type) parameters;             \\\n                                                        \\\n        inline operator type () const                   \\\n        {                                               \\\n          return reinterpret_cast<type>(::func);        \\\n        }                                               \\\n      } func = {};                                      \\\n    }                                                   \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);\n   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);\n   except that the C function is picked among a set of overloaded functions,\n   namely the one with rettype2 and parameters2.  Two consecutive casts\n   are used to silence the \"cannot find a match\" and \"invalid conversion\"\n   errors that would otherwise occur.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n  /* The outer cast must be a reinterpret_cast.\n     The inner cast: When the function is defined as a set of overloaded\n     functions, it works as a static_cast<>, choosing the designated variant.\n     When the function is defined as a single variant, it works as a\n     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    namespace GNULIB_NAMESPACE                                                \\\n    {                                                                         \\\n      static const struct _gl_ ## func ## _wrapper                            \\\n      {                                                                       \\\n        typedef rettype (*type) parameters;                                   \\\n                                                                              \\\n        inline operator type () const                                         \\\n        {                                                                     \\\n          return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \\\n        }                                                                     \\\n      } func = {};                                                            \\\n    }                                                                         \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#else\n# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN (func);\n   causes a warning to be emitted when ::func is used but not when\n   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded\n   variants.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN(func) \\\n   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN_1(func,namespace) \\\n   _GL_CXXALIASWARN_2 (func, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n    _GL_WARN_ON_USE (func, \\\n                     \"The symbol ::\" #func \" refers to the system function. \" \\\n                     \"Use \" #namespace \"::\" #func \" instead.\")\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     extern __typeof__ (func) func\n# else\n#  define _GL_CXXALIASWARN_2(func,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN(func) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);\n   causes a warning to be emitted when the given overloaded variant of ::func\n   is used but not when GNULIB_NAMESPACE::func is used.  */\n#if defined __cplusplus && defined GNULIB_NAMESPACE\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \\\n                        GNULIB_NAMESPACE)\n# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \\\n   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)\n/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,\n   we enable the warning only when not optimizing.  */\n# if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n    _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \\\n                         \"The symbol ::\" #func \" refers to the system function. \" \\\n                         \"Use \" #namespace \"::\" #func \" instead.\")\n# else\n#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \\\n     _GL_EXTERN_C int _gl_cxxalias_dummy\n# endif\n#else\n# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \\\n    _GL_EXTERN_C int _gl_cxxalias_dummy\n#endif\n\n#endif /* _GL_CXXDEFS_H */\n\n/* The definition of _GL_ARG_NONNULL is copied here.  */\n/* A C macro for declaring that specific arguments must not be NULL.\n   Copyright (C) 2009-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools\n   that the values passed as arguments n, ..., m must be non-NULL pointers.\n   n = 1 stands for the first argument, n = 2 for the second argument etc.  */\n#ifndef _GL_ARG_NONNULL\n# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__\n#  define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))\n# else\n#  define _GL_ARG_NONNULL(params)\n# endif\n#endif\n\n/* The definition of _GL_WARN_ON_USE is copied here.  */\n/* A C macro for emitting warnings if a function is used.\n   Copyright (C) 2010-2021 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify it\n   under the terms of the GNU Lesser General Public License as published\n   by the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public License\n   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */\n\n/* _GL_WARN_ON_USE (function, \"literal string\") issues a declaration\n   for FUNCTION which will then trigger a compiler warning containing\n   the text of \"literal string\" anywhere that function is called, if\n   supported by the compiler.  If the compiler does not support this\n   feature, the macro expands to an unused extern declaration.\n\n   _GL_WARN_ON_USE_ATTRIBUTE (\"literal string\") expands to the\n   attribute used in _GL_WARN_ON_USE.  If the compiler does not support\n   this feature, it expands to empty.\n\n   These macros are useful for marking a function as a potential\n   portability trap, with the intent that \"literal string\" include\n   instructions on the replacement function that should be used\n   instead.\n   _GL_WARN_ON_USE is for functions with 'extern' linkage.\n   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'\n   linkage.\n\n   However, one of the reasons that a function is a portability trap is\n   if it has the wrong signature.  Declaring FUNCTION with a different\n   signature in C is a compilation error, so this macro must use the\n   same type as any existing declaration so that programs that avoid\n   the problematic FUNCTION do not fail to compile merely because they\n   included a header that poisoned the function.  But this implies that\n   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already\n   have a declaration.  Use of this macro implies that there must not\n   be any other macro hiding the declaration of FUNCTION; but\n   undefining FUNCTION first is part of the poisoning process anyway\n   (although for symbols that are provided only via a macro, the result\n   is a compilation error rather than a warning containing\n   \"literal string\").  Also note that in C++, it is only safe to use if\n   FUNCTION has no overloads.\n\n   For an example, it is possible to poison 'getline' by:\n   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],\n     [getline]) in configure.ac, which potentially defines\n     HAVE_RAW_DECL_GETLINE\n   - adding this code to a header that wraps the system <stdio.h>:\n     #undef getline\n     #if HAVE_RAW_DECL_GETLINE\n     _GL_WARN_ON_USE (getline, \"getline is required by POSIX 2008, but\"\n       \"not universally present; use the gnulib module getline\");\n     #endif\n\n   It is not possible to directly poison global variables.  But it is\n   possible to write a wrapper accessor function, and poison that\n   (less common usage, like &environ, will cause a compilation error\n   rather than issue the nice warning, but the end result of informing\n   the developer about their portability problem is still achieved):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     rpl_environ (void) { return &environ; }\n     _GL_WARN_ON_USE (rpl_environ, \"environ is not always properly declared\");\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   or better (avoiding contradictory use of 'static' and 'extern'):\n     #if HAVE_RAW_DECL_ENVIRON\n     static char ***\n     _GL_WARN_ON_USE_ATTRIBUTE (\"environ is not always properly declared\")\n     rpl_environ (void) { return &environ; }\n     # undef environ\n     # define environ (*rpl_environ ())\n     #endif\n   */\n#ifndef _GL_WARN_ON_USE\n\n# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function __attribute__ ((__warning__ (message)))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__warning__ (message)))\n# elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \\\n  __attribute__ ((__diagnose_if__ (1, message, \"warning\")))\n# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#  define _GL_WARN_ON_USE(function, message) \\\nextern __typeof__ (function) function\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# else /* Unsupported.  */\n#  define _GL_WARN_ON_USE(function, message) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  define _GL_WARN_ON_USE_ATTRIBUTE(message)\n# endif\n#endif\n\n/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, \"message\")\n   is like _GL_WARN_ON_USE (function, \"message\"), except that in C++ mode the\n   function is declared with the given prototype, consisting of return type,\n   parameters, and attributes.\n   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does\n   not work in this case.  */\n#ifndef _GL_WARN_ON_USE_CXX\n# if !defined __cplusplus\n#  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n     _GL_WARN_ON_USE (function, msg)\n# else\n#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)\n/* A compiler attribute is available in gcc versions 4.3.0 and later.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes \\\n  __attribute__ ((__warning__ (msg)))\n#  elif __clang_major__ >= 4\n/* Another compiler attribute is available in clang.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_clang function parameters_and_attributes \\\n  __attribute__ ((__diagnose_if__ (1, msg, \"warning\")))\n#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING\n/* Verify the existence of the function.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\nextern rettype_gcc function parameters_and_attributes\n#  else /* Unsupported.  */\n#   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \\\n_GL_WARN_EXTERN_C int _gl_warn_on_use\n#  endif\n# endif\n#endif\n\n/* _GL_WARN_EXTERN_C declaration;\n   performs the declaration with C linkage.  */\n#ifndef _GL_WARN_EXTERN_C\n# if defined __cplusplus\n#  define _GL_WARN_EXTERN_C extern \"C\"\n# else\n#  define _GL_WARN_EXTERN_C extern\n# endif\n#endif\n\n\n/* Define wint_t and WEOF.  (Also done in wctype.in.h.)  */\n#if !1 && !defined wint_t\n# define wint_t int\n# ifndef WEOF\n#  define WEOF -1\n# endif\n#else\n/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h> or\n   <stddef.h>.  This is too small: ISO C 99 section 7.24.1.(2) says that\n   wint_t must be \"unchanged by default argument promotions\".  Override it.  */\n# if 0\n#  if !GNULIB_defined_wint_t\n#   if 0\n#    include <crtdefs.h>\n#   else\n#    include <stddef.h>\n#   endif\ntypedef unsigned int rpl_wint_t;\n#   undef wint_t\n#   define wint_t rpl_wint_t\n#   define GNULIB_defined_wint_t 1\n#  endif\n# endif\n# ifndef WEOF\n#  define WEOF ((wint_t) -1)\n# endif\n#endif\n\n\n/* Override mbstate_t if it is too small.\n   On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for\n   implementing mbrtowc for encodings like UTF-8.\n   On AIX and MSVC, mbrtowc needs to be overridden, but mbstate_t exists and is\n   large enough and overriding it would cause problems in C++ mode.  */\n#if !(((defined _WIN32 && !defined __CYGWIN__) || 1) && 1) || 0\n# if !GNULIB_defined_mbstate_t\n#  if !(defined _AIX || defined _MSC_VER)\ntypedef int rpl_mbstate_t;\n#   undef mbstate_t\n#   define mbstate_t rpl_mbstate_t\n#  endif\n#  define GNULIB_defined_mbstate_t 1\n# endif\n#endif\n\n\n/* Convert a single-byte character to a wide character.  */\n#if 1\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef btowc\n#   define btowc rpl_btowc\n#  endif\n_GL_FUNCDECL_RPL (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE);\n_GL_CXXALIAS_RPL (btowc, wint_t, (int c));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE);\n#  endif\n/* Need to cast, because on mingw, the return type is 'unsigned short'.  */\n_GL_CXXALIAS_SYS_CAST (btowc, wint_t, (int c));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (btowc);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef btowc\n# if HAVE_RAW_DECL_BTOWC\n_GL_WARN_ON_USE (btowc, \"btowc is unportable - \"\n                 \"use gnulib module btowc for portability\");\n# endif\n#endif\n\n\n/* Convert a wide character to a single-byte character.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wctob\n#   define wctob rpl_wctob\n#  endif\n_GL_FUNCDECL_RPL (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE);\n_GL_CXXALIAS_RPL (wctob, int, (wint_t wc));\n# else\n#  if !defined wctob && !1\n/* wctob is provided by gnulib, or wctob exists but is not declared.  */\n_GL_FUNCDECL_SYS (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE);\n#  endif\n_GL_CXXALIAS_SYS (wctob, int, (wint_t wc));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wctob);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wctob\n# if HAVE_RAW_DECL_WCTOB\n_GL_WARN_ON_USE (wctob, \"wctob is unportable - \"\n                 \"use gnulib module wctob for portability\");\n# endif\n#endif\n\n\n/* Test whether *PS is in the initial state.  */\n#if 1\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbsinit\n#   define mbsinit rpl_mbsinit\n#  endif\n_GL_FUNCDECL_RPL (mbsinit, int, (const mbstate_t *ps));\n_GL_CXXALIAS_RPL (mbsinit, int, (const mbstate_t *ps));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (mbsinit, int, (const mbstate_t *ps));\n#  endif\n_GL_CXXALIAS_SYS (mbsinit, int, (const mbstate_t *ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (mbsinit);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef mbsinit\n# if HAVE_RAW_DECL_MBSINIT\n_GL_WARN_ON_USE (mbsinit, \"mbsinit is unportable - \"\n                 \"use gnulib module mbsinit for portability\");\n# endif\n#endif\n\n\n/* Convert a multibyte character to a wide character.  */\n#if 1\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbrtowc\n#   define mbrtowc rpl_mbrtowc\n#  endif\n_GL_FUNCDECL_RPL (mbrtowc, size_t,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n,\n                   mbstate_t *restrict ps));\n_GL_CXXALIAS_RPL (mbrtowc, size_t,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n,\n                   mbstate_t *restrict ps));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (mbrtowc, size_t,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n,\n                   mbstate_t *restrict ps));\n#  endif\n_GL_CXXALIAS_SYS (mbrtowc, size_t,\n                  (wchar_t *restrict pwc, const char *restrict s, size_t n,\n                   mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (mbrtowc);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef mbrtowc\n# if HAVE_RAW_DECL_MBRTOWC\n_GL_WARN_ON_USE (mbrtowc, \"mbrtowc is unportable - \"\n                 \"use gnulib module mbrtowc for portability\");\n# endif\n#endif\n\n\n/* Recognize a multibyte character.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbrlen\n#   define mbrlen rpl_mbrlen\n#  endif\n_GL_FUNCDECL_RPL (mbrlen, size_t,\n                  (const char *restrict s, size_t n, mbstate_t *restrict ps));\n_GL_CXXALIAS_RPL (mbrlen, size_t,\n                  (const char *restrict s, size_t n, mbstate_t *restrict ps));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (mbrlen, size_t,\n                  (const char *restrict s, size_t n, mbstate_t *restrict ps));\n#  endif\n_GL_CXXALIAS_SYS (mbrlen, size_t,\n                  (const char *restrict s, size_t n, mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (mbrlen);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef mbrlen\n# if HAVE_RAW_DECL_MBRLEN\n_GL_WARN_ON_USE (mbrlen, \"mbrlen is unportable - \"\n                 \"use gnulib module mbrlen for portability\");\n# endif\n#endif\n\n\n/* Convert a string to a wide string.  */\n#if 1\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbsrtowcs\n#   define mbsrtowcs rpl_mbsrtowcs\n#  endif\n_GL_FUNCDECL_RPL (mbsrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (mbsrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t len,\n                   mbstate_t *restrict ps));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (mbsrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (mbsrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t len,\n                   mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (mbsrtowcs);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef mbsrtowcs\n# if HAVE_RAW_DECL_MBSRTOWCS\n_GL_WARN_ON_USE (mbsrtowcs, \"mbsrtowcs is unportable - \"\n                 \"use gnulib module mbsrtowcs for portability\");\n# endif\n#endif\n\n\n/* Convert a string to a wide string.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef mbsnrtowcs\n#   define mbsnrtowcs rpl_mbsnrtowcs\n#  endif\n_GL_FUNCDECL_RPL (mbsnrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t srclen, size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (mbsnrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t srclen, size_t len,\n                   mbstate_t *restrict ps));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (mbsnrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t srclen, size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (mbsnrtowcs, size_t,\n                  (wchar_t *restrict dest,\n                   const char **restrict srcp, size_t srclen, size_t len,\n                   mbstate_t *restrict ps));\n# endif\n_GL_CXXALIASWARN (mbsnrtowcs);\n#elif defined GNULIB_POSIXCHECK\n# undef mbsnrtowcs\n# if HAVE_RAW_DECL_MBSNRTOWCS\n_GL_WARN_ON_USE (mbsnrtowcs, \"mbsnrtowcs is unportable - \"\n                 \"use gnulib module mbsnrtowcs for portability\");\n# endif\n#endif\n\n\n/* Convert a wide character to a multibyte character.  */\n#if 1\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcrtomb\n#   define wcrtomb rpl_wcrtomb\n#  endif\n_GL_FUNCDECL_RPL (wcrtomb, size_t,\n                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));\n_GL_CXXALIAS_RPL (wcrtomb, size_t,\n                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (wcrtomb, size_t,\n                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));\n#  endif\n_GL_CXXALIAS_SYS (wcrtomb, size_t,\n                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcrtomb);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcrtomb\n# if HAVE_RAW_DECL_WCRTOMB\n_GL_WARN_ON_USE (wcrtomb, \"wcrtomb is unportable - \"\n                 \"use gnulib module wcrtomb for portability\");\n# endif\n#endif\n\n\n/* Convert a wide string to a string.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcsrtombs\n#   define wcsrtombs rpl_wcsrtombs\n#  endif\n_GL_FUNCDECL_RPL (wcsrtombs, size_t,\n                  (char *restrict dest, const wchar_t **restrict srcp,\n                   size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (wcsrtombs, size_t,\n                  (char *restrict dest, const wchar_t **restrict srcp,\n                   size_t len,\n                   mbstate_t *restrict ps));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (wcsrtombs, size_t,\n                  (char *restrict dest, const wchar_t **restrict srcp,\n                   size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (wcsrtombs, size_t,\n                  (char *restrict dest, const wchar_t **restrict srcp,\n                   size_t len,\n                   mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsrtombs);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsrtombs\n# if HAVE_RAW_DECL_WCSRTOMBS\n_GL_WARN_ON_USE (wcsrtombs, \"wcsrtombs is unportable - \"\n                 \"use gnulib module wcsrtombs for portability\");\n# endif\n#endif\n\n\n/* Convert a wide string to a string.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcsnrtombs\n#   define wcsnrtombs rpl_wcsnrtombs\n#  endif\n_GL_FUNCDECL_RPL (wcsnrtombs, size_t,\n                  (char *restrict dest,\n                   const wchar_t **restrict srcp, size_t srclen,\n                   size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n_GL_CXXALIAS_RPL (wcsnrtombs, size_t,\n                  (char *restrict dest,\n                   const wchar_t **restrict srcp, size_t srclen,\n                   size_t len,\n                   mbstate_t *restrict ps));\n# else\n#  if !1 || (defined __cplusplus && defined __sun)\n_GL_FUNCDECL_SYS (wcsnrtombs, size_t,\n                  (char *restrict dest,\n                   const wchar_t **restrict srcp, size_t srclen,\n                   size_t len,\n                   mbstate_t *restrict ps)\n                  _GL_ARG_NONNULL ((2)));\n#  endif\n_GL_CXXALIAS_SYS (wcsnrtombs, size_t,\n                  (char *restrict dest,\n                   const wchar_t **restrict srcp, size_t srclen,\n                   size_t len,\n                   mbstate_t *restrict ps));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsnrtombs);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsnrtombs\n# if HAVE_RAW_DECL_WCSNRTOMBS\n_GL_WARN_ON_USE (wcsnrtombs, \"wcsnrtombs is unportable - \"\n                 \"use gnulib module wcsnrtombs for portability\");\n# endif\n#endif\n\n\n/* Return the number of screen columns needed for WC.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcwidth\n#   define wcwidth rpl_wcwidth\n#  endif\n_GL_FUNCDECL_RPL (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE);\n_GL_CXXALIAS_RPL (wcwidth, int, (wchar_t));\n# else\n#  if !1\n/* wcwidth exists but is not declared.  */\n_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE);\n#  endif\n_GL_CXXALIAS_SYS (wcwidth, int, (wchar_t));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcwidth);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcwidth\n# if HAVE_RAW_DECL_WCWIDTH\n_GL_WARN_ON_USE (wcwidth, \"wcwidth is unportable - \"\n                 \"use gnulib module wcwidth for portability\");\n# endif\n#endif\n\n\n/* Search N wide characters of S for C.  */\n#if 1\n# if !1\n_GL_FUNCDECL_SYS (wmemchr, wchar_t *, (const wchar_t *s, wchar_t c, size_t n)\n                                      _GL_ATTRIBUTE_PURE);\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" {\n         const wchar_t * std::wmemchr (const wchar_t *, wchar_t, size_t);\n         wchar_t * std::wmemchr (wchar_t *, wchar_t, size_t);\n       }  */\n_GL_CXXALIAS_SYS_CAST2 (wmemchr,\n                        wchar_t *, (const wchar_t *, wchar_t, size_t),\n                        const wchar_t *, (const wchar_t *, wchar_t, size_t));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (wmemchr, wchar_t *, (wchar_t *s, wchar_t c, size_t n));\n_GL_CXXALIASWARN1 (wmemchr, const wchar_t *,\n                   (const wchar_t *s, wchar_t c, size_t n));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmemchr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmemchr\n# if HAVE_RAW_DECL_WMEMCHR\n_GL_WARN_ON_USE (wmemchr, \"wmemchr is unportable - \"\n                 \"use gnulib module wmemchr for portability\");\n# endif\n#endif\n\n\n/* Compare N wide characters of S1 and S2.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wmemcmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n)\n                  _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wmemcmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmemcmp);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmemcmp\n# if HAVE_RAW_DECL_WMEMCMP\n_GL_WARN_ON_USE (wmemcmp, \"wmemcmp is unportable - \"\n                 \"use gnulib module wmemcmp for portability\");\n# endif\n#endif\n\n\n/* Copy N wide characters of SRC to DEST.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wmemcpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wmemcpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmemcpy);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmemcpy\n# if HAVE_RAW_DECL_WMEMCPY\n_GL_WARN_ON_USE (wmemcpy, \"wmemcpy is unportable - \"\n                 \"use gnulib module wmemcpy for portability\");\n# endif\n#endif\n\n\n/* Copy N wide characters of SRC to DEST, guaranteeing correct behavior for\n   overlapping memory areas.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wmemmove, wchar_t *,\n                  (wchar_t *dest, const wchar_t *src, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wmemmove, wchar_t *,\n                  (wchar_t *dest, const wchar_t *src, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmemmove);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmemmove\n# if HAVE_RAW_DECL_WMEMMOVE\n_GL_WARN_ON_USE (wmemmove, \"wmemmove is unportable - \"\n                 \"use gnulib module wmemmove for portability\");\n# endif\n#endif\n\n\n/* Copy N wide characters of SRC to DEST.\n   Return pointer to wide characters after the last written wide character.  */\n#if 1\n# if 1\n_GL_FUNCDECL_SYS (wmempcpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wmempcpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmempcpy);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmempcpy\n# if HAVE_RAW_DECL_WMEMPCPY\n_GL_WARN_ON_USE (wmempcpy, \"wmempcpy is unportable - \"\n                 \"use gnulib module wmempcpy for portability\");\n# endif\n#endif\n\n\n/* Set N wide characters of S to C.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wmemset);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wmemset\n# if HAVE_RAW_DECL_WMEMSET\n_GL_WARN_ON_USE (wmemset, \"wmemset is unportable - \"\n                 \"use gnulib module wmemset for portability\");\n# endif\n#endif\n\n\n/* Return the number of wide characters in S.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcslen, size_t, (const wchar_t *s) _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcslen, size_t, (const wchar_t *s));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcslen);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcslen\n# if HAVE_RAW_DECL_WCSLEN\n_GL_WARN_ON_USE (wcslen, \"wcslen is unportable - \"\n                 \"use gnulib module wcslen for portability\");\n# endif\n#endif\n\n\n/* Return the number of wide characters in S, but at most MAXLEN.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen)\n                                   _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen));\n_GL_CXXALIASWARN (wcsnlen);\n#elif defined GNULIB_POSIXCHECK\n# undef wcsnlen\n# if HAVE_RAW_DECL_WCSNLEN\n_GL_WARN_ON_USE (wcsnlen, \"wcsnlen is unportable - \"\n                 \"use gnulib module wcsnlen for portability\");\n# endif\n#endif\n\n\n/* Copy SRC to DEST.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcscpy, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n# endif\n_GL_CXXALIAS_SYS (wcscpy, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcscpy);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcscpy\n# if HAVE_RAW_DECL_WCSCPY\n_GL_WARN_ON_USE (wcscpy, \"wcscpy is unportable - \"\n                 \"use gnulib module wcscpy for portability\");\n# endif\n#endif\n\n\n/* Copy SRC to DEST, returning the address of the terminating L'\\0' in DEST.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcpcpy, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n# endif\n_GL_CXXALIAS_SYS (wcpcpy, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n_GL_CXXALIASWARN (wcpcpy);\n#elif defined GNULIB_POSIXCHECK\n# undef wcpcpy\n# if HAVE_RAW_DECL_WCPCPY\n_GL_WARN_ON_USE (wcpcpy, \"wcpcpy is unportable - \"\n                 \"use gnulib module wcpcpy for portability\");\n# endif\n#endif\n\n\n/* Copy no more than N wide characters of SRC to DEST.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcsncpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wcsncpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsncpy);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsncpy\n# if HAVE_RAW_DECL_WCSNCPY\n_GL_WARN_ON_USE (wcsncpy, \"wcsncpy is unportable - \"\n                 \"use gnulib module wcsncpy for portability\");\n# endif\n#endif\n\n\n/* Copy no more than N characters of SRC to DEST, returning the address of\n   the last character written into DEST.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcpncpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wcpncpy, wchar_t *,\n                  (wchar_t *restrict dest,\n                   const wchar_t *restrict src, size_t n));\n_GL_CXXALIASWARN (wcpncpy);\n#elif defined GNULIB_POSIXCHECK\n# undef wcpncpy\n# if HAVE_RAW_DECL_WCPNCPY\n_GL_WARN_ON_USE (wcpncpy, \"wcpncpy is unportable - \"\n                 \"use gnulib module wcpncpy for portability\");\n# endif\n#endif\n\n\n/* Append SRC onto DEST.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcscat, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n# endif\n_GL_CXXALIAS_SYS (wcscat, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcscat);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcscat\n# if HAVE_RAW_DECL_WCSCAT\n_GL_WARN_ON_USE (wcscat, \"wcscat is unportable - \"\n                 \"use gnulib module wcscat for portability\");\n# endif\n#endif\n\n\n/* Append no more than N wide characters of SRC onto DEST.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcsncat, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src,\n                   size_t n));\n# endif\n_GL_CXXALIAS_SYS (wcsncat, wchar_t *,\n                  (wchar_t *restrict dest, const wchar_t *restrict src,\n                   size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsncat);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsncat\n# if HAVE_RAW_DECL_WCSNCAT\n_GL_WARN_ON_USE (wcsncat, \"wcsncat is unportable - \"\n                 \"use gnulib module wcsncat for portability\");\n# endif\n#endif\n\n\n/* Compare S1 and S2.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)\n                               _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcscmp);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcscmp\n# if HAVE_RAW_DECL_WCSCMP\n_GL_WARN_ON_USE (wcscmp, \"wcscmp is unportable - \"\n                 \"use gnulib module wcscmp for portability\");\n# endif\n#endif\n\n\n/* Compare no more than N wide characters of S1 and S2.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcsncmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n)\n                  _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcsncmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsncmp);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsncmp\n# if HAVE_RAW_DECL_WCSNCMP\n_GL_WARN_ON_USE (wcsncmp, \"wcsncmp is unportable - \"\n                 \"use gnulib module wcsncmp for portability\");\n# endif\n#endif\n\n\n/* Compare S1 and S2, ignoring case.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2)\n                                   _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2));\n_GL_CXXALIASWARN (wcscasecmp);\n#elif defined GNULIB_POSIXCHECK\n# undef wcscasecmp\n# if HAVE_RAW_DECL_WCSCASECMP\n_GL_WARN_ON_USE (wcscasecmp, \"wcscasecmp is unportable - \"\n                 \"use gnulib module wcscasecmp for portability\");\n# endif\n#endif\n\n\n/* Compare no more than N chars of S1 and S2, ignoring case.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcsncasecmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n)\n                  _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcsncasecmp, int,\n                  (const wchar_t *s1, const wchar_t *s2, size_t n));\n_GL_CXXALIASWARN (wcsncasecmp);\n#elif defined GNULIB_POSIXCHECK\n# undef wcsncasecmp\n# if HAVE_RAW_DECL_WCSNCASECMP\n_GL_WARN_ON_USE (wcsncasecmp, \"wcsncasecmp is unportable - \"\n                 \"use gnulib module wcsncasecmp for portability\");\n# endif\n#endif\n\n\n/* Compare S1 and S2, both interpreted as appropriate to the LC_COLLATE\n   category of the current locale.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2));\n# endif\n_GL_CXXALIAS_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcscoll);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcscoll\n# if HAVE_RAW_DECL_WCSCOLL\n_GL_WARN_ON_USE (wcscoll, \"wcscoll is unportable - \"\n                 \"use gnulib module wcscoll for portability\");\n# endif\n#endif\n\n\n/* Transform S2 into array pointed to by S1 such that if wcscmp is applied\n   to two transformed strings the result is the as applying 'wcscoll' to the\n   original strings.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcsxfrm, size_t,\n                  (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n));\n# endif\n_GL_CXXALIAS_SYS (wcsxfrm, size_t,\n                  (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsxfrm);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsxfrm\n# if HAVE_RAW_DECL_WCSXFRM\n_GL_WARN_ON_USE (wcsxfrm, \"wcsxfrm is unportable - \"\n                 \"use gnulib module wcsxfrm for portability\");\n# endif\n#endif\n\n\n/* Duplicate S, returning an identical malloc'd string.  */\n#if 0\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcsdup\n#   define wcsdup _wcsdup\n#  endif\n_GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s));\n#  endif\n_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s));\n# endif\n_GL_CXXALIASWARN (wcsdup);\n#elif defined GNULIB_POSIXCHECK\n# undef wcsdup\n# if HAVE_RAW_DECL_WCSDUP\n_GL_WARN_ON_USE (wcsdup, \"wcsdup is unportable - \"\n                 \"use gnulib module wcsdup for portability\");\n# endif\n#elif 1\n/* On native Windows, map 'wcsdup' to '_wcsdup', so that -loldnames is not\n   required.  In C++ with GNULIB_NAMESPACE, avoid differences between\n   platforms by defining GNULIB_NAMESPACE::wcsdup always.  */\n# if defined _WIN32 && !defined __CYGWIN__\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcsdup\n#   define wcsdup _wcsdup\n#  endif\n_GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s));\n# else\n_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s));\n#  if 1\n_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s));\n#  endif\n# endif\n# if (defined _WIN32 && !defined __CYGWIN__) || 1\n_GL_CXXALIASWARN (wcsdup);\n# endif\n#endif\n\n\n/* Find the first occurrence of WC in WCS.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcschr, wchar_t *, (const wchar_t *wcs, wchar_t wc)\n                                     _GL_ATTRIBUTE_PURE);\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" {\n         const wchar_t * std::wcschr (const wchar_t *, wchar_t);\n         wchar_t * std::wcschr (wchar_t *, wchar_t);\n       }  */\n_GL_CXXALIAS_SYS_CAST2 (wcschr,\n                        wchar_t *, (const wchar_t *, wchar_t),\n                        const wchar_t *, (const wchar_t *, wchar_t));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (wcschr, wchar_t *, (wchar_t *wcs, wchar_t wc));\n_GL_CXXALIASWARN1 (wcschr, const wchar_t *, (const wchar_t *wcs, wchar_t wc));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcschr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcschr\n# if HAVE_RAW_DECL_WCSCHR\n_GL_WARN_ON_USE (wcschr, \"wcschr is unportable - \"\n                 \"use gnulib module wcschr for portability\");\n# endif\n#endif\n\n\n/* Find the last occurrence of WC in WCS.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcsrchr, wchar_t *, (const wchar_t *wcs, wchar_t wc)\n                                      _GL_ATTRIBUTE_PURE);\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" {\n         const wchar_t * std::wcsrchr (const wchar_t *, wchar_t);\n         wchar_t * std::wcsrchr (wchar_t *, wchar_t);\n       }  */\n_GL_CXXALIAS_SYS_CAST2 (wcsrchr,\n                        wchar_t *, (const wchar_t *, wchar_t),\n                        const wchar_t *, (const wchar_t *, wchar_t));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (wcsrchr, wchar_t *, (wchar_t *wcs, wchar_t wc));\n_GL_CXXALIASWARN1 (wcsrchr, const wchar_t *, (const wchar_t *wcs, wchar_t wc));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsrchr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsrchr\n# if HAVE_RAW_DECL_WCSRCHR\n_GL_WARN_ON_USE (wcsrchr, \"wcsrchr is unportable - \"\n                 \"use gnulib module wcsrchr for portability\");\n# endif\n#endif\n\n\n/* Return the length of the initial segmet of WCS which consists entirely\n   of wide characters not in REJECT.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject)\n                                   _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcscspn);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcscspn\n# if HAVE_RAW_DECL_WCSCSPN\n_GL_WARN_ON_USE (wcscspn, \"wcscspn is unportable - \"\n                 \"use gnulib module wcscspn for portability\");\n# endif\n#endif\n\n\n/* Return the length of the initial segmet of WCS which consists entirely\n   of wide characters in ACCEPT.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept)\n                                  _GL_ATTRIBUTE_PURE);\n# endif\n_GL_CXXALIAS_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept));\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsspn);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsspn\n# if HAVE_RAW_DECL_WCSSPN\n_GL_WARN_ON_USE (wcsspn, \"wcsspn is unportable - \"\n                 \"use gnulib module wcsspn for portability\");\n# endif\n#endif\n\n\n/* Find the first occurrence in WCS of any character in ACCEPT.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcspbrk, wchar_t *,\n                  (const wchar_t *wcs, const wchar_t *accept)\n                  _GL_ATTRIBUTE_PURE);\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" {\n         const wchar_t * std::wcspbrk (const wchar_t *, const wchar_t *);\n         wchar_t * std::wcspbrk (wchar_t *, const wchar_t *);\n       }  */\n_GL_CXXALIAS_SYS_CAST2 (wcspbrk,\n                        wchar_t *, (const wchar_t *, const wchar_t *),\n                        const wchar_t *, (const wchar_t *, const wchar_t *));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (wcspbrk, wchar_t *,\n                   (wchar_t *wcs, const wchar_t *accept));\n_GL_CXXALIASWARN1 (wcspbrk, const wchar_t *,\n                   (const wchar_t *wcs, const wchar_t *accept));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcspbrk);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcspbrk\n# if HAVE_RAW_DECL_WCSPBRK\n_GL_WARN_ON_USE (wcspbrk, \"wcspbrk is unportable - \"\n                 \"use gnulib module wcspbrk for portability\");\n# endif\n#endif\n\n\n/* Find the first occurrence of NEEDLE in HAYSTACK.  */\n#if 0\n# if !1\n_GL_FUNCDECL_SYS (wcsstr, wchar_t *,\n                  (const wchar_t *restrict haystack,\n                   const wchar_t *restrict needle)\n                  _GL_ATTRIBUTE_PURE);\n# endif\n  /* On some systems, this function is defined as an overloaded function:\n       extern \"C++\" {\n         const wchar_t * std::wcsstr (const wchar_t *, const wchar_t *);\n         wchar_t * std::wcsstr (wchar_t *, const wchar_t *);\n       }  */\n_GL_CXXALIAS_SYS_CAST2 (wcsstr,\n                        wchar_t *,\n                        (const wchar_t *restrict, const wchar_t *restrict),\n                        const wchar_t *,\n                        (const wchar_t *restrict, const wchar_t *restrict));\n# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \\\n     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))\n_GL_CXXALIASWARN1 (wcsstr, wchar_t *,\n                   (wchar_t *restrict haystack,\n                    const wchar_t *restrict needle));\n_GL_CXXALIASWARN1 (wcsstr, const wchar_t *,\n                   (const wchar_t *restrict haystack,\n                    const wchar_t *restrict needle));\n# elif __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsstr);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsstr\n# if HAVE_RAW_DECL_WCSSTR\n_GL_WARN_ON_USE (wcsstr, \"wcsstr is unportable - \"\n                 \"use gnulib module wcsstr for portability\");\n# endif\n#endif\n\n\n/* Divide WCS into tokens separated by characters in DELIM.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcstok\n#   define wcstok rpl_wcstok\n#  endif\n_GL_FUNCDECL_RPL (wcstok, wchar_t *,\n                  (wchar_t *restrict wcs, const wchar_t *restrict delim,\n                   wchar_t **restrict ptr));\n_GL_CXXALIAS_RPL (wcstok, wchar_t *,\n                  (wchar_t *restrict wcs, const wchar_t *restrict delim,\n                   wchar_t **restrict ptr));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (wcstok, wchar_t *,\n                  (wchar_t *restrict wcs, const wchar_t *restrict delim,\n                   wchar_t **restrict ptr));\n#  endif\n_GL_CXXALIAS_SYS (wcstok, wchar_t *,\n                  (wchar_t *restrict wcs, const wchar_t *restrict delim,\n                   wchar_t **restrict ptr));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcstok);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcstok\n# if HAVE_RAW_DECL_WCSTOK\n_GL_WARN_ON_USE (wcstok, \"wcstok is unportable - \"\n                 \"use gnulib module wcstok for portability\");\n# endif\n#endif\n\n\n/* Determine number of column positions required for first N wide\n   characters (or fewer if S ends before this) in S.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcswidth\n#   define wcswidth rpl_wcswidth\n#  endif\n_GL_FUNCDECL_RPL (wcswidth, int, (const wchar_t *s, size_t n)\n                                 _GL_ATTRIBUTE_PURE);\n_GL_CXXALIAS_RPL (wcswidth, int, (const wchar_t *s, size_t n));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (wcswidth, int, (const wchar_t *s, size_t n)\n                                 _GL_ATTRIBUTE_PURE);\n#  endif\n_GL_CXXALIAS_SYS (wcswidth, int, (const wchar_t *s, size_t n));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcswidth);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcswidth\n# if HAVE_RAW_DECL_WCSWIDTH\n_GL_WARN_ON_USE (wcswidth, \"wcswidth is unportable - \"\n                 \"use gnulib module wcswidth for portability\");\n# endif\n#endif\n\n\n/* Convert *TP to a date and time wide string.  See\n   <https://pubs.opengroup.org/onlinepubs/9699919799/functions/wcsftime.html>.  */\n#if 0\n# if 0\n#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)\n#   undef wcsftime\n#   define wcsftime rpl_wcsftime\n#  endif\n_GL_FUNCDECL_RPL (wcsftime, size_t,\n                  (wchar_t *restrict __buf, size_t __bufsize,\n                   const wchar_t *restrict __fmt,\n                   const struct tm *restrict __tp)\n                  _GL_ARG_NONNULL ((1, 3, 4)));\n_GL_CXXALIAS_RPL (wcsftime, size_t,\n                  (wchar_t *restrict __buf, size_t __bufsize,\n                   const wchar_t *restrict __fmt,\n                   const struct tm *restrict __tp));\n# else\n#  if !1\n_GL_FUNCDECL_SYS (wcsftime, size_t,\n                  (wchar_t *restrict __buf, size_t __bufsize,\n                   const wchar_t *restrict __fmt,\n                   const struct tm *restrict __tp)\n                  _GL_ARG_NONNULL ((1, 3, 4)));\n#  endif\n_GL_CXXALIAS_SYS (wcsftime, size_t,\n                  (wchar_t *restrict __buf, size_t __bufsize,\n                   const wchar_t *restrict __fmt,\n                   const struct tm *restrict __tp));\n# endif\n# if __GLIBC__ >= 2\n_GL_CXXALIASWARN (wcsftime);\n# endif\n#elif defined GNULIB_POSIXCHECK\n# undef wcsftime\n# if HAVE_RAW_DECL_WCSFTIME\n_GL_WARN_ON_USE (wcsftime, \"wcsftime is unportable - \"\n                 \"use gnulib module wcsftime for portability\");\n# endif\n#endif\n\n\n#endif /* _GL_WCHAR_H */\n#endif /* _GL_WCHAR_H */\n#endif\n"
  },
  {
    "path": "win32/license/Copyright.libxml2",
    "content": "Except where otherwise noted in the source code (e.g. the files hash.c,\nlist.c and the trio files, which are covered by a similar licence but\nwith different Copyright notices) all the files are:\n\n Copyright (C) 1998-2012 Daniel Veillard.  All Rights Reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is fur-\nnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-\nNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "win32/license/LICENCE.pcre2",
    "content": "PCRE2 LICENCE\n-------------\n\nPCRE2 is a library of functions to support regular expressions whose syntax\nand semantics are as close as possible to those of the Perl 5 language.\n\nReleases 10.00 and above of PCRE2 are distributed under the terms of the \"BSD\"\nlicence, as specified below, with one exemption for certain binary\nredistributions. The documentation for PCRE2, supplied in the \"doc\" directory,\nis distributed under the same terms as the software itself. The data in the\ntestdata directory is not copyrighted and is in the public domain.\n\nThe basic library functions are written in C and are freestanding. Also\nincluded in the distribution is a just-in-time compiler that can be used to\noptimize pattern matching. This is an optional feature that can be omitted when\nthe library is built.\n\n\nTHE BASIC LIBRARY FUNCTIONS\n---------------------------\n\nWritten by:       Philip Hazel\nEmail local part: Philip.Hazel\nEmail domain:     gmail.com\n\nRetired from University of Cambridge Computing Service,\nCambridge, England.\n\nCopyright (c) 1997-2021 University of Cambridge\nAll rights reserved.\n\n\nPCRE2 JUST-IN-TIME COMPILATION SUPPORT\n--------------------------------------\n\nWritten by:       Zoltan Herczeg\nEmail local part: hzmester\nEmail domain:     freemail.hu\n\nCopyright(c) 2010-2021 Zoltan Herczeg\nAll rights reserved.\n\n\nSTACK-LESS JUST-IN-TIME COMPILER\n--------------------------------\n\nWritten by:       Zoltan Herczeg\nEmail local part: hzmester\nEmail domain:     freemail.hu\n\nCopyright(c) 2009-2021 Zoltan Herczeg\nAll rights reserved.\n\n\nTHE \"BSD\" LICENCE\n-----------------\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notices,\n      this list of conditions and the following disclaimer.\n\n    * Redistributions in binary form must reproduce the above copyright\n      notices, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the name of the University of Cambridge nor the names of any\n      contributors may be used to endorse or promote products derived from this\n      software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\n\nEXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES\n------------------------------------------\n\nThe second condition in the BSD licence (covering binary redistributions) does\nnot apply all the way down a chain of software. If binary package A includes\nPCRE2, it must respect the condition, but if package B is software that\nincludes package A, the condition is not imposed on package B unless it uses\nPCRE2 independently.\n\nEnd\n"
  },
  {
    "path": "win32/license/LICENSE.janssen",
    "content": "Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "win32/license/LICENSE.libyaml",
    "content": "Copyright (c) 2006 Kirill Simonov\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "win32/mkstemp/COPYING.MinGW-w64-runtime.txt",
    "content": "MinGW-w64 runtime licensing\n***************************\n\nThis program or library was built using MinGW-w64 and statically\nlinked against the MinGW-w64 runtime. Some parts of the runtime\nare under licenses which require that the copyright and license\nnotices are included when distributing the code in binary form.\nThese notices are listed below.\n\n\n========================\nOverall copyright notice\n========================\n\nCopyright (c) 2009, 2010, 2011, 2012, 2013 by the mingw-w64 project\n\nThis license has been certified as open source. It has also been designated\nas GPL compatible by the Free Software Foundation (FSF).\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n   1. Redistributions in source code must retain the accompanying copyright\n      notice, this list of conditions, and the following disclaimer.\n   2. Redistributions in binary form must reproduce the accompanying\n      copyright notice, this list of conditions, and the following disclaimer\n      in the documentation and/or other materials provided with the\n      distribution.\n   3. Names of the copyright holders must not be used to endorse or promote\n      products derived from this software without prior written permission\n      from the copyright holders.\n   4. The right to distribute this software or to use it for any purpose does\n      not give you the right to use Servicemarks (sm) or Trademarks (tm) of\n      the copyright holders.  Use of them is covered by separate agreement\n      with the copyright holders.\n   5. If any files are modified, you must cause the modified files to carry\n      prominent notices stating that you changed the files and the date of\n      any change.\n\nDisclaimer\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED\nOR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\nEVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\nOR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\nEVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n======================================== \ngetopt, getopt_long, and getop_long_only\n======================================== \n\nCopyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> \n \nPermission to use, copy, modify, and distribute this software for any \npurpose with or without fee is hereby granted, provided that the above \ncopyright notice and this permission notice appear in all copies. \n \t \nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\nSponsored in part by the Defense Advanced Research Projects\nAgency (DARPA) and Air Force Research Laboratory, Air Force\nMateriel Command, USAF, under agreement number F39502-99-1-0512.\n\n        *       *       *       *       *       *       * \n\nCopyright (c) 2000 The NetBSD Foundation, Inc.\nAll rights reserved.\n\nThis code is derived from software contributed to The NetBSD Foundation\nby Dieter Baron and Thomas Klausner.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n 1. Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n 2. Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in the\n    documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\n``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\nBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\n\n===============================================================\ngdtoa: Converting between IEEE floating point numbers and ASCII\n===============================================================\n\nThe author of this software is David M. Gay.\n\nCopyright (C) 1997, 1998, 1999, 2000, 2001 by Lucent Technologies\nAll Rights Reserved\n\nPermission to use, copy, modify, and distribute this software and\nits documentation for any purpose and without fee is hereby\ngranted, provided that the above copyright notice appear in all\ncopies and that both that the copyright notice and this\npermission notice and warranty disclaimer appear in supporting\ndocumentation, and that the name of Lucent or any of its entities\nnot be used in advertising or publicity pertaining to\ndistribution of the software without specific, written prior\npermission.\n\nLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,\nINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.\nIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY\nSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER\nIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\nARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\nTHIS SOFTWARE.\n\n        *       *       *       *       *       *       *\n\nThe author of this software is David M. Gay.\n\nCopyright (C) 2005 by David M. Gay\nAll Rights Reserved\n\nPermission to use, copy, modify, and distribute this software and its\ndocumentation for any purpose and without fee is hereby granted,\nprovided that the above copyright notice appear in all copies and that\nboth that the copyright notice and this permission notice and warranty\ndisclaimer appear in supporting documentation, and that the name of\nthe author or any of his current or former employers not be used in\nadvertising or publicity pertaining to distribution of the software\nwithout specific, written prior permission.\n\nTHE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,\nINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN\nNO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS BE\nLIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY\nDAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,\nWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\nARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\nSOFTWARE.\n\n        *       *       *       *       *       *       *\n\nThe author of this software is David M. Gay.\n\nCopyright (C) 2004 by David M. Gay.\nAll Rights Reserved\nBased on material in the rest of /netlib/fp/gdota.tar.gz,\nwhich is copyright (C) 1998, 2000 by Lucent Technologies.\n\nPermission to use, copy, modify, and distribute this software and\nits documentation for any purpose and without fee is hereby\ngranted, provided that the above copyright notice appear in all\ncopies and that both that the copyright notice and this\npermission notice and warranty disclaimer appear in supporting\ndocumentation, and that the name of Lucent or any of its entities\nnot be used in advertising or publicity pertaining to\ndistribution of the software without specific, written prior\npermission.\n\nLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,\nINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.\nIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY\nSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER\nIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\nARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\nTHIS SOFTWARE.\n\n\n=========================\nParts of the math library\n=========================\n\nCopyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n\nDeveloped at SunSoft, a Sun Microsystems, Inc. business.\nPermission to use, copy, modify, and distribute this\nsoftware is freely granted, provided that this notice\nis preserved.\n\n        *       *       *       *       *       *       *\n\nCopyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n\nDeveloped at SunPro, a Sun Microsystems, Inc. business.\nPermission to use, copy, modify, and distribute this\nsoftware is freely granted, provided that this notice\nis preserved.\n\n        *       *       *       *       *       *       *\n\nFIXME: Cephes math lib\nCopyright (C) 1984-1998 Stephen L. Moshier\n\nIt sounds vague, but as to be found at\n<http://lists.debian.org/debian-legal/2004/12/msg00295.html>, it gives an\nimpression that the author could be willing to give an explicit\npermission to distribute those files e.g. under a BSD style license. So\nprobably there is no problem here, although it could be good to get a\npermission from the author and then add a license into the Cephes files\nin MinGW runtime. At least on follow-up it is marked that debian sees the\nversion a-like BSD one. As MinGW.org (where those cephes parts are coming\nfrom) distributes them now over 6 years, it should be fine.\n\n===================================\nHeaders and IDLs imported from Wine\n===================================\n\nSome header and IDL files were imported from the Wine project. These files\nare prominent maked in source. Their copyright belongs to contributors and\nthey are distributed under LGPL license.\n\nDisclaimer\n\nThis library is free software; you can redistribute it and/or\nmodify it under the terms of the GNU Lesser General Public\nLicense as published by the Free Software Foundation; either\nversion 2.1 of the License, or (at your option) any later version.\n\nThis library is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\nLesser General Public License for more details.\n"
  },
  {
    "path": "win32/mkstemp/mkstemp.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <io.h>\n#include <errno.h>\n#include <share.h>\n#include <fcntl.h>\n#include <sys/stat.h>\n\n/*\n    The mkstemp() function generates a unique temporary filename from template,\n    creates and opens the file, and returns an open file descriptor for the\n    file.\n\n    The template may be any file name with at least six trailing Xs, for example\n    /tmp/temp.XXXXXXXX. The trailing Xs are replaced with a unique digit and\n    letter combination that makes the file name unique. Since it will be\n    modified, template must not be a string constant, but should be declared as\n    a character array.\n\n    The file is created with permissions 0600, that is, read plus write for\n    owner only. The returned file descriptor provides both read and write access\n    to the file.\n */\nint __cdecl mkstemp (char *template_name)\n{\n    int i, j, fd, len, index;\n\n    /* These are the (62) characters used in temporary filenames. */\n    static const char letters[] = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n\n    /* The last six characters of template must be \"XXXXXX\" */\n    if (template_name == NULL || (len = strlen (template_name)) < 6\n            || memcmp (template_name + (len - 6), \"XXXXXX\", 6)) {\n        errno = EINVAL;\n        return -1;\n    }\n\n    /* User may supply more than six trailing Xs */\n    for (index = len - 6; index > 0 && template_name[index - 1] == 'X'; index--);\n\n    /*\n        Like OpenBSD, mkstemp() will try at least 2 ** 31 combinations before\n        giving up.\n     */\n    for (i = 0; i >= 0; i++) {\n        for(j = index; j < len; j++) {\n            template_name[j] = letters[rand () % 62];\n        }\n        fd = _sopen(template_name,\n                _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY,\n                _SH_DENYRW, _S_IREAD | _S_IWRITE);\n        if (fd != -1) return fd;\n        if (fd == -1 && errno != EEXIST) return -1;\n    }\n\n    return -1;\n}\n\n#if 0\nint main (int argc, char *argv[])\n{\n    int i, fd;\n\n    for (i = 0; i < 10; i++) {\n        char template_name[] = { \"temp_XXXXXX\" };\n        fd = mkstemp (template_name);\n        if (fd >= 0) {\n            fprintf (stderr, \"fd=%d, name=%s\\n\", fd, template_name);\n            _close (fd);\n        } else {\n            fprintf (stderr, \"errno=%d\\n\", errno);\n        }\n    }\n\n    for (i = 0; i < 10; i++) {\n        char template_name[] = { \"temp_XXXXXXXX\" };\n        fd = mkstemp (template_name);\n        if (fd >= 0) {\n            fprintf (stderr, \"fd=%d, name=%s\\n\", fd, template_name);\n            _close (fd);\n        } else {\n            fprintf (stderr, \"errno=%d\\n\", errno);\n        }\n    }\n\n    return 0;\n}\n#endif\n"
  },
  {
    "path": "win32/peg_rule.mak",
    "content": "# Generated by win32/GNUmakefile\npeg/varlink.c peg/varlink.h: peg/varlink.peg $(PACKCC)\npeg/kotlin.c peg/kotlin.h: peg/kotlin.peg $(PACKCC)\npeg/thrift.c peg/thrift.h: peg/thrift.peg $(PACKCC)\npeg/elm.c peg/elm.h: peg/elm.peg $(PACKCC)\npeg/toml.c peg/toml.h: peg/toml.peg $(PACKCC)\n"
  },
  {
    "path": "win32/resource.h",
    "content": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by ctags.rc\n\n// Next default values for new objects\n//\n#ifdef APSTUDIO_INVOKED\n#ifndef APSTUDIO_READONLY_SYMBOLS\n#define _APS_NEXT_RESOURCE_VALUE        101\n#define _APS_NEXT_COMMAND_VALUE         40001\n#define _APS_NEXT_CONTROL_VALUE         1001\n#define _APS_NEXT_SYMED_VALUE           101\n#endif\n#endif\n"
  }
]